linux-renesas-soc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] reset: rzg2l-usbphy-ctrl: Add suspend to RAM support
@ 2025-11-06 14:33 Claudiu
  2025-11-06 14:33 ` [PATCH 1/2] reset: rzg2l-usbphy-ctrl: Propagate the return value of regmap_field_update_bits() Claudiu
  2025-11-06 14:33 ` [PATCH 2/2] reset: rzg2l-usbphy-ctrl: Add suspend/resume support Claudiu
  0 siblings, 2 replies; 6+ messages in thread
From: Claudiu @ 2025-11-06 14:33 UTC (permalink / raw)
  To: p.zabel; +Cc: claudiu.beznea, linux-renesas-soc, linux-kernel, Claudiu Beznea

From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>

Hi,

Series adds suspend to RAM support to the rzg2l-usbphy-ctrl driver.
Patch 1/2 is a preparatory change to avoid suppressing any
configuration errors.

Thank you,
Claudiu

Claudiu Beznea (2):
  reset: rzg2l-usbphy-ctrl: Propagate the return value of
    regmap_field_update_bits()
  reset: rzg2l-usbphy-ctrl: Add suspend/resume support

 drivers/reset/reset-rzg2l-usbphy-ctrl.c | 105 +++++++++++++++++++-----
 1 file changed, 86 insertions(+), 19 deletions(-)

-- 
2.43.0


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

* [PATCH 1/2] reset: rzg2l-usbphy-ctrl: Propagate the return value of regmap_field_update_bits()
  2025-11-06 14:33 [PATCH 0/2] reset: rzg2l-usbphy-ctrl: Add suspend to RAM support Claudiu
@ 2025-11-06 14:33 ` Claudiu
  2025-11-07 13:25   ` Philipp Zabel
  2025-11-06 14:33 ` [PATCH 2/2] reset: rzg2l-usbphy-ctrl: Add suspend/resume support Claudiu
  1 sibling, 1 reply; 6+ messages in thread
From: Claudiu @ 2025-11-06 14:33 UTC (permalink / raw)
  To: p.zabel; +Cc: claudiu.beznea, linux-renesas-soc, linux-kernel, Claudiu Beznea

From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>

Propagate the return value of regmap_field_update_bits() to avoid losing
any possible error. With this, the return type of
rzg2l_usbphy_ctrl_set_pwrrdy() was updated accordingly.

Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
---
 drivers/reset/reset-rzg2l-usbphy-ctrl.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
index 4ecb9acb2641..9ce0c1f5d465 100644
--- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c
+++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
@@ -117,13 +117,13 @@ static const struct regmap_config rzg2l_usb_regconf = {
 	.max_register = 1,
 };
 
-static void rzg2l_usbphy_ctrl_set_pwrrdy(struct regmap_field *pwrrdy,
-					 bool power_on)
+static int rzg2l_usbphy_ctrl_set_pwrrdy(struct regmap_field *pwrrdy,
+					bool power_on)
 {
 	u32 val = power_on ? 0 : 1;
 
 	/* The initialization path guarantees that the mask is 1 bit long. */
-	regmap_field_update_bits(pwrrdy, 1, val);
+	return regmap_field_update_bits(pwrrdy, 1, val);
 }
 
 static void rzg2l_usbphy_ctrl_pwrrdy_off(void *data)
@@ -138,6 +138,7 @@ static int rzg2l_usbphy_ctrl_pwrrdy_init(struct device *dev)
 	struct regmap *regmap;
 	const int *data;
 	u32 args[2];
+	int ret;
 
 	data = device_get_match_data(dev);
 	if ((uintptr_t)data != RZG2L_USBPHY_CTRL_PWRRDY)
@@ -161,7 +162,9 @@ static int rzg2l_usbphy_ctrl_pwrrdy_init(struct device *dev)
 	if (IS_ERR(pwrrdy))
 		return PTR_ERR(pwrrdy);
 
-	rzg2l_usbphy_ctrl_set_pwrrdy(pwrrdy, true);
+	ret = rzg2l_usbphy_ctrl_set_pwrrdy(priv->pwrrdy, true);
+	if (ret)
+		return ret;
 
 	return devm_add_action_or_reset(dev, rzg2l_usbphy_ctrl_pwrrdy_off, pwrrdy);
 }
-- 
2.43.0


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

* [PATCH 2/2] reset: rzg2l-usbphy-ctrl: Add suspend/resume support
  2025-11-06 14:33 [PATCH 0/2] reset: rzg2l-usbphy-ctrl: Add suspend to RAM support Claudiu
  2025-11-06 14:33 ` [PATCH 1/2] reset: rzg2l-usbphy-ctrl: Propagate the return value of regmap_field_update_bits() Claudiu
@ 2025-11-06 14:33 ` Claudiu
  2025-11-07 13:50   ` Philipp Zabel
  1 sibling, 1 reply; 6+ messages in thread
