summaryrefslogtreecommitdiffstats
path: root/drivers/clk/clk.c
diff options
context:
space:
mode:
authorMaxime Ripard <maxime@cerno.tech>2022-08-16 13:25:17 +0200
committerStephen Boyd <sboyd@kernel.org>2022-09-15 18:31:05 +0200
commit3afb07231d603d51dca6a5d5e16d9d8f422f9b5f (patch)
tree3432f40470f753ff7a1383379902168e5b4fc881 /drivers/clk/clk.c
parentclk: tests: Add some tests for orphan with multiple parents (diff)
downloadlinux-3afb07231d603d51dca6a5d5e16d9d8f422f9b5f.tar.xz
linux-3afb07231d603d51dca6a5d5e16d9d8f422f9b5f.zip
clk: Take into account uncached clocks in clk_set_rate_range()
clk_set_rate_range() will use the last requested rate for the clock when it calls into the driver set_rate hook. However, if CLK_GET_RATE_NOCACHE is set on that clock, the last requested rate might not be matching the current rate of the clock. In such a case, let's read out the rate from the hardware and use that in our set_rate instead. Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com> # imx8mp Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> # exynos4210, meson g12b Signed-off-by: Maxime Ripard <maxime@cerno.tech> Link: https://lore.kernel.org/r/20220816112530.1837489-13-maxime@cerno.tech Tested-by: Linux Kernel Functional Testing <lkft@linaro.org> Tested-by: Naresh Kamboju <naresh.kamboju@linaro.org> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Diffstat (limited to 'drivers/clk/clk.c')
-rw-r--r--drivers/clk/clk.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index caa2eb640441..53b28e63deae 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -2373,6 +2373,10 @@ static int clk_set_rate_range_nolock(struct clk *clk,
goto out;
}
+ rate = clk->core->req_rate;
+ if (clk->core->flags & CLK_GET_RATE_NOCACHE)
+ rate = clk_core_get_rate_recalc(clk->core);
+
/*
* Since the boundaries have been changed, let's give the
* opportunity to the provider to adjust the clock rate based on
@@ -2390,7 +2394,7 @@ static int clk_set_rate_range_nolock(struct clk *clk,
* - the determine_rate() callback does not really check for
* this corner case when determining the rate
*/
- rate = clamp(clk->core->req_rate, min, max);
+ rate = clamp(rate, min, max);
ret = clk_core_set_rate_nolock(clk->core, rate);
if (ret) {
/* rollback the changes */