public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 0/4] dw_dmac: move to own folder and split
@ 2013-06-04 12:36 Andy Shevchenko
  2013-06-04 12:36 ` [PATCH v1 1/4] dw_dmac: don't check resource with devm_ioremap_resource Andy Shevchenko
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Andy Shevchenko @ 2013-06-04 12:36 UTC (permalink / raw)
  To: Vinod Koul, linux-kernel, spear-devel, viresh.kumar,
	Arnd Bergmann, Felipe Balbi
  Cc: Andy Shevchenko

This is second attempt to do split as suggested by Arnd et al [1,2].
There are three most important patches:
 2/4 moves driver to its own folder
 3/4 does the actual split
 4/4 introduces PCI part of the driver

During this files are renamed: mostly means that dw_dmac prefix is eliminated.
I hope to get it ready to be included in v3.11.

[1] http://www.spinics.net/lists/kernel/msg1408174.html
[2] http://www.spinics.net/lists/kernel/msg1408495.html

P.S. Viresh, I didn't apply your Ack to the 3/4, because I amended it a bit: I
moved dwc_get_{s,d}ms to the "internal.h" as it shared between core.c and
platform.c.

Cnages v0->v1:
 - apply Viresh's ACKs
 - append PCI part of the driver
 - test altogether on Intel Medfield
 - add 1/4 to the series as it based on it, but Vinod didn't apply it yet to
   his tree.

Andy Shevchenko (4):
  dw_dmac: don't check resource with devm_ioremap_resource
  dma: move dw_dmac driver to an own directory
  dma: dw: split driver to library part and platform code
  dma: dw: add PCI part of the driver

 MAINTAINERS                               |   3 +-
 drivers/dma/Kconfig                       |  20 +-
 drivers/dma/Makefile                      |   2 +-
 drivers/dma/dw/Kconfig                    |  36 ++++
 drivers/dma/dw/Makefile                   |   8 +
 drivers/dma/{dw_dmac.c => dw/core.c}      | 314 ++++--------------------------
 drivers/dma/dw/internal.h                 |  74 +++++++
 drivers/dma/dw/pci.c                      | 101 ++++++++++
 drivers/dma/dw/platform.c                 | 308 +++++++++++++++++++++++++++++
 drivers/dma/{dw_dmac_regs.h => dw/regs.h} |   1 +
 10 files changed, 565 insertions(+), 302 deletions(-)
 create mode 100644 drivers/dma/dw/Kconfig
 create mode 100644 drivers/dma/dw/Makefile
 rename drivers/dma/{dw_dmac.c => dw/core.c} (85%)
 create mode 100644 drivers/dma/dw/internal.h
 create mode 100644 drivers/dma/dw/pci.c
 create mode 100644 drivers/dma/dw/platform.c
 rename drivers/dma/{dw_dmac_regs.h => dw/regs.h} (99%)

-- 
1.8.2.rc0.22.gb3600c3


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v1 1/4] dw_dmac: don't check resource with devm_ioremap_resource
  2013-06-04 12:36 [PATCH v1 0/4] dw_dmac: move to own folder and split Andy Shevchenko
@ 2013-06-04 12:36 ` Andy Shevchenko
  2013-06-04 12:36 ` [PATCH v1 2/4] dma: move dw_dmac driver to an own directory Andy Shevchenko
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Andy Shevchenko @ 2013-06-04 12:36 UTC (permalink / raw)
  To: Vinod Koul, linux-kernel, spear-devel, viresh.kumar,
	Arnd Bergmann, Felipe Balbi
  Cc: Andy Shevchenko

devm_ioremap_resource does sanity checks on the given resource. No need to
duplicate this in the driver.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/dma/dw_dmac.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 724083d..2b65ba6 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -1667,14 +1667,11 @@ static int dw_probe(struct platform_device *pdev)
 	int			err;
 	int			i;
 
-	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!io)
-		return -EINVAL;
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0)
 		return irq;
 
+	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	regs = devm_ioremap_resource(&pdev->dev, io);
 	if (IS_ERR(regs))
 		return PTR_ERR(regs);
-- 
1.8.2.rc0.22.gb3600c3


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v1 2/4] dma: move dw_dmac driver to an own directory
  2013-06-04 12:36 [PATCH v1 0/4] dw_dmac: move to own folder and split Andy Shevchenko
  2013-06-04 12:36 ` [PATCH v1 1/4] dw_dmac: don't check resource with devm_ioremap_resource Andy Shevchenko
@ 2013-06-04 12:36 ` Andy Shevchenko
  2013-06-04 12:36 ` [PATCH v1 3/4] dma: dw: split driver to library part and platform code Andy Shevchenko
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Andy Shevchenko @ 2013-06-04 12:36 UTC (permalink / raw)
  To: Vinod Koul, linux-kernel, spear-devel, viresh.kumar,
	Arnd Bergmann, Felipe Balbi
  Cc: Andy Shevchenko

The dw_dmac driver is going to be split into multiple files. To make this more
convenient move it to an own directory.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 MAINTAINERS                         |  3 +--
 drivers/dma/Kconfig                 | 20 +-------------------
 drivers/dma/Makefile                |  2 +-
 drivers/dma/dw/Kconfig              | 23 +++++++++++++++++++++++
 drivers/dma/dw/Makefile             |  1 +
 drivers/dma/{ => dw}/dw_dmac.c      |  2 +-
 drivers/dma/{ => dw}/dw_dmac_regs.h |  0
 7 files changed, 28 insertions(+), 23 deletions(-)
 create mode 100644 drivers/dma/dw/Kconfig
 create mode 100644 drivers/dma/dw/Makefile
 rename drivers/dma/{ => dw}/dw_dmac.c (99%)
 rename drivers/dma/{ => dw}/dw_dmac_regs.h (100%)

diff --git a/MAINTAINERS b/MAINTAINERS
index c488924..e0b03a9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6995,8 +6995,7 @@ SYNOPSYS DESIGNWARE DMAC DRIVER
 M:	Viresh Kumar <viresh.linux@gmail.com>
 S:	Maintained
 F:	include/linux/dw_dmac.h
-F:	drivers/dma/dw_dmac_regs.h
-F:	drivers/dma/dw_dmac.c
+F:	drivers/dma/dw/
 
 SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER
 M:	Seungwon Jeon <tgih.jun@samsung.com>
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index e992489..146a1d8 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -79,25 +79,7 @@ config INTEL_IOP_ADMA
 	help
 	  Enable support for the Intel(R) IOP Series RAID engines.
 
