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 static inline unsigned long arch_local_irq_save(void) 26 { 27 unsigned long flags; 28 29 asm volatile( 30 " mrs %0, " IRQMASK_REG_NAME_R " @ arch_local_irq_save\n" 31 " cpsid i" 32 : "=r" (flags) : : "memory", "cc"); 33 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 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 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 static inline unsigned long arch_local_save_flags(void) 157 { 158 unsigned long flags; 159 asm volatile( 160 " mrs %0, " IRQMASK_REG_NAME_R " @ local_save_flags" 161 : "=r" (flags) : : "memory", "cc"); 162 return flags; 163 } 164 165 /* 166 * restore saved IRQ & FIQ state 167 */ 168 #define arch_local_irq_restore arch_local_irq_restore 169 static inline void arch_local_irq_restore(unsigned long flags) 170 { 171 asm volatile( 172 " msr " IRQMASK_REG_NAME_W ", %0 @ local_irq_restore" 173 : 174 : "r" (flags) 175 : "memory", "cc"); 176 } 177 178 #define arch_irqs_disabled_flags arch_irqs_disabled_flags 179 static inline int arch_irqs_disabled_flags(unsigned long flags) 180 { 181 return flags & IRQMASK_I_BIT; 182 } 183 184 #include <asm-generic/irqflags.h> 185 186 #endif /* ifdef __KERNEL__ */ 187 #endif /* ifndef __ASM_ARM_IRQFLAGS_H */ 188