[PATCH 4/4] ASoC: wm8994: drain all delayed works on component remove
From: Tristan Madani
Date: Mon Oct 26 2026 - 07:36:17 EST
From: Tristan Madani <tristan@xxxxxxxxxxxxxxxxxxx>
wm8994_component_remove() frees IRQs and firmware but does not cancel
any of the delayed works that IRQ handlers and DAPM events schedule.
jackdet_bootstrap can spawn mic_work (via wm1811_jackdet_irq), and
wm8958_mic_irq can queue mic_complete_work, whose callback may in turn
queue open_circuit_work. If any of these works are pending when the
component is unbound, they fire after DAPM widgets are freed.
After freeing all IRQ producers and before releasing firmware, drain
the full work graph in producer-to-child order: jackdet_bootstrap,
mic_complete_work, mic_work, then open_circuit_work.
Fixes: 99af79dff5a6 ("ASoC: wm8994: Ensure we get a notification on startup for jackdet")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Tristan Madani <tristan@xxxxxxxxxxxxxxxxxxx>
---
sound/soc/codecs/wm8994.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 8bf58a6a8af7c..32c1786bd48ef 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -4592,6 +4592,10 @@ static void wm8994_component_remove(struct snd_soc_component *component)
free_irq(wm8994->micdet_irq, wm8994);
break;
}
+ cancel_delayed_work_sync(&wm8994->jackdet_bootstrap);
+ cancel_delayed_work_sync(&wm8994->mic_complete_work);
+ cancel_delayed_work_sync(&wm8994->mic_work);
+ cancel_delayed_work_sync(&wm8994->open_circuit_work);
release_firmware(wm8994->mbc);
release_firmware(wm8994->mbc_vss);
release_firmware(wm8994->enh_eq);
--
2.47.3