aboutsummaryrefslogtreecommitdiff
path: root/drivers/android/power.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/android/power.c')
-rw-r--r--drivers/android/power.c1336
1 files changed, 0 insertions, 1336 deletions
diff --git a/drivers/android/power.c b/drivers/android/power.c
deleted file mode 100644
index 6c773ab1cde..00000000000
--- a/drivers/android/power.c
+++ /dev/null
@@ -1,1336 +0,0 @@
-/* drivers/android/power.c
- *
- * Copyright (C) 2005-2008 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/miscdevice.h>
-//#include <linux/platform_device.h>
-#include <linux/sysdev.h>
-#include <linux/fs.h>
-#include <linux/poll.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/rtc.h>
-#include <linux/wait.h>
-#include <linux/android_power.h>
-#include <linux/suspend.h>
-#include <linux/syscalls.h> // sys_sync
-#include <linux/console.h>
-#include <linux/kbd_kern.h>
-#include <linux/vt_kern.h>
-#include <linux/freezer.h>
-#ifdef CONFIG_ANDROID_POWER_STAT
-#include <linux/proc_fs.h>
-#endif
-
-enum {
- ANDROID_POWER_DEBUG_USER_STATE = 1U << 0,
- ANDROID_POWER_DEBUG_EXIT_SUSPEND = 1U << 1,
- ANDROID_POWER_DEBUG_SUSPEND = 1U << 2,
- ANDROID_POWER_DEBUG_USER_WAKE_LOCK = 1U << 3,
- ANDROID_POWER_DEBUG_WAKE_LOCK = 1U << 4,
-};
-static int android_power_debug_mask =
- ANDROID_POWER_DEBUG_USER_STATE | ANDROID_POWER_DEBUG_EXIT_SUSPEND;
-module_param_named(debug_mask, android_power_debug_mask,
- int, S_IRUGO | S_IWUSR | S_IWGRP);
-
-#define ANDROID_POWER_TEST_EARLY_SUSPEND 0
-
-MODULE_DESCRIPTION("OMAP CSMI Driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("1.0");
-
-#define ANDROID_SUSPEND_CONSOLE (MAX_NR_CONSOLES-2)
-
-static spinlock_t g_list_lock = SPIN_LOCK_UNLOCKED;
-static DEFINE_MUTEX(g_early_suspend_lock);
-
-wait_queue_head_t g_wait_queue;
-
-static LIST_HEAD(g_inactive_locks);
-static LIST_HEAD(g_active_idle_wake_locks);
-static LIST_HEAD(g_active_partial_wake_locks);
-static LIST_HEAD(g_active_full_wake_locks);
-static LIST_HEAD(g_early_suspend_handlers);
-static enum {
- USER_AWAKE,
- USER_NOTIFICATION,
- USER_SLEEP
-} g_user_suspend_state;
-static int g_current_event_num;
-static struct workqueue_struct *g_suspend_work_queue;
-static void android_power_suspend(struct work_struct *work);
-static void android_power_wakeup_locked(int notification, ktime_t time);
-static DECLARE_WORK(g_suspend_work, android_power_suspend);
-static int g_max_user_lockouts = 16;
-
-//static const char g_free_user_lockout_name[] = "free_user";
-static struct {
- enum {
- USER_WAKE_LOCK_INACTIVE,
- USER_WAKE_LOCK_PARTIAL,
- USER_WAKE_LOCK_FULL
- } state;
- android_suspend_lock_t suspend_lock;
- char name_buffer[32];
-} *g_user_wake_locks;
-#ifdef CONFIG_ANDROID_POWER_STAT
-android_suspend_lock_t g_deleted_wake_locks;
-android_suspend_lock_t g_no_wake_locks;
-#endif
-static struct kobject *android_power_kobj;
-#ifndef CONFIG_FRAMEBUFFER_CONSOLE
-static wait_queue_head_t fb_state_wq;
-static spinlock_t fb_state_lock = SPIN_LOCK_UNLOCKED;
-int fb_state;
-#endif
-
-#if 0
-android_suspend_lock_t *android_allocate_suspend_lock(const char *debug_name)
-{
- unsigned long irqflags;
- struct android_power *e;
-
- e = kzalloc(sizeof(*e), GFP_KERNEL);
- if(e == NULL) {
- printk("android_power_allocate: kzalloc failed\n");
- return NULL;
- }
- e->name = debug_name;
- spin_lock_irqsave(&g_list_lock, irqflags);
- list_add(&e->link, &g_allocated);
- spin_unlock_irqrestore(&g_list_lock, irqflags);
- return e;
-}
-#endif
-
-static int android_init_suspend_lock_internal(
- android_suspend_lock_t *lock, int has_spin_lock)
-{
- unsigned long irqflags;
-
- if(lock->name == NULL) {
- printk(KERN_ERR "android_init_suspend_lock: error name=NULL, "
- "lock=%p\n", lock);
- dump_stack();
- return -EINVAL;
- }
-
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_WAKE_LOCK)
- printk(KERN_INFO "android_init_suspend_lock name=%s\n",
- lock->name);
-#ifdef CONFIG_ANDROID_POWER_STAT
- lock->stat.count = 0;
- lock->stat.expire_count = 0;
- lock->stat.total_time = ktime_set(0, 0);
- lock->stat.max_time = ktime_set(0, 0);
- lock->stat.last_time = ktime_set(0, 0);
-#endif
- lock->flags = 0;
-
- INIT_LIST_HEAD(&lock->link);
- if (!has_spin_lock)
- spin_lock_irqsave(&g_list_lock, irqflags);
- list_add(&lock->link, &g_inactive_locks);
- if (!has_spin_lock)
- spin_unlock_irqrestore(&g_list_lock, irqflags);
-// if(lock->flags & ANDROID_SUSPEND_LOCK_FLAG_USER_VISIBLE_MASK) {
-// sysfs_create_file(struct kobject * k, const struct attribute * a)
-// }
- return 0;
-}
-
-int android_init_suspend_lock(android_suspend_lock_t *lock)
-{
- return android_init_suspend_lock_internal(lock, 0);
-}
-
-void android_uninit_suspend_lock(android_suspend_lock_t *lock)
-{
- unsigned long irqflags;
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_WAKE_LOCK)
- printk(KERN_INFO "android_uninit_suspend_lock name=%s\n",
- lock->name);
- spin_lock_irqsave(&g_list_lock, irqflags);
-#ifdef CONFIG_ANDROID_POWER_STAT
- if(lock->stat.count) {
- if(g_deleted_wake_locks.stat.count == 0) {
- g_deleted_wake_locks.name = "deleted_wake_locks";
- android_init_suspend_lock_internal(
- &g_deleted_wake_locks, 1);
- }
- g_deleted_wake_locks.stat.count += lock->stat.count;
- g_deleted_wake_locks.stat.expire_count += lock->stat.expire_count;
- g_deleted_wake_locks.stat.total_time = ktime_add(g_deleted_wake_locks.stat.total_time, lock->stat.total_time);
- g_deleted_wake_locks.stat.max_time = ktime_add(g_deleted_wake_locks.stat.max_time, lock->stat.max_time);
- }
-#endif
- list_del(&lock->link);
- spin_unlock_irqrestore(&g_list_lock, irqflags);
-}
-
-void android_lock_idle(android_suspend_lock_t *lock)
-{
- unsigned long irqflags;
- spin_lock_irqsave(&g_list_lock, irqflags);
-#ifdef CONFIG_ANDROID_POWER_STAT
- if(!(lock->flags & ANDROID_SUSPEND_LOCK_ACTIVE)) {
- lock->flags |= ANDROID_SUSPEND_LOCK_ACTIVE;
- lock->stat.last_time = ktime_get();
- }
-#endif
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_WAKE_LOCK)
- printk(KERN_INFO "android_power: acquire idle wake lock: %s\n",
- lock->name);
- lock->expires = INT_MAX;
- lock->flags &= ~ANDROID_SUSPEND_LOCK_AUTO_EXPIRE;
- list_del(&lock->link);
- list_add(&lock->link, &g_active_idle_wake_locks);
- spin_unlock_irqrestore(&g_list_lock, irqflags);
-}
-
-void android_lock_idle_auto_expire(android_suspend_lock_t *lock, int timeout)
-{
- unsigned long irqflags;
- spin_lock_irqsave(&g_list_lock, irqflags);
-#ifdef CONFIG_ANDROID_POWER_STAT
- if(!(lock->flags & ANDROID_SUSPEND_LOCK_ACTIVE)) {
- lock->flags |= ANDROID_SUSPEND_LOCK_ACTIVE;
- lock->stat.last_time = ktime_get();
- }
-#endif
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_WAKE_LOCK)
- printk(KERN_INFO "android_power: acquire idle wake lock: %s, "
- "timeout %d.%03lu\n", lock->name, timeout / HZ,
- (timeout % HZ) * MSEC_PER_SEC / HZ);
- lock->expires = jiffies + timeout;
- lock->flags |= ANDROID_SUSPEND_LOCK_AUTO_EXPIRE;
- list_del(&lock->link);
- list_add(&lock->link, &g_active_idle_wake_locks);
- spin_unlock_irqrestore(&g_list_lock, irqflags);
-}
-
-void android_lock_suspend(android_suspend_lock_t *lock)
-{
- unsigned long irqflags;
- spin_lock_irqsave(&g_list_lock, irqflags);
-#ifdef CONFIG_ANDROID_POWER_STAT
- if(!(lock->flags & ANDROID_SUSPEND_LOCK_ACTIVE)) {
- lock->flags |= ANDROID_SUSPEND_LOCK_ACTIVE;
- lock->stat.last_time = ktime_get();
- }
-#endif
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_WAKE_LOCK)
- printk(KERN_INFO "android_power: acquire wake lock: %s\n",
- lock->name);
- lock->expires = INT_MAX;
- lock->flags &= ~ANDROID_SUSPEND_LOCK_AUTO_EXPIRE;
- list_del(&lock->link);
- list_add(&lock->link, &g_active_partial_wake_locks);
- g_current_event_num++;
- spin_unlock_irqrestore(&g_list_lock, irqflags);
-}
-
-void android_lock_suspend_auto_expire(android_suspend_lock_t *lock, int timeout)
-{
- unsigned long irqflags;
- spin_lock_irqsave(&g_list_lock, irqflags);
-#ifdef CONFIG_ANDROID_POWER_STAT
- if(!(lock->flags & ANDROID_SUSPEND_LOCK_ACTIVE)) {
- lock->flags |= ANDROID_SUSPEND_LOCK_ACTIVE;
- lock->stat.last_time = ktime_get();
- }
-#endif
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_WAKE_LOCK)
- printk(KERN_INFO "android_power: acquire wake lock: %s, "
- "timeout %d.%03lu\n", lock->name, timeout / HZ,
- (timeout % HZ) * MSEC_PER_SEC / HZ);
- lock->expires = jiffies + timeout;
- lock->flags |= ANDROID_SUSPEND_LOCK_AUTO_EXPIRE;
- list_del(&lock->link);
- list_add(&lock->link, &g_active_partial_wake_locks);
- g_current_event_num++;
- wake_up(&g_wait_queue);
- spin_unlock_irqrestore(&g_list_lock, irqflags);
-}
-
-void android_lock_partial_suspend_auto_expire(android_suspend_lock_t *lock, int timeout)
-{
- unsigned long irqflags;
- spin_lock_irqsave(&g_list_lock, irqflags);
-#ifdef CONFIG_ANDROID_POWER_STAT
- if(!(lock->flags & ANDROID_SUSPEND_LOCK_ACTIVE)) {
- lock->flags |= ANDROID_SUSPEND_LOCK_ACTIVE;
- lock->stat.last_time = ktime_get();
- }
-#endif
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_WAKE_LOCK)
- printk(KERN_INFO "android_power: acquire full wake lock: %s, "
- "timeout %d.%03lu\n", lock->name, timeout / HZ,
- (timeout % HZ) * MSEC_PER_SEC / HZ);
- lock->expires = jiffies + timeout;
- lock->flags |= ANDROID_SUSPEND_LOCK_AUTO_EXPIRE;
- list_del(&lock->link);
- list_add(&lock->link, &g_active_full_wake_locks);
- g_current_event_num++;
- wake_up(&g_wait_queue);
- android_power_wakeup_locked(1, ktime_get());
- spin_unlock_irqrestore(&g_list_lock, irqflags);
-}
-
-#ifdef CONFIG_ANDROID_POWER_STAT
-static int print_lock_stat(char *buf, android_suspend_lock_t *lock)
-{
- ktime_t active_time;
- if(lock->flags & ANDROID_SUSPEND_LOCK_ACTIVE)
- active_time = ktime_sub(ktime_get(), lock->stat.last_time);
- else
- active_time = ktime_set(0, 0);
- return sprintf(buf, "\"%s\"\t%d\t%d\t%lld\t%lld\t%lld\t%lld\n",
- lock->name,
- lock->stat.count, lock->stat.expire_count,
- ktime_to_ns(active_time),
- ktime_to_ns(lock->stat.total_time),
- ktime_to_ns(lock->stat.max_time),
- ktime_to_ns(lock->stat.last_time));
-}
-
-
-static int wakelocks_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- unsigned long irqflags;
- android_suspend_lock_t *lock;
- int len = 0;
- char *p = page;
-
- spin_lock_irqsave(&g_list_lock, irqflags);
-
- p += sprintf(p, "name\tcount\texpire_count\tactive_since\ttotal_time\tmax_time\tlast_change\n");
- list_for_each_entry(lock, &g_inactive_locks, link) {
- p += print_lock_stat(p, lock);
- }
- list_for_each_entry(lock, &g_active_partial_wake_locks, link) {
- p += print_lock_stat(p, lock);
- }
- list_for_each_entry(lock, &g_active_full_wake_locks, link) {
- p += print_lock_stat(p, lock);
- }
- spin_unlock_irqrestore(&g_list_lock, irqflags);
-
-
- *start = page + off;
-
- len = p - page;
- if (len > off)
- len -= off;
- else
- len = 0;
-
- return len < count ? len : count;
-}
-
-static void android_unlock_suspend_stat_locked(android_suspend_lock_t *lock)
-{
- if(lock->flags & ANDROID_SUSPEND_LOCK_ACTIVE) {
- ktime_t duration;
- lock->flags &= ~ANDROID_SUSPEND_LOCK_ACTIVE;
- lock->stat.count++;
- duration = ktime_sub(ktime_get(), lock->stat.last_time);
- lock->stat.total_time = ktime_add(lock->stat.total_time, duration);
- if(ktime_to_ns(duration) > ktime_to_ns(lock->stat.max_time))
- lock->stat.max_time = duration;
- lock->stat.last_time = ktime_get();
- }
-}
-#endif
-
-void android_unlock_suspend(android_suspend_lock_t *lock)
-{
- int had_full_wake_locks;
- unsigned long irqflags;
- spin_lock_irqsave(&g_list_lock, irqflags);
-#ifdef CONFIG_ANDROID_POWER_STAT
- android_unlock_suspend_stat_locked(lock);
-#endif
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_WAKE_LOCK)
- printk(KERN_INFO "android_power: release wake lock: %s\n",
- lock->name);
- lock->flags &= ~ANDROID_SUSPEND_LOCK_AUTO_EXPIRE;
- had_full_wake_locks = !list_empty(&g_active_full_wake_locks);
- list_del(&lock->link);
- list_add(&lock->link, &g_inactive_locks);
- wake_up(&g_wait_queue);
- if(had_full_wake_locks && list_empty(&g_active_full_wake_locks)) {
- printk("android_unlock_suspend: released at %lld\n", ktime_to_ns(ktime_get()));
- if(g_user_suspend_state == USER_NOTIFICATION) {
- printk("android sleep state %d->%d at %lld\n", g_user_suspend_state, USER_SLEEP, ktime_to_ns(ktime_get()));
- g_user_suspend_state = USER_SLEEP;
- queue_work(g_suspend_work_queue, &g_suspend_work);
- }
- }
- spin_unlock_irqrestore(&g_list_lock, irqflags);
-}
-
-static void android_power_wakeup_locked(int notification, ktime_t time)
-{
- int new_state = (notification == 0) ? USER_AWAKE : USER_NOTIFICATION;
-
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_USER_STATE) {
- struct timespec ts;
- struct rtc_time tm;
- getnstimeofday(&ts);
- rtc_time_to_tm(ts.tv_sec, &tm);
- printk(KERN_INFO "android_power: wakeup (%d->%d) at %lld "
- "(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n",
- g_user_suspend_state, new_state, ktime_to_ns(time),
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);
- }
-
- if(new_state >= g_user_suspend_state) {
- return;
- }
- g_user_suspend_state = new_state;
- g_current_event_num++;
- wake_up(&g_wait_queue);
-}
-
-static void android_power_wakeup(void)
-{
- unsigned long irqflags;
-
- ktime_t ktime_now;
-
- spin_lock_irqsave(&g_list_lock, irqflags);
- ktime_now = ktime_get();
- android_power_wakeup_locked(0, ktime_now);
- spin_unlock_irqrestore(&g_list_lock, irqflags);
-}
-
-static void android_power_request_sleep(void)
-{
- unsigned long irqflags;
- int already_suspended;
- android_suspend_lock_t *lock, *next_lock;
-
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_USER_STATE) {
- ktime_t ktime_now;
- struct timespec ts;
- struct rtc_time tm;
- ktime_now = ktime_get();
- getnstimeofday(&ts);
- rtc_time_to_tm(ts.tv_sec, &tm);
- printk(KERN_INFO "android_power: sleep (%d->%d) at %lld "
- "(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n",
- g_user_suspend_state, USER_SLEEP, ktime_to_ns(ktime_now),
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);
- }
-
- spin_lock_irqsave(&g_list_lock, irqflags);
- already_suspended = g_user_suspend_state == USER_SLEEP;
- if(!already_suspended) {
- g_user_suspend_state = USER_SLEEP;
- }
-
- list_for_each_entry_safe(lock, next_lock, &g_active_full_wake_locks, link) {
-#ifdef CONFIG_ANDROID_POWER_STAT
- android_unlock_suspend_stat_locked(lock);
-#endif
- list_del(&lock->link);
- list_add(&lock->link, &g_inactive_locks);
- printk("android_power_suspend: aborted full wake lock %s\n", lock->name);
- }
- spin_unlock_irqrestore(&g_list_lock, irqflags);
- queue_work(g_suspend_work_queue, &g_suspend_work);
-}
-
-void android_register_early_suspend(android_early_suspend_t *handler)
-{
- struct list_head *pos;
-
- mutex_lock(&g_early_suspend_lock);
- list_for_each(pos, &g_early_suspend_handlers) {
- android_early_suspend_t *e = list_entry(pos, android_early_suspend_t, link);
- if(e->level > handler->level)
- break;
- }
- list_add_tail(&handler->link, pos);
- mutex_unlock(&g_early_suspend_lock);
-}
-
-void android_unregister_early_suspend(android_early_suspend_t *handler)
-{
- mutex_lock(&g_early_suspend_lock);
- list_del(&handler->link);
- mutex_unlock(&g_early_suspend_lock);
-}
-
-#ifdef CONFIG_FRAMEBUFFER_CONSOLE
-static int orig_fgconsole;
-static void console_early_suspend(android_early_suspend_t *h)
-{
- acquire_console_sem();
- orig_fgconsole = fg_console;
- if (vc_allocate(ANDROID_SUSPEND_CONSOLE))
- goto err;
- if (set_console(ANDROID_SUSPEND_CONSOLE))
- goto err;
- release_console_sem();
-
- if (vt_waitactive(ANDROID_SUSPEND_CONSOLE))
- pr_warning("console_early_suspend: Can't switch VCs.\n");
- return;
-err:
- pr_warning("console_early_suspend: Can't set console\n");
- release_console_sem();
-}
-
-static void console_late_resume(android_early_suspend_t *h)
-{
- int ret;
- acquire_console_sem();
- ret = set_console(orig_fgconsole);
- release_console_sem();
- if (ret) {
- pr_warning("console_late_resume: Can't set console.\n");
- return;
- }
-
- if (vt_waitactive(orig_fgconsole))
- pr_warning("console_late_resume: Can't switch VCs.\n");
-}
-
-static android_early_suspend_t console_early_suspend_desc = {
- .level = ANDROID_EARLY_SUSPEND_LEVEL_CONSOLE_SWITCH,
- .suspend = console_early_suspend,
- .resume = console_late_resume,
-};
-#else
-/* tell userspace to stop drawing, wait for it to stop */
-static void stop_drawing_early_suspend(android_early_suspend_t *h)
-{
- int ret;
- unsigned long irq_flags;
-
- spin_lock_irqsave(&fb_state_lock, irq_flags);
- fb_state = ANDROID_REQUEST_STOP_DRAWING;
- spin_unlock_irqrestore(&fb_state_lock, irq_flags);
-
- wake_up_all(&fb_state_wq);
- ret = wait_event_timeout(fb_state_wq,
- fb_state == ANDROID_STOPPED_DRAWING,
- HZ);
- if (unlikely(fb_state != ANDROID_STOPPED_DRAWING))
- printk(KERN_WARNING "android_power: timeout waiting for "
- "userspace to stop drawing\n");
-}
-
-/* tell userspace to start drawing */
-static void start_drawing_late_resume(android_early_suspend_t *h)
-{
- unsigned long irq_flags;
-
- spin_lock_irqsave(&fb_state_lock, irq_flags);
- fb_state = ANDROID_DRAWING_OK;
- spin_unlock_irqrestore(&fb_state_lock, irq_flags);
- wake_up(&fb_state_wq);
-}
-
-static android_early_suspend_t stop_drawing_early_suspend_desc = {
- .level = ANDROID_EARLY_SUSPEND_LEVEL_CONSOLE_SWITCH,
- .suspend = stop_drawing_early_suspend,
- .resume = start_drawing_late_resume,
-};
-#endif
-
-#if ANDROID_POWER_TEST_EARLY_SUSPEND
-
-typedef struct
-{
- android_early_suspend_t h;
- const char *string;
-} early_suspend_test_t;
-
-static void early_suspend_test(android_early_suspend_t *h)
-{
- early_suspend_test_t *est = container_of(h, early_suspend_test_t, h);
- printk("early suspend %s (l %d)\n", est->string, h->level);
-}
-
-static void late_resume_test(android_early_suspend_t *h)
-{
- early_suspend_test_t *est = container_of(h, early_suspend_test_t, h);
- printk("late resume %s (l %d)\n", est->string, h->level);
-}
-
-#define EARLY_SUSPEND_TEST_ENTRY(ilevel, istring) \
-{ \
- .h = { \
- .level = ilevel, \
- .suspend = early_suspend_test, \
- .resume = late_resume_test \
- }, \
- .string = istring \
-}
-static early_suspend_test_t early_suspend_tests[] = {
- EARLY_SUSPEND_TEST_ENTRY(10, "1"),
- EARLY_SUSPEND_TEST_ENTRY(5, "2"),
- EARLY_SUSPEND_TEST_ENTRY(10, "3"),
- EARLY_SUSPEND_TEST_ENTRY(15, "4"),
- EARLY_SUSPEND_TEST_ENTRY(8, "5")
-};
-
-#endif
-
-static int get_wait_timeout(int print_locks, int state, struct list_head *list_head)
-{
- unsigned long irqflags;
- android_suspend_lock_t *lock, *next;
- int max_timeout = 0;
-
- spin_lock_irqsave(&g_list_lock, irqflags);
- list_for_each_entry_safe(lock, next, list_head, link) {
- if(lock->flags & ANDROID_SUSPEND_LOCK_AUTO_EXPIRE) {
- int timeout = lock->expires - (int)jiffies;
- if(timeout <= 0) {
- lock->flags &= ~ANDROID_SUSPEND_LOCK_AUTO_EXPIRE;
-#ifdef CONFIG_ANDROID_POWER_STAT
- lock->stat.expire_count++;
- android_unlock_suspend_stat_locked(lock);
-#endif
- list_del(&lock->link);
- list_add(&lock->link, &g_inactive_locks);
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_WAKE_LOCK)
- printk("expired wake lock %s\n", lock->name);
- }
- else {
- if(timeout > max_timeout)
- max_timeout = timeout;
- if(print_locks)
- printk("active wake lock %s, time left %d\n", lock->name, timeout);
- }
- }
- else {
- if(print_locks)
- printk("active wake lock %s\n", lock->name);
- }
- }
- if(g_user_suspend_state != state || list_empty(list_head))
- max_timeout = -1;
- spin_unlock_irqrestore(&g_list_lock, irqflags);
- return max_timeout;
-}
-
-#ifdef CONFIG_FRAMEBUFFER_CONSOLE
-static int android_power_class_suspend(struct sys_device *sdev, pm_message_t state)
-{
- int rv = 0;
- unsigned long irqflags;
-
- printk("android_power_suspend: enter\n");
- spin_lock_irqsave(&g_list_lock, irqflags);
- if(!list_empty(&g_active_partial_wake_locks)) {
- printk("android_power_suspend: abort for partial wakeup\n");
- rv = -EAGAIN;
- }
- if(g_user_suspend_state != USER_SLEEP) {
- printk("android_power_suspend: abort for full wakeup\n");
- rv = -EAGAIN;
- }
- spin_unlock_irqrestore(&g_list_lock, irqflags);
- return rv;
-}
-
-static int android_power_device_suspend(struct sys_device *sdev, pm_message_t state)
-{
- int rv = 0;
- unsigned long irqflags;
-
- printk("android_power_device_suspend: enter\n");
- spin_lock_irqsave(&g_list_lock, irqflags);
- if(!list_empty(&g_active_partial_wake_locks)) {
- printk("android_power_device_suspend: abort for partial wakeup\n");
- rv = -EAGAIN;
- }
- if(g_user_suspend_state != USER_SLEEP) {
- printk("android_power_device_suspend: abort for full wakeup\n");
- rv = -EAGAIN;
- }
- spin_unlock_irqrestore(&g_list_lock, irqflags);
- return rv;
-}
-#endif
-
-int android_power_is_driver_suspended(void)
-{
- return (get_wait_timeout(0, USER_SLEEP, &g_active_partial_wake_locks) < 0) && (g_user_suspend_state == USER_SLEEP);
-}
-
-int android_power_is_low_power_idle_ok(void)
-{
- get_wait_timeout(0, USER_SLEEP, &g_active_idle_wake_locks);
- return list_empty(&g_active_idle_wake_locks);
-}
-
-static void android_power_suspend(struct work_struct *work)
-{
- int entry_event_num;
- int ret;
- int wait = 0;
- android_early_suspend_t *pos;
- int print_locks = 0;
- unsigned long irqflags;
-
- while(g_user_suspend_state != USER_AWAKE) {
- while(g_user_suspend_state == USER_NOTIFICATION) {
- wait = get_wait_timeout(print_locks, USER_NOTIFICATION, &g_active_full_wake_locks);
- if(wait < 0)
- break;
- if(wait)
- wait_event_interruptible_timeout(g_wait_queue, get_wait_timeout(0, USER_NOTIFICATION, &g_active_full_wake_locks) != wait, wait);
- }
- spin_lock_irqsave(&g_list_lock, irqflags);
- if(g_user_suspend_state == USER_NOTIFICATION && list_empty(&g_active_full_wake_locks)) {
- printk("android sleep state %d->%d at %lld\n", g_user_suspend_state, USER_SLEEP, ktime_to_ns(ktime_get()));
- g_user_suspend_state = USER_SLEEP;
- }
- spin_unlock_irqrestore(&g_list_lock, irqflags);
- wait = 0;
- if(g_user_suspend_state == USER_AWAKE) {
- printk("android_power_suspend: suspend aborted\n");
- return;
- }
-
- mutex_lock(&g_early_suspend_lock);
- //printk("android_power_suspend: call early suspend handlers\n");
- list_for_each_entry(pos, &g_early_suspend_handlers, link) {
- if(pos->suspend != NULL)
- pos->suspend(pos);
- }
- //printk("android_power_suspend: call early suspend handlers\n");
-
- //printk("android_power_suspend: enter\n");
-
- sys_sync();
-
- while(g_user_suspend_state == USER_SLEEP) {
- //printk("android_power_suspend: enter wait (%d)\n", wait);
- if(wait) {
- wait_event_interruptible_timeout(g_wait_queue, g_user_suspend_state != USER_SLEEP, wait);
- wait = 0;
- }
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_SUSPEND)
- print_locks = 1;
- while(1) {
- wait = get_wait_timeout(print_locks, USER_SLEEP, &g_active_partial_wake_locks);
- print_locks = 0;
- if(wait < 0)
- break;
- if(wait)
- wait_event_interruptible_timeout(g_wait_queue, get_wait_timeout(0, USER_SLEEP, &g_active_partial_wake_locks) != wait, wait);
- else
- wait_event_interruptible(g_wait_queue, get_wait_timeout(0, USER_SLEEP, &g_active_partial_wake_locks) != wait);
- }
- wait = 0;
- //printk("android_power_suspend: exit wait\n");
- entry_event_num = g_current_event_num;
- if(g_user_suspend_state != USER_SLEEP)
- break;
- sys_sync();
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_SUSPEND)
- printk(KERN_INFO "android_power_suspend: enter suspend\n");
- ret = pm_suspend(PM_SUSPEND_MEM);
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_EXIT_SUSPEND) {
- struct timespec ts;
- struct rtc_time tm;
- getnstimeofday(&ts);
- rtc_time_to_tm(ts.tv_sec, &tm);
- printk("android_power_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);
- }
- if(g_current_event_num == entry_event_num) {
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_SUSPEND)
- printk(KERN_INFO "android_power_suspend: pm_suspend returned with no event\n");
- wait = HZ / 2;
-#ifdef CONFIG_ANDROID_POWER_STAT
- if(g_no_wake_locks.stat.count == 0) {
- g_no_wake_locks.name = "unknown_wakeups";
- android_init_suspend_lock(&g_no_wake_locks);
- }
- g_no_wake_locks.stat.count++;
- g_no_wake_locks.stat.total_time = ktime_add(
- g_no_wake_locks.stat.total_time,
- ktime_set(0, 500 * NSEC_PER_MSEC));
- g_no_wake_locks.stat.max_time =
- ktime_set(0, 500 * NSEC_PER_MSEC);
-#endif
- }
- }
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_USER_STATE)
- printk("android_power_suspend: done\n");
- //printk("android_power_suspend: call late resume handlers\n");
- list_for_each_entry_reverse(pos, &g_early_suspend_handlers, link) {
- if(pos->resume != NULL)
- pos->resume(pos);
- }
- //printk("android_power_suspend: call late resume handlers\n");
- mutex_unlock(&g_early_suspend_lock);
- }
-}
-
-#if 0
-struct sysdev_class android_power_sysclass = {
- set_kset_name("android_power"),
- .suspend = android_power_class_suspend
-};
-static struct sysdev_class *g_android_power_sysclass = NULL;
-
-static struct {
- struct sys_device sysdev;
-// omap_csmi_gsm_image_info_t *pdata;
-} android_power_device = {
- .sysdev = {
- .id = 0,
- .cls = &android_power_sysclass,
-// .suspend = android_power_device_suspend
- },
-// .pdata = &g_gsm_image_info
-};
-
-struct sysdev_class *android_power_get_sysclass(void)
-{
- return g_android_power_sysclass;
-}
-#endif
-
-static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, char * buf)
-{
- char * s = buf;
- unsigned long irqflags;
-
- spin_lock_irqsave(&g_list_lock, irqflags);
- s += sprintf(s, "%d-%d-%d\n", g_user_suspend_state, list_empty(&g_active_full_wake_locks), list_empty(&g_active_partial_wake_locks));
- spin_unlock_irqrestore(&g_list_lock, irqflags);
- return (s - buf);
-}
-
-static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, const char * buf, size_t n)
-{
- if(n >= strlen("standby") &&
- strncmp(buf, "standby", strlen("standby")) == 0) {
- android_power_request_sleep();
- wait_event_interruptible(g_wait_queue, g_user_suspend_state == USER_AWAKE);
- return n;
- }
- if(n >= strlen("wake") &&
- strncmp(buf, "wake", strlen("wake")) == 0) {
- android_power_wakeup();
- return n;
- }
- printk("android_power state_store: invalid argument\n");
- return -EINVAL;
-}
-
-static ssize_t request_state_show(struct kobject *kobj, struct kobj_attribute *attr, char * buf)
-{
- char * s = buf;
- unsigned long irqflags;
-
- spin_lock_irqsave(&g_list_lock, irqflags);
- if(g_user_suspend_state == USER_AWAKE)
- s += sprintf(s, "wake\n");
- else if(g_user_suspend_state == USER_NOTIFICATION)
- s += sprintf(s, "standby (w/full wake lock)\n");
- else
- s += sprintf(s, "standby\n");
- spin_unlock_irqrestore(&g_list_lock, irqflags);
- return (s - buf);
-}
-
-static ssize_t request_state_store(struct kobject *kobj, struct kobj_attribute *attr, const char * buf, size_t n)
-{
- if(n >= strlen("standby") &&
- strncmp(buf, "standby", strlen("standby")) == 0) {
- android_power_request_sleep();
- return n;
- }
- if(n >= strlen("wake") &&
- strncmp(buf, "wake", strlen("wake")) == 0) {
- android_power_wakeup();
- return n;
- }
- printk("android_power state_store: invalid argument\n");
- return -EINVAL;
-}
-
-
-static int lookup_wake_lock_name(const char *buf, size_t n, int allocate, int *timeout)
-{
- int i;
- int free_index = -1;
- int inactive_index = -1;
- int expires_index = -1;
- int expires_time = INT_MAX;
- char *tmp_buf[64];
- char name[32];
- u64 nanoseconds;
- int num_arg;
-
- if(n <= 0)
- return -EINVAL;
- if(n >= sizeof(tmp_buf))
- return -EOVERFLOW;
- if(n == sizeof(tmp_buf) - 1 && buf[n - 1] != '\0')
- return -EOVERFLOW;
-
- memcpy(tmp_buf, buf, n);
- if(tmp_buf[n - 1] != '\0')
- tmp_buf[n] = '\0';
-
- num_arg = sscanf(buf, "%31s %llu", name, &nanoseconds);
- if(num_arg < 1)
- return -EINVAL;
-
- if(strlen(name) >= sizeof(g_user_wake_locks[i].name_buffer))
- return -EOVERFLOW;
-
- if(timeout != NULL) {
- if(num_arg > 1) {
- do_div(nanoseconds, (NSEC_PER_SEC / HZ));
- if(nanoseconds <= 0)
- nanoseconds = 1;
- *timeout = nanoseconds;
- }
- else
- *timeout = 0;
- }
-
- for(i = 0; i < g_max_user_lockouts; i++) {
- if(strcmp(g_user_wake_locks[i].name_buffer, name) == 0)
- return i;
- if(g_user_wake_locks[i].name_buffer[0] == '\0')
- free_index = i;
- else if(g_user_wake_locks[i].state == USER_WAKE_LOCK_INACTIVE)
- inactive_index = i;
- else if(g_user_wake_locks[i].suspend_lock.expires < expires_time)
- expires_index = i;
- }
- if(allocate) {
- if(free_index >= 0)
- i = free_index;
- else if(inactive_index >= 0)
- i = inactive_index;
- else if(expires_index >= 0) {
- i = expires_index;
- printk("lookup_wake_lock_name: overwriting expired lock, %s\n", g_user_wake_locks[i].name_buffer);
- }
- else {
- i = 0;
- printk("lookup_wake_lock_name: overwriting active lock, %s\n", g_user_wake_locks[i].name_buffer);
- }
- strcpy(g_user_wake_locks[i].name_buffer, name);
- return i;
- }
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_USER_WAKE_LOCK)
- printk(KERN_INFO "lookup_wake_lock_name: %s not found\n", name);
- return -EINVAL;
-}
-
-static ssize_t acquire_full_wake_lock_show(struct kobject *kobj, struct kobj_attribute *attr, char * buf)
-{
- int i;
- char * s = buf;
- unsigned long irqflags;
-
- spin_lock_irqsave(&g_list_lock, irqflags);
- for(i = 0; i < g_max_user_lockouts; i++) {
- if(g_user_wake_locks[i].name_buffer[0] != '\0' && g_user_wake_locks[i].state == USER_WAKE_LOCK_FULL)
- s += sprintf(s, "%s ", g_user_wake_locks[i].name_buffer);
- }
- s += sprintf(s, "\n");
-
- spin_unlock_irqrestore(&g_list_lock, irqflags);
- return (s - buf);
-}
-
-static ssize_t acquire_full_wake_lock_store(struct kobject *kobj, struct kobj_attribute *attr, const char * buf, size_t n)
-{
- int i;
- unsigned long irqflags;
- int timeout;
-
- spin_lock_irqsave(&g_list_lock, irqflags);
- i = lookup_wake_lock_name(buf, n, 1, &timeout);
- if(i >= 0)
- g_user_wake_locks[i].state = USER_WAKE_LOCK_FULL;
- spin_unlock_irqrestore(&g_list_lock, irqflags);
- if(i < 0)
- return i;
-
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_USER_WAKE_LOCK)
- printk(KERN_INFO "acquire_full_wake_lock_store: %s, size %d\n",
- g_user_wake_locks[i].name_buffer, n);
-
- //android_lock_partial_suspend_auto_expire(&g_user_wake_locks[i].suspend_lock, ktime_to_timespec(g_auto_off_timeout).tv_sec * HZ);
- if(timeout == 0)
- timeout = INT_MAX;
- android_lock_partial_suspend_auto_expire(&g_user_wake_locks[i].suspend_lock, timeout);
-
- return n;
-}
-
-static ssize_t acquire_partial_wake_lock_show(struct kobject *kobj, struct kobj_attribute *attr, char * buf)
-{
- int i;
- char * s = buf;
- unsigned long irqflags;
-
- spin_lock_irqsave(&g_list_lock, irqflags);
- for(i = 0; i < g_max_user_lockouts; i++) {
- if(g_user_wake_locks[i].name_buffer[0] != '\0' && g_user_wake_locks[i].state == USER_WAKE_LOCK_PARTIAL)
- s += sprintf(s, "%s ", g_user_wake_locks[i].name_buffer);
- }
- s += sprintf(s, "\n");
-
- spin_unlock_irqrestore(&g_list_lock, irqflags);
- return (s - buf);
-}
-
-static ssize_t acquire_partial_wake_lock_store(struct kobject *kobj, struct kobj_attribute *attr, const char * buf, size_t n)
-{
- int i;
- unsigned long irqflags;
- int timeout;
-
- spin_lock_irqsave(&g_list_lock, irqflags);
- i = lookup_wake_lock_name(buf, n, 1, &timeout);
- if(i >= 0)
- g_user_wake_locks[i].state = USER_WAKE_LOCK_PARTIAL;
- spin_unlock_irqrestore(&g_list_lock, irqflags);
- if(i < 0)
- return 0;
-
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_USER_WAKE_LOCK)
- printk(KERN_INFO "acquire_partial_wake_lock_store: %s, "
- "size %d\n", g_user_wake_locks[i].name_buffer, n);
-
- if(timeout)
- android_lock_suspend_auto_expire(&g_user_wake_locks[i].suspend_lock, timeout);
- else
- android_lock_suspend(&g_user_wake_locks[i].suspend_lock);
-
- return n;
-}
-
-
-static ssize_t release_wake_lock_show(struct kobject *kobj, struct kobj_attribute *attr, char * buf)
-{
- int i;
- char * s = buf;
- unsigned long irqflags;
-
- spin_lock_irqsave(&g_list_lock, irqflags);
- for(i = 0; i < g_max_user_lockouts; i++) {
- if(g_user_wake_locks[i].name_buffer[0] != '\0' && g_user_wake_locks[i].state == USER_WAKE_LOCK_INACTIVE)
- s += sprintf(s, "%s ", g_user_wake_locks[i].name_buffer);
- }
- s += sprintf(s, "\n");
-
- spin_unlock_irqrestore(&g_list_lock, irqflags);
- return (s - buf);
-}
-
-static ssize_t release_wake_lock_store(struct kobject *kobj, struct kobj_attribute *attr, const char * buf, size_t n)
-{
- int i;
- unsigned long irqflags;
-
- spin_lock_irqsave(&g_list_lock, irqflags);
- i = lookup_wake_lock_name(buf, n, 1, NULL);
- if(i >= 0) {
- g_user_wake_locks[i].state = USER_WAKE_LOCK_INACTIVE;
- }
- spin_unlock_irqrestore(&g_list_lock, irqflags);
-
- if(i < 0)
- return i;
-
- if (android_power_debug_mask & ANDROID_POWER_DEBUG_USER_WAKE_LOCK)
- printk(KERN_INFO "release_wake_lock_store: %s, size %d\n",
- g_user_wake_locks[i].name_buffer, n);
-
- android_unlock_suspend(&g_user_wake_locks[i].suspend_lock);
- return n;
-}
-
-
-#ifndef CONFIG_FRAMEBUFFER_CONSOLE
-static ssize_t wait_for_fb_sleep_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
-{
- char * s = buf;
- int ret;
-
- ret = wait_event_interruptible(fb_state_wq,
- fb_state != ANDROID_DRAWING_OK);
- if (ret && fb_state == ANDROID_DRAWING_OK)
- return ret;
- else
- s += sprintf(buf, "sleeping");
- return (s - buf);
-}
-
-static ssize_t wait_for_fb_wake_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
-{
- char * s = buf;
- int ret;
- unsigned long irq_flags;
-
- spin_lock_irqsave(&fb_state_lock, irq_flags);
- if (fb_state == ANDROID_REQUEST_STOP_DRAWING) {
- fb_state = ANDROID_STOPPED_DRAWING;
- wake_up(&fb_state_wq);
- }
- spin_unlock_irqrestore(&fb_state_lock, irq_flags);
-
- ret = wait_event_interruptible(fb_state_wq,
- fb_state == ANDROID_DRAWING_OK);
- if (ret && fb_state != ANDROID_DRAWING_OK)
- return ret;
- else
- s += sprintf(buf, "awake");
-
- return (s - buf);
-}
-#endif
-
-#define android_power_attr(_name) \
-static struct kobj_attribute _name##_attr = { \
- .attr = { \
- .name = __stringify(_name), \
- .mode = 0664, \
- }, \
- .show = _name##_show, \
- .store = _name##_store, \
-}
-
-#define android_power_ro_attr(_name) \
-static struct kobj_attribute _name##_attr = { \
- .attr = { \
- .name = __stringify(_name), \
- .mode = 0444, \
- }, \
- .show = _name##_show, \
- .store = NULL, \
-}
-
-android_power_attr(state);
-android_power_attr(request_state);
-android_power_attr(acquire_full_wake_lock);
-android_power_attr(acquire_partial_wake_lock);
-android_power_attr(release_wake_lock);
-#ifndef CONFIG_FRAMEBUFFER_CONSOLE
-android_power_ro_attr(wait_for_fb_sleep);
-android_power_ro_attr(wait_for_fb_wake);
-#endif
-
-static struct attribute * g[] = {
- &state_attr.attr,
- &request_state_attr.attr,
- &acquire_full_wake_lock_attr.attr,
- &acquire_partial_wake_lock_attr.attr,
- &release_wake_lock_attr.attr,
-#ifndef CONFIG_FRAMEBUFFER_CONSOLE
- &wait_for_fb_sleep_attr.attr,
- &wait_for_fb_wake_attr.attr,
-#endif
- NULL,
-};
-
-static struct attribute_group attr_group = {
- .attrs = g,
-};
-
-#if 0
-// test code when there is no platform suspend
-
-static android_suspend_lock_t test_pm_ops_suspend_lock = {
- .name = "test_pm_ops"
-};
-
-int test_pm_op_enter(suspend_state_t state)
-{
- printk("test_pm_op_enter reached\n");
- android_lock_suspend(&test_pm_ops_suspend_lock);
- printk("test_pm_op_enter returned\n");
- return 0;
-}
-
-void test_pm_ops_late_resume_handler(android_early_suspend_t *h)
-{
- printk("test_pm_ops_late_resume_handler reached\n");
- android_unlock_suspend(&test_pm_ops_suspend_lock);
- printk("test_pm_ops_late_resume_handler returned\n");
-}
-
-static struct pm_ops test_pm_ops = {
- .enter = test_pm_op_enter
-};
-
-static android_early_suspend_t test_pm_ops_early_suspend_handler = {
- .resume = test_pm_ops_late_resume_handler
-};
-#endif
-
-static int __init android_power_init(void)
-{
- int ret;
- int i;
-
-#if 0
- if(pm_ops == NULL) {
- printk("android_power_init no pm_ops, installing test code\n");
- pm_set_ops(&test_pm_ops);
- android_init_suspend_lock(&test_pm_ops_suspend_lock);
- android_register_early_suspend(&test_pm_ops_early_suspend_handler);
- }
-#endif
-
-#ifdef CONFIG_ANDROID_POWER_STAT
- g_deleted_wake_locks.stat.count = 0;
-#endif
- init_waitqueue_head(&g_wait_queue);
-#ifndef CONFIG_FRAMEBUFFER_CONSOLE
- init_waitqueue_head(&fb_state_wq);
- fb_state = ANDROID_DRAWING_OK;
-#endif
-
- g_user_wake_locks = kzalloc(sizeof(*g_user_wake_locks) * g_max_user_lockouts, GFP_KERNEL);
- if(g_user_wake_locks == NULL) {
- ret = -ENOMEM;
- goto err1;
- }
- for(i = 0; i < g_max_user_lockouts; i++) {
- g_user_wake_locks[i].suspend_lock.name = g_user_wake_locks[i].name_buffer;
- android_init_suspend_lock(&g_user_wake_locks[i].suspend_lock);
- }
-
- g_suspend_work_queue = create_workqueue("suspend");
- if(g_suspend_work_queue == NULL) {
- ret = -ENOMEM;
- goto err2;
- }
-
- android_power_kobj = kobject_create_and_add("android_power", NULL);
- if (android_power_kobj == NULL) {
- printk("android_power_init: subsystem_register failed\n");
- ret = -ENOMEM;
- goto err3;
- }
- ret = sysfs_create_group(android_power_kobj, &attr_group);
- if(ret) {
- printk("android_power_init: sysfs_create_group failed\n");
- goto err4;
- }
-#ifdef CONFIG_ANDROID_POWER_STAT
- create_proc_read_entry("wakelocks", S_IRUGO, NULL, wakelocks_read_proc, NULL);
-#endif
-
-#if ANDROID_POWER_TEST_EARLY_SUSPEND
- {
- int i;
- for(i = 0; i < sizeof(early_suspend_tests) / sizeof(early_suspend_tests[0]); i++)
- android_register_early_suspend(&early_suspend_tests[i].h);
- }
-#endif
-#ifdef CONFIG_FRAMEBUFFER_CONSOLE
- android_register_early_suspend(&console_early_suspend_desc);
-#else
- android_register_early_suspend(&stop_drawing_early_suspend_desc);
-#endif
-
-#if 0
- ret = sysdev_class_register(&android_power_sysclass);
- if(ret) {
- printk("android_power_init: sysdev_class_register failed\n");
- goto err1;
- }
- ret = sysdev_register(&android_power_device.sysdev);
- if(ret < 0)
- goto err2;
-
- g_android_power_sysclass = &android_power_sysclass;
-#endif
- return 0;
-
-//err2:
-// sysdev_class_unregister(&android_power_sysclass);
-err4:
- kobject_del(android_power_kobj);
-err3:
- destroy_workqueue(g_suspend_work_queue);
-err2:
- for(i = 0; i < g_max_user_lockouts; i++) {
- android_uninit_suspend_lock(&g_user_wake_locks[i].suspend_lock);
- }
- kfree(g_user_wake_locks);
-err1:
- return ret;
-}
-
-static void __exit android_power_exit(void)
-{
- int i;
-// g_android_power_sysclass = NULL;
-// sysdev_unregister(&android_power_device.sysdev);
-// sysdev_class_unregister(&android_power_sysclass);
-#ifdef CONFIG_FRAMEBUFFER_CONSOLE
- android_unregister_early_suspend(&console_early_suspend_desc);
-#else
- android_unregister_early_suspend(&stop_drawing_early_suspend_desc);
-#endif
-#ifdef CONFIG_ANDROID_POWER_STAT
- remove_proc_entry("wakelocks", NULL);
-#endif
- sysfs_remove_group(android_power_kobj, &attr_group);
- kobject_del(android_power_kobj);
- destroy_workqueue(g_suspend_work_queue);
- for(i = 0; i < g_max_user_lockouts; i++) {
- android_uninit_suspend_lock(&g_user_wake_locks[i].suspend_lock);
- }
- kfree(g_user_wake_locks);
-}
-
-core_initcall(android_power_init);
-module_exit(android_power_exit);
-
-//EXPORT_SYMBOL(android_power_get_sysclass);
-EXPORT_SYMBOL(android_init_suspend_lock);
-EXPORT_SYMBOL(android_uninit_suspend_lock);
-EXPORT_SYMBOL(android_lock_suspend);
-EXPORT_SYMBOL(android_lock_suspend_auto_expire);
-EXPORT_SYMBOL(android_unlock_suspend);
-EXPORT_SYMBOL(android_power_wakeup);
-EXPORT_SYMBOL(android_register_early_suspend);
-EXPORT_SYMBOL(android_unregister_early_suspend);
-
-