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

Biju Das <[email protected]>
Newsgroups org.kernel.vger.linux-renesas-soc,org.kernel.vger.linux-kernel
Message-ID <TY3PR01MB1134615C4D2DBDFAE6407C6FC86A42@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Hi All,

> -----Original Message-----
> From: Biju <[email protected]>
> Sent: 12 August 2026 15:19
> Subject: [PATCH v7 4/9] reset: rzg2l-usbphy-ctrl: Add RZ/G3L support
> 
> From: Biju Das <[email protected]>
> 
> 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 <[email protected]>
> ---
> 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 | 79 +++++++++++++++++++++++--
>  1 file changed, 73 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
> index 79503f6f4b23..f332ef9ef3e5 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,11 +162,16 @@ 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;
> @@ -183,7 +200,43 @@ static int rzg2l_usbphy_ctrl_pwrrdy_init(struct device *dev,
>  	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);
 }

This call is getting duplicated, can be moved to rzg2l_usbphy_ctrl_pwrrdy_init()
to avoid code duplication.

I will send v8 with this change.

Cheers,
Biju

> +
> +static int rzg2l_usbphy_ctrl_pwrrdy_powerseq_init(struct device *dev,
> +						  struct rzg2l_usbphy_ctrl_priv *priv) {
> +	int ret;
> +
> +	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");
> +	}
> +
> +	ret = pwrseq_power_on(priv->pwrseq);
> +	if (ret)
> +		return ret;
> +
> +	return devm_add_action_or_reset(dev, rzg2l_usbphy_ctrl_pwrrdy_off,
> +priv); }
> +
> +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);
> +
> +	return ret;
>  }
> 
>  static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev) @@ -245,7 +298,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 +353,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 +373,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);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	ret = rzg2l_usbphy_ctrl_set_pwrrdy(priv->pwrrdy, true);
>  	if (ret)
>  		return ret;
> @@ -334,6 +399,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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.