clk: mediatek: mt8192: Correctly unregister and free clocks on failure
authorAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Fri, 20 Jan 2023 09:20:31 +0000 (10:20 +0100)
committerStephen Boyd <sboyd@kernel.org>
Tue, 31 Jan 2023 00:44:40 +0000 (16:44 -0800)
If anything fails during probe of the clock controller(s), unregister
(and kfree!) whatever we have previously registered to leave with a
clean state and prevent leaks.

Fixes: 710573dee31b ("clk: mediatek: Add MT8192 basic clocks support")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Chen-Yu Tsai <wenst@chromium.org>
Reviewed-by: Markus Schneider-Pargmann <msp@baylibre.com>
Tested-by: Miles Chen <miles.chen@mediatek.com>
Link: https://lore.kernel.org/r/20230120092053.182923-2-angelogioacchino.delregno@collabora.com
Tested-by: Mingming Su <mingming.su@mediatek.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
drivers/clk/mediatek/clk-mt8192.c

index 0e88588b2c49fb42ff30a1d3877540f2c2e3eaeb..5196a366dd5597fd065c2ddcddbf3b51ea70caaa 100644 (file)
@@ -1100,27 +1100,64 @@ static int clk_mt8192_top_probe(struct platform_device *pdev)
        if (IS_ERR(base))
                return PTR_ERR(base);
 
-       mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), top_clk_data);
-       mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs), top_clk_data);
-       mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
-       mtk_clk_register_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), node, &mt8192_clk_lock,
-                              top_clk_data);
-       mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base, &mt8192_clk_lock,
-                                   top_clk_data);
-       mtk_clk_register_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), base, &mt8192_clk_lock,
-                                   top_clk_data);
-       r = mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), top_clk_data);
+       r = mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), top_clk_data);
        if (r)
                return r;
 
+       r = mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs), top_clk_data);
+       if (r)
+               goto unregister_fixed_clks;
+
+       r = mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
+       if (r)
+               goto unregister_early_factors;
+
+       r = mtk_clk_register_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), node,
+                                  &mt8192_clk_lock, top_clk_data);
+       if (r)
+               goto unregister_factors;
+
+       r = mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
+                                       &mt8192_clk_lock, top_clk_data);
+       if (r)
+               goto unregister_muxes;
+
+       r = mtk_clk_register_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), base,
+                                       &mt8192_clk_lock, top_clk_data);
+       if (r)
+               goto unregister_top_composites;
+
+       r = mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), top_clk_data);
+       if (r)
+               goto unregister_adj_divs_composites;
+
        r = clk_mt8192_reg_mfg_mux_notifier(&pdev->dev,
                                            top_clk_data->hws[CLK_TOP_MFG_PLL_SEL]->clk);
        if (r)
-               return r;
-
+               goto unregister_gates;
 
-       return of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
+       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, top_clk_data);
+       if (r)
+               goto unregister_gates;
+
+       return 0;
+
+unregister_gates:
+       mtk_clk_unregister_gates(top_clks, ARRAY_SIZE(top_clks), top_clk_data);
+unregister_adj_divs_composites:
+       mtk_clk_unregister_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), top_clk_data);
+unregister_top_composites:
+       mtk_clk_unregister_composites(top_muxes, ARRAY_SIZE(top_muxes), top_clk_data);
+unregister_muxes:
+       mtk_clk_unregister_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), top_clk_data);
+unregister_factors:
+       mtk_clk_unregister_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
+unregister_early_factors:
+       mtk_clk_unregister_factors(top_early_divs, ARRAY_SIZE(top_early_divs), top_clk_data);
+unregister_fixed_clks:
+       mtk_clk_unregister_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
                                      top_clk_data);
+       return r;
 }
 
 static int clk_mt8192_infra_probe(struct platform_device *pdev)
@@ -1139,14 +1176,16 @@ static int clk_mt8192_infra_probe(struct platform_device *pdev)
 
        r = mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
        if (r)
-               goto free_clk_data;
+               goto unregister_gates;
 
        r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
        if (r)
-               goto free_clk_data;
+               goto unregister_gates;
 
        return r;
 
+unregister_gates:
+       mtk_clk_unregister_gates(infra_clks, ARRAY_SIZE(infra_clks), clk_data);
 free_clk_data:
        mtk_free_clk_data(clk_data);
        return r;
@@ -1168,10 +1207,12 @@ static int clk_mt8192_peri_probe(struct platform_device *pdev)
 
        r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
        if (r)
-               goto free_clk_data;
+               goto unregister_gates;
 
        return r;
 
+unregister_gates:
+       mtk_clk_unregister_gates(peri_clks, ARRAY_SIZE(peri_clks), clk_data);
 free_clk_data:
        mtk_free_clk_data(clk_data);
        return r;
@@ -1194,10 +1235,12 @@ static int clk_mt8192_apmixed_probe(struct platform_device *pdev)
 
        r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
        if (r)
-               goto free_clk_data;
+               goto unregister_gates;
 
        return r;
 
+unregister_gates:
+       mtk_clk_unregister_gates(apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data);
 free_clk_data:
        mtk_free_clk_data(clk_data);
        return r;