at v3.19-rc4 446 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 75static void devalarm_start(struct devalarm *alrm, ktime_t exp) 76{ 77 if (is_wakeup(alrm->type)) 78 alarm_start(&alrm->u.alrm, exp); 79 else 80 hrtimer_start(&alrm->u.hrt, exp, HRTIMER_MODE_ABS); 81} 82 83static int devalarm_try_to_cancel(struct devalarm *alrm) 84{ 85 if (is_wakeup(alrm->type)) 86 return alarm_try_to_cancel(&alrm->u.alrm); 87 return hrtimer_try_to_cancel(&alrm->u.hrt); 88} 89 90static void devalarm_cancel(struct devalarm *alrm) 91{ 92 if (is_wakeup(alrm->type)) 93 alarm_cancel(&alrm->u.alrm); 94 else 95 hrtimer_cancel(&alrm->u.hrt); 96} 97 98static void alarm_clear(enum android_alarm_type alarm_type) 99{ 100 uint32_t alarm_type_mask = 1U << alarm_type; 101 unsigned long flags; 102 103 spin_lock_irqsave(&alarm_slock, flags); 104 alarm_dbg(IO, "alarm %d clear\n", alarm_type); 105 devalarm_try_to_cancel(&alarms[alarm_type]); 106 if (alarm_pending) { 107 alarm_pending &= ~alarm_type_mask; 108 if (!alarm_pending && !wait_pending) 109 __pm_relax(&alarm_wake_lock); 110 } 111 alarm_enabled &= ~alarm_type_mask; 112 spin_unlock_irqrestore(&alarm_slock, flags); 113} 114 115static void alarm_set(enum android_alarm_type alarm_type, 116 struct timespec *ts) 117{ 118 uint32_t alarm_type_mask = 1U << alarm_type; 119 unsigned long flags; 120 121 spin_lock_irqsave(&alarm_slock, flags); 122 alarm_dbg(IO, "alarm %d set %ld.%09ld\n", 123 alarm_type, ts->tv_sec, ts->tv_nsec); 124 alarm_enabled |= alarm_type_mask; 125 devalarm_start(&alarms[alarm_type], timespec_to_ktime(*ts)); 126 spin_unlock_irqrestore(&alarm_slock, flags); 127} 128 129static int alarm_wait(void) 130{ 131 unsigned long flags; 132 int rv = 0; 133 134 spin_lock_irqsave(&alarm_slock, flags); 135 alarm_dbg(IO, "alarm wait\n"); 136 if (!alarm_pending && wait_pending) { 137 __pm_relax(&alarm_wake_lock); 138 wait_pending = 0; 139 } 140 spin_unlock_irqrestore(&alarm_slock, flags); 141 142 rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); 143 if (rv) 144 return rv; 145 146 spin_lock_irqsave(&alarm_slock, flags); 147 rv = alarm_pending; 148 wait_pending = 1; 149 alarm_pending = 0; 150 spin_unlock_irqrestore(&alarm_slock, flags); 151 152 return rv; 153} 154 155static int alarm_set_rtc(struct timespec *ts) 156{ 157 struct rtc_time new_rtc_tm; 158 struct rtc_device *rtc_dev; 159 unsigned long flags; 160 int rv = 0; 161 162 rtc_time_to_tm(ts->tv_sec, &new_rtc_tm); 163 rtc_dev = alarmtimer_get_rtcdev(); 164 rv = do_settimeofday(ts); 165 if (rv < 0) 166 return rv; 167 if (rtc_dev) 168 rv = rtc_set_time(rtc_dev, &new_rtc_tm); 169 170 spin_lock_irqsave(&alarm_slock, flags); 171 alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; 172 wake_up(&alarm_wait_queue); 173 spin_unlock_irqrestore(&alarm_slock, flags); 174 175 return rv; 176} 177 178static int alarm_get_time(enum android_alarm_type alarm_type, 179 struct timespec *ts) 180{ 181 int rv = 0; 182 183 switch (alarm_type) { 184 case ANDROID_ALARM_RTC_WAKEUP: 185 case ANDROID_ALARM_RTC: 186 getnstimeofday(ts); 187 break; 188 case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: 189 case ANDROID_ALARM_ELAPSED_REALTIME: 190 get_monotonic_boottime(ts); 191 break; 192 case ANDROID_ALARM_SYSTEMTIME: 193 ktime_get_ts(ts); 194 break; 195 default: 196 rv = -EINVAL; 197 } 198 return rv; 199} 200 201static long alarm_do_ioctl(struct file *file, unsigned int cmd, 202 struct timespec *ts) 203{ 204 int rv = 0; 205 unsigned long flags; 206 enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); 207 208 if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) 209 return -EINVAL; 210 211 if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { 212 if ((file->f_flags & O_ACCMODE) == O_RDONLY) 213 return -EPERM; 214 if (file->private_data == NULL && 215 cmd != ANDROID_ALARM_SET_RTC) { 216 spin_lock_irqsave(&alarm_slock, flags); 217 if (alarm_opened) { 218 spin_unlock_irqrestore(&alarm_slock, flags); 219 return -EBUSY; 220 } 221 alarm_opened = 1; 222 file->private_data = (void *)1; 223 spin_unlock_irqrestore(&alarm_slock, flags); 224 } 225 } 226 227 switch (ANDROID_ALARM_BASE_CMD(cmd)) { 228 case ANDROID_ALARM_CLEAR(0): 229 alarm_clear(alarm_type); 230 break; 231 case ANDROID_ALARM_SET(0): 232 alarm_set(alarm_type, ts); 233 break; 234 case ANDROID_ALARM_SET_AND_WAIT(0): 235 alarm_set(alarm_type, ts); 236 /* fall though */ 237 case ANDROID_ALARM_WAIT: 238 rv = alarm_wait(); 239 break; 240 case ANDROID_ALARM_SET_RTC: 241 rv = alarm_set_rtc(ts); 242 break; 243 case ANDROID_ALARM_GET_TIME(0): 244 rv = alarm_get_time(alarm_type, ts); 245 break; 246 247 default: 248 rv = -EINVAL; 249 } 250 return rv; 251} 252 253static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 254{ 255 256 struct timespec ts; 257 int rv; 258 259 switch (ANDROID_ALARM_BASE_CMD(cmd)) { 260 case ANDROID_ALARM_SET_AND_WAIT(0): 261 case ANDROID_ALARM_SET(0): 262 case ANDROID_ALARM_SET_RTC: 263 if (copy_from_user(&ts, (void __user *)arg, sizeof(ts))) 264 return -EFAULT; 265 break; 266 } 267 268 rv = alarm_do_ioctl(file, cmd, &ts); 269 if (rv) 270 return rv; 271 272 switch (ANDROID_ALARM_BASE_CMD(cmd)) { 273 case ANDROID_ALARM_GET_TIME(0): 274 if (copy_to_user((void __user *)arg, &ts, sizeof(ts))) 275 return -EFAULT; 276 break; 277 } 278 279 return 0; 280} 281 282#ifdef CONFIG_COMPAT 283static long alarm_compat_ioctl(struct file *file, unsigned int cmd, 284 unsigned long arg) 285{ 286 287 struct timespec ts; 288 int rv; 289 290 switch (ANDROID_ALARM_BASE_CMD(cmd)) { 291 case ANDROID_ALARM_SET_AND_WAIT_COMPAT(0): 292 case ANDROID_ALARM_SET_COMPAT(0): 293 case ANDROID_ALARM_SET_RTC_COMPAT: 294 if (compat_get_timespec(&ts, (void __user *)arg)) 295 return -EFAULT; 296 /* fall through */ 297 case ANDROID_ALARM_GET_TIME_COMPAT(0): 298 cmd = ANDROID_ALARM_COMPAT_TO_NORM(cmd); 299 break; 300 } 301 302 rv = alarm_do_ioctl(file, cmd, &ts); 303 if (rv) 304 return rv; 305 306 switch (ANDROID_ALARM_BASE_CMD(cmd)) { 307 case ANDROID_ALARM_GET_TIME(0): /* NOTE: we modified cmd above */ 308 if (compat_put_timespec(&ts, (void __user *)arg)) 309 return -EFAULT; 310 break; 311 } 312 313 return 0; 314} 315#endif 316 317static int alarm_open(struct inode *inode, struct file *file) 318{ 319 file->private_data = NULL; 320 return 0; 321} 322 323static int alarm_release(struct inode *inode, struct file *file) 324{ 325 int i; 326 unsigned long flags; 327 328 spin_lock_irqsave(&alarm_slock, flags); 329 if (file->private_data) { 330 for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { 331 uint32_t alarm_type_mask = 1U << i; 332 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 374static enum hrtimer_restart devalarm_hrthandler(struct hrtimer *hrt) 375{ 376 struct devalarm *devalrm = container_of(hrt, struct devalarm, u.hrt); 377 378 devalarm_triggered(devalrm); 379 return HRTIMER_NORESTART; 380} 381 382static enum alarmtimer_restart devalarm_alarmhandler(struct alarm *alrm, 383 ktime_t now) 384{ 385 struct devalarm *devalrm = container_of(alrm, struct devalarm, u.alrm); 386 387 devalarm_triggered(devalrm); 388 return ALARMTIMER_NORESTART; 389} 390 391 392static const struct file_operations alarm_fops = { 393 .owner = THIS_MODULE, 394 .unlocked_ioctl = alarm_ioctl, 395 .open = alarm_open, 396 .release = alarm_release, 397#ifdef CONFIG_COMPAT 398 .compat_ioctl = alarm_compat_ioctl, 399#endif 400}; 401 402static struct miscdevice alarm_device = { 403 .minor = MISC_DYNAMIC_MINOR, 404 .name = "alarm", 405 .fops = &alarm_fops, 406}; 407 408static int __init alarm_dev_init(void) 409{ 410 int err; 411 int i; 412 413 err = misc_register(&alarm_device); 414 if (err) 415 return err; 416 417 alarm_init(&alarms[ANDROID_ALARM_RTC_WAKEUP].u.alrm, 418 ALARM_REALTIME, devalarm_alarmhandler); 419 hrtimer_init(&alarms[ANDROID_ALARM_RTC].u.hrt, 420 CLOCK_REALTIME, HRTIMER_MODE_ABS); 421 alarm_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].u.alrm, 422 ALARM_BOOTTIME, devalarm_alarmhandler); 423 hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME].u.hrt, 424 CLOCK_BOOTTIME, HRTIMER_MODE_ABS); 425 hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt, 426 CLOCK_MONOTONIC, HRTIMER_MODE_ABS); 427 428 for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { 429 alarms[i].type = i; 430 if (!is_wakeup(i)) 431 alarms[i].u.hrt.function = devalarm_hrthandler; 432 } 433 434 wakeup_source_init(&alarm_wake_lock, "alarm"); 435 return 0; 436} 437 438static void __exit alarm_dev_exit(void) 439{ 440 misc_deregister(&alarm_device); 441 wakeup_source_trash(&alarm_wake_lock); 442} 443 444module_init(alarm_dev_init); 445module_exit(alarm_dev_exit); 446MODULE_LICENSE("GPL");