add "phy-reset-in-suspend" device tree option
authorJosep Orga <jorga@somdevices.com>
Mon, 6 May 2019 09:25:17 +0000 (11:25 +0200)
committerJosep Orga <jorga@somdevices.com>
Mon, 6 May 2019 09:25:17 +0000 (11:25 +0200)
Based on: https://github.com/digi-embedded/linux/commit/f0ddbc0153b269bfd21b84dbd4ad16acdfd21f29#diff-28c0935b4b5bf1738a0ee788d25a18ffR3408

Signed-off-by: Josep Orga <jorga@somdevices.com>
Documentation/devicetree/bindings/net/fsl-fec.txt
drivers/net/ethernet/freescale/fec.h
drivers/net/ethernet/freescale/fec_main.c

index 555731a..9d491c1 100644 (file)
@@ -22,6 +22,8 @@ Optional properties:
 - phy-reset-active-high : If present then the reset sequence using the GPIO
   specified in the "phy-reset-gpios" property is reversed (H=reset state,
   L=operation state).
+- phy-reset-in-suspend : keeps the phy in reset during suspend mode to
+  avoid back-drives through the reset line.
 - phy-supply : regulator that powers the Ethernet PHY.
 - phy-handle : phandle to the PHY device connected to this device.
 - fixed-link : Assume a fixed link. See fixed-link.txt in the same directory.
index df0c1d6..1cd505e 100644 (file)
@@ -585,6 +585,7 @@ struct fec_enet_private {
        int     phy_reset_gpio;
        u32     phy_reset_duration;
        bool    active_high;
+       bool    phy_reset_in_suspend;
 
        struct  napi_struct napi;
        int     csum_flags;
index 3482309..fdec8cb 100644 (file)
@@ -3490,6 +3490,9 @@ static int fec_reset_phy_init(struct platform_device *pdev)
                dev_err(&pdev->dev, "failed to get phy-reset-gpios: %d\n", err);
                return err;
        }
+       fep->phy_reset_in_suspend = of_find_property(np,
+                                                    "phy-reset-in-suspend",
+                                                    NULL);
        /* Enable PHY and wait for stabilization */
        gpio_set_value_cansleep(fep->phy_reset_gpio, !fep->active_high);
        if (fep->phy_reset_duration < 20)
@@ -3923,6 +3926,8 @@ static int __maybe_unused fec_suspend(struct device *dev)
                if (!(fep->wol_flag & FEC_WOL_FLAG_ENABLE)) {
                        fec_irqs_disable(ndev);
                        pinctrl_pm_select_sleep_state(&fep->pdev->dev);
+                       if (fep->phy_reset_in_suspend)
+                               gpio_set_value_cansleep(fep->phy_reset_gpio, fep->active_high);
                } else {
                        disable_irq(fep->wake_irq);
                        enable_irq_wake(fep->wake_irq);
@@ -3935,6 +3940,8 @@ static int __maybe_unused fec_suspend(struct device *dev)
                        return ret;
        } else if (fep->mii_bus_share && !ndev->phydev) {
                pinctrl_pm_select_sleep_state(&fep->pdev->dev);
+               if (fep->phy_reset_in_suspend)
+                               gpio_set_value_cansleep(fep->phy_reset_gpio, fep->active_high);
        }
        rtnl_unlock();
 
@@ -3983,6 +3990,8 @@ static int __maybe_unused fec_resume(struct device *dev)
                        fep->wol_flag &= ~FEC_WOL_FLAG_SLEEP_ON;
                } else {
                        pinctrl_pm_select_default_state(&fep->pdev->dev);
+                       if (fep->phy_reset_in_suspend)
+                               gpio_set_value_cansleep(fep->phy_reset_gpio, !fep->active_high);
                }
                fec_restart(ndev);
                netif_tx_lock_bh(ndev);
@@ -3992,6 +4001,8 @@ static int __maybe_unused fec_resume(struct device *dev)
                phy_start(ndev->phydev);
        } else if (fep->mii_bus_share && !ndev->phydev) {
                pinctrl_pm_select_default_state(&fep->pdev->dev);
+               if (fep->phy_reset_in_suspend)
+                               gpio_set_value_cansleep(fep->phy_reset_gpio, !fep->active_high);
                /* And then recovery mii bus */
                ret = fec_restore_mii_bus(ndev);
        }