Linux USB
 help / color / mirror / Atom feed
* RE: [PATCH net-next v4 3/3] r8152: add helper functions for PHY OCP registers
From: Chih Kai Hsu @ 2026-03-31  5:45 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem@davemloft.net, netdev@vger.kernel.org, nic_swsd,
	linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org,
	edumazet@google.com, bjorn@mork.no, pabeni@redhat.com
In-Reply-To: <20260331020156.3518006-2-kuba@kernel.org>

On 31/03/26 10:02 am, Jakub Kicinski wrote:
> 
> > diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index
> > 32a4e8d423115..8747c55e0a484 100644
> > --- a/drivers/net/usb/r8152.c
> > +++ b/drivers/net/usb/r8152.c
> [ ... ]
> > +static void sram_write_w0w1(struct r8152 *tp, u16 addr, u16 clear,
> > +u16 set) {
> > +     u16 data;
> > +
> > +     data = sram_read(tp, addr);
> > +     data = (data & ~clear) | set;
> > +     ocp_reg_write(tp, OCP_SRAM_DATA, data);
> 
> AI flags:
> 
>   Does writing directly to OCP_SRAM_DATA here actually write to the
> intended
>   address?
Yes, this actually writes to the intended address.

> 
>   Because hardware indirect SRAM access ports typically auto-increment their
>   internal address pointer upon access, the sram_read() call will advance the
>   pointer. By writing directly to OCP_SRAM_DATA instead of using
>   sram_write(tp, addr, data) to re-establish the address, the updated value
>   would be written to the next address (addr + 1) rather than the original addr.
> 
>   Could this corrupt the PHY configuration memory across the initialization
> paths
>   that now use sram_clr_bits() and sram_set_bits()?
> 
> Can you confirm if this is legit? Not sure whether this device / register
> auto-increments or where AI got it from.
The address pointer, OCP_SRAM_ADDR, is not auto-incremented after sram_read(tp, addr).
However, the address pointer is incremented automatically after ocp_reg_write(tp, OCP_SRAM_DATA, data).

Best Regards,
Chih-Kai

^ permalink raw reply

* Re: [PATCH] usb: phy: mxs: manually reset phy regs after a warm reset
From: Xu Yang @ 2026-03-31  2:01 UTC (permalink / raw)
  To: Frank Li
  Cc: gregkh, s.hauer, kernel, festevam, linux-usb, imx,
	linux-arm-kernel, linux-kernel
In-Reply-To: <acqJ0Q_Ux8PvGT7s@lizhi-Precision-Tower-5810>

On Mon, Mar 30, 2026 at 10:33:53AM -0400, Frank Li wrote:
> On Mon, Mar 30, 2026 at 05:31:33PM +0800, Xu Yang wrote:
> > The usb phy registers are not fully reset on warm reset under stress
> > conditions. We need to manually reset those (CTRL, PWD, DEBUG, PLL_SIC)
> 
> Avoid the words "we ..."
> 
> So need manually reset CTRL, PWD, DEBUG, PLL_SIC ...

OK.

> 
> > regs after a warm reset. This will reset DEBUG and PLL_SIC registers.
> > CTRL and PWD register are handled by "SFT" bit in stmp_reset_block().
> >
> > ERR051269: USB PHY registers not fully resetting on warm reset under
> >            stress conditions
> >
> > The following USB PHY registers must be written by SW to restore the reset
> > value after a warm reset:
> >
> > Reg: ctrl Addr: 0x29910030 Data: 0xc000_0000
> > Reg: pwd Addr: 0x29910000 Data: 0x001e_1c00
> > Reg: debug0 Addr: 0x29910050 Data: 0x7f18_0000
> > Reg: pll_sic Addr: 0x299100a0 Data: 0x00d1_2000
> >
> > Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
> > ---
> >  drivers/usb/phy/phy-mxs-usb.c | 32 +++++++++++++++++++++++++++++---
> >  1 file changed, 29 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c
> > index 7069dd3f4d0d..dd42db8a0829 100644
> > --- a/drivers/usb/phy/phy-mxs-usb.c
> > +++ b/drivers/usb/phy/phy-mxs-usb.c
> > @@ -209,6 +209,9 @@ static const struct mxs_phy_data imx6ul_phy_data = {
> >  static const struct mxs_phy_data imx7ulp_phy_data = {
> >  };
> >
> > +static const struct mxs_phy_data imx8ulp_phy_data = {
> > +};
> > +
> >  static const struct of_device_id mxs_phy_dt_ids[] = {
> >  	{ .compatible = "fsl,imx6sx-usbphy", .data = &imx6sx_phy_data, },
> >  	{ .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, },
> > @@ -217,6 +220,7 @@ static const struct of_device_id mxs_phy_dt_ids[] = {
> >  	{ .compatible = "fsl,vf610-usbphy", .data = &vf610_phy_data, },
> >  	{ .compatible = "fsl,imx6ul-usbphy", .data = &imx6ul_phy_data, },
> >  	{ .compatible = "fsl,imx7ulp-usbphy", .data = &imx7ulp_phy_data, },
> > +	{ .compatible = "fsl,imx8ulp-usbphy", .data = &imx8ulp_phy_data, },
> >  	{ /* sentinel */ }
> >  };
> >  MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids);
> > @@ -248,6 +252,11 @@ static inline bool is_imx7ulp_phy(struct mxs_phy *mxs_phy)
> >  	return mxs_phy->data == &imx7ulp_phy_data;
> >  }
> >
> > +static inline bool is_imx8ulp_phy(struct mxs_phy *mxs_phy)
> > +{
> > +	return mxs_phy->data == &imx8ulp_phy_data;
> 
> don't use this kind check.
> 
> Add field 'need_reset_reg' in mxs_phy_data
> 
> imx8ulp_phy_data = {
> 	.need_reset_reg = true;
> }
> 
> if (mxs->data->need_reset_reg)
> 	...
> 
> The same logic for
> 	if (is_imx7ulp_phy(mxs_phy) || is_imx8ulp_phy(mxs_phy))
> 		mxs_phy_pll_enable(phy->io_priv, false);
> 
> add 'need_phy_pull_enable' in mxs_phy_data. (new patch for it)
>     set it true at both imx7ulp_phy_data and imx8ulp_phy_data.

OK.

Thanks,
Xu Yang

^ permalink raw reply

* Re: [PATCH] usb: phy: mxs: manually reset phy regs after a warm reset
From: Xu Yang @ 2026-03-31  1:59 UTC (permalink / raw)
  To: Greg KH
  Cc: Frank.Li, s.hauer, kernel, festevam, linux-usb, imx,
	linux-arm-kernel, linux-kernel
In-Reply-To: <2026033057-sixties-erupt-fea7@gregkh>

On Mon, Mar 30, 2026 at 04:19:24PM +0200, Greg KH wrote:
> On Mon, Mar 30, 2026 at 05:31:33PM +0800, Xu Yang wrote:
> > The usb phy registers are not fully reset on warm reset under stress
> > conditions. We need to manually reset those (CTRL, PWD, DEBUG, PLL_SIC)
> > regs after a warm reset. This will reset DEBUG and PLL_SIC registers.
> > CTRL and PWD register are handled by "SFT" bit in stmp_reset_block().
> > 
> > ERR051269: USB PHY registers not fully resetting on warm reset under
> >            stress conditions
> > 
> > The following USB PHY registers must be written by SW to restore the reset
> > value after a warm reset:
> > 
> > Reg: ctrl Addr: 0x29910030 Data: 0xc000_0000
> > Reg: pwd Addr: 0x29910000 Data: 0x001e_1c00
> > Reg: debug0 Addr: 0x29910050 Data: 0x7f18_0000
> > Reg: pll_sic Addr: 0x299100a0 Data: 0x00d1_2000
> > 
> > Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
> > ---
> >  drivers/usb/phy/phy-mxs-usb.c | 32 +++++++++++++++++++++++++++++---
> >  1 file changed, 29 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c
> > index 7069dd3f4d0d..dd42db8a0829 100644
> > --- a/drivers/usb/phy/phy-mxs-usb.c
> > +++ b/drivers/usb/phy/phy-mxs-usb.c
> > @@ -209,6 +209,9 @@ static const struct mxs_phy_data imx6ul_phy_data = {
> >  static const struct mxs_phy_data imx7ulp_phy_data = {
> >  };
> >  
> > +static const struct mxs_phy_data imx8ulp_phy_data = {
> > +};
> > +
> >  static const struct of_device_id mxs_phy_dt_ids[] = {
> >  	{ .compatible = "fsl,imx6sx-usbphy", .data = &imx6sx_phy_data, },
> >  	{ .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, },
> > @@ -217,6 +220,7 @@ static const struct of_device_id mxs_phy_dt_ids[] = {
> >  	{ .compatible = "fsl,vf610-usbphy", .data = &vf610_phy_data, },
> >  	{ .compatible = "fsl,imx6ul-usbphy", .data = &imx6ul_phy_data, },
> >  	{ .compatible = "fsl,imx7ulp-usbphy", .data = &imx7ulp_phy_data, },
> > +	{ .compatible = "fsl,imx8ulp-usbphy", .data = &imx8ulp_phy_data, },
> 
> Why can't you use &imx7ulp_phy_data here as it's all just empty?

Thanks for your review.
Because it's imx8ulp specific errata. Let me add more info in the commit message.

Thanks,
Xu Yang

^ permalink raw reply

* Re: [PATCH net-next v4 3/3] r8152: add helper functions for PHY OCP registers
From: Jakub Kicinski @ 2026-03-31  2:01 UTC (permalink / raw)
  To: hsu.chih.kai
  Cc: Jakub Kicinski, davem, netdev, nic_swsd, linux-kernel, linux-usb,
	edumazet, bjorn, pabeni
In-Reply-To: <20260326073925.32976-456-nic_swsd@realtek.com>

> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
> index 32a4e8d423115..8747c55e0a484 100644
> --- a/drivers/net/usb/r8152.c
> +++ b/drivers/net/usb/r8152.c
[ ... ]
> +static void sram_write_w0w1(struct r8152 *tp, u16 addr, u16 clear, u16 set)
> +{
> +	u16 data;
> +
> +	data = sram_read(tp, addr);
> +	data = (data & ~clear) | set;
> +	ocp_reg_write(tp, OCP_SRAM_DATA, data);

AI flags:

  Does writing directly to OCP_SRAM_DATA here actually write to the intended
  address?

  Because hardware indirect SRAM access ports typically auto-increment their
  internal address pointer upon access, the sram_read() call will advance the
  pointer. By writing directly to OCP_SRAM_DATA instead of using
  sram_write(tp, addr, data) to re-establish the address, the updated value
  would be written to the next address (addr + 1) rather than the original addr.

  Could this corrupt the PHY configuration memory across the initialization paths
  that now use sram_clr_bits() and sram_set_bits()?

Can you confirm if this is legit? Not sure whether this device / register
auto-increments or where AI got it from.

^ permalink raw reply

* Re: [PATCH v3 1/1] usb: dwc3: Add optional VBUS regulator support to SpacemiT K1
From: Troy Mitchell @ 2026-03-31  1:57 UTC (permalink / raw)
  To: Chukun Pan, Thinh Nguyen
  Cc: Yixun Lan, Ze Huang, Greg Kroah-Hartman, linux-riscv,
	linux-kernel, linux-usb, spacemit, Troy Mitchell
In-Reply-To: <20260326100010.3588454-2-amadeus@jmu.edu.cn>

On Thu, Mar 26, 2026 at 18:00:10 CST, Chukun Pan wrote:
> Some SpacemiT K1 boards (like OrangePi R2S) provide USB VBUS
> through a controllable regulator. Add support for the optional
> vbus-supply property so the regulator can be properly managed
> in host mode instead of left always-on. Note that this doesn't
> apply to USB Hub downstream ports with different VBUS supplies.
> 
> The enabled and disabled actions of the regulator are handled
> automatically by devm_regulator_get_enable_optional().
> 
> Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
Thanks for the patch.

Reviewed-by: Troy Mitchell <troy.mitchell@linux.spacemit.com>

^ permalink raw reply

* [PATCH v5 3/3] media: uvcvideo: add quirks for Razer Kiyo Pro webcam
From: JP Hein @ 2026-03-31  0:38 UTC (permalink / raw)
  To: Laurent Pinchart, Hans de Goede, Greg Kroah-Hartman
  Cc: linux-media, linux-usb, Ricardo Ribalda, Michal Pecio, JP Hein,
	stable
In-Reply-To: <20260331003806.212565-1-jp@jphein.com>

The Razer Kiyo Pro (1532:0e05) is a USB 3.0 webcam whose firmware has
two failure modes that cascade into full xHCI host controller death,
disconnecting every USB device on the bus:

  1. LPM/autosuspend resume: the device fails to reinitialize its UVC
     endpoints on resume, producing EPIPE on SET_CUR. The stalled
     endpoint triggers an xHCI stop-endpoint timeout.

  2. Rapid control transfers: sustained rapid SET_CUR operations
     (hundreds over several seconds) overwhelm the firmware.

Add the device to the UVC driver table with:

  - UVC_QUIRK_CTRL_THROTTLE: rate-limit SET_CUR (50ms interval) and
    skip error-code queries after EPIPE to prevent crash trigger #2.

  - UVC_QUIRK_DISABLE_AUTOSUSPEND: prevent USB autosuspend transitions
    that trigger crash #1. Same approach as Insta360 Link.

  - UVC_QUIRK_NO_RESET_RESUME: avoid the fragile reset-during-resume
    path. Same approach as Logitech Rally Bar.

Cc: stable@vger.kernel.org
Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2061177
Signed-off-by: JP Hein <jp@jphein.com>
---
 drivers/media/usb/uvc/uvc_driver.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index b0ca81d92..e8b4de942 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -2920,6 +2920,23 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_minmax },
+
+	/*
+	 * Razer Kiyo Pro -- firmware crashes under rapid control transfers
+	 * and on LPM/autosuspend resume, cascading into xHCI controller
+	 * death that disconnects all USB devices on the bus.
+	 */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x1532,
+	  .idProduct		= 0x0e05,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_INFO_QUIRK(UVC_QUIRK_CTRL_THROTTLE
+					| UVC_QUIRK_DISABLE_AUTOSUSPEND
+					| UVC_QUIRK_NO_RESET_RESUME) },
+
 	/* Kurokesu C1 PRO */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
-- 
2.43.0


^ permalink raw reply related

* [PATCH v5 2/3] media: uvcvideo: add UVC_QUIRK_CTRL_THROTTLE for fragile firmware
From: JP Hein @ 2026-03-31  0:38 UTC (permalink / raw)
  To: Laurent Pinchart, Hans de Goede, Greg Kroah-Hartman
  Cc: linux-media, linux-usb, Ricardo Ribalda, Michal Pecio, JP Hein,
	stable
In-Reply-To: <20260331003806.212565-1-jp@jphein.com>

Some USB webcams have firmware that crashes when it receives rapid
consecutive UVC control transfers (SET_CUR). The Razer Kiyo Pro
(1532:0e05) is one such device -- after several hundred rapid control
changes over a few seconds, the device stops responding entirely,
triggering an xHCI stop-endpoint command timeout that causes the host
controller to be declared dead, disconnecting every USB device on the
bus.

The failure is amplified by the standard UVC error-code query: when a
SET_CUR fails with EPIPE, the driver sends a second transfer (GET_CUR
on UVC_VC_REQUEST_ERROR_CODE_CONTROL) to read the UVC error code. On a
device that is already stalling, this second transfer pushes the
firmware into a full lockup.

Introduce UVC_QUIRK_CTRL_THROTTLE (0x00080000) to address both issues:

  - Enforce a minimum 50ms interval between SET_CUR control transfers,
    preventing the rapid-fire pattern that overwhelms the firmware.
    50ms allows up to 20 control changes per second, which is sufficient
    for interactive slider adjustments while keeping the device stable.

  - Skip the UVC_VC_REQUEST_ERROR_CODE_CONTROL query after EPIPE errors
    on devices with this quirk. EPIPE is returned directly without the
    follow-up query that would amplify the failure.

The UVC control path is serialized by ctrl_mutex, so last_ctrl_set_jiffies
does not require additional locking.

Cc: stable@vger.kernel.org
Signed-off-by: JP Hein <jp@jphein.com>
---
 drivers/media/usb/uvc/uvc_video.c | 32 +++++++++++++++++++++++++++++++
 drivers/media/usb/uvc/uvcvideo.h  |  3 +++
 2 files changed, 35 insertions(+)

diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index 40c76c051..9f402f55e 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -75,8 +75,30 @@ int uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit,
 	u8 error;
 	u8 tmp;
 
+	/*
+	 * Rate-limit SET_CUR operations for devices with fragile firmware.
+	 * The Razer Kiyo Pro locks up under sustained rapid SET_CUR
+	 * transfers (hundreds without delay), crashing the xHCI controller.
+	 */
+	if (query == UVC_SET_CUR &&
+	    (dev->quirks & UVC_QUIRK_CTRL_THROTTLE)) {
+		unsigned long min_interval = msecs_to_jiffies(50);
+
+		if (dev->last_ctrl_set_jiffies &&
+		    time_before(jiffies,
+				dev->last_ctrl_set_jiffies + min_interval)) {
+			unsigned long elapsed = dev->last_ctrl_set_jiffies +
+						min_interval - jiffies;
+			msleep(jiffies_to_msecs(elapsed));
+		}
+	}
+
 	ret = __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size,
 				UVC_CTRL_CONTROL_TIMEOUT);
+
+	if (query == UVC_SET_CUR &&
+	    (dev->quirks & UVC_QUIRK_CTRL_THROTTLE))
+		dev->last_ctrl_set_jiffies = jiffies;
 	if (likely(ret == size))
 		return 0;
 
@@ -108,6 +130,16 @@ int uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit,
 		return ret < 0 ? ret : -EPIPE;
 	}
 
+	/*
+	 * Skip the error code query for devices that crash under load.
+	 * The standard error-code query (GET_CUR on
+	 * UVC_VC_REQUEST_ERROR_CODE_CONTROL) sends a second USB transfer to
+	 * a device that is already stalling, which can amplify the failure
+	 * into a full firmware lockup and xHCI controller death.
+	 */
+	if (dev->quirks & UVC_QUIRK_CTRL_THROTTLE)
+		return -EPIPE;
+
 	/* Reuse data[0] to request the error code. */
 	tmp = *(u8 *)data;
 
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 8480d65ec..cafc71457 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -81,6 +81,7 @@
 #define UVC_QUIRK_INVALID_DEVICE_SOF	0x00010000
 #define UVC_QUIRK_MJPEG_NO_EOF		0x00020000
 #define UVC_QUIRK_MSXU_META		0x00040000
+#define UVC_QUIRK_CTRL_THROTTLE		0x00080000
 
 /* Format flags */
 #define UVC_FMT_FLAG_COMPRESSED		0x00000001
@@ -579,6 +580,8 @@ struct uvc_device {
 	struct usb_interface *intf;
 	unsigned long warnings;
 	u32 quirks;
+	/* Control transfer throttling (UVC_QUIRK_CTRL_THROTTLE) */
+	unsigned long last_ctrl_set_jiffies;
 	int intfnum;
 	char name[32];
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH v5 1/3] USB: core: add NO_LPM quirk for Razer Kiyo Pro webcam
From: JP Hein @ 2026-03-31  0:38 UTC (permalink / raw)
  To: Laurent Pinchart, Hans de Goede, Greg Kroah-Hartman
  Cc: linux-media, linux-usb, Ricardo Ribalda, Michal Pecio, JP Hein,
	stable
In-Reply-To: <20260331003806.212565-1-jp@jphein.com>

The Razer Kiyo Pro (1532:0e05) is a USB 3.0 UVC webcam whose firmware
does not handle USB Link Power Management transitions reliably. When LPM
is active, the device can enter a state where it fails to respond to
control transfers, producing EPIPE (-32) errors on UVC probe control
SET_CUR requests. In the worst case, the stalled endpoint triggers an
xHCI stop-endpoint command that times out, causing the host controller
to be declared dead and every USB device on the bus to be disconnected.

This has been reported as Ubuntu Launchpad Bug #2061177. The failure
mode is:

  1. UVC probe control SET_CUR returns -32 (EPIPE)
  2. xHCI host not responding to stop endpoint command
  3. xHCI host controller not responding, assume dead
  4. All USB devices on the affected xHCI controller disconnect

Disabling LPM prevents the firmware from entering the problematic low-
power states that precede the stall. This is the same approach used for
other webcams with similar firmware issues (e.g., Logitech HD Webcam C270).

Cc: stable@vger.kernel.org
Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2061177
Signed-off-by: JP Hein <jp@jphein.com>
---
 drivers/usb/core/quirks.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 9e7e49712..7c4038a1e 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -480,6 +480,8 @@ static const struct usb_device_id usb_quirk_list[] = {
 	/* Razer - Razer Blade Keyboard */
 	{ USB_DEVICE(0x1532, 0x0116), .driver_info =
 			USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
+	/* Razer - Razer Kiyo Pro Webcam */
+	{ USB_DEVICE(0x1532, 0x0e05), .driver_info = USB_QUIRK_NO_LPM },
 
 	/* Lenovo ThinkPad OneLink+ Dock twin hub controllers (VIA Labs VL812) */
 	{ USB_DEVICE(0x17ef, 0x1018), .driver_info = USB_QUIRK_RESET_RESUME },
-- 
2.43.0


^ permalink raw reply related

* [PATCH v5 0/3] USB/UVC: Add quirks to prevent Razer Kiyo Pro xHCI cascade failure
From: JP Hein @ 2026-03-31  0:38 UTC (permalink / raw)
  To: Laurent Pinchart, Hans de Goede, Greg Kroah-Hartman
  Cc: linux-media, linux-usb, Ricardo Ribalda, Michal Pecio, JP Hein

The Razer Kiyo Pro (1532:0e05) is a USB 3.0 webcam whose firmware has a
well-documented failure mode that cascades into complete xHCI host
controller death, disconnecting every USB device on the bus -- including
keyboards and mice, requiring a hard reboot.

The device has two crash triggers:

  1. LPM/autosuspend resume: Device enters LPM or autosuspend, fails to
     reinitialize on resume, producing EPIPE (-32) on UVC SET_CUR. The
     stalled endpoint triggers an xHCI stop-endpoint timeout, and the
     kernel declares the host controller dead.

  2. Rapid control transfers: sustained rapid UVC SET_CUR operations
     (hundreds over several seconds) overwhelm the firmware. The error-code query
     (GET_CUR on UVC_VC_REQUEST_ERROR_CODE_CONTROL) amplifies the
     failure by sending a second transfer to the already-stalling device,
     pushing it into a full lockup and xHCI controller death.

This has been reported as Ubuntu Launchpad Bug #2061177, with reports
across kernel versions 6.5 through 6.8.

This series adds three patches:

Patch 1: USB core -- USB_QUIRK_NO_LPM to prevent Link Power Management
  transitions that destabilize the device firmware.

Patch 2: UVC driver -- introduce UVC_QUIRK_CTRL_THROTTLE to rate-limit
  SET_CUR control transfers (50ms minimum interval) and skip the
  error-code query after EPIPE errors on affected devices.

Patch 3: UVC driver -- add Razer Kiyo Pro device table entry with
  UVC_QUIRK_CTRL_THROTTLE, UVC_QUIRK_DISABLE_AUTOSUSPEND, and
  UVC_QUIRK_NO_RESET_RESUME to address both crash triggers.

Together, these keep the device in a stable active state, prevent rapid
control transfer crashes, and avoid the power management transitions
that trigger the firmware bug.

Testing on 6.17.0-19-generic (Ubuntu 24.04 HWE) with dynamic debug
enabled and NO patches or workarounds applied:
  - v4l2-ctl stress test (control transfers only): passes 50/50
  - Starting a video call: triggers hc_died() via LPM disable failure
    during isochronous stream setup
  - Stress test during active video call: firmware stalls at round 19,
    repeated endpoint stalls with -32 EPIPE

The 6.8 -> 6.17 xHCI error handling improvements help with control
transfer recovery, but the firmware lockup during video streaming still
cascades to hc_died(). The patches in this series prevent the firmware
from reaching the lockup state in the first place.

Changes since v4:
  - Dropped stable CC (new quirks, not regression fixes)
  - Updated cover letter with 6.17 test results

Changes since v3:
  - Regenerated patches against media-committers next branch to fix
    context mismatch (v3 was based on Ubuntu 6.8 source)

Tested on:
  - Kernel: 6.17.0-19-generic (Ubuntu 24.04 HWE) and 6.8.0-106-generic
  - Hardware: Intel Cannon Lake PCH xHCI (8086:a36d)
  - Device: Razer Kiyo Pro (1532:0e05), firmware 1.5.0.1

Stress test, crash evidence, and debug logs:
  https://github.com/jphein/kiyo-xhci-fix

JP Hein (3):
  USB: core: add NO_LPM quirk for Razer Kiyo Pro webcam
  media: uvcvideo: add UVC_QUIRK_CTRL_THROTTLE for fragile firmware
  media: uvcvideo: add quirks for Razer Kiyo Pro webcam

 drivers/media/usb/uvc/uvc_driver.c | 17 ++++++++++++++++
 drivers/media/usb/uvc/uvc_video.c  | 32 ++++++++++++++++++++++++++++++
 drivers/media/usb/uvc/uvcvideo.h   |  3 +++
 drivers/usb/core/quirks.c          |  2 ++
 4 files changed, 54 insertions(+)

^ permalink raw reply

* Re: [PATCH net v3 04/11] list: Move on_list_rcu() to list.h and add on_list() also
From: Linus Torvalds @ 2026-03-31  0:17 UTC (permalink / raw)
  To: David Howells
  Cc: Jakub Kicinski, netdev, Marc Dionne, David S. Miller,
	Eric Dumazet, Paolo Abeni, linux-afs, linux-kernel,
	Mathieu Desnoyers, John Johansen, Minas Harutyunyan, Simon Horman,
	apparmor, linux-usb, stable
In-Reply-To: <1317861.1774914607@warthog.procyon.org.uk>

On Mon, 30 Mar 2026 at 16:50, David Howells <dhowells@redhat.com> wrote:
>
> If I don't delete entries in rxrpc_destroy_all_calls(), then rxrpc_put_call()
> only needs list_empty() to guard against the call not having being queued yet.
> I could have a flag for that, but it would be superfluous.

So make *that* code use a creaful "delete with flag".

As far as I know, __list_del_clearprev() works fine for RCU walking
too, and that "prev is NULL" works as a "this is not on a list".

Admittedly I didn't think about it a lot.

So my point is more that this should not be some "generic list"
behavior, and I do *not* want people to think that they can just do
"is_on_list()" kind of crap in general.

This should be a "this user needs that particular behavior, and has
used this particular function to get it".

And yes, this pattern started out as a single performance-critical
networking user, and maybe we could rename and codify this pattern
better since we now have a couple of users (bpf and xdp) and another
apparently appearing. But I think that "rename and codify" should be a
separate thing (and done after ths particular issue is fixed).

              Linus

^ permalink raw reply

* Re: [PATCH net v3 04/11] list: Move on_list_rcu() to list.h and add on_list() also
From: Jakub Kicinski @ 2026-03-31  0:12 UTC (permalink / raw)
  To: Linus Torvalds, David Howells
  Cc: netdev, Marc Dionne, David S. Miller, Eric Dumazet, Paolo Abeni,
	linux-afs, linux-kernel, Mathieu Desnoyers, John Johansen,
	Minas Harutyunyan, Simon Horman, apparmor, linux-usb, stable
In-Reply-To: <CAHk-=wjDKfhS5TvEfrsOgBgAvFMPfAd3wT=Um2AQb4txHq5sAQ@mail.gmail.com>

On Mon, 30 Mar 2026 15:14:07 -0700 Linus Torvalds wrote:
> On Mon, 30 Mar 2026 at 03:49, David Howells <dhowells@redhat.com> wrote:
> >
> > Anyway, I'll find a different way to do this, not involving checking the prev
> > pointer.  What I don't want to do is hard code "prev == LIST_POISON2" into my
> > stuff.  Anything like that really needs to be in list.h.  
> 
> So i think the proper model is:
> 
> (a) normal and good list users should never *use* this kind of "is
> this entry on a list or not".
> 
> Dammit, you should *KNOW* that already from core logic. Not with a
> flag, not with a function to ask, but from how things work. The whole
> "am I on a list or not" should not be a list issue, it should be
> obvious.

+1 FWIW, the use of the on_list_rcu() in patch 5 looks kinda shady:

@@ -654,9 +654,9 @@ void rxrpc_put_call(struct rxrpc_call *call, enum rxrpc_call_trace why)
 	if (dead) {
 		ASSERTCMP(__rxrpc_call_state(call), ==, RXRPC_CALL_COMPLETE);
 
-		if (!list_empty(&call->link)) {
+		if (on_list_rcu(&call->link)) {
 			spin_lock(&rxnet->call_lock);
-			list_del_init(&call->link);
+			list_del_rcu(&call->link);
 			spin_unlock(&rxnet->call_lock);
 		}

I haven't dug around to see if there's some higher level lock
protecting the whole op, so I didn't mention it. But I was worried
that on_list() would lead to questionable code, and the first use
didn't deliver the reassurance I was hoping for.

> (b) if the code in question really doesn't know what the ^%&%^ it did,
> and has lost sight of what it has done to a list entry, and really
> wants some kind of "did I remove this entry already" logic, I would
> encourage such uses to either re-consider, or just use the
> "__list_del_clearprev()" function when removing entries.
> 
> Because I really don't want the core list handling to cater to code
> that doesn't know what the hell it has done.


^ permalink raw reply

* Re: [PATCH 0/3] USB/UVC: Add quirks to prevent Razer Kiyo Pro xHCI cascade failure
From: Jeffrey Hein @ 2026-03-31  0:07 UTC (permalink / raw)
  To: Michal Pecio
  Cc: Laurent Pinchart, Hans de Goede, Greg Kroah-Hartman, linux-media,
	linux-usb, stable
In-Reply-To: <20260329174022.6513d797.michal.pecio@gmail.com>

Hi Michal,

I spoke too soon. The stress test (rapid v4l2-ctl control transfers
with no video stream) passes on 6.17, but the crash still occurs
during actual use.

Starting a video call on 6.17.0-19-generic triggered the full
hc_died() cascade. No patches, no workarounds, stock kernel:

    usb 2-3.4: disable of device-initiated U1 failed.
    usb 2-3.4: Failed to set U2 timeout to 0x0,error code -110
    uvcvideo 2-3.4:1.1: usb_set_interface Failed to disable LPM
    usb 2-3.4: Failed to query (SET_CUR) UVC control 11 on unit 3: -71
    [errors escalate from -71 EPROTO to -110 ETIMEDOUT]
    usb 2-3.4: 3:1: cannot set freq 48000 to ep 0x82
    xhci_hcd 0000:00:14.0: xHCI host not responding to stop endpoint command
    xhci_hcd 0000:00:14.0: xHCI host controller not responding, assume dead
    xhci_hcd 0000:00:14.0: HC died; cleaning up

I also ran the stress test during an active video call with dynamic
debug enabled. The firmware locked up at round 19 of 50 with repeated
endpoint stalls:

    xhci_hcd 0000:00:14.0: Stalled endpoint for slot 17 ep 2
    xhci_hcd 0000:00:14.0: Giveback URB ..., status = -32
    [repeated every 2 seconds]

In this case the xHCI controller survived (no hc_died), but the camera
was frozen and needed a physical replug.

So the pattern is: the firmware cannot handle concurrent control
transfers while servicing isochronous streams. The stress test alone
passes because there is no isochronous load. Add video streaming and
the firmware falls over. The 6.8 -> 6.17 xHCI improvements help -- the
controller sometimes recovers instead of always dying -- but the
firmware lockup still occurs.

Full debug logs are at:

    https://github.com/jphein/kiyo-xhci-fix

I have dynamic debug enabled for xhci_hcd and usbcore going forward.

JP


On Sun, Mar 29, 2026 at 8:40 AM Michal Pecio <michal.pecio@gmail.com> wrote:
>
> On Sun, 29 Mar 2026 08:03:42 -0700, Jeffrey Hein wrote:
> > I have now tested on 6.17.0-19-generic (Ubuntu 25.04) with dynamic
> > debug enabled for xhci_hcd and usbcore, and without any of my proposed
> > patches or workarounds applied. No udev quirks, no LPM disable, no
> > control throttle -- completely stock kernel.
> >
> > Results: the stress test passes 50/50 rounds with 0ms delay. On
> > 6.8.0-106-generic the same test crashed consistently around round 25.
>
> Thanks for the update, that's good to hear.
> Hopefully it will still work without dynamic debug too.
>
> If you would want to fix the old 6.8 kernel you will need to talk with
> Ubuntu about it, because that version is no longer supported upstream.
>
> Regards,
> Michal



-- 
Jeffrey Pine Hein
Just plain helpful.
jphein.com ☀️ techempower.org
(530) 798-4099

^ permalink raw reply

* [PATCH v3] usb: cdns3: gadget: fix NULL pointer dereference in ep_queue
From: Yongchao Wu @ 2026-03-31  0:04 UTC (permalink / raw)
  To: peter.chen
  Cc: pawell, rogerq, gregkh, linux-usb, linux-kernel, stable,
	Yongchao Wu

When the gadget endpoint is disabled or not yet configured, the ep->desc
pointer can be NULL. This leads to a NULL pointer dereference when
__cdns3_gadget_ep_queue() is called, causing a kernel crash.

Add a check to return -ESHUTDOWN if ep->desc is NULL, which is the
standard return code for unconfigured endpoints.

This prevents potential crashes when ep_queue is called on endpoints
that are not ready.

Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
Cc: stable@kernel.org

Signed-off-by: Yongchao Wu <yongchao.wu@autochips.com>
Acked-by: Peter Chen <peter.chen@kernel.org>

---
Changes in v3:
  - add Fixes tag
  - add Cc to stable tree
Changes in v2:
  - Fix author name format (use "Yongchao Wu" instead of "yongchao.wu")
---
 drivers/usb/cdns3/cdns3-gadget.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c
index d59a60a16..96d2a4c38 100644
--- a/drivers/usb/cdns3/cdns3-gadget.c
+++ b/drivers/usb/cdns3/cdns3-gadget.c
@@ -2589,6 +2589,9 @@ static int __cdns3_gadget_ep_queue(struct usb_ep *ep,
 	struct cdns3_request *priv_req;
 	int ret = 0;
 
+	if (!ep->desc)
+		return -ESHUTDOWN;
+
 	request->actual = 0;
 	request->status = -EINPROGRESS;
 	priv_req = to_cdns3_request(request);
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH net v3 04/11] list: Move on_list_rcu() to list.h and add on_list() also
From: David Howells @ 2026-03-30 23:50 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: dhowells, Jakub Kicinski, netdev, Marc Dionne, David S. Miller,
	Eric Dumazet, Paolo Abeni, linux-afs, linux-kernel,
	Mathieu Desnoyers, John Johansen, Minas Harutyunyan, Simon Horman,
	apparmor, linux-usb, stable
In-Reply-To: <CAHk-=wjDKfhS5TvEfrsOgBgAvFMPfAd3wT=Um2AQb4txHq5sAQ@mail.gmail.com>

Linus Torvalds <torvalds@linux-foundation.org> wrote:

> Dammit, you should *KNOW* that already from core logic. Not with a
> flag, not with a function to ask, but from how things work. The whole
> "am I on a list or not" should not be a list issue, it should be
> obvious.

The circumstance in question is this: There's a list of outstanding calls
attached to the rxrpc network namespace.  Calls may hang around on it beyond
the life of the socket that created them for a little bit to deal with network
protocol cleanup, timer cleanup, work func cleanup.  Under normal operation,
calls are removed as the last ref is put.

However, should the namespace be deleted, rxrpc_destroy_all_calls() trawls the
list to report any calls that haven't been cleaned up and the calls are
deleted from the list as it reports them so that the spinlock doesn't have to
be kept held.  It used to do other work here too, IIRC, but that's no longer
the case, so perhaps this loop is not needed now, and a warning will suffice
if the list is not empty (or I could just report, say, the first 10 calls and
not worry about calling cond_resched()).  The wait at the bottom of the
function should be sufficient to hold up namespace deallocation.

If I don't delete entries in rxrpc_destroy_all_calls(), then rxrpc_put_call()
only needs list_empty() to guard against the call not having being queued yet.
I could have a flag for that, but it would be superfluous.

Note that the reason for the RCU walking is because /proc/net/rxrpc/calls
walks over the same list, so I still need the next patch which switches to
list_del_rcu().

David


^ permalink raw reply

* [PATCH] usb: xhci: Make usb_host_endpoint.hcpriv survive endpoint_disable()
From: Michal Pecio @ 2026-03-30 23:06 UTC (permalink / raw)
  To: Mathias Nyman, Greg Kroah-Hartman; +Cc: Alan Stern, linux-usb, linux-kernel

xHCI hardware maintains its endpoint state between add_endpoint()
and drop_endpoint() calls followed by successful check_bandwidth().
So does the driver.

Core may call endpoint_disable() during xHCI endpoint life, so don't
clear host_ep->hcpriv then, because this breaks endpoint_reset().

If a driver calls usb_set_interface(), submits URBs which make host
sequence state non-zero and calls usb_clear_halt(), the device clears
its sequence state but xhci_endpoint_reset() bails out. The next URB
malfunctions: USB2 loses one packet, USB3 gets Transaction Error or
may not complete at all on some (buggy?) HCs from ASMedia and AMD.
This is triggered by uvcvideo on bulk video devices.

The code was copied from ehci_endpoint_disable() but it isn't needed
here - hcpriv should only be NULL on emulated root hub endpoints.
It might prevent resetting and inadvertently enabling a disabled and
dropped endpoint, but core shouldn't try to reset dropped endpoints.

Document xhci requirements regarding hcpriv. They are currently met.

Fixes: 18b74067ac78 ("xhci: Fix use-after-free regression in xhci clear hub TT implementation")
Cc: stable@vger.kernel.org
Signed-off-by: Michal Pecio <michal.pecio@gmail.com>
---
 drivers/usb/host/xhci.c | 1 -
 include/linux/usb.h     | 3 ++-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 2f7e6544e5ae..849a568d0e63 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -3353,7 +3353,6 @@ static void xhci_endpoint_disable(struct usb_hcd *hcd,
 		xhci_dbg(xhci, "endpoint disable with ep_state 0x%x\n",
 			 ep->ep_state);
 done:
-	host_ep->hcpriv = NULL;
 	spin_unlock_irqrestore(&xhci->lock, flags);
 }
 
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 04277af4bb9d..27e95eade121 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -54,7 +54,8 @@ struct ep_device;
  * @eusb2_isoc_ep_comp: eUSB2 isoc companion descriptor for this endpoint
  * @urb_list: urbs queued to this endpoint; maintained by usbcore
  * @hcpriv: for use by HCD; typically holds hardware dma queue head (QH)
- *	with one or more transfer descriptors (TDs) per urb
+ *	with one or more transfer descriptors (TDs) per urb; must be preserved
+ *	by core while BW is allocated for the endpoint
  * @ep_dev: ep_device for sysfs info
  * @extra: descriptors following this endpoint in the configuration
  * @extralen: how many bytes of "extra" are valid
-- 
2.48.1

^ permalink raw reply related

* Re: [PATCH net v3 04/11] list: Move on_list_rcu() to list.h and add on_list() also
From: Linus Torvalds @ 2026-03-30 22:14 UTC (permalink / raw)
  To: David Howells
  Cc: Jakub Kicinski, netdev, Marc Dionne, David S. Miller,
	Eric Dumazet, Paolo Abeni, linux-afs, linux-kernel,
	Mathieu Desnoyers, John Johansen, Minas Harutyunyan, Simon Horman,
	apparmor, linux-usb, stable
In-Reply-To: <1179840.1774867765@warthog.procyon.org.uk>

On Mon, 30 Mar 2026 at 03:49, David Howells <dhowells@redhat.com> wrote:
>
> Anyway, I'll find a different way to do this, not involving checking the prev
> pointer.  What I don't want to do is hard code "prev == LIST_POISON2" into my
> stuff.  Anything like that really needs to be in list.h.

So i think the proper model is:

(a) normal and good list users should never *use* this kind of "is
this entry on a list or not".

Dammit, you should *KNOW* that already from core logic. Not with a
flag, not with a function to ask, but from how things work. The whole
"am I on a list or not" should not be a list issue, it should be
obvious.

(b) if the code in question really doesn't know what the ^%&%^ it did,
and has lost sight of what it has done to a list entry, and really
wants some kind of "did I remove this entry already" logic, I would
encourage such uses to either re-consider, or just use the
"__list_del_clearprev()" function when removing entries.

Because I really don't want the core list handling to cater to code
that doesn't know what the hell it has done.

                Linus

^ permalink raw reply

* [PATCH] thunderbolt: tunnel: simplify allocation
From: Rosen Penev @ 2026-03-30 21:10 UTC (permalink / raw)
  To: linux-usb
  Cc: Andreas Noever, Mika Westerberg, Yehezkel Bernat, Kees Cook,
	Gustavo A. R. Silva, open list,
	open list:KERNEL HARDENING (not covered by other areas):Keyword:b__counted_by(_le|_be)?b

Use a flexible array member and kzalloc_flex to combine allocations.

Add __counted_by for extra runtime analysis. Move counting variable
assignment after allocation as required by __counted_by.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
 drivers/thunderbolt/tunnel.c | 10 ++--------
 drivers/thunderbolt/tunnel.h |  3 ++-
 2 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c
index 89676acf1290..f38f7753b6e4 100644
--- a/drivers/thunderbolt/tunnel.c
+++ b/drivers/thunderbolt/tunnel.c
@@ -180,19 +180,14 @@ static struct tb_tunnel *tb_tunnel_alloc(struct tb *tb, size_t npaths,
 {
 	struct tb_tunnel *tunnel;
 
-	tunnel = kzalloc_obj(*tunnel);
+	tunnel = kzalloc_flex(*tunnel, paths, npaths);
 	if (!tunnel)
 		return NULL;
 
-	tunnel->paths = kzalloc_objs(tunnel->paths[0], npaths);
-	if (!tunnel->paths) {
-		kfree(tunnel);
-		return NULL;
-	}
+	tunnel->npaths = npaths;
 
 	INIT_LIST_HEAD(&tunnel->list);
 	tunnel->tb = tb;
-	tunnel->npaths = npaths;
 	tunnel->type = type;
 	kref_init(&tunnel->kref);
 
@@ -219,7 +214,6 @@ static void tb_tunnel_destroy(struct kref *kref)
 			tb_path_free(tunnel->paths[i]);
 	}
 
-	kfree(tunnel->paths);
 	kfree(tunnel);
 }
 
diff --git a/drivers/thunderbolt/tunnel.h b/drivers/thunderbolt/tunnel.h
index 2c44fc8a10bc..55eb83900a2f 100644
--- a/drivers/thunderbolt/tunnel.h
+++ b/drivers/thunderbolt/tunnel.h
@@ -75,7 +75,6 @@ struct tb_tunnel {
 	struct tb *tb;
 	struct tb_port *src_port;
 	struct tb_port *dst_port;
-	struct tb_path **paths;
 	size_t npaths;
 	int (*pre_activate)(struct tb_tunnel *tunnel);
 	int (*activate)(struct tb_tunnel *tunnel, bool activate);
@@ -107,6 +106,8 @@ struct tb_tunnel {
 	struct delayed_work dprx_work;
 	void (*callback)(struct tb_tunnel *tunnel, void *data);
 	void *callback_data;
+
+	struct tb_path *paths[] __counted_by(npaths);
 };
 
 struct tb_tunnel *tb_tunnel_discover_pci(struct tb *tb, struct tb_port *down,
-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 4/4] usb: dwc3: xilinx: Add support to program MMI USB TX deemphasis
From: Radhey Shyam Pandey @ 2026-03-30 19:03 UTC (permalink / raw)
  To: gregkh, robh, krzk+dt, conor+dt, michal.simek, Thinh.Nguyen,
	p.zabel
  Cc: linux-usb, devicetree, linux-arm-kernel, linux-kernel, git,
	Radhey Shyam Pandey
In-Reply-To: <20260330190304.1841593-1-radhey.shyam.pandey@amd.com>

Introduces support for programming the 18-bit TX Deemphasis value that
drives the pipe_TxDeemph signal, as defined in the PIPE4 specification.

The configured value is recommended by Synopsys and is intended for
standard (non-compliance) operation. These Gen2 equalization settings
have been validated through both internal and external compliance
testing. By applying this setting, the stability of USB 3.2 enumeration
is improved and now SuperSpeedPlus devices are consistently recognized as
USB 3.2 Gen 2 by the MMI USB Host controller.

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
---
Changes for v2:
- Don't use compatible check for deemphasis programming.
- Rename property "snps,lcsr_tx_deemph" to "snps,lcsr-tx-deemph"
  (hyphens per kernel convention).
- Fix double space in LCSR_TX_DEEMPH register comment.
- Add blank line between register offset define and "Bit fields" section.
---
 drivers/usb/dwc3/core.c        | 17 +++++++++++++++++
 drivers/usb/dwc3/core.h        |  8 ++++++++
 drivers/usb/dwc3/dwc3-xilinx.c | 15 ++++++++++++---
 3 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 161a4d58b2ce..e678a53a90b3 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -646,6 +646,15 @@ static void dwc3_config_soc_bus(struct dwc3 *dwc)
 		reg |= DWC3_GSBUSCFG0_REQINFO(dwc->gsbuscfg0_reqinfo);
 		dwc3_writel(dwc, DWC3_GSBUSCFG0, reg);
 	}
+
+	if (dwc->csr_tx_deemph_field_1 != DWC3_LCSR_TX_DEEMPH_UNSPECIFIED) {
+		u32 reg;
+
+		reg = dwc3_readl(dwc, DWC3_LCSR_TX_DEEMPH);
+		reg &= ~DWC3_LCSR_TX_DEEMPH_MASK(~0);
+		reg |= DWC3_LCSR_TX_DEEMPH_MASK(dwc->csr_tx_deemph_field_1);
+		dwc3_writel(dwc, DWC3_LCSR_TX_DEEMPH, reg);
+	}
 }
 
 static int dwc3_core_ulpi_init(struct dwc3 *dwc)
@@ -1671,11 +1680,13 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc)
 static void dwc3_get_software_properties(struct dwc3 *dwc,
 					 const struct dwc3_properties *properties)
 {
+	u32 csr_tx_deemph_field_1;
 	struct device *tmpdev;
 	u16 gsbuscfg0_reqinfo;
 	int ret;
 
 	dwc->gsbuscfg0_reqinfo = DWC3_GSBUSCFG0_REQINFO_UNSPECIFIED;
+	dwc->csr_tx_deemph_field_1 = DWC3_LCSR_TX_DEEMPH_UNSPECIFIED;
 
 	if (properties->gsbuscfg0_reqinfo !=
 	    DWC3_GSBUSCFG0_REQINFO_UNSPECIFIED) {
@@ -1693,6 +1704,12 @@ static void dwc3_get_software_properties(struct dwc3 *dwc,
 					       &gsbuscfg0_reqinfo);
 		if (!ret)
 			dwc->gsbuscfg0_reqinfo = gsbuscfg0_reqinfo;
+
+		ret = device_property_read_u32(tmpdev,
+					       "snps,lcsr-tx-deemph",
+					       &csr_tx_deemph_field_1);
+		if (!ret)
+			dwc->csr_tx_deemph_field_1 = csr_tx_deemph_field_1;
 	}
 }
 
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index a35b3db1f9f3..99874ad09730 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -181,6 +181,8 @@
 
 #define DWC3_LLUCTL(n)		(0xd024 + ((n) * 0x80))
 
+#define DWC3_LCSR_TX_DEEMPH	0xd060
+
 /* Bit fields */
 
 /* Global SoC Bus Configuration INCRx Register 0 */
@@ -198,6 +200,10 @@
 #define DWC3_GSBUSCFG0_REQINFO(n)	(((n) & 0xffff) << 16)
 #define DWC3_GSBUSCFG0_REQINFO_UNSPECIFIED	0xffffffff
 
+/* LCSR_TX_DEEMPH Register: setting TX deemphasis used in normal operation in gen2 */
+#define DWC3_LCSR_TX_DEEMPH_MASK(n)		((n) & 0x3ffff)
+#define DWC3_LCSR_TX_DEEMPH_UNSPECIFIED		0xffffffff
+
 /* Global Debug LSP MUX Select */
 #define DWC3_GDBGLSPMUX_ENDBC		BIT(15)	/* Host only */
 #define DWC3_GDBGLSPMUX_HOSTSELECT(n)	((n) & 0x3fff)
@@ -1180,6 +1186,7 @@ struct dwc3_glue_ops {
  * @wakeup_pending_funcs: Indicates whether any interface has requested for
  *			 function wakeup in bitmap format where bit position
  *			 represents interface_id.
+ * @csr_tx_deemph_field_1: stores TX deemphasis used in Gen2 operation.
  */
 struct dwc3 {
 	struct work_struct	drd_work;
@@ -1417,6 +1424,7 @@ struct dwc3 {
 	struct dentry		*debug_root;
 	u32			gsbuscfg0_reqinfo;
 	u32			wakeup_pending_funcs;
+	u32			csr_tx_deemph_field_1;
 };
 
 #define INCRX_BURST_MODE 0
diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c
index f2dee28bdc65..44008856ee73 100644
--- a/drivers/usb/dwc3/dwc3-xilinx.c
+++ b/drivers/usb/dwc3/dwc3-xilinx.c
@@ -41,11 +41,13 @@
 #define PIPE_CLK_SELECT				0
 #define XLNX_USB_FPD_POWER_PRSNT		0x80
 #define FPD_POWER_PRSNT_OPTION			BIT(0)
+#define XLNX_MMI_USB_TX_DEEMPH_DEF		0x8c45
 
 struct dwc3_xlnx;
 
 struct dwc3_xlnx_config {
 	int				(*pltfm_init)(struct dwc3_xlnx *data);
+	u32				tx_deemph;
 	bool				map_resource;
 };
 
@@ -284,6 +286,7 @@ static const struct dwc3_xlnx_config versal_config = {
 
 static const struct dwc3_xlnx_config versal2_config = {
 	.pltfm_init = dwc3_xlnx_init_versal2,
+	.tx_deemph = XLNX_MMI_USB_TX_DEEMPH_DEF,
 };
 
 static const struct of_device_id dwc3_xlnx_of_match[] = {
@@ -303,10 +306,12 @@ static const struct of_device_id dwc3_xlnx_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, dwc3_xlnx_of_match);
 
-static int dwc3_set_swnode(struct device *dev)
+static int dwc3_set_swnode(struct dwc3_xlnx *priv_data)
 {
+	struct device *dev = priv_data->dev;
+	const struct dwc3_xlnx_config *config = priv_data->dwc3_config;
 	struct device_node *np = dev->of_node, *dwc3_np;
-	struct property_entry props[2];
+	struct property_entry props[3];
 	int prop_idx = 0, ret = 0;
 
 	dwc3_np = of_get_compatible_child(np, "snps,dwc3");
@@ -320,6 +325,10 @@ static int dwc3_set_swnode(struct device *dev)
 	if (of_dma_is_coherent(dwc3_np))
 		props[prop_idx++] = PROPERTY_ENTRY_U16("snps,gsbuscfg0-reqinfo",
 						       0xffff);
+	if (config->tx_deemph)
+		props[prop_idx++] = PROPERTY_ENTRY_U32("snps,lcsr-tx-deemph",
+						       config->tx_deemph);
+
 	of_node_put(dwc3_np);
 
 	if (prop_idx)
@@ -368,7 +377,7 @@ static int dwc3_xlnx_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_clk_put;
 
-	ret = dwc3_set_swnode(dev);
+	ret = dwc3_set_swnode(priv_data);
 	if (ret)
 		goto err_clk_put;
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 3/4] usb: dwc3: xilinx: Add Versal2 MMI USB 3.2 controller support
From: Radhey Shyam Pandey @ 2026-03-30 19:03 UTC (permalink / raw)
  To: gregkh, robh, krzk+dt, conor+dt, michal.simek, Thinh.Nguyen,
	p.zabel
  Cc: linux-usb, devicetree, linux-arm-kernel, linux-kernel, git,
	Radhey Shyam Pandey
In-Reply-To: <20260330190304.1841593-1-radhey.shyam.pandey@amd.com>

Multi-media integrated (MMI) USB3.2 DRD IP is usb3.1 gen2 controller
which support following speed SSP (10-Gbps), SuperSpeed(5-Gbps),
high-speed(480-Mbps), full-speed(12-Mbps), and low-speed(1.5-Mbps)
operation modes.

USB2 and USB3 PHY support Physical connectivity via the Type-C
connectivity. The MMI USB controller does not have a dedicated wrapper
register space, so ioremap is skipped via the map_resource config flag.

The driver handles clock and reset initialization. In this initial
version typec reversibility is not implemented and it is assumed that
USB3 PHY TCA mux programming is done by MMI configuration data object
(CDOs) and TI PD controller is configured using external tiva programmer
on VEK385 evaluation board.

Tested host mode with mass storage device.

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
---
- Introduce xlnx,usb-syscon phandle to access UDH address space
  which is wrapper subsystem IP for USB, DP and HDCP.
- Split config struct refactoring into separate patch (2/4).
- Remove unused regmap/syscon fields and parsing code; defer to
  patch that first consumes them.
- Fix error message capitalization to lowercase ("reset", "deassert").
---
 drivers/usb/dwc3/dwc3-xilinx.c | 50 ++++++++++++++++++++++++++++++----
 1 file changed, 44 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c
index bb59b56726e7..f2dee28bdc65 100644
--- a/drivers/usb/dwc3/dwc3-xilinx.c
+++ b/drivers/usb/dwc3/dwc3-xilinx.c
@@ -46,6 +46,7 @@ struct dwc3_xlnx;
 
 struct dwc3_xlnx_config {
 	int				(*pltfm_init)(struct dwc3_xlnx *data);
+	bool				map_resource;
 };
 
 struct dwc3_xlnx {
@@ -93,6 +94,29 @@ static void dwc3_xlnx_set_coherency(struct dwc3_xlnx *priv_data, u32 coherency_o
 	}
 }
 
+static int dwc3_xlnx_init_versal2(struct dwc3_xlnx *priv_data)
+{
+	struct device		*dev = priv_data->dev;
+	struct reset_control	*crst;
+	int			ret;
+
+	crst = devm_reset_control_get_optional_exclusive(dev, NULL);
+	if (IS_ERR(crst))
+		return dev_err_probe(dev, PTR_ERR(crst),
+				     "failed to get reset signal\n");
+
+	/* assert and deassert reset */
+	ret = reset_control_assert(crst);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "failed to assert reset\n");
+
+	ret = reset_control_deassert(crst);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "failed to deassert reset\n");
+
+	return 0;
+}
+
 static int dwc3_xlnx_init_versal(struct dwc3_xlnx *priv_data)
 {
 	struct device		*dev = priv_data->dev;
@@ -250,10 +274,16 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data)
 
 static const struct dwc3_xlnx_config zynqmp_config = {
 	.pltfm_init = dwc3_xlnx_init_zynqmp,
+	.map_resource = true,
 };
 
 static const struct dwc3_xlnx_config versal_config = {
 	.pltfm_init = dwc3_xlnx_init_versal,
+	.map_resource = true,
+};
+
+static const struct dwc3_xlnx_config versal2_config = {
+	.pltfm_init = dwc3_xlnx_init_versal2,
 };
 
 static const struct of_device_id dwc3_xlnx_of_match[] = {
@@ -265,6 +295,10 @@ static const struct of_device_id dwc3_xlnx_of_match[] = {
 		.compatible = "xlnx,versal-dwc3",
 		.data = &versal_config,
 	},
+	{
+		.compatible = "xlnx,versal2-mmi-dwc3",
+		.data = &versal2_config,
+	},
 	{ /* Sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, dwc3_xlnx_of_match);
@@ -299,19 +333,23 @@ static int dwc3_xlnx_probe(struct platform_device *pdev)
 	struct dwc3_xlnx		*priv_data;
 	struct device			*dev = &pdev->dev;
 	struct device_node		*np = dev->of_node;
-	void __iomem			*regs;
 	int				ret;
 
 	priv_data = devm_kzalloc(dev, sizeof(*priv_data), GFP_KERNEL);
 	if (!priv_data)
 		return -ENOMEM;
 
-	regs = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(regs))
-		return dev_err_probe(dev, PTR_ERR(regs), "failed to map registers\n");
-
 	priv_data->dwc3_config = device_get_match_data(dev);
-	priv_data->regs = regs;
+
+	if (priv_data->dwc3_config->map_resource) {
+		void __iomem *regs;
+
+		regs = devm_platform_ioremap_resource(pdev, 0);
+		if (IS_ERR(regs))
+			return dev_err_probe(dev, PTR_ERR(regs),
+					     "failed to map registers\n");
+		priv_data->regs = regs;
+	}
 	priv_data->dev = dev;
 
 	platform_set_drvdata(pdev, priv_data);
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 2/4] usb: dwc3: xilinx: Introduce dwc3_xlnx_config for per-platform data
From: Radhey Shyam Pandey @ 2026-03-30 19:03 UTC (permalink / raw)
  To: gregkh, robh, krzk+dt, conor+dt, michal.simek, Thinh.Nguyen,
	p.zabel
  Cc: linux-usb, devicetree, linux-arm-kernel, linux-kernel, git,
	Radhey Shyam Pandey
In-Reply-To: <20260330190304.1841593-1-radhey.shyam.pandey@amd.com>

Replace the direct pltfm_init function pointer in struct dwc3_xlnx with
a const pointer to a new struct dwc3_xlnx_config. This groups
per-platform configuration in one place and allows future patches to add
platform-specific fields (e.g. tx_deemph) without growing dwc3_xlnx.

While at it, switch from of_match_node() to device_get_match_data() to
simplify the match data lookup.

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
---
Changes for v2:
- New patch, split from "Add Versal2 MMI USB 3.2 controller support".
- Use device_get_match_data() instead of of_match_node().
---
 drivers/usb/dwc3/dwc3-xilinx.c | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c
index f41b0da5e89d..bb59b56726e7 100644
--- a/drivers/usb/dwc3/dwc3-xilinx.c
+++ b/drivers/usb/dwc3/dwc3-xilinx.c
@@ -12,6 +12,7 @@
 #include <linux/clk.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
 #include <linux/dma-mapping.h>
 #include <linux/gpio/consumer.h>
 #include <linux/of_platform.h>
@@ -41,12 +42,18 @@
 #define XLNX_USB_FPD_POWER_PRSNT		0x80
 #define FPD_POWER_PRSNT_OPTION			BIT(0)
 
+struct dwc3_xlnx;
+
+struct dwc3_xlnx_config {
+	int				(*pltfm_init)(struct dwc3_xlnx *data);
+};
+
 struct dwc3_xlnx {
 	int				num_clocks;
 	struct clk_bulk_data		*clks;
 	struct device			*dev;
 	void __iomem			*regs;
-	int				(*pltfm_init)(struct dwc3_xlnx *data);
+	const struct dwc3_xlnx_config	*dwc3_config;
 	struct phy			*usb3_phy;
 };
 
@@ -241,14 +248,22 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data)
 	return ret;
 }
 
+static const struct dwc3_xlnx_config zynqmp_config = {
+	.pltfm_init = dwc3_xlnx_init_zynqmp,
+};
+
+static const struct dwc3_xlnx_config versal_config = {
+	.pltfm_init = dwc3_xlnx_init_versal,
+};
+
 static const struct of_device_id dwc3_xlnx_of_match[] = {
 	{
 		.compatible = "xlnx,zynqmp-dwc3",
-		.data = &dwc3_xlnx_init_zynqmp,
+		.data = &zynqmp_config,
 	},
 	{
 		.compatible = "xlnx,versal-dwc3",
-		.data = &dwc3_xlnx_init_versal,
+		.data = &versal_config,
 	},
 	{ /* Sentinel */ }
 };
@@ -284,7 +299,6 @@ static int dwc3_xlnx_probe(struct platform_device *pdev)
 	struct dwc3_xlnx		*priv_data;
 	struct device			*dev = &pdev->dev;
 	struct device_node		*np = dev->of_node;
-	const struct of_device_id	*match;
 	void __iomem			*regs;
 	int				ret;
 
@@ -296,9 +310,7 @@ static int dwc3_xlnx_probe(struct platform_device *pdev)
 	if (IS_ERR(regs))
 		return dev_err_probe(dev, PTR_ERR(regs), "failed to map registers\n");
 
-	match = of_match_node(dwc3_xlnx_of_match, pdev->dev.of_node);
-
-	priv_data->pltfm_init = match->data;
+	priv_data->dwc3_config = device_get_match_data(dev);
 	priv_data->regs = regs;
 	priv_data->dev = dev;
 
@@ -314,7 +326,7 @@ static int dwc3_xlnx_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	ret = priv_data->pltfm_init(priv_data);
+	ret = priv_data->dwc3_config->pltfm_init(priv_data);
 	if (ret)
 		goto err_clk_put;
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 1/4] dt-bindings: usb: dwc3-xilinx: Add MMI USB support on Versal Gen2 platform
From: Radhey Shyam Pandey @ 2026-03-30 19:03 UTC (permalink / raw)
  To: gregkh, robh, krzk+dt, conor+dt, michal.simek, Thinh.Nguyen,
	p.zabel
  Cc: linux-usb, devicetree, linux-arm-kernel, linux-kernel, git,
	Radhey Shyam Pandey
In-Reply-To: <20260330190304.1841593-1-radhey.shyam.pandey@amd.com>

Versal Gen2 platform multimedia integrated (MMI) module has a USB3.2 Gen
2x1 Dual Role Device IP. Introduce a new compatibility string to support
it. The USB wrapper registers reside in the MMI UDH system-level control
registers (SLCR) block, so instead of a dedicated reg property, add
xlnx,usb-syscon phandle with four cells specifying register offsets for
USB2 PHY, USB3 PHY, USB DRD, and USB power configuration within the SLCR.

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
---
Changes for v2:
- Add blank line after compatible as suggested by Krzysztof.
- Retain the mmi suffix in the compatible string, as this USB 3.2 Gen2
  IP from Synopsys is part of the dedicated Multimedia Interface. The
  Versal Gen2 platform also includes a separate USB 2.0 controller,
  and the mmi suffix uniquely distinguishes between the two USB
  controllers. MMI is an independent subsystem particularly targeted for
  deployment in Multi-Media related applications. The MMI block include
  following submodules: UDH: USB3.2 Gen 2x1 Dual Role Device, DisplayPort
  Transmit Controller, Security Module (ESM) for DisplayPort and HDMI
  Controllers, DP AUX-I2C PHY.
- For MMI USB define parent address space i.e UDH block.
- Fix inconsistent MHz spacing to use SI convention with spaces.
- Move description before $ref and items in xlnx,usb-syscon property.
- Restore original zynqmp-dwc3 example, add new versal2-mmi-dwc3 example.
- Use 'usb' node name (without unit address) for versal2 example since
  it has no reg property.
- Use 1/1 address/size configuration in versal2 example, use lowercase
  hex in syscon offsets.
---
 .../devicetree/bindings/usb/dwc3-xilinx.yaml  | 70 ++++++++++++++++++-
 1 file changed, 67 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/dwc3-xilinx.yaml b/Documentation/devicetree/bindings/usb/dwc3-xilinx.yaml
index d6823ef5f9a7..5e31b961aff7 100644
--- a/Documentation/devicetree/bindings/usb/dwc3-xilinx.yaml
+++ b/Documentation/devicetree/bindings/usb/dwc3-xilinx.yaml
@@ -15,6 +15,8 @@ properties:
       - enum:
           - xlnx,zynqmp-dwc3
           - xlnx,versal-dwc3
+          - xlnx,versal2-mmi-dwc3
+
   reg:
     maxItems: 1
 
@@ -37,8 +39,9 @@ properties:
       A list of phandle and clock-specifier pairs for the clocks
       listed in clock-names.
     items:
-      - description: Master/Core clock, has to be >= 125 MHz
-          for SS operation and >= 60MHz for HS operation.
+      - description: Master/Core clock, has to be >= 156.25 MHz in SSP
+          mode, >= 125 MHz for SS operation and >= 60 MHz for HS
+          operation.
       - description: Clock source to core during PHY power down.
 
   clock-names:
@@ -79,6 +82,20 @@ properties:
     description: GPIO used for the reset ulpi-phy
     maxItems: 1
 
+  xlnx,usb-syscon:
+    description:
+      Phandle to the MMI UDH system-level control register (SLCR) syscon
+      node, with four cells specifying the register offsets for USB2 PHY,
+      USB3 PHY, USB DRD, and USB power configuration respectively.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    items:
+      - items:
+          - description: phandle to MMI UDH SLCR syscon node
+          - description: USB2 PHY register offset within SLCR
+          - description: USB3 PHY register offset within SLCR
+          - description: USB DRD register offset within SLCR
+          - description: USB power register offset within SLCR
+
 # Required child node:
 
 patternProperties:
@@ -87,7 +104,6 @@ patternProperties:
 
 required:
   - compatible
-  - reg
   - "#address-cells"
   - "#size-cells"
   - ranges
@@ -104,6 +120,7 @@ allOf:
           contains:
             enum:
               - xlnx,versal-dwc3
+              - xlnx,versal2-mmi-dwc3
     then:
       properties:
         resets:
@@ -117,6 +134,26 @@ allOf:
         reset-names:
           minItems: 3
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - xlnx,zynqmp-dwc3
+              - xlnx,versal-dwc3
+    then:
+      required:
+        - reg
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: xlnx,versal2-mmi-dwc3
+    then:
+      required:
+        - xlnx,usb-syscon
+
 additionalProperties: false
 
 examples:
@@ -156,3 +193,30 @@ examples:
             };
         };
     };
+  - |
+    #include <dt-bindings/power/xlnx-zynqmp-power.h>
+    #include <dt-bindings/reset/xlnx-zynqmp-resets.h>
+    #include <dt-bindings/phy/phy.h>
+    usb {
+        #address-cells = <1>;
+        #size-cells = <1>;
+        compatible = "xlnx,versal2-mmi-dwc3";
+        clocks = <&zynqmp_clk 32>, <&zynqmp_clk 34>;
+        clock-names = "bus_clk", "ref_clk";
+        power-domains = <&zynqmp_firmware PD_USB_0>;
+        resets = <&zynqmp_reset ZYNQMP_RESET_USB1_CORERESET>;
+        reset-names = "usb_crst";
+        phys = <&psgtr 2 PHY_TYPE_USB3 0 2>;
+        phy-names = "usb3-phy";
+        xlnx,usb-syscon = <&udh_slcr 0x005c 0x0070 0x00c4 0x00f8>;
+        ranges;
+
+        usb@fe200000 {
+            compatible = "snps,dwc3";
+            reg = <0xfe200000 0x40000>;
+            interrupt-names = "host", "otg";
+            interrupts = <0 65 4>, <0 69 4>;
+            dr_mode = "host";
+            dma-coherent;
+        };
+    };
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 0/4] usb: dwc3: xilinx: Add Versal2 MMI USB 3.2 controller support
From: Radhey Shyam Pandey @ 2026-03-30 19:03 UTC (permalink / raw)
  To: gregkh, robh, krzk+dt, conor+dt, michal.simek, Thinh.Nguyen,
	p.zabel
  Cc: linux-usb, devicetree, linux-arm-kernel, linux-kernel, git,
	Radhey Shyam Pandey

