public inbox for chrome-platform@lists.linux.dev
 help / color / mirror / Atom feed
* [PATCH v2 0/6] platform/chrome: Bind drivers to platform devices instead of ACPI ones
@ 2026-03-05 19:34 Rafael J. Wysocki
  2026-03-05 19:37 ` [PATCH v2 1/6] platform/chrome: Convert ChromeOS privacy-screen driver to platform Rafael J. Wysocki
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Rafael J. Wysocki @ 2026-03-05 19:34 UTC (permalink / raw)
  To: Tzung-Bi Shih
  Cc: chrome-platform, LKML, Linux ACPI, Benson Leung,
	Enric Balletbo i Serra, Ravi Chandra Sadineni

Hi All,

This is a v2 of

https://lore.kernel.org/linux-acpi/2274474.Mh6RI2rZIc@rafael.j.wysocki/

addressing review comments on patches [2/6] and [4/6].

The series description below still applies.

This series is part of a larger effort to switch over all drivers using
the struct acpi_driver interface to the more common struct platform_driver
interface and eliminate the former.  The background is explained in
Documentation/driver-api/acpi/acpi-drivers.rst and in the changelog of
the patch that introduced the above document:

https://lore.kernel.org/all/2396510.ElGaqSPkdT@rafael.j.wysocki/

The bottom line is that the kernel would be better off without struct
acpi_driver and so it is better to get rid of it.

This series carries out driver conversions of Chrome platform drivers.

Patche [1/6] converts the ChromeOS privacy screen driver to using struct
platform_driver for device binding.

Patche [2/6] fixes a wakeup source object leak on remove in the
chromeos_tbmc driver.

Patch [3/6] updates the chromeos_tbmc driver to install an ACPI notify
handler by itself instead of using the .notify() callback from struct
acpi_driver, which is requisite for the driver conversion.

Patche [4/6] converts the chromeos_tbmc driver to using struct platform_driver
for device binding.

Patch [5/6] updates the wilco_ec-event driver to install an ACPI notify
handler by itself instead of using the .notify() callback from struct
acpi_driver, which is requisite for the driver conversion.

Patche [6/6] converts the wilco_ec-event driver to using struct platform_driver
for device binding.

Thanks!




^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/6] platform/chrome: Convert ChromeOS privacy-screen driver to platform
  2026-03-05 19:34 [PATCH v2 0/6] platform/chrome: Bind drivers to platform devices instead of ACPI ones Rafael J. Wysocki
@ 2026-03-05 19:37 ` Rafael J. Wysocki
  2026-03-05 19:39 ` [PATCH v2 3/6] platform/chrome: chromeos_tbmc: Register ACPI notify handler Rafael J. Wysocki
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Rafael J. Wysocki @ 2026-03-05 19:37 UTC (permalink / raw)
  To: Tzung-Bi Shih
  Cc: chrome-platform, LKML, Linux ACPI, Benson Leung,
	Enric Balletbo i Serra, Ravi Chandra Sadineni

From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>

In all cases in which a struct acpi_driver is used for binding a driver
to an ACPI device object, a corresponding platform device is created by
the ACPI core and that device is regarded as a proper representation of
underlying hardware.  Accordingly, a struct platform_driver should be
used by driver code to bind to that device.  There are multiple reasons
why drivers should not bind directly to ACPI device objects [1].

Overall, it is better to bind drivers to platform devices than to their
ACPI companions, so convert the ChromeOS privacy-screen ACPI driver
to a platform one.

While this is not expected to alter functionality, it changes sysfs
layout and so it will be visible to user space.

Link: https://lore.kernel.org/all/2396510.ElGaqSPkdT@rafael.j.wysocki/ [1]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---

v1 -> v2: No changes

---
 .../platform/chrome/chromeos_privacy_screen.c | 41 ++++++++-----------
 1 file changed, 18 insertions(+), 23 deletions(-)

diff --git a/drivers/platform/chrome/chromeos_privacy_screen.c b/drivers/platform/chrome/chromeos_privacy_screen.c
index bb74ddf9af4a..abc5d189a389 100644
--- a/drivers/platform/chrome/chromeos_privacy_screen.c
+++ b/drivers/platform/chrome/chromeos_privacy_screen.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/platform_device.h>
 #include <drm/drm_privacy_screen_driver.h>
 
 /*
@@ -32,11 +33,10 @@ chromeos_privacy_screen_get_hw_state(struct drm_privacy_screen
 				     *drm_privacy_screen)
 {
 	union acpi_object *obj;
-	acpi_handle handle;
 	struct device *privacy_screen =
 		drm_privacy_screen_get_drvdata(drm_privacy_screen);
+	acpi_handle handle = ACPI_HANDLE(privacy_screen);
 
-	handle = acpi_device_handle(to_acpi_device(privacy_screen));
 	obj = acpi_evaluate_dsm(handle, &chromeos_privacy_screen_dsm_guid,
 				PRIV_SCRN_DSM_REVID,
 				PRIV_SCRN_DSM_FN_GET_STATUS, NULL);
@@ -65,11 +65,9 @@ chromeos_privacy_screen_set_sw_state(struct drm_privacy_screen
 				     enum drm_privacy_screen_status state)
 {
 	union acpi_object *obj = NULL;
-	acpi_handle handle;
 	struct device *privacy_screen =
 		drm_privacy_screen_get_drvdata(drm_privacy_screen);
-
-	handle = acpi_device_handle(to_acpi_device(privacy_screen));
+	acpi_handle handle = ACPI_HANDLE(privacy_screen);
 
 	if (state == PRIVACY_SCREEN_DISABLED) {
 		obj = acpi_evaluate_dsm(handle,
@@ -104,30 +102,28 @@ static const struct drm_privacy_screen_ops chromeos_privacy_screen_ops = {
 	.set_sw_state = chromeos_privacy_screen_set_sw_state,
 };
 
-static int chromeos_privacy_screen_add(struct acpi_device *adev)
+static int chromeos_privacy_screen_probe(struct platform_device *pdev)
 {
 	struct drm_privacy_screen *drm_privacy_screen =
-		drm_privacy_screen_register(&adev->dev,
+		drm_privacy_screen_register(&pdev->dev,
 					    &chromeos_privacy_screen_ops,
-					    &adev->dev);
+					    &pdev->dev);
 
 	if (IS_ERR(drm_privacy_screen)) {
-		dev_err(&adev->dev, "Error registering privacy-screen\n");
+		dev_err(&pdev->dev, "Error registering privacy-screen\n");
 		return PTR_ERR(drm_privacy_screen);
 	}
 
-	adev->driver_data = drm_privacy_screen;
-	dev_info(&adev->dev, "registered privacy-screen '%s'\n",
+	platform_set_drvdata(pdev, drm_privacy_screen);
+	dev_info(&pdev->dev, "registered privacy-screen '%s'\n",
 		 dev_name(&drm_privacy_screen->dev));
 
 	return 0;
 }
 
-static void chromeos_privacy_screen_remove(struct acpi_device *adev)
+static void chromeos_privacy_screen_remove(struct platform_device *pdev)
 {
-	struct drm_privacy_screen *drm_privacy_screen =	acpi_driver_data(adev);
-
-	drm_privacy_screen_unregister(drm_privacy_screen);
+	drm_privacy_screen_unregister(platform_get_drvdata(pdev));
 }
 
 static const struct acpi_device_id chromeos_privacy_screen_device_ids[] = {
@@ -136,17 +132,16 @@ static const struct acpi_device_id chromeos_privacy_screen_device_ids[] = {
 };
 MODULE_DEVICE_TABLE(acpi, chromeos_privacy_screen_device_ids);
 
-static struct acpi_driver chromeos_privacy_screen_driver = {
-	.name = "chromeos_privacy_screen_driver",
-	.class = "ChromeOS",
-	.ids = chromeos_privacy_screen_device_ids,
-	.ops = {
-		.add = chromeos_privacy_screen_add,
-		.remove = chromeos_privacy_screen_remove,
+static struct platform_driver chromeos_privacy_screen_driver = {
+	.probe = chromeos_privacy_screen_probe,
+	.remove = chromeos_privacy_screen_remove,
+	.driver = {
+		.name = "chromeos_privacy_screen_driver",
+		.acpi_match_table = chromeos_privacy_screen_device_ids,
 	},
 };
 
-module_acpi_driver(chromeos_privacy_screen_driver);
+module_platform_driver(chromeos_privacy_screen_driver);
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("ChromeOS ACPI Privacy Screen driver");
 MODULE_AUTHOR("Rajat Jain <rajatja@google.com>");
-- 
2.51.0





^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 3/6] platform/chrome: chromeos_tbmc: Register ACPI notify handler
  2026-03-05 19:34 [PATCH v2 0/6] platform/chrome: Bind drivers to platform devices instead of ACPI ones Rafael J. Wysocki
  2026-03-05 19:37 ` [PATCH v2 1/6] platform/chrome: Convert ChromeOS privacy-screen driver to platform Rafael J. Wysocki
