From: Greg Kroah-Hartman Date: Mon, 29 Aug 2022 08:11:48 +0000 (+0200) Subject: 5.15-stable patches X-Git-Tag: v5.10.140~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=88f785c5d83857d9b860dddb0e91675887d9a0b0;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: revert-usbnet-smsc95xx-fix-deadlock-on-runtime-resume.patch revert-usbnet-smsc95xx-forward-phy-interrupts-to-phy-driver-to-avoid-polling.patch --- diff --git a/queue-5.15/revert-usbnet-smsc95xx-fix-deadlock-on-runtime-resume.patch b/queue-5.15/revert-usbnet-smsc95xx-fix-deadlock-on-runtime-resume.patch new file mode 100644 index 00000000000..ca296ed0ac4 --- /dev/null +++ b/queue-5.15/revert-usbnet-smsc95xx-fix-deadlock-on-runtime-resume.patch @@ -0,0 +1,146 @@ +From foo@baz Mon Aug 29 10:10:59 AM CEST 2022 +From: Greg Kroah-Hartman +Date: Mon, 29 Aug 2022 10:06:53 +0200 +Subject: Revert "usbnet: smsc95xx: Fix deadlock on runtime resume" + +From: Greg Kroah-Hartman + +This reverts commit b574d1e3e9a2432b5acd9c4a9dc8d70b6a37aaf1 which is +commit 7b960c967f2aa01ab8f45c5a0bd78e754cffdeee upstream. + +It is reported to cause problems, so drop it from the 5.15.y tree until +the root cause can be determined. + +Reported-by: Lukas Wunner +Cc: Oleksij Rempel +Cc: Ferry Toth +Cc: Andrew Lunn +Cc: Andre Edich +Cc: David S. Miller +Cc: Sasha Levin +Link: https://lore.kernel.org/r/20220826132137.GA24932@wunner.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/smsc95xx.c | 26 ++++++-------------------- + 1 file changed, 6 insertions(+), 20 deletions(-) + +--- a/drivers/net/usb/smsc95xx.c ++++ b/drivers/net/usb/smsc95xx.c +@@ -69,7 +69,6 @@ struct smsc95xx_priv { + struct fwnode_handle *irqfwnode; + struct mii_bus *mdiobus; + struct phy_device *phydev; +- struct task_struct *pm_task; + }; + + static bool turbo_mode = true; +@@ -79,14 +78,13 @@ MODULE_PARM_DESC(turbo_mode, "Enable mul + static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index, + u32 *data, int in_pm) + { +- struct smsc95xx_priv *pdata = dev->driver_priv; + u32 buf; + int ret; + int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16); + + BUG_ON(!dev); + +- if (current != pdata->pm_task) ++ if (!in_pm) + fn = usbnet_read_cmd; + else + fn = usbnet_read_cmd_nopm; +@@ -110,14 +108,13 @@ static int __must_check __smsc95xx_read_ + static int __must_check __smsc95xx_write_reg(struct usbnet *dev, u32 index, + u32 data, int in_pm) + { +- struct smsc95xx_priv *pdata = dev->driver_priv; + u32 buf; + int ret; + int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16); + + BUG_ON(!dev); + +- if (current != pdata->pm_task) ++ if (!in_pm) + fn = usbnet_write_cmd; + else + fn = usbnet_write_cmd_nopm; +@@ -1485,12 +1482,9 @@ static int smsc95xx_suspend(struct usb_i + u32 val, link_up; + int ret; + +- pdata->pm_task = current; +- + ret = usbnet_suspend(intf, message); + if (ret < 0) { + netdev_warn(dev->net, "usbnet_suspend error\n"); +- pdata->pm_task = NULL; + return ret; + } + +@@ -1730,7 +1724,6 @@ done: + if (ret && PMSG_IS_AUTO(message)) + usbnet_resume(intf); + +- pdata->pm_task = NULL; + return ret; + } + +@@ -1751,31 +1744,29 @@ static int smsc95xx_resume(struct usb_in + /* do this first to ensure it's cleared even in error case */ + pdata->suspend_flags = 0; + +- pdata->pm_task = current; +- + if (suspend_flags & SUSPEND_ALLMODES) { + /* clear wake-up sources */ + ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val); + if (ret < 0) +- goto done; ++ return ret; + + val &= ~(WUCSR_WAKE_EN_ | WUCSR_MPEN_); + + ret = smsc95xx_write_reg_nopm(dev, WUCSR, val); + if (ret < 0) +- goto done; ++ return ret; + + /* clear wake-up status */ + ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); + if (ret < 0) +- goto done; ++ return ret; + + val &= ~PM_CTL_WOL_EN_; + val |= PM_CTL_WUPS_; + + ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val); + if (ret < 0) +- goto done; ++ return ret; + } + + phy_init_hw(pdata->phydev); +@@ -1784,20 +1775,15 @@ static int smsc95xx_resume(struct usb_in + if (ret < 0) + netdev_warn(dev->net, "usbnet_resume error\n"); + +-done: +- pdata->pm_task = NULL; + return ret; + } + + static int smsc95xx_reset_resume(struct usb_interface *intf) + { + struct usbnet *dev = usb_get_intfdata(intf); +- struct smsc95xx_priv *pdata = dev->driver_priv; + int ret; + +- pdata->pm_task = current; + ret = smsc95xx_reset(dev); +- pdata->pm_task = NULL; + if (ret < 0) + return ret; + diff --git a/queue-5.15/revert-usbnet-smsc95xx-forward-phy-interrupts-to-phy-driver-to-avoid-polling.patch b/queue-5.15/revert-usbnet-smsc95xx-forward-phy-interrupts-to-phy-driver-to-avoid-polling.patch new file mode 100644 index 00000000000..221e44dae26 --- /dev/null +++ b/queue-5.15/revert-usbnet-smsc95xx-forward-phy-interrupts-to-phy-driver-to-avoid-polling.patch @@ -0,0 +1,262 @@ +From foo@baz Mon Aug 29 10:10:59 AM CEST 2022 +From: Greg Kroah-Hartman +Date: Mon, 29 Aug 2022 10:07:09 +0200 +Subject: Revert "usbnet: smsc95xx: Forward PHY interrupts to PHY driver to avoid polling" + +From: Greg Kroah-Hartman + +This reverts commit eaf3a094d8924ecb0baacf6df62ae1c6a96083cf which is +upstream commit 1ce8b37241ed291af56f7a49bbdbf20c08728e88. + +It is reported to cause problems, so drop it from the 5.15.y tree until +the root cause can be determined. + +Reported-by: Lukas Wunner +Cc: Oleksij Rempel +Cc: Ferry Toth +Cc: Andrew Lunn +Cc: Andre Edich +Cc: David S. Miller +Cc: Sasha Levin +Link: https://lore.kernel.org/r/20220826132137.GA24932@wunner.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/smsc95xx.c | 113 ++++++++++++++++++++------------------------- + 1 file changed, 52 insertions(+), 61 deletions(-) + +--- a/drivers/net/usb/smsc95xx.c ++++ b/drivers/net/usb/smsc95xx.c +@@ -18,8 +18,6 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include "smsc95xx.h" +@@ -53,9 +51,6 @@ + #define SUSPEND_ALLMODES (SUSPEND_SUSPEND0 | SUSPEND_SUSPEND1 | \ + SUSPEND_SUSPEND2 | SUSPEND_SUSPEND3) + +-#define SMSC95XX_NR_IRQS (1) /* raise to 12 for GPIOs */ +-#define PHY_HWIRQ (SMSC95XX_NR_IRQS - 1) +- + struct smsc95xx_priv { + u32 mac_cr; + u32 hash_hi; +@@ -64,9 +59,6 @@ struct smsc95xx_priv { + spinlock_t mac_cr_lock; + u8 features; + u8 suspend_flags; +- struct irq_chip irqchip; +- struct irq_domain *irqdomain; +- struct fwnode_handle *irqfwnode; + struct mii_bus *mdiobus; + struct phy_device *phydev; + }; +@@ -603,8 +595,6 @@ static void smsc95xx_mac_update_fulldupl + + static void smsc95xx_status(struct usbnet *dev, struct urb *urb) + { +- struct smsc95xx_priv *pdata = dev->driver_priv; +- unsigned long flags; + u32 intdata; + + if (urb->actual_length != 4) { +@@ -616,15 +606,11 @@ static void smsc95xx_status(struct usbne + intdata = get_unaligned_le32(urb->transfer_buffer); + netif_dbg(dev, link, dev->net, "intdata: 0x%08X\n", intdata); + +- local_irq_save(flags); +- + if (intdata & INT_ENP_PHY_INT_) +- generic_handle_domain_irq(pdata->irqdomain, PHY_HWIRQ); ++ ; + else + netdev_warn(dev->net, "unexpected interrupt, intdata=0x%08X\n", + intdata); +- +- local_irq_restore(flags); + } + + /* Enable or disable Tx & Rx checksum offload engines */ +@@ -1086,9 +1072,8 @@ static int smsc95xx_bind(struct usbnet * + { + struct smsc95xx_priv *pdata; + bool is_internal_phy; +- char usb_path[64]; +- int ret, phy_irq; + u32 val; ++ int ret; + + printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n"); + +@@ -1128,38 +1113,10 @@ static int smsc95xx_bind(struct usbnet * + if (ret) + goto free_pdata; + +- /* create irq domain for use by PHY driver and GPIO consumers */ +- usb_make_path(dev->udev, usb_path, sizeof(usb_path)); +- pdata->irqfwnode = irq_domain_alloc_named_fwnode(usb_path); +- if (!pdata->irqfwnode) { +- ret = -ENOMEM; +- goto free_pdata; +- } +- +- pdata->irqdomain = irq_domain_create_linear(pdata->irqfwnode, +- SMSC95XX_NR_IRQS, +- &irq_domain_simple_ops, +- pdata); +- if (!pdata->irqdomain) { +- ret = -ENOMEM; +- goto free_irqfwnode; +- } +- +- phy_irq = irq_create_mapping(pdata->irqdomain, PHY_HWIRQ); +- if (!phy_irq) { +- ret = -ENOENT; +- goto remove_irqdomain; +- } +- +- pdata->irqchip = dummy_irq_chip; +- pdata->irqchip.name = SMSC_CHIPNAME; +- irq_set_chip_and_handler_name(phy_irq, &pdata->irqchip, +- handle_simple_irq, "phy"); +- + pdata->mdiobus = mdiobus_alloc(); + if (!pdata->mdiobus) { + ret = -ENOMEM; +- goto dispose_irq; ++ goto free_pdata; + } + + ret = smsc95xx_read_reg(dev, HW_CFG, &val); +@@ -1192,7 +1149,6 @@ static int smsc95xx_bind(struct usbnet * + goto unregister_mdio; + } + +- pdata->phydev->irq = phy_irq; + pdata->phydev->is_internal = is_internal_phy; + + /* detect device revision as different features may be available */ +@@ -1235,15 +1191,6 @@ unregister_mdio: + free_mdio: + mdiobus_free(pdata->mdiobus); + +-dispose_irq: +- irq_dispose_mapping(phy_irq); +- +-remove_irqdomain: +- irq_domain_remove(pdata->irqdomain); +- +-free_irqfwnode: +- irq_domain_free_fwnode(pdata->irqfwnode); +- + free_pdata: + kfree(pdata); + return ret; +@@ -1256,9 +1203,6 @@ static void smsc95xx_unbind(struct usbne + phy_disconnect(dev->net->phydev); + mdiobus_unregister(pdata->mdiobus); + mdiobus_free(pdata->mdiobus); +- irq_dispose_mapping(irq_find_mapping(pdata->irqdomain, PHY_HWIRQ)); +- irq_domain_remove(pdata->irqdomain); +- irq_domain_free_fwnode(pdata->irqfwnode); + netif_dbg(dev, ifdown, dev->net, "free pdata\n"); + kfree(pdata); + } +@@ -1283,6 +1227,29 @@ static u32 smsc_crc(const u8 *buffer, si + return crc << ((filter % 2) * 16); + } + ++static int smsc95xx_enable_phy_wakeup_interrupts(struct usbnet *dev, u16 mask) ++{ ++ int ret; ++ ++ netdev_dbg(dev->net, "enabling PHY wakeup interrupts\n"); ++ ++ /* read to clear */ ++ ret = smsc95xx_mdio_read_nopm(dev, PHY_INT_SRC); ++ if (ret < 0) ++ return ret; ++ ++ /* enable interrupt source */ ++ ret = smsc95xx_mdio_read_nopm(dev, PHY_INT_MASK); ++ if (ret < 0) ++ return ret; ++ ++ ret |= mask; ++ ++ smsc95xx_mdio_write_nopm(dev, PHY_INT_MASK, ret); ++ ++ return 0; ++} ++ + static int smsc95xx_link_ok_nopm(struct usbnet *dev) + { + int ret; +@@ -1449,6 +1416,7 @@ static int smsc95xx_enter_suspend3(struc + static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up) + { + struct smsc95xx_priv *pdata = dev->driver_priv; ++ int ret; + + if (!netif_running(dev->net)) { + /* interface is ifconfig down so fully power down hw */ +@@ -1467,10 +1435,27 @@ static int smsc95xx_autosuspend(struct u + } + + netdev_dbg(dev->net, "autosuspend entering SUSPEND1\n"); ++ ++ /* enable PHY wakeup events for if cable is attached */ ++ ret = smsc95xx_enable_phy_wakeup_interrupts(dev, ++ PHY_INT_MASK_ANEG_COMP_); ++ if (ret < 0) { ++ netdev_warn(dev->net, "error enabling PHY wakeup ints\n"); ++ return ret; ++ } ++ + netdev_info(dev->net, "entering SUSPEND1 mode\n"); + return smsc95xx_enter_suspend1(dev); + } + ++ /* enable PHY wakeup events so we remote wakeup if cable is pulled */ ++ ret = smsc95xx_enable_phy_wakeup_interrupts(dev, ++ PHY_INT_MASK_LINK_DOWN_); ++ if (ret < 0) { ++ netdev_warn(dev->net, "error enabling PHY wakeup ints\n"); ++ return ret; ++ } ++ + netdev_dbg(dev->net, "autosuspend entering SUSPEND3\n"); + return smsc95xx_enter_suspend3(dev); + } +@@ -1536,6 +1521,13 @@ static int smsc95xx_suspend(struct usb_i + } + + if (pdata->wolopts & WAKE_PHY) { ++ ret = smsc95xx_enable_phy_wakeup_interrupts(dev, ++ (PHY_INT_MASK_ANEG_COMP_ | PHY_INT_MASK_LINK_DOWN_)); ++ if (ret < 0) { ++ netdev_warn(dev->net, "error enabling PHY wakeup ints\n"); ++ goto done; ++ } ++ + /* if link is down then configure EDPD and enter SUSPEND1, + * otherwise enter SUSPEND0 below + */ +@@ -1769,12 +1761,11 @@ static int smsc95xx_resume(struct usb_in + return ret; + } + +- phy_init_hw(pdata->phydev); +- + ret = usbnet_resume(intf); + if (ret < 0) + netdev_warn(dev->net, "usbnet_resume error\n"); + ++ phy_init_hw(pdata->phydev); + return ret; + } + diff --git a/queue-5.15/series b/queue-5.15/series index 87fb8a39955..91cd3fc0abf 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -116,3 +116,5 @@ smb3-missing-inode-locks-in-punch-hole.patch xen-privcmd-fix-error-exit-of-privcmd_ioctl_dm_op.patch riscv-traps-add-missing-prototype.patch io_uring-fix-issue-with-io_write-not-always-undoing-sb_start_write.patch +revert-usbnet-smsc95xx-fix-deadlock-on-runtime-resume.patch +revert-usbnet-smsc95xx-forward-phy-interrupts-to-phy-driver-to-avoid-polling.patch