at v3.14-rc4 445 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 if (alarm_enabled & alarm_type_mask) { 333 alarm_dbg(INFO, 334 "%s: clear alarm, pending %d\n", 335 __func__, 336 !!(alarm_pending & alarm_type_mask)); 337 alarm_enabled &= ~alarm_type_mask; 338 } 339 spin_unlock_irqrestore(&alarm_slock, flags); 340 devalarm_cancel(&alarms[i]); 341 spin_lock_irqsave(&alarm_slock, flags); 342 } 343 if (alarm_pending | wait_pending) { 344 if (alarm_pending) 345 alarm_dbg(INFO, "%s: clear pending alarms %x\n", 346 __func__, alarm_pending); 347 __pm_relax(&alarm_wake_lock); 348 wait_pending = 0; 349 alarm_pending = 0; 350 } 351 alarm_opened = 0; 352 } 353 spin_unlock_irqrestore(&alarm_slock, flags); 354 return 0; 355} 356 357static void devalarm_triggered(struct devalarm *alarm) 358{ 359 unsigned long flags; 360 uint32_t alarm_type_mask = 1U << alarm->type; 361 362 alarm_dbg(INT, "%s: type %d\n", __func__, alarm->type); 363 spin_lock_irqsave(&alarm_slock, flags); 364 if (alarm_enabled & alarm_type_mask) { 365 __pm_wakeup_event(&alarm_wake_lock, 5000); /* 5secs */ 366 alarm_enabled &= ~alarm_type_mask; 367 alarm_pending |= alarm_type_mask; 368 wake_up(&alarm_wait_queue); 369 } 370 spin_unlock_irqrestore(&alarm_slock, flags); 371} 372 373static enum hrtimer_restart devalarm_hrthandler(struct hrtimer *hrt) 374{ 375 struct devalarm *devalrm = container_of(hrt, struct devalarm, u.hrt); 376 377 devalarm_triggered(devalrm); 378 return HRTIMER_NORESTART; 379} 380 381static enum alarmtimer_restart devalarm_alarmhandler(struct alarm *alrm, 382 ktime_t now) 383{ 384 struct devalarm *devalrm = container_of(alrm, struct devalarm, u.alrm); 385 386 devalarm_triggered(devalrm); 387 return ALARMTIMER_NORESTART; 388} 389 390 391static const struct file_operations alarm_fops = { 392 .owner = THIS_MODULE, 393 .unlocked_ioctl = alarm_ioctl, 394 .open = alarm_open, 395 .release = alarm_release, 396#ifdef CONFIG_COMPAT 397 .compat_ioctl = alarm_compat_ioctl, 398#endif 399}; 400 401static struct miscdevice alarm_device = { 402 .minor = MISC_DYNAMIC_MINOR, 403 .name = "alarm", 404 .fops = &alarm_fops, 405}; 406 407static int __init alarm_dev_init(void) 408{ 409 int err; 410 int i; 411 412 err = misc_register(&alarm_device); 413 if (err) 414 return err; 415 416 alarm_init(&alarms[ANDROID_ALARM_RTC_WAKEUP].u.alrm, 417 ALARM_REALTIME, devalarm_alarmhandler); 418 hrtimer_init(&alarms[ANDROID_ALARM_RTC].u.hrt, 419 CLOCK_REALTIME, HRTIMER_MODE_ABS); 420 alarm_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].u.alrm, 421 ALARM_BOOTTIME, devalarm_alarmhandler); 422 hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME].u.hrt, 423 CLOCK_BOOTTIME, HRTIMER_MODE_ABS); 424 hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt, 425 CLOCK_MONOTONIC, HRTIMER_MODE_ABS); 426 427 for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { 428 alarms[i].type = i; 429 if (!is_wakeup(i)) 430 alarms[i].u.hrt.function = devalarm_hrthandler; 431 } 432 433 wakeup_source_init(&alarm_wake_lock, "alarm"); 434 return 0; 435} 436 437static void __exit alarm_dev_exit(void) 438{ 439 misc_deregister(&alarm_device); 440 wakeup_source_trash(&alarm_wake_lock); 441} 442 443module_init(alarm_dev_init); 444module_exit(alarm_dev_exit); 445