diff options
author | Raul E Rangel <rrangel@chromium.org> | 2021-05-27 15:04:21 -0600 |
---|---|---|
committer | Werner Zeh <werner.zeh@siemens.com> | 2021-06-07 05:21:30 +0000 |
commit | 6d2bc001ea8ee07be94fd25b91423d76918f001c (patch) | |
tree | 7aae0600be18d6ebc0c4ced09d943ce1b3f7cdde /src/acpi | |
parent | fec4db954e44a3fd23fedd2f51189c13c985eee9 (diff) |
acpi/device: Add ability to generate proper _STA for PowerResource
acpi_device_add_power_res currently generates a `_STA` method hardcoded
to ON. This change enables the ability to generate a `_STA` method that
queries the status of the GPIOs to determine if the power resource is ON
or OFF.
BUG=b:184617186
TEST=Dump SSDT table for guybrush
Signed-off-by: Raul E Rangel <rrangel@chromium.org>
Change-Id: I91410556db002c620fd9aaa99981457808da93a5
Reviewed-on: https://review.coreboot.org/c/coreboot/+/55027
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Lance Zhao
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Diffstat (limited to 'src/acpi')
-rw-r--r-- | src/acpi/device.c | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/src/acpi/device.c b/src/acpi/device.c index 5d4d9be4ce..42fa63985b 100644 --- a/src/acpi/device.c +++ b/src/acpi/device.c @@ -598,6 +598,50 @@ void acpi_device_write_uart(const struct acpi_uart *uart) acpi_device_fill_len(desc_length); } +#define ACPI_POWER_RESOURCE_STATUS_ON_OP ONE_OP +#define ACPI_POWER_RESOURCE_STATUS_OFF_OP ZERO_OP + +/** + * Writes an ACPI fragment that will check the GPIO and return 0 if the GPIO + * state does not match the active parameter. + */ +static void acpigen_write_gpio_STA(const struct acpi_gpio *gpio, bool active) +{ + if (!gpio || !gpio->pin_count) + return; + + /* Read current GPIO status into Local0. */ + acpigen_get_tx_gpio(gpio); + + /* + * If (!Local0) + * { + * Return (Zero) + * } + */ + acpigen_write_if(); + if (active) + acpigen_emit_byte(LNOT_OP); + acpigen_emit_byte(LOCAL0_OP); + acpigen_write_return_op(ACPI_POWER_RESOURCE_STATUS_OFF_OP); + acpigen_write_if_end(); +} + +static void acpigen_write_power_res_STA(const struct acpi_power_res_params *params) +{ + acpigen_write_method_serialized("_STA", 0); + + /* Verify all the GPIOs are in the ON state, otherwise return 0 */ + acpigen_write_gpio_STA(params->enable_gpio, true); + acpigen_write_gpio_STA(params->reset_gpio, false); + acpigen_write_gpio_STA(params->stop_gpio, false); + + /* All GPIOs are in the ON state */ + acpigen_write_return_op(ACPI_POWER_RESOURCE_STATUS_ON_OP); + + acpigen_pop_len(); /* Method */ +} + /* PowerResource() with Enable and/or Reset control */ void acpi_device_add_power_res(const struct acpi_power_res_params *params) { @@ -613,8 +657,12 @@ void acpi_device_add_power_res(const struct acpi_power_res_params *params) acpigen_write_power_res("PRIC", 0, 0, power_res_dev_states, ARRAY_SIZE(power_res_dev_states)); - /* Method (_STA, 0, NotSerialized) { Return (0x1) } */ - acpigen_write_STA(0x1); + if (params->use_gpio_for_status) { + acpigen_write_power_res_STA(params); + } else { + /* Method (_STA, 0, NotSerialized) { Return (0x1) } */ + acpigen_write_STA(ACPI_POWER_RESOURCE_STATUS_ON_OP); + } /* Method (_ON, 0, Serialized) */ acpigen_write_method_serialized("_ON", 0); |