[ANDROID KERNEL PATCH 1/2] Prepare current kernel
Michael Trimarchi
trimarchi at gandalf.sssup.it
Mon Jan 26 18:01:25 CET 2009
Prepare current kernel to support the new android layer
Signed-off-by: Michael Trimarchi <michael at panicking.kicks-ass.org>
---
drivers/android/alarm.c | 469 +++++++------
drivers/android/binder.c | 8 +-
drivers/android/logger.c | 4 +-
drivers/android/power.c | 1336 ------------------------------------
drivers/android/timed_gpio.c | 129 ++--
include/linux/android_alarm.h | 29 +-
include/linux/android_power.h | 98 ---
include/linux/android_timed_gpio.h | 31 -
kernel/power/main.c | 25 +
kernel/power/power.h | 31 +-
kernel/power/process.c | 28 +-
kernel/printk.c | 15 +-
12 files changed, 418 insertions(+), 1785 deletions(-)
delete mode 100644 drivers/android/power.c
delete mode 100644 include/linux/android_power.h
delete mode 100644 include/linux/android_timed_gpio.h
diff --git a/drivers/android/alarm.c b/drivers/android/alarm.c
index 317e2c6..9f6134b 100644
--- a/drivers/android/alarm.c
+++ b/drivers/android/alarm.c
@@ -1,4 +1,4 @@
-/* drivers/android/alarm.c
+/* drivers/rtc/alarm.c
*
* Copyright (C) 2007 Google, Inc.
*
@@ -15,13 +15,13 @@
#include <asm/mach/time.h>
#include <linux/android_alarm.h>
-#include <linux/android_power.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/spinlock.h>
#include <linux/sysdev.h>
+#include <linux/wakelock.h>
#define ANDROID_ALARM_PRINT_ERRORS (1U << 0)
#define ANDROID_ALARM_PRINT_INIT_STATUS (1U << 1)
@@ -34,28 +34,28 @@
#define ANDROID_ALARM_DPRINTF_MASK (~0)
#define ANDROID_ALARM_DPRINTF(debug_level_mask, args...) \
do { \
- if(ANDROID_ALARM_DPRINTF_MASK & debug_level_mask) { \
+ if (ANDROID_ALARM_DPRINTF_MASK & debug_level_mask) { \
printk(args); \
} \
- } while(0)
+ } while (0)
#else
#define ANDROID_ALARM_DPRINTF(args...)
#endif
-// support old usespace code
-#define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) // set alarm
+#define ANDROID_ALARM_WAKEUP_MASK ( \
+ ANDROID_ALARM_RTC_WAKEUP_MASK | \
+ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK)
+
+/* support old usespace code */
+#define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */
#define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t)
static struct rtc_device *alarm_rtc_dev;
static int alarm_opened;
static DEFINE_SPINLOCK(alarm_slock);
static DEFINE_MUTEX(alarm_setrtc_mutex);
-static android_suspend_lock_t alarm_suspend_lock = {
- .name = "android_alarm"
-};
-static android_suspend_lock_t alarm_rtc_suspend_lock = {
- .name = "android_alarm_rtc"
-};
+static struct wake_lock alarm_wake_lock;
+static struct wake_lock alarm_rtc_wake_lock;
static DECLARE_WAIT_QUEUE_HEAD(alarm_wait_queue);
static uint32_t alarm_pending;
static uint32_t alarm_enabled;
@@ -65,17 +65,22 @@ static struct hrtimer alarm_timer[ANDROID_ALARM_TYPE_COUNT];
static struct timespec alarm_time[ANDROID_ALARM_TYPE_COUNT];
static struct timespec elapsed_rtc_delta;
-static void alarm_start_hrtimer(android_alarm_type_t alarm_type)
+static void alarm_start_hrtimer(enum android_alarm_type alarm_type)
{
struct timespec hr_alarm_time;
- if(!(alarm_enabled & (1U << alarm_type)))
+ if (!(alarm_enabled & (1U << alarm_type)))
return;
hr_alarm_time = alarm_time[alarm_type];
- if(alarm_type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP || alarm_type == ANDROID_ALARM_ELAPSED_REALTIME)
- set_normalized_timespec(&hr_alarm_time, hr_alarm_time.tv_sec + elapsed_rtc_delta.tv_sec,
- hr_alarm_time.tv_nsec + elapsed_rtc_delta.tv_nsec);
- ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_FLOW, "alarm start hrtimer %d at %ld.%09ld\n", alarm_type, hr_alarm_time.tv_sec, hr_alarm_time.tv_nsec);
- hrtimer_start(&alarm_timer[alarm_type], timespec_to_ktime(hr_alarm_time), HRTIMER_MODE_ABS);
+ if (alarm_type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP ||
+ alarm_type == ANDROID_ALARM_ELAPSED_REALTIME)
+ set_normalized_timespec(&hr_alarm_time,
+ hr_alarm_time.tv_sec + elapsed_rtc_delta.tv_sec,
+ hr_alarm_time.tv_nsec + elapsed_rtc_delta.tv_nsec);
+ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_FLOW,
+ "alarm start hrtimer %d at %ld.%09ld\n",
+ alarm_type, hr_alarm_time.tv_sec, hr_alarm_time.tv_nsec);
+ hrtimer_start(&alarm_timer[alarm_type],
+ timespec_to_ktime(hr_alarm_time), HRTIMER_MODE_ABS);
}
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -87,18 +92,19 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
struct timespec new_rtc_time;
struct timespec tmp_time;
struct rtc_time rtc_new_rtc_time;
- android_alarm_type_t alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd);
+ enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd);
uint32_t alarm_type_mask = 1U << alarm_type;
- if(alarm_type >= ANDROID_ALARM_TYPE_COUNT)
+ if (alarm_type >= ANDROID_ALARM_TYPE_COUNT)
return -EINVAL;
- if(ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) {
+ if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) {
if ((file->f_flags & O_ACCMODE) == O_RDONLY)
return -EPERM;
- if(file->private_data == NULL && cmd != ANDROID_ALARM_SET_RTC) {
+ if (file->private_data == NULL &&
+ cmd != ANDROID_ALARM_SET_RTC) {
spin_lock_irqsave(&alarm_slock, flags);
- if(alarm_opened) {
+ if (alarm_opened) {
spin_unlock_irqrestore(&alarm_slock, flags);
return -EBUSY;
}
@@ -108,131 +114,138 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
}
- switch(ANDROID_ALARM_BASE_CMD(cmd)) {
- //case ANDROID_ALARM_CLEAR_OLD: // same as ANDROID_ALARM_CLEAR(0)
- case ANDROID_ALARM_CLEAR(0):
- spin_lock_irqsave(&alarm_slock, flags);
- ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_IO, "alarm %d clear\n", alarm_type);
- hrtimer_try_to_cancel(&alarm_timer[alarm_type]);
- if(alarm_pending) {
- alarm_pending &= ~alarm_type_mask;
- if(!alarm_pending && !wait_pending) {
- android_unlock_suspend(&alarm_suspend_lock);
- }
- }
- alarm_enabled &= ~alarm_type_mask;
- spin_unlock_irqrestore(&alarm_slock, flags);
- break;
+ switch (ANDROID_ALARM_BASE_CMD(cmd)) {
+ case ANDROID_ALARM_CLEAR(0):
+ spin_lock_irqsave(&alarm_slock, flags);
+ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_IO,
+ "alarm %d clear\n", alarm_type);
+ hrtimer_try_to_cancel(&alarm_timer[alarm_type]);
+ if (alarm_pending) {
+ alarm_pending &= ~alarm_type_mask;
+ if (!alarm_pending && !wait_pending)
+ wake_unlock(&alarm_wake_lock);
+ }
+ alarm_enabled &= ~alarm_type_mask;
+ spin_unlock_irqrestore(&alarm_slock, flags);
+ break;
- case ANDROID_ALARM_SET_OLD:
- case ANDROID_ALARM_SET_AND_WAIT_OLD:
- if(get_user(new_alarm_time.tv_sec, (int __user *)arg)) {
- rv = -EFAULT;
- goto err1;
- }
- new_alarm_time.tv_nsec = 0;
- goto from_old_alarm_set;
-
- case ANDROID_ALARM_SET_AND_WAIT(0):
- case ANDROID_ALARM_SET(0):
- if(copy_from_user(&new_alarm_time, (void __user *)arg, sizeof(new_alarm_time))) {
- rv = -EFAULT;
- goto err1;
- }
+ case ANDROID_ALARM_SET_OLD:
+ case ANDROID_ALARM_SET_AND_WAIT_OLD:
+ if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) {
+ rv = -EFAULT;
+ goto err1;
+ }
+ new_alarm_time.tv_nsec = 0;
+ goto from_old_alarm_set;
+
+ case ANDROID_ALARM_SET_AND_WAIT(0):
+ case ANDROID_ALARM_SET(0):
+ if (copy_from_user(&new_alarm_time, (void __user *)arg,
+ sizeof(new_alarm_time))) {
+ rv = -EFAULT;
+ goto err1;
+ }
from_old_alarm_set:
- spin_lock_irqsave(&alarm_slock, flags);
- ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_IO, "alarm %d set %ld.%09ld\n", alarm_type, new_alarm_time.tv_sec, new_alarm_time.tv_nsec);
- alarm_time[alarm_type] = new_alarm_time;
- alarm_enabled |= alarm_type_mask;
- alarm_start_hrtimer(alarm_type);
- spin_unlock_irqrestore(&alarm_slock, flags);
- if(ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD)
- break;
- // fall though
- case ANDROID_ALARM_WAIT:
- spin_lock_irqsave(&alarm_slock, flags);
- ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_IO, "alarm wait\n");
- if(!alarm_pending && wait_pending) {
- android_unlock_suspend(&alarm_suspend_lock);
- wait_pending = 0;
- }
- spin_unlock_irqrestore(&alarm_slock, flags);
- rv = wait_event_interruptible(alarm_wait_queue, alarm_pending);
- if(rv)
- goto err1;
- spin_lock_irqsave(&alarm_slock, flags);
- rv = alarm_pending;
- wait_pending = 1;
- alarm_pending = 0;
- if(rv & (ANDROID_ALARM_RTC_WAKEUP_MASK | ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK)) {
- android_unlock_suspend(&alarm_rtc_suspend_lock);
- }
- spin_unlock_irqrestore(&alarm_slock, flags);
- break;
- case ANDROID_ALARM_SET_RTC:
- if(copy_from_user(&new_rtc_time, (void __user *)arg, sizeof(new_rtc_time))) {
- rv = -EFAULT;
- goto err1;
- }
- rtc_time_to_tm(new_rtc_time.tv_sec, &rtc_new_rtc_time);
-
- ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_IO,
- "set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n",
- new_rtc_time.tv_sec, new_rtc_time.tv_nsec,
- rtc_new_rtc_time.tm_hour, rtc_new_rtc_time.tm_min,
- rtc_new_rtc_time.tm_sec, rtc_new_rtc_time.tm_mon + 1,
- rtc_new_rtc_time.tm_mday, rtc_new_rtc_time.tm_year + 1900);
-
- mutex_lock(&alarm_setrtc_mutex);
- spin_lock_irqsave(&alarm_slock, flags);
- for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++)
- hrtimer_try_to_cancel(&alarm_timer[i]);
- getnstimeofday(&tmp_time);
- elapsed_rtc_delta = timespec_sub(elapsed_rtc_delta, timespec_sub(tmp_time, new_rtc_time));
- spin_unlock_irqrestore(&alarm_slock, flags);
- rv = do_settimeofday(&new_rtc_time);
- spin_lock_irqsave(&alarm_slock, flags);
- for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++)
- alarm_start_hrtimer(i);
- spin_unlock_irqrestore(&alarm_slock, flags);
- if(rv < 0) {
- ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_ERRORS, "Failed to set time\n");
- mutex_unlock(&alarm_setrtc_mutex);
- goto err1;
- }
- rv = rtc_set_time(alarm_rtc_dev, &rtc_new_rtc_time);
- spin_lock_irqsave(&alarm_slock, flags);
- alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK;
- wake_up(&alarm_wait_queue);
- spin_unlock_irqrestore(&alarm_slock, flags);
- mutex_unlock(&alarm_setrtc_mutex);
- if(rv < 0) {
- ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_ERRORS, "Failed to set RTC, time will be lost on reboot\n");
- goto err1;
- }
+ spin_lock_irqsave(&alarm_slock, flags);
+ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_IO,
+ "alarm %d set %ld.%09ld\n", alarm_type,
+ new_alarm_time.tv_sec, new_alarm_time.tv_nsec);
+ alarm_time[alarm_type] = new_alarm_time;
+ alarm_enabled |= alarm_type_mask;
+ alarm_start_hrtimer(alarm_type);
+ spin_unlock_irqrestore(&alarm_slock, flags);
+ if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0)
+ && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD)
break;
- case ANDROID_ALARM_GET_TIME(0):
- mutex_lock(&alarm_setrtc_mutex);
- spin_lock_irqsave(&alarm_slock, flags);
- if(alarm_type != ANDROID_ALARM_SYSTEMTIME) {
- getnstimeofday(&tmp_time);
- if(alarm_type >= ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP) {
- tmp_time = timespec_sub(tmp_time, elapsed_rtc_delta);
- }
- }
- else
- ktime_get_ts(&tmp_time);
- spin_unlock_irqrestore(&alarm_slock, flags);
+ /* fall though */
+ case ANDROID_ALARM_WAIT:
+ spin_lock_irqsave(&alarm_slock, flags);
+ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_IO, "alarm wait\n");
+ if (!alarm_pending && wait_pending) {
+ wake_unlock(&alarm_wake_lock);
+ wait_pending = 0;
+ }
+ spin_unlock_irqrestore(&alarm_slock, flags);
+ rv = wait_event_interruptible(alarm_wait_queue, alarm_pending);
+ if (rv)
+ goto err1;
+ spin_lock_irqsave(&alarm_slock, flags);
+ rv = alarm_pending;
+ wait_pending = 1;
+ alarm_pending = 0;
+ if (rv & ANDROID_ALARM_WAKEUP_MASK)
+ wake_unlock(&alarm_rtc_wake_lock);
+ spin_unlock_irqrestore(&alarm_slock, flags);
+ break;
+ case ANDROID_ALARM_SET_RTC:
+ if (copy_from_user(&new_rtc_time, (void __user *)arg,
+ sizeof(new_rtc_time))) {
+ rv = -EFAULT;
+ goto err1;
+ }
+ rtc_time_to_tm(new_rtc_time.tv_sec, &rtc_new_rtc_time);
+
+ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_IO,
+ "set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n",
+ new_rtc_time.tv_sec, new_rtc_time.tv_nsec,
+ rtc_new_rtc_time.tm_hour, rtc_new_rtc_time.tm_min,
+ rtc_new_rtc_time.tm_sec, rtc_new_rtc_time.tm_mon + 1,
+ rtc_new_rtc_time.tm_mday,
+ rtc_new_rtc_time.tm_year + 1900);
+
+ mutex_lock(&alarm_setrtc_mutex);
+ spin_lock_irqsave(&alarm_slock, flags);
+ for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++)
+ hrtimer_try_to_cancel(&alarm_timer[i]);
+ getnstimeofday(&tmp_time);
+ elapsed_rtc_delta = timespec_sub(elapsed_rtc_delta,
+ timespec_sub(tmp_time, new_rtc_time));
+ spin_unlock_irqrestore(&alarm_slock, flags);
+ rv = do_settimeofday(&new_rtc_time);
+ spin_lock_irqsave(&alarm_slock, flags);
+ for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++)
+ alarm_start_hrtimer(i);
+ spin_unlock_irqrestore(&alarm_slock, flags);
+ if (rv < 0) {
+ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_ERRORS,
+ "Failed to set time\n");
mutex_unlock(&alarm_setrtc_mutex);
- if(copy_to_user((void __user *)arg, &tmp_time, sizeof(tmp_time))) {
- rv = -EFAULT;
- goto err1;
- }
- break;
-
- default:
- rv = -EINVAL;
goto err1;
+ }
+ rv = rtc_set_time(alarm_rtc_dev, &rtc_new_rtc_time);
+ spin_lock_irqsave(&alarm_slock, flags);
+ alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK;
+ wake_up(&alarm_wait_queue);
+ spin_unlock_irqrestore(&alarm_slock, flags);
+ mutex_unlock(&alarm_setrtc_mutex);
+ if (rv < 0) {
+ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_ERRORS,
+ "Failed to set RTC, time will be lost on reboot\n");
+ goto err1;
+ }
+ break;
+ case ANDROID_ALARM_GET_TIME(0):
+ mutex_lock(&alarm_setrtc_mutex);
+ spin_lock_irqsave(&alarm_slock, flags);
+ if (alarm_type != ANDROID_ALARM_SYSTEMTIME) {
+ getnstimeofday(&tmp_time);
+ if (alarm_type >= ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP)
+ tmp_time = timespec_sub(tmp_time,
+ elapsed_rtc_delta);
+ } else
+ ktime_get_ts(&tmp_time);
+ spin_unlock_irqrestore(&alarm_slock, flags);
+ mutex_unlock(&alarm_setrtc_mutex);
+ if (copy_to_user((void __user *)arg, &tmp_time,
+ sizeof(tmp_time))) {
+ rv = -EFAULT;
+ goto err1;
+ }
+ break;
+
+ default:
+ rv = -EINVAL;
+ goto err1;
}
err1:
return rv;
@@ -250,21 +263,26 @@ static int alarm_release(struct inode *inode, struct file *file)
unsigned long flags;
spin_lock_irqsave(&alarm_slock, flags);
- if(file->private_data != 0) {
- for(i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
+ if (file->private_data != 0) {
+ for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
uint32_t alarm_type_mask = 1U << i;
- if(alarm_enabled & alarm_type_mask) {
- ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO, "alarm_release: clear alarm, pending %d\n", !!(alarm_pending & alarm_type_mask));
+ if (alarm_enabled & alarm_type_mask) {
+ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO,
+ "alarm_release: clear alarm, "
+ "pending %d\n",
+ !!(alarm_pending & alarm_type_mask));
alarm_enabled &= ~alarm_type_mask;
}
spin_unlock_irqrestore(&alarm_slock, flags);
hrtimer_cancel(&alarm_timer[i]);
spin_lock_irqsave(&alarm_slock, flags);
}
- if(alarm_pending | wait_pending) {
- if(alarm_pending)
- ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO, "alarm_release: clear pending alarms %x\n", alarm_pending);
- android_unlock_suspend(&alarm_suspend_lock);
+ if (alarm_pending | wait_pending) {
+ if (alarm_pending)
+ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO,
+ "alarm_release: clear pending alarms "
+ "%x\n", alarm_pending);
+ wake_unlock(&alarm_wake_lock);
wait_pending = 0;
alarm_pending = 0;
}
@@ -277,14 +295,15 @@ static int alarm_release(struct inode *inode, struct file *file)
static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer)
{
unsigned long flags;
- android_alarm_type_t alarm_type = (timer - alarm_timer);
+ enum android_alarm_type alarm_type = (timer - alarm_timer);
uint32_t alarm_type_mask = 1U << alarm_type;
- ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INT, "alarm_timer_triggered type %d\n", alarm_type);
+ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INT,
+ "alarm_timer_triggered type %d\n", alarm_type);
spin_lock_irqsave(&alarm_slock, flags);
if (alarm_enabled & alarm_type_mask) {
- android_lock_suspend_auto_expire(&alarm_suspend_lock, 5 * HZ);
+ wake_lock_timeout(&alarm_wake_lock, 5 * HZ);
alarm_enabled &= ~alarm_type_mask;
alarm_pending |= alarm_type_mask;
wake_up(&alarm_wait_queue);
@@ -295,13 +314,11 @@ static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer)
static void alarm_triggered_func(void *p)
{
-// unsigned long flags;
-
struct rtc_device *rtc = alarm_rtc_dev;
- if(rtc->irq_data & RTC_AF) {
- ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INT, "alarm_triggered_func:\n");
- android_lock_suspend_auto_expire(&alarm_rtc_suspend_lock, 1 * HZ);
- }
+ if (!(rtc->irq_data & RTC_AF))
+ return;
+ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INT, "rtc alarm triggered\n");
+ wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ);
}
int alarm_suspend(struct platform_device *pdev, pm_message_t state)
@@ -316,34 +333,44 @@ int alarm_suspend(struct platform_device *pdev, pm_message_t state)
struct timespec rtc_delta;
struct timespec elapsed_realtime_alarm_time;
- ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_FLOW, "alarm_suspend(%p, %d)\n", pdev, state.event);
+ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_FLOW,
+ "alarm_suspend(%p, %d)\n", pdev, state.event);
spin_lock_irqsave(&alarm_slock, flags);
- if(alarm_pending && (alarm_suspend_lock.flags & ANDROID_SUSPEND_LOCK_AUTO_EXPIRE)) {
- ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO, "alarm pending\n");
+ if (alarm_pending && !wake_lock_active(&alarm_wake_lock)) {
+ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO,
+ "alarm pending\n");
err = -EBUSY;
goto err1;
}
- if(alarm_enabled & (ANDROID_ALARM_RTC_WAKEUP_MASK | ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK)) {
+ if (alarm_enabled & ANDROID_ALARM_WAKEUP_MASK) {
spin_unlock_irqrestore(&alarm_slock, flags);
- if(alarm_enabled & ANDROID_ALARM_RTC_WAKEUP_MASK)
+ if (alarm_enabled & ANDROID_ALARM_RTC_WAKEUP_MASK)
hrtimer_cancel(&alarm_timer[ANDROID_ALARM_RTC_WAKEUP]);
- if(alarm_enabled & ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK)
- hrtimer_cancel(&alarm_timer[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]);
+ if (alarm_enabled & ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK)
+ hrtimer_cancel(&alarm_timer[
+ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]);
rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time);
rtc_current_timespec.tv_nsec = 0;
- rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_timespec.tv_sec);
+ rtc_tm_to_time(&rtc_current_rtc_time,
+ &rtc_current_timespec.tv_sec);
save_time_delta(&rtc_delta, &rtc_current_timespec);
set_normalized_timespec(&elapsed_realtime_alarm_time,
- alarm_time[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].tv_sec + elapsed_rtc_delta.tv_sec,
- alarm_time[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].tv_nsec + elapsed_rtc_delta.tv_nsec);
- if((alarm_enabled & ANDROID_ALARM_RTC_WAKEUP_MASK) &&
- (!(alarm_enabled & ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK)
- || timespec_compare(&alarm_time[ANDROID_ALARM_RTC_WAKEUP], &elapsed_realtime_alarm_time) < 0))
- rtc_alarm_time = timespec_sub(alarm_time[ANDROID_ALARM_RTC_WAKEUP], rtc_delta).tv_sec;
- else {
- rtc_alarm_time = timespec_sub(elapsed_realtime_alarm_time, rtc_delta).tv_sec;
- }
+ alarm_time[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]
+ .tv_sec + elapsed_rtc_delta.tv_sec,
+ alarm_time[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]
+ .tv_nsec + elapsed_rtc_delta.tv_nsec);
+ if ((alarm_enabled & ANDROID_ALARM_RTC_WAKEUP_MASK) &&
+ (!(alarm_enabled &
+ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) ||
+ timespec_compare(&alarm_time[ANDROID_ALARM_RTC_WAKEUP],
+ &elapsed_realtime_alarm_time) < 0))
+ rtc_alarm_time = timespec_sub(
+ alarm_time[ANDROID_ALARM_RTC_WAKEUP],
+ rtc_delta).tv_sec;
+ else
+ rtc_alarm_time = timespec_sub(
+ elapsed_realtime_alarm_time, rtc_delta).tv_sec;
rtc_time_to_tm(rtc_alarm_time, &rtc_alarm.time);
rtc_alarm.enabled = 1;
rtc_set_alarm(alarm_rtc_dev, &rtc_alarm);
@@ -353,22 +380,22 @@ int alarm_suspend(struct platform_device *pdev, pm_message_t state)
"rtc alarm set at %ld, now %ld, rtc delta %ld.%09ld\n",
rtc_alarm_time, rtc_current_time,
rtc_delta.tv_sec, rtc_delta.tv_nsec);
- if(rtc_current_time + 1 >= rtc_alarm_time) {
- //spin_lock_irqsave(&alarm_slock, flags);
- ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO, "alarm about to go off\n");
+ if (rtc_current_time + 1 >= rtc_alarm_time) {
+ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO,
+ "alarm about to go off\n");
memset(&rtc_alarm, 0, sizeof(rtc_alarm));
rtc_alarm.enabled = 0;
rtc_set_alarm(alarm_rtc_dev, &rtc_alarm);
spin_lock_irqsave(&alarm_slock, flags);
- android_lock_suspend_auto_expire(&alarm_rtc_suspend_lock, 2 * HZ); // trigger a wakeup
+ wake_lock_timeout(&alarm_rtc_wake_lock, 2 * HZ);
alarm_start_hrtimer(ANDROID_ALARM_RTC_WAKEUP);
- alarm_start_hrtimer(ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP);
+ alarm_start_hrtimer(
+ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP);
err = -EBUSY;
spin_unlock_irqrestore(&alarm_slock, flags);
}
- }
- else {
+ } else {
err1:
spin_unlock_irqrestore(&alarm_slock, flags);
}
@@ -378,8 +405,9 @@ err1:
int alarm_resume(struct platform_device *pdev)
{
struct rtc_wkalrm alarm;
- ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_FLOW, "alarm_resume(%p)\n", pdev);
- if(alarm_enabled & (ANDROID_ALARM_RTC_WAKEUP_MASK | ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK)) {
+ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_FLOW,
+ "alarm_resume(%p)\n", pdev);
+ if (alarm_enabled & ANDROID_ALARM_WAKEUP_MASK) {
memset(&alarm, 0, sizeof(alarm));
alarm.enabled = 0;
rtc_set_alarm(alarm_rtc_dev, &alarm);
@@ -414,27 +442,28 @@ static int rtc_alarm_add_device(struct device *dev,
mutex_lock(&alarm_setrtc_mutex);
- if(alarm_rtc_dev) {
+ if (alarm_rtc_dev) {
err = -EBUSY;
goto err1;
}
-
+
err = misc_register(&alarm_device);
- if(err)
+ if (err)
goto err1;
- alarm_platform_dev = platform_device_register_simple("alarm", -1, NULL, 0);
- if(IS_ERR(alarm_platform_dev)) {
+ alarm_platform_dev =
+ platform_device_register_simple("alarm", -1, NULL, 0);
+ if (IS_ERR(alarm_platform_dev)) {
err = PTR_ERR(alarm_platform_dev);
goto err2;
}
err = rtc_irq_register(rtc, &alarm_rtc_task);
- if(err)
+ if (err)
goto err3;
alarm_rtc_dev = rtc;
mutex_unlock(&alarm_setrtc_mutex);
-
- //device_pm_set_parent(&alarm_platform_dev->dev, dev); // currently useless, drivers are suspended in reverse creation order
- ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO, "alarm: parent %p\n", alarm_platform_dev->dev.power.pm_parent);
+
+ ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO, "alarm: parent %p\n",
+ alarm_platform_dev->dev.power.pm_parent);
return 0;
err3:
@@ -447,9 +476,9 @@ err1:
}
static void rtc_alarm_remove_device(struct device *dev,
- struct class_interface *class_intf)
+ struct class_interface *class_intf)
{
- if(dev == &alarm_rtc_dev->dev) {
+ if (dev == &alarm_rtc_dev->dev) {
rtc_irq_unregister(alarm_rtc_dev, &alarm_rtc_task);
platform_device_unregister(alarm_platform_dev);
misc_deregister(&alarm_device);
@@ -475,16 +504,17 @@ static int __init alarm_late_init(void)
unsigned long flags;
struct timespec system_time;
- // this needs to run after the rtc is read at boot
+ /* this needs to run after the rtc is read at boot */
spin_lock_irqsave(&alarm_slock, flags);
- // We read the current rtc and system time so we can later calulate
- // elasped realtime to be (boot_systemtime + rtc - boot_rtc) ==
- // (rtc - (boot_rtc - boot_systemtime))
- getnstimeofday(&elapsed_rtc_delta);
+ /* We read the current rtc and system time so we can later calulate
+ * elasped realtime to be (boot_systemtime + rtc - boot_rtc) ==
+ * (rtc - (boot_rtc - boot_systemtime))
+ */
+ getnstimeofday(&elapsed_rtc_delta);
ktime_get_ts(&system_time);
elapsed_rtc_delta = timespec_sub(elapsed_rtc_delta, system_time);
spin_unlock_irqrestore(&alarm_slock, flags);
-
+
ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_INFO,
"alarm_late_init: rtc to elapsed realtime delta %ld.%09ld\n",
elapsed_rtc_delta.tv_sec, elapsed_rtc_delta.tv_nsec);
@@ -496,33 +526,28 @@ static int __init alarm_init(void)
int err;
int i;
- for(i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) {
+ for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) {
hrtimer_init(&alarm_timer[i], CLOCK_REALTIME, HRTIMER_MODE_ABS);
alarm_timer[i].function = alarm_timer_triggered;
}
- hrtimer_init(&alarm_timer[ANDROID_ALARM_SYSTEMTIME], CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+ hrtimer_init(&alarm_timer[ANDROID_ALARM_SYSTEMTIME],
+ CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
alarm_timer[ANDROID_ALARM_SYSTEMTIME].function = alarm_timer_triggered;
err = platform_driver_register(&alarm_driver);
- if(err < 0)
+ if (err < 0)
goto err1;
- err = android_init_suspend_lock(&alarm_suspend_lock);
- if(err < 0)
- goto err2;
- err = android_init_suspend_lock(&alarm_rtc_suspend_lock);
- if(err < 0)
- goto err3;
+ wake_lock_init(&alarm_wake_lock, WAKE_LOCK_SUSPEND, "alarm");
+ wake_lock_init(&alarm_rtc_wake_lock, WAKE_LOCK_SUSPEND, "alarm_rtc");
rtc_alarm_interface.class = rtc_class;
err = class_interface_register(&rtc_alarm_interface);
- if(err < 0)
- goto err4;
-
+ if (err < 0)
+ goto err2;
+
return 0;
-err4:
- android_uninit_suspend_lock(&alarm_rtc_suspend_lock);
-err3:
- android_uninit_suspend_lock(&alarm_suspend_lock);
err2:
+ wake_lock_destroy(&alarm_rtc_wake_lock);
+ wake_lock_destroy(&alarm_wake_lock);
platform_driver_unregister(&alarm_driver);
err1:
return err;
@@ -531,8 +556,8 @@ err1:
static void __exit alarm_exit(void)
{
class_interface_unregister(&rtc_alarm_interface);
- android_uninit_suspend_lock(&alarm_rtc_suspend_lock);
- android_uninit_suspend_lock(&alarm_suspend_lock);
+ wake_lock_destroy(&alarm_rtc_wake_lock);
+ wake_lock_destroy(&alarm_wake_lock);
platform_driver_unregister(&alarm_driver);
}
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 80a96be..a38f48f 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -1,4 +1,4 @@
-/* drivers/android/binder.c
+/* drivers/misc/binder.c
*
* Android IPC Subsystem
*
@@ -54,7 +54,11 @@ static int binder_read_proc_proc(
#define SZ_4M 0x400000
#endif
+//#ifndef __i386__
+//#define FORBIDDEN_MMAP_FLAGS (VM_WRITE | VM_EXEC)
+//#else
#define FORBIDDEN_MMAP_FLAGS (VM_WRITE)
+//#endif
#define BINDER_SMALL_BUF_SIZE (PAGE_SIZE * 64)
@@ -2688,7 +2692,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
proc->buffer = area->addr;
proc->user_buffer_offset = vma->vm_start - (size_t)proc->buffer;
-#if defined(CONFIG_CPU_CACHE_VIPT) && !defined(CONFIG_CPU_S3C6410)
+#ifdef CONFIG_CPU_CACHE_VIPT
if (cache_is_vipt_aliasing()) {
while (CACHE_COLOUR((vma->vm_start ^ (uint32_t)proc->buffer))) {
printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p bad alignment\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer);
diff --git a/drivers/android/logger.c b/drivers/android/logger.c
index 05dac30..473c4da 100644
--- a/drivers/android/logger.c
+++ b/drivers/android/logger.c
@@ -1,7 +1,7 @@
/*
- * drivers/android/logger.c
+ * drivers/misc/logger.c
*
- * Android Logging Subsystem
+ * A Logging Subsystem
*
* Copyright (C) 2007-2008 Google, Inc.
*
diff --git a/drivers/android/power.c b/drivers/android/power.c
deleted file mode 100644
index 6c773ab..0000000
--- 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);
-
-
diff --git a/drivers/android/timed_gpio.c b/drivers/android/timed_gpio.c
index da6db41..7930915 100644
--- a/drivers/android/timed_gpio.c
+++ b/drivers/android/timed_gpio.c
@@ -1,4 +1,4 @@
-/* drivers/android/timed_gpio.c
+/* drivers/misc/timed_gpio.c
*
* Copyright (C) 2008 Google, Inc.
* Author: Mike Lockwood <lockwood at android.com>
@@ -18,15 +18,13 @@
#include <linux/platform_device.h>
#include <linux/hrtimer.h>
#include <linux/err.h>
-#include <mach/gpio.h>
+#include <linux/gpio.h>
+#include <linux/timed_output.h>
+#include <linux/timed_gpio.h>
-#include <linux/android_timed_gpio.h>
-
-
-static struct class *timed_gpio_class;
struct timed_gpio_data {
- struct device *dev;
+ struct timed_output_dev dev;
struct hrtimer timer;
spinlock_t lock;
unsigned gpio;
@@ -36,69 +34,61 @@ struct timed_gpio_data {
static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer)
{
- struct timed_gpio_data *gpio_data = container_of(timer, struct timed_gpio_data, timer);
+ struct timed_gpio_data *data =
+ container_of(timer, struct timed_gpio_data, timer);
- gpio_direction_output(gpio_data->gpio, gpio_data->active_low ? 1 : 0);
+ gpio_direction_output(data->gpio, data->active_low ? 1 : 0);
return HRTIMER_NORESTART;
}
-static ssize_t gpio_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
+static int gpio_get_time(struct timed_output_dev *dev)
{
- struct timed_gpio_data *gpio_data = dev_get_drvdata(dev);
- int remaining;
+ struct timed_gpio_data *data =
+ container_of(dev, struct timed_gpio_data, dev);
- if (hrtimer_active(&gpio_data->timer)) {
- ktime_t r = hrtimer_get_remaining(&gpio_data->timer);
- remaining = r.tv.sec * 1000 + r.tv.nsec / 1000000;
+ if (hrtimer_active(&data->timer)) {
+ ktime_t r = hrtimer_get_remaining(&data->timer);
+ return r.tv.sec * 1000 + r.tv.nsec / 1000000;
} else
- remaining = 0;
-
- return sprintf(buf, "%d\n", remaining);
+ return 0;
}
-static ssize_t gpio_enable_store(
- struct device *dev, struct device_attribute *attr,
- const char *buf, size_t size)
+static void gpio_enable(struct timed_output_dev *dev, int value)
{
- struct timed_gpio_data *gpio_data = dev_get_drvdata(dev);
- int value;
+ struct timed_gpio_data *data =
+ container_of(dev, struct timed_gpio_data, dev);
unsigned long flags;
- sscanf(buf, "%d", &value);
-
- spin_lock_irqsave(&gpio_data->lock, flags);
+ spin_lock_irqsave(&data->lock, flags);
/* cancel previous timer and set GPIO according to value */
- hrtimer_cancel(&gpio_data->timer);
- gpio_direction_output(gpio_data->gpio, gpio_data->active_low ? !value : !!value);
+ hrtimer_cancel(&data->timer);
+ gpio_direction_output(data->gpio, data->active_low ? !value : !!value);
if (value > 0) {
- if (value > gpio_data->max_timeout)
- value = gpio_data->max_timeout;
+ if (value > data->max_timeout)
+ value = data->max_timeout;
- hrtimer_start(&gpio_data->timer,
- ktime_set(value / 1000, (value % 1000) * 1000000),
- HRTIMER_MODE_REL);
+ hrtimer_start(&data->timer,
+ ktime_set(value / 1000, (value % 1000) * 1000000),
+ HRTIMER_MODE_REL);
}
- spin_unlock_irqrestore(&gpio_data->lock, flags);
-
- return size;
+ spin_unlock_irqrestore(&data->lock, flags);
}
-static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, gpio_enable_show, gpio_enable_store);
-
-static int android_timed_gpio_probe(struct platform_device *pdev)
+static int timed_gpio_probe(struct platform_device *pdev)
{
struct timed_gpio_platform_data *pdata = pdev->dev.platform_data;
struct timed_gpio *cur_gpio;
struct timed_gpio_data *gpio_data, *gpio_dat;
- int i, ret = 0;
+ int i, j, ret = 0;
if (!pdata)
return -EBUSY;
- gpio_data = kzalloc(sizeof(struct timed_gpio_data) * pdata->num_gpios, GFP_KERNEL);
+ gpio_data = kzalloc(sizeof(struct timed_gpio_data) * pdata->num_gpios,
+ GFP_KERNEL);
if (!gpio_data)
return -ENOMEM;
@@ -106,23 +96,26 @@ static int android_timed_gpio_probe(struct platform_device *pdev)
cur_gpio = &pdata->gpios[i];
gpio_dat = &gpio_data[i];
- hrtimer_init(&gpio_dat->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ hrtimer_init(&gpio_dat->timer, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
gpio_dat->timer.function = gpio_timer_func;
spin_lock_init(&gpio_dat->lock);
+ gpio_dat->dev.name = cur_gpio->name;
+ gpio_dat->dev.get_time = gpio_get_time;
+ gpio_dat->dev.enable = gpio_enable;
+ ret = timed_output_dev_register(&gpio_dat->dev);
+ if (ret < 0) {
+ for (j = 0; j < i; j++)
+ timed_output_dev_unregister(&gpio_data[i].dev);
+ kfree(gpio_data);
+ return ret;
+ }
+
gpio_dat->gpio = cur_gpio->gpio;
gpio_dat->max_timeout = cur_gpio->max_timeout;
gpio_dat->active_low = cur_gpio->active_low;
gpio_direction_output(gpio_dat->gpio, gpio_dat->active_low);
-
- gpio_dat->dev = device_create(timed_gpio_class, &pdev->dev, 0, "%s", cur_gpio->name);
- if (unlikely(IS_ERR(gpio_dat->dev)))
- return PTR_ERR(gpio_dat->dev);
-
- dev_set_drvdata(gpio_dat->dev, gpio_dat);
- ret = device_create_file(gpio_dat->dev, &dev_attr_enable);
- if (ret)
- return ret;
}
platform_set_drvdata(pdev, gpio_data);
@@ -130,48 +123,42 @@ static int android_timed_gpio_probe(struct platform_device *pdev)
return 0;
}
-static int android_timed_gpio_remove(struct platform_device *pdev)
+static int timed_gpio_remove(struct platform_device *pdev)
{
struct timed_gpio_platform_data *pdata = pdev->dev.platform_data;
struct timed_gpio_data *gpio_data = platform_get_drvdata(pdev);
int i;
- for (i = 0; i < pdata->num_gpios; i++) {
- device_remove_file(gpio_data[i].dev, &dev_attr_enable);
- device_unregister(gpio_data[i].dev);
- }
+ for (i = 0; i < pdata->num_gpios; i++)
+ timed_output_dev_unregister(&gpio_data[i].dev);
kfree(gpio_data);
return 0;
}
-static struct platform_driver android_timed_gpio_driver = {
- .probe = android_timed_gpio_probe,
- .remove = android_timed_gpio_remove,
+static struct platform_driver timed_gpio_driver = {
+ .probe = timed_gpio_probe,
+ .remove = timed_gpio_remove,
.driver = {
- .name = "android-timed-gpio",
+ .name = TIMED_GPIO_NAME,
.owner = THIS_MODULE,
},
};
-static int __init android_timed_gpio_init(void)
+static int __init timed_gpio_init(void)
{
- timed_gpio_class = class_create(THIS_MODULE, "timed_output");
- if (IS_ERR(timed_gpio_class))
- return PTR_ERR(timed_gpio_class);
- return platform_driver_register(&android_timed_gpio_driver);
+ return platform_driver_register(&timed_gpio_driver);
}
-static void __exit android_timed_gpio_exit(void)
+static void __exit timed_gpio_exit(void)
{
- class_destroy(timed_gpio_class);
- platform_driver_unregister(&android_timed_gpio_driver);
+ platform_driver_unregister(&timed_gpio_driver);
}
-module_init(android_timed_gpio_init);
-module_exit(android_timed_gpio_exit);
+module_init(timed_gpio_init);
+module_exit(timed_gpio_exit);
MODULE_AUTHOR("Mike Lockwood <lockwood at android.com>");
-MODULE_DESCRIPTION("Android timed gpio driver");
+MODULE_DESCRIPTION("timed gpio driver");
MODULE_LICENSE("GPL");
diff --git a/include/linux/android_alarm.h b/include/linux/android_alarm.h
index c1a1450..d0cafd6 100644
--- a/include/linux/android_alarm.h
+++ b/include/linux/android_alarm.h
@@ -16,10 +16,10 @@
#ifndef _LINUX_ANDROID_ALARM_H
#define _LINUX_ANDROID_ALARM_H
-#include <asm/ioctl.h>
+#include <linux/ioctl.h>
#include <linux/time.h>
-typedef enum {
+enum android_alarm_type {
/* return code bit numbers or set alarm arg */
ANDROID_ALARM_RTC_WAKEUP,
ANDROID_ALARM_RTC,
@@ -28,19 +28,21 @@ typedef enum {
ANDROID_ALARM_SYSTEMTIME,
ANDROID_ALARM_TYPE_COUNT,
-
+
/* return code bit numbers */
/* ANDROID_ALARM_TIME_CHANGE = 16 */
-} android_alarm_type_t;
+};
-typedef enum {
+enum android_alarm_return_flags {
ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP,
ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC,
- ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK = 1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
- ANDROID_ALARM_ELAPSED_REALTIME_MASK = 1U << ANDROID_ALARM_ELAPSED_REALTIME,
+ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK =
+ 1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
+ ANDROID_ALARM_ELAPSED_REALTIME_MASK =
+ 1U << ANDROID_ALARM_ELAPSED_REALTIME,
ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME,
ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16
-} android_alarm_return_flags_t;
+};
/* Disable alarm */
#define ANDROID_ALARM_CLEAR(type) _IO('a', 0 | ((type) << 4))
@@ -48,12 +50,13 @@ typedef enum {
/* Ack last alarm and wait for next */
#define ANDROID_ALARM_WAIT _IO('a', 1)
+#define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size)
/* Set alarm */
-#define ANDROID_ALARM_SET(type) _IOW('a', 2 | ((type) << 4), struct timespec)
-#define ANDROID_ALARM_SET_AND_WAIT(type) _IOW('a', 3 | ((type) << 4), struct timespec)
-#define ANDROID_ALARM_GET_TIME(type) _IOW('a', 4 | ((type) << 4), struct timespec)
+#define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec)
+#define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec)
+#define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec)
#define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec)
-#define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0)))
-#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4)
+#define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0)))
+#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4)
#endif
diff --git a/include/linux/android_power.h b/include/linux/android_power.h
deleted file mode 100644
index e0d6c2c..0000000
--- a/include/linux/android_power.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* include/linux/android_power.h
- *
- * Copyright (C) 2007-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.
- *
- */
-
-#ifndef _LINUX_ANDROID_POWER_H
-#define _LINUX_ANDROID_POWER_H
-
-#include <linux/list.h>
-#include <linux/ktime.h>
-
-typedef struct
-{
- struct list_head link;
- int flags;
- const char *name;
- int expires;
-#ifdef CONFIG_ANDROID_POWER_STAT
- struct {
- int count;
- int expire_count;
- ktime_t total_time;
- ktime_t max_time;
- ktime_t last_time;
- } stat;
-#endif
-} android_suspend_lock_t;
-
-#if 0 /* none of these flags are implemented */
-#define ANDROID_SUSPEND_LOCK_FLAG_COUNTED (1U << 0)
-#define ANDROID_SUSPEND_LOCK_FLAG_USER_READABLE (1U << 1)
-#define ANDROID_SUSPEND_LOCK_FLAG_USER_SET (1U << 2)
-#define ANDROID_SUSPEND_LOCK_FLAG_USER_CLEAR (1U << 3)
-#define ANDROID_SUSPEND_LOCK_FLAG_USER_INC (1U << 4)
-#define ANDROID_SUSPEND_LOCK_FLAG_USER_DEC (1U << 5)
-#define ANDROID_SUSPEND_LOCK_FLAG_USER_VISIBLE_MASK (0x1fU << 1)
-#endif
-#define ANDROID_SUSPEND_LOCK_AUTO_EXPIRE (1U << 6)
-#define ANDROID_SUSPEND_LOCK_ACTIVE (1U << 7)
-
-enum {
- ANDROID_STOPPED_DRAWING,
- ANDROID_REQUEST_STOP_DRAWING,
- ANDROID_DRAWING_OK,
-};
-
-enum {
- ANDROID_EARLY_SUSPEND_LEVEL_BLANK_SCREEN = 50,
- ANDROID_EARLY_SUSPEND_LEVEL_CONSOLE_SWITCH = 100,
- ANDROID_EARLY_SUSPEND_LEVEL_DISABLE_FB = 150,
-};
-typedef struct android_early_suspend android_early_suspend_t;
-struct android_early_suspend
-{
- struct list_head link;
- int level;
- void (*suspend)(android_early_suspend_t *h);
- void (*resume)(android_early_suspend_t *h);
-};
-
-typedef enum {
- ANDROID_CHARGING_STATE_UNKNOWN,
- ANDROID_CHARGING_STATE_DISCHARGE,
- ANDROID_CHARGING_STATE_MAINTAIN, /* or trickle */
- ANDROID_CHARGING_STATE_SLOW,
- ANDROID_CHARGING_STATE_NORMAL,
- ANDROID_CHARGING_STATE_FAST,
- ANDROID_CHARGING_STATE_OVERHEAT
-} android_charging_state_t;
-
-/* android_suspend_lock_t *android_allocate_suspend_lock(const char *debug_name); */
-/* void android_free_suspend_lock(android_suspend_lock_t *lock); */
-int android_init_suspend_lock(android_suspend_lock_t *lock);
-void android_uninit_suspend_lock(android_suspend_lock_t *lock);
-void android_lock_idle(android_suspend_lock_t *lock);
-void android_lock_idle_auto_expire(android_suspend_lock_t *lock, int timeout);
-void android_lock_suspend(android_suspend_lock_t *lock);
-void android_lock_suspend_auto_expire(android_suspend_lock_t *lock, int timeout);
-void android_unlock_suspend(android_suspend_lock_t *lock);
-
-int android_power_is_driver_suspended(void);
-int android_power_is_low_power_idle_ok(void);
-
-void android_register_early_suspend(android_early_suspend_t *handler);
-void android_unregister_early_suspend(android_early_suspend_t *handler);
-
-#endif
-
diff --git a/include/linux/android_timed_gpio.h b/include/linux/android_timed_gpio.h
deleted file mode 100644
index a38a96c..0000000
--- a/include/linux/android_timed_gpio.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* include/linux/android_timed_gpio.h
- *
- * Copyright (C) 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.
- *
-*/
-
-#ifndef _LINUX_ANDROID_TIMED_GPIO_H
-#define _LINUX_ANDROID_TIMED_GPIO_H
-
-struct timed_gpio {
- const char *name;
- unsigned gpio;
- int max_timeout;
- u8 active_low;
-};
-
-struct timed_gpio_platform_data {
- int num_gpios;
- struct timed_gpio *gpios;
-};
-
-#endif
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 14f5398..c867605 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -398,6 +398,9 @@ static void suspend_finish(void)
static const char * const pm_states[PM_SUSPEND_MAX] = {
+#ifdef CONFIG_EARLYSUSPEND
+ [PM_SUSPEND_ON] = "on",
+#endif
[PM_SUSPEND_STANDBY] = "standby",
[PM_SUSPEND_MEM] = "mem",
};
@@ -517,7 +520,11 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t n)
{
#ifdef CONFIG_SUSPEND
+#ifdef CONFIG_EARLYSUSPEND
+ suspend_state_t state = PM_SUSPEND_ON;
+#else
suspend_state_t state = PM_SUSPEND_STANDBY;
+#endif
const char * const *s;
#endif
char *p;
@@ -539,8 +546,15 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
break;
}
if (state < PM_SUSPEND_MAX && *s)
+#ifdef CONFIG_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;
@@ -573,6 +587,12 @@ pm_trace_store(struct kobject *kobj, struct kobj_attribute *attr,
power_attr(pm_trace);
#endif /* CONFIG_PM_TRACE */
+#ifdef CONFIG_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
@@ -581,6 +601,11 @@ static struct attribute * g[] = {
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PM_DEBUG)
&pm_test_attr.attr,
#endif
+#ifdef CONFIG_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 46b5ec7..c1edb12 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -153,7 +153,7 @@ extern int swsusp_shrink_memory(void);
extern void swsusp_free(void);
extern int swsusp_read(unsigned int *flags_p);
extern int swsusp_write(unsigned int flags);
-extern void swsusp_close(fmode_t);
+extern void swsusp_close(void);
struct timeval;
/* kernel/power/swsusp.c */
@@ -223,3 +223,32 @@ static inline void suspend_thaw_processes(void)
{
}
#endif
+
+#ifdef CONFIG_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_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_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 ca63401..2008b05 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -13,6 +13,9 @@
#include <linux/module.h>
#include <linux/syscalls.h>
#include <linux/freezer.h>
+#ifdef CONFIG_WAKELOCK
+#include <linux/wakelock.h>
+#endif
/*
* Timeout for stopping processes
@@ -36,6 +39,9 @@ static int try_to_freeze_tasks(bool sig_only)
struct timeval start, end;
u64 elapsed_csecs64;
unsigned int elapsed_csecs;
+#ifdef CONFIG_WAKELOCK
+ unsigned int wakeup = 0;
+#endif
do_gettimeofday(&start);
@@ -62,6 +68,12 @@ static int try_to_freeze_tasks(bool sig_only)
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
yield(); /* Yield is okay here */
+#ifdef CONFIG_WAKELOCK
+ if (todo && has_wake_lock(WAKE_LOCK_SUSPEND)) {
+ wakeup = 1;
+ break;
+ }
+#endif
if (time_after(jiffies, end_time))
break;
} while (todo);
@@ -77,11 +89,21 @@ 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 "
+#ifdef CONFIG_WAKELOCK
+ if (wakeup) {
+ printk("\n");
+ printk(KERN_ERR "Freezing of %s aborted\n",
+ sig_only ? "user space " : "tasks ");
+ } else {
+#endif
+ 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();
+#ifdef CONFIG_WAKELOCK
+ }
+#endif
read_lock(&tasklist_lock);
do_each_thread(g, p) {
task_lock(p);
diff --git a/kernel/printk.c b/kernel/printk.c
index a3d44ba..0e36b5c 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -82,7 +82,6 @@ EXPORT_SYMBOL(printk_emergency_debug_spew_send_string);
* driver system.
*/
static DECLARE_MUTEX(console_sem);
-static DECLARE_MUTEX(secondary_console_sem);
struct console *console_drivers;
EXPORT_SYMBOL_GPL(console_drivers);
@@ -936,12 +935,14 @@ void suspend_console(void)
printk("Suspending console(s) (use no_console_suspend to debug)\n");
acquire_console_sem();
console_suspended = 1;
+ up(&console_sem);
}
void resume_console(void)
{
if (!console_suspend_enabled)
return;
+ down(&console_sem);
console_suspended = 0;
release_console_sem();
}
@@ -957,11 +958,9 @@ void resume_console(void)
void acquire_console_sem(void)
{
BUG_ON(in_interrupt());
- if (console_suspended) {
- down(&secondary_console_sem);
- return;
- }
down(&console_sem);
+ if (console_suspended)
+ return;
console_locked = 1;
console_may_schedule = 1;
}
@@ -971,6 +970,10 @@ int try_acquire_console_sem(void)
{
if (down_trylock(&console_sem))
return -1;
+ if (console_suspended) {
+ up(&console_sem);
+ return -1;
+ }
console_locked = 1;
console_may_schedule = 0;
return 0;
@@ -1024,7 +1027,7 @@ void release_console_sem(void)
unsigned wake_klogd = 0;
if (console_suspended) {
- up(&secondary_console_sem);
+ up(&console_sem);
return;
}
--
1.5.6.5
More information about the openmoko-kernel
mailing list