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