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

Andrey Smirnov andrew.smirnov at gmail.com
Sun Jun 12 16:51:12 PDT 2016


On Tue, Jun 7, 2016 at 1:09 PM, Trent Piepho <tpiepho at kymetacorp.com> wrote:
> 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
Typo?  -----------------------------------------------------------------^

> important things, like booting.
>
> This limits the number of tries to start the clock to three.

This is definitely a good change. Might I suggest a slightly different
implementation? Something to the effect of:

------------------------8<----------------------------------------------------

for (retries = 0; retries < 3; retries++) {
    clock_halted = oscillator_failed = false;

    /* 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;
    }

    /* 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]);
              clock_halted = true;
        }
    } 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]);
            clock_halted = true;
        }
    }

    if (clock_halted) {
          dev_warn(&client->dev,
                           "chip's oscillator is disabled. "
                           "Re-enabling it.\n");
          continue;
    }


     /* 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]);
             oscillator_failed = true;
         }
         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]);
              oscillator_failed = true;
         }
         break;
     default: ;
     }

     if (oscillator_failed) {
          dev_warn(&client->dev,
                           "chip's oscillator failed. "
                           "Clearing and re-reading status.\n");
          continue;
     }

     break;
};

if (oscillator_failed || clock_halted) {
    dev_warn(&client->dev,
                     "RTC's time information is incorrect. "
                     "Please set time\n")
}

if (!retries)
    dev_err(&client->dev,
                 "Failed to start clock, placing in correct once per
day mode!\n");


------------------------>8----------------------------------------------------

Note, however that this would restore original error handling behavior
-- which you changed in 3/5 -- where all registers are re-read after
each type of failure is detected.



More information about the barebox mailing list