xref: /linux/arch/arm/include/asm/irqflags.h (revision 55bdd694116597d2f16510b121463cd579ba78da)
14baa9922SRussell King #ifndef __ASM_ARM_IRQFLAGS_H
24baa9922SRussell King #define __ASM_ARM_IRQFLAGS_H
34baa9922SRussell King 
44baa9922SRussell King #ifdef __KERNEL__
54baa9922SRussell King 
64baa9922SRussell King #include <asm/ptrace.h>
74baa9922SRussell King 
84baa9922SRussell King /*
94baa9922SRussell King  * CPU interrupt mask handling.
104baa9922SRussell King  */
11*55bdd694SCatalin Marinas #ifdef CONFIG_CPU_V7M
12*55bdd694SCatalin Marinas #define IRQMASK_REG_NAME_R "primask"
13*55bdd694SCatalin Marinas #define IRQMASK_REG_NAME_W "primask"
14*55bdd694SCatalin Marinas #define IRQMASK_I_BIT	1
15*55bdd694SCatalin Marinas #else
16*55bdd694SCatalin Marinas #define IRQMASK_REG_NAME_R "cpsr"
17*55bdd694SCatalin Marinas #define IRQMASK_REG_NAME_W "cpsr_c"
18*55bdd694SCatalin Marinas #define IRQMASK_I_BIT	PSR_I_BIT
19*55bdd694SCatalin Marinas #endif
20*55bdd694SCatalin Marinas 
214baa9922SRussell King #if __LINUX_ARM_ARCH__ >= 6
224baa9922SRussell King 
23df9ee292SDavid Howells static inline unsigned long arch_local_irq_save(void)
24df9ee292SDavid Howells {
25df9ee292SDavid Howells 	unsigned long flags;
264baa9922SRussell King 
27df9ee292SDavid Howells 	asm volatile(
28*55bdd694SCatalin Marinas 		"	mrs	%0, " IRQMASK_REG_NAME_R "	@ arch_local_irq_save\n"
29df9ee292SDavid Howells 		"	cpsid	i"
30df9ee292SDavid Howells 		: "=r" (flags) : : "memory", "cc");
31df9ee292SDavid Howells 	return flags;
32df9ee292SDavid Howells }
33df9ee292SDavid Howells 
34df9ee292SDavid Howells static inline void arch_local_irq_enable(void)
35df9ee292SDavid Howells {
36df9ee292SDavid Howells 	asm volatile(
37df9ee292SDavid Howells 		"	cpsie i			@ arch_local_irq_enable"
38df9ee292SDavid Howells 		:
39df9ee292SDavid Howells 		:
40df9ee292SDavid Howells 		: "memory", "cc");
41df9ee292SDavid Howells }
42df9ee292SDavid Howells 
43df9ee292SDavid Howells static inline void arch_local_irq_disable(void)
44df9ee292SDavid Howells {
45df9ee292SDavid Howells 	asm volatile(
46df9ee292SDavid Howells 		"	cpsid i			@ arch_local_irq_disable"
47df9ee292SDavid Howells 		:
48df9ee292SDavid Howells 		:
49df9ee292SDavid Howells 		: "memory", "cc");
50df9ee292SDavid Howells }
51df9ee292SDavid Howells 
524baa9922SRussell King #define local_fiq_enable()  __asm__("cpsie f	@ __stf" : : : "memory", "cc")
534baa9922SRussell King #define local_fiq_disable() __asm__("cpsid f	@ __clf" : : : "memory", "cc")
544baa9922SRussell King #else
554baa9922SRussell King 
564baa9922SRussell King /*
574baa9922SRussell King  * Save the current interrupt enable state & disable IRQs
584baa9922SRussell King  */
59df9ee292SDavid Howells static inline unsigned long arch_local_irq_save(void)
60df9ee292SDavid Howells {
61df9ee292SDavid Howells 	unsigned long flags, temp;
62df9ee292SDavid Howells 
63df9ee292SDavid Howells 	asm volatile(
64df9ee292SDavid Howells 		"	mrs	%0, cpsr	@ arch_local_irq_save\n"
65df9ee292SDavid Howells 		"	orr	%1, %0, #128\n"
66df9ee292SDavid Howells 		"	msr	cpsr_c, %1"
67df9ee292SDavid Howells 		: "=r" (flags), "=r" (temp)
68df9ee292SDavid Howells 		:
69df9ee292SDavid Howells 		: "memory", "cc");
70df9ee292SDavid Howells 	return flags;
71df9ee292SDavid Howells }
724baa9922SRussell King 
734baa9922SRussell King /*
744baa9922SRussell King  * Enable IRQs
754baa9922SRussell King  */
76df9ee292SDavid Howells static inline void arch_local_irq_enable(void)
77df9ee292SDavid Howells {
78df9ee292SDavid Howells 	unsigned long temp;
79df9ee292SDavid Howells 	asm volatile(
80df9ee292SDavid Howells 		"	mrs	%0, cpsr	@ arch_local_irq_enable\n"
81df9ee292SDavid Howells 		"	bic	%0, %0, #128\n"
82df9ee292SDavid Howells 		"	msr	cpsr_c, %0"
83df9ee292SDavid Howells 		: "=r" (temp)
84df9ee292SDavid Howells 		:
85df9ee292SDavid Howells 		: "memory", "cc");
86df9ee292SDavid Howells }
874baa9922SRussell King 
884baa9922SRussell King /*
894baa9922SRussell King  * Disable IRQs
904baa9922SRussell King  */
91df9ee292SDavid Howells static inline void arch_local_irq_disable(void)
92df9ee292SDavid Howells {
93df9ee292SDavid Howells 	unsigned long temp;
94df9ee292SDavid Howells 	asm volatile(
95df9ee292SDavid Howells 		"	mrs	%0, cpsr	@ arch_local_irq_disable\n"
96df9ee292SDavid Howells 		"	orr	%0, %0, #128\n"
97df9ee292SDavid Howells 		"	msr	cpsr_c, %0"
98df9ee292SDavid Howells 		: "=r" (temp)
99df9ee292SDavid Howells 		:
100df9ee292SDavid Howells 		: "memory", "cc");
101df9ee292SDavid Howells }
1024baa9922SRussell King 
1034baa9922SRussell King /*
1044baa9922SRussell King  * Enable FIQs
1054baa9922SRussell King  */
1064baa9922SRussell King #define local_fiq_enable()					\
1074baa9922SRussell King 	({							\
1084baa9922SRussell King 		unsigned long temp;				\
1094baa9922SRussell King 	__asm__ __volatile__(					\
1104baa9922SRussell King 	"mrs	%0, cpsr		@ stf\n"		\
1114baa9922SRussell King "	bic	%0, %0, #64\n"					\
1124baa9922SRussell King "	msr	cpsr_c, %0"					\
1134baa9922SRussell King 	: "=r" (temp)						\
1144baa9922SRussell King 	:							\
1154baa9922SRussell King 	: "memory", "cc");					\
1164baa9922SRussell King 	})
1174baa9922SRussell King 
1184baa9922SRussell King /*
1194baa9922SRussell King  * Disable FIQs
1204baa9922SRussell King  */
1214baa9922SRussell King #define local_fiq_disable()					\
1224baa9922SRussell King 	({							\
1234baa9922SRussell King 		unsigned long temp;				\
1244baa9922SRussell King 	__asm__ __volatile__(					\
1254baa9922SRussell King 	"mrs	%0, cpsr		@ clf\n"		\
1264baa9922SRussell King "	orr	%0, %0, #64\n"					\
1274baa9922SRussell King "	msr	cpsr_c, %0"					\
1284baa9922SRussell King 	: "=r" (temp)						\
1294baa9922SRussell King 	:							\
1304baa9922SRussell King 	: "memory", "cc");					\
1314baa9922SRussell King 	})
1324baa9922SRussell King 
1334baa9922SRussell King #endif
1344baa9922SRussell King 
1354baa9922SRussell King /*
1364baa9922SRussell King  * Save the current interrupt enable state.
1374baa9922SRussell King  */
138df9ee292SDavid Howells static inline unsigned long arch_local_save_flags(void)
139df9ee292SDavid Howells {
140df9ee292SDavid Howells 	unsigned long flags;
141df9ee292SDavid Howells 	asm volatile(
142*55bdd694SCatalin Marinas 		"	mrs	%0, " IRQMASK_REG_NAME_R "	@ local_save_flags"
143df9ee292SDavid Howells 		: "=r" (flags) : : "memory", "cc");
144df9ee292SDavid Howells 	return flags;
145df9ee292SDavid Howells }
1464baa9922SRussell King 
1474baa9922SRussell King /*
1484baa9922SRussell King  * restore saved IRQ & FIQ state
1494baa9922SRussell King  */
150df9ee292SDavid Howells static inline void arch_local_irq_restore(unsigned long flags)
151df9ee292SDavid Howells {
152df9ee292SDavid Howells 	asm volatile(
153*55bdd694SCatalin Marinas 		"	msr	" IRQMASK_REG_NAME_W ", %0	@ local_irq_restore"
154df9ee292SDavid Howells 		:
155df9ee292SDavid Howells 		: "r" (flags)
156df9ee292SDavid Howells 		: "memory", "cc");
157df9ee292SDavid Howells }
1584baa9922SRussell King 
159df9ee292SDavid Howells static inline int arch_irqs_disabled_flags(unsigned long flags)
160df9ee292SDavid Howells {
161*55bdd694SCatalin Marinas 	return flags & IRQMASK_I_BIT;
162df9ee292SDavid Howells }
1634baa9922SRussell King 
164*55bdd694SCatalin Marinas #endif /* ifdef __KERNEL__ */
165*55bdd694SCatalin Marinas #endif /* ifndef __ASM_ARM_IRQFLAGS_H */
166