Skip to contentSkip to conversation

dmaengine: Add support for BCM2835

PATCH Superseded Florian Meier 7 participants 13 messages Nov 17, 2013 – Nov 28, 2013

Subsystems (4)

v7 of 10 Superseded Latest is v10 →

lore
Share & tools
lore
#0 lore raw

PATCH v7 1/1 dmaengine: Add support for BCM2835

Add support for DMA controller of BCM2835 as used in the Raspberry Pi. Currently it only supports cyclic DMA.

---

This version includes some more style improvements suggested in the previous thread.

 .../devicetree/bindings/dma/bcm2835-dma.txt        |   56 ++
 drivers/dma/Kconfig                                |    6 +
 drivers/dma/Makefile                               |    1 +
 drivers/dma/bcm2835-dma.c                          |  736 ++++++++++++++++++++
 4 files changed, 799 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/bcm2835-dma.txt
 create mode 100644 drivers/dma/bcm2835-dma.c
Documentation/devicetree/bindings/dma/bcm2835-dma.txt new file +56 -0
new file mode 100644
index 0000000..7d91019
@@ -0,0 +1,56 @@
+* BCM2835 DMA controller
+
+Required properties:
+- compatible: Should be "brcm,bcm2835-dma".
+- reg: Should contain DMA registers location and length.
+- interrupts: Should contain the DMA interrupts associated
+		to the DMA channels in ascending order.
+		First cell is the IRQ bank.
+		Second cell is the IRQ number.
+- #dma-cells: Must be <1>, used to represent the number of integer cells in
+		the dmas property of client devices.
+- brcm,dma-channel-mask: Bit mask representing the channels
+			 not used by the firmware.
+
+Example:
+
+dma: dma at 7e007000 {
+	compatible = "brcm,bcm2835-dma";
+	reg = <0x7e007000 0xf00>;
+	interrupts = <1 16
+		      1 17
+		      1 18
+		      1 19
+		      1 20
+		      1 21
+		      1 22
+		      1 23
+		      1 24
+		      1 25
+		      1 26
+		      1 27
+		      1 28>;
+
+	#dma-cells = <1>;
+	brcm,dma-channel-mask = <0x7f35>;
+};
+
+DMA clients connected to the BCM2835 DMA controller must use the format
+described in the dma.txt file, using a two-cell specifier for each channel:
+a phandle plus one integer cells.
+The two cells in order are:
+
+1. A phandle pointing to the DMA controller.
+2. The DREQ number.
+
+Example:
+
+bcm2835_i2s: i2s at 7e203000 {
+	compatible = "brcm,bcm2835-i2s";
+	reg = <	0x7e203000 0x20
+		0x7e101098 0x02>;
+
+	dmas = <&dma 2
+		&dma 3>;
+	dma-names = "tx", "rx";
+};
drivers/dma/Kconfig +6 -0
index c61a6ec..880e723 100644
@@ -300,6 +300,12 @@ config DMA_OMAP
 	select DMA_ENGINE
 	select DMA_VIRTUAL_CHANNELS
 
+config DMA_BCM2835
+	tristate "BCM2835 DMA engine support"
+	depends on (ARCH_BCM2835 || MACH_BCM2708)
+	select DMA_ENGINE
+	select DMA_VIRTUAL_CHANNELS
+
 config TI_CPPI41
 	tristate "AM33xx CPPI41 DMA support"
 	depends on ARCH_OMAP
drivers/dma/Makefile +1 -0
index 0ce2da9..0a6f08e 100644
@@ -38,6 +38,7 @@ obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
 obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
 obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
 obj-$(CONFIG_DMA_OMAP) += omap-dma.o
+obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o
 obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
 obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
 obj-$(CONFIG_TI_CPPI41) += cppi41.o
drivers/dma/bcm2835-dma.c new file +736 -0

736 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#1 lore raw
Quoted 2 lines · Florian Meier

Add support for DMA controller of BCM2835 as used in the Raspberry Pi. Currently it only supports cyclic DMA.

[]

drivers/dma/bcm2835-dma.c

Quoted 1 line
drivers/dma/bcm2835-dma.c +0 -0

[]

Quoted 12 lines
drivers/dma/bcm2835-dma.c +12 -0
+static int bcm2835_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+	unsigned long arg)
+{
+	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
+	int ret;
+
+	switch (cmd) {
+	case DMA_SLAVE_CONFIG:
+		return bcm2835_dma_slave_config(c,
+				(struct dma_slave_config *)arg);
+
+	case DMA_TERMINATE_ALL:

drivers/dma/bcm2835-dma.c line 516

Quoted 10 lines
drivers/dma/bcm2835-dma.c +10 -0
+		bcm2835_dma_terminate_all(c);
+		break;
+
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}

case DMA_TERMINATE_ALL returns an uninitialized ret;

[]

Quoted 13 lines
drivers/dma/bcm2835-dma.c +13 -0
+static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
+					   struct of_dma *ofdma)
+{
+	struct bcm2835_dmadev *d = ofdma->of_dma_data;
+	struct dma_chan *chan, *candidate;
+
+retry:
+	candidate = NULL;
+
+	/* Walk the list of channels registered with the current instance and
+	 * find one that is currently unused */
+	list_for_each_entry(chan, &d->ddev.channels, device_node)
+		if (chan->client_count == 0) {

drivers/dma/bcm2835-dma.c line 580

Quoted 10 lines
drivers/dma/bcm2835-dma.c +10 -0
+			candidate = chan;
+			break;
+		}
+
+	if (!candidate)
+		return NULL;
+
+	/* dma_get_slave_channel will return NULL if we lost a race between
+	 * the lookup and the reservation */
+	chan = dma_get_slave_channel(candidate);

Can that race happen consistently?
Does this avoid being a tight loop?

drivers/dma/bcm2835-dma.c line 592

Quoted 11 lines
drivers/dma/bcm2835-dma.c +11 -0
+	if (chan) {
+		struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
+
+		/* Set DREQ from param */
+		c->dreq = spec->args[0];
+
+		return chan;
+	}
+
+	goto retry;
+}

Also, I think this would be better as:

	if (!chan)
		goto retry;

	to_bcm2835_dma_chan(chan)->dreq = spec->args[0];

	return chan;
}

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

#2 lore raw
Quoted 22 lines · Joe Perches
Quoted 2 lines · Florian Meier

Add support for DMA controller of BCM2835 as used in the Raspberry Pi. Currently it only supports cyclic DMA.

[]

drivers/dma/bcm2835-dma.c

Quoted 1 line
drivers/dma/bcm2835-dma.c +0 -0

[]

Quoted 16 lines
drivers/dma/bcm2835-dma.c +16 -0
+static int bcm2835_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+	unsigned long arg)
+{
+	struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
+	int ret;
+
+	switch (cmd) {
+	case DMA_SLAVE_CONFIG:
+		return bcm2835_dma_slave_config(c,
+				(struct dma_slave_config *)arg);
+
+	case DMA_TERMINATE_ALL:
+		bcm2835_dma_terminate_all(c);
+		break;
+
+	default:
Quoted 8 lines

drivers/dma/bcm2835-dma.c line 516

Quoted 6 lines
drivers/dma/bcm2835-dma.c +6 -0
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}

case DMA_TERMINATE_ALL returns an uninitialized ret;

Oh yes - stupid mistake. Thank you!

Quoted 20 lines

[]

Quoted 18 lines
drivers/dma/bcm2835-dma.c +18 -0
+static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
+					   struct of_dma *ofdma)
+{
+	struct bcm2835_dmadev *d = ofdma->of_dma_data;
+	struct dma_chan *chan, *candidate;
+
+retry:
+	candidate = NULL;
+
+	/* Walk the list of channels registered with the current instance and
+	 * find one that is currently unused */
+	list_for_each_entry(chan, &d->ddev.channels, device_node)
+		if (chan->client_count == 0) {
+			candidate = chan;
+			break;
+		}
+
+	if (!candidate)
Quoted 8 lines

drivers/dma/bcm2835-dma.c line 580

Quoted 5 lines
drivers/dma/bcm2835-dma.c +5 -0
+		return NULL;
+
+	/* dma_get_slave_channel will return NULL if we lost a race between
+	 * the lookup and the reservation */
+	chan = dma_get_slave_channel(candidate);

Can that race happen consistently?
Does this avoid being a tight loop?

I would say this can not happen.
If I get everything right, the conflicting process will not get NULL (because it has won the race). In the worst case, a new process enters the race, but this will only continue until all channels are used. In that case no candidate exists and the loop will exit.

At least, the code is directly taken from mmp_pdma.c ;-)

Greetings,
Florian

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

#3 lore raw

PATCH 1/1 mmp_pdma: Style neatening

Neaten code used as a template for other drivers. Make the code more consistent with kernel styles.

o Convert #defines with (1<<foo) to BIT(foo)
o Alignment wrapping
o Logic inversions to put return at end of functions
o Convert devm_kzalloc with multiply to devm_kcalloc
o typo of Peripheral fix

---

Quoted 1 line

At least, the code is directly taken from mmp_pdma.c ;-)

Well, maybe the template code should be updated if there are going to be more of these.

Uncompiled/untested.

 drivers/dma/mmp_pdma.c | 204 +++++++++++++++++++++++++------------------------
 1 file changed, 105 insertions(+), 99 deletions(-)
drivers/dma/mmp_pdma.c +105 -99
index dcb1e05..c2658f6 100644
@@ -5,6 +5,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -32,38 +33,37 @@
 #define DTADR		0x0208
 #define DCMD		0x020c
 
