mmc: sdhci-esdhc-imx: Correct two register accesses
authorAaron Brice <aaron.brice@datasoft.com>
Mon, 10 Oct 2016 18:39:52 +0000 (11:39 -0700)
committerUlf Hansson <ulf.hansson@linaro.org>
Thu, 13 Oct 2016 06:58:03 +0000 (08:58 +0200)
- The DMA error interrupt bit is in a different position as
   compared to the sdhci standard.  This is accounted for in
   many cases, but not handled in the case of clearing the
   INT_STATUS register by writing a 1 to that location.
 - The HOST_CONTROL register is very different as compared to
   the sdhci standard.  This is accounted for in the write
   case, but not when read back out (which it is in the sdhci
   code).

Signed-off-by: Dave Russell <david.russell@datasoft.com>
Signed-off-by: Aaron Brice <aaron.brice@datasoft.com>
Acked-by: Dong Aisheng <aisheng.dong@nxp.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/host/sdhci-esdhc-imx.c

index 1f54fd8755c8e026fd8fb99f7fdb1cbc154acc87..7123ef96ed18523c88553146035103f3517bd372 100644 (file)
@@ -346,7 +346,8 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
        struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
        u32 data;
 
-       if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)) {
+       if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE ||
+                       reg == SDHCI_INT_STATUS)) {
                if ((val & SDHCI_INT_CARD_INT) && !esdhc_is_usdhc(imx_data)) {
                        /*
                         * Clear and then set D3CD bit to avoid missing the
@@ -555,6 +556,25 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
        esdhc_clrset_le(host, 0xffff, val, reg);
 }
 
+static u8 esdhc_readb_le(struct sdhci_host *host, int reg)
+{
+       u8 ret;
+       u32 val;
+
+       switch (reg) {
+       case SDHCI_HOST_CONTROL:
+               val = readl(host->ioaddr + reg);
+
+               ret = val & SDHCI_CTRL_LED;
+               ret |= (val >> 5) & SDHCI_CTRL_DMA_MASK;
+               ret |= (val & ESDHC_CTRL_4BITBUS);
+               ret |= (val & ESDHC_CTRL_8BITBUS) << 3;
+               return ret;
+       }
+
+       return readb(host->ioaddr + reg);
+}
+
 static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg)
 {
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -947,6 +967,7 @@ static void esdhc_set_timeout(struct sdhci_host *host, struct mmc_command *cmd)
 static struct sdhci_ops sdhci_esdhc_ops = {
        .read_l = esdhc_readl_le,
        .read_w = esdhc_readw_le,
+       .read_b = esdhc_readb_le,
        .write_l = esdhc_writel_le,
        .write_w = esdhc_writew_le,
        .write_b = esdhc_writeb_le,