diff options
Diffstat (limited to 'drivers/clk/keystone')
-rw-r--r-- | drivers/clk/keystone/sci-clk.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c index 2ad26cb927fd..aaf31abe1c8f 100644 --- a/drivers/clk/keystone/sci-clk.c +++ b/drivers/clk/keystone/sci-clk.c @@ -54,6 +54,8 @@ struct sci_clk_provider { * @provider: Master clock provider * @flags: Flags for the clock * @node: Link for handling clocks probed via DT + * @cached_req: Cached requested freq for determine rate calls + * @cached_res: Cached result freq for determine rate calls */ struct sci_clk { struct clk_hw hw; @@ -63,6 +65,8 @@ struct sci_clk { struct sci_clk_provider *provider; u8 flags; struct list_head node; + unsigned long cached_req; + unsigned long cached_res; }; #define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw) @@ -175,6 +179,11 @@ static int sci_clk_determine_rate(struct clk_hw *hw, int ret; u64 new_rate; + if (clk->cached_req && clk->cached_req == req->rate) { + req->rate = clk->cached_res; + return 0; + } + ret = clk->provider->ops->get_best_match_freq(clk->provider->sci, clk->dev_id, clk->clk_id, @@ -189,6 +198,9 @@ static int sci_clk_determine_rate(struct clk_hw *hw, return ret; } + clk->cached_req = req->rate; + clk->cached_res = new_rate; + req->rate = new_rate; return 0; @@ -209,7 +221,8 @@ static int sci_clk_set_rate(struct clk_hw *hw, unsigned long rate, struct sci_clk *clk = to_sci_clk(hw); return clk->provider->ops->set_freq(clk->provider->sci, clk->dev_id, - clk->clk_id, rate, rate, rate); + clk->clk_id, rate / 10 * 9, rate, + rate / 10 * 11); } /** @@ -249,6 +262,8 @@ static int sci_clk_set_parent(struct clk_hw *hw, u8 index) { struct sci_clk *clk = to_sci_clk(hw); + clk->cached_req = 0; + return clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id, clk->clk_id, index + 1 + clk->clk_id); @@ -522,7 +537,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider) np = of_find_node_with_property(np, *clk_name); if (!np) { clk_name++; - break; + continue; } if (!of_device_is_available(np)) |