From: Petr Štetiar Date: Mon, 20 May 2019 22:18:29 +0000 (+0200) Subject: generic: ar8327: add optional gpio reset support X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=a4e06c3c7a9bbc2eff59a57cd3b395b2754ebec2;p=openwrt%2Fstaging%2Fansuel.git generic: ar8327: add optional gpio reset support Some devices like Linksys EA8500 use designated GPIO to reset the switch and if the switch isn't reset properly before first access, it can lead to unusable switch after soft reboot of the device: libphy: GPIO Bitbanged MDIO: probed mdio_bus gpio-0: MDIO device at address 0 is missing. mdio_bus gpio-0: MDIO device at address 4 is missing. Working case: libphy: GPIO Bitbanged MDIO: probed switch0: Atheros AR8337 rev. 2 switch registered on gpio-0 So this patch introduces reset GPIO, along with duration and active high/low properties which fixes the problem. Ref: https://github.com/openwrt/openwrt/pull/2047 Ref: https://bugs.openwrt.org/index.php?do=details&task_id=2168 Signed-off-by: Petr Štetiar [ remove invalid tested-by and reported-by ] Signed-off-by: Christian Marangi --- diff --git a/target/linux/generic/files/drivers/net/phy/ar8327.c b/target/linux/generic/files/drivers/net/phy/ar8327.c index 3313149559..825a9e0be9 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8327.c +++ b/target/linux/generic/files/drivers/net/phy/ar8327.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -609,6 +610,29 @@ ar8327_hw_config_pdata(struct ar8xxx_priv *priv, } #ifdef CONFIG_OF +static void +ar8327_gpio_reset(struct ar8xxx_priv *priv, struct device_node *np) +{ + int msec; + int reset_init; + bool active_high; + struct gpio_desc *reset; + + active_high = of_property_read_bool(np, "reset-active-high"); + reset_init = active_high ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW; + reset = devm_gpiod_get_optional(priv->pdev, "reset", reset_init); + if (!reset) + return; + + of_property_read_u32(np, "reset-duration", &msec); + if (msec > 20) + msleep(msec); + else + usleep_range(msec * 1000, msec * 1000 + 1000); + + gpiod_set_value_cansleep(reset, !active_high); +} + static int ar8327_hw_config_of(struct ar8xxx_priv *priv, struct device_node *np) { @@ -617,6 +641,8 @@ ar8327_hw_config_of(struct ar8xxx_priv *priv, struct device_node *np) int len; int i; + ar8327_gpio_reset(priv, np); + paddr = of_get_property(np, "qca,ar8327-initvals", &len); if (!paddr || len < (2 * sizeof(*paddr))) return -EINVAL;