Function fec_enet_clk_enable() was disabling this line leaving the PHY
authorJosep Orga <jorga@somdevices.com>
Thu, 2 May 2019 18:19:04 +0000 (20:19 +0200)
committerJosep Orga <jorga@somdevices.com>
Thu, 2 May 2019 18:19:04 +0000 (20:19 +0200)
without a running clock. This makes the PHY lose its internal state
requiring a reset of the PHY to be reactivated.

This patch enables the clk_enet_out once at probe() so that it remains
enabled during all MDIO accesses.

References: https://github.com/digi-embedded/linux/commit/fa3f9ab2d2650ba6b24f2ef62ddedbf971e56d07#diff-28c0935b4b5bf1738a0ee788d25a18ffR1952
https://patchwork.ozlabs.org/patch/549391/

Signed-off-by: Josep Orga <jorga@somdevices.com>
drivers/net/ethernet/freescale/fec_main.c

index eca54e5..6ab85fd 100644 (file)
@@ -1925,11 +1925,6 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
        int ret;
 
        if (enable) {
-               if (fep->clk_enet_out) {
-                       ret = clk_prepare_enable(fep->clk_enet_out);
-                       if (ret)
-                               return ret;
-               }
                if (fep->clk_ptp) {
                        mutex_lock(&fep->ptp_clk_mutex);
                        ret = clk_prepare_enable(fep->clk_ptp);
@@ -1952,8 +1947,6 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
                                goto failed_clk_2x_txclk;
                }
        } else {
-               if (fep->clk_enet_out)
-                       clk_disable_unprepare(fep->clk_enet_out);
                if (fep->clk_ptp) {
                        mutex_lock(&fep->ptp_clk_mutex);
                        clk_disable_unprepare(fep->clk_ptp);
@@ -1975,8 +1968,7 @@ failed_clk_ref:
        if (fep->clk_ptp)
                clk_disable_unprepare(fep->clk_ptp);
 failed_clk_ptp:
-       if (fep->clk_enet_out)
-               clk_disable_unprepare(fep->clk_enet_out);
+       clk_disable_unprepare(fep->clk_ipg);
 
        return ret;
 }
@@ -3701,6 +3693,11 @@ fec_probe(struct platform_device *pdev)
        fep->clk_enet_out = devm_clk_get(&pdev->dev, "enet_out");
        if (IS_ERR(fep->clk_enet_out))
                fep->clk_enet_out = NULL;
+       if (fep->clk_enet_out) {
+               ret = clk_prepare_enable(fep->clk_enet_out);
+               if (ret)
+                       goto failed_clk_ipg;
+       }
 
        fep->ptp_clk_on = false;
        mutex_init(&fep->ptp_clk_mutex);
@@ -3865,6 +3862,8 @@ fec_drv_remove(struct platform_device *pdev)
        fec_ptp_stop(pdev);
        unregister_netdev(ndev);
        fec_enet_mii_remove(fep);
+       if (fep->clk_enet_out)
+               clk_disable_unprepare(fep->clk_enet_out);
        if (fep->reg_phy)
                regulator_disable(fep->reg_phy);
        if (of_phy_is_fixed_link(np))