aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/include/asm/irqflags.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/include/asm/irqflags.h')
-rw-r--r--arch/blackfin/include/asm/irqflags.h284
1 files changed, 147 insertions, 137 deletions
diff --git a/arch/blackfin/include/asm/irqflags.h b/arch/blackfin/include/asm/irqflags.h
index f3ed93144e23..994d76791016 100644
--- a/arch/blackfin/include/asm/irqflags.h
+++ b/arch/blackfin/include/asm/irqflags.h
@@ -33,191 +33,201 @@ static inline unsigned long bfin_cli(void)
33 return flags; 33 return flags;
34} 34}
35 35
36#ifdef CONFIG_IPIPE
37
38#include <linux/compiler.h>
39#include <linux/ipipe_base.h>
40#include <linux/ipipe_trace.h>
41
42#ifdef CONFIG_DEBUG_HWERR 36#ifdef CONFIG_DEBUG_HWERR
43# define bfin_no_irqs 0x3f 37# define bfin_no_irqs 0x3f
44#else 38#else
45# define bfin_no_irqs 0x1f 39# define bfin_no_irqs 0x1f
46#endif 40#endif
47 41
48#define raw_local_irq_disable() \ 42/*****************************************************************************/
49 do { \ 43/*
50 ipipe_check_context(ipipe_root_domain); \ 44 * Hard, untraced CPU interrupt flag manipulation and access.
51 __ipipe_stall_root(); \ 45 */
52 barrier(); \ 46static inline void __hard_local_irq_disable(void)
53 } while (0) 47{
54 48 bfin_cli();
55#define raw_local_irq_enable() \ 49}
56 do { \
57 barrier(); \
58 ipipe_check_context(ipipe_root_domain); \
59 __ipipe_unstall_root(); \
60 } while (0)
61
62#define raw_local_save_flags_ptr(x) \
63 do { \
64 *(x) = __ipipe_test_root() ? bfin_no_irqs : bfin_irq_flags; \
65 } while (0)
66
67#define raw_local_save_flags(x) raw_local_save_flags_ptr(&(x))
68
69#define raw_irqs_disabled_flags(x) ((x) == bfin_no_irqs)
70
71#define raw_local_irq_save_ptr(x) \
72 do { \
73 *(x) = __ipipe_test_and_stall_root() ? bfin_no_irqs : bfin_irq_flags; \
74 barrier(); \
75 } while (0)
76 50
77#define raw_local_irq_save(x) \ 51static inline void __hard_local_irq_enable(void)
78 do { \ 52{
79 ipipe_check_context(ipipe_root_domain); \ 53 bfin_sti(bfin_irq_flags);
80 raw_local_irq_save_ptr(&(x)); \ 54}
81 } while (0)
82 55
83static inline unsigned long raw_mangle_irq_bits(int virt, unsigned long real) 56static inline unsigned long hard_local_save_flags(void)
84{ 57{
85 /* 58 return bfin_read_IMASK();
86 * Merge virtual and real interrupt mask bits into a single
87 * 32bit word.
88 */
89 return (real & ~(1 << 31)) | ((virt != 0) << 31);
90} 59}
91 60
92static inline int raw_demangle_irq_bits(unsigned long *x) 61static inline unsigned long __hard_local_irq_save(void)
93{ 62{
94 int virt = (*x & (1 << 31)) != 0; 63 unsigned long flags;
95 *x &= ~(1L << 31); 64 flags = bfin_cli();
96 return virt; 65#ifdef CONFIG_DEBUG_HWERR
66 bfin_sti(0x3f);
67#endif
68 return flags;
97} 69}
98 70
99static inline void local_irq_disable_hw_notrace(void) 71static inline int hard_irqs_disabled_flags(unsigned long flags)
100{ 72{
101 bfin_cli(); 73 return (flags & ~0x3f) == 0;
102} 74}
103 75
104static inline void local_irq_enable_hw_notrace(void) 76static inline int hard_irqs_disabled(void)
105{ 77{
106 bfin_sti(bfin_irq_flags); 78 unsigned long flags = hard_local_save_flags();
79 return hard_irqs_disabled_flags(flags);
107} 80}
108 81
109#define local_save_flags_hw(flags) \ 82static inline void __hard_local_irq_restore(unsigned long flags)
110 do { \ 83{
111 (flags) = bfin_read_IMASK(); \ 84 if (!hard_irqs_disabled_flags(flags))
112 } while (0) 85 __hard_local_irq_enable();
86}
113 87
114#define irqs_disabled_flags_hw(flags) (((flags) & ~0x3f) == 0) 88/*****************************************************************************/
89/*
90 * Interrupt pipe handling.
91 */
92#ifdef CONFIG_IPIPE
115 93
116#define irqs_disabled_hw() \ 94#include <linux/compiler.h>
117 ({ \ 95#include <linux/ipipe_base.h>
118 unsigned long flags; \ 96#include <linux/ipipe_trace.h>
119 local_save_flags_hw(flags); \
120 irqs_disabled_flags_hw(flags); \
121 })
122 97
123static inline void local_irq_save_ptr_hw(unsigned long *flags) 98/*
99 * Interrupt pipe interface to linux/irqflags.h.
100 */
101static inline void arch_local_irq_disable(void)
124{ 102{
125 *flags = bfin_cli(); 103 ipipe_check_context(ipipe_root_domain);
126#ifdef CONFIG_DEBUG_HWERR 104 __ipipe_stall_root();
127 bfin_sti(0x3f); 105 barrier();
128#endif
129} 106}
130 107
131#define local_irq_save_hw_notrace(flags) \ 108static inline void arch_local_irq_enable(void)
132 do { \ 109{
133 local_irq_save_ptr_hw(&(flags)); \ 110 barrier();
134 } while (0) 111 ipipe_check_context(ipipe_root_domain);
112 __ipipe_unstall_root();
113}
135 114
136static inline void local_irq_restore_hw_notrace(unsigned long flags) 115static inline unsigned long arch_local_save_flags(void)
137{ 116{
138 if (!irqs_disabled_flags_hw(flags)) 117 return __ipipe_test_root() ? bfin_no_irqs : bfin_irq_flags;
139 local_irq_enable_hw_notrace();
140} 118}
141 119
142#ifdef CONFIG_IPIPE_TRACE_IRQSOFF 120static inline int arch_irqs_disabled_flags(unsigned long flags)
143# define local_irq_disable_hw() \ 121{
144 do { \ 122 return flags == bfin_no_irqs;
145 if (!irqs_disabled_hw()) { \ 123}
146 local_irq_disable_hw_notrace(); \
147 ipipe_trace_begin(0x80000000); \
148 } \
149 } while (0)
150# define local_irq_enable_hw() \
151 do { \
152 if (irqs_disabled_hw()) { \
153 ipipe_trace_end(0x80000000); \
154 local_irq_enable_hw_notrace(); \
155 } \
156 } while (0)
157# define local_irq_save_hw(flags) \
158 do { \
159 local_save_flags_hw(flags); \
160 if (!irqs_disabled_flags_hw(flags)) { \
161 local_irq_disable_hw_notrace(); \
162 ipipe_trace_begin(0x80000001); \
163 } \
164 } while (0)
165# define local_irq_restore_hw(flags) \
166 do { \
167 if (!irqs_disabled_flags_hw(flags)) { \
168 ipipe_trace_end(0x80000001); \
169 local_irq_enable_hw_notrace(); \
170 } \
171 } while (0)
172#else /* !CONFIG_IPIPE_TRACE_IRQSOFF */
173# define local_irq_disable_hw() local_irq_disable_hw_notrace()
174# define local_irq_enable_hw() local_irq_enable_hw_notrace()
175# define local_irq_save_hw(flags) local_irq_save_hw_notrace(flags)
176# define local_irq_restore_hw(flags) local_irq_restore_hw_notrace(flags)
177#endif /* !CONFIG_IPIPE_TRACE_IRQSOFF */
178 124
179#else /* CONFIG_IPIPE */ 125static inline void arch_local_irq_save_ptr(unsigned long *_flags)
126{
127 x = __ipipe_test_and_stall_root() ? bfin_no_irqs : bfin_irq_flags;
128 barrier();
129}
180 130
181static inline void raw_local_irq_disable(void) 131static inline unsigned long arch_local_irq_save(void)
182{ 132{
183 bfin_cli(); 133 ipipe_check_context(ipipe_root_domain);
134 return __hard_local_irq_save();
184} 135}
185static inline void raw_local_irq_enable(void) 136
137static inline unsigned long arch_mangle_irq_bits(int virt, unsigned long real)
186{ 138{
187 bfin_sti(bfin_irq_flags); 139 /*
140 * Merge virtual and real interrupt mask bits into a single
141 * 32bit word.
142 */
143 return (real & ~(1 << 31)) | ((virt != 0) << 31);
188} 144}
189 145
190static inline unsigned long arch_local_save_flags(void) 146static inline int arch_demangle_irq_bits(unsigned long *x)
191{ 147{
192 return bfin_read_IMASK(); 148 int virt = (*x & (1 << 31)) != 0;
149 *x &= ~(1L << 31);
150 return virt;
193} 151}
194 152
195#define raw_local_save_flags(flags) do { (flags) = arch_local_save_flags(); } while (0) 153/*
154 * Interface to various arch routines that may be traced.
155 */
156#ifdef CONFIG_IPIPE_TRACE_IRQSOFF
157static inline void hard_local_irq_disable(void)
158{
159 if (!hard_irqs_disabled()) {
160 __hard_local_irq_disable();
161 ipipe_trace_begin(0x80000000);
162 }
163}
196 164
197#define raw_irqs_disabled_flags(flags) (((flags) & ~0x3f) == 0) 165static inline void hard_local_irq_enable(void)
166{
167 if (hard_irqs_disabled()) {
168 ipipe_trace_end(0x80000000);
169 __hard_local_irq_enable();
170 }
171}
198 172
199static inline unsigned long __raw_local_irq_save(void) 173static inline unsigned long hard_local_irq_save(void)
200{ 174{
201 unsigned long flags = bfin_cli(); 175 unsigned long flags = hard_local_save_flags();
202#ifdef CONFIG_DEBUG_HWERR 176 if (!hard_irqs_disabled_flags(flags)) {
203 bfin_sti(0x3f); 177 __hard_local_irq_disable();
204#endif 178 ipipe_trace_begin(0x80000001);
179 }
205 return flags; 180 return flags;
206} 181}
207#define raw_local_irq_save(flags) do { (flags) = __raw_local_irq_save(); } while (0)
208 182
209#define local_irq_save_hw(flags) raw_local_irq_save(flags) 183static inline void hard_local_irq_restore(unsigned long flags)
210#define local_irq_restore_hw(flags) raw_local_irq_restore(flags) 184{
211#define local_irq_enable_hw() raw_local_irq_enable() 185 if (!hard_irqs_disabled_flags(flags)) {
212#define local_irq_disable_hw() raw_local_irq_disable() 186 ipipe_trace_end(0x80000001);
213#define irqs_disabled_hw() irqs_disabled() 187 __hard_local_irq_enable();
188 }
189}
190
191#else /* !CONFIG_IPIPE_TRACE_IRQSOFF */
192# define hard_local_irq_disable() __hard_local_irq_disable()
193# define hard_local_irq_enable() __hard_local_irq_enable()
194# define hard_local_irq_save() __hard_local_irq_save()
195# define hard_local_irq_restore(flags) __hard_local_irq_restore(flags)
196#endif /* !CONFIG_IPIPE_TRACE_IRQSOFF */
197
198#else /* CONFIG_IPIPE */
199
200/*
201 * Direct interface to linux/irqflags.h.
202 */
203#define arch_local_save_flags() hard_local_save_flags()
204#define arch_local_irq_save(flags) __hard_local_irq_save()
205#define arch_local_irq_restore(flags) __hard_local_irq_restore(flags)
206#define arch_local_irq_enable() __hard_local_irq_enable()
207#define arch_local_irq_disable() __hard_local_irq_disable()
208#define arch_irqs_disabled_flags(flags) hard_irqs_disabled_flags(flags)
209#define arch_irqs_disabled() hard_irqs_disabled()
210
211/*
212 * Interface to various arch routines that may be traced.
213 */
214#define hard_local_irq_save() __hard_local_irq_save()
215#define hard_local_irq_restore(flags) __hard_local_irq_restore(flags)
216#define hard_local_irq_enable() __hard_local_irq_enable()
217#define hard_local_irq_disable() __hard_local_irq_disable()
218
214 219
215#endif /* !CONFIG_IPIPE */ 220#endif /* !CONFIG_IPIPE */
216 221
217static inline void raw_local_irq_restore(unsigned long flags) 222/*
218{ 223 * Raw interface to linux/irqflags.h.
219 if (!raw_irqs_disabled_flags(flags)) 224 */
220 raw_local_irq_enable(); 225#define raw_local_save_flags(flags) do { (flags) = arch_local_save_flags(); } while (0)
221} 226#define raw_local_irq_save(flags) do { (flags) = arch_local_irq_save(); } while (0)
227#define raw_local_irq_restore(flags) arch_local_irq_restore(flags)
228#define raw_local_irq_enable() arch_local_irq_enable()
229#define raw_local_irq_disable() arch_local_irq_disable()
230#define raw_irqs_disabled_flags(flags) arch_irqs_disabled_flags(flags)
231#define raw_irqs_disabled() arch_irqs_disabled()
222 232
223#endif 233#endif