]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ASoC: codecs: rk3328: Use managed GPIO and clock helpers
authorCássio Gabriel <cassiogabrielcontato@gmail.com>
Mon, 25 May 2026 17:18:03 +0000 (14:18 -0300)
committerMark Brown <broonie@kernel.org>
Tue, 2 Jun 2026 15:06:48 +0000 (16:06 +0100)
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>
sound/soc/codecs/rk3328_codec.c

index 9697aefc6e030e101ad833a46a4a206f8b0e7c10..5871b5a81975784a9fe00d3f51bb9a7169634527 100644 (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 = {