diff options
author | Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | 2012-11-15 19:47:58 +0400 |
---|---|---|
committer | Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | 2012-11-20 18:59:00 +0400 |
commit | f7d12ef53ddfd8175933af42bfc477376d19e19e (patch) | |
tree | b4fa58b8dfd5003e9fd182fc1e01b66654f18bf3 | |
parent | 88eb92cb4d0a1520c2f9a653fba0f838871af3ab (diff) | |
download | linux-f7d12ef53ddfd8175933af42bfc477376d19e19e.tar.xz |
dma: mv_xor: add Device Tree binding
This patch finally adds a Device Tree binding to the mv_xor
driver. Thanks to the previous cleanup patches, the Device Tree
binding is relatively simply: one DT node per XOR engine, with
sub-nodes for each XOR channel of the XOR engine. The binding
obviously comes with the necessary documentation.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: devicetree-discuss@lists.ozlabs.org
-rw-r--r-- | Documentation/devicetree/bindings/dma/mv-xor.txt | 40 | ||||
-rw-r--r-- | drivers/dma/mv_xor.c | 58 |
2 files changed, 94 insertions, 4 deletions
diff --git a/Documentation/devicetree/bindings/dma/mv-xor.txt b/Documentation/devicetree/bindings/dma/mv-xor.txt new file mode 100644 index 000000000000..7c6cb7fcecd2 --- /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 d48245c0b0b0..b1c4edd56ebc 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -26,6 +26,9 @@ #include <linux/platform_device.h> #include <linux/memory.h> #include <linux/clk.h> +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/irqdomain.h> #include <linux/platform_data/dma-mv_xor.h> #include "dmaengine.h" @@ -1278,7 +1281,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 +1347,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 +1376,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), }, }; |