[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210105161533.250865-1-marex@denx.de>
Date: Tue, 5 Jan 2021 17:15:33 +0100
From: Marek Vasut <marex@...x.de>
To: netdev@...r.kernel.org
Cc: Marek Vasut <marex@...x.de>, Andrew Lunn <andrew@...n.ch>,
Florian Fainelli <f.fainelli@...il.com>,
"David S . Miller" <davem@...emloft.net>,
Heiner Kallweit <hkallweit1@...il.com>
Subject: [PATCH] [RFC] net: phy: smsc: Add magnetics VIO regulator support
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@...x.de>
Cc: Andrew Lunn <andrew@...n.ch>
Cc: Florian Fainelli <f.fainelli@...il.com>
Cc: David S. Miller <davem@...emloft.net>
Cc: Heiner Kallweit <hkallweit1@...il.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
Powered by blists - more mailing lists