[PATCH] PCI: mediatek: Free IRQ domains while freeing Root Ports

Manivannan Sadhasivam manivannan.sadhasivam at oss.qualcomm.com
Thu May 21 00:19:07 PDT 2026


Currently, the driver frees the IRQ domains only during driver remove().
But when mtk_pcie_enable_port() fails for some reason, the domains are
not freed. This leads to resource leakage.

Hence, free the IRQ domains inside mtk_pcie_port_free() helper which gets
called in the error path of mtk_pcie_enable_port() and also during driver
removal.

This issue was flagged by Sashiko when reviewing the EcoNet EN7528 SoC
support series.

Cc: stable at vger.kernel.org # 5.10
Cc: Caleb James DeLisle <cjd at cjdns.fr>
Fixes: b099631df160 ("PCI: mediatek: Add controller support for MT2712 and MT7622")
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam at oss.qualcomm.com>
---
 drivers/pci/controller/pcie-mediatek.c | 35 +++++++++++---------------
 1 file changed, 14 insertions(+), 21 deletions(-)

diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
index c503fbd774d0..c45baf681cf5 100644
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -250,6 +250,20 @@ static void mtk_pcie_port_free(struct mtk_pcie_port *port)
 	struct mtk_pcie *pcie = port->pcie;
 	struct device *dev = pcie->dev;
 
+	if (port->irq) {
+		irq_set_chained_handler_and_data(port->irq, NULL, NULL);
+
+		if (port->irq_domain)
+			irq_domain_remove(port->irq_domain);
+
+		if (IS_ENABLED(CONFIG_PCI_MSI)) {
+			if (port->inner_domain)
+				irq_domain_remove(port->inner_domain);
+		}
+
+		irq_dispose_mapping(port->irq);
+	}
+
 	devm_iounmap(dev, port->base);
 	list_del(&port->list);
 	devm_kfree(dev, port);
@@ -531,25 +545,6 @@ static void mtk_pcie_enable_msi(struct mtk_pcie_port *port)
 	writel(val, port->base + PCIE_INT_MASK);
 }
 
-static void mtk_pcie_irq_teardown(struct mtk_pcie *pcie)
-{
-	struct mtk_pcie_port *port, *tmp;
-
-	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
-		irq_set_chained_handler_and_data(port->irq, NULL, NULL);
-
-		if (port->irq_domain)
-			irq_domain_remove(port->irq_domain);
-
-		if (IS_ENABLED(CONFIG_PCI_MSI)) {
-			if (port->inner_domain)
-				irq_domain_remove(port->inner_domain);
-		}
-
-		irq_dispose_mapping(port->irq);
-	}
-}
-
 static int mtk_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
 			     irq_hw_number_t hwirq)
 {
@@ -1186,8 +1181,6 @@ static void mtk_pcie_remove(struct platform_device *pdev)
 	pci_remove_root_bus(host->bus);
 	mtk_pcie_free_resources(pcie);
 
-	mtk_pcie_irq_teardown(pcie);
-
 	mtk_pcie_put_resources(pcie);
 }
 
-- 
2.51.0




More information about the Linux-mediatek mailing list