Linux seems to permit GPE re-assignment (at least from what I can tell,
the code is a bit convoluted). In the Surface Book AML, Microsoft provides
an _L50 method as well as a _GPE method on the EC object that also returns 0x50.
This makes no sense, since EC GPEs must be edge-triggered (and an _Lxx method
indicates a level-triggered GPE). What happens now is that we ignore the
second GPE registration, meaning all EC GPEs get ignored.

This diff removes the -EBUSY return in that situation, allowing the second
(and, I suppose, subsequent) GPEs to be registered properly.

With this diff, and another one not yet posted, I can get the EC on the
Surface Book to actually generate events, which means we can support the 
buttons and other events on this machine.

I am still not 100% convinced this is the right way to go. I have not yet
unravelled all the Linux GPE code, but I'd like to see if the diff below
breaks anyone, in case I decide to go this way. I have discussed this
with kettenis@ and we can't come up with anything better at the moment.

Testing appreciated, look for "GPE xxx already enabled" in your dmesgs.

-ml

Index: acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.345
diff -u -p -a -u -r1.345 acpi.c
--- acpi.c      25 Jun 2018 22:33:24 -0000      1.345
+++ acpi.c      26 Jun 2018 03:36:10 -0000
@@ -2186,10 +2186,9 @@ acpi_set_gpehandler(struct acpi_softc *s
        ptbl = acpi_find_gpe(sc, gpe);
        if (ptbl == NULL || handler == NULL)
                return -EINVAL;
-       if (ptbl->handler != NULL) {
-               dnprintf(10, "error: GPE %.2x already enabled\n", gpe);
-               return -EBUSY;
-       }
+       if (ptbl->handler != NULL)
+               printf("%s: GPE %.2x already enabled\n", DEVNAME(sc), gpe);
+
        dnprintf(50, "Adding GPE handler %.2x (%s)\n", gpe, edge ? "edge" : 
"level");
        ptbl->handler = handler;
        ptbl->arg = arg;

Reply via email to