Commit d0ab4a4d5094e5d17b103dc5073529a04f00a469
Committed by
Linus Torvalds
1 parent
019b4d123a
Exists in
master
and in
7 other branches
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 |
include/linux/rtc.h
... | ... | @@ -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_ */ |