@ 2026-03-05 19:39 ` Rafael J. Wysocki
  2026-03-05 19:42 ` [PATCH v2 4/6] platform/chrome: chromeos_tbmc: Convert to a platform driver Rafael J. Wysocki
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Rafael J. Wysocki @ 2026-03-05 19:39 UTC (permalink / raw)
  To: Tzung-Bi Shih
  Cc: chrome-platform, LKML, Linux ACPI, Benson Leung,
	Enric Balletbo i Serra, Ravi Chandra Sadineni

From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>

To facilitate subsequent conversion of the driver to a platform one,
make it install an ACPI notify handler directly instead of using
a .notify() callback in struct acpi_driver.

No intentional functional impact.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---

v1 -> v2: No changes

---
 drivers/platform/chrome/chromeos_tbmc.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/platform/chrome/chromeos_tbmc.c b/drivers/platform/chrome/chromeos_tbmc.c
index e248567c0a18..9c988e697d09 100644
--- a/drivers/platform/chrome/chromeos_tbmc.c
+++ b/drivers/platform/chrome/chromeos_tbmc.c
@@ -45,8 +45,10 @@ static __maybe_unused int chromeos_tbmc_resume(struct device *dev)
 	return chromeos_tbmc_query_switch(adev, adev->driver_data);
 }
 
