Commit 95fc3f38 authored by Russell King's avatar Russell King

[ARM] rtctime tweaks

- if alarm operations are NULL, don't allow alarm ioctls to succeed.
- if ops->ioctl is NULL, don't try to call NULL function.
- only display the alarm times in /proc/rtc if we successfully read
  the alarm time.
parent e0fb7100
...@@ -147,15 +147,23 @@ static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm) ...@@ -147,15 +147,23 @@ static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm)
return ops->set_time(tm); return ops->set_time(tm);
} }
static inline void rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) static inline int rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
{ {
int ret = -EINVAL;
if (ops->read_alarm) {
memset(alrm, 0, sizeof(struct rtc_wkalrm)); memset(alrm, 0, sizeof(struct rtc_wkalrm));
ops->read_alarm(alrm); ops->read_alarm(alrm);
ret = 0;
}
return ret;
} }
static inline int rtc_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm) static inline int rtc_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
{ {
return ops->set_alarm(alrm); int ret = -EINVAL;
if (ops->set_alarm)
ret = ops->set_alarm(alrm);
return ret;
} }
void rtc_update(unsigned long num, unsigned long events) void rtc_update(unsigned long num, unsigned long events)
...@@ -233,11 +241,13 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -233,11 +241,13 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
struct rtc_ops *ops = file->private_data; struct rtc_ops *ops = file->private_data;
struct rtc_time tm; struct rtc_time tm;
struct rtc_wkalrm alrm; struct rtc_wkalrm alrm;
int ret; int ret = -EINVAL;
switch (cmd) { switch (cmd) {
case RTC_ALM_READ: case RTC_ALM_READ:
rtc_read_alarm(ops, &alrm); ret = rtc_read_alarm(ops, &alrm);
if (ret)
break;
ret = copy_to_user((void *)arg, &alrm.time, sizeof(tm)); ret = copy_to_user((void *)arg, &alrm.time, sizeof(tm));
if (ret) if (ret)
ret = -EFAULT; ret = -EFAULT;
...@@ -245,6 +255,10 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -245,6 +255,10 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case RTC_ALM_SET: case RTC_ALM_SET:
ret = copy_from_user(&alrm.time, (void *)arg, sizeof(tm)); ret = copy_from_user(&alrm.time, (void *)arg, sizeof(tm));
if (ret) {
ret = -EFAULT;
break;
}
alrm.enabled = 0; alrm.enabled = 0;
alrm.pending = 0; alrm.pending = 0;
alrm.time.tm_mday = -1; alrm.time.tm_mday = -1;
...@@ -253,10 +267,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -253,10 +267,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
alrm.time.tm_wday = -1; alrm.time.tm_wday = -1;
alrm.time.tm_yday = -1; alrm.time.tm_yday = -1;
alrm.time.tm_isdst = -1; alrm.time.tm_isdst = -1;
if (ret == 0)
ret = rtc_set_alarm(ops, &alrm); ret = rtc_set_alarm(ops, &alrm);
else
ret = -EFAULT;
break; break;
case RTC_RD_TIME: case RTC_RD_TIME:
...@@ -278,8 +289,8 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -278,8 +289,8 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
ret = -EFAULT; ret = -EFAULT;
break; break;
#ifndef rtc_epoch
case RTC_EPOCH_SET: case RTC_EPOCH_SET:
#ifndef rtc_epoch
/* /*
* There were no RTC clocks before 1900. * There were no RTC clocks before 1900.
*/ */
...@@ -293,8 +304,8 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -293,8 +304,8 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
} }
rtc_epoch = arg; rtc_epoch = arg;
ret = 0; ret = 0;
break;
#endif #endif
break;
case RTC_EPOCH_READ: case RTC_EPOCH_READ:
ret = put_user(rtc_epoch, (unsigned long *)arg); ret = put_user(rtc_epoch, (unsigned long *)arg);
...@@ -302,21 +313,26 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -302,21 +313,26 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case RTC_WKALM_SET: case RTC_WKALM_SET:
ret = copy_from_user(&alrm, (void *)arg, sizeof(alrm)); ret = copy_from_user(&alrm, (void *)arg, sizeof(alrm));
if (ret == 0) if (ret) {
ret = rtc_set_alarm(ops, &alrm);
else
ret = -EFAULT; ret = -EFAULT;
break; break;
}
ret = rtc_set_alarm(ops, &alrm);
break;
case RTC_WKALM_RD: case RTC_WKALM_RD:
rtc_read_alarm(ops, &alrm); ret = rtc_read_alarm(ops, &alrm);
if (ret)
break;
ret = copy_to_user((void *)arg, &alrm, sizeof(alrm)); ret = copy_to_user((void *)arg, &alrm, sizeof(alrm));
if (ret) if (ret)
ret = -EFAULT; ret = -EFAULT;
break; break;
default: default:
if (ops->ioctl)
ret = ops->ioctl(cmd, arg); ret = ops->ioctl(cmd, arg);
break;
} }
return ret; return ret;
} }
...@@ -406,7 +422,7 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo ...@@ -406,7 +422,7 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
rtc_epoch); rtc_epoch);
rtc_read_alarm(ops, &alrm); if (rtc_read_alarm(ops, &alrm) == 0) {
p += sprintf(p, "alrm_time\t: "); p += sprintf(p, "alrm_time\t: ");
if ((unsigned int)alrm.time.tm_hour <= 24) if ((unsigned int)alrm.time.tm_hour <= 24)
p += sprintf(p, "%02d:", alrm.time.tm_hour); p += sprintf(p, "%02d:", alrm.time.tm_hour);
...@@ -434,8 +450,11 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo ...@@ -434,8 +450,11 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo
p += sprintf(p, "%02d\n", alrm.time.tm_mday); p += sprintf(p, "%02d\n", alrm.time.tm_mday);
else else
p += sprintf(p, "**\n"); p += sprintf(p, "**\n");
p += sprintf(p, "alrm_wakeup\t: %s\n", alrm.enabled ? "yes" : "no"); p += sprintf(p, "alrm_wakeup\t: %s\n",
p += sprintf(p, "alrm_pending\t: %s\n", alrm.pending ? "yes" : "no"); alrm.enabled ? "yes" : "no");
p += sprintf(p, "alrm_pending\t: %s\n",
alrm.pending ? "yes" : "no");
}
if (ops->proc) if (ops->proc)
p += ops->proc(p); p += ops->proc(p);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment