[PATCH v3] ACPI: NFIT: Use cleanup.h helpers instead of devm_*()

2023-10-17 Thread Michal Wilczynski
The new cleanup.h facilities that arrived in v6.5-rc1 can replace the
the usage of devm semantics in acpi_nfit_init_interleave_set(). That
routine appears to only be using devm to avoid goto statements. The
new __free() annotation at variable declaration time can achieve the same
effect more efficiently.

There is no end user visible side effects of this patch, I was
motivated to send this cleanup to practice using the new helpers.

Suggested-by: Dave Jiang 
Suggested-by: Andy Shevchenko 
Reviewed-by: Dave Jiang 
Reviewed-by: Andy Shevchenko 
Signed-off-by: Michal Wilczynski 
---

Dan, would you like me to give you credit for the changelog changes
with Co-developed-by tag ?

v3:
 - changed changelog
v2:
 - removed first commit from the patchset, as the commit couldn't
   be marked as a fix
 - squashed those commits together, since the second one were
   mostly overwriting the previous one

 drivers/acpi/nfit/core.c | 21 -
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 3826f49d481b..67a844a705c4 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -2257,26 +2257,23 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
struct nd_region_desc *ndr_desc,
struct acpi_nfit_system_address *spa)
 {
+   u16 nr = ndr_desc->num_mappings;
+   struct nfit_set_info2 *info2 __free(kfree) =
+   kcalloc(nr, sizeof(*info2), GFP_KERNEL);
+   struct nfit_set_info *info __free(kfree) =
+   kcalloc(nr, sizeof(*info), GFP_KERNEL);
struct device *dev = acpi_desc->dev;
struct nd_interleave_set *nd_set;
-   u16 nr = ndr_desc->num_mappings;
-   struct nfit_set_info2 *info2;
-   struct nfit_set_info *info;
int i;
 
+   if (!info || !info2)
+   return -ENOMEM;
+
nd_set = devm_kzalloc(dev, sizeof(*nd_set), GFP_KERNEL);
if (!nd_set)
return -ENOMEM;
import_guid(_set->type_guid, spa->range_guid);
 
-   info = devm_kcalloc(dev, nr, sizeof(*info), GFP_KERNEL);
-   if (!info)
-   return -ENOMEM;
-
-   info2 = devm_kcalloc(dev, nr, sizeof(*info2), GFP_KERNEL);
-   if (!info2)
-   return -ENOMEM;
-
for (i = 0; i < nr; i++) {
struct nd_mapping_desc *mapping = _desc->mapping[i];
struct nvdimm *nvdimm = mapping->nvdimm;
@@ -2337,8 +2334,6 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
}
 
ndr_desc->nd_set = nd_set;
-   devm_kfree(dev, info);
-   devm_kfree(dev, info2);
 
return 0;
 }
-- 
2.41.0




[PATCH v2] ACPI: NFIT: Fix local use of devm_*()

2023-10-13 Thread Michal Wilczynski
devm_*() family of functions purpose is managing memory attached to a
device. So in general it should only be used for allocations that should
last for the whole lifecycle of the device. This is not the case for
acpi_nfit_init_interleave_set(). There are two allocations that are only
used locally in this function.

Fix this by switching from devm_kcalloc() to kcalloc(), and adding
modern scope based rollback. This is similar to C++ RAII and is
preferred way for handling local memory allocations.

Reported-by: Andy Shevchenko 
Suggested-by: Dave Jiang 
Suggested-by: Andy Shevchenko 
Reviewed-by: Dave Jiang 
Reviewed-by: Andy Shevchenko 
Signed-off-by: Michal Wilczynski 
---
v2:
 - removed first commit from the patchset, as the commit couldn't
   be marked as a fix
 - squashed those commits together, since the second one were
   mostly overwriting the previous one

 drivers/acpi/nfit/core.c | 21 -
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 3826f49d481b..67a844a705c4 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -2257,26 +2257,23 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
struct nd_region_desc *ndr_desc,
struct acpi_nfit_system_address *spa)
 {
+   u16 nr = ndr_desc->num_mappings;
+   struct nfit_set_info2 *info2 __free(kfree) =
+   kcalloc(nr, sizeof(*info2), GFP_KERNEL);
+   struct nfit_set_info *info __free(kfree) =
+   kcalloc(nr, sizeof(*info), GFP_KERNEL);
struct device *dev = acpi_desc->dev;
struct nd_interleave_set *nd_set;
-   u16 nr = ndr_desc->num_mappings;
-   struct nfit_set_info2 *info2;
-   struct nfit_set_info *info;
int i;
 
+   if (!info || !info2)
+   return -ENOMEM;
+
nd_set = devm_kzalloc(dev, sizeof(*nd_set), GFP_KERNEL);
if (!nd_set)
return -ENOMEM;
import_guid(_set->type_guid, spa->range_guid);
 
-   info = devm_kcalloc(dev, nr, sizeof(*info), GFP_KERNEL);
-   if (!info)
-   return -ENOMEM;
-
-   info2 = devm_kcalloc(dev, nr, sizeof(*info2), GFP_KERNEL);
-   if (!info2)
-   return -ENOMEM;
-
for (i = 0; i < nr; i++) {
struct nd_mapping_desc *mapping = _desc->mapping[i];
struct nvdimm *nvdimm = mapping->nvdimm;
@@ -2337,8 +2334,6 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
}
 
ndr_desc->nd_set = nd_set;
-   devm_kfree(dev, info);
-   devm_kfree(dev, info2);
 
return 0;
 }
-- 
2.41.0




[PATCH v3 6/6] ACPI: NFIT: Remove redundant call to to_acpi_dev()

2023-10-11 Thread Michal Wilczynski
In acpi_nfit_ctl() ACPI handle is extracted using to_acpi_dev()
function and accessing handle field in ACPI device. After transformation
from ACPI driver to platform driver this is not optimal anymore. To get
a handle it's enough to just use ACPI_HANDLE() macro to extract the
handle.

Suggested-by: Andy Shevchenko 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/nfit/core.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 6b9d10cae92c..402bb56d4163 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -475,8 +475,6 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, 
struct nvdimm *nvdimm,
guid = to_nfit_uuid(nfit_mem->family);
handle = adev->handle;
} else {
-   struct acpi_device *adev = to_acpi_dev(acpi_desc);
-
cmd_name = nvdimm_bus_cmd_name(cmd);
cmd_mask = nd_desc->cmd_mask;
if (cmd == ND_CMD_CALL && call_pkg->nd_family) {
@@ -493,7 +491,7 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, 
struct nvdimm *nvdimm,
guid = to_nfit_uuid(NFIT_DEV_BUS);
}
desc = nd_cmd_bus_desc(cmd);
-   handle = adev->handle;
+   handle = ACPI_HANDLE(dev);
dimm_name = "bus";
}
 
-- 
2.41.0




[PATCH v3 5/6] ACPI: NFIT: Replace acpi_driver with platform_driver

2023-10-11 Thread Michal Wilczynski
NFIT driver uses struct acpi_driver incorrectly to register itself.
This is wrong as the instances of the ACPI devices are not meant
to be literal devices, they're supposed to describe ACPI entry of a
particular device.

Use platform_driver instead of acpi_driver. In relevant places call
platform devices instances pdev to make a distinction with ACPI
devices instances.

NFIT driver uses devm_*() family of functions extensively. This change
has no impact on correct functioning of the whole devm_*() family of
functions, since the lifecycle of the device stays the same. It is still
being created during the enumeration, and destroyed on platform device
removal.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/nfit/core.c | 34 ++
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 3826f49d481b..6b9d10cae92c 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include "intel.h"
@@ -98,7 +99,7 @@ static struct acpi_device *to_acpi_dev(struct acpi_nfit_desc 
*acpi_desc)
|| 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)
@@ -3284,11 +3285,11 @@ static void acpi_nfit_put_table(void *table)
 
 static void acpi_nfit_notify(acpi_handle handle, u32 event, void *data)
 {
-   struct acpi_device *adev = data;
+   struct device *dev = data;
 
-   device_lock(>dev);
-   __acpi_nfit_notify(>dev, handle, event);
-   device_unlock(>dev);
+   device_lock(dev);
+   __acpi_nfit_notify(dev, handle, event);
+   device_unlock(dev);
 }
 
 static void acpi_nfit_remove_notify_handler(void *data)
@@ -3329,11 +3330,12 @@ 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 = >dev;
+   struct device *dev = >dev;
+   struct acpi_device *adev = ACPI_COMPANION(dev);
struct acpi_table_header *tbl;
acpi_status status = AE_OK;
acpi_size sz;
@@ -3360,7 +3362,7 @@ static int acpi_nfit_add(struct acpi_device *adev)
acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL);
if (!acpi_desc)
return -ENOMEM;
-   acpi_nfit_desc_init(acpi_desc, >dev);
+   acpi_nfit_desc_init(acpi_desc, dev);
 
/* Save the acpi header for exporting the revision via sysfs */
acpi_desc->acpi_header = *tbl;
@@ -3391,7 +3393,7 @@ static int acpi_nfit_add(struct acpi_device *adev)
return rc;
 
rc = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
-acpi_nfit_notify, adev);
+acpi_nfit_notify, dev);
if (rc)
return rc;
 
@@ -3475,11 +3477,11 @@ static const struct acpi_device_id acpi_nfit_ids[] = {
 };
 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 = KBUILD_MODNAME,
+   .acpi_match_table = acpi_nfit_ids,
},
 };
 
@@ -3517,7 +3519,7 @@ static __init int nfit_init(void)
return -ENOMEM;
 
nfit_mce_register();
-   ret = acpi_bus_register_driver(_nfit_driver);
+   ret = platform_driver_register(_nfit_driver);
if (ret) {
nfit_mce_unregister();
destroy_workqueue(nfit_wq);
@@ -3530,7 +3532,7 @@ static __init int nfit_init(void)
 static __exit void nfit_exit(void)
 {
nfit_mce_unregister();
-   acpi_bus_unregister_driver(_nfit_driver);
+   platform_driver_unregister(_nfit_driver);
destroy_workqueue(nfit_wq);
WARN_ON(!list_empty(_descs));
 }
-- 
2.41.0




[PATCH v3 4/6] ACPI: AC: Rename ACPI device from device to adev

2023-10-11 Thread Michal Wilczynski
Since transformation from ACPI driver to platform driver there are two
devices on which the driver operates - ACPI device and platform device.
For the sake of reader this calls for the distinction in their naming,
to avoid confusion. Rename device to adev, as corresponding
platform device is called pdev.

Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/ac.c | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 1dd4919be7ac..2618a7ccc11c 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -121,11 +121,11 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, 
void *data)
 {
struct device *dev = data;
struct acpi_ac *ac = dev_get_drvdata(dev);
-   struct acpi_device *device = ACPI_COMPANION(dev);
+   struct acpi_device *adev = ACPI_COMPANION(dev);
 
switch (event) {
default:
-   acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
+   acpi_handle_debug(adev->handle, "Unsupported event [0x%x]\n",
  event);
fallthrough;
case ACPI_AC_NOTIFY_STATUS:
@@ -142,11 +142,11 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, 
void *data)
msleep(ac_sleep_before_get_state_ms);
 
acpi_ac_get_state(ac);
-   acpi_bus_generate_netlink_event(device->pnp.device_class,
+   acpi_bus_generate_netlink_event(adev->pnp.device_class,
dev_name(dev),
event,
ac->state);
-   acpi_notifier_call_chain(device, event, ac->state);
+   acpi_notifier_call_chain(adev, event, ac->state);
kobject_uevent(>charger->dev.kobj, KOBJ_CHANGE);
}
 }
@@ -205,7 +205,7 @@ static const struct dmi_system_id ac_dmi_table[]  
__initconst = {
 
 static int acpi_ac_probe(struct platform_device *pdev)
 {
-   struct acpi_device *device = ACPI_COMPANION(>dev);
+   struct acpi_device *adev = ACPI_COMPANION(>dev);
struct power_supply_config psy_cfg = {};
struct acpi_ac *ac;
int result;
@@ -214,9 +214,9 @@ static int acpi_ac_probe(struct platform_device *pdev)
if (!ac)
return -ENOMEM;
 
-   ac->device = device;
-   strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME);
-   strcpy(acpi_device_class(device), ACPI_AC_CLASS);
+   ac->device = adev;
+   strcpy(acpi_device_name(adev), ACPI_AC_DEVICE_NAME);
+   strcpy(acpi_device_class(adev), ACPI_AC_CLASS);
 
platform_set_drvdata(pdev, ac);
 
@@ -226,7 +226,7 @@ static int acpi_ac_probe(struct platform_device *pdev)
 
psy_cfg.drv_data = ac;
 
-   ac->charger_desc.name = acpi_device_bid(device);
+   ac->charger_desc.name = acpi_device_bid(adev);
ac->charger_desc.type = POWER_SUPPLY_TYPE_MAINS;
ac->charger_desc.properties = ac_props;
ac->charger_desc.num_properties = ARRAY_SIZE(ac_props);
@@ -238,13 +238,13 @@ static int acpi_ac_probe(struct platform_device *pdev)
goto err_release_ac;
}
 
-   pr_info("%s [%s] (%s-line)\n", acpi_device_name(device),
-   acpi_device_bid(device), str_on_off(ac->state));
+   pr_info("%s [%s] (%s-line)\n", acpi_device_name(adev),
+   acpi_device_bid(adev), str_on_off(ac->state));
 
ac->battery_nb.notifier_call = acpi_ac_battery_notify;
register_acpi_notifier(>battery_nb);
 
-   result = acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY,
+   result = acpi_dev_install_notify_handler(adev, ACPI_ALL_NOTIFY,
 acpi_ac_notify, >dev);
if (result)
goto err_unregister;
-- 
2.41.0




[PATCH v3 3/6] ACPI: AC: Replace acpi_driver with platform_driver

2023-10-11 Thread Michal Wilczynski
AC driver uses struct acpi_driver incorrectly to register itself. This
is wrong as the instances of the ACPI devices are not meant to
be literal devices, they're supposed to describe ACPI entry of a
particular device.

Use platform_driver instead of acpi_driver. In relevant places call
platform devices instances pdev to make a distinction with ACPI
devices instances.

Drop unnecessary casts from acpi_bus_generate_netlink_event() and
acpi_notifier_call_chain().

Add a blank line to distinguish pdev API vs local ACPI notify function.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/ac.c | 61 +--
 1 file changed, 33 insertions(+), 28 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index f809f6889b4a..1dd4919be7ac 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -33,8 +33,9 @@ MODULE_AUTHOR("Paul Diefenbaugh");
 MODULE_DESCRIPTION("ACPI AC Adapter Driver");
 MODULE_LICENSE("GPL");
 
-static int acpi_ac_add(struct acpi_device *device);
-static void acpi_ac_remove(struct acpi_device *device);
+static int acpi_ac_probe(struct platform_device *pdev);
+static void acpi_ac_remove(struct platform_device *pdev);
+
 static void acpi_ac_notify(acpi_handle handle, u32 event, void *data);
 
 static const struct acpi_device_id ac_device_ids[] = {
@@ -51,17 +52,6 @@ static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume);
 static int ac_sleep_before_get_state_ms;
 static int ac_only;
 
-static struct acpi_driver acpi_ac_driver = {
-   .name = "ac",
-   .class = ACPI_AC_CLASS,
-   .ids = ac_device_ids,
-   .ops = {
-   .add = acpi_ac_add,
-   .remove = acpi_ac_remove,
-   },
-   .drv.pm = _ac_pm,
-};
-
 struct acpi_ac {
struct power_supply *charger;
struct power_supply_desc charger_desc;
@@ -129,8 +119,9 @@ static enum power_supply_property ac_props[] = {
 /* Driver Model */
 static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
 {
-   struct acpi_device *device = data;
-   struct acpi_ac *ac = acpi_driver_data(device);
+   struct device *dev = data;
+   struct acpi_ac *ac = dev_get_drvdata(dev);
+   struct acpi_device *device = ACPI_COMPANION(dev);
 
switch (event) {
default:
@@ -152,9 +143,10 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, 
void *data)
 
acpi_ac_get_state(ac);
acpi_bus_generate_netlink_event(device->pnp.device_class,
- dev_name(>dev), event,
- (u32) ac->state);
-   acpi_notifier_call_chain(device, event, (u32) ac->state);
+   dev_name(dev),
+   event,
+   ac->state);
+   acpi_notifier_call_chain(device, event, ac->state);
kobject_uevent(>charger->dev.kobj, KOBJ_CHANGE);
}
 }
@@ -211,8 +203,9 @@ static const struct dmi_system_id ac_dmi_table[]  
__initconst = {
{},
 };
 
-static int acpi_ac_add(struct acpi_device *device)
+static int acpi_ac_probe(struct platform_device *pdev)
 {
+   struct acpi_device *device = ACPI_COMPANION(>dev);
struct power_supply_config psy_cfg = {};
struct acpi_ac *ac;
int result;
@@ -224,7 +217,8 @@ static int acpi_ac_add(struct acpi_device *device)
ac->device = device;
strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_AC_CLASS);
-   device->driver_data = ac;
+
+   platform_set_drvdata(pdev, ac);
 
result = acpi_ac_get_state(ac);
if (result)
@@ -237,7 +231,7 @@ static int acpi_ac_add(struct acpi_device *device)
ac->charger_desc.properties = ac_props;
ac->charger_desc.num_properties = ARRAY_SIZE(ac_props);
ac->charger_desc.get_property = get_ac_property;
-   ac->charger = power_supply_register(>device->dev,
+   ac->charger = power_supply_register(>dev,
>charger_desc, _cfg);
if (IS_ERR(ac->charger)) {
result = PTR_ERR(ac->charger);
@@ -251,7 +245,7 @@ static int acpi_ac_add(struct acpi_device *device)
register_acpi_notifier(>battery_nb);
 
result = acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY,
-acpi_ac_notify, device);
+acpi_ac_notify, >dev);
if (result)
goto err_unregister;
 
