All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/3] usb: gadget: rcar: Add RZ/G2L support and lifecycle fixes
@ 2026-04-22 16:59 Michele Bisogno
  2026-04-22 16:59 ` [PATCH v4 1/3] usb: gadget: rcar: Fix gadget registration lifecycle in remove Michele Bisogno
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Michele Bisogno @ 2026-04-22 16:59 UTC (permalink / raw)
  To: Marek Vasut, Lukasz Majewski, Mattijs Korpershoek
  Cc: Nobuhiro Iwamatsu, Tom Rini, u-boot, Michele Bisogno

This series adds support for the Renesas RZ/G2L (R9A07G044) USBHS
controller. During development, several lifecycle and resource 
management issues were identified and addressed to satisfy RZ/G2L 
hardware requirements and prevent resource leaks across the driver.

The series is split into three logical parts to ensure bisectability:
1. A bugfix for the gadget deletion sequence during driver remove.
2. The addition of reset controller infrastructure and proper 
   clock/reset teardown logic.
3. The RZ/G2L specific hardware parameters, SYSCFG logic, and 
   compatible strings.

Changes in v4:
- Split the monolithic patch into a 3-patch series as requested.
- Added usb_del_gadget_udc() to fix resource leak on driver remove.
- Implemented bulk reset controller support (required for RZ/G2L).
- Improved error handling in probe() to ensure clocks are disabled 
  if reset initialization or deassertion fails.
- Moved reset and clock handles to private data to ensure persistence.
- Reorganized hunks to ensure each patch in the series compiles 
  independently (bisectability).

Michele Bisogno (3):
  usb: gadget: rcar: Fix gadget registration lifecycle in remove
  usb: gadget: rcar: Add support for reset controller
  usb: gadget: rcar: Add support for RZ/G2L (R9A07G044)

 drivers/usb/gadget/rcar/common.c      | 53 ++++++++++++++++++++++++---
 drivers/usb/gadget/rcar/renesas_usb.h |  1 +
 2 files changed, 48 insertions(+), 6 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v4 1/3] usb: gadget: rcar: Fix gadget registration lifecycle in remove
  2026-04-22 16:59 [PATCH v4 0/3] usb: gadget: rcar: Add RZ/G2L support and lifecycle fixes Michele Bisogno
@ 2026-04-22 16:59 ` Michele Bisogno
       [not found]   ` <edd83758-4f28-425c-b828-fb1e7a885d4d@mailbox.org>
  2026-04-22 16:59 ` [PATCH v4 2/3] usb: gadget: rcar: Add support for reset controller Michele Bisogno
  2026-04-22 16:59 ` [PATCH v4 3/3] usb: gadget: rcar: Add support for RZ/G2L (R9A07G044) Michele Bisogno
  2 siblings, 1 reply; 6+ messages in thread
From: Michele Bisogno @ 2026-04-22 16:59 UTC (permalink / raw)
  To: Marek Vasut, Lukasz Majewski, Mattijs Korpershoek
  Cc: Nobuhiro Iwamatsu, Tom Rini, u-boot, Michele Bisogno

The driver currently fails to unregister the USB gadget when the
device is removed or the driver is unbound. This leads to dangling
pointers in the UDC core and potential memory corruption.

Add a call to usb_del_gadget_udc() in the remove path to ensure
a clean teardown of the gadget interface.

Signed-off-by: Michele Bisogno <micbis.openwrt@gmail.com>
---
 drivers/usb/gadget/rcar/common.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/usb/gadget/rcar/common.c b/drivers/usb/gadget/rcar/common.c
index 2ba022a3f2c..f7b34f0485f 100644
--- a/drivers/usb/gadget/rcar/common.c
+++ b/drivers/usb/gadget/rcar/common.c
@@ -447,8 +447,12 @@ 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;
 
 	usbhs_rcar3_power_ctrl(&priv->usbhs_priv, false);
+	gadget = usbhsg_get_gadget(&priv->usbhs_priv);
+	if (gadget)
+		usb_del_gadget_udc(gadget);
 	usbhs_mod_remove(&priv->usbhs_priv);
 	usbhs_fifo_remove(&priv->usbhs_priv);
 	usbhs_pipe_remove(&priv->usbhs_priv);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v4 2/3] usb: gadget: rcar: Add support for reset controller
  2026-04-22 16:59 [PATCH v4 0/3] usb: gadget: rcar: Add RZ/G2L support and lifecycle fixes Michele Bisogno
  2026-04-22 16:59 ` [PATCH v4 1/3] usb: gadget: rcar: Fix gadget registration lifecycle in remove Michele Bisogno
