From patchwork Wed Mar 16 21:09:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Li X-Patchwork-Id: 12783197 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 63EE2C433EF for ; Wed, 16 Mar 2022 21:10:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1358131AbiCPVLs (ORCPT ); Wed, 16 Mar 2022 17:11:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34896 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1358104AbiCPVLq (ORCPT ); Wed, 16 Mar 2022 17:11:46 -0400 Received: from mail-pj1-x1032.google.com (mail-pj1-x1032.google.com [IPv6:2607:f8b0:4864:20::1032]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 558164D629 for ; Wed, 16 Mar 2022 14:10:28 -0700 (PDT) Received: by mail-pj1-x1032.google.com with SMTP id m11-20020a17090a7f8b00b001beef6143a8so3654187pjl.4 for ; Wed, 16 Mar 2022 14:10:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=squareup.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=YuBwkb6Bm2dJygmGjKNMzcQ7V38KULA7oyW33icX/Xs=; b=f2Pkm0+UTgAdPrRxaAeSDHe2Wp9gfhaR7VrH65WjuMJTB8JJEn4ensEPYp3kvebZ/1 Iuzewo74EBgaO5auuBP4euHPDcWXtXahB0WhOJ2A6uDo/KeSm6EuFGApxjRLPpwtxYvH k1x1C2KOtBGn46T71xGS0u+hwDMvUxQXmv1XI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=YuBwkb6Bm2dJygmGjKNMzcQ7V38KULA7oyW33icX/Xs=; b=yIaGcOZKX8BaXk6ExYqyNLktbVIOlWDgz3Cl3qWMhPct0jqnb6XQmdz4tqJeNGK3pG bQRLqRHI3zogI83vpKE8FbigalRnnh6LNNpiueNBUMEcnPWMrezPSNuC3Ka8Dwc7fSYf 8I8+kr4D1e4enAEM3UDA+Qdk51ozWt/TWsAPe2PDH0RgSk4+dwl1sAO1ioBaeODTKVX7 zX1aI/eTtZD+ffcKDvOQ0+r9mB7xp4jjoC4akWgkGUoYlknkXZj962Pydmu29ge7Mnjo RyoEZN0EaOgW3tDMWlVNbdcC0xI4IdHFUzJg9J9iSLMD/oiOFl4dx/TKq4r/IQhaaWNb QkCw== X-Gm-Message-State: AOAM532yjKtTHMIM4SidjgOLzYx4dgdPYRNSs5sGtAkWlXxy0w2He4LU kn0I8kzApx3TZwKXqmTZRgYe3A== X-Google-Smtp-Source: ABdhPJxh5UhmNk4YCcGt0E/+WtCoAz7hr3beaRxtARhLtP83XT+fe8dwt5IvhPsE65sdrXs7b6QV8g== X-Received: by 2002:a17:902:e848:b0:151:e3a5:b609 with SMTP id t8-20020a170902e84800b00151e3a5b609mr1440981plg.137.1647465027663; Wed, 16 Mar 2022 14:10:27 -0700 (PDT) Received: from localhost ([135.84.132.250]) by smtp.gmail.com with ESMTPSA id q9-20020a056a00088900b004e03b051040sm4476450pfj.112.2022.03.16.14.10.26 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Mar 2022 14:10:27 -0700 (PDT) From: Benjamin Li To: Daniel Lezcano , Amit Kucheria , Thara Gopinath Cc: Bjorn Andersson , Zac Crosby , Benjamin Li , Andy Gross , "Rafael J. Wysocki" , Zhang Rui , linux-pm@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] thermal: thermal_of: add pass-through change_mode to ops struct Date: Wed, 16 Mar 2022 14:09:44 -0700 Message-Id: <20220316210946.6935-2-benl@squareup.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220316210946.6935-1-benl@squareup.com> References: <20220316210946.6935-1-benl@squareup.com> Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add an optional change_mode method to the ops struct, allowing thermal_of- based drivers to properly implement disabling of sensors/IRQs. Previously thermal_core would just disable the polling timer when a zone is disabled, as thermal_of drivers could not provide a change_mode implementation. This meant thermal_of drivers supporting interrupt-based updates had to keep sensors/IRQs enabled at all times, and needed to resort to reading tzd->mode in their IRQ handler or get_temp implementation to actually stop updating. This is a waste of resources in IRQ handlers to ignore updates, and for sensors that can power down it's a waste of power. Signed-off-by: Benjamin Li --- drivers/thermal/thermal_of.c | 14 ++++++++++++++ include/linux/thermal.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index 9233f7e74454..a69ec39780a7 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -106,6 +106,17 @@ static int of_thermal_set_trips(struct thermal_zone_device *tz, return data->ops->set_trips(data->sensor_data, low, high); } +static int of_thermal_change_mode(struct thermal_zone_device *tz, + enum thermal_device_mode mode) +{ + struct __thermal_zone *data = tz->devdata; + + if (!data->ops || !data->ops->change_mode) + return -EINVAL; + + return data->ops->change_mode(data->sensor_data, mode); +} + /** * of_thermal_get_ntrips - function to export number of available trip * points. @@ -405,6 +416,9 @@ thermal_zone_of_add_sensor(struct device_node *zone, if (ops->set_trips) tzd->ops->set_trips = of_thermal_set_trips; + if (ops->change_mode) + tzd->ops->change_mode = of_thermal_change_mode; + if (ops->set_emul_temp) tzd->ops->set_emul_temp = of_thermal_set_emul_temp; diff --git a/include/linux/thermal.h b/include/linux/thermal.h index c314893970b3..469a1664f1ed 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -295,6 +295,7 @@ struct thermal_zone_params { * @set_trips: a pointer to a function that sets a temperature window. When * this window is left the driver must inform the thermal core via * thermal_zone_device_update. + * @change_mode: a pointer to a function that enables/disables reporting. * @set_emul_temp: a pointer to a function that sets sensor emulated * temperature. * @set_trip_temp: a pointer to a function that sets the trip temperature on @@ -304,6 +305,7 @@ struct thermal_zone_of_device_ops { int (*get_temp)(void *, int *); int (*get_trend)(void *, int, enum thermal_trend *); int (*set_trips)(void *, int, int); + int (*change_mode)(void *, enum thermal_device_mode); int (*set_emul_temp)(void *, int); int (*set_trip_temp)(void *, int, int); }; From patchwork Wed Mar 16 21:09:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Li X-Patchwork-Id: 12783198 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0FB04C43217 for ; Wed, 16 Mar 2022 21:10:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355799AbiCPVLx (ORCPT ); Wed, 16 Mar 2022 17:11:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34920 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1358124AbiCPVLs (ORCPT ); Wed, 16 Mar 2022 17:11:48 -0400 Received: from mail-pl1-x631.google.com (mail-pl1-x631.google.com [IPv6:2607:f8b0:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8CFA966AF7 for ; Wed, 16 Mar 2022 14:10:31 -0700 (PDT) Received: by mail-pl1-x631.google.com with SMTP id q13so2790645plk.12 for ; Wed, 16 Mar 2022 14:10:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=squareup.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=iRv99gRR+dDFqt3eRpswNmiSreBZ631Owy00tW6yZcU=; b=c37P/rYSqo6TcipSclHSiCTCd0xxWgz89Nf4rmIGY9y9jjel7xO28Lmh9gP6nJlR0C LX5ks4TT5WXNA3tYH4d2s8i/VdLCtak+f0FgUZmmbZbGLTd/WUV0Q+6D+AlTnhth42Fj pMdDo4lnir731OXifK8eqYIBmm9smt3/PbitM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=iRv99gRR+dDFqt3eRpswNmiSreBZ631Owy00tW6yZcU=; b=raBLmSQHYrVg/5B1ZCJOqhV5+hp5+wZ1JKHiqpr4FZ3kaOlpwtUYQgzOnwW3qURJ3b tFXGkGQ8kOxSXBLIZ4HiJDprkDZxPqrGRS3y3NMY5Ewv3iigSeE2QwPH/Q1DQH2s/M9Y 6WmMMlfeAiXWbi6PGr+SgJjEMH2UaYJD+TDrvuCqLta9lnRIawx3ZjCsttZNelfWZcC1 1M0hQcKRQK5MJvncTGCsHKVGEukgr8uAyCG+AcAVRaG7DG7yGJCbaG+L/lYTN3Fy0crb 2RWyxg9ppEqIxtJWfLjd4sHKJiiN8n26WUvtntcLZcut/Um5XKffQtwb59ETc8pxAaNU t6Vw== X-Gm-Message-State: AOAM531OHeC1tgd7gGdE31wtn5OAJxsBsVgoYycY2rv2CySj/csPrbpJ IhO0P++3duWfsrRUq5DEn0L9ag== X-Google-Smtp-Source: ABdhPJyhIbq2BD3mzyRKhiWn/+GC/52p+XjCj0nGHchwnpXbu+hGsVhnES70nSuyfEp5Tl3by9Q81g== X-Received: by 2002:a17:90a:6003:b0:1c6:64a9:2155 with SMTP id y3-20020a17090a600300b001c664a92155mr1740666pji.30.1647465030726; Wed, 16 Mar 2022 14:10:30 -0700 (PDT) Received: from localhost ([135.84.132.250]) by smtp.gmail.com with ESMTPSA id f21-20020a056a00239500b004f7a6d338c3sm4386234pfc.41.2022.03.16.14.10.29 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 16 Mar 2022 14:10:30 -0700 (PDT) From: Benjamin Li To: Daniel Lezcano , Amit Kucheria , Thara Gopinath Cc: Bjorn Andersson , Zac Crosby , Benjamin Li , Andy Gross , "Rafael J. Wysocki" , Zhang Rui , linux-pm@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/2] drivers: thermal: tsens: implement change_mode to disable sensor IRQs Date: Wed, 16 Mar 2022 14:09:45 -0700 Message-Id: <20220316210946.6935-3-benl@squareup.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220316210946.6935-1-benl@squareup.com> References: <20220316210946.6935-1-benl@squareup.com> Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Implement change_mode() to disable sensor IRQs when a sensor is disabled. Note that this commit does not touch: - The tsens device's CPU IRQ, which is global across all sensors on a tsens device. - Power/clock of the sensor. Future work is needed in the tsens_ops interface to support single-sensor disable + handle quirks (the only implementation of tsens_ops->enable and disable only supports individual enable/disable on some sensors, and others must be enabled/disabled as a block). 'echo disabled > .../thermal_zoneX/mode' will disable the thermal core's polling mechanism to check for threshold trips. However, tsens supports an interrupt mechanism to receive notification of trips, implemented in commit 634e11d5b450 ("drivers: thermal: tsens: Add interrupt support"). This is used sometimes to run performance test cases. Currently the thermal zone mode that's set by userspace does not control threshold trip events from IRQs. Let's fix this to restore the abilty to disable thermal throttling at runtime. ==================== Tested on MSM8939 running 5.17. This platform has 8 cores; the first four thermal zones control cpu0-3 and the last zone is for the other four CPUs together. for f in /sys/class/thermal/thermal_zone*; do echo "disabled" > $f/mode echo $f | paste - $f/type $f/mode done /sys/class/thermal/thermal_zone0 cpu0-thermal disabled /sys/class/thermal/thermal_zone1 cpu1-thermal disabled /sys/class/thermal/thermal_zone2 cpu2-thermal disabled /sys/class/thermal/thermal_zone3 cpu3-thermal disabled /sys/class/thermal/thermal_zone4 cpu4567-thermal disabled With mitigation thresholds at 75 degC and load running, we can now cruise past temp=75000 without CPU throttling kicking in. watch -n 1 "grep '' /sys/class/thermal/*/temp /sys/class/thermal/*/cur_state /sys/bus/cpu/devices/cpu*/cpufreq/cpuinfo_cur_freq" /sys/class/thermal/thermal_zone0/temp:82000 /sys/class/thermal/thermal_zone1/temp:84000 /sys/class/thermal/thermal_zone2/temp:87000 /sys/class/thermal/thermal_zone3/temp:84000 /sys/class/thermal/thermal_zone4/temp:84000 /sys/class/thermal/cooling_device0/cur_state:0 /sys/class/thermal/cooling_device1/cur_state:0 /sys/bus/cpu/devices/cpu0/cpufreq/cpuinfo_cur_freq:1113600 /sys/bus/cpu/devices/cpu1/cpufreq/cpuinfo_cur_freq:1113600 /sys/bus/cpu/devices/cpu2/cpufreq/cpuinfo_cur_freq:1113600 /sys/bus/cpu/devices/cpu3/cpufreq/cpuinfo_cur_freq:1113600 /sys/bus/cpu/devices/cpu4/cpufreq/cpuinfo_cur_freq:800000 /sys/bus/cpu/devices/cpu5/cpufreq/cpuinfo_cur_freq:800000 /sys/bus/cpu/devices/cpu6/cpufreq/cpuinfo_cur_freq:800000 /sys/bus/cpu/devices/cpu7/cpufreq/cpuinfo_cur_freq:800000 Reported-by: Zac Crosby Reviewed-by: Bjorn Andersson Signed-off-by: Benjamin Li --- drivers/thermal/qcom/tsens.c | 43 ++++++++++++++++++++++++++++++++++-- drivers/thermal/qcom/tsens.h | 4 ++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index 99a8d9f3e03c..d5263436f959 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -564,8 +564,12 @@ static int tsens_set_trips(void *_sensor, int low, int high) /* Write the new thresholds and clear the status */ regmap_field_write(priv->rf[LOW_THRESH_0 + hw_id], low_val); regmap_field_write(priv->rf[UP_THRESH_0 + hw_id], high_val); - tsens_set_interrupt(priv, hw_id, LOWER, true); - tsens_set_interrupt(priv, hw_id, UPPER, true); + s->trips_configured = true; + + if (s->enable_irqs) { + tsens_set_interrupt(priv, hw_id, LOWER, true); + tsens_set_interrupt(priv, hw_id, UPPER, true); + } spin_unlock_irqrestore(&priv->ul_lock, flags); @@ -575,6 +579,40 @@ static int tsens_set_trips(void *_sensor, int low, int high) return 0; } +static int tsens_change_mode(void *_sensor, enum thermal_device_mode mode) +{ + struct tsens_sensor *s = _sensor; + struct tsens_priv *priv = s->priv; + u32 hw_id = s->hw_id; + bool enable = (mode == THERMAL_DEVICE_ENABLED); + unsigned long flags; + + if (tsens_version(priv) < VER_0_1) { + /* Pre v0.1 IP had a single register for each type of interrupt + * and threshold, so we can't support individual enable/disable. + */ + hw_id = 0; + enable = true; + } + + spin_lock_irqsave(&priv->ul_lock, flags); + + /* During sensor registration, thermal core calls change_mode(ENABLED) + * before it calls set_trips(low, high). To avoid enabling threshold + * interrupts before thresholds are configured, let's let set_trips do + * the first enable. + */ + if (s->trips_configured) { + tsens_set_interrupt(priv, hw_id, LOWER, enable); + tsens_set_interrupt(priv, hw_id, UPPER, enable); + } + s->enable_irqs = enable; + + spin_unlock_irqrestore(&priv->ul_lock, flags); + + return 0; +} + static int tsens_enable_irq(struct tsens_priv *priv) { int ret; @@ -1002,6 +1040,7 @@ static const struct thermal_zone_of_device_ops tsens_of_ops = { .get_temp = tsens_get_temp, .get_trend = tsens_get_trend, .set_trips = tsens_set_trips, + .change_mode = tsens_change_mode, }; static int tsens_register_irq(struct tsens_priv *priv, char *irqname, diff --git a/drivers/thermal/qcom/tsens.h b/drivers/thermal/qcom/tsens.h index 1471a2c00f15..1a835d7688e0 100644 --- a/drivers/thermal/qcom/tsens.h +++ b/drivers/thermal/qcom/tsens.h @@ -45,6 +45,8 @@ enum tsens_irq_type { * @offset: offset of temperature adjustment curve * @hw_id: HW ID can be used in case of platform-specific IDs * @slope: slope of temperature adjustment curve + * @trips_configured: whether this sensor's upper/lower thresholds are set + * @enable_irqs: whether this sensor's threshold IRQs should be enabled * @status: 8960-specific variable to track 8960 and 8660 status register offset */ struct tsens_sensor { @@ -53,6 +55,8 @@ struct tsens_sensor { int offset; unsigned int hw_id; int slope; + bool trips_configured; + bool enable_irqs; u32 status; };