-config DW_DMAC
-	tristate "Synopsys DesignWare AHB DMA support"
-	depends on GENERIC_HARDIRQS
-	select DMA_ENGINE
-	default y if CPU_AT32AP7000
-	help
-	  Support the Synopsys DesignWare AHB DMA controller.  This
-	  can be integrated in chips such as the Atmel AT32ap7000.
-
-config DW_DMAC_BIG_ENDIAN_IO
-	bool "Use big endian I/O register access"
-	default y if AVR32
-	depends on DW_DMAC
-	help
-	  Say yes here to use big endian I/O access when reading and writing
-	  to the DMA controller registers. This is needed on some platforms,
-	  like the Atmel AVR32 architecture.
-
-	  If unsure, use the default setting.
+source "drivers/dma/dw/Kconfig"
 
 config AT_HDMAC
 	tristate "Atmel AHB DMA support"
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index a2b0df5..ac44ca0 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_FSL_DMA) += fsldma.o
 obj-$(CONFIG_MPC512X_DMA) += mpc512x_dma.o
 obj-$(CONFIG_PPC_BESTCOMM) += bestcomm/
 obj-$(CONFIG_MV_XOR) += mv_xor.o
-obj-$(CONFIG_DW_DMAC) += dw_dmac.o
+obj-$(CONFIG_DW_DMAC) += dw/
 obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
 obj-$(CONFIG_MX3_IPU) += ipu/
 obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
diff --git a/drivers/dma/dw/Kconfig b/drivers/dma/dw/Kconfig
new file mode 100644
index 0000000..38a215a
--- /dev/null
+++ b/drivers/dma/dw/Kconfig
@@ -0,0 +1,23 @@
+#
+# DMA engine configuration for dw
+#
+
+config DW_DMAC
+	tristate "Synopsys DesignWare AHB DMA support"
+	depends on GENERIC_HARDIRQS
+	select DMA_ENGINE
+	default y if CPU_AT32AP7000
+	help
+	  Support the Synopsys DesignWare AHB DMA controller. This
+	  can be integrated in chips such as the Atmel AT32ap7000.
+
+config DW_DMAC_BIG_ENDIAN_IO
+	bool "Use big endian I/O register access"
+	default y if AVR32
+	depends on DW_DMAC
+	help
+	  Say yes here to use big endian I/O access when reading and writing
+	  to the DMA controller registers. This is needed on some platforms,
+	  like the Atmel AVR32 architecture.
+
+	  If unsure, use the default setting.
diff --git a/drivers/dma/dw/Makefile b/drivers/dma/dw/Makefile
new file mode 100644
index 0000000..dd8d993
--- /dev/null
+++ b/drivers/dma/dw/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_DW_DMAC) += dw_dmac.o
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw/dw_dmac.c
similarity index 99%
rename from drivers/dma/dw_dmac.c
rename to drivers/dma/dw/dw_dmac.c
index 2b65ba6..15f3f4f 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw/dw_dmac.c
@@ -28,8 +28,8 @@
 #include <linux/acpi.h>
 #include <linux/acpi_dma.h>
 
+#include "../dmaengine.h"
 #include "dw_dmac_regs.h"
-#include "dmaengine.h"
 
 /*
  * This supports the Synopsys "DesignWare AHB Central DMA Controller",
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw/dw_dmac_regs.h
similarity index 100%
rename from drivers/dma/dw_dmac_regs.h
rename to drivers/dma/dw/dw_dmac_regs.h
-- 
1.8.2.rc0.22.gb3600c3


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v1 3/4] dma: dw: split driver to library part and platform code
  2013-06-04 12:36 [PATCH v1 0/4] dw_dmac: move to own folder and split Andy Shevchenko
  2013-06-04 12:36 ` [PATCH v1 1/4] dw_dmac: don't check resource with devm_ioremap_resource Andy Shevchenko
  2013-06-04 12:36 ` [PATCH v1 2/4] dma: move dw_dmac driver to an own directory Andy Shevchenko
@ 2013-06-04 12:36 ` Andy Shevchenko
  2013-06-04 13:00   ` Arnd Bergmann
  2013-06-05  8:45   ` Viresh Kumar
  2013-06-04 12:36 ` [PATCH v1 4/4] dma: dw: add PCI part of the driver Andy Shevchenko
  2013-06-04 13:01 ` [PATCH v1 0/4] dw_dmac: move to own folder and split Arnd Bergmann
  4 siblings, 2 replies; 10+ messages in thread
From: Andy Shevchenko @ 2013-06-04 12:36 UTC (permalink / raw)
  To: Vinod Koul, linux-kernel, spear-devel, viresh.kumar,
	Arnd Bergmann, Felipe Balbi
  Cc: Andy Shevchenko

To simplify the driver development let's split driver to library and platform
code parts. It helps us to add PCI driver in future.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/Makefile                      |   2 +-
 drivers/dma/dw/Kconfig                    |   8 +-
 drivers/dma/dw/Makefile                   |   6 +-
 drivers/dma/dw/{dw_dmac.c => core.c}      | 309 ++++--------------------------
 drivers/dma/dw/internal.h                 |  74 +++++++
 drivers/dma/dw/platform.c                 | 308 +++++++++++++++++++++++++++++
 drivers/dma/dw/{dw_dmac_regs.h => regs.h} |   1 +
 7 files changed, 428 insertions(+), 280 deletions(-)
 rename drivers/dma/dw/{dw_dmac.c => core.c} (85%)
 create mode 100644 drivers/dma/dw/internal.h
 create mode 100644 drivers/dma/dw/platform.c
 rename drivers/dma/dw/{dw_dmac_regs.h => regs.h} (99%)

diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index ac44ca0..6e2a521 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_FSL_DMA) += fsldma.o
 obj-$(CONFIG_MPC512X_DMA) += mpc512x_dma.o
 obj-$(CONFIG_PPC_BESTCOMM) += bestcomm/
 obj-$(CONFIG_MV_XOR) += mv_xor.o
-obj-$(CONFIG_DW_DMAC) += dw/
+obj-$(CONFIG_DW_DMAC_CORE) += dw/
 obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
 obj-$(CONFIG_MX3_IPU) += ipu/
 obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
diff --git a/drivers/dma/dw/Kconfig b/drivers/dma/dw/Kconfig
index 38a215a..efd9e02 100644
--- a/drivers/dma/dw/Kconfig
+++ b/drivers/dma/dw/Kconfig
@@ -2,10 +2,14 @@
 # DMA engine configuration for dw
 #
 
-config DW_DMAC
+config DW_DMAC_CORE
 	tristate "Synopsys DesignWare AHB DMA support"
 	depends on GENERIC_HARDIRQS
 	select DMA_ENGINE
+
+config DW_DMAC
+	tristate "Synopsys DesignWare AHB DMA platform driver"
+	select DW_DMAC_CORE
 	default y if CPU_AT32AP7000
 	help
 	  Support the Synopsys DesignWare AHB DMA controller. This
@@ -14,7 +18,7 @@ config DW_DMAC
 config DW_DMAC_BIG_ENDIAN_IO
 	bool "Use big endian I/O register access"
 	default y if AVR32
-	depends on DW_DMAC
+	depends on DW_DMAC_CORE
 	help
 	  Say yes here to use big endian I/O access when reading and writing
 	  to the DMA controller registers. This is needed on some platforms,
diff --git a/drivers/dma/dw/Makefile b/drivers/dma/dw/Makefile
index dd8d993..47f3674 100644
--- a/drivers/dma/dw/Makefile
+++ b/drivers/dma/dw/Makefile
@@ -1 +1,5 @@
-obj-$(CONFIG_DW_DMAC) += dw_dmac.o
+obj-$(CONFIG_DW_DMAC_CORE)	+= dw_dmac_core.o
+dw_dmac_core-objs	:= core.o
+
+obj-$(CONFIG_DW_DMAC)		+= dw_dmac.o
+dw_dmac-objs		:= platform.o
diff --git a/drivers/dma/dw/dw_dmac.c b/drivers/dma/dw/core.c
similarity index 85%
rename from drivers/dma/dw/dw_dmac.c
rename to drivers/dma/dw/core.c
index 15f3f4f..6bf82d5 100644
--- a/drivers/dma/dw/dw_dmac.c
+++ b/drivers/dma/dw/core.c
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2007-2008 Atmel Corporation
  * Copyright (C) 2010-2011 ST Microelectronics
+ * Copyright (C) 2013 Intel Corporation
  *
  * 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
@@ -19,17 +20,12 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_dma.h>
 #include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/acpi.h>
-#include <linux/acpi_dma.h>
 
 #include "../dmaengine.h"
-#include "dw_dmac_regs.h"
+#include "internal.h"
 
 /*
  * This supports the Synopsys "DesignWare AHB Central DMA Controller",
@@ -41,16 +37,6 @@
  * which does not support descriptor writeback.
  */
 
