From f2c6f8711c3866caafee997cfa60af4f38879be0 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 25 Jun 2025 00:45:11 +0200 Subject: [PATCH 1/2] net: phy: add PHY_DETACH_NO_HW_RESET PHY flag Some PHY require a firmware to correctly work and such firmware might get reset when the GPIO reset is assert. This is the case for the Aeonsemi PHY where when the PHY is torn down, phy_detach() is called that assert the GPIO reset pin resetting the firmware. To handle this introduce a flag, PHY_DETACH_NO_HW_RESET that instruct phy_detach() to skip asserting the GPIO reset on detaching the PHY. The PHY is still reset in all other case where it's removed or the PHY fails to probe. Signed-off-by: Christian Marangi --- drivers/net/phy/as21xxx.c | 10 ++++++++++ drivers/net/phy/phy_device.c | 3 ++- include/linux/phy.h | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) --- a/drivers/net/phy/as21xxx.c +++ b/drivers/net/phy/as21xxx.c @@ -965,6 +965,7 @@ static struct phy_driver as21xxx_drivers .led_hw_control_set = as21xxx_led_hw_control_set, .led_hw_control_get = as21xxx_led_hw_control_get, .led_polarity_set = as21xxx_led_polarity_set, + .flags = PHY_DETACH_NO_RESET, }, { PHY_ID_MATCH_EXACT(PHY_ID_AS21011PB1), @@ -977,6 +978,7 @@ static struct phy_driver as21xxx_drivers .led_hw_control_set = as21xxx_led_hw_control_set, .led_hw_control_get = as21xxx_led_hw_control_get, .led_polarity_set = as21xxx_led_polarity_set, + .flags = PHY_DETACH_NO_RESET, }, { PHY_ID_MATCH_EXACT(PHY_ID_AS21010PB1), @@ -989,6 +991,7 @@ static struct phy_driver as21xxx_drivers .led_hw_control_set = as21xxx_led_hw_control_set, .led_hw_control_get = as21xxx_led_hw_control_get, .led_polarity_set = as21xxx_led_polarity_set, + .flags = PHY_DETACH_NO_RESET, }, { PHY_ID_MATCH_EXACT(PHY_ID_AS21010JB1), @@ -1001,6 +1004,7 @@ static struct phy_driver as21xxx_drivers .led_hw_control_set = as21xxx_led_hw_control_set, .led_hw_control_get = as21xxx_led_hw_control_get, .led_polarity_set = as21xxx_led_polarity_set, + .flags = PHY_DETACH_NO_RESET, }, { PHY_ID_MATCH_EXACT(PHY_ID_AS21210PB1), @@ -1013,6 +1017,7 @@ static struct phy_driver as21xxx_drivers .led_hw_control_set = as21xxx_led_hw_control_set, .led_hw_control_get = as21xxx_led_hw_control_get, .led_polarity_set = as21xxx_led_polarity_set, + .flags = PHY_DETACH_NO_RESET, }, { PHY_ID_MATCH_EXACT(PHY_ID_AS21510JB1), @@ -1025,6 +1030,7 @@ static struct phy_driver as21xxx_drivers .led_hw_control_set = as21xxx_led_hw_control_set, .led_hw_control_get = as21xxx_led_hw_control_get, .led_polarity_set = as21xxx_led_polarity_set, + .flags = PHY_DETACH_NO_RESET, }, { PHY_ID_MATCH_EXACT(PHY_ID_AS21510PB1), @@ -1037,6 +1043,7 @@ static struct phy_driver as21xxx_drivers .led_hw_control_set = as21xxx_led_hw_control_set, .led_hw_control_get = as21xxx_led_hw_control_get, .led_polarity_set = as21xxx_led_polarity_set, + .flags = PHY_DETACH_NO_RESET, }, { PHY_ID_MATCH_EXACT(PHY_ID_AS21511JB1), @@ -1049,6 +1056,7 @@ static struct phy_driver as21xxx_drivers .led_hw_control_set = as21xxx_led_hw_control_set, .led_hw_control_get = as21xxx_led_hw_control_get, .led_polarity_set = as21xxx_led_polarity_set, + .flags = PHY_DETACH_NO_RESET, }, { PHY_ID_MATCH_EXACT(PHY_ID_AS21210JB1), @@ -1061,6 +1069,7 @@ static struct phy_driver as21xxx_drivers .led_hw_control_set = as21xxx_led_hw_control_set, .led_hw_control_get = as21xxx_led_hw_control_get, .led_polarity_set = as21xxx_led_polarity_set, + .flags = PHY_DETACH_NO_RESET, }, { PHY_ID_MATCH_EXACT(PHY_ID_AS21511PB1), @@ -1073,6 +1082,7 @@ static struct phy_driver as21xxx_drivers .led_hw_control_set = as21xxx_led_hw_control_set, .led_hw_control_get = as21xxx_led_hw_control_get, .led_polarity_set = as21xxx_led_polarity_set, + .flags = PHY_DETACH_NO_RESET, }, }; module_phy_driver(as21xxx_drivers); --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -1882,7 +1882,8 @@ void phy_detach(struct phy_device *phyde } /* Assert the reset signal */ - phy_device_reset(phydev, 1); + if (!phydev->drv || !(phydev->drv->flags & PHY_DETACH_NO_HW_RESET)) + phy_device_reset(phydev, 1); /* * The phydev might go away on the put_device() below, so avoid --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -64,6 +64,7 @@ extern const int phy_basic_ports_array[3 #define PHY_RST_AFTER_CLK_EN 0x00000002 #define PHY_POLL_CABLE_TEST 0x00000004 #define PHY_ALWAYS_CALL_SUSPEND 0x00000008 +#define PHY_DETACH_NO_HW_RESET 0x00000010 #define MDIO_DEVICE_IS_PHY 0x80000000 /**