aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;
1528 }
1529 if (node) {
1530 ret = of_address_to_resource(node, j, &res[j]);
1531 if (!ret)
1532 r[j] = &res[j];
1533 } else {
1534 sprintf(res_name, "edma_cc%d", j);