Re: [PATCH v4 13/18] PCI: dwc: Let glue drivers hide the Root Port MSI capabilities
From: Koichiro Den
Date: Thu Oct 15 2026 - 03:18:39 EST
On Thu, Oct 15, 2026 at 12:11:45PM +0800, Shawn Lin wrote:
> Hi Koichiro
>
> 在 2026/10/15 星期四 11:30, Koichiro Den 写道:
> > Commit f5cd8a929c82 ("PCI: dwc: Remove MSI/MSIX capability for Root Port
> > if iMSI-RX is used as MSI controller") hides the Root Port MSI/MSI-X
> > capabilities when iMSI-RX is the MSI controller, as it cannot receive
> > the Root Port's own MSIs.
> >
> > Some platforms cannot deliver them with an external MSI controller
> > either. The DesignWare core signals Root Port interrupts (AER, PME,
> > bandwidth, hotplug) as sideband signals on its SII interface and only
> > turns them into MSI writes with the optional SII2MSI feature. Otherwise
> > it is up to the vendor wrapper. The controller on R-Car Gen4 SoCs
> > (DWC 5.20a) appears to lack SII2MSI, and its APP block merely latches
> > the signals into status registers wired to platform IRQs, so an MSI
> > targeted at the GIC ITS is never sent.
> >
> > Add a no_rp_msi flag so glue drivers can request the same INTx fallback
> > regardless of the MSI controller in use. It is the counterpart of
> > 'keep_rp_msi_en' from commit 3a4e8302e72f ("PCI: imx6: Keep Root Port
> > MSI capability with iMSI-RX to work around hardware bug"), which keeps
> > precedence: that one is needed for endpoint MSIs to work at all, whereas
> > hiding the capability only moves the Root Port services to INTx. The
> > removal stays in dw_pcie_setup_rc(), which also runs after a Root Port
> > reset.
> >
>
> With it, dw_pcie_rp will carry three flags with overlapping and
> priority-dependent semantics:
>
> use_imsi_rx - the MSI controller is iMSI-RX
> keep_rp_msi_en - do NOT remove the RP MSI caps (i.MX6 workaround)
> no_rp_msi - the platform never gets the RP's own MSIs
>
> and the resulting condition:
>
> if ((pp->use_imsi_rx || pp->no_rp_msi) && !pp->keep_rp_msi_en)
>
> is getting hard to reason about. Adding no_rp_msi for a single platform
> whose controller is not even iMSI-RX makes the combination worse.
>
> Since only R-Car Gen4 needs this, and it has its own host init, would it
> be fine for the glue driver to call dw_pcie_remove_capability()
> directly? I'd like to avoid growing the shared struct if a local
> solution is possible.
That makes sense. Let me respin and add dw_pcie_remove_capability() calls
to pcie-rcar-gen4.c's host_setup(), with a short comment.
Then I'll drop this patch ([PATCH v4 13/18]).
Thanks for the review!
Best regards,
Koichiro Den
>
> > Signed-off-by: Koichiro Den <den@xxxxxxxxxxxxx>
> > ---
> > Changes since v3:
> > - No changes.
> >
> > drivers/pci/controller/dwc/pcie-designware-host.c | 6 ++++--
> > drivers/pci/controller/dwc/pcie-designware.h | 1 +
> > 2 files changed, 5 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > index 774e1936d999..32e179603cf4 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -1191,9 +1191,11 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
> > * The iMSI-RX module does not support receiving MSI or MSI-X generated
> > * by the Root Port. If iMSI-RX is used as the MSI controller, remove
> > * the MSI and MSI-X capabilities of the Root Port to allow the drivers
> > - * to fall back to INTx instead.
> > + * to fall back to INTx instead. Glue drivers set no_rp_msi when the
> > + * platform never delivers the Root Port's own MSIs, whatever the MSI
> > + * controller in use.
> > */
> > - if (pp->use_imsi_rx && !pp->keep_rp_msi_en) {
> > + if ((pp->use_imsi_rx || pp->no_rp_msi) && !pp->keep_rp_msi_en) {
> > dw_pcie_remove_capability(pci, PCI_CAP_ID_MSI);
> > dw_pcie_remove_capability(pci, PCI_CAP_ID_MSIX);
> > }
> > diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> > index 2ce61709b58c..d94116402b74 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware.h
> > +++ b/drivers/pci/controller/dwc/pcie-designware.h
> > @@ -445,6 +445,7 @@ struct dw_pcie_host_ops {
> > struct dw_pcie_rp {
> > bool use_imsi_rx:1;
> > bool keep_rp_msi_en:1;
> > + bool no_rp_msi:1;
> > bool cfg0_io_shared:1;
> > u64 cfg0_base;
> > void __iomem *va_cfg0_base;
>