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;