From patchwork Tue Nov 12 05:19:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Pitre X-Patchwork-Id: 13871737 Received: from fhigh-a7-smtp.messagingengine.com (fhigh-a7-smtp.messagingengine.com [103.168.172.158]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F1EF41A3BDE; Tue, 12 Nov 2024 05:22:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.158 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731388938; cv=none; b=uMn7v3nmuqxLQyNeK1Ke5G/E1S6leRlBr2vJMAeE2VG9xWKklaP5ao5E2ztaJXAzLGnBKbHtvwsvWDqdAQsvgn4gVk3oEXkrorwEkc1twP4HBFGRatZv3o+RkSRhcUCwQJ/I6KqU3+FAWKTOzjlABoLojQ7dfJzS8V70w8A5PTA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731388938; c=relaxed/simple; bh=1e+Tc2DW78hIcS81YoDcnInvTNlfYkBlO6mo88FyfgY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FWPTX2xyvcn4N+woF47Ummf57+BiiBhM/stpkR4oLT4CI41aM8eYv9mW2y4Ex3cih8mRS5s+FPFL0HneHG1Wd70Nqgw2TibfXwOiUzA70bHv6z2N5STKM8aX1CB9+4DV1rG83gA9HKbPgHDxDOrH6IoVYqUYvAtLXlzAhdVsrC0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=fluxnic.net; spf=pass smtp.mailfrom=fluxnic.net; dkim=pass (1024-bit key) header.d=fluxnic.net header.i=@fluxnic.net header.b=SAzbASsQ; dkim=pass (2048-bit key) header.d=pobox.com header.i=@pobox.com header.b=GMgjvh8i; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=n/ZqWwrM; arc=none smtp.client-ip=103.168.172.158 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=fluxnic.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fluxnic.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=fluxnic.net header.i=@fluxnic.net header.b="SAzbASsQ"; dkim=pass (2048-bit key) header.d=pobox.com header.i=@pobox.com header.b="GMgjvh8i"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="n/ZqWwrM" Received: from phl-compute-12.internal (phl-compute-12.phl.internal [10.202.2.52]) by mailfhigh.phl.internal (Postfix) with ESMTP id EAD1111401C7; Tue, 12 Nov 2024 00:22:14 -0500 (EST) Received: from phl-frontend-01 ([10.202.2.160]) by phl-compute-12.internal (MEProxy); Tue, 12 Nov 2024 00:22:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fluxnic.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=2016-12.pbsmtp; t=1731388934; x=1731475334; bh=qo85hZPOEbaIqOSv3+i46F4vrPDjYiXGCZHA8L//gAc=; b= SAzbASsQtvEGTn6mN69VvnE6mYNa2idz9BJ36JSbOGoY6pRs3YTbFvu/LIUym57+ rLN5aCO1Lj7j6JO06Ev4cQjQHd46NnJmoJpuzqw1VdY1dtBaZk2bbus0z0bDzMhP FsxXL5p6r9NuVw3rkA2MoZLwJc+cZDhGEL2GkpExeWI= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pobox.com; h=cc :cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm2; t=1731388934; x= 1731475334; bh=qo85hZPOEbaIqOSv3+i46F4vrPDjYiXGCZHA8L//gAc=; b=G Mgjvh8i/dJiXt5TOxJxFqezqkuz+VuhJEwt69MiwaRkwVSn9P3MfD9N77m7zleIL QjiqCBVvxHITNIK1k3X7+bL+44xypePVF8uPGxb9fCOBC+Z+xbtPUSMoQnH8i8UL ss0SkaYJoM181p31tRPdb5ixGQ155bEFRgNiNylrHkrWQSnDngArmLeztfrVg5bx ZizoNV5sYv+cxw5+X3llWkWCD16cY3hCsYGrM9mm7ScJmb7e6hQON4rJl2ezK5gh lXLVLybksha/oGVzpBzI3A7vU5CCkzYo+YIasHhtHc57nyeaS0ShZfOoOBTzgWJX PZh4KHftSNZ3f2ciER+0g== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1731388934; x=1731475334; bh=q o85hZPOEbaIqOSv3+i46F4vrPDjYiXGCZHA8L//gAc=; b=n/ZqWwrMp0CBV09IW Knoyc+AVPw31MPaBCdbKNuTVXoP5h39eXs40uOplBGTw2HgwndLsviord0vBWmw7 xGVOChqnropKn334GxbI7pB03jgpS2gs0kDoT3qcNEFAplj3XRsUOcxXLZ+mrsa8 6Z7BgkOiza72nRWN9GxH+nxmeK9e5ki7QQg3SADDTKnOXdbEREH/iwJgkELZhwY0 fBhIpnF8b2xGEAAdXx8ruyL0U6QjhjbFnJfTzmKUMVLZWlOQirtwlZpIE+JKA7+D tbxGQz7Bik90xb6Eda3CRENKuBum8WoYGeucXzgccYMwQE91MimWIMRXT77eZmPj kZBow== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrudefgdekvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdpuffr tefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnth hsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecu hfhrohhmpefpihgtohhlrghsucfrihhtrhgvuceonhhitghosehflhhugihnihgtrdhnvg htqeenucggtffrrghtthgvrhhnpedtjeeuieeiheeiueffuddvffelheekleegkedukeef fffhudffudegvdetiefhteenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmh grihhlfhhrohhmpehnihgtohesfhhluhignhhitgdrnhgvthdpnhgspghrtghpthhtohep kedpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtoheprggsrghilhhonhessggrhihlih gsrhgvrdgtohhmpdhrtghpthhtohepnhhpihhtrhgvsegsrgihlhhisghrvgdrtghomhdp rhgtphhtthhopehrrghfrggvlheskhgvrhhnvghlrdhorhhgpdhrtghpthhtohepuggrnh hivghlrdhlvgiitggrnhhosehlihhnrghrohdrohhrghdprhgtphhtthhopehlihhnuhig qdhmvgguihgrthgvkheslhhishhtshdrihhnfhhrrgguvggrugdrohhrghdprhgtphhtth hopeguvghvihgtvghtrhgvvgesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthho pehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtth hopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrgh X-ME-Proxy: Feedback-ID: i58514971:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 12 Nov 2024 00:22:14 -0500 (EST) Received: from xanadu.lan (OpenWrt.lan [192.168.1.1]) by yoda.fluxnic.net (Postfix) with ESMTPSA id DA8FBECB7FE; Tue, 12 Nov 2024 00:22:13 -0500 (EST) From: Nicolas Pitre To: Daniel Lezcano , "Rafael J . Wysocki" , linux-pm@vger.kernel.org, linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Nicolas Pitre , Alexandre Bailon Subject: [PATCH 1/5] thermal: of: properly parse coefficients with multiple thermal-sensors entries Date: Tue, 12 Nov 2024 00:19:38 -0500 Message-ID: <20241112052211.3087348-2-nico@fluxnic.net> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241112052211.3087348-1-nico@fluxnic.net> References: <20241112052211.3087348-1-nico@fluxnic.net> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Nicolas Pitre The thermal zone DT binding description says: coefficients: $ref: /schemas/types.yaml#/definitions/uint32-array description: An array of integers containing the coefficients of a linear equation that binds all the sensors listed in this thermal zone. The linear equation used is as follows, z = c0 * x0 + c1 * x1 + ... + c(n-1) * x(n-1) + cn where c0, c1, .., cn are the coefficients. Coefficients default to 1 in case this property is not specified. The coefficients are ordered and are matched with sensors by means of the sensor ID. Additional coefficients are interpreted as constant offset. And the code says: /* * For now, the thermal framework supports only one sensor per * thermal zone. Thus, we are considering only the first two * values as slope and offset. */ Furthermore, only bcm2711_thermal, bcm2835_thermal and ti-soc-thermal use these values. It is not clear how the equation in the bindings documentation should be interpreted especially in the context of multiple sensors and sensor aggregation. Assuming x0..xn are temperature values, coefficients have to be fractional values otherwise the sum won't correspond to a temperature anymore. So this patch interprets those coefficients as per-sensor weight for determining the aggregated temperature value instead. Also, in that context, constant offsets make no sense so they're always set to 0. Because those weights are integer values, they must all be provided otherwise they all default to 1. To preserve backward compatibility, the current behavior is preserved when "thermal-sensors" contains only one entry. The alternative interpretation is applied only when "thermal-sensors" holds multiple entries (which never happened so far). Signed-off-by: Nicolas Pitre --- drivers/thermal/thermal_of.c | 63 +++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index 07e0989716..b8ddd41247 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -136,7 +136,8 @@ static struct thermal_trip *thermal_of_trips_init(struct device_node *np, int *n return ERR_PTR(ret); } -static struct device_node *of_thermal_zone_find(struct device_node *sensor, int id) +static struct device_node *of_thermal_zone_find(struct device_node *sensor, + int id, int *index) { struct device_node *np, *tz; struct of_phandle_args sensor_specs; @@ -179,6 +180,8 @@ static struct device_node *of_thermal_zone_find(struct device_node *sensor, int if ((sensor == sensor_specs.np) && id == (sensor_specs.args_count ? sensor_specs.args[0] : 0)) { pr_debug("sensor %pOFn id=%d belongs to %pOFn\n", sensor, id, child); + /* return index only if multiple entries exist */ + *index = (count > 1) ? i : -1; tz = no_free_ptr(child); goto out; } @@ -213,11 +216,10 @@ static int thermal_of_monitor_init(struct device_node *np, int *delay, int *pdel return 0; } -static void thermal_of_parameters_init(struct device_node *np, +static void thermal_of_parameters_init(struct device_node *np, int index, struct thermal_zone_params *tzp) { - int coef[2]; - int ncoef = ARRAY_SIZE(coef); + int ncoef, count; int prop, ret; tzp->no_hwmon = true; @@ -226,18 +228,46 @@ static void thermal_of_parameters_init(struct device_node *np, tzp->sustainable_power = prop; /* - * For now, the thermal framework supports only one sensor per - * thermal zone. Thus, we are considering only the first two - * values as slope and offset. + * If only one sensor is specified in "thermal-sensors" (index == -1) + * then only the first two "coefficients" values are considered, and + * used as slope and offset (legacy interpretation). + * + * If /thermal-sensors" contains more than one sensor then index + * contains a positive value indicating the "coefficients" value of + * interest. The listed sensors are meant to be aggregated and the + * provided coefficients represent the relative weight among those + * sensors. The slope field is used for that purpose while the offset + * is always 0. */ - ret = of_property_read_u32_array(np, "coefficients", coef, ncoef); - if (ret) { - coef[0] = 1; - coef[1] = 0; + tzp->slope = 1; + tzp->offset = 0; + if (index == -1) { + int coef[2]; + + ncoef = ARRAY_SIZE(coef); + ret = of_property_read_u32_array(np, "coefficients", coef, ncoef); + if (!ret) { + tzp->slope = coef[0]; + tzp->offset = coef[1]; + } + } else { + ncoef = of_property_count_u32_elems(np, "coefficients"); + if (ncoef > 0) { + count = of_count_phandle_with_args(np, "thermal-sensors", + "#thermal-sensor-cells"); + if (ncoef != count) { + pr_err("%pOFn: sensors and coefficients mismatch\n", np); + } else { + int *coef = kmalloc(sizeof(*coef) * (index + 1), + GFP_KERNEL); + if (coef && + of_property_read_u32_array(np, "coefficients", + coef, (index + 1)) == 0) + tzp->slope = coef[index]; + kfree(coef); + } + } } - - tzp->slope = coef[0]; - tzp->offset = coef[1]; } static struct device_node *thermal_of_zone_get_by_name(struct thermal_zone_device *tz) @@ -386,9 +416,10 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node * const char *action; int delay, pdelay; int ntrips; + int index; int ret; - np = of_thermal_zone_find(sensor, id); + np = of_thermal_zone_find(sensor, id, &index); if (IS_ERR(np)) { if (PTR_ERR(np) != -ENODEV) pr_err("Failed to find thermal zone for %pOFn id=%d\n", sensor, id); @@ -411,7 +442,7 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node * goto out_kfree_trips; } - thermal_of_parameters_init(np, &tzp); + thermal_of_parameters_init(np, index, &tzp); of_ops.should_bind = thermal_of_should_bind; From patchwork Tue Nov 12 05:19:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Pitre X-Patchwork-Id: 13871733 Received: from fhigh-a7-smtp.messagingengine.com (fhigh-a7-smtp.messagingengine.com [103.168.172.158]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 130271B86E4; Tue, 12 Nov 2024 05:22:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.158 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731388937; cv=none; b=mvHNdYvlEQwaT6ecTHsT52aUSFd2NTjAzqenrAfcg8VCmkNhQf6VBdXLOL9CwCkOvevA+KoaXxxh+T2bJ4S7wiAQm9jPMEEhABeffUuP+/e7I+iW8WhcD8ggucXFn8FENhMHPbLwPcD46QjR9jLczbMv9lMnsppgI8YCwqgIx0c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731388937; c=relaxed/simple; bh=EgAk20EvJCg88PMVz2QRMrI6zJZOF2IbzwRr3YmAPss=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dXfPTB2gXsnRXV1nh3/iBeyB4t3CiekMhQsGIZ7632HzxTXzvaW+AebMH6NMRAFeMhdYWQAsopUd6lg522lKE19k3CXjwsD+wtoeenMgJk9e6JinlC4GVEFGv5EUanPED0At4YK5gcxxQNY6i18X7w7g/YzwC4hSH9xmpEIVIPU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=fluxnic.net; spf=pass smtp.mailfrom=fluxnic.net; dkim=pass (1024-bit key) header.d=fluxnic.net header.i=@fluxnic.net header.b=OOROsmSN; dkim=pass (2048-bit key) header.d=pobox.com header.i=@pobox.com header.b=eurYevQt; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=UPt3vMFa; arc=none smtp.client-ip=103.168.172.158 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=fluxnic.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fluxnic.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=fluxnic.net header.i=@fluxnic.net header.b="OOROsmSN"; dkim=pass (2048-bit key) header.d=pobox.com header.i=@pobox.com header.b="eurYevQt"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="UPt3vMFa" Received: from phl-compute-05.internal (phl-compute-05.phl.internal [10.202.2.45]) by mailfhigh.phl.internal (Postfix) with ESMTP id 4F3E311401D1; Tue, 12 Nov 2024 00:22:15 -0500 (EST) Received: from phl-frontend-02 ([10.202.2.161]) by phl-compute-05.internal (MEProxy); Tue, 12 Nov 2024 00:22:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fluxnic.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=2016-12.pbsmtp; t=1731388935; x=1731475335; bh=8kK3U8pQ/oVsZSw+Ik49NDaOUzj3r9K2JH8mb1XDC8U=; b= OOROsmSN51+kdEIZyYaKT1mqI2yX2LIxaWjlL5m7f2PIib14HlQiX3mbNlfV281D 3usjqHWfLupuoDHU4w+JD+BWiFXCthumm6AQGBhxV1h4ZnIZthjg2FLyQPcs7EsO lckkyahvAiwv3kmt1KvbRXY7ZM/BvV4gNI5wAitqG3g= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pobox.com; h=cc :cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm2; t=1731388935; x= 1731475335; bh=8kK3U8pQ/oVsZSw+Ik49NDaOUzj3r9K2JH8mb1XDC8U=; b=e urYevQt4J3NbEfLryNaK9IF308g1dkBj17a/JcSnIPxQYzSy3OlO3E4Q4UrDqamQ yUmpFY6X6nLWIDVSN6MAzKn37tWHpskm+F6i5Ooy+gNSjsHWLaiJZymJKFD/5F98 9Nn19RsBbZJjyGSbEgwJTcKqEkpKRp+CUxhBkFDe7uHRw3D6Kd5tXs0FmyywF8xQ U38xPggFEx1lVpfF+gU8of3jYg4XP2lON/HSJmdCyO5FZduUiKOStYX2KcddxtF3 /NgtJD9N8o5PB98yQ0AvBhW6Oddo3EdnkfDOAAqQbREwpLDjA0Uhxb0YDz4gbQOv KFE8bRddeIp1SUjgbbA9A== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1731388935; x=1731475335; bh=8 kK3U8pQ/oVsZSw+Ik49NDaOUzj3r9K2JH8mb1XDC8U=; b=UPt3vMFa5wj4iU3vf 3j4n34PWJy/ZVhyhSonlxnJV0xrfzQh+XONDax+Kqvv066EgWobO/PMYl8NgsgQ+ +FZWffxamm6BNquBUfFby++2XE4jA67iqEvsPXyAboLwM5o9rY/UXwpNw/T9PBOV HEAogTVG1y5TLAysvgY3r2K9M8QVYjMo2eWNu0B60PTAorOTxJ8MjIQGnioezf6K UTQqq8YMHFUqOFgX64EBrDJ5RCHIHuoWw75o7paN9m3OjGPUvnEpvsEV5utlyL0Y lJjmOo86dAHGX0N7Pb7+SxZKdB/cW/SbNlDulsvsRQP6T31tuuo63R7v6lrGceA2 Mc+CA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrudefgdekvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdpuffr tefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnth hsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecu hfhrohhmpefpihgtohhlrghsucfrihhtrhgvuceonhhitghosehflhhugihnihgtrdhnvg htqeenucggtffrrghtthgvrhhnpedtjeeuieeiheeiueffuddvffelheekleegkedukeef fffhudffudegvdetiefhteenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmh grihhlfhhrohhmpehnihgtohesfhhluhignhhitgdrnhgvthdpnhgspghrtghpthhtohep kedpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtoheprggsrghilhhonhessggrhihlih gsrhgvrdgtohhmpdhrtghpthhtohepnhhpihhtrhgvsegsrgihlhhisghrvgdrtghomhdp rhgtphhtthhopehrrghfrggvlheskhgvrhhnvghlrdhorhhgpdhrtghpthhtohepuggrnh hivghlrdhlvgiitggrnhhosehlihhnrghrohdrohhrghdprhgtphhtthhopehlihhnuhig qdhmvgguihgrthgvkheslhhishhtshdrihhnfhhrrgguvggrugdrohhrghdprhgtphhtth hopeguvghvihgtvghtrhgvvgesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthho pehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtth hopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrgh X-ME-Proxy: Feedback-ID: i58514971:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 12 Nov 2024 00:22:14 -0500 (EST) Received: from xanadu.lan (OpenWrt.lan [192.168.1.1]) by yoda.fluxnic.net (Postfix) with ESMTPSA id 01444ECB7FF; Tue, 12 Nov 2024 00:22:14 -0500 (EST) From: Nicolas Pitre To: Daniel Lezcano , "Rafael J . Wysocki" , linux-pm@vger.kernel.org, linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Nicolas Pitre , Alexandre Bailon Subject: [PATCH 2/5] dt-bindings: thermal: Restore the thermal-sensors property Date: Tue, 12 Nov 2024 00:19:39 -0500 Message-ID: <20241112052211.3087348-3-nico@fluxnic.net> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241112052211.3087348-1-nico@fluxnic.net> References: <20241112052211.3087348-1-nico@fluxnic.net> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Alexandre Bailon thermal-sensors was defined in thermal.txt but when the yaml binding has been defined, its definition has changed, dropping support of multi sensors. Since we are adding support of multi sensors, use the original definition for thermal-sensors property. Signed-off-by: Alexandre Bailon Reviewed-by: Rob Herring Signed-off-by: Nicolas Pitre --- Documentation/devicetree/bindings/thermal/thermal-zones.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml index 0f435be1db..cc98f87633 100644 --- a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml +++ b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml @@ -96,10 +96,9 @@ patternProperties: thermal-sensors: $ref: /schemas/types.yaml#/definitions/phandle-array - maxItems: 1 description: - The thermal sensor phandle and sensor specifier used to monitor this - thermal zone. + A list of thermal sensor phandles and sensor specifier + used while monitoring the thermal zone. coefficients: $ref: /schemas/types.yaml#/definitions/uint32-array From patchwork Tue Nov 12 05:19:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Pitre X-Patchwork-Id: 13871738 Received: from fout-a3-smtp.messagingengine.com (fout-a3-smtp.messagingengine.com [103.168.172.146]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 139F520720F; Tue, 12 Nov 2024 05:22:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.146 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731388939; cv=none; b=mwJuoZv56zC1DO9usQt317R0O0MFMKAtD8ZlaiwdC+I7vDAWgaO5xD49Vfa7xRqDoH0rFXcofCfWcb2OnpgzwjpMUj/B21d2CXNjkX9jxjOIha7LdcG3GcB8hnaGM9+lkyyZ6pBb1qpY0Srl5qKIygjG2N092NIyLE4nJAXzY/M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731388939; c=relaxed/simple; bh=8xwilQFGOCfXbB+ZJp+tGPxGwe3Aq/z9dFzjyvqsuZU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MOqVQk4cazSC65UVjkOve0460QZdtrw7h8iBlrGY8+/kUlEbpx9CbEGsze/2uJI/UAqedTaeiozGVCAGMUnM0j1Ls1v/d78NRjmuf2lUIzgsc9i/3iPMDG4bs2ATtuQytFNP44LwEvN3JBDVs9eWtgRGVz5CqjwiBljFg8qT/9s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=fluxnic.net; spf=pass smtp.mailfrom=fluxnic.net; dkim=pass (1024-bit key) header.d=fluxnic.net header.i=@fluxnic.net header.b=b2Ub0Gix; dkim=pass (2048-bit key) header.d=pobox.com header.i=@pobox.com header.b=QrZyyn/s; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=Tmq4MrcL; arc=none smtp.client-ip=103.168.172.146 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=fluxnic.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fluxnic.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=fluxnic.net header.i=@fluxnic.net header.b="b2Ub0Gix"; dkim=pass (2048-bit key) header.d=pobox.com header.i=@pobox.com header.b="QrZyyn/s"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="Tmq4MrcL" Received: from phl-compute-03.internal (phl-compute-03.phl.internal [10.202.2.43]) by mailfout.phl.internal (Postfix) with ESMTP id 185A113800AB; Tue, 12 Nov 2024 00:22:15 -0500 (EST) Received: from phl-frontend-02 ([10.202.2.161]) by phl-compute-03.internal (MEProxy); Tue, 12 Nov 2024 00:22:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fluxnic.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=2016-12.pbsmtp; t=1731388935; x=1731475335; bh=Nq/6/CpfdvFHxWlMyGuOOsUGAG0x/aWCQ1FsqavQtag=; b= b2Ub0GixUiKwPuZ7/wiIbHZA9KFM9ovk3JvBNwwfoGaSBvnP1u6EvYJTgWPNDhlM ZwSOgebG0AaFjSZMgiJzpuPR88wdq1t4bxvKJPW478/VmYBqa6vQ/N4E3T0CLtXw lzdKFXQ+xHIGkQT0tp2C0kDPikyED6X9G1q+H35XVIM= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pobox.com; h=cc :cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm2; t=1731388935; x= 1731475335; bh=Nq/6/CpfdvFHxWlMyGuOOsUGAG0x/aWCQ1FsqavQtag=; b=Q rZyyn/sYsLDHeMObQHre8KQqKi7dIoa2X8OKkWeMG7jFbiT9EZvv4H3pbmYSfc+m y1PrfnpeE3xb5f4wcgQuPTtJzs+zg6KWAF79iWVZH62nor2YfW6uUEm3cs9ncoG6 eXrSbYcSILbRoVLS4DFkN2d/TIeyVWo1YHo1a/guMtDJ5QfjCM5cR4qyw5X7JW2S rmlH7TVqsY1lHEFFPQjhrTOW1TsBhq5QbAeDGNnjchf57bIOdWgzOljQ2Ddq9rVB JOR3fhINmFwsyCO6WTpypZOMJ6uKFMZaUqDOur3RtxgsfR9L43vlavlAN/o6zFWQ eJRqC0ivzt6FpfAAXmg1g== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1731388935; x=1731475335; bh=N q/6/CpfdvFHxWlMyGuOOsUGAG0x/aWCQ1FsqavQtag=; b=Tmq4MrcLscEkBmac1 MWosvcbvpDyrcO7Aoz71MPLfUrMqmKWWspkg08d1x5x2TOYBZCFe8NLsF3OPPN+r 92C3dOCYFsAjyHSZ/+ydxNQOgDrgVfGSvUgHUTwlQVR324lg9N4Y6q1Zbx3It2KS v795n5P0L9bPXYLxlis+bpT5Q6wHrb2amxvTfsc3hPYiD5EMyVsgyNlTaUWOoaC4 y2qw3+l6+bk+PjDwUqYeIKXDMMW5w4KHNj5LS1pu4XbKeBJlGWjAC4t9Uh8UQSG8 E5kVe2wJ8J08jwPliADl98KBbCMRwZ4oqrldiav1Ksic2YxbeTJFvetfP9zMZ7QW gJqvQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrudefgdekvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdpuffr tefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnth hsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecu hfhrohhmpefpihgtohhlrghsucfrihhtrhgvuceonhhitghosehflhhugihnihgtrdhnvg htqeenucggtffrrghtthgvrhhnpedtjeeuieeiheeiueffuddvffelheekleegkedukeef fffhudffudegvdetiefhteenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmh grihhlfhhrohhmpehnihgtohesfhhluhignhhitgdrnhgvthdpnhgspghrtghpthhtohep kedpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtoheprggsrghilhhonhessggrhihlih gsrhgvrdgtohhmpdhrtghpthhtohepnhhpihhtrhgvsegsrgihlhhisghrvgdrtghomhdp rhgtphhtthhopehrrghfrggvlheskhgvrhhnvghlrdhorhhgpdhrtghpthhtohepuggrnh hivghlrdhlvgiitggrnhhosehlihhnrghrohdrohhrghdprhgtphhtthhopehlihhnuhig qdhmvgguihgrthgvkheslhhishhtshdrihhnfhhrrgguvggrugdrohhrghdprhgtphhtth hopeguvghvihgtvghtrhgvvgesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthho pehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtth hopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrgh X-ME-Proxy: Feedback-ID: i58514971:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 12 Nov 2024 00:22:14 -0500 (EST) Received: from xanadu.lan (OpenWrt.lan [192.168.1.1]) by yoda.fluxnic.net (Postfix) with ESMTPSA id 17908ECB800; Tue, 12 Nov 2024 00:22:14 -0500 (EST) From: Nicolas Pitre To: Daniel Lezcano , "Rafael J . Wysocki" , linux-pm@vger.kernel.org, linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Nicolas Pitre , Alexandre Bailon Subject: [PATCH 3/5] thermal: aggregation support Date: Tue, 12 Nov 2024 00:19:40 -0500 Message-ID: <20241112052211.3087348-4-nico@fluxnic.net> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241112052211.3087348-1-nico@fluxnic.net> References: <20241112052211.3087348-1-nico@fluxnic.net> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Nicolas Pitre This provides support for the creation of virtual thermal zone devices that serve as aggregation point for other devices. Individual primary thermal devices remain accessible in sysfs but all cooling device bindings are moved over to the thermal aggregator whose temperature is the weighted average of its primary devices. Trip points are inherited from the aggregator but only the aggregator will bind to cooling devices. Although cooling devices are bound to the aggregator, critical trip points remain individually accessible, and more importantly triggerable for each primary device. Full visibility of primary devices is preserved via the sysfs interface. Some sysfs symbolic links are created to represent the hierarchical relationship between the aggregator and its primary devices. When this is enabled, the aggregation is applied to all entries found in the device tree's "thermal-sensors" list when it contains more than one entry. For example, let's consider: ``` thermal_zones: thermal-zones { cpu0-thermal { thermal-sensors = <&sensor_mcu 0>; }; cpu1-thermal { thermal-sensors = <&sensor_mcu 1>; }; }; ``` The above won't provide any aggregation. However: ``` thermal_zones: thermal-zones { cluster0-thermal { thermal-sensors = <&sensor_mcu 0>, <&sensor_mcu 1>; coefficients = <6 4>; }; }; ``` The above will create the "cluster0-thermal" aggregator that combines the "sensor_mcu(0)" and "sensor_mcu(1)" primary zones whose thermal measurement contributions are 60% and 40% respectively. In sysfs we have: ``` $ cd /sys/class/thermal $ ls -l thermal_zone*/aggregator lrwxrwxrwx 1 root root ... thermal_zone5/aggregator -> ../thermal_zone4 lrwxrwxrwx 1 root root ... thermal_zone6/aggregator -> ../thermal_zone4 $ ls ls -l thermal_zone*/primary_zone* lrwxrwxrwx 1 root root ... thermal_zone4/primary_zone_0 -> ../thermal_zone5 lrwxrwxrwx 1 root root ... thermal_zone4/primary_zone_1 -> ../thermal_zone6 $ cat thermal_zone4/type cluster0-thermal $ cat thermal_zone*/primary_zone*/type sensor_mcu(0) sensor_mcu(1) ``` Future work may allow the addition and removal of primary thermal zones to an aggregadirectly tor within sysfs for added flexibility. Signed-off-by: Nicolas Pitre --- drivers/thermal/Kconfig | 15 ++ drivers/thermal/thermal_core.c | 416 +++++++++++++++++++++++++++++++++ drivers/thermal/thermal_core.h | 14 ++ drivers/thermal/thermal_of.c | 23 +- 4 files changed, 467 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 61e7ae524b..111f07b52a 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -220,6 +220,21 @@ config DEVFREQ_THERMAL If you want this support, you should say Y here. +config THERMAL_AGGREGATION + bool "Thermal zone aggregation support" + depends on THERMAL_OF + help + This provides support for the creation of virtual thermal zone + devices that serve as aggregation point for other devices. + Individual primary thermal devices remain accessible in sysfs + but all cooling device bindings are moved over to the thermal + aggregator whose temperature is the weighted average of its + primary devices. + + When this is enabled, the aggregation is applied to all entries + found in the device tree's "thermal-sensors" list when it contains + more than one entry. + config THERMAL_EMULATION bool "Thermal emulation mode support" help diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 8f03985f97..73a1b30081 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -748,6 +748,13 @@ struct thermal_zone_device *thermal_zone_get_by_id(int id) * binding, and unbinding. */ +#ifdef CONFIG_THERMAL_AGGREGATION +static void thermal_remove_tz_from_aggregator(struct thermal_zone_device *tz); +#else +static inline void thermal_remove_tz_from_aggregator(struct thermal_zone_device *tz) +{} +#endif /* CONFIG_THERMAL_AGGREGATION */ + /** * thermal_bind_cdev_to_trip - bind a cooling device to a thermal zone * @tz: pointer to struct thermal_zone_device @@ -1577,6 +1584,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) thermal_debug_tz_remove(tz); + thermal_remove_tz_from_aggregator(tz); + mutex_lock(&thermal_list_lock); list_for_each_entry(pos, &thermal_tz_list, node) if (pos == tz) @@ -1654,6 +1663,413 @@ struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name) } EXPORT_SYMBOL_GPL(thermal_zone_get_zone_by_name); +#ifdef CONFIG_THERMAL_AGGREGATION + +static LIST_HEAD(thermal_aggregator_list); + +struct thermal_zone_aggregator { + struct thermal_zone_device *tz; + struct list_head primary_tz_list; + struct mutex lock; + struct ida ida; + struct list_head node; +}; + +static bool is_aggregated(struct thermal_zone_device *tz) +{ + return tz->aggregator != NULL; +} + +/* + * Get weighted average temperature for all aggregated zones. + * + * A "max temp" variant could also be provided but the end result on the + * cooling device would be the same as if no aggregation was done in the + * first place. + */ +static int thermal_aggr_get_average_temp(struct thermal_zone_device *aggr_tz, + int *aggr_temp) +{ + struct thermal_zone_aggregator *aggr = aggr_tz->devdata; + struct thermal_zone_device *tz; + int temp, weight; + s64 temp_sum = 0; + u32 weight_sum = 0; + int ret = -ENODATA; + + mutex_lock(&aggr->lock); + list_for_each_entry(tz, &aggr->primary_tz_list, aggregated_node) { + mutex_lock(&tz->lock); + if (tz->suspended || tz->mode != THERMAL_DEVICE_ENABLED) { + mutex_unlock(&tz->lock); + continue; + } + ret = __thermal_zone_get_temp(tz, &temp); + if (ret) { + mutex_unlock(&tz->lock); + break; + } + if (temp <= THERMAL_TEMP_INVALID) { + /* + * Invalid temp values are ignored, unless all + * primary zones are invalid in which case it is + * passed up to accommodate the special case in + * __thermal_zone_device_update(). + */ + *aggr_temp = temp; + } else { + weight = tz->tzp->slope; + temp_sum += (s64)temp * weight; + weight_sum += weight; + } + mutex_unlock(&tz->lock); + } + mutex_unlock(&aggr->lock); + + if (weight_sum) + *aggr_temp = div_s64(temp_sum, weight_sum); + + return ret; +} + +static int thermal_aggr_set_trips(struct thermal_zone_device *aggr_tz, + int low, int high) +{ + struct thermal_zone_aggregator *aggr = aggr_tz->devdata; + struct thermal_zone_device *tz; + + mutex_lock(&aggr->lock); + list_for_each_entry(tz, &aggr->primary_tz_list, aggregated_node) { + mutex_lock(&tz->lock); + if (!tz->suspended && tz->mode == THERMAL_DEVICE_ENABLED) + thermal_zone_set_trips(tz, low, high); + mutex_unlock(&tz->lock); + } + mutex_unlock(&aggr->lock); + + return 0; +} + +static int thermal_aggr_change_mode(struct thermal_zone_device *aggr_tz, + enum thermal_device_mode mode) +{ + struct thermal_zone_aggregator *aggr = aggr_tz->devdata; + struct thermal_zone_device *tz; + int ret, err = 0; + + mutex_lock(&aggr->lock); + list_for_each_entry(tz, &aggr->primary_tz_list, aggregated_node) { + ret = thermal_zone_device_set_mode(tz, mode); + if (ret) + err = ret; + /* cycle through all tz's even if there are errors */ + } + mutex_unlock(&aggr->lock); + + return err; +} + +static const struct thermal_zone_device_ops thermal_aggr_tz_ops = { + .get_temp = thermal_aggr_get_average_temp, + .set_trips = thermal_aggr_set_trips, + .change_mode = thermal_aggr_change_mode, +}; + +/** + * create_thermal_aggregator - create a tz to be used as an aggregator + * + * @ref_tz: the tz from which parameters such as trip values are copied + * @name: name to identify this aggregator + * + * This creates a virtual thermal zone to be used as an aggregator for + * other zones called "primary" zones. Those primary zones must be added to + * the created aggregator with add_tz_to_aggregator(). + * + * Return: a pointer to the created struct thermal_zone_device or an ERR_PTR + * value in case of errors. + */ +static struct thermal_zone_device * +create_thermal_aggregator(struct thermal_zone_device *ref_tz, const char *name) +{ + struct thermal_zone_aggregator *aggr; + struct thermal_zone_device *aggr_tz; + struct thermal_trip *trips; + int ntrips = ref_tz->num_trips; + int ret; + + trips = kcalloc(ntrips, sizeof(*trips), GFP_KERNEL); + if (!trips) + return ERR_PTR(-ENOMEM); + for (int i = 0; i < ntrips; i++) + trips[i] = ref_tz->trips[i].trip; + + aggr = kzalloc(sizeof(*aggr), GFP_KERNEL); + if (!aggr) { + ret = -ENOMEM; + goto err_free_trips; + } + mutex_init(&aggr->lock); + INIT_LIST_HEAD(&aggr->primary_tz_list); + ida_init(&aggr->ida); + + aggr_tz = thermal_zone_device_register_with_trips(name, trips, ntrips, + aggr, + &thermal_aggr_tz_ops, + ref_tz->tzp, 0, 0); + if (IS_ERR(aggr_tz)) { + ret = PTR_ERR(aggr_tz); + pr_err("Failed to register thermal aggregator zone: %d\n", ret); + goto err_free_aggr; + } + aggr_tz->polling_delay_jiffies = ref_tz->polling_delay_jiffies; + aggr_tz->passive_delay_jiffies = ref_tz->passive_delay_jiffies; + aggr_tz->ops.should_bind = ref_tz->ops.should_bind; + aggr->tz = aggr_tz; + kfree(trips); + + ret = thermal_zone_device_enable(aggr_tz); + if (ret) { + pr_err("Failed to enable thermal aggregator zone: %d\n", ret); + goto err_unregister_tz; + } + + mutex_lock(&thermal_list_lock); + list_add_tail(&aggr->node, &thermal_aggregator_list); + mutex_unlock(&thermal_list_lock); + + return aggr_tz; + +err_unregister_tz: + thermal_zone_device_unregister(aggr_tz); +err_free_aggr: + ida_destroy(&aggr->ida); + kfree(aggr); +err_free_trips: + kfree(trips); + return ERR_PTR(ret); +} + +/** + * add_tz_to_aggregator() - add a primary zone to an aggregator + * + * @aggr_tz: the aggregator tz to use, as returned by create_thermal_aggregator() + * @tz: a primary tz to be added + * + * This enrolls a primary tz with an aggregator tz. Thermal instances + * (bindings) from the primary tz are moved to the aggregator. It is assumed + * that all primary tz's added to a given aggregator have the same set of + * trip points. This can be called with an already enrolled tz in which case + * only new thermal instances from the primary, if any, will be moved over + * to the aggregator. Duplicate thermal instances are simply dropped. + * + * An "aggregator" symlink is created within the primary tz's sysfs directory + * to the aggregator tz directory. And a list of "primary_zone_" symlinks + * in the aggregator's directory point back to all primary tz's it owns. + */ +static void add_tz_to_aggregator(struct thermal_zone_device *aggr_tz, + struct thermal_zone_device *tz) +{ + struct thermal_zone_aggregator *aggr = aggr_tz->devdata; + struct thermal_instance *ti, *next; + int ret; + + mutex_lock(&aggr->lock); + mutex_lock(&aggr_tz->lock); + mutex_lock(&tz->lock); + + /* duplicate thermal instances onto the aggregator */ + list_for_each_entry(ti, &tz->thermal_instances, tz_node) { + int i = thermal_zone_trip_id(tz, ti->trip); + struct thermal_trip *aggr_trip = &aggr_tz->trips[i].trip; + struct thermal_cooling_device *cdev = ti->cdev; + struct cooling_spec c = { + .upper = ti->upper_no_limit ? THERMAL_NO_LIMIT : ti->upper, + .lower = ti->lower, + .weight = ti->weight, + }; + ret = thermal_bind_cdev_to_trip(aggr_tz, aggr_trip, cdev, &c); + if (ret == -EEXIST) + ret = 0; + if (ret) { + print_bind_err_msg(aggr_tz, aggr_trip, cdev, ret); + goto out; + } + } + + /* remove thermal instances from the primary tz */ + list_for_each_entry_safe(ti, next, &tz->thermal_instances, tz_node) { + thermal_unbind_cdev_from_trip(tz, ti->trip, ti->cdev); + } + + if (!tz->aggregator) { + list_add_tail(&tz->aggregated_node, &aggr->primary_tz_list); + tz->aggregator = aggr_tz; + + /* add a link from the primary tz to its aggregator */ + ret = sysfs_create_link(&tz->device.kobj, + &aggr_tz->device.kobj, + "aggregator"); + if (ret) + dev_err(&tz->device, "linking to aggregator failed: %d\n", ret); + + /* add a link from the aggregator to this primary tz */ + tz->aggregated_id = ret = ida_alloc(&aggr->ida, GFP_KERNEL); + if (ret >= 0) { + char name[sizeof("primary_zone_000")]; + + snprintf(name, sizeof(name), "primary_zone_%d", ret); + ret = sysfs_create_link(&aggr_tz->device.kobj, + &tz->device.kobj, + name); + if (ret) { + ida_free(&aggr->ida, tz->aggregated_id); + tz->aggregated_id = -1; + } + } + if (ret) + dev_err(&aggr_tz->device, "linking to primary failed: %d\n", ret); + } + +out: + mutex_unlock(&tz->lock); + mutex_unlock(&aggr_tz->lock); + mutex_unlock(&aggr->lock); +} + +/** + * free_thermal_aggregator_unlock - unregister and free an aggregator tz + * + * @aggr_tz: the aggregator to free, as returned by create_thermal_aggregator() + * + * This unregisters the tz used as an aggregator and frees its associated + * memory. This is called by thermal_remove_tz_from_aggregator() when the + * last primary tz is removed from the aggregator, or if the aggregator was + * created and is no longer needed before any primary tz's have been added + * to it. + * + * Note: To avoid race issues, this is expected to be called with + * thermal_list_lock held, but it will be released before returning. + */ +static void free_thermal_aggregator_unlock(struct thermal_zone_device *aggr_tz) +{ + struct thermal_zone_aggregator *aggr = aggr_tz->devdata; + + lockdep_assert_held(&thermal_list_lock); + BUG_ON(!list_empty(&aggr->primary_tz_list)); + + list_del(&aggr->node); + mutex_unlock(&thermal_list_lock); + + thermal_zone_device_disable(aggr_tz); + thermal_zone_device_unregister(aggr_tz); + ida_destroy(&aggr->ida); + kfree(aggr); +} + +/** + * thermal_remove_tz_from_aggregator - remove a primary tz from an aggregator + * + * @tz: the thermal zone to remove from its aggregator + * + * This retires a primary tz from its aggregator. If not aggregated, this + * is a no-op. Thermal instance bindings are re-established with the primary + * tz. + * + * If given tz was the last one owned by the aggregator, then the aggregator + * is destroyed. + */ +static void thermal_remove_tz_from_aggregator(struct thermal_zone_device *tz) +{ + struct thermal_zone_device *aggr_tz = tz->aggregator; + struct thermal_zone_aggregator *aggr = aggr_tz->devdata; + struct thermal_cooling_device *cdev; + + if (!is_aggregated(tz)) + return; + + mutex_lock(&thermal_list_lock); + + /* Bind cooling devices back to this zone */ + tz->ops.should_bind = aggr_tz->ops.should_bind; + list_for_each_entry(cdev, &thermal_cdev_list, node) + thermal_zone_cdev_bind(tz, cdev); + + mutex_lock(&aggr->lock); + list_del(&tz->aggregated_node); + tz->aggregator = NULL; + sysfs_remove_link(&tz->device.kobj, "aggregator"); + if (tz->aggregated_id >= 0) { + char name[sizeof("primary_zone_000")]; + + snprintf(name, sizeof(name), "primary_zone_%d", tz->aggregated_id); + sysfs_remove_link(&aggr_tz->device.kobj, name); + ida_free(&aggr->ida, tz->aggregated_id); + } + mutex_unlock(&aggr->lock); + + if (list_empty(&aggr->primary_tz_list)) { + /* no more tz tied to this aggregator */ + free_thermal_aggregator_unlock(aggr_tz); + } else { + mutex_unlock(&thermal_list_lock); + } +} + +/** + * thermal_zone_device_aggregate - aggregate provided thermal zone device + * + * @tz: the thermal zone to aggregate + * @name: the aggregator's name to use + * + * This adds the provided thermal zone device to the thermal aggregator + * identified by @name. If no such aggregator exists it is created. + * + * In case of any error, the provided thermal zone will remain freestanding + * on its own and an error message will be logged. There is no point returning + * an error as it would be unwise for the caller to revert registration of + * this tz anyway (a suboptimal thermal configuration is better than no + * configuration). + */ +void thermal_zone_device_aggregate(struct thermal_zone_device *tz, + const char *name) +{ + struct thermal_zone_aggregator *aggr; + struct thermal_zone_device *aggr_tz; + + /* look for an existing aggregator */ + mutex_lock(&thermal_list_lock); + list_for_each_entry(aggr, &thermal_aggregator_list, node) { + aggr_tz = aggr->tz; + if (strcmp(aggr_tz->type, name) != 0) + continue; + if (aggr_tz->ops.should_bind != tz->ops.should_bind) { + pr_err("%s: same name but ops.should_bind differs\n", + __func__); + goto out; + } + goto add; + } + mutex_unlock(&thermal_list_lock); + + /* no aggregator with specified name exists, create one */ + aggr_tz = create_thermal_aggregator(tz, name); + if (IS_ERR(aggr_tz)) { + pr_err("unable to create thermal aggregator (%ld)\n", + PTR_ERR(aggr_tz)); + return; + } + + mutex_lock(&thermal_list_lock); +add: + add_tz_to_aggregator(aggr_tz, tz); + if (is_aggregated(tz)) + tz->ops.should_bind = NULL; +out: + mutex_unlock(&thermal_list_lock); +} + +#endif /* CONFIG_THERMAL_AGGREGATION */ + static void thermal_zone_device_resume(struct work_struct *work) { struct thermal_zone_device *tz; diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index a64d39b1c8..ff5aa20e82 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -136,6 +136,11 @@ struct thermal_zone_device { enum thermal_notify_event notify_event; bool suspended; bool resuming; +#ifdef CONFIG_THERMAL_AGGREGATION + struct thermal_zone_device *aggregator; + struct list_head aggregated_node; + int aggregated_id; +#endif #ifdef CONFIG_THERMAL_DEBUGFS struct thermal_debugfs *debugfs; #endif @@ -287,4 +292,13 @@ thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev, unsigned long new_state) {} #endif /* CONFIG_THERMAL_STATISTICS */ +#ifdef CONFIG_THERMAL_AGGREGATION +void thermal_zone_device_aggregate(struct thermal_zone_device *tz, + const char *aggr_name); +#else +static inline void +thermal_zone_device_aggregate(struct thermal_zone_device *tz, const char *aggr_name) +{} +#endif /* CONFIG_THERMAL_AGGREGATION */ + #endif /* __THERMAL_CORE_H__ */ diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index b8ddd41247..1761a60db5 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -451,7 +451,25 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node * if (!of_ops.critical && !strcasecmp(action, "reboot")) of_ops.critical = thermal_zone_device_critical_reboot; - tz = thermal_zone_device_register_with_trips(np->name, trips, ntrips, + /* + * The device tree node name is used with single-sensor entries. + * When multiple-sensor entries are aggregated, the node name is used + * for the aggregator and primary sensors use their compatible alias + * name with the id value. + */ + bool multi = (index != -1); + char namebuf[THERMAL_NAME_LENGTH]; + const char *tz_name = namebuf; + + if (!multi) + tz_name = np->name; + else if (of_alias_from_compatible(sensor, namebuf, sizeof(namebuf)) == 0) + snprintf(namebuf + strlen(namebuf), sizeof(namebuf) - strlen(namebuf), + "(%d)", id); + else + snprintf(namebuf, sizeof(namebuf), "%s(%d)", sensor->name, id); + + tz = thermal_zone_device_register_with_trips(tz_name, trips, ntrips, data, &of_ops, &tzp, pdelay, delay); if (IS_ERR(tz)) { @@ -460,6 +478,9 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node * goto out_kfree_trips; } + if (multi) + thermal_zone_device_aggregate(tz, np->name); + of_node_put(np); kfree(trips); From patchwork Tue Nov 12 05:19:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Pitre X-Patchwork-Id: 13871735 Received: from fout-a3-smtp.messagingengine.com (fout-a3-smtp.messagingengine.com [103.168.172.146]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 13999204932; Tue, 12 Nov 2024 05:22:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.146 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731388938; cv=none; b=dpmkhgXl09gA+8v7HZRMpL4Zo3Kmpb/dGkcQds7W5p0HXzSrLSqIV2keL0fzyyUk5PsDyPrXT0Jk3vlLSieWcQNec8PTWKV9OzW0EShJGE41VJ0RHEBP5GyKHvdr9ggmfOg9ySGLXKWa8UnlnGujoom+L7ebL+dRQwVBSi40KL0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731388938; c=relaxed/simple; bh=zni73RqvremBaxqTSqo+uI0FtebRS0qFn43PsYFOywA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KkT8GT/RI8JN/ZOHFLdb2YX/Fl/afuoyVCIpyJFEOm63j4o4qo4xifwG3z/joRZAXm4Iy60WnBb5GStZdtN9mEOuQOPwaYyZlk5gpdGrkrSkUzagHgLUYRMNPTbjGJ7hfPndbsprw0nc/9ZreJbKdwMXDnHOs3JaXr1M3ZfdSHE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=fluxnic.net; spf=pass smtp.mailfrom=fluxnic.net; dkim=pass (1024-bit key) header.d=fluxnic.net header.i=@fluxnic.net header.b=jYatm4tJ; dkim=pass (2048-bit key) header.d=pobox.com header.i=@pobox.com header.b=Ihlurd1z; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=ntcc2Tke; arc=none smtp.client-ip=103.168.172.146 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=fluxnic.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fluxnic.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=fluxnic.net header.i=@fluxnic.net header.b="jYatm4tJ"; dkim=pass (2048-bit key) header.d=pobox.com header.i=@pobox.com header.b="Ihlurd1z"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="ntcc2Tke" Received: from phl-compute-01.internal (phl-compute-01.phl.internal [10.202.2.41]) by mailfout.phl.internal (Postfix) with ESMTP id 3CB5E1380171; Tue, 12 Nov 2024 00:22:15 -0500 (EST) Received: from phl-frontend-01 ([10.202.2.160]) by phl-compute-01.internal (MEProxy); Tue, 12 Nov 2024 00:22:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fluxnic.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=2016-12.pbsmtp; t=1731388935; x=1731475335; bh=5bdj/n2LgxLKoSXpmbjX7w9HpSLYegxH5T6o6/+YLS4=; b= jYatm4tJFXRKm7NQ8XYg2KX0WHovLYH0dUK9B1MYh4UMuZc7QetfVrW1VMzX/c4L xK2+kCKgriOtR4B/LdRxzV46koiaEUk0oAudOcmLX+g1rhoTAwI2XsbUUEOmvR5V Ln8DpIn4c8FWmvyK5bmLxcak+WObR2zi1cFXKdxjDbs= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pobox.com; h=cc :cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm2; t=1731388935; x= 1731475335; bh=5bdj/n2LgxLKoSXpmbjX7w9HpSLYegxH5T6o6/+YLS4=; b=I hlurd1z1Sd2ci34BmfzTXcoQ/Is08G1unGuXoEmyREBNmgqiGPinELUWuqKsFpL4 4B3dXnkhDdrdAyvepACJVP1hMPbw39nno52z7+3reN0IcqeyM4XJSnE5CUG9fCD7 cFUlD8DkGk0CtDZmk8IkllwAPDFbCtjcaeIpnXzqm/x2U9bEt6Eh9OPwTSu6LG9M ISPiXpbn47r2momwV/TkJz+RC4bqyijlH9trQ7Y+iP7ZPITJ0uoEvai2+vCdzj6f 14XZIqHbUJrfuOgkSvMtp3iYcTAsyN3GyaW3/C7PWX/7Sq+YTFrSlb8kjRQpcPnL FOVeGdkCN3KKC44lMpMcw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1731388935; x=1731475335; bh=5 bdj/n2LgxLKoSXpmbjX7w9HpSLYegxH5T6o6/+YLS4=; b=ntcc2TkeDYUK6tgEf YYUrMidO7bng67ULq+kMCjMT7f5peMKz/HNy4QQF4jJlwYhz+kqi4jLin+M3n8jl 47vfMBjOwl9uwXB8FDKHi4BreoLeyt9wkkgLlDUO+dkN18QeMpOloyFSAGKvn1KD KUT7tioNiMTN7nHE+GqG8FGFxSFz7fmbtsixyyC0MFoV5r77FA/wXkAMrXTuVEpC z63Wu1zl+e/DhMszVclkEIeswHXVXRiiUF8pWfSkrWMizulwFkP5nlWrretiMm7R oM4sOOc+aFkpQfGx5nD+5OrH/u5R4uJ9AuIIHIY+vJJ5PwtiSeq9FL1PNr/Pk3OO 3RQ9w== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrudefgdekvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdpuffr tefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnth hsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecu hfhrohhmpefpihgtohhlrghsucfrihhtrhgvuceonhhitghosehflhhugihnihgtrdhnvg htqeenucggtffrrghtthgvrhhnpedtjeeuieeiheeiueffuddvffelheekleegkedukeef fffhudffudegvdetiefhteenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmh grihhlfhhrohhmpehnihgtohesfhhluhignhhitgdrnhgvthdpnhgspghrtghpthhtohep kedpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtoheprggsrghilhhonhessggrhihlih gsrhgvrdgtohhmpdhrtghpthhtohepnhhpihhtrhgvsegsrgihlhhisghrvgdrtghomhdp rhgtphhtthhopehrrghfrggvlheskhgvrhhnvghlrdhorhhgpdhrtghpthhtohepuggrnh hivghlrdhlvgiitggrnhhosehlihhnrghrohdrohhrghdprhgtphhtthhopehlihhnuhig qdhmvgguihgrthgvkheslhhishhtshdrihhnfhhrrgguvggrugdrohhrghdprhgtphhtth hopeguvghvihgtvghtrhgvvgesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthho pehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtth hopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrgh X-ME-Proxy: Feedback-ID: i58514971:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 12 Nov 2024 00:22:14 -0500 (EST) Received: from xanadu.lan (OpenWrt.lan [192.168.1.1]) by yoda.fluxnic.net (Postfix) with ESMTPSA id 32494ECB802; Tue, 12 Nov 2024 00:22:14 -0500 (EST) From: Nicolas Pitre To: Daniel Lezcano , "Rafael J . Wysocki" , linux-pm@vger.kernel.org, linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Nicolas Pitre , Alexandre Bailon Subject: [PATCH 4/5] thermal: automatic aggregation support Date: Tue, 12 Nov 2024 00:19:41 -0500 Message-ID: <20241112052211.3087348-5-nico@fluxnic.net> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241112052211.3087348-1-nico@fluxnic.net> References: <20241112052211.3087348-1-nico@fluxnic.net> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Nicolas Pitre Automatically apply thermal aggregation of multiple related thermal zones into a single one. Here "related" means such zones must have the same trip points and cooling devices bound to them. This is an alternative to the device tree's "thermal-sensors" list for testing purpose without actually modifying the DTB. Signed-off-by: Nicolas Pitre --- drivers/thermal/Kconfig | 12 ++ drivers/thermal/thermal_core.c | 227 +++++++++++++++++++++++++++++++++ 2 files changed, 239 insertions(+) diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 111f07b52a..1b2f319838 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -235,6 +235,18 @@ config THERMAL_AGGREGATION found in the device tree's "thermal-sensors" list when it contains more than one entry. +config THERMAL_AGGREGATION_AUTO + bool "Automatic Thermal Aggregation support" + depends on THERMAL_AGGREGATION + help + Automatically apply thermal aggregation of multiple related thermal + zones into a single one. Here "related" means such zones must have + the same trip points and cooling devices bound to them. This is an + alternative to the device tree's "thermal-sensors" list for testing + purpose without actually modifying the DTB. It is highly recommended + that the device tree method be used in preference to this for actual + system deployment. + config THERMAL_EMULATION bool "Thermal emulation mode support" help diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 73a1b30081..934d248aa9 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -755,6 +755,16 @@ static inline void thermal_remove_tz_from_aggregator(struct thermal_zone_device {} #endif /* CONFIG_THERMAL_AGGREGATION */ +#ifdef CONFIG_THERMAL_AGGREGATION_AUTO +static void thermal_check_zone_for_aggregation(struct thermal_zone_device *target_tz); +static void thermal_check_cdev_for_aggregation(struct thermal_cooling_device *new_cdev); +#else +static inline void thermal_check_zone_for_aggregation(struct thermal_zone_device *target_tz) +{} +static inline void thermal_check_cdev_for_aggregation(struct thermal_cooling_device *new_cdev) +{} +#endif /* CONFIG_THERMAL_AGGREGATION_AUTO */ + /** * thermal_bind_cdev_to_trip - bind a cooling device to a thermal zone * @tz: pointer to struct thermal_zone_device @@ -1073,6 +1083,8 @@ __thermal_cooling_device_register(struct device_node *np, mutex_unlock(&thermal_list_lock); + thermal_check_cdev_for_aggregation(cdev); + return cdev; out_cooling_dev: @@ -1515,6 +1527,8 @@ thermal_zone_device_register_with_trips(const char *type, if (atomic_cmpxchg(&tz->need_update, 1, 0)) thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); + thermal_check_zone_for_aggregation(tz); + thermal_notify_tz_create(tz); thermal_debug_tz_add(tz); @@ -2068,6 +2082,219 @@ void thermal_zone_device_aggregate(struct thermal_zone_device *tz, mutex_unlock(&thermal_list_lock); } +#ifdef CONFIG_THERMAL_AGGREGATION_AUTO + +static bool is_aggregator(struct thermal_zone_device *tz) +{ + return !strcmp(tz->type, "aggregator"); +} + +/** + * thermal_trip_related - determine if two trips are equivalent + * + * @tt1, @tt2: thermal trip specs to compare + * + * Determine if given trips may be candidates for aggregation. + * + * Return: true if related for aggregation, false otherwise + */ +static bool thermal_trip_related(struct thermal_trip *tt1, + struct thermal_trip *tt2) +{ + return tt1->temperature == tt2->temperature && + tt1->hysteresis == tt2->hysteresis && + tt1->type == tt2->type && + tt1->flags == tt2->flags; +} + +static struct thermal_cooling_device * +trip_to_cdev(struct thermal_zone_device *tz, int trip_idx) +{ + struct thermal_instance *ti; + + list_for_each_entry(ti, &tz->thermal_instances, tz_node) + if (trip_to_trip_desc(ti->trip) == &tz->trips[trip_idx]) + return ti->cdev; + + return NULL; +} + +/** + * thermal_zone_related - determine if two tz's are candidates for aggregation + * + * @tz1, @tz2: thermal zones to compare + * + * Return: true if related for aggregation, false otherwise + */ +static bool thermal_zone_related(struct thermal_zone_device *tz1, + struct thermal_zone_device *tz2) +{ + /* a tz can't aggregate with itself */ + if (tz1 == tz2) + return false; + + /* no relation possible if ops.should_bind is unset */ + if (!tz1->ops.should_bind || !tz2->ops.should_bind) + return false; + + /* a tz always relates to its aggregator */ + if (tz1->aggregator == tz2 || tz2->aggregator == tz1) + return true; + + /* related tz's must have the same number of trip points */ + if (tz1->num_trips != tz2->num_trips) + return false; + + /* tz's with no cdev bindings are not (yet) considered */ + if (list_empty(&tz1->thermal_instances) || + list_empty(&tz2->thermal_instances)) + return false; + + for (int i = 0; i < tz1->num_trips; i++) { + /* all trips must be related */ + if (!thermal_trip_related(&tz1->trips[i].trip, &tz2->trips[i].trip)) + return false; + /* cdevs for given trips must be the same */ + if (trip_to_cdev(tz1, i) != trip_to_cdev(tz2, i)) + return false; + } + + return true; +} + +/** + * find_related_tz - look for a tz aggregation candidate + * + * @target_tz: tz to compare against + * + * Return: candidate tz for aggregation, or NULL if none + */ +static struct thermal_zone_device * +find_related_tz(struct thermal_zone_device *target_tz) +{ + struct thermal_zone_device *tz; + + list_for_each_entry(tz, &thermal_tz_list, node) { + if (is_aggregated(tz)) + continue; + if (is_aggregator(tz)) + continue; + if (!thermal_zone_related(tz, target_tz)) + continue; + return tz; + } + + return NULL; +} + +/** + * thermal_check_zone_for_aggregation - consider tz for aggregation + * + * @target_tz: tz to compare against + * + * Adds the provided tz to a compatible aggregator. If none found, look for + * the possibility to create a new aggregator if another compatible tz exists. + * This is called, notably, when a new tz is registered and potentially bound + * to existing cdevs. + */ +static void thermal_check_zone_for_aggregation(struct thermal_zone_device *target_tz) +{ + struct thermal_zone_aggregator *aggr; + struct thermal_zone_device *aggr_tz, *tz; + + if (is_aggregator(target_tz)) + return; + + mutex_lock(&thermal_list_lock); + if (!thermal_zone_is_present(target_tz)) { + mutex_unlock(&thermal_list_lock); + return; + } + + /* see if existing aggregators can appropriate this zone */ + list_for_each_entry(aggr, &thermal_aggregator_list, node) { + aggr_tz = aggr->tz; + if (!thermal_zone_related(aggr_tz, target_tz)) + continue; + pr_debug("aggr %s(%d) and zone %s(%d) are related\n", + aggr_tz->type, aggr_tz->id, target_tz->type, target_tz->id); + add_tz_to_aggregator(aggr_tz, target_tz); + mutex_unlock(&thermal_list_lock); + return; + } + + /* see if non-aggregated zones can be aggregated */ + tz = find_related_tz(target_tz); + if (!tz) { + mutex_unlock(&thermal_list_lock); + return; + } + + pr_debug("zones %s(%d) and %s(%d) are related\n", + tz->type, tz->id, target_tz->type, target_tz->id); + + mutex_unlock(&thermal_list_lock); + aggr_tz = create_thermal_aggregator(target_tz, "aggregator"); + if (IS_ERR(aggr_tz)) { + pr_err("unable to create thermal aggregator (%ld)\n", + PTR_ERR(aggr_tz)); + return; + } + + mutex_lock(&thermal_list_lock); + + /* the lock was momentarily dropped so need to revalide everything */ + if (thermal_zone_is_present(target_tz)) { + tz = find_related_tz(target_tz); + if (tz) { + add_tz_to_aggregator(aggr_tz, target_tz); + add_tz_to_aggregator(aggr_tz, tz); + mutex_unlock(&thermal_list_lock); + return; + } + } + + /* our match disappeared in the mean time */ + free_thermal_aggregator_unlock(aggr_tz); +} + +/** + * thermal_check_cdev_for_aggregation - consider aggregation after new cdev registration + * + * @new_cdev: cdev for which new thermal bindings might create aggregation candidates + * + * Consider tz's having thermal instance bindings with this new cdev as + * candidates for aggregation. This is called when a new cdev is registered + * and potentially bound to existing tz's. + */ +static void thermal_check_cdev_for_aggregation(struct thermal_cooling_device *new_cdev) +{ + struct thermal_zone_device *tz, *last_tz = NULL; + struct thermal_instance *ti; + +start_over: + mutex_lock(&thermal_list_lock); + + list_for_each_entry(tz, &thermal_tz_list, node) { + if (tz == last_tz) + continue; + if (is_aggregator(tz)) + continue; + list_for_each_entry(ti, &tz->thermal_instances, tz_node) { + if (ti->cdev == new_cdev) { + last_tz = tz; + mutex_unlock(&thermal_list_lock); + thermal_check_zone_for_aggregation(tz); + /* because the lock was dropped ... */ + goto start_over; + } + } + } + + mutex_unlock(&thermal_list_lock); +} + +#endif /* CONFIG_THERMAL_AGGREGATION_AUTO */ #endif /* CONFIG_THERMAL_AGGREGATION */ static void thermal_zone_device_resume(struct work_struct *work) From patchwork Tue Nov 12 05:19:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Pitre X-Patchwork-Id: 13871736 Received: from fhigh-a7-smtp.messagingengine.com (fhigh-a7-smtp.messagingengine.com [103.168.172.158]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 84C1B20820A; Tue, 12 Nov 2024 05:22:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.158 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731388938; cv=none; b=K92K0PK+s/7X2U5Z+mRe6OVQTwx6eDeYjlrAjgFP/pmu1xQTHias5EdzdrB2SoaNTyxrWgvwC8wlO4jmgNKn88zBaMVjy5oOBWyxM/4S+msTE/rxECGcbbDbBvrSwhqRk39y8/UzbWdWa3Fxp2X7ZCCD9GkOe0WoTTS8dW2Wwv8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731388938; c=relaxed/simple; bh=7vUZIpiGECxPt5UrdemGsd4XTl6f/2xvNaeQZbXn5bY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ruo/I8c+4HQfL0ee5qHH21qsTtH7Y/6t7mJ+nZL+JCglz2lMIRJZ+F3vD/1A7k+nsIosO2t03audVk0nz3AeF4HJAx1VB/vYuToUgshWM9ERjvK+3gAkmRwYaS+tQgLmyz1QKFURnflEULLhvJM+LKsCAV18X+nXzA4V8urgBgw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=fluxnic.net; spf=pass smtp.mailfrom=fluxnic.net; dkim=pass (1024-bit key) header.d=fluxnic.net header.i=@fluxnic.net header.b=2DKJiYYP; dkim=pass (2048-bit key) header.d=pobox.com header.i=@pobox.com header.b=TXcYxnI5; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=dZS5LbI1; arc=none smtp.client-ip=103.168.172.158 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=fluxnic.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fluxnic.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=fluxnic.net header.i=@fluxnic.net header.b="2DKJiYYP"; dkim=pass (2048-bit key) header.d=pobox.com header.i=@pobox.com header.b="TXcYxnI5"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="dZS5LbI1" Received: from phl-compute-11.internal (phl-compute-11.phl.internal [10.202.2.51]) by mailfhigh.phl.internal (Postfix) with ESMTP id B80A011401D5; Tue, 12 Nov 2024 00:22:15 -0500 (EST) Received: from phl-frontend-01 ([10.202.2.160]) by phl-compute-11.internal (MEProxy); Tue, 12 Nov 2024 00:22:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fluxnic.net; h= cc:cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=2016-12.pbsmtp; t=1731388935; x=1731475335; bh=HLuQfhssIlYGR5o1gb9fHia6gSq18YEO9t8QMEHdmVg=; b= 2DKJiYYPGmrbtpRKl8RDvFwQ3fw9MeWuIE/dXFaImFBP/HrmwFRSR/Ae81dAJhqF taCustXegIQgQKFU8YHksTUcyTz414JQJiC7DZcQefITVLlF8p8rlqpYmmZLeCdO 50tD1Z+3D8uUns7TbM8hPnTIBByk+RV9++I2iFf8Qgg= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pobox.com; h=cc :cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm2; t=1731388935; x= 1731475335; bh=HLuQfhssIlYGR5o1gb9fHia6gSq18YEO9t8QMEHdmVg=; b=T XcYxnI5cthvzdcE/KZOjJqfoBSv4W1lBhsB9LDCiLpUSUOnpfnk8T2JU/1nCmZn2 AD8e/VrdiLyjApCs7XjivY/jJs96zRvw6NQY7NloTu/Fcv+fvHQdcuSsz7qMir1l QPYMMKlLYYsOMJcoLj8Ziv9SR6WAKoS3IWysNzYObPWKa7xXyWaEXy5s6KLlOwVe 3nzsmh+OLP5MdVH/ixVxr/W2dMm55S0XIpthBZqCxeIMYIVZ5fd1YH+Iomk0sElo jDhrfwOjncmysDtHNgu12sK82WLUUWXpgPhZTPj5O57txWiZX5TB8ZqoizUkApiG gcL/H5ePXWgk1HfaYHuig== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1731388935; x=1731475335; bh=H LuQfhssIlYGR5o1gb9fHia6gSq18YEO9t8QMEHdmVg=; b=dZS5LbI1X8hk3kWl4 2gU5FChpYhO9T6WLBHFIQYVO1wNcqqeXtuqjOv0+2xaMz4IEmifWHkvlKs+q5qXZ EHgTWekQDXOpSDyJbI8DKrIMDDl9ADYWTJuqJ4cIdcugjdCMw/lSLB+Ri+XIGse3 jAa2AZEn3VopOFs1fXMvr0UE+0O8CNjbVViR4LEcSl7rBStCWJyj1IsCBgH4UNlr niUA4qBgmP5u0xm2hZx6jPhsbpbGmO/kAq+LBQEueydSF2pZRvHBl7WhoNMVLthd DVLMJNuDC07lR0FCHy+iHXIDDt+yW/KWXEDLq8bv20o3WrKISHGDZJbXpUoVntS8 p0/LA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrudefgdekvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdpuffr tefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnth hsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecu hfhrohhmpefpihgtohhlrghsucfrihhtrhgvuceonhhitghosehflhhugihnihgtrdhnvg htqeenucggtffrrghtthgvrhhnpedtjeeuieeiheeiueffuddvffelheekleegkedukeef fffhudffudegvdetiefhteenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmh grihhlfhhrohhmpehnihgtohesfhhluhignhhitgdrnhgvthdpnhgspghrtghpthhtohep kedpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtoheprggsrghilhhonhessggrhihlih gsrhgvrdgtohhmpdhrtghpthhtohepnhhpihhtrhgvsegsrgihlhhisghrvgdrtghomhdp rhgtphhtthhopehrrghfrggvlheskhgvrhhnvghlrdhorhhgpdhrtghpthhtohepuggrnh hivghlrdhlvgiitggrnhhosehlihhnrghrohdrohhrghdprhgtphhtthhopehlihhnuhig qdhmvgguihgrthgvkheslhhishhtshdrihhnfhhrrgguvggrugdrohhrghdprhgtphhtth hopeguvghvihgtvghtrhgvvgesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthho pehlihhnuhigqdhkvghrnhgvlhesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtth hopehlihhnuhigqdhpmhesvhhgvghrrdhkvghrnhgvlhdrohhrgh X-ME-Proxy: Feedback-ID: i58514971:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 12 Nov 2024 00:22:15 -0500 (EST) Received: from xanadu.lan (OpenWrt.lan [192.168.1.1]) by yoda.fluxnic.net (Postfix) with ESMTPSA id 4AB00ECB803; Tue, 12 Nov 2024 00:22:14 -0500 (EST) From: Nicolas Pitre To: Daniel Lezcano , "Rafael J . Wysocki" , linux-pm@vger.kernel.org, linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Nicolas Pitre , Alexandre Bailon Subject: [PATCH 5/5] ARM64: mt8195: Use thermal aggregation for big and little cpu Date: Tue, 12 Nov 2024 00:19:42 -0500 Message-ID: <20241112052211.3087348-6-nico@fluxnic.net> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241112052211.3087348-1-nico@fluxnic.net> References: <20241112052211.3087348-1-nico@fluxnic.net> Precedence: bulk X-Mailing-List: linux-pm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Alexandre Bailon This uses the thermal aggregation for the mt8195 to get the maximal temperature of big and little cpu clusters. Signed-off-by: Alexandre Bailon Signed-off-by: Nicolas Pitre --- arch/arm64/boot/dts/mediatek/mt8195.dtsi | 210 +++-------------------- 1 file changed, 25 insertions(+), 185 deletions(-) diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi index e89ba384c4..a75a56f67e 100644 --- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi @@ -3601,50 +3601,30 @@ dp_tx: dp-tx@1c600000 { }; thermal_zones: thermal-zones { - cpu0-thermal { + cpu-little { polling-delay = <1000>; - polling-delay-passive = <250>; - thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU0>; + polling-delay-passive = <100>; + thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU0>, + <&lvts_mcu MT8195_MCU_LITTLE_CPU1>, + <&lvts_mcu MT8195_MCU_LITTLE_CPU2>, + <&lvts_mcu MT8195_MCU_LITTLE_CPU3>; + sustainable-power = <1500>; trips { - cpu0_alert: trip-alert { - temperature = <85000>; + cpu_little_threshold: trip-point { + temperature = <68000>; hysteresis = <2000>; type = "passive"; }; - cpu0_crit: trip-crit { - temperature = <100000>; - hysteresis = <2000>; - type = "critical"; - }; - }; - - cooling-maps { - map0 { - trip = <&cpu0_alert>; - cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; - }; - - cpu1-thermal { - polling-delay = <1000>; - polling-delay-passive = <250>; - thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU1>; - - trips { - cpu1_alert: trip-alert { + cpu_little_target: target { temperature = <85000>; hysteresis = <2000>; type = "passive"; }; - cpu1_crit: trip-crit { - temperature = <100000>; + cpu_little_soc_max_crit: soc-max-crit { + temperature = <115000>; hysteresis = <2000>; type = "critical"; }; @@ -3652,7 +3632,7 @@ cpu1_crit: trip-crit { cooling-maps { map0 { - trip = <&cpu1_alert>; + trip = <&cpu_little_target>; cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, @@ -3661,170 +3641,30 @@ map0 { }; }; - cpu2-thermal { + cpu-big { polling-delay = <1000>; polling-delay-passive = <250>; - thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU2>; + thermal-sensors = <&lvts_mcu MT8195_MCU_BIG_CPU0>, + <&lvts_mcu MT8195_MCU_BIG_CPU1>, + <&lvts_mcu MT8195_MCU_BIG_CPU2>, + <&lvts_mcu MT8195_MCU_BIG_CPU3>; + sustainable-power = <1500>; trips { - cpu2_alert: trip-alert { - temperature = <85000>; + cpu_big_threshold: trip-point { + temperature = <68000>; hysteresis = <2000>; type = "passive"; }; - cpu2_crit: trip-crit { - temperature = <100000>; - hysteresis = <2000>; - type = "critical"; - }; - }; - - cooling-maps { - map0 { - trip = <&cpu2_alert>; - cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; - }; - - cpu3-thermal { - polling-delay = <1000>; - polling-delay-passive = <250>; - thermal-sensors = <&lvts_mcu MT8195_MCU_LITTLE_CPU3>; - - trips { - cpu3_alert: trip-alert { - temperature = <85000>; - hysteresis = <2000>; - type = "passive"; - }; - - cpu3_crit: trip-crit { - temperature = <100000>; - hysteresis = <2000>; - type = "critical"; - }; - }; - - cooling-maps { - map0 { - trip = <&cpu3_alert>; - cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; - }; - - cpu4-thermal { - polling-delay = <1000>; - polling-delay-passive = <250>; - thermal-sensors = <&lvts_mcu MT8195_MCU_BIG_CPU0>; - - trips { - cpu4_alert: trip-alert { + cpu_big_target: target { temperature = <85000>; hysteresis = <2000>; type = "passive"; }; - cpu4_crit: trip-crit { - temperature = <100000>; - hysteresis = <2000>; - type = "critical"; - }; - }; - - cooling-maps { - map0 { - trip = <&cpu4_alert>; - cooling-device = <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; - }; - - cpu5-thermal { - polling-delay = <1000>; - polling-delay-passive = <250>; - thermal-sensors = <&lvts_mcu MT8195_MCU_BIG_CPU1>; - - trips { - cpu5_alert: trip-alert { - temperature = <85000>; - hysteresis = <2000>; - type = "passive"; - }; - - cpu5_crit: trip-crit { - temperature = <100000>; - hysteresis = <2000>; - type = "critical"; - }; - }; - - cooling-maps { - map0 { - trip = <&cpu5_alert>; - cooling-device = <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; - }; - - cpu6-thermal { - polling-delay = <1000>; - polling-delay-passive = <250>; - thermal-sensors = <&lvts_mcu MT8195_MCU_BIG_CPU2>; - - trips { - cpu6_alert: trip-alert { - temperature = <85000>; - hysteresis = <2000>; - type = "passive"; - }; - - cpu6_crit: trip-crit { - temperature = <100000>; - hysteresis = <2000>; - type = "critical"; - }; - }; - - cooling-maps { - map0 { - trip = <&cpu6_alert>; - cooling-device = <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; - }; - - cpu7-thermal { - polling-delay = <1000>; - polling-delay-passive = <250>; - thermal-sensors = <&lvts_mcu MT8195_MCU_BIG_CPU3>; - - trips { - cpu7_alert: trip-alert { - temperature = <85000>; - hysteresis = <2000>; - type = "passive"; - }; - - cpu7_crit: trip-crit { - temperature = <100000>; + cpu_big_soc_max_crit: soc-max-crit { + temperature = <115000>; hysteresis = <2000>; type = "critical"; }; @@ -3832,7 +3672,7 @@ cpu7_crit: trip-crit { cooling-maps { map0 { - trip = <&cpu7_alert>; + trip = <&cpu_big_target>; cooling-device = <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,