| From 1e3c864a163ae8b999df3cdf65338d2d628dd3c8 Mon Sep 17 00:00:00 2001 |
| From: Leonard Crestez <leonard.crestez@nxp.com> |
| Date: Wed, 31 May 2017 13:29:30 +0300 |
| Subject: [PATCH 173/286] net: phy: micrel: Restore led_mode and clk_sel on |
| resume |
| |
| 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> |
| (cherry picked from commit 79e498a9c7da0737829ff864aae44df434105676) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| drivers/net/phy/micrel.c | 42 ++++++++++++++++++++++++++++-------------- |
| 1 file changed, 28 insertions(+), 14 deletions(-) |
| |
| --- a/drivers/net/phy/micrel.c |
| +++ b/drivers/net/phy/micrel.c |
| @@ -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,11 +284,30 @@ static int kszphy_config_init(struct phy |
| } |
| |
| 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); |
| |
| 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; |
| @@ -703,8 +711,14 @@ static int kszphy_suspend(struct phy_dev |
| |
| 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; |