diff options
Diffstat (limited to 'drivers/acpi/acpica/hwsleep.c')
-rw-r--r-- | drivers/acpi/acpica/hwsleep.c | 130 |
1 files changed, 62 insertions, 68 deletions
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index a2af2a4f2f26..baa5fc05e124 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 | ||
91 | ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) | 91 | ACPI_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 | ******************************************************************************/ |
106 | acpi_status | 108 | acpi_status |
@@ -124,6 +126,7 @@ acpi_set_firmware_waking_vector64(u64 physical_address) | |||
124 | } | 126 | } |
125 | 127 | ||
126 | ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64) | 128 | ACPI_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 | ******************************************************************************/ |
224 | acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | 226 | acpi_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); |