diff options
| author | Vincent Cloutier <vincent@cloutier.co> | 2026-07-26 21:13:04 -0400 |
|---|---|---|
| committer | Sebastian Reichel <sebastian.reichel@collabora.com> | 2026-07-27 20:32:38 +0200 |
| commit | fc9ff915b1fb6f6f826953d1bef3087d7a489d65 (patch) | |
| tree | a1da80838c617545a51bc39defc36f09faae7a6b | |
| parent | 98d02b5128833c3d812e62a2616f33f1524c8394 (diff) | |
| download | linux-next-fc9ff915b1fb6f6f826953d1bef3087d7a489d65.tar.gz linux-next-fc9ff915b1fb6f6f826953d1bef3087d7a489d65.zip | |
power: supply: max17042_battery: Retry failed MAX17055 initialization
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 <vincent@cloutier.co>
Link: https://patch.msgid.link/20260727011319.621794-7-vincent.cloutier@icloud.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
| -rw-r--r-- | drivers/power/supply/max17042_battery.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/power/supply/max17042_battery.c b/drivers/power/supply/max17042_battery.c index f59dec8864ef..e44795d54b43 100644 --- a/drivers/power/supply/max17042_battery.c +++ b/drivers/power/supply/max17042_battery.c @@ -63,6 +63,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; @@ -848,13 +850,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) @@ -862,10 +864,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 @@ -997,16 +1002,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 |
