aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/hwsleep.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/hwsleep.c')
-rw-r--r--drivers/acpi/acpica/hwsleep.c130
1 files changed, 62 insertions, 68 deletions
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c
index a2af2a4f2f2..baa5fc05e12 100644
--- a/drivers/acpi/acpica/hwsleep.c
+++ b/drivers/acpi/acpica/hwsleep.c
@@ -90,6 +90,7 @@ acpi_set_firmware_waking_vector(u32 physical_address)
90 90
91ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) 91ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
92 92
93#if ACPI_MACHINE_WIDTH == 64
93/******************************************************************************* 94/*******************************************************************************
94 * 95 *
95 * FUNCTION: acpi_set_firmware_waking_vector64 96 * FUNCTION: acpi_set_firmware_waking_vector64
@@ -100,7 +101,8 @@ ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
100 * RETURN: Status 101 * RETURN: Status
101 * 102 *
102 * DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if 103 * DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if
103 * it exists in the table. 104 * it exists in the table. This function is intended for use with
105 * 64-bit host operating systems.
104 * 106 *
105 ******************************************************************************/ 107 ******************************************************************************/
106acpi_status 108acpi_status
@@ -124,6 +126,7 @@ acpi_set_firmware_waking_vector64(u64 physical_address)
124} 126}
125 127
126ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64) 128ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64)
129#endif
127 130
128/******************************************************************************* 131/*******************************************************************************
129 * 132 *
@@ -147,9 +150,8 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
147 150
148 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep); 151 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep);
149 152
150 /* 153 /* _PSW methods could be run here to enable wake-on keyboard, LAN, etc. */
151 * _PSW methods could be run here to enable wake-on keyboard, LAN, etc. 154
152 */
153 status = acpi_get_sleep_type_data(sleep_state, 155 status = acpi_get_sleep_type_data(sleep_state,
154 &acpi_gbl_sleep_type_a, 156 &acpi_gbl_sleep_type_a,
155 &acpi_gbl_sleep_type_b); 157 &acpi_gbl_sleep_type_b);
@@ -223,8 +225,8 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
223 ******************************************************************************/ 225 ******************************************************************************/
224acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) 226acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
225{ 227{
226 u32 PM1Acontrol; 228 u32 pm1a_control;
227 u32 PM1Bcontrol; 229 u32 pm1b_control;
228 struct acpi_bit_register_info *sleep_type_reg_info; 230 struct acpi_bit_register_info *sleep_type_reg_info;
229 struct acpi_bit_register_info *sleep_enable_reg_info; 231 struct acpi_bit_register_info *sleep_enable_reg_info;
230 u32 in_value; 232 u32 in_value;
@@ -242,13 +244,14 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
242 } 244 }
243 245
244 sleep_type_reg_info = 246 sleep_type_reg_info =
245 acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A); 247 acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
246 sleep_enable_reg_info = 248 sleep_enable_reg_info =
247 acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE); 249 acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
248 250
249 /* Clear wake status */ 251 /* Clear wake status */
250 252
251 status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1); 253 status =
254 acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
252 if (ACPI_FAILURE(status)) { 255 if (ACPI_FAILURE(status)) {
253 return_ACPI_STATUS(status); 256 return_ACPI_STATUS(status);
254 } 257 }
@@ -289,24 +292,25 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
289 292
290 /* Get current value of PM1A control */ 293 /* Get current value of PM1A control */
291 294
292 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); 295 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
296 &pm1a_control);
293 if (ACPI_FAILURE(status)) { 297 if (ACPI_FAILURE(status)) {
294 return_ACPI_STATUS(status); 298 return_ACPI_STATUS(status);
295 } 299 }
296 ACPI_DEBUG_PRINT((ACPI_DB_INIT, 300 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
297 "Entering sleep state [S%d]\n", sleep_state)); 301 "Entering sleep state [S%d]\n", sleep_state));
298 302
299 /* Clear SLP_EN and SLP_TYP fields */ 303 /* Clear the SLP_EN and SLP_TYP fields */
300 304
301 PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | 305 pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
302 sleep_enable_reg_info->access_bit_mask); 306 sleep_enable_reg_info->access_bit_mask);
303 PM1Bcontrol = PM1Acontrol; 307 pm1b_control = pm1a_control;
304 308
305 /* Insert SLP_TYP bits */ 309 /* Insert the SLP_TYP bits */
306 310
307 PM1Acontrol |= 311 pm1a_control |=
308 (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position); 312 (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position);
309 PM1Bcontrol |= 313 pm1b_control |=
310 (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position); 314 (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position);
311 315
312 /* 316 /*
@@ -314,37 +318,25 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
314 * poorly implemented hardware. 318 * poorly implemented hardware.
315 */ 319 */
316 320
317 /* Write #1: fill in SLP_TYP data */ 321 /* Write #1: write the SLP_TYP data to the PM1 Control registers */
318 322
319 status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL, 323 status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
320 PM1Acontrol);
321 if (ACPI_FAILURE(status)) { 324 if (ACPI_FAILURE(status)) {
322 return_ACPI_STATUS(status); 325 return_ACPI_STATUS(status);
323 } 326 }
324 327
325 status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL, 328 /* Insert the sleep enable (SLP_EN) bit */
326 PM1Bcontrol);
327 if (ACPI_FAILURE(status)) {
328 return_ACPI_STATUS(status);
329 }
330 329
331 /* Insert SLP_ENABLE bit */ 330 pm1a_control |= sleep_enable_reg_info->access_bit_mask;
331 pm1b_control |= sleep_enable_reg_info->access_bit_mask;
332 332
333 PM1Acontrol |= sleep_enable_reg_info->access_bit_mask; 333 /* Flush caches, as per ACPI specification */
334 PM1Bcontrol |= sleep_enable_reg_info->access_bit_mask;
335
336 /* Write #2: SLP_TYP + SLP_EN */
337 334
338 ACPI_FLUSH_CPU_CACHE(); 335 ACPI_FLUSH_CPU_CACHE();
339 336
340 status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL, 337 /* Write #2: Write both SLP_TYP + SLP_EN */
341 PM1Acontrol);
342 if (ACPI_FAILURE(status)) {
343 return_ACPI_STATUS(status);
344 }
345 338
346 status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL, 339 status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
347 PM1Bcontrol);
348 if (ACPI_FAILURE(status)) { 340 if (ACPI_FAILURE(status)) {
349 return_ACPI_STATUS(status); 341 return_ACPI_STATUS(status);
350 } 342 }
@@ -357,8 +349,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
357 * Wait ten seconds, then try again. This is to get S4/S5 to work on 349 * Wait ten seconds, then try again. This is to get S4/S5 to work on
358 * all machines. 350 * all machines.
359 * 351 *
360 * We wait so long to allow chipsets that poll this reg very slowly to 352 * We wait so long to allow chipsets that poll this reg very slowly
361 * still read the right value. Ideally, this block would go 353 * to still read the right value. Ideally, this block would go
362 * away entirely. 354 * away entirely.
363 */ 355 */
364 acpi_os_stall(10000000); 356 acpi_os_stall(10000000);
@@ -374,7 +366,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
374 /* Wait until we enter sleep state */ 366 /* Wait until we enter sleep state */
375 367
376 do { 368 do {
377 status = acpi_get_register_unlocked(ACPI_BITREG_WAKE_STATUS, 369 status = acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS,
378 &in_value); 370 &in_value);
379 if (ACPI_FAILURE(status)) { 371 if (ACPI_FAILURE(status)) {
380 return_ACPI_STATUS(status); 372 return_ACPI_STATUS(status);
@@ -408,7 +400,10 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
408 400
409 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios); 401 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios);
410 402
411 status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1); 403 /* Clear the wake status bit (PM1) */
404
405 status =
406 acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
412 if (ACPI_FAILURE(status)) { 407 if (ACPI_FAILURE(status)) {
413 return_ACPI_STATUS(status); 408 return_ACPI_STATUS(status);
414 } 409 }
@@ -435,12 +430,13 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
435 430
436 ACPI_FLUSH_CPU_CACHE(); 431 ACPI_FLUSH_CPU_CACHE();
437 432
438 status = acpi_os_write_port(acpi_gbl_FADT.smi_command, 433 status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
439 (u32) acpi_gbl_FADT.S4bios_request, 8); 434 (u32) acpi_gbl_FADT.S4bios_request, 8);
440 435
441 do { 436 do {
442 acpi_os_stall(1000); 437 acpi_os_stall(1000);
443 status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value); 438 status =
439 acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value);
444 if (ACPI_FAILURE(status)) { 440 if (ACPI_FAILURE(status)) {
445 return_ACPI_STATUS(status); 441 return_ACPI_STATUS(status);
446 } 442 }
@@ -471,8 +467,8 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
471 acpi_status status; 467 acpi_status status;
472 struct acpi_bit_register_info *sleep_type_reg_info; 468 struct acpi_bit_register_info *sleep_type_reg_info;
473 struct acpi_bit_register_info *sleep_enable_reg_info; 469 struct acpi_bit_register_info *sleep_enable_reg_info;
474 u32 PM1Acontrol; 470 u32 pm1a_control;
475 u32 PM1Bcontrol; 471 u32 pm1b_control;
476 472
477 ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep); 473 ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
478 474
@@ -486,38 +482,34 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
486 &acpi_gbl_sleep_type_b); 482 &acpi_gbl_sleep_type_b);
487 if (ACPI_SUCCESS(status)) { 483 if (ACPI_SUCCESS(status)) {
488 sleep_type_reg_info = 484 sleep_type_reg_info =
489 acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A); 485 acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
490 sleep_enable_reg_info = 486 sleep_enable_reg_info =
491 acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE); 487 acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
492 488
493 /* Get current value of PM1A control */ 489 /* Get current value of PM1A control */
494 490
495 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, 491 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
496 &PM1Acontrol); 492 &pm1a_control);
497 if (ACPI_SUCCESS(status)) { 493 if (ACPI_SUCCESS(status)) {
498 494
499 /* Clear SLP_EN and SLP_TYP fields */ 495 /* Clear the SLP_EN and SLP_TYP fields */
500 496
501 PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | 497 pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
502 sleep_enable_reg_info-> 498 sleep_enable_reg_info->
503 access_bit_mask); 499 access_bit_mask);
504 PM1Bcontrol = PM1Acontrol; 500 pm1b_control = pm1a_control;
505 501
506 /* Insert SLP_TYP bits */ 502 /* Insert the SLP_TYP bits */
507 503
508 PM1Acontrol |= 504 pm1a_control |= (acpi_gbl_sleep_type_a <<
509 (acpi_gbl_sleep_type_a << sleep_type_reg_info-> 505 sleep_type_reg_info->bit_position);
510 bit_position); 506 pm1b_control |= (acpi_gbl_sleep_type_b <<
511 PM1Bcontrol |= 507 sleep_type_reg_info->bit_position);
512 (acpi_gbl_sleep_type_b << sleep_type_reg_info->
513 bit_position);
514 508
515 /* Just ignore any errors */ 509 /* Write the control registers and ignore any errors */
516 510
517 (void)acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL, 511 (void)acpi_hw_write_pm1_control(pm1a_control,
518 PM1Acontrol); 512 pm1b_control);
519 (void)acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
520 PM1Bcontrol);
521 } 513 }
522 } 514 }
523 515
@@ -603,19 +595,21 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
603 * it to determine whether the system is rebooting or resuming. Clear 595 * it to determine whether the system is rebooting or resuming. Clear
604 * it for compatibility. 596 * it for compatibility.
605 */ 597 */
606 acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1); 598 acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, 1);
607 599
608 acpi_gbl_system_awake_and_running = TRUE; 600 acpi_gbl_system_awake_and_running = TRUE;
609 601
610 /* Enable power button */ 602 /* Enable power button */
611 603
612 (void) 604 (void)
613 acpi_set_register(acpi_gbl_fixed_event_info 605 acpi_write_bit_register(acpi_gbl_fixed_event_info
614 [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1); 606 [ACPI_EVENT_POWER_BUTTON].
607 enable_register_id, ACPI_ENABLE_EVENT);
615 608
616 (void) 609 (void)
617 acpi_set_register(acpi_gbl_fixed_event_info 610 acpi_write_bit_register(acpi_gbl_fixed_event_info
618 [ACPI_EVENT_POWER_BUTTON].status_register_id, 1); 611 [ACPI_EVENT_POWER_BUTTON].
612 status_register_id, ACPI_CLEAR_STATUS);
619 613
620 arg.integer.value = ACPI_SST_WORKING; 614 arg.integer.value = ACPI_SST_WORKING;
621 status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); 615 status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);