From 08b6ffc54a4b29e2072f7b4dc619ba3a2a5602c0 Mon Sep 17 00:00:00 2001
From: Kedareswara rao Appana <appanad@xilinx.com>
Date: Sun, 7 Jun 2015 16:30:08 +0530
Subject: [LINUX PATCH 1/2] dma: xilinx: Use of_dma framework in dma test
 client

This patch does following things:
- Uses of_dma framework in dma test client.
- Document the device node for dma test client.

Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
---
 .../devicetree/bindings/dma/xilinx/axi-dma.txt     |  46 ++++-----
 drivers/dma/xilinx/axidmatest.c                    | 114 ++++++++++-----------
 2 files changed, 76 insertions(+), 84 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/xilinx/axi-dma.txt b/Documentation/devicetree/bindings/dma/xilinx/axi-dma.txt
index 80c4633..74199cc 100644
--- a/Documentation/devicetree/bindings/dma/xilinx/axi-dma.txt
+++ b/Documentation/devicetree/bindings/dma/xilinx/axi-dma.txt
@@ -1,46 +1,38 @@
-Xilinx AXI DMA engine, it does transfers between memory and device. It can be
-configured to have one channel or two channels. If configured as two
-channels, one is to transmit to device and another is to receive from
-device.
+* Xilinx AXI DMA Test client
 
 Required properties:
-- compatible: Should be "xlnx,axi-dma"
-- reg: Should contain DMA registers location and length.
+- compatible: Should be "xlnx,axi-dma-test-1.00.a"
+- dmas: a list of <[DMA device phandle] [Channel ID]> pairs,
+	where Channel ID is '0' for write/tx and '1' for read/rx
+	channel.
+- dma-names: a list of DMA channel names, one per "dmas" entry
 
-Option node properties:
-- xlnx,include-sg: Tells whether configured for Scatter-mode in
-	the hardware.
+Example:
+++++++++
 
-Required child node properties:
-- compatible: It should be either "xlnx,axi-dma-mm2s-channel" or
-	"xlnx,axi-dma-s2mm-channel". It depends on the hardware design and it
-	can also have both channels.
-- interrupts: Should contain per channel DMA interrupts.
-- xlnx,data-width: Should contain the stream data width, take values
-	{32,64...1024}.
-- xlnx,device-id: Should contain device number in each channel. It should be
-	{0,1,2...so on} to the number of DMA devices configured in hardware.
+dmatest_0: dmatest@0 {
+	compatible ="xlnx,axi-dma-test-1.00.a";
+	dmas = <&axi_dma_0 0
+		&axi_dma_0 1>;
+	dma-names = "axidma0", "axidma1";
+} ;
 
-Optional child node properties:
-- xlnx,include-dre: Tells whether hardware is configured for Data
-	Realignment Engine.
 
