From a87c74ebe14aee0d4a82f5ff8a0170afb8105598 Mon Sep 17 00:00:00 2001
From: Stefan Kerkmann <karlk90@pm.me>
Date: Mon, 26 Jun 2023 23:55:52 +0200
Subject: [Bug] Fix non-functional S3 wakeup / resume from suspense  (#19780)

* Update ChibiOS-Contrib for USB suspend fixes

* Remove S3 wakup workaround

ChibiOS OTGv1 driver has a remote wakeup bug that prevents the device to
resume it's operation. 02516cbc24647f522eee975e69cc0c8a925470eb
introduced a hotfix that forcefully restarted the usb driver as a workaround.
This workaround broke multiple boards which do not use this driver /
peripheral. With the update of ChibiOS this hotfix is now obsolete.

* Remove restart_usb_driver overrides

they are no longer necessary as the workaround is not needed anymore
for stm32f4

* Remove unused RP_USB_USE_SOF_INTR defines

The SOF interrupt is enabled dynamically by the RP2040 usb driver
---
 lib/chibios-contrib                                |  2 +-
 .../GENERIC_PROMICRO_RP2040/configs/mcuconf.h      |  1 -
 .../boards/GENERIC_RP_RP2040/configs/mcuconf.h     |  1 -
 .../boards/GENERIC_WB32_F3G71XX/board/board.c      |  4 ----
 .../boards/GENERIC_WB32_FQ95XX/board/board.c       |  4 ----
 .../chibios/boards/IC_TEENSY_3_1/board/board.c     |  5 -----
 .../chibios/boards/PJRC_TEENSY_3_5/board/board.mk  |  2 +-
 .../chibios/boards/PJRC_TEENSY_3_5/board/extra.c   |  7 -------
 .../chibios/boards/PJRC_TEENSY_3_6/board/board.mk  |  2 +-
 .../chibios/boards/PJRC_TEENSY_3_6/board/extra.c   |  7 -------
 .../chibios/boards/QMK_PM2040/configs/mcuconf.h    |  1 -
 platforms/chibios/suspend.c                        |  1 +
 tmk_core/protocol/chibios/chibios.c                | 22 +++++++++-------------
 tmk_core/protocol/lufa/lufa.c                      |  2 +-
 14 files changed, 14 insertions(+), 47 deletions(-)
 delete mode 100644 platforms/chibios/boards/PJRC_TEENSY_3_5/board/extra.c
 delete mode 100644 platforms/chibios/boards/PJRC_TEENSY_3_6/board/extra.c

diff --git a/lib/chibios-contrib b/lib/chibios-contrib
index a224be155a..5d2d95c520 160000
--- a/lib/chibios-contrib
+++ b/lib/chibios-contrib
@@ -1 +1 @@
-Subproject commit a224be155ae18d38deccf33a6c1d259b9a5ad8d3
+Subproject commit 5d2d95c520a13d2c3e42343f51b18822d63781d6
diff --git a/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/mcuconf.h
index ab293c0b40..8621807cbb 100644
--- a/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/mcuconf.h
+++ b/platforms/chibios/boards/GENERIC_PROMICRO_RP2040/configs/mcuconf.h
@@ -106,7 +106,6 @@
 #define RP_USB_USE_USBD0                    TRUE
 #define RP_USB_FORCE_VBUS_DETECT            TRUE
 #define RP_USE_EXTERNAL_VBUS_DETECT         FALSE
-#define RP_USB_USE_SOF_INTR                 TRUE
 #define RP_USB_USE_ERROR_DATA_SEQ_INTR      FALSE
 
 #endif /* MCUCONF_H */
diff --git a/platforms/chibios/boards/GENERIC_RP_RP2040/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_RP_RP2040/configs/mcuconf.h
index b91d762419..902f9b5005 100644
--- a/platforms/chibios/boards/GENERIC_RP_RP2040/configs/mcuconf.h
+++ b/platforms/chibios/boards/GENERIC_RP_RP2040/configs/mcuconf.h
@@ -106,7 +106,6 @@
 #define RP_USB_USE_USBD0                    TRUE
 #define RP_USB_FORCE_VBUS_DETECT            TRUE
 #define RP_USE_EXTERNAL_VBUS_DETECT         FALSE
-#define RP_USB_USE_SOF_INTR                 TRUE
 #define RP_USB_USE_ERROR_DATA_SEQ_INTR      FALSE
 
 #endif /* MCUCONF_H */
diff --git a/platforms/chibios/boards/GENERIC_WB32_F3G71XX/board/board.c b/platforms/chibios/boards/GENERIC_WB32_F3G71XX/board/board.c
index f74c9e8be7..e38a7e0054 100644
--- a/platforms/chibios/boards/GENERIC_WB32_F3G71XX/board/board.c
+++ b/platforms/chibios/boards/GENERIC_WB32_F3G71XX/board/board.c
@@ -80,7 +80,3 @@ void __early_init(void) {
 void boardInit(void) {
 
 }
-
-void restart_usb_driver(USBDriver *usbp) {
-  // Do nothing. Restarting the USB driver on these boards breaks it.
-}
diff --git a/platforms/chibios/boards/GENERIC_WB32_FQ95XX/board/board.c b/platforms/chibios/boards/GENERIC_WB32_FQ95XX/board/board.c
index a99537fc27..22b4ff73b5 100644
--- a/platforms/chibios/boards/GENERIC_WB32_FQ95XX/board/board.c
+++ b/platforms/chibios/boards/GENERIC_WB32_FQ95XX/board/board.c
@@ -80,7 +80,3 @@ void __early_init(void) {
 void boardInit(void) {
 
 }
-
-void restart_usb_driver(USBDriver *usbp) {
-  // Do nothing. Restarting the USB driver on these boards breaks it.
-}
diff --git a/platforms/chibios/boards/IC_TEENSY_3_1/board/board.c b/platforms/chibios/boards/IC_TEENSY_3_1/board/board.c
index 424e0c975b..36ae8051ee 100644
--- a/platforms/chibios/boards/IC_TEENSY_3_1/board/board.c
+++ b/platforms/chibios/boards/IC_TEENSY_3_1/board/board.c
@@ -144,8 +144,3 @@ void __early_init(void) {
  * @todo    Add your board-specific code, if any.
  */
 void boardInit(void) {}
-
-
-void restart_usb_driver(USBDriver *usbp) {
-    // Do nothing. Restarting the USB driver on these boards breaks it.
-}
diff --git a/platforms/chibios/boards/PJRC_TEENSY_3_5/board/board.mk b/platforms/chibios/boards/PJRC_TEENSY_3_5/board/board.mk
index e129836b08..d76f1b9cc6 100644
--- a/platforms/chibios/boards/PJRC_TEENSY_3_5/board/board.mk
+++ b/platforms/chibios/boards/PJRC_TEENSY_3_5/board/board.mk
@@ -1,7 +1,7 @@
 include $(CHIBIOS_CONTRIB)/os/hal/boards/PJRC_TEENSY_3_5/board.mk
 
 # List of all the board related files.
-BOARDSRC += $(BOARD_PATH)/board/extra.c
+BOARDSRC +=
 
 # Required include directories
 BOARDINC += $(BOARD_PATH)/board
diff --git a/platforms/chibios/boards/PJRC_TEENSY_3_5/board/extra.c b/platforms/chibios/boards/PJRC_TEENSY_3_5/board/extra.c
deleted file mode 100644
index 4940d6d99b..0000000000
--- a/platforms/chibios/boards/PJRC_TEENSY_3_5/board/extra.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <hal.h>
-
-void restart_usb_driver(USBDriver *usbp) {
-    // Do nothing. Restarting the USB driver on the Teensy 3.6 breaks it,
-    // resulting in a keyboard which can wake up a PC from Suspend-to-RAM, but
-    // does not actually produce any keypresses until you un-plug and re-plug.
-}
diff --git a/platforms/chibios/boards/PJRC_TEENSY_3_6/board/board.mk b/platforms/chibios/boards/PJRC_TEENSY_3_6/board/board.mk
index aba195db04..8225bc2e0f 100644
--- a/platforms/chibios/boards/PJRC_TEENSY_3_6/board/board.mk
+++ b/platforms/chibios/boards/PJRC_TEENSY_3_6/board/board.mk
@@ -1,7 +1,7 @@
 include $(CHIBIOS_CONTRIB)/os/hal/boards/PJRC_TEENSY_3_6/board.mk
 
 # List of all the board related files.
-BOARDSRC += $(BOARD_PATH)/board/extra.c
+BOARDSRC +=
 
 # Required include directories
 BOARDINC += $(BOARD_PATH)/board
diff --git a/platforms/chibios/boards/PJRC_TEENSY_3_6/board/extra.c b/platforms/chibios/boards/PJRC_TEENSY_3_6/board/extra.c
deleted file mode 100644
index 4940d6d99b..0000000000
--- a/platforms/chibios/boards/PJRC_TEENSY_3_6/board/extra.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <hal.h>
-
-void restart_usb_driver(USBDriver *usbp) {
-    // Do nothing. Restarting the USB driver on the Teensy 3.6 breaks it,
-    // resulting in a keyboard which can wake up a PC from Suspend-to-RAM, but
-    // does not actually produce any keypresses until you un-plug and re-plug.
-}
diff --git a/platforms/chibios/boards/QMK_PM2040/configs/mcuconf.h b/platforms/chibios/boards/QMK_PM2040/configs/mcuconf.h
index f19f08e93c..493dcf6434 100644
--- a/platforms/chibios/boards/QMK_PM2040/configs/mcuconf.h
+++ b/platforms/chibios/boards/QMK_PM2040/configs/mcuconf.h
@@ -106,7 +106,6 @@
 #define RP_USB_USE_USBD0                    TRUE
 #define RP_USB_FORCE_VBUS_DETECT            TRUE
 #define RP_USE_EXTERNAL_VBUS_DETECT         FALSE
-#define RP_USB_USE_SOF_INTR                 TRUE
 #define RP_USB_USE_ERROR_DATA_SEQ_INTR      FALSE
 
 #endif /* MCUCONF_H */
diff --git a/platforms/chibios/suspend.c b/platforms/chibios/suspend.c
index ce03433e3a..a937ccf059 100644
--- a/platforms/chibios/suspend.c
+++ b/platforms/chibios/suspend.c
@@ -42,6 +42,7 @@ void suspend_wakeup_init(void) {
     clear_keys();
 #ifdef MOUSEKEY_ENABLE
     mousekey_clear();
+    mousekey_send();
 #endif /* MOUSEKEY_ENABLE */
 #ifdef PROGRAMMABLE_BUTTON_ENABLE
     programmable_button_clear();
diff --git a/tmk_core/protocol/chibios/chibios.c b/tmk_core/protocol/chibios/chibios.c
index 52aea241ff..1eebdaf6c3 100644
--- a/tmk_core/protocol/chibios/chibios.c
+++ b/tmk_core/protocol/chibios/chibios.c
@@ -180,28 +180,24 @@ void protocol_post_init(void) {
 }
 
 void protocol_pre_task(void) {
-    usb_event_queue_task();
-
 #if !defined(NO_USB_STARTUP_CHECK)
     if (USB_DRIVER.state == USB_SUSPENDED) {
-        print("[s]");
+        dprintln("suspending keyboard");
         while (USB_DRIVER.state == USB_SUSPENDED) {
-            /* Do this in the suspended state */
-            suspend_power_down(); // on AVR this deep sleeps for 15ms
-            /* Remote wakeup */
+            suspend_power_down();
             if ((USB_DRIVER.status & USB_GETSTATUS_REMOTE_WAKEUP_ENABLED) && suspend_wakeup_condition()) {
+                /* issue a remote wakeup event to the host which should resume
+                 * the bus and get our keyboard out of suspension. */
                 usbWakeupHost(&USB_DRIVER);
-                restart_usb_driver(&USB_DRIVER);
             }
         }
-        /* Woken up */
-        // variables has been already cleared by the wakeup hook
-        send_keyboard_report();
-#    ifdef MOUSEKEY_ENABLE
-        mousekey_send();
-#    endif /* MOUSEKEY_ENABLE */
+        /* after a successful wakeup a USB_EVENT_WAKEUP is signaled to QMK by
+         * ChibiOS, which triggers a wakeup callback that restores the state of
+         * the keyboard. Therefore we do nothing here. */
     }
 #endif
+
+    usb_event_queue_task();
 }
 
 void protocol_post_task(void) {
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index 20bfc8fb3c..d1cda24227 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -858,7 +858,7 @@ void protocol_post_init(void) {
 void protocol_pre_task(void) {
 #if !defined(NO_USB_STARTUP_CHECK)
     if (USB_DeviceState == DEVICE_STATE_Suspended) {
-        print("[s]");
+        dprintln("suspending keyboard");
         while (USB_DeviceState == DEVICE_STATE_Suspended) {
             suspend_power_down();
             if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
-- 
cgit v1.2.3