diff options
author | John Stultz <john.stultz@linaro.org> | 2012-04-20 15:31:44 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-04-20 17:53:37 -0400 |
commit | e2d8ccef0a8e8aedaf401edca6ad54663b0da24b (patch) | |
tree | d0b2fa630e7d638527448be8ad8fba0c110a2269 | |
parent | 8f9064a8a3b9f0dfd53bb0dfb3bbbfb457dda4bb (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.c | 3 | ||||
-rw-r--r-- | drivers/staging/android/alarm.c | 70 | ||||
-rw-r--r-- | drivers/staging/android/android_alarm.h | 7 |
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 | */ | ||
318 | ktime_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 | |||
331 | static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) | 308 | static 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 | ||
539 | static 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 | |||
560 | static int __init alarm_driver_init(void) | 515 | static 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 | ||
598 | late_initcall(alarm_late_init); | ||
599 | module_init(alarm_driver_init); | 559 | module_init(alarm_driver_init); |
600 | module_exit(alarm_exit); | 560 | module_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); |
72 | int android_alarm_try_to_cancel(struct android_alarm *alarm); | 73 | int android_alarm_try_to_cancel(struct android_alarm *alarm); |
73 | int android_alarm_cancel(struct android_alarm *alarm); | 74 | int android_alarm_cancel(struct android_alarm *alarm); |
74 | ktime_t alarm_get_elapsed_realtime(void); | 75 | |
76 | static 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 */ |
77 | int android_alarm_set_rtc(const struct timespec ts); | 82 | int android_alarm_set_rtc(const struct timespec ts); |