-static inline unsigned int dwc_get_dms(struct dw_dma_slave *slave)
-{
-	return slave ? slave->dst_master : 0;
-}
-
-static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave)
-{
-	return slave ? slave->src_master : 1;
-}
-
 static inline void dwc_set_masters(struct dw_dma_chan *dwc)
 {
 	struct dw_dma *dw = to_dw_dma(dwc->chan.device);
@@ -1225,99 +1211,6 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
 	dev_vdbg(chan2dev(chan), "%s: done\n", __func__);
 }
 
-/*----------------------------------------------------------------------*/
-
-struct dw_dma_of_filter_args {
-	struct dw_dma *dw;
-	unsigned int req;
-	unsigned int src;
-	unsigned int dst;
-};
-
-static bool dw_dma_of_filter(struct dma_chan *chan, void *param)
-{
-	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
-	struct dw_dma_of_filter_args *fargs = param;
-
-	/* Ensure the device matches our channel */
-        if (chan->device != &fargs->dw->dma)
-                return false;
-
-	dwc->request_line = fargs->req;
-	dwc->src_master	= fargs->src;
-	dwc->dst_master	= fargs->dst;
-
-	return true;
-}
-
-static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec,
-					struct of_dma *ofdma)
-{
-	struct dw_dma *dw = ofdma->of_dma_data;
-	struct dw_dma_of_filter_args fargs = {
-		.dw = dw,
-	};
-	dma_cap_mask_t cap;
-
-	if (dma_spec->args_count != 3)
-		return NULL;
-
-	fargs.req = dma_spec->args[0];
-	fargs.src = dma_spec->args[1];
-	fargs.dst = dma_spec->args[2];
-
-	if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS ||
-		    fargs.src >= dw->nr_masters ||
-		    fargs.dst >= dw->nr_masters))
-		return NULL;
-
-	dma_cap_zero(cap);
-	dma_cap_set(DMA_SLAVE, cap);
-
-	/* TODO: there should be a simpler way to do this */
-	return dma_request_channel(cap, dw_dma_of_filter, &fargs);
-}
-
-#ifdef CONFIG_ACPI
-static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
-{
-	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
-	struct acpi_dma_spec *dma_spec = param;
-
-	if (chan->device->dev != dma_spec->dev ||
-	    chan->chan_id != dma_spec->chan_id)
-		return false;
-
-	dwc->request_line = dma_spec->slave_id;
-	dwc->src_master = dwc_get_sms(NULL);
-	dwc->dst_master = dwc_get_dms(NULL);
-
-	return true;
-}
-
-static void dw_dma_acpi_controller_register(struct dw_dma *dw)
-{
-	struct device *dev = dw->dma.dev;
-	struct acpi_dma_filter_info *info;
-	int ret;
-
-	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
-	if (!info)
-		return;
-
-	dma_cap_zero(info->dma_cap);
-	dma_cap_set(DMA_SLAVE, info->dma_cap);
-	info->filter_fn = dw_dma_acpi_filter;
-
-	ret = devm_acpi_dma_controller_register(dev, acpi_dma_simple_xlate,
-						info);
-	if (ret)
-		dev_err(dev, "could not register acpi_dma_controller\n");
-}
-#else /* !CONFIG_ACPI */
-static inline void dw_dma_acpi_controller_register(struct dw_dma *dw) {}
-#endif /* !CONFIG_ACPI */
-
 /* --------------------- Cyclic DMA API extensions -------------------- */
 
 /**
@@ -1598,101 +1491,24 @@ static void dw_dma_off(struct dw_dma *dw)
 		dw->chan[i].initialized = false;
 }
 
-#ifdef CONFIG_OF
-static struct dw_dma_platform_data *
-dw_dma_parse_dt(struct platform_device *pdev)
-{
-	struct device_node *np = pdev->dev.of_node;
-	struct dw_dma_platform_data *pdata;
-	u32 tmp, arr[4];
-
-	if (!np) {
-		dev_err(&pdev->dev, "Missing DT data\n");
-		return NULL;
-	}
-
-	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
-	if (!pdata)
-		return NULL;
-
-	if (of_property_read_u32(np, "dma-channels", &pdata->nr_channels))
-		return NULL;
-
-	if (of_property_read_bool(np, "is_private"))
-		pdata->is_private = true;
-
-	if (!of_property_read_u32(np, "chan_allocation_order", &tmp))
-		pdata->chan_allocation_order = (unsigned char)tmp;
-
-	if (!of_property_read_u32(np, "chan_priority", &tmp))
-		pdata->chan_priority = tmp;
-
-	if (!of_property_read_u32(np, "block_size", &tmp))
-		pdata->block_size = tmp;
-
-	if (!of_property_read_u32(np, "dma-masters", &tmp)) {
-		if (tmp > 4)
-			return NULL;
-
-		pdata->nr_masters = tmp;
-	}
-
-	if (!of_property_read_u32_array(np, "data_width", arr,
-				pdata->nr_masters))
-		for (tmp = 0; tmp < pdata->nr_masters; tmp++)
-			pdata->data_width[tmp] = arr[tmp];
-
-	return pdata;
-}
-#else
-static inline struct dw_dma_platform_data *
-dw_dma_parse_dt(struct platform_device *pdev)
+int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
 {
-	return NULL;
-}
-#endif
-
-static int dw_probe(struct platform_device *pdev)
-{
-	struct dw_dma_platform_data *pdata;
-	struct resource		*io;
 	struct dw_dma		*dw;
 	size_t			size;
-	void __iomem		*regs;
 	bool			autocfg;
 	unsigned int		dw_params;
 	unsigned int		nr_channels;
 	unsigned int		max_blk_size = 0;
-	int			irq;
 	int			err;
 	int			i;
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
-
-	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	regs = devm_ioremap_resource(&pdev->dev, io);
-	if (IS_ERR(regs))
-		return PTR_ERR(regs);
-
-	/* Apply default dma_mask if needed */
-	if (!pdev->dev.dma_mask) {
-		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
-		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
-	}
-
-	dw_params = dma_read_byaddr(regs, DW_PARAMS);
+	dw_params = dma_read_byaddr(chip->regs, DW_PARAMS);
 	autocfg = dw_params >> DW_PARAMS_EN & 0x1;
 
