Skip to content

Commit

Permalink
usb: musb: Fix cppi_channel_abort() function to handle Tx abort corre…
Browse files Browse the repository at this point in the history
…ctly

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: Swaminathan S <swami.iyer@ti.com>
Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Swaminathan S authored and Greg Kroah-Hartman committed Mar 2, 2010
1 parent 5274dab commit 5659692
Showing 1 changed file with 10 additions and 23 deletions.
33 changes: 10 additions & 23 deletions drivers/usb/musb/cppi_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -1191,8 +1191,13 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id)

bd = tx_ch->head;

/*
* If Head is null then this could mean that a abort interrupt
* that needs to be acknowledged.
*/
if (NULL == bd) {
DBG(1, "null BD\n");
tx_ram->tx_complete = 0;
continue;
}

Expand Down Expand Up @@ -1412,15 +1417,6 @@ static int cppi_channel_abort(struct dma_channel *channel)

if (cppi_ch->transmit) {
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 */

cppi_dump_tx(6, cppi_ch, " (teardown)");
Expand All @@ -1435,7 +1431,6 @@ static int cppi_channel_abort(struct dma_channel *channel)
do {
value = musb_readl(&tx_ram->tx_complete, 0);
} while (0xFFFFFFFC != value);
musb_writel(&tx_ram->tx_complete, 0, 0xFFFFFFFC);

/* FIXME clean up the transfer state ... here?
* the completion routine should get called with
Expand All @@ -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);

/* 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)
* (write back mode)
* 2. Write to completion Ptr value 0x0(bit 0 cleared)
* (compare mode)
* Value written is compared(for bits 31:2) and when
* equal, interrupt is deasserted.
* 2. Wait for abort interrupt and then put the channel in
* compare mode by writing 1 to the tx_complete register.
*/
cppi_reset_tx(tx_ram, 1);
musb_writel(&tx_ram->tx_complete, 0, 0);

/* re-enable interrupt */
if (enabled)
musb_writel(tibase, DAVINCI_TXCPPI_INTENAB_REG,
(1 << cppi_ch->index));

cppi_ch->head = 0;
musb_writel(&tx_ram->tx_complete, 0, 1);
cppi_dump_tx(5, cppi_ch, " (done teardown)");

/* REVISIT tx side _should_ clean up the same way
Expand Down

0 comments on commit 5659692

Please sign in to comment.