From patchwork Sun Nov 4 17:33:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Rui" X-Patchwork-Id: 10666965 X-Patchwork-Delegate: rui.zhang@intel.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A5A3715E9 for ; Sun, 4 Nov 2018 17:33:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 83E87288D8 for ; Sun, 4 Nov 2018 17:33:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5DC04288BD; Sun, 4 Nov 2018 17:33:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B9D04288BD for ; Sun, 4 Nov 2018 17:33:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731064AbeKECtU (ORCPT ); Sun, 4 Nov 2018 21:49:20 -0500 Received: from mga18.intel.com ([134.134.136.126]:33539 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729332AbeKECtU (ORCPT ); Sun, 4 Nov 2018 21:49:20 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 04 Nov 2018 09:33:34 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,464,1534834800"; d="scan'208";a="88505169" Received: from dgao1-mobl1.ccr.corp.intel.com (HELO rzhang-dell-9360.ccr.corp.intel.com) ([10.255.30.243]) by orsmga006.jf.intel.com with ESMTP; 04 Nov 2018 09:33:32 -0800 From: Zhang Rui To: linux-pm@vger.kernel.org Cc: b.zolnierkie@samsung.com, amit.kucheria@linaro.org, edubezval@gmail.com, srinivas.pandruvada@linux.intel.com, rui.zhang@intel.com Subject: [RTC PATCH 1/2] thermal: remove redundant polling timer update Date: Mon, 5 Nov 2018 01:33:29 +0800 Message-Id: <1541352810-21164-1-git-send-email-rui.zhang@intel.com> X-Mailer: git-send-email 2.7.4 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP polling timer only needs to be updated once after all the trip points have been updated. Thus remove the redundant call of monitor_thermal_zone(). Signed-off-by: Zhang Rui --- drivers/thermal/thermal_core.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index d6ebc1c..98f02b0 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -419,11 +419,6 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip) handle_critical_trips(tz, trip, type); else handle_non_critical_trips(tz, trip, type); - /* - * Alright, we handled this trip successfully. - * So, start monitoring again. - */ - monitor_thermal_zone(tz); } static void update_temperature(struct thermal_zone_device *tz) @@ -482,6 +477,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz, for (count = 0; count < tz->trips; count++) handle_thermal_trip(tz, count); + monitor_thermal_zone(tz); } EXPORT_SYMBOL_GPL(thermal_zone_device_update); From patchwork Sun Nov 4 17:33:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Rui" X-Patchwork-Id: 10666967 X-Patchwork-Delegate: rui.zhang@intel.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 189DE175A for ; Sun, 4 Nov 2018 17:33:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0235E288BD for ; Sun, 4 Nov 2018 17:33:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E8B42288D8; Sun, 4 Nov 2018 17:33:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 57BB128918 for ; Sun, 4 Nov 2018 17:33:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729332AbeKECtV (ORCPT ); Sun, 4 Nov 2018 21:49:21 -0500 Received: from mga18.intel.com ([134.134.136.126]:33539 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729529AbeKECtU (ORCPT ); Sun, 4 Nov 2018 21:49:20 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 04 Nov 2018 09:33:37 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,464,1534834800"; d="scan'208";a="88505179" Received: from dgao1-mobl1.ccr.corp.intel.com (HELO rzhang-dell-9360.ccr.corp.intel.com) ([10.255.30.243]) by orsmga006.jf.intel.com with ESMTP; 04 Nov 2018 09:33:34 -0800 From: Zhang Rui To: linux-pm@vger.kernel.org Cc: b.zolnierkie@samsung.com, amit.kucheria@linaro.org, edubezval@gmail.com, srinivas.pandruvada@linux.intel.com, rui.zhang@intel.com Subject: [RTC PATCH 2/2] thermal core: improve thermal zone device mode control Date: Mon, 5 Nov 2018 01:33:30 +0800 Message-Id: <1541352810-21164-2-git-send-email-rui.zhang@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1541352810-21164-1-git-send-email-rui.zhang@intel.com> References: <1541352810-21164-1-git-send-email-rui.zhang@intel.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Thermal "mode" sysfs attribute is introduced to enable/disable a thermal zone, and .set_mode() callback is introduced for platform thermal driver to enable/disable the hardware thermal control logic. But, thermal core does not handle disabled thermal zone well and this brings a couple of issues. 1. thermal core polling timer for disabled thermal zone still runs. 2. thermal core still pokes disabled thermal zone occasionally, e.g. upon system resume. 3. platform thermal driver can not register a disabled thermal zone. To fix this, a new flag 'mode' is introduced in struct thermal_zone_device to represent the thermal zone mode, and several decisions have been made based on this flag, including a. check the thermal zone mode right after it's registered. b. skip updating thermal zone if the thermal zone is disabled. c. stop the polling timer when the thermal zone is disabled. TODO: This patch fixes issue 1 and 2, but for issue 3, for drivers that needs to register a disabled thermal zone, they should setup tzp->disalbed explicitly during registration and invokes thermal_zone_set_mode() when the hardware is ready. Signed-off-by: Zhang Rui --- drivers/thermal/thermal_core.c | 39 ++++++++++++++++++++++++++++++++++++++- drivers/thermal/thermal_sysfs.c | 27 +++++++-------------------- include/linux/thermal.h | 9 +++++++++ 3 files changed, 54 insertions(+), 21 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 98f02b0..65a984a 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -305,7 +305,9 @@ static void monitor_thermal_zone(struct thermal_zone_device *tz) { mutex_lock(&tz->lock); - if (tz->passive) + if (tz->mode == THERMAL_DEVICE_DISABLED) + thermal_zone_device_set_polling(tz, 0); + else if (tz->passive) thermal_zone_device_set_polling(tz, tz->passive_delay); else if (tz->polling_delay) thermal_zone_device_set_polling(tz, tz->polling_delay); @@ -458,11 +460,33 @@ 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->mode == mode) + return 0; + + if (tz->ops->set_mode) { + result = tz->ops->set_mode(tz, mode); + if (result) + return result; + } + + thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); + 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; + if (tz->mode == THERMAL_DEVICE_DISABLED) + goto update_timer; + if (atomic_read(&in_suspend)) return; @@ -477,6 +501,8 @@ void thermal_zone_device_update(struct thermal_zone_device *tz, for (count = 0; count < tz->trips; count++) handle_thermal_trip(tz, count); + +update_timer: monitor_thermal_zone(tz); } EXPORT_SYMBOL_GPL(thermal_zone_device_update); @@ -1275,6 +1301,17 @@ 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); + + /* + * As .get_mode() is not guaranteed to work at this moment, to register + * a disabled thermal zone, tzp->disalbed must be set explicitly. + */ + if (tz->tzp) { + tz->mode = tzp->disabled == true ? THERMAL_DEVICE_DISABLED : + THERMAL_DEVICE_ENABLED; + } 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); diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index 2241cea..8d144d4 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -49,18 +49,9 @@ 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" - : "disabled"); + return sprintf(buf, "%s\n", tz->mode == THERMAL_DEVICE_ENABLED ? + "enabled" : "disabled"); } static ssize_t @@ -68,20 +59,16 @@ mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct thermal_zone_device *tz = to_thermal_zone(dev); - int result; - - if (!tz->ops->set_mode) - return -EPERM; + enum thermal_device_mode mode; 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; - if (result) - return result; + thermal_zone_set_mode(tz, mode); return count; } diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 5f4705f..67e4b5b 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -197,6 +197,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; @@ -287,6 +288,9 @@ struct thermal_zone_params { */ bool no_hwmon; + /* a boolean to indicate if the thermal zone is disabled or not */ + bool disabled; + int num_tbps; /* Number of tbp entries */ struct thermal_bind_params *tbp; @@ -452,6 +456,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 *, @@ -518,6 +524,9 @@ static inline int thermal_zone_get_slope( static inline int thermal_zone_get_offset( struct thermal_zone_device *tz) { return -ENODEV; } +static inline int thermal_zone_set_mode(struct thermal_zone_device *tz, + enum thermal_device_mode mode); +{ return -ENODEV; } static inline int get_tz_trend(struct thermal_zone_device *tz, int trip) { return -ENODEV; } static inline struct thermal_instance *