diff options
author | Tobias Weingartner <weingart@cvs.openbsd.org> | 2007-11-05 03:15:23 +0000 |
---|---|---|
committer | Tobias Weingartner <weingart@cvs.openbsd.org> | 2007-11-05 03:15:23 +0000 |
commit | b66f62f3a029d7c622b111734d8d067d06d581cb (patch) | |
tree | 9a93679346327d790ff28f8de91c03e91f60f8a1 /sys/dev/acpi | |
parent | f754ea84cf2b01540d109fa80b2c776879a072b1 (diff) |
Use the acpi_{acquire,release}_global_lock() to implement the global
functionality for ACPI. Has not shown any regressions, and may solve
some EC race conditions.
Ok gwk@, canacar@, ckuethe@
Diffstat (limited to 'sys/dev/acpi')
-rw-r--r-- | sys/dev/acpi/dsdt.c | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/sys/dev/acpi/dsdt.c b/sys/dev/acpi/dsdt.c index e3f38ea0094..9c5d8848186 100644 --- a/sys/dev/acpi/dsdt.c +++ b/sys/dev/acpi/dsdt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dsdt.c,v 1.96 2007/11/03 21:13:48 ckuethe Exp $ */ +/* $OpenBSD: dsdt.c,v 1.97 2007/11/05 03:15:22 weingart Exp $ */ /* * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> * @@ -1025,20 +1025,54 @@ aml_getbufint(struct aml_value *src, int bitpos, int bitlen, } } +long acpi_acquire_global_lock(void*); +long acpi_release_global_lock(void*); +static long global_lock_count = 0; + void aml_lockfield(struct aml_scope *scope, struct aml_value *field) { - if (AML_FIELD_LOCK(field->v_field.flags) == AML_FIELD_LOCK_ON) { - /* XXX: do locking here */ + int st = 0; + + if (AML_FIELD_LOCK(field->v_field.flags) != AML_FIELD_LOCK_ON) + return; + + /* If lock is already ours, just continue */ + if (global_lock_count++) + return; + + /* Spin to acquire lock */ + while (!st) { + st = acpi_acquire_global_lock(&dsdt_softc->sc_facs->global_lock); + /* XXX - yield/delay? */ } + + return; } void aml_unlockfield(struct aml_scope *scope, struct aml_value *field) { - if (AML_FIELD_LOCK(field->v_field.flags) == AML_FIELD_LOCK_ON) { - /* XXX: do unlocking here */ - } + int st, x; + + if (AML_FIELD_LOCK(field->v_field.flags) != AML_FIELD_LOCK_ON) + return; + + /* If we are the last ones, turn out the lights */ + if (--global_lock_count) + return; + + /* Release lock */ + st = acpi_release_global_lock(&dsdt_softc->sc_facs->global_lock); + if (!st) + return; + + /* Signal others if someone waiting */ + x = acpi_read_pmreg(dsdt_softc, ACPIREG_PM1_CNT, 0); + x |= ACPI_PM1_GBL_RLS; + acpi_write_pmreg(dsdt_softc, ACPIREG_PM1_CNT, 0, x); + + return; } void *aml_getbuffer(struct aml_value *, int *); |