-#define DCSR_RUN	(1 << 31)	/* Run Bit (read / write) */
-#define DCSR_NODESC	(1 << 30)	/* No-Descriptor Fetch (read / write) */
-#define DCSR_STOPIRQEN	(1 << 29)	/* Stop Interrupt Enable (read / write) */
-#define DCSR_REQPEND	(1 << 8)	/* Request Pending (read-only) */
-#define DCSR_STOPSTATE	(1 << 3)	/* Stop State (read-only) */
-#define DCSR_ENDINTR	(1 << 2)	/* End Interrupt (read / write) */
-#define DCSR_STARTINTR	(1 << 1)	/* Start Interrupt (read / write) */
-#define DCSR_BUSERR	(1 << 0)	/* Bus Error Interrupt (read / write) */
-
-#define DCSR_EORIRQEN	(1 << 28)       /* End of Receive Interrupt Enable (R/W) */
-#define DCSR_EORJMPEN	(1 << 27)       /* Jump to next descriptor on EOR */
-#define DCSR_EORSTOPEN	(1 << 26)       /* STOP on an EOR */
-#define DCSR_SETCMPST	(1 << 25)       /* Set Descriptor Compare Status */
-#define DCSR_CLRCMPST	(1 << 24)       /* Clear Descriptor Compare Status */
-#define DCSR_CMPST	(1 << 10)       /* The Descriptor Compare Status */
-#define DCSR_EORINTR	(1 << 9)        /* The end of Receive */
-
-#define DRCMR(n)	((((n) < 64) ? 0x0100 : 0x1100) + \
-				 (((n) & 0x3f) << 2))
-#define DRCMR_MAPVLD	(1 << 7)	/* Map Valid (read / write) */
-#define DRCMR_CHLNUM	0x1f		/* mask for Channel Number (read / write) */
+#define DCSR_RUN	BIT(31)	/* Run Bit (read / write) */
+#define DCSR_NODESC	BIT(30)	/* No-Descriptor Fetch (read / write) */
+#define DCSR_STOPIRQEN	BIT(29)	/* Stop Interrupt Enable (read / write) */
+#define DCSR_REQPEND	BIT(8)	/* Request Pending (read-only) */
+#define DCSR_STOPSTATE	BIT(3)	/* Stop State (read-only) */
+#define DCSR_ENDINTR	BIT(2)	/* End Interrupt (read / write) */
+#define DCSR_STARTINTR	BIT(1)	/* Start Interrupt (read / write) */
+#define DCSR_BUSERR	BIT(0)	/* Bus Error Interrupt (read / write) */
+
+#define DCSR_EORIRQEN	BIT(28)	/* End of Receive Interrupt Enable (R/W) */
+#define DCSR_EORJMPEN	BIT(27)	/* Jump to next descriptor on EOR */
+#define DCSR_EORSTOPEN	BIT(26)	/* STOP on an EOR */
+#define DCSR_SETCMPST	BIT(25)	/* Set Descriptor Compare Status */
+#define DCSR_CLRCMPST	BIT(24)	/* Clear Descriptor Compare Status */
+#define DCSR_CMPST	BIT(10)	/* The Descriptor Compare Status */
+#define DCSR_EORINTR	BIT(9)	/* The end of Receive */
+
+#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) */
 
 #define DDADR_DESCADDR	0xfffffff0	/* Address of next descriptor (mask) */
-#define DDADR_STOP	(1 << 0)	/* Stop (read / write) */
-
-#define DCMD_INCSRCADDR	(1 << 31)	/* Source Address Increment Setting. */
-#define DCMD_INCTRGADDR	(1 << 30)	/* Target Address Increment Setting. */
-#define DCMD_FLOWSRC	(1 << 29)	/* Flow Control by the source. */
-#define DCMD_FLOWTRG	(1 << 28)	/* Flow Control by the target. */
-#define DCMD_STARTIRQEN	(1 << 22)	/* Start Interrupt Enable */
-#define DCMD_ENDIRQEN	(1 << 21)	/* End Interrupt Enable */
-#define DCMD_ENDIAN	(1 << 18)	/* Device Endian-ness. */
+#define DDADR_STOP	BIT(0)	/* Stop (read / write) */
+
+#define DCMD_INCSRCADDR	BIT(31)	/* Source Address Increment Setting. */
+#define DCMD_INCTRGADDR	BIT(30)	/* Target Address Increment Setting. */
+#define DCMD_FLOWSRC	BIT(29)	/* Flow Control by the source. */
+#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_ENDIAN	BIT(18)	/* Device Endian-ness. */
 #define DCMD_BURST8	(1 << 16)	/* 8 byte burst */
 #define DCMD_BURST16	(2 << 16)	/* 16 byte burst */
 #define DCMD_BURST32	(3 << 16)	/* 32 byte burst */
@@ -132,10 +132,14 @@ struct mmp_pdma_device {
 	spinlock_t phy_lock; /* protect alloc/free phy channels */
 };
 
-#define tx_to_mmp_pdma_desc(tx) container_of(tx, struct mmp_pdma_desc_sw, async_tx)
-#define to_mmp_pdma_desc(lh) container_of(lh, struct mmp_pdma_desc_sw, node)
-#define to_mmp_pdma_chan(dchan) container_of(dchan, struct mmp_pdma_chan, chan)
-#define to_mmp_pdma_dev(dmadev) container_of(dmadev, struct mmp_pdma_device, device)
+#define tx_to_mmp_pdma_desc(tx)					\
+	container_of(tx, struct mmp_pdma_desc_sw, async_tx)
+#define to_mmp_pdma_desc(lh)					\
+	container_of(lh, struct mmp_pdma_desc_sw, node)
+#define to_mmp_pdma_chan(dchan)					\
+	container_of(dchan, struct mmp_pdma_chan, chan)
+#define to_mmp_pdma_dev(dmadev)					\
+	container_of(dmadev, struct mmp_pdma_device, device)
 
 static void set_desc(struct mmp_pdma_phy *phy, dma_addr_t addr)
 {
@@ -162,19 +166,18 @@ static void enable_chan(struct mmp_pdma_phy *phy)
 	writel(dalgn, phy->base + DALGN);
 
 	reg = (phy->idx << 2) + DCSR;
-	writel(readl(phy->base + reg) | DCSR_RUN,
-					phy->base + reg);
+	writel(readl(phy->base + reg) | DCSR_RUN, phy->base + reg);
 }
 
 static void disable_chan(struct mmp_pdma_phy *phy)
 {
 	u32 reg;
 
-	if (phy) {
-		reg = (phy->idx << 2) + DCSR;
-		writel(readl(phy->base + reg) & ~DCSR_RUN,
-						phy->base + reg);
-	}
+	if (!phy)
+		return;
+
+	reg = (phy->idx << 2) + DCSR;
+	writel(readl(phy->base + reg) & ~DCSR_RUN, phy->base + reg);
 }
 
 static int clear_chan_irq(struct mmp_pdma_phy *phy)
@@ -183,26 +186,27 @@ static int clear_chan_irq(struct mmp_pdma_phy *phy)
 	u32 dint = readl(phy->base + DINT);
 	u32 reg = (phy->idx << 2) + DCSR;
 
-	if (dint & BIT(phy->idx)) {
-		/* clear irq */
-		dcsr = readl(phy->base + reg);
-		writel(dcsr, phy->base + reg);
-		if ((dcsr & DCSR_BUSERR) && (phy->vchan))
-			dev_warn(phy->vchan->dev, "DCSR_BUSERR\n");
-		return 0;
-	}
-	return -EAGAIN;
+	if (!(dint & BIT(phy->idx)))
+		return -EAGAIN;
+
+	/* clear irq */
+	dcsr = readl(phy->base + reg);
+	writel(dcsr, phy->base + reg);
+	if ((dcsr & DCSR_BUSERR) && (phy->vchan))
+		dev_warn(phy->vchan->dev, "DCSR_BUSERR\n");
+
+	return 0;
 }
 
 static irqreturn_t mmp_pdma_chan_handler(int irq, void *dev_id)
 {
 	struct mmp_pdma_phy *phy = dev_id;
 
-	if (clear_chan_irq(phy) == 0) {
-		tasklet_schedule(&phy->vchan->tasklet);
-		return IRQ_HANDLED;
-	} else
+	if (clear_chan_irq(phy) != 0)
 		return IRQ_NONE;
+
+	tasklet_schedule(&phy->vchan->tasklet);
+	return IRQ_HANDLED;
 }
 
 static irqreturn_t mmp_pdma_int_handler(int irq, void *dev_id)
@@ -224,8 +228,8 @@ static irqreturn_t mmp_pdma_int_handler(int irq, void *dev_id)
 
 	if (irq_num)
 		return IRQ_HANDLED;
-	else
-		return IRQ_NONE;
+
+	return IRQ_NONE;
 }
 
 /* lookup free phy channel as descending priority */
@@ -245,9 +249,9 @@ static struct mmp_pdma_phy *lookup_phy(struct mmp_pdma_chan *pchan)
 	 */
 
 	spin_lock_irqsave(&pdev->phy_lock, flags);
-	for (prio = 0; prio <= (((pdev->dma_channels - 1) & 0xf) >> 2); prio++) {
+	for (prio = 0; prio <= ((pdev->dma_channels - 1) & 0xf) >> 2; prio++) {
 		for (i = 0; i < pdev->dma_channels; i++) {
-			if (prio != ((i & 0xf) >> 2))
+			if (prio != (i & 0xf) >> 2)
 				continue;
 			phy = &pdev->phy[i];
 			if (!phy->vchan) {
@@ -389,14 +393,16 @@ static int mmp_pdma_alloc_chan_resources(struct dma_chan *dchan)
 	if (chan->desc_pool)
 		return 1;
 
-	chan->desc_pool =
-		dma_pool_create(dev_name(&dchan->dev->device), chan->dev,
-				  sizeof(struct mmp_pdma_desc_sw),
-				  __alignof__(struct mmp_pdma_desc_sw), 0);
+	chan->desc_pool = dma_pool_create(dev_name(&dchan->dev->device),
+					  chan->dev,
+					  sizeof(struct mmp_pdma_desc_sw),
+					  __alignof__(struct mmp_pdma_desc_sw),
+					  0);
 	if (!chan->desc_pool) {
 		dev_err(chan->dev, "unable to allocate descriptor pool\n");
 		return -ENOMEM;
 	}
+
 	mmp_pdma_free_phy(chan);
 	chan->idle = true;
 	chan->dev_addr = 0;
@@ -404,7 +410,7 @@ static int mmp_pdma_alloc_chan_resources(struct dma_chan *dchan)
 }
 
 static void mmp_pdma_free_desc_list(struct mmp_pdma_chan *chan,
-				  struct list_head *list)
+				    struct list_head *list)
 {
 	struct mmp_pdma_desc_sw *desc, *_desc;
 
@@ -434,8 +440,8 @@ static void mmp_pdma_free_chan_resources(struct dma_chan *dchan)
 
 static struct dma_async_tx_descriptor *
 mmp_pdma_prep_memcpy(struct dma_chan *dchan,
-	dma_addr_t dma_dst, dma_addr_t dma_src,
-	size_t len, unsigned long flags)
+		     dma_addr_t dma_dst, dma_addr_t dma_src,
+		     size_t len, unsigned long flags)
 {
 	struct mmp_pdma_chan *chan;
 	struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new;
@@ -515,8 +521,8 @@ fail:
 
 static struct dma_async_tx_descriptor *
 mmp_pdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
-			 unsigned int sg_len, enum dma_transfer_direction dir,
-			 unsigned long flags, void *context)
+		       unsigned int sg_len, enum dma_transfer_direction dir,
+		       unsigned long flags, void *context)
 {
 	struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
 	struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new = NULL;
@@ -591,10 +597,11 @@ fail:
 	return NULL;
 }
 
-static struct dma_async_tx_descriptor *mmp_pdma_prep_dma_cyclic(
-	struct dma_chan *dchan, dma_addr_t buf_addr, size_t len,
-	size_t period_len, enum dma_transfer_direction direction,
-	unsigned long flags, void *context)
+static struct dma_async_tx_descriptor *
+mmp_pdma_prep_dma_cyclic(struct dma_chan *dchan,
+			 dma_addr_t buf_addr, size_t len, size_t period_len,
+			 enum dma_transfer_direction direction,
+			 unsigned long flags, void *context)
 {
 	struct mmp_pdma_chan *chan;
 	struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new;
@@ -636,8 +643,8 @@ static struct dma_async_tx_descriptor *mmp_pdma_prep_dma_cyclic(
 			goto fail;
 		}
 
-		new->desc.dcmd = chan->dcmd | DCMD_ENDIRQEN |
-					(DCMD_LENGTH & period_len);
+		new->desc.dcmd = (chan->dcmd | DCMD_ENDIRQEN |
+				  (DCMD_LENGTH & period_len));
 		new->desc.dsadr = dma_src;
 		new->desc.dtadr = dma_dst;
 
@@ -677,12 +684,11 @@ fail:
 }
 
 static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
-		unsigned long arg)
+			    unsigned long arg)
 {
 	struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
 	struct dma_slave_config *cfg = (void *)arg;
 	unsigned long flags;
-	int ret = 0;
 	u32 maxburst = 0, addr = 0;
 	enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
 
@@ -739,11 +745,12 @@ static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
 		return -ENOSYS;
 	}
 
