From: Jens Wiklander <jens.wiklander@linaro.org>
To: u-boot@lists.denx.de, Marek Vasut <marex@denx.de>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>,
Andre Przywara <andre.przywara@arm.com>,
Andrew Goodbody <andrew.goodbody@linaro.org>,
Anshul Dalal <anshuld@ti.com>, Bin Meng <bmeng.cn@gmail.com>,
Casey Connolly <casey.connolly@linaro.org>,
Chunfeng Yun <chunfeng.yun@mediatek.com>,
Eddie Cai <eddie.cai.linux@gmail.com>,
GSS_MTK_Uboot_upstream <GSS_MTK_Uboot_upstream@mediatek.com>,
Ion Agorria <ion@agorria.com>,
Junhui Liu <junhui.liu@pigmoral.tech>,
Kongyang Liu <seashell11234455@gmail.com>,
Lukasz Majewski <lukma@denx.de>,
Mattijs Korpershoek <mkorpershoek@kernel.org>,
Neil Armstrong <neil.armstrong@linaro.org>,
Patrice Chotard <patrice.chotard@foss.st.com>,
Quentin Schulz <quentin.schulz@cherry.de>,
Rasmus Villemoes <ravi@prevas.dk>,
Ryder Lee <ryder.lee@mediatek.com>,
Simon Glass <sjg@chromium.org>,
Stephan Gerhold <stephan.gerhold@linaro.org>,
Svyatoslav Ryhel <clamor95@gmail.com>,
Tom Rini <trini@konsulko.com>,
Varadarajan Narayanan <quic_varada@quicinc.com>,
Weijie Gao <weijie.gao@mediatek.com>,
Zixun LI <admin@hifiphile.com>,
Jerome Forissier <jerome.forissier@arm.com>,
Jens Wiklander <jens.wiklander@linaro.org>,
Alexey Charkov <alchark@flipper.net>
Subject: [PATCH v4 58/64] usb: dwc3: import from kernel v6.14
Date: Mon, 29 Jun 2026 10:44:34 +0200 [thread overview]
Message-ID: <20260629084507.3254232-59-jens.wiklander@linaro.org> (raw)
In-Reply-To: <20260629084507.3254232-1-jens.wiklander@linaro.org>
Sync Linux kernel dwc3 changes from v6.13 to v6.14.
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.13..v6.14
Commits imported:
cc5bfc4e16fc usb: dwc3: Set SUSPENDENABLE soon after phy init
69c58deec196 usb: dwc3: gadget: Prevent irq storm when TH re-executes
d3a8c28426fc usb: dwc3: Fix timeout issue during controller enter/exit from halt state
1ed3af5a2aae usb: dwc3: Document nostream_work
66e0ea341a2a usb: dwc3: core: Defer the probe until USB power supply ready
dcfe437492e2 usb: dwc3: gadget: Reinitiate stream for all host NoStream behavior
2919c4a3d883 Merge 6.13-rc7 into usb-next
7d3934884bab usb: dwc3: omap: Fix devm_regulator_get_optional() error handling
e84a7da8c5d6 usb: dwc3: st: Switch from CONFIG_PM_SLEEP guards to pm_sleep_ptr()
a266462b937b usb: dwc3-am62: Fix an OF node leak in phy_syscon_pll_refclk()
e3a9bd247cdd usb: dwc3: Skip resume if pm_runtime_set_active() fails
533561a8aad5 usb: dwc3: omap: Use devm_regulator_get_optional()
1ff24d40b3c3 usb: dwc3: gadget: Fix incorrect UDC state after manual deconfiguration
31d500c2d0d4 usb: dwc3: dwc3-am62: Re-initialize controller if lost power in PM suspend
362a7993ed01 Merge 6.13-rc3 into usb-next
04d5b4c23f3b usb: dwc3: core: Disable USB2 retry for DWC_usb31 1.80a and prior
686d4a2c26b4 usb: dwc3: remove unused sg struct member
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Tested-by: Alexey Charkov <alchark@flipper.net>
---
drivers/usb/dwc3/core.c | 140 ++++++++++++++++++++-----------
drivers/usb/dwc3/core.h | 8 +-
drivers/usb/dwc3/dwc3-am62.c | 83 +++++++++++++------
drivers/usb/dwc3/gadget.c | 155 ++++++++++++++++++++++-------------
4 files changed, 254 insertions(+), 132 deletions(-)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index f219c82e9619..66a08b527165 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -131,11 +131,24 @@ void dwc3_enable_susphy(struct dwc3 *dwc, bool enable)
}
}
-void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode)
+void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode, bool ignore_susphy)
{
+ unsigned int hw_mode;
u32 reg;
reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+
+ /*
+ * For DRD controllers, GUSB3PIPECTL.SUSPENDENABLE and
+ * GUSB2PHYCFG.SUSPHY should be cleared during mode switching,
+ * and they can be set after core initialization.
+ */
+ hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);
+ if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD && !ignore_susphy) {
+ if (DWC3_GCTL_PRTCAP(reg) != mode)
+ dwc3_enable_susphy(dwc, false);
+ }
+
reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
reg |= DWC3_GCTL_PRTCAPDIR(mode);
dwc3_writel(dwc->regs, DWC3_GCTL, reg);
@@ -216,7 +229,7 @@ static void __dwc3_set_mode(struct work_struct *work)
spin_lock_irqsave(&dwc->lock, flags);
- dwc3_set_prtcap(dwc, desired_dr_role);
+ dwc3_set_prtcap(dwc, desired_dr_role, false);
spin_unlock_irqrestore(&dwc->lock, flags);
@@ -658,16 +671,7 @@ static int dwc3_ss_phy_setup(struct dwc3 *dwc, int index)
*/
reg &= ~DWC3_GUSB3PIPECTL_UX_EXIT_PX;
- /*
- * Above DWC_usb3.0 1.94a, it is recommended to set
- * DWC3_GUSB3PIPECTL_SUSPHY to '0' during coreConsultant configuration.
- * So default value will be '0' when the core is reset. Application
- * needs to set it to '1' after the core initialization is completed.
- *
- * Similarly for DRD controllers, GUSB3PIPECTL.SUSPENDENABLE must be
- * cleared after power-on reset, and it can be set after core
- * initialization.
- */
+ /* Ensure the GUSB3PIPECTL.SUSPENDENABLE is cleared prior to phy init. */
reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
if (dwc->u2ss_inp3_quirk)
@@ -747,15 +751,7 @@ static int dwc3_hs_phy_setup(struct dwc3 *dwc, int index)
break;
}
- /*
- * Above DWC_usb3.0 1.94a, it is recommended to set
- * DWC3_GUSB2PHYCFG_SUSPHY to '0' during coreConsultant configuration.
- * So default value will be '0' when the core is reset. Application
- * needs to set it to '1' after the core initialization is completed.
- *
- * Similarly for DRD controllers, GUSB2PHYCFG.SUSPHY must be cleared
- * after power-on reset, and it can be set after core initialization.
- */
+ /* Ensure the GUSB2PHYCFG.SUSPHY is cleared prior to phy init. */
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
if (dwc->dis_enblslpm_quirk)
@@ -830,6 +826,25 @@ static int dwc3_phy_init(struct dwc3 *dwc)
goto err_exit_usb3_phy;
}
+ /*
+ * Above DWC_usb3.0 1.94a, it is recommended to set
+ * DWC3_GUSB3PIPECTL_SUSPHY and DWC3_GUSB2PHYCFG_SUSPHY to '0' during
+ * coreConsultant configuration. So default value will be '0' when the
+ * core is reset. Application needs to set it to '1' after the core
+ * initialization is completed.
+ *
+ * Certain phy requires to be in P0 power state during initialization.
+ * Make sure GUSB3PIPECTL.SUSPENDENABLE and GUSB2PHYCFG.SUSPHY are clear
+ * prior to phy init to maintain in the P0 state.
+ *
+ * After phy initialization, some phy operations can only be executed
+ * while in lower P states. Ensure GUSB3PIPECTL.SUSPENDENABLE and
+ * GUSB2PHYCFG.SUSPHY are set soon after initialization to avoid
+ * blocking phy ops.
+ */
+ if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A))
+ dwc3_enable_susphy(dwc, true);
+
return 0;
err_exit_usb3_phy:
@@ -1479,6 +1494,26 @@ static int dwc3_core_init(struct dwc3 *dwc)
}
}
+ /*
+ * STAR 9001346572: This issue affects DWC_usb31 versions 1.80a and
+ * prior. When an active endpoint not currently cached in the host
+ * controller is chosen to be cached to the same index as an endpoint
+ * receiving NAKs, the endpoint receiving NAKs enters continuous
+ * retry mode. This prevents it from being evicted from the host
+ * controller cache, blocking the new endpoint from being cached and
+ * serviced.
+ *
+ * To resolve this, for controller versions 1.70a and 1.80a, set the
+ * GUCTL3 bit[16] (USB2.0 Internal Retry Disable) to 1. This bit
+ * disables the USB2.0 internal retry feature. The GUCTL3[16] register
+ * function is available only from version 1.70a.
+ */
+ if (DWC3_VER_IS_WITHIN(DWC31, 170A, 180A)) {
+ reg = dwc3_readl(dwc->regs, DWC3_GUCTL3);
+ reg |= DWC3_GUCTL3_USB20_RETRY_DISABLE;
+ dwc3_writel(dwc->regs, DWC3_GUCTL3, reg);
+ }
+
return 0;
err_power_off_phy:
@@ -1568,7 +1603,7 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
switch (dwc->dr_mode) {
case USB_DR_MODE_PERIPHERAL:
- dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE);
+ dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE, false);
if (dwc->usb2_phy)
otg_set_vbus(dwc->usb2_phy->otg, false);
@@ -1580,7 +1615,7 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
return dev_err_probe(dev, ret, "failed to initialize gadget\n");
break;
case USB_DR_MODE_HOST:
- dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST);
+ dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST, false);
if (dwc->usb2_phy)
otg_set_vbus(dwc->usb2_phy->otg, true);
@@ -1625,7 +1660,7 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc)
}
/* de-assert DRVVBUS for HOST and OTG mode */
- dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE);
+ dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE, true);
}
static void dwc3_get_software_properties(struct dwc3 *dwc)
@@ -1664,8 +1699,6 @@ static void dwc3_get_properties(struct dwc3 *dwc)
u8 tx_thr_num_pkt_prd = 0;
u8 tx_max_burst_prd = 0;
u8 tx_fifo_resize_max_num;
- const char *usb_psy_name;
- int ret;
/* default to highest possible threshold */
lpm_nyet_threshold = 0xf;
@@ -1700,13 +1733,6 @@ static void dwc3_get_properties(struct dwc3 *dwc)
dwc->sys_wakeup = device_may_wakeup(dwc->sysdev);
- ret = device_property_read_string(dev, "usb-psy-name", &usb_psy_name);
- if (ret >= 0) {
- dwc->usb_psy = power_supply_get_by_name(usb_psy_name);
- if (!dwc->usb_psy)
- dev_err(dev, "couldn't get usb power supply\n");
- }
-
dwc->has_lpm_erratum = device_property_read_bool(dev,
"snps,has-lpm-erratum");
device_property_read_u8(dev, "snps,lpm-nyet-threshold",
@@ -1824,8 +1850,6 @@ static void dwc3_get_properties(struct dwc3 *dwc)
dwc->tx_thr_num_pkt_prd = tx_thr_num_pkt_prd;
dwc->tx_max_burst_prd = tx_max_burst_prd;
- dwc->imod_interval = 0;
-
dwc->tx_fifo_resize_max_num = tx_fifo_resize_max_num;
}
@@ -1843,21 +1867,19 @@ static void dwc3_check_params(struct dwc3 *dwc)
unsigned int hwparam_gen =
DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3);
- /* Check for proper value of imod_interval */
- if (dwc->imod_interval && !dwc3_has_imod(dwc)) {
- dev_warn(dwc->dev, "Interrupt moderation not supported\n");
- dwc->imod_interval = 0;
- }
-
/*
+ * Enable IMOD for all supporting controllers.
+ *
+ * Particularly, DWC_usb3 v3.00a must enable this feature for
+ * the following reason:
+ *
* Workaround for STAR 9000961433 which affects only version
* 3.00a of the DWC_usb3 core. This prevents the controller
* interrupt from being masked while handling events. IMOD
* allows us to work around this issue. Enable it for the
* affected version.
*/
- if (!dwc->imod_interval &&
- DWC3_VER_IS(DWC3, 300A))
+ if (dwc3_has_imod((dwc)))
dwc->imod_interval = 1;
/* Check the maximum_speed parameter */
@@ -2109,6 +2131,23 @@ static int dwc3_get_num_ports(struct dwc3 *dwc)
return 0;
}
+static struct power_supply *dwc3_get_usb_power_supply(struct dwc3 *dwc)
+{
+ struct power_supply *usb_psy;
+ const char *usb_psy_name;
+ int ret;
+
+ ret = device_property_read_string(dwc->dev, "usb-psy-name", &usb_psy_name);
+ if (ret < 0)
+ return NULL;
+
+ usb_psy = power_supply_get_by_name(usb_psy_name);
+ if (!usb_psy)
+ return ERR_PTR(-EPROBE_DEFER);
+
+ return usb_psy;
+}
+
static int dwc3_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -2165,6 +2204,10 @@ static int dwc3_probe(struct platform_device *pdev)
dwc3_get_software_properties(dwc);
+ dwc->usb_psy = dwc3_get_usb_power_supply(dwc);
+ if (IS_ERR(dwc->usb_psy))
+ return dev_err_probe(dev, PTR_ERR(dwc->usb_psy), "couldn't get usb power supply\n");
+
dwc->reset = devm_reset_control_array_get_optional_shared(dev);
if (IS_ERR(dwc->reset)) {
ret = PTR_ERR(dwc->reset);
@@ -2425,7 +2468,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
if (ret)
return ret;
- dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE);
+ dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE, true);
dwc3_gadget_resume(dwc);
break;
case DWC3_GCTL_PRTCAP_HOST:
@@ -2433,7 +2476,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
ret = dwc3_core_init_for_resume(dwc);
if (ret)
return ret;
- dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST);
+ dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST, true);
break;
}
/* Restore GUSB2PHYCFG bits that were modified in suspend */
@@ -2462,7 +2505,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
if (ret)
return ret;
- dwc3_set_prtcap(dwc, dwc->current_dr_role);
+ dwc3_set_prtcap(dwc, dwc->current_dr_role, true);
dwc3_otg_init(dwc);
if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST) {
@@ -2589,12 +2632,15 @@ static int dwc3_resume(struct device *dev)
pinctrl_pm_select_default_state(dev);
pm_runtime_disable(dev);
- pm_runtime_set_active(dev);
+ ret = pm_runtime_set_active(dev);
+ if (ret)
+ goto out;
ret = dwc3_resume_common(dwc, PMSG_RESUME);
if (ret)
pm_runtime_set_suspended(dev);
+out:
pm_runtime_enable(dev);
return ret;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index f11570c8ffd0..aaa39e663f60 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -425,6 +425,7 @@
/* Global User Control Register 3 */
#define DWC3_GUCTL3_SPLITDISABLE BIT(14)
+#define DWC3_GUCTL3_USB20_RETRY_DISABLE BIT(16)
/* Device Configuration Register */
#define DWC3_DCFG_NUMLANES(n) (((n) & 0x3) << 30) /* DWC_usb32 only */
@@ -716,6 +717,7 @@ struct dwc3_event_buffer {
/**
* struct dwc3_ep - device side endpoint representation
* @endpoint: usb endpoint
+ * @nostream_work: work for handling bulk NoStream
* @cancelled_list: list of cancelled requests for this endpoint
* @pending_list: list of pending requests for this endpoint
* @started_list: list of started requests on this endpoint
@@ -742,6 +744,7 @@ struct dwc3_event_buffer {
*/
struct dwc3_ep {
struct usb_ep endpoint;
+ struct delayed_work nostream_work;
struct list_head cancelled_list;
struct list_head pending_list;
struct list_head started_list;
@@ -764,7 +767,7 @@ struct dwc3_ep {
#define DWC3_EP_WAIT_TRANSFER_COMPLETE BIT(7)
#define DWC3_EP_IGNORE_NEXT_NOSTREAM BIT(8)
#define DWC3_EP_FORCE_RESTART_STREAM BIT(9)
-#define DWC3_EP_FIRST_STREAM_PRIMED BIT(10)
+#define DWC3_EP_STREAM_PRIMED BIT(10)
#define DWC3_EP_PENDING_CLEAR_STALL BIT(11)
#define DWC3_EP_TXFIFO_RESIZED BIT(12)
#define DWC3_EP_DELAY_STOP BIT(13)
@@ -957,7 +960,6 @@ struct dwc3_request {
struct usb_request request;
struct list_head list;
struct dwc3_ep *dep;
- struct scatterlist *sg;
struct scatterlist *start_sg;
unsigned int num_pending_sgs;
@@ -1556,7 +1558,7 @@ struct dwc3_gadget_ep_cmd_params {
#define DWC3_HAS_OTG BIT(3)
/* prototypes */
-void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode);
+void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode, bool ignore_susphy);
void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type);
diff --git a/drivers/usb/dwc3/dwc3-am62.c b/drivers/usb/dwc3/dwc3-am62.c
index 7d43da5f2897..c158364bc03e 100644
--- a/drivers/usb/dwc3/dwc3-am62.c
+++ b/drivers/usb/dwc3/dwc3-am62.c
@@ -108,6 +108,9 @@
#define DWC3_AM62_AUTOSUSPEND_DELAY 100
+#define USBSS_DEBUG_CFG_OFF 0x0
+#define USBSS_DEBUG_CFG_DISABLED 0x7
+
struct dwc3_am62 {
struct device *dev;
void __iomem *usbss;
@@ -117,6 +120,7 @@ struct dwc3_am62 {
unsigned int offset;
unsigned int vbus_divider;
u32 wakeup_stat;
+ void __iomem *phy_regs;
};
static const int dwc3_ti_rate_table[] = { /* in KHZ */
@@ -166,6 +170,7 @@ static int phy_syscon_pll_refclk(struct dwc3_am62 *am62)
if (ret)
return ret;
+ of_node_put(args.np);
am62->offset = args.args[0];
/* Core voltage. PHY_CORE_VOLTAGE bit Recommended to be 0 always */
@@ -184,15 +189,47 @@ static int phy_syscon_pll_refclk(struct dwc3_am62 *am62)
return 0;
}
+static int dwc3_ti_init(struct dwc3_am62 *am62)
+{
+ int ret;
+ u32 reg;
+
+ /* Read the syscon property and set the rate code */
+ ret = phy_syscon_pll_refclk(am62);
+ if (ret)
+ return ret;
+
+ /* Workaround Errata i2409 */
+ if (am62->phy_regs) {
+ reg = readl(am62->phy_regs + USB_PHY_PLL_REG12);
+ reg |= USB_PHY_PLL_LDO_REF_EN | USB_PHY_PLL_LDO_REF_EN_EN;
+ writel(reg, am62->phy_regs + USB_PHY_PLL_REG12);
+ }
+
+ /* VBUS divider select */
+ reg = dwc3_ti_readl(am62, USBSS_PHY_CONFIG);
+ if (am62->vbus_divider)
+ reg |= 1 << USBSS_PHY_VBUS_SEL_SHIFT;
+
+ dwc3_ti_writel(am62, USBSS_PHY_CONFIG, reg);
+
+ clk_prepare_enable(am62->usb2_refclk);
+
+ /* Set mode valid bit to indicate role is valid */
+ reg = dwc3_ti_readl(am62, USBSS_MODE_CONTROL);
+ reg |= USBSS_MODE_VALID;
+ dwc3_ti_writel(am62, USBSS_MODE_CONTROL, reg);
+
+ return 0;
+}
+
static int dwc3_ti_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *node = pdev->dev.of_node;
struct dwc3_am62 *am62;
unsigned long rate;
- void __iomem *phy;
int i, ret;
- u32 reg;
am62 = devm_kzalloc(dev, sizeof(*am62), GFP_KERNEL);
if (!am62)
@@ -228,29 +265,17 @@ static int dwc3_ti_probe(struct platform_device *pdev)
am62->rate_code = i;
- /* Read the syscon property and set the rate code */
- ret = phy_syscon_pll_refclk(am62);
- if (ret)
- return ret;
-
- /* Workaround Errata i2409 */
- phy = devm_platform_ioremap_resource(pdev, 1);
- if (IS_ERR(phy)) {
+ am62->phy_regs = devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(am62->phy_regs)) {
dev_err(dev, "can't map PHY IOMEM resource. Won't apply i2409 fix.\n");
- phy = NULL;
- } else {
- reg = readl(phy + USB_PHY_PLL_REG12);
- reg |= USB_PHY_PLL_LDO_REF_EN | USB_PHY_PLL_LDO_REF_EN_EN;
- writel(reg, phy + USB_PHY_PLL_REG12);
+ am62->phy_regs = NULL;
}
- /* VBUS divider select */
am62->vbus_divider = device_property_read_bool(dev, "ti,vbus-divider");
- reg = dwc3_ti_readl(am62, USBSS_PHY_CONFIG);
- if (am62->vbus_divider)
- reg |= 1 << USBSS_PHY_VBUS_SEL_SHIFT;
- dwc3_ti_writel(am62, USBSS_PHY_CONFIG, reg);
+ ret = dwc3_ti_init(am62);
+ if (ret)
+ return ret;
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
@@ -258,7 +283,6 @@ static int dwc3_ti_probe(struct platform_device *pdev)
* Don't ignore its dependencies with its children
*/
pm_suspend_ignore_children(dev, false);
- clk_prepare_enable(am62->usb2_refclk);
pm_runtime_get_noresume(dev);
ret = of_platform_populate(node, NULL, NULL, dev);
@@ -267,11 +291,6 @@ static int dwc3_ti_probe(struct platform_device *pdev)
goto err_pm_disable;
}
- /* Set mode valid bit to indicate role is valid */
- reg = dwc3_ti_readl(am62, USBSS_MODE_CONTROL);
- reg |= USBSS_MODE_VALID;
- dwc3_ti_writel(am62, USBSS_MODE_CONTROL, reg);
-
/* Device has capability to wakeup system from sleep */
device_set_wakeup_capable(dev, true);
ret = device_wakeup_enable(dev);
@@ -339,6 +358,9 @@ static int dwc3_ti_suspend_common(struct device *dev)
dwc3_ti_writel(am62, USBSS_WAKEUP_STAT, USBSS_WAKEUP_STAT_CLR);
}
+ /* just to track if module resets on suspend */
+ dwc3_ti_writel(am62, USBSS_DEBUG_CFG, USBSS_DEBUG_CFG_DISABLED);
+
clk_disable_unprepare(am62->usb2_refclk);
return 0;
@@ -349,7 +371,14 @@ static int dwc3_ti_resume_common(struct device *dev)
struct dwc3_am62 *am62 = dev_get_drvdata(dev);
u32 reg;
- clk_prepare_enable(am62->usb2_refclk);
+ reg = dwc3_ti_readl(am62, USBSS_DEBUG_CFG);
+ if (reg != USBSS_DEBUG_CFG_DISABLED) {
+ /* lost power/context */
+ dwc3_ti_init(am62);
+ } else {
+ dwc3_ti_writel(am62, USBSS_DEBUG_CFG, USBSS_DEBUG_CFG_OFF);
+ clk_prepare_enable(am62->usb2_refclk);
+ }
if (device_may_wakeup(dev)) {
/* Clear wakeup config enable bits */
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 31a654c6f15b..89a4dc8ebf94 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -996,8 +996,7 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action)
/*
* All stream eps will reinitiate stream on NoStream
- * rejection until we can determine that the host can
- * prime after the first transfer.
+ * rejection.
*
* However, if the controller is capable of
* TXF_FLUSH_BYPASS, then IN direction endpoints will
@@ -2630,10 +2629,38 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)
{
u32 reg;
u32 timeout = 2000;
+ u32 saved_config = 0;
if (pm_runtime_suspended(dwc->dev))
return 0;
+ /*
+ * When operating in USB 2.0 speeds (HS/FS), ensure that
+ * GUSB2PHYCFG.ENBLSLPM and GUSB2PHYCFG.SUSPHY are cleared before starting
+ * or stopping the controller. This resolves timeout issues that occur
+ * during frequent role switches between host and device modes.
+ *
+ * Save and clear these settings, then restore them after completing the
+ * controller start or stop sequence.
+ *
+ * This solution was discovered through experimentation as it is not
+ * mentioned in the dwc3 programming guide. It has been tested on an
+ * Exynos platforms.
+ */
+ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ if (reg & DWC3_GUSB2PHYCFG_SUSPHY) {
+ saved_config |= DWC3_GUSB2PHYCFG_SUSPHY;
+ reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
+ }
+
+ if (reg & DWC3_GUSB2PHYCFG_ENBLSLPM) {
+ saved_config |= DWC3_GUSB2PHYCFG_ENBLSLPM;
+ reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
+ }
+
+ if (saved_config)
+ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
if (is_on) {
if (DWC3_VER_IS_WITHIN(DWC3, ANY, 187A)) {
@@ -2661,6 +2688,12 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)
reg &= DWC3_DSTS_DEVCTRLHLT;
} while (--timeout && !(!is_on ^ !reg));
+ if (saved_config) {
+ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ reg |= saved_config;
+ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+ }
+
if (!timeout)
return -ETIMEDOUT;
@@ -2740,6 +2773,8 @@ static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc)
__dwc3_gadget_stop(dwc);
spin_unlock_irqrestore(&dwc->lock, flags);
+ usb_gadget_set_state(dwc->gadget, USB_STATE_NOTATTACHED);
+
return ret;
}
@@ -3298,6 +3333,50 @@ static int dwc3_gadget_init_out_endpoint(struct dwc3_ep *dep)
return dwc3_alloc_trb_pool(dep);
}
+#define nostream_work_to_dep(w) (container_of(to_delayed_work(w), struct dwc3_ep, nostream_work))
+static void dwc3_nostream_work(struct work_struct *work)
+{
+ struct dwc3_ep *dep = nostream_work_to_dep(work);
+ struct dwc3 *dwc = dep->dwc;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dwc->lock, flags);
+ if (dep->flags & DWC3_EP_STREAM_PRIMED)
+ goto out;
+
+ if ((dep->flags & DWC3_EP_IGNORE_NEXT_NOSTREAM) ||
+ (!DWC3_MST_CAPABLE(&dwc->hwparams) &&
+ !(dep->flags & DWC3_EP_WAIT_TRANSFER_COMPLETE)))
+ goto out;
+ /*
+ * If the host rejects a stream due to no active stream, by the
+ * USB and xHCI spec, the endpoint will be put back to idle
+ * state. When the host is ready (buffer added/updated), it will
+ * prime the endpoint to inform the usb device controller. This
+ * triggers the device controller to issue ERDY to restart the
+ * stream. However, some hosts don't follow this and keep the
+ * endpoint in the idle state. No prime will come despite host
+ * streams are updated, and the device controller will not be
+ * triggered to generate ERDY to move the next stream data. To
+ * workaround this and maintain compatibility with various
+ * hosts, force to reinitiate the stream until the host is ready
+ * instead of waiting for the host to prime the endpoint.
+ */
+ if (DWC3_VER_IS_WITHIN(DWC32, 100A, ANY)) {
+ unsigned int cmd = DWC3_DGCMD_SET_ENDPOINT_PRIME;
+
+ dwc3_send_gadget_generic_command(dwc, cmd, dep->number);
+ } else {
+ dep->flags |= DWC3_EP_DELAY_START;
+ dwc3_stop_active_transfer(dep, true, true);
+ spin_unlock_irqrestore(&dwc->lock, flags);
+ return;
+ }
+out:
+ dep->flags &= ~DWC3_EP_IGNORE_NEXT_NOSTREAM;
+ spin_unlock_irqrestore(&dwc->lock, flags);
+}
+
static int dwc3_gadget_init_endpoint(struct dwc3 *dwc, u8 epnum)
{
struct dwc3_ep *dep;
@@ -3343,6 +3422,7 @@ static int dwc3_gadget_init_endpoint(struct dwc3 *dwc, u8 epnum)
INIT_LIST_HEAD(&dep->pending_list);
INIT_LIST_HEAD(&dep->started_list);
INIT_LIST_HEAD(&dep->cancelled_list);
+ INIT_DELAYED_WORK(&dep->nostream_work, dwc3_nostream_work);
dwc3_debugfs_create_endpoint_dir(dep);
@@ -3742,66 +3822,27 @@ static void dwc3_gadget_endpoint_command_complete(struct dwc3_ep *dep,
static void dwc3_gadget_endpoint_stream_event(struct dwc3_ep *dep,
const struct dwc3_event_depevt *event)
{
- struct dwc3 *dwc = dep->dwc;
-
if (event->status == DEPEVT_STREAMEVT_FOUND) {
- dep->flags |= DWC3_EP_FIRST_STREAM_PRIMED;
- goto out;
+ cancel_delayed_work(&dep->nostream_work);
+ dep->flags |= DWC3_EP_STREAM_PRIMED;
+ dep->flags &= ~DWC3_EP_IGNORE_NEXT_NOSTREAM;
+ return;
}
/* Note: NoStream rejection event param value is 0 and not 0xFFFF */
switch (event->parameters) {
case DEPEVT_STREAM_PRIME:
- /*
- * If the host can properly transition the endpoint state from
- * idle to prime after a NoStream rejection, there's no need to
- * force restarting the endpoint to reinitiate the stream. To
- * simplify the check, assume the host follows the USB spec if
- * it primed the endpoint more than once.
- */
- if (dep->flags & DWC3_EP_FORCE_RESTART_STREAM) {
- if (dep->flags & DWC3_EP_FIRST_STREAM_PRIMED)
- dep->flags &= ~DWC3_EP_FORCE_RESTART_STREAM;
- else
- dep->flags |= DWC3_EP_FIRST_STREAM_PRIMED;
- }
-
+ cancel_delayed_work(&dep->nostream_work);
+ dep->flags |= DWC3_EP_STREAM_PRIMED;
+ dep->flags &= ~DWC3_EP_IGNORE_NEXT_NOSTREAM;
break;
case DEPEVT_STREAM_NOSTREAM:
- if ((dep->flags & DWC3_EP_IGNORE_NEXT_NOSTREAM) ||
- !(dep->flags & DWC3_EP_FORCE_RESTART_STREAM) ||
- (!DWC3_MST_CAPABLE(&dwc->hwparams) &&
- !(dep->flags & DWC3_EP_WAIT_TRANSFER_COMPLETE)))
- break;
-
- /*
- * If the host rejects a stream due to no active stream, by the
- * USB and xHCI spec, the endpoint will be put back to idle
- * state. When the host is ready (buffer added/updated), it will
- * prime the endpoint to inform the usb device controller. This
- * triggers the device controller to issue ERDY to restart the
- * stream. However, some hosts don't follow this and keep the
- * endpoint in the idle state. No prime will come despite host
- * streams are updated, and the device controller will not be
- * triggered to generate ERDY to move the next stream data. To
- * workaround this and maintain compatibility with various
- * hosts, force to reinitiate the stream until the host is ready
- * instead of waiting for the host to prime the endpoint.
- */
- if (DWC3_VER_IS_WITHIN(DWC32, 100A, ANY)) {
- unsigned int cmd = DWC3_DGCMD_SET_ENDPOINT_PRIME;
-
- dwc3_send_gadget_generic_command(dwc, cmd, dep->number);
- } else {
- dep->flags |= DWC3_EP_DELAY_START;
- dwc3_stop_active_transfer(dep, true, true);
- return;
- }
+ dep->flags &= ~DWC3_EP_STREAM_PRIMED;
+ if (dep->flags & DWC3_EP_FORCE_RESTART_STREAM)
+ queue_delayed_work(system_wq, &dep->nostream_work,
+ msecs_to_jiffies(100));
break;
}
-
-out:
- dep->flags &= ~DWC3_EP_IGNORE_NEXT_NOSTREAM;
}
static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
@@ -4460,14 +4501,18 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3_event_buffer *evt)
dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0),
DWC3_GEVNTSIZ_SIZE(evt->length));
+ evt->flags &= ~DWC3_EVENT_PENDING;
+ /*
+ * Add an explicit write memory barrier to make sure that the update of
+ * clearing DWC3_EVENT_PENDING is observed in dwc3_check_event_buf()
+ */
+ wmb();
+
if (dwc->imod_interval) {
dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), DWC3_GEVNTCOUNT_EHB);
dwc3_writel(dwc->regs, DWC3_DEV_IMOD(0), dwc->imod_interval);
}
- /* Keep the clearing of DWC3_EVENT_PENDING at the end */
- evt->flags &= ~DWC3_EVENT_PENDING;
-
return ret;
}
--
2.43.0
next prev parent reply other threads:[~2026-06-29 8:55 UTC|newest]
Thread overview: 98+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-29 8:43 [PATCH v4 00/64] drivers: usb: dwc3: sync code with Linux v6.16 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 01/64] usb: dwc3: restore to original v3.19-rc1 kernel import Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 02/64] usb: dwc3: import from kernel v3.19 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 03/64] usb: dwc3: import from kernel v4.0 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 04/64] usb: dwc3: import from kernel v4.1 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 05/64] usb: dwc3: import from kernel v4.2 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 06/64] usb: dwc3: import from kernel v4.3 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 07/64] usb: dwc3: import from kernel v4.4 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 08/64] usb: dwc3: import from kernel v4.5 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 09/64] usb: dwc3: import from kernel v4.6 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 10/64] usb: dwc3: import from kernel v4.7 Jens Wiklander
2026-06-30 8:47 ` Marek Vasut
2026-06-30 8:51 ` Alexey Charkov
2026-06-30 9:22 ` Marek Vasut
2026-06-29 8:43 ` [PATCH v4 11/64] usb: dwc3: import from kernel v4.8 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 12/64] usb: dwc3: import from kernel v4.9 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 13/64] usb: dwc3: import from kernel v4.10 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 14/64] usb: dwc3: import from kernel v4.11 Jens Wiklander
2026-06-30 8:59 ` Marek Vasut
2026-06-30 9:05 ` Ilias Apalodimas
2026-06-30 9:22 ` Marek Vasut
2026-06-29 8:43 ` [PATCH v4 15/64] usb: dwc3: import from kernel v4.12 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 16/64] usb: dwc3: import from kernel v4.13 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 17/64] usb: dwc3: import from kernel v4.14 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 18/64] usb: dwc3: import from kernel v4.15 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 19/64] usb: dwc3: import from kernel v4.16 Jens Wiklander
2026-06-30 9:03 ` Marek Vasut
2026-06-30 9:11 ` Jens Wiklander
2026-06-30 9:23 ` Marek Vasut
2026-07-01 9:26 ` Ilias Apalodimas
2026-06-29 8:43 ` [PATCH v4 20/64] usb: dwc3: import from kernel v4.17 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 21/64] usb: dwc3: import from kernel v4.18 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 22/64] usb: dwc3: import from kernel v4.19 Jens Wiklander
2026-06-29 8:43 ` [PATCH v4 23/64] usb: dwc3: import from kernel v4.20 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 24/64] usb: dwc3: import from kernel v5.0 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 25/64] usb: dwc3: import from kernel v5.1 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 26/64] usb: dwc3: import from kernel v5.2 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 27/64] usb: dwc3: import from kernel v5.3 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 28/64] usb: dwc3: import from kernel v5.4 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 29/64] usb: dwc3: import from kernel v5.5 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 30/64] usb: dwc3: import from kernel v5.6 Jens Wiklander
2026-06-30 9:51 ` Marek Vasut
2026-06-29 8:44 ` [PATCH v4 31/64] usb: dwc3: import from kernel v5.7 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 32/64] usb: dwc3: import from kernel v5.8 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 33/64] usb: dwc3: import from kernel v5.9 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 34/64] usb: dwc3: import from kernel v5.10 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 35/64] usb: dwc3: import from kernel v5.11 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 36/64] usb: dwc3: import from kernel v5.12 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 37/64] usb: dwc3: import from kernel v5.13 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 38/64] usb: dwc3: import from kernel v5.14 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 39/64] usb: dwc3: import from kernel v5.15 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 40/64] usb: dwc3: import from kernel v5.16 Jens Wiklander
2026-06-30 10:04 ` Marek Vasut
2026-06-29 8:44 ` [PATCH v4 41/64] usb: dwc3: import from kernel v5.17 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 42/64] usb: dwc3: import from kernel v5.18 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 43/64] usb: dwc3: import from kernel v5.19 Jens Wiklander
2026-06-30 10:04 ` Marek Vasut
2026-06-29 8:44 ` [PATCH v4 44/64] usb: dwc3: import from kernel v6.0 Jens Wiklander
2026-06-30 10:06 ` Marek Vasut
2026-06-29 8:44 ` [PATCH v4 45/64] usb: dwc3: import from kernel v6.1 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 46/64] usb: dwc3: import from kernel v6.2 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 47/64] usb: dwc3: import from kernel v6.3 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 48/64] usb: dwc3: import from kernel v6.4 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 49/64] usb: dwc3: import from kernel v6.5 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 50/64] usb: dwc3: import from kernel v6.6 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 51/64] usb: dwc3: import from kernel v6.7 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 52/64] usb: dwc3: import from kernel v6.8 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 53/64] usb: dwc3: import from kernel v6.9 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 54/64] usb: dwc3: import from kernel v6.10 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 55/64] usb: dwc3: import from kernel v6.11 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 56/64] usb: dwc3: import from kernel v6.12 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 57/64] usb: dwc3: import from kernel v6.13 Jens Wiklander
2026-06-29 8:44 ` Jens Wiklander [this message]
2026-06-29 8:44 ` [PATCH v4 59/64] usb: dwc3: import from kernel v6.15 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 60/64] usb: dwc3: import from kernel v6.16 Jens Wiklander
2026-06-29 8:44 ` [PATCH v4 61/64] usb: host: re-import xhci-ext-caps.h " Jens Wiklander
2026-06-30 10:35 ` Marek Vasut
2026-06-29 8:44 ` [PATCH v4 62/64] usb: gadget: re-import epautoconf.c " Jens Wiklander
2026-06-30 10:36 ` Marek Vasut
2026-07-01 10:53 ` Alexey Charkov
2026-07-01 11:00 ` Marek Vasut
2026-06-29 8:44 ` [PATCH v4 63/64] usb: udc: re-import udc-core.c " Jens Wiklander
2026-06-30 10:37 ` Marek Vasut
2026-06-29 8:44 ` [PATCH v4 64/64] usb: fix build after resync of DWC3 with " Jens Wiklander
2026-06-30 10:38 ` Marek Vasut
2026-07-01 10:52 ` Mattijs Korpershoek
2026-07-01 17:03 ` Ilias Apalodimas
2026-07-01 17:30 ` Tom Rini
2026-07-02 9:02 ` Mattijs Korpershoek
2026-06-29 10:53 ` [PATCH v4 00/64] drivers: usb: dwc3: sync code with Linux v6.16 Michal Simek
2026-06-29 19:07 ` Ilias Apalodimas
2026-06-30 4:36 ` Michal Simek
2026-06-30 5:57 ` Jens Wiklander
2026-06-30 9:36 ` Mattijs Korpershoek
2026-06-30 13:38 ` Mattijs Korpershoek
2026-07-01 10:51 ` Mattijs Korpershoek
2026-07-01 19:56 ` Ilias Apalodimas
2026-07-03 13:32 ` Mattijs Korpershoek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260629084507.3254232-59-jens.wiklander@linaro.org \
--to=jens.wiklander@linaro.org \
--cc=GSS_MTK_Uboot_upstream@mediatek.com \
--cc=admin@hifiphile.com \
--cc=alchark@flipper.net \
--cc=andre.przywara@arm.com \
--cc=andrew.goodbody@linaro.org \
--cc=anshuld@ti.com \
--cc=bmeng.cn@gmail.com \
--cc=casey.connolly@linaro.org \
--cc=chunfeng.yun@mediatek.com \
--cc=clamor95@gmail.com \
--cc=eddie.cai.linux@gmail.com \
--cc=ilias.apalodimas@linaro.org \
--cc=ion@agorria.com \
--cc=jerome.forissier@arm.com \
--cc=junhui.liu@pigmoral.tech \
--cc=lukma@denx.de \
--cc=marex@denx.de \
--cc=mkorpershoek@kernel.org \
--cc=neil.armstrong@linaro.org \
--cc=patrice.chotard@foss.st.com \
--cc=quentin.schulz@cherry.de \
--cc=quic_varada@quicinc.com \
--cc=ravi@prevas.dk \
--cc=ryder.lee@mediatek.com \
--cc=seashell11234455@gmail.com \
--cc=sjg@chromium.org \
--cc=stephan.gerhold@linaro.org \
--cc=trini@konsulko.com \
--cc=u-boot@lists.denx.de \
--cc=weijie.gao@mediatek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.