> Date: Mon, 25 Jun 2018 21:02:38 -0700
> From: Mike Larkin <[email protected]>
>
> 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.
I think you should just commit this (keeping the printf).
ok kettenis@
> 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;
>
>