diff options
author | John Stultz <john.stultz@linaro.org> | 2012-04-20 15:31:47 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-04-20 18:06:25 -0400 |
commit | ef2353d26bdc44c78713da1a6eb2325ba9dac6f7 (patch) | |
tree | 4bf704bdf991bb2c22e4066e1c2bb89292f4482d | |
parent | b8793260980b0fc356af3bf11abea82650b0d595 (diff) |
android-alarm: Remove unused android alarm in-kernel interfaces
Now that alarm-dev.c uses the upstreamed alarmtimer interfaces,
we can remove the otherwise unused in-kernel android alarm api.
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/Kconfig | 21 | ||||
-rw-r--r-- | drivers/staging/android/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/android/alarm.c | 561 | ||||
-rw-r--r-- | drivers/staging/android/android_alarm.h | 64 |
4 files changed, 2 insertions, 645 deletions
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index 08a3b1133d29..84ac619ba87a 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig | |||
@@ -54,31 +54,14 @@ config ANDROID_LOW_MEMORY_KILLER | |||
54 | 54 | ||
55 | source "drivers/staging/android/switch/Kconfig" | 55 | source "drivers/staging/android/switch/Kconfig" |
56 | 56 | ||
57 | config ANDROID_INTF_ALARM | 57 | config ANDROID_INTF_ALARM_DEV |
58 | bool "Android alarm driver" | 58 | bool "Android alarm driver" |
59 | depends on RTC_CLASS | 59 | depends on RTC_CLASS |
60 | default n | 60 | default n |
61 | help | 61 | help |
62 | Provides non-wakeup and rtc backed wakeup alarms based on rtc or | 62 | Provides non-wakeup and rtc backed wakeup alarms based on rtc or |
63 | elapsed realtime, and a non-wakeup alarm on the monotonic clock. | 63 | elapsed realtime, and a non-wakeup alarm on the monotonic clock. |
64 | Also provides an interface to set the wall time which must be used | 64 | Also exports the alarm interface to user-space. |
65 | for elapsed realtime to work. | ||
66 | |||
67 | config ANDROID_INTF_ALARM_DEV | ||
68 | bool "Android alarm device" | ||
69 | depends on ANDROID_INTF_ALARM | ||
70 | default y | ||
71 | help | ||
72 | Exports the alarm interface to user-space. | ||
73 | |||
74 | config ANDROID_ALARM_OLDDRV_COMPAT | ||
75 | bool "Android Alarm compatability with old drivers" | ||
76 | depends on ANDROID_INTF_ALARM | ||
77 | default n | ||
78 | help | ||
79 | Provides preprocessor alias to aid compatability with | ||
80 | older out-of-tree drivers that use the Android Alarm | ||
81 | in-kernel API. This will be removed eventually. | ||
82 | 65 | ||
83 | endif # if ANDROID | 66 | endif # if ANDROID |
84 | 67 | ||
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index 9b6c9ed91f69..b4be69f80d78 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile | |||
@@ -7,5 +7,4 @@ obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o | |||
7 | obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o | 7 | obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o |
8 | obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o | 8 | obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o |
9 | obj-$(CONFIG_ANDROID_SWITCH) += switch/ | 9 | obj-$(CONFIG_ANDROID_SWITCH) += switch/ |
10 | obj-$(CONFIG_ANDROID_INTF_ALARM) += alarm.o | ||
11 | obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o | 10 | obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o |
diff --git a/drivers/staging/android/alarm.c b/drivers/staging/android/alarm.c deleted file mode 100644 index 22b18d1f1fe8..000000000000 --- a/drivers/staging/android/alarm.c +++ /dev/null | |||
@@ -1,561 +0,0 @@ | |||
1 | /* drivers/rtc/alarm.c | ||
2 | * | ||
3 | * Copyright (C) 2007-2009 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/time.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/device.h> | ||
19 | #include <linux/miscdevice.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/rtc.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/spinlock.h> | ||
24 | #include "android_alarm.h" | ||
25 | |||
26 | /* XXX - Hack out wakelocks, while they are out of tree */ | ||
27 | struct wake_lock { | ||
28 | int i; | ||
29 | }; | ||
30 | #define wake_lock(x) | ||
31 | #define wake_lock_timeout(x, y) | ||
32 | #define wake_unlock(x) | ||
33 | #define WAKE_LOCK_SUSPEND 0 | ||
34 | #define wake_lock_init(x, y, z) ((x)->i = 1) | ||
35 | #define wake_lock_destroy(x) | ||
36 | |||
37 | #define ANDROID_ALARM_PRINT_ERROR (1U << 0) | ||
38 | #define ANDROID_ALARM_PRINT_INIT_STATUS (1U << 1) | ||
39 | #define ANDROID_ALARM_PRINT_TSET (1U << 2) | ||
40 | #define ANDROID_ALARM_PRINT_CALL (1U << 3) | ||
41 | #define ANDROID_ALARM_PRINT_SUSPEND (1U << 4) | ||
42 | #define ANDROID_ALARM_PRINT_INT (1U << 5) | ||
43 | #define ANDROID_ALARM_PRINT_FLOW (1U << 6) | ||
44 | |||
45 | static int debug_mask = ANDROID_ALARM_PRINT_ERROR | \ | ||
46 | ANDROID_ALARM_PRINT_INIT_STATUS; | ||
47 | module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); | ||
48 | |||
49 | #define pr_alarm(debug_level_mask, args...) \ | ||
50 | do { \ | ||
51 | if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) { \ | ||
52 | pr_info(args); \ | ||
53 | } \ | ||
54 | } while (0) | ||
55 | |||
56 | #define ANDROID_ALARM_WAKEUP_MASK ( \ | ||
57 | ANDROID_ALARM_RTC_WAKEUP_MASK | \ | ||
58 | ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) | ||
59 | |||
60 | /* support old userspace code */ | ||
61 | #define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */ | ||
62 | #define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t) | ||
63 | |||
64 | struct alarm_queue { | ||
65 | struct rb_root alarms; | ||
66 | struct rb_node *first; | ||
67 | struct hrtimer timer; | ||
68 | bool stopped; | ||
69 | ktime_t stopped_time; | ||
70 | }; | ||
71 | |||
72 | static struct rtc_device *alarm_rtc_dev; | ||
73 | static DEFINE_SPINLOCK(alarm_slock); | ||
74 | static DEFINE_MUTEX(alarm_setrtc_mutex); | ||
75 | static struct wake_lock alarm_rtc_wake_lock; | ||
76 | static struct platform_device *alarm_platform_dev; | ||
77 | struct alarm_queue alarms[ANDROID_ALARM_TYPE_COUNT]; | ||
78 | static bool suspended; | ||
79 | |||
80 | static void update_timer_locked(struct alarm_queue *base, bool head_removed) | ||
81 | { | ||
82 | struct android_alarm *alarm; | ||
83 | bool is_wakeup = base == &alarms[ANDROID_ALARM_RTC_WAKEUP] || | ||
84 | base == &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]; | ||
85 | |||
86 | if (base->stopped) { | ||
87 | pr_alarm(FLOW, "changed alarm while setting the wall time\n"); | ||
88 | return; | ||
89 | } | ||
90 | |||
91 | if (is_wakeup && !suspended && head_removed) | ||
92 | wake_unlock(&alarm_rtc_wake_lock); | ||
93 | |||
94 | if (!base->first) | ||
95 | return; | ||
96 | |||
97 | alarm = container_of(base->first, struct android_alarm, node); | ||
98 | |||
99 | pr_alarm(FLOW, "selected alarm, type %d, func %pF at %lld\n", | ||
100 | alarm->type, alarm->function, ktime_to_ns(alarm->expires)); | ||
101 | |||
102 | if (is_wakeup && suspended) { | ||
103 | pr_alarm(FLOW, "changed alarm while suspened\n"); | ||
104 | wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ); | ||
105 | return; | ||
106 | } | ||
107 | |||
108 | hrtimer_try_to_cancel(&base->timer); | ||
109 | base->timer.node.expires = alarm->expires; | ||
110 | base->timer._softexpires = alarm->softexpires; | ||
111 | hrtimer_start_expires(&base->timer, HRTIMER_MODE_ABS); | ||
112 | } | ||
113 | |||
114 | static void alarm_enqueue_locked(struct android_alarm *alarm) | ||
115 | { | ||
116 | struct alarm_queue *base = &alarms[alarm->type]; | ||
117 | struct rb_node **link = &base->alarms.rb_node; | ||
118 | struct rb_node *parent = NULL; | ||
119 | struct android_alarm *entry; | ||
120 | int leftmost = 1; | ||
121 | bool was_first = false; | ||
122 | |||
123 | pr_alarm(FLOW, "added alarm, type %d, func %pF at %lld\n", | ||
124 | alarm->type, alarm->function, ktime_to_ns(alarm->expires)); | ||
125 | |||
126 | if (base->first == &alarm->node) { | ||
127 | base->first = rb_next(&alarm->node); | ||
128 | was_first = true; | ||
129 | } | ||
130 | if (!RB_EMPTY_NODE(&alarm->node)) { | ||
131 | rb_erase(&alarm->node, &base->alarms); | ||
132 | RB_CLEAR_NODE(&alarm->node); | ||
133 | } | ||
134 | |||
135 | while (*link) { | ||
136 | parent = *link; | ||
137 | entry = rb_entry(parent, struct android_alarm, node); | ||
138 | /* | ||
139 | * We dont care about collisions. Nodes with | ||
140 | * the same expiry time stay together. | ||
141 | */ | ||
142 | if (alarm->expires.tv64 < entry->expires.tv64) { | ||
143 | link = &(*link)->rb_left; | ||
144 | } else { | ||
145 | link = &(*link)->rb_right; | ||
146 | leftmost = 0; | ||
147 | } | ||
148 | } | ||
149 | if (leftmost) | ||
150 | base->first = &alarm->node; | ||
151 | if (leftmost || was_first) | ||
152 | update_timer_locked(base, was_first); | ||
153 | |||
154 | rb_link_node(&alarm->node, parent, link); | ||
155 | rb_insert_color(&alarm->node, &base->alarms); | ||
156 | } | ||
157 | |||
158 | /** | ||
159 | * android_alarm_init - initialize an alarm | ||
160 | * @alarm: the alarm to be initialized | ||
161 | * @type: the alarm type to be used | ||
162 | * @function: alarm callback function | ||
163 | */ | ||
164 | void android_alarm_init(struct android_alarm *alarm, | ||
165 | enum android_alarm_type type, void (*function)(struct android_alarm *)) | ||
166 | { | ||
167 | RB_CLEAR_NODE(&alarm->node); | ||
168 | alarm->type = type; | ||
169 | alarm->function = function; | ||
170 | |||
171 | pr_alarm(FLOW, "created alarm, type %d, func %pF\n", type, function); | ||
172 | } | ||
173 | |||
174 | |||
175 | /** | ||
176 | * android_alarm_start_range - (re)start an alarm | ||
177 | * @alarm: the alarm to be added | ||
178 | * @start: earliest expiry time | ||
179 | * @end: expiry time | ||
180 | */ | ||
181 | void android_alarm_start_range(struct android_alarm *alarm, ktime_t start, | ||
182 | ktime_t end) | ||
183 | { | ||
184 | unsigned long flags; | ||
185 | |||
186 | spin_lock_irqsave(&alarm_slock, flags); | ||
187 | alarm->softexpires = start; | ||
188 | alarm->expires = end; | ||
189 | alarm_enqueue_locked(alarm); | ||
190 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
191 | } | ||
192 | |||
193 | /** | ||
194 | * android_alarm_try_to_cancel - try to deactivate an alarm | ||
195 | * @alarm: alarm to stop | ||
196 | * | ||
197 | * Returns: | ||
198 | * 0 when the alarm was not active | ||
199 | * 1 when the alarm was active | ||
200 | * -1 when the alarm may currently be excuting the callback function and | ||
201 | * cannot be stopped (it may also be inactive) | ||
202 | */ | ||
203 | int android_alarm_try_to_cancel(struct android_alarm *alarm) | ||
204 | { | ||
205 | struct alarm_queue *base = &alarms[alarm->type]; | ||
206 | unsigned long flags; | ||
207 | bool first = false; | ||
208 | int ret = 0; | ||
209 | |||
210 | spin_lock_irqsave(&alarm_slock, flags); | ||
211 | if (!RB_EMPTY_NODE(&alarm->node)) { | ||
212 | pr_alarm(FLOW, "canceled alarm, type %d, func %pF at %lld\n", | ||
213 | alarm->type, alarm->function, | ||
214 | ktime_to_ns(alarm->expires)); | ||
215 | ret = 1; | ||
216 | if (base->first == &alarm->node) { | ||
217 | base->first = rb_next(&alarm->node); | ||
218 | first = true; | ||
219 | } | ||
220 | rb_erase(&alarm->node, &base->alarms); | ||
221 | RB_CLEAR_NODE(&alarm->node); | ||
222 | if (first) | ||
223 | update_timer_locked(base, true); | ||
224 | } else | ||
225 | pr_alarm(FLOW, "tried to cancel alarm, type %d, func %pF\n", | ||
226 | alarm->type, alarm->function); | ||
227 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
228 | if (!ret && hrtimer_callback_running(&base->timer)) | ||
229 | ret = -1; | ||
230 | return ret; | ||
231 | } | ||
232 | |||
233 | /** | ||
234 | * android_alarm_cancel - cancel an alarm and wait for the handler to finish. | ||
235 | * @alarm: the alarm to be cancelled | ||
236 | * | ||
237 | * Returns: | ||
238 | * 0 when the alarm was not active | ||
239 | * 1 when the alarm was active | ||
240 | */ | ||
241 | int android_alarm_cancel(struct android_alarm *alarm) | ||
242 | { | ||
243 | for (;;) { | ||
244 | int ret = android_alarm_try_to_cancel(alarm); | ||
245 | if (ret >= 0) | ||
246 | return ret; | ||
247 | cpu_relax(); | ||
248 | } | ||
249 | } | ||
250 | |||
251 | /** | ||
252 | * alarm_set_rtc - set the kernel and rtc walltime | ||
253 | * @new_time: timespec value containing the new time | ||
254 | */ | ||
255 | int android_alarm_set_rtc(struct timespec new_time) | ||
256 | { | ||
257 | int i; | ||
258 | int ret; | ||
259 | unsigned long flags; | ||
260 | struct rtc_time rtc_new_rtc_time; | ||
261 | struct timespec tmp_time; | ||
262 | |||
263 | rtc_time_to_tm(new_time.tv_sec, &rtc_new_rtc_time); | ||
264 | |||
265 | pr_alarm(TSET, "set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n", | ||
266 | new_time.tv_sec, new_time.tv_nsec, | ||
267 | rtc_new_rtc_time.tm_hour, rtc_new_rtc_time.tm_min, | ||
268 | rtc_new_rtc_time.tm_sec, rtc_new_rtc_time.tm_mon + 1, | ||
269 | rtc_new_rtc_time.tm_mday, | ||
270 | rtc_new_rtc_time.tm_year + 1900); | ||
271 | |||
272 | mutex_lock(&alarm_setrtc_mutex); | ||
273 | spin_lock_irqsave(&alarm_slock, flags); | ||
274 | wake_lock(&alarm_rtc_wake_lock); | ||
275 | getnstimeofday(&tmp_time); | ||
276 | for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { | ||
277 | hrtimer_try_to_cancel(&alarms[i].timer); | ||
278 | alarms[i].stopped = true; | ||
279 | alarms[i].stopped_time = timespec_to_ktime(tmp_time); | ||
280 | } | ||
281 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
282 | ret = do_settimeofday(&new_time); | ||
283 | spin_lock_irqsave(&alarm_slock, flags); | ||
284 | for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { | ||
285 | alarms[i].stopped = false; | ||
286 | update_timer_locked(&alarms[i], false); | ||
287 | } | ||
288 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
289 | if (ret < 0) { | ||
290 | pr_alarm(ERROR, "alarm_set_rtc: Failed to set time\n"); | ||
291 | goto err; | ||
292 | } | ||
293 | if (!alarm_rtc_dev) { | ||
294 | pr_alarm(ERROR, | ||
295 | "alarm_set_rtc: no RTC, time will be lost on reboot\n"); | ||
296 | goto err; | ||
297 | } | ||
298 | ret = rtc_set_time(alarm_rtc_dev, &rtc_new_rtc_time); | ||
299 | if (ret < 0) | ||
300 | pr_alarm(ERROR, "alarm_set_rtc: " | ||
301 | "Failed to set RTC, time will be lost on reboot\n"); | ||
302 | err: | ||
303 | wake_unlock(&alarm_rtc_wake_lock); | ||
304 | mutex_unlock(&alarm_setrtc_mutex); | ||
305 | return ret; | ||
306 | } | ||
307 | |||
308 | static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) | ||
309 | { | ||
310 | struct alarm_queue *base; | ||
311 | struct android_alarm *alarm; | ||
312 | unsigned long flags; | ||
313 | ktime_t now; | ||
314 | |||
315 | spin_lock_irqsave(&alarm_slock, flags); | ||
316 | |||
317 | base = container_of(timer, struct alarm_queue, timer); | ||
318 | now = base->stopped ? base->stopped_time : hrtimer_cb_get_time(timer); | ||
319 | |||
320 | pr_alarm(INT, "alarm_timer_triggered type %td at %lld\n", | ||
321 | base - alarms, ktime_to_ns(now)); | ||
322 | |||
323 | while (base->first) { | ||
324 | alarm = container_of(base->first, struct android_alarm, node); | ||
325 | if (alarm->softexpires.tv64 > now.tv64) { | ||
326 | pr_alarm(FLOW, "don't call alarm, %pF, %lld (s %lld)\n", | ||
327 | alarm->function, ktime_to_ns(alarm->expires), | ||
328 | ktime_to_ns(alarm->softexpires)); | ||
329 | break; | ||
330 | } | ||
331 | base->first = rb_next(&alarm->node); | ||
332 | rb_erase(&alarm->node, &base->alarms); | ||
333 | RB_CLEAR_NODE(&alarm->node); | ||
334 | pr_alarm(CALL, "call alarm, type %d, func %pF, %lld (s %lld)\n", | ||
335 | alarm->type, alarm->function, | ||
336 | ktime_to_ns(alarm->expires), | ||
337 | ktime_to_ns(alarm->softexpires)); | ||
338 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
339 | alarm->function(alarm); | ||
340 | spin_lock_irqsave(&alarm_slock, flags); | ||
341 | } | ||
342 | if (!base->first) | ||
343 | pr_alarm(FLOW, "no more alarms of type %td\n", base - alarms); | ||
344 | update_timer_locked(base, true); | ||
345 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
346 | return HRTIMER_NORESTART; | ||
347 | } | ||
348 | |||
349 | static void alarm_triggered_func(void *p) | ||
350 | { | ||
351 | struct rtc_device *rtc = alarm_rtc_dev; | ||
352 | if (!(rtc->irq_data & RTC_AF)) | ||
353 | return; | ||
354 | pr_alarm(INT, "rtc alarm triggered\n"); | ||
355 | wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ); | ||
356 | } | ||
357 | |||
358 | static int alarm_suspend(struct platform_device *pdev, pm_message_t state) | ||
359 | { | ||
360 | int err = 0; | ||
361 | unsigned long flags; | ||
362 | struct rtc_wkalrm rtc_alarm; | ||
363 | struct rtc_time rtc_current_rtc_time; | ||
364 | unsigned long rtc_current_time; | ||
365 | unsigned long rtc_alarm_time; | ||
366 | struct timespec rtc_delta; | ||
367 | struct timespec wall_time; | ||
368 | struct alarm_queue *wakeup_queue = NULL; | ||
369 | struct alarm_queue *tmp_queue = NULL; | ||
370 | |||
371 | pr_alarm(SUSPEND, "alarm_suspend(%p, %d)\n", pdev, state.event); | ||
372 | |||
373 | spin_lock_irqsave(&alarm_slock, flags); | ||
374 | suspended = true; | ||
375 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
376 | |||
377 | hrtimer_cancel(&alarms[ANDROID_ALARM_RTC_WAKEUP].timer); | ||
378 | hrtimer_cancel(&alarms[ | ||
379 | ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].timer); | ||
380 | |||
381 | tmp_queue = &alarms[ANDROID_ALARM_RTC_WAKEUP]; | ||
382 | if (tmp_queue->first) | ||
383 | wakeup_queue = tmp_queue; | ||
384 | tmp_queue = &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]; | ||
385 | if (tmp_queue->first && (!wakeup_queue || | ||
386 | hrtimer_get_expires(&tmp_queue->timer).tv64 < | ||
387 | hrtimer_get_expires(&wakeup_queue->timer).tv64)) | ||
388 | wakeup_queue = tmp_queue; | ||
389 | if (wakeup_queue) { | ||
390 | rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); | ||
391 | getnstimeofday(&wall_time); | ||
392 | rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time); | ||
393 | set_normalized_timespec(&rtc_delta, | ||
394 | wall_time.tv_sec - rtc_current_time, | ||
395 | wall_time.tv_nsec); | ||
396 | |||
397 | rtc_alarm_time = timespec_sub(ktime_to_timespec( | ||
398 | hrtimer_get_expires(&wakeup_queue->timer)), | ||
399 | rtc_delta).tv_sec; | ||
400 | |||
401 | rtc_time_to_tm(rtc_alarm_time, &rtc_alarm.time); | ||
402 | rtc_alarm.enabled = 1; | ||
403 | rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); | ||
404 | rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); | ||
405 | rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time); | ||
406 | pr_alarm(SUSPEND, | ||
407 | "rtc alarm set at %ld, now %ld, rtc delta %ld.%09ld\n", | ||
408 | rtc_alarm_time, rtc_current_time, | ||
409 | rtc_delta.tv_sec, rtc_delta.tv_nsec); | ||
410 | if (rtc_current_time + 1 >= rtc_alarm_time) { | ||
411 | pr_alarm(SUSPEND, "alarm about to go off\n"); | ||
412 | memset(&rtc_alarm, 0, sizeof(rtc_alarm)); | ||
413 | rtc_alarm.enabled = 0; | ||
414 | rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); | ||
415 | |||
416 | spin_lock_irqsave(&alarm_slock, flags); | ||
417 | suspended = false; | ||
418 | wake_lock_timeout(&alarm_rtc_wake_lock, 2 * HZ); | ||
419 | update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP], | ||
420 | false); | ||
421 | update_timer_locked(&alarms[ | ||
422 | ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP], false); | ||
423 | err = -EBUSY; | ||
424 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
425 | } | ||
426 | } | ||
427 | return err; | ||
428 | } | ||
429 | |||
430 | static int alarm_resume(struct platform_device *pdev) | ||
431 | { | ||
432 | struct rtc_wkalrm alarm; | ||
433 | unsigned long flags; | ||
434 | |||
435 | pr_alarm(SUSPEND, "alarm_resume(%p)\n", pdev); | ||
436 | |||
437 | memset(&alarm, 0, sizeof(alarm)); | ||
438 | alarm.enabled = 0; | ||
439 | rtc_set_alarm(alarm_rtc_dev, &alarm); | ||
440 | |||
441 | spin_lock_irqsave(&alarm_slock, flags); | ||
442 | suspended = false; | ||
443 | update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP], false); | ||
444 | update_timer_locked(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP], | ||
445 | false); | ||
446 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
447 | |||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | static struct rtc_task alarm_rtc_task = { | ||
452 | .func = alarm_triggered_func | ||
453 | }; | ||
454 | |||
455 | static int rtc_alarm_add_device(struct device *dev, | ||
456 | struct class_interface *class_intf) | ||
457 | { | ||
458 | int err; | ||
459 | struct rtc_device *rtc = to_rtc_device(dev); | ||
460 | |||
461 | mutex_lock(&alarm_setrtc_mutex); | ||
462 | |||
463 | if (alarm_rtc_dev) { | ||
464 | err = -EBUSY; | ||
465 | goto err1; | ||
466 | } | ||
467 | |||
468 | alarm_platform_dev = | ||
469 | platform_device_register_simple("alarm", -1, NULL, 0); | ||
470 | if (IS_ERR(alarm_platform_dev)) { | ||
471 | err = PTR_ERR(alarm_platform_dev); | ||
472 | goto err2; | ||
473 | } | ||
474 | err = rtc_irq_register(rtc, &alarm_rtc_task); | ||
475 | if (err) | ||
476 | goto err3; | ||
477 | alarm_rtc_dev = rtc; | ||
478 | pr_alarm(INIT_STATUS, "using rtc device, %s, for alarms", rtc->name); | ||
479 | mutex_unlock(&alarm_setrtc_mutex); | ||
480 | |||
481 | return 0; | ||
482 | |||
483 | err3: | ||
484 | platform_device_unregister(alarm_platform_dev); | ||
485 | err2: | ||
486 | err1: | ||
487 | mutex_unlock(&alarm_setrtc_mutex); | ||
488 | return err; | ||
489 | } | ||
490 | |||
491 | static void rtc_alarm_remove_device(struct device *dev, | ||
492 | struct class_interface *class_intf) | ||
493 | { | ||
494 | if (dev == &alarm_rtc_dev->dev) { | ||
495 | pr_alarm(INIT_STATUS, "lost rtc device for alarms"); | ||
496 | rtc_irq_unregister(alarm_rtc_dev, &alarm_rtc_task); | ||
497 | platform_device_unregister(alarm_platform_dev); | ||
498 | alarm_rtc_dev = NULL; | ||
499 | } | ||
500 | } | ||
501 | |||
502 | static struct class_interface rtc_alarm_interface = { | ||
503 | .add_dev = &rtc_alarm_add_device, | ||
504 | .remove_dev = &rtc_alarm_remove_device, | ||
505 | }; | ||
506 | |||
507 | static struct platform_driver alarm_driver = { | ||
508 | .suspend = alarm_suspend, | ||
509 | .resume = alarm_resume, | ||
510 | .driver = { | ||
511 | .name = "alarm" | ||
512 | } | ||
513 | }; | ||
514 | |||
515 | static int __init alarm_driver_init(void) | ||
516 | { | ||
517 | int err; | ||
518 | int i; | ||
519 | |||
520 | hrtimer_init(&alarms[ANDROID_ALARM_RTC_WAKEUP].timer, | ||
521 | CLOCK_REALTIME, HRTIMER_MODE_ABS); | ||
522 | hrtimer_init(&alarms[ANDROID_ALARM_RTC].timer, | ||
523 | CLOCK_REALTIME, HRTIMER_MODE_ABS); | ||
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); | ||
528 | hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].timer, | ||
529 | CLOCK_MONOTONIC, HRTIMER_MODE_ABS); | ||
530 | |||
531 | for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) | ||
532 | alarms[i].timer.function = alarm_timer_triggered; | ||
533 | |||
534 | err = platform_driver_register(&alarm_driver); | ||
535 | if (err < 0) | ||
536 | goto err1; | ||
537 | wake_lock_init(&alarm_rtc_wake_lock, WAKE_LOCK_SUSPEND, "alarm_rtc"); | ||
538 | rtc_alarm_interface.class = rtc_class; | ||
539 | err = class_interface_register(&rtc_alarm_interface); | ||
540 | if (err < 0) | ||
541 | goto err2; | ||
542 | |||
543 | return 0; | ||
544 | |||
545 | err2: | ||
546 | wake_lock_destroy(&alarm_rtc_wake_lock); | ||
547 | platform_driver_unregister(&alarm_driver); | ||
548 | err1: | ||
549 | return err; | ||
550 | } | ||
551 | |||
552 | static void __exit alarm_exit(void) | ||
553 | { | ||
554 | class_interface_unregister(&rtc_alarm_interface); | ||
555 | wake_lock_destroy(&alarm_rtc_wake_lock); | ||
556 | platform_driver_unregister(&alarm_driver); | ||
557 | } | ||
558 | |||
559 | module_init(alarm_driver_init); | ||
560 | module_exit(alarm_exit); | ||
561 | |||
diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h index a1121772bc2e..d0cafd637199 100644 --- a/drivers/staging/android/android_alarm.h +++ b/drivers/staging/android/android_alarm.h | |||
@@ -33,70 +33,6 @@ enum android_alarm_type { | |||
33 | /* ANDROID_ALARM_TIME_CHANGE = 16 */ | 33 | /* ANDROID_ALARM_TIME_CHANGE = 16 */ |
34 | }; | 34 | }; |
35 | 35 | ||
36 | #ifdef __KERNEL__ | ||
37 | |||
38 | #include <linux/ktime.h> | ||
39 | #include <linux/rbtree.h> | ||
40 | #include <linux/hrtimer.h> | ||
41 | |||
42 | /* | ||
43 | * The alarm interface is similar to the hrtimer interface but adds support | ||
44 | * for wakeup from suspend. It also adds an elapsed realtime clock that can | ||
45 | * be used for periodic timers that need to keep running while the system is | ||
46 | * suspended and not be disrupted when the wall time is set. | ||
47 | */ | ||
48 | |||
49 | /** | ||
50 | * struct alarm - the basic alarm structure | ||
51 | * @node: red black tree node for time ordered insertion | ||
52 | * @type: alarm type. rtc/elapsed-realtime/systemtime, wakeup/non-wakeup. | ||
53 | * @softexpires: the absolute earliest expiry time of the alarm. | ||
54 | * @expires: the absolute expiry time. | ||
55 | * @function: alarm expiry callback function | ||
56 | * | ||
57 | * The alarm structure must be initialized by alarm_init() | ||
58 | * | ||
59 | */ | ||
60 | |||
61 | struct android_alarm { | ||
62 | struct rb_node node; | ||
63 | enum android_alarm_type type; | ||
64 | ktime_t softexpires; | ||
65 | ktime_t expires; | ||
66 | void (*function)(struct android_alarm *); | ||
67 | }; | ||
68 | |||
69 | void android_alarm_init(struct android_alarm *alarm, | ||
70 | enum android_alarm_type type, void (*function)(struct android_alarm *)); | ||
71 | void android_alarm_start_range(struct android_alarm *alarm, ktime_t start, | ||
72 | ktime_t end); | ||
73 | int android_alarm_try_to_cancel(struct android_alarm *alarm); | ||
74 | int android_alarm_cancel(struct android_alarm *alarm); | ||
75 | |||
76 | static inline ktime_t alarm_get_elapsed_realtime(void) | ||
77 | { | ||
78 | return ktime_get_boottime(); | ||
79 | } | ||
80 | |||
81 | /* set rtc while preserving elapsed realtime */ | ||
82 | int android_alarm_set_rtc(const struct timespec ts); | ||
83 | |||
84 | #ifdef CONFIG_ANDROID_ALARM_OLDDRV_COMPAT | ||
85 | /* | ||
86 | * Some older drivers depend on the old API, | ||
87 | * so provide compatability macros for now. | ||
88 | */ | ||
89 | #define alarm android_alarm | ||
90 | #define alarm_init(x, y, z) android_alarm_init(x, y, z) | ||
91 | #define alarm_start_range(x, y, z) android_alarm_start_range(x, y, z) | ||
92 | #define alarm_try_to_cancel(x) android_alarm_try_to_cancel(x) | ||
93 | #define alarm_cancel(x) android_alarm_cancel(x) | ||
94 | #define alarm_set_rtc(x) android_alarm_set_rtc(x) | ||
95 | #endif | ||
96 | |||
97 | |||
98 | #endif | ||
99 | |||
100 | enum android_alarm_return_flags { | 36 | enum android_alarm_return_flags { |
101 | ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP, | 37 | ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP, |
102 | ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC, | 38 | ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC, |