@@ -269,7 +263,7 @@ static int acpi_ac_add(struct acpi_device *device)
 #ifdef CONFIG_PM_SLEEP
 static int acpi_ac_resume(struct device *dev)
 {
-   struct acpi_ac *ac = acpi_dri

[PATCH v3 1/6] ACPI: AC: Remove unnecessary checks

2023-10-11 Thread Michal Wilczynski
Remove unnecessary checks for NULL for variables that can't be NULL at
the point they're checked for it. Defensive programming is discouraged
in the kernel.

Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/ac.c | 27 ---
 1 file changed, 4 insertions(+), 23 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index aac3e561790c..83d45c681121 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -131,9 +131,6 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, 
void *data)
struct acpi_device *device = data;
struct acpi_ac *ac = acpi_driver_data(device);
 
-   if (!ac)
-   return;
-
switch (event) {
default:
acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
@@ -216,12 +213,8 @@ static const struct dmi_system_id ac_dmi_table[]  
__initconst = {
 static int acpi_ac_add(struct acpi_device *device)
 {
struct power_supply_config psy_cfg = {};
-   int result = 0;
-   struct acpi_ac *ac = NULL;
-
-
-   if (!device)
-   return -EINVAL;
+   struct acpi_ac *ac;
+   int result;
 
ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL);
if (!ac)
@@ -275,16 +268,9 @@ static int acpi_ac_add(struct acpi_device *device)
 #ifdef CONFIG_PM_SLEEP
 static int acpi_ac_resume(struct device *dev)
 {
-   struct acpi_ac *ac;
+   struct acpi_ac *ac = acpi_driver_data(to_acpi_device(dev));
unsigned int old_state;
 
-   if (!dev)
-   return -EINVAL;
-
-   ac = acpi_driver_data(to_acpi_device(dev));
-   if (!ac)
-   return -EINVAL;
-
old_state = ac->state;
if (acpi_ac_get_state(ac))
return 0;
@@ -299,12 +285,7 @@ static int acpi_ac_resume(struct device *dev)
 
 static void acpi_ac_remove(struct acpi_device *device)
 {
-   struct acpi_ac *ac = NULL;
-
-   if (!device || !acpi_driver_data(device))
-   return;
-
-   ac = acpi_driver_data(device);
+   struct acpi_ac *ac = acpi_driver_data(device);
 
acpi_dev_remove_notify_handler(device, ACPI_ALL_NOTIFY,
   acpi_ac_notify);
-- 
2.41.0




[PATCH v3 2/6] ACPI: AC: Use string_choices API instead of ternary operator

2023-10-11 Thread Michal Wilczynski
Use modern string_choices API instead of manually determining the
output using ternary operator.

Suggested-by: Andy Shevchenko 
Reviewed-by: Andy Shevchenko 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/ac.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 83d45c681121..f809f6889b4a 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -243,8 +244,8 @@ static int acpi_ac_add(struct acpi_device *device)
goto err_release_ac;
}
 
-   pr_info("%s [%s] (%s)\n", acpi_device_name(device),
-   acpi_device_bid(device), ac->state ? "on-line" : "off-line");
+   pr_info("%s [%s] (%s-line)\n", acpi_device_name(device),
+   acpi_device_bid(device), str_on_off(ac->state));
 
ac->battery_nb.notifier_call = acpi_ac_battery_notify;
register_acpi_notifier(>battery_nb);
-- 
2.41.0




[PATCH v3 0/6] Replace acpi_driver with platform_driver

2023-10-11 Thread Michal Wilczynski
Currently there is a number of drivers that somewhat incorrectly
register themselves as acpi_driver, while they should be registering as
platform_drivers. acpi_device was never meant to represent actual
device, it only represents an entry in the ACPI table and ACPI driver
should be treated as a driver for the ACPI entry of the particular
device, not the device itself. Drivers of the devices itself should
register as platform_drivers. Replace acpi_driver with platform_driver
for all relevant drivers in drivers/acpi directory. This is just the
first part of the change, as many acpi_drivers are present in many files
outside of drivers/acpi directory.

Additionally during internal review we've decided that it's best to send
the relevant patches sequentially, in order not to overwhelm the reviewers.
So I'm starting with NFIT and AC drivers.

This change is possible thanks to recent .notify callback removal in
drivers/acpi [1]. So flow for the remaining acpi_drivers will look like
this:

1) Remove .notify callback with separate patchset for drivers/platform
   and other outstanding places like drivers/hwmon, drivers/iio etc.
2) Replace acpi_driver with platform_driver, as aside for .notify
   callback they're mostly functionally compatible.

Most of the patches in this series could be considered independent, and
could be merged separately, with a notable exception of the very first
patch in this series that changes notify installer wrappers to be more
generic. I decided it would be best not to force the user of this
wrappers to pass any specific structure, like acpi_device or
platform_device. It makes sense as it is very often the case that
drivers declare their own private structure which gets allocated during
the .probe() callback, and become the heart of the driver. In that case
it makes much more sense to pass this structure to notify handler.
Additionally some drivers, like acpi_video that already have custom
notify handlers do that already.

Link: 
https://lore.kernel.org/linux-acpi/20230703080252.2899090-1-michal.wilczyn...@intel.com/
 [1]

v3:
 - in AC transformation patch replaced struct device* with
   struct acpi_device*, as suggested.

v2:
 - dropped first, second and last commit. Last commit was deemed
   pointless, first and second are already merged.
 - rebased on top of modified first commit (changes in the wrappers)

Michal Wilczynski (6):
  ACPI: AC: Remove unnecessary checks
  ACPI: AC: Use string_choices API instead of ternary operator
  ACPI: AC: Replace acpi_driver with platform_driver
  ACPI: AC: Rename ACPI device from device to adev
  ACPI: NFIT: Replace acpi_driver with platform_driver
  ACPI: NFIT: Remove redundant call to to_acpi_dev()

 drivers/acpi/ac.c| 103 +--
 drivers/acpi/nfit/core.c |  38 +++
 2 files changed, 64 insertions(+), 77 deletions(-)

-- 
2.41.0




[PATCH v2 6/6] ACPI: NFIT: Remove redundant call to to_acpi_dev()

2023-10-06 Thread Michal Wilczynski
In acpi_nfit_ctl() ACPI handle is extracted using to_acpi_dev()
function and accessing handle field in ACPI device. After transformation
from ACPI driver to platform driver this is not optimal anymore. To get
a handle it's enough to just use ACPI_HANDLE() macro to extract the
handle.

Suggested-by: Andy Shevchenko 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/nfit/core.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index fb0bc16fa186..3d254b2cf2e7 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -475,8 +475,6 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, 
struct nvdimm *nvdimm,
guid = to_nfit_uuid(nfit_mem->family);
handle = adev->handle;
} else {
-   struct acpi_device *adev = to_acpi_dev(acpi_desc);
-
cmd_name = nvdimm_bus_cmd_name(cmd);
cmd_mask = nd_desc->cmd_mask;
if (cmd == ND_CMD_CALL && call_pkg->nd_family) {
@@ -493,7 +491,7 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, 
struct nvdimm *nvdimm,
guid = to_nfit_uuid(NFIT_DEV_BUS);
}
desc = nd_cmd_bus_desc(cmd);
-   handle = adev->handle;
+   handle = ACPI_HANDLE(dev);
dimm_name = "bus";
}
 
-- 
2.41.0




[PATCH v2 4/6] ACPI: AC: Rename ACPI device from device to adev

2023-10-06 Thread Michal Wilczynski
Since transformation from ACPI driver to platform driver there are two
devices on which the driver operates - ACPI device and platform device.
For the sake of reader this calls for the distinction in their naming,
to avoid confusion. Rename device to adev, as corresponding
platform device is called pdev.

Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/ac.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 298defeb5301..bb02e7f5d65a 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -120,7 +120,7 @@ static enum power_supply_property ac_props[] = {
 static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
 {
struct acpi_ac *ac = data;
-   struct acpi_device *device = ACPI_COMPANION(ac->dev);
+   struct acpi_device *adev = ACPI_COMPANION(ac->dev);
 
switch (event) {
default:
@@ -141,11 +141,11 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, 
void *data)
msleep(ac_sleep_before_get_state_ms);
 
acpi_ac_get_state(ac);
-   acpi_bus_generate_netlink_event(device->pnp.device_class,
+   acpi_bus_generate_netlink_event(adev->pnp.device_class,
dev_name(ac->dev),
event,
ac->state);
-   acpi_notifier_call_chain(device, event, ac->state);
+   acpi_notifier_call_chain(adev, event, ac->state);
kobject_uevent(>charger->dev.kobj, KOBJ_CHANGE);
}
 }
@@ -204,7 +204,7 @@ static const struct dmi_system_id ac_dmi_table[]  
__initconst = {
 
 static int acpi_ac_probe(struct platform_device *pdev)
 {
-   struct acpi_device *device = ACPI_COMPANION(>dev);
+   struct acpi_device *adev = ACPI_COMPANION(>dev);
struct power_supply_config psy_cfg = {};
struct acpi_ac *ac;
int result;
@@ -214,8 +214,8 @@ static int acpi_ac_probe(struct platform_device *pdev)
return -ENOMEM;
 
ac->dev = >dev;
-   strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME);
-   strcpy(acpi_device_class(device), ACPI_AC_CLASS);
+   strcpy(acpi_device_name(adev), ACPI_AC_DEVICE_NAME);
+   strcpy(acpi_device_class(adev), ACPI_AC_CLASS);
 
platform_set_drvdata(pdev, ac);
 
@@ -225,7 +225,7 @@ static int acpi_ac_probe(struct platform_device *pdev)
 
psy_cfg.drv_data = ac;
 
-   ac->charger_desc.name = acpi_device_bid(device);
+   ac->charger_desc.name = acpi_device_bid(adev);
ac->charger_desc.type = POWER_SUPPLY_TYPE_MAINS;
ac->charger_desc.properties = ac_props;
ac->charger_desc.num_properties = ARRAY_SIZE(ac_props);
@@ -237,13 +237,13 @@ static int acpi_ac_probe(struct platform_device *pdev)
goto err_release_ac;
}
 
-   pr_info("%s [%s] (%s-line)\n", acpi_device_name(device),
-   acpi_device_bid(device), str_on_off(ac->state));
+   pr_info("%s [%s] (%s-line)\n", acpi_device_name(adev),
+   acpi_device_bid(adev), str_on_off(ac->state));
 
ac->battery_nb.notifier_call = acpi_ac_battery_notify;
register_acpi_notifier(>battery_nb);
 
-   result = acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY,
+   result = acpi_dev_install_notify_handler(adev, ACPI_ALL_NOTIFY,
 acpi_ac_notify, ac);
if (result)
goto err_unregister;
-- 
2.41.0




[PATCH v2 5/6] ACPI: NFIT: Replace acpi_driver with platform_driver

2023-10-06 Thread Michal Wilczynski
NFIT driver uses struct acpi_driver incorrectly to register itself.
This is wrong as the instances of the ACPI devices are not meant
to be literal devices, they're supposed to describe ACPI entry of a
particular device.

Use platform_driver instead of acpi_driver. In relevant places call
platform devices instances pdev to make a distinction with ACPI
devices instances.

NFIT driver uses devm_*() family of functions extensively. This change
has no impact on correct functioning of the whole devm_*() family of
functions, since the lifecycle of the device stays the same. It is still
being created during the enumeration, and destroyed on platform device
removal.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/nfit/core.c | 34 ++
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 942b84d94078..fb0bc16fa186 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include "intel.h"
@@ -98,7 +99,7 @@ static struct acpi_device *to_acpi_dev(struct acpi_nfit_desc 
*acpi_desc)
|| 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)
@@ -3284,11 +3285,11 @@ static void acpi_nfit_put_table(void *table)
 
 static void acpi_nfit_notify(acpi_handle handle, u32 event, void *data)
 {
-   struct acpi_device *adev = data;
+   struct device *dev = data;
 
-   device_lock(>dev);
-   __acpi_nfit_notify(>dev, handle, event);
-   device_unlock(>dev);
+   device_lock(dev);
+   __acpi_nfit_notify(dev, handle, event);
+   device_unlock(dev);
 }
 
 static void acpi_nfit_remove_notify_handler(void *data)
@@ -3329,11 +3330,12 @@ 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 = >dev;
+   struct device *dev = >dev;
+   struct acpi_device *adev = ACPI_COMPANION(dev);
struct acpi_table_header *tbl;
acpi_status status = AE_OK;
acpi_size sz;
@@ -3360,7 +3362,7 @@ static int acpi_nfit_add(struct acpi_device *adev)
acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL);
if (!acpi_desc)
return -ENOMEM;
-   acpi_nfit_desc_init(acpi_desc, >dev);
+   acpi_nfit_desc_init(acpi_desc, dev);
 
/* Save the acpi header for exporting the revision via sysfs */
acpi_desc->acpi_header = *tbl;
@@ -3391,7 +3393,7 @@ static int acpi_nfit_add(struct acpi_device *adev)
return rc;
 
rc = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
-acpi_nfit_notify, adev);
+acpi_nfit_notify, dev);
if (rc)
return rc;
 
@@ -3475,11 +3477,11 @@ static const struct acpi_device_id acpi_nfit_ids[] = {
 };
 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 = KBUILD_MODNAME,
+   .acpi_match_table = acpi_nfit_ids,
},
 };
 
@@ -3517,7 +3519,7 @@ static __init int nfit_init(void)
return -ENOMEM;
 
nfit_mce_register();
-   ret = acpi_bus_register_driver(_nfit_driver);
+   ret = platform_driver_register(_nfit_driver);
if (ret) {
nfit_mce_unregister();
destroy_workqueue(nfit_wq);
@@ -3530,7 +3532,7 @@ static __init int nfit_init(void)
 static __exit void nfit_exit(void)
 {
nfit_mce_unregister();
-   acpi_bus_unregister_driver(_nfit_driver);
+   platform_driver_unregister(_nfit_driver);
destroy_workqueue(nfit_wq);
WARN_ON(!list_empty(_descs));
 }
-- 
2.41.0




[PATCH v2 3/6] ACPI: AC: Replace acpi_driver with platform_driver

2023-10-06 Thread Michal Wilczynski
AC driver uses struct acpi_driver incorrectly to register itself. This
is wrong as the instances of the ACPI devices are not meant to
be literal devices, they're supposed to describe ACPI entry of a
particular device.

Use platform_driver instead of acpi_driver. In relevant places call
platform devices instances pdev to make a distinction with ACPI
devices instances.

Drop unnecessary casts from acpi_bus_generate_netlink_event() and
acpi_notifier_call_chain().

Add a blank line to distinguish pdev API vs local ACPI notify function.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/ac.c | 70 +--
 1 file changed, 37 insertions(+), 33 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index f809f6889b4a..298defeb5301 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -33,8 +33,9 @@ MODULE_AUTHOR("Paul Diefenbaugh");
 MODULE_DESCRIPTION("ACPI AC Adapter Driver");
 MODULE_LICENSE("GPL");
 
-static int acpi_ac_add(struct acpi_device *device);
-static void acpi_ac_remove(struct acpi_device *device);
+static int acpi_ac_probe(struct platform_device *pdev);
+static void acpi_ac_remove(struct platform_device *pdev);
+
 static void acpi_ac_notify(acpi_handle handle, u32 event, void *data);
 
 static const struct acpi_device_id ac_device_ids[] = {
@@ -51,21 +52,10 @@ static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume);
 static int ac_sleep_before_get_state_ms;
 static int ac_only;
 
-static struct acpi_driver acpi_ac_driver = {
-   .name = "ac",
-   .class = ACPI_AC_CLASS,
-   .ids = ac_device_ids,
-   .ops = {
-   .add = acpi_ac_add,
-   .remove = acpi_ac_remove,
-   },
-   .drv.pm = _ac_pm,
-};
-
 struct acpi_ac {
struct power_supply *charger;
struct power_supply_desc charger_desc;
-   struct acpi_device *device;
+   struct device *dev;
unsigned long long state;
struct notifier_block battery_nb;
 };
@@ -85,10 +75,10 @@ static int acpi_ac_get_state(struct acpi_ac *ac)
return 0;
}
 
-   status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL,
+   status = acpi_evaluate_integer(ACPI_HANDLE(ac->dev), "_PSR", NULL,
   >state);
