Skip to contentSkip to conversation

rework IRQ handling in mtk_eth_soc

PATCH Superseded Frank Wunderlich 3 participants 7 messages Jun 15, 2025

Subsystems (4)

v3 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

v3 cover rework IRQ handling in mtk_eth_soc

From: Frank Wunderlich <[email protected]>

This series introduces named IRQs while keeping the index based way for older dts.
Further it makes some cleanup like adding consts for index access and avoids loading first IRQ which was not used on non SHARED_INT SoCs.

Frank Wunderlich (3):
net: ethernet: mtk_eth_soc: support named IRQs
net: ethernet: mtk_eth_soc: add consts for irq index
net: ethernet: mtk_eth_soc: change code to skip first IRQ completely

 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 56 ++++++++++++++-------
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  5 ++
 2 files changed, 44 insertions(+), 17 deletions(-)
Signature · 1 line
2.43.0
#1 lore raw

PATCH v3 1/3 net: ethernet: mtk_eth_soc: support named IRQs

From: Frank Wunderlich <[email protected]>

Add named interrupts and keep index based fallback for exiting devicetrees.

Currently only rx and tx IRQs are defined to be used with mt7988, but later extended with RSS/LRO support.

---
v2:
- move irqs loading part into own helper function
- reduce indentation
- place mtk_get_irqs helper before the irq_handler (note for simon)

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 39 +++++++++++++++------
 1 file changed, 28 insertions(+), 11 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +28 -11
index b38e4f2de674..f91ea87d2f72 100644
@@ -3336,6 +3336,30 @@ static void mtk_tx_timeout(struct net_device *dev, unsigned int txqueue)
 	schedule_work(&eth->pending_work);
 }
 
+static int mtk_get_irqs(struct platform_device *pdev, struct mtk_eth *eth)
+{
+	int i;
+
+	eth->irq[1] = platform_get_irq_byname(pdev, "tx");
+	eth->irq[2] = platform_get_irq_byname(pdev, "rx");
+	if (eth->irq[1] >= 0 && eth->irq[2] >= 0)
+		return 0;
+
+	for (i = 0; i < 3; i++) {
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0)
+			eth->irq[i] = eth->irq[0];
+		else
+			eth->irq[i] = platform_get_irq(pdev, i);
+
+		if (eth->irq[i] < 0) {
+			dev_err(&pdev->dev, "no IRQ%d resource found\n", i);
+			return -ENXIO;
+		}
+	}
+
+	return 0;
+}
+
 static irqreturn_t mtk_handle_irq_rx(int irq, void *_eth)
 {
 	struct mtk_eth *eth = _eth;
@@ -5105,17 +5129,10 @@ static int mtk_probe(struct platform_device *pdev)
 		}
 	}
 
