git: e7d1f208fde8 - stable/14 - gpioaei: Add support for ACPI _EVT method
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 09 Mar 2025 20:45:01 UTC
The branch stable/14 has been updated by wulf:
URL: https://cgit.FreeBSD.org/src/commit/?id=e7d1f208fde82c85b061ce792f20a4aa178ec82f
commit e7d1f208fde82c85b061ce792f20a4aa178ec82f
Author: Vladimir Kondratyev <wulf@FreeBSD.org>
AuthorDate: 2025-03-07 15:59:12 +0000
Commit: Vladimir Kondratyev <wulf@FreeBSD.org>
CommitDate: 2025-03-09 20:42:35 +0000
gpioaei: Add support for ACPI _EVT method
This method is often used to process GPIO "Power on" button press on
modern x86 laptops with S0ix sleep mode.
Tested with patch from https://reviews.freebsd.org/D26407
Sponsored by: Future Crew LLC
MFC after: 2 month
(cherry picked from commit adc2c156acb50bac6e8ec66b72cadc8910ce4975)
---
sys/dev/gpio/gpioaei.c | 40 +++++++++++++++++++++++++++++++---------
1 file changed, 31 insertions(+), 9 deletions(-)
diff --git a/sys/dev/gpio/gpioaei.c b/sys/dev/gpio/gpioaei.c
index 050f259a2127..f43674b53c7d 100644
--- a/sys/dev/gpio/gpioaei.c
+++ b/sys/dev/gpio/gpioaei.c
@@ -39,9 +39,16 @@
#include <dev/gpio/gpiobusvar.h>
#include <dev/gpio/acpi_gpiobusvar.h>
+enum gpio_aei_type {
+ ACPI_AEI_TYPE_UNKNOWN,
+ ACPI_AEI_TYPE_ELX,
+ ACPI_AEI_TYPE_EVT
+};
+
struct gpio_aei_softc {
ACPI_HANDLE handle;
- char objname[5]; /* "_EXX" or "_LXX" */
+ enum gpio_aei_type type;
+ int pin;
struct resource * intr_res;
int intr_rid;
void * intr_cookie;
@@ -60,8 +67,11 @@ gpio_aei_intr(void * arg)
{
struct gpio_aei_softc * sc = arg;
- /* Ask ACPI to run the appropriate _Exx or _Lxx method. */
- AcpiEvaluateObject(sc->handle, sc->objname, NULL, NULL);
+ /* Ask ACPI to run the appropriate _EVT, _Exx or _Lxx method. */
+ if (sc->type == ACPI_AEI_TYPE_EVT)
+ acpi_SetInteger(sc->handle, NULL, sc->pin);
+ else
+ AcpiEvaluateObject(sc->handle, NULL, NULL, NULL);
}
static int
@@ -69,23 +79,35 @@ gpio_aei_attach(device_t dev)
{
struct gpio_aei_softc * sc = device_get_softc(dev);
gpio_pin_t pin;
+ ACPI_HANDLE handle;
int err;
/* This is us. */
device_set_desc(dev, "ACPI Event Information Device");
/* Store parameters needed by gpio_aei_intr. */
- sc->handle = acpi_gpiobus_get_handle(dev);
+ handle = acpi_gpiobus_get_handle(dev);
if (gpio_pin_get_by_acpi_index(dev, 0, &pin) != 0) {
device_printf(dev, "Unable to get the input pin\n");
return (ENXIO);
}
- sprintf(sc->objname, "_%c%02X",
- (pin->flags & GPIO_INTR_EDGE_MASK) ? 'E' : 'L', pin->pin);
- /* Support for GPIO pins > 255 is not implemented. */
- if (pin->pin > 255) {
- device_printf(dev, "ACPI Event Information Device does not support pins > 255");
+ sc->type = ACPI_AEI_TYPE_UNKNOWN;
+ sc->pin = pin->pin;
+ if (pin->pin <= 255) {
+ char objname[5]; /* "_EXX" or "_LXX" */
+ sprintf(objname, "_%c%02X",
+ (pin->flags & GPIO_INTR_EDGE_MASK) ? 'E' : 'L', pin->pin);
+ if (ACPI_SUCCESS(AcpiGetHandle(handle, objname, &sc->handle)))
+ sc->type = ACPI_AEI_TYPE_ELX;
+ }
+ if (sc->type == ACPI_AEI_TYPE_UNKNOWN) {
+ if (ACPI_SUCCESS(AcpiGetHandle(handle, "_EVT", &sc->handle)))
+ sc->type = ACPI_AEI_TYPE_EVT;
+ }
+
+ if (sc->type == ACPI_AEI_TYPE_UNKNOWN) {
+ device_printf(dev, "ACPI Event Information Device type is unknown");
return (ENOTSUP);
}