usb: dwc2: gadget: report disconnection after reset
authorMian Yousaf Kaukab <yousaf.kaukab@intel.com>
Fri, 9 Jan 2015 12:39:10 +0000 (13:39 +0100)
committerFelipe Balbi <balbi@ti.com>
Mon, 12 Jan 2015 21:34:58 +0000 (15:34 -0600)
If usb bus is reset without a physical disconnection, all endpoints
will remain open. Call s3c_hsotg_disconnect() from reset handler to
report a disconnect to gadget framework. hsotg->connected is checked
in s3c_hsotg_disconnect() before processing disconnect.

In some cases, USBRst is seen before EnumDone and after it as well.
So move setting of hsotg->connected to set-address to avoid reporting
extra disconnection in this case.

Tested-by: Robert Baldyga <r.baldyga@samsung.com>
Acked-by: Paul Zimmerman <paulz@synopsys.com>
Signed-off-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/dwc2/gadget.c

index df9080d..882a1a8 100644 (file)
@@ -1103,6 +1103,7 @@ static void s3c_hsotg_process_control(struct dwc2_hsotg *hsotg,
        if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
                switch (ctrl->bRequest) {
                case USB_REQ_SET_ADDRESS:
+                       hsotg->connected = 1;
                        dcfg = readl(hsotg->regs + DCFG);
                        dcfg &= ~DCFG_DEVADDR_MASK;
                        dcfg |= (le16_to_cpu(ctrl->wValue) <<
@@ -2305,7 +2306,6 @@ irq_retry:
                writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS);
 
                s3c_hsotg_irq_enumdone(hsotg);
-               hsotg->connected = 1;
        }
 
        if (gintsts & (GINTSTS_OEPINT | GINTSTS_IEPINT)) {
@@ -2343,6 +2343,9 @@ irq_retry:
 
                writel(GINTSTS_USBRST, hsotg->regs + GINTSTS);
 
+               /* Report disconnection if it is not already done. */
+               s3c_hsotg_disconnect(hsotg);
+
                if (usb_status & GOTGCTL_BSESVLD) {
                        if (time_after(jiffies, hsotg->last_rst +
                                       msecs_to_jiffies(200))) {