aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/freescale
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2014-07-08 07:39:57 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-08 23:02:58 -0400
commitda1774e5f1974294dcfc2c08363bb103e769d302 (patch)
treedaf0b6e67d4b07c713a981b7431b9917f3034335 /drivers/net/ethernet/freescale
parent2167cefc9e07753d158a56be0c58eb7702aa122b (diff)
net: fec: improve safety of suspend/resume/transmit timeout paths
We should hold the rtnl lock while suspending, resuming or processing the transmit timeout to ensure that nothing will interfere while we bring up, take down or restart the hardware. The transmit timeout could run if we're preempted during suspend. Acked-by: Fugang Duan <B38611@freescale.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/freescale')
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index f43c388e2eb9..1cd71a8d9996 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1068,8 +1068,10 @@ static void fec_enet_work(struct work_struct *work)
1068 1068
1069 if (fep->delay_work.timeout) { 1069 if (fep->delay_work.timeout) {
1070 fep->delay_work.timeout = false; 1070 fep->delay_work.timeout = false;
1071 rtnl_lock();
1071 fec_restart(fep->netdev, fep->full_duplex); 1072 fec_restart(fep->netdev, fep->full_duplex);
1072 netif_wake_queue(fep->netdev); 1073 netif_wake_queue(fep->netdev);
1074 rtnl_unlock();
1073 } 1075 }
1074 1076
1075 if (fep->delay_work.trig_tx) { 1077 if (fep->delay_work.trig_tx) {
@@ -2680,11 +2682,14 @@ fec_suspend(struct device *dev)
2680 struct net_device *ndev = dev_get_drvdata(dev); 2682 struct net_device *ndev = dev_get_drvdata(dev);
2681 struct fec_enet_private *fep = netdev_priv(ndev); 2683 struct fec_enet_private *fep = netdev_priv(ndev);
2682 2684
2685 rtnl_lock();
2683 if (netif_running(ndev)) { 2686 if (netif_running(ndev)) {
2684 phy_stop(fep->phy_dev); 2687 phy_stop(fep->phy_dev);
2685 fec_stop(ndev); 2688 fec_stop(ndev);
2686 netif_device_detach(ndev); 2689 netif_device_detach(ndev);
2687 } 2690 }
2691 rtnl_unlock();
2692
2688 fec_enet_clk_enable(ndev, false); 2693 fec_enet_clk_enable(ndev, false);
2689 pinctrl_pm_select_sleep_state(&fep->pdev->dev); 2694 pinctrl_pm_select_sleep_state(&fep->pdev->dev);
2690 2695
@@ -2712,11 +2717,13 @@ fec_resume(struct device *dev)
2712 if (ret) 2717 if (ret)
2713 goto failed_clk; 2718 goto failed_clk;
2714 2719
2720 rtnl_lock();
2715 if (netif_running(ndev)) { 2721 if (netif_running(ndev)) {
2716 fec_restart(ndev, fep->full_duplex); 2722 fec_restart(ndev, fep->full_duplex);
2717 netif_device_attach(ndev); 2723 netif_device_attach(ndev);
2718 phy_start(fep->phy_dev); 2724 phy_start(fep->phy_dev);
2719 } 2725 }
2726 rtnl_unlock();
2720 2727
2721 return 0; 2728 return 0;
2722 2729