diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/dwc3/dwc3-msm.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index de6bb295bf67..95e27e097b6b 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -188,6 +188,7 @@ struct dwc3_msm { struct work_struct restart_usb_work; bool in_restart; struct workqueue_struct *dwc3_wq; + struct workqueue_struct *sm_usb_wq; struct delayed_work sm_work; unsigned long inputs; unsigned max_power; @@ -1597,7 +1598,7 @@ static int msm_dwc3_usbdev_notify(struct notifier_block *self, } mdwc->hc_died = true; - schedule_delayed_work(&mdwc->sm_work, 0); + queue_delayed_work(mdwc->sm_usb_wq, &mdwc->sm_work, 0); return 0; } @@ -2358,7 +2359,7 @@ static void dwc3_ext_event_notify(struct dwc3_msm *mdwc) } pm_stay_awake(mdwc->dev); - schedule_delayed_work(&mdwc->sm_work, 0); + queue_delayed_work(mdwc->sm_usb_wq, &mdwc->sm_work, 0); } static void dwc3_resume_work(struct work_struct *w) @@ -2944,6 +2945,12 @@ static int dwc3_msm_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&mdwc->perf_vote_work, msm_dwc3_perf_vote_work); INIT_DELAYED_WORK(&mdwc->sdp_check, check_for_sdp_connection); + mdwc->sm_usb_wq = create_freezable_workqueue("k_sm_usb"); + if (!mdwc->sm_usb_wq) { + pr_err("%s: Failed to create workqueue for sm_usb\n", __func__); + return -ENOMEM; + } + mdwc->dwc3_wq = alloc_ordered_workqueue("dwc3_wq", 0); if (!mdwc->dwc3_wq) { pr_err("%s: Unable to create workqueue dwc3_wq\n", __func__); @@ -3248,7 +3255,7 @@ static int dwc3_msm_probe(struct platform_device *pdev) dwc3_msm_id_notifier(&mdwc->id_nb, true, mdwc->extcon_id); else if (!pval.intval) { /* USB cable is not connected */ - schedule_delayed_work(&mdwc->sm_work, 0); + queue_delayed_work(mdwc->sm_usb_wq, &mdwc->sm_work, 0); } else { if (pval.intval > 0) dev_info(mdwc->dev, "charger detection in progress\n"); @@ -3868,6 +3875,7 @@ static void dwc3_otg_sm_work(struct work_struct *w) break; } else { dwc3_msm_gadget_vbus_draw(mdwc, 0); + pm_relax(mdwc->dev); dev_dbg(mdwc->dev, "Cable disconnected\n"); } break; @@ -3981,7 +3989,7 @@ static void dwc3_otg_sm_work(struct work_struct *w) } if (work) - schedule_delayed_work(&mdwc->sm_work, delay); + queue_delayed_work(mdwc->sm_usb_wq, &mdwc->sm_work, delay); ret: return; @@ -4086,9 +4094,7 @@ static int dwc3_msm_pm_resume(struct device *dev) if (mdwc->no_wakeup_src_in_hostmode && !test_bit(ID, &mdwc->inputs)) dwc3_msm_resume(mdwc); - /* kick in otg state machine */ - if (mdwc->vbus_active || !mdwc->id_state) - queue_work(mdwc->dwc3_wq, &mdwc->resume_work); + queue_work(mdwc->dwc3_wq, &mdwc->resume_work); return 0; } |