[PATCH v4 06/11] power: supply: max17042_battery: Retry failed MAX17055 initialization
Vincent Cloutier <[email protected]>
| Newsgroups | org.kernel.vger.linux-pm,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Vincent Cloutier <[email protected]> MAX17055 initialization can fail on register I/O. Propagate the ModelCfg Refresh command error and retry MAX17055 failures every 10 seconds so a transient startup error does not become permanent. Report failures for the other gauges without changing their one-shot behavior. Notify consumers whenever initialization succeeds, including on the first attempt. The core registration notification is deferred and can observe -EAGAIN while asynchronous gauge initialization is still running, so a new notification is needed when driver-backed properties become available. Assisted-by: OpenCode:gpt-5.6-sol Signed-off-by: Vincent Cloutier <[email protected]> --- drivers/power/supply/max17042_battery.c | 37 +++++++++++++++++-------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/power/supply/max17042_battery.c b/drivers/power/supply/max17042_battery.c index 9210bdb4d67e..27d881d4324f 100644 --- a/drivers/power/supply/max17042_battery.c +++ b/drivers/power/supply/max17042_battery.c @@ -62,6 +62,8 @@ #define MAX17042_RESISTANCE_LSB 1 / 4096 /* Ω */ #define MAX17042_TEMPERATURE_LSB 1 / 256 /* °C */ +#define MAX17055_INIT_RETRY_DELAY_MS 10000 + struct max17042_chip { struct device *dev; struct regmap *regmap; @@ -847,13 +849,13 @@ static inline void max17042_override_por_values(struct max17042_chip *chip) max17042_override_por(map, MAX17055_ModelCfg, config->model_cfg); } -static void max17055_init_chip(struct max17042_chip *chip) +static int max17055_init_chip(struct max17042_chip *chip) { max17042_override_por_values(chip); - regmap_write_bits(chip->regmap, MAX17055_ModelCfg, - MAX17055_MODELCFG_REFRESH_BIT, - MAX17055_MODELCFG_REFRESH_BIT); + return regmap_write_bits(chip->regmap, MAX17055_ModelCfg, + MAX17055_MODELCFG_REFRESH_BIT, + MAX17055_MODELCFG_REFRESH_BIT); } static int max17042_init_chip(struct max17042_chip *chip) @@ -861,10 +863,13 @@ static int max17042_init_chip(struct max17042_chip *chip) struct regmap *map = chip->regmap; int ret; - if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17055) - max17055_init_chip(chip); - else + if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17055) { + ret = max17055_init_chip(chip); + if (ret) + return ret; + } else { max17042_override_por_values(chip); + } /* After Power up, the MAX17042 requires 500mS in order * to perform signal debouncing and initial SOC reporting @@ -996,16 +1001,26 @@ static void max17042_init_worker(struct work_struct *work) { struct max17042_chip *chip = container_of(to_delayed_work(work), struct max17042_chip, work); - int ret; + int ret = 0; /* Initialize registers according to values from config_data */ - if (chip->enable_por_init && chip->config_data) { + if (chip->enable_por_init && chip->config_data) ret = max17042_init_chip(chip); - if (ret) - return; + + if (ret) { + if (chip->chip_type == MAXIM_DEVICE_TYPE_MAX17055) { + dev_warn_ratelimited(chip->dev, + "initialization failed: %d, retrying\n", ret); + schedule_delayed_work(&chip->work, + msecs_to_jiffies(MAX17055_INIT_RETRY_DELAY_MS)); + } else { + dev_err(chip->dev, "initialization failed: %d\n", ret); + } + return; } WRITE_ONCE(chip->init_complete, true); + power_supply_changed(chip->battery); } #ifdef CONFIG_OF -- 2.55.0