Thermal: Introduce thermal_zone_trip_update()
[deliverable/linux.git] / drivers / thermal / thermal_sys.c
index 0cf3dce554628e73bcda5b67137720b7f704ae5b..735e6e6daada83d1921259f8186a9086c10cbe2c 100644 (file)
@@ -1076,6 +1076,81 @@ void thermal_cooling_device_unregister(struct
 }
 EXPORT_SYMBOL(thermal_cooling_device_unregister);
 
+/*
+ * Cooling algorithm for active trip points
+ *
+ * 1. if the temperature is higher than a trip point,
+ *    a. if the trend is THERMAL_TREND_RAISING, use higher cooling
+ *       state for this trip point
+ *    b. if the trend is THERMAL_TREND_DROPPING, use lower cooling
+ *       state for this trip point
+ *
+ * 2. if the temperature is lower than a trip point, use lower
+ *    cooling state for this trip point
+ *
+ * Note that this behaves the same as the previous passive cooling
+ * algorithm.
+ */
+
+static void thermal_zone_trip_update(struct thermal_zone_device *tz,
+                                    int trip, long temp)
+{
+       struct thermal_cooling_device_instance *instance;
+       struct thermal_cooling_device *cdev = NULL;
+       unsigned long cur_state, max_state;
+       long trip_temp;
+       enum thermal_trend trend;
+
+       tz->ops->get_trip_temp(tz, trip, &trip_temp);
+
+       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;
+       }
+
+       if (temp >= trip_temp) {
+               list_for_each_entry(instance, &tz->cooling_devices, node) {
+                       if (instance->trip != trip)
+                               continue;
+
+                       cdev = instance->cdev;
+
+                       cdev->ops->get_cur_state(cdev, &cur_state);
+                       cdev->ops->get_max_state(cdev, &max_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;
+                       }
+                       cdev->ops->set_cur_state(cdev, cur_state);
+               }
+       } else {        /* below trip */
+               list_for_each_entry(instance, &tz->cooling_devices, node) {
+                       if (instance->trip != trip)
+                               continue;
+
+                       cdev = instance->cdev;
+                       cdev->ops->get_cur_state(cdev, &cur_state);
+
+                       cur_state = cur_state > instance->lower ?
+                                   (cur_state - 1) : instance->lower;
+                       cdev->ops->set_cur_state(cdev, cur_state);
+               }
+       }
+
+       return;
+}
 /**
  * thermal_zone_device_update - force an update of a thermal zone's state
  * @ttz:       the thermal zone to update
@@ -1086,9 +1161,6 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
        int count, ret = 0;
        long temp, trip_temp;
        enum thermal_trip_type trip_type;
-       struct thermal_cooling_device_instance *instance;
-       struct thermal_cooling_device *cdev;
-       unsigned long cur_state, max_state;
 
        mutex_lock(&tz->lock);
 
@@ -1124,29 +1196,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
                                        tz->ops->notify(tz, count, trip_type);
                        break;
                case THERMAL_TRIP_ACTIVE:
-                       list_for_each_entry(instance, &tz->cooling_devices,
-                                           node) {
-                               if (instance->trip != count)
-                                       continue;
-
-                               cdev = instance->cdev;
-
-                               cdev->ops->get_cur_state(cdev, &cur_state);
-                               cdev->ops->get_max_state(cdev, &max_state);
-
-                               if (temp >= trip_temp)
-                                       cur_state =
-                                               cur_state < instance->upper ?
-                                               (cur_state + 1) :
-                                               instance->upper;
-                               else
-                                       cur_state =
-                                               cur_state > instance->lower ?
-                                               (cur_state - 1) :
-                                               instance->lower;
-
-                               cdev->ops->set_cur_state(cdev, cur_state);
-                       }
+                       thermal_zone_trip_update(tz, count, temp);
                        break;
                case THERMAL_TRIP_PASSIVE:
                        if (temp >= trip_temp || tz->passive)
This page took 0.024525 seconds and 5 git commands to generate.