-	return ret;
+	return 0;
 }
 
 static enum dma_status mmp_pdma_tx_status(struct dma_chan *dchan,
-			dma_cookie_t cookie, struct dma_tx_state *txstate)
+					  dma_cookie_t cookie,
+					  struct dma_tx_state *txstate)
 {
 	return dma_cookie_status(dchan, cookie, txstate);
 }
@@ -845,15 +852,14 @@ static int mmp_pdma_remove(struct platform_device *op)
 	return 0;
 }
 
-static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev,
-							int idx, int irq)
+static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev, int idx, int irq)
 {
 	struct mmp_pdma_phy *phy  = &pdev->phy[idx];
 	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(struct mmp_pdma_chan),
+			    GFP_KERNEL);
 	if (chan == NULL)
 		return -ENOMEM;
 
@@ -861,8 +867,8 @@ static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev,
 	phy->base = pdev->base;
 
 	if (irq) {
-		ret = devm_request_irq(pdev->dev, irq,
-			mmp_pdma_chan_handler, 0, "pdma", phy);
+		ret = devm_request_irq(pdev->dev, irq, mmp_pdma_chan_handler, 0,
+				       "pdma", phy);
 		if (ret) {
 			dev_err(pdev->dev, "channel request irq fail!\n");
 			return ret;
@@ -877,8 +883,7 @@ static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev,
 	INIT_LIST_HEAD(&chan->chain_running);
 
 	/* register virt channel to dma engine */
-	list_add_tail(&chan->chan.device_node,
-			&pdev->device.channels);
+	list_add_tail(&chan->chan.device_node, &pdev->device.channels);
 
 	return 0;
 }
@@ -913,13 +918,12 @@ retry:
 	 * the lookup and the reservation */
 	chan = dma_get_slave_channel(candidate);
 
-	if (chan) {
-		struct mmp_pdma_chan *c = to_mmp_pdma_chan(chan);
-		c->drcmr = dma_spec->args[0];
-		return chan;
-	}
+	if (!chan)
+		goto retry;
 
-	goto retry;
+	to_mmp_pdma_chan(chan)->drcmr = dma_spec->args[0];
+
+	return chan;
 }
 
 static int mmp_pdma_probe(struct platform_device *op)
@@ -934,6 +938,7 @@ static int mmp_pdma_probe(struct platform_device *op)
 	pdev = devm_kzalloc(&op->dev, sizeof(*pdev), GFP_KERNEL);
 	if (!pdev)
 		return -ENOMEM;
+
 	pdev->dev = &op->dev;
 
 	spin_lock_init(&pdev->phy_lock);
@@ -945,8 +950,8 @@ static int mmp_pdma_probe(struct platform_device *op)
 
 	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);
+		of_property_read_u32(pdev->dev->of_node, "#dma-channels",
+				     &dma_channels);
 	else if (pdata && pdata->dma_channels)
 		dma_channels = pdata->dma_channels;
 	else
@@ -958,8 +963,9 @@ static int mmp_pdma_probe(struct platform_device *op)
 			irq_num++;
 	}
 
-	pdev->phy = devm_kzalloc(pdev->dev,
-		dma_channels * sizeof(struct mmp_pdma_chan), GFP_KERNEL);
+	pdev->phy = devm_kcalloc(pdev->dev,
+				 dma_channels, sizeof(struct mmp_pdma_chan),
+				 GFP_KERNEL);
 	if (pdev->phy == NULL)
 		return -ENOMEM;
 
@@ -968,8 +974,8 @@ static int mmp_pdma_probe(struct platform_device *op)
 	if (irq_num != dma_channels) {
 		/* all chan share one irq, demux inside */
 		irq = platform_get_irq(op, 0);
-		ret = devm_request_irq(pdev->dev, irq,
-			mmp_pdma_int_handler, 0, "pdma", pdev);
+		ret = devm_request_irq(pdev->dev, irq, mmp_pdma_int_handler, 0,
+				       "pdma", pdev);
 		if (ret)
 			return ret;
 	}
@@ -1044,7 +1050,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;
+	c->drcmr = *(unsigned int *)param;
 
 	return true;
 }
@@ -1052,6 +1058,6 @@ EXPORT_SYMBOL_GPL(mmp_pdma_filter_fn);
 
 module_platform_driver(mmp_pdma_driver);
 
-MODULE_DESCRIPTION("MARVELL MMP Periphera DMA Driver");
+MODULE_DESCRIPTION("MARVELL MMP Peripheral DMA Driver");
 MODULE_AUTHOR("Marvell International Ltd.");
 MODULE_LICENSE("GPL v2");
#4 lore raw

Re: [PATCH] mmp_pdma: Style neatening

Quoted 9 lines · Joe Perches

Neaten code used as a template for other drivers. Make the code more consistent with kernel styles.

o Convert #defines with (1<<foo) to BIT(foo)
o Alignment wrapping
o Logic inversions to put return at end of functions
o Convert devm_kzalloc with multiply to devm_kcalloc
o typo of Peripheral fix

Quoted 8 lines

---

Quoted 1 line

At least, the code is directly taken from mmp_pdma.c ;-)

Well, maybe the template code should be updated if there are going to be more of these.

Uncompiled/untested.

Compile tested and applied.

BUT you should not have hijacked the thread and sent this patch on a different chain!

--
~Vinod

Quoted 422 lines
 drivers/dma/mmp_pdma.c | 204 +++++++++++++++++++++++++------------------------
 1 file changed, 105 insertions(+), 99 deletions(-)
drivers/dma/mmp_pdma.c +105 -99
index dcb1e05..c2658f6 100644
@@ -5,6 +5,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -32,38 +33,37 @@
 #define DTADR		0x0208
 #define DCMD		0x020c
 
-#define DCSR_RUN	(1 << 31)	/* Run Bit (read / write) */
-#define DCSR_NODESC	(1 << 30)	/* No-Descriptor Fetch (read / write) */
-#define DCSR_STOPIRQEN	(1 << 29)	/* Stop Interrupt Enable (read / write) */
-#define DCSR_REQPEND	(1 << 8)	/* Request Pending (read-only) */
-#define DCSR_STOPSTATE	(1 << 3)	/* Stop State (read-only) */
-#define DCSR_ENDINTR	(1 << 2)	/* End Interrupt (read / write) */
-#define DCSR_STARTINTR	(1 << 1)	/* Start Interrupt (read / write) */
-#define DCSR_BUSERR	(1 << 0)	/* Bus Error Interrupt (read / write) */
-
-#define DCSR_EORIRQEN	(1 << 28)       /* End of Receive Interrupt Enable (R/W) */
-#define DCSR_EORJMPEN	(1 << 27)       /* Jump to next descriptor on EOR */
-#define DCSR_EORSTOPEN	(1 << 26)       /* STOP on an EOR */
-#define DCSR_SETCMPST	(1 << 25)       /* Set Descriptor Compare Status */
-#define DCSR_CLRCMPST	(1 << 24)       /* Clear Descriptor Compare Status */
-#define DCSR_CMPST	(1 << 10)       /* The Descriptor Compare Status */
-#define DCSR_EORINTR	(1 << 9)        /* The end of Receive */
-
-#define DRCMR(n)	((((n) < 64) ? 0x0100 : 0x1100) + \
-				 (((n) & 0x3f) << 2))
-#define DRCMR_MAPVLD	(1 << 7)	/* Map Valid (read / write) */
-#define DRCMR_CHLNUM	0x1f		/* mask for Channel Number (read / write) */
+#define DCSR_RUN	BIT(31)	/* Run Bit (read / write) */
+#define DCSR_NODESC	BIT(30)	/* No-Descriptor Fetch (read / write) */
+#define DCSR_STOPIRQEN	BIT(29)	/* Stop Interrupt Enable (read / write) */
+#define DCSR_REQPEND	BIT(8)	/* Request Pending (read-only) */
+#define DCSR_STOPSTATE	BIT(3)	/* Stop State (read-only) */
+#define DCSR_ENDINTR	BIT(2)	/* End Interrupt (read / write) */
+#define DCSR_STARTINTR	BIT(1)	/* Start Interrupt (read / write) */
+#define DCSR_BUSERR	BIT(0)	/* Bus Error Interrupt (read / write) */
+
+#define DCSR_EORIRQEN	BIT(28)	/* End of Receive Interrupt Enable (R/W) */
+#define DCSR_EORJMPEN	BIT(27)	/* Jump to next descriptor on EOR */
+#define DCSR_EORSTOPEN	BIT(26)	/* STOP on an EOR */
+#define DCSR_SETCMPST	BIT(25)	/* Set Descriptor Compare Status */
+#define DCSR_CLRCMPST	BIT(24)	/* Clear Descriptor Compare Status */
+#define DCSR_CMPST	BIT(10)	/* The Descriptor Compare Status */
+#define DCSR_EORINTR	BIT(9)	/* The end of Receive */
+
+#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) */
 
 #define DDADR_DESCADDR	0xfffffff0	/* Address of next descriptor (mask) */