-static void chromeos_tbmc_notify(struct acpi_device *adev, u32 event)
+static void chromeos_tbmc_notify(acpi_handle handle, u32 event, void *data)
 {
+	struct acpi_device *adev = data;
+
 	acpi_pm_wakeup_event(&adev->dev);
 	switch (event) {
 	case 0x80:
@@ -92,11 +94,22 @@ static int chromeos_tbmc_add(struct acpi_device *adev)
 		return ret;
 	}
 	device_init_wakeup(dev, true);
+
+	ret = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
+					      chromeos_tbmc_notify, adev);
+	if (ret) {
+		dev_err(dev, "cannot install ACPI notify handler\n");
+		device_init_wakeup(dev, false);
+		return ret;
+	}
+
 	return 0;
 }
 
 static void chromeos_tbmc_remove(struct acpi_device *adev)
 {
+	acpi_dev_remove_notify_handler(adev, ACPI_DEVICE_NOTIFY,
+				       chromeos_tbmc_notify);
 	device_init_wakeup(&adev->dev, false);
 }
 
@@ -116,7 +129,6 @@ static struct acpi_driver chromeos_tbmc_driver = {
 	.ops = {
 		.add = chromeos_tbmc_add,
 		.remove = chromeos_tbmc_remove,
-		.notify = chromeos_tbmc_notify,
 	},
 	.drv.pm = &chromeos_tbmc_pm_ops,
 };
-- 
2.51.0





^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 4/6] platform/chrome: chromeos_tbmc: Convert to a platform driver
  2026-03-05 19:34 [PATCH v2 0/6] platform/chrome: Bind drivers to platform devices instead of ACPI ones Rafael J. Wysocki
  2026-03-05 19:37 ` [PATCH v2 1/6] platform/chrome: Convert ChromeOS privacy-screen driver to platform Rafael J. Wysocki
  2026-03-05 19:39 ` [PATCH v2 3/6] platform/chrome: chromeos_tbmc: Register ACPI notify handler Rafael J. Wysocki
@ 2026-03-05 19:42 ` Rafael J. Wysocki
  2026-03-05 19:43 ` [PATCH v2 5/6] platform/chrome: wilco_ec: event: Register ACPI notify handler Rafael J. Wysocki
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Rafael J. Wysocki @ 2026-03-05 19:42 UTC (permalink / raw)
  To: Tzung-Bi Shih
  Cc: chrome-platform, LKML, Linux ACPI, Benson Leung,
	Enric Balletbo i Serra, Ravi Chandra Sadineni

From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>

In all cases in which a struct acpi_driver is used for binding a driver
to an ACPI device object, a corresponding platform device is created by
the ACPI core and that device is regarded as a proper representation of
underlying hardware.  Accordingly, a struct platform_driver should be
used by driver code to bind to that device.  There are multiple reasons
why drivers should not bind directly to ACPI device objects [1].

Overall, it is better to bind drivers to platform devices than to their
ACPI companions, so convert the ChromeOS tablet mode change (TBMC) ACPI
driver to a platform one.

After this change, the subordinate input device and wakeup source class
device will be registered under the platform device used for driver
binding instead of its ACPI companion.

While this is not expected to alter functionality, it changes sysfs
layout and so it will be visible to user space.

Link: https://lore.kernel.org/all/2396510.ElGaqSPkdT@rafael.j.wysocki/ [1]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---

v1 -> v2:
   * Pass dev to acpi_pm_wakeup_event() in chromeos_tbmc_notify() (Tzung-Bi Shih)
   * Pass ACPI_COMPANION(dev) directly to chromeos_tbmc_query_switch in
     chromeos_tbmc_notify()

---
 drivers/platform/chrome/chromeos_tbmc.c | 47 ++++++++++++-------------
 1 file changed, 23 insertions(+), 24 deletions(-)

diff --git a/drivers/platform/chrome/chromeos_tbmc.c b/drivers/platform/chrome/chromeos_tbmc.c
index 9c988e697d09..5133806b2d95 100644
--- a/drivers/platform/chrome/chromeos_tbmc.c
+++ b/drivers/platform/chrome/chromeos_tbmc.c
@@ -16,6 +16,7 @@
 #include <linux/input.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/printk.h>
 
 #define DRV_NAME "chromeos_tbmc"
