aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/include/asm/irqflags.h
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /arch/blackfin/include/asm/irqflags.h
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'arch/blackfin/include/asm/irqflags.h')
-rw-r--r--arch/blackfin/include/asm/irqflags.h339
1 files changed, 204 insertions, 135 deletions
diff --git a/arch/blackfin/include/asm/irqflags.h b/arch/blackfin/include/asm/irqflags.h
index 813a1af3e865..b4bbb75a9e15 100644
--- a/arch/blackfin/include/asm/irqflags.h
+++ b/arch/blackfin/include/asm/irqflags.h
@@ -8,12 +8,11 @@
8#ifndef __ASM_BFIN_IRQFLAGS_H__ 8#ifndef __ASM_BFIN_IRQFLAGS_H__
9#define __ASM_BFIN_IRQFLAGS_H__ 9#define __ASM_BFIN_IRQFLAGS_H__
10 10
11#include <mach/blackfin.h>
12
11#ifdef CONFIG_SMP 13#ifdef CONFIG_SMP
12# include <asm/pda.h> 14# include <asm/pda.h>
13# include <asm/processor.h> 15# include <asm/processor.h>
14/* Forward decl needed due to cdef inter dependencies */
15static 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 16# define bfin_irq_flags cpu_pda[blackfin_core_id()].imask
18#else 17#else
19extern unsigned long bfin_irq_flags; 18extern unsigned long bfin_irq_flags;
@@ -31,186 +30,256 @@ static inline unsigned long bfin_cli(void)
31 return flags; 30 return flags;
32} 31}
33 32
34#ifdef CONFIG_IPIPE
35
36#include <linux/compiler.h>
37#include <linux/ipipe_base.h>
38#include <linux/ipipe_trace.h>
39
40#ifdef CONFIG_DEBUG_HWERR 33#ifdef CONFIG_DEBUG_HWERR
41# define bfin_no_irqs 0x3f 34# define bfin_no_irqs 0x3f
42#else 35#else
43# define bfin_no_irqs 0x1f 36# define bfin_no_irqs 0x1f
44#endif 37#endif
45 38
46#define raw_local_irq_disable() \ 39/*****************************************************************************/
47 do { \ 40/*
48 ipipe_check_context(ipipe_root_domain); \ 41 * Hard, untraced CPU interrupt flag manipulation and access.
49 __ipipe_stall_root(); \ 42 */
50 barrier(); \ 43static inline void __hard_local_irq_disable(void)
51 } while (0) 44{
45 bfin_cli();
46}
52 47
53#define raw_local_irq_enable() \ 48static inline void __hard_local_irq_enable(void)
54 do { \ 49{
55 barrier(); \ 50 bfin_sti(bfin_irq_flags);
56 ipipe_check_context(ipipe_root_domain); \ 51}
57 __ipipe_unstall_root(); \
58 } while (0)
59 52
60#define raw_local_save_flags_ptr(x) \ 53static inline unsigned long hard_local_save_flags(void)
61 do { \ 54{
62 *(x) = __ipipe_test_root() ? bfin_no_irqs : bfin_irq_flags; \ 55 return bfin_read_IMASK();
63 } while (0) 56}
64 57
65#define raw_local_save_flags(x) raw_local_save_flags_ptr(&(x)) 58static inline unsigned long __hard_local_irq_save(void)
59{
60 unsigned long flags;
61 flags = bfin_cli();
62#ifdef CONFIG_DEBUG_HWERR
63 bfin_sti(0x3f);
64#endif
65 return flags;
66}
66 67
67#define raw_irqs_disabled_flags(x) ((x) == bfin_no_irqs) 68static inline int hard_irqs_disabled_flags(unsigned long flags)
69{
70 return (flags & ~0x3f) == 0;
71}
68 72
69#define raw_local_irq_save_ptr(x) \ 73static inline int hard_irqs_disabled(void)
70 do { \ 74{
71 *(x) = __ipipe_test_and_stall_root() ? bfin_no_irqs : bfin_irq_flags; \ 75 unsigned long flags = hard_local_save_flags();
72 barrier(); \ 76 return hard_irqs_disabled_flags(flags);
73 } while (0) 77}
74 78
75#define raw_local_irq_save(x) \ 79static inline void __hard_local_irq_restore(unsigned long flags)
76 do { \ 80{
77 ipipe_check_context(ipipe_root_domain); \ 81 if (!hard_irqs_disabled_flags(flags))
78 raw_local_irq_save_ptr(&(x)); \ 82 __hard_local_irq_enable();
79 } while (0) 83}
80 84
81static inline unsigned long raw_mangle_irq_bits(int virt, unsigned long real) 85/*****************************************************************************/
86/*
87 * Interrupt pipe handling.
88 */
89#ifdef CONFIG_IPIPE
90
91#include <linux/compiler.h>
92#include <linux/ipipe_trace.h>
93/*
94 * Way too many inter-deps between low-level headers in this port, so
95 * we redeclare the required bits we cannot pick from
96 * <asm/ipipe_base.h> to prevent circular dependencies.
97 */
98void __ipipe_stall_root(void);
99void __ipipe_unstall_root(void);
100unsigned long __ipipe_test_root(void);
101unsigned long __ipipe_test_and_stall_root(void);
102void __ipipe_restore_root(unsigned long flags);
103
104#ifdef CONFIG_IPIPE_DEBUG_CONTEXT
105struct ipipe_domain;
106extern struct ipipe_domain ipipe_root;
107void ipipe_check_context(struct ipipe_domain *ipd);
108#define __check_irqop_context(ipd) ipipe_check_context(&ipipe_root)
109#else /* !CONFIG_IPIPE_DEBUG_CONTEXT */
110#define __check_irqop_context(ipd) do { } while (0)
111#endif /* !CONFIG_IPIPE_DEBUG_CONTEXT */
112
113/*
114 * Interrupt pipe interface to linux/irqflags.h.
115 */
116static inline void arch_local_irq_disable(void)
82{ 117{
83 /* 118 __check_irqop_context();
84 * Merge virtual and real interrupt mask bits into a single 119 __ipipe_stall_root();
85 * 32bit word. 120 barrier();
86 */
87 return (real & ~(1 << 31)) | ((virt != 0) << 31);
88} 121}
89 122
90static inline int raw_demangle_irq_bits(unsigned long *x) 123static inline void arch_local_irq_enable(void)
91{ 124{
92 int virt = (*x & (1 << 31)) != 0; 125 barrier();
93 *x &= ~(1L << 31); 126 __check_irqop_context();
94 return virt; 127 __ipipe_unstall_root();
95} 128}
96 129
97static inline void local_irq_disable_hw_notrace(void) 130static inline unsigned long arch_local_save_flags(void)
98{ 131{
99 bfin_cli(); 132 return __ipipe_test_root() ? bfin_no_irqs : bfin_irq_flags;
100} 133}
101 134
102static inline void local_irq_enable_hw_notrace(void) 135static inline int arch_irqs_disabled_flags(unsigned long flags)
103{ 136{
104 bfin_sti(bfin_irq_flags); 137 return flags == bfin_no_irqs;
105} 138}
106 139
107#define local_save_flags_hw(flags) \ 140static inline unsigned long arch_local_irq_save(void)
108 do { \ 141{
109 (flags) = bfin_read_IMASK(); \ 142 unsigned long flags;
110 } while (0)
111 143
112#define irqs_disabled_flags_hw(flags) (((flags) & ~0x3f) == 0) 144 __check_irqop_context();
145 flags = __ipipe_test_and_stall_root() ? bfin_no_irqs : bfin_irq_flags;
146 barrier();
113 147
114#define irqs_disabled_hw() \ 148 return flags;
115 ({ \ 149}
116 unsigned long flags; \
117 local_save_flags_hw(flags); \
118 irqs_disabled_flags_hw(flags); \
119 })
120 150
121static inline void local_irq_save_ptr_hw(unsigned long *flags) 151static inline void arch_local_irq_restore(unsigned long flags)
122{ 152{
123 *flags = bfin_cli(); 153 __check_irqop_context();
124#ifdef CONFIG_DEBUG_HWERR 154 __ipipe_restore_root(flags == bfin_no_irqs);
125 bfin_sti(0x3f);
126#endif
127} 155}
128 156
129#define local_irq_save_hw_notrace(flags) \ 157static inline unsigned long arch_mangle_irq_bits(int virt, unsigned long real)
130 do { \ 158{
131 local_irq_save_ptr_hw(&(flags)); \ 159 /*
132 } while (0) 160 * Merge virtual and real interrupt mask bits into a single
161 * 32bit word.
162 */
163 return (real & ~(1 << 31)) | ((virt != 0) << 31);
164}
133 165
134static inline void local_irq_restore_hw_notrace(unsigned long flags) 166static inline int arch_demangle_irq_bits(unsigned long *x)
135{ 167{
136 if (!irqs_disabled_flags_hw(flags)) 168 int virt = (*x & (1 << 31)) != 0;
137 local_irq_enable_hw_notrace(); 169 *x &= ~(1L << 31);
170 return virt;
138} 171}
139 172
173/*
174 * Interface to various arch routines that may be traced.
175 */
140#ifdef CONFIG_IPIPE_TRACE_IRQSOFF 176#ifdef CONFIG_IPIPE_TRACE_IRQSOFF
141# define local_irq_disable_hw() \ 177static inline void hard_local_irq_disable(void)
142 do { \ 178{
143 if (!irqs_disabled_hw()) { \ 179 if (!hard_irqs_disabled()) {
144 local_irq_disable_hw_notrace(); \ 180 __hard_local_irq_disable();
145 ipipe_trace_begin(0x80000000); \ 181 ipipe_trace_begin(0x80000000);
146 } \ 182 }
147 } while (0) 183}
148# define local_irq_enable_hw() \
149 do { \
150 if (irqs_disabled_hw()) { \
151 ipipe_trace_end(0x80000000); \
152 local_irq_enable_hw_notrace(); \
153 } \
154 } while (0)
155# define local_irq_save_hw(flags) \
156 do { \
157 local_save_flags_hw(flags); \
158 if (!irqs_disabled_flags_hw(flags)) { \
159 local_irq_disable_hw_notrace(); \
160 ipipe_trace_begin(0x80000001); \
161 } \
162 } while (0)
163# define local_irq_restore_hw(flags) \
164 do { \
165 if (!irqs_disabled_flags_hw(flags)) { \
166 ipipe_trace_end(0x80000001); \
167 local_irq_enable_hw_notrace(); \
168 } \
169 } while (0)
170#else /* !CONFIG_IPIPE_TRACE_IRQSOFF */
171# define local_irq_disable_hw() local_irq_disable_hw_notrace()
172# define local_irq_enable_hw() local_irq_enable_hw_notrace()
173# define local_irq_save_hw(flags) local_irq_save_hw_notrace(flags)
174# define local_irq_restore_hw(flags) local_irq_restore_hw_notrace(flags)
175#endif /* !CONFIG_IPIPE_TRACE_IRQSOFF */
176 184
177#else /* CONFIG_IPIPE */ 185static inline void hard_local_irq_enable(void)
186{
187 if (hard_irqs_disabled()) {
188 ipipe_trace_end(0x80000000);
189 __hard_local_irq_enable();
190 }
191}
178 192
179static inline void raw_local_irq_disable(void) 193static inline unsigned long hard_local_irq_save(void)
180{ 194{
181 bfin_cli(); 195 unsigned long flags = hard_local_save_flags();
196 if (!hard_irqs_disabled_flags(flags)) {
197 __hard_local_irq_disable();
198 ipipe_trace_begin(0x80000001);
199 }
200 return flags;
182} 201}
183static inline void raw_local_irq_enable(void) 202
203static inline void hard_local_irq_restore(unsigned long flags)
184{ 204{
185 bfin_sti(bfin_irq_flags); 205 if (!hard_irqs_disabled_flags(flags)) {
206 ipipe_trace_end(0x80000001);
207 __hard_local_irq_enable();
208 }
186} 209}
187 210
188#define raw_local_save_flags(flags) do { (flags) = bfin_read_IMASK(); } while (0) 211#else /* !CONFIG_IPIPE_TRACE_IRQSOFF */
212# define hard_local_irq_disable() __hard_local_irq_disable()
213# define hard_local_irq_enable() __hard_local_irq_enable()
214# define hard_local_irq_save() __hard_local_irq_save()
215# define hard_local_irq_restore(flags) __hard_local_irq_restore(flags)
216#endif /* !CONFIG_IPIPE_TRACE_IRQSOFF */
189 217
190#define raw_irqs_disabled_flags(flags) (((flags) & ~0x3f) == 0) 218#define hard_local_irq_save_cond() hard_local_irq_save()
219#define hard_local_irq_restore_cond(flags) hard_local_irq_restore(flags)
191 220
192static inline unsigned long __raw_local_irq_save(void) 221#else /* !CONFIG_IPIPE */
193{
194 unsigned long flags = bfin_cli();
195#ifdef CONFIG_DEBUG_HWERR
196 bfin_sti(0x3f);
197#endif
198 return flags;
199}
200#define raw_local_irq_save(flags) do { (flags) = __raw_local_irq_save(); } while (0)
201 222
202#define local_irq_save_hw(flags) raw_local_irq_save(flags) 223/*
203#define local_irq_restore_hw(flags) raw_local_irq_restore(flags) 224 * Direct interface to linux/irqflags.h.
204#define local_irq_enable_hw() raw_local_irq_enable() 225 */
205#define local_irq_disable_hw() raw_local_irq_disable() 226#define arch_local_save_flags() hard_local_save_flags()
206#define irqs_disabled_hw() irqs_disabled() 227#define arch_local_irq_save(flags) __hard_local_irq_save()
228#define arch_local_irq_restore(flags) __hard_local_irq_restore(flags)
229#define arch_local_irq_enable() __hard_local_irq_enable()
230#define arch_local_irq_disable() __hard_local_irq_disable()
231#define arch_irqs_disabled_flags(flags) hard_irqs_disabled_flags(flags)
232#define arch_irqs_disabled() hard_irqs_disabled()
233
234/*
235 * Interface to various arch routines that may be traced.
236 */
237#define hard_local_irq_save() __hard_local_irq_save()
238#define hard_local_irq_restore(flags) __hard_local_irq_restore(flags)
239#define hard_local_irq_enable() __hard_local_irq_enable()
240#define hard_local_irq_disable() __hard_local_irq_disable()
241#define hard_local_irq_save_cond() hard_local_save_flags()
242#define hard_local_irq_restore_cond(flags) do { (void)(flags); } while (0)
207 243
208#endif /* !CONFIG_IPIPE */ 244#endif /* !CONFIG_IPIPE */
209 245
210static inline void raw_local_irq_restore(unsigned long flags) 246#ifdef CONFIG_SMP
211{ 247#define hard_local_irq_save_smp() hard_local_irq_save()
212 if (!raw_irqs_disabled_flags(flags)) 248#define hard_local_irq_restore_smp(flags) hard_local_irq_restore(flags)
213 raw_local_irq_enable(); 249#else
214} 250#define hard_local_irq_save_smp() hard_local_save_flags()
251#define hard_local_irq_restore_smp(flags) do { (void)(flags); } while (0)
252#endif
253
254/*
255 * Remap the arch-neutral IRQ state manipulation macros to the
256 * blackfin-specific hard_local_irq_* API.
257 */
258#define local_irq_save_hw(flags) \
259 do { \
260 (flags) = hard_local_irq_save(); \
261 } while (0)
262#define local_irq_restore_hw(flags) \
263 do { \
264 hard_local_irq_restore(flags); \
265 } while (0)
266#define local_irq_disable_hw() \
267 do { \
268 hard_local_irq_disable(); \
269 } while (0)
270#define local_irq_enable_hw() \
271 do { \
272 hard_local_irq_enable(); \
273 } while (0)
274#define local_irq_save_hw_notrace(flags) \
275 do { \
276 (flags) = __hard_local_irq_save(); \
277 } while (0)
278#define local_irq_restore_hw_notrace(flags) \
279 do { \
280 __hard_local_irq_restore(flags); \
281 } while (0)
282
283#define irqs_disabled_hw() hard_irqs_disabled()
215 284
216#endif 285#endif