Commit 0cbe1269 authored by AngeloGioacchino Del Regno's avatar AngeloGioacchino Del Regno Committed by Stephen Boyd
Browse files

clk: mediatek: mt8192: Correctly unregister and free clocks on failure



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: 710573de ("clk: mediatek: Add MT8192 basic clocks support")
Signed-off-by: default avatarAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: default avatarChen-Yu Tsai <wenst@chromium.org>
Reviewed-by: default avatarMarkus Schneider-Pargmann <msp@baylibre.com>
Tested-by: default avatarMiles Chen <miles.chen@mediatek.com>
Link: https://lore.kernel.org/r/20230120092053.182923-2-angelogioacchino.delregno@collabora.com


Tested-by: default avatarMingming Su <mingming.su@mediatek.com>
Signed-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent 1b929c02
Loading
Loading
Loading
Loading
+60 −17
Original line number Diff line number Diff line
@@ -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;