1/* $OpenBSD: acpige.c,v 1.2 2022/04/06 18:59:27 naddy Exp $ */ 2/* 3 * Copyright (c) 2020 Patrick Wildt <patrick@blueri.se> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18#include <sys/param.h> 19#include <sys/malloc.h> 20#include <sys/systm.h> 21#include <sys/tty.h> 22 23#include <dev/acpi/acpireg.h> 24#include <dev/acpi/acpivar.h> 25#include <dev/acpi/acpidev.h> 26#include <dev/acpi/amltypes.h> 27#include <dev/acpi/dsdt.h> 28 29struct acpige_softc; 30struct acpige_irq { 31 struct acpige_softc *ai_sc; 32 void *ai_ih; 33 uint32_t ai_irq; 34}; 35 36struct acpige_softc { 37 struct device sc_dev; 38 struct acpi_softc *sc_acpi; 39 struct aml_node *sc_devnode; 40 struct acpige_irq *sc_irq; 41}; 42 43int acpige_match(struct device *, void *, void *); 44void acpige_attach(struct device *, struct device *, void *); 45 46int acpige_intr(void *); 47void acpige_event_task(void *, int); 48 49const struct cfattach acpige_ca = { 50 sizeof(struct acpige_softc), acpige_match, acpige_attach 51}; 52 53struct cfdriver acpige_cd = { 54 NULL, "acpige", DV_DULL 55}; 56 57const char *acpige_hids[] = { 58 "ACPI0013", 59 NULL 60}; 61 62int 63acpige_match(struct device *parent, void *match, void *aux) 64{ 65 struct acpi_attach_args *aaa = aux; 66 struct cfdata *cf = match; 67 68 return acpi_matchhids(aaa, acpige_hids, cf->cf_driver->cd_name); 69} 70 71void 72acpige_attach(struct device *parent, struct device *self, void *aux) 73{ 74 struct acpige_softc *sc = (struct acpige_softc *)self; 75 struct acpi_attach_args *aaa = aux; 76 struct acpige_irq *ai; 77 int i; 78 79 sc->sc_acpi = (struct acpi_softc *)parent; 80 sc->sc_devnode = aaa->aaa_node; 81 82 if (aaa->aaa_nirq < 1) { 83 printf(": no interrupt\n"); 84 return; 85 } 86 87 sc->sc_irq = mallocarray(aaa->aaa_nirq, sizeof(struct acpige_irq), 88 M_DEVBUF, M_WAITOK); 89 90 for (i = 0; i < aaa->aaa_nirq; i++) { 91 printf("%s %d", i ? "," : " irq", aaa->aaa_irq[i]); 92 ai = &sc->sc_irq[i]; 93 ai->ai_sc = sc; 94 ai->ai_irq = aaa->aaa_irq[i]; 95 ai->ai_ih = acpi_intr_establish(aaa->aaa_irq[i], 96 aaa->aaa_irq_flags[i], IPL_BIO, acpige_intr, ai, 97 sc->sc_dev.dv_xname); 98 if (ai->ai_ih == NULL) { 99 printf(": can't establish interrupt\n"); 100 return; 101 } 102 } 103 104 printf("\n"); 105} 106 107int 108acpige_intr(void *arg) 109{ 110 struct acpige_irq *ai = arg; 111 struct acpige_softc *sc = ai->ai_sc; 112 113 acpi_addtask(sc->sc_acpi, acpige_event_task, sc, ai->ai_irq); 114 acpi_wakeup(sc->sc_acpi); 115 return 1; 116} 117 118void 119acpige_event_task(void *arg0, int irq) 120{ 121 struct acpige_softc *sc = arg0; 122 struct aml_value cmd; 123 124 memset(&cmd, 0, sizeof cmd); 125 cmd.v_integer = irq; 126 cmd.type = AML_OBJTYPE_INTEGER; 127 aml_evalname(sc->sc_acpi, sc->sc_devnode, "_EVT", 1, &cmd, NULL); 128} 129