aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorZhangfei Gao <zhangfei.gao@linaro.org>2014-05-15 01:35:34 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-16 15:17:58 -0400
commit6e14a5eeb158215881ef4507833a3574d0dbad19 (patch)
tree729b51179e2cf5a3616b5520684219052722616f /drivers/net
parent0c2e3fa9583192b0255fa9ec0260350e6ed202bd (diff)
net: phy: resume phydev when going to RESUMING
With commit be9dad1f9f26604fb ("net: phy: suspend phydev when going to HALTED"), an unused PHY device will be put in a low-power mode using BMCR_PDOWN. Some Ethernet drivers might be calling phy_start() and phy_stop() from ndo_open and ndo_close() respectively, while calling phy_connect() and phy_disconnect() from probe and remove. In such a case, the PHY will be powered down during the phy_stop() call, but will fail to be powered up in phy_start(). This patch fixes this scenario. Signed-off-by: Jiancheng Xue <xuejiancheng@huawei.com> Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/phy/phy.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index a972056b2249..3bc079a67a3d 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -715,7 +715,7 @@ void phy_state_machine(struct work_struct *work)
715 struct delayed_work *dwork = to_delayed_work(work); 715 struct delayed_work *dwork = to_delayed_work(work);
716 struct phy_device *phydev = 716 struct phy_device *phydev =
717 container_of(dwork, struct phy_device, state_queue); 717 container_of(dwork, struct phy_device, state_queue);
718 int needs_aneg = 0, do_suspend = 0; 718 bool needs_aneg = false, do_suspend = false, do_resume = false;
719 int err = 0; 719 int err = 0;
720 720
721 mutex_lock(&phydev->lock); 721 mutex_lock(&phydev->lock);
@@ -727,7 +727,7 @@ void phy_state_machine(struct work_struct *work)
727 case PHY_PENDING: 727 case PHY_PENDING:
728 break; 728 break;
729 case PHY_UP: 729 case PHY_UP:
730 needs_aneg = 1; 730 needs_aneg = true;
731 731
732 phydev->link_timeout = PHY_AN_TIMEOUT; 732 phydev->link_timeout = PHY_AN_TIMEOUT;
733 733
@@ -757,7 +757,7 @@ void phy_state_machine(struct work_struct *work)
757 phydev->adjust_link(phydev->attached_dev); 757 phydev->adjust_link(phydev->attached_dev);
758 758
759 } else if (0 == phydev->link_timeout--) 759 } else if (0 == phydev->link_timeout--)
760 needs_aneg = 1; 760 needs_aneg = true;
761 break; 761 break;
762 case PHY_NOLINK: 762 case PHY_NOLINK:
763 err = phy_read_status(phydev); 763 err = phy_read_status(phydev);
@@ -791,7 +791,7 @@ void phy_state_machine(struct work_struct *work)
791 netif_carrier_on(phydev->attached_dev); 791 netif_carrier_on(phydev->attached_dev);
792 } else { 792 } else {
793 if (0 == phydev->link_timeout--) 793 if (0 == phydev->link_timeout--)
794 needs_aneg = 1; 794 needs_aneg = true;
795 } 795 }
796 796
797 phydev->adjust_link(phydev->attached_dev); 797 phydev->adjust_link(phydev->attached_dev);
@@ -827,7 +827,7 @@ void phy_state_machine(struct work_struct *work)
827 phydev->link = 0; 827 phydev->link = 0;
828 netif_carrier_off(phydev->attached_dev); 828 netif_carrier_off(phydev->attached_dev);
829 phydev->adjust_link(phydev->attached_dev); 829 phydev->adjust_link(phydev->attached_dev);
830 do_suspend = 1; 830 do_suspend = true;
831 } 831 }
832 break; 832 break;
833 case PHY_RESUMING: 833 case PHY_RESUMING:
@@ -876,6 +876,7 @@ void phy_state_machine(struct work_struct *work)
876 } 876 }
877 phydev->adjust_link(phydev->attached_dev); 877 phydev->adjust_link(phydev->attached_dev);
878 } 878 }
879 do_resume = true;
879 break; 880 break;
880 } 881 }
881 882
@@ -883,9 +884,10 @@ void phy_state_machine(struct work_struct *work)
883 884
884 if (needs_aneg) 885 if (needs_aneg)
885 err = phy_start_aneg(phydev); 886 err = phy_start_aneg(phydev);
886 887 else if (do_suspend)
887 if (do_suspend)
888 phy_suspend(phydev); 888 phy_suspend(phydev);
889 else if (do_resume)
890 phy_resume(phydev);
889 891
890 if (err < 0) 892 if (err < 0)
891 phy_error(phydev); 893 phy_error(phydev);