summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoriwasaki <iwasaki@FreeBSD.org>2000-09-20 01:53:11 +0000
committeriwasaki <iwasaki@FreeBSD.org>2000-09-20 01:53:11 +0000
commit41b627fced8950f99775c2d5a75ef9d5c1dd0b3a (patch)
treebcead4ef651d4bfeb814cf5e3956ede62cd06521
parent25e47ad7a2fc03462f2f9b79c003eb3042e0bed5 (diff)
downloadFreeBSD-src-41b627fced8950f99775c2d5a75ef9d5c1dd0b3a.zip
FreeBSD-src-41b627fced8950f99775c2d5a75ef9d5c1dd0b3a.tar.gz
Ignore power button and sleep button events for 5 sec.
Wakeup event is generated by power button and/or sleep button on some laptops but this also generates SCI interrupt, and shutdown the system as result. So this kind of mechanism is introduced so that acpi driver ignore given events for certain period.
-rw-r--r--sys/dev/acpi/acpi.c25
-rw-r--r--sys/dev/acpi/acpi.h1
2 files changed, 24 insertions, 2 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c
index a8b84a3..afd39a6 100644
--- a/sys/dev/acpi/acpi.c
+++ b/sys/dev/acpi/acpi.c
@@ -153,6 +153,7 @@ static void acpi_process_event(acpi_softc_t *sc,
u_int32_t status_0, u_int32_t status_1);
static void acpi_intr(void *data);
static void acpi_enable_events(acpi_softc_t *sc);
+static void acpi_clear_ignore_events(void *arg);
/* New-bus dependent code */
static acpi_softc_t *acpi_get_softc(dev_t dev);
@@ -834,6 +835,10 @@ acpi_trans_sleeping_state(acpi_softc_t *sc, u_int8_t state)
val_a = ACPI_PM1_WAK_STS;
val_b = ACPI_PM1_WAK_STS;
acpi_io_pm1_status(sc, ACPI_REGISTERS_OUTPUT, &val_a, &val_b);
+
+ /* ignore power button and sleep button events for 5 sec. */
+ sc->ignore_events = ACPI_PM1_PWRBTN_EN | ACPI_PM1_SLPBTN_EN;
+ timeout(acpi_clear_ignore_events, (caddr_t)sc, hz * 5);
}
acpi_io_pm1_control(sc, ACPI_REGISTERS_INPUT, &val_a, &val_b);
@@ -1001,11 +1006,19 @@ acpi_process_event(acpi_softc_t *sc, u_int32_t status_a, u_int32_t status_b,
{
if (status_a & ACPI_PM1_PWRBTN_EN || status_b & ACPI_PM1_PWRBTN_EN) {
- acpi_set_sleeping_state(sc, ACPI_S_STATE_S5);
+ if (sc->ignore_events & ACPI_PM1_PWRBTN_EN) {
+ ACPI_DEBUGPRINT("PWRBTN event ingnored\n");
+ } else {
+ acpi_set_sleeping_state(sc, ACPI_S_STATE_S5);
+ }
}
if (status_a & ACPI_PM1_SLPBTN_EN || status_b & ACPI_PM1_SLPBTN_EN) {
- acpi_set_sleeping_state(sc, ACPI_S_STATE_S1);
+ if (sc->ignore_events & ACPI_PM1_SLPBTN_EN) {
+ ACPI_DEBUGPRINT("SLPBTN event ingnored\n");
+ } else {
+ acpi_set_sleeping_state(sc, ACPI_S_STATE_S1);
+ }
}
}
@@ -1166,6 +1179,14 @@ acpi_enable_events(acpi_softc_t *sc)
acpi_io_pm_timer(sc, ACPI_REGISTERS_INPUT, &status_a);
}
+static void
+acpi_clear_ignore_events(void *arg)
+{
+
+ ((acpi_softc_t *)arg)->ignore_events = 0;
+ ACPI_DEBUGPRINT("ignore events cleared\n");
+}
+
/*
* Character device stuff
*/
diff --git a/sys/dev/acpi/acpi.h b/sys/dev/acpi/acpi.h
index 5c4cb2e..59c60c2 100644
--- a/sys/dev/acpi/acpi.h
+++ b/sys/dev/acpi/acpi.h
@@ -68,6 +68,7 @@ typedef struct acpi_softc {
int system_state_initialized;
int broken_wakeuplogic;
int enabled;
+ u_int32_t ignore_events;
struct acpi_system_state_package system_state_package;
LIST_HEAD(, acpi_powerres_info) acpi_powerres_inflist;
LIST_HEAD(, acpi_powerres_device) acpi_powerres_devlist;
OpenPOWER on IntegriCloud