summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTero Kristo <t-kristo@ti.com>2021-03-23 08:03:55 +0000
committerPraneeth Bajjuri <praneeth@ti.com>2021-03-23 17:18:44 -0500
commit886b07be69a7e27115a6a3789c7afa71bd451104 (patch)
tree2a6acb1ff70882213101238bde35427b1c7623cf
parent153554764b0833505e353be0a68bfcbc327c90ad (diff)
clk: fix set_rate to clean up cached rates for the hierarchy
Clock rates are cached within the individual clock nodes, and right now if one changes a clock rate somewhere in the middle of the tree, none of its child clocks notice the change. To fix this, clear up all the cached rates for us and our child clocks. Signed-off-by: Tero Kristo <t-kristo@ti.com>
-rw-r--r--drivers/clk/clk-uclass.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 8ec44ecada..11c982ca92 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -543,6 +543,22 @@ long long clk_get_parent_rate(struct clk *clk)
return pclk->rate;
}
+static void clk_clean_rate_cache(struct clk *clk)
+{
+ struct udevice *child_dev;
+ struct clk *clkp;
+
+ if (!clk)
+ return;
+
+ clk->rate = 0;
+
+ list_for_each_entry(child_dev, &clk->dev->child_head, sibling_node) {
+ clkp = dev_get_clk_ptr(child_dev);
+ clk_clean_rate_cache(clkp);
+ }
+}
+
ulong clk_set_rate(struct clk *clk, ulong rate)
{
const struct clk_ops *ops;
@@ -555,6 +571,9 @@ ulong clk_set_rate(struct clk *clk, ulong rate)
if (!ops->set_rate)
return -ENOSYS;
+ /* Clean up cached rates for us and all child clocks */
+ clk_clean_rate_cache(clk);
+
return ops->set_rate(clk, rate);
}