xref: /linux/arch/arm/include/asm/irqflags.h (revision 498495dba268b20e8eadd7fe93c140c68b6cc9d2)
1*b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
24baa9922SRussell King #ifndef __ASM_ARM_IRQFLAGS_H
34baa9922SRussell King #define __ASM_ARM_IRQFLAGS_H
44baa9922SRussell King 
54baa9922SRussell King #ifdef __KERNEL__
64baa9922SRussell King 
74baa9922SRussell King #include <asm/ptrace.h>
84baa9922SRussell King 
94baa9922SRussell King /*
104baa9922SRussell King  * CPU interrupt mask handling.
114baa9922SRussell King  */
1255bdd694SCatalin Marinas #ifdef CONFIG_CPU_V7M
1355bdd694SCatalin Marinas #define IRQMASK_REG_NAME_R "primask"
1455bdd694SCatalin Marinas #define IRQMASK_REG_NAME_W "primask"
1555bdd694SCatalin Marinas #define IRQMASK_I_BIT	1
1655bdd694SCatalin Marinas #else
1755bdd694SCatalin Marinas #define IRQMASK_REG_NAME_R "cpsr"
1855bdd694SCatalin Marinas #define IRQMASK_REG_NAME_W "cpsr_c"
1955bdd694SCatalin Marinas #define IRQMASK_I_BIT	PSR_I_BIT
2055bdd694SCatalin Marinas #endif
2155bdd694SCatalin Marinas 
224baa9922SRussell King #if __LINUX_ARM_ARCH__ >= 6
234baa9922SRussell King 
246fb18ac9SDaniel Thompson #define arch_local_irq_save arch_local_irq_save
arch_local_irq_save(void)25df9ee292SDavid Howells static inline unsigned long arch_local_irq_save(void)
26df9ee292SDavid Howells {
27df9ee292SDavid Howells 	unsigned long flags;
284baa9922SRussell King 
29df9ee292SDavid Howells 	asm volatile(
3055bdd694SCatalin Marinas 		"	mrs	%0, " IRQMASK_REG_NAME_R "	@ arch_local_irq_save\n"
31df9ee292SDavid Howells 		"	cpsid	i"
32df9ee292SDavid Howells 		: "=r" (flags) : : "memory", "cc");
33df9ee292SDavid Howells 	return flags;
34df9ee292SDavid Howells }
35df9ee292SDavid Howells 
366fb18ac9SDaniel Thompson #define arch_local_irq_enable arch_local_irq_enable
arch_local_irq_enable(void)37df9ee292SDavid Howells static inline void arch_local_irq_enable(void)
38df9ee292SDavid Howells {
39df9ee292SDavid Howells 	asm volatile(
40df9ee292SDavid Howells 		"	cpsie i			@ arch_local_irq_enable"
41df9ee292SDavid Howells 		:
42df9ee292SDavid Howells 		:
43df9ee292SDavid Howells 		: "memory", "cc");
44df9ee292SDavid Howells }
45df9ee292SDavid Howells 
466fb18ac9SDaniel Thompson #define arch_local_irq_disable arch_local_irq_disable
arch_local_irq_disable(void)47df9ee292SDavid Howells static inline void arch_local_irq_disable(void)
48df9ee292SDavid Howells {
49df9ee292SDavid Howells 	asm volatile(
50df9ee292SDavid Howells 		"	cpsid i			@ arch_local_irq_disable"
51df9ee292SDavid Howells 		:
52df9ee292SDavid Howells 		:
53df9ee292SDavid Howells 		: "memory", "cc");
54df9ee292SDavid Howells }
55df9ee292SDavid Howells 
564baa9922SRussell King #define local_fiq_enable()  __asm__("cpsie f	@ __stf" : : : "memory", "cc")
574baa9922SRussell King #define local_fiq_disable() __asm__("cpsid f	@ __clf" : : : "memory", "cc")
58bbeb9209SLucas Stach 
59bbeb9209SLucas Stach #ifndef CONFIG_CPU_V7M
60bbeb9209SLucas Stach #define local_abt_enable()  __asm__("cpsie a	@ __sta" : : : "memory", "cc")
61bbeb9209SLucas Stach #define local_abt_disable() __asm__("cpsid a	@ __cla" : : : "memory", "cc")
62bbeb9209SLucas Stach #else
63bbeb9209SLucas Stach #define local_abt_enable()	do { } while (0)
64bbeb9209SLucas Stach #define local_abt_disable()	do { } while (0)
65bbeb9209SLucas Stach #endif
664baa9922SRussell King #else
674baa9922SRussell King 
684baa9922SRussell King /*
694baa9922SRussell King  * Save the current interrupt enable state & disable IRQs
704baa9922SRussell King  */
716fb18ac9SDaniel Thompson #define arch_local_irq_save arch_local_irq_save
arch_local_irq_save(void)72df9ee292SDavid Howells static inline unsigned long arch_local_irq_save(void)
73df9ee292SDavid Howells {
74df9ee292SDavid Howells 	unsigned long flags, temp;
75df9ee292SDavid Howells 
76df9ee292SDavid Howells 	asm volatile(
77df9ee292SDavid Howells 		"	mrs	%0, cpsr	@ arch_local_irq_save\n"
78df9ee292SDavid Howells 		"	orr	%1, %0, #128\n"
79df9ee292SDavid Howells 		"	msr	cpsr_c, %1"
80df9ee292SDavid Howells 		: "=r" (flags), "=r" (temp)
81df9ee292SDavid Howells 		:
82df9ee292SDavid Howells 		: "memory", "cc");
83df9ee292SDavid Howells 	return flags;
84df9ee292SDavid Howells }
854baa9922SRussell King 
864baa9922SRussell King /*
874baa9922SRussell King  * Enable IRQs
884baa9922SRussell King  */
896fb18ac9SDaniel Thompson #define arch_local_irq_enable arch_local_irq_enable
arch_local_irq_enable(void)90df9ee292SDavid Howells static inline void arch_local_irq_enable(void)
91df9ee292SDavid Howells {
92df9ee292SDavid Howells 	unsigned long temp;
93df9ee292SDavid Howells 	asm volatile(
94df9ee292SDavid Howells 		"	mrs	%0, cpsr	@ arch_local_irq_enable\n"
95df9ee292SDavid Howells 		"	bic	%0, %0, #128\n"
96df9ee292SDavid Howells 		"	msr	cpsr_c, %0"
97df9ee292SDavid Howells 		: "=r" (temp)
98df9ee292SDavid Howells 		:
99df9ee292SDavid Howells 		: "memory", "cc");
100df9ee292SDavid Howells }
1014baa9922SRussell King 
1024baa9922SRussell King /*
1034baa9922SRussell King  * Disable IRQs
1044baa9922SRussell King  */
1056fb18ac9SDaniel Thompson #define arch_local_irq_disable arch_local_irq_disable
arch_local_irq_disable(void)106df9ee292SDavid Howells static inline void arch_local_irq_disable(void)
107df9ee292SDavid Howells {
108df9ee292SDavid Howells 	unsigned long temp;
109df9ee292SDavid Howells 	asm volatile(
110df9ee292SDavid Howells 		"	mrs	%0, cpsr	@ arch_local_irq_disable\n"
111df9ee292SDavid Howells 		"	orr	%0, %0, #128\n"
112df9ee292SDavid Howells 		"	msr	cpsr_c, %0"
113df9ee292SDavid Howells 		: "=r" (temp)
114df9ee292SDavid Howells 		:
115df9ee292SDavid Howells 		: "memory", "cc");
116df9ee292SDavid Howells }
1174baa9922SRussell King 
1184baa9922SRussell King /*
1194baa9922SRussell King  * Enable FIQs
1204baa9922SRussell King  */
1214baa9922SRussell King #define local_fiq_enable()					\
1224baa9922SRussell King 	({							\
1234baa9922SRussell King 		unsigned long temp;				\
1244baa9922SRussell King 	__asm__ __volatile__(					\
1254baa9922SRussell King 	"mrs	%0, cpsr		@ stf\n"		\
1264baa9922SRussell King "	bic	%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 /*
1344baa9922SRussell King  * Disable FIQs
1354baa9922SRussell King  */
1364baa9922SRussell King #define local_fiq_disable()					\
1374baa9922SRussell King 	({							\
1384baa9922SRussell King 		unsigned long temp;				\
1394baa9922SRussell King 	__asm__ __volatile__(					\
1404baa9922SRussell King 	"mrs	%0, cpsr		@ clf\n"		\
1414baa9922SRussell King "	orr	%0, %0, #64\n"					\
1424baa9922SRussell King "	msr	cpsr_c, %0"					\
1434baa9922SRussell King 	: "=r" (temp)						\
1444baa9922SRussell King 	:							\
1454baa9922SRussell King 	: "memory", "cc");					\
1464baa9922SRussell King 	})
1474baa9922SRussell King 
148bbeb9209SLucas Stach #define local_abt_enable()	do { } while (0)
149bbeb9209SLucas Stach #define local_abt_disable()	do { } while (0)
1504baa9922SRussell King #endif
1514baa9922SRussell King 
1524baa9922SRussell King /*
1534baa9922SRussell King  * Save the current interrupt enable state.
1544baa9922SRussell King  */
1556fb18ac9SDaniel Thompson #define arch_local_save_flags arch_local_save_flags
arch_local_save_flags(void)156df9ee292SDavid Howells static inline unsigned long arch_local_save_flags(void)
157df9ee292SDavid Howells {
158df9ee292SDavid Howells 	unsigned long flags;
159df9ee292SDavid Howells 	asm volatile(
16055bdd694SCatalin Marinas 		"	mrs	%0, " IRQMASK_REG_NAME_R "	@ local_save_flags"
161df9ee292SDavid Howells 		: "=r" (flags) : : "memory", "cc");
162df9ee292SDavid Howells 	return flags;
163df9ee292SDavid Howells }
1644baa9922SRussell King 
1654baa9922SRussell King /*
1664baa9922SRussell King  * restore saved IRQ & FIQ state
1674baa9922SRussell King  */
1686fb18ac9SDaniel Thompson #define arch_local_irq_restore arch_local_irq_restore
arch_local_irq_restore(unsigned long flags)169df9ee292SDavid Howells static inline void arch_local_irq_restore(unsigned long flags)
170df9ee292SDavid Howells {
171df9ee292SDavid Howells 	asm volatile(
17255bdd694SCatalin Marinas 		"	msr	" IRQMASK_REG_NAME_W ", %0	@ local_irq_restore"
173df9ee292SDavid Howells 		:
174df9ee292SDavid Howells 		: "r" (flags)
175df9ee292SDavid Howells 		: "memory", "cc");
176df9ee292SDavid Howells }
1774baa9922SRussell King 
1786fb18ac9SDaniel Thompson #define arch_irqs_disabled_flags arch_irqs_disabled_flags
arch_irqs_disabled_flags(unsigned long flags)179df9ee292SDavid Howells static inline int arch_irqs_disabled_flags(unsigned long flags)
180df9ee292SDavid Howells {
18155bdd694SCatalin Marinas 	return flags & IRQMASK_I_BIT;
182df9ee292SDavid Howells }
1834baa9922SRussell King 
1846fb18ac9SDaniel Thompson #include <asm-generic/irqflags.h>
1856fb18ac9SDaniel Thompson 
18655bdd694SCatalin Marinas #endif /* ifdef __KERNEL__ */
18755bdd694SCatalin Marinas #endif /* ifndef __ASM_ARM_IRQFLAGS_H */
188