summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-08 11:02:21 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-08 11:02:21 -0700
commit2996148a9d4169f19a57827003c75605ce3b152b (patch)
tree77230462b98573fb87237ceafb086c1e7fe4c906 /drivers
parent18f1837632783fec017fd932a812d383e3406af0 (diff)
parent67f31971e7c221c1aff7bc023a724ae284c01a14 (diff)
Merge tag 'dmaengine-4.18-rc1' of git://git.infradead.org/users/vkoul/slave-dma
Pull dmaengine updates from Vinod Koul: - updates to sprd, bam_dma, stm drivers - remove VLAs in dmatest - move TI drivers to their own subdir - switch to SPDX tags for ima/mxs dma drivers - simplify getting .drvdata on bunch of drivers by Wolfram Sang * tag 'dmaengine-4.18-rc1' of git://git.infradead.org/users/vkoul/slave-dma: (32 commits) dmaengine: sprd: Add Spreadtrum DMA configuration dmaengine: sprd: Optimize the sprd_dma_prep_dma_memcpy() dmaengine: imx-dma: Switch to SPDX identifier dmaengine: mxs-dma: Switch to SPDX identifier dmaengine: imx-sdma: Switch to SPDX identifier dmaengine: usb-dmac: Document R8A7799{0,5} bindings dmaengine: qcom: bam_dma: fix some doc warnings. dmaengine: qcom: bam_dma: fix invalid assignment warning dmaengine: sprd: fix an NULL vs IS_ERR() bug dmaengine: sprd: Use devm_ioremap_resource() to map memory dmaengine: sprd: Fix potential NULL dereference in sprd_dma_probe() dmaengine: pl330: flush before wait, and add dev burst support. dmaengine: axi-dmac: Request IRQ with IRQF_SHARED dmaengine: stm32-mdma: fix spelling mistake: "avalaible" -> "available" dmaengine: rcar-dmac: Document R-Car D3 bindings dmaengine: sprd: Move DMA request mode and interrupt type into head file dmaengine: sprd: Define the DMA data width type dmaengine: sprd: Define the DMA transfer step type dmaengine: ti: New directory for Texas Instruments DMA drivers dmaengine: shdmac: Change platform check to CONFIG_ARCH_RENESAS ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dma/Kconfig31
-rw-r--r--drivers/dma/Makefile5
-rw-r--r--drivers/dma/at_hdmac.c9
-rw-r--r--drivers/dma/at_xdmac.c9
-rw-r--r--drivers/dma/dma-axi-dmac.c2
-rw-r--r--drivers/dma/dmatest.c16
-rw-r--r--drivers/dma/dw/platform.c6
-rw-r--r--drivers/dma/fsldma.c6
-rw-r--r--drivers/dma/idma64.c6
-rw-r--r--drivers/dma/imx-dma.c26
-rw-r--r--drivers/dma/imx-sdma.c29
-rw-r--r--drivers/dma/mxs-dma.c14
-rw-r--r--drivers/dma/pl330.c209
-rw-r--r--drivers/dma/qcom/bam_dma.c10
-rw-r--r--drivers/dma/qcom/hidma.c3
-rw-r--r--drivers/dma/qcom/hidma_mgmt_sys.c6
-rw-r--r--drivers/dma/sh/shdmac.c50
-rw-r--r--drivers/dma/sprd-dma.c349
-rw-r--r--drivers/dma/ste_dma40.c12
-rw-r--r--drivers/dma/stm32-mdma.c100
-rw-r--r--drivers/dma/ti/Kconfig37
-rw-r--r--drivers/dma/ti/Makefile5
-rw-r--r--drivers/dma/ti/cppi41.c (renamed from drivers/dma/cppi41.c)2
-rw-r--r--drivers/dma/ti/dma-crossbar.c (renamed from drivers/dma/ti-dma-crossbar.c)0
-rw-r--r--drivers/dma/ti/edma.c (renamed from drivers/dma/edma.c)4
-rw-r--r--drivers/dma/ti/omap-dma.c (renamed from drivers/dma/omap-dma.c)2
-rw-r--r--drivers/dma/txx9dmac.c8
27 files changed, 559 insertions, 397 deletions
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 6d61cd023633..ca1680afa20a 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -151,13 +151,6 @@ config DMA_JZ4780
If you have a board based on such a SoC and wish to use DMA for
devices which can use the DMA controller, say Y or M here.
-config DMA_OMAP
- tristate "OMAP DMA support"
- depends on ARCH_OMAP || COMPILE_TEST
- select DMA_ENGINE
- select DMA_VIRTUAL_CHANNELS
- select TI_DMA_CROSSBAR if (SOC_DRA7XX || COMPILE_TEST)
-
config DMA_SA11X0
tristate "SA-11x0 DMA support"
depends on ARCH_SA1100 || COMPILE_TEST
@@ -574,28 +567,6 @@ config TIMB_DMA
help
Enable support for the Timberdale FPGA DMA engine.
-config TI_CPPI41
- tristate "CPPI 4.1 DMA support"
- depends on (ARCH_OMAP || ARCH_DAVINCI_DA8XX)
- select DMA_ENGINE
- help
- The Communications Port Programming Interface (CPPI) 4.1 DMA engine
- is currently used by the USB driver on AM335x and DA8xx platforms.
-
-config TI_DMA_CROSSBAR
- bool
-
-config TI_EDMA
- bool "TI EDMA support"
- depends on ARCH_DAVINCI || ARCH_OMAP || ARCH_KEYSTONE || COMPILE_TEST
- select DMA_ENGINE
- select DMA_VIRTUAL_CHANNELS
- select TI_DMA_CROSSBAR if (ARCH_OMAP || COMPILE_TEST)
- default n
- help
- Enable support for the TI EDMA controller. This DMA
- engine is found on TI DaVinci and AM33xx parts.
-
config XGENE_DMA
tristate "APM X-Gene DMA support"
depends on ARCH_XGENE || COMPILE_TEST
@@ -653,6 +624,8 @@ source "drivers/dma/hsu/Kconfig"
source "drivers/dma/sh/Kconfig"
+source "drivers/dma/ti/Kconfig"
+
# clients
comment "DMA Clients"
depends on DMA_ENGINE
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 0f62a4d49aab..203a99d68315 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -24,7 +24,6 @@ obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o
obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o
obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
obj-$(CONFIG_DMA_JZ4780) += dma-jz4780.o
-obj-$(CONFIG_DMA_OMAP) += omap-dma.o
obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
obj-$(CONFIG_DMA_SUN4I) += sun4i-dma.o
obj-$(CONFIG_DMA_SUN6I) += sun6i-dma.o
@@ -69,13 +68,11 @@ obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o
obj-$(CONFIG_TEGRA210_ADMA) += tegra210-adma.o
obj-$(CONFIG_TIMB_DMA) += timb_dma.o
-obj-$(CONFIG_TI_CPPI41) += cppi41.o
-obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma-crossbar.o
-obj-$(CONFIG_TI_EDMA) += edma.o
obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
obj-$(CONFIG_ZX_DMA) += zx_dma.o
obj-$(CONFIG_ST_FDMA) += st_fdma.o
obj-y += mediatek/
obj-y += qcom/
+obj-y += ti/
obj-y += xilinx/
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index a861b5b4d443..75f38d19fcbe 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -2041,8 +2041,7 @@ static void at_dma_shutdown(struct platform_device *pdev)
static int at_dma_prepare(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct at_dma *atdma = platform_get_drvdata(pdev);
+ struct at_dma *atdma = dev_get_drvdata(dev);
struct dma_chan *chan, *_chan;
list_for_each_entry_safe(chan, _chan, &atdma->dma_common.channels,
@@ -2076,8 +2075,7 @@ static void atc_suspend_cyclic(struct at_dma_chan *atchan)
static int at_dma_suspend_noirq(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct at_dma *atdma = platform_get_drvdata(pdev);
+ struct at_dma *atdma = dev_get_drvdata(dev);
struct dma_chan *chan, *_chan;
/* preserve data */
@@ -2118,8 +2116,7 @@ static void atc_resume_cyclic(struct at_dma_chan *atchan)
static int at_dma_resume_noirq(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct at_dma *atdma = platform_get_drvdata(pdev);
+ struct at_dma *atdma = dev_get_drvdata(dev);
struct dma_chan *chan, *_chan;
/* bring back DMA controller */
diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index 94236ec9d410..4bf72561667c 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -1833,8 +1833,7 @@ static void at_xdmac_free_chan_resources(struct dma_chan *chan)
#ifdef CONFIG_PM
static int atmel_xdmac_prepare(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct at_xdmac *atxdmac = platform_get_drvdata(pdev);
+ struct at_xdmac *atxdmac = dev_get_drvdata(dev);
struct dma_chan *chan, *_chan;
list_for_each_entry_safe(chan, _chan, &atxdmac->dma.channels, device_node) {
@@ -1853,8 +1852,7 @@ static int atmel_xdmac_prepare(struct device *dev)
#ifdef CONFIG_PM_SLEEP
static int atmel_xdmac_suspend(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct at_xdmac *atxdmac = platform_get_drvdata(pdev);
+ struct at_xdmac *atxdmac = dev_get_drvdata(dev);
struct dma_chan *chan, *_chan;
list_for_each_entry_safe(chan, _chan, &atxdmac->dma.channels, device_node) {
@@ -1878,8 +1876,7 @@ static int atmel_xdmac_suspend(struct device *dev)
static int atmel_xdmac_resume(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct at_xdmac *atxdmac = platform_get_drvdata(pdev);
+ struct at_xdmac *atxdmac = dev_get_drvdata(dev);
struct at_xdmac_chan *atchan;
struct dma_chan *chan, *_chan;
int i;
diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
index 2419fe524daa..15b2453d2647 100644
--- a/drivers/dma/dma-axi-dmac.c
+++ b/drivers/dma/dma-axi-dmac.c
@@ -687,7 +687,7 @@ static int axi_dmac_probe(struct platform_device *pdev)
if (ret)
goto err_unregister_device;
- ret = request_irq(dmac->irq, axi_dmac_interrupt_handler, 0,
+ ret = request_irq(dmac->irq, axi_dmac_interrupt_handler, IRQF_SHARED,
dev_name(&pdev->dev), dmac);
if (ret)
goto err_unregister_of;
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index b9339524d5bd..aa1712beb0cc 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -468,6 +468,8 @@ static int dmatest_func(void *data)
unsigned long long total_len = 0;
u8 align = 0;
bool is_memset = false;
+ dma_addr_t *srcs;
+ dma_addr_t *dma_pq;
set_freezable();
@@ -551,6 +553,14 @@ static int dmatest_func(void *data)
set_user_nice(current, 10);
+ srcs = kcalloc(src_cnt, sizeof(dma_addr_t), GFP_KERNEL);
+ if (!srcs)
+ goto err_dstbuf;
+
+ dma_pq = kcalloc(dst_cnt, sizeof(dma_addr_t), GFP_KERNEL);
+ if (!dma_pq)
+ goto err_srcs_array;
+
/*
* src and dst buffers are freed by ourselves below
*/
@@ -561,7 +571,6 @@ static int dmatest_func(void *data)
&& !(params->iterations && total_tests >= params->iterations)) {
struct dma_async_tx_descriptor *tx = NULL;
struct dmaengine_unmap_data *um;
- dma_addr_t srcs[src_cnt];
dma_addr_t *dsts;
unsigned int src_off, dst_off, len;
@@ -676,8 +685,6 @@ static int dmatest_func(void *data)
srcs, src_cnt,
len, flags);
else if (thread->type == DMA_PQ) {
- dma_addr_t dma_pq[dst_cnt];
-
for (i = 0; i < dst_cnt; i++)
dma_pq[i] = dsts[i] + dst_off;
tx = dev->device_prep_dma_pq(chan, dma_pq, srcs,
@@ -779,6 +786,9 @@ static int dmatest_func(void *data)
runtime = ktime_to_us(ktime);
ret = 0;
+ kfree(dma_pq);
+err_srcs_array:
+ kfree(srcs);
err_dstbuf:
for (i = 0; thread->udsts[i]; i++)
kfree(thread->udsts[i]);
diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c
index bc31fe802061..f62dd0944908 100644
--- a/drivers/dma/dw/platform.c
+++ b/drivers/dma/dw/platform.c
@@ -293,8 +293,7 @@ MODULE_DEVICE_TABLE(acpi, dw_dma_acpi_id_table);
static int dw_suspend_late(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct dw_dma_chip *chip = platform_get_drvdata(pdev);
+ struct dw_dma_chip *chip = dev_get_drvdata(dev);
dw_dma_disable(chip);
clk_disable_unprepare(chip->clk);
@@ -304,8 +303,7 @@ static int dw_suspend_late(struct device *dev)
static int dw_resume_early(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct dw_dma_chip *chip = platform_get_drvdata(pdev);
+ struct dw_dma_chip *chip = dev_get_drvdata(dev);
int ret;
ret = clk_prepare_enable(chip->clk);
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 3eaece888e75..1117b5123a6f 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -1328,8 +1328,7 @@ static int fsldma_of_remove(struct platform_device *op)
#ifdef CONFIG_PM
static int fsldma_suspend_late(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct fsldma_device *fdev = platform_get_drvdata(pdev);
+ struct fsldma_device *fdev = dev_get_drvdata(dev);
struct fsldma_chan *chan;
int i;
@@ -1360,8 +1359,7 @@ out:
static int fsldma_resume_early(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct fsldma_device *fdev = platform_get_drvdata(pdev);
+ struct fsldma_device *fdev = dev_get_drvdata(dev);
struct fsldma_chan *chan;
u32 mode;
int i;
diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c
index 1953e57505f4..e5c911200bdb 100644
--- a/drivers/dma/idma64.c
+++ b/drivers/dma/idma64.c
@@ -670,8 +670,7 @@ static int idma64_platform_remove(struct platform_device *pdev)
static int idma64_pm_suspend(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct idma64_chip *chip = platform_get_drvdata(pdev);
+ struct idma64_chip *chip = dev_get_drvdata(dev);
idma64_off(chip->idma64);
return 0;
@@ -679,8 +678,7 @@ static int idma64_pm_suspend(struct device *dev)
static int idma64_pm_resume(struct device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct idma64_chip *chip = platform_get_drvdata(pdev);
+ struct idma64_chip *chip = dev_get_drvdata(dev);
idma64_on(chip->idma64);
return 0;
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index 715b39ae5a46..75b6ff0415ee 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -1,19 +1,13 @@
-/*
- * drivers/dma/imx-dma.c
- *
- * This file contains a driver for the Freescale i.MX DMA engine
- * found on i.MX1/21/27
- *
- * Copyright 2010 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
- * Copyright 2012 Javier Martin, Vista Silicon <javier.martin@vista-silicon.com>
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
+// SPDX-License-Identifier: GPL-2.0+
+//
+// drivers/dma/imx-dma.c
+//
+// This file contains a driver for the Freescale i.MX DMA engine
+// found on i.MX1/21/27
+//
+// Copyright 2010 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+// Copyright 2012 Javier Martin, Vista Silicon <javier.martin@vista-silicon.com>
+
#include <linux/err.h>
#include <linux/init.h>
#include <linux/types.h>
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index ccd03c3cedfe..f077992635c2 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -1,21 +1,14 @@
-/*
- * drivers/dma/imx-sdma.c
- *
- * This file contains a driver for the Freescale Smart DMA engine
- *
- * Copyright 2010 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
- *
- * Based on code from Freescale:
- *
- * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
+// SPDX-License-Identifier: GPL-2.0+
+//
+// drivers/dma/imx-sdma.c
+//
+// This file contains a driver for the Freescale Smart DMA engine
+//
+// Copyright 2010 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+//
+// Based on code from Freescale:
+//
+// Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
#include <linux/init.h>
#include <linux/iopoll.h>
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 41d167921fab..ae5182ff0128 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -1,12 +1,8 @@
-/*
- * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * Refer to drivers/dma/imx-sdma.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+//
+// Refer to drivers/dma/imx-sdma.c
#include <linux/init.h>
#include <linux/types.h>
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index de1fd59fe136..6237069001c4 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -27,6 +27,7 @@
#include <linux/of_dma.h>
#include <linux/err.h>
#include <linux/pm_runtime.h>
+#include <linux/bug.h>
#include "dmaengine.h"
#define PL330_MAX_CHAN 8
@@ -1094,51 +1095,96 @@ static inline int _ldst_memtomem(unsigned dry_run, u8 buf[],
return off;
}
-static inline int _ldst_devtomem(struct pl330_dmac *pl330, unsigned dry_run,
- u8 buf[], const struct _xfer_spec *pxs,
- int cyc)
+static u32 _emit_load(unsigned int dry_run, u8 buf[],
+ enum pl330_cond cond, enum dma_transfer_direction direction,
+ u8 peri)
{
int off = 0;
- enum pl330_cond cond;
- if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)
- cond = BURST;
- else
- cond = SINGLE;
+ switch (direction) {
+ case DMA_MEM_TO_MEM:
+ /* fall through */
+ case DMA_MEM_TO_DEV:
+ off += _emit_LD(dry_run, &buf[off], cond);
+ break;
- while (cyc--) {
- off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
- off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri);
- off += _emit_ST(dry_run, &buf[off], ALWAYS);
+ case DMA_DEV_TO_MEM:
+ if (cond == ALWAYS) {
+ off += _emit_LDP(dry_run, &buf[off], SINGLE,
+ peri);
+ off += _emit_LDP(dry_run, &buf[off], BURST,
+ peri);
+ } else {
+ off += _emit_LDP(dry_run, &buf[off], cond,
+ peri);
+ }
+ break;
- if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
- off += _emit_FLUSHP(dry_run, &buf[off],
- pxs->desc->peri);
+ default:
+ /* this code should be unreachable */
+ WARN_ON(1);
+ break;
}
return off;
}
-static inline int _ldst_memtodev(struct pl330_dmac *pl330,
+static inline u32 _emit_store(unsigned int dry_run, u8 buf[],
+ enum pl330_cond cond, enum dma_transfer_direction direction,
+ u8 peri)
+{
+ int off = 0;
+
+ switch (direction) {
+ case DMA_MEM_TO_MEM:
+ /* fall through */
+ case DMA_DEV_TO_MEM:
+ off += _emit_ST(dry_run, &buf[off], cond);
+ break;
+
+ case DMA_MEM_TO_DEV:
+ if (cond == ALWAYS) {
+ off += _emit_STP(dry_run, &buf[off], SINGLE,
+ peri);
+ off += _emit_STP(dry_run, &buf[off], BURST,
+ peri);
+ } else {
+ off += _emit_STP(dry_run, &buf[off], cond,
+ peri);
+ }
+ break;
+
+ default:
+ /* this code should be unreachable */
+ WARN_ON(1);
+ break;
+ }
+
+ return off;
+}
+
+static inline int _ldst_peripheral(struct pl330_dmac *pl330,
unsigned dry_run, u8 buf[],
- const struct _xfer_spec *pxs, int cyc)
+ const struct _xfer_spec *pxs, int cyc,
+ enum pl330_cond cond)
{
int off = 0;
- enum pl330_cond cond;
if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)
cond = BURST;
- else
- cond = SINGLE;
+ /*
+ * do FLUSHP at beginning to clear any stale dma requests before the
+ * first WFP.
+ */
+ if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
+ off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
while (cyc--) {
off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
- off += _emit_LD(dry_run, &buf[off], ALWAYS);
- off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri);
-
- if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
- off += _emit_FLUSHP(dry_run, &buf[off],
- pxs->desc->peri);
+ off += _emit_load(dry_run, &buf[off], cond, pxs->desc->rqtype,
+ pxs->desc->peri);
+ off += _emit_store(dry_run, &buf[off], cond, pxs->desc->rqtype,
+ pxs->desc->peri);
}
return off;
@@ -1148,19 +1194,65 @@ static int _bursts(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[],
const struct _xfer_spec *pxs, int cyc)
{
int off = 0;
+ enum pl330_cond cond = BRST_LEN(pxs->ccr) > 1 ? BURST : SINGLE;
switch (pxs->desc->rqtype) {
case DMA_MEM_TO_DEV:
- off += _ldst_memtodev(pl330, dry_run, &buf[off], pxs, cyc);
- break;
+ /* fall through */
case DMA_DEV_TO_MEM:
- off += _ldst_devtomem(pl330, dry_run, &buf[off], pxs, cyc);
+ off += _ldst_peripheral(pl330, dry_run, &buf[off], pxs, cyc,
+ cond);
break;
+
case DMA_MEM_TO_MEM:
off += _ldst_memtomem(dry_run, &buf[off], pxs, cyc);
break;
+
+ default:
+ /* this code should be unreachable */
+ WARN_ON(1);
+ break;
+ }
+
+ return off;
+}
+
+/*
+ * transfer dregs with single transfers to peripheral, or a reduced size burst
+ * for mem-to-mem.
+ */
+static int _dregs(struct pl330_dmac *pl330, unsigned int dry_run, u8 buf[],
+ const struct _xfer_spec *pxs, int transfer_length)
+{
+ int off = 0;
+ int dregs_ccr;
+
+ if (transfer_length == 0)
+ return off;
+
+ switch (pxs->desc->rqtype) {
+ case DMA_MEM_TO_DEV:
+ /* fall through */
+ case DMA_DEV_TO_MEM:
+ off += _ldst_peripheral(pl330, dry_run, &buf[off], pxs,
+ transfer_length, SINGLE);
+ break;
+
+ case DMA_MEM_TO_MEM:
+ dregs_ccr = pxs->ccr;
+ dregs_ccr &= ~((0xf << CC_SRCBRSTLEN_SHFT) |
+ (0xf << CC_DSTBRSTLEN_SHFT));
+ dregs_ccr |= (((transfer_length - 1) & 0xf) <<
+ CC_SRCBRSTLEN_SHFT);
+ dregs_ccr |= (((transfer_length - 1) & 0xf) <<
+ CC_DSTBRSTLEN_SHFT);
+ off += _emit_MOV(dry_run, &buf[off], CCR, dregs_ccr);
+ off += _ldst_memtomem(dry_run, &buf[off], pxs, 1);
+ break;
+
default:
- off += 0x40000000; /* Scare off the Client */
+ /* this code should be unreachable */
+ WARN_ON(1);
break;
}
@@ -1256,6 +1348,8 @@ static inline int _setup_loops(struct pl330_dmac *pl330,
struct pl330_xfer *x = &pxs->desc->px;
u32 ccr = pxs->ccr;
unsigned long c, bursts = BYTE_TO_BURST(x->bytes, ccr);
+ int num_dregs = (x->bytes - BURST_TO_BYTE(bursts, ccr)) /
+ BRST_SIZE(ccr);
int off = 0;
while (bursts) {
@@ -1263,6 +1357,7 @@ static inline int _setup_loops(struct pl330_dmac *pl330,
off += _loop(pl330, dry_run, &buf[off], &c, pxs);
bursts -= c;
}
+ off += _dregs(pl330, dry_run, &buf[off], pxs, num_dregs);
return off;
}
@@ -1294,7 +1389,6 @@ static int _setup_req(struct pl330_dmac *pl330, unsigned dry_run,
struct _xfer_spec *pxs)
{
struct _pl330_req *req = &thrd->req[index];
- struct pl330_xfer *x;
u8 *buf = req->mc_cpu;
int off = 0;
@@ -1303,11 +1397,6 @@ static int _setup_req(struct pl330_dmac *pl330, unsigned dry_run,
/* DMAMOV CCR, ccr */
off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr);
- x = &pxs->desc->px;
- /* Error if xfer length is not aligned at burst size */
- if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr)))
- return -EINVAL;
-
off += _setup_xfer(pl330, dry_run, &buf[off], pxs);
/* DMASEV peripheral/event */
@@ -1365,6 +1454,20 @@ static int pl330_submit_req(struct pl330_thread *thrd,
u32 ccr;
int ret = 0;
+ switch (desc->rqtype) {
+ case DMA_MEM_TO_DEV:
+ break;
+
+ case DMA_DEV_TO_MEM:
+ break;
+
+ case DMA_MEM_TO_MEM:
+ break;
+
+ default:
+ return -ENOTSUPP;
+ }
+
if (pl330->state == DYING
|| pl330->dmac_tbd.reset_chan & (1 << thrd->id)) {
dev_info(thrd->dmac->ddma.dev, "%s:%d\n",
@@ -2106,6 +2209,18 @@ static bool pl330_prep_slave_fifo(struct dma_pl330_chan *pch,
return true;
}
+static int fixup_burst_len(int max_burst_len, int quirks)
+{
+ if (quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)
+ return 1;
+ else if (max_burst_len > PL330_MAX_BURST)
+ return PL330_MAX_BURST;
+ else if (max_burst_len < 1)
+ return 1;
+ else
+ return max_burst_len;
+}
+
static int pl330_config(struct dma_chan *chan,
struct dma_slave_config *slave_config)
{
@@ -2117,15 +2232,15 @@ static int pl330_config(struct dma_chan *chan,
pch->fifo_addr = slave_config->dst_addr;
if (slave_config->dst_addr_width)
pch->burst_sz = __ffs(slave_config->dst_addr_width);
- if (slave_config->dst_maxburst)
- pch->burst_len = slave_config->dst_maxburst;
+ pch->burst_len = fixup_burst_len(slave_config->dst_maxburst,
+ pch->dmac->quirks);
} else if (slave_config->direction == DMA_DEV_TO_MEM) {
if (slave_config->src_addr)
pch->fifo_addr = slave_config->src_addr;
if (slave_config->src_addr_width)
pch->burst_sz = __ffs(slave_config->src_addr_width);
- if (slave_config->src_maxburst)
- pch->burst_len = slave_config->src_maxburst;
+ pch->burst_len = fixup_burst_len(slave_config->src_maxburst,
+ pch->dmac->quirks);
}
return 0;
@@ -2519,14 +2634,8 @@ static inline int get_burst_len(struct dma_pl330_desc *desc, size_t len)
burst_len >>= desc->rqcfg.brst_size;
/* src/dst_burst_len can't be more than 16 */
- if (burst_len > 16)
- burst_len = 16;
-
- while (burst_len > 1) {
- if (!(len % (burst_len << desc->rqcfg.brst_size)))
- break;
- burst_len--;
- }
+ if (burst_len > PL330_MAX_BURST)
+ burst_len = PL330_MAX_BURST;
return burst_len;
}
@@ -2598,7 +2707,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
desc->rqtype = direction;
desc->rqcfg.brst_size = pch->burst_sz;
- desc->rqcfg.brst_len = 1;
+ desc->rqcfg.brst_len = pch->burst_len;
desc->bytes_requested = period_len;
fill_px(&desc->px, dst, src, period_len);
@@ -2743,7 +2852,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
}
desc->rqcfg.brst_size = pch->burst_sz;
- desc->rqcfg.brst_len = 1;
+ desc->rqcfg.brst_len = pch->burst_len;
desc->rqtype = direction;
desc->bytes_requested = sg_dma_len(sg);
}
diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index 4a828c18099a..1617715aa6e0 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -451,6 +451,7 @@ static void bam_reset_channel(struct bam_chan *bchan)
/**
* bam_chan_init_hw - Initialize channel hardware
* @bchan: bam channel
+ * @dir: DMA transfer direction
*
* This function resets and initializes the BAM channel
*/
@@ -673,7 +674,7 @@ static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan,
remainder = 0;
}
- async_desc->length += desc->size;
+ async_desc->length += le16_to_cpu(desc->size);
desc++;
} while (remainder > 0);
}
@@ -687,7 +688,7 @@ err_out:
/**
* bam_dma_terminate_all - terminate all transactions on a channel
- * @bchan: bam dma channel
+ * @chan: bam dma channel
*
* Dequeues and frees all transactions
* No callbacks are done
@@ -918,7 +919,8 @@ static enum dma_status bam_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
continue;
for (i = 0; i < async_desc->num_desc; i++)
- residue += async_desc->curr_desc[i].size;
+ residue += le16_to_cpu(
+ async_desc->curr_desc[i].size);
}
}
@@ -958,7 +960,7 @@ static void bam_apply_new_config(struct bam_chan *bchan,
/**
* bam_start_dma - start next transaction
- * @bchan - bam dma channel
+ * @bchan: bam dma channel
*/
static void bam_start_dma(struct bam_chan *bchan)
{
diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c
index 963cc5228d05..43d4b00b8138 100644
--- a/drivers/dma/qcom/hidma.c
+++ b/drivers/dma/qcom/hidma.c
@@ -616,8 +616,7 @@ static irqreturn_t hidma_chirq_handler_msi(int chirq, void *arg)
static ssize_t hidma_show_values(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct hidma_dev *mdev = platform_get_drvdata(pdev);
+ struct hidma_dev *mdev = dev_get_drvdata(dev);
buf[0] = 0;
diff --git a/drivers/dma/qcom/hidma_mgmt_sys.c b/drivers/dma/qcom/hidma_mgmt_sys.c
index d61f1068a34b..cbb89eafd844 100644
--- a/drivers/dma/qcom/hidma_mgmt_sys.c
+++ b/drivers/dma/qcom/hidma_mgmt_sys.c
@@ -107,8 +107,7 @@ static struct hidma_mgmt_fileinfo hidma_mgmt_files[] = {
static ssize_t show_values(struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct hidma_mgmt_dev *mdev = platform_get_drvdata(pdev);
+ struct hidma_mgmt_dev *mdev = dev_get_drvdata(dev);
unsigned int i;
buf[0] = 0;
@@ -125,8 +124,7 @@ static ssize_t show_values(struct device *dev, struct device_attribute *attr,
static ssize_t set_values(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct hidma_mgmt_dev *mdev = platform_get_drvdata(pdev);
+ struct hidma_mgmt_dev *mdev = dev_get_drvdata(dev);
unsigned long tmp;
unsigned int i;
int rc;
diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c
index c94ffab0d25c..04a74e0a95b7 100644
--- a/drivers/dma/sh/shdmac.c
+++ b/drivers/dma/sh/shdmac.c
@@ -443,7 +443,6 @@ static bool sh_dmae_reset(struct sh_dmae_device *shdev)
return ret;
}
-#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
static irqreturn_t sh_dmae_err(int irq, void *data)
{
struct sh_dmae_device *shdev = data;
@@ -454,7 +453,6 @@ static irqreturn_t sh_dmae_err(int irq, void *data)
sh_dmae_reset(shdev);
return IRQ_HANDLED;
}
-#endif