diff --git a/src/acpi/acpigen_dsm.c b/src/acpi/acpigen_dsm.c index 734fbd5cfb..d51d643c7e 100644 --- a/src/acpi/acpigen_dsm.c +++ b/src/acpi/acpigen_dsm.c @@ -47,3 +47,26 @@ void acpigen_write_dsm_i2c_hid(struct dsm_i2c_hid_config *config) } /* ------------------- End: I2C HID DSM ------------------------- */ + +#define USB_DSM_UUID "CE2EE385-00E6-48CB-9F05-2EDB927C4899" + +static void usb_dsm_func5_cb(void *arg) +{ + struct dsm_usb_config *config = arg; + acpigen_write_return_byte(config->usb_lpm_incapable); +} + +static void (*usb_dsm_callbacks[6])(void *) = { + NULL, + NULL, + NULL, + NULL, + NULL, + usb_dsm_func5_cb, +}; + +void acpigen_write_dsm_usb(struct dsm_usb_config *config) +{ + acpigen_write_dsm(USB_DSM_UUID, usb_dsm_callbacks, + ARRAY_SIZE(usb_dsm_callbacks), config); +} diff --git a/src/drivers/usb/acpi/chip.h b/src/drivers/usb/acpi/chip.h index 4adffcf2c0..9acd382c3d 100644 --- a/src/drivers/usb/acpi/chip.h +++ b/src/drivers/usb/acpi/chip.h @@ -72,6 +72,12 @@ struct drivers_usb_acpi_config { * will always return ON. */ bool use_gpio_for_status; + + /* + * Generate _DSM method Function 5 to disable USB U1/U2 transition + * for a port + */ + bool usb_lpm_incapable; }; /* Method to get PLD structure from USB device */ diff --git a/src/drivers/usb/acpi/usb_acpi.c b/src/drivers/usb/acpi/usb_acpi.c index f72129cba8..b95ebc9a60 100644 --- a/src/drivers/usb/acpi/usb_acpi.c +++ b/src/drivers/usb/acpi/usb_acpi.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,7 @@ static void usb_acpi_fill_ssdt_generator(const struct device *dev) struct drivers_usb_acpi_config *config = dev->chip_info; const char *path = acpi_device_path(dev); struct acpi_pld pld; + struct dsm_usb_config usb_cfg; if (!path || !config) return; @@ -56,6 +58,11 @@ static void usb_acpi_fill_ssdt_generator(const struct device *dev) else printk(BIOS_ERR, "Error retrieving PLD for %s\n", path); + if (config->usb_lpm_incapable) { + usb_cfg.usb_lpm_incapable = 1; + acpigen_write_dsm_usb(&usb_cfg); + } + /* Resources */ if (usb_acpi_add_gpios_to_crs(config) == true) { struct acpi_dp *dsd; diff --git a/src/include/acpi/acpigen_dsm.h b/src/include/acpi/acpigen_dsm.h index 5df7f304c9..8e60d0a0ab 100644 --- a/src/include/acpi/acpigen_dsm.h +++ b/src/include/acpi/acpigen_dsm.h @@ -11,4 +11,9 @@ struct dsm_i2c_hid_config { void acpigen_write_dsm_i2c_hid(struct dsm_i2c_hid_config *config); +struct dsm_usb_config { + uint8_t usb_lpm_incapable; +}; +void acpigen_write_dsm_usb(struct dsm_usb_config *config); + #endif /* __ACPI_ACPIGEN_DSM_H__ */