-	dev_dbg(&pdev->dev, "DW_PARAMS: 0x%08x\n", dw_params);
-
-	pdata = dev_get_platdata(&pdev->dev);
-	if (!pdata)
-		pdata = dw_dma_parse_dt(pdev);
+	dev_dbg(chip->dev, "DW_PARAMS: 0x%08x\n", dw_params);
 
 	if (!pdata && autocfg) {
-		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+		pdata = devm_kzalloc(chip->dev, sizeof(*pdata), GFP_KERNEL);
 		if (!pdata)
 			return -ENOMEM;
 
@@ -1709,16 +1525,17 @@ static int dw_probe(struct platform_device *pdev)
 		nr_channels = pdata->nr_channels;
 
 	size = sizeof(struct dw_dma) + nr_channels * sizeof(struct dw_dma_chan);
-	dw = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
+	dw = devm_kzalloc(chip->dev, size, GFP_KERNEL);
 	if (!dw)
 		return -ENOMEM;
 
-	dw->clk = devm_clk_get(&pdev->dev, "hclk");
+	dw->clk = devm_clk_get(chip->dev, "hclk");
 	if (IS_ERR(dw->clk))
 		return PTR_ERR(dw->clk);
 	clk_prepare_enable(dw->clk);
 
-	dw->regs = regs;
+	dw->regs = chip->regs;
+	chip->dw = dw;
 
 	/* Get hardware configuration parameters */
 	if (autocfg) {
@@ -1743,18 +1560,16 @@ static int dw_probe(struct platform_device *pdev)
 	/* Disable BLOCK interrupts as well */
 	channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
 
-	err = devm_request_irq(&pdev->dev, irq, dw_dma_interrupt, 0,
+	err = devm_request_irq(chip->dev, chip->irq, dw_dma_interrupt, 0,
 			       "dw_dmac", dw);
 	if (err)
 		return err;
 
-	platform_set_drvdata(pdev, dw);
-
 	/* Create a pool of consistent memory blocks for hardware descriptors */
-	dw->desc_pool = dmam_pool_create("dw_dmac_desc_pool", &pdev->dev,
+	dw->desc_pool = dmam_pool_create("dw_dmac_desc_pool", chip->dev,
 					 sizeof(struct dw_desc), 4, 0);
 	if (!dw->desc_pool) {
-		dev_err(&pdev->dev, "No memory for descriptors dma pool\n");
+		dev_err(chip->dev, "No memory for descriptors dma pool\n");
 		return -ENOMEM;
 	}
 
@@ -1795,12 +1610,12 @@ static int dw_probe(struct platform_device *pdev)
 		/* Hardware configuration */
 		if (autocfg) {
 			unsigned int dwc_params;
+			void __iomem *addr = chip->regs + r * sizeof(u32);
 
-			dwc_params = dma_read_byaddr(regs + r * sizeof(u32),
-						     DWC_PARAMS);
+			dwc_params = dma_read_byaddr(addr, DWC_PARAMS);
 
-			dev_dbg(&pdev->dev, "DWC_PARAMS[%d]: 0x%08x\n", i,
-					    dwc_params);
+			dev_dbg(chip->dev, "DWC_PARAMS[%d]: 0x%08x\n", i,
+					   dwc_params);
 
 			/* Decode maximum block size for given channel. The
 			 * stored 4 bit value represents blocks from 0x00 for 3
@@ -1831,7 +1646,7 @@ static int dw_probe(struct platform_device *pdev)
 	dma_cap_set(DMA_SLAVE, dw->dma.cap_mask);
 	if (pdata->is_private)
 		dma_cap_set(DMA_PRIVATE, dw->dma.cap_mask);
-	dw->dma.dev = &pdev->dev;
+	dw->dma.dev = chip->dev;
 	dw->dma.device_alloc_chan_resources = dwc_alloc_chan_resources;
 	dw->dma.device_free_chan_resources = dwc_free_chan_resources;
 
@@ -1845,32 +1660,20 @@ static int dw_probe(struct platform_device *pdev)
 
 	dma_writel(dw, CFG, DW_CFG_DMA_EN);
 
-	dev_info(&pdev->dev, "DesignWare DMA Controller, %d channels\n",
+	dev_info(chip->dev, "DesignWare DMA Controller, %d channels\n",
 		 nr_channels);
 
 	dma_async_device_register(&dw->dma);
 
-	if (pdev->dev.of_node) {
-		err = of_dma_controller_register(pdev->dev.of_node,
-						 dw_dma_of_xlate, dw);
-		if (err)
-			dev_err(&pdev->dev,
-				"could not register of_dma_controller\n");
-	}
-
-	if (ACPI_HANDLE(&pdev->dev))
-		dw_dma_acpi_controller_register(dw);
-
 	return 0;
 }
+EXPORT_SYMBOL_GPL(dw_dma_probe);
 
-static int dw_remove(struct platform_device *pdev)
+int dw_dma_remove(struct dw_dma_chip *chip)
 {
-	struct dw_dma		*dw = platform_get_drvdata(pdev);
+	struct dw_dma		*dw = chip->dw;
 	struct dw_dma_chan	*dwc, *_dwc;
 
-	if (pdev->dev.of_node)
-		of_dma_controller_free(pdev->dev.of_node);
 	dw_dma_off(dw);
 	dma_async_device_unregister(&dw->dma);
 
@@ -1884,86 +1687,40 @@ static int dw_remove(struct platform_device *pdev)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(dw_dma_remove);
 
-static void dw_shutdown(struct platform_device *pdev)
+void dw_dma_shutdown(struct dw_dma_chip *chip)
 {
-	struct dw_dma	*dw = platform_get_drvdata(pdev);
+	struct dw_dma *dw = chip->dw;
 
 	dw_dma_off(dw);
 	clk_disable_unprepare(dw->clk);
 }
+EXPORT_SYMBOL_GPL(dw_dma_shutdown);
 
-static int dw_suspend_noirq(struct device *dev)
+int dw_dma_suspend_noirq(struct dw_dma_chip *chip)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct dw_dma	*dw = platform_get_drvdata(pdev);
+	struct dw_dma *dw = chip->dw;
 
 	dw_dma_off(dw);
 	clk_disable_unprepare(dw->clk);
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(dw_dma_suspend_noirq);
 
-static int dw_resume_noirq(struct device *dev)
+int dw_dma_resume_noirq(struct dw_dma_chip *chip)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct dw_dma	*dw = platform_get_drvdata(pdev);
+	struct dw_dma *dw = chip->dw;
 
 	clk_prepare_enable(dw->clk);
 	dma_writel(dw, CFG, DW_CFG_DMA_EN);
 
 	return 0;
 }
-
-static const struct dev_pm_ops dw_dev_pm_ops = {
-	.suspend_noirq = dw_suspend_noirq,
-	.resume_noirq = dw_resume_noirq,
-	.freeze_noirq = dw_suspend_noirq,
-	.thaw_noirq = dw_resume_noirq,
-	.restore_noirq = dw_resume_noirq,
-	.poweroff_noirq = dw_suspend_noirq,
-};
-
-#ifdef CONFIG_OF
-static const struct of_device_id dw_dma_of_id_table[] = {
-	{ .compatible = "snps,dma-spear1340" },
-	{}
-};
-MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
-#endif
-
-#ifdef CONFIG_ACPI
-static const struct acpi_device_id dw_dma_acpi_id_table[] = {
-	{ "INTL9C60", 0 },
-	{ }
-};
-#endif
-
-static struct platform_driver dw_driver = {
-	.probe		= dw_probe,
-	.remove		= dw_remove,
-	.shutdown	= dw_shutdown,
-	.driver = {
-		.name	= "dw_dmac",
-		.pm	= &dw_dev_pm_ops,
-		.of_match_table = of_match_ptr(dw_dma_of_id_table),
-		.acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table),
-	},
-};
-
-static int __init dw_init(void)
-{
-	return platform_driver_register(&dw_driver);
-}
-subsys_initcall(dw_init);
-
-static void __exit dw_exit(void)
-{
-	platform_driver_unregister(&dw_driver);
-}
-module_exit(dw_exit);
+EXPORT_SYMBOL_GPL(dw_dma_resume_noirq);
 
 MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver");
+MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller core driver");
 MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
 MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>");
diff --git a/drivers/dma/dw/internal.h b/drivers/dma/dw/internal.h
new file mode 100644
index 0000000..be62c47
--- /dev/null
+++ b/drivers/dma/dw/internal.h
@@ -0,0 +1,74 @@
+/*
+ * Driver for the Synopsys DesignWare AHB DMA Controller
+ *
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * 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.
+ */
+
+#ifndef _DW_DMAC_INTERNAL_H
+#define _DW_DMAC_INTERNAL_H
+
+#include <linux/device.h>
+#include <linux/dw_dmac.h>
+
+#include "regs.h"
+
+/**
+ * struct dw_dma_chip - representation of DesignWare DMA controller hardware
+ * @dev:		struct device of the DMA controller
+ * @irq:		irq line
+ * @regs:		memory mapped I/O space
+ * @dw:			struct dw_dma that is filed by dw_dma_probe()
+ */
+struct dw_dma_chip {
+	struct device	*dev;
+	int		irq;
+	void __iomem	*regs;
+	struct dw_dma	*dw;
+};
+
+/* Export to the platform drivers */
+int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata);
+int dw_dma_remove(struct dw_dma_chip *chip);
+void dw_dma_shutdown(struct dw_dma_chip *chip);
+
+#ifdef CONFIG_PM_SLEEP
+
+int dw_dma_suspend_noirq(struct dw_dma_chip *chip);
+int dw_dma_resume_noirq(struct dw_dma_chip *chip);
+
+#else /* !CONFIG_PM_SLEEP */
+
+#define dw_dma_suspend_noirq	NULL
+#define dw_dma_resume_noirq	NULL
+
+#endif /* !CONFIG_PM_SLEEP */
+
+/**
+ * dwc_get_dms - get destination master
+ * @slave:	pointer to the custom slave configuration
+ *
+ * Returns destination master in the custom slave configuration if defined, or
+ * default value otherwise.
+ */
+static inline unsigned int dwc_get_dms(struct dw_dma_slave *slave)
+{
+	return slave ? slave->dst_master : 0;
+}
+
+/**
+ * dwc_get_sms - get source master
+ * @slave:	pointer to the custom slave configuration
+ *
+ * Returns source master in the custom slave configuration if defined, or
+ * default value otherwise.
+ */
+static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave)
+{
+	return slave ? slave->src_master : 1;
+}
+
+#endif /* _DW_DMAC_INTERNAL_H */
diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c
new file mode 100644
index 0000000..f0764c7
--- /dev/null
+++ b/drivers/dma/dw/platform.c
@@ -0,0 +1,308 @@
+/*
+ * Platform driver for the Synopsys DesignWare DMA Controller
+ *
+ * Copyright (C) 2007-2008 Atmel Corporation
+ * Copyright (C) 2010-2011 ST Microelectronics
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Some parts of this driver are derived from the original dw_dmac.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/of_dma.h>
+#include <linux/acpi.h>
+#include <linux/acpi_dma.h>
+
+#include "internal.h"
+
+struct dw_dma_of_filter_args {
+	struct dw_dma *dw;
+	unsigned int req;
+	unsigned int src;
+	unsigned int dst;
+};
+
+static bool dw_dma_of_filter(struct dma_chan *chan, void *param)
+{
+	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+	struct dw_dma_of_filter_args *fargs = param;
+
+	/* Ensure the device matches our channel */
+        if (chan->device != &fargs->dw->dma)
+                return false;
+
+	dwc->request_line = fargs->req;
+	dwc->src_master	= fargs->src;
+	dwc->dst_master	= fargs->dst;
+
+	return true;
+}
+
+static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec,
+					struct of_dma *ofdma)
+{
+	struct dw_dma *dw = ofdma->of_dma_data;
+	struct dw_dma_of_filter_args fargs = {
+		.dw = dw,
+	};
+	dma_cap_mask_t cap;
+
+	if (dma_spec->args_count != 3)
+		return NULL;
+
+	fargs.req = dma_spec->args[0];
+	fargs.src = dma_spec->args[1];
+	fargs.dst = dma_spec->args[2];
+
+	if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS ||
+		    fargs.src >= dw->nr_masters ||
+		    fargs.dst >= dw->nr_masters))
+		return NULL;
+
+	dma_cap_zero(cap);
+	dma_cap_set(DMA_SLAVE, cap);
+
+	/* TODO: there should be a simpler way to do this */
+	return dma_request_channel(cap, dw_dma_of_filter, &fargs);
+}
+
+#ifdef CONFIG_ACPI
+static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
+{
+	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+	struct acpi_dma_spec *dma_spec = param;
+
+	if (chan->device->dev != dma_spec->dev ||
+	    chan->chan_id != dma_spec->chan_id)
+		return false;
+
+	dwc->request_line = dma_spec->slave_id;
+	dwc->src_master = dwc_get_sms(NULL);
+	dwc->dst_master = dwc_get_dms(NULL);
+
+	return true;
+}
+
+static void dw_dma_acpi_controller_register(struct dw_dma *dw)
+{
+	struct device *dev = dw->dma.dev;
+	struct acpi_dma_filter_info *info;
+	int ret;
+
+	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return;
+
+	dma_cap_zero(info->dma_cap);
+	dma_cap_set(DMA_SLAVE, info->dma_cap);
+	info->filter_fn = dw_dma_acpi_filter;
+
+	ret = devm_acpi_dma_controller_register(dev, acpi_dma_simple_xlate,
+						info);
+	if (ret)
+		dev_err(dev, "could not register acpi_dma_controller\n");
+}
+#else /* !CONFIG_ACPI */
+static inline void dw_dma_acpi_controller_register(struct dw_dma *dw) {}
+#endif /* !CONFIG_ACPI */
+
+#ifdef CONFIG_OF
+static struct dw_dma_platform_data *
+dw_dma_parse_dt(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct dw_dma_platform_data *pdata;
+	u32 tmp, arr[4];
+
+	if (!np) {
+		dev_err(&pdev->dev, "Missing DT data\n");
+		return NULL;
+	}
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return NULL;
+
+	if (of_property_read_u32(np, "dma-channels", &pdata->nr_channels))
+		return NULL;
+
+	if (of_property_read_bool(np, "is_private"))
+		pdata->is_private = true;
+
+	if (!of_property_read_u32(np, "chan_allocation_order", &tmp))
+		pdata->chan_allocation_order = (unsigned char)tmp;
+
+	if (!of_property_read_u32(np, "chan_priority", &tmp))
+		pdata->chan_priority = tmp;
+
+	if (!of_property_read_u32(np, "block_size", &tmp))
+		pdata->block_size = tmp;
+
+	if (!of_property_read_u32(np, "dma-masters", &tmp)) {
+		if (tmp > 4)
+			return NULL;
+
+		pdata->nr_masters = tmp;
+	}
+
+	if (!of_property_read_u32_array(np, "data_width", arr,
+				pdata->nr_masters))
+		for (tmp = 0; tmp < pdata->nr_masters; tmp++)
+			pdata->data_width[tmp] = arr[tmp];
+
+	return pdata;
+}
+#else
+static inline struct dw_dma_platform_data *
+dw_dma_parse_dt(struct platform_device *pdev)
+{
+	return NULL;
+}
+#endif
+
+static int dw_probe(struct platform_device *pdev)
+{
+	struct dw_dma_chip *chip;
+	struct device *dev = &pdev->dev;
+	struct resource *mem;
+	struct dw_dma_platform_data *pdata;
+	int err;
+
+	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	chip->irq = platform_get_irq(pdev, 0);
+	if (chip->irq < 0)
+		return chip->irq;
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	chip->regs = devm_ioremap_resource(dev, mem);
+	if (IS_ERR(chip->regs))
+		return PTR_ERR(chip->regs);
+
+	/* Apply default dma_mask if needed */
+	if (!dev->dma_mask) {
+		dev->dma_mask = &dev->coherent_dma_mask;
+		dev->coherent_dma_mask = DMA_BIT_MASK(32);
+	}
+
+	pdata = dev_get_platdata(dev);
+	if (!pdata)
+		pdata = dw_dma_parse_dt(pdev);
+
+	chip->dev = dev;
+
+	err = dw_dma_probe(chip, pdata);
+	if (err)
+		return err;
+
+	platform_set_drvdata(pdev, chip);
+
+	if (pdev->dev.of_node) {
+		err = of_dma_controller_register(pdev->dev.of_node,
+						 dw_dma_of_xlate, chip->dw);
+		if (err)
+			dev_err(&pdev->dev,
+				"could not register of_dma_controller\n");
+	}
+
+	if (ACPI_HANDLE(pdev->dev))
+		dw_dma_acpi_controller_register(chip->dw);
+
+	return 0;
+}
+
+static int dw_remove(struct platform_device *pdev)
+{
+	struct dw_dma_chip *chip = platform_get_drvdata(pdev);
+
+	if (pdev->dev.of_node)
+		of_dma_controller_free(pdev->dev.of_node);
+
+	return dw_dma_remove(chip);
+}
+
+static void dw_shutdown(struct platform_device *pdev)
+{
+	struct dw_dma_chip *chip = platform_get_drvdata(pdev);
+
+	dw_dma_shutdown(chip);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id dw_dma_of_id_table[] = {
+	{ .compatible = "snps,dma-spear1340" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
+#endif
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id dw_dma_acpi_id_table[] = {
+	{ "INTL9C60", 0 },
+	{ }
+};
+#endif
+
+static int dw_suspend_noirq(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dw_dma_chip *chip = platform_get_drvdata(pdev);
+
+	return dw_dma_suspend_noirq(chip);
+}
+
+static int dw_resume_noirq(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dw_dma_chip *chip = platform_get_drvdata(pdev);
+
+	return dw_dma_resume_noirq(chip);
+}
+
+static const struct dev_pm_ops dw_dev_pm_ops = {
+	.suspend_noirq = dw_suspend_noirq,
+	.resume_noirq = dw_resume_noirq,
+	.freeze_noirq = dw_suspend_noirq,
+	.thaw_noirq = dw_resume_noirq,
+	.restore_noirq = dw_resume_noirq,
+	.poweroff_noirq = dw_suspend_noirq,
+};
+
+static struct platform_driver dw_driver = {
+	.probe		= dw_probe,
+	.remove		= dw_remove,
+	.shutdown	= dw_shutdown,
+	.driver = {
+		.name	= "dw_dmac",
+		.pm	= &dw_dev_pm_ops,
+		.of_match_table = of_match_ptr(dw_dma_of_id_table),
+		.acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table),
+	},
+};
+
+static int __init dw_init(void)
+{
+	return platform_driver_register(&dw_driver);
+}
+subsys_initcall(dw_init);
+
+static void __exit dw_exit(void)
+{
+	platform_driver_unregister(&dw_driver);
+}
+module_exit(dw_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller platform driver");
diff --git a/drivers/dma/dw/dw_dmac_regs.h b/drivers/dma/dw/regs.h
similarity index 99%
rename from drivers/dma/dw/dw_dmac_regs.h
rename to drivers/dma/dw/regs.h
index 9d41720..07c5a6e 100644
--- a/drivers/dma/dw/dw_dmac_regs.h
+++ b/drivers/dma/dw/regs.h
@@ -9,6 +9,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/interrupt.h>
 #include <linux/dmaengine.h>
 #include <linux/dw_dmac.h>
 
-- 
1.8.2.rc0.22.gb3600c3


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v1 4/4] dma: dw: add PCI part of the driver
  2013-06-04 12:36 [PATCH v1 0/4] dw_dmac: move to own folder and split Andy Shevchenko
                   ` (2 preceding siblings ...)
  2013-06-04 12:36 ` [PATCH v1 3/4] dma: dw: split driver to library part and platform code Andy Shevchenko
@ 2013-06-04 12:36 ` Andy Shevchenko
  2013-06-05  9:41   ` Viresh Kumar
  2013-06-04 13:01 ` [PATCH v1 0/4] dw_dmac: move to own folder and split Arnd Bergmann
  4 siblings, 1 reply; 10+ messages in thread
From: Andy Shevchenko @ 2013-06-04 12:36 UTC (permalink / raw)
  To: Vinod Koul, linux-kernel, spear-devel, viresh.kumar,
	Arnd Bergmann, Felipe Balbi
  Cc: Andy Shevchenko

This is the PCI part of the DesignWare DMAC driver. The controller is usually
used in the Intel hardware such as Intel Medfield.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw/Kconfig  |   9 +++++
 drivers/dma/dw/Makefile |   3 ++
 drivers/dma/dw/pci.c    | 101 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 113 insertions(+)
 create mode 100644 drivers/dma/dw/pci.c

diff --git a/drivers/dma/dw/Kconfig b/drivers/dma/dw/Kconfig
index efd9e02..db2b41f 100644
--- a/drivers/dma/dw/Kconfig
+++ b/drivers/dma/dw/Kconfig
@@ -15,6 +15,15 @@ config DW_DMAC
 	  Support the Synopsys DesignWare AHB DMA controller. This
 	  can be integrated in chips such as the Atmel AT32ap7000.
 
+config DW_DMAC_PCI
+	tristate "Synopsys DesignWare AHB DMA PCI driver"
+	depends on PCI
+	select DW_DMAC_CORE
+	help
+	  Support the Synopsys DesignWare AHB DMA controller on the
+	  platfroms that enumerate it as a PCI device. For example,
+	  Intel Medfield has integrated this GPDMA controller.
+
 config DW_DMAC_BIG_ENDIAN_IO
 	bool "Use big endian I/O register access"
 	default y if AVR32
diff --git a/drivers/dma/dw/Makefile b/drivers/dma/dw/Makefile
index 47f3674..3eebd1c 100644
--- a/drivers/dma/dw/Makefile
+++ b/drivers/dma/dw/Makefile
@@ -3,3 +3,6 @@ dw_dmac_core-objs	:= core.o
 
 obj-$(CONFIG_DW_DMAC)		+= dw_dmac.o
 dw_dmac-objs		:= platform.o
+
+obj-$(CONFIG_DW_DMAC_PCI)	+= dw_dmac_pci.o
+dw_dmac_pci-objs	:= pci.o
diff --git a/drivers/dma/dw/pci.c b/drivers/dma/dw/pci.c
new file mode 100644
index 0000000..e972c5dd
--- /dev/null
+++ b/drivers/dma/dw/pci.c
@@ -0,0 +1,101 @@
+/*
+ * PCI driver for the Synopsys DesignWare DMA Controller
+ *
+ * Copyright (C) 2013 Intel Corporation
+ * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/device.h>
+
+#include "internal.h"
+
+static struct dw_dma_platform_data dw_pci_pdata = {
+	.is_private = 1,
+	.chan_allocation_order = CHAN_ALLOCATION_ASCENDING,
+	.chan_priority = CHAN_PRIORITY_ASCENDING,
+};
+
+static int dw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
+{
+	struct dw_dma_chip *chip;
+	struct dw_dma_platform_data *pdata = (void *)pid->driver_data;
+	int ret;
+
+	ret = pcim_enable_device(pdev);
+	if (ret)
+		return ret;
+
+	ret = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev));
+	if (ret) {
+		dev_err(&pdev->dev, "I/O memory remapping failed\n");
+		return ret;
+	}
+
+	pci_set_master(pdev);
+	pci_try_set_mwi(pdev);
+
+	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+	if (ret)
+		return ret;
+
+	ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+	if (ret)
+		return ret;
+
+	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	chip->dev = &pdev->dev;
+	chip->regs = pcim_iomap_table(pdev)[0];
+	chip->irq = pdev->irq;
+
+	ret = dw_dma_probe(chip, pdata);
+	if (ret)
+		return ret;
+
+	pci_set_drvdata(pdev, chip);
+
+	return 0;
+}
+
+static void dw_pci_remove(struct pci_dev *pdev)
+{
+	struct dw_dma_chip *chip = pci_get_drvdata(pdev);
+	int ret;
+
+	ret = dw_dma_remove(chip);
+	if (ret)
+		dev_warn(&pdev->dev, "can't remove device properly: %d\n", ret);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(dw_pci_id_table) = {
+	/* Medfield */
+	{ PCI_VDEVICE(INTEL, 0x0827), (kernel_ulong_t)&dw_pci_pdata },
+	{ PCI_VDEVICE(INTEL, 0x0830), (kernel_ulong_t)&dw_pci_pdata },
+
+	/* BayTrail */
+	{ PCI_VDEVICE(INTEL, 0x0f06), (kernel_ulong_t)&dw_pci_pdata },
+	{ PCI_VDEVICE(INTEL, 0x0f40), (kernel_ulong_t)&dw_pci_pdata },
+	{ }
+};
+MODULE_DEVICE_TABLE(pci, dw_pci_id_table);
+
+static struct pci_driver dw_pci_driver = {
+	.name		= "dw_dmac_pci",
+	.id_table	= dw_pci_id_table,
+	.probe		= dw_pci_probe,
+	.remove		= dw_pci_remove,
+};
+
+module_pci_driver(dw_pci_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Synopsys DesignWare DMAC PCI driver");
+MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
-- 
1.8.2.rc0.22.gb3600c3


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v1 3/4] dma: dw: split driver to library part and platform code
  2013-06-04 12:36 ` [PATCH v1 3/4] dma: dw: split driver to library part and platform code Andy Shevchenko
@ 2013-06-04 13:00   ` Arnd Bergmann
  2013-06-05  8:45   ` Viresh Kumar
  1 sibling, 0 replies; 10+ messages in thread
From: Arnd Bergmann @ 2013-06-04 13:00 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Vinod Koul, linux-kernel, spear-devel, viresh.kumar, Felipe Balbi

On Tuesday 04 June 2013 15:36:21 Andy Shevchenko wrote:
> To simplify the driver development let's split driver to library and platform
> code parts. It helps us to add PCI driver in future.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  drivers/dma/Makefile                      |   2 +-
>  drivers/dma/dw/Kconfig                    |   8 +-
>  drivers/dma/dw/Makefile                   |   6 +-
>  drivers/dma/dw/{dw_dmac.c => core.c}      | 309 ++++--------------------------
>  drivers/dma/dw/internal.h                 |  74 +++++++
>  drivers/dma/dw/platform.c                 | 308 +++++++++++++++++++++++++++++
>  drivers/dma/dw/{dw_dmac_regs.h => regs.h} |   1 +

Looks good to me, just one issue I found:

> +#ifdef CONFIG_PM_SLEEP
> +
> +int dw_dma_suspend_noirq(struct dw_dma_chip *chip);
> +int dw_dma_resume_noirq(struct dw_dma_chip *chip);
> +
> +#else /* !CONFIG_PM_SLEEP */
> +
> +#define dw_dma_suspend_noirq	NULL
> +#define dw_dma_resume_noirq	NULL
> +
> +#endif /* !CONFIG_PM_SLEEP */

This won't work ...

> +static int dw_suspend_noirq(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct dw_dma_chip *chip = platform_get_drvdata(pdev);
> +
> +	return dw_dma_suspend_noirq(chip);
> +}
> +
> +static int dw_resume_noirq(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct dw_dma_chip *chip = platform_get_drvdata(pdev);
> +
> +	return dw_dma_resume_noirq(chip);
> +}

when you try to call NULL as a function.

Please try to get it to build with CONFIG_PM_SLEEP disabled.

	Arnd

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v1 0/4] dw_dmac: move to own folder and split
  2013-06-04 12:36 [PATCH v1 0/4] dw_dmac: move to own folder and split Andy Shevchenko
                   ` (3 preceding siblings ...)
  2013-06-04 12:36 ` [PATCH v1 4/4] dma: dw: add PCI part of the driver Andy Shevchenko
@ 2013-06-04 13:01 ` Arnd Bergmann
  2013-06-04 13:43   ` Andy Shevchenko
  4 siblings, 1 reply; 10+ messages in thread
From: Arnd Bergmann @ 2013-06-04 13:01 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Vinod Koul, linux-kernel, spear-devel, viresh.kumar, Felipe Balbi

On Tuesday 04 June 2013 15:36:18 Andy Shevchenko wrote:
> This is second attempt to do split as suggested by Arnd et al [1,2].
> There are three most important patches:
>  2/4 moves driver to its own folder
>  3/4 does the actual split
>  4/4 introduces PCI part of the driver
> 
> During this files are renamed: mostly means that dw_dmac prefix is eliminated.
> I hope to get it ready to be included in v3.11.
> 
> [1] http://www.spinics.net/lists/kernel/msg1408174.html
> [2] http://www.spinics.net/lists/kernel/msg1408495.html

Whole series

Acked-by: Arnd Bergmann <arnd@arndb.de>

provided you make it work with !CONFIG_PM.

	Arnd

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v1 0/4] dw_dmac: move to own folder and split
  2013-06-04 13:01 ` [PATCH v1 0/4] dw_dmac: move to own folder and split Arnd Bergmann
@ 2013-06-04 13:43   ` Andy Shevchenko
  0 siblings, 0 replies; 10+ messages in thread