This series introduces support for the Multi-Media Integrated (MMI) USB
3.2 Dual-Role Device (DRD) controller on Xilinx Versal2 platforms.

The controller supports SSP(10-Gbps), SuperSpeed, high-speed, full-speed
and low-speed operation modes.

USB2 and USB3 PHY support Physical connectivity via the Type-C
connectivity. DWC3 wrapper IP IO space is in SLCR so reg is made
optional.

The driver is required for the clock, reset and platform specific
initialization (coherency/TX_DEEMPH etc). In this initial version typec
reversibility is not implemented and it is assumed that USB3 PHY TCA mux
programming is done by MMI configuration data object (CDOs) and TI PD
controller is configured using external tiva programmer on VEK385
evaluation board.

Changes for v2:
- DT binding: fix MHz spacing (SI convention), reorder description
  before $ref in xlnx,usb-syscon, restore zynqmp-dwc3 example and add
  versal2-mmi-dwc3 example, fix node name for no-reg case, use 1/1
  address/size configuration and lowercase hex in syscon offsets.
- Split config struct refactoring (device_get_match_data,dwc3_xlnx_config)
  into a separate preparatory patch.
- Fix error message capitalization to lowercase per kernel convention.
- Rename property snps,lcsr_tx_deemph to snps,lcsr-tx-deemph (hyphens).
- Fix double space in comment and missing blank line in core.h.
- Use platform data instead of of_device_is_compatible() check for
  deemphasis support.

