Skip to contentSkip to conversation

dma: mmp_pdma: fly-by transfers and external DMA requests support

PATCH New Laurent Pinchart 3 participants 14 messages Apr 15, 2014 – May 5, 2014

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover dma: mmp_pdma: fly-by transfers and external DMA requests support

Hello,

This patch set adds support for fly-by transfers and external DMA requests to the mmp_pdma driver. It's broken out as

- extending the dma_slave_config structure with a fly-by flag (1/6)
- miscellaneous small fixes and cleanups (2/6 to 4/6)
- fly-by transfer support (5/6)
- external DMA requests support (6/6)

I haven't been able to test the DT-related changes as my only PXA platform is a PXA270 that doesn't boot through DT yet.

Laurent Pinchart (6):
dmaengine: Add fly-by transfer flag to slave configuration structure
dma: mmp_pdma: Fix the #dma-channels DT property documentation
dma: mmp_pdma: Simplify access to channel drcmr value
dma: mmp_pdma: Fix physical channel memory allocation size
dma: mmp_pdma: Add support for fly-by transfers
dma: mmp_pdma: Add support externel DMA requests

 Documentation/devicetree/bindings/dma/mmp-dma.txt |  13 ++-
 drivers/dma/mmp_pdma.c                            | 110 ++++++++++++++++++----
 include/linux/dmaengine.h                         |  13 +++
 include/linux/platform_data/mmp_dma.h             |   2 +
 4 files changed, 116 insertions(+), 22 deletions(-)
Signature · 3 lines
Regards,

Laurent Pinchart
#1 lore raw

PATCH 1/6 dmaengine: Add fly-by transfer flag to slave configuration structure

Fly-by transfer mode cuts down the number of bus transactions by letting the slave drive or latch the memory data bus during memory transactions instead of performing a dedicated transaction to read data from or write data to the slave.

Support for fly-by mode by adding a new flag field to struct dma_slave_config.

---
 include/linux/dmaengine.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)
