From: Gregory Herrero <gregory.herrero@xxxxxxxxx> 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). Signed-off-by: Gregory Herrero <gregory.herrero@xxxxxxxxx> --- drivers/usb/dwc2/core_intr.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 42f2fd5..f5ef26e 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -436,6 +436,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); } @@ -443,6 +449,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); @@ -451,9 +459,6 @@ skip_power_saving: } } - /* Change to L2 (suspend) state */ - hsotg->lx_state = DWC2_L2; - clear_int: /* Clear interrupt */ writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html