]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00274056-3 thermal: imx: binding device cooling to thermal
authorAnson Huang <b20788@freescale.com>
Thu, 8 Aug 2013 17:57:23 +0000 (13:57 -0400)
committerLothar Waßmann <LW@KARO-electronics.de>
Mon, 16 Jun 2014 14:00:34 +0000 (16:00 +0200)
1. imx thermal depends on device cooling config, as only cpu
cooling is not enough for cooling down SOC;

2. binding device cooling to imx thermal driver.

3. add temperature buffer for passive trip, which means when
temperature cross passive trip, cooling devices will be triggered,
but only when temperature drop to more than the number we defined(10 C)
lower than passive trip, cooling devices will be canceled. this
is to avoid triggering/canceling cooling device back and forth when
temperature is around passive trip.

Signed-off-by: Anson Huang <b20788@freescale.com>
drivers/thermal/imx_thermal.c

index a99c63152b8dc4f9aa73b6d4ff26e3867721e9b0..1dd32210a346644d9299fcef52d39061976729c5 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/cpufreq.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/device_cooling.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -58,6 +59,7 @@ enum imx_thermal_trip {
  * that will trigger cooling action when crossed.
  */
 #define IMX_TEMP_PASSIVE               85000
+#define IMX_TEMP_PASSIVE_COOL_DELTA    10000
 
 #define IMX_POLLING_DELAY              2000 /* millisecond */
 #define IMX_PASSIVE_DELAY              1000
@@ -68,7 +70,7 @@ enum imx_thermal_trip {
 
 struct imx_thermal_data {
        struct thermal_zone_device *tz;
-       struct thermal_cooling_device *cdev;
+       struct thermal_cooling_device *cdev[2];
        enum thermal_device_mode mode;
        struct regmap *tempmon;
        u32 c1, c2; /* See formula in imx_get_sensor_data() */
@@ -290,7 +292,25 @@ static int imx_unbind(struct thermal_zone_device *tz,
        return 0;
 }
 
-static struct thermal_zone_device_ops imx_tz_ops = {
+static int imx_get_trend(struct thermal_zone_device *tz,
+               int trip, enum thermal_trend *trend)
+{
+       int ret;
+       unsigned long trip_temp;
+
+       ret = imx_get_trip_temp(tz, trip, &trip_temp);
+       if (ret < 0)
+               return ret;
+
+       if (tz->temperature >= (trip_temp - IMX_TEMP_PASSIVE_COOL_DELTA))
+               *trend = THERMAL_TREND_RAISE_FULL;
+       else
+               *trend = THERMAL_TREND_DROP_FULL;
+
+       return 0;
+}
+
+static const struct thermal_zone_device_ops imx_tz_ops = {
        .bind = imx_bind,
        .unbind = imx_unbind,
        .get_temp = imx_get_temp,
@@ -299,6 +319,7 @@ static struct thermal_zone_device_ops imx_tz_ops = {
        .get_trip_type = imx_get_trip_type,
        .get_trip_temp = imx_get_trip_temp,
        .get_crit_temp = imx_get_crit_temp,
+       .get_trend = imx_get_trend,
        .set_trip_temp = imx_set_trip_temp,
 };
 
@@ -450,14 +471,24 @@ static int imx_thermal_probe(struct platform_device *pdev)
        regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN);
 
        cpumask_set_cpu(0, &clip_cpus);
-       data->cdev = cpufreq_cooling_register(&clip_cpus);
-       if (IS_ERR(data->cdev)) {
-               ret = PTR_ERR(data->cdev);
+       data->cdev[0] = cpufreq_cooling_register(&clip_cpus);
+       if (IS_ERR(data->cdev[0])) {
+               ret = PTR_ERR(data->cdev[0]);
                dev_err(&pdev->dev,
                        "failed to register cpufreq cooling device: %d\n", ret);
                return ret;
        }
 
+       data->cdev[1] = devfreq_cooling_register();
+       if (IS_ERR(data->cdev[1])) {
+               ret = PTR_ERR(data->cdev[1]);
+               dev_err(&pdev->dev,
+                       "failed to register devfreq cooling device: %d\n", ret);
+               return ret;
+       }
+
+       data->trip_temp[IMX_TRIP_PASSIVE] = IMX_TEMP_PASSIVE;
+       data->trip_temp[IMX_TRIP_CRITICAL] = IMX_TEMP_CRITICAL;
        data->tz = thermal_zone_device_register("imx_thermal_zone",
                                                IMX_TRIP_NUM,
                                                BIT(IMX_TRIP_PASSIVE), data,
@@ -468,7 +499,8 @@ static int imx_thermal_probe(struct platform_device *pdev)
                ret = PTR_ERR(data->tz);
                dev_err(&pdev->dev,
                        "failed to register thermal zone device %d\n", ret);
-               cpufreq_cooling_unregister(data->cdev);
+               cpufreq_cooling_unregister(data->cdev[0]);
+               devfreq_cooling_unregister(data->cdev[1]);
                return ret;
        }
 
@@ -513,7 +545,8 @@ static int imx_thermal_remove(struct platform_device *pdev)
                clk_disable_unprepare(data->thermal_clk);
 
        thermal_zone_device_unregister(data->tz);
-       cpufreq_cooling_unregister(data->cdev);
+       cpufreq_cooling_unregister(data->cdev[0]);
+       devfreq_cooling_unregister(data->cdev[1]);
 
        return 0;
 }