Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1232021 > unrolled thread

[PATCH v4 00/25] dmaengine/ARM: Merge the edma drivers into one

Started byPeter Ujfalusi <peter.ujfalusi@ti.com>
First post2015-09-24 12:20 +0200
Last post2015-09-24 12:20 +0200
Articles 6 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCH v4 00/25] dmaengine/ARM: Merge the edma drivers into one Peter Ujfalusi <peter.ujfalusi@ti.com> - 2015-09-24 12:20 +0200
    [PATCH v4 12/25] dmaengine: edma: Allocate memory dynamically for bitmaps and structures Peter Ujfalusi <peter.ujfalusi@ti.com> - 2015-09-24 12:20 +0200
    [PATCH v4 04/25] ARM: davinci/common: Convert edma driver to handle one eDMA instance per driver Peter Ujfalusi <peter.ujfalusi@ti.com> - 2015-09-24 12:20 +0200
    [PATCH v4 08/25] ARM/dmaengine: edma: Remove limitation on the number of eDMA controllers Peter Ujfalusi <peter.ujfalusi@ti.com> - 2015-09-24 12:20 +0200
    [PATCH v4 01/25] ARM: common: edma: Fix channel parameter for irq callbacks Peter Ujfalusi <peter.ujfalusi@ti.com> - 2015-09-24 12:20 +0200
    [PATCH v4 03/25] dmaengine: edma: Simplify and optimize the edma_execute path Peter Ujfalusi <peter.ujfalusi@ti.com> - 2015-09-24 12:20 +0200

#1232021 — [PATCH v4 00/25] dmaengine/ARM: Merge the edma drivers into one

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2015-09-24 12:20 +0200
Subject[PATCH v4 00/25] dmaengine/ARM: Merge the edma drivers into one
Message-ID<qcbDr-8jL-7@gated-at.bofh.it>
Hi,

Changes since v3:
- Separated the two (patch 10/11 in v2 patch 10 in v3) patch which got squashed
  by accident for v3
- Added Tony's Acked-by to patch 11 (for mach-oamp2 part)

Changes since v2:
- devm_kasprintf format string fixed
- Additional patch to enable dynamic paRAM slot usage when the channel mapping
  is supported by the eDMA module.
  On am335x we have 256 paRAM slots and 64 DMA channels, this means that we had
  64 slots 'locked away' all the time. The dynamic paRAM slot logic will allow
  us to use all 256 slots freely for any purpose.

Changes since v1:
- Convert edma platform device registration to use platform_device_register_full
- Moved the PM callback also to the dmaengine driver - missed in v1
- Commit message added to:
  ARM/dmaengine: edma: Remove limitation on the number of eDMA controllers
- New patch which reads the flag for the channel mapping support in one place

Cover letter:

with this series the edma two driver setup will be changed to have only one
driver to support eDMA3. The legacy edma interface will be removed and eDMA can
only be used via dmaengine API from this point on.
In order to do the merge the following improvements has been done:
- One driver instance per eDMA:
 - Any number of eDMA instances are supported (both legacy and DT boot)
- Not relying on global variables, arrays, etc
- Code simplification and optimizations in several places

This change will also help us to do bigger changes in the eDMA driver since,
since now we have only one driver to work with.

The series has been tested on:
da850-evm (OMAP-L138)
- with legacy and DT boot (both eDMA0 and eDMA1 is enabled)
- In code swapping the eDMA instances in legacy mode to make sure the second
  instance is handled correctly.

am335x-evmsk
- DT boot

I think this series could go via the dmaengine tree. Changes are trivial under
arch/arm/

Regards,
Peter
---
Peter Ujfalusi (25):
  ARM: common: edma: Fix channel parameter for irq callbacks
  ARM: common: edma: Remove unused functions
  dmaengine: edma: Simplify and optimize the edma_execute path
  ARM: davinci/common: Convert edma driver to handle one eDMA instance
    per driver
  ARM/dmaengine: edma: Move of_dma_controller_register to the dmaengine
    driver
  ARM: common: edma: Internal API to use pointer to 'struct edma'
  ARM/dmaengine: edma: Public API to use private struct pointer
  ARM/dmaengine: edma: Remove limitation on the number of eDMA
    controllers
  ARM: davinci: Use platform_device_register_full() to create pdev for
    eDMA
  ARM: davinci: Add dma_mask to eDMA devices
  ARM/dmaengine: edma: Merge the two drivers under drivers/dma/
  dmaengine: edma: Allocate memory dynamically for bitmaps and
    structures
  dmaengine: edma: Parameter alignment and long line fixes
  dmaengine: edma: Use devm_kcalloc when possible
  dmaengine: edma: Cleanup regarding the use of dev around the code
  dmaengine: edma: Use dev_dbg instead pr_debug
  dmaengine: edma: Use the edma_write_slot instead open coded
    memcpy_toio
  dmaengine: edma: Print warning when linking slots from different eDMA
  dmaengine: edma: Consolidate the comments for functions
  dmaengine: edma: Simplify the interrupt handling
  dmaengine: edma: Move the pending error check into helper function
  dmaengine: edma: Simplify and optimize ccerr interrupt handler
  dmaengine: edma: Read channel mapping support only once from HW
  dmaengine: edma: Rename bitfields for slot and channel usage tracking
  dmaengine: edma: Dynamic paRAM slot handling if HW supports it

 arch/arm/Kconfig                      |    1 -
 arch/arm/common/Kconfig               |    3 -
 arch/arm/common/Makefile              |    1 -
 arch/arm/common/edma.c                | 1876 ---------------------------------
 arch/arm/mach-davinci/devices-da8xx.c |  122 +--
 arch/arm/mach-davinci/dm355.c         |   40 +-
 arch/arm/mach-davinci/dm365.c         |   25 +-
 arch/arm/mach-davinci/dm644x.c        |   40 +-
 arch/arm/mach-davinci/dm646x.c        |   44 +-
 arch/arm/mach-omap2/Kconfig           |    1 -
 drivers/dma/Kconfig                   |    1 -
 drivers/dma/edma.c                    | 1569 ++++++++++++++++++++++++---
 include/linux/platform_data/edma.h    |  101 --
 13 files changed, 1523 insertions(+), 2301 deletions(-)
 delete mode 100644 arch/arm/common/edma.c

-- 
2.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1232022 — [PATCH v4 12/25] dmaengine: edma: Allocate memory dynamically for bitmaps and structures

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2015-09-24 12:20 +0200
Subject[PATCH v4 12/25] dmaengine: edma: Allocate memory dynamically for bitmaps and structures
Message-ID<qcbN8-8v1-7@gated-at.bofh.it>
In reply to#1232021
Instead of using defines to specify the size of different arrays and
bitmaps, allocate the memory for them based on the information we get from
the HW itself.
Since these defines are set based on the worst case, there are devices
where they are not valid.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/edma.c | 62 ++++++++++++++++++++++++++++++------------------------
 1 file changed, 34 insertions(+), 28 deletions(-)

diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index f31c463f94bd..49158ab1c798 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -113,23 +113,6 @@
 #define CHMAP_EXIST		BIT(24)
 
 /*
- * This will go away when the private EDMA API is folded
- * into this driver and the platform device(s) are
- * instantiated in the arch code. We can only get away
- * with this simplification because DA8XX may not be built
- * in the same kernel image with other DaVinci parts. This
- * avoids having to sprinkle dmaengine driver platform devices
- * and data throughout all the existing board files.
- */
-#ifdef CONFIG_ARCH_DAVINCI_DA8XX
-#define EDMA_CTLRS	2
-#define EDMA_CHANS	32
-#else
-#define EDMA_CTLRS	1
-#define EDMA_CHANS	64
-#endif /* CONFIG_ARCH_DAVINCI_DA8XX */
-
-/*
  * Max of 20 segments per channel to conserve PaRAM slots
  * Also note that MAX_NR_SG should be atleast the no.of periods
  * that are required for ASoC, otherwise DMA prep calls will
@@ -140,16 +123,12 @@
 #define EDMA_MAX_SLOTS		MAX_NR_SG
 #define EDMA_DESCRIPTORS	16
 
-#define EDMA_MAX_PARAMENTRY     512
-
 #define EDMA_CHANNEL_ANY		-1	/* for edma_alloc_channel() */
 #define EDMA_SLOT_ANY			-1	/* for edma_alloc_slot() */
 #define EDMA_CONT_PARAMS_ANY		 1001
 #define EDMA_CONT_PARAMS_FIXED_EXACT	 1002
 #define EDMA_CONT_PARAMS_FIXED_NOT_EXACT 1003
 
