Thread (12 messages) 12 messages, 5 authors, 2012-11-27

RE: [PATCH 2/2] platform / ACPI: Attach/detach ACPI PM during probe/remove/shutdown

From: Zheng, Lv <hidden>
Date: 2012-11-27 05:25:04
Also in: linux-acpi, lkml

It looks cleanest unless more abstractions are introduced for other power management providers.

Best regards/Lv Zheng
quoted hunk ↗ jump to hunk
-----Original Message-----
From: Rafael J. Wysocki [mailto:rjw@sisk.pl]
Sent: Sunday, November 25, 2012 10:58 PM
To: LKML
Cc: Greg Kroah-Hartman; Linux PM list; ACPI Devel Maling List; Zhang, Rui;
Svahn, Kai; Mika Westerberg; Huang, Ying; Lan, Tianyu; Zheng, Lv; Lu, Aaron;
Grant Likely
Subject: [PATCH 2/2] platform / ACPI: Attach/detach ACPI PM during
probe/remove/shutdown

From: Rafael J. Wysocki <redacted>

Drivers usually expect that the devices they are supposed to handle will be
operational when their .probe() routines are called, but that need not be the
case on some ACPI-based systems with ACPI-based device enumeration where
the BIOSes don't put devices into D0 by default.  To work around this problem
it is sufficient to change bus type .probe() routines to ensure that devices will
be powered on before the drivers' .probe() routines run (and their .remove()
and .shutdown() routines accordingly).

Modify platform_drv_probe() to run acpi_dev_pm_attach() for devices whose
ACPI handles are present, so that ACPI power management is used to change
their power states and change their power states to D0 before driver probing.
Analogously, modify platform_drv_remove() and
platform_drv_shutdown() to call acpi_dev_pm_detach() for those devices, so
that they are not subject to ACPI PM any more.

Signed-off-by: Rafael J. Wysocki <redacted>
---
 drivers/base/platform.c |   19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

Index: linux/drivers/base/platform.c
================================================================
===
--- linux.orig/drivers/base/platform.c
+++ linux/drivers/base/platform.c
@@ -484,8 +484,16 @@ static int platform_drv_probe(struct dev  {
 	struct platform_driver *drv = to_platform_driver(_dev->driver);
 	struct platform_device *dev = to_platform_device(_dev);
+	int ret;

-	return drv->probe(dev);
+	if (ACPI_HANDLE(_dev))
+		acpi_dev_pm_attach(_dev, true);
+
+	ret = drv->probe(dev);
+	if (ret && ACPI_HANDLE(_dev))
+		acpi_dev_pm_detach(_dev, true);
+
+	return ret;
 }

 static int platform_drv_probe_fail(struct device *_dev) @@ -497,8 +505,13
@@ static int platform_drv_remove(struct de  {
 	struct platform_driver *drv = to_platform_driver(_dev->driver);
 	struct platform_device *dev = to_platform_device(_dev);
+	int ret;
+
+	ret = drv->remove(dev);
+	if (ACPI_HANDLE(_dev))
+		acpi_dev_pm_detach(_dev, true);

-	return drv->remove(dev);
+	return ret;
 }

 static void platform_drv_shutdown(struct device *_dev) @@ -507,6 +520,8
@@ static void platform_drv_shutdown(struct
 	struct platform_device *dev = to_platform_device(_dev);

 	drv->shutdown(dev);
+	if (ACPI_HANDLE(_dev))
+		acpi_dev_pm_detach(_dev, true);
 }

 /**
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help