[PATCH v3 2/2] usb: gadget: renesas: add support for RZ/G2L SoC

Marek Vasut marek.vasut at mailbox.org
Thu Apr 16 20:11:36 CEST 2026


On 4/16/26 5:38 PM, Michele Bisogno wrote:
> common: Add "renesas,rzg2l-usbhs" compatible and support
> reset deassertion. Fix a re-entrancy bug by calling usb_del_gadget_udc()
> in the remove callback to prevent stale UDC list entries.
> fifo: Refactor PIO push/pop logic to handle trailing bytes
> using iowrite8/ioread8. This ensures correct data alignment on
> RZ/G2L and simplifies the data transfer loop.

This looks like two separate changes.

> Signed-off-by: Michele Bisogno <micbis.openwrt at gmail.com>
> ---
>   drivers/usb/gadget/rcar/common.c | 15 +++++++++++++++
>   drivers/usb/gadget/rcar/fifo.c   | 23 +++++++++++++----------
>   2 files changed, 28 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/usb/gadget/rcar/common.c b/drivers/usb/gadget/rcar/common.c
> index 2ba022a3f2c..1f266ae5ac9 100644
> --- a/drivers/usb/gadget/rcar/common.c
> +++ b/drivers/usb/gadget/rcar/common.c
> @@ -16,6 +16,7 @@
>   #include <linux/usb/ch9.h>
>   #include <linux/usb/gadget.h>
>   #include <usb.h>
> +#include <reset.h>
>   
>   #include "common.h"
>   
> @@ -397,6 +398,7 @@ static int usbhs_udc_otg_probe(struct udevice *dev)
>   	struct usbhs_priv_otg_data *priv = dev_get_priv(dev);
>   	struct usb_gadget *gadget;
>   	struct clk_bulk clk_bulk;
> +	struct reset_ctl_bulk reset_bulk;
>   	int ret = -EINVAL;
>   
>   	priv->base = dev_read_addr_ptr(dev);
> @@ -411,6 +413,14 @@ static int usbhs_udc_otg_probe(struct udevice *dev)
>   	if (ret)
>   		return ret;
>   
> +	ret = reset_get_bulk(dev, &reset_bulk);
> +	if (ret)
> +		return ret;
> +
> +	ret = reset_deassert_bulk(&reset_bulk);
> +	if (ret)
> +		return ret;

This reset handling should be a separate patch.

>   	clrsetbits_le32(priv->base + UGCTRL2, UGCTRL2_USB0SEL_MASK, UGCTRL2_USB0SEL_EHCI);
>   	clrsetbits_le16(priv->base + LPSTS, LPSTS_SUSPM, LPSTS_SUSPM);
>   
> @@ -447,7 +457,11 @@ err_clk:
>   static int usbhs_udc_otg_remove(struct udevice *dev)
>   {
>   	struct usbhs_priv_otg_data *priv = dev_get_priv(dev);
> +	struct usb_gadget *gadget;
>   
> +	gadget = usbhsg_get_gadget(&priv->usbhs_priv);
> +	if (gadget)
> +		usb_del_gadget_udc(gadget);

This also looks like a separate fix for some other issue ?

Also, reset_assert/put_bulk() is missing here ?

>   	usbhs_rcar3_power_ctrl(&priv->usbhs_priv, false);
>   	usbhs_mod_remove(&priv->usbhs_priv);
>   	usbhs_fifo_remove(&priv->usbhs_priv);
> @@ -460,6 +474,7 @@ static int usbhs_udc_otg_remove(struct udevice *dev)
>   
>   static const struct udevice_id usbhs_udc_otg_ids[] = {
>   	{ .compatible = "renesas,rcar-gen3-usbhs" },
> +	{ .compatible = "renesas,rzg2l-usbhs"},

Separate patch please, this should be last, after all the fixes.

>   	{},
>   };
>   
> diff --git a/drivers/usb/gadget/rcar/fifo.c b/drivers/usb/gadget/rcar/fifo.c
> index 6016b2987d5..b5340b4d860 100644
> --- a/drivers/usb/gadget/rcar/fifo.c

This whole FIFO part should also be a separate patch, and it should also 
be implemented for the Linux kernel, otherwise the two code bases will 
diverge. Please submit a matching patch to Linux.

> +++ b/drivers/usb/gadget/rcar/fifo.c
> @@ -535,18 +535,21 @@ static int usbhsf_pio_try_push(struct usbhs_pkt *pkt, int *is_done)
>   	 * 32-bit access only
>   	 */
>   	if (len >= 4 && !((unsigned long)buf & 0x03)) {
> -		iowrite32_rep(addr, buf, len / 4);
> -		len %= 4;
> -		buf += total_len - len;
> +		int words = len / 4;
> +
> +		iowrite32_rep(addr, buf, words);
> +		buf += (words * 4);
> +		len -= (words * 4);
>   	}
>   
>   	/* the rest operation */
> -	if (usbhs_get_dparam(priv, cfifo_byte_addr)) {
> -		for (i = 0; i < len; i++)
> -			iowrite8(buf[i], addr + (i & 0x03));
> -	} else {
> -		for (i = 0; i < len; i++)
> -			iowrite8(buf[i], addr + (0x03 - (i & 0x03)));
> +	if (len > 0) {
> +		if (len == 2 && !((unsigned long)buf & 0x01)) {
> +			iowrite16(*(u16 *)buf, addr);
> +		} else {
> +			for (i = 0; i < len; i++)
> +				iowrite8(buf[i], addr);
> +		}
>   	}
>   
>   	/*
> @@ -716,7 +719,7 @@ static int usbhsf_pio_try_pop(struct usbhs_pkt *pkt, int *is_done)
>   		if (!(i & 0x03))
>   			data = ioread32(addr);
>   
> -		buf[i] = (data >> ((i & 0x03) * 8)) & 0xff;
> +		buf[i] = ioread8(addr);
>   	}
>   
>   usbhs_fifo_read_end:

[...]


More information about the U-Boot mailing list