Link: https://lore.kernel.org/all/20251119193036.2666877-1-radhey.shyam.pandey@amd.com/

Radhey Shyam Pandey (4):
  dt-bindings: usb: dwc3-xilinx: Add MMI USB support on Versal Gen2
    platform
  usb: dwc3: xilinx: Introduce dwc3_xlnx_config for per-platform data
  usb: dwc3: xilinx: Add Versal2 MMI USB 3.2 controller support
  usb: dwc3: xilinx: Add support to program MMI USB TX deemphasis

 .../devicetree/bindings/usb/dwc3-xilinx.yaml  | 70 ++++++++++++++-
 drivers/usb/dwc3/core.c                       | 17 ++++
 drivers/usb/dwc3/core.h                       |  8 ++
 drivers/usb/dwc3/dwc3-xilinx.c                | 89 +++++++++++++++----
 4 files changed, 166 insertions(+), 18 deletions(-)


base-commit: 46b513250491a7bfc97d98791dbe6a10bcc8129d
-- 
2.43.0


^ permalink raw reply

* Re: [PATCH net-next 3/3] net: usb: smsc95xx: suspend PHY during USB suspend
From: Oliver Neukum @ 2026-03-30 17:39 UTC (permalink / raw)
  To: Parthiban Veerasooran, piergiorgio.beruto, andrew, hkallweit1,
	linux, davem, edumazet, kuba, pabeni, steve.glendinning,
	UNGLinuxDriver
  Cc: netdev, linux-usb
In-Reply-To: <20260330134222.67597-4-parthiban.veerasooran@microchip.com>



On 30.03.26 15:42, Parthiban Veerasooran wrote:
> The smsc95xx driver registers a PHY device but does not currently
> propagate suspend events to it when the USB interface is suspended.
> 
> Call phy_suspend() from the driver's suspend callback so the attached
> PHY can properly enter low-power state during system or runtime
> suspend. This aligns smsc95xx suspend handling with other network
> drivers that manage an external or integrated PHY.
> 
> Without this, the PHY may remain active and fail to execute its own
> suspend procedure, leading to unnecessary power consumption or
> incorrect resume behavior.
> 
> This change is also required for the EVB-LAN8670-USB Rev.D0 device to
> support OATC10-compliant sleep and wake functionality.
> 
> Signed-off-by: Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
> ---
>   drivers/net/usb/smsc95xx.c | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
> index 42e4048b574b..3a6e03b7410a 100644
> --- a/drivers/net/usb/smsc95xx.c
> +++ b/drivers/net/usb/smsc95xx.c
> @@ -1550,6 +1550,12 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
>   
>   	pdata->pm_task = current;
>   
> +	if (pdata->phydev) {
> +		ret = phy_suspend(pdata->phydev);
> +		if (ret)
> +			return ret;
> +	}

At this point you have suspended the phy.
Hence the device can no longer transmit

> +
>   	ret = usbnet_suspend(intf, message);

This wants to

1. drain the queue if you do runtime PM
2. can return -EBUSY

>   	if (ret < 0) {
>   		netdev_warn(dev->net, "usbnet_suspend error\n");

And here it will return in the error case. With the phy
already suspended.

And, as a question of principle: Why do you suspend the phy
in suspend(), but take no action in resume()?

	Regards
		Oliver



^ permalink raw reply

* Re: [PATCH] usb: misc: usbio: Fix URB memory leak on submit failure
From: Oliver Neukum @ 2026-03-30 17:26 UTC (permalink / raw)
  To: Felix Gu, Israel Cepeda, Hans de Goede, Sakari Ailus,
	Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel
In-Reply-To: <20260330-usbio-v1-1-7141b6dc612a@gmail.com>

On 30.03.26 17:47, Felix Gu wrote:
> When usb_submit_urb() fails in usbio_probe(), the previously allocated
> URB is never freed, causing a memory leak.
> 
> Add usb_free_urb() call to properly release the URB on the error path.

Hi,

the driver uses goto to unwind. Could you use the existing code
with an additional label defined?

	Regards
		Oliver


^ permalink raw reply

* Re: [PATCH v2] usbip: tools: Add usbip host driver availability check
From: Shuah Khan @ 2026-03-30 16:44 UTC (permalink / raw)
  To: Zongmin Zhou
  Cc: i, linux-kernel, linux-usb, valentina.manea.m, Zongmin Zhou,
	Greg KH, Shuah Khan
In-Reply-To: <1667ddf5-e36c-4cba-87b4-9cd3d34032e1@163.com>

On 3/29/26 21:10, Zongmin Zhou wrote:
> 
> On 2026/3/28 02:29, Shuah Khan wrote:
>> On 3/27/26 11:51, Shuah Khan wrote:
>>> On 3/27/26 02:39, Zongmin Zhou wrote:
>>>>
>>>> On 2026/3/27 02:43, Shuah Khan wrote:
>>>>> On 3/26/26 02:43, Greg KH wrote:
>>>
>>> [removed text]
>>>
>>>>>
>>>>> The problem Zongmin is trying fix ish when usbipd starts, it looks for
>>>>> exported if any - if it doesn't find any it assumes there aren't any
>>>>> exported and doesn't detect that usbip_host driver isn't loaded.
>>>>>
>>>>> refresh_exported_devices() doesn't have the logic and it shouldn't
>>>>> include that logic because this hook is called periodically to
>>>>> refresh the list of exported devices. Starting usbipd and loading
>>>>> the driver are distinct steps and without any dependencies.
>>>>>
>>>>> This patch he is trying to add that detection so a message can be printed
>>>>> to say "load the driver".
>>>>>
>>>>> A message can be added easily to cover two cases:
>>>>>
>>>>> 1. usbip_host driver isn't loaded
>>>>> 2. There are no exported devices.
>>>>>
>>>>> refresh_exported_devices() will not find any devices in both
>>>>> of the above scenarios. It isn't an error if it can't find
>>>>> any exported devices.
>>>>>
>>>>> An informational message when refresh_exported_devices()
>>>>> when it doesn't find any devices could help users.
>>>>>
>>>>> Zongmin,
>>>>>
>>>>> Would adding a message that says
>>>>> "Check if usbip_host driver is loaded or export devices"
>>>>> solve the problem of hard to debug problem you are addressing here?
>>>>>
>>>> Shuah,
>>>>
>>>> Your suggestion makes sense.
>>>> Adding an informational message when no devices are found would be a simple
>>>> and clean solution that helps users debug without being intrusive.
>>>>
>>>> However, I plan to add the info() message in usbip_generic_driver_open() instead of
>>>> refresh_exported_devices(), because:
>>>> - usbip_generic_driver_open() is called only once at initialization.
>>>> - refresh_exported_devices() is called periodically to refresh the exported device list.
>>>
>>> refresh_exported_devices() isn't called periodically - it is called
>>> from usbip_host_driver op: refresh_device_list and it will be called
>>> whenever usbipd (host side) calls it whenever it receives a request from
>>> user-space via process_request()
>>>
>>> For example running "usbip list -l" command will trigger a run of
>>> refresh_exported_devices() via usbip_host_driver op: refresh_device_list
>>>
>>> I don't think it will that noisy to add a message to refresh_exported_devices()
>>> when device list is zero. Currently the logic doesn't detect device list zero.
>>> You have add that condition to print informational message.
>>>
>>>
>>>> - When the server has no exported devices, having zero devices
>>>>    is normal and not worth frequent info messages.
>>>
>>> That is correct. Zero exported devices isn't an error and this could
>>> persist until devices are exported.
>>>
>>>>
>>>> Theoretically, we only need to prompt once at startup. Is my understanding correct?> > I'll also remove the existing error messages like below,
>>>> since they cannot accurately determine whether the driver is loaded:
>>>>
>>>> if (ret)
>>>>      err("please load " USBIP_CORE_MOD_NAME ".ko and "
>>>>          USBIP_HOST_DRV_NAME ".ko!");
>>>
>>> Leave this one alone, because it gets called from a couple of places.
> In usbip_generic_driver_open(), the only path that triggers this message is a failure of udev_new().
> This function fails due to system-level issues like memory exhaustion, not because usbip driver module is missing.
> 
> Furthermore, since refresh_exported_devices() doesn't practically return an error here,
> the message is never seen during actual driver loading failures.
> So I think it’s better to remove this inaccurate hint to avoid confusing the users.
> 
> This is the reason why I previously wanted to remove it.
>>>
>>
>> Better yet, why not change the usbip instead - usbip_list for example.
>> This is the one that prints the device list and the change can be made
>> there when the list is zero to say, "Check if driver is loaded and
>> exported devices"
> I think placing the check/message in refresh_exported_devices() would be more effective.
> This function covers all scenarios where the device list is refreshed, including:
> usbipd startup, usbip list -r, and usbip attach operations.

Right changing refresh_exported_devices() covers all cases. Think about the
following scenarios:

- Where will this message get printed when usbipd is started on the console and in
   background?

- Where will this message get printed when user runs various usbip list commands?

Ideally these commands should tell the user what happened without looking
at daemon logs.

thanks,
-- Shuah

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox