[PATCH net-next] net: phy: call phy_init_hw() in phy resume path

Biju posted 1 patch 2 months ago
There is a newer version of this series
drivers/net/phy/phy_device.c | 4 ++++
1 file changed, 4 insertions(+)
[PATCH net-next] net: phy: call phy_init_hw() in phy resume path
Posted by Biju 2 months ago
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
Re: [PATCH net-next] net: phy: call phy_init_hw() in phy resume path
Posted by Russell King (Oracle) 2 months ago
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!
Re: [PATCH net-next] net: phy: call phy_init_hw() in phy resume path
Posted by Florian Fainelli 2 months ago
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
Re: [PATCH net-next] net: phy: call phy_init_hw() in phy resume path
Posted by Andrew Lunn 2 months 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.

Haven't we had deadlocks in this area before?

Please test with CONFIG_PROVE_LOCKING enabled.

       Andrew
Re: [PATCH net-next] net: phy: call phy_init_hw() in phy resume path
Posted by Russell King (Oracle) 2 months ago
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!
Re: [PATCH net-next] net: phy: call phy_init_hw() in phy resume path
Posted by Andrew Lunn 2 months ago
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
Re: [PATCH net-next] net: phy: call phy_init_hw() in phy resume path
Posted by Russell King (Oracle) 2 months ago
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!