[PATCH] ACPI: Be more careful about returning errors from acpi_power_resume()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I have a problem with acpi_power_resume() and the patch introducing the new
callbacks for suspend/hibernation:

http://marc.info/?l=linux-kernel&m=120684588424639&w=4

Namely, this patch also changes the behavior of the PM core wrt errors returned
by drivers' ->resume() callbacks in such a way that if an error is returned by
one of them, the devices is regarded as "invalid" by the PM core and won't be
suspended etc.

OTOH, acpi_power_resume() apparently returns errors in situations which are
perfectly recoverable.  Namely, it may return an error if it attempts to turn a
power resource on, which appears to be successful (ie.
acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL) returns 0),
but the state of the resource returned by acpi_power_get_state() called
subsequently is not ACPI_POWER_RESOURCE_STATE_ON.  However, on
my nx6325 this only means that the platform firmware's idea about the state
the power resource should be in is different than ours.  Thus, apparently,
acpi_power_resume() shouldn't return errors in such cases.

Moreover, having looked at acpi_power_resume() I understand that it's supposed
to try to turn the power resource on, if it references any device.  If that is
correct, acpi_power_resume() doesn't really need to call acpi_power_on()
and it may use acpi_evaluate_object() on a power resource directly if that
resource references at least one device.  This makes it possible to handle
errors in acpi_power_resume() more carefully, which is implemented by the
appended patch.

Thanks,
Rafael

---
From: Rafael J. Wysocki <rjw@xxxxxxx>

Modify acpi_power_resume() so that it doesn't return errors unnecessarily.

This doesn't make a real difference with the current PM core code (the errors
returned by acpi_power_resume() are ignored anyway), but in the future it may
cause problems if acpi_power_resume() returns an error code that it shouldn't
return.

Signed-off-by: Rafael J. Wysocki <rjw@xxxxxxx>
---
 drivers/acpi/power.c |   27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

Index: linux-2.6/drivers/acpi/power.c
===================================================================
--- linux-2.6.orig/drivers/acpi/power.c
+++ linux-2.6/drivers/acpi/power.c
@@ -665,7 +665,7 @@ static int acpi_power_resume(struct acpi
 {
 	int result = 0, state;
 	struct acpi_power_resource *resource = NULL;
-	struct acpi_power_reference *ref;
+	acpi_status status = AE_UNKNOWN_STATUS;
 
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
@@ -679,13 +679,28 @@ static int acpi_power_resume(struct acpi
 	mutex_lock(&resource->resource_lock);
 	if (state == ACPI_POWER_RESOURCE_STATE_OFF &&
 	    !list_empty(&resource->reference)) {
-		ref = container_of(resource->reference.next, struct acpi_power_reference, node);
-		mutex_unlock(&resource->resource_lock);
-		result = acpi_power_on(device->handle, ref->device);
-		return result;
+		/* Try to turn the power resource on. */
+		status = acpi_evaluate_object(resource->device->handle,
+						"_ON", NULL, NULL);
+		if (ACPI_FAILURE(status))
+			printk(KERN_WARNING PREFIX
+				"Failed to turn power resource %s [%s] on\n",
+				acpi_device_name(device),
+				acpi_device_bid(device));
 	}
-
 	mutex_unlock(&resource->resource_lock);
+	if (ACPI_SUCCESS(status)) {
+		result = acpi_power_get_state(resource, &state);
+		if (!result && state == ACPI_POWER_RESOURCE_STATE_ON) {
+			/* Update the power resource's _device_ power state */
+			resource->device->power.state = ACPI_STATE_D0;
+
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+					"Resource [%s] turned on\n",
+					resource->name));
+		}
+	}
+
 	return 0;
 }
 

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux