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 static inline unsigned long arch_local_irq_save(void) 24 { 25 unsigned long flags; 26 27 asm volatile( 28 " mrs %0, " IRQMASK_REG_NAME_R " @ arch_local_irq_save\n" 29 " cpsid i" 30 : "=r" (flags) : : "memory", "cc"); 31 return flags; 32 } 33 34 static inline void arch_local_irq_enable(void) 35 { 36 asm volatile( 37 " cpsie i @ arch_local_irq_enable" 38 : 39 : 40 : "memory", "cc"); 41 } 42 43 static inline void arch_local_irq_disable(void) 44 { 45 asm volatile( 46 " cpsid i @ arch_local_irq_disable" 47 : 48 : 49 : "memory", "cc"); 50 } 51 52 #define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc") 53 #define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc") 54 #else 55 56 /* 57 * Save the current interrupt enable state & disable IRQs 58 */ 59 static inline unsigned long arch_local_irq_save(void) 60 { 61 unsigned long flags, temp; 62 63 asm volatile( 64 " mrs %0, cpsr @ arch_local_irq_save\n" 65 " orr %1, %0, #128\n" 66 " msr cpsr_c, %1" 67 : "=r" (flags), "=r" (temp) 68 : 69 : "memory", "cc"); 70 return flags; 71 } 72 73 /* 74 * Enable IRQs 75 */ 76 static inline void arch_local_irq_enable(void) 77 { 78 unsigned long temp; 79 asm volatile( 80 " mrs %0, cpsr @ arch_local_irq_enable\n" 81 " bic %0, %0, #128\n" 82 " msr cpsr_c, %0" 83 : "=r" (temp) 84 : 85 : "memory", "cc"); 86 } 87 88 /* 89 * Disable IRQs 90 */ 91 static inline void arch_local_irq_disable(void) 92 { 93 unsigned long temp; 94 asm volatile( 95 " mrs %0, cpsr @ arch_local_irq_disable\n" 96 " orr %0, %0, #128\n" 97 " msr cpsr_c, %0" 98 : "=r" (temp) 99 : 100 : "memory", "cc"); 101 } 102 103 /* 104 * Enable FIQs 105 */ 106 #define local_fiq_enable() \ 107 ({ \ 108 unsigned long temp; \ 109 __asm__ __volatile__( \ 110 "mrs %0, cpsr @ stf\n" \ 111 " bic %0, %0, #64\n" \ 112 " msr cpsr_c, %0" \ 113 : "=r" (temp) \ 114 : \ 115 : "memory", "cc"); \ 116 }) 117 118 /* 119 * Disable FIQs 120 */ 121 #define local_fiq_disable() \ 122 ({ \ 123 unsigned long temp; \ 124 __asm__ __volatile__( \ 125 "mrs %0, cpsr @ clf\n" \ 126 " orr %0, %0, #64\n" \ 127 " msr cpsr_c, %0" \ 128 : "=r" (temp) \ 129 : \ 130 : "memory", "cc"); \ 131 }) 132 133 #endif 134 135 /* 136 * Save the current interrupt enable state. 137 */ 138 static inline unsigned long arch_local_save_flags(void) 139 { 140 unsigned long flags; 141 asm volatile( 142 " mrs %0, " IRQMASK_REG_NAME_R " @ local_save_flags" 143 : "=r" (flags) : : "memory", "cc"); 144 return flags; 145 } 146 147 /* 148 * restore saved IRQ & FIQ state 149 */ 150 static inline void arch_local_irq_restore(unsigned long flags) 151 { 152 asm volatile( 153 " msr " IRQMASK_REG_NAME_W ", %0 @ local_irq_restore" 154 : 155 : "r" (flags) 156 : "memory", "cc"); 157 } 158 159 static inline int arch_irqs_disabled_flags(unsigned long flags) 160 { 161 return flags & IRQMASK_I_BIT; 162 } 163 164 #endif /* ifdef __KERNEL__ */ 165 #endif /* ifndef __ASM_ARM_IRQFLAGS_H */ 166