]> Pileus Git - ~andy/linux/blobdiff - drivers/thermal/step_wise.c
virtio_ring: virtqueue_add_outbuf / virtqueue_add_inbuf.
[~andy/linux] / drivers / thermal / step_wise.c
index 0cd5e9fbab1c96ea7393db980aeafc26c87bb577..407cde3211c1bccfcf1e43515fb0a47a5a99e67c 100644 (file)
  *       state for this trip point
  *    b. if the trend is THERMAL_TREND_DROPPING, use lower cooling
  *       state for this trip point
+ *    c. if the trend is THERMAL_TREND_RAISE_FULL, use upper limit
+ *       for this trip point
+ *    d. if the trend is THERMAL_TREND_DROP_FULL, use lower limit
+ *       for this trip point
+ * If the temperature is lower than a trip point,
+ *    a. if the trend is THERMAL_TREND_RAISING, do nothing
+ *    b. if the trend is THERMAL_TREND_DROPPING, use lower cooling
+ *       state for this trip point, if the cooling state already
+ *       equals lower limit, deactivate the thermal instance
+ *    c. if the trend is THERMAL_TREND_RAISE_FULL, do nothing
+ *    d. if the trend is THERMAL_TREND_DROP_FULL, use lower limit,
+ *       if the cooling state already equals lower limit,
+ *       deactive the thermal instance
  */
 static unsigned long get_target_state(struct thermal_instance *instance,
-                                       enum thermal_trend trend)
+                               enum thermal_trend trend, bool throttle)
 {
        struct thermal_cooling_device *cdev = instance->cdev;
        unsigned long cur_state;
 
        cdev->ops->get_cur_state(cdev, &cur_state);
 
-       if (trend == THERMAL_TREND_RAISING) {
-               cur_state = cur_state < instance->upper ?
-                           (cur_state + 1) : instance->upper;
-       } else if (trend == THERMAL_TREND_DROPPING) {
-               cur_state = cur_state > instance->lower ?
-                           (cur_state - 1) : instance->lower;
+       switch (trend) {
+       case THERMAL_TREND_RAISING:
+               if (throttle)
+                       cur_state = cur_state < instance->upper ?
+                                   (cur_state + 1) : instance->upper;
+               break;
+       case THERMAL_TREND_RAISE_FULL:
+               if (throttle)
+                       cur_state = instance->upper;
+               break;
+       case THERMAL_TREND_DROPPING:
+               if (cur_state == instance->lower) {
+                       if (!throttle)
+                               cur_state = -1;
+               } else
+                       cur_state -= 1;
+               break;
+       case THERMAL_TREND_DROP_FULL:
+               if (cur_state == instance->lower) {
+                       if (!throttle)
+                               cur_state = -1;
+               } else
+                       cur_state = instance->lower;
+               break;
+       default:
+               break;
        }
 
        return cur_state;
@@ -66,57 +99,14 @@ static void update_passive_instance(struct thermal_zone_device *tz,
                tz->passive += value;
 }
 
-static void update_instance_for_throttle(struct thermal_zone_device *tz,
-                               int trip, enum thermal_trip_type trip_type,
-                               enum thermal_trend trend)
-{
-       struct thermal_instance *instance;
-
-       list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
-               if (instance->trip != trip)
-                       continue;
-
-               instance->target = get_target_state(instance, trend);
-
-               /* Activate a passive thermal instance */
-               if (instance->target == THERMAL_NO_TARGET)
-                       update_passive_instance(tz, trip_type, 1);
-
-               instance->cdev->updated = false; /* cdev needs update */
-       }
-}
-
-static void update_instance_for_dethrottle(struct thermal_zone_device *tz,
-                               int trip, enum thermal_trip_type trip_type)
-{
-       struct thermal_instance *instance;
-       struct thermal_cooling_device *cdev;
-       unsigned long cur_state;
-
-       list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
-               if (instance->trip != trip ||
-                       instance->target == THERMAL_NO_TARGET)
-                       continue;
-
-               cdev = instance->cdev;
-               cdev->ops->get_cur_state(cdev, &cur_state);
-
-               instance->target = cur_state > instance->lower ?
-                           (cur_state - 1) : THERMAL_NO_TARGET;
-
-               /* Deactivate a passive thermal instance */
-               if (instance->target == THERMAL_NO_TARGET)
-                       update_passive_instance(tz, trip_type, -1);
-
-               cdev->updated = false; /* cdev needs update */
-       }
-}
-
 static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
 {
        long trip_temp;
        enum thermal_trip_type trip_type;
        enum thermal_trend trend;
+       struct thermal_instance *instance;
+       bool throttle = false;
+       int old_target;
 
        if (trip == THERMAL_TRIPS_NONE) {
                trip_temp = tz->forced_passive;
@@ -128,12 +118,30 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
 
        trend = get_tz_trend(tz, trip);
 
+       if (tz->temperature >= trip_temp)
+               throttle = true;
+
        mutex_lock(&tz->lock);
 
-       if (tz->temperature >= trip_temp)
-               update_instance_for_throttle(tz, trip, trip_type, trend);
-       else
-               update_instance_for_dethrottle(tz, trip, trip_type);
+       list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
+               if (instance->trip != trip)
+                       continue;
+
+               old_target = instance->target;
+               instance->target = get_target_state(instance, trend, throttle);
+
+               /* Activate a passive thermal instance */
+               if (old_target == THERMAL_NO_TARGET &&
+                       instance->target != THERMAL_NO_TARGET)
+                       update_passive_instance(tz, trip_type, 1);
+               /* Deactivate a passive thermal instance */
+               else if (old_target != THERMAL_NO_TARGET &&
+                       instance->target == THERMAL_NO_TARGET)
+                       update_passive_instance(tz, trip_type, -1);
+
+
+               instance->cdev->updated = false; /* cdev needs update */
+       }
 
        mutex_unlock(&tz->lock);
 }