Hi, On Mon, Aug 16, 2021 at 01:52:44PM -0300, Bruno Meneguele wrote: > The BQ24735 charger allows the user to set the watchdog timer delay between > two consecutives ChargeCurrent or ChargeVoltage command writes, if the IC > doesn't receive any command before the timeout happens, the charge is turned > off. > > This patch adds the support to the user to change the default/POR value with > four discrete values: > > 0 - disabled > 1 - enabled, 44 sec > 2 - enabled, 88 sec > 3 - enabled, 175 sec (default at POR) > > These are the options supported in the ChargeOptions register bits 13&14. > > Also, this patch make one additional check when poll-interval is set by the > user: if the interval set is greater than the WDT timeout it'll fail during > the probe stage, preventing the user to set non-compatible values between > the two options. > > Signed-off-by: Bruno Meneguele > --- > Changelog: > v3 - check wdt_timeout for the maximum and minimum available values > > drivers/power/supply/bq24735-charger.c | 54 ++++++++++++++++++++++++++ > include/linux/power/bq24735-charger.h | 1 + > 2 files changed, 55 insertions(+) > > diff --git a/drivers/power/supply/bq24735-charger.c b/drivers/power/supply/bq24735-charger.c > index 3ce36d09c017..7e8d0c23df9a 100644 > --- a/drivers/power/supply/bq24735-charger.c > +++ b/drivers/power/supply/bq24735-charger.c > @@ -45,6 +45,8 @@ > /* ChargeOptions bits of interest */ > #define BQ24735_CHARGE_OPT_CHG_DISABLE (1 << 0) > #define BQ24735_CHARGE_OPT_AC_PRESENT (1 << 4) > +#define BQ24735_CHARGE_OPT_WDT_OFFSET 13 > +#define BQ24735_CHARGE_OPT_WDT (3 << BQ24735_CHARGE_OPT_WDT_OFFSET) > > struct bq24735 { > struct power_supply *charger; > @@ -156,6 +158,20 @@ static int bq24735_config_charger(struct bq24735 *charger) > } > } > > + if (pdata->wdt_timeout >= 0 && pdata->wdt_timeout <= 3) { wdt_timeout is unsigned and can't be smaller than 0. > + value = pdata->wdt_timeout; > + > + ret = bq24735_update_word(charger->client, BQ24735_CHARGE_OPT, > + BQ24735_CHARGE_OPT_WDT, > + (value << BQ24735_CHARGE_OPT_WDT_OFFSET)); > + if (ret < 0) { > + dev_err(&charger->client->dev, > + "Failed to write watchdog timer: %d\n", > + ret); > + return ret; > + } > + } > + > return 0; > } > > @@ -347,6 +363,23 @@ static struct bq24735_platform *bq24735_parse_dt_data(struct i2c_client *client) > if (!ret) > pdata->input_current = val; > > + ret = of_property_read_u32(np, "ti,wdt-timeout", &val); > + if (!ret) { > + if (val >= 0 && val <= 3) { wdt_timeout is unsigned and can't be smaller than 0. > + pdata->wdt_timeout = val; > + } else { > + dev_warn(&client->dev, > + "Invalid value for ti,wdt-timeout: %d", > + val); > + } > + } else { > + /* Since 0 is a valid value (disabled), set something > + * greater than the maximum limit accepted from the user to > + * represent the "no change" state. */ > + pdata->wdt_timeout = 4; > + } > + > + > pdata->ext_control = of_property_read_bool(np, "ti,external-control"); > > return pdata; > @@ -476,6 +509,27 @@ static int bq24735_charger_probe(struct i2c_client *client, > return 0; > if (!charger->poll_interval) > return 0; > + if (charger->pdata->wdt_timeout > 0) { > + int wdt_ms; > + > + switch (charger->pdata->wdt_timeout) { > + case 1: > + wdt_ms = 44000; > + break; > + case 2: > + wdt_ms = 88000; > + break; > + case 3: > + wdt_ms = 175000; > + break; > + } wdt_ms is not initialized when wdt_timeout is not 1-3 resulting in undefined behaviour. Also please create constants for the magic numbers, e.g. #define BQ24735_WDT_OFF 0 #define BQ24735_WDT_44_SEC 1 #define BQ24735_WDT_88_SEC 2 #define BQ24735_WDT_175_SEC 3 #define BQ24735_WDT_INVALID 4 and use them throughout the code. -- Sebastian > + > + if (charger->poll_interval > wdt_ms) { > + dev_err(&client->dev, > + "Poll interval greater than WDT timeout\n"); > + return -EINVAL; > + } > + } > > ret = devm_delayed_work_autocancel(&client->dev, &charger->poll, > bq24735_poll); > diff --git a/include/linux/power/bq24735-charger.h b/include/linux/power/bq24735-charger.h > index 321dd009ce66..ce5a030ca111 100644 > --- a/include/linux/power/bq24735-charger.h > +++ b/include/linux/power/bq24735-charger.h > @@ -12,6 +12,7 @@ struct bq24735_platform { > uint32_t charge_current; > uint32_t charge_voltage; > uint32_t input_current; > + uint32_t wdt_timeout; > > const char *name; > > -- > 2.31.1 >