diff mbox

[MUSB] Fix for crash in DM646x USB when (CPPI)DMA is enabled.

Message ID 1253872613-28746-1-git-send-email-swami.iyer@ti.com (mailing list archive)
State Awaiting Upstream
Headers show

Commit Message

Subbrathnam, Swaminathan Sept. 25, 2009, 9:56 a.m. UTC
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>
---
 drivers/usb/musb/cppi_dma.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

Comments

Sergei Shtylyov Sept. 25, 2009, 12:59 p.m. UTC | #1
Hello.

Swaminathan S wrote:

> 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>

[...]

> diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c
> index c3577bb..cc83ffa 100644
> --- a/drivers/usb/musb/cppi_dma.c
> +++ b/drivers/usb/musb/cppi_dma.c
> @@ -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;
>  }
>  

    OK, but don't you want to modify davinci.c instead?

WBR, Sergei
diff mbox

Patch

diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c
index c3577bb..cc83ffa 100644
--- a/drivers/usb/musb/cppi_dma.c
+++ b/drivers/usb/musb/cppi_dma.c
@@ -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;
 }