sun8i_dwmac_exit calls sun8i_dwmac_unpower_internal_phy, but
sun8i_dwmac_init did not call sun8i_dwmac_power_internal_phy. This
caused PHY power to remain off after a suspend/resume cycle. Fix this by
recording if PHY power should be restored, and if so, restoring it.

Fixes: 634db83b8265 ("net: stmmac: dwmac-sun8i: Handle integrated/external 
MDIOs")
Signed-off-by: Samuel Holland <sam...@sholland.org>
---
 .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 31 ++++++++++++++-----
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index a05dee5d4584..e2c25c1c702a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -64,6 +64,7 @@ struct emac_variant {
  * @variant:   reference to the current board variant
  * @regmap:    regmap for using the syscon
  * @internal_phy_powered: Does the internal PHY is enabled
+ * @use_internal_phy: Is the internal PHY selected for use
  * @mux_handle:        Internal pointer used by mdio-mux lib
  */
 struct sunxi_priv_data {
@@ -74,6 +75,7 @@ struct sunxi_priv_data {
        const struct emac_variant *variant;
        struct regmap_field *regmap_field;
        bool internal_phy_powered;
+       bool use_internal_phy;
        void *mux_handle;
 };
 
@@ -539,8 +541,11 @@ static const struct stmmac_dma_ops sun8i_dwmac_dma_ops = {
        .dma_interrupt = sun8i_dwmac_dma_interrupt,
 };
 
+static int sun8i_dwmac_power_internal_phy(struct stmmac_priv *priv);
+
 static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
 {
+       struct net_device *ndev = platform_get_drvdata(pdev);
        struct sunxi_priv_data *gmac = priv;
        int ret;
 
@@ -554,13 +559,25 @@ static int sun8i_dwmac_init(struct platform_device *pdev, 
void *priv)
 
        ret = clk_prepare_enable(gmac->tx_clk);
        if (ret) {
-               if (gmac->regulator)
-                       regulator_disable(gmac->regulator);
                dev_err(&pdev->dev, "Could not enable AHB clock\n");
-               return ret;
+               goto err_disable_regulator;
+       }
+
+       if (gmac->use_internal_phy) {
+               ret = sun8i_dwmac_power_internal_phy(netdev_priv(ndev));
+               if (ret)
+                       goto err_disable_clk;
        }
 
        return 0;
+
+err_disable_clk:
+       clk_disable_unprepare(gmac->tx_clk);
+err_disable_regulator:
+       if (gmac->regulator)
+               regulator_disable(gmac->regulator);
+
+       return ret;
 }
 
 static void sun8i_dwmac_core_init(struct mac_device_info *hw,
@@ -831,7 +848,6 @@ static int mdio_mux_syscon_switch_fn(int current_child, int 
desired_child,
        struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
        u32 reg, val;
        int ret = 0;
-       bool need_power_ephy = false;
 
        if (current_child ^ desired_child) {
                regmap_field_read(gmac->regmap_field, &reg);
@@ -839,13 +855,12 @@ static int mdio_mux_syscon_switch_fn(int current_child, 
int desired_child,
                case DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID:
                        dev_info(priv->device, "Switch mux to internal PHY");
                        val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SELECT;
-
-                       need_power_ephy = true;
+                       gmac->use_internal_phy = true;
                        break;
                case DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID:
                        dev_info(priv->device, "Switch mux to external PHY");
                        val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SHUTDOWN;
-                       need_power_ephy = false;
+                       gmac->use_internal_phy = false;
                        break;
                default:
                        dev_err(priv->device, "Invalid child ID %x\n",
@@ -853,7 +868,7 @@ static int mdio_mux_syscon_switch_fn(int current_child, int 
desired_child,
                        return -EINVAL;
                }
                regmap_field_write(gmac->regmap_field, val);
-               if (need_power_ephy) {
+               if (gmac->use_internal_phy) {
                        ret = sun8i_dwmac_power_internal_phy(priv);
                        if (ret)
                                return ret;
-- 
2.26.2

Reply via email to