Skip to content

Commit e383531

Browse files
CassivsGabriellisbroonie
authored andcommitted
ASoC: mediatek: mt8196: Fix probe resource cleanup
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: 57513aa ("ASoC: mediatek: mt8196: add platform driver") Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com> Link: https://patch.msgid.link/20260517-asoc-mt8196-probe-cleanup-v1-1-a5d26949d7fe@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent e001484 commit e383531

1 file changed

Lines changed: 30 additions & 14 deletions

File tree

sound/soc/mediatek/mt8196/mt8196-afe-pcm.c

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,13 +2242,16 @@ static int mt8196_afe_runtime_resume(struct device *dev)
22422242
static int mt8196_afe_component_probe(struct snd_soc_component *component)
22432243
{
22442244
struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
2245+
int ret;
2246+
2247+
/* enable clock for regcache get default value from hw */
2248+
ret = pm_runtime_resume_and_get(afe->dev);
2249+
if (ret)
2250+
return dev_err_probe(afe->dev, ret, "failed to resume device\n");
2251+
2252+
mtk_afe_add_sub_dai_control(component);
2253+
pm_runtime_put_sync(afe->dev);
22452254

2246-
if (component) {
2247-
/* enable clock for regcache get default value from hw */
2248-
pm_runtime_get_sync(afe->dev);
2249-
mtk_afe_add_sub_dai_control(component);
2250-
pm_runtime_put_sync(afe->dev);
2251-
}
22522255
return 0;
22532256
}
22542257

@@ -2306,6 +2309,11 @@ static const struct reg_sequence mt8196_cg_patch[] = {
23062309
{ AUDIO_TOP_CON4, 0x361c },
23072310
};
23082311

2312+
static void mt8196_afe_release_reserved_mem(void *data)
2313+
{
2314+
of_reserved_mem_device_release(data);
2315+
}
2316+
23092317
static int mt8196_afe_pcm_dev_probe(struct platform_device *pdev)
23102318
{
23112319
int ret, i;
@@ -2320,8 +2328,13 @@ static int mt8196_afe_pcm_dev_probe(struct platform_device *pdev)
23202328
return ret;
23212329

23222330
ret = of_reserved_mem_device_init(dev);
2323-
if (ret)
2331+
if (ret) {
23242332
dev_err(dev, "failed to assign memory region: %d\n", ret);
2333+
} else {
2334+
ret = devm_add_action_or_reset(dev, mt8196_afe_release_reserved_mem, dev);
2335+
if (ret)
2336+
return ret;
2337+
}
23252338

23262339
afe = devm_kzalloc(dev, sizeof(*afe), GFP_KERNEL);
23272340
if (!afe)
@@ -2422,18 +2435,22 @@ static int mt8196_afe_pcm_dev_probe(struct platform_device *pdev)
24222435
dev_pm_syscore_device(dev, true);
24232436

24242437
/* enable clock for regcache get default value from hw */
2425-
pm_runtime_get_sync(dev);
2438+
ret = pm_runtime_resume_and_get(dev);
2439+
if (ret)
2440+
return dev_err_probe(dev, ret, "failed to resume device\n");
24262441

24272442
afe->regmap = devm_regmap_init_mmio(dev, afe->base_addr,
24282443
&mt8196_afe_regmap_config);
2429-
if (IS_ERR(afe->regmap))
2430-
return PTR_ERR(afe->regmap);
2444+
if (IS_ERR(afe->regmap)) {
2445+
ret = PTR_ERR(afe->regmap);
2446+
goto err_pm_put;
2447+
}
24312448

24322449
ret = regmap_register_patch(afe->regmap, mt8196_cg_patch,
24332450
ARRAY_SIZE(mt8196_cg_patch));
24342451
if (ret < 0) {
24352452
dev_err(dev, "Failed to apply cg patch\n");
2436-
goto err_pm_disable;
2453+
goto err_pm_put;
24372454
}
24382455

24392456
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)
24522469
afe->num_dai_drivers);
24532470
if (ret) {
24542471
dev_err(dev, "afe component err\n");
2455-
goto err_pm_disable;
2472+
return ret;
24562473
}
24572474

24582475
return 0;
24592476

2460-
err_pm_disable:
2477+
err_pm_put:
24612478
pm_runtime_put_sync(dev);
24622479
return ret;
24632480
}
@@ -2467,7 +2484,6 @@ static void mt8196_afe_pcm_dev_remove(struct platform_device *pdev)
24672484
struct mtk_base_afe *afe = platform_get_drvdata(pdev);
24682485
struct device *dev = &pdev->dev;
24692486

2470-
pm_runtime_put_sync(dev);
24712487
if (!pm_runtime_status_suspended(dev))
24722488
mt8196_afe_runtime_suspend(dev);
24732489

0 commit comments

Comments
 (0)