diff options
author | Jordan Hargrave <jordan@cvs.openbsd.org> | 2007-11-03 20:33:49 +0000 |
---|---|---|
committer | Jordan Hargrave <jordan@cvs.openbsd.org> | 2007-11-03 20:33:49 +0000 |
commit | 1215bffb2b84f3ed0c103ccb5ea475b7887fabe9 (patch) | |
tree | 1b571822d92e2179a2175ca5fc6c97b9628e60a6 /sys | |
parent | 73e900f7befcce354fec7c7b2c48d7fc6d80f8a0 (diff) |
Added support for displaying wakeup devices
ok beck@,weingart@,gwk@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/acpi/acpi.c | 62 | ||||
-rw-r--r-- | sys/dev/acpi/acpivar.h | 12 |
2 files changed, 72 insertions, 2 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c index 0044195d302..d990d954328 100644 --- a/sys/dev/acpi/acpi.c +++ b/sys/dev/acpi/acpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi.c,v 1.92 2007/10/11 16:48:21 kettenis Exp $ */ +/* $OpenBSD: acpi.c,v 1.93 2007/11/03 20:33:48 jordan Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> @@ -65,6 +65,7 @@ int acpi_foundhid(struct aml_node *, void *); int acpi_foundec(struct aml_node *, void *); int acpi_foundtmp(struct aml_node *, void *); int acpi_foundprt(struct aml_node *, void *); +int acpi_foundprw(struct aml_node *, void *); int acpi_inidev(struct aml_node *, void *); int acpi_loadtables(struct acpi_softc *, struct acpi_rsdp *); @@ -388,6 +389,7 @@ acpi_attach(struct device *parent, struct device *self, void *aux) struct acpi_mem_map handle; struct acpi_rsdp *rsdp; struct acpi_q *entry; + struct acpi_wakeq *wentry; struct acpi_dsdt *p_dsdt; #ifndef SMALL_KERNEL struct device *dev; @@ -408,6 +410,7 @@ acpi_attach(struct device *parent, struct device *self, void *aux) printf(": rev %d", (int)rsdp->rsdp_revision); SIMPLEQ_INIT(&sc->sc_tables); + SIMPLEQ_INIT(&sc->sc_wakedevs); sc->sc_fadt = NULL; sc->sc_facs = NULL; @@ -556,6 +559,16 @@ acpi_attach(struct device *parent, struct device *self, void *aux) } printf("\n"); + /* Display wakeup devices and lowest S-state */ + printf("%s: wakeup devices ", DEVNAME(sc)); + SIMPLEQ_FOREACH(wentry, &sc->sc_wakedevs, q_next) { + printf("%.4s(S%d) ", + wentry->q_node->name, + wentry->q_state); + } + printf("\n"); + + #ifndef SMALL_KERNEL /* * ACPI is enabled now -- attach timer @@ -1079,6 +1092,52 @@ acpi_gpe_edge(struct acpi_softc *sc, int gpe, void *arg) return (0); } +/* Discover Devices that can wakeup the system + * _PRW returns a package + * pkg[0] = integer (FADT gpe bit) or package (gpe block,gpe bit) + * pkg[1] = lowest sleep state + * pkg[2+] = power resource devices (optional) + * + * To enable wakeup devices: + * Evaluate _ON method in each power resource device + * Evaluate _PSW method + */ +int +acpi_foundprw(struct aml_node *node, void *arg) +{ + struct acpi_softc *sc = arg; + struct acpi_wakeq *wq; + + wq = (struct acpi_wakeq *)malloc(sizeof(struct acpi_wakeq), M_DEVBUF, M_NOWAIT); + if (wq == NULL) { + return 0; + } + memset(wq, 0, sizeof(struct acpi_wakeq)); + + wq->q_wakepkg = (struct aml_value *)malloc(sizeof(struct aml_value), M_DEVBUF, M_NOWAIT); + if (wq->q_wakepkg == NULL) { + free(wq, M_DEVBUF); + return 0; + } + memset(wq->q_wakepkg, 0, sizeof(struct aml_value)); + dnprintf(10, "Found _PRW (%s)\n", node->parent->name); + aml_evalnode(sc, node, 0, NULL, wq->q_wakepkg); + wq->q_node = node->parent; + wq->q_gpe = -1; + + /* Get GPE of wakeup device, and lowest sleep level */ + if (wq->q_wakepkg->type == AML_OBJTYPE_PACKAGE && wq->q_wakepkg->length >= 2) { + if (wq->q_wakepkg->v_package[0]->type == AML_OBJTYPE_INTEGER) { + wq->q_gpe = wq->q_wakepkg->v_package[0]->v_integer; + } + if (wq->q_wakepkg->v_package[1]->type == AML_OBJTYPE_INTEGER) { + wq->q_state = wq->q_wakepkg->v_package[1]->v_integer; + } + } + SIMPLEQ_INSERT_TAIL(&sc->sc_wakedevs, wq, q_next); + return 0; +} + void acpi_init_gpes(struct acpi_softc *sc) { @@ -1118,6 +1177,7 @@ acpi_init_gpes(struct acpi_softc *sc) "edge"); } } + aml_find_node(aml_root.child, "_PRW", acpi_foundprw, sc); sc->sc_maxgpe = ngpe; } diff --git a/sys/dev/acpi/acpivar.h b/sys/dev/acpi/acpivar.h index 274b26bc856..a1d7ea8f4a6 100644 --- a/sys/dev/acpi/acpivar.h +++ b/sys/dev/acpi/acpivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: acpivar.h,v 1.36 2007/05/31 17:49:16 gwk Exp $ */ +/* $OpenBSD: acpivar.h,v 1.37 2007/11/03 20:33:48 jordan Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * @@ -59,7 +59,16 @@ struct acpi_q { u_int8_t q_data[0]; }; +struct acpi_wakeq { + SIMPLEQ_ENTRY(acpi_wakeq) q_next; + struct aml_node *q_node; + struct aml_value *q_wakepkg; + int q_gpe; + int q_state; +}; + typedef SIMPLEQ_HEAD(, acpi_q) acpi_qhead_t; +typedef SIMPLEQ_HEAD(, acpi_wakeq) acpi_wakeqhead_t; #define ACPIREG_PM1A_STS 0x00 #define ACPIREG_PM1A_EN 0x01 @@ -146,6 +155,7 @@ struct acpi_softc { */ struct acpi_fadt *sc_fadt; acpi_qhead_t sc_tables; + acpi_wakeqhead_t sc_wakedevs; /* * Second-level information from FADT |