-#define DDADR_STOP	(1 << 0)	/* Stop (read / write) */
-
-#define DCMD_INCSRCADDR	(1 << 31)	/* Source Address Increment Setting. */
-#define DCMD_INCTRGADDR	(1 << 30)	/* Target Address Increment Setting. */
-#define DCMD_FLOWSRC	(1 << 29)	/* Flow Control by the source. */
-#define DCMD_FLOWTRG	(1 << 28)	/* Flow Control by the target. */
-#define DCMD_STARTIRQEN	(1 << 22)	/* Start Interrupt Enable */
-#define DCMD_ENDIRQEN	(1 << 21)	/* End Interrupt Enable */
-#define DCMD_ENDIAN	(1 << 18)	/* Device Endian-ness. */
+#define DDADR_STOP	BIT(0)	/* Stop (read / write) */
+
+#define DCMD_INCSRCADDR	BIT(31)	/* Source Address Increment Setting. */
+#define DCMD_INCTRGADDR	BIT(30)	/* Target Address Increment Setting. */
+#define DCMD_FLOWSRC	BIT(29)	/* Flow Control by the source. */
+#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_ENDIAN	BIT(18)	/* Device Endian-ness. */
 #define DCMD_BURST8	(1 << 16)	/* 8 byte burst */
 #define DCMD_BURST16	(2 << 16)	/* 16 byte burst */
 #define DCMD_BURST32	(3 << 16)	/* 32 byte burst */
@@ -132,10 +132,14 @@ struct mmp_pdma_device {
 	spinlock_t phy_lock; /* protect alloc/free phy channels */
 };
 
-#define tx_to_mmp_pdma_desc(tx) container_of(tx, struct mmp_pdma_desc_sw, async_tx)
-#define to_mmp_pdma_desc(lh) container_of(lh, struct mmp_pdma_desc_sw, node)
-#define to_mmp_pdma_chan(dchan) container_of(dchan, struct mmp_pdma_chan, chan)
-#define to_mmp_pdma_dev(dmadev) container_of(dmadev, struct mmp_pdma_device, device)
+#define tx_to_mmp_pdma_desc(tx)					\
+	container_of(tx, struct mmp_pdma_desc_sw, async_tx)
+#define to_mmp_pdma_desc(lh)					\
+	container_of(lh, struct mmp_pdma_desc_sw, node)
+#define to_mmp_pdma_chan(dchan)					\
+	container_of(dchan, struct mmp_pdma_chan, chan)
+#define to_mmp_pdma_dev(dmadev)					\
+	container_of(dmadev, struct mmp_pdma_device, device)
 
 static void set_desc(struct mmp_pdma_phy *phy, dma_addr_t addr)
 {
@@ -162,19 +166,18 @@ static void enable_chan(struct mmp_pdma_phy *phy)
 	writel(dalgn, phy->base + DALGN);
 
 	reg = (phy->idx << 2) + DCSR;
-	writel(readl(phy->base + reg) | DCSR_RUN,
-					phy->base + reg);
+	writel(readl(phy->base + reg) | DCSR_RUN, phy->base + reg);
 }
 
 static void disable_chan(struct mmp_pdma_phy *phy)
 {
 	u32 reg;
 
-	if (phy) {
-		reg = (phy->idx << 2) + DCSR;
-		writel(readl(phy->base + reg) & ~DCSR_RUN,
-						phy->base + reg);
-	}
+	if (!phy)
+		return;
+
+	reg = (phy->idx << 2) + DCSR;
+	writel(readl(phy->base + reg) & ~DCSR_RUN, phy->base + reg);
 }
 
 static int clear_chan_irq(struct mmp_pdma_phy *phy)
@@ -183,26 +186,27 @@ static int clear_chan_irq(struct mmp_pdma_phy *phy)
 	u32 dint = readl(phy->base + DINT);
 	u32 reg = (phy->idx << 2) + DCSR;
 
-	if (dint & BIT(phy->idx)) {
-		/* clear irq */
-		dcsr = readl(phy->base + reg);
-		writel(dcsr, phy->base + reg);
-		if ((dcsr & DCSR_BUSERR) && (phy->vchan))
-			dev_warn(phy->vchan->dev, "DCSR_BUSERR\n");
-		return 0;
-	}
-	return -EAGAIN;
+	if (!(dint & BIT(phy->idx)))
+		return -EAGAIN;
+
+	/* clear irq */
+	dcsr = readl(phy->base + reg);
+	writel(dcsr, phy->base + reg);
+	if ((dcsr & DCSR_BUSERR) && (phy->vchan))
+		dev_warn(phy->vchan->dev, "DCSR_BUSERR\n");
+
+	return 0;
 }
 
 static irqreturn_t mmp_pdma_chan_handler(int irq, void *dev_id)
 {
 	struct mmp_pdma_phy *phy = dev_id;
 
-	if (clear_chan_irq(phy) == 0) {
-		tasklet_schedule(&phy->vchan->tasklet);
-		return IRQ_HANDLED;
-	} else
+	if (clear_chan_irq(phy) != 0)
 		return IRQ_NONE;
+
+	tasklet_schedule(&phy->vchan->tasklet);
+	return IRQ_HANDLED;
 }
 
 static irqreturn_t mmp_pdma_int_handler(int irq, void *dev_id)
@@ -224,8 +228,8 @@ static irqreturn_t mmp_pdma_int_handler(int irq, void *dev_id)
 
 	if (irq_num)
 		return IRQ_HANDLED;
-	else
-		return IRQ_NONE;
+
+	return IRQ_NONE;
 }
 
 /* lookup free phy channel as descending priority */
@@ -245,9 +249,9 @@ static struct mmp_pdma_phy *lookup_phy(struct mmp_pdma_chan *pchan)
 	 */
 
 	spin_lock_irqsave(&pdev->phy_lock, flags);
-	for (prio = 0; prio <= (((pdev->dma_channels - 1) & 0xf) >> 2); prio++) {
+	for (prio = 0; prio <= ((pdev->dma_channels - 1) & 0xf) >> 2; prio++) {
 		for (i = 0; i < pdev->dma_channels; i++) {
-			if (prio != ((i & 0xf) >> 2))
+			if (prio != (i & 0xf) >> 2)
 				continue;
 			phy = &pdev->phy[i];
 			if (!phy->vchan) {
@@ -389,14 +393,16 @@ static int mmp_pdma_alloc_chan_resources(struct dma_chan *dchan)
 	if (chan->desc_pool)
 		return 1;
 
-	chan->desc_pool =
-		dma_pool_create(dev_name(&dchan->dev->device), chan->dev,
-				  sizeof(struct mmp_pdma_desc_sw),
-				  __alignof__(struct mmp_pdma_desc_sw), 0);
+	chan->desc_pool = dma_pool_create(dev_name(&dchan->dev->device),
+					  chan->dev,
+					  sizeof(struct mmp_pdma_desc_sw),
+					  __alignof__(struct mmp_pdma_desc_sw),
+					  0);
 	if (!chan->desc_pool) {
 		dev_err(chan->dev, "unable to allocate descriptor pool\n");
 		return -ENOMEM;
 	}
+
 	mmp_pdma_free_phy(chan);
 	chan->idle = true;
 	chan->dev_addr = 0;
@@ -404,7 +410,7 @@ static int mmp_pdma_alloc_chan_resources(struct dma_chan *dchan)
 }
 
 static void mmp_pdma_free_desc_list(struct mmp_pdma_chan *chan,
-				  struct list_head *list)
+				    struct list_head *list)
 {
 	struct mmp_pdma_desc_sw *desc, *_desc;
 
@@ -434,8 +440,8 @@ static void mmp_pdma_free_chan_resources(struct dma_chan *dchan)
 
 static struct dma_async_tx_descriptor *
 mmp_pdma_prep_memcpy(struct dma_chan *dchan,
-	dma_addr_t dma_dst, dma_addr_t dma_src,
-	size_t len, unsigned long flags)
+		     dma_addr_t dma_dst, dma_addr_t dma_src,
+		     size_t len, unsigned long flags)
 {
 	struct mmp_pdma_chan *chan;
 	struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new;
@@ -515,8 +521,8 @@ fail:
 
 static struct dma_async_tx_descriptor *
 mmp_pdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
-			 unsigned int sg_len, enum dma_transfer_direction dir,
-			 unsigned long flags, void *context)
+		       unsigned int sg_len, enum dma_transfer_direction dir,
+		       unsigned long flags, void *context)
 {
 	struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
 	struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new = NULL;
@@ -591,10 +597,11 @@ fail:
 	return NULL;
 }
 
-static struct dma_async_tx_descriptor *mmp_pdma_prep_dma_cyclic(
-	struct dma_chan *dchan, dma_addr_t buf_addr, size_t len,
-	size_t period_len, enum dma_transfer_direction direction,
-	unsigned long flags, void *context)
+static struct dma_async_tx_descriptor *
+mmp_pdma_prep_dma_cyclic(struct dma_chan *dchan,
+			 dma_addr_t buf_addr, size_t len, size_t period_len,
+			 enum dma_transfer_direction direction,
+			 unsigned long flags, void *context)
 {
 	struct mmp_pdma_chan *chan;
 	struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new;
@@ -636,8 +643,8 @@ static struct dma_async_tx_descriptor *mmp_pdma_prep_dma_cyclic(
 			goto fail;
 		}
 
-		new->desc.dcmd = chan->dcmd | DCMD_ENDIRQEN |
-					(DCMD_LENGTH & period_len);
+		new->desc.dcmd = (chan->dcmd | DCMD_ENDIRQEN |
+				  (DCMD_LENGTH & period_len));
 		new->desc.dsadr = dma_src;
 		new->desc.dtadr = dma_dst;
 
@@ -677,12 +684,11 @@ fail:
 }
 
 static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
-		unsigned long arg)
+			    unsigned long arg)
 {
 	struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
 	struct dma_slave_config *cfg = (void *)arg;
 	unsigned long flags;
-	int ret = 0;
 	u32 maxburst = 0, addr = 0;
 	enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
 
@@ -739,11 +745,12 @@ static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
 		return -ENOSYS;
 	}
 
-	return ret;
+	return 0;
 }
 
 static enum dma_status mmp_pdma_tx_status(struct dma_chan *dchan,
-			dma_cookie_t cookie, struct dma_tx_state *txstate)
+					  dma_cookie_t cookie,
+					  struct dma_tx_state *txstate)
 {
 	return dma_cookie_status(dchan, cookie, txstate);
 }
@@ -845,15 +852,14 @@ static int mmp_pdma_remove(struct platform_device *op)
 	return 0;
 }
 
-static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev,
-							int idx, int irq)
+static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev, int idx, int irq)
 {
 	struct mmp_pdma_phy *phy  = &pdev->phy[idx];
 	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(struct mmp_pdma_chan),
+			    GFP_KERNEL);
 	if (chan == NULL)
 		return -ENOMEM;
 