include/linux/dmaengine.h +13 -0
index c5c92d5..ae99153 100644
@@ -304,6 +304,17 @@ enum dma_slave_buswidth {
 };
 
 /**
+ * enum dma_slave_flags - DMA slave configuration flags
+ * @DMA_SLAVE_FLAG_FLY_BY - perform DMA transfers for the slave in fly-by mode.
+ *   Instead of performing a bus transaction to read (write) data from (to) the
+ *   slave, let the slave drive (latch) the memory bus data signals during the
+ *   memory write (read) transaction.
+ */
+enum dma_slave_flags {
+	DMA_SLAVE_FLAG_FLY_BY = (1 << 0),
+};
+
+/**
  * struct dma_slave_config - dma slave channel runtime config
  * @direction: whether the data shall go in or out on this slave
  * channel, right now. DMA_MEM_TO_DEV and DMA_DEV_TO_MEM are
@@ -333,6 +344,7 @@ enum dma_slave_buswidth {
  * @slave_id: Slave requester id. Only valid for slave channels. The dma
  * slave peripheral will have unique id as dma requester which need to be
  * pass as slave config.
+ * @flags: DMA slave flags, a combination of enum dma_slave_flags flags.
  *
  * This struct is passed in as configuration data to a DMA engine
  * in order to set up a certain channel for DMA transport@runtime.
@@ -361,6 +373,7 @@ struct dma_slave_config {
 	u32 dst_maxburst;
 	bool device_fc;
 	unsigned int slave_id;
+	u32 flags;
 };
 
 /**
Signature · 1 line
1.8.3.2
#2 lore raw

PATCH 1/6 dmaengine: Add fly-by transfer flag to slave configuration structure

Quoted 2 lines · Laurent Pinchart

Fly-by transfer mode cuts down the number of bus transactions by letting the slave drive or latch the memory data bus during memory transactions

?? ^^^^^^^^^^^

Quoted 1 line

instead of performing a dedicated transaction to read data from or write

/ ^^^^

Quoted 41 lines

data to the slave.

Support for fly-by mode by adding a new flag field to struct dma_slave_config.

---
 include/linux/dmaengine.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)
include/linux/dmaengine.h +12 -0
index c5c92d5..ae99153 100644
@@ -304,6 +304,17 @@ enum dma_slave_buswidth {
 };
 
 /**
+ * enum dma_slave_flags - DMA slave configuration flags
+ * @DMA_SLAVE_FLAG_FLY_BY - perform DMA transfers for the slave in fly-by mode.
+ *   Instead of performing a bus transaction to read (write) data from (to) the
+ *   slave, let the slave drive (latch) the memory bus data signals during the
+ *   memory write (read) transaction.
+ */
+enum dma_slave_flags {
+	DMA_SLAVE_FLAG_FLY_BY = (1 << 0),
+};
+
+/**
  * struct dma_slave_config - dma slave channel runtime config
  * @direction: whether the data shall go in or out on this slave
  * channel, right now. DMA_MEM_TO_DEV and DMA_DEV_TO_MEM are
@@ -333,6 +344,7 @@ enum dma_slave_buswidth {
  * @slave_id: Slave requester id. Only valid for slave channels. The dma
  * slave peripheral will have unique id as dma requester which need to be
  * pass as slave config.
+ * @flags: DMA slave flags, a combination of enum dma_slave_flags flags.
  *
  * This struct is passed in as configuration data to a DMA engine
  * in order to set up a certain channel for DMA transport at runtime.

include/linux/dmaengine.h struct dma_slave_config { · line 377

Quoted 5 lines
include/linux/dmaengine.h +1 -0
@@ -361,6 +373,7 @@ struct dma_slave_config {
 	u32 dst_maxburst;
 	bool device_fc;
 	unsigned int slave_id;
+	u32 flags;
 };

I am not sure about this. Should we have a generic flag for this or just add a bool for fly_by mode?

Suggestions?

Signature · 1 line
~Vinod
#3 lore raw

PATCH 1/6 dmaengine: Add fly-by transfer flag to slave configuration structure

On Fri, May 02, 2014 at 09:16:34PM +0530, Vinod Koul wrote:
+ Dan

Pls cc Dan as well

~Vinod

Quoted 60 lines · Laurent Pinchart
Quoted 2 lines

Fly-by transfer mode cuts down the number of bus transactions by letting the slave drive or latch the memory data bus during memory transactions

?? ^^^^^^^^^^^

Quoted 1 line

instead of performing a dedicated transaction to read data from or write

/ ^^^^

Quoted 41 lines

data to the slave.

Support for fly-by mode by adding a new flag field to struct dma_slave_config.

---
 include/linux/dmaengine.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)
include/linux/dmaengine.h +12 -0
index c5c92d5..ae99153 100644
@@ -304,6 +304,17 @@ enum dma_slave_buswidth {
 };
 
 /**
+ * enum dma_slave_flags - DMA slave configuration flags
+ * @DMA_SLAVE_FLAG_FLY_BY - perform DMA transfers for the slave in fly-by mode.
+ *   Instead of performing a bus transaction to read (write) data from (to) the
+ *   slave, let the slave drive (latch) the memory bus data signals during the
+ *   memory write (read) transaction.
+ */
+enum dma_slave_flags {
+	DMA_SLAVE_FLAG_FLY_BY = (1 << 0),
+};
+
+/**
  * struct dma_slave_config - dma slave channel runtime config
  * @direction: whether the data shall go in or out on this slave
  * channel, right now. DMA_MEM_TO_DEV and DMA_DEV_TO_MEM are
@@ -333,6 +344,7 @@ enum dma_slave_buswidth {
  * @slave_id: Slave requester id. Only valid for slave channels. The dma
  * slave peripheral will have unique id as dma requester which need to be
  * pass as slave config.
+ * @flags: DMA slave flags, a combination of enum dma_slave_flags flags.
  *
  * This struct is passed in as configuration data to a DMA engine
  * in order to set up a certain channel for DMA transport at runtime.

include/linux/dmaengine.h struct dma_slave_config { · line 377

Quoted 5 lines
include/linux/dmaengine.h +1 -0
@@ -361,6 +373,7 @@ struct dma_slave_config {
 	u32 dst_maxburst;
 	bool device_fc;
 	unsigned int slave_id;
+	u32 flags;
 };

I am not sure about this. Should we have a generic flag for this or just add a bool for fly_by mode?

Suggestions?

Signature · 1 line
~Vinod
#4 lore raw

PATCH 1/6 dmaengine: Add fly-by transfer flag to slave configuration structure

In reply to Laurent Pinchart
Quoted 18 lines · Laurent Pinchart

Fly-by transfer mode cuts down the number of bus transactions by letting the slave drive or latch the memory data bus during memory transactions instead of performing a dedicated transaction to read data from or write data to the slave.

Support for fly-by mode by adding a new flag field to struct dma_slave_config.

---
  include/linux/dmaengine.h | 13 +++++++++++++
  1 file changed, 13 insertions(+)
include/linux/dmaengine.h +0 -0
index c5c92d5..ae99153 100644

include/linux/dmaengine.h enum dma_slave_buswidth { · line 312

Quoted 9 lines
include/linux/dmaengine.h +6 -0
@@ -304,6 +304,17 @@ enum dma_slave_buswidth {
  };
 
  /**
+ * enum dma_slave_flags - DMA slave configuration flags
+ * @DMA_SLAVE_FLAG_FLY_BY - perform DMA transfers for the slave in fly-by mode.
+ *   Instead of performing a bus transaction to read (write) data from (to) the
+ *   slave, let the slave drive (latch) the memory bus data signals during the
+ *   memory write (read) transaction.
+ */

