Devicetree
 help / color / mirror / Atom feed
From: Koichiro Den <den@valinux.co.jp>
To: "Marek Vasut" <marek.vasut+renesas@mailbox.org>,
	"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>,
	"Geert Uytterhoeven" <geert+renesas@glider.be>,
	"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 v2 10/15] PCI: rcar-gen4: Take over the iMSI-RX interrupt
Date: Tue, 29 Sep 2026 01:52:25 +0900	[thread overview]
Message-ID: <20260928165230.3397664-11-den@valinux.co.jp> (raw)
In-Reply-To: <20260928165230.3397664-1-den@valinux.co.jp>

On R-Car Gen4, 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. With an external MSI controller or pci=nomsi the iMSI-RX
is not set up, so keep msi_ctrl_int masked rather than enabled, and the
handler has nothing to do there yet. Request the interrupt before
enumeration, as endpoint drivers may use MSIs from their probe, with
IRQF_NO_THREAD so the MSIs are demultiplexed in hard IRQ context like
the chained handler did. The interrupt is required by the binding.

Release the interrupt in .deinit, before asserting the controller reset
and disabling its clocks. Disable it around a Root Port reset because
the handler accesses the MSI status registers through DBI.

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 v2:
  - New patch. Owning the interrupt in both MSI configurations, as
    suggested by Marek, replaces the pre_msi_irq host op and the
    two-path handling of v1. (Marek)
  - Rename sub_irq to msi_irq to avoid confusion with a child IRQ. In the
    complete series, pcie-rcar-gen4.c uses these names:
      * DT "msi" IRQ: msi_irq (was named sub_irq in v1, after
	                       intreq_pcim_sub)
      * DT "aer" IRQ: aer_irq
      * Virtual Root Port IRQ: rp_irq

Known gap spotted while preparing v2:
  - dw_pcie_host_deinit() frees the iMSI-RX domain before .deinit, so a
    parent handler already past the APP status check can still reach it.
    Not specific to this driver: spear13xx, keembay and dra7xx own their
    parent IRQ the same way (no .remove, so probe unwind only), and
    dw_pcie_free_msi() does not synchronize the core's own chained
    handler either. I believe this needs a common DWC core fix letting
    glue drivers stop the parent IRQ before the domain goes. That would
    require each driver review and testing, so I left it out of scope.

 drivers/pci/controller/dwc/pcie-rcar-gen4.c | 75 ++++++++++++++++++++-
 1 file changed, 72 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
index d3f04358bbe3..256410fb4b1c 100644
--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
@@ -116,6 +116,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.
@@ -556,13 +558,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);
 }
@@ -627,6 +630,52 @@ 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.
+	 *
+	 * Release the IRQ in .deinit before asserting reset and disabling the
+	 * clocks. Automatic devres cleanup would be too late.
+	 */
+	ret = request_irq(irq, rcar_gen4_pcie_msi_irq_handler, IRQF_NO_THREAD,
+			  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)
 {
@@ -724,6 +773,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,
@@ -733,6 +785,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);
 }
 
 /*
@@ -804,11 +858,17 @@ static int rcar_gen4_pcie_host_init(struct dw_pcie_rp *pp)
 
 	ret = rcar_gen4_pcie_host_setup(pp);
 	if (ret)
-		goto err;
+		goto err_deinit;
+
+	ret = rcar_gen4_pcie_msi_irq_init(rcar);
+	if (ret)
+		goto err_assert_perst;
 
 	return 0;
 
-err:
+err_assert_perst:
+	rcar_gen4_pcie_host_perst_assert(pp, true);
+err_deinit:
 	rcar->drvdata->deinit(rcar);
 	return ret;
 }
@@ -818,6 +878,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. */
+	free_irq(rcar->msi_irq, rcar);
+
 	rcar_gen4_pcie_host_perst_assert(pp, true);
 	rcar->drvdata->deinit(rcar);
 }
@@ -842,6 +905,12 @@ static int rcar_gen4_add_dw_pcie_rp(struct rcar_gen4_pcie *rcar)
 	raw_spin_lock_init(&rcar->app_lock);
 
 	pp->num_vectors = MAX_MSI_IRQS;
