Commit d0ab4a4d authored by Uwe Kleine-König's avatar Uwe Kleine-König Committed by Linus Torvalds

rtc/hctosys: only claim the RTC provided the system time if it did

Without this patch /sys/class/rtc/$CONFIG_RTC_HCTOSYS_DEVICE/hctosys
contains a 1 (meaning "This rtc was used to initialize the system clock")
even if reading the time at bootup failed.

Moreover change error handling in rtc_hctosys() to use goto and so reduce
the indention level.
Signed-off-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Cc: Paul Gortmaker <p_gortmaker@yahoo.com>
Acked-by: default avatarAlessandro Zummo <a.zummo@towertech.it>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 019b4d12
...@@ -22,48 +22,57 @@ ...@@ -22,48 +22,57 @@
* the best guess is to add 0.5s. * the best guess is to add 0.5s.
*/ */
int rtc_hctosys_ret = -ENODEV;
static int __init rtc_hctosys(void) static int __init rtc_hctosys(void)
{ {
int err; int err = -ENODEV;
struct rtc_time tm; struct rtc_time tm;
struct timespec tv = {
.tv_nsec = NSEC_PER_SEC >> 1,
};
struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
if (rtc == NULL) { if (rtc == NULL) {
printk("%s: unable to open rtc device (%s)\n", pr_err("%s: unable to open rtc device (%s)\n",
__FILE__, CONFIG_RTC_HCTOSYS_DEVICE); __FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
return -ENODEV; goto err_open;
} }
err = rtc_read_time(rtc, &tm); err = rtc_read_time(rtc, &tm);
if (err == 0) { if (err) {
err = rtc_valid_tm(&tm); dev_err(rtc->dev.parent,
if (err == 0) { "hctosys: unable to read the hardware clock\n");
struct timespec tv; goto err_read;
tv.tv_nsec = NSEC_PER_SEC >> 1; }
rtc_tm_to_time(&tm, &tv.tv_sec); err = rtc_valid_tm(&tm);
if (err) {
dev_err(rtc->dev.parent,
"hctosys: invalid date/time\n");
goto err_invalid;
}
do_settimeofday(&tv); rtc_tm_to_time(&tm, &tv.tv_sec);
dev_info(rtc->dev.parent, do_settimeofday(&tv);
"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);
}
else
dev_err(rtc->dev.parent,
"hctosys: invalid date/time\n");
}
else
dev_err(rtc->dev.parent,
"hctosys: unable to read the hardware clock\n");
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);
err_invalid:
err_read:
rtc_class_close(rtc); rtc_class_close(rtc);
return 0; err_open:
rtc_hctosys_ret = err;
return err;
} }
late_initcall(rtc_hctosys); late_initcall(rtc_hctosys);
...@@ -107,8 +107,9 @@ rtc_sysfs_show_hctosys(struct device *dev, struct device_attribute *attr, ...@@ -107,8 +107,9 @@ rtc_sysfs_show_hctosys(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
#ifdef CONFIG_RTC_HCTOSYS_DEVICE #ifdef CONFIG_RTC_HCTOSYS_DEVICE
if (strcmp(dev_name(&to_rtc_device(dev)->dev), if (rtc_hctosys_ret == 0 &&
CONFIG_RTC_HCTOSYS_DEVICE) == 0) strcmp(dev_name(&to_rtc_device(dev)->dev),
CONFIG_RTC_HCTOSYS_DEVICE) == 0)
return sprintf(buf, "1\n"); return sprintf(buf, "1\n");
else else
#endif #endif
......
...@@ -238,6 +238,12 @@ static inline bool is_leap_year(unsigned int year) ...@@ -238,6 +238,12 @@ static inline bool is_leap_year(unsigned int year)
return (!(year % 4) && (year % 100)) || !(year % 400); return (!(year % 4) && (year % 100)) || !(year % 400);
} }
#ifdef CONFIG_RTC_HCTOSYS
extern int rtc_hctosys_ret;
#else
#define rtc_hctosys_ret -ENODEV
#endif
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _LINUX_RTC_H_ */ #endif /* _LINUX_RTC_H_ */
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