Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+94 -4
+40
Documentation/devicetree/bindings/dma/mv-xor.txt
··· 1 + * Marvell XOR engines 2 + 3 + Required properties: 4 + - compatible: Should be "marvell,orion-xor" 5 + - reg: Should contain registers location and length (two sets) 6 + the first set is the low registers, the second set the high 7 + registers for the XOR engine. 8 + - clocks: pointer to the reference clock 9 + 10 + The DT node must also contains sub-nodes for each XOR channel that the 11 + XOR engine has. Those sub-nodes have the following required 12 + properties: 13 + - interrupts: interrupt of the XOR channel 14 + 15 + And the following optional properties: 16 + - dmacap,memcpy to indicate that the XOR channel is capable of memcpy operations 17 + - dmacap,memset to indicate that the XOR channel is capable of memset operations 18 + - dmacap,xor to indicate that the XOR channel is capable of xor operations 19 + 20 + Example: 21 + 22 + xor@d0060900 { 23 + compatible = "marvell,orion-xor"; 24 + reg = <0xd0060900 0x100 25 + 0xd0060b00 0x100>; 26 + clocks = <&coreclk 0>; 27 + status = "okay"; 28 + 29 + xor00 { 30 + interrupts = <51>; 31 + dmacap,memcpy; 32 + dmacap,xor; 33 + }; 34 + xor01 { 35 + interrupts = <52>; 36 + dmacap,memcpy; 37 + dmacap,xor; 38 + dmacap,memset; 39 + }; 40 + };
+54 -4
drivers/dma/mv_xor.c
··· 26 26 #include <linux/platform_device.h> 27 27 #include <linux/memory.h> 28 28 #include <linux/clk.h> 29 + #include <linux/of.h> 30 + #include <linux/of_irq.h> 31 + #include <linux/irqdomain.h> 29 32 #include <linux/platform_data/dma-mv_xor.h> 30 33 31 34 #include "dmaengine.h" ··· 1281 1278 if (!IS_ERR(xordev->clk)) 1282 1279 clk_prepare_enable(xordev->clk); 1283 1280 1284 - if (pdata && pdata->channels) { 1281 + if (pdev->dev.of_node) { 1282 + struct device_node *np; 1283 + int i = 0; 1284 + 1285 + for_each_child_of_node(pdev->dev.of_node, np) { 1286 + dma_cap_mask_t cap_mask; 1287 + int irq; 1288 + 1289 + dma_cap_zero(cap_mask); 1290 + if (of_property_read_bool(np, "dmacap,memcpy")) 1291 + dma_cap_set(DMA_MEMCPY, cap_mask); 1292 + if (of_property_read_bool(np, "dmacap,xor")) 1293 + dma_cap_set(DMA_XOR, cap_mask); 1294 + if (of_property_read_bool(np, "dmacap,memset")) 1295 + dma_cap_set(DMA_MEMSET, cap_mask); 1296 + if (of_property_read_bool(np, "dmacap,interrupt")) 1297 + dma_cap_set(DMA_INTERRUPT, cap_mask); 1298 + 1299 + irq = irq_of_parse_and_map(np, 0); 1300 + if (irq < 0) { 1301 + ret = irq; 1302 + goto err_channel_add; 1303 + } 1304 + 1305 + xordev->channels[i] = 1306 + mv_xor_channel_add(xordev, pdev, i, 1307 + cap_mask, irq); 1308 + if (IS_ERR(xordev->channels[i])) { 1309 + ret = PTR_ERR(xordev->channels[i]); 1310 + irq_dispose_mapping(irq); 1311 + goto err_channel_add; 1312 + } 1313 + 1314 + i++; 1315 + } 1316 + } else if (pdata && pdata->channels) { 1285 1317 for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) { 1286 1318 struct mv_xor_channel_data *cd; 1287 1319 int irq; ··· 1347 1309 1348 1310 err_channel_add: 1349 1311 for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) 1350 - if (xordev->channels[i]) 1312 + if (xordev->channels[i]) { 1313 + if (pdev->dev.of_node) 1314 + irq_dispose_mapping(xordev->channels[i]->irq); 1351 1315 mv_xor_channel_remove(xordev->channels[i]); 1316 + } 1352 1317 1353 1318 clk_disable_unprepare(xordev->clk); 1354 1319 clk_put(xordev->clk); ··· 1376 1335 return 0; 1377 1336 } 1378 1337 1338 + #ifdef CONFIG_OF 1339 + static struct of_device_id mv_xor_dt_ids[] __devinitdata = { 1340 + { .compatible = "marvell,orion-xor", }, 1341 + {}, 1342 + }; 1343 + MODULE_DEVICE_TABLE(of, mv_xor_dt_ids); 1344 + #endif 1345 + 1379 1346 static struct platform_driver mv_xor_driver = { 1380 1347 .probe = mv_xor_probe, 1381 1348 .remove = mv_xor_remove, 1382 1349 .driver = { 1383 - .owner = THIS_MODULE, 1384 - .name = MV_XOR_NAME, 1350 + .owner = THIS_MODULE, 1351 + .name = MV_XOR_NAME, 1352 + .of_match_table = of_match_ptr(mv_xor_dt_ids), 1385 1353 }, 1386 1354 }; 1387 1355