mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
net: stmmac: dwmac4: mask interrupts when stopping DMA in suspend
Since commit1b9707e6f1("net: stmmac: enable RPS and RBU interrupts"), suspending causes an interrupt storm from the RPS interrupt. Fix this by adding a deinit_chan() op to stmmac_dma_ops, which masks all default dma channel interrupts. This is called from stmmac_stop_all_dma(), so interrupts don't trigger while suspending. Fixes:1b9707e6f1("net: stmmac: enable RPS and RBU interrupts") Suggested-by: Andrew Lunn <andrew@lunn.ch> Suggested-by: Maxime Chevallier <maxime.chevallier@bootlin.com> Signed-off-by: Luis Lang <luis.la@mail.de> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Tested-by: Maxime Chevallier <maxime.chevallier@bootlin.com> Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com> Link: https://patch.msgid.link/20260720111534.163416-1-luis.la@mail.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
da2c6bcc5e
commit
59a57128ae
|
|
@ -106,6 +106,17 @@ static void dwmac4_dma_init_channel(struct stmmac_priv *priv,
|
|||
ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
|
||||
}
|
||||
|
||||
static void dwmac4_dma_deinit_channel(struct stmmac_priv *priv,
|
||||
void __iomem *ioaddr, u32 chan)
|
||||
{
|
||||
const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
|
||||
u32 value;
|
||||
|
||||
value = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
|
||||
value &= ~DMA_CHAN_INTR_DEFAULT_MASK;
|
||||
writel(value, ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
|
||||
}
|
||||
|
||||
static void dwmac410_dma_init_channel(struct stmmac_priv *priv,
|
||||
void __iomem *ioaddr,
|
||||
struct stmmac_dma_cfg *dma_cfg, u32 chan)
|
||||
|
|
@ -125,6 +136,17 @@ static void dwmac410_dma_init_channel(struct stmmac_priv *priv,
|
|||
ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
|
||||
}
|
||||
|
||||
static void dwmac410_dma_deinit_channel(struct stmmac_priv *priv,
|
||||
void __iomem *ioaddr, u32 chan)
|
||||
{
|
||||
const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
|
||||
u32 value;
|
||||
|
||||
value = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
|
||||
value &= ~DMA_CHAN_INTR_DEFAULT_MASK_4_10;
|
||||
writel(value, ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
|
||||
}
|
||||
|
||||
static void dwmac4_dma_init(void __iomem *ioaddr,
|
||||
struct stmmac_dma_cfg *dma_cfg)
|
||||
{
|
||||
|
|
@ -548,6 +570,7 @@ const struct stmmac_dma_ops dwmac4_dma_ops = {
|
|||
.reset = dwmac4_dma_reset,
|
||||
.init = dwmac4_dma_init,
|
||||
.init_chan = dwmac4_dma_init_channel,
|
||||
.deinit_chan = dwmac4_dma_deinit_channel,
|
||||
.init_rx_chan = dwmac4_dma_init_rx_chan,
|
||||
.init_tx_chan = dwmac4_dma_init_tx_chan,
|
||||
.axi = dwmac4_dma_axi,
|
||||
|
|
@ -577,6 +600,7 @@ const struct stmmac_dma_ops dwmac410_dma_ops = {
|
|||
.reset = dwmac4_dma_reset,
|
||||
.init = dwmac4_dma_init,
|
||||
.init_chan = dwmac410_dma_init_channel,
|
||||
.deinit_chan = dwmac410_dma_deinit_channel,
|
||||
.init_rx_chan = dwmac4_dma_init_rx_chan,
|
||||
.init_tx_chan = dwmac4_dma_init_tx_chan,
|
||||
.axi = dwmac4_dma_axi,
|
||||
|
|
|
|||
|
|
@ -170,6 +170,8 @@ struct stmmac_dma_ops {
|
|||
void (*init)(void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg);
|
||||
void (*init_chan)(struct stmmac_priv *priv, void __iomem *ioaddr,
|
||||
struct stmmac_dma_cfg *dma_cfg, u32 chan);
|
||||
void (*deinit_chan)(struct stmmac_priv *priv, void __iomem *ioaddr,
|
||||
u32 chan);
|
||||
void (*init_rx_chan)(struct stmmac_priv *priv, void __iomem *ioaddr,
|
||||
struct stmmac_dma_cfg *dma_cfg,
|
||||
dma_addr_t phy, u32 chan);
|
||||
|
|
@ -235,6 +237,8 @@ struct stmmac_dma_ops {
|
|||
stmmac_do_void_callback(__priv, dma, init, __args)
|
||||
#define stmmac_init_chan(__priv, __args...) \
|
||||
stmmac_do_void_callback(__priv, dma, init_chan, __priv, __args)
|
||||
#define stmmac_deinit_chan(__priv, __args...) \
|
||||
stmmac_do_void_callback(__priv, dma, deinit_chan, __priv, __args)
|
||||
#define stmmac_init_rx_chan(__priv, __args...) \
|
||||
stmmac_do_void_callback(__priv, dma, init_rx_chan, __priv, __args)
|
||||
#define stmmac_init_tx_chan(__priv, __args...) \
|
||||
|
|
|
|||
|
|
@ -2560,6 +2560,7 @@ static void stmmac_stop_all_dma(struct stmmac_priv *priv)
|
|||
{
|
||||
u8 rx_channels_count = priv->plat->rx_queues_to_use;
|
||||
u8 tx_channels_count = priv->plat->tx_queues_to_use;
|
||||
u8 dma_csr_ch = max(rx_channels_count, tx_channels_count);
|
||||
u8 chan;
|
||||
|
||||
for (chan = 0; chan < rx_channels_count; chan++)
|
||||
|
|
@ -2567,6 +2568,9 @@ static void stmmac_stop_all_dma(struct stmmac_priv *priv)
|
|||
|
||||
for (chan = 0; chan < tx_channels_count; chan++)
|
||||
stmmac_stop_tx_dma(priv, chan);
|
||||
|
||||
for (chan = 0; chan < dma_csr_ch; chan++)
|
||||
stmmac_deinit_chan(priv, priv->ioaddr, chan);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user