@@ -40,22 +41,20 @@ static int chromeos_tbmc_query_switch(struct acpi_device *adev,
 
 static __maybe_unused int chromeos_tbmc_resume(struct device *dev)
 {
-	struct acpi_device *adev = to_acpi_device(dev);
-
-	return chromeos_tbmc_query_switch(adev, adev->driver_data);
+	return chromeos_tbmc_query_switch(ACPI_COMPANION(dev), dev_get_drvdata(dev));
 }
 
 static void chromeos_tbmc_notify(acpi_handle handle, u32 event, void *data)
 {
-	struct acpi_device *adev = data;
+	struct device *dev = data;
 
-	acpi_pm_wakeup_event(&adev->dev);
+	acpi_pm_wakeup_event(dev);
 	switch (event) {
 	case 0x80:
-		chromeos_tbmc_query_switch(adev, adev->driver_data);
+		chromeos_tbmc_query_switch(ACPI_COMPANION(dev), dev_get_drvdata(dev));
 		break;
 	default:
-		dev_err(&adev->dev, "Unexpected event: 0x%08X\n", event);
+		dev_err(dev, "Unexpected event: 0x%08X\n", event);
 	}
 }
 
@@ -66,10 +65,11 @@ static int chromeos_tbmc_open(struct input_dev *idev)
 	return chromeos_tbmc_query_switch(adev, idev);
 }
 
-static int chromeos_tbmc_add(struct acpi_device *adev)
+static int chromeos_tbmc_probe(struct platform_device *pdev)
 {
 	struct input_dev *idev;
-	struct device *dev = &adev->dev;
+	struct device *dev = &pdev->dev;
+	struct acpi_device *adev = ACPI_COMPANION(dev);
 	int ret;
 
 	idev = devm_input_allocate_device(dev);
@@ -85,7 +85,7 @@ static int chromeos_tbmc_add(struct acpi_device *adev)
 	idev->open = chromeos_tbmc_open;
 
 	input_set_drvdata(idev, adev);
-	adev->driver_data = idev;
+	platform_set_drvdata(pdev, idev);
 
 	input_set_capability(idev, EV_SW, SW_TABLET_MODE);
 	ret = input_register_device(idev);
@@ -96,7 +96,7 @@ static int chromeos_tbmc_add(struct acpi_device *adev)
 	device_init_wakeup(dev, true);
 
 	ret = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
-					      chromeos_tbmc_notify, adev);
+					      chromeos_tbmc_notify, dev);
 	if (ret) {
 		dev_err(dev, "cannot install ACPI notify handler\n");
 		device_init_wakeup(dev, false);
@@ -106,11 +106,11 @@ static int chromeos_tbmc_add(struct acpi_device *adev)
 	return 0;
 }
 