-#define EDMA_MAX_CC               2
-
 /* PaRAM slots are laid out like this */
 struct edmacc_param {
 	u32 opt;
@@ -256,22 +235,22 @@ struct edma_cc {
 	/* The edma_inuse bit for each PaRAM slot is clear unless the
 	 * channel is in use ... by ARM or DSP, for QDMA, or whatever.
 	 */
-	DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY);
+	unsigned long *edma_inuse;
 
 	/* The edma_unused bit for each channel is clear unless
 	 * it is not being used on this platform. It uses a bit
 	 * of SOC-specific initialization code.
 	 */
-	DECLARE_BITMAP(edma_unused, EDMA_CHANS);
+	unsigned long *edma_unused;
 
 	struct dma_interrupt_data {
 		void (*callback)(unsigned channel, unsigned short ch_status,
 				void *data);
 		void *data;
-	} intr_data[EDMA_CHANS];
+	} *intr_data;
 
 	struct dma_device		dma_slave;
-	struct edma_chan		slave_chans[EDMA_CHANS];
+	struct edma_chan		*slave_chans;
 	int				dummy_slot;
 };
 
@@ -431,6 +410,8 @@ static int prepare_unused_channel_list(struct device *dev, void *data)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct edma_cc *ecc = data;
+	int dma_req_min = EDMA_CTLR_CHAN(ecc->id, 0);
+	int dma_req_max = dma_req_min + ecc->num_channels;
 	int i, count;
 	struct of_phandle_args  dma_spec;
 
@@ -466,11 +447,15 @@ static int prepare_unused_channel_list(struct device *dev, void *data)
 	/* For non-OF case */
 	for (i = 0; i < pdev->num_resources; i++) {
 		struct resource	*res = &pdev->resource[i];
+		int dma_req;
+
+		if (!(res->flags & IORESOURCE_DMA))
+			continue;
 
-		if ((res->flags & IORESOURCE_DMA) && (int)res->start >= 0) {
+		dma_req = (int)res->start;
+		if (dma_req >= dma_req_min && dma_req < dma_req_max)
 			clear_bit(EDMA_CHAN_SLOT(pdev->resource[i].start),
 				  ecc->edma_unused);
-		}
 	}
 
 	return 0;