@@ -861,8 +867,8 @@ static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev,
 	phy->base = pdev->base;
 
 	if (irq) {
-		ret = devm_request_irq(pdev->dev, irq,
-			mmp_pdma_chan_handler, 0, "pdma", phy);
+		ret = devm_request_irq(pdev->dev, irq, mmp_pdma_chan_handler, 0,
+				       "pdma", phy);
 		if (ret) {
 			dev_err(pdev->dev, "channel request irq fail!\n");
 			return ret;
@@ -877,8 +883,7 @@ static int mmp_pdma_chan_init(struct mmp_pdma_device *pdev,
 	INIT_LIST_HEAD(&chan->chain_running);
 
 	/* register virt channel to dma engine */
-	list_add_tail(&chan->chan.device_node,
-			&pdev->device.channels);
+	list_add_tail(&chan->chan.device_node, &pdev->device.channels);
 
 	return 0;
 }
@@ -913,13 +918,12 @@ retry:
 	 * the lookup and the reservation */
 	chan = dma_get_slave_channel(candidate);
 
-	if (chan) {
-		struct mmp_pdma_chan *c = to_mmp_pdma_chan(chan);
-		c->drcmr = dma_spec->args[0];
-		return chan;
-	}
+	if (!chan)
+		goto retry;
 
-	goto retry;
+	to_mmp_pdma_chan(chan)->drcmr = dma_spec->args[0];
+
+	return chan;
 }
 
 static int mmp_pdma_probe(struct platform_device *op)
@@ -934,6 +938,7 @@ static int mmp_pdma_probe(struct platform_device *op)
 	pdev = devm_kzalloc(&op->dev, sizeof(*pdev), GFP_KERNEL);
 	if (!pdev)
 		return -ENOMEM;
+
 	pdev->dev = &op->dev;
 
 	spin_lock_init(&pdev->phy_lock);
@@ -945,8 +950,8 @@ static int mmp_pdma_probe(struct platform_device *op)
 
 	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);
+		of_property_read_u32(pdev->dev->of_node, "#dma-channels",
+				     &dma_channels);
 	else if (pdata && pdata->dma_channels)
 		dma_channels = pdata->dma_channels;
 	else
@@ -958,8 +963,9 @@ static int mmp_pdma_probe(struct platform_device *op)
 			irq_num++;
 	}
 
-	pdev->phy = devm_kzalloc(pdev->dev,
-		dma_channels * sizeof(struct mmp_pdma_chan), GFP_KERNEL);
+	pdev->phy = devm_kcalloc(pdev->dev,
+				 dma_channels, sizeof(struct mmp_pdma_chan),
+				 GFP_KERNEL);
 	if (pdev->phy == NULL)
 		return -ENOMEM;
 
@@ -968,8 +974,8 @@ static int mmp_pdma_probe(struct platform_device *op)
 	if (irq_num != dma_channels) {
 		/* all chan share one irq, demux inside */
 		irq = platform_get_irq(op, 0);
-		ret = devm_request_irq(pdev->dev, irq,
-			mmp_pdma_int_handler, 0, "pdma", pdev);
+		ret = devm_request_irq(pdev->dev, irq, mmp_pdma_int_handler, 0,
+				       "pdma", pdev);
 		if (ret)
 			return ret;
 	}
@@ -1044,7 +1050,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;
+	c->drcmr = *(unsigned int *)param;
 
 	return true;
 }
@@ -1052,6 +1058,6 @@ EXPORT_SYMBOL_GPL(mmp_pdma_filter_fn);
 
 module_platform_driver(mmp_pdma_driver);
 
-MODULE_DESCRIPTION("MARVELL MMP Periphera DMA Driver");
+MODULE_DESCRIPTION("MARVELL MMP Peripheral DMA Driver");
 MODULE_AUTHOR("Marvell International Ltd.");
 MODULE_LICENSE("GPL v2");
#5 lore raw
In reply to Florian Meier

