From: wlf Date: Mon, 9 Jun 2014 01:40:06 +0000 (+0800) Subject: USB: fix usb host hot-plug bug. X-Git-Tag: firefly_0821_release~5163 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=f534474238945717d9a78396589e7d1e63861336;p=firefly-linux-kernel-4.4.55.git USB: fix usb host hot-plug bug. --- diff --git a/drivers/usb/dwc_otg_310/dwc_otg_hcd.c b/drivers/usb/dwc_otg_310/dwc_otg_hcd.c index 06fc33531e11..30a8bf1fa32c 100755 --- a/drivers/usb/dwc_otg_310/dwc_otg_hcd.c +++ b/drivers/usb/dwc_otg_310/dwc_otg_hcd.c @@ -276,7 +276,21 @@ static int32_t dwc_otg_hcd_disconnect_cb(void *p) { gintsts_data_t intr; dwc_otg_hcd_t *dwc_otg_hcd = p; + hprt0_data_t hprt0; + + dwc_otg_hcd->non_periodic_qh_ptr = &dwc_otg_hcd->non_periodic_sched_active; + dwc_otg_hcd->non_periodic_channels = 0; + dwc_otg_hcd->periodic_channels = 0; + hprt0.d32 = DWC_READ_REG32(dwc_otg_hcd->core_if->host_if->hprt0); + /* In some case, we don't disconnect a usb device, but + * disconnect intr was triggered, so check hprt0 here. */ + if ((!hprt0.b.prtenchng) + && (hprt0.d32 != 0x1000) + && (hprt0.d32 != 0x1100)) { + DWC_PRINTF("%s: hprt0 = 0x%08x\n", __func__, hprt0.d32); + return 1; + } /* * Set status flags for the hub driver. */ @@ -313,6 +327,7 @@ static int32_t dwc_otg_hcd_disconnect_cb(void *p) /** Delete timers if become device */ del_timers(dwc_otg_hcd); dwc_otg_disable_host_interrupts(dwc_otg_hcd->core_if); + goto out; } /* Respond with an error status to all URBs in the schedule. */ @@ -385,6 +400,7 @@ static int32_t dwc_otg_hcd_disconnect_cb(void *p) } } +out: if (dwc_otg_hcd->fops->disconnect) { dwc_otg_hcd->fops->disconnect(dwc_otg_hcd); } diff --git a/drivers/usb/dwc_otg_310/dwc_otg_hcd_intr.c b/drivers/usb/dwc_otg_310/dwc_otg_hcd_intr.c index fb6de91b5a5d..9065863c3048 100755 --- a/drivers/usb/dwc_otg_310/dwc_otg_hcd_intr.c +++ b/drivers/usb/dwc_otg_310/dwc_otg_hcd_intr.c @@ -48,7 +48,6 @@ int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t *dwc_otg_hcd) { int retval = 0; - dwc_irqflags_t flags; dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if; gintsts_data_t gintsts; @@ -65,12 +64,12 @@ int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t *dwc_otg_hcd) if (core_if->hibernation_suspend == 1) { return retval; } - DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags); + DWC_SPINLOCK(dwc_otg_hcd->lock); /* Check if HOST Mode */ if (dwc_otg_is_host_mode(core_if)) { gintsts.d32 = dwc_otg_read_core_intr(core_if); if (!gintsts.d32) { - DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags); + DWC_SPINUNLOCK(dwc_otg_hcd->lock); return 0; } #ifdef DEBUG @@ -139,7 +138,7 @@ int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t *dwc_otg_hcd) #endif } - DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags); + DWC_SPINUNLOCK(dwc_otg_hcd->lock); return retval; }