diff options
author | Gregory Herrero <gregory.herrero@intel.com> | 2015-04-29 22:09:03 +0200 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2015-04-29 15:18:49 -0500 |
commit | 3eb42df3ebfbd8d46b831c26ecb90e128ad474a5 (patch) | |
tree | c2a2c523d1599779d44e992b79375e8017aff440 /drivers/usb/dwc2/core_intr.c | |
parent | f81f46e1f530900323b6e32eba1af7244ca69537 (diff) |
usb: dwc2: controller must update lx_state before releasing lock
During suspend, there could a race condition between ep_queue and
suspend interrupt if lx_state is updated after releasing spinlock in
call_gadget(hsotg, suspend).
Acked-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Gregory Herrero <gregory.herrero@intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/dwc2/core_intr.c')
-rw-r--r-- | drivers/usb/dwc2/core_intr.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 6ffb5a9c385e..0b7f2b2e580e 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -439,6 +439,12 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) if (!IS_ERR_OR_NULL(hsotg->uphy)) usb_phy_set_suspend(hsotg->uphy, true); skip_power_saving: + /* + * Change to L2 (suspend) state before releasing + * spinlock + */ + hsotg->lx_state = DWC2_L2; + /* Call gadget suspend callback */ call_gadget(hsotg, suspend); } @@ -446,6 +452,8 @@ skip_power_saving: if (hsotg->op_state == OTG_STATE_A_PERIPHERAL) { dev_dbg(hsotg->dev, "a_peripheral->a_host\n"); + /* Change to L2 (suspend) state */ + hsotg->lx_state = DWC2_L2; /* Clear the a_peripheral flag, back to a_host */ spin_unlock(&hsotg->lock); dwc2_hcd_start(hsotg); @@ -454,9 +462,6 @@ skip_power_saving: } } - /* Change to L2 (suspend) state */ - hsotg->lx_state = DWC2_L2; - clear_int: /* Clear interrupt */ writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS); |