sound/soc/mediatek/mt8196/mt8196-afe-pcm.c | 44 ++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 14 deletions(-)
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@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@gmail.com>
On Sun, 17 May 2026 23:41:07 -0300, Cássio Gabriel wrote:
> ASoC: mediatek: mt8196: Fix probe resource cleanup
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-7.2
Thanks!
[1/1] ASoC: mediatek: mt8196: Fix probe resource cleanup
https://git.kernel.org/broonie/sound/c/e38353138a09
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
© 2016 - 2026 Red Hat, Inc.