Skip to content

Commit 5ef4d5e

Browse files
Phil Elwellpopcornmix
Phil Elwell
authored andcommitted
rtc: pcf8523: Fix oscillator stop bit handling
See: raspberrypi/firmware#1065 Signed-off-by: Phil Elwell <[email protected]>
1 parent f82b5a7 commit 5ef4d5e

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

drivers/rtc/rtc-pcf8523.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm)
100100
{
101101
struct pcf8523 *pcf8523 = dev_get_drvdata(dev);
102102
u8 regs[10];
103+
u32 value;
103104
int err;
104105

105106
err = regmap_bulk_read(pcf8523->regmap, PCF8523_REG_CONTROL1, regs,
@@ -110,6 +111,33 @@ static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm)
110111
if ((regs[0] & PCF8523_CONTROL1_STOP) || (regs[3] & PCF8523_SECONDS_OS))
111112
return -EINVAL;
112113

114+
if (regs[0] & PCF8523_SECONDS_OS) {
115+
/*
116+
* If the oscillator was stopped, try to clear the flag. Upon
117+
* power-up the flag is always set, but if we cannot clear it
118+
* the oscillator isn't running properly for some reason. The
119+
* sensible thing therefore is to return an error, signalling
120+
* that the clock cannot be assumed to be correct.
121+
*/
122+
123+
regs[0] &= ~PCF8523_SECONDS_OS;
124+
125+
err = regmap_write(pcf8523->regmap, PCF8523_REG_SECONDS,
126+
regs[0]);
127+
if (err < 0)
128+
return err;
129+
130+
err = regmap_read(pcf8523->regmap, PCF8523_REG_SECONDS,
131+
&value);
132+
if (err < 0)
133+
return err;
134+
135+
if (value & PCF8523_SECONDS_OS)
136+
return -EAGAIN;
137+
138+
regs[0] = value;
139+
}
140+
113141
tm->tm_sec = bcd2bin(regs[3] & 0x7f);
114142
tm->tm_min = bcd2bin(regs[4] & 0x7f);
115143
tm->tm_hour = bcd2bin(regs[5] & 0x3f);

0 commit comments

Comments
 (0)