mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 22:14:04 +02:00
PM: Backoff suspend if repeated attempts fail
Change-Id: I32289676d95a307ea3aa5e78f6c126ca979c0fec Signed-off-by: Todd Poynor <toddpoynor@google.com>
This commit is contained in:
parent
64753a4df6
commit
7013f49763
|
|
@ -48,6 +48,12 @@ struct workqueue_struct *suspend_work_queue;
|
|||
struct wake_lock main_wake_lock;
|
||||
suspend_state_t requested_suspend_state = PM_SUSPEND_MEM;
|
||||
static struct wake_lock unknown_wakeup;
|
||||
static struct wake_lock suspend_backoff_lock;
|
||||
|
||||
#define SUSPEND_BACKOFF_THRESHOLD 10
|
||||
#define SUSPEND_BACKOFF_INTERVAL 10000
|
||||
|
||||
static unsigned suspend_short_count;
|
||||
|
||||
#ifdef CONFIG_WAKELOCK_STAT
|
||||
static struct wake_lock deleted_wake_locks;
|
||||
|
|
@ -255,10 +261,18 @@ long has_wake_lock(int type)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void suspend_backoff(void)
|
||||
{
|
||||
pr_info("suspend: too many immediate wakeups, back off\n");
|
||||
wake_lock_timeout(&suspend_backoff_lock,
|
||||
msecs_to_jiffies(SUSPEND_BACKOFF_INTERVAL));
|
||||
}
|
||||
|
||||
static void suspend(struct work_struct *work)
|
||||
{
|
||||
int ret;
|
||||
int entry_event_num;
|
||||
struct timespec ts_entry, ts_exit;
|
||||
|
||||
if (has_wake_lock(WAKE_LOCK_SUSPEND)) {
|
||||
if (debug_mask & DEBUG_SUSPEND)
|
||||
|
|
@ -270,17 +284,30 @@ static void suspend(struct work_struct *work)
|
|||
sys_sync();
|
||||
if (debug_mask & DEBUG_SUSPEND)
|
||||
pr_info("suspend: enter suspend\n");
|
||||
getnstimeofday(&ts_entry);
|
||||
ret = pm_suspend(requested_suspend_state);
|
||||
getnstimeofday(&ts_exit);
|
||||
|
||||
if (debug_mask & DEBUG_EXIT_SUSPEND) {
|
||||
struct timespec ts;
|
||||
struct rtc_time tm;
|
||||
getnstimeofday(&ts);
|
||||
rtc_time_to_tm(ts.tv_sec, &tm);
|
||||
rtc_time_to_tm(ts_exit.tv_sec, &tm);
|
||||
pr_info("suspend: exit suspend, ret = %d "
|
||||
"(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n", ret,
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec, ts_exit.tv_nsec);
|
||||
}
|
||||
|
||||
if (ts_exit.tv_sec - ts_entry.tv_sec <= 1) {
|
||||
++suspend_short_count;
|
||||
|
||||
if (suspend_short_count == SUSPEND_BACKOFF_THRESHOLD) {
|
||||
suspend_backoff();
|
||||
suspend_short_count = 0;
|
||||
}
|
||||
} else {
|
||||
suspend_short_count = 0;
|
||||
}
|
||||
|
||||
if (current_event_num == entry_event_num) {
|
||||
if (debug_mask & DEBUG_SUSPEND)
|
||||
pr_info("suspend: pm_suspend returned with no event\n");
|
||||
|
|
@ -547,6 +574,8 @@ static int __init wakelocks_init(void)
|
|||
wake_lock_init(&main_wake_lock, WAKE_LOCK_SUSPEND, "main");
|
||||
wake_lock(&main_wake_lock);
|
||||
wake_lock_init(&unknown_wakeup, WAKE_LOCK_SUSPEND, "unknown_wakeups");
|
||||
wake_lock_init(&suspend_backoff_lock, WAKE_LOCK_SUSPEND,
|
||||
"suspend_backoff");
|
||||
|
||||
ret = platform_device_register(&power_device);
|
||||
if (ret) {
|
||||
|
|
@ -576,6 +605,7 @@ static int __init wakelocks_init(void)
|
|||
err_platform_driver_register:
|
||||
platform_device_unregister(&power_device);
|
||||
err_platform_device_register:
|
||||
wake_lock_destroy(&suspend_backoff_lock);
|
||||
wake_lock_destroy(&unknown_wakeup);
|
||||
wake_lock_destroy(&main_wake_lock);
|
||||
#ifdef CONFIG_WAKELOCK_STAT
|
||||
|
|
@ -592,6 +622,7 @@ static void __exit wakelocks_exit(void)
|
|||
destroy_workqueue(suspend_work_queue);
|
||||
platform_driver_unregister(&power_driver);
|
||||
platform_device_unregister(&power_device);
|
||||
wake_lock_destroy(&suspend_backoff_lock);
|
||||
wake_lock_destroy(&unknown_wakeup);
|
||||
wake_lock_destroy(&main_wake_lock);
|
||||
#ifdef CONFIG_WAKELOCK_STAT
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user