]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
ACPI: EC: Dispatch the EC GPE directly on s2idle wake
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 16 May 2018 12:13:21 +0000 (14:13 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 25 May 2018 08:32:13 +0000 (10:32 +0200)
On platforms where the Low Power S0 Idle _DSM interface is used,
on wakeup from suspend-to-idle, when it is known that the ACPI SCI
has triggered while suspended, dispatch the EC GPE in order to catch
all EC events that may have triggered the wakeup before carrying out
the noirq phase of device resume.

That is needed to handle power button wakeup on some platforms where
the EC goes into a low-power mode during suspend-to-idle and while in
that mode it will discard events after a timeout.  If that timeout is
shorter than the time it takes to complete the noirq resume of
devices, looking for EC events after the latter is too late.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reported-by: Zhang Rui <rui.zhang@intel.com>
Tested-by: Wendy Wang <wendy.wang@intel.com>
drivers/acpi/ec.c
drivers/acpi/internal.h
drivers/acpi/sleep.c

index 30a5729565575f83cb02700ac2050f35abab5e5d..bb94cf0731feb92b89b78cec274668fe204ed1e4 100644 (file)
@@ -1034,6 +1034,12 @@ void acpi_ec_unblock_transactions(void)
                acpi_ec_start(first_ec, true);
 }
 
+void acpi_ec_dispatch_gpe(void)
+{
+       if (first_ec)
+               acpi_dispatch_gpe(NULL, first_ec->gpe);
+}
+
 /* --------------------------------------------------------------------------
                                 Event Management
    -------------------------------------------------------------------------- */
index 1d0a501bc7f0cbbf309c3268b951606206cc43ea..530a3f67549049c1600ccb2ac9af26a683a7099a 100644 (file)
@@ -188,6 +188,7 @@ int acpi_ec_ecdt_probe(void);
 int acpi_ec_dsdt_probe(void);
 void acpi_ec_block_transactions(void);
 void acpi_ec_unblock_transactions(void);
+void acpi_ec_dispatch_gpe(void);
 int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
                              acpi_handle handle, acpi_ec_query_func func,
                              void *data);
index 974e58457697fce086248a4af23aed15fc608c4e..5d0486f1cfcd5ef0918bffc1fe09dccae162c96a 100644 (file)
@@ -989,6 +989,13 @@ static void acpi_s2idle_wake(void)
            !irqd_is_wakeup_armed(irq_get_irq_data(acpi_sci_irq))) {
                pm_system_cancel_wakeup();
                s2idle_wakeup = true;
+               /*
+                * On some platforms with the LPS0 _DSM device noirq resume
+                * takes too much time for EC wakeup events to survive, so look
+                * for them now.
+                */
+               if (lps0_device_handle)
+                       acpi_ec_dispatch_gpe();
        }
 }