From: Andy Shevchenko @ 2013-06-04 13:43 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Vinod Koul, linux-kernel, spear-devel, viresh.kumar, Felipe Balbi

On Tue, 2013-06-04 at 15:01 +0200, Arnd Bergmann wrote: 
> On Tuesday 04 June 2013 15:36:18 Andy Shevchenko wrote:
> > This is second attempt to do split as suggested by Arnd et al [1,2].
> > There are three most important patches:
> >  2/4 moves driver to its own folder
> >  3/4 does the actual split
> >  4/4 introduces PCI part of the driver
> > 
> > During this files are renamed: mostly means that dw_dmac prefix is eliminated.
> > I hope to get it ready to be included in v3.11.
> > 
> > [1] http://www.spinics.net/lists/kernel/msg1408174.html
> > [2] http://www.spinics.net/lists/kernel/msg1408495.html
> 
> Whole series
> 
> Acked-by: Arnd Bergmann <arnd@arndb.de>
> 
> provided you make it work with !CONFIG_PM.

Thank you for review.

I will wait for a while, if no more comments I will resubmit v2.

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v1 3/4] dma: dw: split driver to library part and platform code
  2013-06-04 12:36 ` [PATCH v1 3/4] dma: dw: split driver to library part and platform code Andy Shevchenko
  2013-06-04 13:00   ` Arnd Bergmann