if (ACPI_FAILURE(status)) {
-   acpi_handle_info(ac->device->handle,
+   acpi_handle_info(ACPI_HANDLE(ac->dev),
"Error reading AC Adapter state: %s\n",
acpi_format_exception(status));
ac->state = ACPI_AC_STATUS_UNKNOWN;
@@ -129,12 +119,12 @@ static enum power_supply_property ac_props[] = {
 /* Driver Model */
 static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
 {
-   struct acpi_device *device = data;
-   struct acpi_ac *ac = acpi_driver_data(device);
+   struct acpi_ac *ac = data;
+   struct acpi_device *device = ACPI_COMPANION(ac->dev);
 
switch (event) {
default:
-   acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
+   acpi_handle_debug(ACPI_HANDLE(ac->dev), "Unsupported event 
[0x%x]\n",
  event);
fallthrough;
case ACPI_AC_NOTIFY_STATUS:
@@ -152,9 +142,10 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, 
void *data)
 
acpi_ac_get_state(ac);
acpi_bus_generate_netlink_event(device->pnp.device_class,
- dev_name(>dev), event,
- (u32) ac->state);
-   acpi_notifier_call_chain(device, event, (u32) ac->state);
+   dev_name(ac->dev),
+   event,
+   ac->state);
+   acpi_notifier_call_chain(device, event, ac->state);
kobject_uevent(>charger->dev.kobj, KOBJ_CHANGE);
}
 }
@@ -211,8 +202,9 @@ static const struct dmi_system_id ac_dmi_table[]  
__initconst = {
{},
 };
 
-static int acpi_ac_add(struct acpi_device *device)
+static int acpi_ac_probe(struct platform_device *pdev)
 {
+   struct acpi_device *device = ACPI_COMPANION(>dev);
struct power_supply_config psy_cfg = {};
struct acpi_ac *ac;
int result;
@@ -221,10 +213,11 @@ static int acpi_ac_add(struct acpi_device *device)
if (!ac)
return -ENOMEM;
 
-   ac->device = device;
+   ac->dev = >dev;
strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_AC_CLASS);
-   device->driver_data = ac;
+
+   platform_s

[PATCH v2 2/6] ACPI: AC: Use string_choices API instead of ternary operator

2023-10-06 Thread Michal Wilczynski
Use modern string_choices API instead of manually determining the
output using ternary operator.

Suggested-by: Andy Shevchenko 
Reviewed-by: Andy Shevchenko 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/ac.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 83d45c681121..f809f6889b4a 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -243,8 +244,8 @@ static int acpi_ac_add(struct acpi_device *device)
goto err_release_ac;
}
 
-   pr_info("%s [%s] (%s)\n", acpi_device_name(device),
-   acpi_device_bid(device), ac->state ? "on-line" : "off-line");
+   pr_info("%s [%s] (%s-line)\n", acpi_device_name(device),
+   acpi_device_bid(device), str_on_off(ac->state));
 
ac->battery_nb.notifier_call = acpi_ac_battery_notify;
register_acpi_notifier(>battery_nb);
-- 
2.41.0




[PATCH v2 1/6] ACPI: AC: Remove unnecessary checks

2023-10-06 Thread Michal Wilczynski
Remove unnecessary checks for NULL for variables that can't be NULL at
the point they're checked for it. Defensive programming is discouraged
in the kernel.

Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/ac.c | 27 ---
 1 file changed, 4 insertions(+), 23 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index aac3e561790c..83d45c681121 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -131,9 +131,6 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, 
void *data)
struct acpi_device *device = data;
struct acpi_ac *ac = acpi_driver_data(device);
 
-   if (!ac)
-   return;
-
switch (event) {
default:
acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
@@ -216,12 +213,8 @@ static const struct dmi_system_id ac_dmi_table[]  
__initconst = {
 static int acpi_ac_add(struct acpi_device *device)
 {
struct power_supply_config psy_cfg = {};
-   int result = 0;
-   struct acpi_ac *ac = NULL;
-
-
-   if (!device)
-   return -EINVAL;
+   struct acpi_ac *ac;
+   int result;
 
ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL);
if (!ac)
@@ -275,16 +268,9 @@ static int acpi_ac_add(struct acpi_device *device)
 #ifdef CONFIG_PM_SLEEP
 static int acpi_ac_resume(struct device *dev)
 {
-   struct acpi_ac *ac;
+   struct acpi_ac *ac = acpi_driver_data(to_acpi_device(dev));
unsigned int old_state;
 
-   if (!dev)
-   return -EINVAL;
-
-   ac = acpi_driver_data(to_acpi_device(dev));
-   if (!ac)
-   return -EINVAL;
-
old_state = ac->state;
if (acpi_ac_get_state(ac))
return 0;
@@ -299,12 +285,7 @@ static int acpi_ac_resume(struct device *dev)
 
 static void acpi_ac_remove(struct acpi_device *device)
 {
-   struct acpi_ac *ac = NULL;
-
-   if (!device || !acpi_driver_data(device))
-   return;
-
-   ac = acpi_driver_data(device);
+   struct acpi_ac *ac = acpi_driver_data(device);
 
acpi_dev_remove_notify_handler(device, ACPI_ALL_NOTIFY,
   acpi_ac_notify);
-- 
2.41.0




[PATCH v2 0/6] Replace acpi_driver with platform_driver

2023-10-06 Thread Michal Wilczynski
Currently there is a number of drivers that somewhat incorrectly
register themselves as acpi_driver, while they should be registering as
platform_drivers. acpi_device was never meant to represent actual
device, it only represents an entry in the ACPI table and ACPI driver
should be treated as a driver for the ACPI entry of the particular
device, not the device itself. Drivers of the devices itself should
register as platform_drivers. Replace acpi_driver with platform_driver
for all relevant drivers in drivers/acpi directory. This is just the
first part of the change, as many acpi_drivers are present in many files
outside of drivers/acpi directory.

Additionally during internal review we've decided that it's best to send
the relevant patches sequentially, in order not to overwhelm the reviewers.
So I'm starting with NFIT and AC drivers.

This change is possible thanks to recent .notify callback removal in
drivers/acpi [1]. So flow for the remaining acpi_drivers will look like
this:

1) Remove .notify callback with separate patchset for drivers/platform
   and other outstanding places like drivers/hwmon, drivers/iio etc.
2) Replace acpi_driver with platform_driver, as aside for .notify
   callback they're mostly functionally compatible.

Most of the patches in this series could be considered independent, and
could be merged separately, with a notable exception of the very first
patch in this series that changes notify installer wrappers to be more
generic. I decided it would be best not to force the user of this
wrappers to pass any specific structure, like acpi_device or
platform_device. It makes sense as it is very often the case that
drivers declare their own private structure which gets allocated during
the .probe() callback, and become the heart of the driver. In that case
it makes much more sense to pass this structure to notify handler.
Additionally some drivers, like acpi_video that already have custom
notify handlers do that already.

Link: 
https://lore.kernel.org/linux-acpi/20230703080252.2899090-1-michal.wilczyn...@intel.com/
 [1]

v2:
 - dropped first, second and last commit. Last commit was deemed
   pointless, first and second are already merged.
 - rebased on top of modified first commit (changes in the wrappers)

Michal Wilczynski (6):
  ACPI: AC: Remove unnecessary checks
  ACPI: AC: Use string_choices API instead of ternary operator
  ACPI: AC: Replace acpi_driver with platform_driver
  ACPI: AC: Rename ACPI device from device to adev
  ACPI: NFIT: Replace acpi_driver with platform_driver
  ACPI: NFIT: Remove redundant call to to_acpi_dev()

 drivers/acpi/ac.c| 108 +--
 drivers/acpi/nfit/core.c |  38 +++---
 2 files changed, 66 insertions(+), 80 deletions(-)

-- 
2.41.0




[PATCH v1 1/2] ACPI: NFIT: Fix memory leak, and local use of devm_*()

2023-09-26 Thread Michal Wilczynski
devm_*() family of functions purpose is managing memory attached to a
device. So in general it should only be used for allocations that should
last for the whole lifecycle of the device. This is not the case for
acpi_nfit_init_interleave_set(). There are two allocations that are only
used locally in this function. What's more - if the function exits on
error path memory is never freed. It's still attached to dev and would
be freed on device detach, so this leak could be called a 'local leak'.

Fix this by switching from devm_kcalloc() to kcalloc(), and adding
proper rollback.

Fixes: eaf961536e16 ("libnvdimm, nfit: add interleave-set state-tracking 
infrastructure")
Reported-by: Andy Shevchenko 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/nfit/core.c | 23 +++
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index f0e6738ae3c9..78f0f855c4de 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -2262,6 +2262,7 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
u16 nr = ndr_desc->num_mappings;
struct nfit_set_info2 *info2;
struct nfit_set_info *info;
+   int err = 0;
int i;
 
nd_set = devm_kzalloc(dev, sizeof(*nd_set), GFP_KERNEL);
@@ -2269,13 +2270,15 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
return -ENOMEM;
import_guid(_set->type_guid, spa->range_guid);
 
-   info = devm_kcalloc(dev, nr, sizeof(*info), GFP_KERNEL);
+   info = kcalloc(nr, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
 
-   info2 = devm_kcalloc(dev, nr, sizeof(*info2), GFP_KERNEL);
-   if (!info2)
-   return -ENOMEM;
+   info2 = kcalloc(nr, sizeof(*info2), GFP_KERNEL);
+   if (!info2) {
+   err = -ENOMEM;
+   goto free_info;
+   }
 
for (i = 0; i < nr; i++) {
struct nd_mapping_desc *mapping = _desc->mapping[i];
@@ -2289,7 +2292,8 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
 
if (!memdev || !nfit_mem->dcr) {
dev_err(dev, "%s: failed to find DCR\n", __func__);
-   return -ENODEV;
+   err = -ENODEV;
+   goto free_info2;
}
 
map->region_offset = memdev->region_offset;
@@ -2337,10 +2341,13 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
}
 
ndr_desc->nd_set = nd_set;
-   devm_kfree(dev, info);
-   devm_kfree(dev, info2);
 
-   return 0;
+free_info2:
+   kfree(info2);
+free_info:
+   kfree(info);
+
+   return err;
 }
 
 static int ars_get_cap(struct acpi_nfit_desc *acpi_desc,
-- 
2.41.0




[PATCH v1 2/2] ACPI: NFIT: Use modern scope based rollback

2023-09-26 Thread Michal Wilczynski
Change rollback in acpi_nfit_init_interleave_set() to use modern scope
based attribute __free(). This is similar to C++ RAII and is a preferred
way for handling local memory allocations.

Suggested-by: Dave Jiang 
Suggested-by: Andy Shevchenko 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/nfit/core.c | 32 ++--
 1 file changed, 10 insertions(+), 22 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 78f0f855c4de..079bd663495f 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -2257,29 +2257,23 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
struct nd_region_desc *ndr_desc,
struct acpi_nfit_system_address *spa)
 {
+   u16 nr = ndr_desc->num_mappings;
+   struct nfit_set_info2 *info2 __free(kfree) =
+   kcalloc(nr, sizeof(*info2), GFP_KERNEL);
+   struct nfit_set_info *info __free(kfree) =
+   kcalloc(nr, sizeof(*info), GFP_KERNEL);
struct device *dev = acpi_desc->dev;
struct nd_interleave_set *nd_set;
-   u16 nr = ndr_desc->num_mappings;
-   struct nfit_set_info2 *info2;
-   struct nfit_set_info *info;
-   int err = 0;
int i;
 
+   if (!info || !info2)
+   return -ENOMEM;
+
nd_set = devm_kzalloc(dev, sizeof(*nd_set), GFP_KERNEL);
if (!nd_set)
return -ENOMEM;
import_guid(_set->type_guid, spa->range_guid);
 
-   info = kcalloc(nr, sizeof(*info), GFP_KERNEL);
-   if (!info)
-   return -ENOMEM;
-
-   info2 = kcalloc(nr, sizeof(*info2), GFP_KERNEL);
-   if (!info2) {
-   err = -ENOMEM;
-   goto free_info;
-   }
-
for (i = 0; i < nr; i++) {
struct nd_mapping_desc *mapping = _desc->mapping[i];
struct nvdimm *nvdimm = mapping->nvdimm;
@@ -2292,8 +2286,7 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
 
if (!memdev || !nfit_mem->dcr) {
dev_err(dev, "%s: failed to find DCR\n", __func__);
-   err = -ENODEV;
-   goto free_info2;
+   return -ENODEV;
}
 
map->region_offset = memdev->region_offset;
@@ -2342,12 +2335,7 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
 
ndr_desc->nd_set = nd_set;
 
-free_info2:
-   kfree(info2);
-free_info:
-   kfree(info);
-
-   return err;
+   return 0;
 }
 
 static int ars_get_cap(struct acpi_nfit_desc *acpi_desc,
-- 
2.41.0




[PATCH v1 0/2] Fix memory leak and move to modern scope based rollback

2023-09-26 Thread Michal Wilczynski
In acpi_nfit_init_interleave_set() there is a memory leak + improper use
of devm_*() family of functions for local memory allocations. This patch
series provides two commits - one is meant as a bug fix, and could
potentially be backported, and the other one improves old style rollback
with scope based, similar to C++ RAII [1].

Link: https://lwn.net/Articles/934679/ [1]

Michal Wilczynski (2):
  ACPI: NFIT: Fix memory leak, and local use of devm_*()
  ACPI: NFIT: Use modern scope based rollback

 drivers/acpi/nfit/core.c | 21 -
 1 file changed, 8 insertions(+), 13 deletions(-)

-- 
2.41.0




[PATCH v1 9/9] ACPI: NFIT: Don't use KBUILD_MODNAME for driver name

2023-09-25 Thread Michal Wilczynski
Driver name is part of the ABI, so it should be hard-coded, as ABI
should be always kept backward compatible. Prevent ABI from changing
accidentally in case KBUILD_MODNAME change.

Suggested-by: Andy Shevchenko 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/nfit/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index f09530d2520a..987eb5567036 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -3478,7 +3478,7 @@ MODULE_DEVICE_TABLE(acpi, acpi_nfit_ids);
 static struct platform_driver acpi_nfit_driver = {
.probe = acpi_nfit_probe,
.driver = {
-   .name = KBUILD_MODNAME,
+   .name = "nfit",
.acpi_match_table = acpi_nfit_ids,
},
 };
-- 
2.41.0




[PATCH v1 8/9] ACPI: NFIT: Remove redundant call to to_acpi_dev()

2023-09-25 Thread Michal Wilczynski
In acpi_nfit_ctl() ACPI handle is extracted using to_acpi_dev()
function and accessing handle field in ACPI device. After transformation
from ACPI driver to platform driver this is not optimal anymore. To get
a handle it's enough to just use ACPI_HANDLE() macro to extract the
handle.

Suggested-by: Andy Shevchenko 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/nfit/core.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 2e50b1334a69..f09530d2520a 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -475,8 +475,6 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, 
struct nvdimm *nvdimm,
guid = to_nfit_uuid(nfit_mem->family);
handle = adev->handle;
} else {
-   struct acpi_device *adev = to_acpi_dev(acpi_desc);
-
cmd_name = nvdimm_bus_cmd_name(cmd);
cmd_mask = nd_desc->cmd_mask;
if (cmd == ND_CMD_CALL && call_pkg->nd_family) {
@@ -493,7 +491,7 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, 
struct nvdimm *nvdimm,
guid = to_nfit_uuid(NFIT_DEV_BUS);
}
desc = nd_cmd_bus_desc(cmd);
-   handle = adev->handle;
+   handle = ACPI_HANDLE(dev);
dimm_name = "bus";
}
 
-- 
2.41.0




[PATCH v1 7/9] ACPI: NFIT: Replace acpi_driver with platform_driver

2023-09-25 Thread Michal Wilczynski
NFIT driver uses struct acpi_driver incorrectly to register itself.
This is wrong as the instances of the ACPI devices are not meant
to be literal devices, they're supposed to describe ACPI entry of a
particular device.

Use platform_driver instead of acpi_driver. In relevant places call
platform devices instances pdev to make a distinction with ACPI
devices instances.

NFIT driver uses devm_*() family of functions extensively. This change
has no impact on correct functioning of the whole devm_*() family of
functions, since the lifecycle of the device stays the same. It is still
being created during the enumeration, and destroyed on platform device
removal.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/nfit/core.c | 34 ++
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 821870f57862..2e50b1334a69 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include "intel.h"
@@ -98,7 +99,7 @@ static struct acpi_device *to_acpi_dev(struct acpi_nfit_desc 
*acpi_desc)
|| 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)
@@ -3284,11 +3285,11 @@ static void acpi_nfit_put_table(void *table)
 
 static void acpi_nfit_notify(acpi_handle handle, u32 event, void *data)
 {
-   struct acpi_device *adev = data;
+   struct device *dev = data;
 
-   device_lock(>dev);
-   __acpi_nfit_notify(>dev, handle, event);
-   device_unlock(>dev);
+   device_lock(dev);
+   __acpi_nfit_notify(dev, handle, event);
+   device_unlock(dev);
 }
 
 static void acpi_nfit_remove_notify_handler(void *data)
@@ -3329,11 +3330,12 @@ 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 = >dev;
+   struct device *dev = >dev;
+   struct acpi_device *adev = ACPI_COMPANION(dev);
struct acpi_table_header *tbl;
acpi_status status = AE_OK;
acpi_size sz;
@@ -3360,7 +3362,7 @@ static int acpi_nfit_add(struct acpi_device *adev)
acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL);
if (!acpi_desc)
return -ENOMEM;
-   acpi_nfit_desc_init(acpi_desc, >dev);
+   acpi_nfit_desc_init(acpi_desc, dev);
 
/* Save the acpi header for exporting the revision via sysfs */
acpi_desc->acpi_header = *tbl;
@@ -3391,7 +3393,7 @@ static int acpi_nfit_add(struct acpi_device *adev)
return rc;
 
rc = acpi_dev_install_notify_handler(adev->handle, ACPI_DEVICE_NOTIFY,
-acpi_nfit_notify, adev);
+acpi_nfit_notify, dev);
if (rc)
return rc;
 
@@ -3475,11 +3477,11 @@ static const struct acpi_device_id acpi_nfit_ids[] = {
 };
 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 = KBUILD_MODNAME,
+   .acpi_match_table = acpi_nfit_ids,
},
 };
 
@@ -3517,7 +3519,7 @@ static __init int nfit_init(void)
return -ENOMEM;
 
