aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/imx6q-cpufreq.c
diff options
context:
space:
mode:
authorPhilipp Zabel <p.zabel@pengutronix.de>2014-05-14 12:02:23 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-05-16 19:32:15 -0400
commitf8269c19222550dd357e515673f628071880d64c (patch)
tree265159658442e42a23a28952651eb601f8965523 /drivers/cpufreq/imx6q-cpufreq.c
parente54173b4ed0fca1a5dce9911f54e71f2917d4869 (diff)
cpufreq: imx6q: Drop devm_clk/regulator_get usage
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> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq/imx6q-cpufreq.c')
-rw-r--r--drivers/cpufreq/imx6q-cpufreq.c53
1 files changed, 39 insertions, 14 deletions
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index e27fca86fe4f..92a82ec763c6 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)
170 return -ENOENT; 170 return -ENOENT;
171 } 171 }
172 172
173 arm_clk = devm_clk_get(cpu_dev, "arm"); 173 arm_clk = clk_get(cpu_dev, "arm");
174 pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys"); 174 pll1_sys_clk = clk_get(cpu_dev, "pll1_sys");
175 pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw"); 175 pll1_sw_clk = clk_get(cpu_dev, "pll1_sw");
176 step_clk = devm_clk_get(cpu_dev, "step"); 176 step_clk = clk_get(cpu_dev, "step");
177 pll2_pfd2_396m_clk = devm_clk_get(cpu_dev, "pll2_pfd2_396m"); 177 pll2_pfd2_396m_clk = clk_get(cpu_dev, "pll2_pfd2_396m");
178 if (IS_ERR(arm_clk) || IS_ERR(pll1_sys_clk) || IS_ERR(pll1_sw_clk) || 178 if (IS_ERR(arm_clk) || IS_ERR(pll1_sys_clk) || IS_ERR(pll1_sw_clk) ||
179 IS_ERR(step_clk) || IS_ERR(pll2_pfd2_396m_clk)) { 179 IS_ERR(step_clk) || IS_ERR(pll2_pfd2_396m_clk)) {
180 dev_err(cpu_dev, "failed to get clocks\n"); 180 dev_err(cpu_dev, "failed to get clocks\n");
181 ret = -ENOENT; 181 ret = -ENOENT;
182 goto put_node; 182 goto put_clk;
183 } 183 }
184 184
185 arm_reg = devm_regulator_get(cpu_dev, "arm"); 185 arm_reg = regulator_get(cpu_dev, "arm");
186 pu_reg = devm_regulator_get(cpu_dev, "pu"); 186 pu_reg = regulator_get(cpu_dev, "pu");
187 soc_reg = devm_regulator_get(cpu_dev, "soc"); 187 soc_reg = regulator_get(cpu_dev, "soc");
188 if (IS_ERR(arm_reg) || IS_ERR(pu_reg) || IS_ERR(soc_reg)) { 188 if (IS_ERR(arm_reg) || IS_ERR(pu_reg) || IS_ERR(soc_reg)) {
189 dev_err(cpu_dev, "failed to get regulators\n"); 189 dev_err(cpu_dev, "failed to get regulators\n");
190 ret = -ENOENT; 190 ret = -ENOENT;
191 goto put_node; 191 goto put_reg;
192 } 192 }
193 193
194 /* 194 /*
@@ -201,21 +201,21 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
201 ret = of_init_opp_table(cpu_dev); 201 ret = of_init_opp_table(cpu_dev);
202 if (ret < 0) { 202 if (ret < 0) {
203 dev_err(cpu_dev, "failed to init OPP table: %d\n", ret); 203 dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
204 goto put_node; 204 goto put_reg;
205 } 205 }
206 206
207 num = dev_pm_opp_get_opp_count(cpu_dev); 207 num = dev_pm_opp_get_opp_count(cpu_dev);
208 if (num < 0) { 208 if (num < 0) {
209 ret = num; 209 ret = num;
210 dev_err(cpu_dev, "no OPP table is found: %d\n", ret); 210 dev_err(cpu_dev, "no OPP table is found: %d\n", ret);
211 goto put_node; 211 goto put_reg;
212 } 212 }
213 } 213 }
214 214
215 ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); 215 ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
216 if (ret) { 216 if (ret) {
217 dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret); 217 dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
218 goto put_node; 218 goto put_reg;
219 } 219 }
220 220
221 /* Make imx6_soc_volt array's size same as arm opp number */ 221 /* Make imx6_soc_volt array's size same as arm opp number */
@@ -301,7 +301,24 @@ soc_opp_out:
301 301
302free_freq_table: 302free_freq_table:
303 dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); 303 dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
304put_node: 304put_reg:
305 if (!IS_ERR(arm_reg))
306 regulator_put(arm_reg);
307 if (!IS_ERR(pu_reg))
308 regulator_put(pu_reg);
309 if (!IS_ERR(soc_reg))
310 regulator_put(soc_reg);
311put_clk:
312 if (!IS_ERR(arm_clk))
313 clk_put(arm_clk);
314 if (!IS_ERR(pll1_sys_clk))
315 clk_put(pll1_sys_clk);
316 if (!IS_ERR(pll1_sw_clk))
317 clk_put(pll1_sw_clk);
318 if (!IS_ERR(step_clk))
319 clk_put(step_clk);
320 if (!IS_ERR(pll2_pfd2_396m_clk))
321 clk_put(pll2_pfd2_396m_clk);
305 of_node_put(np); 322 of_node_put(np);
306 return ret; 323 return ret;
307} 324}
@@ -310,6 +327,14 @@ static int imx6q_cpufreq_remove(struct platform_device *pdev)
310{ 327{
311 cpufreq_unregister_driver(&imx6q_cpufreq_driver); 328 cpufreq_unregister_driver(&imx6q_cpufreq_driver);
312 dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); 329 dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
330 regulator_put(arm_reg);
331 regulator_put(pu_reg);
332 regulator_put(soc_reg);
333 clk_put(arm_clk);
334 clk_put(pll1_sys_clk);
335 clk_put(pll1_sw_clk);
336 clk_put(step_clk);
337 clk_put(pll2_pfd2_396m_clk);
313 338
314 return 0; 339 return 0;
315} 340}