From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrzej Pietrasiewicz Subject: [RFC 5/8] thermal: core: Monitor thermal zone after mode change Date: Tue, 7 Apr 2020 19:49:23 +0200 Message-ID: <20200407174926.23971-6-andrzej.p@collabora.com> References: <20200407174926.23971-1-andrzej.p@collabora.com> Return-path: In-Reply-To: <20200407174926.23971-1-andrzej.p@collabora.com> Sender: linux-acpi-owner@vger.kernel.org To: linux-pm@vger.kernel.org Cc: Zhang Rui , "Rafael J . Wysocki" , Len Brown , Jiri Pirko , Ido Schimmel , "David S . Miller" , Peter Kaestle , Darren Hart , Andy Shevchenko , Support Opensource , Daniel Lezcano , Amit Kucheria , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , Allison Randal , Enrico Weigelt , Gayatri Kammela List-Id: platform-driver-x86.vger.kernel.org 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 --- 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