usb: dwc3-msm: Ensure hardware is reset during role change
Introduce additional WAIT_FOR_LPM input flag to ensure USB enters low power mode after stop_peripheral or stop_host. This makes sure that USB hardware is reset after LPM for cases where quick transition to host mode happens while its child was still preventing dwc3 to enter low power mode. In the absence of h/w reset after stop_peripheral, host mode doesn't work. Change-Id: I67e4fcdc11a3337e3e90b4ca8f461e328a6e8ecf Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
This commit is contained in:
parent
582ce26ce1
commit
7d34ffa6c3
1 changed files with 18 additions and 0 deletions
|
@ -174,6 +174,7 @@ enum plug_orientation {
|
|||
#define ID 0
|
||||
#define B_SESS_VLD 1
|
||||
#define B_SUSPEND 2
|
||||
#define WAIT_FOR_LPM 3
|
||||
|
||||
#define PM_QOS_SAMPLE_SEC 2
|
||||
#define PM_QOS_THRESHOLD 400
|
||||
|
@ -2214,7 +2215,13 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool hibernation)
|
|||
}
|
||||
|
||||
dev_info(mdwc->dev, "DWC3 in low power mode\n");
|
||||
|
||||
/* kick_sm if it is waiting for lpm sequence to finish */
|
||||
if (test_and_clear_bit(WAIT_FOR_LPM, &mdwc->inputs))
|
||||
schedule_delayed_work(&mdwc->sm_work, 0);
|
||||
|
||||
mutex_unlock(&mdwc->suspend_resume_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3724,6 +3731,9 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on)
|
|||
if (!mdwc->host_only_mode)
|
||||
dwc3_post_host_reset_core_init(dwc);
|
||||
|
||||
/* wait for LPM, to ensure h/w is reset after stop_host */
|
||||
set_bit(WAIT_FOR_LPM, &mdwc->inputs);
|
||||
|
||||
pm_runtime_mark_last_busy(mdwc->dev);
|
||||
pm_runtime_put_sync_autosuspend(mdwc->dev);
|
||||
dbg_event(0xFF, "StopHost psync",
|
||||
|
@ -3804,6 +3814,9 @@ static int dwc3_otg_start_peripheral(struct dwc3_msm *mdwc, int on)
|
|||
usb_phy_notify_disconnect(mdwc->ss_phy, USB_SPEED_SUPER);
|
||||
dwc3_override_vbus_status(mdwc, false);
|
||||
dwc3_usb3_phy_suspend(dwc, false);
|
||||
|
||||
/* wait for LPM, to ensure h/w is reset after stop_peripheral */
|
||||
set_bit(WAIT_FOR_LPM, &mdwc->inputs);
|
||||
}
|
||||
|
||||
pm_runtime_put_sync(mdwc->dev);
|
||||
|
@ -3920,6 +3933,11 @@ static void dwc3_otg_sm_work(struct work_struct *w)
|
|||
pm_runtime_enable(mdwc->dev);
|
||||
/* fall-through */
|
||||
case DRD_STATE_IDLE:
|
||||
if (test_bit(WAIT_FOR_LPM, &mdwc->inputs)) {
|
||||
dev_dbg(mdwc->dev, "still not in lpm, wait.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!test_bit(ID, &mdwc->inputs)) {
|
||||
dev_dbg(mdwc->dev, "!id\n");
|
||||
mdwc->drd_state = DRD_STATE_HOST_IDLE;
|
||||
|
|
Loading…
Add table
Reference in a new issue