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
