diff options
| -rw-r--r-- | drivers/acpi/thermal.c | 8 | ||||
| -rw-r--r-- | drivers/thermal/thermal_sys.c | 102 |
2 files changed, 81 insertions, 29 deletions
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 07cb2172bd09..bd66bd28a43f 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
| @@ -716,9 +716,11 @@ static int thermal_get_trend(struct thermal_zone_device *thermal, | |||
| 716 | if (thermal_get_trip_type(thermal, trip, &type)) | 716 | if (thermal_get_trip_type(thermal, trip, &type)) |
| 717 | return -EINVAL; | 717 | return -EINVAL; |
| 718 | 718 | ||
| 719 | /* Only PASSIVE trip points need TREND */ | 719 | if (type == THERMAL_TRIP_ACTIVE) { |
| 720 | if (type != THERMAL_TRIP_PASSIVE) | 720 | /* aggressive active cooling */ |
| 721 | return -EINVAL; | 721 | *trend = THERMAL_TREND_RAISING; |
| 722 | return 0; | ||
| 723 | } | ||
| 722 | 724 | ||
| 723 | /* | 725 | /* |
| 724 | * tz->temperature has already been updated by generic thermal layer, | 726 | * tz->temperature has already been updated by generic thermal layer, |
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) |
