Thread (5 messages) flat view 5 messages, 2 authors, 2021-01-05
STALE2044d

[PATCH] [RFC] net: phy: smsc: Add magnetics VIO regulator support

From: Marek Vasut <marex@denx.de>
Date: 2021-01-05 16:16:46
Subsystem: ethernet phy library, networking drivers, the rest · Maintainers: Andrew Lunn, Heiner Kallweit, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

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 <marex@denx.de>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Heiner Kallweit <hkallweit1@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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help