stmmac: do not sleep in atomic context while suspend/resume
[firefly-linux-kernel-4.4.55.git] / drivers / net / ethernet / stmicro / stmmac / stmmac_main.c
index 3c6549aee11dee5cf13c92c90c5b4b7a8618f375..13e02c375708840e10e318104c576d3a1f2d3b68 100644 (file)
@@ -1745,9 +1745,11 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
        }
 
 #ifdef CONFIG_DEBUG_FS
-       ret = stmmac_init_fs(dev);
-       if (ret < 0)
-               pr_warn("%s: failed debugFS registration\n", __func__);
+       if (init_ptp) {
+               ret = stmmac_init_fs(dev);
+               if (ret < 0)
+                       pr_warn("%s: failed debugFS registration\n", __func__);
+       }
 #endif
        /* Start the ball rolling... */
        pr_debug("%s: DMA RX/TX processes started...\n", dev->name);
@@ -3035,19 +3037,17 @@ int stmmac_suspend(struct net_device *ndev)
        if (priv->phydev)
                phy_stop(priv->phydev);
 
-       spin_lock_irqsave(&priv->lock, flags);
-
        netif_device_detach(ndev);
        netif_stop_queue(ndev);
 
        napi_disable(&priv->napi);
 
+       spin_lock_irqsave(&priv->lock, flags);
+
        /* Stop TX/RX DMA */
        priv->hw->dma->stop_tx(priv->ioaddr);
        priv->hw->dma->stop_rx(priv->ioaddr);
 
-       stmmac_clear_descriptors(priv);
-
        /* Enable Power down mode by programming the PMT regs */
        if (device_may_wakeup(priv->device)) {
                priv->hw->mac->pmt(priv->hw, priv->wolopts);
@@ -3082,8 +3082,6 @@ int stmmac_resume(struct net_device *ndev)
        if (!netif_running(ndev))
                return 0;
 
-       spin_lock_irqsave(&priv->lock, flags);
-
        /* Power Down bit, into the PM register, is cleared
         * automatically as soon as a magic packet or a Wake-up frame
         * is received. Anyway, it's better to manually clear
@@ -3091,7 +3089,9 @@ int stmmac_resume(struct net_device *ndev)
         * from another devices (e.g. serial console).
         */
        if (device_may_wakeup(priv->device)) {
+               spin_lock_irqsave(&priv->lock, flags);
                priv->hw->mac->pmt(priv->hw, 0);
+               spin_unlock_irqrestore(&priv->lock, flags);
                priv->irq_wake = 0;
        } else {
                pinctrl_pm_select_default_state(priv->device);
@@ -3105,7 +3105,14 @@ int stmmac_resume(struct net_device *ndev)
 
        netif_device_attach(ndev);
 
-       init_dma_desc_rings(ndev, GFP_ATOMIC);
+       spin_lock_irqsave(&priv->lock, flags);
+
+       priv->cur_rx = 0;
+       priv->dirty_rx = 0;
+       priv->dirty_tx = 0;
+       priv->cur_tx = 0;
+       stmmac_clear_descriptors(priv);
+
        stmmac_hw_setup(ndev, false);
        stmmac_init_tx_coalesce(priv);
        stmmac_set_rx_mode(ndev);