On Fri, Feb 20, 2009 at 11:32:24PM +0300, Sergei Shtylyov wrote:
> The MUSB code either expects TXCSR.DMAReqEnab bit cleared in several places
> and then proceeds with clearing the TXCSR.DMAMode bit (but does not bother
> with actually clearing DMAReqEnab beforehand) or just clears both bits at
> once -- while is the programming guide explicitly forbids to clear DMAMode
> before or in the same cycle as DMAReEnab.  Fix this and while at it:
> 
> - in musb_gadget::txstate(), stop clearing the AutoSet and DMAReqMode bits for
>   the CPPI case since they never get set anyway (the former bit is reserved on
>   DaVinci) but do clear the DMAReqEnab bit on the DMA error path;
> 
> - in musb_host::musb_ep_program(), remove the duplicate DMA controller 
> specific
>   code code clearing the TXCSR previous state, add the code to clear TXCSR DMA
>   bits on the Inventra DMA error path, to replace such code (executed late) on
>   the PIO path;
> 
> - in musbhsdma::dma_channel_abort()/dma_controller_irq(), add/use the 'offset'
>   variable to avoid MUSB_EP_OFFSET() invocations on every RXCSR/TXCSR access.
> 
> Signed-off-by: Sergei Shtylyov <[email protected]>

I ran into the same issue and had to fix similarly, the patch still in
my "nokia-only" queue. Good that you're pushing your version out :-)

just one comment below

> Index: linux-2.6/drivers/usb/musb/musb_gadget.c
> ===================================================================
> --- linux-2.6.orig/drivers/usb/musb/musb_gadget.c
> +++ linux-2.6/drivers/usb/musb/musb_gadget.c
> @@ -165,9 +165,19 @@ static void nuke(struct musb_ep *ep, con
>       if (is_dma_capable() && ep->dma) {
>               struct dma_controller   *c = ep->musb->dma_controller;
>               int value;
> +
>               if (ep->is_in) {
> +                     u16 txcsr = musb_readw(epio, MUSB_TXCSR);

this looks unnecessary, in the end you just wanna keep FLUSHFIFO set
so...

> +
> +                     /*
> +                      * The programming guide says that we must not clear
> +                      * the DMAReqMode bit before DMAReqEnab, so we only
> +                      * clear it in the second write...
> +                      */
> +                     txcsr &= MUSB_TXCSR_DMAMODE;
> +
>                       musb_writew(epio, MUSB_TXCSR,
> -                                     0 | MUSB_TXCSR_FLUSHFIFO);
> +                                 txcsr | MUSB_TXCSR_FLUSHFIFO);

musb_writew(epio, MUSB_TXCSR,
        0 | MUSB_TXCSR_DMAMODE | MUSB_TXCSR_FLUSHFIFO);
musb_writew(epio, MUSB_TXCSR, 0 | MUSB_TXCSR_FLUSHFIFO);

should do it.

-- 
balbi

_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to