From 0d9ddf2e820a3ab95f17dc45eff68272f5415137 Mon Sep 17 00:00:00 2001 From: Mayank Rana Date: Mon, 23 Mar 2020 10:39:31 -0700 Subject: [PATCH] dwc3-msm: Check usb role switch status If extcon handler is present and dpdm regulator is absent, current code starts USB state machine without checking usb role switch status. This results into USB PHY being reset while ADSP firmware is performing charger detection. This may result into wrong/invalid charger detection instead of SDP causing no USB enumeration. Fix this issue by checking usb role switch status before kicking USB state machine. Change-Id: Ic25083a74ac867eeb3869588c3060e6bf05e4007 Signed-off-by: Mayank Rana --- drivers/usb/dwc3/dwc3-msm.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index f23c30fdd4f0..48249d1f0c0d 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -4167,6 +4167,16 @@ static int dwc3_msm_probe(struct platform_device *pdev) mutex_init(&mdwc->suspend_resume_mutex); + if (of_property_read_bool(node, "usb-role-switch")) { + role_desc.fwnode = dev_fwnode(&pdev->dev); + mdwc->role_switch = usb_role_switch_register(mdwc->dev, + &role_desc); + if (IS_ERR(mdwc->role_switch)) { + ret = PTR_ERR(mdwc->role_switch); + goto put_dwc3; + } + } + if (of_property_read_bool(node, "extcon")) { ret = dwc3_msm_extcon_register(mdwc); if (ret) @@ -4193,18 +4203,12 @@ static int dwc3_msm_probe(struct platform_device *pdev) regulator_register_notifier(mdwc->dpdm_reg, &mdwc->dpdm_nb); } else { - queue_delayed_work(mdwc->sm_usb_wq, &mdwc->sm_work, 0); + if (!mdwc->role_switch) + queue_delayed_work(mdwc->sm_usb_wq, + &mdwc->sm_work, 0); } } - if (of_property_read_bool(node, "usb-role-switch")) { - role_desc.fwnode = dev_fwnode(&pdev->dev); - mdwc->role_switch = usb_role_switch_register(mdwc->dev, - &role_desc); - if (IS_ERR(mdwc->role_switch)) - return PTR_ERR(mdwc->role_switch); - } - if (!mdwc->role_switch && !mdwc->extcon) { switch (dwc->dr_mode) { case USB_DR_MODE_OTG: @@ -4244,6 +4248,7 @@ static int dwc3_msm_probe(struct platform_device *pdev) return 0; put_dwc3: + usb_role_switch_unregister(mdwc->role_switch); platform_device_put(mdwc->dwc3); for (i = 0; i < ARRAY_SIZE(mdwc->icc_paths); i++) icc_put(mdwc->icc_paths[i]);