aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhang Rui <rui.zhang@intel.com>2012-06-26 21:54:33 -0400
committerZhang Rui <rui.zhang@intel.com>2012-09-24 02:44:36 -0400
commit601f3d4242be6ed6f72a2aadabc91e8255dad811 (patch)
tree497f09fcf665c066e4efc5d9542b33f021632ea9
parent9d99842f99d847191ebd0c28469d2c70fcc5bf9e (diff)
Thermal: Introduce .get_trend() callback.
According to ACPI spec, tc1 and tc2 are used by OSPM to anticipate the temperature trends. We introduced the same concept to the generic thermal layer for passive cooling, but now it seems that these values are hard to be used on other platforms. So We introduce .get_trend() as a more general solution. For the platform thermal drivers that have their own way to anticipate the temperature trends, they should provide their own .get_trend() callback. Or else, we will calculate the temperature trends by simply comparing the current temperature and the cached previous temperature reading. Signed-off-by: Zhang Rui <rui.zhang@intel.com> Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl> Reviewed-by: Valentin, Eduardo <eduardo.valentin@ti.com>
-rw-r--r--drivers/acpi/thermal.c33
-rw-r--r--drivers/thermal/thermal_sys.c19
-rw-r--r--include/linux/thermal.h9
3 files changed, 59 insertions, 2 deletions
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index d7ef69d835f2..bb95709a6be8 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -706,6 +706,38 @@ static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
706 return -EINVAL; 706 return -EINVAL;
707} 707}
708 708
709static int thermal_get_trend(struct thermal_zone_device *thermal,
710 int trip, enum thermal_trend *trend)
711{
712 struct acpi_thermal *tz = thermal->devdata;
713 enum thermal_trip_type type;
714 int i;
715
716 if (thermal_get_trip_type(thermal, trip, &type))
717 return -EINVAL;
718
719 /* Only PASSIVE trip points need TREND */
720 if (type != THERMAL_TRIP_PASSIVE)
721 return -EINVAL;
722
723 /*
724 * tz->temperature has already been updated by generic thermal layer,
725 * before this callback being invoked
726 */
727 i = (tz->trips.passive.tc1 * (tz->temperature - tz->last_temperature))
728 + (tz->trips.passive.tc2
729 * (tz->temperature - tz->trips.passive.temperature));
730
731 if (i > 0)
732 *trend = THERMAL_TREND_RAISING;
733 else if (i < 0)
734 *trend = THERMAL_TREND_DROPPING;
735 else
736 *trend = THERMAL_TREND_STABLE;
737 return 0;
738}
739
740
709static int thermal_notify(struct thermal_zone_device *thermal, int trip, 741static int thermal_notify(struct thermal_zone_device *thermal, int trip,
710 enum thermal_trip_type trip_type) 742 enum thermal_trip_type trip_type)
711{ 743{
@@ -838,6 +870,7 @@ static const struct thermal_zone_device_ops acpi_thermal_zone_ops = {
838 .get_trip_type = thermal_get_trip_type, 870 .get_trip_type = thermal_get_trip_type,
839 .get_trip_temp = thermal_get_trip_temp, 871 .get_trip_temp = thermal_get_trip_temp,
840 .get_crit_temp = thermal_get_crit_temp, 872 .get_crit_temp = thermal_get_crit_temp,
873 .get_trend = thermal_get_trend,
841 .notify = thermal_notify, 874 .notify = thermal_notify,
842}; 875};
843 876
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index b04fe2c4b0d5..146aa043f15b 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -723,6 +723,20 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
723 struct thermal_cooling_device *cdev; 723 struct thermal_cooling_device *cdev;
724 long state, max_state; 724 long state, max_state;
725 725
726 if (!tz->ops->get_trend ||
727 tz->ops->get_trend(tz, trip, (enum thermal_trend *)&trend)) {
728 /*
729 * compare the current temperature and previous temperature
730 * to get the thermal trend, if no special requirement
731 */
732 if (tz->temperature > tz->last_temperature)
733 trend = THERMAL_TREND_RAISING;
734 else if (tz->temperature < tz->last_temperature)
735 trend = THERMAL_TREND_DROPPING;
736 else
737 trend = THERMAL_TREND_STABLE;
738 }
739
726 /* 740 /*
727 * Above Trip? 741 * Above Trip?
728 * ----------- 742 * -----------
@@ -1091,6 +1105,9 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
1091 goto leave; 1105 goto leave;
1092 } 1106 }
1093 1107
1108 tz->last_temperature = tz->temperature;
1109 tz->temperature = temp;
1110
1094 for (count = 0; count < tz->trips; count++) { 1111 for (count = 0; count < tz->trips; count++) {
1095 tz->ops->get_trip_type(tz, count, &trip_type); 1112 tz->ops->get_trip_type(tz, count, &trip_type);
1096 tz->ops->get_trip_temp(tz, count, &trip_temp); 1113 tz->ops->get_trip_temp(tz, count, &trip_temp);
@@ -1150,8 +1167,6 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
1150 thermal_zone_device_passive(tz, temp, tz->forced_passive, 1167 thermal_zone_device_passive(tz, temp, tz->forced_passive,
1151 THERMAL_TRIPS_NONE); 1168 THERMAL_TRIPS_NONE);
1152 1169
1153 tz->last_temperature = temp;
1154
1155leave: 1170leave:
1156 if (tz->passive) 1171 if (tz->passive)
1157 thermal_zone_device_set_polling(tz, tz->passive_delay); 1172 thermal_zone_device_set_polling(tz, tz->passive_delay);
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 5946a3b90bb2..6a1d43d2ec92 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -44,6 +44,12 @@ enum thermal_trip_type {
44 THERMAL_TRIP_CRITICAL, 44 THERMAL_TRIP_CRITICAL,
45}; 45};
46 46
47enum thermal_trend {
48 THERMAL_TREND_STABLE, /* temperature is stable */
49 THERMAL_TREND_RAISING, /* temperature is raising */
50 THERMAL_TREND_DROPPING, /* temperature is dropping */
51};
52
47struct thermal_zone_device_ops { 53struct thermal_zone_device_ops {
48 int (*bind) (struct thermal_zone_device *, 54 int (*bind) (struct thermal_zone_device *,
49 struct thermal_cooling_device *); 55 struct thermal_cooling_device *);
@@ -65,6 +71,8 @@ struct thermal_zone_device_ops {
65 int (*set_trip_hyst) (struct thermal_zone_device *, int, 71 int (*set_trip_hyst) (struct thermal_zone_device *, int,
66 unsigned long); 72 unsigned long);
67 int (*get_crit_temp) (struct thermal_zone_device *, unsigned long *); 73 int (*get_crit_temp) (struct thermal_zone_device *, unsigned long *);
74 int (*get_trend) (struct thermal_zone_device *, int,
75 enum thermal_trend *);
68 int (*notify) (struct thermal_zone_device *, int, 76 int (*notify) (struct thermal_zone_device *, int,
69 enum thermal_trip_type); 77 enum thermal_trip_type);
70}; 78};
@@ -111,6 +119,7 @@ struct thermal_zone_device {
111 int tc2; 119 int tc2;
112 int passive_delay; 120 int passive_delay;
113 int polling_delay; 121 int polling_delay;
122 int temperature;
114 int last_temperature; 123 int last_temperature;
115 bool passive; 124 bool passive;
116 unsigned int forced_passive; 125 unsigned int forced_passive;