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; }
int ip_options_compile(struct net *net, struct ip_options * opt, struct sk_buff * skb) { int l; unsigned char * iph; unsigned char * optptr; int optlen; unsigned char * pp_ptr = NULL; struct rtable *rt = NULL; if (skb != NULL) { rt = skb_rtable(skb); optptr = (unsigned char *)&(ip_hdr(skb)[1]); } else optptr = opt->__data; iph = optptr - sizeof(struct iphdr); for (l = opt->optlen; l > 0; ) { switch (*optptr) { case IPOPT_END: for (optptr++, l--; l>0; optptr++, l--) { if (*optptr != IPOPT_END) { *optptr = IPOPT_END; opt->is_changed = 1; } } goto eol; case IPOPT_NOOP: l--; optptr++; continue; } optlen = optptr[1]; if (optlen<2 || optlen>l) { pp_ptr = optptr; goto error; } switch (*optptr) { case IPOPT_SSRR: case IPOPT_LSRR: if (optlen < 3) { pp_ptr = optptr + 1; goto error; } if (optptr[2] < 4) { pp_ptr = optptr + 2; goto error; } /* NB: cf RFC-1812 5.2.4.1 */ if (opt->srr) { pp_ptr = optptr; goto error; } if (!skb) { if (optptr[2] != 4 || optlen < 7 || ((optlen-3) & 3)) { pp_ptr = optptr + 1; goto error; } memcpy(&opt->faddr, &optptr[3], 4); if (optlen > 7) memmove(&optptr[3], &optptr[7], optlen-7); } opt->is_strictroute = (optptr[0] == IPOPT_SSRR); opt->srr = optptr - iph; break; case IPOPT_RR: if (opt->rr) { pp_ptr = optptr; goto error; } if (optlen < 3) { pp_ptr = optptr + 1; goto error; } if (optptr[2] < 4) { pp_ptr = optptr + 2; goto error; } if (optptr[2] <= optlen) { if (optptr[2]+3 > optlen) { pp_ptr = optptr + 2; goto error; } if (skb) { memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); opt->is_changed = 1; } optptr[2] += 4; opt->rr_needaddr = 1; } opt->rr = optptr - iph; break; case IPOPT_TIMESTAMP: if (opt->ts) { pp_ptr = optptr; goto error; } if (optlen < 4) { pp_ptr = optptr + 1; goto error; } if (optptr[2] < 5) { pp_ptr = optptr + 2; goto error; } if (optptr[2] <= optlen) { __be32 *timeptr = NULL; if (optptr[2]+3 > optptr[1]) { pp_ptr = optptr + 2; goto error; } switch (optptr[3]&0xF) { case IPOPT_TS_TSONLY: opt->ts = optptr - iph; if (skb) timeptr = (__be32*)&optptr[optptr[2]-1]; opt->ts_needtime = 1; optptr[2] += 4; break; case IPOPT_TS_TSANDADDR: if (optptr[2]+7 > optptr[1]) { pp_ptr = optptr + 2; goto error; } opt->ts = optptr - iph; if (skb) { memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); timeptr = (__be32*)&optptr[optptr[2]+3]; } opt->ts_needaddr = 1; opt->ts_needtime = 1; optptr[2] += 8; break; case IPOPT_TS_PRESPEC: if (optptr[2]+7 > optptr[1]) { pp_ptr = optptr + 2; goto error; } opt->ts = optptr - iph; { __be32 addr; memcpy(&addr, &optptr[optptr[2]-1], 4); if (inet_addr_type(net, addr) == RTN_UNICAST) break; if (skb) timeptr = (__be32*)&optptr[optptr[2]+3]; } opt->ts_needtime = 1; optptr[2] += 8; break; default: if (!skb && !capable(CAP_NET_RAW)) { pp_ptr = optptr + 3; goto error; } break; } if (timeptr) { struct timespec tv; __be32 midtime; getnstimeofday(&tv); midtime = htonl((tv.tv_sec % 86400) * MSEC_PER_SEC + tv.tv_nsec / NSEC_PER_MSEC); memcpy(timeptr, &midtime, sizeof(__be32)); opt->is_changed = 1; } } else { unsigned overflow = optptr[3]>>4; if (overflow == 15) { pp_ptr = optptr + 3; goto error; } opt->ts = optptr - iph; if (skb) { optptr[3] = (optptr[3]&0xF)|((overflow+1)<<4); opt->is_changed = 1; } } break; case IPOPT_RA: if (optlen < 4) { pp_ptr = optptr + 1; goto error; } if (optptr[2] == 0 && optptr[3] == 0) opt->router_alert = optptr - iph; break; case IPOPT_CIPSO: if ((!skb && !capable(CAP_NET_RAW)) || opt->cipso) { pp_ptr = optptr; goto error; } opt->cipso = optptr - iph; if (cipso_v4_validate(skb, &optptr)) { pp_ptr = optptr; goto error; } break; case IPOPT_SEC: case IPOPT_SID: default: if (!skb && !capable(CAP_NET_RAW)) { pp_ptr = optptr; goto error; } break; } l -= optlen; optptr += optlen; } eol: if (!pp_ptr) return 0; error: if (skb) { icmp_send(skb, ICMP_PARAMETERPROB, 0, htonl((pp_ptr-iph)<<24)); } return -EINVAL; }
void fbtft_update_display(struct fbtft_par *par, unsigned start_line, unsigned end_line) { size_t offset, len; struct timespec ts_start, ts_end, test_of_time; long ms, us, ns; bool timeit = false; int ret = 0; if (unlikely(par->debug & (DEBUG_TIME_FIRST_UPDATE | DEBUG_TIME_EACH_UPDATE))) { if ((par->debug & DEBUG_TIME_EACH_UPDATE) || \ ((par->debug & DEBUG_TIME_FIRST_UPDATE) && !par->first_update_done)) { getnstimeofday(&ts_start); timeit = true; } } /* Sanity checks */ if (start_line > end_line) { dev_warn(par->info->device, "%s: start_line=%u is larger than end_line=%u. Shouldn't happen, will do full display update\n", __func__, start_line, end_line); start_line = 0; end_line = par->info->var.yres - 1; } if (start_line > par->info->var.yres - 1 || end_line > par->info->var.yres - 1) { dev_warn(par->info->device, "%s: start_line=%u or end_line=%u is larger than max=%d. Shouldn't happen, will do full display update\n", __func__, start_line, end_line, par->info->var.yres - 1); start_line = 0; end_line = par->info->var.yres - 1; } fbtft_par_dbg(DEBUG_UPDATE_DISPLAY, par, "%s(start_line=%u, end_line=%u)\n", __func__, start_line, end_line); if (par->fbtftops.set_addr_win) par->fbtftops.set_addr_win(par, 0, start_line, par->info->var.xres-1, end_line); offset = start_line * par->info->fix.line_length; len = (end_line - start_line + 1) * par->info->fix.line_length; ret = par->fbtftops.write_vmem(par, offset, len); if (ret < 0) dev_err(par->info->device, "%s: write_vmem failed to update display buffer\n", __func__); if (unlikely(timeit)) { getnstimeofday(&ts_end); test_of_time = timespec_sub(ts_end, ts_start); us = (test_of_time.tv_nsec / 1000) % 1000; ms = (test_of_time.tv_sec * 1000) + ((test_of_time.tv_nsec / 1000000) % 1000); ns = test_of_time.tv_nsec % 1000; dev_info(par->info->device, "Elapsed time for display update: %4lu.%.3lu%.3lu ms (fps: %2lu, lines=%u)\n", ms, us, ns, test_of_time.tv_nsec ? 1000000000 / test_of_time.tv_nsec : 0, end_line - start_line + 1); par->first_update_done = true; } }
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; } 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; 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; }
// [email protected] 20110110 MUIC mode change in case of trap [START] static void CP_CRASH_wq_func(struct work_struct *cp_crash_wq) { volatile unsigned long *make_panic = 0; extern void set_muic_mode(u32 mode); int ret; // CRASH TIME INFORMATION ADD. 2011-04-23 eunae.kim struct timespec ts; struct rtc_time tm; getnstimeofday(&ts); rtc_time_to_tm(ts.tv_sec, &tm); printk(KERN_INFO "[CP CRASH IRQ] CP_CRASH_wq_func()"); printk(KERN_INFO "(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec); // CHEOLGWAK 2011-5-14 delayed work queue #ifdef CONFIG_MACH_LGE_COSMO_DOMASTIC if(!gpio_get_value(CP_CRASH_INT_N)){ #else if(gpio_get_value(CP_CRASH_INT_N)){ #endif #if 0 // [email protected] prevent to make panic *make_panic = 0xDEAD; #endif //LGE_ChangeS [email protected] 20110131 CIQ [START] lge_store_ciq_reset(0, LGE_NVDATA_IQ_RESET_EXCEPTION); //LGE_ChangeS [email protected] 20110131 CIQ [END] // CHEOLGWAK 2011-2-26 CP_CRASH_COUNT { unsigned char data; lge_dynamic_nvdata_read(LGE_NVDATA_DYNAMIC_CP_CRASH_COUNT_OFFSET,&data,1); data++; lge_dynamic_nvdata_write(LGE_NVDATA_DYNAMIC_CP_CRASH_COUNT_OFFSET,&data,1); } // CHEOLGWAK 2011-2-26 CP_CRASH_COUNT // CHEOLGWAK 2011-2-28 // [email protected] 20110111 if (lge_is_crash_dump_enabled() != 1) { #ifndef ENABLE_CP_CRASH_RESET //20110301 LGE_RIL_RECOVERY printk(" CP CRASH! immediate RIL/CP reset"); input_report_key(in_dev, EVENT_KEY, 1); input_report_key(in_dev, EVENT_KEY, 0); input_sync(in_dev); printk("[CPW] input_report_key(): %d\n", EVENT_KEY); #endif return; } // [email protected] 20110130 CP Crash Core Dump Season2 [START] // set_muic_mode(7 /* MUIC_CP_UART */); printk(KERN_INFO "[CP CRASH IRQ] launch ifx_coredump process\n"); { char* argv[] = {"/system/bin/ifx_coredump", "CP_CRASH_IRQ", NULL}; char *envp[] = { "HOME=/", "PATH=/sbin:/bin:/system/bin", NULL }; //@@ret = call_usermodehelper(argv[0], argv, envp, UMH_NO_WAIT); ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC); printk(KERN_INFO "[CP CRASH IRQ] launch ifx_coredump process ret:%d\n",ret); } gpio_set_value(82, 1); #if 0 // LED toggle int toggle = 0; for(;;) { if(toggle == 0) { gpio_set_value(82, 1); toggle = 1; } else { gpio_set_value(82, 0); toggle = 0; } msleep(100); } #endif // [email protected] 20110130 CP Crash Core Dump Season2 [END] } else { return; } // CHEOLGWAK 2011-5-14 delayed work queue } static irqreturn_t CP_CRASH_interrupt_handler(s32 irq, void *data) { /* Make the interrupt on CP CRASH INT wake up OMAP which is in suspend mode */ // CHEOLGWAK 2011-5-14 delayed work queue //schedule_work(&CP_CRASH_INT_wq); schedule_delayed_work( &cp_crash_int_delayed_wq, msecs_to_jiffies(500)); // CHEOLGWAK 2011-5-14 delayed work queue return IRQ_HANDLED; }
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 inline void start_profile() { getnstimeofday(&start_ts); }
static inline void stop_profile() { getnstimeofday(&end_ts); }
DWORD BAHW_MyGetMSecs(void) { struct timespec now; getnstimeofday(&now); return now.tv_sec * 1000 + now.tv_nsec / 1000000; }
u64 get_time_ns(void) { struct timespec tsval; getnstimeofday(&tsval); return (u64)timespec_to_ns(&tsval); }
static void ramdump_get_time(void){ getnstimeofday(&ts); rtc_time_to_tm(ts.tv_sec, &tm); sprintf(rd_kernel_time, "%d-%02d-%02d-%02d%02d%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); }
static int omap3_enter_idle(struct cpuidle_device *dev, struct cpuidle_state *state) { struct omap3_processor_cx *cx; struct timespec ts_preidle; struct timespec ts_postidle; struct timespec ts_idle; /* Used for LPR mode DSS context save/restore. */ u32 pm_wken_dss = 0; u32 pm_pwstctrl_dss = 0; u32 cm_clkstctrl_dss = 0; u32 cm_fclken_dss = 0; u32 cm_iclken_dss = 0; u32 cm_autoidle_dss = 0; u32 fclken_core; u32 iclken_core; u32 fclken_per; u32 iclken_per; int wakeup_latency; struct system_power_state target_state; struct system_power_state cur_state; #ifdef CONFIG_HW_SUP_TRANS u32 sleepdep_per; u32 wakedep_per; #endif /* #ifdef CONFIG_HW_SUP_TRANS */ u32 sdrc_power_register = 0; int core_sleep_flg = 0; int got_console_lock = 0; /* Disable interrupts. */ local_irq_disable(); local_fiq_disable(); /* If need resched - return immediately */ if( need_resched()) { local_fiq_enable(); local_irq_enable(); return 0; } /* Reset previous power state registers. */ clear_prepwstst(); omap3_idle_setup_wkup_sources (); /* Set up target state from state context provided by cpuidle. */ cx = cpuidle_get_statedata(state); target_state.mpu_state = cx->mpu_state; target_state.core_state = cx->core_state; target_state.neon_state = 0; /* Avoid gcc warning. Will be set in adjust_target_states(). */ /* take a time marker for residency. */ getnstimeofday(&ts_preidle); /* If the requested state is C0, we bail here... */ if (cx->type == OMAP3_STATE_C1) { omap_sram_idle(target_state.mpu_state); goto return_sleep_time; } if (cx->type > OMAP3_STATE_C2) sched_clock_idle_sleep_event(); /* about to enter deep idle */ /* Adjust PER and NEON domain target states as well as CORE domain * target state depending on MPU/CORE setting, enable_off sysfs entry * and PER timer status. */ adjust_target_states(&target_state); wakeup_latency = cx->wakeup_latency; /* NOTE: * We will never get the condition below as we are not supporting * CORE OFF right now. Keeping this code around for future reference. */ if (target_state.core_state != cx->core_state) { /* Currently, this can happen only for core_off. Adjust wakeup * latency to that of core_cswr state. Hard coded now and needs * to be made more generic omap3_power_states[4] is CSWR for * core */ wakeup_latency = omap3_power_states[4].wakeup_latency; } /* Reprogram next wake up tick to adjust for wake latency */ if (wakeup_latency > 1000) { struct tick_device *d = tick_get_device(smp_processor_id()); ktime_t now = ktime_get(); if (ktime_to_ns(ktime_sub(d->evtdev->next_event, now)) > (wakeup_latency * 1000 + NSEC_PER_MSEC)) { ktime_t adjust = ktime_set(0, (wakeup_latency * 1000)); ktime_t next = ktime_sub(d->evtdev->next_event, adjust); clockevents_program_event(d->evtdev, next, now); } } /* Check for pending interrupts. If there is an interrupt, return */ if (INTCPS_PENDING_IRQ0 | INTCPS_PENDING_IRQ1 | INTCPS_PENDING_IRQ2) goto return_sleep_time; /* Remember the current power states and clock settings. */ prcm_get_power_domain_state(DOM_PER, &cur_state.per_state); prcm_get_power_domain_state(DOM_CAM, &cur_state.cam_state); prcm_get_power_domain_state(DOM_SGX, &cur_state.sgx_state); prcm_get_power_domain_state(DOM_NEON, &cur_state.neon_state); fclken_core = CM_FCLKEN1_CORE; iclken_core = CM_ICLKEN1_CORE; fclken_per = CM_FCLKEN_PER; iclken_per = CM_ICLKEN_PER; #ifdef CONFIG_HW_SUP_TRANS /* Facilitating SWSUP RET, from HWSUP mode */ sleepdep_per = CM_SLEEPDEP_PER; wakedep_per = PM_WKDEP_PER; #endif /* #ifdef CONFIG_HW_SUP_TRANS */ /* If target state if core_off, save registers before changing * anything. */ if (target_state.core_state >= PRCM_CORE_OSWR_MEMRET) { prcm_save_registers(); } /* Check for pending interrupts. If there is an interrupt, return */ if (INTCPS_PENDING_IRQ0 | INTCPS_PENDING_IRQ1 | INTCPS_PENDING_IRQ2) goto return_sleep_time; /* Program MPU and NEON to target state */ if (target_state.mpu_state > PRCM_MPU_ACTIVE) { if ((cur_state.neon_state == PRCM_ON) && (target_state.neon_state != PRCM_ON)) { if (target_state.neon_state == PRCM_OFF) omap3_save_neon_context(); prcm_transition_domain_to(DOM_NEON, target_state.neon_state); } #ifdef _disabled_CONFIG_MPU_OFF /* Populate scratchpad restore address */ scratchpad_set_restore_addr(); #endif /* TODO No support for OFF Mode yet if(target_state.core_state > PRCM_CORE_CSWR_MEMRET) omap3_save_secure_ram_context(target_state.core_state); */ prcm_set_mpu_domain_state(target_state.mpu_state); } /* Check for pending interrupts. If there is an interrupt, return */ if (INTCPS_PENDING_IRQ0 | INTCPS_PENDING_IRQ1 | INTCPS_PENDING_IRQ2) goto restore; /* Program CORE and PER to target state */ if (target_state.core_state > PRCM_CORE_ACTIVE) { /* Log core sleep attempt */ core_sleep_flg = 1; /* Lock the console to prevent potential access to UARTs. */ if (0 == try_acquire_console_sem()) { got_console_lock = 1; } /* Handle PER, CAM and SGX domains. */ if ((cur_state.per_state == PRCM_ON) && (target_state.per_state != PRCM_ON)) { if (target_state.per_state == PRCM_OFF) { omap3_save_per_context(); } prcm_transition_domain_to(DOM_PER, target_state.per_state); } if (PRCM_ON == cur_state.cam_state) prcm_transition_domain_to(DOM_CAM, PRCM_RET); if (PRCM_ON == cur_state.sgx_state) prcm_transition_domain_to(DOM_SGX, PRCM_RET); disable_smartreflex(SR1_ID); disable_smartreflex(SR2_ID); prcm_set_core_domain_state(target_state.core_state); /* Enable Autoidle for GPT1 explicitly - Errata 1.4 */ CM_AUTOIDLE_WKUP |= 0x1; /* Disable HSUSB OTG ICLK explicitly*/ CM_ICLKEN1_CORE &= ~0x10; /* Enabling GPT1 wake-up capabilities */ PM_WKEN_WKUP |= 0x1; /* Errata 2.15 * Configure UARTs to ForceIdle. Otherwise they can prevent * CORE RET. */ omap24xx_uart_set_force_idle(); CM_ICLKEN1_CORE &= ~(1<<7); /* MAILBOXES */ CM_ICLKEN1_CORE &= ~(1<<6); /* OMAPCTRL */ /* If we are in LPR mode we need to set up DSS accordingly. */ if (omap2_disp_lpr_is_enabled()) { pm_wken_dss = PM_WKEN_DSS; pm_pwstctrl_dss = PM_PWSTCTRL_DSS; cm_clkstctrl_dss = CM_CLKSTCTRL_DSS; cm_fclken_dss = CM_FCLKEN_DSS; cm_iclken_dss = CM_ICLKEN_DSS; cm_autoidle_dss = CM_AUTOIDLE_DSS; PM_WKEN_DSS = 0x00000001; PM_PWSTCTRL_DSS = 0x00030107; CM_CLKSTCTRL_DSS = 0x00000003; CM_FCLKEN_DSS = 0x00000001; CM_ICLKEN_DSS = 0x00000001; CM_AUTOIDLE_DSS = 0x00000001; } } /* Check for pending interrupts. If there is an interrupt, return */ if (INTCPS_PENDING_IRQ0 | INTCPS_PENDING_IRQ1 | INTCPS_PENDING_IRQ2) goto restore; #ifdef CONFIG_DISABLE_HFCLK PRM_CLKSRC_CTRL |= 0x18; /* set sysclk to stop */ #endif /* #ifdef CONFIG_DISABLE_HFCLK */ DEBUG_STATE_CAPTURE(); /* Errata 1.142: * SDRC not sending auto-refresh when OMAP wakes-up from OFF mode */ if (!is_device_type_gp() && is_sil_rev_equal_to(OMAP3430_REV_ES3_0)) { sdrc_power_register = SDRC_POWER_REG; SDRC_POWER_REG &= ~(SDRC_PWR_AUTOCOUNT_MASK | SDRC_PWR_CLKCTRL_MASK); SDRC_POWER_REG |= 0x120; if (target_state.core_state == PRCM_CORE_OFF) save_scratchpad_contents(); } omap_sram_idle(target_state.mpu_state); /* Errata 1.142: * SDRC not sending auto-refresh when OMAP wakes-up from OFF mode */ if (!is_device_type_gp() && is_sil_rev_equal_to(OMAP3430_REV_ES3_0)) SDRC_POWER_REG = sdrc_power_register; restore: #ifdef CONFIG_DISABLE_HFCLK PRM_CLKSRC_CTRL &= ~0x18; #endif /* #ifdef CONFIG_DISABLE_HFCLK */ /* Disabling IO_PAD capabilities */ PM_WKEN_WKUP &= ~(0x100); CM_FCLKEN1_CORE = fclken_core; CM_ICLKEN1_CORE = iclken_core; if (target_state.mpu_state > PRCM_MPU_ACTIVE) { #ifdef _disabled_CONFIG_MPU_OFF /* On ES 2.0, if scratchpad is populated with valid pointer, * warm reset does not work So populate scratchpad restore * address only in cpuidle and suspend calls */ scratchpad_clr_restore_addr(); #endif prcm_set_mpu_domain_state(PRCM_MPU_ACTIVE); if ((cur_state.neon_state == PRCM_ON) && (target_state.mpu_state > PRCM_MPU_INACTIVE)) { u8 pre_state; prcm_force_power_domain_state(DOM_NEON, cur_state.neon_state); prcm_get_pre_power_domain_state(DOM_NEON, &pre_state); if (pre_state == PRCM_OFF) { omap3_restore_neon_context(); } #ifdef CONFIG_HW_SUP_TRANS prcm_set_power_domain_state(DOM_NEON, POWER_DOMAIN_ON, PRCM_AUTO); #endif } } /* Continue core restoration part, only if Core-Sleep is attempted */ if ((target_state.core_state > PRCM_CORE_ACTIVE) && core_sleep_flg) { u8 pre_per_state; prcm_set_core_domain_state(PRCM_CORE_ACTIVE); omap24xx_uart_clr_force_idle(); enable_smartreflex(SR1_ID); enable_smartreflex(SR2_ID); /* Turn PER back ON if it was ON before idle. */ if (cur_state.per_state == PRCM_ON) { prcm_force_power_domain_state(DOM_PER, cur_state.per_state); CM_ICLKEN_PER = iclken_per; CM_FCLKEN_PER = fclken_per; prcm_get_pre_power_domain_state(DOM_PER, &pre_per_state); if (pre_per_state == PRCM_OFF) { omap3_restore_per_context(); #ifdef CONFIG_OMAP34XX_OFFMODE context_restore_update(DOM_PER); #endif } #ifdef CONFIG_HW_SUP_TRANS /* Facilitating SWSUP RET, from HWSUP mode */ CM_SLEEPDEP_PER = sleepdep_per; PM_WKDEP_PER = wakedep_per; prcm_set_power_domain_state(DOM_PER, PRCM_ON, PRCM_AUTO); #endif } /* Restore CAM and SGX. */ if (PRCM_ON == cur_state.cam_state) prcm_transition_domain_to(DOM_CAM, PRCM_ON); if (PRCM_ON == cur_state.sgx_state) prcm_transition_domain_to(DOM_SGX, PRCM_ON); /* If we lost CORE context, restore it. */ if (target_state.core_state >= PRCM_CORE_OSWR_MEMRET) { #ifdef CONFIG_OMAP34XX_OFFMODE context_restore_update(DOM_CORE1); #endif prcm_restore_registers(); prcm_restore_core_context(target_state.core_state); #ifdef CONFIG_CORE_OFF omap3_restore_core_settings(); #endif } /* Restore DSS settings */ if (omap2_disp_lpr_is_enabled()) { PM_WKEN_DSS = pm_wken_dss; PM_PWSTCTRL_DSS = pm_pwstctrl_dss; CM_CLKSTCTRL_DSS = cm_clkstctrl_dss; CM_FCLKEN_DSS = cm_fclken_dss; CM_ICLKEN_DSS = cm_iclken_dss; CM_AUTOIDLE_DSS = cm_autoidle_dss; } /* At this point CORE and PER domain are back. We can release * the console if we have it. */ if (got_console_lock) { release_console_sem(); } #ifdef CONFIG_OMAP_32K_TIMER /* Errata 1.4 * If a General Purpose Timer (GPTimer) is in posted mode * (TSIRC.POSTED=1), due to internal resynchronizations, values * read in TCRR, TCAR1 and TCAR2 registers right after the * timer interface clock (L4) goes from stopped to active may * not return the expected values. The most common event * leading to this situation occurs upon wake up from idle. * * Software has to wait at least (2 timer interface clock * cycles + 1 timer functional clock cycle) after L4 clock * wakeup before reading TCRR, TCAR1 or TCAR2 registers for * GPTimers in POSTED internal synchro- nization mode, and * before reading WCRR register of the Watchdog timers . The * same workaround must be applied before reading CR and * 32KSYNCNT_REV registers of the synctimer module. * * Wait Period = 2 timer interface clock cycles + * 1 timer functional clock cycle * Interface clock = L4 clock (50MHz worst case). * Functional clock = 32KHz * Wait Period = 2*10^-6/50 + 1/32768 = 0.000030557 = 30.557us * Rounding off the delay value to a safer 50us. */ udelay(GPTIMER_WAIT_DELAY); #endif /* Disable autoidling of GPT1. */ CM_AUTOIDLE_WKUP &= ~(0x1); } DPRINTK("MPU state:%x, CORE state:%x\n", PM_PREPWSTST_MPU, PM_PREPWSTST_CORE); /* Do wakeup event check s*/ post_uart_activity(); /* Update stats for sysfs entries. */ store_prepwst(); return_sleep_time: getnstimeofday(&ts_postidle); #if defined(CONFIG_SYSFS) && defined(DEBUG_BAIL_STATS) ts_last_wake_up = ts_postidle; #endif ts_idle = timespec_sub(ts_postidle, ts_preidle); if (cx->type > OMAP3_STATE_C2) sched_clock_idle_wakeup_event(timespec_to_ns(&ts_idle)); DEBUG_STATE_PRINT(core_sleep_flg); local_irq_enable(); local_fiq_enable(); return (u32)timespec_to_ns(&ts_idle)/1000; }
static int msm_voice_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int rc = 0; uint32_t rx_dev_id; uint32_t tx_dev_id; struct msm_snddev_info *rx_dev_info; struct msm_snddev_info *tx_dev_info; int set = ucontrol->value.integer.value[2]; u32 session_mask; int i = 0, j = 0; struct snddev_icodec_state *icodec; struct adie_codec_hwsetting_entry *rx_entry; struct adie_codec_hwsetting_entry *tx_entry; struct timespec ts; struct rtc_time tm; /* if (!set) return -EPERM; */ pr_aud_info("[ALSA] msm_route_voice: " "tx %d, rx %d, set %d\n", (int) ucontrol->value.integer.value[1], (int) ucontrol->value.integer.value[0], set); if (set) { getnstimeofday(&ts); rtc_time_to_tm(ts.tv_sec, &tm); pr_aud_info1("[ATS][phonecall_start][successful] at %lld (%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n", ktime_to_ns(ktime_get()), tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec); } else { getnstimeofday(&ts); rtc_time_to_tm(ts.tv_sec, &tm); pr_aud_info1("[ATS][phonecall_end][successful] at %lld (%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n", ktime_to_ns(ktime_get()), tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec); } /* Rx Device Routing */ rx_dev_id = ucontrol->value.integer.value[0]; rx_dev_info = audio_dev_ctrl_find_dev(rx_dev_id); if (IS_ERR(rx_dev_info)) { MM_AUD_ERR("pass invalid dev_id\n"); rc = PTR_ERR(rx_dev_info); return rc; } if (!(rx_dev_info->capability & SNDDEV_CAP_RX)) { MM_AUD_ERR("First Dev is supposed to be RX\n"); return -EFAULT; } MM_DBG("route cfg %d STREAM_VOICE_RX type\n", rx_dev_id); /* replace with Rx voice/media setting for adie */ if (rx_dev_info->acdb_id != 10 && (rx_dev_info->acdb_id < 1000)) { icodec = (struct snddev_icodec_state *)rx_dev_info->private_data; rx_entry = icodec->data->profile->settings; j = icodec->data->profile->setting_sz; if (set) { for (i = 0; i < j; i++) if (rx_entry[i].voc_action != NULL) { rx_entry[i].actions = rx_entry[i].voc_action; rx_entry[i].action_sz = rx_entry[i].voc_action_sz; } } else { for (i = 0; i < j; i++) if (rx_entry[i].midi_action != NULL) { rx_entry[i].actions = rx_entry[i].midi_action; rx_entry[i].action_sz = rx_entry[i].midi_action_sz; } } } msm_set_voc_route(rx_dev_info, AUDIO_ROUTE_STREAM_VOICE_RX, rx_dev_id); session_mask = 0x1 << (8 * ((int)AUDDEV_CLNT_VOC-1)); /* Tx Device Routing */ tx_dev_id = ucontrol->value.integer.value[1]; tx_dev_info = audio_dev_ctrl_find_dev(tx_dev_id); if (IS_ERR(tx_dev_info)) { MM_AUD_ERR("pass invalid dev_id\n"); rc = PTR_ERR(tx_dev_info); return rc; } if (!(tx_dev_info->capability & SNDDEV_CAP_TX)) { MM_AUD_ERR("Second Dev is supposed to be Tx\n"); return -EFAULT; } MM_DBG("route cfg %d %d type\n", tx_dev_id, AUDIO_ROUTE_STREAM_VOICE_TX); /* replace with Tx voice/media setting for adie */ if (tx_dev_info->acdb_id != 9 && (tx_dev_info->acdb_id < 1000)) { icodec = (struct snddev_icodec_state *)tx_dev_info->private_data; tx_entry = icodec->data->profile->settings; j = icodec->data->profile->setting_sz; if (set) { for (i = 0; i < j; i++) if (tx_entry[i].voc_action != NULL) { tx_entry[i].actions = tx_entry[i].voc_action; tx_entry[i].action_sz = tx_entry[i].voc_action_sz; } } else { for (i = 0; i < j; i++) if (tx_entry[i].midi_action != NULL) { tx_entry[i].actions = tx_entry[i].midi_action; tx_entry[i].action_sz = tx_entry[i].midi_action_sz; } } } msm_set_voc_route(tx_dev_info, AUDIO_ROUTE_STREAM_VOICE_TX, tx_dev_id); broadcast_event(AUDDEV_EVT_DEV_CHG_VOICE, tx_dev_id, session_mask); if (set) { if (rx_dev_info->opened) broadcast_event(AUDDEV_EVT_DEV_RDY, rx_dev_id, session_mask); if (tx_dev_info->opened) broadcast_event(AUDDEV_EVT_DEV_RDY, tx_dev_id, session_mask); } return rc; }
static int __init rtc_hctosys(void) { int err = -ENODEV; struct rtc_time tm; struct timespec tv = { .tv_nsec = NSEC_PER_SEC >> 1, }; struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); if (rtc == NULL) { pr_err("%s: unable to open rtc device (%s)\n", __FILE__, CONFIG_RTC_HCTOSYS_DEVICE); goto err_open; } err = rtc_read_time(rtc, &tm); if (err) { dev_err(rtc->dev.parent, "hctosys: unable to read the hardware clock\n"); goto err_read; } err = rtc_valid_tm(&tm); if (err) { dev_err(rtc->dev.parent, "hctosys: invalid date/time\n"); goto err_invalid; } rtc_tm_to_time(&tm, &tv.tv_sec); do_settimeofday(&tv); // #if 1 { struct timespec ts; getnstimeofday(&ts); printk(KERN_UTC_BOOT "%d-%02d-%02d %02d:%02d:%02d.%06lu\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec/1000); } #else // dev_info(rtc->dev.parent, "setting system clock to " "%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, (unsigned int) tv.tv_sec); #endif err_invalid: err_read: rtc_class_close(rtc); err_open: rtc_hctosys_ret = err; return err; } late_initcall(rtc_hctosys);
/* * This function executes in interrupt context. */ static int msm_isp_notify_vfe(struct v4l2_subdev *sd, unsigned int notification, void *arg) { int rc = 0; struct v4l2_event v4l2_evt; struct msm_isp_event_ctrl *isp_event; struct msm_cam_media_controller *pmctl = (struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd); struct msm_free_buf buf; if (!pmctl) { pr_err("%s: no context in dsp callback.\n", __func__); rc = -EINVAL; return rc; } if (notification == NOTIFY_VFE_BUF_EVT) return msm_isp_notify_VFE_BUF_EVT(sd, arg); if (notification == NOTIFY_VFE_BUF_FREE_EVT) return msm_isp_notify_VFE_BUF_FREE_EVT(sd, arg); isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_ATOMIC); if (!isp_event) { pr_err("%s Insufficient memory. return", __func__); return -ENOMEM; } v4l2_evt.type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_STAT_EVT_MSG; v4l2_evt.id = 0; *((uint32_t *)v4l2_evt.u.data) = (uint32_t)isp_event; isp_event->resptype = MSM_CAM_RESP_STAT_EVT_MSG; isp_event->isp_data.isp_msg.type = MSM_CAMERA_MSG; isp_event->isp_data.isp_msg.len = 0; switch (notification) { case NOTIFY_ISP_MSG_EVT: { struct isp_msg_event *isp_msg = (struct isp_msg_event *)arg; isp_event->isp_data.isp_msg.msg_id = isp_msg->msg_id; isp_event->isp_data.isp_msg.frame_id = isp_msg->sof_count; getnstimeofday(&(isp_event->isp_data.isp_msg.timestamp)); break; } case NOTIFY_VFE_MSG_OUT: { uint8_t msgid; struct isp_msg_output *isp_output = (struct isp_msg_output *)arg; switch (isp_output->output_id) { case MSG_ID_OUTPUT_P: msgid = VFE_MSG_OUTPUT_P; break; case MSG_ID_OUTPUT_V: msgid = VFE_MSG_OUTPUT_V; break; case MSG_ID_OUTPUT_T: msgid = VFE_MSG_OUTPUT_T; break; case MSG_ID_OUTPUT_S: msgid = VFE_MSG_OUTPUT_S; break; case MSG_ID_OUTPUT_PRIMARY: msgid = VFE_MSG_OUTPUT_PRIMARY; break; case MSG_ID_OUTPUT_SECONDARY: msgid = VFE_MSG_OUTPUT_SECONDARY; break; case MSG_ID_OUTPUT_TERTIARY1: msgid = VFE_MSG_OUTPUT_TERTIARY1; break; case MSG_ID_OUTPUT_TERTIARY2: msgid = VFE_MSG_OUTPUT_TERTIARY2; break; default: pr_err("%s: Invalid VFE output id: %d\n", __func__, isp_output->output_id); rc = -EINVAL; break; } if (!rc) { isp_event->isp_data.isp_msg.msg_id = isp_output->output_id; isp_event->isp_data.isp_msg.frame_id = isp_output->frameCounter; buf = isp_output->buf; msgid = msm_isp_vfe_msg_to_img_mode(pmctl, msgid); BUG_ON(msgid < 0); msm_mctl_buf_done(pmctl, msgid, &buf, isp_output->frameCounter); } } break; case NOTIFY_VFE_MSG_COMP_STATS: { struct msm_stats_buf *stats = (struct msm_stats_buf *)arg; struct msm_stats_buf *stats_buf = NULL; isp_event->isp_data.isp_msg.msg_id = MSG_ID_STATS_COMPOSITE; stats->aec.buff = msm_pmem_stats_ptov_lookup(pmctl, stats->aec.buff, &(stats->aec.fd)); stats->awb.buff = msm_pmem_stats_ptov_lookup(pmctl, stats->awb.buff, &(stats->awb.fd)); stats->af.buff = msm_pmem_stats_ptov_lookup(pmctl, stats->af.buff, &(stats->af.fd)); stats->ihist.buff = msm_pmem_stats_ptov_lookup(pmctl, stats->ihist.buff, &(stats->ihist.fd)); stats->rs.buff = msm_pmem_stats_ptov_lookup(pmctl, stats->rs.buff, &(stats->rs.fd)); stats->cs.buff = msm_pmem_stats_ptov_lookup(pmctl, stats->cs.buff, &(stats->cs.fd)); stats_buf = kmalloc(sizeof(struct msm_stats_buf), GFP_ATOMIC); if (!stats_buf) { pr_err("%s: out of memory.\n", __func__); rc = -ENOMEM; } else { *stats_buf = *stats; isp_event->isp_data.isp_msg.len = sizeof(struct msm_stats_buf); isp_event->isp_data.isp_msg.data = stats_buf; } } break; case NOTIFY_VFE_MSG_STATS: { struct msm_stats_buf stats; struct isp_msg_stats *isp_stats = (struct isp_msg_stats *)arg; isp_event->isp_data.isp_msg.msg_id = isp_stats->id; isp_event->isp_data.isp_msg.frame_id = isp_stats->frameCounter; stats.buffer = msm_pmem_stats_ptov_lookup(pmctl, isp_stats->buffer, &(stats.fd)); switch (isp_stats->id) { case MSG_ID_STATS_AEC: stats.aec.buff = stats.buffer; stats.aec.fd = stats.fd; break; case MSG_ID_STATS_AF: stats.af.buff = stats.buffer; stats.af.fd = stats.fd; break; case MSG_ID_STATS_AWB: stats.awb.buff = stats.buffer; stats.awb.fd = stats.fd; break; case MSG_ID_STATS_IHIST: stats.ihist.buff = stats.buffer; stats.ihist.fd = stats.fd; break; case MSG_ID_STATS_RS: stats.rs.buff = stats.buffer; stats.rs.fd = stats.fd; break; case MSG_ID_STATS_CS: stats.cs.buff = stats.buffer; stats.cs.fd = stats.fd; break; case MSG_ID_STATS_AWB_AEC: break; default: pr_err("%s: Invalid msg type", __func__); break; } if (!stats.buffer) { pr_err("%s: msm_pmem_stats_ptov_lookup error\n", __func__); isp_event->isp_data.isp_msg.len = 0; rc = -EFAULT; } else { struct msm_stats_buf *stats_buf = kmalloc(sizeof(struct msm_stats_buf), GFP_ATOMIC); if (!stats_buf) { pr_err("%s: out of memory.\n", __func__); rc = -ENOMEM; } else { *stats_buf = stats; isp_event->isp_data.isp_msg.len = sizeof(struct msm_stats_buf); isp_event->isp_data.isp_msg.data = stats_buf; } } } break; default: pr_err("%s: Unsupport isp notification %d\n", __func__, notification); rc = -EINVAL; break; } v4l2_event_queue(pmctl->config_device->config_stat_event_queue.pvdev, &v4l2_evt); return rc; }
int enter_lowpm(struct cpuidle_device *dev, struct cpuidle_state *state) { int icanidle = 0; int idle_time; int cpu_id = 0; int cpu_idle_flag = IDLE_DISABLE; struct cpuidle_state *new_state = state; struct timeval before, after; int enter_state; struct timespec t; unsigned int timer_id = 0; unsigned int schedule_time = 0xffffffff; unsigned int expected_us; local_irq_disable(); cpu_id = get_cpu(); put_cpu(); if(get_enter_state(state, &enter_state) != 0) { local_irq_enable(); return 0; } /* Used to keep track of the total time in idle */ getnstimeofday(&before); #if 1 /*启动过程中不允许ACPU下电*/ /*if((CPU_IDLE_C1 <= enter_state)&&(CPU_IDLE_C3 >= enter_state)&&(before.tv_sec < IDLE_ACTIVE_DELAY_S))*/ if((CPU_IDLE_C1 <= enter_state)&&(CPU_IDLE_C3 >= enter_state)&&(0 == g_pwc_init_flag)) { PRINT_PWC_DBG(PWC_SWITCH_CPUIDLE,"before.tv_sec:0x%x\n",before.tv_sec); local_irq_enable(); return 0; } #endif if((RET_OK == pwrctrl_is_func_on(PWC_SWITCH_CPUIDLE))&&((CPU_IDLE_C0 < enter_state)&&(CPU_IDLE_C4 > enter_state))&&(0 == cpu_id)) { cpu_idle_flag = IDLE_ENABLE; } else { cpu_idle_flag = IDLE_DISABLE; } /*C3起定时器来唤醒 后续可优化*/ if((enter_state >= CPU_IDLE_C3)&&(IDLE_ENABLE == cpu_idle_flag)) { pwrctrl_sleep_mgr_get_next_schedule_time(0, &timer_id, &schedule_time); if(schedule_time > (0xFFFFFFFF / 1000)) { schedule_time = 0xFFFFFFFF; } else { schedule_time *= USEC_PER_MSEC; } /*C3停止所有TCXO定时器,待优化*/ /* determine the expected residency time, round up */ t = ktime_to_timespec(tick_nohz_get_sleep_length()); expected_us = t.tv_sec * USEC_PER_SEC + t.tv_nsec / NSEC_PER_USEC; if(schedule_time < expected_us) { PRINT_PWC_DBG(PWC_SWITCH_CPUIDLE,"enter_lowpm,system time:%d private time:%d\n",expected_us, schedule_time); expected_us = schedule_time; } expected_us -= state->exit_latency; DRV_TIMER_STOP(CPU_IDLE_TIMER); DRV_TIMER_START((unsigned int)CPU_IDLE_TIMER, cpu_idle_timer_isr, (int)0, (expected_us / MSEC_PER_SEC), TIMER_ONCE_COUNT, TIMER_UNIT_MS); } if(IDLE_ENABLE == cpu_idle_flag) { *gp_cpuidle_state = (enter_state << CPUIDLE_STATE_START_BIT) | (CPU_IDLE_STAT_VALID << CPUIDLE_STATE_MAGIC_START_BIT); /*pwrctrl_wdt_disable();*/ } if(0 == cpu_id) { PRINT_PWC_DBG(PWC_SWITCH_CPUIDLE,"system will enter cpuidle state(%d)\n",enter_state); } if(CPU_IDLE_C0 == enter_state) { cpu_do_idle(); } else if(IDLE_ENABLE == cpu_idle_flag) { pwrctrl_deep_sleep(); } if(enter_state >= SPECIAL_HANDLE_STATE) { /*清除timer中断*/ /*C3恢复之前停止所有TCXO定时器,待优化*/ } if(IDLE_ENABLE == cpu_idle_flag) { *gp_cpuidle_state = (CPU_IDLE_C4 << CPUIDLE_STATE_START_BIT) | (CPU_IDLE_STAT_VALID << CPUIDLE_STATE_MAGIC_START_BIT); /*pwrctrl_wdt_enable();*/ } getnstimeofday(&after); idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + (after.tv_usec - before.tv_usec); local_irq_enable(); return idle_time; }
/** * ecryptfs_readdir * @file: The eCryptfs directory file * @ctx: The actor to feed the entries to */ static int ecryptfs_readdir(struct file *file, struct dir_context *ctx) { int rc; struct file *lower_file; struct inode *inode = file_inode(file); struct ecryptfs_getdents_callback buf = { .ctx.actor = ecryptfs_filldir, .caller = ctx, .sb = inode->i_sb, }; lower_file = ecryptfs_file_to_lower(file); lower_file->f_pos = ctx->pos; rc = iterate_dir(lower_file, &buf.ctx); ctx->pos = buf.ctx.pos; if (rc < 0) goto out; if (buf.filldir_called && !buf.entries_written) goto out; if (rc >= 0) fsstack_copy_attr_atime(inode, file_inode(lower_file)); out: return rc; } struct kmem_cache *ecryptfs_file_info_cache; static int read_or_initialize_metadata(struct dentry *dentry) { struct inode *inode = dentry->d_inode; struct ecryptfs_mount_crypt_stat *mount_crypt_stat; struct ecryptfs_crypt_stat *crypt_stat; int rc; crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; mount_crypt_stat = &ecryptfs_superblock_to_private( inode->i_sb)->mount_crypt_stat; #ifdef CONFIG_WTL_ENCRYPTION_FILTER if (crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED && crypt_stat->flags & ECRYPTFS_POLICY_APPLIED && crypt_stat->flags & ECRYPTFS_ENCRYPTED && !(crypt_stat->flags & ECRYPTFS_KEY_VALID) && !(crypt_stat->flags & ECRYPTFS_KEY_SET) && crypt_stat->flags & ECRYPTFS_I_SIZE_INITIALIZED) { crypt_stat->flags |= ECRYPTFS_ENCRYPTED_OTHER_DEVICE; } mutex_lock(&crypt_stat->cs_mutex); if ((mount_crypt_stat->flags & ECRYPTFS_ENABLE_NEW_PASSTHROUGH) && (crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { if (ecryptfs_read_metadata(dentry)) { crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED | ECRYPTFS_ENCRYPTED); rc = 0; goto out; } } else if ((mount_crypt_stat->flags & ECRYPTFS_ENABLE_FILTERING) && (crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { struct dentry *fp_dentry = ecryptfs_inode_to_private(inode)->lower_file->f_dentry; char filename[NAME_MAX+1] = {0}; if (fp_dentry->d_name.len <= NAME_MAX) memcpy(filename, fp_dentry->d_name.name, fp_dentry->d_name.len + 1); if (is_file_name_match(mount_crypt_stat, fp_dentry) || is_file_ext_match(mount_crypt_stat, filename)) { if (ecryptfs_read_metadata(dentry)) crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED | ECRYPTFS_ENCRYPTED); rc = 0; goto out; } } mutex_unlock(&crypt_stat->cs_mutex); #endif mutex_lock(&crypt_stat->cs_mutex); if (crypt_stat->flags & ECRYPTFS_POLICY_APPLIED && crypt_stat->flags & ECRYPTFS_KEY_VALID) { rc = 0; goto out; } rc = ecryptfs_read_metadata(dentry); if (!rc) goto out; #ifdef CONFIG_SDP /* * no passthrough/xattr for sensitive files */ if ((rc) && crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE) goto out; #endif if (mount_crypt_stat->flags & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED) { crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED | ECRYPTFS_ENCRYPTED); rc = 0; goto out; } if (!(mount_crypt_stat->flags & ECRYPTFS_XATTR_METADATA_ENABLED) && !i_size_read(ecryptfs_inode_to_lower(inode))) { rc = ecryptfs_initialize_file(dentry, inode); if (!rc) goto out; } rc = -EIO; out: mutex_unlock(&crypt_stat->cs_mutex); #ifdef CONFIG_SDP if(!rc) { /* * SDP v2.0 : sensitive directory (SDP vault) * Files under sensitive directory automatically becomes sensitive */ struct dentry *p = dentry->d_parent; struct inode *parent_inode = p->d_inode; struct ecryptfs_crypt_stat *parent_crypt_stat = &ecryptfs_inode_to_private(parent_inode)->crypt_stat; if (!(crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE) && ((S_ISDIR(parent_inode->i_mode)) && (parent_crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE))) { rc = ecryptfs_sdp_set_sensitive(parent_crypt_stat->engine_id, dentry); } } #endif return rc; } #if defined(CONFIG_MMC_DW_FMP_ECRYPT_FS) || defined(CONFIG_UFS_FMP_ECRYPT_FS) static void ecryptfs_set_rapages(struct file *file, unsigned int flag) { if (!flag) file->f_ra.ra_pages = 0; else file->f_ra.ra_pages = (unsigned int)file->f_mapping->backing_dev_info->ra_pages; } static int ecryptfs_set_fmpinfo(struct file *file, struct inode *inode, unsigned int set_flag) { struct address_space *mapping = file->f_mapping; if (set_flag) { struct ecryptfs_crypt_stat *crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; struct ecryptfs_mount_crypt_stat *mount_crypt_stat = &ecryptfs_superblock_to_private(inode->i_sb)->mount_crypt_stat; if (strncmp(crypt_stat->cipher, "aesxts", sizeof("aesxts")) && strncmp(crypt_stat->cipher, "aes", sizeof("aes"))) { if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { mapping->plain_text = 1; return 0; } else { ecryptfs_printk(KERN_ERR, "%s: Error invalid file encryption algorithm, inode %lu, filename %s alg %s\n" , __func__, inode->i_ino, file->f_dentry->d_name.name, crypt_stat->cipher); return -EINVAL; } } mapping->iv = crypt_stat->root_iv; mapping->key = crypt_stat->key; mapping->sensitive_data_index = crypt_stat->metadata_size/4096; if (mount_crypt_stat->cipher_code == RFC2440_CIPHER_AES_XTS_256) { mapping->key_length = crypt_stat->key_size * 2; mapping->alg = "aesxts"; } else { mapping->key_length = crypt_stat->key_size; mapping->alg = crypt_stat->cipher; } mapping->hash_tfm = crypt_stat->hash_tfm; #ifdef CONFIG_CRYPTO_FIPS mapping->cc_enable = (mount_crypt_stat->flags & ECRYPTFS_ENABLE_CC)?1:0; #endif } else { mapping->iv = NULL; mapping->key = NULL; mapping->key_length = 0; mapping->sensitive_data_index = 0; mapping->alg = NULL; mapping->hash_tfm = NULL; #ifdef CONFIG_CRYPTO_FIPS mapping->cc_enable = 0; #endif mapping->plain_text = 0; } return 0; } void ecryptfs_propagate_rapages(struct file *file, unsigned int flag) { struct file *f = file; do { if (!f) return; ecryptfs_set_rapages(f, flag); } while(f->f_op->get_lower_file && (f = f->f_op->get_lower_file(f))); } int ecryptfs_propagate_fmpinfo(struct inode *inode, unsigned int flag) { struct file *f = ecryptfs_inode_to_private(inode)->lower_file; do { if (!f) return 0; if (ecryptfs_set_fmpinfo(f, inode, flag)) return -EINVAL; } while(f->f_op->get_lower_file && (f = f->f_op->get_lower_file(f))); return 0; } #endif /** * ecryptfs_open * @inode: inode speciying file to open * @file: Structure to return filled in * * Opens the file specified by inode. * * Returns zero on success; non-zero otherwise */ static int ecryptfs_open(struct inode *inode, struct file *file) { int rc = 0; struct ecryptfs_crypt_stat *crypt_stat = NULL; struct dentry *ecryptfs_dentry = file->f_path.dentry; /* Private value of ecryptfs_dentry allocated in * ecryptfs_lookup() */ struct ecryptfs_file_info *file_info; #ifdef CONFIG_DLP sdp_fs_command_t *cmd = NULL; ssize_t dlp_len = 0; struct knox_dlp_data dlp_data; struct timespec ts; #endif #if defined(CONFIG_MMC_DW_FMP_ECRYPT_FS) || defined(CONFIG_UFS_FMP_ECRYPT_FS) || defined(CONFIG_SDP) struct ecryptfs_mount_crypt_stat *mount_crypt_stat; mount_crypt_stat = &ecryptfs_superblock_to_private( inode->i_sb)->mount_crypt_stat; #endif /* Released in ecryptfs_release or end of function if failure */ file_info = kmem_cache_zalloc(ecryptfs_file_info_cache, GFP_KERNEL); ecryptfs_set_file_private(file, file_info); if (!file_info) { ecryptfs_printk(KERN_ERR, "Error attempting to allocate memory\n"); rc = -ENOMEM; goto out; } crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; mutex_lock(&crypt_stat->cs_mutex); if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) { ecryptfs_printk(KERN_DEBUG, "Setting flags for stat...\n"); /* Policy code enabled in future release */ crypt_stat->flags |= (ECRYPTFS_POLICY_APPLIED | ECRYPTFS_ENCRYPTED); } mutex_unlock(&crypt_stat->cs_mutex); rc = ecryptfs_get_lower_file(ecryptfs_dentry, inode); if (rc) { printk(KERN_ERR "%s: Error attempting to initialize " "the lower file for the dentry with name " "[%pd]; rc = [%d]\n", __func__, ecryptfs_dentry, rc); goto out_free; } if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_ACCMODE) == O_RDONLY && (file->f_flags & O_ACCMODE) != O_RDONLY) { rc = -EPERM; printk(KERN_WARNING "%s: Lower file is RO; eCryptfs " "file must hence be opened RO\n", __func__); goto out_put; } ecryptfs_set_file_lower( file, ecryptfs_inode_to_private(inode)->lower_file); if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { #ifdef CONFIG_SDP /* * it's possible to have a sensitive directory. (vault) */ if (mount_crypt_stat->flags & ECRYPTFS_MOUNT_SDP_ENABLED) crypt_stat->flags |= ECRYPTFS_DEK_SDP_ENABLED; #endif ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); mutex_lock(&crypt_stat->cs_mutex); crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); mutex_unlock(&crypt_stat->cs_mutex); rc = 0; goto out; } rc = read_or_initialize_metadata(ecryptfs_dentry); if (rc) { #ifdef CONFIG_SDP if(file->f_flags & O_SDP){ printk("Failed to initialize metadata, " "but let it continue cause current call is from SDP API\n"); mutex_lock(&crypt_stat->cs_mutex); crypt_stat->flags &= ~(ECRYPTFS_KEY_VALID); mutex_unlock(&crypt_stat->cs_mutex); rc = 0; /* * Letting this continue doesn't mean to allow read/writing. It will anyway fail later. * * 1. In this stage, ecryptfs_stat won't have key/iv and encryption ctx. * 2. ECRYPTFS_KEY_VALID bit is off, next attempt will try reading metadata again. * 3. Skip DEK conversion. it cannot be done anyway. */ goto out; } #endif goto out_put; } #if defined(CONFIG_MMC_DW_FMP_ECRYPT_FS) || defined(CONFIG_UFS_FMP_ECRYPT_FS) if (mount_crypt_stat->flags & ECRYPTFS_USE_FMP) rc = ecryptfs_propagate_fmpinfo(inode, FMPINFO_SET); else rc = ecryptfs_propagate_fmpinfo(inode, FMPINFO_CLEAR); #endif if (rc) goto out_put; #ifdef CONFIG_SDP if (crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE) { #ifdef CONFIG_SDP_KEY_DUMP if (S_ISREG(ecryptfs_dentry->d_inode->i_mode)) { if(get_sdp_sysfs_key_dump()) { printk("FEK[%s] : ", ecryptfs_dentry->d_name.name); key_dump(crypt_stat->key, 32); } } #endif /* * Need to update sensitive mapping on file open */ if (S_ISREG(ecryptfs_dentry->d_inode->i_mode)) { ecryptfs_set_mapping_sensitive(inode, mount_crypt_stat->userid, TO_SENSITIVE); } if (ecryptfs_is_sdp_locked(crypt_stat->engine_id)) { ecryptfs_printk(KERN_INFO, "ecryptfs_open: persona is locked, rc=%d\n", rc); } else { int dek_type = crypt_stat->sdp_dek.type; ecryptfs_printk(KERN_INFO, "ecryptfs_open: persona is unlocked, rc=%d\n", rc); if(dek_type != DEK_TYPE_AES_ENC) { ecryptfs_printk(KERN_DEBUG, "converting dek...\n"); rc = ecryptfs_sdp_convert_dek(ecryptfs_dentry); ecryptfs_printk(KERN_DEBUG, "conversion ready, rc=%d\n", rc); rc = 0; // TODO: Do we need to return error if conversion fails? } } } #if ECRYPTFS_DEK_DEBUG else { ecryptfs_printk(KERN_INFO, "ecryptfs_open: dek_file_type is protected\n"); } #endif #endif #ifdef CONFIG_DLP if(crypt_stat->flags & ECRYPTFS_DLP_ENABLED) { #if DLP_DEBUG printk("DLP %s: try to open %s with crypt_stat->flags %d\n", __func__, ecryptfs_dentry->d_name.name, crypt_stat->flags); #endif if (dlp_is_locked(mount_crypt_stat->userid)) { printk("%s: DLP locked\n", __func__); rc = -EPERM; goto out_put; } if(in_egroup_p(AID_KNOX_DLP) || in_egroup_p(AID_KNOX_DLP_RESTRICTED)) { dlp_len = ecryptfs_getxattr_lower( ecryptfs_dentry_to_lower(ecryptfs_dentry), KNOX_DLP_XATTR_NAME, &dlp_data, sizeof(dlp_data)); if (dlp_len == sizeof(dlp_data)) { getnstimeofday(&ts); #if DLP_DEBUG printk("DLP %s: current time [%ld/%ld] %s\n", __func__, (long)ts.tv_sec, (long)dlp_data.expiry_time.tv_sec, ecryptfs_dentry->d_name.name); #endif if ((ts.tv_sec > dlp_data.expiry_time.tv_sec) && dlp_isInterestedFile(ecryptfs_dentry->d_name.name)==0) { /* Command to delete expired file */ cmd = sdp_fs_command_alloc(FSOP_DLP_FILE_REMOVE, current->tgid, mount_crypt_stat->userid, mount_crypt_stat->partition_id, inode->i_ino, GFP_KERNEL); rc = -ENOENT; goto out_put; } } else if (dlp_len == -ENODATA) { /* DLP flag is set, but no DLP data. Let it continue, xattr will be set later */ printk("DLP %s: normal file [%s]\n", __func__, ecryptfs_dentry->d_name.name); } else { printk("DLP %s: Error, len [%ld], [%s]\n", __func__, (long)dlp_len, ecryptfs_dentry->d_name.name); rc = -EFAULT; goto out_put; } #if DLP_DEBUG printk("DLP %s: DLP file [%s] opened with tgid %d, %d\n" , __func__, ecryptfs_dentry->d_name.name, current->tgid, in_egroup_p(AID_KNOX_DLP_RESTRICTED)); #endif if(in_egroup_p(AID_KNOX_DLP_RESTRICTED)) { cmd = sdp_fs_command_alloc(FSOP_DLP_FILE_OPENED, current->tgid, mount_crypt_stat->userid, mount_crypt_stat->partition_id, inode->i_ino, GFP_KERNEL); } } else { printk("DLP %s: not DLP app [%s]\n", __func__, current->comm); rc = -EPERM; goto out_put; } } #endif ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = " "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, (unsigned long long)i_size_read(inode)); goto out; out_put: ecryptfs_put_lower_file(inode); out_free: kmem_cache_free(ecryptfs_file_info_cache, ecryptfs_file_to_private(file)); out: #ifdef CONFIG_DLP if(cmd) { sdp_fs_request(cmd, NULL); sdp_fs_command_free(cmd); } #endif return rc; }
static unsigned long read_current_us(void) { struct timespec now; getnstimeofday(&now); return (now.tv_sec * 1000000) + (now.tv_nsec/1000); }
int pscnv_dma_bo_to_bo(struct pscnv_bo *tgt, struct pscnv_bo *src, int flags) { struct drm_device *dev = tgt->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct pscnv_dma *dma = dev_priv->dma; struct pscnv_mm_node *tgt_node; struct pscnv_mm_node *src_node; const uint32_t size = tgt->size; struct timespec start, start_real, end, end_real; s64 start_ns, start_real_ns, duration, duration_real; int ret; flags = pscnv_dma_setup_flags(flags); if (!dma) { NV_ERROR(dev, "DMA: not available\n"); return -ENOENT; } BUG_ON(tgt->dev != src->dev); mutex_lock(&dma->lock); getnstimeofday(&start_real); start_real_ns = timespec_to_ns(&start_real); if (tgt->size < src->size) { NV_INFO(dev, "DMA: source bo (cookie=%x) has size %lld, but target bo " "(cookie=%x) only has size %lld\n", src->cookie, src->size, tgt->cookie, tgt->size); return -ENOSPC; } ret = pscnv_vspace_map(dma->vs, tgt, 0x20000000, /* start */ 1ull << 40, /* end */ 0, /* back, nonsense? */ &tgt_node); if (ret) { NV_INFO(dev, "DMA: failed to map target bo\n"); goto fail_map_tgt; } ret = pscnv_vspace_map(dma->vs, src, 0x20000000, /* start */ 1ull << 40, /* end */ 0, /* back, nonsense? */ &src_node); if (ret) { NV_INFO(dev, "DMA: failed to map source bo\n"); goto fail_map_src; } if (flags & PSCNV_DMA_DEBUG) { dev_priv->chan->pd_dump_chan(dev, NULL /* seq_file */, PSCNV_DMA_CHAN); } getnstimeofday(&start); start_ns = timespec_to_ns(&start); pscnv_ib_membar(dma->ib_chan); if (flags & PSCNV_DMA_ASYNC) { pscnv_ib_fence_write(dma->ib_chan, GDEV_SUBCH_NV_PCOPY0); nvc0_memcpy_pcopy0(dma->ib_chan, tgt_node->start, src_node->start, size, flags); } else { pscnv_ib_fence_write(dma->ib_chan, GDEV_SUBCH_NV_M2MF); nvc0_memcpy_m2mf(dma->ib_chan, tgt_node->start, src_node->start, size, flags); } ret = pscnv_ib_fence_wait(dma->ib_chan); if (ret) { NV_INFO(dev, "DMA: failed to wait for fence completion\n"); goto fail_fence_wait; } getnstimeofday(&end); /* no return here, always unmap memory */ fail_fence_wait: pscnv_vspace_unmap_node(src_node); fail_map_src: pscnv_vspace_unmap_node(tgt_node); fail_map_tgt: mutex_unlock(&dma->lock); getnstimeofday(&end_real); if (!ret) { duration = timespec_to_ns(&end) - start_ns; duration_real = timespec_to_ns(&end_real) - start_real_ns; if (flags & PSCNV_DMA_VERBOSE) { NV_INFO(dev, "DMA: took %lld.%04lld ms (real %lld.%04lld ms)\n", duration / 1000000, (duration % 1000000) / 100, duration_real / 1000000, (duration_real % 1000000) / 100); } pscnv_client_track_time(src->client, start_ns, duration, size, "DMA"); pscnv_client_track_time(src->client, start_ns, duration_real, size, "DMA_REAL"); if (src->client) src->client->pause_bytes_transferred += size; } return ret; }
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; }
int pscnv_dma_chunk_to_chunk(struct pscnv_chunk *from, struct pscnv_chunk *to, int flags) { struct drm_device *dev = from->bo->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct pscnv_dma *dma = dev_priv->dma; struct pscnv_client *client = from->bo->client; struct pscnv_mm_node *from_node; struct pscnv_mm_node *to_node; const uint64_t size = pscnv_chunk_size(from); struct timespec start, start_real, end, end_real; s64 start_ns, start_real_ns, duration, duration_real; int ret; flags = pscnv_dma_setup_flags(flags); if (!dma) { NV_ERROR(dev, "DMA: not available\n"); return -ENOENT; } BUG_ON(from->bo->dev != to->bo->dev); mutex_lock(&dma->lock); getnstimeofday(&start_real); start_real_ns = timespec_to_ns(&start_real); if (pscnv_chunk_size(to) < size) { NV_INFO(dev, "DMA: source chunk %08x/%d-%u has size %lld, but " "target chunk %08x/%d-%u only has size %lld\n", from->bo->cookie, from->bo->serial, from->idx, size, to->bo->cookie, to->bo->serial, to->idx, pscnv_chunk_size(to)); return -ENOSPC; } ret = pscnv_vspace_map_chunk(dma->vs, to, 0x20000000, /* start */ 1ull << 40, /* end */ 0, /* back, nonsense? */ &to_node); if (ret) { NV_INFO(dev, "DMA: failed to map 'to' chunk\n"); goto fail_map_to; } ret = pscnv_vspace_map_chunk(dma->vs, from, 0x20000000, /* start */ 1ull << 40, /* end */ 0, /* back, nonsense? */ &from_node); if (ret) { NV_INFO(dev, "DMA: failed to map 'from' chunk\n"); goto fail_map_from; } if (flags & PSCNV_DMA_DEBUG) { dev_priv->chan->pd_dump_chan(dev, NULL /* seq_file */, PSCNV_DMA_CHAN); } getnstimeofday(&start); start_ns = timespec_to_ns(&start); pscnv_ib_membar(dma->ib_chan); if (flags & PSCNV_DMA_ASYNC) { pscnv_ib_fence_write(dma->ib_chan, GDEV_SUBCH_NV_PCOPY0); nvc0_memcpy_pcopy0(dma->ib_chan, to_node->start, from_node->start, size, flags); } else { pscnv_ib_fence_write(dma->ib_chan, GDEV_SUBCH_NV_M2MF); nvc0_memcpy_m2mf(dma->ib_chan, to_node->start, from_node->start, size, flags); } ret = pscnv_ib_fence_wait(dma->ib_chan); if (ret) { NV_INFO(dev, "DMA: failed to wait for fence completion\n"); goto fail_fence_wait; } getnstimeofday(&end); /* no return here, always unmap memory */ fail_fence_wait: pscnv_vspace_unmap_node(from_node); fail_map_from: pscnv_vspace_unmap_node(to_node); fail_map_to: mutex_unlock(&dma->lock); getnstimeofday(&end_real); if (!ret) { duration = timespec_to_ns(&end) - start_ns; duration_real = timespec_to_ns(&end_real) - start_real_ns; if (flags & PSCNV_DMA_VERBOSE) { NV_INFO(dev, "DMA: took %lld.%04lld ms (real %lld.%04lld ms)\n", duration / 1000000, (duration % 1000000) / 100, duration_real / 1000000, (duration_real % 1000000) / 100); } pscnv_client_track_time(client, start_ns, duration, size, "DMA"); pscnv_client_track_time(client, start_ns, duration_real, size, "DMA_REAL"); if (client) client->pause_bytes_transferred += size; } return ret; }
int ip_options_compile(struct net *net, struct ip_options *opt, struct sk_buff *skb) { __be32 spec_dst = htonl(INADDR_ANY); unsigned char *pp_ptr = NULL; struct rtable *rt = NULL; unsigned char *optptr; unsigned char *iph; int optlen, l; if (skb) { rt = skb_rtable(skb); optptr = (unsigned char *)&(ip_hdr(skb)[1]); } else optptr = opt->__data; iph = optptr - sizeof(struct iphdr); for (l = opt->optlen; l > 0; ) { switch (*optptr) { case IPOPT_END: for (optptr++, l--; l > 0; optptr++, l--) { if (*optptr != IPOPT_END) { *optptr = IPOPT_END; opt->is_changed = 1; } } goto eol; case IPOPT_NOOP: l--; optptr++; continue; } if (unlikely(l < 2)) { pp_ptr = optptr; goto error; } optlen = optptr[1]; if (optlen < 2 || optlen > l) { pp_ptr = optptr; goto error; } switch (*optptr) { case IPOPT_SSRR: case IPOPT_LSRR: if (optlen < 3) { pp_ptr = optptr + 1; goto error; } if (optptr[2] < 4) { pp_ptr = optptr + 2; goto error; } /* NB: cf RFC-1812 5.2.4.1 */ if (opt->srr) { pp_ptr = optptr; goto error; } if (!skb) { if (optptr[2] != 4 || optlen < 7 || ((optlen-3) & 3)) { pp_ptr = optptr + 1; goto error; } memcpy(&opt->faddr, &optptr[3], 4); if (optlen > 7) memmove(&optptr[3], &optptr[7], optlen-7); } opt->is_strictroute = (optptr[0] == IPOPT_SSRR); opt->srr = optptr - iph; break; case IPOPT_RR: if (opt->rr) { pp_ptr = optptr; goto error; } if (optlen < 3) { pp_ptr = optptr + 1; goto error; } if (optptr[2] < 4) { pp_ptr = optptr + 2; goto error; } if (optptr[2] <= optlen) { if (optptr[2]+3 > optlen) { pp_ptr = optptr + 2; goto error; } if (rt) { spec_dst_fill(&spec_dst, skb); memcpy(&optptr[optptr[2]-1], &spec_dst, 4); opt->is_changed = 1; } optptr[2] += 4; opt->rr_needaddr = 1; } opt->rr = optptr - iph; break; case IPOPT_TIMESTAMP: if (opt->ts) { pp_ptr = optptr; goto error; } if (optlen < 4) { pp_ptr = optptr + 1; goto error; } if (optptr[2] < 5) { pp_ptr = optptr + 2; goto error; } if (optptr[2] <= optlen) { unsigned char *timeptr = NULL; if (optptr[2]+3 > optlen) { pp_ptr = optptr + 2; goto error; } switch (optptr[3]&0xF) { case IPOPT_TS_TSONLY: if (skb) timeptr = &optptr[optptr[2]-1]; opt->ts_needtime = 1; optptr[2] += 4; break; case IPOPT_TS_TSANDADDR: if (optptr[2]+7 > optlen) { pp_ptr = optptr + 2; goto error; } if (rt) { spec_dst_fill(&spec_dst, skb); memcpy(&optptr[optptr[2]-1], &spec_dst, 4); timeptr = &optptr[optptr[2]+3]; } opt->ts_needaddr = 1; opt->ts_needtime = 1; optptr[2] += 8; break; case IPOPT_TS_PRESPEC: if (optptr[2]+7 > optlen) { pp_ptr = optptr + 2; goto error; } { __be32 addr; memcpy(&addr, &optptr[optptr[2]-1], 4); if (inet_addr_type(net, addr) == RTN_UNICAST) break; if (skb) timeptr = &optptr[optptr[2]+3]; } opt->ts_needtime = 1; optptr[2] += 8; break; default: if (!skb && !ns_capable(net->user_ns, CAP_NET_RAW)) { pp_ptr = optptr + 3; goto error; } break; } if (timeptr) { struct timespec tv; u32 midtime; getnstimeofday(&tv); midtime = (tv.tv_sec % 86400) * MSEC_PER_SEC + tv.tv_nsec / NSEC_PER_MSEC; put_unaligned_be32(midtime, timeptr); opt->is_changed = 1; } } else if ((optptr[3]&0xF) != IPOPT_TS_PRESPEC) { unsigned int overflow = optptr[3]>>4; if (overflow == 15) { pp_ptr = optptr + 3; goto error; } if (skb) { optptr[3] = (optptr[3]&0xF)|((overflow+1)<<4); opt->is_changed = 1; } } opt->ts = optptr - iph; break; case IPOPT_RA: if (optlen < 4) { pp_ptr = optptr + 1; goto error; } if (optptr[2] == 0 && optptr[3] == 0) opt->router_alert = optptr - iph; break; case IPOPT_CIPSO: if ((!skb && !ns_capable(net->user_ns, CAP_NET_RAW)) || opt->cipso) { pp_ptr = optptr; goto error; } opt->cipso = optptr - iph; if (cipso_v4_validate(skb, &optptr)) { pp_ptr = optptr; goto error; } break; case IPOPT_SEC: case IPOPT_SID: default: if (!skb && !ns_capable(net->user_ns, CAP_NET_RAW)) { pp_ptr = optptr; goto error; } break; } l -= optlen; optptr += optlen; }
void iframe_worker(unsigned long data) { struct fscc_port *port = 0; int receive_length = 0; /* Needs to be signed */ unsigned finished_frame = 0; unsigned long board_flags = 0; unsigned long frame_flags = 0; unsigned long queued_flags = 0; static int rejected_last_frame = 0; unsigned current_memory = 0; unsigned memory_cap = 0; unsigned rfcnt = 0; port = (struct fscc_port *)data; return_if_untrue(port); do { current_memory = fscc_port_get_input_memory_usage(port); memory_cap = fscc_port_get_input_memory_cap(port); spin_lock_irqsave(&port->board_rx_spinlock, board_flags); spin_lock_irqsave(&port->pending_iframe_spinlock, frame_flags); rfcnt = fscc_port_get_RFCNT(port); finished_frame = (rfcnt > 0) ? 1 : 0; if (finished_frame) { unsigned bc_fifo_l = 0; unsigned current_length = 0; bc_fifo_l = fscc_port_get_register(port, 0, BC_FIFO_L_OFFSET); if (port->pending_iframe) current_length = fscc_frame_get_length(port->pending_iframe); receive_length = bc_fifo_l - current_length; } else { unsigned rxcnt = 0; // Refresh rfcnt, if the frame is now complete, reloop through // This prevents the situation where the frame has finished being // received between the original rfcnt and now, causing a possible // read of a larger byte count than in the actual frame due to // another incoming frame rxcnt = fscc_port_get_RXCNT(port); rfcnt = fscc_port_get_RFCNT(port); if (rfcnt) { spin_unlock_irqrestore(&port->pending_iframe_spinlock, frame_flags); spin_unlock_irqrestore(&port->board_rx_spinlock, board_flags); break; } /* We choose a safe amount to read due to more data coming in after we get our values. The rest will be read on the next interrupt. */ receive_length = max((int)(rxcnt - rxcnt % 4), (int)0); } if (receive_length <= 0) { spin_unlock_irqrestore(&port->pending_iframe_spinlock, frame_flags); spin_unlock_irqrestore(&port->board_rx_spinlock, board_flags); return; } /* Make sure we don't go over the user's memory constraint. */ if (current_memory + receive_length > memory_cap) { if (rejected_last_frame == 0) { dev_warn(port->device, "Rejecting frames (memory constraint)\n"); rejected_last_frame = 1; /* Track that we dropped a frame so we don't have to warn the user again. */ } if (port->pending_iframe) { fscc_frame_delete(port->pending_iframe); port->pending_iframe = 0; } spin_unlock_irqrestore(&port->pending_iframe_spinlock, frame_flags); spin_unlock_irqrestore(&port->board_rx_spinlock, board_flags); return; } if (!port->pending_iframe) { port->pending_iframe = fscc_frame_new(port); if (!port->pending_iframe) { spin_unlock_irqrestore(&port->pending_iframe_spinlock, frame_flags); spin_unlock_irqrestore(&port->board_rx_spinlock, board_flags); return; } } fscc_frame_add_data_from_port(port->pending_iframe, port, receive_length); #ifdef __BIG_ENDIAN { char status[STATUS_LENGTH]; /* Moves the status bytes to the end. */ memmove(&status, port->pending_iframe->data, STATUS_LENGTH); memmove(port->pending_iframe->data, port->pending_iframe->data + STATUS_LENGTH, port->pending_iframe->current_length - STATUS_LENGTH); memmove(port->pending_iframe->data + port->pending_iframe->current_length - STATUS_LENGTH, &status, STATUS_LENGTH); } #endif dev_dbg(port->device, "F#%i <= %i byte%s (%sfinished)\n", port->pending_iframe->number, receive_length, (receive_length == 1) ? "" : "s", (finished_frame) ? "" : "un"); if (!finished_frame) { spin_unlock_irqrestore(&port->pending_iframe_spinlock, frame_flags); spin_unlock_irqrestore(&port->board_rx_spinlock, board_flags); return; } if (port->pending_iframe) { #ifdef RELEASE_PREVIEW getnstimeofday(&port->pending_iframe->timestamp); #else do_gettimeofday(&port->pending_iframe->timestamp); #endif spin_lock_irqsave(&port->queued_iframes_spinlock, queued_flags); fscc_flist_add_frame(&port->queued_iframes, port->pending_iframe); spin_unlock_irqrestore(&port->queued_iframes_spinlock, queued_flags); } rejected_last_frame = 0; /* Track that we received a frame to reset the memory constraint warning print message. */ port->pending_iframe = 0; spin_unlock_irqrestore(&port->pending_iframe_spinlock, frame_flags); spin_unlock_irqrestore(&port->board_rx_spinlock, board_flags); wake_up_interruptible(&port->input_queue); } while (receive_length); }
static void process_cb_request(void *buffer) { struct rtc_cb_recv *rtc_cb = buffer; struct timespec ts, tv; rtc_cb->client_cb_id = be32_to_cpu(rtc_cb->client_cb_id); rtc_cb->event = be32_to_cpu(rtc_cb->event); rtc_cb->cb_info_ptr = be32_to_cpu(rtc_cb->cb_info_ptr); if (rtc_cb->event == EVENT_TOD_CHANGE) { /* A TOD update has been received from the Modem */ rtc_cb->cb_info_data.tod_update.tick = be32_to_cpu(rtc_cb->cb_info_data.tod_update.tick); rtc_cb->cb_info_data.tod_update.stamp = be64_to_cpu(rtc_cb->cb_info_data.tod_update.stamp); rtc_cb->cb_info_data.tod_update.freq = be32_to_cpu(rtc_cb->cb_info_data.tod_update.freq); pr_info("RPC CALL -- TOD TIME UPDATE: ttick = %d\n" "stamp=%lld, freq = %d\n", rtc_cb->cb_info_data.tod_update.tick, rtc_cb->cb_info_data.tod_update.stamp, rtc_cb->cb_info_data.tod_update.freq); getnstimeofday(&ts); /* CR 291540 - Function/Feature Failure (Partial) * system uptime gets corrupted with overflow in slow clock. * * Problem description * During power collapse, APPS sleep time is calculated using slow clock * ticks. The calculation of sleep time does not considers slow clock * overflow and thus If slow clock overflows during suspend state then we * get wrong sleep time and thus system uptime values gets corrupted. * earlier sleep time was calculates as follows: * sleep = current_sclk_tick - suspend_state_sclk_tick * * Failure frequency: Occasionally * Scenario frequency: Uncommon * Change description * Modified the sleep time calculation to include slow clock overflow as follows: * Now sleep time is calculated as: * sleep = Maximum_sclk_tick_val - suspend_state_sclk_tick + current_sclk_tick. * Files affected * kernel/drivers/rtc/rtc-msm.c * kernel/arch/arm/mach-msm/rpc_server_time_remote.c */ if (atomic_read(&suspend_state.state)) { #if 1 //QCT SBA 404016 int64_t now, sleep, sclk_max; now = msm_timer_get_sclk_time(&sclk_max); #else int64_t now, sleep; now = msm_timer_get_sclk_time(NULL); #endif if (now && suspend_state.tick_at_suspend) { #if 1 //QCT SBA 404016 if (now < suspend_state.tick_at_suspend) { sleep = sclk_max - suspend_state.tick_at_suspend + now; } else { sleep = now - suspend_state.tick_at_suspend; } #else sleep = now - suspend_state.tick_at_suspend; #endif timespec_add_ns(&ts, sleep); /* CR 293735 - Function/Feature Failure (Partial) * When system was in suspend, could make invalid "elapsed system time" at AP side. * * Problem description * When system is in suspend mode and if more than one network time update * comes while system is in suspend mode then the uptime gets corrupted. * * Failure frequency: Occasionally * Scenario frequency: Uncommon * Change description * Added change to modify tick_at_suspend (variable that stores time tick * while entering suspend) after each update to the current time tick. * Setting the suspend mode variable in case alarm time expires the current * RTC time as in thic case also system enters suspend mode. * to sdcc irq handlers returning IRQ_NONE without handling the interrupt. * When interrupt is disabled the communication between the SDIO client and * SDCC host controller is stopped while a pending command is in progress * and hence WLAN operation is stuck forever and LOGP recovery cannot be * processed. * Files affected * arch/arm/mach-msm/rpc_server_time_remote.c * drivers/rtc/rtc-msm.c * include/linux/rtc-msm.h */ #if 1 //QCT SBA 404017 suspend_state.tick_at_suspend = now; #endif } else pr_err("%s: Invalid ticks from SCLK" "now=%lld tick_at_suspend=%lld", __func__, now, suspend_state.tick_at_suspend); } rtc_hctosys(); getnstimeofday(&tv); /* Update the alarm information with the new time info. */ alarm_update_timedelta(ts, tv); } else pr_err("%s: Unknown event EVENT=%x\n", __func__, rtc_cb->event); }
static void omap2_enter_full_retention(void) { u32 l; struct timespec ts_preidle, ts_postidle, ts_idle; /* There is 1 reference hold for all children of the oscillator * clock, the following will remove it. If no one else uses the * oscillator itself it will be disabled if/when we enter retention * mode. */ clk_disable(osc_ck); /* Clear old wake-up events */ /* REVISIT: These write to reserved bits? */ prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1); prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2); prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST); /* * Set MPU powerdomain's next power state to RETENTION; * preserve logic state during retention */ pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET); pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET); /* Workaround to kill USB */ l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL; omap_ctrl_writel(l, OMAP2_CONTROL_DEVCONF0); omap2_gpio_prepare_for_idle(PWRDM_POWER_RET); if (omap2_pm_debug) { omap2_pm_dump(0, 0, 0); getnstimeofday(&ts_preidle); } /* One last check for pending IRQs to avoid extra latency due * to sleeping unnecessarily. */ if (omap_irq_pending()) goto no_sleep; omap_uart_prepare_idle(0); omap_uart_prepare_idle(1); omap_uart_prepare_idle(2); /* Jump to SRAM suspend code */ omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL), OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL), OMAP_SDRC_REGADDR(SDRC_POWER)); omap_uart_resume_idle(2); omap_uart_resume_idle(1); omap_uart_resume_idle(0); no_sleep: if (omap2_pm_debug) { unsigned long long tmp; getnstimeofday(&ts_postidle); ts_idle = timespec_sub(ts_postidle, ts_preidle); tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC; omap2_pm_dump(0, 1, tmp); } omap2_gpio_resume_after_idle(); clk_enable(osc_ck); /* clear CORE wake-up events */ prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1); prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2); /* wakeup domain events - bit 1: GPT1, bit5 GPIO */ prm_clear_mod_reg_bits(0x4 | 0x1, WKUP_MOD, PM_WKST); /* MPU domain wake events */ l = prm_read_mod_reg(OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET); if (l & 0x01) prm_write_mod_reg(0x01, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET); if (l & 0x20) prm_write_mod_reg(0x20, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET); /* Mask future PRCM-to-MPU interrupts */ prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET); }
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; }
/* return time in microseconds */ u64 bpf_get_usec_time(void) { struct timespec now; getnstimeofday(&now); return (((u64)now.tv_sec) * 1000000) + now.tv_nsec / 1000; }
/* -------------------------------------------------------------------- */ int fpc1020_capture_task(fpc1020_data_t *fpc1020) { struct timespec ts_t1, ts_t2, ts_t3, ts_delta; int time_settings_us[FPC1020_BUFFER_MAX_IMAGES]; int time_capture_us[FPC1020_BUFFER_MAX_IMAGES]; int time_capture_sum_us; int error = 0; bool wait_finger_down = false; bool wait_finger_up = false; bool adjust_settings; fpc1020_capture_mode_t mode = fpc1020->capture.current_mode; int current_capture, capture_count; int image_offset; size_t image_byte_size; fpc1020->capture.state = FPC1020_CAPTURE_STATE_WRITE_SETTINGS; error = fpc1020_wake_up(fpc1020); if (error < 0) goto out_error; switch (mode) { case FPC1020_MODE_WAIT_AND_CAPTURE: wait_finger_down = wait_finger_up = true; case FPC1020_MODE_SINGLE_CAPTURE: case FPC1020_MODE_SINGLE_CAPTURE_CAL: capture_count = fpc1020->setup.capture_count; adjust_settings = true; error = fpc1020_write_capture_setup(fpc1020); break; case FPC1020_MODE_CHECKERBOARD_TEST_NORM: capture_count = 1; adjust_settings = false; error = fpc1020_write_cb_test_setup(fpc1020, false); break; case FPC1020_MODE_CHECKERBOARD_TEST_INV: capture_count = 1; adjust_settings = false; error = fpc1020_write_cb_test_setup(fpc1020, true); break; case FPC1020_MODE_BOARD_TEST_ONE: capture_count = 1; adjust_settings = false; error = fpc1020_write_test_setup(fpc1020, 0xffff); break; case FPC1020_MODE_BOARD_TEST_ZERO: capture_count = 1; adjust_settings = false; error = fpc1020_write_test_setup(fpc1020, 0x0000); break; case FPC1020_MODE_WAIT_FINGER_DOWN: wait_finger_down = true; capture_count = 0; adjust_settings = false; error = fpc1020_write_capture_setup(fpc1020); break; case FPC1020_MODE_WAIT_FINGER_UP: wait_finger_up = true; capture_count = 0; adjust_settings = false; error = fpc1020_write_capture_setup(fpc1020); break; case FPC1020_MODE_IDLE: default: capture_count = 0; adjust_settings = false; error = -EINVAL; break; } if (error < 0) goto out_error; error = fpc1020_capture_set_crop(fpc1020, fpc1020->setup.capture_col_start, fpc1020->setup.capture_col_groups, fpc1020->setup.capture_row_start, fpc1020->setup.capture_row_count); if (error < 0) goto out_error; image_byte_size = fpc1020_calc_image_size(fpc1020); dev_dbg(&fpc1020->spi->dev, "Start capture, mode %d, (%d frames)\n", mode, capture_count); if (!wait_finger_down) fpc1020->capture.deferred_finger_up = false; if (wait_finger_down) { error = fpc1020_capture_finger_detect_settings(fpc1020); if (error < 0) goto out_error; } if (wait_finger_down && fpc1020->capture.deferred_finger_up) { fpc1020->capture.state = FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_UP; dev_dbg(&fpc1020->spi->dev, "Waiting for (deferred) finger up\n"); error = fpc1020_capture_wait_finger_up(fpc1020); if (error < 0) goto out_error; dev_dbg(&fpc1020->spi->dev, "Finger up\n"); fpc1020->capture.deferred_finger_up = false; } if (wait_finger_down) { fpc1020->capture.state = FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_DOWN; error = fpc1020_capture_wait_finger_down(fpc1020); if (error < 0) goto out_error; dev_dbg(&fpc1020->spi->dev, "Finger down\n"); if (mode == FPC1020_MODE_WAIT_FINGER_DOWN) { fpc1020->capture.available_bytes = 4; fpc1020->huge_buffer[0] = 'F'; fpc1020->huge_buffer[1] = ':'; fpc1020->huge_buffer[2] = 'D'; fpc1020->huge_buffer[3] = 'N'; } } current_capture = 0; image_offset = 0; fpc1020->diag.last_capture_time = 0; if (mode == FPC1020_MODE_SINGLE_CAPTURE_CAL) { error = fpc1020_capture_set_sample_mode(fpc1020, true); if (error) goto out_error; } while (capture_count && (error >= 0)) { getnstimeofday(&ts_t1); fpc1020->capture.state = FPC1020_CAPTURE_STATE_ACQUIRE; dev_dbg(&fpc1020->spi->dev, "Capture, frame #%d \n", current_capture + 1); error = (!adjust_settings) ? 0 : fpc1020_capture_settings(fpc1020, current_capture); if (error < 0) goto out_error; getnstimeofday(&ts_t2); error = fpc1020_cmd(fpc1020, FPC1020_CMD_CAPTURE_IMAGE, FPC_1020_IRQ_REG_BIT_FIFO_NEW_DATA); if (error < 0) goto out_error; fpc1020->capture.state = FPC1020_CAPTURE_STATE_FETCH; error = fpc1020_fetch_image(fpc1020, fpc1020->huge_buffer, image_offset, image_byte_size, (size_t)fpc1020->huge_buffer_size); if (error < 0) goto out_error; fpc1020->capture.available_bytes += (error >= 0) ? (int)image_byte_size : 0; fpc1020->capture.last_error = error; getnstimeofday(&ts_t3); ts_delta = timespec_sub(ts_t2, ts_t1); time_settings_us[current_capture] = ts_delta.tv_sec * USEC_PER_SEC + (ts_delta.tv_nsec / NSEC_PER_USEC); ts_delta = timespec_sub(ts_t3, ts_t2); time_capture_us[current_capture] = ts_delta.tv_sec * USEC_PER_SEC + (ts_delta.tv_nsec / NSEC_PER_USEC); capture_count--; current_capture++; image_offset += (int)image_byte_size; } error = fpc1020_capture_set_sample_mode(fpc1020, false); if (error) goto out_error; if (mode != FPC1020_MODE_WAIT_FINGER_UP) wake_up_interruptible(&fpc1020->capture.wq_data_avail); if (wait_finger_up) { fpc1020->capture.state = FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_UP; error = fpc1020_capture_finger_detect_settings(fpc1020); if (error < 0) goto out_error; error = fpc1020_capture_wait_finger_up(fpc1020); if(error == -EINTR) { dev_dbg(&fpc1020->spi->dev, "Finger up check interrupted\n"); fpc1020->capture.deferred_finger_up = true; goto out_interrupted; } else if (error < 0) goto out_error; if (mode == FPC1020_MODE_WAIT_FINGER_UP) { fpc1020->capture.available_bytes = 4; fpc1020->huge_buffer[0] = 'F'; fpc1020->huge_buffer[1] = ':'; fpc1020->huge_buffer[2] = 'U'; fpc1020->huge_buffer[3] = 'P'; wake_up_interruptible(&fpc1020->capture.wq_data_avail); } dev_dbg(&fpc1020->spi->dev, "Finger up\n"); } out_interrupted: capture_count = 0; time_capture_sum_us = 0; while (current_capture){ current_capture--; dev_dbg(&fpc1020->spi->dev, "Frame #%d acq. time %d+%d=%d (us)\n", capture_count + 1, time_settings_us[capture_count], time_capture_us[capture_count], time_settings_us[capture_count] + time_capture_us[capture_count]); time_capture_sum_us += time_settings_us[capture_count]; time_capture_sum_us += time_capture_us[capture_count]; capture_count++; } fpc1020->diag.last_capture_time = time_capture_sum_us / 1000; dev_dbg(&fpc1020->spi->dev, "Total acq. time %d (us)\n", time_capture_sum_us); out_error: fpc1020->capture.last_error = error; if (error) { fpc1020->capture.state = FPC1020_CAPTURE_STATE_FAILED; dev_err(&fpc1020->spi->dev, "%s %s %d\n", __func__, (error == -EINTR) ? "TERMINATED" : "FAILED", error); } else { fpc1020->capture.state = FPC1020_CAPTURE_STATE_COMPLETED; dev_dbg(&fpc1020->spi->dev, "%s OK\n", __func__); } return error; }
static int read(int **buffer) { int cnt; int len = 0; long sample_interval_us = 0; struct timespec read_timestamp; if (!on_primary_core()) { return 0; } /* Get the start of this sample period. */ getnstimeofday(&read_timestamp); /* * Calculate the sample interval if the previous sample time is valid. * We use tv_sec since it will not be 0. */ if (prev_timestamp.tv_sec != 0) { sample_interval_us = get_duration_us(&prev_timestamp, &read_timestamp); } /* Structure copy. Update the previous timestamp. */ prev_timestamp = read_timestamp; /* * Report the timeline counters (ACTIVITY_START/STOP) */ for (cnt = FIRST_TIMELINE_EVENT; cnt < (FIRST_TIMELINE_EVENT + NUMBER_OF_TIMELINE_EVENTS); cnt++) { mali_counter *counter = &counters[cnt]; if (counter->enabled) { const int index = cnt - FIRST_TIMELINE_EVENT; unsigned int value; /* If the activity is still running, reset its start time to the start of this sample period * to correct the count. Add the time up to the end of the sample onto the count. */ if (timeline_event_starttime[index].tv_sec != 0) { const long event_duration = get_duration_us(&timeline_event_starttime[index], &read_timestamp); timeline_data[index] += event_duration; timeline_event_starttime[index] = read_timestamp; /* Activity is still running. */ } if (sample_interval_us != 0) { /* Convert the counter to a percent-of-sample value */ value = (timeline_data[index] * 100) / sample_interval_us; } else { pr_debug("gator: Mali-T6xx: setting value to zero\n"); value = 0; } /* Clear the counter value ready for the next sample. */ timeline_data[index] = 0; counter_dump[len++] = counter->key; counter_dump[len++] = value; } } /* Report the software counters */ for (cnt = FIRST_SOFTWARE_COUNTER; cnt < (FIRST_SOFTWARE_COUNTER + NUMBER_OF_SOFTWARE_COUNTERS); cnt++) { const mali_counter *counter = &counters[cnt]; if (counter->enabled) { const int index = cnt - FIRST_SOFTWARE_COUNTER; counter_dump[len++] = counter->key; counter_dump[len++] = sw_counter_data[index]; /* Set the value to zero for the next time */ sw_counter_data[index] = 0; } } /* Report the accumulators */ for (cnt = FIRST_ACCUMULATOR; cnt < (FIRST_ACCUMULATOR + NUMBER_OF_ACCUMULATORS); cnt++) { const mali_counter *counter = &counters[cnt]; if (counter->enabled) { const int index = cnt - FIRST_ACCUMULATOR; counter_dump[len++] = counter->key; counter_dump[len++] = accumulators_data[index]; /* Do not zero the accumulator */ } } /* Update the buffer */ if (buffer) { *buffer = (int *)counter_dump; } return len; }