Is there any reason not to use fly-by mode for memory to peripheral or peripheral to memory transfers, if fly-by mode is available? And if not how should generic drivers using the DMAengine API decide when to use fly-by mode and when not?

- Lars

#5 lore raw

PATCH 2/6 dma: mmp_pdma: Fix the #dma-channels DT property documentation

In reply to Laurent Pinchart

The property is optional and defaults to 32. Document it as such.

Cc devicetree at vger.kernel.org
---
 Documentation/devicetree/bindings/dma/mmp-dma.txt | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/dma/mmp-dma.txt +7 -4
index a4fa4ef..7a802f6 100644
@@ -1,17 +1,20 @@
 * MARVELL MMP DMA controller
 
 Marvell Peripheral DMA Controller
-Used platfroms: pxa688, pxa910, pxa3xx, etc
+Used platforms: pxa688, pxa910, pxa3xx, etc
 
 Required properties:
 - compatible: Should be "marvell,pdma-1.0"
 - reg: Should contain DMA registers location and length.
 - interrupts: Either contain all of the per-channel DMA interrupts
 		or one irq for pdma device
-- #dma-channels: Number of DMA channels supported by the controller.
+
+Optional properties:
+- #dma-channels: Number of DMA channels supported by the controller (defaults
+  to 32 when not specified)
 
 "marvell,pdma-1.0"
-Used platfroms: pxa25x, pxa27x, pxa3xx, pxa93x, pxa168, pxa910, pxa688.
+Used platforms: pxa25x, pxa27x, pxa3xx, pxa93x, pxa168, pxa910, pxa688.
 
 Examples:
 
