From 6e6fff51ae5e54092611d174fa45fa78c237a415 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Tue, 21 May 2024 20:01:46 +0200 Subject: [PATCH] net: phy: move LED polarity to phy_init_hw Some PHY reset the polarity on reset and this cause the LED to malfunction as LED polarity is configured only when LED is registered. To better handle this, move the LED polarity configuration in phy_init_hw to reconfigure it after PHY reset. Signed-off-by: Christian Marangi --- drivers/net/phy/phy_device.c | 53 +++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 16 deletions(-) --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -1223,6 +1223,37 @@ static int phy_poll_reset(struct phy_dev return 0; } +static int of_phy_led_init(struct phy_device *phydev) +{ + struct phy_led *phyled; + + list_for_each_entry(phyled, &phydev->leds, list) { + struct led_classdev *cdev = &phyled->led_cdev; + struct device_node *np = cdev->dev->of_node; + unsigned long modes = 0; + int err; + + if (of_property_read_bool(np, "active-low")) + set_bit(PHY_LED_ACTIVE_LOW, &modes); + if (of_property_read_bool(np, "inactive-high-impedance")) + set_bit(PHY_LED_INACTIVE_HIGH_IMPEDANCE, &modes); + + if (!modes) + continue; + + /* Return error if asked to set polarity modes but not supported */ + if (!phydev->drv->led_polarity_set) + return -EINVAL; + + err = phydev->drv->led_polarity_set(phydev, phyled->index, + modes); + if (err) + return err; + } + + return 0; +} + int phy_init_hw(struct phy_device *phydev) { int ret = 0; @@ -1259,6 +1290,12 @@ int phy_init_hw(struct phy_device *phyde return ret; } + if (IS_ENABLED(CONFIG_PHYLIB_LEDS)) { + ret = of_phy_led_init(phydev); + if (ret < 0) + return ret; + } + return 0; } EXPORT_SYMBOL(phy_init_hw); @@ -3204,7 +3241,6 @@ static int of_phy_led(struct phy_device struct device *dev = &phydev->mdio.dev; struct led_init_data init_data = {}; struct led_classdev *cdev; - unsigned long modes = 0; struct phy_led *phyled; u32 index; int err; @@ -3222,21 +3258,6 @@ static int of_phy_led(struct phy_device if (index > U8_MAX) return -EINVAL; - if (of_property_read_bool(led, "active-low")) - set_bit(PHY_LED_ACTIVE_LOW, &modes); - if (of_property_read_bool(led, "inactive-high-impedance")) - set_bit(PHY_LED_INACTIVE_HIGH_IMPEDANCE, &modes); - - if (modes) { - /* Return error if asked to set polarity modes but not supported */ - if (!phydev->drv->led_polarity_set) - return -EINVAL; - - err = phydev->drv->led_polarity_set(phydev, index, modes); - if (err) - return err; - } - phyled->index = index; if (phydev->drv->led_brightness_set) cdev->brightness_set_blocking = phy_led_set_brightness;