diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-03-19 17:02:01 -0700 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-03-19 17:02:01 -0700 |
commit | 10ce3cc919f50c2043b41ca968b43c26a3672600 (patch) | |
tree | ea409366a5208aced495bc0516a08b81fd43222e /drivers/mmc/host/mmci.c | |
parent | 24e3e5ae1e4c2a3a32f5b1f96b4e3fd721806acd (diff) | |
parent | 5c6a7a62c130afef3d61c1dee153012231ff5cd9 (diff) |
Merge branch 'next' into for-linus
Diffstat (limited to 'drivers/mmc/host/mmci.c')
-rw-r--r-- | drivers/mmc/host/mmci.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 50b5f9926f6..0d955ffaf44 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -374,6 +374,7 @@ static int mmci_dma_prep_data(struct mmci_host *host, struct mmc_data *data, struct dma_chan *chan; struct dma_device *device; struct dma_async_tx_descriptor *desc; + enum dma_data_direction buffer_dirn; int nr_sg; /* Check if next job is already prepared */ @@ -387,10 +388,12 @@ static int mmci_dma_prep_data(struct mmci_host *host, struct mmc_data *data, } if (data->flags & MMC_DATA_READ) { - conf.direction = DMA_FROM_DEVICE; + conf.direction = DMA_DEV_TO_MEM; + buffer_dirn = DMA_FROM_DEVICE; chan = host->dma_rx_channel; } else { - conf.direction = DMA_TO_DEVICE; + conf.direction = DMA_MEM_TO_DEV; + buffer_dirn = DMA_TO_DEVICE; chan = host->dma_tx_channel; } @@ -403,7 +406,7 @@ static int mmci_dma_prep_data(struct mmci_host *host, struct mmc_data *data, return -EINVAL; device = chan->device; - nr_sg = dma_map_sg(device->dev, data->sg, data->sg_len, conf.direction); + nr_sg = dma_map_sg(device->dev, data->sg, data->sg_len, buffer_dirn); if (nr_sg == 0) return -EINVAL; @@ -426,7 +429,7 @@ static int mmci_dma_prep_data(struct mmci_host *host, struct mmc_data *data, unmap_exit: if (!next) dmaengine_terminate_all(chan); - dma_unmap_sg(device->dev, data->sg, data->sg_len, conf.direction); + dma_unmap_sg(device->dev, data->sg, data->sg_len, buffer_dirn); return -ENOMEM; } @@ -675,7 +678,8 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, unsigned int status) { /* First check for errors */ - if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { + if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR| + MCI_TXUNDERRUN|MCI_RXOVERRUN)) { u32 remain, success; /* Terminate the DMA transfer */ @@ -754,8 +758,12 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, } if (!cmd->data || cmd->error) { - if (host->data) + if (host->data) { + /* Terminate the DMA transfer */ + if (dma_inprogress(host)) + mmci_dma_data_error(host); mmci_stop_data(host); + } mmci_request_end(host, cmd->mrq); } else if (!(cmd->data->flags & MMC_DATA_READ)) { mmci_start_data(host, cmd->data); @@ -955,8 +963,9 @@ static irqreturn_t mmci_irq(int irq, void *dev_id) dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); data = host->data; - if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN| - MCI_RXOVERRUN|MCI_DATAEND|MCI_DATABLOCKEND) && data) + if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR| + MCI_TXUNDERRUN|MCI_RXOVERRUN|MCI_DATAEND| + MCI_DATABLOCKEND) && data) mmci_data_irq(host, data, status); cmd = host->cmd; @@ -1239,6 +1248,7 @@ static int __devinit mmci_probe(struct amba_device *dev, if (host->vcc == NULL) mmc->ocr_avail = plat->ocr_mask; mmc->caps = plat->capabilities; + mmc->caps2 = plat->capabilities2; /* * We can do SGIO @@ -1496,6 +1506,8 @@ static struct amba_id mmci_ids[] = { { 0, 0 }, }; +MODULE_DEVICE_TABLE(amba, mmci_ids); + static struct amba_driver mmci_driver = { .drv = { .name = DRIVER_NAME, |