[PATCH 5/5] rtc: ds1307: Limit clock starting retries

Trent Piepho tpiepho at kymetacorp.com
Tue Jun 7 13:09:53 PDT 2016


If the driver detects the clock is stopped, via clock halted control
bit or oscillator stopped status flag, it will try to start the clock
and then reread the control registers and retry the probe process.

It will continue to retry until the clock starts, possibly forever if
the clock crystal is not installed.  While the driver's dogged
determination to start the clock is admirable, at some point you have
to say enough is enough, this clock won't go, and get one with more
important things, like booting.

This limits the number of tries to start the clock to three.

Signed-off-by: Trent Piepho <tpiepho at kymetacorp.com>
---
 drivers/rtc/rtc-ds1307.c | 101 ++++++++++++++++++++++++-----------------------
 1 file changed, 51 insertions(+), 50 deletions(-)

diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index b772ca3..34f24ed 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -365,7 +365,7 @@ static int ds1307_probe(struct device_d *dev)
 	struct ds1307		*ds1307;
 	int			err = -ENODEV;
 	int			tmp;
-	int			fault;
+	int			fault, retries;
 	int			nreg;
 	unsigned char		buf[DS13xx_REG_COUNT];
 	unsigned long driver_data;
@@ -400,60 +400,61 @@ static int ds1307_probe(struct device_d *dev)
 		goto exit;
 	}
 
-read_rtc:
-	/* read RTC registers */
-	tmp = ds1307_read_block_data(client, 0, nreg, buf);
-	if (tmp != nreg) {
-		dev_dbg(&client->dev, "read error %d\n", tmp);
-		err = -EIO;
-		goto exit;
-	}
-
-	/* Check for clock halted conditions and start clock */
-	fault = 0;
-
-	/* clock halted?  turn it on, so clock can tick. */
-	if (ds1307->has_alarms) {
-		if (buf[DS1337_REG_CONTROL] & DS1337_BIT_nEOSC) {
-			buf[DS1337_REG_CONTROL] &= ~DS1337_BIT_nEOSC;
-			i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL,
-						  buf[DS1337_REG_CONTROL]);
-			fault = 1;
-		}
-	} else {
-		if (buf[DS1307_REG_SECS] & DS1307_BIT_CH) {
-			buf[DS1307_REG_SECS] = 0;
-			i2c_smbus_write_byte_data(client, DS1307_REG_SECS,
-			                          buf[DS1307_REG_SECS]);
-			fault = 1;
+	retries = 3;
+	do {
+		/* read RTC registers */
+		tmp = ds1307_read_block_data(client, 0, nreg, buf);
+		if (tmp != nreg) {
+			dev_dbg(&client->dev, "read error %d\n", tmp);
+			err = -EIO;
+			goto exit;
 		}
-	}
 
-	/* Oscillator fault?  clear flag and print warning */
-	switch (ds1307->osf) {
-	case OSF_1338:
-		if (buf[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
-			buf[DS1307_REG_CONTROL] &= ~DS1338_BIT_OSF;
-			i2c_smbus_write_byte_data(client, DS1307_REG_CONTROL,
-				                  buf[DS1307_REG_CONTROL]);
-			fault = 1;
+		fault = 0;
+		/* clock halted?  turn it on, so clock can tick. */
+		if (ds1307->has_alarms) {
+			if (buf[DS1337_REG_CONTROL] & DS1337_BIT_nEOSC) {
+				buf[DS1337_REG_CONTROL] &= ~DS1337_BIT_nEOSC;
+				i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL,
+							  buf[DS1337_REG_CONTROL]);
+				fault = 1;
+			}
+		} else {
+			if (buf[DS1307_REG_SECS] & DS1307_BIT_CH) {
+				buf[DS1307_REG_SECS] = 0;
+				i2c_smbus_write_byte_data(client, DS1307_REG_SECS,
+							  buf[DS1307_REG_SECS]);
+				fault = 1;
+			}
 		}
-		break;
-	case OSF_1337:
-		if (buf[DS1337_REG_STATUS] & DS1337_BIT_OSF) {
-			buf[DS1337_REG_STATUS] &= ~DS1337_BIT_OSF;
-			i2c_smbus_write_byte_data(client, DS1337_REG_STATUS,
-				                  buf[DS1337_REG_STATUS]);
-			fault = 1;
+
+		/* Oscillator fault?  clear flag and print warning */
+		switch (ds1307->osf) {
+		case OSF_1338:
+			if (buf[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
+				buf[DS1307_REG_CONTROL] &= ~DS1338_BIT_OSF;
+				i2c_smbus_write_byte_data(client, DS1307_REG_CONTROL,
+							  buf[DS1307_REG_CONTROL]);
+				fault = 1;
+			}
+			break;
+		case OSF_1337:
+			if (buf[DS1337_REG_STATUS] & DS1337_BIT_OSF) {
+				buf[DS1337_REG_STATUS] &= ~DS1337_BIT_OSF;
+				i2c_smbus_write_byte_data(client, DS1337_REG_STATUS,
+							  buf[DS1337_REG_STATUS]);
+				fault = 1;
+			}
+			break;
+		default: ;
 		}
-		break;
-	default: ;
-	}
 
-	if (fault) {
-		dev_warn(&client->dev, "SET TIME!\n");
-		goto read_rtc;
-	}
+		if (fault)
+			dev_warn(&client->dev, "SET TIME!\n");
+	} while (fault && retries--);
+
+	if (fault)
+		dev_err(&client->dev, "Failed to start clock, placing in correct once per day mode!\n");
 
 	/* Configure clock using OF data if available */
 	if (IS_ENABLED(CONFIG_OFDEVICE) && np) {
-- 
2.7.0.25.gfc10eb5.dirty




More information about the barebox mailing list