From: Jacob Chen Date: Mon, 19 Sep 2016 02:16:50 +0000 (+0800) Subject: mmc: dw_mmc: push/pop all FIFO data if any data request X-Git-Tag: v2016.11-rc1~121^2 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=2b42903397b4d6b68fe2af95565a8953b08ab96e;p=u-boot mmc: dw_mmc: push/pop all FIFO data if any data request When DTO interrupt occurred, there are any remaining data still in FIFO due to RX FIFO threshold is larger than remaining data. It also causes that dwmmc didn't trigger RXDR interrupt, so is TX. It's responsibility of driver to read remaining bytes on seeing DTO interrupt. Signed-off-by: Jacob Chen Signed-off-by: Ziyuan Xu --- diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index afc674dd14..074f86c502 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -120,9 +120,9 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) if (host->fifo_mode && size) { len = 0; - if (data->flags == MMC_DATA_READ) { - if ((dwmci_readl(host, DWMCI_RINTSTS) & - DWMCI_INTMSK_RXDR)) { + if (data->flags == MMC_DATA_READ && + (mask & DWMCI_INTMSK_RXDR)) { + while (size) { len = dwmci_readl(host, DWMCI_STATUS); len = (len >> DWMCI_FIFO_SHIFT) & DWMCI_FIFO_MASK; @@ -130,12 +130,13 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) for (i = 0; i < len; i++) *buf++ = dwmci_readl(host, DWMCI_DATA); - dwmci_writel(host, DWMCI_RINTSTS, - DWMCI_INTMSK_RXDR); + size = size > len ? (size - len) : 0; } - } else { - if ((dwmci_readl(host, DWMCI_RINTSTS) & - DWMCI_INTMSK_TXDR)) { + dwmci_writel(host, DWMCI_RINTSTS, + DWMCI_INTMSK_RXDR); + } else if (data->flags == MMC_DATA_WRITE && + (mask & DWMCI_INTMSK_TXDR)) { + while (size) { len = dwmci_readl(host, DWMCI_STATUS); len = fifo_depth - ((len >> DWMCI_FIFO_SHIFT) & @@ -144,11 +145,11 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) for (i = 0; i < len; i++) dwmci_writel(host, DWMCI_DATA, *buf++); - dwmci_writel(host, DWMCI_RINTSTS, - DWMCI_INTMSK_TXDR); + size = size > len ? (size - len) : 0; } + dwmci_writel(host, DWMCI_RINTSTS, + DWMCI_INTMSK_TXDR); } - size = size > len ? (size - len) : 0; } /* Data arrived correctly. */