[PATCH v4 3/3] PCI: imx6: Add root port reset to support link recovery
Hongxing Zhu
hongxing.zhu at nxp.com
Wed May 13 00:41:03 PDT 2026
> -----Original Message-----
> From: Bough Chen <haibo.chen at nxp.com>
> Sent: Wednesday, May 13, 2026 11:32 AM
> To: Hongxing Zhu <hongxing.zhu at nxp.com>; robh at kernel.org;
> krzk+dt at kernel.org; conor+dt at kernel.org; bhelgaas at google.com; Frank Li
> <frank.li at nxp.com>; l.stach at pengutronix.de; lpieralisi at kernel.org;
> kwilczynski at kernel.org; mani at kernel.org; s.hauer at pengutronix.de;
> kernel at pengutronix.de; festevam at gmail.com
> Cc: linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> devicetree at vger.kernel.org; imx at lists.linux.dev; linux-kernel at vger.kernel.org;
> Hongxing Zhu <hongxing.zhu at nxp.com>
> Subject: RE: [PATCH v4 3/3] PCI: imx6: Add root port reset to support link
> recovery
>
> > -----Original Message-----
> > From: Richard Zhu <hongxing.zhu at nxp.com>
> > Sent: 2026年5月13日 10:51
> > To: robh at kernel.org; krzk+dt at kernel.org; conor+dt at kernel.org;
> > bhelgaas at google.com; Frank Li <frank.li at nxp.com>;
> > l.stach at pengutronix.de; lpieralisi at kernel.org; kwilczynski at kernel.org;
> > mani at kernel.org; s.hauer at pengutronix.de; kernel at pengutronix.de;
> > festevam at gmail.com
> > Cc: linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > devicetree at vger.kernel.org; imx at lists.linux.dev;
> > linux-kernel at vger.kernel.org; Hongxing Zhu <hongxing.zhu at nxp.com>
> > Subject: [PATCH v4 3/3] PCI: imx6: Add root port reset to support link
> > recovery
> >
> > The PCIe link can go down due to various unexpected circumstances. Add
> > root port reset support to enable link recovery for the i.MX PCIe
> > controller when the optional "intr" interrupt is present.
> >
> > Reset root port to uninitialize, initialize the PCIe controller, and
> > restart the PCIe link at end when a link down event happens.
> >
> > On i.MX95 platforms, link events and PME share the same interrupt line.
> > The link event interrupt cannot use a threaded-only IRQ handler
> > because the PME driver uses request_irq() with only the IRQF_SHARED
> > flag set, which requires a primary handler.
> >
> > To handle this shared interrupt scenario, register a primary interrupt
> > handler with IRQF_SHARED for link events and manipulate the link event
> > enable bits to ensure the shared interrupt source triggers only one handler at a
> time.
> >
> > Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
> > ---
> > drivers/pci/controller/dwc/pci-imx6.c | 123
> > ++++++++++++++++++++++++++
> > 1 file changed, 123 insertions(+)
> >
> > diff --git a/drivers/pci/controller/dwc/pci-imx6.c
> > b/drivers/pci/controller/dwc/pci-imx6.c
> > index 1034ac5c5f5c..79c92c77b85b 100644
> > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > @@ -34,6 +34,7 @@
> > #include <linux/pm_runtime.h>
> >
> > #include "../../pci.h"
> > +#include "../pci-host-common.h"
> > #include "pcie-designware.h"
> >
> > #define IMX8MQ_GPR_PCIE_REF_USE_PAD BIT(9)
> > @@ -78,6 +79,10 @@
> > #define IMX95_SID_MASK GENMASK(5, 0)
> > #define IMX95_MAX_LUT 32
> >
> > +#define IMX95_LINK_INT_CTRL_STS 0x1040
> > +#define IMX95_LINK_DOWN_INT_STS BIT(11)
> > +#define IMX95_LINK_DOWN_INT_EN BIT(10)
> > +
> > #define IMX95_PCIE_RST_CTRL 0x3010
> > #define IMX95_PCIE_COLD_RST BIT(0)
> >
> > @@ -125,6 +130,8 @@ enum imx_pcie_variants {
> > #define IMX_PCIE_MAX_INSTANCES 2
> >
> > struct imx_pcie;
> > +static int imx_pcie_reset_root_port(struct pci_host_bridge *bridge,
> > + struct pci_dev *pdev);
> >
> > struct imx_pcie_drvdata {
> > enum imx_pcie_variants variant;
> > @@ -158,6 +165,7 @@ struct imx_pcie {
> > bool supports_clkreq;
> > bool enable_ext_refclk;
> > struct regmap *iomuxc_gpr;
> > + u32 lnk_intr;
> > u16 msi_ctrl;
> > u32 controller_id;
> > struct reset_control *pciephy_reset;
> > @@ -1301,6 +1309,13 @@ static int imx_pcie_host_init(struct dw_pcie_rp
> > *pp)
> >
> > imx_setup_phy_mpll(imx_pcie);
> >
> > + /*
> > + * Callback invoked by PCI core when link down is detected and
> > + * recovery is needed.
> > + */
> > + if (pp->bridge)
> > + pp->bridge->reset_root_port = imx_pcie_reset_root_port;
> > +
> > return 0;
> >
> > err_phy_off:
> > @@ -1568,6 +1583,9 @@ static int imx_pcie_suspend_noirq(struct device
> > *dev)
> > if (!(imx_pcie->drvdata->flags & IMX_PCIE_FLAG_SUPPORTS_SUSPEND))
> > return 0;
> >
> > + if (imx_pcie->lnk_intr)
> > + regmap_clear_bits(imx_pcie->iomuxc_gpr,
> > IMX95_LINK_INT_CTRL_STS,
> > + IMX95_LINK_DOWN_INT_EN);
> > imx_pcie_msi_save_restore(imx_pcie, true);
> > if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT))
> > imx_pcie_lut_save(imx_pcie);
> > @@ -1618,6 +1636,9 @@ static int imx_pcie_resume_noirq(struct device *dev)
> > if (imx_check_flag(imx_pcie, IMX_PCIE_FLAG_HAS_LUT))
> > imx_pcie_lut_restore(imx_pcie);
> > imx_pcie_msi_save_restore(imx_pcie, false);
> > + if (imx_pcie->lnk_intr)
> > + regmap_set_bits(imx_pcie->iomuxc_gpr,
> IMX95_LINK_INT_CTRL_STS,
> > + IMX95_LINK_DOWN_INT_EN);
> >
> > return 0;
> > }
> > @@ -1627,6 +1648,84 @@ static const struct dev_pm_ops imx_pcie_pm_ops
> > = {
> > imx_pcie_resume_noirq)
> > };
> >
> > +static irqreturn_t imx_pcie_lnk_irq_isr(int irq, void *priv) {
> > + struct imx_pcie *imx_pcie = priv;
> > + struct dw_pcie *pci = imx_pcie->pci;
> > + struct device *dev = pci->dev;
> > + u32 val;
> > +
> > + regmap_read(imx_pcie->iomuxc_gpr, IMX95_LINK_INT_CTRL_STS, &val);
> > + if (val & IMX95_LINK_DOWN_INT_STS) {
> > + dev_dbg(dev, "PCIe link down detected, initiating recovery\n");
> > + regmap_clear_bits(imx_pcie->iomuxc_gpr,
> > IMX95_LINK_INT_CTRL_STS,
> > + IMX95_LINK_DOWN_INT_EN);
> > + regmap_set_bits(imx_pcie->iomuxc_gpr,
> IMX95_LINK_INT_CTRL_STS,
> > + IMX95_LINK_DOWN_INT_STS);
>
> Hi Richard
>
> Better to add comment here to point out that write the
> IMX95_LINK_DOWN_INT_STS means clear this bit, or mention this bit is W1C.
Okay, would add the comment later. Thanks.
Best Regards
Richard Zhu
>
> Regards
> Haibo Chen
More information about the linux-arm-kernel
mailing list