summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirupathi Chippakurthy <thirupathi.chippakurthy@stericsson.com>2011-09-27 16:18:13 +0530
committerRabin VINCENT <rabin.vincent@stericsson.com>2011-09-27 13:17:50 +0200
commit46c3153b404408ac73d26a771406561dd72ebd2d (patch)
tree62e541655344b14fc37146c2f8f41d5805c23d33
parentfc08bb7e25e8bb430259d3d9740b110b75c38735 (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 54aed9b2386..07e25fa1bf2 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 */
@@ -1154,6 +1154,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);