aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal/thermal_sys.c
diff options
context:
space:
mode:
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)