@@ -45,7 +48,7 @@ pdma: dma-controller at d4000000 {
 
 
 Marvell Two Channel DMA Controller used specifically for audio
-Used platfroms: pxa688, pxa910
+Used platforms: pxa688, pxa910
 
 Required properties:
 - compatible: Should be "marvell,adma-1.0" or "marvell,pxa910-squ"
Signature · 1 line
1.8.3.2
Applied
#6 lore raw

PATCH 2/6 dma: mmp_pdma: Fix the #dma-channels DT property documentation

Quoted 1 line · Laurent Pinchart

The property is optional and defaults to 32. Document it as such.

Applied, thanks

Signature · 1 line
~Vinod
#7 lore raw

PATCH 3/6 dma: mmp_pdma: Simplify access to channel drcmr value

In reply to Laurent Pinchart

As the physical channel and virtual channel point to each other, pchan->phy->vchan is always equal to pchan. Simplify the code accordingly.

---
 drivers/dma/mmp_pdma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/dma/mmp_pdma.c +1 -1
index b439679..643f225 100644
@@ -277,7 +277,7 @@ static void mmp_pdma_free_phy(struct mmp_pdma_chan *pchan)
 		return;
 
 	/* clear the channel mapping in DRCMR */
-	reg = DRCMR(pchan->phy->vchan->drcmr);
+	reg = DRCMR(pchan->drcmr);
 	writel(0, pchan->phy->base + reg);
 
 	spin_lock_irqsave(&pdev->phy_lock, flags);
Signature · 1 line
1.8.3.2
Applied
#8 lore raw

PATCH 3/6 dma: mmp_pdma: Simplify access to channel drcmr value

Quoted 4 lines · Laurent Pinchart

As the physical channel and virtual channel point to each other, pchan->phy->vchan is always equal to pchan. Simplify the code accordingly.

Applied, thanks

Signature · 1 line
~Vinod
#9 lore raw

PATCH 4/6 dma: mmp_pdma: Fix physical channel memory allocation size

In reply to Laurent Pinchart

Use sizeof(*var) instead of sizeof(type) when calling devm_k*alloc(). This avoids using the wrong type as was done to allocate the physical channels array.

---
 drivers/dma/mmp_pdma.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/dma/mmp_pdma.c +2 -4
index 643f225..7ed7850 100644
@@ -858,8 +858,7 @@ static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev, int idx, int irq)
 	struct mmp_pdma_chan *chan;
 	int ret;
 
-	chan = devm_kzalloc(pdev->dev, sizeof(struct mmp_pdma_chan),
-			    GFP_KERNEL);
+	chan = devm_kzalloc(pdev->dev, sizeof(*chan), GFP_KERNEL);
 	if (chan == NULL)
 		return -ENOMEM;
 
@@ -946,8 +945,7 @@ static int mmp_pdma_probe(struct platform_device *op)
 			irq_num++;
 	}
 
