* [PATCH 0/4] ASoC: cancel pending delayed works on component remove
@ 2026-10-26 11:22 Tristan Madani
2026-10-26 11:22 ` [PATCH 1/4] ASoC: rt5668: " Tristan Madani
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: Tristan Madani @ 2026-10-26 11:22 UTC (permalink / raw)
To: Mark Brown, Takashi Iwai
Cc: Oder Chiou, Bard Liao, Liam Girdwood, Jaroslav Kysela,
Jorge Eduardo Candelaria, linux-sound, linux-kernel, stable,
Tristan Madani
From: Tristan Madani <tristan@talencesecurity.com>
Four ASoC codec drivers initialise delayed works that are not
cancelled during component removal. If the card is unbound while
these works are pending, callbacks fire after DAPM widgets are freed.
rt5668 and rt5659 share the same pattern: the IRQ handler reschedules
work after the codec is reset. Track IRQ acquisition so that
disable_irq() only quiesces a line the driver owns, then drain all
delayed works before resetting the hardware.
twl6040 frees the plug-detect IRQ but does not drain the work that the
handler schedules.
wm8994 frees IRQs and firmware but does not cancel any of the four
delayed works that IRQ handlers and DAPM events schedule.
Tristan Madani (4):
ASoC: rt5668: cancel pending delayed works on component remove
ASoC: rt5659: cancel jack_detect_work on component remove
ASoC: twl6040: cancel headset jack work on component remove
ASoC: wm8994: drain all delayed works on component remove
sound/soc/codecs/rt5659.c | 17 ++++++++++++++++-
sound/soc/codecs/rt5659.h | 2 ++
sound/soc/codecs/rt5668.c | 20 +++++++++++++++++++-
sound/soc/codecs/twl6040.c | 1 +
sound/soc/codecs/wm8994.c | 4 ++++
5 files changed, 42 insertions(+), 2 deletions(-)
--
2.47.3
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/4] ASoC: rt5668: cancel pending delayed works on component remove
2026-10-26 11:22 [PATCH 0/4] ASoC: cancel pending delayed works on component remove Tristan Madani
@ 2026-10-26 11:22 ` Tristan Madani
2026-10-26 11:22 ` [PATCH 2/4] ASoC: rt5659: cancel jack_detect_work " Tristan Madani
` (3 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Tristan Madani @ 2026-10-26 11:22 UTC (permalink / raw)
To: Mark Brown, Takashi Iwai
Cc: Oder Chiou, Bard Liao, Liam Girdwood, Jaroslav Kysela,
Jorge Eduardo Candelaria, linux-sound, linux-kernel, stable,
Tristan Madani
From: Tristan Madani <tristan@talencesecurity.com>
The rt5668 codec initializes two delayed works (jack_detect_work,
jd_check_work) but neither is cancelled during component removal.
If the card is unbound while these works are pending, they fire on
freed resources when snd_soc_jack_report() dereferences the cleared
card pointer.
Track successful IRQ acquisition with a flag so that disable_irq()
only quiesces a line this driver actually owns. On component remove,
disable the IRQ to stop the handler from rescheduling work, then
drain both delayed works before resetting the codec. On the next
component probe (card rebind), re-enable the IRQ to restore jack
detection.
Fixes: d59fb2856223 ("ASoC: rt5668: add rt5668B codec driver")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
sound/soc/codecs/rt5668.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/rt5668.c b/sound/soc/codecs/rt5668.c
index 4154bad276101..01b14c62fde7f 100644
--- a/sound/soc/codecs/rt5668.c
+++ b/sound/soc/codecs/rt5668.c
@@ -62,6 +62,8 @@ struct rt5668_priv {
int pll_out;
int jack_type;
+ bool irq_acquired;
+ bool irq_disabled;
};
static const struct reg_default rt5668_reg[] = {
@@ -2213,6 +2215,12 @@ static int rt5668_set_bias_level(struct snd_soc_component *component,
static int rt5668_probe(struct snd_soc_component *component)
{
struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
+ struct i2c_client *i2c = to_i2c_client(component->dev);
+
+ if (rt5668->irq_disabled) {
+ enable_irq(i2c->irq);
+ rt5668->irq_disabled = false;
+ }
rt5668->component = component;
@@ -2222,7 +2230,15 @@ static int rt5668_probe(struct snd_soc_component *component)
static void rt5668_remove(struct snd_soc_component *component)
{
struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component);
+ struct i2c_client *i2c = to_i2c_client(component->dev);
+ if (rt5668->irq_acquired) {
+ disable_irq(i2c->irq);
+ rt5668->irq_disabled = true;
+ }
+
+ cancel_delayed_work_sync(&rt5668->jack_detect_work);
+ cancel_delayed_work_sync(&rt5668->jd_check_work);
rt5668_reset(rt5668->regmap);
}
@@ -2531,7 +2547,9 @@ static int rt5668_i2c_probe(struct i2c_client *i2c)
ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
rt5668_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
| IRQF_ONESHOT, "rt5668", rt5668);
- if (ret)
+ if (!ret)
+ rt5668->irq_acquired = true;
+ else
dev_err(&i2c->dev, "Failed to request IRQ: %d\n", ret);
}
--
2.47.3
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 2/4] ASoC: rt5659: cancel jack_detect_work on component remove
2026-10-26 11:22 [PATCH 0/4] ASoC: cancel pending delayed works on component remove Tristan Madani
2026-10-26 11:22 ` [PATCH 1/4] ASoC: rt5668: " Tristan Madani
@ 2026-10-26 11:22 ` Tristan Madani
2026-10-26 19:16 ` Mark Brown
2026-10-26 11:22 ` [PATCH 3/4] ASoC: twl6040: cancel headset jack work " Tristan Madani
` (2 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Tristan Madani @ 2026-10-26 11:22 UTC (permalink / raw)
To: Mark Brown, Takashi Iwai
Cc: Oder Chiou, Bard Liao, Liam Girdwood, Jaroslav Kysela,
Jorge Eduardo Candelaria, linux-sound, linux-kernel, stable,
Tristan Madani
From: Tristan Madani <tristan@talencesecurity.com>
rt5659_remove() resets the codec via regmap_write() but does not cancel
the pending jack_detect_work. Since the IRQ is registered with
devm_request_threaded_irq(), it remains active until after the component
remove callback returns. The IRQ handler (rt5659_irq) schedules
jack_detect_work, so a late interrupt can queue work that runs against a
reset codec.
Track successful IRQ acquisition with a flag so that disable_irq()
only quiesces a line this driver actually owns. On component remove,
disable the IRQ to synchronize with any running handler and prevent
new enqueues, then drain the residual jack_detect_work synchronously
before resetting the hardware. On the next component probe (card
rebind), re-enable the IRQ to restore jack detection.
Fixes: d3cb2de2479b ("ASoC: rt5659: add rt5659 codec driver")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
sound/soc/codecs/rt5659.c | 17 ++++++++++++++++-
sound/soc/codecs/rt5659.h | 2 ++
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c
index 3097ee6d4e89f..340d3e7be7a40 100644
--- a/sound/soc/codecs/rt5659.c
+++ b/sound/soc/codecs/rt5659.c
@@ -3664,6 +3664,12 @@ static int rt5659_probe(struct snd_soc_component *component)
{
struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
+ struct i2c_client *i2c = to_i2c_client(component->dev);
+
+ if (rt5659->irq_disabled) {
+ enable_irq(i2c->irq);
+ rt5659->irq_disabled = false;
+ }
rt5659->component = component;
@@ -3684,7 +3690,14 @@ static int rt5659_probe(struct snd_soc_component *component)
static void rt5659_remove(struct snd_soc_component *component)
{
struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
+ struct i2c_client *i2c = to_i2c_client(component->dev);
+
+ if (rt5659->irq_acquired) {
+ disable_irq(i2c->irq);
+ rt5659->irq_disabled = true;
+ }
+ cancel_delayed_work_sync(&rt5659->jack_detect_work);
regmap_write(rt5659->regmap, RT5659_RESET, 0);
}
@@ -4290,7 +4303,9 @@ static int rt5659_i2c_probe(struct i2c_client *i2c)
ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
rt5659_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
| IRQF_ONESHOT, "rt5659", rt5659);
- if (ret)
+ if (!ret)
+ rt5659->irq_acquired = true;
+ else
dev_err(&i2c->dev, "Failed to request IRQ: %d\n", ret);
/* Enable IRQ output for GPIO1 pin any way */
diff --git a/sound/soc/codecs/rt5659.h b/sound/soc/codecs/rt5659.h
index b49fd8baf4e7e..4df7d7dd99e16 100644
--- a/sound/soc/codecs/rt5659.h
+++ b/sound/soc/codecs/rt5659.h
@@ -1813,6 +1813,8 @@ struct rt5659_priv {
int jack_type;
bool hda_hp_plugged;
bool hda_mic_plugged;
+ bool irq_acquired;
+ bool irq_disabled;
};
int rt5659_set_jack_detect(struct snd_soc_component *component,
--
2.47.3
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 3/4] ASoC: twl6040: cancel headset jack work on component remove
2026-10-26 11:22 [PATCH 0/4] ASoC: cancel pending delayed works on component remove Tristan Madani
2026-10-26 11:22 ` [PATCH 1/4] ASoC: rt5668: " Tristan Madani
2026-10-26 11:22 ` [PATCH 2/4] ASoC: rt5659: cancel jack_detect_work " Tristan Madani
@ 2026-10-26 11:22 ` Tristan Madani
2026-10-26 11:22 ` [PATCH 4/4] ASoC: wm8994: drain all delayed works " Tristan Madani
2026-10-29 10:25 ` [PATCH v9] ASoC: wm8994: drain delayed works on remove and probe error Tristan Madani
4 siblings, 0 replies; 11+ messages in thread
From: Tristan Madani @ 2026-10-26 11:22 UTC (permalink / raw)
To: Mark Brown, Takashi Iwai
Cc: Oder Chiou, Bard Liao, Liam Girdwood, Jaroslav Kysela,
Jorge Eduardo Candelaria, linux-sound, linux-kernel, stable,
Tristan Madani
From: Tristan Madani <tristan@talencesecurity.com>
twl6040_remove() frees the plug detect IRQ but does not cancel the
delayed work that the IRQ handler schedules. If the work is still
pending after free_irq() returns, it fires on freed memory.
Add cancel_delayed_work_sync() after free_irq() to drain any residual
work. The IRQ is freed first to stop the producer, then the work is
drained.
Fixes: a2d2362edf9f ("ASoC: twl6040: Add jack support for headset and handset")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
sound/soc/codecs/twl6040.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 650836f9615fb..826bde1a9ba46 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -1136,6 +1136,7 @@ static void twl6040_remove(struct snd_soc_component *component)
struct twl6040_data *priv = snd_soc_component_get_drvdata(component);
free_irq(priv->plug_irq, component);
+ cancel_delayed_work_sync(&priv->hs_jack.work);
}
static const struct snd_soc_component_driver soc_component_dev_twl6040 = {
--
2.47.3
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 4/4] ASoC: wm8994: drain all delayed works on component remove
2026-10-26 11:22 [PATCH 0/4] ASoC: cancel pending delayed works on component remove Tristan Madani
` (2 preceding siblings ...)
2026-10-26 11:22 ` [PATCH 3/4] ASoC: twl6040: cancel headset jack work " Tristan Madani
@ 2026-10-26 11:22 ` Tristan Madani
2026-10-26 19:16 ` Mark Brown
2026-10-29 10:25 ` [PATCH v9] ASoC: wm8994: drain delayed works on remove and probe error Tristan Madani
4 siblings, 1 reply; 11+ messages in thread
From: Tristan Madani @ 2026-10-26 11:22 UTC (permalink / raw)
To: Mark Brown, Takashi Iwai
Cc: Oder Chiou, Bard Liao, Liam Girdwood, Jaroslav Kysela,
Jorge Eduardo Candelaria, linux-sound, linux-kernel, stable,
Tristan Madani
From: Tristan Madani <tristan@talencesecurity.com>
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@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
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
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/4] ASoC: rt5659: cancel jack_detect_work on component remove
2026-10-26 11:22 ` [PATCH 2/4] ASoC: rt5659: cancel jack_detect_work " Tristan Madani
@ 2026-10-26 19:16 ` Mark Brown
0 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2026-10-26 19:16 UTC (permalink / raw)
To: Tristan Madani
Cc: Mark Brown, Takashi Iwai, Oder Chiou, Bard Liao, Liam Girdwood,
Jaroslav Kysela, Jorge Eduardo Candelaria, linux-sound,
linux-kernel, stable, Tristan Madani
> Track successful IRQ acquisition with a flag so that disable_irq()
> only quiesces a line this driver actually owns. On component remove,
> disable the IRQ to synchronize with any running handler and prevent
> new enqueues, then drain the residual jack_detect_work synchronously
> before resetting the hardware. On the next component probe (card
> rebind), re-enable the IRQ to restore jack detection.
> @@ -3684,7 +3690,14 @@ static int rt5659_probe(struct snd_soc_component *component)
> static void rt5659_remove(struct snd_soc_component *component)
> {
> struct rt5659_priv *rt5659 = snd_soc_component_get_drvdata(component);
> + struct i2c_client *i2c = to_i2c_client(component->dev);
> +
> + if (rt5659->irq_acquired) {
> + disable_irq(i2c->irq);
> + rt5659->irq_disabled = true;
> + }
>
> + cancel_delayed_work_sync(&rt5659->jack_detect_work);
This work isn't unconditionally initialised, cancelling something that
wasn't initialised is an error and will trigger warnings. Either this
needs to be conditional or we should just always initialise.
--
Mark Brown <broonie@kernel.org>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 4/4] ASoC: wm8994: drain all delayed works on component remove
2026-10-26 11:22 ` [PATCH 4/4] ASoC: wm8994: drain all delayed works " Tristan Madani
@ 2026-10-26 19:16 ` Mark Brown
0 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2026-10-26 19:16 UTC (permalink / raw)
To: Tristan Madani
Cc: Mark Brown, Takashi Iwai, Oder Chiou, Bard Liao, Liam Girdwood,
Jaroslav Kysela, Jorge Eduardo Candelaria, linux-sound,
linux-kernel, stable, Tristan Madani
> 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.
> + cancel_delayed_work_sync(&wm8994->jackdet_bootstrap);
> + cancel_delayed_work_sync(&wm8994->mic_complete_work);
> + cancel_delayed_work_sync(&wm8994->mic_work);
Same issue here for mic_work.
--
Mark Brown <broonie@kernel.org>
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v9] ASoC: wm8994: drain delayed works on remove and probe error
2026-10-26 11:22 [PATCH 0/4] ASoC: cancel pending delayed works on component remove Tristan Madani
` (3 preceding siblings ...)
2026-10-26 11:22 ` [PATCH 4/4] ASoC: wm8994: drain all delayed works " Tristan Madani
@ 2026-10-29 10:25 ` Tristan Madani
2026-10-29 10:57 ` [PATCH v10] " Tristan Madani
2026-10-29 11:10 ` [PATCH v9] " Mark Brown
4 siblings, 2 replies; 11+ messages in thread
From: Tristan Madani @ 2026-10-29 10:25 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai
Cc: patches, linux-sound, linux-kernel, stable, Tristan Madani
From: Tristan Madani <tristan@talencesecurity.com>
wm8994_component_probe() schedules several delayed works to handle jack
detection and microphone status polling. If the component is removed or
probe fails after these works are scheduled, they can execute after
resources are freed.
Cancel all pending delayed works in the error and removal paths. Guard
cancel_delayed_work_sync(&wm8994->mic_work) with a type check because
INIT_DELAYED_WORK for mic_work only runs in the WM8994 and WM1811 code
paths.
Fixes: 99af79dff5a6 ("ASoC: wm8994: Ensure we get a notification on startup for jackdet")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
Changes since v8 [4/4]:
- Guard cancel_delayed_work_sync(&wm8994->mic_work) with type check
(WM8994 || WM1811), as mic_work is only initialized in those code
paths — addresses Mark Brown review comment
- Add cleanup to probe error path (err_irq label), not just remove
sound/soc/codecs/wm8994.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index fc9894975a1d5..30a164796fd48 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -4563,6 +4563,11 @@ static int wm8994_component_probe(struct snd_soc_component *component)
wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR, component);
wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT, component);
wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN, component);
+ cancel_delayed_work_sync(&wm8994->jackdet_bootstrap);
+ cancel_delayed_work_sync(&wm8994->mic_complete_work);
+ if (control->type == WM8994 || control->type == WM1811)
+ cancel_delayed_work_sync(&wm8994->mic_work);
+ cancel_delayed_work_sync(&wm8994->open_circuit_work);
return ret;
}
@@ -4604,6 +4609,11 @@ 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);
+ if (control->type == WM8994 || control->type == WM1811)
+ 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
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v10] ASoC: wm8994: drain delayed works on remove and probe error
2026-10-29 10:25 ` [PATCH v9] ASoC: wm8994: drain delayed works on remove and probe error Tristan Madani
@ 2026-10-29 10:57 ` Tristan Madani
2026-10-29 11:18 ` Mark Brown
2026-10-29 11:10 ` [PATCH v9] " Mark Brown
1 sibling, 1 reply; 11+ messages in thread
From: Tristan Madani @ 2026-10-29 10:57 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai
Cc: patches, linux-sound, linux-kernel, stable, Tristan Madani
From: Tristan Madani <tristan@talencesecurity.com>
wm8994_component_probe() schedules several delayed works to handle jack
detection and microphone status polling. If the component is removed or
probe fails after these works are scheduled, they can execute after
resources are freed.
Cancel all pending delayed works in the error and removal paths. Guard
cancel_delayed_work_sync(&wm8994->mic_work) with a type check because
INIT_DELAYED_WORK for mic_work only runs in the WM8994 and WM1811 code
paths.
Cancel mic_work before jackdet_bootstrap and mic_complete_work because
wm1811_mic_work() can re-arm jackdet_bootstrap through the DAPM power-up
chain (force-enabling MICBIAS2 triggers clk_sys_event which queues
jackdet_bootstrap), and enabling microphone detection in hardware can
cause WM8994_IRQ_MIC1_DET to fire and re-queue mic_complete_work.
Fixes: 99af79dff5a6 ("ASoC: wm8994: Ensure we get a notification on startup for jackdet")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
Changes since v9:
- Reorder cancel_delayed_work_sync calls: cancel mic_work first,
then jackdet_bootstrap, mic_complete_work, open_circuit_work.
wm1811_mic_work() can re-arm jackdet_bootstrap through the DAPM
power-up chain (MICBIAS2 -> CLK_SYS -> clk_sys_event) and can
trigger MIC1_DET which re-queues mic_complete_work, so cancelling
mic_work before its downstream consumers prevents re-arming after
cancel.
Changes since v8 [4/4]:
- Guard cancel_delayed_work_sync(&wm8994->mic_work) with type check
(WM8994 || WM1811), as mic_work is only initialized in those code
paths — addresses Mark Brown review comment
- Add cleanup to probe error path (err_irq label), not just remove
sound/soc/codecs/wm8994.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index fc9894975a1d5..5a493f29c2ca3 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -4563,6 +4563,11 @@ static int wm8994_component_probe(struct snd_soc_component *component)
wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR, component);
wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT, component);
wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN, component);
+ if (control->type == WM8994 || control->type == WM1811)
+ cancel_delayed_work_sync(&wm8994->mic_work);
+ cancel_delayed_work_sync(&wm8994->jackdet_bootstrap);
+ cancel_delayed_work_sync(&wm8994->mic_complete_work);
+ cancel_delayed_work_sync(&wm8994->open_circuit_work);
return ret;
}
@@ -4604,6 +4609,11 @@ static void wm8994_component_remove(struct snd_soc_component *component)
free_irq(wm8994->micdet_irq, wm8994);
break;
}
+ if (control->type == WM8994 || control->type == WM1811)
+ cancel_delayed_work_sync(&wm8994->mic_work);
+ cancel_delayed_work_sync(&wm8994->jackdet_bootstrap);
+ cancel_delayed_work_sync(&wm8994->mic_complete_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
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v9] ASoC: wm8994: drain delayed works on remove and probe error
2026-10-29 10:25 ` [PATCH v9] ASoC: wm8994: drain delayed works on remove and probe error Tristan Madani
2026-10-29 10:57 ` [PATCH v10] " Tristan Madani
@ 2026-10-29 11:10 ` Mark Brown
1 sibling, 0 replies; 11+ messages in thread
From: Mark Brown @ 2026-10-29 11:10 UTC (permalink / raw)
To: Tristan Madani
Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai, patches,
linux-sound, linux-kernel, stable, Tristan Madani
[-- Attachment #1: Type: text/plain, Size: 700 bytes --]
On Thu, Oct 29, 2026 at 10:25:15AM +0000, Tristan Madani wrote:
> From: Tristan Madani <tristan@talencesecurity.com>
>
> wm8994_component_probe() schedules several delayed works to handle jack
> detection and microphone status polling. If the component is removed or
> probe fails after these works are scheduled, they can execute after
> resources are freed.
You've taken what was previously a series of 4 patches with only v1
posted, resent only two of the patches individually and for some reason
incremented the version to v9. This all makes things really confusing
to track for both me and my tooling. Please resend the full series as a
single series, with all of the patches.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v10] ASoC: wm8994: drain delayed works on remove and probe error
2026-10-29 10:57 ` [PATCH v10] " Tristan Madani
@ 2026-10-29 11:18 ` Mark Brown
0 siblings, 0 replies; 11+ messages in thread
From: Mark Brown @ 2026-10-29 11:18 UTC (permalink / raw)
To: Tristan Madani
Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai, patches,
linux-sound, linux-kernel, stable, Tristan Madani
[-- Attachment #1: Type: text/plain, Size: 662 bytes --]
On Thu, Oct 29, 2026 at 10:57:49AM +0000, Tristan Madani wrote:
> From: Tristan Madani <tristan@talencesecurity.com>
>
> wm8994_component_probe() schedules several delayed works to handle jack
> detection and microphone status polling. If the component is removed or
> probe fails after these works are scheduled, they can execute after
> resources are freed.
Please don't send new patches in reply to old patches or serieses, this
makes it harder for both people and tools to understand what is going
on - it can bury things in mailboxes and make it difficult to keep track
of what current patches are, both for the new patches and the old ones.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-10-29 11:18 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-26 11:22 [PATCH 0/4] ASoC: cancel pending delayed works on component remove Tristan Madani
2026-10-26 11:22 ` [PATCH 1/4] ASoC: rt5668: " Tristan Madani
2026-10-26 11:22 ` [PATCH 2/4] ASoC: rt5659: cancel jack_detect_work " Tristan Madani
2026-10-26 19:16 ` Mark Brown
2026-10-26 11:22 ` [PATCH 3/4] ASoC: twl6040: cancel headset jack work " Tristan Madani
2026-10-26 11:22 ` [PATCH 4/4] ASoC: wm8994: drain all delayed works " Tristan Madani
2026-10-26 19:16 ` Mark Brown
2026-10-29 10:25 ` [PATCH v9] ASoC: wm8994: drain delayed works on remove and probe error Tristan Madani
2026-10-29 10:57 ` [PATCH v10] " Tristan Madani
2026-10-29 11:18 ` Mark Brown
2026-10-29 11:10 ` [PATCH v9] " Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®