Commit 56596923 authored by Swaminathan S's avatar Swaminathan S Committed by Greg Kroah-Hartman

usb: musb: Fix cppi_channel_abort() function to handle Tx abort correctly

This patch fixes the Tx abort/teardown logic. We now wait for the teardown
completion interrupt and acknowledge the same by setting the tx_complete
register to 0.

This change is needed to ensure that abort processing works on DM365 platform.
Without this change after completion of abort processing the system is
overwhelmed with continuous stream of abort interrupts.

This change has been tested on all CPPI3.x platforms (DM644x, DM646x, DM35x,
DM36x).
Signed-off-by: default avatarSwaminathan S <swami.iyer@ti.com>
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@nokia.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 5274dab6
...@@ -1191,8 +1191,13 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) ...@@ -1191,8 +1191,13 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id)
bd = tx_ch->head; bd = tx_ch->head;
/*
* If Head is null then this could mean that a abort interrupt
* that needs to be acknowledged.
*/
if (NULL == bd) { if (NULL == bd) {
DBG(1, "null BD\n"); DBG(1, "null BD\n");
tx_ram->tx_complete = 0;
continue; continue;
} }
...@@ -1412,15 +1417,6 @@ static int cppi_channel_abort(struct dma_channel *channel) ...@@ -1412,15 +1417,6 @@ static int cppi_channel_abort(struct dma_channel *channel)
if (cppi_ch->transmit) { if (cppi_ch->transmit) {
struct cppi_tx_stateram __iomem *tx_ram; struct cppi_tx_stateram __iomem *tx_ram;
int enabled;
/* mask interrupts raised to signal teardown complete. */
enabled = musb_readl(tibase, DAVINCI_TXCPPI_INTENAB_REG)
& (1 << cppi_ch->index);
if (enabled)
musb_writel(tibase, DAVINCI_TXCPPI_INTCLR_REG,
(1 << cppi_ch->index));
/* REVISIT put timeouts on these controller handshakes */ /* REVISIT put timeouts on these controller handshakes */
cppi_dump_tx(6, cppi_ch, " (teardown)"); cppi_dump_tx(6, cppi_ch, " (teardown)");
...@@ -1435,7 +1431,6 @@ static int cppi_channel_abort(struct dma_channel *channel) ...@@ -1435,7 +1431,6 @@ static int cppi_channel_abort(struct dma_channel *channel)
do { do {
value = musb_readl(&tx_ram->tx_complete, 0); value = musb_readl(&tx_ram->tx_complete, 0);
} while (0xFFFFFFFC != value); } while (0xFFFFFFFC != value);
musb_writel(&tx_ram->tx_complete, 0, 0xFFFFFFFC);
/* FIXME clean up the transfer state ... here? /* FIXME clean up the transfer state ... here?
* the completion routine should get called with * the completion routine should get called with
...@@ -1448,23 +1443,15 @@ static int cppi_channel_abort(struct dma_channel *channel) ...@@ -1448,23 +1443,15 @@ static int cppi_channel_abort(struct dma_channel *channel)
musb_writew(regs, MUSB_TXCSR, value); musb_writew(regs, MUSB_TXCSR, value);
musb_writew(regs, MUSB_TXCSR, value); musb_writew(regs, MUSB_TXCSR, value);
/* While we scrub the TX state RAM, ensure that we clean /*
* up any interrupt that's currently asserted:
* 1. Write to completion Ptr value 0x1(bit 0 set) * 1. Write to completion Ptr value 0x1(bit 0 set)
* (write back mode) * (write back mode)
* 2. Write to completion Ptr value 0x0(bit 0 cleared) * 2. Wait for abort interrupt and then put the channel in
* (compare mode) * compare mode by writing 1 to the tx_complete register.
* Value written is compared(for bits 31:2) and when
* equal, interrupt is deasserted.
*/ */
cppi_reset_tx(tx_ram, 1); cppi_reset_tx(tx_ram, 1);
musb_writel(&tx_ram->tx_complete, 0, 0); cppi_ch->head = 0;
musb_writel(&tx_ram->tx_complete, 0, 1);
/* re-enable interrupt */
if (enabled)
musb_writel(tibase, DAVINCI_TXCPPI_INTENAB_REG,
(1 << cppi_ch->index));
cppi_dump_tx(5, cppi_ch, " (done teardown)"); cppi_dump_tx(5, cppi_ch, " (done teardown)");
/* REVISIT tx side _should_ clean up the same way /* REVISIT tx side _should_ clean up the same way
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment