Commit 5e6d4fe4 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Len Brown

ACPI / PM: Introduce __acpi_bus_get_power()

It sometimes is necessary to get the power state of an ACPI device
without updating its device->power.state field, for example to
avoid inconsistencies between device->power.state and the reference
counters of the device's power resources.  For this purpose introduce
__acpi_bus_get_power() that will return the given device's power
state via a pointer (instead of modifying device->power.state)
and make acpi_bus_get_power() use it.
Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 30d3df41
......@@ -196,34 +196,24 @@ EXPORT_SYMBOL(acpi_bus_get_private_data);
Power Management
-------------------------------------------------------------------------- */
int acpi_bus_get_power(acpi_handle handle, int *state)
static int __acpi_bus_get_power(struct acpi_device *device, int *state)
{
int result = 0;
acpi_status status = 0;
struct acpi_device *device = NULL;
unsigned long long psc = 0;
result = acpi_bus_get_device(handle, &device);
if (result)
return result;
if (!device || !state)
return -EINVAL;
*state = ACPI_STATE_UNKNOWN;
if (!device->flags.power_manageable) {
/* TBD: Non-recursive algorithm for walking up hierarchy */
if (device->parent)
*state = device->parent->power.state;
else
*state = ACPI_STATE_D0;
} else {
if (device->flags.power_manageable) {
/*
* Get the device's power state either directly (via _PSC) or
* indirectly (via power resources).
*/
if (device->power.flags.power_resources) {
result = acpi_power_get_inferred_state(device,
&device->power.state);
result = acpi_power_get_inferred_state(device, state);
if (result)
return result;
} else if (device->power.flags.explicit_get) {
......@@ -231,20 +221,40 @@ int acpi_bus_get_power(acpi_handle handle, int *state)
NULL, &psc);
if (ACPI_FAILURE(status))
return -ENODEV;
device->power.state = (int)psc;
*state = (int)psc;
}
*state = device->power.state;
} else {
/* TBD: Non-recursive algorithm for walking up hierarchy. */
*state = device->parent ?
device->parent->power.state : ACPI_STATE_D0;
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n",
device->pnp.bus_id, device->power.state));
device->pnp.bus_id, *state));
return 0;
}
int acpi_bus_get_power(acpi_handle handle, int *state)
{
struct acpi_device *device;
int result;
result = acpi_bus_get_device(handle, &device);
if (result)
return result;
result = __acpi_bus_get_power(device, state);
if (result)
return result;
device->power.state = *state;
return 0;
}
EXPORT_SYMBOL(acpi_bus_get_power);
int acpi_bus_set_power(acpi_handle handle, int state)
{
int result = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment