summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Lin <shawn.lin@rock-chips.com>2018-03-14 08:28:31 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-05-30 07:49:11 +0200
commit9c43286998a2d5e26da0414e92958819790db4de (patch)
treeac1a3e95a55588a6f3b710f4d2ca15335aa9421c
parent1177eca04218d40af78edeae87f54a9a8f76bec0 (diff)
clk: Don't show the incorrect clock phase
[ Upstream commit 1f9c63e8de3d7b377c9d74e4a17524cfb60e6384 ] It's found that the clock phase output from clk_summary is wrong compared to the actual phase reading from the register. cat /sys/kernel/debug/clk/clk_summary | grep sdio_sample sdio_sample 0 1 0 50000000 0 -22 It exposes an issue that clk core, clk_core_get_phase, always returns the cached core->phase which should be either updated by calling clk_set_phase or directly from the first place the clk was registered. When registering the clk, the core->phase geting from ->get_phase() may return negative value indicating error. This is quite common since the clk's phase may be highly related to its parent chain, but it was temporarily orphan when registered, since its parent chains hadn't be ready at that time, so the clk drivers decide to return error in this case. However, if no clk_set_phase is called or maybe the ->set_phase() isn't even implemented, the core->phase would never be updated. This is wrong, and we should try to update it when all its parent chains are settled down, like the way of updating clock rate for that. But it's not deserved to complicate the code now and just update it anyway when calling clk_core_get_phase, which would be much simple and enough. Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com> Acked-by: Jerome Brunet <jbrunet@baylibre.com> Signed-off-by: Stephen Boyd <sboyd@kernel.org> Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/clk/clk.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index f13c3f4228d4..53c068f90b37 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1905,6 +1905,9 @@ static int clk_core_get_phase(struct clk_core *core)
int ret;
clk_prepare_lock();
+ /* Always try to update cached phase if possible */
+ if (core->ops->get_phase)
+ core->phase = core->ops->get_phase(core->hw);
ret = core->phase;
clk_prepare_unlock();