-	for (i = 0; i < 3; i++) {
-		if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0)
-			eth->irq[i] = eth->irq[0];
-		else
-			eth->irq[i] = platform_get_irq(pdev, i);
-		if (eth->irq[i] < 0) {
-			dev_err(&pdev->dev, "no IRQ%d resource found\n", i);
-			err = -ENXIO;
-			goto err_wed_exit;
-		}
-	}
+	err = mtk_get_irqs(pdev, eth);
+	if (err)
+		goto err_wed_exit;
+
 	for (i = 0; i < ARRAY_SIZE(eth->clks); i++) {
 		eth->clks[i] = devm_clk_get(eth->dev,
 					    mtk_clks_source_name[i]);
Signature · 1 line
2.43.0
#2 lore raw

PATCH v3 2/3 net: ethernet: mtk_eth_soc: add consts for irq index

In reply to Frank Wunderlich

From: Frank Wunderlich <[email protected]>

Use consts instead of fixed integers for accessing IRQ array.

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 22 ++++++++++-----------
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  5 +++++
 2 files changed, 16 insertions(+), 11 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +11 -11
index f91ea87d2f72..9aec67c9c6d7 100644
@@ -3340,14 +3340,14 @@ static int mtk_get_irqs(struct platform_device *pdev, struct mtk_eth *eth)
 {
 	int i;
 
-	eth->irq[1] = platform_get_irq_byname(pdev, "tx");
-	eth->irq[2] = platform_get_irq_byname(pdev, "rx");
-	if (eth->irq[1] >= 0 && eth->irq[2] >= 0)
+	eth->irq[MTK_ETH_IRQ_TX] = platform_get_irq_byname(pdev, "tx");
+	eth->irq[MTK_ETH_IRQ_RX] = platform_get_irq_byname(pdev, "rx");
+	if (eth->irq[MTK_ETH_IRQ_TX] >= 0 && eth->irq[MTK_ETH_IRQ_RX] >= 0)
 		return 0;
 
-	for (i = 0; i < 3; i++) {
+	for (i = 0; i < MTK_ETH_IRQ_MAX; i++) {
 		if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0)
-			eth->irq[i] = eth->irq[0];
+			eth->irq[i] = eth->irq[MTK_ETH_IRQ_SHARED];
 		else
 			eth->irq[i] = platform_get_irq(pdev, i);
 
@@ -3413,7 +3413,7 @@ static void mtk_poll_controller(struct net_device *dev)
 
 	mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
 	mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask);
-	mtk_handle_irq_rx(eth->irq[2], dev);
+	mtk_handle_irq_rx(eth->irq[MTK_ETH_IRQ_RX], dev);
 	mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
 	mtk_rx_irq_enable(eth, eth->soc->rx.irq_done_mask);
 }
@@ -4899,7 +4899,7 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 	eth->netdev[id]->features |= eth->soc->hw_features;
 	eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops;
 
-	eth->netdev[id]->irq = eth->irq[0];
+	eth->netdev[id]->irq = eth->irq[MTK_ETH_IRQ_SHARED];
 	eth->netdev[id]->dev.of_node = np;
 
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
@@ -5176,17 +5176,17 @@ static int mtk_probe(struct platform_device *pdev)
 	}
 
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) {
-		err = devm_request_irq(eth->dev, eth->irq[0],
+		err = devm_request_irq(eth->dev, eth->irq[MTK_ETH_IRQ_SHARED],
 				       mtk_handle_irq, 0,
 				       dev_name(eth->dev), eth);
 	} else {
-		err = devm_request_irq(eth->dev, eth->irq[1],
+		err = devm_request_irq(eth->dev, eth->irq[MTK_ETH_IRQ_TX],
 				       mtk_handle_irq_tx, 0,
 				       dev_name(eth->dev), eth);
 		if (err)
 			goto err_free_dev;
 
-		err = devm_request_irq(eth->dev, eth->irq[2],
+		err = devm_request_irq(eth->dev, eth->irq[MTK_ETH_IRQ_RX],
 				       mtk_handle_irq_rx, 0,
 				       dev_name(eth->dev), eth);
 	}
@@ -5232,7 +5232,7 @@ static int mtk_probe(struct platform_device *pdev)
 		} else
 			netif_info(eth, probe, eth->netdev[i],
 				   "mediatek frame engine at 0x%08lx, irq %d\n",
-				   eth->netdev[i]->base_addr, eth->irq[0]);
+				   eth->netdev[i]->base_addr, eth->irq[MTK_ETH_IRQ_SHARED]);
 	}
 
 	/* we run 2 devices on the same DMA ring so we need a dummy device
drivers/net/ethernet/mediatek/mtk_eth_soc.h +5 -0
index 6f72a8c8ae1e..6b1208d05f79 100644
@@ -642,6 +642,11 @@
 
 #define MTK_MAC_FSM(x)		(0x1010C + ((x) * 0x100))
 
+#define MTK_ETH_IRQ_SHARED	0
+#define MTK_ETH_IRQ_TX		1
+#define MTK_ETH_IRQ_RX		2
+#define MTK_ETH_IRQ_MAX		3
+
 struct mtk_rx_dma {
 	unsigned int rxd1;
 	unsigned int rxd2;
Signature · 1 line
2.43.0
#3 lore raw

PATCH v3 3/3 net: ethernet: mtk_eth_soc: change code to skip first IRQ completely

In reply to Frank Wunderlich

From: Frank Wunderlich <[email protected]>

On SoCs without MTK_SHARED_INT capability (mt7621 + mt7628) the first IRQ (eth->irq[0]) was read but never used. Skip reading it now too.

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 ++++++++---
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  4 ++--
 2 files changed, 10 insertions(+), 5 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +8 -3
index 9aec67c9c6d7..4d7de282b940 100644
@@ -3346,10 +3346,15 @@ static int mtk_get_irqs(struct platform_device *pdev, struct mtk_eth *eth)
 		return 0;
 
 	for (i = 0; i < MTK_ETH_IRQ_MAX; i++) {
-		if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0)
-			eth->irq[i] = eth->irq[MTK_ETH_IRQ_SHARED];
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) {
+			if (i == 0)
+				eth->irq[MTK_ETH_IRQ_SHARED] = platform_get_irq(pdev, i);
+			else
+				eth->irq[i] = eth->irq[MTK_ETH_IRQ_SHARED];
+		} else if (i < 2)  //skip the 1st and 4th IRQ on !MTK_SHARED_INT
+			eth->irq[i] = platform_get_irq(pdev, i + 1);
 		else
-			eth->irq[i] = platform_get_irq(pdev, i);
+			continue;
 
 		if (eth->irq[i] < 0) {
 			dev_err(&pdev->dev, "no IRQ%d resource found\n", i);
drivers/net/ethernet/mediatek/mtk_eth_soc.h +2 -2
index 6b1208d05f79..ff2ae3c80179 100644
@@ -643,8 +643,8 @@
 #define MTK_MAC_FSM(x)		(0x1010C + ((x) * 0x100))
 
 #define MTK_ETH_IRQ_SHARED	0
-#define MTK_ETH_IRQ_TX		1
-#define MTK_ETH_IRQ_RX		2
+#define MTK_ETH_IRQ_TX		0
+#define MTK_ETH_IRQ_RX		1
 #define MTK_ETH_IRQ_MAX		3
 
 struct mtk_rx_dma {
Signature · 1 line
2.43.0
#4 lore raw

Re: [net-next v3 3/3] net: ethernet: mtk_eth_soc: change code to skip first IRQ completely

Quoted 17 lines · Frank Wunderlich

From: Frank Wunderlich <[email protected]>

On SoCs without MTK_SHARED_INT capability (mt7621 + mt7628) the first IRQ (eth->irq[0]) was read but never used. Skip reading it now too.

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 ++++++++---
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  4 ++--
 2 files changed, 10 insertions(+), 5 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +0 -0
index 9aec67c9c6d7..4d7de282b940 100644
@@ -3346,10 +3346,15 @@ static int mtk_get_irqs(struct platform_device *pdev, struct mtk_eth *eth)
 		return 0;

drivers/net/ethernet/mediatek/mtk_eth_soc.c static int mtk_get_irqs(struct platform_device *pdev, struct mtk_eth *eth) · line 3354

Quoted 10 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c +6 -2
 
 	for (i = 0; i < MTK_ETH_IRQ_MAX; i++) {
-		if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0)
-			eth->irq[i] = eth->irq[MTK_ETH_IRQ_SHARED];
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) {
+			if (i == 0)
+				eth->irq[MTK_ETH_IRQ_SHARED] = platform_get_irq(pdev, i);
+			else
+				eth->irq[i] = eth->irq[MTK_ETH_IRQ_SHARED];
+		} else if (i < 2)  //skip the 1st and 4th IRQ on !MTK_SHARED_INT

Please use conformant comment style, ie. do not use '//' but always use '/* ... */' instead, on a dedicated line.

