summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPengpeng Hou <pengpeng@iscas.ac.cn>2026-07-04 11:49:46 +0800
committerMark Brown <broonie@kernel.org>2026-07-09 17:45:20 +0100
commite38cbb75248a4027389c8a3d0bbd27bb760ba992 (patch)
tree769ff34f8f0822014cd6ba5f6f9d9b76772abc86
parentabe8ddff80fdfce5255ab9f5931aaed5b058bb65 (diff)
ASoC: codecs: lpass-rx-macro: Propagate regcache_sync() errors
regcache_sync() can fail while replaying cached register state. The RX 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@iscas.ac.cn> Link: https://patch.msgid.link/20260704034946.20369-1-pengpeng@iscas.ac.cn Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/codecs/lpass-rx-macro.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c
index 6233aa9f5bc6..550fc76109c6 100644
--- a/sound/soc/codecs/lpass-rx-macro.c
+++ b/sound/soc/codecs/lpass-rx-macro.c
@@ -2030,9 +2030,10 @@ static struct snd_soc_dai_driver rx_macro_dai[] = {
},
};
-static void rx_macro_mclk_enable(struct rx_macro *rx, bool mclk_enable)
+static int rx_macro_mclk_enable(struct rx_macro *rx, bool mclk_enable)
{
struct regmap *regmap = rx->regmap;
+ int ret;
if (mclk_enable) {
if (rx->rx_mclk_users == 0) {
@@ -2047,14 +2048,16 @@ static void rx_macro_mclk_enable(struct rx_macro *rx, bool mclk_enable)
CDC_RX_FS_MCLK_CNT_EN_MASK,
CDC_RX_FS_MCLK_CNT_ENABLE);
regcache_mark_dirty(regmap);
- regcache_sync(regmap);
+ ret = regcache_sync(regmap);
+ if (ret)
+ return ret;
}
rx->rx_mclk_users++;
} else {
if (rx->rx_mclk_users <= 0) {
dev_err(rx->dev, "%s: clock already disabled\n", __func__);
rx->rx_mclk_users = 0;
- return;
+ return 0;
}
rx->rx_mclk_users--;
if (rx->rx_mclk_users == 0) {
@@ -2068,6 +2071,8 @@ static void rx_macro_mclk_enable(struct rx_macro *rx, bool mclk_enable)
CDC_RX_CLK_MCLK2_EN_MASK, 0x0);
}
}
+
+ return 0;
}
static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w,
@@ -2079,11 +2084,9 @@ static int rx_macro_mclk_event(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
- rx_macro_mclk_enable(rx, true);
- break;
+ return rx_macro_mclk_enable(rx, true);
case SND_SOC_DAPM_POST_PMD:
- rx_macro_mclk_enable(rx, false);
- break;
+ return rx_macro_mclk_enable(rx, false);
default:
dev_err(component->dev, "%s: invalid DAPM event %d\n", __func__, event);
ret = -EINVAL;
@@ -3677,7 +3680,11 @@ static int swclk_gate_enable(struct clk_hw *hw)
return ret;
}
- rx_macro_mclk_enable(rx, true);
+ ret = rx_macro_mclk_enable(rx, true);
+ if (ret) {
+ clk_disable_unprepare(rx->mclk);
+ return ret;
+ }
regmap_update_bits(rx->regmap, CDC_RX_CLK_RST_CTRL_SWR_CONTROL,
CDC_RX_SWR_CLK_EN_MASK, 1);
@@ -4003,9 +4010,15 @@ static int rx_macro_runtime_resume(struct device *dev)
goto err_fsgen;
}
regcache_cache_only(rx->regmap, false);
- regcache_sync(rx->regmap);
+ ret = regcache_sync(rx->regmap);
+ if (ret)
+ goto err_sync;
return 0;
+err_sync:
+ regcache_cache_only(rx->regmap, true);
+ regcache_mark_dirty(rx->regmap);
+ clk_disable_unprepare(rx->fsgen);
err_fsgen:
clk_disable_unprepare(rx->npl);
err_npl: