mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 14:42:24 +00:00
usb: musb: cppi41: improve rx channel abort routine
1. set AUTOREQ to NONE at the beginning of teardown; 2. add delay for dma pipeline to drain; 3. Do not set USB_TDOWN bit for RX teardown. The CPPI hw has an issue that when tearing down a RX channel, if another RX channel is receiving data, the CPPI will lockup. To workaround the issue, do not set the CPPI TD bit. The steps before this point ensures the CPPI channel will be torn down properly. Signed-off-by: Bin Liu <b-liu@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
parent
0149b07a9e
commit
cb83df77f3
@ -549,10 +549,15 @@ static int cppi41_dma_channel_abort(struct dma_channel *channel)
|
|||||||
csr &= ~MUSB_TXCSR_DMAENAB;
|
csr &= ~MUSB_TXCSR_DMAENAB;
|
||||||
musb_writew(epio, MUSB_TXCSR, csr);
|
musb_writew(epio, MUSB_TXCSR, csr);
|
||||||
} else {
|
} else {
|
||||||
|
cppi41_set_autoreq_mode(cppi41_channel, EP_MODE_AUTOREQ_NONE);
|
||||||
|
|
||||||
csr = musb_readw(epio, MUSB_RXCSR);
|
csr = musb_readw(epio, MUSB_RXCSR);
|
||||||
csr &= ~(MUSB_RXCSR_H_REQPKT | MUSB_RXCSR_DMAENAB);
|
csr &= ~(MUSB_RXCSR_H_REQPKT | MUSB_RXCSR_DMAENAB);
|
||||||
musb_writew(epio, MUSB_RXCSR, csr);
|
musb_writew(epio, MUSB_RXCSR, csr);
|
||||||
|
|
||||||
|
/* wait to drain cppi dma pipe line */
|
||||||
|
udelay(50);
|
||||||
|
|
||||||
csr = musb_readw(epio, MUSB_RXCSR);
|
csr = musb_readw(epio, MUSB_RXCSR);
|
||||||
if (csr & MUSB_RXCSR_RXPKTRDY) {
|
if (csr & MUSB_RXCSR_RXPKTRDY) {
|
||||||
csr |= MUSB_RXCSR_FLUSHFIFO;
|
csr |= MUSB_RXCSR_FLUSHFIFO;
|
||||||
@ -566,13 +571,14 @@ static int cppi41_dma_channel_abort(struct dma_channel *channel)
|
|||||||
tdbit <<= 16;
|
tdbit <<= 16;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
musb_writel(musb->ctrl_base, USB_TDOWN, tdbit);
|
if (is_tx)
|
||||||
|
musb_writel(musb->ctrl_base, USB_TDOWN, tdbit);
|
||||||
ret = dmaengine_terminate_all(cppi41_channel->dc);
|
ret = dmaengine_terminate_all(cppi41_channel->dc);
|
||||||
} while (ret == -EAGAIN);
|
} while (ret == -EAGAIN);
|
||||||
|
|
||||||
musb_writel(musb->ctrl_base, USB_TDOWN, tdbit);
|
|
||||||
|
|
||||||
if (is_tx) {
|
if (is_tx) {
|
||||||
|
musb_writel(musb->ctrl_base, USB_TDOWN, tdbit);
|
||||||
|
|
||||||
csr = musb_readw(epio, MUSB_TXCSR);
|
csr = musb_readw(epio, MUSB_TXCSR);
|
||||||
if (csr & MUSB_TXCSR_TXPKTRDY) {
|
if (csr & MUSB_TXCSR_TXPKTRDY) {
|
||||||
csr |= MUSB_TXCSR_FLUSHFIFO;
|
csr |= MUSB_TXCSR_FLUSHFIFO;
|
||||||
|
Loading…
Reference in New Issue
Block a user