[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.