UPSTREAM: stmmac: do not sleep in atomic context for mdio_reset
authorVincent Palatin <vpalatin@chromium.org>
Wed, 1 Jun 2016 15:53:48 +0000 (08:53 -0700)
committerHuang, Tao <huangtao@rock-chips.com>
Mon, 4 Jul 2016 10:01:40 +0000 (18:01 +0800)
stmmac_mdio_reset() has been updated to use msleep rather udelay
(as some PHY requires a one second delay there).
It called from stmmac_resume() within the spin_lock_irqsave block
atomic context triggering 'scheduling while atomic'.

The stmmac_priv lock usage is not fully documented, but it seems
to protect the access to the MAC registers / DMA structures rather
than the MDIO bus or the PHY (which have separate locking),
so we can push the spin_lock after the stmmac_mdio_reset call.

Change-Id: I0e8a0f7e798f89678d59eefdfd251f217c00787e
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
(cherry picked from commit f55d84b07c4e7340473a25dc82b462607578402c)

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

index a5b869eb46783e338708f93c31f33524116e637f..81ef9202a3672382c52fee4af9f92ad9bdf9ac67 100644 (file)
@@ -3080,8 +3080,6 @@ int stmmac_resume(struct net_device *ndev)
        if (!netif_running(ndev))
                return 0;
 
        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
        /* 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
@@ -3089,7 +3087,9 @@ int stmmac_resume(struct net_device *ndev)
         * from another devices (e.g. serial console).
         */
        if (device_may_wakeup(priv->device)) {
         * 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);
                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);
                priv->irq_wake = 0;
        } else {
                pinctrl_pm_select_default_state(priv->device);
@@ -3103,6 +3103,8 @@ int stmmac_resume(struct net_device *ndev)
 
        netif_device_attach(ndev);
 
 
        netif_device_attach(ndev);
 
+       spin_lock_irqsave(&priv->lock, flags);
+
        priv->cur_rx = 0;
        priv->dirty_rx = 0;
        priv->dirty_tx = 0;
        priv->cur_rx = 0;
        priv->dirty_rx = 0;
        priv->dirty_tx = 0;