From 9b14142be776019ef0c0f88ddf2e14b7721bae3d Mon Sep 17 00:00:00 2001 From: jinqian Date: Tue, 14 Apr 2015 13:47:35 -0700 Subject: [PATCH] power: increment wakeup_count when save_wakeup_count failed. user-space aborts suspend attempt if writing wakeup_count failed. Count the write failure towards wakeup_count. Signed-off-by: jinqian Change-Id: Ic0123ac7ef31564700b1f6b5f2234275ac104244 --- drivers/base/power/wakeup.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 6686e5ff6041..ebe6c7310c85 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -54,6 +54,8 @@ static LIST_HEAD(wakeup_sources); static DECLARE_WAIT_QUEUE_HEAD(wakeup_count_wait_queue); +static ktime_t last_read_time; + /** * wakeup_source_prepare - Prepare a new wakeup source for initialization. * @ws: Wakeup source to prepare. @@ -778,10 +780,15 @@ bool pm_wakeup_pending(void) bool pm_get_wakeup_count(unsigned int *count, bool block) { unsigned int cnt, inpr; + unsigned long flags; if (block) { DEFINE_WAIT(wait); + spin_lock_irqsave(&events_lock, flags); + last_read_time = ktime_get(); + spin_unlock_irqrestore(&events_lock, flags); + for (;;) { prepare_to_wait(&wakeup_count_wait_queue, &wait, TASK_INTERRUPTIBLE); @@ -813,6 +820,7 @@ bool pm_save_wakeup_count(unsigned int count) { unsigned int cnt, inpr; unsigned long flags; + struct wakeup_source *ws; events_check_enabled = false; spin_lock_irqsave(&events_lock, flags); @@ -820,6 +828,15 @@ bool pm_save_wakeup_count(unsigned int count) if (cnt == count && inpr == 0) { saved_count = count; events_check_enabled = true; + } else { + rcu_read_lock(); + list_for_each_entry_rcu(ws, &wakeup_sources, entry) { + if (ws->active || + ktime_compare(ws->last_time, last_read_time) > 0) { + ws->wakeup_count++; + } + } + rcu_read_unlock(); } spin_unlock_irqrestore(&events_lock, flags); return events_check_enabled; -- 2.34.1