From: Koichiro Den <den@valinux.co.jp>
To: "Marek Vasut" <marek.vasut+renesas@mailbox.org>,
"Geert Uytterhoeven" <geert+renesas@glider.be>,
"Yoshihiro Shimoda" <yoshihiro.shimoda.uh@renesas.com>,
"Lorenzo Pieralisi" <lpieralisi@kernel.org>,
"Krzysztof Wilczyński" <kwilczynski@kernel.org>,
"Manivannan Sadhasivam" <mani@kernel.org>,
"Rob Herring" <robh@kernel.org>,
"Bjorn Helgaas" <bhelgaas@google.com>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"Magnus Damm" <magnus.damm@gmail.com>,
"Jingoo Han" <jingoohan1@gmail.com>
Cc: Philipp Zabel <p.zabel@pengutronix.de>,
Frank Li <Frank.Li@nxp.com>, Niklas Cassel <cassel@kernel.org>,
Wilfred Mallawa <wilfred.mallawa@wdc.com>,
Serge Semin <fancer.lancer@gmail.com>,
linux-pci@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v3 11/18] PCI: rcar-gen4: Take over the iMSI-RX interrupt
Date: Tue, 6 Oct 2026 17:46:31 +0900 [thread overview]
Message-ID: <20261006084638.3821710-12-den@valinux.co.jp> (raw)
In-Reply-To: <20261006084638.3821710-1-den@valinux.co.jp>
On R-Car Gen4 SoCs, intreq_pcim_sub ("msi") carries more than the
integrated MSI receiver: the controller's reset requests and the Root
Port's PME and bandwidth notifications are signalled on the same line,
and the following patches need to handle them. With the DesignWare core
owning the line through its chained handler, the driver would have to
hook into that handler when iMSI-RX is used and request the line itself
otherwise.
Instead, request the interrupt in the driver in all configurations and
set pp->msi_irq[0] to -ENODEV so the core does not install its chained
handler, as spear13xx, keembay and dra7xx do. The handler demultiplexes
the MSIs through dw_handle_msi_irq() when the APP block reports
msi_ctrl_int, in hard IRQ context like the chained handler did. With an
external MSI controller or pci=nomsi the iMSI-RX is not set up, so keep
msi_ctrl_int masked, and the handler has nothing to do there yet.
Request the interrupt in probe with IRQF_NO_AUTOEN and enable it at the
end of .init(), before endpoint drivers can use MSIs from their probe.
Disable it in .deinit(), before the controller is powered down, and
around a Root Port reset, as the handler reads the controller registers.
Suspend and resume go through the same two callbacks.
The DT routes downstream INTx to the same line, but the driver has never
supported INTx (no INTx domain, INTx enables never set), so requesting
the line exclusively takes nothing away.
Signed-off-by: Koichiro Den <den@valinux.co.jp>
---
Changes in v3:
- Request the IRQ in probe with IRQF_NO_AUTOEN, so a failure does not
toggle PERST#, and enable it in .init().
- Keep the IRQ registered across suspend/resume, disabling it in
.deinit() and re-enabling it in .init(). This fixes the unbalanced
enable Geert reported when combining v2 with the PM ops patch:
https://lore.kernel.org/CAMuHMdXoKFCroL1d6-fLwYR0UkLBL7suKy=rOFavioLd7rC4OA@mail.gmail.com/
- Stop the handler in .deinit() while the DWC MSI domain is still
alive, which the previous patch makes possible. This closes the
known gap noted in v2.
- Request the IRQ with devm. The handler is stopped in .deinit(), so
releasing the IRQ at driver detach is no longer too late.
- Revise the commit message.
v2: https://lore.kernel.org/r/20260928165230.3397664-11-den@valinux.co.jp/
drivers/pci/controller/dwc/pcie-rcar-gen4.c | 79 ++++++++++++++++++++-
1 file changed, 78 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
index 54260e62293b..d51c0fc5ff36 100644
--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
@@ -115,6 +115,8 @@ struct rcar_gen4_pcie {
struct platform_device *pdev;
struct reset_control *perst;
const struct rcar_gen4_pcie_drvdata *drvdata;
+ /* intreq_pcim_sub ("msi"): iMSI-RX and other controller notifications */
+ int msi_irq;
/*
* The controller needs reinitializing; the APP interrupt sources
* stay masked until a reset succeeds.
@@ -540,13 +542,14 @@ static int rcar_gen4_pcie_host_msi_addr(struct dw_pcie_rp *pp, u32 *msi_addr)
static void rcar_gen4_pcie_app_irq_sync_locked(struct rcar_gen4_pcie *rcar)
{
+ struct dw_pcie_rp *pp = &rcar->dw.pp;
u32 val;
lockdep_assert_held(&rcar->app_lock);
val = readl(rcar->base + PCIEINTSTS0EN);
val &= ~MSI_CTRL_INT;
- if (!rcar->reinit_pending && pci_msi_enabled())
+ if (!rcar->reinit_pending && pp->use_imsi_rx && pci_msi_enabled())
val |= MSI_CTRL_INT;
writel(val, rcar->base + PCIEINTSTS0EN);
}
@@ -613,6 +616,54 @@ static int rcar_gen4_pcie_host_msi_init(struct dw_pcie_rp *pp)
return ret;
}
+/*
+ * intreq_pcim_sub carries the iMSI-RX interrupt along with other controller
+ * notifications, so the driver owns it instead of the DesignWare core (see
+ * pp->msi_irq[0]) and demultiplexes the MSIs itself.
+ */
+static irqreturn_t rcar_gen4_pcie_msi_irq_handler(int irq, void *data)
+{
+ struct rcar_gen4_pcie *rcar = data;
+ u32 status;
+
+ status = readl(rcar->base + PCIEINTSTS0) &
+ readl(rcar->base + PCIEINTSTS0EN);
+ if (!(status & MSI_CTRL_INT))
+ return IRQ_NONE;
+
+ dw_handle_msi_irq(&rcar->dw.pp);
+
+ return IRQ_HANDLED;
+}
+
+static int rcar_gen4_pcie_msi_irq_init(struct rcar_gen4_pcie *rcar)
+{
+ struct device *dev = rcar->dw.dev;
+ int irq, ret;
+
+ irq = platform_get_irq_byname(rcar->pdev, "msi");
+ if (irq < 0)
+ return irq;
+
+ /*
+ * Child IRQ flow handlers require local IRQs to be disabled. Keep this
+ * handler in hard IRQ context on PREEMPT_RT.
+ *
+ * Keep the IRQ registered for the lifetime of the driver. .init()
+ * enables it once the controller is set up, and .deinit() disables it
+ * before the controller is powered down.
+ */
+ ret = devm_request_irq(dev, irq, rcar_gen4_pcie_msi_irq_handler,
+ IRQF_NO_THREAD | IRQF_NO_AUTOEN, dev_name(dev),
+ rcar);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to request \"msi\" IRQ\n");
+
+ rcar->msi_irq = irq;
+
+ return 0;
+}
+
static int rcar_gen4_pcie_enable_device(struct pci_host_bridge *bridge,
struct pci_dev *dev)
{
@@ -710,6 +761,9 @@ static void rcar_gen4_pcie_quiesce_irqs(struct rcar_gen4_pcie *rcar)
rcar->reinit_pending = true;
rcar_gen4_pcie_app_irq_sync_locked(rcar);
}
+
+ /* The MSI status lives in DBI; keep the handler away during the reset. */
+ disable_irq(rcar->msi_irq);
}
static void rcar_gen4_pcie_resume_irqs(struct rcar_gen4_pcie *rcar,
@@ -719,6 +773,8 @@ static void rcar_gen4_pcie_resume_irqs(struct rcar_gen4_pcie *rcar,
rcar->reinit_pending = !recovered;
rcar_gen4_pcie_app_irq_sync_locked(rcar);
}
+
+ enable_irq(rcar->msi_irq);
}
/*
@@ -796,6 +852,13 @@ static int rcar_gen4_pcie_host_init(struct dw_pcie_rp *pp)
if (ret)
goto err;
+ /*
+ * Undo IRQF_NO_AUTOEN at probe, or the disable in .deinit() on resume.
+ * The iMSI-RX interrupts stay disabled until dw_pcie_setup_rc(), so the
+ * handler cannot run before the MSI domain exists.
+ */
+ rcar_gen4_pcie_resume_irqs(rcar, true);
+
return 0;
err:
@@ -808,6 +871,9 @@ static void rcar_gen4_pcie_host_deinit(struct dw_pcie_rp *pp)
struct dw_pcie *dw = to_dw_pcie_from_pp(pp);
struct rcar_gen4_pcie *rcar = to_rcar_gen4_pcie(dw);
+ /* Stop the handler before asserting reset and disabling the clocks. */
+ rcar_gen4_pcie_quiesce_irqs(rcar);
+
rcar_gen4_pcie_host_perst_assert(pp, true);
rcar->drvdata->deinit(rcar);
}
@@ -820,15 +886,26 @@ static const struct dw_pcie_host_ops rcar_gen4_pcie_host_ops = {
static int rcar_gen4_add_dw_pcie_rp(struct rcar_gen4_pcie *rcar)
{
struct dw_pcie_rp *pp = &rcar->dw.pp;
+ int ret;
if (!IS_ENABLED(CONFIG_PCIE_RCAR_GEN4_HOST))
return -ENODEV;
raw_spin_lock_init(&rcar->app_lock);
+ ret = rcar_gen4_pcie_msi_irq_init(rcar);
+ if (ret)
+ return ret;
+
pp->num_vectors = MAX_MSI_IRQS;
/* Reserve an iATU window for the generic PME_Turn_Off implementation. */
pp->use_atu_msg = true;
+ /*
+ * intreq_pcim_sub ("msi") is shared with other controller
+ * notifications: the driver requests it itself and demultiplexes the
+ * iMSI-RX MSIs from its own handler.
+ */
+ pp->msi_irq[0] = -ENODEV;
pp->ops = &rcar_gen4_pcie_host_ops;
return dw_pcie_host_init(pp);
--
2.51.0
next prev parent reply other threads:[~2026-10-06 8:47 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-06 8:46 [PATCH v3 00/18] PCI: rcar-gen4: Recover from link down and route Root Port interrupts Koichiro Den
2026-10-06 8:46 ` [PATCH v3 01/18] PCI: dwc: Add Renesas to the RAS DES VSEC list Koichiro Den
2026-10-06 8:50 ` sashiko-bot
2026-10-06 8:46 ` [PATCH v3 02/18] PCI: dwc: Factor out the PORT_LINK_DEBUG1 link-up check Koichiro Den
2026-10-06 8:51 ` sashiko-bot
2026-10-06 8:46 ` [PATCH v3 03/18] PCI: rcar-gen4: Check live link status in link_up() Koichiro Den
2026-10-06 8:53 ` sashiko-bot
2026-10-06 8:46 ` [PATCH v3 04/18] dt-bindings: PCI: rcar-gen4: Add optional "aer" interrupt Koichiro Den
2026-10-06 8:52 ` sashiko-bot
2026-10-06 8:46 ` [PATCH v3 05/18] PCI: dwc: Export dw_handle_msi_irq() Koichiro Den
2026-10-06 8:51 ` sashiko-bot
2026-10-06 8:46 ` [PATCH v3 06/18] PCI: rcar-gen4: Move deinitialization helpers before SoC initialization Koichiro Den
2026-10-06 8:51 ` sashiko-bot
2026-10-06 8:46 ` [PATCH v3 07/18] PCI: rcar-gen4: Assert resets when Gen5 SoC PHY initialization fails Koichiro Den
2026-10-06 8:54 ` sashiko-bot
2026-10-06 8:46 ` [PATCH v3 08/18] PCI: rcar-gen4: Separate hardware setup from resource acquisition Koichiro Den
2026-10-06 8:50 ` sashiko-bot
2026-10-06 8:46 ` [PATCH v3 09/18] PCI: rcar-gen4: Add Root Port reset support Koichiro Den
2026-10-06 8:55 ` sashiko-bot
2026-10-06 8:46 ` [PATCH v3 10/18] PCI: dwc: Free the MSI domain after the host .deinit() callback Koichiro Den
2026-10-06 9:01 ` sashiko-bot
2026-10-06 8:46 ` Koichiro Den [this message]
2026-10-06 8:56 ` [PATCH v3 11/18] PCI: rcar-gen4: Take over the iMSI-RX interrupt sashiko-bot
2026-10-06 8:46 ` [PATCH v3 12/18] PCI: rcar-gen4: Recover the Root Port on link down Koichiro Den
2026-10-06 8:58 ` sashiko-bot
2026-10-06 8:46 ` [PATCH v3 13/18] PCI: dwc: Let glue drivers hide the Root Port MSI capabilities Koichiro Den
2026-10-06 8:51 ` sashiko-bot
2026-10-06 8:46 ` [PATCH v3 14/18] PCI: rcar-gen4: Route Root Port AER to a virtual Root Port IRQ Koichiro Den
2026-10-06 8:54 ` sashiko-bot
2026-10-06 8:46 ` [PATCH v3 15/18] PCI: rcar-gen4: Route Root Port PME and bandwidth notifications Koichiro Den
2026-10-06 8:54 ` sashiko-bot
2026-10-06 8:46 ` [PATCH v3 16/18] arm64: dts: renesas: r8a779f0: Describe the PCIe AER interrupts Koichiro Den
2026-10-06 8:52 ` sashiko-bot
2026-10-06 8:46 ` [PATCH v3 17/18] arm64: dts: renesas: r8a779g0: " Koichiro Den
2026-10-06 8:52 ` sashiko-bot
2026-10-06 8:46 ` [PATCH v3 18/18] arm64: dts: renesas: r8a779h0: Describe the PCIe AER interrupt Koichiro Den
2026-10-06 8:53 ` sashiko-bot
2026-10-08 5:45 ` [PATCH v3 00/18] PCI: rcar-gen4: Recover from link down and route Root Port interrupts Koichiro Den
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261006084638.3821710-12-den@valinux.co.jp \
--to=den@valinux.co.jp \
--cc=Frank.Li@nxp.com \
--cc=bhelgaas@google.com \
--cc=cassel@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=fancer.lancer@gmail.com \
--cc=geert+renesas@glider.be \
--cc=jingoohan1@gmail.com \
--cc=krzk+dt@kernel.org \
--cc=kwilczynski@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-renesas-soc@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=magnus.damm@gmail.com \
--cc=mani@kernel.org \
--cc=marek.vasut+renesas@mailbox.org \
--cc=p.zabel@pengutronix.de \
--cc=robh@kernel.org \
--cc=wilfred.mallawa@wdc.com \
--cc=yoshihiro.shimoda.uh@renesas.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox