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