aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2014-11-26 19:37:52 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-11-29 17:38:38 -0500
commit9a004428d77f1571c883b993d77ec64767b1959a (patch)
tree891e5d8f6f2ead70f466c6e98524baf82c36f607
parent7c45cf31b3ab9be270a7bf6af2926631dc566436 (diff)
cpufreq-dt: register cooling device from ->ready() callback
Currently we are calling of_cpufreq_cooling_register() from ->init() callback. At this point of time cpufreq driver's policy isn't completely ready to be used as few of its fields/structure/pointers aren't yet initialized. Because of_cpufreq_cooling_register() tries to access policy with help of cpufreq_cpu_get() and then tries to get freq-table as well, these calls fail. To fix this, register the cooling device after the policy is ready to be used. And the right callback for it is the newly added ->ready() one. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Eduardo Valentin <edubezval@gmail.com> Tested-by: Eduardo Valentin <edubezval@gmail.com> Reviewed-by: Lukasz Majewski <l.majewski@samsung.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/cpufreq/cpufreq-dt.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
index 7374fc4b6bb3..e720954244b1 100644
--- a/drivers/cpufreq/cpufreq-dt.c
+++ b/drivers/cpufreq/cpufreq-dt.c
@@ -186,7 +186,6 @@ static int cpufreq_init(struct cpufreq_policy *policy)
186{ 186{
187 struct cpufreq_dt_platform_data *pd; 187 struct cpufreq_dt_platform_data *pd;
188 struct cpufreq_frequency_table *freq_table; 188 struct cpufreq_frequency_table *freq_table;
189 struct thermal_cooling_device *cdev;
190 struct device_node *np; 189 struct device_node *np;
191 struct private_data *priv; 190 struct private_data *priv;
192 struct device *cpu_dev; 191 struct device *cpu_dev;
@@ -269,20 +268,6 @@ static int cpufreq_init(struct cpufreq_policy *policy)
269 goto out_free_priv; 268 goto out_free_priv;
270 } 269 }
271 270
272 /*
273 * For now, just loading the cooling device;
274 * thermal DT code takes care of matching them.
275 */
276 if (of_find_property(np, "#cooling-cells", NULL)) {
277 cdev = of_cpufreq_cooling_register(np, policy->related_cpus);
278 if (IS_ERR(cdev))
279 dev_err(cpu_dev,
280 "running cpufreq without cooling device: %ld\n",
281 PTR_ERR(cdev));
282 else
283 priv->cdev = cdev;
284 }
285
286 priv->cpu_dev = cpu_dev; 271 priv->cpu_dev = cpu_dev;
287 priv->cpu_reg = cpu_reg; 272 priv->cpu_reg = cpu_reg;
288 policy->driver_data = priv; 273 policy->driver_data = priv;
@@ -292,7 +277,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
292 if (ret) { 277 if (ret) {
293 dev_err(cpu_dev, "%s: invalid frequency table: %d\n", __func__, 278 dev_err(cpu_dev, "%s: invalid frequency table: %d\n", __func__,
294 ret); 279 ret);
295 goto out_cooling_unregister; 280 goto out_free_cpufreq_table;
296 } 281 }
297 282
298 policy->cpuinfo.transition_latency = transition_latency; 283 policy->cpuinfo.transition_latency = transition_latency;
@@ -305,8 +290,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
305 290
306 return 0; 291 return 0;
307 292
308out_cooling_unregister: 293out_free_cpufreq_table:
309 cpufreq_cooling_unregister(priv->cdev);
310 dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); 294 dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
311out_free_priv: 295out_free_priv:
312 kfree(priv); 296 kfree(priv);
@@ -324,7 +308,8 @@ static int cpufreq_exit(struct cpufreq_policy *policy)
324{ 308{
325 struct private_data *priv = policy->driver_data; 309 struct private_data *priv = policy->driver_data;
326 310
327 cpufreq_cooling_unregister(priv->cdev); 311 if (priv->cdev)
312 cpufreq_cooling_unregister(priv->cdev);
328 dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table); 313 dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
329 clk_put(policy->clk); 314 clk_put(policy->clk);
330 if (!IS_ERR(priv->cpu_reg)) 315 if (!IS_ERR(priv->cpu_reg))
@@ -334,6 +319,33 @@ static int cpufreq_exit(struct cpufreq_policy *policy)
334 return 0; 319 return 0;
335} 320}
336 321
322static void cpufreq_ready(struct cpufreq_policy *policy)
323{
324 struct private_data *priv = policy->driver_data;
325 struct device_node *np = of_node_get(priv->cpu_dev->of_node);
326
327 if (WARN_ON(!np))
328 return;
329
330 /*
331 * For now, just loading the cooling device;
332 * thermal DT code takes care of matching them.
333 */
334 if (of_find_property(np, "#cooling-cells", NULL)) {
335 priv->cdev = of_cpufreq_cooling_register(np,
336 policy->related_cpus);
337 if (IS_ERR(priv->cdev)) {
338 dev_err(priv->cpu_dev,
339 "running cpufreq without cooling device: %ld\n",
340 PTR_ERR(priv->cdev));
341
342 priv->cdev = NULL;
343 }
344 }
345
346 of_node_put(np);
347}
348
337static struct cpufreq_driver dt_cpufreq_driver = { 349static struct cpufreq_driver dt_cpufreq_driver = {
338 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, 350 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
339 .verify = cpufreq_generic_frequency_table_verify, 351 .verify = cpufreq_generic_frequency_table_verify,
@@ -341,6 +353,7 @@ static struct cpufreq_driver dt_cpufreq_driver = {
341 .get = cpufreq_generic_get, 353 .get = cpufreq_generic_get,
342 .init = cpufreq_init, 354 .init = cpufreq_init,
343 .exit = cpufreq_exit, 355 .exit = cpufreq_exit,
356 .ready = cpufreq_ready,
344 .name = "cpufreq-dt", 357 .name = "cpufreq-dt",
345 .attr = cpufreq_generic_attr, 358 .attr = cpufreq_generic_attr,
346}; 359};