提交 0dd8d6cb 编写于 作者: M Mateusz Jończyk 提交者: Alexandre Belloni

rtc: Check return value from mc146818_get_time()

There are 4 users of mc146818_get_time() and none of them was checking
the return value from this function. Change this.

Print the appropriate warnings in callers of mc146818_get_time() instead
of in the function mc146818_get_time() itself, in order not to add
strings to rtc-mc146818-lib.c, which is kind of a library.

The callers of alpha_rtc_read_time() and cmos_read_time() may use the
contents of (struct rtc_time *) even when the functions return a failure
code. Therefore, set the contents of (struct rtc_time *) to 0x00,
which looks more sensible then 0xff and aligns with the (possibly
stale?) comment in cmos_read_time:

	/*
	 * If pm_trace abused the RTC for storage, set the timespec to 0,
	 * which tells the caller that this RTC value is unusable.
	 */

For consistency, do this in mc146818_get_time().

Note: hpet_rtc_interrupt() may call mc146818_get_time() many times a
second. It is very unlikely, though, that the RTC suddenly stops
working and mc146818_get_time() would consistently fail.

Only compile-tested on alpha.
Signed-off-by: NMateusz Jończyk <mat.jonczyk@o2.pl>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: linux-alpha@vger.kernel.org
Cc: x86@kernel.org
Signed-off-by: NAlexandre Belloni <alexandre.belloni@bootlin.com>
Link: https://lore.kernel.org/r/20211210200131.153887-4-mat.jonczyk@o2.pl
上级 d35786b3
...@@ -80,7 +80,12 @@ init_rtc_epoch(void) ...@@ -80,7 +80,12 @@ init_rtc_epoch(void)
static int static int
alpha_rtc_read_time(struct device *dev, struct rtc_time *tm) alpha_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
mc146818_get_time(tm); int ret = mc146818_get_time(tm);
if (ret < 0) {
dev_err_ratelimited(dev, "unable to read current time\n");
return ret;
}
/* Adjust for non-default epochs. It's easier to depend on the /* Adjust for non-default epochs. It's easier to depend on the
generic __get_rtc_time and adjust the epoch here than create generic __get_rtc_time and adjust the epoch here than create
......
...@@ -1435,8 +1435,12 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) ...@@ -1435,8 +1435,12 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id)
hpet_rtc_timer_reinit(); hpet_rtc_timer_reinit();
memset(&curr_time, 0, sizeof(struct rtc_time)); memset(&curr_time, 0, sizeof(struct rtc_time));
if (hpet_rtc_flags & (RTC_UIE | RTC_AIE)) if (hpet_rtc_flags & (RTC_UIE | RTC_AIE)) {
mc146818_get_time(&curr_time); if (unlikely(mc146818_get_time(&curr_time) < 0)) {
pr_err_ratelimited("unable to read current time from RTC\n");
return IRQ_HANDLED;
}
}
if (hpet_rtc_flags & RTC_UIE && if (hpet_rtc_flags & RTC_UIE &&
curr_time.tm_sec != hpet_prev_update_sec) { curr_time.tm_sec != hpet_prev_update_sec) {
......
...@@ -120,7 +120,11 @@ static unsigned int read_magic_time(void) ...@@ -120,7 +120,11 @@ static unsigned int read_magic_time(void)
struct rtc_time time; struct rtc_time time;
unsigned int val; unsigned int val;
mc146818_get_time(&time); if (mc146818_get_time(&time) < 0) {
pr_err("Unable to read current time from RTC\n");
return 0;
}
pr_info("RTC time: %ptRt, date: %ptRd\n", &time, &time); pr_info("RTC time: %ptRt, date: %ptRd\n", &time, &time);
val = time.tm_year; /* 100 years */ val = time.tm_year; /* 100 years */
if (val > 100) if (val > 100)
......
...@@ -222,6 +222,8 @@ static inline void cmos_write_bank2(unsigned char val, unsigned char addr) ...@@ -222,6 +222,8 @@ static inline void cmos_write_bank2(unsigned char val, unsigned char addr)
static int cmos_read_time(struct device *dev, struct rtc_time *t) static int cmos_read_time(struct device *dev, struct rtc_time *t)
{ {
int ret;
/* /*
* If pm_trace abused the RTC for storage, set the timespec to 0, * If pm_trace abused the RTC for storage, set the timespec to 0,
* which tells the caller that this RTC value is unusable. * which tells the caller that this RTC value is unusable.
...@@ -229,7 +231,12 @@ static int cmos_read_time(struct device *dev, struct rtc_time *t) ...@@ -229,7 +231,12 @@ static int cmos_read_time(struct device *dev, struct rtc_time *t)
if (!pm_trace_rtc_valid()) if (!pm_trace_rtc_valid())
return -EIO; return -EIO;
mc146818_get_time(t); ret = mc146818_get_time(t);
if (ret < 0) {
dev_err_ratelimited(dev, "unable to read current time\n");
return ret;
}
return 0; return 0;
} }
......
...@@ -24,7 +24,7 @@ unsigned int mc146818_get_time(struct rtc_time *time) ...@@ -24,7 +24,7 @@ unsigned int mc146818_get_time(struct rtc_time *time)
/* Ensure that the RTC is accessible. Bit 6 must be 0! */ /* Ensure that the RTC is accessible. Bit 6 must be 0! */
if (WARN_ON_ONCE((CMOS_READ(RTC_VALID) & 0x40) != 0)) { if (WARN_ON_ONCE((CMOS_READ(RTC_VALID) & 0x40) != 0)) {
spin_unlock_irqrestore(&rtc_lock, flags); spin_unlock_irqrestore(&rtc_lock, flags);
memset(time, 0xff, sizeof(*time)); memset(time, 0, sizeof(*time));
return -EIO; return -EIO;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册