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

Commit 0d8df81b authored by Vijayavardhan Vennapusa's avatar Vijayavardhan Vennapusa Committed by Gerrit - the friendly Code Review server
Browse files

USB: phy: msm: Apply DP pulse for CDP during bootup from sm_work



Currently driver is calling API to apply pulse from vbus notifier, but
it might lead to race condition during bootup and result in unclocked
access. Hence avoid applying DP pulse during bootup from vbus notifier
callback. Also enable LDOs and clocks only if usb is in lpm, else apply
DP pulse without enabling LDOs and clocks again.

Change-Id: I987d93de5261147481f3856254941091dedba108
Signed-off-by: default avatarVijayavardhan Vennapusa <vvreddy@codeaurora.org>
parent 05996fd8
Loading
Loading
Loading
Loading
+41 −20
Original line number Diff line number Diff line
@@ -2862,6 +2862,10 @@ static void check_for_sdp_connection(struct work_struct *w)
	msm_otg_set_vbus_state(motg->vbus_state);
}

#define DP_PULSE_WIDTH_MSEC 200
static int
msm_otg_phy_drive_dp_pulse(struct msm_otg *motg, unsigned int pulse_width);

static void msm_otg_sm_work(struct work_struct *w)
{
	struct msm_otg *motg = container_of(w, struct msm_otg, sm_work);
@@ -2905,6 +2909,9 @@ static void msm_otg_sm_work(struct work_struct *w)
				get_pm_runtime_counter(dev), 0);
			pm_runtime_put_sync(dev);
			break;
		} else if (get_psy_type(motg) == POWER_SUPPLY_TYPE_USB_CDP) {
			pr_debug("Connected to CDP, pull DP up from sm_work\n");
			msm_otg_phy_drive_dp_pulse(motg, DP_PULSE_WIDTH_MSEC);
		}
		pm_runtime_put(dev);
		/* FALL THROUGH */
@@ -3073,9 +3080,14 @@ msm_otg_phy_drive_dp_pulse(struct msm_otg *motg, unsigned int pulse_width)
{
	int ret = 0;
	u32 val;
	bool in_lpm = false;

	msm_otg_dbg_log_event(&motg->phy, "DRIVE DP PULSE",
				motg->inputs, 0);
	if (atomic_read(&motg->in_lpm))
		in_lpm = true;

	if (in_lpm) {
		ret = msm_hsusb_ldo_enable(motg, USB_PHY_REG_ON);
		if (ret)
			return ret;
@@ -3086,6 +3098,7 @@ msm_otg_phy_drive_dp_pulse(struct msm_otg *motg, unsigned int pulse_width)
		clk_prepare_enable(motg->phy_csr_clk);
		clk_prepare_enable(motg->core_clk);
		clk_prepare_enable(motg->pclk);
	}

	msm_otg_exit_phy_retention(motg);

@@ -3131,6 +3144,7 @@ msm_otg_phy_drive_dp_pulse(struct msm_otg *motg, unsigned int pulse_width)

	/* Make sure above writes are completed before clks off */
	mb();
	if (in_lpm) {
		clk_disable_unprepare(motg->pclk);
		clk_disable_unprepare(motg->core_clk);
		clk_disable_unprepare(motg->phy_csr_clk);
@@ -3138,17 +3152,19 @@ msm_otg_phy_drive_dp_pulse(struct msm_otg *motg, unsigned int pulse_width)
		regulator_disable(hsusb_vdd);
		msm_hsusb_config_vddcx(0);
		msm_hsusb_ldo_enable(motg, USB_PHY_REG_OFF);
	} else {
		msm_otg_reset(&motg->phy);
	}

	msm_otg_dbg_log_event(&motg->phy, "DP PULSE DRIVEN",
				motg->inputs, 0);
	return 0;
}

#define DP_PULSE_WIDTH_MSEC 200

static void msm_otg_set_vbus_state(int online)
{
	struct msm_otg *motg = the_msm_otg;
	struct usb_otg *otg = motg->phy.otg;

	motg->vbus_state = online;

@@ -3161,7 +3177,12 @@ static void msm_otg_set_vbus_state(int online)
				motg->inputs, 0);
		if (test_and_set_bit(B_SESS_VLD, &motg->inputs))
			return;
		if (get_psy_type(motg) == POWER_SUPPLY_TYPE_USB_CDP) {
		/*
		 * It might race with block reset happening in sm_work, while
		 * state machine is in undefined state. Add check to avoid it.
		 */
		if ((get_psy_type(motg) == POWER_SUPPLY_TYPE_USB_CDP) &&
		    (otg->state != OTG_STATE_UNDEFINED)) {
			pr_debug("Connected to CDP, pull DP up\n");
			msm_otg_phy_drive_dp_pulse(motg, DP_PULSE_WIDTH_MSEC);
		}