From: Sudhakar Rajashekhara <[email protected]>

Current EDMA driver is not taking care of EDMA channels/slots
which are allocated from other processor, say DSP. If a
channel/slot is allocated from DSP, the existing EDMA driver
can still allocate the same resource on ARM.

This patch enables the user to pass the channel/slots reserved
for DSP as platform data. EDMA driver scans this list during
probe and prepares a bitmap of channel/slots which can be used
on ARM side.

Signed-off-by: Sudhakar Rajashekhara <[email protected]>
Signed-off-by: Sekhar Nori <[email protected]>
Cc: David Brownell <[email protected]>
---
Since v1, the reservation information has been moved to a
seperate structure so it is easier for boards to pass this
information or pass NULL if they are not interested in 
resource reservation at all.

 arch/arm/mach-davinci/dma.c               |   41 ++++++++++++++++++++++++++++-
 arch/arm/mach-davinci/include/mach/edma.h |    9 ++++++
 2 files changed, 49 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
index 260485c..9574e14 100644
--- a/arch/arm/mach-davinci/dma.c
+++ b/arch/arm/mach-davinci/dma.c
@@ -206,6 +206,18 @@ static inline void edma_parm_or(unsigned ctlr, int offset, 
int param_no,
        edma_or(ctlr, EDMA_PARM + offset + (param_no << 5), or);
 }
 
+static inline void set_bits(int offset, int len, unsigned long *p)
+{
+       for (; len > 0; len--)
+               set_bit(offset + (len - 1), p);
+}
+
+static inline void clear_bits(int offset, int len, unsigned long *p)
+{
+       for (; len > 0; len--)
+               clear_bit(offset + (len - 1), p);
+}
+
 /*****************************************************************************/
 
 /* actual number of DMA channels and slots on this silicon */
@@ -1380,8 +1392,10 @@ static int __init edma_probe(struct platform_device 
*pdev)
        struct edma_soc_info    *info = pdev->dev.platform_data;
        const s8                (*queue_priority_mapping)[2];
        const s8                (*queue_tc_mapping)[2];
-       int                     i, j, found = 0;
+       int                     i, j, off, ln, found = 0;
        int                     status = -1;
+       const s16               (*rsv_chans)[2];
+       const s16               (*rsv_slots)[2];
        int                     irq[EDMA_MAX_CC] = {0, 0};
        int                     err_irq[EDMA_MAX_CC] = {0, 0};
        struct resource         *r[EDMA_MAX_CC] = {NULL};
@@ -1448,6 +1462,31 @@ static int __init edma_probe(struct platform_device 
*pdev)
                memset(edma_info[j]->edma_unused, 0xff,
                        sizeof(edma_info[j]->edma_unused));
 
+               if (info[j].rsv) {
+
+                       /* Clear the reserved channels in unused list */
+                       rsv_chans = info[j].rsv->rsv_chans;
+                       if (rsv_chans) {
+                               for (i = 0; rsv_chans[i][0] != -1; i++) {
+                                       off = rsv_chans[i][0];
+                                       ln = rsv_chans[i][1];
+                                       clear_bits(off, ln,
+                                               edma_info[j]->edma_unused);
+                               }
+                       }
+
+                       /* Set the reserved slots in inuse list */
+                       rsv_slots = info[j].rsv->rsv_slots;
+                       if (rsv_slots) {
+                               for (i = 0; rsv_slots[i][0] != -1; i++) {
+                                       off = rsv_slots[i][0];
+                                       ln = rsv_slots[i][1];
+                                       set_bits(off, ln,
+                                               edma_info[j]->edma_inuse);
+                               }
+                       }
+               }
+
                sprintf(irq_name, "edma%d", j);
                irq[j] = platform_get_irq_byname(pdev, irq_name);
                edma_info[j]->irq_res_start = irq[j];
diff --git a/arch/arm/mach-davinci/include/mach/edma.h 
b/arch/arm/mach-davinci/include/mach/edma.h
index ced3092..3983644 100644
--- a/arch/arm/mach-davinci/include/mach/edma.h
+++ b/arch/arm/mach-davinci/include/mach/edma.h
@@ -269,6 +269,12 @@ void edma_clear_event(unsigned channel);
 void edma_pause(unsigned channel);
 void edma_resume(unsigned channel);
 
+struct edma_rsv_info {
+
+       const s16       (*rsv_chans)[2];
+       const s16       (*rsv_slots)[2];
+};
+
 /* platform_data for EDMA driver */
 struct edma_soc_info {
 
@@ -280,6 +286,9 @@ struct edma_soc_info {
        unsigned        n_cc;
        enum dma_event_q        default_queue;
 
+       /* Resource reservation for other cores */
+       struct edma_rsv_info    *rsv;
+
        const s8        (*queue_tc_mapping)[2];
        const s8        (*queue_priority_mapping)[2];
 };
-- 
1.6.2.4

_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to