Skip to contentSkip to conversation

dmaengine: add k3dma

PATCH Superseded Zhangfei Gao 4 participants 10 messages Aug 15, 2013 – Sep 3, 2013

Subsystems (2)

v3 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

v3 cover dmaengine: add k3dma

change since v2:
0001:
Dan Carpenter find compile warnning

0002:
Vinod suggest use __ffl, remove "#ifdef CONFIG_PM_SLEEP" and micro namespace

change since v1:
Follow Arnd suggestion:
using dma_get_slave_channel interface
Correct dma-channels and dma-requests for phy and virt channel

Follow Vinod suggestion:
add name space
use SIMPLE_DEV_PM_OPS

Besides:
add pause/resume
Using kzalloc instead of dma pool

Zhangfei Gao (2):
dmaengine: add interface of dma_get_slave_channel
dmaengine: Add hisilicon k3 DMA engine driver

 Documentation/devicetree/bindings/dma/k3dma.txt |   46 ++
 drivers/dma/Kconfig                             |    9 +
 drivers/dma/Makefile                            |    1 +
 drivers/dma/dmaengine.c                         |   25 +
 drivers/dma/k3dma.c                             |  840 +++++++++++++++++++++++
 include/linux/dmaengine.h                       |    1 +
 6 files changed, 922 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/k3dma.txt
 create mode 100644 drivers/dma/k3dma.c
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH v3 1/2 dmaengine: add interface of dma_get_slave_channel

Suggested by Arnd, add dma_get_slave_channel interface
Dma host driver could get specific channel specificied by request line, rather than filter.

host example:
static struct dma_chan *xx_of_dma_simple_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma)

{
	struct xx_dma_dev *d = ofdma->of_dma_data;
	unsigned int request = dma_spec->args[0];

	if (request > d->dma_requests)
		return NULL;

	return dma_get_slave_channel(&(d->chans[request].vc.chan));
}

probe:
of_dma_controller_register((&op->dev)->of_node, xx_of_dma_simple_xlate, d);

---
 drivers/dma/dmaengine.c   |   25 +++++++++++++++++++++++++
 include/linux/dmaengine.h |    1 +
 2 files changed, 26 insertions(+)
drivers/dma/dmaengine.c +25 -0
index 9e56745..38dd8c3 100644
@@ -504,6 +504,31 @@ static struct dma_chan *private_candidate(const dma_cap_mask_t *mask,
 }
 
 /**
+ * dma_request_channel - try to get specific channel exclusively
+ * @chan: target channel
+ */
+struct dma_chan *dma_get_slave_channel(struct dma_chan *chan)
+{
+	int err = -EBUSY;
+
+	/* lock against __dma_request_channel */
+	mutex_lock(&dma_list_mutex);
+
+	if (chan->client_count == 0) {
+		err = dma_chan_get(chan);
+		if (err)
+			pr_debug("%s: failed to get %s: (%d)\n",
+				__func__, dma_chan_name(chan), err);
+	} else
+		chan = NULL;
+
+	mutex_unlock(&dma_list_mutex);
+
+	return chan;
+}
+EXPORT_SYMBOL_GPL(dma_get_slave_channel);
+
+/**
  * dma_request_channel - try to allocate an exclusive channel
  * @mask: capabilities that the channel must satisfy
  * @fn: optional callback to disposition available channels
include/linux/dmaengine.h +1 -0
index cb286b1..c271608 100644
@@ -995,6 +995,7 @@ int dma_async_device_register(struct dma_device *device);
 void dma_async_device_unregister(struct dma_device *device);
 void dma_run_dependencies(struct dma_async_tx_descriptor *tx);
 struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type);
+struct dma_chan *dma_get_slave_channel(struct dma_chan *chan);
 struct dma_chan *net_dma_find_channel(void);
 #define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y)
 #define dma_request_slave_channel_compat(mask, x, y, dev, name) \
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH v3 1/2 dmaengine: add interface of dma_get_slave_channel

Quoted 47 lines · Zhangfei Gao

Suggested by Arnd, add dma_get_slave_channel interface
Dma host driver could get specific channel specificied by request line, rather than filter.

host example:
static struct dma_chan *xx_of_dma_simple_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma)

{
	struct xx_dma_dev *d = ofdma->of_dma_data;
	unsigned int request = dma_spec->args[0];

	if (request > d->dma_requests)
		return NULL;

	return dma_get_slave_channel(&(d->chans[request].vc.chan));
}

probe:
of_dma_controller_register((&op->dev)->of_node, xx_of_dma_simple_xlate, d);

---
 drivers/dma/dmaengine.c   |   25 +++++++++++++++++++++++++
 include/linux/dmaengine.h |    1 +
 2 files changed, 26 insertions(+)
drivers/dma/dmaengine.c +13 -0
index 9e56745..38dd8c3 100644
@@ -504,6 +504,31 @@ static struct dma_chan *private_candidate(const dma_cap_mask_t *mask,
 }
 
 /**
+ * dma_request_channel - try to get specific channel exclusively
+ * @chan: target channel
+ */
+struct dma_chan *dma_get_slave_channel(struct dma_chan *chan)
+{
+	int err = -EBUSY;
+
+	/* lock against __dma_request_channel */
+	mutex_lock(&dma_list_mutex);
+
+	if (chan->client_count == 0) {
+		err = dma_chan_get(chan);
+		if (err)

drivers/dma/dmaengine.c static struct dma_chan *private_candidate(const dma_cap_mask_t *mask, · line 529

Quoted 10 lines
drivers/dma/dmaengine.c +10 -0
+			pr_debug("%s: failed to get %s: (%d)\n",
+				__func__, dma_chan_name(chan), err);
+	} else
+		chan = NULL;
+
+	mutex_unlock(&dma_list_mutex);
+
+	return chan;
+}
+EXPORT_SYMBOL_GPL(dma_get_slave_channel);

No, this is not the right approach.

When patch is applied and you find an issue you fix the issue. I have already pushed and merged this. So removing is a bad idea.
you provide a fix for this miss.

Also for this you need to give due credit to Dan (reporter). That is how the process works.

Anyway I have applied the below fix and will push it out.

---
dmaengine: fix - error: potential NULL dereference 'chan'

commit 7bb587f4 "dmaengine: add interface of dma_get_slave_channel" introduced the above error so fix it

---
 drivers/dma/dmaengine.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)
drivers/dma/dmaengine.c +5 -5
index 5932ab1..755ba2f 100644
@@ -514,16 +514,16 @@ struct dma_chan *dma_get_slave_channel(struct dma_chan *chan)
 	/* lock against __dma_request_channel */
 	mutex_lock(&dma_list_mutex);
 
-	if (chan->client_count == 0)
+	if (chan->client_count == 0) {
 		err = dma_chan_get(chan);
-	else
+		if (err)
+			pr_debug("%s: failed to get %s: (%d)\n",
+				__func__, dma_chan_name(chan), err);
+	} else
 		chan = NULL;
 
 	mutex_unlock(&dma_list_mutex);
 
-	if (err)
-		pr_debug("%s: failed to get %s: (%d)\n",
-			__func__, dma_chan_name(chan), err);
 
 	return chan;
 }

--
~Vinod

#3 lore raw

PATCH v3 1/2 dmaengine: add interface of dma_get_slave_channel

Quoted 14 lines

No, this is not the right approach.

When patch is applied and you find an issue you fix the issue. I have already pushed and merged this. So removing is a bad idea.
you provide a fix for this miss.

Also for this you need to give due credit to Dan (reporter). That is how the process works.

Anyway I have applied the below fix and will push it out.

---
dmaengine: fix - error: potential NULL dereference 'chan'

Quoted 6 lines

commit 7bb587f4 "dmaengine: add interface of dma_get_slave_channel" introduced the above error so fix it

Thanks Vinod for the kind education.
Understand, will take care next time.

BTW, it is strange I do not see such compile warning here :(

#4 lore raw

PATCH v3 1/2 dmaengine: add interface of dma_get_slave_channel

Quoted 1 line · zhangfei gao

BTW, it is strange I do not see such compile warning here :(

This was a Smatch static checker warning, not a regular build warning.

regards,
dan carpenter

#5 lore raw

PATCH v3 1/2 dmaengine: add interface of dma_get_slave_channel

Quoted 6 lines · Dan Carpenter
Quoted 1 line · zhangfei gao

BTW, it is strange I do not see such compile warning here :(

This was a Smatch static checker warning, not a regular build warning.

my guess was right!

~Vinod

author
#6 lore raw

PATCH v3 1/2 dmaengine: add interface of dma_get_slave_channel

In reply to Dan Carpenter
Quoted 10 lines · Dan Carpenter
Quoted 1 line · zhangfei gao

BTW, it is strange I do not see such compile warning here :(

This was a Smatch static checker warning, not a regular build warning.

regards,
dan carpenter

Dear Dan

Thanks for introducing this valuable tool.
Have download from git://repo.or.cz/smatch.git

When trying use this tool, could get some warning,
make CHECK="~/bin/smatch -p=kernel --no-data" C=1 | tee warns.txt

Also some strange warning, like "SQL error #2: no such table:
caller_info", is it ignored?

Besides, when test this case for check smatch setting. Still not reproduce the issue, should be not config correct?

Only get
drivers/dma/dmaengine.c:845 dma_async_device_register() warn: possible memory leak of 'idr_ref'
drivers/dma/dmaengine.c:866 dma_async_device_register() warn: possible memory leak of 'idr_ref'

Anyway, though config not totally correct, it really could find some warning.

Thanks

#7 lore raw

PATCH v3 1/2 dmaengine: add interface of dma_get_slave_channel

Quoted 13 lines · zhangfei
Quoted 10 lines · Dan Carpenter
Quoted 1 line · zhangfei gao

BTW, it is strange I do not see such compile warning here :(

This was a Smatch static checker warning, not a regular build warning.

regards,
dan carpenter

Dear Dan

Quoted 9 lines

Thanks for introducing this valuable tool. Have download from git://repo.or.cz/smatch.git

When trying use this tool, could get some warning,
make CHECK="~/bin/smatch -p=kernel --no-data" C=1 | tee warns.txt

Also some strange warning, like "SQL error #2: no such table:
caller_info", is it ignored?

Oops. I'll fix that. The problem is that I don't normally test with --no-data. Sorry about that.

Quoted 2 lines

Besides, when test this case for check smatch setting. Still not reproduce the issue, should be not config correct?

This warning requires that the cross function database be set up.

regards,
dan carpenter

#8 lore raw

PATCH v3 1/2 dmaengine: add interface of dma_get_slave_channel

In reply to zhangfei gao
Quoted 17 lines · zhangfei gao
Quoted 17 lines

No, this is not the right approach.

When patch is applied and you find an issue you fix the issue. I have already pushed and merged this. So removing is a bad idea.
you provide a fix for this miss.

Also for this you need to give due credit to Dan (reporter). That is how the process works.

Anyway I have applied the below fix and will push it out.

---
dmaengine: fix - error: potential NULL dereference 'chan'

commit 7bb587f4 "dmaengine: add interface of dma_get_slave_channel" introduced the above error so fix it

Quoted 6 lines
Quoted 3 lines

Thanks Vinod for the kind education.
Understand, will take care next time.

No issues...

Quoted 2 lines

BTW, it is strange I do not see such compile warning here :(

Try running smatch and you will see. Compiler will not worry about these, static checkers would. Since the bug report is from Dan, my guess is it would be triggered by Smatch.

~Vinod

#9 lore raw

PATCH v3 2/2 dmaengine: Add hisilicon k3 DMA engine driver

In reply to Zhangfei Gao

Add dmaengine driver for hisilicon k3 platform based on virt_dma

---
 Documentation/devicetree/bindings/dma/k3dma.txt |   46 ++
 drivers/dma/Kconfig                             |    9 +
 drivers/dma/Makefile                            |    1 +
 drivers/dma/k3dma.c                             |  840 +++++++++++++++++++++++
 4 files changed, 896 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/k3dma.txt
 create mode 100644 drivers/dma/k3dma.c
Documentation/devicetree/bindings/dma/k3dma.txt new file +46 -0
new file mode 100644
index 0000000..23f8d71
@@ -0,0 +1,46 @@
+* Hisilicon K3 DMA controller
+
+See dma.txt first
+
+Required properties:
+- compatible: Should be "hisilicon,k3-dma-1.0"
+- reg: Should contain DMA registers location and length.
+- interrupts: Should contain one interrupt shared by all channel
+- #dma-cells: see dma.txt, should be 1, para number
+- dma-channels: physical channels supported
+- dma-requests: virtual channels supported, each virtual channel
+		have specific request line
+- clocks: clock required
+
+Example:
+
+Controller:
+		dma0: dma at fcd02000 {
+			compatible = "hisilicon,k3-dma-1.0";
+			reg = <0xfcd02000 0x1000>;
+			#dma-cells = <1>;
+			dma-channels = <16>;
+			dma-requests = <27>;
+			interrupts = <0 12 4>;
+			clocks = <&pclk>;
+			status = "disable";
+		};
+
+Client:
+Use specific request line passing from dmax
+For example, i2c0 read channel request line is 18, while write channel use 19
+
+		i2c0: i2c at fcb08000 {
+			compatible = "snps,designware-i2c";
+			dmas =	<&dma0 18          /* read channel */
+				 &dma0 19>;        /* write channel */
+			dma-names = "rx", "tx";
+		};
+
+		i2c1: i2c at fcb09000 {
+			compatible = "snps,designware-i2c";
+			dmas =	<&dma0 20          /* read channel */
+				 &dma0 21>;        /* write channel */
+			dma-names = "rx", "tx";
+		};
+
drivers/dma/Kconfig +9 -0
index 6825957..2945ff0 100644
@@ -300,6 +300,15 @@ config DMA_JZ4740
 	select DMA_ENGINE
 	select DMA_VIRTUAL_CHANNELS
 
+config K3_DMA
+	tristate "Hisilicon K3 DMA support"
+	depends on ARCH_HI3xxx
+	select DMA_ENGINE
+	select DMA_VIRTUAL_CHANNELS
+	help
+	  Support the DMA engine for Hisilicon K3 platform
+	  devices.
+
 config DMA_ENGINE
 	bool
 
drivers/dma/Makefile +1 -0
index 5e0f2ef..8c97941 100644
@@ -39,3 +39,4 @@ obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
 obj-$(CONFIG_DMA_OMAP) += omap-dma.o
 obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
 obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
+obj-$(CONFIG_K3_DMA) += k3dma.o
drivers/dma/k3dma.c new file +840 -0

840 lines not on this page · raw message

Signature · 1 line
1.7.9.5