USB: musb: fix for crash in DM646x USB when (CPPI)DMA is enabled
authorSwaminathan S <swami.iyer@ti.com>
Tue, 15 Dec 2009 11:30:00 +0000 (13:30 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 23 Dec 2009 19:34:17 +0000 (11:34 -0800)
Race condition exists between the cppi_interrupt handler and
davinci_interrupt handler w.r.t completing a TX IO.  Since DM646x
has seperate DMA and USB endpoint interrupts cppi_interrupt handler
needs to hold the lock while operating on the endpoint.

Update over previous patch to avoid taking the lock if already
taken.  Tested on DM644x, DM355 and DM646x platforms.

Signed-off-by: Swaminathan S <swami.iyer@ti.com>
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Acked-by: Anand Gadiyar <gadiyar@ti.com>
Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/musb/cppi_dma.c

index ef2332a9941dec7a39c25d52a69b4fce3943771d..a44a450c860d9e248c3c317d437c67abc4694a8f 100644 (file)
@@ -1154,8 +1154,11 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id)
        struct musb_hw_ep       *hw_ep = NULL;
        u32                     rx, tx;
        int                     i, index;
+       unsigned long           flags;
 
        cppi = container_of(musb->dma_controller, struct cppi, controller);
+       if (cppi->irq)
+               spin_lock_irqsave(&musb->lock, flags);
 
        tibase = musb->ctrl_base;
 
@@ -1285,6 +1288,9 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id)
        /* write to CPPI EOI register to re-enable interrupts */
        musb_writel(tibase, DAVINCI_CPPI_EOI_REG, 0);
 
+       if (cppi->irq)
+               spin_unlock_irqrestore(&musb->lock, flags);
+
        return IRQ_HANDLED;
 }