diff options
-rw-r--r-- | arch/sparc/Kconfig | 1 | ||||
-rw-r--r-- | arch/sparc/include/asm/qspinlock.h | 7 | ||||
-rw-r--r-- | arch/sparc/include/asm/spinlock_64.h | 84 | ||||
-rw-r--r-- | arch/sparc/include/asm/spinlock_types.h | 5 |
4 files changed, 14 insertions, 83 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 0e8065207596..78af684f63b9 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -84,6 +84,7 @@ config SPARC64 | |||
84 | select HAVE_NMI | 84 | select HAVE_NMI |
85 | select HAVE_REGS_AND_STACK_ACCESS_API | 85 | select HAVE_REGS_AND_STACK_ACCESS_API |
86 | select ARCH_USE_QUEUED_RWLOCKS | 86 | select ARCH_USE_QUEUED_RWLOCKS |
87 | select ARCH_USE_QUEUED_SPINLOCKS | ||
87 | 88 | ||
88 | config ARCH_DEFCONFIG | 89 | config ARCH_DEFCONFIG |
89 | string | 90 | string |
diff --git a/arch/sparc/include/asm/qspinlock.h b/arch/sparc/include/asm/qspinlock.h new file mode 100644 index 000000000000..5ae9a2802846 --- /dev/null +++ b/arch/sparc/include/asm/qspinlock.h | |||
@@ -0,0 +1,7 @@ | |||
1 | #ifndef _ASM_SPARC_QSPINLOCK_H | ||
2 | #define _ASM_SPARC_QSPINLOCK_H | ||
3 | |||
4 | #include <asm-generic/qspinlock_types.h> | ||
5 | #include <asm-generic/qspinlock.h> | ||
6 | |||
7 | #endif /* _ASM_SPARC_QSPINLOCK_H */ | ||
diff --git a/arch/sparc/include/asm/spinlock_64.h b/arch/sparc/include/asm/spinlock_64.h index 8901c2d4ada9..f7028f5e1a5a 100644 --- a/arch/sparc/include/asm/spinlock_64.h +++ b/arch/sparc/include/asm/spinlock_64.h | |||
@@ -11,89 +11,7 @@ | |||
11 | #include <asm/processor.h> | 11 | #include <asm/processor.h> |
12 | #include <asm/barrier.h> | 12 | #include <asm/barrier.h> |
13 | #include <asm/qrwlock.h> | 13 | #include <asm/qrwlock.h> |
14 | 14 | #include <asm/qspinlock.h> | |
15 | /* To get debugging spinlocks which detect and catch | ||
16 | * deadlock situations, set CONFIG_DEBUG_SPINLOCK | ||
17 | * and rebuild your kernel. | ||
18 | */ | ||
19 | |||
20 | /* Because we play games to save cycles in the non-contention case, we | ||
21 | * need to be extra careful about branch targets into the "spinning" | ||
22 | * code. They live in their own section, but the newer V9 branches | ||
23 | * have a shorter range than the traditional 32-bit sparc branch | ||
24 | * variants. The rule is that the branches that go into and out of | ||
25 | * the spinner sections must be pre-V9 branches. | ||
26 | */ | ||
27 | |||
28 | #define arch_spin_is_locked(lp) ((lp)->lock != 0) | ||
29 | |||
30 | static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) | ||
31 | { | ||
32 | smp_cond_load_acquire(&lock->lock, !VAL); | ||
33 | } | ||
34 | |||
35 | static inline void arch_spin_lock(arch_spinlock_t *lock) | ||
36 | { | ||
37 | unsigned long tmp; | ||
38 | |||
39 | __asm__ __volatile__( | ||
40 | "1: ldstub [%1], %0\n" | ||
41 | " brnz,pn %0, 2f\n" | ||
42 | " nop\n" | ||
43 | " .subsection 2\n" | ||
44 | "2: ldub [%1], %0\n" | ||
45 | " brnz,pt %0, 2b\n" | ||
46 | " nop\n" | ||
47 | " ba,a,pt %%xcc, 1b\n" | ||
48 | " .previous" | ||
49 | : "=&r" (tmp) | ||
50 | : "r" (lock) | ||
51 | : "memory"); | ||
52 | } | ||
53 | |||
54 | static inline int arch_spin_trylock(arch_spinlock_t *lock) | ||
55 | { | ||
56 | unsigned long result; | ||
57 | |||
58 | __asm__ __volatile__( | ||
59 | " ldstub [%1], %0\n" | ||
60 | : "=r" (result) | ||
61 | : "r" (lock) | ||
62 | : "memory"); | ||
63 | |||
64 | return (result == 0UL); | ||
65 | } | ||
66 | |||
67 | static inline void arch_spin_unlock(arch_spinlock_t *lock) | ||
68 | { | ||
69 | __asm__ __volatile__( | ||
70 | " stb %%g0, [%0]" | ||
71 | : /* No outputs */ | ||
72 | : "r" (lock) | ||
73 | : "memory"); | ||
74 | } | ||
75 | |||
76 | static inline void arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long flags) | ||
77 | { | ||
78 | unsigned long tmp1, tmp2; | ||
79 | |||
80 | __asm__ __volatile__( | ||
81 | "1: ldstub [%2], %0\n" | ||
82 | " brnz,pn %0, 2f\n" | ||
83 | " nop\n" | ||
84 | " .subsection 2\n" | ||
85 | "2: rdpr %%pil, %1\n" | ||
86 | " wrpr %3, %%pil\n" | ||
87 | "3: ldub [%2], %0\n" | ||
88 | " brnz,pt %0, 3b\n" | ||
89 | " nop\n" | ||
90 | " ba,pt %%xcc, 1b\n" | ||
91 | " wrpr %1, %%pil\n" | ||
92 | " .previous" | ||
93 | : "=&r" (tmp1), "=&r" (tmp2) | ||
94 | : "r"(lock), "r"(flags) | ||
95 | : "memory"); | ||
96 | } | ||
97 | 15 | ||
98 | #define arch_read_lock_flags(p, f) arch_read_lock(p) | 16 | #define arch_read_lock_flags(p, f) arch_read_lock(p) |
99 | #define arch_write_lock_flags(p, f) arch_write_lock(p) | 17 | #define arch_write_lock_flags(p, f) arch_write_lock(p) |
diff --git a/arch/sparc/include/asm/spinlock_types.h b/arch/sparc/include/asm/spinlock_types.h index 64fce21b23df..bce8ef44dfa9 100644 --- a/arch/sparc/include/asm/spinlock_types.h +++ b/arch/sparc/include/asm/spinlock_types.h | |||
@@ -1,11 +1,16 @@ | |||
1 | #ifndef __SPARC_SPINLOCK_TYPES_H | 1 | #ifndef __SPARC_SPINLOCK_TYPES_H |
2 | #define __SPARC_SPINLOCK_TYPES_H | 2 | #define __SPARC_SPINLOCK_TYPES_H |
3 | 3 | ||
4 | #ifdef CONFIG_QUEUED_SPINLOCKS | ||
5 | #include <asm-generic/qspinlock_types.h> | ||
6 | #else | ||
7 | |||
4 | typedef struct { | 8 | typedef struct { |
5 | volatile unsigned char lock; | 9 | volatile unsigned char lock; |
6 | } arch_spinlock_t; | 10 | } arch_spinlock_t; |
7 | 11 | ||
8 | #define __ARCH_SPIN_LOCK_UNLOCKED { 0 } | 12 | #define __ARCH_SPIN_LOCK_UNLOCKED { 0 } |
13 | #endif /* CONFIG_QUEUED_SPINLOCKS */ | ||
9 | 14 | ||
10 | #ifdef CONFIG_QUEUED_RWLOCKS | 15 | #ifdef CONFIG_QUEUED_RWLOCKS |
11 | #include <asm-generic/qrwlock_types.h> | 16 | #include <asm-generic/qrwlock_types.h> |