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: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
parent
30d3df41b3
commit
5e6d4fe429
|
@ -196,34 +196,24 @@ EXPORT_SYMBOL(acpi_bus_get_private_data);
|
||||||
Power Management
|
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;
|
int result = 0;
|
||||||
acpi_status status = 0;
|
acpi_status status = 0;
|
||||||
struct acpi_device *device = NULL;
|
|
||||||
unsigned long long psc = 0;
|
unsigned long long psc = 0;
|
||||||
|
|
||||||
|
if (!device || !state)
|
||||||
result = acpi_bus_get_device(handle, &device);
|
return -EINVAL;
|
||||||
if (result)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
*state = ACPI_STATE_UNKNOWN;
|
*state = ACPI_STATE_UNKNOWN;
|
||||||
|
|
||||||
if (!device->flags.power_manageable) {
|
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 {
|
|
||||||
/*
|
/*
|
||||||
* Get the device's power state either directly (via _PSC) or
|
* Get the device's power state either directly (via _PSC) or
|
||||||
* indirectly (via power resources).
|
* indirectly (via power resources).
|
||||||
*/
|
*/
|
||||||
if (device->power.flags.power_resources) {
|
if (device->power.flags.power_resources) {
|
||||||
result = acpi_power_get_inferred_state(device,
|
result = acpi_power_get_inferred_state(device, state);
|
||||||
&device->power.state);
|
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
} else if (device->power.flags.explicit_get) {
|
} else if (device->power.flags.explicit_get) {
|
||||||
|
@ -231,20 +221,40 @@ int acpi_bus_get_power(acpi_handle handle, int *state)
|
||||||
NULL, &psc);
|
NULL, &psc);
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
device->power.state = (int)psc;
|
*state = (int)psc;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
*state = device->power.state;
|
/* 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",
|
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;
|
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);
|
EXPORT_SYMBOL(acpi_bus_get_power);
|
||||||
|
|
||||||
|
|
||||||
int acpi_bus_set_power(acpi_handle handle, int state)
|
int acpi_bus_set_power(acpi_handle handle, int state)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
Loading…
Reference in New Issue