[RFC PATCH v2 46/64] usb: dwc3: import from kernel v6.2
Jens Wiklander
jens.wiklander at linaro.org
Thu May 7 11:27:53 CEST 2026
Sync Linux kernel dwc3 changes from v6.1 to v6.2.
The following files are preserved accross the import:
Makefile Kconfig dwc3-meson-g12a.c dwc3-meson-gxl.c dwc3-omap.c
dwc3-uniphier.c dwc3-generic.h dwc3-generic.c dwc3-generic-sti.c
dwc3-layerscape.c ti_usb_phy.c
Skipping unused files:
debugfs.c drd.c dwc3-exynos.c dwc3-haps.c dwc3-imx8mp.c dwc3-keystone.c
dwc3-octeon.c dwc3-of-simple.c dwc3-pci.c dwc3-qcom.c dwc3-qcom-legacy.c
dwc3-rtk.c dwc3-st.c dwc3-xilinx.c host.c trace.c trace.h ulpi.c
Note that this is a raw import and doesn't build.
A fixup commit at the end of the series fixes that.
List of commits: git log --oneline v6.1..v6.2
Commits imported:
eb320f76e31d usb: dwc3: qcom: enable vbus override when in OTG dr-mode
7d80dbd708c1 usb: dwc3: fix extcon dependency
c4e3ef568539 usb: dwc3: gadget: Ignore End Transfer delay on teardown
e498a0444324 usb: dwc3: xilinx: include linux/gpio/consumer.h
63130462c919 usb: dwc3: core: defer probe on ulpi_read_id timeout
97a48da1619b usb: dwc3: qcom: Fix memory leak in dwc3_qcom_interconnect_init
62c73bfea048 usb: dwc3: Fix race between dwc3_set_mode and __dwc3_set_mode
f05f80f217bf usb: dwc3: pci: Update PCIe device ID for USB3 controller on CPU sub-system for Raptor Lake
9d1566e1f36b Merge 6.1-rc7 into usb-next
3205054dc6fe usb: dwc3: improve the config dependency of USB_DWC3_XILINX
d9c3b34d3b3a Merge 6.1-rc6 into usb-next
049142335613 usb: dwc3: gadget: Reduce TRB IOC settings
8527e9421690 Merge 6.1-rc3 into usb-next
Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
drivers/usb/dwc3/core.c | 23 ++++++++++++++++-------
drivers/usb/dwc3/gadget.c | 19 ++++++++++++++++---
2 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 1f348bc867c2..476b63618511 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -122,21 +122,25 @@ static void __dwc3_set_mode(struct work_struct *work)
unsigned long flags;
int ret;
u32 reg;
+ u32 desired_dr_role;
mutex_lock(&dwc->mutex);
+ spin_lock_irqsave(&dwc->lock, flags);
+ desired_dr_role = dwc->desired_dr_role;
+ spin_unlock_irqrestore(&dwc->lock, flags);
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)
+ if (!desired_dr_role)
goto out;
- if (dwc->desired_dr_role == dwc->current_dr_role)
+ if (desired_dr_role == dwc->current_dr_role)
goto out;
- if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev)
+ if (desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev)
goto out;
switch (dwc->current_dr_role) {
@@ -164,7 +168,7 @@ static void __dwc3_set_mode(struct work_struct *work)
*/
if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
- dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
+ 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);
@@ -184,11 +188,11 @@ static void __dwc3_set_mode(struct work_struct *work)
spin_lock_irqsave(&dwc->lock, flags);
- dwc3_set_prtcap(dwc, dwc->desired_dr_role);
+ dwc3_set_prtcap(dwc, desired_dr_role);
spin_unlock_irqrestore(&dwc->lock, flags);
- switch (dwc->desired_dr_role) {
+ switch (desired_dr_role) {
case DWC3_GCTL_PRTCAP_HOST:
ret = dwc3_host_init(dwc);
if (ret) {
@@ -1096,8 +1100,13 @@ static int dwc3_core_init(struct dwc3 *dwc)
if (!dwc->ulpi_ready) {
ret = dwc3_core_ulpi_init(dwc);
- if (ret)
+ if (ret) {
+ if (ret == -ETIMEDOUT) {
+ dwc3_core_soft_reset(dwc);
+ ret = -EPROBE_DEFER;
+ }
goto err0;
+ }
dwc->ulpi_ready = true;
}
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 6d524fa76443..89dcfac01235 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1464,8 +1464,18 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep,
*/
if (num_trbs_left == 1 || (needs_extra_trb &&
num_trbs_left <= 2 &&
- sg_dma_len(sg_next(s)) >= length))
- must_interrupt = true;
+ sg_dma_len(sg_next(s)) >= length)) {
+ struct dwc3_request *r;
+
+ /* Check if previous requests already set IOC */
+ list_for_each_entry(r, &dep->started_list, list) {
+ if (r != req && !r->request.no_interrupt)
+ break;
+
+ if (r == req)
+ must_interrupt = true;
+ }
+ }
dwc3_prepare_one_trb(dep, req, trb_length, 1, i, false,
must_interrupt);
@@ -1717,6 +1727,7 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int
else if (!ret)
dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
+ dep->flags &= ~DWC3_EP_DELAY_STOP;
return ret;
}
@@ -3722,8 +3733,10 @@ void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
if (dep->number <= 1 && dwc->ep0state != EP0_DATA_PHASE)
return;
+ if (interrupt && (dep->flags & DWC3_EP_DELAY_STOP))
+ return;
+
if (!(dep->flags & DWC3_EP_TRANSFER_STARTED) ||
- (dep->flags & DWC3_EP_DELAY_STOP) ||
(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
return;
--
2.43.0
More information about the U-Boot
mailing list