The PHY reset is requested through the legacy GPIO API, which knows
nothing about the GPIO_OPEN_DRAIN flag in the reset-gpios property. On
the Libre Computer Alta the RTL8211F's reset line is declared open drain,
and driving it high after the pulse leaves it low: the PHY stays in reset
and is never found. Released to input, the external pull-up takes over
and the PHY answers.

Let's request the GPIO as a descriptor so gpiolib applies the flags from
the device tree, as it does for every other consumer.

Fixes: 8fd3bb0f2284 ("phylib: add support for reset-gpios")
Assisted-by: Claude:fable-5.1
Signed-off-by: Ahmad Fatoum <[email protected]>
---
 drivers/net/phy/mdio_bus.c | 31 ++++++++++---------------------
 1 file changed, 10 insertions(+), 21 deletions(-)

diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 401206256127..7795fcf388d7 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -12,10 +12,9 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <common.h>
-#include <of_gpio.h>
 #include <driver.h>
 #include <init.h>
-#include <gpio.h>
+#include <linux/gpio/consumer.h>
 #include <clock.h>
 #include <net.h>
 #include <sched.h>
@@ -217,25 +216,16 @@ static bool of_mdiobus_child_is_phy(struct device_node 
*np)
  */
 static u64 of_mdiobus_reset_phy(struct mii_bus *bus, struct device_node *np)
 {
-       enum of_gpio_flags of_flags;
        u32 reset_deassert_delay;
        u32 reset_assert_delay;
-       unsigned long flags;
-       int gpio;
-       int ret;
+       struct gpio_desc *gpiod;
 
-       gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, &of_flags);
-       if (!gpio_is_valid(gpio))
-               return 0;
-
-       flags = GPIOF_OUT_INIT_INACTIVE;
-       if (of_flags & OF_GPIO_ACTIVE_LOW)
-               flags |= GPIOF_ACTIVE_LOW;
-
-       ret = gpio_request_one(gpio, flags, np->name);
-       if (ret) {
-               dev_err(&bus->dev, "failed to request reset gpio for: %s\n",
-                       np->name);
+       /* requested asserted, released below once the pulse is over */
+       gpiod = dev_gpiod_get(&bus->dev, np, "reset", GPIOD_OUT_HIGH, np->name);
+       if (IS_ERR(gpiod)) {
+               if (PTR_ERR(gpiod) != -ENOENT)
+                       dev_err(&bus->dev, "failed to request reset gpio for: 
%s\n",
+                               np->name);
                return 0;
        }
 
@@ -246,10 +236,9 @@ static u64 of_mdiobus_reset_phy(struct mii_bus *bus, 
struct device_node *np)
        of_property_read_u32(np, "reset-deassert-us", &reset_deassert_delay);
 
        /* reset the PHY */
-       dev_dbg(&bus->dev, "reset PHY with GPIO: %d\n", gpio);
-       gpio_set_active(gpio, 1);
+       dev_dbg(&bus->dev, "reset PHY %s\n", np->name);
        udelay(reset_assert_delay);
-       gpio_set_active(gpio, 0);
+       gpiod_set_value(gpiod, 0);
 
        return get_time_ns() + (u64)reset_deassert_delay * 1000;
 }
-- 
2.47.3


Reply via email to