Quoted 12 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c +2 -1
+			eth->irq[i] = platform_get_irq(pdev, i + 1);
 		else
-			eth->irq[i] = platform_get_irq(pdev, i);
+			continue;
 
 		if (eth->irq[i] < 0) {
 			dev_err(&pdev->dev, "no IRQ%d resource found\n", i);
drivers/net/ethernet/mediatek/mtk_eth_soc.h +0 -0
index 6b1208d05f79..ff2ae3c80179 100644

drivers/net/ethernet/mediatek/mtk_eth_soc.h line 648

Quoted 8 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.h +2 -2
@@ -643,8 +643,8 @@
 #define MTK_MAC_FSM(x)		(0x1010C + ((x) * 0x100))
 
 #define MTK_ETH_IRQ_SHARED	0
-#define MTK_ETH_IRQ_TX		1
-#define MTK_ETH_IRQ_RX		2
+#define MTK_ETH_IRQ_TX		0
+#define MTK_ETH_IRQ_RX		1
 #define MTK_ETH_IRQ_MAX		3

Shouldn't MAX be 1 now?

#5 lore raw

Re: [net-next v3 3/3] net: ethernet: mtk_eth_soc: change code to skip first IRQ completely

Am 15. Juni 2025 21:49:43 MESZ schrieb Daniel Golle <[email protected]>:

Quoted 19 lines · Frank Wunderlich
Quoted 18 lines

From: Frank Wunderlich <[email protected]>

On SoCs without MTK_SHARED_INT capability (mt7621 + mt7628) the first IRQ (eth->irq[0]) was read but never used. Skip reading it now too.

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 ++++++++---
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  4 ++--
 2 files changed, 10 insertions(+), 5 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +0 -0
index 9aec67c9c6d7..4d7de282b940 100644
@@ -3346,10 +3346,15 @@ static int mtk_get_irqs(struct platform_device *pdev, struct mtk_eth *eth)
 		return 0;
 
Quoted 12 lines

drivers/net/ethernet/mediatek/mtk_eth_soc.c static int mtk_get_irqs(struct platform_device *pdev, struct mtk_eth *eth) · line 3354

Quoted 9 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c +6 -2
 	for (i = 0; i < MTK_ETH_IRQ_MAX; i++) {
-		if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0)
-			eth->irq[i] = eth->irq[MTK_ETH_IRQ_SHARED];
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) {
+			if (i == 0)
+				eth->irq[MTK_ETH_IRQ_SHARED] = platform_get_irq(pdev, i);
+			else
+				eth->irq[i] = eth->irq[MTK_ETH_IRQ_SHARED];
+		} else if (i < 2)  //skip the 1st and 4th IRQ on !MTK_SHARED_INT

