--- /dev/null
+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;
+
--- /dev/null
+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;
+ }
+