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