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 : 3 : static inline unsigned long arch_local_irq_save(void) 26 : : { 27 : : unsigned long flags; 28 : : 29 : 3 : asm volatile( 30 : : " mrs %0, " IRQMASK_REG_NAME_R " @ arch_local_irq_save\n" 31 : : " cpsid i" 32 : : : "=r" (flags) : : "memory", "cc"); 33 : 3 : 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 : 3 : 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 : 3 : 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 : 3 : 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 : 3 : static inline void arch_local_irq_restore(unsigned long flags) 170 : : { 171 : : unsigned long temp = 0; 172 : 3 : flags &= ~(1 << 6); 173 : 3 : asm volatile ( 174 : : " mrs %0, cpsr" 175 : : : "=r" (temp) 176 : : : 177 : : : "memory", "cc"); 178 : : /* Preserve FIQ bit */ 179 : 3 : temp &= (1 << 6); 180 : 3 : flags = flags | temp; 181 : 3 : asm volatile ( 182 : : " msr cpsr_c, %0 @ local_irq_restore" 183 : : : 184 : : : "r" (flags) 185 : : : "memory", "cc"); 186 : 3 : } 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 : 3 : 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 */