]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
rtc-add-nxp-pcf8523-support-v2
authorThierry Reding <thierry.reding@avionic-design.de>
Thu, 29 Nov 2012 03:18:47 +0000 (14:18 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Wed, 5 Dec 2012 05:23:41 +0000 (16:23 +1100)
Changes in v2:
- return an error if the OS flag cannot be cleared
- add comment as to why we clear the OS flag
- restart RTC if setting the time fails

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
drivers/rtc/rtc-pcf8523.c

index b29ea6dbdc628ad371d63444bf6e97e86859b548..be05a645f99e985ebea76a9a9903ffdead17fb4c 100644 (file)
@@ -178,14 +178,26 @@ static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm)
                return err;
 
        if (regs[0] & REG_SECONDS_OS) {
-               dev_dbg(dev, "clock integrity is not guaranteed\n");
+               /*
+                * If the oscillator was stopped, try to clear the flag. Upon
+                * power-up the flag is always set, but if we cannot clear it
+                * the oscillator isn't running properly for some reason. The
+                * sensible thing therefore is to return an error, signalling
+                * that the clock cannot be assumed to be correct.
+                */
 
-               /* try to clear the flag */
                regs[0] &= ~REG_SECONDS_OS;
 
                err = pcf8523_write(client, REG_SECONDS, regs[0]);
                if (err < 0)
                        return err;
+
+               err = pcf8523_read(client, REG_SECONDS, &regs[0]);
+               if (err < 0)
+                       return err;
+
+               if (regs[0] & REG_SECONDS_OS)
+                       return -EAGAIN;
        }
 
        tm->tm_sec = bcd2bin(regs[0] & 0x7f);
@@ -225,8 +237,15 @@ static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm)
        msg.buf = regs;
 
        err = i2c_transfer(client->adapter, &msg, 1);
-       if (err < 0)
+       if (err < 0) {
+               /*
+                * If the time cannot be set, restart the RTC anyway. Note
+                * that errors are ignored if the RTC cannot be started so
+                * that we have a chance to propagate the original error.
+                */
+               pcf8523_start_rtc(client);
                return err;
+       }
 
        return pcf8523_start_rtc(client);
 }