dwc3-msm: Allow USB LPM with data role swap from dfp to ufp
Current code checks IN_P3 status (i.e. USB is into U3 or not) with dwc3_prepare_suspend() API using in_host_mode or vbus_active flag. With data role swap transition (e.g. dfp -> ufp case), in_host_mode flag sets to false and vbus_active flag sets to true due to quick calling of stop host and start peripheral mode from policy engine. This results into USB doesn't go into LPM with stop host mode (i.e. USB LPM is aborted due to vbus_active flag seen as true) which results into no USB enumeration in start peripheral mode. Current code doesn't perform block reset while stopping USB host mode functionality. Hence to invoke USB core and PHYs related reset and init functionality allow USB LPM by replacing vbus_active check with in_device_mode flag which provides status of USB controller's data role while going into USB LPM. Start peripheral mode brings USB out of LPM which performs POR functionality. Change-Id: I2bbb804bce5f910826ba30a3dda4317bbdb2e1f1 Signed-off-by: Mayank Rana <mrana@codeaurora.org> Signed-off-by: Ajay Agarwal <ajaya@codeaurora.org>
This commit is contained in:
parent
58a9174f20
commit
21caf80630
1 changed files with 8 additions and 6 deletions
|
@ -202,6 +202,7 @@ struct dwc3_msm {
|
|||
struct power_supply *usb_psy;
|
||||
struct work_struct vbus_draw_work;
|
||||
bool in_host_mode;
|
||||
bool in_device_mode;
|
||||
enum usb_device_speed max_rh_port_speed;
|
||||
unsigned int tx_fifo_size;
|
||||
bool vbus_active;
|
||||
|
@ -1934,7 +1935,7 @@ static int dwc3_msm_prepare_suspend(struct dwc3_msm *mdwc)
|
|||
unsigned long timeout;
|
||||
u32 reg = 0;
|
||||
|
||||
if ((mdwc->in_host_mode || mdwc->vbus_active)
|
||||
if ((mdwc->in_host_mode || mdwc->in_device_mode)
|
||||
&& dwc3_msm_is_superspeed(mdwc) && !mdwc->in_restart) {
|
||||
if (!atomic_read(&mdwc->in_p3)) {
|
||||
dev_err(mdwc->dev, "Not in P3,aborting LPM sequence\n");
|
||||
|
@ -2017,8 +2018,6 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool hibernation)
|
|||
int ret, i;
|
||||
struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
|
||||
|
||||
dbg_event(0xFF, "Ctl Sus", atomic_read(&dwc->in_lpm));
|
||||
|
||||
mutex_lock(&mdwc->suspend_resume_mutex);
|
||||
if (atomic_read(&dwc->in_lpm)) {
|
||||
dev_dbg(mdwc->dev, "%s: Already suspended\n", __func__);
|
||||
|
@ -2134,8 +2133,8 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool hibernation)
|
|||
clk_disable_unprepare(mdwc->xo_clk);
|
||||
|
||||
/* Perform controller power collapse */
|
||||
if ((!mdwc->in_host_mode && (!mdwc->vbus_active || mdwc->in_restart)) ||
|
||||
hibernation) {
|
||||
if ((!mdwc->in_host_mode && (!mdwc->in_device_mode || mdwc->in_restart))
|
||||
|| hibernation) {
|
||||
mdwc->lpm_flags |= MDWC3_POWER_COLLAPSE;
|
||||
dev_dbg(mdwc->dev, "%s: power collapse\n", __func__);
|
||||
dwc3_msm_config_gdsc(mdwc, 0);
|
||||
|
@ -2168,7 +2167,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool hibernation)
|
|||
* using HS_PHY_IRQ or SS_PHY_IRQ. Hence enable wakeup only in
|
||||
* case of host bus suspend and device bus suspend.
|
||||
*/
|
||||
if (mdwc->vbus_active || mdwc->in_host_mode) {
|
||||
if (mdwc->in_device_mode || mdwc->in_host_mode) {
|
||||
if (!mdwc->no_wakeup_src_in_hostmode)
|
||||
enable_irq_wake(mdwc->hs_phy_irq);
|
||||
enable_irq(mdwc->hs_phy_irq);
|
||||
|
@ -2181,6 +2180,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool hibernation)
|
|||
}
|
||||
|
||||
dev_info(mdwc->dev, "DWC3 in low power mode\n");
|
||||
dbg_event(0xFF, "Ctl Sus", atomic_read(&dwc->in_lpm));
|
||||
mutex_unlock(&mdwc->suspend_resume_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
@ -3725,6 +3725,7 @@ static int dwc3_otg_start_peripheral(struct dwc3_msm *mdwc, int on)
|
|||
dwc3_msm_block_reset(mdwc, false);
|
||||
|
||||
dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE);
|
||||
mdwc->in_device_mode = true;
|
||||
usb_gadget_vbus_connect(&dwc->gadget);
|
||||
#ifdef CONFIG_SMP
|
||||
mdwc->pm_qos_req_dma.type = PM_QOS_REQ_AFFINE_IRQ;
|
||||
|
@ -3743,6 +3744,7 @@ static int dwc3_otg_start_peripheral(struct dwc3_msm *mdwc, int on)
|
|||
msm_dwc3_perf_vote_update(mdwc, false);
|
||||
pm_qos_remove_request(&mdwc->pm_qos_req_dma);
|
||||
|
||||
mdwc->in_device_mode = false;
|
||||
usb_gadget_vbus_disconnect(&dwc->gadget);
|
||||
usb_phy_notify_disconnect(mdwc->hs_phy, USB_SPEED_HIGH);
|
||||
usb_phy_notify_disconnect(mdwc->ss_phy, USB_SPEED_SUPER);
|
||||
|
|
Loading…
Add table
Reference in a new issue