From: Sudhakar Rajashekhara <sudhakar....@ti.com>

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 <sudhakar....@ti.com>
Reviewed-by: David Brownell <dbrown...@users.sourceforge.net>
Signed-off-by: Kevin Hilman <khil...@deeprootsystems.com>
---
 arch/arm/mach-davinci/dm355.c             |    5 +-
 arch/arm/mach-davinci/dm644x.c            |    5 +-
 arch/arm/mach-davinci/dma.c               |  100 +++++++++++++++++++----------
 arch/arm/mach-davinci/include/mach/edma.h |    1 +
 4 files changed, 73 insertions(+), 38 deletions(-)

diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index baaaf32..beda643 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -563,12 +563,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,
@@ -598,7 +599,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 fb5449b..ddc1d4f 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 15e9eb1..9afd55f 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 void __iomem *edmacc_regs_base;
+static void __iomem *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);
 
-static struct dma_interrupt_data {
-       void (*callback)(unsigned channel, unsigned short ch_status,
-                        void *data);
-       void *data;
-} intr_data[EDMA_MAX_DMACH];
+       /* 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);
 
-/* 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);
+       unsigned        irq_res_start;
+       unsigned        irq_res_end;
 
-/* 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);
+       struct dma_interrupt_data {
+               void (*callback)(unsigned channel, unsigned short ch_status,
+                               void *data);
+               void *data;
+       } intr_data[EDMA_MAX_DMACH];
+};
+
+static struct edma *edma_info[EDMA_MAX_CC];
 
 /* dummy param set used to (re)initialize parameter RAM slots */
 static const struct edmacc_param dummy_paramset = {
@@ -1018,11 +1033,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;
 
@@ -1032,28 +1049,41 @@ 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] = kmalloc(sizeof(struct edma), GFP_KERNEL);
+       if (!edma_info[pdev->id]) {
+               status = -ENOMEM;
+               iounmap(edmacc_regs_base[pdev->id]);
+               goto fail1;
+       }
+       memset(edma_info[pdev->id], 0, sizeof(struct edma));
+
+       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_res_start = 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",
@@ -1062,6 +1092,7 @@ static int __init edma_probe(struct platform_device *pdev)
        }
 
        err_irq = platform_get_irq(pdev, 1);
+       edma_info[pdev->id]->irq_res_end = err_irq;
        status = request_irq(err_irq, dma_ccerr_handler, 0,
                                "edma_error", &pdev->dev);
        if (status < 0) {
@@ -1091,22 +1122,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;
@@ -1116,7 +1148,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 24a3792..0780a4e 100644
--- a/arch/arm/mach-davinci/include/mach/edma.h
+++ b/arch/arm/mach-davinci/include/mach/edma.h
@@ -216,6 +216,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.6.3.3


_______________________________________________
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to