Merge branch 'upstream/wm8974' into for-2.6.33
[pandora-kernel.git] / arch / blackfin / include / asm / irqflags.h
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
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
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
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
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
215 #endif