summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorArve Hjønnevåg <arve@android.com>2008-10-14 16:02:39 -0700
committerArve Hjønnevåg <arve@android.com>2009-04-07 16:43:04 -0700
commit3f8e407c418205252f00615da4d0182e8c960344 (patch)
tree12bef08852e54c1f8d3e06c452863fd04efac374 /kernel
parent48e1af2bdd11204f11b3770a6c8d3eee64aee2e8 (diff)
PM: wakelock: Abort task freezing if a wake lock is held.
Avoids a problem where the device sometimes hangs for 20 seconds before the screen is turned on.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/power/process.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/kernel/power/process.c b/kernel/power/process.c
index ca634019497a..723cfbe6df63 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/syscalls.h>
#include <linux/freezer.h>
+#include <linux/wakelock.h>
/*
* Timeout for stopping processes
@@ -36,6 +37,7 @@ static int try_to_freeze_tasks(bool sig_only)
struct timeval start, end;
u64 elapsed_csecs64;
unsigned int elapsed_csecs;
+ unsigned int wakeup = 0;
do_gettimeofday(&start);
@@ -62,6 +64,10 @@ static int try_to_freeze_tasks(bool sig_only)
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
yield(); /* Yield is okay here */
+ if (todo && has_wake_lock(WAKE_LOCK_SUSPEND)) {
+ wakeup = 1;
+ break;
+ }
if (time_after(jiffies, end_time))
break;
} while (todo);
@@ -77,11 +83,18 @@ static int try_to_freeze_tasks(bool sig_only)
* and caller must call thaw_processes() if something fails),
* but it cleans up leftover PF_FREEZE requests.
*/
- printk("\n");
- printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
- "(%d tasks refusing to freeze):\n",
- elapsed_csecs / 100, elapsed_csecs % 100, todo);
- show_state();
+ if(wakeup) {
+ printk("\n");
+ printk(KERN_ERR "Freezing of %s aborted\n",
+ sig_only ? "user space " : "tasks ");
+ }
+ else {
+ printk("\n");
+ printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
+ "(%d tasks refusing to freeze):\n",
+ elapsed_csecs / 100, elapsed_csecs % 100, todo);
+ show_state();
+ }
read_lock(&tasklist_lock);
do_each_thread(g, p) {
task_lock(p);