From 1a59390f2d167ad335e3b9f62be92cf55d8d31ae Mon Sep 17 00:00:00 2001 From: Paweł Anikiel Date: Mon, 16 Oct 2023 14:22:15 +0000 Subject: drivers/wwan/fm: Wake up modem on PEWAKE# signal change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create an event handler for the PEWAKE# GPIO and notify the device driver to wake up the device. BUG=b:301150499 TEST=Compiled and tested on google/redrix: 1. Enable runtime suspend for linux mtk_t7xx driver 2. Wait for device to enter suspended state 3. Modem should be able to wake up driver, e.g. on SIM card insert/eject The interrupts should show up under /proc/interrupts as ACPI:Event Signed-off-by: Paweł Anikiel Change-Id: I32257689da85ea71f9de781093b3ede0cfe70a0e Reviewed-on: https://review.coreboot.org/c/coreboot/+/78297 Reviewed-by: Jakub Czapiga Tested-by: build bot (Jenkins) --- src/drivers/wwan/fm/acpi_fm350gl.c | 54 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'src/drivers') diff --git a/src/drivers/wwan/fm/acpi_fm350gl.c b/src/drivers/wwan/fm/acpi_fm350gl.c index 139fd15047..08f672f7c2 100644 --- a/src/drivers/wwan/fm/acpi_fm350gl.c +++ b/src/drivers/wwan/fm/acpi_fm350gl.c @@ -2,6 +2,8 @@ #include #include +#include +#include #include "chip.h" #include "soc/intel/common/block/include/intelblocks/acpi.h" #include "soc/intel/common/block/pcie/rtd3/chip.h" @@ -263,6 +265,55 @@ static const char *wwan_fm350gl_acpi_name(const struct device *dev) return "PXSX"; } +static void +wwan_fm350gl_acpi_event_interrupts(const struct acpi_gpio *wake_gpio) +{ + acpigen_write_name("_AEI"); + acpigen_write_resourcetemplate_header(); + acpi_device_write_gpio(wake_gpio); + acpigen_write_resourcetemplate_footer(); +} + +static void +wwan_fm350gl_acpi_event_method(const struct device *dev, + const struct acpi_gpio *wake_gpio) +{ + char name[5]; + uint16_t pin; + + pin = wake_gpio->pins[0]; + if (CONFIG(GENERIC_GPIO_LIB)) + pin = gpio_acpi_pin(pin); + + if (pin > 0xff) { + printk(BIOS_ERR, "%s: pins above 0xFF are unsupported (pin %u)\n", + __func__, pin); + return; + } + + snprintf(name, sizeof(name), "_%c%02X", + wake_gpio->irq.mode == ACPI_IRQ_EDGE_TRIGGERED ? 'E' : 'L', pin); + + acpigen_write_method_serialized(name, 0); + acpigen_notify(acpi_device_path(dev), 0x02); /* NOTIFY_DEVICE_WAKE */ + acpigen_write_method_end(); +} + +static void wwan_fm350gl_acpi_gpio_events(const struct device *dev) +{ + const struct drivers_wwan_fm_config *config = config_of(dev); + const struct acpi_gpio *wake_gpio = &config->wake_gpio; + + /* Write into GPIO controller's scope */ + if (CONFIG(GENERIC_GPIO_LIB)) + acpigen_write_scope(wake_gpio->resource ? : gpio_acpi_path(wake_gpio->pins[0])); + else + acpigen_write_scope(wake_gpio->resource); + wwan_fm350gl_acpi_event_interrupts(wake_gpio); + wwan_fm350gl_acpi_event_method(dev, wake_gpio); + acpigen_write_scope_end(); +} + static void wwan_fm350gl_acpi_fill_ssdt(const struct device *dev) { const struct drivers_wwan_fm_config *config = config_of(dev); @@ -323,6 +374,9 @@ static void wwan_fm350gl_acpi_fill_ssdt(const struct device *dev) acpigen_write_device_end(); /* Device */ } acpigen_write_scope_end(); /* Scope */ + + if (config->wake_gpio.pin_count && config->wake_gpio.type == ACPI_GPIO_TYPE_INTERRUPT) + wwan_fm350gl_acpi_gpio_events(dev); } static struct device_operations wwan_fm350gl_ops = { -- cgit v1.2.3