drivers/net/phy/phy_device.c | 4 ++++ 1 file changed, 4 insertions(+)
From: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
When mac_managed_pm flag is set, mdio_bus_phy_resume() is skipped, so
phy_init_hw(), which performs soft_reset and config_init, is not called
during resume.
This is inconsistent with the non-mac_managed_pm path, where
mdio_bus_phy_resume() calls phy_init_hw() before phy_resume() on every
resume.
To align both paths, add a phy_init_hw() call at the top of
__phy_resume(), before invoking the driver's resume callback. This
guarantees the PHY undergoes soft reset and re-initialization regardless
of whether PM is managed by the MAC or the MDIO bus.
Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
drivers/net/phy/phy_device.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 0edff47478c2..8255f4208d66 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -2008,6 +2008,10 @@ int __phy_resume(struct phy_device *phydev)
if (!phydrv || !phydrv->resume)
return 0;
+ ret = phy_init_hw(phydev);
+ if (ret)
+ return ret;
+
ret = phydrv->resume(phydev);
if (!ret)
phydev->suspended = false;
--
2.43.0
On Fri, Apr 10, 2026 at 03:29:01PM +0100, Biju wrote: > From: Ovidiu Panait <ovidiu.panait.rb@renesas.com> > > When mac_managed_pm flag is set, mdio_bus_phy_resume() is skipped, so > phy_init_hw(), which performs soft_reset and config_init, is not called > during resume. > > This is inconsistent with the non-mac_managed_pm path, where > mdio_bus_phy_resume() calls phy_init_hw() before phy_resume() on every > resume. > > To align both paths, add a phy_init_hw() call at the top of > __phy_resume(), before invoking the driver's resume callback. This > guarantees the PHY undergoes soft reset and re-initialization regardless > of whether PM is managed by the MAC or the MDIO bus. > > Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com> > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> > --- > drivers/net/phy/phy_device.c | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c > index 0edff47478c2..8255f4208d66 100644 > --- a/drivers/net/phy/phy_device.c > +++ b/drivers/net/phy/phy_device.c > @@ -2008,6 +2008,10 @@ int __phy_resume(struct phy_device *phydev) > if (!phydrv || !phydrv->resume) > return 0; > > + ret = phy_init_hw(phydev); > + if (ret) > + return ret; Do we want to do this even when phydrv->resume is NULL? Apart from that, looks fine to me - it seems some paths call phy_init_hw() can be called with or without phydev->lock held, and this one will call it with the lock held which seems to be okay. -- RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
On 4/10/26 07:51, Russell King (Oracle) wrote: > On Fri, Apr 10, 2026 at 03:29:01PM +0100, Biju wrote: >> From: Ovidiu Panait <ovidiu.panait.rb@renesas.com> >> >> When mac_managed_pm flag is set, mdio_bus_phy_resume() is skipped, so >> phy_init_hw(), which performs soft_reset and config_init, is not called >> during resume. >> >> This is inconsistent with the non-mac_managed_pm path, where >> mdio_bus_phy_resume() calls phy_init_hw() before phy_resume() on every >> resume. >> >> To align both paths, add a phy_init_hw() call at the top of >> __phy_resume(), before invoking the driver's resume callback. This >> guarantees the PHY undergoes soft reset and re-initialization regardless >> of whether PM is managed by the MAC or the MDIO bus. >> >> Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com> >> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> >> --- >> drivers/net/phy/phy_device.c | 4 ++++ >> 1 file changed, 4 insertions(+) >> >> diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c >> index 0edff47478c2..8255f4208d66 100644 >> --- a/drivers/net/phy/phy_device.c >> +++ b/drivers/net/phy/phy_device.c >> @@ -2008,6 +2008,10 @@ int __phy_resume(struct phy_device *phydev) >> if (!phydrv || !phydrv->resume) >> return 0; >> >> + ret = phy_init_hw(phydev); >> + if (ret) >> + return ret; > > Do we want to do this even when phydrv->resume is NULL? Seems to me we would want that, but this gets into the territory of potentially creating many soft-reset of the PHYs, something that I regret having introduced years ago. > > Apart from that, looks fine to me - it seems some paths call > phy_init_hw() can be called with or without phydev->lock held, and > this one will call it with the lock held which seems to be okay. > Agreed. -- Florian
> Apart from that, looks fine to me - it seems some paths call
> phy_init_hw() can be called with or without phydev->lock held, and
> this one will call it with the lock held which seems to be okay.
Haven't we had deadlocks in this area before?
Please test with CONFIG_PROVE_LOCKING enabled.
Andrew
On Fri, Apr 10, 2026 at 05:15:21PM +0200, Andrew Lunn wrote:
> > Apart from that, looks fine to me - it seems some paths call
> > phy_init_hw() can be called with or without phydev->lock held, and
> > this one will call it with the lock held which seems to be okay.
>
> Haven't we had deadlocks in this area before?
If we have a problem calling phy_init_hw() with phydev->lock held, then:
phy_state_machine():
mutex_lock(&phydev->lock);
state_work = _phy_state_machine(phydev);
_phy_state_machine():
switch (phydev->state) {
...
case PHY_CABLETEST:
err = phydev->drv->cable_test_get_status(phydev, &finished);
if (err) {
phy_abort_cable_test(phydev);
phy_abort_cable_test():
err = phy_init_hw(phydev);
that path has a problem and needs fixing.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
On Fri, Apr 10, 2026 at 04:22:23PM +0100, Russell King (Oracle) wrote: > On Fri, Apr 10, 2026 at 05:15:21PM +0200, Andrew Lunn wrote: > > > Apart from that, looks fine to me - it seems some paths call > > > phy_init_hw() can be called with or without phydev->lock held, and > > > this one will call it with the lock held which seems to be okay. > > > > Haven't we had deadlocks in this area before? > > If we have a problem calling phy_init_hw() with phydev->lock held, then: I thought it was an AB-BA with RTNL? Lets see what PROVE_LOCKING actually says. I could be remembering wrongly. Andrew
On Fri, Apr 10, 2026 at 03:51:18PM +0100, Russell King (Oracle) wrote: > On Fri, Apr 10, 2026 at 03:29:01PM +0100, Biju wrote: > > From: Ovidiu Panait <ovidiu.panait.rb@renesas.com> > > > > When mac_managed_pm flag is set, mdio_bus_phy_resume() is skipped, so > > phy_init_hw(), which performs soft_reset and config_init, is not called > > during resume. > > > > This is inconsistent with the non-mac_managed_pm path, where > > mdio_bus_phy_resume() calls phy_init_hw() before phy_resume() on every > > resume. > > > > To align both paths, add a phy_init_hw() call at the top of > > __phy_resume(), before invoking the driver's resume callback. This > > guarantees the PHY undergoes soft reset and re-initialization regardless > > of whether PM is managed by the MAC or the MDIO bus. > > > > Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com> > > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> > > --- > > drivers/net/phy/phy_device.c | 4 ++++ > > 1 file changed, 4 insertions(+) > > > > diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c > > index 0edff47478c2..8255f4208d66 100644 > > --- a/drivers/net/phy/phy_device.c > > +++ b/drivers/net/phy/phy_device.c > > @@ -2008,6 +2008,10 @@ int __phy_resume(struct phy_device *phydev) > > if (!phydrv || !phydrv->resume) > > return 0; > > > > + ret = phy_init_hw(phydev); > > + if (ret) > > + return ret; > > Do we want to do this even when phydrv->resume is NULL? I should've also added (sorry, busy packing) - with it always being called even when phydrv->resume is NULL, it means that the call sites to phy_resume() in phylib which are preceeded by a call to phy_init_hw() should have that call removed, otherwise we're going to be calling phy_init_hw() twice. As the patch currently stands, that's the case when phydrv->resume is populated, and I think we should avoid that. > Apart from that, looks fine to me - it seems some paths call > phy_init_hw() can be called with or without phydev->lock held, and > this one will call it with the lock held which seems to be okay. -- RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
© 2016 - 2026 Red Hat, Inc.