net: dwc_eth_qos: implement reset-gpios for stm32
authorChristophe Roullier <christophe.roullier@st.com>
Wed, 18 Mar 2020 09:50:15 +0000 (10:50 +0100)
committerPatrice Chotard <patrice.chotard@st.com>
Wed, 15 Apr 2020 07:08:29 +0000 (09:08 +0200)
Add management of property "reset-gpios" in the node identified by
"phy-handle" to configure any GPIO used to reset the PHY.

Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
Reviewed-by: Patrice CHOTARD <patrice.chotard@st.com>
Reviewed-by: Patrick DELAUNAY <patrick.delaunay@st.com>
Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
drivers/net/dwc_eth_qos.c

index 0564bebf76c007ae2fb37c819febf371951b731a..47966592165732e8c4a21ae96b6b940749d1662c 100644 (file)
@@ -694,6 +694,29 @@ static int eqos_start_resets_tegra186(struct udevice *dev)
 
 static int eqos_start_resets_stm32(struct udevice *dev)
 {
+       struct eqos_priv *eqos = dev_get_priv(dev);
+       int ret;
+
+       debug("%s(dev=%p):\n", __func__, dev);
+       if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
+               ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 1);
+               if (ret < 0) {
+                       pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d",
+                              ret);
+                       return ret;
+               }
+
+               udelay(2);
+
+               ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
+               if (ret < 0) {
+                       pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d",
+                              ret);
+                       return ret;
+               }
+       }
+       debug("%s: OK\n", __func__);
+
        return 0;
 }
 
@@ -709,6 +732,18 @@ static int eqos_stop_resets_tegra186(struct udevice *dev)
 
 static int eqos_stop_resets_stm32(struct udevice *dev)
 {
+       struct eqos_priv *eqos = dev_get_priv(dev);
+       int ret;
+
+       if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
+               ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 1);
+               if (ret < 0) {
+                       pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d",
+                              ret);
+                       return ret;
+               }
+       }
+
        return 0;
 }
 
@@ -1604,6 +1639,7 @@ static int eqos_probe_resources_stm32(struct udevice *dev)
        struct eqos_priv *eqos = dev_get_priv(dev);
        int ret;
        phy_interface_t interface;
+       struct ofnode_phandle_args phandle_args;
 
        debug("%s(dev=%p):\n", __func__, dev);
 
@@ -1641,6 +1677,20 @@ static int eqos_probe_resources_stm32(struct udevice *dev)
        if (ret)
                pr_warn("No phy clock provided %d", ret);
 
+       ret = dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
+                                        &phandle_args);
+       if (!ret) {
+               /* search "reset-gpios" in phy node */
+               ret = gpio_request_by_name_nodev(phandle_args.node,
+                                                "reset-gpios", 0,
+                                                &eqos->phy_reset_gpio,
+                                                GPIOD_IS_OUT |
+                                                GPIOD_IS_OUT_ACTIVE);
+               if (ret)
+                       pr_warn("gpio_request_by_name(phy reset) not provided %d",
+                               ret);
+       }
+
        debug("%s: OK\n", __func__);
        return 0;
 
@@ -1704,6 +1754,9 @@ static int eqos_remove_resources_stm32(struct udevice *dev)
        if (clk_valid(&eqos->clk_ck))
                clk_free(&eqos->clk_ck);
 
+       if (dm_gpio_is_valid(&eqos->phy_reset_gpio))
+               dm_gpio_free(dev, &eqos->phy_reset_gpio);
+
        debug("%s: OK\n", __func__);
        return 0;
 }