diff options
Diffstat (limited to 'drivers/acpi')
| -rw-r--r-- | drivers/acpi/bus.c | 51 | ||||
| -rw-r--r-- | drivers/acpi/power.c | 2 |
2 files changed, 30 insertions, 23 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index a41be56c1cc0..adceafda9c17 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
| @@ -202,37 +202,44 @@ static const char *state_string(int state) | |||
| 202 | 202 | ||
| 203 | static int __acpi_bus_get_power(struct acpi_device *device, int *state) | 203 | static int __acpi_bus_get_power(struct acpi_device *device, int *state) |
| 204 | { | 204 | { |
| 205 | int result = 0; | 205 | int result = ACPI_STATE_UNKNOWN; |
| 206 | acpi_status status = 0; | ||
| 207 | unsigned long long psc = 0; | ||
| 208 | 206 | ||
| 209 | if (!device || !state) | 207 | if (!device || !state) |
| 210 | return -EINVAL; | 208 | return -EINVAL; |
| 211 | 209 | ||
| 212 | *state = ACPI_STATE_UNKNOWN; | 210 | if (!device->flags.power_manageable) { |
| 213 | |||
| 214 | if (device->flags.power_manageable) { | ||
| 215 | /* | ||
| 216 | * Get the device's power state either directly (via _PSC) or | ||
| 217 | * indirectly (via power resources). | ||
| 218 | */ | ||
| 219 | if (device->power.flags.power_resources) { | ||
| 220 | result = acpi_power_get_inferred_state(device, state); | ||
| 221 | if (result) | ||
| 222 | return result; | ||
| 223 | } else if (device->power.flags.explicit_get) { | ||
| 224 | status = acpi_evaluate_integer(device->handle, "_PSC", | ||
| 225 | NULL, &psc); | ||
| 226 | if (ACPI_FAILURE(status)) | ||
| 227 | return -ENODEV; | ||
| 228 | *state = (int)psc; | ||
| 229 | } | ||
| 230 | } else { | ||
| 231 | /* TBD: Non-recursive algorithm for walking up hierarchy. */ | 211 | /* TBD: Non-recursive algorithm for walking up hierarchy. */ |
| 232 | *state = device->parent ? | 212 | *state = device->parent ? |
| 233 | device->parent->power.state : ACPI_STATE_D0; | 213 | device->parent->power.state : ACPI_STATE_D0; |
| 214 | goto out; | ||
| 215 | } | ||
| 216 | |||
| 217 | /* | ||
| 218 | * Get the device's power state either directly (via _PSC) or | ||
| 219 | * indirectly (via power resources). | ||
| 220 | */ | ||
| 221 | if (device->power.flags.explicit_get) { | ||
| 222 | unsigned long long psc; | ||
| 223 | acpi_status status = acpi_evaluate_integer(device->handle, | ||
| 224 | "_PSC", NULL, &psc); | ||
| 225 | if (ACPI_FAILURE(status)) | ||
| 226 | return -ENODEV; | ||
| 227 | |||
| 228 | result = psc; | ||
| 229 | } | ||
| 230 | /* The test below covers ACPI_STATE_UNKNOWN too. */ | ||
| 231 | if (result <= ACPI_STATE_D2) { | ||
| 232 | ; /* Do nothing. */ | ||
| 233 | } else if (device->power.flags.power_resources) { | ||
| 234 | int error = acpi_power_get_inferred_state(device, &result); | ||
| 235 | if (error) | ||
| 236 | return error; | ||
| 237 | } else if (result == ACPI_STATE_D3_HOT) { | ||
| 238 | result = ACPI_STATE_D3; | ||
| 234 | } | 239 | } |
| 240 | *state = result; | ||
| 235 | 241 | ||
| 242 | out: | ||
| 236 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is %s\n", | 243 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is %s\n", |
| 237 | device->pnp.bus_id, state_string(*state))); | 244 | device->pnp.bus_id, state_string(*state))); |
| 238 | 245 | ||
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 0500f719f63e..dd6d6a3c6780 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
| @@ -631,7 +631,7 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state) | |||
| 631 | * We know a device's inferred power state when all the resources | 631 | * We know a device's inferred power state when all the resources |
| 632 | * required for a given D-state are 'on'. | 632 | * required for a given D-state are 'on'. |
| 633 | */ | 633 | */ |
| 634 | for (i = ACPI_STATE_D0; i < ACPI_STATE_D3_HOT; i++) { | 634 | for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) { |
| 635 | list = &device->power.states[i].resources; | 635 | list = &device->power.states[i].resources; |
| 636 | if (list->count < 1) | 636 | if (list->count < 1) |
| 637 | continue; | 637 | continue; |
