[PATCH 14/15] net: phy: add PHY regulator support

From: Bartosz Golaszewski
Date: Mon Jun 22 2020 - 05:41:55 EST


From: Bartosz Golaszewski <bgolaszewski@xxxxxxxxxxxx>

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 <bgolaszewski@xxxxxxxxxxxx>
---
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