Download raw body.
return of the chromebook keyboard diff
Updated diff:
- adds LEN0071 to the "might need pckbc@acpi" list
- fixes and adds a few comments
- reworks match logic to run faster
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 30 Jan 2025 20:26:07 -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 30 Jan 2025 20:26:07 -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 30 Jan 2025 20:26:07 -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 30 Jan 2025 20:26:07 -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 30 Jan 2025 20:26:07 -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 30 Jan 2025 20:26:07 -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 30 Jan 2025 20:26:07 -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 30 Jan 2025 20:26:07 -0000
@@ -0,0 +1,552 @@
+/* $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 */
+ "LEN0071", /* Built-in keyboard found on various Lenovo systems */
+ "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
+};
+
+/*
+ * Matching logic for the keyboard node. We want two I/O ports, at least
+ * one interrupt, and either a HID match or a CID match (if allowed).
+ */
+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;
+ rv = acpi_matchhids(aaa, pckbc_acpi_cids_kbd, cf->cf_driver->cd_name);
+ if (rv == 0 && (cf->cf_flags & 0x0001) != 0)
+ rv = acpi_matchhids(aaa,
+ pckbc_acpi_cids_kbd + nitems(pckbc_acpi_cids_kbd) - 2,
+ cf->cf_driver->cd_name);
+ if (rv == 0)
+ return 0;
+ /* perform the expensive checks last */
+ if (pckbc_acpi_get_nirq(parent, aaa) < 1)
+ return 0;
+ return rv;
+}
+
+const char *pckbc_acpi_cids_mou[] = {
+ "PNP0F03", /* Microsoft PS/2-style Mouse */
+ "PNP0F13", /* PS/2 Mouse */
+ NULL
+};
+
+/*
+ * Matching logic for the mouse node. We want a previous keyboard to have
+ * attached, and want an interrupt if the keyboard node didn't have two.
+ */
+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;
+ int rv;
+
+ /*
+ * 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;
+ rv = acpi_matchhids(aaa, pckbc_acpi_cids_mou, cf->cf_driver->cd_name);
+ if (rv == 0)
+ return 0;
+ /* perform the expensive checks last */
+ if (pckbc_acpi_get_nirq(parent, aaa) < 1)
+ return 0;
+ return rv;
+}
+
+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. 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;
+}
+
+/*
+ * _CRS resource walker, which only counts GPIO interrupts.
+ */
+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;
+}
+
+/*
+ * Callback for the above routine.
+ */
+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;
+}
+
+/*
+ * _CRS resource walker, which only registers GPIO interrupt details.
+ */
+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);
+}
+
+/*
+ * Callback for the above routine.
+ */
+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;
+}
+
+/*
+ * Wrapper for GPIO interrupts, to enforce IPL_TTY.
+ */
+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 30 Jan 2025 20:26:07 -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 30 Jan 2025 20:26:07 -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