Patch "usb: dwc3: core: Power-off core/PHYs on system_suspend in host mode" has been added to the 4.15-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
usb: dwc3: core: Power-off core/PHYs on system_suspend in host mode
to the 4.15-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
usb-dwc3-core-power-off-core-phys-on-system_suspend-in-host-mode.patch
and it can be found in the queue-4.15 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
c4a5153e87fdf6805f63ff57556260e2554155a5Mon Sep 17 00:00:00 2001
From: Manu Gautam <[email protected]>
Date: Thu, 18 Jan 2018 16:54:30 +0530
Subject: usb: dwc3: core: Power-off core/PHYs on system_suspend in host mode
From: Manu Gautam <[email protected]>
commit c4a5153e87fdf6805f63ff57556260e2554155a5 upstream.
Commit 689bf72c6e0d ("usb: dwc3: Don't reinitialize core during host bus-suspend/resume") updated suspend/resume routines to not power_off and reinit PHYs/core for host mode.
It broke platforms that rely on DWC3 core to power_off PHYs to enter low power state on system suspend.
Perform dwc3_core_exit/init only during host mode system_suspend/ resume to addresses power regression from above mentioned patch and also allow USB session to stay connected across runtime_suspend/resume in host mode. While at it also replace existing checks for HOST only dr_mode with current_dr_role to have similar core driver behavior for both Host-only and DRD+Host configurations.
--- drivers/usb/dwc3/core.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-)
drivers/usb/dwc3/core.c +22 -14
@@ -100,6 +100,8 @@ static void dwc3_set_prtcap(struct dwc3 reg &= ~(DWC3_GCTL_PRTCAPDIR (DWC3_GCTL_PRTCAP_OTG )); reg |=DWC3_GCTL_PRTCAPDIR (mode);dwc3_writel (dwc->regs,DWC3_GCTL , reg); + + dwc->current_dr_role = mode; }static void __dwc3_set_mode (struct work_struct *work)
@@ -133,8 +135,6 @@ static void __dwc3_set_mode(struct work_dwc3_set_prtcap (dwc, dwc->desired_dr_role); - dwc->current_dr_role = dwc->desired_dr_role; -spin_unlock_irqrestore (&dwc->lock, flags);switch (dwc->desired_dr_role) {
@@ -218,7 +218,7 @@ static int dwc3_core_soft_reset(struct d* XHCI driver will reset the host block. If dwc3 was configured for * host-only mode, then we can return early. */ -if (dwc->dr_mode ==USB_DR_MODE_HOST ) +if (dwc->current_dr_role ==DWC3_GCTL_PRTCAP_HOST )return 0 ; reg =dwc3_readl (dwc->regs,DWC3_DCTL );
@@ -915,7 +915,6 @@ static int dwc3_core_init_mode(struct dwswitch (dwc->dr_mode) {case USB_DR_MODE_PERIPHERAL : - dwc->current_dr_role =DWC3_GCTL_PRTCAP_DEVICE ;dwc3_set_prtcap (dwc,DWC3_GCTL_PRTCAP_DEVICE );if (dwc->usb2_phy)
@@ -931,7 +930,6 @@ static int dwc3_core_init_mode(struct dw }break ;case USB_DR_MODE_HOST : - dwc->current_dr_role =DWC3_GCTL_PRTCAP_HOST ;dwc3_set_prtcap (dwc,DWC3_GCTL_PRTCAP_HOST );if (dwc->usb2_phy)
@@ -1279,7 +1277,7 @@ static int dwc3_remove(struct platform_d }#ifdef CONFIG_PM -static int dwc3_suspend_common (struct dwc3 *dwc) +static int dwc3_suspend_common (struct dwc3 *dwc,pm_message_t msg) {unsigned long flags;
@@ -1291,6 +1289,10 @@ static int dwc3_suspend_common(struct dwdwc3_core_exit (dwc);break ;case DWC3_GCTL_PRTCAP_HOST : +/* do nothing during host runtime_suspend */ +if (!PMSG_IS_AUTO (msg)) +dwc3_core_exit (dwc); +break ;default :/* do nothing */ break ;
@@ -1299,7 +1301,7 @@ static int dwc3_suspend_common(struct dwreturn 0 ; } -static int dwc3_resume_common (struct dwc3 *dwc) +static int dwc3_resume_common (struct dwc3 *dwc,pm_message_t msg) {unsigned long flags;int ret;
@@ -1315,6 +1317,13 @@ static int dwc3_resume_common(struct dwcspin_unlock_irqrestore (&dwc->lock, flags);break ;case DWC3_GCTL_PRTCAP_HOST : +/* nothing to do on host runtime_resume */ +if (!PMSG_IS_AUTO (msg)) { + ret =dwc3_core_init (dwc); +if (ret) +return ret; + } +break ;default :/* do nothing */ break ;
@@ -1326,12 +1335,11 @@ static int dwc3_resume_common(struct dwcstatic int dwc3_runtime_checks (struct dwc3 *dwc) {switch (dwc->current_dr_role) { -case USB_DR_MODE_PERIPHERAL : -case USB_DR_MODE_OTG : +case DWC3_GCTL_PRTCAP_DEVICE :if (dwc->connected)return -EBUSY ;break ; -case USB_DR_MODE_HOST : +case DWC3_GCTL_PRTCAP_HOST :default :/* do nothing */ break ;
@@ -1348,7 +1356,7 @@ static int dwc3_runtime_suspend(struct dif (dwc3_runtime_checks (dwc))return -EBUSY ; - ret =dwc3_suspend_common (dwc); + ret =dwc3_suspend_common (dwc,PMSG_AUTO_SUSPEND );if (ret)return ret;
@@ -1364,7 +1372,7 @@ static int dwc3_runtime_resume(struct dedevice_init_wakeup (dev, false); - ret =dwc3_resume_common (dwc); + ret =dwc3_resume_common (dwc,PMSG_AUTO_RESUME );if (ret)return ret;
@@ -1411,7 +1419,7 @@ static int dwc3_suspend(struct device *dstruct dwc3 *dwc =dev_get_drvdata (dev);int ret; - ret =dwc3_suspend_common (dwc); + ret =dwc3_suspend_common (dwc,PMSG_SUSPEND );if (ret)return ret;
@@ -1427,7 +1435,7 @@ static int dwc3_resume(struct device *depinctrl_pm_select_default_state (dev); - ret =dwc3_resume_common (dwc); + ret =dwc3_resume_common (dwc,PMSG_RESUME );if (ret)return ret;
Patches currently in stable-queue which might be from [email protected] are
queue-4.15/usb-dwc3-core-power-off-core-phys-on-system_suspend-in-host-mode.patch