Re: [PATCH] mmc: sdhci-of-esdhc: fixup PRESENT_STATE read

From: Michael Walle
Date: Fri Nov 11 2016 - 08:26:16 EST


Am 2016-11-11 14:15, schrieb Adrian Hunter:
On 10/11/16 18:47, Michael Walle wrote:
Since commit 87a18a6a5652 ("mmc: mmc: Use ->card_busy() to detect busy
cards in __mmc_switch()") the ESDHC driver is broken:
mmc0: Card stuck in programming state! __mmc_switch
mmc0: error -110 whilst initialising MMC card

Since this commit __mmc_switch() uses ->card_busy(), which is
sdhci_card_busy() for the esdhc driver. sdhci_card_busy() uses the
PRESENT_STATE register, specifically the DAT0 signal level bit. But the
ESDHC uses a non-conformant PRESENT_STATE register, thus a read fixup is
required to make the driver work again.

Signed-off-by: Michael Walle <michael@xxxxxxxx>

Could add a Fixes tag here.

ah, right, will do :)


---
drivers/mmc/host/sdhci-of-esdhc.c | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index fb71c86..243fee9 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -66,6 +66,18 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host,
return ret;
}
}
+ /*
+ * The DAT[3:0] line signal levels and the CMD line signal level is
+ * not compatible with standard SDHC reegister. Move the corresponding

reegister -> register
ok


+ * bits around.
+ */
+ if (spec_reg == SDHCI_PRESENT_STATE) {
+ ret = value & 0xf8000000;
+ ret |= (value >> 4) & SDHCI_DATA_LVL_MASK;
+ ret |= (value << 1) & 0x01000000;
+ return ret;

SDHCI also uses other bits in SDHCI_PRESENT_STATE like SDHCI_CMD_INHIBIT and
SDHCI_DATA_INHIBIT etc, but this looks like all those bits will be zero. Is
that right?

ugh, thanks for spotting that. actually all lower bits should be taken from the original value. Therefore the first statement should be
ret = value & ~0xf8000000;

Will post a v2 soon.

-michael