]> git.kernelconcepts.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>
Wed, 20 Aug 2014 08:06:12 +0000 (10:06 +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 2c516f2eebed7e63537760c6eb12980207198cc3..36220599acf7066412a14b3b7a10f9789bcc86a5 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,
 };
 
@@ -446,14 +467,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,
@@ -464,7 +495,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;
        }
 
@@ -509,7 +541,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;
 }