-	pdev->phy = devm_kcalloc(pdev->dev,
-				 dma_channels, sizeof(struct mmp_pdma_chan),
+	pdev->phy = devm_kcalloc(pdev->dev, dma_channels, sizeof(*pdev->phy),
 				 GFP_KERNEL);
 	if (pdev->phy == NULL)
 		return -ENOMEM;
Signature · 1 line
1.8.3.2
Applied
#10 lore raw

PATCH 4/6 dma: mmp_pdma: Fix physical channel memory allocation size

Quoted 4 lines · Laurent Pinchart

Use sizeof(*var) instead of sizeof(type) when calling devm_k*alloc(). This avoids using the wrong type as was done to allocate the physical channels array.

Applied, thanks

Signature · 1 line
~Vinod
#11 lore raw

PATCH 5/6 dma: mmp_pdma: Add support for fly-by transfers

In reply to Laurent Pinchart

Enable fly-by mode when the DMA_SLAVE_FLAG_FLY_BY flag is set in the slave configuration.

---
 drivers/dma/mmp_pdma.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/dma/mmp_pdma.c +6 -0
index 7ed7850..849bf75 100644
@@ -63,6 +63,8 @@
 #define DCMD_FLOWTRG	BIT(28)	/* Flow Control by the target. */
 #define DCMD_STARTIRQEN	BIT(22)	/* Start Interrupt Enable */
 #define DCMD_ENDIRQEN	BIT(21)	/* End Interrupt Enable */
+#define DCMD_FLYBYS	BIT(20)	/* Fly-By Source */
+#define DCMD_FLYBYT	BIT(19)	/* Fly-By Target */
 #define DCMD_ENDIAN	BIT(18)	/* Device Endian-ness. */
 #define DCMD_BURST8	(1 << 16)	/* 8 byte burst */
 #define DCMD_BURST16	(2 << 16)	/* 16 byte burst */
@@ -708,11 +710,15 @@ static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
 	case DMA_SLAVE_CONFIG:
 		if (cfg->direction == DMA_DEV_TO_MEM) {
 			chan->dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC;
+			if (cfg->flags & DMA_SLAVE_FLAG_FLY_BY)
+				chan->dcmd |= DCMD_FLYBYT;
 			maxburst = cfg->src_maxburst;
 			width = cfg->src_addr_width;
 			addr = cfg->src_addr;
 		} else if (cfg->direction == DMA_MEM_TO_DEV) {
 			chan->dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG;
+			if (cfg->flags & DMA_SLAVE_FLAG_FLY_BY)
+				chan->dcmd |= DCMD_FLYBYS;
 			maxburst = cfg->dst_maxburst;
 			width = cfg->dst_addr_width;
 			addr = cfg->dst_addr;
Signature · 1 line
1.8.3.2
#12 lore raw

PATCH 6/6 dma: mmp_pdma: Add support externel DMA requests

In reply to Laurent Pinchart

The MMP/PXA DMA engine supports transfer initiation by external chips through DMA request (DREQ) signals. Support them by clearing pending DMA requests for the associated source when starting a channel.

The request ID to DREQ index mapping depends on the hardware and is passed through platform data or DT.

Cc devicetree at vger.kernel.org
---
 Documentation/devicetree/bindings/dma/mmp-dma.txt |  2 +
 drivers/dma/mmp_pdma.c                            | 96 ++++++++++++++++++++---
 include/linux/platform_data/mmp_dma.h             |  2 +
 3 files changed, 87 insertions(+), 13 deletions(-)
Documentation/devicetree/bindings/dma/mmp-dma.txt +2 -0
index 7a802f6..edb9ff3 100644
@@ -12,6 +12,8 @@ Required properties:
 Optional properties:
 - #dma-channels: Number of DMA channels supported by the controller (defaults
   to 32 when not specified)
+- marvell,dreq: Array of the DMA request IDs corresponding to each of the
+  external device request (DREQ) lines
 
 "marvell,pdma-1.0"
 Used platforms: pxa25x, pxa27x, pxa3xx, pxa93x, pxa168, pxa910, pxa688.
drivers/dma/mmp_pdma.c +83 -13

164 lines not on this page · raw message

include/linux/platform_data/mmp_dma.h +2 -0
index 2a330ec..32595b8 100644
@@ -14,6 +14,8 @@
 
 struct mmp_dma_platdata {
 	int dma_channels;
+	unsigned int num_dreq;
+	const u32 *dreq;
 };
 
 #endif /* MMP_DMA_H */
Signature · 1 line
1.8.3.2
#13 lore raw

PATCH 6/6 dma: mmp_pdma: Add support externel DMA requests

Quoted 20 lines · Laurent Pinchart

The MMP/PXA DMA engine supports transfer initiation by external chips through DMA request (DREQ) signals. Support them by clearing pending DMA requests for the associated source when starting a channel.

The request ID to DREQ index mapping depends on the hardware and is passed through platform data or DT.

Cc devicetree at vger.kernel.org
---
 Documentation/devicetree/bindings/dma/mmp-dma.txt |  2 +
 drivers/dma/mmp_pdma.c                            | 96 ++++++++++++++++++++---
 include/linux/platform_data/mmp_dma.h             |  2 +
 3 files changed, 87 insertions(+), 13 deletions(-)
Documentation/devicetree/bindings/dma/mmp-dma.txt +0 -0
index 7a802f6..edb9ff3 100644

Documentation/devicetree/bindings/dma/mmp-dma.txt Required properties: · line 19

Quoted 8 lines
Documentation/devicetree/bindings/dma/mmp-dma.txt +2 -0
@@ -12,6 +12,8 @@ Required properties:
 Optional properties:
 - #dma-channels: Number of DMA channels supported by the controller (defaults
   to 32 when not specified)
