Skip to content

Commit

Permalink
clk: mediatek: mt8192: Correctly unregister and free clocks on failure
Browse files Browse the repository at this point in the history
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: 710573d ("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>
  • Loading branch information
AngeloGioacchino Del Regno authored and Stephen Boyd committed Jan 31, 2023
1 parent 1b929c0 commit 0cbe126
Showing 1 changed file with 60 additions and 17 deletions.
77 changes: 60 additions & 17 deletions drivers/clk/mediatek/clk-mt8192.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down

0 comments on commit 0cbe126

Please sign in to comment.