staging: ti-soc-thermal: defer probe if cpufreq is not ready
authorEduardo Valentin <eduardo.valentin@ti.com>
Mon, 8 Apr 2013 12:19:13 +0000 (08:19 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 8 Apr 2013 17:35:08 +0000 (10:35 -0700)
When builtin compiled, there is a chance for this driver
be probed before cpufreq driver is up and running. In this
case, the cpucooling device can be wrong initialized.

Thus, this patch makes sure this driver is probed only
when cpufreq driver is ready. Whenever there is no
cpufreq driver registered, the probe will return -EPROBE_DEFER.

Tested-by: J Keerthy <j-keerthy@ti.com>
Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/ti-soc-thermal/ti-bandgap.c
drivers/staging/ti-soc-thermal/ti-thermal-common.c

index 5b06b12ae91cf4c6cc84054dfb05bafa8477bf41..37fdba639842974b47bf219d2ccbb2e71367abc7 100644 (file)
@@ -1305,12 +1305,18 @@ int ti_bandgap_probe(struct platform_device *pdev)
        for (i = 0; i < bgp->conf->sensor_count; i++) {
                char *domain;
 
-               if (bgp->conf->sensors[i].register_cooling)
-                       bgp->conf->sensors[i].register_cooling(bgp, i);
+               if (bgp->conf->sensors[i].register_cooling) {
+                       ret = bgp->conf->sensors[i].register_cooling(bgp, i);
+                       if (ret)
+                               goto remove_sensors;
+               }
 
-               domain = bgp->conf->sensors[i].domain;
-               if (bgp->conf->expose_sensor)
-                       bgp->conf->expose_sensor(bgp, i, domain);
+               if (bgp->conf->expose_sensor) {
+                       domain = bgp->conf->sensors[i].domain;
+                       ret = bgp->conf->expose_sensor(bgp, i, domain);
+                       if (ret)
+                               goto remove_last_cooling;
+               }
        }
 
        /*
@@ -1329,6 +1335,17 @@ int ti_bandgap_probe(struct platform_device *pdev)
 
        return 0;
 
+remove_last_cooling:
+       if (bgp->conf->sensors[i].unregister_cooling)
+               bgp->conf->sensors[i].unregister_cooling(bgp, i);
+remove_sensors:
+       for (i--; i >= 0; i--) {
+               if (bgp->conf->sensors[i].unregister_cooling)
+                       bgp->conf->sensors[i].unregister_cooling(bgp, i);
+               if (bgp->conf->remove_sensor)
+                       bgp->conf->remove_sensor(bgp, i);
+       }
+       ti_bandgap_power(bgp, false);
 disable_clk:
        if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
                clk_disable_unprepare(bgp->fclock);
index 58e19bc244dfee9720e12087126a2b3e7f5602a6..e3c5e677eaa5c7a13007354b9fa3d2f99bc4b125 100644 (file)
@@ -339,6 +339,11 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id)
        if (!data)
                return -EINVAL;
 
+       if (!cpufreq_get_current_driver()) {
+               dev_dbg(bgp->dev, "no cpufreq driver yet\n");
+               return -EPROBE_DEFER;
+       }
+
        /* Register cooling device */
        data->cool_dev = cpufreq_cooling_register(cpu_present_mask);
        if (IS_ERR_OR_NULL(data->cool_dev)) {