Merge remote-tracking branch 'livepatching/for-next'
[deliverable/linux.git] / drivers / thermal / thermal_core.c
index e2fc6161dded9650c300cf829a381c0a2d14b38c..f2d55e478b2a70f367efd2d6f609e029feaf464b 100644 (file)
@@ -520,6 +520,56 @@ exit:
 }
 EXPORT_SYMBOL_GPL(thermal_zone_get_temp);
 
+void thermal_zone_set_trips(struct thermal_zone_device *tz)
+{
+       int low = -INT_MAX;
+       int high = INT_MAX;
+       int trip_temp, hysteresis;
+       int i, ret;
+
+       mutex_lock(&tz->lock);
+
+       if (!tz->ops->set_trips || !tz->ops->get_trip_hyst)
+               goto exit;
+
+       for (i = 0; i < tz->trips; i++) {
+               int trip_low;
+
+               tz->ops->get_trip_temp(tz, i, &trip_temp);
+               tz->ops->get_trip_hyst(tz, i, &hysteresis);
+
+               trip_low = trip_temp - hysteresis;
+
+               if (trip_low < tz->temperature && trip_low > low)
+                       low = trip_low;
+
+               if (trip_temp > tz->temperature && trip_temp < high)
+                       high = trip_temp;
+       }
+
+       /* No need to change trip points */
+       if (tz->prev_low_trip == low && tz->prev_high_trip == high)
+               goto exit;
+
+       tz->prev_low_trip = low;
+       tz->prev_high_trip = high;
+
+       dev_dbg(&tz->device,
+               "new temperature boundaries: %d < x < %d\n", low, high);
+
+       /*
+        * Set a temperature window. When this window is left the driver
+        * must inform the thermal core via thermal_zone_device_update.
+        */
+       ret = tz->ops->set_trips(tz, low, high);
+       if (ret)
+               dev_err(&tz->device, "Failed to set trips: %d\n", ret);
+
+exit:
+       mutex_unlock(&tz->lock);
+}
+EXPORT_SYMBOL_GPL(thermal_zone_set_trips);
+
 static void update_temperature(struct thermal_zone_device *tz)
 {
        int temp, ret;
@@ -569,6 +619,8 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
 
        update_temperature(tz);
 
+       thermal_zone_set_trips(tz);
+
        for (count = 0; count < tz->trips; count++)
                handle_thermal_trip(tz, count);
 }
@@ -754,6 +806,9 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
         */
        ret = tz->ops->set_trip_hyst(tz, trip, temperature);
 
+       if (!ret)
+               thermal_zone_set_trips(tz);
+
        return ret ? ret : count;
 }
 
@@ -2069,6 +2124,36 @@ exit:
 }
 EXPORT_SYMBOL_GPL(thermal_zone_get_zone_by_name);
 
+/**
+ * thermal_zone_get_slope - return the slope attribute of the thermal zone
+ * @tz: thermal zone device with the slope attribute
+ *
+ * Return: If the thermal zone device has a slope attribute, return it, else
+ * return 1.
+ */
+int thermal_zone_get_slope(struct thermal_zone_device *tz)
+{
+       if (tz && tz->tzp)
+               return tz->tzp->slope;
+       return 1;
+}
+EXPORT_SYMBOL_GPL(thermal_zone_get_slope);
+
+/**
+ * thermal_zone_get_offset - return the offset attribute of the thermal zone
+ * @tz: thermal zone device with the offset attribute
+ *
+ * Return: If the thermal zone device has a offset attribute, return it, else
+ * return 0.
+ */
+int thermal_zone_get_offset(struct thermal_zone_device *tz)
+{
+       if (tz && tz->tzp)
+               return tz->tzp->offset;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(thermal_zone_get_offset);
+
 #ifdef CONFIG_NET
 static const struct genl_multicast_group thermal_event_mcgrps[] = {
        { .name = THERMAL_GENL_MCAST_GROUP_NAME, },
This page took 0.024343 seconds and 5 git commands to generate.