aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/common
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/common')
-rw-r--r--arch/arm/common/edma.c186
1 files changed, 173 insertions, 13 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);
1535 r[j] = platform_get_resource_byname(pdev,
1536 IORESOURCE_MEM,
1395 res_name); 1537 res_name);
1396 if (!r[j] || !info[j]) { 1538 }
1539 if (!r[j]) {
1397 if (found) 1540 if (found)
1398 break; 1541 break;
1399 else 1542 else
@@ -1440,7 +1583,7 @@ static int __init edma_probe(struct platform_device *pdev)
1440 off = rsv_chans[i][0]; 1583 off = rsv_chans[i][0];
1441 ln = rsv_chans[i][1]; 1584 ln = rsv_chans[i][1];
1442 clear_bits(off, ln, 1585 clear_bits(off, ln,
1443 edma_cc[j]->edma_unused); 1586 edma_cc[j]->edma_unused);
1444 } 1587 }
1445 } 1588 }
1446 1589
@@ -1456,8 +1599,13 @@ static int __init edma_probe(struct platform_device *pdev)
1456 } 1599 }
1457 } 1600 }
1458 1601
1459 sprintf(irq_name, "edma%d", j); 1602
1460 irq[j] = platform_get_irq_byname(pdev, irq_name); 1603 if (node) {
1604 irq[j] = irq_of_parse_and_map(node, 0);
1605 } else {
1606 sprintf(irq_name, "edma%d", j);
1607 irq[j] = platform_get_irq_byname(pdev, irq_name);
1608 }
1461 edma_cc[j]->irq_res_start = irq[j]; 1609 edma_cc[j]->irq_res_start = irq[j];
1462 status = devm_request_irq(&pdev->dev, irq[j], 1610 status = devm_request_irq(&pdev->dev, irq[j],
1463 dma_irq_handler, 0, "edma", 1611 dma_irq_handler, 0, "edma",
@@ -1469,8 +1617,12 @@ static int __init edma_probe(struct platform_device *pdev)
1469 return status; 1617 return status;
1470 } 1618 }
1471 1619
1472 sprintf(irq_name, "edma%d_err", j); 1620 if (node) {
1473 err_irq[j] = platform_get_irq_byname(pdev, irq_name); 1621 err_irq[j] = irq_of_parse_and_map(node, 2);
1622 } else {
1623 sprintf(irq_name, "edma%d_err", j);
1624 err_irq[j] = platform_get_irq_byname(pdev, irq_name);
1625 }
1474 edma_cc[j]->irq_res_end = err_irq[j]; 1626 edma_cc[j]->irq_res_end = err_irq[j];
1475 status = devm_request_irq(&pdev->dev, err_irq[j], 1627 status = devm_request_irq(&pdev->dev, err_irq[j],
1476 dma_ccerr_handler, 0, 1628 dma_ccerr_handler, 0,
@@ -1516,9 +1668,17 @@ static int __init edma_probe(struct platform_device *pdev)
1516 return 0; 1668 return 0;
1517} 1669}
1518 1670
1671static const struct of_device_id edma_of_ids[] = {
1672 { .compatible = "ti,edma3", },
1673 {}
1674};
1519 1675
1520static struct platform_driver edma_driver = { 1676static struct platform_driver edma_driver = {
1521 .driver.name = "edma", 1677 .driver = {
1678 .name = "edma",
1679 .of_match_table = edma_of_ids,
1680 },
1681 .probe = edma_probe,
1522}; 1682};
1523 1683
1524static int __init edma_init(void) 1684static int __init edma_init(void)