diff options
-rw-r--r-- | drivers/acpi/ec.c | 10 | ||||
-rw-r--r-- | drivers/acpi/internal.h | 1 | ||||
-rw-r--r-- | drivers/acpi/sleep.c | 55 |
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 | ||
488 | void 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 | |||
488 | static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data) | 498 | static 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); | |||
51 | int acpi_boot_ec_enable(void); | 51 | int acpi_boot_ec_enable(void); |
52 | void acpi_ec_suspend_transactions(void); | 52 | void acpi_ec_suspend_transactions(void); |
53 | void acpi_ec_resume_transactions(void); | 53 | void acpi_ec_resume_transactions(void); |
54 | void 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 | */ |
115 | static int acpi_pm_disable_gpes(void) | 115 | static 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 | ||
294 | static void acpi_suspend_finish(void) | ||
295 | { | ||
296 | acpi_ec_resume_transactions(); | ||
297 | acpi_pm_finish(); | ||
298 | } | ||
299 | |||
289 | static int acpi_suspend_state_valid(suspend_state_t pm_state) | 300 | static 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) | |||
333 | static struct platform_suspend_ops acpi_suspend_ops_old = { | 344 | static 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) | |||
586 | static void acpi_hibernation_finish(void) | 597 | static 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 | ||
611 | static int acpi_pm_pre_restore(void) | 625 | static 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 | |||
619 | static 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 | ||
664 | static int acpi_hibernation_pre_snapshot_old(void) | 670 | static 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 */ |