return 0;
 }
 
+static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
+{
+       struct fec_enet_private *fep = netdev_priv(ndev);
+       int ret;
+
+       if (enable) {
+               ret = clk_prepare_enable(fep->clk_ahb);
+               if (ret)
+                       return ret;
+               ret = clk_prepare_enable(fep->clk_ipg);
+               if (ret)
+                       goto failed_clk_ipg;
+               if (fep->clk_enet_out) {
+                       ret = clk_prepare_enable(fep->clk_enet_out);
+                       if (ret)
+                               goto failed_clk_enet_out;
+               }
+               if (fep->clk_ptp) {
+                       ret = clk_prepare_enable(fep->clk_ptp);
+                       if (ret)
+                               goto failed_clk_ptp;
+               }
+       } else {
+               clk_disable_unprepare(fep->clk_ahb);
+               clk_disable_unprepare(fep->clk_ipg);
+               if (fep->clk_enet_out)
+                       clk_disable_unprepare(fep->clk_enet_out);
+               if (fep->clk_ptp)
+                       clk_disable_unprepare(fep->clk_ptp);
+       }
+
+       return 0;
+failed_clk_ptp:
+       if (fep->clk_enet_out)
+               clk_disable_unprepare(fep->clk_enet_out);
+failed_clk_enet_out:
+               clk_disable_unprepare(fep->clk_ipg);
+failed_clk_ipg:
+               clk_disable_unprepare(fep->clk_ahb);
+
+       return ret;
+}
+
 static int fec_enet_mii_probe(struct net_device *ndev)
 {
        struct fec_enet_private *fep = netdev_priv(ndev);
        struct fec_enet_private *fep = netdev_priv(ndev);
        int ret;
 
+       ret = fec_enet_clk_enable(ndev, true);
+       if (ret)
+               return ret;
+
        /* I should reset the ring buffers here, but I don't yet know
         * a simple way to do that.
         */
                phy_disconnect(fep->phy_dev);
        }
 
+       fec_enet_clk_enable(ndev, false);
        fec_enet_free_buffers(ndev);
 
        return 0;
                fep->bufdesc_ex = 0;
        }
 
-       ret = clk_prepare_enable(fep->clk_ahb);
+       ret = fec_enet_clk_enable(ndev, true);
        if (ret)
                goto failed_clk;
 
-       ret = clk_prepare_enable(fep->clk_ipg);
-       if (ret)
-               goto failed_clk_ipg;
-
-       if (fep->clk_enet_out) {
-               ret = clk_prepare_enable(fep->clk_enet_out);
-               if (ret)
-                       goto failed_clk_enet_out;
-       }
-
-       if (fep->clk_ptp) {
-               ret = clk_prepare_enable(fep->clk_ptp);
-               if (ret)
-                       goto failed_clk_ptp;
-       }
-
        fep->reg_phy = devm_regulator_get(&pdev->dev, "phy");
        if (!IS_ERR(fep->reg_phy)) {
                ret = regulator_enable(fep->reg_phy);
 
        /* Carrier starts down, phylib will bring it up */
        netif_carrier_off(ndev);
+       fec_enet_clk_enable(ndev, false);
 
        ret = register_netdev(ndev);
        if (ret)
        if (fep->reg_phy)
                regulator_disable(fep->reg_phy);
 failed_regulator:
-       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);
-failed_clk_enet_out:
-       clk_disable_unprepare(fep->clk_ipg);
-failed_clk_ipg:
-       clk_disable_unprepare(fep->clk_ahb);
+       fec_enet_clk_enable(ndev, false);
 failed_clk:
 failed_ioremap:
        free_netdev(ndev);
        del_timer_sync(&fep->time_keep);
        if (fep->reg_phy)
                regulator_disable(fep->reg_phy);
-       if (fep->clk_ptp)
-               clk_disable_unprepare(fep->clk_ptp);
        if (fep->ptp_clock)
                ptp_clock_unregister(fep->ptp_clock);
-       if (fep->clk_enet_out)
-               clk_disable_unprepare(fep->clk_enet_out);
-       clk_disable_unprepare(fep->clk_ipg);
-       clk_disable_unprepare(fep->clk_ahb);
+       fec_enet_clk_enable(ndev, false);
        free_netdev(ndev);
 
        return 0;
                fec_stop(ndev);
                netif_device_detach(ndev);
        }
-       if (fep->clk_ptp)
-               clk_disable_unprepare(fep->clk_ptp);
-       if (fep->clk_enet_out)
-               clk_disable_unprepare(fep->clk_enet_out);
-       clk_disable_unprepare(fep->clk_ipg);
-       clk_disable_unprepare(fep->clk_ahb);
+       fec_enet_clk_enable(ndev, false);
 
        if (fep->reg_phy)
                regulator_disable(fep->reg_phy);
                        return ret;
        }
 
-       ret = clk_prepare_enable(fep->clk_ahb);
-       if (ret)
-               goto failed_clk_ahb;
-
-       ret = clk_prepare_enable(fep->clk_ipg);
+       ret = fec_enet_clk_enable(ndev, true);
        if (ret)
-               goto failed_clk_ipg;
-
-       if (fep->clk_enet_out) {
-               ret = clk_prepare_enable(fep->clk_enet_out);
-               if (ret)
-                       goto failed_clk_enet_out;
-       }
-
-       if (fep->clk_ptp) {
-               ret = clk_prepare_enable(fep->clk_ptp);
-               if (ret)
-                       goto failed_clk_ptp;
-       }
+               goto failed_clk;
 
        if (netif_running(ndev)) {
                fec_restart(ndev, fep->full_duplex);
 
        return 0;
 
-failed_clk_ptp:
-       if (fep->clk_enet_out)
-               clk_disable_unprepare(fep->clk_enet_out);
-failed_clk_enet_out:
-       clk_disable_unprepare(fep->clk_ipg);
-failed_clk_ipg:
-       clk_disable_unprepare(fep->clk_ahb);
-failed_clk_ahb:
+failed_clk:
        if (fep->reg_phy)
                regulator_disable(fep->reg_phy);
        return ret;