|
@@ -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;
|