From: Greg Kroah-Hartman Date: Tue, 22 Apr 2025 08:38:12 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v6.1.135~78 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7536f8e9514dd2905047a05d68c4dc2ff4b3e2a9;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: usb-dwc3-core-do-core-softreset-when-switch-mode.patch usb-dwc3-support-continuous-runtime-pm-with-dual-role.patch --- diff --git a/queue-5.4/series b/queue-5.4/series index f83dfc768c..8ad521b616 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -113,3 +113,5 @@ powerpc-prom_init-use-ffreestanding-to-avoid-a-reference-to-bcmp.patch tcp-dccp-don-t-use-timer_pending-in-reqsk_queue_unlink.patch misc-pci_endpoint_test-avoid-issue-of-interrupts-remaining-after-request_irq-error.patch misc-pci_endpoint_test-fix-irq_type-to-convey-the-correct-type.patch +usb-dwc3-support-continuous-runtime-pm-with-dual-role.patch +usb-dwc3-core-do-core-softreset-when-switch-mode.patch diff --git a/queue-5.4/usb-dwc3-core-do-core-softreset-when-switch-mode.patch b/queue-5.4/usb-dwc3-core-do-core-softreset-when-switch-mode.patch new file mode 100644 index 0000000000..8aef6e7d39 --- /dev/null +++ b/queue-5.4/usb-dwc3-core-do-core-softreset-when-switch-mode.patch @@ -0,0 +1,148 @@ +From f88359e1588b85cf0e8209ab7d6620085f3441d9 Mon Sep 17 00:00:00 2001 +From: Yu Chen +Date: Thu, 15 Apr 2021 15:20:30 -0700 +Subject: usb: dwc3: core: Do core softreset when switch mode + +From: Yu Chen + +commit f88359e1588b85cf0e8209ab7d6620085f3441d9 upstream. + +From: John Stultz + +According to the programming guide, to switch mode for DRD controller, +the driver needs to do the following. + +To switch from device to host: +1. Reset controller with GCTL.CoreSoftReset +2. Set GCTL.PrtCapDir(host mode) +3. Reset the host with USBCMD.HCRESET +4. Then follow up with the initializing host registers sequence + +To switch from host to device: +1. Reset controller with GCTL.CoreSoftReset +2. Set GCTL.PrtCapDir(device mode) +3. Reset the device with DCTL.CSftRst +4. Then follow up with the initializing registers sequence + +Currently we're missing step 1) to do GCTL.CoreSoftReset and step 3) of +switching from host to device. John Stult reported a lockup issue seen +with HiKey960 platform without these steps[1]. Similar issue is observed +with Ferry's testing platform[2]. + +So, apply the required steps along with some fixes to Yu Chen's and John +Stultz's version. The main fixes to their versions are the missing wait +for clocks synchronization before clearing GCTL.CoreSoftReset and only +apply DCTL.CSftRst when switching from host to device. + +[1] https://lore.kernel.org/linux-usb/20210108015115.27920-1-john.stultz@linaro.org/ +[2] https://lore.kernel.org/linux-usb/0ba7a6ba-e6a7-9cd4-0695-64fc927e01f1@gmail.com/ + +Fixes: 41ce1456e1db ("usb: dwc3: core: make dwc3_set_mode() work properly") +Cc: Andy Shevchenko +Cc: Ferry Toth +Cc: Wesley Cheng +Cc: +Tested-by: John Stultz +Tested-by: Wesley Cheng +Signed-off-by: Yu Chen +Signed-off-by: John Stultz +Signed-off-by: Thinh Nguyen +Link: https://lore.kernel.org/r/374440f8dcd4f06c02c2caf4b1efde86774e02d9.1618521663.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Hardik Gohil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/core.c | 25 +++++++++++++++++++++++++ + drivers/usb/dwc3/core.h | 5 +++++ + 2 files changed, 30 insertions(+) + +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -122,6 +122,8 @@ static void __dwc3_set_mode(struct work_ + if (dwc->dr_mode != USB_DR_MODE_OTG) + return; + ++ mutex_lock(&dwc->mutex); ++ + pm_runtime_get_sync(dwc->dev); + + if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG) +@@ -155,6 +157,25 @@ static void __dwc3_set_mode(struct work_ + break; + } + ++ /* For DRD host or device mode only */ ++ if (dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) { ++ reg = dwc3_readl(dwc->regs, DWC3_GCTL); ++ reg |= DWC3_GCTL_CORESOFTRESET; ++ dwc3_writel(dwc->regs, DWC3_GCTL, reg); ++ ++ /* ++ * Wait for internal clocks to synchronized. DWC_usb31 and ++ * DWC_usb32 may need at least 50ms (less for DWC_usb3). To ++ * keep it consistent across different IPs, let's wait up to ++ * 100ms before clearing GCTL.CORESOFTRESET. ++ */ ++ msleep(100); ++ ++ reg = dwc3_readl(dwc->regs, DWC3_GCTL); ++ reg &= ~DWC3_GCTL_CORESOFTRESET; ++ dwc3_writel(dwc->regs, DWC3_GCTL, reg); ++ } ++ + spin_lock_irqsave(&dwc->lock, flags); + + dwc3_set_prtcap(dwc, dwc->desired_dr_role); +@@ -179,6 +200,8 @@ static void __dwc3_set_mode(struct work_ + } + break; + case DWC3_GCTL_PRTCAP_DEVICE: ++ dwc3_core_soft_reset(dwc); ++ + dwc3_event_buffers_setup(dwc); + + if (dwc->usb2_phy) +@@ -201,6 +224,7 @@ static void __dwc3_set_mode(struct work_ + out: + pm_runtime_mark_last_busy(dwc->dev); + pm_runtime_put_autosuspend(dwc->dev); ++ mutex_unlock(&dwc->mutex); + } + + void dwc3_set_mode(struct dwc3 *dwc, u32 mode) +@@ -1511,6 +1535,7 @@ static int dwc3_probe(struct platform_de + dwc3_cache_hwparams(dwc); + + spin_lock_init(&dwc->lock); ++ mutex_init(&dwc->mutex); + + pm_runtime_get_noresume(dev); + pm_runtime_set_active(dev); +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -13,6 +13,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -929,6 +930,7 @@ struct dwc3_scratchpad_array { + * @scratch_addr: dma address of scratchbuf + * @ep0_in_setup: one control transfer is completed and enter setup phase + * @lock: for synchronizing ++ * @mutex: for mode switching + * @dev: pointer to our struct device + * @sysdev: pointer to the DMA-capable device + * @xhci: pointer to our xHCI child +@@ -1061,6 +1063,9 @@ struct dwc3 { + /* device lock */ + spinlock_t lock; + ++ /* mode switching lock */ ++ struct mutex mutex; ++ + struct device *dev; + struct device *sysdev; + diff --git a/queue-5.4/usb-dwc3-support-continuous-runtime-pm-with-dual-role.patch b/queue-5.4/usb-dwc3-support-continuous-runtime-pm-with-dual-role.patch new file mode 100644 index 0000000000..790927b2e0 --- /dev/null +++ b/queue-5.4/usb-dwc3-support-continuous-runtime-pm-with-dual-role.patch @@ -0,0 +1,56 @@ +From c2cd3452d5f8b66d49a73138fba5baadd5b489bd Mon Sep 17 00:00:00 2001 +From: Martin Kepplinger +Date: Thu, 19 Mar 2020 11:02:07 +0100 +Subject: usb: dwc3: support continuous runtime PM with dual role + +From: Martin Kepplinger + +commit c2cd3452d5f8b66d49a73138fba5baadd5b489bd upstream. + +The DRD module calls dwc3_set_mode() on role switches, i.e. when a device is +being plugged in. In order to support continuous runtime power management when +plugging in / unplugging a cable, we need to call pm_runtime_get_sync() in +this path. + +Signed-off-by: Martin Kepplinger +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/core.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -122,17 +122,19 @@ static void __dwc3_set_mode(struct work_ + if (dwc->dr_mode != USB_DR_MODE_OTG) + return; + ++ pm_runtime_get_sync(dwc->dev); ++ + if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG) + dwc3_otg_update(dwc, 0); + + if (!dwc->desired_dr_role) +- return; ++ goto out; + + if (dwc->desired_dr_role == dwc->current_dr_role) +- return; ++ goto out; + + if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev) +- return; ++ goto out; + + switch (dwc->current_dr_role) { + case DWC3_GCTL_PRTCAP_HOST: +@@ -196,6 +198,9 @@ static void __dwc3_set_mode(struct work_ + break; + } + ++out: ++ pm_runtime_mark_last_busy(dwc->dev); ++ pm_runtime_put_autosuspend(dwc->dev); + } + + void dwc3_set_mode(struct dwc3 *dwc, u32 mode)