@@ -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 */
/**
@@ -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,
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@toradex.com> --- drivers/net/phy/phy_device.c | 24 ++++++++++++++++++++++++ include/linux/phy.h | 2 ++ 2 files changed, 26 insertions(+)