From 66a28a886a94fe255fd96ffbe849f33fae72477d Mon Sep 17 00:00:00 2001 From: Rohith Kollalsi Date: Tue, 2 Nov 2021 17:35:47 +0530 Subject: [PATCH] usb: dwc3: Resume the controller before setting device active in sm_work Driver core invokes runtime PM idle after the device is probed. When the runtime idle callback returns 0, platform bus proceed to runtime suspend. If this races with state machine work which marks the runtime state as active and enables runtime PM, there is a possibility that the runtime PM thinks device is suspended. Because the runtime PM suspend patch returns simply because in_lpm is true. Now, state machine work calls dwc3_msm_resume() which sets WAIT_FOR_LPM flag hoping that it would be cleared while runtime suspend happens via pm_runtime_put_sync(). Though the device is in resume state, runtime PM core thinks it is suspended due to the race mentioned above. The fact that WAIT_FOR_LPM is set, state machine for ever stuck in DRD_STATE_IDLE waiting for this flag to be cleared. Fix this by calling dwc3_msm_resume before setting device as active so that the corresponding pm_runtime_put_sync operation happens correctly. Change-Id: I3ee58ca01d2afdf169b1f52816d7d4d448cbf8e6 Signed-off-by: Rohith Kollalsi --- drivers/usb/dwc3/dwc3-msm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index d3cb07b02cde..959700da4498 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -5742,10 +5742,10 @@ static void dwc3_otg_sm_work(struct work_struct *w) if (test_bit(ID, &mdwc->inputs) && !test_bit(B_SESS_VLD, &mdwc->inputs)) { dbg_event(0xFF, "undef_id_!bsv", 0); + dwc3_msm_resume(mdwc); pm_runtime_set_active(mdwc->dev); pm_runtime_enable(mdwc->dev); pm_runtime_get_noresume(mdwc->dev); - dwc3_msm_resume(mdwc); pm_runtime_put_sync(mdwc->dev); dbg_event(0xFF, "Undef NoUSB", atomic_read(&mdwc->dev->power.usage_count));