From 2c455f7be19ae4deb0884cef204746b386a7e199 Mon Sep 17 00:00:00 2001 From: Azhar Shaikh Date: Mon, 27 Apr 2015 15:09:23 -0700 Subject: usb: dwc3: gadget: Fix PM runtime get/put in case of remote wakeup In case of remote wakeup interrupt, dwc3_gadget_wakeup_work() does a pm_runtime_get_sync() and dwc3_gadget_wakeup_interrupt() does not notify OTG state machine about this state change. Due to which OTG will be still in B_SUSPEND state. Now when bus suspend happens, since OTG state machine is already in B_SUSPEND state, it does not do a pm_runtime_put_autosuspend() and the count is not decremented. To fix, this do an unconditional pm_runtime_get_sync() and pm_runtime_put_noidle() in dwc3_gadget_wakeup_work() to avoid any unclocked register access. In dwc3_gadget_wakeup_interrupt() kick in SM machine in all cases and handle the remote wakeup same as host initiated resume, by clearing the B_SUSPEND bit so that OTG state machine moves to B_PERIPHERAL state. CRs-fixed: 829205 Change-Id: I270df517d5dd58fe28bf0087e0ba951c4e9e15ba Signed-off-by: Azhar Shaikh --- drivers/usb/dwc3/gadget.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f9ded176b77d..c615d5917867 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1512,11 +1512,9 @@ static void dwc3_gadget_wakeup_work(struct work_struct *w) dwc = container_of(w, struct dwc3, wakeup_work); - if (atomic_read(&dwc->in_lpm)) { - pm_runtime_get_sync(dwc->dev); - dbg_event(0xFF, "Gdgwake gsyn", - atomic_read(&dwc->dev->power.usage_count)); - } + pm_runtime_get_sync(dwc->dev); + dbg_event(0xFF, "Gdgwake gsyn", + atomic_read(&dwc->dev->power.usage_count)); ret = dwc3_gadget_wakeup_int(dwc); @@ -1524,6 +1522,10 @@ static void dwc3_gadget_wakeup_work(struct work_struct *w) pr_err("Remote wakeup failed. ret = %d.\n", ret); else pr_debug("Remote wakeup succeeded.\n"); + + pm_runtime_put_noidle(dwc->dev); + dbg_event(0xFF, "Gdgwake put", + atomic_read(&dwc->dev->power.usage_count)); } static int dwc3_gadget_wakeup_int(struct dwc3 *dwc) -- cgit v1.2.3