Loading drivers/usb/dwc3/gadget.c +24 −9 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ module_param(bulk_ep_xfer_timeout_ms, int, S_IRUGO | S_IWUSR); static void dwc3_gadget_usb2_phy_suspend(struct dwc3 *dwc, int suspend); static void dwc3_gadget_usb3_phy_suspend(struct dwc3 *dwc, int suspend); static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc); static void _dwc3_gadget_wakeup(struct dwc3 *dwc); static int dwc3_gadget_wakeup_int(struct dwc3 *dwc); struct dwc3_usb_gadget { Loading Loading @@ -1442,22 +1442,29 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) static int dwc3_gadget_wakeup(struct usb_gadget *g) { int ret = 0; struct dwc3_usb_gadget *dwc3_gadget = g->private; struct dwc3 *dwc = dwc3_gadget->dwc; unsigned long flags; spin_lock_irqsave(&dwc->lock, flags); if (atomic_read(&dwc->in_lpm)) { spin_unlock_irqrestore(&dwc->lock, flags); schedule_work(&dwc3_gadget->wakeup_work); return -EBUSY; pr_debug("Core is in low-power mode. Scheduling wakeup work.\n"); ret = -EBUSY; } else { _dwc3_gadget_wakeup(dwc); pr_debug("Core is active. Initiating remote wakeup.\n"); ret = dwc3_gadget_wakeup_int(dwc); if (ret) pr_err("Remote wakeup failed. ret = %d\n", ret); else pr_debug("Remote wake up succeeded.\n"); } spin_unlock_irqrestore(&dwc->lock, flags); return 0; return ret; } static inline enum dwc3_link_state dwc3_get_link_state(struct dwc3 *dwc) Loading Loading @@ -1688,6 +1695,7 @@ static void dwc3_gadget_wakeup_work(struct work_struct *w) struct dwc3_usb_gadget *dwc3_gadget; struct dwc3 *dwc; unsigned long flags; int ret; dwc3_gadget = container_of(w, struct dwc3_usb_gadget, wakeup_work); dwc = dwc3_gadget->dwc; Loading @@ -1701,11 +1709,17 @@ static void dwc3_gadget_wakeup_work(struct work_struct *w) spin_lock_irqsave(&dwc->lock, flags); } _dwc3_gadget_wakeup(dwc); ret = dwc3_gadget_wakeup_int(dwc); if (ret) pr_err("Remote wakeup failed. ret = %d.\n", ret); else pr_debug("Remote wakeup succeeded.\n"); spin_unlock_irqrestore(&dwc->lock, flags); } static void _dwc3_gadget_wakeup(struct dwc3 *dwc) static int dwc3_gadget_wakeup_int(struct dwc3 *dwc) { u32 timeout = 0; bool link_recover_only = false; Loading Loading @@ -1768,6 +1782,7 @@ static void _dwc3_gadget_wakeup(struct dwc3 *dwc) if (DWC3_DSTS_USBLNKST(reg) != DWC3_LINK_STATE_U0) { dev_err(dwc->dev, "failed to send remote wakeup\n"); ret = -EINVAL; goto out; } /* Loading @@ -1781,7 +1796,7 @@ static void _dwc3_gadget_wakeup(struct dwc3 *dwc) dwc3_gadget_wakeup_interrupt(dwc); out: return; return ret; } static int dwc_gadget_func_wakeup(struct usb_gadget *g, int interface_id) Loading Loading @@ -3045,7 +3060,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc) { dev_vdbg(dwc->dev, "%s\n", __func__); dev_dbg(dwc->dev, "%s\n", __func__); /* * TODO take core out of low power mode when that's Loading Loading
drivers/usb/dwc3/gadget.c +24 −9 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ module_param(bulk_ep_xfer_timeout_ms, int, S_IRUGO | S_IWUSR); static void dwc3_gadget_usb2_phy_suspend(struct dwc3 *dwc, int suspend); static void dwc3_gadget_usb3_phy_suspend(struct dwc3 *dwc, int suspend); static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc); static void _dwc3_gadget_wakeup(struct dwc3 *dwc); static int dwc3_gadget_wakeup_int(struct dwc3 *dwc); struct dwc3_usb_gadget { Loading Loading @@ -1442,22 +1442,29 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) static int dwc3_gadget_wakeup(struct usb_gadget *g) { int ret = 0; struct dwc3_usb_gadget *dwc3_gadget = g->private; struct dwc3 *dwc = dwc3_gadget->dwc; unsigned long flags; spin_lock_irqsave(&dwc->lock, flags); if (atomic_read(&dwc->in_lpm)) { spin_unlock_irqrestore(&dwc->lock, flags); schedule_work(&dwc3_gadget->wakeup_work); return -EBUSY; pr_debug("Core is in low-power mode. Scheduling wakeup work.\n"); ret = -EBUSY; } else { _dwc3_gadget_wakeup(dwc); pr_debug("Core is active. Initiating remote wakeup.\n"); ret = dwc3_gadget_wakeup_int(dwc); if (ret) pr_err("Remote wakeup failed. ret = %d\n", ret); else pr_debug("Remote wake up succeeded.\n"); } spin_unlock_irqrestore(&dwc->lock, flags); return 0; return ret; } static inline enum dwc3_link_state dwc3_get_link_state(struct dwc3 *dwc) Loading Loading @@ -1688,6 +1695,7 @@ static void dwc3_gadget_wakeup_work(struct work_struct *w) struct dwc3_usb_gadget *dwc3_gadget; struct dwc3 *dwc; unsigned long flags; int ret; dwc3_gadget = container_of(w, struct dwc3_usb_gadget, wakeup_work); dwc = dwc3_gadget->dwc; Loading @@ -1701,11 +1709,17 @@ static void dwc3_gadget_wakeup_work(struct work_struct *w) spin_lock_irqsave(&dwc->lock, flags); } _dwc3_gadget_wakeup(dwc); ret = dwc3_gadget_wakeup_int(dwc); if (ret) pr_err("Remote wakeup failed. ret = %d.\n", ret); else pr_debug("Remote wakeup succeeded.\n"); spin_unlock_irqrestore(&dwc->lock, flags); } static void _dwc3_gadget_wakeup(struct dwc3 *dwc) static int dwc3_gadget_wakeup_int(struct dwc3 *dwc) { u32 timeout = 0; bool link_recover_only = false; Loading Loading @@ -1768,6 +1782,7 @@ static void _dwc3_gadget_wakeup(struct dwc3 *dwc) if (DWC3_DSTS_USBLNKST(reg) != DWC3_LINK_STATE_U0) { dev_err(dwc->dev, "failed to send remote wakeup\n"); ret = -EINVAL; goto out; } /* Loading @@ -1781,7 +1796,7 @@ static void _dwc3_gadget_wakeup(struct dwc3 *dwc) dwc3_gadget_wakeup_interrupt(dwc); out: return; return ret; } static int dwc_gadget_func_wakeup(struct usb_gadget *g, int interface_id) Loading Loading @@ -3045,7 +3060,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc) { dev_vdbg(dwc->dev, "%s\n", __func__); dev_dbg(dwc->dev, "%s\n", __func__); /* * TODO take core out of low power mode when that's Loading