net: phy: micrel: Restore led_mode and clk_sel on resume
authorLeonard Crestez <leonard.crestez@nxp.com>
Wed, 31 May 2017 10:29:30 +0000 (13:29 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 13 Apr 2018 17:48:17 +0000 (19:48 +0200)
[ Upstream commit 79e498a9c7da0737829ff864aae44df434105676 ]

These bits seem to be lost after a suspend/resume cycle so just set them
again. Do this by splitting the handling of these bits into a function
that is also called on resume.

This patch fixes ethernet suspend/resume on imx6ul-14x14-evk boards.

Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/phy/micrel.c

index 2032a6de026bfd26c6ded8a20a83ca034473e640..4da73e2c37cfbc1215e95c590b747af8dcadc353 100644 (file)
@@ -268,23 +268,12 @@ out:
        return ret;
 }
 
-static int kszphy_config_init(struct phy_device *phydev)
+/* Some config bits need to be set again on resume, handle them here. */
+static int kszphy_config_reset(struct phy_device *phydev)
 {
        struct kszphy_priv *priv = phydev->priv;
-       const struct kszphy_type *type;
        int ret;
 
-       if (!priv)
-               return 0;
-
-       type = priv->type;
-
-       if (type->has_broadcast_disable)
-               kszphy_broadcast_disable(phydev);
-
-       if (type->has_nand_tree_disable)
-               kszphy_nand_tree_disable(phydev);
-
        if (priv->rmii_ref_clk_sel) {
                ret = kszphy_rmii_clk_sel(phydev, priv->rmii_ref_clk_sel_val);
                if (ret) {
@@ -295,7 +284,7 @@ static int kszphy_config_init(struct phy_device *phydev)
        }
 
        if (priv->led_mode >= 0)
-               kszphy_setup_led(phydev, type->led_mode_reg, priv->led_mode);
+               kszphy_setup_led(phydev, priv->type->led_mode_reg, priv->led_mode);
 
        if (phy_interrupt_is_valid(phydev)) {
                int ctl = phy_read(phydev, MII_BMCR);
@@ -311,6 +300,25 @@ static int kszphy_config_init(struct phy_device *phydev)
        return 0;
 }
 
+static int kszphy_config_init(struct phy_device *phydev)
+{
+       struct kszphy_priv *priv = phydev->priv;
+       const struct kszphy_type *type;
+
+       if (!priv)
+               return 0;
+
+       type = priv->type;
+
+       if (type->has_broadcast_disable)
+               kszphy_broadcast_disable(phydev);
+
+       if (type->has_nand_tree_disable)
+               kszphy_nand_tree_disable(phydev);
+
+       return kszphy_config_reset(phydev);
+}
+
 static int ksz8041_config_init(struct phy_device *phydev)
 {
        struct device_node *of_node = phydev->mdio.dev.of_node;
@@ -715,8 +723,14 @@ static int kszphy_suspend(struct phy_device *phydev)
 
 static int kszphy_resume(struct phy_device *phydev)
 {
+       int ret;
+
        genphy_resume(phydev);
 
+       ret = kszphy_config_reset(phydev);
+       if (ret)
+               return ret;
+
        /* Enable PHY Interrupts */
        if (phy_interrupt_is_valid(phydev)) {
                phydev->interrupts = PHY_INTERRUPT_ENABLED;