/*
* rtc_lock protects rtc_irq_data
*/
-static spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rtc_lock);
static unsigned long rtc_irq_data;
/*
EXPORT_SYMBOL(rtc_time_to_tm);
/*
- * Convert Gregorian date to seconds since 01-01-1970 00:00:00.
+ * Does the rtc_time represent a valid date/time?
*/
-int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
+int rtc_valid_tm(struct rtc_time *tm)
{
- unsigned int yrs = tm->tm_year + 1900;
-
- *time = 0;
-
- if (yrs < 1970 ||
+ if (tm->tm_year < 70 ||
tm->tm_mon >= 12 ||
tm->tm_mday < 1 ||
- tm->tm_mday > month_days(tm->tm_mon, yrs) ||
+ tm->tm_mday > month_days(tm->tm_mon, tm->tm_year + 1900) ||
tm->tm_hour >= 24 ||
tm->tm_min >= 60 ||
tm->tm_sec >= 60)
return -EINVAL;
- *time = mktime(yrs, tm->tm_mon + 1, tm->tm_mday,
+ return 0;
+}
+EXPORT_SYMBOL(rtc_valid_tm);
+
+/*
+ * Convert Gregorian date to seconds since 01-01-1970 00:00:00.
+ */
+int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
+{
+ *time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
return 0;
next->tm_sec = alrm->tm_sec;
}
-static inline void rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm)
+static inline int rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm)
{
memset(tm, 0, sizeof(struct rtc_time));
- ops->read_time(tm);
+ return ops->read_time(tm);
}
static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm)
{
- return ops->set_time(tm);
+ int ret;
+
+ ret = rtc_valid_tm(tm);
+ if (ret == 0)
+ ret = ops->set_time(tm);
+
+ return ret;
}
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));
- ops->read_alarm(alrm);
- ret = 0;
+ ret = ops->read_alarm(alrm);
}
return ret;
}
break;
case RTC_RD_TIME:
- rtc_read_time(ops, &tm);
+ ret = rtc_read_time(ops, &tm);
+ if (ret)
+ break;
ret = copy_to_user(uarg, &tm, sizeof(tm));
if (ret)
ret = -EFAULT;
struct rtc_wkalrm alrm;
struct rtc_time tm;
char *p = page;
- int len;
-
- rtc_read_time(ops, &tm);
- p += sprintf(p,
- "rtc_time\t: %02d:%02d:%02d\n"
- "rtc_date\t: %04d-%02d-%02d\n"
- "rtc_epoch\t: %04lu\n",
- tm.tm_hour, tm.tm_min, tm.tm_sec,
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
- rtc_epoch);
+ if (rtc_read_time(ops, &tm) == 0) {
+ p += sprintf(p,
+ "rtc_time\t: %02d:%02d:%02d\n"
+ "rtc_date\t: %04d-%02d-%02d\n"
+ "rtc_epoch\t: %04lu\n",
+ tm.tm_hour, tm.tm_min, tm.tm_sec,
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+ rtc_epoch);
+ }
if (rtc_read_alarm(ops, &alrm) == 0) {
p += sprintf(p, "alrm_time\t: ");
if (ops->proc)
p += ops->proc(p);
- len = (p - page) - off;
- if (len < 0)
- len = 0;
- *eof = len <= count;
- *start = page + off;
-
- return len;
+ return p - page;
}
int register_rtc(struct rtc_ops *ops)