aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal/thermal_sys.c
diff options
context:
space:
mode:
authorZhang Rui <rui.zhang@intel.com>2012-06-26 22:05:39 -0400
committerZhang Rui <rui.zhang@intel.com>2012-09-24 02:44:37 -0400
commit4ae46befb49d4173122e0afa995c4e93d01948a2 (patch)
tree8585d4f0e2b67d51f5d945e3ab78fe610f592971 /drivers/thermal/thermal_sys.c
parent1b7ddb840c3908464b19d4aa4f6dc4c463302442 (diff)
Thermal: Introduce thermal_zone_trip_update()
This function is used to update the cooling state of all the cooling devices that are bound to an active trip point. This will be used for passive cooling as well, in the future patches. as both active and passive cooling can share the same algorithm, which is 1. if the temperature is higher than a trip point, a. if the trend is THERMAL_TREND_RAISING, use higher cooling state for this trip point b. if the trend is THERMAL_TREND_DROPPING, use lower cooling state for this trip point 2. if the temperature is lower than a trip point, use lower cooling state for this trip point. Signed-off-by: Zhang Rui <rui.zhang@intel.com> Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl> Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>
Diffstat (limited to 'drivers/thermal/thermal_sys.c')
-rw-r--r--drivers/thermal/thermal_sys.c102
1 files changed, 76 insertions, 26 deletions
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 0cf3dce55462..735e6e6daada 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -1076,6 +1076,81 @@ void thermal_cooling_device_unregister(struct
1076} 1076}
1077EXPORT_SYMBOL(thermal_cooling_device_unregister); 1077EXPORT_SYMBOL(thermal_cooling_device_unregister);
1078 1078
1079/*
1080 * Cooling algorithm for active trip points
1081 *
1082 * 1. if the temperature is higher than a trip point,
1083 * a. if the trend is THERMAL_TREND_RAISING, use higher cooling
1084 * state for this trip point
1085 * b. if the trend is THERMAL_TREND_DROPPING, use lower cooling
1086 * state for this trip point
1087 *
1088 * 2. if the temperature is lower than a trip point, use lower
1089 * cooling state for this trip point
1090 *
1091 * Note that this behaves the same as the previous passive cooling
1092 * algorithm.
1093 */
1094
1095static void thermal_zone_trip_update(struct thermal_zone_device *tz,
1096 int trip, long temp)
1097{
1098 struct thermal_cooling_device_instance *instance;
1099 struct thermal_cooling_device *cdev = NULL;
1100 unsigned long cur_state, max_state;
1101 long trip_temp;
1102 enum thermal_trend trend;
1103
1104 tz->ops->get_trip_temp(tz, trip, &trip_temp);
1105
1106 if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
1107 /*
1108 * compare the current temperature and previous temperature
1109 * to get the thermal trend, if no special requirement
1110 */
1111 if (tz->temperature > tz->last_temperature)
1112 trend = THERMAL_TREND_RAISING;
1113 else if (tz->temperature < tz->last_temperature)
1114 trend = THERMAL_TREND_DROPPING;
1115 else
1116 trend = THERMAL_TREND_STABLE;
1117 }
1118
1119 if (temp >= trip_temp) {
1120 list_for_each_entry(instance, &tz->cooling_devices, node) {
1121 if (instance->trip != trip)
1122 continue;
1123
1124 cdev = instance->cdev;
1125
1126 cdev->ops->get_cur_state(cdev, &cur_state);
1127 cdev->ops->get_max_state(cdev, &max_state);
1128
1129 if (trend == THERMAL_TREND_RAISING) {
1130 cur_state = cur_state < instance->upper ?
1131 (cur_state + 1) : instance->upper;
1132 } else if (trend == THERMAL_TREND_DROPPING) {
1133 cur_state = cur_state > instance->lower ?
1134 (cur_state - 1) : instance->lower;
1135 }
1136 cdev->ops->set_cur_state(cdev, cur_state);
1137 }
1138 } else { /* below trip */
1139 list_for_each_entry(instance, &tz->cooling_devices, node) {
1140 if (instance->trip != trip)
1141 continue;
1142
1143 cdev = instance->cdev;
1144 cdev->ops->get_cur_state(cdev, &cur_state);
1145
1146 cur_state = cur_state > instance->lower ?
1147 (cur_state - 1) : instance->lower;
1148 cdev->ops->set_cur_state(cdev, cur_state);
1149 }
1150 }
1151
1152 return;
1153}
1079/** 1154/**
1080 * thermal_zone_device_update - force an update of a thermal zone's state 1155 * thermal_zone_device_update - force an update of a thermal zone's state
1081 * @ttz: the thermal zone to update 1156 * @ttz: the thermal zone to update
@@ -1086,9 +1161,6 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
1086 int count, ret = 0; 1161 int count, ret = 0;
1087 long temp, trip_temp; 1162 long temp, trip_temp;
1088 enum thermal_trip_type trip_type; 1163 enum thermal_trip_type trip_type;
1089 struct thermal_cooling_device_instance *instance;
1090 struct thermal_cooling_device *cdev;
1091 unsigned long cur_state, max_state;
1092 1164
1093 mutex_lock(&tz->lock); 1165 mutex_lock(&tz->lock);
1094 1166
@@ -1124,29 +1196,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
1124 tz->ops->notify(tz, count, trip_type); 1196 tz->ops->notify(tz, count, trip_type);
1125 break; 1197 break;
1126 case THERMAL_TRIP_ACTIVE: 1198 case THERMAL_TRIP_ACTIVE:
1127 list_for_each_entry(instance, &tz->cooling_devices, 1199 thermal_zone_trip_update(tz, count, temp);
1128 node) {
1129 if (instance->trip != count)
1130 continue;
1131
1132 cdev = instance->cdev;
1133
1134 cdev->ops->get_cur_state(cdev, &cur_state);
1135 cdev->ops->get_max_state(cdev, &max_state);
1136
1137 if (temp >= trip_temp)
1138 cur_state =
1139 cur_state < instance->upper ?
1140 (cur_state + 1) :
1141 instance->upper;
1142 else
1143 cur_state =
1144 cur_state > instance->lower ?
1145 (cur_state - 1) :
1146 instance->lower;
1147
1148 cdev->ops->set_cur_state(cdev, cur_state);
1149 }
1150 break; 1200 break;
1151 case THERMAL_TRIP_PASSIVE: 1201 case THERMAL_TRIP_PASSIVE:
1152 if (temp >= trip_temp || tz->passive) 1202 if (temp >= trip_temp || tz->passive)