diff options
Diffstat (limited to 'drivers/acpi/sleep.c')
-rw-r--r-- | drivers/acpi/sleep.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index a4782c75ebdd..555de11a56b6 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -650,6 +650,8 @@ static const struct platform_suspend_ops acpi_suspend_ops_old = { | |||
650 | .recover = acpi_pm_finish, | 650 | .recover = acpi_pm_finish, |
651 | }; | 651 | }; |
652 | 652 | ||
653 | static bool s2idle_wakeup; | ||
654 | |||
653 | static int acpi_freeze_begin(void) | 655 | static int acpi_freeze_begin(void) |
654 | { | 656 | { |
655 | acpi_scan_lock_acquire(); | 657 | acpi_scan_lock_acquire(); |
@@ -666,6 +668,33 @@ static int acpi_freeze_prepare(void) | |||
666 | return 0; | 668 | return 0; |
667 | } | 669 | } |
668 | 670 | ||
671 | static void acpi_freeze_wake(void) | ||
672 | { | ||
673 | /* | ||
674 | * If IRQD_WAKEUP_ARMED is not set for the SCI at this point, it means | ||
675 | * that the SCI has triggered while suspended, so cancel the wakeup in | ||
676 | * case it has not been a wakeup event (the GPEs will be checked later). | ||
677 | */ | ||
678 | if (acpi_sci_irq_valid() && | ||
679 | !irqd_is_wakeup_armed(irq_get_irq_data(acpi_sci_irq))) { | ||
680 | pm_system_cancel_wakeup(); | ||
681 | s2idle_wakeup = true; | ||
682 | } | ||
683 | } | ||
684 | |||
685 | static void acpi_freeze_sync(void) | ||
686 | { | ||
687 | /* | ||
688 | * Process all pending events in case there are any wakeup ones. | ||
689 | * | ||
690 | * The EC driver uses the system workqueue, so that one needs to be | ||
691 | * flushed too. | ||
692 | */ | ||
693 | acpi_os_wait_events_complete(); | ||
694 | flush_scheduled_work(); | ||
695 | s2idle_wakeup = false; | ||
696 | } | ||
697 | |||
669 | static void acpi_freeze_restore(void) | 698 | static void acpi_freeze_restore(void) |
670 | { | 699 | { |
671 | if (acpi_sci_irq_valid()) | 700 | if (acpi_sci_irq_valid()) |
@@ -682,6 +711,8 @@ static void acpi_freeze_end(void) | |||
682 | static const struct platform_freeze_ops acpi_freeze_ops = { | 711 | static const struct platform_freeze_ops acpi_freeze_ops = { |
683 | .begin = acpi_freeze_begin, | 712 | .begin = acpi_freeze_begin, |
684 | .prepare = acpi_freeze_prepare, | 713 | .prepare = acpi_freeze_prepare, |
714 | .wake = acpi_freeze_wake, | ||
715 | .sync = acpi_freeze_sync, | ||
685 | .restore = acpi_freeze_restore, | 716 | .restore = acpi_freeze_restore, |
686 | .end = acpi_freeze_end, | 717 | .end = acpi_freeze_end, |
687 | }; | 718 | }; |
@@ -700,9 +731,15 @@ static void acpi_sleep_suspend_setup(void) | |||
700 | } | 731 | } |
701 | 732 | ||
702 | #else /* !CONFIG_SUSPEND */ | 733 | #else /* !CONFIG_SUSPEND */ |
734 | #define s2idle_wakeup (false) | ||
703 | static inline void acpi_sleep_suspend_setup(void) {} | 735 | static inline void acpi_sleep_suspend_setup(void) {} |
704 | #endif /* !CONFIG_SUSPEND */ | 736 | #endif /* !CONFIG_SUSPEND */ |
705 | 737 | ||
738 | bool acpi_s2idle_wakeup(void) | ||
739 | { | ||
740 | return s2idle_wakeup; | ||
741 | } | ||
742 | |||
706 | #ifdef CONFIG_PM_SLEEP | 743 | #ifdef CONFIG_PM_SLEEP |
707 | static u32 saved_bm_rld; | 744 | static u32 saved_bm_rld; |
708 | 745 | ||