Skip to content

Commit 07f531b

Browse files
kuu-rtij-intel
authored andcommitted
ACPI: platform_profile: Remove platform_profile_handler from exported symbols
In order to protect the platform_profile_handler from API consumers, allocate it in platform_profile_register() and modify it's signature accordingly. Remove the platform_profile_handler from all consumer drivers and replace them with a pointer to the class device, which is now returned from platform_profile_register(). Replace *pprof with a pointer to the class device in the rest of exported symbols. Reviewed-by: Mario Limonciello <[email protected]> Signed-off-by: Kurt Borja <[email protected]> Reviewed-by: Mark Pearson <[email protected]> Tested-by: Mark Pearson <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Ilpo Järvinen <[email protected]> Signed-off-by: Ilpo Järvinen <[email protected]>
1 parent 31658c9 commit 07f531b

File tree

13 files changed

+129
-132
lines changed

13 files changed

+129
-132
lines changed

drivers/acpi/platform_profile.c

Lines changed: 61 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <linux/acpi.h>
66
#include <linux/bits.h>
7+
#include <linux/cleanup.h>
78
#include <linux/init.h>
89
#include <linux/mutex.h>
910
#include <linux/platform_profile.h>
@@ -212,9 +213,17 @@ static struct attribute *profile_attrs[] = {
212213
};
213214
ATTRIBUTE_GROUPS(profile);
214215

216+
static void pprof_device_release(struct device *dev)
217+
{
218+
struct platform_profile_handler *pprof = to_pprof_handler(dev);
219+
220+
kfree(pprof);
221+
}
222+
215223
static const struct class platform_profile_class = {
216224
.name = "platform-profile",
217225
.dev_groups = profile_groups,
226+
.dev_release = pprof_device_release,
218227
};
219228

220229
/**
@@ -408,10 +417,10 @@ static const struct attribute_group platform_profile_group = {
408417
.is_visible = profile_class_is_visible,
409418
};
410419

411-
void platform_profile_notify(struct platform_profile_handler *pprof)
420+
void platform_profile_notify(struct device *dev)
412421
{
413422
scoped_cond_guard(mutex_intr, return, &profile_lock) {
414-
_notify_class_profile(&pprof->class_dev, NULL);
423+
_notify_class_profile(dev, NULL);
415424
}
416425
sysfs_notify(acpi_kobj, NULL, "platform_profile");
417426
}
@@ -460,42 +469,54 @@ int platform_profile_cycle(void)
460469
}
461470
EXPORT_SYMBOL_GPL(platform_profile_cycle);
462471

463-
int platform_profile_register(struct platform_profile_handler *pprof, void *drvdata)
472+
struct device *platform_profile_register(struct device *dev, const char *name,
473+
void *drvdata,
474+
const struct platform_profile_ops *ops)
464475
{
476+
struct device *ppdev;
477+
int minor;
465478
int err;
466479

467-
/* Sanity check the profile handler */
468-
if (!pprof || !pprof->ops->profile_set || !pprof->ops->profile_get ||
469-
!pprof->ops->probe) {
470-
pr_err("platform_profile: handler is invalid\n");
471-
return -EINVAL;
472-
}
480+
/* Sanity check */
481+
if (WARN_ON_ONCE(!dev || !name || !ops || !ops->profile_get ||
482+
!ops->profile_set || !ops->probe))
483+
return ERR_PTR(-EINVAL);
484+
485+
struct platform_profile_handler *pprof __free(kfree) = kzalloc(
486+
sizeof(*pprof), GFP_KERNEL);
487+
if (!pprof)
488+
return ERR_PTR(-ENOMEM);
473489

474-
err = pprof->ops->probe(drvdata, pprof->choices);
490+
err = ops->probe(drvdata, pprof->choices);
475491
if (err) {
476-
dev_err(pprof->dev, "platform_profile probe failed\n");
477-
return err;
492+
dev_err(dev, "platform_profile probe failed\n");
493+
return ERR_PTR(err);
478494
}
479495

480496
if (bitmap_empty(pprof->choices, PLATFORM_PROFILE_LAST)) {
481-
dev_err(pprof->dev, "Failed to register a platform_profile class device with empty choices\n");
482-
return -EINVAL;
497+
dev_err(dev, "Failed to register platform_profile class device with empty choices\n");
498+
return ERR_PTR(-EINVAL);
483499
}
484500

485501
guard(mutex)(&profile_lock);
486502

