ramips: add support for Edimax EW-7476RPC / EW-7478AC
[openwrt/staging/mkresin.git] / target / linux / ramips / files-4.14 / drivers / net / ethernet / mediatek / mtk_eth_soc.c
index b2c3d32c5549b6fd8ea4c76dc224b9b4b41130d8..65aa7f32606518a1ed6e497559f17113115cbe86 100644 (file)
@@ -32,6 +32,9 @@
 #include <linux/bug.h>
 #include <linux/netfilter.h>
 #include <net/netfilter/nf_flow_table.h>
 #include <linux/bug.h>
 #include <linux/netfilter.h>
 #include <net/netfilter/nf_flow_table.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 
 #include <asm/mach-ralink/ralink_regs.h>
 
 
 #include <asm/mach-ralink/ralink_regs.h>
 
@@ -1333,6 +1336,35 @@ static int fe_stop(struct net_device *dev)
        return 0;
 }
 
        return 0;
 }
 
+static void fe_reset_phy(struct fe_priv *priv)
+{
+       int err, msec = 30;
+       struct gpio_desc *phy_reset;
+
+       phy_reset = devm_gpiod_get_optional(priv->dev, "phy-reset",
+                                           GPIOD_OUT_HIGH);
+       if (!phy_reset)
+               return;
+
+       if (IS_ERR(phy_reset)) {
+               dev_err(priv->dev, "Error acquiring reset gpio pins: %ld\n",
+                       PTR_ERR(phy_reset));
+               return;
+       }
+
+       err = of_property_read_u32(priv->dev->of_node, "phy-reset-duration",
+                                  &msec);
+       if (!err && msec > 1000)
+               msec = 30;
+
+       if (msec > 20)
+               msleep(msec);
+       else
+               usleep_range(msec * 1000, msec * 1000 + 1000);
+
+       gpiod_set_value(phy_reset, 0);
+}
+
 static int __init fe_init(struct net_device *dev)
 {
        struct fe_priv *priv = netdev_priv(dev);
 static int __init fe_init(struct net_device *dev)
 {
        struct fe_priv *priv = netdev_priv(dev);
@@ -1348,6 +1380,8 @@ static int __init fe_init(struct net_device *dev)
                        return -ENODEV;
                }
 
                        return -ENODEV;
                }
 
+       fe_reset_phy(priv);
+
        mac_addr = of_get_mac_address(priv->dev->of_node);
        if (mac_addr)
                ether_addr_copy(dev->dev_addr, mac_addr);
        mac_addr = of_get_mac_address(priv->dev->of_node);
        if (mac_addr)
                ether_addr_copy(dev->dev_addr, mac_addr);