aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/kernel/entry-armv.S13
-rw-r--r--include/asm-arm/irqflags.h132
-rw-r--r--include/asm-arm/system.h125
4 files changed, 150 insertions, 124 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f81a62380add..d9376f048ed7 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -51,6 +51,10 @@ config GENERIC_HARDIRQS
51 bool 51 bool
52 default y 52 default y
53 53
54config TRACE_IRQFLAGS_SUPPORT
55 bool
56 default y
57
54config HARDIRQS_SW_RESEND 58config HARDIRQS_SW_RESEND
55 bool 59 bool
56 default y 60 default y
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index de4e33137901..bd623b73445f 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -191,6 +191,9 @@ __dabt_svc:
191__irq_svc: 191__irq_svc:
192 svc_entry 192 svc_entry
193 193
194#ifdef CONFIG_TRACE_IRQFLAGS
195 bl trace_hardirqs_off
196#endif
194#ifdef CONFIG_PREEMPT 197#ifdef CONFIG_PREEMPT
195 get_thread_info tsk 198 get_thread_info tsk
196 ldr r8, [tsk, #TI_PREEMPT] @ get preempt count 199 ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
@@ -211,6 +214,10 @@ preempt_return:
211#endif 214#endif
212 ldr r0, [sp, #S_PSR] @ irqs are already disabled 215 ldr r0, [sp, #S_PSR] @ irqs are already disabled
213 msr spsr_cxsf, r0 216 msr spsr_cxsf, r0
217#ifdef CONFIG_TRACE_IRQFLAGS
218 tst r0, #PSR_I_BIT
219 bleq trace_hardirqs_on
220#endif
214 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr 221 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
215 222
216 .ltorg 223 .ltorg
@@ -398,6 +405,9 @@ __dabt_usr:
398__irq_usr: 405__irq_usr:
399 usr_entry 406 usr_entry
400 407
408#ifdef CONFIG_TRACE_IRQFLAGS
409 bl trace_hardirqs_off
410#endif
401 get_thread_info tsk 411 get_thread_info tsk
402#ifdef CONFIG_PREEMPT 412#ifdef CONFIG_PREEMPT
403 ldr r8, [tsk, #TI_PREEMPT] @ get preempt count 413 ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
@@ -412,6 +422,9 @@ __irq_usr:
412 teq r0, r7 422 teq r0, r7
413 strne r0, [r0, -r0] 423 strne r0, [r0, -r0]
414#endif 424#endif
425#ifdef CONFIG_TRACE_IRQFLAGS
426 bl trace_hardirqs_on
427#endif
415 428
416 mov why, #0 429 mov why, #0
417 b ret_to_user 430 b ret_to_user
diff --git a/include/asm-arm/irqflags.h b/include/asm-arm/irqflags.h
new file mode 100644
index 000000000000..6d09974e6646
--- /dev/null
+++ b/include/asm-arm/irqflags.h
@@ -0,0 +1,132 @@
1#ifndef __ASM_ARM_IRQFLAGS_H
2#define __ASM_ARM_IRQFLAGS_H
3
4#ifdef __KERNEL__
5
6#include <asm/ptrace.h>
7
8/*
9 * CPU interrupt mask handling.
10 */
11#if __LINUX_ARM_ARCH__ >= 6
12
13#define raw_local_irq_save(x) \
14 ({ \
15 __asm__ __volatile__( \
16 "mrs %0, cpsr @ local_irq_save\n" \
17 "cpsid i" \
18 : "=r" (x) : : "memory", "cc"); \
19 })
20
21#define raw_local_irq_enable() __asm__("cpsie i @ __sti" : : : "memory", "cc")
22#define raw_local_irq_disable() __asm__("cpsid i @ __cli" : : : "memory", "cc")
23#define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc")
24#define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc")
25
26#else
27
28/*
29 * Save the current interrupt enable state & disable IRQs
30 */
31#define raw_local_irq_save(x) \
32 ({ \
33 unsigned long temp; \
34 (void) (&temp == &x); \
35 __asm__ __volatile__( \
36 "mrs %0, cpsr @ local_irq_save\n" \
37" orr %1, %0, #128\n" \
38" msr cpsr_c, %1" \
39 : "=r" (x), "=r" (temp) \
40 : \
41 : "memory", "cc"); \
42 })
43
44/*
45 * Enable IRQs
46 */
47#define raw_local_irq_enable() \
48 ({ \
49 unsigned long temp; \
50 __asm__ __volatile__( \
51 "mrs %0, cpsr @ local_irq_enable\n" \
52" bic %0, %0, #128\n" \
53" msr cpsr_c, %0" \
54 : "=r" (temp) \
55 : \
56 : "memory", "cc"); \
57 })
58
59/*
60 * Disable IRQs
61 */
62#define raw_local_irq_disable() \
63 ({ \
64 unsigned long temp; \
65 __asm__ __volatile__( \
66 "mrs %0, cpsr @ local_irq_disable\n" \
67" orr %0, %0, #128\n" \
68" msr cpsr_c, %0" \
69 : "=r" (temp) \
70 : \
71 : "memory", "cc"); \
72 })
73
74/*
75 * Enable FIQs
76 */
77#define local_fiq_enable() \
78 ({ \
79 unsigned long temp; \
80 __asm__ __volatile__( \
81 "mrs %0, cpsr @ stf\n" \
82" bic %0, %0, #64\n" \
83" msr cpsr_c, %0" \
84 : "=r" (temp) \
85 : \
86 : "memory", "cc"); \
87 })
88
89/*
90 * Disable FIQs
91 */
92#define local_fiq_disable() \
93 ({ \
94 unsigned long temp; \
95 __asm__ __volatile__( \
96 "mrs %0, cpsr @ clf\n" \
97" orr %0, %0, #64\n" \
98" msr cpsr_c, %0" \
99 : "=r" (temp) \
100 : \
101 : "memory", "cc"); \
102 })
103
104#endif
105
106/*
107 * Save the current interrupt enable state.
108 */
109#define raw_local_save_flags(x) \
110 ({ \
111 __asm__ __volatile__( \
112 "mrs %0, cpsr @ local_save_flags" \
113 : "=r" (x) : : "memory", "cc"); \
114 })
115
116/*
117 * restore saved IRQ & FIQ state
118 */
119#define raw_local_irq_restore(x) \
120 __asm__ __volatile__( \
121 "msr cpsr_c, %0 @ local_irq_restore\n" \
122 : \
123 : "r" (x) \
124 : "memory", "cc")
125
126#define raw_irqs_disabled_flags(flags) \
127({ \
128 (int)((flags) & PSR_I_BIT); \
129})
130
131#endif
132#endif
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index 0947cbf9b69a..174ff52661b0 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -207,130 +207,7 @@ static inline void sched_cacheflush(void)
207{ 207{
208} 208}
209 209
210/* 210#include <linux/irqflags.h>
211 * CPU interrupt mask handling.
212 */
213#if __LINUX_ARM_ARCH__ >= 6
214
215#define local_irq_save(x) \
216 ({ \
217 __asm__ __volatile__( \
218 "mrs %0, cpsr @ local_irq_save\n" \
219 "cpsid i" \
220 : "=r" (x) : : "memory", "cc"); \
221 })
222
223#define local_irq_enable() __asm__("cpsie i @ __sti" : : : "memory", "cc")
224#define local_irq_disable() __asm__("cpsid i @ __cli" : : : "memory", "cc")
225#define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc")
226#define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc")
227
228#else
229
230/*
231 * Save the current interrupt enable state & disable IRQs
232 */
233#define local_irq_save(x) \
234 ({ \
235 unsigned long temp; \
236 (void) (&temp == &x); \
237 __asm__ __volatile__( \
238 "mrs %0, cpsr @ local_irq_save\n" \
239" orr %1, %0, #128\n" \
240" msr cpsr_c, %1" \
241 : "=r" (x), "=r" (temp) \
242 : \
243 : "memory", "cc"); \
244 })
245
246/*
247 * Enable IRQs
248 */
249#define local_irq_enable() \
250 ({ \
251 unsigned long temp; \
252 __asm__ __volatile__( \
253 "mrs %0, cpsr @ local_irq_enable\n" \
254" bic %0, %0, #128\n" \
255" msr cpsr_c, %0" \
256 : "=r" (temp) \
257 : \
258 : "memory", "cc"); \
259 })
260
261/*
262 * Disable IRQs
263 */
264#define local_irq_disable() \
265 ({ \
266 unsigned long temp; \
267 __asm__ __volatile__( \
268 "mrs %0, cpsr @ local_irq_disable\n" \
269" orr %0, %0, #128\n" \
270" msr cpsr_c, %0" \
271 : "=r" (temp) \
272 : \
273 : "memory", "cc"); \
274 })
275
276/*
277 * Enable FIQs
278 */
279#define local_fiq_enable() \
280 ({ \
281 unsigned long temp; \
282 __asm__ __volatile__( \
283 "mrs %0, cpsr @ stf\n" \
284" bic %0, %0, #64\n" \
285" msr cpsr_c, %0" \
286 : "=r" (temp) \
287 : \
288 : "memory", "cc"); \
289 })
290
291/*
292 * Disable FIQs
293 */
294#define local_fiq_disable() \
295 ({ \
296 unsigned long temp; \
297 __asm__ __volatile__( \
298 "mrs %0, cpsr @ clf\n" \
299" orr %0, %0, #64\n" \
300" msr cpsr_c, %0" \
301 : "=r" (temp) \
302 : \
303 : "memory", "cc"); \
304 })
305
306#endif
307
308/*
309 * Save the current interrupt enable state.
310 */
311#define local_save_flags(x) \
312 ({ \
313 __asm__ __volatile__( \
314 "mrs %0, cpsr @ local_save_flags" \
315 : "=r" (x) : : "memory", "cc"); \
316 })
317
318/*
319 * restore saved IRQ & FIQ state
320 */
321#define local_irq_restore(x) \
322 __asm__ __volatile__( \
323 "msr cpsr_c, %0 @ local_irq_restore\n" \
324 : \
325 : "r" (x) \
326 : "memory", "cc")
327
328#define irqs_disabled() \
329({ \
330 unsigned long flags; \
331 local_save_flags(flags); \
332 (int)(flags & PSR_I_BIT); \
333})
334 211
335#ifdef CONFIG_SMP 212#ifdef CONFIG_SMP
336 213