]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
rtc: rs5c348: report error when time is invalid
authorAlexandre Belloni <alexandre.belloni@bootlin.com>
Mon, 24 Sep 2018 15:05:09 +0000 (17:05 +0200)
committerAlexandre Belloni <alexandre.belloni@bootlin.com>
Fri, 28 Sep 2018 12:21:03 +0000 (14:21 +0200)
Instead of resetting the RTC to an bogus valid time, let userspace know
that the time is invalid when XSTP is set. Reset XSTP when setting the time
again.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
drivers/rtc/rtc-rs5c348.c

index 7b9c7dc5b309fef186efba1e64c8bf83356a76c2..6582be707bd0f73609c83038afcd92fbc45f5441 100644 (file)
@@ -66,6 +66,17 @@ rs5c348_rtc_set_time(struct device *dev, struct rtc_time *tm)
        u8 txbuf[5+7], *txp;
        int ret;
 
+       ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL2));
+       if (ret < 0)
+               return ret;
+       if (ret & RS5C348_BIT_XSTP) {
+               txbuf[0] = RS5C348_CMD_W(RS5C348_REG_CTL2);
+               txbuf[1] = 0;
+               ret = spi_write_then_read(spi, txbuf, 2, NULL, 0);
+               if (ret < 0)
+                       return ret;
+       }
+
        /* Transfer 5 bytes before writing SEC.  This gives 31us for carry. */
        txp = txbuf;
        txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
@@ -102,6 +113,16 @@ rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm)
        u8 txbuf[5], rxbuf[7];
        int ret;
 
+       ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL2));
+       if (ret < 0)
+               return ret;
+       if (ret & RS5C348_BIT_VDET)
+               dev_warn(&spi->dev, "voltage-low detected.\n");
+       if (ret & RS5C348_BIT_XSTP) {
+               dev_warn(&spi->dev, "oscillator-stop detected.\n");
+               return -EINVAL;
+       }
+
        /* Transfer 5 byte befores reading SEC.  This gives 31us for carry. */
        txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
        txbuf[1] = 0;   /* dummy */
@@ -165,28 +186,6 @@ static int rs5c348_probe(struct spi_device *spi)
        dev_info(&spi->dev, "spiclk %u KHz.\n",
                 (spi->max_speed_hz + 500) / 1000);
 
-       /* turn RTC on if it was not on */
-       ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL2));
-       if (ret < 0)
-               return ret;
-       if (ret & (RS5C348_BIT_XSTP | RS5C348_BIT_VDET)) {
-               u8 buf[2];
-               struct rtc_time tm;
-               if (ret & RS5C348_BIT_VDET)
-                       dev_warn(&spi->dev, "voltage-low detected.\n");
-               if (ret & RS5C348_BIT_XSTP)
-                       dev_warn(&spi->dev, "oscillator-stop detected.\n");
-               rtc_time_to_tm(0, &tm); /* 1970/1/1 */
-               ret = rs5c348_rtc_set_time(&spi->dev, &tm);
-               if (ret < 0)
-                       return ret;
-               buf[0] = RS5C348_CMD_W(RS5C348_REG_CTL2);
-               buf[1] = 0;
-               ret = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0);
-               if (ret < 0)
-                       return ret;
-       }
-
        ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL1));
        if (ret < 0)
                return ret;