487503
/* create class interface for individual handler */
488-
pprof->minor = ida_alloc(&platform_profile_ida, GFP_KERNEL);
489-
if (pprof->minor < 0)
490-
return pprof->minor;
504+
minor = ida_alloc(&platform_profile_ida, GFP_KERNEL);
505+
if (minor < 0)
506+
return ERR_PTR(minor);
491507

508+
pprof->name = name;
509+
pprof->ops = ops;
510+
pprof->minor = minor;
492511
pprof->class_dev.class = &platform_profile_class;
493-
pprof->class_dev.parent = pprof->dev;
512+
pprof->class_dev.parent = dev;
494513
dev_set_drvdata(&pprof->class_dev, drvdata);
495514
dev_set_name(&pprof->class_dev, "platform-profile-%d", pprof->minor);
496-
err = device_register(&pprof->class_dev);
515+
/* device_register() takes ownership of pprof/ppdev */
516+
ppdev = &no_free_ptr(pprof)->class_dev;
517+
err = device_register(ppdev);
497518
if (err) {
498-
put_device(&pprof->class_dev);
519+
put_device(ppdev);
499520
goto cleanup_ida;
500521
}
501522

@@ -505,20 +526,21 @@ int platform_profile_register(struct platform_profile_handler *pprof, void *drvd
505526
if (err)
506527
goto cleanup_cur;
507528

508-
return 0;
529+
return ppdev;
509530

510531
cleanup_cur:
511-
device_unregister(&pprof->class_dev);
532+
device_unregister(ppdev);
512533

513534
cleanup_ida:
514-
ida_free(&platform_profile_ida, pprof->minor);
535+
ida_free(&platform_profile_ida, minor);
515536

516-
return err;
537+
return ERR_PTR(err);
517538
}
518539
EXPORT_SYMBOL_GPL(platform_profile_register);
519540

