Download raw body.
return of the chromebook keyboard diff
New year, new diff! Sorry for taking too much time.
This new diff tries to do the following:
- attach to the ACPI keyboard node, if we run on a machine where we know
it helps.
- attach to the ACPI mouse node, if we have attached to the keyboard
node, and the mouse node provides interrupt information.
- use regular interrupts as well as GPIO interrupts.
If you have a system where your keyboard does not work correctly with
"pckbc0 at isa0" and running this diff does not make "pckbc1 at acpi0"
appear, you can force the pckbc at acpi attachment by changing device
flags in UKC.
To do this, pass the -c option when booting. After the kernel loads, it
will drop you to a "UKC>" prompt. Enter "find pckbc". You will get
something like:
273 pckbc0 at isa0 (more stuff on the line)
478 pckbc* at acpi0 addr -1 flags 0x0
You need to change the flags of the acpi attachment; in my case, number
478, but this may be slightly different on your machine. So enter
"change 478". The 478 line will be reprinted, and you'll be asked to
confirm you want to change it with "y". Keep the "addr" value unchanged
(press enter), then enter "1" for the "flags" value. The kernel will
display something like:
478 pckbc* changed
478 pckbc* at acpi0 addr -1 flags 0x1
(note the flags value has changed). Then enter "quit" for the kernel to
resume booting.
I am interested (obviously) in test reports, both positive and negative.
Don't forget to try to suspend your system, too, and see if the keyboard
and trackpad are still working upon resume.
Beware: I have only compile-tested the GPIO-related code as none of the
systems I have been able to test use GPIO interrupts.
Miod
Index: share/man/man4/acpi.4
===================================================================
RCS file: /OpenBSD/src/share/man/man4/acpi.4,v
diff -u -p -u -p -r1.76 acpi.4
--- share/man/man4/acpi.4 5 Nov 2024 11:12:48 -0000 1.76
+++ share/man/man4/acpi.4 27 Jan 2025 18:21:00 -0000
@@ -132,6 +132,8 @@ Intel OnChip System Fabric device
Intelligent Platform Management Interface driver
.It Xr pchgpio 4
Intel PCH GPIO controller
+.It Xr pckbc 4
+Keyboard controller
.It Xr pluart 4
ARM PrimeCell PL011 UART
.It Xr qcgpio 4
Index: share/man/man4/pckbc.4
===================================================================
RCS file: /OpenBSD/src/share/man/man4/pckbc.4,v
diff -u -p -u -p -r1.18 pckbc.4
--- share/man/man4/pckbc.4 26 Sep 2010 20:39:08 -0000 1.18
+++ share/man/man4/pckbc.4 27 Jan 2025 18:21:00 -0000
@@ -33,6 +33,7 @@
.Nd PC (ISA) keyboard controller driver
.Sh SYNOPSIS
.Cd "pckbc* at isa? flags 0x00 " Pq "alpha, amd64, i386, loongson"
+.Cd "pckbc* at acpi? flags 0x00 " Pq "amd64"
.Cd "pckbc* at ebus? " Pq "sparc64"
.Cd "pckbd* at pckbc?"
.Cd "pms* at pckbc?"
@@ -40,21 +41,17 @@
The
.Nm
driver handles resource allocation and device attachment for the
-traditional PC/AT keyboard controller.
-It provides two logical connections for child devices, the
+traditional PC/AT keyboard controller, or emulations thereof.
+It provides up to two logical connections for child devices, the
.Dq keyboard
slot for a keyboard and the
.Dq auxiliary
-slot for mice (the latter might be missing in older keyboard controllers).
-.\" .Pp
-.\" The optional
-.\" .Dq slot
-.\" locator argument can be used to force unusual connections of devices to
-.\" logical slots.
-.\" This feature is for experimentation only, it will not be
-.\" useful in normal operation.
+slot for mice (the latter might be missing in older keyboard controllers,
+or recent emulations).
.Pp
To avoid attaching a phantom PS/2 keyboard device, the
+.Nm isa 4
+attachment of the
.Nm
driver will attempt to detect USB legacy keyboard emulation on amd64 and i386
systems.
@@ -62,7 +59,19 @@ Unfortunately, the detection heuristics
PS/2 keyboard.
The keyboard can be forced to attach on these systems, by changing the
device flags to 1.
+.Pp
+The
+.Nm acpi 4
+attachment of the
+.Nm
+driver defaults to attach to only a well-known list of devices where it would
+perform better than its legacy
+.Nm isa 4
+attachment.
+It is possible to force it to always attach, by changing its
+device flags to 1.
.Sh SEE ALSO
+.Xr acpi 4 ,
.Xr ebus 4 ,
.Xr intro 4 ,
.Xr isa 4 ,
Index: sys/arch/amd64/conf/GENERIC
===================================================================
RCS file: /OpenBSD/src/sys/arch/amd64/conf/GENERIC,v
diff -u -p -u -p -r1.530 GENERIC
--- sys/arch/amd64/conf/GENERIC 26 Nov 2024 21:45:35 -0000 1.530
+++ sys/arch/amd64/conf/GENERIC 27 Jan 2025 18:21:00 -0000
@@ -86,6 +86,7 @@ ipmi0 at acpi? disable
ccpmic* at iic?
tipmic* at iic?
intelpmc* at acpi?
+pckbc* at acpi?
efi0 at bios0
mpbios0 at bios0
Index: sys/arch/amd64/conf/RAMDISK
===================================================================
RCS file: /OpenBSD/src/sys/arch/amd64/conf/RAMDISK,v
diff -u -p -u -p -r1.87 RAMDISK
--- sys/arch/amd64/conf/RAMDISK 12 Aug 2024 18:43:41 -0000 1.87
+++ sys/arch/amd64/conf/RAMDISK 27 Jan 2025 18:21:00 -0000
@@ -37,6 +37,7 @@ acpimadt0 at acpi?
com0 at acpi? addr 0x3f8
com1 at acpi? addr 0x2f8
com* at acpi?
+pckbc* at acpi?
mpbios0 at bios0
Index: sys/arch/amd64/conf/RAMDISK_CD
===================================================================
RCS file: /OpenBSD/src/sys/arch/amd64/conf/RAMDISK_CD,v
diff -u -p -u -p -r1.209 RAMDISK_CD
--- sys/arch/amd64/conf/RAMDISK_CD 26 Nov 2024 21:45:35 -0000 1.209
+++ sys/arch/amd64/conf/RAMDISK_CD 27 Jan 2025 18:21:00 -0000
@@ -56,6 +56,7 @@ com1 at acpi? addr 0x2f8
com2 at acpi? addr 0x3e8
com* at acpi?
glkgpio* at acpi?
+pckbc* at acpi?
mpbios0 at bios0
Index: sys/dev/acpi/acpi.c
===================================================================
RCS file: /OpenBSD/src/sys/dev/acpi/acpi.c,v
diff -u -p -u -p -r1.440 acpi.c
--- sys/dev/acpi/acpi.c 23 Jan 2025 11:24:34 -0000 1.440
+++ sys/dev/acpi/acpi.c 27 Jan 2025 18:21:00 -0000
@@ -3037,12 +3037,9 @@ const char *acpi_skip_hids[] = {
/* ISA devices for which we attach a driver later */
const char *acpi_isa_hids[] = {
- "PNP0303", /* IBM Enhanced Keyboard (101/102-key, PS/2 Mouse) */
"PNP0400", /* Standard LPT Parallel Port */
"PNP0401", /* ECP Parallel Port */
"PNP0700", /* PC-class Floppy Disk Controller */
- "PNP0F03", /* Microsoft PS/2-style Mouse */
- "PNP0F13", /* PS/2 Mouse */
NULL
};
Index: sys/dev/acpi/files.acpi
===================================================================
RCS file: /OpenBSD/src/sys/dev/acpi/files.acpi,v
diff -u -p -u -p -r1.71 files.acpi
--- sys/dev/acpi/files.acpi 4 Aug 2024 11:05:18 -0000 1.71
+++ sys/dev/acpi/files.acpi 27 Jan 2025 18:21:00 -0000
@@ -289,3 +289,7 @@ file dev/acpi/iosf_acpi.c iosf_acpi
device intelpmc
attach intelpmc at acpi
file dev/acpi/intelpmc.c intelpmc
+
+# PS/2 Keyboard Controller
+attach pckbc at acpi with pckbc_acpi
+file dev/acpi/pckbc_acpi.c pckbc_acpi
Index: sys/dev/acpi/pckbc_acpi.c
===================================================================
RCS file: sys/dev/acpi/pckbc_acpi.c
diff -N sys/dev/acpi/pckbc_acpi.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sys/dev/acpi/pckbc_acpi.c 27 Jan 2025 18:21:00 -0000
@@ -0,0 +1,524 @@
+/* $OpenBSD$ */
+/*
+ * Copyright (c) 2024, 2025, Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Copyright (c) 1998
+ * Matthias Drochner. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+
+#include <machine/bus.h>
+
+#include <dev/acpi/acpidev.h>
+#include <dev/acpi/acpivar.h>
+#include <dev/acpi/amltypes.h>
+#include <dev/acpi/dsdt.h>
+
+#include <dev/ic/i8042reg.h>
+#include <dev/ic/pckbcvar.h>
+
+/*
+ * This driver is more complicated than it should have to be, as it needs
+ * to gather the needs of pckbc (2 I/O ports, and up to 2 interrupts),
+ * which may be scattered across two ACPI nodes.
+ * Because of this, it is able to attach to two different ACPI nodes,
+ * but the second attachment "hijacks" the first one's softc struct, so
+ * that all the required data is gathered in one place.
+ */
+
+int pckbc_acpi_match(struct device *, void *, void *);
+void pckbc_acpi_attach(struct device *, struct device *, void *);
+int pckbc_acpi_activate(struct device *, int);
+
+struct pckbc_acpi_softc {
+ struct pckbc_softc sc;
+ void *sc_ih[2];
+ unsigned int sc_nints;
+};
+
+const struct cfattach pckbc_acpi_ca = {
+ .ca_devsize = sizeof(struct pckbc_acpi_softc),
+ .ca_match = pckbc_acpi_match,
+ .ca_attach = pckbc_acpi_attach,
+ .ca_activate = pckbc_acpi_activate
+};
+
+struct pckbc_acpi_gpio_intr {
+ struct aml_node *node;
+ uint16_t pin;
+ uint16_t flags;
+};
+
+struct pckbc_acpi_crs_data {
+ struct aml_node *basenode;
+ struct pckbc_acpi_gpio_intr intrs[2];
+ unsigned int nints;
+};
+
+int pckbc_acpi_match_kbd(struct device *, void *, void *);
+int pckbc_acpi_match_mou(struct device *, void *, void *,
+ struct pckbc_acpi_softc *);
+void pckbc_acpi_attach_kbd(struct device *, struct device *, void *);
+void pckbc_acpi_attach_mou(struct device *, struct device *, void *);
+struct pckbc_acpi_softc *pckbc_acpi_find(int);
+int pckbc_acpi_getgpioirqcount(int, union acpi_resource *, void *);
+int pckbc_acpi_getgpioirqdata(int, union acpi_resource *, void *);
+int pckbc_acpi_get_nirq(struct device *, struct acpi_attach_args *);
+void pckbc_acpi_get_gpioirqdata(struct device *, struct aml_node *,
+ struct pckbc_acpi_crs_data *);
+int pckbc_acpi_gpio_intr_wrapper(void *);
+
+int
+pckbc_acpi_match(struct device *parent, void *match, void *aux)
+{
+ struct pckbc_acpi_softc *sc = pckbc_acpi_find(1);
+ if (sc == NULL) /* no pckbc@acpi attachment yet */
+ return pckbc_acpi_match_kbd(parent, match, aux);
+ else
+ return pckbc_acpi_match_mou(parent, match, aux, sc);
+}
+
+void
+pckbc_acpi_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct pckbc_acpi_softc *sc = pckbc_acpi_find(2);
+ if (sc == NULL) /* no second pckbc@acpi attachment yet */
+ return pckbc_acpi_attach_kbd(parent, self, aux);
+ else
+ return pckbc_acpi_attach_mou(parent, self, aux);
+}
+
+const char *pckbc_acpi_cids_kbd[] = {
+ /* Devices which are known to require this pckbc@acpi attachment. */
+ "GOOG000A", /* Chromebook built-in keyboard */
+ "MSFT0001", /* Built-in keyboard found on various systems */
+ NULL,
+
+ /* Generic keyboard match, which can be enabled using cf_flags. */
+ "PNP0303", /* IBM Enhanced Keyboard (101/102-key, PS/2 Mouse) */
+ NULL
+};
+
+int
+pckbc_acpi_match_kbd(struct device *parent, void *match, void *aux)
+{
+ struct acpi_attach_args *aaa = aux;
+ struct cfdata *cf = match;
+ int rv;
+
+ if (aaa->aaa_naddr < 2)
+ return 0;
+ if (pckbc_acpi_get_nirq(parent, aaa) < 1)
+ return 0;
+ rv = acpi_matchhids(aaa, pckbc_acpi_cids_kbd, cf->cf_driver->cd_name);
+ if (rv > 0)
+ return rv;
+ if (cf->cf_flags & 0x0001)
+ rv = acpi_matchhids(aaa,
+ pckbc_acpi_cids_kbd + nitems(pckbc_acpi_cids_kbd) - 2,
+ cf->cf_driver->cd_name);
+ return rv;
+}
+
+const char *pckbc_acpi_cids_mou[] = {
+ "PNP0F03", /* Microsoft PS/2-style Mouse */
+ "PNP0F13", /* PS/2 Mouse */
+ NULL
+};
+
+int
+pckbc_acpi_match_mou(struct device *parent, void *match, void *aux,
+ struct pckbc_acpi_softc *pasc)
+{
+ struct acpi_attach_args *aaa = aux;
+ struct cfdata *cf = match;
+
+ /*
+ * We only need to attach the mouse node if the keyboard attachment
+ * succeeded, we need interrupt information for the aux slot, and
+ * this acpi node provides it.
+ */
+ if (pasc->sc_nints == 0 || pasc->sc_nints == nitems(pasc->sc_ih))
+ return 0;
+ if (pckbc_acpi_get_nirq(parent, aaa) < 1)
+ return 0;
+ return acpi_matchhids(aaa, pckbc_acpi_cids_mou, cf->cf_driver->cd_name);
+}
+
+int
+pckbc_acpi_activate(struct device *self, int act)
+{
+ struct pckbc_acpi_softc *pasc = (struct pckbc_acpi_softc *)self;
+ struct pckbc_softc *sc = &pasc->sc;
+ int rv = 0;
+
+ switch (act) {
+ case DVACT_SUSPEND:
+ rv = config_activate_children(self, act);
+ pckbc_stop(sc);
+ break;
+ case DVACT_RESUME:
+ pckbc_reset(sc);
+ rv = config_activate_children(self, act);
+ break;
+ default:
+ rv = config_activate_children(self, act);
+ break;
+ }
+ return rv;
+}
+
+void
+pckbc_acpi_attach_kbd(struct device *parent, struct device *self, void *aux)
+{
+ struct pckbc_acpi_softc *pasc = (struct pckbc_acpi_softc *)self;
+ struct pckbc_softc *sc = &pasc->sc;
+ struct acpi_attach_args *aaa = aux;
+ struct pckbc_internal *t;
+ struct pckbc_acpi_crs_data crsdata;
+ bus_space_handle_t ioh_d, ioh_c;
+ int irq, rv;
+
+ if (aaa->aaa_nirq == 0)
+ pckbc_acpi_get_gpioirqdata(parent, aaa->aaa_node, &crsdata);
+
+ printf(" addr 0x%llx/0x%llx 0x%llx/0x%llx", aaa->aaa_addr[0],
+ aaa->aaa_size[0], aaa->aaa_addr[1], aaa->aaa_size[1]);
+ if (aaa->aaa_nirq == 0) {
+ printf(" gpio irq pin");
+ for (irq = 0; irq < crsdata.nints && irq < nitems(pasc->sc_ih);
+ irq++)
+ printf(" %d", crsdata.intrs[irq].pin);
+ } else {
+ printf(" irq");
+ for (irq = 0; irq < aaa->aaa_nirq && irq < nitems(pasc->sc_ih);
+ irq++)
+ printf(" %d", aaa->aaa_irq[irq]);
+ }
+ printf(": \"%s\"", aaa->aaa_dev);
+
+ if (aaa->aaa_nirq == 0) {
+ for (irq = 0; irq < crsdata.nints; irq++) {
+ struct acpi_gpio *gpio = crsdata.intrs[irq].node->gpio;
+ gpio->intr_establish(gpio->cookie,
+ crsdata.intrs[irq].pin, crsdata.intrs[irq].flags,
+ pckbc_acpi_gpio_intr_wrapper, pasc);
+ pasc->sc_nints++;
+ if (pasc->sc_nints == nitems(pasc->sc_ih))
+ break;
+ }
+ } else {
+ for (irq = 0; irq < aaa->aaa_nirq; irq++) {
+ pasc->sc_ih[pasc->sc_nints] = acpi_intr_establish(
+ aaa->aaa_irq[irq], aaa->aaa_irq_flags[irq], IPL_TTY,
+ pckbcintr, pasc, self->dv_xname);
+ if (pasc->sc_ih[pasc->sc_nints] == NULL) {
+ printf(": can't establish interrupt %d\n",
+ aaa->aaa_irq[irq]);
+ goto fail_intr;
+ }
+ pasc->sc_nints++;
+ if (pasc->sc_nints == nitems(pasc->sc_ih))
+ break;
+ }
+ }
+
+ if (pckbc_is_console(aaa->aaa_bst[0], aaa->aaa_addr[0])) {
+ t = &pckbc_consdata;
+ pckbc_console_attached = 1;
+ /* t->t_cmdbyte was initialized by cnattach */
+ } else {
+ if ((rv = bus_space_map(aaa->aaa_bst[0], aaa->aaa_addr[0], 1, 0,
+ &ioh_d)) != 0) {
+ printf(": couldn't map data port (%d)\n", rv);
+ goto fail_mapd;
+ }
+ if ((rv = bus_space_map(aaa->aaa_bst[1], aaa->aaa_addr[1], 1, 0,
+ &ioh_c)) != 0) {
+ printf(": couldn't map command port (%d)\n", rv);
+ goto fail_mapc;
+ }
+
+ t = malloc(sizeof(*t), M_DEVBUF, M_WAITOK | M_ZERO);
+ /*
+ * pckbc should theoretically be updated to use separate
+ * bus_space_tag_t for the data and command ports, since on
+ * this particular attachment they appear as separate I/O
+ * resources. But since these are I/O resources, all
+ * aaa_bst[] are identical, so we can avoid this change
+ * for the time being as long as the logic in
+ * acpi_parse_resources() does not change.
+ */
+ t->t_iot = aaa->aaa_bst[0];
+ t->t_ioh_d = ioh_d;
+ t->t_ioh_c = ioh_c;
+ t->t_cmdbyte = KC8_CPU; /* Enable ports */
+ }
+
+ t->t_sc = sc;
+ sc->id = t;
+
+ printf("\n");
+
+ /*
+ * Make sure pckbc@isa will not try to attach.
+ */
+ {
+ extern int pckbc_acpi;
+ pckbc_acpi = 1;
+ }
+
+ pckbc_attach(sc, 0);
+ return;
+
+ fail_mapc:
+ bus_space_unmap(aaa->aaa_bst[0], ioh_d, 1);
+ fail_mapd:
+ fail_intr:
+ if (aaa->aaa_nirq == 0) {
+ /* XXX there is no way to disestablish GPIO interrupts */
+ } else {
+ for (irq = pasc->sc_nints - 1; irq >= 0; irq--)
+ acpi_intr_disestablish(pasc->sc_ih[irq]);
+ }
+ pasc->sc_nints = 0;
+}
+
+void
+pckbc_acpi_attach_mou(struct device *parent, struct device *self, void *aux)
+{
+ struct pckbc_acpi_softc *pasc = pckbc_acpi_find(1);
+ struct acpi_attach_args *aaa = aux;
+ struct pckbc_acpi_crs_data crsdata;
+ int irq, base;
+
+ if (aaa->aaa_nirq == 0)
+ pckbc_acpi_get_gpioirqdata(parent, aaa->aaa_node, &crsdata);
+
+ if (aaa->aaa_nirq == 0) {
+ printf(" gpio irq pin");
+ for (irq = 0; irq < crsdata.nints &&
+ irq < nitems(pasc->sc_ih) - pasc->sc_nints; irq++)
+ printf(" %d", crsdata.intrs[irq].pin);
+ } else {
+ printf(" irq");
+ for (irq = 0; irq < aaa->aaa_nirq &&
+ irq < nitems(pasc->sc_ih) - pasc->sc_nints; irq++)
+ printf(" %d", aaa->aaa_irq[irq]);
+ }
+ printf(": \"%s\"", aaa->aaa_dev);
+
+ base = pasc->sc_nints;
+ if (aaa->aaa_nirq == 0) {
+ for (irq = 0; irq < crsdata.nints; irq++) {
+ struct acpi_gpio *gpio = crsdata.intrs[irq].node->gpio;
+ gpio->intr_establish(gpio->cookie,
+ crsdata.intrs[irq].pin, crsdata.intrs[irq].flags,
+ pckbc_acpi_gpio_intr_wrapper, pasc);
+ pasc->sc_nints++;
+ if (pasc->sc_nints == nitems(pasc->sc_ih))
+ break;
+ }
+ } else {
+ for (irq = 0; irq < aaa->aaa_nirq; irq++) {
+ pasc->sc_ih[pasc->sc_nints] = acpi_intr_establish(
+ aaa->aaa_irq[irq], aaa->aaa_irq_flags[irq], IPL_TTY,
+ pckbcintr, pasc, self->dv_xname);
+ if (pasc->sc_ih[pasc->sc_nints] == NULL) {
+ printf(": can't establish interrupt %d\n",
+ aaa->aaa_irq[irq]);
+ goto fail_intr;
+ }
+ pasc->sc_nints++;
+ if (pasc->sc_nints == nitems(pasc->sc_ih))
+ break;
+ }
+ }
+
+ printf("\n");
+ return;
+
+ fail_intr:
+ if (aaa->aaa_nirq == 0) {
+ /* XXX there is no way to disestablish GPIO interrupts */
+ } else {
+ for (irq = pasc->sc_nints - 1; irq >= base; irq--)
+ acpi_intr_disestablish(pasc->sc_ih[irq]);
+ }
+ pasc->sc_nints = base;
+}
+
+struct pckbc_acpi_softc *
+pckbc_acpi_find(int nth)
+{
+ /*
+ * Iterate over all pckbc attachments, and picks the first one
+ * which turns out to be our previous selves, i.e. pckbc@acpi.
+ *
+ * The `nth' argument tells us which pckbc@acpi device to return.
+ *
+ * Note that, at `match' time, the device we may end up attaching
+ * is not found, but at `attach' time, it will be found.
+ */
+ extern struct cfdriver pckbc_cd;
+ struct device *sc;
+ int devno;
+
+ for (devno = 0; devno < pckbc_cd.cd_ndevs; devno++) {
+ if ((sc = pckbc_cd.cd_devs[devno]) == NULL)
+ continue;
+ if (sc->dv_cfdata->cf_attach != &pckbc_acpi_ca)
+ continue;
+ if (--nth == 0)
+ return (struct pckbc_acpi_softc *)sc;
+ }
+
+ return NULL;
+}
+
+int
+pckbc_acpi_get_nirq(struct device *acpidev, struct acpi_attach_args *aaa)
+{
+ struct aml_value val;
+ struct pckbc_acpi_crs_data crsdata;
+
+ /*
+ * We can probably safely assume there won't be a mix of regular
+ * and GPIO interrupts.
+ */
+ if (aaa->aaa_nirq != 0)
+ return aaa->aaa_nirq;
+
+ memset(&crsdata, 0, sizeof crsdata);
+ crsdata.basenode = aaa->aaa_node;
+ if (aml_evalname((struct acpi_softc *)acpidev, aaa->aaa_node, "_CRS",
+ 0, NULL, &val) != 0)
+ return 0;
+ if (val.type == AML_OBJTYPE_BUFFER && val.length >= 5)
+ aml_parse_resource(&val, pckbc_acpi_getgpioirqcount, &crsdata);
+ aml_freevalue(&val);
+ return crsdata.nints;
+}
+
+void
+pckbc_acpi_get_gpioirqdata(struct device *acpidev, struct aml_node *basenode,
+ struct pckbc_acpi_crs_data *crsdata)
+{
+ struct aml_value val;
+
+ memset(crsdata, 0, sizeof *crsdata);
+ crsdata->basenode = basenode;
+ if (aml_evalname((struct acpi_softc *)acpidev, basenode, "_CRS",
+ 0, NULL, &val) != 0)
+ return;
+ if (val.type == AML_OBJTYPE_BUFFER && val.length >= 5)
+ aml_parse_resource(&val, pckbc_acpi_getgpioirqdata, crsdata);
+ aml_freevalue(&val);
+}
+
+int
+pckbc_acpi_getgpioirqcount(int crsidx, union acpi_resource *crs, void *arg)
+{
+ struct pckbc_acpi_crs_data *crsdata = arg;
+ struct aml_node *node;
+
+ if (crsdata->nints == nitems(crsdata->intrs))
+ return 0;
+
+ switch (AML_CRSTYPE(crs)) {
+ case LR_GPIO:
+ if (crs->lr_gpio.type != LR_GPIO_INT)
+ break;
+ node = aml_searchname(crsdata->basenode,
+ (char *)&crs->pad[crs->lr_gpio.res_off]);
+ /*
+ * No need to count interrupts if no gpio driver has
+ * attached, as we won't be able to do anything with
+ * them.
+ * That's a bit paranoid but that's also in order to
+ * make sure we won't try to supersede pckbc@isa
+ * (legacy) unless we really have a chance to work
+ * better than it.
+ */
+ if (node != NULL && node->gpio != NULL)
+ crsdata->nints++;
+ break;
+ }
+ return 0;
+}
+
+int
+pckbc_acpi_getgpioirqdata(int crsidx, union acpi_resource *crs, void *arg)
+{
+ struct pckbc_acpi_crs_data *crsdata = arg;
+ struct aml_node *node;
+
+ if (crsdata->nints == nitems(crsdata->intrs))
+ return 0;
+
+ switch (AML_CRSTYPE(crs)) {
+ case LR_GPIO:
+ if (crs->lr_gpio.type != LR_GPIO_INT)
+ break;
+ node = aml_searchname(crsdata->basenode,
+ (char *)&crs->pad[crs->lr_gpio.res_off]);
+ if (node != NULL && node->gpio != NULL) {
+ crsdata->intrs[crsdata->nints].node = node;
+ crsdata->intrs[crsdata->nints].pin =
+ *(uint16_t *)&crs->pad[crs->lr_gpio.pin_off];
+ crsdata->intrs[crsdata->nints].flags =
+ crs->lr_gpio.tflags;
+ crsdata->nints++;
+ }
+ break;
+ }
+ return 0;
+}
+
+int
+pckbc_acpi_gpio_intr_wrapper(void *arg)
+{
+ int s, rv;
+
+ s = spltty();
+ rv = pckbcintr(arg);
+ splx(s);
+ return rv;
+}
Index: sys/dev/ic/pckbc.c
===================================================================
RCS file: /OpenBSD/src/sys/dev/ic/pckbc.c,v
diff -u -p -u -p -r1.55 pckbc.c
--- sys/dev/ic/pckbc.c 26 Aug 2023 15:01:00 -0000 1.55
+++ sys/dev/ic/pckbc.c 27 Jan 2025 18:21:00 -0000
@@ -89,6 +89,10 @@ int pckbc_console_attached;
int pckbc_console;
static struct pckbc_slotdata pckbc_cons_slotdata;
+#ifdef __HAVE_ACPI
+int pckbc_acpi;
+#endif
+
static int pckbc_wait_output(bus_space_tag_t, bus_space_handle_t);
static int pckbc_get8042cmd(struct pckbc_internal *);
Index: sys/dev/isa/pckbc_isa.c
===================================================================
RCS file: /OpenBSD/src/sys/dev/isa/pckbc_isa.c,v
diff -u -p -u -p -r1.19 pckbc_isa.c
--- sys/dev/isa/pckbc_isa.c 18 Aug 2015 06:54:00 -0000 1.19
+++ sys/dev/isa/pckbc_isa.c 27 Jan 2025 18:21:00 -0000
@@ -56,6 +56,15 @@ pckbc_isa_match(struct device *parent, v
bus_space_handle_t ioh_d, ioh_c;
int res;
+#ifdef __HAVE_ACPI
+ /* Don't try anything if pckbc@acpi has claimed the keyboard. */
+ {
+ extern int pckbc_acpi;
+ if (pckbc_acpi)
+ return 0;
+ }
+#endif
+
/* If values are hardwired to something that they can't be, punt. */
if ((ia->ia_iobase != IOBASEUNK && ia->ia_iobase != IO_KBD) ||
ia->ia_maddr != MADDRUNK ||
return of the chromebook keyboard diff