ACPI: PM: s2idle: Always set up EC GPE for system wakeup
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 21 Aug 2019 09:40:19 +0000 (11:40 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 21 Aug 2019 21:56:05 +0000 (23:56 +0200)
Commit 10a08fd65ec1 ("ACPI: PM: Set up EC GPE for system wakeup from
drivers that need it") assumed that the EC GPE would only need to be
set up for system wakeup if either the intel-hid or the intel-vbtn
driver was in use, but that turns out to be incorrect.  In particular,
on ASUS Zenbook UX430UNR/i7-8550U, if the EC GPE is not enabled while
suspended, the system cannot be woken up by opening the lid or
pressing a key, and that machine doesn't use any of the drivers
mentioned above.

For this reason, always set up the EC GPE for system wakeup from
suspend-to-idle by setting and clearing its wake mask in the ACPI
suspend-to-idle callbacks.

Fixes: 10a08fd65ec1 ("ACPI: PM: Set up EC GPE for system wakeup from drivers that need it")
Reported-by: Kristian Klausen <kristian@klausen.dk>
Tested-by: Kristian Klausen <kristian@klausen.dk>
Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/ec.c
drivers/acpi/sleep.c
drivers/platform/x86/intel-hid.c
drivers/platform/x86/intel-vbtn.c

index 58597ec813eb6580531dbf68bc3b8d82614301c2..da1e5c5ce15065dbddac0e6c0b6abe1bde43fe2d 100644 (file)
@@ -1970,7 +1970,6 @@ void acpi_ec_set_gpe_wake_mask(u8 action)
        if (pm_suspend_no_platform() && first_ec && !ec_no_wakeup)
                acpi_set_gpe_wake_mask(NULL, first_ec->gpe, action);
 }
-EXPORT_SYMBOL_GPL(acpi_ec_set_gpe_wake_mask);
 
 bool acpi_ec_dispatch_gpe(void)
 {
index c52ecbda863f68f4f4cd6f6c8a4696094f8d561a..9fa77d72ef27f52369a23f9ed99788705661bc3a 100644 (file)
@@ -938,6 +938,13 @@ static int lps0_device_attach(struct acpi_device *adev,
        if (mem_sleep_default > PM_SUSPEND_MEM && !acpi_sleep_default_s3)
                mem_sleep_current = PM_SUSPEND_TO_IDLE;
 
+       /*
+        * Some LPS0 systems, like ASUS Zenbook UX430UNR/i7-8550U, require the
+        * EC GPE to be enabled while suspended for certain wakeup devices to
+        * work, so mark it as wakeup-capable.
+        */
+       acpi_ec_mark_gpe_for_wake();
+
        return 0;
 }
 
@@ -954,8 +961,10 @@ static int acpi_s2idle_begin(void)
 
 static int acpi_s2idle_prepare(void)
 {
-       if (acpi_sci_irq_valid())
+       if (acpi_sci_irq_valid()) {
                enable_irq_wake(acpi_sci_irq);
+               acpi_ec_set_gpe_wake_mask(ACPI_GPE_ENABLE);
+       }
 
        acpi_enable_wakeup_devices(ACPI_STATE_S0);
 
@@ -1034,8 +1043,10 @@ static void acpi_s2idle_restore(void)
 
        acpi_disable_wakeup_devices(ACPI_STATE_S0);
 
-       if (acpi_sci_irq_valid())
+       if (acpi_sci_irq_valid()) {
+               acpi_ec_set_gpe_wake_mask(ACPI_GPE_DISABLE);
                disable_irq_wake(acpi_sci_irq);
+       }
 }
 
 static void acpi_s2idle_end(void)
index 18ac237114ff31396318fd340b4eb46dcdbf9877..ef6d4bd77b1a10dcf42728a654a58a5e1534374e 100644 (file)
@@ -257,7 +257,6 @@ static int intel_hid_pm_prepare(struct device *device)
                struct intel_hid_priv *priv = dev_get_drvdata(device);
 
                priv->wakeup_mode = true;
-               acpi_ec_set_gpe_wake_mask(ACPI_GPE_ENABLE);
        }
        return 0;
 }
@@ -266,10 +265,7 @@ static void intel_hid_pm_complete(struct device *device)
 {
        struct intel_hid_priv *priv = dev_get_drvdata(device);
 
-       if (priv->wakeup_mode) {
-               acpi_ec_set_gpe_wake_mask(ACPI_GPE_DISABLE);
-               priv->wakeup_mode = false;
-       }
+       priv->wakeup_mode = false;
 }
 
 static int intel_hid_pl_suspend_handler(struct device *device)
index b28e5519337edfb063a78ac201c952859ae42c87..b74932307d69b292effdce8283aad646f251e2f8 100644 (file)
@@ -205,7 +205,6 @@ static int intel_vbtn_pm_prepare(struct device *dev)
                struct intel_vbtn_priv *priv = dev_get_drvdata(dev);
 
                priv->wakeup_mode = true;
-               acpi_ec_set_gpe_wake_mask(ACPI_GPE_ENABLE);
        }
        return 0;
 }
@@ -214,10 +213,7 @@ static void intel_vbtn_pm_complete(struct device *dev)
 {
        struct intel_vbtn_priv *priv = dev_get_drvdata(dev);
 
-       if (priv->wakeup_mode) {
-               acpi_ec_set_gpe_wake_mask(ACPI_GPE_DISABLE);
-               priv->wakeup_mode = false;
-       }
+       priv->wakeup_mode = false;
 }
 
 static int intel_vbtn_pm_resume(struct device *dev)