xref: /netbsd-src/sys/dev/acpi/acpica/acpi_func.h (revision 274254cdae52594c1aa480a736aef78313d15c9c)
1 /*	$NetBSD: acpi_func.h,v 1.1 2008/05/24 22:16:20 jmcneill Exp $	*/
2 
3 #include <machine/cpufunc.h>
4 
5 #include <sys/atomic.h>
6 
7 #define GL_ACQUIRED	(-1)
8 #define GL_BUSY		0
9 #define GL_BIT_PENDING	1
10 #define GL_BIT_OWNED	2
11 #define GL_BIT_MASK	(GL_BIT_PENDING | GL_BIT_OWNED)
12 
13 #define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) 				\
14 do { 									\
15 	(Acq) = acpi_acquire_global_lock(&((GLptr)->GlobalLock));	\
16 } while (0)
17 
18 #define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) 				\
19 do {									\
20 	(Acq) = acpi_release_global_lock(&((GLptr)->GlobalLock));	\
21 } while (0)
22 
23 static inline int
24 acpi_acquire_global_lock(uint32_t *lock)
25 {
26 	uint32_t new, old, val;
27 
28 	do {
29 		old = *lock;
30 		new = ((old & ~GL_BIT_MASK) | GL_BIT_OWNED) |
31 		    ((old >> 1) & GL_BIT_PENDING);
32 		val = atomic_cas_32(lock, old, new);
33 	} while (__predict_false(val != old));
34 
35 	return ((new < GL_BIT_MASK) ? GL_ACQUIRED : GL_BUSY);
36 }
37 
38 static inline int
39 acpi_release_global_lock(uint32_t *lock)
40 {
41 	uint32_t new, old, val;
42 
43 	do {
44 		old = *lock;
45 		new = old & ~GL_BIT_MASK;
46 		val = atomic_cas_32(lock, old, new);
47 	} while (__predict_false(val != old));
48 
49 	return old & GL_BIT_PENDING;
50 }
51 
52 #define	ACPI_FLUSH_CPU_CACHE()		wbinvd()
53