From: Rafael J. Wysocki Date: Sun, 1 Mar 2026 13:18:49 +0000 (+0100) Subject: hwmon: (acpi_power_meter) Convert ACPI driver to a platform one X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=afc6c4aedea5717b7cb4a14b4bcc094892ea8d89;p=thirdparty%2Flinux.git hwmon: (acpi_power_meter) Convert ACPI driver to a platform one In all cases in which a struct acpi_driver is used for binding a driver to an ACPI device object, a corresponding platform device is created by the ACPI core and that device is regarded as a proper representation of underlying hardware. Accordingly, a struct platform_driver should be used by driver code to bind to that device. There are multiple reasons why drivers should not bind directly to ACPI device objects [1]. Overall, it is better to bind drivers to platform devices than to their ACPI companions, so convert the hwmon ACPI power meter driver to a platform one. After this change, the subordinate hwmon device will be registered under the platform device representing the ACPI power meter, sysfs notifications will trigger on that device, and diagnostic messages will be printed relative to it instead of its ACPI companion. Link: https://lore.kernel.org/all/2396510.ElGaqSPkdT@rafael.j.wysocki/ [1] Signed-off-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/1952740.tdWV9SEqCh@rafael.j.wysocki Signed-off-by: Guenter Roeck --- diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c index c010f55f7c7ba..be7f702dcde9c 100644 --- a/drivers/hwmon/acpi_power_meter.c +++ b/drivers/hwmon/acpi_power_meter.c @@ -18,6 +18,7 @@ #include #include #include +#include #define ACPI_POWER_METER_NAME "power_meter" #define ACPI_POWER_METER_DEVICE_NAME "Power Meter" @@ -816,8 +817,8 @@ end: /* Handle ACPI event notifications */ static void acpi_power_meter_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_device *device = data; - struct acpi_power_meter_resource *resource = acpi_driver_data(device); + struct device *dev = data; + struct acpi_power_meter_resource *resource = dev_get_drvdata(dev); int res; guard(mutex)(&acpi_notify_lock); @@ -833,43 +834,43 @@ static void acpi_power_meter_notify(acpi_handle handle, u32 event, void *data) remove_domain_devices(resource); res = read_capabilities(resource); if (res) - dev_err_once(&device->dev, "read capabilities failed.\n"); + dev_err_once(dev, "read capabilities failed.\n"); res = read_domain_devices(resource); if (res && res != -ENODEV) - dev_err_once(&device->dev, "read domain devices failed.\n"); + dev_err_once(dev, "read domain devices failed.\n"); mutex_unlock(&resource->lock); resource->hwmon_dev = - hwmon_device_register_with_info(&device->dev, + hwmon_device_register_with_info(dev, ACPI_POWER_METER_NAME, resource, &power_meter_chip_info, power_extra_groups); if (IS_ERR(resource->hwmon_dev)) - dev_err_once(&device->dev, "register hwmon device failed.\n"); + dev_err_once(dev, "register hwmon device failed.\n"); break; case METER_NOTIFY_TRIP: - sysfs_notify(&device->dev.kobj, NULL, POWER_AVERAGE_NAME); + sysfs_notify(&dev->kobj, NULL, POWER_AVERAGE_NAME); break; case METER_NOTIFY_CAP: mutex_lock(&resource->lock); res = update_cap(resource); if (res) - dev_err_once(&device->dev, "update cap failed when capping value is changed.\n"); + dev_err_once(dev, "update cap failed when capping value is changed.\n"); mutex_unlock(&resource->lock); - sysfs_notify(&device->dev.kobj, NULL, POWER_CAP_NAME); + sysfs_notify(&dev->kobj, NULL, POWER_CAP_NAME); break; case METER_NOTIFY_INTERVAL: - sysfs_notify(&device->dev.kobj, NULL, POWER_AVG_INTERVAL_NAME); + sysfs_notify(&dev->kobj, NULL, POWER_AVG_INTERVAL_NAME); break; case METER_NOTIFY_CAPPING: mutex_lock(&resource->lock); resource->power_alarm = true; mutex_unlock(&resource->lock); - sysfs_notify(&device->dev.kobj, NULL, POWER_ALARM_NAME); - dev_info(&device->dev, "Capping in progress.\n"); + sysfs_notify(&dev->kobj, NULL, POWER_ALARM_NAME); + dev_info(dev, "Capping in progress.\n"); break; default: WARN(1, "Unexpected event %d\n", event); @@ -877,16 +878,15 @@ static void acpi_power_meter_notify(acpi_handle handle, u32 event, void *data) } acpi_bus_generate_netlink_event(ACPI_POWER_METER_CLASS, - dev_name(&device->dev), event, 0); + dev_name(&resource->acpi_dev->dev), + event, 0); } -static int acpi_power_meter_add(struct acpi_device *device) +static int acpi_power_meter_probe(struct platform_device *pdev) { - int res; + struct acpi_device *device = ACPI_COMPANION(&pdev->dev); struct acpi_power_meter_resource *resource; - - if (!device) - return -EINVAL; + int res; resource = kzalloc_obj(*resource); if (!resource) @@ -897,7 +897,8 @@ static int acpi_power_meter_add(struct acpi_device *device) mutex_init(&resource->lock); strscpy(acpi_device_name(device), ACPI_POWER_METER_DEVICE_NAME); strscpy(acpi_device_class(device), ACPI_POWER_METER_CLASS); - device->driver_data = resource; + + platform_set_drvdata(pdev, resource); #if IS_REACHABLE(CONFIG_ACPI_IPMI) /* @@ -910,7 +911,7 @@ static int acpi_power_meter_add(struct acpi_device *device) struct acpi_device *ipi_device = acpi_dev_get_first_match_dev("IPI0001", NULL, -1); if (ipi_device && acpi_wait_for_acpi_ipmi()) - dev_warn(&device->dev, "Waiting for ACPI IPMI timeout"); + dev_warn(&pdev->dev, "Waiting for ACPI IPMI timeout"); acpi_dev_put(ipi_device); } #endif @@ -928,7 +929,7 @@ static int acpi_power_meter_add(struct acpi_device *device) goto exit_free_capability; resource->hwmon_dev = - hwmon_device_register_with_info(&device->dev, + hwmon_device_register_with_info(&pdev->dev, ACPI_POWER_METER_NAME, resource, &power_meter_chip_info, power_extra_groups); @@ -938,7 +939,7 @@ static int acpi_power_meter_add(struct acpi_device *device) } res = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY, - acpi_power_meter_notify, device); + acpi_power_meter_notify, &pdev->dev); if (res) goto exit_hwmon; @@ -957,11 +958,11 @@ exit: return res; } -static void acpi_power_meter_remove(struct acpi_device *device) +static void acpi_power_meter_remove(struct platform_device *pdev) { - struct acpi_power_meter_resource *resource = acpi_driver_data(device); + struct acpi_power_meter_resource *resource = platform_get_drvdata(pdev); - acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY, + acpi_dev_remove_notify_handler(resource->acpi_dev, ACPI_DEVICE_NOTIFY, acpi_power_meter_notify); if (!IS_ERR(resource->hwmon_dev)) @@ -975,9 +976,7 @@ static void acpi_power_meter_remove(struct acpi_device *device) static int acpi_power_meter_resume(struct device *dev) { - struct acpi_power_meter_resource *resource; - - resource = acpi_driver_data(to_acpi_device(dev)); + struct acpi_power_meter_resource *resource = dev_get_drvdata(dev); free_capabilities(resource); read_capabilities(resource); @@ -988,15 +987,14 @@ static int acpi_power_meter_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(acpi_power_meter_pm, NULL, acpi_power_meter_resume); -static struct acpi_driver acpi_power_meter_driver = { - .name = "power_meter", - .class = ACPI_POWER_METER_CLASS, - .ids = power_meter_ids, - .ops = { - .add = acpi_power_meter_add, - .remove = acpi_power_meter_remove, - }, - .drv.pm = pm_sleep_ptr(&acpi_power_meter_pm), +static struct platform_driver acpi_power_meter_driver = { + .probe = acpi_power_meter_probe, + .remove = acpi_power_meter_remove, + .driver = { + .name = "acpi-power-meter", + .acpi_match_table = power_meter_ids, + .pm = &acpi_power_meter_pm, + }, }; /* Module init/exit routines */ @@ -1025,7 +1023,7 @@ static int __init acpi_power_meter_init(void) dmi_check_system(pm_dmi_table); - result = acpi_bus_register_driver(&acpi_power_meter_driver); + result = platform_driver_register(&acpi_power_meter_driver); if (result < 0) return result; @@ -1034,7 +1032,7 @@ static int __init acpi_power_meter_init(void) static void __exit acpi_power_meter_exit(void) { - acpi_bus_unregister_driver(&acpi_power_meter_driver); + platform_driver_unregister(&acpi_power_meter_driver); } MODULE_AUTHOR("Darrick J. Wong ");