+- marvell,dreq: Array of the DMA request IDs corresponding to each of the
+  external device request (DREQ) lines
 
 "marvell,pdma-1.0"
 Used platforms: pxa25x, pxa27x, pxa3xx, pxa93x, pxa168, pxa910, pxa688.

Can you please split the binding to separate patch and we need to get an ACK on it from DT folks.

The below looks fine to me

Signature · 1 line
~Vinod
Quoted 198 lines
drivers/dma/mmp_pdma.c +83 -13
index 849bf75..4546a1c 100644
@@ -27,6 +27,7 @@
 
 #define DCSR		0x0000
 #define DALGN		0x00a0
+#define DRQSR(n)	(0x00e0 + ((n) << 2))
 #define DINT		0x00f0
 #define DDADR		0x0200
 #define DSADR		0x0204
@@ -50,6 +51,9 @@
 #define DCSR_CMPST	BIT(10)	/* The Descriptor Compare Status */
 #define DCSR_EORINTR	BIT(9)	/* The end of Receive */
 
+#define DRQSR_CLR	BIT(8)	/* Clear Pending Requests */
+#define DRQSR_REQPEND	0x1f	/* Requests Pending */
+
 #define DRCMR(n)	((((n) < 64) ? 0x0100 : 0x1100) + (((n) & 0x3f) << 2))
 #define DRCMR_MAPVLD	BIT(7)	/* Map Valid (read / write) */
 #define DRCMR_CHLNUM	0x1f	/* mask for Channel Number (read / write) */
