Skip to content

Commit 965e063

Browse files
MrVanbebarino
authored andcommitted
clk: clk-conf: support assigned-clock-rates-u64
i.MX95 System Management Control Firmware(SCMI) manages the clock function, it exposes PLL VCO which could support up to 5GHz rate that exceeds UINT32_MAX. So add assigned-clock-rates-u64 support to set rate that exceeds UINT32_MAX. Signed-off-by: Peng Fan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Stephen Boyd <[email protected]>
1 parent 8400291 commit 965e063

File tree

1 file changed

+38
-5
lines changed

1 file changed

+38
-5
lines changed

drivers/clk/clk-conf.c

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/device.h>
1111
#include <linux/of.h>
1212
#include <linux/printk.h>
13+
#include <linux/slab.h>
1314

1415
static int __set_clk_parents(struct device_node *node, bool clk_supplier)
1516
{
@@ -81,11 +82,44 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier)
8182
static int __set_clk_rates(struct device_node *node, bool clk_supplier)
8283
{
8384
struct of_phandle_args clkspec;
84-
int rc, index = 0;
85+
int rc, count, count_64, index;
8586
struct clk *clk;
86-
u32 rate;
87+
u64 *rates_64 __free(kfree) = NULL;
88+
u32 *rates __free(kfree) = NULL;
89+
90+
count = of_property_count_u32_elems(node, "assigned-clock-rates");
91+
count_64 = of_property_count_u64_elems(node, "assigned-clock-rates-u64");
92+
if (count_64 > 0) {
93+
count = count_64;
94+
rates_64 = kcalloc(count, sizeof(*rates_64), GFP_KERNEL);
95+
if (!rates_64)
96+
return -ENOMEM;
97+
98+
rc = of_property_read_u64_array(node,
99+
"assigned-clock-rates-u64",
100+
rates_64, count);
101+
} else if (count > 0) {
102+
rates = kcalloc(count, sizeof(*rates), GFP_KERNEL);
103+
if (!rates)
104+
return -ENOMEM;
105+
106+
rc = of_property_read_u32_array(node, "assigned-clock-rates",
107+
rates, count);
108+
} else {
109+
return 0;
110+
}
111+
112+
if (rc)
113+
return rc;
114+
115+
for (index = 0; index < count; index++) {
116+
unsigned long rate;
117+
118+
if (rates_64)
119+
rate = rates_64[index];
120+
else
121+
rate = rates[index];
87122

88-
of_property_for_each_u32(node, "assigned-clock-rates", rate) {
89123
if (rate) {
90124
rc = of_parse_phandle_with_args(node, "assigned-clocks",
91125
"#clock-cells", index, &clkspec);
@@ -112,12 +146,11 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
112146

113147
rc = clk_set_rate(clk, rate);
114148
if (rc < 0)
115-
pr_err("clk: couldn't set %s clk rate to %u (%d), current rate: %lu\n",
149+
pr_err("clk: couldn't set %s clk rate to %lu (%d), current rate: %lu\n",
116150
__clk_get_name(clk), rate, rc,
117151
clk_get_rate(clk));
118152
clk_put(clk);
119153
}
120-
index++;
121154
}
122155
return 0;
123156
}

0 commit comments

Comments
 (0)