diff options
Diffstat (limited to 'drivers/thermal/thermal_sys.c')
-rw-r--r-- | drivers/thermal/thermal_sys.c | 102 |
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 | } |
1077 | EXPORT_SYMBOL(thermal_cooling_device_unregister); | 1077 | EXPORT_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 | |||
1095 | static 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) |