Commit | Line | Data |
---|---|---|
ac4c244d VG |
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 | ||
ac4c244d VG |
18 | #include <asm/arcregs.h> |
19 | ||
da1677b0 VG |
20 | /* status32 Reg bits related to Interrupt Handling */ |
21 | #define STATUS_E1_BIT 1 /* Int 1 enable */ | |
22 | #define STATUS_E2_BIT 2 /* Int 2 enable */ | |
23 | #define STATUS_A1_BIT 3 /* Int 1 active */ | |
24 | #define STATUS_A2_BIT 4 /* Int 2 active */ | |
25 | ||
26 | #define STATUS_E1_MASK (1<<STATUS_E1_BIT) | |
27 | #define STATUS_E2_MASK (1<<STATUS_E2_BIT) | |
28 | #define STATUS_A1_MASK (1<<STATUS_A1_BIT) | |
29 | #define STATUS_A2_MASK (1<<STATUS_A2_BIT) | |
30 | ||
31 | /* Other Interrupt Handling related Aux regs */ | |
32 | #define AUX_IRQ_LEV 0x200 /* IRQ Priority: L1 or L2 */ | |
33 | #define AUX_IRQ_HINT 0x201 /* For generating Soft Interrupts */ | |
34 | #define AUX_IRQ_LV12 0x43 /* interrupt level register */ | |
35 | ||
36 | #define AUX_IENABLE 0x40c | |
37 | #define AUX_ITRIGGER 0x40d | |
38 | #define AUX_IPULSE 0x415 | |
39 | ||
ac4c244d VG |
40 | #ifndef __ASSEMBLY__ |
41 | ||
42 | /****************************************************************** | |
43 | * IRQ Control Macros | |
44 | ******************************************************************/ | |
45 | ||
46 | /* | |
47 | * Save IRQ state and disable IRQs | |
48 | */ | |
49 | static inline long arch_local_irq_save(void) | |
50 | { | |
51 | unsigned long temp, flags; | |
52 | ||
53 | __asm__ __volatile__( | |
54 | " lr %1, [status32] \n" | |
55 | " bic %0, %1, %2 \n" | |
56 | " and.f 0, %1, %2 \n" | |
57 | " flag.nz %0 \n" | |
58 | : "=r"(temp), "=r"(flags) | |
59 | : "n"((STATUS_E1_MASK | STATUS_E2_MASK)) | |
79e5f05e | 60 | : "memory", "cc"); |
ac4c244d VG |
61 | |
62 | return flags; | |
63 | } | |
64 | ||
65 | /* | |
66 | * restore saved IRQ state | |
67 | */ | |
68 | static inline void arch_local_irq_restore(unsigned long flags) | |
69 | { | |
70 | ||
71 | __asm__ __volatile__( | |
72 | " flag %0 \n" | |
73 | : | |
79e5f05e CR |
74 | : "r"(flags) |
75 | : "memory"); | |
ac4c244d VG |
76 | } |
77 | ||
78 | /* | |
79 | * Unconditionally Enable IRQs | |
80 | */ | |
81 | extern void arch_local_irq_enable(void); | |
82 | ||
83 | /* | |
84 | * Unconditionally Disable IRQs | |
85 | */ | |
86 | static inline void arch_local_irq_disable(void) | |
87 | { | |
88 | unsigned long temp; | |
89 | ||
90 | __asm__ __volatile__( | |
91 | " lr %0, [status32] \n" | |
92 | " and %0, %0, %1 \n" | |
93 | " flag %0 \n" | |
94 | : "=&r"(temp) | |
79e5f05e CR |
95 | : "n"(~(STATUS_E1_MASK | STATUS_E2_MASK)) |
96 | : "memory"); | |
ac4c244d VG |
97 | } |
98 | ||
99 | /* | |
100 | * save IRQ state | |
101 | */ | |
102 | static inline long arch_local_save_flags(void) | |
103 | { | |
104 | unsigned long temp; | |
105 | ||
106 | __asm__ __volatile__( | |
107 | " lr %0, [status32] \n" | |
79e5f05e CR |
108 | : "=&r"(temp) |
109 | : | |
110 | : "memory"); | |
ac4c244d VG |
111 | |
112 | return temp; | |
113 | } | |
114 | ||
115 | /* | |
116 | * Query IRQ state | |
117 | */ | |
118 | static inline int arch_irqs_disabled_flags(unsigned long flags) | |
119 | { | |
4788a594 VG |
120 | return !(flags & (STATUS_E1_MASK |
121 | #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS | |
122 | | STATUS_E2_MASK | |
123 | #endif | |
124 | )); | |
ac4c244d VG |
125 | } |
126 | ||
127 | static inline int arch_irqs_disabled(void) | |
128 | { | |
129 | return arch_irqs_disabled_flags(arch_local_save_flags()); | |
130 | } | |
131 | ||
ac4c244d VG |
132 | #else |
133 | ||
0dafafc3 VG |
134 | #ifdef CONFIG_TRACE_IRQFLAGS |
135 | ||
136 | .macro TRACE_ASM_IRQ_DISABLE | |
137 | bl trace_hardirqs_off | |
138 | .endm | |
139 | ||
140 | .macro TRACE_ASM_IRQ_ENABLE | |
141 | bl trace_hardirqs_on | |
142 | .endm | |
143 | ||
144 | #else | |
145 | ||
146 | .macro TRACE_ASM_IRQ_DISABLE | |
147 | .endm | |
148 | ||
149 | .macro TRACE_ASM_IRQ_ENABLE | |
150 | .endm | |
151 | ||
152 | #endif | |
153 | ||
ac4c244d VG |
154 | .macro IRQ_DISABLE scratch |
155 | lr \scratch, [status32] | |
156 | bic \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK) | |
157 | flag \scratch | |
0dafafc3 | 158 | TRACE_ASM_IRQ_DISABLE |
ac4c244d VG |
159 | .endm |
160 | ||
ac4c244d VG |
161 | .macro IRQ_ENABLE scratch |
162 | lr \scratch, [status32] | |
163 | or \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK) | |
164 | flag \scratch | |
0dafafc3 | 165 | TRACE_ASM_IRQ_ENABLE |
ac4c244d VG |
166 | .endm |
167 | ||
168 | #endif /* __ASSEMBLY__ */ | |
169 | ||
ac4c244d | 170 | #endif |