usb: dwc2: gadget: add reset flag in init function
authorGregory Herrero <gregory.herrero@intel.com>
Fri, 30 Jan 2015 08:09:32 +0000 (09:09 +0100)
committerFelipe Balbi <balbi@ti.com>
Fri, 30 Jan 2015 16:32:41 +0000 (10:32 -0600)
Add a flag to request physical reset of the controller when
s3c_hsotg_core_init_disconnected is called.
During the usb reset, controller must not be fully reconfigured and
resetted. Else this leads to shorter chirp-k duration during
enumeration.

Tested-by: Robert Baldyga <r.baldyga@samsung.com>
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/dwc2/core.h
drivers/usb/dwc2/gadget.c
drivers/usb/dwc2/hcd.c

index 485b195126e728d0d6f3a1f0f11213dbbdb58f7f..f74304b12652062d43335e266812fe4cb645a822 100644 (file)
@@ -999,7 +999,8 @@ extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg);
 extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2);
 extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2);
 extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq);
-extern void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2);
+extern void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2,
+               bool reset);
 extern void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg);
 extern void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2);
 #else
@@ -1011,7 +1012,8 @@ static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2)
 { return 0; }
 static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
 { return 0; }
-static inline void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2) {}
+static inline void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2,
+               bool reset) {}
 static inline void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg) {}
 static inline void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2) {}
 #endif
index 5e91cf154bba33589a8dfe67785e8fa3055478fe..3cf9c6a5e2c78a532251c69cc85c4582e4f00664 100644 (file)
@@ -2271,9 +2271,13 @@ static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg)
  *
  * Issue a soft reset to the core, and await the core finishing it.
  */
-void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg)
+void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
+                                               bool is_usb_reset)
 {
-       s3c_hsotg_corereset(hsotg);
+       u32 val;
+
+       if (!is_usb_reset)
+               s3c_hsotg_corereset(hsotg);
 
        /*
         * we must now enable ep0 ready for host detection and then
@@ -2286,7 +2290,8 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg)
 
        s3c_hsotg_init_fifo(hsotg);
 
-       __orr32(hsotg->regs + DCTL, DCTL_SFTDISCON);
+       if (!is_usb_reset)
+               __orr32(hsotg->regs + DCTL, DCTL_SFTDISCON);
 
        writel(1 << 18 | DCFG_DEVSPD_HS,  hsotg->regs + DCFG);
 
@@ -2357,9 +2362,11 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg)
        s3c_hsotg_ctrl_epint(hsotg, 0, 0, 1);
        s3c_hsotg_ctrl_epint(hsotg, 0, 1, 1);
 
-       __orr32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE);
-       udelay(10);  /* see openiboot */
-       __bic32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE);
+       if (!is_usb_reset) {
+               __orr32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE);
+               udelay(10);  /* see openiboot */
+               __bic32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE);
+       }
 
        dev_dbg(hsotg->dev, "DCTL=0x%08x\n", readl(hsotg->regs + DCTL));
 
@@ -2388,8 +2395,10 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg)
                readl(hsotg->regs + DOEPCTL0));
 
        /* clear global NAKs */
-       writel(DCTL_CGOUTNAK | DCTL_CGNPINNAK | DCTL_SFTDISCON,
-              hsotg->regs + DCTL);
+       val = DCTL_CGOUTNAK | DCTL_CGNPINNAK;
+       if (!is_usb_reset)
+               val |= DCTL_SFTDISCON;
+       __orr32(hsotg->regs + DCTL, val);
 
        /* must be at-least 3ms to allow bus to see disconnect */
        mdelay(3);
@@ -2482,7 +2491,7 @@ irq_retry:
                                kill_all_requests(hsotg, hsotg->eps_out[0],
                                                          -ECONNRESET);
 
-                               s3c_hsotg_core_init_disconnected(hsotg);
+                               s3c_hsotg_core_init_disconnected(hsotg, true);
                                s3c_hsotg_core_connect(hsotg);
                        }
                }
@@ -3052,7 +3061,7 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget,
 
        spin_lock_irqsave(&hsotg->lock, flags);
        s3c_hsotg_init(hsotg);
-       s3c_hsotg_core_init_disconnected(hsotg);
+       s3c_hsotg_core_init_disconnected(hsotg, false);
        hsotg->enabled = 0;
        spin_unlock_irqrestore(&hsotg->lock, flags);
 
@@ -3171,7 +3180,7 @@ static int s3c_hsotg_vbus_session(struct usb_gadget *gadget, int is_active)
        if (is_active) {
                /* Kill any ep0 requests as controller will be reinitialized */
                kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET);
-               s3c_hsotg_core_init_disconnected(hsotg);
+               s3c_hsotg_core_init_disconnected(hsotg, false);
                if (hsotg->enabled)
                        s3c_hsotg_core_connect(hsotg);
        } else {
@@ -4097,7 +4106,7 @@ int s3c_hsotg_resume(struct dwc2_hsotg *hsotg)
                s3c_hsotg_phy_enable(hsotg);
 
                spin_lock_irqsave(&hsotg->lock, flags);
-               s3c_hsotg_core_init_disconnected(hsotg);
+               s3c_hsotg_core_init_disconnected(hsotg, false);
                if (hsotg->enabled)
                        s3c_hsotg_core_connect(hsotg);
                spin_unlock_irqrestore(&hsotg->lock, flags);
index 4a9bcdd5cb23090108b482530a7bcb87b01227ef..c78c8740db1d7855967d441a21ae1ffafe3d26fc 100644 (file)
@@ -1373,7 +1373,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work)
                hsotg->op_state = OTG_STATE_B_PERIPHERAL;
                dwc2_core_init(hsotg, false, -1);
                dwc2_enable_global_interrupts(hsotg);
-               s3c_hsotg_core_init_disconnected(hsotg);
+               s3c_hsotg_core_init_disconnected(hsotg, false);
                s3c_hsotg_core_connect(hsotg);
        } else {
                /* A-Device connector (Host Mode) */