diff options
Diffstat (limited to 'drivers/usb/dwc3/dwc3-msm.c')
-rw-r--r-- | drivers/usb/dwc3/dwc3-msm.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 010331bb80a5..96a16808b028 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -234,6 +234,7 @@ struct dwc3_msm { struct pm_qos_request pm_qos_req_dma; struct delayed_work perf_vote_work; struct delayed_work sdp_check; + struct mutex suspend_resume_mutex; }; #define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */ @@ -1998,8 +1999,10 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc) dbg_event(0xFF, "Ctl Sus", atomic_read(&dwc->in_lpm)); + mutex_lock(&mdwc->suspend_resume_mutex); if (atomic_read(&dwc->in_lpm)) { dev_dbg(mdwc->dev, "%s: Already suspended\n", __func__); + mutex_unlock(&mdwc->suspend_resume_mutex); return 0; } @@ -2016,6 +2019,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc) __func__, evt->count / 4); dbg_print_reg("PENDING DEVICE EVENT", *(u32 *)(evt->buf + evt->lpos)); + mutex_unlock(&mdwc->suspend_resume_mutex); return -EBUSY; } } @@ -2035,6 +2039,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc) dev_dbg(mdwc->dev, "%s: cable disconnected while not in idle otg state\n", __func__); + mutex_unlock(&mdwc->suspend_resume_mutex); return -EBUSY; } @@ -2048,12 +2053,15 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc) pr_err("%s(): Trying to go in LPM with state:%d\n", __func__, dwc->gadget.state); pr_err("%s(): LPM is not performed.\n", __func__); + mutex_unlock(&mdwc->suspend_resume_mutex); return -EBUSY; } ret = dwc3_msm_prepare_suspend(mdwc); - if (ret) + if (ret) { + mutex_unlock(&mdwc->suspend_resume_mutex); return ret; + } /* Initialize variables here */ can_suspend_ssphy = !(mdwc->in_host_mode && @@ -2154,6 +2162,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc) } dev_info(mdwc->dev, "DWC3 in low power mode\n"); + mutex_unlock(&mdwc->suspend_resume_mutex); return 0; } @@ -2165,8 +2174,10 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc) dev_dbg(mdwc->dev, "%s: exiting lpm\n", __func__); + mutex_lock(&mdwc->suspend_resume_mutex); if (!atomic_read(&dwc->in_lpm)) { dev_dbg(mdwc->dev, "%s: Already resumed\n", __func__); + mutex_unlock(&mdwc->suspend_resume_mutex); return 0; } @@ -2301,6 +2312,7 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc) msecs_to_jiffies(1000 * PM_QOS_SAMPLE_SEC)); dbg_event(0xFF, "Ctl Res", atomic_read(&dwc->in_lpm)); + mutex_unlock(&mdwc->suspend_resume_mutex); return 0; } @@ -3188,6 +3200,7 @@ static int dwc3_msm_probe(struct platform_device *pdev) POWER_SUPPLY_PROP_PRESENT, &pval); } + mutex_init(&mdwc->suspend_resume_mutex); /* Update initial VBUS/ID state from extcon */ if (mdwc->extcon_vbus && extcon_get_cable_state_(mdwc->extcon_vbus, EXTCON_USB)) |