nfit_mce_register();
-   ret = acpi_bus_register_driver(_nfit_driver);
+   ret = platform_driver_register(_nfit_driver);
if (ret) {
nfit_mce_unregister();
destroy_workqueue(nfit_wq);
@@ -3530,7 +3532,7 @@ static __init int nfit_init(void)
 static __exit void nfit_exit(void)
 {
nfit_mce_unregister();
-   acpi_bus_unregister_driver(_nfit_driver);
+   platform_driver_unregister(_nfit_driver);
destroy_workqueue(nfit_wq);
WARN_ON(!list_empty(_descs));
 }
-- 
2.41.0




[PATCH v1 6/9] ACPI: AC: Rename ACPI device from device to adev

2023-09-25 Thread Michal Wilczynski
Since transformation from ACPI driver to platform driver there are two
devices on which the driver operates - ACPI device and platform device.
For the sake of reader this calls for the distinction in their naming,
to avoid confusion. Rename device to adev, as corresponding
platform device is called pdev.

Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/ac.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 78e53d0fdece..270a6919ec12 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -120,7 +120,7 @@ static enum power_supply_property ac_props[] = {
 static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
 {
struct acpi_ac *ac = data;
-   struct acpi_device *device = ACPI_COMPANION(ac->dev);
+   struct acpi_device *adev = ACPI_COMPANION(ac->dev);
 
switch (event) {
default:
@@ -141,11 +141,11 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, 
void *data)
msleep(ac_sleep_before_get_state_ms);
 
acpi_ac_get_state(ac);
-   acpi_bus_generate_netlink_event(device->pnp.device_class,
+   acpi_bus_generate_netlink_event(adev->pnp.device_class,
dev_name(ac->dev),
event,
ac->state);
-   acpi_notifier_call_chain(device, event, ac->state);
+   acpi_notifier_call_chain(adev, event, ac->state);
kobject_uevent(>charger->dev.kobj, KOBJ_CHANGE);
}
 }
@@ -204,7 +204,7 @@ static const struct dmi_system_id ac_dmi_table[]  
__initconst = {
 
 static int acpi_ac_probe(struct platform_device *pdev)
 {
-   struct acpi_device *device = ACPI_COMPANION(>dev);
+   struct acpi_device *adev = ACPI_COMPANION(>dev);
struct power_supply_config psy_cfg = {};
struct acpi_ac *ac;
int result;
@@ -214,8 +214,8 @@ static int acpi_ac_probe(struct platform_device *pdev)
return -ENOMEM;
 
ac->dev = >dev;
-   strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME);
-   strcpy(acpi_device_class(device), ACPI_AC_CLASS);
+   strcpy(acpi_device_name(adev), ACPI_AC_DEVICE_NAME);
+   strcpy(acpi_device_class(adev), ACPI_AC_CLASS);
 
platform_set_drvdata(pdev, ac);
 
@@ -225,7 +225,7 @@ static int acpi_ac_probe(struct platform_device *pdev)
 
psy_cfg.drv_data = ac;
 
-   ac->charger_desc.name = acpi_device_bid(device);
+   ac->charger_desc.name = acpi_device_bid(adev);
ac->charger_desc.type = POWER_SUPPLY_TYPE_MAINS;
ac->charger_desc.properties = ac_props;
ac->charger_desc.num_properties = ARRAY_SIZE(ac_props);
@@ -237,13 +237,13 @@ static int acpi_ac_probe(struct platform_device *pdev)
goto err_release_ac;
}
 
-   pr_info("%s [%s] (%s-line)\n", acpi_device_name(device),
-   acpi_device_bid(device), str_on_off(ac->state));
+   pr_info("%s [%s] (%s-line)\n", acpi_device_name(adev),
+   acpi_device_bid(adev), str_on_off(ac->state));
 
ac->battery_nb.notifier_call = acpi_ac_battery_notify;
register_acpi_notifier(>battery_nb);
 
-   result = acpi_dev_install_notify_handler(device->handle, 
ACPI_ALL_NOTIFY,
+   result = acpi_dev_install_notify_handler(adev->handle, ACPI_ALL_NOTIFY,
 acpi_ac_notify, ac);
if (result)
goto err_unregister;
-- 
2.41.0




[PATCH v1 5/9] ACPI: AC: Replace acpi_driver with platform_driver

2023-09-25 Thread Michal Wilczynski
AC driver uses struct acpi_driver incorrectly to register itself. This
is wrong as the instances of the ACPI devices are not meant to
be literal devices, they're supposed to describe ACPI entry of a
particular device.

Use platform_driver instead of acpi_driver. In relevant places call
platform devices instances pdev to make a distinction with ACPI
devices instances.

Drop unnecessary casts from acpi_bus_generate_netlink_event() and
acpi_notifier_call_chain().

Add a blank line to distinguish pdev API vs local ACPI notify function.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/ac.c | 70 +--
 1 file changed, 37 insertions(+), 33 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index fd8b392c19f4..78e53d0fdece 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -33,8 +33,9 @@ MODULE_AUTHOR("Paul Diefenbaugh");
 MODULE_DESCRIPTION("ACPI AC Adapter Driver");
 MODULE_LICENSE("GPL");
 
-static int acpi_ac_add(struct acpi_device *device);
-static void acpi_ac_remove(struct acpi_device *device);
+static int acpi_ac_probe(struct platform_device *pdev);
+static void acpi_ac_remove(struct platform_device *pdev);
+
 static void acpi_ac_notify(acpi_handle handle, u32 event, void *data);
 
 static const struct acpi_device_id ac_device_ids[] = {
@@ -51,21 +52,10 @@ static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume);
 static int ac_sleep_before_get_state_ms;
 static int ac_only;
 
-static struct acpi_driver acpi_ac_driver = {
-   .name = "ac",
-   .class = ACPI_AC_CLASS,
-   .ids = ac_device_ids,
-   .ops = {
-   .add = acpi_ac_add,
-   .remove = acpi_ac_remove,
-   },
-   .drv.pm = _ac_pm,
-};
-
 struct acpi_ac {
struct power_supply *charger;
struct power_supply_desc charger_desc;
-   struct acpi_device *device;
+   struct device *dev;
unsigned long long state;
struct notifier_block battery_nb;
 };
@@ -85,10 +75,10 @@ static int acpi_ac_get_state(struct acpi_ac *ac)
return 0;
}
 
-   status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL,
+   status = acpi_evaluate_integer(ACPI_HANDLE(ac->dev), "_PSR", NULL,
   >state);
if (ACPI_FAILURE(status)) {
-   acpi_handle_info(ac->device->handle,
+   acpi_handle_info(ACPI_HANDLE(ac->dev),
"Error reading AC Adapter state: %s\n",
acpi_format_exception(status));
ac->state = ACPI_AC_STATUS_UNKNOWN;
@@ -129,12 +119,12 @@ static enum power_supply_property ac_props[] = {
 /* Driver Model */
 static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
 {
-   struct acpi_device *device = data;
-   struct acpi_ac *ac = acpi_driver_data(device);
+   struct acpi_ac *ac = data;
+   struct acpi_device *device = ACPI_COMPANION(ac->dev);
 
switch (event) {
default:
-   acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
+   acpi_handle_debug(ACPI_HANDLE(ac->dev), "Unsupported event 
[0x%x]\n",
  event);
fallthrough;
case ACPI_AC_NOTIFY_STATUS:
@@ -152,9 +142,10 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, 
void *data)
 
acpi_ac_get_state(ac);
acpi_bus_generate_netlink_event(device->pnp.device_class,
- dev_name(>dev), event,
- (u32) ac->state);
-   acpi_notifier_call_chain(device, event, (u32) ac->state);
+   dev_name(ac->dev),
+   event,
+   ac->state);
+   acpi_notifier_call_chain(device, event, ac->state);
kobject_uevent(>charger->dev.kobj, KOBJ_CHANGE);
}
 }
@@ -211,8 +202,9 @@ static const struct dmi_system_id ac_dmi_table[]  
__initconst = {
{},
 };
 
-static int acpi_ac_add(struct acpi_device *device)
+static int acpi_ac_probe(struct platform_device *pdev)
 {
+   struct acpi_device *device = ACPI_COMPANION(>dev);
struct power_supply_config psy_cfg = {};
struct acpi_ac *ac;
int result;
@@ -221,10 +213,11 @@ static int acpi_ac_add(struct acpi_device *device)
if (!ac)
return -ENOMEM;
 
-   ac->device = device;
+   ac->dev = >dev;
strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_AC_CLASS);
-   device->driver_data = ac;
+
+   platform_s

[PATCH v1 4/9] ACPI: AC: Use string_choices API instead of ternary operator

2023-09-25 Thread Michal Wilczynski
Use modern string_choices API instead of manually determining the
output using ternary operator.

Suggested-by: Andy Shevchenko 
Reviewed-by: Andy Shevchenko 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/ac.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index dd04809a787c..fd8b392c19f4 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -243,8 +244,8 @@ static int acpi_ac_add(struct acpi_device *device)
goto err_release_ac;
}
 
-   pr_info("%s [%s] (%s)\n", acpi_device_name(device),
-   acpi_device_bid(device), ac->state ? "on-line" : "off-line");
+   pr_info("%s [%s] (%s-line)\n", acpi_device_name(device),
+   acpi_device_bid(device), str_on_off(ac->state));
 
ac->battery_nb.notifier_call = acpi_ac_battery_notify;
register_acpi_notifier(>battery_nb);
-- 
2.41.0




[PATCH v1 1/9] ACPI: bus: Make notify wrappers more generic

2023-09-25 Thread Michal Wilczynski
acpi_dev_install_notify_handler() and acpi_dev_remove_notify_handler()
are wrappers around ACPICA installers. They are meant to save some
duplicated code from drivers. However as we're moving towards drivers
operating on platform_device they become a bit inconvenient to use as
inside the driver code we mostly want to use driver data of platform
device instead of ACPI device.

Make notify handlers installer wrappers more generic, while still
saving some code that would be duplicated otherwise.

Reviewed-by: Andy Shevchenko 
Signed-off-by: Michal Wilczynski 
---

Notes:
So one solution could be to just replace acpi_device with
platform_device as an argument in those functions. However I don't
believe this is a correct solution, as it is very often the case that
drivers declare their own private structures which gets allocated during
the .probe() callback, and become the heart of the driver. When drivers
do that it makes much more sense to just pass the private structure
to the notify handler instead of forcing user to dance with the
platform_device or acpi_device.

 drivers/acpi/ac.c |  6 +++---
 drivers/acpi/acpi_video.c |  6 +++---
 drivers/acpi/battery.c|  6 +++---
 drivers/acpi/bus.c| 14 ++
 drivers/acpi/hed.c|  6 +++---
 drivers/acpi/nfit/core.c  |  6 +++---
 drivers/acpi/thermal.c|  6 +++---
 include/acpi/acpi_bus.h   |  9 -
 8 files changed, 28 insertions(+), 31 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 225dc6818751..0b245f9f7ec8 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -256,8 +256,8 @@ static int acpi_ac_add(struct acpi_device *device)
ac->battery_nb.notifier_call = acpi_ac_battery_notify;
register_acpi_notifier(>battery_nb);
 
-   result = acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY,
-acpi_ac_notify);
+   result = acpi_dev_install_notify_handler(device->handle, 
ACPI_ALL_NOTIFY,
+acpi_ac_notify, device);
if (result)
goto err_unregister;
 
@@ -306,7 +306,7 @@ static void acpi_ac_remove(struct acpi_device *device)
 
ac = acpi_driver_data(device);
 
-   acpi_dev_remove_notify_handler(device, ACPI_ALL_NOTIFY,
+   acpi_dev_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY,
   acpi_ac_notify);
power_supply_unregister(ac->charger);
unregister_acpi_notifier(>battery_nb);
diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
index 948e31f7ce6e..025c17890127 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video.c
@@ -2059,8 +2059,8 @@ static int acpi_video_bus_add(struct acpi_device *device)
 
acpi_video_bus_add_notify_handler(video);
 
-   error = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
-   acpi_video_bus_notify);
+   error = acpi_dev_install_notify_handler(device->handle, 
ACPI_DEVICE_NOTIFY,
+   acpi_video_bus_notify, device);
if (error)
goto err_remove;
 
@@ -2092,7 +2092,7 @@ static void acpi_video_bus_remove(struct acpi_device 
*device)
 
video = acpi_driver_data(device);
 
-   acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY,
+   acpi_dev_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
   acpi_video_bus_notify);
 
mutex_lock(_list_lock);
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 969bf81e8d54..45dae32a8646 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -1213,8 +1213,8 @@ static int acpi_battery_add(struct acpi_device *device)
 
device_init_wakeup(>dev, 1);
 
-   result = acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY,
-acpi_battery_notify);
+   result = acpi_dev_install_notify_handler(device->handle, 
ACPI_ALL_NOTIFY,
+acpi_battery_notify, device);
if (result)
goto fail_pm;
 
@@ -1241,7 +1241,7 @@ static void acpi_battery_remove(struct acpi_device 
*device)
 
battery = acpi_driver_data(device);
 
-   acpi_dev_remove_notify_handler(device, ACPI_ALL_NOTIFY,
+   acpi_dev_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY,
   acpi_battery_notify);
 
device_init_wakeup(>dev, 0);
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index f41dda2d3493..479fe888d629 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -554,14 +554,13 @@ static void acpi_device_remove_notify_handler(struct 
acpi_device *device,
acpi_os_wait_events_complete();
 }
 
-int acpi_dev_install_not

[PATCH v1 3/9] ACPI: AC: Remove unnecessary checks

2023-09-25 Thread Michal Wilczynski
Remove unnecessary checks for NULL for variables that can't be NULL at
the point they're checked for it. Defensive programming is discouraged
in the kernel.

Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/ac.c | 27 ---
 1 file changed, 4 insertions(+), 23 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 0b245f9f7ec8..dd04809a787c 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -131,9 +131,6 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, 
void *data)
struct acpi_device *device = data;
struct acpi_ac *ac = acpi_driver_data(device);
 
-   if (!ac)
-   return;
-
switch (event) {
default:
acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
@@ -216,12 +213,8 @@ static const struct dmi_system_id ac_dmi_table[]  
__initconst = {
 static int acpi_ac_add(struct acpi_device *device)
 {
struct power_supply_config psy_cfg = {};
-   int result = 0;
-   struct acpi_ac *ac = NULL;
-
-
-   if (!device)
-   return -EINVAL;
+   struct acpi_ac *ac;
+   int result;
 
ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL);
if (!ac)
@@ -275,16 +268,9 @@ static int acpi_ac_add(struct acpi_device *device)
 #ifdef CONFIG_PM_SLEEP
 static int acpi_ac_resume(struct device *dev)
 {
-   struct acpi_ac *ac;
+   struct acpi_ac *ac = acpi_driver_data(to_acpi_device(dev));
unsigned int old_state;
 
-   if (!dev)
-   return -EINVAL;
-
-   ac = acpi_driver_data(to_acpi_device(dev));
-   if (!ac)
-   return -EINVAL;
-
old_state = ac->state;
if (acpi_ac_get_state(ac))
return 0;
@@ -299,12 +285,7 @@ static int acpi_ac_resume(struct device *dev)
 
 static void acpi_ac_remove(struct acpi_device *device)
 {
-   struct acpi_ac *ac = NULL;
-
-   if (!device || !acpi_driver_data(device))
-   return;
-
-   ac = acpi_driver_data(device);
+   struct acpi_ac *ac = acpi_driver_data(device);
 
acpi_dev_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY,
   acpi_ac_notify);
-- 
2.41.0




[PATCH v1 2/9] docs: firmware-guide: ACPI: Clarify ACPI bus concepts

2023-09-25 Thread Michal Wilczynski
Some devices implement ACPI driver as a way to manage devices
enumerated by the ACPI. This might be confusing as a preferred way to
implement a driver for devices not connected to any bus is a platform
driver, as stated in the documentation. Clarify relationships between
ACPI device, platform device and ACPI entries.

Suggested-by: Elena Reshetova 
Signed-off-by: Michal Wilczynski 
---
 Documentation/firmware-guide/acpi/enumeration.rst | 13 +
 1 file changed, 13 insertions(+)

diff --git a/Documentation/firmware-guide/acpi/enumeration.rst 
b/Documentation/firmware-guide/acpi/enumeration.rst
index 56d9913a3370..f56cc79a9e83 100644
--- a/Documentation/firmware-guide/acpi/enumeration.rst
+++ b/Documentation/firmware-guide/acpi/enumeration.rst
@@ -64,6 +64,19 @@ If the driver needs to perform more complex initialization 
like getting and
 configuring GPIOs it can get its ACPI handle and extract this information
 from ACPI tables.
 
+ACPI bus
+
+
+Historically some devices not connected to any bus were represented as ACPI
+devices, and had to implement ACPI driver. This is not a preferred way for new
+drivers. As explained above devices not connected to any bus should implement
+platform driver. ACPI device would be created during enumeration nonetheless,
+and would be accessible through ACPI_COMPANION() macro, and the ACPI handle 
would
+be accessible through ACPI_HANDLE() macro. ACPI device is meant to describe
+information related to ACPI entry e.g. handle of the ACPI entry. Think -
+ACPI device interfaces with the FW, and the platform device with the rest of
+the system.
+
 DMA support
 ===
 
-- 
2.41.0




[PATCH v1 0/9] Replace acpi_driver with platform_driver

2023-09-25 Thread Michal Wilczynski
Currently there is a number of drivers that somewhat incorrectly
register themselves as acpi_driver, while they should be registering as
platform_drivers. acpi_device was never meant to represent actual
device, it only represents an entry in the ACPI table and ACPI driver
should be treated as a driver for the ACPI entry of the particular
device, not the device itself. Drivers of the devices itself should
register as platform_drivers. Replace acpi_driver with platform_driver
for all relevant drivers in drivers/acpi directory. This is just the
first part of the change, as many acpi_drivers are present in many files
outside of drivers/acpi directory.

Additionally during internal review we've decided that it's best to send
the relevant patches sequentially, in order not to overwhelm the reviewers.
So I'm starting with NFIT and AC drivers.

This change is possible thanks to recent .notify callback removal in
drivers/acpi [1]. So flow for the remaining acpi_drivers will look like
this:

1) Remove .notify callback with separate patchset for drivers/platform
   and other outstanding places like drivers/hwmon, drivers/iio etc.
2) Replace acpi_driver with platform_driver, as aside for .notify
   callback they're mostly functionally compatible.

Most of the patches in this series could be considered independent, and
could be merged separately, with a notable exception of the very first
patch in this series that changes notify installer wrappers to be more
generic. I decided it would be best not to force the user of this
wrappers to pass any specific structure, like acpi_device or
platform_device. It makes sense as it is very often the case that
drivers declare their own private structure which gets allocated during
the .probe() callback, and become the heart of the driver. In that case
it makes much more sense to pass this structure to notify handler.
Additionally some drivers, like acpi_video that already have custom
notify handlers do that already.

Link: 
https://lore.kernel.org/linux-acpi/20230703080252.2899090-1-michal.wilczyn...@intel.com/
 [1]

Michal Wilczynski (9):
  ACPI: bus: Make notify wrappers more generic
  docs: firmware-guide: ACPI: Clarify ACPI bus concepts
  ACPI: AC: Remove unnecessary checks
  ACPI: AC: Use string_choices API instead of ternary operator
  ACPI: AC: Replace acpi_driver with platform_driver
  ACPI: AC: Rename ACPI device from device to adev
  ACPI: NFIT: Replace acpi_driver with platform_driver
  ACPI: NFIT: Remove redundant call to to_acpi_dev()
  ACPI: NFIT: Don't use KBUILD_MODNAME for driver name

 .../firmware-guide/acpi/enumeration.rst   |  13 +++
 drivers/acpi/ac.c | 108 --
 drivers/acpi/acpi_video.c |   6 +-
 drivers/acpi/battery.c|   6 +-
 drivers/acpi/bus.c|  14 +--
 drivers/acpi/hed.c|   6 +-
 drivers/acpi/nfit/core.c  |  42 +++
 drivers/acpi/thermal.c|   6 +-
 include/acpi/acpi_bus.h   |   9 +-
 9 files changed, 103 insertions(+), 107 deletions(-)

-- 
2.41.0




[PATCH v7 9/9] acpi/thermal: Move handler installing logic to driver

2023-07-03 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of .remove()
callback. Change arguments passed to the notify function to match with
what's required by acpi_dev_install_notify_handler(). Remove .notify
callback initialization in acpi_driver.

While at it, fix whitespaces in .remove() callback.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/thermal.c | 25 -
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index f9f6ebb08fdb..97858ad59d68 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -825,8 +825,9 @@ static void acpi_queue_thermal_check(struct acpi_thermal 
*tz)
queue_work(acpi_thermal_pm_queue, >thermal_check_work);
 }
 
