aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Porter <mporter@ti.com>2013-06-20 17:06:38 -0400
committerSekhar Nori <nsekhar@ti.com>2013-06-24 04:38:26 -0400
commit6cba4355066bda19f14d4da66b8abbca0ffdfd59 (patch)
tree0c9fea0669bf397c8b22dcbcff1b567817bf9050
parentbf3156dde3b6718e843152e826a493f80b973655 (diff)
ARM: edma: Add DT and runtime PM support to the private EDMA API
Adds support for parsing the TI EDMA DT data into the required EDMA private API platform data. Enables runtime PM support to initialize the EDMA hwmod. Enables build on OMAP. Changes by Joel: * Setup default one-to-one mapping for queue_priority and queue_tc mapping as discussed in [1]. * Split out xbar stuff to separate patch. [1] * Dropped unused DT helper to convert to array * Fixed dangling pointer issue with Sekhar's changes [1] https://patchwork.kernel.org/patch/2226761/ Signed-off-by: Matt Porter <mporter@ti.com> [nsekhar@ti.com: fix checkpatch errors, build breakages. Introduce edma_setup_info_from_dt() as part of that effort] Signed-off-by: Joel A Fernandes <joelagnel@ti.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Sekhar Nori <nsekhar@ti.com>
-rw-r--r--arch/arm/common/edma.c186
-rw-r--r--arch/arm/mach-davinci/devices-da8xx.c8
-rw-r--r--arch/arm/mach-davinci/devices-tnetv107x.c4
-rw-r--r--arch/arm/mach-davinci/dm355.c4
-rw-r--r--arch/arm/mach-davinci/dm365.c4
-rw-r--r--arch/arm/mach-davinci/dm644x.c4
-rw-r--r--arch/arm/mach-davinci/dm646x.c4
-rw-r--r--include/linux/platform_data/edma.h4
8 files changed, 189 insertions, 29 deletions
diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c
index 7658874cc3d5..5183a310657c 100644
--- a/arch/arm/common/edma.c
+++ b/arch/arm/common/edma.c
@@ -25,6 +25,13 @@
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/edma.h>
29#include <linux/err.h>
30#include <linux/of_address.h>
31#include <linux/of_device.h>
32#include <linux/of_dma.h>
33#include <linux/of_irq.h>
34#include <linux/pm_runtime.h>
28 35
29#include <linux/platform_data/edma.h> 36#include <linux/platform_data/edma.h>
30 37
@@ -1369,13 +1376,110 @@ void edma_clear_event(unsigned channel)
1369} 1376}
1370EXPORT_SYMBOL(edma_clear_event); 1377EXPORT_SYMBOL(edma_clear_event);
1371 1378
1372/*-----------------------------------------------------------------------*/ 1379#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DMADEVICES)
1380
1381static int edma_of_parse_dt(struct device *dev,
1382 struct device_node *node,
1383 struct edma_soc_info *pdata)
1384{
1385 int ret = 0, i;
1386 u32 value;
1387 struct edma_rsv_info *rsv_info;
1388 s8 (*queue_tc_map)[2], (*queue_priority_map)[2];
1389
1390 memset(pdata, 0, sizeof(struct edma_soc_info));
1391
1392 ret = of_property_read_u32(node, "dma-channels", &value);
1393 if (ret < 0)
1394 return ret;
1395 pdata->n_channel = value;
1396
1397 ret = of_property_read_u32(node, "ti,edma-regions", &value);
1398 if (ret < 0)
1399 return ret;
1400 pdata->n_region = value;
1401
1402 ret = of_property_read_u32(node, "ti,edma-slots", &value);
1403 if (ret < 0)
1404 return ret;
1405 pdata->n_slot = value;
1406
1407 pdata->n_cc = 1;
1408
1409 rsv_info = devm_kzalloc(dev, sizeof(struct edma_rsv_info), GFP_KERNEL);
1410 if (!rsv_info)
1411 return -ENOMEM;
1412 pdata->rsv = rsv_info;
1413
1414 queue_tc_map = devm_kzalloc(dev, 8*sizeof(s8), GFP_KERNEL);
1415 if (!queue_tc_map)
1416 return -ENOMEM;
1417
1418 for (i = 0; i < 3; i++) {
1419 queue_tc_map[i][0] = i;
1420 queue_tc_map[i][1] = i;
1421 }
1422 queue_tc_map[i][0] = -1;
1423 queue_tc_map[i][1] = -1;
1424
1425 pdata->queue_tc_mapping = queue_tc_map;
1426
1427 queue_priority_map = devm_kzalloc(dev, 8*sizeof(s8), GFP_KERNEL);
1428 if (!queue_priority_map)
1429 return -ENOMEM;
1430
1431 for (i = 0; i < 3; i++) {
1432 queue_priority_map[i][0] = i;
1433 queue_priority_map[i][1] = i;
1434 }
1435 queue_priority_map[i][0] = -1;
1436 queue_priority_map[i][1] = -1;
1437
1438 pdata->queue_priority_mapping = queue_priority_map;
1439
1440 pdata->default_queue = 0;
1373 1441
1374static int __init edma_probe(struct platform_device *pdev) 1442 return ret;
1443}
1444
1445static struct of_dma_filter_info edma_filter_info = {
1446 .filter_fn = edma_filter_fn,
1447};
1448
1449static struct edma_soc_info *edma_setup_info_from_dt(struct device *dev,
1450 struct device_node *node)
1451{
1452 struct edma_soc_info *info;
1453 int ret;
1454
1455 info = devm_kzalloc(dev, sizeof(struct edma_soc_info), GFP_KERNEL);
1456 if (!info)
1457 return ERR_PTR(-ENOMEM);
1458
1459 ret = edma_of_parse_dt(dev, node, info);
1460 if (ret)
1461 return ERR_PTR(ret);
1462
1463 dma_cap_set(DMA_SLAVE, edma_filter_info.dma_cap);
1464 of_dma_controller_register(dev->of_node, of_dma_simple_xlate,
1465 &edma_filter_info);
1466
1467 return info;
1468}
1469#else
1470static struct edma_soc_info *edma_setup_info_from_dt(struct device *dev,
1471 struct device_node *node)
1472{
1473 return ERR_PTR(-ENOSYS);
1474}
1475#endif
1476
1477static int edma_probe(struct platform_device *pdev)
1375{ 1478{
1376 struct edma_soc_info **info = pdev->dev.platform_data; 1479 struct edma_soc_info **info = pdev->dev.platform_data;
1377 const s8 (*queue_priority_mapping)[2]; 1480 struct edma_soc_info *ninfo[EDMA_MAX_CC] = {NULL};
1378 const s8 (*queue_tc_mapping)[2]; 1481 s8 (*queue_priority_mapping)[2];
1482 s8 (*queue_tc_mapping)[2];
1379 int i, j, off, ln, found = 0; 1483 int i, j, off, ln, found = 0;
1380 int status = -1; 1484 int status = -1;
1381 const s16 (*rsv_chans)[2]; 1485 const s16 (*rsv_chans)[2];
@@ -1383,17 +1487,56 @@ static int __init edma_probe(struct platform_device *pdev)
1383 int irq[EDMA_MAX_CC] = {0, 0}; 1487 int irq[EDMA_MAX_CC] = {0, 0};
1384 int err_irq[EDMA_MAX_CC] = {0, 0}; 1488 int err_irq[EDMA_MAX_CC] = {0, 0};
1385 struct resource *r[EDMA_MAX_CC] = {NULL}; 1489 struct resource *r[EDMA_MAX_CC] = {NULL};
1490 struct resource res[EDMA_MAX_CC];
1386 char res_name[10]; 1491 char res_name[10];
1387 char irq_name[10]; 1492 char irq_name[10];
1493 struct device_node *node = pdev->dev.of_node;
1494 struct device *dev = &pdev->dev;
1495 int ret;
1496
1497 if (node) {
1498 /* Check if this is a second instance registered */
1499 if (arch_num_cc) {
1500 dev_err(dev, "only one EDMA instance is supported via DT\n");
1501 return -ENODEV;
1502 }
1503
1504 ninfo[0] = edma_setup_info_from_dt(dev, node);
1505 if (IS_ERR(ninfo[0])) {
1506 dev_err(dev, "failed to get DT data\n");
1507 return PTR_ERR(ninfo[0]);
1508 }
1509
1510 info = ninfo;
1511 }
1388 1512
1389 if (!info) 1513 if (!info)
1390 return -ENODEV; 1514 return -ENODEV;
1391 1515
1516 pm_runtime_enable(dev);
1517 ret = pm_runtime_get_sync(dev);
1518 if (ret < 0) {
1519 dev_err(dev, "pm_runtime_get_sync() failed\n");
1520 return ret;
1521 }
1522
1392 for (j = 0; j < EDMA_MAX_CC; j++) { 1523 for (j = 0; j < EDMA_MAX_CC; j++) {
1393 sprintf(res_name, "edma_cc%d", j); 1524 if (!info[j]) {
1394 r[j] = platform_get_resource_byname(pdev, IORESOURCE_MEM, 1525 if (!found)
1526 return -ENODEV;
1527 break;