public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] clk: st: clkgen-pll: Add cleaup in clkgen_c32_pll_setup()
@ 2026-01-15  4:44 Haoxiang Li
  2026-01-15 12:27 ` Markus Elfring
  2026-01-15 12:34 ` Brian Masney
  0 siblings, 2 replies; 3+ messages in thread
From: Haoxiang Li @ 2026-01-15  4:44 UTC (permalink / raw)
  To: mturquette, sboyd, bmasney; +Cc: linux-clk, linux-kernel, Haoxiang Li

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@isrc.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


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] clk: st: clkgen-pll: Add cleaup in clkgen_c32_pll_setup()
  2026-01-15  4:44 [PATCH v2] clk: st: clkgen-pll: Add cleaup in clkgen_c32_pll_setup() Haoxiang Li
@ 2026-01-15 12:27 ` Markus Elfring
  2026-01-15 12:34 ` Brian Masney
  1 sibling, 0 replies; 3+ messages in thread
From: Markus Elfring @ 2026-01-15 12:27 UTC (permalink / raw)
  To: Haoxiang Li, linux-clk, Brian Masney, Michael Turquette,
	Stephen Boyd; +Cc: LKML

> In clkgen_c32_pll_setup(), there exists several leaks if errors ouccers.

                                                                  occur?


> 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().

                                () calls?  cleanup?

Please avoid such typos at more places (including the summary phrase).


> Add a while to do the cleaup for clkgen_odf_register().
> Use distinct variable names for two register calls' return values.

I would find such sentences a bit nicer with a formatting for enumerations.

Regards,
Markus

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] clk: st: clkgen-pll: Add cleaup in clkgen_c32_pll_setup()
  2026-01-15  4:44 [PATCH v2] clk: st: clkgen-pll: Add cleaup in clkgen_c32_pll_setup() Haoxiang Li
  2026-01-15 12:27 ` Markus Elfring
@ 2026-01-15 12:34 ` Brian Masney
  1 sibling, 0 replies; 3+ messages in thread
From: Brian Masney @ 2026-01-15 12:34 UTC (permalink / raw)
  To: Haoxiang Li; +Cc: mturquette, sboyd, linux-clk, linux-kernel

Hi Haoxiang,

Thanks for the patch!

On Thu, Jan 15, 2026 at 12:44:39PM +0800, Haoxiang Li wrote:
> 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@isrc.iscas.ac.cn>

There's a lot going on in this patch, and it's hard for someone else to
review. Can you break this up into several patches? For example:

- The kfree(pll_name) should be in it's own patch, with it's own
  explanation.

- It would help if the rename of 'clk' to 'pll_clk' was in it's own
  patch. Along with the rename of 'clk' to 'odf_clk' in a separate
  patch. You can say in these two commit messages that the renames
  are in preparation for cleaning up some memory leaks.

I'll pick up below with more suggestions.

> ---
> 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;

This could also be it's own cleanup patch.

>  
>  	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--) {

odf is not initialized at the top of the function. It would be good to
default it to 0. I know it is in the for loop, but just to be safe.

> +		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));

Generally declarations go at the top of the function, or the top of an
if / while.

Since you are making changes to the top of the function, it would be
good to add another patch to put the variables in reverse Christmas tree
order (longest to shortest by name).

> +
> +       clk_unregister(pll_clk);

The clk_unregister() can also be it's own cleanup patch.

> +       kfree(pll);
> +err_unmap:
> +       if (pll_base)
> +               iounmap(pll_base);

The iounmap() can also be in it's own patch like you had in v1.

You may end up with 6-8 patches, but each one will be small, boring, and
it will make it easier for others review.

Thanks!

Brian


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-01-15 12:34 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-15  4:44 [PATCH v2] clk: st: clkgen-pll: Add cleaup in clkgen_c32_pll_setup() Haoxiang Li
2026-01-15 12:27 ` Markus Elfring
2026-01-15 12:34 ` Brian Masney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox