blob: fb9732977358a2e27e4ba0bc7c099df84fca20cd [file] [log] [blame]
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -07001/* drivers/rtc/alarm.c
2 *
Arve Hjønnevågfa565402009-05-04 14:09:15 -07003 * Copyright (C) 2007-2009 Google, Inc.
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -07004 *
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
Steve Mucklef132c6c2012-06-06 18:30:57 -070016#include <linux/module.h>
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -070017#include <linux/android_alarm.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>
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -070024#include <linux/wakelock.h>
25
Steve Mucklef132c6c2012-06-06 18:30:57 -070026#include <asm/mach/time.h>
27
Mohit Aggarwal7289fdd2013-08-06 23:24:31 +053028#define ALARM_DELTA 120
Arve Hjønnevågfa565402009-05-04 14:09:15 -070029#define ANDROID_ALARM_PRINT_ERROR (1U << 0)
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -070030#define ANDROID_ALARM_PRINT_INIT_STATUS (1U << 1)
Arve Hjønnevågfa565402009-05-04 14:09:15 -070031#define ANDROID_ALARM_PRINT_TSET (1U << 2)
32#define ANDROID_ALARM_PRINT_CALL (1U << 3)
33#define ANDROID_ALARM_PRINT_SUSPEND (1U << 4)
34#define ANDROID_ALARM_PRINT_INT (1U << 5)
35#define ANDROID_ALARM_PRINT_FLOW (1U << 6)
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -070036
Arve Hjønnevågfa565402009-05-04 14:09:15 -070037static int debug_mask = ANDROID_ALARM_PRINT_ERROR | \
38 ANDROID_ALARM_PRINT_INIT_STATUS;
39module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
40
41#define pr_alarm(debug_level_mask, args...) \
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -070042 do { \
Arve Hjønnevågfa565402009-05-04 14:09:15 -070043 if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) { \
44 pr_info(args); \
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -070045 } \
46 } while (0)
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -070047
48#define ANDROID_ALARM_WAKEUP_MASK ( \
49 ANDROID_ALARM_RTC_WAKEUP_MASK | \
50 ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK)
51
52/* support old usespace code */
53#define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */
54#define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t)
55
Arve Hjønnevågfa565402009-05-04 14:09:15 -070056struct alarm_queue {
57 struct rb_root alarms;
58 struct rb_node *first;
59 struct hrtimer timer;
60 ktime_t delta;
61 bool stopped;
62 ktime_t stopped_time;
63};
64
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -070065static struct rtc_device *alarm_rtc_dev;
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -070066static DEFINE_SPINLOCK(alarm_slock);
67static DEFINE_MUTEX(alarm_setrtc_mutex);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -070068static struct wake_lock alarm_rtc_wake_lock;
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -070069static struct platform_device *alarm_platform_dev;
Arve Hjønnevågfa565402009-05-04 14:09:15 -070070struct alarm_queue alarms[ANDROID_ALARM_TYPE_COUNT];
71static bool suspended;
Ashay Jaiswalc1b2e472013-05-17 15:15:02 +053072static long power_on_alarm;
73
Figo Wangaec339e2013-09-25 12:59:35 +080074static void alarm_shutdown(struct platform_device *dev);
Ashay Jaiswalc1b2e472013-05-17 15:15:02 +053075void set_power_on_alarm(long secs)
76{
77 power_on_alarm = secs;
Figo Wangaec339e2013-09-25 12:59:35 +080078 alarm_shutdown(NULL);
Ashay Jaiswalc1b2e472013-05-17 15:15:02 +053079}
80
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -070081
Arve Hjønnevågfa565402009-05-04 14:09:15 -070082static void update_timer_locked(struct alarm_queue *base, bool head_removed)
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -070083{
Arve Hjønnevågfa565402009-05-04 14:09:15 -070084 struct alarm *alarm;
85 bool is_wakeup = base == &alarms[ANDROID_ALARM_RTC_WAKEUP] ||
Figo Wang091c9af2013-09-12 20:41:27 +080086 base == &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP] ||
87 base == &alarms[ANDROID_ALARM_RTC_POWEROFF_WAKEUP];
Arve Hjønnevågfa565402009-05-04 14:09:15 -070088
89 if (base->stopped) {
90 pr_alarm(FLOW, "changed alarm while setting the wall time\n");
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -070091 return;
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -070092 }
93
Arve Hjønnevågfa565402009-05-04 14:09:15 -070094 if (is_wakeup && !suspended && head_removed)
95 wake_unlock(&alarm_rtc_wake_lock);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -070096
Arve Hjønnevågfa565402009-05-04 14:09:15 -070097 if (!base->first)
98 return;
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -070099
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700100 alarm = container_of(base->first, struct alarm, node);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700101
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700102 pr_alarm(FLOW, "selected alarm, type %d, func %pF at %lld\n",
103 alarm->type, alarm->function, ktime_to_ns(alarm->expires));
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700104
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700105 if (is_wakeup && suspended) {
106 pr_alarm(FLOW, "changed alarm while suspened\n");
107 wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ);
108 return;
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700109 }
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700110
111 hrtimer_try_to_cancel(&base->timer);
112 base->timer.node.expires = ktime_add(base->delta, alarm->expires);
113 base->timer._softexpires = ktime_add(base->delta, alarm->softexpires);
114 hrtimer_start_expires(&base->timer, HRTIMER_MODE_ABS);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700115}
116
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700117static void alarm_enqueue_locked(struct alarm *alarm)
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700118{
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700119 struct alarm_queue *base = &alarms[alarm->type];
120 struct rb_node **link = &base->alarms.rb_node;
121 struct rb_node *parent = NULL;
122 struct alarm *entry;
123 int leftmost = 1;
Arve Hjønnevåg2cd24682011-01-07 19:00:01 -0800124 bool was_first = false;
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700125
126 pr_alarm(FLOW, "added alarm, type %d, func %pF at %lld\n",
127 alarm->type, alarm->function, ktime_to_ns(alarm->expires));
128
Arve Hjønnevåg2cd24682011-01-07 19:00:01 -0800129 if (base->first == &alarm->node) {
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700130 base->first = rb_next(&alarm->node);
Arve Hjønnevåg2cd24682011-01-07 19:00:01 -0800131 was_first = true;
132 }
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700133 if (!RB_EMPTY_NODE(&alarm->node)) {
134 rb_erase(&alarm->node, &base->alarms);
135 RB_CLEAR_NODE(&alarm->node);
136 }
137
138 while (*link) {
139 parent = *link;
140 entry = rb_entry(parent, struct alarm, node);
141 /*
142 * We dont care about collisions. Nodes with
143 * the same expiry time stay together.
144 */
145 if (alarm->expires.tv64 < entry->expires.tv64) {
146 link = &(*link)->rb_left;
147 } else {
148 link = &(*link)->rb_right;
149 leftmost = 0;
150 }
151 }
Arve Hjønnevåg2cd24682011-01-07 19:00:01 -0800152 if (leftmost)
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700153 base->first = &alarm->node;
Arve Hjønnevåg2cd24682011-01-07 19:00:01 -0800154 if (leftmost || was_first)
155 update_timer_locked(base, was_first);
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700156
157 rb_link_node(&alarm->node, parent, link);
158 rb_insert_color(&alarm->node, &base->alarms);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700159}
160
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700161/**
162 * alarm_init - initialize an alarm
163 * @alarm: the alarm to be initialized
164 * @type: the alarm type to be used
165 * @function: alarm callback function
166 */
167void alarm_init(struct alarm *alarm,
168 enum android_alarm_type type, void (*function)(struct alarm *))
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700169{
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700170 RB_CLEAR_NODE(&alarm->node);
171 alarm->type = type;
172 alarm->function = function;
173
174 pr_alarm(FLOW, "created alarm, type %d, func %pF\n", type, function);
175}
176
177
178/**
179 * alarm_start_range - (re)start an alarm
180 * @alarm: the alarm to be added
181 * @start: earliest expiry time
182 * @end: expiry time
183 */
184void alarm_start_range(struct alarm *alarm, ktime_t start, ktime_t end)
185{
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700186 unsigned long flags;
187
188 spin_lock_irqsave(&alarm_slock, flags);
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700189 alarm->softexpires = start;
190 alarm->expires = end;
191 alarm_enqueue_locked(alarm);
192 spin_unlock_irqrestore(&alarm_slock, flags);
193}
194
195/**
196 * alarm_try_to_cancel - try to deactivate an alarm
197 * @alarm: alarm to stop
198 *
199 * Returns:
200 * 0 when the alarm was not active
201 * 1 when the alarm was active
202 * -1 when the alarm may currently be excuting the callback function and
203 * cannot be stopped (it may also be inactive)
204 */
205int alarm_try_to_cancel(struct alarm *alarm)
206{
207 struct alarm_queue *base = &alarms[alarm->type];
208 unsigned long flags;
209 bool first = false;
210 int ret = 0;
211
212 spin_lock_irqsave(&alarm_slock, flags);
213 if (!RB_EMPTY_NODE(&alarm->node)) {
214 pr_alarm(FLOW, "canceled alarm, type %d, func %pF at %lld\n",
215 alarm->type, alarm->function,
216 ktime_to_ns(alarm->expires));
217 ret = 1;
218 if (base->first == &alarm->node) {
219 base->first = rb_next(&alarm->node);
220 first = true;
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700221 }
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700222 rb_erase(&alarm->node, &base->alarms);
223 RB_CLEAR_NODE(&alarm->node);
224 if (first)
225 update_timer_locked(base, true);
226 } else
227 pr_alarm(FLOW, "tried to cancel alarm, type %d, func %pF\n",
228 alarm->type, alarm->function);
229 spin_unlock_irqrestore(&alarm_slock, flags);
230 if (!ret && hrtimer_callback_running(&base->timer))
231 ret = -1;
232 return ret;
233}
234
235/**
236 * alarm_cancel - cancel an alarm and wait for the handler to finish.
237 * @alarm: the alarm to be cancelled
238 *
239 * Returns:
240 * 0 when the alarm was not active
241 * 1 when the alarm was active
242 */
243int alarm_cancel(struct alarm *alarm)
244{
245 for (;;) {
246 int ret = alarm_try_to_cancel(alarm);
247 if (ret >= 0)
248 return ret;
249 cpu_relax();
250 }
251}
252
253/**
254 * alarm_set_rtc - set the kernel and rtc walltime
255 * @new_time: timespec value containing the new time
256 */
257int alarm_set_rtc(struct timespec new_time)
258{
259 int i;
260 int ret;
261 unsigned long flags;
262 struct rtc_time rtc_new_rtc_time;
263 struct timespec tmp_time;
264
265 rtc_time_to_tm(new_time.tv_sec, &rtc_new_rtc_time);
266
267 pr_alarm(TSET, "set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n",
268 new_time.tv_sec, new_time.tv_nsec,
269 rtc_new_rtc_time.tm_hour, rtc_new_rtc_time.tm_min,
270 rtc_new_rtc_time.tm_sec, rtc_new_rtc_time.tm_mon + 1,
271 rtc_new_rtc_time.tm_mday,
272 rtc_new_rtc_time.tm_year + 1900);
273
274 mutex_lock(&alarm_setrtc_mutex);
275 spin_lock_irqsave(&alarm_slock, flags);
276 wake_lock(&alarm_rtc_wake_lock);
277 getnstimeofday(&tmp_time);
278 for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) {
279 hrtimer_try_to_cancel(&alarms[i].timer);
280 alarms[i].stopped = true;
281 alarms[i].stopped_time = timespec_to_ktime(tmp_time);
282 }
283 alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta =
284 alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta =
285 ktime_sub(alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta,
286 timespec_to_ktime(timespec_sub(tmp_time, new_time)));
287 spin_unlock_irqrestore(&alarm_slock, flags);
288 ret = do_settimeofday(&new_time);
289 spin_lock_irqsave(&alarm_slock, flags);
290 for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) {
291 alarms[i].stopped = false;
292 update_timer_locked(&alarms[i], false);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700293 }
294 spin_unlock_irqrestore(&alarm_slock, flags);
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700295 if (ret < 0) {
296 pr_alarm(ERROR, "alarm_set_rtc: Failed to set time\n");
297 goto err;
298 }
299 if (!alarm_rtc_dev) {
300 pr_alarm(ERROR,
301 "alarm_set_rtc: no RTC, time will be lost on reboot\n");
302 goto err;
303 }
304 ret = rtc_set_time(alarm_rtc_dev, &rtc_new_rtc_time);
305 if (ret < 0)
306 pr_alarm(ERROR, "alarm_set_rtc: "
307 "Failed to set RTC, time will be lost on reboot\n");
308err:
309 wake_unlock(&alarm_rtc_wake_lock);
310 mutex_unlock(&alarm_setrtc_mutex);
311 return ret;
312}
313
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700314
315void
316alarm_update_timedelta(struct timespec tmp_time, struct timespec new_time)
317{
318 int i;
319 unsigned long flags;
320
321 spin_lock_irqsave(&alarm_slock, flags);
322 for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) {
323 hrtimer_try_to_cancel(&alarms[i].timer);
324 alarms[i].stopped = true;
325 alarms[i].stopped_time = timespec_to_ktime(tmp_time);
326 }
327 alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta =
328 alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta =
329 ktime_sub(alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta,
330 timespec_to_ktime(timespec_sub(tmp_time, new_time)));
331 for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) {
332 alarms[i].stopped = false;
333 update_timer_locked(&alarms[i], false);
334 }
335 spin_unlock_irqrestore(&alarm_slock, flags);
336}
337
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700338/**
339 * alarm_get_elapsed_realtime - get the elapsed real time in ktime_t format
340 *
341 * returns the time in ktime_t format
342 */
343ktime_t alarm_get_elapsed_realtime(void)
344{
345 ktime_t now;
346 unsigned long flags;
347 struct alarm_queue *base = &alarms[ANDROID_ALARM_ELAPSED_REALTIME];
348
349 spin_lock_irqsave(&alarm_slock, flags);
350 now = base->stopped ? base->stopped_time : ktime_get_real();
351 now = ktime_sub(now, base->delta);
352 spin_unlock_irqrestore(&alarm_slock, flags);
353 return now;
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700354}
355
356static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer)
357{
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700358 struct alarm_queue *base;
359 struct alarm *alarm;
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700360 unsigned long flags;
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700361 ktime_t now;
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700362
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700363 spin_lock_irqsave(&alarm_slock, flags);
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700364
365 base = container_of(timer, struct alarm_queue, timer);
366 now = base->stopped ? base->stopped_time : hrtimer_cb_get_time(timer);
367 now = ktime_sub(now, base->delta);
368
369 pr_alarm(INT, "alarm_timer_triggered type %d at %lld\n",
370 base - alarms, ktime_to_ns(now));
371
372 while (base->first) {
373 alarm = container_of(base->first, struct alarm, node);
374 if (alarm->softexpires.tv64 > now.tv64) {
375 pr_alarm(FLOW, "don't call alarm, %pF, %lld (s %lld)\n",
376 alarm->function, ktime_to_ns(alarm->expires),
377 ktime_to_ns(alarm->softexpires));
378 break;
379 }
380 base->first = rb_next(&alarm->node);
381 rb_erase(&alarm->node, &base->alarms);
382 RB_CLEAR_NODE(&alarm->node);
383 pr_alarm(CALL, "call alarm, type %d, func %pF, %lld (s %lld)\n",
384 alarm->type, alarm->function,
385 ktime_to_ns(alarm->expires),
386 ktime_to_ns(alarm->softexpires));
387 spin_unlock_irqrestore(&alarm_slock, flags);
388 alarm->function(alarm);
389 spin_lock_irqsave(&alarm_slock, flags);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700390 }
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700391 if (!base->first)
392 pr_alarm(FLOW, "no more alarms of type %d\n", base - alarms);
393 update_timer_locked(base, true);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700394 spin_unlock_irqrestore(&alarm_slock, flags);
395 return HRTIMER_NORESTART;
396}
397
398static void alarm_triggered_func(void *p)
399{
400 struct rtc_device *rtc = alarm_rtc_dev;
401 if (!(rtc->irq_data & RTC_AF))
402 return;
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700403 pr_alarm(INT, "rtc alarm triggered\n");
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700404 wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ);
405}
406
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700407static int alarm_suspend(struct platform_device *pdev, pm_message_t state)
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700408{
409 int err = 0;
410 unsigned long flags;
411 struct rtc_wkalrm rtc_alarm;
412 struct rtc_time rtc_current_rtc_time;
413 unsigned long rtc_current_time;
414 unsigned long rtc_alarm_time;
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700415 struct timespec rtc_delta;
Arve Hjønnevågb2a4ab22010-03-12 20:05:32 -0800416 struct timespec wall_time;
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700417 struct alarm_queue *wakeup_queue = NULL;
418 struct alarm_queue *tmp_queue = NULL;
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700419
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700420 pr_alarm(SUSPEND, "alarm_suspend(%p, %d)\n", pdev, state.event);
421
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700422 spin_lock_irqsave(&alarm_slock, flags);
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700423 suspended = true;
424 spin_unlock_irqrestore(&alarm_slock, flags);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700425
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700426 hrtimer_cancel(&alarms[ANDROID_ALARM_RTC_WAKEUP].timer);
427 hrtimer_cancel(&alarms[
JP Abgrall692e4682011-09-02 18:14:12 -0700428 ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].timer);
Figo Wang091c9af2013-09-12 20:41:27 +0800429 hrtimer_cancel(&alarms[
430 ANDROID_ALARM_RTC_POWEROFF_WAKEUP].timer);
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700431
432 tmp_queue = &alarms[ANDROID_ALARM_RTC_WAKEUP];
433 if (tmp_queue->first)
434 wakeup_queue = tmp_queue;
Figo Wang091c9af2013-09-12 20:41:27 +0800435
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700436 tmp_queue = &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP];
437 if (tmp_queue->first && (!wakeup_queue ||
438 hrtimer_get_expires(&tmp_queue->timer).tv64 <
439 hrtimer_get_expires(&wakeup_queue->timer).tv64))
440 wakeup_queue = tmp_queue;
Figo Wang091c9af2013-09-12 20:41:27 +0800441
442 tmp_queue = &alarms[ANDROID_ALARM_RTC_POWEROFF_WAKEUP];
443 if (tmp_queue->first && (!wakeup_queue ||
444 hrtimer_get_expires(&tmp_queue->timer).tv64 <
445 hrtimer_get_expires(&wakeup_queue->timer).tv64))
446 wakeup_queue = tmp_queue;
447
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700448 if (wakeup_queue) {
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700449 rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time);
Arve Hjønnevågb2a4ab22010-03-12 20:05:32 -0800450 getnstimeofday(&wall_time);
451 rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time);
452 set_normalized_timespec(&rtc_delta,
453 wall_time.tv_sec - rtc_current_time,
454 wall_time.tv_nsec);
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700455
456 rtc_alarm_time = timespec_sub(ktime_to_timespec(
457 hrtimer_get_expires(&wakeup_queue->timer)),
458 rtc_delta).tv_sec;
459
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700460 rtc_time_to_tm(rtc_alarm_time, &rtc_alarm.time);
461 rtc_alarm.enabled = 1;
462 rtc_set_alarm(alarm_rtc_dev, &rtc_alarm);
463 rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time);
464 rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time);
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700465 pr_alarm(SUSPEND,
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700466 "rtc alarm set at %ld, now %ld, rtc delta %ld.%09ld\n",
467 rtc_alarm_time, rtc_current_time,
468 rtc_delta.tv_sec, rtc_delta.tv_nsec);
469 if (rtc_current_time + 1 >= rtc_alarm_time) {
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700470 pr_alarm(SUSPEND, "alarm about to go off\n");
Figo Wang1b2c1c62013-07-30 09:33:59 +0800471 rtc_time_to_tm(0, &rtc_alarm.time);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700472 rtc_alarm.enabled = 0;
473 rtc_set_alarm(alarm_rtc_dev, &rtc_alarm);
474
475 spin_lock_irqsave(&alarm_slock, flags);
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700476 suspended = false;
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700477 wake_lock_timeout(&alarm_rtc_wake_lock, 2 * HZ);
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700478 update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP],
479 false);
480 update_timer_locked(&alarms[
481 ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP], false);
Figo Wang091c9af2013-09-12 20:41:27 +0800482 update_timer_locked(&alarms[
483 ANDROID_ALARM_RTC_POWEROFF_WAKEUP], false);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700484 err = -EBUSY;
485 spin_unlock_irqrestore(&alarm_slock, flags);
486 }
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700487 }
488 return err;
489}
490
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700491static int alarm_resume(struct platform_device *pdev)
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700492{
493 struct rtc_wkalrm alarm;
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700494 unsigned long flags;
495
496 pr_alarm(SUSPEND, "alarm_resume(%p)\n", pdev);
497
Figo Wang1b2c1c62013-07-30 09:33:59 +0800498 rtc_time_to_tm(0, &alarm.time);
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700499 alarm.enabled = 0;
500 rtc_set_alarm(alarm_rtc_dev, &alarm);
501
502 spin_lock_irqsave(&alarm_slock, flags);
503 suspended = false;
504 update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP], false);
505 update_timer_locked(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP],
506 false);
Figo Wang091c9af2013-09-12 20:41:27 +0800507 update_timer_locked(&alarms[ANDROID_ALARM_RTC_POWEROFF_WAKEUP],
508 false);
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700509 spin_unlock_irqrestore(&alarm_slock, flags);
510
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700511 return 0;
512}
513
Ashay Jaiswalc1b2e472013-05-17 15:15:02 +0530514static void alarm_shutdown(struct platform_device *dev)
515{
516 struct timespec wall_time;
517 struct rtc_time rtc_time;
518 struct rtc_wkalrm alarm;
519 unsigned long flags;
520 long rtc_secs, alarm_delta, alarm_time;
521 int rc;
522
523 spin_lock_irqsave(&alarm_slock, flags);
524
Mohit Aggarwal6a5881b2014-03-04 21:43:37 +0530525 if (!power_on_alarm) {
526 spin_unlock_irqrestore(&alarm_slock, flags);
Ashay Jaiswalc1b2e472013-05-17 15:15:02 +0530527 goto disable_alarm;
Mohit Aggarwal6a5881b2014-03-04 21:43:37 +0530528 }
529 spin_unlock_irqrestore(&alarm_slock, flags);
Ashay Jaiswalc1b2e472013-05-17 15:15:02 +0530530
531 rtc_read_time(alarm_rtc_dev, &rtc_time);
532 getnstimeofday(&wall_time);
533 rtc_tm_to_time(&rtc_time, &rtc_secs);
534 alarm_delta = wall_time.tv_sec - rtc_secs;
535 alarm_time = power_on_alarm - alarm_delta;
Mohit Aggarwal7289fdd2013-08-06 23:24:31 +0530536
537 /*
538 * Substract ALARM_DELTA from actual alarm time
539 * to powerup the device before actual alarm
540 * expiration.
541 */
542 if ((alarm_time - ALARM_DELTA) > rtc_secs)
543 alarm_time -= ALARM_DELTA;
544
Ashay Jaiswalc1b2e472013-05-17 15:15:02 +0530545 if (alarm_time <= rtc_secs)
546 goto disable_alarm;
547
548 rtc_time_to_tm(alarm_time, &alarm.time);
549 alarm.enabled = 1;
550 rc = rtc_set_alarm(alarm_rtc_dev, &alarm);
551 if (rc)
552 pr_alarm(ERROR, "Unable to set power-on alarm\n");
553 else
554 pr_alarm(FLOW, "Power-on alarm set to %lu\n",
555 alarm_time);
556
Ashay Jaiswalc1b2e472013-05-17 15:15:02 +0530557 return;
558
559disable_alarm:
Prasad Sodagudic83a3822013-12-31 16:34:26 +0530560 rtc_alarm_irq_enable(alarm_rtc_dev, 0);
Ashay Jaiswalc1b2e472013-05-17 15:15:02 +0530561}
562
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700563static struct rtc_task alarm_rtc_task = {
564 .func = alarm_triggered_func
565};
566
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700567static int rtc_alarm_add_device(struct device *dev,
568 struct class_interface *class_intf)
569{
570 int err;
571 struct rtc_device *rtc = to_rtc_device(dev);
572
573 mutex_lock(&alarm_setrtc_mutex);
574
575 if (alarm_rtc_dev) {
576 err = -EBUSY;
577 goto err1;
578 }
579
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700580 alarm_platform_dev =
581 platform_device_register_simple("alarm", -1, NULL, 0);
582 if (IS_ERR(alarm_platform_dev)) {
583 err = PTR_ERR(alarm_platform_dev);
584 goto err2;
585 }
586 err = rtc_irq_register(rtc, &alarm_rtc_task);
587 if (err)
588 goto err3;
589 alarm_rtc_dev = rtc;
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700590 pr_alarm(INIT_STATUS, "using rtc device, %s, for alarms", rtc->name);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700591 mutex_unlock(&alarm_setrtc_mutex);
592
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700593 return 0;
594
595err3:
596 platform_device_unregister(alarm_platform_dev);
597err2:
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700598err1:
599 mutex_unlock(&alarm_setrtc_mutex);
600 return err;
601}
602
603static void rtc_alarm_remove_device(struct device *dev,
604 struct class_interface *class_intf)
605{
606 if (dev == &alarm_rtc_dev->dev) {
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700607 pr_alarm(INIT_STATUS, "lost rtc device for alarms");
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700608 rtc_irq_unregister(alarm_rtc_dev, &alarm_rtc_task);
609 platform_device_unregister(alarm_platform_dev);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700610 alarm_rtc_dev = NULL;
611 }
612}
613
614static struct class_interface rtc_alarm_interface = {
615 .add_dev = &rtc_alarm_add_device,
616 .remove_dev = &rtc_alarm_remove_device,
617};
618
619static struct platform_driver alarm_driver = {
620 .suspend = alarm_suspend,
621 .resume = alarm_resume,
Ashay Jaiswalc1b2e472013-05-17 15:15:02 +0530622 .shutdown = alarm_shutdown,
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700623 .driver = {
624 .name = "alarm"
625 }
626};
627
628static int __init alarm_late_init(void)
629{
630 unsigned long flags;
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700631 struct timespec tmp_time, system_time;
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700632
633 /* this needs to run after the rtc is read at boot */
634 spin_lock_irqsave(&alarm_slock, flags);
635 /* We read the current rtc and system time so we can later calulate
636 * elasped realtime to be (boot_systemtime + rtc - boot_rtc) ==
637 * (rtc - (boot_rtc - boot_systemtime))
638 */
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700639 getnstimeofday(&tmp_time);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700640 ktime_get_ts(&system_time);
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700641 alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta =
642 alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta =
643 timespec_to_ktime(timespec_sub(tmp_time, system_time));
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700644
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700645 spin_unlock_irqrestore(&alarm_slock, flags);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700646 return 0;
647}
648
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700649static int __init alarm_driver_init(void)
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700650{
651 int err;
652 int i;
653
654 for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) {
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700655 hrtimer_init(&alarms[i].timer,
656 CLOCK_REALTIME, HRTIMER_MODE_ABS);
657 alarms[i].timer.function = alarm_timer_triggered;
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700658 }
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700659 hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].timer,
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700660 CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700661 alarms[ANDROID_ALARM_SYSTEMTIME].timer.function = alarm_timer_triggered;
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700662 err = platform_driver_register(&alarm_driver);
663 if (err < 0)
664 goto err1;
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700665 wake_lock_init(&alarm_rtc_wake_lock, WAKE_LOCK_SUSPEND, "alarm_rtc");
666 rtc_alarm_interface.class = rtc_class;
667 err = class_interface_register(&rtc_alarm_interface);
668 if (err < 0)
669 goto err2;
670
671 return 0;
672
673err2:
674 wake_lock_destroy(&alarm_rtc_wake_lock);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700675 platform_driver_unregister(&alarm_driver);
676err1:
677 return err;
678}
679
680static void __exit alarm_exit(void)
681{
682 class_interface_unregister(&rtc_alarm_interface);
683 wake_lock_destroy(&alarm_rtc_wake_lock);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700684 platform_driver_unregister(&alarm_driver);
685}
686
687late_initcall(alarm_late_init);
Arve Hjønnevågfa565402009-05-04 14:09:15 -0700688module_init(alarm_driver_init);
Arve Hjønnevågb54b33d2008-10-14 17:38:04 -0700689module_exit(alarm_exit);
690