@@ -84,7 +84,7 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
struct clk *clk;
u32 rate;
- of_property_for_each_u32(node, "assigned-clock-rates", prop, cur, rate) {
+ of_property_for_each_u32(node, "assigned-force-rates", prop, cur, rate) {
if (rate) {
rc = of_parse_phandle_with_args(node, "assigned-clocks",
"#clock-cells", index, &clkspec);
@@ -104,7 +104,38 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
index, node->full_name);
return PTR_ERR(clk);
}
+ /* change the old rate to 0 to make sure we can get into
+ * clk_change_rate */
+ clk->rate = 0;
+ rc = clk_set_rate(clk, rate);
+ if (rc < 0)
+ pr_err("clk: couldn't set %s clock rate: %d\n",
+ __clk_get_name(clk), rc);
+ clk_put(clk);
+ }
+ index++;
+ }
+ of_property_for_each_u32(node, "assigned-clock-rates", prop, cur, rate) {
+ if (rate) {
+ rc = of_parse_phandle_with_args(node, "assigned-clocks",
+ "#clock-cells", index, &clkspec);
+ if (rc < 0) {
+ /* skip empty (null) phandles */
+ if (rc == -ENOENT)
+ continue;
+ else
+ return rc;
+ }
+ if (clkspec.np == node && !clk_supplier)
+ return 0;
+
+ clk = of_clk_get_by_clkspec(&clkspec);
+ if (IS_ERR(clk)) {
+ pr_warn("clk: couldn't get clock %d for %s\n",
+ index, node->full_name);
+ return PTR_ERR(clk);
+ }
rc = clk_set_rate(clk, rate);
if (rc < 0)
pr_err("clk: couldn't set %s clock rate: %d\n",
Usually we assigned a clock to a default rate in dts, there is a situation that the clock already initialized to the rate we intend to set before kernel(hardware default or init in uboot etc). For the PLLs we can get a rate from different PLL parameter configure, we can't change the PLL parameter if the rate is not changed by now. This patch adds a option property 'assigned-clock-force-rates' to make sure we update all the setting even if we don't need to update the clock rate. Signed-off-by: Kever Yang <kever.yang@rock-chips.com> --- drivers/clk/clk-conf.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-)