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

From: Peng Fan

Date: Fri Feb 27 2026 - 21:27:32 EST


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@xxxxxxx>
>---
> 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
>