aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2012-04-20 15:31:44 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-20 17:53:37 -0400
commite2d8ccef0a8e8aedaf401edca6ad54663b0da24b (patch)
treed0b2fa630e7d638527448be8ad8fba0c110a2269
parent8f9064a8a3b9f0dfd53bb0dfb3bbbfb457dda4bb (diff)
staging: android-alarm: Convert ALARM_ELAPSED_REALTIME to use CLOCK_BOOTTIME
The ALARM_ELAPSED_REALTIME clock domain in Android pointed to the need for something similar in linux system-wide (instead of limited to just the alarm interface). Thus CLOCK_BOOTTIME was introduced into the upstream kernel in 2.6.39. This patch attempts to convert the android alarm timer to utilize the kernel's CLOCK_BOOTTIME clockid for ALARM_ELAPSED_REALTIME, instead of managing it itself. CC: Colin Cross <ccross@android.com> CC: Thomas Gleixner <tglx@linutronix.de> CC: Android Kernel Team <kernel-team@android.com> Signed-off-by: John Stultz <john.stultz@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/android/alarm-dev.c3
-rw-r--r--drivers/staging/android/alarm.c70
-rw-r--r--drivers/staging/android/android_alarm.h7
3 files changed, 22 insertions, 58 deletions
diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c
index 1b618f328115..3840ca22d835 100644
--- a/drivers/staging/android/alarm-dev.c
+++ b/drivers/staging/android/alarm-dev.c
@@ -179,8 +179,7 @@ from_old_alarm_set:
179 break; 179 break;
180 case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: 180 case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP:
181 case ANDROID_ALARM_ELAPSED_REALTIME: 181 case ANDROID_ALARM_ELAPSED_REALTIME:
182 tmp_time = 182 get_monotonic_boottime(&tmp_time);
183 ktime_to_timespec(alarm_get_elapsed_realtime());
184 break; 183 break;
185 case ANDROID_ALARM_TYPE_COUNT: 184 case ANDROID_ALARM_TYPE_COUNT:
186 case ANDROID_ALARM_SYSTEMTIME: 185 case ANDROID_ALARM_SYSTEMTIME:
diff --git a/drivers/staging/android/alarm.c b/drivers/staging/android/alarm.c
index 0cae132fbfd7..22b18d1f1fe8 100644
--- a/drivers/staging/android/alarm.c
+++ b/drivers/staging/android/alarm.c
@@ -65,7 +65,6 @@ struct alarm_queue {
65 struct rb_root alarms; 65 struct rb_root alarms;
66 struct rb_node *first; 66 struct rb_node *first;
67 struct hrtimer timer; 67 struct hrtimer timer;
68 ktime_t delta;
69 bool stopped; 68 bool stopped;
70 ktime_t stopped_time; 69 ktime_t stopped_time;
71}; 70};
@@ -107,8 +106,8 @@ static void update_timer_locked(struct alarm_queue *base, bool head_removed)
107 } 106 }
108 107
109 hrtimer_try_to_cancel(&base->timer); 108 hrtimer_try_to_cancel(&base->timer);
110 base->timer.node.expires = ktime_add(base->delta, alarm->expires); 109 base->timer.node.expires = alarm->expires;
111 base->timer._softexpires = ktime_add(base->delta, alarm->softexpires); 110 base->timer._softexpires = alarm->softexpires;
112 hrtimer_start_expires(&base->timer, HRTIMER_MODE_ABS); 111 hrtimer_start_expires(&base->timer, HRTIMER_MODE_ABS);
113} 112}
114 113
@@ -279,10 +278,6 @@ int android_alarm_set_rtc(struct timespec new_time)
279 alarms[i].stopped = true; 278 alarms[i].stopped = true;
280 alarms[i].stopped_time = timespec_to_ktime(tmp_time); 279 alarms[i].stopped_time = timespec_to_ktime(tmp_time);
281 } 280 }
282 alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta =
283 alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta =
284 ktime_sub(alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta,
285 timespec_to_ktime(timespec_sub(tmp_time, new_time)));
286 spin_unlock_irqrestore(&alarm_slock, flags); 281 spin_unlock_irqrestore(&alarm_slock, flags);
287 ret = do_settimeofday(&new_time); 282 ret = do_settimeofday(&new_time);
288 spin_lock_irqsave(&alarm_slock, flags); 283 spin_lock_irqsave(&alarm_slock, flags);
@@ -310,24 +305,6 @@ err:
310 return ret; 305 return ret;
311} 306}
312 307
313/**
314 * alarm_get_elapsed_realtime - get the elapsed real time in ktime_t format
315 *
316 * returns the time in ktime_t format
317 */
318ktime_t alarm_get_elapsed_realtime(void)
319{
320 ktime_t now;
321 unsigned long flags;
322 struct alarm_queue *base = &alarms[ANDROID_ALARM_ELAPSED_REALTIME];
323
324 spin_lock_irqsave(&alarm_slock, flags);
325 now = base->stopped ? base->stopped_time : ktime_get_real();
326 now = ktime_sub(now, base->delta);
327 spin_unlock_irqrestore(&alarm_slock, flags);
328 return now;
329}
330
331static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) 308static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer)
332{ 309{
333 struct alarm_queue *base; 310 struct alarm_queue *base;
@@ -339,7 +316,6 @@ static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer)
339 316
340 base = container_of(timer, struct alarm_queue, timer); 317 base = container_of(timer, struct alarm_queue, timer);
341 now = base->stopped ? base->stopped_time : hrtimer_cb_get_time(timer); 318 now = base->stopped ? base->stopped_time : hrtimer_cb_get_time(timer);
342 now = ktime_sub(now, base->delta);
343 319
344 pr_alarm(INT, "alarm_timer_triggered type %td at %lld\n", 320 pr_alarm(INT, "alarm_timer_triggered type %td at %lld\n",
345 base - alarms, ktime_to_ns(now)); 321 base - alarms, ktime_to_ns(now));
@@ -536,40 +512,25 @@ static struct platform_driver alarm_driver = {
536 } 512 }
537}; 513};
538 514
539static int __init alarm_late_init(void)
540{
541 unsigned long flags;
542 struct timespec tmp_time, system_time;
543
544 /* this needs to run after the rtc is read at boot */
545 spin_lock_irqsave(&alarm_slock, flags);
546 /* We read the current rtc and system time so we can later calculate
547 * elasped realtime to be (boot_systemtime + rtc - boot_rtc) ==
548 * (rtc - (boot_rtc - boot_systemtime))
549 */
550 getnstimeofday(&tmp_time);
551 ktime_get_ts(&system_time);
552 alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta =
553 alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta =
554 timespec_to_ktime(timespec_sub(tmp_time, system_time));
555
556 spin_unlock_irqrestore(&alarm_slock, flags);
557 return 0;
558}
559
560static int __init alarm_driver_init(void) 515static int __init alarm_driver_init(void)
561{ 516{
562 int err; 517 int err;
563 int i; 518 int i;
564 519
565 for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { 520 hrtimer_init(&alarms[ANDROID_ALARM_RTC_WAKEUP].timer,
566 hrtimer_init(&alarms[i].timer, 521 CLOCK_REALTIME, HRTIMER_MODE_ABS);
567 CLOCK_REALTIME, HRTIMER_MODE_ABS); 522 hrtimer_init(&alarms[ANDROID_ALARM_RTC].timer,
568 alarms[i].timer.function = alarm_timer_triggered; 523 CLOCK_REALTIME, HRTIMER_MODE_ABS);
569 } 524 hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].timer,
525 CLOCK_BOOTTIME, HRTIMER_MODE_ABS);
526 hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME].timer,
527 CLOCK_BOOTTIME, HRTIMER_MODE_ABS);
570 hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].timer, 528 hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].timer,
571 CLOCK_MONOTONIC, HRTIMER_MODE_ABS); 529 CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
572 alarms[ANDROID_ALARM_SYSTEMTIME].timer.function = alarm_timer_triggered; 530
531 for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++)
532 alarms[i].timer.function = alarm_timer_triggered;
533
573 err = platform_driver_register(&alarm_driver); 534 err = platform_driver_register(&alarm_driver);
574 if (err < 0) 535 if (err < 0)
575 goto err1; 536 goto err1;
@@ -595,7 +556,6 @@ static void __exit alarm_exit(void)
595 platform_driver_unregister(&alarm_driver); 556 platform_driver_unregister(&alarm_driver);
596} 557}
597 558
598late_initcall(alarm_late_init);
599module_init(alarm_driver_init); 559module_init(alarm_driver_init);
600module_exit(alarm_exit); 560module_exit(alarm_exit);
601 561
diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h
index e586caef4ba8..a1121772bc2e 100644
--- a/drivers/staging/android/android_alarm.h
+++ b/drivers/staging/android/android_alarm.h
@@ -37,6 +37,7 @@ enum android_alarm_type {
37 37
38#include <linux/ktime.h> 38#include <linux/ktime.h>
39#include <linux/rbtree.h> 39#include <linux/rbtree.h>
40#include <linux/hrtimer.h>
40 41
41/* 42/*
42 * The alarm interface is similar to the hrtimer interface but adds support 43 * The alarm interface is similar to the hrtimer interface but adds support
@@ -71,7 +72,11 @@ void android_alarm_start_range(struct android_alarm *alarm, ktime_t start,
71 ktime_t end); 72 ktime_t end);
72int android_alarm_try_to_cancel(struct android_alarm *alarm); 73int android_alarm_try_to_cancel(struct android_alarm *alarm);
73int android_alarm_cancel(struct android_alarm *alarm); 74int android_alarm_cancel(struct android_alarm *alarm);
74ktime_t alarm_get_elapsed_realtime(void); 75
76static inline ktime_t alarm_get_elapsed_realtime(void)
77{
78 return ktime_get_boottime();
79}
75 80
76/* set rtc while preserving elapsed realtime */ 81/* set rtc while preserving elapsed realtime */
77int android_alarm_set_rtc(const struct timespec ts); 82int android_alarm_set_rtc(const struct timespec ts);