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>
This commit is contained in:
Raul E Rangel 2021-05-27 15:04:21 -06:00 committed by Werner Zeh
parent fec4db954e
commit 6d2bc001ea
2 changed files with 56 additions and 2 deletions

View File

@ -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);

View File

@ -456,6 +456,12 @@ struct acpi_power_res_params {
* (_OFF method delay)
*/
unsigned int stop_off_delay_ms;
/* Write a _STA method that uses the state of the GPIOs to determine if
* the PowerResource is ON or OFF. If this is false, the _STA method
* will always return ON.
*/
bool use_gpio_for_status;
};
/*