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>
This commit is contained in:
parent
f81f46e1f5
commit
3eb42df3eb
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue