static long alarm_do_ioctl(struct file *file, unsigned int cmd, struct timespec *ts) { int rv = 0; unsigned long flags; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) return -EINVAL; if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0) && ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_WAIT_CHANGE) { if ((file->f_flags & O_ACCMODE) == O_RDONLY) return -EPERM; if (file->private_data == NULL && cmd != ANDROID_ALARM_SET_RTC) { spin_lock_irqsave(&alarm_slock, flags); if (alarm_opened) { spin_unlock_irqrestore(&alarm_slock, flags); return -EBUSY; } alarm_opened = 1; file->private_data = (void *)1; spin_unlock_irqrestore(&alarm_slock, flags); } } switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_CLEAR(0): alarm_clear(alarm_type); break; case ANDROID_ALARM_SET(0): alarm_set(alarm_type, ts); break; case ANDROID_ALARM_SET_AND_WAIT(0): alarm_set(alarm_type, ts); /* fall though */ case ANDROID_ALARM_WAIT: rv = alarm_wait(); break; case ANDROID_ALARM_WAIT_CHANGE: { rv = wait_event_interruptible(alarm_wait_change_queue, delta); if (rv == -ERESTARTSYS) { rv = -EINTR; } break; } case ANDROID_ALARM_SET_RTC: rv = alarm_set_rtc(ts); break; case ANDROID_ALARM_GET_TIME(0): rv = alarm_get_time(alarm_type, ts); break; default: rv = -EINVAL; } err1: return rv; }
static long alarm_do_ioctl(struct file *file, unsigned int cmd, struct timespec *ts) { int rv = 0; unsigned long flags; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) return -EINVAL; if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { if ((file->f_flags & O_ACCMODE) == O_RDONLY) return -EPERM; if (file->private_data == NULL && cmd != ANDROID_ALARM_SET_RTC) { spin_lock_irqsave(&alarm_slock, flags); if (alarm_opened) { spin_unlock_irqrestore(&alarm_slock, flags); return -EBUSY; } alarm_opened = 1; file->private_data = (void *)1; spin_unlock_irqrestore(&alarm_slock, flags); } } switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_CLEAR(0): alarm_clear(alarm_type); break; case ANDROID_ALARM_SET(0): alarm_set(alarm_type, ts); break; case ANDROID_ALARM_SET_AND_WAIT(0): alarm_set(alarm_type, ts); /* fall though */ case ANDROID_ALARM_WAIT: rv = alarm_wait(); break; case ANDROID_ALARM_SET_RTC: rv = alarm_set_rtc(ts); break; #ifdef CONFIG_RTC_BOOT_ALARM case ANDROID_ALARM_SET_BOOT_ALARM: rv = alarm_set_boot_alarm(ts); break; #endif case ANDROID_ALARM_GET_TIME(0): rv = alarm_get_time(alarm_type, ts); break; default: rv = -EINVAL; } return rv; }
UINT64 GKI_now_us() { struct timespec ts_now; #ifdef HAVE_ANDROID_OS static int s_fd = -1; int result; if (s_fd == -1) { int fd = open("/dev/alarm", O_RDONLY); if (android_atomic_cmpxchg(-1, fd, &s_fd)) { close(fd); } } result = ioctl(s_fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts_now); if (result != 0) { #endif clock_gettime(CLOCK_BOOTTIME, &ts_now); #ifdef HAVE_ANDROID_OS } #endif return ((UINT64)ts_now.tv_sec * USEC_PER_SEC) + ((UINT64)ts_now.tv_nsec / NSEC_PER_USEC); }
/* * native public static long elapsedRealtime(); */ int64_t elapsedRealtime() { #ifdef HAVE_ANDROID_OS static int s_fd = -1; if (s_fd == -1) { int fd = open("/dev/alarm", O_RDONLY); if (android_atomic_cmpxchg(-1, fd, &s_fd)) { close(fd); } } struct timespec ts; int result = ioctl(s_fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts); if (result == 0) { int64_t when = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec; return (int64_t) nanoseconds_to_milliseconds(when); } else { // XXX: there was an error, probably because the driver didn't // exist ... this should return // a real error, like an exception! int64_t when = systemTime(SYSTEM_TIME_MONOTONIC); return (int64_t) nanoseconds_to_milliseconds(when); } #else int64_t when = systemTime(SYSTEM_TIME_MONOTONIC); return (int64_t) nanoseconds_to_milliseconds(when); #endif }
static long alarm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct timespec ts; int rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_SET_AND_WAIT_COMPAT(0): case ANDROID_ALARM_SET_COMPAT(0): case ANDROID_ALARM_SET_RTC_COMPAT: if (compat_get_timespec(&ts, (void __user *)arg)) return -EFAULT; /* fall through */ case ANDROID_ALARM_GET_TIME_COMPAT(0): cmd = ANDROID_ALARM_COMPAT_TO_NORM(cmd); break; } rv = alarm_do_ioctl(file, cmd, &ts); if (rv) return rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_GET_TIME(0): /* NOTE: we modified cmd above */ if (compat_put_timespec(&ts, (void __user *)arg)) return -EFAULT; break; } return 0; }
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct timespec ts; int rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_SET_AND_WAIT(0): case ANDROID_ALARM_SET(0): case ANDROID_ALARM_SET_RTC: if (copy_from_user(&ts, (void __user *)arg, sizeof(ts))) return -EFAULT; break; } rv = alarm_do_ioctl(file, cmd, &ts); if (rv) return rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_GET_TIME(0): if (copy_to_user((void __user *)arg, &ts, sizeof(ts))) return -EFAULT; break; } return 0; }
/* * native public static long elapsedRealtimeNano(); */ int64_t elapsedRealtimeNano() { #ifdef HAVE_ANDROID_OS struct timespec ts; int result; int64_t timestamp; #if DEBUG_TIMESTAMP static volatile int64_t prevTimestamp; static volatile int prevMethod; #endif static int s_fd = -1; if (s_fd == -1) { int fd = open("/dev/alarm", O_RDONLY); if (android_atomic_cmpxchg(-1, fd, &s_fd)) { close(fd); } } result = ioctl(s_fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts); if (result == 0) { timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec; checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, METHOD_IOCTL); return timestamp; } // /dev/alarm doesn't exist, fallback to CLOCK_BOOTTIME result = clock_gettime(CLOCK_BOOTTIME, &ts); if (result == 0) { timestamp = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec; checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, METHOD_CLOCK_GETTIME); return timestamp; } // XXX: there was an error, probably because the driver didn't // exist ... this should return // a real error, like an exception! timestamp = systemTime(SYSTEM_TIME_MONOTONIC); checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, METHOD_SYSTEMTIME); return timestamp; #else return systemTime(SYSTEM_TIME_MONOTONIC); #endif }
int64_t elapsedRealtime() { struct timespec ts; int fd, result; fd = open("/dev/alarm", O_RDONLY); if (fd < 0) return fd; result = ioctl(fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts); close(fd); if (result == 0) return ts.tv_sec; return -1; }
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int rv = 0; unsigned long flags; struct timespec new_alarm_time; struct timespec new_rtc_time; struct timespec tmp_time; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); uint32_t alarm_type_mask = 1U << alarm_type; int new_alarm_status; if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) return -EINVAL; if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { if ((file->f_flags & O_ACCMODE) == O_RDONLY) return -EPERM; if (file->private_data == NULL && cmd != ANDROID_ALARM_SET_RTC) { spin_lock_irqsave(&alarm_slock, flags); if (alarm_opened) { spin_unlock_irqrestore(&alarm_slock, flags); return -EBUSY; } alarm_opened = 1; file->private_data = (void *)1; spin_unlock_irqrestore(&alarm_slock, flags); } } switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_REMOVE(0): if (alarm_type != ANDROID_ALARM_RTC_HW_WAKEUP) break; if (copy_from_user(&new_alarm_time, (void __user *)arg, sizeof(new_alarm_time))) { rv = -EFAULT; goto err1; } spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d remove %ld.%09ld\n", alarm_type, new_alarm_time.tv_sec, new_alarm_time.tv_nsec); if ((alarms[alarm_type].expires.tv64 == timespec_to_ktime(new_alarm_time).tv64 && alarms[alarm_type].softexpires.tv64 == timespec_to_ktime(new_alarm_time).tv64) || timespec_to_ktime(new_alarm_time).tv64 == 0) { alarm_start_range(&alarms[alarm_type], (ktime_t){ .tv64 = 0 }, (ktime_t){ .tv64 = 0 });
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct timespec ts; int rv; #if defined(CONFIG_RTC_ALARM_BOOT) char bootalarm_data[14]; #endif switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_SET_AND_WAIT(0): case ANDROID_ALARM_SET(0): case ANDROID_ALARM_SET_RTC: if (copy_from_user(&ts, (void __user *)arg, sizeof(ts))) return -EFAULT; break; #if defined(CONFIG_RTC_ALARM_BOOT) case ANDROID_ALARM_SET_ALARM_BOOT: if (copy_from_user(bootalarm_data, (void __user *)arg, 14)) { return -EFAULT; } rv = alarm_set_alarm_boot(bootalarm_data); alarm_opened = 1; return rv; break; #endif } rv = alarm_do_ioctl(file, cmd, &ts); if (rv) return rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_GET_TIME(0): if (copy_to_user((void __user *)arg, &ts, sizeof(ts))) return -EFAULT; break; } return 0; }
static long alarm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct timespec ts; struct rtc_wkalrm pwron_alm; int rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_SET_AND_WAIT_COMPAT(0): case ANDROID_ALARM_SET_COMPAT(0): case ANDROID_ALARM_SET_RTC_COMPAT: case ANDROID_ALARM_SET_IPO_COMPAT(0): if (compat_get_timespec(&ts, (void __user *)arg)) return -EFAULT; /* fall through */ case ANDROID_ALARM_GET_TIME_COMPAT(0): cmd = ANDROID_ALARM_COMPAT_TO_NORM(cmd); break; } rv = alarm_do_ioctl(file, cmd, &ts, &pwron_alm); if (rv) return rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_GET_TIME(0): /* NOTE: we modified cmd above */ if (compat_put_timespec(&ts, (void __user *)arg)) return -EFAULT; break; case ANDROID_ALARM_GET_POWER_ON: case ANDROID_ALARM_GET_POWER_ON_IPO: if (copy_to_user((void __user *)arg, &pwron_alm, sizeof(struct rtc_wkalrm))) { rv = -EFAULT; return rv; } break; } return 0; }
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct timespec ts; int rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_SET_AND_WAIT(0): case ANDROID_ALARM_SET(0): case ANDROID_ALARM_SET_RTC: if (copy_from_user(&ts, (void __user *)arg, sizeof(ts))) return -EFAULT; break; } rv = alarm_do_ioctl(file, cmd, &ts); if (rv) return rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_GET_TIME(0): if (copy_to_user((void __user *)arg, &ts, sizeof(ts))) return -EFAULT; break; case ANDROID_ALARM_WAIT_CHANGE: { unsigned long flags; spin_lock_irqsave(&alarm_slock, flags); if (copy_to_user((void __user *)arg, &delta, 4)) { rv = -EFAULT; delta = 0; spin_unlock_irqrestore(&alarm_slock, flags); return rv; } delta = 0; spin_unlock_irqrestore(&alarm_slock, flags); break; } } return 0; }
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct timespec ts; struct rtc_wkalrm pwron_alm; int rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_SET_AND_WAIT(0): case ANDROID_ALARM_SET(0): case ANDROID_ALARM_SET_RTC: case ANDROID_ALARM_SET_IPO(0): if (copy_from_user(&ts, (void __user *)arg, sizeof(ts))) return -EFAULT; break; } rv = alarm_do_ioctl(file, cmd, &ts, &pwron_alm); if (rv) return rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_GET_TIME(0): if (copy_to_user((void __user *)arg, &ts, sizeof(ts))) return -EFAULT; break; case ANDROID_ALARM_GET_POWER_ON: case ANDROID_ALARM_GET_POWER_ON_IPO: if (copy_to_user((void __user *)arg, &pwron_alm, sizeof(struct rtc_wkalrm))) { rv = -EFAULT; return rv; } break; default: break; } return 0; }
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct timespec ts; int rv; #ifdef CONFIG_RTC_AUTO_PWRON char bootalarm_data[14]; #endif switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_SET_AND_WAIT(0): case ANDROID_ALARM_SET(0): case ANDROID_ALARM_SET_RTC: case ANDROID_ALARM_CLEAR(0): if (copy_from_user(&ts, (void __user *)arg, sizeof(ts))) return -EFAULT; break; #ifdef CONFIG_RTC_AUTO_PWRON case ANDROID_ALARM_SET_ALARM: pr_info("[SAPA] %s\n", __func__); if (copy_from_user(bootalarm_data, (void __user *)arg, 14)) rv = -EFAULT; rv = alarm_set_alarm(bootalarm_data); break; #endif } rv = alarm_do_ioctl(file, cmd, &ts); if (rv) return rv; switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_GET_TIME(0): if (copy_to_user((void __user *)arg, &ts, sizeof(ts))) return -EFAULT; break; } return 0; }
static int is_set_cmd(unsigned int cmd) { if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) return 1; return 0; }
int alarm_main(int argc, char *argv[]) { int c; int res; struct tm tm; time_t t; struct timespec ts; // struct rtc_time rtc_time; char strbuf[26]; int afd; int nfd; // struct timeval timeout = { 0, 0 }; int wait = 0; fd_set rfds; const char wake_lock_id[] = "alarm_test"; int waitalarmmask = 0; int useutc = 0; android_alarm_type_t alarmtype_low = ANDROID_ALARM_RTC_WAKEUP; android_alarm_type_t alarmtype_high = ANDROID_ALARM_RTC_WAKEUP; android_alarm_type_t alarmtype = 0; do { //c = getopt(argc, argv, "uw:"); c = getopt(argc, argv, "uwat:"); if (c == EOF) break; switch (c) { case 'u': useutc = 1; break; case 't': alarmtype_low = alarmtype_high = strtol(optarg, NULL, 0); break; case 'a': alarmtype_low = ANDROID_ALARM_RTC_WAKEUP; alarmtype_high = ANDROID_ALARM_TYPE_COUNT - 1; break; case 'w': //timeout.tv_sec = strtol(optarg, NULL, 0); wait = 1; break; case '?': fprintf(stderr, "%s: invalid option -%c\n", argv[0], optopt); exit(1); } } while (1); if(optind + 2 < argc) { fprintf(stderr,"%s [-uwa] [-t type] [seconds]\n", argv[0]); return 1; } afd = open("/dev/alarm", O_RDWR); if(afd < 0) { fprintf(stderr, "Unable to open rtc: %s\n", strerror(errno)); return 1; } if(optind == argc) { for(alarmtype = alarmtype_low; alarmtype <= alarmtype_high; alarmtype++) { waitalarmmask |= 1U << alarmtype; } #if 0 res = ioctl(fd, RTC_ALM_READ, &tm); if(res < 0) { fprintf(stderr, "Unable to read alarm: %s\n", strerror(errno)); return 1; } #endif #if 0 t = timegm(&tm); if(useutc) gmtime_r(&t, &tm); else localtime_r(&t, &tm); #endif #if 0 asctime_r(&tm, strbuf); printf("%s", strbuf); #endif } else if(optind + 1 == argc) { #if 0 res = ioctl(fd, RTC_RD_TIME, &tm); if(res < 0) { fprintf(stderr, "Unable to set alarm: %s\n", strerror(errno)); return 1; } asctime_r(&tm, strbuf); printf("Now: %s", strbuf); time(&tv.tv_sec); #endif #if 0 time(&ts.tv_sec); ts.tv_nsec = 0; //strptime(argv[optind], NULL, &tm); //tv.tv_sec = mktime(&tm); //tv.tv_usec = 0; #endif for(alarmtype = alarmtype_low; alarmtype <= alarmtype_high; alarmtype++) { waitalarmmask |= 1U << alarmtype; res = ioctl(afd, ANDROID_ALARM_GET_TIME(alarmtype), &ts); if(res < 0) { fprintf(stderr, "Unable to get current time: %s\n", strerror(errno)); return 1; } ts.tv_sec += strtol(argv[optind], NULL, 0); //strtotimeval(argv[optind], &tv); gmtime_r(&ts.tv_sec, &tm); printf("time %s -> %ld.%09ld\n", argv[optind], ts.tv_sec, ts.tv_nsec); asctime_r(&tm, strbuf); printf("Requested %s", strbuf); res = ioctl(afd, ANDROID_ALARM_SET(alarmtype), &ts); if(res < 0) { fprintf(stderr, "Unable to set alarm: %s\n", strerror(errno)); return 1; } } #if 0 res = ioctl(fd, RTC_ALM_SET, &tm); if(res < 0) { fprintf(stderr, "Unable to set alarm: %s\n", strerror(errno)); return 1; } res = ioctl(fd, RTC_AIE_ON); if(res < 0) { fprintf(stderr, "Unable to enable alarm: %s\n", strerror(errno)); return 1; } #endif } else { fprintf(stderr,"%s [-u] [date]\n", argv[0]); return 1; } if(wait) { while(waitalarmmask) { printf("wait for alarm %x\n", waitalarmmask); res = ioctl(afd, ANDROID_ALARM_WAIT); if(res < 0) { fprintf(stderr, "alarm wait failed\n"); } printf("got alarm %x\n", res); waitalarmmask &= ~res; nfd = open("/sys/android_power/acquire_full_wake_lock", O_RDWR); write(nfd, wake_lock_id, sizeof(wake_lock_id) - 1); close(nfd); //sleep(5); nfd = open("/sys/android_power/release_wake_lock", O_RDWR); write(nfd, wake_lock_id, sizeof(wake_lock_id) - 1); close(nfd); } printf("done\n"); } #if 0 FD_ZERO(&rfds); FD_SET(fd, &rfds); res = select(fd + 1, &rfds, NULL, NULL, &timeout); if(res < 0) { fprintf(stderr, "select failed: %s\n", strerror(errno)); return 1; } if(res > 0) { int event; read(fd, &event, sizeof(event)); fprintf(stderr, "got %x\n", event); } else { fprintf(stderr, "timeout waiting for alarm\n"); } #endif close(afd); return 0; }
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { /* Using u32 instead of int for 32bit uspace and 64bit kernel */ u32 rv = 0; unsigned long flags; struct timespec new_alarm_time; struct timespec new_rtc_time; struct timespec tmp_time; uint32_t alarm_type_mask = 0; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); if (alarm_type == ANDROID_ALARM_RTC_DEVICEUP) alarm_type=ANDROID_ALARM_POWER_OFF_WAKEUP; if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) return -EINVAL; alarm_type_mask = 1U << alarm_type; if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { if ((file->f_flags & O_ACCMODE) == O_RDONLY) return -EPERM; if (file->private_data == NULL && cmd != ANDROID_ALARM_SET_RTC) { spin_lock_irqsave(&alarm_slock, flags); if (alarm_opened) { spin_unlock_irqrestore(&alarm_slock, flags); return -EBUSY; } alarm_opened = 1; file->private_data = (void *)1; spin_unlock_irqrestore(&alarm_slock, flags); } } switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_CLEAR(0): spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d clear\n", alarm_type); alarm_try_to_cancel(&alarms[alarm_type]); if (alarm_pending) { alarm_pending &= ~alarm_type_mask; if (!alarm_pending && !wait_pending) wake_unlock(&alarm_wake_lock); } alarm_enabled &= ~alarm_type_mask; spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_OLD: case ANDROID_ALARM_SET_AND_WAIT_OLD: if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) { rv = -EFAULT; goto err1; } new_alarm_time.tv_nsec = 0; goto from_old_alarm_set; case ANDROID_ALARM_SET_AND_WAIT(0): case ANDROID_ALARM_SET(0): if (copy_from_user(&new_alarm_time, (void __user *)arg, sizeof(new_alarm_time))) { rv = -EFAULT; goto err1; } from_old_alarm_set: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type, new_alarm_time.tv_sec, new_alarm_time.tv_nsec); alarm_enabled |= alarm_type_mask; alarm_start_range(&alarms[alarm_type], timespec_to_ktime(new_alarm_time), timespec_to_ktime(new_alarm_time)); spin_unlock_irqrestore(&alarm_slock, flags); if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD) break; /* fall though */ case ANDROID_ALARM_WAIT: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm wait\n"); if (!alarm_pending && wait_pending) { wake_unlock(&alarm_wake_lock); wait_pending = 0; } spin_unlock_irqrestore(&alarm_slock, flags); rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); if (rv) goto err1; //AndyPan add if (alarm_pending & pwoff_mask) { //printk("andy alarm_pending &= ~ pwoff_mask =%d \r\n",alarm_pending); alarm_pending &= ~ pwoff_mask; alarm_pending |= deviceup_mask; //printk("andy alarm_pending |= deviceup_mask =%d \r\n",alarm_pending); } //AndyPan add spin_lock_irqsave(&alarm_slock, flags); rv = alarm_pending; wait_pending = 1; alarm_pending = 0; spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_RTC: if (copy_from_user(&new_rtc_time, (void __user *)arg, sizeof(new_rtc_time))) { rv = -EFAULT; goto err1; } rv = alarm_set_rtc(new_rtc_time); spin_lock_irqsave(&alarm_slock, flags); alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; wake_up(&alarm_wait_queue); spin_unlock_irqrestore(&alarm_slock, flags); if (rv < 0) goto err1; break; case ANDROID_ALARM_GET_TIME(0): switch (alarm_type) { case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_RTC: case ANDROID_ALARM_POWER_OFF_WAKEUP: getnstimeofday(&tmp_time); break; case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME: tmp_time = ktime_to_timespec(alarm_get_elapsed_realtime()); break; case ANDROID_ALARM_TYPE_COUNT: case ANDROID_ALARM_SYSTEMTIME: ktime_get_ts(&tmp_time); break; } if (copy_to_user((void __user *)arg, &tmp_time, sizeof(tmp_time))) { rv = -EFAULT; goto err1; } break; default: rv = -EINVAL; goto err1; } err1: return rv; }
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int rv = 0; unsigned long flags; struct timespec new_alarm_time; struct timespec new_rtc_time; struct timespec tmp_time; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); uint32_t alarm_type_mask = 1U << alarm_type; if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) return -EINVAL; if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { if ((file->f_flags & O_ACCMODE) == O_RDONLY) return -EPERM; if (file->private_data == NULL && cmd != ANDROID_ALARM_SET_RTC) { spin_lock_irqsave(&alarm_slock, flags); if (alarm_opened) { spin_unlock_irqrestore(&alarm_slock, flags); return -EBUSY; } alarm_opened = 1; file->private_data = (void *)1; spin_unlock_irqrestore(&alarm_slock, flags); } } switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_CLEAR(0): spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d clear\n", alarm_type); alarm_try_to_cancel(&alarms[alarm_type]); if (alarm_pending) { alarm_pending &= ~alarm_type_mask; if (!alarm_pending && !wait_pending) wake_unlock(&alarm_wake_lock); } alarm_enabled &= ~alarm_type_mask; if (alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP) set_power_on_alarm(0); spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_OLD: case ANDROID_ALARM_SET_AND_WAIT_OLD: if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) { rv = -EFAULT; goto err1; } new_alarm_time.tv_nsec = 0; goto from_old_alarm_set; case ANDROID_ALARM_SET_AND_WAIT(0): case ANDROID_ALARM_SET(0): if (copy_from_user(&new_alarm_time, (void __user *)arg, sizeof(new_alarm_time))) { rv = -EFAULT; goto err1; } from_old_alarm_set: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type, new_alarm_time.tv_sec, new_alarm_time.tv_nsec); // ASUS_BSP+++ Shawn_Huang "Add debug log for setting alarm " ktime_get_ts(&tmp_time); printk("asus_alarm %d now %ld.%09ld, set %ld.%09ld\n", alarm_type, tmp_time.tv_sec, tmp_time.tv_nsec, new_alarm_time.tv_sec, new_alarm_time.tv_nsec); // ASUS_BSP--- Shawn_Huang "Add debug log for setting alarm " alarm_enabled |= alarm_type_mask; alarm_start_range(&alarms[alarm_type], timespec_to_ktime(new_alarm_time), timespec_to_ktime(new_alarm_time)); if ((alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP) && (ANDROID_ALARM_BASE_CMD(cmd) == ANDROID_ALARM_SET(0))) set_power_on_alarm(new_alarm_time.tv_sec); spin_unlock_irqrestore(&alarm_slock, flags); if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD) break; /* fall though */ case ANDROID_ALARM_WAIT: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm wait\n"); if (!alarm_pending && wait_pending) { wake_unlock(&alarm_wake_lock); wait_pending = 0; } spin_unlock_irqrestore(&alarm_slock, flags); rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); if (rv) goto err1; spin_lock_irqsave(&alarm_slock, flags); rv = alarm_pending; wait_pending = 1; alarm_pending = 0; spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_RTC: if (copy_from_user(&new_rtc_time, (void __user *)arg, sizeof(new_rtc_time))) { rv = -EFAULT; goto err1; } rv = alarm_set_rtc(new_rtc_time); spin_lock_irqsave(&alarm_slock, flags); alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; wake_up(&alarm_wait_queue); spin_unlock_irqrestore(&alarm_slock, flags); { // jack added to get correct time for last shutdown log +++++++++++ if(!asus_rtc_set) { asus_rtc_set = 1; } }// jack added to get correct time for last shutdown log ------------ if (rv < 0) goto err1; break; case ANDROID_ALARM_GET_TIME(0): switch (alarm_type) { case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_RTC: case ANDROID_ALARM_RTC_POWEROFF_WAKEUP: getnstimeofday(&tmp_time); break; case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME: tmp_time = ktime_to_timespec(alarm_get_elapsed_realtime()); break; case ANDROID_ALARM_TYPE_COUNT: case ANDROID_ALARM_SYSTEMTIME: ktime_get_ts(&tmp_time); break; } if (copy_to_user((void __user *)arg, &tmp_time, sizeof(tmp_time))) { rv = -EFAULT; goto err1; } break; default: rv = -EINVAL; goto err1; } err1: return rv; }
static long alarm_do_ioctl(struct file *file, unsigned int cmd, struct timespec *ts, struct rtc_wkalrm *alm) { int rv = 0; unsigned long flags; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); alarm_dbg(INFO, "alarm_do_ioctl cmd:%d type:%d (%lu)\n", cmd, alarm_type, (uintptr_t)file->private_data); if (alarm_type >= ANDROID_ALARM_TYPE_COUNT && alarm_type != ANDROID_ALARM_POWER_ON && alarm_type != ANDROID_ALARM_POWER_ON_LOGO) { return -EINVAL; } if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0) && ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_IPO(0) && ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_POWER_ON_IPO) { if ((file->f_flags & O_ACCMODE) == O_RDONLY) return -EPERM; if (file->private_data == NULL && cmd != ANDROID_ALARM_SET_RTC) { spin_lock_irqsave(&alarm_slock, flags); if (alarm_opened) { spin_unlock_irqrestore(&alarm_slock, flags); alarm_dbg(INFO, "alarm_do_ioctl EBUSY\n"); file->private_data = NULL; return -EBUSY; } alarm_opened = 1; file->private_data = (void *)1; spin_unlock_irqrestore(&alarm_slock, flags); alarm_dbg(INFO, "alarm_do_ioctl opened\n"); } } switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_CLEAR(0): alarm_clear(alarm_type, ts); break; case ANDROID_ALARM_SET(0): alarm_set(alarm_type, ts); break; case ANDROID_ALARM_SET_AND_WAIT(0): alarm_set(alarm_type, ts); /* fall though */ case ANDROID_ALARM_WAIT: rv = alarm_wait(); break; case ANDROID_ALARM_SET_IPO(0): alarm_set(alarm_type, ts); break; case ANDROID_ALARM_SET_AND_WAIT_IPO(0): alarm_set(alarm_type, ts); /* fall though */ case ANDROID_ALARM_WAIT_IPO: rv = alarm_wait(); break; case ANDROID_ALARM_SET_RTC: rv = alarm_set_rtc(ts); break; case ANDROID_ALARM_GET_TIME(0): rv = alarm_get_time(alarm_type, ts); break; case ANDROID_ALARM_GET_POWER_ON: alarm_get_power_on(alm); break; case ANDROID_ALARM_GET_POWER_ON_IPO: alarm_get_power_on(alm); break; default: rv = -EINVAL; } return rv; }
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int rv = 0; unsigned long flags; struct timespec new_alarm_time; struct timespec new_rtc_time; struct timespec tmp_time; struct rtc_time new_rtc_tm; struct rtc_device *rtc_dev; struct rtc_wkalrm pwron_alm; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); uint32_t alarm_type_mask = 1U << alarm_type; if (alarm_type >= ANDROID_ALARM_TYPE_COUNT && alarm_type != ANDROID_ALARM_POWER_ON && alarm_type != ANDROID_ALARM_POWER_ON_LOGO) { return -EINVAL; } if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { if ((file->f_flags & O_ACCMODE) == O_RDONLY) return -EPERM; if (file->private_data == NULL && cmd != ANDROID_ALARM_SET_RTC) { spin_lock_irqsave(&alarm_slock, flags); if (alarm_opened) { spin_unlock_irqrestore(&alarm_slock, flags); return -EBUSY; } alarm_opened = 1; file->private_data = (void *)1; spin_unlock_irqrestore(&alarm_slock, flags); } } switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_CLEAR(0): pr_alarm(IO, "alarm %d clear\n", alarm_type); if (alarm_type == ANDROID_ALARM_POWER_ON || alarm_type == ANDROID_ALARM_POWER_ON_LOGO) { new_alarm_time.tv_sec = 0; alarm_set_power_on(new_alarm_time, false); break; } spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d clear\n", alarm_type); devalarm_try_to_cancel(&alarms[alarm_type]); if (alarm_pending) { alarm_pending &= ~alarm_type_mask; if (!alarm_pending && !wait_pending) wake_unlock(&alarm_wake_lock); } alarm_enabled &= ~alarm_type_mask; spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_OLD: case ANDROID_ALARM_SET_AND_WAIT_OLD: if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) { rv = -EFAULT; goto err1; } new_alarm_time.tv_nsec = 0; goto from_old_alarm_set; case ANDROID_ALARM_SET_AND_WAIT(0): case ANDROID_ALARM_SET(0): if (copy_from_user(&new_alarm_time, (void __user *)arg, sizeof(new_alarm_time))) { rv = -EFAULT; goto err1; } from_old_alarm_set: pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type, new_alarm_time.tv_sec, new_alarm_time.tv_nsec); if (alarm_type == ANDROID_ALARM_POWER_ON) { alarm_set_power_on(new_alarm_time, false); break; } if (alarm_type == ANDROID_ALARM_POWER_ON_LOGO) { alarm_set_power_on(new_alarm_time, true); break; } spin_lock_irqsave(&alarm_slock, flags); alarm_enabled |= alarm_type_mask; devalarm_start(&alarms[alarm_type], timespec_to_ktime(new_alarm_time)); spin_unlock_irqrestore(&alarm_slock, flags); if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD) break; /* fall though */ case ANDROID_ALARM_WAIT: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm wait\n"); if (!alarm_pending && wait_pending) { wake_unlock(&alarm_wake_lock); wait_pending = 0; } spin_unlock_irqrestore(&alarm_slock, flags); rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); if (rv) goto err1; spin_lock_irqsave(&alarm_slock, flags); rv = alarm_pending; wait_pending = 1; alarm_pending = 0; spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_RTC: if (copy_from_user(&new_rtc_time, (void __user *)arg, sizeof(new_rtc_time))) { rv = -EFAULT; goto err1; } rtc_time_to_tm(new_rtc_time.tv_sec, &new_rtc_tm); pr_alarm(IO, "set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n", new_rtc_time.tv_sec, new_rtc_time.tv_nsec, new_rtc_tm.tm_hour, new_rtc_tm.tm_min, new_rtc_tm.tm_sec, new_rtc_tm.tm_mon + 1, new_rtc_tm.tm_mday, new_rtc_tm.tm_year + 1900); rtc_dev = alarmtimer_get_rtcdev(); rv = do_settimeofday(&new_rtc_time); if (rv < 0) { goto err1; } if (rtc_dev) { rv = rtc_set_time(rtc_dev, &new_rtc_tm); } spin_lock_irqsave(&alarm_slock, flags); alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; wake_up(&alarm_wait_queue); spin_unlock_irqrestore(&alarm_slock, flags); if (rv < 0) goto err1; break; case ANDROID_ALARM_GET_TIME(0): switch (alarm_type) { case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_RTC: getnstimeofday(&tmp_time); break; case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME: get_monotonic_boottime(&tmp_time); break; case ANDROID_ALARM_TYPE_COUNT: case ANDROID_ALARM_SYSTEMTIME: ktime_get_ts(&tmp_time); break; case ANDROID_ALARM_POWER_ON: case ANDROID_ALARM_POWER_ON_LOGO: break; } if (copy_to_user((void __user *)arg, &tmp_time, sizeof(tmp_time))) { rv = -EFAULT; goto err1; } break; case ANDROID_ALARM_GET_POWER_ON: alarm_get_power_on(&pwron_alm); if (copy_to_user((void __user *)arg, &pwron_alm, sizeof(struct rtc_wkalrm))) { rv = -EFAULT; goto err1; } break; default: rv = -EINVAL; goto err1; } err1: return rv; }
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int rv = 0; unsigned long flags; struct timespec new_alarm_time; struct timespec new_rtc_time; struct timespec tmp_time; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); uint32_t alarm_type_mask = 1U << alarm_type; /*[[_SHP_STMC_BSP:[email protected] 2012-5-15 [Mod] [P120503-3333] add auto power alarm for CHN feature */ #if defined(CONFIG_MACH_ZANIN_CHN_OPEN) char bootalarm_data[14]; #endif /*]]_SHP_STMC_BSP:[email protected] 2012-5-15*/ if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) return -EINVAL; if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { if ((file->f_flags & O_ACCMODE) == O_RDONLY) return -EPERM; if (file->private_data == NULL && cmd != ANDROID_ALARM_SET_RTC) { spin_lock_irqsave(&alarm_slock, flags); if (alarm_opened) { spin_unlock_irqrestore(&alarm_slock, flags); return -EBUSY; } alarm_opened = 1; file->private_data = (void *)1; spin_unlock_irqrestore(&alarm_slock, flags); } } switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_CLEAR(0): spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d clear\n", alarm_type); alarm_try_to_cancel(&alarms[alarm_type]); if (alarm_pending) { alarm_pending &= ~alarm_type_mask; if (!alarm_pending && !wait_pending) wake_unlock(&alarm_wake_lock); } alarm_enabled &= ~alarm_type_mask; spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_OLD: case ANDROID_ALARM_SET_AND_WAIT_OLD: if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) { rv = -EFAULT; goto err1; } new_alarm_time.tv_nsec = 0; goto from_old_alarm_set; case ANDROID_ALARM_SET_AND_WAIT(0): case ANDROID_ALARM_SET(0): if (copy_from_user(&new_alarm_time, (void __user *)arg, sizeof(new_alarm_time))) { rv = -EFAULT; goto err1; } from_old_alarm_set: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type, new_alarm_time.tv_sec, new_alarm_time.tv_nsec); alarm_enabled |= alarm_type_mask; alarm_start_range(&alarms[alarm_type], timespec_to_ktime(new_alarm_time), timespec_to_ktime(new_alarm_time)); spin_unlock_irqrestore(&alarm_slock, flags); if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD) break; /* fall though */ case ANDROID_ALARM_WAIT: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm wait\n"); if (!alarm_pending && wait_pending) { wake_unlock(&alarm_wake_lock); wait_pending = 0; } spin_unlock_irqrestore(&alarm_slock, flags); rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); if (rv) goto err1; spin_lock_irqsave(&alarm_slock, flags); rv = alarm_pending; wait_pending = 1; alarm_pending = 0; spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_RTC: if (copy_from_user(&new_rtc_time, (void __user *)arg, sizeof(new_rtc_time))) { rv = -EFAULT; goto err1; } rv = alarm_set_rtc(new_rtc_time); spin_lock_irqsave(&alarm_slock, flags); alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; wake_up(&alarm_wait_queue); spin_unlock_irqrestore(&alarm_slock, flags); if (rv < 0) goto err1; break; /*[[_SHP_STMC_BSP:[email protected] 2012-5-15 [Mod] [P120503-3333] add auto power alarm for CHN feature */ #if defined(CONFIG_MACH_ZANIN_CHN_OPEN) case ANDROID_ALARM_SET_ALARM: if (copy_from_user(bootalarm_data, (void __user *)arg, 14)) { printk("%s error!\n", __func__); rv = -EFAULT; goto err1; } printk("%s set alarm: %d\n", __func__,bootalarm_data); rv = alarm_set_alarm(bootalarm_data); break; #endif /*]]_SHP_STMC_BSP:[email protected] 2012-5-15*/ case ANDROID_ALARM_GET_TIME(0): switch (alarm_type) { case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_RTC: getnstimeofday(&tmp_time); break; case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME: tmp_time = ktime_to_timespec(alarm_get_elapsed_realtime()); break; case ANDROID_ALARM_TYPE_COUNT: case ANDROID_ALARM_SYSTEMTIME: ktime_get_ts(&tmp_time); break; } if (copy_to_user((void __user *)arg, &tmp_time, sizeof(tmp_time))) { rv = -EFAULT; goto err1; } break; default: rv = -EINVAL; goto err1; } err1: return rv; }
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int rv = 0; unsigned long flags; long long int tmp_ns; struct timespec tmp; struct timespec new_alarm_time; struct timespec new_rtc_time; struct timespec tmp_time; static struct timespec prev_time = { 0, 0 }; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); uint32_t alarm_type_mask = 1U << alarm_type; if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) return -EINVAL; if (is_set_cmd(cmd)) { if ((file->f_flags & O_ACCMODE) == O_RDONLY) { pr_alarm(INFO, "set cmd not permitted in %s cmd=%d type=%d\n" , __FUNCTION__ , ANDROID_ALARM_BASE_CMD(cmd) , alarm_type); return -EPERM; } if (file->private_data == NULL && cmd != ANDROID_ALARM_SET_RTC) { spin_lock_irqsave(&alarm_slock, flags); if (alarm_opened) { spin_unlock_irqrestore(&alarm_slock, flags); return -EBUSY; } alarm_opened = 1; file->private_data = (void *)1; spin_unlock_irqrestore(&alarm_slock, flags); } } switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_CLEAR(0): spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d clear\n", alarm_type); alarm_try_to_cancel(&alarms[alarm_type]); if (alarm_pending) { alarm_pending &= ~alarm_type_mask; if (!alarm_pending && !wait_pending) wake_unlock(&alarm_wake_lock); } alarm_enabled &= ~alarm_type_mask; spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_OLD: case ANDROID_ALARM_SET_AND_WAIT_OLD: if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) { rv = -EFAULT; goto err1; } new_alarm_time.tv_nsec = 0; goto from_old_alarm_set; case ANDROID_ALARM_SET_AND_WAIT(0): case ANDROID_ALARM_SET(0): if (copy_from_user(&new_alarm_time, (void __user *)arg, sizeof(new_alarm_time))) { rv = -EFAULT; goto err1; } from_old_alarm_set: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type, new_alarm_time.tv_sec, new_alarm_time.tv_nsec); alarm_enabled |= alarm_type_mask; alarm_start_range(&alarms[alarm_type], timespec_to_ktime(new_alarm_time), timespec_to_ktime(new_alarm_time)); spin_unlock_irqrestore(&alarm_slock, flags); if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD) break; /* fall though */ case ANDROID_ALARM_WAIT: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm wait\n"); if (!alarm_pending && wait_pending) { wake_unlock(&alarm_wake_lock); wait_pending = 0; } spin_unlock_irqrestore(&alarm_slock, flags); rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); if (rv) goto err1; spin_lock_irqsave(&alarm_slock, flags); rv = alarm_pending; wait_pending = 1; alarm_pending = 0; spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_RTC: if (copy_from_user(&new_rtc_time, (void __user *)arg, sizeof(new_rtc_time))) { rv = -EFAULT; goto err1; } rv = alarm_set_rtc(new_rtc_time); spin_lock_irqsave(&alarm_slock, flags); alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; wake_up(&alarm_wait_queue); spin_unlock_irqrestore(&alarm_slock, flags); if (rv < 0) goto err1; break; case ANDROID_ALARM_GET_TIME(0): switch (alarm_type) { case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_RTC: getnstimeofday(&tmp_time); break; case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME: tmp_time = ktime_to_timespec(alarm_get_elapsed_realtime()); tmp = timespec_sub(tmp_time, prev_time); tmp_ns = timespec_to_ns(&tmp); if (tmp_ns >= 0) { prev_time = tmp_time; } else if (-tmp_ns < 100*1000000) { /* (previous time - current time) < 100ms */ tmp_time = prev_time; } else { /* (previous time - current time) >= 100ms */ pr_alarm(INFO, "previous time=%lld > current time=%lld\n" , timespec_to_ns(&prev_time) , timespec_to_ns(&tmp_time)); tmp_time = prev_time; } break; case ANDROID_ALARM_TYPE_COUNT: case ANDROID_ALARM_SYSTEMTIME: ktime_get_ts(&tmp_time); break; } if (copy_to_user((void __user *)arg, &tmp_time, sizeof(tmp_time))) { rv = -EFAULT; goto err1; } break; default: rv = -EINVAL; goto err1; } err1: return rv; }
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int rv = 0; unsigned long flags; struct timespec new_alarm_time; struct timespec new_rtc_time; struct timespec tmp_time; struct rtc_time new_rtc_tm; struct rtc_device *rtc_dev; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); uint32_t alarm_type_mask = 1U << alarm_type; if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) return -EINVAL; if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { if ((file->f_flags & O_ACCMODE) == O_RDONLY) return -EPERM; if (file->private_data == NULL && cmd != ANDROID_ALARM_SET_RTC) { spin_lock_irqsave(&alarm_slock, flags); if (alarm_opened) { spin_unlock_irqrestore(&alarm_slock, flags); return -EBUSY; } alarm_opened = 1; file->private_data = (void *)1; spin_unlock_irqrestore(&alarm_slock, flags); } } switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_CLEAR(0): switch (alarm_type) { case ANDROID_ALARM_POWER_UP: /* disable power up alarm interrupt */ rv = alarm_irq_enable(0); break; case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_RTC: case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME: case ANDROID_ALARM_SYSTEMTIME: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d clear\n", alarm_type); devalarm_try_to_cancel(&alarms[alarm_type]); if (alarm_pending) { alarm_pending &= ~alarm_type_mask; if (!alarm_pending && !wait_pending) wake_unlock(&alarm_wake_lock); } alarm_enabled &= ~alarm_type_mask; spin_unlock_irqrestore(&alarm_slock, flags); break; default: break; } break; case ANDROID_ALARM_SET_OLD: case ANDROID_ALARM_SET_AND_WAIT_OLD: if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) { rv = -EFAULT; goto err1; } new_alarm_time.tv_nsec = 0; goto from_old_alarm_set; #if defined(CONFIG_RTC_CHN_ALARM_BOOT) case ANDROID_ALARM_SET_ALARM: { char bootalarm_data[14]; if (copy_from_user(bootalarm_data, (void __user *)arg, 14)) { rv = -EFAULT; goto err1; } alarm_set_bootalarm(bootalarm_data); break; } #endif case ANDROID_ALARM_SET_AND_WAIT(0): case ANDROID_ALARM_SET(0): if (copy_from_user(&new_alarm_time, (void __user *)arg, sizeof(new_alarm_time))) { rv = -EFAULT; goto err1; } from_old_alarm_set: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type, new_alarm_time.tv_sec, new_alarm_time.tv_nsec); alarm_enabled |= alarm_type_mask; devalarm_start(&alarms[alarm_type], timespec_to_ktime(new_alarm_time)); spin_unlock_irqrestore(&alarm_slock, flags); if (alarm_type == ANDROID_ALARM_POWER_UP) alarm_set_rtc_ring(new_alarm_time); if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD) break; /* fall though */ case ANDROID_ALARM_WAIT: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm wait\n"); if (!alarm_pending && wait_pending) { wake_unlock(&alarm_wake_lock); wait_pending = 0; } spin_unlock_irqrestore(&alarm_slock, flags); rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); if (rv) goto err1; spin_lock_irqsave(&alarm_slock, flags); rv = alarm_pending; wait_pending = 1; alarm_pending = 0; spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_RTC: if (copy_from_user(&new_rtc_time, (void __user *)arg, sizeof(new_rtc_time))) { rv = -EFAULT; goto err1; } rtc_time_to_tm(new_rtc_time.tv_sec, &new_rtc_tm); rtc_dev = alarmtimer_get_rtcdev(); rv = do_settimeofday(&new_rtc_time); if (rv < 0) goto err1; if (rtc_dev) rv = rtc_set_time(rtc_dev, &new_rtc_tm); if (pwr_rtc_dev) rv = rtc_set_time(pwr_rtc_dev, &new_rtc_tm); spin_lock_irqsave(&alarm_slock, flags); alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; wake_up(&alarm_wait_queue); spin_unlock_irqrestore(&alarm_slock, flags); if (rv < 0) goto err1; break; case ANDROID_ALARM_GET_TIME(0): switch (alarm_type) { case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_POWER_UP: case ANDROID_ALARM_RTC: getnstimeofday(&tmp_time); break; case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME: get_monotonic_boottime(&tmp_time); break; case ANDROID_ALARM_TYPE_COUNT: case ANDROID_ALARM_SYSTEMTIME: ktime_get_ts(&tmp_time); break; } if (copy_to_user((void __user *)arg, &tmp_time, sizeof(tmp_time))) { rv = -EFAULT; goto err1; } break; default: rv = -EINVAL; goto err1; } err1: return rv; }
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int rv = 0; unsigned long flags; struct timespec new_alarm_time; struct timespec new_rtc_time; struct timespec tmp_time; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); uint32_t alarm_type_mask = 1U << alarm_type; if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) return -EINVAL; #ifdef CONFIG_ANDROID_RTC_CHANGE_WAIT if( ANDROID_ALARM_BASE_CMD(cmd)!=ANDROID_ALARM_GET_TIME(0) && ANDROID_ALARM_BASE_CMD(cmd)!=ANDROID_RTC_CHANGE_WAIT ){ #else if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { #endif if ((file->f_flags & O_ACCMODE) == O_RDONLY) return -EPERM; if (file->private_data == NULL && cmd != ANDROID_ALARM_SET_RTC) { spin_lock_irqsave(&alarm_slock, flags); if (alarm_opened) { spin_unlock_irqrestore(&alarm_slock, flags); return -EBUSY; } alarm_opened = 1; file->private_data = (void *)1; spin_unlock_irqrestore(&alarm_slock, flags); } } switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_CLEAR(0): spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d clear\n", alarm_type); alarm_try_to_cancel(&alarms[alarm_type]); if (alarm_pending) { alarm_pending &= ~alarm_type_mask; if (!alarm_pending && !wait_pending) wake_unlock(&alarm_wake_lock); } alarm_enabled &= ~alarm_type_mask; spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_OLD: case ANDROID_ALARM_SET_AND_WAIT_OLD: if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) { rv = -EFAULT; goto err1; } new_alarm_time.tv_nsec = 0; goto from_old_alarm_set; case ANDROID_ALARM_SET_AND_WAIT(0): case ANDROID_ALARM_SET(0): if (copy_from_user(&new_alarm_time, (void __user *)arg, sizeof(new_alarm_time))) { rv = -EFAULT; goto err1; } from_old_alarm_set: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type, new_alarm_time.tv_sec, new_alarm_time.tv_nsec); alarm_enabled |= alarm_type_mask; alarm_start_range(&alarms[alarm_type], timespec_to_ktime(new_alarm_time), timespec_to_ktime(new_alarm_time)); spin_unlock_irqrestore(&alarm_slock, flags); if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD) break; /* fall though */ case ANDROID_ALARM_WAIT: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm wait\n"); if (!alarm_pending && wait_pending) { wake_unlock(&alarm_wake_lock); wait_pending = 0; } spin_unlock_irqrestore(&alarm_slock, flags); rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); if (rv) goto err1; spin_lock_irqsave(&alarm_slock, flags); rv = alarm_pending; wait_pending = 1; alarm_pending = 0; spin_unlock_irqrestore(&alarm_slock, flags); break; #ifdef CONFIG_ANDROID_RTC_CHANGE_WAIT case ANDROID_RTC_CHANGE_WAIT: rv = wait_event_interruptible(rtc_change_wait_queue, rtc_changed); spin_lock_irqsave(&alarm_slock, flags); rtc_changed = 0; spin_unlock_irqrestore(&alarm_slock, flags); if (rv) goto err1; break; #endif case ANDROID_ALARM_SET_RTC: if (copy_from_user(&new_rtc_time, (void __user *)arg, sizeof(new_rtc_time))) { rv = -EFAULT; goto err1; } rv = alarm_set_rtc(new_rtc_time); spin_lock_irqsave(&alarm_slock, flags); alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; wake_up(&alarm_wait_queue); #ifdef CONFIG_ANDROID_RTC_CHANGE_WAIT rtc_changed = 1; wake_up(&rtc_change_wait_queue); #endif spin_unlock_irqrestore(&alarm_slock, flags); if (rv < 0) goto err1; break; case ANDROID_ALARM_GET_TIME(0): switch (alarm_type) { case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_RTC: getnstimeofday(&tmp_time); break; case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME: tmp_time = ktime_to_timespec(alarm_get_elapsed_realtime()); break; case ANDROID_ALARM_TYPE_COUNT: case ANDROID_ALARM_SYSTEMTIME: ktime_get_ts(&tmp_time); break; } if (copy_to_user((void __user *)arg, &tmp_time, sizeof(tmp_time))) { rv = -EFAULT; goto err1; } break; default: rv = -EINVAL; goto err1; } err1: return rv; } static int alarm_open(struct inode *inode, struct file *file) { file->private_data = NULL; return 0; }
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int rv = 0; unsigned long flags; struct timespec new_alarm_time; struct timespec new_rtc_time; struct timespec tmp_time; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); uint32_t alarm_type_mask = 1U << alarm_type; if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) return -EINVAL; if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { if ((file->f_flags & O_ACCMODE) == O_RDONLY) return -EPERM; if (file->private_data == NULL && cmd != ANDROID_ALARM_SET_RTC) { spin_lock_irqsave(&alarm_slock, flags); if (alarm_opened) { spin_unlock_irqrestore(&alarm_slock, flags); return -EBUSY; } alarm_opened = 1; file->private_data = (void *)1; spin_unlock_irqrestore(&alarm_slock, flags); } } switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_CLEAR(0): mutex_lock(&alarm_mutex); spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d clear\n", alarm_type); alarm_try_to_cancel(&alarms[alarm_type]); if (alarm_pending) { alarm_pending &= ~alarm_type_mask; if (!alarm_pending && !wait_pending) wake_unlock(&alarm_wake_lock); } alarm_enabled &= ~alarm_type_mask; spin_unlock_irqrestore(&alarm_slock, flags); if (alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP) { set_power_on_alarm(0,0); printk("PM_DEBUG_MXP: RTC alarm has been cleared.\n"); } mutex_unlock(&alarm_mutex); break; case ANDROID_ALARM_SET_OLD: case ANDROID_ALARM_SET_AND_WAIT_OLD: if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) { rv = -EFAULT; goto err1; } new_alarm_time.tv_nsec = 0; goto from_old_alarm_set; case ANDROID_ALARM_SET_AND_WAIT(0): case ANDROID_ALARM_SET(0): if (copy_from_user(&new_alarm_time, (void __user *)arg, sizeof(new_alarm_time))) { rv = -EFAULT; goto err1; } from_old_alarm_set: mutex_lock(&alarm_mutex); spin_lock_irqsave(&alarm_slock, flags); /*printk("PM_DEBUG_MXP: alarm %d set %ld.%09ld\n", alarm_type, */ alarm_enabled |= alarm_type_mask; alarm_start_range(&alarms[alarm_type], timespec_to_ktime(new_alarm_time), timespec_to_ktime(new_alarm_time)); spin_unlock_irqrestore(&alarm_slock, flags); //[ECID:0000]ZTE_BSP maxiaoping 20140415 modify MSM8X10 alarm driver for power of charge,start. if ((alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP) && (ANDROID_ALARM_BASE_CMD(cmd) == ANDROID_ALARM_SET(0))) { set_power_on_alarm(new_alarm_time.tv_sec, 1); /*printk("PM_DEBUG_MXP: RTC alarm type %d is set to %ld.%09ld\n", alarm_type, */ } //[ECID:0000]ZTE_BSP maxiaoping 20140415 modify MSM8X10 alarm driver for power of charge,end. mutex_unlock(&alarm_mutex); if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD) break; /* fall though */ case ANDROID_ALARM_WAIT: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm wait\n"); if (!alarm_pending && wait_pending) { wake_unlock(&alarm_wake_lock); wait_pending = 0; } spin_unlock_irqrestore(&alarm_slock, flags); rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); if (rv) goto err1; spin_lock_irqsave(&alarm_slock, flags); rv = alarm_pending; wait_pending = 1; alarm_pending = 0; spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_RTC: if (copy_from_user(&new_rtc_time, (void __user *)arg, sizeof(new_rtc_time))) { rv = -EFAULT; goto err1; } rv = alarm_set_rtc(new_rtc_time); spin_lock_irqsave(&alarm_slock, flags); alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; wake_up(&alarm_wait_queue); spin_unlock_irqrestore(&alarm_slock, flags); if (rv < 0) goto err1; break; case ANDROID_ALARM_GET_TIME(0): switch (alarm_type) { case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_RTC: case ANDROID_ALARM_RTC_POWEROFF_WAKEUP: getnstimeofday(&tmp_time); break; case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME: tmp_time = ktime_to_timespec(alarm_get_elapsed_realtime()); break; case ANDROID_ALARM_TYPE_COUNT: case ANDROID_ALARM_SYSTEMTIME: ktime_get_ts(&tmp_time); break; } if (copy_to_user((void __user *)arg, &tmp_time, sizeof(tmp_time))) { rv = -EFAULT; goto err1; } break; default: rv = -EINVAL; goto err1; } err1: return rv; }