public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] phy: renesas: phy-rzg3e-usb3: Fix runtime PM underflow during suspend
@ 2026-04-27 19:47 Ovidiu Panait
  2026-04-28  6:17 ` Biju Das
  2026-05-03 16:57 ` Vinod Koul
  0 siblings, 2 replies; 8+ messages in thread
From: Ovidiu Panait @ 2026-04-27 19:47 UTC (permalink / raw)
  To: vkoul, neil.armstrong, biju.das.jz
  Cc: linux-phy, linux-kernel, linux-renesas-soc, Ovidiu Panait

On the Renesas RZ/V2H platform, if the xhcd driver is unbound and the
system is suspended afterwards, a PM underflow error will occur:

 # echo 15850000.usb > /sys/bus/platform/drivers/xhci-renesas-hcd/unbind
 # systemctl suspend
 15870000.usb-phy: PM: dpm_run_callback(): genpd_resume_noirq returns -13
 15870000.usb-phy: PM: failed to resume noirq: error -13
 15870000.usb-phy: Runtime PM usage count underflow!

Since the PHY framework is managing the runtime PM of the PHY via
phy_power_on()/phy_power_off(), there is no need for the PHY driver to
manipulate the runtime PM state during suspend.

To fix this, remove the runtime PM calls from the suspend/resume paths
and add a get/put pair inside rzg3e_phy_usb3_init_helper() to make sure
the clock is enabled during init, even when there is no consumer for
the PHY.

Also, change the suspend ops from NOIRQ_SYSTEM_SLEEP_PM_OPS to
SYSTEM_SLEEP_PM_OPS because runtime PM is disabled during the noirq phase
and pm_runtime_resume_and_get() would not actually enable the device clock.

Fixes: ee5f1a3f90a4 ("phy: renesas: Add Renesas RZ/G3E USB3.0 PHY driver")
Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
---
 drivers/phy/renesas/phy-rzg3e-usb3.c | 31 ++++++++++++++++------------
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/drivers/phy/renesas/phy-rzg3e-usb3.c b/drivers/phy/renesas/phy-rzg3e-usb3.c
index 6b3453ea0004..055775e1a0f7 100644
--- a/drivers/phy/renesas/phy-rzg3e-usb3.c
+++ b/drivers/phy/renesas/phy-rzg3e-usb3.c
@@ -64,6 +64,7 @@
 #define USB3_TEST_LANECONFIG0_DEFAULT		(0xd)
 
 struct rz_usb3 {
+	struct device *dev;
 	void __iomem *base;
 	struct reset_control *rstc;
 	bool skip_reinit;
@@ -130,11 +131,21 @@ static int rzg3e_phy_usb3test_phy_init(void __iomem *base)
 	return 0;
 }
 
-static int rzg3e_phy_usb3_init_helper(void __iomem *base)
+static int rzg3e_phy_usb3_init_helper(struct rz_usb3 *r)
 {
-	rzg3e_phy_usb2test_phy_init(base);
+	int ret;
+
+	ret = pm_runtime_resume_and_get(r->dev);
+	if (ret)
+		return ret;
+
+	rzg3e_phy_usb2test_phy_init(r->base);
 
-	return rzg3e_phy_usb3test_phy_init(base);
+	ret = rzg3e_phy_usb3test_phy_init(r->base);
+
+	pm_runtime_put_sync(r->dev);
+
+	return ret;
 }
 
 static int rzg3e_phy_usb3_init(struct phy *p)
@@ -143,7 +154,7 @@ static int rzg3e_phy_usb3_init(struct phy *p)
 	int ret = 0;
 
 	if (!r->skip_reinit)
-		ret = rzg3e_phy_usb3_init_helper(r->base);
+		ret = rzg3e_phy_usb3_init_helper(r);
 
 	return ret;
 }
@@ -187,6 +198,7 @@ static int rzg3e_phy_usb3_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, r);
 	phy_set_drvdata(phy, r);
+	r->dev = dev;
 
 	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
 	if (IS_ERR(provider))
@@ -199,7 +211,6 @@ static int rzg3e_phy_usb3_suspend(struct device *dev)
 {
 	struct rz_usb3 *r = dev_get_drvdata(dev);
 
-	pm_runtime_put(dev);
 	reset_control_assert(r->rstc);
 	r->skip_reinit = false;
 
@@ -215,27 +226,21 @@ static int rzg3e_phy_usb3_resume(struct device *dev)
 	if (ret)
 		return ret;
 
-	ret = pm_runtime_resume_and_get(dev);
+	ret = rzg3e_phy_usb3_init_helper(r);
 	if (ret)
 		goto reset_assert;
 
-	ret = rzg3e_phy_usb3_init_helper(r->base);
-	if (ret)
-		goto pm_put;
-
 	r->skip_reinit = true;
 
 	return 0;
 
-pm_put:
-	pm_runtime_put(dev);
 reset_assert:
 	reset_control_assert(r->rstc);
 	return ret;
 }
 
 static const struct dev_pm_ops rzg3e_phy_usb3_pm = {
-	NOIRQ_SYSTEM_SLEEP_PM_OPS(rzg3e_phy_usb3_suspend, rzg3e_phy_usb3_resume)
+	SYSTEM_SLEEP_PM_OPS(rzg3e_phy_usb3_suspend, rzg3e_phy_usb3_resume)
 };
 
 static const struct of_device_id rzg3e_phy_usb3_match_table[] = {
-- 
2.34.1


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

end of thread, other threads:[~2026-05-04 12:11 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-27 19:47 [PATCH] phy: renesas: phy-rzg3e-usb3: Fix runtime PM underflow during suspend Ovidiu Panait
2026-04-28  6:17 ` Biju Das
2026-04-28  9:21   ` Ovidiu Panait
2026-04-28  9:38     ` Biju Das
2026-05-03 16:57 ` Vinod Koul
2026-05-04 11:09   ` Ovidiu Panait
2026-05-04 11:44     ` Geert Uytterhoeven
2026-05-04 12:11       ` Ovidiu Panait

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox