From: Cássio Gabriel Date: Thu, 14 May 2026 13:52:35 +0000 (-0300) Subject: ASoC: mediatek: mt8189: Fix probe resource cleanup X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5404599c3292a12dfc6a3b604cebb5d51064f553;p=thirdparty%2Fkernel%2Flinux.git ASoC: mediatek: mt8189: Fix probe resource cleanup The MT8189 AFE probe assigns reserved memory with of_reserved_mem_device_init(), but only releases that assignment from .remove(). If probe fails after the reserved memory has been assigned, the assignment record is left behind. The probe path also uses pm_runtime_get_sync() without checking its return value. If runtime resume fails, pm_runtime_get_sync() leaves the usage count incremented and the driver continues initialization without the device being resumed. Use pm_runtime_resume_and_get() so resume errors abort probe without leaking a PM usage count. Finally, component registration failure currently jumps to a label that drops a runtime PM reference even though the temporary probe reference was already released. Return the component registration error directly, and do not drop an unmatched PM reference from .remove(). Fixes: 7eb153585598 ("ASoC: mediatek: mt8189: add platform driver") Signed-off-by: Cássio Gabriel Link: https://patch.msgid.link/20260514-asoc-mt8189-probe-cleanup-v1-1-ded733363281@gmail.com Signed-off-by: Mark Brown --- diff --git a/sound/soc/mediatek/mt8189/mt8189-afe-pcm.c b/sound/soc/mediatek/mt8189/mt8189-afe-pcm.c index 24b0c78815f61..77cf2b604f6ce 100644 --- a/sound/soc/mediatek/mt8189/mt8189-afe-pcm.c +++ b/sound/soc/mediatek/mt8189/mt8189-afe-pcm.c @@ -2351,9 +2351,13 @@ static int mt8189_afe_runtime_resume(struct device *dev) static int mt8189_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 */ - pm_runtime_get_sync(afe->dev); + 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); @@ -2417,6 +2421,11 @@ static const struct reg_sequence mt8189_cg_patch[] = { { AUDIO_TOP_CON4, 0x361c }, }; +static void mt8189_afe_release_reserved_mem(void *data) +{ + of_reserved_mem_device_release(data); +} + static int mt8189_afe_pcm_dev_probe(struct platform_device *pdev) { int ret, i; @@ -2431,8 +2440,15 @@ static int mt8189_afe_pcm_dev_probe(struct platform_device *pdev) return ret; ret = of_reserved_mem_device_init(dev); - if (ret) + if (ret) { dev_warn(dev, "failed to assign memory region: %d\n", ret); + } else { + ret = devm_add_action_or_reset(dev, + mt8189_afe_release_reserved_mem, + dev); + if (ret) + return ret; + } afe = devm_kzalloc(dev, sizeof(*afe), GFP_KERNEL); if (!afe) @@ -2533,18 +2549,22 @@ static int mt8189_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, &mt8189_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, mt8189_cg_patch, ARRAY_SIZE(mt8189_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); @@ -2563,12 +2583,12 @@ static int mt8189_afe_pcm_dev_probe(struct platform_device *pdev) afe->num_dai_drivers); if (ret) { dev_err(dev, "afe component err: %d\n", ret); - goto err_pm_disable; + return ret; } return 0; -err_pm_disable: +err_pm_put: pm_runtime_put_sync(dev); return ret; } @@ -2578,14 +2598,12 @@ static void mt8189_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)) mt8189_afe_runtime_suspend(dev); mt8189_afe_disable_main_clock(afe); /* disable afe clock */ mt8189_afe_disable_reg_rw_clk(afe); - of_reserved_mem_device_release(dev); } static const struct of_device_id mt8189_afe_pcm_dt_match[] = {