T24gU3VuLCAyMDEzLTExLTE3IGF0IDE2OjM5ICswMTAwLCBGbG9yaWFuIE1laWVyIHdyb3RlOg0K PiBBZGQgc3VwcG9ydCBmb3IgRE1BIGNvbnRyb2xsZXIgb2YgQkNNMjgzNSBhcyB1c2VkIGluIHRo ZSBSYXNwYmVycnkgUGkuDQo+IEN1cnJlbnRseSBpdCBvbmx5IHN1cHBvcnRzIGN5Y2xpYyBETUEu DQoNCkZldyBjb21tZW50cyBiZWxvdy4NCg0KPiArKysgYi9kcml2ZXJzL2RtYS9iY20yODM1LWRt YS5jDQo+IEBAIC0wLDAgKzEsNzM2IEBADQoNCj4gK3N0YXRpYyBpbnQgYmNtMjgzNV9kbWFfYWJv cnQodm9pZCBfX2lvbWVtICpjaGFuX2Jhc2UpDQo+ICt7DQo+ICsJdW5zaWduZWQgbG9uZyBpbnQg Y3M7DQo+ICsJbG9uZyBpbnQgdGltZW91dCA9IDEwMDAwOw0KPiArDQo+ICsJY3MgPSByZWFkbChj aGFuX2Jhc2UgKyBCQ00yODM1X0RNQV9DUyk7DQo+ICsJaWYgKCEoY3MgJiBCQ00yODM1X0RNQV9B Q1RJVkUpKQ0KPiArCQlyZXR1cm4gMDsNCj4gKw0KPiArCS8qIFdyaXRlIDAgdG8gdGhlIGFjdGl2 ZSBiaXQgLSBQYXVzZSB0aGUgRE1BICovDQo+ICsJd3JpdGVsKDAsIGNoYW5fYmFzZSArIEJDTTI4 MzVfRE1BX0NTKTsNCj4gKw0KPiArCS8qIFdhaXQgZm9yIGFueSBjdXJyZW50IEFYSSB0cmFuc2Zl ciB0byBjb21wbGV0ZSAqLw0KPiArCXdoaWxlICgoY3MgJiBCQ00yODM1X0RNQV9JU1BBVVNFRCkg JiYgLS10aW1lb3V0ID49IDApDQo+ICsJCWNzID0gcmVhZGwoY2hhbl9iYXNlICsgQkNNMjgzNV9E TUFfQ1MpOw0KDQpJIGFjdHVhbGx5IGRvbid0IHNlZSB0aW1lb3V0IGhlcmUuIHRpbWVvdXQgbWVh bnMgY291bnRlciBpbiB5b3VyIGNhc2UuDQpNaWdodCBiZSBiZXR0ZXIgdG8gaGF2ZSBzb21ldGhp bmcgbGlrZQ0KDQp3aGlsZSAocmVhZGwoLi4uKSAmIEJDTTI4MzVfRE1BX0lTUEFVU0VEICYmIC0t dGltZW91dCkNCmNwdV9yZWxheCgpOw0KDQo/DQoNCj4gKwkvKiBXZSdsbCB1bi1wYXVzZSB3aGVu IHdlIHNldCBvZiBvdXIgbmV4dCBETUEgKi8NCj4gKwlpZiAoY3MgJiBCQ00yODM1X0RNQV9JU1BB VVNFRCkNCg0KaWYgKCF0aW1lb3V0KQ0KDQo+ICsJCXJldHVybiAtRVRJTUVET1VUOw0KDQoNCj4g Kw0KPiArCWlmICghKGNzICYgQkNNMjgzNV9ETUFfQUNUSVZFKSkNCj4gKwkJcmV0dXJuIDA7DQoN CkR1cGxpY2F0ZSBjb2RlLiBQZXJoYXBzDQpzdGF0aWMgaW5saW5lIGJvb2wgaXNfY2hhbl9ub3Rf YWN0aXZlKHVuc2lnbmVkIGxvbmcgY3MpDQp7DQpyZXR1cm4gIShjcyAmIEJDTTI4MzVfRE1BX0FD VElWRSk7DQp9DQoNCltdDQoNCj4gK3N0YXRpYyBpcnFyZXR1cm5fdCBiY20yODM1X2RtYV9jYWxs YmFjayhpbnQgaXJxLCB2b2lkICpkYXRhKQ0KPiArew0KDQpbXQ0KDQo+ICsJd3JpdGVsKEJDTTI4 MzVfRE1BX0FDVElWRSwgYy0+Y2hhbl9iYXNlICsgQkNNMjgzNV9ETUFfQ1MpOw0KDQpTaW5jZSBp dCdzIGR1cGxpY2F0ZSBjb2RlLCBwZXJoYXBzDQoNCnN0YXRpYyBpbmxpbmUgdm9pZCBzZXRfY2hh bl9hY3RpdmUodm9pZCBfX2lvbWVtICpiYXNlKQ0Kew0Kd3JpdGVsKEJDTTI4MzVfRE1BX0FDVElW RSwgYmFzZSArIEJDTTI4MzVfRE1BX0NTKTsNCn0NCg0KW10NCg0KPiArc3RhdGljIHNpemVfdCBi Y20yODM1X2RtYV9kZXNjX3NpemVfcG9zKHN0cnVjdCBiY20yODM1X2Rlc2MgKmQsIGRtYV9hZGRy X3QgYWRkcikNCj4gK3sNCj4gKwl1bnNpZ25lZCBpOw0KDQpJbiBzb21lIGNhc2VzIHlvdSB1c2Ug J3Vuc2lnbmVkIGxvbmcgaW50JyBmb3IgJ3Vuc2lnbmVkIGxvbmcnLCBmb3INCmV4YW1wbGUsIGJ1 dCBoZXJlICd1bnNpZ25lZCcgaW5zdGVhZCBvZiAndW5zaWduZWQgaW50Jy4gUGxlYXNlLCBhbGln bg0Kc3R5bGUgd2l0aCBjZXJ0YWluIGNob2ljZS4NCg0KW10NCg0KPiArc3RhdGljIGVudW0gZG1h X3N0YXR1cyBiY20yODM1X2RtYV90eF9zdGF0dXMoc3RydWN0IGRtYV9jaGFuICpjaGFuLA0KPiAr CWRtYV9jb29raWVfdCBjb29raWUsIHN0cnVjdCBkbWFfdHhfc3RhdGUgKnR4c3RhdGUpDQo+ICt7 DQoNCltdDQoNCj4gKwl9IGVsc2Ugew0KPiArCQl0eHN0YXRlLT5yZXNpZHVlID0gMDsNCg0KVXNl bGVzcyBhc3NpZ25tZW50IHNpbmNlIGRtYWVuZ2luZSB3aWxsIGRvIHRoaXMgZm9yIHlvdSBpbg0K ZG1hX2Nvb2tpZV9zdGF0dXMuDQoNCltdDQoNCj4gK3N0YXRpYyBzdHJ1Y3QgZG1hX2FzeW5jX3R4 X2Rlc2NyaXB0b3IgKmJjbTI4MzVfZG1hX3ByZXBfZG1hX2N5Y2xpYygNCj4gKwlzdHJ1Y3QgZG1h X2NoYW4gKmNoYW4sIGRtYV9hZGRyX3QgYnVmX2FkZHIsIHNpemVfdCBidWZfbGVuLA0KPiArCXNp emVfdCBwZXJpb2RfbGVuLCBlbnVtIGRtYV90cmFuc2Zlcl9kaXJlY3Rpb24gZGlyZWN0aW9uLA0K PiArCXVuc2lnbmVkIGxvbmcgZmxhZ3MsIHZvaWQgKmNvbnRleHQpDQo+ICt7DQoNCltdDQoNCj4g KwkvKiBHcmFiIGNvbmZpZ3VyYXRpb24gKi8NCj4gKwlpZiAoZGlyZWN0aW9uID09IERNQV9ERVZf VE9fTUVNKSB7DQo+ICsJCWRldl9hZGRyID0gYy0+Y2ZnLnNyY19hZGRyOw0KPiArCQlkZXZfd2lk dGggPSBjLT5jZmcuc3JjX2FkZHJfd2lkdGg7DQo+ICsJCXN5bmNfdHlwZSA9IEJDTTI4MzVfRE1B X1NfRFJFUTsNCj4gKwl9IGVsc2UgaWYgKGRpcmVjdGlvbiA9PSBETUFfTUVNX1RPX0RFVikgew0K PiArCQlkZXZfYWRkciA9IGMtPmNmZy5kc3RfYWRkcjsNCj4gKwkJZGV2X3dpZHRoID0gYy0+Y2Zn LmRzdF9hZGRyX3dpZHRoOw0KPiArCQlzeW5jX3R5cGUgPSBCQ00yODM1X0RNQV9EX0RSRVE7DQo+ ICsJfSBlbHNlIHsNCj4gKwkJZGV2X2VycihjaGFuLT5kZXZpY2UtPmRldiwgIiVzOiBiYWQgZGly ZWN0aW9uP1xuIiwgX19mdW5jX18pOw0KPiArCQlyZXR1cm4gTlVMTDsNCj4gKwl9DQoNCllvdSBt aWdodCB1c2UgZm9sbG93aW5nIGFzIHdlbGwNCg0KaWYgKCFpc19zbGF2ZV9kaXJlY3Rpb24pIHsN CiBkZXZfZXJyKC4uLik7DQogcmV0dXJuIE5VTEw7DQp9DQoNCmlmIChkaXJlY3Rpb24gPT0gRE1B X0RFVl9UT19NRU0pDQp7DQouLi4NCn0gZWxzZSB7DQouLi4NCn0NCg0KPw0KDQpBdCBsZWFzdCBp dCB3aWxsIGJlIGFsaWduZWQgd2l0aCB3aGF0IHlvdSBoYXZlIGZ1cnRoZXIgaW4gdGhpcyBmdW5j dGlvbi4NCg0KPiArCS8qIEJ1cyB3aWR0aCB0cmFuc2xhdGVzIHRvIHRoZSBlbGVtZW50IHNpemUg KEVTKSAqLw0KPiArCXN3aXRjaCAoZGV2X3dpZHRoKSB7DQo+ICsJY2FzZSBETUFfU0xBVkVfQlVT V0lEVEhfNF9CWVRFUzoNCj4gKwkJZXMgPSBCQ00yODM1X0RNQV9EQVRBX1RZUEVfUzMyOw0KPiAr CQlicmVhazsNCj4gKwlkZWZhdWx0Og0KPiArCQlyZXR1cm4gTlVMTDsNCj4gKwl9DQoNClNvLCB5 b3UgdXNlIHN3aXRjaC1jYXNlIG9uIGhvcGUgdG8gZXh0ZW5kIGl0IGxhdGVyLCBjb3JyZWN0Pw0K DQpbXQ0KDQo+ICtzdGF0aWMgaW50IGJjbTI4MzVfZG1hX3Rlcm1pbmF0ZV9hbGwoc3RydWN0IGJj bTI4MzVfY2hhbiAqYykNCj4gK3sNCj4gKwlzdHJ1Y3QgYmNtMjgzNV9kbWFkZXYgKmQgPSB0b19i Y20yODM1X2RtYV9kZXYoYy0+dmMuY2hhbi5kZXZpY2UpOw0KPiArCXVuc2lnbmVkIGxvbmcgZmxh Z3M7DQo+ICsJaW50IHRpbWVvdXQgPSAxMDAwOw0KPiArCUxJU1RfSEVBRChoZWFkKTsNCg0KW10N Cg0KPiArCWlmIChjLT5kZXNjKSB7DQo+ICsJCWMtPmRlc2MgPSBOVUxMOw0KPiArCQliY20yODM1 X2RtYV9hYm9ydChjLT5jaGFuX2Jhc2UpOw0KPiArDQo+ICsJCS8qIFdhaXQgZm9yIHN0b3BwaW5n ICovDQo+ICsJCXdoaWxlICh0aW1lb3V0ID4gMCkgew0KPiArCQkJdGltZW91dC0tOw0KDQp3aGls ZSAoLS10aW1lb3V0KQ0KDQo+ICsJCQlpZiAoIShyZWFkbChjLT5jaGFuX2Jhc2UgKyBCQ00yODM1 X0RNQV9DUykgJg0KPiArCQkJCQkJQkNNMjgzNV9ETUFfQUNUSVZFKSkNCj4gKwkJCQlicmVhazsN Cj4gKw0KPiArCQkJY3B1X3JlbGF4KCk7DQo+ICsJCX0NCj4gKw0KPiArCQlpZiAodGltZW91dCA8 PSAwKQ0KDQppZiAoIXRpbWVvdXQpDQoNCltdDQoNCj4gK3N0YXRpYyBzdHJ1Y3QgZG1hX2NoYW4g KmJjbTI4MzVfZG1hX3hsYXRlKHN0cnVjdCBvZl9waGFuZGxlX2FyZ3MgKnNwZWMsDQo+ICsJCQkJ CSAgIHN0cnVjdCBvZl9kbWEgKm9mZG1hKQ0KPiArew0KPiArCXN0cnVjdCBiY20yODM1X2RtYWRl diAqZCA9IG9mZG1hLT5vZl9kbWFfZGF0YTsNCj4gKwlzdHJ1Y3QgZG1hX2NoYW4gKmNoYW4sICpj YW5kaWRhdGU7DQo+ICsNCj4gK3JldHJ5Og0KPiArCWNhbmRpZGF0ZSA9IE5VTEw7DQo+ICsNCj4g KwkvKiBXYWxrIHRoZSBsaXN0IG9mIGNoYW5uZWxzIHJlZ2lzdGVyZWQgd2l0aCB0aGUgY3VycmVu dCBpbnN0YW5jZSBhbmQNCj4gKwkgKiBmaW5kIG9uZSB0aGF0IGlzIGN1cnJlbnRseSB1bnVzZWQg Ki8NCj4gKwlsaXN0X2Zvcl9lYWNoX2VudHJ5KGNoYW4sICZkLT5kZGV2LmNoYW5uZWxzLCBkZXZp Y2Vfbm9kZSkNCj4gKwkJaWYgKGNoYW4tPmNsaWVudF9jb3VudCA9PSAwKSB7DQo+ICsJCQljYW5k aWRhdGUgPSBjaGFuOw0KPiArCQkJYnJlYWs7DQo+ICsJCX0NCj4gKw0KPiArCWlmICghY2FuZGlk YXRlKQ0KPiArCQlyZXR1cm4gTlVMTDsNCj4gKw0KPiArCS8qIGRtYV9nZXRfc2xhdmVfY2hhbm5l bCB3aWxsIHJldHVybiBOVUxMIGlmIHdlIGxvc3QgYSByYWNlIGJldHdlZW4NCj4gKwkgKiB0aGUg bG9va3VwIGFuZCB0aGUgcmVzZXJ2YXRpb24gKi8NCj4gKwljaGFuID0gZG1hX2dldF9zbGF2ZV9j aGFubmVsKGNhbmRpZGF0ZSk7DQo+ICsNCj4gKwlpZiAoY2hhbikgew0KDQpQZXJoYXBzDQoNCmlm ICghY2hhbikNCmdvdG8gcmV0cnk7DQoNCg0KPiArCQlzdHJ1Y3QgYmNtMjgzNV9jaGFuICpjID0g dG9fYmNtMjgzNV9kbWFfY2hhbihjaGFuKTsNCj4gKw0KPiArCQkvKiBTZXQgRFJFUSBmcm9tIHBh cmFtICovDQo+ICsJCWMtPmRyZXEgPSBzcGVjLT5hcmdzWzBdOw0KPiArDQo+ICsJCXJldHVybiBj aGFuOw0KPiArCX0NCj4gKw0KPiArCWdvdG8gcmV0cnk7DQo+ICt9DQoNCj4gK3N0YXRpYyBpbnQg YmNtMjgzNV9kbWFfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikNCj4gK3sNCj4g KwlzdHJ1Y3QgYmNtMjgzNV9kbWFkZXYgKm9kOw0KPiArCXN0cnVjdCByZXNvdXJjZSAqcmVzOw0K PiArCXZvaWQgX19pb21lbSAqYmFzZTsNCj4gKwlpbnQgcmM7DQo+ICsJaW50IGk7DQo+ICsJaW50 IGlycTsNCj4gKwl1aW50MzJfdCBjaGFuc19hdmFpbGFibGU7DQoNCldoeSB1aW50MzJfdD8NCg0K W10NCg0KPiArCWlmIChwZGV2LT5kZXYub2Zfbm9kZSkgew0KDQpQZXJoYXBzDQoNCmlmICghLi4u b2Zfbm9kZSkgew0KIC4uLg0KIHJldHVybiAtRUlOVkFMOw0KfQ0KDQo+ICsJCS8qIFJlcXVlc3Qg RE1BIGNoYW5uZWwgbWFzayBmcm9tIGRldmljZSB0cmVlICovDQo+ICsJCWlmIChvZl9wcm9wZXJ0 eV9yZWFkX3UzMihwZGV2LT5kZXYub2Zfbm9kZSwNCj4gKwkJCQkiYnJjbSxkbWEtY2hhbm5lbC1t YXNrIiwNCj4gKwkJCQkmY2hhbnNfYXZhaWxhYmxlKSkgew0KPiArCQkJZGV2X2VycigmcGRldi0+ ZGV2LCAiRmFpbGVkIHRvIGdldCBjaGFubmVsIG1hc2tcbiIpOw0KPiArCQkJYmNtMjgzNV9kbWFf ZnJlZShvZCk7DQo+ICsJCQlyZXR1cm4gLUVJTlZBTDsNCj4gKwkJfQ0KPiArCX0gZWxzZSB7DQo+ ICsJCWRldl9lcnIoJnBkZXYtPmRldiwgIkZhaWxlZCB0byBnZXQgY2hhbm5lbCBtYXNrLiBObyBk ZXZpY2UgdHJlZS5cbiIpOw0KPiArCQliY20yODM1X2RtYV9mcmVlKG9kKTsNCj4gKwkJcmV0dXJu IC1FSU5WQUw7DQo+ICsJfQ0KDQo+ICsJZGV2X2RiZygmcGRldi0+ZGV2LCAiSW5pdGlhbGl6ZWQg JWkgRE1BIGNoYW5uZWxzXG4iLCBpKTsNCj4gKw0KPiArCWlmIChwZGV2LT5kZXYub2Zfbm9kZSkg ew0KDQpEb2VzIGl0IG1ha2Ugc2Vuc2U/DQoNCj4gKwkJLyogRGV2aWNlLXRyZWUgRE1BIGNvbnRy b2xsZXIgcmVnaXN0cmF0aW9uICovDQo+ICsJCXJjID0gb2ZfZG1hX2NvbnRyb2xsZXJfcmVnaXN0 ZXIocGRldi0+ZGV2Lm9mX25vZGUsDQo+ICsJCQkJYmNtMjgzNV9kbWFfeGxhdGUsIG9kKTsNCj4g KwkJaWYgKHJjKSB7DQo+ICsJCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJGYWlsZWQgdG8gcmVnaXN0 ZXIgRE1BIGNvbnRyb2xsZXJcbiIpOw0KPiArCQkJYmNtMjgzNV9kbWFfZnJlZShvZCk7DQo+ICsJ CQlyZXR1cm4gcmM7DQoNCmdvdG8gZXJyX25vX2RtYTsNCg0KPiArCQl9DQo+ICsJfQ0KPiArDQo+ ICsJcmMgPSBkbWFfYXN5bmNfZGV2aWNlX3JlZ2lzdGVyKCZvZC0+ZGRldik7DQo+ICsJaWYgKHJj KSB7DQo+ICsJCWRldl9lcnIoJnBkZXYtPmRldiwNCj4gKwkJCSJGYWlsZWQgdG8gcmVnaXN0ZXIg c2xhdmUgRE1BIGVuZ2luZSBkZXZpY2U6ICVkXG4iLCByYyk7DQo+ICsJCWJjbTI4MzVfZG1hX2Zy ZWUob2QpOw0KPiArCQlyZXR1cm4gcmM7DQoNCmdvdG8gZXJyX25vX2RtYTsNCg0KPiArCX0NCj4g Kw0KPiArCWRldl9kYmcoJnBkZXYtPmRldiwgIkxvYWQgQkNNMjgzNSBETUEgZW5naW5lIGRyaXZl clxuIik7DQoNCg0KPiArCXJldHVybiByYzsNCg0KcmV0dXJuIDA7DQoNCmVycl9ub19kbWE6DQpi Y20yODM1X2RtYV9mcmVlKG9kKTsNCnJldHVybiByYzsNCg0KPw0KDQoNCi0tIA0KQW5keSBTaGV2 Y2hlbmtvIDxhbmRyaXkuc2hldmNoZW5rb0BpbnRlbC5jb20+DQpJbnRlbCBGaW5sYW5kIE95DQot LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0KSW50ZWwgRmlubGFuZCBPeQpSZWdpc3RlcmVkIEFkZHJlc3M6IFBMIDI4MSwg MDAxODEgSGVsc2lua2kgCkJ1c2luZXNzIElkZW50aXR5IENvZGU6IDAzNTc2MDYgLSA0IApEb21p Y2lsZWQgaW4gSGVsc2lua2kgCgpUaGlzIGUtbWFpbCBhbmQgYW55IGF0dGFjaG1lbnRzIG1heSBj b250YWluIGNvbmZpZGVudGlhbCBtYXRlcmlhbCBmb3IKdGhlIHNvbGUgdXNlIG9mIHRoZSBpbnRl bmRlZCByZWNpcGllbnQocykuIEFueSByZXZpZXcgb3IgZGlzdHJpYnV0aW9uCmJ5IG90aGVycyBp cyBzdHJpY3RseSBwcm9oaWJpdGVkLiBJZiB5b3UgYXJlIG5vdCB0aGUgaW50ZW5kZWQKcmVjaXBp ZW50LCBwbGVhc2UgY29udGFjdCB0aGUgc2VuZGVyIGFuZCBkZWxldGUgYWxsIGNvcGllcy4K

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