-static void acpi_thermal_notify(struct acpi_device *device, u32 event)
+static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
 {
+   struct acpi_device *device = data;
struct acpi_thermal *tz = acpi_driver_data(device);
 
if (!tz)
@@ -997,11 +998,21 @@ static int acpi_thermal_add(struct acpi_device *device)
 
pr_info("%s [%s] (%ld C)\n", acpi_device_name(device),
acpi_device_bid(device), 
deci_kelvin_to_celsius(tz->temperature));
-   goto end;
 
+   result = acpi_dev_install_notify_handler(device,
+ACPI_DEVICE_NOTIFY,
+acpi_thermal_notify);
+   if (result)
+   goto flush_wq;
+
+   return 0;
+
+flush_wq:
+   flush_workqueue(acpi_thermal_pm_queue);
+   acpi_thermal_unregister_thermal_zone(tz);
 free_memory:
kfree(tz);
-end:
+
return result;
 }
 
@@ -1012,10 +1023,15 @@ static void acpi_thermal_remove(struct acpi_device 
*device)
if (!device || !acpi_driver_data(device))
return;
 
-   flush_workqueue(acpi_thermal_pm_queue);
tz = acpi_driver_data(device);
 
+   acpi_dev_remove_notify_handler(device,
+  ACPI_DEVICE_NOTIFY,
+  acpi_thermal_notify);
+
+   flush_workqueue(acpi_thermal_pm_queue);
acpi_thermal_unregister_thermal_zone(tz);
+
kfree(tz);
 }
 
@@ -1078,7 +1094,6 @@ static struct acpi_driver acpi_thermal_driver = {
.ops = {
.add = acpi_thermal_add,
.remove = acpi_thermal_remove,
-   .notify = acpi_thermal_notify,
},
.drv.pm = _thermal_pm,
 };
-- 
2.41.0




[PATCH v7 8/9] acpi/nfit: Remove unnecessary .remove callback

2023-07-03 Thread Michal Wilczynski
Nfit driver doesn't use .remove() callback and provide an empty function
as it's .remove() callback. Remove empty acpi_nfit_remove() and
initialization of callback.

Suggested-by: Dan Williams 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/nfit/core.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 124e928647d3..16bf17a3d6ff 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -3402,11 +3402,6 @@ static int acpi_nfit_add(struct acpi_device *adev)
adev);
 }
 
-static void acpi_nfit_remove(struct acpi_device *adev)
-{
-   /* see acpi_nfit_unregister */
-}
-
 static void acpi_nfit_update_notify(struct device *dev, acpi_handle handle)
 {
struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(dev);
@@ -3488,7 +3483,6 @@ static struct acpi_driver acpi_nfit_driver = {
.ids = acpi_nfit_ids,
.ops = {
.add = acpi_nfit_add,
-   .remove = acpi_nfit_remove,
},
 };
 
-- 
2.41.0




[PATCH v7 7/9] acpi/nfit: Move handler installing logic to driver

2023-07-03 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of
acpi_nfit_shutdown(). Change arguments passed to the notify function to
match with what's required by acpi_dev_install_notify_handler(). Remove
.notify callback initialization in acpi_driver.

Introduce a new devm action acpi_nfit_remove_notify_handler.

Move acpi_nfit_notify() upwards in the file, so it can be used inside
acpi_nfit_add() and acpi_nfit_remove_notify_handler().

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/nfit/core.c | 41 +++-
 1 file changed, 32 insertions(+), 9 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 07204d482968..124e928647d3 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -3282,6 +3282,24 @@ static void acpi_nfit_put_table(void *table)
acpi_put_table(table);
 }
 
+static void acpi_nfit_notify(acpi_handle handle, u32 event, void *data)
+{
+   struct acpi_device *adev = data;
+
+   device_lock(>dev);
+   __acpi_nfit_notify(>dev, handle, event);
+   device_unlock(>dev);
+}
+
+static void acpi_nfit_remove_notify_handler(void *data)
+{
+   struct acpi_device *adev = data;
+
+   acpi_dev_remove_notify_handler(adev,
+  ACPI_DEVICE_NOTIFY,
+  acpi_nfit_notify);
+}
+
 void acpi_nfit_shutdown(void *data)
 {
struct acpi_nfit_desc *acpi_desc = data;
@@ -3368,7 +3386,20 @@ static int acpi_nfit_add(struct acpi_device *adev)
 
if (rc)
return rc;
-   return devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc);
+
+   rc = devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc);
+   if (rc)
+   return rc;
+
+   rc = acpi_dev_install_notify_handler(adev,
+ACPI_DEVICE_NOTIFY,
+acpi_nfit_notify);
+   if (rc)
+   return rc;
+
+   return devm_add_action_or_reset(dev,
+   acpi_nfit_remove_notify_handler,
+   adev);
 }
 
 static void acpi_nfit_remove(struct acpi_device *adev)
@@ -3446,13 +3477,6 @@ void __acpi_nfit_notify(struct device *dev, acpi_handle 
handle, u32 event)
 }
 EXPORT_SYMBOL_GPL(__acpi_nfit_notify);
 
-static void acpi_nfit_notify(struct acpi_device *adev, u32 event)
-{
-   device_lock(>dev);
-   __acpi_nfit_notify(>dev, adev->handle, event);
-   device_unlock(>dev);
-}
-
 static const struct acpi_device_id acpi_nfit_ids[] = {
{ "ACPI0012", 0 },
{ "", 0 },
@@ -3465,7 +3489,6 @@ static struct acpi_driver acpi_nfit_driver = {
.ops = {
.add = acpi_nfit_add,
.remove = acpi_nfit_remove,
-   .notify = acpi_nfit_notify,
},
 };
 
-- 
2.41.0




[PATCH v7 6/9] acpi/hed: Move handler installing logic to driver

2023-07-03 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of .remove()
callback. Change arguments passed to the notify function to match with
what's required by acpi_dev_install_notify_handler(). Remove .notify
callback initialization in acpi_driver.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/hed.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c
index 78d44e3fe129..8f54560c6d1c 100644
--- a/drivers/acpi/hed.c
+++ b/drivers/acpi/hed.c
@@ -42,22 +42,34 @@ EXPORT_SYMBOL_GPL(unregister_acpi_hed_notifier);
  * it is used by HEST Generic Hardware Error Source with notify type
  * SCI.
  */
-static void acpi_hed_notify(struct acpi_device *device, u32 event)
+static void acpi_hed_notify(acpi_handle handle, u32 event, void *data)
 {
blocking_notifier_call_chain(_hed_notify_list, 0, NULL);
 }
 
 static int acpi_hed_add(struct acpi_device *device)
 {
+   int err;
+
/* Only one hardware error device */
if (hed_handle)
return -EINVAL;
hed_handle = device->handle;
-   return 0;
+
+   err = acpi_dev_install_notify_handler(device,
+ ACPI_DEVICE_NOTIFY,
+ acpi_hed_notify);
+   if (err)
+   hed_handle = NULL;
+
+   return err;
 }
 
 static void acpi_hed_remove(struct acpi_device *device)
 {
+   acpi_dev_remove_notify_handler(device,
+  ACPI_DEVICE_NOTIFY,
+  acpi_hed_notify);
hed_handle = NULL;
 }
 
@@ -68,7 +80,6 @@ static struct acpi_driver acpi_hed_driver = {
.ops = {
.add = acpi_hed_add,
.remove = acpi_hed_remove,
-   .notify = acpi_hed_notify,
},
 };
 module_acpi_driver(acpi_hed_driver);
-- 
2.41.0




[PATCH v7 5/9] acpi/battery: Move handler installing logic to driver

2023-07-03 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of .remove()
callback. Change arguments passed to the notify function to match with
what's required by acpi_dev_install_notify_handler(). Remove .notify
callback initialization in acpi_driver.

While at it, fix lack of whitespaces in .remove() callback.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/battery.c | 26 +-
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 9c67ed02d797..4c634a4c32dd 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -1034,8 +1034,9 @@ static void acpi_battery_refresh(struct acpi_battery 
*battery)
 }
 
 /* Driver Interface */
-static void acpi_battery_notify(struct acpi_device *device, u32 event)
+static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
 {
+   struct acpi_device *device = data;
struct acpi_battery *battery = acpi_driver_data(device);
struct power_supply *old;
 
@@ -1212,13 +1213,23 @@ static int acpi_battery_add(struct acpi_device *device)
 
device_init_wakeup(>dev, 1);
 
-   return result;
+   result = acpi_dev_install_notify_handler(device,
+ACPI_ALL_NOTIFY,
+acpi_battery_notify);
+   if (result)
+   goto fail_pm;
+
+   return 0;
 
+fail_pm:
+   device_init_wakeup(>dev, 0);
+   unregister_pm_notifier(>pm_nb);
 fail:
sysfs_remove_battery(battery);
mutex_destroy(>lock);
mutex_destroy(>sysfs_lock);
kfree(battery);
+
return result;
 }
 
@@ -1228,10 +1239,17 @@ static void acpi_battery_remove(struct acpi_device 
*device)
 
if (!device || !acpi_driver_data(device))
return;
-   device_init_wakeup(>dev, 0);
+
battery = acpi_driver_data(device);
+
+   acpi_dev_remove_notify_handler(device,
+  ACPI_ALL_NOTIFY,
+  acpi_battery_notify);
+
+   device_init_wakeup(>dev, 0);
unregister_pm_notifier(>pm_nb);
sysfs_remove_battery(battery);
+
mutex_destroy(>lock);
mutex_destroy(>sysfs_lock);
kfree(battery);
@@ -1264,11 +1282,9 @@ static struct acpi_driver acpi_battery_driver = {
.name = "battery",
.class = ACPI_BATTERY_CLASS,
.ids = battery_device_ids,
-   .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
.ops = {
.add = acpi_battery_add,
.remove = acpi_battery_remove,
-   .notify = acpi_battery_notify,
},
.drv.pm = _battery_pm,
 };
-- 
2.41.0




[PATCH v7 4/9] acpi/video: Move handler installing logic to driver

2023-07-03 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of .remove()
callback. Change arguments passed to the notify function to match with
what's required by acpi_dev_install_notify_handler(). Remove .notify
callback initialization in acpi_driver.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/acpi_video.c | 22 +++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
index 62f4364e4460..168bb43e0c65 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video.c
@@ -77,7 +77,7 @@ static DEFINE_MUTEX(video_list_lock);
 static LIST_HEAD(video_bus_head);
 static int acpi_video_bus_add(struct acpi_device *device);
 static void acpi_video_bus_remove(struct acpi_device *device);
-static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
+static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data);
 
 /*
  * Indices in the _BCL method response: the first two items are special,
@@ -104,7 +104,6 @@ static struct acpi_driver acpi_video_bus = {
.ops = {
.add = acpi_video_bus_add,
.remove = acpi_video_bus_remove,
-   .notify = acpi_video_bus_notify,
},
 };
 
@@ -1527,8 +1526,9 @@ static int acpi_video_bus_stop_devices(struct 
acpi_video_bus *video)
  acpi_osi_is_win8() ? 0 : 1);
 }
 
-static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
+static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
 {
+   struct acpi_device *device = data;
struct acpi_video_bus *video = acpi_driver_data(device);
struct input_dev *input;
int keycode = 0;
@@ -2053,8 +2053,20 @@ static int acpi_video_bus_add(struct acpi_device *device)
 
acpi_video_bus_add_notify_handler(video);
 
+   error = acpi_dev_install_notify_handler(device,
+   ACPI_DEVICE_NOTIFY,
+   acpi_video_bus_notify);
+   if (error)
+   goto err_remove;
+
return 0;
 
+err_remove:
+   mutex_lock(_list_lock);
+   list_del(>entry);
+   mutex_unlock(_list_lock);
+   acpi_video_bus_remove_notify_handler(video);
+   acpi_video_bus_unregister_backlight(video);
 err_put_video:
acpi_video_bus_put_devices(video);
kfree(video->attached_array);
@@ -2075,6 +2087,10 @@ static void acpi_video_bus_remove(struct acpi_device 
*device)
 
video = acpi_driver_data(device);
 
+   acpi_dev_remove_notify_handler(device,
+  ACPI_DEVICE_NOTIFY,
+  acpi_video_bus_notify);
+
mutex_lock(_list_lock);
list_del(>entry);
mutex_unlock(_list_lock);
-- 
2.41.0




[PATCH v7 3/9] acpi/ac: Move handler installing logic to driver

2023-07-03 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of .remove()
callback. Change arguments passed to the notify function to match with
what's required by acpi_dev_install_notify_handler(). Remove .notify
callback initialization in acpi_driver.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/ac.c | 29 +
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 1ace70b831cd..f6feff1f3118 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -34,7 +34,7 @@ MODULE_LICENSE("GPL");
 
 static int acpi_ac_add(struct acpi_device *device);
 static void acpi_ac_remove(struct acpi_device *device);
-static void acpi_ac_notify(struct acpi_device *device, u32 event);
+static void acpi_ac_notify(acpi_handle handle, u32 event, void *data);
 
 static const struct acpi_device_id ac_device_ids[] = {
{"ACPI0003", 0},
@@ -54,11 +54,9 @@ static struct acpi_driver acpi_ac_driver = {
.name = "ac",
.class = ACPI_AC_CLASS,
.ids = ac_device_ids,
-   .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
.ops = {
.add = acpi_ac_add,
.remove = acpi_ac_remove,
-   .notify = acpi_ac_notify,
},
.drv.pm = _ac_pm,
 };
@@ -128,8 +126,9 @@ static enum power_supply_property ac_props[] = {
 };
 
 /* Driver Model */
-static void acpi_ac_notify(struct acpi_device *device, u32 event)
+static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
 {
+   struct acpi_device *device = data;
struct acpi_ac *ac = acpi_driver_data(device);
 
if (!ac)
@@ -235,7 +234,7 @@ static int acpi_ac_add(struct acpi_device *device)
 
result = acpi_ac_get_state(ac);
if (result)
-   goto end;
+   goto err_release_ac;
 
psy_cfg.drv_data = ac;
 
@@ -248,7 +247,7 @@ static int acpi_ac_add(struct acpi_device *device)
>charger_desc, _cfg);
if (IS_ERR(ac->charger)) {
result = PTR_ERR(ac->charger);
-   goto end;
+   goto err_release_ac;
}
 
