aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/dw_mmc.c
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2011-06-29 04:28:43 -0400
committerChris Ball <cjb@laptop.org>2011-07-20 17:21:05 -0400
commit03e8cb534e7cc3f71a07528a44da7ce68e5b5708 (patch)
tree989d0a96a03d8838de7617f6eb0062ed2a7065e6 /drivers/mmc/host/dw_mmc.c
parent65d13516b2358c38ac56a5f83e989a6837dcf825 (diff)
mmc: dw_mmc: fix stop when fallen back to PIO
There are several situations when dw_mci_submit_data_dma() decides to fall back to PIO mode instead of using DMA, due to a short (to avoid overhead) or "complex" (e.g. with unaligned buffers) transaction, even though host->use_dma is set. However dw_mci_stop_dma() decides whether to stop DMA or set the EVENT_XFER_COMPLETE event based on host->use_dma. When falling back to PIO mode this results in data timeout errors getting missed and the driver locking up. Therefore add host->using_dma to indicate whether the current transaction is using dma or not, and adjust dw_mci_stop_dma() to use that instead. Signed-off-by: James Hogan <james.hogan@imgtec.com> Acked-by: Will Newton <will.newton@imgtec.com> Tested-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/host/dw_mmc.c')
-rw-r--r--drivers/mmc/host/dw_mmc.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 10b697986283..fcff3c042f69 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -287,7 +287,7 @@ static void send_stop_cmd(struct dw_mci *host, struct mmc_data *data)
287/* DMA interface functions */ 287/* DMA interface functions */
288static void dw_mci_stop_dma(struct dw_mci *host) 288static void dw_mci_stop_dma(struct dw_mci *host)
289{ 289{
290 if (host->use_dma) { 290 if (host->using_dma) {
291 host->dma_ops->stop(host); 291 host->dma_ops->stop(host);
292 host->dma_ops->cleanup(host); 292 host->dma_ops->cleanup(host);
293 } else { 293 } else {
@@ -435,6 +435,8 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
435 unsigned int i, direction, sg_len; 435 unsigned int i, direction, sg_len;
436 u32 temp; 436 u32 temp;
437 437
438 host->using_dma = 0;
439
438 /* If we don't have a channel, we can't do DMA */ 440 /* If we don't have a channel, we can't do DMA */
439 if (!host->use_dma) 441 if (!host->use_dma)
440 return -ENODEV; 442 return -ENODEV;
@@ -454,6 +456,8 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
454 return -EINVAL; 456 return -EINVAL;
455 } 457 }
456 458
459 host->using_dma = 1;
460
457 if (data->flags & MMC_DATA_READ) 461 if (data->flags & MMC_DATA_READ)
458 direction = DMA_FROM_DEVICE; 462 direction = DMA_FROM_DEVICE;
459 else 463 else