summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/amd64/include/pci_machdep.h3
-rw-r--r--sys/arch/amd64/pci/pci_machdep.c16
-rw-r--r--sys/arch/i386/pci/pci_machdep.c16
-rw-r--r--sys/arch/i386/pci/pci_machdep.h3
-rw-r--r--sys/dev/acpi/acpi.c92
-rw-r--r--sys/dev/acpi/acpipwrres.c240
-rw-r--r--sys/dev/acpi/acpireg.h10
-rw-r--r--sys/dev/acpi/acpivar.h26
-rw-r--r--sys/dev/acpi/files.acpi4
9 files changed, 322 insertions, 88 deletions
diff --git a/sys/arch/amd64/include/pci_machdep.h b/sys/arch/amd64/include/pci_machdep.h
index 51894074a34..395970faffd 100644
--- a/sys/arch/amd64/include/pci_machdep.h
+++ b/sys/arch/amd64/include/pci_machdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_machdep.h,v 1.21 2012/09/19 23:23:50 kettenis Exp $ */
+/* $OpenBSD: pci_machdep.h,v 1.22 2013/11/06 10:40:36 mpi Exp $ */
/* $NetBSD: pci_machdep.h,v 1.1 2003/02/26 21:26:11 fvdl Exp $ */
/*
@@ -95,6 +95,7 @@ void pci_decompose_tag(pci_chipset_tag_t, pcitag_t,
void pci_dev_postattach(struct device *, struct pci_attach_args *);
pcireg_t pci_min_powerstate(pci_chipset_tag_t, pcitag_t);
+void pci_set_powerstate_md(pci_chipset_tag_t, pcitag_t, int, int);
/*
* ALL OF THE FOLLOWING ARE MACHINE-DEPENDENT, AND SHOULD NOT BE USED
diff --git a/sys/arch/amd64/pci/pci_machdep.c b/sys/arch/amd64/pci/pci_machdep.c
index b6afa739d27..9fac42f5785 100644
--- a/sys/arch/amd64/pci/pci_machdep.c
+++ b/sys/arch/amd64/pci/pci_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_machdep.c,v 1.57 2013/05/30 16:19:25 deraadt Exp $ */
+/* $OpenBSD: pci_machdep.c,v 1.58 2013/11/06 10:40:36 mpi Exp $ */
/* $NetBSD: pci_machdep.c,v 1.3 2003/05/07 21:33:58 fvdl Exp $ */
/*-
@@ -665,6 +665,8 @@ pci_init_extents(void)
#include "acpi.h"
#if NACPI > 0
void acpi_pci_match(struct device *, struct pci_attach_args *);
+pcireg_t acpi_pci_min_powerstate(pci_chipset_tag_t, pcitag_t);
+void acpi_pci_set_powerstate(pci_chipset_tag_t, pcitag_t, int, int);
#endif
void
@@ -675,10 +677,6 @@ pci_dev_postattach(struct device *dev, struct pci_attach_args *pa)
#endif
}
-#if NACPI > 0
-pcireg_t acpi_pci_min_powerstate(pci_chipset_tag_t, pcitag_t);
-#endif
-
pcireg_t
pci_min_powerstate(pci_chipset_tag_t pc, pcitag_t tag)
{
@@ -688,3 +686,11 @@ pci_min_powerstate(pci_chipset_tag_t pc, pcitag_t tag)
return pci_get_powerstate(pc, tag);
#endif
}
+
+void
+pci_set_powerstate_md(pci_chipset_tag_t pc, pcitag_t tag, int state, int pre)
+{
+#if NACPI > 0
+ acpi_pci_set_powerstate(pc, tag, state, pre);
+#endif
+}
diff --git a/sys/arch/i386/pci/pci_machdep.c b/sys/arch/i386/pci/pci_machdep.c
index 374a7373842..d7b394a81c5 100644
--- a/sys/arch/i386/pci/pci_machdep.c
+++ b/sys/arch/i386/pci/pci_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_machdep.c,v 1.76 2013/07/10 21:31:12 kettenis Exp $ */
+/* $OpenBSD: pci_machdep.c,v 1.77 2013/11/06 10:40:36 mpi Exp $ */
/* $NetBSD: pci_machdep.c,v 1.28 1997/06/06 23:29:17 thorpej Exp $ */
/*-
@@ -941,6 +941,8 @@ pci_init_extents(void)
#include "acpi.h"
#if NACPI > 0
void acpi_pci_match(struct device *, struct pci_attach_args *);
+pcireg_t acpi_pci_min_powerstate(pci_chipset_tag_t, pcitag_t);
+void acpi_pci_set_powerstate(pci_chipset_tag_t, pcitag_t, int, int);
#endif
void
@@ -951,10 +953,6 @@ pci_dev_postattach(struct device *dev, struct pci_attach_args *pa)
#endif
}
-#if NACPI > 0
-pcireg_t acpi_pci_min_powerstate(pci_chipset_tag_t, pcitag_t);
-#endif
-
pcireg_t
pci_min_powerstate(pci_chipset_tag_t pc, pcitag_t tag)
{
@@ -964,3 +962,11 @@ pci_min_powerstate(pci_chipset_tag_t pc, pcitag_t tag)
return pci_get_powerstate(pc, tag);
#endif
}
+
+void
+pci_set_powerstate_md(pci_chipset_tag_t pc, pcitag_t tag, int state, int pre)
+{
+#if NACPI > 0
+ acpi_pci_set_powerstate(pc, tag, state, pre);
+#endif
+}
diff --git a/sys/arch/i386/pci/pci_machdep.h b/sys/arch/i386/pci/pci_machdep.h
index 1a45e9c9537..d6c298cb8c0 100644
--- a/sys/arch/i386/pci/pci_machdep.h
+++ b/sys/arch/i386/pci/pci_machdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci_machdep.h,v 1.25 2012/09/19 23:03:12 kettenis Exp $ */
+/* $OpenBSD: pci_machdep.h,v 1.26 2013/11/06 10:40:36 mpi Exp $ */
/* $NetBSD: pci_machdep.h,v 1.7 1997/06/06 23:29:18 thorpej Exp $ */
/*
@@ -111,6 +111,7 @@ void pci_decompose_tag(pci_chipset_tag_t, pcitag_t,
void pci_dev_postattach(struct device *, struct pci_attach_args *);
pcireg_t pci_min_powerstate(pci_chipset_tag_t, pcitag_t);
+void pci_set_powerstate_md(pci_chipset_tag_t, pcitag_t, int, int);
/*
* Section 6.2.4, `Miscellaneous Functions' of the PIC Specification,
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c
index 9d65faa395c..1683dbdc36c 100644
--- a/sys/dev/acpi/acpi.c
+++ b/sys/dev/acpi/acpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi.c,v 1.246 2013/06/01 23:00:16 mlarkin Exp $ */
+/* $OpenBSD: acpi.c,v 1.247 2013/11/06 10:40:36 mpi Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -74,6 +74,7 @@ int acpi_hasprocfvs;
void acpi_pci_match(struct device *, struct pci_attach_args *);
pcireg_t acpi_pci_min_powerstate(pci_chipset_tag_t, pcitag_t);
+void acpi_pci_set_powerstate(pci_chipset_tag_t, pcitag_t, int, int);
int acpi_match(struct device *, void *, void *);
void acpi_attach(struct device *, struct device *, void *);
@@ -559,15 +560,26 @@ void
acpi_pci_match(struct device *dev, struct pci_attach_args *pa)
{
struct acpi_pci *pdev;
+ int state;
TAILQ_FOREACH(pdev, &acpi_pcidevs, next) {
- if (pdev->bus == pa->pa_bus &&
- pdev->dev == pa->pa_device &&
- pdev->fun == pa->pa_function) {
- dnprintf(10,"%s at acpi0 %s\n",
- dev->dv_xname, aml_nodename(pdev->node));
- pdev->device = dev;
- }
+ if (pdev->bus != pa->pa_bus ||
+ pdev->dev != pa->pa_device ||
+ pdev->fun != pa->pa_function)
+ continue;
+
+ dnprintf(10,"%s at acpi0 %s\n", dev->dv_xname,
+ aml_nodename(pdev->node));
+
+ pdev->device = dev;
+
+ /*
+ * If some Power Resources are dependent on this device
+ * initialize them.
+ */
+ state = pci_get_powerstate(pa->pa_pc, pa->pa_tag);
+ acpi_pci_set_powerstate(pa->pa_pc, pa->pa_tag, state, 1);
+ acpi_pci_set_powerstate(pa->pa_pc, pa->pa_tag, state, 0);
}
}
@@ -604,6 +616,66 @@ acpi_pci_min_powerstate(pci_chipset_tag_t pc, pcitag_t tag)
}
void
+acpi_pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag, int state, int pre)
+{
+#if NACPIPWRRES > 0
+ struct acpi_softc *sc = acpi_softc;
+ struct acpi_pwrres *pr;
+ struct acpi_pci *pdev;
+ int bus, dev, fun;
+ char name[5];
+
+ pci_decompose_tag(pc, tag, &bus, &dev, &fun);
+ TAILQ_FOREACH(pdev, &acpi_pcidevs, next) {
+ if (pdev->bus == bus && pdev->dev == dev && pdev->fun == fun)
+ break;
+ }
+
+ /* XXX Add a check to discard nodes without Power Resources? */
+ if (pdev == NULL)
+ return;
+
+ SIMPLEQ_FOREACH(pr, &sc->sc_pwrresdevs, p_next) {
+ if (pr->p_node != pdev->node)
+ continue;
+
+ /*
+ * If the firmware is already aware that the device
+ * is in the given state, there's nothing to do.
+ */
+ if (pr->p_state == state)
+ continue;
+
+ if (pre) {
+ /*
+ * If a Resource is dependent on this device for
+ * the given state, make sure it is turned "_ON".
+ */
+ if (pr->p_res_state == state)
+ acpipwrres_ref_incr(pr->p_res_sc, pr->p_node);
+ } else {
+ /*
+ * If a Resource was referenced for the state we
+ * left, drop a reference and turn it "_OFF" if
+ * it was the last one.
+ */
+ if (pr->p_res_state == pr->p_state)
+ acpipwrres_ref_decr(pr->p_res_sc, pr->p_node);
+
+ if (pr->p_res_state == state) {
+ snprintf(name, sizeof(name), "_PS%d", state);
+ aml_evalname(sc, pr->p_node, name, 0,
+ NULL, NULL);
+ }
+
+ pr->p_state = state;
+ }
+
+ }
+#endif /* NACPIPWRRES > 0 */
+}
+
+void
acpi_pciroots_attach(struct device *dev, void *aux, cfprint_t pr)
{
struct acpi_pci *pdev;
@@ -658,6 +730,10 @@ acpi_attach(struct device *parent, struct device *self, void *aux)
SIMPLEQ_INIT(&sc->sc_tables);
SIMPLEQ_INIT(&sc->sc_wakedevs);
+#if NACPIPWRRES > 0
+ SIMPLEQ_INIT(&sc->sc_pwrresdevs);
+#endif /* NACPIPWRRES > 0 */
+
#ifndef SMALL_KERNEL
sc->sc_note = malloc(sizeof(struct klist), M_DEVBUF, M_NOWAIT | M_ZERO);
diff --git a/sys/dev/acpi/acpipwrres.c b/sys/dev/acpi/acpipwrres.c
index 8f3afccdbc7..56c4c89103b 100644
--- a/sys/dev/acpi/acpipwrres.c
+++ b/sys/dev/acpi/acpipwrres.c
@@ -1,5 +1,7 @@
-/* $OpenBSD: acpipwrres.c,v 1.4 2010/07/21 19:35:15 deraadt Exp $ */
+/* $OpenBSD: acpipwrres.c,v 1.5 2013/11/06 10:40:36 mpi Exp $ */
+
/*
+ * Copyright (c) 2013 Martin Pieuchot <mpi@openbsd.org>
* Copyright (c) 2009 Paul Irofti <pirofti@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -14,6 +16,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/signalvar.h>
@@ -31,10 +34,6 @@
int acpipwrres_match(struct device *, void *, void *);
void acpipwrres_attach(struct device *, struct device *, void *);
-int acpipwrres_notify(struct aml_node *, int, void *);
-
-#define NOTIFY_PWRRES_OFF 0
-#define NOTIFY_PWRRES_ON 1
#ifdef ACPIPWRRES_DEBUG
#define DPRINTF(x) printf x
@@ -51,11 +50,11 @@ struct acpipwrres_softc {
struct acpi_softc *sc_acpi;
struct aml_node *sc_devnode;
- TAILQ_HEAD(acpipwrres_cons_h, acpipwrres_consumer) sc_cons;
+ SIMPLEQ_HEAD(, acpipwrres_consumer) sc_cons;
+ int sc_cons_ref;
int sc_level;
int sc_order;
- int sc_ncons;
int sc_state;
#define ACPIPWRRES_OFF 0
#define ACPIPWRRES_ON 1
@@ -64,7 +63,7 @@ struct acpipwrres_softc {
struct acpipwrres_consumer {
struct aml_node *cs_node;
- TAILQ_ENTRY(acpipwrres_consumer) cs_link;
+ SIMPLEQ_ENTRY(acpipwrres_consumer) cs_next;
};
struct cfattach acpipwrres_ca = {
@@ -75,6 +74,8 @@ struct cfdriver acpipwrres_cd = {
NULL, "acpipwrres", DV_DULL
};
+int acpipwrres_hascons(struct acpipwrres_softc *, struct aml_node *);
+int acpipwrres_addcons(struct acpipwrres_softc *, struct aml_node *);
int acpipwrres_foundcons(struct aml_node *, void *);
int
@@ -93,9 +94,10 @@ acpipwrres_match(struct device *parent, void *match, void *aux)
void
acpipwrres_attach(struct device *parent, struct device *self, void *aux)
{
- struct acpipwrres_softc *sc = (struct acpipwrres_softc *)self;
- struct acpi_attach_args *aaa = aux;
- struct aml_value res;
+ struct acpipwrres_softc *sc = (struct acpipwrres_softc *)self;
+ struct acpi_attach_args *aaa = aux;
+ struct aml_value res;
+ struct acpipwrres_consumer *cons;
extern struct aml_node aml_root;
@@ -103,10 +105,7 @@ acpipwrres_attach(struct device *parent, struct device *self, void *aux)
sc->sc_devnode = aaa->aaa_node;
memset(&res, 0, sizeof res);
- printf(": %s\n", sc->sc_devnode->name);
-
- aml_register_notify(sc->sc_devnode, aaa->aaa_dev,
- acpipwrres_notify, sc, ACPIDEV_NOPOLL);
+ printf(": %s", sc->sc_devnode->name);
if (!aml_evalname(sc->sc_acpi, sc->sc_devnode, "_STA", 0, NULL, &res)) {
sc->sc_state = (int)aml_val2int(&res);
@@ -115,7 +114,7 @@ acpipwrres_attach(struct device *parent, struct device *self, void *aux)
sc->sc_state = ACPIPWRRES_UNK;
} else
sc->sc_state = ACPIPWRRES_UNK;
- DPRINTF(("%s: state = %d\n", DEVNAME(sc), sc->sc_state));
+ DPRINTF(("\n%s: state = %d\n", DEVNAME(sc), sc->sc_state));
if (aml_evalnode(sc->sc_acpi, aaa->aaa_node, 0, NULL, &res) == 0) {
sc->sc_level = res.v_powerrsrc.pwr_level;
sc->sc_order = res.v_powerrsrc.pwr_order;
@@ -125,86 +124,199 @@ acpipwrres_attach(struct device *parent, struct device *self, void *aux)
}
/* Get the list of consumers */
- TAILQ_INIT(&sc->sc_cons);
+ SIMPLEQ_INIT(&sc->sc_cons);
+#if notyet
aml_find_node(&aml_root, "_PRW", acpipwrres_foundcons, sc);
+#endif
aml_find_node(&aml_root, "_PR0", acpipwrres_foundcons, sc);
aml_find_node(&aml_root, "_PR1", acpipwrres_foundcons, sc);
aml_find_node(&aml_root, "_PR2", acpipwrres_foundcons, sc);
+ aml_find_node(&aml_root, "_PR3", acpipwrres_foundcons, sc);
+
+ DPRINTF(("%s", DEVNAME(sc)));
+ if (!SIMPLEQ_EMPTY(&sc->sc_cons)) {
+ printf(": resource for");
+ SIMPLEQ_FOREACH(cons, &sc->sc_cons, cs_next)
+ printf(" %s%s", cons->cs_node->name,
+ (SIMPLEQ_NEXT(cons, cs_next) == NULL) ? "" : ",");
+ }
+ printf("\n");
}
int
-acpipwrres_notify(struct aml_node *node, int notify, void *arg)
+acpipwrres_ref_incr(struct acpipwrres_softc *sc, struct aml_node *node)
{
- int fmatch = 0;
- struct acpipwrres_consumer *cons;
- struct acpipwrres_softc *sc = arg;
struct aml_value res;
- memset(&res, 0, sizeof res);
+ if (!acpipwrres_hascons(sc, node))
+ return (1);
- TAILQ_FOREACH(cons, &sc->sc_cons, cs_link)
- if (cons->cs_node == node) {
- fmatch = 1;
- break;
- }
- if (!fmatch)
- return (0);
+ DPRINTF(("%s: dev %s ON %d\n", DEVNAME(sc), node->name,
+ sc->sc_cons_ref));
- switch (notify) {
- case NOTIFY_PWRRES_ON:
- DPRINTF(("pwr: on devs %d\n", sc->sc_ncons));
- if (sc->sc_ncons++ == 0)
- aml_evalname(sc->sc_acpi, sc->sc_devnode, "_ON", 0, NULL,
- &res);
+ if (sc->sc_cons_ref++ == 0) {
+ memset(&res, 0, sizeof(res));
+ aml_evalname(sc->sc_acpi, sc->sc_devnode, "_ON", 0,
+ NULL, &res);
aml_freevalue(&res);
- break;
- case NOTIFY_PWRRES_OFF:
- DPRINTF(("pwr: off devs %d\n", sc->sc_ncons));
- if (--sc->sc_ncons == 0)
- aml_evalname(sc->sc_acpi, sc->sc_devnode, "_OFF", 0, NULL,
- &res);
+ }
+
+ return (0);
+}
+
+int
+acpipwrres_ref_decr(struct acpipwrres_softc *sc, struct aml_node *node)
+{
+ struct aml_value res;
+
+ if (!acpipwrres_hascons(sc, node))
+ return (1);
+
+ DPRINTF(("%s: dev %s OFF %d\n", DEVNAME(sc), node->name,
+ sc->sc_cons_ref));
+
+ if (--sc->sc_cons_ref == 0) {
+ memset(&res, 0, sizeof(res));
+ aml_evalname(sc->sc_acpi, sc->sc_devnode, "_OFF", 0,
+ NULL, &res);
aml_freevalue(&res);
- break;
- default:
- printf("%s: unknown event 0x%02x\n", DEVNAME(sc), notify);
- break;
}
return (0);
}
int
-acpipwrres_foundcons(struct aml_node *node, void *arg)
+acpipwrres_hascons(struct acpipwrres_softc *sc, struct aml_node *node)
+{
+ struct acpipwrres_consumer *cons;
+
+ SIMPLEQ_FOREACH(cons, &sc->sc_cons, cs_next) {
+ if (cons->cs_node == node)
+ return (1);
+ }
+
+ return (0);
+}
+
+int
+acpipwrres_addcons(struct acpipwrres_softc *sc, struct aml_node *node)
{
- int i = 0;
struct acpipwrres_consumer *cons;
- struct aml_node *pnode;
+ struct acpi_pwrres *pr;
+ int state;
+
+ /*
+ * Add handlers to put the device into Dx states.
+ *
+ * XXX What about PRW?
+ */
+ if (strcmp(node->name, "_PR0") == 0) {
+ state = ACPI_STATE_D0;
+ } else if (strcmp(node->name, "_PR1") == 0) {
+ state = ACPI_STATE_D1;
+ } else if (strcmp(node->name, "_PR2") == 0) {
+ state = ACPI_STATE_D2;
+ } else if (strcmp(node->name, "_PR3") == 0) {
+ state = ACPI_STATE_D3;
+ } else {
+ return (0);
+ }
+
+ if (!acpipwrres_hascons(sc, node->parent)) {
+ cons = malloc(sizeof(*cons), M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (cons == NULL)
+ return (ENOMEM);
+
+ cons->cs_node = node->parent;
+ SIMPLEQ_INSERT_TAIL(&sc->sc_cons, cons, cs_next);
+ }
+
+ DPRINTF(("%s: resource for %s (D%d) \n", DEVNAME(sc),
+ node->parent->name, state));
+
+ /*
+ * Make sure we attach only once the same Power Resource for a
+ * given state.
+ */
+ SIMPLEQ_FOREACH(pr, &sc->sc_acpi->sc_pwrresdevs, p_next) {
+ if (pr->p_node == node->parent &&
+ pr->p_res_state == state &&
+ pr->p_res_sc == sc) {
+ DPRINTF(("error: pr for %s already set\n",
+ aml_nodename(pr->p_node)));
+ return (EINVAL);
+ }
+ }
+
+ pr = malloc(sizeof(struct acpi_pwrres), M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (pr == NULL)
+ return (ENOMEM);
+
+ pr->p_node = node->parent;
+ pr->p_state = -1;
+ pr->p_res_state = state;
+ pr->p_res_sc = sc;
+
+ SIMPLEQ_INSERT_TAIL(&sc->sc_acpi->sc_pwrresdevs, pr, p_next);
+
+ return (0);
+}
+
+int
+acpipwrres_foundcons(struct aml_node *node, void *arg)
+{
struct acpipwrres_softc *sc = (struct acpipwrres_softc *)arg;
- struct aml_value res;
+ struct aml_value res, *ref;
+ int i = 0;
extern struct aml_node aml_root;
- memset(&res, 0, sizeof res);
+ memset(&res, 0, sizeof(res));
if (aml_evalnode(sc->sc_acpi, node, 0, NULL, &res) == -1) {
DPRINTF(("pwr: consumer not found\n"));
- return (-1);
- } else {
- DPRINTF(("%s: node name %s\n", DEVNAME(sc), aml_nodename(node)));
- if (!strcmp(node->name, "_PRW"))
- i = 2; /* _PRW first two values are ints */
- for (; i < res.length; i++) {
- pnode = aml_searchname(&aml_root,
- res.v_package[i]->v_string);
- if (pnode == sc->sc_devnode) {
- DPRINTF(("%s: consumer match\n", DEVNAME(sc)));
- cons = malloc(sizeof *cons, M_DEVBUF,
- M_WAITOK | M_ZERO);
- cons->cs_node = pnode;
- TAILQ_INSERT_HEAD(&sc->sc_cons, cons, cs_link);
+ return (1);
+ }
+
+ if (res.type != AML_OBJTYPE_PACKAGE) {
+ DPRINTF(("%s: %s is not a package\n", DEVNAME(sc),
+ aml_nodename(node)));
+ aml_freevalue(&res);
+ return (1);
+ }
+
+ DPRINTF(("%s: node name %s\n", DEVNAME(sc), aml_nodename(node)));
+ if (!strcmp(node->name, "_PRW"))
+ i = 2; /* _PRW first two values are ints */
+
+ for (; i < res.length; i++) {
+ ref = res.v_package[i];
+
+ if (ref->type == AML_OBJTYPE_STRING) {
+ struct aml_node *pnode;
+
+ pnode = aml_searchrel(&aml_root, ref->v_string);
+ if (pnode == NULL) {
+ DPRINTF(("%s: device %s not found\n",
+ DEVNAME(sc), ref->v_string));
+ continue;
}
+ ref = pnode->value;
}
+
+ if (ref->type == AML_OBJTYPE_OBJREF)
+ ref = ref->v_objref.ref;
+
+ if (ref->type != AML_OBJTYPE_POWERRSRC) {
+ DPRINTF(("%s: object reference has a wrong type (%d)\n",
+ DEVNAME(sc), ref->type));
+ continue;
+ }
+
+ if (ref->node == sc->sc_devnode)
+ (void)acpipwrres_addcons(sc, node);
}
+ aml_freevalue(&res);
return (0);
}
diff --git a/sys/dev/acpi/acpireg.h b/sys/dev/acpi/acpireg.h
index ebc2edaa169..420fe9173e8 100644
--- a/sys/dev/acpi/acpireg.h
+++ b/sys/dev/acpi/acpireg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpireg.h,v 1.28 2012/07/13 11:51:41 pirofti Exp $ */
+/* $OpenBSD: acpireg.h,v 1.29 2013/11/06 10:40:36 mpi Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
@@ -702,6 +702,14 @@ struct acpi_ivrs {
#define ACPI_STATE_S5 5
/*
+ * Device Power States
+ */
+#define ACPI_STATE_D0 0
+#define ACPI_STATE_D1 1
+#define ACPI_STATE_D2 2
+#define ACPI_STATE_D3 3
+
+/*
* ACPI Device IDs
*/
#define ACPI_DEV_TIM "PNP0100" /* System timer */
diff --git a/sys/dev/acpi/acpivar.h b/sys/dev/acpi/acpivar.h
index 78e8303df3c..023ced0408c 100644
--- a/sys/dev/acpi/acpivar.h
+++ b/sys/dev/acpi/acpivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpivar.h,v 1.75 2012/11/27 17:38:46 pirofti Exp $ */
+/* $OpenBSD: acpivar.h,v 1.76 2013/11/06 10:40:36 mpi Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
@@ -26,6 +26,8 @@
#include <sys/rwlock.h>
#include <machine/biosvar.h>
+#include "acpipwrres.h"
+
/* #define ACPI_DEBUG */
#ifdef ACPI_DEBUG
extern int acpi_debug;
@@ -43,6 +45,7 @@ extern u_int8_t acpi_lapic_flags[LAPIC_MAP_SIZE];
struct klist;
struct acpiec_softc;
+struct acpipwrres_softc;
struct acpivideo_softc {
struct device sc_dev;
@@ -89,6 +92,19 @@ struct acpi_wakeq {
int q_state;
};
+#if NACPIPWRRES > 0
+struct acpi_pwrres {
+ SIMPLEQ_ENTRY(acpi_pwrres) p_next;
+ struct aml_node *p_node; /* device's node */
+ int p_state; /* current state */
+
+ int p_res_state;
+ struct acpipwrres_softc *p_res_sc;
+};
+
+typedef SIMPLEQ_HEAD(, acpi_pwrres) acpi_pwrreshead_t;
+#endif /* NACPIPWRRES > 0 */
+
typedef SIMPLEQ_HEAD(, acpi_q) acpi_qhead_t;
typedef SIMPLEQ_HEAD(, acpi_wakeq) acpi_wakeqhead_t;
@@ -193,6 +209,9 @@ struct acpi_softc {
struct acpi_fadt *sc_fadt;
acpi_qhead_t sc_tables;
acpi_wakeqhead_t sc_wakedevs;
+#if NACPIPWRRES > 0
+ acpi_pwrreshead_t sc_pwrresdevs;
+#endif /* NACPIPWRRES > 0 */
/*
* Second-level information from FADT
@@ -309,6 +328,11 @@ void acpiec_read(struct acpiec_softc *, u_int8_t, int, u_int8_t *);
void acpiec_write(struct acpiec_softc *, u_int8_t, int, u_int8_t *);
void acpiec_handle_events(struct acpiec_softc *);
+#if NACPIPWRRES > 0
+int acpipwrres_ref_incr(struct acpipwrres_softc *, struct aml_node *);
+int acpipwrres_ref_decr(struct acpipwrres_softc *, struct aml_node *);
+#endif /* NACPIPWRRES > 0 */
+
int acpi_read_pmreg(struct acpi_softc *, int, int);
void acpi_write_pmreg(struct acpi_softc *, int, int, int);
diff --git a/sys/dev/acpi/files.acpi b/sys/dev/acpi/files.acpi
index 6c23a65ef8b..97802ad9c4e 100644
--- a/sys/dev/acpi/files.acpi
+++ b/sys/dev/acpi/files.acpi
@@ -1,4 +1,4 @@
-# $OpenBSD: files.acpi,v 1.26 2011/06/16 23:02:11 pirofti Exp $
+# $OpenBSD: files.acpi,v 1.27 2013/11/06 10:40:36 mpi Exp $
#
# Config file and device description for machine-independent ACPI code.
# Included by ports that need it.
@@ -105,7 +105,7 @@ file dev/acpi/acpivout.c acpivout
# ACPI pwrres
device acpipwrres
attach acpipwrres at acpi
-file dev/acpi/acpipwrres.c acpipwrres
+file dev/acpi/acpipwrres.c acpipwrres needs-flag
# ASUSTeK AI Booster ATK0110
device aibs