|
@@ -1597,16 +1597,30 @@ 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);
|
|
@@ -1614,37 +1628,31 @@ irqreturn_t musb_interrupt(struct musb *musb)
|
|
|
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++;
|
|
|
}
|