aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSeungwon Jeon <tgih.jun@samsung.com>2011-06-20 04:24:16 -0400
committerChris Ball <cjb@laptop.org>2011-07-20 17:20:53 -0400
commit6e83e10d92e12fa0181766a1fbb00d857bfab779 (patch)
tree9a6a19212477dc7f5a82ca6ecb9bbbb8238ec005
parent1d56c453b14854637567c838109127b8decbf328 (diff)
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 <tgih.jun@samsung.com> Acked-by: Will Newton <will.newton@imgtec.com> Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r--drivers/mmc/host/dw_mmc.c5
1 files 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)
1202 host->cmd_status = status; 1202 host->cmd_status = status;
1203 smp_wmb(); 1203 smp_wmb();
1204 set_bit(EVENT_CMD_COMPLETE, &host->pending_events); 1204 set_bit(EVENT_CMD_COMPLETE, &host->pending_events);
1205 tasklet_schedule(&host->tasklet);
1206 } 1205 }
1207 1206
1208 if (pending & DW_MCI_DATA_ERROR_FLAGS) { 1207 if (pending & DW_MCI_DATA_ERROR_FLAGS) {
@@ -1211,7 +1210,9 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
1211 host->data_status = status; 1210 host->data_status = status;
1212 smp_wmb(); 1211 smp_wmb();
1213 set_bit(EVENT_DATA_ERROR, &host->pending_events); 1212 set_bit(EVENT_DATA_ERROR, &host->pending_events);
1214 tasklet_schedule(&host->tasklet); 1213 if (!(pending & (SDMMC_INT_DTO | SDMMC_INT_DCRC |
1214 SDMMC_INT_SBE | SDMMC_INT_EBE)))
1215 tasklet_schedule(&host->tasklet);
1215 } 1216 }
1216 1217
1217 if (pending & SDMMC_INT_DATA_OVER) { 1218 if (pending & SDMMC_INT_DATA_OVER) {