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.c63
1 files changed, 43 insertions, 20 deletions
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 5f2c379ab7bf..f74834a544fd 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -81,6 +81,23 @@ static int acpi_sleep_prepare(u32 acpi_state)
81#ifdef CONFIG_ACPI_SLEEP 81#ifdef CONFIG_ACPI_SLEEP
82static u32 acpi_target_sleep_state = ACPI_STATE_S0; 82static u32 acpi_target_sleep_state = ACPI_STATE_S0;
83/* 83/*
84 * According to the ACPI specification the BIOS should make sure that ACPI is
85 * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still,
86 * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
87 * on such systems during resume. Unfortunately that doesn't help in
88 * particularly pathological cases in which SCI_EN has to be set directly on
89 * resume, although the specification states very clearly that this flag is
90 * owned by the hardware. The set_sci_en_on_resume variable will be set in such
91 * cases.
92 */
93static bool set_sci_en_on_resume;
94
95void __init acpi_set_sci_en_on_resume(void)
96{
97 set_sci_en_on_resume = true;
98}
99
100/*
84 * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the 101 * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the
85 * user to request that behavior by using the 'acpi_old_suspend_ordering' 102 * user to request that behavior by using the 'acpi_old_suspend_ordering'
86 * kernel command line option that causes the following variable to be set. 103 * kernel command line option that causes the following variable to be set.
@@ -170,18 +187,6 @@ static void acpi_pm_end(void)
170#endif /* CONFIG_ACPI_SLEEP */ 187#endif /* CONFIG_ACPI_SLEEP */
171 188
172#ifdef CONFIG_SUSPEND 189#ifdef CONFIG_SUSPEND
173/*
174 * According to the ACPI specification the BIOS should make sure that ACPI is
175 * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still,
176 * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
177 * on such systems during resume. Unfortunately that doesn't help in
178 * particularly pathological cases in which SCI_EN has to be set directly on
179 * resume, although the specification states very clearly that this flag is
180 * owned by the hardware. The set_sci_en_on_resume variable will be set in such
181 * cases.
182 */
183static bool set_sci_en_on_resume;
184
185extern void do_suspend_lowlevel(void); 190extern void do_suspend_lowlevel(void);
186 191
187static u32 acpi_suspend_states[] = { 192static u32 acpi_suspend_states[] = {
@@ -547,8 +552,17 @@ static void acpi_hibernation_leave(void)
547 hibernate_nvs_restore(); 552 hibernate_nvs_restore();
548} 553}
549 554
550static void acpi_pm_enable_gpes(void) 555static int acpi_pm_pre_restore(void)
551{ 556{
557 acpi_disable_all_gpes();
558 acpi_os_wait_events_complete(NULL);
559 acpi_ec_suspend_transactions();
560 return 0;
561}
562
563static void acpi_pm_restore_cleanup(void)
564{
565 acpi_ec_resume_transactions();
552 acpi_enable_all_runtime_gpes(); 566 acpi_enable_all_runtime_gpes();
553} 567}
554 568
@@ -560,8 +574,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops = {
560 .prepare = acpi_pm_prepare, 574 .prepare = acpi_pm_prepare,
561 .enter = acpi_hibernation_enter, 575 .enter = acpi_hibernation_enter,
562 .leave = acpi_hibernation_leave, 576 .leave = acpi_hibernation_leave,
563 .pre_restore = acpi_pm_disable_gpes, 577 .pre_restore = acpi_pm_pre_restore,
564 .restore_cleanup = acpi_pm_enable_gpes, 578 .restore_cleanup = acpi_pm_restore_cleanup,
565}; 579};
566 580
567/** 581/**
@@ -613,8 +627,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = {
613 .prepare = acpi_pm_disable_gpes, 627 .prepare = acpi_pm_disable_gpes,
614 .enter = acpi_hibernation_enter, 628 .enter = acpi_hibernation_enter,
615 .leave = acpi_hibernation_leave, 629 .leave = acpi_hibernation_leave,
616 .pre_restore = acpi_pm_disable_gpes, 630 .pre_restore = acpi_pm_pre_restore,
617 .restore_cleanup = acpi_pm_enable_gpes, 631 .restore_cleanup = acpi_pm_restore_cleanup,
618 .recover = acpi_pm_finish, 632 .recover = acpi_pm_finish,
619}; 633};
620#endif /* CONFIG_HIBERNATION */ 634#endif /* CONFIG_HIBERNATION */
@@ -740,9 +754,18 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
740 return -ENODEV; 754 return -ENODEV;
741 } 755 }
742 756
743 error = enable ? 757 if (enable) {
744 acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) : 758 error = acpi_enable_wakeup_device_power(adev,
745 acpi_disable_wakeup_device_power(adev); 759 acpi_target_sleep_state);
760 if (!error)
761 acpi_enable_gpe(adev->wakeup.gpe_device,
762 adev->wakeup.gpe_number,
763 ACPI_GPE_TYPE_WAKE);
764 } else {
765 acpi_disable_gpe(adev->wakeup.gpe_device, adev->wakeup.gpe_number,
766 ACPI_GPE_TYPE_WAKE);
767 error = acpi_disable_wakeup_device_power(adev);
768 }
746 if (!error) 769 if (!error)
747 dev_info(dev, "wake-up capability %s by ACPI\n", 770 dev_info(dev, "wake-up capability %s by ACPI\n",
748 enable ? "enabled" : "disabled"); 771 enable ? "enabled" : "disabled");