All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ACPI / PM: Fix PM initialization for devices that are not present
@ 2015-01-01 22:38 Rafael J. Wysocki
  2015-01-05 13:40 ` Mika Westerberg
  0 siblings, 1 reply; 2+ messages in thread
From: Rafael J. Wysocki @ 2015-01-01 22:38 UTC (permalink / raw)
  To: ACPI Devel Maling List
  Cc: Linux PM list, Mika Westerberg, Linux Kernel Mailing List

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

If an ACPI device object whose _STA returns 0 (not present and not
functional) has _PR0 or _PS0, its power_manageable flag will be set
and acpi_bus_init_power() will return 0 for it.  Consequently, if
such a device object is passed to the ACPI device PM functions, they
will attempt to carry out the requested operation on the device,
although they should not do that for devices that are not present.

To fix that problem make acpi_bus_init_power() return an error code
for devices that are not present which will cause power_manageable to
be cleared for them as appropriate in acpi_bus_get_power_flags().
However, the lists of power resources should not be freed for the
device in that case, so modify acpi_bus_get_power_flags() to keep
those lists even if acpi_bus_init_power() returns an error.
Accordingly, when deciding whether or not the lists of power
resources need to be freed, acpi_free_power_resources_lists()
should check the power.flags.power_resources flag instead of
flags.power_manageable, so make that change too.

Furthermore, if acpi_bus_attach() sees that flags.initialized is
unset for the given device, it should reset the power management
settings of the device and re-initialize them from scratch instead
of relying on the previous settings (the device may have appeared
after being not present previously, for example), so make it use
the 'valid' flag of the D0 power state as the initial value of
flags.power_manageable for it and call acpi_bus_init_power() to
discover its current power state.

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

"Stable" material.

---
 drivers/acpi/device_pm.c |    2 +-
 drivers/acpi/scan.c      |   13 ++++++++-----
 2 files changed, 9 insertions(+), 6 deletions(-)

Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -257,7 +257,7 @@ int acpi_bus_init_power(struct acpi_devi
 
 	device->power.state = ACPI_STATE_UNKNOWN;
 	if (!acpi_device_is_present(device))
-		return 0;
+		return -ENXIO;
 
 	result = acpi_device_get_power(device, &state);
 	if (result)
Index: linux-pm/drivers/acpi/scan.c
===================================================================
--- linux-pm.orig/drivers/acpi/scan.c
+++ linux-pm/drivers/acpi/scan.c
@@ -1001,7 +1001,7 @@ static void acpi_free_power_resources_li
 	if (device->wakeup.flags.valid)
 		acpi_power_resources_list_free(&device->wakeup.resources);
 
-	if (!device->flags.power_manageable)
+	if (!device->power.flags.power_resources)
 		return;
 
 	for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) {
@@ -1744,10 +1744,8 @@ static void acpi_bus_get_power_flags(str
 			device->power.flags.power_resources)
 		device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible = 1;
 
-	if (acpi_bus_init_power(device)) {
-		acpi_free_power_resources_lists(device);
+	if (acpi_bus_init_power(device))
 		device->flags.power_manageable = 0;
-	}
 }
 
 static void acpi_bus_get_flags(struct acpi_device *device)
@@ -2371,13 +2369,18 @@ static void acpi_bus_attach(struct acpi_
 	/* Skip devices that are not present. */
 	if (!acpi_device_is_present(device)) {
 		device->flags.visited = false;
+		device->flags.power_manageable = 0;
 		return;
 	}
 	if (device->handler)
 		goto ok;
 
 	if (!device->flags.initialized) {
-		acpi_bus_update_power(device, NULL);
+		device->flags.power_manageable =
+			device->power.states[ACPI_STATE_D0].flags.valid;
+		if (acpi_bus_init_power(device))
+			device->flags.power_manageable = 0;
+
 		device->flags.initialized = true;
 	}
 	device->flags.visited = false;


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

* Re: [PATCH] ACPI / PM: Fix PM initialization for devices that are not present
  2015-01-01 22:38 [PATCH] ACPI / PM: Fix PM initialization for devices that are not present Rafael J. Wysocki
@ 2015-01-05 13:40 ` Mika Westerberg
  0 siblings, 0 replies; 2+ messages in thread
From: Mika Westerberg @ 2015-01-05 13:40 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: ACPI Devel Maling List, Linux PM list, Linux Kernel Mailing List

On Thu, Jan 01, 2015 at 11:38:28PM +0100, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> If an ACPI device object whose _STA returns 0 (not present and not
> functional) has _PR0 or _PS0, its power_manageable flag will be set
> and acpi_bus_init_power() will return 0 for it.  Consequently, if
> such a device object is passed to the ACPI device PM functions, they
> will attempt to carry out the requested operation on the device,
> although they should not do that for devices that are not present.
> 
> To fix that problem make acpi_bus_init_power() return an error code
> for devices that are not present which will cause power_manageable to
> be cleared for them as appropriate in acpi_bus_get_power_flags().
> However, the lists of power resources should not be freed for the
> device in that case, so modify acpi_bus_get_power_flags() to keep
> those lists even if acpi_bus_init_power() returns an error.
> Accordingly, when deciding whether or not the lists of power
> resources need to be freed, acpi_free_power_resources_lists()
> should check the power.flags.power_resources flag instead of
> flags.power_manageable, so make that change too.
> 
> Furthermore, if acpi_bus_attach() sees that flags.initialized is
> unset for the given device, it should reset the power management
> settings of the device and re-initialize them from scratch instead
> of relying on the previous settings (the device may have appeared
> after being not present previously, for example), so make it use
> the 'valid' flag of the D0 power state as the initial value of
> flags.power_manageable for it and call acpi_bus_init_power() to
> discover its current power state.
> 
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>

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

end of thread, other threads:[~2015-01-05 13:40 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-01 22:38 [PATCH] ACPI / PM: Fix PM initialization for devices that are not present Rafael J. Wysocki
2015-01-05 13:40 ` Mika Westerberg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.