520-
int platform_profile_remove(struct platform_profile_handler *pprof)
541+
int platform_profile_remove(struct device *dev)
521542
{
543+
struct platform_profile_handler *pprof = to_pprof_handler(dev);
522544
int id;
523545
guard(mutex)(&profile_lock);
524546

@@ -536,30 +558,32 @@ EXPORT_SYMBOL_GPL(platform_profile_remove);
536558

537559
static void devm_platform_profile_release(struct device *dev, void *res)
538560
{
539-
struct platform_profile_handler **pprof = res;
561+
struct device **ppdev = res;
540562

541-
platform_profile_remove(*pprof);
563+
platform_profile_remove(*ppdev);
542564
}
543565

544-
int devm_platform_profile_register(struct platform_profile_handler *pprof, void *drvdata)
566+
struct device *devm_platform_profile_register(struct device *dev, const char *name,
567+
void *drvdata,
568+
const struct platform_profile_ops *ops)
545569
{
546-
struct platform_profile_handler **dr;
547-
int ret;
570+
struct device *ppdev;
571+
struct device **dr;
548572

549573
dr = devres_alloc(devm_platform_profile_release, sizeof(*dr), GFP_KERNEL);
550574
if (!dr)
551-
return -ENOMEM;
575+
return ERR_PTR(-ENOMEM);
552576

553-
ret = platform_profile_register(pprof, drvdata);
554-
if (ret) {
577+
ppdev = platform_profile_register(dev, name, drvdata, ops);
578+
if (IS_ERR(ppdev)) {
555579
devres_free(dr);
556-
return ret;
580+
return ppdev;
557581
}
558582

559-
*dr = pprof;
560-
devres_add(pprof->dev, dr);
583+
*dr = ppdev;
584+
devres_add(dev, dr);
561585

562-
return 0;
586+
return ppdev;
563587
}
564588
EXPORT_SYMBOL_GPL(devm_platform_profile_register);
565589

drivers/platform/surface/surface_platform_profile.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ struct ssam_tmp_profile_info {
4040

4141
struct ssam_platform_profile_device {
4242
struct ssam_device *sdev;
43-
struct platform_profile_handler handler;
43+
struct device *ppdev;
4444
bool has_fan;
4545
};
4646

@@ -228,13 +228,12 @@ static int surface_platform_profile_probe(struct ssam_device *sdev)
228228
tpd->sdev = sdev;
229229
ssam_device_set_drvdata(sdev, tpd);
230230

231-
tpd->handler.name = "Surface Platform Profile";
232-
tpd->handler.dev = &sdev->dev;
233-
tpd->handler.ops = &ssam_platform_profile_ops;
234-
235231
tpd->has_fan = device_property_read_bool(&sdev->dev, "has_fan");
236232

237-
return devm_platform_profile_register(&tpd->handler, tpd);
233+
tpd->ppdev = devm_platform_profile_register(&sdev->dev, "Surface Platform Profile",
234+
tpd, &ssam_platform_profile_ops);
235+
236+
return PTR_ERR_OR_ZERO(tpd->ppdev);
238237
}
239238

240239
static const struct ssam_device_id ssam_platform_profile_match[] = {

drivers/platform/x86/acer-wmi.c

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,7 @@ static const struct dmi_system_id non_acer_quirks[] __initconst = {
784784
{}
785785
};
786786

787-
static struct platform_profile_handler platform_profile_handler;
787+
static struct device *platform_profile_device;
788788
static bool platform_profile_support;
789789

790790
/*
@@ -2073,16 +2073,10 @@ static const struct platform_profile_ops acer_predator_v4_platform_profile_ops =
20732073
static int acer_platform_profile_setup(struct platform_device *device)
20742074
{
20752075
if (quirks->predator_v4) {
2076-
int err;
2077-
2078-
platform_profile_handler.name = "acer-wmi";
2079-
platform_profile_handler.dev = &device->dev;
2080-
platform_profile_handler.ops =
2081-
&acer_predator_v4_platform_profile_ops;
2082-
2083-
err = devm_platform_profile_register(&platform_profile_handler, NULL);
2084-
if (err)
2085-
return err;
2076+
platform_profile_device = devm_platform_profile_register(
2077+
&device->dev, "acer-wmi", NULL, &acer_predator_v4_platform_profile_ops);
2078+
if (IS_ERR(platform_profile_device))
2079+
return PTR_ERR(platform_profile_device);
20862080

20872081
platform_profile_support = true;
20882082

@@ -2125,7 +2119,7 @@ static int acer_thermal_profile_change(void)
21252119
if (current_tp != acer_predator_v4_max_perf)
21262120
last_non_turbo_profile = current_tp;
21272121

2128-
platform_profile_notify(&platform_profile_handler);
2122+
platform_profile_notify(platform_profile_device);
21292123
}
21302124
}
21312125

drivers/platform/x86/amd/pmf/pmf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ struct amd_pmf_dev {
338338
struct mutex lock; /* protects the PMF interface */
339339
u32 supported_func;
340340
enum platform_profile_option current_profile;
341-
struct platform_profile_handler pprof;
341+
struct device *ppdev; /* platform profile class device */
342342
struct dentry *dbgfs_dir;
343343
int hb_interval; /* SBIOS heartbeat interval */
344344
struct delayed_work heart_beat;

drivers/platform/x86/amd/pmf/sps.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -404,8 +404,6 @@ static const struct platform_profile_ops amd_pmf_profile_ops = {
404404

405405
int amd_pmf_init_sps(struct amd_pmf_dev *dev)
406406
{
407-
int err;
408-
409407
dev->current_profile = PLATFORM_PROFILE_BALANCED;
410408

411409
if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) {
@@ -420,15 +418,12 @@ int amd_pmf_init_sps(struct amd_pmf_dev *dev)
420418
amd_pmf_set_sps_power_limits(dev);
421419
}
422420

423-
dev->pprof.name = "amd-pmf";
424-
dev->pprof.dev = dev->dev;
425-
dev->pprof.ops = &amd_pmf_profile_ops;
426-
427421
/* Create platform_profile structure and register */
428-
err = devm_platform_profile_register(&dev->pprof, dev);
429-
if (err)
430-
dev_err(dev->dev, "Failed to register SPS support, this is most likely an SBIOS bug: %d\n",
431-
err);
422+
dev->ppdev = devm_platform_profile_register(dev->dev, "amd-pmf", dev,
423+
&amd_pmf_profile_ops);
424+
if (IS_ERR(dev->ppdev))
425+
dev_err(dev->dev, "Failed to register SPS support, this is most likely an SBIOS bug: %ld\n",
426+
PTR_ERR(dev->ppdev));
432427

433-
return err;
428+
return PTR_ERR_OR_ZERO(dev->ppdev);
434429
}

drivers/platform/x86/asus-wmi.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ struct asus_wmi {
313313
bool mid_fan_curve_available;
314314
struct fan_curve_data custom_fan_curves[3];
315315

316-
struct platform_profile_handler platform_profile_handler;
316+
struct device *ppdev;
317317
bool platform_profile_support;
318318

319319
// The RSOC controls the maximum charging percentage.
@@ -3789,7 +3789,7 @@ static ssize_t throttle_thermal_policy_store(struct device *dev,
37893789
* Ensure that platform_profile updates userspace with the change to ensure
37903790
* that platform_profile and throttle_thermal_policy_mode are in sync.
37913791
*/
3792-
platform_profile_notify(&asus->platform_profile_handler);
3792+
platform_profile_notify(asus->ppdev);
37933793

37943794
return count;
37953795
}
@@ -3891,14 +3891,11 @@ static int platform_profile_setup(struct asus_wmi *asus)
38913891

38923892
dev_info(dev, "Using throttle_thermal_policy for platform_profile support\n");
38933893

3894-
asus->platform_profile_handler.name = "asus-wmi";
3895-
asus->platform_profile_handler.dev = dev;
3896-
asus->platform_profile_handler.ops = &asus_wmi_platform_profile_ops;
3897-
3898-
err = devm_platform_profile_register(&asus->platform_profile_handler, asus);
3899-
if (err) {
3894+
asus->ppdev = devm_platform_profile_register(dev, "asus-wmi", asus,
3895+
&asus_wmi_platform_profile_ops);
3896+
if (IS_ERR(asus->ppdev)) {
39003897
dev_err(dev, "Failed to register a platform_profile class device\n");
3901-
return err;
3898+
return PTR_ERR(asus->ppdev);
39023899
}
39033900

39043901
asus->platform_profile_support = true;

drivers/platform/x86/dell/alienware-wmi.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,6 @@ struct wmax_u32_args {
406406

407407
static struct platform_device *platform_device;
408408
static struct color_platform colors[4];
409-
static struct platform_profile_handler pp_handler;
410409
static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
411410

412411
static u8 interface;
@@ -1135,11 +1134,12 @@ static const struct platform_profile_ops awcc_platform_profile_ops = {
11351134

11361135
static int create_thermal_profile(struct platform_device *platform_device)
11371136
{
1138-
pp_handler.name = "alienware-wmi";
1139-
pp_handler.dev = &platform_device->dev;
1140-
pp_handler.ops = &awcc_platform_profile_ops;
1137+
struct device *ppdev;
11411138

1142-
return devm_platform_profile_register(&pp_handler, NULL);
1139+
ppdev = devm_platform_profile_register(&platform_device->dev, "alienware-wmi",
1140+
NULL, &awcc_platform_profile_ops);
1141+
1142+
return PTR_ERR_OR_ZERO(ppdev);
11431143
}
11441144

11451145
/*

drivers/platform/x86/dell/dell-pc.c

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,6 @@ MODULE_DEVICE_TABLE(dmi, dell_device_table);
109109
#define DELL_ACC_SET_FIELD GENMASK(11, 8)
110110
#define DELL_THERMAL_SUPPORTED GENMASK(3, 0)
111111

112-
static struct platform_profile_handler *thermal_handler;
113-
114112
enum thermal_mode_bits {
115113
DELL_BALANCED = BIT(0),
116114
DELL_COOL_BOTTOM = BIT(1),
@@ -254,6 +252,7 @@ static const struct platform_profile_ops dell_pc_platform_profile_ops = {
254252

255253
static int thermal_init(void)
256254
{
255+
struct device *ppdev;
257256
int ret;
258257

259258
/* If thermal commands are not supported, exit without error */
@@ -271,25 +270,15 @@ static int thermal_init(void)
271270
if (IS_ERR(platform_device))
272271
return PTR_ERR(platform_device);
273272

274-
thermal_handler = devm_kzalloc(&platform_device->dev, sizeof(*thermal_handler), GFP_KERNEL);
275-
if (!thermal_handler) {
276-
ret = -ENOMEM;
273+
ppdev = devm_platform_profile_register(&platform_device->dev, "dell-pc",
274+
NULL, &dell_pc_platform_profile_ops);
275+
if (IS_ERR(ppdev)) {
276+
ret = PTR_ERR(ppdev);
277277
goto cleanup_platform_device;
278278
}
279-
thermal_handler->name = "dell-pc";
280-
thermal_handler->dev = &platform_device->dev;
281-
thermal_handler->ops = &dell_pc_platform_profile_ops;
282-
283-
/* Clean up if failed */
284-
ret = devm_platform_profile_register(thermal_handler, NULL);
285-
if (ret)
286-
goto cleanup_thermal_handler;
287279

288280
return 0;
289281

290-
cleanup_thermal_handler:
291-
thermal_handler = NULL;
292-
293282
cleanup_platform_device:
294283
platform_device_unregister(platform_device);
295284

0 commit comments

Comments
 (0)