summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJordan Hargrave <jordan@cvs.openbsd.org>2007-11-03 20:33:49 +0000
committerJordan Hargrave <jordan@cvs.openbsd.org>2007-11-03 20:33:49 +0000
commit1215bffb2b84f3ed0c103ccb5ea475b7887fabe9 (patch)
tree1b571822d92e2179a2175ca5fc6c97b9628e60a6 /sys
parent73e900f7befcce354fec7c7b2c48d7fc6d80f8a0 (diff)
Added support for displaying wakeup devices
ok beck@,weingart@,gwk@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/acpi/acpi.c62
-rw-r--r--sys/dev/acpi/acpivar.h12
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