From: Greg Kroah-Hartman Date: Mon, 13 Jul 2026 13:24:31 +0000 (+0200) Subject: 6.18-stable patches X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83defea4815c270b3881dd73c4a143c1fd83b1e7;p=thirdparty%2Fkernel%2Fstable-queue.git 6.18-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-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 --- diff --git a/queue-6.18/pci-always-lift-2.5gt-s-restriction-in-pcie-failed-link-retraining.patch b/queue-6.18/pci-always-lift-2.5gt-s-restriction-in-pcie-failed-link-retraining.patch new file mode 100644 index 0000000000..85be5b181a --- /dev/null +++ b/queue-6.18/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 +@@ -79,11 +79,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 +@@ -94,52 +93,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-6.18/pci-host-common-request-bus-reassignment-when-not-probe-only.patch b/queue-6.18/pci-host-common-request-bus-reassignment-when-not-probe-only.patch new file mode 100644 index 0000000000..067b0eaee4 --- /dev/null +++ b/queue-6.18/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 +@@ -72,6 +72,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-6.18/pci-imx6-fix-imx6sx_gpr12_pcie_test_powerdown-handling.patch b/queue-6.18/pci-imx6-fix-imx6sx_gpr12_pcie_test_powerdown-handling.patch new file mode 100644 index 0000000000..c2e4cf5ffe --- /dev/null +++ b/queue-6.18/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 +@@ -659,14 +659,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) { +@@ -765,6 +757,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, +@@ -1852,7 +1847,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-6.18/pci-mediatek-fix-irq-domain-leak-when-port-fails-to-enable.patch b/queue-6.18/pci-mediatek-fix-irq-domain-leak-when-port-fails-to-enable.patch new file mode 100644 index 0000000000..62262f5985 --- /dev/null +++ b/queue-6.18/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 +@@ -519,23 +519,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, +@@ -823,7 +827,7 @@ static int mtk_pcie_startup_port(struct + return 0; + } + +-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; +@@ -832,7 +836,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); +@@ -880,11 +884,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); +@@ -900,8 +908,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, +@@ -1067,8 +1075,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)) +@@ -1167,14 +1180,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-6.18/pci-qcom-initialize-dwc-msi-lock-for-firmware-managed-ecam-hosts.patch b/queue-6.18/pci-qcom-initialize-dwc-msi-lock-for-firmware-managed-ecam-hosts.patch new file mode 100644 index 0000000000..72360e3ba9 --- /dev/null +++ b/queue-6.18/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 +@@ -1626,6 +1626,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-6.18/series b/queue-6.18/series index b239773592..85ab239c07 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -135,3 +135,8 @@ usb-typec-tcpci_rt1711h-unregister-tcpci-port-with-devres.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-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