summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Peereboom <marco@cvs.openbsd.org>2010-08-06 21:12:28 +0000
committerMarco Peereboom <marco@cvs.openbsd.org>2010-08-06 21:12:28 +0000
commit27c6001792f5964052d46f76b792b533f7a789b2 (patch)
treedd3edb33df93abd4c55aaa9ce835f4eea6347eac
parent0499b8250ef43faf29977ef964fe96df877da251 (diff)
Always call _PSW on _LID devices that support it to enable lid open to
resume the machine. Conversely disable it when the machine wakes up. Tested by several ok deraadt
-rw-r--r--sys/dev/acpi/acpi.c11
-rw-r--r--sys/dev/acpi/acpibtn.c68
-rw-r--r--sys/dev/acpi/acpidev.h4
3 files changed, 66 insertions, 17 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c
index 273a35c8f0c..a90f2f81106 100644
--- a/sys/dev/acpi/acpi.c
+++ b/sys/dev/acpi/acpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi.c,v 1.204 2010/08/06 14:20:14 deraadt Exp $ */
+/* $OpenBSD: acpi.c,v 1.205 2010/08/06 21:12:27 marco Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
* Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
@@ -1809,6 +1809,9 @@ acpi_resume(struct acpi_softc *sc, int state)
}
}
+ /* disable _LID for wakeup */
+ acpibtn_disable_psw();
+
/* Reset the indicator lights to "working" */
if (sc->sc_sst) {
env.v_integer = ACPI_SST_WORKING;
@@ -1850,6 +1853,9 @@ acpi_handle_suspend_failure(struct acpi_softc *sc)
}
}
+ /* disable _LID for wakeup */
+ acpibtn_disable_psw();
+
/* Reset the indicator lights to "working" */
if (sc->sc_sst) {
env.v_integer = ACPI_SST_WORKING;
@@ -1919,6 +1925,9 @@ acpi_prepare_sleep_state(struct acpi_softc *sc, int state)
goto fail;
}
+ /* enable _LID for wakeup */
+ acpibtn_enable_psw();
+
/* Reset the indicator lights to "sleeping" */
if (sc->sc_sst) {
env.v_integer = ACPI_SST_SLEEPING;
diff --git a/sys/dev/acpi/acpibtn.c b/sys/dev/acpi/acpibtn.c
index 278e296cd4f..274c956ddad 100644
--- a/sys/dev/acpi/acpibtn.c
+++ b/sys/dev/acpi/acpibtn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpibtn.c,v 1.31 2010/08/05 21:10:06 deraadt Exp $ */
+/* $OpenBSD: acpibtn.c,v 1.32 2010/08/06 21:12:27 marco Exp $ */
/*
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
*
@@ -47,13 +47,21 @@ struct acpibtn_softc {
struct aml_node *sc_devnode;
int sc_btn_type;
-#define ACPIBTN_UNKNOWN -1
-#define ACPIBTN_LID 0
-#define ACPIBTN_POWER 1
-#define ACPIBTN_SLEEP 2
+#define ACPIBTN_UNKNOWN 0
+#define ACPIBTN_LID 1
+#define ACPIBTN_POWER 2
+#define ACPIBTN_SLEEP 3
};
int acpibtn_getsta(struct acpibtn_softc *);
+int acpibtn_setpsw(struct acpibtn_softc *, int);
+
+struct acpi_lid {
+ struct acpibtn_softc *abl_softc;
+ SLIST_ENTRY(acpi_lid) abl_link;
+};
+SLIST_HEAD(acpi_lid_head, acpi_lid) acpibtn_lids =
+ SLIST_HEAD_INITIALIZER(acpibtn_lids);
struct cfattach acpibtn_ca = {
sizeof(struct acpibtn_softc), acpibtn_match, acpibtn_attach
@@ -66,6 +74,40 @@ struct cfdriver acpibtn_cd = {
const char *acpibtn_hids[] = { ACPI_DEV_LD, ACPI_DEV_PBD, ACPI_DEV_SBD, 0 };
int
+acpibtn_setpsw(struct acpibtn_softc *sc, int psw)
+{
+ struct aml_value val;
+
+ bzero(&val, sizeof val);
+ val.type = AML_OBJTYPE_INTEGER;
+ val.v_integer = psw;
+ val.length = 1;
+
+ return (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_PSW", 1, &val,
+ NULL));
+}
+
+void
+acpibtn_disable_psw(void)
+{
+ struct acpi_lid *lid;
+
+ /* disable _LID for wakeup */
+ SLIST_FOREACH(lid, &acpibtn_lids, abl_link)
+ acpibtn_setpsw(lid->abl_softc, 0);
+}
+
+void
+acpibtn_enable_psw(void)
+{
+ struct acpi_lid *lid;
+
+ /* enable _LID for wakeup */
+ SLIST_FOREACH(lid, &acpibtn_lids, abl_link)
+ acpibtn_setpsw(lid->abl_softc, 1);
+}
+
+int
acpibtn_match(struct device *parent, void *match, void *aux)
{
struct acpi_attach_args *aa = aux;
@@ -80,26 +122,22 @@ acpibtn_attach(struct device *parent, struct device *self, void *aux)
{
struct acpibtn_softc *sc = (struct acpibtn_softc *)self;
struct acpi_attach_args *aa = aux;
+ struct acpi_lid *lid;
sc->sc_acpi = (struct acpi_softc *)parent;
sc->sc_devnode = aa->aaa_node;
if (!strcmp(aa->aaa_dev, ACPI_DEV_LD)) {
- struct aml_value val;
-
sc->sc_btn_type = ACPIBTN_LID;
- bzero(&val, sizeof val);
- val.type = AML_OBJTYPE_INTEGER;
- val.v_integer = 1;
- val.length = 1;
- (void) aml_evalname(sc->sc_acpi, sc->sc_devnode, "_PSW",
- 1, &val, NULL);
+ if (acpibtn_setpsw(sc, 0) == 0) {
+ lid = malloc(sizeof(*lid), M_DEVBUF, M_WAITOK | M_ZERO);
+ lid->abl_softc = sc;
+ SLIST_INSERT_HEAD(&acpibtn_lids, lid, abl_link);
+ }
} else if (!strcmp(aa->aaa_dev, ACPI_DEV_PBD))
sc->sc_btn_type = ACPIBTN_POWER;
else if (!strcmp(aa->aaa_dev, ACPI_DEV_SBD))
sc->sc_btn_type = ACPIBTN_SLEEP;
- else
- sc->sc_btn_type = ACPIBTN_UNKNOWN;
acpibtn_getsta(sc);
diff --git a/sys/dev/acpi/acpidev.h b/sys/dev/acpi/acpidev.h
index b0e2d425a3e..c04d292d133 100644
--- a/sys/dev/acpi/acpidev.h
+++ b/sys/dev/acpi/acpidev.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpidev.h,v 1.31 2010/08/03 16:55:06 marco Exp $ */
+/* $OpenBSD: acpidev.h,v 1.32 2010/08/06 21:12:27 marco Exp $ */
/*
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
@@ -334,4 +334,6 @@ struct acpiec_softc {
int sc_gotsci;
};
+void acpibtn_disable_psw(void);
+void acpibtn_enable_psw(void);
#endif /* __DEV_ACPI_ACPIDEV_H__ */