Skip to contentSkip to conversation

mmc: sdhci: add the quirk for broken r1b response

PATCH Superseded Jaehoon Chung 1 participant 1 message Apr 10, 2012 MMC, SD and SDIO

v4 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

PATCH v4 1/4 mmc: sdhci: add the quirk for broken r1b response

When response type is R1b, mask value is added the SDHCI_INT_DAT_END. but in while(), didn't check that flag.
So sdhci controller didn't work fine.
CMD6 didn't always complete.

So add the quirks for broken r1b response
and add the timeout value to prevent the infinite loop.

---
 drivers/mmc/sdhci.c |   12 ++++++++++++
 include/sdhci.h     |    1 +
 2 files changed, 13 insertions(+), 0 deletions(-)
drivers/mmc/sdhci.c +12 -0
index fc904b5..4de19e8 100644
@@ -128,6 +128,7 @@ int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
 	int trans_bytes = 0, is_aligned = 1;
 	u32 mask, flags, mode;
 	unsigned int timeout, start_addr = 0;
+	unsigned int retry = 1000;
 
 	/* Wait max 10 ms */
 	timeout = 10;
@@ -210,8 +211,19 @@ int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
 		stat = sdhci_readl(host, SDHCI_INT_STATUS);
 		if (stat & SDHCI_INT_ERROR)
 			break;
+		if (retry-- == 0)
+			break;
 	} while ((stat & mask) != mask);
 
+	if (retry == 0) {
+		if (host->quirks == SDHCI_QUIRK_BROKEN_R1B)
+			return 0;
+		else {
+			printf("Timeout for stauts update!\n");
+			return TIMEOUT;
+		}
+	}
+
 	if ((stat & (SDHCI_INT_ERROR | mask)) == mask) {
 		sdhci_cmd_done(host, cmd);
 		sdhci_writel(host, mask, SDHCI_INT_STATUS);
include/sdhci.h +1 -0
index 800f9d9..a2415ba 100644
@@ -216,6 +216,7 @@
  */
 #define SDHCI_QUIRK_32BIT_DMA_ADDR	(1 << 0)
 #define SDHCI_QUIRK_REG32_RW		(1 << 1)
+#define SDHCI_QUIRK_BROKEN_R1B		(1 << 2)
 
 /* to make gcc happy */
 struct sdhci_host;