[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20260115044439.632676-1-lihaoxiang@isrc.iscas.ac.cn>
Date: Thu, 15 Jan 2026 12:44:39 +0800
From: Haoxiang Li <lihaoxiang@...c.iscas.ac.cn>
To: mturquette@...libre.com,
sboyd@...nel.org,
bmasney@...hat.com
Cc: linux-clk@...r.kernel.org,
linux-kernel@...r.kernel.org,
Haoxiang Li <lihaoxiang@...c.iscas.ac.cn>
Subject: [PATCH v2] clk: st: clkgen-pll: Add cleaup in clkgen_c32_pll_setup()
In clkgen_c32_pll_setup(), there exists several leaks if errors ouccers.
Add iounmap() to free the memory allocated by clkgen_get_register_base().
Add clk_unregister() and kfree to do the cleaup for clkgen_pll_register().
Add a while to do the cleaup for clkgen_odf_register().
Use distinct variable names for two register calls' return values.
Signed-off-by: Haoxiang Li <lihaoxiang@...c.iscas.ac.cn>
---
Changes in v2:
- Add several cleanups. Thanks, Brian!
- Modify the changelog.
---
drivers/clk/st/clkgen-pll.c | 44 +++++++++++++++++++++++++------------
1 file changed, 30 insertions(+), 14 deletions(-)
diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c
index c258ff87a171..100172f9fdf8 100644
--- a/drivers/clk/st/clkgen-pll.c
+++ b/drivers/clk/st/clkgen-pll.c
@@ -752,11 +752,10 @@ static struct clk * __init clkgen_odf_register(const char *parent_name,
return clk;
}
-
static void __init clkgen_c32_pll_setup(struct device_node *np,
struct clkgen_pll_data_clks *datac)
{
- struct clk *clk;
+ struct clk *pll_clk;
const char *parent_name, *pll_name;
void __iomem *pll_base;
int num_odfs, odf;
@@ -774,18 +773,18 @@ static void __init clkgen_c32_pll_setup(struct device_node *np,
of_clk_detect_critical(np, 0, &pll_flags);
- clk = clkgen_pll_register(parent_name, datac->data, pll_base, pll_flags,
+ pll_clk = clkgen_pll_register(parent_name, datac->data, pll_base, pll_flags,
np->name, datac->data->lock);
- if (IS_ERR(clk))
- return;
+ if (IS_ERR(pll_clk))
+ goto err_unmap;
- pll_name = __clk_get_name(clk);
+ pll_name = __clk_get_name(pll_clk);
num_odfs = datac->data->num_odfs;
clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
if (!clk_data)
- return;
+ goto err_pll_unregister;
clk_data->clk_num = num_odfs;
clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *),
@@ -795,7 +794,7 @@ static void __init clkgen_c32_pll_setup(struct device_node *np,
goto err;
for (odf = 0; odf < num_odfs; odf++) {
- struct clk *clk;
+ struct clk *odf_clk;
const char *clk_name;
unsigned long odf_flags = 0;
@@ -806,28 +805,45 @@ static void __init clkgen_c32_pll_setup(struct device_node *np,
if (of_property_read_string_index(np,
"clock-output-names",
odf, &clk_name))
- return;
+ goto err;
of_clk_detect_critical(np, odf, &odf_flags);
}
- clk = clkgen_odf_register(pll_name, pll_base, datac->data,
+ odf_clk = clkgen_odf_register(pll_name, pll_base, datac->data,
odf_flags, odf, &clkgena_c32_odf_lock,
clk_name);
- if (IS_ERR(clk))
- goto err;
+ if (IS_ERR(odf_clk))
+ goto err_odf_unregister;
- clk_data->clks[odf] = clk;
+ clk_data->clks[odf] = odf_clk;
}
of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
return;
+err_odf_unregister:
+ while (odf--) {
+ struct clk_gate *gate = to_clk_gate(__clk_get_hw(clk_data->clks[odf]));
+ struct clk_divider *div = to_clk_divider(__clk_get_hw(clk_data->clks[odf]));
+
+ clk_unregister_composite(clk_data->clks[odf]);
+ kfree(div);
+ kfree(gate);
+ }
err:
- kfree(pll_name);
kfree(clk_data->clks);
kfree(clk_data);
+err_pll_unregister:
+ struct clkgen_pll *pll = to_clkgen_pll(__clk_get_hw(pll_clk));
+
+ clk_unregister(pll_clk);
+ kfree(pll);
+err_unmap:
+ if (pll_base)
+ iounmap(pll_base);
}
+
static void __init clkgen_c32_pll0_setup(struct device_node *np)
{
clkgen_c32_pll_setup(np,
--
2.25.1
Powered by blists - more mailing lists