diff options
author | Sebastian Rasmussen <sebastian.rasmussen@stericsson.com> | 2011-04-11 11:28:19 +0200 |
---|---|---|
committer | Sebastian RASMUSSEN <sebastian.rasmussen@stericsson.com> | 2011-04-11 11:35:38 +0200 |
commit | 7d92304ec4e34ea7e0af90f8a9a4f33526f8ce0d (patch) | |
tree | 15c0fce84d456228b6bc82d3df9a0e9ec8908ca5 /drivers/mmc | |
parent | 88d075c19943f111df5464fb097a99b0cd06d0f8 (diff) |
Revert "mmci: dma split adaptation: setup and preparation"
This reverts commit 104f06d9e3b4f6ad7ec55d5ee13c88a5299d5c2e.
Change-Id: I5008f57728a340a14e481ba7add38753a1285c20
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/20572
Reviewed-by: Sebastian RASMUSSEN <sebastian.rasmussen@stericsson.com>
Tested-by: Sebastian RASMUSSEN <sebastian.rasmussen@stericsson.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/mmci.c | 76 |
1 files changed, 47 insertions, 29 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 4114c17c25b..b0c53445c84 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -373,14 +373,14 @@ static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data) * no custom DMA interfaces are supported. */ #ifdef CONFIG_DMA_ENGINE -static int __devinit mmci_setup_dma(struct mmci_host *host) +static void __devinit mmci_setup_dma(struct mmci_host *host) { struct mmci_platform_data *plat = host->plat; dma_cap_mask_t mask; if (!plat || !plat->dma_filter) { dev_err(mmc_dev(host->mmc), "no DMA platform data!\n"); - return -EINVAL; + return; } /* Try to acquire a generic DMA engine slave channel */ @@ -397,7 +397,7 @@ static int __devinit mmci_setup_dma(struct mmci_host *host) /* E.g if no DMA hardware is present */ if (!host->dma_rx_channel) { dev_err(mmc_dev(host->mmc), "no RX DMA channel!\n"); - return -EINVAL; + return; } if (plat->dma_tx_param) { host->dma_tx_channel = dma_request_channel(mask, @@ -406,7 +406,7 @@ static int __devinit mmci_setup_dma(struct mmci_host *host) if (!host->dma_tx_channel) { dma_release_channel(host->dma_rx_channel); host->dma_rx_channel = NULL; - return -EINVAL; + return; } } else { host->dma_tx_channel = host->dma_rx_channel; @@ -415,8 +415,19 @@ static int __devinit mmci_setup_dma(struct mmci_host *host) dev_info(mmc_dev(host->mmc), "use DMA channels DMA RX %s, DMA TX %s\n", dma_chan_name(host->dma_rx_channel), dma_chan_name(host->dma_tx_channel)); +} - return 0; +/* + * This is used in __devinit or __devexit so inline it + * so it can be discarded. + */ +static inline void mmci_disable_dma(struct mmci_host *host) +{ + if (host->dma_rx_channel) + dma_release_channel(host->dma_rx_channel); + if (host->dma_tx_channel) + dma_release_channel(host->dma_tx_channel); + host->dma_enable = false; } static void mmci_dma_data_end(struct mmci_host *host) @@ -470,37 +481,37 @@ static void mmci_dma_callback(void *arg) spin_unlock_irqrestore(&host->lock, flags); } -static inline int mmci_prepare_dma(struct mmci_host *host, - struct mmc_data *data) +static int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl) { struct variant_data *variant = host->variant; - int burst_sz = variant->fifohalfsize >> 2; /* # of words */ struct dma_slave_config rx_conf = { .src_addr = host->phybase + MMCIFIFO, .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, .direction = DMA_FROM_DEVICE, - .src_maxburst = burst_sz, + .src_maxburst = variant->fifohalfsize >> 2, /* # of words */ }; struct dma_slave_config tx_conf = { .dst_addr = host->phybase + MMCIFIFO, .dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, .direction = DMA_TO_DEVICE, - .dst_maxburst = burst_sz, + .dst_maxburst = variant->fifohalfsize >> 2, /* # of words */ }; + struct mmc_data *data = host->data; enum dma_data_direction direction; struct dma_chan *chan; struct dma_async_tx_descriptor *desc; struct scatterlist *sg; dma_cookie_t cookie; int i; + unsigned int irqmask0; int sg_len; /* If less than or equal to the fifo size, don't bother with DMA */ if (host->size <= variant->fifosize) return -EINVAL; - host->mmci_datactrl |= MCI_DPSM_DMAENABLE; - host->mmci_datactrl |= variant->dmareg_enable; + datactrl |= MCI_DPSM_DMAENABLE; + datactrl |= variant->dmareg_enable; if (data->flags & MMC_DATA_READ) { if (host->size <= variant->txsize_threshold) @@ -523,8 +534,8 @@ static inline int mmci_prepare_dma(struct mmci_host *host, /* Check for weird stuff in the sg list */ for_each_sg(data->sg, sg, data->sg_len, i) { dev_vdbg(mmc_dev(host->mmc), - "[%s] MMCI SGlist %d dir %d: length: %08x\n", - __func__, i, direction, sg->length); + "MMCI SGlist %d dir %d: length: %08x\n", + i, direction, sg->length); if (sg->offset & 3 || sg->length & 3) return -EINVAL; } @@ -543,18 +554,30 @@ static inline int mmci_prepare_dma(struct mmci_host *host, desc->callback = mmci_dma_callback; desc->callback_param = host; host->dma_desc = desc; + dev_vdbg(mmc_dev(host->mmc), "Submit MMCI DMA job, sglen %d " + "blksz %04x blks %04x flags %08x\n", + data->sg_len, data->blksz, data->blocks, data->flags); cookie = desc->tx_submit(desc); /* Here overloaded DMA controllers may fail */ if (dma_submit_error(cookie)) goto unmap_exit; + host->dma_on_current_xfer = true; chan->device->device_issue_pending(chan); - host->mmci_mask0 |= MCI_DATAENDMASK; + /* + * MMCI monitors both MCI_DATAEND and the DMA callback. + * Both events must occur before the transfer is considered + * to be completed. MCI_DATABLOCKEND is not used in DMA mode. + */ + host->last_blockend = true; + irqmask0 = readl(host->base + MMCIMASK0); + irqmask0 &= ~MCI_DATABLOCKENDMASK; + writel(irqmask0, host->base + MMCIMASK0); - dev_dbg(mmc_dev(host->mmc), "[%s] config dma transfert: len:%d\n", - __func__, host->mmci_datalenght); + /* Trigger the DMA transfer */ + writel(datactrl, host->base + MMCIDATACTRL); return 0; unmap_exit: @@ -565,16 +588,14 @@ map_err: } #else /* Blank functions if the DMA engine is not available */ -static inline int mmci_setup_dma(struct mmci_host *host) +static inline void mmci_setup_dma(struct mmci_host *host) { - return -1; } -static inline int mmci_prepare_dma(struct mmci_host *host, - struct mmc_data *data) +static inline void mmci_disable_dma(struct mmci_host *host) { - return -1; } + static inline void mmci_dma_data_end(struct mmci_host *host) { } @@ -582,16 +603,13 @@ static inline void mmci_dma_data_end(struct mmci_host *host) static inline void mmci_dma_terminate(struct mmci_host *host) { } -#endif -static inline void mmci_disable_dma(struct mmci_host *host) +static inline int mmci_dma_start_data(struct mmci_host *host, + unsigned int datactrl) { - if (host->dma_rx_channel) - dma_release_channel(host->dma_rx_channel); - if (host->dma_tx_channel) - dma_release_channel(host->dma_tx_channel); - host->dma_enable = false; + return -ENOSYS; } +#endif static void mmci_data_irq(struct mmci_host *host, struct mmc_data *data, |