pr_info("%s [%s] (%s)\n", acpi_device_name(device),
@@ -256,9 +255,20 @@ static int acpi_ac_add(struct acpi_device *device)
 
ac->battery_nb.notifier_call = acpi_ac_battery_notify;
register_acpi_notifier(>battery_nb);
-end:
+
+   result = acpi_dev_install_notify_handler(device,
+ACPI_ALL_NOTIFY,
+acpi_ac_notify);
if (result)
-   kfree(ac);
+   goto err_unregister;
+
+   return 0;
+
+err_unregister:
+   power_supply_unregister(ac->charger);
+   unregister_acpi_notifier(>battery_nb);
+err_release_ac:
+   kfree(ac);
 
return result;
 }
@@ -297,6 +307,9 @@ static void acpi_ac_remove(struct acpi_device *device)
 
ac = acpi_driver_data(device);
 
+   acpi_dev_remove_notify_handler(device,
+  ACPI_ALL_NOTIFY,
+  acpi_ac_notify);
power_supply_unregister(ac->charger);
unregister_acpi_notifier(>battery_nb);
 
-- 
2.41.0




[PATCH v7 1/9] acpi/bus: Introduce wrappers for ACPICA event handler install/remove

2023-07-03 Thread Michal Wilczynski
Introduce new acpi_dev_install_notify_handler() and
acpi_dev_remove_notify_handler(). Those functions are replacing old
installers, and after all drivers switch to the new model, old installers
will be removed.

Make acpi_dev_install_notify_handler() and acpi_dev_remove_notify_handler()
non-static, and export symbols. This will allow the drivers to call them
directly, instead of relying on .notify callback.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/bus.c  | 26 ++
 include/acpi/acpi_bus.h |  6 ++
 2 files changed, 32 insertions(+)

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 20cdfb37da79..2d6f1f45d44e 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -554,6 +554,32 @@ static void acpi_device_remove_notify_handler(struct 
acpi_device *device,
acpi_os_wait_events_complete();
 }
 
+int acpi_dev_install_notify_handler(struct acpi_device *adev,
+   u32 handler_type,
+   acpi_notify_handler handler)
+{
+   acpi_status status;
+
+   status = acpi_install_notify_handler(adev->handle,
+handler_type,
+handler,
+adev);
+   if (ACPI_FAILURE(status))
+   return -ENODEV;
+
+   return 0;
+}
+EXPORT_SYMBOL(acpi_dev_install_notify_handler);
+
+void acpi_dev_remove_notify_handler(struct acpi_device *adev,
+   u32 handler_type,
+   acpi_notify_handler handler)
+{
+   acpi_remove_notify_handler(adev->handle, handler_type, handler);
+   acpi_os_wait_events_complete();
+}
+EXPORT_SYMBOL(acpi_dev_remove_notify_handler);
+
 /* Handle events targeting \_SB device (at present only graceful shutdown) */
 
 #define ACPI_SB_NOTIFY_SHUTDOWN_REQUEST 0x81
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index c941d99162c0..23fbe4a16972 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -515,6 +515,12 @@ void acpi_bus_private_data_handler(acpi_handle, void *);
 int acpi_bus_get_private_data(acpi_handle, void **);
 int acpi_bus_attach_private_data(acpi_handle, void *);
 void acpi_bus_detach_private_data(acpi_handle);
+int acpi_dev_install_notify_handler(struct acpi_device *adev,
+   u32 handler_type,
+   acpi_notify_handler handler);
+void acpi_dev_remove_notify_handler(struct acpi_device *adev,
+   u32 handler_type,
+   acpi_notify_handler handler);
 extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32);
 extern int register_acpi_notifier(struct notifier_block *);
 extern int unregister_acpi_notifier(struct notifier_block *);
-- 
2.41.0




[PATCH v7 2/9] acpi/bus: Set driver_data to NULL every time .add() fails

2023-07-03 Thread Michal Wilczynski
Most drivers set driver_data during .add() callback, but usually
they don't set it back to NULL in case of a failure. Set driver_data to
NULL in acpi_device_probe() to avoid code duplication.

Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/bus.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 2d6f1f45d44e..c087fd6e8398 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1014,8 +1014,10 @@ static int acpi_device_probe(struct device *dev)
return -ENOSYS;
 
ret = acpi_drv->ops.add(acpi_dev);
-   if (ret)
+   if (ret) {
+   acpi_dev->driver_data = NULL;
return ret;
+   }
 
pr_debug("Driver [%s] successfully bound to device [%s]\n",
 acpi_drv->name, acpi_dev->pnp.bus_id);
-- 
2.41.0




[PATCH v7 0/9] Remove .notify callback in acpi_device_ops

2023-07-03 Thread Michal Wilczynski
*** IMPORTANT ***
This is part 1 - only drivers in acpi directory to ease up review
process. Rest of the drivers will be handled in separate patchsets.

Currently drivers support ACPI event handlers by defining .notify
callback in acpi_device_ops. This solution is suboptimal as event
handler installer installs intermediary function acpi_notify_device as a
handler in every driver. Also this approach requires extra variable
'flags' for specifying event types that the driver want to subscribe to.
Additionally this is a pre-work required to align acpi_driver with
platform_driver and eventually replace acpi_driver with platform_driver.

Remove .notify callback from the acpi_device_ops. Replace it with each
driver installing and removing it's event handlers.

This is part 1 - only drivers in acpi directory to ease up review
process.

v7:
 - fix warning by declaring acpi_nfit_remove_notify_handler() as static

v6:
 - fixed unnecessary RCT in all drivers, as it's not a purpose of
   this patch series
 - changed error label names to simplify them
 - dropped commit that remove a comma
 - squashed commit moving code for nfit
 - improved nfit driver to use devm instead of .remove()
 - re-based as Rafael changes [1] are merged already

v5:
 - rebased on top of Rafael changes [1], they're not merged yet
 - fixed rollback in multiple drivers so they don't leak resources on
   failure
 - made this part 1, meaning only drivers in acpi directory, rest of
   the drivers will be handled in separate patchsets to ease up review

v4:
 - added one commit for previously missed driver sony-laptop,
   refactored return statements, added NULL check for event installer
v3:
 - lkp still reported some failures for eeepc, fujitsu and
   toshiba_bluetooth, fix those
v2:
 - fix compilation errors for drivers

[1]: https://lore.kernel.org/linux-acpi/1847933.atdPhlSkOF@kreacher/

Michal Wilczynski (9):
  acpi/bus: Introduce wrappers for ACPICA event handler install/remove
  acpi/bus: Set driver_data to NULL every time .add() fails
  acpi/ac: Move handler installing logic to driver
  acpi/video: Move handler installing logic to driver
  acpi/battery: Move handler installing logic to driver
  acpi/hed: Move handler installing logic to driver
  acpi/nfit: Move handler installing logic to driver
  acpi/nfit: Remove unnecessary .remove callback
  acpi/thermal: Move handler installing logic to driver

 drivers/acpi/ac.c | 29 ++---
 drivers/acpi/acpi_video.c | 22 ---
 drivers/acpi/battery.c| 26 +-
 drivers/acpi/bus.c| 30 +-
 drivers/acpi/hed.c| 17 ---
 drivers/acpi/nfit/core.c  | 45 +++
 drivers/acpi/thermal.c| 25 +-
 include/acpi/acpi_bus.h   |  6 ++
 8 files changed, 161 insertions(+), 39 deletions(-)

-- 
2.41.0




[PATCH v6 9/9] acpi/thermal: Move handler installing logic to driver

2023-06-30 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of .remove()
callback. Change arguments passed to the notify function to match with
what's required by acpi_dev_install_notify_handler(). Remove .notify
callback initialization in acpi_driver.

While at it, fix whitespaces in .remove() callback.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/thermal.c | 25 -
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index f9f6ebb08fdb..97858ad59d68 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -825,8 +825,9 @@ static void acpi_queue_thermal_check(struct acpi_thermal 
*tz)
queue_work(acpi_thermal_pm_queue, >thermal_check_work);
 }
 
-static void acpi_thermal_notify(struct acpi_device *device, u32 event)
+static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
 {
+   struct acpi_device *device = data;
struct acpi_thermal *tz = acpi_driver_data(device);
 
if (!tz)
@@ -997,11 +998,21 @@ static int acpi_thermal_add(struct acpi_device *device)
 
pr_info("%s [%s] (%ld C)\n", acpi_device_name(device),
acpi_device_bid(device), 
deci_kelvin_to_celsius(tz->temperature));
-   goto end;
 
+   result = acpi_dev_install_notify_handler(device,
+ACPI_DEVICE_NOTIFY,
+acpi_thermal_notify);
+   if (result)
+   goto flush_wq;
+
+   return 0;
+
+flush_wq:
+   flush_workqueue(acpi_thermal_pm_queue);
+   acpi_thermal_unregister_thermal_zone(tz);
 free_memory:
kfree(tz);
-end:
+
return result;
 }
 
@@ -1012,10 +1023,15 @@ static void acpi_thermal_remove(struct acpi_device 
*device)
if (!device || !acpi_driver_data(device))
return;
 
-   flush_workqueue(acpi_thermal_pm_queue);
tz = acpi_driver_data(device);
 
+   acpi_dev_remove_notify_handler(device,
+  ACPI_DEVICE_NOTIFY,
+  acpi_thermal_notify);
+
+   flush_workqueue(acpi_thermal_pm_queue);
acpi_thermal_unregister_thermal_zone(tz);
+
kfree(tz);
 }
 
@@ -1078,7 +1094,6 @@ static struct acpi_driver acpi_thermal_driver = {
.ops = {
.add = acpi_thermal_add,
.remove = acpi_thermal_remove,
-   .notify = acpi_thermal_notify,
},
.drv.pm = _thermal_pm,
 };
-- 
2.41.0




[PATCH v6 8/9] acpi/nfit: Remove unnecessary .remove callback

2023-06-30 Thread Michal Wilczynski
Nfit driver doesn't use .remove() callback and provide an empty function
as it's .remove() callback. Remove empty acpi_nfit_remove() and
initialization of callback.

Suggested-by: Dan Williams 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/nfit/core.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index ee2365a80aa1..daaea23cacfd 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -3402,11 +3402,6 @@ static int acpi_nfit_add(struct acpi_device *adev)
adev);
 }
 
-static void acpi_nfit_remove(struct acpi_device *adev)
-{
-   /* see acpi_nfit_unregister */
-}
-
 static void acpi_nfit_update_notify(struct device *dev, acpi_handle handle)
 {
struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(dev);
@@ -3488,7 +3483,6 @@ static struct acpi_driver acpi_nfit_driver = {
.ids = acpi_nfit_ids,
.ops = {
.add = acpi_nfit_add,
-   .remove = acpi_nfit_remove,
},
 };
 
-- 
2.41.0




[PATCH v6 7/9] acpi/nfit: Move handler installing logic to driver

2023-06-30 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of
acpi_nfit_shutdown(). Change arguments passed to the notify function to
match with what's required by acpi_dev_install_notify_handler(). Remove
.notify callback initialization in acpi_driver.

Introduce a new devm action acpi_nfit_remove_notify_handler.

Move acpi_nfit_notify() upwards in the file, so it can be used inside
acpi_nfit_add() and acpi_nfit_remove_notify_handler().

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/nfit/core.c | 41 +++-
 1 file changed, 32 insertions(+), 9 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 07204d482968..ee2365a80aa1 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -3282,6 +3282,24 @@ static void acpi_nfit_put_table(void *table)
acpi_put_table(table);
 }
 
+static void acpi_nfit_notify(acpi_handle handle, u32 event, void *data)
+{
+   struct acpi_device *adev = data;
+
+   device_lock(>dev);
+   __acpi_nfit_notify(>dev, handle, event);
+   device_unlock(>dev);
+}
+
+void acpi_nfit_remove_notify_handler(void *data)
+{
+   struct acpi_device *adev = data;
+
+   acpi_dev_remove_notify_handler(adev,
+  ACPI_DEVICE_NOTIFY,
+  acpi_nfit_notify);
+}
+
 void acpi_nfit_shutdown(void *data)
 {
struct acpi_nfit_desc *acpi_desc = data;
@@ -3368,7 +3386,20 @@ static int acpi_nfit_add(struct acpi_device *adev)
 
if (rc)
return rc;
-   return devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc);
+
+   rc = devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc);
+   if (rc)
+   return rc;
+
+   rc = acpi_dev_install_notify_handler(adev,
+ACPI_DEVICE_NOTIFY,
+acpi_nfit_notify);
+   if (rc)
+   return rc;
+
+   return devm_add_action_or_reset(dev,
+   acpi_nfit_remove_notify_handler,
+   adev);
 }
 
 static void acpi_nfit_remove(struct acpi_device *adev)
@@ -3446,13 +3477,6 @@ void __acpi_nfit_notify(struct device *dev, acpi_handle 
handle, u32 event)
 }
 EXPORT_SYMBOL_GPL(__acpi_nfit_notify);
 
-static void acpi_nfit_notify(struct acpi_device *adev, u32 event)
-{
-   device_lock(>dev);
-   __acpi_nfit_notify(>dev, adev->handle, event);
-   device_unlock(>dev);
-}
-
 static const struct acpi_device_id acpi_nfit_ids[] = {
{ "ACPI0012", 0 },
{ "", 0 },
@@ -3465,7 +3489,6 @@ static struct acpi_driver acpi_nfit_driver = {
.ops = {
.add = acpi_nfit_add,
.remove = acpi_nfit_remove,
-   .notify = acpi_nfit_notify,
},
 };
 
-- 
2.41.0




[PATCH v6 6/9] acpi/hed: Move handler installing logic to driver

2023-06-30 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of .remove()
callback. Change arguments passed to the notify function to match with
what's required by acpi_dev_install_notify_handler(). Remove .notify
callback initialization in acpi_driver.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/hed.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c
index 78d44e3fe129..8f54560c6d1c 100644
--- a/drivers/acpi/hed.c
+++ b/drivers/acpi/hed.c
@@ -42,22 +42,34 @@ EXPORT_SYMBOL_GPL(unregister_acpi_hed_notifier);
  * it is used by HEST Generic Hardware Error Source with notify type
  * SCI.
  */
-static void acpi_hed_notify(struct acpi_device *device, u32 event)
+static void acpi_hed_notify(acpi_handle handle, u32 event, void *data)
 {
blocking_notifier_call_chain(_hed_notify_list, 0, NULL);
 }
 
 static int acpi_hed_add(struct acpi_device *device)
 {
+   int err;
+
/* Only one hardware error device */
if (hed_handle)
return -EINVAL;
hed_handle = device->handle;
-   return 0;
+
+   err = acpi_dev_install_notify_handler(device,
+ ACPI_DEVICE_NOTIFY,
+ acpi_hed_notify);
+   if (err)
+   hed_handle = NULL;
+
+   return err;
 }
 
 static void acpi_hed_remove(struct acpi_device *device)
 {
+   acpi_dev_remove_notify_handler(device,
+  ACPI_DEVICE_NOTIFY,
+  acpi_hed_notify);
hed_handle = NULL;
 }
 
@@ -68,7 +80,6 @@ static struct acpi_driver acpi_hed_driver = {
.ops = {
.add = acpi_hed_add,
.remove = acpi_hed_remove,
-   .notify = acpi_hed_notify,
},
 };
 module_acpi_driver(acpi_hed_driver);
-- 
2.41.0




[PATCH v6 5/9] acpi/battery: Move handler installing logic to driver

2023-06-30 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of .remove()
callback. Change arguments passed to the notify function to match with
what's required by acpi_dev_install_notify_handler(). Remove .notify
callback initialization in acpi_driver.

While at it, fix lack of whitespaces in .remove() callback.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/battery.c | 26 +-
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 9c67ed02d797..4c634a4c32dd 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -1034,8 +1034,9 @@ static void acpi_battery_refresh(struct acpi_battery 
*battery)
 }
 
 /* Driver Interface */
-static void acpi_battery_notify(struct acpi_device *device, u32 event)
+static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
 {
+   struct acpi_device *device = data;
struct acpi_battery *battery = acpi_driver_data(device);
struct power_supply *old;
 
@@ -1212,13 +1213,23 @@ static int acpi_battery_add(struct acpi_device *device)
 
device_init_wakeup(>dev, 1);
 
-   return result;
+   result = acpi_dev_install_notify_handler(device,
+ACPI_ALL_NOTIFY,
+acpi_battery_notify);
+   if (result)
+   goto fail_pm;
+
+   return 0;
 
+fail_pm:
+   device_init_wakeup(>dev, 0);
+   unregister_pm_notifier(>pm_nb);
 fail:
sysfs_remove_battery(battery);
mutex_destroy(>lock);
mutex_destroy(>sysfs_lock);
kfree(battery);
+
return result;
 }
 
@@ -1228,10 +1239,17 @@ static void acpi_battery_remove(struct acpi_device 
*device)
 
if (!device || !acpi_driver_data(device))
return;
-   device_init_wakeup(>dev, 0);
+
battery = acpi_driver_data(device);
+
+   acpi_dev_remove_notify_handler(device,
+  ACPI_ALL_NOTIFY,
+  acpi_battery_notify);
+
+   device_init_wakeup(>dev, 0);
unregister_pm_notifier(>pm_nb);
sysfs_remove_battery(battery);
+
mutex_destroy(>lock);
mutex_destroy(>sysfs_lock);
kfree(battery);
@@ -1264,11 +1282,9 @@ static struct acpi_driver acpi_battery_driver = {
.name = "battery",
.class = ACPI_BATTERY_CLASS,
.ids = battery_device_ids,
-   .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
.ops = {
.add = acpi_battery_add,
.remove = acpi_battery_remove,
-   .notify = acpi_battery_notify,
},
.drv.pm = _battery_pm,
 };
