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