Merge tag 'mac80211-for-davem-2018-05-09' of git://git.kernel.org/pub/scm/linux/kerne...
[sfrench/cifs-2.6.git] / drivers / clk / rockchip / clk-mmc-phase.c
index dc4c227732bd9f06de5394785b537d69f386dde9..026a26bb702d9b9f6ab53a6ffaa8864149dfc01b 100644 (file)
@@ -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 @@ err_notifier:
        clk_unregister(clk);
 err_register:
        kfree(mmc_clock);
-       return clk;
+       return ERR_PTR(ret);
 }