aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSudhakar Rajashekhara <sudhakar.raj@ti.com>2010-01-06 06:59:49 -0500
committerKevin Hilman <khilman@deeprootsystems.com>2010-02-04 16:30:02 -0500
commitf900d552f95a009e4c4910aff7acbd45f952aa2e (patch)
tree8c326e61d18d65c502414c178d5dc49ca1a020a7
parent447f18f1b4a3e86159353d016dcaac25414b3a42 (diff)
davinci: build list of unused EDMA events dynamically
Currently, the edma_noevent list is passed from platform data. But on some architectures, there will be many EDMA channels which will not be used at all. This patch scans all the platform devices and then builds a list of events which are not being used. The unused event list will be used to allocate EDMA channels in case of EDMA_CHANNEL_ANY usage instead of the edma_noevent being used earlier for this purpose. This patch is based on David Brownells's suggestion at http://article.gmane.org/gmane.linux.davinci/15176. Signed-off-by: Sudhakar Rajashekhara <sudhakar.raj@ti.com> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
-rw-r--r--arch/arm/mach-davinci/devices-da8xx.c6
-rw-r--r--arch/arm/mach-davinci/dm355.c8
-rw-r--r--arch/arm/mach-davinci/dm644x.c10
-rw-r--r--arch/arm/mach-davinci/dm646x.c9
-rw-r--r--arch/arm/mach-davinci/dma.c55
-rw-r--r--arch/arm/mach-davinci/include/mach/edma.h2
6 files changed, 43 insertions, 47 deletions
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 0c759ad0aeee..ab12a8f0d75d 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -83,11 +83,6 @@ struct platform_device da8xx_serial_device = {
83 }, 83 },
84}; 84};
85 85
86static const s8 da8xx_dma_chan_no_event[] = {
87 20, 21,
88 -1
89};
90
91static const s8 da8xx_queue_tc_mapping[][2] = { 86static const s8 da8xx_queue_tc_mapping[][2] = {
92 /* {event queue no, TC no} */ 87 /* {event queue no, TC no} */
93 {0, 0}, 88 {0, 0},
@@ -109,7 +104,6 @@ static struct edma_soc_info da8xx_edma_info[] = {
109 .n_slot = 128, 104 .n_slot = 128,
110 .n_tc = 2, 105 .n_tc = 2,
111 .n_cc = 1, 106 .n_cc = 1,
112 .noevent = da8xx_dma_chan_no_event,
113 .queue_tc_mapping = da8xx_queue_tc_mapping, 107 .queue_tc_mapping = da8xx_queue_tc_mapping,
114 .queue_priority_mapping = da8xx_queue_priority_mapping, 108 .queue_priority_mapping = da8xx_queue_priority_mapping,
115 }, 109 },
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index dedf4d4f3a27..b1185f82ffb3 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -564,13 +564,6 @@ static u8 dm355_default_priorities[DAVINCI_N_AINTC_IRQ] = {
564 564
565/*----------------------------------------------------------------------*/ 565/*----------------------------------------------------------------------*/
566 566
567static const s8 dma_chan_dm355_no_event[] = {
568 12, 13, 24, 56, 57,
569 58, 59, 60, 61, 62,
570 63,
571 -1
572};
573
574static const s8 567static const s8
575queue_tc_mapping[][2] = { 568queue_tc_mapping[][2] = {
576 /* {event queue no, TC no} */ 569 /* {event queue no, TC no} */
@@ -594,7 +587,6 @@ static struct edma_soc_info dm355_edma_info[] = {
594 .n_slot = 128, 587 .n_slot = 128,
595 .n_tc = 2, 588 .n_tc = 2,
596 .n_cc = 1, 589 .n_cc = 1,
597 .noevent = dma_chan_dm355_no_event,
598 .queue_tc_mapping = queue_tc_mapping, 590 .queue_tc_mapping = queue_tc_mapping,
599 .queue_priority_mapping = queue_priority_mapping, 591 .queue_priority_mapping = queue_priority_mapping,
600 }, 592 },
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 2cd008156dea..fc060e7aefdf 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -479,15 +479,6 @@ static u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
479 479
480/*----------------------------------------------------------------------*/ 480/*----------------------------------------------------------------------*/
481 481
482static const s8 dma_chan_dm644x_no_event[] = {
483 0, 1, 12, 13, 14,
484 15, 25, 30, 31, 45,
485 46, 47, 55, 56, 57,
486 58, 59, 60, 61, 62,
487 63,
488 -1
489};
490
491static const s8 482static const s8
492queue_tc_mapping[][2] = { 483queue_tc_mapping[][2] = {
493 /* {event queue no, TC no} */ 484 /* {event queue no, TC no} */
@@ -511,7 +502,6 @@ static struct edma_soc_info dm644x_edma_info[] = {
511 .n_slot = 128, 502 .n_slot = 128,
512 .n_tc = 2, 503 .n_tc = 2,
513 .n_cc = 1, 504 .n_cc = 1,
514 .noevent = dma_chan_dm644x_no_event,
515 .queue_tc_mapping = queue_tc_mapping, 505 .queue_tc_mapping = queue_tc_mapping,
516 .queue_priority_mapping = queue_priority_mapping, 506 .queue_priority_mapping = queue_priority_mapping,
517 }, 507 },
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 515d3edb9a33..7eb34e9253c6 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -511,14 +511,6 @@ static u8 dm646x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
511 511
512/*----------------------------------------------------------------------*/ 512/*----------------------------------------------------------------------*/
513 513
514static const s8 dma_chan_dm646x_no_event[] = {
515 0, 1, 2, 3, 13,
516 14, 15, 24, 25, 26,
517 27, 30, 31, 54, 55,
518 56,
519 -1
520};
521
522/* Four Transfer Controllers on DM646x */ 514/* Four Transfer Controllers on DM646x */
523static const s8 515static const s8
524dm646x_queue_tc_mapping[][2] = { 516dm646x_queue_tc_mapping[][2] = {
@@ -547,7 +539,6 @@ static struct edma_soc_info dm646x_edma_info[] = {
547 .n_slot = 512, 539 .n_slot = 512,
548 .n_tc = 4, 540 .n_tc = 4,
549 .n_cc = 1, 541 .n_cc = 1,
550 .noevent = dma_chan_dm646x_no_event,
551 .queue_tc_mapping = dm646x_queue_tc_mapping, 542 .queue_tc_mapping = dm646x_queue_tc_mapping,
552 .queue_priority_mapping = dm646x_queue_priority_mapping, 543 .queue_priority_mapping = dm646x_queue_priority_mapping,
553 }, 544 },
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
index 89a3dccde19f..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;
@@ -556,8 +556,27 @@ static int reserve_contiguous_slots(int ctlr, unsigned int id,
556 return EDMA_CTLR_CHAN(ctlr, i - num_slots + 1); 556 return EDMA_CTLR_CHAN(ctlr, i - num_slots + 1);
557} 557}
558 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
559/*-----------------------------------------------------------------------*/ 576/*-----------------------------------------------------------------------*/
560 577
578static bool unused_chan_list_done;
579
561/* Resource alloc/free: dma channels, parameter RAM slots */ 580/* Resource alloc/free: dma channels, parameter RAM slots */
562 581
563/** 582/**
@@ -596,6 +615,21 @@ int edma_alloc_channel(int channel,
596 enum dma_event_q eventq_no) 615 enum dma_event_q eventq_no)
597{ 616{
598 unsigned i, done = 0, 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 }
599 633
600 if (channel >= 0) { 634 if (channel >= 0) {
601 ctlr = EDMA_CTLR(channel); 635 ctlr = EDMA_CTLR(channel);
@@ -607,7 +641,7 @@ int edma_alloc_channel(int channel,
607 channel = 0; 641 channel = 0;
608 for (;;) { 642 for (;;) {
609 channel = find_next_bit(edma_info[i]-> 643 channel = find_next_bit(edma_info[i]->
610 edma_noevent, 644 edma_unused,
611 edma_info[i]->num_channels, 645 edma_info[i]->num_channels,
612 channel); 646 channel);
613 if (channel == edma_info[i]->num_channels) 647 if (channel == edma_info[i]->num_channels)
@@ -1222,7 +1256,7 @@ int edma_start(unsigned channel)
1222 unsigned int mask = (1 << (channel & 0x1f)); 1256 unsigned int mask = (1 << (channel & 0x1f));
1223 1257
1224 /* EDMA channels without event association */ 1258 /* EDMA channels without event association */
1225 if (test_bit(channel, edma_info[ctlr]->edma_noevent)) { 1259 if (test_bit(channel, edma_info[ctlr]->edma_unused)) {
1226 pr_debug("EDMA: ESR%d %08x\n", j, 1260 pr_debug("EDMA: ESR%d %08x\n", j,
1227 edma_shadow0_read_array(ctlr, SH_ESR, j)); 1261 edma_shadow0_read_array(ctlr, SH_ESR, j));
1228 edma_shadow0_write_array(ctlr, SH_ESR, j, mask); 1262 edma_shadow0_write_array(ctlr, SH_ESR, j, mask);
@@ -1347,7 +1381,6 @@ static int __init edma_probe(struct platform_device *pdev)
1347 const s8 (*queue_tc_mapping)[2]; 1381 const s8 (*queue_tc_mapping)[2];
1348 int i, j, found = 0; 1382 int i, j, found = 0;
1349 int status = -1; 1383 int status = -1;
1350 const s8 *noevent;
1351 int irq[EDMA_MAX_CC] = {0, 0}; 1384 int irq[EDMA_MAX_CC] = {0, 0};
1352 int err_irq[EDMA_MAX_CC] = {0, 0}; 1385 int err_irq[EDMA_MAX_CC] = {0, 0};
1353 struct resource *r[EDMA_MAX_CC] = {NULL}; 1386 struct resource *r[EDMA_MAX_CC] = {NULL};
@@ -1410,11 +1443,9 @@ static int __init edma_probe(struct platform_device *pdev)
1410 memcpy_toio(edmacc_regs_base[j] + PARM_OFFSET(i), 1443 memcpy_toio(edmacc_regs_base[j] + PARM_OFFSET(i),
1411 &dummy_paramset, PARM_SIZE); 1444 &dummy_paramset, PARM_SIZE);
1412 1445
1413 noevent = info[j].noevent; 1446 /* Mark all channels as unused */
1414 if (noevent) { 1447 memset(edma_info[j]->edma_unused, 0xff,
1415 while (*noevent != -1) 1448 sizeof(edma_info[j]->edma_unused));
1416 set_bit(*noevent++, edma_info[j]->edma_noevent);
1417 }
1418 1449
1419 sprintf(irq_name, "edma%d", j); 1450 sprintf(irq_name, "edma%d", j);
1420 irq[j] = platform_get_irq_byname(pdev, irq_name); 1451 irq[j] = platform_get_irq_byname(pdev, irq_name);
diff --git a/arch/arm/mach-davinci/include/mach/edma.h b/arch/arm/mach-davinci/include/mach/edma.h
index eb8bfd7925e7..ced3092af5ba 100644
--- a/arch/arm/mach-davinci/include/mach/edma.h
+++ b/arch/arm/mach-davinci/include/mach/edma.h
@@ -280,8 +280,6 @@ struct edma_soc_info {
280 unsigned n_cc; 280 unsigned n_cc;
281 enum dma_event_q default_queue; 281 enum dma_event_q default_queue;
282 282
283 /* list of channels with no even trigger; terminated by "-1" */
284 const s8 *noevent;
285 const s8 (*queue_tc_mapping)[2]; 283 const s8 (*queue_tc_mapping)[2];
286 const s8 (*queue_priority_mapping)[2]; 284 const s8 (*queue_priority_mapping)[2];
287}; 285};