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 23static 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 34static 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 43static 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 */ 59static 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 */ 76static 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 */ 91static 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 */ 138static 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 */ 150static 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 159static 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