[PATCH 04/11] PCI: dwc: Add a host op to run before iMSI-RX status is read

From: Koichiro Den

Date: Thu Sep 17 2026 - 23:22:52 EST


Some SoCs multiplex the integrated MSI receiver interrupt and other
notifications on the same interrupt line. On R-Car Gen4, the
intreq_pcim_sub interrupt carries both iMSI-RX MSI status and
controller reset-request notifications.

The generic chained handler reads the MSI status from DBI as soon as the
interrupt fires. That is a problem when the same line also signals a
link down: on R-Car Gen4, DBI accesses issued right after an unexpected
link down stall the host for a while, and the controller then has to be
reset before DBI can be used again. The glue driver needs to look at its
own status first and keep the generic handler away from DBI until the
controller has been recovered.

Add a host callback invoked from the chained handler before the MSI
status is read. Returning true skips MSI handling for that invocation.

Signed-off-by: Koichiro Den <den@xxxxxxxxxxxxx>
---
drivers/pci/controller/dwc/pcie-designware-host.c | 3 ++-
drivers/pci/controller/dwc/pcie-designware.h | 7 +++++++
2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index f5a38e6fd8d7..ad013dd0a166 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -95,7 +95,8 @@ static void dw_chained_msi_isr(struct irq_desc *desc)
chained_irq_enter(chip, desc);

pp = irq_desc_get_handler_data(desc);
- dw_handle_msi_irq(pp);
+ if (!pp->ops->pre_msi_irq || !pp->ops->pre_msi_irq(pp))
+ dw_handle_msi_irq(pp);

chained_irq_exit(chip, desc);
}
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index a53ac27cd244..947b16086979 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -438,6 +438,13 @@ struct dw_pcie_host_ops {
void (*deinit)(struct dw_pcie_rp *pp);
void (*post_init)(struct dw_pcie_rp *pp);
int (*msi_init)(struct dw_pcie_rp *pp);
+ /*
+ * Called from the chained iMSI-RX interrupt handler before the MSI
+ * status is read from DBI. Return true to skip MSI handling for this
+ * invocation, e.g. when the glue driver has detected a link down
+ * after which DBI must not be accessed.
+ */
+ bool (*pre_msi_irq)(struct dw_pcie_rp *pp);
void (*pme_turn_off)(struct dw_pcie_rp *pp);
};

--
2.51.0