@ 2026-04-22 16:59 ` Michele Bisogno
       [not found]   ` <4961ac43-a879-411d-a32e-7fe8d1c879e5@mailbox.org>
  2026-04-22 16:59 ` [PATCH v4 3/3] usb: gadget: rcar: Add support for RZ/G2L (R9A07G044) Michele Bisogno
  2 siblings, 1 reply; 6+ messages in thread
From: Michele Bisogno @ 2026-04-22 16:59 UTC (permalink / raw)
  To: Marek Vasut, Lukasz Majewski, Mattijs Korpershoek
  Cc: Nobuhiro Iwamatsu, Tom Rini, u-boot, Michele Bisogno

Some Renesas SoCs, such as the RZ/G2L, require the USBHS core to
be explicitly deasserted from reset before register access is
possible.

Update the OTG probe to handle a bulk reset controller. To maintain
hardware stability, the reset is deasserted after clocks are
enabled in probe(), and asserted before clocks are disabled
in remove().

Update the error paths in probe to ensures clocks are disabled
if the reset initialization fails.

Signed-off-by: Michele Bisogno <micbis.openwrt@gmail.com>
---
 drivers/usb/gadget/rcar/common.c | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/gadget/rcar/common.c b/drivers/usb/gadget/rcar/common.c
index f7b34f0485f..a5d56f8dbe4 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"
 
@@ -290,6 +291,9 @@ struct usbhs_priv_otg_data {
 	void __iomem		*base;
 	void __iomem		*phybase;
 
+	struct clk_bulk clk_bulk;
+	struct reset_ctl_bulk reset_bulk;
+
 	struct platform_device	usbhs_dev;
 	struct usbhs_priv	usbhs_priv;
 
@@ -355,7 +359,7 @@ static int usbhs_udc_otg_gadget_handle_interrupts(struct udevice *dev)
 	return 0;
 }
 
-static int usbhs_probe(struct usbhs_priv *priv)
+static int usbhs_probe(struct usbhs_priv *priv, struct udevice *dev)
 {
 	int ret;
 
@@ -396,21 +400,28 @@ 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;
 	int ret = -EINVAL;
 
 	priv->base = dev_read_addr_ptr(dev);
 	if (!priv->base)
 		return -EINVAL;
 
-	ret = clk_get_bulk(dev, &clk_bulk);
+	ret = clk_get_bulk(dev, &priv->clk_bulk);
 	if (ret)
 		return ret;
 
-	ret = clk_enable_bulk(&clk_bulk);
+	ret = clk_enable_bulk(&priv->clk_bulk);
 	if (ret)
 		return ret;
 
+	ret = reset_get_bulk(dev, &priv->reset_bulk);
+	if (ret)
+		goto err_clk;
+
+	ret = reset_deassert_bulk(&priv->reset_bulk);
+	if (ret)
+		goto err_clk;
+
 	clrsetbits_le32(priv->base + UGCTRL2, UGCTRL2_USB0SEL_MASK, UGCTRL2_USB0SEL_EHCI);
 	clrsetbits_le16(priv->base + LPSTS, LPSTS_SUSPM, LPSTS_SUSPM);
 
@@ -423,7 +434,7 @@ static int usbhs_udc_otg_probe(struct udevice *dev)
 	priv->usbhs_priv.pdev = &priv->usbhs_dev;
 	priv->usbhs_priv.base = priv->base;
 	priv->usbhs_dev.dev.driver_data = &priv->usbhs_priv;
-	ret = usbhs_probe(&priv->usbhs_priv);
+	ret = usbhs_probe(&priv->usbhs_priv, dev);
 	if (ret < 0)
 		goto err_phy;
 
@@ -440,7 +451,7 @@ static int usbhs_udc_otg_probe(struct udevice *dev)
 err_phy:
 	generic_shutdown_phy(&priv->phy);
 err_clk:
-	clk_disable_bulk(&clk_bulk);
+	clk_disable_bulk(&priv->clk_bulk);
 	return ret;
 }
 
@@ -457,6 +468,12 @@ static int usbhs_udc_otg_remove(struct udevice *dev)
 	usbhs_fifo_remove(&priv->usbhs_priv);
 	usbhs_pipe_remove(&priv->usbhs_priv);
 
+	reset_assert_bulk(&priv->reset_bulk);
+	reset_release_bulk(&priv->reset_bulk);
+
+	clk_disable_bulk(&priv->clk_bulk);
+	clk_release_bulk(&priv->clk_bulk);
+
 	generic_shutdown_phy(&priv->phy);
 
 	return dm_scan_fdt_dev(dev);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v4 3/3] usb: gadget: rcar: Add support for RZ/G2L (R9A07G044)
  2026-04-22 16:59 [PATCH v4 0/3] usb: gadget: rcar: Add RZ/G2L support and lifecycle fixes Michele Bisogno
  2026-04-22 16:59 ` [PATCH v4 1/3] usb: gadget: rcar: Fix gadget registration lifecycle in remove Michele Bisogno
  2026-04-22 16:59 ` [PATCH v4 2/3] usb: gadget: rcar: Add support for reset controller Michele Bisogno
@ 2026-04-22 16:59 ` Michele Bisogno
  2 siblings, 0 replies; 6+ messages in thread