@ 2013-06-05  8:45   ` Viresh Kumar
  1 sibling, 0 replies; 10+ messages in thread
From: Viresh Kumar @ 2013-06-05  8:45 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Vinod Koul, linux-kernel, spear-devel, Arnd Bergmann,
	Felipe Balbi

On 4 June 2013 18:06, Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
> To simplify the driver development let's split driver to library and platform
> code parts. It helps us to add PCI driver in future.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  drivers/dma/Makefile                      |   2 +-
>  drivers/dma/dw/Kconfig                    |   8 +-
>  drivers/dma/dw/Makefile                   |   6 +-
>  drivers/dma/dw/{dw_dmac.c => core.c}      | 309 ++++--------------------------
>  drivers/dma/dw/internal.h                 |  74 +++++++
>  drivers/dma/dw/platform.c                 | 308 +++++++++++++++++++++++++++++
>  drivers/dma/dw/{dw_dmac_regs.h => regs.h} |   1 +
>  7 files changed, 428 insertions(+), 280 deletions(-)
>  rename drivers/dma/dw/{dw_dmac.c => core.c} (85%)
>  create mode 100644 drivers/dma/dw/internal.h
>  create mode 100644 drivers/dma/dw/platform.c
>  rename drivers/dma/dw/{dw_dmac_regs.h => regs.h} (99%)

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v1 4/4] dma: dw: add PCI part of the driver
  2013-06-04 12:36 ` [PATCH v1 4/4] dma: dw: add PCI part of the driver Andy Shevchenko
