diff options
| author | GuEe-GUI <[email protected]> | 2026-03-24 20:51:22 +0800 |
|---|---|---|
| committer | Rbb666 <[email protected]> | 2026-03-24 22:56:54 +0800 |
| commit | e41c7ccf88c0b5b8e9f033404fa371b7fd2c9a3b (patch) | |
| tree | 94fbc93fdd743fb4c1e1fc64c93d2601054c00a2 /components/drivers | |
| parent | 25295501c0cc7181d6a541a867fdf7214879ddf8 (diff) | |
[dm][clk][rockchip] fixup rockchip clk
Signed-off-by: GuEe-GUI <[email protected]>
Diffstat (limited to 'components/drivers')
| -rwxr-xr-x | components/drivers/clk/clk-scmi.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/components/drivers/clk/clk-scmi.c b/components/drivers/clk/clk-scmi.c index d6240fa406..038c702589 100755 --- a/components/drivers/clk/clk-scmi.c +++ b/components/drivers/clk/clk-scmi.c @@ -230,7 +230,7 @@ static rt_err_t scmi_clk_probe(struct rt_scmi_device *sdev) for (int id = 0; id < cell_count; ++id) { const char *clk_name; - rt_uint32_t flags, rates_nr, rate_discrete; + rt_uint32_t flags, rate_discrete; in.id = rt_cpu_to_le32(id); in.rate_index = rt_cpu_to_le32(0); @@ -242,7 +242,6 @@ static rt_err_t scmi_clk_probe(struct rt_scmi_device *sdev) } flags = rt_le32_to_cpu(out->num_rates_flags); - rates_nr = SCMI_NUM_REMAINING(flags); rate_discrete = SCMI_RATE_DISCRETE(flags); if (rate_discrete) @@ -263,12 +262,40 @@ static rt_err_t scmi_clk_probe(struct rt_scmi_device *sdev) if (rate_discrete) { - for (int i = 0; i < rates_nr; ++i) + /* + * SCMI: [11:0] = rates in this message, [31:16] = remaining to query. + * Using REMAINING as the copy count overflows rates[] and corrupts heap. + */ + int idx = 0; + + for (;;) { - clk_data->info.list.rates[i] = SCMI_RATE_TO_U64(out->rate[i]); + rt_uint32_t nr = SCMI_NUM_RETURNED(flags); + rt_uint32_t remaining = SCMI_NUM_REMAINING(flags); + + for (rt_uint32_t i = 0; i < nr && idx < SCMI_MAX_NUM_RATES; ++i, ++idx) + { + clk_data->info.list.rates[idx] = SCMI_RATE_TO_U64(out->rate[i]); + } + + if (remaining == 0 || idx >= SCMI_MAX_NUM_RATES) + { + break; + } + + in.rate_index = rt_cpu_to_le32(idx); + msg = RT_SCMI_MSG_RAW(SCMI_CLOCK_DESCRIBE_RATES, &in, sizeof(in), out, out_size); + + if ((err = rt_scmi_process_msg(sclk->sdev, &msg))) + { + rt_free(clk_data); + goto _fail; + } + + flags = rt_le32_to_cpu(out->num_rates_flags); } - clk_data->info.list.rates_nr = rates_nr; + clk_data->info.list.rates_nr = idx; } else { |
