lkml.org 
[lkml]   [2016]   [Jun]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 11/17] RTC: ds1307: Convert goto to a loop
    Date
    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@gmail.com>
    ---
    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
    \
     
     \ /
      Last update: 2016-06-21 10:01    [W:4.225 / U:0.424 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site