From: Michele Bisogno @ 2026-04-22 16:59 UTC (permalink / raw)
  To: Marek Vasut, Lukasz Majewski, Mattijs Korpershoek
  Cc: Nobuhiro Iwamatsu, Tom Rini, u-boot, Michele Bisogno

The Renesas RZ/G2L (and RZ/G2LC) USBHS controller requires the
CNEN bit in the SYSCFG register to be set for function operation.
Additionally, its CFIFO is byte-addressable.

Introduce a new renesas_usbhs_driver_param structure for the
RZ/G2L SoC and link it via the udevice_id data pointer. Update
usbhs_probe() to accept the udevice pointer to retrieve these
parameters during initialization.

This alignment follows the logic used in the Linux kernel
renesas_usbhs driver.

Signed-off-by: Michele Bisogno <micbis.openwrt@gmail.com>
---
 drivers/usb/gadget/rcar/common.c      | 20 ++++++++++++++++++++
 drivers/usb/gadget/rcar/renesas_usb.h |  1 +
 2 files changed, 21 insertions(+)

diff --git a/drivers/usb/gadget/rcar/common.c b/drivers/usb/gadget/rcar/common.c
index a5d56f8dbe4..051cab8a422 100644
--- a/drivers/usb/gadget/rcar/common.c
+++ b/drivers/usb/gadget/rcar/common.c
@@ -92,6 +92,12 @@ void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable)
 	u16 mask = DCFM | DRPD | DPRPU | HSE | USBE;
 	u16 val  = HSE | USBE;
 
+	/* CNEN bit is required for function operation */
+	if (usbhs_get_dparam(priv, has_cnen)) {
+		mask |= CNEN;
+		val  |= CNEN;
+	}
+
 	/*
 	 * if enable
 	 *
@@ -361,13 +367,21 @@ static int usbhs_udc_otg_gadget_handle_interrupts(struct udevice *dev)
 
 static int usbhs_probe(struct usbhs_priv *priv, struct udevice *dev)
 {
+	struct renesas_usbhs_driver_param *plat_param;
 	int ret;
 
+	plat_param = (struct renesas_usbhs_driver_param *)dev_get_driver_data(dev);
+
 	priv->dparam.type = USBHS_TYPE_RCAR_GEN3;
 	priv->dparam.pio_dma_border = 64;
 	priv->dparam.pipe_configs = usbhsc_new_pipe;
 	priv->dparam.pipe_size = ARRAY_SIZE(usbhsc_new_pipe);
 
+	if (plat_param) {
+		priv->dparam.has_cnen		= plat_param->has_cnen;
+		priv->dparam.cfifo_byte_addr	= plat_param->cfifo_byte_addr;
+	}
+
 	/* call pipe and module init */
 	ret = usbhs_pipe_probe(priv);
 	if (ret < 0)
@@ -479,8 +493,14 @@ static int usbhs_udc_otg_remove(struct udevice *dev)
 	return dm_scan_fdt_dev(dev);
 }
 
+static struct renesas_usbhs_driver_param rzg2l_param = {
+	.has_cnen = 1,
+	.cfifo_byte_addr = 1,
+};
+
 static const struct udevice_id usbhs_udc_otg_ids[] = {
 	{ .compatible = "renesas,rcar-gen3-usbhs" },
+	{ .compatible = "renesas,rzg2l-usbhs", .data = (unsigned long)&rzg2l_param },
 	{},
 };
 
diff --git a/drivers/usb/gadget/rcar/renesas_usb.h b/drivers/usb/gadget/rcar/renesas_usb.h
index 8155e3dcaf6..140a70251cf 100644
--- a/drivers/usb/gadget/rcar/renesas_usb.h
+++ b/drivers/usb/gadget/rcar/renesas_usb.h
@@ -111,6 +111,7 @@ struct renesas_usbhs_driver_param {
 	u32 has_otg:1; /* for controlling PWEN/EXTLP */
 	u32 has_sudmac:1; /* for SUDMAC */
 	u32 has_usb_dmac:1; /* for USB-DMAC */
+	u32 has_cnen:1;
 	u32 cfifo_byte_addr:1; /* CFIFO is byte addressable */
 #define USBHS_USB_DMAC_XFER_SIZE	32	/* hardcode the xfer size */
 	u32 multi_clks:1;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v4 1/3] usb: gadget: rcar: Fix gadget registration lifecycle in remove
       [not found]   ` <edd83758-4f28-425c-b828-fb1e7a885d4d@mailbox.org>
@ 2026-04-23  8:05     ` Michele Bisogno
  0 siblings, 0 replies; 6+ messages in thread
