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 #else 58 59 /* 60 * Save the current interrupt enable state & disable IRQs 61 */ 62 #define arch_local_irq_save arch_local_irq_save 63 static inline unsigned long arch_local_irq_save(void) 64 { 65 unsigned long flags, temp; 66 67 asm volatile( 68 " mrs %0, cpsr @ arch_local_irq_save\n" 69 " orr %1, %0, #128\n" 70 " msr cpsr_c, %1" 71 : "=r" (flags), "=r" (temp) 72 : 73 : "memory", "cc"); 74 return flags; 75 } 76 77 /* 78 * Enable IRQs 79 */ 80 #define arch_local_irq_enable arch_local_irq_enable 81 static inline void arch_local_irq_enable(void) 82 { 83 unsigned long temp; 84 asm volatile( 85 " mrs %0, cpsr @ arch_local_irq_enable\n" 86 " bic %0, %0, #128\n" 87 " msr cpsr_c, %0" 88 : "=r" (temp) 89 : 90 : "memory", "cc"); 91 } 92 93 /* 94 * Disable IRQs 95 */ 96 #define arch_local_irq_disable arch_local_irq_disable 97 static inline void arch_local_irq_disable(void) 98 { 99 unsigned long temp; 100 asm volatile( 101 " mrs %0, cpsr @ arch_local_irq_disable\n" 102 " orr %0, %0, #128\n" 103 " msr cpsr_c, %0" 104 : "=r" (temp) 105 : 106 : "memory", "cc"); 107 } 108 109 /* 110 * Enable FIQs 111 */ 112 #define local_fiq_enable() \ 113 ({ \ 114 unsigned long temp; \ 115 __asm__ __volatile__( \ 116 "mrs %0, cpsr @ stf\n" \ 117 " bic %0, %0, #64\n" \ 118 " msr cpsr_c, %0" \ 119 : "=r" (temp) \ 120 : \ 121 : "memory", "cc"); \ 122 }) 123 124 /* 125 * Disable FIQs 126 */ 127 #define local_fiq_disable() \ 128 ({ \ 129 unsigned long temp; \ 130 __asm__ __volatile__( \ 131 "mrs %0, cpsr @ clf\n" \ 132 " orr %0, %0, #64\n" \ 133 " msr cpsr_c, %0" \ 134 : "=r" (temp) \ 135 : \ 136 : "memory", "cc"); \ 137 }) 138 139 #endif 140 141 /* 142 * Save the current interrupt enable state. 143 */ 144 #define arch_local_save_flags arch_local_save_flags 145 static inline unsigned long arch_local_save_flags(void) 146 { 147 unsigned long flags; 148 asm volatile( 149 " mrs %0, " IRQMASK_REG_NAME_R " @ local_save_flags" 150 : "=r" (flags) : : "memory", "cc"); 151 return flags; 152 } 153 154 /* 155 * restore saved IRQ & FIQ state 156 */ 157 #define arch_local_irq_restore arch_local_irq_restore 158 static inline void arch_local_irq_restore(unsigned long flags) 159 { 160 asm volatile( 161 " msr " IRQMASK_REG_NAME_W ", %0 @ local_irq_restore" 162 : 163 : "r" (flags) 164 : "memory", "cc"); 165 } 166 167 #define arch_irqs_disabled_flags arch_irqs_disabled_flags 168 static inline int arch_irqs_disabled_flags(unsigned long flags) 169 { 170 return flags & IRQMASK_I_BIT; 171 } 172 173 #include <asm-generic/irqflags.h> 174 175 #endif /* ifdef __KERNEL__ */ 176 #endif /* ifndef __ASM_ARM_IRQFLAGS_H */ 177