Commit | Line | Data |
---|---|---|
8f86001f MF |
1 | /* |
2 | * interface to Blackfin CEC | |
3 | * | |
4 | * Copyright 2009 Analog Devices Inc. | |
5 | * Licensed under the GPL-2 or later. | |
6 | */ | |
7 | ||
8 | #ifndef __ASM_BFIN_IRQFLAGS_H__ | |
9 | #define __ASM_BFIN_IRQFLAGS_H__ | |
10 | ||
11 | #ifdef CONFIG_SMP | |
12 | # include <asm/pda.h> | |
13 | # include <asm/processor.h> | |
14 | /* Forward decl needed due to cdef inter dependencies */ | |
15 | static inline uint32_t __pure bfin_dspid(void); | |
16 | # define blackfin_core_id() (bfin_dspid() & 0xff) | |
17 | # define bfin_irq_flags cpu_pda[blackfin_core_id()].imask | |
18 | #else | |
19 | extern unsigned long bfin_irq_flags; | |
20 | #endif | |
21 | ||
22 | static inline void bfin_sti(unsigned long flags) | |
23 | { | |
24 | asm volatile("sti %0;" : : "d" (flags)); | |
25 | } | |
26 | ||
27 | static inline unsigned long bfin_cli(void) | |
28 | { | |
29 | unsigned long flags; | |
30 | asm volatile("cli %0;" : "=d" (flags)); | |
31 | return flags; | |
32 | } | |
33 | ||
06ecc190 PG |
34 | #ifdef CONFIG_IPIPE |
35 | ||
36 | #include <linux/ipipe_base.h> | |
37 | #include <linux/ipipe_trace.h> | |
38 | ||
39 | #ifdef CONFIG_DEBUG_HWERR | |
40 | # define bfin_no_irqs 0x3f | |
41 | #else | |
42 | # define bfin_no_irqs 0x1f | |
43 | #endif | |
44 | ||
45 | #define raw_local_irq_disable() \ | |
46 | do { \ | |
47 | ipipe_check_context(ipipe_root_domain); \ | |
48 | __ipipe_stall_root(); \ | |
49 | barrier(); \ | |
50 | } while (0) | |
51 | ||
52 | static inline void raw_local_irq_enable(void) | |
53 | { | |
54 | barrier(); | |
55 | ipipe_check_context(ipipe_root_domain); | |
56 | __ipipe_unstall_root(); | |
57 | } | |
58 | ||
59 | #define raw_local_save_flags_ptr(x) \ | |
60 | do { \ | |
61 | *(x) = __ipipe_test_root() ? bfin_no_irqs : bfin_irq_flags; \ | |
62 | } while (0) | |
63 | ||
64 | #define raw_local_save_flags(x) raw_local_save_flags_ptr(&(x)) | |
65 | ||
66 | #define raw_irqs_disabled_flags(x) ((x) == bfin_no_irqs) | |
67 | ||
68 | #define raw_local_irq_save_ptr(x) \ | |
69 | do { \ | |
70 | *(x) = __ipipe_test_and_stall_root() ? bfin_no_irqs : bfin_irq_flags; \ | |
71 | barrier(); \ | |
72 | } while (0) | |
73 | ||
74 | #define raw_local_irq_save(x) \ | |
75 | do { \ | |
76 | ipipe_check_context(ipipe_root_domain); \ | |
77 | raw_local_irq_save_ptr(&(x)); \ | |
78 | } while (0) | |
79 | ||
80 | static inline unsigned long raw_mangle_irq_bits(int virt, unsigned long real) | |
81 | { | |
82 | /* | |
83 | * Merge virtual and real interrupt mask bits into a single | |
84 | * 32bit word. | |
85 | */ | |
86 | return (real & ~(1 << 31)) | ((virt != 0) << 31); | |
87 | } | |
88 | ||
89 | static inline int raw_demangle_irq_bits(unsigned long *x) | |
90 | { | |
91 | int virt = (*x & (1 << 31)) != 0; | |
92 | *x &= ~(1L << 31); | |
93 | return virt; | |
94 | } | |
95 | ||
96 | static inline void local_irq_disable_hw_notrace(void) | |
97 | { | |
98 | bfin_cli(); | |
99 | } | |
100 | ||
101 | static inline void local_irq_enable_hw_notrace(void) | |
102 | { | |
103 | bfin_sti(bfin_irq_flags); | |
104 | } | |
105 | ||
106 | #define local_save_flags_hw(flags) \ | |
107 | do { \ | |
108 | (flags) = bfin_read_IMASK(); \ | |
109 | } while (0) | |
110 | ||
111 | #define irqs_disabled_flags_hw(flags) (((flags) & ~0x3f) == 0) | |
112 | ||
113 | #define irqs_disabled_hw() \ | |
114 | ({ \ | |
115 | unsigned long flags; \ | |
116 | local_save_flags_hw(flags); \ | |
117 | irqs_disabled_flags_hw(flags); \ | |
118 | }) | |
119 | ||
120 | static inline void local_irq_save_ptr_hw(unsigned long *flags) | |
121 | { | |
122 | *flags = bfin_cli(); | |
123 | #ifdef CONFIG_DEBUG_HWERR | |
124 | bfin_sti(0x3f); | |
125 | #endif | |
126 | } | |
127 | ||
128 | #define local_irq_save_hw_notrace(flags) \ | |
129 | do { \ | |
130 | local_irq_save_ptr_hw(&(flags)); \ | |
131 | } while (0) | |
132 | ||
133 | static inline void local_irq_restore_hw_notrace(unsigned long flags) | |
134 | { | |
135 | if (!irqs_disabled_flags_hw(flags)) | |
136 | local_irq_enable_hw_notrace(); | |
137 | } | |
138 | ||
139 | #ifdef CONFIG_IPIPE_TRACE_IRQSOFF | |
140 | # define local_irq_disable_hw() \ | |
141 | do { \ | |
142 | if (!irqs_disabled_hw()) { \ | |
143 | local_irq_disable_hw_notrace(); \ | |
144 | ipipe_trace_begin(0x80000000); \ | |
145 | } \ | |
146 | } while (0) | |
147 | # define local_irq_enable_hw() \ | |
148 | do { \ | |
149 | if (irqs_disabled_hw()) { \ | |
150 | ipipe_trace_end(0x80000000); \ | |
151 | local_irq_enable_hw_notrace(); \ | |
152 | } \ | |
153 | } while (0) | |
154 | # define local_irq_save_hw(flags) \ | |
155 | do { \ | |
156 | local_save_flags_hw(flags); \ | |
157 | if (!irqs_disabled_flags_hw(flags)) { \ | |
158 | local_irq_disable_hw_notrace(); \ | |
159 | ipipe_trace_begin(0x80000001); \ | |
160 | } \ | |
161 | } while (0) | |
162 | # define local_irq_restore_hw(flags) \ | |
163 | do { \ | |
164 | if (!irqs_disabled_flags_hw(flags)) { \ | |
165 | ipipe_trace_end(0x80000001); \ | |
166 | local_irq_enable_hw_notrace(); \ | |
167 | } \ | |
168 | } while (0) | |
169 | #else /* !CONFIG_IPIPE_TRACE_IRQSOFF */ | |
170 | # define local_irq_disable_hw() local_irq_disable_hw_notrace() | |
171 | # define local_irq_enable_hw() local_irq_enable_hw_notrace() | |
172 | # define local_irq_save_hw(flags) local_irq_save_hw_notrace(flags) | |
173 | # define local_irq_restore_hw(flags) local_irq_restore_hw_notrace(flags) | |
174 | #endif /* !CONFIG_IPIPE_TRACE_IRQSOFF */ | |
175 | ||
176 | #else /* CONFIG_IPIPE */ | |
177 | ||
8f86001f MF |
178 | static inline void raw_local_irq_disable(void) |
179 | { | |
180 | bfin_cli(); | |
181 | } | |
182 | static inline void raw_local_irq_enable(void) | |
183 | { | |
184 | bfin_sti(bfin_irq_flags); | |
185 | } | |
186 | ||
187 | #define raw_local_save_flags(flags) do { (flags) = bfin_read_IMASK(); } while (0) | |
188 | ||
189 | #define raw_irqs_disabled_flags(flags) (((flags) & ~0x3f) == 0) | |
190 | ||
8f86001f MF |
191 | static inline unsigned long __raw_local_irq_save(void) |
192 | { | |
193 | unsigned long flags = bfin_cli(); | |
194 | #ifdef CONFIG_DEBUG_HWERR | |
195 | bfin_sti(0x3f); | |
196 | #endif | |
197 | return flags; | |
198 | } | |
199 | #define raw_local_irq_save(flags) do { (flags) = __raw_local_irq_save(); } while (0) | |
200 | ||
06ecc190 PG |
201 | #define local_irq_save_hw(flags) raw_local_irq_save(flags) |
202 | #define local_irq_restore_hw(flags) raw_local_irq_restore(flags) | |
203 | #define local_irq_enable_hw() raw_local_irq_enable() | |
204 | #define local_irq_disable_hw() raw_local_irq_disable() | |
205 | #define irqs_disabled_hw() irqs_disabled() | |
206 | ||
207 | #endif /* !CONFIG_IPIPE */ | |
208 | ||
209 | static inline void raw_local_irq_restore(unsigned long flags) | |
210 | { | |
211 | if (!raw_irqs_disabled_flags(flags)) | |
212 | raw_local_irq_enable(); | |
213 | } | |
214 | ||
8f86001f | 215 | #endif |