[PATCH v2 11/17] RTC: ds1307: Convert goto to a loop

From: Andrey Smirnov
Date: Tue Jun 21 2016 - 03:25:22 EST


Convert goto to a loop and set a hard upper limit on the number of times
driver would try to make RTC work (as opposed to having an infinite
retry loop).

Signed-off-by: Andrey Smirnov <andrew.smirnov@xxxxxxxxx>
---
drivers/rtc/rtc-ds1307.c | 151 +++++++++++++++++++++++++----------------------
1 file changed, 82 insertions(+), 69 deletions(-)

diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 67907f1..cbbe9f0 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -1424,87 +1424,100 @@ static int ds1307_chip_configure(const struct ds1307 *ds1307)

static int ds1307_chip_sanity_check(const struct ds1307 *ds1307)
{
- int tmp;
+ int tmp, retries;
u8 regs[DS1307_REG_COUNT];
struct i2c_client *client = ds1307->client;

-read_rtc:
- /* read RTC registers */
- tmp = ds1307->read_block_data(ds1307->client, ds1307->offset, 8, regs);
- if (tmp != 8) {
- dev_dbg(&client->dev, "read error %d\n", tmp);
- return -EIO;
- }
-
- /*
- * minimal sanity checking; some chips (like DS1340) don't
- * specify the extra bits as must-be-zero, but there are
- * still a few values that are clearly out-of-range.
- */
- tmp = regs[DS1307_REG_SECS];
- switch (ds1307->type) {
- case ds_1307:
- case m41t00:
- /* clock halted? turn it on, so clock can tick. */
- if (tmp & DS1307_BIT_CH) {
- i2c_smbus_write_byte_data(client, DS1307_REG_SECS, 0);
- dev_warn(&client->dev, "SET TIME!\n");
- goto read_rtc;
- }
- break;
- case ds_1338:
- /* clock halted? turn it on, so clock can tick. */
- if (tmp & DS1307_BIT_CH)
- i2c_smbus_write_byte_data(client, DS1307_REG_SECS, 0);
-
- /* oscillator fault? clear flag, and warn */
- if (regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
- i2c_smbus_write_byte_data(client, DS1307_REG_CONTROL,
- regs[DS1307_REG_CONTROL]
- & ~DS1338_BIT_OSF);
- dev_warn(&client->dev, "SET TIME!\n");
- goto read_rtc;
- }
- break;
- case ds_1340:
- /* clock halted? turn it on, so clock can tick. */
- if (tmp & DS1340_BIT_nEOSC)
- i2c_smbus_write_byte_data(client, DS1307_REG_SECS, 0);
-
- tmp = i2c_smbus_read_byte_data(client, DS1340_REG_FLAG);
- if (tmp < 0) {
+ for (retries = 0; retries < 5; retries++) {
+ /* read RTC registers */
+ tmp = ds1307->read_block_data(ds1307->client,
+ ds1307->offset, 8, regs);
+ if (tmp != 8) {
dev_dbg(&client->dev, "read error %d\n", tmp);
return -EIO;
}

- /* oscillator fault? clear flag, and warn */
- if (tmp & DS1340_BIT_OSF) {
- i2c_smbus_write_byte_data(client, DS1340_REG_FLAG, 0);
- dev_warn(&client->dev, "SET TIME!\n");
- }
- break;
- case mcp794xx:
- /* make sure that the backup battery is enabled */
- if (!(regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) {
- i2c_smbus_write_byte_data(client, DS1307_REG_WDAY,
- regs[DS1307_REG_WDAY]
- | MCP794XX_BIT_VBATEN);
- }
+ /*
+ * minimal sanity checking; some chips (like DS1340)
+ * don't specify the extra bits as must-be-zero, but
+ * there are still a few values that are clearly
+ * out-of-range.
+ */
+ tmp = regs[DS1307_REG_SECS];
+ switch (ds1307->type) {
+ case ds_1307:
+ case m41t00:
+ /* clock halted? turn it on, so clock can tick. */
+ if (tmp & DS1307_BIT_CH) {
+ i2c_smbus_write_byte_data(client,
+ DS1307_REG_SECS, 0);
+ dev_warn(&client->dev, "SET TIME!\n");
+ continue;
+ }
+ break;
+ case ds_1338:
+ /* clock halted? turn it on, so clock can tick. */
+ if (tmp & DS1307_BIT_CH)
+ i2c_smbus_write_byte_data(client,
+ DS1307_REG_SECS, 0);
+
+ /* oscillator fault? clear flag, and warn */
+ if (regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
+ i2c_smbus_write_byte_data(client,
+ DS1307_REG_CONTROL,
+ regs[DS1307_REG_CONTROL]
+ & ~DS1338_BIT_OSF);
+ dev_warn(&client->dev, "SET TIME!\n");
+ continue;
+ }
+ break;
+ case ds_1340:
+ /* clock halted? turn it on, so clock can tick. */
+ if (tmp & DS1340_BIT_nEOSC)
+ i2c_smbus_write_byte_data(client,
+ DS1307_REG_SECS, 0);
+
+ tmp = i2c_smbus_read_byte_data(client, DS1340_REG_FLAG);
+ if (tmp < 0) {
+ dev_dbg(&client->dev, "read error %d\n", tmp);
+ return -EIO;
+ }
+
+ /* oscillator fault? clear flag, and warn */
+ if (tmp & DS1340_BIT_OSF) {
+ i2c_smbus_write_byte_data(client,
+ DS1340_REG_FLAG, 0);
+ dev_warn(&client->dev, "SET TIME!\n");
+ }
+ return 0;

- /* clock halted? turn it on, so clock can tick. */
- if (!(tmp & MCP794XX_BIT_ST)) {
- i2c_smbus_write_byte_data(client, DS1307_REG_SECS,
- MCP794XX_BIT_ST);
- dev_warn(&client->dev, "SET TIME!\n");
- goto read_rtc;
+ case mcp794xx:
+ /* make sure that the backup battery is enabled */
+ if (!(regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) {
+ i2c_smbus_write_byte_data(client,
+ DS1307_REG_WDAY,
+ regs[DS1307_REG_WDAY]
+ | MCP794XX_BIT_VBATEN);
+ }
+
+ /* clock halted? turn it on, so clock can tick. */
+ if (!(tmp & MCP794XX_BIT_ST)) {
+ i2c_smbus_write_byte_data(client,
+ DS1307_REG_SECS,
+ MCP794XX_BIT_ST);
+ dev_warn(&client->dev, "SET TIME!\n");
+ continue;
+ }
+
+ break;
+ default:
+ break;
}

- break;
- default:
- break;
+ return 0;
}

- return 0;
+ return -EIO;
}

static int ds1307_probe(struct i2c_client *client,
--
2.5.5