Mode changing might imply a need to stop/start polling the device. monitor_thermal_zone() when mode changes or if previous mode is unknown. Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxxxx> --- drivers/thermal/thermal_core.c | 26 ++++++++++++++++++++++++++ drivers/thermal/thermal_core.h | 2 ++ drivers/thermal/thermal_sysfs.c | 8 +++++--- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 9a321dc548c8..aae2b049d45c 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -469,6 +469,32 @@ static void thermal_zone_device_reset(struct thermal_zone_device *tz) thermal_zone_device_init(tz); } +int thermal_zone_set_mode(struct thermal_zone_device *tz, + enum thermal_device_mode mode) +{ + enum thermal_device_mode old_mode; + int result; + + if (!tz->ops->set_mode) + return -EPERM; + + if (tz->ops->get_mode) { + result = tz->ops->get_mode(tz, &old_mode); + if (result) + return result; + } + + result = tz->ops->set_mode(tz, mode); + if (result) + return result; + + /* old mode unknown or mode changed */ + if (!tz->ops->get_mode || mode != old_mode) + monitor_thermal_zone(tz); + + return 0; +} + void thermal_zone_device_update(struct thermal_zone_device *tz, enum thermal_notify_event event) { diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index a9bf00e91d64..1ed0bdb812d8 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -74,6 +74,8 @@ int thermal_zone_create_device_groups(struct thermal_zone_device *, int); void thermal_zone_destroy_device_groups(struct thermal_zone_device *); void thermal_cooling_device_setup_sysfs(struct thermal_cooling_device *); void thermal_cooling_device_destroy_sysfs(struct thermal_cooling_device *cdev); +int thermal_zone_set_mode(struct thermal_zone_device *tz, + enum thermal_device_mode mode); /* used only at binding time */ ssize_t trip_point_show(struct device *, struct device_attribute *, char *); ssize_t weight_show(struct device *, struct device_attribute *, char *); diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index 6bfef21abce4..cc1f808b48b3 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -68,18 +68,20 @@ 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; -- 2.17.1