#6 lore raw

Thank you! Few comments below.

Quoted 7 lines

[]

drivers/dma/bcm2835-dma.c line 283

Quoted 3 lines
drivers/dma/bcm2835-dma.c new file +3 -0
+static enum dma_status bcm2835_dma_tx_status(struct dma_chan *chan,
+	dma_cookie_t cookie, struct dma_tx_state *txstate)
+{

[]

Quoted 5 lines

drivers/dma/bcm2835-dma.c line 311

Quoted 2 lines
drivers/dma/bcm2835-dma.c new file +2 -0
+	} else {
+		txstate->residue = 0;

Useless assignment since dmaengine will do this for you in dma_cookie_status.

I agree that it is useless, but I think otherwise it might be concealed that there is a third case left that uses a residue of 0. Do you think a comment is better? E.g.:

+ } else {
+ /* residue = 0 per default */

Quoted 10 lines

drivers/dma/bcm2835-dma.c line 366

Quoted 8 lines
drivers/dma/bcm2835-dma.c new file +8 -0
+	/* Bus width translates to the element size (ES) */
+	switch (dev_width) {
+	case DMA_SLAVE_BUSWIDTH_4_BYTES:
+		es = BCM2835_DMA_DATA_TYPE_S32;
+		break;
+	default:
+		return NULL;
+	}

So, you use switch-case on hope to extend it later, correct?

Yes, there is a S128 case left, but that is not implemented yet.

Quoted 11 lines

drivers/dma/bcm2835-dma.c line 614

Quoted 9 lines
drivers/dma/bcm2835-dma.c new file +9 -0
+static int bcm2835_dma_probe(struct platform_device *pdev)
+{
+	struct bcm2835_dmadev *od;
+	struct resource *res;
+	void __iomem *base;
+	int rc;
+	int i;
+	int irq;
+	uint32_t chans_available;

Why uint32_t?

Because it is a bit mask of fixed length that directly comes from the firmware.

Quoted 14 lines
Quoted 13 lines
drivers/dma/bcm2835-dma.c new file +13 -0
+		/* Request DMA channel mask from device tree */
+		if (of_property_read_u32(pdev->dev.of_node,
+				"brcm,dma-channel-mask",
+				&chans_available)) {
+			dev_err(&pdev->dev, "Failed to get channel mask\n");
+			bcm2835_dma_free(od);
+			return -EINVAL;
+		}
+	} else {
+		dev_err(&pdev->dev, "Failed to get channel mask. No device tree.\n");
+		bcm2835_dma_free(od);
+		return -EINVAL;
+	}
Quoted 5 lines

drivers/dma/bcm2835-dma.c line 687

Quoted 3 lines
drivers/dma/bcm2835-dma.c new file +3 -0
+	dev_dbg(&pdev->dev, "Initialized %i DMA channels\n", i);
+
+	if (pdev->dev.of_node) {

Does it make sense?

There was already a discussion about that in PATCHv4. It should be possible to add board file initialization later with few patching. Although, maybe this will not be relevant anymore, because device tree support of this platform is getting better more and more.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#7 lore raw
Quoted 1 line · Florian Meier

Thank you! Few comments below.

See my answers below.

Quoted 16 lines
Quoted 11 lines

drivers/dma/bcm2835-dma.c line 283

Quoted 3 lines
drivers/dma/bcm2835-dma.c new file +3 -0
+static enum dma_status bcm2835_dma_tx_status(struct dma_chan *chan,
+	dma_cookie_t cookie, struct dma_tx_state *txstate)
+{

[]

drivers/dma/bcm2835-dma.c line 311

Quoted 2 lines
drivers/dma/bcm2835-dma.c new file +2 -0
+	} else {
+		txstate->residue = 0;

Useless assignment since dmaengine will do this for you in dma_cookie_status.

I agree that it is useless, but I think otherwise it might be concealed that there is a third case left that uses a residue of 0. Do you think a comment is better? E.g.:

Review

Quoted 2 lines
(quoted diff) +2 -0
+	} else {
+		/* residue = 0 per default */

I think like in many other DMA drivers either you have separate function to get residue, which returns 0, or just not include this case.

Quoted 9 lines
Quoted 6 lines

drivers/dma/bcm2835-dma.c line 614

Quoted 4 lines
drivers/dma/bcm2835-dma.c new file +3 -0
+static int bcm2835_dma_probe(struct platform_device *pdev)
+{
 
+	uint32_t chans_available;

Why uint32_t?

Because it is a bit mask of fixed length that directly comes from the firmware.

Like one already told you in your i2s patch, please, change that to corresponding u* value, namely u32.

Signature · 7 lines
Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/[email protected]>
Intel Finland Oy

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#8 lore raw
Quoted 16 lines
Quoted 16 lines
Quoted 11 lines

drivers/dma/bcm2835-dma.c line 283

Quoted 3 lines
drivers/dma/bcm2835-dma.c new file +3 -0
+static enum dma_status bcm2835_dma_tx_status(struct dma_chan *chan,
+	dma_cookie_t cookie, struct dma_tx_state *txstate)
+{

[]

drivers/dma/bcm2835-dma.c line 311

Quoted 2 lines
drivers/dma/bcm2835-dma.c new file +2 -0
+	} else {
+		txstate->residue = 0;

Useless assignment since dmaengine will do this for you in dma_cookie_status.

I agree that it is useless, but I think otherwise it might be concealed that there is a third case left that uses a residue of 0. Do you think a comment is better? E.g.:

Quoted 5 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+	} else {
+		/* residue = 0 per default */

I think like in many other DMA drivers either you have separate function to get residue, which returns 0, or just not include this case.

You mean like in the omap-dma.c? ;-P

Quoted 7 lines
Quoted 7 lines
Quoted 6 lines

drivers/dma/bcm2835-dma.c line 614

Quoted 4 lines
drivers/dma/bcm2835-dma.c new file +3 -0
+static int bcm2835_dma_probe(struct platform_device *pdev)
+{
 
+	uint32_t chans_available;

Why uint32_t?

Quoted 5 lines
Quoted 2 lines

Because it is a bit mask of fixed length that directly comes from the firmware.

Like one already told you in your i2s patch, please, change that to corresponding u* value, namely u32.

I have no problem with changing that, but why?

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

#9 lore raw
In reply to Andy Shevchenko
Quoted 10 lines · Andy Shevchenko
Quoted 6 lines · Florian Meier
Quoted 3 lines

drivers/dma/bcm2835-dma.c line 614

Quoted 1 line
drivers/dma/bcm2835-dma.c new file +1 -0
+	uint32_t chans_available;

Why uint32_t?

Because it is a bit mask of fixed length that directly comes from the firmware.

Like one already told you in your i2s patch, please, change that to corresponding u* value, namely u32.

There's no problem with uint32_t vs u32 - either will do. u32 is the pre-stdint.h Linux definition of a 32-bit unsigned integer. There's no reason why uint32_t isn't perfectly acceptable. It's a matter of author taste which gets used. (Except where modifications are to an existing chunk of code using one or the other - where consistency then matters more.)
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#10 lore raw
Quoted 12 lines · Russell King - ARM Linux
Quoted 10 lines · Andy Shevchenko
Quoted 6 lines · Florian Meier
Quoted 3 lines

drivers/dma/bcm2835-dma.c line 614

Quoted 1 line
drivers/dma/bcm2835-dma.c new file +1 -0
+	uint32_t chans_available;

Why uint32_t?

Because it is a bit mask of fixed length that directly comes from the firmware.

Like one already told you in your i2s patch, please, change that to corresponding u* value, namely u32.

Quoted 6 lines

There's no problem with uint32_t vs u32 - either will do. u32 is the pre-stdint.h Linux definition of a 32-bit unsigned integer. There's no reason why uint32_t isn't perfectly acceptable. It's a matter of author taste which gets used. (Except where modifications are to an existing chunk of code using one or the other - where consistency then matters more.)

Sorry for being a source of confusion here. I won't push this point in future.

Thanks,
Mark.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#11 lore raw
In reply to Russell King - ARM Linux
Quoted 12 lines · Russell King - ARM Linux
Quoted 10 lines · Andy Shevchenko
Quoted 6 lines · Florian Meier
Quoted 3 lines

drivers/dma/bcm2835-dma.c line 614

Quoted 1 line
drivers/dma/bcm2835-dma.c new file +1 -0
+	uint32_t chans_available;

Why uint32_t?

Because it is a bit mask of fixed length that directly comes from the firmware.

Like one already told you in your i2s patch, please, change that to corresponding u* value, namely u32.

Quoted 6 lines

There's no problem with uint32_t vs u32 - either will do. u32 is the pre-stdint.h Linux definition of a 32-bit unsigned integer. There's no reason why uint32_t isn't perfectly acceptable. It's a matter of author taste which gets used. (Except where modifications are to an existing chunk of code using one or the other - where consistency then matters more.)

https://lkml.org/lkml/2006/5/2/258

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

#12 lore raw
In reply to Florian Meier
Quoted 23 lines · Florian Meier

Add support for DMA controller of BCM2835 as used in the Raspberry Pi. Currently it only supports cyclic DMA.

---

This version includes some more style improvements suggested in the previous thread.

 .../devicetree/bindings/dma/bcm2835-dma.txt        |   56 ++
 drivers/dma/Kconfig                                |    6 +
 drivers/dma/Makefile                               |    1 +
 drivers/dma/bcm2835-dma.c                          |  736 ++++++++++++++++++++
 4 files changed, 799 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/bcm2835-dma.txt
 create mode 100644 drivers/dma/bcm2835-dma.c
Documentation/devicetree/bindings/dma/bcm2835-dma.txt new file +0 -0
new file mode 100644
index 0000000..7d91019

Documentation/devicetree/bindings/dma/bcm2835-dma.txt line 9

Quoted 9 lines
Documentation/devicetree/bindings/dma/bcm2835-dma.txt new file +9 -0
@@ -0,0 +1,56 @@
+* BCM2835 DMA controller
+
+Required properties:
+- compatible: Should be "brcm,bcm2835-dma".
+- reg: Should contain DMA registers location and length.
+- interrupts: Should contain the DMA interrupts associated
+               to the DMA channels in ascending order.
+               First cell is the IRQ bank.
+               Second cell is the IRQ number.

The format of the cells is a property of the interrupt parent, not of the DMA controller. It shouldn't be described here.

Documentation/devicetree/bindings/dma/bcm2835-dma.txt line 11

Quoted 2 lines
Documentation/devicetree/bindings/dma/bcm2835-dma.txt new file +2 -0
+- #dma-cells: Must be <1>, used to represent the number of integer cells in
+               the dmas property of client devices.

A brief description of the set of sane values of the dma-specifier cell would be better.

How many channels does the DMA controller have?

Documentation/devicetree/bindings/dma/bcm2835-dma.txt line 13

Quoted 2 lines
Documentation/devicetree/bindings/dma/bcm2835-dma.txt new file +2 -0
+- brcm,dma-channel-mask: Bit mask representing the channels
+                        not used by the firmware.

Which bits correspond to which channels?

How many channels are likely to be reserved out of how many in total?

Are they likely to be an arbitrary set, or some contiguous range?

Quoted 9 lines
Documentation/devicetree/bindings/dma/bcm2835-dma.txt new file +9 -0
+
+Example:
+
+dma: dma at 7e007000 {
+       compatible = "brcm,bcm2835-dma";
+       reg = <0x7e007000 0xf00>;
+       interrupts = <1 16
+                     1 17
+                     1 18

Documentation/devicetree/bindings/dma/bcm2835-dma.txt line 32

Quoted 10 lines
Documentation/devicetree/bindings/dma/bcm2835-dma.txt new file +10 -0
+                     1 19
+                     1 20
+                     1 21
+                     1 22
+                     1 23
+                     1 24
+                     1 25
+                     1 26
+                     1 27
+                     1 28>;

Please bracket these individually.

Documentation/devicetree/bindings/dma/bcm2835-dma.txt line 44

Quoted 12 lines
Documentation/devicetree/bindings/dma/bcm2835-dma.txt new file +12 -0
+
+       #dma-cells = <1>;
+       brcm,dma-channel-mask = <0x7f35>;
+};
+
+DMA clients connected to the BCM2835 DMA controller must use the format
+described in the dma.txt file, using a two-cell specifier for each channel:
+a phandle plus one integer cells.
+The two cells in order are:
+
+1. A phandle pointing to the DMA controller.
+2. The DREQ number.

This description is unnecessary, and technically wrong (the phandle isn't part of the specifier, as the specifier goes with the phandle).

Documentation/devicetree/bindings/dma/bcm2835-dma.txt line 54

Quoted 10 lines
Documentation/devicetree/bindings/dma/bcm2835-dma.txt new file +10 -0
+
+Example:
+
+bcm2835_i2s: i2s at 7e203000 {
+       compatible = "brcm,bcm2835-i2s";
+       reg = < 0x7e203000 0x20
+               0x7e101098 0x02>;
+
+       dmas = <&dma 2
+               &dma 3>;

Brackets please.

[...]

Documentation/devicetree/bindings/dma/bcm2835-dma.txt

Quoted 8 lines
Documentation/devicetree/bindings/dma/bcm2835-dma.txt new file +8 -0
+struct bcm2835_dma_cb {
+       uint32_t info;
+       uint32_t src;
+       uint32_t dst;
+       uint32_t length;
+       uint32_t stride;
+       uint32_t next;
+       uint32_t pad[2];

s/uint32_t/u32/ here and elsewhere.

[...]

Quoted 5 lines
Documentation/devicetree/bindings/dma/bcm2835-dma.txt new file +5 -0
+static void bcm2835_dma_start_desc(struct bcm2835_chan *c)
+{
+       struct virt_dma_desc *vd = vchan_next_desc(&c->vc);
+       struct bcm2835_desc *d;
+

Documentation/devicetree/bindings/dma/bcm2835-dma.txt

Quoted 10 lines
Documentation/devicetree/bindings/dma/bcm2835-dma.txt new file +10 -0
+       if (!vd) {
+               c->desc = NULL;
+               return;
+       }
+
+       list_del(&vd->node);
+
+       c->desc = d = to_bcm2835_dma_desc(&vd->tx);
+
+       dsb();  /* ARM data synchronization (push) operation */

We all know what a dsb is. What you should explain is _why_ the dsb is here. As this is sat under drivers, it would be nicer to use an architecture generic barrier rather than dsb() directly.

Quoted 15 lines
Documentation/devicetree/bindings/dma/bcm2835-dma.txt new file +15 -0
+
+       writel(d->control_block_base_phys, c->chan_base + BCM2835_DMA_ADDR);
+       writel(BCM2835_DMA_ACTIVE, c->chan_base + BCM2835_DMA_CS);
+}
+
+static irqreturn_t bcm2835_dma_callback(int irq, void *data)
+{
+       struct bcm2835_chan *c = data;
+       struct bcm2835_desc *d;
+       unsigned long flags;
+
+       spin_lock_irqsave(&c->vc.lock, flags);
+
+       /* Acknowledge interrupt */
+       writel(BCM2835_DMA_INT, c->chan_base + BCM2835_DMA_CS);

Documentation/devicetree/bindings/dma/bcm2835-dma.txt

Quoted 10 lines
Documentation/devicetree/bindings/dma/bcm2835-dma.txt new file +10 -0
+
+       d = c->desc;
+
+       if (d) {
+               /* TODO Only works for cyclic DMA */
+               vchan_cyclic_callback(&d->vd);
+       }
+
+       /* Keep the DMA engine running */
+       dsb(); /* ARM synchronization barrier */

Better explanation please.

Documentation/devicetree/bindings/dma/bcm2835-dma.txt

Quoted 13 lines
Documentation/devicetree/bindings/dma/bcm2835-dma.txt new file +13 -0
+       writel(BCM2835_DMA_ACTIVE, c->chan_base + BCM2835_DMA_CS);
+
+       spin_unlock_irqrestore(&c->vc.lock, flags);
+
+       return IRQ_HANDLED;
+}
+
+static int bcm2835_dma_alloc_chan_resources(struct dma_chan *chan)
+{
+       struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
+
+       dev_dbg(c->vc.chan.device->dev,
+                       "Allocating DMA channel %i\n", c->ch);

Why not %d? It's far more common...

[...]

Documentation/devicetree/bindings/dma/bcm2835-dma.txt

Quoted 9 lines
Documentation/devicetree/bindings/dma/bcm2835-dma.txt new file +9 -0
+       if (pdev->dev.of_node) {
+               /* Request DMA channel mask from device tree */
+               if (of_property_read_u32(pdev->dev.of_node,
+                               "brcm,dma-channel-mask",
+                               &chans_available)) {
+                       dev_err(&pdev->dev, "Failed to get channel mask\n");
+                       bcm2835_dma_free(od);
+                       return -EINVAL;
+               }

As of_property_read_u32 has an implicit check on np, you don't need to first check pdev->dev.of_node.

Documentation/devicetree/bindings/dma/bcm2835-dma.txt

Quoted 8 lines
Documentation/devicetree/bindings/dma/bcm2835-dma.txt new file +8 -0
+       } else {
+               dev_err(&pdev->dev, "Failed to get channel mask. No device tree.\n");
+               bcm2835_dma_free(od);
+               return -EINVAL;
+       }
+
+       /* Do not use the FIQ and BULK channels */
+       chans_available &= ~0xD;

A couple of #defines would be nice, along with an explanation as to why...

Thanks,
Mark.