Message ID | 24285515.9Jp3KUo9Px@vostro.rjw.lan (mailing list archive) |
---|---|
State | Not Applicable, archived |
Headers | show |
On Tue, Jan 22, 2013 at 03:09:01AM +0100, Rafael J. Wysocki wrote: > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > The ACPI specification requires the _PSC method to be present under > a device object if its power state cannot be inferred from the states > of power resources used by it (ACPI 5, Section 7.6.2). However, it > also requires that (for power states D0-D2 and D3hot) if the _PSn > (n = 0, 1, 2, 3) method is present under the device object, it also > must be executed after the power resources have been set > appropriately for the device to go into power state Dn (D3 means > D3hot in this case). Thus it is not clear from the specification > whether or not the _PSn method should be executed if the initial > configuraion of power resources used by the device indicates power > state Dn and the _PSC method is not present. > > The current implementation of acpi_bus_init_power() is based on the > assumption that it should not be necessary to execute _PSn in the > above situation, but experience shows that in fact that assumption > need not be satisfied. For this reason, make acpi_bus_init_power() > always execute _PSn if the initial configuration of device power > resources indicates power state Dn. > > Reported-by: Mika Westerberg <mika.westerberg@linux.intel.com> You can add also, Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com> if you like. Thanks for fixing this. -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Index: linux-pm/drivers/acpi/device_pm.c =================================================================== --- linux-pm.orig/drivers/acpi/device_pm.c +++ linux-pm/drivers/acpi/device_pm.c @@ -330,13 +330,23 @@ int acpi_bus_init_power(struct acpi_devi if (result) return result; - if (device->power.flags.power_resources) + if (state < ACPI_STATE_D3_COLD && device->power.flags.power_resources) { result = acpi_power_on_resources(device, state); + if (result) + return result; - if (!result) - device->power.state = state; + if (device->power.states[state].flags.explicit_set) { + char method[5] = { '_', 'P', 'S', '0' + state, '\0' }; + acpi_status status; - return result; + status = acpi_evaluate_object(device->handle, method, + NULL, NULL); + if (ACPI_FAILURE(status)) + return -ENODEV; + } + } + device->power.state = state; + return 0; } int acpi_bus_update_power(acpi_handle handle, int *state_p)