From: Claudiu @ 2025-11-06 14:33 UTC (permalink / raw)
  To: p.zabel; +Cc: claudiu.beznea, linux-renesas-soc, linux-kernel, Claudiu Beznea

From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>

The RZ/G2L USBPHY control driver is also used on the RZ/G3S SoC.
The RZ/G3S SoC supports a power-saving mode in which power to most USB
components (including the USBPHY control block) is turned off. Because of
this, the USBPHY control block needs to be reconfigured when returning
from power-saving mode.

Add suspend/resume support to handle runtime suspend/resume of the device,
assert/deassert the reset signal, and reinitialize the USBPHY control
block.

Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
---
 drivers/reset/reset-rzg2l-usbphy-ctrl.c | 94 +++++++++++++++++++++----
 1 file changed, 79 insertions(+), 15 deletions(-)

diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
index 9ce0c1f5d465..8ba65839f6e4 100644
--- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c
+++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
@@ -36,6 +36,7 @@ struct rzg2l_usbphy_ctrl_priv {
 	struct reset_control *rstc;
 	void __iomem *base;
 	struct platform_device *vdev;
+	struct regmap_field *pwrrdy;
 
 	spinlock_t lock;
 };
@@ -92,6 +93,19 @@ static int rzg2l_usbphy_ctrl_status(struct reset_controller_dev *rcdev,
 	return !!(readl(priv->base + RESET) & port_mask);
 }
 
+/* put pll and phy into reset state */
+static void rzg2l_usbphy_ctrl_init(struct rzg2l_usbphy_ctrl_priv *priv)
+{
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	val = readl(priv->base + RESET);
+	val |= RESET_SEL_PLLRESET | RESET_PLLRESET | PHY_RESET_PORT2 | PHY_RESET_PORT1;
+	writel(val, priv->base + RESET);
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
 #define RZG2L_USBPHY_CTRL_PWRRDY	1
 
 static const struct of_device_id rzg2l_usbphy_ctrl_match_table[] = {
@@ -131,9 +145,9 @@ static void rzg2l_usbphy_ctrl_pwrrdy_off(void *data)
 	rzg2l_usbphy_ctrl_set_pwrrdy(data, false);
 }
 
-static int rzg2l_usbphy_ctrl_pwrrdy_init(struct device *dev)
+static int rzg2l_usbphy_ctrl_pwrrdy_init(struct device *dev,
+					 struct rzg2l_usbphy_ctrl_priv *priv)
 {
-	struct regmap_field *pwrrdy;
 	struct reg_field field;
 	struct regmap *regmap;
 	const int *data;
@@ -158,15 +172,15 @@ static int rzg2l_usbphy_ctrl_pwrrdy_init(struct device *dev)
 	field.lsb = __ffs(args[1]);
 	field.msb = __fls(args[1]);
 
-	pwrrdy = devm_regmap_field_alloc(dev, regmap, field);
-	if (IS_ERR(pwrrdy))
-		return PTR_ERR(pwrrdy);
+	priv->pwrrdy = devm_regmap_field_alloc(dev, regmap, field);
+	if (IS_ERR(priv->pwrrdy))
+		return PTR_ERR(priv->pwrrdy);
 
 	ret = rzg2l_usbphy_ctrl_set_pwrrdy(priv->pwrrdy, true);
 	if (ret)
 		return ret;
 
-	return devm_add_action_or_reset(dev, rzg2l_usbphy_ctrl_pwrrdy_off, pwrrdy);
+	return devm_add_action_or_reset(dev, rzg2l_usbphy_ctrl_pwrrdy_off, priv->pwrrdy);
 }
 
 static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev)
@@ -175,9 +189,7 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev)
 	struct rzg2l_usbphy_ctrl_priv *priv;
 	struct platform_device *vdev;
 	struct regmap *regmap;
-	unsigned long flags;
 	int error;
-	u32 val;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
@@ -191,7 +203,7 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev)
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	error = rzg2l_usbphy_ctrl_pwrrdy_init(dev);
+	error = rzg2l_usbphy_ctrl_pwrrdy_init(dev, priv);
 	if (error)
 		return error;
 
@@ -214,12 +226,7 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev)
 		goto err_pm_disable_reset_deassert;
 	}
 
-	/* put pll and phy into reset state */
-	spin_lock_irqsave(&priv->lock, flags);
-	val = readl(priv->base + RESET);
-	val |= RESET_SEL_PLLRESET | RESET_PLLRESET | PHY_RESET_PORT2 | PHY_RESET_PORT1;
-	writel(val, priv->base + RESET);
-	spin_unlock_irqrestore(&priv->lock, flags);
+	rzg2l_usbphy_ctrl_init(priv);
 
 	priv->rcdev.ops = &rzg2l_usbphy_ctrl_reset_ops;
 	priv->rcdev.of_reset_n_cells = 1;
