From 6d7cc1fdfafd9aff00f5a71dfab650a3a9dd7306 Mon Sep 17 00:00:00 2001 From: Vincent Palatin Date: Wed, 1 Jun 2016 08:53:48 -0700 Subject: [PATCH] UPSTREAM: stmmac: do not sleep in atomic context for mdio_reset 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 Signed-off-by: David S. Miller Signed-off-by: Huang, Tao (cherry picked from commit f55d84b07c4e7340473a25dc82b462607578402c) --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index a5b869eb4678..81ef9202a367 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3080,8 +3080,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 @@ -3089,7 +3087,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); @@ -3103,6 +3103,8 @@ int stmmac_resume(struct net_device *ndev) netif_device_attach(ndev); + spin_lock_irqsave(&priv->lock, flags); + priv->cur_rx = 0; priv->dirty_rx = 0; priv->dirty_tx = 0; -- 2.34.1