+	/*
+	 * 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


  parent reply	other threads:[~2026-09-28 16:53 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-28 16:52 [PATCH v2 00/15] PCI: rcar-gen4: Recover from link down and route Root Port interrupts Koichiro Den
2026-09-28 16:52 ` [PATCH v2 01/15] PCI: dwc: Add Renesas to the RAS DES VSEC list Koichiro Den
2026-09-28 16:56   ` sashiko-bot
2026-09-28 16:52 ` [PATCH v2 02/15] PCI: rcar-gen4: Check live link status in link_up() Koichiro Den
2026-09-28 16:57   ` sashiko-bot
2026-10-03 18:29   ` Marek Vasut
2026-10-03 18:51     ` Marek Vasut
2026-10-05  4:22       ` Koichiro Den
2026-10-05  5:59         ` Marek Vasut
2026-09-28 16:52 ` [PATCH v2 03/15] dt-bindings: PCI: rcar-gen4: Add optional "aer" interrupt Koichiro Den
2026-09-28 16:58   ` sashiko-bot
2026-09-30 10:31   ` Krzysztof Kozlowski
2026-10-03 20:00   ` Marek Vasut
2026-09-28 16:52 ` [PATCH v2 04/15] PCI: dwc: Export dw_handle_msi_irq() Koichiro Den
2026-09-28 16:58   ` sashiko-bot
2026-10-03 20:02   ` Marek Vasut
2026-09-28 16:52 ` [PATCH v2 05/15] PCI: rcar-gen4: Move deinitialization helpers before SoC initialization Koichiro Den
2026-09-28 16:57   ` sashiko-bot
2026-10-03 20:23   ` Marek Vasut
2026-09-28 16:52 ` [PATCH v2 06/15] PCI: rcar-gen4: Assert resets when Gen5 PHY initialization fails Koichiro Den
2026-09-28 16:59   ` sashiko-bot
2026-10-03 21:34   ` Marek Vasut
2026-09-28 16:52 ` [PATCH v2 07/15] PCI: rcar-gen4: Separate hardware setup from resource acquisition Koichiro Den
2026-09-28 16:56   ` sashiko-bot
2026-10-03 23:41   ` Marek Vasut
2026-09-28 16:52 ` [PATCH v2 08/15] PCI: rcar-gen4: Add a controller reinitialization callback Koichiro Den
2026-09-28 17:02   ` sashiko-bot
2026-10-03 23:54   ` Marek Vasut
2026-10-05  4:31     ` Koichiro Den
2026-09-28 16:52 ` [PATCH v2 09/15] PCI: rcar-gen4: Add Root Port reset support Koichiro Den
2026-09-28 17:03   ` sashiko-bot
2026-10-04  0:11   ` Marek Vasut
2026-10-05  6:14     ` Koichiro Den
2026-09-28 16:52 ` Koichiro Den [this message]
2026-09-28 17:04   ` [PATCH v2 10/15] PCI: rcar-gen4: Take over the iMSI-RX interrupt sashiko-bot
2026-09-29 17:43   ` Geert Uytterhoeven
2026-09-30  6:38     ` Koichiro Den
2026-10-04  1:17       ` Marek Vasut
2026-10-04  0:53   ` Marek Vasut
2026-10-05 17:05     ` Koichiro Den
2026-09-28 16:52 ` [PATCH v2 11/15] PCI: rcar-gen4: Recover the Root Port on link down Koichiro Den
2026-09-28 17:07   ` sashiko-bot
2026-10-04  1:38   ` Marek Vasut
2026-09-28 16:52 ` [PATCH v2 12/15] PCI: dwc: Let glue drivers hide the Root Port MSI capabilities Koichiro Den
2026-09-28 16:59   ` sashiko-bot
2026-09-28 16:52 ` [PATCH v2 13/15] PCI: rcar-gen4: Route Root Port AER to a virtual Root Port IRQ Koichiro Den
2026-09-28 17:06   ` sashiko-bot
2026-10-04  2:52   ` Marek Vasut
2026-09-28 16:52 ` [PATCH v2 14/15] PCI: rcar-gen4: Route Root Port PME and bandwidth notifications Koichiro Den
2026-09-28 17:08   ` sashiko-bot
2026-10-04  4:40   ` Marek Vasut
2026-10-05 17:09     ` Koichiro Den
2026-09-28 16:52 ` [PATCH v2 15/15] arm64: dts: renesas: r8a779f0: Describe the PCIe AER interrupts Koichiro Den
2026-09-28 16:59   ` sashiko-bot
2026-10-03 20:00   ` Marek Vasut
2026-10-05 17:11     ` Koichiro Den
2026-10-06  5:20       ` Marek Vasut
2026-10-03 17:46 ` [PATCH v2 00/15] PCI: rcar-gen4: Recover from link down and route Root Port interrupts Marek Vasut

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=20260928165230.3397664-11-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