From 3a957735404718a8e010737c1c0bb3025fdcfb4d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 1 Sep 2014 13:47:49 +0200 Subject: PM / sleep: Mechanism for aborting system suspends unconditionally It sometimes may be necessary to abort a system suspend in progress or wake up the system from suspend-to-idle even if the pm_wakeup_event()/pm_stay_awake() mechanism is not enabled. For this purpose, introduce a new global variable pm_abort_suspend and make pm_wakeup_pending() check its value. Also add routines for manipulating that variable. Change-Id: I694bee866a1b9e85a724f3efec09326d47a4ef6e Signed-off-by: Rafael J. Wysocki --- drivers/base/power/wakeup.c | 17 ++++++++++++++++- include/linux/suspend.h | 4 ++++ kernel/power/process.c | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 96ffdb24b..ea313db99 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -42,6 +42,10 @@ int wakeup_debug = 0; * if wakeup events are registered during or immediately before the transition. */ bool events_check_enabled __read_mostly; + +/* If set and the system is suspending, terminate the suspend. */ +static bool pm_abort_suspend __read_mostly; + EXPORT_SYMBOL_GPL(events_check_enabled); /* @@ -796,7 +800,18 @@ bool pm_wakeup_pending(void) if (ret) print_active_wakeup_sources(); - return ret; + return ret || pm_abort_suspend; +} + +void pm_system_wakeup(void) +{ + pm_abort_suspend = true; + freeze_wake(); +} + +void pm_wakeup_clear(void) +{ + pm_abort_suspend = false; } EXPORT_SYMBOL_GPL(pm_wakeup_pending); diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 62fb46e31..b198156ee 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -365,6 +365,8 @@ extern int unregister_pm_notifier(struct notifier_block *nb); extern bool events_check_enabled; extern bool pm_wakeup_pending(void); +extern void pm_system_wakeup(void); +extern void pm_wakeup_clear(void); extern bool pm_get_wakeup_count(unsigned int *count, bool block); extern bool pm_save_wakeup_count(unsigned int count); extern void pm_wakep_autosleep_enabled(bool set); @@ -411,6 +413,8 @@ static inline int unregister_pm_notifier(struct notifier_block *nb) #define pm_notifier(fn, pri) do { (void)(fn); } while (0) static inline bool pm_wakeup_pending(void) { return false; } +static inline void pm_system_wakeup(void) {} +static inline void pm_wakeup_clear(void) {} static inline void lock_system_sleep(void) {} static inline void unlock_system_sleep(void) {} diff --git a/kernel/power/process.c b/kernel/power/process.c index 1febd6b4f..8ea711f0d 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -162,6 +162,7 @@ int freeze_processes(void) if (!pm_freezing) atomic_inc(&system_freezing_cnt); + pm_wakeup_clear(); printk("Freezing user space processes ... "); pm_freezing = true; oom_kills_saved = oom_kills_count(); -- cgit v1.2.3