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