[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20211214121638.138784-2-philippe.schenker@toradex.com>
Date: Tue, 14 Dec 2021 13:16:36 +0100
From: Philippe Schenker <philippe.schenker@...adex.com>
To: netdev@...r.kernel.org, Joakim Zhang <qiangqing.zhang@....com>,
"David S . Miller" <davem@...emloft.net>,
Russell King <linux@...linux.org.uk>,
Andrew Lunn <andrew@...n.ch>
Cc: Heiner Kallweit <hkallweit1@...il.com>,
Francesco Dolcini <francesco.dolcini@...adex.com>,
Jakub Kicinski <kuba@...nel.org>,
Fabio Estevam <festevam@...il.com>,
Fugang Duan <fugang.duan@....com>,
Philippe Schenker <philippe.schenker@...adex.com>,
linux-kernel@...r.kernel.org
Subject: [PATCH net-next 1/3] net: phy: add phy_reset_after_power_on() function
Some PHY requires a reset after being powered on (e.g. KSZ9131), add a
new function and related PHY_RST_AFTER_POWER_ON phy flag to be called
after the PHY regulator is enabled.
Signed-off-by: Philippe Schenker <philippe.schenker@...adex.com>
---
drivers/net/phy/phy_device.c | 24 ++++++++++++++++++++++++
include/linux/phy.h | 2 ++
2 files changed, 26 insertions(+)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 74d8e1dc125f..bad836a7ee01 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1878,6 +1878,30 @@ int phy_reset_after_clk_enable(struct phy_device *phydev)
}
EXPORT_SYMBOL(phy_reset_after_clk_enable);
+/**
+ * phy_reset_after_power_on - perform a PHY reset if needed
+ * @phydev: target phy_device struct
+ *
+ * Description: Some PHYs or hardware design, need a reset after power was
+ * enabled and rely on that software reset. This function evaluates the flags
+ * and perform the reset if it's needed.
+ * Returns < 0 on error, 0 if the phy wasn't reset and 1 if the phy was reset.
+ */
+int phy_reset_after_power_on(struct phy_device *phydev)
+{
+ if (!phydev || !phydev->drv)
+ return -ENODEV;
+
+ if (phydev->drv->flags & PHY_RST_AFTER_POWER_ON) {
+ phy_device_reset(phydev, 1);
+ phy_device_reset(phydev, 0);
+ return 1;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(phy_reset_after_power_on);
+
/* Generic PHY support and helper functions */
/**
diff --git a/include/linux/phy.h b/include/linux/phy.h
index cbf03a5f9cf5..0d88cdc97dbd 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -80,6 +80,7 @@ extern const int phy_10gbit_features_array[1];
#define PHY_IS_INTERNAL 0x00000001
#define PHY_RST_AFTER_CLK_EN 0x00000002
#define PHY_POLL_CABLE_TEST 0x00000004
+#define PHY_RST_AFTER_POWER_ON 0x00000008
#define MDIO_DEVICE_IS_PHY 0x80000000
/**
@@ -1499,6 +1500,7 @@ int phy_speed_up(struct phy_device *phydev);
int phy_restart_aneg(struct phy_device *phydev);
int phy_reset_after_clk_enable(struct phy_device *phydev);
+int phy_reset_after_power_on(struct phy_device *phydev);
#if IS_ENABLED(CONFIG_PHYLIB)
int phy_start_cable_test(struct phy_device *phydev,
--
2.34.1
Powered by blists - more mailing lists