summaryrefslogtreecommitdiffstats
path: root/drivers/clk/keystone
diff options
context:
space:
mode:
authorTero Kristo <t-kristo@ti.com>2020-09-07 11:57:39 +0300
committerStephen Boyd <sboyd@kernel.org>2020-09-22 12:58:43 -0700
commitd3f3f499cb335eba84788a9456f7d6f92a069bbe (patch)
treec26137d678d0cc923706d9c2145c89a6a19d11e3 /drivers/clk/keystone
parent2f05cced7307489faab873367fb20cd212e1d890 (diff)
downloadlinux-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.c14
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);