Add support for controlling regulator powering the magnetics. In case the interface is down, it is possible to save considerable power by turning the regulator supplying the magnetics off.
Signed-off-by: Marek Vasut <ma...@denx.de> Cc: Andrew Lunn <and...@lunn.ch> Cc: Florian Fainelli <f.faine...@gmail.com> Cc: David S. Miller <da...@davemloft.net> Cc: Heiner Kallweit <hkallwe...@gmail.com> --- drivers/net/phy/smsc.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index 33372756a451..edc2bd7d8100 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c @@ -20,6 +20,9 @@ #include <linux/of.h> #include <linux/phy.h> #include <linux/netdevice.h> +#include <linux/regulator/of_regulator.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/consumer.h> #include <linux/smscphy.h> /* Vendor-specific PHY Definitions */ @@ -46,6 +49,7 @@ static struct smsc_hw_stat smsc_hw_stats[] = { struct smsc_phy_priv { bool energy_enable; struct clk *refclk; + struct regulator *vddio; }; static int smsc_phy_ack_interrupt(struct phy_device *phydev) @@ -288,6 +292,20 @@ static void smsc_get_stats(struct phy_device *phydev, data[i] = smsc_get_stat(phydev, i); } +static void smsc_link_change_notify(struct phy_device *phydev) +{ + struct smsc_phy_priv *priv = phydev->priv; + + if (!priv->vddio) + return; + + if (phydev->state == PHY_HALTED) + regulator_disable(priv->vddio); + + if (phydev->state == PHY_NOLINK) + regulator_enable(priv->vddio); +} + static void smsc_phy_remove(struct phy_device *phydev) { struct smsc_phy_priv *priv = phydev->priv; @@ -309,6 +327,10 @@ static int smsc_phy_probe(struct phy_device *phydev) priv->energy_enable = true; + priv->vddio = devm_regulator_get_optional(&phydev->mdio.dev, "vddio"); + if (IS_ERR(priv->vddio)) + return PTR_ERR(priv->vddio); + if (of_property_read_bool(of_node, "smsc,disable-energy-detect")) priv->energy_enable = false; @@ -432,7 +454,7 @@ static struct phy_driver smsc_phy_driver[] = { .name = "SMSC LAN8710/LAN8720", /* PHY_BASIC_FEATURES */ - + .link_change_notify = smsc_link_change_notify, .probe = smsc_phy_probe, .remove = smsc_phy_remove, -- 2.29.2