[PATCH 03/19] ASoC: codecs: lpass-wsa-macro: Propagate regcache_sync() errors

From: Pengpeng Hou

Date: Fri Jul 03 2026 - 23:52:19 EST


regcache_sync() can fail while replaying cached register state. The WSA
macro MCLK helper and runtime resume path currently ignore that failure
and report success.

Propagate the error from the MCLK helper users and from runtime resume.
If runtime resume fails after enabling clocks, restore cache-only/dirty
state and unwind the clocks acquired by the resume path.

Signed-off-by: Pengpeng Hou <pengpeng@xxxxxxxxxxx>
---
sound/soc/codecs/lpass-wsa-macro.c | 28 +++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c
index 5ad0448af649..59786316b49a 100644
--- a/sound/soc/codecs/lpass-wsa-macro.c
+++ b/sound/soc/codecs/lpass-wsa-macro.c
@@ -1408,14 +1408,17 @@ static struct snd_soc_dai_driver wsa_macro_dai[] = {
},
};

-static void wsa_macro_mclk_enable(struct wsa_macro *wsa, bool mclk_enable)
+static int wsa_macro_mclk_enable(struct wsa_macro *wsa, bool mclk_enable)
{
struct regmap *regmap = wsa->regmap;
+ int ret;

if (mclk_enable) {
if (wsa->wsa_mclk_users == 0) {
regcache_mark_dirty(regmap);
- regcache_sync(regmap);
+ ret = regcache_sync(regmap);
+ if (ret)
+ return ret;
/* 9.6MHz MCLK, set value 0x00 if other frequency */
regmap_update_bits(regmap, CDC_WSA_TOP_FREQ_MCLK, 0x01, 0x01);
regmap_update_bits(regmap,
@@ -1432,7 +1435,7 @@ static void wsa_macro_mclk_enable(struct wsa_macro *wsa, bool mclk_enable)
if (wsa->wsa_mclk_users <= 0) {
dev_err(wsa->dev, "clock already disabled\n");
wsa->wsa_mclk_users = 0;
- return;
+ return 0;
}
wsa->wsa_mclk_users--;
if (wsa->wsa_mclk_users == 0) {
@@ -1446,6 +1449,8 @@ static void wsa_macro_mclk_enable(struct wsa_macro *wsa, bool mclk_enable)
CDC_WSA_MCLK_DISABLE);
}
}
+
+ return 0;
}

static void wsa_macro_enable_disable_vi_sense(struct snd_soc_component *component, bool enable,
@@ -1515,8 +1520,7 @@ static int wsa_macro_mclk_event(struct snd_soc_dapm_widget *w,
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);

- wsa_macro_mclk_enable(wsa, event == SND_SOC_DAPM_PRE_PMU);
- return 0;
+ return wsa_macro_mclk_enable(wsa, event == SND_SOC_DAPM_PRE_PMU);
}

static int wsa_macro_enable_vi_feedback(struct snd_soc_dapm_widget *w,
@@ -2538,7 +2542,11 @@ static int wsa_swrm_clock(struct wsa_macro *wsa, bool enable)
dev_err(wsa->dev, "failed to enable mclk\n");
return ret;
}
- wsa_macro_mclk_enable(wsa, true);
+ ret = wsa_macro_mclk_enable(wsa, true);
+ if (ret) {
+ clk_disable_unprepare(wsa->mclk);
+ return ret;
+ }

regmap_update_bits(regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
CDC_WSA_SWR_CLK_EN_MASK,
@@ -2887,9 +2895,15 @@ static int wsa_macro_runtime_resume(struct device *dev)
}

regcache_cache_only(wsa->regmap, false);
- regcache_sync(wsa->regmap);
+ ret = regcache_sync(wsa->regmap);
+ if (ret)
+ goto err_sync;

return 0;
+err_sync:
+ regcache_cache_only(wsa->regmap, true);
+ regcache_mark_dirty(wsa->regmap);
+ clk_disable_unprepare(wsa->fsgen);
err_fsgen:
clk_disable_unprepare(wsa->npl);
err_npl:
--
2.43.0