All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Add support for AHB DMA controller on Milbeaut series
@ 2019-06-13  0:51 jassisinghbrar
  2019-06-13  0:52 ` [PATCH 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings jassisinghbrar
                   ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: jassisinghbrar @ 2019-06-13  0:51 UTC (permalink / raw)
  To: dmaengine, devicetree, linux-kernel
  Cc: vkoul, robh+dt, mark.rutland, orito.takao, masami.hiramatsu,
	kasai.kazuhiro, Jassi Brar

From: Jassi Brar <jaswinder.singh@linaro.org>

The following series adds AHB DMA (HDMAC) controller support on Milbeaut series.
This controller is capable of Mem<->MEM and DEV<->MEM transfer. But only DEV<->MEM
is currently supported.

Jassi Brar (2):
  dt-bindings: milbeaut-hdmac: Add Socionext Milbeaut HDMAC bindings
  dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms

 .../bindings/dma/milbeaut-m10v-hdmac.txt           |  54 ++
 drivers/dma/Kconfig                           |  10 +
 drivers/dma/Makefile                          |   1 +
 drivers/dma/milbeaut-hdmac.c                  | 572 ++++++++++++++++++
 4 files changed, 637 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
 create mode 100644 drivers/dma/milbeaut-hdmac.c

-- 
2.17.1


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

* [PATCH 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings
  2019-06-13  0:51 [PATCH 0/2] Add support for AHB DMA controller on Milbeaut series jassisinghbrar
@ 2019-06-13  0:52 ` jassisinghbrar
  2019-07-09 14:34   ` Rob Herring
  2019-06-13  0:52 ` [PATCH 2/2] dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms jassisinghbrar
  2019-08-18  5:16 ` [PATCH v2 0/2] Add support for AHB DMA controller on Milbeaut series jassisinghbrar
  2 siblings, 1 reply; 17+ messages in thread
From: jassisinghbrar @ 2019-06-13  0:52 UTC (permalink / raw)
  To: dmaengine, devicetree, linux-kernel
  Cc: vkoul, robh+dt, mark.rutland, orito.takao, masami.hiramatsu,
	kasai.kazuhiro, Jassi Brar

From: Jassi Brar <jaswinder.singh@linaro.org>

Document the devicetree bindings for Socionext Milbeaut HDMAC
controller. Controller has upto 8 floating channels, that need
a predefined slave-id to work from a set of slaves.

Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
---
 .../bindings/dma/milbeaut-m10v-hdmac.txt           | 54 +++++++++++++++++++
 1 file changed, 54 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt

diff --git a/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
new file mode 100644
index 000000000000..a104fcb9e73d
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
@@ -0,0 +1,51 @@
+* Milbeaut AHB DMA Controller
+
+Milbeaut AHB DMA controller has transfer capability bellow.
+ - memory to memory transfer
+ - device to memory transfer
+ - memory to device transfer
+
+Required property:
+- compatible:       Should be  "socionext,milbeaut-m10v-hdmac"
+- reg:              Should contain DMA registers location and length.
+- interrupts:       Should contain all of the per-channel DMA interrupts.
+- #dma-cells:       Should be 1. Specify the ID of the slave.
+- clocks:           Phandle to the clock used by the HDMAC module.
+
+
+Example:
+
+	hdmac1: hdmac@1e110000 {
+		compatible = "socionext,milbeaut-m10v-hdmac";
+		reg = <0x1e110000 0x10000>;
+		interrupts = <0 132 4>,
+			     <0 133 4>,
+			     <0 134 4>,
+			     <0 135 4>,
+			     <0 136 4>,
+			     <0 137 4>,
+			     <0 138 4>,
+			     <0 139 4>;
+		#dma-cells = <1>;
+		clocks = <&dummy_clk>;
+	};
+
+* DMA client
+
+Clients have to specify the DMA requests with phandles in a list.
+
+Required properties:
+- dmas:             List of one or more DMA request specifiers. One DMA request specifier
+                    consists of a phandle to the DMA controller followed by the integer
+                    specifying the request line.
+- dma-names:        List of string identifiers for the DMA requests. For the correct
+                    names, have a look at the specific client driver.
+
+Example:
+
+	sni_spi1: spi@1e800100 {
+		...
+		dmas = <&hdmac1 22>, <&hdmac1 21>;
+		dma-names = "tx", "rx";
+		...
+	};
-- 
2.17.1


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

* [PATCH 2/2] dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms
  2019-06-13  0:51 [PATCH 0/2] Add support for AHB DMA controller on Milbeaut series jassisinghbrar
  2019-06-13  0:52 ` [PATCH 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings jassisinghbrar
@ 2019-06-13  0:52 ` jassisinghbrar
  2019-06-24  6:44   ` Vinod Koul
  2019-08-18  5:16 ` [PATCH v2 0/2] Add support for AHB DMA controller on Milbeaut series jassisinghbrar
  2 siblings, 1 reply; 17+ messages in thread
From: jassisinghbrar @ 2019-06-13  0:52 UTC (permalink / raw)
  To: dmaengine, devicetree, linux-kernel
  Cc: vkoul, robh+dt, mark.rutland, orito.takao, masami.hiramatsu,
	kasai.kazuhiro, Jassi Brar

From: Jassi Brar <jaswinder.singh@linaro.org>

Driver for Socionext Milbeaut HDMAC controller. The controller has
upto 8 floating channels, that need a predefined slave-id to work
from a set of slaves.

Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
---
 drivers/dma/Kconfig          |  10 +
 drivers/dma/Makefile         |   1 +
 drivers/dma/milbeaut-hdmac.c | 572 +++++++++++++++++++++++++++++++++++
 3 files changed, 583 insertions(+)
 create mode 100644 drivers/dma/milbeaut-hdmac.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 703275cc29de..15a1d5263ca1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -347,6 +347,16 @@ config MCF_EDMA
 	  minimal intervention from a host processor.
 	  This module can be found on Freescale ColdFire mcf5441x SoCs.
 
+config MILBEAUT_HDMAC
+	tristate "Milbeaut AHB DMA support"
+	depends on ARCH_MILBEAUT || COMPILE_TEST
+	depends on OF
+	select DMA_ENGINE
+	select DMA_VIRTUAL_CHANNELS
+	help
+	  Say yes here to support the Socionext Milbeaut
+	  HDMAC device.
+
 config MMP_PDMA
 	bool "MMP PDMA support"
 	depends on ARCH_MMP || ARCH_PXA || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 6126e1c3a875..d0a9f46726e8 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
 obj-$(CONFIG_INTEL_MIC_X100_DMA) += mic_x100_dma.o
 obj-$(CONFIG_K3_DMA) += k3dma.o
 obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o
+obj-$(CONFIG_MILBEAUT_HDMAC) += milbeaut-hdmac.o
 obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
 obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
 obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
diff --git a/drivers/dma/milbeaut-hdmac.c b/drivers/dma/milbeaut-hdmac.c
new file mode 100644
index 000000000000..9c9fabdf8cdc
--- /dev/null
+++ b/drivers/dma/milbeaut-hdmac.c
@@ -0,0 +1,572 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2019 Linaro Ltd.
+// Copyright (C) 2019 Socionext Inc.
+
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_dma.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/bitfield.h>
+
+#include "virt-dma.h"
+
+#define MLB_HDMAC_DMACR		0x0	/* global */
+#define MLB_HDMAC_DE		BIT(31)
+#define MLB_HDMAC_DS		BIT(30)
+#define MLB_HDMAC_PR		BIT(28)
+#define MLB_HDMAC_DH		GENMASK(27, 24)
+
+#define MLB_HDMAC_CH_STRIDE	0x10
+
+#define MLB_HDMAC_DMACA		0x0	/* channel */
+#define MLB_HDMAC_EB		BIT(31)
+#define MLB_HDMAC_PB		BIT(30)
+#define MLB_HDMAC_ST		BIT(29)
+#define MLB_HDMAC_IS		GENMASK(28, 24)
+#define MLB_HDMAC_BT		GENMASK(23, 20)
+#define MLB_HDMAC_BC		GENMASK(19, 16)
+#define MLB_HDMAC_TC		GENMASK(15, 0)
+#define MLB_HDMAC_DMACB		0x4
+#define MLB_HDMAC_TT		GENMASK(31, 30)
+#define MLB_HDMAC_MS		GENMASK(29, 28)
+#define MLB_HDMAC_TW		GENMASK(27, 26)
+#define MLB_HDMAC_FS		BIT(25)
+#define MLB_HDMAC_FD		BIT(24)
+#define MLB_HDMAC_RC		BIT(23)
+#define MLB_HDMAC_RS		BIT(22)
+#define MLB_HDMAC_RD		BIT(21)
+#define MLB_HDMAC_EI		BIT(20)
+#define MLB_HDMAC_CI		BIT(19)
+#define MLB_HDMAC_SS		GENMASK(18, 16)
+#define MLB_HDMAC_SP		GENMASK(15, 12)
+#define MLB_HDMAC_DP		GENMASK(11, 8)
+#define MLB_HDMAC_DMACSA	0x8
+#define MLB_HDMAC_DMACDA	0xc
+
+#define MLB_HDMAC_BUSWIDTHS		(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
+					BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+					BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
+
+struct milbeaut_hdmac_desc {
+	struct virt_dma_desc vd;
+	struct scatterlist *sgl;
+	unsigned int sg_len;
+	unsigned int sg_cur;
+	enum dma_transfer_direction dir;
+};
+
+struct milbeaut_hdmac_chan {
+	struct virt_dma_chan vc;
+	struct milbeaut_hdmac_device *mdev;
+	struct milbeaut_hdmac_desc *md;
+	void __iomem *reg_ch_base;
+	unsigned int slave_id;
+	struct dma_slave_config	cfg;
+};
+
+struct milbeaut_hdmac_device {
+	struct dma_device ddev;
+	struct clk *clk;
+	void __iomem *reg_base;
+	struct milbeaut_hdmac_chan channels[0];
+};
+
+static struct milbeaut_hdmac_chan *
+to_milbeaut_hdmac_chan(struct virt_dma_chan *vc)
+{
+	return container_of(vc, struct milbeaut_hdmac_chan, vc);
+}
+
+static struct milbeaut_hdmac_desc *
+to_milbeaut_hdmac_desc(struct virt_dma_desc *vd)
+{
+	return container_of(vd, struct milbeaut_hdmac_desc, vd);
+}
+
+/* mc->vc.lock must be held by caller */
+static struct milbeaut_hdmac_desc *
+milbeaut_hdmac_next_desc(struct milbeaut_hdmac_chan *mc)
+{
+	struct virt_dma_desc *vd;
+
+	vd = vchan_next_desc(&mc->vc);
+	if (!vd) {
+		mc->md = NULL;
+		return NULL;
+	}
+
+	list_del(&vd->node);
+
+	mc->md = to_milbeaut_hdmac_desc(vd);
+
+	return mc->md;
+}
+
+/* mc->vc.lock must be held by caller */
+static void milbeaut_chan_start(struct milbeaut_hdmac_chan *mc,
+				struct milbeaut_hdmac_desc *md)
+{
+	struct scatterlist *sg;
+	u32  cb, ca, src_addr, dest_addr, len;
+	u32 width, burst;
+
+	sg = &md->sgl[md->sg_cur];
+	len = sg_dma_len(sg);
+
+	cb = MLB_HDMAC_CI | MLB_HDMAC_EI;
+	if (md->dir == DMA_MEM_TO_DEV) {
+		cb |= MLB_HDMAC_FD;
+		width = mc->cfg.dst_addr_width;
+		burst = mc->cfg.dst_maxburst;
+		src_addr = sg_dma_address(sg);
+		dest_addr = mc->cfg.dst_addr;
+	} else {
+		cb |= MLB_HDMAC_FS;
+		width = mc->cfg.src_addr_width;
+		burst = mc->cfg.src_maxburst;
+		src_addr = mc->cfg.src_addr;
+		dest_addr = sg_dma_address(sg);
+	}
+	cb |= FIELD_PREP(MLB_HDMAC_TW, (width >> 1));
+	cb |= FIELD_PREP(MLB_HDMAC_MS, 2);
+
+	writel_relaxed(src_addr, mc->reg_ch_base + MLB_HDMAC_DMACSA);
+	writel_relaxed(dest_addr, mc->reg_ch_base + MLB_HDMAC_DMACDA);
+	writel_relaxed(cb, mc->reg_ch_base + MLB_HDMAC_DMACB);
+
+	ca = FIELD_PREP(MLB_HDMAC_IS, mc->slave_id);
+	if (burst == 16)
+		ca |= FIELD_PREP(MLB_HDMAC_BT, 0xf);
+	else if (burst == 8)
+		ca |= FIELD_PREP(MLB_HDMAC_BT, 0xd);
+	else if (burst == 4)
+		ca |= FIELD_PREP(MLB_HDMAC_BT, 0xb);
+	burst *= width;
+	ca |= FIELD_PREP(MLB_HDMAC_TC, (len / burst - 1));
+	writel_relaxed(ca, mc->reg_ch_base + MLB_HDMAC_DMACA);
+	ca |= MLB_HDMAC_EB;
+	writel_relaxed(ca, mc->reg_ch_base + MLB_HDMAC_DMACA);
+}
+
+/* mc->vc.lock must be held by caller */
+static void milbeaut_hdmac_start(struct milbeaut_hdmac_chan *mc)
+{
+	struct milbeaut_hdmac_desc *md;
+
+	md = milbeaut_hdmac_next_desc(mc);
+	if (md)
+		milbeaut_chan_start(mc, md);
+}
+
+static irqreturn_t milbeaut_hdmac_interrupt(int irq, void *dev_id)
+{
+	struct milbeaut_hdmac_chan *mc = dev_id;
+	struct milbeaut_hdmac_desc *md;
+	irqreturn_t ret = IRQ_HANDLED;
+	u32 val;
+
+	spin_lock(&mc->vc.lock);
+
+	/* Ack and Disable irqs */
+	val = readl_relaxed(mc->reg_ch_base + MLB_HDMAC_DMACB);
+	val &= ~(FIELD_PREP(MLB_HDMAC_SS, 0x7));
+	writel_relaxed(val, mc->reg_ch_base + MLB_HDMAC_DMACB);
+	val &= ~MLB_HDMAC_EI;
+	val &= ~MLB_HDMAC_CI;
+	writel_relaxed(val, mc->reg_ch_base + MLB_HDMAC_DMACB);
+
+	md = mc->md;
+	if (!md)
+		goto out;
+
+	md->sg_cur++;
+
+	if (md->sg_cur >= md->sg_len) {
+		vchan_cookie_complete(&md->vd);
+		md = milbeaut_hdmac_next_desc(mc);
+		if (!md)
+			goto out;
+	}
+
+	milbeaut_chan_start(mc, md);
+
+out:
+	spin_unlock(&mc->vc.lock);
+	return ret;
+}
+
+static void milbeaut_hdmac_free_chan_resources(struct dma_chan *chan)
+{
+	vchan_free_chan_resources(to_virt_chan(chan));
+}
+
+static int
+milbeaut_hdmac_chan_config(struct dma_chan *chan, struct dma_slave_config *cfg)
+{
+	struct virt_dma_chan *vc = to_virt_chan(chan);
+	struct milbeaut_hdmac_chan *mc = to_milbeaut_hdmac_chan(vc);
+
+	spin_lock(&mc->vc.lock);
+	mc->cfg = *cfg;
+	spin_unlock(&mc->vc.lock);
+
+	return 0;
+}
+
+static int milbeaut_hdmac_chan_pause(struct dma_chan *chan)
+{
+	struct virt_dma_chan *vc = to_virt_chan(chan);
+	struct milbeaut_hdmac_chan *mc = to_milbeaut_hdmac_chan(vc);
+	u32 val;
+
+	spin_lock(&mc->vc.lock);
+	val = readl_relaxed(mc->reg_ch_base + MLB_HDMAC_DMACA);
+	val |= MLB_HDMAC_PB;
+	writel_relaxed(val, mc->reg_ch_base + MLB_HDMAC_DMACA);
+	spin_unlock(&mc->vc.lock);
+
+	return 0;
+}
+
+static int milbeaut_hdmac_chan_resume(struct dma_chan *chan)
+{
+	struct virt_dma_chan *vc = to_virt_chan(chan);
+	struct milbeaut_hdmac_chan *mc = to_milbeaut_hdmac_chan(vc);
+	u32 val;
+
+	spin_lock(&mc->vc.lock);
+	val = readl_relaxed(mc->reg_ch_base + MLB_HDMAC_DMACA);
+	val &= ~MLB_HDMAC_PB;
+	writel_relaxed(val, mc->reg_ch_base + MLB_HDMAC_DMACA);
+	spin_unlock(&mc->vc.lock);
+
+	return 0;
+}
+
+static struct dma_async_tx_descriptor *
+milbeaut_hdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+			     unsigned int sg_len,
+			     enum dma_transfer_direction direction,
+			     unsigned long flags, void *context)
+{
+	struct virt_dma_chan *vc = to_virt_chan(chan);
+	struct milbeaut_hdmac_desc *md;
+
+	if (!is_slave_direction(direction))
+		return NULL;
+
+	md = kzalloc(sizeof(*md), GFP_NOWAIT);
+	if (!md)
+		return NULL;
+
+	md->sgl = sgl;
+	md->sg_len = sg_len;
+	md->dir = direction;
+
+	return vchan_tx_prep(vc, &md->vd, flags);
+}
+
+static int milbeaut_hdmac_terminate_all(struct dma_chan *chan)
+{
+	struct virt_dma_chan *vc = to_virt_chan(chan);
+	struct milbeaut_hdmac_chan *mc = to_milbeaut_hdmac_chan(vc);
+	unsigned long flags;
+	int ret = 0;
+	u32 val;
+
+	LIST_HEAD(head);
+
+	spin_lock_irqsave(&vc->lock, flags);
+
+	val = readl_relaxed(mc->reg_ch_base + MLB_HDMAC_DMACA);
+	val &= ~MLB_HDMAC_EB; /* disable the channel */
+	writel_relaxed(val, mc->reg_ch_base + MLB_HDMAC_DMACA);
+
+	if (mc->md) {
+		vchan_terminate_vdesc(&mc->md->vd);
+		mc->md = NULL;
+	}
+
+	vchan_get_all_descriptors(vc, &head);
+
+	spin_unlock_irqrestore(&vc->lock, flags);
+
+	vchan_dma_desc_free_list(vc, &head);
+
+	return ret;
+}
+
+static void milbeaut_hdmac_synchronize(struct dma_chan *chan)
+{
+	vchan_synchronize(to_virt_chan(chan));
+}
+
+static enum dma_status milbeaut_hdmac_tx_status(struct dma_chan *chan,
+						dma_cookie_t cookie,
+						struct dma_tx_state *txstate)
+{
+	struct virt_dma_chan *vc;
+	struct virt_dma_desc *vd;
+	struct milbeaut_hdmac_chan *mc;
+	struct milbeaut_hdmac_desc *md = NULL;
+	enum dma_status stat;
+	unsigned long flags;
+	int i;
+
+	stat = dma_cookie_status(chan, cookie, txstate);
+	/* Return immediately if we do not need to compute the residue. */
+	if (stat == DMA_COMPLETE || !txstate)
+		return stat;
+
+	vc = to_virt_chan(chan);
+
+	spin_lock_irqsave(&vc->lock, flags);
+
+	mc = to_milbeaut_hdmac_chan(vc);
+
+	/* residue from the on-flight chunk */
+	if (mc->md && mc->md->vd.tx.cookie == cookie) {
+		struct scatterlist *sg;
+		u32 done;
+
+		md = mc->md;
+		sg = &md->sgl[md->sg_cur];
+
+		if (md->dir == DMA_DEV_TO_MEM)
+			done = readl_relaxed(mc->reg_ch_base
+					     + MLB_HDMAC_DMACDA);
+		else
+			done = readl_relaxed(mc->reg_ch_base
+					     + MLB_HDMAC_DMACSA);
+		done -= sg_dma_address(sg);
+
+		txstate->residue = -done;
+	}
+
+	if (!md) {
+		vd = vchan_find_desc(vc, cookie);
+		if (vd)
+			md = to_milbeaut_hdmac_desc(vd);
+	}
+
+	if (md) {
+		/* residue from the queued chunks */
+		for (i = md->sg_cur; i < md->sg_len; i++)
+			txstate->residue += sg_dma_len(&md->sgl[i]);
+	}
+
+	spin_unlock_irqrestore(&vc->lock, flags);
+
+	return stat;
+}
+
+static void milbeaut_hdmac_issue_pending(struct dma_chan *chan)
+{
+	struct virt_dma_chan *vc = to_virt_chan(chan);
+	struct milbeaut_hdmac_chan *mc = to_milbeaut_hdmac_chan(vc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&vc->lock, flags);
+
+	if (vchan_issue_pending(vc) && !mc->md)
+		milbeaut_hdmac_start(mc);
+
+	spin_unlock_irqrestore(&vc->lock, flags);
+}
+
+static void milbeaut_hdmac_desc_free(struct virt_dma_desc *vd)
+{
+	kfree(to_milbeaut_hdmac_desc(vd));
+}
+
+static struct dma_chan *
+milbeaut_hdmac_xlate(struct of_phandle_args *dma_spec, struct of_dma *of_dma)
+{
+	struct milbeaut_hdmac_device *mdev = of_dma->of_dma_data;
+	struct milbeaut_hdmac_chan *mc;
+	struct virt_dma_chan *vc;
+	struct dma_chan *chan;
+
+	if (dma_spec->args_count != 1)
+		return NULL;
+
+	chan = dma_get_any_slave_channel(&mdev->ddev);
+	if (!chan)
+		return NULL;
+
+	vc = to_virt_chan(chan);
+	mc = to_milbeaut_hdmac_chan(vc);
+	mc->slave_id = dma_spec->args[0];
+
+	return chan;
+}
+
+static int milbeaut_hdmac_chan_init(struct platform_device *pdev,
+				    struct milbeaut_hdmac_device *mdev,
+				    int chan_id)
+{
+	struct device *dev = &pdev->dev;
+	struct milbeaut_hdmac_chan *mc = &mdev->channels[chan_id];
+	char *irq_name;
+	int irq, ret;
+
+	irq = platform_get_irq(pdev, chan_id);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "failed to get IRQ number for ch%d\n",
+			chan_id);
+		return irq;
+	}
+
+	irq_name = devm_kasprintf(dev, GFP_KERNEL, "milbeaut-hdmac-%d",
+				  chan_id);
+	if (!irq_name)
+		return -ENOMEM;
+
+	ret = devm_request_irq(dev, irq, milbeaut_hdmac_interrupt,
+			       IRQF_SHARED, irq_name, mc);
+	if (ret)
+		return ret;
+
+	mc->mdev = mdev;
+	mc->reg_ch_base = mdev->reg_base + MLB_HDMAC_CH_STRIDE * (chan_id + 1);
+	mc->vc.desc_free = milbeaut_hdmac_desc_free;
+	vchan_init(&mc->vc, &mdev->ddev);
+
+	return 0;
+}
+
+static int milbeaut_hdmac_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct milbeaut_hdmac_device *mdev;
+	struct dma_device *ddev;
+	struct resource *res;
+	int nr_chans, ret, i;
+
+	nr_chans = platform_irq_count(pdev);
+	if (nr_chans < 0)
+		return nr_chans;
+
+	ret = dma_set_mask(dev, DMA_BIT_MASK(32));
+	if (ret)
+		return ret;
+
+	mdev = devm_kzalloc(dev, struct_size(mdev, channels, nr_chans),
+			    GFP_KERNEL);
+	if (!mdev)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mdev->reg_base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(mdev->reg_base))
+		return PTR_ERR(mdev->reg_base);
+
+	mdev->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(mdev->clk)) {
+		dev_err(dev, "failed to get clock\n");
+		return PTR_ERR(mdev->clk);
+	}
+
+	ret = clk_prepare_enable(mdev->clk);
+	if (ret)
+		return ret;
+
+	ddev = &mdev->ddev;
+	ddev->dev = dev;
+	dma_cap_set(DMA_PRIVATE, ddev->cap_mask);
+	ddev->src_addr_widths = MLB_HDMAC_BUSWIDTHS;
+	ddev->dst_addr_widths = MLB_HDMAC_BUSWIDTHS;
+	ddev->directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM);
+	ddev->device_free_chan_resources = milbeaut_hdmac_free_chan_resources;
+	ddev->device_config = milbeaut_hdmac_chan_config;
+	ddev->device_pause = milbeaut_hdmac_chan_pause;
+	ddev->device_resume = milbeaut_hdmac_chan_resume;
+	ddev->device_prep_slave_sg = milbeaut_hdmac_prep_slave_sg;
+	ddev->device_terminate_all = milbeaut_hdmac_terminate_all;
+	ddev->device_synchronize = milbeaut_hdmac_synchronize;
+	ddev->device_tx_status = milbeaut_hdmac_tx_status;
+	ddev->device_issue_pending = milbeaut_hdmac_issue_pending;
+	INIT_LIST_HEAD(&ddev->channels);
+
+	for (i = 0; i < nr_chans; i++) {
+		ret = milbeaut_hdmac_chan_init(pdev, mdev, i);
+		if (ret)
+			goto disable_clk;
+	}
+
+	ret = dma_async_device_register(ddev);
+	if (ret)
+		goto disable_clk;
+
+	ret = of_dma_controller_register(dev->of_node,
+					 milbeaut_hdmac_xlate, mdev);
+	if (ret)
+		goto unregister_dmac;
+
+	platform_set_drvdata(pdev, mdev);
+
+	return 0;
+
+unregister_dmac:
+	dma_async_device_unregister(ddev);
+disable_clk:
+	clk_disable_unprepare(mdev->clk);
+
+	return ret;
+}
+
+static int milbeaut_hdmac_remove(struct platform_device *pdev)
+{
+	struct milbeaut_hdmac_device *mdev = platform_get_drvdata(pdev);
+	struct dma_chan *chan;
+	int ret;
+
+	/*
+	 * Before reaching here, almost all descriptors have been freed by the
+	 * ->device_free_chan_resources() hook. However, each channel might
+	 * be still holding one descriptor that was on-flight at that moment.
+	 * Terminate it to make sure this hardware is no longer running. Then,
+	 * free the channel resources once again to avoid memory leak.
+	 */
+	list_for_each_entry(chan, &mdev->ddev.channels, device_node) {
+		ret = dmaengine_terminate_sync(chan);
+		if (ret)
+			return ret;
+		milbeaut_hdmac_free_chan_resources(chan);
+	}
+
+	of_dma_controller_free(pdev->dev.of_node);
+	dma_async_device_unregister(&mdev->ddev);
+	clk_disable_unprepare(mdev->clk);
+
+	return 0;
+}
+
+static const struct of_device_id milbeaut_hdmac_match[] = {
+	{ .compatible = "socionext,milbeaut-m10v-hdmac" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, milbeaut_hdmac_match);
+
+static struct platform_driver milbeaut_hdmac_driver = {
+	.probe = milbeaut_hdmac_probe,
+	.remove = milbeaut_hdmac_remove,
+	.driver = {
+		.name = "milbeaut-m10v-hdmac",
+		.of_match_table = milbeaut_hdmac_match,
+	},
+};
+module_platform_driver(milbeaut_hdmac_driver);
+
+MODULE_DESCRIPTION("Milbeaut HDMAC DmaEngine driver");
+MODULE_LICENSE("GPL v2");
-- 
2.17.1


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

* Re: [PATCH 2/2] dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms
  2019-06-13  0:52 ` [PATCH 2/2] dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms jassisinghbrar
@ 2019-06-24  6:44   ` Vinod Koul
  2019-08-16  2:25     ` Jassi Brar
  0 siblings, 1 reply; 17+ messages in thread
From: Vinod Koul @ 2019-06-24  6:44 UTC (permalink / raw)
  To: jassisinghbrar
  Cc: dmaengine, devicetree, linux-kernel, robh+dt, mark.rutland,
	orito.takao, masami.hiramatsu, kasai.kazuhiro, Jassi Brar

On 12-06-19, 19:52, jassisinghbrar@gmail.com wrote:

> +#include <linux/bits.h>
> +#include <linux/clk.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/dmaengine.h>
> +#include <linux/interrupt.h>
> +#include <linux/iopoll.h>
> +#include <linux/list.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_dma.h>

Do we need both, IIRC of_dma.h does include of.h!

> +/* mc->vc.lock must be held by caller */
> +static void milbeaut_chan_start(struct milbeaut_hdmac_chan *mc,
> +				struct milbeaut_hdmac_desc *md)
> +{
> +	struct scatterlist *sg;
> +	u32  cb, ca, src_addr, dest_addr, len;
           ^^
double space

> +static irqreturn_t milbeaut_hdmac_interrupt(int irq, void *dev_id)
> +{
> +	struct milbeaut_hdmac_chan *mc = dev_id;
> +	struct milbeaut_hdmac_desc *md;
> +	irqreturn_t ret = IRQ_HANDLED;
> +	u32 val;
> +
> +	spin_lock(&mc->vc.lock);
> +
> +	/* Ack and Disable irqs */
> +	val = readl_relaxed(mc->reg_ch_base + MLB_HDMAC_DMACB);
> +	val &= ~(FIELD_PREP(MLB_HDMAC_SS, 0x7));
                                         ^^^^
Magic ..?

> +static int milbeaut_hdmac_chan_pause(struct dma_chan *chan)
> +{
> +	struct virt_dma_chan *vc = to_virt_chan(chan);
> +	struct milbeaut_hdmac_chan *mc = to_milbeaut_hdmac_chan(vc);
> +	u32 val;
> +
> +	spin_lock(&mc->vc.lock);
> +	val = readl_relaxed(mc->reg_ch_base + MLB_HDMAC_DMACA);
> +	val |= MLB_HDMAC_PB;
> +	writel_relaxed(val, mc->reg_ch_base + MLB_HDMAC_DMACA);

We really should have an updatel() and friends in kernel, feel free to
add in your driver though!

> +static int milbeaut_hdmac_chan_init(struct platform_device *pdev,
> +				    struct milbeaut_hdmac_device *mdev,
> +				    int chan_id)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct milbeaut_hdmac_chan *mc = &mdev->channels[chan_id];
> +	char *irq_name;
> +	int irq, ret;
> +
> +	irq = platform_get_irq(pdev, chan_id);
> +	if (irq < 0) {
> +		dev_err(&pdev->dev, "failed to get IRQ number for ch%d\n",
> +			chan_id);
> +		return irq;
> +	}
> +
> +	irq_name = devm_kasprintf(dev, GFP_KERNEL, "milbeaut-hdmac-%d",
> +				  chan_id);
> +	if (!irq_name)
> +		return -ENOMEM;
> +
> +	ret = devm_request_irq(dev, irq, milbeaut_hdmac_interrupt,
> +			       IRQF_SHARED, irq_name, mc);

I tend to dislike using devm_request_irq(), we have no control over when
the irq is freed and what is a spirious irq is running while we are
unrolling, so IMHO it make sense to free up and ensure all tasklets are
quiesced when remove returns

> +	if (ret)
> +		return ret;
> +
> +	mc->mdev = mdev;
> +	mc->reg_ch_base = mdev->reg_base + MLB_HDMAC_CH_STRIDE * (chan_id + 1);
> +	mc->vc.desc_free = milbeaut_hdmac_desc_free;
> +	vchan_init(&mc->vc, &mdev->ddev);

who kills the vc->task?

> +static int milbeaut_hdmac_remove(struct platform_device *pdev)
> +{
> +	struct milbeaut_hdmac_device *mdev = platform_get_drvdata(pdev);
> +	struct dma_chan *chan;
> +	int ret;
> +
> +	/*
> +	 * Before reaching here, almost all descriptors have been freed by the
> +	 * ->device_free_chan_resources() hook. However, each channel might
> +	 * be still holding one descriptor that was on-flight at that moment.
> +	 * Terminate it to make sure this hardware is no longer running. Then,
> +	 * free the channel resources once again to avoid memory leak.
> +	 */
> +	list_for_each_entry(chan, &mdev->ddev.channels, device_node) {
> +		ret = dmaengine_terminate_sync(chan);
> +		if (ret)
> +			return ret;
> +		milbeaut_hdmac_free_chan_resources(chan);
> +	}
> +
> +	of_dma_controller_free(pdev->dev.of_node);
> +	dma_async_device_unregister(&mdev->ddev);
> +	clk_disable_unprepare(mdev->clk);

And as suspected we have active tasklets and irq at this time :(
-- 
~Vinod

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

* Re: [PATCH 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings
  2019-06-13  0:52 ` [PATCH 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings jassisinghbrar
@ 2019-07-09 14:34   ` Rob Herring
  2019-07-10  4:12     ` Jassi Brar
  0 siblings, 1 reply; 17+ messages in thread
From: Rob Herring @ 2019-07-09 14:34 UTC (permalink / raw)
  To: jassisinghbrar
  Cc: dmaengine, devicetree, linux-kernel, vkoul, mark.rutland,
	orito.takao, masami.hiramatsu, kasai.kazuhiro, Jassi Brar

On Wed, Jun 12, 2019 at 07:52:37PM -0500, jassisinghbrar@gmail.com wrote:
> From: Jassi Brar <jaswinder.singh@linaro.org>
> 
> Document the devicetree bindings for Socionext Milbeaut HDMAC
> controller. Controller has upto 8 floating channels, that need
> a predefined slave-id to work from a set of slaves.
> 
> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> ---
>  .../bindings/dma/milbeaut-m10v-hdmac.txt           | 54 +++++++++++++++++++
>  1 file changed, 54 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> 
> diff --git a/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> new file mode 100644
> index 000000000000..a104fcb9e73d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> @@ -0,0 +1,51 @@
> +* Milbeaut AHB DMA Controller
> +
> +Milbeaut AHB DMA controller has transfer capability bellow.
> + - memory to memory transfer
> + - device to memory transfer
> + - memory to device transfer
> +
> +Required property:
> +- compatible:       Should be  "socionext,milbeaut-m10v-hdmac"
> +- reg:              Should contain DMA registers location and length.
> +- interrupts:       Should contain all of the per-channel DMA interrupts.

How many?

> +- #dma-cells:       Should be 1. Specify the ID of the slave.
> +- clocks:           Phandle to the clock used by the HDMAC module.
> +
> +
> +Example:
> +
> +	hdmac1: hdmac@1e110000 {

dma-controller@...

> +		compatible = "socionext,milbeaut-m10v-hdmac";
> +		reg = <0x1e110000 0x10000>;
> +		interrupts = <0 132 4>,
> +			     <0 133 4>,
> +			     <0 134 4>,
> +			     <0 135 4>,
> +			     <0 136 4>,
> +			     <0 137 4>,
> +			     <0 138 4>,
> +			     <0 139 4>;
> +		#dma-cells = <1>;
> +		clocks = <&dummy_clk>;
> +	};
> +
> +* DMA client
> +
> +Clients have to specify the DMA requests with phandles in a list.

Nothing specific to this binding here and the client side is already 
documented, so drop this section.

> +
> +Required properties:
> +- dmas:             List of one or more DMA request specifiers. One DMA request specifier
> +                    consists of a phandle to the DMA controller followed by the integer
> +                    specifying the request line.
> +- dma-names:        List of string identifiers for the DMA requests. For the correct
> +                    names, have a look at the specific client driver.
> +
> +Example:
> +
> +	sni_spi1: spi@1e800100 {
> +		...
> +		dmas = <&hdmac1 22>, <&hdmac1 21>;
> +		dma-names = "tx", "rx";
> +		...
> +	};
> -- 
> 2.17.1
> 

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

* Re: [PATCH 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings
  2019-07-09 14:34   ` Rob Herring
@ 2019-07-10  4:12     ` Jassi Brar
  2019-07-10 13:48         ` Rob Herring
  0 siblings, 1 reply; 17+ messages in thread
From: Jassi Brar @ 2019-07-10  4:12 UTC (permalink / raw)
  To: Rob Herring
  Cc: dmaengine, Devicetree List, Linux Kernel Mailing List, vkoul,
	Mark Rutland, orito.takao, Masami Hiramatsu, kasai.kazuhiro,
	Jassi Brar

On Tue, Jul 9, 2019 at 9:34 AM Rob Herring <robh@kernel.org> wrote:
>
> On Wed, Jun 12, 2019 at 07:52:37PM -0500, jassisinghbrar@gmail.com wrote:
> > From: Jassi Brar <jaswinder.singh@linaro.org>
> >
> > Document the devicetree bindings for Socionext Milbeaut HDMAC
> > controller. Controller has upto 8 floating channels, that need
> > a predefined slave-id to work from a set of slaves.
> >
> > Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> > ---
> >  .../bindings/dma/milbeaut-m10v-hdmac.txt           | 54 +++++++++++++++++++
> >  1 file changed, 54 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> >
> > diff --git a/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> > new file mode 100644
> > index 000000000000..a104fcb9e73d
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> > @@ -0,0 +1,51 @@
> > +* Milbeaut AHB DMA Controller
> > +
> > +Milbeaut AHB DMA controller has transfer capability bellow.
> > + - memory to memory transfer
> > + - device to memory transfer
> > + - memory to device transfer
> > +
> > +Required property:
> > +- compatible:       Should be  "socionext,milbeaut-m10v-hdmac"
> > +- reg:              Should contain DMA registers location and length.
> > +- interrupts:       Should contain all of the per-channel DMA interrupts.
>
> How many?
>
Each channel has an IRQ line. And the number of channels is
configurable. So instead of having some explicit property like
'dma-channels', we infer that from the number of irqs registered.

> > +- #dma-cells:       Should be 1. Specify the ID of the slave.
> > +- clocks:           Phandle to the clock used by the HDMAC module.
> > +
> > +
> > +Example:
> > +
> > +     hdmac1: hdmac@1e110000 {
>
> dma-controller@...
>
OK

> > +             compatible = "socionext,milbeaut-m10v-hdmac";
> > +             reg = <0x1e110000 0x10000>;
> > +             interrupts = <0 132 4>,
> > +                          <0 133 4>,
> > +                          <0 134 4>,
> > +                          <0 135 4>,
> > +                          <0 136 4>,
> > +                          <0 137 4>,
> > +                          <0 138 4>,
> > +                          <0 139 4>;
> > +             #dma-cells = <1>;
> > +             clocks = <&dummy_clk>;
> > +     };
> > +
> > +* DMA client
> > +
> > +Clients have to specify the DMA requests with phandles in a list.
>
> Nothing specific to this binding here and the client side is already
> documented, so drop this section.
>
OK.

Thanks

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

* Re: [PATCH 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings
  2019-07-10  4:12     ` Jassi Brar
@ 2019-07-10 13:48         ` Rob Herring
  0 siblings, 0 replies; 17+ messages in thread
From: Rob Herring @ 2019-07-10 13:48 UTC (permalink / raw)
  To: Jassi Brar
  Cc: open list:DMA GENERIC OFFLOAD ENGINE SUBSYSTEM, Devicetree List,
	Linux Kernel Mailing List, Vinod, Mark Rutland, Takao Orito,
	Masami Hiramatsu, Kazuhiro Kasai, Jassi Brar

On Tue, Jul 9, 2019 at 10:12 PM Jassi Brar <jassisinghbrar@gmail.com> wrote:
>
> On Tue, Jul 9, 2019 at 9:34 AM Rob Herring <robh@kernel.org> wrote:
> >
> > On Wed, Jun 12, 2019 at 07:52:37PM -0500, jassisinghbrar@gmail.com wrote:
> > > From: Jassi Brar <jaswinder.singh@linaro.org>
> > >
> > > Document the devicetree bindings for Socionext Milbeaut HDMAC
> > > controller. Controller has upto 8 floating channels, that need
> > > a predefined slave-id to work from a set of slaves.
> > >
> > > Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> > > ---
> > >  .../bindings/dma/milbeaut-m10v-hdmac.txt           | 54 +++++++++++++++++++
> > >  1 file changed, 54 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> > >
> > > diff --git a/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> > > new file mode 100644
> > > index 000000000000..a104fcb9e73d
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> > > @@ -0,0 +1,51 @@
> > > +* Milbeaut AHB DMA Controller
> > > +
> > > +Milbeaut AHB DMA controller has transfer capability bellow.
> > > + - memory to memory transfer
> > > + - device to memory transfer
> > > + - memory to device transfer
> > > +
> > > +Required property:
> > > +- compatible:       Should be  "socionext,milbeaut-m10v-hdmac"
> > > +- reg:              Should contain DMA registers location and length.
> > > +- interrupts:       Should contain all of the per-channel DMA interrupts.
> >
> > How many?
> >
> Each channel has an IRQ line. And the number of channels is
> configurable. So instead of having some explicit property like
> 'dma-channels', we infer that from the number of irqs registered.

Yes, I get that. There's still a range that's valid and you need to
define those constraints. If there's a variable number of channels,
then that implies different SoCs which should also mean different
compatible strings.

Rob

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

* Re: [PATCH 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings
@ 2019-07-10 13:48         ` Rob Herring
  0 siblings, 0 replies; 17+ messages in thread
From: Rob Herring @ 2019-07-10 13:48 UTC (permalink / raw)
  To: Jassi Brar
  Cc: open list:DMA GENERIC OFFLOAD ENGINE SUBSYSTEM, Devicetree List,
	Linux Kernel Mailing List, Vinod, Mark Rutland, Takao Orito,
	Masami Hiramatsu, Kazuhiro Kasai, Jassi Brar

On Tue, Jul 9, 2019 at 10:12 PM Jassi Brar <jassisinghbrar@gmail.com> wrote:
>
> On Tue, Jul 9, 2019 at 9:34 AM Rob Herring <robh@kernel.org> wrote:
> >
> > On Wed, Jun 12, 2019 at 07:52:37PM -0500, jassisinghbrar@gmail.com wrote:
> > > From: Jassi Brar <jaswinder.singh@linaro.org>
> > >
> > > Document the devicetree bindings for Socionext Milbeaut HDMAC
> > > controller. Controller has upto 8 floating channels, that need
> > > a predefined slave-id to work from a set of slaves.
> > >
> > > Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> > > ---
> > >  .../bindings/dma/milbeaut-m10v-hdmac.txt           | 54 +++++++++++++++++++
> > >  1 file changed, 54 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> > >
> > > diff --git a/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> > > new file mode 100644
> > > index 000000000000..a104fcb9e73d
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> > > @@ -0,0 +1,51 @@
> > > +* Milbeaut AHB DMA Controller
> > > +
> > > +Milbeaut AHB DMA controller has transfer capability bellow.
> > > + - memory to memory transfer
> > > + - device to memory transfer
> > > + - memory to device transfer
> > > +
> > > +Required property:
> > > +- compatible:       Should be  "socionext,milbeaut-m10v-hdmac"
> > > +- reg:              Should contain DMA registers location and length.
> > > +- interrupts:       Should contain all of the per-channel DMA interrupts.
> >
> > How many?
> >
> Each channel has an IRQ line. And the number of channels is
> configurable. So instead of having some explicit property like
> 'dma-channels', we infer that from the number of irqs registered.

Yes, I get that. There's still a range that's valid and you need to
define those constraints. If there's a variable number of channels,
then that implies different SoCs which should also mean different
compatible strings.

Rob

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

* Re: [PATCH 2/2] dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms
  2019-06-24  6:44   ` Vinod Koul
@ 2019-08-16  2:25     ` Jassi Brar
  2019-08-16  4:43       ` Vinod Koul
  0 siblings, 1 reply; 17+ messages in thread
From: Jassi Brar @ 2019-08-16  2:25 UTC (permalink / raw)
  To: Vinod Koul
  Cc: dmaengine, Devicetree List, Linux Kernel Mailing List,
	Rob Herring, Mark Rutland, orito.takao, Masami Hiramatsu,
	kasai.kazuhiro, Jassi Brar

On Mon, Jun 24, 2019 at 1:47 AM Vinod Koul <vkoul@kernel.org> wrote:
>
> On 12-06-19, 19:52, jassisinghbrar@gmail.com wrote:
>
> > +#include <linux/bits.h>
> > +#include <linux/clk.h>
> > +#include <linux/dma-mapping.h>
> > +#include <linux/dmaengine.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/iopoll.h>
> > +#include <linux/list.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_dma.h>
>
> Do we need both, IIRC of_dma.h does include of.h!
>
OK

> > +/* mc->vc.lock must be held by caller */
> > +static void milbeaut_chan_start(struct milbeaut_hdmac_chan *mc,
> > +                             struct milbeaut_hdmac_desc *md)
> > +{
> > +     struct scatterlist *sg;
> > +     u32  cb, ca, src_addr, dest_addr, len;
>            ^^
> double space
>
OK

> > +static irqreturn_t milbeaut_hdmac_interrupt(int irq, void *dev_id)
> > +{
> > +     struct milbeaut_hdmac_chan *mc = dev_id;
> > +     struct milbeaut_hdmac_desc *md;
> > +     irqreturn_t ret = IRQ_HANDLED;
> > +     u32 val;
> > +
> > +     spin_lock(&mc->vc.lock);
> > +
> > +     /* Ack and Disable irqs */
> > +     val = readl_relaxed(mc->reg_ch_base + MLB_HDMAC_DMACB);
> > +     val &= ~(FIELD_PREP(MLB_HDMAC_SS, 0x7));
>                                          ^^^^
> Magic ..?
>
OK, will define a macro for 7

> > +static int milbeaut_hdmac_chan_pause(struct dma_chan *chan)
> > +{
> > +     struct virt_dma_chan *vc = to_virt_chan(chan);
> > +     struct milbeaut_hdmac_chan *mc = to_milbeaut_hdmac_chan(vc);
> > +     u32 val;
> > +
> > +     spin_lock(&mc->vc.lock);
> > +     val = readl_relaxed(mc->reg_ch_base + MLB_HDMAC_DMACA);
> > +     val |= MLB_HDMAC_PB;
> > +     writel_relaxed(val, mc->reg_ch_base + MLB_HDMAC_DMACA);
>
> We really should have an updatel() and friends in kernel, feel free to
> add in your driver though!
>
I'll pass on that for now.

> > +static int milbeaut_hdmac_chan_init(struct platform_device *pdev,
> > +                                 struct milbeaut_hdmac_device *mdev,
> > +                                 int chan_id)
> > +{
> > +     struct device *dev = &pdev->dev;
> > +     struct milbeaut_hdmac_chan *mc = &mdev->channels[chan_id];
> > +     char *irq_name;
> > +     int irq, ret;
> > +
> > +     irq = platform_get_irq(pdev, chan_id);
> > +     if (irq < 0) {
> > +             dev_err(&pdev->dev, "failed to get IRQ number for ch%d\n",
> > +                     chan_id);
> > +             return irq;
> > +     }
> > +
> > +     irq_name = devm_kasprintf(dev, GFP_KERNEL, "milbeaut-hdmac-%d",
> > +                               chan_id);
> > +     if (!irq_name)
> > +             return -ENOMEM;
> > +
> > +     ret = devm_request_irq(dev, irq, milbeaut_hdmac_interrupt,
> > +                            IRQF_SHARED, irq_name, mc);
>
> I tend to dislike using devm_request_irq(), we have no control over when
> the irq is freed and what is a spirious irq is running while we are
> unrolling, so IMHO it make sense to free up and ensure all tasklets are
> quiesced when remove returns
>
If the code is written clean and tight we need not be so paranoid.

> > +     if (ret)
> > +             return ret;
> > +
> > +     mc->mdev = mdev;
> > +     mc->reg_ch_base = mdev->reg_base + MLB_HDMAC_CH_STRIDE * (chan_id + 1);
> > +     mc->vc.desc_free = milbeaut_hdmac_desc_free;
> > +     vchan_init(&mc->vc, &mdev->ddev);
>
> who kills the vc->task?
>
vchan_synchronize() called from milbeaut_hdmac_synchronize()

> > +static int milbeaut_hdmac_remove(struct platform_device *pdev)
> > +{
> > +     struct milbeaut_hdmac_device *mdev = platform_get_drvdata(pdev);
> > +     struct dma_chan *chan;
> > +     int ret;
> > +
> > +     /*
> > +      * Before reaching here, almost all descriptors have been freed by the
> > +      * ->device_free_chan_resources() hook. However, each channel might
> > +      * be still holding one descriptor that was on-flight at that moment.
> > +      * Terminate it to make sure this hardware is no longer running. Then,
> > +      * free the channel resources once again to avoid memory leak.
> > +      */
> > +     list_for_each_entry(chan, &mdev->ddev.channels, device_node) {
> > +             ret = dmaengine_terminate_sync(chan);
> > +             if (ret)
> > +                     return ret;
> > +             milbeaut_hdmac_free_chan_resources(chan);
> > +     }
> > +
> > +     of_dma_controller_free(pdev->dev.of_node);
> > +     dma_async_device_unregister(&mdev->ddev);
> > +     clk_disable_unprepare(mdev->clk);
>
> And as suspected we have active tasklets and irq at this time :(
>
Not sure how is that....

thanks.

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

* Re: [PATCH 2/2] dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms
  2019-08-16  2:25     ` Jassi Brar
@ 2019-08-16  4:43       ` Vinod Koul
  0 siblings, 0 replies; 17+ messages in thread
From: Vinod Koul @ 2019-08-16  4:43 UTC (permalink / raw)
  To: Jassi Brar
  Cc: dmaengine, Devicetree List, Linux Kernel Mailing List,
	Rob Herring, Mark Rutland, orito.takao, Masami Hiramatsu,
	kasai.kazuhiro, Jassi Brar

On 15-08-19, 21:25, Jassi Brar wrote:
> On Mon, Jun 24, 2019 at 1:47 AM Vinod Koul <vkoul@kernel.org> wrote:
> >
> > On 12-06-19, 19:52, jassisinghbrar@gmail.com wrote:
> >
> > > +#include <linux/bits.h>
> > > +#include <linux/clk.h>
> > > +#include <linux/dma-mapping.h>
> > > +#include <linux/dmaengine.h>
> > > +#include <linux/interrupt.h>
> > > +#include <linux/iopoll.h>
> > > +#include <linux/list.h>
> > > +#include <linux/module.h>
> > > +#include <linux/of.h>
> > > +#include <linux/of_dma.h>
> >
> > Do we need both, IIRC of_dma.h does include of.h!
> >
> OK
> 
> > > +/* mc->vc.lock must be held by caller */
> > > +static void milbeaut_chan_start(struct milbeaut_hdmac_chan *mc,
> > > +                             struct milbeaut_hdmac_desc *md)
> > > +{
> > > +     struct scatterlist *sg;
> > > +     u32  cb, ca, src_addr, dest_addr, len;
> >            ^^
> > double space
> >
> OK
> 
> > > +static irqreturn_t milbeaut_hdmac_interrupt(int irq, void *dev_id)
> > > +{
> > > +     struct milbeaut_hdmac_chan *mc = dev_id;
> > > +     struct milbeaut_hdmac_desc *md;
> > > +     irqreturn_t ret = IRQ_HANDLED;
> > > +     u32 val;
> > > +
> > > +     spin_lock(&mc->vc.lock);
> > > +
> > > +     /* Ack and Disable irqs */
> > > +     val = readl_relaxed(mc->reg_ch_base + MLB_HDMAC_DMACB);
> > > +     val &= ~(FIELD_PREP(MLB_HDMAC_SS, 0x7));
> >                                          ^^^^
> > Magic ..?
> >
> OK, will define a macro for 7
> 
> > > +static int milbeaut_hdmac_chan_pause(struct dma_chan *chan)
> > > +{
> > > +     struct virt_dma_chan *vc = to_virt_chan(chan);
> > > +     struct milbeaut_hdmac_chan *mc = to_milbeaut_hdmac_chan(vc);
> > > +     u32 val;
> > > +
> > > +     spin_lock(&mc->vc.lock);
> > > +     val = readl_relaxed(mc->reg_ch_base + MLB_HDMAC_DMACA);
> > > +     val |= MLB_HDMAC_PB;
> > > +     writel_relaxed(val, mc->reg_ch_base + MLB_HDMAC_DMACA);
> >
> > We really should have an updatel() and friends in kernel, feel free to
> > add in your driver though!
> >
> I'll pass on that for now.
> 
> > > +static int milbeaut_hdmac_chan_init(struct platform_device *pdev,
> > > +                                 struct milbeaut_hdmac_device *mdev,
> > > +                                 int chan_id)
> > > +{
> > > +     struct device *dev = &pdev->dev;
> > > +     struct milbeaut_hdmac_chan *mc = &mdev->channels[chan_id];
> > > +     char *irq_name;
> > > +     int irq, ret;
> > > +
> > > +     irq = platform_get_irq(pdev, chan_id);
> > > +     if (irq < 0) {
> > > +             dev_err(&pdev->dev, "failed to get IRQ number for ch%d\n",
> > > +                     chan_id);
> > > +             return irq;
> > > +     }
> > > +
> > > +     irq_name = devm_kasprintf(dev, GFP_KERNEL, "milbeaut-hdmac-%d",
> > > +                               chan_id);
> > > +     if (!irq_name)
> > > +             return -ENOMEM;
> > > +
> > > +     ret = devm_request_irq(dev, irq, milbeaut_hdmac_interrupt,
> > > +                            IRQF_SHARED, irq_name, mc);
> >
> > I tend to dislike using devm_request_irq(), we have no control over when
> > the irq is freed and what is a spirious irq is running while we are
> > unrolling, so IMHO it make sense to free up and ensure all tasklets are
> > quiesced when remove returns
> >
> If the code is written clean and tight we need not be so paranoid.
> 
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     mc->mdev = mdev;
> > > +     mc->reg_ch_base = mdev->reg_base + MLB_HDMAC_CH_STRIDE * (chan_id + 1);
> > > +     mc->vc.desc_free = milbeaut_hdmac_desc_free;
> > > +     vchan_init(&mc->vc, &mdev->ddev);
> >
> > who kills the vc->task?
> >
> vchan_synchronize() called from milbeaut_hdmac_synchronize()

But that can be skipped by called, from driver pov we need to ensure
that it is killed

> > > +static int milbeaut_hdmac_remove(struct platform_device *pdev)
> > > +{
> > > +     struct milbeaut_hdmac_device *mdev = platform_get_drvdata(pdev);
> > > +     struct dma_chan *chan;
> > > +     int ret;
> > > +
> > > +     /*
> > > +      * Before reaching here, almost all descriptors have been freed by the
> > > +      * ->device_free_chan_resources() hook. However, each channel might
> > > +      * be still holding one descriptor that was on-flight at that moment.
> > > +      * Terminate it to make sure this hardware is no longer running. Then,
> > > +      * free the channel resources once again to avoid memory leak.
> > > +      */
> > > +     list_for_each_entry(chan, &mdev->ddev.channels, device_node) {
> > > +             ret = dmaengine_terminate_sync(chan);
> > > +             if (ret)
> > > +                     return ret;
> > > +             milbeaut_hdmac_free_chan_resources(chan);
> > > +     }
> > > +
> > > +     of_dma_controller_free(pdev->dev.of_node);
> > > +     dma_async_device_unregister(&mdev->ddev);
> > > +     clk_disable_unprepare(mdev->clk);
> >
> > And as suspected we have active tasklets and irq at this time :(
> >
> Not sure how is that....

Since you use devm variants, and driver tasklet is not killed, irq can
be fired (spurious as well) and can run irq and schedule a tasklet. How
do you prevent that?

Thanks
-- 
~Vinod

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

* [PATCH v2 0/2] Add support for AHB DMA controller on Milbeaut series
  2019-06-13  0:51 [PATCH 0/2] Add support for AHB DMA controller on Milbeaut series jassisinghbrar
  2019-06-13  0:52 ` [PATCH 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings jassisinghbrar
  2019-06-13  0:52 ` [PATCH 2/2] dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms jassisinghbrar
@ 2019-08-18  5:16 ` jassisinghbrar
  2019-08-18  5:17   ` [PATCH v2 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings jassisinghbrar
  2019-08-18  5:18   ` [PATCH v2 2/2] dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms jassisinghbrar
  2 siblings, 2 replies; 17+ messages in thread
From: jassisinghbrar @ 2019-08-18  5:16 UTC (permalink / raw)
  To: dmaengine, devicetree, linux-kernel; +Cc: vkoul, robh+dt, Jassi Brar

From: Jassi Brar <jaswinder.singh@linaro.org>

Changes since v1:
1) Drop uncessary headers from driver
2) Some Cosmetic changes.
3) Define macro for magic numbers
4) Specify constraints on number of channels/irq in DT bindings

Jassi Brar (2):
  dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC
    bindings
  dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms

 .../bindings/dma/milbeaut-m10v-hdmac.txt      |  32 +
 drivers/dma/Kconfig                           |  10 +
 drivers/dma/Makefile                          |   1 +
 drivers/dma/milbeaut-hdmac.c                  | 571 ++++++++++++++++++
 4 files changed, 614 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
 create mode 100644 drivers/dma/milbeaut-hdmac.c

-- 
2.17.1


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

* [PATCH v2 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings
  2019-08-18  5:16 ` [PATCH v2 0/2] Add support for AHB DMA controller on Milbeaut series jassisinghbrar
@ 2019-08-18  5:17   ` jassisinghbrar
  2019-08-27 16:31     ` Rob Herring
  2019-09-04  5:50     ` Vinod Koul
  2019-08-18  5:18   ` [PATCH v2 2/2] dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms jassisinghbrar
  1 sibling, 2 replies; 17+ messages in thread
From: jassisinghbrar @ 2019-08-18  5:17 UTC (permalink / raw)
  To: dmaengine, devicetree, linux-kernel; +Cc: vkoul, robh+dt, Jassi Brar

From: Jassi Brar <jaswinder.singh@linaro.org>

Document the devicetree bindings for Socionext Milbeaut HDMAC
controller. Controller has upto 8 floating channels, that need
a predefined slave-id to work from a set of slaves.

Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
---
 .../bindings/dma/milbeaut-m10v-hdmac.txt      | 32 +++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt

diff --git a/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
new file mode 100644
index 000000000000..f0960724f1c7
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
@@ -0,0 +1,32 @@
+* Milbeaut AHB DMA Controller
+
+Milbeaut AHB DMA controller has transfer capability bellow.
+ - device to memory transfer
+ - memory to device transfer
+
+Required property:
+- compatible:       Should be  "socionext,milbeaut-m10v-hdmac"
+- reg:              Should contain DMA registers location and length.
+- interrupts:       Should contain all of the per-channel DMA interrupts.
+                     Number of channels is configurable - 2, 4 or 8, so
+                     the number of interrupts specfied should be {2,4,8}.
+- #dma-cells:       Should be 1. Specify the ID of the slave.
+- clocks:           Phandle to the clock used by the HDMAC module.
+
+
+Example:
+
+	hdmac1: dma-controller@1e110000 {
+		compatible = "socionext,milbeaut-m10v-hdmac";
+		reg = <0x1e110000 0x10000>;
+		interrupts = <0 132 4>,
+			     <0 133 4>,
+			     <0 134 4>,
+			     <0 135 4>,
+			     <0 136 4>,
+			     <0 137 4>,
+			     <0 138 4>,
+			     <0 139 4>;
+		#dma-cells = <1>;
+		clocks = <&dummy_clk>;
+	};
-- 
2.17.1


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

* [PATCH v2 2/2] dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms
  2019-08-18  5:16 ` [PATCH v2 0/2] Add support for AHB DMA controller on Milbeaut series jassisinghbrar
  2019-08-18  5:17   ` [PATCH v2 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings jassisinghbrar
@ 2019-08-18  5:18   ` jassisinghbrar
  1 sibling, 0 replies; 17+ messages in thread
From: jassisinghbrar @ 2019-08-18  5:18 UTC (permalink / raw)
  To: dmaengine, devicetree, linux-kernel; +Cc: vkoul, robh+dt, Jassi Brar

From: Jassi Brar <jaswinder.singh@linaro.org>

Driver for Socionext Milbeaut HDMAC controller. The controller has
upto 8 floating channels, that need a predefined slave-id to work
from a set of slaves.

Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
---
 drivers/dma/Kconfig          |  10 +
 drivers/dma/Makefile         |   1 +
 drivers/dma/milbeaut-hdmac.c | 571 +++++++++++++++++++++++++++++++++++
 3 files changed, 582 insertions(+)
 create mode 100644 drivers/dma/milbeaut-hdmac.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 03fa0c58cef3..66979f27f0f3 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -348,6 +348,16 @@ config MCF_EDMA
 	  minimal intervention from a host processor.
 	  This module can be found on Freescale ColdFire mcf5441x SoCs.
 
+config MILBEAUT_HDMAC
+	tristate "Milbeaut AHB DMA support"
+	depends on ARCH_MILBEAUT || COMPILE_TEST
+	depends on OF
+	select DMA_ENGINE
+	select DMA_VIRTUAL_CHANNELS
+	help
+	  Say yes here to support the Socionext Milbeaut
+	  HDMAC device.
+
 config MMP_PDMA
 	bool "MMP PDMA support"
 	depends on ARCH_MMP || ARCH_PXA || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 5bddf6f8790f..e4aed0730dea 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
 obj-$(CONFIG_INTEL_MIC_X100_DMA) += mic_x100_dma.o
 obj-$(CONFIG_K3_DMA) += k3dma.o
 obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o
+obj-$(CONFIG_MILBEAUT_HDMAC) += milbeaut-hdmac.o
 obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
 obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
 obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
diff --git a/drivers/dma/milbeaut-hdmac.c b/drivers/dma/milbeaut-hdmac.c
new file mode 100644
index 000000000000..25ba0a692c94
--- /dev/null
+++ b/drivers/dma/milbeaut-hdmac.c
@@ -0,0 +1,571 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2019 Linaro Ltd.
+// Copyright (C) 2019 Socionext Inc.
+
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of_dma.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/bitfield.h>
+
+#include "virt-dma.h"
+
+#define MLB_HDMAC_DMACR		0x0	/* global */
+#define MLB_HDMAC_DE		BIT(31)
+#define MLB_HDMAC_DS		BIT(30)
+#define MLB_HDMAC_PR		BIT(28)
+#define MLB_HDMAC_DH		GENMASK(27, 24)
+
+#define MLB_HDMAC_CH_STRIDE	0x10
+
+#define MLB_HDMAC_DMACA		0x0	/* channel */
+#define MLB_HDMAC_EB		BIT(31)
+#define MLB_HDMAC_PB		BIT(30)
+#define MLB_HDMAC_ST		BIT(29)
+#define MLB_HDMAC_IS		GENMASK(28, 24)
+#define MLB_HDMAC_BT		GENMASK(23, 20)
+#define MLB_HDMAC_BC		GENMASK(19, 16)
+#define MLB_HDMAC_TC		GENMASK(15, 0)
+#define MLB_HDMAC_DMACB		0x4
+#define MLB_HDMAC_TT		GENMASK(31, 30)
+#define MLB_HDMAC_MS		GENMASK(29, 28)
+#define MLB_HDMAC_TW		GENMASK(27, 26)
+#define MLB_HDMAC_FS		BIT(25)
+#define MLB_HDMAC_FD		BIT(24)
+#define MLB_HDMAC_RC		BIT(23)
+#define MLB_HDMAC_RS		BIT(22)
+#define MLB_HDMAC_RD		BIT(21)
+#define MLB_HDMAC_EI		BIT(20)
+#define MLB_HDMAC_CI		BIT(19)
+#define HDMAC_PAUSE		0x7
+#define MLB_HDMAC_SS		GENMASK(18, 16)
+#define MLB_HDMAC_SP		GENMASK(15, 12)
+#define MLB_HDMAC_DP		GENMASK(11, 8)
+#define MLB_HDMAC_DMACSA	0x8
+#define MLB_HDMAC_DMACDA	0xc
+
+#define MLB_HDMAC_BUSWIDTHS		(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
+					BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
+					BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
+
+struct milbeaut_hdmac_desc {
+	struct virt_dma_desc vd;
+	struct scatterlist *sgl;
+	unsigned int sg_len;
+	unsigned int sg_cur;
+	enum dma_transfer_direction dir;
+};
+
+struct milbeaut_hdmac_chan {
+	struct virt_dma_chan vc;
+	struct milbeaut_hdmac_device *mdev;
+	struct milbeaut_hdmac_desc *md;
+	void __iomem *reg_ch_base;
+	unsigned int slave_id;
+	struct dma_slave_config	cfg;
+};
+
+struct milbeaut_hdmac_device {
+	struct dma_device ddev;
+	struct clk *clk;
+	void __iomem *reg_base;
+	struct milbeaut_hdmac_chan channels[0];
+};
+
+static struct milbeaut_hdmac_chan *
+to_milbeaut_hdmac_chan(struct virt_dma_chan *vc)
+{
+	return container_of(vc, struct milbeaut_hdmac_chan, vc);
+}
+
+static struct milbeaut_hdmac_desc *
+to_milbeaut_hdmac_desc(struct virt_dma_desc *vd)
+{
+	return container_of(vd, struct milbeaut_hdmac_desc, vd);
+}
+
+/* mc->vc.lock must be held by caller */
+static struct milbeaut_hdmac_desc *
+milbeaut_hdmac_next_desc(struct milbeaut_hdmac_chan *mc)
+{
+	struct virt_dma_desc *vd;
+
+	vd = vchan_next_desc(&mc->vc);
+	if (!vd) {
+		mc->md = NULL;
+		return NULL;
+	}
+
+	list_del(&vd->node);
+
+	mc->md = to_milbeaut_hdmac_desc(vd);
+
+	return mc->md;
+}
+
+/* mc->vc.lock must be held by caller */
+static void milbeaut_chan_start(struct milbeaut_hdmac_chan *mc,
+				struct milbeaut_hdmac_desc *md)
+{
+	struct scatterlist *sg;
+	u32 cb, ca, src_addr, dest_addr, len;
+	u32 width, burst;
+
+	sg = &md->sgl[md->sg_cur];
+	len = sg_dma_len(sg);
+
+	cb = MLB_HDMAC_CI | MLB_HDMAC_EI;
+	if (md->dir == DMA_MEM_TO_DEV) {
+		cb |= MLB_HDMAC_FD;
+		width = mc->cfg.dst_addr_width;
+		burst = mc->cfg.dst_maxburst;
+		src_addr = sg_dma_address(sg);
+		dest_addr = mc->cfg.dst_addr;
+	} else {
+		cb |= MLB_HDMAC_FS;
+		width = mc->cfg.src_addr_width;
+		burst = mc->cfg.src_maxburst;
+		src_addr = mc->cfg.src_addr;
+		dest_addr = sg_dma_address(sg);
+	}
+	cb |= FIELD_PREP(MLB_HDMAC_TW, (width >> 1));
+	cb |= FIELD_PREP(MLB_HDMAC_MS, 2);
+
+	writel_relaxed(src_addr, mc->reg_ch_base + MLB_HDMAC_DMACSA);
+	writel_relaxed(dest_addr, mc->reg_ch_base + MLB_HDMAC_DMACDA);
+	writel_relaxed(cb, mc->reg_ch_base + MLB_HDMAC_DMACB);
+
+	ca = FIELD_PREP(MLB_HDMAC_IS, mc->slave_id);
+	if (burst == 16)
+		ca |= FIELD_PREP(MLB_HDMAC_BT, 0xf);
+	else if (burst == 8)
+		ca |= FIELD_PREP(MLB_HDMAC_BT, 0xd);
+	else if (burst == 4)
+		ca |= FIELD_PREP(MLB_HDMAC_BT, 0xb);
+	burst *= width;
+	ca |= FIELD_PREP(MLB_HDMAC_TC, (len / burst - 1));
+	writel_relaxed(ca, mc->reg_ch_base + MLB_HDMAC_DMACA);
+	ca |= MLB_HDMAC_EB;
+	writel_relaxed(ca, mc->reg_ch_base + MLB_HDMAC_DMACA);
+}
+
+/* mc->vc.lock must be held by caller */
+static void milbeaut_hdmac_start(struct milbeaut_hdmac_chan *mc)
+{
+	struct milbeaut_hdmac_desc *md;
+
+	md = milbeaut_hdmac_next_desc(mc);
+	if (md)
+		milbeaut_chan_start(mc, md);
+}
+
+static irqreturn_t milbeaut_hdmac_interrupt(int irq, void *dev_id)
+{
+	struct milbeaut_hdmac_chan *mc = dev_id;
+	struct milbeaut_hdmac_desc *md;
+	irqreturn_t ret = IRQ_HANDLED;
+	u32 val;
+
+	spin_lock(&mc->vc.lock);
+
+	/* Ack and Disable irqs */
+	val = readl_relaxed(mc->reg_ch_base + MLB_HDMAC_DMACB);
+	val &= ~(FIELD_PREP(MLB_HDMAC_SS, HDMAC_PAUSE));
+	writel_relaxed(val, mc->reg_ch_base + MLB_HDMAC_DMACB);
+	val &= ~MLB_HDMAC_EI;
+	val &= ~MLB_HDMAC_CI;
+	writel_relaxed(val, mc->reg_ch_base + MLB_HDMAC_DMACB);
+
+	md = mc->md;
+	if (!md)
+		goto out;
+
+	md->sg_cur++;
+
+	if (md->sg_cur >= md->sg_len) {
+		vchan_cookie_complete(&md->vd);
+		md = milbeaut_hdmac_next_desc(mc);
+		if (!md)
+			goto out;
+	}
+
+	milbeaut_chan_start(mc, md);
+
+out:
+	spin_unlock(&mc->vc.lock);
+	return ret;
+}
+
+static void milbeaut_hdmac_free_chan_resources(struct dma_chan *chan)
+{
+	vchan_free_chan_resources(to_virt_chan(chan));
+}
+
+static int
+milbeaut_hdmac_chan_config(struct dma_chan *chan, struct dma_slave_config *cfg)
+{
+	struct virt_dma_chan *vc = to_virt_chan(chan);
+	struct milbeaut_hdmac_chan *mc = to_milbeaut_hdmac_chan(vc);
+
+	spin_lock(&mc->vc.lock);
+	mc->cfg = *cfg;
+	spin_unlock(&mc->vc.lock);
+
+	return 0;
+}
+
+static int milbeaut_hdmac_chan_pause(struct dma_chan *chan)
+{
+	struct virt_dma_chan *vc = to_virt_chan(chan);
+	struct milbeaut_hdmac_chan *mc = to_milbeaut_hdmac_chan(vc);
+	u32 val;
+
+	spin_lock(&mc->vc.lock);
+	val = readl_relaxed(mc->reg_ch_base + MLB_HDMAC_DMACA);
+	val |= MLB_HDMAC_PB;
+	writel_relaxed(val, mc->reg_ch_base + MLB_HDMAC_DMACA);
+	spin_unlock(&mc->vc.lock);
+
+	return 0;
+}
+
+static int milbeaut_hdmac_chan_resume(struct dma_chan *chan)
+{
+	struct virt_dma_chan *vc = to_virt_chan(chan);
+	struct milbeaut_hdmac_chan *mc = to_milbeaut_hdmac_chan(vc);
+	u32 val;
+
+	spin_lock(&mc->vc.lock);
+	val = readl_relaxed(mc->reg_ch_base + MLB_HDMAC_DMACA);
+	val &= ~MLB_HDMAC_PB;
+	writel_relaxed(val, mc->reg_ch_base + MLB_HDMAC_DMACA);
+	spin_unlock(&mc->vc.lock);
+
+	return 0;
+}
+
+static struct dma_async_tx_descriptor *
+milbeaut_hdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+			     unsigned int sg_len,
+			     enum dma_transfer_direction direction,
+			     unsigned long flags, void *context)
+{
+	struct virt_dma_chan *vc = to_virt_chan(chan);
+	struct milbeaut_hdmac_desc *md;
+
+	if (!is_slave_direction(direction))
+		return NULL;
+
+	md = kzalloc(sizeof(*md), GFP_NOWAIT);
+	if (!md)
+		return NULL;
+
+	md->sgl = sgl;
+	md->sg_len = sg_len;
+	md->dir = direction;
+
+	return vchan_tx_prep(vc, &md->vd, flags);
+}
+
+static int milbeaut_hdmac_terminate_all(struct dma_chan *chan)
+{
+	struct virt_dma_chan *vc = to_virt_chan(chan);
+	struct milbeaut_hdmac_chan *mc = to_milbeaut_hdmac_chan(vc);
+	unsigned long flags;
+	int ret = 0;
+	u32 val;
+
+	LIST_HEAD(head);
+
+	spin_lock_irqsave(&vc->lock, flags);
+
+	val = readl_relaxed(mc->reg_ch_base + MLB_HDMAC_DMACA);
+	val &= ~MLB_HDMAC_EB; /* disable the channel */
+	writel_relaxed(val, mc->reg_ch_base + MLB_HDMAC_DMACA);
+
+	if (mc->md) {
+		vchan_terminate_vdesc(&mc->md->vd);
+		mc->md = NULL;
+	}
+
+	vchan_get_all_descriptors(vc, &head);
+
+	spin_unlock_irqrestore(&vc->lock, flags);
+
+	vchan_dma_desc_free_list(vc, &head);
+
+	return ret;
+}
+
+static void milbeaut_hdmac_synchronize(struct dma_chan *chan)
+{
+	vchan_synchronize(to_virt_chan(chan));
+}
+
+static enum dma_status milbeaut_hdmac_tx_status(struct dma_chan *chan,
+						dma_cookie_t cookie,
+						struct dma_tx_state *txstate)
+{
+	struct virt_dma_chan *vc;
+	struct virt_dma_desc *vd;
+	struct milbeaut_hdmac_chan *mc;
+	struct milbeaut_hdmac_desc *md = NULL;
+	enum dma_status stat;
+	unsigned long flags;
+	int i;
+
+	stat = dma_cookie_status(chan, cookie, txstate);
+	/* Return immediately if we do not need to compute the residue. */
+	if (stat == DMA_COMPLETE || !txstate)
+		return stat;
+
+	vc = to_virt_chan(chan);
+
+	spin_lock_irqsave(&vc->lock, flags);
+
+	mc = to_milbeaut_hdmac_chan(vc);
+
+	/* residue from the on-flight chunk */
+	if (mc->md && mc->md->vd.tx.cookie == cookie) {
+		struct scatterlist *sg;
+		u32 done;
+
+		md = mc->md;
+		sg = &md->sgl[md->sg_cur];
+
+		if (md->dir == DMA_DEV_TO_MEM)
+			done = readl_relaxed(mc->reg_ch_base
+					     + MLB_HDMAC_DMACDA);
+		else
+			done = readl_relaxed(mc->reg_ch_base
+					     + MLB_HDMAC_DMACSA);
+		done -= sg_dma_address(sg);
+
+		txstate->residue = -done;
+	}
+
+	if (!md) {
+		vd = vchan_find_desc(vc, cookie);
+		if (vd)
+			md = to_milbeaut_hdmac_desc(vd);
+	}
+
+	if (md) {
+		/* residue from the queued chunks */
+		for (i = md->sg_cur; i < md->sg_len; i++)
+			txstate->residue += sg_dma_len(&md->sgl[i]);
+	}
+
+	spin_unlock_irqrestore(&vc->lock, flags);
+
+	return stat;
+}
+
+static void milbeaut_hdmac_issue_pending(struct dma_chan *chan)
+{
+	struct virt_dma_chan *vc = to_virt_chan(chan);
+	struct milbeaut_hdmac_chan *mc = to_milbeaut_hdmac_chan(vc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&vc->lock, flags);
+
+	if (vchan_issue_pending(vc) && !mc->md)
+		milbeaut_hdmac_start(mc);
+
+	spin_unlock_irqrestore(&vc->lock, flags);
+}
+
+static void milbeaut_hdmac_desc_free(struct virt_dma_desc *vd)
+{
+	kfree(to_milbeaut_hdmac_desc(vd));
+}
+
+static struct dma_chan *
+milbeaut_hdmac_xlate(struct of_phandle_args *dma_spec, struct of_dma *of_dma)
+{
+	struct milbeaut_hdmac_device *mdev = of_dma->of_dma_data;
+	struct milbeaut_hdmac_chan *mc;
+	struct virt_dma_chan *vc;
+	struct dma_chan *chan;
+
+	if (dma_spec->args_count != 1)
+		return NULL;
+
+	chan = dma_get_any_slave_channel(&mdev->ddev);
+	if (!chan)
+		return NULL;
+
+	vc = to_virt_chan(chan);
+	mc = to_milbeaut_hdmac_chan(vc);
+	mc->slave_id = dma_spec->args[0];
+
+	return chan;
+}
+
+static int milbeaut_hdmac_chan_init(struct platform_device *pdev,
+				    struct milbeaut_hdmac_device *mdev,
+				    int chan_id)
+{
+	struct device *dev = &pdev->dev;
+	struct milbeaut_hdmac_chan *mc = &mdev->channels[chan_id];
+	char *irq_name;
+	int irq, ret;
+
+	irq = platform_get_irq(pdev, chan_id);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "failed to get IRQ number for ch%d\n",
+			chan_id);
+		return irq;
+	}
+
+	irq_name = devm_kasprintf(dev, GFP_KERNEL, "milbeaut-hdmac-%d",
+				  chan_id);
+	if (!irq_name)
+		return -ENOMEM;
+
+	ret = devm_request_irq(dev, irq, milbeaut_hdmac_interrupt,
+			       IRQF_SHARED, irq_name, mc);
+	if (ret)
+		return ret;
+
+	mc->mdev = mdev;
+	mc->reg_ch_base = mdev->reg_base + MLB_HDMAC_CH_STRIDE * (chan_id + 1);
+	mc->vc.desc_free = milbeaut_hdmac_desc_free;
+	vchan_init(&mc->vc, &mdev->ddev);
+
+	return 0;
+}
+
+static int milbeaut_hdmac_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct milbeaut_hdmac_device *mdev;
+	struct dma_device *ddev;
+	struct resource *res;
+	int nr_chans, ret, i;
+
+	nr_chans = platform_irq_count(pdev);
+	if (nr_chans < 0)
+		return nr_chans;
+
+	ret = dma_set_mask(dev, DMA_BIT_MASK(32));
+	if (ret)
+		return ret;
+
+	mdev = devm_kzalloc(dev, struct_size(mdev, channels, nr_chans),
+			    GFP_KERNEL);
+	if (!mdev)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mdev->reg_base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(mdev->reg_base))
+		return PTR_ERR(mdev->reg_base);
+
+	mdev->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(mdev->clk)) {
+		dev_err(dev, "failed to get clock\n");
+		return PTR_ERR(mdev->clk);
+	}
+
+	ret = clk_prepare_enable(mdev->clk);
+	if (ret)
+		return ret;
+
+	ddev = &mdev->ddev;
+	ddev->dev = dev;
+	dma_cap_set(DMA_PRIVATE, ddev->cap_mask);
+	ddev->src_addr_widths = MLB_HDMAC_BUSWIDTHS;
+	ddev->dst_addr_widths = MLB_HDMAC_BUSWIDTHS;
+	ddev->directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM);
+	ddev->device_free_chan_resources = milbeaut_hdmac_free_chan_resources;
+	ddev->device_config = milbeaut_hdmac_chan_config;
+	ddev->device_pause = milbeaut_hdmac_chan_pause;
+	ddev->device_resume = milbeaut_hdmac_chan_resume;
+	ddev->device_prep_slave_sg = milbeaut_hdmac_prep_slave_sg;
+	ddev->device_terminate_all = milbeaut_hdmac_terminate_all;
+	ddev->device_synchronize = milbeaut_hdmac_synchronize;
+	ddev->device_tx_status = milbeaut_hdmac_tx_status;
+	ddev->device_issue_pending = milbeaut_hdmac_issue_pending;
+	INIT_LIST_HEAD(&ddev->channels);
+
+	for (i = 0; i < nr_chans; i++) {
+		ret = milbeaut_hdmac_chan_init(pdev, mdev, i);
+		if (ret)
+			goto disable_clk;
+	}
+
+	ret = dma_async_device_register(ddev);
+	if (ret)
+		goto disable_clk;
+
+	ret = of_dma_controller_register(dev->of_node,
+					 milbeaut_hdmac_xlate, mdev);
+	if (ret)
+		goto unregister_dmac;
+
+	platform_set_drvdata(pdev, mdev);
+
+	return 0;
+
+unregister_dmac:
+	dma_async_device_unregister(ddev);
+disable_clk:
+	clk_disable_unprepare(mdev->clk);
+
+	return ret;
+}
+
+static int milbeaut_hdmac_remove(struct platform_device *pdev)
+{
+	struct milbeaut_hdmac_device *mdev = platform_get_drvdata(pdev);
+	struct dma_chan *chan;
+	int ret;
+
+	/*
+	 * Before reaching here, almost all descriptors have been freed by the
+	 * ->device_free_chan_resources() hook. However, each channel might
+	 * be still holding one descriptor that was on-flight at that moment.
+	 * Terminate it to make sure this hardware is no longer running. Then,
+	 * free the channel resources once again to avoid memory leak.
+	 */
+	list_for_each_entry(chan, &mdev->ddev.channels, device_node) {
+		ret = dmaengine_terminate_sync(chan);
+		if (ret)
+			return ret;
+		milbeaut_hdmac_free_chan_resources(chan);
+	}
+
+	of_dma_controller_free(pdev->dev.of_node);
+	dma_async_device_unregister(&mdev->ddev);
+	clk_disable_unprepare(mdev->clk);
+
+	return 0;
+}
+
+static const struct of_device_id milbeaut_hdmac_match[] = {
+	{ .compatible = "socionext,milbeaut-m10v-hdmac" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, milbeaut_hdmac_match);
+
+static struct platform_driver milbeaut_hdmac_driver = {
+	.probe = milbeaut_hdmac_probe,
+	.remove = milbeaut_hdmac_remove,
+	.driver = {
+		.name = "milbeaut-m10v-hdmac",
+		.of_match_table = milbeaut_hdmac_match,
+	},
+};
+module_platform_driver(milbeaut_hdmac_driver);
+
+MODULE_DESCRIPTION("Milbeaut HDMAC DmaEngine driver");
+MODULE_LICENSE("GPL v2");
-- 
2.17.1


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

* Re: [PATCH v2 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings
  2019-08-18  5:17   ` [PATCH v2 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings jassisinghbrar
@ 2019-08-27 16:31     ` Rob Herring
  2019-09-04  5:50     ` Vinod Koul
  1 sibling, 0 replies; 17+ messages in thread
From: Rob Herring @ 2019-08-27 16:31 UTC (permalink / raw)
  To: jassisinghbrar
  Cc: dmaengine, devicetree, linux-kernel, vkoul, robh+dt, Jassi Brar

On Sun, 18 Aug 2019 00:17:54 -0500, jassisinghbrar@gmail.com wrote:
> From: Jassi Brar <jaswinder.singh@linaro.org>
> 
> Document the devicetree bindings for Socionext Milbeaut HDMAC
> controller. Controller has upto 8 floating channels, that need
> a predefined slave-id to work from a set of slaves.
> 
> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> ---
>  .../bindings/dma/milbeaut-m10v-hdmac.txt      | 32 +++++++++++++++++++
>  1 file changed, 32 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> 

Reviewed-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v2 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings
  2019-08-18  5:17   ` [PATCH v2 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings jassisinghbrar
  2019-08-27 16:31     ` Rob Herring
@ 2019-09-04  5:50     ` Vinod Koul
  2019-09-04  6:18       ` Jassi Brar
  1 sibling, 1 reply; 17+ messages in thread
From: Vinod Koul @ 2019-09-04  5:50 UTC (permalink / raw)
  To: jassisinghbrar; +Cc: dmaengine, devicetree, linux-kernel, robh+dt, Jassi Brar

On 18-08-19, 00:17, jassisinghbrar@gmail.com wrote:
> From: Jassi Brar <jaswinder.singh@linaro.org>
> 
> Document the devicetree bindings for Socionext Milbeaut HDMAC
> controller. Controller has upto 8 floating channels, that need
> a predefined slave-id to work from a set of slaves.
> 
> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> ---
>  .../bindings/dma/milbeaut-m10v-hdmac.txt      | 32 +++++++++++++++++++
>  1 file changed, 32 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> 
> diff --git a/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> new file mode 100644
> index 000000000000..f0960724f1c7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> @@ -0,0 +1,32 @@
> +* Milbeaut AHB DMA Controller
> +
> +Milbeaut AHB DMA controller has transfer capability bellow.

s/bellow/below:

> + - device to memory transfer
> + - memory to device transfer
> +
> +Required property:
> +- compatible:       Should be  "socionext,milbeaut-m10v-hdmac"
> +- reg:              Should contain DMA registers location and length.
> +- interrupts:       Should contain all of the per-channel DMA interrupts.
> +                     Number of channels is configurable - 2, 4 or 8, so
> +                     the number of interrupts specfied should be {2,4,8}.

s/specfied/specified

-- 
~Vinod

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

* Re: [PATCH v2 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings
  2019-09-04  5:50     ` Vinod Koul
@ 2019-09-04  6:18       ` Jassi Brar
  2019-09-06  5:12         ` Vinod Koul
  0 siblings, 1 reply; 17+ messages in thread
From: Jassi Brar @ 2019-09-04  6:18 UTC (permalink / raw)
  To: Vinod Koul
  Cc: dmaengine, Devicetree List, Linux Kernel Mailing List,
	Rob Herring, Jassi Brar

On Wed, Sep 4, 2019 at 12:51 AM Vinod Koul <vkoul@kernel.org> wrote:
>
> On 18-08-19, 00:17, jassisinghbrar@gmail.com wrote:
> > From: Jassi Brar <jaswinder.singh@linaro.org>
> >
> > Document the devicetree bindings for Socionext Milbeaut HDMAC
> > controller. Controller has upto 8 floating channels, that need
> > a predefined slave-id to work from a set of slaves.
> >
> > Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> > ---
> >  .../bindings/dma/milbeaut-m10v-hdmac.txt      | 32 +++++++++++++++++++
> >  1 file changed, 32 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> >
> > diff --git a/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> > new file mode 100644
> > index 000000000000..f0960724f1c7
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> > @@ -0,0 +1,32 @@
> > +* Milbeaut AHB DMA Controller
> > +
> > +Milbeaut AHB DMA controller has transfer capability bellow.
>
> s/bellow/below:
>
> > + - device to memory transfer
> > + - memory to device transfer
> > +
> > +Required property:
> > +- compatible:       Should be  "socionext,milbeaut-m10v-hdmac"
> > +- reg:              Should contain DMA registers location and length.
> > +- interrupts:       Should contain all of the per-channel DMA interrupts.
> > +                     Number of channels is configurable - 2, 4 or 8, so
> > +                     the number of interrupts specfied should be {2,4,8}.
>
> s/specfied/specified
>
Hi Vinod,
  Do you want me to spin yet another revision for the two types in text?

thnx

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

* Re: [PATCH v2 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings
  2019-09-04  6:18       ` Jassi Brar
@ 2019-09-06  5:12         ` Vinod Koul
  0 siblings, 0 replies; 17+ messages in thread
From: Vinod Koul @ 2019-09-06  5:12 UTC (permalink / raw)
  To: Jassi Brar
  Cc: dmaengine, Devicetree List, Linux Kernel Mailing List,
	Rob Herring, Jassi Brar

On 04-09-19, 01:18, Jassi Brar wrote:
> On Wed, Sep 4, 2019 at 12:51 AM Vinod Koul <vkoul@kernel.org> wrote:
> >
> > On 18-08-19, 00:17, jassisinghbrar@gmail.com wrote:
> > > From: Jassi Brar <jaswinder.singh@linaro.org>
> > >
> > > Document the devicetree bindings for Socionext Milbeaut HDMAC
> > > controller. Controller has upto 8 floating channels, that need
> > > a predefined slave-id to work from a set of slaves.
> > >
> > > Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> > > ---
> > >  .../bindings/dma/milbeaut-m10v-hdmac.txt      | 32 +++++++++++++++++++
> > >  1 file changed, 32 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> > >
> > > diff --git a/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> > > new file mode 100644
> > > index 000000000000..f0960724f1c7
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/dma/milbeaut-m10v-hdmac.txt
> > > @@ -0,0 +1,32 @@
> > > +* Milbeaut AHB DMA Controller
> > > +
> > > +Milbeaut AHB DMA controller has transfer capability bellow.
> >
> > s/bellow/below:
> >
> > > + - device to memory transfer
> > > + - memory to device transfer
> > > +
> > > +Required property:
> > > +- compatible:       Should be  "socionext,milbeaut-m10v-hdmac"
> > > +- reg:              Should contain DMA registers location and length.
> > > +- interrupts:       Should contain all of the per-channel DMA interrupts.
> > > +                     Number of channels is configurable - 2, 4 or 8, so
> > > +                     the number of interrupts specfied should be {2,4,8}.
> >
> > s/specfied/specified
> >
> Hi Vinod,
>   Do you want me to spin yet another revision for the two types in text?

Yes that would be easier for me

Thanks

-- 
~Vinod

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

end of thread, other threads:[~2019-09-06  5:13 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-13  0:51 [PATCH 0/2] Add support for AHB DMA controller on Milbeaut series jassisinghbrar
2019-06-13  0:52 ` [PATCH 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings jassisinghbrar
2019-07-09 14:34   ` Rob Herring
2019-07-10  4:12     ` Jassi Brar
2019-07-10 13:48       ` Rob Herring
2019-07-10 13:48         ` Rob Herring
2019-06-13  0:52 ` [PATCH 2/2] dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms jassisinghbrar
2019-06-24  6:44   ` Vinod Koul
2019-08-16  2:25     ` Jassi Brar
2019-08-16  4:43       ` Vinod Koul
2019-08-18  5:16 ` [PATCH v2 0/2] Add support for AHB DMA controller on Milbeaut series jassisinghbrar
2019-08-18  5:17   ` [PATCH v2 1/2] dt-bindings: milbeaut-m10v-hdmac: Add Socionext Milbeaut HDMAC bindings jassisinghbrar
2019-08-27 16:31     ` Rob Herring
2019-09-04  5:50     ` Vinod Koul
2019-09-04  6:18       ` Jassi Brar
2019-09-06  5:12         ` Vinod Koul
2019-08-18  5:18   ` [PATCH v2 2/2] dmaengine: milbeaut-hdmac: Add HDMAC driver for Milbeaut platforms jassisinghbrar

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.