aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ramips
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@nbd.name>2018-02-21 14:45:48 +0100
committerFelix Fietkau <nbd@nbd.name>2018-02-21 14:46:45 +0100
commit8a59f9590e0b79f5ec6620a9e8534224e96db9a4 (patch)
tree537a734dcf7fbcaac7d4cfd930a98e8bd2f4eee2 /target/linux/ramips
parent04052051405c2835aecf9c4d539bc6ed4e05878d (diff)
downloadupstream-8a59f9590e0b79f5ec6620a9e8534224e96db9a4.tar.gz
upstream-8a59f9590e0b79f5ec6620a9e8534224e96db9a4.tar.bz2
upstream-8a59f9590e0b79f5ec6620a9e8534224e96db9a4.zip
ramips: fix MT7621 switch driver IRQ storm on init with linux 4.14
The hardware emits some interrupts while initializing and handling them can mess up the state or cause infinite loops. Fix this by disabling IRQs during init and re-enabling them afterwards Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'target/linux/ramips')
-rw-r--r--target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/gsw_mt7621.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/gsw_mt7621.c b/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/gsw_mt7621.c
index ef0b79e09d..c9fea0caa2 100644
--- a/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/gsw_mt7621.c
+++ b/target/linux/ramips/files-4.14/drivers/net/ethernet/mtk/gsw_mt7621.c
@@ -41,6 +41,7 @@ static irqreturn_t gsw_interrupt_mt7621(int irq, void *_priv)
u32 reg, i;
reg = mt7530_mdio_r32(gsw, 0x700c);
+ mt7530_mdio_w32(gsw, 0x700c, reg);
for (i = 0; i < 5; i++)
if (reg & BIT(i)) {
@@ -61,7 +62,6 @@ static irqreturn_t gsw_interrupt_mt7621(int irq, void *_priv)
}
mt7620_handle_carrier(priv);
- mt7530_mdio_w32(gsw, 0x700c, 0x1f);
return IRQ_HANDLED;
}
@@ -193,9 +193,8 @@ static void mt7621_hw_init(struct mt7620_gsw *gsw, struct device_node *np)
_mt7620_mii_write(gsw, i, 0, val);
}
- /* mask irq */
- mt7530_mdio_w32(gsw, 0x7008, 0x1f);
/* enable irq */
+ mt7530_mdio_w32(gsw, 0x7008, 0x1f);
val = mt7530_mdio_r32(gsw, 0x7808);
val |= 3 << 16;
mt7530_mdio_w32(gsw, 0x7808, val);
@@ -225,10 +224,14 @@ int mtk_gsw_init(struct fe_priv *priv)
if (gsw->irq) {
request_irq(gsw->irq, gsw_interrupt_mt7621, 0,
"gsw", priv);
- mt7530_mdio_w32(gsw, 0x7008, ~0x1f);
+ disable_irq(gsw->irq);
}
+
mt7621_hw_init(gsw, np);
+ if (gsw->irq)
+ enable_irq(gsw->irq);
+
return 0;
}