--- /dev/null
+From 72780f7964684939d7d2f69c348876213b184484 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@orcam.me.uk>
+Date: Mon, 8 Dec 2025 19:24:29 +0000
+Subject: PCI: Always lift 2.5GT/s restriction in PCIe failed link retraining
+
+From: Maciej W. Rozycki <macro@orcam.me.uk>
+
+commit 72780f7964684939d7d2f69c348876213b184484 upstream.
+
+Discard Vendor:Device ID matching in the PCIe failed link retraining quirk
+and ignore the link status for the removal of the 2.5GT/s speed clamp,
+whether applied by the quirk itself or the firmware earlier on. Revert to
+the original target link speed if this final link retraining has failed.
+
+This is so that link training noise in hot-plug scenarios does not make a
+link remain clamped to the 2.5GT/s speed where an event race has led the
+quirk to apply the speed clamp for one device, only to leave it in place
+for a subsequent device to be plugged in.
+
+Refer to the Link Capabilities register directly for the maximum link speed
+determination so as to streamline backporting.
+
+Fixes: a89c82249c37 ("PCI: Work around PCIe link training failures")
+Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Alok Tiwari <alok.a.tiwari@oracle.com>
+Cc: stable@vger.kernel.org # v6.5+
+Link: https://patch.msgid.link/alpine.DEB.2.21.2512080331530.49654@angie.orcam.me.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/quirks.c | 51 ++++++++++++++++++---------------------------------
+ 1 file changed, 18 insertions(+), 33 deletions(-)
+
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -80,11 +80,10 @@ static bool pcie_lbms_seen(struct pci_de
+ * Restrict the speed to 2.5GT/s then with the Target Link Speed field,
+ * request a retrain and check the result.
+ *
+- * If this turns out successful and we know by the Vendor:Device ID it is
+- * safe to do so, then lift the restriction, letting the devices negotiate
+- * a higher speed. Also check for a similar 2.5GT/s speed restriction the
+- * firmware may have already arranged and lift it with ports that already
+- * report their data link being up.
++ * If this turns out successful, or where a 2.5GT/s speed restriction has
++ * been previously arranged by the firmware and the port reports its link
++ * already being up, lift the restriction, in a hope it is safe to do so,
++ * letting the devices negotiate a higher speed.
+ *
+ * Otherwise revert the speed to the original setting and request a retrain
+ * again to remove any residual state, ignoring the result as it's supposed
+@@ -95,52 +94,38 @@ static bool pcie_lbms_seen(struct pci_de
+ */
+ int pcie_failed_link_retrain(struct pci_dev *dev)
+ {
+- static const struct pci_device_id ids[] = {
+- { PCI_VDEVICE(ASMEDIA, 0x2824) }, /* ASMedia ASM2824 */
+- {}
+- };
+- u16 lnksta, lnkctl2;
++ u16 lnksta, lnkctl2, oldlnkctl2;
+ int ret = -ENOTTY;
++ u32 lnkcap;
+
+ if (!pci_is_pcie(dev) || !pcie_downstream_port(dev) ||
+ !pcie_cap_has_lnkctl2(dev) || !dev->link_active_reporting)
+ return ret;
+
+ pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
++ pcie_capability_read_word(dev, PCI_EXP_LNKCTL2, &oldlnkctl2);
+ if (!(lnksta & PCI_EXP_LNKSTA_DLLLA) && pcie_lbms_seen(dev, lnksta)) {
+- u16 oldlnkctl2;
+-
+ pci_info(dev, "broken device, retraining non-functional downstream link at 2.5GT/s\n");
+-
+- pcie_capability_read_word(dev, PCI_EXP_LNKCTL2, &oldlnkctl2);
+ ret = pcie_set_target_speed(dev, PCIE_SPEED_2_5GT, false);
+- if (ret) {
+- pci_info(dev, "retraining failed\n");
+- pcie_set_target_speed(dev, PCIE_LNKCTL2_TLS2SPEED(oldlnkctl2),
+- true);
+- return ret;
+- }
+-
+- pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
++ if (ret)
++ goto err;
+ }
+
+ pcie_capability_read_word(dev, PCI_EXP_LNKCTL2, &lnkctl2);
+-
+- if ((lnksta & PCI_EXP_LNKSTA_DLLLA) &&
+- (lnkctl2 & PCI_EXP_LNKCTL2_TLS) == PCI_EXP_LNKCTL2_TLS_2_5GT &&
+- pci_match_id(ids, dev)) {
+- u32 lnkcap;
+-
++ pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap);
++ if ((lnkctl2 & PCI_EXP_LNKCTL2_TLS) == PCI_EXP_LNKCTL2_TLS_2_5GT &&
++ (lnkcap & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) {
+ pci_info(dev, "removing 2.5GT/s downstream link speed restriction\n");
+- pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap);
+ ret = pcie_set_target_speed(dev, PCIE_LNKCAP_SLS2SPEED(lnkcap), false);
+- if (ret) {
+- pci_info(dev, "retraining failed\n");
+- return ret;
+- }
++ if (ret)
++ goto err;
+ }
+
+ return ret;
++err:
++ pci_info(dev, "retraining failed\n");
++ pcie_set_target_speed(dev, PCIE_LNKCTL2_TLS2SPEED(oldlnkctl2), true);
++ return ret;
+ }
+
+ static ktime_t fixup_debug_start(struct pci_dev *dev,
--- /dev/null
+From fda8749ba73638f5bbca3ffb39bc6861eb3b23fa Mon Sep 17 00:00:00 2001
+From: Ratheesh Kannoth <rkannoth@marvell.com>
+Date: Tue, 14 Apr 2026 13:47:30 +0530
+Subject: PCI: host-common: Request bus reassignment when not probe-only
+
+From: Ratheesh Kannoth <rkannoth@marvell.com>
+
+commit fda8749ba73638f5bbca3ffb39bc6861eb3b23fa upstream.
+
+pci_host_common_init() is used by several generic ECAM host drivers.
+After PCI core changes around pci_flags and preserve_config, these hosts
+no longer opted into full bus number reassignment the way they did
+before, which broke enumeration of devices on a Marvell CN106XX board.
+
+When PCI_PROBE_ONLY is not set, add PCI_REASSIGN_ALL_BUS so
+pci_scan_bridge_extend() takes the reassignment path: bus numbers can be
+assigned from firmware EA data (e.g. pci_ea_fixed_busnrs()). Skip the
+flag in probe-only mode so existing assignments are not overridden.
+
+Fixes: 7246a4520b4b ("PCI: Use preserve_config in place of pci_flags")
+Closes: https://lore.kernel.org/all/abkqm_LCd9zAM8cW@rkannoth-OptiPlex-7090/
+Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
+[mani: added stable tag]
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+[bhelgaas: add problem report link]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: stable@vger.kernel.org
+Cc: Vidya Sagar <vidyas@nvidia.com>
+Link: https://patch.msgid.link/20260414081730.3864372-1-rkannoth@marvell.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/pci-host-common.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/pci/controller/pci-host-common.c
++++ b/drivers/pci/controller/pci-host-common.c
+@@ -68,6 +68,10 @@ int pci_host_common_init(struct platform
+ if (IS_ERR(cfg))
+ return PTR_ERR(cfg);
+
++ /* Do not reassign bus numbers if probe only */
++ if (!pci_has_flag(PCI_PROBE_ONLY))
++ pci_add_flags(PCI_REASSIGN_ALL_BUS);
++
+ bridge->sysdata = cfg;
+ bridge->ops = (struct pci_ops *)&ops->pci_ops;
+ bridge->enable_device = ops->enable_device;
--- /dev/null
+From 9dda3f83ba677b9cc2613cecd9120123000ae50f Mon Sep 17 00:00:00 2001
+From: Richard Zhu <hongxing.zhu@nxp.com>
+Date: Mon, 18 May 2026 15:27:15 +0800
+Subject: PCI: imx6: Assert ref_clk_en after reference clock stabilizes on i.MX95
+
+From: Richard Zhu <hongxing.zhu@nxp.com>
+
+commit 9dda3f83ba677b9cc2613cecd9120123000ae50f upstream.
+
+According to the PHY Databook Common Block Signals section, the
+ref_clk_en signal must remain de-asserted until the reference clock is
+running at the appropriate frequency. Once the clock is stable,
+ref_clk_en can be asserted. For lower power states where the reference
+clock to the PHY is disabled, ref_clk_en should also be de-asserted.
+
+Move the ref_clk_en bit manipulation into imx95_pcie_enable_ref_clk()
+to ensure the reference clock stabilizes before ref_clk_en is asserted
+and before the PHY reset is de-asserted. This aligns with the timing
+requirements specified in the PHY documentation.
+
+Fixes: d8574ce57d76 ("PCI: imx6: Add external reference clock input mode support")
+Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260518072715.3166514-3-hongxing.zhu@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/dwc/pci-imx6.c | 28 ++++++++++++++++++++++------
+ 1 file changed, 22 insertions(+), 6 deletions(-)
+
+--- a/drivers/pci/controller/dwc/pci-imx6.c
++++ b/drivers/pci/controller/dwc/pci-imx6.c
+@@ -268,8 +268,6 @@ static int imx95_pcie_select_ref_clk_src
+
+ static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie)
+ {
+- bool ext = imx_pcie->enable_ext_refclk;
+-
+ /*
+ * ERR051624: The Controller Without Vaux Cannot Exit L23 Ready
+ * Through Beacon or PERST# De-assertion
+@@ -288,10 +286,6 @@ static int imx95_pcie_init_phy(struct im
+ IMX95_PCIE_PHY_CR_PARA_SEL,
+ IMX95_PCIE_PHY_CR_PARA_SEL);
+
+- regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_0,
+- IMX95_PCIE_REF_CLKEN,
+- ext ? 0 : IMX95_PCIE_REF_CLKEN);
+-
+ return 0;
+ }
+
+@@ -740,7 +734,29 @@ static void imx95_pcie_clkreq_override(s
+
+ static int imx95_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable)
+ {
++ bool ext = imx_pcie->enable_ext_refclk;
++
+ imx95_pcie_clkreq_override(imx_pcie, enable);
++ /*
++ * The ref_clk_en signal must remain de-asserted until the
++ * reference clock is running at appropriate frequency, at which
++ * point this bit can be asserted. For lower power states where
++ * the reference clock to the PHY is disabled, it may also be
++ * de-asserted.
++ * +------------------- -+--------+----------------+
++ * | External clock mode | Enable | PCIE_REF_CLKEN |
++ * +---------------------+--------+----------------+
++ * | TRUE | X | 1b'0 |
++ * +---------------------+--------+----------------+
++ * | FALSE | TRUE | 1b'1 |
++ * +---------------------+--------+----------------+
++ * | FALSE | FALSE | 1b'0 |
++ * +---------------------+--------+----------------+
++ */
++ regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_0,
++ IMX95_PCIE_REF_CLKEN,
++ ext || !enable ? 0 : IMX95_PCIE_REF_CLKEN);
++
+ return 0;
+ }
+
--- /dev/null
+From 0c26b1c34d12d4debfb5363cc0be6cdf68e87ba2 Mon Sep 17 00:00:00 2001
+From: Richard Zhu <hongxing.zhu@nxp.com>
+Date: Mon, 18 May 2026 15:27:14 +0800
+Subject: PCI: imx6: Configure REF_USE_PAD before PHY reset for i.MX95
+
+From: Richard Zhu <hongxing.zhu@nxp.com>
+
+commit 0c26b1c34d12d4debfb5363cc0be6cdf68e87ba2 upstream.
+
+According to the i.MX95 PCIe PHY Databook, the ref_use_pad signal in the
+Common Block Signals section selects the reference clock source connected
+to the PHY pads. Per the specification, any change to this input must be
+followed by a PHY reset assertion to take effect.
+
+Move the REF_USE_PAD configuration before the PHY reset toggle to comply
+with the required initialization sequence.
+
+Fixes: 47f54a902dcd ("PCI: imx6: Toggle the core reset for i.MX95 PCIe")
+Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
+[mani: renamed the callback and helper to match the usecase]
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260518072715.3166514-2-hongxing.zhu@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/dwc/pci-imx6.c | 27 ++++++++++++++++++++++++---
+ 1 file changed, 24 insertions(+), 3 deletions(-)
+
+--- a/drivers/pci/controller/dwc/pci-imx6.c
++++ b/drivers/pci/controller/dwc/pci-imx6.c
+@@ -137,6 +137,7 @@ struct imx_pcie_drvdata {
+ const u32 mode_off[IMX_PCIE_MAX_INSTANCES];
+ const u32 mode_mask[IMX_PCIE_MAX_INSTANCES];
+ const struct pci_epc_features *epc_features;
++ int (*select_ref_clk_src)(struct imx_pcie *pcie);
+ int (*init_phy)(struct imx_pcie *pcie);
+ int (*enable_ref_clk)(struct imx_pcie *pcie, bool enable);
+ int (*core_reset)(struct imx_pcie *pcie, bool assert);
+@@ -247,6 +248,24 @@ static unsigned int imx_pcie_grp_offset(
+ return imx_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
+ }
+
++static int imx95_pcie_select_ref_clk_src(struct imx_pcie *imx_pcie)
++{
++ bool ext = imx_pcie->enable_ext_refclk;
++
++ /*
++ * Regarding the Signal Descriptions of i.MX95 PCIe PHY, ref_use_pad is
++ * used to select reference clock connected to a pair of pads.
++ *
++ * Any change in this input must be followed by phy_reset assertion.
++ */
++
++ regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_PHY_GEN_CTRL,
++ IMX95_PCIE_REF_USE_PAD,
++ ext ? IMX95_PCIE_REF_USE_PAD : 0);
++
++ return 0;
++}
++
+ static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie)
+ {
+ bool ext = imx_pcie->enable_ext_refclk;
+@@ -269,9 +288,6 @@ static int imx95_pcie_init_phy(struct im
+ IMX95_PCIE_PHY_CR_PARA_SEL,
+ IMX95_PCIE_PHY_CR_PARA_SEL);
+
+- regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_PHY_GEN_CTRL,
+- IMX95_PCIE_REF_USE_PAD,
+- ext ? IMX95_PCIE_REF_USE_PAD : 0);
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_0,
+ IMX95_PCIE_REF_CLKEN,
+ ext ? 0 : IMX95_PCIE_REF_CLKEN);
+@@ -1256,6 +1272,9 @@ static int imx_pcie_host_init(struct dw_
+ pp->bridge->disable_device = imx_pcie_disable_device;
+ }
+
++ if (imx_pcie->drvdata->select_ref_clk_src)
++ imx_pcie->drvdata->select_ref_clk_src(imx_pcie);
++
+ imx_pcie_assert_core_reset(imx_pcie);
+ imx_pcie_assert_perst(imx_pcie, true);
+
+@@ -1967,6 +1986,7 @@ static const struct imx_pcie_drvdata drv
+ .mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
+ .core_reset = imx95_pcie_core_reset,
+ .init_phy = imx95_pcie_init_phy,
++ .select_ref_clk_src = imx95_pcie_select_ref_clk_src,
+ .wait_pll_lock = imx95_pcie_wait_for_phy_pll_lock,
+ .enable_ref_clk = imx95_pcie_enable_ref_clk,
+ .clr_clkreq_override = imx95_pcie_clr_clkreq_override,
+@@ -2022,6 +2042,7 @@ static const struct imx_pcie_drvdata drv
+ .ltssm_mask = IMX95_PCIE_LTSSM_EN,
+ .mode_off[0] = IMX95_PE0_GEN_CTRL_1,
+ .mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
++ .select_ref_clk_src = imx95_pcie_select_ref_clk_src,
+ .init_phy = imx95_pcie_init_phy,
+ .core_reset = imx95_pcie_core_reset,
+ .wait_pll_lock = imx95_pcie_wait_for_phy_pll_lock,
--- /dev/null
+From aad953fb4eed0df5486cd54ccad80ac197678e01 Mon Sep 17 00:00:00 2001
+From: Richard Zhu <hongxing.zhu@nxp.com>
+Date: Thu, 19 Mar 2026 17:08:44 +0800
+Subject: PCI: imx6: Fix IMX6SX_GPR12_PCIE_TEST_POWERDOWN handling
+
+From: Richard Zhu <hongxing.zhu@nxp.com>
+
+commit aad953fb4eed0df5486cd54ccad80ac197678e01 upstream.
+
+The IMX6SX_GPR12_PCIE_TEST_POWERDOWN bit does not control the PCIe
+reference clock on i.MX6SX. Instead, it is part of i.MX6SX PCIe core
+reset sequence.
+
+Move the IMX6SX_GPR12_PCIE_TEST_POWERDOWN assertion/deassertion into
+the core reset functions to properly reflect its purpose. Remove the
+.enable_ref_clk() callback for i.MX6SX since it was incorrectly
+manipulating this bit.
+
+Fixes: e3c06cd063d6 ("PCI: imx6: Add initial imx6sx support")
+Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260319090844.444987-1-hongxing.zhu@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/dwc/pci-imx6.c | 12 +++---------
+ 1 file changed, 3 insertions(+), 9 deletions(-)
+
+--- a/drivers/pci/controller/dwc/pci-imx6.c
++++ b/drivers/pci/controller/dwc/pci-imx6.c
+@@ -681,14 +681,6 @@ static int imx_pcie_attach_pd(struct dev
+ return 0;
+ }
+
+-static int imx6sx_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable)
+-{
+- regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
+- IMX6SX_GPR12_PCIE_TEST_POWERDOWN,
+- enable ? 0 : IMX6SX_GPR12_PCIE_TEST_POWERDOWN);
+- return 0;
+-}
+-
+ static int imx6q_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable)
+ {
+ if (enable) {
+@@ -802,6 +794,9 @@ static int imx6sx_pcie_core_reset(struct
+ if (assert)
+ regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
+ IMX6SX_GPR12_PCIE_TEST_POWERDOWN);
++ else
++ regmap_clear_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
++ IMX6SX_GPR12_PCIE_TEST_POWERDOWN);
+
+ /* Force PCIe PHY reset */
+ regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR5, IMX6SX_GPR5_PCIE_BTNRST_RESET,
+@@ -1896,7 +1891,6 @@ static const struct imx_pcie_drvdata drv
+ .mode_off[0] = IOMUXC_GPR12,
+ .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
+ .init_phy = imx6sx_pcie_init_phy,
+- .enable_ref_clk = imx6sx_pcie_enable_ref_clk,
+ .core_reset = imx6sx_pcie_core_reset,
+ .ops = &imx_pcie_host_ops,
+ },
--- /dev/null
+From f865a57896bd92d7662eb2818d8f48872e2cbbc7 Mon Sep 17 00:00:00 2001
+From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
+Date: Thu, 21 May 2026 23:16:17 +0530
+Subject: PCI: mediatek: Fix IRQ domain leak when port fails to enable
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
+
+commit f865a57896bd92d7662eb2818d8f48872e2cbbc7 upstream.
+
+When mtk_pcie_enable_port() fails, mtk_pcie_port_free() removes the port
+from pcie->ports and frees the port structure. However, the IRQ domains set
+up earlier by mtk_pcie_init_irq_domain() are never freed.
+
+Fix this by refactoring mtk_pcie_irq_teardown() into a per-port helper,
+mtk_pcie_irq_teardown_port(), and calling it from mtk_pcie_setup() when
+mtk_pcie_enable_port() fails. Since the IRQ teardown must only happen in
+the probe error path (during resume, child devices may have active MSI
+mappings and the NOIRQ context prohibits sleeping locks),
+mtk_pcie_enable_port() is changed to return an error code so callers can
+distinguish the two paths and act accordingly.
+
+This issue was reported by Sashiko while reviewing the EcoNet EN7528 SoC
+support series.
+
+Fixes: b099631df160 ("PCI: mediatek: Add controller support for MT2712 and MT7622")
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Cc: stable@vger.kernel.org # 5.10
+Cc: Caleb James DeLisle <cjd@cjdns.fr>
+Link: https://patch.msgid.link/20260521174617.17692-1-mani@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/pcie-mediatek.c | 63 ++++++++++++++++++++-------------
+ 1 file changed, 40 insertions(+), 23 deletions(-)
+
+--- a/drivers/pci/controller/pcie-mediatek.c
++++ b/drivers/pci/controller/pcie-mediatek.c
+@@ -529,23 +529,27 @@ static void mtk_pcie_enable_msi(struct m
+ writel(val, port->base + PCIE_INT_MASK);
+ }
+
+-static void mtk_pcie_irq_teardown(struct mtk_pcie *pcie)
++static void mtk_pcie_irq_teardown_port(struct mtk_pcie_port *port)
+ {
+- struct mtk_pcie_port *port, *tmp;
++ irq_set_chained_handler_and_data(port->irq, NULL, NULL);
+
+- list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
+- irq_set_chained_handler_and_data(port->irq, NULL, NULL);
++ if (port->irq_domain)
++ irq_domain_remove(port->irq_domain);
+
+- if (port->irq_domain)
+- irq_domain_remove(port->irq_domain);
++ if (IS_ENABLED(CONFIG_PCI_MSI)) {
++ if (port->inner_domain)
++ irq_domain_remove(port->inner_domain);
++ }
+
+- if (IS_ENABLED(CONFIG_PCI_MSI)) {
+- if (port->inner_domain)
+- irq_domain_remove(port->inner_domain);
+- }
++ irq_dispose_mapping(port->irq);
++}
+
+- irq_dispose_mapping(port->irq);
+- }
++static void mtk_pcie_irq_teardown(struct mtk_pcie *pcie)
++{
++ struct mtk_pcie_port *port, *tmp;
++
++ list_for_each_entry_safe(port, tmp, &pcie->ports, list)
++ mtk_pcie_irq_teardown_port(port);
+ }
+
+ static int mtk_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
+@@ -865,7 +869,7 @@ static int mtk_pcie_startup_port_an7583(
+ return mtk_pcie_startup_port_v2(port);
+ }
+
+-static void mtk_pcie_enable_port(struct mtk_pcie_port *port)
++static int mtk_pcie_enable_port(struct mtk_pcie_port *port)
+ {
+ struct mtk_pcie *pcie = port->pcie;
+ struct device *dev = pcie->dev;
+@@ -874,7 +878,7 @@ static void mtk_pcie_enable_port(struct
+ err = clk_prepare_enable(port->sys_ck);
+ if (err) {
+ dev_err(dev, "failed to enable sys_ck%d clock\n", port->slot);
+- goto err_sys_clk;
++ return err;
+ }
+
+ err = clk_prepare_enable(port->ahb_ck);
+@@ -922,11 +926,15 @@ static void mtk_pcie_enable_port(struct
+ goto err_phy_on;
+ }
+
+- if (!pcie->soc->startup(port))
+- return;
++ err = pcie->soc->startup(port);
++ if (err) {
++ dev_info(dev, "Port%d link down\n", port->slot);
++ goto err_soc_startup;
++ }
+
+- dev_info(dev, "Port%d link down\n", port->slot);
++ return 0;
+
++err_soc_startup:
+ phy_power_off(port->phy);
+ err_phy_on:
+ phy_exit(port->phy);
+@@ -942,8 +950,8 @@ err_aux_clk:
+ clk_disable_unprepare(port->ahb_ck);
+ err_ahb_clk:
+ clk_disable_unprepare(port->sys_ck);
+-err_sys_clk:
+- mtk_pcie_port_free(port);
++
++ return err;
+ }
+
+ static int mtk_pcie_parse_port(struct mtk_pcie *pcie,
+@@ -1109,8 +1117,13 @@ static int mtk_pcie_setup(struct mtk_pci
+ return err;
+
+ /* enable each port, and then check link status */
+- list_for_each_entry_safe(port, tmp, &pcie->ports, list)
+- mtk_pcie_enable_port(port);
++ list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
++ err = mtk_pcie_enable_port(port);
++ if (err) {
++ mtk_pcie_irq_teardown_port(port);
++ mtk_pcie_port_free(port);
++ }
++ }
+
+ /* power down PCIe subsys if slots are all empty (link down) */
+ if (list_empty(&pcie->ports))
+@@ -1209,14 +1222,18 @@ static int mtk_pcie_resume_noirq(struct
+ {
+ struct mtk_pcie *pcie = dev_get_drvdata(dev);
+ struct mtk_pcie_port *port, *tmp;
++ int err;
+
+ if (list_empty(&pcie->ports))
+ return 0;
+
+ clk_prepare_enable(pcie->free_ck);
+
+- list_for_each_entry_safe(port, tmp, &pcie->ports, list)
+- mtk_pcie_enable_port(port);
++ list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
++ err = mtk_pcie_enable_port(port);
++ if (err)
++ mtk_pcie_port_free(port);
++ }
+
+ /* In case of EP was removed while system suspend. */
+ if (list_empty(&pcie->ports))
--- /dev/null
+From e0779713a1e2f891aeec53e629dbbd33f423c629 Mon Sep 17 00:00:00 2001
+From: Yadu M G <yadu.mg@oss.qualcomm.com>
+Date: Thu, 4 Jun 2026 17:54:18 +0530
+Subject: PCI: qcom: Initialize DWC MSI lock for firmware-managed ECAM hosts
+
+From: Yadu M G <yadu.mg@oss.qualcomm.com>
+
+commit e0779713a1e2f891aeec53e629dbbd33f423c629 upstream.
+
+A lockdep warning is observed during boot on a Qcom firmware-managed
+platform:
+
+ INFO: trying to register non-static key.
+ The code is fine but needs lockdep annotation, or maybe
+ you didn't initialize this object before use?
+ turning off the locking correctness validator.
+ ...
+ Call trace:
+ register_lock_class+0x128/0x4d8
+ __lock_acquire+0x110/0x1db0
+ lock_acquire+0x278/0x3d8
+ _raw_spin_lock_irq+0x6c/0xc0
+ dw_pcie_irq_domain_alloc+0x48/0x190
+ irq_domain_alloc_irqs_parent+0x2c/0x48
+ msi_domain_alloc+0x90/0x160
+ ...
+
+dw_pcie_irq_domain_alloc() takes pp->lock while allocating MSI
+interrupts. pp->lock is normally initialized by dw_pcie_host_init(), but
+Qcom firmware-managed hosts use the ECAM init path instead:
+
+ pci_host_common_ecam_create()
+ pci_ecam_create()
+ qcom_pcie_ecam_host_init()
+ dw_pcie_msi_host_init()
+ dw_pcie_allocate_domains()
+
+That path constructs a fresh struct dw_pcie_rp and calls
+dw_pcie_msi_host_init() directly, without going through
+dw_pcie_host_init(). As a result, pp->lock was not initialized, which
+triggers the warning.
+
+Initialize pp->lock in qcom_pcie_ecam_host_init() before registering the
+MSI domains so the firmware-managed ECAM path matches the normal DWC host
+initialization sequence.
+
+Fixes: 7d944c0f1469 ("PCI: qcom: Add support for Qualcomm SA8255p based PCIe Root Complex")
+Signed-off-by: Yadu M G <yadu.mg@oss.qualcomm.com>
+[mani: added fixes tag and CCed stable]
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Cc: stable@kernel.org
+Link: https://patch.msgid.link/20260604122418.727274-1-yadu.mg@oss.qualcomm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/dwc/pcie-qcom.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/pci/controller/dwc/pcie-qcom.c
++++ b/drivers/pci/controller/dwc/pcie-qcom.c
+@@ -1674,6 +1674,12 @@ static int qcom_pcie_ecam_host_init(stru
+ pci->dbi_base = cfg->win;
+ pp->num_vectors = MSI_DEF_NUM_VECTORS;
+
++ /*
++ * dw_pcie_msi_host_init() is called directly here, bypassing
++ * dw_pcie_host_init() where pp->lock is normally initialized.
++ */
++ raw_spin_lock_init(&pp->lock);
++
+ ret = dw_pcie_msi_host_init(pp);
+ if (ret)
+ return ret;
--- /dev/null
+From ee7471fe968d210939be9046089a924cd23c8c3b Mon Sep 17 00:00:00 2001
+From: Marco Nenciarini <mnencia@kcore.it>
+Date: Fri, 17 Apr 2026 15:24:36 +0200
+Subject: PCI: Skip Resizable BAR restore on read error
+
+From: Marco Nenciarini <mnencia@kcore.it>
+
+commit ee7471fe968d210939be9046089a924cd23c8c3b upstream.
+
+pci_restore_rebar_state() uses the Resizable BAR Control register to decide
+how many BARs to restore (nbars) and which BAR each iteration addresses
+(bar_idx).
+
+When a device does not respond, config reads typically return
+PCI_ERROR_RESPONSE (~0). Both fields are 3 bits wide, so nbars and bar_idx
+both evaluate to 7, past the spec's valid ranges for both fields.
+pci_resource_n() then returns an unrelated resource slot, whose size is
+used to derive a nonsensical value written back to the Resizable BAR
+Control register.
+
+Bail out if any Resizable BAR Control read returns PCI_ERROR_RESPONSE. No
+further BARs are touched, which is safe because a config read that returns
+PCI_ERROR_RESPONSE indicates the device is unreachable and restoration is
+pointless.
+
+Fixes: d3252ace0bc6 ("PCI: Restore resized BAR state on resume")
+Signed-off-by: Marco Nenciarini <mnencia@kcore.it>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/666cac19b5daa0ab0e0ab64454e76b4d24465dbd.1776429882.git.mnencia@kcore.it
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/rebar.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/pci/rebar.c
++++ b/drivers/pci/rebar.c
+@@ -231,6 +231,9 @@ void pci_restore_rebar_state(struct pci_
+ return;
+
+ pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++ if (PCI_POSSIBLE_ERROR(ctrl))
++ return;
++
+ nbars = FIELD_GET(PCI_REBAR_CTRL_NBAR_MASK, ctrl);
+
+ for (i = 0; i < nbars; i++, pos += 8) {
+@@ -238,6 +241,9 @@ void pci_restore_rebar_state(struct pci_
+ int bar_idx, size;
+
+ pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
++ if (PCI_POSSIBLE_ERROR(ctrl))
++ return;
++
+ bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX;
+ res = pci_resource_n(pdev, bar_idx);
+ size = pci_rebar_bytes_to_size(resource_size(res));
pci-loongson-override-pcie-bridge-supported-speeds-for-loongson-3c6000-series.patch
pci-altera-do-not-dispose-parent-irq-mapping.patch
pci-altera-fix-resource-leaks-on-probe-failure.patch
+pci-always-lift-2.5gt-s-restriction-in-pcie-failed-link-retraining.patch
+pci-host-common-request-bus-reassignment-when-not-probe-only.patch
+pci-imx6-configure-ref_use_pad-before-phy-reset-for-i.mx95.patch
+pci-imx6-fix-imx6sx_gpr12_pcie_test_powerdown-handling.patch
+pci-imx6-assert-ref_clk_en-after-reference-clock-stabilizes-on-i.mx95.patch
+pci-mediatek-fix-irq-domain-leak-when-port-fails-to-enable.patch
+pci-qcom-initialize-dwc-msi-lock-for-firmware-managed-ecam-hosts.patch
+pci-skip-resizable-bar-restore-on-read-error.patch