| From 9c2c2e62df3fa30fb13fbeb7512a4eede729383b Mon Sep 17 00:00:00 2001 |
| From: Andrew Lunn <andrew@lunn.ch> |
| Date: Tue, 27 Feb 2018 01:56:06 +0100 |
| Subject: net: phy: Restore phy_resume() locking assumption |
| |
| From: Andrew Lunn <andrew@lunn.ch> |
| |
| commit 9c2c2e62df3fa30fb13fbeb7512a4eede729383b upstream. |
| |
| commit f5e64032a799 ("net: phy: fix resume handling") changes the |
| locking semantics for phy_resume() such that the caller now needs to |
| hold the phy mutex. Not all call sites were adopted to this new |
| semantic, resulting in warnings from the added |
| WARN_ON(!mutex_is_locked(&phydev->lock)). Rather than change the |
| semantics, add a __phy_resume() and restore the old behavior of |
| phy_resume(). |
| |
| Reported-by: Heiner Kallweit <hkallweit1@gmail.com> |
| Fixes: f5e64032a799 ("net: phy: fix resume handling") |
| Signed-off-by: Andrew Lunn <andrew@lunn.ch> |
| Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/net/phy/phy.c | 2 +- |
| drivers/net/phy/phy_device.c | 18 +++++++++++++----- |
| include/linux/phy.h | 1 + |
| 3 files changed, 15 insertions(+), 6 deletions(-) |
| |
| --- a/drivers/net/phy/phy.c |
| +++ b/drivers/net/phy/phy.c |
| @@ -841,7 +841,7 @@ void phy_start(struct phy_device *phydev |
| break; |
| case PHY_HALTED: |
| /* if phy was suspended, bring the physical link up again */ |
| - phy_resume(phydev); |
| + __phy_resume(phydev); |
| |
| /* make sure interrupts are re-enabled for the PHY */ |
| if (phy_interrupt_is_valid(phydev)) { |
| --- a/drivers/net/phy/phy_device.c |
| +++ b/drivers/net/phy/phy_device.c |
| @@ -135,9 +135,7 @@ static int mdio_bus_phy_resume(struct de |
| if (!mdio_bus_phy_may_suspend(phydev)) |
| goto no_resume; |
| |
| - mutex_lock(&phydev->lock); |
| ret = phy_resume(phydev); |
| - mutex_unlock(&phydev->lock); |
| if (ret < 0) |
| return ret; |
| |
| @@ -1028,9 +1026,7 @@ int phy_attach_direct(struct net_device |
| if (err) |
| goto error; |
| |
| - mutex_lock(&phydev->lock); |
| phy_resume(phydev); |
| - mutex_unlock(&phydev->lock); |
| phy_led_triggers_register(phydev); |
| |
| return err; |
| @@ -1156,7 +1152,7 @@ int phy_suspend(struct phy_device *phyde |
| } |
| EXPORT_SYMBOL(phy_suspend); |
| |
| -int phy_resume(struct phy_device *phydev) |
| +int __phy_resume(struct phy_device *phydev) |
| { |
| struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver); |
| int ret = 0; |
| @@ -1173,6 +1169,18 @@ int phy_resume(struct phy_device *phydev |
| |
| return ret; |
| } |
| +EXPORT_SYMBOL(__phy_resume); |
| + |
| +int phy_resume(struct phy_device *phydev) |
| +{ |
| + int ret; |
| + |
| + mutex_lock(&phydev->lock); |
| + ret = __phy_resume(phydev); |
| + mutex_unlock(&phydev->lock); |
| + |
| + return ret; |
| +} |
| EXPORT_SYMBOL(phy_resume); |
| |
| int phy_loopback(struct phy_device *phydev, bool enable) |
| --- a/include/linux/phy.h |
| +++ b/include/linux/phy.h |
| @@ -817,6 +817,7 @@ void phy_device_remove(struct phy_device |
| int phy_init_hw(struct phy_device *phydev); |
| int phy_suspend(struct phy_device *phydev); |
| int phy_resume(struct phy_device *phydev); |
| +int __phy_resume(struct phy_device *phydev); |
| int phy_loopback(struct phy_device *phydev, bool enable); |
| struct phy_device *phy_attach(struct net_device *dev, const char *bus_id, |
| phy_interface_t interface); |