Loading drivers/usb/dwc3/gadget.c +57 −15 Original line number Diff line number Diff line Loading @@ -814,19 +814,6 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) dbg_log_string("START for %s(%d)", dep->name, dep->number); dwc3_stop_active_transfer(dwc, dep->number, true); /* - giveback all requests to gadget driver */ while (!list_empty(&dep->started_list)) { req = next_request(&dep->started_list); dwc3_gadget_giveback(dep, req, -ESHUTDOWN); } while (!list_empty(&dep->pending_list)) { req = next_request(&dep->pending_list); dwc3_gadget_giveback(dep, req, -ESHUTDOWN); } if (dep->number == 1 && dwc->ep0state != EP0_SETUP_PHASE) { unsigned int dir; Loading @@ -841,6 +828,19 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) dwc->eps[1]->trb_enqueue = 0; } /* - giveback all requests to gadget driver */ while (!list_empty(&dep->started_list)) { req = next_request(&dep->started_list); if (req) dwc3_gadget_giveback(dep, req, -ESHUTDOWN); } while (!list_empty(&dep->pending_list)) { req = next_request(&dep->pending_list); if (req) dwc3_gadget_giveback(dep, req, -ESHUTDOWN); } dbg_log_string("DONE for %s(%d)", dep->name, dep->number); } Loading Loading @@ -2067,6 +2067,38 @@ static int dwc3_gadget_set_selfpowered(struct usb_gadget *g, return 0; } /** * dwc3_device_core_soft_reset - Issues device core soft reset * @dwc: pointer to our context structure */ static int dwc3_device_core_soft_reset(struct dwc3 *dwc) { u32 reg; int retries = 10; reg = dwc3_readl(dwc->regs, DWC3_DCTL); reg |= DWC3_DCTL_CSFTRST; dwc3_writel(dwc->regs, DWC3_DCTL, reg); do { reg = dwc3_readl(dwc->regs, DWC3_DCTL); if (!(reg & DWC3_DCTL_CSFTRST)) goto done; usleep_range(1000, 1100); } while (--retries); dev_err(dwc->dev, "%s timedout\n", __func__); return -ETIMEDOUT; done: /* phy sync delay as per data book */ msleep(50); return 0; } static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend) { u32 reg, reg1; Loading Loading @@ -2229,6 +2261,10 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) ret = dwc3_gadget_run_stop(dwc, is_on, false); spin_unlock_irqrestore(&dwc->lock, flags); if (!is_on && ret == -ETIMEDOUT) { dev_err(dwc->dev, "%s: Core soft reset...\n", __func__); dwc3_device_core_soft_reset(dwc); } enable_irq(dwc->irq); pm_runtime_mark_last_busy(dwc->dev); Loading Loading @@ -2313,6 +2349,7 @@ static int dwc3_gadget_vbus_session(struct usb_gadget *_gadget, int is_active) { struct dwc3 *dwc = gadget_to_dwc(_gadget); unsigned long flags; int ret = 0; if (dwc->dr_mode != USB_DR_MODE_OTG && dwc->dr_mode != USB_DR_MODE_DRD) return -EPERM; Loading Loading @@ -2340,9 +2377,9 @@ static int dwc3_gadget_vbus_session(struct usb_gadget *_gadget, int is_active) * Both vbus was activated by otg and pullup was * signaled by the gadget driver. */ dwc3_gadget_run_stop(dwc, 1, false); ret = dwc3_gadget_run_stop(dwc, 1, false); } else { dwc3_gadget_run_stop(dwc, 0, false); ret = dwc3_gadget_run_stop(dwc, 0, false); } } Loading @@ -2356,8 +2393,13 @@ static int dwc3_gadget_vbus_session(struct usb_gadget *_gadget, int is_active) } spin_unlock_irqrestore(&dwc->lock, flags); if (!is_active && ret == -ETIMEDOUT) { dev_err(dwc->dev, "%s: Core soft reset...\n", __func__); dwc3_device_core_soft_reset(dwc); } enable_irq(dwc->irq); return 0; } Loading Loading
drivers/usb/dwc3/gadget.c +57 −15 Original line number Diff line number Diff line Loading @@ -814,19 +814,6 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) dbg_log_string("START for %s(%d)", dep->name, dep->number); dwc3_stop_active_transfer(dwc, dep->number, true); /* - giveback all requests to gadget driver */ while (!list_empty(&dep->started_list)) { req = next_request(&dep->started_list); dwc3_gadget_giveback(dep, req, -ESHUTDOWN); } while (!list_empty(&dep->pending_list)) { req = next_request(&dep->pending_list); dwc3_gadget_giveback(dep, req, -ESHUTDOWN); } if (dep->number == 1 && dwc->ep0state != EP0_SETUP_PHASE) { unsigned int dir; Loading @@ -841,6 +828,19 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) dwc->eps[1]->trb_enqueue = 0; } /* - giveback all requests to gadget driver */ while (!list_empty(&dep->started_list)) { req = next_request(&dep->started_list); if (req) dwc3_gadget_giveback(dep, req, -ESHUTDOWN); } while (!list_empty(&dep->pending_list)) { req = next_request(&dep->pending_list); if (req) dwc3_gadget_giveback(dep, req, -ESHUTDOWN); } dbg_log_string("DONE for %s(%d)", dep->name, dep->number); } Loading Loading @@ -2067,6 +2067,38 @@ static int dwc3_gadget_set_selfpowered(struct usb_gadget *g, return 0; } /** * dwc3_device_core_soft_reset - Issues device core soft reset * @dwc: pointer to our context structure */ static int dwc3_device_core_soft_reset(struct dwc3 *dwc) { u32 reg; int retries = 10; reg = dwc3_readl(dwc->regs, DWC3_DCTL); reg |= DWC3_DCTL_CSFTRST; dwc3_writel(dwc->regs, DWC3_DCTL, reg); do { reg = dwc3_readl(dwc->regs, DWC3_DCTL); if (!(reg & DWC3_DCTL_CSFTRST)) goto done; usleep_range(1000, 1100); } while (--retries); dev_err(dwc->dev, "%s timedout\n", __func__); return -ETIMEDOUT; done: /* phy sync delay as per data book */ msleep(50); return 0; } static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend) { u32 reg, reg1; Loading Loading @@ -2229,6 +2261,10 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) ret = dwc3_gadget_run_stop(dwc, is_on, false); spin_unlock_irqrestore(&dwc->lock, flags); if (!is_on && ret == -ETIMEDOUT) { dev_err(dwc->dev, "%s: Core soft reset...\n", __func__); dwc3_device_core_soft_reset(dwc); } enable_irq(dwc->irq); pm_runtime_mark_last_busy(dwc->dev); Loading Loading @@ -2313,6 +2349,7 @@ static int dwc3_gadget_vbus_session(struct usb_gadget *_gadget, int is_active) { struct dwc3 *dwc = gadget_to_dwc(_gadget); unsigned long flags; int ret = 0; if (dwc->dr_mode != USB_DR_MODE_OTG && dwc->dr_mode != USB_DR_MODE_DRD) return -EPERM; Loading Loading @@ -2340,9 +2377,9 @@ static int dwc3_gadget_vbus_session(struct usb_gadget *_gadget, int is_active) * Both vbus was activated by otg and pullup was * signaled by the gadget driver. */ dwc3_gadget_run_stop(dwc, 1, false); ret = dwc3_gadget_run_stop(dwc, 1, false); } else { dwc3_gadget_run_stop(dwc, 0, false); ret = dwc3_gadget_run_stop(dwc, 0, false); } } Loading @@ -2356,8 +2393,13 @@ static int dwc3_gadget_vbus_session(struct usb_gadget *_gadget, int is_active) } spin_unlock_irqrestore(&dwc->lock, flags); if (!is_active && ret == -ETIMEDOUT) { dev_err(dwc->dev, "%s: Core soft reset...\n", __func__); dwc3_device_core_soft_reset(dwc); } enable_irq(dwc->irq); return 0; } Loading