aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhang Rui <rui.zhang@intel.com>2012-06-27 02:14:05 -0400
committerZhang Rui <rui.zhang@intel.com>2012-09-24 02:44:37 -0400
commit908b9fb792b77663a007af240e7ee89460de2025 (patch)
treeaf3ac03a4823028a51b0f067a9da291368ff65be
parentce119f83257aae29b84a5bfad0669e8348437b18 (diff)
Thermal: Unify the code for both active and passive cooling
Remove thermal_zone_device_passive(). And use thermal_zone_trip_update() and thermal_zone_do_update() for both active and passive cooling. 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>
-rw-r--r--drivers/thermal/thermal_sys.c110
-rw-r--r--include/linux/thermal.h2
2 files changed, 26 insertions, 86 deletions
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 36ae2f43ee2..6e9d3dc9d89 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -715,84 +715,6 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
715 msecs_to_jiffies(delay)); 715 msecs_to_jiffies(delay));
716} 716}
717 717
718static void thermal_zone_device_passive(struct thermal_zone_device *tz,
719 int temp, int trip_temp, int trip)
720{
721 enum thermal_trend trend;
722 struct thermal_instance *instance;
723 struct thermal_cooling_device *cdev;
724 long state, max_state;
725
726 if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
727 /*
728 * compare the current temperature and previous temperature
729 * to get the thermal trend, if no special requirement
730 */
731 if (tz->temperature > tz->last_temperature)
732 trend = THERMAL_TREND_RAISING;
733 else if (tz->temperature < tz->last_temperature)
734 trend = THERMAL_TREND_DROPPING;
735 else
736 trend = THERMAL_TREND_STABLE;
737 }
738
739 /*
740 * Above Trip?
741 * -----------
742 * Calculate the thermal trend (using the passive cooling equation)
743 * and modify the performance limit for all passive cooling devices
744 * accordingly. Note that we assume symmetry.
745 */
746 if (temp >= trip_temp) {
747 tz->passive = true;
748
749 /* Heating up? */
750 if (trend == THERMAL_TREND_RAISING) {
751 list_for_each_entry(instance, &tz->thermal_instances,
752 tz_node) {
753 if (instance->trip != trip)
754 continue;
755 cdev = instance->cdev;
756 cdev->ops->get_cur_state(cdev, &state);
757 cdev->ops->get_max_state(cdev, &max_state);
758 if (state++ < max_state)
759 cdev->ops->set_cur_state(cdev, state);
760 }
761 } else if (trend == THERMAL_TREND_DROPPING) { /* Cooling off? */
762 list_for_each_entry(instance, &tz->thermal_instances,
763 tz_node) {
764 if (instance->trip != trip)
765 continue;
766 cdev = instance->cdev;
767 cdev->ops->get_cur_state(cdev, &state);
768 cdev->ops->get_max_state(cdev, &max_state);
769 if (state > 0)
770 cdev->ops->set_cur_state(cdev, --state);
771 }
772 }
773 return;
774 }
775
776 /*
777 * Below Trip?
778 * -----------
779 * Implement passive cooling hysteresis to slowly increase performance
780 * and avoid thrashing around the passive trip point. Note that we
781 * assume symmetry.
782 */
783 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
784 if (instance->trip != trip)
785 continue;
786 cdev = instance->cdev;
787 cdev->ops->get_cur_state(cdev, &state);
788 cdev->ops->get_max_state(cdev, &max_state);
789 if (state > 0)
790 cdev->ops->set_cur_state(cdev, --state);
791 if (state == 0)
792 tz->passive = false;
793 }
794}
795
796static void thermal_zone_device_check(struct work_struct *work) 718static void thermal_zone_device_check(struct work_struct *work)
797{ 719{
798 struct thermal_zone_device *tz = container_of(work, struct 720 struct thermal_zone_device *tz = container_of(work, struct
@@ -1114,7 +1036,7 @@ static void thermal_zone_do_update(struct thermal_zone_device *tz)
1114} 1036}
1115 1037
1116/* 1038/*
1117 * Cooling algorithm for active trip points 1039 * Cooling algorithm for both active and passive cooling
1118 * 1040 *
1119 * 1. if the temperature is higher than a trip point, 1041 * 1. if the temperature is higher than a trip point,
1120 * a. if the trend is THERMAL_TREND_RAISING, use higher cooling 1042 * a. if the trend is THERMAL_TREND_RAISING, use higher cooling
@@ -1136,9 +1058,16 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
1136 struct thermal_cooling_device *cdev = NULL; 1058 struct thermal_cooling_device *cdev = NULL;
1137 unsigned long cur_state, max_state; 1059 unsigned long cur_state, max_state;
1138 long trip_temp; 1060 long trip_temp;
1061 enum thermal_trip_type trip_type;
1139 enum thermal_trend trend; 1062 enum thermal_trend trend;
1140 1063
1141 tz->ops->get_trip_temp(tz, trip, &trip_temp); 1064 if (trip == THERMAL_TRIPS_NONE) {
1065 trip_temp = tz->forced_passive;
1066 trip_type = THERMAL_TRIPS_NONE;
1067 } else {
1068 tz->ops->get_trip_temp(tz, trip, &trip_temp);
1069 tz->ops->get_trip_type(tz, trip, &trip_type);
1070 }
1142 1071
1143 if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) { 1072 if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
1144 /* 1073 /*
@@ -1170,6 +1099,13 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
1170 cur_state = cur_state > instance->lower ? 1099 cur_state = cur_state > instance->lower ?
1171 (cur_state - 1) : instance->lower; 1100 (cur_state - 1) : instance->lower;
1172 } 1101 }
1102
1103 /* activate a passive thermal instance */
1104 if ((trip_type == THERMAL_TRIP_PASSIVE ||
1105 trip_type == THERMAL_TRIPS_NONE) &&
1106 instance->target == THERMAL_NO_TARGET)
1107 tz->passive++;
1108
1173 instance->target = cur_state; 1109 instance->target = cur_state;
1174 cdev->updated = false; /* cooling device needs update */ 1110 cdev->updated = false; /* cooling device needs update */
1175 } 1111 }
@@ -1186,6 +1122,12 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
1186 1122
1187 cur_state = cur_state > instance->lower ? 1123 cur_state = cur_state > instance->lower ?
1188 (cur_state - 1) : THERMAL_NO_TARGET; 1124 (cur_state - 1) : THERMAL_NO_TARGET;
1125
1126 /* deactivate a passive thermal instance */
1127 if ((trip_type == THERMAL_TRIP_PASSIVE ||
1128 trip_type == THERMAL_TRIPS_NONE) &&
1129 cur_state == THERMAL_NO_TARGET)
1130 tz->passive--;
1189 instance->target = cur_state; 1131 instance->target = cur_state;
1190 cdev->updated = false; /* cooling device needs update */ 1132 cdev->updated = false; /* cooling device needs update */
1191 } 1133 }
@@ -1242,16 +1184,14 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
1242 break; 1184 break;
1243 case THERMAL_TRIP_PASSIVE: 1185 case THERMAL_TRIP_PASSIVE:
1244 if (temp >= trip_temp || tz->passive) 1186 if (temp >= trip_temp || tz->passive)
1245 thermal_zone_device_passive(tz, temp, 1187 thermal_zone_trip_update(tz, count, temp);
1246 trip_temp, count);
1247 break; 1188 break;
1248 } 1189 }
1249 } 1190 }
1250 1191
1251 thermal_zone_do_update(tz);
1252 if (tz->forced_passive) 1192 if (tz->forced_passive)
1253 thermal_zone_device_passive(tz, temp, tz->forced_passive, 1193 thermal_zone_trip_update(tz, THERMAL_TRIPS_NONE, temp);
1254 THERMAL_TRIPS_NONE); 1194 thermal_zone_do_update(tz);
1255 1195
1256leave: 1196leave:
1257 if (tz->passive) 1197 if (tz->passive)
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index de0515a96f9..76d0fe88eb1 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -121,7 +121,7 @@ struct thermal_zone_device {
121 int polling_delay; 121 int polling_delay;
122 int temperature; 122 int temperature;
123 int last_temperature; 123 int last_temperature;
124 bool passive; 124 int passive;
125 unsigned int forced_passive; 125 unsigned int forced_passive;
126 const struct thermal_zone_device_ops *ops; 126 const struct thermal_zone_device_ops *ops;
127 struct list_head thermal_instances; 127 struct list_head thermal_instances;