Skip to content

Commit

Permalink
usb: musb: core: fix TX/RX endpoint order
Browse files Browse the repository at this point in the history
As per Mentor Graphics' documentation, we should
always handle TX endpoints before RX endpoints.

This patch fixes that error while also updating
some hard-to-read comments which were scattered
around musb_interrupt().

This patch should be backported as far back as
possible since this error has been in the driver
since it's conception.

Cc: <stable@vger.kernel.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
  • Loading branch information
Felipe Balbi committed Mar 9, 2015
1 parent d5638fc commit e3c93e1
Showing 1 changed file with 26 additions and 18 deletions.
44 changes: 26 additions & 18 deletions drivers/usb/musb/musb_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1597,54 +1597,62 @@ irqreturn_t musb_interrupt(struct musb *musb)
is_host_active(musb) ? "host" : "peripheral",
musb->int_usb, musb->int_tx, musb->int_rx);

/* the core can interrupt us for multiple reasons; docs have
* a generic interrupt flowchart to follow
/**
* According to Mentor Graphics' documentation, flowchart on page 98,
* IRQ should be handled as follows:
*
* . Resume IRQ
* . Session Request IRQ
* . VBUS Error IRQ
* . Suspend IRQ
* . Connect IRQ
* . Disconnect IRQ
* . Reset/Babble IRQ
* . SOF IRQ (we're not using this one)
* . Endpoint 0 IRQ
* . TX Endpoints
* . RX Endpoints
*
* We will be following that flowchart in order to avoid any problems
* that might arise with internal Finite State Machine.
*/

if (musb->int_usb)
retval |= musb_stage0_irq(musb, musb->int_usb,
devctl);

/* "stage 1" is handling endpoint irqs */

/* handle endpoint 0 first */
if (musb->int_tx & 1) {
if (is_host_active(musb))
retval |= musb_h_ep0_irq(musb);
else
retval |= musb_g_ep0_irq(musb);
}

/* RX on endpoints 1-15 */
reg = musb->int_rx >> 1;
reg = musb->int_tx >> 1;
ep_num = 1;
while (reg) {
if (reg & 1) {
/* musb_ep_select(musb->mregs, ep_num); */
/* REVISIT just retval = ep->rx_irq(...) */
retval = IRQ_HANDLED;
if (is_host_active(musb))
musb_host_rx(musb, ep_num);
musb_host_tx(musb, ep_num);
else
musb_g_rx(musb, ep_num);
musb_g_tx(musb, ep_num);
}

reg >>= 1;
ep_num++;
}

/* TX on endpoints 1-15 */
reg = musb->int_tx >> 1;
reg = musb->int_rx >> 1;
ep_num = 1;
while (reg) {
if (reg & 1) {
/* musb_ep_select(musb->mregs, ep_num); */
/* REVISIT just retval |= ep->tx_irq(...) */
retval = IRQ_HANDLED;
if (is_host_active(musb))
musb_host_tx(musb, ep_num);
musb_host_rx(musb, ep_num);
else
musb_g_tx(musb, ep_num);
musb_g_rx(musb, ep_num);
}

reg >>= 1;
ep_num++;
}
Expand Down

0 comments on commit e3c93e1

Please sign in to comment.