diff mbox

[RESEND,1/2] cpufreq: imx6q: Drop devm_clk/regulator_get usage

Message ID 1400083344-20042-1-git-send-email-p.zabel@pengutronix.de (mailing list archive)
State Accepted, archived
Headers show

Commit Message

Philipp Zabel May 14, 2014, 4:02 p.m. UTC
This driver is using devres managed calls incorrectly, giving the cpu0
device as first parameter instead of the cpufreq platform device.
This results in resources not being freed if the cpufreq platform device
is unbound, for example if probing has to be deferred for a missing
regulator.
Supporting probe deferral properly is a prerequisite to enabling the
internal LDO bypass on i.MX6 and regulating the CPU voltage with an
external regulator.

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Shawn Guo <shawn.guo@freescale.com>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
Resent to linux-pm@vger.kernel.org instead of cpufreq@vger.kernel.org.
---
 drivers/cpufreq/imx6q-cpufreq.c | 53 ++++++++++++++++++++++++++++++-----------
 1 file changed, 39 insertions(+), 14 deletions(-)

Comments

Rafael J. Wysocki May 19, 2014, 11:23 p.m. UTC | #1
On Wednesday, May 14, 2014 06:02:23 PM Philipp Zabel wrote:
> This driver is using devres managed calls incorrectly, giving the cpu0
> device as first parameter instead of the cpufreq platform device.
> This results in resources not being freed if the cpufreq platform device
> is unbound, for example if probing has to be deferred for a missing
> regulator.
> Supporting probe deferral properly is a prerequisite to enabling the
> internal LDO bypass on i.MX6 and regulating the CPU voltage with an
> external regulator.
> 
> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
> Acked-by: Shawn Guo <shawn.guo@freescale.com>
> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>

Both patches queued up for 3.16, thanks!

> ---
> Resent to linux-pm@vger.kernel.org instead of cpufreq@vger.kernel.org.
> ---
>  drivers/cpufreq/imx6q-cpufreq.c | 53 ++++++++++++++++++++++++++++++-----------
>  1 file changed, 39 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
> index e27fca8..92a82ec 100644
> --- a/drivers/cpufreq/imx6q-cpufreq.c
> +++ b/drivers/cpufreq/imx6q-cpufreq.c
> @@ -170,25 +170,25 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
>  		return -ENOENT;
>  	}
>  
> -	arm_clk = devm_clk_get(cpu_dev, "arm");
> -	pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys");
> -	pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw");
> -	step_clk = devm_clk_get(cpu_dev, "step");
> -	pll2_pfd2_396m_clk = devm_clk_get(cpu_dev, "pll2_pfd2_396m");
> +	arm_clk = clk_get(cpu_dev, "arm");
> +	pll1_sys_clk = clk_get(cpu_dev, "pll1_sys");
> +	pll1_sw_clk = clk_get(cpu_dev, "pll1_sw");
> +	step_clk = clk_get(cpu_dev, "step");
> +	pll2_pfd2_396m_clk = clk_get(cpu_dev, "pll2_pfd2_396m");
>  	if (IS_ERR(arm_clk) || IS_ERR(pll1_sys_clk) || IS_ERR(pll1_sw_clk) ||
>  	    IS_ERR(step_clk) || IS_ERR(pll2_pfd2_396m_clk)) {
>  		dev_err(cpu_dev, "failed to get clocks\n");
>  		ret = -ENOENT;
> -		goto put_node;
> +		goto put_clk;
>  	}
>  
> -	arm_reg = devm_regulator_get(cpu_dev, "arm");
> -	pu_reg = devm_regulator_get(cpu_dev, "pu");
> -	soc_reg = devm_regulator_get(cpu_dev, "soc");
> +	arm_reg = regulator_get(cpu_dev, "arm");
> +	pu_reg = regulator_get(cpu_dev, "pu");
> +	soc_reg = regulator_get(cpu_dev, "soc");
>  	if (IS_ERR(arm_reg) || IS_ERR(pu_reg) || IS_ERR(soc_reg)) {
>  		dev_err(cpu_dev, "failed to get regulators\n");
>  		ret = -ENOENT;
> -		goto put_node;
> +		goto put_reg;
>  	}
>  
>  	/*
> @@ -201,21 +201,21 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
>  		ret = of_init_opp_table(cpu_dev);
>  		if (ret < 0) {
>  			dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
> -			goto put_node;
> +			goto put_reg;
>  		}
>  
>  		num = dev_pm_opp_get_opp_count(cpu_dev);
>  		if (num < 0) {
>  			ret = num;
>  			dev_err(cpu_dev, "no OPP table is found: %d\n", ret);
> -			goto put_node;
> +			goto put_reg;
>  		}
>  	}
>  
>  	ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
>  	if (ret) {
>  		dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
> -		goto put_node;
> +		goto put_reg;
>  	}
>  
>  	/* Make imx6_soc_volt array's size same as arm opp number */
> @@ -301,7 +301,24 @@ soc_opp_out:
>  
>  free_freq_table:
>  	dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
> -put_node:
> +put_reg:
> +	if (!IS_ERR(arm_reg))
> +		regulator_put(arm_reg);
> +	if (!IS_ERR(pu_reg))
> +		regulator_put(pu_reg);
> +	if (!IS_ERR(soc_reg))
> +		regulator_put(soc_reg);
> +put_clk:
> +	if (!IS_ERR(arm_clk))
> +		clk_put(arm_clk);
> +	if (!IS_ERR(pll1_sys_clk))
> +		clk_put(pll1_sys_clk);
> +	if (!IS_ERR(pll1_sw_clk))
> +		clk_put(pll1_sw_clk);
> +	if (!IS_ERR(step_clk))
> +		clk_put(step_clk);
> +	if (!IS_ERR(pll2_pfd2_396m_clk))
> +		clk_put(pll2_pfd2_396m_clk);
>  	of_node_put(np);
>  	return ret;
>  }
> @@ -310,6 +327,14 @@ static int imx6q_cpufreq_remove(struct platform_device *pdev)
>  {
>  	cpufreq_unregister_driver(&imx6q_cpufreq_driver);
>  	dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
> +	regulator_put(arm_reg);
> +	regulator_put(pu_reg);
> +	regulator_put(soc_reg);
> +	clk_put(arm_clk);
> +	clk_put(pll1_sys_clk);
> +	clk_put(pll1_sw_clk);
> +	clk_put(step_clk);
> +	clk_put(pll2_pfd2_396m_clk);
>  
>  	return 0;
>  }
>
diff mbox

Patch

diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index e27fca8..92a82ec 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -170,25 +170,25 @@  static int imx6q_cpufreq_probe(struct platform_device *pdev)
 		return -ENOENT;
 	}
 
-	arm_clk = devm_clk_get(cpu_dev, "arm");
-	pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys");
-	pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw");
-	step_clk = devm_clk_get(cpu_dev, "step");
-	pll2_pfd2_396m_clk = devm_clk_get(cpu_dev, "pll2_pfd2_396m");
+	arm_clk = clk_get(cpu_dev, "arm");
+	pll1_sys_clk = clk_get(cpu_dev, "pll1_sys");
+	pll1_sw_clk = clk_get(cpu_dev, "pll1_sw");
+	step_clk = clk_get(cpu_dev, "step");
+	pll2_pfd2_396m_clk = clk_get(cpu_dev, "pll2_pfd2_396m");
 	if (IS_ERR(arm_clk) || IS_ERR(pll1_sys_clk) || IS_ERR(pll1_sw_clk) ||
 	    IS_ERR(step_clk) || IS_ERR(pll2_pfd2_396m_clk)) {
 		dev_err(cpu_dev, "failed to get clocks\n");
 		ret = -ENOENT;
-		goto put_node;
+		goto put_clk;
 	}
 
-	arm_reg = devm_regulator_get(cpu_dev, "arm");
-	pu_reg = devm_regulator_get(cpu_dev, "pu");
-	soc_reg = devm_regulator_get(cpu_dev, "soc");
+	arm_reg = regulator_get(cpu_dev, "arm");
+	pu_reg = regulator_get(cpu_dev, "pu");
+	soc_reg = regulator_get(cpu_dev, "soc");
 	if (IS_ERR(arm_reg) || IS_ERR(pu_reg) || IS_ERR(soc_reg)) {
 		dev_err(cpu_dev, "failed to get regulators\n");
 		ret = -ENOENT;
-		goto put_node;
+		goto put_reg;
 	}
 
 	/*
@@ -201,21 +201,21 @@  static int imx6q_cpufreq_probe(struct platform_device *pdev)
 		ret = of_init_opp_table(cpu_dev);
 		if (ret < 0) {
 			dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
-			goto put_node;
+			goto put_reg;
 		}
 
 		num = dev_pm_opp_get_opp_count(cpu_dev);
 		if (num < 0) {
 			ret = num;
 			dev_err(cpu_dev, "no OPP table is found: %d\n", ret);
-			goto put_node;
+			goto put_reg;
 		}
 	}
 
 	ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
 	if (ret) {
 		dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
-		goto put_node;
+		goto put_reg;
 	}
 
 	/* Make imx6_soc_volt array's size same as arm opp number */
@@ -301,7 +301,24 @@  soc_opp_out:
 
 free_freq_table:
 	dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
-put_node:
+put_reg:
+	if (!IS_ERR(arm_reg))
+		regulator_put(arm_reg);
+	if (!IS_ERR(pu_reg))
+		regulator_put(pu_reg);
+	if (!IS_ERR(soc_reg))
+		regulator_put(soc_reg);
+put_clk:
+	if (!IS_ERR(arm_clk))
+		clk_put(arm_clk);
+	if (!IS_ERR(pll1_sys_clk))
+		clk_put(pll1_sys_clk);
+	if (!IS_ERR(pll1_sw_clk))
+		clk_put(pll1_sw_clk);
+	if (!IS_ERR(step_clk))
+		clk_put(step_clk);
+	if (!IS_ERR(pll2_pfd2_396m_clk))
+		clk_put(pll2_pfd2_396m_clk);
 	of_node_put(np);
 	return ret;
 }
@@ -310,6 +327,14 @@  static int imx6q_cpufreq_remove(struct platform_device *pdev)
 {
 	cpufreq_unregister_driver(&imx6q_cpufreq_driver);
 	dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
+	regulator_put(arm_reg);
+	regulator_put(pu_reg);
+	regulator_put(soc_reg);
+	clk_put(arm_clk);
+	clk_put(pll1_sys_clk);
+	clk_put(pll1_sw_clk);
+	clk_put(step_clk);
+	clk_put(pll2_pfd2_396m_clk);
 
 	return 0;
 }