summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirupathi Chippakurthy <thirupathi.chippakurthy@stericsson.com>2011-09-27 16:18:13 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:03:10 +0200
commit760e099efb373f7fb7a23bc4b9202066565614b9 (patch)
tree6604e2f41214490b0c2b13ed3dc19796be2a5efe
parent9bd7c9e53254e920bb83b67aa67b771f4bec4d8f (diff)
musb: host: Wait for TXPKTRDY to clear in host
MUSB_TXCSR_TXPKTRDY will not get cleared if the data is not on the bus. So, need to wait for it to clear in the DMA completion callback.As per musb datasheet, generally mode 1 needs to be used for data length greater than or equal to max packet size. ST-Ericsson ID:AP 363893 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: NA Change-Id: I934295798a5fbccf60c6f4004595b625a98098ed Signed-off-by: <thirupathi.chippakurthy@stericsson.com> Signed-off-by: Praveena <praveen.nadahally@stericsson.com> Signed-off-by: rajaram <rajaram.ragupathy@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32012 Reviewed-by: Rabin VINCENT <rabin.vincent@stericsson.com>
-rw-r--r--drivers/usb/musb/musb_host.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 70bf46c4487..cfbd088d863 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -636,7 +636,7 @@ static bool musb_tx_dma_program(struct dma_controller *dma,
length = channel->max_len;
csr = musb_readw(epio, MUSB_TXCSR);
- if (length > pkt_size) {
+ if (length >= pkt_size) {
mode = 1;
csr |= MUSB_TXCSR_DMAMODE | MUSB_TXCSR_DMAENAB;
/* autoset shouldn't be set in high bandwidth */
@@ -1158,6 +1158,21 @@ void musb_host_tx(struct musb *musb, u8 epnum)
status = -ETIMEDOUT;
} else if (tx_csr & MUSB_TXCSR_TXPKTRDY) {
/* BUSY - can happen during USB transfer cancel */
+
+ /* MUSB_TXCSR_TXPKTRDY indicates that the data written
+ * to the FIFO by DMA has not still gone on the USB bus.
+ * DMA completion callback doesn't indicate that data has
+ * gone on the USB bus. So, if we reach this case, need to
+ * wait for the MUSB_TXCSR_TXPKTRDY to be cleared and then
+ * proceed.
+ */
+ dev_dbg(musb->controller, "TXPKTRDY set. Data transfer ongoing. Wait...\n");
+
+ do {
+ tx_csr = musb_readw(epio, MUSB_TXCSR);
+ } while ((tx_csr & MUSB_TXCSR_TXPKTRDY) != 0);
+ dev_dbg(musb->controller, "TXPKTRDY Cleared. Continue...\n");
+
return;
} else if (tx_csr & MUSB_TXCSR_H_NAKTIMEOUT) {
dev_dbg(musb->controller, "TX end=%d device not responding\n", epnum);