ASoC: codecs: max98396: Unwind supplies on resume failure

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@iscas.ac.cn>
Link: https://patch.msgid.link/20260704040651.47558-1-pengpeng@iscas.ac.cn
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Pengpeng Hou 2026-07-04 12:06:51 +08:00 committed by Mark Brown
parent 446a8b7a03
commit d20de7409d
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -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 = {