Commit 329fe7b14d6cef4b8cf8c866ff41057a70224de2

Authored by Anson Huang
Committed by Zhang Rui
1 parent beeb5a1e0e

thermal: imx: add necessary clk operation

Thermal sensor needs pll3_usb_otg when measuring temperature,
otherwise the temperature read will be incorrect, so need to
enable this clk before sensor working, for alarm function,
as hardware will take measurement periodically, so we should
keep this clk always on once alarm function is enabled.

Signed-off-by: Anson Huang <b20788@freescale.com>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>

Showing 2 changed files with 24 additions and 0 deletions Side-by-side Diff

Documentation/devicetree/bindings/thermal/imx-thermal.txt
... ... @@ -8,11 +8,15 @@
8 8 calibration data, e.g. OCOTP on imx6q. The details about calibration data
9 9 can be found in SoC Reference Manual.
10 10  
  11 +Optional properties:
  12 +- clocks : thermal sensor's clock source.
  13 +
11 14 Example:
12 15  
13 16 tempmon {
14 17 compatible = "fsl,imx6q-tempmon";
15 18 fsl,tempmon = <&anatop>;
16 19 fsl,tempmon-data = <&ocotp>;
  20 + clocks = <&clks 172>;
17 21 };
drivers/thermal/imx_thermal.c
... ... @@ -7,6 +7,7 @@
7 7 *
8 8 */
9 9  
  10 +#include <linux/clk.h>
10 11 #include <linux/cpu_cooling.h>
11 12 #include <linux/cpufreq.h>
12 13 #include <linux/delay.h>
... ... @@ -73,6 +74,7 @@
73 74 unsigned long last_temp;
74 75 bool irq_enabled;
75 76 int irq;
  77 + struct clk *thermal_clk;
76 78 };
77 79  
78 80 static void imx_set_alarm_temp(struct imx_thermal_data *data,
... ... @@ -457,6 +459,22 @@
457 459 return ret;
458 460 }
459 461  
  462 + data->thermal_clk = devm_clk_get(&pdev->dev, NULL);
  463 + if (IS_ERR(data->thermal_clk)) {
  464 + dev_warn(&pdev->dev, "failed to get thermal clk!\n");
  465 + } else {
  466 + /*
  467 + * Thermal sensor needs clk on to get correct value, normally
  468 + * we should enable its clk before taking measurement and disable
  469 + * clk after measurement is done, but if alarm function is enabled,
  470 + * hardware will auto measure the temperature periodically, so we
  471 + * need to keep the clk always on for alarm function.
  472 + */
  473 + ret = clk_prepare_enable(data->thermal_clk);
  474 + if (ret)
  475 + dev_warn(&pdev->dev, "failed to enable thermal clk: %d\n", ret);
  476 + }
  477 +
460 478 /* Enable measurements at ~ 10 Hz */
461 479 regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ);
462 480 measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */
... ... @@ -478,6 +496,8 @@
478 496  
479 497 /* Disable measurements */
480 498 regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
  499 + if (!IS_ERR(data->thermal_clk))
  500 + clk_disable_unprepare(data->thermal_clk);
481 501  
482 502 thermal_zone_device_unregister(data->tz);
483 503 cpufreq_cooling_unregister(data->cdev);