-Example:
-++++++++
+Xilinx AXI DMA Device Node Example
+++++++++++++++++++++++++++++++++++++
 
 axi_dma_0: axidma@40400000 {
-	compatible = "xlnx,axi-dma";
+	compatible = "xlnx,axi-dma-1.00.a";
+	#dma_cells = <1>;
 	reg = < 0x40400000 0x10000 >;
 	dma-channel@40400000 {
 		compatible = "xlnx,axi-dma-mm2s-channel";
 		interrupts = < 0 59 4 >;
 		xlnx,datawidth = <0x40>;
-		xlnx,device-id = <0x0>;
 	} ;
-	dma-channel@40030030 {
+	dma-channel@40400030 {
 		compatible = "xlnx,axi-dma-s2mm-channel";
 		interrupts = < 0 58 4 >;
 		xlnx,datawidth = <0x40>;
-		xlnx,device-id = <0x0>;
 	} ;
 } ;
diff --git a/drivers/dma/xilinx/axidmatest.c b/drivers/dma/xilinx/axidmatest.c
index bbc88d7..3d570b1 100644
--- a/drivers/dma/xilinx/axidmatest.c
+++ b/drivers/dma/xilinx/axidmatest.c
@@ -14,6 +14,8 @@
 #include <linux/init.h>
 #include <linux/kthread.h>
 #include <linux/module.h>
+#include <linux/of_dma.h>
+#include <linux/platform_device.h>
 #include <linux/random.h>
 #include <linux/slab.h>
 #include <linux/wait.h>
@@ -589,71 +591,41 @@ static int dmatest_add_slave_channels(struct dma_chan *tx_chan,
 	return 0;
 }
 
-static bool xdma_filter(struct dma_chan *chan, void *param)
+static int xilinx_axidmatest_probe(struct platform_device *pdev)
 {
-	pr_debug("dmatest: Private is %x\n", *((int *)chan->private));
+	struct dma_chan *chan, *rx_chan;
+	int err;
 
-	if (*((int *)chan->private) == *(int *)param)
-		return true;
+	chan = dma_request_slave_channel(&pdev->dev, "axidma0");
+	if (IS_ERR(chan)) {
+		pr_err("xilinx_dmatest: No Tx channel\n");
+		return PTR_ERR(chan);
+	}
 
-	return false;
-}
+	rx_chan = dma_request_slave_channel(&pdev->dev, "axidma1");
+	if (IS_ERR(rx_chan)) {
+		err = PTR_ERR(rx_chan);
+		pr_err("xilinx_dmatest: No Rx channel\n");
+		goto free_tx;
+	}
 
-static int __init dmatest_init(void)
-{
-	dma_cap_mask_t mask;
-	struct dma_chan *chan;
-	int err = 0;
+	err = dmatest_add_slave_channels(chan, rx_chan);
+	if (err) {
+		pr_err("xilinx_dmatest: Unable to add channels\n");
+		goto free_rx;
+	}
 
-	/* JZ for slave transfer channels */
-	enum dma_data_direction direction;
-	struct dma_chan *rx_chan;
-	u32 match, device_id = 0;
-
-	dma_cap_zero(mask);
-	dma_cap_set(DMA_SLAVE | DMA_PRIVATE, mask);
-
-	for (;;) {
-		direction = DMA_MEM_TO_DEV;
-		match = (direction & 0xFF) | XILINX_DMA_IP_DMA |
-				(device_id << XILINX_DMA_DEVICE_ID_SHIFT);
-		pr_debug("dmatest: match is %x\n", match);
-
-		chan = dma_request_channel(mask, xdma_filter, (void *)&match);
-
-		if (chan)
-			pr_debug("dmatest: Found tx device\n");
-		else
-			pr_debug("dmatest: No more tx channels available\n");
-
-		direction = DMA_DEV_TO_MEM;
-		match = (direction & 0xFF) | XILINX_DMA_IP_DMA |
-				(device_id << XILINX_DMA_DEVICE_ID_SHIFT);
-		rx_chan = dma_request_channel(mask, xdma_filter, &match);
-
-		if (rx_chan)
-			pr_debug("dmatest: Found rx device\n");
-		else
-			pr_debug("dmatest: No more rx channels available\n");
-
-		if (chan && rx_chan) {
-			err = dmatest_add_slave_channels(chan, rx_chan);
-			if (err) {
-				dma_release_channel(chan);
-				dma_release_channel(rx_chan);
-			}
-		} else
-			break;
+	return 0;
 
-		device_id++;
-	}
+free_rx:
+	dma_release_channel(rx_chan);
+free_tx:
+	dma_release_channel(chan);
 
 	return err;
 }
-/* when compiled-in wait for drivers to load first */
-late_initcall(dmatest_init);
 
-static void __exit dmatest_exit(void)
+static int xilinx_axidmatest_remove(struct platform_device *pdev)
 {
 	struct dmatest_chan *dtc, *_dtc;
 	struct dma_chan *chan;
@@ -662,12 +634,40 @@ static void __exit dmatest_exit(void)
 		list_del(&dtc->node);
 		chan = dtc->chan;
 		dmatest_cleanup_channel(dtc);
-		pr_debug("dmatest: dropped channel %s\n",
+		pr_info("xilinx_dmatest: dropped channel %s\n",
 			dma_chan_name(chan));
 		dma_release_channel(chan);
 	}
+	return 0;
+}
+
+static const struct of_device_id xilinx_axidmatest_of_ids[] = {
+	{ .compatible = "xlnx,axi-dma-test-1.00.a",},
+	{}
+};
+
+static struct platform_driver xilinx_axidmatest_driver = {
+	.driver = {
+		.name = "xilinx_axidmatest",
+		.owner = THIS_MODULE,
+		.of_match_table = xilinx_axidmatest_of_ids,
+	},
+	.probe = xilinx_axidmatest_probe,
+	.remove = xilinx_axidmatest_remove,
+};
+
+static int __init axidma_init(void)
+{
+	return platform_driver_register(&xilinx_axidmatest_driver);
+
+}
+late_initcall(axidma_init);
+
+static void __exit axidma_exit(void)
+{
+	platform_driver_unregister(&xilinx_axidmatest_driver);
 }
-module_exit(dmatest_exit);
+module_exit(axidma_exit)
 
 MODULE_AUTHOR("Xilinx, Inc.");
 MODULE_DESCRIPTION("Xilinx AXI DMA Test Client");
-- 
2.1.2

