aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/musb/davinci.c7
-rw-r--r--drivers/usb/musb/musb_core.c8
-rw-r--r--drivers/usb/musb/musb_core.h3
-rw-r--r--drivers/usb/musb/musb_gadget_ep0.c45
4 files changed, 43 insertions, 20 deletions
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 10d11ab113ab..898b52fcff5d 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -372,12 +372,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
372 372
373 spin_unlock_irqrestore(&musb->lock, flags); 373 spin_unlock_irqrestore(&musb->lock, flags);
374 374
375 /* REVISIT we sometimes get unhandled IRQs 375 return retval;
376 * (e.g. ep0). not clear why...
377 */
378 if (retval != IRQ_HANDLED)
379 DBG(5, "unhandled? %08x\n", tmp);
380 return IRQ_HANDLED;
381} 376}
382 377
383int musb_platform_set_mode(struct musb *musb, u8 mode) 378int musb_platform_set_mode(struct musb *musb, u8 mode)
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 4000cf6d1e81..324459b619f7 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1481,13 +1481,7 @@ static irqreturn_t generic_interrupt(int irq, void *__hci)
1481 1481
1482 spin_unlock_irqrestore(&musb->lock, flags); 1482 spin_unlock_irqrestore(&musb->lock, flags);
1483 1483
1484 /* REVISIT we sometimes get spurious IRQs on g_ep0 1484 return retval;
1485 * not clear why...
1486 */
1487 if (retval != IRQ_HANDLED)
1488 DBG(5, "spurious?\n");
1489
1490 return IRQ_HANDLED;
1491} 1485}
1492 1486
1493#else 1487#else
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index efb39b5e55b5..c2a776ee1947 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -171,7 +171,8 @@ enum musb_h_ep0_state {
171 171
172/* peripheral side ep0 states */ 172/* peripheral side ep0 states */
173enum musb_g_ep0_state { 173enum musb_g_ep0_state {
174 MUSB_EP0_STAGE_SETUP, /* idle, waiting for setup */ 174 MUSB_EP0_STAGE_IDLE, /* idle, waiting for SETUP */
175 MUSB_EP0_STAGE_SETUP, /* received SETUP */
175 MUSB_EP0_STAGE_TX, /* IN data */ 176 MUSB_EP0_STAGE_TX, /* IN data */
176 MUSB_EP0_STAGE_RX, /* OUT data */ 177 MUSB_EP0_STAGE_RX, /* OUT data */
177 MUSB_EP0_STAGE_STATUSIN, /* (after OUT data) */ 178 MUSB_EP0_STAGE_STATUSIN, /* (after OUT data) */
diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c
index 3f5e30ddfa27..40ed50ecedff 100644
--- a/drivers/usb/musb/musb_gadget_ep0.c
+++ b/drivers/usb/musb/musb_gadget_ep0.c
@@ -4,6 +4,7 @@
4 * Copyright 2005 Mentor Graphics Corporation 4 * Copyright 2005 Mentor Graphics Corporation
5 * Copyright (C) 2005-2006 by Texas Instruments 5 * Copyright (C) 2005-2006 by Texas Instruments
6 * Copyright (C) 2006-2007 Nokia Corporation 6 * Copyright (C) 2006-2007 Nokia Corporation
7 * Copyright (C) 2008-2009 MontaVista Software, Inc. <source@mvista.com>
7 * 8 *
8 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 10 * modify it under the terms of the GNU General Public License
@@ -58,7 +59,8 @@
58static char *decode_ep0stage(u8 stage) 59static char *decode_ep0stage(u8 stage)
59{ 60{
60 switch (stage) { 61 switch (stage) {
61 case MUSB_EP0_STAGE_SETUP: return "idle"; 62 case MUSB_EP0_STAGE_IDLE: return "idle";
63 case MUSB_EP0_STAGE_SETUP: return "setup";
62 case MUSB_EP0_STAGE_TX: return "in"; 64 case MUSB_EP0_STAGE_TX: return "in";
63 case MUSB_EP0_STAGE_RX: return "out"; 65 case MUSB_EP0_STAGE_RX: return "out";
64 case MUSB_EP0_STAGE_ACKWAIT: return "wait"; 66 case MUSB_EP0_STAGE_ACKWAIT: return "wait";
@@ -628,7 +630,7 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb)
628 musb_writew(regs, MUSB_CSR0, 630 musb_writew(regs, MUSB_CSR0,
629 csr & ~MUSB_CSR0_P_SENTSTALL); 631 csr & ~MUSB_CSR0_P_SENTSTALL);
630 retval = IRQ_HANDLED; 632 retval = IRQ_HANDLED;
631 musb->ep0_state = MUSB_EP0_STAGE_SETUP; 633 musb->ep0_state = MUSB_EP0_STAGE_IDLE;
632 csr = musb_readw(regs, MUSB_CSR0); 634 csr = musb_readw(regs, MUSB_CSR0);
633 } 635 }
634 636
@@ -636,7 +638,18 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb)
636 if (csr & MUSB_CSR0_P_SETUPEND) { 638 if (csr & MUSB_CSR0_P_SETUPEND) {
637 musb_writew(regs, MUSB_CSR0, MUSB_CSR0_P_SVDSETUPEND); 639 musb_writew(regs, MUSB_CSR0, MUSB_CSR0_P_SVDSETUPEND);
638 retval = IRQ_HANDLED; 640 retval = IRQ_HANDLED;
639 musb->ep0_state = MUSB_EP0_STAGE_SETUP; 641 /* Transition into the early status phase */
642 switch (musb->ep0_state) {
643 case MUSB_EP0_STAGE_TX:
644 musb->ep0_state = MUSB_EP0_STAGE_STATUSOUT;
645 break;
646 case MUSB_EP0_STAGE_RX:
647 musb->ep0_state = MUSB_EP0_STAGE_STATUSIN;
648 break;
649 default:
650 ERR("SetupEnd came in a wrong ep0stage %s",
651 decode_ep0stage(musb->ep0_state));
652 }
640 csr = musb_readw(regs, MUSB_CSR0); 653 csr = musb_readw(regs, MUSB_CSR0);
641 /* NOTE: request may need completion */ 654 /* NOTE: request may need completion */
642 } 655 }
@@ -697,11 +710,31 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb)
697 if (req) 710 if (req)
698 musb_g_ep0_giveback(musb, req); 711 musb_g_ep0_giveback(musb, req);
699 } 712 }
713
714 /*
715 * In case when several interrupts can get coalesced,
716 * check to see if we've already received a SETUP packet...
717 */
718 if (csr & MUSB_CSR0_RXPKTRDY)
719 goto setup;
720
721 retval = IRQ_HANDLED;
722 musb->ep0_state = MUSB_EP0_STAGE_IDLE;
723 break;
724
725 case MUSB_EP0_STAGE_IDLE:
726 /*
727 * This state is typically (but not always) indiscernible
728 * from the status states since the corresponding interrupts
729 * tend to happen within too little period of time (with only
730 * a zero-length packet in between) and so get coalesced...
731 */
700 retval = IRQ_HANDLED; 732 retval = IRQ_HANDLED;
701 musb->ep0_state = MUSB_EP0_STAGE_SETUP; 733 musb->ep0_state = MUSB_EP0_STAGE_SETUP;
702 /* FALLTHROUGH */ 734 /* FALLTHROUGH */
703 735
704 case MUSB_EP0_STAGE_SETUP: 736 case MUSB_EP0_STAGE_SETUP:
737setup:
705 if (csr & MUSB_CSR0_RXPKTRDY) { 738 if (csr & MUSB_CSR0_RXPKTRDY) {
706 struct usb_ctrlrequest setup; 739 struct usb_ctrlrequest setup;
707 int handled = 0; 740 int handled = 0;
@@ -783,7 +816,7 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb)
783stall: 816stall:
784 DBG(3, "stall (%d)\n", handled); 817 DBG(3, "stall (%d)\n", handled);
785 musb->ackpend |= MUSB_CSR0_P_SENDSTALL; 818 musb->ackpend |= MUSB_CSR0_P_SENDSTALL;
786 musb->ep0_state = MUSB_EP0_STAGE_SETUP; 819 musb->ep0_state = MUSB_EP0_STAGE_IDLE;
787finish: 820finish:
788 musb_writew(regs, MUSB_CSR0, 821 musb_writew(regs, MUSB_CSR0,
789 musb->ackpend); 822 musb->ackpend);
@@ -803,7 +836,7 @@ finish:
803 /* "can't happen" */ 836 /* "can't happen" */
804 WARN_ON(1); 837 WARN_ON(1);
805 musb_writew(regs, MUSB_CSR0, MUSB_CSR0_P_SENDSTALL); 838 musb_writew(regs, MUSB_CSR0, MUSB_CSR0_P_SENDSTALL);
806 musb->ep0_state = MUSB_EP0_STAGE_SETUP; 839 musb->ep0_state = MUSB_EP0_STAGE_IDLE;
807 break; 840 break;
808 } 841 }
809 842
@@ -959,7 +992,7 @@ static int musb_g_ep0_halt(struct usb_ep *e, int value)
959 992
960 csr |= MUSB_CSR0_P_SENDSTALL; 993 csr |= MUSB_CSR0_P_SENDSTALL;
961 musb_writew(regs, MUSB_CSR0, csr); 994 musb_writew(regs, MUSB_CSR0, csr);
962 musb->ep0_state = MUSB_EP0_STAGE_SETUP; 995 musb->ep0_state = MUSB_EP0_STAGE_IDLE;
963 musb->ackpend = 0; 996 musb->ackpend = 0;
964 break; 997 break;
965 default: 998 default: