tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / staging / android / alarm-dev.c
1 /* drivers/rtc/alarm-dev.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/fs.h>
21 #include <linux/platform_device.h>
22 #include <linux/sched.h>
23 #include <linux/spinlock.h>
24 #include <linux/uaccess.h>
25 #include <linux/alarmtimer.h>
26 #include "android_alarm.h"
27
28 #define ANDROID_ALARM_PRINT_INFO (1U << 0)
29 #define ANDROID_ALARM_PRINT_IO (1U << 1)
30 #define ANDROID_ALARM_PRINT_INT (1U << 2)
31
32 static int debug_mask = ANDROID_ALARM_PRINT_INFO | ANDROID_ALARM_PRINT_IO | \
33                         ANDROID_ALARM_PRINT_INT;
34 module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
35
36 #define alarm_dbg(debug_level_mask, fmt, ...)                           \
37 do {                                                                    \
38         if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask)        \
39                 pr_info(fmt, ##__VA_ARGS__);                            \
40 } while (0)
41
42 #define ANDROID_ALARM_WAKEUP_MASK ( \
43         ANDROID_ALARM_RTC_WAKEUP_MASK | \
44         ANDROID_ALARM_POWER_OFF_WAKEUP_MASK | \
45         ANDROID_ALARM_POWER_OFF_ALARM_MASK | \
46         ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK)
47
48 static int alarm_opened;
49 static DEFINE_SPINLOCK(alarm_slock);
50 static struct wakeup_source alarm_wake_lock;
51 static struct wakeup_source alarm_rtc_lock;
52 static DECLARE_WAIT_QUEUE_HEAD(alarm_wait_queue);
53 static DECLARE_WAIT_QUEUE_HEAD(alarm_wait_change_queue);
54 static uint32_t alarm_pending;
55 static uint32_t alarm_enabled;
56 static uint32_t wait_pending;
57 static int delta = 0;
58
59 struct devalarm {
60         union {
61                 struct hrtimer hrt;
62                 struct alarm alrm;
63         } u;
64         enum android_alarm_type type;
65 };
66
67 static struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT];
68
69
70 static int is_wakeup(enum android_alarm_type type)
71 {
72         return (type == ANDROID_ALARM_RTC_WAKEUP ||
73                 type == ANDROID_ALARM_POWER_OFF_WAKEUP ||
74                 type == ANDROID_ALARM_POWER_OFF_ALARM ||
75                 type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP);
76 }
77
78
79 static void devalarm_start(struct devalarm *alrm, ktime_t exp)
80 {
81         if (is_wakeup(alrm->type)) {
82                 __pm_stay_awake(&alarm_rtc_lock);
83                 alarm_start(&alrm->u.alrm, exp);
84                 __pm_relax(&alarm_rtc_lock);
85         }
86         else
87                 hrtimer_start(&alrm->u.hrt, exp, HRTIMER_MODE_ABS);
88 }
89
90
91 static int devalarm_try_to_cancel(struct devalarm *alrm)
92 {
93         if (is_wakeup(alrm->type))
94                 return alarm_try_to_cancel(&alrm->u.alrm);
95         return hrtimer_try_to_cancel(&alrm->u.hrt);
96 }
97
98 static void devalarm_cancel(struct devalarm *alrm)
99 {
100         if (is_wakeup(alrm->type))
101                 alarm_cancel(&alrm->u.alrm);
102         else
103                 hrtimer_cancel(&alrm->u.hrt);
104 }
105
106 static void alarm_clear(enum android_alarm_type alarm_type)
107 {
108         uint32_t alarm_type_mask = 1U << alarm_type;
109         unsigned long flags;
110
111         spin_lock_irqsave(&alarm_slock, flags);
112         alarm_dbg(INFO, "alarm %d clear\n", alarm_type);
113         devalarm_try_to_cancel(&alarms[alarm_type]);
114         if (alarm_pending)
115                 alarm_pending &= ~alarm_type_mask;
116
117         alarm_enabled &= ~alarm_type_mask;
118
119         if (!alarm_enabled && !wait_pending) {
120                 __pm_relax(&alarm_wake_lock);
121                 alarm_dbg(INFO, "%s: wakeup_event cleared\n", __func__);
122         }
123
124         spin_unlock_irqrestore(&alarm_slock, flags);
125 }
126
127 static void alarm_set(enum android_alarm_type alarm_type,
128                                                         struct timespec *ts)
129 {
130         uint32_t alarm_type_mask = 1U << alarm_type;
131         unsigned long flags;
132
133         spin_lock_irqsave(&alarm_slock, flags);
134         alarm_dbg(INFO, "alarm %d set %ld.%09ld\n",
135                         alarm_type, ts->tv_sec, ts->tv_nsec);
136         alarm_enabled |= alarm_type_mask;
137         devalarm_start(&alarms[alarm_type], timespec_to_ktime(*ts));
138         spin_unlock_irqrestore(&alarm_slock, flags);
139 }
140
141 static int alarm_wait(void)
142 {
143         unsigned long flags;
144         int rv = 0;
145
146         spin_lock_irqsave(&alarm_slock, flags);
147         alarm_dbg(INFO, "alarm wait, alarm_pending 0x%x, wait_pending 0x%x\n",
148                 alarm_pending, wait_pending);
149         if (!alarm_pending && wait_pending) {
150                 __pm_relax(&alarm_wake_lock);
151                 wait_pending = 0;
152         }
153         spin_unlock_irqrestore(&alarm_slock, flags);
154
155         rv = wait_event_interruptible(alarm_wait_queue, alarm_pending);
156         if (rv) {
157                 alarm_dbg(IO, "alarm wait ret %d\n", rv);
158                 return rv;
159         }
160
161         spin_lock_irqsave(&alarm_slock, flags);
162         rv = alarm_pending;
163         wait_pending = 1;
164         alarm_pending = 0;
165         spin_unlock_irqrestore(&alarm_slock, flags);
166         alarm_dbg(IO, "alarm wake up %d\n", rv);
167
168         return rv;
169 }
170
171 static int alarm_set_rtc(struct timespec *ts)
172 {
173         struct rtc_time new_rtc_tm;
174         struct timespec old_rtc_time;
175         struct rtc_device *rtc_dev;
176         unsigned long flags;
177         int rv = 0;
178
179 /* get original rct time */
180                 getnstimeofday(&old_rtc_time);
181
182         rtc_time_to_tm(ts->tv_sec, &new_rtc_tm);
183         rtc_dev = alarmtimer_get_rtcdev();
184         rv = do_settimeofday(ts);
185         if (rv < 0)
186                 return rv;
187         if (rtc_dev)
188                 rv = rtc_set_time(rtc_dev, &new_rtc_tm);
189
190         spin_lock_irqsave(&alarm_slock, flags);
191         alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK;
192         delta += ts->tv_sec - old_rtc_time.tv_sec;
193         wake_up(&alarm_wait_queue);
194         wake_up(&alarm_wait_change_queue);
195         spin_unlock_irqrestore(&alarm_slock, flags);
196
197         return rv;
198 }
199
200 static int alarm_get_time(enum android_alarm_type alarm_type,
201                                                         struct timespec *ts)
202 {
203         int rv = 0;
204
205         switch (alarm_type) {
206         case ANDROID_ALARM_RTC_WAKEUP:
207         case ANDROID_ALARM_RTC:
208         case ANDROID_ALARM_POWER_OFF_WAKEUP:
209         case ANDROID_ALARM_POWER_OFF_ALARM:
210                 getnstimeofday(ts);
211                 break;
212         case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP:
213         case ANDROID_ALARM_ELAPSED_REALTIME:
214                 get_monotonic_boottime(ts);
215                 break;
216         case ANDROID_ALARM_SYSTEMTIME:
217                 ktime_get_ts(ts);
218                 break;
219         default:
220                 rv = -EINVAL;
221         }
222         return rv;
223 }
224
225 static long alarm_do_ioctl(struct file *file, unsigned int cmd,
226                                                         struct timespec *ts)
227 {
228         int rv = 0;
229         unsigned long flags;
230         enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd);
231
232         if (alarm_type >= ANDROID_ALARM_TYPE_COUNT)
233                 return -EINVAL;
234
235         if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0) && ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_WAIT_CHANGE) {
236                 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
237                         return -EPERM;
238                 if (file->private_data == NULL &&
239                     cmd != ANDROID_ALARM_SET_RTC) {
240                         spin_lock_irqsave(&alarm_slock, flags);
241                         if (alarm_opened) {
242                                 spin_unlock_irqrestore(&alarm_slock, flags);
243                                 return -EBUSY;
244                         }
245                         alarm_opened = 1;
246                         file->private_data = (void *)1;
247                         spin_unlock_irqrestore(&alarm_slock, flags);
248                 }
249         }
250
251         switch (ANDROID_ALARM_BASE_CMD(cmd)) {
252         case ANDROID_ALARM_CLEAR(0):
253                 alarm_clear(alarm_type);
254                 break;
255         case ANDROID_ALARM_SET(0):
256                 alarm_set(alarm_type, ts);
257                 break;
258         case ANDROID_ALARM_SET_AND_WAIT(0):
259                 alarm_set(alarm_type, ts);
260                 /* fall though */
261         case ANDROID_ALARM_WAIT:
262                 rv = alarm_wait();
263                 break;
264         case ANDROID_ALARM_WAIT_CHANGE:
265                 {
266                         rv = wait_event_interruptible(alarm_wait_change_queue, delta);
267                         if (rv == -ERESTARTSYS) {
268                             rv = -EINTR;
269                         }
270                         break;                  
271                 }
272         case ANDROID_ALARM_SET_RTC:
273                 rv = alarm_set_rtc(ts);
274                 break;
275         case ANDROID_ALARM_GET_TIME(0):
276                 rv = alarm_get_time(alarm_type, ts);
277                 break;
278
279         default:
280                 rv = -EINVAL;
281         }
282 err1:   
283         return rv;
284 }
285
286 static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
287 {
288
289         struct timespec ts;
290         int rv;
291
292         switch (ANDROID_ALARM_BASE_CMD(cmd)) {
293         case ANDROID_ALARM_SET_AND_WAIT(0):
294         case ANDROID_ALARM_SET(0):
295         case ANDROID_ALARM_SET_RTC:
296                 if (copy_from_user(&ts, (void __user *)arg, sizeof(ts)))
297                         return -EFAULT;
298                 break;
299         }
300
301         rv = alarm_do_ioctl(file, cmd, &ts);
302         if (rv)
303                 return rv;
304
305         switch (ANDROID_ALARM_BASE_CMD(cmd)) {
306         case ANDROID_ALARM_GET_TIME(0):
307                 if (copy_to_user((void __user *)arg, &ts, sizeof(ts)))
308                         return -EFAULT;
309                 break;
310         case ANDROID_ALARM_WAIT_CHANGE:
311                 {
312                         unsigned long flags;
313                         spin_lock_irqsave(&alarm_slock, flags);
314                         if (copy_to_user((void __user *)arg, &delta, 4)) {
315                             rv = -EFAULT;
316                                 delta = 0;
317                             spin_unlock_irqrestore(&alarm_slock, flags);
318                                 return rv;
319                         }
320                         delta = 0;
321                         spin_unlock_irqrestore(&alarm_slock, flags);
322                         break;
323                 }
324         }
325
326         return 0;
327 }
328 #ifdef CONFIG_COMPAT
329 static long alarm_compat_ioctl(struct file *file, unsigned int cmd,
330                                                         unsigned long arg)
331 {
332
333         struct timespec ts;
334         int rv;
335
336         switch (ANDROID_ALARM_BASE_CMD(cmd)) {
337         case ANDROID_ALARM_SET_AND_WAIT_COMPAT(0):
338         case ANDROID_ALARM_SET_COMPAT(0):
339         case ANDROID_ALARM_SET_RTC_COMPAT:
340                 if (compat_get_timespec(&ts, (void __user *)arg))
341                         return -EFAULT;
342                 /* fall through */
343         case ANDROID_ALARM_GET_TIME_COMPAT(0):
344                 cmd = ANDROID_ALARM_COMPAT_TO_NORM(cmd);
345                 break;
346         }
347
348         rv = alarm_do_ioctl(file, cmd, &ts);
349         if (rv)
350                 return rv;
351
352         switch (ANDROID_ALARM_BASE_CMD(cmd)) {
353         case ANDROID_ALARM_GET_TIME(0): /* NOTE: we modified cmd above */
354                 if (compat_put_timespec(&ts, (void __user *)arg))
355                         return -EFAULT;
356                 break;
357         }
358
359         return 0;
360 }
361 #endif
362
363 static int alarm_open(struct inode *inode, struct file *file)
364 {
365         file->private_data = NULL;
366         return 0;
367 }
368
369 static int alarm_release(struct inode *inode, struct file *file)
370 {
371         int i;
372         unsigned long flags;
373
374         spin_lock_irqsave(&alarm_slock, flags);
375         if (file->private_data) {
376                 for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
377                         uint32_t alarm_type_mask = 1U << i;
378                         if (alarm_enabled & alarm_type_mask) {
379                                 alarm_dbg(INFO,
380                                           "%s: clear alarm, pending %d\n",
381                                           __func__,
382                                           !!(alarm_pending & alarm_type_mask));
383                                 alarm_enabled &= ~alarm_type_mask;
384                         }
385                         spin_unlock_irqrestore(&alarm_slock, flags);
386                         devalarm_cancel(&alarms[i]);
387                         spin_lock_irqsave(&alarm_slock, flags);
388                 }
389                 if (alarm_pending | wait_pending) {
390                         if (alarm_pending)
391                                 alarm_dbg(INFO, "%s: clear pending alarms %x\n",
392                                           __func__, alarm_pending);
393                         __pm_relax(&alarm_wake_lock);
394                         wait_pending = 0;
395                         alarm_pending = 0;
396                 }
397                 alarm_opened = 0;
398         }
399         spin_unlock_irqrestore(&alarm_slock, flags);
400         return 0;
401 }
402
403 static void devalarm_triggered(struct devalarm *alarm)
404 {
405         unsigned long flags;
406         uint32_t alarm_type_mask = 1U << alarm->type;
407
408         alarm_dbg(INT, "%s: type %d, time %lu\n", __func__, alarm->type,
409                 alarm->u.alrm.node.expires.tv64);
410         spin_lock_irqsave(&alarm_slock, flags);
411         if (alarm_enabled & alarm_type_mask) {
412                 __pm_wakeup_event(&alarm_wake_lock, 3000); /* 3secs */
413                 alarm_dbg(INFO, "%s: wakeup_event keep 3s\n", __func__);
414
415                 alarm_enabled &= ~alarm_type_mask;
416                 alarm_pending |= alarm_type_mask;
417                 wake_up(&alarm_wait_queue);
418                 alarm_dbg(INT, "%s: wake up alarm_wait_queue\n", __func__);
419         }
420         spin_unlock_irqrestore(&alarm_slock, flags);
421 }
422
423
424 static enum hrtimer_restart devalarm_hrthandler(struct hrtimer *hrt)
425 {
426         struct devalarm *devalrm = container_of(hrt, struct devalarm, u.hrt);
427
428         devalarm_triggered(devalrm);
429         return HRTIMER_NORESTART;
430 }
431
432 static enum alarmtimer_restart devalarm_alarmhandler(struct alarm *alrm,
433                                                         ktime_t now)
434 {
435         struct devalarm *devalrm = container_of(alrm, struct devalarm, u.alrm);
436
437         devalarm_triggered(devalrm);
438         return ALARMTIMER_NORESTART;
439 }
440
441
442 static const struct file_operations alarm_fops = {
443         .owner = THIS_MODULE,
444         .unlocked_ioctl = alarm_ioctl,
445         .open = alarm_open,
446         .release = alarm_release,
447 #ifdef CONFIG_COMPAT
448         .compat_ioctl = alarm_compat_ioctl,
449 #endif
450 };
451
452 static struct miscdevice alarm_device = {
453         .minor = MISC_DYNAMIC_MINOR,
454         .name = "alarm",
455         .fops = &alarm_fops,
456 };
457
458 static int __init alarm_dev_init(void)
459 {
460         int err;
461         int i;
462
463         err = misc_register(&alarm_device);
464         if (err)
465                 return err;
466
467         alarm_init(&alarms[ANDROID_ALARM_RTC_WAKEUP].u.alrm,
468                         ALARM_REALTIME, devalarm_alarmhandler);
469         hrtimer_init(&alarms[ANDROID_ALARM_RTC].u.hrt,
470                         CLOCK_REALTIME, HRTIMER_MODE_ABS);
471         alarm_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].u.alrm,
472                         ALARM_BOOTTIME, devalarm_alarmhandler);
473         hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME].u.hrt,
474                         CLOCK_BOOTTIME, HRTIMER_MODE_ABS);
475         hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt,
476                         CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
477         alarm_init(&alarms[ANDROID_ALARM_POWER_OFF_WAKEUP].u.alrm,
478                         ALARM_POWEROFF, devalarm_alarmhandler);
479         alarm_init(&alarms[ANDROID_ALARM_POWER_OFF_ALARM].u.alrm,
480                         ALARM_POWEROFF_ALARM, devalarm_alarmhandler);
481
482         for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
483                 alarms[i].type = i;
484                 if (!is_wakeup(i))
485                         alarms[i].u.hrt.function = devalarm_hrthandler;
486         }
487
488         wakeup_source_init(&alarm_wake_lock, "alarm");
489         wakeup_source_init(&alarm_rtc_lock, "alarm-rtc-lock");
490         return 0;
491 }
492
493 static void  __exit alarm_dev_exit(void)
494 {
495         misc_deregister(&alarm_device);
496         wakeup_source_trash(&alarm_wake_lock);
497         wakeup_source_trash(&alarm_rtc_lock);
498 }
499
500 module_init(alarm_dev_init);
501 module_exit(alarm_dev_exit);
502