Page MenuHomeFreeBSD

D37032.diff
No OneTemporary

D37032.diff

diff --git a/share/man/man4/acpi_ged.4 b/share/man/man4/acpi_ged.4
new file mode 100644
--- /dev/null
+++ b/share/man/man4/acpi_ged.4
@@ -0,0 +1,64 @@
+.\" Copyright (c) 2022 Takanori Watanabe
+.\"
+.\" 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd October 18, 2022
+.Dt ACPI_GED 4
+.Os
+.Sh NAME
+.Nm acpi_ged
+.Nd "ACPI Generic Event Device"
+.Sh SYNOPSIS
+To compile this driver into the kernel,
+place the following line in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device acpi_ged"
+.Ed
+.Pp
+Alternatively, to load the driver as a
+module at boot time, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+acpi_ged_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for generic events interface.
+This handles interrupts and evaluates the specific ACPI method.
+This may generate optionally ACPI notify for another device.
+.Sh SEE ALSO
+.Xr acpi 4
+.Sh HISTORY
+The
+.Nm
+device driver first appeared in
+.Fx 14.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Takanori Watanabe Aq Mt takawata@FreeBSD.org
diff --git a/sys/arm64/conf/std.virt b/sys/arm64/conf/std.virt
--- a/sys/arm64/conf/std.virt
+++ b/sys/arm64/conf/std.virt
@@ -24,3 +24,4 @@
options FDT
device acpi
+device acpi_ged
diff --git a/sys/conf/files b/sys/conf/files
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -806,6 +806,7 @@
dev/acpica/acpi_cmbat.c optional acpi
dev/acpica/acpi_cpu.c optional acpi
dev/acpica/acpi_ec.c optional acpi
+dev/acpica/acpi_ged.c optional acpi_ged acpi
dev/acpica/acpi_isab.c optional acpi isa
dev/acpica/acpi_lid.c optional acpi
dev/acpica/acpi_package.c optional acpi
diff --git a/sys/dev/acpica/acpi_ged.c b/sys/dev/acpica/acpi_ged.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/acpica/acpi_ged.c
@@ -0,0 +1,267 @@
+/*-
+ * Copyright (c) 2022 Takanori Watanabe
+ *
+ * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_acpi.h"
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <dev/acpica/acpivar.h>
+
+/* Hooks for the ACPI CA debugging infrastructure */
+#define _COMPONENT ACPI_GED
+ACPI_MODULE_NAME("GED")
+
+static MALLOC_DEFINE(M_ACPIGED, "acpiged", "ACPI Generic event data");
+
+struct acpi_ged_event {
+ device_t dev;
+ struct resource *r;
+ int rid;
+ void *cookie;
+ ACPI_HANDLE ah;
+ ACPI_OBJECT_LIST args;
+ ACPI_OBJECT arg1;
+};
+
+struct acpi_ged_softc {
+ int numevts;
+ struct acpi_ged_event *evts;
+};
+
+static int acpi_ged_probe(device_t dev);
+static int acpi_ged_attach(device_t dev);
+static int acpi_ged_detach(device_t dev);
+
+static char *ged_ids[] = { "ACPI0013", NULL };
+
+static device_method_t acpi_ged_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, acpi_ged_probe),
+ DEVMETHOD(device_attach, acpi_ged_attach),
+ DEVMETHOD(device_detach, acpi_ged_detach),
+ DEVMETHOD_END
+};
+
+static driver_t acpi_ged_driver = {
+ "acpi_ged",
+ acpi_ged_methods,
+ sizeof(struct acpi_ged_softc),
+};
+
+DRIVER_MODULE(acpi_ged, acpi, acpi_ged_driver, 0, 0);
+MODULE_DEPEND(acpi_ged, acpi, 1, 1, 1);
+
+static void
+acpi_ged_evt(void *arg)
+{
+ struct acpi_ged_event *evt = arg;
+
+ AcpiEvaluateObject(evt->ah, NULL, &evt->args, NULL);
+}
+
+static void
+acpi_ged_intr(void *arg)
+{
+ AcpiOsExecute(OSL_GPE_HANDLER, acpi_ged_evt, arg);
+}
+static int
+acpi_ged_probe(device_t dev)
+{
+ int rv;
+
+ if (acpi_disabled("ged"))
+ return (ENXIO);
+ rv = ACPI_ID_PROBE(device_get_parent(dev), dev, ged_ids, NULL);
+ if (rv > 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "Generic Event Device");
+ return (rv);
+}
+
+/*this should be in acpi_resource.*/
+static int
+acpi_get_trigger(ACPI_RESOURCE *res)
+{
+ int trig;
+
+ switch (res->Type) {
+ case ACPI_RESOURCE_TYPE_IRQ:
+ KASSERT(res->Data.Irq.InterruptCount == 1,
+ ("%s: multiple interrupts", __func__));
+ trig = res->Data.Irq.Triggering;
+ break;
+ case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+ KASSERT(res->Data.ExtendedIrq.InterruptCount == 1,
+ ("%s: multiple interrupts", __func__));
+ trig = res->Data.ExtendedIrq.Triggering;
+ break;
+ default:
+ panic("%s: bad resource type %u", __func__, res->Type);
+ }
+
+ return (trig == ACPI_EDGE_SENSITIVE)
+ ? INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL;
+}
+
+static int
+acpi_ged_attach(device_t dev)
+{
+ struct acpi_ged_softc *sc = device_get_softc(dev);
+ struct resource_list *rl;
+ struct resource_list_entry *rle;
+ ACPI_RESOURCE ares;
+ ACPI_HANDLE evt_method;
+ int i;
+ int rawirq, trig;
+ char name[] = "_Xnn";
+
+ ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__);
+
+ if (ACPI_FAILURE(AcpiGetHandle(acpi_get_handle(dev), "_EVT",
+ &evt_method))) {
+ device_printf(dev, "_EVT not found\n");
+ evt_method = NULL;
+ }
+
+ rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev);
+ STAILQ_FOREACH(rle, rl, link) {
+ if (rle->type == SYS_RES_IRQ) {
+ sc->numevts++;
+ }
+ }
+ sc->evts = mallocarray(sc->numevts, sizeof(*sc->evts), M_ACPIGED,
+ M_WAITOK | M_ZERO);
+ for (i = 0; i < sc->numevts; i++) {
+ sc->evts[i].dev = dev;
+ sc->evts[i].rid = i;
+ sc->evts[i].r = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+ &sc->evts[i].rid, RF_ACTIVE | RF_SHAREABLE);
+ if (sc->evts[i].r == NULL) {
+ device_printf(dev, "Cannot alloc %dth irq\n", i);
+ continue;
+ }
+#ifdef INTRNG
+ {
+ struct intr_map_data_acpi *ima;
+ ima = rman_get_virtual(sc->evts[i].r);
+ if (ima == NULL) {
+ device_printf(dev, "map not found"
+ " non-intrng?\n");
+ rawirq = rman_get_start(sc->evts[i].r);
+ trig = INTR_TRIGGER_LEVEL;
+ if (ACPI_SUCCESS(acpi_lookup_irq_resource
+ (dev, sc->evts[i].rid,
+ sc->evts[i].r, &ares))) {
+ trig = acpi_get_trigger(&ares);
+ }
+ } else if (ima->hdr.type == INTR_MAP_DATA_ACPI) {
+ device_printf(dev, "Raw IRQ %d\n", ima->irq);
+ rawirq = ima->irq;
+ trig = ima->trig;
+ } else {
+ device_printf(dev, "Not supported intr"
+ " type%d\n", ima->hdr.type);
+ continue;
+ }
+ }
+#else
+ rawirq = rman_get_start(sc->evt[i].r);
+ trig = INTR_TRIGGER_LEVEL;
+ if (ACPI_SUCCESS(acpi_lookup_irq_resource
+ (dev, sc->evts[i].rid,
+ sc->evts[i].r, &ares))) {
+ trig = acpi_get_trigger(&ares);
+ }
+#endif
+ if (rawirq < 0x100) {
+ sprintf(name, "_%c%02X",
+ ((trig == INTR_TRIGGER_EDGE) ? 'E' : 'L'),
+ rawirq);
+ if (ACPI_SUCCESS(AcpiGetHandle
+ (acpi_get_handle(dev),
+ name, &sc->evts[i].ah))) {
+ sc->evts[i].args.Count = 0; /* ensure */
+ } else {
+ sc->evts[i].ah = NULL; /* ensure */
+ }
+ }
+
+ if (sc->evts[i].ah == NULL) {
+ if (evt_method != NULL) {
+ sc->evts[i].ah = evt_method;
+ sc->evts[i].arg1.Type = ACPI_TYPE_INTEGER;
+ sc->evts[i].arg1.Integer.Value = rawirq;
+ sc->evts[i].args.Count = 1;
+ sc->evts[i].args.Pointer = &sc->evts[i].arg1;
+ } else{
+ device_printf
+ (dev,
+ "Cannot find handler method %d\n",
+ i);
+ continue;
+ }
+ }
+
+ if (bus_setup_intr(dev, sc->evts[i].r,
+ INTR_TYPE_MISC | INTR_MPSAFE, NULL, acpi_ged_intr,
+ &sc->evts[i], &sc->evts[i].cookie) != 0) {
+ device_printf(dev, "Failed to setup intr %d\n", i);
+ }
+ }
+
+ return_VALUE(0);
+}
+
+static int
+acpi_ged_detach(device_t dev)
+{
+ struct acpi_ged_softc *sc = device_get_softc(dev);
+ int i;
+
+ for (i = 0; i < sc->numevts; i++) {
+ if (sc->evts[i].cookie) {
+ bus_teardown_intr(dev, sc->evts[i].r,
+ sc->evts[i].cookie);
+ }
+ if (sc->evts[i].r) {
+ bus_release_resource(dev, SYS_RES_IRQ, sc->evts[i].rid,
+ sc->evts[i].r);
+ }
+ }
+ free(sc->evts, M_ACPIGED);
+
+ return (0);
+}
diff --git a/sys/modules/acpi/Makefile b/sys/modules/acpi/Makefile
--- a/sys/modules/acpi/Makefile
+++ b/sys/modules/acpi/Makefile
@@ -1,7 +1,7 @@
# $FreeBSD$
SUBDIR= acpi_asus acpi_asus_wmi acpi_dock acpi_fujitsu acpi_hp \
- acpi_ibm acpi_panasonic acpi_sony acpi_toshiba \
+ acpi_ged acpi_ibm acpi_panasonic acpi_sony acpi_toshiba \
acpi_video acpi_wmi aibs
.include <bsd.subdir.mk>
diff --git a/sys/modules/acpi/acpi_ged/Makefile b/sys/modules/acpi/acpi_ged/Makefile
new file mode 100644
--- /dev/null
+++ b/sys/modules/acpi/acpi_ged/Makefile
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+.PATH: ${SRCTOP}/sys/dev/acpica
+.if ${TARGET_ARCH} == aarch64
+CFLAGS += -DINTRNG
+.endif
+KMOD= acpi_ged
+SRCS= acpi_ged.c
+SRCS+= opt_acpi.h opt_evdev.h acpi_if.h bus_if.h device_if.h
+
+.include <bsd.kmod.mk>

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 16, 1:01 PM (21 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14659057
Default Alt Text
D37032.diff (10 KB)

Event Timeline