-- 
2.41.0




[PATCH v6 4/9] acpi/video: Move handler installing logic to driver

2023-06-30 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of .remove()
callback. Change arguments passed to the notify function to match with
what's required by acpi_dev_install_notify_handler(). Remove .notify
callback initialization in acpi_driver.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/acpi_video.c | 22 +++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
index 62f4364e4460..168bb43e0c65 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video.c
@@ -77,7 +77,7 @@ static DEFINE_MUTEX(video_list_lock);
 static LIST_HEAD(video_bus_head);
 static int acpi_video_bus_add(struct acpi_device *device);
 static void acpi_video_bus_remove(struct acpi_device *device);
-static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
+static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data);
 
 /*
  * Indices in the _BCL method response: the first two items are special,
@@ -104,7 +104,6 @@ static struct acpi_driver acpi_video_bus = {
.ops = {
.add = acpi_video_bus_add,
.remove = acpi_video_bus_remove,
-   .notify = acpi_video_bus_notify,
},
 };
 
@@ -1527,8 +1526,9 @@ static int acpi_video_bus_stop_devices(struct 
acpi_video_bus *video)
  acpi_osi_is_win8() ? 0 : 1);
 }
 
-static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
+static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
 {
+   struct acpi_device *device = data;
struct acpi_video_bus *video = acpi_driver_data(device);
struct input_dev *input;
int keycode = 0;
@@ -2053,8 +2053,20 @@ static int acpi_video_bus_add(struct acpi_device *device)
 
acpi_video_bus_add_notify_handler(video);
 
+   error = acpi_dev_install_notify_handler(device,
+   ACPI_DEVICE_NOTIFY,
+   acpi_video_bus_notify);
+   if (error)
+   goto err_remove;
+
return 0;
 
+err_remove:
+   mutex_lock(_list_lock);
+   list_del(>entry);
+   mutex_unlock(_list_lock);
+   acpi_video_bus_remove_notify_handler(video);
+   acpi_video_bus_unregister_backlight(video);
 err_put_video:
acpi_video_bus_put_devices(video);
kfree(video->attached_array);
@@ -2075,6 +2087,10 @@ static void acpi_video_bus_remove(struct acpi_device 
*device)
 
video = acpi_driver_data(device);
 
+   acpi_dev_remove_notify_handler(device,
+  ACPI_DEVICE_NOTIFY,
+  acpi_video_bus_notify);
+
mutex_lock(_list_lock);
list_del(>entry);
mutex_unlock(_list_lock);
-- 
2.41.0




[PATCH v6 3/9] acpi/ac: Move handler installing logic to driver

2023-06-30 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of .remove()
callback. Change arguments passed to the notify function to match with
what's required by acpi_dev_install_notify_handler(). Remove .notify
callback initialization in acpi_driver.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/ac.c | 29 +
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 1ace70b831cd..f6feff1f3118 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -34,7 +34,7 @@ MODULE_LICENSE("GPL");
 
 static int acpi_ac_add(struct acpi_device *device);
 static void acpi_ac_remove(struct acpi_device *device);
-static void acpi_ac_notify(struct acpi_device *device, u32 event);
+static void acpi_ac_notify(acpi_handle handle, u32 event, void *data);
 
 static const struct acpi_device_id ac_device_ids[] = {
{"ACPI0003", 0},
@@ -54,11 +54,9 @@ static struct acpi_driver acpi_ac_driver = {
.name = "ac",
.class = ACPI_AC_CLASS,
.ids = ac_device_ids,
-   .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
.ops = {
.add = acpi_ac_add,
.remove = acpi_ac_remove,
-   .notify = acpi_ac_notify,
},
.drv.pm = _ac_pm,
 };
@@ -128,8 +126,9 @@ static enum power_supply_property ac_props[] = {
 };
 
 /* Driver Model */
-static void acpi_ac_notify(struct acpi_device *device, u32 event)
+static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
 {
+   struct acpi_device *device = data;
struct acpi_ac *ac = acpi_driver_data(device);
 
if (!ac)
@@ -235,7 +234,7 @@ static int acpi_ac_add(struct acpi_device *device)
 
result = acpi_ac_get_state(ac);
if (result)
-   goto end;
+   goto err_release_ac;
 
psy_cfg.drv_data = ac;
 
@@ -248,7 +247,7 @@ static int acpi_ac_add(struct acpi_device *device)
>charger_desc, _cfg);
if (IS_ERR(ac->charger)) {
result = PTR_ERR(ac->charger);
-   goto end;
+   goto err_release_ac;
}
 
pr_info("%s [%s] (%s)\n", acpi_device_name(device),
@@ -256,9 +255,20 @@ static int acpi_ac_add(struct acpi_device *device)
 
ac->battery_nb.notifier_call = acpi_ac_battery_notify;
register_acpi_notifier(>battery_nb);
-end:
+
+   result = acpi_dev_install_notify_handler(device,
+ACPI_ALL_NOTIFY,
+acpi_ac_notify);
if (result)
-   kfree(ac);
+   goto err_unregister;
+
+   return 0;
+
+err_unregister:
+   power_supply_unregister(ac->charger);
+   unregister_acpi_notifier(>battery_nb);
+err_release_ac:
+   kfree(ac);
 
return result;
 }
@@ -297,6 +307,9 @@ static void acpi_ac_remove(struct acpi_device *device)
 
ac = acpi_driver_data(device);
 
+   acpi_dev_remove_notify_handler(device,
+  ACPI_ALL_NOTIFY,
+  acpi_ac_notify);
power_supply_unregister(ac->charger);
unregister_acpi_notifier(>battery_nb);
 
-- 
2.41.0




[PATCH v6 2/9] acpi/bus: Set driver_data to NULL every time .add() fails

2023-06-30 Thread Michal Wilczynski
Most drivers set driver_data during .add() callback, but usually
they don't set it back to NULL in case of a failure. Set driver_data to
NULL in acpi_device_probe() to avoid code duplication.

Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/bus.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 2d6f1f45d44e..c087fd6e8398 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1014,8 +1014,10 @@ static int acpi_device_probe(struct device *dev)
return -ENOSYS;
 
ret = acpi_drv->ops.add(acpi_dev);
-   if (ret)
+   if (ret) {
+   acpi_dev->driver_data = NULL;
return ret;
+   }
 
pr_debug("Driver [%s] successfully bound to device [%s]\n",
 acpi_drv->name, acpi_dev->pnp.bus_id);
-- 
2.41.0




[PATCH v6 1/9] acpi/bus: Introduce wrappers for ACPICA event handler install/remove

2023-06-30 Thread Michal Wilczynski
Introduce new acpi_dev_install_notify_handler() and
acpi_dev_remove_notify_handler(). Those functions are replacing old
installers, and after all drivers switch to the new model, old installers
will be removed.

Make acpi_dev_install_notify_handler() and acpi_dev_remove_notify_handler()
non-static, and export symbols. This will allow the drivers to call them
directly, instead of relying on .notify callback.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/bus.c  | 26 ++
 include/acpi/acpi_bus.h |  6 ++
 2 files changed, 32 insertions(+)

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 20cdfb37da79..2d6f1f45d44e 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -554,6 +554,32 @@ static void acpi_device_remove_notify_handler(struct 
acpi_device *device,
acpi_os_wait_events_complete();
 }
 
+int acpi_dev_install_notify_handler(struct acpi_device *adev,
+   u32 handler_type,
+   acpi_notify_handler handler)
+{
+   acpi_status status;
+
+   status = acpi_install_notify_handler(adev->handle,
+handler_type,
+handler,
+adev);
+   if (ACPI_FAILURE(status))
+   return -ENODEV;
+
+   return 0;
+}
+EXPORT_SYMBOL(acpi_dev_install_notify_handler);
+
+void acpi_dev_remove_notify_handler(struct acpi_device *adev,
+   u32 handler_type,
+   acpi_notify_handler handler)
+{
+   acpi_remove_notify_handler(adev->handle, handler_type, handler);
+   acpi_os_wait_events_complete();
+}
+EXPORT_SYMBOL(acpi_dev_remove_notify_handler);
+
 /* Handle events targeting \_SB device (at present only graceful shutdown) */
 
 #define ACPI_SB_NOTIFY_SHUTDOWN_REQUEST 0x81
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index c941d99162c0..23fbe4a16972 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -515,6 +515,12 @@ void acpi_bus_private_data_handler(acpi_handle, void *);
 int acpi_bus_get_private_data(acpi_handle, void **);
 int acpi_bus_attach_private_data(acpi_handle, void *);
 void acpi_bus_detach_private_data(acpi_handle);
+int acpi_dev_install_notify_handler(struct acpi_device *adev,
+   u32 handler_type,
+   acpi_notify_handler handler);
+void acpi_dev_remove_notify_handler(struct acpi_device *adev,
+   u32 handler_type,
+   acpi_notify_handler handler);
 extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32);
 extern int register_acpi_notifier(struct notifier_block *);
 extern int unregister_acpi_notifier(struct notifier_block *);
-- 
2.41.0




[PATCH v6 0/9] Remove .notify callback in acpi_device_ops

2023-06-30 Thread Michal Wilczynski
*** IMPORTANT ***
This is part 1 - only drivers in acpi directory to ease up review
process. Rest of the drivers will be handled in separate patchsets.

Currently drivers support ACPI event handlers by defining .notify
callback in acpi_device_ops. This solution is suboptimal as event
handler installer installs intermediary function acpi_notify_device as a
handler in every driver. Also this approach requires extra variable
'flags' for specifying event types that the driver want to subscribe to.
Additionally this is a pre-work required to align acpi_driver with
platform_driver and eventually replace acpi_driver with platform_driver.

Remove .notify callback from the acpi_device_ops. Replace it with each
driver installing and removing it's event handlers.

This is part 1 - only drivers in acpi directory to ease up review
process.

v6:
 - fixed unnecessary RCT in all drivers, as it's not a purpose of
   this patch series
 - changed error label names to simplify them
 - dropped commit that remove a comma
 - squashed commit moving code for nfit
 - improved nfit driver to use devm instead of .remove()
 - re-based as Rafael changes [1] are merged already

v5:
 - rebased on top of Rafael changes [1], they're not merged yet
 - fixed rollback in multiple drivers so they don't leak resources on
   failure
 - made this part 1, meaning only drivers in acpi directory, rest of
   the drivers will be handled in separate patchsets to ease up review

v4:
 - added one commit for previously missed driver sony-laptop,
   refactored return statements, added NULL check for event installer
v3:
 - lkp still reported some failures for eeepc, fujitsu and
   toshiba_bluetooth, fix those
v2:
 - fix compilation errors for drivers

[1]: https://lore.kernel.org/linux-acpi/1847933.atdPhlSkOF@kreacher/

Michal Wilczynski (9):
  acpi/bus: Introduce wrappers for ACPICA event handler install/remove
  acpi/bus: Set driver_data to NULL every time .add() fails
  acpi/ac: Move handler installing logic to driver
  acpi/video: Move handler installing logic to driver
  acpi/battery: Move handler installing logic to driver
  acpi/hed: Move handler installing logic to driver
  acpi/nfit: Move handler installing logic to driver
  acpi/nfit: Remove unnecessary .remove callback
  acpi/thermal: Move handler installing logic to driver

 drivers/acpi/ac.c | 29 ++---
 drivers/acpi/acpi_video.c | 22 ---
 drivers/acpi/battery.c| 26 +-
 drivers/acpi/bus.c| 30 +-
 drivers/acpi/hed.c| 17 ---
 drivers/acpi/nfit/core.c  | 45 +++
 drivers/acpi/thermal.c| 25 +-
 include/acpi/acpi_bus.h   |  6 ++
 8 files changed, 161 insertions(+), 39 deletions(-)

-- 
2.41.0




[PATCH v5 10/10] acpi/thermal: Move handler installing logic to driver

2023-06-16 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of .remove()
callback. Change arguments passed to the notify function to match with
what's required by acpi_install_notify_handler(). Remove .notify
callback initialization in acpi_driver.

While at it, fix whitespaces in .remove() callback and move tz
assignment upwards.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/thermal.c | 28 ++--
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index f9f6ebb08fdb..84716e4b967c 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -825,9 +825,12 @@ static void acpi_queue_thermal_check(struct acpi_thermal 
*tz)
queue_work(acpi_thermal_pm_queue, >thermal_check_work);
 }
 
-static void acpi_thermal_notify(struct acpi_device *device, u32 event)
+static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
 {
-   struct acpi_thermal *tz = acpi_driver_data(device);
+   struct acpi_device *device = data;
+   struct acpi_thermal *tz;
+
+   tz = acpi_driver_data(device);
 
if (!tz)
return;
@@ -997,11 +1000,20 @@ static int acpi_thermal_add(struct acpi_device *device)
 
pr_info("%s [%s] (%ld C)\n", acpi_device_name(device),
acpi_device_bid(device), 
deci_kelvin_to_celsius(tz->temperature));
-   goto end;
 
+   result = acpi_dev_install_notify_handler(device,
+ACPI_DEVICE_NOTIFY,
+acpi_thermal_notify);
+   if (result)
+   goto flush_wq_and_unregister;
+
+   return 0;
+
+flush_wq_and_unregister:
+   flush_workqueue(acpi_thermal_pm_queue);
+   acpi_thermal_unregister_thermal_zone(tz);
 free_memory:
kfree(tz);
-end:
return result;
 }
 
@@ -1012,10 +1024,15 @@ static void acpi_thermal_remove(struct acpi_device 
*device)
if (!device || !acpi_driver_data(device))
return;
 
-   flush_workqueue(acpi_thermal_pm_queue);
tz = acpi_driver_data(device);
 
+   acpi_dev_remove_notify_handler(device,
+  ACPI_DEVICE_NOTIFY,
+  acpi_thermal_notify);
+
+   flush_workqueue(acpi_thermal_pm_queue);
acpi_thermal_unregister_thermal_zone(tz);
+
kfree(tz);
 }
 
@@ -1078,7 +1095,6 @@ static struct acpi_driver acpi_thermal_driver = {
.ops = {
.add = acpi_thermal_add,
.remove = acpi_thermal_remove,
-   .notify = acpi_thermal_notify,
},
.drv.pm = _thermal_pm,
 };
-- 
2.41.0




[PATCH v5 09/10] acpi/nfit: Move handler installing logic to driver

2023-06-16 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of .remove()
callback. Change arguments passed to the notify function to match with
what's required by acpi_install_notify_handler(). Remove .notify
callback initialization in acpi_driver.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/nfit/core.c | 24 ++--
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 95930e9d776c..a281bdfee8a0 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -3312,11 +3312,13 @@ void acpi_nfit_shutdown(void *data)
 }
 EXPORT_SYMBOL_GPL(acpi_nfit_shutdown);
 
-static void acpi_nfit_notify(struct acpi_device *adev, u32 event)
+static void acpi_nfit_notify(acpi_handle handle, u32 event, void *data)
 {
-   device_lock(>dev);
-   __acpi_nfit_notify(>dev, adev->handle, event);
-   device_unlock(>dev);
+   struct acpi_device *device = data;
+
+   device_lock(>dev);
+   __acpi_nfit_notify(>dev, handle, event);
+   device_unlock(>dev);
 }
 
 static int acpi_nfit_add(struct acpi_device *adev)
@@ -3375,12 +3377,23 @@ static int acpi_nfit_add(struct acpi_device *adev)
 
if (rc)
return rc;
-   return devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc);
+
+   rc = devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc);
+   if (rc)
+   return rc;
+
+   return acpi_dev_install_notify_handler(adev,
+  ACPI_DEVICE_NOTIFY,
+  acpi_nfit_notify);
 }
 
 static void acpi_nfit_remove(struct acpi_device *adev)
 {
/* see acpi_nfit_unregister */
+
+   acpi_dev_remove_notify_handler(adev,
+  ACPI_DEVICE_NOTIFY,
+  acpi_nfit_notify);
 }
 
 static void acpi_nfit_update_notify(struct device *dev, acpi_handle handle)
@@ -3465,7 +3478,6 @@ static struct acpi_driver acpi_nfit_driver = {
.ops = {
.add = acpi_nfit_add,
.remove = acpi_nfit_remove,
-   .notify = acpi_nfit_notify,
},
 };
 
-- 
2.41.0




[PATCH v5 08/10] acpi/nfit: Improve terminator line in acpi_nfit_ids

2023-06-16 Thread Michal Wilczynski
Currently terminator line contains redunant characters. Remove them and
also remove a comma at the end.

Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/nfit/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index aff79cbc2190..95930e9d776c 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -3455,7 +3455,7 @@ EXPORT_SYMBOL_GPL(__acpi_nfit_notify);
 
 static const struct acpi_device_id acpi_nfit_ids[] = {
{ "ACPI0012", 0 },
-   { "", 0 },
+   {}
 };
 MODULE_DEVICE_TABLE(acpi, acpi_nfit_ids);
 
-- 
2.41.0




[PATCH v5 07/10] acpi/nfit: Move acpi_nfit_notify() before acpi_nfit_add()

2023-06-16 Thread Michal Wilczynski
To use new style of installing event handlers acpi_nfit_notify() needs
to be known inside acpi_nfit_add(). Move acpi_nfit_notify() upwards in
the file, so it can be used inside acpi_nfit_add().

Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/nfit/core.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 07204d482968..aff79cbc2190 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -3312,6 +3312,13 @@ void acpi_nfit_shutdown(void *data)
 }
 EXPORT_SYMBOL_GPL(acpi_nfit_shutdown);
 
