From: Anson Huang Date: Thu, 8 Aug 2013 17:57:23 +0000 (-0400) Subject: ENGR00274056-3 thermal: imx: binding device cooling to thermal X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=f9c34b6d73cb42ee94e15df441414066b37f20a2;p=karo-tx-linux.git 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 --- diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index 0f78121c0892..7343476c5964 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,7 @@ enum imx_thermal_trip { * that will trigger cooling action when crossed. */ #define IMX_TEMP_PASSIVE 85000 +#define IMX_TEMP_PASSIVE_COOL_DELTA 10000 /* * The maximum die temperature on imx parts is 105C, let's give some cushion @@ -70,7 +72,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; unsigned long trip_temp[IMX_TRIP_NUM]; @@ -222,6 +224,24 @@ static int imx_unbind(struct thermal_zone_device *tz, return 0; } +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, @@ -231,6 +251,7 @@ static const 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, }; @@ -331,14 +352,22 @@ 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", @@ -352,7 +381,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; } @@ -366,7 +396,8 @@ static int imx_thermal_remove(struct platform_device *pdev) struct imx_thermal_data *data = platform_get_drvdata(pdev); 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; }