diff options
Diffstat (limited to 'drivers/acpi/hardware/hwsleep.c')
-rw-r--r-- | drivers/acpi/hardware/hwsleep.c | 101 |
1 files changed, 54 insertions, 47 deletions
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c index 77b3e9a8550b..415d342aeab5 100644 --- a/drivers/acpi/hardware/hwsleep.c +++ b/drivers/acpi/hardware/hwsleep.c | |||
@@ -43,27 +43,13 @@ | |||
43 | */ | 43 | */ |
44 | 44 | ||
45 | #include <linux/module.h> | 45 | #include <linux/module.h> |
46 | |||
47 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
48 | 47 | ||
49 | #define _COMPONENT ACPI_HARDWARE | 48 | #define _COMPONENT ACPI_HARDWARE |
50 | ACPI_MODULE_NAME ("hwsleep") | 49 | ACPI_MODULE_NAME ("hwsleep") |
51 | 50 | ||
52 | 51 | ||
53 | #define METHOD_NAME__BFS "\\_BFS" | 52 | /******************************************************************************* |
54 | #define METHOD_NAME__GTS "\\_GTS" | ||
55 | #define METHOD_NAME__PTS "\\_PTS" | ||
56 | #define METHOD_NAME__SST "\\_SI._SST" | ||
57 | #define METHOD_NAME__WAK "\\_WAK" | ||
58 | |||
59 | #define ACPI_SST_INDICATOR_OFF 0 | ||
60 | #define ACPI_SST_WORKING 1 | ||
61 | #define ACPI_SST_WAKING 2 | ||
62 | #define ACPI_SST_SLEEPING 3 | ||
63 | #define ACPI_SST_SLEEP_CONTEXT 4 | ||
64 | |||
65 | |||
66 | /****************************************************************************** | ||
67 | * | 53 | * |
68 | * FUNCTION: acpi_set_firmware_waking_vector | 54 | * FUNCTION: acpi_set_firmware_waking_vector |
69 | * | 55 | * |
@@ -72,7 +58,7 @@ | |||
72 | * | 58 | * |
73 | * RETURN: Status | 59 | * RETURN: Status |
74 | * | 60 | * |
75 | * DESCRIPTION: access function for d_firmware_waking_vector field in FACS | 61 | * DESCRIPTION: Access function for the firmware_waking_vector field in FACS |
76 | * | 62 | * |
77 | ******************************************************************************/ | 63 | ******************************************************************************/ |
78 | 64 | ||
@@ -99,19 +85,20 @@ acpi_set_firmware_waking_vector ( | |||
99 | } | 85 | } |
100 | 86 | ||
101 | 87 | ||
102 | /****************************************************************************** | 88 | /******************************************************************************* |
103 | * | 89 | * |
104 | * FUNCTION: acpi_get_firmware_waking_vector | 90 | * FUNCTION: acpi_get_firmware_waking_vector |
105 | * | 91 | * |
106 | * PARAMETERS: *physical_address - Output buffer where contents of | 92 | * PARAMETERS: *physical_address - Where the contents of |
107 | * the firmware_waking_vector field of | 93 | * the firmware_waking_vector field of |
108 | * the FACS will be stored. | 94 | * the FACS will be returned. |
109 | * | 95 | * |
110 | * RETURN: Status | 96 | * RETURN: Status, vector |
111 | * | 97 | * |
112 | * DESCRIPTION: Access function for firmware_waking_vector field in FACS | 98 | * DESCRIPTION: Access function for the firmware_waking_vector field in FACS |
113 | * | 99 | * |
114 | ******************************************************************************/ | 100 | ******************************************************************************/ |
101 | |||
115 | #ifdef ACPI_FUTURE_USAGE | 102 | #ifdef ACPI_FUTURE_USAGE |
116 | acpi_status | 103 | acpi_status |
117 | acpi_get_firmware_waking_vector ( | 104 | acpi_get_firmware_waking_vector ( |
@@ -141,7 +128,7 @@ acpi_get_firmware_waking_vector ( | |||
141 | #endif | 128 | #endif |
142 | 129 | ||
143 | 130 | ||
144 | /****************************************************************************** | 131 | /******************************************************************************* |
145 | * | 132 | * |
146 | * FUNCTION: acpi_enter_sleep_state_prep | 133 | * FUNCTION: acpi_enter_sleep_state_prep |
147 | * | 134 | * |
@@ -215,7 +202,7 @@ acpi_enter_sleep_state_prep ( | |||
215 | break; | 202 | break; |
216 | 203 | ||
217 | default: | 204 | default: |
218 | arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is indicator off */ | 205 | arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is off */ |
219 | break; | 206 | break; |
220 | } | 207 | } |
221 | 208 | ||
@@ -223,14 +210,15 @@ acpi_enter_sleep_state_prep ( | |||
223 | 210 | ||
224 | status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL); | 211 | status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL); |
225 | if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { | 212 | if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { |
226 | ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status))); | 213 | ACPI_REPORT_ERROR (("Method _SST failed, %s\n", |
214 | acpi_format_exception (status))); | ||
227 | } | 215 | } |
228 | 216 | ||
229 | return_ACPI_STATUS (AE_OK); | 217 | return_ACPI_STATUS (AE_OK); |
230 | } | 218 | } |
231 | 219 | ||
232 | 220 | ||
233 | /****************************************************************************** | 221 | /******************************************************************************* |
234 | * | 222 | * |
235 | * FUNCTION: acpi_enter_sleep_state | 223 | * FUNCTION: acpi_enter_sleep_state |
236 | * | 224 | * |
@@ -299,15 +287,18 @@ acpi_enter_sleep_state ( | |||
299 | 287 | ||
300 | /* Get current value of PM1A control */ | 288 | /* Get current value of PM1A control */ |
301 | 289 | ||
302 | status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); | 290 | status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, |
291 | ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); | ||
303 | if (ACPI_FAILURE (status)) { | 292 | if (ACPI_FAILURE (status)) { |
304 | return_ACPI_STATUS (status); | 293 | return_ACPI_STATUS (status); |
305 | } | 294 | } |
306 | ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Entering sleep state [S%d]\n", sleep_state)); | 295 | ACPI_DEBUG_PRINT ((ACPI_DB_INIT, |
296 | "Entering sleep state [S%d]\n", sleep_state)); | ||
307 | 297 | ||
308 | /* Clear SLP_EN and SLP_TYP fields */ | 298 | /* Clear SLP_EN and SLP_TYP fields */ |
309 | 299 | ||
310 | PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | sleep_enable_reg_info->access_bit_mask); | 300 | PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | |
301 | sleep_enable_reg_info->access_bit_mask); | ||
311 | PM1Bcontrol = PM1Acontrol; | 302 | PM1Bcontrol = PM1Acontrol; |
312 | 303 | ||
313 | /* Insert SLP_TYP bits */ | 304 | /* Insert SLP_TYP bits */ |
@@ -322,12 +313,14 @@ acpi_enter_sleep_state ( | |||
322 | 313 | ||
323 | /* Write #1: fill in SLP_TYP data */ | 314 | /* Write #1: fill in SLP_TYP data */ |
324 | 315 | ||
325 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol); | 316 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, |
317 | ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol); | ||
326 | if (ACPI_FAILURE (status)) { | 318 | if (ACPI_FAILURE (status)) { |
327 | return_ACPI_STATUS (status); | 319 | return_ACPI_STATUS (status); |
328 | } | 320 | } |
329 | 321 | ||
330 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol); | 322 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, |
323 | ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol); | ||
331 | if (ACPI_FAILURE (status)) { | 324 | if (ACPI_FAILURE (status)) { |
332 | return_ACPI_STATUS (status); | 325 | return_ACPI_STATUS (status); |
333 | } | 326 | } |
@@ -341,22 +334,25 @@ acpi_enter_sleep_state ( | |||
341 | 334 | ||
342 | ACPI_FLUSH_CPU_CACHE (); | 335 | ACPI_FLUSH_CPU_CACHE (); |
343 | 336 | ||
344 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol); | 337 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, |
338 | ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol); | ||
345 | if (ACPI_FAILURE (status)) { | 339 | if (ACPI_FAILURE (status)) { |
346 | return_ACPI_STATUS (status); | 340 | return_ACPI_STATUS (status); |
347 | } | 341 | } |
348 | 342 | ||
349 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol); | 343 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, |
344 | ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol); | ||
350 | if (ACPI_FAILURE (status)) { | 345 | if (ACPI_FAILURE (status)) { |
351 | return_ACPI_STATUS (status); | 346 | return_ACPI_STATUS (status); |
352 | } | 347 | } |
353 | 348 | ||
354 | if (sleep_state > ACPI_STATE_S3) { | 349 | if (sleep_state > ACPI_STATE_S3) { |
355 | /* | 350 | /* |
356 | * We wanted to sleep > S3, but it didn't happen (by virtue of the fact that | 351 | * We wanted to sleep > S3, but it didn't happen (by virtue of the |
357 | * we are still executing!) | 352 | * fact that we are still executing!) |
358 | * | 353 | * |
359 | * Wait ten seconds, then try again. This is to get S4/S5 to work on all machines. | 354 | * Wait ten seconds, then try again. This is to get S4/S5 to work on |
355 | * all machines. | ||
360 | * | 356 | * |
361 | * We wait so long to allow chipsets that poll this reg very slowly to | 357 | * We wait so long to allow chipsets that poll this reg very slowly to |
362 | * still read the right value. Ideally, this block would go | 358 | * still read the right value. Ideally, this block would go |
@@ -364,7 +360,8 @@ acpi_enter_sleep_state ( | |||
364 | */ | 360 | */ |
365 | acpi_os_stall (10000000); | 361 | acpi_os_stall (10000000); |
366 | 362 | ||
367 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL, | 363 | status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, |
364 | ACPI_REGISTER_PM1_CONTROL, | ||
368 | sleep_enable_reg_info->access_bit_mask); | 365 | sleep_enable_reg_info->access_bit_mask); |
369 | if (ACPI_FAILURE (status)) { | 366 | if (ACPI_FAILURE (status)) { |
370 | return_ACPI_STATUS (status); | 367 | return_ACPI_STATUS (status); |
@@ -374,7 +371,8 @@ acpi_enter_sleep_state ( | |||
374 | /* Wait until we enter sleep state */ | 371 | /* Wait until we enter sleep state */ |
375 | 372 | ||
376 | do { | 373 | do { |
377 | status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK); | 374 | status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, |
375 | ACPI_MTX_DO_NOT_LOCK); | ||
378 | if (ACPI_FAILURE (status)) { | 376 | if (ACPI_FAILURE (status)) { |
379 | return_ACPI_STATUS (status); | 377 | return_ACPI_STATUS (status); |
380 | } | 378 | } |
@@ -388,7 +386,7 @@ acpi_enter_sleep_state ( | |||
388 | EXPORT_SYMBOL(acpi_enter_sleep_state); | 386 | EXPORT_SYMBOL(acpi_enter_sleep_state); |
389 | 387 | ||
390 | 388 | ||
391 | /****************************************************************************** | 389 | /******************************************************************************* |
392 | * | 390 | * |
393 | * FUNCTION: acpi_enter_sleep_state_s4bios | 391 | * FUNCTION: acpi_enter_sleep_state_s4bios |
394 | * | 392 | * |
@@ -439,11 +437,13 @@ acpi_enter_sleep_state_s4bios ( | |||
439 | 437 | ||
440 | ACPI_FLUSH_CPU_CACHE (); | 438 | ACPI_FLUSH_CPU_CACHE (); |
441 | 439 | ||
442 | status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, (u32) acpi_gbl_FADT->S4bios_req, 8); | 440 | status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, |
441 | (u32) acpi_gbl_FADT->S4bios_req, 8); | ||
443 | 442 | ||
444 | do { | 443 | do { |
445 | acpi_os_stall(1000); | 444 | acpi_os_stall(1000); |
446 | status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK); | 445 | status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, |
446 | ACPI_MTX_DO_NOT_LOCK); | ||
447 | if (ACPI_FAILURE (status)) { | 447 | if (ACPI_FAILURE (status)) { |
448 | return_ACPI_STATUS (status); | 448 | return_ACPI_STATUS (status); |
449 | } | 449 | } |
@@ -454,7 +454,7 @@ acpi_enter_sleep_state_s4bios ( | |||
454 | EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios); | 454 | EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios); |
455 | 455 | ||
456 | 456 | ||
457 | /****************************************************************************** | 457 | /******************************************************************************* |
458 | * | 458 | * |
459 | * FUNCTION: acpi_leave_sleep_state | 459 | * FUNCTION: acpi_leave_sleep_state |
460 | * | 460 | * |
@@ -534,18 +534,21 @@ acpi_leave_sleep_state ( | |||
534 | arg.integer.value = ACPI_SST_WAKING; | 534 | arg.integer.value = ACPI_SST_WAKING; |
535 | status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL); | 535 | status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL); |
536 | if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { | 536 | if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { |
537 | ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status))); | 537 | ACPI_REPORT_ERROR (("Method _SST failed, %s\n", |
538 | acpi_format_exception (status))); | ||
538 | } | 539 | } |
539 | 540 | ||
540 | arg.integer.value = sleep_state; | 541 | arg.integer.value = sleep_state; |
541 | status = acpi_evaluate_object (NULL, METHOD_NAME__BFS, &arg_list, NULL); | 542 | status = acpi_evaluate_object (NULL, METHOD_NAME__BFS, &arg_list, NULL); |
542 | if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { | 543 | if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { |
543 | ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", acpi_format_exception (status))); | 544 | ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", |
545 | acpi_format_exception (status))); | ||
544 | } | 546 | } |
545 | 547 | ||
546 | status = acpi_evaluate_object (NULL, METHOD_NAME__WAK, &arg_list, NULL); | 548 | status = acpi_evaluate_object (NULL, METHOD_NAME__WAK, &arg_list, NULL); |
547 | if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { | 549 | if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { |
548 | ACPI_REPORT_ERROR (("Method _WAK failed, %s\n", acpi_format_exception (status))); | 550 | ACPI_REPORT_ERROR (("Method _WAK failed, %s\n", |
551 | acpi_format_exception (status))); | ||
549 | } | 552 | } |
550 | /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */ | 553 | /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */ |
551 | 554 | ||
@@ -567,15 +570,19 @@ acpi_leave_sleep_state ( | |||
567 | 570 | ||
568 | /* Enable power button */ | 571 | /* Enable power button */ |
569 | 572 | ||
570 | (void) acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id, | 573 | (void) acpi_set_register( |
574 | acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id, | ||
571 | 1, ACPI_MTX_DO_NOT_LOCK); | 575 | 1, ACPI_MTX_DO_NOT_LOCK); |
572 | (void) acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id, | 576 | |
577 | (void) acpi_set_register( | ||
578 | acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id, | ||
573 | 1, ACPI_MTX_DO_NOT_LOCK); | 579 | 1, ACPI_MTX_DO_NOT_LOCK); |
574 | 580 | ||
575 | arg.integer.value = ACPI_SST_WORKING; | 581 | arg.integer.value = ACPI_SST_WORKING; |
576 | status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL); | 582 | status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL); |
577 | if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { | 583 | if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { |
578 | ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status))); | 584 | ACPI_REPORT_ERROR (("Method _SST failed, %s\n", |
585 | acpi_format_exception (status))); | ||
579 | } | 586 | } |
580 | 587 | ||
581 | return_ACPI_STATUS (status); | 588 | return_ACPI_STATUS (status); |