ARM: OMAP2+: DMA: remove requirement of irq for platform-dma driver
authorNishanth Menon <nm@ti.com>
Thu, 12 Jun 2014 11:45:22 +0000 (17:15 +0530)
committerTony Lindgren <tony@atomide.com>
Tue, 22 Jul 2014 06:32:51 +0000 (23:32 -0700)
we have currently 2 DMA drivers that try to co-exist.
drivers/dma/omap-dma.c which registers it's own IRQ and is device tree
aware and uses arch/arm/plat-omap/dma.c instance created by
arch/arm/mach-omap2/dma.c to maintain channel usage (omap_request_dma).

Currently both try to register interrupts and mach-omap2/plat-omap dma.c
attempts to use the IRQ number registered by hwmod to register it's own
interrupt handler.

Now, there is no reasonable way of static allocating DMA irq in GIC
SPI when we use crossbar. However, since the dma_chan structure is
freed as a result of IRQ not being present due to devm allocation,
maintaining information of channel by platform code fails at a later
point in time when that region of memory is reused.

So, if hwmod does not indicate an IRQ number, then, assume that
dma-engine will take care of the interrupt handling.

Signed-off-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap2/dma.c
arch/arm/plat-omap/dma.c
include/linux/omap-dma.h

index a6d2cf1f8d02f790f82a45ab73cfb1e256f1177f..e1a56d87599e640620e506989de7b5f302c49695 100644 (file)
@@ -259,6 +259,9 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
        if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
                d->dev_caps |= HS_CHANNELS_RESERVED;
 
+       if (platform_get_irq_byname(pdev, "0") < 0)
+               d->dev_caps |= DMA_ENGINE_HANDLE_IRQ;
+
        /* Check the capabilities register for descriptor loading feature */
        if (dma_read(CAPS_0, 0) & DMA_HAS_DESCRIPTOR_CAPS)
                dma_common_ch_end = CCDN;
index b5608b1f9fbdf5da32bf354643c1c842a755df83..7aae0e5b188c814fc858a9a0ba3d20d9919986c6 100644 (file)
@@ -2100,7 +2100,7 @@ static int omap_system_dma_probe(struct platform_device *pdev)
                omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE,
                                DMA_DEFAULT_FIFO_DEPTH, 0);
 
-       if (dma_omap2plus()) {
+       if (dma_omap2plus() && !(d->dev_caps & DMA_ENGINE_HANDLE_IRQ)) {
                strcpy(irq_name, "0");
                dma_irq = platform_get_irq_byname(pdev, irq_name);
                if (dma_irq < 0) {
@@ -2145,7 +2145,8 @@ static int omap_system_dma_remove(struct platform_device *pdev)
                char irq_name[4];
                strcpy(irq_name, "0");
                dma_irq = platform_get_irq_byname(pdev, irq_name);
-               remove_irq(dma_irq, &omap24xx_dma_irq);
+               if (dma_irq >= 0)
+                       remove_irq(dma_irq, &omap24xx_dma_irq);
        } else {
                int irq_rel = 0;
                for ( ; irq_rel < dma_chan_count; irq_rel++) {
index 88e6ea4a5d3683543cf6c4cc57be13483ef36476..6f06f8bc612c6628bfc4f12aebfde9f1e552b280 100644 (file)
 #define IS_WORD_16                     BIT(0xd)
 #define ENABLE_16XX_MODE               BIT(0xe)
 #define HS_CHANNELS_RESERVED           BIT(0xf)
+#define DMA_ENGINE_HANDLE_IRQ          BIT(0x10)
 
 /* Defines for DMA Capabilities */
 #define DMA_HAS_TRANSPARENT_CAPS       (0x1 << 18)