aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 d7ef69d835f..bb95709a6be 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 b04fe2c4b0d..146aa043f15 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 5946a3b90bb..6a1d43d2ec9 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;