usb: dwc_otg: double check disconnect state when otg state
authorlyz <lyz@rock-chips.com>
Mon, 19 Jan 2015 11:17:37 +0000 (19:17 +0800)
committerlyz <lyz@rock-chips.com>
Fri, 23 Jan 2015 09:08:18 +0000 (17:08 +0800)
changed

When otg stop host mode and before change to device mode hcd_stop
function should do something to double check all usb device is
disconnect because the disconnect interrupt might be lost.
1.kill all active urbs attached to this hcd
2.set hcd->flags to notify usb core to disconnect all usb devices

Signed-off-by: lyz <lyz@rock-chips.com>
drivers/usb/dwc_otg_310/dwc_otg_hcd.c

index 9bde3ba4da05c4b56c3547d47ddabcde50f042a1..451424e842042205760df4ac55e104bd079d774f 100755 (executable)
@@ -471,8 +471,9 @@ void dwc_otg_hcd_stop(dwc_otg_hcd_t *hcd)
 {
        hprt0_data_t hprt0 = {.d32 = 0 };
        struct dwc_otg_platform_data *pldata;
-       pldata = hcd->core_if->otg_dev->pldata;
+       dwc_irqflags_t flags;
 
+       pldata = hcd->core_if->otg_dev->pldata;
        DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD STOP\n");
 
        /*
@@ -480,6 +481,15 @@ void dwc_otg_hcd_stop(dwc_otg_hcd_t *hcd)
         * The disconnect will clear the QTD lists (via ..._hcd_urb_dequeue)
         * and the QH lists (via ..._hcd_endpoint_disable).
         */
+       DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags);
+       kill_all_urbs(hcd);
+       DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags);
+
+       /*
+        * Set status flags for the hub driver.
+        */
+       hcd->flags.b.port_connect_status_change = 1;
+       hcd->flags.b.port_connect_status = 0;
 
        /* Turn off all host-specific interrupts. */
        dwc_otg_disable_host_interrupts(hcd->core_if);