diff options
author | Felipe Balbi <felipe.balbi@linux.intel.com> | 2016-04-04 11:46:33 +0200 |
---|---|---|
committer | Felipe Balbi <felipe.balbi@linux.intel.com> | 2016-04-18 14:23:42 +0200 |
commit | c36d8e947a56a6e6478fc48152c5f4626462db55 (patch) | |
tree | dc3f2b9ad069457cc869fe56278cf08332bcdedd /drivers/usb | |
parent | usb: dwc3: gadget: extract unlocked dwc3_gadget_wakeup() (diff) | |
download | linux-c36d8e947a56a6e6478fc48152c5f4626462db55.tar.xz linux-c36d8e947a56a6e6478fc48152c5f4626462db55.zip |
usb: dwc3: gadget: put link to U0 before Start Transfer
Synopsys Databook says we should move link to U0
before issuing a Start Transfer command. We could
require the gadget driver to call
usb_gadget_wakeup() however I feel that changing all
gadget drivers to keep track of Link State and
conditionally call usb_gadget_wakeup() would be far
too much work. For now we will handle this at the
UDC level, but at some point composite.c should be
one handling this.
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 2cc2c1545f49..0e271584e4cf 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -221,6 +221,8 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned cmd, u32 param) } while (1); } +static int __dwc3_gadget_wakeup(struct dwc3 *dwc); + int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, unsigned cmd, struct dwc3_gadget_ep_cmd_params *params) { @@ -248,6 +250,20 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); } + if (cmd == DWC3_DEPCMD_STARTTRANSFER) { + int needs_wakeup; + + 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)) { + ret = __dwc3_gadget_wakeup(dwc); + dev_WARN_ONCE(dwc->dev, ret, "wakeup failed --> %d\n", + ret); + } + } + dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0); dwc3_writel(dwc->regs, DWC3_DEPCMDPAR1(ep), params->param1); dwc3_writel(dwc->regs, DWC3_DEPCMDPAR2(ep), params->param2); |