* [RFT][PATCH v1 1/6] ACPI: EC: Register a platform device for ECDT EC
2025-12-11 14:15 [RFT][PATCH v1 0/6] ACPI: Convert remaining ACPI drivers in drivers/acpi/ to platform drivers Rafael J. Wysocki
@ 2025-12-11 14:16 ` Rafael J. Wysocki
2025-12-11 14:17 ` [RFT][PATCH v1 2/6] ACPI: EC: Convert the driver to a platform one Rafael J. Wysocki
` (4 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Rafael J. Wysocki @ 2025-12-11 14:16 UTC (permalink / raw)
To: Linux ACPI; +Cc: LKML, Linux PM, Armin Wolf, Hans de Goede
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
To facilitate converting the ACPI EC driver into a platform one,
modify acpi_bus_register_early_device(), used by acpi_ec_ecdt_start()
for creating a struct acpi_device to represent the "early" EC based
on the ECDT ACPI table, to carry out the default ACPI enumeration for
the given device which will cause a platform device to be registered
for it.
No intentional functional impact.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/acpi/scan.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -2643,6 +2643,8 @@ int acpi_bus_register_early_device(int t
if (result)
return result;
+ acpi_default_enumeration(device);
+
device->flags.match_driver = true;
return device_attach(&device->dev);
}
^ permalink raw reply [flat|nested] 12+ messages in thread* [RFT][PATCH v1 2/6] ACPI: EC: Convert the driver to a platform one
2025-12-11 14:15 [RFT][PATCH v1 0/6] ACPI: Convert remaining ACPI drivers in drivers/acpi/ to platform drivers Rafael J. Wysocki
2025-12-11 14:16 ` [RFT][PATCH v1 1/6] ACPI: EC: Register a platform device for ECDT EC Rafael J. Wysocki
@ 2025-12-11 14:17 ` Rafael J. Wysocki
2025-12-11 14:17 ` [RFT][PATCH v1 3/6] ACPI: SMBUS HC: " Rafael J. Wysocki
` (3 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Rafael J. Wysocki @ 2025-12-11 14:17 UTC (permalink / raw)
To: Linux ACPI; +Cc: LKML, Linux PM, Armin Wolf, Hans de Goede
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
While binding drivers directly to struct acpi_device objects allows
basic functionality to be provided, at least in the majority of cases,
there are some problems with it, related to general consistency, sysfs
layout, power management operation ordering, and code cleanliness.
Overall, it is better to bind drivers to platform devices than to their
ACPI companions, so convert the ACPI embedded controller (EC) driver
to a platform one.
After this conversion, acpi_bus_register_early_device() does not need
to attempt to bind an ACPI driver to the struct acpi_device created by
it, so update it accordingly.
While this is not expected to alter functionality, it changes sysfs
layout and so it will be visible to user space.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/acpi/ec.c | 54 ++++++++++++++++++++--------------------------------
drivers/acpi/scan.c | 6 +----
2 files changed, 23 insertions(+), 37 deletions(-)
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/list.h>
+#include <linux/platform_device.h>
#include <linux/printk.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
@@ -1674,8 +1675,9 @@ static int acpi_ec_setup(struct acpi_ec
return ret;
}
-static int acpi_ec_add(struct acpi_device *device)
+static int acpi_ec_probe(struct platform_device *pdev)
{
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
struct acpi_ec *ec;
int ret;
@@ -1730,6 +1732,8 @@ static int acpi_ec_add(struct acpi_devic
acpi_handle_info(ec->handle,
"EC: Used to handle transactions and events\n");
+ platform_set_drvdata(pdev, ec);
+ /* This is needed for the SMBUS HC driver to work. */
device->driver_data = ec;
ret = !!request_region(ec->data_addr, 1, "EC data");
@@ -1750,14 +1754,11 @@ err:
return ret;
}
-static void acpi_ec_remove(struct acpi_device *device)
+static void acpi_ec_remove(struct platform_device *pdev)
{
- struct acpi_ec *ec;
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
+ struct acpi_ec *ec = platform_get_drvdata(pdev);
- if (!device)
- return;
-
- ec = acpi_driver_data(device);
release_region(ec->data_addr, 1);
release_region(ec->command_addr, 1);
device->driver_data = NULL;
@@ -2095,8 +2096,7 @@ out:
#ifdef CONFIG_PM_SLEEP
static int acpi_ec_suspend(struct device *dev)
{
- struct acpi_ec *ec =
- acpi_driver_data(to_acpi_device(dev));
+ struct acpi_ec *ec = dev_get_drvdata(dev);
if (!pm_suspend_no_platform() && ec_freeze_events)
acpi_ec_disable_event(ec);
@@ -2105,7 +2105,7 @@ static int acpi_ec_suspend(struct device
static int acpi_ec_suspend_noirq(struct device *dev)
{
- struct acpi_ec *ec = acpi_driver_data(to_acpi_device(dev));
+ struct acpi_ec *ec = dev_get_drvdata(dev);
/*
* The SCI handler doesn't run at this point, so the GPE can be
@@ -2122,7 +2122,7 @@ static int acpi_ec_suspend_noirq(struct
static int acpi_ec_resume_noirq(struct device *dev)
{
- struct acpi_ec *ec = acpi_driver_data(to_acpi_device(dev));
+ struct acpi_ec *ec = dev_get_drvdata(dev);
acpi_ec_leave_noirq(ec);
@@ -2135,8 +2135,7 @@ static int acpi_ec_resume_noirq(struct d
static int acpi_ec_resume(struct device *dev)
{
- struct acpi_ec *ec =
- acpi_driver_data(to_acpi_device(dev));
+ struct acpi_ec *ec = dev_get_drvdata(dev);
acpi_ec_enable_event(ec);
return 0;
@@ -2265,15 +2264,14 @@ module_param_call(ec_event_clearing, par
NULL, 0644);
MODULE_PARM_DESC(ec_event_clearing, "Assumed SCI_EVT clearing timing");
-static struct acpi_driver acpi_ec_driver = {
- .name = "ec",
- .class = ACPI_EC_CLASS,
- .ids = ec_device_ids,
- .ops = {
- .add = acpi_ec_add,
- .remove = acpi_ec_remove,
- },
- .drv.pm = &acpi_ec_pm,
+static struct platform_driver acpi_ec_driver = {
+ .probe = acpi_ec_probe,
+ .remove = acpi_ec_remove,
+ .driver = {
+ .name = "acpi-ec",
+ .acpi_match_table = ec_device_ids,
+ .pm = &acpi_ec_pm,
+ },
};
static void acpi_ec_destroy_workqueues(void)
@@ -2378,17 +2376,7 @@ void __init acpi_ec_init(void)
}
/* Driver must be registered after acpi_ec_init_workqueues(). */
- acpi_bus_register_driver(&acpi_ec_driver);
+ platform_driver_register(&acpi_ec_driver);
acpi_ec_ecdt_start();
}
-
-/* EC driver currently not unloadable */
-#if 0
-static void __exit acpi_ec_exit(void)
-{
-
- acpi_bus_unregister_driver(&acpi_ec_driver);
- acpi_ec_destroy_workqueues();
-}
-#endif /* 0 */
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -2643,10 +2643,8 @@ int acpi_bus_register_early_device(int t
if (result)
return result;
- acpi_default_enumeration(device);
-
- device->flags.match_driver = true;
- return device_attach(&device->dev);
+ acpi_default_enumeration(device);;
+ return 0;
}
EXPORT_SYMBOL_GPL(acpi_bus_register_early_device);
^ permalink raw reply [flat|nested] 12+ messages in thread* [RFT][PATCH v1 3/6] ACPI: SMBUS HC: Convert the driver to a platform one
2025-12-11 14:15 [RFT][PATCH v1 0/6] ACPI: Convert remaining ACPI drivers in drivers/acpi/ to platform drivers Rafael J. Wysocki
2025-12-11 14:16 ` [RFT][PATCH v1 1/6] ACPI: EC: Register a platform device for ECDT EC Rafael J. Wysocki
2025-12-11 14:17 ` [RFT][PATCH v1 2/6] ACPI: EC: Convert the driver to a platform one Rafael J. Wysocki
@ 2025-12-11 14:17 ` Rafael J. Wysocki
2025-12-11 14:18 ` [RFT][PATCH v1 4/6] ACPI: SBS: " Rafael J. Wysocki
` (2 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Rafael J. Wysocki @ 2025-12-11 14:17 UTC (permalink / raw)
To: Linux ACPI; +Cc: LKML, Linux PM, Armin Wolf, Hans de Goede
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
While binding drivers directly to struct acpi_device objects allows
basic functionality to be provided, at least in the majority of cases,
there are some problems with it, related to general consistency, sysfs
layout, power management operation ordering, and code cleanliness.
Overall, it is better to bind drivers to platform devices than to their
ACPI companions, so convert the ACPI SMBUS HC driver to a platform one.
After this conversion, acpi_ec_probe() does not need to populate the
driver_data pointer of the EC platform device's ACPI companion any
more, so update it accordingly.
While this is not expected to alter functionality, it changes sysfs
layout and so it will be visible to user space.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/acpi/ec.c | 2 --
drivers/acpi/sbshc.c | 43 +++++++++++++++++++++----------------------
2 files changed, 21 insertions(+), 24 deletions(-)
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1733,8 +1733,6 @@ static int acpi_ec_probe(struct platform
"EC: Used to handle transactions and events\n");
platform_set_drvdata(pdev, ec);
- /* This is needed for the SMBUS HC driver to work. */
- device->driver_data = ec;
ret = !!request_region(ec->data_addr, 1, "EC data");
WARN(!ret, "Could not request EC data io port 0x%lx", ec->data_addr);
--- a/drivers/acpi/sbshc.c
+++ b/drivers/acpi/sbshc.c
@@ -13,6 +13,8 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
#include "sbshc.h"
#include "internal.h"
@@ -30,8 +32,8 @@ struct acpi_smb_hc {
bool done;
};
-static int acpi_smbus_hc_add(struct acpi_device *device);
-static void acpi_smbus_hc_remove(struct acpi_device *device);
+static int acpi_smbus_hc_probe(struct platform_device *pdev);
+static void acpi_smbus_hc_remove(struct platform_device *pdev);
static const struct acpi_device_id sbs_device_ids[] = {
{"ACPI0001", 0},
@@ -41,14 +43,13 @@ static const struct acpi_device_id sbs_d
MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
-static struct acpi_driver acpi_smb_hc_driver = {
- .name = "smbus_hc",
- .class = ACPI_SMB_HC_CLASS,
- .ids = sbs_device_ids,
- .ops = {
- .add = acpi_smbus_hc_add,
- .remove = acpi_smbus_hc_remove,
- },
+static struct platform_driver acpi_smb_hc_driver = {
+ .probe = acpi_smbus_hc_probe,
+ .remove = acpi_smbus_hc_remove,
+ .driver = {
+ .name = "acpi-smbus-hc",
+ .acpi_match_table = sbs_device_ids,
+ },
};
union acpi_smb_status {
@@ -237,15 +238,13 @@ static int smbus_alarm(void *context)
return 0;
}
-static int acpi_smbus_hc_add(struct acpi_device *device)
+static int acpi_smbus_hc_probe(struct platform_device *pdev)
{
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
int status;
unsigned long long val;
struct acpi_smb_hc *hc;
- if (!device)
- return -EINVAL;
-
status = acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
if (ACPI_FAILURE(status)) {
pr_err("error obtaining _EC.\n");
@@ -261,9 +260,12 @@ static int acpi_smbus_hc_add(struct acpi
mutex_init(&hc->lock);
init_waitqueue_head(&hc->wait);
- hc->ec = acpi_driver_data(acpi_dev_parent(device));
+ platform_set_drvdata(pdev, hc);
+
+ hc->ec = dev_get_drvdata(pdev->dev.parent);
hc->offset = (val >> 8) & 0xff;
hc->query_bit = val & 0xff;
+ /* This is needed for the SBS driver to work. */
device->driver_data = hc;
acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc);
@@ -273,21 +275,18 @@ static int acpi_smbus_hc_add(struct acpi
return 0;
}
-static void acpi_smbus_hc_remove(struct acpi_device *device)
+static void acpi_smbus_hc_remove(struct platform_device *pdev)
{
- struct acpi_smb_hc *hc;
-
- if (!device)
- return;
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
+ struct acpi_smb_hc *hc = platform_get_drvdata(pdev);
- hc = acpi_driver_data(device);
acpi_ec_remove_query_handler(hc->ec, hc->query_bit);
acpi_os_wait_events_complete();
kfree(hc);
device->driver_data = NULL;
}
-module_acpi_driver(acpi_smb_hc_driver);
+module_platform_driver(acpi_smb_hc_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alexey Starikovskiy");
^ permalink raw reply [flat|nested] 12+ messages in thread* [RFT][PATCH v1 4/6] ACPI: SBS: Convert the driver to a platform one
2025-12-11 14:15 [RFT][PATCH v1 0/6] ACPI: Convert remaining ACPI drivers in drivers/acpi/ to platform drivers Rafael J. Wysocki
` (2 preceding siblings ...)
2025-12-11 14:17 ` [RFT][PATCH v1 3/6] ACPI: SMBUS HC: " Rafael J. Wysocki
@ 2025-12-11 14:18 ` Rafael J. Wysocki
2025-12-11 14:19 ` [RFT][PATCH v1 5/6] ACPI: HED: " Rafael J. Wysocki
2025-12-11 14:22 ` [RFT][PATCH v1 6/6] ACPI: NFIT: core: " Rafael J. Wysocki
5 siblings, 0 replies; 12+ messages in thread
From: Rafael J. Wysocki @ 2025-12-11 14:18 UTC (permalink / raw)
To: Linux ACPI; +Cc: LKML, Linux PM, Armin Wolf, Hans de Goede
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
While binding drivers directly to struct acpi_device objects allows
basic functionality to be provided, at least in the majority of cases,
there are some problems with it, related to general consistency, sysfs
layout, power management operation ordering, and code cleanliness.
Overall, it is better to bind drivers to platform devices than to their
ACPI companions, so convert the ACPI smart battery subsystem (SBS)
driver to a platform one.
After this conversion, acpi_smbus_hc_probe() does not need to populate the
driver_data pointer of the SMBUS HC platform device's ACPI companion any
more, so update it accordingly.
While this is not expected to alter functionality, it changes sysfs
layout and so it will be visible to user space.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/acpi/sbs.c | 48 +++++++++++++++++++++---------------------------
drivers/acpi/sbshc.c | 2 --
2 files changed, 21 insertions(+), 29 deletions(-)
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -19,6 +19,7 @@
#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/delay.h>
+#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/platform_data/x86/apple.h>
#include <acpi/battery.h>
@@ -95,7 +96,7 @@ struct acpi_sbs {
#define to_acpi_sbs(x) power_supply_get_drvdata(x)
-static void acpi_sbs_remove(struct acpi_device *device);
+static void acpi_sbs_remove(struct platform_device *pdev);
static int acpi_battery_get_state(struct acpi_battery *battery);
static inline int battery_scale(int log)
@@ -628,8 +629,9 @@ static void acpi_sbs_callback(void *cont
}
}
-static int acpi_sbs_add(struct acpi_device *device)
+static int acpi_sbs_probe(struct platform_device *pdev)
{
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
struct acpi_sbs *sbs;
int result = 0;
int id;
@@ -642,11 +644,12 @@ static int acpi_sbs_add(struct acpi_devi
mutex_init(&sbs->lock);
- sbs->hc = acpi_driver_data(acpi_dev_parent(device));
+ platform_set_drvdata(pdev, sbs);
+
+ sbs->hc = dev_get_drvdata(pdev->dev.parent);
sbs->device = device;
strscpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
strscpy(acpi_device_class(device), ACPI_SBS_CLASS);
- device->driver_data = sbs;
result = acpi_charger_add(sbs);
if (result && result != -ENODEV)
@@ -670,20 +673,15 @@ static int acpi_sbs_add(struct acpi_devi
acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs);
end:
if (result)
- acpi_sbs_remove(device);
+ acpi_sbs_remove(pdev);
return result;
}
-static void acpi_sbs_remove(struct acpi_device *device)
+static void acpi_sbs_remove(struct platform_device *pdev)
{
- struct acpi_sbs *sbs;
+ struct acpi_sbs *sbs = platform_get_drvdata(pdev);
int id;
- if (!device)
- return;
- sbs = acpi_driver_data(device);
- if (!sbs)
- return;
mutex_lock(&sbs->lock);
acpi_smbus_unregister_callback(sbs->hc);
for (id = 0; id < MAX_SBS_BAT; ++id)
@@ -697,11 +695,7 @@ static void acpi_sbs_remove(struct acpi_
#ifdef CONFIG_PM_SLEEP
static int acpi_sbs_resume(struct device *dev)
{
- struct acpi_sbs *sbs;
- if (!dev)
- return -EINVAL;
- sbs = to_acpi_device(dev)->driver_data;
- acpi_sbs_callback(sbs);
+ acpi_sbs_callback(dev_get_drvdata(dev));
return 0;
}
#else
@@ -710,14 +704,14 @@ static int acpi_sbs_resume(struct device
static SIMPLE_DEV_PM_OPS(acpi_sbs_pm, NULL, acpi_sbs_resume);
-static struct acpi_driver acpi_sbs_driver = {
- .name = "sbs",
- .class = ACPI_SBS_CLASS,
- .ids = sbs_device_ids,
- .ops = {
- .add = acpi_sbs_add,
- .remove = acpi_sbs_remove,
- },
- .drv.pm = &acpi_sbs_pm,
+static struct platform_driver acpi_sbs_driver = {
+ .probe = acpi_sbs_probe,
+ .remove = acpi_sbs_remove,
+ .driver = {
+ .name = "acpi-sbs",
+ .acpi_match_table = sbs_device_ids,
+ .pm = &acpi_sbs_pm,
+ },
};
-module_acpi_driver(acpi_sbs_driver);
+
+module_platform_driver(acpi_sbs_driver);
--- a/drivers/acpi/sbshc.c
+++ b/drivers/acpi/sbshc.c
@@ -265,8 +265,6 @@ static int acpi_smbus_hc_probe(struct pl
hc->ec = dev_get_drvdata(pdev->dev.parent);
hc->offset = (val >> 8) & 0xff;
hc->query_bit = val & 0xff;
- /* This is needed for the SBS driver to work. */
- device->driver_data = hc;
acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc);
dev_info(&device->dev, "SBS HC: offset = 0x%0x, query_bit = 0x%0x\n",
^ permalink raw reply [flat|nested] 12+ messages in thread* [RFT][PATCH v1 5/6] ACPI: HED: Convert the driver to a platform one
2025-12-11 14:15 [RFT][PATCH v1 0/6] ACPI: Convert remaining ACPI drivers in drivers/acpi/ to platform drivers Rafael J. Wysocki
` (3 preceding siblings ...)
2025-12-11 14:18 ` [RFT][PATCH v1 4/6] ACPI: SBS: " Rafael J. Wysocki
@ 2025-12-11 14:19 ` Rafael J. Wysocki
2025-12-11 14:22 ` [RFT][PATCH v1 6/6] ACPI: NFIT: core: " Rafael J. Wysocki
5 siblings, 0 replies; 12+ messages in thread
From: Rafael J. Wysocki @ 2025-12-11 14:19 UTC (permalink / raw)
To: Linux ACPI; +Cc: LKML, Linux PM, Armin Wolf, Hans de Goede
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
While binding drivers directly to struct acpi_device objects allows
basic functionality to be provided, at least in the majority of cases,
there are some problems with it, related to general consistency, sysfs
layout, power management operation ordering, and code cleanliness.
Overall, it is better to bind drivers to platform devices than to their
ACPI companions, so convert the ACPI hardware error device (HED) driver
to a platform one.
While this is not expected to alter functionality, it changes sysfs
layout and so it will be visible to user space.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/acpi/hed.c | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
--- a/drivers/acpi/hed.c
+++ b/drivers/acpi/hed.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/acpi.h>
+#include <linux/platform_device.h>
#include <acpi/hed.h>
static const struct acpi_device_id acpi_hed_ids[] = {
@@ -47,8 +48,9 @@ static void acpi_hed_notify(acpi_handle
blocking_notifier_call_chain(&acpi_hed_notify_list, 0, NULL);
}
-static int acpi_hed_add(struct acpi_device *device)
+static int acpi_hed_probe(struct platform_device *pdev)
{
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
int err;
/* Only one hardware error device */
@@ -64,26 +66,27 @@ static int acpi_hed_add(struct acpi_devi
return err;
}
-static void acpi_hed_remove(struct acpi_device *device)
+static void acpi_hed_remove(struct platform_device *pdev)
{
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
+
acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY,
acpi_hed_notify);
hed_handle = NULL;
}
-static struct acpi_driver acpi_hed_driver = {
- .name = "hardware_error_device",
- .class = "hardware_error",
- .ids = acpi_hed_ids,
- .ops = {
- .add = acpi_hed_add,
- .remove = acpi_hed_remove,
+static struct platform_driver acpi_hed_driver = {
+ .probe = acpi_hed_probe,
+ .remove = acpi_hed_remove,
+ .driver = {
+ .name = "acpi-hardware-error-device",
+ .acpi_match_table = acpi_hed_ids,
},
};
static int __init acpi_hed_driver_init(void)
{
- return acpi_bus_register_driver(&acpi_hed_driver);
+ return platform_driver_register(&acpi_hed_driver);
}
subsys_initcall(acpi_hed_driver_init);
^ permalink raw reply [flat|nested] 12+ messages in thread* [RFT][PATCH v1 6/6] ACPI: NFIT: core: Convert the driver to a platform one
2025-12-11 14:15 [RFT][PATCH v1 0/6] ACPI: Convert remaining ACPI drivers in drivers/acpi/ to platform drivers Rafael J. Wysocki
` (4 preceding siblings ...)
2025-12-11 14:19 ` [RFT][PATCH v1 5/6] ACPI: HED: " Rafael J. Wysocki
@ 2025-12-11 14:22 ` Rafael J. Wysocki
2025-12-11 18:40 ` Alison Schofield
2025-12-12 23:04 ` Ira Weiny
5 siblings, 2 replies; 12+ messages in thread
From: Rafael J. Wysocki @ 2025-12-11 14:22 UTC (permalink / raw)
To: Linux ACPI
Cc: LKML, Linux PM, Armin Wolf, Hans de Goede, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, nvdimm
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
While binding drivers directly to struct acpi_device objects allows
basic functionality to be provided, at least in the majority of cases,
there are some problems with it, related to general consistency, sysfs
layout, power management operation ordering, and code cleanliness.
Overall, it is better to bind drivers to platform devices than to their
ACPI companions, so convert the ACPI NFIT core driver to a platform one.
While this is not expected to alter functionality, it changes sysfs
layout and so it will be visible to user space.
This change was mostly developed by Michal Wilczynski [1].
Linu: https://lore.kernel.org/linux-acpi/20231011083334.3987477-6-michal.wilczynski@intel.com/ [1]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/acpi/nfit/core.c | 34 ++++++++++++++++++----------------
1 file changed, 18 insertions(+), 16 deletions(-)
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -2,6 +2,7 @@
/*
* Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
*/
+#include <linux/platform_device.h>
#include <linux/list_sort.h>
#include <linux/libnvdimm.h>
#include <linux/module.h>
@@ -98,7 +99,7 @@ static struct acpi_device *to_acpi_dev(s
|| strcmp(nd_desc->provider_name, "ACPI.NFIT") != 0)
return NULL;
- return to_acpi_device(acpi_desc->dev);
+ return ACPI_COMPANION(acpi_desc->dev);
}
static int xlat_bus_status(void *buf, unsigned int cmd, u32 status)
@@ -3283,11 +3284,11 @@ static void acpi_nfit_put_table(void *ta
static void acpi_nfit_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_device *adev = data;
+ struct device *dev = data;
- device_lock(&adev->dev);
- __acpi_nfit_notify(&adev->dev, handle, event);
- device_unlock(&adev->dev);
+ device_lock(dev);
+ __acpi_nfit_notify(dev, handle, event);
+ device_unlock(dev);
}
static void acpi_nfit_remove_notify_handler(void *data)
@@ -3328,18 +3329,19 @@ void acpi_nfit_shutdown(void *data)
}
EXPORT_SYMBOL_GPL(acpi_nfit_shutdown);
-static int acpi_nfit_add(struct acpi_device *adev)
+static int acpi_nfit_probe(struct platform_device *pdev)
{
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
struct acpi_nfit_desc *acpi_desc;
- struct device *dev = &adev->dev;
+ struct device *dev = &pdev->dev;
+ struct acpi_device *adev = ACPI_COMPANION(dev);
struct acpi_table_header *tbl;
acpi_status status = AE_OK;
acpi_size sz;
int rc = 0;
rc = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
- acpi_nfit_notify, adev);
+ acpi_nfit_notify, dev);
if (rc)
return rc;
@@ -3369,7 +3371,7 @@ static int acpi_nfit_add(struct acpi_dev
acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL);
if (!acpi_desc)
return -ENOMEM;
- acpi_nfit_desc_init(acpi_desc, &adev->dev);
+ acpi_nfit_desc_init(acpi_desc, dev);
/* Save the acpi header for exporting the revision via sysfs */
acpi_desc->acpi_header = *tbl;
@@ -3474,11 +3476,11 @@ static const struct acpi_device_id acpi_
};
MODULE_DEVICE_TABLE(acpi, acpi_nfit_ids);
-static struct acpi_driver acpi_nfit_driver = {
- .name = KBUILD_MODNAME,
- .ids = acpi_nfit_ids,
- .ops = {
- .add = acpi_nfit_add,
+static struct platform_driver acpi_nfit_driver = {
+ .probe = acpi_nfit_probe,
+ .driver = {
+ .name = "acpi-nfit",
+ .acpi_match_table = acpi_nfit_ids,
},
};
@@ -3516,7 +3518,7 @@ static __init int nfit_init(void)
return -ENOMEM;
nfit_mce_register();
- ret = acpi_bus_register_driver(&acpi_nfit_driver);
+ ret = platform_driver_register(&acpi_nfit_driver);
if (ret) {
nfit_mce_unregister();
destroy_workqueue(nfit_wq);
@@ -3529,7 +3531,7 @@ static __init int nfit_init(void)
static __exit void nfit_exit(void)
{
nfit_mce_unregister();
- acpi_bus_unregister_driver(&acpi_nfit_driver);
+ platform_driver_unregister(&acpi_nfit_driver);
destroy_workqueue(nfit_wq);
WARN_ON(!list_empty(&acpi_descs));
}
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [RFT][PATCH v1 6/6] ACPI: NFIT: core: Convert the driver to a platform one
2025-12-11 14:22 ` [RFT][PATCH v1 6/6] ACPI: NFIT: core: " Rafael J. Wysocki
@ 2025-12-11 18:40 ` Alison Schofield
2025-12-11 19:11 ` Rafael J. Wysocki
2025-12-12 23:04 ` Ira Weiny
1 sibling, 1 reply; 12+ messages in thread
From: Alison Schofield @ 2025-12-11 18:40 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linux ACPI, LKML, Linux PM, Armin Wolf, Hans de Goede,
Dan Williams, Vishal Verma, Dave Jiang, Ira Weiny, nvdimm
On Thu, Dec 11, 2025 at 03:22:00PM +0100, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> While binding drivers directly to struct acpi_device objects allows
> basic functionality to be provided, at least in the majority of cases,
> there are some problems with it, related to general consistency, sysfs
> layout, power management operation ordering, and code cleanliness.
>
> Overall, it is better to bind drivers to platform devices than to their
> ACPI companions, so convert the ACPI NFIT core driver to a platform one.
>
> While this is not expected to alter functionality, it changes sysfs
> layout and so it will be visible to user space.
Changes sysfs layout? That means it changes sysfs paths?
Does it change paths defined in Documentation/ABI/testing/sysfs "What:"
>
> This change was mostly developed by Michal Wilczynski [1].
>
> Linu: https://lore.kernel.org/linux-acpi/20231011083334.3987477-6-michal.wilczynski@intel.com/ [1]
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
> drivers/acpi/nfit/core.c | 34 ++++++++++++++++++----------------
> 1 file changed, 18 insertions(+), 16 deletions(-)
>
> --- a/drivers/acpi/nfit/core.c
> +++ b/drivers/acpi/nfit/core.c
> @@ -2,6 +2,7 @@
> /*
> * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
> */
> +#include <linux/platform_device.h>
> #include <linux/list_sort.h>
> #include <linux/libnvdimm.h>
> #include <linux/module.h>
> @@ -98,7 +99,7 @@ static struct acpi_device *to_acpi_dev(s
> || strcmp(nd_desc->provider_name, "ACPI.NFIT") != 0)
> return NULL;
>
> - return to_acpi_device(acpi_desc->dev);
> + return ACPI_COMPANION(acpi_desc->dev);
> }
>
> static int xlat_bus_status(void *buf, unsigned int cmd, u32 status)
> @@ -3283,11 +3284,11 @@ static void acpi_nfit_put_table(void *ta
>
> static void acpi_nfit_notify(acpi_handle handle, u32 event, void *data)
> {
> - struct acpi_device *adev = data;
> + struct device *dev = data;
>
> - device_lock(&adev->dev);
> - __acpi_nfit_notify(&adev->dev, handle, event);
> - device_unlock(&adev->dev);
> + device_lock(dev);
> + __acpi_nfit_notify(dev, handle, event);
> + device_unlock(dev);
> }
>
> static void acpi_nfit_remove_notify_handler(void *data)
> @@ -3328,18 +3329,19 @@ void acpi_nfit_shutdown(void *data)
> }
> EXPORT_SYMBOL_GPL(acpi_nfit_shutdown);
>
> -static int acpi_nfit_add(struct acpi_device *adev)
> +static int acpi_nfit_probe(struct platform_device *pdev)
> {
> struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
> struct acpi_nfit_desc *acpi_desc;
> - struct device *dev = &adev->dev;
> + struct device *dev = &pdev->dev;
> + struct acpi_device *adev = ACPI_COMPANION(dev);
> struct acpi_table_header *tbl;
> acpi_status status = AE_OK;
> acpi_size sz;
> int rc = 0;
>
> rc = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
> - acpi_nfit_notify, adev);
> + acpi_nfit_notify, dev);
> if (rc)
> return rc;
>
> @@ -3369,7 +3371,7 @@ static int acpi_nfit_add(struct acpi_dev
> acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL);
> if (!acpi_desc)
> return -ENOMEM;
> - acpi_nfit_desc_init(acpi_desc, &adev->dev);
> + acpi_nfit_desc_init(acpi_desc, dev);
>
> /* Save the acpi header for exporting the revision via sysfs */
> acpi_desc->acpi_header = *tbl;
> @@ -3474,11 +3476,11 @@ static const struct acpi_device_id acpi_
> };
> MODULE_DEVICE_TABLE(acpi, acpi_nfit_ids);
>
> -static struct acpi_driver acpi_nfit_driver = {
> - .name = KBUILD_MODNAME,
> - .ids = acpi_nfit_ids,
> - .ops = {
> - .add = acpi_nfit_add,
> +static struct platform_driver acpi_nfit_driver = {
> + .probe = acpi_nfit_probe,
> + .driver = {
> + .name = "acpi-nfit",
> + .acpi_match_table = acpi_nfit_ids,
> },
> };
>
> @@ -3516,7 +3518,7 @@ static __init int nfit_init(void)
> return -ENOMEM;
>
> nfit_mce_register();
> - ret = acpi_bus_register_driver(&acpi_nfit_driver);
> + ret = platform_driver_register(&acpi_nfit_driver);
> if (ret) {
> nfit_mce_unregister();
> destroy_workqueue(nfit_wq);
> @@ -3529,7 +3531,7 @@ static __init int nfit_init(void)
> static __exit void nfit_exit(void)
> {
> nfit_mce_unregister();
> - acpi_bus_unregister_driver(&acpi_nfit_driver);
> + platform_driver_unregister(&acpi_nfit_driver);
> destroy_workqueue(nfit_wq);
> WARN_ON(!list_empty(&acpi_descs));
> }
>
>
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [RFT][PATCH v1 6/6] ACPI: NFIT: core: Convert the driver to a platform one
2025-12-11 18:40 ` Alison Schofield
@ 2025-12-11 19:11 ` Rafael J. Wysocki
0 siblings, 0 replies; 12+ messages in thread
From: Rafael J. Wysocki @ 2025-12-11 19:11 UTC (permalink / raw)
To: Alison Schofield
Cc: Rafael J. Wysocki, Linux ACPI, LKML, Linux PM, Armin Wolf,
Hans de Goede, Dan Williams, Vishal Verma, Dave Jiang, Ira Weiny,
nvdimm
On Thu, Dec 11, 2025 at 7:40 PM Alison Schofield
<alison.schofield@intel.com> wrote:
>
> On Thu, Dec 11, 2025 at 03:22:00PM +0100, Rafael J. Wysocki wrote:
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >
> > While binding drivers directly to struct acpi_device objects allows
> > basic functionality to be provided, at least in the majority of cases,
> > there are some problems with it, related to general consistency, sysfs
> > layout, power management operation ordering, and code cleanliness.
> >
> > Overall, it is better to bind drivers to platform devices than to their
> > ACPI companions, so convert the ACPI NFIT core driver to a platform one.
> >
> > While this is not expected to alter functionality, it changes sysfs
> > layout and so it will be visible to user space.
>
> Changes sysfs layout? That means it changes sysfs paths?
> Does it change paths defined in Documentation/ABI/testing/sysfs "What:"
No, it doesn't AFAICS.
It changes things like /sys/bus/platform/drivers/ for instance and the like.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFT][PATCH v1 6/6] ACPI: NFIT: core: Convert the driver to a platform one
2025-12-11 14:22 ` [RFT][PATCH v1 6/6] ACPI: NFIT: core: " Rafael J. Wysocki
2025-12-11 18:40 ` Alison Schofield
@ 2025-12-12 23:04 ` Ira Weiny
2025-12-14 14:25 ` [PATCH v2] " Rafael J. Wysocki
1 sibling, 1 reply; 12+ messages in thread
From: Ira Weiny @ 2025-12-12 23:04 UTC (permalink / raw)
To: Rafael J. Wysocki, Linux ACPI
Cc: LKML, Linux PM, Armin Wolf, Hans de Goede, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, nvdimm
Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> While binding drivers directly to struct acpi_device objects allows
> basic functionality to be provided, at least in the majority of cases,
> there are some problems with it, related to general consistency, sysfs
> layout, power management operation ordering, and code cleanliness.
>
> Overall, it is better to bind drivers to platform devices than to their
> ACPI companions, so convert the ACPI NFIT core driver to a platform one.
>
> While this is not expected to alter functionality, it changes sysfs
> layout and so it will be visible to user space.
I'm not sure right off why but when I run the libndctl test with this patch I
get the following panic.
[ 17.483472] BUG: kernel NULL pointer dereference, address: 0000000000000008
[ 17.484116] #PF: supervisor read access in kernel mode
[ 17.484593] #PF: error_code(0x0000) - not-present page
[ 17.485056] PGD 9def067 P4D 9def067 PUD 9df3067 PMD 0
[ 17.485516] Oops: Oops: 0000 [#1] SMP NOPTI
[ 17.485886] CPU: 2 UID: 0 PID: 1191 Comm: libndctl Tainted: G O 6.18.0ira+ #34 PREEMPT(voluntary)
[ 17.486804] Tainted: [O]=OOT_MODULE
[ 17.487125] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS edk2-20250812-18.fc42 08/12/2025
[ 17.487749] RIP: 0010:acpi_nfit_ctl+0x40b/0xa00 [nfit]
[ 17.488222] Code: 48 48 c7 44 24 28 28 f1 8c a1 48 8b 83 c8 01 00 00 44 89 e7 48 89 44 24 50 e8 01 83 fd ff 48 c7 44 24 40 10 58 8c a1 48 89 c3 <49> 8b 47 08 48 c7 44 24 30 30 f1 8c a1 48 89 44 24 18 e9 24 fd
ff
[ 17.491668] RSP: 0018:ffffc9000f11ba28 EFLAGS: 00010286
[ 17.492422] RAX: ffffffffa18679f0 RBX: ffffffffa18679f0 RCX: ffffc9000f11bb40
[ 17.492903] RDX: 000000000000041e RSI: ffffffffa18cf116 RDI: 0000000000000003
[ 17.493408] RBP: ffffc9000f11bb40 R08: 0000000000000008 R09: ffffc9000f11bafc
[ 17.493888] R10: ffffc9000f11bae0 R11: 0000000000004019 R12: 0000000000000003
[ 17.494396] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[ 17.494878] FS: 00007f432f5fd7c0(0000) GS:ffff8880f9fdd000(0000) knlGS:0000000000000000
[ 17.495436] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 17.495826] CR2: 0000000000000008 CR3: 0000000009e0c005 CR4: 0000000000770ef0
[ 17.496324] PKRU: 55555554
[ 17.496516] Call Trace:
[ 17.496691] <TASK>
[ 17.496844] ? __kmalloc_noprof+0x410/0x650
[ 17.497138] ? setup_result+0x1b/0xa0 [nfit_test]
[ 17.497474] nfit_ctl_test+0x21a/0x780 [nfit_test]
[ 17.497803] ? preempt_count_add+0x51/0xd0
[ 17.498086] ? up_write+0x13/0x60
[ 17.498333] ? up_write+0x35/0x60
[ 17.498565] ? preempt_count_add+0x51/0xd0
[ 17.498846] ? kernfs_next_descendant_post+0x1b/0xe0
[ 17.499196] nfit_test_probe+0x350/0x4d0 [nfit_test]
[ 17.499535] platform_probe+0x38/0x70
[ 17.499791] really_probe+0xde/0x380
[ 17.500039] ? _raw_spin_unlock_irq+0x18/0x40
[ 17.500354] __driver_probe_device+0xc0/0x150
[ 17.500656] driver_probe_device+0x1f/0xa0 [ 17.500939] ? __pfx___driver_attach+0x10/0x10
[ 17.501263] __driver_attach+0xc7/0x200
[ 17.501529] bus_for_each_dev+0x63/0xa0
[ 17.501794] bus_add_driver+0x114/0x200
[ 17.502059] driver_register+0x71/0xe0
[ 17.502480] nfit_test_init+0x24e/0xff0 [nfit_test]
[ 17.502956] ? __pfx_nfit_test_init+0x10/0x10 [nfit_test]
[ 17.503483] do_one_initcall+0x42/0x210
[ 17.503891] do_init_module+0x62/0x230
[ 17.504296] init_module_from_file+0xb1/0xe0
[ 17.504732] idempotent_init_module+0xed/0x2d0
[ 17.505184] __x64_sys_finit_module+0x6d/0xe0
[ 17.505626] do_syscall_64+0x62/0x390
[ 17.506016] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 17.506563] RIP: 0033:0x7f432f8920cd
[ 17.506946] Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 03 4d 0f 00 f7 d8 64 89 01
48
[ 17.508548] RSP: 002b:00007fff0a6ccd98 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
[ 17.509209] RAX: ffffffffffffffda RBX: 000000001f5def50 RCX: 00007f432f8920cd
[ 17.509831] RDX: 0000000000000000 RSI: 00007f432f9aa965 RDI: 0000000000000003 [ 17.510472] RBP: 00007fff0a6cce50 R08: 0000000000000000 R09: 00007fff0a6cce00
[ 17.511091] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000020000
[ 17.511727] R13: 000000001f5deb60 R14: 00007f432f9aa965 R15: 0000000000000000
[ 17.512353] </TASK>
[ 17.512638] Modules linked in: nfit_test(O+) device_dax(O) nd_pmem(O) dax_pmem(O) kmem nd_btt(O) nfit(O) dax_cxl cxl_pci nd_e820(O) cxl_mock_mem(O) cxl_test(O) cxl_mem(O) cxl_pmem(O) cxl_acpi(O) cxl_port(O) cx
l_mock(O) libnvdimm(O) nfit_test_iomap(O) cxl_core(O) fwctl
[ 17.514512] CR2: 0000000000000008
[ 17.514878] ---[ end trace 0000000000000000 ]---
I'll try and find some time to dig into it but perhaps yall have a quick
idea of what it could be?
Ira
>
> This change was mostly developed by Michal Wilczynski [1].
>
> Linu: https://lore.kernel.org/linux-acpi/20231011083334.3987477-6-michal.wilczynski@intel.com/ [1]
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
> drivers/acpi/nfit/core.c | 34 ++++++++++++++++++----------------
> 1 file changed, 18 insertions(+), 16 deletions(-)
>
> --- a/drivers/acpi/nfit/core.c
> +++ b/drivers/acpi/nfit/core.c
> @@ -2,6 +2,7 @@
> /*
> * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
> */
> +#include <linux/platform_device.h>
> #include <linux/list_sort.h>
> #include <linux/libnvdimm.h>
> #include <linux/module.h>
> @@ -98,7 +99,7 @@ static struct acpi_device *to_acpi_dev(s
> || strcmp(nd_desc->provider_name, "ACPI.NFIT") != 0)
> return NULL;
>
> - return to_acpi_device(acpi_desc->dev);
> + return ACPI_COMPANION(acpi_desc->dev);
> }
>
> static int xlat_bus_status(void *buf, unsigned int cmd, u32 status)
> @@ -3283,11 +3284,11 @@ static void acpi_nfit_put_table(void *ta
>
> static void acpi_nfit_notify(acpi_handle handle, u32 event, void *data)
> {
> - struct acpi_device *adev = data;
> + struct device *dev = data;
>
> - device_lock(&adev->dev);
> - __acpi_nfit_notify(&adev->dev, handle, event);
> - device_unlock(&adev->dev);
> + device_lock(dev);
> + __acpi_nfit_notify(dev, handle, event);
> + device_unlock(dev);
> }
>
> static void acpi_nfit_remove_notify_handler(void *data)
> @@ -3328,18 +3329,19 @@ void acpi_nfit_shutdown(void *data)
> }
> EXPORT_SYMBOL_GPL(acpi_nfit_shutdown);
>
> -static int acpi_nfit_add(struct acpi_device *adev)
> +static int acpi_nfit_probe(struct platform_device *pdev)
> {
> struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
> struct acpi_nfit_desc *acpi_desc;
> - struct device *dev = &adev->dev;
> + struct device *dev = &pdev->dev;
> + struct acpi_device *adev = ACPI_COMPANION(dev);
> struct acpi_table_header *tbl;
> acpi_status status = AE_OK;
> acpi_size sz;
> int rc = 0;
>
> rc = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
> - acpi_nfit_notify, adev);
> + acpi_nfit_notify, dev);
> if (rc)
> return rc;
>
> @@ -3369,7 +3371,7 @@ static int acpi_nfit_add(struct acpi_dev
> acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL);
> if (!acpi_desc)
> return -ENOMEM;
> - acpi_nfit_desc_init(acpi_desc, &adev->dev);
> + acpi_nfit_desc_init(acpi_desc, dev);
>
> /* Save the acpi header for exporting the revision via sysfs */
> acpi_desc->acpi_header = *tbl;
> @@ -3474,11 +3476,11 @@ static const struct acpi_device_id acpi_
> };
> MODULE_DEVICE_TABLE(acpi, acpi_nfit_ids);
>
> -static struct acpi_driver acpi_nfit_driver = {
> - .name = KBUILD_MODNAME,
> - .ids = acpi_nfit_ids,
> - .ops = {
> - .add = acpi_nfit_add,
> +static struct platform_driver acpi_nfit_driver = {
> + .probe = acpi_nfit_probe,
> + .driver = {
> + .name = "acpi-nfit",
> + .acpi_match_table = acpi_nfit_ids,
> },
> };
>
> @@ -3516,7 +3518,7 @@ static __init int nfit_init(void)
> return -ENOMEM;
>
> nfit_mce_register();
> - ret = acpi_bus_register_driver(&acpi_nfit_driver);
> + ret = platform_driver_register(&acpi_nfit_driver);
> if (ret) {
> nfit_mce_unregister();
> destroy_workqueue(nfit_wq);
> @@ -3529,7 +3531,7 @@ static __init int nfit_init(void)
> static __exit void nfit_exit(void)
> {
> nfit_mce_unregister();
> - acpi_bus_unregister_driver(&acpi_nfit_driver);
> + platform_driver_unregister(&acpi_nfit_driver);
> destroy_workqueue(nfit_wq);
> WARN_ON(!list_empty(&acpi_descs));
> }
>
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v2] ACPI: NFIT: core: Convert the driver to a platform one
2025-12-12 23:04 ` Ira Weiny
@ 2025-12-14 14:25 ` Rafael J. Wysocki
2025-12-14 18:25 ` [PATCH v3] " Rafael J. Wysocki
0 siblings, 1 reply; 12+ messages in thread
From: Rafael J. Wysocki @ 2025-12-14 14:25 UTC (permalink / raw)
To: Linux ACPI, Ira Weiny
Cc: LKML, Linux PM, Armin Wolf, Hans de Goede, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, nvdimm
On Saturday, December 13, 2025 12:04:02 AM CET Ira Weiny wrote:
> Rafael J. Wysocki wrote:
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >
> > While binding drivers directly to struct acpi_device objects allows
> > basic functionality to be provided, at least in the majority of cases,
> > there are some problems with it, related to general consistency, sysfs
> > layout, power management operation ordering, and code cleanliness.
> >
> > Overall, it is better to bind drivers to platform devices than to their
> > ACPI companions, so convert the ACPI NFIT core driver to a platform one.
> >
> > While this is not expected to alter functionality, it changes sysfs
> > layout and so it will be visible to user space.
>
> I'm not sure right off why but when I run the libndctl test with this patch I
> get the following panic.
>
> [ 17.483472] BUG: kernel NULL pointer dereference, address: 0000000000000008
> [ 17.484116] #PF: supervisor read access in kernel mode
> [ 17.484593] #PF: error_code(0x0000) - not-present page
> [ 17.485056] PGD 9def067 P4D 9def067 PUD 9df3067 PMD 0
> [ 17.485516] Oops: Oops: 0000 [#1] SMP NOPTI
> [ 17.485886] CPU: 2 UID: 0 PID: 1191 Comm: libndctl Tainted: G O 6.18.0ira+ #34 PREEMPT(voluntary)
> [ 17.486804] Tainted: [O]=OOT_MODULE
> [ 17.487125] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS edk2-20250812-18.fc42 08/12/2025
> [ 17.487749] RIP: 0010:acpi_nfit_ctl+0x40b/0xa00 [nfit]
> [ 17.488222] Code: 48 48 c7 44 24 28 28 f1 8c a1 48 8b 83 c8 01 00 00 44 89 e7 48 89 44 24 50 e8 01 83 fd ff 48 c7 44 24 40 10 58 8c a1 48 89 c3 <49> 8b 47 08 48 c7 44 24 30 30 f1 8c a1 48 89 44 24 18 e9 24 fd
> ff
> [ 17.491668] RSP: 0018:ffffc9000f11ba28 EFLAGS: 00010286
> [ 17.492422] RAX: ffffffffa18679f0 RBX: ffffffffa18679f0 RCX: ffffc9000f11bb40
> [ 17.492903] RDX: 000000000000041e RSI: ffffffffa18cf116 RDI: 0000000000000003
> [ 17.493408] RBP: ffffc9000f11bb40 R08: 0000000000000008 R09: ffffc9000f11bafc
> [ 17.493888] R10: ffffc9000f11bae0 R11: 0000000000004019 R12: 0000000000000003
> [ 17.494396] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
> [ 17.494878] FS: 00007f432f5fd7c0(0000) GS:ffff8880f9fdd000(0000) knlGS:0000000000000000
> [ 17.495436] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 17.495826] CR2: 0000000000000008 CR3: 0000000009e0c005 CR4: 0000000000770ef0
> [ 17.496324] PKRU: 55555554
> [ 17.496516] Call Trace:
> [ 17.496691] <TASK>
> [ 17.496844] ? __kmalloc_noprof+0x410/0x650
> [ 17.497138] ? setup_result+0x1b/0xa0 [nfit_test]
> [ 17.497474] nfit_ctl_test+0x21a/0x780 [nfit_test]
> [ 17.497803] ? preempt_count_add+0x51/0xd0
> [ 17.498086] ? up_write+0x13/0x60
> [ 17.498333] ? up_write+0x35/0x60
> [ 17.498565] ? preempt_count_add+0x51/0xd0
> [ 17.498846] ? kernfs_next_descendant_post+0x1b/0xe0
> [ 17.499196] nfit_test_probe+0x350/0x4d0 [nfit_test]
> [ 17.499535] platform_probe+0x38/0x70
> [ 17.499791] really_probe+0xde/0x380
> [ 17.500039] ? _raw_spin_unlock_irq+0x18/0x40
> [ 17.500354] __driver_probe_device+0xc0/0x150
> [ 17.500656] driver_probe_device+0x1f/0xa0 [ 17.500939] ? __pfx___driver_attach+0x10/0x10
> [ 17.501263] __driver_attach+0xc7/0x200
> [ 17.501529] bus_for_each_dev+0x63/0xa0
> [ 17.501794] bus_add_driver+0x114/0x200
> [ 17.502059] driver_register+0x71/0xe0
> [ 17.502480] nfit_test_init+0x24e/0xff0 [nfit_test]
> [ 17.502956] ? __pfx_nfit_test_init+0x10/0x10 [nfit_test]
> [ 17.503483] do_one_initcall+0x42/0x210
> [ 17.503891] do_init_module+0x62/0x230
> [ 17.504296] init_module_from_file+0xb1/0xe0
> [ 17.504732] idempotent_init_module+0xed/0x2d0
> [ 17.505184] __x64_sys_finit_module+0x6d/0xe0
> [ 17.505626] do_syscall_64+0x62/0x390
> [ 17.506016] entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [ 17.506563] RIP: 0033:0x7f432f8920cd
> [ 17.506946] Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 03 4d 0f 00 f7 d8 64 89 01
> 48
> [ 17.508548] RSP: 002b:00007fff0a6ccd98 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
> [ 17.509209] RAX: ffffffffffffffda RBX: 000000001f5def50 RCX: 00007f432f8920cd
> [ 17.509831] RDX: 0000000000000000 RSI: 00007f432f9aa965 RDI: 0000000000000003 [ 17.510472] RBP: 00007fff0a6cce50 R08: 0000000000000000 R09: 00007fff0a6cce00
> [ 17.511091] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000020000
> [ 17.511727] R13: 000000001f5deb60 R14: 00007f432f9aa965 R15: 0000000000000000
> [ 17.512353] </TASK>
> [ 17.512638] Modules linked in: nfit_test(O+) device_dax(O) nd_pmem(O) dax_pmem(O) kmem nd_btt(O) nfit(O) dax_cxl cxl_pci nd_e820(O) cxl_mock_mem(O) cxl_test(O) cxl_mem(O) cxl_pmem(O) cxl_acpi(O) cxl_port(O) cx
> l_mock(O) libnvdimm(O) nfit_test_iomap(O) cxl_core(O) fwctl
> [ 17.514512] CR2: 0000000000000008
> [ 17.514878] ---[ end trace 0000000000000000 ]---
>
>
> I'll try and find some time to dig into it but perhaps yall have a quick
> idea of what it could be?
>
> Ira
>
> >
> > This change was mostly developed by Michal Wilczynski [1].
> >
> > Linu: https://lore.kernel.org/linux-acpi/20231011083334.3987477-6-michal.wilczynski@intel.com/ [1]
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> > drivers/acpi/nfit/core.c | 34 ++++++++++++++++++----------------
> > 1 file changed, 18 insertions(+), 16 deletions(-)
> >
> > --- a/drivers/acpi/nfit/core.c
> > +++ b/drivers/acpi/nfit/core.c
> > @@ -2,6 +2,7 @@
> > /*
> > * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
> > */
> > +#include <linux/platform_device.h>
> > #include <linux/list_sort.h>
> > #include <linux/libnvdimm.h>
> > #include <linux/module.h>
> > @@ -98,7 +99,7 @@ static struct acpi_device *to_acpi_dev(s
> > || strcmp(nd_desc->provider_name, "ACPI.NFIT") != 0)
> > return NULL;
> >
> > - return to_acpi_device(acpi_desc->dev);
> > + return ACPI_COMPANION(acpi_desc->dev);
> > }
It's likely this change and it is not even necessary.
If possible, please check the v2 below.
---
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Subject: [PATCH v2] ACPI: NFIT: core: Convert the driver to a platform one
While binding drivers directly to struct acpi_device objects allows
basic functionality to be provided, at least in the majority of cases,
there are some problems with it, related to general consistency, sysfs
layout, power management operation ordering, and code cleanliness.
Overall, it is better to bind drivers to platform devices than to their
ACPI companions, so convert the ACPI NFIT core driver to a platform one.
While this is not expected to alter functionality, it changes sysfs
layout and so it will be visible to user space.
This change is based on an earlier one from Michal Wilczynski [1].
Linu: https://lore.kernel.org/linux-acpi/20231011083334.3987477-6-michal.wilczynski@intel.com/ [1]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/acpi/nfit/core.c | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -2,6 +2,7 @@
/*
* Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
*/
+#include <linux/platform_device.h>
#include <linux/list_sort.h>
#include <linux/libnvdimm.h>
#include <linux/module.h>
@@ -3328,9 +3329,10 @@ void acpi_nfit_shutdown(void *data)
}
EXPORT_SYMBOL_GPL(acpi_nfit_shutdown);
-static int acpi_nfit_add(struct acpi_device *adev)
+static int acpi_nfit_probe(struct platform_device *pdev)
{
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
struct acpi_nfit_desc *acpi_desc;
struct device *dev = &adev->dev;
struct acpi_table_header *tbl;
@@ -3343,7 +3345,7 @@ static int acpi_nfit_add(struct acpi_dev
if (rc)
return rc;
- rc = devm_add_action_or_reset(dev, acpi_nfit_remove_notify_handler,
+ rc = devm_add_action_or_reset(&pdev->dev, acpi_nfit_remove_notify_handler,
adev);
if (rc)
return rc;
@@ -3361,12 +3363,12 @@ static int acpi_nfit_add(struct acpi_dev
return 0;
}
- rc = devm_add_action_or_reset(dev, acpi_nfit_put_table, tbl);
+ rc = devm_add_action_or_reset(&pdev->dev, acpi_nfit_put_table, tbl);
if (rc)
return rc;
sz = tbl->length;
- acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL);
+ acpi_desc = devm_kzalloc(&pdev->dev, sizeof(*acpi_desc), GFP_KERNEL);
if (!acpi_desc)
return -ENOMEM;
acpi_nfit_desc_init(acpi_desc, &adev->dev);
@@ -3395,7 +3397,7 @@ static int acpi_nfit_add(struct acpi_dev
if (rc)
return rc;
- return devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc);
+ return devm_add_action_or_reset(&pdev->dev, acpi_nfit_shutdown, acpi_desc);
}
static void acpi_nfit_update_notify(struct device *dev, acpi_handle handle)
@@ -3474,11 +3476,11 @@ static const struct acpi_device_id acpi_
};
MODULE_DEVICE_TABLE(acpi, acpi_nfit_ids);
-static struct acpi_driver acpi_nfit_driver = {
- .name = KBUILD_MODNAME,
- .ids = acpi_nfit_ids,
- .ops = {
- .add = acpi_nfit_add,
+static struct platform_driver acpi_nfit_driver = {
+ .probe = acpi_nfit_probe,
+ .driver = {
+ .name = "acpi-nfit",
+ .acpi_match_table = acpi_nfit_ids,
},
};
@@ -3516,7 +3518,7 @@ static __init int nfit_init(void)
return -ENOMEM;
nfit_mce_register();
- ret = acpi_bus_register_driver(&acpi_nfit_driver);
+ ret = platform_driver_register(&acpi_nfit_driver);
if (ret) {
nfit_mce_unregister();
destroy_workqueue(nfit_wq);
@@ -3529,7 +3531,7 @@ static __init int nfit_init(void)
static __exit void nfit_exit(void)
{
nfit_mce_unregister();
- acpi_bus_unregister_driver(&acpi_nfit_driver);
+ platform_driver_unregister(&acpi_nfit_driver);
destroy_workqueue(nfit_wq);
WARN_ON(!list_empty(&acpi_descs));
}
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v3] ACPI: NFIT: core: Convert the driver to a platform one
2025-12-14 14:25 ` [PATCH v2] " Rafael J. Wysocki
@ 2025-12-14 18:25 ` Rafael J. Wysocki
0 siblings, 0 replies; 12+ messages in thread
From: Rafael J. Wysocki @ 2025-12-14 18:25 UTC (permalink / raw)
To: Linux ACPI, Ira Weiny
Cc: LKML, Linux PM, Armin Wolf, Hans de Goede, Dan Williams,
Vishal Verma, Dave Jiang, Ira Weiny, nvdimm
On Sunday, December 14, 2025 3:25:04 PM CET Rafael J. Wysocki wrote:
> On Saturday, December 13, 2025 12:04:02 AM CET Ira Weiny wrote:
> > Rafael J. Wysocki wrote:
> > > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > >
> > > While binding drivers directly to struct acpi_device objects allows
> > > basic functionality to be provided, at least in the majority of cases,
> > > there are some problems with it, related to general consistency, sysfs
> > > layout, power management operation ordering, and code cleanliness.
> > >
> > > Overall, it is better to bind drivers to platform devices than to their
> > > ACPI companions, so convert the ACPI NFIT core driver to a platform one.
> > >
> > > While this is not expected to alter functionality, it changes sysfs
> > > layout and so it will be visible to user space.
> >
> > I'm not sure right off why but when I run the libndctl test with this patch I
> > get the following panic.
> >
> > [ 17.483472] BUG: kernel NULL pointer dereference, address: 0000000000000008
> > [ 17.484116] #PF: supervisor read access in kernel mode
> > [ 17.484593] #PF: error_code(0x0000) - not-present page
> > [ 17.485056] PGD 9def067 P4D 9def067 PUD 9df3067 PMD 0
> > [ 17.485516] Oops: Oops: 0000 [#1] SMP NOPTI
> > [ 17.485886] CPU: 2 UID: 0 PID: 1191 Comm: libndctl Tainted: G O 6.18.0ira+ #34 PREEMPT(voluntary)
> > [ 17.486804] Tainted: [O]=OOT_MODULE
> > [ 17.487125] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS edk2-20250812-18.fc42 08/12/2025
> > [ 17.487749] RIP: 0010:acpi_nfit_ctl+0x40b/0xa00 [nfit]
> > [ 17.488222] Code: 48 48 c7 44 24 28 28 f1 8c a1 48 8b 83 c8 01 00 00 44 89 e7 48 89 44 24 50 e8 01 83 fd ff 48 c7 44 24 40 10 58 8c a1 48 89 c3 <49> 8b 47 08 48 c7 44 24 30 30 f1 8c a1 48 89 44 24 18 e9 24 fd
> > ff
> > [ 17.491668] RSP: 0018:ffffc9000f11ba28 EFLAGS: 00010286
> > [ 17.492422] RAX: ffffffffa18679f0 RBX: ffffffffa18679f0 RCX: ffffc9000f11bb40
> > [ 17.492903] RDX: 000000000000041e RSI: ffffffffa18cf116 RDI: 0000000000000003
> > [ 17.493408] RBP: ffffc9000f11bb40 R08: 0000000000000008 R09: ffffc9000f11bafc
> > [ 17.493888] R10: ffffc9000f11bae0 R11: 0000000000004019 R12: 0000000000000003
> > [ 17.494396] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
> > [ 17.494878] FS: 00007f432f5fd7c0(0000) GS:ffff8880f9fdd000(0000) knlGS:0000000000000000
> > [ 17.495436] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > [ 17.495826] CR2: 0000000000000008 CR3: 0000000009e0c005 CR4: 0000000000770ef0
> > [ 17.496324] PKRU: 55555554
> > [ 17.496516] Call Trace:
> > [ 17.496691] <TASK>
> > [ 17.496844] ? __kmalloc_noprof+0x410/0x650
> > [ 17.497138] ? setup_result+0x1b/0xa0 [nfit_test]
> > [ 17.497474] nfit_ctl_test+0x21a/0x780 [nfit_test]
> > [ 17.497803] ? preempt_count_add+0x51/0xd0
> > [ 17.498086] ? up_write+0x13/0x60
> > [ 17.498333] ? up_write+0x35/0x60
> > [ 17.498565] ? preempt_count_add+0x51/0xd0
> > [ 17.498846] ? kernfs_next_descendant_post+0x1b/0xe0
> > [ 17.499196] nfit_test_probe+0x350/0x4d0 [nfit_test]
> > [ 17.499535] platform_probe+0x38/0x70
> > [ 17.499791] really_probe+0xde/0x380
> > [ 17.500039] ? _raw_spin_unlock_irq+0x18/0x40
> > [ 17.500354] __driver_probe_device+0xc0/0x150
> > [ 17.500656] driver_probe_device+0x1f/0xa0 [ 17.500939] ? __pfx___driver_attach+0x10/0x10
> > [ 17.501263] __driver_attach+0xc7/0x200
> > [ 17.501529] bus_for_each_dev+0x63/0xa0
> > [ 17.501794] bus_add_driver+0x114/0x200
> > [ 17.502059] driver_register+0x71/0xe0
> > [ 17.502480] nfit_test_init+0x24e/0xff0 [nfit_test]
> > [ 17.502956] ? __pfx_nfit_test_init+0x10/0x10 [nfit_test]
> > [ 17.503483] do_one_initcall+0x42/0x210
> > [ 17.503891] do_init_module+0x62/0x230
> > [ 17.504296] init_module_from_file+0xb1/0xe0
> > [ 17.504732] idempotent_init_module+0xed/0x2d0
> > [ 17.505184] __x64_sys_finit_module+0x6d/0xe0
> > [ 17.505626] do_syscall_64+0x62/0x390
> > [ 17.506016] entry_SYSCALL_64_after_hwframe+0x76/0x7e
> > [ 17.506563] RIP: 0033:0x7f432f8920cd
> > [ 17.506946] Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 03 4d 0f 00 f7 d8 64 89 01
> > 48
> > [ 17.508548] RSP: 002b:00007fff0a6ccd98 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
> > [ 17.509209] RAX: ffffffffffffffda RBX: 000000001f5def50 RCX: 00007f432f8920cd
> > [ 17.509831] RDX: 0000000000000000 RSI: 00007f432f9aa965 RDI: 0000000000000003 [ 17.510472] RBP: 00007fff0a6cce50 R08: 0000000000000000 R09: 00007fff0a6cce00
> > [ 17.511091] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000020000
> > [ 17.511727] R13: 000000001f5deb60 R14: 00007f432f9aa965 R15: 0000000000000000
> > [ 17.512353] </TASK>
> > [ 17.512638] Modules linked in: nfit_test(O+) device_dax(O) nd_pmem(O) dax_pmem(O) kmem nd_btt(O) nfit(O) dax_cxl cxl_pci nd_e820(O) cxl_mock_mem(O) cxl_test(O) cxl_mem(O) cxl_pmem(O) cxl_acpi(O) cxl_port(O) cx
> > l_mock(O) libnvdimm(O) nfit_test_iomap(O) cxl_core(O) fwctl
> > [ 17.514512] CR2: 0000000000000008
> > [ 17.514878] ---[ end trace 0000000000000000 ]---
> >
> >
> > I'll try and find some time to dig into it but perhaps yall have a quick
> > idea of what it could be?
> >
> > Ira
> >
> > >
> > > This change was mostly developed by Michal Wilczynski [1].
> > >
> > > Linu: https://lore.kernel.org/linux-acpi/20231011083334.3987477-6-michal.wilczynski@intel.com/ [1]
> > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > > ---
> > > drivers/acpi/nfit/core.c | 34 ++++++++++++++++++----------------
> > > 1 file changed, 18 insertions(+), 16 deletions(-)
> > >
> > > --- a/drivers/acpi/nfit/core.c
> > > +++ b/drivers/acpi/nfit/core.c
> > > @@ -2,6 +2,7 @@
> > > /*
> > > * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
> > > */
> > > +#include <linux/platform_device.h>
> > > #include <linux/list_sort.h>
> > > #include <linux/libnvdimm.h>
> > > #include <linux/module.h>
> > > @@ -98,7 +99,7 @@ static struct acpi_device *to_acpi_dev(s
> > > || strcmp(nd_desc->provider_name, "ACPI.NFIT") != 0)
> > > return NULL;
> > >
> > > - return to_acpi_device(acpi_desc->dev);
> > > + return ACPI_COMPANION(acpi_desc->dev);
> > > }
>
> It's likely this change and it is not even necessary.
>
> If possible, please check the v2 below.
Well, scratch this, it was a mistake.
The original patch was almost there AFAICS, but it overlooked the fact that
nfit_ctl_test() could create an acpi_desc with dev pointing to an artificial
struct acpi_device.
So to_acpi_dev() needs to check if the ACPI_COMPANION() is there and fall back
to acpi_desc->dev if that is not the case.
---
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Subject: [PATCH v3] ACPI: NFIT: core: Convert the driver to a platform one
While binding drivers directly to struct acpi_device objects allows
basic functionality to be provided, at least in the majority of cases,
there are some problems with it, related to general consistency, sysfs
layout, power management operation ordering, and code cleanliness.
Overall, it is better to bind drivers to platform devices than to their
ACPI companions, so convert the ACPI NFIT core driver to a platform one.
While this is not expected to alter functionality, it changes sysfs
layout and so it will be visible to user space.
This change was mostly developed by Michal Wilczynski [1].
Linu: https://lore.kernel.org/linux-acpi/20231011083334.3987477-6-michal.wilczynski@intel.com/ [1]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
v1 -> v3: Adjust to_acpi_dev() to take the "no ACPI companion" case into account.
---
drivers/acpi/nfit/core.c | 47 ++++++++++++++++++++++++++++-------------------
1 file changed, 28 insertions(+), 19 deletions(-)
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -2,6 +2,7 @@
/*
* Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
*/
+#include <linux/platform_device.h>
#include <linux/list_sort.h>
#include <linux/libnvdimm.h>
#include <linux/module.h>
@@ -89,15 +90,22 @@ static const guid_t *to_nfit_bus_uuid(in
static struct acpi_device *to_acpi_dev(struct acpi_nfit_desc *acpi_desc)
{
struct nvdimm_bus_descriptor *nd_desc = &acpi_desc->nd_desc;
+ struct acpi_device *adev;
- /*
- * If provider == 'ACPI.NFIT' we can assume 'dev' is a struct
- * acpi_device.
- */
+ /* If provider == 'ACPI.NFIT', a struct acpi_device is there. */
if (!nd_desc->provider_name
|| strcmp(nd_desc->provider_name, "ACPI.NFIT") != 0)
return NULL;
+ /*
+ * But it can be the ACPI companion of acpi_desc->dev when it cones from
+ * acpi_nfit_probe().
+ */
+ adev = ACPI_COMPANION(acpi_desc->dev);
+ if (adev)
+ return adev;
+
+ /* Or it is acpi_desc->dev itself when it comes from nfit_ctl_test(). */
return to_acpi_device(acpi_desc->dev);
}
@@ -3283,11 +3291,11 @@ static void acpi_nfit_put_table(void *ta
static void acpi_nfit_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_device *adev = data;
+ struct device *dev = data;
- device_lock(&adev->dev);
- __acpi_nfit_notify(&adev->dev, handle, event);
- device_unlock(&adev->dev);
+ device_lock(dev);
+ __acpi_nfit_notify(dev, handle, event);
+ device_unlock(dev);
}
static void acpi_nfit_remove_notify_handler(void *data)
@@ -3328,18 +3336,19 @@ void acpi_nfit_shutdown(void *data)
}
EXPORT_SYMBOL_GPL(acpi_nfit_shutdown);
-static int acpi_nfit_add(struct acpi_device *adev)
+static int acpi_nfit_probe(struct platform_device *pdev)
{
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
struct acpi_nfit_desc *acpi_desc;
- struct device *dev = &adev->dev;
+ struct device *dev = &pdev->dev;
+ struct acpi_device *adev = ACPI_COMPANION(dev);
struct acpi_table_header *tbl;
acpi_status status = AE_OK;
acpi_size sz;
int rc = 0;
rc = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
- acpi_nfit_notify, adev);
+ acpi_nfit_notify, dev);
if (rc)
return rc;
@@ -3369,7 +3378,7 @@ static int acpi_nfit_add(struct acpi_dev
acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL);
if (!acpi_desc)
return -ENOMEM;
- acpi_nfit_desc_init(acpi_desc, &adev->dev);
+ acpi_nfit_desc_init(acpi_desc, dev);
/* Save the acpi header for exporting the revision via sysfs */
acpi_desc->acpi_header = *tbl;
@@ -3474,11 +3483,11 @@ static const struct acpi_device_id acpi_
};
MODULE_DEVICE_TABLE(acpi, acpi_nfit_ids);
-static struct acpi_driver acpi_nfit_driver = {
- .name = KBUILD_MODNAME,
- .ids = acpi_nfit_ids,
- .ops = {
- .add = acpi_nfit_add,
+static struct platform_driver acpi_nfit_driver = {
+ .probe = acpi_nfit_probe,
+ .driver = {
+ .name = "acpi-nfit",
+ .acpi_match_table = acpi_nfit_ids,
},
};
@@ -3516,7 +3525,7 @@ static __init int nfit_init(void)
return -ENOMEM;
nfit_mce_register();
- ret = acpi_bus_register_driver(&acpi_nfit_driver);
+ ret = platform_driver_register(&acpi_nfit_driver);
if (ret) {
nfit_mce_unregister();
destroy_workqueue(nfit_wq);
@@ -3529,7 +3538,7 @@ static __init int nfit_init(void)
static __exit void nfit_exit(void)
{
nfit_mce_unregister();
- acpi_bus_unregister_driver(&acpi_nfit_driver);
+ platform_driver_unregister(&acpi_nfit_driver);
destroy_workqueue(nfit_wq);
WARN_ON(!list_empty(&acpi_descs));
}
^ permalink raw reply [flat|nested] 12+ messages in thread