thermal: core: Stop polling DISABLED thermal devices
[linux-2.6-microblaze.git] / drivers / thermal / thermal_core.c
index 9a321dc..e613f5c 100644 (file)
@@ -9,9 +9,9 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/module.h>
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/kdev_t.h>
 #include <linux/idr.h>
 #include "thermal_core.h"
 #include "thermal_hwmon.h"
 
-MODULE_AUTHOR("Zhang Rui");
-MODULE_DESCRIPTION("Generic thermal management sysfs support");
-MODULE_LICENSE("GPL v2");
-
 static DEFINE_IDA(thermal_tz_ida);
 static DEFINE_IDA(thermal_cdev_ida);
 
@@ -305,13 +301,22 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
                cancel_delayed_work(&tz->poll_queue);
 }
 
+static inline bool should_stop_polling(struct thermal_zone_device *tz)
+{
+       return !thermal_zone_device_is_enabled(tz);
+}
+
 static void monitor_thermal_zone(struct thermal_zone_device *tz)
 {
+       bool stop;
+
+       stop = should_stop_polling(tz);
+
        mutex_lock(&tz->lock);
 
-       if (tz->passive)
+       if (!stop && tz->passive)
                thermal_zone_device_set_polling(tz, tz->passive_delay);
-       else if (tz->polling_delay)
+       else if (!stop && tz->polling_delay)
                thermal_zone_device_set_polling(tz, tz->polling_delay);
        else
                thermal_zone_device_set_polling(tz, 0);
@@ -447,12 +452,6 @@ static void update_temperature(struct thermal_zone_device *tz)
        mutex_unlock(&tz->lock);
 
        trace_thermal_temperature(tz);
-       if (tz->last_temperature == THERMAL_TEMP_INVALID)
-               dev_dbg(&tz->device, "last_temperature N/A, current_temperature=%d\n",
-                       tz->temperature);
-       else
-               dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
-                       tz->last_temperature, tz->temperature);
 }
 
 static void thermal_zone_device_init(struct thermal_zone_device *tz)
@@ -469,11 +468,67 @@ static void thermal_zone_device_reset(struct thermal_zone_device *tz)
        thermal_zone_device_init(tz);
 }
 
+static int thermal_zone_device_set_mode(struct thermal_zone_device *tz,
+                                       enum thermal_device_mode mode)
+{
+       int ret = 0;
+
+       mutex_lock(&tz->lock);
+
+       /* do nothing if mode isn't changing */
+       if (mode == tz->mode) {
+               mutex_unlock(&tz->lock);
+
+               return ret;
+       }
+
+       if (tz->ops->set_mode)
+               ret = tz->ops->set_mode(tz, mode);
+
+       if (!ret)
+               tz->mode = mode;
+
+       mutex_unlock(&tz->lock);
+
+       thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
+
+       return ret;
+}
+
+int thermal_zone_device_enable(struct thermal_zone_device *tz)
+{
+       return thermal_zone_device_set_mode(tz, THERMAL_DEVICE_ENABLED);
+}
+EXPORT_SYMBOL_GPL(thermal_zone_device_enable);
+
+int thermal_zone_device_disable(struct thermal_zone_device *tz)
+{
+       return thermal_zone_device_set_mode(tz, THERMAL_DEVICE_DISABLED);
+}
+EXPORT_SYMBOL_GPL(thermal_zone_device_disable);
+
+int thermal_zone_device_is_enabled(struct thermal_zone_device *tz)
+{
+       enum thermal_device_mode mode;
+
+       mutex_lock(&tz->lock);
+
+       mode = tz->mode;
+
+       mutex_unlock(&tz->lock);
+
+       return mode == THERMAL_DEVICE_ENABLED;
+}
+EXPORT_SYMBOL_GPL(thermal_zone_device_is_enabled);
+
 void thermal_zone_device_update(struct thermal_zone_device *tz,
                                enum thermal_notify_event event)
 {
        int count;
 
+       if (should_stop_polling(tz))
+               return;
+
        if (atomic_read(&in_suspend))
                return;
 
@@ -1466,7 +1521,6 @@ static int thermal_pm_notify(struct notifier_block *nb,
                             unsigned long mode, void *_unused)
 {
        struct thermal_zone_device *tz;
-       enum thermal_device_mode tz_mode;
 
        switch (mode) {
        case PM_HIBERNATION_PREPARE:
@@ -1479,11 +1533,7 @@ static int thermal_pm_notify(struct notifier_block *nb,
        case PM_POST_SUSPEND:
                atomic_set(&in_suspend, 0);
                list_for_each_entry(tz, &thermal_tz_list, node) {
-                       tz_mode = THERMAL_DEVICE_ENABLED;
-                       if (tz->ops->get_mode)
-                               tz->ops->get_mode(tz, &tz_mode);
-
-                       if (tz_mode == THERMAL_DEVICE_DISABLED)
+                       if (!thermal_zone_device_is_enabled(tz))
                                continue;
 
                        thermal_zone_device_init(tz);