Please use conformant comment style, ie. do not use '//' but always use '/* ... */' instead, on a dedicated line.

Ok,not sure if the comment should stay :) It was a comment for me and i forgot to remove it.

Quoted 14 lines
Quoted 14 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.c +2 -1
+			eth->irq[i] = platform_get_irq(pdev, i + 1);
 		else
-			eth->irq[i] = platform_get_irq(pdev, i);
+			continue;
 
 		if (eth->irq[i] < 0) {
 			dev_err(&pdev->dev, "no IRQ%d resource found\n", i);
drivers/net/ethernet/mediatek/mtk_eth_soc.h +0 -0
index 6b1208d05f79..ff2ae3c80179 100644
@@ -643,8 +643,8 @@
 #define MTK_MAC_FSM(x)		(0x1010C + ((x) * 0x100))
 
Quoted 8 lines

drivers/net/ethernet/mediatek/mtk_eth_soc.h line 648

Quoted 6 lines
drivers/net/ethernet/mediatek/mtk_eth_soc.h +2 -2
 #define MTK_ETH_IRQ_SHARED	0
-#define MTK_ETH_IRQ_TX		1
-#define MTK_ETH_IRQ_RX		2
+#define MTK_ETH_IRQ_TX		0
+#define MTK_ETH_IRQ_RX		1
 #define MTK_ETH_IRQ_MAX		3

Shouldn't MAX be 1 now?

No as we still need to loop over the first 3 irqs on the older devicetrees. Or was the MAX intented for anything else (e.g. array size for storing the sw irqs - not changed this yet,but imho thi should be 2 now if SHARED_INT does not need 3 entries)?

regards Frank

#6 lore raw
In reply to Frank Wunderlich
Quoted 2 lines

Gesendet: Sonntag, 15. Juni 2025 um 17:03
Von: "Frank Wunderlich" <[email protected]>

sorry, missed the changelog:

v3:
added patches
- #2 (add constants for irq index)
- #3 (skip first IRQ on ! MTK_SHARED_INT)
to the v2 non-series patch

https://patchwork.kernel.org/project/netdevbpf/patch/[email protected]/

Tested on BPI-R4/mt7988 with IRQ names and BPI-R2/mt7623 and BPI-R3/mt7986 with upstreamed dts via index-mode.
I do not have any MTK_SHARED_INT (mt7621/mt7628) boards to testing.