From: Anders Berg <anders.b...@lsi.com>

Driver was picking up the wrong interrupt line for the error status interrupt.
A mixup between the BUSY (not used) and ERROR interrupts.  This commit also
makes the error interupt service routine clear the error before returning.

Signed-off-by: Anders Berg <anders.b...@lsi.com>
---
 arch/arm/boot/dts/axm55xx.dts |  1 -
 drivers/dma/lsi-dma32.c       | 25 ++++++++++++++-----------
 drivers/dma/lsi-dma32.h       |  5 +++++
 3 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/arch/arm/boot/dts/axm55xx.dts b/arch/arm/boot/dts/axm55xx.dts
index 925e3b2..5ba1824 100644
--- a/arch/arm/boot/dts/axm55xx.dts
+++ b/arch/arm/boot/dts/axm55xx.dts
@@ -210,7 +210,6 @@
        };
 
        gpdma@2020141000 {
-               status = "disabled";
                compatible = "lsi,dma32";
                reg = <0x20 0x20141000 0x00 0x1000>;
                interrupts = <0 64 4>, /* busy */
diff --git a/drivers/dma/lsi-dma32.c b/drivers/dma/lsi-dma32.c
index b5d25d8..f2ec6c6 100644
--- a/drivers/dma/lsi-dma32.c
+++ b/drivers/dma/lsi-dma32.c
@@ -102,19 +102,14 @@ static void soft_reset(struct gpdma_engine *engine)
        wr32(GPDMA_MAGIC, engine->gbase + SOFT_RESET);
        wmb();
 
-       /*
-        *  Set has to be done twice???
-        *  Yep! According to LSI code it has to be done twice,
-        *  have no idea why.
-        */
        cfg = (engine->pool.phys & 0xfff00000) | GEN_CONFIG_EXT_MEM;
+
        if (engine->chip->flags & LSIDMA_EDGE_INT) {
                for (i = 0; i < engine->chip->num_channels; i++)
                        cfg |= GEN_CONFIG_INT_EDGE(i);
                engine_dbg(engine, "Using edge-triggered interrupts\n");
        }
        wr32(cfg, engine->gbase + GEN_CONFIG);
-       wr32(cfg, engine->gbase + GEN_CONFIG);
        engine_dbg(engine, "engine->desc.phys & 0xfff00000 == %llx\n",
                   (engine->pool.phys & 0xfff00000));
 
@@ -327,9 +322,18 @@ static irqreturn_t gpdma_isr_err(int irqno, void *_engine)
 {
        struct gpdma_engine *engine = _engine;
        u32 status = rd32(engine->gbase + GEN_STAT);
+       u32 ch = (status & GEN_STAT_CH0_ERROR) ? 0 : 1;
+       struct gpdma_channel *dmac = &engine->channel[ch];
+
+       if (0 == (status & (GEN_STAT_CH0_ERROR | GEN_STAT_CH1_ERROR)))
+               return IRQ_NONE;
+
+       /* Read the channel status bits and dump the error */
+       status = rd32(dmac->base + DMA_STATUS);
+       pr_err("dma: channel%d error %08x\n", dmac->channel, status);
+       /* Clear the error indication */
+       wr32(DMA_STATUS_ERROR, dmac->base+DMA_STATUS);
 
-       (void) status;
-       engine_dbg(engine, "ERROR ISR: status=%08x\n", status);
        return IRQ_HANDLED;
 }
 
@@ -715,8 +719,7 @@ static struct lsidma_hw lsi_dma32 = {
        .chregs_offset  = 0x80,
        .genregs_offset = 0xF00,
        .flags          = (LSIDMA_NEXT_FULL |
-                          LSIDMA_SEG_REGS  |
-                          LSIDMA_EDGE_INT)
+                          LSIDMA_SEG_REGS)
 };
 
 static struct lsidma_hw lsi_dma31 = {
@@ -800,7 +803,7 @@ static int __devinit gpdma_of_probe(struct platform_device 
*op)
        }
        dev_dbg(&op->dev, "mapped base @ %p\n", engine->iobase);
 
-       engine->err_irq = irq_of_parse_and_map(op->dev.of_node, 0);
+       engine->err_irq = irq_of_parse_and_map(op->dev.of_node, 1);
        if (engine->err_irq) {
                rc = request_irq(engine->err_irq, gpdma_isr_err,
                                 IRQF_SHARED, "lsi-dma-err", engine);
diff --git a/drivers/dma/lsi-dma32.h b/drivers/dma/lsi-dma32.h
index 04504c1..5f10198 100644
--- a/drivers/dma/lsi-dma32.h
+++ b/drivers/dma/lsi-dma32.h
@@ -114,6 +114,11 @@
                                         DMA_CONFIG_CHAN_EN)
 
 #define GEN_STAT       0x0
+#define   GEN_STAT_CH0_ACTIVE (1<<0)
+#define   GEN_STAT_CH1_ACTIVE (1<<2)
+#define   GEN_STAT_CH1_ACTIVE (1<<2)
+#define   GEN_STAT_CH0_ERROR  (1<<16)
+#define   GEN_STAT_CH1_ERROR  (1<<17)
 #define GEN_CONFIG     0x4
 #define  GEN_CONFIG_EXT_MEM                     (1<<19)
 #define  GEN_CONFIG_INT_EDGE(_ch)               (1<<(_ch))
-- 
1.8.3.4

_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to