[PATCH 06/11] firmware: arm_scmi: Make clock rates allocation dynamic

Peng Fan peng.fan at oss.nxp.com
Fri Feb 27 18:29:11 PST 2026


On Fri, Feb 27, 2026 at 03:32:20PM +0000, Cristian Marussi wrote:
>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 <cristian.marussi at arm.com>
>---
> 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 f5d1c608f85a..d0fb5affb5cf 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_state *st,
> 			   QUIRK_OUT_OF_SPEC_TRIPLET);
> 	}
> 
>+	if (!st->max_resources) {
>+		int num_rates = st->num_returned + st->num_remaining;
>+
>+		p->clkd->rates = devm_kcalloc(p->dev, num_rates,
>+					      sizeof(*p->clkd->rates), GFP_KERNEL);
>+		if (!p->clkd->rates)
>+			return -ENOMEM;

It may be not related to this patch,
I see scmi_clock_describe_rates_get() does not have return value check
when being called in scmi_clock_protocol_init().

So if devm_kcalloc() fails, there maybe issue without a sanity check
to return value of scmi_clock_describe_rates_get().

Regards
Peng

>+
>+		/* max_resources is used by the iterators to control bounds */
>+		st->max_resources = st->num_returned + st->num_remaining;
>+	}
>+
> 	return 0;
> }
> 
>@@ -493,6 +505,8 @@ iter_clk_describe_process_response(const struct scmi_protocol_handle *ph,
> 
> 	p->clkd->rates[st->desc_index + st->loop_idx] =
> 		RATE_TO_U64(r->rate[st->loop_idx]);
>+
>+	/* Count only effectively discovered rates */
> 	p->clkd->num_rates++;
> 
> 	return 0;
>@@ -515,8 +529,7 @@ scmi_clock_describe_rates_get(const struct scmi_protocol_handle *ph, u32 clk_id,
> 		.dev = ph->dev,
> 	};
> 
>-	iter = ph->hops->iter_response_init(ph, &ops, SCMI_MAX_NUM_RATES,
>-					    CLOCK_DESCRIBE_RATES,
>+	iter = 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 @@
> 
> #define SCMI_MAX_STR_SIZE		64
> #define SCMI_SHORT_NAME_MAX_SIZE	16
>-#define SCMI_MAX_NUM_RATES		16
> 
> /**
>  * struct scmi_revision_info - version information structure
>-- 
>2.53.0
>



More information about the linux-arm-kernel mailing list