xref: /linux/arch/arm/include/asm/irqflags.h (revision 20b4755e4fbb226eb42951bd40b53fcbce9ef944)
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 static inline unsigned long arch_local_irq_save(void)
14 {
15 	unsigned long flags;
16 
17 	asm volatile(
18 		"	mrs	%0, cpsr	@ arch_local_irq_save\n"
19 		"	cpsid	i"
20 		: "=r" (flags) : : "memory", "cc");
21 	return flags;
22 }
23 
24 static inline void arch_local_irq_enable(void)
25 {
26 	asm volatile(
27 		"	cpsie i			@ arch_local_irq_enable"
28 		:
29 		:
30 		: "memory", "cc");
31 }
32 
33 static inline void arch_local_irq_disable(void)
34 {
35 	asm volatile(
36 		"	cpsid i			@ arch_local_irq_disable"
37 		:
38 		:
39 		: "memory", "cc");
40 }
41 
42 #define local_fiq_enable()  __asm__("cpsie f	@ __stf" : : : "memory", "cc")
43 #define local_fiq_disable() __asm__("cpsid f	@ __clf" : : : "memory", "cc")
44 #else
45 
46 /*
47  * Save the current interrupt enable state & disable IRQs
48  */
49 static inline unsigned long arch_local_irq_save(void)
50 {
51 	unsigned long flags, temp;
52 
53 	asm volatile(
54 		"	mrs	%0, cpsr	@ arch_local_irq_save\n"
55 		"	orr	%1, %0, #128\n"
56 		"	msr	cpsr_c, %1"
57 		: "=r" (flags), "=r" (temp)
58 		:
59 		: "memory", "cc");
60 	return flags;
61 }
62 
63 /*
64  * Enable IRQs
65  */
66 static inline void arch_local_irq_enable(void)
67 {
68 	unsigned long temp;
69 	asm volatile(
70 		"	mrs	%0, cpsr	@ arch_local_irq_enable\n"
71 		"	bic	%0, %0, #128\n"
72 		"	msr	cpsr_c, %0"
73 		: "=r" (temp)
74 		:
75 		: "memory", "cc");
76 }
77 
78 /*
79  * Disable IRQs
80  */
81 static inline void arch_local_irq_disable(void)
82 {
83 	unsigned long temp;
84 	asm volatile(
85 		"	mrs	%0, cpsr	@ arch_local_irq_disable\n"
86 		"	orr	%0, %0, #128\n"
87 		"	msr	cpsr_c, %0"
88 		: "=r" (temp)
89 		:
90 		: "memory", "cc");
91 }
92 
93 /*
94  * Enable FIQs
95  */
96 #define local_fiq_enable()					\
97 	({							\
98 		unsigned long temp;				\
99 	__asm__ __volatile__(					\
100 	"mrs	%0, cpsr		@ stf\n"		\
101 "	bic	%0, %0, #64\n"					\
102 "	msr	cpsr_c, %0"					\
103 	: "=r" (temp)						\
104 	:							\
105 	: "memory", "cc");					\
106 	})
107 
108 /*
109  * Disable FIQs
110  */
111 #define local_fiq_disable()					\
112 	({							\
113 		unsigned long temp;				\
114 	__asm__ __volatile__(					\
115 	"mrs	%0, cpsr		@ clf\n"		\
116 "	orr	%0, %0, #64\n"					\
117 "	msr	cpsr_c, %0"					\
118 	: "=r" (temp)						\
119 	:							\
120 	: "memory", "cc");					\
121 	})
122 
123 #endif
124 
125 /*
126  * Save the current interrupt enable state.
127  */
128 static inline unsigned long arch_local_save_flags(void)
129 {
130 	unsigned long flags;
131 	asm volatile(
132 		"	mrs	%0, cpsr	@ local_save_flags"
133 		: "=r" (flags) : : "memory", "cc");
134 	return flags;
135 }
136 
137 /*
138  * restore saved IRQ & FIQ state
139  */
140 static inline void arch_local_irq_restore(unsigned long flags)
141 {
142 	asm volatile(
143 		"	msr	cpsr_c, %0	@ local_irq_restore"
144 		:
145 		: "r" (flags)
146 		: "memory", "cc");
147 }
148 
149 static inline int arch_irqs_disabled_flags(unsigned long flags)
150 {
151 	return flags & PSR_I_BIT;
152 }
153 
154 #endif
155 #endif
156