[PATCH v2] ASoC: mediatek: mt2701: initialize IRQ dependencies before requesting it
From: Myeonghun Pak
Date: Tue Nov 10 2026 - 00:09:01 EST
The ASYS IRQ is registered before the regmap, memif arrays and clocks
are initialized. It also remains registered while remove and probe
unwind disable those clocks, allowing the handler to run without its
dependencies.
Request the IRQ after initializing handler state and successfully
resuming the device. Release it before PM and clock teardown on component
registration failure and remove. Check runtime resume errors and avoid
running clock cleanup twice if the manual resume path has already
unwound a failed clock enable.
This issue was found by our static analysis tool under development.
Fixes: 43a6a7e71063 ("ASoC: mediatek: add mt2701 platform driver implementation.")
Co-developed-by: Ijae Kim <ae878000@xxxxxxxxx>
Signed-off-by: Ijae Kim <ae878000@xxxxxxxxx>
Signed-off-by: Myeonghun Pak <mhun512@xxxxxxxxx>
---
No hardware testing.
Changes in v2:
- Rebase onto current code.
- Replace devres actions with explicit IRQ release.
- Check resume errors and preserve CONFIG_PM-disabled unwind.
sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 27 ++++++++++++++++++---------
1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
index 3c5a76591..4054083e3 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
@@ -1620,11 +1620,6 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
if (irq_id < 0)
return irq_id;
- ret = devm_request_irq(dev, irq_id, mt2701_asys_isr,
- IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
- if (ret)
- return ret;
-
afe->regmap = syscon_node_to_regmap(dev->parent->of_node);
if (IS_ERR(afe->regmap)) {
dev_err(dev, "could not get regmap from parent\n");
@@ -1684,15 +1679,22 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
if (!pm_runtime_enabled(dev)) {
ret = mt2701_afe_runtime_resume(dev);
if (ret)
- goto err_pm_disable;
+ return ret;
}
- pm_runtime_get_sync(dev);
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret < 0)
+ goto err_pm_disable;
+
+ ret = devm_request_irq(dev, irq_id, mt2701_asys_isr,
+ IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
+ if (ret)
+ goto err_platform;
ret = devm_snd_soc_register_component(&pdev->dev, &mtk_afe_pcm_platform,
NULL, 0);
if (ret) {
dev_warn(dev, "err_platform\n");
- goto err_platform;
+ goto err_free_irq;
}
ret = devm_snd_soc_register_component(&pdev->dev,
@@ -1701,21 +1703,28 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
ARRAY_SIZE(mt2701_afe_pcm_dais));
if (ret) {
dev_warn(dev, "err_dai_component\n");
- goto err_platform;
+ goto err_free_irq;
}
return 0;
+err_free_irq:
+ devm_free_irq(dev, irq_id, afe);
err_platform:
pm_runtime_put_sync(dev);
err_pm_disable:
pm_runtime_disable(dev);
+ if (!pm_runtime_status_suspended(dev))
+ mt2701_afe_runtime_suspend(dev);
return ret;
}
static void mt2701_afe_pcm_dev_remove(struct platform_device *pdev)
{
+ struct mtk_base_afe *afe = platform_get_drvdata(pdev);
+
+ devm_free_irq(&pdev->dev, platform_get_irq_byname(pdev, "asys"), afe);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))