Skip to content

Commit

Permalink
usb: dwc3: gadget: Allow runtime suspend if UDC unbinded
Browse files Browse the repository at this point in the history
The DWC3 runtime suspend routine checks for the USB connected parameter to
determine if the controller can enter into a low power state.  The
connected state is only set to false after receiving a disconnect event.
However, in the case of a device initiated disconnect (i.e. UDC unbind),
the controller is halted and a disconnect event is never generated.  Set
the connected flag to false if issuing a device initiated disconnect to
allow the controller to be suspended.

Signed-off-by: Wesley Cheng <wcheng@codeaurora.org>
Link: https://lore.kernel.org/r/1609283136-22140-2-git-send-email-wcheng@codeaurora.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Wesley Cheng authored and Greg Kroah-Hartman committed Jan 4, 2021
1 parent 8280de6 commit 77adb8b
Showing 1 changed file with 13 additions and 0 deletions.
13 changes: 13 additions & 0 deletions drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -2107,6 +2107,17 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
}
}

/*
* 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.
*/
ret = pm_runtime_get_sync(dwc->dev);
if (!ret || ret < 0) {
pm_runtime_put(dwc->dev);
return 0;
}

/*
* Synchronize any pending event handling before executing the controller
* halt routine.
Expand Down Expand Up @@ -2145,10 +2156,12 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) %
dwc->ev_buf->length;
}
dwc->connected = false;
}

ret = dwc3_gadget_run_stop(dwc, is_on, false);
spin_unlock_irqrestore(&dwc->lock, flags);
pm_runtime_put(dwc->dev);

return ret;
}
Expand Down

0 comments on commit 77adb8b

Please sign in to comment.