diff options
-rw-r--r-- | drivers/acpi/thermal.c | 33 | ||||
-rw-r--r-- | drivers/thermal/thermal_sys.c | 19 | ||||
-rw-r--r-- | include/linux/thermal.h | 9 |
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 | ||
709 | static 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 | |||
709 | static int thermal_notify(struct thermal_zone_device *thermal, int trip, | 741 | static 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 | |||
1155 | leave: | 1170 | leave: |
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 | ||
47 | enum 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 | |||
47 | struct thermal_zone_device_ops { | 53 | struct 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; |