@@ -266,10 +273,67 @@ static void rzg2l_usbphy_ctrl_remove(struct platform_device *pdev)
 	reset_control_assert(priv->rstc);
 }
 
+static int rzg2l_usbphy_ctrl_suspend(struct device *dev)
+{
+	struct rzg2l_usbphy_ctrl_priv *priv = dev_get_drvdata(dev);
+	int ret;
+
+	pm_runtime_put(dev);
+
+	ret = reset_control_assert(priv->rstc);
+	if (ret)
+		goto rpm_resume;
+
+	ret = rzg2l_usbphy_ctrl_set_pwrrdy(priv->pwrrdy, false);
+	if (ret)
+		goto reset_deassert;
+
+	return 0;
+
+reset_deassert:
+	reset_control_deassert(priv->rstc);
+rpm_resume:
+	pm_runtime_resume_and_get(dev);
+	return ret;
+}
+
+static int rzg2l_usbphy_ctrl_resume(struct device *dev)
+{
+	struct rzg2l_usbphy_ctrl_priv *priv = dev_get_drvdata(dev);
+	int ret;
+
+	ret = rzg2l_usbphy_ctrl_set_pwrrdy(priv->pwrrdy, true);
+	if (ret)
+		return ret;
+
+	ret = reset_control_deassert(priv->rstc);
+	if (ret)
+		goto pwrrdy_off;
+
+	ret = pm_runtime_resume_and_get(dev);
+	if (ret)
+		goto reset_assert;
+
+	rzg2l_usbphy_ctrl_init(priv);
+
+	return 0;
+
+reset_assert:
+	reset_control_assert(priv->rstc);
+pwrrdy_off:
+	rzg2l_usbphy_ctrl_set_pwrrdy(priv->pwrrdy, false);
+	return ret;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(rzg2l_usbphy_ctrl_pm_ops,
+				rzg2l_usbphy_ctrl_suspend,
+				rzg2l_usbphy_ctrl_resume);
+
 static struct platform_driver rzg2l_usbphy_ctrl_driver = {
 	.driver = {
 		.name		= "rzg2l_usbphy_ctrl",
 		.of_match_table	= rzg2l_usbphy_ctrl_match_table,
+		.pm		= pm_ptr(&rzg2l_usbphy_ctrl_pm_ops),
 	},
 	.probe	= rzg2l_usbphy_ctrl_probe,
 	.remove = rzg2l_usbphy_ctrl_remove,
-- 
2.43.0


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

* Re: [PATCH 1/2] reset: rzg2l-usbphy-ctrl: Propagate the return value of regmap_field_update_bits()
  2025-11-06 14:33 ` [PATCH 1/2] reset: rzg2l-usbphy-ctrl: Propagate the return value of regmap_field_update_bits() Claudiu
@ 2025-11-07 13:25   ` Philipp Zabel
  0 siblings, 0 replies; 6+ messages in thread
From: Philipp Zabel @ 2025-11-07 13:25 UTC (permalink / raw)
  To: Claudiu; +Cc: linux-renesas-soc, linux-kernel, Claudiu Beznea

On Do, 2025-11-06 at 16:33 +0200, Claudiu wrote:
> From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
> 
> Propagate the return value of regmap_field_update_bits() to avoid losing
> any possible error. With this, the return type of
> rzg2l_usbphy_ctrl_set_pwrrdy() was updated accordingly.
> 
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>

Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>

regards
Philipp

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

* Re: [PATCH 2/2] reset: rzg2l-usbphy-ctrl: Add suspend/resume support
  2025-11-06 14:33 ` [PATCH 2/2] reset: rzg2l-usbphy-ctrl: Add suspend/resume support Claudiu
@ 2025-11-07 13:50   ` Philipp Zabel
  2025-11-07 13:57     ` Claudiu Beznea
  0 siblings, 1 reply; 6+ messages in thread
From: Philipp Zabel @ 2025-11-07 13:50 UTC (permalink / raw)
  To: Claudiu; +Cc: linux-renesas-soc, linux-kernel, Claudiu Beznea

On Do, 2025-11-06 at 16:33 +0200, Claudiu wrote:
> From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
> 
> The RZ/G2L USBPHY control driver is also used on the RZ/G3S SoC.
> The RZ/G3S SoC supports a power-saving mode in which power to most USB
> components (including the USBPHY control block) is turned off. Because of
> this, the USBPHY control block needs to be reconfigured when returning
> from power-saving mode.
> 
> Add suspend/resume support to handle runtime suspend/resume of the device,
> assert/deassert the reset signal, and reinitialize the USBPHY control
> block.
> 
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
> ---
>  drivers/reset/reset-rzg2l-usbphy-ctrl.c | 94 +++++++++++++++++++++----
>  1 file changed, 79 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
> index 9ce0c1f5d465..8ba65839f6e4 100644
> --- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c
> +++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
[...]
> @@ -266,10 +273,67 @@ static void rzg2l_usbphy_ctrl_remove(struct platform_device *pdev)
>  	reset_control_assert(priv->rstc);
>  }
>  
> +static int rzg2l_usbphy_ctrl_suspend(struct device *dev)
> +{
> +	struct rzg2l_usbphy_ctrl_priv *priv = dev_get_drvdata(dev);
> +	int ret;
> +
> +	pm_runtime_put(dev);

Should this be pm_runtime_put_sync(dev)?

> +
> +	ret = reset_control_assert(priv->rstc);
> +	if (ret)
> +		goto rpm_resume;
> +
> +	ret = rzg2l_usbphy_ctrl_set_pwrrdy(priv->pwrrdy, false);

This sets PWRRDY=1, and needs to be set after MSTOP=1,CLK_ON=0,
according to 58128aa88867 ("reset: rzg2l-usbphy-ctrl: Add support for
USB PWRRDY"). I assume MSTOP/CLK_ON refer to the PHY clock in that
description, so the pm_runtime_put() above is required to have taken
effect here.



regards
Philipp

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

* Re: [PATCH 2/2] reset: rzg2l-usbphy-ctrl: Add suspend/resume support
  2025-11-07 13:50   ` Philipp Zabel
@ 2025-11-07 13:57     ` Claudiu Beznea
  0 siblings, 0 replies; 6+ messages in thread
From: Claudiu Beznea @ 2025-11-07 13:57 UTC (permalink / raw)
  To: Philipp Zabel; +Cc: linux-renesas-soc, linux-kernel, Claudiu Beznea

Hi, Philipp,

On 11/7/25 15:50, Philipp Zabel wrote:
> On Do, 2025-11-06 at 16:33 +0200, Claudiu wrote:
>> From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
>>
>> The RZ/G2L USBPHY control driver is also used on the RZ/G3S SoC.
>> The RZ/G3S SoC supports a power-saving mode in which power to most USB
>> components (including the USBPHY control block) is turned off. Because of
>> this, the USBPHY control block needs to be reconfigured when returning
>> from power-saving mode.
>>
>> Add suspend/resume support to handle runtime suspend/resume of the device,
>> assert/deassert the reset signal, and reinitialize the USBPHY control
>> block.
>>
>> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
>> ---
>>  drivers/reset/reset-rzg2l-usbphy-ctrl.c | 94 +++++++++++++++++++++----
>>  1 file changed, 79 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
>> index 9ce0c1f5d465..8ba65839f6e4 100644
>> --- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c
>> +++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
> [...]
>> @@ -266,10 +273,67 @@ static void rzg2l_usbphy_ctrl_remove(struct platform_device *pdev)
>>  	reset_control_assert(priv->rstc);
>>  }
>>  
>> +static int rzg2l_usbphy_ctrl_suspend(struct device *dev)
>> +{
>> +	struct rzg2l_usbphy_ctrl_priv *priv = dev_get_drvdata(dev);
>> +	int ret;
>> +
>> +	pm_runtime_put(dev);
> 
> Should this be pm_runtime_put_sync(dev)?
> 
>> +
>> +	ret = reset_control_assert(priv->rstc);
>> +	if (ret)
>> +		goto rpm_resume;
>> +
>> +	ret = rzg2l_usbphy_ctrl_set_pwrrdy(priv->pwrrdy, false);
> 
> This sets PWRRDY=1, and needs to be set after MSTOP=1,CLK_ON=0,
> according to 58128aa88867 ("reset: rzg2l-usbphy-ctrl: Add support for
> USB PWRRDY"). I assume MSTOP/CLK_ON refer to the PHY clock in that
> description,

It refers to the MSTOP/CLK_ON of the USB block. USB PHY CTRL and USB PHYs
are all part of the USB block.

> so the pm_runtime_put() above is required to have taken
> effect here.

You're right. I'll use pm_runtime_put_sync().

Thank you for your review,
Claudiu

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

end of thread, other threads:[~2025-11-07 13:57 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-06 14:33 [PATCH 0/2] reset: rzg2l-usbphy-ctrl: Add suspend to RAM support Claudiu
2025-11-06 14:33 ` [PATCH 1/2] reset: rzg2l-usbphy-ctrl: Propagate the return value of regmap_field_update_bits() Claudiu
2025-11-07 13:25   ` Philipp Zabel
2025-11-06 14:33 ` [PATCH 2/2] reset: rzg2l-usbphy-ctrl: Add suspend/resume support Claudiu
2025-11-07 13:50   ` Philipp Zabel
2025-11-07 13:57     ` Claudiu Beznea

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).