From 6e83e10d92e12fa0181766a1fbb00d857bfab779 Mon Sep 17 00:00:00 2001 From: Seungwon Jeon Date: Mon, 20 Jun 2011 17:24:16 +0900 Subject: [PATCH] mmc: dw_mmc: protect a sequence of request and request-done. Response timeout (RTO), Response crc error (RCRC) and Response error (RE) signals come with command done (CD) and can be raised preceding command done (CD). That is these error interrupts and CD can be handled in separate dw_mci_interrupt(). If mmc_request_done() is called because of a response timeout before command done has occured, we might send the next request before the CD of current request is finished. This can bring about a broken sequence of request and request-done. And Data error interrupt (DRTO, DCRC, SBE, EBE) and data transfer over (DTO) have the same problem. Signed-off-by: Seungwon Jeon Acked-by: Will Newton Signed-off-by: Chris Ball --- drivers/mmc/host/dw_mmc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 1ca830c171fd..22be372cae7d 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1202,7 +1202,6 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) host->cmd_status = status; smp_wmb(); set_bit(EVENT_CMD_COMPLETE, &host->pending_events); - tasklet_schedule(&host->tasklet); } if (pending & DW_MCI_DATA_ERROR_FLAGS) { @@ -1211,7 +1210,9 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) host->data_status = status; smp_wmb(); set_bit(EVENT_DATA_ERROR, &host->pending_events); - tasklet_schedule(&host->tasklet); + if (!(pending & (SDMMC_INT_DTO | SDMMC_INT_DCRC | + SDMMC_INT_SBE | SDMMC_INT_EBE))) + tasklet_schedule(&host->tasklet); } if (pending & SDMMC_INT_DATA_OVER) { -- 2.39.2