Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 151299
b: refs/heads/master
c: a5073b5
h: refs/heads/master
i:
  151297: 1c29462
  151295: 9379522
v: v3
  • Loading branch information
Sergei Shtylyov authored and Greg Kroah-Hartman committed Jun 16, 2009
1 parent 53bc46d commit dbcb3f1
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 003051bfb62513842a9e9efde17afeba46519c95
refs/heads/master: a5073b52833e4df8e16c93dc4cbb7e0c558c74a2
7 changes: 1 addition & 6 deletions trunk/drivers/usb/musb/davinci.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,12 +372,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)

spin_unlock_irqrestore(&musb->lock, flags);

/* REVISIT we sometimes get unhandled IRQs
* (e.g. ep0). not clear why...
*/
if (retval != IRQ_HANDLED)
DBG(5, "unhandled? %08x\n", tmp);
return IRQ_HANDLED;
return retval;
}

int musb_platform_set_mode(struct musb *musb, u8 mode)
Expand Down
8 changes: 1 addition & 7 deletions trunk/drivers/usb/musb/musb_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1481,13 +1481,7 @@ static irqreturn_t generic_interrupt(int irq, void *__hci)

spin_unlock_irqrestore(&musb->lock, flags);

/* REVISIT we sometimes get spurious IRQs on g_ep0
* not clear why...
*/
if (retval != IRQ_HANDLED)
DBG(5, "spurious?\n");

return IRQ_HANDLED;
return retval;
}

#else
Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/usb/musb/musb_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ enum musb_h_ep0_state {

/* peripheral side ep0 states */
enum musb_g_ep0_state {
MUSB_EP0_STAGE_SETUP, /* idle, waiting for setup */
MUSB_EP0_STAGE_IDLE, /* idle, waiting for SETUP */
MUSB_EP0_STAGE_SETUP, /* received SETUP */
MUSB_EP0_STAGE_TX, /* IN data */
MUSB_EP0_STAGE_RX, /* OUT data */
MUSB_EP0_STAGE_STATUSIN, /* (after OUT data) */
Expand Down
45 changes: 39 additions & 6 deletions trunk/drivers/usb/musb/musb_gadget_ep0.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Copyright 2005 Mentor Graphics Corporation
* Copyright (C) 2005-2006 by Texas Instruments
* Copyright (C) 2006-2007 Nokia Corporation
* Copyright (C) 2008-2009 MontaVista Software, Inc. <source@mvista.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
Expand Down Expand Up @@ -58,7 +59,8 @@
static char *decode_ep0stage(u8 stage)
{
switch (stage) {
case MUSB_EP0_STAGE_SETUP: return "idle";
case MUSB_EP0_STAGE_IDLE: return "idle";
case MUSB_EP0_STAGE_SETUP: return "setup";
case MUSB_EP0_STAGE_TX: return "in";
case MUSB_EP0_STAGE_RX: return "out";
case MUSB_EP0_STAGE_ACKWAIT: return "wait";
Expand Down Expand Up @@ -628,15 +630,26 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb)
musb_writew(regs, MUSB_CSR0,
csr & ~MUSB_CSR0_P_SENTSTALL);
retval = IRQ_HANDLED;
musb->ep0_state = MUSB_EP0_STAGE_SETUP;
musb->ep0_state = MUSB_EP0_STAGE_IDLE;
csr = musb_readw(regs, MUSB_CSR0);
}

/* request ended "early" */
if (csr & MUSB_CSR0_P_SETUPEND) {
musb_writew(regs, MUSB_CSR0, MUSB_CSR0_P_SVDSETUPEND);
retval = IRQ_HANDLED;
musb->ep0_state = MUSB_EP0_STAGE_SETUP;
/* Transition into the early status phase */
switch (musb->ep0_state) {
case MUSB_EP0_STAGE_TX:
musb->ep0_state = MUSB_EP0_STAGE_STATUSOUT;
break;
case MUSB_EP0_STAGE_RX:
musb->ep0_state = MUSB_EP0_STAGE_STATUSIN;
break;
default:
ERR("SetupEnd came in a wrong ep0stage %s",
decode_ep0stage(musb->ep0_state));
}
csr = musb_readw(regs, MUSB_CSR0);
/* NOTE: request may need completion */
}
Expand Down Expand Up @@ -697,11 +710,31 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb)
if (req)
musb_g_ep0_giveback(musb, req);
}

/*
* In case when several interrupts can get coalesced,
* check to see if we've already received a SETUP packet...
*/
if (csr & MUSB_CSR0_RXPKTRDY)
goto setup;

retval = IRQ_HANDLED;
musb->ep0_state = MUSB_EP0_STAGE_IDLE;
break;

case MUSB_EP0_STAGE_IDLE:
/*
* This state is typically (but not always) indiscernible
* from the status states since the corresponding interrupts
* tend to happen within too little period of time (with only
* a zero-length packet in between) and so get coalesced...
*/
retval = IRQ_HANDLED;
musb->ep0_state = MUSB_EP0_STAGE_SETUP;
/* FALLTHROUGH */

case MUSB_EP0_STAGE_SETUP:
setup:
if (csr & MUSB_CSR0_RXPKTRDY) {
struct usb_ctrlrequest setup;
int handled = 0;
Expand Down Expand Up @@ -783,7 +816,7 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb)
stall:
DBG(3, "stall (%d)\n", handled);
musb->ackpend |= MUSB_CSR0_P_SENDSTALL;
musb->ep0_state = MUSB_EP0_STAGE_SETUP;
musb->ep0_state = MUSB_EP0_STAGE_IDLE;
finish:
musb_writew(regs, MUSB_CSR0,
musb->ackpend);
Expand All @@ -803,7 +836,7 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb)
/* "can't happen" */
WARN_ON(1);
musb_writew(regs, MUSB_CSR0, MUSB_CSR0_P_SENDSTALL);
musb->ep0_state = MUSB_EP0_STAGE_SETUP;
musb->ep0_state = MUSB_EP0_STAGE_IDLE;
break;
}

Expand Down Expand Up @@ -959,7 +992,7 @@ static int musb_g_ep0_halt(struct usb_ep *e, int value)

csr |= MUSB_CSR0_P_SENDSTALL;
musb_writew(regs, MUSB_CSR0, csr);
musb->ep0_state = MUSB_EP0_STAGE_SETUP;
musb->ep0_state = MUSB_EP0_STAGE_IDLE;
musb->ackpend = 0;
break;
default:
Expand Down

0 comments on commit dbcb3f1

Please sign in to comment.