FROMGIT: usb: dwc3: gadget: Fix START_TRANSFER link state check
The START_TRANSFER command needs to be executed while in ON/U0 link state (with an exception during register initialization). Don't use dwc->link_state to check this since the driver only tracks the link state when the link state change interrupt is enabled. Check the link state from DSTS register instead. Note that often the host already brings the device out of low power before it sends/requests the next transfer. So, the user won't see any issue when the device starts transfer then. This issue is more noticeable in cases when the device delays starting transfer, which can happen during delayed control status after the host put the device in low power. Fixes:799e9dc829("usb: dwc3: gadget: conditionally disable Link State change events") Cc: <stable@vger.kernel.org> Acked-by: Felipe Balbi <balbi@kernel.org> Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/bcefaa9ecbc3e1936858c0baa14de6612960e909.1618884221.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> (cherry picked from commitc560e76319https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-next) Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I19ddf77f506ee44c05c6d2be8dc30e351bf6d94d
This commit is contained in:
parent
fcd2a56bb0
commit
ee5af5cb09
1 changed files with 7 additions and 6 deletions
|
|
@ -308,13 +308,12 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
|
|||
}
|
||||
|
||||
if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_STARTTRANSFER) {
|
||||
int needs_wakeup;
|
||||
int link_state;
|
||||
|
||||
needs_wakeup = (dwc->link_state == DWC3_LINK_STATE_U1 ||
|
||||
dwc->link_state == DWC3_LINK_STATE_U2 ||
|
||||
dwc->link_state == DWC3_LINK_STATE_U3);
|
||||
|
||||
if (unlikely(needs_wakeup)) {
|
||||
link_state = dwc3_gadget_get_link_state(dwc);
|
||||
if (link_state == DWC3_LINK_STATE_U1 ||
|
||||
link_state == DWC3_LINK_STATE_U2 ||
|
||||
link_state == DWC3_LINK_STATE_U3) {
|
||||
ret = __dwc3_gadget_wakeup(dwc);
|
||||
dev_WARN_ONCE(dwc->dev, ret, "wakeup failed --> %d\n",
|
||||
ret);
|
||||
|
|
@ -1983,6 +1982,8 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
|
|||
case DWC3_LINK_STATE_RESET:
|
||||
case DWC3_LINK_STATE_RX_DET: /* in HS, means Early Suspend */
|
||||
case DWC3_LINK_STATE_U3: /* in HS, means SUSPEND */
|
||||
case DWC3_LINK_STATE_U2: /* in HS, means Sleep (L1) */
|
||||
case DWC3_LINK_STATE_U1:
|
||||
case DWC3_LINK_STATE_RESUME:
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue