From f0d2f413f966b58e3f3d7b0654eacbb16d72a836 Mon Sep 17 00:00:00 2001 From: Feng Mingli Date: Wed, 30 Dec 2015 09:22:29 +0800 Subject: [PATCH] USB: dwc_otg_310: hcd: resume rh when handle disconnect or force mode If the root hub is in suspend, we need to resume it when handle hcd disconnect or force device mode, otherwise the hub driver can't detect the status change when port disconnect or mode change. This issue always happens if connect with an usb device which supports auto-suspend. Test=Plug in an usb device which supports auto-suspend(such as: hub, usb camera, etc.). Wait a few seconds until usb enter auto suspend, then plug out the device or set force device mode, check wheather the device disconnect from the usb bus or not. Change-Id: I0f96bba1b9516b264e75d2d829f46fddc193fca7 Signed-off-by: Feng Mingli Signed-off-by: William Wu --- drivers/usb/dwc_otg_310/dwc_otg_hcd.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/usb/dwc_otg_310/dwc_otg_hcd.c b/drivers/usb/dwc_otg_310/dwc_otg_hcd.c index 3cb08f261c47..2129de2ace3c 100644 --- a/drivers/usb/dwc_otg_310/dwc_otg_hcd.c +++ b/drivers/usb/dwc_otg_310/dwc_otg_hcd.c @@ -280,6 +280,8 @@ static int32_t dwc_otg_hcd_disconnect_cb(void *p) { gintsts_data_t intr; dwc_otg_hcd_t *dwc_otg_hcd = p; + struct usb_hcd *usb_hcd = dwc_otg_hcd_get_priv_data(dwc_otg_hcd); + struct usb_bus *bus = hcd_to_bus(usb_hcd); hprt0_data_t hprt0; dwc_otg_hcd->non_periodic_qh_ptr = &dwc_otg_hcd->non_periodic_sched_active; @@ -412,6 +414,9 @@ out: dwc_otg_hcd->fops->disconnect(dwc_otg_hcd); } + if ((bus->root_hub) && (usb_hcd->state == HC_STATE_SUSPENDED)) + usb_hcd_resume_root_hub(usb_hcd); + return 1; } @@ -476,6 +481,8 @@ void dwc_otg_hcd_stop(dwc_otg_hcd_t *hcd) hprt0_data_t hprt0 = {.d32 = 0 }; struct dwc_otg_platform_data *pldata; dwc_irqflags_t flags; + struct usb_hcd *usb_hcd = dwc_otg_hcd_get_priv_data(hcd); + struct usb_bus *bus = hcd_to_bus(usb_hcd); pldata = hcd->core_if->otg_dev->pldata; DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD STOP\n"); @@ -506,6 +513,9 @@ void dwc_otg_hcd_stop(dwc_otg_hcd_t *hcd) if (pldata->power_enable) pldata->power_enable(0); + if ((bus->root_hub) && (usb_hcd->state == HC_STATE_SUSPENDED)) + usb_hcd_resume_root_hub(usb_hcd); + dwc_mdelay(1); }