[openwrt/openwrt] ramips: fix MT7621 switch driver IRQ storm on init with linux 4.14

LEDE Commits lede-commits at lists.infradead.org
Wed Feb 21 05:47:23 PST 2018


nbd pushed a commit to openwrt/openwrt.git, branch master:
https://git.lede-project.org/8a59f9590e0b79f5ec6620a9e8534224e96db9a4

commit 8a59f9590e0b79f5ec6620a9e8534224e96db9a4
Author: Felix Fietkau <nbd at nbd.name>
AuthorDate: Wed Feb 21 14:45:48 2018 +0100

    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 at nbd.name>
---
 .../ramips/files-4.14/drivers/net/ethernet/mtk/gsw_mt7621.c   | 11 +++++++----
 1 file 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 ef0b79e..c9fea0c 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;
 }
 



More information about the lede-commits mailing list