#include <linux/acpi.h>
 #include <linux/backlight.h>
 #include <linux/debugfs.h>
+#include <linux/delay.h>
 #include <linux/dmi.h>
 #include <linux/fb.h>
 #include <linux/hwmon.h>
 #define ASUS_SCREENPAD_BRIGHT_MAX 255
 #define ASUS_SCREENPAD_BRIGHT_DEFAULT 60
 
+/* Controls the power state of the USB0 hub on ROG Ally which input is on */
+#define ASUS_USB0_PWR_EC0_CSEE "\\_SB.PCI0.SBRG.EC0.CSEE"
+/* 300ms so far seems to produce a reliable result on AC and battery */
+#define ASUS_USB0_PWR_EC0_CSEE_WAIT 300
+
 static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL };
 
 static int throttle_thermal_policy_write(struct asus_wmi *);
 
        bool fnlock_locked;
 
+       /* The ROG Ally device requires the MCU USB device be disconnected before suspend */
+       bool ally_mcu_usb_switch;
+
        struct asus_wmi_debug debug;
 
        struct asus_wmi_driver *driver;
        asus->nv_temp_tgt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_THERM_TARGET);
        asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD);
        asus->mini_led_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE);
+       asus->ally_mcu_usb_switch = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE)
+                                               && dmi_match(DMI_BOARD_NAME, "RC71L");
 
        err = fan_boost_mode_check_present(asus);
        if (err)
                asus_wmi_fnlock_update(asus);
 
        asus_wmi_tablet_mode_get_state(asus);
+
+       return 0;
+}
+
+static int asus_hotk_resume_early(struct device *device)
+{
+       struct asus_wmi *asus = dev_get_drvdata(device);
+
+       if (asus->ally_mcu_usb_switch) {
+               if (ACPI_FAILURE(acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, 0xB8)))
+                       dev_err(device, "ROG Ally MCU failed to connect USB dev\n");
+               else
+                       msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT);
+       }
+       return 0;
+}
+
+static int asus_hotk_prepare(struct device *device)
+{
+       struct asus_wmi *asus = dev_get_drvdata(device);
+       int result, err;
+
+       if (asus->ally_mcu_usb_switch) {
+               /* When powersave is enabled it causes many issues with resume of USB hub */
+               result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_MCU_POWERSAVE);
+               if (result == 1) {
+                       dev_warn(device, "MCU powersave enabled, disabling to prevent resume issues");
+                       err = asus_wmi_set_devstate(ASUS_WMI_DEVID_MCU_POWERSAVE, 0, &result);
+                       if (err || result != 1)
+                               dev_err(device, "Failed to set MCU powersave mode: %d\n", err);
+               }
+               /* sleep required to ensure USB0 is disabled before sleep continues */
+               if (ACPI_FAILURE(acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, 0xB7)))
+                       dev_err(device, "ROG Ally MCU failed to disconnect USB dev\n");
+               else
+                       msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT);
+       }
        return 0;
 }
 
        .thaw = asus_hotk_thaw,
        .restore = asus_hotk_restore,
        .resume = asus_hotk_resume,
+       .resume_early = asus_hotk_resume_early,
+       .prepare = asus_hotk_prepare,
 };
 
 /* Registration ***************************************************************/