From: Bartosz Golaszewski <bgolaszew...@baylibre.com>

The MDIO sub-system now supports PHY regulators. Let's reuse the code
to extend this support over to the PHY device.

Signed-off-by: Bartosz Golaszewski <bgolaszew...@baylibre.com>
---
 drivers/net/phy/phy_device.c | 49 ++++++++++++++++++++++++++++--------
 include/linux/phy.h          | 10 ++++++++
 2 files changed, 48 insertions(+), 11 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 58923826838b..d755adb748a5 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -827,7 +827,12 @@ int phy_device_register(struct phy_device *phydev)
 
        err = mdiobus_register_device(&phydev->mdio);
        if (err)
-               return err;
+               goto err_out;
+
+       /* Enable the PHY regulator */
+       err = phy_device_power_on(phydev);
+       if (err)
+               goto err_unregister_mdio;
 
        /* Deassert the reset signal */
        phy_device_reset(phydev, 0);
@@ -846,22 +851,25 @@ int phy_device_register(struct phy_device *phydev)
        err = phy_scan_fixups(phydev);
        if (err) {
                phydev_err(phydev, "failed to initialize\n");
-               goto out;
+               goto err_reset;
        }
 
        err = device_add(&phydev->mdio.dev);
        if (err) {
                phydev_err(phydev, "failed to add\n");
-               goto out;
+               goto err_reset;
        }
 
        return 0;
 
- out:
+err_reset:
        /* Assert the reset signal */
        phy_device_reset(phydev, 1);
-
+       /* Disable the PHY regulator */
+       phy_device_power_off(phydev);
+err_unregister_mdio:
        mdiobus_unregister_device(&phydev->mdio);
+err_out:
        return err;
 }
 EXPORT_SYMBOL(phy_device_register);
@@ -883,6 +891,8 @@ void phy_device_remove(struct phy_device *phydev)
 
        /* Assert the reset signal */
        phy_device_reset(phydev, 1);
+       /* Disable the PHY regulator */
+       phy_device_power_off(phydev);
 
        mdiobus_unregister_device(&phydev->mdio);
 }
@@ -1064,6 +1074,11 @@ int phy_init_hw(struct phy_device *phydev)
 {
        int ret = 0;
 
+       /* Enable the PHY regulator */
+       ret = phy_device_power_on(phydev);
+       if (ret)
+               return ret;
+
        /* Deassert the reset signal */
        phy_device_reset(phydev, 0);
 
@@ -1644,6 +1659,8 @@ void phy_detach(struct phy_device *phydev)
 
        /* Assert the reset signal */
        phy_device_reset(phydev, 1);
+       /* Disable the PHY regulator */
+       phy_device_power_off(phydev);
 }
 EXPORT_SYMBOL(phy_detach);
 
@@ -2684,13 +2701,18 @@ static int phy_probe(struct device *dev)
 
        mutex_lock(&phydev->lock);
 
+       /* Enable the PHY regulator */
+       err = phy_device_power_on(phydev);
+       if (err)
+               goto out;
+
        /* Deassert the reset signal */
        phy_device_reset(phydev, 0);
 
        if (phydev->drv->probe) {
                err = phydev->drv->probe(phydev);
                if (err)
-                       goto out;
+                       goto out_reset;
        }
 
        /* Start out supporting everything. Eventually,
@@ -2708,7 +2730,7 @@ static int phy_probe(struct device *dev)
        }
 
        if (err)
-               goto out;
+               goto out_reset;
 
        if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
                               phydev->supported))
@@ -2751,11 +2773,16 @@ static int phy_probe(struct device *dev)
        /* Set the state to READY by default */
        phydev->state = PHY_READY;
 
-out:
-       /* Assert the reset signal */
-       if (err)
-               phy_device_reset(phydev, 1);
+       mutex_unlock(&phydev->lock);
+
+       return 0;
 
+out_reset:
+       /* Assert the reset signal */
+       phy_device_reset(phydev, 1);
+       /* Disable the PHY regulator */
+       phy_device_power_off(phydev);
+out:
        mutex_unlock(&phydev->lock);
 
        return err;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 01d24a934ad1..585ce8db32cf 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1291,6 +1291,16 @@ static inline void phy_device_reset(struct phy_device 
*phydev, int value)
        mdio_device_reset(&phydev->mdio, value);
 }
 
+static inline int phy_device_power_on(struct phy_device *phydev)
+{
+       return mdio_device_power_on(&phydev->mdio);
+}
+
+static inline int phy_device_power_off(struct phy_device *phydev)
+{
+       return mdio_device_power_off(&phydev->mdio);
+}
+
 #define phydev_err(_phydev, format, args...)   \
        dev_err(&_phydev->mdio.dev, format, ##args)
 
-- 
2.26.1

Reply via email to