diff options
Diffstat (limited to 'arch/arm/mach-davinci/dma.c')
| -rw-r--r-- | arch/arm/mach-davinci/dma.c | 62 |
1 files changed, 50 insertions, 12 deletions
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c index d33827aadda7..2ede598b77dd 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/mach-davinci/dma.c | |||
| @@ -99,8 +99,6 @@ | |||
| 99 | 99 | ||
| 100 | #define EDMA_MAX_DMACH 64 | 100 | #define EDMA_MAX_DMACH 64 |
| 101 | #define EDMA_MAX_PARAMENTRY 512 | 101 | #define EDMA_MAX_PARAMENTRY 512 |
| 102 | #define EDMA_MAX_CC 2 | ||
| 103 | |||
| 104 | 102 | ||
| 105 | /*****************************************************************************/ | 103 | /*****************************************************************************/ |
| 106 | 104 | ||
| @@ -207,6 +205,18 @@ static inline void edma_parm_or(unsigned ctlr, int offset, int param_no, | |||
| 207 | edma_or(ctlr, EDMA_PARM + offset + (param_no << 5), or); | 205 | edma_or(ctlr, EDMA_PARM + offset + (param_no << 5), or); |
| 208 | } | 206 | } |
| 209 | 207 | ||
| 208 | static inline void set_bits(int offset, int len, unsigned long *p) | ||
| 209 | { | ||
| 210 | for (; len > 0; len--) | ||
| 211 | set_bit(offset + (len - 1), p); | ||
| 212 | } | ||
| 213 | |||
| 214 | static inline void clear_bits(int offset, int len, unsigned long *p) | ||
| 215 | { | ||
| 216 | for (; len > 0; len--) | ||
| 217 | clear_bit(offset + (len - 1), p); | ||
| 218 | } | ||
| 219 | |||
| 210 | /*****************************************************************************/ | 220 | /*****************************************************************************/ |
| 211 | 221 | ||
| 212 | /* actual number of DMA channels and slots on this silicon */ | 222 | /* actual number of DMA channels and slots on this silicon */ |
| @@ -1376,11 +1386,13 @@ EXPORT_SYMBOL(edma_clear_event); | |||
| 1376 | 1386 | ||
| 1377 | static int __init edma_probe(struct platform_device *pdev) | 1387 | static int __init edma_probe(struct platform_device *pdev) |
| 1378 | { | 1388 | { |
| 1379 | struct edma_soc_info *info = pdev->dev.platform_data; | 1389 | struct edma_soc_info **info = pdev->dev.platform_data; |
| 1380 | const s8 (*queue_priority_mapping)[2]; | 1390 | const s8 (*queue_priority_mapping)[2]; |
| 1381 | const s8 (*queue_tc_mapping)[2]; | 1391 | const s8 (*queue_tc_mapping)[2]; |
| 1382 | int i, j, found = 0; | 1392 | int i, j, off, ln, found = 0; |
| 1383 | int status = -1; | 1393 | int status = -1; |
| 1394 | const s16 (*rsv_chans)[2]; | ||
| 1395 | const s16 (*rsv_slots)[2]; | ||
| 1384 | int irq[EDMA_MAX_CC] = {0, 0}; | 1396 | int irq[EDMA_MAX_CC] = {0, 0}; |
| 1385 | int err_irq[EDMA_MAX_CC] = {0, 0}; | 1397 | int err_irq[EDMA_MAX_CC] = {0, 0}; |
| 1386 | struct resource *r[EDMA_MAX_CC] = {NULL}; | 1398 | struct resource *r[EDMA_MAX_CC] = {NULL}; |
| @@ -1395,7 +1407,7 @@ static int __init edma_probe(struct platform_device *pdev) | |||
| 1395 | sprintf(res_name, "edma_cc%d", j); | 1407 | sprintf(res_name, "edma_cc%d", j); |
| 1396 | r[j] = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 1408 | r[j] = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
| 1397 | res_name); | 1409 | res_name); |
| 1398 | if (!r[j]) { | 1410 | if (!r[j] || !info[j]) { |
| 1399 | if (found) | 1411 | if (found) |
| 1400 | break; | 1412 | break; |
| 1401 | else | 1413 | else |
| @@ -1426,13 +1438,14 @@ static int __init edma_probe(struct platform_device *pdev) | |||
| 1426 | } | 1438 | } |
| 1427 | memset(edma_cc[j], 0, sizeof(struct edma)); | 1439 | memset(edma_cc[j], 0, sizeof(struct edma)); |
| 1428 | 1440 | ||
| 1429 | edma_cc[j]->num_channels = min_t(unsigned, info[j].n_channel, | 1441 | edma_cc[j]->num_channels = min_t(unsigned, info[j]->n_channel, |
| 1430 | EDMA_MAX_DMACH); | 1442 | EDMA_MAX_DMACH); |
| 1431 | edma_cc[j]->num_slots = min_t(unsigned, info[j].n_slot, | 1443 | edma_cc[j]->num_slots = min_t(unsigned, info[j]->n_slot, |
| 1432 | EDMA_MAX_PARAMENTRY); | 1444 | EDMA_MAX_PARAMENTRY); |
| 1433 | edma_cc[j]->num_cc = min_t(unsigned, info[j].n_cc, EDMA_MAX_CC); | 1445 | edma_cc[j]->num_cc = min_t(unsigned, info[j]->n_cc, |
| 1446 | EDMA_MAX_CC); | ||
| 1434 | 1447 | ||
| 1435 | edma_cc[j]->default_queue = info[j].default_queue; | 1448 | edma_cc[j]->default_queue = info[j]->default_queue; |
| 1436 | if (!edma_cc[j]->default_queue) | 1449 | if (!edma_cc[j]->default_queue) |
| 1437 | edma_cc[j]->default_queue = EVENTQ_1; | 1450 | edma_cc[j]->default_queue = EVENTQ_1; |
| 1438 | 1451 | ||
| @@ -1447,6 +1460,31 @@ static int __init edma_probe(struct platform_device *pdev) | |||
| 1447 | memset(edma_cc[j]->edma_unused, 0xff, | 1460 | memset(edma_cc[j]->edma_unused, 0xff, |
| 1448 | sizeof(edma_cc[j]->edma_unused)); | 1461 | sizeof(edma_cc[j]->edma_unused)); |
| 1449 | 1462 | ||
| 1463 | if (info[j]->rsv) { | ||
| 1464 | |||
| 1465 | /* Clear the reserved channels in unused list */ | ||
| 1466 | rsv_chans = info[j]->rsv->rsv_chans; | ||
| 1467 | if (rsv_chans) { | ||
| 1468 | for (i = 0; rsv_chans[i][0] != -1; i++) { | ||
| 1469 | off = rsv_chans[i][0]; | ||
| 1470 | ln = rsv_chans[i][1]; | ||
| 1471 | clear_bits(off, ln, | ||
| 1472 | edma_cc[j]->edma_unused); | ||
| 1473 | } | ||
| 1474 | } | ||
| 1475 | |||
| 1476 | /* Set the reserved slots in inuse list */ | ||
| 1477 | rsv_slots = info[j]->rsv->rsv_slots; | ||
| 1478 | if (rsv_slots) { | ||
| 1479 | for (i = 0; rsv_slots[i][0] != -1; i++) { | ||
| 1480 | off = rsv_slots[i][0]; | ||
| 1481 | ln = rsv_slots[i][1]; | ||
| 1482 | set_bits(off, ln, | ||
| 1483 | edma_cc[j]->edma_inuse); | ||
| 1484 | } | ||
| 1485 | } | ||
| 1486 | } | ||
| 1487 | |||
| 1450 | sprintf(irq_name, "edma%d", j); | 1488 | sprintf(irq_name, "edma%d", j); |
| 1451 | irq[j] = platform_get_irq_byname(pdev, irq_name); | 1489 | irq[j] = platform_get_irq_byname(pdev, irq_name); |
| 1452 | edma_cc[j]->irq_res_start = irq[j]; | 1490 | edma_cc[j]->irq_res_start = irq[j]; |
| @@ -1476,8 +1514,8 @@ static int __init edma_probe(struct platform_device *pdev) | |||
| 1476 | for (i = 0; i < edma_cc[j]->num_channels; i++) | 1514 | for (i = 0; i < edma_cc[j]->num_channels; i++) |
| 1477 | map_dmach_queue(j, i, EVENTQ_1); | 1515 | map_dmach_queue(j, i, EVENTQ_1); |
| 1478 | 1516 | ||
| 1479 | queue_tc_mapping = info[j].queue_tc_mapping; | 1517 | queue_tc_mapping = info[j]->queue_tc_mapping; |
| 1480 | queue_priority_mapping = info[j].queue_priority_mapping; | 1518 | queue_priority_mapping = info[j]->queue_priority_mapping; |
| 1481 | 1519 | ||
| 1482 | /* Event queue to TC mapping */ | 1520 | /* Event queue to TC mapping */ |
| 1483 | for (i = 0; queue_tc_mapping[i][0] != -1; i++) | 1521 | for (i = 0; queue_tc_mapping[i][0] != -1; i++) |
| @@ -1496,7 +1534,7 @@ static int __init edma_probe(struct platform_device *pdev) | |||
| 1496 | if (edma_read(j, EDMA_CCCFG) & CHMAP_EXIST) | 1534 | if (edma_read(j, EDMA_CCCFG) & CHMAP_EXIST) |
| 1497 | map_dmach_param(j); | 1535 | map_dmach_param(j); |
| 1498 | 1536 | ||
| 1499 | for (i = 0; i < info[j].n_region; i++) { | 1537 | for (i = 0; i < info[j]->n_region; i++) { |
| 1500 | edma_write_array2(j, EDMA_DRAE, i, 0, 0x0); | 1538 | edma_write_array2(j, EDMA_DRAE, i, 0, 0x0); |
| 1501 | edma_write_array2(j, EDMA_DRAE, i, 1, 0x0); | 1539 | edma_write_array2(j, EDMA_DRAE, i, 1, 0x0); |
| 1502 | edma_write_array(j, EDMA_QRAE, i, 0x0); | 1540 | edma_write_array(j, EDMA_QRAE, i, 0x0); |
