Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[cascardo/linux.git] / drivers / net / phy / phy.c
index 1457ecf..377d2db 100644 (file)
@@ -767,6 +767,9 @@ EXPORT_SYMBOL(phy_stop);
  */
 void phy_start(struct phy_device *phydev)
 {
+       bool do_resume = false;
+       int err = 0;
+
        mutex_lock(&phydev->lock);
 
        switch (phydev->state) {
@@ -777,11 +780,22 @@ void phy_start(struct phy_device *phydev)
                phydev->state = PHY_UP;
                break;
        case PHY_HALTED:
+               /* make sure interrupts are re-enabled for the PHY */
+               err = phy_enable_interrupts(phydev);
+               if (err < 0)
+                       break;
+
                phydev->state = PHY_RESUMING;
+               do_resume = true;
+               break;
        default:
                break;
        }
        mutex_unlock(&phydev->lock);
+
+       /* if phy was suspended, bring the physical link up again */
+       if (do_resume)
+               phy_resume(phydev);
 }
 EXPORT_SYMBOL(phy_start);
 
@@ -794,7 +808,7 @@ void phy_state_machine(struct work_struct *work)
        struct delayed_work *dwork = to_delayed_work(work);
        struct phy_device *phydev =
                        container_of(dwork, struct phy_device, state_queue);
-       bool needs_aneg = false, do_suspend = false, do_resume = false;
+       bool needs_aneg = false, do_suspend = false;
        enum phy_state old_state;
        int err = 0;
 
@@ -916,14 +930,6 @@ void phy_state_machine(struct work_struct *work)
                }
                break;
        case PHY_RESUMING:
-               err = phy_clear_interrupt(phydev);
-               if (err)
-                       break;
-
-               err = phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED);
-               if (err)
-                       break;
-
                if (AUTONEG_ENABLE == phydev->autoneg) {
                        err = phy_aneg_done(phydev);
                        if (err < 0)
@@ -961,7 +967,6 @@ void phy_state_machine(struct work_struct *work)
                        }
                        phydev->adjust_link(phydev->attached_dev);
                }
-               do_resume = true;
                break;
        }
 
@@ -971,8 +976,6 @@ void phy_state_machine(struct work_struct *work)
                err = phy_start_aneg(phydev);
        else if (do_suspend)
                phy_suspend(phydev);
-       else if (do_resume)
-               phy_resume(phydev);
 
        if (err < 0)
                phy_error(phydev);
@@ -1084,13 +1087,14 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
 {
        /* According to 802.3az,the EEE is supported only in full duplex-mode.
         * Also EEE feature is active when core is operating with MII, GMII
-        * or RGMII. Internal PHYs are also allowed to proceed and should
-        * return an error if they do not support EEE.
+        * or RGMII (all kinds). Internal PHYs are also allowed to proceed and
+        * should return an error if they do not support EEE.
         */
        if ((phydev->duplex == DUPLEX_FULL) &&
            ((phydev->interface == PHY_INTERFACE_MODE_MII) ||
            (phydev->interface == PHY_INTERFACE_MODE_GMII) ||
-           (phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
+           (phydev->interface >= PHY_INTERFACE_MODE_RGMII &&
+            phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID) ||
             phy_is_internal(phydev))) {
                int eee_lp, eee_cap, eee_adv;
                u32 lp, cap, adv;