diff mbox

[28/29] mv_xor: add Device Tree binding

Message ID 1353000034-30567-29-git-send-email-thomas.petazzoni@free-electrons.com (mailing list archive)
State New, archived
Headers show

Commit Message

Thomas Petazzoni Nov. 15, 2012, 5:20 p.m. UTC
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: devicetree-discuss@lists.ozlabs.org
---
 Documentation/devicetree/bindings/dma/mv-xor.txt |   40 +++++++++++++++
 drivers/dma/mv_xor.c                             |   57 ++++++++++++++++++++--
 2 files changed, 93 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/mv-xor.txt
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/dma/mv-xor.txt b/Documentation/devicetree/bindings/dma/mv-xor.txt
new file mode 100644
index 0000000..7c6cb7f
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mv-xor.txt
@@ -0,0 +1,40 @@ 
+* Marvell XOR engines
+
+Required properties:
+- compatible: Should be "marvell,orion-xor"
+- reg: Should contain registers location and length (two sets)
+    the first set is the low registers, the second set the high
+    registers for the XOR engine.
+- clocks: pointer to the reference clock
+
+The DT node must also contains sub-nodes for each XOR channel that the
+XOR engine has. Those sub-nodes have the following required
+properties:
+- interrupts: interrupt of the XOR channel
+
+And the following optional properties:
+- dmacap,memcpy to indicate that the XOR channel is capable of memcpy operations
+- dmacap,memset to indicate that the XOR channel is capable of memset operations
+- dmacap,xor to indicate that the XOR channel is capable of xor operations
+
+Example:
+
+xor@d0060900 {
+	compatible = "marvell,orion-xor";
+	reg = <0xd0060900 0x100
+	       0xd0060b00 0x100>;
+	clocks = <&coreclk 0>;
+	status = "okay";
+
+	xor00 {
+	      interrupts = <51>;
+	      dmacap,memcpy;
+	      dmacap,xor;
+	};
+	xor01 {
+	      interrupts = <52>;
+	      dmacap,memcpy;
+	      dmacap,xor;
+	      dmacap,memset;
+	};
+};
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index 71cbb0e..d645d43 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -26,6 +26,8 @@ 
 #include <linux/platform_device.h>
 #include <linux/memory.h>
 #include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
 #include <linux/platform_data/dma-mv_xor.h>
 
 #include "dmaengine.h"
@@ -1278,7 +1280,42 @@  static int mv_xor_probe(struct platform_device *pdev)
 	if (!IS_ERR(xordev->clk))
 		clk_prepare_enable(xordev->clk);
 
-	if (pdata && pdata->channels) {
+	if (pdev->dev.of_node) {
+		struct device_node *np;
+		int i = 0;
+
+		for_each_child_of_node(pdev->dev.of_node, np) {
+			dma_cap_mask_t cap_mask;
+			int irq;
+
+			dma_cap_zero(cap_mask);
+			if (of_property_read_bool(np, "dmacap,memcpy"))
+				dma_cap_set(DMA_MEMCPY, cap_mask);
+			if (of_property_read_bool(np, "dmacap,xor"))
+				dma_cap_set(DMA_XOR, cap_mask);
+			if (of_property_read_bool(np, "dmacap,memset"))
+				dma_cap_set(DMA_MEMSET, cap_mask);
+			if (of_property_read_bool(np, "dmacap,interrupt"))
+				dma_cap_set(DMA_INTERRUPT, cap_mask);
+
+			irq = irq_of_parse_and_map(np, 0);
+			if (irq < 0) {
+				ret = irq;
+				goto err_channel_add;
+			}
+
+			xordev->channels[i] =
+				mv_xor_channel_add(xordev, pdev, i,
+						   cap_mask, irq);
+			if (IS_ERR(xordev->channels[i])) {
+				ret = PTR_ERR(xordev->channels[i]);
+				irq_dispose_mapping(irq);
+				goto err_channel_add;
+			}
+
+			i++;
+		}
+	} else if (pdata && pdata->channels) {
 		for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) {
 			struct mv_xor_channel_data *cd;
 			int irq;
@@ -1309,8 +1346,11 @@  static int mv_xor_probe(struct platform_device *pdev)
 
 err_channel_add:
 	for (i = 0; i < MV_XOR_MAX_CHANNELS; i++)
-		if (xordev->channels[i])
+		if (xordev->channels[i]) {
+			if (pdev->dev.of_node)
+				irq_dispose_mapping(xordev->channels[i]->irq);
 			mv_xor_channel_remove(xordev->channels[i]);
+		}
 
 	clk_disable_unprepare(xordev->clk);
 	clk_put(xordev->clk);
@@ -1335,12 +1375,21 @@  static int mv_xor_remove(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_OF
+static struct of_device_id mv_xor_dt_ids[] __devinitdata = {
+       { .compatible = "marvell,orion-xor", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, mv_xor_dt_ids);
+#endif
+
 static struct platform_driver mv_xor_driver = {
 	.probe		= mv_xor_probe,
 	.remove		= mv_xor_remove,
 	.driver		= {
-		.owner	= THIS_MODULE,
-		.name	= MV_XOR_NAME,
+		.owner	        = THIS_MODULE,
+		.name	        = MV_XOR_NAME,
+		.of_match_table = of_match_ptr(mv_xor_dt_ids),
 	},
 };