net: phy: Trigger state machine on state change and not polling.
[cascardo/linux.git] / drivers / net / phy / phy.c
index c6f6683..f424b86 100644 (file)
@@ -607,6 +607,21 @@ void phy_start_machine(struct phy_device *phydev)
        queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, HZ);
 }
 
+/**
+ * phy_trigger_machine - trigger the state machine to run
+ *
+ * @phydev: the phy_device struct
+ *
+ * Description: There has been a change in state which requires that the
+ *   state machine runs.
+ */
+
+static void phy_trigger_machine(struct phy_device *phydev)
+{
+       cancel_delayed_work_sync(&phydev->state_queue);
+       queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, 0);
+}
+
 /**
  * phy_stop_machine - stop the PHY state machine tracking
  * @phydev: target phy_device struct
@@ -639,6 +654,8 @@ static void phy_error(struct phy_device *phydev)
        mutex_lock(&phydev->lock);
        phydev->state = PHY_HALTED;
        mutex_unlock(&phydev->lock);
+
+       phy_trigger_machine(phydev);
 }
 
 /**
@@ -800,8 +817,7 @@ void phy_change(struct work_struct *work)
        }
 
        /* reschedule state queue work to run as soon as possible */
-       cancel_delayed_work_sync(&phydev->state_queue);
-       queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, 0);
+       phy_trigger_machine(phydev);
        return;
 
 ignore:
@@ -890,6 +906,8 @@ void phy_start(struct phy_device *phydev)
        /* if phy was suspended, bring the physical link up again */
        if (do_resume)
                phy_resume(phydev);
+
+       phy_trigger_machine(phydev);
 }
 EXPORT_SYMBOL(phy_start);