@@ -306,9 +306,9 @@ static void monitor_thermal_zone(struct thermal_zone_device *tz)
{
mutex_lock(&tz->lock);
- if (tz->passive)
+ if (tz->mode == THERMAL_DEVICE_ENABLED && tz->passive)
thermal_zone_device_set_polling(tz, tz->passive_delay);
- else if (tz->polling_delay)
+ else if (tz->mode == THERMAL_DEVICE_ENABLED && tz->polling_delay)
thermal_zone_device_set_polling(tz, tz->polling_delay);
else
thermal_zone_device_set_polling(tz, 0);
@@ -464,11 +464,35 @@ static void thermal_zone_device_reset(struct thermal_zone_device *tz)
pos->initialized = false;
}
+int thermal_zone_set_mode(struct thermal_zone_device *tz,
+ enum thermal_device_mode mode)
+{
+ int result;
+
+ if (!tz->ops->set_mode)
+ return -EPERM;
+
+ result = tz->ops->set_mode(tz, mode);
+ if (result)
+ return result;
+
+ if (tz->mode != mode) {
+ tz->mode = mode;
+ monitor_thermal_zone(tz);
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(thermal_zone_set_mode);
+
void thermal_zone_device_update(struct thermal_zone_device *tz,
enum thermal_notify_event event)
{
int count;
+ /* Do nothing if the thermal zone is disabled */
+ if (tz->mode == THERMAL_DEVICE_DISABLED)
+ return;
+
if (atomic_read(&in_suspend))
return;
@@ -1287,6 +1311,15 @@ thermal_zone_device_register(const char *type, int trips, int mask,
INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_check);
thermal_zone_device_reset(tz);
+
+ if (tz->ops->get_mode) {
+ enum thermal_device_mode mode;
+
+ result = tz->ops->get_mode(tz, &mode);
+ tz->mode = result ? THERMAL_DEVICE_ENABLED : mode;
+ } else
+ tz->mode = THERMAL_DEVICE_ENABLED;
+
/* Update the new thermal zone and mark it as already updated. */
if (atomic_cmpxchg(&tz->need_update, 1, 0))
thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
@@ -51,17 +51,8 @@ static ssize_t
mode_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct thermal_zone_device *tz = to_thermal_zone(dev);
- enum thermal_device_mode mode;
- int result;
-
- if (!tz->ops->get_mode)
- return -EPERM;
- result = tz->ops->get_mode(tz, &mode);
- if (result)
- return result;
-
- return sprintf(buf, "%s\n", mode == THERMAL_DEVICE_ENABLED ? "enabled"
+ return sprintf(buf, "%s\n", tz->mode == THERMAL_DEVICE_ENABLED ? "enabled"
: "disabled");
}
@@ -70,18 +61,17 @@ mode_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct thermal_zone_device *tz = to_thermal_zone(dev);
+ enum thermal_device_mode mode;
int result;
- if (!tz->ops->set_mode)
- return -EPERM;
-
if (!strncmp(buf, "enabled", sizeof("enabled") - 1))
- result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
+ mode = THERMAL_DEVICE_ENABLED;
else if (!strncmp(buf, "disabled", sizeof("disabled") - 1))
- result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
+ mode = THERMAL_DEVICE_DISABLED;
else
- result = -EINVAL;
+ return -EINVAL;
+ result = thermal_zone_set_mode(tz, mode);
if (result)
return result;
@@ -210,6 +210,7 @@ struct thermal_zone_device {
struct thermal_attr *trip_type_attrs;
struct thermal_attr *trip_hyst_attrs;
void *devdata;
+ enum thermal_device_mode mode;
int trips;
unsigned long trips_disabled; /* bitmap for disabled trips */
int passive_delay;
@@ -465,6 +466,8 @@ struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name);
int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp);
int thermal_zone_get_slope(struct thermal_zone_device *tz);
int thermal_zone_get_offset(struct thermal_zone_device *tz);
+int thermal_zone_set_mode(struct thermal_zone_device *tz,
+ enum thermal_device_mode mode);
int get_tz_trend(struct thermal_zone_device *, int);
struct thermal_instance *get_thermal_instance(struct thermal_zone_device *,