RE: [PATCH v8 4/5] reset: rzg2l-usbphy-ctrl: Add RZ/G3L support

From: Biju Das

Date: Wed Aug 26 2026 - 06:26:15 EST


Hi All,

> -----Original Message-----
> From: Biju <biju.das.au@xxxxxxxxx>
> Sent: 20 August 2026 10:55
> Subject: [PATCH v8 4/5] reset: rzg2l-usbphy-ctrl: Add RZ/G3L support
>
> From: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
>
> Add the renesas,r9a08g046-usbphy-ctrl compatible string to the OF match table for the RZ/G3L (r9a08g046)
> SoC, using a dedicated rzg3l_info struct with pwrrdy set, similar to RZ/G3S.
>
> The RZ/G3L SoC has 2 OTG controllers compared to one on RZ/G3S, so it uses a separate rzg3l-vbus-
> regulator driver to handle the additional VBUSEN control for port 2. The regulator_name field is used as
> the platform device name passed to platform_device_alloc(), and must exactly match the name the
> corresponding regulator driver registers via its id_table for platform bus matching to succeed.
>
> Signed-off-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
> ---
> v7->v8:
> * Avoided code duplication by moving devm_add_action_or_reset() to
> rzg2l_usbphy_ctrl_pwrrdy_init().
> v6->v7:
> * No change.
> v5->v6:
> * No change.
> v4->v5:
> * Replaced the variable regulator_driver_name->regulator_name in struct
> rzg2l_usbphy_ctrl_info
> * Switched to power sequence consumer for controlling pwrrdy signal.
> * Updated commit description.
> v3->v4:
> * Updated the commit description.
> * Migrated to id_table match using driver_name and reduced the length
> < 24.
> v2->v3:
> * No change.
> v1->v2:
> * No change.
> ---
> drivers/reset/reset-rzg2l-usbphy-ctrl.c | 75 ++++++++++++++++++++++---
> 1 file changed, 67 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
> index 79503f6f4b23..da98776da648 100644
> --- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c
> +++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
> @@ -10,6 +10,7 @@
> #include <linux/of.h>
> #include <linux/platform_device.h>
> #include <linux/pm_runtime.h>
> +#include <linux/pwrseq/consumer.h>
> #include <linux/regmap.h>
> #include <linux/reset.h>
> #include <linux/reset-controller.h>
> @@ -37,11 +38,13 @@ struct rzg2l_usbphy_ctrl_priv {
> void __iomem *base;
> struct platform_device *vdev;
> struct regmap_field *pwrrdy;
> + struct pwrseq_desc *pwrseq;
>
> spinlock_t lock;
> };
>
> struct rzg2l_usbphy_ctrl_info {
> + const char *regulator_name;
> bool pwrrdy;
> };
>
> @@ -110,15 +113,24 @@ static void rzg2l_usbphy_ctrl_init(struct rzg2l_usbphy_ctrl_priv *priv)
> spin_unlock_irqrestore(&priv->lock, flags); }
>
> -static const struct rzg2l_usbphy_ctrl_info rzg2l_info = {};
> +static const struct rzg2l_usbphy_ctrl_info rzg2l_info = {
> + .regulator_name = "rzg2l-vbus-regulator", };
>
> static const struct rzg2l_usbphy_ctrl_info rzg3s_info = {
> + .regulator_name = "rzg2l-vbus-regulator",
> + .pwrrdy = true,
> +};
> +
> +static const struct rzg2l_usbphy_ctrl_info rzg3l_info = {
> + .regulator_name = "rzg3l-vbus-regulator",
> .pwrrdy = true,
> };
>
> static const struct of_device_id rzg2l_usbphy_ctrl_match_table[] = {
> { .compatible = "renesas,rzg2l-usbphy-ctrl", .data = &rzg2l_info },
> { .compatible = "renesas,r9a08g045-usbphy-ctrl", .data = &rzg3s_info },
> + { .compatible = "renesas,r9a08g046-usbphy-ctrl", .data = &rzg3l_info
> +},
> { /* Sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, rzg2l_usbphy_ctrl_match_table); @@ -150,16 +162,20 @@ static int
> rzg2l_usbphy_ctrl_set_pwrrdy(struct regmap_field *pwrrdy,
>
> static void rzg2l_usbphy_ctrl_pwrrdy_off(void *data) {
> - rzg2l_usbphy_ctrl_set_pwrrdy(data, false);
> + struct rzg2l_usbphy_ctrl_priv *priv = data;
> +
> + if (priv->pwrrdy)
> + rzg2l_usbphy_ctrl_set_pwrrdy(priv->pwrrdy, false);
> + else
> + pwrseq_power_off(priv->pwrseq);
> }
>
> -static int rzg2l_usbphy_ctrl_pwrrdy_init(struct device *dev,
> - struct rzg2l_usbphy_ctrl_priv *priv)
> +static int rzg2l_usbphy_ctrl_pwrrdy_syscon_init(struct device *dev,
> + struct rzg2l_usbphy_ctrl_priv *priv)
> {
> struct reg_field field;
> struct regmap *regmap;
> u32 args[2];
> - int ret;
>
> regmap = syscon_regmap_lookup_by_phandle_args(dev->of_node,
> "renesas,sysc-pwrrdy",
> @@ -179,11 +195,40 @@ static int rzg2l_usbphy_ctrl_pwrrdy_init(struct device *dev,
> if (IS_ERR(priv->pwrrdy))
> return PTR_ERR(priv->pwrrdy);
>
> - ret = rzg2l_usbphy_ctrl_set_pwrrdy(priv->pwrrdy, true);
> + return rzg2l_usbphy_ctrl_set_pwrrdy(priv->pwrrdy, true); }
> +
> +static int rzg2l_usbphy_ctrl_pwrrdy_powerseq_init(struct device *dev,
> + struct rzg2l_usbphy_ctrl_priv *priv) {
> + priv->pwrseq = devm_pwrseq_get(dev, "usb-pwrrdy");
> + if (IS_ERR(priv->pwrseq)) {
> + /*
> + * This platform requires a sequencer. If we can't get it, we
> + * must return the error (including -EPROBE_DEFER to wait for
> + * the provider to appear)
> + */
> + return dev_err_probe(dev, PTR_ERR(priv->pwrseq),
> + "Failed to get required power sequencer\n");
> + }
> +
> + return pwrseq_power_on(priv->pwrseq);
> +}
> +
> +static int rzg2l_usbphy_ctrl_pwrrdy_init(struct device *dev,
> + struct rzg2l_usbphy_ctrl_priv *priv) {
> + int ret;
> +
> + if (of_property_present(dev->of_node, "renesas,sysc-pwrrdy"))
> + ret = rzg2l_usbphy_ctrl_pwrrdy_syscon_init(dev, priv);
> + else
> + ret = rzg2l_usbphy_ctrl_pwrrdy_powerseq_init(dev, priv);
> +
> if (ret)
> return ret;
>
> - return devm_add_action_or_reset(dev, rzg2l_usbphy_ctrl_pwrrdy_off, priv->pwrrdy);
> + return devm_add_action_or_reset(dev, rzg2l_usbphy_ctrl_pwrrdy_off,
> +priv);
> }
>
> static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev) @@ -245,7 +290,7 @@ static int
> rzg2l_usbphy_ctrl_probe(struct platform_device *pdev)
> if (error)
> goto err_pm_runtime_put;
>
> - vdev = platform_device_alloc("rzg2l-vbus-regulator", pdev->id);
> + vdev = platform_device_alloc(info->regulator_name, pdev->id);
> if (!vdev) {
> error = -ENOMEM;
> goto err_pm_runtime_put;
> @@ -300,6 +345,12 @@ static int rzg2l_usbphy_ctrl_suspend(struct device *dev)
> if (ret)
> goto reset_deassert;
>
> + if (priv->pwrseq) {
> + ret = pwrseq_power_off(priv->pwrseq);
> + if (ret)
> + goto reset_deassert;
> + }
> +
> return 0;
>
> reset_deassert:
> @@ -314,6 +365,12 @@ static int rzg2l_usbphy_ctrl_resume(struct device *dev)
> struct rzg2l_usbphy_ctrl_priv *priv = dev_get_drvdata(dev);
> int ret;
>
> + if (priv->pwrseq) {
> + ret = pwrseq_power_on(priv->pwrseq);

There is an API change, I will send V9 fixing this.

https://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git/commit/?id=d51fc9d4cd6eb18ac82913d83ecf7bd8c85f71ee

Cheers,
Biju

> + if (ret)
> + return ret;
> + }
> +
> ret = rzg2l_usbphy_ctrl_set_pwrrdy(priv->pwrrdy, true);
> if (ret)
> return ret;
> @@ -334,6 +391,8 @@ static int rzg2l_usbphy_ctrl_resume(struct device *dev)
> reset_control_assert(priv->rstc);
> pwrrdy_off:
> rzg2l_usbphy_ctrl_set_pwrrdy(priv->pwrrdy, false);
> + if (priv->pwrseq)
> + pwrseq_power_off(priv->pwrseq);
> return ret;
> }
>
> --
> 2.43.0