Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */
2 : : #ifndef __ASM_ARM_IRQFLAGS_H
3 : : #define __ASM_ARM_IRQFLAGS_H
4 : :
5 : : #ifdef __KERNEL__
6 : :
7 : : #include <asm/ptrace.h>
8 : :
9 : : /*
10 : : * CPU interrupt mask handling.
11 : : */
12 : : #ifdef CONFIG_CPU_V7M
13 : : #define IRQMASK_REG_NAME_R "primask"
14 : : #define IRQMASK_REG_NAME_W "primask"
15 : : #define IRQMASK_I_BIT 1
16 : : #else
17 : : #define IRQMASK_REG_NAME_R "cpsr"
18 : : #define IRQMASK_REG_NAME_W "cpsr_c"
19 : : #define IRQMASK_I_BIT PSR_I_BIT
20 : : #endif
21 : :
22 : : #if __LINUX_ARM_ARCH__ >= 6
23 : :
24 : : #define arch_local_irq_save arch_local_irq_save
25 : 521042044 : static inline unsigned long arch_local_irq_save(void)
26 : : {
27 : : unsigned long flags;
28 : :
29 : 4907247902 : asm volatile(
30 : : " mrs %0, " IRQMASK_REG_NAME_R " @ arch_local_irq_save\n"
31 : : " cpsid i"
32 : : : "=r" (flags) : : "memory", "cc");
33 : 521529908 : return flags;
34 : : }
35 : :
36 : : #define arch_local_irq_enable arch_local_irq_enable
37 : : static inline void arch_local_irq_enable(void)
38 : : {
39 : 740676336 : asm volatile(
40 : : " cpsie i @ arch_local_irq_enable"
41 : : :
42 : : :
43 : : : "memory", "cc");
44 : : }
45 : :
46 : : #define arch_local_irq_disable arch_local_irq_disable
47 : : static inline void arch_local_irq_disable(void)
48 : : {
49 : 460996666 : asm volatile(
50 : : " cpsid i @ arch_local_irq_disable"
51 : : :
52 : : :
53 : : : "memory", "cc");
54 : : }
55 : :
56 : : #define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc")
57 : : #define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc")
58 : :
59 : : #ifndef CONFIG_CPU_V7M
60 : : #define local_abt_enable() __asm__("cpsie a @ __sta" : : : "memory", "cc")
61 : : #define local_abt_disable() __asm__("cpsid a @ __cla" : : : "memory", "cc")
62 : : #else
63 : : #define local_abt_enable() do { } while (0)
64 : : #define local_abt_disable() do { } while (0)
65 : : #endif
66 : : #else
67 : :
68 : : /*
69 : : * Save the current interrupt enable state & disable IRQs
70 : : */
71 : : #define arch_local_irq_save arch_local_irq_save
72 : : static inline unsigned long arch_local_irq_save(void)
73 : : {
74 : : unsigned long flags, temp;
75 : :
76 : : asm volatile(
77 : : " mrs %0, cpsr @ arch_local_irq_save\n"
78 : : " orr %1, %0, #128\n"
79 : : " msr cpsr_c, %1"
80 : : : "=r" (flags), "=r" (temp)
81 : : :
82 : : : "memory", "cc");
83 : : return flags;
84 : : }
85 : :
86 : : /*
87 : : * Enable IRQs
88 : : */
89 : : #define arch_local_irq_enable arch_local_irq_enable
90 : : static inline void arch_local_irq_enable(void)
91 : : {
92 : : unsigned long temp;
93 : : asm volatile(
94 : : " mrs %0, cpsr @ arch_local_irq_enable\n"
95 : : " bic %0, %0, #128\n"
96 : : " msr cpsr_c, %0"
97 : : : "=r" (temp)
98 : : :
99 : : : "memory", "cc");
100 : : }
101 : :
102 : : /*
103 : : * Disable IRQs
104 : : */
105 : : #define arch_local_irq_disable arch_local_irq_disable
106 : : static inline void arch_local_irq_disable(void)
107 : : {
108 : : unsigned long temp;
109 : : asm volatile(
110 : : " mrs %0, cpsr @ arch_local_irq_disable\n"
111 : : " orr %0, %0, #128\n"
112 : : " msr cpsr_c, %0"
113 : : : "=r" (temp)
114 : : :
115 : : : "memory", "cc");
116 : : }
117 : :
118 : : /*
119 : : * Enable FIQs
120 : : */
121 : : #define local_fiq_enable() \
122 : : ({ \
123 : : unsigned long temp; \
124 : : __asm__ __volatile__( \
125 : : "mrs %0, cpsr @ stf\n" \
126 : : " bic %0, %0, #64\n" \
127 : : " msr cpsr_c, %0" \
128 : : : "=r" (temp) \
129 : : : \
130 : : : "memory", "cc"); \
131 : : })
132 : :
133 : : /*
134 : : * Disable FIQs
135 : : */
136 : : #define local_fiq_disable() \
137 : : ({ \
138 : : unsigned long temp; \
139 : : __asm__ __volatile__( \
140 : : "mrs %0, cpsr @ clf\n" \
141 : : " orr %0, %0, #64\n" \
142 : : " msr cpsr_c, %0" \
143 : : : "=r" (temp) \
144 : : : \
145 : : : "memory", "cc"); \
146 : : })
147 : :
148 : : #define local_abt_enable() do { } while (0)
149 : : #define local_abt_disable() do { } while (0)
150 : : #endif
151 : :
152 : : /*
153 : : * Save the current interrupt enable state.
154 : : */
155 : : #define arch_local_save_flags arch_local_save_flags
156 : 0 : static inline unsigned long arch_local_save_flags(void)
157 : : {
158 : : unsigned long flags;
159 : 348580076 : asm volatile(
160 : : " mrs %0, " IRQMASK_REG_NAME_R " @ local_save_flags"
161 : : : "=r" (flags) : : "memory", "cc");
162 : 0 : return flags;
163 : : }
164 : :
165 : : /*
166 : : * restore saved IRQ state
167 : : */
168 : : #define arch_local_irq_restore arch_local_irq_restore
169 : 521562708 : static inline void arch_local_irq_restore(unsigned long flags)
170 : : {
171 : : unsigned long temp = 0;
172 : 4922562036 : flags &= ~(1 << 6);
173 : 4922562036 : asm volatile (
174 : : " mrs %0, cpsr"
175 : : : "=r" (temp)
176 : : :
177 : : : "memory", "cc");
178 : : /* Preserve FIQ bit */
179 : 4923184130 : temp &= (1 << 6);
180 : 4923184130 : flags = flags | temp;
181 : 4923184130 : asm volatile (
182 : : " msr cpsr_c, %0 @ local_irq_restore"
183 : : :
184 : : : "r" (flags)
185 : : : "memory", "cc");
186 : 521553860 : }
187 : :
188 : : #define arch_irqs_disabled_flags arch_irqs_disabled_flags
189 : 0 : static inline int arch_irqs_disabled_flags(unsigned long flags)
190 : : {
191 : 1470797932 : return flags & IRQMASK_I_BIT;
192 : : }
193 : :
194 : : #include <asm-generic/irqflags.h>
195 : :
196 : : #endif /* ifdef __KERNEL__ */
197 : : #endif /* ifndef __ASM_ARM_IRQFLAGS_H */
|