aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2006-12-04 04:17:28 -0500
committerPaul Mundt <lethal@linux-sh.org>2006-12-05 20:45:40 -0500
commitafbfb52e47273a440df33274452c603e8c332de2 (patch)
tree041dc70061a67e787b362959298e093830b4b4d7
parentc03c69610bfa728805deceeb624ee4268c722a5a (diff)
sh: stacktrace/lockdep/irqflags tracing support.
Wire up all of the essentials for lockdep.. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/sh/Kconfig8
-rw-r--r--arch/sh/Kconfig.debug4
-rw-r--r--arch/sh/kernel/Makefile1
-rw-r--r--arch/sh/kernel/cpu/sh2/entry.S16
-rw-r--r--arch/sh/kernel/cpu/sh3/entry.S2
-rw-r--r--arch/sh/kernel/entry-common.S64
-rw-r--r--arch/sh/kernel/stacktrace.c43
-rw-r--r--arch/sh/mm/fault.c3
-rw-r--r--include/asm-sh/irqflags.h123
-rw-r--r--include/asm-sh/rwsem.h27
-rw-r--r--include/asm-sh/system.h101
11 files changed, 289 insertions, 103 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index aa1ebc561b84..013732074d35 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -51,6 +51,14 @@ config GENERIC_TIME
51config ARCH_MAY_HAVE_PC_FDC 51config ARCH_MAY_HAVE_PC_FDC
52 bool 52 bool
53 53
54config STACKTRACE_SUPPORT
55 bool
56 default y
57
58config LOCKDEP_SUPPORT
59 bool
60 default y
61
54source "init/Kconfig" 62source "init/Kconfig"
55 63
56menu "System type" 64menu "System type"
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
index dcceec95a2d5..66a25ef4ef1b 100644
--- a/arch/sh/Kconfig.debug
+++ b/arch/sh/Kconfig.debug
@@ -1,5 +1,9 @@
1menu "Kernel hacking" 1menu "Kernel hacking"
2 2
3config TRACE_IRQFLAGS_SUPPORT
4 bool
5 default y
6
3source "lib/Kconfig.debug" 7source "lib/Kconfig.debug"
4 8
5config SH_STANDARD_BIOS 9config SH_STANDARD_BIOS
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 50d54c24d76a..99c7e5249f7a 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -21,3 +21,4 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
21obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 21obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
22obj-$(CONFIG_APM) += apm.o 22obj-$(CONFIG_APM) += apm.o
23obj-$(CONFIG_PM) += pm.o 23obj-$(CONFIG_PM) += pm.o
24obj-$(CONFIG_STACKTRACE) += stacktrace.o
diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S
index 298d9191909d..34d51b3745ea 100644
--- a/arch/sh/kernel/cpu/sh2/entry.S
+++ b/arch/sh/kernel/cpu/sh2/entry.S
@@ -184,6 +184,11 @@ trap_entry:
184 add r15,r8 184 add r15,r8
185 mov.l r9,@r8 185 mov.l r9,@r8
186 mov r9,r8 186 mov r9,r8
187#ifdef CONFIG_TRACE_IRQFLAGS
188 mov.l 5f, r9
189 jsr @r9
190 nop
191#endif
187 sti 192 sti
188 bra system_call 193 bra system_call
189 nop 194 nop
@@ -193,6 +198,9 @@ trap_entry:
1932: .long break_point_trap_software 1982: .long break_point_trap_software
1943: .long NR_syscalls 1993: .long NR_syscalls
1954: .long sys_call_table 2004: .long sys_call_table
201#ifdef CONFIG_TRACE_IRQFLAGS
2025: .long trace_hardirqs_on
203#endif
196 204
197#if defined(CONFIG_SH_STANDARD_BIOS) 205#if defined(CONFIG_SH_STANDARD_BIOS)
198 /* Unwind the stack and jmp to the debug entry */ 206 /* Unwind the stack and jmp to the debug entry */
@@ -255,6 +263,11 @@ ENTRY(address_error_handler)
255 263
256restore_all: 264restore_all:
257 cli 265 cli
266#ifdef CONFIG_TRACE_IRQFLAGS
267 mov.l 3f, r0
268 jsr @r0
269 nop
270#endif
258 mov r15,r0 271 mov r15,r0
259 mov.l $cpu_mode,r2 272 mov.l $cpu_mode,r2
260 mov #OFF_SR,r3 273 mov #OFF_SR,r3
@@ -307,6 +320,9 @@ $current_thread_info:
307 .long __current_thread_info 320 .long __current_thread_info
308$cpu_mode: 321$cpu_mode:
309 .long __cpu_mode 322 .long __cpu_mode
323#ifdef CONFIG_TRACE_IRQFLAGS
3243: .long trace_hardirqs_off
325#endif
310 326
311! common exception handler 327! common exception handler
312#include "../../entry-common.S" 328#include "../../entry-common.S"
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 7ba3dcbe7504..8c0dc2700c69 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -140,7 +140,7 @@ call_dpf:
140 mov.l 1f, r0 140 mov.l 1f, r0
141 mov.l @r0, r6 ! address 141 mov.l @r0, r6 ! address
142 mov.l 3f, r0 142 mov.l 3f, r0
143 sti 143
144 jmp @r0 144 jmp @r0
145 mov r15, r4 ! regs 145 mov r15, r4 ! regs
146 146
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 8f96d21fcb1c..29136a35d7c7 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -100,6 +100,11 @@ debug_trap:
100 .align 2 100 .align 2
101ENTRY(exception_error) 101ENTRY(exception_error)
102 ! 102 !
103#ifdef CONFIG_TRACE_IRQFLAGS
104 mov.l 3f, r0
105 jsr @r0
106 nop
107#endif
103 sti 108 sti
104 mov.l 2f, r0 109 mov.l 2f, r0
105 jmp @r0 110 jmp @r0
@@ -109,10 +114,18 @@ ENTRY(exception_error)
109 .align 2 114 .align 2
1101: .long break_point_trap_software 1151: .long break_point_trap_software
1112: .long do_exception_error 1162: .long do_exception_error
117#ifdef CONFIG_TRACE_IRQFLAGS
1183: .long trace_hardirqs_on
119#endif
112 120
113 .align 2 121 .align 2
114ret_from_exception: 122ret_from_exception:
115 preempt_stop() 123 preempt_stop()
124#ifdef CONFIG_TRACE_IRQFLAGS
125 mov.l 4f, r0
126 jsr @r0
127 nop
128#endif
116ENTRY(ret_from_irq) 129ENTRY(ret_from_irq)
117 ! 130 !
118 mov #OFF_SR, r0 131 mov #OFF_SR, r0
@@ -143,6 +156,11 @@ need_resched:
143 mov.l 1f, r0 156 mov.l 1f, r0
144 mov.l r0, @(TI_PRE_COUNT,r8) 157 mov.l r0, @(TI_PRE_COUNT,r8)
145 158
159#ifdef CONFIG_TRACE_IRQFLAGS
160 mov.l 3f, r0
161 jsr @r0
162 nop
163#endif
146 sti 164 sti
147 mov.l 2f, r0 165 mov.l 2f, r0
148 jsr @r0 166 jsr @r0
@@ -150,9 +168,15 @@ need_resched:
150 mov #0, r0 168 mov #0, r0
151 mov.l r0, @(TI_PRE_COUNT,r8) 169 mov.l r0, @(TI_PRE_COUNT,r8)
152 cli 170 cli
171#ifdef CONFIG_TRACE_IRQFLAGS
172 mov.l 4f, r0
173 jsr @r0
174 nop
175#endif
153 176
154 bra need_resched 177 bra need_resched
155 nop 178 nop
179
156noresched: 180noresched:
157 bra __restore_all 181 bra __restore_all
158 nop 182 nop
@@ -160,11 +184,20 @@ noresched:
160 .align 2 184 .align 2
1611: .long PREEMPT_ACTIVE 1851: .long PREEMPT_ACTIVE
1622: .long schedule 1862: .long schedule
187#ifdef CONFIG_TRACE_IRQFLAGS
1883: .long trace_hardirqs_on
1894: .long trace_hardirqs_off
190#endif
163#endif 191#endif
164 192
165ENTRY(resume_userspace) 193ENTRY(resume_userspace)
166 ! r8: current_thread_info 194 ! r8: current_thread_info
167 cli 195 cli
196#ifdef CONFIG_TRACE_IRQFLAGS
197 mov.l 5f, r0
198 jsr @r0
199 nop
200#endif
168 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags 201 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
169 tst #_TIF_WORK_MASK, r0 202 tst #_TIF_WORK_MASK, r0
170 bt/s __restore_all 203 bt/s __restore_all
@@ -210,6 +243,11 @@ work_resched:
210 jsr @r1 ! schedule 243 jsr @r1 ! schedule
211 nop 244 nop
212 cli 245 cli
246#ifdef CONFIG_TRACE_IRQFLAGS
247 mov.l 5f, r0
248 jsr @r0
249 nop
250#endif
213 ! 251 !
214 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags 252 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
215 tst #_TIF_WORK_MASK, r0 253 tst #_TIF_WORK_MASK, r0
@@ -221,6 +259,10 @@ work_resched:
2211: .long schedule 2591: .long schedule
2222: .long do_notify_resume 2602: .long do_notify_resume
2233: .long restore_all 2613: .long restore_all
262#ifdef CONFIG_TRACE_IRQFLAGS
2634: .long trace_hardirqs_on
2645: .long trace_hardirqs_off
265#endif
224 266
225 .align 2 267 .align 2
226syscall_exit_work: 268syscall_exit_work:
@@ -229,6 +271,11 @@ syscall_exit_work:
229 tst #_TIF_SYSCALL_TRACE, r0 271 tst #_TIF_SYSCALL_TRACE, r0
230 bt/s work_pending 272 bt/s work_pending
231 tst #_TIF_NEED_RESCHED, r0 273 tst #_TIF_NEED_RESCHED, r0
274#ifdef CONFIG_TRACE_IRQFLAGS
275 mov.l 5f, r0
276 jsr @r0
277 nop
278#endif
232 sti 279 sti
233 ! XXX setup arguments... 280 ! XXX setup arguments...
234 mov.l 4f, r0 ! do_syscall_trace 281 mov.l 4f, r0 ! do_syscall_trace
@@ -265,7 +312,7 @@ syscall_trace_entry:
265 mov.l r0, @(OFF_R0,r15) ! Return value 312 mov.l r0, @(OFF_R0,r15) ! Return value
266 313
267__restore_all: 314__restore_all:
268 mov.l 1f,r0 315 mov.l 1f, r0
269 jmp @r0 316 jmp @r0
270 nop 317 nop
271 318
@@ -331,7 +378,13 @@ ENTRY(system_call)
331 mov #OFF_TRA, r9 378 mov #OFF_TRA, r9
332 add r15, r9 379 add r15, r9
333 mov.l r8, @r9 ! set TRA value to tra 380 mov.l r8, @r9 ! set TRA value to tra
381#ifdef CONFIG_TRACE_IRQFLAGS
382 mov.l 5f, r10
383 jsr @r10
384 nop
385#endif
334 sti 386 sti
387
335 ! 388 !
336 get_current_thread_info r8, r10 389 get_current_thread_info r8, r10
337 mov.l @(TI_FLAGS,r8), r8 390 mov.l @(TI_FLAGS,r8), r8
@@ -355,6 +408,11 @@ syscall_call:
355 ! 408 !
356syscall_exit: 409syscall_exit:
357 cli 410 cli
411#ifdef CONFIG_TRACE_IRQFLAGS
412 mov.l 6f, r0
413 jsr @r0
414 nop
415#endif
358 ! 416 !
359 get_current_thread_info r8, r0 417 get_current_thread_info r8, r0
360 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags 418 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
@@ -369,3 +427,7 @@ syscall_exit:
3692: .long NR_syscalls 4272: .long NR_syscalls
3703: .long sys_call_table 4283: .long sys_call_table
3714: .long do_syscall_trace 4294: .long do_syscall_trace
430#ifdef CONFIG_TRACE_IRQFLAGS
4315: .long trace_hardirqs_on
4326: .long trace_hardirqs_off
433#endif
diff --git a/arch/sh/kernel/stacktrace.c b/arch/sh/kernel/stacktrace.c
new file mode 100644
index 000000000000..0d5268afe80f
--- /dev/null
+++ b/arch/sh/kernel/stacktrace.c
@@ -0,0 +1,43 @@
1/*
2 * arch/sh/kernel/stacktrace.c
3 *
4 * Stack trace management functions
5 *
6 * Copyright (C) 2006 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/sched.h>
13#include <linux/stacktrace.h>
14#include <linux/thread_info.h>
15#include <asm/ptrace.h>
16
17/*
18 * Save stack-backtrace addresses into a stack_trace buffer.
19 */
20void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
21{
22 unsigned long *sp;
23
24 if (!task)
25 task = current;
26 if (task == current)
27 sp = (unsigned long *)current_stack_pointer;
28 else
29 sp = (unsigned long *)task->thread.sp;
30
31 while (!kstack_end(sp)) {
32 unsigned long addr = *sp++;
33
34 if (__kernel_text_address(addr)) {
35 if (trace->skip > 0)
36 trace->skip--;
37 else
38 trace->entries[trace->nr_entries++] = addr;
39 if (trace->nr_entries >= trace->max_entries)
40 break;
41 }
42 }
43}
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index cfeefc10e254..716ebf568af2 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -37,6 +37,9 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
37 int si_code; 37 int si_code;
38 siginfo_t info; 38 siginfo_t info;
39 39
40 trace_hardirqs_on();
41 local_irq_enable();
42
40#ifdef CONFIG_SH_KGDB 43#ifdef CONFIG_SH_KGDB
41 if (kgdb_nofault && kgdb_bus_err_hook) 44 if (kgdb_nofault && kgdb_bus_err_hook)
42 kgdb_bus_err_hook(); 45 kgdb_bus_err_hook();
diff --git a/include/asm-sh/irqflags.h b/include/asm-sh/irqflags.h
new file mode 100644
index 000000000000..9dedc1b693e3
--- /dev/null
+++ b/include/asm-sh/irqflags.h
@@ -0,0 +1,123 @@
1#ifndef __ASM_SH_IRQFLAGS_H
2#define __ASM_SH_IRQFLAGS_H
3
4static inline void raw_local_irq_enable(void)
5{
6 unsigned long __dummy0, __dummy1;
7
8 __asm__ __volatile__ (
9 "stc sr, %0\n\t"
10 "and %1, %0\n\t"
11#ifdef CONFIG_CPU_HAS_SR_RB
12 "stc r6_bank, %1\n\t"
13 "or %1, %0\n\t"
14#endif
15 "ldc %0, sr\n\t"
16 : "=&r" (__dummy0), "=r" (__dummy1)
17 : "1" (~0x000000f0)
18 : "memory"
19 );
20}
21
22static inline void raw_local_irq_disable(void)
23{
24 unsigned long flags;
25
26 __asm__ __volatile__ (
27 "stc sr, %0\n\t"
28 "or #0xf0, %0\n\t"
29 "ldc %0, sr\n\t"
30 : "=&z" (flags)
31 : /* no inputs */
32 : "memory"
33 );
34}
35
36static inline void set_bl_bit(void)
37{
38 unsigned long __dummy0, __dummy1;
39
40 __asm__ __volatile__ (
41 "stc sr, %0\n\t"
42 "or %2, %0\n\t"
43 "and %3, %0\n\t"
44 "ldc %0, sr\n\t"
45 : "=&r" (__dummy0), "=r" (__dummy1)
46 : "r" (0x10000000), "r" (0xffffff0f)
47 : "memory"
48 );
49}
50
51static inline void clear_bl_bit(void)
52{
53 unsigned long __dummy0, __dummy1;
54
55 __asm__ __volatile__ (
56 "stc sr, %0\n\t"
57 "and %2, %0\n\t"
58 "ldc %0, sr\n\t"
59 : "=&r" (__dummy0), "=r" (__dummy1)
60 : "1" (~0x10000000)
61 : "memory"
62 );
63}
64
65static inline unsigned long __raw_local_save_flags(void)
66{
67 unsigned long flags;
68
69 __asm__ __volatile__ (
70 "stc sr, %0\n\t"
71 "and #0xf0, %0\n\t"
72 : "=&z" (flags)
73 : /* no inputs */
74 : "memory"
75 );
76
77 return flags;
78}
79
80#define raw_local_save_flags(flags) \
81 do { (flags) = __raw_local_save_flags(); } while (0)
82
83static inline int raw_irqs_disabled_flags(unsigned long flags)
84{
85 return (flags != 0);
86}
87
88static inline int raw_irqs_disabled(void)
89{
90 unsigned long flags = __raw_local_save_flags();
91
92 return raw_irqs_disabled_flags(flags);
93}
94
95static inline unsigned long __raw_local_irq_save(void)
96{
97 unsigned long flags, __dummy;
98
99 __asm__ __volatile__ (
100 "stc sr, %1\n\t"
101 "mov %1, %0\n\t"
102 "or #0xf0, %0\n\t"
103 "ldc %0, sr\n\t"
104 "mov %1, %0\n\t"
105 "and #0xf0, %0\n\t"
106 : "=&z" (flags), "=&r" (__dummy)
107 : /* no inputs */
108 : "memory"
109 );
110
111 return flags;
112}
113
114#define raw_local_irq_save(flags) \
115 do { (flags) = __raw_local_irq_save(); } while (0)
116
117static inline void raw_local_irq_restore(unsigned long flags)
118{
119 if ((flags & 0xf0) != 0xf0)
120 raw_local_irq_enable();
121}
122
123#endif /* __ASM_SH_IRQFLAGS_H */
diff --git a/include/asm-sh/rwsem.h b/include/asm-sh/rwsem.h
index 9d2aea5e8488..4931ba817d73 100644
--- a/include/asm-sh/rwsem.h
+++ b/include/asm-sh/rwsem.h
@@ -25,11 +25,21 @@ struct rw_semaphore {
25#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) 25#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
26 spinlock_t wait_lock; 26 spinlock_t wait_lock;
27 struct list_head wait_list; 27 struct list_head wait_list;
28#ifdef CONFIG_DEBUG_LOCK_ALLOC
29 struct lockdep_map dep_map;
30#endif
28}; 31};
29 32
33#ifdef CONFIG_DEBUG_LOCK_ALLOC
34# define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname }
35#else
36# define __RWSEM_DEP_MAP_INIT(lockname)
37#endif
38
30#define __RWSEM_INITIALIZER(name) \ 39#define __RWSEM_INITIALIZER(name) \
31 { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \ 40 { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
32 LIST_HEAD_INIT((name).wait_list) } 41 LIST_HEAD_INIT((name).wait_list) \
42 __RWSEM_DEP_MAP_INIT(name) }
33 43
34#define DECLARE_RWSEM(name) \ 44#define DECLARE_RWSEM(name) \
35 struct rw_semaphore name = __RWSEM_INITIALIZER(name) 45 struct rw_semaphore name = __RWSEM_INITIALIZER(name)
@@ -39,6 +49,16 @@ extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
39extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem); 49extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
40extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem); 50extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
41 51
52extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
53 struct lock_class_key *key);
54
55#define init_rwsem(sem) \
56do { \
57 static struct lock_class_key __key; \
58 \
59 __init_rwsem((sem), #sem, &__key); \
60} while (0)
61
42static inline void init_rwsem(struct rw_semaphore *sem) 62static inline void init_rwsem(struct rw_semaphore *sem)
43{ 63{
44 sem->count = RWSEM_UNLOCKED_VALUE; 64 sem->count = RWSEM_UNLOCKED_VALUE;
@@ -141,6 +161,11 @@ static inline void __downgrade_write(struct rw_semaphore *sem)
141 rwsem_downgrade_wake(sem); 161 rwsem_downgrade_wake(sem);
142} 162}
143 163
164static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
165{
166 __down_write(sem);
167}
168
144/* 169/*
145 * implement exchange and add functionality 170 * implement exchange and add functionality
146 */ 171 */
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h
index 3340126f4e0f..b1e42e7f998b 100644
--- a/include/asm-sh/system.h
+++ b/include/asm-sh/system.h
@@ -6,6 +6,7 @@
6 * Copyright (C) 2002 Paul Mundt 6 * Copyright (C) 2002 Paul Mundt
7 */ 7 */
8 8
9#include <linux/irqflags.h>
9#include <asm/types.h> 10#include <asm/types.h>
10 11
11/* 12/*
@@ -131,103 +132,6 @@ static inline unsigned long tas(volatile int *m)
131 132
132#define set_mb(var, value) do { xchg(&var, value); } while (0) 133#define set_mb(var, value) do { xchg(&var, value); } while (0)
133 134
134/* Interrupt Control */
135#ifdef CONFIG_CPU_HAS_SR_RB
136static inline void local_irq_enable(void)
137{
138 unsigned long __dummy0, __dummy1;
139
140 __asm__ __volatile__("stc sr, %0\n\t"
141 "and %1, %0\n\t"
142 "stc r6_bank, %1\n\t"
143 "or %1, %0\n\t"
144 "ldc %0, sr"
145 : "=&r" (__dummy0), "=r" (__dummy1)
146 : "1" (~0x000000f0)
147 : "memory");
148}
149#else
150static inline void local_irq_enable(void)
151{
152 unsigned long __dummy0, __dummy1;
153
154 __asm__ __volatile__ (
155 "stc sr, %0\n\t"
156 "and %1, %0\n\t"
157 "ldc %0, sr\n\t"
158 : "=&r" (__dummy0), "=r" (__dummy1)
159 : "1" (~0x000000f0)
160 : "memory");
161}
162#endif
163
164static inline void local_irq_disable(void)
165{
166 unsigned long __dummy;
167 __asm__ __volatile__("stc sr, %0\n\t"
168 "or #0xf0, %0\n\t"
169 "ldc %0, sr"
170 : "=&z" (__dummy)
171 : /* no inputs */
172 : "memory");
173}
174
175static inline void set_bl_bit(void)
176{
177 unsigned long __dummy0, __dummy1;
178
179 __asm__ __volatile__ ("stc sr, %0\n\t"
180 "or %2, %0\n\t"
181 "and %3, %0\n\t"
182 "ldc %0, sr"
183 : "=&r" (__dummy0), "=r" (__dummy1)
184 : "r" (0x10000000), "r" (0xffffff0f)
185 : "memory");
186}
187
188static inline void clear_bl_bit(void)
189{
190 unsigned long __dummy0, __dummy1;
191
192 __asm__ __volatile__ ("stc sr, %0\n\t"
193 "and %2, %0\n\t"
194 "ldc %0, sr"
195 : "=&r" (__dummy0), "=r" (__dummy1)
196 : "1" (~0x10000000)
197 : "memory");
198}
199
200#define local_save_flags(x) \
201 __asm__("stc sr, %0; and #0xf0, %0" : "=&z" (x) :/**/: "memory" )
202
203#define irqs_disabled() \
204({ \
205 unsigned long flags; \
206 local_save_flags(flags); \
207 (flags != 0); \
208})
209
210static inline unsigned long local_irq_save(void)
211{
212 unsigned long flags, __dummy;
213
214 __asm__ __volatile__("stc sr, %1\n\t"
215 "mov %1, %0\n\t"
216 "or #0xf0, %0\n\t"
217 "ldc %0, sr\n\t"
218 "mov %1, %0\n\t"
219 "and #0xf0, %0"
220 : "=&z" (flags), "=&r" (__dummy)
221 :/**/
222 : "memory" );
223 return flags;
224}
225
226#define local_irq_restore(x) do { \
227 if ((x & 0x000000f0) != 0x000000f0) \
228 local_irq_enable(); \
229} while (0)
230
231/* 135/*
232 * Jump to P2 area. 136 * Jump to P2 area.
233 * When handling TLB or caches, we need to do it from P2 area. 137 * When handling TLB or caches, we need to do it from P2 area.
@@ -264,9 +168,6 @@ do { \
264 : "=&r" (__dummy)); \ 168 : "=&r" (__dummy)); \
265} while (0) 169} while (0)
266 170
267/* For spinlocks etc */
268#define local_irq_save(x) x = local_irq_save()
269
270static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val) 171static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val)
271{ 172{
272 unsigned long flags, retval; 173 unsigned long flags, retval;