]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 21 Sep 2025 17:33:40 +0000 (19:33 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 21 Sep 2025 17:33:40 +0000 (19:33 +0200)
added patches:
phy-broadcom-convert-to-devm_platform_ioremap_resource-_byname.patch
phy-broadcom-ns-usb3-fix-wvoid-pointer-to-enum-cast-warning.patch
phy-phy-bcm-ns-usb3-drop-support-for-deprecated-dt-binding.patch
phy-ti-convert-to-devm_platform_ioremap_resource-_byname.patch
phy-ti-omap-usb2-fix-device-leak-at-unbind.patch
phy-use-device_get_match_data.patch
serial-sc16is7xx-fix-bug-in-flow-control-levels-init.patch
usb-gadget-dummy-hcd-fix-locking-bug-in-rt-enabled-kernels.patch
usb-gadget-dummy_hcd-remove-usage-of-list-iterator-past-the-loop-body.patch
xhci-dbc-decouple-endpoint-allocation-from-initialization.patch
xhci-dbc-fix-full-dbc-transfer-ring-after-several-reconnects.patch

12 files changed:
queue-5.10/phy-broadcom-convert-to-devm_platform_ioremap_resource-_byname.patch [new file with mode: 0644]
queue-5.10/phy-broadcom-ns-usb3-fix-wvoid-pointer-to-enum-cast-warning.patch [new file with mode: 0644]
queue-5.10/phy-phy-bcm-ns-usb3-drop-support-for-deprecated-dt-binding.patch [new file with mode: 0644]
queue-5.10/phy-ti-convert-to-devm_platform_ioremap_resource-_byname.patch [new file with mode: 0644]
queue-5.10/phy-ti-omap-usb2-fix-device-leak-at-unbind.patch [new file with mode: 0644]
queue-5.10/phy-use-device_get_match_data.patch [new file with mode: 0644]
queue-5.10/serial-sc16is7xx-fix-bug-in-flow-control-levels-init.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/usb-gadget-dummy-hcd-fix-locking-bug-in-rt-enabled-kernels.patch [new file with mode: 0644]
queue-5.10/usb-gadget-dummy_hcd-remove-usage-of-list-iterator-past-the-loop-body.patch [new file with mode: 0644]
queue-5.10/xhci-dbc-decouple-endpoint-allocation-from-initialization.patch [new file with mode: 0644]
queue-5.10/xhci-dbc-fix-full-dbc-transfer-ring-after-several-reconnects.patch [new file with mode: 0644]

diff --git a/queue-5.10/phy-broadcom-convert-to-devm_platform_ioremap_resource-_byname.patch b/queue-5.10/phy-broadcom-convert-to-devm_platform_ioremap_resource-_byname.patch
new file mode 100644 (file)
index 0000000..9cf4610
--- /dev/null
@@ -0,0 +1,229 @@
+From stable+bounces-180389-greg=kroah.com@vger.kernel.org Wed Sep 17 16:40:54 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Sep 2025 09:54:57 -0400
+Subject: phy: broadcom: convert to devm_platform_ioremap_resource(_byname)
+To: stable@vger.kernel.org
+Cc: Chunfeng Yun <chunfeng.yun@mediatek.com>, Florian Fainelli <f.fainelli@gmail.com>, Al Cooper <alcooperx@gmail.com>, Vinod Koul <vkoul@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250917135502.565547-1-sashal@kernel.org>
+
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+
+[ Upstream commit f669bc8b9f7beb6b1936882a2c3670dc1bd985ba ]
+
+Use devm_platform_ioremap_resource(_byname) to simplify code
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Cc: Al Cooper <alcooperx@gmail.com>
+Link: https://lore.kernel.org/r/1604642930-29019-3-git-send-email-chunfeng.yun@mediatek.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Stable-dep-of: 64961557efa1 ("phy: ti: omap-usb2: fix device leak at unbind")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/phy/broadcom/phy-bcm-cygnus-pcie.c |    4 +---
+ drivers/phy/broadcom/phy-bcm-kona-usb2.c   |    4 +---
+ drivers/phy/broadcom/phy-bcm-ns-usb2.c     |    4 +---
+ drivers/phy/broadcom/phy-bcm-ns-usb3.c     |    7 ++-----
+ drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c  |   13 ++++---------
+ drivers/phy/broadcom/phy-bcm-sr-pcie.c     |    5 +----
+ drivers/phy/broadcom/phy-bcm-sr-usb.c      |    4 +---
+ drivers/phy/broadcom/phy-brcm-sata.c       |    8 ++------
+ 8 files changed, 13 insertions(+), 36 deletions(-)
+
+--- a/drivers/phy/broadcom/phy-bcm-cygnus-pcie.c
++++ b/drivers/phy/broadcom/phy-bcm-cygnus-pcie.c
+@@ -126,7 +126,6 @@ static int cygnus_pcie_phy_probe(struct
+       struct device_node *node = dev->of_node, *child;
+       struct cygnus_pcie_phy_core *core;
+       struct phy_provider *provider;
+-      struct resource *res;
+       unsigned cnt = 0;
+       int ret;
+@@ -141,8 +140,7 @@ static int cygnus_pcie_phy_probe(struct
+       core->dev = dev;
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      core->base = devm_ioremap_resource(dev, res);
++      core->base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(core->base))
+               return PTR_ERR(core->base);
+--- a/drivers/phy/broadcom/phy-bcm-kona-usb2.c
++++ b/drivers/phy/broadcom/phy-bcm-kona-usb2.c
+@@ -94,7 +94,6 @@ static int bcm_kona_usb2_probe(struct pl
+ {
+       struct device *dev = &pdev->dev;
+       struct bcm_kona_usb *phy;
+-      struct resource *res;
+       struct phy *gphy;
+       struct phy_provider *phy_provider;
+@@ -102,8 +101,7 @@ static int bcm_kona_usb2_probe(struct pl
+       if (!phy)
+               return -ENOMEM;
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      phy->regs = devm_ioremap_resource(&pdev->dev, res);
++      phy->regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(phy->regs))
+               return PTR_ERR(phy->regs);
+--- a/drivers/phy/broadcom/phy-bcm-ns-usb2.c
++++ b/drivers/phy/broadcom/phy-bcm-ns-usb2.c
+@@ -83,7 +83,6 @@ static int bcm_ns_usb2_probe(struct plat
+ {
+       struct device *dev = &pdev->dev;
+       struct bcm_ns_usb2 *usb2;
+-      struct resource *res;
+       struct phy_provider *phy_provider;
+       usb2 = devm_kzalloc(&pdev->dev, sizeof(*usb2), GFP_KERNEL);
+@@ -91,8 +90,7 @@ static int bcm_ns_usb2_probe(struct plat
+               return -ENOMEM;
+       usb2->dev = dev;
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmu");
+-      usb2->dmu = devm_ioremap_resource(dev, res);
++      usb2->dmu = devm_platform_ioremap_resource_byname(pdev, "dmu");
+       if (IS_ERR(usb2->dmu)) {
+               dev_err(dev, "Failed to map DMU regs\n");
+               return PTR_ERR(usb2->dmu);
+--- a/drivers/phy/broadcom/phy-bcm-ns-usb3.c
++++ b/drivers/phy/broadcom/phy-bcm-ns-usb3.c
+@@ -305,7 +305,6 @@ static int bcm_ns_usb3_probe(struct plat
+       struct device *dev = &pdev->dev;
+       const struct of_device_id *of_id;
+       struct bcm_ns_usb3 *usb3;
+-      struct resource *res;
+       struct phy_provider *phy_provider;
+       usb3 = devm_kzalloc(dev, sizeof(*usb3), GFP_KERNEL);
+@@ -319,15 +318,13 @@ static int bcm_ns_usb3_probe(struct plat
+               return -EINVAL;
+       usb3->family = (enum bcm_ns_family)of_id->data;
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dmp");
+-      usb3->dmp = devm_ioremap_resource(dev, res);
++      usb3->dmp = devm_platform_ioremap_resource_byname(pdev, "dmp");
+       if (IS_ERR(usb3->dmp)) {
+               dev_err(dev, "Failed to map DMP regs\n");
+               return PTR_ERR(usb3->dmp);
+       }
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ccb-mii");
+-      usb3->ccb_mii = devm_ioremap_resource(dev, res);
++      usb3->ccb_mii = devm_platform_ioremap_resource_byname(pdev, "ccb-mii");
+       if (IS_ERR(usb3->ccb_mii)) {
+               dev_err(dev, "Failed to map ChipCommon B MII regs\n");
+               return PTR_ERR(usb3->ccb_mii);
+--- a/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
++++ b/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
+@@ -293,7 +293,6 @@ static int ns2_drd_phy_probe(struct plat
+       struct device *dev = &pdev->dev;
+       struct ns2_phy_driver *driver;
+       struct ns2_phy_data *data;
+-      struct resource *res;
+       int ret;
+       u32 val;
+@@ -307,23 +306,19 @@ static int ns2_drd_phy_probe(struct plat
+       if (!driver->data)
+               return -ENOMEM;
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "icfg");
+-      driver->icfgdrd_regs = devm_ioremap_resource(dev, res);
++      driver->icfgdrd_regs = devm_platform_ioremap_resource_byname(pdev, "icfg");
+       if (IS_ERR(driver->icfgdrd_regs))
+               return PTR_ERR(driver->icfgdrd_regs);
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rst-ctrl");
+-      driver->idmdrd_rst_ctrl = devm_ioremap_resource(dev, res);
++      driver->idmdrd_rst_ctrl = devm_platform_ioremap_resource_byname(pdev, "rst-ctrl");
+       if (IS_ERR(driver->idmdrd_rst_ctrl))
+               return PTR_ERR(driver->idmdrd_rst_ctrl);
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "crmu-ctrl");
+-      driver->crmu_usb2_ctrl = devm_ioremap_resource(dev, res);
++      driver->crmu_usb2_ctrl = devm_platform_ioremap_resource_byname(pdev, "crmu-ctrl");
+       if (IS_ERR(driver->crmu_usb2_ctrl))
+               return PTR_ERR(driver->crmu_usb2_ctrl);
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "usb2-strap");
+-      driver->usb2h_strap_reg = devm_ioremap_resource(dev, res);
++      driver->usb2h_strap_reg = devm_platform_ioremap_resource_byname(pdev, "usb2-strap");
+       if (IS_ERR(driver->usb2h_strap_reg))
+               return PTR_ERR(driver->usb2h_strap_reg);
+--- a/drivers/phy/broadcom/phy-bcm-sr-pcie.c
++++ b/drivers/phy/broadcom/phy-bcm-sr-pcie.c
+@@ -217,7 +217,6 @@ static int sr_pcie_phy_probe(struct plat
+       struct device *dev = &pdev->dev;
+       struct device_node *node = dev->of_node;
+       struct sr_pcie_phy_core *core;
+-      struct resource *res;
+       struct phy_provider *provider;
+       unsigned int phy_idx = 0;
+@@ -226,9 +225,7 @@ static int sr_pcie_phy_probe(struct plat
+               return -ENOMEM;
+       core->dev = dev;
+-
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      core->base = devm_ioremap_resource(core->dev, res);
++      core->base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(core->base))
+               return PTR_ERR(core->base);
+--- a/drivers/phy/broadcom/phy-bcm-sr-usb.c
++++ b/drivers/phy/broadcom/phy-bcm-sr-usb.c
+@@ -300,14 +300,12 @@ static int bcm_usb_phy_probe(struct plat
+       struct device *dev = &pdev->dev;
+       struct device_node *dn = dev->of_node;
+       const struct of_device_id *of_id;
+-      struct resource *res;
+       void __iomem *regs;
+       int ret;
+       enum bcm_usb_phy_version version;
+       struct phy_provider *phy_provider;
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      regs = devm_ioremap_resource(dev, res);
++      regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(regs))
+               return PTR_ERR(regs);
+--- a/drivers/phy/broadcom/phy-brcm-sata.c
++++ b/drivers/phy/broadcom/phy-brcm-sata.c
+@@ -726,7 +726,6 @@ static int brcm_sata_phy_probe(struct pl
+       struct device_node *dn = dev->of_node, *child;
+       const struct of_device_id *of_id;
+       struct brcm_sata_phy *priv;
+-      struct resource *res;
+       struct phy_provider *provider;
+       int ret, count = 0;
+@@ -739,8 +738,7 @@ static int brcm_sata_phy_probe(struct pl
+       dev_set_drvdata(dev, priv);
+       priv->dev = dev;
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
+-      priv->phy_base = devm_ioremap_resource(dev, res);
++      priv->phy_base = devm_platform_ioremap_resource_byname(pdev, "phy");
+       if (IS_ERR(priv->phy_base))
+               return PTR_ERR(priv->phy_base);
+@@ -751,9 +749,7 @@ static int brcm_sata_phy_probe(struct pl
+               priv->version = BRCM_SATA_PHY_STB_28NM;
+       if (priv->version == BRCM_SATA_PHY_IPROC_NS2) {
+-              res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+-                                                 "phy-ctrl");
+-              priv->ctrl_base = devm_ioremap_resource(dev, res);
++              priv->ctrl_base = devm_platform_ioremap_resource_byname(pdev, "phy-ctrl");
+               if (IS_ERR(priv->ctrl_base))
+                       return PTR_ERR(priv->ctrl_base);
+       }
diff --git a/queue-5.10/phy-broadcom-ns-usb3-fix-wvoid-pointer-to-enum-cast-warning.patch b/queue-5.10/phy-broadcom-ns-usb3-fix-wvoid-pointer-to-enum-cast-warning.patch
new file mode 100644 (file)
index 0000000..eda8695
--- /dev/null
@@ -0,0 +1,38 @@
+From stable+bounces-180392-greg=kroah.com@vger.kernel.org Wed Sep 17 16:02:36 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Sep 2025 09:55:00 -0400
+Subject: phy: broadcom: ns-usb3: fix Wvoid-pointer-to-enum-cast warning
+To: stable@vger.kernel.org
+Cc: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>, Vinod Koul <vkoul@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250917135502.565547-4-sashal@kernel.org>
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+[ Upstream commit bd6e74a2f0a0c76dda8e44d26f9b91a797586c3b ]
+
+'family' is an enum, thus cast of pointer on 64-bit compile test with
+W=1 causes:
+
+  drivers/phy/broadcom/phy-bcm-ns-usb3.c:209:17: error: cast to smaller integer type 'enum bcm_ns_family' from 'const void *' [-Werror,-Wvoid-pointer-to-enum-cast]
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20230810111958.205705-2-krzysztof.kozlowski@linaro.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Stable-dep-of: 64961557efa1 ("phy: ti: omap-usb2: fix device leak at unbind")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/phy/broadcom/phy-bcm-ns-usb3.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/phy/broadcom/phy-bcm-ns-usb3.c
++++ b/drivers/phy/broadcom/phy-bcm-ns-usb3.c
+@@ -206,7 +206,7 @@ static int bcm_ns_usb3_mdio_probe(struct
+       of_id = of_match_device(bcm_ns_usb3_id_table, dev);
+       if (!of_id)
+               return -EINVAL;
+-      usb3->family = (enum bcm_ns_family)of_id->data;
++      usb3->family = (uintptr_t)of_id->data;
+       syscon_np = of_parse_phandle(dev->of_node, "usb3-dmp-syscon", 0);
+       err = of_address_to_resource(syscon_np, 0, &res);
diff --git a/queue-5.10/phy-phy-bcm-ns-usb3-drop-support-for-deprecated-dt-binding.patch b/queue-5.10/phy-phy-bcm-ns-usb3-drop-support-for-deprecated-dt-binding.patch
new file mode 100644 (file)
index 0000000..0b9881b
--- /dev/null
@@ -0,0 +1,236 @@
+From stable+bounces-180391-greg=kroah.com@vger.kernel.org Wed Sep 17 16:41:40 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Sep 2025 09:54:59 -0400
+Subject: phy: phy-bcm-ns-usb3: drop support for deprecated DT binding
+To: stable@vger.kernel.org
+Cc: "Rafał Miłecki" <rafal@milecki.pl>, "Florian Fainelli" <f.fainelli@gmail.com>, "Vinod Koul" <vkoul@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20250917135502.565547-3-sashal@kernel.org>
+
+From: Rafał Miłecki <rafal@milecki.pl>
+
+[ Upstream commit 36a94760c98954e50ea621f7a9603fee3621deb7 ]
+
+Initially this PHY driver was implementing MDIO access on its own. It
+was caused by lack of proper hardware design understanding.
+
+It has been changed back in 2017. DT bindings were changed and driver
+was updated to use MDIO layer.
+
+It should be really safe now to drop the old deprecated code. All Linux
+stored DT files don't use it for 3,5 year. There is close to 0 chance
+there is any bootloader with its own DTB using old the binding.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Acked-by: Florian Fainelli <f.fainelli@gmail.com>
+Link: https://lore.kernel.org/r/20201113113423.9466-1-zajec5@gmail.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Stable-dep-of: 64961557efa1 ("phy: ti: omap-usb2: fix device leak at unbind")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/phy/broadcom/phy-bcm-ns-usb3.c |  156 +--------------------------------
+ 1 file changed, 5 insertions(+), 151 deletions(-)
+
+--- a/drivers/phy/broadcom/phy-bcm-ns-usb3.c
++++ b/drivers/phy/broadcom/phy-bcm-ns-usb3.c
+@@ -22,8 +22,6 @@
+ #include <linux/phy/phy.h>
+ #include <linux/slab.h>
+-#define BCM_NS_USB3_MII_MNG_TIMEOUT_US        1000    /* usecs */
+-
+ #define BCM_NS_USB3_PHY_BASE_ADDR_REG 0x1f
+ #define BCM_NS_USB3_PHY_PLL30_BLOCK   0x8000
+ #define BCM_NS_USB3_PHY_TX_PMD_BLOCK  0x8040
+@@ -51,11 +49,8 @@ struct bcm_ns_usb3 {
+       struct device *dev;
+       enum bcm_ns_family family;
+       void __iomem *dmp;
+-      void __iomem *ccb_mii;
+       struct mdio_device *mdiodev;
+       struct phy *phy;
+-
+-      int (*phy_write)(struct bcm_ns_usb3 *usb3, u16 reg, u16 value);
+ };
+ static const struct of_device_id bcm_ns_usb3_id_table[] = {
+@@ -69,13 +64,9 @@ static const struct of_device_id bcm_ns_
+       },
+       {},
+ };
+-MODULE_DEVICE_TABLE(of, bcm_ns_usb3_id_table);
+ static int bcm_ns_usb3_mdio_phy_write(struct bcm_ns_usb3 *usb3, u16 reg,
+-                                    u16 value)
+-{
+-      return usb3->phy_write(usb3, reg, value);
+-}
++                                    u16 value);
+ static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3)
+ {
+@@ -187,8 +178,8 @@ static const struct phy_ops ops = {
+  * MDIO driver code
+  **************************************************/
+-static int bcm_ns_usb3_mdiodev_phy_write(struct bcm_ns_usb3 *usb3, u16 reg,
+-                                       u16 value)
++static int bcm_ns_usb3_mdio_phy_write(struct bcm_ns_usb3 *usb3, u16 reg,
++                                    u16 value)
+ {
+       struct mdio_device *mdiodev = usb3->mdiodev;
+@@ -229,8 +220,6 @@ static int bcm_ns_usb3_mdio_probe(struct
+               return PTR_ERR(usb3->dmp);
+       }
+-      usb3->phy_write = bcm_ns_usb3_mdiodev_phy_write;
+-
+       usb3->phy = devm_phy_create(dev, NULL, &ops);
+       if (IS_ERR(usb3->phy)) {
+               dev_err(dev, "Failed to create PHY\n");
+@@ -254,142 +243,7 @@ static struct mdio_driver bcm_ns_usb3_md
+       .probe = bcm_ns_usb3_mdio_probe,
+ };
+-/**************************************************
+- * Platform driver code
+- **************************************************/
+-
+-static int bcm_ns_usb3_wait_reg(struct bcm_ns_usb3 *usb3, void __iomem *addr,
+-                              u32 mask, u32 value, int usec)
+-{
+-      u32 val;
+-      int ret;
+-
+-      ret = readl_poll_timeout_atomic(addr, val, ((val & mask) == value),
+-                                      10, usec);
+-      if (ret)
+-              dev_err(usb3->dev, "Timeout waiting for register %p\n", addr);
+-
+-      return ret;
+-}
+-
+-static inline int bcm_ns_usb3_mii_mng_wait_idle(struct bcm_ns_usb3 *usb3)
+-{
+-      return bcm_ns_usb3_wait_reg(usb3, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL,
+-                                  0x0100, 0x0000,
+-                                  BCM_NS_USB3_MII_MNG_TIMEOUT_US);
+-}
+-
+-static int bcm_ns_usb3_platform_phy_write(struct bcm_ns_usb3 *usb3, u16 reg,
+-                                        u16 value)
+-{
+-      u32 tmp = 0;
+-      int err;
+-
+-      err = bcm_ns_usb3_mii_mng_wait_idle(usb3);
+-      if (err < 0) {
+-              dev_err(usb3->dev, "Couldn't write 0x%08x value\n", value);
+-              return err;
+-      }
+-
+-      /* TODO: Use a proper MDIO bus layer */
+-      tmp |= 0x58020000; /* Magic value for MDIO PHY write */
+-      tmp |= reg << 18;
+-      tmp |= value;
+-      writel(tmp, usb3->ccb_mii + BCMA_CCB_MII_MNG_CMD_DATA);
+-
+-      return bcm_ns_usb3_mii_mng_wait_idle(usb3);
+-}
+-
+-static int bcm_ns_usb3_probe(struct platform_device *pdev)
+-{
+-      struct device *dev = &pdev->dev;
+-      const struct of_device_id *of_id;
+-      struct bcm_ns_usb3 *usb3;
+-      struct phy_provider *phy_provider;
+-
+-      usb3 = devm_kzalloc(dev, sizeof(*usb3), GFP_KERNEL);
+-      if (!usb3)
+-              return -ENOMEM;
+-
+-      usb3->dev = dev;
+-
+-      of_id = of_match_device(bcm_ns_usb3_id_table, dev);
+-      if (!of_id)
+-              return -EINVAL;
+-      usb3->family = (enum bcm_ns_family)of_id->data;
+-
+-      usb3->dmp = devm_platform_ioremap_resource_byname(pdev, "dmp");
+-      if (IS_ERR(usb3->dmp)) {
+-              dev_err(dev, "Failed to map DMP regs\n");
+-              return PTR_ERR(usb3->dmp);
+-      }
+-
+-      usb3->ccb_mii = devm_platform_ioremap_resource_byname(pdev, "ccb-mii");
+-      if (IS_ERR(usb3->ccb_mii)) {
+-              dev_err(dev, "Failed to map ChipCommon B MII regs\n");
+-              return PTR_ERR(usb3->ccb_mii);
+-      }
+-
+-      /* Enable MDIO. Setting MDCDIV as 26  */
+-      writel(0x0000009a, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL);
+-
+-      /* Wait for MDIO? */
+-      udelay(2);
+-
+-      usb3->phy_write = bcm_ns_usb3_platform_phy_write;
+-
+-      usb3->phy = devm_phy_create(dev, NULL, &ops);
+-      if (IS_ERR(usb3->phy)) {
+-              dev_err(dev, "Failed to create PHY\n");
+-              return PTR_ERR(usb3->phy);
+-      }
+-
+-      phy_set_drvdata(usb3->phy, usb3);
+-      platform_set_drvdata(pdev, usb3);
+-
+-      phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+-      if (!IS_ERR(phy_provider))
+-              dev_info(dev, "Registered Broadcom Northstar USB 3.0 PHY driver\n");
+-
+-      return PTR_ERR_OR_ZERO(phy_provider);
+-}
+-
+-static struct platform_driver bcm_ns_usb3_driver = {
+-      .probe          = bcm_ns_usb3_probe,
+-      .driver = {
+-              .name = "bcm_ns_usb3",
+-              .of_match_table = bcm_ns_usb3_id_table,
+-      },
+-};
+-
+-static int __init bcm_ns_usb3_module_init(void)
+-{
+-      int err;
+-
+-      /*
+-       * For backward compatibility we register as MDIO and platform driver.
+-       * After getting MDIO binding commonly used (e.g. switching all DT files
+-       * to use it) we should deprecate the old binding and eventually drop
+-       * support for it.
+-       */
+-
+-      err = mdio_driver_register(&bcm_ns_usb3_mdio_driver);
+-      if (err)
+-              return err;
+-
+-      err = platform_driver_register(&bcm_ns_usb3_driver);
+-      if (err)
+-              mdio_driver_unregister(&bcm_ns_usb3_mdio_driver);
+-
+-      return err;
+-}
+-module_init(bcm_ns_usb3_module_init);
+-
+-static void __exit bcm_ns_usb3_module_exit(void)
+-{
+-      platform_driver_unregister(&bcm_ns_usb3_driver);
+-      mdio_driver_unregister(&bcm_ns_usb3_mdio_driver);
+-}
+-module_exit(bcm_ns_usb3_module_exit)
++mdio_module_driver(bcm_ns_usb3_mdio_driver);
+ MODULE_LICENSE("GPL v2");
++MODULE_DEVICE_TABLE(of, bcm_ns_usb3_id_table);
diff --git a/queue-5.10/phy-ti-convert-to-devm_platform_ioremap_resource-_byname.patch b/queue-5.10/phy-ti-convert-to-devm_platform_ioremap_resource-_byname.patch
new file mode 100644 (file)
index 0000000..f9b11e7
--- /dev/null
@@ -0,0 +1,131 @@
+From stable+bounces-180390-greg=kroah.com@vger.kernel.org Wed Sep 17 16:41:42 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Sep 2025 09:54:58 -0400
+Subject: phy: ti: convert to devm_platform_ioremap_resource(_byname)
+To: stable@vger.kernel.org
+Cc: Chunfeng Yun <chunfeng.yun@mediatek.com>, Vinod Koul <vkoul@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250917135502.565547-2-sashal@kernel.org>
+
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+
+[ Upstream commit 79caf207d6699419e83ac150accc5c80c5719b47 ]
+
+Use devm_platform_ioremap_resource(_byname) to simplify code
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Link: https://lore.kernel.org/r/1604642930-29019-17-git-send-email-chunfeng.yun@mediatek.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Stable-dep-of: 64961557efa1 ("phy: ti: omap-usb2: fix device leak at unbind")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/phy/ti/phy-omap-control.c |   17 ++++++-----------
+ drivers/phy/ti/phy-omap-usb2.c    |    4 +---
+ drivers/phy/ti/phy-ti-pipe3.c     |   15 ++++-----------
+ 3 files changed, 11 insertions(+), 25 deletions(-)
+
+--- a/drivers/phy/ti/phy-omap-control.c
++++ b/drivers/phy/ti/phy-omap-control.c
+@@ -268,7 +268,6 @@ MODULE_DEVICE_TABLE(of, omap_control_phy
+ static int omap_control_phy_probe(struct platform_device *pdev)
+ {
+-      struct resource *res;
+       const struct of_device_id *of_id;
+       struct omap_control_phy *control_phy;
+@@ -285,16 +284,13 @@ static int omap_control_phy_probe(struct
+       control_phy->type = *(enum omap_control_phy_type *)of_id->data;
+       if (control_phy->type == OMAP_CTRL_TYPE_OTGHS) {
+-              res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+-                      "otghs_control");
+-              control_phy->otghs_control = devm_ioremap_resource(
+-                      &pdev->dev, res);
++              control_phy->otghs_control =
++                      devm_platform_ioremap_resource_byname(pdev, "otghs_control");
+               if (IS_ERR(control_phy->otghs_control))
+                       return PTR_ERR(control_phy->otghs_control);
+       } else {
+-              res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+-                              "power");
+-              control_phy->power = devm_ioremap_resource(&pdev->dev, res);
++              control_phy->power =
++                      devm_platform_ioremap_resource_byname(pdev, "power");
+               if (IS_ERR(control_phy->power)) {
+                       dev_err(&pdev->dev, "Couldn't get power register\n");
+                       return PTR_ERR(control_phy->power);
+@@ -312,9 +308,8 @@ static int omap_control_phy_probe(struct
+       }
+       if (control_phy->type == OMAP_CTRL_TYPE_PCIE) {
+-              res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+-                                                 "pcie_pcs");
+-              control_phy->pcie_pcs = devm_ioremap_resource(&pdev->dev, res);
++              control_phy->pcie_pcs =
++                      devm_platform_ioremap_resource_byname(pdev, "pcie_pcs");
+               if (IS_ERR(control_phy->pcie_pcs))
+                       return PTR_ERR(control_phy->pcie_pcs);
+       }
+--- a/drivers/phy/ti/phy-omap-usb2.c
++++ b/drivers/phy/ti/phy-omap-usb2.c
+@@ -366,7 +366,6 @@ static int omap_usb2_probe(struct platfo
+ {
+       struct omap_usb *phy;
+       struct phy *generic_phy;
+-      struct resource *res;
+       struct phy_provider *phy_provider;
+       struct usb_otg *otg;
+       struct device_node *node = pdev->dev.of_node;
+@@ -403,8 +402,7 @@ static int omap_usb2_probe(struct platfo
+       omap_usb2_init_errata(phy);
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      phy->phy_base = devm_ioremap_resource(&pdev->dev, res);
++      phy->phy_base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(phy->phy_base))
+               return PTR_ERR(phy->phy_base);
+--- a/drivers/phy/ti/phy-ti-pipe3.c
++++ b/drivers/phy/ti/phy-ti-pipe3.c
+@@ -758,35 +758,28 @@ static int ti_pipe3_get_sysctrl(struct t
+ static int ti_pipe3_get_tx_rx_base(struct ti_pipe3 *phy)
+ {
+-      struct resource *res;
+       struct device *dev = phy->dev;
+       struct platform_device *pdev = to_platform_device(dev);
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+-                                         "phy_rx");
+-      phy->phy_rx = devm_ioremap_resource(dev, res);
++      phy->phy_rx = devm_platform_ioremap_resource_byname(pdev, "phy_rx");
+       if (IS_ERR(phy->phy_rx))
+               return PTR_ERR(phy->phy_rx);
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+-                                         "phy_tx");
+-      phy->phy_tx = devm_ioremap_resource(dev, res);
++      phy->phy_tx = devm_platform_ioremap_resource_byname(pdev, "phy_tx");
+       return PTR_ERR_OR_ZERO(phy->phy_tx);
+ }
+ static int ti_pipe3_get_pll_base(struct ti_pipe3 *phy)
+ {
+-      struct resource *res;
+       struct device *dev = phy->dev;
+       struct platform_device *pdev = to_platform_device(dev);
+       if (phy->mode == PIPE3_MODE_PCIE)
+               return 0;
+-      res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+-                                         "pll_ctrl");
+-      phy->pll_ctrl_base = devm_ioremap_resource(dev, res);
++      phy->pll_ctrl_base =
++              devm_platform_ioremap_resource_byname(pdev, "pll_ctrl");
+       return PTR_ERR_OR_ZERO(phy->pll_ctrl_base);
+ }
diff --git a/queue-5.10/phy-ti-omap-usb2-fix-device-leak-at-unbind.patch b/queue-5.10/phy-ti-omap-usb2-fix-device-leak-at-unbind.patch
new file mode 100644 (file)
index 0000000..e1b001b
--- /dev/null
@@ -0,0 +1,63 @@
+From stable+bounces-180394-greg=kroah.com@vger.kernel.org Wed Sep 17 16:42:46 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Sep 2025 09:55:02 -0400
+Subject: phy: ti: omap-usb2: fix device leak at unbind
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Roger Quadros <rogerq@kernel.org>, Vinod Koul <vkoul@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250917135502.565547-6-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 64961557efa1b98f375c0579779e7eeda1a02c42 ]
+
+Make sure to drop the reference to the control device taken by
+of_find_device_by_node() during probe when the driver is unbound.
+
+Fixes: 478b6c7436c2 ("usb: phy: omap-usb2: Don't use omap_get_control_dev()")
+Cc: stable@vger.kernel.org     # 3.13
+Cc: Roger Quadros <rogerq@kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20250724131206.2211-3-johan@kernel.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/phy/ti/phy-omap-usb2.c |   13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/drivers/phy/ti/phy-omap-usb2.c
++++ b/drivers/phy/ti/phy-omap-usb2.c
+@@ -363,6 +363,13 @@ static void omap_usb2_init_errata(struct
+               phy->flags |= OMAP_USB2_DISABLE_CHRG_DET;
+ }
++static void omap_usb2_put_device(void *_dev)
++{
++      struct device *dev = _dev;
++
++      put_device(dev);
++}
++
+ static int omap_usb2_probe(struct platform_device *pdev)
+ {
+       struct omap_usb *phy;
+@@ -373,6 +380,7 @@ static int omap_usb2_probe(struct platfo
+       struct device_node *control_node;
+       struct platform_device *control_pdev;
+       const struct usb_phy_data *phy_data;
++      int ret;
+       phy_data = device_get_match_data(&pdev->dev);
+       if (!phy_data)
+@@ -423,6 +431,11 @@ static int omap_usb2_probe(struct platfo
+                       return -EINVAL;
+               }
+               phy->control_dev = &control_pdev->dev;
++
++              ret = devm_add_action_or_reset(&pdev->dev, omap_usb2_put_device,
++                                             phy->control_dev);
++              if (ret)
++                      return ret;
+       } else {
+               if (of_property_read_u32_index(node,
+                                              "syscon-phy-power", 1,
diff --git a/queue-5.10/phy-use-device_get_match_data.patch b/queue-5.10/phy-use-device_get_match_data.patch
new file mode 100644 (file)
index 0000000..19e6ece
--- /dev/null
@@ -0,0 +1,321 @@
+From stable+bounces-180393-greg=kroah.com@vger.kernel.org Wed Sep 17 16:44:04 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Sep 2025 09:55:01 -0400
+Subject: phy: Use device_get_match_data()
+To: stable@vger.kernel.org
+Cc: Rob Herring <robh@kernel.org>, Heiko Stuebner <heiko@sntech.de>, Vinod Koul <vkoul@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250917135502.565547-5-sashal@kernel.org>
+
+From: Rob Herring <robh@kernel.org>
+
+[ Upstream commit 21bf6fc47a1e45031ba8a7084343b7cfd09ed1d3 ]
+
+Use preferred device_get_match_data() instead of of_match_device() to
+get the driver match data. With this, adjust the includes to explicitly
+include the correct headers.
+
+Signed-off-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://lore.kernel.org/r/20231009172923.2457844-15-robh@kernel.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Stable-dep-of: 64961557efa1 ("phy: ti: omap-usb2: fix device leak at unbind")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/phy/broadcom/phy-bcm-ns-usb3.c   |    9 +++------
+ drivers/phy/marvell/phy-berlin-usb.c     |    7 +++----
+ drivers/phy/ralink/phy-ralink-usb.c      |   10 +++-------
+ drivers/phy/rockchip/phy-rockchip-pcie.c |   11 ++++-------
+ drivers/phy/rockchip/phy-rockchip-usb.c  |   10 +++-------
+ drivers/phy/ti/phy-omap-control.c        |    9 ++-------
+ drivers/phy/ti/phy-omap-usb2.c           |   11 ++++-------
+ drivers/phy/ti/phy-ti-pipe3.c            |   14 ++++----------
+ 8 files changed, 26 insertions(+), 55 deletions(-)
+
+--- a/drivers/phy/broadcom/phy-bcm-ns-usb3.c
++++ b/drivers/phy/broadcom/phy-bcm-ns-usb3.c
+@@ -16,10 +16,11 @@
+ #include <linux/iopoll.h>
+ #include <linux/mdio.h>
+ #include <linux/module.h>
++#include <linux/of.h>
+ #include <linux/of_address.h>
+-#include <linux/of_platform.h>
+ #include <linux/platform_device.h>
+ #include <linux/phy/phy.h>
++#include <linux/property.h>
+ #include <linux/slab.h>
+ #define BCM_NS_USB3_PHY_BASE_ADDR_REG 0x1f
+@@ -189,7 +190,6 @@ static int bcm_ns_usb3_mdio_phy_write(st
+ static int bcm_ns_usb3_mdio_probe(struct mdio_device *mdiodev)
+ {
+       struct device *dev = &mdiodev->dev;
+-      const struct of_device_id *of_id;
+       struct phy_provider *phy_provider;
+       struct device_node *syscon_np;
+       struct bcm_ns_usb3 *usb3;
+@@ -203,10 +203,7 @@ static int bcm_ns_usb3_mdio_probe(struct
+       usb3->dev = dev;
+       usb3->mdiodev = mdiodev;
+-      of_id = of_match_device(bcm_ns_usb3_id_table, dev);
+-      if (!of_id)
+-              return -EINVAL;
+-      usb3->family = (uintptr_t)of_id->data;
++      usb3->family = (enum bcm_ns_family)device_get_match_data(dev);
+       syscon_np = of_parse_phandle(dev->of_node, "usb3-dmp-syscon", 0);
+       err = of_address_to_resource(syscon_np, 0, &res);
+--- a/drivers/phy/marvell/phy-berlin-usb.c
++++ b/drivers/phy/marvell/phy-berlin-usb.c
+@@ -8,9 +8,10 @@
+ #include <linux/io.h>
+ #include <linux/module.h>
+-#include <linux/of_device.h>
++#include <linux/of.h>
+ #include <linux/phy/phy.h>
+ #include <linux/platform_device.h>
++#include <linux/property.h>
+ #include <linux/reset.h>
+ #define USB_PHY_PLL           0x04
+@@ -162,8 +163,6 @@ MODULE_DEVICE_TABLE(of, phy_berlin_usb_o
+ static int phy_berlin_usb_probe(struct platform_device *pdev)
+ {
+-      const struct of_device_id *match =
+-              of_match_device(phy_berlin_usb_of_match, &pdev->dev);
+       struct phy_berlin_usb_priv *priv;
+       struct resource *res;
+       struct phy *phy;
+@@ -182,7 +181,7 @@ static int phy_berlin_usb_probe(struct p
+       if (IS_ERR(priv->rst_ctrl))
+               return PTR_ERR(priv->rst_ctrl);
+-      priv->pll_divider = *((u32 *)match->data);
++      priv->pll_divider = *((u32 *)device_get_match_data(&pdev->dev));
+       phy = devm_phy_create(&pdev->dev, NULL, &phy_berlin_usb_ops);
+       if (IS_ERR(phy)) {
+--- a/drivers/phy/ralink/phy-ralink-usb.c
++++ b/drivers/phy/ralink/phy-ralink-usb.c
+@@ -13,9 +13,10 @@
+ #include <linux/mfd/syscon.h>
+ #include <linux/module.h>
+ #include <linux/mutex.h>
+-#include <linux/of_platform.h>
++#include <linux/of.h>
+ #include <linux/phy/phy.h>
+ #include <linux/platform_device.h>
++#include <linux/platform_device.h>
+ #include <linux/regmap.h>
+ #include <linux/reset.h>
+@@ -172,18 +173,13 @@ static int ralink_usb_phy_probe(struct p
+       struct device *dev = &pdev->dev;
+       struct resource *res;
+       struct phy_provider *phy_provider;
+-      const struct of_device_id *match;
+       struct ralink_usb_phy *phy;
+-      match = of_match_device(ralink_usb_phy_of_match, &pdev->dev);
+-      if (!match)
+-              return -ENODEV;
+-
+       phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+       if (!phy)
+               return -ENOMEM;
+-      phy->clk = (uintptr_t)match->data;
++      phy->clk = (uintptr_t)device_get_match_data(&pdev->dev);
+       phy->base = NULL;
+       phy->sysctl = syscon_regmap_lookup_by_phandle(dev->of_node, "ralink,sysctl");
+--- a/drivers/phy/rockchip/phy-rockchip-pcie.c
++++ b/drivers/phy/rockchip/phy-rockchip-pcie.c
+@@ -12,10 +12,9 @@
+ #include <linux/mfd/syscon.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
+-#include <linux/of_address.h>
+-#include <linux/of_platform.h>
+ #include <linux/phy/phy.h>
+ #include <linux/platform_device.h>
++#include <linux/property.h>
+ #include <linux/regmap.h>
+ #include <linux/reset.h>
+@@ -63,7 +62,7 @@ struct rockchip_pcie_data {
+ };
+ struct rockchip_pcie_phy {
+-      struct rockchip_pcie_data *phy_data;
++      const struct rockchip_pcie_data *phy_data;
+       struct regmap *reg_base;
+       struct phy_pcie_instance {
+               struct phy *phy;
+@@ -365,7 +364,6 @@ static int rockchip_pcie_phy_probe(struc
+       struct rockchip_pcie_phy *rk_phy;
+       struct phy_provider *phy_provider;
+       struct regmap *grf;
+-      const struct of_device_id *of_id;
+       int i;
+       u32 phy_num;
+@@ -379,11 +377,10 @@ static int rockchip_pcie_phy_probe(struc
+       if (!rk_phy)
+               return -ENOMEM;
+-      of_id = of_match_device(rockchip_pcie_phy_dt_ids, &pdev->dev);
+-      if (!of_id)
++      rk_phy->phy_data = device_get_match_data(&pdev->dev);
++      if (!rk_phy->phy_data)
+               return -EINVAL;
+-      rk_phy->phy_data = (struct rockchip_pcie_data *)of_id->data;
+       rk_phy->reg_base = grf;
+       mutex_init(&rk_phy->pcie_mutex);
+--- a/drivers/phy/rockchip/phy-rockchip-usb.c
++++ b/drivers/phy/rockchip/phy-rockchip-usb.c
+@@ -13,10 +13,9 @@
+ #include <linux/module.h>
+ #include <linux/mutex.h>
+ #include <linux/of.h>
+-#include <linux/of_address.h>
+-#include <linux/of_platform.h>
+ #include <linux/phy/phy.h>
+ #include <linux/platform_device.h>
++#include <linux/property.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/reset.h>
+ #include <linux/regmap.h>
+@@ -458,7 +457,6 @@ static int rockchip_usb_phy_probe(struct
+       struct device *dev = &pdev->dev;
+       struct rockchip_usb_phy_base *phy_base;
+       struct phy_provider *phy_provider;
+-      const struct of_device_id *match;
+       struct device_node *child;
+       int err;
+@@ -466,14 +464,12 @@ static int rockchip_usb_phy_probe(struct
+       if (!phy_base)
+               return -ENOMEM;
+-      match = of_match_device(dev->driver->of_match_table, dev);
+-      if (!match || !match->data) {
++      phy_base->pdata = device_get_match_data(dev);
++      if (!phy_base->pdata) {
+               dev_err(dev, "missing phy data\n");
+               return -EINVAL;
+       }
+-      phy_base->pdata = match->data;
+-
+       phy_base->dev = dev;
+       phy_base->reg_base = ERR_PTR(-ENODEV);
+       if (dev->parent && dev->parent->of_node)
+--- a/drivers/phy/ti/phy-omap-control.c
++++ b/drivers/phy/ti/phy-omap-control.c
+@@ -8,9 +8,9 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
++#include <linux/property.h>
+ #include <linux/slab.h>
+ #include <linux/of.h>
+-#include <linux/of_device.h>
+ #include <linux/err.h>
+ #include <linux/io.h>
+ #include <linux/clk.h>
+@@ -268,20 +268,15 @@ MODULE_DEVICE_TABLE(of, omap_control_phy
+ static int omap_control_phy_probe(struct platform_device *pdev)
+ {
+-      const struct of_device_id *of_id;
+       struct omap_control_phy *control_phy;
+-      of_id = of_match_device(omap_control_phy_id_table, &pdev->dev);
+-      if (!of_id)
+-              return -EINVAL;
+-
+       control_phy = devm_kzalloc(&pdev->dev, sizeof(*control_phy),
+               GFP_KERNEL);
+       if (!control_phy)
+               return -ENOMEM;
+       control_phy->dev = &pdev->dev;
+-      control_phy->type = *(enum omap_control_phy_type *)of_id->data;
++      control_phy->type = *(enum omap_control_phy_type *)device_get_match_data(&pdev->dev);
+       if (control_phy->type == OMAP_CTRL_TYPE_OTGHS) {
+               control_phy->otghs_control =
+--- a/drivers/phy/ti/phy-omap-usb2.c
++++ b/drivers/phy/ti/phy-omap-usb2.c
+@@ -19,6 +19,7 @@
+ #include <linux/phy/phy.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
++#include <linux/property.h>
+ #include <linux/regmap.h>
+ #include <linux/slab.h>
+ #include <linux/sys_soc.h>
+@@ -371,16 +372,12 @@ static int omap_usb2_probe(struct platfo
+       struct device_node *node = pdev->dev.of_node;
+       struct device_node *control_node;
+       struct platform_device *control_pdev;
+-      const struct of_device_id *of_id;
+-      struct usb_phy_data *phy_data;
++      const struct usb_phy_data *phy_data;
+-      of_id = of_match_device(omap_usb2_id_table, &pdev->dev);
+-
+-      if (!of_id)
++      phy_data = device_get_match_data(&pdev->dev);
++      if (!phy_data)
+               return -EINVAL;
+-      phy_data = (struct usb_phy_data *)of_id->data;
+-
+       phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
+       if (!phy)
+               return -ENOMEM;
+--- a/drivers/phy/ti/phy-ti-pipe3.c
++++ b/drivers/phy/ti/phy-ti-pipe3.c
+@@ -8,6 +8,7 @@
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
++#include <linux/property.h>
+ #include <linux/slab.h>
+ #include <linux/phy/phy.h>
+ #include <linux/of.h>
+@@ -790,23 +791,16 @@ static int ti_pipe3_probe(struct platfor
+       struct phy_provider *phy_provider;
+       struct device *dev = &pdev->dev;
+       int ret;
+-      const struct of_device_id *match;
+-      struct pipe3_data *data;
++      const struct pipe3_data *data;
+       phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+       if (!phy)
+               return -ENOMEM;
+-      match = of_match_device(ti_pipe3_id_table, dev);
+-      if (!match)
++      data = device_get_match_data(dev);
++      if (!data)
+               return -EINVAL;
+-      data = (struct pipe3_data *)match->data;
+-      if (!data) {
+-              dev_err(dev, "no driver data\n");
+-              return -EINVAL;
+-      }
+-
+       phy->dev = dev;
+       phy->mode = data->mode;
+       phy->dpll_map = data->dpll_map;
diff --git a/queue-5.10/serial-sc16is7xx-fix-bug-in-flow-control-levels-init.patch b/queue-5.10/serial-sc16is7xx-fix-bug-in-flow-control-levels-init.patch
new file mode 100644 (file)
index 0000000..268b203
--- /dev/null
@@ -0,0 +1,96 @@
+From sashal@kernel.org Wed Sep 17 14:45:02 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Sep 2025 08:44:59 -0400
+Subject: serial: sc16is7xx: fix bug in flow control levels init
+To: stable@vger.kernel.org
+Cc: Hugo Villeneuve <hvilleneuve@dimonoff.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250917124459.518238-1-sashal@kernel.org>
+
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+
+[ Upstream commit 535fd4c98452c87537a40610abba45daf5761ec6 ]
+
+When trying to set MCR[2], XON1 is incorrectly accessed instead. And when
+writing to the TCR register to configure flow control levels, we are
+incorrectly writing to the MSR register. The default value of $00 is then
+used for TCR, which means that selectable trigger levels in FCR are used
+in place of TCR.
+
+TCR/TLR access requires EFR[4] (enable enhanced functions) and MCR[2]
+to be set. EFR[4] is already set in probe().
+
+MCR access requires LCR[7] to be zero.
+
+Since LCR is set to $BF when trying to set MCR[2], XON1 is incorrectly
+accessed instead because MCR shares the same address space as XON1.
+
+Since MCR[2] is unmodified and still zero, when writing to TCR we are in
+fact writing to MSR because TCR/TLR registers share the same address space
+as MSR/SPR.
+
+Fix by first removing useless reconfiguration of EFR[4] (enable enhanced
+functions), as it is already enabled in sc16is7xx_probe() since commit
+43c51bb573aa ("sc16is7xx: make sure device is in suspend once probed").
+Now LCR is $00, which means that MCR access is enabled.
+
+Also remove regcache_cache_bypass() calls since we no longer access the
+enhanced registers set, and TCR is already declared as volatile (in fact
+by declaring MSR as volatile, which shares the same address).
+
+Finally disable access to TCR/TLR registers after modifying them by
+clearing MCR[2].
+
+Note: the comment about "... and internal clock div" is wrong and can be
+      ignored/removed as access to internal clock div registers (DLL/DLH)
+      is permitted only when LCR[7] is logic 1, not when enhanced features
+      is enabled. And DLL/DLH access is not needed in sc16is7xx_startup().
+
+Fixes: dfeae619d781 ("serial: sc16is7xx")
+Cc: stable@vger.kernel.org
+Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Link: https://lore.kernel.org/r/20250731124451.1108864-1-hugo@hugovil.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ changed regmap variable from one->regmap to s->regmap ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/sc16is7xx.c |   14 ++------------
+ 1 file changed, 2 insertions(+), 12 deletions(-)
+
+--- a/drivers/tty/serial/sc16is7xx.c
++++ b/drivers/tty/serial/sc16is7xx.c
+@@ -1018,7 +1018,6 @@ static int sc16is7xx_config_rs485(struct
+ static int sc16is7xx_startup(struct uart_port *port)
+ {
+       struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
+-      struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
+       unsigned int val;
+       sc16is7xx_power(port, 1);
+@@ -1030,16 +1029,6 @@ static int sc16is7xx_startup(struct uart
+       sc16is7xx_port_write(port, SC16IS7XX_FCR_REG,
+                            SC16IS7XX_FCR_FIFO_BIT);
+-      /* Enable EFR */
+-      sc16is7xx_port_write(port, SC16IS7XX_LCR_REG,
+-                           SC16IS7XX_LCR_CONF_MODE_B);
+-
+-      regcache_cache_bypass(s->regmap, true);
+-
+-      /* Enable write access to enhanced features and internal clock div */
+-      sc16is7xx_port_write(port, SC16IS7XX_EFR_REG,
+-                           SC16IS7XX_EFR_ENABLE_BIT);
+-
+       /* Enable TCR/TLR */
+       sc16is7xx_port_update(port, SC16IS7XX_MCR_REG,
+                             SC16IS7XX_MCR_TCRTLR_BIT,
+@@ -1051,7 +1040,8 @@ static int sc16is7xx_startup(struct uart
+                            SC16IS7XX_TCR_RX_RESUME(24) |
+                            SC16IS7XX_TCR_RX_HALT(48));
+-      regcache_cache_bypass(s->regmap, false);
++      /* Disable TCR/TLR access */
++      sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, SC16IS7XX_MCR_TCRTLR_BIT, 0);
+       /* Now, initialize the UART */
+       sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_WORD_LEN_8);
index 1e7f6493787ab419dbb4bd067dd21457c071895e..18f5614af08ecab2fccecde17f7eb3e7df929d33 100644 (file)
@@ -66,3 +66,14 @@ asoc-wm8974-correct-pll-rate-rounding.patch
 asoc-sof-intel-hda-stream-fix-incorrect-variable-use.patch
 drm-bridge-cdns-mhdp8546-fix-missing-mutex-unlock-on.patch
 crypto-af_alg-disallow-concurrent-writes-in-af_alg_s.patch
+serial-sc16is7xx-fix-bug-in-flow-control-levels-init.patch
+usb-gadget-dummy_hcd-remove-usage-of-list-iterator-past-the-loop-body.patch
+usb-gadget-dummy-hcd-fix-locking-bug-in-rt-enabled-kernels.patch
+xhci-dbc-decouple-endpoint-allocation-from-initialization.patch
+xhci-dbc-fix-full-dbc-transfer-ring-after-several-reconnects.patch
+phy-broadcom-convert-to-devm_platform_ioremap_resource-_byname.patch
+phy-ti-convert-to-devm_platform_ioremap_resource-_byname.patch
+phy-phy-bcm-ns-usb3-drop-support-for-deprecated-dt-binding.patch
+phy-broadcom-ns-usb3-fix-wvoid-pointer-to-enum-cast-warning.patch
+phy-use-device_get_match_data.patch
+phy-ti-omap-usb2-fix-device-leak-at-unbind.patch
diff --git a/queue-5.10/usb-gadget-dummy-hcd-fix-locking-bug-in-rt-enabled-kernels.patch b/queue-5.10/usb-gadget-dummy-hcd-fix-locking-bug-in-rt-enabled-kernels.patch
new file mode 100644 (file)
index 0000000..7fe80b1
--- /dev/null
@@ -0,0 +1,95 @@
+From sashal@kernel.org Wed Sep 17 15:25:47 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Sep 2025 09:25:43 -0400
+Subject: USB: gadget: dummy-hcd: Fix locking bug in RT-enabled kernels
+To: stable@vger.kernel.org
+Cc: Alan Stern <stern@rowland.harvard.edu>, stable <stable@kernel.org>, Yunseong Kim <ysk@kzalloc.com>, syzbot+8baacc4139f12fa77909@syzkaller.appspotmail.com, Sebastian Andrzej Siewior <bigeasy@linutronix.de>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250917132543.548029-2-sashal@kernel.org>
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+[ Upstream commit 8d63c83d8eb922f6c316320f50c82fa88d099bea ]
+
+Yunseong Kim and the syzbot fuzzer both reported a problem in
+RT-enabled kernels caused by the way dummy-hcd mixes interrupt
+management and spin-locking.  The pattern was:
+
+       local_irq_save(flags);
+       spin_lock(&dum->lock);
+       ...
+       spin_unlock(&dum->lock);
+       ...             // calls usb_gadget_giveback_request()
+       local_irq_restore(flags);
+
+The code was written this way because usb_gadget_giveback_request()
+needs to be called with interrupts disabled and the private lock not
+held.
+
+While this pattern works fine in non-RT kernels, it's not good when RT
+is enabled.  RT kernels handle spinlocks much like mutexes; in particular,
+spin_lock() may sleep.  But sleeping is not allowed while local
+interrupts are disabled.
+
+To fix the problem, rewrite the code to conform to the pattern used
+elsewhere in dummy-hcd and other UDC drivers:
+
+       spin_lock_irqsave(&dum->lock, flags);
+       ...
+       spin_unlock(&dum->lock);
+       usb_gadget_giveback_request(...);
+       spin_lock(&dum->lock);
+       ...
+       spin_unlock_irqrestore(&dum->lock, flags);
+
+This approach satisfies the RT requirements.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Cc: stable <stable@kernel.org>
+Fixes: b4dbda1a22d2 ("USB: dummy-hcd: disable interrupts during req->complete")
+Reported-by: Yunseong Kim <ysk@kzalloc.com>
+Closes: <https://lore.kernel.org/linux-usb/5b337389-73b9-4ee4-a83e-7e82bf5af87a@kzalloc.com/>
+Reported-by: syzbot+8baacc4139f12fa77909@syzkaller.appspotmail.com
+Closes: <https://lore.kernel.org/linux-usb/68ac2411.050a0220.37038e.0087.GAE@google.com/>
+Tested-by: syzbot+8baacc4139f12fa77909@syzkaller.appspotmail.com
+CC: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+CC: stable@vger.kernel.org
+Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: https://lore.kernel.org/r/bb192ae2-4eee-48ee-981f-3efdbbd0d8f0@rowland.harvard.edu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/udc/dummy_hcd.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/gadget/udc/dummy_hcd.c
++++ b/drivers/usb/gadget/udc/dummy_hcd.c
+@@ -759,8 +759,7 @@ static int dummy_dequeue(struct usb_ep *
+       if (!dum->driver)
+               return -ESHUTDOWN;
+-      local_irq_save(flags);
+-      spin_lock(&dum->lock);
++      spin_lock_irqsave(&dum->lock, flags);
+       list_for_each_entry(iter, &ep->queue, queue) {
+               if (&iter->req != _req)
+                       continue;
+@@ -770,15 +769,16 @@ static int dummy_dequeue(struct usb_ep *
+               retval = 0;
+               break;
+       }
+-      spin_unlock(&dum->lock);
+       if (retval == 0) {
+               dev_dbg(udc_dev(dum),
+                               "dequeued req %p from %s, len %d buf %p\n",
+                               req, _ep->name, _req->length, _req->buf);
++              spin_unlock(&dum->lock);
+               usb_gadget_giveback_request(_ep, _req);
++              spin_lock(&dum->lock);
+       }
+-      local_irq_restore(flags);
++      spin_unlock_irqrestore(&dum->lock, flags);
+       return retval;
+ }
diff --git a/queue-5.10/usb-gadget-dummy_hcd-remove-usage-of-list-iterator-past-the-loop-body.patch b/queue-5.10/usb-gadget-dummy_hcd-remove-usage-of-list-iterator-past-the-loop-body.patch
new file mode 100644 (file)
index 0000000..f0c9165
--- /dev/null
@@ -0,0 +1,63 @@
+From sashal@kernel.org Wed Sep 17 15:25:46 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Sep 2025 09:25:42 -0400
+Subject: usb: gadget: dummy_hcd: remove usage of list iterator past the loop body
+To: stable@vger.kernel.org
+Cc: Jakob Koschel <jakobkoschel@gmail.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250917132543.548029-1-sashal@kernel.org>
+
+From: Jakob Koschel <jakobkoschel@gmail.com>
+
+[ Upstream commit 7975f080d3557725160a878b1a64339043ba3d91 ]
+
+To move the list iterator variable into the list_for_each_entry_*()
+macro in the future it should be avoided to use the list iterator
+variable after the loop body.
+
+To *never* use the list iterator variable after the loop it was
+concluded to use a separate iterator variable [1].
+
+Link: https://lore.kernel.org/all/YhdfEIwI4EdtHdym@kroah.com/
+Signed-off-by: Jakob Koschel <jakobkoschel@gmail.com>
+Link: https://lore.kernel.org/r/20220308171818.384491-26-jakobkoschel@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 8d63c83d8eb9 ("USB: gadget: dummy-hcd: Fix locking bug in RT-enabled kernels")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/udc/dummy_hcd.c |   17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/gadget/udc/dummy_hcd.c
++++ b/drivers/usb/gadget/udc/dummy_hcd.c
+@@ -749,7 +749,7 @@ static int dummy_dequeue(struct usb_ep *
+       struct dummy            *dum;
+       int                     retval = -EINVAL;
+       unsigned long           flags;
+-      struct dummy_request    *req = NULL;
++      struct dummy_request    *req = NULL, *iter;
+       if (!_ep || !_req)
+               return retval;
+@@ -761,13 +761,14 @@ static int dummy_dequeue(struct usb_ep *
+       local_irq_save(flags);
+       spin_lock(&dum->lock);
+-      list_for_each_entry(req, &ep->queue, queue) {
+-              if (&req->req == _req) {
+-                      list_del_init(&req->queue);
+-                      _req->status = -ECONNRESET;
+-                      retval = 0;
+-                      break;
+-              }
++      list_for_each_entry(iter, &ep->queue, queue) {
++              if (&iter->req != _req)
++                      continue;
++              list_del_init(&iter->queue);
++              _req->status = -ECONNRESET;
++              req = iter;
++              retval = 0;
++              break;
+       }
+       spin_unlock(&dum->lock);
diff --git a/queue-5.10/xhci-dbc-decouple-endpoint-allocation-from-initialization.patch b/queue-5.10/xhci-dbc-decouple-endpoint-allocation-from-initialization.patch
new file mode 100644 (file)
index 0000000..8978206
--- /dev/null
@@ -0,0 +1,140 @@
+From sashal@kernel.org Wed Sep 17 16:11:05 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Sep 2025 10:11:00 -0400
+Subject: xhci: dbc: decouple endpoint allocation from initialization
+To: stable@vger.kernel.org
+Cc: Mathias Nyman <mathias.nyman@linux.intel.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250917141101.578289-1-sashal@kernel.org>
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+[ Upstream commit 220a0ffde02f962c13bc752b01aa570b8c65a37b ]
+
+Decouple allocation of endpoint ring buffer from initialization
+of the buffer, and initialization of endpoint context parts from
+from the rest of the contexts.
+
+It allows driver to clear up and reinitialize endpoint rings
+after disconnect without reallocating everything.
+
+This is a prerequisite for the next patch that prevents the transfer
+ring from filling up with cancelled (no-op) TRBs if a debug cable is
+reconnected several times without transferring anything.
+
+Cc: stable@vger.kernel.org
+Fixes: dfba2174dc42 ("usb: xhci: Add DbC support in xHCI driver")
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20250902105306.877476-2-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-dbgcap.c |   71 ++++++++++++++++++++++++++---------------
+ 1 file changed, 46 insertions(+), 25 deletions(-)
+
+--- a/drivers/usb/host/xhci-dbgcap.c
++++ b/drivers/usb/host/xhci-dbgcap.c
+@@ -86,13 +86,34 @@ static u32 xhci_dbc_populate_strings(str
+       return string_length;
+ }
++static void xhci_dbc_init_ep_contexts(struct xhci_dbc *dbc)
++{
++      struct xhci_ep_ctx      *ep_ctx;
++      unsigned int            max_burst;
++      dma_addr_t              deq;
++
++      max_burst               = DBC_CTRL_MAXBURST(readl(&dbc->regs->control));
++
++      /* Populate bulk out endpoint context: */
++      ep_ctx                  = dbc_bulkout_ctx(dbc);
++      deq                     = dbc_bulkout_enq(dbc);
++      ep_ctx->ep_info         = 0;
++      ep_ctx->ep_info2        = dbc_epctx_info2(BULK_OUT_EP, 1024, max_burst);
++      ep_ctx->deq             = cpu_to_le64(deq | dbc->ring_out->cycle_state);
++
++      /* Populate bulk in endpoint context: */
++      ep_ctx                  = dbc_bulkin_ctx(dbc);
++      deq                     = dbc_bulkin_enq(dbc);
++      ep_ctx->ep_info         = 0;
++      ep_ctx->ep_info2        = dbc_epctx_info2(BULK_IN_EP, 1024, max_burst);
++      ep_ctx->deq             = cpu_to_le64(deq | dbc->ring_in->cycle_state);
++}
++
+ static void xhci_dbc_init_contexts(struct xhci_dbc *dbc, u32 string_length)
+ {
+       struct dbc_info_context *info;
+-      struct xhci_ep_ctx      *ep_ctx;
+       u32                     dev_info;
+-      dma_addr_t              deq, dma;
+-      unsigned int            max_burst;
++      dma_addr_t              dma;
+       if (!dbc)
+               return;
+@@ -106,20 +127,8 @@ static void xhci_dbc_init_contexts(struc
+       info->serial            = cpu_to_le64(dma + DBC_MAX_STRING_LENGTH * 3);
+       info->length            = cpu_to_le32(string_length);
+-      /* Populate bulk out endpoint context: */
+-      ep_ctx                  = dbc_bulkout_ctx(dbc);
+-      max_burst               = DBC_CTRL_MAXBURST(readl(&dbc->regs->control));
+-      deq                     = dbc_bulkout_enq(dbc);
+-      ep_ctx->ep_info         = 0;
+-      ep_ctx->ep_info2        = dbc_epctx_info2(BULK_OUT_EP, 1024, max_burst);
+-      ep_ctx->deq             = cpu_to_le64(deq | dbc->ring_out->cycle_state);
+-
+-      /* Populate bulk in endpoint context: */
+-      ep_ctx                  = dbc_bulkin_ctx(dbc);
+-      deq                     = dbc_bulkin_enq(dbc);
+-      ep_ctx->ep_info         = 0;
+-      ep_ctx->ep_info2        = dbc_epctx_info2(BULK_IN_EP, 1024, max_burst);
+-      ep_ctx->deq             = cpu_to_le64(deq | dbc->ring_in->cycle_state);
++      /* Populate bulk in and out endpoint contexts: */
++      xhci_dbc_init_ep_contexts(dbc);
+       /* Set DbC context and info registers: */
+       lo_hi_writeq(dbc->ctx->dma, &dbc->regs->dccp);
+@@ -421,6 +430,23 @@ dbc_alloc_ctx(struct device *dev, gfp_t
+       return ctx;
+ }
++static void xhci_dbc_ring_init(struct xhci_ring *ring)
++{
++      struct xhci_segment *seg = ring->first_seg;
++
++      /* clear all trbs on ring in case of old ring */
++      memset(seg->trbs, 0, TRB_SEGMENT_SIZE);
++
++      /* Only event ring does not use link TRB */
++      if (ring->type != TYPE_EVENT) {
++              union xhci_trb *trb = &seg->trbs[TRBS_PER_SEGMENT - 1];
++
++              trb->link.segment_ptr = cpu_to_le64(ring->first_seg->dma);
++              trb->link.control = cpu_to_le32(LINK_TOGGLE | TRB_TYPE(TRB_LINK));
++      }
++      xhci_initialize_ring_info(ring, 1);
++}
++
+ static struct xhci_ring *
+ xhci_dbc_ring_alloc(struct device *dev, enum xhci_ring_type type, gfp_t flags)
+ {
+@@ -449,15 +475,10 @@ xhci_dbc_ring_alloc(struct device *dev,
+       seg->dma = dma;
+-      /* Only event ring does not use link TRB */
+-      if (type != TYPE_EVENT) {
+-              union xhci_trb *trb = &seg->trbs[TRBS_PER_SEGMENT - 1];
+-
+-              trb->link.segment_ptr = cpu_to_le64(dma);
+-              trb->link.control = cpu_to_le32(LINK_TOGGLE | TRB_TYPE(TRB_LINK));
+-      }
+       INIT_LIST_HEAD(&ring->td_list);
+-      xhci_initialize_ring_info(ring, 1);
++
++      xhci_dbc_ring_init(ring);
++
+       return ring;
+ dma_fail:
+       kfree(seg);
diff --git a/queue-5.10/xhci-dbc-fix-full-dbc-transfer-ring-after-several-reconnects.patch b/queue-5.10/xhci-dbc-fix-full-dbc-transfer-ring-after-several-reconnects.patch
new file mode 100644 (file)
index 0000000..0816251
--- /dev/null
@@ -0,0 +1,91 @@
+From sashal@kernel.org Wed Sep 17 16:11:05 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Sep 2025 10:11:01 -0400
+Subject: xhci: dbc: Fix full DbC transfer ring after several reconnects
+To: stable@vger.kernel.org
+Cc: Mathias Nyman <mathias.nyman@linux.intel.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250917141101.578289-2-sashal@kernel.org>
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+[ Upstream commit a5c98e8b1398534ae1feb6e95e2d3ee5215538ed ]
+
+Pending requests will be flushed on disconnect, and the corresponding
+TRBs will be turned into No-op TRBs, which are ignored by the xHC
+controller once it starts processing the ring.
+
+If the USB debug cable repeatedly disconnects before ring is started
+then the ring will eventually be filled with No-op TRBs.
+No new transfers can be queued when the ring is full, and driver will
+print the following error message:
+
+    "xhci_hcd 0000:00:14.0: failed to queue trbs"
+
+This is a normal case for 'in' transfers where TRBs are always enqueued
+in advance, ready to take on incoming data. If no data arrives, and
+device is disconnected, then ring dequeue will remain at beginning of
+the ring while enqueue points to first free TRB after last cancelled
+No-op TRB.
+s
+Solve this by reinitializing the rings when the debug cable disconnects
+and DbC is leaving the configured state.
+Clear the whole ring buffer and set enqueue and dequeue to the beginning
+of ring, and set cycle bit to its initial state.
+
+Cc: stable@vger.kernel.org
+Fixes: dfba2174dc42 ("usb: xhci: Add DbC support in xHCI driver")
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20250902105306.877476-3-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-dbgcap.c |   23 +++++++++++++++++++++--
+ 1 file changed, 21 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/xhci-dbgcap.c
++++ b/drivers/usb/host/xhci-dbgcap.c
+@@ -447,6 +447,25 @@ static void xhci_dbc_ring_init(struct xh
+       xhci_initialize_ring_info(ring, 1);
+ }
++static int xhci_dbc_reinit_ep_rings(struct xhci_dbc *dbc)
++{
++      struct xhci_ring *in_ring = dbc->eps[BULK_IN].ring;
++      struct xhci_ring *out_ring = dbc->eps[BULK_OUT].ring;
++
++      if (!in_ring || !out_ring || !dbc->ctx) {
++              dev_warn(dbc->dev, "Can't re-init unallocated endpoints\n");
++              return -ENODEV;
++      }
++
++      xhci_dbc_ring_init(in_ring);
++      xhci_dbc_ring_init(out_ring);
++
++      /* set ep context enqueue, dequeue, and cycle to initial values */
++      xhci_dbc_init_ep_contexts(dbc);
++
++      return 0;
++}
++
+ static struct xhci_ring *
+ xhci_dbc_ring_alloc(struct device *dev, enum xhci_ring_type type, gfp_t flags)
+ {
+@@ -871,7 +890,7 @@ static enum evtreturn xhci_dbc_do_handle
+                       dev_info(dbc->dev, "DbC cable unplugged\n");
+                       dbc->state = DS_ENABLED;
+                       xhci_dbc_flush_requests(dbc);
+-
++                      xhci_dbc_reinit_ep_rings(dbc);
+                       return EVT_DISC;
+               }
+@@ -881,7 +900,7 @@ static enum evtreturn xhci_dbc_do_handle
+                       writel(portsc, &dbc->regs->portsc);
+                       dbc->state = DS_ENABLED;
+                       xhci_dbc_flush_requests(dbc);
+-
++                      xhci_dbc_reinit_ep_rings(dbc);
+                       return EVT_DISC;
+               }