diff options
-rw-r--r-- | drivers/acpi/hardware/hwsleep.c | 75 | ||||
-rw-r--r-- | drivers/acpi/sleep/main.c | 7 | ||||
-rw-r--r-- | include/acpi/acpixf.h | 2 |
3 files changed, 66 insertions, 18 deletions
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c index 81b248429703..13c93a13785e 100644 --- a/drivers/acpi/hardware/hwsleep.c +++ b/drivers/acpi/hardware/hwsleep.c | |||
@@ -192,18 +192,13 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) | |||
192 | arg.type = ACPI_TYPE_INTEGER; | 192 | arg.type = ACPI_TYPE_INTEGER; |
193 | arg.integer.value = sleep_state; | 193 | arg.integer.value = sleep_state; |
194 | 194 | ||
195 | /* Run the _PTS and _GTS methods */ | 195 | /* Run the _PTS method */ |
196 | 196 | ||
197 | status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL); | 197 | status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL); |
198 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 198 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
199 | return_ACPI_STATUS(status); | 199 | return_ACPI_STATUS(status); |
200 | } | 200 | } |
201 | 201 | ||
202 | status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL); | ||
203 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
204 | return_ACPI_STATUS(status); | ||
205 | } | ||
206 | |||
207 | /* Setup the argument to _SST */ | 202 | /* Setup the argument to _SST */ |
208 | 203 | ||
209 | switch (sleep_state) { | 204 | switch (sleep_state) { |
@@ -262,6 +257,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
262 | struct acpi_bit_register_info *sleep_type_reg_info; | 257 | struct acpi_bit_register_info *sleep_type_reg_info; |
263 | struct acpi_bit_register_info *sleep_enable_reg_info; | 258 | struct acpi_bit_register_info *sleep_enable_reg_info; |
264 | u32 in_value; | 259 | u32 in_value; |
260 | struct acpi_object_list arg_list; | ||
261 | union acpi_object arg; | ||
265 | acpi_status status; | 262 | acpi_status status; |
266 | 263 | ||
267 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state); | 264 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state); |
@@ -307,6 +304,18 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
307 | return_ACPI_STATUS(status); | 304 | return_ACPI_STATUS(status); |
308 | } | 305 | } |
309 | 306 | ||
307 | /* Execute the _GTS method */ | ||
308 | |||
309 | arg_list.count = 1; | ||
310 | arg_list.pointer = &arg; | ||
311 | arg.type = ACPI_TYPE_INTEGER; | ||
312 | arg.integer.value = sleep_state; | ||
313 | |||
314 | status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL); | ||
315 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
316 | return_ACPI_STATUS(status); | ||
317 | } | ||
318 | |||
310 | /* Get current value of PM1A control */ | 319 | /* Get current value of PM1A control */ |
311 | 320 | ||
312 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); | 321 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); |
@@ -473,17 +482,18 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios) | |||
473 | 482 | ||
474 | /******************************************************************************* | 483 | /******************************************************************************* |
475 | * | 484 | * |
476 | * FUNCTION: acpi_leave_sleep_state | 485 | * FUNCTION: acpi_leave_sleep_state_prep |
477 | * | 486 | * |
478 | * PARAMETERS: sleep_state - Which sleep state we just exited | 487 | * PARAMETERS: sleep_state - Which sleep state we are exiting |
479 | * | 488 | * |
480 | * RETURN: Status | 489 | * RETURN: Status |
481 | * | 490 | * |
482 | * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep | 491 | * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a |
483 | * Called with interrupts ENABLED. | 492 | * sleep. |
493 | * Called with interrupts DISABLED. | ||
484 | * | 494 | * |
485 | ******************************************************************************/ | 495 | ******************************************************************************/ |
486 | acpi_status acpi_leave_sleep_state(u8 sleep_state) | 496 | acpi_status acpi_leave_sleep_state_prep(u8 sleep_state) |
487 | { | 497 | { |
488 | struct acpi_object_list arg_list; | 498 | struct acpi_object_list arg_list; |
489 | union acpi_object arg; | 499 | union acpi_object arg; |
@@ -493,7 +503,7 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) | |||
493 | u32 PM1Acontrol; | 503 | u32 PM1Acontrol; |
494 | u32 PM1Bcontrol; | 504 | u32 PM1Bcontrol; |
495 | 505 | ||
496 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); | 506 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep); |
497 | 507 | ||
498 | /* | 508 | /* |
499 | * Set SLP_TYPE and SLP_EN to state S0. | 509 | * Set SLP_TYPE and SLP_EN to state S0. |
@@ -540,6 +550,41 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) | |||
540 | } | 550 | } |
541 | } | 551 | } |
542 | 552 | ||
553 | /* Execute the _BFS method */ | ||
554 | |||
555 | arg_list.count = 1; | ||
556 | arg_list.pointer = &arg; | ||
557 | arg.type = ACPI_TYPE_INTEGER; | ||
558 | arg.integer.value = sleep_state; | ||
559 | |||
560 | status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL); | ||
561 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
562 | ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); | ||
563 | } | ||
564 | |||
565 | return_ACPI_STATUS(status); | ||
566 | } | ||
567 | |||
568 | /******************************************************************************* | ||
569 | * | ||
570 | * FUNCTION: acpi_leave_sleep_state | ||
571 | * | ||
572 | * PARAMETERS: sleep_state - Which sleep state we just exited | ||
573 | * | ||
574 | * RETURN: Status | ||
575 | * | ||
576 | * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep | ||
577 | * Called with interrupts ENABLED. | ||
578 | * | ||
579 | ******************************************************************************/ | ||
580 | acpi_status acpi_leave_sleep_state(u8 sleep_state) | ||
581 | { | ||
582 | struct acpi_object_list arg_list; | ||
583 | union acpi_object arg; | ||
584 | acpi_status status; | ||
585 | |||
586 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); | ||
587 | |||
543 | /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ | 588 | /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ |
544 | 589 | ||
545 | acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; | 590 | acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; |
@@ -558,12 +603,6 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) | |||
558 | ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); | 603 | ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); |
559 | } | 604 | } |
560 | 605 | ||
561 | arg.integer.value = sleep_state; | ||
562 | status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL); | ||
563 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
564 | ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); | ||
565 | } | ||
566 | |||
567 | /* | 606 | /* |
568 | * GPEs must be enabled before _WAK is called as GPEs | 607 | * GPEs must be enabled before _WAK is called as GPEs |
569 | * might get fired there | 608 | * might get fired there |
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index e2e4e617952b..fdd8139b3f98 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c | |||
@@ -139,6 +139,9 @@ static int acpi_pm_enter(suspend_state_t pm_state) | |||
139 | break; | 139 | break; |
140 | } | 140 | } |
141 | 141 | ||
142 | /* Reprogram control registers and execute _BFS */ | ||
143 | acpi_leave_sleep_state_prep(acpi_state); | ||
144 | |||
142 | /* ACPI 3.0 specs (P62) says that it's the responsabilty | 145 | /* ACPI 3.0 specs (P62) says that it's the responsabilty |
143 | * of the OSPM to clear the status bit [ implying that the | 146 | * of the OSPM to clear the status bit [ implying that the |
144 | * POWER_BUTTON event should not reach userspace ] | 147 | * POWER_BUTTON event should not reach userspace ] |
@@ -272,6 +275,8 @@ static int acpi_hibernation_enter(void) | |||
272 | acpi_enable_wakeup_device(ACPI_STATE_S4); | 275 | acpi_enable_wakeup_device(ACPI_STATE_S4); |
273 | /* This shouldn't return. If it returns, we have a problem */ | 276 | /* This shouldn't return. If it returns, we have a problem */ |
274 | status = acpi_enter_sleep_state(ACPI_STATE_S4); | 277 | status = acpi_enter_sleep_state(ACPI_STATE_S4); |
278 | /* Reprogram control registers and execute _BFS */ | ||
279 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); | ||
275 | local_irq_restore(flags); | 280 | local_irq_restore(flags); |
276 | 281 | ||
277 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; | 282 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; |
@@ -284,6 +289,8 @@ static void acpi_hibernation_leave(void) | |||
284 | * enable it here. | 289 | * enable it here. |
285 | */ | 290 | */ |
286 | acpi_enable(); | 291 | acpi_enable(); |
292 | /* Reprogram control registers and execute _BFS */ | ||
293 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); | ||
287 | } | 294 | } |
288 | 295 | ||
289 | static void acpi_hibernation_finish(void) | 296 | static void acpi_hibernation_finish(void) |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 9512f0456ad1..b729e64d0d4c 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -335,6 +335,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state); | |||
335 | 335 | ||
336 | acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void); | 336 | acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void); |
337 | 337 | ||
338 | acpi_status acpi_leave_sleep_state_prep(u8 sleep_state); | ||
339 | |||
338 | acpi_status acpi_leave_sleep_state(u8 sleep_state); | 340 | acpi_status acpi_leave_sleep_state(u8 sleep_state); |
339 | 341 | ||
340 | #endif /* __ACXFACE_H__ */ | 342 | #endif /* __ACXFACE_H__ */ |