Unconditionally clearing DTO when RXDR is set leads to spurious timeouts
in FIFO mode transfers if events occur in the following order:

        mask = dwmci_readl(host, DWMCI_RINTSTS);

        // Hardware asserts DWMCI_INTMSK_DTO here

        dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_DTO);

        if (mask & DWMCI_INTMSK_DTO) {
                // Unreachable as DTO is cleared without being handled!
                return 0;
        }

Only clear interrupts that we have seen and are handling so that DTO is
not missed.

Signed-off-by: John Keeping <j...@metanate.com>
---
 drivers/mmc/dw_mmc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 4232c5eb8c..5085a3b491 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -168,7 +168,8 @@ static int dwmci_data_transfer(struct dwmci_host *host, 
struct mmc_data *data)
                        if (data->flags == MMC_DATA_READ &&
                            (mask & (DWMCI_INTMSK_RXDR | DWMCI_INTMSK_DTO))) {
                                dwmci_writel(host, DWMCI_RINTSTS,
-                                            DWMCI_INTMSK_RXDR | 
DWMCI_INTMSK_DTO);
+                                            mask & (DWMCI_INTMSK_RXDR |
+                                                    DWMCI_INTMSK_DTO));
                                while (size) {
                                        ret = dwmci_fifo_ready(host,
                                                        DWMCI_FIFO_EMPTY,
-- 
2.37.3

Reply via email to