From: Michele Bisogno @ 2026-04-23  8:05 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Lukasz Majewski, Mattijs Korpershoek, Nobuhiro Iwamatsu, Tom Rini,
	u-boot

On Thu, 23 Apr 2026 at 05:02, Marek Vasut <marek.vasut@mailbox.org> wrote:
>
> On 4/22/26 6:59 PM, Michele Bisogno wrote:
> > The driver currently fails to unregister the USB gadget when the
> > device is removed or the driver is unbound. This leads to dangling
> > pointers in the UDC core and potential memory corruption.
> >
> > Add a call to usb_del_gadget_udc() in the remove path to ensure
> > a clean teardown of the gadget interface.
> >
> > Signed-off-by: Michele Bisogno <micbis.openwrt@gmail.com>
> > ---
> >   drivers/usb/gadget/rcar/common.c | 4 ++++
> >   1 file changed, 4 insertions(+)
> >
> > diff --git a/drivers/usb/gadget/rcar/common.c b/drivers/usb/gadget/rcar/common.c
> > index 2ba022a3f2c..f7b34f0485f 100644
> > --- a/drivers/usb/gadget/rcar/common.c
> > +++ b/drivers/usb/gadget/rcar/common.c
> > @@ -447,8 +447,12 @@ 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;
> >
> >       usbhs_rcar3_power_ctrl(&priv->usbhs_priv, false);
> > +     gadget = usbhsg_get_gadget(&priv->usbhs_priv);
>
> One more nitpick, usbhsg_get_gadget() can never return NULL, so this
> test for NULL is unnecessary, please drop it.

OK.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4 2/3] usb: gadget: rcar: Add support for reset controller
       [not found]   ` <4961ac43-a879-411d-a32e-7fe8d1c879e5@mailbox.org>
@ 2026-04-23  8:14     ` Michele Bisogno
  0 siblings, 0 replies; 6+ messages in thread
From: Michele Bisogno @ 2026-04-23  8:14 UTC (permalink / raw)
  To: Marek Vasut
  Cc: Lukasz Majewski, Mattijs Korpershoek, Nobuhiro Iwamatsu, Tom Rini,
	u-boot

On Thu, 23 Apr 2026 at 05:02, Marek Vasut <marek.vasut@mailbox.org> wrote:
>
> On 4/22/26 6:59 PM, Michele Bisogno wrote:
>
> [...]
>
> > -static int usbhs_probe(struct usbhs_priv *priv)
> > +static int usbhs_probe(struct usbhs_priv *priv, struct udevice *dev)
> >   {
> >       int ret;
> >
> > @@ -396,21 +400,28 @@ static int usbhs_udc_otg_probe(struct udevice *dev)
> >   {
> >       struct usbhs_priv_otg_data *priv = dev_get_priv(dev);
>
> [...]
>
> > -     ret = usbhs_probe(&priv->usbhs_priv);
> > +     ret = usbhs_probe(&priv->usbhs_priv, dev);
>
> It would be sufficient to pass dev to usbhs_probe().
>
> usbhs_probe() can extract the struct usbhs_priv *priv from it:
>
> "
> struct usbhs_priv_otg_data *priv = dev_get_priv(dev);
> struct usbhs_priv *priv = &priv->usbhs_priv;
> "

OK, actually I thought about that but I was unsure which one was best.

> >       if (ret < 0)
> >               goto err_phy;
> >
> > @@ -440,7 +451,7 @@ static int usbhs_udc_otg_probe(struct udevice *dev)
> >   err_phy:
> >       generic_shutdown_phy(&priv->phy);
> >   err_clk:
> > -     clk_disable_bulk(&clk_bulk);
> > +     clk_disable_bulk(&priv->clk_bulk);
>
> Reset likely needs to be handled in this fail path too ?

OK.

Thanks for your review and suggestions!

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-04-25 20:36 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-22 16:59 [PATCH v4 0/3] usb: gadget: rcar: Add RZ/G2L support and lifecycle fixes Michele Bisogno
2026-04-22 16:59 ` [PATCH v4 1/3] usb: gadget: rcar: Fix gadget registration lifecycle in remove Michele Bisogno
     [not found]   ` <edd83758-4f28-425c-b828-fb1e7a885d4d@mailbox.org>
2026-04-23  8:05     ` Michele Bisogno
2026-04-22 16:59 ` [PATCH v4 2/3] usb: gadget: rcar: Add support for reset controller Michele Bisogno
     [not found]   ` <4961ac43-a879-411d-a32e-7fe8d1c879e5@mailbox.org>
2026-04-23  8:14     ` Michele Bisogno
2026-04-22 16:59 ` [PATCH v4 3/3] usb: gadget: rcar: Add support for RZ/G2L (R9A07G044) Michele Bisogno

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.