aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/sleep.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/sleep.c')
-rw-r--r--drivers/acpi/sleep.c57
1 files changed, 30 insertions, 27 deletions
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 4ab2275b4461..3fb4bdea7e06 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -94,11 +94,13 @@ void __init acpi_old_suspend_ordering(void)
94} 94}
95 95
96/** 96/**
97 * acpi_pm_disable_gpes - Disable the GPEs. 97 * acpi_pm_freeze - Disable the GPEs and suspend EC transactions.
98 */ 98 */
99static int acpi_pm_disable_gpes(void) 99static int acpi_pm_freeze(void)
100{ 100{
101 acpi_disable_all_gpes(); 101 acpi_disable_all_gpes();
102 acpi_os_wait_events_complete(NULL);
103 acpi_ec_block_transactions();
102 return 0; 104 return 0;
103} 105}
104 106
@@ -126,7 +128,8 @@ static int acpi_pm_prepare(void)
126 int error = __acpi_pm_prepare(); 128 int error = __acpi_pm_prepare();
127 129
128 if (!error) 130 if (!error)
129 acpi_disable_all_gpes(); 131 acpi_pm_freeze();
132
130 return error; 133 return error;
131} 134}
132 135
@@ -256,6 +259,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
256 * acpi_leave_sleep_state will reenable specific GPEs later 259 * acpi_leave_sleep_state will reenable specific GPEs later
257 */ 260 */
258 acpi_disable_all_gpes(); 261 acpi_disable_all_gpes();
262 /* Allow EC transactions to happen. */
263 acpi_ec_unblock_transactions_early();
259 264
260 local_irq_restore(flags); 265 local_irq_restore(flags);
261 printk(KERN_DEBUG "Back to C!\n"); 266 printk(KERN_DEBUG "Back to C!\n");
@@ -267,6 +272,12 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
267 return ACPI_SUCCESS(status) ? 0 : -EFAULT; 272 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
268} 273}
269 274
275static void acpi_suspend_finish(void)
276{
277 acpi_ec_unblock_transactions();
278 acpi_pm_finish();
279}
280
270static int acpi_suspend_state_valid(suspend_state_t pm_state) 281static int acpi_suspend_state_valid(suspend_state_t pm_state)
271{ 282{
272 u32 acpi_state; 283 u32 acpi_state;
@@ -288,7 +299,7 @@ static struct platform_suspend_ops acpi_suspend_ops = {
288 .begin = acpi_suspend_begin, 299 .begin = acpi_suspend_begin,
289 .prepare_late = acpi_pm_prepare, 300 .prepare_late = acpi_pm_prepare,
290 .enter = acpi_suspend_enter, 301 .enter = acpi_suspend_enter,
291 .wake = acpi_pm_finish, 302 .wake = acpi_suspend_finish,
292 .end = acpi_pm_end, 303 .end = acpi_pm_end,
293}; 304};
294 305
@@ -314,9 +325,9 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state)
314static struct platform_suspend_ops acpi_suspend_ops_old = { 325static struct platform_suspend_ops acpi_suspend_ops_old = {
315 .valid = acpi_suspend_state_valid, 326 .valid = acpi_suspend_state_valid,
316 .begin = acpi_suspend_begin_old, 327 .begin = acpi_suspend_begin_old,
317 .prepare_late = acpi_pm_disable_gpes, 328 .prepare_late = acpi_pm_freeze,
318 .enter = acpi_suspend_enter, 329 .enter = acpi_suspend_enter,
319 .wake = acpi_pm_finish, 330 .wake = acpi_suspend_finish,
320 .end = acpi_pm_end, 331 .end = acpi_pm_end,
321 .recover = acpi_pm_finish, 332 .recover = acpi_pm_finish,
322}; 333};
@@ -433,6 +444,7 @@ static int acpi_hibernation_enter(void)
433static void acpi_hibernation_finish(void) 444static void acpi_hibernation_finish(void)
434{ 445{
435 hibernate_nvs_free(); 446 hibernate_nvs_free();
447 acpi_ec_unblock_transactions();
436 acpi_pm_finish(); 448 acpi_pm_finish();
437} 449}
438 450
@@ -453,19 +465,13 @@ static void acpi_hibernation_leave(void)
453 } 465 }
454 /* Restore the NVS memory area */ 466 /* Restore the NVS memory area */
455 hibernate_nvs_restore(); 467 hibernate_nvs_restore();
468 /* Allow EC transactions to happen. */
469 acpi_ec_unblock_transactions_early();
456} 470}
457 471
458static int acpi_pm_pre_restore(void) 472static void acpi_pm_thaw(void)
459{
460 acpi_disable_all_gpes();
461 acpi_os_wait_events_complete(NULL);
462 acpi_ec_suspend_transactions();
463 return 0;
464}
465
466static void acpi_pm_restore_cleanup(void)
467{ 473{
468 acpi_ec_resume_transactions(); 474 acpi_ec_unblock_transactions();
469 acpi_enable_all_runtime_gpes(); 475 acpi_enable_all_runtime_gpes();
470} 476}
471 477
@@ -477,8 +483,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops = {
477 .prepare = acpi_pm_prepare, 483 .prepare = acpi_pm_prepare,
478 .enter = acpi_hibernation_enter, 484 .enter = acpi_hibernation_enter,
479 .leave = acpi_hibernation_leave, 485 .leave = acpi_hibernation_leave,
480 .pre_restore = acpi_pm_pre_restore, 486 .pre_restore = acpi_pm_freeze,
481 .restore_cleanup = acpi_pm_restore_cleanup, 487 .restore_cleanup = acpi_pm_thaw,
482}; 488};
483 489
484/** 490/**
@@ -510,12 +516,9 @@ static int acpi_hibernation_begin_old(void)
510 516
511static int acpi_hibernation_pre_snapshot_old(void) 517static int acpi_hibernation_pre_snapshot_old(void)
512{ 518{
513 int error = acpi_pm_disable_gpes(); 519 acpi_pm_freeze();
514 520 hibernate_nvs_save();
515 if (!error) 521 return 0;
516 hibernate_nvs_save();
517
518 return error;
519} 522}
520 523
521/* 524/*
@@ -527,11 +530,11 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = {
527 .end = acpi_pm_end, 530 .end = acpi_pm_end,
528 .pre_snapshot = acpi_hibernation_pre_snapshot_old, 531 .pre_snapshot = acpi_hibernation_pre_snapshot_old,
529 .finish = acpi_hibernation_finish, 532 .finish = acpi_hibernation_finish,
530 .prepare = acpi_pm_disable_gpes, 533 .prepare = acpi_pm_freeze,
531 .enter = acpi_hibernation_enter, 534 .enter = acpi_hibernation_enter,
532 .leave = acpi_hibernation_leave, 535 .leave = acpi_hibernation_leave,
533 .pre_restore = acpi_pm_pre_restore, 536 .pre_restore = acpi_pm_freeze,
534 .restore_cleanup = acpi_pm_restore_cleanup, 537 .restore_cleanup = acpi_pm_thaw,
535 .recover = acpi_pm_finish, 538 .recover = acpi_pm_finish,
536}; 539};
537#endif /* CONFIG_HIBERNATION */ 540#endif /* CONFIG_HIBERNATION */