xref: /linux/arch/arm/include/asm/irqflags.h (revision 005438a8eef063495ac059d128eea71b58de50e5)
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 #else
58 
59 /*
60  * Save the current interrupt enable state & disable IRQs
61  */
62 #define arch_local_irq_save arch_local_irq_save
63 static inline unsigned long arch_local_irq_save(void)
64 {
65 	unsigned long flags, temp;
66 
67 	asm volatile(
68 		"	mrs	%0, cpsr	@ arch_local_irq_save\n"
69 		"	orr	%1, %0, #128\n"
70 		"	msr	cpsr_c, %1"
71 		: "=r" (flags), "=r" (temp)
72 		:
73 		: "memory", "cc");
74 	return flags;
75 }
76 
77 /*
78  * Enable IRQs
79  */
80 #define arch_local_irq_enable arch_local_irq_enable
81 static inline void arch_local_irq_enable(void)
82 {
83 	unsigned long temp;
84 	asm volatile(
85 		"	mrs	%0, cpsr	@ arch_local_irq_enable\n"
86 		"	bic	%0, %0, #128\n"
87 		"	msr	cpsr_c, %0"
88 		: "=r" (temp)
89 		:
90 		: "memory", "cc");
91 }
92 
93 /*
94  * Disable IRQs
95  */
96 #define arch_local_irq_disable arch_local_irq_disable
97 static inline void arch_local_irq_disable(void)
98 {
99 	unsigned long temp;
100 	asm volatile(
101 		"	mrs	%0, cpsr	@ arch_local_irq_disable\n"
102 		"	orr	%0, %0, #128\n"
103 		"	msr	cpsr_c, %0"
104 		: "=r" (temp)
105 		:
106 		: "memory", "cc");
107 }
108 
109 /*
110  * Enable FIQs
111  */
112 #define local_fiq_enable()					\
113 	({							\
114 		unsigned long temp;				\
115 	__asm__ __volatile__(					\
116 	"mrs	%0, cpsr		@ stf\n"		\
117 "	bic	%0, %0, #64\n"					\
118 "	msr	cpsr_c, %0"					\
119 	: "=r" (temp)						\
120 	:							\
121 	: "memory", "cc");					\
122 	})
123 
124 /*
125  * Disable FIQs
126  */
127 #define local_fiq_disable()					\
128 	({							\
129 		unsigned long temp;				\
130 	__asm__ __volatile__(					\
131 	"mrs	%0, cpsr		@ clf\n"		\
132 "	orr	%0, %0, #64\n"					\
133 "	msr	cpsr_c, %0"					\
134 	: "=r" (temp)						\
135 	:							\
136 	: "memory", "cc");					\
137 	})
138 
139 #endif
140 
141 /*
142  * Save the current interrupt enable state.
143  */
144 #define arch_local_save_flags arch_local_save_flags
145 static inline unsigned long arch_local_save_flags(void)
146 {
147 	unsigned long flags;
148 	asm volatile(
149 		"	mrs	%0, " IRQMASK_REG_NAME_R "	@ local_save_flags"
150 		: "=r" (flags) : : "memory", "cc");
151 	return flags;
152 }
153 
154 /*
155  * restore saved IRQ & FIQ state
156  */
157 #define arch_local_irq_restore arch_local_irq_restore
158 static inline void arch_local_irq_restore(unsigned long flags)
159 {
160 	asm volatile(
161 		"	msr	" IRQMASK_REG_NAME_W ", %0	@ local_irq_restore"
162 		:
163 		: "r" (flags)
164 		: "memory", "cc");
165 }
166 
167 #define arch_irqs_disabled_flags arch_irqs_disabled_flags
168 static inline int arch_irqs_disabled_flags(unsigned long flags)
169 {
170 	return flags & IRQMASK_I_BIT;
171 }
172 
173 #include <asm-generic/irqflags.h>
174 
175 #endif /* ifdef __KERNEL__ */
176 #endif /* ifndef __ASM_ARM_IRQFLAGS_H */
177