From: Greg Kroah-Hartman Date: Mon, 13 Jul 2026 13:24:29 +0000 (+0200) Subject: 7.1-stable patches X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=68c6a504454ff5bb43f9538a5e8396371d2f09cd;p=thirdparty%2Fkernel%2Fstable-queue.git 7.1-stable patches added patches: 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-assert-ref_clk_en-after-reference-clock-stabilizes-on-i.mx95.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-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 --- diff --git a/queue-7.1/pci-always-lift-2.5gt-s-restriction-in-pcie-failed-link-retraining.patch b/queue-7.1/pci-always-lift-2.5gt-s-restriction-in-pcie-failed-link-retraining.patch new file mode 100644 index 0000000000..4c8f9b8c63 --- /dev/null +++ b/queue-7.1/pci-always-lift-2.5gt-s-restriction-in-pcie-failed-link-retraining.patch @@ -0,0 +1,118 @@ +From 72780f7964684939d7d2f69c348876213b184484 Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" +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 + +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 +Signed-off-by: Bjorn Helgaas +Tested-by: Alok Tiwari +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 +--- + 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, diff --git a/queue-7.1/pci-host-common-request-bus-reassignment-when-not-probe-only.patch b/queue-7.1/pci-host-common-request-bus-reassignment-when-not-probe-only.patch new file mode 100644 index 0000000000..117cf575d6 --- /dev/null +++ b/queue-7.1/pci-host-common-request-bus-reassignment-when-not-probe-only.patch @@ -0,0 +1,47 @@ +From fda8749ba73638f5bbca3ffb39bc6861eb3b23fa Mon Sep 17 00:00:00 2001 +From: Ratheesh Kannoth +Date: Tue, 14 Apr 2026 13:47:30 +0530 +Subject: PCI: host-common: Request bus reassignment when not probe-only + +From: Ratheesh Kannoth + +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 +[mani: added stable tag] +Signed-off-by: Manivannan Sadhasivam +[bhelgaas: add problem report link] +Signed-off-by: Bjorn Helgaas +Cc: stable@vger.kernel.org +Cc: Vidya Sagar +Link: https://patch.msgid.link/20260414081730.3864372-1-rkannoth@marvell.com +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-7.1/pci-imx6-assert-ref_clk_en-after-reference-clock-stabilizes-on-i.mx95.patch b/queue-7.1/pci-imx6-assert-ref_clk_en-after-reference-clock-stabilizes-on-i.mx95.patch new file mode 100644 index 0000000000..4cf31c99ac --- /dev/null +++ b/queue-7.1/pci-imx6-assert-ref_clk_en-after-reference-clock-stabilizes-on-i.mx95.patch @@ -0,0 +1,83 @@ +From 9dda3f83ba677b9cc2613cecd9120123000ae50f Mon Sep 17 00:00:00 2001 +From: Richard Zhu +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 + +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 +Signed-off-by: Manivannan Sadhasivam +Reviewed-by: Frank Li +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260518072715.3166514-3-hongxing.zhu@nxp.com +Signed-off-by: Greg Kroah-Hartman +--- + 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; + } + diff --git a/queue-7.1/pci-imx6-configure-ref_use_pad-before-phy-reset-for-i.mx95.patch b/queue-7.1/pci-imx6-configure-ref_use_pad-before-phy-reset-for-i.mx95.patch new file mode 100644 index 0000000000..984b2f62af --- /dev/null +++ b/queue-7.1/pci-imx6-configure-ref_use_pad-before-phy-reset-for-i.mx95.patch @@ -0,0 +1,99 @@ +From 0c26b1c34d12d4debfb5363cc0be6cdf68e87ba2 Mon Sep 17 00:00:00 2001 +From: Richard Zhu +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 + +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 +[mani: renamed the callback and helper to match the usecase] +Signed-off-by: Manivannan Sadhasivam +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260518072715.3166514-2-hongxing.zhu@nxp.com +Signed-off-by: Greg Kroah-Hartman +--- + 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, diff --git a/queue-7.1/pci-imx6-fix-imx6sx_gpr12_pcie_test_powerdown-handling.patch b/queue-7.1/pci-imx6-fix-imx6sx_gpr12_pcie_test_powerdown-handling.patch new file mode 100644 index 0000000000..b5e4980d5b --- /dev/null +++ b/queue-7.1/pci-imx6-fix-imx6sx_gpr12_pcie_test_powerdown-handling.patch @@ -0,0 +1,65 @@ +From aad953fb4eed0df5486cd54ccad80ac197678e01 Mon Sep 17 00:00:00 2001 +From: Richard Zhu +Date: Thu, 19 Mar 2026 17:08:44 +0800 +Subject: PCI: imx6: Fix IMX6SX_GPR12_PCIE_TEST_POWERDOWN handling + +From: Richard Zhu + +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 +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Reviewed-by: Frank Li +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260319090844.444987-1-hongxing.zhu@nxp.com +Signed-off-by: Greg Kroah-Hartman +--- + 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, + }, diff --git a/queue-7.1/pci-mediatek-fix-irq-domain-leak-when-port-fails-to-enable.patch b/queue-7.1/pci-mediatek-fix-irq-domain-leak-when-port-fails-to-enable.patch new file mode 100644 index 0000000000..248ae8d27d --- /dev/null +++ b/queue-7.1/pci-mediatek-fix-irq-domain-leak-when-port-fails-to-enable.patch @@ -0,0 +1,162 @@ +From f865a57896bd92d7662eb2818d8f48872e2cbbc7 Mon Sep 17 00:00:00 2001 +From: Manivannan Sadhasivam +Date: Thu, 21 May 2026 23:16:17 +0530 +Subject: PCI: mediatek: Fix IRQ domain leak when port fails to enable + +From: Manivannan Sadhasivam + +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 +Signed-off-by: Manivannan Sadhasivam +Cc: stable@vger.kernel.org # 5.10 +Cc: Caleb James DeLisle +Link: https://patch.msgid.link/20260521174617.17692-1-mani@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + 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)) diff --git a/queue-7.1/pci-qcom-initialize-dwc-msi-lock-for-firmware-managed-ecam-hosts.patch b/queue-7.1/pci-qcom-initialize-dwc-msi-lock-for-firmware-managed-ecam-hosts.patch new file mode 100644 index 0000000000..2284499b2f --- /dev/null +++ b/queue-7.1/pci-qcom-initialize-dwc-msi-lock-for-firmware-managed-ecam-hosts.patch @@ -0,0 +1,72 @@ +From e0779713a1e2f891aeec53e629dbbd33f423c629 Mon Sep 17 00:00:00 2001 +From: Yadu M G +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 + +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 +[mani: added fixes tag and CCed stable] +Signed-off-by: Manivannan Sadhasivam +Cc: stable@kernel.org +Link: https://patch.msgid.link/20260604122418.727274-1-yadu.mg@oss.qualcomm.com +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-7.1/pci-skip-resizable-bar-restore-on-read-error.patch b/queue-7.1/pci-skip-resizable-bar-restore-on-read-error.patch new file mode 100644 index 0000000000..a4bb62220d --- /dev/null +++ b/queue-7.1/pci-skip-resizable-bar-restore-on-read-error.patch @@ -0,0 +1,57 @@ +From ee7471fe968d210939be9046089a924cd23c8c3b Mon Sep 17 00:00:00 2001 +From: Marco Nenciarini +Date: Fri, 17 Apr 2026 15:24:36 +0200 +Subject: PCI: Skip Resizable BAR restore on read error + +From: Marco Nenciarini + +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 +Signed-off-by: Bjorn Helgaas +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/666cac19b5daa0ab0e0ab64454e76b4d24465dbd.1776429882.git.mnencia@kcore.it +Signed-off-by: Greg Kroah-Hartman +--- + 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)); diff --git a/queue-7.1/series b/queue-7.1/series index 382a6acaa7..9687a52da9 100644 --- a/queue-7.1/series +++ b/queue-7.1/series @@ -128,3 +128,11 @@ riscv-dts-sophgo-add-dma-coherent-to-sg2042-pcie-controllers.patch 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