aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2008-01-07 18:05:21 -0500
committerLen Brown <len.brown@intel.com>2008-02-01 18:30:56 -0500
commitc95d47a868f35cd47643d116a3c680cdaa954df8 (patch)
tree36e3b820c8bb0c1c962029ce5a28c6e3251443a9 /drivers/acpi
parentc697eecebc6cfc0b393afea3c4ff1a5041526ad1 (diff)
ACPI: Separate invocations of _GTS and _BFS from _PTS and _WAK
The execution of ACPI global control methods _GTS and _BFS is currently tied to the preparation to enter a sleep state and to the leaving of the sleep state, respectively. However, these functions are called before disabling the nonboot CPUs and after enabling them, respectively (in fact, on ACPI 1.0x systems the first of them ought to be called before suspending devices), while according to the ACPI specification, _GTS is to be executed right prior to entering the system sleep state and _BFS is to be executed right after the platfor firmware has returned control to the OS on wake up. Move the execution of _GTS and _BFS to the right places. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Pavel Machek <pavel@suse.cz> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/hardware/hwsleep.c75
-rw-r--r--drivers/acpi/sleep/main.c7
2 files changed, 64 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 ******************************************************************************/
486acpi_status acpi_leave_sleep_state(u8 sleep_state) 496acpi_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 ******************************************************************************/
580acpi_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
289static void acpi_hibernation_finish(void) 296static void acpi_hibernation_finish(void)