aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/ec.c10
-rw-r--r--drivers/acpi/internal.h1
-rw-r--r--drivers/acpi/sleep.c55
3 files changed, 40 insertions, 26 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index f2234db85da0..2c2b73a2a7c2 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -485,6 +485,16 @@ void acpi_ec_resume_transactions(void)
485 mutex_unlock(&ec->lock); 485 mutex_unlock(&ec->lock);
486} 486}
487 487
488void acpi_ec_resume_transactions_early(void)
489{
490 /*
491 * Allow transactions to happen again (this function is called from
492 * atomic context during wakeup, so we don't need to acquire the mutex).
493 */
494 if (first_ec)
495 clear_bit(EC_FLAGS_FROZEN, &first_ec->flags);
496}
497
488static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data) 498static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data)
489{ 499{
490 int result; 500 int result;
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index e28411367239..0ec48c7efa9b 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -51,6 +51,7 @@ int acpi_ec_ecdt_probe(void);
51int acpi_boot_ec_enable(void); 51int acpi_boot_ec_enable(void);
52void acpi_ec_suspend_transactions(void); 52void acpi_ec_suspend_transactions(void);
53void acpi_ec_resume_transactions(void); 53void acpi_ec_resume_transactions(void);
54void acpi_ec_resume_transactions_early(void);
54 55
55/*-------------------------------------------------------------------------- 56/*--------------------------------------------------------------------------
56 Suspend/Resume 57 Suspend/Resume
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index baa76bbf244a..24741ac65897 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -110,11 +110,13 @@ void __init acpi_old_suspend_ordering(void)
110} 110}
111 111
112/** 112/**
113 * acpi_pm_disable_gpes - Disable the GPEs. 113 * acpi_pm_freeze - Disable the GPEs and suspend EC transactions.
114 */ 114 */
115static int acpi_pm_disable_gpes(void) 115static int acpi_pm_freeze(void)
116{ 116{
117 acpi_disable_all_gpes(); 117 acpi_disable_all_gpes();
118 acpi_os_wait_events_complete(NULL);
119 acpi_ec_suspend_transactions();
118 return 0; 120 return 0;
119} 121}
120 122
@@ -142,7 +144,8 @@ static int acpi_pm_prepare(void)
142 int error = __acpi_pm_prepare(); 144 int error = __acpi_pm_prepare();
143 145
144 if (!error) 146 if (!error)
145 acpi_disable_all_gpes(); 147 acpi_pm_freeze();
148
146 return error; 149 return error;
147} 150}
148 151
@@ -275,6 +278,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
275 * acpi_leave_sleep_state will reenable specific GPEs later 278 * acpi_leave_sleep_state will reenable specific GPEs later
276 */ 279 */
277 acpi_disable_all_gpes(); 280 acpi_disable_all_gpes();
281 /* Allow EC transactions to happen. */
282 acpi_ec_resume_transactions_early();
278 283
279 local_irq_restore(flags); 284 local_irq_restore(flags);
280 printk(KERN_DEBUG "Back to C!\n"); 285 printk(KERN_DEBUG "Back to C!\n");
@@ -286,6 +291,12 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
286 return ACPI_SUCCESS(status) ? 0 : -EFAULT; 291 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
287} 292}
288 293
294static void acpi_suspend_finish(void)
295{
296 acpi_ec_resume_transactions();
297 acpi_pm_finish();
298}
299
289static int acpi_suspend_state_valid(suspend_state_t pm_state) 300static int acpi_suspend_state_valid(suspend_state_t pm_state)
290{ 301{
291 u32 acpi_state; 302 u32 acpi_state;
@@ -307,7 +318,7 @@ static struct platform_suspend_ops acpi_suspend_ops = {
307 .begin = acpi_suspend_begin, 318 .begin = acpi_suspend_begin,
308 .prepare_late = acpi_pm_prepare, 319 .prepare_late = acpi_pm_prepare,
309 .enter = acpi_suspend_enter, 320 .enter = acpi_suspend_enter,
310 .wake = acpi_pm_finish, 321 .wake = acpi_suspend_finish,
311 .end = acpi_pm_end, 322 .end = acpi_pm_end,
312}; 323};
313 324
@@ -333,9 +344,9 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state)
333static struct platform_suspend_ops acpi_suspend_ops_old = { 344static struct platform_suspend_ops acpi_suspend_ops_old = {
334 .valid = acpi_suspend_state_valid, 345 .valid = acpi_suspend_state_valid,
335 .begin = acpi_suspend_begin_old, 346 .begin = acpi_suspend_begin_old,
336 .prepare_late = acpi_pm_disable_gpes, 347 .prepare_late = acpi_pm_freeze,
337 .enter = acpi_suspend_enter, 348 .enter = acpi_suspend_enter,
338 .wake = acpi_pm_finish, 349 .wake = acpi_suspend_finish,
339 .end = acpi_pm_end, 350 .end = acpi_pm_end,
340 .recover = acpi_pm_finish, 351 .recover = acpi_pm_finish,
341}; 352};
@@ -586,6 +597,7 @@ static int acpi_hibernation_enter(void)
586static void acpi_hibernation_finish(void) 597static void acpi_hibernation_finish(void)
587{ 598{
588 hibernate_nvs_free(); 599 hibernate_nvs_free();
600 acpi_ec_resume_transactions();
589 acpi_pm_finish(); 601 acpi_pm_finish();
590} 602}
591 603
@@ -606,17 +618,11 @@ static void acpi_hibernation_leave(void)
606 } 618 }
607 /* Restore the NVS memory area */ 619 /* Restore the NVS memory area */
608 hibernate_nvs_restore(); 620 hibernate_nvs_restore();
621 /* Allow EC transactions to happen. */
622 acpi_ec_resume_transactions_early();
609} 623}
610 624
611static int acpi_pm_pre_restore(void) 625static void acpi_pm_thaw(void)
612{
613 acpi_disable_all_gpes();
614 acpi_os_wait_events_complete(NULL);
615 acpi_ec_suspend_transactions();
616 return 0;
617}
618
619static void acpi_pm_restore_cleanup(void)
620{ 626{
621 acpi_ec_resume_transactions(); 627 acpi_ec_resume_transactions();
622 acpi_enable_all_runtime_gpes(); 628 acpi_enable_all_runtime_gpes();
@@ -630,8 +636,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops = {
630 .prepare = acpi_pm_prepare, 636 .prepare = acpi_pm_prepare,
631 .enter = acpi_hibernation_enter, 637 .enter = acpi_hibernation_enter,
632 .leave = acpi_hibernation_leave, 638 .leave = acpi_hibernation_leave,
633 .pre_restore = acpi_pm_pre_restore, 639 .pre_restore = acpi_pm_freeze,
634 .restore_cleanup = acpi_pm_restore_cleanup, 640 .restore_cleanup = acpi_pm_thaw,
635}; 641};
636 642
637/** 643/**
@@ -663,12 +669,9 @@ static int acpi_hibernation_begin_old(void)
663 669
664static int acpi_hibernation_pre_snapshot_old(void) 670static int acpi_hibernation_pre_snapshot_old(void)
665{ 671{
666 int error = acpi_pm_disable_gpes(); 672 acpi_pm_freeze();
667 673 hibernate_nvs_save();
668 if (!error) 674 return 0;
669 hibernate_nvs_save();
670
671 return error;
672} 675}
673 676
674/* 677/*
@@ -680,11 +683,11 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = {
680 .end = acpi_pm_end, 683 .end = acpi_pm_end,
681 .pre_snapshot = acpi_hibernation_pre_snapshot_old, 684 .pre_snapshot = acpi_hibernation_pre_snapshot_old,
682 .finish = acpi_hibernation_finish, 685 .finish = acpi_hibernation_finish,
683 .prepare = acpi_pm_disable_gpes, 686 .prepare = acpi_pm_freeze,
684 .enter = acpi_hibernation_enter, 687 .enter = acpi_hibernation_enter,
685 .leave = acpi_hibernation_leave, 688 .leave = acpi_hibernation_leave,
686 .pre_restore = acpi_pm_pre_restore, 689 .pre_restore = acpi_pm_freeze,
687 .restore_cleanup = acpi_pm_restore_cleanup, 690 .restore_cleanup = acpi_pm_thaw,
688 .recover = acpi_pm_finish, 691 .recover = acpi_pm_finish,
689}; 692};
690#endif /* CONFIG_HIBERNATION */ 693#endif /* CONFIG_HIBERNATION */