From: Daniel Mack <zonque@gmail.com> To: haojian.zhuang@linaro.org, eric.y.miao@gmail.com, linux-arm-kernel@lists.infradead.org Cc: mark.rutland@arm.com, s.neumann@raumfeld.com, linux-mtd@lists.infradead.org, Daniel Mack <zonque@gmail.com>, cxie4@marvell.com, lars@metafoo.de, nico@linaro.org, vinod.koul@intel.com, marek.vasut@gmail.com, ezequiel.garcia@free-electrons.com, rmk+kernel@arm.linux.org.uk, devicetree@vger.kernel.org, samuel@sortiz.org, arnd@arndb.de, broonie@kernel.org, mika.westerberg@linux.intel.com, thomas.petazzoni@free-electrons.com, gregkh@linuxfoundation.org, g.liakhovetski@gmx.de, sachin.kamat@linaro.org, kernel@pengutronix.de, djbw@fb.com, davem@davemloft.net Subject: [PATCH 08/20] mmc: host: pxamci: switch over to dmaengine use Date: Wed, 7 Aug 2013 17:33:57 +0200 [thread overview] Message-ID: <1375889649-14638-9-git-send-email-zonque@gmail.com> (raw) In-Reply-To: <1375889649-14638-1-git-send-email-zonque@gmail.com> Successfully testes on a PXA3xx board. Signed-off-by: Daniel Mack <zonque@gmail.com> --- drivers/mmc/host/pxamci.c | 188 +++++++++++++++++++++++++--------------------- 1 file changed, 102 insertions(+), 86 deletions(-) diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index 2c5a91b..7aa97eb 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -22,7 +22,9 @@ #include <linux/platform_device.h> #include <linux/delay.h> #include <linux/interrupt.h> +#include <linux/dmaengine.h> #include <linux/dma-mapping.h> +#include <linux/dma/mmp-pdma.h> #include <linux/clk.h> #include <linux/err.h> #include <linux/mmc/host.h> @@ -37,7 +39,6 @@ #include <asm/sizes.h> #include <mach/hardware.h> -#include <mach/dma.h> #include <linux/platform_data/mmc-pxamci.h> #include "pxamci.h" @@ -58,7 +59,6 @@ struct pxamci_host { struct clk *clk; unsigned long clkrate; int irq; - int dma; unsigned int clkrt; unsigned int cmdat; unsigned int imask; @@ -69,8 +69,10 @@ struct pxamci_host { struct mmc_command *cmd; struct mmc_data *data; + struct dma_chan *dma_chan_rx; + struct dma_chan *dma_chan_tx; + dma_cookie_t dma_cookie; dma_addr_t sg_dma; - struct pxa_dma_desc *sg_cpu; unsigned int dma_len; unsigned int dma_dir; @@ -173,14 +175,18 @@ static void pxamci_disable_irq(struct pxamci_host *host, unsigned int mask) spin_unlock_irqrestore(&host->lock, flags); } +static void pxamci_dma_irq(void *param); + static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) { + struct dma_async_tx_descriptor *tx; + enum dma_data_direction direction; + struct dma_slave_config config; + struct dma_chan *chan; unsigned int nob = data->blocks; unsigned long long clks; unsigned int timeout; - bool dalgn = 0; - u32 dcmd; - int i; + int ret; host->data = data; @@ -195,54 +201,46 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) timeout = (unsigned int)clks + (data->timeout_clks << host->clkrt); writel((timeout + 255) / 256, host->base + MMC_RDTO); + memset(&config, 0, sizeof(config)); + config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + config.src_addr = host->res->start + MMC_RXFIFO; + config.dst_addr = host->res->start + MMC_TXFIFO; + config.src_maxburst = 32; + config.dst_maxburst = 32; + if (data->flags & MMC_DATA_READ) { host->dma_dir = DMA_FROM_DEVICE; - dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC; - DRCMR(host->dma_drcmrtx) = 0; - DRCMR(host->dma_drcmrrx) = host->dma | DRCMR_MAPVLD; + direction = DMA_DEV_TO_MEM; + chan = host->dma_chan_rx; } else { host->dma_dir = DMA_TO_DEVICE; - dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG; - DRCMR(host->dma_drcmrrx) = 0; - DRCMR(host->dma_drcmrtx) = host->dma | DRCMR_MAPVLD; + direction = DMA_MEM_TO_DEV; + chan = host->dma_chan_tx; } - dcmd |= DCMD_BURST32 | DCMD_WIDTH1; + config.direction = direction; + + ret = dmaengine_slave_config(chan, &config); + if (ret < 0) { + dev_err(mmc_dev(host->mmc), "dma slave config failed\n"); + return; + } - host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, + host->dma_len = dma_map_sg(chan->device->dev, data->sg, data->sg_len, host->dma_dir); - for (i = 0; i < host->dma_len; i++) { - unsigned int length = sg_dma_len(&data->sg[i]); - host->sg_cpu[i].dcmd = dcmd | length; - if (length & 31 && !(data->flags & MMC_DATA_READ)) - host->sg_cpu[i].dcmd |= DCMD_ENDIRQEN; - /* Not aligned to 8-byte boundary? */ - if (sg_dma_address(&data->sg[i]) & 0x7) - dalgn = 1; - if (data->flags & MMC_DATA_READ) { - host->sg_cpu[i].dsadr = host->res->start + MMC_RXFIFO; - host->sg_cpu[i].dtadr = sg_dma_address(&data->sg[i]); - } else { - host->sg_cpu[i].dsadr = sg_dma_address(&data->sg[i]); - host->sg_cpu[i].dtadr = host->res->start + MMC_TXFIFO; - } - host->sg_cpu[i].ddadr = host->sg_dma + (i + 1) * - sizeof(struct pxa_dma_desc); + tx = dmaengine_prep_slave_sg(chan, data->sg, host->dma_len, direction, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!tx) { + dev_err(mmc_dev(host->mmc), "prep_slave_sg() failed\n"); + return; } - host->sg_cpu[host->dma_len - 1].ddadr = DDADR_STOP; - wmb(); - /* - * The PXA27x DMA controller encounters overhead when working with - * unaligned (to 8-byte boundaries) data, so switch on byte alignment - * mode only if we have unaligned data. - */ - if (dalgn) - DALGN |= (1 << host->dma); - else - DALGN &= ~(1 << host->dma); - DDADR(host->dma) = host->sg_dma; + tx->callback = pxamci_dma_irq; + tx->callback_param = host; + + host->dma_cookie = dmaengine_submit(tx); /* * workaround for erratum #91: @@ -251,7 +249,7 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) * before starting DMA. */ if (!cpu_is_pxa27x() || data->flags & MMC_DATA_READ) - DCSR(host->dma) = DCSR_RUN; + dma_async_issue_pending(chan); } static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, unsigned int cmdat) @@ -343,7 +341,7 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat) * enable DMA late */ if (cpu_is_pxa27x() && host->data->flags & MMC_DATA_WRITE) - DCSR(host->dma) = DCSR_RUN; + dma_async_issue_pending(host->dma_chan_tx); } else { pxamci_finish_request(host, host->mrq); } @@ -358,9 +356,8 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat) if (!data) return 0; - DCSR(host->dma) = 0; - dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, - host->dma_dir); + dma_unmap_sg(host->dma_chan_rx->device->dev, + data->sg, data->sg_len, host->dma_dir); if (stat & STAT_READ_TIME_OUT) data->error = -ETIMEDOUT; @@ -552,17 +549,25 @@ static const struct mmc_host_ops pxamci_ops = { .enable_sdio_irq = pxamci_enable_sdio_irq, }; -static void pxamci_dma_irq(int dma, void *devid) +static void pxamci_dma_irq(void *param) { - struct pxamci_host *host = devid; - int dcsr = DCSR(dma); - DCSR(dma) = dcsr & ~DCSR_STOPIRQEN; + struct pxamci_host *host = param; + struct dma_tx_state state; + enum dma_status status; + struct dma_chan *chan; - if (dcsr & DCSR_ENDINTR) { + if (host->data->flags & MMC_DATA_READ) + chan = host->dma_chan_rx; + else + chan = host->dma_chan_tx; + + status = dmaengine_tx_status(chan, host->dma_cookie, &state); + + if (likely(status == DMA_SUCCESS)) { writel(BUF_PART_FULL, host->base + MMC_PRTBUF); } else { - pr_err("%s: DMA error on channel %d (DCSR=%#x)\n", - mmc_hostname(host->mmc), dma, dcsr); + pr_err("%s: DMA error on %s channel\n", mmc_hostname(host->mmc), + host->data->flags & MMC_DATA_READ ? "rx" : "tx"); host->data->error = -EIO; pxamci_data_done(host, 0); } @@ -626,6 +631,7 @@ static int pxamci_probe(struct platform_device *pdev) struct pxamci_host *host = NULL; struct resource *r, *dmarx, *dmatx; int ret, irq, gpio_cd = -1, gpio_ro = -1, gpio_power = -1; + dma_cap_mask_t mask; ret = pxamci_of_init(pdev); if (ret) @@ -671,7 +677,6 @@ static int pxamci_probe(struct platform_device *pdev) host = mmc_priv(mmc); host->mmc = mmc; - host->dma = -1; host->pdata = pdev->dev.platform_data; host->clkrt = CLKRT_OFF; @@ -702,12 +707,6 @@ static int pxamci_probe(struct platform_device *pdev) MMC_CAP_SD_HIGHSPEED; } - host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL); - if (!host->sg_cpu) { - ret = -ENOMEM; - goto out; - } - spin_lock_init(&host->lock); host->res = r; host->irq = irq; @@ -728,32 +727,50 @@ static int pxamci_probe(struct platform_device *pdev) writel(64, host->base + MMC_RESTO); writel(host->imask, host->base + MMC_I_MASK); - host->dma = pxa_request_dma(DRIVER_NAME, DMA_PRIO_LOW, - pxamci_dma_irq, host); - if (host->dma < 0) { - ret = -EBUSY; - goto out; - } - ret = request_irq(host->irq, pxamci_irq, 0, DRIVER_NAME, host); if (ret) goto out; platform_set_drvdata(pdev, mmc); - dmarx = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!dmarx) { - ret = -ENXIO; + if (!pdev->dev.of_node) { + dmarx = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!dmarx) { + ret = -ENXIO; + goto out; + } + host->dma_drcmrrx = dmarx->start; + + dmatx = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!dmatx) { + ret = -ENXIO; + goto out; + } + host->dma_drcmrtx = dmatx->start; + } + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + + host->dma_chan_rx = + dma_request_slave_channel_compat(mask, mmp_pdma_filter_fn, + &host->dma_drcmrrx, + &pdev->dev, "rx"); + if (host->dma_chan_rx == NULL) { + dev_err(&pdev->dev, "unable to request rx dma channel\n"); + ret = -ENODEV; goto out; } - host->dma_drcmrrx = dmarx->start; - dmatx = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (!dmatx) { - ret = -ENXIO; + host->dma_chan_tx = + dma_request_slave_channel_compat(mask, mmp_pdma_filter_fn, + &host->dma_drcmrtx, + &pdev->dev, "tx"); + if (host->dma_chan_tx == NULL) { + dev_err(&pdev->dev, "unable to request tx dma channel\n"); + ret = -ENODEV; goto out; } - host->dma_drcmrtx = dmatx->start; if (host->pdata) { gpio_cd = host->pdata->gpio_card_detect; @@ -814,12 +831,12 @@ err_gpio_ro: gpio_free(gpio_power); out: if (host) { - if (host->dma >= 0) - pxa_free_dma(host->dma); + if (host->dma_chan_rx) + dma_release_channel(host->dma_chan_rx); + if (host->dma_chan_tx) + dma_release_channel(host->dma_chan_tx); if (host->base) iounmap(host->base); - if (host->sg_cpu) - dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); if (host->clk) clk_put(host->clk); } @@ -863,13 +880,12 @@ static int pxamci_remove(struct platform_device *pdev) END_CMD_RES|PRG_DONE|DATA_TRAN_DONE, host->base + MMC_I_MASK); - DRCMR(host->dma_drcmrrx) = 0; - DRCMR(host->dma_drcmrtx) = 0; - free_irq(host->irq, host); - pxa_free_dma(host->dma); + dmaengine_terminate_all(host->dma_chan_rx); + dmaengine_terminate_all(host->dma_chan_tx); + dma_release_channel(host->dma_chan_rx); + dma_release_channel(host->dma_chan_tx); iounmap(host->base); - dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); clk_put(host->clk); -- 1.8.3.1
WARNING: multiple messages have this Message-ID (diff)
From: zonque@gmail.com (Daniel Mack) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 08/20] mmc: host: pxamci: switch over to dmaengine use Date: Wed, 7 Aug 2013 17:33:57 +0200 [thread overview] Message-ID: <1375889649-14638-9-git-send-email-zonque@gmail.com> (raw) In-Reply-To: <1375889649-14638-1-git-send-email-zonque@gmail.com> Successfully testes on a PXA3xx board. Signed-off-by: Daniel Mack <zonque@gmail.com> --- drivers/mmc/host/pxamci.c | 188 +++++++++++++++++++++++++--------------------- 1 file changed, 102 insertions(+), 86 deletions(-) diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index 2c5a91b..7aa97eb 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -22,7 +22,9 @@ #include <linux/platform_device.h> #include <linux/delay.h> #include <linux/interrupt.h> +#include <linux/dmaengine.h> #include <linux/dma-mapping.h> +#include <linux/dma/mmp-pdma.h> #include <linux/clk.h> #include <linux/err.h> #include <linux/mmc/host.h> @@ -37,7 +39,6 @@ #include <asm/sizes.h> #include <mach/hardware.h> -#include <mach/dma.h> #include <linux/platform_data/mmc-pxamci.h> #include "pxamci.h" @@ -58,7 +59,6 @@ struct pxamci_host { struct clk *clk; unsigned long clkrate; int irq; - int dma; unsigned int clkrt; unsigned int cmdat; unsigned int imask; @@ -69,8 +69,10 @@ struct pxamci_host { struct mmc_command *cmd; struct mmc_data *data; + struct dma_chan *dma_chan_rx; + struct dma_chan *dma_chan_tx; + dma_cookie_t dma_cookie; dma_addr_t sg_dma; - struct pxa_dma_desc *sg_cpu; unsigned int dma_len; unsigned int dma_dir; @@ -173,14 +175,18 @@ static void pxamci_disable_irq(struct pxamci_host *host, unsigned int mask) spin_unlock_irqrestore(&host->lock, flags); } +static void pxamci_dma_irq(void *param); + static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) { + struct dma_async_tx_descriptor *tx; + enum dma_data_direction direction; + struct dma_slave_config config; + struct dma_chan *chan; unsigned int nob = data->blocks; unsigned long long clks; unsigned int timeout; - bool dalgn = 0; - u32 dcmd; - int i; + int ret; host->data = data; @@ -195,54 +201,46 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) timeout = (unsigned int)clks + (data->timeout_clks << host->clkrt); writel((timeout + 255) / 256, host->base + MMC_RDTO); + memset(&config, 0, sizeof(config)); + config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + config.src_addr = host->res->start + MMC_RXFIFO; + config.dst_addr = host->res->start + MMC_TXFIFO; + config.src_maxburst = 32; + config.dst_maxburst = 32; + if (data->flags & MMC_DATA_READ) { host->dma_dir = DMA_FROM_DEVICE; - dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC; - DRCMR(host->dma_drcmrtx) = 0; - DRCMR(host->dma_drcmrrx) = host->dma | DRCMR_MAPVLD; + direction = DMA_DEV_TO_MEM; + chan = host->dma_chan_rx; } else { host->dma_dir = DMA_TO_DEVICE; - dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG; - DRCMR(host->dma_drcmrrx) = 0; - DRCMR(host->dma_drcmrtx) = host->dma | DRCMR_MAPVLD; + direction = DMA_MEM_TO_DEV; + chan = host->dma_chan_tx; } - dcmd |= DCMD_BURST32 | DCMD_WIDTH1; + config.direction = direction; + + ret = dmaengine_slave_config(chan, &config); + if (ret < 0) { + dev_err(mmc_dev(host->mmc), "dma slave config failed\n"); + return; + } - host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, + host->dma_len = dma_map_sg(chan->device->dev, data->sg, data->sg_len, host->dma_dir); - for (i = 0; i < host->dma_len; i++) { - unsigned int length = sg_dma_len(&data->sg[i]); - host->sg_cpu[i].dcmd = dcmd | length; - if (length & 31 && !(data->flags & MMC_DATA_READ)) - host->sg_cpu[i].dcmd |= DCMD_ENDIRQEN; - /* Not aligned to 8-byte boundary? */ - if (sg_dma_address(&data->sg[i]) & 0x7) - dalgn = 1; - if (data->flags & MMC_DATA_READ) { - host->sg_cpu[i].dsadr = host->res->start + MMC_RXFIFO; - host->sg_cpu[i].dtadr = sg_dma_address(&data->sg[i]); - } else { - host->sg_cpu[i].dsadr = sg_dma_address(&data->sg[i]); - host->sg_cpu[i].dtadr = host->res->start + MMC_TXFIFO; - } - host->sg_cpu[i].ddadr = host->sg_dma + (i + 1) * - sizeof(struct pxa_dma_desc); + tx = dmaengine_prep_slave_sg(chan, data->sg, host->dma_len, direction, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!tx) { + dev_err(mmc_dev(host->mmc), "prep_slave_sg() failed\n"); + return; } - host->sg_cpu[host->dma_len - 1].ddadr = DDADR_STOP; - wmb(); - /* - * The PXA27x DMA controller encounters overhead when working with - * unaligned (to 8-byte boundaries) data, so switch on byte alignment - * mode only if we have unaligned data. - */ - if (dalgn) - DALGN |= (1 << host->dma); - else - DALGN &= ~(1 << host->dma); - DDADR(host->dma) = host->sg_dma; + tx->callback = pxamci_dma_irq; + tx->callback_param = host; + + host->dma_cookie = dmaengine_submit(tx); /* * workaround for erratum #91: @@ -251,7 +249,7 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) * before starting DMA. */ if (!cpu_is_pxa27x() || data->flags & MMC_DATA_READ) - DCSR(host->dma) = DCSR_RUN; + dma_async_issue_pending(chan); } static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, unsigned int cmdat) @@ -343,7 +341,7 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat) * enable DMA late */ if (cpu_is_pxa27x() && host->data->flags & MMC_DATA_WRITE) - DCSR(host->dma) = DCSR_RUN; + dma_async_issue_pending(host->dma_chan_tx); } else { pxamci_finish_request(host, host->mrq); } @@ -358,9 +356,8 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat) if (!data) return 0; - DCSR(host->dma) = 0; - dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, - host->dma_dir); + dma_unmap_sg(host->dma_chan_rx->device->dev, + data->sg, data->sg_len, host->dma_dir); if (stat & STAT_READ_TIME_OUT) data->error = -ETIMEDOUT; @@ -552,17 +549,25 @@ static const struct mmc_host_ops pxamci_ops = { .enable_sdio_irq = pxamci_enable_sdio_irq, }; -static void pxamci_dma_irq(int dma, void *devid) +static void pxamci_dma_irq(void *param) { - struct pxamci_host *host = devid; - int dcsr = DCSR(dma); - DCSR(dma) = dcsr & ~DCSR_STOPIRQEN; + struct pxamci_host *host = param; + struct dma_tx_state state; + enum dma_status status; + struct dma_chan *chan; - if (dcsr & DCSR_ENDINTR) { + if (host->data->flags & MMC_DATA_READ) + chan = host->dma_chan_rx; + else + chan = host->dma_chan_tx; + + status = dmaengine_tx_status(chan, host->dma_cookie, &state); + + if (likely(status == DMA_SUCCESS)) { writel(BUF_PART_FULL, host->base + MMC_PRTBUF); } else { - pr_err("%s: DMA error on channel %d (DCSR=%#x)\n", - mmc_hostname(host->mmc), dma, dcsr); + pr_err("%s: DMA error on %s channel\n", mmc_hostname(host->mmc), + host->data->flags & MMC_DATA_READ ? "rx" : "tx"); host->data->error = -EIO; pxamci_data_done(host, 0); } @@ -626,6 +631,7 @@ static int pxamci_probe(struct platform_device *pdev) struct pxamci_host *host = NULL; struct resource *r, *dmarx, *dmatx; int ret, irq, gpio_cd = -1, gpio_ro = -1, gpio_power = -1; + dma_cap_mask_t mask; ret = pxamci_of_init(pdev); if (ret) @@ -671,7 +677,6 @@ static int pxamci_probe(struct platform_device *pdev) host = mmc_priv(mmc); host->mmc = mmc; - host->dma = -1; host->pdata = pdev->dev.platform_data; host->clkrt = CLKRT_OFF; @@ -702,12 +707,6 @@ static int pxamci_probe(struct platform_device *pdev) MMC_CAP_SD_HIGHSPEED; } - host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL); - if (!host->sg_cpu) { - ret = -ENOMEM; - goto out; - } - spin_lock_init(&host->lock); host->res = r; host->irq = irq; @@ -728,32 +727,50 @@ static int pxamci_probe(struct platform_device *pdev) writel(64, host->base + MMC_RESTO); writel(host->imask, host->base + MMC_I_MASK); - host->dma = pxa_request_dma(DRIVER_NAME, DMA_PRIO_LOW, - pxamci_dma_irq, host); - if (host->dma < 0) { - ret = -EBUSY; - goto out; - } - ret = request_irq(host->irq, pxamci_irq, 0, DRIVER_NAME, host); if (ret) goto out; platform_set_drvdata(pdev, mmc); - dmarx = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!dmarx) { - ret = -ENXIO; + if (!pdev->dev.of_node) { + dmarx = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!dmarx) { + ret = -ENXIO; + goto out; + } + host->dma_drcmrrx = dmarx->start; + + dmatx = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!dmatx) { + ret = -ENXIO; + goto out; + } + host->dma_drcmrtx = dmatx->start; + } + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + + host->dma_chan_rx = + dma_request_slave_channel_compat(mask, mmp_pdma_filter_fn, + &host->dma_drcmrrx, + &pdev->dev, "rx"); + if (host->dma_chan_rx == NULL) { + dev_err(&pdev->dev, "unable to request rx dma channel\n"); + ret = -ENODEV; goto out; } - host->dma_drcmrrx = dmarx->start; - dmatx = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (!dmatx) { - ret = -ENXIO; + host->dma_chan_tx = + dma_request_slave_channel_compat(mask, mmp_pdma_filter_fn, + &host->dma_drcmrtx, + &pdev->dev, "tx"); + if (host->dma_chan_tx == NULL) { + dev_err(&pdev->dev, "unable to request tx dma channel\n"); + ret = -ENODEV; goto out; } - host->dma_drcmrtx = dmatx->start; if (host->pdata) { gpio_cd = host->pdata->gpio_card_detect; @@ -814,12 +831,12 @@ err_gpio_ro: gpio_free(gpio_power); out: if (host) { - if (host->dma >= 0) - pxa_free_dma(host->dma); + if (host->dma_chan_rx) + dma_release_channel(host->dma_chan_rx); + if (host->dma_chan_tx) + dma_release_channel(host->dma_chan_tx); if (host->base) iounmap(host->base); - if (host->sg_cpu) - dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); if (host->clk) clk_put(host->clk); } @@ -863,13 +880,12 @@ static int pxamci_remove(struct platform_device *pdev) END_CMD_RES|PRG_DONE|DATA_TRAN_DONE, host->base + MMC_I_MASK); - DRCMR(host->dma_drcmrrx) = 0; - DRCMR(host->dma_drcmrtx) = 0; - free_irq(host->irq, host); - pxa_free_dma(host->dma); + dmaengine_terminate_all(host->dma_chan_rx); + dmaengine_terminate_all(host->dma_chan_tx); + dma_release_channel(host->dma_chan_rx); + dma_release_channel(host->dma_chan_tx); iounmap(host->base); - dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); clk_put(host->clk); -- 1.8.3.1
next prev parent reply other threads:[~2013-08-07 15:33 UTC|newest] Thread overview: 131+ messages / expand[flat|nested] mbox.gz Atom feed top 2013-08-07 15:33 [PATCH 00/20] ARM: pxa: move core and drivers to dmaengine Daniel Mack 2013-08-07 15:33 ` Daniel Mack 2013-08-07 15:33 ` [PATCH 01/20] mtd: pxa3xx-nand: replace pxa_request_dma with dmaengine Daniel Mack 2013-08-07 15:33 ` Daniel Mack 2013-08-07 17:46 ` Ezequiel Garcia 2013-08-07 17:46 ` Ezequiel Garcia 2013-08-08 6:42 ` Daniel Mack 2013-08-08 6:42 ` Daniel Mack 2013-08-08 10:12 ` Ezequiel Garcia 2013-08-08 10:12 ` Ezequiel Garcia 2013-08-08 10:14 ` Daniel Mack 2013-08-08 10:14 ` Daniel Mack 2013-08-07 15:33 ` [PATCH 02/20] mtd: pxa3xx-nand: use mmp_pdma_filter_fn and dma_request_slave_channel_compat Daniel Mack 2013-08-07 15:33 ` Daniel Mack 2013-08-07 15:33 ` [PATCH 03/20] ARM: pxa: ssp: add shortcut for &pdev->dev Daniel Mack 2013-08-07 15:33 ` Daniel Mack 2013-08-08 7:32 ` Brian Norris 2013-08-08 7:32 ` Brian Norris 2013-08-08 7:52 ` Artem Bityutskiy 2013-08-08 7:52 ` Artem Bityutskiy 2013-08-08 8:20 ` Daniel Mack 2013-08-08 8:20 ` Daniel Mack 2013-08-07 15:33 ` [PATCH 04/20] ARM: pxa: ssp: add DT bindings Daniel Mack 2013-08-07 15:33 ` Daniel Mack 2013-08-07 15:54 ` Arnd Bergmann 2013-08-07 15:54 ` Arnd Bergmann 2013-08-07 15:33 ` [PATCH 05/20] ARM: pxa: ssp: use devm_ functions Daniel Mack 2013-08-07 15:33 ` Daniel Mack 2013-08-07 15:33 ` [PATCH 06/20] tty: serial: pxa: remove old cruft Daniel Mack 2013-08-07 15:33 ` Daniel Mack 2013-08-12 8:19 ` Daniel Mack 2013-08-12 18:08 ` Greg KH 2013-08-07 15:33 ` [PATCH 07/20] spi: spi-pxa2xx: remove legacy PXA DMA bits Daniel Mack 2013-08-07 15:33 ` Daniel Mack 2013-08-07 15:55 ` Mark Brown 2013-08-07 15:55 ` Mark Brown 2013-08-07 15:59 ` Daniel Mack 2013-08-07 15:59 ` Daniel Mack 2013-08-07 16:41 ` Mark Brown 2013-08-07 16:41 ` Mark Brown 2013-08-07 15:33 ` Daniel Mack [this message] 2013-08-07 15:33 ` [PATCH 08/20] mmc: host: pxamci: switch over to dmaengine use Daniel Mack [not found] ` <1375889649-14638-9-git-send-email-zonque-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2014-10-15 18:32 ` Vasily Khoruzhick 2014-10-15 18:32 ` Vasily Khoruzhick 2014-10-15 18:32 ` Vasily Khoruzhick [not found] ` <CA+E=qVe5zRoR8qVa_gyJu+qpuGHFmqoGvEHowcu_hXR01GBzTA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 2014-10-16 17:57 ` Vasily Khoruzhick 2014-10-16 17:57 ` Vasily Khoruzhick 2014-10-16 17:57 ` Vasily Khoruzhick 2013-08-07 15:33 ` [PATCH 09/20] ata: pdata_pxa: migrate over to dmaengine usage Daniel Mack 2013-08-07 15:33 ` Daniel Mack 2013-08-07 15:59 ` Arnd Bergmann 2013-08-07 15:59 ` Arnd Bergmann 2013-08-07 15:33 ` [PATCH 10/20] net: irda: pxaficp_ir: switch to dmaengine Daniel Mack 2013-08-07 15:33 ` Daniel Mack 2013-08-07 15:34 ` [PATCH 11/20] net: smc91x.c: switch to generic buf-to-buf DMA offload Daniel Mack 2013-08-07 15:34 ` Daniel Mack 2013-08-07 15:34 ` [PATCH 12/20] net: smc911x.c: switch to dmaengine API Daniel Mack 2013-08-07 15:34 ` Daniel Mack 2013-08-07 15:34 ` [PATCH 13/20] ASoC: pxa: pxa-ssp: add DT bindings Daniel Mack 2013-08-07 15:34 ` Daniel Mack 2013-08-07 16:40 ` Mark Brown 2013-08-07 16:40 ` Mark Brown 2013-08-08 9:39 ` Daniel Mack 2013-08-08 9:39 ` Daniel Mack 2013-08-08 13:20 ` Mark Brown 2013-08-08 13:20 ` Mark Brown 2013-08-09 13:03 ` Daniel Mack 2013-08-09 13:03 ` Daniel Mack 2013-08-07 15:34 ` [PATCH 14/20] ASoC: pxa: use snd_dmaengine_dai_dma_data Daniel Mack 2013-08-07 15:34 ` Daniel Mack 2013-08-07 15:57 ` Mark Brown 2013-08-07 15:57 ` Mark Brown 2013-08-07 15:34 ` [PATCH 15/20] ASoC: pxa: pxa-ssp: set dma filter data from startup hook Daniel Mack 2013-08-07 15:34 ` Daniel Mack 2013-08-07 15:58 ` Mark Brown 2013-08-07 15:58 ` Mark Brown 2013-08-07 15:34 ` [PATCH 16/20] ASoC: pxa: add DT bindings for pxa2xx-pcm Daniel Mack 2013-08-07 15:34 ` Daniel Mack 2013-08-07 16:06 ` Mark Brown 2013-08-07 16:06 ` Mark Brown 2013-08-07 15:34 ` [PATCH 17/20] ASoC: pxa: pxa-pcm-lib: switch over to snd-soc-dmaengine-pcm Daniel Mack 2013-08-07 15:34 ` Daniel Mack 2013-08-07 16:07 ` Mark Brown 2013-08-07 16:07 ` Mark Brown 2013-08-07 16:10 ` Daniel Mack 2013-08-07 16:10 ` Daniel Mack 2013-08-07 16:32 ` Mark Brown 2013-08-07 16:32 ` Mark Brown 2013-08-08 8:18 ` Daniel Mack 2013-08-08 8:18 ` Daniel Mack 2013-08-08 8:44 ` Lars-Peter Clausen 2013-08-08 8:44 ` Lars-Peter Clausen 2013-08-08 9:03 ` Daniel Mack 2013-08-08 9:03 ` Daniel Mack 2013-08-08 9:36 ` Mark Brown 2013-08-08 9:36 ` Mark Brown 2013-08-08 9:43 ` Daniel Mack 2013-08-08 9:43 ` Daniel Mack 2013-08-08 10:35 ` Mark Brown 2013-08-08 10:35 ` Mark Brown 2013-08-08 10:39 ` Daniel Mack 2013-08-08 10:39 ` Daniel Mack 2013-08-08 11:03 ` Mark Brown 2013-08-08 11:03 ` Mark Brown 2013-08-08 10:25 ` Russell King - ARM Linux 2013-08-08 10:25 ` Russell King - ARM Linux 2013-08-07 15:34 ` [PATCH 18/20] ARM: pxa: register static mmp_pdma device Daniel Mack 2013-08-07 15:34 ` Daniel Mack 2013-08-07 15:34 ` [PATCH 19/20] ARM: mmp: " Daniel Mack 2013-08-07 15:34 ` Daniel Mack 2013-08-07 15:34 ` [PATCH 20/20] ARM: pxa: remove old DMA implementation Daniel Mack 2013-08-07 15:34 ` Daniel Mack 2013-08-07 16:08 ` [PATCH 00/20] ARM: pxa: move core and drivers to dmaengine Arnd Bergmann 2013-08-07 16:08 ` Arnd Bergmann 2013-08-09 22:50 ` Robert Jarzmik 2013-08-09 22:50 ` Robert Jarzmik 2013-08-10 10:56 ` Daniel Mack 2013-08-10 10:56 ` Daniel Mack 2013-08-11 20:05 ` Robert Jarzmik 2013-08-11 20:05 ` Robert Jarzmik 2013-08-14 10:00 ` Vinod Koul 2013-08-14 10:00 ` Vinod Koul 2013-08-15 15:22 ` Robert Jarzmik 2013-08-15 15:22 ` Robert Jarzmik 2013-08-15 15:30 ` Daniel Mack 2013-08-15 15:30 ` Daniel Mack 2013-12-10 9:24 [PATCH 08/20] mmc: host: pxamci: switch over to dmaengine use Sergei Ianovich [not found] <1375889649-14638-9-git-send-email-zonque> 2013-12-10 9:27 ` Sergei Ianovich 2013-12-10 10:25 ` Sergei Ianovich 2013-12-10 10:48 ` Daniel Mack 2013-12-10 15:04 ` Sergei Ianovich
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1375889649-14638-9-git-send-email-zonque@gmail.com \ --to=zonque@gmail.com \ --cc=arnd@arndb.de \ --cc=broonie@kernel.org \ --cc=cxie4@marvell.com \ --cc=davem@davemloft.net \ --cc=devicetree@vger.kernel.org \ --cc=djbw@fb.com \ --cc=eric.y.miao@gmail.com \ --cc=ezequiel.garcia@free-electrons.com \ --cc=g.liakhovetski@gmx.de \ --cc=gregkh@linuxfoundation.org \ --cc=haojian.zhuang@linaro.org \ --cc=kernel@pengutronix.de \ --cc=lars@metafoo.de \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-mtd@lists.infradead.org \ --cc=marek.vasut@gmail.com \ --cc=mark.rutland@arm.com \ --cc=mika.westerberg@linux.intel.com \ --cc=nico@linaro.org \ --cc=rmk+kernel@arm.linux.org.uk \ --cc=s.neumann@raumfeld.com \ --cc=sachin.kamat@linaro.org \ --cc=samuel@sortiz.org \ --cc=thomas.petazzoni@free-electrons.com \ --cc=vinod.koul@intel.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.