2023-10-11 08:34:47

by Wilczynski, Michal

[permalink] [raw]
Subject: [PATCH v3 0/6] Replace acpi_driver with platform_driver

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/[email protected]/ [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


2023-10-11 08:34:50

by Wilczynski, Michal

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

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 <[email protected]>
Signed-off-by: Michal Wilczynski <[email protected]>
---
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

2023-10-11 08:35:13

by Wilczynski, Michal

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

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 <[email protected]>
---
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

2023-10-11 08:35:53

by Wilczynski, Michal

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

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 <[email protected]>
Signed-off-by: Michal Wilczynski <[email protected]>
---
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 <linux/sort.h>
#include <linux/io.h>
#include <linux/nd.h>
+#include <linux/platform_device.h>
#include <asm/cacheflush.h>
#include <acpi/nfit.h>
#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(&adev->dev);
- __acpi_nfit_notify(&adev->dev, handle, event);
- device_unlock(&adev->dev);
+ device_lock(dev);
+ __acpi_nfit_notify(dev, handle, event);
+ device_unlock(dev);
}

static void acpi_nfit_remove_notify_handler(void *data)
@@ -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 = &adev->dev;
+ struct device *dev = &pdev->dev;
+ struct acpi_device *adev = ACPI_COMPANION(dev);
struct acpi_table_header *tbl;
acpi_status status = AE_OK;
acpi_size sz;
@@ -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, &adev->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(&acpi_nfit_driver);
+ ret = platform_driver_register(&acpi_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(&acpi_nfit_driver);
+ platform_driver_unregister(&acpi_nfit_driver);
destroy_workqueue(nfit_wq);
WARN_ON(!list_empty(&acpi_descs));
}
--
2.41.0

2023-10-13 17:33:36

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH v3 1/6] ACPI: AC: Remove unnecessary checks

On Wed, Oct 11, 2023 at 10:34 AM Michal Wilczynski
<[email protected]> wrote:
>
> 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 <[email protected]>
> ---
> 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);
> --

Applied as 6.7 material with edits in the subject and changelog, thanks!