aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Lin <shawn.lin@rock-chips.com>2018-03-20 22:39:20 -0400
committerHeiko Stuebner <heiko@sntech.de>2018-03-23 04:02:58 -0400
commit570fda972b3178f9a981d1b7ac18e05245a52eab (patch)
treec00a3df5d82d90834f68d615b1fa98fccced849b
parentce84eca927af24ca27897ba5fee4fbeed443d5fc (diff)
clk: rockchip: Correct the behaviour of restoring cached phase
We can't restore every phase, for instance the invalid phase and the phase for coming rate which is out of the scope of boards' ability. And this patch also corrects the error path to return invalid pointer to clk if clk_notifier_register failed introduced by the same offending commit. Fixes: 60cf09e45fbc ("clk: rockchip: Restore the clock phase after the rate was changed") Reported-by: wlq <wlq@rock-chips.com> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com> Tested-by: wlq <wlq@rock-chips.com> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
-rw-r--r--drivers/clk/rockchip/clk-mmc-phase.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
index dc4c227732bd..b7b9f2e7d64b 100644
--- a/drivers/clk/rockchip/clk-mmc-phase.c
+++ b/drivers/clk/rockchip/clk-mmc-phase.c
@@ -170,18 +170,30 @@ static int rockchip_mmc_clk_rate_notify(struct notifier_block *nb,
170 unsigned long event, void *data) 170 unsigned long event, void *data)
171{ 171{
172 struct rockchip_mmc_clock *mmc_clock = to_rockchip_mmc_clock(nb); 172 struct rockchip_mmc_clock *mmc_clock = to_rockchip_mmc_clock(nb);
173 struct clk_notifier_data *ndata = data;
173 174
174 /* 175 /*
175 * rockchip_mmc_clk is mostly used by mmc controllers to sample 176 * rockchip_mmc_clk is mostly used by mmc controllers to sample
176 * the intput data, which expects the fixed phase after the tuning 177 * the intput data, which expects the fixed phase after the tuning
177 * process. However if the clock rate is changed, the phase is stale 178 * process. However if the clock rate is changed, the phase is stale
178 * and may break the data sampling. So here we try to restore the phase 179 * and may break the data sampling. So here we try to restore the phase
179 * for that case. 180 * for that case, except that
181 * (1) cached_phase is invaild since we inevitably cached it when the
182 * clock provider be reparented from orphan to its real parent in the
183 * first place. Otherwise we may mess up the initialization of MMC cards
184 * since we only set the default sample phase and drive phase later on.
185 * (2) the new coming rate is higher than the older one since mmc driver
186 * set the max-frequency to match the boards' ability but we can't go
187 * over the heads of that, otherwise the tests smoke out the issue.
180 */ 188 */
189 if (ndata->old_rate <= ndata->new_rate)
190 return NOTIFY_DONE;
191
181 if (event == PRE_RATE_CHANGE) 192 if (event == PRE_RATE_CHANGE)
182 mmc_clock->cached_phase = 193 mmc_clock->cached_phase =
183 rockchip_mmc_get_phase(&mmc_clock->hw); 194 rockchip_mmc_get_phase(&mmc_clock->hw);
184 else if (event == POST_RATE_CHANGE) 195 else if (mmc_clock->cached_phase != -EINVAL &&
196 event == POST_RATE_CHANGE)
185 rockchip_mmc_set_phase(&mmc_clock->hw, mmc_clock->cached_phase); 197 rockchip_mmc_set_phase(&mmc_clock->hw, mmc_clock->cached_phase);
186 198
187 return NOTIFY_DONE; 199 return NOTIFY_DONE;