[PATCH] ASoC: mediatek: mt8196: Fix probe resource cleanup
Cássio Gabriel
cassiogabrielcontato at gmail.com
Sun May 17 19:41:07 PDT 2026
The MT8196 AFE probe assigns reserved memory with
of_reserved_mem_device_init(), but never releases it.
This leaks the reserved memory assignment on driver
removal and on later probe failures.
The same probe path also uses unchecked pm_runtime_get_sync() calls.
A failure while resuming the device can leave the runtime PM usage
count in an unexpected state.
The regmap error path returns directly while the device is still
runtime active, and the remove path drops a runtime PM reference even
though successful probe has already released its temporary reference.
Register a devm cleanup action for the reserved memory assignment,
use pm_runtime_resume_and_get(), and only drop runtime PM references
on paths where they are actually held.
Fixes: 57513aabfe5b ("ASoC: mediatek: mt8196: add platform driver")
Signed-off-by: Cássio Gabriel <cassiogabrielcontato at gmail.com>
---
sound/soc/mediatek/mt8196/mt8196-afe-pcm.c | 44 ++++++++++++++++++++----------
1 file changed, 30 insertions(+), 14 deletions(-)
diff --git a/sound/soc/mediatek/mt8196/mt8196-afe-pcm.c b/sound/soc/mediatek/mt8196/mt8196-afe-pcm.c
index 511e888567be..a1ae8322d8b6 100644
--- a/sound/soc/mediatek/mt8196/mt8196-afe-pcm.c
+++ b/sound/soc/mediatek/mt8196/mt8196-afe-pcm.c
@@ -2242,13 +2242,16 @@ static int mt8196_afe_runtime_resume(struct device *dev)
static int mt8196_afe_component_probe(struct snd_soc_component *component)
{
struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+ int ret;
+
+ /* enable clock for regcache get default value from hw */
+ ret = pm_runtime_resume_and_get(afe->dev);
+ if (ret)
+ return dev_err_probe(afe->dev, ret, "failed to resume device\n");
+
+ mtk_afe_add_sub_dai_control(component);
+ pm_runtime_put_sync(afe->dev);
- if (component) {
- /* enable clock for regcache get default value from hw */
- pm_runtime_get_sync(afe->dev);
- mtk_afe_add_sub_dai_control(component);
- pm_runtime_put_sync(afe->dev);
- }
return 0;
}
@@ -2306,6 +2309,11 @@ static const struct reg_sequence mt8196_cg_patch[] = {
{ AUDIO_TOP_CON4, 0x361c },
};
+static void mt8196_afe_release_reserved_mem(void *data)
+{
+ of_reserved_mem_device_release(data);
+}
+
static int mt8196_afe_pcm_dev_probe(struct platform_device *pdev)
{
int ret, i;
@@ -2320,8 +2328,13 @@ static int mt8196_afe_pcm_dev_probe(struct platform_device *pdev)
return ret;
ret = of_reserved_mem_device_init(dev);
- if (ret)
+ if (ret) {
dev_err(dev, "failed to assign memory region: %d\n", ret);
+ } else {
+ ret = devm_add_action_or_reset(dev, mt8196_afe_release_reserved_mem, dev);
+ if (ret)
+ return ret;
+ }
afe = devm_kzalloc(dev, sizeof(*afe), GFP_KERNEL);
if (!afe)
@@ -2422,18 +2435,22 @@ static int mt8196_afe_pcm_dev_probe(struct platform_device *pdev)
dev_pm_syscore_device(dev, true);
/* enable clock for regcache get default value from hw */
- pm_runtime_get_sync(dev);
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to resume device\n");
afe->regmap = devm_regmap_init_mmio(dev, afe->base_addr,
&mt8196_afe_regmap_config);
- if (IS_ERR(afe->regmap))
- return PTR_ERR(afe->regmap);
+ if (IS_ERR(afe->regmap)) {
+ ret = PTR_ERR(afe->regmap);
+ goto err_pm_put;
+ }
ret = regmap_register_patch(afe->regmap, mt8196_cg_patch,
ARRAY_SIZE(mt8196_cg_patch));
if (ret < 0) {
dev_err(dev, "Failed to apply cg patch\n");
- goto err_pm_disable;
+ goto err_pm_put;
}
regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &tmp_reg);
@@ -2452,12 +2469,12 @@ static int mt8196_afe_pcm_dev_probe(struct platform_device *pdev)
afe->num_dai_drivers);
if (ret) {
dev_err(dev, "afe component err\n");
- goto err_pm_disable;
+ return ret;
}
return 0;
-err_pm_disable:
+err_pm_put:
pm_runtime_put_sync(dev);
return ret;
}
@@ -2467,7 +2484,6 @@ static void mt8196_afe_pcm_dev_remove(struct platform_device *pdev)
struct mtk_base_afe *afe = platform_get_drvdata(pdev);
struct device *dev = &pdev->dev;
- pm_runtime_put_sync(dev);
if (!pm_runtime_status_suspended(dev))
mt8196_afe_runtime_suspend(dev);
---
base-commit: 2be19ed9535043fe6abd7ccfc9aac6b7ecaac842
change-id: 20260507-asoc-mt8196-probe-cleanup-222142d1000c
Best regards,
--
Cássio Gabriel <cassiogabrielcontato at gmail.com>
More information about the Linux-mediatek
mailing list