diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/bus.c | 14 | ||||
-rw-r--r-- | drivers/acpi/power.c | 42 |
2 files changed, 44 insertions, 12 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index ccae305ee55d..91bdeb3b081e 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -223,7 +223,19 @@ int acpi_bus_set_power(acpi_handle handle, int state) | |||
223 | /* | 223 | /* |
224 | * Get device's current power state | 224 | * Get device's current power state |
225 | */ | 225 | */ |
226 | acpi_bus_get_power(device->handle, &device->power.state); | 226 | if (!acpi_power_nocheck) { |
227 | /* | ||
228 | * Maybe the incorrect power state is returned on the bogus | ||
229 | * bios, which is different with the real power state. | ||
230 | * For example: the bios returns D0 state and the real power | ||
231 | * state is D3. OS expects to set the device to D0 state. In | ||
232 | * such case if OS uses the power state returned by the BIOS, | ||
233 | * the device can't be transisted to the correct power state. | ||
234 | * So if the acpi_power_nocheck is set, it is unnecessary to | ||
235 | * get the power state by calling acpi_bus_get_power. | ||
236 | */ | ||
237 | acpi_bus_get_power(device->handle, &device->power.state); | ||
238 | } | ||
227 | if ((state == device->power.state) && !device->flags.force_power_state) { | 239 | if ((state == device->power.state) && !device->flags.force_power_state) { |
228 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", | 240 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", |
229 | state)); | 241 | state)); |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index e7bab75075a9..7ff7349c0c52 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -54,6 +54,14 @@ ACPI_MODULE_NAME("power"); | |||
54 | #define ACPI_POWER_RESOURCE_STATE_OFF 0x00 | 54 | #define ACPI_POWER_RESOURCE_STATE_OFF 0x00 |
55 | #define ACPI_POWER_RESOURCE_STATE_ON 0x01 | 55 | #define ACPI_POWER_RESOURCE_STATE_ON 0x01 |
56 | #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF | 56 | #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF |
57 | |||
58 | #ifdef MODULE_PARAM_PREFIX | ||
59 | #undef MODULE_PARAM_PREFIX | ||
60 | #endif | ||
61 | #define MODULE_PARAM_PREFIX "acpi." | ||
62 | int acpi_power_nocheck; | ||
63 | module_param_named(power_nocheck, acpi_power_nocheck, bool, 000); | ||
64 | |||
57 | static int acpi_power_add(struct acpi_device *device); | 65 | static int acpi_power_add(struct acpi_device *device); |
58 | static int acpi_power_remove(struct acpi_device *device, int type); | 66 | static int acpi_power_remove(struct acpi_device *device, int type); |
59 | static int acpi_power_resume(struct acpi_device *device); | 67 | static int acpi_power_resume(struct acpi_device *device); |
@@ -228,12 +236,18 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) | |||
228 | if (ACPI_FAILURE(status)) | 236 | if (ACPI_FAILURE(status)) |
229 | return -ENODEV; | 237 | return -ENODEV; |
230 | 238 | ||
231 | result = acpi_power_get_state(resource->device->handle, &state); | 239 | if (!acpi_power_nocheck) { |
232 | if (result) | 240 | /* |
233 | return result; | 241 | * If acpi_power_nocheck is set, it is unnecessary to check |
234 | if (state != ACPI_POWER_RESOURCE_STATE_ON) | 242 | * the power state after power transition. |
235 | return -ENOEXEC; | 243 | */ |
236 | 244 | result = acpi_power_get_state(resource->device->handle, | |
245 | &state); | ||
246 | if (result) | ||
247 | return result; | ||
248 | if (state != ACPI_POWER_RESOURCE_STATE_ON) | ||
249 | return -ENOEXEC; | ||
250 | } | ||
237 | /* Update the power resource's _device_ power state */ | 251 | /* Update the power resource's _device_ power state */ |
238 | resource->device->power.state = ACPI_STATE_D0; | 252 | resource->device->power.state = ACPI_STATE_D0; |
239 | 253 | ||
@@ -279,11 +293,17 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) | |||
279 | if (ACPI_FAILURE(status)) | 293 | if (ACPI_FAILURE(status)) |
280 | return -ENODEV; | 294 | return -ENODEV; |
281 | 295 | ||
282 | result = acpi_power_get_state(handle, &state); | 296 | if (!acpi_power_nocheck) { |
283 | if (result) | 297 | /* |
284 | return result; | 298 | * If acpi_power_nocheck is set, it is unnecessary to check |
285 | if (state != ACPI_POWER_RESOURCE_STATE_OFF) | 299 | * the power state after power transition. |
286 | return -ENOEXEC; | 300 | */ |
301 | result = acpi_power_get_state(handle, &state); | ||
302 | if (result) | ||
303 | return result; | ||
304 | if (state != ACPI_POWER_RESOURCE_STATE_OFF) | ||
305 | return -ENOEXEC; | ||
306 | } | ||
287 | 307 | ||
288 | /* Update the power resource's _device_ power state */ | 308 | /* Update the power resource's _device_ power state */ |
289 | resource->device->power.state = ACPI_STATE_D3; | 309 | resource->device->power.state = ACPI_STATE_D3; |