diff options
author | Tero Kristo <t-kristo@ti.com> | 2020-09-07 11:57:39 +0300 |
---|---|---|
committer | Stephen Boyd <sboyd@kernel.org> | 2020-09-22 12:58:43 -0700 |
commit | d3f3f499cb335eba84788a9456f7d6f92a069bbe (patch) | |
tree | c26137d678d0cc923706d9c2145c89a6a19d11e3 /drivers/clk/keystone | |
parent | 2f05cced7307489faab873367fb20cd212e1d890 (diff) | |
download | linux-stable-d3f3f499cb335eba84788a9456f7d6f92a069bbe.tar.gz linux-stable-d3f3f499cb335eba84788a9456f7d6f92a069bbe.tar.bz2 linux-stable-d3f3f499cb335eba84788a9456f7d6f92a069bbe.zip |
clk: keystone: sci-clk: cache results of last query rate operation
Cache results of the latest query rate operation. This optimizes the
firmware interface a bit, avoiding unnecessary calls to firmware if we
know the result already; the firmware interface is pretty expensive
to use for query rate functionality.
Signed-off-by: Tero Kristo <t-kristo@ti.com>
Link: https://lore.kernel.org/r/20200907085740.1083-3-t-kristo@ti.com
Acked-by: Santosh Shilimkar <ssantosh@kernel.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Diffstat (limited to 'drivers/clk/keystone')
-rw-r--r-- | drivers/clk/keystone/sci-clk.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c index f126b6045afa..b6477b08af04 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; @@ -249,6 +261,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); |