@@ -170,18 +170,30 @@ static int rockchip_mmc_clk_rate_notify(struct notifier_block *nb,
unsigned long event, void *data)
{
struct rockchip_mmc_clock *mmc_clock = to_rockchip_mmc_clock(nb);
+ struct clk_notifier_data *ndata = data;
/*
* rockchip_mmc_clk is mostly used by mmc controllers to sample
* the intput data, which expects the fixed phase after the tuning
* process. However if the clock rate is changed, the phase is stale
* and may break the data sampling. So here we try to restore the phase
- * for that case.
+ * for that case, except that
+ * (1) cached_phase is invaild since we inevitably cached it when the
+ * clock provider be reparented from orphan to its real parent in the
+ * first place. Otherwise we may mess up the initialization of MMC cards
+ * since we only set the default sample phase and drive phase later on.
+ * (2) the new coming rate is higher than the older one since mmc driver
+ * set the max-frequency to match the boards' ability but we can't go
+ * over the heads of that, otherwise the tests smoke out the issue.
*/
+ if (ndata->old_rate <= ndata->new_rate)
+ return NOTIFY_DONE;
+
if (event == PRE_RATE_CHANGE)
mmc_clock->cached_phase =
rockchip_mmc_get_phase(&mmc_clock->hw);
- else if (event == POST_RATE_CHANGE)
+ else if (mmc_clock->cached_phase != -EINVAL &&
+ event == POST_RATE_CHANGE)
rockchip_mmc_set_phase(&mmc_clock->hw, mmc_clock->cached_phase);
return NOTIFY_DONE;
@@ -211,8 +223,10 @@ struct clk *rockchip_clk_register_mmc(const char *name,
mmc_clock->shift = shift;
clk = clk_register(NULL, &mmc_clock->hw);
- if (IS_ERR(clk))
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
goto err_register;
+ }
mmc_clock->clk_rate_change_nb.notifier_call =
&rockchip_mmc_clk_rate_notify;
@@ -225,5 +239,5 @@ struct clk *rockchip_clk_register_mmc(const char *name,
clk_unregister(clk);
err_register:
kfree(mmc_clock);
- return clk;
+ return ERR_PTR(ret);
}