-static void chromeos_tbmc_remove(struct acpi_device *adev)
+static void chromeos_tbmc_remove(struct platform_device *pdev)
 {
-	acpi_dev_remove_notify_handler(adev, ACPI_DEVICE_NOTIFY,
-				       chromeos_tbmc_notify);
-	device_init_wakeup(&adev->dev, false);
+	acpi_dev_remove_notify_handler(ACPI_COMPANION(&pdev->dev),
+				       ACPI_DEVICE_NOTIFY, chromeos_tbmc_notify);
+	device_init_wakeup(&pdev->dev, false);
 }
 
 static const struct acpi_device_id chromeos_tbmc_acpi_device_ids[] = {
@@ -122,18 +122,17 @@ MODULE_DEVICE_TABLE(acpi, chromeos_tbmc_acpi_device_ids);
 static SIMPLE_DEV_PM_OPS(chromeos_tbmc_pm_ops, NULL,
 		chromeos_tbmc_resume);
 
-static struct acpi_driver chromeos_tbmc_driver = {
-	.name = DRV_NAME,
-	.class = DRV_NAME,
-	.ids = chromeos_tbmc_acpi_device_ids,
-	.ops = {
-		.add = chromeos_tbmc_add,
-		.remove = chromeos_tbmc_remove,
+static struct platform_driver chromeos_tbmc_driver = {
+	.probe = chromeos_tbmc_probe,
+	.remove = chromeos_tbmc_remove,
+	.driver = {
+		.name = DRV_NAME,
+		.acpi_match_table = chromeos_tbmc_acpi_device_ids,
+		.pm = &chromeos_tbmc_pm_ops,
 	},
-	.drv.pm = &chromeos_tbmc_pm_ops,
 };
 
-module_acpi_driver(chromeos_tbmc_driver);
+module_platform_driver(chromeos_tbmc_driver);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("ChromeOS ACPI tablet switch driver");
-- 
2.51.0





^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 5/6] platform/chrome: wilco_ec: event: Register ACPI notify handler
  2026-03-05 19:34 [PATCH v2 0/6] platform/chrome: Bind drivers to platform devices instead of ACPI ones Rafael J. Wysocki
                   ` (2 preceding siblings ...)
  2026-03-05 19:42 ` [PATCH v2 4/6] platform/chrome: chromeos_tbmc: Convert to a platform driver Rafael J. Wysocki
@ 2026-03-05 19:43 ` Rafael J. Wysocki
  2026-03-05 19:46 ` [PATCH v2 6/6] platform/chrome: wilco_ec: event: Convert to a platform driver Rafael J. Wysocki
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Rafael J. Wysocki @ 2026-03-05 19:43 UTC (permalink / raw)
  To: Tzung-Bi Shih
  Cc: chrome-platform, LKML, Linux ACPI, Benson Leung,
	Enric Balletbo i Serra, Ravi Chandra Sadineni

From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>

To facilitate subsequent conversion of the driver to a platform one,
make it install an ACPI notify handler directly instead of using
a .notify() callback in struct acpi_driver.

No intentional functional impact.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---

v1 -> v2: No changes

---
 drivers/platform/chrome/wilco_ec/event.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/platform/chrome/wilco_ec/event.c b/drivers/platform/chrome/wilco_ec/event.c
index 743cd4839bff..f4500dd05f93 100644
--- a/drivers/platform/chrome/wilco_ec/event.c
+++ b/drivers/platform/chrome/wilco_ec/event.c
@@ -253,14 +253,16 @@ static int enqueue_events(struct acpi_device *adev, const u8 *buf, u32 length)
 
 /**
  * event_device_notify() - Callback when EC generates an event over ACPI.
- * @adev: The device that the event is coming from.
+ * @handle: ACPI handle of the device that the event is coming from.
  * @value: Value passed to Notify() in ACPI.
+ * @data: Notify handler data.
  *
  * This function will read the events from the device and enqueue them.
  */
-static void event_device_notify(struct acpi_device *adev, u32 value)
+static void event_device_notify(acpi_handle handle, u32 value, void *data)
 {
 	struct acpi_buffer event_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_device *adev = data;
 	union acpi_object *obj;
 	acpi_status status;
 
@@ -489,8 +491,16 @@ static int event_device_add(struct acpi_device *adev)
 	if (error)
 		goto free_dev_data;
 
+	/* Install an ACPI notify handler. */
+	error = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
+						event_device_notify, adev);
+	if (error)
+		goto free_cdev;
+
 	return 0;
 
+free_cdev:
+	cdev_device_del(&dev_data->cdev, &dev_data->dev);
 free_dev_data:
 	hangup_device(dev_data);
 free_minor:
@@ -502,6 +512,8 @@ static void event_device_remove(struct acpi_device *adev)
 {
 	struct event_device_data *dev_data = adev->driver_data;
 
+	acpi_dev_remove_notify_handler(adev, ACPI_DEVICE_NOTIFY,
+				       event_device_notify);
 	cdev_device_del(&dev_data->cdev, &dev_data->dev);
 	ida_free(&event_ida, MINOR(dev_data->dev.devt));
 	hangup_device(dev_data);
@@ -519,7 +531,6 @@ static struct acpi_driver event_driver = {
 	.ids = event_acpi_ids,
 	.ops = {
 		.add = event_device_add,
-		.notify = event_device_notify,
 		.remove = event_device_remove,
 	},
 };
-- 
2.51.0





^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 6/6] platform/chrome: wilco_ec: event: Convert to a platform driver
  2026-03-05 19:34 [PATCH v2 0/6] platform/chrome: Bind drivers to platform devices instead of ACPI ones Rafael J. Wysocki
                   ` (3 preceding siblings ...)
  2026-03-05 19:43 ` [PATCH v2 5/6] platform/chrome: wilco_ec: event: Register ACPI notify handler Rafael J. Wysocki
@ 2026-03-05 19:46 ` Rafael J. Wysocki
  2026-03-05 19:47 ` [PATCH v2 2/6] platform/chrome: chromeos_tbmc: Drop wakeup source on remove Rafael J. Wysocki
  2026-03-06  4:46 ` [PATCH v2 0/6] platform/chrome: Bind drivers to platform devices instead of ACPI ones Tzung-Bi Shih
  6 siblings, 0 replies; 8+ messages in thread
From: Rafael J. Wysocki @ 2026-03-05 19:46 UTC (permalink / raw)
  To: Tzung-Bi Shih
  Cc: chrome-platform, LKML, Linux ACPI, Benson Leung,
	Enric Balletbo i Serra, Ravi Chandra Sadineni

From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>

In all cases in which a struct acpi_driver is used for binding a driver
to an ACPI device object, a corresponding platform device is created by
the ACPI core and that device is regarded as a proper representation of
underlying hardware.  Accordingly, a struct platform_driver should be
used by driver code to bind to that device.  There are multiple reasons
why drivers should not bind directly to ACPI device objects [1].

Overall, it is better to bind drivers to platform devices than to their
ACPI companions, so convert the ChromeOS Wilco Embedded Controller event
ACPI driver to a platform one.

While this is not expected to alter functionality, it changes sysfs
layout and so it will be visible to user space.

Link: https://lore.kernel.org/all/2396510.ElGaqSPkdT@rafael.j.wysocki/ [1]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---

v1 -> v2: No changes

---
 drivers/platform/chrome/wilco_ec/event.c | 66 ++++++++++++------------
 1 file changed, 34 insertions(+), 32 deletions(-)

diff --git a/drivers/platform/chrome/wilco_ec/event.c b/drivers/platform/chrome/wilco_ec/event.c
index f4500dd05f93..b6e935badc0e 100644
--- a/drivers/platform/chrome/wilco_ec/event.c
+++ b/drivers/platform/chrome/wilco_ec/event.c
@@ -38,6 +38,7 @@
 #include <linux/io.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/poll.h>
 #include <linux/spinlock.h>
 #include <linux/uaccess.h>
@@ -198,7 +199,7 @@ struct event_device_data {
 
 /**
  * enqueue_events() - Place EC events in queue to be read by userspace.
- * @adev: Device the events came from.
+ * @dev: Device the events came from.
  * @buf: Buffer of event data.
  * @length: Length of event data buffer.
  *
@@ -209,9 +210,9 @@ struct event_device_data {
  *
  * Return: 0 on success or negative error code on failure.
  */
-static int enqueue_events(struct acpi_device *adev, const u8 *buf, u32 length)
+static int enqueue_events(struct device *dev, const u8 *buf, u32 length)
 {
-	struct event_device_data *dev_data = adev->driver_data;
+	struct event_device_data *dev_data = dev_get_drvdata(dev);
 	struct ec_event *event, *queue_event, *old_event;
 	size_t num_words, event_size;
 	u32 offset = 0;
@@ -222,14 +223,14 @@ static int enqueue_events(struct acpi_device *adev, const u8 *buf, u32 length)
 		num_words = ec_event_num_words(event);
 		event_size = ec_event_size(event);
 		if (num_words > EC_ACPI_MAX_EVENT_WORDS) {
-			dev_err(&adev->dev, "Too many event words: %zu > %d\n",
+			dev_err(dev, "Too many event words: %zu > %d\n",
 				num_words, EC_ACPI_MAX_EVENT_WORDS);
 			return -EOVERFLOW;
 		}
 
 		/* Ensure event does not overflow the available buffer */
 		if ((offset + event_size) > length) {
-			dev_err(&adev->dev, "Event exceeds buffer: %zu > %d\n",
+			dev_err(dev, "Event exceeds buffer: %zu > %d\n",
 				offset + event_size, length);
 			return -EOVERFLOW;
 		}
@@ -262,12 +263,13 @@ static int enqueue_events(struct acpi_device *adev, const u8 *buf, u32 length)
 static void event_device_notify(acpi_handle handle, u32 value, void *data)
 {
 	struct acpi_buffer event_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-	struct acpi_device *adev = data;
+	struct device *dev = data;
+	struct acpi_device *adev = ACPI_COMPANION(dev);
 	union acpi_object *obj;
 	acpi_status status;
 
 	if (value != EC_ACPI_NOTIFY_EVENT) {
-		dev_err(&adev->dev, "Invalid event: 0x%08x\n", value);
+		dev_err(dev, "Invalid event: 0x%08x\n", value);
 		return;
 	}
 
@@ -275,31 +277,31 @@ static void event_device_notify(acpi_handle handle, u32 value, void *data)
 	status = acpi_evaluate_object(adev->handle, EC_ACPI_GET_EVENT,
 				      NULL, &event_buffer);
 	if (ACPI_FAILURE(status)) {
-		dev_err(&adev->dev, "Error executing ACPI method %s()\n",
+		dev_err(dev, "Error executing ACPI method %s()\n",
 			EC_ACPI_GET_EVENT);
 		return;
 	}
 
 	obj = (union acpi_object *)event_buffer.pointer;
 	if (!obj) {
-		dev_err(&adev->dev, "Nothing returned from %s()\n",
+		dev_err(dev, "Nothing returned from %s()\n",
 			EC_ACPI_GET_EVENT);
 		return;
 	}
 	if (obj->type != ACPI_TYPE_BUFFER) {
-		dev_err(&adev->dev, "Invalid object returned from %s()\n",
+		dev_err(dev, "Invalid object returned from %s()\n",
 			EC_ACPI_GET_EVENT);
 		kfree(obj);
 		return;
 	}
 	if (obj->buffer.length < sizeof(struct ec_event)) {
-		dev_err(&adev->dev, "Invalid buffer length %d from %s()\n",
+		dev_err(dev, "Invalid buffer length %d from %s()\n",
 			obj->buffer.length, EC_ACPI_GET_EVENT);
 		kfree(obj);
 		return;
 	}
 
-	enqueue_events(adev, obj->buffer.pointer, obj->buffer.length);
+	enqueue_events(dev, obj->buffer.pointer, obj->buffer.length);
 	kfree(obj);
 }
 
@@ -434,8 +436,8 @@ static void hangup_device(struct event_device_data *dev_data)
 }
 
 /**
- * event_device_add() - Callback when creating a new device.
- * @adev: ACPI device that we will be receiving events from.
+ * event_device_probe() - Callback when creating a new device.
+ * @pdev: Platform device that we will be receiving events from.
  *
  * This finds a free minor number for the device, allocates and initializes
  * some device data, and creates a new device and char dev node.
@@ -447,7 +449,7 @@ static void hangup_device(struct event_device_data *dev_data)
  *
  * Return: 0 on success, negative error code on failure.
  */
-static int event_device_add(struct acpi_device *adev)
+static int event_device_probe(struct platform_device *pdev)
 {
 	struct event_device_data *dev_data;
 	int error, minor;
@@ -455,7 +457,7 @@ static int event_device_add(struct acpi_device *adev)
 	minor = ida_alloc_max(&event_ida, EVENT_MAX_DEV-1, GFP_KERNEL);
 	if (minor < 0) {
 		error = minor;
-		dev_err(&adev->dev, "Failed to find minor number: %d\n", error);
+		dev_err(&pdev->dev, "Failed to find minor number: %d\n", error);
 		return error;
 	}
 
@@ -466,7 +468,7 @@ static int event_device_add(struct acpi_device *adev)
 	}
 
 	/* Initialize the device data. */
-	adev->driver_data = dev_data;
+	platform_set_drvdata(pdev, dev_data);
 	dev_data->events = event_queue_new(queue_size);
 	if (!dev_data->events) {
 		kfree(dev_data);
@@ -492,8 +494,9 @@ static int event_device_add(struct acpi_device *adev)
 		goto free_dev_data;
 
 	/* Install an ACPI notify handler. */
-	error = acpi_dev_install_notify_handler(adev, ACPI_DEVICE_NOTIFY,
-						event_device_notify, adev);
+	error = acpi_dev_install_notify_handler(ACPI_COMPANION(&pdev->dev),
+						ACPI_DEVICE_NOTIFY,
+						event_device_notify, &pdev->dev);
 	if (error)
 		goto free_cdev;
 
@@ -508,12 +511,12 @@ static int event_device_add(struct acpi_device *adev)
 	return error;
 }
 
-static void event_device_remove(struct acpi_device *adev)
+static void event_device_remove(struct platform_device *pdev)
 {
-	struct event_device_data *dev_data = adev->driver_data;
+	struct event_device_data *dev_data = platform_get_drvdata(pdev);
 
-	acpi_dev_remove_notify_handler(adev, ACPI_DEVICE_NOTIFY,
-				       event_device_notify);
+	acpi_dev_remove_notify_handler(ACPI_COMPANION(&pdev->dev),
+				       ACPI_DEVICE_NOTIFY, event_device_notify);
 	cdev_device_del(&dev_data->cdev, &dev_data->dev);
 	ida_free(&event_ida, MINOR(dev_data->dev.devt));
 	hangup_device(dev_data);
@@ -525,13 +528,12 @@ static const struct acpi_device_id event_acpi_ids[] = {
 };
 MODULE_DEVICE_TABLE(acpi, event_acpi_ids);
 
-static struct acpi_driver event_driver = {
-	.name = DRV_NAME,
-	.class = DRV_NAME,
-	.ids = event_acpi_ids,
-	.ops = {
-		.add = event_device_add,
-		.remove = event_device_remove,
+static struct platform_driver event_driver = {
+	.probe = event_device_probe,
+	.remove = event_device_remove,
+	.driver = {
+		.name = DRV_NAME,
+		.acpi_match_table = event_acpi_ids,
 	},
 };
 
@@ -554,7 +556,7 @@ static int __init event_module_init(void)
 	}
 	event_major = MAJOR(dev_num);
 
-	ret = acpi_bus_register_driver(&event_driver);
+	ret = platform_driver_register(&event_driver);
 	if (ret < 0) {
 		pr_err(DRV_NAME ": Failed registering driver: %d\n", ret);
 		goto unregister_region;
@@ -572,7 +574,7 @@ static int __init event_module_init(void)
 
 static void __exit event_module_exit(void)
 {
-	acpi_bus_unregister_driver(&event_driver);
+	platform_driver_unregister(&event_driver);
 	unregister_chrdev_region(MKDEV(event_major, 0), EVENT_MAX_DEV);
 	class_unregister(&event_class);
 	ida_destroy(&event_ida);
-- 
2.51.0





^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/6] platform/chrome: chromeos_tbmc: Drop wakeup source on remove
  2026-03-05 19:34 [PATCH v2 0/6] platform/chrome: Bind drivers to platform devices instead of ACPI ones Rafael J. Wysocki
                   ` (4 preceding siblings ...)
  2026-03-05 19:46 ` [PATCH v2 6/6] platform/chrome: wilco_ec: event: Convert to a platform driver Rafael J. Wysocki
@ 2026-03-05 19:47 ` Rafael J. Wysocki
  2026-03-06  4:46 ` [PATCH v2 0/6] platform/chrome: Bind drivers to platform devices instead of ACPI ones Tzung-Bi Shih
  6 siblings, 0 replies; 8+ messages in thread
From: Rafael J. Wysocki @ 2026-03-05 19:47 UTC (permalink / raw)
  To: Tzung-Bi Shih
  Cc: chrome-platform, LKML, Linux ACPI, Benson Leung,
	Enric Balletbo i Serra, Ravi Chandra Sadineni

From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>

The wakeup source added by device_init_wakeup() in chromeos_tbmc_add()
needs to be dropped during driver removal, so add a .remove() callback
to the driver for this purpose.

Fixes: 0144c00ed86b ("platform/chrome: chromeos_tbmc: Report wake events")
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---

v1 -> v2: Fixes the Fixes: tag (Tzung-Bi Shih)

---
 drivers/platform/chrome/chromeos_tbmc.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/platform/chrome/chromeos_tbmc.c b/drivers/platform/chrome/chromeos_tbmc.c
index d1cf8f3463ce..e248567c0a18 100644
--- a/drivers/platform/chrome/chromeos_tbmc.c
+++ b/drivers/platform/chrome/chromeos_tbmc.c
@@ -95,6 +95,11 @@ static int chromeos_tbmc_add(struct acpi_device *adev)
 	return 0;
 }
 
+static void chromeos_tbmc_remove(struct acpi_device *adev)
+{
+	device_init_wakeup(&adev->dev, false);
+}
+
 static const struct acpi_device_id chromeos_tbmc_acpi_device_ids[] = {
 	{ ACPI_DRV_NAME, 0 },
 	{ }
@@ -110,6 +115,7 @@ static struct acpi_driver chromeos_tbmc_driver = {
 	.ids = chromeos_tbmc_acpi_device_ids,
 	.ops = {
 		.add = chromeos_tbmc_add,
+		.remove = chromeos_tbmc_remove,
 		.notify = chromeos_tbmc_notify,
 	},
 	.drv.pm = &chromeos_tbmc_pm_ops,
-- 
2.51.0





^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 0/6] platform/chrome: Bind drivers to platform devices instead of ACPI ones
  2026-03-05 19:34 [PATCH v2 0/6] platform/chrome: Bind drivers to platform devices instead of ACPI ones Rafael J. Wysocki
                   ` (5 preceding siblings ...)
  2026-03-05 19:47 ` [PATCH v2 2/6] platform/chrome: chromeos_tbmc: Drop wakeup source on remove Rafael J. Wysocki
@ 2026-03-06  4:46 ` Tzung-Bi Shih
  6 siblings, 0 replies; 8+ messages in thread
From: Tzung-Bi Shih @ 2026-03-06  4:46 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: chrome-platform, LKML, Linux ACPI, Benson Leung,
	Enric Balletbo i Serra, Ravi Chandra Sadineni

On Thu, Mar 05, 2026 at 08:34:58PM +0100, Rafael J. Wysocki wrote:
> Hi All,
> 
> This is a v2 of
> 
> https://lore.kernel.org/linux-acpi/2274474.Mh6RI2rZIc@rafael.j.wysocki/
> 
> addressing review comments on patches [2/6] and [4/6].
> 
> The series description below still applies.
>
> [...]

Applied to

    https://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux.git for-next

[1/6] platform/chrome: Convert ChromeOS privacy-screen driver to platform
      commit: d3c2872ae323ea45cc32ea0247f26c2189a481cb
[2/6] platform/chrome: chromeos_tbmc: Drop wakeup source on remove
      commit: 5d441a4bc93642ed6f41da87327a39946b4e1455
[3/6] platform/chrome: chromeos_tbmc: Register ACPI notify handler
      commit: de1260139dbd7610a2f25343c962569b8fe23f8f
[4/6] platform/chrome: chromeos_tbmc: Convert to a platform driver
      commit: a2676ead257f6cf12e458efc786a68d6ab7c1224
[5/6] platform/chrome: wilco_ec: event: Register ACPI notify handler
      commit: 25a06b7a3224161cf4b27049bea93cac21136460
[6/6] platform/chrome: wilco_ec: event: Convert to a platform driver
      commit: 27d58498f690ab39140678df918155a597b3a17a

Thanks!

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-03-06  4:46 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-05 19:34 [PATCH v2 0/6] platform/chrome: Bind drivers to platform devices instead of ACPI ones Rafael J. Wysocki
2026-03-05 19:37 ` [PATCH v2 1/6] platform/chrome: Convert ChromeOS privacy-screen driver to platform Rafael J. Wysocki
2026-03-05 19:39 ` [PATCH v2 3/6] platform/chrome: chromeos_tbmc: Register ACPI notify handler Rafael J. Wysocki
2026-03-05 19:42 ` [PATCH v2 4/6] platform/chrome: chromeos_tbmc: Convert to a platform driver Rafael J. Wysocki
2026-03-05 19:43 ` [PATCH v2 5/6] platform/chrome: wilco_ec: event: Register ACPI notify handler Rafael J. Wysocki
2026-03-05 19:46 ` [PATCH v2 6/6] platform/chrome: wilco_ec: event: Convert to a platform driver Rafael J. Wysocki
2026-03-05 19:47 ` [PATCH v2 2/6] platform/chrome: chromeos_tbmc: Drop wakeup source on remove Rafael J. Wysocki
2026-03-06  4:46 ` [PATCH v2 0/6] platform/chrome: Bind drivers to platform devices instead of ACPI ones Tzung-Bi Shih

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox