diff --git a/devices/r8169/r8169_main-5.10-ethercat.c b/devices/r8169/r8169_main-5.10-ethercat.c index 9508e74d..b00c04af 100644 --- a/devices/r8169/r8169_main-5.10-ethercat.c +++ b/devices/r8169/r8169_main-5.10-ethercat.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -633,6 +634,7 @@ struct rtl8169_private { ec_device_t *ecdev; unsigned long ec_watchdog_jiffies; + struct irq_work ec_watchdog_kicker; }; typedef void (*rtl_generic_fct)(struct rtl8169_private *tp); @@ -5079,6 +5081,7 @@ static void rtl_remove_one(struct pci_dev *pdev) if (tp->ecdev) { ecdev_close(tp->ecdev); + irq_work_sync(&tp->ec_watchdog_kicker); ecdev_withdraw(tp->ecdev); } else { unregister_netdev(tp->dev); @@ -5369,6 +5372,14 @@ done: rtl_rar_set(tp, mac_addr); } +static void ec_kick_watchdog(struct irq_work *work) +{ + struct rtl8169_private *tp = + container_of(work, struct rtl8169_private, ec_watchdog_kicker); + + phy_mac_interrupt(tp->phydev); +} + static void ec_poll(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -5387,8 +5398,7 @@ static void ec_poll(struct net_device *dev) rtl_rx(dev, tp, 100); if (status & LinkChg) - phy_mac_interrupt(tp->phydev); - + irq_work_queue(&tp->ec_watchdog_kicker); rtl_ack_events(tp, status); } @@ -5588,6 +5598,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pm_runtime_put_sync(&pdev->dev); if (tp->ecdev) { + init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog); rc = ecdev_open(tp->ecdev); if (rc) { ecdev_withdraw(tp->ecdev); diff --git a/devices/r8169/r8169_main-5.14-ethercat.c b/devices/r8169/r8169_main-5.14-ethercat.c index 58ed3d95..51c54f47 100644 --- a/devices/r8169/r8169_main-5.14-ethercat.c +++ b/devices/r8169/r8169_main-5.14-ethercat.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -653,6 +654,7 @@ struct rtl8169_private { ec_device_t *ecdev; unsigned long ec_watchdog_jiffies; + struct irq_work ec_watchdog_kicker; }; typedef void (*rtl_generic_fct)(struct rtl8169_private *tp); @@ -5048,6 +5050,7 @@ static void rtl_remove_one(struct pci_dev *pdev) if (tp->ecdev) { ecdev_close(tp->ecdev); + irq_work_sync(&tp->ec_watchdog_kicker); ecdev_withdraw(tp->ecdev); } else { unregister_netdev(tp->dev); @@ -5338,6 +5341,14 @@ done: rtl_rar_set(tp, mac_addr); } +static void ec_kick_watchdog(struct irq_work *work) +{ + struct rtl8169_private *tp = + container_of(work, struct rtl8169_private, ec_watchdog_kicker); + + phy_mac_interrupt(tp->phydev); +} + static void ec_poll(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -5356,7 +5367,7 @@ static void ec_poll(struct net_device *dev) rtl_rx(dev, tp, 100); if (status & LinkChg) - phy_mac_interrupt(tp->phydev); + irq_work_queue(&tp->ec_watchdog_kicker); rtl_ack_events(tp, status); } @@ -5560,6 +5571,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pm_runtime_put_sync(&pdev->dev); if (tp->ecdev) { + init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog); rc = ecdev_open(tp->ecdev); if (rc) { ecdev_withdraw(tp->ecdev); diff --git a/devices/r8169/r8169_main-5.15-ethercat.c b/devices/r8169/r8169_main-5.15-ethercat.c index f2bc5230..df956257 100644 --- a/devices/r8169/r8169_main-5.15-ethercat.c +++ b/devices/r8169/r8169_main-5.15-ethercat.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -641,6 +642,7 @@ struct rtl8169_private { ec_device_t *ecdev; unsigned long ec_watchdog_jiffies; + struct irq_work ec_watchdog_kicker; }; typedef void (*rtl_generic_fct)(struct rtl8169_private *tp); @@ -5041,6 +5043,7 @@ static void rtl_remove_one(struct pci_dev *pdev) if (tp->ecdev) { ecdev_close(tp->ecdev); + irq_work_sync(&tp->ec_watchdog_kicker); ecdev_withdraw(tp->ecdev); } else { unregister_netdev(tp->dev); @@ -5331,6 +5334,14 @@ done: rtl_rar_set(tp, mac_addr); } +static void ec_kick_watchdog(struct irq_work *work) +{ + struct rtl8169_private *tp = + container_of(work, struct rtl8169_private, ec_watchdog_kicker); + + phy_mac_interrupt(tp->phydev); +} + static void ec_poll(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -5349,7 +5360,7 @@ static void ec_poll(struct net_device *dev) rtl_rx(dev, tp, 100); if (status & LinkChg) - phy_mac_interrupt(tp->phydev); + irq_work_queue(&tp->ec_watchdog_kicker); rtl_ack_events(tp, status); } @@ -5552,6 +5563,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pm_runtime_put_sync(&pdev->dev); if (tp->ecdev) { + init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog); rc = ecdev_open(tp->ecdev); if (rc) { ecdev_withdraw(tp->ecdev); diff --git a/devices/r8169/r8169_main-6.1-ethercat.c b/devices/r8169/r8169_main-6.1-ethercat.c index 82405979..06e02bc6 100644 --- a/devices/r8169/r8169_main-6.1-ethercat.c +++ b/devices/r8169/r8169_main-6.1-ethercat.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -630,6 +631,7 @@ struct rtl8169_private { ec_device_t *ecdev; unsigned long ec_watchdog_jiffies; + struct irq_work ec_watchdog_kicker; }; typedef void (*rtl_generic_fct)(struct rtl8169_private *tp); @@ -4919,6 +4921,7 @@ static void rtl_remove_one(struct pci_dev *pdev) if (tp->ecdev) { ecdev_close(tp->ecdev); + irq_work_sync(&tp->ec_watchdog_kicker); ecdev_withdraw(tp->ecdev); } else { unregister_netdev(tp->dev); @@ -5189,6 +5192,14 @@ static bool rtl_aspm_is_safe(struct rtl8169_private *tp) return false; } +static void ec_kick_watchdog(struct irq_work *work) +{ + struct rtl8169_private *tp = + container_of(work, struct rtl8169_private, ec_watchdog_kicker); + + phy_mac_interrupt(tp->phydev); +} + static void ec_poll(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -5207,7 +5218,7 @@ static void ec_poll(struct net_device *dev) rtl_rx(dev, tp, 100); if (status & LinkChg) - phy_mac_interrupt(tp->phydev); + irq_work_queue(&tp->ec_watchdog_kicker); rtl_ack_events(tp, status); } @@ -5416,6 +5427,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pm_runtime_put_sync(&pdev->dev); if (tp->ecdev) { + init_irq_work(&tp->ec_watchdog_kicker, ec_kick_watchdog); rc = ecdev_open(tp->ecdev); if (rc) { ecdev_withdraw(tp->ecdev);