From: Shawn Lin <shawn.lin@rock-chips.com>
To: Manivannan Sadhasivam <mani@kernel.org>,
Bjorn Helgaas <bhelgaas@google.com>
Cc: linux-rockchip@lists.infradead.org, linux-pci@vger.kernel.org,
Niklas Cassel <cassel@kernel.org>,
Shawn Lin <shawn.lin@rock-chips.com>
Subject: [PATCH v3 2/3] PCI: dw-rockchip: Make the INTx irq setup devm-managed
Date: Tue, 22 Sep 2026 10:37:01 +0800 [thread overview]
Message-ID: <1790044622-164744-3-git-send-email-shawn.lin@rock-chips.com> (raw)
In-Reply-To: <1790044622-164744-1-git-send-email-shawn.lin@rock-chips.com>
The irq domain and the chained handler set up by the previous commit
are resources owned by the device, but nothing releases them if probing
ever fails after they are set up, and they are not tied to the device
lifetime in any other way either.
Tie their lifetime to the device with devres: create the irq domain
with devm_irq_domain_instantiate() and uninstall the chained handler
through the rockchip_pcie_intx_chained_release() devres action. The
driver is builtin and cannot be unbound (suppress_bind_attrs), so probe
failure is the only path that ever needs this cleanup, and devres takes
care of it without sprinkling it over every error path.
Since the irq setup is the last step of rockchip_pcie_configure_rc(),
the only failure point left after the chained handler is installed is
devm_add_action_or_reset() itself, whose failure mode runs the action,
so the handler can never run against the devm-freed rockchip structure.
devres also unwinds in reverse registration order, so the handler is
always uninstalled before the domain is removed. There is no devm API
for chained handlers, hence the small devres action wrapper.
While at it, drop the now unused rockchip variable from
rockchip_pcie_host_init().
Suggested-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
This patch didn't find a suitable fix tag as it fixes an issue along with
patch 1/3, then patch 3/3 depends on it. So it might go with the whole series
into a fix branch.
Changes in v3: None
Changes in v2: None
drivers/pci/controller/dwc/pcie-dw-rockchip.c | 46 ++++++++++++++++++++-------
1 file changed, 34 insertions(+), 12 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index 8788a10..f395a66 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -114,6 +114,7 @@ struct rockchip_pcie {
struct reset_control *rst;
struct gpio_desc *rst_gpio;
struct irq_domain *irq_domain;
+ int intx_irq;
const struct rockchip_pcie_of_data *data;
bool supports_clkreq;
struct delayed_work trace_work;
@@ -188,9 +189,16 @@ static const struct irq_domain_ops intx_domain_ops = {
.map = rockchip_pcie_intx_map,
};
-static int rockchip_pcie_init_irq_domain(struct rockchip_pcie *rockchip)
+static void rockchip_pcie_intx_chained_release(void *data)
+{
+ struct rockchip_pcie *rockchip = data;
+
+ irq_set_chained_handler_and_data(rockchip->intx_irq, NULL, NULL);
+}
+
+static int rockchip_pcie_init_irq_domain(struct device *dev,
+ struct rockchip_pcie *rockchip)
{
- struct device *dev = rockchip->pci.dev;
struct device_node *intc;
intc = of_get_child_by_name(dev->of_node, "legacy-interrupt-controller");
@@ -199,12 +207,17 @@ static int rockchip_pcie_init_irq_domain(struct rockchip_pcie *rockchip)
return -EINVAL;
}
- rockchip->irq_domain = irq_domain_create_linear(of_fwnode_handle(intc), PCI_NUM_INTX,
- &intx_domain_ops, rockchip);
+ rockchip->irq_domain = devm_irq_domain_instantiate(dev,
+ &(struct irq_domain_info){
+ .fwnode = of_fwnode_handle(intc),
+ .size = PCI_NUM_INTX,
+ .ops = &intx_domain_ops,
+ .host_data = rockchip,
+ });
of_node_put(intc);
- if (!rockchip->irq_domain) {
+ if (IS_ERR(rockchip->irq_domain)) {
dev_err(dev, "failed to get a INTx IRQ domain\n");
- return -EINVAL;
+ return PTR_ERR(rockchip->irq_domain);
}
return 0;
@@ -731,18 +744,27 @@ static int rockchip_pcie_configure_rc(struct platform_device *pdev,
* which is also re-run by .reset_root_port(), so that the INTx irq
* domain is only created once, at probe time.
*/
- irq = of_irq_get_byname(dev->of_node, "legacy");
- if (irq < 0)
- return irq;
+ rockchip->intx_irq = of_irq_get_byname(dev->of_node, "legacy");
+ if (rockchip->intx_irq < 0)
+ return rockchip->intx_irq;
- ret = rockchip_pcie_init_irq_domain(rockchip);
+ ret = rockchip_pcie_init_irq_domain(dev, rockchip);
if (ret < 0) {
dev_err(dev, "failed to init irq domain\n");
return ret;
}
- irq_set_chained_handler_and_data(irq, rockchip_pcie_intx_handler,
- rockchip);
+ irq_set_chained_handler_and_data(rockchip->intx_irq,
+ rockchip_pcie_intx_handler, rockchip);
+
+ /*
+ * Uninstall the chained handler on probe failure, so that it can
+ * never run against the devm-freed rockchip structure.
+ */
+ ret = devm_add_action_or_reset(dev, rockchip_pcie_intx_chained_release,
+ rockchip);
+ if (ret)
+ return ret;
/* unmask hot reset/link-down reset */
val = FIELD_PREP_WM16(PCIE_LINK_REQ_RST_NOT_INT, 0);
--
2.7.4
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
next prev parent reply other threads:[~2026-09-22 2:42 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-22 2:36 [PATCH v3 0/3] Small INTx fixes for Rockchip's dwc based PCIe controller driver Shawn Lin
2026-09-22 2:37 ` [PATCH v3 1/3] PCI: dw-rockchip: Move the INTx irq setup to probe Shawn Lin
2026-09-22 9:56 ` Niklas Cassel
2026-09-22 2:37 ` Shawn Lin [this message]
2026-09-22 9:58 ` [PATCH v3 2/3] PCI: dw-rockchip: Make the INTx irq setup devm-managed Niklas Cassel
2026-09-22 2:37 ` [PATCH v3 3/3] PCI: dw-rockchip: Mask the INTx IRQ while the controller clocks are gated Shawn Lin
2026-09-23 9:13 ` [PATCH v3 0/3] Small INTx fixes for Rockchip's dwc based PCIe controller driver Diederik de Haas
2026-09-23 9:21 ` Shawn Lin
2026-09-23 15:25 ` Niklas Cassel
2026-09-24 3:27 ` Shawn Lin
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=1790044622-164744-3-git-send-email-shawn.lin@rock-chips.com \
--to=shawn.lin@rock-chips.com \
--cc=bhelgaas@google.com \
--cc=cassel@kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-rockchip@lists.infradead.org \
--cc=mani@kernel.org \
/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