diff options
Diffstat (limited to 'drivers/usb/musb/cppi_dma.c')
-rw-r--r-- | drivers/usb/musb/cppi_dma.c | 33 |
1 files changed, 10 insertions, 23 deletions
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index a44a450c860d..3c69a76ec392 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c | |||
@@ -1191,8 +1191,13 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) | |||
1191 | 1191 | ||
1192 | bd = tx_ch->head; | 1192 | bd = tx_ch->head; |
1193 | 1193 | ||
1194 | /* | ||
1195 | * If Head is null then this could mean that a abort interrupt | ||
1196 | * that needs to be acknowledged. | ||
1197 | */ | ||
1194 | if (NULL == bd) { | 1198 | if (NULL == bd) { |
1195 | DBG(1, "null BD\n"); | 1199 | DBG(1, "null BD\n"); |
1200 | tx_ram->tx_complete = 0; | ||
1196 | continue; | 1201 | continue; |
1197 | } | 1202 | } |
1198 | 1203 | ||
@@ -1412,15 +1417,6 @@ static int cppi_channel_abort(struct dma_channel *channel) | |||
1412 | 1417 | ||
1413 | if (cppi_ch->transmit) { | 1418 | if (cppi_ch->transmit) { |
1414 | struct cppi_tx_stateram __iomem *tx_ram; | 1419 | struct cppi_tx_stateram __iomem *tx_ram; |
1415 | int enabled; | ||
1416 | |||
1417 | /* mask interrupts raised to signal teardown complete. */ | ||
1418 | enabled = musb_readl(tibase, DAVINCI_TXCPPI_INTENAB_REG) | ||
1419 | & (1 << cppi_ch->index); | ||
1420 | if (enabled) | ||
1421 | musb_writel(tibase, DAVINCI_TXCPPI_INTCLR_REG, | ||
1422 | (1 << cppi_ch->index)); | ||
1423 | |||
1424 | /* REVISIT put timeouts on these controller handshakes */ | 1420 | /* REVISIT put timeouts on these controller handshakes */ |
1425 | 1421 | ||
1426 | cppi_dump_tx(6, cppi_ch, " (teardown)"); | 1422 | cppi_dump_tx(6, cppi_ch, " (teardown)"); |
@@ -1435,7 +1431,6 @@ static int cppi_channel_abort(struct dma_channel *channel) | |||
1435 | do { | 1431 | do { |
1436 | value = musb_readl(&tx_ram->tx_complete, 0); | 1432 | value = musb_readl(&tx_ram->tx_complete, 0); |
1437 | } while (0xFFFFFFFC != value); | 1433 | } while (0xFFFFFFFC != value); |
1438 | musb_writel(&tx_ram->tx_complete, 0, 0xFFFFFFFC); | ||
1439 | 1434 | ||
1440 | /* FIXME clean up the transfer state ... here? | 1435 | /* FIXME clean up the transfer state ... here? |
1441 | * the completion routine should get called with | 1436 | * the completion routine should get called with |
@@ -1448,23 +1443,15 @@ static int cppi_channel_abort(struct dma_channel *channel) | |||
1448 | musb_writew(regs, MUSB_TXCSR, value); | 1443 | musb_writew(regs, MUSB_TXCSR, value); |
1449 | musb_writew(regs, MUSB_TXCSR, value); | 1444 | musb_writew(regs, MUSB_TXCSR, value); |
1450 | 1445 | ||
1451 | /* While we scrub the TX state RAM, ensure that we clean | 1446 | /* |
1452 | * up any interrupt that's currently asserted: | ||
1453 | * 1. Write to completion Ptr value 0x1(bit 0 set) | 1447 | * 1. Write to completion Ptr value 0x1(bit 0 set) |
1454 | * (write back mode) | 1448 | * (write back mode) |
1455 | * 2. Write to completion Ptr value 0x0(bit 0 cleared) | 1449 | * 2. Wait for abort interrupt and then put the channel in |
1456 | * (compare mode) | 1450 | * compare mode by writing 1 to the tx_complete register. |
1457 | * Value written is compared(for bits 31:2) and when | ||
1458 | * equal, interrupt is deasserted. | ||
1459 | */ | 1451 | */ |
1460 | cppi_reset_tx(tx_ram, 1); | 1452 | cppi_reset_tx(tx_ram, 1); |
1461 | musb_writel(&tx_ram->tx_complete, 0, 0); | 1453 | cppi_ch->head = 0; |
1462 | 1454 | musb_writel(&tx_ram->tx_complete, 0, 1); | |
1463 | /* re-enable interrupt */ | ||
1464 | if (enabled) | ||
1465 | musb_writel(tibase, DAVINCI_TXCPPI_INTENAB_REG, | ||
1466 | (1 << cppi_ch->index)); | ||
1467 | |||
1468 | cppi_dump_tx(5, cppi_ch, " (done teardown)"); | 1455 | cppi_dump_tx(5, cppi_ch, " (done teardown)"); |
1469 | 1456 | ||
1470 | /* REVISIT tx side _should_ clean up the same way | 1457 | /* REVISIT tx side _should_ clean up the same way |