]> Pileus Git - ~andy/linux/commitdiff
thermal: imx: add necessary clk operation
authorAnson Huang <b20788@freescale.com>
Mon, 23 Dec 2013 20:49:22 +0000 (15:49 -0500)
committerZhang Rui <rui.zhang@intel.com>
Fri, 3 Jan 2014 14:49:16 +0000 (22:49 +0800)
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>
Documentation/devicetree/bindings/thermal/imx-thermal.txt
drivers/thermal/imx_thermal.c

index 541c25e49abfa6f09bf621ff3f78c92435dd68cd..1f0f67234a917bae606b17ad2432e45d7d171895 100644 (file)
@@ -8,10 +8,14 @@ Required properties:
   calibration data, e.g. OCOTP on imx6q.  The details about calibration data
   can be found in SoC Reference Manual.
 
+Optional properties:
+- clocks : thermal sensor's clock source.
+
 Example:
 
 tempmon {
        compatible = "fsl,imx6q-tempmon";
        fsl,tempmon = <&anatop>;
        fsl,tempmon-data = <&ocotp>;
+       clocks = <&clks 172>;
 };
index 77a962f1837be385de02882bbbeb35d4be6228aa..deab7baeeb72c19b48b14445e3f1ee1e78d900e7 100644 (file)
@@ -7,6 +7,7 @@
  *
  */
 
+#include <linux/clk.h>
 #include <linux/cpu_cooling.h>
 #include <linux/cpufreq.h>
 #include <linux/delay.h>
@@ -73,6 +74,7 @@ struct imx_thermal_data {
        unsigned long last_temp;
        bool irq_enabled;
        int irq;
+       struct clk *thermal_clk;
 };
 
 static void imx_set_alarm_temp(struct imx_thermal_data *data,
@@ -457,6 +459,22 @@ static int imx_thermal_probe(struct platform_device *pdev)
                return ret;
        }
 
+       data->thermal_clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(data->thermal_clk)) {
+               dev_warn(&pdev->dev, "failed to get thermal clk!\n");
+       } else {
+               /*
+                * Thermal sensor needs clk on to get correct value, normally
+                * we should enable its clk before taking measurement and disable
+                * clk after measurement is done, but if alarm function is enabled,
+                * hardware will auto measure the temperature periodically, so we
+                * need to keep the clk always on for alarm function.
+                */
+               ret = clk_prepare_enable(data->thermal_clk);
+               if (ret)
+                       dev_warn(&pdev->dev, "failed to enable thermal clk: %d\n", ret);
+       }
+
        /* Enable measurements at ~ 10 Hz */
        regmap_write(map, TEMPSENSE1 + REG_CLR, TEMPSENSE1_MEASURE_FREQ);
        measure_freq = DIV_ROUND_UP(32768, 10); /* 10 Hz */
@@ -478,6 +496,8 @@ static int imx_thermal_remove(struct platform_device *pdev)
 
        /* Disable measurements */
        regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
+       if (!IS_ERR(data->thermal_clk))
+               clk_disable_unprepare(data->thermal_clk);
 
        thermal_zone_device_unregister(data->tz);
        cpufreq_cooling_unregister(data->cdev);