mmc: add additional quirk for APP_CMD retry
authorJoel Johnson <mrjoel@lixil.net>
Sat, 11 Jan 2020 16:08:14 +0000 (09:08 -0700)
committerPeng Fan <peng.fan@nxp.com>
Thu, 16 Jan 2020 05:21:01 +0000 (13:21 +0800)
It was observed (on ClearFog Base) that sending MMC APP_CMD returned
an error on the first attempt. The issue appears to be timing related
since even inserting a puts() short debug entry before the execution
added sufficient delay to receive success on first attempt.

Follow the existing quirks pattern to retry if initial issuance
failed so as to not introduce any delay unless needed.

Signed-off-by: Joel Johnson <mrjoel@lixil.net>
drivers/mmc/mmc.c
include/mmc.h

index f683b52eada39eabf3f3adbc2bfbadc9135d2f78..d43983d4a648213b6d985a285029c50557cfecd8 100644 (file)
@@ -1444,6 +1444,20 @@ static int sd_read_ssr(struct mmc *mmc)
        cmd.cmdarg = mmc->rca << 16;
 
        err = mmc_send_cmd(mmc, &cmd, NULL);
+#ifdef CONFIG_MMC_QUIRKS
+       if (err && (mmc->quirks & MMC_QUIRK_RETRY_APP_CMD)) {
+               int retries = 4;
+               /*
+                * It has been seen that APP_CMD may fail on the first
+                * attempt, let's try a few more times
+                */
+               do {
+                       err = mmc_send_cmd(mmc, &cmd, NULL);
+                       if (!err)
+                               break;
+               } while (retries--);
+       }
+#endif
        if (err)
                return err;
 
@@ -2755,7 +2769,8 @@ int mmc_get_op_cond(struct mmc *mmc)
 
 #ifdef CONFIG_MMC_QUIRKS
        mmc->quirks = MMC_QUIRK_RETRY_SET_BLOCKLEN |
-                     MMC_QUIRK_RETRY_SEND_CID;
+                     MMC_QUIRK_RETRY_SEND_CID |
+                     MMC_QUIRK_RETRY_APP_CMD;
 #endif
 
        err = mmc_power_cycle(mmc);
index 1a9efe4c3843efdfcaaa5926d27a417401733ecb..b5cb514f57d6c12f525148f45cd19d74468eb650 100644 (file)
@@ -331,6 +331,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
 
 #define MMC_QUIRK_RETRY_SEND_CID       BIT(0)
 #define MMC_QUIRK_RETRY_SET_BLOCKLEN   BIT(1)
+#define MMC_QUIRK_RETRY_APP_CMD        BIT(2)
 
 enum mmc_voltage {
        MMC_SIGNAL_VOLTAGE_000 = 0,