@ 2013-06-05  9:41   ` Viresh Kumar
  0 siblings, 0 replies; 10+ messages in thread
From: Viresh Kumar @ 2013-06-05  9:41 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Vinod Koul, linux-kernel, spear-devel, Arnd Bergmann,
	Felipe Balbi

On 4 June 2013 18:06, Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
> This is the PCI part of the DesignWare DMAC driver. The controller is usually
> used in the Intel hardware such as Intel Medfield.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  drivers/dma/dw/Kconfig  |   9 +++++
>  drivers/dma/dw/Makefile |   3 ++
>  drivers/dma/dw/pci.c    | 101 ++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 113 insertions(+)
>  create mode 100644 drivers/dma/dw/pci.c

Looks fine.

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2013-06-05  9:42 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-04 12:36 [PATCH v1 0/4] dw_dmac: move to own folder and split Andy Shevchenko
2013-06-04 12:36 ` [PATCH v1 1/4] dw_dmac: don't check resource with devm_ioremap_resource Andy Shevchenko
2013-06-04 12:36 ` [PATCH v1 2/4] dma: move dw_dmac driver to an own directory Andy Shevchenko
2013-06-04 12:36 ` [PATCH v1 3/4] dma: dw: split driver to library part and platform code Andy Shevchenko
2013-06-04 13:00   ` Arnd Bergmann
2013-06-05  8:45   ` Viresh Kumar
2013-06-04 12:36 ` [PATCH v1 4/4] dma: dw: add PCI part of the driver Andy Shevchenko
2013-06-05  9:41   ` Viresh Kumar
2013-06-04 13:01 ` [PATCH v1 0/4] dw_dmac: move to own folder and split Arnd Bergmann
2013-06-04 13:43   ` Andy Shevchenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox