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