summaryrefslogtreecommitdiffstats
path: root/include/asm-ppc/spinlock.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-ppc/spinlock.h')
-rw-r--r--include/asm-ppc/spinlock.h103
1 files changed, 29 insertions, 74 deletions
diff --git a/include/asm-ppc/spinlock.h b/include/asm-ppc/spinlock.h
index b2fb48d03..bb4af6a0c 100644
--- a/include/asm-ppc/spinlock.h
+++ b/include/asm-ppc/spinlock.h
@@ -71,71 +71,37 @@ typedef struct _spinlock_debug spinlock_t;
#define spin_unlock_wait(lp) do { barrier(); } while((lp)->lock)
extern void _spin_lock(spinlock_t *lock);
-extern int _spin_trylock(spinlock_t *lock);
extern void _spin_unlock(spinlock_t *lock);
-extern void _spin_lock_irq(spinlock_t *lock);
-extern void _spin_unlock_irq(spinlock_t *lock);
-extern void _spin_lock_irqsave(spinlock_t *lock);
-extern void _spin_unlock_irqrestore(spinlock_t *lock);
#define spin_lock(lp) _spin_lock(lp)
-#define spin_trylock(lp) _spin_trylock(lp)
#define spin_unlock(lp) _spin_unlock(lp)
-#define spin_lock_irq(lp) _spin_lock_irq(lp)
-#define spin_unlock_irq(lp) _spin_unlock_irq(lp)
-#define spin_lock_irqsave(lp, flags) do { __save_and_cli(flags); \
- _spin_lock_irqsave(lp); } while (0)
-#define spin_unlock_irqrestore(lp, flags) do { _spin_unlock_irqrestore(lp); \
- __restore_flags(flags); } while(0)
-#if 0
-extern __inline__ void spin_unlock(spinlock_t *lock)
-{
- __asm__ __volatile__("stw 0,%0" : : "m" (lock) : "memory");
-}
-
-static inline void spin_lock(spinlock_t * lock)
-{
- int stuck = 10000000;
- int tmp, val;
-
- __asm__ __volatile__(
- " mtctr %2\n"
- "1: lwarx %0,0,%3\n"
- " andi. %1,%0,1\n\t"
- " ori %0,%0,1\n\t"
- " bne- 2f\n\t"
- " stwcx. %0,0,%3\n\t"
- "2: bdnzf- 2,1b"
- : "=r" (tmp), "=r" (val)
- : "r" (stuck), "r" (lock)
- : "ctr");
- if (!val)
- {
- unsigned long __nip;
- asm("mfnip %0\n": "=r" (__nip));
- printk("spinlock stuck at %08lx\n", __nip);
- }
-}
-#define spin_trylock(lock) (!set_bit(0,(lock)))
+
+#define spin_trylock(l) (!test_and_set_bit(0, &((l)->lock) ))
#define spin_lock_irq(lock) \
do { __cli(); spin_lock(lock); } while (0)
-
#define spin_unlock_irq(lock) \
do { spin_unlock(lock); __sti(); } while (0)
#define spin_lock_irqsave(lock, flags) \
do { __save_flags(flags); __cli(); spin_lock(lock); } while (0)
-
#define spin_unlock_irqrestore(lock, flags) \
do { spin_unlock(lock); __restore_flags(flags); } while (0)
-#endif
-struct _rwlock_debug {
- volatile unsigned int lock;
- unsigned long owner_pc;
-};
-typedef struct _rwlock_debug rwlock_t;
+/*
+ * 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 {
+ volatile unsigned long lock;
+ volatile unsigned long owner_pc;
+} rwlock_t;
#define RW_LOCK_UNLOCKED { 0, 0 }
@@ -143,36 +109,25 @@ extern void _read_lock(rwlock_t *rw);
extern void _read_unlock(rwlock_t *rw);
extern void _write_lock(rwlock_t *rw);
extern void _write_unlock(rwlock_t *rw);
-extern void _read_lock_irq(rwlock_t *rw);
-extern void _read_unlock_irq(rwlock_t *rw);
-extern void _write_lock_irq(rwlock_t *rw);
-extern void _write_unlock_irq(rwlock_t *rw);
-extern void _read_lock_irqsave(rwlock_t *rw);
-extern void _read_unlock_irqrestore(rwlock_t *rw);
-extern void _write_lock_irqsave(rwlock_t *rw);
-extern void _write_unlock_irqrestore(rwlock_t *rw);
#define read_lock(rw) _read_lock(rw)
-#define read_unlock(rw) _read_unlock(rw)
#define write_lock(rw) _write_lock(rw)
#define write_unlock(rw) _write_unlock(rw)
-#define read_lock_irq(rw) _read_lock_irq(rw)
-#define read_unlock_irq(rw) _read_unlock_irq(rw)
-#define write_lock_irq(rw) _write_lock_irq(rw)
-#define write_unlock_irq(rw) _write_unlock_irq(rw)
-
-#define read_lock_irqsave(rw, flags) \
-do { __save_and_cli(flags); _read_lock_irqsave(rw); } while (0)
-
-#define read_unlock_irqrestore(rw, flags) do { _read_unlock_irqrestore(rw); \
- __restore_flags(flags); } while(0)
-
-#define write_lock_irqsave(rw, flags) \
-do { __save_and_cli(flags); _write_lock_irqsave(rw); } while(0)
+#define read_unlock(rw) _read_unlock(rw)
-#define write_unlock_irqrestore(rw, flags) do { _write_unlock_irqrestore(rw); \
- __restore_flags(flags); } while(0)
+#define read_lock_irq(lock) do { __cli(); read_lock(lock); } while (0)
+#define read_unlock_irq(lock) do { read_unlock(lock); __sti(); } while (0)
+#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_irqsave(lock, flags) \
+ do { __save_flags(flags); __cli(); read_lock(lock); } while (0)
+#define read_unlock_irqrestore(lock, flags) \
+ do { read_unlock(lock); __restore_flags(flags); } while (0)
+#define write_lock_irqsave(lock, flags) \
+ do { __save_flags(flags); __cli(); write_lock(lock); } while (0)
+#define write_unlock_irqrestore(lock, flags) \
+ do { write_unlock(lock); __restore_flags(flags); } while (0)
#endif /* SMP */
#endif /* __ASM_SPINLOCK_H */