[PATCH v2 2/2] PCI: dw-rockchip: Mask the INTx IRQ while the controller clocks are gated
Shawn Lin
shawn.lin at rock-chips.com
Thu Sep 3 18:18:29 PDT 2026
.reset_root_port() gates the controller clocks and PHY before
re-initializing the hardware. Devices on the bus may keep their INTx
line asserted across this window, so the chained INTx handler can run
and read the APB registers of the unclocked controller, raising a
synchronous external abort.
Mask the INTx IRQ before turning the clocks off and re-enable it once
the clocks are running again. On the error paths the clocks stay
gated, so the IRQ is deliberately left masked there.
Fixes: b376b3ff9cb0 ("PCI: dw-rockchip: Implement .reset_root_port() and use for link down")
Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---
Changes in v2:
- keep the INTx IRQ masked while .reset_root_port()
gates the controller clocks, responding to the Sashiko review
finding about accessing the unclocked APB bus.
drivers/pci/controller/dwc/pcie-dw-rockchip.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index ecf0d7e..aee5ca8 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -434,7 +434,6 @@ static void rockchip_pcie_stop_link(struct dw_pcie *pci)
static int rockchip_pcie_host_init(struct dw_pcie_rp *pp)
{
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
- struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
pci->dbi_base2 = pci->dbi_base + PCIE_TYPE0_HDR_DBI2_OFFSET;
@@ -925,6 +924,16 @@ static int rockchip_pcie_rc_reset_root_port(struct pci_host_bridge *bridge,
u32 val;
int ret;
+ /*
+ * Devices may keep their INTx line asserted across the reset. Mask
+ * the INTx IRQ so that the chained handler does not touch the
+ * unclocked APB bus, which would raise a synchronous external abort.
+ * The IRQ is re-enabled once the clocks are restored, and is
+ * deliberately left masked on the error paths where the controller
+ * remains unclocked.
+ */
+ disable_irq(rockchip->intx_irq);
+
dw_pcie_stop_link(pci);
clk_bulk_disable_unprepare(rockchip->clk_cnt, rockchip->clks);
rockchip_pcie_phy_deinit(rockchip);
@@ -975,6 +984,7 @@ static int rockchip_pcie_rc_reset_root_port(struct pci_host_bridge *bridge,
/* Ignore errors, the link may come up later */
dw_pcie_wait_for_link(pci);
+ enable_irq(rockchip->intx_irq);
dev_dbg(dev, "Root Port reset completed\n");
return ret;
--
2.7.4
More information about the Linux-rockchip
mailing list