[PATCH v3 07/15] firmware: arm_scmi: Make clock rates allocation dynamic

Cristian Marussi
2026-04-28T20:16:54Z

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.

Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v2 --> v3
- collected Review-by tags
---
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_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;
+
+ /* 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