[PATCH 8/9] ASoC: rt5640: stop jack resume after restore errors

From: Pengpeng Hou

Date: Sat Sep 05 2026 - 23:46:56 EST


rt5640_resume() ignores cache replay and jack-detect register update
failures, then enables the IRQ and queues jack work. The work can
therefore run against a partially restored codec.

Return the first restore error before publishing IRQ or work activity.
Keep the LDO enabled on failure because deferred component resume
remains best effort and the core still marks the component resumed;
powering it down here would create a contradictory software and hardware
state.

The issue was found by our static-analysis tool and manually reviewed.

Fixes: 997b05203b0a ("ASoC: add RT5640 CODEC driver")
Assisted-by: gpt 5
Signed-off-by: Pengpeng Hou <hppiscas@xxxxxxx>
---
sound/soc/codecs/rt5640.c | 41 +++++++++++++++++++++++----------------
1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 74fd05176eff..2ae3c7407ee7 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -2826,6 +2826,7 @@ static int rt5640_suspend(struct snd_soc_component *component)
static int rt5640_resume(struct snd_soc_component *component)
{
struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+ int ret = 0;

if (rt5640->ldo1_en) {
gpiod_set_value_cansleep(rt5640->ldo1_en, 1);
@@ -2833,35 +2834,41 @@ static int rt5640_resume(struct snd_soc_component *component)
}

regcache_cache_only(rt5640->regmap, false);
- regcache_sync(rt5640->regmap);
+ ret = regcache_sync(rt5640->regmap);
+ if (ret)
+ return ret;

if (rt5640->jack) {
if (rt5640->jd_src == RT5640_JD_SRC_HDA_HEADER) {
- snd_soc_component_update_bits(component,
- RT5640_GCTL2, 0x1100, 0x1100);
+ ret = snd_soc_component_update_bits(component,
+ RT5640_GCTL2,
+ 0x1100, 0x1100);
} else {
if (rt5640->jd_inverted) {
if (rt5640->jd_src == RT5640_JD_SRC_JD2_IN4N)
- snd_soc_component_update_bits(
- component, RT5640_GCTL2,
- RT5640_IRQ_JD2_MASK |
- RT5640_JD2_MASK,
- RT5640_IRQ_JD2_NOR |
- RT5640_JD2_EN);
+ ret = snd_soc_component_update_bits(component,
+ RT5640_GCTL2,
+ RT5640_IRQ_JD2_MASK |
+ RT5640_JD2_MASK,
+ RT5640_IRQ_JD2_NOR |
+ RT5640_JD2_EN);

} else {
if (rt5640->jd_src == RT5640_JD_SRC_JD2_IN4N)
- snd_soc_component_update_bits(
- component, RT5640_GCTL2,
- RT5640_IRQ_JD2_MASK |
- RT5640_JD2_P_MASK |
- RT5640_JD2_MASK,
- RT5640_IRQ_JD2_NOR |
- RT5640_JD2_P_INV |
- RT5640_JD2_EN);
+ ret = snd_soc_component_update_bits(component,
+ RT5640_GCTL2,
+ RT5640_IRQ_JD2_MASK |
+ RT5640_JD2_P_MASK |
+ RT5640_JD2_MASK,
+ RT5640_IRQ_JD2_NOR |
+ RT5640_JD2_P_INV |
+ RT5640_JD2_EN);
}
}

+ if (ret < 0)
+ return ret;
+
enable_irq(rt5640->irq);
queue_delayed_work(system_dfl_long_wq, &rt5640->jack_work, 0);
}
--
2.50.1 (Apple Git-155)