]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 29 Aug 2022 08:11:48 +0000 (10:11 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 29 Aug 2022 08:11:48 +0000 (10:11 +0200)
added patches:
revert-usbnet-smsc95xx-fix-deadlock-on-runtime-resume.patch
revert-usbnet-smsc95xx-forward-phy-interrupts-to-phy-driver-to-avoid-polling.patch

queue-5.15/revert-usbnet-smsc95xx-fix-deadlock-on-runtime-resume.patch [new file with mode: 0644]
queue-5.15/revert-usbnet-smsc95xx-forward-phy-interrupts-to-phy-driver-to-avoid-polling.patch [new file with mode: 0644]
queue-5.15/series

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 (file)
index 0000000..ca296ed
--- /dev/null
@@ -0,0 +1,146 @@
+From foo@baz Mon Aug 29 10:10:59 AM CEST 2022
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Mon, 29 Aug 2022 10:06:53 +0200
+Subject: Revert "usbnet: smsc95xx: Fix deadlock on runtime resume"
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+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 <lukas@wunner.de>
+Cc: Oleksij Rempel <o.rempel@pengutronix.de>
+Cc: Ferry Toth <fntoth@gmail.com>
+Cc: Andrew Lunn <andrew@lunn.ch>
+Cc: Andre Edich <andre.edich@microchip.com>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Sasha Levin <sashal@kernel.org>
+Link: https://lore.kernel.org/r/20220826132137.GA24932@wunner.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..221e44d
--- /dev/null
@@ -0,0 +1,262 @@
+From foo@baz Mon Aug 29 10:10:59 AM CEST 2022
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+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 <gregkh@linuxfoundation.org>
+
+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 <lukas@wunner.de>
+Cc: Oleksij Rempel <o.rempel@pengutronix.de>
+Cc: Ferry Toth <fntoth@gmail.com>
+Cc: Andrew Lunn <andrew@lunn.ch>
+Cc: Andre Edich <andre.edich@microchip.com>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Sasha Levin <sashal@kernel.org>
+Link: https://lore.kernel.org/r/20220826132137.GA24932@wunner.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <linux/usb/usbnet.h>
+ #include <linux/slab.h>
+ #include <linux/of_net.h>
+-#include <linux/irq.h>
+-#include <linux/irqdomain.h>
+ #include <linux/mdio.h>
+ #include <linux/phy.h>
+ #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;
+ }
index 87fb8a3995536c46babc905407c95655b1071777..91cd3fc0abf1f3140d4cd4c7bb94f70805aa9ba0 100644 (file)
@@ -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