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.c85
1 files changed, 46 insertions, 39 deletions
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 4ab2275b4461..5b7c52e4a00f 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
@@ -112,6 +114,8 @@ static int __acpi_pm_prepare(void)
112{ 114{
113 int error = acpi_sleep_prepare(acpi_target_sleep_state); 115 int error = acpi_sleep_prepare(acpi_target_sleep_state);
114 116
117 suspend_nvs_save();
118
115 if (error) 119 if (error)
116 acpi_target_sleep_state = ACPI_STATE_S0; 120 acpi_target_sleep_state = ACPI_STATE_S0;
117 return error; 121 return error;
@@ -126,7 +130,8 @@ static int acpi_pm_prepare(void)
126 int error = __acpi_pm_prepare(); 130 int error = __acpi_pm_prepare();
127 131
128 if (!error) 132 if (!error)
129 acpi_disable_all_gpes(); 133 acpi_pm_freeze();
134
130 return error; 135 return error;
131} 136}
132 137
@@ -140,6 +145,9 @@ static void acpi_pm_finish(void)
140{ 145{
141 u32 acpi_state = acpi_target_sleep_state; 146 u32 acpi_state = acpi_target_sleep_state;
142 147
148 suspend_nvs_free();
149 acpi_ec_unblock_transactions();
150
143 if (acpi_state == ACPI_STATE_S0) 151 if (acpi_state == ACPI_STATE_S0)
144 return; 152 return;
145 153
@@ -189,6 +197,11 @@ static int acpi_suspend_begin(suspend_state_t pm_state)
189 u32 acpi_state = acpi_suspend_states[pm_state]; 197 u32 acpi_state = acpi_suspend_states[pm_state];
190 int error = 0; 198 int error = 0;
191 199
200 error = suspend_nvs_alloc();
201
202 if (error)
203 return error;
204
192 if (sleep_states[acpi_state]) { 205 if (sleep_states[acpi_state]) {
193 acpi_target_sleep_state = acpi_state; 206 acpi_target_sleep_state = acpi_state;
194 acpi_sleep_tts_switch(acpi_target_sleep_state); 207 acpi_sleep_tts_switch(acpi_target_sleep_state);
@@ -256,6 +269,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
256 * acpi_leave_sleep_state will reenable specific GPEs later 269 * acpi_leave_sleep_state will reenable specific GPEs later
257 */ 270 */
258 acpi_disable_all_gpes(); 271 acpi_disable_all_gpes();
272 /* Allow EC transactions to happen. */
273 acpi_ec_unblock_transactions_early();
259 274
260 local_irq_restore(flags); 275 local_irq_restore(flags);
261 printk(KERN_DEBUG "Back to C!\n"); 276 printk(KERN_DEBUG "Back to C!\n");
@@ -264,9 +279,16 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
264 if (acpi_state == ACPI_STATE_S3) 279 if (acpi_state == ACPI_STATE_S3)
265 acpi_restore_state_mem(); 280 acpi_restore_state_mem();
266 281
282 suspend_nvs_restore();
283
267 return ACPI_SUCCESS(status) ? 0 : -EFAULT; 284 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
268} 285}
269 286
287static void acpi_suspend_finish(void)
288{
289 acpi_pm_finish();
290}
291
270static int acpi_suspend_state_valid(suspend_state_t pm_state) 292static int acpi_suspend_state_valid(suspend_state_t pm_state)
271{ 293{
272 u32 acpi_state; 294 u32 acpi_state;
@@ -288,7 +310,7 @@ static struct platform_suspend_ops acpi_suspend_ops = {
288 .begin = acpi_suspend_begin, 310 .begin = acpi_suspend_begin,
289 .prepare_late = acpi_pm_prepare, 311 .prepare_late = acpi_pm_prepare,
290 .enter = acpi_suspend_enter, 312 .enter = acpi_suspend_enter,
291 .wake = acpi_pm_finish, 313 .wake = acpi_suspend_finish,
292 .end = acpi_pm_end, 314 .end = acpi_pm_end,
293}; 315};
294 316
@@ -314,9 +336,9 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state)
314static struct platform_suspend_ops acpi_suspend_ops_old = { 336static struct platform_suspend_ops acpi_suspend_ops_old = {
315 .valid = acpi_suspend_state_valid, 337 .valid = acpi_suspend_state_valid,
316 .begin = acpi_suspend_begin_old, 338 .begin = acpi_suspend_begin_old,
317 .prepare_late = acpi_pm_disable_gpes, 339 .prepare_late = acpi_pm_freeze,
318 .enter = acpi_suspend_enter, 340 .enter = acpi_suspend_enter,
319 .wake = acpi_pm_finish, 341 .wake = acpi_suspend_finish,
320 .end = acpi_pm_end, 342 .end = acpi_pm_end,
321 .recover = acpi_pm_finish, 343 .recover = acpi_pm_finish,
322}; 344};
@@ -393,7 +415,7 @@ static int acpi_hibernation_begin(void)
393{ 415{
394 int error; 416 int error;
395 417
396 error = s4_no_nvs ? 0 : hibernate_nvs_alloc(); 418 error = s4_no_nvs ? 0 : suspend_nvs_alloc();
397 if (!error) { 419 if (!error) {
398 acpi_target_sleep_state = ACPI_STATE_S4; 420 acpi_target_sleep_state = ACPI_STATE_S4;
399 acpi_sleep_tts_switch(acpi_target_sleep_state); 421 acpi_sleep_tts_switch(acpi_target_sleep_state);
@@ -407,7 +429,7 @@ static int acpi_hibernation_pre_snapshot(void)
407 int error = acpi_pm_prepare(); 429 int error = acpi_pm_prepare();
408 430
409 if (!error) 431 if (!error)
410 hibernate_nvs_save(); 432 suspend_nvs_save();
411 433
412 return error; 434 return error;
413} 435}
@@ -430,12 +452,6 @@ static int acpi_hibernation_enter(void)
430 return ACPI_SUCCESS(status) ? 0 : -EFAULT; 452 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
431} 453}
432 454
433static void acpi_hibernation_finish(void)
434{
435 hibernate_nvs_free();
436 acpi_pm_finish();
437}
438
439static void acpi_hibernation_leave(void) 455static void acpi_hibernation_leave(void)
440{ 456{
441 /* 457 /*
@@ -452,20 +468,14 @@ static void acpi_hibernation_leave(void)
452 panic("ACPI S4 hardware signature mismatch"); 468 panic("ACPI S4 hardware signature mismatch");
453 } 469 }
454 /* Restore the NVS memory area */ 470 /* Restore the NVS memory area */
455 hibernate_nvs_restore(); 471 suspend_nvs_restore();
472 /* Allow EC transactions to happen. */
473 acpi_ec_unblock_transactions_early();
456} 474}
457 475
458static int acpi_pm_pre_restore(void) 476static void acpi_pm_thaw(void)
459{ 477{
460 acpi_disable_all_gpes(); 478 acpi_ec_unblock_transactions();
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{
468 acpi_ec_resume_transactions();
469 acpi_enable_all_runtime_gpes(); 479 acpi_enable_all_runtime_gpes();
470} 480}
471 481
@@ -473,12 +483,12 @@ static struct platform_hibernation_ops acpi_hibernation_ops = {
473 .begin = acpi_hibernation_begin, 483 .begin = acpi_hibernation_begin,
474 .end = acpi_pm_end, 484 .end = acpi_pm_end,
475 .pre_snapshot = acpi_hibernation_pre_snapshot, 485 .pre_snapshot = acpi_hibernation_pre_snapshot,
476 .finish = acpi_hibernation_finish, 486 .finish = acpi_pm_finish,
477 .prepare = acpi_pm_prepare, 487 .prepare = acpi_pm_prepare,
478 .enter = acpi_hibernation_enter, 488 .enter = acpi_hibernation_enter,
479 .leave = acpi_hibernation_leave, 489 .leave = acpi_hibernation_leave,
480 .pre_restore = acpi_pm_pre_restore, 490 .pre_restore = acpi_pm_freeze,
481 .restore_cleanup = acpi_pm_restore_cleanup, 491 .restore_cleanup = acpi_pm_thaw,
482}; 492};
483 493
484/** 494/**
@@ -501,7 +511,7 @@ static int acpi_hibernation_begin_old(void)
501 511
502 if (!error) { 512 if (!error) {
503 if (!s4_no_nvs) 513 if (!s4_no_nvs)
504 error = hibernate_nvs_alloc(); 514 error = suspend_nvs_alloc();
505 if (!error) 515 if (!error)
506 acpi_target_sleep_state = ACPI_STATE_S4; 516 acpi_target_sleep_state = ACPI_STATE_S4;
507 } 517 }
@@ -510,12 +520,9 @@ static int acpi_hibernation_begin_old(void)
510 520
511static int acpi_hibernation_pre_snapshot_old(void) 521static int acpi_hibernation_pre_snapshot_old(void)
512{ 522{
513 int error = acpi_pm_disable_gpes(); 523 acpi_pm_freeze();
514 524 suspend_nvs_save();
515 if (!error) 525 return 0;
516 hibernate_nvs_save();
517
518 return error;
519} 526}
520 527
521/* 528/*
@@ -526,12 +533,12 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = {
526 .begin = acpi_hibernation_begin_old, 533 .begin = acpi_hibernation_begin_old,
527 .end = acpi_pm_end, 534 .end = acpi_pm_end,
528 .pre_snapshot = acpi_hibernation_pre_snapshot_old, 535 .pre_snapshot = acpi_hibernation_pre_snapshot_old,
529 .finish = acpi_hibernation_finish, 536 .prepare = acpi_pm_freeze,
530 .prepare = acpi_pm_disable_gpes, 537 .finish = acpi_pm_finish,
531 .enter = acpi_hibernation_enter, 538 .enter = acpi_hibernation_enter,
532 .leave = acpi_hibernation_leave, 539 .leave = acpi_hibernation_leave,
533 .pre_restore = acpi_pm_pre_restore, 540 .pre_restore = acpi_pm_freeze,
534 .restore_cleanup = acpi_pm_restore_cleanup, 541 .restore_cleanup = acpi_pm_thaw,
535 .recover = acpi_pm_finish, 542 .recover = acpi_pm_finish,
536}; 543};
537#endif /* CONFIG_HIBERNATION */ 544#endif /* CONFIG_HIBERNATION */