summaryrefslogtreecommitdiff
path: root/src/acpi
diff options
context:
space:
mode:
authorRaul E Rangel <rrangel@chromium.org>2021-05-27 15:04:21 -0600
committerWerner Zeh <werner.zeh@siemens.com>2021-06-07 05:21:30 +0000
commit6d2bc001ea8ee07be94fd25b91423d76918f001c (patch)
tree7aae0600be18d6ebc0c4ced09d943ce1b3f7cdde /src/acpi
parentfec4db954e44a3fd23fedd2f51189c13c985eee9 (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.c52
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);