1 /* 2 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 */ 8 9 #ifndef __ASM_ARC_IRQFLAGS_H 10 #define __ASM_ARC_IRQFLAGS_H 11 12 /* vineetg: March 2010 : local_irq_save( ) optimisation 13 * -Remove explicit mov of current status32 into reg, that is not needed 14 * -Use BIC insn instead of INVERTED + AND 15 * -Conditionally disable interrupts (if they are not enabled, don't disable) 16 */ 17 18 #ifdef __KERNEL__ 19 20 #include <asm/arcregs.h> 21 22 #ifndef __ASSEMBLY__ 23 24 /****************************************************************** 25 * IRQ Control Macros 26 ******************************************************************/ 27 28 /* 29 * Save IRQ state and disable IRQs 30 */ 31 static inline long arch_local_irq_save(void) 32 { 33 unsigned long temp, flags; 34 35 __asm__ __volatile__( 36 " lr %1, [status32] \n" 37 " bic %0, %1, %2 \n" 38 " and.f 0, %1, %2 \n" 39 " flag.nz %0 \n" 40 : "=r"(temp), "=r"(flags) 41 : "n"((STATUS_E1_MASK | STATUS_E2_MASK)) 42 : "cc"); 43 44 return flags; 45 } 46 47 /* 48 * restore saved IRQ state 49 */ 50 static inline void arch_local_irq_restore(unsigned long flags) 51 { 52 53 __asm__ __volatile__( 54 " flag %0 \n" 55 : 56 : "r"(flags)); 57 } 58 59 /* 60 * Unconditionally Enable IRQs 61 */ 62 extern void arch_local_irq_enable(void); 63 64 /* 65 * Unconditionally Disable IRQs 66 */ 67 static inline void arch_local_irq_disable(void) 68 { 69 unsigned long temp; 70 71 __asm__ __volatile__( 72 " lr %0, [status32] \n" 73 " and %0, %0, %1 \n" 74 " flag %0 \n" 75 : "=&r"(temp) 76 : "n"(~(STATUS_E1_MASK | STATUS_E2_MASK))); 77 } 78 79 /* 80 * save IRQ state 81 */ 82 static inline long arch_local_save_flags(void) 83 { 84 unsigned long temp; 85 86 __asm__ __volatile__( 87 " lr %0, [status32] \n" 88 : "=&r"(temp)); 89 90 return temp; 91 } 92 93 /* 94 * Query IRQ state 95 */ 96 static inline int arch_irqs_disabled_flags(unsigned long flags) 97 { 98 return !(flags & (STATUS_E1_MASK 99 #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS 100 | STATUS_E2_MASK 101 #endif 102 )); 103 } 104 105 static inline int arch_irqs_disabled(void) 106 { 107 return arch_irqs_disabled_flags(arch_local_save_flags()); 108 } 109 110 static inline void arch_mask_irq(unsigned int irq) 111 { 112 unsigned int ienb; 113 114 ienb = read_aux_reg(AUX_IENABLE); 115 ienb &= ~(1 << irq); 116 write_aux_reg(AUX_IENABLE, ienb); 117 } 118 119 static inline void arch_unmask_irq(unsigned int irq) 120 { 121 unsigned int ienb; 122 123 ienb = read_aux_reg(AUX_IENABLE); 124 ienb |= (1 << irq); 125 write_aux_reg(AUX_IENABLE, ienb); 126 } 127 128 #else 129 130 .macro IRQ_DISABLE scratch 131 lr \scratch, [status32] 132 bic \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK) 133 flag \scratch 134 .endm 135 136 .macro IRQ_DISABLE_SAVE scratch, save 137 lr \scratch, [status32] 138 mov \save, \scratch /* Make a copy */ 139 bic \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK) 140 flag \scratch 141 .endm 142 143 .macro IRQ_ENABLE scratch 144 lr \scratch, [status32] 145 or \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK) 146 flag \scratch 147 .endm 148 149 #endif /* __ASSEMBLY__ */ 150 151 #endif /* KERNEL */ 152 153 #endif 154