aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-ds1307.c
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2019-01-25 15:35:57 +0100
committerAlexandre Belloni <alexandre.belloni@bootlin.com>2019-02-07 20:55:46 +0100
commit501f98266caddd2b76cdf10093105aa2318d1421 (patch)
tree571ef45be792e102fb8e99361d22733277112a24 /drivers/rtc/rtc-ds1307.c
parent3ffd4a2fcf52c1170654c68459fff40773a729ea (diff)
downloadlinux-501f98266caddd2b76cdf10093105aa2318d1421.tar.gz
rtc: ds1307: rx8130: honor Voltage Loss Flag when reading the time
When voltage dropped since the RTC was last set the reported time is not reliable. In this case return an error indicator instead of a bogus time. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Diffstat (limited to 'drivers/rtc/rtc-ds1307.c')
-rw-r--r--drivers/rtc/rtc-ds1307.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 81e20653700d3..974eafda9de4f 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -194,6 +194,20 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
const struct chip_desc *chip = &chips[ds1307->type];
u8 regs[7];
+ if (ds1307->type == rx_8130) {
+ unsigned int regflag;
+ ret = regmap_read(ds1307->regmap, RX8130_REG_FLAG, &regflag);
+ if (ret) {
+ dev_err(dev, "%s error %d\n", "read", ret);
+ return ret;
+ }
+
+ if (regflag & RX8130_REG_FLAG_VLF) {
+ dev_warn_once(dev, "oscillator failed, set time!\n");
+ return -EINVAL;
+ }
+ }
+
/* read the RTC date and time registers all at once */
ret = regmap_bulk_read(ds1307->regmap, chip->offset, regs,
sizeof(regs));
@@ -293,6 +307,17 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
dev_err(dev, "%s error %d\n", "write", result);
return result;
}
+
+ if (ds1307->type == rx_8130) {
+ /* clear Voltage Loss Flag as data is available now */
+ result = regmap_write(ds1307->regmap, RX8130_REG_FLAG,
+ ~(u8)RX8130_REG_FLAG_VLF);
+ if (result) {
+ dev_err(dev, "%s error %d\n", "write", result);
+ return result;
+ }
+ }
+
return 0;
}