[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