diff options
Diffstat (limited to 'kernel/power')
-rw-r--r-- | kernel/power/main.c | 25 | ||||
-rw-r--r-- | kernel/power/power.h | 29 | ||||
-rw-r--r-- | kernel/power/process.c | 18 |
3 files changed, 69 insertions, 3 deletions
diff --git a/kernel/power/main.c b/kernel/power/main.c index e3e7cc1f7cd..1f5717866f6 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -395,6 +395,9 @@ static void suspend_finish(void) static const char * const pm_states[PM_SUSPEND_MAX] = { +#ifdef CONFIG_ANDROID_EARLYSUSPEND + [PM_SUSPEND_ON] = "on", +#endif [PM_SUSPEND_STANDBY] = "standby", [PM_SUSPEND_MEM] = "mem", }; @@ -514,7 +517,11 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t n) { #ifdef CONFIG_SUSPEND +#ifdef CONFIG_ANDROID_EARLYSUSPEND + suspend_state_t state = PM_SUSPEND_ON; +#else suspend_state_t state = PM_SUSPEND_STANDBY; +#endif const char * const *s; #endif char *p; @@ -536,8 +543,15 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, break; } if (state < PM_SUSPEND_MAX && *s) +#ifdef CONFIG_ANDROID_EARLYSUSPEND + if (state == PM_SUSPEND_ON || valid_state(state)) { + error = 0; + request_suspend_state(state); + } +#else error = enter_state(state); #endif +#endif Exit: return error ? error : n; @@ -570,6 +584,12 @@ pm_trace_store(struct kobject *kobj, struct kobj_attribute *attr, power_attr(pm_trace); #endif /* CONFIG_PM_TRACE */ +#ifdef CONFIG_ANDROID_USER_WAKELOCK +power_attr(wake_lock); +power_attr(wake_full_lock); +power_attr(wake_unlock); +#endif + static struct attribute * g[] = { &state_attr.attr, #ifdef CONFIG_PM_TRACE @@ -578,6 +598,11 @@ static struct attribute * g[] = { #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PM_DEBUG) &pm_test_attr.attr, #endif +#ifdef CONFIG_ANDROID_USER_WAKELOCK + &wake_lock_attr.attr, + &wake_unlock_attr.attr, + &wake_full_lock_attr.attr, +#endif NULL, }; diff --git a/kernel/power/power.h b/kernel/power/power.h index 46b5ec7a3af..7e377394adf 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -223,3 +223,32 @@ static inline void suspend_thaw_processes(void) { } #endif + +#ifdef CONFIG_ANDROID_WAKELOCK +/* kernel/power/wakelock.c */ +extern struct workqueue_struct *suspend_work_queue; +extern struct wake_lock main_wake_lock; +extern suspend_state_t requested_suspend_state; +#endif + +#ifdef CONFIG_ANDROID_USER_WAKELOCK +ssize_t wake_lock_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf); +ssize_t wake_lock_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n); +ssize_t wake_full_lock_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n); + +#define wake_full_lock_show wake_lock_show + +ssize_t wake_unlock_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf); +ssize_t wake_unlock_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n); +#endif + +#ifdef CONFIG_ANDROID_EARLYSUSPEND +/* kernel/power/earlysuspend.c */ +void request_suspend_state(suspend_state_t state); +suspend_state_t get_suspend_state(void); +#endif diff --git a/kernel/power/process.c b/kernel/power/process.c index ca634019497..3ca2b7c1b02 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,17 @@ 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 " + 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(); + show_state(); + } read_lock(&tasklist_lock); do_each_thread(g, p) { task_lock(p); |