Thermal: Unify the code for both active and passive cooling
authorZhang Rui <rui.zhang@intel.com>
Wed, 27 Jun 2012 06:14:05 +0000 (14:14 +0800)
committerZhang Rui <rui.zhang@intel.com>
Mon, 24 Sep 2012 06:44:37 +0000 (14:44 +0800)
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>
drivers/thermal/thermal_sys.c
include/linux/thermal.h

index 36ae2f4..6e9d3dc 100644 (file)
@@ -715,84 +715,6 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
                                      msecs_to_jiffies(delay));
 }
 
-static void thermal_zone_device_passive(struct thermal_zone_device *tz,
-                                       int temp, int trip_temp, int trip)
-{
-       enum thermal_trend trend;
-       struct thermal_instance *instance;
-       struct thermal_cooling_device *cdev;
-       long state, max_state;
-
-       if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
-               /*
-                * compare the current temperature and previous temperature
-                * to get the thermal trend, if no special requirement
-                */
-               if (tz->temperature > tz->last_temperature)
-                       trend = THERMAL_TREND_RAISING;
-               else if (tz->temperature < tz->last_temperature)
-                       trend = THERMAL_TREND_DROPPING;
-               else
-                       trend = THERMAL_TREND_STABLE;
-       }
-
-       /*
-        * Above Trip?
-        * -----------
-        * Calculate the thermal trend (using the passive cooling equation)
-        * and modify the performance limit for all passive cooling devices
-        * accordingly.  Note that we assume symmetry.
-        */
-       if (temp >= trip_temp) {
-               tz->passive = true;
-
-               /* Heating up? */
-               if (trend == THERMAL_TREND_RAISING) {
-                       list_for_each_entry(instance, &tz->thermal_instances,
-                                           tz_node) {
-                               if (instance->trip != trip)
-                                       continue;
-                               cdev = instance->cdev;
-                               cdev->ops->get_cur_state(cdev, &state);
-                               cdev->ops->get_max_state(cdev, &max_state);
-                               if (state++ < max_state)
-                                       cdev->ops->set_cur_state(cdev, state);
-                       }
-               } else if (trend == THERMAL_TREND_DROPPING) { /* Cooling off? */
-                       list_for_each_entry(instance, &tz->thermal_instances,
-                                           tz_node) {
-                               if (instance->trip != trip)
-                                       continue;
-                               cdev = instance->cdev;
-                               cdev->ops->get_cur_state(cdev, &state);
-                               cdev->ops->get_max_state(cdev, &max_state);
-                               if (state > 0)
-                                       cdev->ops->set_cur_state(cdev, --state);
-                       }
-               }
-               return;
-       }
-
-       /*
-        * Below Trip?
-        * -----------
-        * Implement passive cooling hysteresis to slowly increase performance
-        * and avoid thrashing around the passive trip point.  Note that we
-        * assume symmetry.
-        */
-       list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
-               if (instance->trip != trip)
-                       continue;
-               cdev = instance->cdev;
-               cdev->ops->get_cur_state(cdev, &state);
-               cdev->ops->get_max_state(cdev, &max_state);
-               if (state > 0)
-                       cdev->ops->set_cur_state(cdev, --state);
-               if (state == 0)
-                       tz->passive = false;
-       }
-}
-
 static void thermal_zone_device_check(struct work_struct *work)
 {
        struct thermal_zone_device *tz = container_of(work, struct
@@ -1114,7 +1036,7 @@ static void thermal_zone_do_update(struct thermal_zone_device *tz)
 }
 
 /*
- * Cooling algorithm for active trip points
+ * Cooling algorithm for both active and passive cooling
  *
  * 1. if the temperature is higher than a trip point,
  *    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,
        struct thermal_cooling_device *cdev = NULL;
        unsigned long cur_state, max_state;
        long trip_temp;
+       enum thermal_trip_type trip_type;
        enum thermal_trend trend;
 
-       tz->ops->get_trip_temp(tz, trip, &trip_temp);
+       if (trip == THERMAL_TRIPS_NONE) {
+               trip_temp = tz->forced_passive;
+               trip_type = THERMAL_TRIPS_NONE;
+       } else {
+               tz->ops->get_trip_temp(tz, trip, &trip_temp);
+               tz->ops->get_trip_type(tz, trip, &trip_type);
+       }
 
        if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
                /*
@@ -1170,6 +1099,13 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
                                cur_state = cur_state > instance->lower ?
                                    (cur_state - 1) : instance->lower;
                        }
+
+                       /* activate a passive thermal instance */
+                       if ((trip_type == THERMAL_TRIP_PASSIVE ||
+                            trip_type == THERMAL_TRIPS_NONE) &&
+                            instance->target == THERMAL_NO_TARGET)
+                               tz->passive++;
+
                        instance->target = cur_state;
                        cdev->updated = false; /* cooling device needs update */
                }
@@ -1186,6 +1122,12 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
 
                        cur_state = cur_state > instance->lower ?
                                    (cur_state - 1) : THERMAL_NO_TARGET;
+
+                       /* deactivate a passive thermal instance */
+                       if ((trip_type == THERMAL_TRIP_PASSIVE ||
+                            trip_type == THERMAL_TRIPS_NONE) &&
+                            cur_state == THERMAL_NO_TARGET)
+                               tz->passive--;
                        instance->target = cur_state;
                        cdev->updated = false; /* cooling device needs update */
                }
@@ -1242,16 +1184,14 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
                        break;
                case THERMAL_TRIP_PASSIVE:
                        if (temp >= trip_temp || tz->passive)
-                               thermal_zone_device_passive(tz, temp,
-                                                           trip_temp, count);
+                               thermal_zone_trip_update(tz, count, temp);
                        break;
                }
        }
 
-       thermal_zone_do_update(tz);
        if (tz->forced_passive)
-               thermal_zone_device_passive(tz, temp, tz->forced_passive,
-                                           THERMAL_TRIPS_NONE);
+               thermal_zone_trip_update(tz, THERMAL_TRIPS_NONE, temp);
+       thermal_zone_do_update(tz);
 
 leave:
        if (tz->passive)
index de0515a..76d0fe8 100644 (file)
@@ -121,7 +121,7 @@ struct thermal_zone_device {
        int polling_delay;
        int temperature;
        int last_temperature;
-       bool passive;
+       int passive;
        unsigned int forced_passive;
        const struct thermal_zone_device_ops *ops;
        struct list_head thermal_instances;