@@ -108,6 +112,7 @@ struct mmp_pdma_chan {
 	u32 dcmd;
 	u32 drcmr;
 	u32 dev_addr;
+	int drq;
 
 	/* list for desc */
 	spinlock_t desc_lock;		/* Descriptor list lock */
@@ -127,6 +132,8 @@ struct mmp_pdma_phy {
 
 struct mmp_pdma_device {
 	int				dma_channels;
+	unsigned int			num_dreq;
+	const u32			*dreq;
 	void __iomem			*base;
 	struct device			*dev;
 	struct dma_device		device;
@@ -167,6 +174,9 @@ static void enable_chan(struct mmp_pdma_phy *phy)
 		dalgn &= ~(1 << phy->idx);
 	writel(dalgn, phy->base + DALGN);
 
+	if (phy->vchan->drq != -1)
+		writel(DRQSR_CLR, phy->base + DRQSR(phy->vchan->drq));
+
 	reg = (phy->idx << 2) + DCSR;
 	writel(readl(phy->base + reg) | DCSR_RUN, phy->base + reg);
 }
@@ -685,6 +695,22 @@ fail:
 	return NULL;
 }
 
+static void mmp_pdma_set_drcmr(struct mmp_pdma_chan *chan, unsigned int drmcr)
+{
+	struct mmp_pdma_device *pdev = to_mmp_pdma_dev(cchan->chan.device);
+	unsigned int i;
+
+	chan->drcmr = drmcr;
+	chan->drq = -1;
+
+	for (i = 0; i < pdev->num_dreq; ++i) {
+		if (pdev->dreq[i] == drmcr) {
+			chan->drq = i;
+			break;
+		}
+	}
+}
+
 static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
 			    unsigned long arg)
 {
@@ -745,7 +771,7 @@ static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
 		 * be removed.
 		 */
 		if (cfg->slave_id)
-			chan->drcmr = cfg->slave_id;
+			mmp_pdma_set_drcmr(chan, cfg->slave_id);
 		break;
 	default:
 		return -ENOSYS;
@@ -909,16 +935,64 @@ static struct dma_chan *mmp_pdma_dma_xlate(struct of_phandle_args *dma_spec,
 	if (!chan)
 		return NULL;
 
-	to_mmp_pdma_chan(chan)->drcmr = dma_spec->args[0];
+	mmp_pdma_set_drcmr(to_mmp_pdma_chan(chan), dma_spec->args[0]);
 
 	return chan;
 }
 
+static int mmap_pdma_parse_platform_data(struct mmp_pdma_device *pdev)
+{
+	struct device_node *np = pdev->dev->of_node;
+	struct property *prop;
+
+	/* Default values: 32 channels, no external DREQ. */
+	pdev->dma_channels = 32;
+	pdev->num_dreq = 0;
+
+	if (!IS_ENABLED(CONFIG_OF) || !np) {
+		struct mmp_dma_platdata *pdata = dev_get_platdata(pdev->dev);
+
+		if (!pdata)
+			return 0;
+
+		if (pdata->dma_channels)
+			pdev->dma_channels = pdata->dma_channels;
+		if (pdata->num_dreq) {
+			pdev->num_dreq = pdata->num_dreq;
+			pdev->dreq = pdata->dreq;
+		}
+
+		return 0;
+	}
+
+	of_property_read_u32(np, "#dma-channels", &pdev->dma_channels);
+
+	prop = of_find_property(np, "marvell,dreq");
+	if (prop) {
+		unsigned int num_dreq = prop->length / sizeof(unsigned long);
+		u32 *dreq;
+
+		dreq = devm_kcalloc(pdev->dev, num_dreq, sizeof(*pdreq),
+				    GFP_KERNEL);
+		if (dreq == NULL)
+			return -ENOMEM;
+
+		ret = of_property_read_u32_array(np, "marvell,dreq", dreq,
+						 num_dreq);
+		if (ret < 0)
+			return ret;
+
+		pdev->num_dreq = num_dreq;
+		pdev->dreq = dreq;
+	}
+
+	return 0;
+}
+
 static int mmp_pdma_probe(struct platform_device *op)
 {
 	struct mmp_pdma_device *pdev;
 	const struct of_device_id *of_id;
-	struct mmp_dma_platdata *pdata = dev_get_platdata(&op->dev);
 	struct resource *iores;
 	int i, ret, irq = 0;
 	int dma_channels = 0, irq_num = 0;
@@ -936,15 +1010,11 @@ static int mmp_pdma_probe(struct platform_device *op)
 	if (IS_ERR(pdev->base))
 		return PTR_ERR(pdev->base);
 
-	of_id = of_match_device(mmp_pdma_dt_ids, pdev->dev);
-	if (of_id)
-		of_property_read_u32(pdev->dev->of_node, "#dma-channels",
-				     &dma_channels);
-	else if (pdata && pdata->dma_channels)
-		dma_channels = pdata->dma_channels;
-	else
-		dma_channels = 32;	/* default 32 channel */
-	pdev->dma_channels = dma_channels;
+	ret = mmp_pdma_parse_platform_data(pdev);
+	if (ret < 0)
+		return ret;
+
+	dma_channels = pdev->dma_channels;
 
 	for (i = 0; i < dma_channels; i++) {
 		if (platform_get_irq(op, i) > 0)
@@ -1038,7 +1108,7 @@ bool mmp_pdma_filter_fn(struct dma_chan *chan, void *param)
 	if (chan->device->dev->driver != &mmp_pdma_driver.driver)
 		return false;
 
-	c->drcmr = *(unsigned int *)param;
+	mmp_pdma_set_drcmr(c, *(unsigned int *)param);
 
 	return true;
 }
include/linux/platform_data/mmp_dma.h +2 -0
index 2a330ec..32595b8 100644
@@ -14,6 +14,8 @@
 
 struct mmp_dma_platdata {
 	int dma_channels;
+	unsigned int num_dreq;
+	const u32 *dreq;
 };
 
 #endif /* MMP_DMA_H */
Signature · 6 lines
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe dmaengine" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html