#ifndef __SPARC_SPINLOCK_H
#define __SPARC_SPINLOCK_H
-#ifndef __ASSEMBLY__
-
-#ifndef __SMP__
-
-typedef unsigned char spinlock_t;
-#define SPIN_LOCK_UNLOCKED 0
-
-#define spin_lock_init(lock) do { } while(0)
-#define spin_lock(lock) do { } while(0)
-#define spin_trylock(lock) do { } while(0)
-#define spin_unlock_wait(lock) do { } while(0)
-#define spin_unlock(lock) do { } while(0)
-#define spin_lock_irq(lock) cli()
-#define spin_unlock_irq(lock) sti()
-
-#define spin_lock_irqsave(lock, flags) save_and_cli(flags)
-#define spin_unlock_irqrestore(lock, flags) restore_flags(flags)
-
-/*
- * Read-write spinlocks, allowing multiple readers
- * but only one writer.
- *
- * NOTE! it is quite common to have readers in interrupts
- * but no interrupt writers. For those circumstances we
- * can "mix" irq-safe locks - any writer needs to get a
- * irq-safe write-lock, but readers can get non-irqsafe
- * read-locks.
- */
-typedef struct { } rwlock_t;
-#define RW_LOCK_UNLOCKED { }
-
-#define read_lock(lock) do { } while(0)
-#define read_unlock(lock) do { } while(0)
-#define write_lock(lock) do { } while(0)
-#define write_unlock(lock) do { } while(0)
-#define read_lock_irq(lock) cli()
-#define read_unlock_irq(lock) sti()
-#define write_lock_irq(lock) cli()
-#define write_unlock_irq(lock) sti()
-
-#define read_lock_irqsave(lock, flags) save_and_cli(flags)
-#define read_unlock_irqrestore(lock, flags) restore_flags(flags)
-#define write_lock_irqsave(lock, flags) save_and_cli(flags)
-#define write_unlock_irqrestore(lock, flags) restore_flags(flags)
+#include <linux/threads.h> /* For NR_CPUS */
-#else /* !(__SMP__) */
+#ifndef __ASSEMBLY__
#include <asm/psr.h>
@@ -65,8+22,9 @@ struct _spinlock_debug { };
typedef struct _spinlock_debug spinlock_t;
-#define SPIN_LOCK_UNLOCKED { 0, 0 }
+#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0, 0 }
#define spin_lock_init(lp) do { (lp)->owner_pc = 0; (lp)->lock = 0; } while(0)
+#define spin_is_locked(lp) (*((volatile unsigned char *)(&((lp)->lock))) != 0)
#define spin_unlock_wait(lp) do { barrier(); } while(*(volatile unsigned char *)(&(lp)->lock))
extern void _do_spin_lock(spinlock_t *lock, char *str);
@@ -77,20+35,22 @@ extern void _do_spin_unlock(spinlock_t *lock);
#define spin_lock(lock) _do_spin_lock(lock, "spin_lock")
#define spin_lock_irq(lock) do { __cli(); _do_spin_lock(lock, "spin_lock_irq"); } while(0)
+#define spin_lock_bh(lock) do { local_bh_disable(); _do_spin_lock(lock, "spin_lock_irq"); } while(0)
#define spin_lock_irqsave(lock, flags) do { __save_and_cli(flags); _do_spin_lock(lock, "spin_lock_irqsave"); } while(0)
#define spin_unlock(lock) _do_spin_unlock(lock)
#define spin_unlock_irq(lock) do { _do_spin_unlock(lock); __sti(); } while(0)
+#define spin_unlock_bh(lock) do { _do_spin_unlock(lock); local_bh_enable(); } while(0)
#define spin_unlock_irqrestore(lock, flags) do { _do_spin_unlock(lock); __restore_flags(flags); } while(0)
struct _rwlock_debug {
volatile unsigned int lock;
unsigned long owner_pc;
- unsigned long reader_pc[NCPUS];
+ unsigned long reader_pc[NR_CPUS];
};
typedef struct _rwlock_debug rwlock_t;
-#define RW_LOCK_UNLOCKED { 0, 0, {0} }
+#define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, {0} }
extern void _do_read_lock(rwlock_t *rw, char *str);
extern void _do_read_unlock(rwlock_t *rw, char *str);
@@ -104,6+64,7 @@ do { unsigned long flags; \ __restore_flags(flags); \
} while(0)
#define read_lock_irq(lock) do { __cli(); _do_read_lock(lock, "read_lock_irq"); } while(0)
+#define read_lock_bh(lock) do { local_bh_disable(); _do_read_lock(lock, "read_lock_irq"); } while(0)
#define read_lock_irqsave(lock, flags) do { __save_and_cli(flags); _do_read_lock(lock, "read_lock_irqsave"); } while(0)
#define read_unlock(lock) \
@@ -112,7+73,8 @@ do { unsigned long flags; \ _do_read_unlock(lock, "read_unlock"); \
__restore_flags(flags); \
} while(0)
-#define read_unlock_irq(lock) do { _do_read_unlock(lock, "read_unlock_irq"); __sti() } while(0)
+#define read_unlock_irq(lock) do { _do_read_unlock(lock, "read_unlock_irq"); __sti(); } while(0)
+#define read_unlock_bh(lock) do { _do_read_unlock(lock, "read_unlock_irq"); local_bh_enable(); } while(0)
#define read_unlock_irqrestore(lock, flags) do { _do_read_unlock(lock, "read_unlock_irqrestore"); __restore_flags(flags); } while(0)
#define write_lock(lock) \
@@ -122,6+84,7 @@ do { unsigned long flags; \ __restore_flags(flags); \
} while(0)
#define write_lock_irq(lock) do { __cli(); _do_write_lock(lock, "write_lock_irq"); } while(0)
+#define write_lock_bh(lock) do { local_bh_disable(); _do_write_lock(lock, "write_lock_irq"); } while(0)
#define write_lock_irqsave(lock, flags) do { __save_and_cli(flags); _do_write_lock(lock, "write_lock_irqsave"); } while(0)
#define write_unlock(lock) \
@@ -131,6+94,7 @@ do { unsigned long flags; \ __restore_flags(flags); \
} while(0)
#define write_unlock_irq(lock) do { _do_write_unlock(lock); __sti(); } while(0)
+#define write_unlock_bh(lock) do { _do_write_unlock(lock); local_bh_enable(); } while(0)
#define write_unlock_irqrestore(lock, flags) do { _do_write_unlock(lock); __restore_flags(flags); } while(0)
#else /* !SPIN_LOCK_DEBUG */
@@ -139,7+103,8 @@ typedef unsigned char spinlock_t; #define SPIN_LOCK_UNLOCKED 0
#define spin_lock_init(lock) (*(lock) = 0)
-#define spin_unlock_wait(lock) do { barrier(); } while(*(volatile spinlock_t *)lock)
+#define spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0)
+#define spin_unlock_wait(lock) do { barrier(); } while(*(volatile unsigned char *)lock)
extern __inline__ void spin_lock(spinlock_t *lock)
{
@@ -196,6+161,8 @@ extern __inline__ void spin_lock_irq(spinlock_t *lock) : "g2", "memory", "cc");
}
+#define spin_lock_bh(___lk) do { local_bh_disable(); spin_lock(___lk); } while(0)
+
extern __inline__ void spin_unlock_irq(spinlock_t *lock)
{
__asm__ __volatile__("
@@ -209,10+176,12 @@ extern __inline__ void spin_unlock_irq(spinlock_t *lock) : "g2", "memory");
}
-#define spin_lock_irqsave(lock, flags) \
+#define spin_unlock_bh(___lk) do { spin_unlock(___lk); local_bh_enable(); } while(0)
+
+#define spin_lock_irqsave(__lock, flags) \
do { \
- register spinlock_t *lp asm("g1"); \
- lp = lock; \
+ register spinlock_t *__lp asm("g1"); \
+ __lp = (__lock); \
__asm__ __volatile__( \
"rd %%psr, %0\n\t" \
"or %0, %1, %%g2\n\t" \
@@ -231,7+200,7 @@ do { \ "b,a 1b\n\t" \
".previous\n" \
: "=r" (flags) \
- : "i" (PSR_PIL), "r" (lp) \
+ : "i" (PSR_PIL), "r" (__lp) \
: "g2", "memory", "cc"); \
} while(0)
@@ -260,7+229,7 @@ extern __inline__ void spin_unlock_irqrestore(spinlock_t *lock, unsigned long fl */
typedef struct { volatile unsigned int lock; } rwlock_t;
-#define RW_LOCK_UNLOCKED { 0 }
+#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
/* Sort of like atomic_t's on Sparc, but even more clever.
*
@@ -335,6+304,11 @@ extern __inline__ void write_lock(rwlock_t *rw) #define write_lock_irq(lock) do { __cli(); write_lock(lock); } while (0)
#define write_unlock_irq(lock) do { write_unlock(lock); __sti(); } while (0)
+#define read_lock_bh(lock) do { local_bh_disable(); _read_lock(lock); } while (0)
+#define read_unlock_bh(lock) do { _read_unlock(lock); local_bh_enable(); } while (0)
+#define write_lock_bh(lock) do { local_bh_disable(); write_lock(lock); } while (0)
+#define write_unlock_bh(lock) do { write_unlock(lock); local_bh_enable(); } while (0)
+
#define read_lock_irqsave(lock, flags) \
do { __save_and_cli(flags); _read_lock(lock); } while (0)
#define read_unlock_irqrestore(lock, flags) \
@@ -346,8+320,6 @@ extern __inline__ void write_lock(rwlock_t *rw)
#endif /* SPIN_LOCK_DEBUG */
-#endif /* __SMP__ */
-
#endif /* !(__ASSEMBLY__) */
#endif /* __SPARC_SPINLOCK_H */