Commit d0ab4a4d5094e5d17b103dc5073529a04f00a469

Authored by Uwe Kleine-König
Committed by Linus Torvalds
1 parent 019b4d123a

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: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Cc: Paul Gortmaker <p_gortmaker@yahoo.com>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 3 changed files with 43 additions and 27 deletions Side-by-side Diff

drivers/rtc/hctosys.c
... ... @@ -22,48 +22,57 @@
22 22 * the best guess is to add 0.5s.
23 23 */
24 24  
  25 +int rtc_hctosys_ret = -ENODEV;
  26 +
25 27 static int __init rtc_hctosys(void)
26 28 {
27   - int err;
  29 + int err = -ENODEV;
28 30 struct rtc_time tm;
  31 + struct timespec tv = {
  32 + .tv_nsec = NSEC_PER_SEC >> 1,
  33 + };
29 34 struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
30 35  
31 36 if (rtc == NULL) {
32   - printk("%s: unable to open rtc device (%s)\n",
  37 + pr_err("%s: unable to open rtc device (%s)\n",
33 38 __FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
34   - return -ENODEV;
  39 + goto err_open;
35 40 }
36 41  
37 42 err = rtc_read_time(rtc, &tm);
38   - if (err == 0) {
39   - err = rtc_valid_tm(&tm);
40   - if (err == 0) {
41   - struct timespec tv;
  43 + if (err) {
  44 + dev_err(rtc->dev.parent,
  45 + "hctosys: unable to read the hardware clock\n");
  46 + goto err_read;
42 47  
43   - tv.tv_nsec = NSEC_PER_SEC >> 1;
  48 + }
44 49  
45   - rtc_tm_to_time(&tm, &tv.tv_sec);
  50 + err = rtc_valid_tm(&tm);
  51 + if (err) {
  52 + dev_err(rtc->dev.parent,
  53 + "hctosys: invalid date/time\n");
  54 + goto err_invalid;
  55 + }
46 56  
47   - do_settimeofday(&tv);
  57 + rtc_tm_to_time(&tm, &tv.tv_sec);
48 58  
49   - dev_info(rtc->dev.parent,
50   - "setting system clock to "
51   - "%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n",
52   - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
53   - tm.tm_hour, tm.tm_min, tm.tm_sec,
54   - (unsigned int) tv.tv_sec);
55   - }
56   - else
57   - dev_err(rtc->dev.parent,
58   - "hctosys: invalid date/time\n");
59   - }
60   - else
61   - dev_err(rtc->dev.parent,
62   - "hctosys: unable to read the hardware clock\n");
  59 + do_settimeofday(&tv);
63 60  
  61 + dev_info(rtc->dev.parent,
  62 + "setting system clock to "
  63 + "%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n",
  64 + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
  65 + tm.tm_hour, tm.tm_min, tm.tm_sec,
  66 + (unsigned int) tv.tv_sec);
  67 +
  68 +err_invalid:
  69 +err_read:
64 70 rtc_class_close(rtc);
65 71  
66   - return 0;
  72 +err_open:
  73 + rtc_hctosys_ret = err;
  74 +
  75 + return err;
67 76 }
68 77  
69 78 late_initcall(rtc_hctosys);
drivers/rtc/rtc-sysfs.c
... ... @@ -107,8 +107,9 @@
107 107 char *buf)
108 108 {
109 109 #ifdef CONFIG_RTC_HCTOSYS_DEVICE
110   - if (strcmp(dev_name(&to_rtc_device(dev)->dev),
111   - CONFIG_RTC_HCTOSYS_DEVICE) == 0)
  110 + if (rtc_hctosys_ret == 0 &&
  111 + strcmp(dev_name(&to_rtc_device(dev)->dev),
  112 + CONFIG_RTC_HCTOSYS_DEVICE) == 0)
112 113 return sprintf(buf, "1\n");
113 114 else
114 115 #endif
... ... @@ -238,6 +238,12 @@
238 238 return (!(year % 4) && (year % 100)) || !(year % 400);
239 239 }
240 240  
  241 +#ifdef CONFIG_RTC_HCTOSYS
  242 +extern int rtc_hctosys_ret;
  243 +#else
  244 +#define rtc_hctosys_ret -ENODEV
  245 +#endif
  246 +
241 247 #endif /* __KERNEL__ */
242 248  
243 249 #endif /* _LINUX_RTC_H_ */