summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2020-02-11 12:11:02 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-02-19 21:52:56 +0300
commit0671627a5faa339e0c85608d99f365f4a940c073 (patch)
tree401c3c5b7b452b4722041cf04adbea9ff91698a5 /include
parentb9f78af90d9248d58e88aab553d48ee9c4a838b7 (diff)
downloadlinux-0671627a5faa339e0c85608d99f365f4a940c073.tar.xz
ACPI: PM: s2idle: Avoid possible race related to the EC GPE
commit e3728b50cd9be7d4b1469447cdf1feb93e3b7adb upstream. It is theoretically possible for the ACPI EC GPE to be set after the s2idle_ops->wake() called from s2idle_loop() has returned and before the subsequent pm_wakeup_pending() check is carried out. If that happens, the resulting wakeup event will cause the system to resume even though it may be a spurious one. To avoid that race, first make the ->wake() callback in struct platform_s2idle_ops return a bool value indicating whether or not to let the system resume and rearrange s2idle_loop() to use that value instad of the direct pm_wakeup_pending() call if ->wake() is present. Next, rework acpi_s2idle_wake() to process EC events and check pm_wakeup_pending() before re-arming the SCI for system wakeup to prevent it from triggering prematurely and add comments to that function to explain the rationale for the new code flow. Fixes: 56b991849009 ("PM: sleep: Simplify suspend-to-idle control flow") 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>
Diffstat (limited to 'include')
-rw-r--r--include/linux/suspend.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 6fc8843f1c9e..cd97d2c8840c 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -191,7 +191,7 @@ struct platform_s2idle_ops {
int (*begin)(void);
int (*prepare)(void);
int (*prepare_late)(void);
- void (*wake)(void);
+ bool (*wake)(void);
void (*restore_early)(void);
void (*restore)(void);
void (*end)(void);