* [PATCH v10 1/5] mux: Add driver for Renesas RZ/V2H USB VBENCTL VBUS_SEL mux
2026-04-01 15:16 [PATCH v10 0/5] Add USB2.0 VBUS mux driver and extend rzv2h-usb2phy reset for RZ/G3E support Tommaso Merciai
@ 2026-04-01 15:16 ` Tommaso Merciai
2026-04-01 15:16 ` [PATCH v10 2/5] dt-bindings: reset: renesas,rzv2h-usb2phy: Add '#mux-state-cells' property Tommaso Merciai
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Tommaso Merciai @ 2026-04-01 15:16 UTC (permalink / raw)
To: tomm.merciai, peda, p.zabel
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, Fabrizio Castro,
Lad Prabhakar, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Arnd Bergmann, Ulf Hansson,
Josua Mayer, devicetree, linux-kernel
As per the RZ/V2H(P) HW manual, VBUSEN can be controlled by the VBUS_SEL
bit of the VBENCTL Control Register. This register is mapped in the
reset framework. The reset driver expose this register as mux-controller
and instantiates this driver. The consumer will use the mux API to
control the VBUS_SEL bit.
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
v9->v10:
- No changes.
v8->v9:
- Fixed driver comment year (2025 -> 2026)
- Switch from devm_regmap_init_mmio() to dev_get_regmap().
- Drop unnecessasry include bitops.h, of.h, property.h and
drivers/reset/reset-rzv2h-usb2phy.h headers, driver is now based on regmap.
- Collected PZabel tag.
v7->v8:
- No changes.
v6->v7:
- No changes.
v5->v6:
- No changes.
v4->v5:
- Changed file name to rzv2h-usb-vbenctl.c and Fixed
Makefile, Kconfig, function names accordingly.
- Changed driver .name to "vbenctl" and fix auxiliary_device_id name.
- Updated commit msg.
v3->v4:
- Removed mux_chip->dev.of_node not needed.
v2->v3:
- Added mux_chip->dev.of_node = dev->of_node->child as the mux-controller
is an internal node.
- Fixed auxiliary_device_id name.
- Get rdev using from platform_data.
- Drop struct auxiliary_device adev from reset_rzv2h_usb2phy_adev
as it is needed.
- Drop to_reset_rzv2h_usb2phy_adev() as it is not needed.
v1->v2:
- New patch
drivers/mux/Kconfig | 11 +++++
drivers/mux/Makefile | 2 +
drivers/mux/rzv2h-usb-vbenctl.c | 85 +++++++++++++++++++++++++++++++++
3 files changed, 98 insertions(+)
create mode 100644 drivers/mux/rzv2h-usb-vbenctl.c
diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig
index 6d17dfa25dad..7f334540c189 100644
--- a/drivers/mux/Kconfig
+++ b/drivers/mux/Kconfig
@@ -70,6 +70,17 @@ config MUX_MMIO
To compile the driver as a module, choose M here: the module will
be called mux-mmio.
+config MUX_RZV2H_USB_VBENCTL
+ tristate "Renesas RZ/V2H USB VBENCTL VBUS_SEL mux driver"
+ depends on RESET_RZV2H_USB2PHY || COMPILE_TEST
+ depends on OF
+ select REGMAP
+ select AUXILIARY_BUS
+ default RESET_RZV2H_USB2PHY
+ help
+ Support for USB VBENCTL VBUS_SEL mux implemented on Renesas
+ RZ/V2H SoCs.
+
endmenu
endif # MULTIPLEXER
diff --git a/drivers/mux/Makefile b/drivers/mux/Makefile
index 6e9fa47daf56..3bd9b3846835 100644
--- a/drivers/mux/Makefile
+++ b/drivers/mux/Makefile
@@ -8,9 +8,11 @@ mux-adg792a-objs := adg792a.o
mux-adgs1408-objs := adgs1408.o
mux-gpio-objs := gpio.o
mux-mmio-objs := mmio.o
+mux-rzv2h-usb-vbenctl-objs := rzv2h-usb-vbenctl.o
obj-$(CONFIG_MULTIPLEXER) += mux-core.o
obj-$(CONFIG_MUX_ADG792A) += mux-adg792a.o
obj-$(CONFIG_MUX_ADGS1408) += mux-adgs1408.o
obj-$(CONFIG_MUX_GPIO) += mux-gpio.o
obj-$(CONFIG_MUX_MMIO) += mux-mmio.o
+obj-$(CONFIG_MUX_RZV2H_USB_VBENCTL) += mux-rzv2h-usb-vbenctl.o
diff --git a/drivers/mux/rzv2h-usb-vbenctl.c b/drivers/mux/rzv2h-usb-vbenctl.c
new file mode 100644
index 000000000000..79197fddbf74
--- /dev/null
+++ b/drivers/mux/rzv2h-usb-vbenctl.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas RZ/V2H(P) USB VBENCTL VBUS_SEL mux driver
+ *
+ * Copyright (C) 2026 Renesas Electronics Corp.
+ */
+
+#include <linux/auxiliary_bus.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/mux/driver.h>
+#include <linux/regmap.h>
+
+#define RZV2H_VBENCTL 0xf0c
+
+struct mux_rzv2h_usb_vbenctl_priv {
+ struct regmap_field *field;
+};
+
+static int mux_rzv2h_usb_vbenctl_set(struct mux_control *mux, int state)
+{
+ struct mux_rzv2h_usb_vbenctl_priv *priv = mux_chip_priv(mux->chip);
+
+ return regmap_field_write(priv->field, state);
+}
+
+static const struct mux_control_ops mux_rzv2h_usb_vbenctl_ops = {
+ .set = mux_rzv2h_usb_vbenctl_set,
+};
+
+static int mux_rzv2h_usb_vbenctl_probe(struct auxiliary_device *adev,
+ const struct auxiliary_device_id *id)
+{
+ struct mux_rzv2h_usb_vbenctl_priv *priv;
+ struct device *dev = &adev->dev;
+ struct mux_chip *mux_chip;
+ struct regmap *regmap;
+ struct reg_field reg_field = {
+ .reg = RZV2H_VBENCTL,
+ .lsb = 0,
+ .msb = 0,
+ };
+ int ret;
+
+ regmap = dev_get_regmap(adev->dev.parent, NULL);
+ if (!regmap)
+ return -ENODEV;
+
+ mux_chip = devm_mux_chip_alloc(dev, 1, sizeof(*priv));
+ if (IS_ERR(mux_chip))
+ return PTR_ERR(mux_chip);
+
+ priv = mux_chip_priv(mux_chip);
+
+ priv->field = devm_regmap_field_alloc(dev, regmap, reg_field);
+ if (IS_ERR(priv->field))
+ return PTR_ERR(priv->field);
+
+ mux_chip->ops = &mux_rzv2h_usb_vbenctl_ops;
+ mux_chip->mux[0].states = 2;
+ mux_chip->mux[0].idle_state = MUX_IDLE_AS_IS;
+
+ ret = devm_mux_chip_register(dev, mux_chip);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to register mux chip\n");
+
+ return 0;
+}
+
+static const struct auxiliary_device_id mux_rzv2h_usb_vbenctl_ids[] = {
+ { .name = "rzv2h_usb2phy_reset.vbenctl" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(auxiliary, mux_rzv2h_usb_vbenctl_ids);
+
+static struct auxiliary_driver mux_rzv2h_usb_vbenctl_driver = {
+ .name = "vbenctl",
+ .probe = mux_rzv2h_usb_vbenctl_probe,
+ .id_table = mux_rzv2h_usb_vbenctl_ids,
+};
+module_auxiliary_driver(mux_rzv2h_usb_vbenctl_driver);
+
+MODULE_DESCRIPTION("RZ/V2H USB VBENCTL VBUS_SEL mux driver");
+MODULE_AUTHOR("Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>");
+MODULE_LICENSE("GPL");
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v10 2/5] dt-bindings: reset: renesas,rzv2h-usb2phy: Add '#mux-state-cells' property
2026-04-01 15:16 [PATCH v10 0/5] Add USB2.0 VBUS mux driver and extend rzv2h-usb2phy reset for RZ/G3E support Tommaso Merciai
2026-04-01 15:16 ` [PATCH v10 1/5] mux: Add driver for Renesas RZ/V2H USB VBENCTL VBUS_SEL mux Tommaso Merciai
@ 2026-04-01 15:16 ` Tommaso Merciai
2026-04-01 15:16 ` [PATCH v10 3/5] dt-bindings: reset: renesas,rzv2h-usb2phy: Document RZ/G3E USB2PHY reset Tommaso Merciai
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Tommaso Merciai @ 2026-04-01 15:16 UTC (permalink / raw)
To: tomm.merciai, peda, p.zabel
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, Fabrizio Castro,
Lad Prabhakar, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Arnd Bergmann, Ulf Hansson,
Josua Mayer, devicetree, linux-kernel, Krzysztof Kozlowski
Add the '#mux-state-cells' property to support describing the USB VBUS_SEL
multiplexer as a mux-controller in the Renesas RZ/V2H(P) USB2PHY binding.
The mux-controller cannot be integrated into the parent USB2PHY node
because the VBUS source selector is part of a separate hardware block,
not the USB2PHY block itself.
This is required to properly configure USB PHY power selection on
RZ/V2H(P) and RZ/G3E SoCs.
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
v9->v10:
- No changes
v8->v9:
- No changes
v7->v8:
- No changes
v6->v7:
- No changes
v5->v6:
- Collected KKrzysztof tag
v4->v5:
- No changes
v3->v4:
- Switch back to v2 implementation.
- Improve commit body.
v2->v3:
- Manipulate mux-controller as an internal node.
- Improved commit body.
v1->v2:
- New patch
.../bindings/reset/renesas,rzv2h-usb2phy-reset.yaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml b/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml
index c1b800a10b53..7ed0980b9ee1 100644
--- a/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml
+++ b/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml
@@ -37,6 +37,9 @@ properties:
'#reset-cells':
const: 0
+ '#mux-state-cells':
+ const: 1
+
required:
- compatible
- reg
@@ -44,6 +47,7 @@ required:
- resets
- power-domains
- '#reset-cells'
+ - '#mux-state-cells'
additionalProperties: false
@@ -58,4 +62,5 @@ examples:
resets = <&cpg 0xaf>;
power-domains = <&cpg>;
#reset-cells = <0>;
+ #mux-state-cells = <1>;
};
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v10 3/5] dt-bindings: reset: renesas,rzv2h-usb2phy: Document RZ/G3E USB2PHY reset
2026-04-01 15:16 [PATCH v10 0/5] Add USB2.0 VBUS mux driver and extend rzv2h-usb2phy reset for RZ/G3E support Tommaso Merciai
2026-04-01 15:16 ` [PATCH v10 1/5] mux: Add driver for Renesas RZ/V2H USB VBENCTL VBUS_SEL mux Tommaso Merciai
2026-04-01 15:16 ` [PATCH v10 2/5] dt-bindings: reset: renesas,rzv2h-usb2phy: Add '#mux-state-cells' property Tommaso Merciai
@ 2026-04-01 15:16 ` Tommaso Merciai
2026-04-01 15:16 ` [PATCH v10 4/5] reset: rzv2h-usb2phy: Convert to regmap API Tommaso Merciai
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Tommaso Merciai @ 2026-04-01 15:16 UTC (permalink / raw)
To: tomm.merciai, peda, p.zabel
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, Fabrizio Castro,
Lad Prabhakar, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Arnd Bergmann, Ulf Hansson,
Josua Mayer, devicetree, linux-kernel, Conor Dooley
Document USB2PHY reset controller bindings for RZ/G3E ("R9A09G047") SoC.
The RZ/G3E USB2PHY reset controller is functionally identical to the one
found on the RZ/V2H(P), so no driver changes are needed. The existing
"renesas,r9a09g057-usb2phy-reset" will be used as a fallback compatible
for this IP.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
v9->v10:
- No changes
v8->v9:
- No changes
v7->v8:
- No changes
v6->v7:
- No changes
v5->v6:
- Fixed commit msg
v4->v5:
- No changes
v3->v4:
- No changes
v2->v3:
- No changes
v1->v2:
- Collected CDooley tag
.../bindings/reset/renesas,rzv2h-usb2phy-reset.yaml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml b/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml
index 7ed0980b9ee1..66650ef8f772 100644
--- a/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml
+++ b/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml
@@ -17,7 +17,9 @@ properties:
compatible:
oneOf:
- items:
- - const: renesas,r9a09g056-usb2phy-reset # RZ/V2N
+ - enum:
+ - renesas,r9a09g047-usb2phy-reset # RZ/G3E
+ - renesas,r9a09g056-usb2phy-reset # RZ/V2N
- const: renesas,r9a09g057-usb2phy-reset
- const: renesas,r9a09g057-usb2phy-reset # RZ/V2H(P)
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v10 4/5] reset: rzv2h-usb2phy: Convert to regmap API
2026-04-01 15:16 [PATCH v10 0/5] Add USB2.0 VBUS mux driver and extend rzv2h-usb2phy reset for RZ/G3E support Tommaso Merciai
` (2 preceding siblings ...)
2026-04-01 15:16 ` [PATCH v10 3/5] dt-bindings: reset: renesas,rzv2h-usb2phy: Document RZ/G3E USB2PHY reset Tommaso Merciai
@ 2026-04-01 15:16 ` Tommaso Merciai
2026-04-02 12:34 ` Philipp Zabel
2026-04-01 15:16 ` [PATCH v10 5/5] reset: rzv2h-usb2phy: Add support for VBUS mux controller registration Tommaso Merciai
2026-04-02 12:35 ` [PATCH v10 0/5] Add USB2.0 VBUS mux driver and extend rzv2h-usb2phy reset for RZ/G3E support Philipp Zabel
5 siblings, 1 reply; 8+ messages in thread
From: Tommaso Merciai @ 2026-04-01 15:16 UTC (permalink / raw)
To: tomm.merciai, peda, p.zabel
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, Fabrizio Castro,
Lad Prabhakar, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Arnd Bergmann, Ulf Hansson,
Josua Mayer, devicetree, linux-kernel
Replace raw MMIO accesses (readl/writel) with regmap_read() and
regmap_multi_reg_write() via devm_regmap_init_mmio().
Drop the manual spinlock as regmap provides internal locking.
Replace the custom rzv2h_usb2phy_regval struct with the standard
reg_sequence, and encode assert/deassert sequences as reg_sequence
arrays rather than individual scalar fields in the of_data
descriptor.
Use the reg_sequence .delay_us field to encode the 11 µs post-assert
delay, replacing the explicit usleep_range(11, 20) call in
rzv2h_usbphy_reset_assert().
Select REGMAP_MMIO in Kconfig.
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
v9->v10:
- Use struct reg_sequence and regmap_multi_reg_write() to handle
initialization, assert and deassert sequences and drop custom struct
rzv2h_usb2phy_regval.
v8->v9:
- New patch
drivers/reset/Kconfig | 1 +
drivers/reset/reset-rzv2h-usb2phy.c | 108 ++++++++++++++--------------
2 files changed, 55 insertions(+), 54 deletions(-)
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 5165006be693..c539ca88518f 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -257,6 +257,7 @@ config RESET_RZG2L_USBPHY_CTRL
config RESET_RZV2H_USB2PHY
tristate "Renesas RZ/V2H(P) (and similar SoCs) USB2PHY Reset driver"
depends on ARCH_RENESAS || COMPILE_TEST
+ select REGMAP_MMIO
help
Support for USB2PHY Port reset Control found on the RZ/V2H(P) SoC
(and similar SoCs).
diff --git a/drivers/reset/reset-rzv2h-usb2phy.c b/drivers/reset/reset-rzv2h-usb2phy.c
index 5bdd39274612..c79bf72602e8 100644
--- a/drivers/reset/reset-rzv2h-usb2phy.c
+++ b/drivers/reset/reset-rzv2h-usb2phy.c
@@ -5,42 +5,35 @@
* Copyright (C) 2025 Renesas Electronics Corporation
*/
-#include <linux/cleanup.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/reset-controller.h>
-struct rzv2h_usb2phy_regval {
- u16 reg;
- u16 val;
-};
-
struct rzv2h_usb2phy_reset_of_data {
- const struct rzv2h_usb2phy_regval *init_vals;
- unsigned int init_val_count;
+ const struct reg_sequence *init_seq;
+ unsigned int init_nseq;
+
+ const struct reg_sequence *assert_seq;
+ unsigned int assert_nseq;
+
+ const struct reg_sequence *deassert_seq;
+ unsigned int deassert_nseq;
u16 reset_reg;
- u16 reset_assert_val;
- u16 reset_deassert_val;
u16 reset_status_bits;
- u16 reset_release_val;
-
- u16 reset2_reg;
- u16 reset2_acquire_val;
- u16 reset2_release_val;
};
struct rzv2h_usb2phy_reset_priv {
const struct rzv2h_usb2phy_reset_of_data *data;
- void __iomem *base;
+ struct regmap *regmap;
struct device *dev;
struct reset_controller_dev rcdev;
- spinlock_t lock; /* protects register accesses */
};
static inline struct rzv2h_usb2phy_reset_priv
@@ -53,31 +46,18 @@ static int rzv2h_usbphy_reset_assert(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct rzv2h_usb2phy_reset_priv *priv = rzv2h_usbphy_rcdev_to_priv(rcdev);
- const struct rzv2h_usb2phy_reset_of_data *data = priv->data;
- scoped_guard(spinlock, &priv->lock) {
- writel(data->reset2_acquire_val, priv->base + data->reset2_reg);
- writel(data->reset_assert_val, priv->base + data->reset_reg);
- }
-
- usleep_range(11, 20);
-
- return 0;
+ return regmap_multi_reg_write(priv->regmap, priv->data->assert_seq,
+ priv->data->assert_nseq);
}
static int rzv2h_usbphy_reset_deassert(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct rzv2h_usb2phy_reset_priv *priv = rzv2h_usbphy_rcdev_to_priv(rcdev);
- const struct rzv2h_usb2phy_reset_of_data *data = priv->data;
- scoped_guard(spinlock, &priv->lock) {
- writel(data->reset_deassert_val, priv->base + data->reset_reg);
- writel(data->reset2_release_val, priv->base + data->reset2_reg);
- writel(data->reset_release_val, priv->base + data->reset_reg);
- }
-
- return 0;
+ return regmap_multi_reg_write(priv->regmap, priv->data->deassert_seq,
+ priv->data->deassert_nseq);
}
static int rzv2h_usbphy_reset_status(struct reset_controller_dev *rcdev,
@@ -86,7 +66,7 @@ static int rzv2h_usbphy_reset_status(struct reset_controller_dev *rcdev,
struct rzv2h_usb2phy_reset_priv *priv = rzv2h_usbphy_rcdev_to_priv(rcdev);
u32 reg;
- reg = readl(priv->base + priv->data->reset_reg);
+ regmap_read(priv->regmap, priv->data->reset_reg, ®);
return (reg & priv->data->reset_status_bits) == priv->data->reset_status_bits;
}
@@ -104,6 +84,13 @@ static int rzv2h_usb2phy_reset_of_xlate(struct reset_controller_dev *rcdev,
return 0;
}
+static const struct regmap_config rzv2h_usb2phy_reset_regconf = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .can_sleep = true,
+};
+
static void rzv2h_usb2phy_reset_pm_runtime_put(void *data)
{
pm_runtime_put(data);
@@ -115,6 +102,7 @@ static int rzv2h_usb2phy_reset_probe(struct platform_device *pdev)
struct rzv2h_usb2phy_reset_priv *priv;
struct device *dev = &pdev->dev;
struct reset_control *rstc;
+ void __iomem *base;
int error;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -124,17 +112,19 @@ static int rzv2h_usb2phy_reset_probe(struct platform_device *pdev)
data = of_device_get_match_data(dev);
priv->data = data;
priv->dev = dev;
- priv->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(priv->base))
- return PTR_ERR(priv->base);
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ priv->regmap = devm_regmap_init_mmio(dev, base, &rzv2h_usb2phy_reset_regconf);
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
rstc = devm_reset_control_get_shared_deasserted(dev, NULL);
if (IS_ERR(rstc))
return dev_err_probe(dev, PTR_ERR(rstc),
"failed to get deasserted reset\n");
- spin_lock_init(&priv->lock);
-
error = devm_pm_runtime_enable(dev);
if (error)
return dev_err_probe(dev, error, "Failed to enable pm_runtime\n");
@@ -148,8 +138,9 @@ static int rzv2h_usb2phy_reset_probe(struct platform_device *pdev)
if (error)
return dev_err_probe(dev, error, "unable to register cleanup action\n");
- for (unsigned int i = 0; i < data->init_val_count; i++)
- writel(data->init_vals[i].val, priv->base + data->init_vals[i].reg);
+ error = regmap_multi_reg_write(priv->regmap, data->init_seq, data->init_nseq);
+ if (error)
+ return dev_err_probe(dev, error, "failed to initialize PHY registers\n");
priv->rcdev.ops = &rzv2h_usbphy_reset_ops;
priv->rcdev.of_reset_n_cells = 0;
@@ -169,23 +160,32 @@ static int rzv2h_usb2phy_reset_probe(struct platform_device *pdev)
* initialization values required to prepare the PHY to receive
* assert and deassert requests.
*/
-static const struct rzv2h_usb2phy_regval rzv2h_init_vals[] = {
- { .reg = 0xc10, .val = 0x67c },
- { .reg = 0xc14, .val = 0x1f },
- { .reg = 0x600, .val = 0x909 },
+static const struct reg_sequence rzv2h_init_seq[] = {
+ { .reg = 0xc10, .def = 0x67c },
+ { .reg = 0xc14, .def = 0x01f },
+ { .reg = 0x600, .def = 0x909 },
+};
+
+static const struct reg_sequence rzv2h_assert_seq[] = {
+ { .reg = 0xb04, .def = 0x303 },
+ { .reg = 0x000, .def = 0x206, .delay_us = 11 },
+};
+
+static const struct reg_sequence rzv2h_deassert_seq[] = {
+ { .reg = 0x000, .def = 0x200 },
+ { .reg = 0xb04, .def = 0x003 },
+ { .reg = 0x000, .def = 0x000 },
};
static const struct rzv2h_usb2phy_reset_of_data rzv2h_reset_of_data = {
- .init_vals = rzv2h_init_vals,
- .init_val_count = ARRAY_SIZE(rzv2h_init_vals),
+ .init_seq = rzv2h_init_seq,
+ .init_nseq = ARRAY_SIZE(rzv2h_init_seq),
+ .assert_seq = rzv2h_assert_seq,
+ .assert_nseq = ARRAY_SIZE(rzv2h_assert_seq),
+ .deassert_seq = rzv2h_deassert_seq,
+ .deassert_nseq = ARRAY_SIZE(rzv2h_deassert_seq),
.reset_reg = 0,
- .reset_assert_val = 0x206,
.reset_status_bits = BIT(2),
- .reset_deassert_val = 0x200,
- .reset_release_val = 0x0,
- .reset2_reg = 0xb04,
- .reset2_acquire_val = 0x303,
- .reset2_release_val = 0x3,
};
static const struct of_device_id rzv2h_usb2phy_reset_of_match[] = {
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH v10 4/5] reset: rzv2h-usb2phy: Convert to regmap API
2026-04-01 15:16 ` [PATCH v10 4/5] reset: rzv2h-usb2phy: Convert to regmap API Tommaso Merciai
@ 2026-04-02 12:34 ` Philipp Zabel
0 siblings, 0 replies; 8+ messages in thread
From: Philipp Zabel @ 2026-04-02 12:34 UTC (permalink / raw)
To: Tommaso Merciai, tomm.merciai, peda
Cc: linux-renesas-soc, biju.das.jz, Fabrizio Castro, Lad Prabhakar,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Arnd Bergmann, Ulf Hansson,
Josua Mayer, devicetree, linux-kernel
On Mi, 2026-04-01 at 17:16 +0200, Tommaso Merciai wrote:
> Replace raw MMIO accesses (readl/writel) with regmap_read() and
> regmap_multi_reg_write() via devm_regmap_init_mmio().
> Drop the manual spinlock as regmap provides internal locking.
>
> Replace the custom rzv2h_usb2phy_regval struct with the standard
> reg_sequence, and encode assert/deassert sequences as reg_sequence
> arrays rather than individual scalar fields in the of_data
> descriptor.
>
> Use the reg_sequence .delay_us field to encode the 11 µs post-assert
> delay, replacing the explicit usleep_range(11, 20) call in
> rzv2h_usbphy_reset_assert().
>
> Select REGMAP_MMIO in Kconfig.
>
> Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
regards
Philipp
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v10 5/5] reset: rzv2h-usb2phy: Add support for VBUS mux controller registration
2026-04-01 15:16 [PATCH v10 0/5] Add USB2.0 VBUS mux driver and extend rzv2h-usb2phy reset for RZ/G3E support Tommaso Merciai
` (3 preceding siblings ...)
2026-04-01 15:16 ` [PATCH v10 4/5] reset: rzv2h-usb2phy: Convert to regmap API Tommaso Merciai
@ 2026-04-01 15:16 ` Tommaso Merciai
2026-04-02 12:35 ` [PATCH v10 0/5] Add USB2.0 VBUS mux driver and extend rzv2h-usb2phy reset for RZ/G3E support Philipp Zabel
5 siblings, 0 replies; 8+ messages in thread
From: Tommaso Merciai @ 2026-04-01 15:16 UTC (permalink / raw)
To: tomm.merciai, peda, p.zabel
Cc: linux-renesas-soc, biju.das.jz, Tommaso Merciai, Fabrizio Castro,
Lad Prabhakar, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Arnd Bergmann, Ulf Hansson,
Josua Mayer, devicetree, linux-kernel
The RZ/V2H USB2 PHY requires control of the VBUS selection line
(VBENCTL) through a mux controller described in the device tree as
"mux-controller". This change adds support for registering the
rzv2h-usb-vbenctl auxiliary driver during probe.
This enables proper management of USB2.0 VBUS source selection on
platforms using the RZ/V2H SoC.
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
v9->v10:
- No changes.
v8->v9:
- Drop linux/reset/reset_rzv2h_usb2phy.h dependecy as the driver
is now based on regmap and does not need the reset driver's
private header, update driver accordingly.
- Collected PZabel tag.
v7->v8:
- No changes
v6->v7:
- No changes
v5->v6:
- No changes
v4->v5:
- Update mux_name to "vbenctl" to match the driver name.
- Updated commit message.
v3->v4:
- No changes.
v2->v3:
- Use __devm_auxiliary_device_create() to create the auxiliary device.
v1->v2:
- New patch
drivers/reset/Kconfig | 1 +
drivers/reset/reset-rzv2h-usb2phy.c | 35 +++++++++++++++++++++++++++++
2 files changed, 36 insertions(+)
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index c539ca88518f..62b2c3919613 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -257,6 +257,7 @@ config RESET_RZG2L_USBPHY_CTRL
config RESET_RZV2H_USB2PHY
tristate "Renesas RZ/V2H(P) (and similar SoCs) USB2PHY Reset driver"
depends on ARCH_RENESAS || COMPILE_TEST
+ select AUXILIARY_BUS
select REGMAP_MMIO
help
Support for USB2PHY Port reset Control found on the RZ/V2H(P) SoC
diff --git a/drivers/reset/reset-rzv2h-usb2phy.c b/drivers/reset/reset-rzv2h-usb2phy.c
index c79bf72602e8..d96042e28cd5 100644
--- a/drivers/reset/reset-rzv2h-usb2phy.c
+++ b/drivers/reset/reset-rzv2h-usb2phy.c
@@ -5,7 +5,9 @@
* Copyright (C) 2025 Renesas Electronics Corporation
*/
+#include <linux/auxiliary_bus.h>
#include <linux/delay.h>
+#include <linux/idr.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -15,6 +17,8 @@
#include <linux/reset.h>
#include <linux/reset-controller.h>
+static DEFINE_IDA(auxiliary_ids);
+
struct rzv2h_usb2phy_reset_of_data {
const struct reg_sequence *init_seq;
unsigned int init_nseq;
@@ -84,6 +88,33 @@ static int rzv2h_usb2phy_reset_of_xlate(struct reset_controller_dev *rcdev,
return 0;
}
+static void rzv2h_usb2phy_reset_ida_free(void *data)
+{
+ struct auxiliary_device *adev = data;
+
+ ida_free(&auxiliary_ids, adev->id);
+}
+
+static int rzv2h_usb2phy_reset_mux_register(struct device *dev,
+ const char *mux_name)
+{
+ struct auxiliary_device *adev;
+ int id;
+
+ id = ida_alloc(&auxiliary_ids, GFP_KERNEL);
+ if (id < 0)
+ return id;
+
+ adev = __devm_auxiliary_device_create(dev, dev->driver->name,
+ mux_name, NULL, id);
+ if (!adev) {
+ ida_free(&auxiliary_ids, id);
+ return -ENOMEM;
+ }
+
+ return devm_add_action_or_reset(dev, rzv2h_usb2phy_reset_ida_free, adev);
+}
+
static const struct regmap_config rzv2h_usb2phy_reset_regconf = {
.reg_bits = 32,
.val_bits = 32,
@@ -153,6 +184,10 @@ static int rzv2h_usb2phy_reset_probe(struct platform_device *pdev)
if (error)
return dev_err_probe(dev, error, "could not register reset controller\n");
+ error = rzv2h_usb2phy_reset_mux_register(dev, "vbenctl");
+ if (error)
+ return dev_err_probe(dev, error, "could not register aux mux\n");
+
return 0;
}
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH v10 0/5] Add USB2.0 VBUS mux driver and extend rzv2h-usb2phy reset for RZ/G3E support
2026-04-01 15:16 [PATCH v10 0/5] Add USB2.0 VBUS mux driver and extend rzv2h-usb2phy reset for RZ/G3E support Tommaso Merciai
` (4 preceding siblings ...)
2026-04-01 15:16 ` [PATCH v10 5/5] reset: rzv2h-usb2phy: Add support for VBUS mux controller registration Tommaso Merciai
@ 2026-04-02 12:35 ` Philipp Zabel
5 siblings, 0 replies; 8+ messages in thread
From: Philipp Zabel @ 2026-04-02 12:35 UTC (permalink / raw)
To: Tommaso Merciai, tomm.merciai, peda
Cc: linux-renesas-soc, biju.das.jz, Fabrizio Castro, Lad Prabhakar,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Arnd Bergmann, Ulf Hansson,
Josua Mayer, devicetree, linux-kernel
On Mi, 2026-04-01 at 17:16 +0200, Tommaso Merciai wrote:
> Dear All,
>
> The series adds:
> - A new mux driver for RZ/V2H USB VBENCTL VBUS_SEL
> - Updates to the rzv2h-usb2phy reset driver/bindings to support RZ/G3E.
>
> Merge strategy, if any:
>
> - patches 1/5 can go through the MUX tree
> - patches 2-5/5 can go through the Reset tree
Patches 2-5 applied to reset/next, thanks!
[2/5] dt-bindings: reset: renesas,rzv2h-usb2phy: Add '#mux-state-cells' property
https://git.pengutronix.de/cgit/pza/linux/commit/?id=6a1b6f7e56dc
[3/5] dt-bindings: reset: renesas,rzv2h-usb2phy: Document RZ/G3E USB2PHY reset
https://git.pengutronix.de/cgit/pza/linux/commit/?id=63be00249dd9
[4/5] reset: rzv2h-usb2phy: Convert to regmap API
https://git.pengutronix.de/cgit/pza/linux/commit/?id=890628c8d0f1
[5/5] reset: rzv2h-usb2phy: Add support for VBUS mux controller registration
https://git.pengutronix.de/cgit/pza/linux/commit/?id=f62fcdf8ab82
regards
Philipp
^ permalink raw reply [flat|nested] 8+ messages in thread