aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-davinci/dma.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-03-01 16:05:40 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-01 16:05:40 -0500
commit13dda80e48439b446d0bc9bab34b91484bc8f533 (patch)
treee8037122d65fe2a5dd8f633a7648b2597640a2ce /arch/arm/mach-davinci/dma.c
parent379e3a820da171cb1d97e8dccd736a69cebfb7c0 (diff)
parent5f19daa16ffca55db5b0253eba2bd0f71ee7f7f4 (diff)
Merge branch 'davinci-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci
* 'davinci-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci: (40 commits) DaVinci DM365: Adding support for SPI EEPROM DaVinci DM365: Adding DM365 SPI support DaVinci DM355: Modifications to DM355 SPI support DaVinci: SPI: Adding header file for SPI support. davinci: dm646x: CDCE clocks: davinci_clk converted to clk_lookup davinci: clkdev cleanup: remove clk_lookup wrapper, use clkdev_add_table() DaVinci: DM365: Voice codec support for the DM365 SoC davinci: clock: let clk->set_rate function sleep Add SDA and SCL pin numbers to i2c platform data davinci: da8xx/omap-l1xx: Add EDMA platform data for da850/omap-l138 davinci: build list of unused EDMA events dynamically davinci: Fix edma_alloc_channel api for EDMA_CHANNEL_ANY case davinci: Keep count of channel controllers on a platform davinci: Correct return value of edma_alloc_channel api davinci: add CDCE949 support on DM6467 EVM davinci: add support for CDCE949 clock synthesizer davinci: da850/omap-l138 EVM: register for suspend support davinci: da850/omap-l138: add support for SoC suspend davinci: add power management support DaVinci: DM365: Changing default queue for DM365. ...
Diffstat (limited to 'arch/arm/mach-davinci/dma.c')
-rw-r--r--arch/arm/mach-davinci/dma.c67
1 files changed, 51 insertions, 16 deletions
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
index 648fbb760ae1..15dd886df04c 100644
--- a/arch/arm/mach-davinci/dma.c
+++ b/arch/arm/mach-davinci/dma.c
@@ -226,11 +226,11 @@ struct edma {
226 */ 226 */
227 DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY); 227 DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY);
228 228
229 /* The edma_noevent bit for each channel is clear unless 229 /* The edma_unused bit for each channel is clear unless
230 * it doesn't trigger DMA events on this platform. It uses a 230 * it is not being used on this platform. It uses a bit
231 * bit of SOC-specific initialization code. 231 * of SOC-specific initialization code.
232 */ 232 */
233 DECLARE_BITMAP(edma_noevent, EDMA_MAX_DMACH); 233 DECLARE_BITMAP(edma_unused, EDMA_MAX_DMACH);
234 234
235 unsigned irq_res_start; 235 unsigned irq_res_start;
236 unsigned irq_res_end; 236 unsigned irq_res_end;
@@ -243,6 +243,7 @@ struct edma {
243}; 243};
244 244
245static struct edma *edma_info[EDMA_MAX_CC]; 245static struct edma *edma_info[EDMA_MAX_CC];
246static int arch_num_cc;
246 247
247/* dummy param set used to (re)initialize parameter RAM slots */ 248/* dummy param set used to (re)initialize parameter RAM slots */
248static const struct edmacc_param dummy_paramset = { 249static const struct edmacc_param dummy_paramset = {
@@ -555,8 +556,27 @@ static int reserve_contiguous_slots(int ctlr, unsigned int id,
555 return EDMA_CTLR_CHAN(ctlr, i - num_slots + 1); 556 return EDMA_CTLR_CHAN(ctlr, i - num_slots + 1);
556} 557}
557 558
559static int prepare_unused_channel_list(struct device *dev, void *data)
560{
561 struct platform_device *pdev = to_platform_device(dev);
562 int i, ctlr;
563
564 for (i = 0; i < pdev->num_resources; i++) {
565 if ((pdev->resource[i].flags & IORESOURCE_DMA) &&
566 (int)pdev->resource[i].start >= 0) {
567 ctlr = EDMA_CTLR(pdev->resource[i].start);
568 clear_bit(EDMA_CHAN_SLOT(pdev->resource[i].start),
569 edma_info[ctlr]->edma_unused);
570 }
571 }
572
573 return 0;
574}
575
558/*-----------------------------------------------------------------------*/ 576/*-----------------------------------------------------------------------*/
559 577
578static bool unused_chan_list_done;
579
560/* Resource alloc/free: dma channels, parameter RAM slots */ 580/* Resource alloc/free: dma channels, parameter RAM slots */
561 581
562/** 582/**
@@ -594,7 +614,22 @@ int edma_alloc_channel(int channel,
594 void *data, 614 void *data,
595 enum dma_event_q eventq_no) 615 enum dma_event_q eventq_no)
596{ 616{
597 unsigned i, done, ctlr = 0; 617 unsigned i, done = 0, ctlr = 0;
618 int ret = 0;
619
620 if (!unused_chan_list_done) {
621 /*
622 * Scan all the platform devices to find out the EDMA channels
623 * used and clear them in the unused list, making the rest
624 * available for ARM usage.
625 */
626 ret = bus_for_each_dev(&platform_bus_type, NULL, NULL,
627 prepare_unused_channel_list);
628 if (ret < 0)
629 return ret;
630
631 unused_chan_list_done = true;
632 }
598 633
599 if (channel >= 0) { 634 if (channel >= 0) {
600 ctlr = EDMA_CTLR(channel); 635 ctlr = EDMA_CTLR(channel);
@@ -602,15 +637,15 @@ int edma_alloc_channel(int channel,
602 } 637 }
603 638
604 if (channel < 0) { 639 if (channel < 0) {
605 for (i = 0; i < EDMA_MAX_CC; i++) { 640 for (i = 0; i < arch_num_cc; i++) {
606 channel = 0; 641 channel = 0;
607 for (;;) { 642 for (;;) {
608 channel = find_next_bit(edma_info[i]-> 643 channel = find_next_bit(edma_info[i]->
609 edma_noevent, 644 edma_unused,
610 edma_info[i]->num_channels, 645 edma_info[i]->num_channels,
611 channel); 646 channel);
612 if (channel == edma_info[i]->num_channels) 647 if (channel == edma_info[i]->num_channels)
613 return -ENOMEM; 648 break;
614 if (!test_and_set_bit(channel, 649 if (!test_and_set_bit(channel,
615 edma_info[i]->edma_inuse)) { 650 edma_info[i]->edma_inuse)) {
616 done = 1; 651 done = 1;
@@ -622,6 +657,8 @@ int edma_alloc_channel(int channel,
622 if (done) 657 if (done)
623 break; 658 break;
624 } 659 }
660 if (!done)
661 return -ENOMEM;
625 } else if (channel >= edma_info[ctlr]->num_channels) { 662 } else if (channel >= edma_info[ctlr]->num_channels) {
626 return -EINVAL; 663 return -EINVAL;
627 } else if (test_and_set_bit(channel, edma_info[ctlr]->edma_inuse)) { 664 } else if (test_and_set_bit(channel, edma_info[ctlr]->edma_inuse)) {
@@ -642,7 +679,7 @@ int edma_alloc_channel(int channel,
642 679
643 map_dmach_queue(ctlr, channel, eventq_no); 680 map_dmach_queue(ctlr, channel, eventq_no);
644 681
645 return channel; 682 return EDMA_CTLR_CHAN(ctlr, channel);
646} 683}
647EXPORT_SYMBOL(edma_alloc_channel); 684EXPORT_SYMBOL(edma_alloc_channel);
648 685
@@ -1219,7 +1256,7 @@ int edma_start(unsigned channel)
1219 unsigned int mask = (1 << (channel & 0x1f)); 1256 unsigned int mask = (1 << (channel & 0x1f));
1220 1257
1221 /* EDMA channels without event association */ 1258 /* EDMA channels without event association */
1222 if (test_bit(channel, edma_info[ctlr]->edma_noevent)) { 1259 if (test_bit(channel, edma_info[ctlr]->edma_unused)) {
1223 pr_debug("EDMA: ESR%d %08x\n", j, 1260 pr_debug("EDMA: ESR%d %08x\n", j,
1224 edma_shadow0_read_array(ctlr, SH_ESR, j)); 1261 edma_shadow0_read_array(ctlr, SH_ESR, j));
1225 edma_shadow0_write_array(ctlr, SH_ESR, j, mask); 1262 edma_shadow0_write_array(ctlr, SH_ESR, j, mask);
@@ -1344,7 +1381,6 @@ static int __init edma_probe(struct platform_device *pdev)
1344 const s8 (*queue_tc_mapping)[2]; 1381 const s8 (*queue_tc_mapping)[2];
1345 int i, j, found = 0; 1382 int i, j, found = 0;
1346 int status = -1; 1383 int status = -1;
1347 const s8 *noevent;
1348 int irq[EDMA_MAX_CC] = {0, 0}; 1384 int irq[EDMA_MAX_CC] = {0, 0};
1349 int err_irq[EDMA_MAX_CC] = {0, 0}; 1385 int err_irq[EDMA_MAX_CC] = {0, 0};
1350 struct resource *r[EDMA_MAX_CC] = {NULL}; 1386 struct resource *r[EDMA_MAX_CC] = {NULL};
@@ -1407,11 +1443,9 @@ static int __init edma_probe(struct platform_device *pdev)
1407 memcpy_toio(edmacc_regs_base[j] + PARM_OFFSET(i), 1443 memcpy_toio(edmacc_regs_base[j] + PARM_OFFSET(i),
1408 &dummy_paramset, PARM_SIZE); 1444 &dummy_paramset, PARM_SIZE);
1409 1445
1410 noevent = info[j].noevent; 1446 /* Mark all channels as unused */
1411 if (noevent) { 1447 memset(edma_info[j]->edma_unused, 0xff,
1412 while (*noevent != -1) 1448 sizeof(edma_info[j]->edma_unused));
1413 set_bit(*noevent++, edma_info[j]->edma_noevent);
1414 }
1415 1449
1416 sprintf(irq_name, "edma%d", j); 1450 sprintf(irq_name, "edma%d", j);
1417 irq[j] = platform_get_irq_byname(pdev, irq_name); 1451 irq[j] = platform_get_irq_byname(pdev, irq_name);
@@ -1467,6 +1501,7 @@ static int __init edma_probe(struct platform_device *pdev)
1467 edma_write_array2(j, EDMA_DRAE, i, 1, 0x0); 1501 edma_write_array2(j, EDMA_DRAE, i, 1, 0x0);
1468 edma_write_array(j, EDMA_QRAE, i, 0x0); 1502 edma_write_array(j, EDMA_QRAE, i, 0x0);
1469 } 1503 }
1504 arch_num_cc++;
1470 } 1505 }
1471 1506
1472 if (tc_errs_handled) { 1507 if (tc_errs_handled) {