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

Commit 3685d27c authored by Manu Gautam's avatar Manu Gautam Committed by Chandana Kishori Chiluveru
Browse files

usb: dwc3-msm: Ensure hardware is reset during role change



Introduce additional WAIT_FOR_LPM input flag to ensure USB
enters low power mode after stop_peripheral or stop_host.
This makes sure that USB hardware is reset after LPM for
cases where quick transition to host mode happens while
its child was still preventing dwc3 to enter low power mode.
In the absence of h/w reset after stop_peripheral, host mode
doesn't work.

Change-Id: I67e4fcdc11a3337e3e90b4ca8f461e328a6e8ecf
Signed-off-by: default avatarManu Gautam <mgautam@codeaurora.org>
parent 08535ecb
Loading
Loading
Loading
Loading
+18 −0
Original line number Original line Diff line number Diff line
@@ -202,6 +202,7 @@ static const struct usb_irq usb_irq_info[USB_MAX_IRQ] = {
#define ID			0
#define ID			0
#define B_SESS_VLD		1
#define B_SESS_VLD		1
#define B_SUSPEND		2
#define B_SUSPEND		2
#define WAIT_FOR_LPM		3


#define PM_QOS_SAMPLE_SEC	2
#define PM_QOS_SAMPLE_SEC	2
#define PM_QOS_THRESHOLD	400
#define PM_QOS_THRESHOLD	400
@@ -2490,7 +2491,13 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool hibernation)


	dev_info(mdwc->dev, "DWC3 in low power mode\n");
	dev_info(mdwc->dev, "DWC3 in low power mode\n");
	dbg_event(0xFF, "Ctl Sus", atomic_read(&dwc->in_lpm));
	dbg_event(0xFF, "Ctl Sus", atomic_read(&dwc->in_lpm));

	/* kick_sm if it is waiting for lpm sequence to finish */
	if (test_and_clear_bit(WAIT_FOR_LPM, &mdwc->inputs))
		schedule_delayed_work(&mdwc->sm_work, 0);

	mutex_unlock(&mdwc->suspend_resume_mutex);
	mutex_unlock(&mdwc->suspend_resume_mutex);

	return 0;
	return 0;
}
}


@@ -4132,6 +4139,9 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on)
		dwc3_usb3_phy_suspend(dwc, false);
		dwc3_usb3_phy_suspend(dwc, false);
		mdwc->in_host_mode = false;
		mdwc->in_host_mode = false;


		/* wait for LPM, to ensure h/w is reset after stop_host */
		set_bit(WAIT_FOR_LPM, &mdwc->inputs);

		pm_runtime_put_sync_suspend(mdwc->dev);
		pm_runtime_put_sync_suspend(mdwc->dev);
		dbg_event(0xFF, "StopHost psync",
		dbg_event(0xFF, "StopHost psync",
			atomic_read(&mdwc->dev->power.usage_count));
			atomic_read(&mdwc->dev->power.usage_count));
@@ -4215,6 +4225,9 @@ static int dwc3_otg_start_peripheral(struct dwc3_msm *mdwc, int on)
		usb_phy_notify_disconnect(mdwc->ss_phy, USB_SPEED_SUPER);
		usb_phy_notify_disconnect(mdwc->ss_phy, USB_SPEED_SUPER);
		dwc3_override_vbus_status(mdwc, false);
		dwc3_override_vbus_status(mdwc, false);
		dwc3_usb3_phy_suspend(dwc, false);
		dwc3_usb3_phy_suspend(dwc, false);

		/* wait for LPM, to ensure h/w is reset after stop_peripheral */
		set_bit(WAIT_FOR_LPM, &mdwc->inputs);
	}
	}


	pm_runtime_put_sync(mdwc->dev);
	pm_runtime_put_sync(mdwc->dev);
@@ -4381,6 +4394,11 @@ static void dwc3_otg_sm_work(struct work_struct *w)
		pm_runtime_enable(mdwc->dev);
		pm_runtime_enable(mdwc->dev);
		/* fall-through */
		/* fall-through */
	case DRD_STATE_IDLE:
	case DRD_STATE_IDLE:
		if (test_bit(WAIT_FOR_LPM, &mdwc->inputs)) {
			dev_dbg(mdwc->dev, "still not in lpm, wait.\n");
			break;
		}

		if (!test_bit(ID, &mdwc->inputs)) {
		if (!test_bit(ID, &mdwc->inputs)) {
			dev_dbg(mdwc->dev, "!id\n");
			dev_dbg(mdwc->dev, "!id\n");
			mdwc->drd_state = DRD_STATE_HOST_IDLE;
			mdwc->drd_state = DRD_STATE_HOST_IDLE;