aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMian Yousaf Kaukab <yousaf.kaukab@intel.com>2015-09-29 06:08:29 -0400
committerFelipe Balbi <balbi@ti.com>2015-10-01 13:40:27 -0400
commit8fc37b82a4a43f63e3464e5d02578ea988cb5c01 (patch)
tree58c042f0f5270162ce6129b6b39451b471c531aa
parent61f7223bf14689382fdf36b7580f206745c2409a (diff)
usb: dwc2: gadget: handle reset interrupt before endpoint interrupts
If system is loaded, reset, enum-done and setup interrupts can occur at the same time. Current interrupt handling sequence will handle setup packet's interrupt before handling reset interrupt. Which will break the enumeration process. Correct sequence is to handle reset, enum-done and then any other endpoint interrupts. Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com> Tested-by: Robert Baldyga <r.baldyga@samsung.com> Tested-by: Dinh Nguyen <dinguyen@opensource.altera.com> Tested-by: John Youn <johnyoun@synopsys.com> Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--drivers/usb/dwc2/gadget.c60
1 files changed, 30 insertions, 30 deletions
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index ef964814b928..bdda32cefeda 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -2460,6 +2460,36 @@ irq_retry:
2460 2460
2461 gintsts &= gintmsk; 2461 gintsts &= gintmsk;
2462 2462
2463 if (gintsts & GINTSTS_RESETDET) {
2464 dev_dbg(hsotg->dev, "%s: USBRstDet\n", __func__);
2465
2466 dwc2_writel(GINTSTS_RESETDET, hsotg->regs + GINTSTS);
2467
2468 /* This event must be used only if controller is suspended */
2469 if (hsotg->lx_state == DWC2_L2) {
2470 dwc2_exit_hibernation(hsotg, true);
2471 hsotg->lx_state = DWC2_L0;
2472 }
2473 }
2474
2475 if (gintsts & (GINTSTS_USBRST | GINTSTS_RESETDET)) {
2476
2477 u32 usb_status = dwc2_readl(hsotg->regs + GOTGCTL);
2478 u32 connected = hsotg->connected;
2479
2480 dev_dbg(hsotg->dev, "%s: USBRst\n", __func__);
2481 dev_dbg(hsotg->dev, "GNPTXSTS=%08x\n",
2482 dwc2_readl(hsotg->regs + GNPTXSTS));
2483
2484 dwc2_writel(GINTSTS_USBRST, hsotg->regs + GINTSTS);
2485
2486 /* Report disconnection if it is not already done. */
2487 dwc2_hsotg_disconnect(hsotg);
2488
2489 if (usb_status & GOTGCTL_BSESVLD && connected)
2490 dwc2_hsotg_core_init_disconnected(hsotg, true);
2491 }
2492
2463 if (gintsts & GINTSTS_ENUMDONE) { 2493 if (gintsts & GINTSTS_ENUMDONE) {
2464 dwc2_writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS); 2494 dwc2_writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS);
2465 2495
@@ -2491,36 +2521,6 @@ irq_retry:
2491 } 2521 }
2492 } 2522 }
2493 2523
2494 if (gintsts & GINTSTS_RESETDET) {
2495 dev_dbg(hsotg->dev, "%s: USBRstDet\n", __func__);
2496
2497 dwc2_writel(GINTSTS_RESETDET, hsotg->regs + GINTSTS);
2498
2499 /* This event must be used only if controller is suspended */
2500 if (hsotg->lx_state == DWC2_L2) {
2501 dwc2_exit_hibernation(hsotg, true);
2502 hsotg->lx_state = DWC2_L0;
2503 }
2504 }
2505
2506 if (gintsts & (GINTSTS_USBRST | GINTSTS_RESETDET)) {
2507
2508 u32 usb_status = dwc2_readl(hsotg->regs + GOTGCTL);
2509 u32 connected = hsotg->connected;
2510
2511 dev_dbg(hsotg->dev, "%s: USBRst\n", __func__);
2512 dev_dbg(hsotg->dev, "GNPTXSTS=%08x\n",
2513 dwc2_readl(hsotg->regs + GNPTXSTS));
2514
2515 dwc2_writel(GINTSTS_USBRST, hsotg->regs + GINTSTS);
2516
2517 /* Report disconnection if it is not already done. */
2518 dwc2_hsotg_disconnect(hsotg);
2519
2520 if (usb_status & GOTGCTL_BSESVLD && connected)
2521 dwc2_hsotg_core_init_disconnected(hsotg, true);
2522 }
2523
2524 /* check both FIFOs */ 2524 /* check both FIFOs */
2525 2525
2526 if (gintsts & GINTSTS_NPTXFEMP) { 2526 if (gintsts & GINTSTS_NPTXFEMP) {