提交 777da230 编写于 作者: G Giuseppe CAVALLARO 提交者: David S. Miller

stmmac: fix atomicity in pm routines

This patch is to fix the atomicity when suspend and resume the
driver. The clk api have been changed (as reported by Hao Liang)
and the skb allocation is done out of the hw setup function and
taking care about the GFP flags.
Reported-by: NHao Liang <hliang1025@gmail.com>
Signed-off-by: NGiuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexey Khoroshilov <khoroshilov@ispras.ru>
Cc: Hao Liang <hliang1025@gmail.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 4741cf9c
...@@ -964,12 +964,12 @@ static void stmmac_clear_descriptors(struct stmmac_priv *priv) ...@@ -964,12 +964,12 @@ static void stmmac_clear_descriptors(struct stmmac_priv *priv)
} }
static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p, static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p,
int i) int i, gfp_t flags)
{ {
struct sk_buff *skb; struct sk_buff *skb;
skb = __netdev_alloc_skb(priv->dev, priv->dma_buf_sz + NET_IP_ALIGN, skb = __netdev_alloc_skb(priv->dev, priv->dma_buf_sz + NET_IP_ALIGN,
GFP_KERNEL); flags);
if (!skb) { if (!skb) {
pr_err("%s: Rx init fails; skb is NULL\n", __func__); pr_err("%s: Rx init fails; skb is NULL\n", __func__);
return -ENOMEM; return -ENOMEM;
...@@ -1011,7 +1011,7 @@ static void stmmac_free_rx_buffers(struct stmmac_priv *priv, int i) ...@@ -1011,7 +1011,7 @@ static void stmmac_free_rx_buffers(struct stmmac_priv *priv, int i)
* and allocates the socket buffers. It suppors the chained and ring * and allocates the socket buffers. It suppors the chained and ring
* modes. * modes.
*/ */
static int init_dma_desc_rings(struct net_device *dev) static int init_dma_desc_rings(struct net_device *dev, gfp_t flags)
{ {
int i; int i;
struct stmmac_priv *priv = netdev_priv(dev); struct stmmac_priv *priv = netdev_priv(dev);
...@@ -1046,7 +1046,7 @@ static int init_dma_desc_rings(struct net_device *dev) ...@@ -1046,7 +1046,7 @@ static int init_dma_desc_rings(struct net_device *dev)
else else
p = priv->dma_rx + i; p = priv->dma_rx + i;
ret = stmmac_init_rx_buffers(priv, p, i); ret = stmmac_init_rx_buffers(priv, p, i, flags);
if (ret) if (ret)
goto err_init_rx_buffers; goto err_init_rx_buffers;
...@@ -1652,11 +1652,6 @@ static int stmmac_hw_setup(struct net_device *dev) ...@@ -1652,11 +1652,6 @@ static int stmmac_hw_setup(struct net_device *dev)
struct stmmac_priv *priv = netdev_priv(dev); struct stmmac_priv *priv = netdev_priv(dev);
int ret; int ret;
ret = init_dma_desc_rings(dev);
if (ret < 0) {
pr_err("%s: DMA descriptors initialization failed\n", __func__);
return ret;
}
/* DMA initialization and SW reset */ /* DMA initialization and SW reset */
ret = stmmac_init_dma_engine(priv); ret = stmmac_init_dma_engine(priv);
if (ret < 0) { if (ret < 0) {
...@@ -1710,8 +1705,6 @@ static int stmmac_hw_setup(struct net_device *dev) ...@@ -1710,8 +1705,6 @@ static int stmmac_hw_setup(struct net_device *dev)
} }
priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS; priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;
stmmac_init_tx_coalesce(priv);
if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) { if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) {
priv->rx_riwt = MAX_DMA_RIWT; priv->rx_riwt = MAX_DMA_RIWT;
priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT); priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT);
...@@ -1764,12 +1757,20 @@ static int stmmac_open(struct net_device *dev) ...@@ -1764,12 +1757,20 @@ static int stmmac_open(struct net_device *dev)
goto dma_desc_error; goto dma_desc_error;
} }
ret = init_dma_desc_rings(dev, GFP_KERNEL);
if (ret < 0) {
pr_err("%s: DMA descriptors initialization failed\n", __func__);
goto init_error;
}
ret = stmmac_hw_setup(dev); ret = stmmac_hw_setup(dev);
if (ret < 0) { if (ret < 0) {
pr_err("%s: Hw setup failed\n", __func__); pr_err("%s: Hw setup failed\n", __func__);
goto init_error; goto init_error;
} }
stmmac_init_tx_coalesce(priv);
if (priv->phydev) if (priv->phydev)
phy_start(priv->phydev); phy_start(priv->phydev);
...@@ -2953,7 +2954,7 @@ int stmmac_suspend(struct net_device *ndev) ...@@ -2953,7 +2954,7 @@ int stmmac_suspend(struct net_device *ndev)
stmmac_set_mac(priv->ioaddr, false); stmmac_set_mac(priv->ioaddr, false);
pinctrl_pm_select_sleep_state(priv->device); pinctrl_pm_select_sleep_state(priv->device);
/* Disable clock in case of PWM is off */ /* Disable clock in case of PWM is off */
clk_disable_unprepare(priv->stmmac_clk); clk_disable(priv->stmmac_clk);
} }
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
...@@ -2985,7 +2986,7 @@ int stmmac_resume(struct net_device *ndev) ...@@ -2985,7 +2986,7 @@ int stmmac_resume(struct net_device *ndev)
} else { } else {
pinctrl_pm_select_default_state(priv->device); pinctrl_pm_select_default_state(priv->device);
/* enable the clk prevously disabled */ /* enable the clk prevously disabled */
clk_prepare_enable(priv->stmmac_clk); clk_enable(priv->stmmac_clk);
/* reset the phy so that it's ready */ /* reset the phy so that it's ready */
if (priv->mii) if (priv->mii)
stmmac_mdio_reset(priv->mii); stmmac_mdio_reset(priv->mii);
...@@ -2993,7 +2994,9 @@ int stmmac_resume(struct net_device *ndev) ...@@ -2993,7 +2994,9 @@ int stmmac_resume(struct net_device *ndev)
netif_device_attach(ndev); netif_device_attach(ndev);
init_dma_desc_rings(ndev, GFP_ATOMIC);
stmmac_hw_setup(ndev); stmmac_hw_setup(ndev);
stmmac_init_tx_coalesce(priv);
napi_enable(&priv->napi); napi_enable(&priv->napi);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册