+static void acpi_nfit_notify(struct acpi_device *adev, u32 event)
+{
+   device_lock(>dev);
+   __acpi_nfit_notify(>dev, adev->handle, event);
+   device_unlock(>dev);
+}
+
 static int acpi_nfit_add(struct acpi_device *adev)
 {
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -3446,13 +3453,6 @@ void __acpi_nfit_notify(struct device *dev, acpi_handle 
handle, u32 event)
 }
 EXPORT_SYMBOL_GPL(__acpi_nfit_notify);
 
-static void acpi_nfit_notify(struct acpi_device *adev, u32 event)
-{
-   device_lock(>dev);
-   __acpi_nfit_notify(>dev, adev->handle, event);
-   device_unlock(>dev);
-}
-
 static const struct acpi_device_id acpi_nfit_ids[] = {
{ "ACPI0012", 0 },
{ "", 0 },
-- 
2.41.0




[PATCH v5 06/10] acpi/hed: Move handler installing logic to driver

2023-06-16 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of .remove()
callback. Change arguments passed to the notify function to match with
what's required by acpi_install_notify_handler(). Remove .notify
callback initialization in acpi_driver.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/hed.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c
index 78d44e3fe129..8f54560c6d1c 100644
--- a/drivers/acpi/hed.c
+++ b/drivers/acpi/hed.c
@@ -42,22 +42,34 @@ EXPORT_SYMBOL_GPL(unregister_acpi_hed_notifier);
  * it is used by HEST Generic Hardware Error Source with notify type
  * SCI.
  */
-static void acpi_hed_notify(struct acpi_device *device, u32 event)
+static void acpi_hed_notify(acpi_handle handle, u32 event, void *data)
 {
blocking_notifier_call_chain(_hed_notify_list, 0, NULL);
 }
 
 static int acpi_hed_add(struct acpi_device *device)
 {
+   int err;
+
/* Only one hardware error device */
if (hed_handle)
return -EINVAL;
hed_handle = device->handle;
-   return 0;
+
+   err = acpi_dev_install_notify_handler(device,
+ ACPI_DEVICE_NOTIFY,
+ acpi_hed_notify);
+   if (err)
+   hed_handle = NULL;
+
+   return err;
 }
 
 static void acpi_hed_remove(struct acpi_device *device)
 {
+   acpi_dev_remove_notify_handler(device,
+  ACPI_DEVICE_NOTIFY,
+  acpi_hed_notify);
hed_handle = NULL;
 }
 
@@ -68,7 +80,6 @@ static struct acpi_driver acpi_hed_driver = {
.ops = {
.add = acpi_hed_add,
.remove = acpi_hed_remove,
-   .notify = acpi_hed_notify,
},
 };
 module_acpi_driver(acpi_hed_driver);
-- 
2.41.0




[PATCH v5 05/10] acpi/battery: Move handler installing logic to driver

2023-06-16 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of .remove()
callback. Change arguments passed to the notify function to match with
what's required by acpi_install_notify_handler(). Remove .notify
callback initialization in acpi_driver.

While at it, fix lack of whitespaces in .remove() callback.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/battery.c | 30 --
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 9c67ed02d797..6337e7b1f6e1 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -1034,11 +1034,14 @@ static void acpi_battery_refresh(struct acpi_battery 
*battery)
 }
 
 /* Driver Interface */
-static void acpi_battery_notify(struct acpi_device *device, u32 event)
+static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
 {
-   struct acpi_battery *battery = acpi_driver_data(device);
+   struct acpi_device *device = data;
+   struct acpi_battery *battery;
struct power_supply *old;
 
+   battery = acpi_driver_data(device);
+
if (!battery)
return;
old = battery->bat;
@@ -1212,13 +1215,23 @@ static int acpi_battery_add(struct acpi_device *device)
 
device_init_wakeup(>dev, 1);
 
-   return result;
+   result = acpi_dev_install_notify_handler(device,
+ACPI_ALL_NOTIFY,
+acpi_battery_notify);
+   if (result)
+   goto fail_deinit_wakup_and_unregister;
+
+   return 0;
 
+fail_deinit_wakup_and_unregister:
+   device_init_wakeup(>dev, 0);
+   unregister_pm_notifier(>pm_nb);
 fail:
sysfs_remove_battery(battery);
mutex_destroy(>lock);
mutex_destroy(>sysfs_lock);
kfree(battery);
+
return result;
 }
 
@@ -1228,10 +1241,17 @@ static void acpi_battery_remove(struct acpi_device 
*device)
 
if (!device || !acpi_driver_data(device))
return;
-   device_init_wakeup(>dev, 0);
+
battery = acpi_driver_data(device);
+
+   acpi_dev_remove_notify_handler(device,
+  ACPI_ALL_NOTIFY,
+  acpi_battery_notify);
+
+   device_init_wakeup(>dev, 0);
unregister_pm_notifier(>pm_nb);
sysfs_remove_battery(battery);
+
mutex_destroy(>lock);
mutex_destroy(>sysfs_lock);
kfree(battery);
@@ -1264,11 +1284,9 @@ static struct acpi_driver acpi_battery_driver = {
.name = "battery",
.class = ACPI_BATTERY_CLASS,
.ids = battery_device_ids,
-   .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
.ops = {
.add = acpi_battery_add,
.remove = acpi_battery_remove,
-   .notify = acpi_battery_notify,
},
.drv.pm = _battery_pm,
 };
-- 
2.41.0




[PATCH v5 04/10] acpi/video: Move handler installing logic to driver

2023-06-16 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of .remove()
callback. Change arguments passed to the notify function to match with
what's required by acpi_install_notify_handler(). Remove .notify
callback initialization in acpi_driver.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/acpi_video.c | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
index 62f4364e4460..60b7013d0009 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video.c
@@ -77,7 +77,7 @@ static DEFINE_MUTEX(video_list_lock);
 static LIST_HEAD(video_bus_head);
 static int acpi_video_bus_add(struct acpi_device *device);
 static void acpi_video_bus_remove(struct acpi_device *device);
-static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
+static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data);
 
 /*
  * Indices in the _BCL method response: the first two items are special,
@@ -104,7 +104,6 @@ static struct acpi_driver acpi_video_bus = {
.ops = {
.add = acpi_video_bus_add,
.remove = acpi_video_bus_remove,
-   .notify = acpi_video_bus_notify,
},
 };
 
@@ -1527,12 +1526,15 @@ static int acpi_video_bus_stop_devices(struct 
acpi_video_bus *video)
  acpi_osi_is_win8() ? 0 : 1);
 }
 
-static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
+static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
 {
-   struct acpi_video_bus *video = acpi_driver_data(device);
+   struct acpi_device *device = data;
+   struct acpi_video_bus *video;
struct input_dev *input;
int keycode = 0;
 
+   video = acpi_driver_data(device);
+
if (!video || !video->input)
return;
 
@@ -2053,8 +2055,20 @@ static int acpi_video_bus_add(struct acpi_device *device)
 
acpi_video_bus_add_notify_handler(video);
 
+   error = acpi_dev_install_notify_handler(device,
+   ACPI_DEVICE_NOTIFY,
+   acpi_video_bus_notify);
+   if (error)
+   goto err_remove_and_unregister_video;
+
return 0;
 
+err_remove_and_unregister_video:
+   mutex_lock(_list_lock);
+   list_del(>entry);
+   mutex_unlock(_list_lock);
+   acpi_video_bus_remove_notify_handler(video);
+   acpi_video_bus_unregister_backlight(video);
 err_put_video:
acpi_video_bus_put_devices(video);
kfree(video->attached_array);
@@ -2075,6 +2089,10 @@ static void acpi_video_bus_remove(struct acpi_device 
*device)
 
video = acpi_driver_data(device);
 
+   acpi_dev_remove_notify_handler(device,
+  ACPI_DEVICE_NOTIFY,
+  acpi_video_bus_notify);
+
mutex_lock(_list_lock);
list_del(>entry);
mutex_unlock(_list_lock);
-- 
2.41.0




[PATCH v5 03/10] acpi/ac: Move handler installing logic to driver

2023-06-16 Thread Michal Wilczynski
Currently logic for installing notifications from ACPI devices is
implemented using notify callback in struct acpi_driver. Preparations
are being made to replace acpi_driver with more generic struct
platform_driver, which doesn't contain notify callback. Furthermore
as of now handlers are being called indirectly through
acpi_notify_device(), which decreases performance.

Call acpi_dev_install_notify_handler() at the end of .add() callback.
Call acpi_dev_remove_notify_handler() at the beginning of .remove()
callback. Change arguments passed to the notify function to match with
what's required by acpi_install_notify_handler(). Remove .notify
callback initialization in acpi_driver.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/ac.c | 33 -
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 1ace70b831cd..207ee3c85bad 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -34,7 +34,7 @@ MODULE_LICENSE("GPL");
 
 static int acpi_ac_add(struct acpi_device *device);
 static void acpi_ac_remove(struct acpi_device *device);
-static void acpi_ac_notify(struct acpi_device *device, u32 event);
+static void acpi_ac_notify(acpi_handle handle, u32 event, void *data);
 
 static const struct acpi_device_id ac_device_ids[] = {
{"ACPI0003", 0},
@@ -54,11 +54,9 @@ static struct acpi_driver acpi_ac_driver = {
.name = "ac",
.class = ACPI_AC_CLASS,
.ids = ac_device_ids,
-   .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
.ops = {
.add = acpi_ac_add,
.remove = acpi_ac_remove,
-   .notify = acpi_ac_notify,
},
.drv.pm = _ac_pm,
 };
@@ -128,9 +126,12 @@ static enum power_supply_property ac_props[] = {
 };
 
 /* Driver Model */
-static void acpi_ac_notify(struct acpi_device *device, u32 event)
+static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
 {
-   struct acpi_ac *ac = acpi_driver_data(device);
+   struct acpi_device *device = data;
+   struct acpi_ac *ac;
+
+   ac = acpi_driver_data(device);
 
if (!ac)
return;
@@ -235,7 +236,7 @@ static int acpi_ac_add(struct acpi_device *device)
 
result = acpi_ac_get_state(ac);
if (result)
-   goto end;
+   goto err_release_ac;
 
psy_cfg.drv_data = ac;
 
@@ -248,7 +249,7 @@ static int acpi_ac_add(struct acpi_device *device)
>charger_desc, _cfg);
if (IS_ERR(ac->charger)) {
result = PTR_ERR(ac->charger);
-   goto end;
+   goto err_release_ac;
}
 
pr_info("%s [%s] (%s)\n", acpi_device_name(device),
@@ -256,9 +257,20 @@ static int acpi_ac_add(struct acpi_device *device)
 
ac->battery_nb.notifier_call = acpi_ac_battery_notify;
register_acpi_notifier(>battery_nb);
-end:
+
+   result = acpi_dev_install_notify_handler(device,
+ACPI_ALL_NOTIFY,
+acpi_ac_notify);
if (result)
-   kfree(ac);
+   goto err_unregister;
+
+   return 0;
+
+err_unregister:
+   power_supply_unregister(ac->charger);
+   unregister_acpi_notifier(>battery_nb);
+err_release_ac:
+   kfree(ac);
 
return result;
 }
@@ -297,6 +309,9 @@ static void acpi_ac_remove(struct acpi_device *device)
 
ac = acpi_driver_data(device);
 
+   acpi_dev_remove_notify_handler(device,
+  ACPI_ALL_NOTIFY,
+  acpi_ac_notify);
power_supply_unregister(ac->charger);
unregister_acpi_notifier(>battery_nb);
 
-- 
2.41.0




[PATCH v5 02/10] acpi/bus: Set driver_data to NULL every time .add() fails

2023-06-16 Thread Michal Wilczynski
Most drivers set driver_data during .add() callback, but usually
they don't set it back to NULL in case of a failure. Set driver_data to
NULL in acpi_device_probe() to avoid code duplication.

Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/bus.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 22468589c551..c1cb570c8d8c 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1017,8 +1017,10 @@ static int acpi_device_probe(struct device *dev)
return -ENOSYS;
 
ret = acpi_drv->ops.add(acpi_dev);
-   if (ret)
+   if (ret) {
+   acpi_dev->driver_data = NULL;
return ret;
+   }
 
pr_debug("Driver [%s] successfully bound to device [%s]\n",
 acpi_drv->name, acpi_dev->pnp.bus_id);
-- 
2.41.0




[PATCH v5 01/10] acpi/bus: Introduce wrappers for ACPICA event handler install/remove

2023-06-16 Thread Michal Wilczynski
Introduce new acpi_dev_install_notify_handler() and
acpi_dev_remove_notify_handler(). Those functions are replacing old
installers, and after all drivers switch to the new model, old installers
will be removed.

Make acpi_dev_install_notify_handler() and acpi_dev_remove_notify_handler()
non-static, and export symbols. This will allow the drivers to call them
directly, instead of relying on .notify callback.

Suggested-by: Rafael J. Wysocki 
Signed-off-by: Michal Wilczynski 
---
 drivers/acpi/bus.c  | 26 ++
 include/acpi/acpi_bus.h |  6 ++
 2 files changed, 32 insertions(+)

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index b6ab3608d782..22468589c551 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -557,6 +557,32 @@ static void acpi_device_remove_notify_handler(struct 
acpi_device *device,
acpi_os_wait_events_complete();
 }
 
+int acpi_dev_install_notify_handler(struct acpi_device *adev,
+   u32 handler_type,
+   acpi_notify_handler handler)
+{
+   acpi_status status;
+
+   status = acpi_install_notify_handler(adev->handle,
+handler_type,
+handler,
+adev);
+   if (ACPI_FAILURE(status))
+   return -ENODEV;
+
+   return 0;
+}
+EXPORT_SYMBOL(acpi_dev_install_notify_handler);
+
+void acpi_dev_remove_notify_handler(struct acpi_device *adev,
+   u32 handler_type,
+   acpi_notify_handler handler)
+{
+   acpi_remove_notify_handler(adev->handle, handler_type, handler);
+   acpi_os_wait_events_complete();
+}
+EXPORT_SYMBOL(acpi_dev_remove_notify_handler);
+
 /* Handle events targeting \_SB device (at present only graceful shutdown) */
 
 #define ACPI_SB_NOTIFY_SHUTDOWN_REQUEST 0x81
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index c941d99162c0..23fbe4a16972 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -515,6 +515,12 @@ void acpi_bus_private_data_handler(acpi_handle, void *);
 int acpi_bus_get_private_data(acpi_handle, void **);
 int acpi_bus_attach_private_data(acpi_handle, void *);
 void acpi_bus_detach_private_data(acpi_handle);
+int acpi_dev_install_notify_handler(struct acpi_device *adev,
+   u32 handler_type,
+   acpi_notify_handler handler);
+void acpi_dev_remove_notify_handler(struct acpi_device *adev,
+   u32 handler_type,
+   acpi_notify_handler handler);
 extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32);
 extern int register_acpi_notifier(struct notifier_block *);
 extern int unregister_acpi_notifier(struct notifier_block *);
-- 
2.41.0




[PATCH v5 00/10] Remove .notify callback in acpi_device_ops

2023-06-16 Thread Michal Wilczynski
*** IMPORTANT ***
This is part 1 - only drivers in acpi directory to ease up review
process. Rest of the drivers will be handled in separate patchsets.

Currently drivers support ACPI event handlers by defining .notify
callback in acpi_device_ops. This solution is suboptimal as event
handler installer installs intermediary function acpi_notify_device as a
handler in every driver. Also this approach requires extra variable
'flags' for specifying event types that the driver want to subscribe to.
Additionally this is a pre-work required to align acpi_driver with
platform_driver and eventually replace acpi_driver with platform_driver.

Remove .notify callback from the acpi_device_ops. Replace it with each
driver installing and removing it's event handlers.

v5:
 - rebased on top of Rafael changes [1], they're not merged yet
 - fixed rollback in multiple drivers so they don't leak resources on
   failure
 - made this part 1, meaning only drivers in acpi directory, rest of
   the drivers will be handled in separate patchsets to ease up review

v4:
 - added one commit for previously missed driver sony-laptop,
   refactored return statements, added NULL check for event installer
v3:
 - lkp still reported some failures for eeepc, fujitsu and
   toshiba_bluetooth, fix those
v2:
 - fix compilation errors for drivers

[1]: https://lore.kernel.org/linux-acpi/1847933.atdPhlSkOF@kreacher/

Michal Wilczynski (10):
  acpi/bus: Introduce wrappers for ACPICA event handler install/remove
  acpi/bus: Set driver_data to NULL every time .add() fails
  acpi/ac: Move handler installing logic to driver
  acpi/video: Move handler installing logic to driver
  acpi/battery: Move handler installing logic to driver
  acpi/hed: Move handler installing logic to driver
  acpi/nfit: Move acpi_nfit_notify() before acpi_nfit_add()
  acpi/nfit: Improve terminator line in acpi_nfit_ids
  acpi/nfit: Move handler installing logic to driver
  acpi/thermal: Move handler installing logic to driver

 drivers/acpi/ac.c | 33 -
 drivers/acpi/acpi_video.c | 26 ++
 drivers/acpi/battery.c| 30 --
 drivers/acpi/bus.c| 30 +-
 drivers/acpi/hed.c| 17 ++---
 drivers/acpi/nfit/core.c  | 32 ++--
 drivers/acpi/thermal.c| 28 ++--
 include/acpi/acpi_bus.h   |  6 ++
 8 files changed, 163 insertions(+), 39 deletions(-)

-- 
2.41.0