Define a structure to store EDMA channel controller based information.
Use platform_device.id to find out the instance being configured in
probe function.

Signed-off-by: Sudhakar Rajashekhara <[email protected]>
---
 arch/arm/mach-davinci/dm355.c             |    5 +-
 arch/arm/mach-davinci/dm644x.c            |    5 +-
 arch/arm/mach-davinci/dma.c               |   86 ++++++++++++++++++----------
 arch/arm/mach-davinci/include/mach/edma.h |    1 +
 4 files changed, 62 insertions(+), 35 deletions(-)

diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 497a65d..96bbd7c 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -561,12 +561,13 @@ static struct edma_soc_info dm355_edma_info = {
        .n_region       = 4,
        .n_slot         = 128,
        .n_tc           = 2,
+       .n_cc           = 1,
        .noevent        = dma_chan_dm355_no_event,
 };
 
 static struct resource edma_resources[] = {
        {
-               .name   = "edma_cc",
+               .name   = "edma_cc0",
                .start  = 0x01c00000,
                .end    = 0x01c00000 + SZ_64K - 1,
                .flags  = IORESOURCE_MEM,
@@ -596,7 +597,7 @@ static struct resource edma_resources[] = {
 
 static struct platform_device dm355_edma_device = {
        .name                   = "edma",
-       .id                     = -1,
+       .id                     = 0,
        .dev.platform_data      = &dm355_edma_info,
        .num_resources          = ARRAY_SIZE(edma_resources),
        .resource               = edma_resources,
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 43b2f1c..d06b31e 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -489,12 +489,13 @@ static struct edma_soc_info dm644x_edma_info = {
        .n_region       = 4,
        .n_slot         = 128,
        .n_tc           = 2,
+       .n_cc           = 1,
        .noevent        = dma_chan_dm644x_no_event,
 };
 
 static struct resource edma_resources[] = {
        {
-               .name   = "edma_cc",
+               .name   = "edma_cc0",
                .start  = 0x01c00000,
                .end    = 0x01c00000 + SZ_64K - 1,
                .flags  = IORESOURCE_MEM,
@@ -524,7 +525,7 @@ static struct resource edma_resources[] = {
 
 static struct platform_device dm644x_edma_device = {
        .name                   = "edma",
-       .id                     = -1,
+       .id                     = 0,
        .dev.platform_data      = &dm644x_edma_info,
        .num_resources          = ARRAY_SIZE(edma_resources),
        .resource               = edma_resources,
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
index 1f58631..dbf9e2d 100644
--- a/arch/arm/mach-davinci/dma.c
+++ b/arch/arm/mach-davinci/dma.c
@@ -107,11 +107,12 @@
 #define EDMA_MAX_DMACH           64
 #define EDMA_MAX_PARAMENTRY     512
 #define EDMA_MAX_EVQUE            2    /* FIXME too small */
+#define EDMA_MAX_CC               2
 
 
 /*****************************************************************************/
 
-static __iomem void *edmacc_regs_base;
+static __iomem void *edmacc_regs_base[EDMA_MAX_CC];
 
 static inline unsigned int edma_read(int offset)
 {
@@ -207,25 +208,39 @@ static inline void edma_parm_or(int offset, int param_no, 
unsigned or)
 /*****************************************************************************/
 
 /* actual number of DMA channels and slots on this silicon */
-static unsigned num_channels;
-static unsigned num_slots;
+struct edma {
+       /* how many dma resources of each type */
+       unsigned        num_channels;
+       unsigned        num_region;
+       unsigned        num_slots;
+       unsigned        num_tc;
+       unsigned        num_cc;
+
+       /* list of channels with no even trigger; terminated by "-1" */
+       const s8        *noevent;
+
+       /* The edma_inuse bit for each PaRAM slot is clear unless the
+        * channel is in use ... by ARM or DSP, for QDMA, or whatever.
+        */
+       DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY);
+
+       /* The edma_noevent bit for each channel is clear unless
+        * it doesn't trigger DMA events on this platform.  It uses a
+        * bit of SOC-specific initialization code.
+        */
+       DECLARE_BITMAP(edma_noevent, EDMA_MAX_DMACH);
+
+       unsigned        irq_start[EDMA_MAX_CC];
+       unsigned        irq_end[EDMA_MAX_CC];
+};
+
+struct edma edma_info[EDMA_MAX_CC];
 
 static struct dma_interrupt_data {
        void (*callback)(unsigned channel, unsigned short ch_status, void 
*data);
        void *data;
 } intr_data[EDMA_MAX_DMACH];
 
-/* The edma_inuse bit for each PaRAM slot is clear unless the
- * channel is in use ... by ARM or DSP, for QDMA, or whatever.
- */
-static DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY);
-
-/* The edma_noevent bit for each channel is clear unless
- * it doesn't trigger DMA events on this platform.  It uses a
- * bit of SOC-specific initialization code.
- */
-static DECLARE_BITMAP(edma_noevent, EDMA_MAX_DMACH);
-
 /* dummy param set used to (re)initialize parameter RAM slots */
 static const struct edmacc_param dummy_paramset = {
        .link_bcntrld = 0xffff,
@@ -1017,11 +1032,13 @@ static int __init edma_probe(struct platform_device 
*pdev)
        int                     irq = 0, err_irq = 0;
        struct resource         *r;
        resource_size_t         len;
+       char                    name[10];
 
        if (!info)
                return -ENODEV;
 
-       r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "edma_cc");
+       sprintf(name, "edma_cc%d", pdev->id);
+       r = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
        if (!r)
                return -ENODEV;
 
@@ -1031,28 +1048,33 @@ static int __init edma_probe(struct platform_device 
*pdev)
        if (!r)
                return -EBUSY;
 
-       edmacc_regs_base = ioremap(r->start, len);
-       if (!edmacc_regs_base) {
+       edmacc_regs_base[pdev->id] = ioremap(r->start, len);
+       if (!edmacc_regs_base[pdev->id]) {
                status = -EBUSY;
                goto fail1;
        }
 
-       num_channels = min_t(unsigned, info->n_channel, EDMA_MAX_DMACH);
-       num_slots = min_t(unsigned, info->n_slot, EDMA_MAX_PARAMENTRY);
+       edma_info[pdev->id].num_channels = min_t(unsigned, info->n_channel,
+                                               EDMA_MAX_DMACH);
+       edma_info[pdev->id].num_slots = min_t(unsigned, info->n_slot,
+                                               EDMA_MAX_PARAMENTRY);
+       edma_info[pdev->id].num_cc = min_t(unsigned, info->n_cc, EDMA_MAX_CC);
 
-       dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n", edmacc_regs_base);
+       dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n",
+               edmacc_regs_base[pdev->id]);
 
-       for (i = 0; i < num_slots; i++)
-               memcpy_toio(edmacc_regs_base + PARM_OFFSET(i),
+       for (i = 0; i < edma_info[pdev->id].num_slots; i++)
+               memcpy_toio(edmacc_regs_base[pdev->id] + PARM_OFFSET(i),
                                &dummy_paramset, PARM_SIZE);
 
        noevent = info->noevent;
        if (noevent) {
                while (*noevent != -1)
-                       set_bit(*noevent++, edma_noevent);
+                       set_bit(*noevent++, edma_info[pdev->id].edma_noevent);
        }
 
        irq = platform_get_irq(pdev, 0);
+       edma_info[pdev->id].irq_start[pdev->id] = irq;
        status = request_irq(irq, dma_irq_handler, 0, "edma", &pdev->dev);
        if (status < 0) {
                dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
@@ -1061,6 +1083,7 @@ static int __init edma_probe(struct platform_device *pdev)
        }
 
        err_irq = platform_get_irq(pdev, 1);
+       edma_info[pdev->id].irq_end[pdev->id] = err_irq;
        status = request_irq(err_irq, dma_ccerr_handler, 0,
                                "edma_error", &pdev->dev);
        if (status < 0) {
@@ -1090,22 +1113,23 @@ static int __init edma_probe(struct platform_device 
*pdev)
         * This way, long transfers on the low priority queue
         * started by the codec engine will not cause audio defects.
         */
-       for (i = 0; i < num_channels; i++)
-               map_dmach_queue(i, EVENTQ_1);
+       for (i = 0; i < edma_info[pdev->id].num_channels; i++)
+               map_dmach_queue(pdev->id, i, EVENTQ_1);
 
        /* Event queue to TC mapping */
        for (i = 0; queue_tc_mapping[i][0] != -1; i++)
-               map_queue_tc(queue_tc_mapping[i][0], queue_tc_mapping[i][1]);
+               map_queue_tc(pdev->id, queue_tc_mapping[i][0],
+                               queue_tc_mapping[i][1]);
 
        /* Event queue priority mapping */
        for (i = 0; queue_priority_mapping[i][0] != -1; i++)
-               assign_priority_to_queue(queue_priority_mapping[i][0],
+               assign_priority_to_queue(pdev->id, queue_priority_mapping[i][0],
                                         queue_priority_mapping[i][1]);
 
        for (i = 0; i < info->n_region; i++) {
-               edma_write_array2(EDMA_DRAE, i, 0, 0x0);
-               edma_write_array2(EDMA_DRAE, i, 1, 0x0);
-               edma_write_array(EDMA_QRAE, i, 0x0);
+               edma_write_array2(pdev->id, EDMA_DRAE, i, 0, 0x0);
+               edma_write_array2(pdev->id, EDMA_DRAE, i, 1, 0x0);
+               edma_write_array(pdev->id, EDMA_QRAE, i, 0x0);
        }
 
        return 0;
@@ -1115,7 +1139,7 @@ fail:
                free_irq(err_irq, NULL);
        if (irq)
                free_irq(irq, NULL);
-       iounmap(edmacc_regs_base);
+       iounmap(edmacc_regs_base[pdev->id]);
 fail1:
        release_mem_region(r->start, len);
        return status;
diff --git a/arch/arm/mach-davinci/include/mach/edma.h 
b/arch/arm/mach-davinci/include/mach/edma.h
index b467358..6606078 100644
--- a/arch/arm/mach-davinci/include/mach/edma.h
+++ b/arch/arm/mach-davinci/include/mach/edma.h
@@ -221,6 +221,7 @@ struct edma_soc_info {
        unsigned        n_region;
        unsigned        n_slot;
        unsigned        n_tc;
+       unsigned        n_cc;
 
        /* list of channels with no even trigger; terminated by "-1" */
        const s8        *noevent;
-- 
1.5.6

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

Reply via email to