summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorJacob Chen <jacob2.chen@rock-chips.com>2016-09-19 02:16:50 (GMT)
committerJaehoon Chung <jh80.chung@samsung.com>2016-09-21 07:00:14 (GMT)
commit2b42903397b4d6b68fe2af95565a8953b08ab96e (patch)
tree549ee71317f8bbeccf207f95ddc03489ababd6a6 /drivers/mmc
parent6dffdbc3a5911e768be21850a612bfb4871a23ef (diff)
downloadu-boot-fsl-qoriq-2b42903397b4d6b68fe2af95565a8953b08ab96e.tar.xz
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 <jacob2.chen@rock-chips.com> Signed-off-by: Ziyuan Xu <xzy.xu@rock-chips.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/dw_mmc.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index afc674d..074f86c 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. */