diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-08-09 09:03:47 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-08-09 09:03:47 +0200 |
commit | bd935a7b21340e2e37f51a7f2d3188145e2fcf1f (patch) | |
tree | ac8af4e6ea552d32839c415b2f36d416ee327ea4 /drivers/usb/dwc3/gadget.c | |
parent | 96ba6c6e8922e89ca4908c650072d8f8d7b39cbc (diff) | |
parent | 36a21d51725af2ce0700c6ebcb6b9594aac658a6 (diff) | |
download | linux-bd935a7b21340e2e37f51a7f2d3188145e2fcf1f.tar.gz linux-bd935a7b21340e2e37f51a7f2d3188145e2fcf1f.tar.bz2 linux-bd935a7b21340e2e37f51a7f2d3188145e2fcf1f.zip |
Merge 5.14-rc5 into driver-core-next
We need the driver core fixes in here as well.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 45f2bc0807e8..b8d4b2d327b2 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1741,9 +1741,13 @@ static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep) { struct dwc3_request *req; struct dwc3_request *tmp; + struct list_head local; struct dwc3 *dwc = dep->dwc; - list_for_each_entry_safe(req, tmp, &dep->cancelled_list, list) { +restart: + list_replace_init(&dep->cancelled_list, &local); + + list_for_each_entry_safe(req, tmp, &local, list) { dwc3_gadget_ep_skip_trbs(dep, req); switch (req->status) { case DWC3_REQUEST_STATUS_DISCONNECTED: @@ -1761,6 +1765,9 @@ static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep) break; } } + + if (!list_empty(&dep->cancelled_list)) + goto restart; } static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, @@ -2250,6 +2257,17 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) } /* + * Avoid issuing a runtime resume if the device is already in the + * suspended state during gadget disconnect. DWC3 gadget was already + * halted/stopped during runtime suspend. + */ + if (!is_on) { + pm_runtime_barrier(dwc->dev); + if (pm_runtime_suspended(dwc->dev)) + return 0; + } + + /* * Check the return value for successful resume, or error. For a * successful resume, the DWC3 runtime PM resume routine will handle * the run stop sequence, so avoid duplicate operations here. @@ -2958,8 +2976,12 @@ static void dwc3_gadget_ep_cleanup_completed_requests(struct dwc3_ep *dep, { struct dwc3_request *req; struct dwc3_request *tmp; + struct list_head local; - list_for_each_entry_safe(req, tmp, &dep->started_list, list) { +restart: + list_replace_init(&dep->started_list, &local); + + list_for_each_entry_safe(req, tmp, &local, list) { int ret; ret = dwc3_gadget_ep_cleanup_completed_request(dep, event, @@ -2967,6 +2989,9 @@ static void dwc3_gadget_ep_cleanup_completed_requests(struct dwc3_ep *dep, if (ret) break; } + + if (!list_empty(&dep->started_list)) + goto restart; } static bool dwc3_gadget_ep_should_continue(struct dwc3_ep *dep) |