aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/power/main.c25
-rw-r--r--kernel/power/power.h29
-rw-r--r--kernel/power/process.c18
-rw-r--r--kernel/printk.c24
4 files changed, 93 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);
diff --git a/kernel/printk.c b/kernel/printk.c
index 227edece457..9d02873686c 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -82,7 +82,9 @@ EXPORT_SYMBOL(printk_emergency_debug_spew_send_string);
* driver system.
*/
static DECLARE_MUTEX(console_sem);
+#ifdef CONFIG_ANDROID_CONSOLE_EARLYSUSPEND
static DECLARE_MUTEX(secondary_console_sem);
+#endif
struct console *console_drivers;
EXPORT_SYMBOL_GPL(console_drivers);
@@ -931,12 +933,18 @@ void suspend_console(void)
printk("Suspending console(s) (use no_console_suspend to debug)\n");
acquire_console_sem();
console_suspended = 1;
+#ifdef CONFIG_ANDROID_CONSOLE_EARLYSUSPEND
+ up(&console_sem);
+#endif
}
void resume_console(void)
{
if (!console_suspend_enabled)
return;
+#ifdef CONFIG_ANDROID_CONSOLE_EARLYSUSPEND
+ down(&console_sem);
+#endif
console_suspended = 0;
release_console_sem();
}
@@ -952,11 +960,17 @@ void resume_console(void)
void acquire_console_sem(void)
{
BUG_ON(in_interrupt());
+#ifndef CONFIG_ANDROID_CONSOLE_EARLYSUSPEND
if (console_suspended) {
down(&secondary_console_sem);
return;
}
+#endif
down(&console_sem);
+#ifdef CONFIG_ANDROID_CONSOLE_EARLYSUSPEND
+ if (console_suspended)
+ return;
+#endif
console_locked = 1;
console_may_schedule = 1;
}
@@ -966,6 +980,12 @@ int try_acquire_console_sem(void)
{
if (down_trylock(&console_sem))
return -1;
+#ifdef CONFIG_ANDROID_CONSOLE_EARLYSUSPEND
+ if (console_suspended) {
+ up(&console_sem);
+ return -1;
+ }
+#endif
console_locked = 1;
console_may_schedule = 0;
return 0;
@@ -1019,7 +1039,11 @@ void release_console_sem(void)
unsigned wake_klogd = 0;
if (console_suspended) {
+#ifdef CONFIG_ANDROID_CONSOLE_EARLYSUSPEND
+ up(&console_sem);
+#else
up(&secondary_console_sem);
+#endif
return;
}