[PATCH 18/19] ASoC: codecs: max98396: Unwind supplies on resume failure
From: Pengpeng Hou
Date: Sat Jul 04 2026 - 00:07:42 EST
max98396_resume() enables the core, pvdd, and vbat supplies before
leaving cache-only mode, resetting the device, and replaying cached
register state. The function currently ignores regcache_sync() failures,
and the optional pvdd/vbat enable failures return without unwinding
supplies that were already enabled in this resume attempt.
Rework the function to use common error labels. This propagates sync
failures, restores cache-only/dirty state on failed cache replay, and
disables each supply acquired by this resume path before returning the
error.
Signed-off-by: Pengpeng Hou <pengpeng@xxxxxxxxxxx>
---
sound/soc/codecs/max98396.c | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/max98396.c b/sound/soc/codecs/max98396.c
index 9c1d7213410c..e5a2fe824c03 100644
--- a/sound/soc/codecs/max98396.c
+++ b/sound/soc/codecs/max98396.c
@@ -1600,19 +1600,37 @@ static int max98396_resume(struct device *dev)
if (max98396->pvdd) {
ret = regulator_enable(max98396->pvdd);
if (ret < 0)
- return ret;
+ goto err_core_supplies;
}
if (max98396->vbat) {
ret = regulator_enable(max98396->vbat);
if (ret < 0)
- return ret;
+ goto err_pvdd;
}
regcache_cache_only(max98396->regmap, false);
max98396_reset(max98396, dev);
- regcache_sync(max98396->regmap);
+ ret = regcache_sync(max98396->regmap);
+ if (ret < 0) {
+ regcache_cache_only(max98396->regmap, true);
+ regcache_mark_dirty(max98396->regmap);
+ goto err_vbat;
+ }
+
return 0;
+
+err_vbat:
+ if (max98396->vbat)
+ regulator_disable(max98396->vbat);
+err_pvdd:
+ if (max98396->pvdd)
+ regulator_disable(max98396->pvdd);
+err_core_supplies:
+ regulator_bulk_disable(MAX98396_NUM_CORE_SUPPLIES,
+ max98396->core_supplies);
+
+ return ret;
}
static const struct dev_pm_ops max98396_pm = {
--
2.43.0