aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal
diff options
context:
space:
mode:
authorHeiner Kallweit <heiner.kallweit@web.de>2014-11-08 14:35:54 -0500
committerEduardo Valentin <edubezval@gmail.com>2014-11-09 14:42:53 -0500
commit90a21ff5824c3ae8b49c1c0498b137792b935aab (patch)
tree6ed150cd27b31178e040f3ed56fefd840da2ae1c /drivers/thermal
parent1d6a27775762110d675f71d7192972c7357b99a7 (diff)
imx: thermal: imx_get_temp might be called before sensor clock is prepared
imx_get_temp might be called before the sensor clock is prepared thus resulting in a timeout of the first attempt to read temp: thermal thermal_zone0: failed to read out thermal zone 0 Happened to me on a Utilite Standard with IMX6 Dual SoC. Reason is that in imx_thermal_probe thermal_zone_device_register is called before the sensor clock is prepared. thermal_zone_device_register however calls thermal_zone_device_update which eventually calls imx_get_temp. Fix this by preparing the clock before calling thermal_zone_device_register. Signed-off-by: Heiner Kallweit <heiner.kallweit@web.de> Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
Diffstat (limited to 'drivers/thermal')
-rw-r--r--drivers/thermal/imx_thermal.c41
1 files changed, 25 insertions, 16 deletions
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index 0e35999ad8b2..5a1f1070b702 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -525,6 +525,30 @@ static int imx_thermal_probe(struct platform_device *pdev)
525 return ret; 525 return ret;
526 } 526 }
527 527
528 data->thermal_clk = devm_clk_get(&pdev->dev, NULL);
529 if (IS_ERR(data->thermal_clk)) {
530 ret = PTR_ERR(data->thermal_clk);
531 if (ret != -EPROBE_DEFER)
532 dev_err(&pdev->dev,
533 "failed to get thermal clk: %d\n", ret);
534 cpufreq_cooling_unregister(data->cdev);
535 return ret;
536 }
537
538 /*
539 * Thermal sensor needs clk on to get correct value, normally
540 * we should enable its clk before taking measurement and disable
541 * clk after measurement is done, but if alarm function is enabled,
542 * hardware will auto measure the temperature periodically, so we
543 * need to keep the clk always on for alarm function.
544 */
545 ret = clk_prepare_enable(data->thermal_clk);
546 if (ret) {
547 dev_err(&pdev->dev, "failed to enable thermal clk: %d\n", ret);
548 cpufreq_cooling_unregister(data->cdev);
549 return ret;
550 }
551
528 data->tz = thermal_zone_device_register("imx_thermal_zone", 552 data->tz = thermal_zone_device_register("imx_thermal_zone",
529 IMX_TRIP_NUM, 553 IMX_TRIP_NUM,
530 BIT(IMX_TRIP_PASSIVE), data, 554 BIT(IMX_TRIP_PASSIVE), data,
@@ -535,26 +559,11 @@ static int imx_thermal_probe(struct platform_device *pdev)
535 ret = PTR_ERR(data->tz); 559 ret = PTR_ERR(data->tz);
536 dev_err(&pdev->dev, 560 dev_err(&pdev->dev,
537 "failed to register thermal zone device %d\n", ret); 561 "failed to register thermal zone device %d\n", ret);
562 clk_disable_unprepare(data->thermal_clk);
538 cpufreq_cooling_unregister(data->cdev); 563 cpufreq_cooling_unregister(data->cdev);
539 return ret; 564 return ret;
540 } 565 }
541 566
542 data->thermal_clk = devm_clk_get(&pdev->dev, NULL);
543 if (IS_ERR(data->thermal_clk)) {
544 dev_warn(&pdev->dev, "failed to get thermal clk!\n");
545 } else {
546 /*
547 * Thermal sensor needs clk on to get correct value, normally
548 * we should enable its clk before taking measurement and disable
549 * clk after measurement is done, but if alarm function is enabled,
550 * hardware will auto measure the temperature periodically, so we
551 * need to keep the clk always on for alarm function.
552 */
553 ret = clk_prepare_enable(data->thermal_clk);
554 if (ret)
555 dev_warn(&pdev->dev, "failed to enable thermal clk: %d\n", ret);
556 }
557
558 /* Enable measurements at ~ 10 Hz */ 567 /* Enable measurements at ~ 10 Hz */
559 regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ); 568 regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ);
560 measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */ 569 measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */