[PATCH] PCI: iproc: Fix MSI shutdown operations

Eugen Hristev ehristev at kernel.org
Thu Oct 29 00:25:19 PDT 2026


On reboot, shutting down iPROC leaves MSI irqs enabled and not
cleaned up. This can lead to IRQs being served after the iPROC
was shutdown.
Fix it by implementing an MSI shutdown procedure, and call it
before the iPROC shutdown.

Assisted-by: Github Copilot
Fixes: 3bc2b2348835 ("PCI: iproc: Add iProc PCIe MSI support")
Signed-off-by: Eugen Hristev <ehristev at kernel.org>
---
 drivers/pci/controller/pcie-iproc-msi.c | 16 ++++++++++++++++
 drivers/pci/controller/pcie-iproc.c     |  3 +++
 drivers/pci/controller/pcie-iproc.h     |  4 ++++
 3 files changed, 23 insertions(+)

diff --git a/drivers/pci/controller/pcie-iproc-msi.c b/drivers/pci/controller/pcie-iproc-msi.c
index 9ba242ab9596..1d19db67f314 100644
--- a/drivers/pci/controller/pcie-iproc-msi.c
+++ b/drivers/pci/controller/pcie-iproc-msi.c
@@ -651,6 +651,22 @@ int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node)
 }
 EXPORT_SYMBOL(iproc_msi_init);
 
+void iproc_msi_shutdown(struct iproc_pcie *pcie)
+{
+	struct iproc_msi *msi = pcie->msi;
+	unsigned int index;
+
+	if (!msi)
+		return;
+
+	iproc_msi_disable(msi);
+	iproc_msi_read_reg(msi, IPROC_MSI_CTRL, msi->nr_irqs - 1);
+
+	for (index = 0; index < msi->nr_irqs; index++)
+		disable_irq(msi->grps[index].gic_irq);
+}
+EXPORT_SYMBOL(iproc_msi_shutdown);
+
 void iproc_msi_exit(struct iproc_pcie *pcie)
 {
 	struct iproc_msi *msi = pcie->msi;
diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/pcie-iproc.c
index afb3aa38ac6b..6f3dc2f81a1c 100644
--- a/drivers/pci/controller/pcie-iproc.c
+++ b/drivers/pci/controller/pcie-iproc.c
@@ -756,8 +756,11 @@ static void iproc_pcie_perst_ctrl(struct iproc_pcie *pcie, bool assert)
 
 int iproc_pcie_shutdown(struct iproc_pcie *pcie)
 {
+	dev_dbg(pcie->dev, "quiescing MSI before PCIe reset\n");
+	iproc_msi_shutdown(pcie);
 	iproc_pcie_perst_ctrl(pcie, true);
 	msleep(500);
+	dev_dbg(pcie->dev, "PCIe shutdown complete\n");
 
 	return 0;
 }
diff --git a/drivers/pci/controller/pcie-iproc.h b/drivers/pci/controller/pcie-iproc.h
index c4443f236ca3..54e6e365774e 100644
--- a/drivers/pci/controller/pcie-iproc.h
+++ b/drivers/pci/controller/pcie-iproc.h
@@ -114,6 +114,7 @@ int iproc_pcie_shutdown(struct iproc_pcie *pcie);
 
 #ifdef CONFIG_PCIE_IPROC_MSI
 int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node);
+void iproc_msi_shutdown(struct iproc_pcie *pcie);
 void iproc_msi_exit(struct iproc_pcie *pcie);
 #else
 static inline int iproc_msi_init(struct iproc_pcie *pcie,
@@ -121,6 +122,9 @@ static inline int iproc_msi_init(struct iproc_pcie *pcie,
 {
 	return -ENODEV;
 }
+static inline void iproc_msi_shutdown(struct iproc_pcie *pcie)
+{
+}
 static inline void iproc_msi_exit(struct iproc_pcie *pcie)
 {
 }

---
base-commit: 6d0933ae9d46674a6ea63a87e9e9ab4e662670c9
change-id: 20261029-iproc-shutdown-abbbce302daa

Best regards,
--  
Eugen Hristev <ehristev at kernel.org>




More information about the linux-arm-kernel mailing list