Skip to content

Commit

Permalink
usb: dwc2: controller must update lx_state before releasing lock
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Gregory Herrero authored and Felipe Balbi committed Apr 29, 2015
1 parent f81f46e commit 3eb42df
Showing 1 changed file with 8 additions and 3 deletions.
11 changes: 8 additions & 3 deletions drivers/usb/dwc2/core_intr.c
Original file line number Diff line number Diff line change
Expand Up @@ -439,13 +439,21 @@ 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);
}
} else {
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);
Expand All @@ -454,9 +462,6 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
}
}

/* Change to L2 (suspend) state */
hsotg->lx_state = DWC2_L2;

clear_int:
/* Clear interrupt */
writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS);
Expand Down

0 comments on commit 3eb42df

Please sign in to comment.