From nobody Wed Apr 8 03:09:21 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CDF8B31A07B; Tue, 10 Mar 2026 18:40:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168048; cv=none; b=BUAWV6l3RWesrgRrLjYOL5hhhz/X+HslkyTyyXPSzSuMovHCfK0taeLMkQb6wDTT+RnraiedjwdP0ALbwa41bQ6oviOwqMydyhepGgnYAq+swH32sH+5Mo9FfQ+eb+3bAhDvpvdPpYLvb2ri/AgSBjSpCdrZkHQELpwLPe1dtw0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168048; c=relaxed/simple; bh=WC1R4qV6I0MneBfZAXWbYrl3W9fg6IoQSFQXIfGStN0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JVthszxuT3r5lLuDrHBOsf/AzU9nc5wP9E5pTAc4w4Fu1KPQicSS42C9bLzK89gOIhOTP/SSYYnc0zEh3wndVVFXy+FvYuH7md+9DsSHRu4H+AYt1bx1OAW2+k/XtMNnqD/OtmmQRz6CmyIjjBiom6fLh2RJmuv7rbenNjnrtnM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 15D181596; Tue, 10 Mar 2026 11:40:40 -0700 (PDT) Received: from pluto.guest.local (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BF11E3F7BD; Tue, 10 Mar 2026 11:40:42 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org, linux-clk@vger.kernel.org, linux-renesas-soc@vger.kernel.org Cc: sudeep.holla@arm.com, philip.radford@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@foss.st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, dan.carpenter@linaro.org, geert+renesas@glider.be, kuninori.morimoto.gx@renesas.com, marek.vasut+renesas@gmail.com, Cristian Marussi , Michael Turquette , Stephen Boyd Subject: [PATCH v2 01/13] clk: scmi: Fix clock rate rounding Date: Tue, 10 Mar 2026 18:40:18 +0000 Message-ID: <20260310184030.3669330-2-cristian.marussi@arm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310184030.3669330-1-cristian.marussi@arm.com> References: <20260310184030.3669330-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" While the do_div() helper used for rounding expects its divisor argument to be a 32bits quantity, the currently provided divisor parameter is a 64bit value that, as a consequence, is silently truncated and a possible source of bugs. Fix by using the proper div64_ul helper. Cc: Michael Turquette Cc: Stephen Boyd Cc: linux-clk@vger.kernel.org Fixes: 7a8655e19bdb ("clk: scmi: Fix the rounding of clock rate") Signed-off-by: Cristian Marussi Tested-by: Geert Uytterhoeven --- drivers/clk/clk-scmi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c index 6b286ea6f121..b6a12f3bc123 100644 --- a/drivers/clk/clk-scmi.c +++ b/drivers/clk/clk-scmi.c @@ -10,9 +10,9 @@ #include #include #include +#include #include #include -#include =20 #define NOT_ATOMIC false #define ATOMIC true @@ -83,7 +83,7 @@ static int scmi_clk_determine_rate(struct clk_hw *hw, =20 ftmp =3D req->rate - fmin; ftmp +=3D clk->info->range.step_size - 1; /* to round up */ - do_div(ftmp, clk->info->range.step_size); + ftmp =3D div64_ul(ftmp, clk->info->range.step_size); =20 req->rate =3D ftmp * clk->info->range.step_size + fmin; =20 --=20 2.53.0 From nobody Wed Apr 8 03:09:21 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 685C13AD50A; Tue, 10 Mar 2026 18:40:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168052; cv=none; b=h8ovtWwQ3V8cZ78pC0gGbeHSjyY/ZS7o8jUrlkp05unf13SQU/jzAcelUUdZNFhNTHDPltFDnWTOb2XzwYkPirjTv0k0EogvyQrse4DbVGA+lVH3FmNprYXesRUda2p2jJbgoxoIddXR/ym8jJ43b3dmyPfl+2Ipq7SxpAreZss= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168052; c=relaxed/simple; bh=FouQA+bv5j1EdgH3z1eqPEIT8/R9xB/bagn+V+J4Zec=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ct9II6yS/40wzBJKu2DfgvWWoV3iv0euBXKhLo4bVIeR9oBdV4oUSdP2ahgpG1bXTWJnfq9mzvTTo4l5lGZaMgt74VSXYRgXMEhnYxHYrf3/pq0Zmlq8itpwYxY7YKAyboo0D4XI2HBVdjusRYDVo4sTkw6aX85W+Z8XflbBid8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 976191596; Tue, 10 Mar 2026 11:40:43 -0700 (PDT) Received: from pluto.guest.local (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BCAD83F7BD; Tue, 10 Mar 2026 11:40:46 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org, linux-clk@vger.kernel.org, linux-renesas-soc@vger.kernel.org Cc: sudeep.holla@arm.com, philip.radford@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@foss.st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, dan.carpenter@linaro.org, geert+renesas@glider.be, kuninori.morimoto.gx@renesas.com, marek.vasut+renesas@gmail.com, Cristian Marussi Subject: [PATCH v2 02/13] firmware: arm_scmi: Add clock determine_rate operation Date: Tue, 10 Mar 2026 18:40:19 +0000 Message-ID: <20260310184030.3669330-3-cristian.marussi@arm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310184030.3669330-1-cristian.marussi@arm.com> References: <20260310184030.3669330-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a clock operation to help determining the effective rate, closest to the required one, that a specific clock can support. Calculation is currently performed kernel side and the logic is taken directly from the SCMI Clock driver: embedding the determinate rate logic in the protocol layer enables simplifications in the SCMI Clock protocol interface and will more easily accommodate further evolutions where such determine_rate logic into is optionally delegated to the platform SCMI server. Signed-off-by: Cristian Marussi Tested-by: Geert Uytterhoeven --- v1 --> v2 - use the fixed rounding algo using div64_ul Spoiler alert next SCMI spec will most probably include a new CLOCK_DETERMINE_RATE command to delegate to the platform such calculations, so this clock proto_ops will be needed anyway sooner or later --- drivers/firmware/arm_scmi/clock.c | 42 +++++++++++++++++++++++++++++++ include/linux/scmi_protocol.h | 6 +++++ 2 files changed, 48 insertions(+) diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/= clock.c index ab36871650a1..54b55517b759 100644 --- a/drivers/firmware/arm_scmi/clock.c +++ b/drivers/firmware/arm_scmi/clock.c @@ -5,6 +5,7 @@ * Copyright (C) 2018-2022 ARM Ltd. */ =20 +#include #include #include #include @@ -624,6 +625,46 @@ static int scmi_clock_rate_set(const struct scmi_proto= col_handle *ph, return ret; } =20 +static int scmi_clock_determine_rate(const struct scmi_protocol_handle *ph, + u32 clk_id, unsigned long *rate) +{ + u64 fmin, fmax, ftmp; + struct scmi_clock_info *clk; + struct clock_info *ci =3D ph->get_priv(ph); + + if (!rate) + return -EINVAL; + + clk =3D scmi_clock_domain_lookup(ci, clk_id); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + /* + * If we can't figure out what rate it will be, so just return the + * rate back to the caller. + */ + if (clk->rate_discrete) + return 0; + + fmin =3D clk->range.min_rate; + fmax =3D clk->range.max_rate; + if (*rate <=3D fmin) { + *rate =3D fmin; + return 0; + } else if (*rate >=3D fmax) { + *rate =3D fmax; + return 0; + } + + ftmp =3D *rate - fmin; + ftmp +=3D clk->range.step_size - 1; /* to round up */ + ftmp =3D div64_ul(ftmp, clk->range.step_size); + + *rate =3D ftmp * clk->range.step_size + fmin; + + return 0; +} + static int scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id, enum clk_state state, @@ -936,6 +977,7 @@ static const struct scmi_clk_proto_ops clk_proto_ops = =3D { .info_get =3D scmi_clock_info_get, .rate_get =3D scmi_clock_rate_get, .rate_set =3D scmi_clock_rate_set, + .determine_rate =3D scmi_clock_determine_rate, .enable =3D scmi_clock_enable, .disable =3D scmi_clock_disable, .state_get =3D scmi_clock_state_get, diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index aafaac1496b0..28579c145045 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -91,6 +91,10 @@ enum scmi_clock_oem_config { * @info_get: get the information of the specified clock * @rate_get: request the current clock rate of a clock * @rate_set: set the clock rate of a clock + * @determine_rate: determine the effective rate that can be supported by a + * clock calculating the closest allowed rate. + * Note that @rate is an input/output parameter used both to + * describe the requested rate and report the closest match * @enable: enables the specified clock * @disable: disables the specified clock * @state_get: get the status of the specified clock @@ -108,6 +112,8 @@ struct scmi_clk_proto_ops { u64 *rate); int (*rate_set)(const struct scmi_protocol_handle *ph, u32 clk_id, u64 rate); + int (*determine_rate)(const struct scmi_protocol_handle *ph, u32 clk_id, + unsigned long *rate); int (*enable)(const struct scmi_protocol_handle *ph, u32 clk_id, bool atomic); int (*disable)(const struct scmi_protocol_handle *ph, u32 clk_id, --=20 2.53.0 From nobody Wed Apr 8 03:09:21 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 99CB83BED78; Tue, 10 Mar 2026 18:40:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168057; cv=none; b=oIX0TC1/jaofEgu81zRV4GxM+GpGX37gi7QuRsl7MIQrcl1bZ+mijiLQmVbRxPuvALUUrufuqqWtHyxajzj++aog/hSrhJALvPaL5fbdeh+qyM9TnU19SyUs9foMy62rUD6g3dmdf6r/DQLHFFRszMeR2xpJ+J3bj35pEyr2ybk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168057; c=relaxed/simple; bh=rgpT6JeYUUTF8dPGQi0+aswaXnBqWOyh+njR4c8YQ2g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mj7BUzo9rD3jv0PF+Ggy7kpoIslJNphVhxtcGueIvZScq8XQ/ENr+s+/ZtI+Xd0OcZoBSJIh2tlMXpYF+1IVBA3KUOQ9kG+AXOtnjNW9AmzSjElLC32RVzBRYbqFJzEHUJ2Y3jc7krf1FKtPwiqoZzKqRqOLqaqaRrxHp52Bd1s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id BADEB14BF; Tue, 10 Mar 2026 11:40:47 -0700 (PDT) Received: from pluto.guest.local (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 283403F7BD; Tue, 10 Mar 2026 11:40:50 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org, linux-clk@vger.kernel.org, linux-renesas-soc@vger.kernel.org Cc: sudeep.holla@arm.com, philip.radford@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@foss.st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, dan.carpenter@linaro.org, geert+renesas@glider.be, kuninori.morimoto.gx@renesas.com, marek.vasut+renesas@gmail.com, Cristian Marussi , Brian Masney , Michael Turquette , Stephen Boyd Subject: [PATCH v2 03/13] clk: scmi: Use new determine_rate clock operation Date: Tue, 10 Mar 2026 18:40:20 +0000 Message-ID: <20260310184030.3669330-4-cristian.marussi@arm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310184030.3669330-1-cristian.marussi@arm.com> References: <20260310184030.3669330-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Use the Clock protocol layer determine_rate logic to calculate the closest rate that can be supported by a specific clock. No functional change. Cc: Brian Masney Cc: Michael Turquette Cc: Stephen Boyd Cc: linux-clk@vger.kernel.org Signed-off-by: Cristian Marussi Tested-by: Geert Uytterhoeven --- @brian: I'd modify further this clk-scmi driver, with a patch on top of this series, to properly use your new CLK_ROUNDING_NOOP flag once your series AND another (already reviewed) series on clk-scmi from Peng are in. --- drivers/clk/clk-scmi.c | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c index b6a12f3bc123..c223e4ef1dd1 100644 --- a/drivers/clk/clk-scmi.c +++ b/drivers/clk/clk-scmi.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include =20 @@ -57,35 +56,17 @@ static unsigned long scmi_clk_recalc_rate(struct clk_hw= *hw, static int scmi_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { - u64 fmin, fmax, ftmp; + int ret; struct scmi_clk *clk =3D to_scmi_clk(hw); =20 /* - * We can't figure out what rate it will be, so just return the - * rate back to the caller. scmi_clk_recalc_rate() will be called - * after the rate is set and we'll know what rate the clock is + * If we could not get a better rate scmi_clk_recalc_rate() will be + * called after the rate is set and we'll know what rate the clock is * running at then. */ - if (clk->info->rate_discrete) - return 0; - - fmin =3D clk->info->range.min_rate; - fmax =3D clk->info->range.max_rate; - if (req->rate <=3D fmin) { - req->rate =3D fmin; - - return 0; - } else if (req->rate >=3D fmax) { - req->rate =3D fmax; - - return 0; - } - - ftmp =3D req->rate - fmin; - ftmp +=3D clk->info->range.step_size - 1; /* to round up */ - ftmp =3D div64_ul(ftmp, clk->info->range.step_size); - - req->rate =3D ftmp * clk->info->range.step_size + fmin; + ret =3D scmi_proto_clk_ops->determine_rate(clk->ph, clk->id, &req->rate); + if (ret) + return ret; =20 return 0; } --=20 2.53.0 From nobody Wed Apr 8 03:09:21 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 493633B4EBA; Tue, 10 Mar 2026 18:40:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168064; cv=none; b=fXUkqQmxSRF+VaJpa7YrwKLGK183aqZICfY/ysKvi8pEkVwO/uqWNUEntzhLG+0VGa9Fi09YG1jSF1G3CyBOznZMCirUK5sUYGDP9RHV8fMWZYAaKAJhWinOa0zVzyTae7vp46zr7EDLxn0iJ96hF9uqeoZXf/odxKtBnVsVJYM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168064; c=relaxed/simple; bh=fJJelEs4dlfqo0M3gZyvgEKJPcdj/dOI+ns6rfZ+JSI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=g01AacAx2JExWA2KP/rbGPcn1cIGcbosN7B3sz5cPCA48gktrWRLlsQL2HfuBUCJeaOL5ZDSipe4BhCvxPs0WoRlJBCXb70lkPnkS6yBuEya3qq5qHduZCPf0mLVn+fDjrtPXUhagyaWO5reey7037lHBIJcb4wv2KrGgPCa7gA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 75AF11596; Tue, 10 Mar 2026 11:40:51 -0700 (PDT) Received: from pluto.guest.local (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4AE283F7BD; Tue, 10 Mar 2026 11:40:54 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org, linux-clk@vger.kernel.org, linux-renesas-soc@vger.kernel.org Cc: sudeep.holla@arm.com, philip.radford@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@foss.st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, dan.carpenter@linaro.org, geert+renesas@glider.be, kuninori.morimoto.gx@renesas.com, marek.vasut+renesas@gmail.com, Cristian Marussi Subject: [PATCH v2 04/13] firmware: arm_scmi: Simplify clock rates exposed interface Date: Tue, 10 Mar 2026 18:40:21 +0000 Message-ID: <20260310184030.3669330-5-cristian.marussi@arm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310184030.3669330-1-cristian.marussi@arm.com> References: <20260310184030.3669330-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Introduce a new internal struct scmi_clock_desc so as to be able to hide, in the future, some of the needlessly public fields currently kept inside scmi_clock_info, while keeping exposed only the two new min_rate and max_rate fields for each clock. No functional change. Signed-off-by: Cristian Marussi Reviewed-by: Peng Fan Tested-by: Geert Uytterhoeven --- v1 --> v2 - removed useless parenthesis - reworded comit message --- drivers/firmware/arm_scmi/clock.c | 145 +++++++++++++++--------------- include/linux/scmi_protocol.h | 2 + 2 files changed, 74 insertions(+), 73 deletions(-) diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/= clock.c index 54b55517b759..467b13a3a18f 100644 --- a/drivers/firmware/arm_scmi/clock.c +++ b/drivers/firmware/arm_scmi/clock.c @@ -157,13 +157,27 @@ struct scmi_clock_rate_notify_payld { __le32 rate_high; }; =20 +struct scmi_clock_desc { + u32 id; + bool rate_discrete; + unsigned int num_rates; + u64 rates[SCMI_MAX_NUM_RATES]; +#define RATE_MIN 0 +#define RATE_MAX 1 +#define RATE_STEP 2 + struct scmi_clock_info info; +}; + +#define to_desc(p) (container_of(p, struct scmi_clock_desc, info)) + struct clock_info { int num_clocks; int max_async_req; bool notify_rate_changed_cmd; bool notify_rate_change_requested_cmd; atomic_t cur_async_req; - struct scmi_clock_info *clk; + struct scmi_clock_desc *clkds; +#define CLOCK_INFO(c, i) (&(((c)->clkds + (i))->info)) int (*clock_config_set)(const struct scmi_protocol_handle *ph, u32 clk_id, enum clk_state state, enum scmi_clock_oem_config oem_type, @@ -185,7 +199,7 @@ scmi_clock_domain_lookup(struct clock_info *ci, u32 clk= _id) if (clk_id >=3D ci->num_clocks) return ERR_PTR(-EINVAL); =20 - return ci->clk + clk_id; + return CLOCK_INFO(ci, clk_id); } =20 static int @@ -226,8 +240,7 @@ scmi_clock_protocol_attributes_get(const struct scmi_pr= otocol_handle *ph, =20 struct scmi_clk_ipriv { struct device *dev; - u32 clk_id; - struct scmi_clock_info *clk; + struct scmi_clock_desc *clkd; }; =20 static void iter_clk_possible_parents_prepare_message(void *message, unsig= ned int desc_index, @@ -236,7 +249,7 @@ static void iter_clk_possible_parents_prepare_message(v= oid *message, unsigned in struct scmi_msg_clock_possible_parents *msg =3D message; const struct scmi_clk_ipriv *p =3D priv; =20 - msg->id =3D cpu_to_le32(p->clk_id); + msg->id =3D cpu_to_le32(p->clkd->id); /* Set the number of OPPs to be skipped/already read */ msg->skip_parents =3D cpu_to_le32(desc_index); } @@ -246,7 +259,6 @@ static int iter_clk_possible_parents_update_state(struc= t scmi_iterator_state *st { const struct scmi_msg_resp_clock_possible_parents *r =3D response; struct scmi_clk_ipriv *p =3D priv; - struct device *dev =3D ((struct scmi_clk_ipriv *)p)->dev; u32 flags; =20 flags =3D le32_to_cpu(r->num_parent_flags); @@ -258,12 +270,13 @@ static int iter_clk_possible_parents_update_state(str= uct scmi_iterator_state *st * assume it's returned+remaining on first call. */ if (!st->max_resources) { - p->clk->num_parents =3D st->num_returned + st->num_remaining; - p->clk->parents =3D devm_kcalloc(dev, p->clk->num_parents, - sizeof(*p->clk->parents), - GFP_KERNEL); - if (!p->clk->parents) { - p->clk->num_parents =3D 0; + p->clkd->info.num_parents =3D st->num_returned + st->num_remaining; + p->clkd->info.parents =3D devm_kcalloc(p->dev, + p->clkd->info.num_parents, + sizeof(*p->clkd->info.parents), + GFP_KERNEL); + if (!p->clkd->info.parents) { + p->clkd->info.num_parents =3D 0; return -ENOMEM; } st->max_resources =3D st->num_returned + st->num_remaining; @@ -280,29 +293,27 @@ static int iter_clk_possible_parents_process_response= (const struct scmi_protocol const struct scmi_msg_resp_clock_possible_parents *r =3D response; struct scmi_clk_ipriv *p =3D priv; =20 - u32 *parent =3D &p->clk->parents[st->desc_index + st->loop_idx]; + u32 *parent =3D &p->clkd->info.parents[st->desc_index + st->loop_idx]; =20 *parent =3D le32_to_cpu(r->possible_parents[st->loop_idx]); =20 return 0; } =20 -static int scmi_clock_possible_parents(const struct scmi_protocol_handle *= ph, u32 clk_id, - struct scmi_clock_info *clk) +static int scmi_clock_possible_parents(const struct scmi_protocol_handle *= ph, + u32 clk_id, struct clock_info *cinfo) { struct scmi_iterator_ops ops =3D { .prepare_message =3D iter_clk_possible_parents_prepare_message, .update_state =3D iter_clk_possible_parents_update_state, .process_response =3D iter_clk_possible_parents_process_response, }; - + struct scmi_clock_desc *clkd =3D &cinfo->clkds[clk_id]; struct scmi_clk_ipriv ppriv =3D { - .clk_id =3D clk_id, - .clk =3D clk, + .clkd =3D clkd, .dev =3D ph->dev, }; void *iter; - int ret; =20 iter =3D ph->hops->iter_response_init(ph, &ops, 0, CLOCK_POSSIBLE_PARENTS_GET, @@ -311,9 +322,7 @@ static int scmi_clock_possible_parents(const struct scm= i_protocol_handle *ph, u3 if (IS_ERR(iter)) return PTR_ERR(iter); =20 - ret =3D ph->hops->iter_response_run(iter); - - return ret; + return ph->hops->iter_response_run(iter); } =20 static int @@ -352,7 +361,7 @@ static int scmi_clock_attributes_get(const struct scmi_= protocol_handle *ph, u32 attributes; struct scmi_xfer *t; struct scmi_msg_resp_clock_attributes *attr; - struct scmi_clock_info *clk =3D cinfo->clk + clk_id; + struct scmi_clock_info *clk =3D CLOCK_INFO(cinfo, clk_id); =20 ret =3D ph->xops->xfer_get_init(ph, CLOCK_ATTRIBUTES, sizeof(clk_id), sizeof(*attr), &t); @@ -394,7 +403,7 @@ static int scmi_clock_attributes_get(const struct scmi_= protocol_handle *ph, clk->rate_change_requested_notifications =3D true; if (PROTOCOL_REV_MAJOR(ph->version) >=3D 0x3) { if (SUPPORTS_PARENT_CLOCK(attributes)) - scmi_clock_possible_parents(ph, clk_id, clk); + scmi_clock_possible_parents(ph, clk_id, cinfo); if (SUPPORTS_GET_PERMISSIONS(attributes)) scmi_clock_get_permissions(ph, clk_id, clk); if (SUPPORTS_EXTENDED_CONFIG(attributes)) @@ -424,7 +433,7 @@ static void iter_clk_describe_prepare_message(void *mes= sage, struct scmi_msg_clock_describe_rates *msg =3D message; const struct scmi_clk_ipriv *p =3D priv; =20 - msg->id =3D cpu_to_le32(p->clk_id); + msg->id =3D cpu_to_le32(p->clkd->id); /* Set the number of rates to be skipped/already read */ msg->rate_index =3D cpu_to_le32(desc_index); } @@ -457,14 +466,14 @@ iter_clk_describe_update_state(struct scmi_iterator_s= tate *st, flags =3D le32_to_cpu(r->num_rates_flags); st->num_remaining =3D NUM_REMAINING(flags); st->num_returned =3D NUM_RETURNED(flags); - p->clk->rate_discrete =3D RATE_DISCRETE(flags); + p->clkd->rate_discrete =3D RATE_DISCRETE(flags); =20 /* Warn about out of spec replies ... */ - if (!p->clk->rate_discrete && + if (!p->clkd->rate_discrete && (st->num_returned !=3D 3 || st->num_remaining !=3D 0)) { dev_warn(p->dev, "Out-of-spec CLOCK_DESCRIBE_RATES reply for %s - returned:%d remaining= :%d rx_len:%zd\n", - p->clk->name, st->num_returned, st->num_remaining, + p->clkd->info.name, st->num_returned, st->num_remaining, st->rx_len); =20 SCMI_QUIRK(clock_rates_triplet_out_of_spec, @@ -479,38 +488,19 @@ iter_clk_describe_process_response(const struct scmi_= protocol_handle *ph, const void *response, struct scmi_iterator_state *st, void *priv) { - int ret =3D 0; struct scmi_clk_ipriv *p =3D priv; const struct scmi_msg_resp_clock_describe_rates *r =3D response; =20 - if (!p->clk->rate_discrete) { - switch (st->desc_index + st->loop_idx) { - case 0: - p->clk->range.min_rate =3D RATE_TO_U64(r->rate[0]); - break; - case 1: - p->clk->range.max_rate =3D RATE_TO_U64(r->rate[1]); - break; - case 2: - p->clk->range.step_size =3D RATE_TO_U64(r->rate[2]); - break; - default: - ret =3D -EINVAL; - break; - } - } else { - u64 *rate =3D &p->clk->list.rates[st->desc_index + st->loop_idx]; + p->clkd->rates[st->desc_index + st->loop_idx] =3D + RATE_TO_U64(r->rate[st->loop_idx]); + p->clkd->num_rates++; =20 - *rate =3D RATE_TO_U64(r->rate[st->loop_idx]); - p->clk->list.num_rates++; - } - - return ret; + return 0; } =20 static int scmi_clock_describe_rates_get(const struct scmi_protocol_handle *ph, u32 c= lk_id, - struct scmi_clock_info *clk) + struct clock_info *cinfo) { int ret; void *iter; @@ -519,9 +509,9 @@ scmi_clock_describe_rates_get(const struct scmi_protoco= l_handle *ph, u32 clk_id, .update_state =3D iter_clk_describe_update_state, .process_response =3D iter_clk_describe_process_response, }; + struct scmi_clock_desc *clkd =3D &cinfo->clkds[clk_id]; struct scmi_clk_ipriv cpriv =3D { - .clk_id =3D clk_id, - .clk =3D clk, + .clkd =3D clkd, .dev =3D ph->dev, }; =20 @@ -536,16 +526,23 @@ scmi_clock_describe_rates_get(const struct scmi_proto= col_handle *ph, u32 clk_id, if (ret) return ret; =20 - if (!clk->rate_discrete) { + /* empty set ? */ + if (!clkd->num_rates) + return 0; + + if (!clkd->rate_discrete) { + clkd->info.max_rate =3D clkd->rates[RATE_MAX]; dev_dbg(ph->dev, "Min %llu Max %llu Step %llu Hz\n", - clk->range.min_rate, clk->range.max_rate, - clk->range.step_size); - } else if (clk->list.num_rates) { - sort(clk->list.rates, clk->list.num_rates, - sizeof(clk->list.rates[0]), rate_cmp_func, NULL); + clkd->rates[RATE_MIN], clkd->rates[RATE_MAX], + clkd->rates[RATE_STEP]); + } else { + sort(clkd->rates, clkd->num_rates, + sizeof(clkd->rates[0]), rate_cmp_func, NULL); + clkd->info.max_rate =3D clkd->rates[clkd->num_rates - 1]; } + clkd->info.min_rate =3D clkd->rates[RATE_MIN]; =20 - return ret; + return 0; } =20 static int @@ -630,6 +627,7 @@ static int scmi_clock_determine_rate(const struct scmi_= protocol_handle *ph, { u64 fmin, fmax, ftmp; struct scmi_clock_info *clk; + struct scmi_clock_desc *clkd; struct clock_info *ci =3D ph->get_priv(ph); =20 if (!rate) @@ -639,15 +637,17 @@ static int scmi_clock_determine_rate(const struct scm= i_protocol_handle *ph, if (IS_ERR(clk)) return PTR_ERR(clk); =20 + clkd =3D to_desc(clk); + /* * If we can't figure out what rate it will be, so just return the * rate back to the caller. */ - if (clk->rate_discrete) + if (clkd->rate_discrete) return 0; =20 - fmin =3D clk->range.min_rate; - fmax =3D clk->range.max_rate; + fmin =3D clk->min_rate; + fmax =3D clk->max_rate; if (*rate <=3D fmin) { *rate =3D fmin; return 0; @@ -657,10 +657,10 @@ static int scmi_clock_determine_rate(const struct scm= i_protocol_handle *ph, } =20 ftmp =3D *rate - fmin; - ftmp +=3D clk->range.step_size - 1; /* to round up */ - ftmp =3D div64_ul(ftmp, clk->range.step_size); + ftmp +=3D clkd->rates[RATE_STEP] - 1; /* to round up */ + ftmp =3D div64_ul(ftmp, clkd->rates[RATE_STEP]); =20 - *rate =3D ftmp * clk->range.step_size + fmin; + *rate =3D ftmp * clkd->rates[RATE_STEP] + fmin; =20 return 0; } @@ -1122,17 +1122,16 @@ static int scmi_clock_protocol_init(const struct sc= mi_protocol_handle *ph) if (ret) return ret; =20 - cinfo->clk =3D devm_kcalloc(ph->dev, cinfo->num_clocks, - sizeof(*cinfo->clk), GFP_KERNEL); - if (!cinfo->clk) + cinfo->clkds =3D devm_kcalloc(ph->dev, cinfo->num_clocks, + sizeof(*cinfo->clkds), GFP_KERNEL); + if (!cinfo->clkds) return -ENOMEM; =20 for (clkid =3D 0; clkid < cinfo->num_clocks; clkid++) { - struct scmi_clock_info *clk =3D cinfo->clk + clkid; - + cinfo->clkds[clkid].id =3D clkid; ret =3D scmi_clock_attributes_get(ph, clkid, cinfo); if (!ret) - scmi_clock_describe_rates_get(ph, clkid, clk); + scmi_clock_describe_rates_get(ph, clkid, cinfo); } =20 if (PROTOCOL_REV_MAJOR(ph->version) >=3D 0x3) { diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index 28579c145045..7283302b0c85 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -51,6 +51,8 @@ struct scmi_clock_info { bool rate_ctrl_forbidden; bool parent_ctrl_forbidden; bool extended_config; + u64 min_rate; + u64 max_rate; union { struct { int num_rates; --=20 2.53.0 From nobody Wed Apr 8 03:09:21 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6BEF838BF87; Tue, 10 Mar 2026 18:41:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168068; cv=none; b=WUeMJlc+BzvlkeDMGArimko69EUq8powRkjOAiux6L2BCrr8sBgFhlbJ+CzBAZYZlBo1lX6hMPNr+/58Nkoxm3wSTW2bGNf1oHMz6NriV5vbtwOHNR20mRxwsQ343cyCJLmVvvt51S8JoMcxGEi0E7ssuoZERIgljXF1drSWyC4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168068; c=relaxed/simple; bh=AxDBdwk/l4DP4oCMpuyPHG7biswl244Z7Wb0hlRCNKM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nqIGK1c7YM1RkfsNF4rm1mm24dpzqRXOFA2vr3jI49DX0/xz2ooNt299TfZ8AAtCkFaEYcEEbqQTxryCH382w0JlsBUKvi/vOZtYhVWGv79W7viqnjWJcRtTaZUPrnVobQXCjnqud6VlAWwHRg21FlKcLQKtamFj3F6JIdF/Uis= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9C1DD14BF; Tue, 10 Mar 2026 11:40:55 -0700 (PDT) Received: from pluto.guest.local (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 080643F7BD; Tue, 10 Mar 2026 11:40:57 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org, linux-clk@vger.kernel.org, linux-renesas-soc@vger.kernel.org Cc: sudeep.holla@arm.com, philip.radford@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@foss.st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, dan.carpenter@linaro.org, geert+renesas@glider.be, kuninori.morimoto.gx@renesas.com, marek.vasut+renesas@gmail.com, Cristian Marussi , Michael Turquette , Stephen Boyd , Peng Fan Subject: [PATCH v2 05/13] clk: scmi: Use new simplified per-clock rate properties Date: Tue, 10 Mar 2026 18:40:22 +0000 Message-ID: <20260310184030.3669330-6-cristian.marussi@arm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310184030.3669330-1-cristian.marussi@arm.com> References: <20260310184030.3669330-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Use the new min_rate and max_rate unified properties that provide the proper values without having to consider the clock type. Cc: Michael Turquette Cc: Stephen Boyd Cc: linux-clk@vger.kernel.org Reviewed-by: Peng Fan Signed-off-by: Cristian Marussi Tested-by: Geert Uytterhoeven --- v1 --> v2 - Collected Peng Reviewed-by tag --- drivers/clk/clk-scmi.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c index c223e4ef1dd1..7c562559ad8b 100644 --- a/drivers/clk/clk-scmi.c +++ b/drivers/clk/clk-scmi.c @@ -202,7 +202,6 @@ static int scmi_clk_ops_init(struct device *dev, struct= scmi_clk *sclk, const struct clk_ops *scmi_ops) { int ret; - unsigned long min_rate, max_rate; =20 struct clk_init_data init =3D { .flags =3D CLK_GET_RATE_NOCACHE, @@ -217,20 +216,8 @@ static int scmi_clk_ops_init(struct device *dev, struc= t scmi_clk *sclk, if (ret) return ret; =20 - if (sclk->info->rate_discrete) { - int num_rates =3D sclk->info->list.num_rates; - - if (num_rates <=3D 0) - return -EINVAL; - - min_rate =3D sclk->info->list.rates[0]; - max_rate =3D sclk->info->list.rates[num_rates - 1]; - } else { - min_rate =3D sclk->info->range.min_rate; - max_rate =3D sclk->info->range.max_rate; - } - - clk_hw_set_rate_range(&sclk->hw, min_rate, max_rate); + clk_hw_set_rate_range(&sclk->hw, sclk->info->min_rate, + sclk->info->max_rate); return ret; } =20 --=20 2.53.0 From nobody Wed Apr 8 03:09:21 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7B38D3DC4A1; Tue, 10 Mar 2026 18:41:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168068; cv=none; b=fJDqs2R/8HsYAmEy/LOdtS3OL0yTJXG9E8Y06/uUO+B2AQd2fxtXR2eV/H859kbnUkv3HHx4C25VXmW9iPaP4cONm377RMTaCoM5v6L8/OMDHEeFczJbKoNnVC6jir1TmVEMpp6Db86RDVMPDBcRSxV/FmfT4A7ftL+KrA45SbI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168068; c=relaxed/simple; bh=Jx+iLBHfzCZCNu0Rbo9kQcSH7PClpwB4Q84bljdtVgQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XE9rqklNhymbymrT7341vEZOWLJ4X99O8TxyU6PtTmewJ/kyZivckpvUCyGFenLT4j3BU2Fs70RpEEh21SMYgCdNQD3NluR0u6wM9yIQPIeXspNRErDOmNIYisli0sC9N+f1XN1/3/7u9weAdXCOEBXlu5HT1iB/tTqsNDH3YUI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 86C111596; Tue, 10 Mar 2026 11:40:59 -0700 (PDT) Received: from pluto.guest.local (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 28F193F7BD; Tue, 10 Mar 2026 11:41:02 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org, linux-clk@vger.kernel.org, linux-renesas-soc@vger.kernel.org Cc: sudeep.holla@arm.com, philip.radford@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@foss.st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, dan.carpenter@linaro.org, geert+renesas@glider.be, kuninori.morimoto.gx@renesas.com, marek.vasut+renesas@gmail.com, Cristian Marussi , Peng Fan Subject: [PATCH v2 06/13] firmware: arm_scmi: Drop unused clock rate interfaces Date: Tue, 10 Mar 2026 18:40:23 +0000 Message-ID: <20260310184030.3669330-7-cristian.marussi@arm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310184030.3669330-1-cristian.marussi@arm.com> References: <20260310184030.3669330-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Only the unified interface exposing min_rate/max_rate is now used. Reviewed-by: Peng Fan Signed-off-by: Cristian Marussi Tested-by: Geert Uytterhoeven --- v1 --> v2 - Collected Peng Reviewed-by tag --- include/linux/scmi_protocol.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index 7283302b0c85..d97b4e734744 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -53,17 +53,6 @@ struct scmi_clock_info { bool extended_config; u64 min_rate; u64 max_rate; - union { - struct { - int num_rates; - u64 rates[SCMI_MAX_NUM_RATES]; - } list; - struct { - u64 min_rate; - u64 max_rate; - u64 step_size; - } range; - }; int num_parents; u32 *parents; }; --=20 2.53.0 From nobody Wed Apr 8 03:09:21 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0369B3ACA59; Tue, 10 Mar 2026 18:41:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168073; cv=none; b=iM3vvmNZGNuXb10HDY+crbHBiyKib93URBAqL+IKTsUwBg7HPOAr1A218QQ+mBfddulKpDjGvGqRl7ATFU7jyLmOckd67MSKER8KAPX8fsokT749HejHhyrNIhUXrUqwSx+eQ2Go4walYnFxj+oFh43DOLVQLLHM+xkZnK0UUjQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168073; c=relaxed/simple; bh=tAXZbQO3lfNUeKaNdgyEAOZcuatbe/cp0YB0Fsh0EPc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ItjkW64eqGOI1hiLUTBBtBzGaDJdqXX8byAM8q0g/Ws/u0cQ6XWtWkWEfzM4UJF+jJKQ9TrGeVzVjcz5SEkENmw1VNdDurVw67uQE3XC9Rvzh5MHryhW9mDiDMKHMYCHeVTU9zU58Xn0ZlY5Hs2GzE3rwz86t6iB18YhsixpbZo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 29A2014BF; Tue, 10 Mar 2026 11:41:03 -0700 (PDT) Received: from pluto.guest.local (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 12B433F7BD; Tue, 10 Mar 2026 11:41:05 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org, linux-clk@vger.kernel.org, linux-renesas-soc@vger.kernel.org Cc: sudeep.holla@arm.com, philip.radford@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@foss.st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, dan.carpenter@linaro.org, geert+renesas@glider.be, kuninori.morimoto.gx@renesas.com, marek.vasut+renesas@gmail.com, Cristian Marussi Subject: [PATCH v2 07/13] firmware: arm_scmi: Make clock rates allocation dynamic Date: Tue, 10 Mar 2026 18:40:24 +0000 Message-ID: <20260310184030.3669330-8-cristian.marussi@arm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310184030.3669330-1-cristian.marussi@arm.com> References: <20260310184030.3669330-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Leveraging SCMI Clock protocol dynamic discovery capabilities, move away from the static per-clock rates allocation model in favour of a dynamic runtime allocation based on effectively discovered resources. No functional change. Signed-off-by: Cristian Marussi Reviewed-by: Peng Fan Tested-by: Geert Uytterhoeven --- drivers/firmware/arm_scmi/clock.c | 19 ++++++++++++++++--- include/linux/scmi_protocol.h | 1 - 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/= clock.c index 467b13a3a18f..c9b62edce4fd 100644 --- a/drivers/firmware/arm_scmi/clock.c +++ b/drivers/firmware/arm_scmi/clock.c @@ -161,7 +161,7 @@ struct scmi_clock_desc { u32 id; bool rate_discrete; unsigned int num_rates; - u64 rates[SCMI_MAX_NUM_RATES]; + u64 *rates; #define RATE_MIN 0 #define RATE_MAX 1 #define RATE_STEP 2 @@ -480,6 +480,18 @@ iter_clk_describe_update_state(struct scmi_iterator_st= ate *st, QUIRK_OUT_OF_SPEC_TRIPLET); } =20 + if (!st->max_resources) { + int num_rates =3D st->num_returned + st->num_remaining; + + p->clkd->rates =3D devm_kcalloc(p->dev, num_rates, + sizeof(*p->clkd->rates), GFP_KERNEL); + if (!p->clkd->rates) + return -ENOMEM; + + /* max_resources is used by the iterators to control bounds */ + st->max_resources =3D st->num_returned + st->num_remaining; + } + return 0; } =20 @@ -493,6 +505,8 @@ iter_clk_describe_process_response(const struct scmi_pr= otocol_handle *ph, =20 p->clkd->rates[st->desc_index + st->loop_idx] =3D RATE_TO_U64(r->rate[st->loop_idx]); + + /* Count only effectively discovered rates */ p->clkd->num_rates++; =20 return 0; @@ -515,8 +529,7 @@ scmi_clock_describe_rates_get(const struct scmi_protoco= l_handle *ph, u32 clk_id, .dev =3D ph->dev, }; =20 - iter =3D ph->hops->iter_response_init(ph, &ops, SCMI_MAX_NUM_RATES, - CLOCK_DESCRIBE_RATES, + iter =3D ph->hops->iter_response_init(ph, &ops, 0, CLOCK_DESCRIBE_RATES, sizeof(struct scmi_msg_clock_describe_rates), &cpriv); if (IS_ERR(iter)) diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index d97b4e734744..5552ac04c820 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -15,7 +15,6 @@ =20 #define SCMI_MAX_STR_SIZE 64 #define SCMI_SHORT_NAME_MAX_SIZE 16 -#define SCMI_MAX_NUM_RATES 16 =20 /** * struct scmi_revision_info - version information structure --=20 2.53.0 From nobody Wed Apr 8 03:09:21 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0DDE63DCD80; Tue, 10 Mar 2026 18:41:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168082; cv=none; b=WRtDEV+zS2cMLpPiXQsN2/z6v9PTNTz5Y5xbJegj8wi+sS4BUUA/5BjWj3y69zfGUiSrEVKSNwNF9qgDbjTc0xlnZwSKM4tCj+lwDPjTYhSZsNrl1BTekytW5khGBY5oWRTcfPDPhUZIuRqwhw2bM+2p9wOhTI2LNrMBe7wW+80= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168082; c=relaxed/simple; bh=0gtxfZvGuGgeBgIZ7QQiH9NmWBca46yZWoiKvZCz40s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=s8Q53gpotPTuxpRR4S/85FgMpA429CWafh3I7lxjN+oLSWt24nMSeMOYkHULEQ4yAQ2vNvz0qfjj095Tl/CeAVBDdksr4jz22B0gEL7jR2IC79q+SqkoN9+2aQvXq5IkYzIhiQAbC2W4mwgHgx/kt9IMhEiFp7T/csWqrHIgfVI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E659E14BF; Tue, 10 Mar 2026 11:41:07 -0700 (PDT) Received: from pluto.guest.local (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id AAC3B3F7BD; Tue, 10 Mar 2026 11:41:09 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org, linux-clk@vger.kernel.org, linux-renesas-soc@vger.kernel.org Cc: sudeep.holla@arm.com, philip.radford@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@foss.st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, dan.carpenter@linaro.org, geert+renesas@glider.be, kuninori.morimoto.gx@renesas.com, marek.vasut+renesas@gmail.com, Cristian Marussi Subject: [PATCH v2 08/13] firmware: arm_scmi: Harden clock protocol initialization Date: Tue, 10 Mar 2026 18:40:25 +0000 Message-ID: <20260310184030.3669330-9-cristian.marussi@arm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310184030.3669330-1-cristian.marussi@arm.com> References: <20260310184030.3669330-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add proper error handling on failure to enumerate clocks features or rates. Signed-off-by: Cristian Marussi Tested-by: Geert Uytterhoeven --- drivers/firmware/arm_scmi/clock.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/= clock.c index c9b62edce4fd..bf956305a8fe 100644 --- a/drivers/firmware/arm_scmi/clock.c +++ b/drivers/firmware/arm_scmi/clock.c @@ -402,10 +402,16 @@ static int scmi_clock_attributes_get(const struct scm= i_protocol_handle *ph, SUPPORTS_RATE_CHANGE_REQUESTED_NOTIF(attributes)) clk->rate_change_requested_notifications =3D true; if (PROTOCOL_REV_MAJOR(ph->version) >=3D 0x3) { - if (SUPPORTS_PARENT_CLOCK(attributes)) - scmi_clock_possible_parents(ph, clk_id, cinfo); - if (SUPPORTS_GET_PERMISSIONS(attributes)) - scmi_clock_get_permissions(ph, clk_id, clk); + if (SUPPORTS_PARENT_CLOCK(attributes)) { + ret =3D scmi_clock_possible_parents(ph, clk_id, cinfo); + if (ret) + return ret; + } + if (SUPPORTS_GET_PERMISSIONS(attributes)) { + ret =3D scmi_clock_get_permissions(ph, clk_id, clk); + if (ret) + return ret; + } if (SUPPORTS_EXTENDED_CONFIG(attributes)) clk->extended_config =3D true; } @@ -1143,8 +1149,12 @@ static int scmi_clock_protocol_init(const struct scm= i_protocol_handle *ph) for (clkid =3D 0; clkid < cinfo->num_clocks; clkid++) { cinfo->clkds[clkid].id =3D clkid; ret =3D scmi_clock_attributes_get(ph, clkid, cinfo); - if (!ret) - scmi_clock_describe_rates_get(ph, clkid, cinfo); + if (ret) + return ret; + + ret =3D scmi_clock_describe_rates_get(ph, clkid, cinfo); + if (ret) + return ret; } =20 if (PROTOCOL_REV_MAJOR(ph->version) >=3D 0x3) { --=20 2.53.0 From nobody Wed Apr 8 03:09:21 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3EE883D3CEC; Tue, 10 Mar 2026 18:41:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168086; cv=none; b=rrSoSDARGrxuO2SDviEjYl/svJQfoPa4RiTgKLEUpflBE40Soq5J4I3KkciWjqzBAAHXBPg4aukcjaevZg2OcZ/rO62rP0ygFHsIJoED+Mz5ef6iYjKW2hdeLG2c2E7pRGQe7DVOii6RkVBIHVyFeW5hSXdHx3E6J54pRvJv74Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168086; c=relaxed/simple; bh=gVTXXUE7IQUGsVeOy2FxRTwfLfEGpwrdcxq04i0MjL8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sKrxPuFMjuKcaOTBvILN8tdxvFwYzoqNHZXANqUJ7sOgn7ZqEULmYF1m0FCVoHnmE7cchq35x889WjNu/rWPzbwdeMXJnHpkTaFtCBKmVGxax5PPomWxaCx4hiFgE4Q++hgx3xZ2FGoAY7dAWmXz2o8kuSl/lEMnu6266dMhPjY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6F7031596; Tue, 10 Mar 2026 11:41:12 -0700 (PDT) Received: from pluto.guest.local (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9CA273F7BD; Tue, 10 Mar 2026 11:41:14 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org, linux-clk@vger.kernel.org, linux-renesas-soc@vger.kernel.org Cc: sudeep.holla@arm.com, philip.radford@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@foss.st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, dan.carpenter@linaro.org, geert+renesas@glider.be, kuninori.morimoto.gx@renesas.com, marek.vasut+renesas@gmail.com, Cristian Marussi Subject: [PATCH v2 09/13] firmware: arm_scmi: Harden clock parents discovery Date: Tue, 10 Mar 2026 18:40:26 +0000 Message-ID: <20260310184030.3669330-10-cristian.marussi@arm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310184030.3669330-1-cristian.marussi@arm.com> References: <20260310184030.3669330-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Fix clock parents enumeration to account only for effectively discovered parents during enumeration, avoiding to trust the total number of parents declared upfront by the platform. Signed-off-by: Cristian Marussi Reviewed-by: Peng Fan Tested-by: Geert Uytterhoeven --- drivers/firmware/arm_scmi/clock.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/= clock.c index bf956305a8fe..5f6b25c7b523 100644 --- a/drivers/firmware/arm_scmi/clock.c +++ b/drivers/firmware/arm_scmi/clock.c @@ -270,15 +270,15 @@ static int iter_clk_possible_parents_update_state(str= uct scmi_iterator_state *st * assume it's returned+remaining on first call. */ if (!st->max_resources) { - p->clkd->info.num_parents =3D st->num_returned + st->num_remaining; - p->clkd->info.parents =3D devm_kcalloc(p->dev, - p->clkd->info.num_parents, + int num_parents =3D st->num_returned + st->num_remaining; + + p->clkd->info.parents =3D devm_kcalloc(p->dev, num_parents, sizeof(*p->clkd->info.parents), GFP_KERNEL); - if (!p->clkd->info.parents) { - p->clkd->info.num_parents =3D 0; + if (!p->clkd->info.parents) return -ENOMEM; - } + + /* max_resources is used by the iterators to control bounds */ st->max_resources =3D st->num_returned + st->num_remaining; } =20 @@ -293,9 +293,11 @@ static int iter_clk_possible_parents_process_response(= const struct scmi_protocol const struct scmi_msg_resp_clock_possible_parents *r =3D response; struct scmi_clk_ipriv *p =3D priv; =20 - u32 *parent =3D &p->clkd->info.parents[st->desc_index + st->loop_idx]; + p->clkd->info.parents[st->desc_index + st->loop_idx] =3D + le32_to_cpu(r->possible_parents[st->loop_idx]); =20 - *parent =3D le32_to_cpu(r->possible_parents[st->loop_idx]); + /* Count only effectively discovered parents */ + p->clkd->info.num_parents++; =20 return 0; } --=20 2.53.0 From nobody Wed Apr 8 03:09:21 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id F0A8E3DCDB8; Tue, 10 Mar 2026 18:41:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168092; cv=none; b=hUc/26v5HIhF0oLM+m0C7fRxxhq2EGjgBfaraxgfGfNCZaN2OL2akWG0X2fIjnjvXZMPsueGDztYg3H/kl+bZVetPL8bzuigAE/nASViNd2PQ/v81mX4lyvOutLHQwBvGPs3y5hDNRJmDyQkg510PRaQ8F8Z2xigo9cTH+v5tKA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168092; c=relaxed/simple; bh=eL8cNPPMXiZclbubgOaXwi19oqnawiSQo1n5NvEj14Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ShemV3rDUlxcXPY6KLBfZBq6rdUtK1xCp+j9pw4UI9iUZMqd3J41pYuwNAqhdQ395GPkriOs+XmFJLnfC0CN+gHiHKQH+P+ls5kUpP20rJlwENPBw/GxPYcHwVlcGYh8QUU/b58zHrXX65zXn1gtlDR67jQrKu0pz8aYCqv3tqg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id ECDE81A00; Tue, 10 Mar 2026 11:41:15 -0700 (PDT) Received: from pluto.guest.local (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id F0DF73F7BD; Tue, 10 Mar 2026 11:41:18 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org, linux-clk@vger.kernel.org, linux-renesas-soc@vger.kernel.org Cc: sudeep.holla@arm.com, philip.radford@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@foss.st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, dan.carpenter@linaro.org, geert+renesas@glider.be, kuninori.morimoto.gx@renesas.com, marek.vasut+renesas@gmail.com, Cristian Marussi Subject: [PATCH v2 10/13] firmware: arm_scmi: Refactor iterators internal allocation Date: Tue, 10 Mar 2026 18:40:27 +0000 Message-ID: <20260310184030.3669330-11-cristian.marussi@arm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310184030.3669330-1-cristian.marussi@arm.com> References: <20260310184030.3669330-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Use cleanup handlers to manage iterator data structures. No functional change. Signed-off-by: Cristian Marussi Reviewed-by: Peng Fan Tested-by: Geert Uytterhoeven --- drivers/firmware/arm_scmi/driver.c | 35 +++++++++++++++--------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi= /driver.c index 3e76a3204ba4..4bd069da879e 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -17,6 +17,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt =20 #include +#include #include #include #include @@ -1789,39 +1790,41 @@ static void *scmi_iterator_init(const struct scmi_p= rotocol_handle *ph, size_t tx_size, void *priv) { int ret; - struct scmi_iterator *i; =20 - i =3D devm_kzalloc(ph->dev, sizeof(*i), GFP_KERNEL); + struct scmi_iterator *i __free(kfree) =3D kzalloc(sizeof(*i), GFP_KERNEL); if (!i) return ERR_PTR(-ENOMEM); =20 + if (!ops || !ph) + return ERR_PTR(-EINVAL); + i->ph =3D ph; i->ops =3D ops; i->priv =3D priv; =20 ret =3D ph->xops->xfer_get_init(ph, msg_id, tx_size, 0, &i->t); - if (ret) { - devm_kfree(ph->dev, i); + if (ret) return ERR_PTR(ret); - } =20 i->state.max_resources =3D max_resources; i->msg =3D i->t->tx.buf; i->resp =3D i->t->rx.buf; =20 - return i; + return no_free_ptr(i); } =20 static int scmi_iterator_run(void *iter) { - int ret =3D -EINVAL; + int ret; struct scmi_iterator_ops *iops; const struct scmi_protocol_handle *ph; struct scmi_iterator_state *st; - struct scmi_iterator *i =3D iter; =20 - if (!i || !i->ops || !i->ph) - return ret; + if (!iter) + return -EINVAL; + + /* Take ownership of the iterator */ + struct scmi_iterator *i __free(kfree) =3D iter; =20 iops =3D i->ops; ph =3D i->ph; @@ -1846,12 +1849,12 @@ static int scmi_iterator_run(void *iter) break; } =20 - for (st->loop_idx =3D 0; st->loop_idx < st->num_returned; - st->loop_idx++) { + for (st->loop_idx =3D 0; !ret && st->loop_idx < st->num_returned; + st->loop_idx++) ret =3D iops->process_response(ph, i->resp, st, i->priv); - if (ret) - goto out; - } + + if (ret) + break; =20 st->desc_index +=3D st->num_returned; ph->xops->reset_rx_to_maxsz(ph, i->t); @@ -1861,10 +1864,8 @@ static int scmi_iterator_run(void *iter) */ } while (st->num_returned && st->num_remaining); =20 -out: /* Finalize and destroy iterator */ ph->xops->xfer_put(ph, i->t); - devm_kfree(ph->dev, i); =20 return ret; } --=20 2.53.0 From nobody Wed Apr 8 03:09:21 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A29A23DCDA7; Tue, 10 Mar 2026 18:41:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168091; cv=none; b=tgfVnvxe/aXcojkuzQR4Fzqz/Sa4yI1oMfIj+XhY4h3HQ7mfOqbghCq86q3r3e1PbFI/Wzr3WWpSIn0p5XFVO+oFPWDYimtB1yNUxzQxRZZ7ZHe9wc92qOjqziJ7Odmbr/MDnRvbG1WYNWnTAHQ9+0OfBZjbEYK/i2VzjF9m4sM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168091; c=relaxed/simple; bh=4PsJYF0qEC5bYPzqJY/2oi7M+0Ulx0rXVTlWOgy9JOo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BYb7yhqicfvkUXlSaV2ZEYftdyrmuk4+IDkolj3lbwB6U/W5fVhZO8mqa5LkNZ9V8rB5Qj7qyUloZuJ8nohKxEfurm//3FThi0xab5T6oWO8m8gzijPBiFIOW2tLpBxyBZXJAynMWIcD3MthtwqqW+Yaz9cj48ehS5aZ9ZZf3Ec= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 996D014BF; Tue, 10 Mar 2026 11:41:19 -0700 (PDT) Received: from pluto.guest.local (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9C2903F7BD; Tue, 10 Mar 2026 11:41:22 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org, linux-clk@vger.kernel.org, linux-renesas-soc@vger.kernel.org Cc: sudeep.holla@arm.com, philip.radford@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@foss.st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, dan.carpenter@linaro.org, geert+renesas@glider.be, kuninori.morimoto.gx@renesas.com, marek.vasut+renesas@gmail.com, Cristian Marussi Subject: [PATCH v2 11/13] firmware: arm_scmi: Add bound iterators support Date: Tue, 10 Mar 2026 18:40:28 +0000 Message-ID: <20260310184030.3669330-12-cristian.marussi@arm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310184030.3669330-1-cristian.marussi@arm.com> References: <20260310184030.3669330-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" SCMI core stack provides some common helpers to handle in a unified way multipart message replies: such iterator-helpers, when run, currently process by default the whole set of discovered resources. Introduce an alternative way to run the initialized iterator on a limited range of resources. Note that the subset of resources that can be chosen is anyway limited by the SCMI protocol specification, since you are only allowed to choose the startindex on a multi-part enumeration NOT the end index, so that the effective number of returned items by a bound iterators depends really on platform side decisions. Suggested-by: Etienne Carriere Signed-off-by: Cristian Marussi Tested-by: Geert Uytterhoeven --- drivers/firmware/arm_scmi/clock.c | 3 +- drivers/firmware/arm_scmi/driver.c | 58 +++++++++++++++++++-------- drivers/firmware/arm_scmi/protocols.h | 13 +++++- 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/= clock.c index 5f6b25c7b523..a7dbb0c4f31c 100644 --- a/drivers/firmware/arm_scmi/clock.c +++ b/drivers/firmware/arm_scmi/clock.c @@ -511,8 +511,7 @@ iter_clk_describe_process_response(const struct scmi_pr= otocol_handle *ph, struct scmi_clk_ipriv *p =3D priv; const struct scmi_msg_resp_clock_describe_rates *r =3D response; =20 - p->clkd->rates[st->desc_index + st->loop_idx] =3D - RATE_TO_U64(r->rate[st->loop_idx]); + p->clkd->rates[p->clkd->num_rates] =3D RATE_TO_U64(r->rate[st->loop_idx]); =20 /* Count only effectively discovered rates */ p->clkd->num_rates++; diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi= /driver.c index 4bd069da879e..3c393a071750 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -1813,48 +1813,50 @@ static void *scmi_iterator_init(const struct scmi_p= rotocol_handle *ph, return no_free_ptr(i); } =20 -static int scmi_iterator_run(void *iter) +static int __scmi_iterator_run(void *iter, unsigned int *start, unsigned i= nt *end) { int ret; struct scmi_iterator_ops *iops; const struct scmi_protocol_handle *ph; struct scmi_iterator_state *st; + struct scmi_iterator *i; =20 if (!iter) return -EINVAL; =20 - /* Take ownership of the iterator */ - struct scmi_iterator *i __free(kfree) =3D iter; - + i =3D iter; iops =3D i->ops; ph =3D i->ph; st =3D &i->state; =20 + /* Reinitialize state for next run */ + st->num_returned =3D 0; + st->num_remaining =3D 0; + st->desc_index =3D start ? *start : 0; + do { iops->prepare_message(i->msg, st->desc_index, i->priv); ret =3D ph->xops->do_xfer(ph, i->t); if (ret) - break; + return ret; =20 st->rx_len =3D i->t->rx.len; ret =3D iops->update_state(st, i->resp, i->priv); if (ret) - break; + return ret; =20 if (st->num_returned > st->max_resources - st->desc_index) { dev_err(ph->dev, "No. of resources can't exceed %d\n", st->max_resources); - ret =3D -EINVAL; - break; + return -EINVAL; } =20 - for (st->loop_idx =3D 0; !ret && st->loop_idx < st->num_returned; - st->loop_idx++) + for (st->loop_idx =3D 0; st->loop_idx < st->num_returned; st->loop_idx++= ) { ret =3D iops->process_response(ph, i->resp, st, i->priv); - - if (ret) - break; + if (ret) + return ret; + } =20 st->desc_index +=3D st->num_returned; ph->xops->reset_rx_to_maxsz(ph, i->t); @@ -1862,14 +1864,36 @@ static int scmi_iterator_run(void *iter) * check for both returned and remaining to avoid infinite * loop due to buggy firmware */ - } while (st->num_returned && st->num_remaining); + } while (st->num_returned && st->num_remaining && + (!end || (st->desc_index <=3D min(*end, st->max_resources - 1)))); =20 - /* Finalize and destroy iterator */ - ph->xops->xfer_put(ph, i->t); + return 0; +} + +static void scmi_iterator_cleanup(void *iter) +{ + struct scmi_iterator *i =3D iter; + + i->ph->xops->xfer_put(i->ph, i->t); + kfree(i); +} + +static int scmi_iterator_run(void *iter) +{ + int ret; + + ret =3D __scmi_iterator_run(iter, NULL, NULL); + scmi_iterator_cleanup(iter); =20 return ret; } =20 +static int scmi_iterator_run_bound(void *iter, unsigned int *start, + unsigned int *end) +{ + return __scmi_iterator_run(iter, start, end); +} + struct scmi_msg_get_fc_info { __le32 domain; __le32 message_id; @@ -2048,6 +2072,8 @@ static const struct scmi_proto_helpers_ops helpers_op= s =3D { .get_max_msg_size =3D scmi_common_get_max_msg_size, .iter_response_init =3D scmi_iterator_init, .iter_response_run =3D scmi_iterator_run, + .iter_response_run_bound =3D scmi_iterator_run_bound, + .iter_response_cleanup =3D scmi_iterator_cleanup, .protocol_msg_check =3D scmi_protocol_msg_check, .fastchannel_init =3D scmi_common_fastchannel_init, .fastchannel_db_ring =3D scmi_common_fastchannel_db_ring, diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_s= cmi/protocols.h index 4c75970326e6..487f84239385 100644 --- a/drivers/firmware/arm_scmi/protocols.h +++ b/drivers/firmware/arm_scmi/protocols.h @@ -259,7 +259,15 @@ struct scmi_fc_info { * multi-part responses using the custom operations * provided in @ops. * @iter_response_run: A common helper to trigger the run of a previously - * initialized iterator. + * initialized iterator. Note that unbound iterators are + * automatically cleaned up. + * @iter_response_run_bound: A common helper to trigger the run of a previ= ously + * initialized iterator, but only within the + * specified, optional, @start and @end resource + * indexes. Note that these bound-iterators need + * explicit cleanup via @iter_response_bound_cleanup. + * @iter_response_bound_cleanup: A common helper to finally release the it= erator + * for bound iterators. * @protocol_msg_check: A common helper to check is a specific protocol me= ssage * is supported. * @fastchannel_init: A common helper used to initialize FC descriptors by @@ -276,6 +284,9 @@ struct scmi_proto_helpers_ops { unsigned int max_resources, u8 msg_id, size_t tx_size, void *priv); int (*iter_response_run)(void *iter); + int (*iter_response_run_bound)(void *iter, + unsigned int *start, unsigned int *end); + void (*iter_response_cleanup)(void *iter); int (*protocol_msg_check)(const struct scmi_protocol_handle *ph, u32 message_id, u32 *attributes); void (*fastchannel_init)(const struct scmi_protocol_handle *ph, --=20 2.53.0 From nobody Wed Apr 8 03:09:21 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4476D3DD531; Tue, 10 Mar 2026 18:41:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168095; cv=none; b=VKeZPeP/2wnePeb3htebL3HVdApgOgYzbSUNNEeQRvIxhlGVP1yO1v/dzP84SaQBCeHHL9KqpC4ambvK9W7mEFvP3aHp+ifIfvikFQ9reVPoxGNqIRADTETEeyEOXSWaGuK1Qe65uvP12b6ke+Fhrd6PZWyQiDPSATcoASq+jHg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168095; c=relaxed/simple; bh=Fe70dvm/fvloZZ/pzMVRZXpVJRbHMWgs0CJxlTumHmY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QtH8h1yqoHiZehsk2cfZChl/dCUbAH3kfy0uqbBycgrdW+qpn2+Daed5Vcw86IOvz90R7T3hDhiACRE3cYFxDKLpdrlsJp059XaM7iA4grvQLCRUfA+NCQ6mz7OqAebGnygNPkuRoRhDMog+8S2nGg0ooFbRWkMCJ2SM4ePIq64= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4B4D41BA8; Tue, 10 Mar 2026 11:41:23 -0700 (PDT) Received: from pluto.guest.local (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 244953F7BD; Tue, 10 Mar 2026 11:41:25 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org, linux-clk@vger.kernel.org, linux-renesas-soc@vger.kernel.org Cc: sudeep.holla@arm.com, philip.radford@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@foss.st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, dan.carpenter@linaro.org, geert+renesas@glider.be, kuninori.morimoto.gx@renesas.com, marek.vasut+renesas@gmail.com, Cristian Marussi Subject: [PATCH v2 12/13] firmware: arm_scmi: Use bound iterators to minimize discovered rates Date: Tue, 10 Mar 2026 18:40:29 +0000 Message-ID: <20260310184030.3669330-13-cristian.marussi@arm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310184030.3669330-1-cristian.marussi@arm.com> References: <20260310184030.3669330-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Clock rates are guaranteed to be returned in ascending order for SCMI clock protocol versions greater than 1.0: in such a case, use bounded iterators to minimize the number of message exchanges needed to discover min and max rate. Signed-off-by: Cristian Marussi Tested-by: Geert Uytterhoeven --- v1 --> v2 - fixed final ret value in scmi_clock_describe_get --- drivers/firmware/arm_scmi/clock.c | 90 +++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 9 deletions(-) diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/= clock.c index a7dbb0c4f31c..f50689bf5414 100644 --- a/drivers/firmware/arm_scmi/clock.c +++ b/drivers/firmware/arm_scmi/clock.c @@ -160,6 +160,7 @@ struct scmi_clock_rate_notify_payld { struct scmi_clock_desc { u32 id; bool rate_discrete; + unsigned int tot_rates; unsigned int num_rates; u64 *rates; #define RATE_MIN 0 @@ -489,15 +490,16 @@ iter_clk_describe_update_state(struct scmi_iterator_s= tate *st, } =20 if (!st->max_resources) { - int num_rates =3D st->num_returned + st->num_remaining; + unsigned int tot_rates =3D st->num_returned + st->num_remaining; =20 - p->clkd->rates =3D devm_kcalloc(p->dev, num_rates, + p->clkd->rates =3D devm_kcalloc(p->dev, tot_rates, sizeof(*p->clkd->rates), GFP_KERNEL); if (!p->clkd->rates) return -ENOMEM; =20 /* max_resources is used by the iterators to control bounds */ - st->max_resources =3D st->num_returned + st->num_remaining; + p->clkd->tot_rates =3D tot_rates; + st->max_resources =3D tot_rates; } =20 return 0; @@ -520,8 +522,8 @@ iter_clk_describe_process_response(const struct scmi_pr= otocol_handle *ph, } =20 static int -scmi_clock_describe_rates_get(const struct scmi_protocol_handle *ph, u32 c= lk_id, - struct clock_info *cinfo) +scmi_clock_describe_rates_get_full(const struct scmi_protocol_handle *ph, + struct scmi_clock_desc *clkd) { int ret; void *iter; @@ -530,7 +532,6 @@ scmi_clock_describe_rates_get(const struct scmi_protoco= l_handle *ph, u32 clk_id, .update_state =3D iter_clk_describe_update_state, .process_response =3D iter_clk_describe_process_response, }; - struct scmi_clock_desc *clkd =3D &cinfo->clkds[clk_id]; struct scmi_clk_ipriv cpriv =3D { .clkd =3D clkd, .dev =3D ph->dev, @@ -550,17 +551,88 @@ scmi_clock_describe_rates_get(const struct scmi_proto= col_handle *ph, u32 clk_id, if (!clkd->num_rates) return 0; =20 + if (clkd->rate_discrete) + sort(clkd->rates, clkd->num_rates, + sizeof(clkd->rates[0]), rate_cmp_func, NULL); + + return 0; +} + +static int +scmi_clock_describe_rates_get_lazy(const struct scmi_protocol_handle *ph, + struct scmi_clock_desc *clkd) +{ + struct scmi_iterator_ops ops =3D { + .prepare_message =3D iter_clk_describe_prepare_message, + .update_state =3D iter_clk_describe_update_state, + .process_response =3D iter_clk_describe_process_response, + }; + struct scmi_clk_ipriv cpriv =3D { + .clkd =3D clkd, + .dev =3D ph->dev, + }; + unsigned int first, last; + void *iter; + int ret; + + iter =3D ph->hops->iter_response_init(ph, &ops, 0, CLOCK_DESCRIBE_RATES, + sizeof(struct scmi_msg_clock_describe_rates), + &cpriv); + if (IS_ERR(iter)) + return PTR_ERR(iter); + + /* Try to grab a triplet, so that in case is NON-discrete we are done */ + first =3D 0; + last =3D 2; + ret =3D ph->hops->iter_response_run_bound(iter, &first, &last); + if (ret) + goto out; + + /* If discrete grab the last value, which should be the max */ + if (clkd->rate_discrete && clkd->tot_rates > 3) { + first =3D clkd->tot_rates - 1; + last =3D clkd->tot_rates - 1; + ret =3D ph->hops->iter_response_run_bound(iter, &first, &last); + } + +out: + ph->hops->iter_response_cleanup(iter); + + return ret; +} + +static int +scmi_clock_describe_rates_get(const struct scmi_protocol_handle *ph, + u32 clk_id, struct clock_info *cinfo) +{ + struct scmi_clock_desc *clkd =3D &cinfo->clkds[clk_id]; + int ret; + + /* + * Since only after SCMI Clock v1.0 the returned rates are guaranteed to + * be discovered in ascending order, lazy enumeration cannot be use for + * SCMI Clock v1.0 protocol. + */ + if (PROTOCOL_REV_MAJOR(ph->version) > 0x1) + ret =3D scmi_clock_describe_rates_get_lazy(ph, clkd); + else + ret =3D scmi_clock_describe_rates_get_full(ph, clkd); + + if (ret) + return ret; + + clkd->info.min_rate =3D clkd->rates[RATE_MIN]; if (!clkd->rate_discrete) { clkd->info.max_rate =3D clkd->rates[RATE_MAX]; dev_dbg(ph->dev, "Min %llu Max %llu Step %llu Hz\n", clkd->rates[RATE_MIN], clkd->rates[RATE_MAX], clkd->rates[RATE_STEP]); } else { - sort(clkd->rates, clkd->num_rates, - sizeof(clkd->rates[0]), rate_cmp_func, NULL); clkd->info.max_rate =3D clkd->rates[clkd->num_rates - 1]; + dev_dbg(ph->dev, "Clock:%s DISCRETE:%d -> Min %llu Max %llu\n", + clkd->info.name, clkd->rate_discrete, + clkd->info.min_rate, clkd->info.max_rate); } - clkd->info.min_rate =3D clkd->rates[RATE_MIN]; =20 return 0; } --=20 2.53.0 From nobody Wed Apr 8 03:09:21 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BA6443DDDA3; Tue, 10 Mar 2026 18:41:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168100; cv=none; b=OIKprhdC8MoWYpPvjmsFj4xywsSdbRFGoveCks7L0MCcd+m+LWj5F1qpH/Lwrd/bJPaaRakqFEyRCLnYFGLCEZKRE/KipzSQk5DrpCSQSsBnzxyNNCt48tqYg6ofBa2JCTI4FNqkkbnQAhYYDFB7ePu77Gh0vnUT4vLzwdfv1KA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773168100; c=relaxed/simple; bh=1QkmU4Mi4WIOxOY2NsEGq0vCDogKf52p+0AlpEx0gks=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MnJFnUjdgdwPPCilcvn6UgFWxx0LI7PUvvADUBI29dNeaRlhv08yXhyyDC5hCdqeOLCEQKh4NVP9Bnwjs6TWqDuVkAfkTJRdz/KpgYxQOQr+plmde0rGsiXd3sts/7eqmmqqNV4mrNYQMpA52d32vOqYcMRPfMsIMRjuWnzrn3A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 1290A14BF; Tue, 10 Mar 2026 11:41:27 -0700 (PDT) Received: from pluto.guest.local (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id CCBB13F7BD; Tue, 10 Mar 2026 11:41:29 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org, linux-clk@vger.kernel.org, linux-renesas-soc@vger.kernel.org Cc: sudeep.holla@arm.com, philip.radford@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@foss.st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, dan.carpenter@linaro.org, geert+renesas@glider.be, kuninori.morimoto.gx@renesas.com, marek.vasut+renesas@gmail.com, Cristian Marussi Subject: [PATCH v2 13/13] firmware: arm_scmi: Introduce all_rates_get clock operation Date: Tue, 10 Mar 2026 18:40:30 +0000 Message-ID: <20260310184030.3669330-14-cristian.marussi@arm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310184030.3669330-1-cristian.marussi@arm.com> References: <20260310184030.3669330-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a clock operation to get the whole set of rates available to a specific clock: when needed this request could transparently trigger a full rate discovery enumeration if this specific clock-rates were previously only lazily enumerated. Signed-off-by: Cristian Marussi Reviewed-by: Peng Fan Tested-by: Geert Uytterhoeven --- drivers/firmware/arm_scmi/clock.c | 85 +++++++++++++++++++++---------- include/linux/scmi_protocol.h | 9 ++++ 2 files changed, 67 insertions(+), 27 deletions(-) diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/= clock.c index f50689bf5414..082fb0db8681 100644 --- a/drivers/firmware/arm_scmi/clock.c +++ b/drivers/firmware/arm_scmi/clock.c @@ -159,10 +159,8 @@ struct scmi_clock_rate_notify_payld { =20 struct scmi_clock_desc { u32 id; - bool rate_discrete; unsigned int tot_rates; - unsigned int num_rates; - u64 *rates; + struct scmi_clock_rates r; #define RATE_MIN 0 #define RATE_MAX 1 #define RATE_STEP 2 @@ -475,10 +473,10 @@ iter_clk_describe_update_state(struct scmi_iterator_s= tate *st, flags =3D le32_to_cpu(r->num_rates_flags); st->num_remaining =3D NUM_REMAINING(flags); st->num_returned =3D NUM_RETURNED(flags); - p->clkd->rate_discrete =3D RATE_DISCRETE(flags); + p->clkd->r.rate_discrete =3D RATE_DISCRETE(flags); =20 /* Warn about out of spec replies ... */ - if (!p->clkd->rate_discrete && + if (!p->clkd->r.rate_discrete && (st->num_returned !=3D 3 || st->num_remaining !=3D 0)) { dev_warn(p->dev, "Out-of-spec CLOCK_DESCRIBE_RATES reply for %s - returned:%d remaining= :%d rx_len:%zd\n", @@ -492,9 +490,9 @@ iter_clk_describe_update_state(struct scmi_iterator_sta= te *st, if (!st->max_resources) { unsigned int tot_rates =3D st->num_returned + st->num_remaining; =20 - p->clkd->rates =3D devm_kcalloc(p->dev, tot_rates, - sizeof(*p->clkd->rates), GFP_KERNEL); - if (!p->clkd->rates) + p->clkd->r.rates =3D devm_kcalloc(p->dev, tot_rates, + sizeof(*p->clkd->r.rates), GFP_KERNEL); + if (!p->clkd->r.rates) return -ENOMEM; =20 /* max_resources is used by the iterators to control bounds */ @@ -513,10 +511,10 @@ iter_clk_describe_process_response(const struct scmi_= protocol_handle *ph, struct scmi_clk_ipriv *p =3D priv; const struct scmi_msg_resp_clock_describe_rates *r =3D response; =20 - p->clkd->rates[p->clkd->num_rates] =3D RATE_TO_U64(r->rate[st->loop_idx]); + p->clkd->r.rates[p->clkd->r.num_rates] =3D RATE_TO_U64(r->rate[st->loop_i= dx]); =20 /* Count only effectively discovered rates */ - p->clkd->num_rates++; + p->clkd->r.num_rates++; =20 return 0; } @@ -537,7 +535,13 @@ scmi_clock_describe_rates_get_full(const struct scmi_p= rotocol_handle *ph, .dev =3D ph->dev, }; =20 - iter =3D ph->hops->iter_response_init(ph, &ops, 0, CLOCK_DESCRIBE_RATES, + /* + * Using tot_rates as max_resources parameter here so as to trigger + * the dynamic allocation only when strictly needed: when trying a + * full enumeration after a lazy one tot_rates will be non-zero. + */ + iter =3D ph->hops->iter_response_init(ph, &ops, clkd->tot_rates, + CLOCK_DESCRIBE_RATES, sizeof(struct scmi_msg_clock_describe_rates), &cpriv); if (IS_ERR(iter)) @@ -548,12 +552,12 @@ scmi_clock_describe_rates_get_full(const struct scmi_= protocol_handle *ph, return ret; =20 /* empty set ? */ - if (!clkd->num_rates) + if (!clkd->r.num_rates) return 0; =20 - if (clkd->rate_discrete) - sort(clkd->rates, clkd->num_rates, - sizeof(clkd->rates[0]), rate_cmp_func, NULL); + if (clkd->r.rate_discrete && PROTOCOL_REV_MAJOR(ph->version) =3D=3D 0x1) + sort(clkd->r.rates, clkd->r.num_rates, + sizeof(clkd->r.rates[0]), rate_cmp_func, NULL); =20 return 0; } @@ -589,7 +593,7 @@ scmi_clock_describe_rates_get_lazy(const struct scmi_pr= otocol_handle *ph, goto out; =20 /* If discrete grab the last value, which should be the max */ - if (clkd->rate_discrete && clkd->tot_rates > 3) { + if (clkd->r.rate_discrete && clkd->tot_rates > 3) { first =3D clkd->tot_rates - 1; last =3D clkd->tot_rates - 1; ret =3D ph->hops->iter_response_run_bound(iter, &first, &last); @@ -621,16 +625,16 @@ scmi_clock_describe_rates_get(const struct scmi_proto= col_handle *ph, if (ret) return ret; =20 - clkd->info.min_rate =3D clkd->rates[RATE_MIN]; - if (!clkd->rate_discrete) { - clkd->info.max_rate =3D clkd->rates[RATE_MAX]; + clkd->info.min_rate =3D clkd->r.rates[RATE_MIN]; + if (!clkd->r.rate_discrete) { + clkd->info.max_rate =3D clkd->r.rates[RATE_MAX]; dev_dbg(ph->dev, "Min %llu Max %llu Step %llu Hz\n", - clkd->rates[RATE_MIN], clkd->rates[RATE_MAX], - clkd->rates[RATE_STEP]); + clkd->r.rates[RATE_MIN], clkd->r.rates[RATE_MAX], + clkd->r.rates[RATE_STEP]); } else { - clkd->info.max_rate =3D clkd->rates[clkd->num_rates - 1]; + clkd->info.max_rate =3D clkd->r.rates[clkd->r.num_rates - 1]; dev_dbg(ph->dev, "Clock:%s DISCRETE:%d -> Min %llu Max %llu\n", - clkd->info.name, clkd->rate_discrete, + clkd->info.name, clkd->r.rate_discrete, clkd->info.min_rate, clkd->info.max_rate); } =20 @@ -735,7 +739,7 @@ static int scmi_clock_determine_rate(const struct scmi_= protocol_handle *ph, * If we can't figure out what rate it will be, so just return the * rate back to the caller. */ - if (clkd->rate_discrete) + if (clkd->r.rate_discrete) return 0; =20 fmin =3D clk->min_rate; @@ -749,14 +753,40 @@ static int scmi_clock_determine_rate(const struct scm= i_protocol_handle *ph, } =20 ftmp =3D *rate - fmin; - ftmp +=3D clkd->rates[RATE_STEP] - 1; /* to round up */ - ftmp =3D div64_ul(ftmp, clkd->rates[RATE_STEP]); + ftmp +=3D clkd->r.rates[RATE_STEP] - 1; /* to round up */ + ftmp =3D div64_ul(ftmp, clkd->r.rates[RATE_STEP]); =20 - *rate =3D ftmp * clkd->rates[RATE_STEP] + fmin; + *rate =3D ftmp * clkd->r.rates[RATE_STEP] + fmin; =20 return 0; } =20 +static const struct scmi_clock_rates * +scmi_clock_all_rates_get(const struct scmi_protocol_handle *ph, u32 clk_id) +{ + struct clock_info *ci =3D ph->get_priv(ph); + struct scmi_clock_desc *clkd; + struct scmi_clock_info *clk; + + clk =3D scmi_clock_domain_lookup(ci, clk_id); + if (IS_ERR(clk) || !clk->name[0]) + return NULL; + + clkd =3D to_desc(clk); + /* Needs full enumeration ? */ + if (clkd->r.rate_discrete && clkd->tot_rates !=3D clkd->r.num_rates) { + int ret; + + /* rates[] is already allocated BUT we need to re-enumerate */ + clkd->r.num_rates =3D 0; + ret =3D scmi_clock_describe_rates_get_full(ph, clkd); + if (ret) + return NULL; + } + + return &clkd->r; +} + static int scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id, enum clk_state state, @@ -1070,6 +1100,7 @@ static const struct scmi_clk_proto_ops clk_proto_ops = =3D { .rate_get =3D scmi_clock_rate_get, .rate_set =3D scmi_clock_rate_set, .determine_rate =3D scmi_clock_determine_rate, + .all_rates_get =3D scmi_clock_all_rates_get, .enable =3D scmi_clock_enable, .disable =3D scmi_clock_disable, .state_get =3D scmi_clock_state_get, diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index 5552ac04c820..c710107c2120 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -40,6 +40,12 @@ struct scmi_revision_info { char sub_vendor_id[SCMI_SHORT_NAME_MAX_SIZE]; }; =20 +struct scmi_clock_rates { + bool rate_discrete; + unsigned int num_rates; + u64 *rates; +}; + struct scmi_clock_info { char name[SCMI_MAX_STR_SIZE]; unsigned int enable_latency; @@ -85,6 +91,7 @@ enum scmi_clock_oem_config { * clock calculating the closest allowed rate. * Note that @rate is an input/output parameter used both to * describe the requested rate and report the closest match + * @all_rates_get: get the list of all available rates for the specified c= lock. * @enable: enables the specified clock * @disable: disables the specified clock * @state_get: get the status of the specified clock @@ -104,6 +111,8 @@ struct scmi_clk_proto_ops { u64 rate); int (*determine_rate)(const struct scmi_protocol_handle *ph, u32 clk_id, unsigned long *rate); + const struct scmi_clock_rates __must_check *(*all_rates_get) + (const struct scmi_protocol_handle *ph, u32 clk_id); int (*enable)(const struct scmi_protocol_handle *ph, u32 clk_id, bool atomic); int (*disable)(const struct scmi_protocol_handle *ph, u32 clk_id, --=20 2.53.0