@@ -1953,7 +1938,7 @@ static void __init edma_chan_init(struct edma_cc *ecc,
 {
 	int i, j;
 
-	for (i = 0; i < EDMA_CHANS; i++) {
+	for (i = 0; i < ecc->num_channels; i++) {
 		struct edma_chan *echan = &echans[i];
 		echan->ch_num = EDMA_CTLR_CHAN(ecc->id, i);
 		echan->ecc = ecc;
@@ -2222,6 +2207,27 @@ static int edma_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	/* Allocate memory based on the information we got from the IP */
+	ecc->slave_chans = devm_kcalloc(dev, ecc->num_channels,
+					sizeof(*ecc->slave_chans), GFP_KERNEL);
+	if (!ecc->slave_chans)
+		return -ENOMEM;
+
+	ecc->intr_data = devm_kcalloc(dev, ecc->num_channels,
+				      sizeof(*ecc->intr_data), GFP_KERNEL);
+	if (!ecc->intr_data)
+		return -ENOMEM;
+
+	ecc->edma_unused = devm_kcalloc(dev, BITS_TO_LONGS(ecc->num_channels),
+					sizeof(unsigned long), GFP_KERNEL);
+	if (!ecc->edma_unused)
+		return -ENOMEM;
+
+	ecc->edma_inuse = devm_kcalloc(dev, BITS_TO_LONGS(ecc->num_slots),
+				       sizeof(unsigned long), GFP_KERNEL);
+	if (!ecc->edma_inuse)
+		return -ENOMEM;
+
 	ecc->default_queue = info->default_queue;
 
 	for (i = 0; i < ecc->num_slots; i++)
-- 
2.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1232023 — [PATCH v4 04/25] ARM: davinci/common: Convert edma driver to handle one eDMA instance per driver

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2015-09-24 12:20 +0200
Subject[PATCH v4 04/25] ARM: davinci/common: Convert edma driver to handle one eDMA instance per driver
Message-ID<qcbN8-8v1-11@gated-at.bofh.it>
In reply to#1232021
Currently we have one device created to handle all (maximum 2) eDMAs in the
system.
With this change all eDMA instance will have it's own device/driver.
This change is needed for further cleanups in the eDMA driver stack since
the one device/driver to handle all eDMAs in the system was not flexible
enough and prevents the upcoming work.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 arch/arm/common/edma.c                | 356 +++++++++++++++-------------------
 arch/arm/mach-davinci/devices-da8xx.c | 110 ++++-------
 arch/arm/mach-davinci/dm355.c         |  21 +-
 arch/arm/mach-davinci/dm365.c         |  25 +--
 arch/arm/mach-davinci/dm644x.c        |  21 +-
 arch/arm/mach-davinci/dm646x.c        |  27 ++-
 6 files changed, 234 insertions(+), 326 deletions(-)

diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c
index e9c4cb16a47e..7c2fe527e53b 100644
--- a/arch/arm/common/edma.c
+++ b/arch/arm/common/edma.c
@@ -235,6 +235,7 @@ static inline void clear_bits(int offset, int len, unsigned long *p)
 
 /* actual number of DMA channels and slots on this silicon */
 struct edma {
+	struct device	*dev;
 	/* how many dma resources of each type */
 	unsigned	num_channels;
 	unsigned	num_region;
@@ -246,6 +247,7 @@ struct edma {
 	const s8	*noevent;
 
 	struct edma_soc_info *info;
+	int		id;
 
 	/* The edma_inuse bit for each PaRAM slot is clear unless the
 	 * channel is in use ... by ARM or DSP, for QDMA, or whatever.
@@ -258,9 +260,6 @@ struct edma {
 	 */
 	DECLARE_BITMAP(edma_unused, EDMA_MAX_DMACH);
 
-	unsigned	irq_res_start;
-	unsigned	irq_res_end;
-
 	struct dma_interrupt_data {
 		void (*callback)(unsigned channel, unsigned short ch_status,
 				void *data);
@@ -349,17 +348,6 @@ setup_dma_interrupt(unsigned lch,
 	}
 }
 
-static int irq2ctlr(int irq)
-{
-	if (irq >= edma_cc[0]->irq_res_start && irq <= edma_cc[0]->irq_res_end)
-		return 0;
-	else if (irq >= edma_cc[1]->irq_res_start &&
-		irq <= edma_cc[1]->irq_res_end)
-		return 1;
-
-	return -1;
-}
-
 /******************************************************************************
  *
  * DMA interrupt handler
@@ -367,16 +355,17 @@ static int irq2ctlr(int irq)
  *****************************************************************************/
 static irqreturn_t dma_irq_handler(int irq, void *data)
 {
+	struct edma *cc = data;
 	int ctlr;
 	u32 sh_ier;
 	u32 sh_ipr;
 	u32 bank;
 
-	ctlr = irq2ctlr(irq);
+	ctlr = cc->id;
 	if (ctlr < 0)
 		return IRQ_NONE;
 
-	dev_dbg(data, "dma_irq_handler\n");
+	dev_dbg(cc->dev, "dma_irq_handler\n");
 
 	sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 0);
 	if (!sh_ipr) {
@@ -394,7 +383,7 @@ static irqreturn_t dma_irq_handler(int irq, void *data)
 		u32 slot;
 		u32 channel;
 
-		dev_dbg(data, "IPR%d %08x\n", bank, sh_ipr);
+		dev_dbg(cc->dev, "IPR%d %08x\n", bank, sh_ipr);
 
 		slot = __ffs(sh_ipr);
 		sh_ipr &= ~(BIT(slot));
@@ -404,11 +393,11 @@ static irqreturn_t dma_irq_handler(int irq, void *data)
 			/* Clear the corresponding IPR bits */
 			edma_shadow0_write_array(ctlr, SH_ICR, bank,
 					BIT(slot));
-			if (edma_cc[ctlr]->intr_data[channel].callback)
-				edma_cc[ctlr]->intr_data[channel].callback(
+			if (cc->intr_data[channel].callback)
+				cc->intr_data[channel].callback(
 					EDMA_CTLR_CHAN(ctlr, channel),
 					EDMA_DMA_COMPLETE,
-					edma_cc[ctlr]->intr_data[channel].data);
+					cc->intr_data[channel].data);
 		}
 	} while (sh_ipr);
 
@@ -423,15 +412,16 @@ static irqreturn_t dma_irq_handler(int irq, void *data)
  *****************************************************************************/
 static irqreturn_t dma_ccerr_handler(int irq, void *data)
 {
+	struct edma *cc = data;
 	int i;
 	int ctlr;
 	unsigned int cnt = 0;
 
-	ctlr = irq2ctlr(irq);
+	ctlr = cc->id;
 	if (ctlr < 0)
 		return IRQ_NONE;
 
-	dev_dbg(data, "dma_ccerr_handler\n");
+	dev_dbg(cc->dev, "dma_ccerr_handler\n");
 
 	if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) &&
 	    (edma_read_array(ctlr, EDMA_EMR, 1) == 0) &&
@@ -446,8 +436,8 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data)
 		else if (edma_read_array(ctlr, EDMA_EMR, 1))
 			j = 1;
 		if (j >= 0) {
-			dev_dbg(data, "EMR%d %08x\n", j,
-					edma_read_array(ctlr, EDMA_EMR, j));
+			dev_dbg(cc->dev, "EMR%d %08x\n", j,
+				edma_read_array(ctlr, EDMA_EMR, j));
 			for (i = 0; i < 32; i++) {
 				int k = (j << 5) + i;
 				if (edma_read_array(ctlr, EDMA_EMR, j) &
@@ -458,19 +448,16 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data)
 					/* Clear any SER */
 					edma_shadow0_write_array(ctlr, SH_SECR,
 								j, BIT(i));
-					if (edma_cc[ctlr]->intr_data[k].
-								callback) {
-						edma_cc[ctlr]->intr_data[k].
-						callback(
-						EDMA_CTLR_CHAN(ctlr, k),
-						EDMA_DMA_CC_ERROR,
-						edma_cc[ctlr]->intr_data
-						[k].data);
+					if (cc->intr_data[k].callback) {
+						cc->intr_data[k].callback(
+							EDMA_CTLR_CHAN(ctlr, k),
+							EDMA_DMA_CC_ERROR,
+							cc->intr_data[k].data);
 					}
 				}
 			}
 		} else if (edma_read(ctlr, EDMA_QEMR)) {
-			dev_dbg(data, "QEMR %02x\n",
+			dev_dbg(cc->dev, "QEMR %02x\n",
 				edma_read(ctlr, EDMA_QEMR));
 			for (i = 0; i < 8; i++) {
 				if (edma_read(ctlr, EDMA_QEMR) & BIT(i)) {
@@ -483,7 +470,7 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data)
 				}
 			}
 		} else if (edma_read(ctlr, EDMA_CCERR)) {
-			dev_dbg(data, "CCERR %08x\n",
+			dev_dbg(cc->dev, "CCERR %08x\n",
 				edma_read(ctlr, EDMA_CCERR));
 			/* FIXME:  CCERR.BIT(16) ignored!  much better
 			 * to just write CCERRCLR with CCERR value...
@@ -1239,21 +1226,19 @@ static struct edma_soc_info *edma_setup_info_from_dt(struct device *dev,
 
 static int edma_probe(struct platform_device *pdev)
 {
-	struct edma_soc_info	**info = pdev->dev.platform_data;
-	struct edma_soc_info    *ninfo[EDMA_MAX_CC] = {NULL};
+	struct edma_soc_info	*info = pdev->dev.platform_data;
 	s8		(*queue_priority_mapping)[2];
-	int			i, j, off, ln, found = 0;
-	int			status = -1;
+	int			i, off, ln;
 	const s16		(*rsv_chans)[2];
 	const s16		(*rsv_slots)[2];
 	const s16		(*xbar_chans)[2];
-	int			irq[EDMA_MAX_CC] = {0, 0};
-	int			err_irq[EDMA_MAX_CC] = {0, 0};
-	struct resource		*r[EDMA_MAX_CC] = {NULL};
-	struct resource		res[EDMA_MAX_CC];
-	char			res_name[10];
+	int			irq;
+	char			*irq_name;
+	struct resource		*mem;
 	struct device_node	*node = pdev->dev.of_node;
 	struct device		*dev = &pdev->dev;
+	int			dev_id = pdev->id;
+	struct edma		*cc;
 	int			ret;
 	struct platform_device_info edma_dev_info = {
 		.name = "edma-dma-engine",
@@ -1261,6 +1246,17 @@ static int edma_probe(struct platform_device *pdev)
 		.parent = &pdev->dev,
 	};
 
+	/* When booting with DT the pdev->id is -1 */
+	if (dev_id < 0)
+		dev_id = arch_num_cc;
+
+	if (dev_id >= EDMA_MAX_CC) {
+		dev_err(dev,
+			"eDMA3 with device id 0 and 1 is supported (id: %d)\n",
+			dev_id);
+		return -EINVAL;
+	}
+
 	if (node) {
 		/* Check if this is a second instance registered */
 		if (arch_num_cc) {
@@ -1268,13 +1264,11 @@ static int edma_probe(struct platform_device *pdev)
 			return -ENODEV;
 		}
 
-		ninfo[0] = edma_setup_info_from_dt(dev, node);
-		if (IS_ERR(ninfo[0])) {
+		info = edma_setup_info_from_dt(dev, node);
+		if (IS_ERR(info)) {
 			dev_err(dev, "failed to get DT data\n");
-			return PTR_ERR(ninfo[0]);
+			return PTR_ERR(info);
 		}
-
-		info = ninfo;
 	}
 
 	if (!info)
@@ -1287,154 +1281,132 @@ static int edma_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	for (j = 0; j < EDMA_MAX_CC; j++) {
-		if (!info[j]) {
-			if (!found)
-				return -ENODEV;
-			break;
-		}
-		if (node) {
-			ret = of_address_to_resource(node, j, &res[j]);
-			if (!ret)
-				r[j] = &res[j];
-		} else {
-			sprintf(res_name, "edma_cc%d", j);
-			r[j] = platform_get_resource_byname(pdev,
-						IORESOURCE_MEM,
-						res_name);
-		}
-		if (!r[j]) {
-			if (found)
-				break;
-			else
-				return -ENODEV;
-		} else {
-			found = 1;
+	mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "edma3_cc");
+	if (!mem) {
+		dev_dbg(dev, "mem resource not found, using index 0\n");
+		mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		if (!mem) {
+			dev_err(dev, "no mem resource?\n");
+			return -ENODEV;
 		}
+	}
 
-		edmacc_regs_base[j] = devm_ioremap_resource(&pdev->dev, r[j]);
-		if (IS_ERR(edmacc_regs_base[j]))
-			return PTR_ERR(edmacc_regs_base[j]);
+	edmacc_regs_base[dev_id] = devm_ioremap_resource(dev, mem);
+	if (IS_ERR(edmacc_regs_base[dev_id]))
+		return PTR_ERR(edmacc_regs_base[dev_id]);
 
-		edma_cc[j] = devm_kzalloc(&pdev->dev, sizeof(struct edma),
-					  GFP_KERNEL);
-		if (!edma_cc[j])
-			return -ENOMEM;
+	edma_cc[dev_id] = devm_kzalloc(dev, sizeof(struct edma), GFP_KERNEL);
+	if (!edma_cc[dev_id])
+		return -ENOMEM;
 
-		/* Get eDMA3 configuration from IP */
-		ret = edma_setup_from_hw(dev, info[j], edma_cc[j], j);
-		if (ret)
-			return ret;
+	cc = edma_cc[dev_id];
+	cc->dev = dev;
+	cc->id = dev_id;
+	dev_set_drvdata(dev, cc);
 
-		edma_cc[j]->default_queue = info[j]->default_queue;
+	/* Get eDMA3 configuration from IP */
+	ret = edma_setup_from_hw(dev, info, cc, dev_id);
+	if (ret)
+		return ret;
 
-		dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n",
-			edmacc_regs_base[j]);
+	cc->default_queue = info->default_queue;
 
-		for (i = 0; i < edma_cc[j]->num_slots; i++)
-			memcpy_toio(edmacc_regs_base[j] + PARM_OFFSET(i),
-					&dummy_paramset, PARM_SIZE);
+	dev_dbg(dev, "DMA REG BASE ADDR=%p\n", edmacc_regs_base[dev_id]);
 
-		/* Mark all channels as unused */
-		memset(edma_cc[j]->edma_unused, 0xff,
-			sizeof(edma_cc[j]->edma_unused));
+	for (i = 0; i < cc->num_slots; i++)
+		memcpy_toio(edmacc_regs_base[dev_id] + PARM_OFFSET(i),
+			    &dummy_paramset, PARM_SIZE);
 
-		if (info[j]->rsv) {
+	/* Mark all channels as unused */
+	memset(cc->edma_unused, 0xff, sizeof(cc->edma_unused));
 
-			/* Clear the reserved channels in unused list */
-			rsv_chans = info[j]->rsv->rsv_chans;
-			if (rsv_chans) {
-				for (i = 0; rsv_chans[i][0] != -1; i++) {
-					off = rsv_chans[i][0];
-					ln = rsv_chans[i][1];
-					clear_bits(off, ln,
-						  edma_cc[j]->edma_unused);
-				}
-			}
+	if (info->rsv) {
 
-			/* Set the reserved slots in inuse list */
-			rsv_slots = info[j]->rsv->rsv_slots;
-			if (rsv_slots) {
-				for (i = 0; rsv_slots[i][0] != -1; i++) {
-					off = rsv_slots[i][0];
-					ln = rsv_slots[i][1];
-					set_bits(off, ln,
-						edma_cc[j]->edma_inuse);
-				}
+		/* Clear the reserved channels in unused list */
+		rsv_chans = info->rsv->rsv_chans;
+		if (rsv_chans) {
+			for (i = 0; rsv_chans[i][0] != -1; i++) {
+				off = rsv_chans[i][0];
+				ln = rsv_chans[i][1];
+				clear_bits(off, ln, cc->edma_unused);
 			}
 		}
 
-		/* Clear the xbar mapped channels in unused list */
-		xbar_chans = info[j]->xbar_chans;
-		if (xbar_chans) {
-			for (i = 0; xbar_chans[i][1] != -1; i++) {
-				off = xbar_chans[i][1];
-				clear_bits(off, 1,
-					   edma_cc[j]->edma_unused);
+		/* Set the reserved slots in inuse list */
+		rsv_slots = info->rsv->rsv_slots;
+		if (rsv_slots) {
+			for (i = 0; rsv_slots[i][0] != -1; i++) {
+				off = rsv_slots[i][0];
+				ln = rsv_slots[i][1];
+				set_bits(off, ln, cc->edma_inuse);
 			}
 		}
+	}
 
-		if (node) {
-			irq[j] = irq_of_parse_and_map(node, 0);
-			err_irq[j] = irq_of_parse_and_map(node, 2);
-		} else {
-			char irq_name[10];
-
-			sprintf(irq_name, "edma%d", j);
-			irq[j] = platform_get_irq_byname(pdev, irq_name);
-
-			sprintf(irq_name, "edma%d_err", j);
-			err_irq[j] = platform_get_irq_byname(pdev, irq_name);
-		}
-		edma_cc[j]->irq_res_start = irq[j];
-		edma_cc[j]->irq_res_end = err_irq[j];
-
-		status = devm_request_irq(dev, irq[j], dma_irq_handler, 0,
-					  "edma", dev);
-		if (status < 0) {
-			dev_dbg(&pdev->dev,
-				"devm_request_irq %d failed --> %d\n",
-				irq[j], status);
-			return status;
+	/* Clear the xbar mapped channels in unused list */
+	xbar_chans = info->xbar_chans;
+	if (xbar_chans) {
+		for (i = 0; xbar_chans[i][1] != -1; i++) {
+			off = xbar_chans[i][1];
+			clear_bits(off, 1, cc->edma_unused);
 		}
+	}
 
-		status = devm_request_irq(dev, err_irq[j], dma_ccerr_handler, 0,
-					  "edma_error", dev);
-		if (status < 0) {
-			dev_dbg(&pdev->dev,
-				"devm_request_irq %d failed --> %d\n",
-				err_irq[j], status);
-			return status;
+	irq = platform_get_irq_byname(pdev, "edma3_ccint");
+	if (irq < 0 && node)
+		irq = irq_of_parse_and_map(node, 0);
+
+	if (irq >= 0) {
+		irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccint",
+					  dev_name(dev));
+		ret = devm_request_irq(dev, irq, dma_irq_handler, 0, irq_name,
+				       cc);
+		if (ret) {
+			dev_err(dev, "CCINT (%d) failed --> %d\n", irq, ret);
+			return ret;
 		}
+	}
 
-		for (i = 0; i < edma_cc[j]->num_channels; i++)
-			map_dmach_queue(j, i, info[j]->default_queue);
+	irq = platform_get_irq_byname(pdev, "edma3_ccerrint");
+	if (irq < 0 && node)
+		irq = irq_of_parse_and_map(node, 2);
+
+	if (irq >= 0) {
+		irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccerrint",
+					  dev_name(dev));
+		ret = devm_request_irq(dev, irq, dma_ccerr_handler, 0, irq_name,
+				       cc);
+		if (ret) {
+			dev_err(dev, "CCERRINT (%d) failed --> %d\n", irq, ret);
+			return ret;
+		}
+	}
 
-		queue_priority_mapping = info[j]->queue_priority_mapping;
+	for (i = 0; i < cc->num_channels; i++)
+		map_dmach_queue(dev_id, i, info->default_queue);
 
-		/* Event queue priority mapping */
-		for (i = 0; queue_priority_mapping[i][0] != -1; i++)
-			assign_priority_to_queue(j,
-						queue_priority_mapping[i][0],
-						queue_priority_mapping[i][1]);
+	queue_priority_mapping = info->queue_priority_mapping;
 
-		/* Map the channel to param entry if channel mapping logic
-		 * exist
-		 */
-		if (edma_read(j, EDMA_CCCFG) & CHMAP_EXIST)
-			map_dmach_param(j);
+	/* Event queue priority mapping */
+	for (i = 0; queue_priority_mapping[i][0] != -1; i++)
+		assign_priority_to_queue(dev_id, queue_priority_mapping[i][0],
+					 queue_priority_mapping[i][1]);
 
-		for (i = 0; i < edma_cc[j]->num_region; i++) {
-			edma_write_array2(j, EDMA_DRAE, i, 0, 0x0);
-			edma_write_array2(j, EDMA_DRAE, i, 1, 0x0);
-			edma_write_array(j, EDMA_QRAE, i, 0x0);
-		}
-		edma_cc[j]->info = info[j];
-		arch_num_cc++;
+	/* Map the channel to param entry if channel mapping logic exist */
+	if (edma_read(dev_id, EDMA_CCCFG) & CHMAP_EXIST)
+		map_dmach_param(dev_id);
 
-		edma_dev_info.id = j;
-		platform_device_register_full(&edma_dev_info);
+	for (i = 0; i < cc->num_region; i++) {
+		edma_write_array2(dev_id, EDMA_DRAE, i, 0, 0x0);
+		edma_write_array2(dev_id, EDMA_DRAE, i, 1, 0x0);
+		edma_write_array(dev_id, EDMA_QRAE, i, 0x0);
 	}
+	cc->info = info;
+	arch_num_cc++;
+
+	edma_dev_info.id = dev_id;
+
+	platform_device_register_full(&edma_dev_info);
 
 	return 0;
 }
@@ -1442,38 +1414,30 @@ static int edma_probe(struct platform_device *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int edma_pm_resume(struct device *dev)
 {
-	int i, j;
+	struct edma *cc = dev_get_drvdata(dev);
+	int i;
+	s8 (*queue_priority_mapping)[2];
 
-	for (j = 0; j < arch_num_cc; j++) {
-		struct edma *cc = edma_cc[j];
+	queue_priority_mapping = cc->info->queue_priority_mapping;
 
-		s8 (*queue_priority_mapping)[2];
+	/* Event queue priority mapping */
+	for (i = 0; queue_priority_mapping[i][0] != -1; i++)
+		assign_priority_to_queue(cc->id, queue_priority_mapping[i][0],
+					 queue_priority_mapping[i][1]);
 
-		queue_priority_mapping = cc->info->queue_priority_mapping;
+	/* Map the channel to param entry if channel mapping logic */
+	if (edma_read(cc->id, EDMA_CCCFG) & CHMAP_EXIST)
+		map_dmach_param(cc->id);
 
-		/* Event queue priority mapping */
-		for (i = 0; queue_priority_mapping[i][0] != -1; i++)
-			assign_priority_to_queue(j,
-						 queue_priority_mapping[i][0],
-						 queue_priority_mapping[i][1]);
+	for (i = 0; i < cc->num_channels; i++) {
+		if (test_bit(i, cc->edma_inuse)) {
+			/* ensure access through shadow region 0 */
+			edma_or_array2(cc->id, EDMA_DRAE, 0, i >> 5,
+				       BIT(i & 0x1f));
 
-		/*
-		 * Map the channel to param entry if channel mapping logic
-		 * exist
-		 */
-		if (edma_read(j, EDMA_CCCFG) & CHMAP_EXIST)
-			map_dmach_param(j);
-
-		for (i = 0; i < cc->num_channels; i++) {
-			if (test_bit(i, cc->edma_inuse)) {
-				/* ensure access through shadow region 0 */
-				edma_or_array2(j, EDMA_DRAE, 0, i >> 5,
-					       BIT(i & 0x1f));
-
-				setup_dma_interrupt(i,
-						    cc->intr_data[i].callback,
-						    cc->intr_data[i].data);
-			}
+			setup_dma_interrupt(EDMA_CTLR_CHAN(cc->id, i),
+					    cc->intr_data[i].callback,
+					    cc->intr_data[i].data);
 		}
 	}
 
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 29e08aac8294..9ae049ae816a 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -147,150 +147,114 @@ static s8 da850_queue_priority_mapping[][2] = {
 	{-1, -1}
 };
 
-static struct edma_soc_info da830_edma_cc0_info = {
+static struct edma_soc_info da8xx_edma0_pdata = {
 	.queue_priority_mapping	= da8xx_queue_priority_mapping,
 	.default_queue		= EVENTQ_1,
 };
 
-static struct edma_soc_info *da830_edma_info[EDMA_MAX_CC] = {
-	&da830_edma_cc0_info,
+static struct edma_soc_info da850_edma1_pdata = {
+	.queue_priority_mapping	= da850_queue_priority_mapping,
+	.default_queue		= EVENTQ_0,
 };
 
-static struct edma_soc_info da850_edma_cc_info[] = {
+static struct resource da8xx_edma0_resources[] = {
 	{
-		.queue_priority_mapping	= da8xx_queue_priority_mapping,
-		.default_queue		= EVENTQ_1,
-	},
-	{
-		.queue_priority_mapping	= da850_queue_priority_mapping,
-		.default_queue		= EVENTQ_0,
-	},
-};
-
-static struct edma_soc_info *da850_edma_info[EDMA_MAX_CC] = {
-	&da850_edma_cc_info[0],
-	&da850_edma_cc_info[1],
-};
-
-static struct resource da830_edma_resources[] = {
-	{
-		.name	= "edma_cc0",
+		.name	= "edma3_cc",
 		.start	= DA8XX_TPCC_BASE,
 		.end	= DA8XX_TPCC_BASE + SZ_32K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma_tc0",
+		.name	= "edma3_tc0",
 		.start	= DA8XX_TPTC0_BASE,
 		.end	= DA8XX_TPTC0_BASE + SZ_1K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma_tc1",
+		.name	= "edma3_tc1",
 		.start	= DA8XX_TPTC1_BASE,
 		.end	= DA8XX_TPTC1_BASE + SZ_1K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma0",
+		.name	= "edma3_ccint",
 		.start	= IRQ_DA8XX_CCINT0,
 		.flags	= IORESOURCE_IRQ,
 	},
 	{
-		.name	= "edma0_err",
+		.name	= "edma3_ccerrint",
 		.start	= IRQ_DA8XX_CCERRINT,
 		.flags	= IORESOURCE_IRQ,
 	},
 };
 
-static struct resource da850_edma_resources[] = {
-	{
-		.name	= "edma_cc0",
-		.start	= DA8XX_TPCC_BASE,
-		.end	= DA8XX_TPCC_BASE + SZ_32K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.name	= "edma_tc0",
-		.start	= DA8XX_TPTC0_BASE,
-		.end	= DA8XX_TPTC0_BASE + SZ_1K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
+static struct resource da850_edma1_resources[] = {
 	{
-		.name	= "edma_tc1",
-		.start	= DA8XX_TPTC1_BASE,
-		.end	= DA8XX_TPTC1_BASE + SZ_1K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.name	= "edma_cc1",
+		.name	= "edma3_cc",
 		.start	= DA850_TPCC1_BASE,
 		.end	= DA850_TPCC1_BASE + SZ_32K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma_tc2",
+		.name	= "edma3_tc0",
 		.start	= DA850_TPTC2_BASE,
 		.end	= DA850_TPTC2_BASE + SZ_1K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma0",
-		.start	= IRQ_DA8XX_CCINT0,
-		.flags	= IORESOURCE_IRQ,
-	},
-	{
-		.name	= "edma0_err",
-		.start	= IRQ_DA8XX_CCERRINT,
-		.flags	= IORESOURCE_IRQ,
-	},
-	{
-		.name	= "edma1",
+		.name	= "edma3_ccint",
 		.start	= IRQ_DA850_CCINT1,
 		.flags	= IORESOURCE_IRQ,
 	},
 	{
-		.name	= "edma1_err",
+		.name	= "edma3_ccerrint",
 		.start	= IRQ_DA850_CCERRINT1,
 		.flags	= IORESOURCE_IRQ,
 	},
 };
 
-static struct platform_device da830_edma_device = {
+static struct platform_device da8xx_edma0_device = {
 	.name		= "edma",
-	.id		= -1,
+	.id		= 0,
 	.dev = {
-		.platform_data = da830_edma_info,
+		.platform_data = &da8xx_edma0_pdata,
 	},
-	.num_resources	= ARRAY_SIZE(da830_edma_resources),
-	.resource	= da830_edma_resources,
+	.num_resources	= ARRAY_SIZE(da8xx_edma0_resources),
+	.resource	= da8xx_edma0_resources,
 };
 
-static struct platform_device da850_edma_device = {
+static struct platform_device da850_edma1_device = {
 	.name		= "edma",
-	.id		= -1,
+	.id		= 1,
 	.dev = {
-		.platform_data = da850_edma_info,
+		.platform_data = &da850_edma1_pdata,
 	},
-	.num_resources	= ARRAY_SIZE(da850_edma_resources),
-	.resource	= da850_edma_resources,
+	.num_resources	= ARRAY_SIZE(da850_edma1_resources),
+	.resource	= da850_edma1_resources,
 };
 
 int __init da830_register_edma(struct edma_rsv_info *rsv)
 {
-	da830_edma_cc0_info.rsv = rsv;
+	da8xx_edma0_pdata.rsv = rsv;
 
-	return platform_device_register(&da830_edma_device);
+	return platform_device_register(&da8xx_edma0_device);
 }
 
 int __init da850_register_edma(struct edma_rsv_info *rsv[2])
 {
+	int ret;
+
 	if (rsv) {
-		da850_edma_cc_info[0].rsv = rsv[0];
-		da850_edma_cc_info[1].rsv = rsv[1];
+		da8xx_edma0_pdata.rsv = rsv[0];
+		da850_edma1_pdata.rsv = rsv[1];
 	}
 
-	return platform_device_register(&da850_edma_device);
+	ret = platform_device_register(&da8xx_edma0_device);
+	if (ret) {
+		pr_warn("%s: Failed to register eDMA0\n", __func__);
+		return ret;
+	}
+	return platform_device_register(&da850_edma1_device);
 }
 
 static struct resource da8xx_i2c_resources0[] = {
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 567dc56fe8cd..a50bb9c66952 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -569,49 +569,44 @@ static u8 dm355_default_priorities[DAVINCI_N_AINTC_IRQ] = {
 
 /*----------------------------------------------------------------------*/
 
-static s8
-queue_priority_mapping[][2] = {
+static s8 queue_priority_mapping[][2] = {
 	/* {event queue no, Priority} */
 	{0, 3},
 	{1, 7},
 	{-1, -1},
 };
 
-static struct edma_soc_info edma_cc0_info = {
+static struct edma_soc_info dm355_edma_pdata = {
 	.queue_priority_mapping	= queue_priority_mapping,
 	.default_queue		= EVENTQ_1,
 };
 
-static struct edma_soc_info *dm355_edma_info[EDMA_MAX_CC] = {
-       &edma_cc0_info,
-};
-
 static struct resource edma_resources[] = {
 	{
-		.name	= "edma_cc0",
+		.name	= "edma3_cc",
 		.start	= 0x01c00000,
 		.end	= 0x01c00000 + SZ_64K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma_tc0",
+		.name	= "edma3_tc0",
 		.start	= 0x01c10000,
 		.end	= 0x01c10000 + SZ_1K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma_tc1",
+		.name	= "edma3_tc1",
 		.start	= 0x01c10400,
 		.end	= 0x01c10400 + SZ_1K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma0",
+		.name	= "edma3_ccint",
 		.start	= IRQ_CCINT0,
 		.flags	= IORESOURCE_IRQ,
 	},
 	{
-		.name	= "edma0_err",
+		.name	= "edma3_ccerrint",
 		.start	= IRQ_CCERRINT,
 		.flags	= IORESOURCE_IRQ,
 	},
@@ -621,7 +616,7 @@ static struct resource edma_resources[] = {
 static struct platform_device dm355_edma_device = {
 	.name			= "edma",
 	.id			= 0,
-	.dev.platform_data	= dm355_edma_info,
+	.dev.platform_data	= &dm355_edma_pdata,
 	.num_resources		= ARRAY_SIZE(edma_resources),
 	.resource		= edma_resources,
 };
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 6a890a8486d0..2068cbeaeb03 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -853,8 +853,7 @@ static u8 dm365_default_priorities[DAVINCI_N_AINTC_IRQ] = {
 };
 
 /* Four Transfer Controllers on DM365 */
-static s8
-dm365_queue_priority_mapping[][2] = {
+static s8 dm365_queue_priority_mapping[][2] = {
 	/* {event queue no, Priority} */
 	{0, 7},
 	{1, 7},
@@ -863,53 +862,49 @@ dm365_queue_priority_mapping[][2] = {
 	{-1, -1},
 };
 
-static struct edma_soc_info edma_cc0_info = {
+static struct edma_soc_info dm365_edma_pdata = {
 	.queue_priority_mapping	= dm365_queue_priority_mapping,
 	.default_queue		= EVENTQ_3,
 };
 
-static struct edma_soc_info *dm365_edma_info[EDMA_MAX_CC] = {
-	&edma_cc0_info,
-};
-
 static struct resource edma_resources[] = {
 	{
-		.name	= "edma_cc0",
+		.name	= "edma3_cc",
 		.start	= 0x01c00000,
 		.end	= 0x01c00000 + SZ_64K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma_tc0",
+		.name	= "edma3_tc0",
 		.start	= 0x01c10000,
 		.end	= 0x01c10000 + SZ_1K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma_tc1",
+		.name	= "edma3_tc1",
 		.start	= 0x01c10400,
 		.end	= 0x01c10400 + SZ_1K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma_tc2",
+		.name	= "edma3_tc2",
 		.start	= 0x01c10800,
 		.end	= 0x01c10800 + SZ_1K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma_tc3",
+		.name	= "edma3_tc3",
 		.start	= 0x01c10c00,
 		.end	= 0x01c10c00 + SZ_1K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma0",
+		.name	= "edma3_ccint",
 		.start	= IRQ_CCINT0,
 		.flags	= IORESOURCE_IRQ,
 	},
 	{
-		.name	= "edma0_err",
+		.name	= "edma3_ccerrint",
 		.start	= IRQ_CCERRINT,
 		.flags	= IORESOURCE_IRQ,
 	},
@@ -919,7 +914,7 @@ static struct resource edma_resources[] = {
 static struct platform_device dm365_edma_device = {
 	.name			= "edma",
 	.id			= 0,
-	.dev.platform_data	= dm365_edma_info,
+	.dev.platform_data	= &dm365_edma_pdata,
 	.num_resources		= ARRAY_SIZE(edma_resources),
 	.resource		= edma_resources,
 };
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index dc52657909c4..d759ca8e58e8 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -498,49 +498,44 @@ static u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
 
 /*----------------------------------------------------------------------*/
 
-static s8
-queue_priority_mapping[][2] = {
+static s8 queue_priority_mapping[][2] = {
 	/* {event queue no, Priority} */
 	{0, 3},
 	{1, 7},
 	{-1, -1},
 };
 
-static struct edma_soc_info edma_cc0_info = {
+static struct edma_soc_info dm644x_edma_pdata = {
 	.queue_priority_mapping	= queue_priority_mapping,
 	.default_queue		= EVENTQ_1,
 };
 
-static struct edma_soc_info *dm644x_edma_info[EDMA_MAX_CC] = {
-	&edma_cc0_info,
-};
-
 static struct resource edma_resources[] = {
 	{
-		.name	= "edma_cc0",
+		.name	= "edma3_cc",
 		.start	= 0x01c00000,
 		.end	= 0x01c00000 + SZ_64K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma_tc0",
+		.name	= "edma3_tc0",
 		.start	= 0x01c10000,
 		.end	= 0x01c10000 + SZ_1K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma_tc1",
+		.name	= "edma3_tc1",
 		.start	= 0x01c10400,
 		.end	= 0x01c10400 + SZ_1K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma0",
+		.name	= "edma3_ccint",
 		.start	= IRQ_CCINT0,
 		.flags	= IORESOURCE_IRQ,
 	},
 	{
-		.name	= "edma0_err",
+		.name	= "edma3_ccerrint",
 		.start	= IRQ_CCERRINT,
 		.flags	= IORESOURCE_IRQ,
 	},
@@ -550,7 +545,7 @@ static struct resource edma_resources[] = {
 static struct platform_device dm644x_edma_device = {
 	.name			= "edma",
 	.id			= 0,
-	.dev.platform_data	= dm644x_edma_info,
+	.dev.platform_data	= &dm644x_edma_pdata,
 	.num_resources		= ARRAY_SIZE(edma_resources),
 	.resource		= edma_resources,
 };
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 3f842bb266d6..219ebc8f674a 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -531,8 +531,7 @@ static u8 dm646x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
 /*----------------------------------------------------------------------*/
 
 /* Four Transfer Controllers on DM646x */
-static s8
-dm646x_queue_priority_mapping[][2] = {
+static s8 dm646x_queue_priority_mapping[][2] = {
 	/* {event queue no, Priority} */
 	{0, 4},
 	{1, 0},
@@ -541,53 +540,49 @@ dm646x_queue_priority_mapping[][2] = {
 	{-1, -1},
 };
 
-static struct edma_soc_info edma_cc0_info = {
+static struct edma_soc_info dm646x_edma_pdata = {
 	.queue_priority_mapping	= dm646x_queue_priority_mapping,
 	.default_queue		= EVENTQ_1,
 };
 
-static struct edma_soc_info *dm646x_edma_info[EDMA_MAX_CC] = {
-	&edma_cc0_info,
-};
-
 static struct resource edma_resources[] = {
 	{
-		.name	= "edma_cc0",
+		.name	= "edma3_cc",
 		.start	= 0x01c00000,
 		.end	= 0x01c00000 + SZ_64K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma_tc0",
+		.name	= "edma3_tc0",
 		.start	= 0x01c10000,
 		.end	= 0x01c10000 + SZ_1K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma_tc1",
+		.name	= "edma3_tc1",
 		.start	= 0x01c10400,
 		.end	= 0x01c10400 + SZ_1K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma_tc2",
+		.name	= "edma3_tc2",
 		.start	= 0x01c10800,
 		.end	= 0x01c10800 + SZ_1K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma_tc3",
+		.name	= "edma3_tc3",
 		.start	= 0x01c10c00,
 		.end	= 0x01c10c00 + SZ_1K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
-		.name	= "edma0",
+		.name	= "edma3_ccint",
 		.start	= IRQ_CCINT0,
 		.flags	= IORESOURCE_IRQ,
 	},
 	{
-		.name	= "edma0_err",
+		.name	= "edma3_ccerrint",
 		.start	= IRQ_CCERRINT,
 		.flags	= IORESOURCE_IRQ,
 	},
@@ -597,7 +592,7 @@ static struct resource edma_resources[] = {
 static struct platform_device dm646x_edma_device = {
 	.name			= "edma",
 	.id			= 0,
-	.dev.platform_data	= dm646x_edma_info,
+	.dev.platform_data	= &dm646x_edma_pdata,
 	.num_resources		= ARRAY_SIZE(edma_resources),
 	.resource		= edma_resources,
 };
@@ -936,7 +931,7 @@ void dm646x_setup_vpif(struct vpif_display_config *display_config,
 
 int __init dm646x_init_edma(struct edma_rsv_info *rsv)
 {
-	edma_cc0_info.rsv = rsv;
+	dm646x_edma_pdata.rsv = rsv;
 
 	return platform_device_register(&dm646x_edma_device);
 }
-- 
2.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1232024 — [PATCH v4 08/25] ARM/dmaengine: edma: Remove limitation on the number of eDMA controllers

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2015-09-24 12:20 +0200
Subject[PATCH v4 08/25] ARM/dmaengine: edma: Remove limitation on the number of eDMA controllers
Message-ID<qcbN8-8v1-19@gated-at.bofh.it>
In reply to#1232021
Since the driver stack no longer depends on lookup with id number in a
global array of pointers, the limitation for the number of eDMAs are no
longer needed. We can handle as many eDMAs in legacy and DT boot as we have
memory for them to allocate the needed structures.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 arch/arm/common/edma.c | 22 +++++-----------------
 drivers/dma/edma.c     | 17 ++++++++---------
 2 files changed, 13 insertions(+), 26 deletions(-)

diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c
index 03692520812a..5b747f1bc8b5 100644
--- a/arch/arm/common/edma.c
+++ b/arch/arm/common/edma.c
@@ -1227,24 +1227,7 @@ static int edma_probe(struct platform_device *pdev)
 		.parent = &pdev->dev,
 	};
 
-	/* When booting with DT the pdev->id is -1 */
-	if (dev_id < 0)
-		dev_id = arch_num_cc;
-
-	if (dev_id >= EDMA_MAX_CC) {
-		dev_err(dev,
-			"eDMA3 with device id 0 and 1 is supported (id: %d)\n",
-			dev_id);
-		return -EINVAL;
-	}
-
 	if (node) {
-		/* Check if this is a second instance registered */
-		if (arch_num_cc) {
-			dev_err(dev, "only one EDMA instance is supported via DT\n");
-			return -ENODEV;
-		}
-
 		info = edma_setup_info_from_dt(dev, node);
 		if (IS_ERR(info)) {
 			dev_err(dev, "failed to get DT data\n");
@@ -1278,6 +1261,11 @@ static int edma_probe(struct platform_device *pdev)
 
 	cc->dev = dev;
 	cc->id = dev_id;
+	/* When booting with DT the pdev->id is -1 */
+	if (dev_id < 0) {
+		cc->id = 0;
+		dev_id = arch_num_cc;
+	}
 	dev_set_drvdata(dev, cc);
 
 	cc->base = devm_ioremap_resource(dev, mem);
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 53d48b2a700d..fc91ab9dd1bb 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -991,14 +991,12 @@ static void edma_dma_init(struct edma_cc *ecc, struct dma_device *dma,
 	INIT_LIST_HEAD(&dma->channels);
 }
 
-static struct of_dma_filter_info edma_filter_info = {
-	.filter_fn = edma_filter_fn,
-};
-
 static int edma_probe(struct platform_device *pdev)
 {
 	struct edma_cc *ecc;
 	struct device_node *parent_node = pdev->dev.parent->of_node;
+	struct platform_device *parent_pdev =
+					to_platform_device(pdev->dev.parent);
 	int ret;
 
 	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
@@ -1015,7 +1013,10 @@ static int edma_probe(struct platform_device *pdev)
 	if (!ecc->cc)
 		return -ENODEV;
 
-	ecc->ctlr = pdev->id;
+	ecc->ctlr = parent_pdev->id;
+	if (ecc->ctlr < 0)
+		ecc->ctlr = 0;
+
 	ecc->dummy_slot = edma_alloc_slot(ecc->cc, EDMA_SLOT_ANY);
 	if (ecc->dummy_slot < 0) {
 		dev_err(&pdev->dev, "Can't allocate PaRAM dummy slot\n");
@@ -1038,10 +1039,8 @@ static int edma_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, ecc);
 
 	if (parent_node) {
-		dma_cap_set(DMA_SLAVE, edma_filter_info.dma_cap);
-		dma_cap_set(DMA_CYCLIC, edma_filter_info.dma_cap);
-		of_dma_controller_register(parent_node, of_dma_simple_xlate,
-					   &edma_filter_info);
+		of_dma_controller_register(parent_node, of_dma_xlate_by_chan_id,
+					   &ecc->dma_slave);
 	}
 
 	dev_info(&pdev->dev, "TI EDMA DMA engine driver\n");
-- 
2.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1232025 — [PATCH v4 01/25] ARM: common: edma: Fix channel parameter for irq callbacks

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2015-09-24 12:20 +0200
Subject[PATCH v4 01/25] ARM: common: edma: Fix channel parameter for irq callbacks
Message-ID<qcbN9-8v1-23@gated-at.bofh.it>
In reply to#1232021
In case when the interrupt happened for the second eDMA the channel
number was incorrectly passed to the client driver.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
CC: <stable@vger.kernel.org>
---
 arch/arm/common/edma.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c
index 873dbfcc7dc9..56fc339571f9 100644
--- a/arch/arm/common/edma.c
+++ b/arch/arm/common/edma.c
@@ -406,7 +406,8 @@ static irqreturn_t dma_irq_handler(int irq, void *data)
 					BIT(slot));
 			if (edma_cc[ctlr]->intr_data[channel].callback)
 				edma_cc[ctlr]->intr_data[channel].callback(
-					channel, EDMA_DMA_COMPLETE,
+					EDMA_CTLR_CHAN(ctlr, channel),
+					EDMA_DMA_COMPLETE,
 					edma_cc[ctlr]->intr_data[channel].data);
 		}
 	} while (sh_ipr);
@@ -460,7 +461,8 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data)
 					if (edma_cc[ctlr]->intr_data[k].
 								callback) {
 						edma_cc[ctlr]->intr_data[k].
-						callback(k,
+						callback(
+						EDMA_CTLR_CHAN(ctlr, k),
 						EDMA_DMA_CC_ERROR,
 						edma_cc[ctlr]->intr_data
 						[k].data);
-- 
2.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1232029 — [PATCH v4 03/25] dmaengine: edma: Simplify and optimize the edma_execute path

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2015-09-24 12:20 +0200
Subject[PATCH v4 03/25] dmaengine: edma: Simplify and optimize the edma_execute path
Message-ID<qcbN9-8v1-25@gated-at.bofh.it>
In reply to#1232021
The code path in edma_execute() and edma_callback() can be simplified
and make it more optimal.
There is not need to call in to edma_execute() when the transfer
has been finished for example.
Also the handling of missed/first or next batch of paRAMs can
be done in a more optimal way.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/edma.c | 76 +++++++++++++++++++++---------------------------------
 1 file changed, 29 insertions(+), 47 deletions(-)

diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 3e5d4f193005..19fa49d6f555 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -154,15 +154,11 @@ static void edma_execute(struct edma_chan *echan)
 	struct device *dev = echan->vchan.chan.device->dev;
 	int i, j, left, nslots;
 
-	/* If either we processed all psets or we're still not started */
-	if (!echan->edesc ||
-	    echan->edesc->pset_nr == echan->edesc->processed) {
-		/* Get next vdesc */
+	if (!echan->edesc) {
+		/* Setup is needed for the first transfer */
 		vdesc = vchan_next_desc(&echan->vchan);
-		if (!vdesc) {
-			echan->edesc = NULL;
+		if (!vdesc)
 			return;
-		}
 		list_del(&vdesc->node);
 		echan->edesc = to_edma_desc(&vdesc->tx);
 	}
@@ -220,28 +216,26 @@ static void edma_execute(struct edma_chan *echan)
 				  echan->ecc->dummy_slot);
 	}
 
-	if (edesc->processed <= MAX_NR_SG) {
-		dev_dbg(dev, "first transfer starting on channel %d\n",
-			echan->ch_num);
-		edma_start(echan->ch_num);
-	} else {
-		dev_dbg(dev, "chan: %d: completed %d elements, resuming\n",
-			echan->ch_num, edesc->processed);
-		edma_resume(echan->ch_num);
-	}
-
-	/*
-	 * This happens due to setup times between intermediate transfers
-	 * in long SG lists which have to be broken up into transfers of
-	 * MAX_NR_SG
-	 */
 	if (echan->missed) {
+		/*
+		 * This happens due to setup times between intermediate
+		 * transfers in long SG lists which have to be broken up into
+		 * transfers of MAX_NR_SG
+		 */
 		dev_dbg(dev, "missed event on channel %d\n", echan->ch_num);
 		edma_clean_channel(echan->ch_num);
 		edma_stop(echan->ch_num);
 		edma_start(echan->ch_num);
 		edma_trigger_channel(echan->ch_num);
 		echan->missed = 0;
+	} else if (edesc->processed <= MAX_NR_SG) {
+		dev_dbg(dev, "first transfer starting on channel %d\n",
+			echan->ch_num);
+		edma_start(echan->ch_num);
+	} else {
+		dev_dbg(dev, "chan: %d: completed %d elements, resuming\n",
+			echan->ch_num, edesc->processed);
+		edma_resume(echan->ch_num);
 	}
 }
 
@@ -259,20 +253,17 @@ static int edma_terminate_all(struct dma_chan *chan)
 	 * echan->edesc is NULL and exit.)
 	 */
 	if (echan->edesc) {
-		int cyclic = echan->edesc->cyclic;
-
+		edma_stop(echan->ch_num);
+		/* Move the cyclic channel back to default queue */
+		if (echan->edesc->cyclic)
+			edma_assign_channel_eventq(echan->ch_num,
+						   EVENTQ_DEFAULT);
 		/*
 		 * free the running request descriptor
 		 * since it is not in any of the vdesc lists
 		 */
 		edma_desc_free(&echan->edesc->vdesc);
-
 		echan->edesc = NULL;
-		edma_stop(echan->ch_num);
-		/* Move the cyclic channel back to default queue */
-		if (cyclic)
-			edma_assign_channel_eventq(echan->ch_num,
-						   EVENTQ_DEFAULT);
 	}
 
 	vchan_get_all_descriptors(&echan->vchan, &head);
@@ -725,41 +716,33 @@ static void edma_callback(unsigned ch_num, u16 ch_status, void *data)
 
 	edesc = echan->edesc;
 
-	/* Pause the channel for non-cyclic */
-	if (!edesc || (edesc && !edesc->cyclic))
-		edma_pause(echan->ch_num);
-
+	spin_lock(&echan->vchan.lock);
 	switch (ch_status) {
 	case EDMA_DMA_COMPLETE:
-		spin_lock(&echan->vchan.lock);
-
 		if (edesc) {
 			if (edesc->cyclic) {
 				vchan_cyclic_callback(&edesc->vdesc);
+				goto out;
 			} else if (edesc->processed == edesc->pset_nr) {
 				dev_dbg(dev, "Transfer complete, stopping channel %d\n", ch_num);
 				edesc->residue = 0;
 				edma_stop(echan->ch_num);
 				vchan_cookie_complete(&edesc->vdesc);
-				edma_execute(echan);
+				echan->edesc = NULL;
 			} else {
 				dev_dbg(dev, "Intermediate transfer complete on channel %d\n", ch_num);
 
+				edma_pause(echan->ch_num);
+
 				/* Update statistics for tx_status */
 				edesc->residue -= edesc->sg_len;
 				edesc->residue_stat = edesc->residue;
 				edesc->processed_stat = edesc->processed;
-
-				edma_execute(echan);
 			}
+			edma_execute(echan);
 		}
-
-		spin_unlock(&echan->vchan.lock);
-
 		break;
 	case EDMA_DMA_CC_ERROR:
-		spin_lock(&echan->vchan.lock);
-
 		edma_read_slot(EDMA_CHAN_SLOT(echan->slot[0]), &p);
 
 		/*
@@ -788,13 +771,12 @@ static void edma_callback(unsigned ch_num, u16 ch_status, void *data)
 			edma_start(echan->ch_num);
 			edma_trigger_channel(echan->ch_num);
 		}
-
-		spin_unlock(&echan->vchan.lock);
-
 		break;
 	default:
 		break;
 	}
+out:
+	spin_unlock(&echan->vchan.lock);
 }
 
 /* Alloc channel resources */
-- 
2.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web