[PATCH v2 4/9] ASoC: rt5663: restore safe state after resume errors
From: Pengpeng Hou
Date: Tue Oct 13 2026 - 23:26:22 EST
rt5663_resume() ignores regcache_sync() failure before continuing
dependent resume operations. Restore cache-only mode, leave the cache
dirty, and return the replay error before those operations.
Do not schedule jack-detection work or enable its IRQ after a failed
replay.
ASoC still marks the component resumed when the callback reports failure.
Track the suspend-owned IRQ disable so another suspend does not increment
the disable depth again after a failed resume. A later successful resume
releases that one disable reference. This does not add automatic retry or
change the framework's best-effort card resume policy.
The issue was found by our static-analysis tool and manually reviewed.
Fixes: df7c52168ee1 ("ASoC: add rt5663 codec driver")
Assisted-by: gpt 5
Signed-off-by: Pengpeng Hou <hppiscas@xxxxxxx>
---
Changes since v1:
- restore cache-only mode and dirty state on replay failure
- keep suspend-owned IRQ disables balanced across failed resume cycles
- send as one correctly threaded series, as Mark requested
Previous series:
https://lore.kernel.org/all/20260906034321.86080-1-hppiscas@xxxxxxx/
sound/soc/codecs/rt5663.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c
index ec46e6180cc0ee9fd66df0174bf0d0ac8022dc45..bd6a8e98bf44445e91edf81896f526a180df083f 100644
--- a/sound/soc/codecs/rt5663.c
+++ b/sound/soc/codecs/rt5663.c
@@ -75,6 +75,7 @@ struct rt5663_priv {
int jack_type;
unsigned int irq;
+ bool suspend_irq_disabled;
};
static const struct reg_sequence rt5663_patch_list[] = {
@@ -3187,8 +3188,10 @@ static int rt5663_suspend(struct snd_soc_component *component)
{
struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
- if (rt5663->irq)
+ if (rt5663->irq && !rt5663->suspend_irq_disabled) {
disable_irq(rt5663->irq);
+ rt5663->suspend_irq_disabled = true;
+ }
cancel_delayed_work_sync(&rt5663->jack_detect_work);
cancel_delayed_work_sync(&rt5663->jd_unplug_work);
@@ -3202,14 +3205,22 @@ static int rt5663_suspend(struct snd_soc_component *component)
static int rt5663_resume(struct snd_soc_component *component)
{
struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component);
+ int ret;
regcache_cache_only(rt5663->regmap, false);
- regcache_sync(rt5663->regmap);
+ ret = regcache_sync(rt5663->regmap);
+ if (ret) {
+ regcache_cache_only(rt5663->regmap, true);
+ regcache_mark_dirty(rt5663->regmap);
+ return ret;
+ }
rt5663_irq(0, rt5663);
- if (rt5663->irq)
+ if (rt5663->suspend_irq_disabled) {
+ rt5663->suspend_irq_disabled = false;
enable_irq(rt5663->irq);
+ }
return 0;
}
base-commit: 8ef28aef33f2d5da6959ad6b579ec3cfccc009f6