]> git.karo-electronics.de Git - linux-beck.git/commitdiff
mmc: dw_mmc: protect a sequence of request and request-done.
authorSeungwon Jeon <tgih.jun@samsung.com>
Mon, 20 Jun 2011 08:24:16 +0000 (17:24 +0900)
committerChris Ball <cjb@laptop.org>
Wed, 20 Jul 2011 21:20:53 +0000 (17:20 -0400)
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 <tgih.jun@samsung.com>
Acked-by: Will Newton <will.newton@imgtec.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
drivers/mmc/host/dw_mmc.c

index 1ca830c171fde45111923f4cfe3207c68d09ec87..22be372cae7d3f072c214093ae4a955c5aa760d5 100644 (file)
@@ -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) {