in acpi.c [205:264]
static int tb_acpi_retimer_set_power(struct tb_port *port, bool power)
{
struct usb4_port *usb4 = port->usb4;
union acpi_object argv4[2];
struct acpi_device *adev;
union acpi_object *obj;
int ret;
if (!usb4->can_offline)
return 0;
adev = ACPI_COMPANION(&usb4->dev);
if (WARN_ON(!adev))
return 0;
/* Check if we are already powered on (and in correct mode) */
obj = acpi_evaluate_dsm_typed(adev->handle, &retimer_dsm_guid, 1,
RETIMER_DSM_QUERY_ONLINE_STATE, NULL,
ACPI_TYPE_INTEGER);
if (!obj) {
tb_port_warn(port, "ACPI: query online _DSM failed\n");
return -EIO;
}
ret = obj->integer.value;
ACPI_FREE(obj);
if (power == ret)
return 0;
tb_port_dbg(port, "ACPI: calling _DSM to power %s retimers\n",
power ? "on" : "off");
argv4[0].type = ACPI_TYPE_PACKAGE;
argv4[0].package.count = 1;
argv4[0].package.elements = &argv4[1];
argv4[1].integer.type = ACPI_TYPE_INTEGER;
argv4[1].integer.value = power;
obj = acpi_evaluate_dsm_typed(adev->handle, &retimer_dsm_guid, 1,
RETIMER_DSM_SET_ONLINE_STATE, argv4,
ACPI_TYPE_INTEGER);
if (!obj) {
tb_port_warn(port,
"ACPI: set online state _DSM evaluation failed\n");
return -EIO;
}
ret = obj->integer.value;
ACPI_FREE(obj);
if (ret >= 0) {
if (power)
return ret == 1 ? 0 : -EBUSY;
return 0;
}
tb_port_warn(port, "ACPI: set online state _DSM failed with error %d\n", ret);
return -EIO;
}