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@xxxxxxxxxxxxxx> --- 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 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox