Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
[linux-2.6-block.git] / drivers / net / ethernet / freescale / fec_main.c
index c043afb38b6e16d4ed227a7bdca405c2e44e68b1..8f7eca1e7716c9bbaddb28f9b541a339ef326a8c 100644 (file)
@@ -1912,6 +1912,27 @@ out:
        return ret;
 }
 
+static void fec_enet_phy_reset_after_clk_enable(struct net_device *ndev)
+{
+       struct fec_enet_private *fep = netdev_priv(ndev);
+       struct phy_device *phy_dev = ndev->phydev;
+
+       if (phy_dev) {
+               phy_reset_after_clk_enable(phy_dev);
+       } else if (fep->phy_node) {
+               /*
+                * If the PHY still is not bound to the MAC, but there is
+                * OF PHY node and a matching PHY device instance already,
+                * use the OF PHY node to obtain the PHY device instance,
+                * and then use that PHY device instance when triggering
+                * the PHY reset.
+                */
+               phy_dev = of_phy_find_device(fep->phy_node);
+               phy_reset_after_clk_enable(phy_dev);
+               put_device(&phy_dev->mdio.dev);
+       }
+}
+
 static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
 {
        struct fec_enet_private *fep = netdev_priv(ndev);
@@ -1938,7 +1959,7 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
                if (ret)
                        goto failed_clk_ref;
 
-               phy_reset_after_clk_enable(ndev->phydev);
+               fec_enet_phy_reset_after_clk_enable(ndev);
        } else {
                clk_disable_unprepare(fep->clk_enet_out);
                if (fep->clk_ptp) {
@@ -2983,16 +3004,16 @@ fec_enet_open(struct net_device *ndev)
        /* Init MAC prior to mii bus probe */
        fec_restart(ndev);
 
-       /* Probe and connect to PHY when open the interface */
-       ret = fec_enet_mii_probe(ndev);
-       if (ret)
-               goto err_enet_mii_probe;
-
        /* Call phy_reset_after_clk_enable() again if it failed during
         * phy_reset_after_clk_enable() before because the PHY wasn't probed.
         */
        if (reset_again)
-               phy_reset_after_clk_enable(ndev->phydev);
+               fec_enet_phy_reset_after_clk_enable(ndev);
+
+       /* Probe and connect to PHY when open the interface */
+       ret = fec_enet_mii_probe(ndev);
+       if (ret)
+               goto err_enet_mii_probe;
 
        if (fep->quirks & FEC_QUIRK_ERR006687)
                imx6q_cpuidle_fec_irqs_used();