Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7143a1e4 authored by Manu Gautam's avatar Manu Gautam
Browse files

phy-msm-usb: Fix crash due to USB h/w reset on disconnect



Commit 734b1be2 ("phy-msm-usb: Put PHY in non-driving mode
during charger detection") resets USB h/w to put PHY in normal
mode on charger disconnect. However, in case of disconnect of
host PC this can create a race condition where USB hardware is
reset while USB controller is active in device mode and can
cause NOC errors. Fix this by not touching USB h/w on disconnect
if USB was active in device mode as there is not need to change
PHY mode in that case.

Change-Id: Ifbb8caa8d76e10758bce6e79c26310c52c25c1b0
Signed-off-by: default avatarManu Gautam <mgautam@codeaurora.org>
parent 525f63ef
Loading
Loading
Loading
Loading
+26 −14
Original line number Diff line number Diff line
@@ -3340,17 +3340,24 @@ static int msm_otg_dpdm_regulator_enable(struct regulator_dev *rdev)
{
	int ret = 0;
	struct msm_otg *motg = rdev_get_drvdata(rdev);
	struct usb_phy *phy = &motg->phy;

	if (!motg->rm_pulldown) {
		msm_otg_dbg_log_event(&motg->phy, "Disable Pulldown",
				      motg->rm_pulldown, 0);
		ret = msm_hsusb_ldo_enable(motg, USB_PHY_REG_3P3_ON);
		if (!ret) {
		if (ret)
			return ret;

		motg->rm_pulldown = true;
			msm_otg_dbg_log_event(&motg->phy, "RM Pulldown",
		/* Don't reset h/w if previous disconnect handling is pending */
		if (phy->otg->state == OTG_STATE_B_IDLE ||
		    phy->otg->state == OTG_STATE_UNDEFINED)
			msm_otg_set_mode_nondriving(motg, true);
		else
			msm_otg_dbg_log_event(&motg->phy, "NonDrv err",
					      motg->rm_pulldown, 0);
	}
	}

	msm_otg_set_mode_nondriving(motg, true);

	return ret;
}
@@ -3359,17 +3366,22 @@ static int msm_otg_dpdm_regulator_disable(struct regulator_dev *rdev)
{
	int ret = 0;
	struct msm_otg *motg = rdev_get_drvdata(rdev);
	struct usb_phy *phy = &motg->phy;

	if (motg->rm_pulldown) {
		/* Let sm_work handle it if USB core is active */
		if (phy->otg->state == OTG_STATE_B_IDLE ||
		    phy->otg->state == OTG_STATE_UNDEFINED)
			msm_otg_set_mode_nondriving(motg, false);

	if (motg->rm_pulldown) {
		ret = msm_hsusb_ldo_enable(motg, USB_PHY_REG_3P3_OFF);
		if (!ret) {
		if (ret)
			return ret;

		motg->rm_pulldown = false;
			msm_otg_dbg_log_event(&motg->phy, "RM Pulldown",
		msm_otg_dbg_log_event(&motg->phy, "EN Pulldown",
				      motg->rm_pulldown, 0);
	}
	}

	return ret;
}