ACPI: PM: s2idle: Refine active GPEs check
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 25 Mar 2020 10:55:48 +0000 (11:55 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 17 Apr 2020 08:50:09 +0000 (10:50 +0200)
commit d5406284ff803a578ca503373624312770319054 upstream.

The check for any active GPEs added by commit fdde0ff8590b ("ACPI:
PM: s2idle: Prevent spurious SCIs from waking up the system") turns
out to be insufficiently precise to prevent some systems from
resuming prematurely due to a spurious EC wakeup, so refine it
by first checking if any GPEs other than the EC GPE are active
and skipping all of the SCIs coming from the EC that do not produce
any genuine wakeup events after processing.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=206629
Fixes: fdde0ff8590b ("ACPI: PM: s2idle: Prevent spurious SCIs from waking up the system")
Reported-by: Ondřej Caletka <ondrej@caletka.cz>
Tested-by: Ondřej Caletka <ondrej@caletka.cz>
Cc: 5.4+ <stable@vger.kernel.org> # 5.4+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/acpi/ec.c
drivers/acpi/internal.h
drivers/acpi/sleep.c

index 2dba4e7a83b76e02caca2ca02628f74e41bba32d..ed2ecb00004f270631c9ab1d1e599ba43f0ad13d 100644 (file)
@@ -1964,6 +1964,11 @@ void acpi_ec_set_gpe_wake_mask(u8 action)
                acpi_set_gpe_wake_mask(NULL, first_ec->gpe, action);
 }
 
+bool acpi_ec_other_gpes_active(void)
+{
+       return acpi_any_gpe_status_set(first_ec ? first_ec->gpe : U32_MAX);
+}
+
 bool acpi_ec_dispatch_gpe(void)
 {
        u32 ret;
index afe6636f9ad39d33333c2aae9e3e0467b70f9b64..cbf7f34c3ce76e89ecc29b088a53b949ead5d5d0 100644 (file)
@@ -201,6 +201,7 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);
 
 #ifdef CONFIG_PM_SLEEP
 void acpi_ec_flush_work(void);
+bool acpi_ec_other_gpes_active(void);
 bool acpi_ec_dispatch_gpe(void);
 #endif
 
index da9953609323262be4ee5e57a837bccfdcc68cc8..ce1d9048a36d98f903ee498cd8c3728d0fa1966f 100644 (file)
@@ -1014,18 +1014,19 @@ static bool acpi_s2idle_wake(void)
                        return true;
 
                /*
-                * If there are no EC events to process and at least one of the
-                * other enabled GPEs is active, the wakeup is regarded as a
-                * genuine one.
-                *
-                * Note that the checks below must be carried out in this order
-                * to avoid returning prematurely due to a change of the EC GPE
-                * status bit from unset to set between the checks with the
-                * status bits of all the other GPEs unset.
+                * If the status bit is set for any enabled GPE other than the
+                * EC one, the wakeup is regarded as a genuine one.
                 */
-               if (acpi_any_gpe_status_set(U32_MAX) && !acpi_ec_dispatch_gpe())
+               if (acpi_ec_other_gpes_active())
                        return true;
 
+               /*
+                * If the EC GPE status bit has not been set, the wakeup is
+                * regarded as a spurious one.
+                */
+               if (!acpi_ec_dispatch_gpe())
+                       return false;
+
                /*
                 * Cancel the wakeup and process all pending events in case
                 * there are any wakeup ones in there.