static int gen_rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct rtc_time wtime; struct rtc_pll_info pll; switch (cmd) { case RTC_PLL_GET: if (get_rtc_pll(&pll)) return -EINVAL; else return copy_to_user((void *)arg, &pll, sizeof pll) ? -EFAULT : 0; case RTC_PLL_SET: if (!capable(CAP_SYS_TIME)) return -EACCES; if (copy_from_user(&pll, (struct rtc_pll_info*)arg, sizeof(pll))) return -EFAULT; return set_rtc_pll(&pll); case RTC_UIE_OFF: /* disable ints from RTC updates. */ gen_clear_rtc_irq_bit(RTC_UIE); return 0; case RTC_UIE_ON: /* enable ints for RTC updates. */ return gen_set_rtc_irq_bit(RTC_UIE); case RTC_RD_TIME: /* Read the time/date from RTC */ /* this doesn't get week-day, who cares */ memset(&wtime, 0, sizeof(wtime)); get_rtc_time(&wtime); return copy_to_user((void *)arg, &wtime, sizeof(wtime)) ? -EFAULT : 0; case RTC_SET_TIME: /* Set the RTC */ { int year; unsigned char leap_yr; if (!capable(CAP_SYS_TIME)) return -EACCES; if (copy_from_user(&wtime, (struct rtc_time *)arg, sizeof(wtime))) return -EFAULT; year = wtime.tm_year + 1900; leap_yr = ((!(year % 4) && (year % 100)) || !(year % 400)); if ((wtime.tm_mon < 0 || wtime.tm_mon > 11) || (wtime.tm_mday < 1)) return -EINVAL; if (wtime.tm_mday < 0 || wtime.tm_mday > (days_in_mo[wtime.tm_mon] + ((wtime.tm_mon == 1) && leap_yr))) return -EINVAL; if (wtime.tm_hour < 0 || wtime.tm_hour >= 24 || wtime.tm_min < 0 || wtime.tm_min >= 60 || wtime.tm_sec < 0 || wtime.tm_sec >= 60) return -EINVAL; return set_rtc_time(&wtime); } } return -EINVAL; }
static int gen_rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct rtc_time wtime; struct rtc_pll_info pll; void __user *argp = (void __user *)arg; switch (cmd) { #ifdef CONFIG_REALTEK_VENUS case RTC_ALM_READ: /* Read the present alarm time */ { /* * This returns a struct rtc_time. Reading >= 0xc0 * means "don't care" or "match all". Only the tm_hour, * tm_min, and tm_sec values are filled in. */ memset(&wtime, 0, sizeof(wtime)); get_rtc_alarm_time(&wtime); return copy_to_user(argp, &wtime, sizeof(wtime)) ? -EFAULT : 0; } case RTC_ALM_SET: /* Store a time into the alarm */ { int year; unsigned char leap_yr; if (copy_from_user(&wtime, argp, sizeof(wtime))) return -EFAULT; year = wtime.tm_year + 1900; leap_yr = ((!(year % 4) && (year % 100)) || !(year % 400)); if ((wtime.tm_mon < 0 || wtime.tm_mon > 11) || (wtime.tm_mday < 1)) return -EINVAL; if (wtime.tm_mday < 0 || wtime.tm_mday > (days_in_mo[wtime.tm_mon] + ((wtime.tm_mon == 1) && leap_yr))) return -EINVAL; if (wtime.tm_hour < 0 || wtime.tm_hour >= 24 || wtime.tm_min < 0 || wtime.tm_min >= 60 || wtime.tm_sec < 0 || wtime.tm_sec >= 60) return -EINVAL; return set_rtc_alarm_time(&wtime); } #endif case RTC_PLL_GET: if (get_rtc_pll(&pll)) return -EINVAL; else return copy_to_user(argp, &pll, sizeof pll) ? -EFAULT : 0; case RTC_PLL_SET: if (!capable(CAP_SYS_TIME)) return -EACCES; if (copy_from_user(&pll, argp, sizeof(pll))) return -EFAULT; return set_rtc_pll(&pll); case RTC_UIE_OFF: /* disable ints from RTC updates. */ gen_clear_rtc_irq_bit(RTC_UIE); return 0; case RTC_UIE_ON: /* enable ints for RTC updates. */ return gen_set_rtc_irq_bit(RTC_UIE); case RTC_RD_TIME: /* Read the time/date from RTC */ /* this doesn't get week-day, who cares */ memset(&wtime, 0, sizeof(wtime)); get_rtc_time(&wtime); return copy_to_user(argp, &wtime, sizeof(wtime)) ? -EFAULT : 0; case RTC_SET_TIME: /* Set the RTC */ { int year; unsigned char leap_yr; if (!capable(CAP_SYS_TIME)) return -EACCES; if (copy_from_user(&wtime, argp, sizeof(wtime))) return -EFAULT; year = wtime.tm_year + 1900; leap_yr = ((!(year % 4) && (year % 100)) || !(year % 400)); if ((wtime.tm_mon < 0 || wtime.tm_mon > 11) || (wtime.tm_mday < 1)) return -EINVAL; if (wtime.tm_mday < 0 || wtime.tm_mday > (days_in_mo[wtime.tm_mon] + ((wtime.tm_mon == 1) && leap_yr))) return -EINVAL; if (wtime.tm_hour < 0 || wtime.tm_hour >= 24 || wtime.tm_min < 0 || wtime.tm_min >= 60 || wtime.tm_sec < 0 || wtime.tm_sec >= 60) return -EINVAL; return set_rtc_time(&wtime); } } return -EINVAL; }