ASoC: codecs: rk3328: Use managed GPIO and clock helpers

rk3328_platform_probe() acquires the mute GPIO with gpiod_get_optional()
but never releases it. It also enables mclk and pclk manually while
relying on probe error labels for unwind, and the driver has no platform
remove callback to disable those clocks after a successful unbind.

This path has already needed fixes for missing clock unwinds on probe
errors. Use devm_gpiod_get_optional() and devm_clk_get_enabled() so the
GPIO and enabled clock lifetimes are tied to the device. This removes the
manual error labels and makes both probe failure and driver unbind follow
the normal devres cleanup path.

Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
Link: https://patch.msgid.link/20260525-asoc-rk3328-devm-resources-v1-1-2abde0006f89@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Cássio Gabriel 2026-05-25 14:18:03 -03:00 committed by Mark Brown
parent 2d90ecdfa3
commit 0cf3489bba
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -425,7 +425,6 @@ static int rk3328_platform_probe(struct platform_device *pdev)
struct rk3328_codec_priv *rk3328;
struct regmap *grf;
void __iomem *base;
int ret = 0;
rk3328 = devm_kzalloc(&pdev->dev, sizeof(*rk3328), GFP_KERNEL);
if (!rk3328)
@ -441,14 +440,13 @@ static int rk3328_platform_probe(struct platform_device *pdev)
regmap_write(grf, RK3328_GRF_SOC_CON2,
(BIT(14) << 16 | BIT(14)));
ret = of_property_read_u32(rk3328_np, "spk-depop-time-ms",
&rk3328->spk_depop_time);
if (ret < 0) {
if (of_property_read_u32(rk3328_np, "spk-depop-time-ms",
&rk3328->spk_depop_time)) {
dev_info(&pdev->dev, "spk_depop_time use default value.\n");
rk3328->spk_depop_time = 200;
}
rk3328->mute = gpiod_get_optional(&pdev->dev, "mute", GPIOD_OUT_HIGH);
rk3328->mute = devm_gpiod_get_optional(&pdev->dev, "mute", GPIOD_OUT_HIGH);
if (IS_ERR(rk3328->mute))
return PTR_ERR(rk3328->mute);
/*
@ -461,57 +459,31 @@ static int rk3328_platform_probe(struct platform_device *pdev)
regmap_write(grf, RK3328_GRF_SOC_CON10, BIT(17) | BIT(1));
}
rk3328->mclk = devm_clk_get(&pdev->dev, "mclk");
rk3328->mclk = devm_clk_get_enabled(&pdev->dev, "mclk");
if (IS_ERR(rk3328->mclk))
return PTR_ERR(rk3328->mclk);
ret = clk_prepare_enable(rk3328->mclk);
if (ret)
return ret;
clk_set_rate(rk3328->mclk, INITIAL_FREQ);
rk3328->pclk = devm_clk_get(&pdev->dev, "pclk");
if (IS_ERR(rk3328->pclk)) {
dev_err(&pdev->dev, "can't get acodec pclk\n");
ret = PTR_ERR(rk3328->pclk);
goto err_unprepare_mclk;
}
ret = clk_prepare_enable(rk3328->pclk);
if (ret < 0) {
dev_err(&pdev->dev, "failed to enable acodec pclk\n");
goto err_unprepare_mclk;
}
rk3328->pclk = devm_clk_get_enabled(&pdev->dev, "pclk");
if (IS_ERR(rk3328->pclk))
return dev_err_probe(&pdev->dev, PTR_ERR(rk3328->pclk),
"failed to get or enable acodec pclk\n");
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base)) {
ret = PTR_ERR(base);
goto err_unprepare_pclk;
}
if (IS_ERR(base))
return PTR_ERR(base);
rk3328->regmap = devm_regmap_init_mmio(&pdev->dev, base,
&rk3328_codec_regmap_config);
if (IS_ERR(rk3328->regmap)) {
ret = PTR_ERR(rk3328->regmap);
goto err_unprepare_pclk;
}
if (IS_ERR(rk3328->regmap))
return PTR_ERR(rk3328->regmap);
platform_set_drvdata(pdev, rk3328);
ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_rk3328,
return devm_snd_soc_register_component(&pdev->dev, &soc_codec_rk3328,
rk3328_dai,
ARRAY_SIZE(rk3328_dai));
if (ret)
goto err_unprepare_pclk;
return 0;
err_unprepare_pclk:
clk_disable_unprepare(rk3328->pclk);
err_unprepare_mclk:
clk_disable_unprepare(rk3328->mclk);
return ret;
}
static const struct of_device_id rk3328_codec_of_match[] __maybe_unused = {