Loading drivers/staging/android/alarm-dev.c +12 −2 Original line number Original line Diff line number Diff line Loading @@ -40,7 +40,8 @@ do { \ #define ANDROID_ALARM_WAKEUP_MASK ( \ #define ANDROID_ALARM_WAKEUP_MASK ( \ ANDROID_ALARM_RTC_WAKEUP_MASK | \ ANDROID_ALARM_RTC_WAKEUP_MASK | \ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK | \ ANDROID_ALARM_RTC_POWEROFF_WAKEUP_MASK) static int alarm_opened; static int alarm_opened; static DEFINE_SPINLOCK(alarm_slock); static DEFINE_SPINLOCK(alarm_slock); Loading @@ -64,7 +65,8 @@ static struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT]; static int is_wakeup(enum android_alarm_type type) static int is_wakeup(enum android_alarm_type type) { { return (type == ANDROID_ALARM_RTC_WAKEUP || return (type == ANDROID_ALARM_RTC_WAKEUP || type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP); type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP || type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP); } } Loading Loading @@ -108,6 +110,8 @@ static void alarm_clear(enum android_alarm_type alarm_type) alarm_enabled &= ~alarm_type_mask; alarm_enabled &= ~alarm_type_mask; spin_unlock_irqrestore(&alarm_slock, flags); spin_unlock_irqrestore(&alarm_slock, flags); if (alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP) set_power_on_alarm(0); } } static void alarm_set(enum android_alarm_type alarm_type, static void alarm_set(enum android_alarm_type alarm_type, Loading @@ -122,6 +126,9 @@ static void alarm_set(enum android_alarm_type alarm_type, alarm_enabled |= alarm_type_mask; alarm_enabled |= alarm_type_mask; devalarm_start(&alarms[alarm_type], timespec_to_ktime(*ts)); devalarm_start(&alarms[alarm_type], timespec_to_ktime(*ts)); spin_unlock_irqrestore(&alarm_slock, flags); spin_unlock_irqrestore(&alarm_slock, flags); if (alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP) set_power_on_alarm(ts->tv_sec); } } static int alarm_wait(void) static int alarm_wait(void) Loading Loading @@ -181,6 +188,7 @@ static int alarm_get_time(enum android_alarm_type alarm_type, switch (alarm_type) { switch (alarm_type) { case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_RTC: case ANDROID_ALARM_RTC: case ANDROID_ALARM_RTC_POWEROFF_WAKEUP: getnstimeofday(ts); getnstimeofday(ts); break; break; case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: Loading Loading @@ -421,6 +429,8 @@ static int __init alarm_dev_init(void) CLOCK_BOOTTIME, HRTIMER_MODE_ABS); CLOCK_BOOTTIME, HRTIMER_MODE_ABS); hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt, hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); CLOCK_MONOTONIC, HRTIMER_MODE_ABS); alarm_init(&alarms[ANDROID_ALARM_RTC_POWEROFF_WAKEUP].u.alrm, ALARM_REALTIME, devalarm_alarmhandler); for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { alarms[i].type = i; alarms[i].type = i; Loading drivers/staging/android/android_alarm.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ enum android_alarm_type { ANDROID_ALARM_RTC, ANDROID_ALARM_RTC, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, ANDROID_ALARM_ELAPSED_REALTIME, ANDROID_ALARM_ELAPSED_REALTIME, ANDROID_ALARM_RTC_POWEROFF_WAKEUP, ANDROID_ALARM_SYSTEMTIME, ANDROID_ALARM_SYSTEMTIME, ANDROID_ALARM_TYPE_COUNT, ANDROID_ALARM_TYPE_COUNT, Loading @@ -41,6 +42,8 @@ enum android_alarm_return_flags { 1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, 1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, ANDROID_ALARM_ELAPSED_REALTIME_MASK = ANDROID_ALARM_ELAPSED_REALTIME_MASK = 1U << ANDROID_ALARM_ELAPSED_REALTIME, 1U << ANDROID_ALARM_ELAPSED_REALTIME, ANDROID_ALARM_RTC_POWEROFF_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_POWEROFF_WAKEUP, ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME, ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME, ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16 ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16 }; }; Loading include/linux/alarmtimer.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -48,6 +48,7 @@ int alarm_start_relative(struct alarm *alarm, ktime_t start); void alarm_restart(struct alarm *alarm); void alarm_restart(struct alarm *alarm); int alarm_try_to_cancel(struct alarm *alarm); int alarm_try_to_cancel(struct alarm *alarm); int alarm_cancel(struct alarm *alarm); int alarm_cancel(struct alarm *alarm); void set_power_on_alarm(long secs); u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval); u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval); u64 alarm_forward_now(struct alarm *alarm, ktime_t interval); u64 alarm_forward_now(struct alarm *alarm, ktime_t interval); Loading kernel/time/alarmtimer.c +51 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,8 @@ #include <linux/workqueue.h> #include <linux/workqueue.h> #include <linux/freezer.h> #include <linux/freezer.h> #define ALARM_DELTA 120 /** /** * struct alarm_base - Alarm timer bases * struct alarm_base - Alarm timer bases * @lock: Lock for syncrhonized access to the base * @lock: Lock for syncrhonized access to the base Loading @@ -52,6 +54,54 @@ static struct wakeup_source *ws; static struct rtc_timer rtctimer; static struct rtc_timer rtctimer; static struct rtc_device *rtcdev; static struct rtc_device *rtcdev; static DEFINE_SPINLOCK(rtcdev_lock); static DEFINE_SPINLOCK(rtcdev_lock); static unsigned long power_on_alarm; static struct mutex power_on_alarm_lock; void set_power_on_alarm(long secs) { int rc; long rtc_secs, alarm_time; struct rtc_time rtc_time; struct rtc_wkalrm alarm; rc = mutex_lock_interruptible(&power_on_alarm_lock); if (rc != 0) return; rtc_read_time(rtcdev, &rtc_time); rtc_tm_to_time(&rtc_time, &rtc_secs); if (!secs) goto disable_alarm; else power_on_alarm = secs + rtc_secs; alarm_time = power_on_alarm; /* *Substract ALARM_DELTA from actual alarm time *to power up the device before actual alarm *expiration */ if ((alarm_time - ALARM_DELTA) > rtc_secs) alarm_time -= ALARM_DELTA; if (alarm_time <= rtc_secs) goto disable_alarm; rtc_time_to_tm(alarm_time, &alarm.time); alarm.enabled = 1; rc = rtc_set_alarm(rtcdev, &alarm); if (rc) goto disable_alarm; mutex_unlock(&power_on_alarm_lock); return; disable_alarm: rtc_alarm_irq_enable(rtcdev, 0); mutex_unlock(&power_on_alarm_lock); } static void alarmtimer_triggered_func(void *p) static void alarmtimer_triggered_func(void *p) { { Loading Loading @@ -837,6 +887,7 @@ static int __init alarmtimer_init(void) .nsleep = alarm_timer_nsleep, .nsleep = alarm_timer_nsleep, }; }; mutex_init(&power_on_alarm_lock); alarmtimer_rtc_timer_init(); alarmtimer_rtc_timer_init(); posix_timers_register_clock(CLOCK_REALTIME_ALARM, &alarm_clock); posix_timers_register_clock(CLOCK_REALTIME_ALARM, &alarm_clock); Loading Loading
drivers/staging/android/alarm-dev.c +12 −2 Original line number Original line Diff line number Diff line Loading @@ -40,7 +40,8 @@ do { \ #define ANDROID_ALARM_WAKEUP_MASK ( \ #define ANDROID_ALARM_WAKEUP_MASK ( \ ANDROID_ALARM_RTC_WAKEUP_MASK | \ ANDROID_ALARM_RTC_WAKEUP_MASK | \ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK | \ ANDROID_ALARM_RTC_POWEROFF_WAKEUP_MASK) static int alarm_opened; static int alarm_opened; static DEFINE_SPINLOCK(alarm_slock); static DEFINE_SPINLOCK(alarm_slock); Loading @@ -64,7 +65,8 @@ static struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT]; static int is_wakeup(enum android_alarm_type type) static int is_wakeup(enum android_alarm_type type) { { return (type == ANDROID_ALARM_RTC_WAKEUP || return (type == ANDROID_ALARM_RTC_WAKEUP || type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP); type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP || type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP); } } Loading Loading @@ -108,6 +110,8 @@ static void alarm_clear(enum android_alarm_type alarm_type) alarm_enabled &= ~alarm_type_mask; alarm_enabled &= ~alarm_type_mask; spin_unlock_irqrestore(&alarm_slock, flags); spin_unlock_irqrestore(&alarm_slock, flags); if (alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP) set_power_on_alarm(0); } } static void alarm_set(enum android_alarm_type alarm_type, static void alarm_set(enum android_alarm_type alarm_type, Loading @@ -122,6 +126,9 @@ static void alarm_set(enum android_alarm_type alarm_type, alarm_enabled |= alarm_type_mask; alarm_enabled |= alarm_type_mask; devalarm_start(&alarms[alarm_type], timespec_to_ktime(*ts)); devalarm_start(&alarms[alarm_type], timespec_to_ktime(*ts)); spin_unlock_irqrestore(&alarm_slock, flags); spin_unlock_irqrestore(&alarm_slock, flags); if (alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP) set_power_on_alarm(ts->tv_sec); } } static int alarm_wait(void) static int alarm_wait(void) Loading Loading @@ -181,6 +188,7 @@ static int alarm_get_time(enum android_alarm_type alarm_type, switch (alarm_type) { switch (alarm_type) { case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_RTC: case ANDROID_ALARM_RTC: case ANDROID_ALARM_RTC_POWEROFF_WAKEUP: getnstimeofday(ts); getnstimeofday(ts); break; break; case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: Loading Loading @@ -421,6 +429,8 @@ static int __init alarm_dev_init(void) CLOCK_BOOTTIME, HRTIMER_MODE_ABS); CLOCK_BOOTTIME, HRTIMER_MODE_ABS); hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt, hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); CLOCK_MONOTONIC, HRTIMER_MODE_ABS); alarm_init(&alarms[ANDROID_ALARM_RTC_POWEROFF_WAKEUP].u.alrm, ALARM_REALTIME, devalarm_alarmhandler); for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { alarms[i].type = i; alarms[i].type = i; Loading
drivers/staging/android/android_alarm.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ enum android_alarm_type { ANDROID_ALARM_RTC, ANDROID_ALARM_RTC, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, ANDROID_ALARM_ELAPSED_REALTIME, ANDROID_ALARM_ELAPSED_REALTIME, ANDROID_ALARM_RTC_POWEROFF_WAKEUP, ANDROID_ALARM_SYSTEMTIME, ANDROID_ALARM_SYSTEMTIME, ANDROID_ALARM_TYPE_COUNT, ANDROID_ALARM_TYPE_COUNT, Loading @@ -41,6 +42,8 @@ enum android_alarm_return_flags { 1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, 1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, ANDROID_ALARM_ELAPSED_REALTIME_MASK = ANDROID_ALARM_ELAPSED_REALTIME_MASK = 1U << ANDROID_ALARM_ELAPSED_REALTIME, 1U << ANDROID_ALARM_ELAPSED_REALTIME, ANDROID_ALARM_RTC_POWEROFF_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_POWEROFF_WAKEUP, ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME, ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME, ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16 ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16 }; }; Loading
include/linux/alarmtimer.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -48,6 +48,7 @@ int alarm_start_relative(struct alarm *alarm, ktime_t start); void alarm_restart(struct alarm *alarm); void alarm_restart(struct alarm *alarm); int alarm_try_to_cancel(struct alarm *alarm); int alarm_try_to_cancel(struct alarm *alarm); int alarm_cancel(struct alarm *alarm); int alarm_cancel(struct alarm *alarm); void set_power_on_alarm(long secs); u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval); u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval); u64 alarm_forward_now(struct alarm *alarm, ktime_t interval); u64 alarm_forward_now(struct alarm *alarm, ktime_t interval); Loading
kernel/time/alarmtimer.c +51 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,8 @@ #include <linux/workqueue.h> #include <linux/workqueue.h> #include <linux/freezer.h> #include <linux/freezer.h> #define ALARM_DELTA 120 /** /** * struct alarm_base - Alarm timer bases * struct alarm_base - Alarm timer bases * @lock: Lock for syncrhonized access to the base * @lock: Lock for syncrhonized access to the base Loading @@ -52,6 +54,54 @@ static struct wakeup_source *ws; static struct rtc_timer rtctimer; static struct rtc_timer rtctimer; static struct rtc_device *rtcdev; static struct rtc_device *rtcdev; static DEFINE_SPINLOCK(rtcdev_lock); static DEFINE_SPINLOCK(rtcdev_lock); static unsigned long power_on_alarm; static struct mutex power_on_alarm_lock; void set_power_on_alarm(long secs) { int rc; long rtc_secs, alarm_time; struct rtc_time rtc_time; struct rtc_wkalrm alarm; rc = mutex_lock_interruptible(&power_on_alarm_lock); if (rc != 0) return; rtc_read_time(rtcdev, &rtc_time); rtc_tm_to_time(&rtc_time, &rtc_secs); if (!secs) goto disable_alarm; else power_on_alarm = secs + rtc_secs; alarm_time = power_on_alarm; /* *Substract ALARM_DELTA from actual alarm time *to power up the device before actual alarm *expiration */ if ((alarm_time - ALARM_DELTA) > rtc_secs) alarm_time -= ALARM_DELTA; if (alarm_time <= rtc_secs) goto disable_alarm; rtc_time_to_tm(alarm_time, &alarm.time); alarm.enabled = 1; rc = rtc_set_alarm(rtcdev, &alarm); if (rc) goto disable_alarm; mutex_unlock(&power_on_alarm_lock); return; disable_alarm: rtc_alarm_irq_enable(rtcdev, 0); mutex_unlock(&power_on_alarm_lock); } static void alarmtimer_triggered_func(void *p) static void alarmtimer_triggered_func(void *p) { { Loading Loading @@ -837,6 +887,7 @@ static int __init alarmtimer_init(void) .nsleep = alarm_timer_nsleep, .nsleep = alarm_timer_nsleep, }; }; mutex_init(&power_on_alarm_lock); alarmtimer_rtc_timer_init(); alarmtimer_rtc_timer_init(); posix_timers_register_clock(CLOCK_REALTIME_ALARM, &alarm_clock); posix_timers_register_clock(CLOCK_REALTIME_ALARM, &alarm_clock); Loading