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