]> git.karo-electronics.de Git - linux-beck.git/commitdiff
mmc: mmc: Relax checking for switch errors after HS200 switch
authorAdrian Hunter <adrian.hunter@intel.com>
Fri, 2 Dec 2016 11:16:35 +0000 (13:16 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Mon, 5 Dec 2016 13:15:46 +0000 (14:15 +0100)
The JEDEC specification indicates CMD13 can be used after a HS200 switch
to check for errors. However in practice some boards experience CRC errors
in the CMD13 response. Consequently, for HS200, CRC errors are not a
reliable way to know the switch failed. If there really is a problem, we
would expect tuning will fail and the result ends up the same. So change
the error condition to ignore CRC errors in that case.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Acked-by: Jaehoon Chung <jh80.chung@samsung.com>
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/core/mmc.c
drivers/mmc/core/mmc_ops.c
drivers/mmc/core/mmc_ops.h

index 033e00abe93fc8ad40bb99a8609f69cddfc9a24c..b61b52f9da3d88bc1903e14ffc56dd276700c814 100644 (file)
@@ -1240,7 +1240,12 @@ int mmc_hs400_to_hs200(struct mmc_card *card)
 
        mmc_set_timing(host, MMC_TIMING_MMC_HS200);
 
-       err = mmc_switch_status(card);
+       /*
+        * For HS200, CRC errors are not a reliable way to know the switch
+        * failed. If there really is a problem, we would expect tuning will
+        * fail and the result ends up the same.
+        */
+       err = __mmc_switch_status(card, false);
        if (err)
                goto out_err;
 
@@ -1403,7 +1408,13 @@ static int mmc_select_hs200(struct mmc_card *card)
                old_timing = host->ios.timing;
                mmc_set_timing(host, MMC_TIMING_MMC_HS200);
 
-               err = mmc_switch_status(card);
+               /*
+                * For HS200, CRC errors are not a reliable way to know the
+                * switch failed. If there really is a problem, we would expect
+                * tuning will fail and the result ends up the same.
+                */
+               err = __mmc_switch_status(card, false);
+
                /*
                 * mmc_select_timing() assumes timing has not changed if
                 * it is a switch error.
index cb7006feb5c449569e6c055dce7abcb0ba02d3d3..81ce63bb07735953787b24ae4d590e8c0c271acd 100644 (file)
@@ -431,18 +431,25 @@ static int mmc_switch_status_error(struct mmc_host *host, u32 status)
 }
 
 /* Caller must hold re-tuning */
-int mmc_switch_status(struct mmc_card *card)
+int __mmc_switch_status(struct mmc_card *card, bool crc_err_fatal)
 {
        u32 status;
        int err;
 
        err = mmc_send_status(card, &status);
+       if (!crc_err_fatal && err == -EILSEQ)
+               return 0;
        if (err)
                return err;
 
        return mmc_switch_status_error(card->host, status);
 }
 
+int mmc_switch_status(struct mmc_card *card)
+{
+       return __mmc_switch_status(card, true);
+}
+
 static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
                        bool send_status, bool retry_crc_err)
 {
index 761cb69c46afeab63af9706ab030f4901c722b5b..abd525ed74be37b4fb3d1a4bdfeb770f835061f4 100644 (file)
@@ -28,6 +28,7 @@ int mmc_bus_test(struct mmc_card *card, u8 bus_width);
 int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status);
 int mmc_can_ext_csd(struct mmc_card *card);
 int mmc_switch_status(struct mmc_card *card);
+int __mmc_switch_status(struct mmc_card *card, bool crc_err_fatal);
 int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
                unsigned int timeout_ms, unsigned char timing,
                bool use_busy_signal, bool send_status, bool retry_crc_err);