From e82f2f95a6b1d61eebc2b22bf7480b9ad9a47d3b Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Thu, 8 Aug 2013 13:57:23 -0400 Subject: [PATCH] ENGR00274056-3 thermal: imx: binding device cooling to thermal 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 --- drivers/thermal/imx_thermal.c | 47 +++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index a99c63152b8d..1dd32210a346 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -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; } -- 2.39.2