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.y...@rock-chips.com>
---

 drivers/clk/clk-conf.c | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c
index aad4796..0c9df48 100644
--- a/drivers/clk/clk-conf.c
+++ b/drivers/clk/clk-conf.c
@@ -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",
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to