]> git.karo-electronics.de Git - mv-sheeva.git/blob - arch/blackfin/include/asm/irqflags.h
f3ed93144e23e1eaeceb333a507a04af1c8b8aac
[mv-sheeva.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 #include <mach/blackfin.h>
12
13 #ifdef CONFIG_SMP
14 # include <asm/pda.h>
15 # include <asm/processor.h>
16 /* Forward decl needed due to cdef inter dependencies */
17 static inline uint32_t __pure bfin_dspid(void);
18 # define blackfin_core_id() (bfin_dspid() & 0xff)
19 # define bfin_irq_flags cpu_pda[blackfin_core_id()].imask
20 #else
21 extern unsigned long bfin_irq_flags;
22 #endif
23
24 static inline void bfin_sti(unsigned long flags)
25 {
26         asm volatile("sti %0;" : : "d" (flags));
27 }
28
29 static inline unsigned long bfin_cli(void)
30 {
31         unsigned long flags;
32         asm volatile("cli %0;" : "=d" (flags));
33         return flags;
34 }
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
43 # define bfin_no_irqs 0x3f
44 #else
45 # define bfin_no_irqs 0x1f
46 #endif
47
48 #define raw_local_irq_disable()                         \
49         do {                                            \
50                 ipipe_check_context(ipipe_root_domain); \
51                 __ipipe_stall_root();                   \
52                 barrier();                              \
53         } while (0)
54
55 #define raw_local_irq_enable()                          \
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
77 #define raw_local_irq_save(x)                           \
78         do {                                            \
79                 ipipe_check_context(ipipe_root_domain); \
80                 raw_local_irq_save_ptr(&(x));           \
81         } while (0)
82
83 static inline unsigned long raw_mangle_irq_bits(int virt, unsigned long real)
84 {
85         /*
86          * Merge virtual and real interrupt mask bits into a single
87          * 32bit word.
88          */
89         return (real & ~(1 << 31)) | ((virt != 0) << 31);
90 }
91
92 static inline int raw_demangle_irq_bits(unsigned long *x)
93 {
94         int virt = (*x & (1 << 31)) != 0;
95         *x &= ~(1L << 31);
96         return virt;
97 }
98
99 static inline void local_irq_disable_hw_notrace(void)
100 {
101         bfin_cli();
102 }
103
104 static inline void local_irq_enable_hw_notrace(void)
105 {
106         bfin_sti(bfin_irq_flags);
107 }
108
109 #define local_save_flags_hw(flags)                      \
110         do {                                            \
111                 (flags) = bfin_read_IMASK();            \
112         } while (0)
113
114 #define irqs_disabled_flags_hw(flags) (((flags) & ~0x3f) == 0)
115
116 #define irqs_disabled_hw()                      \
117         ({                                      \
118         unsigned long flags;                    \
119         local_save_flags_hw(flags);             \
120         irqs_disabled_flags_hw(flags);          \
121         })
122
123 static inline void local_irq_save_ptr_hw(unsigned long *flags)
124 {
125         *flags = bfin_cli();
126 #ifdef CONFIG_DEBUG_HWERR
127         bfin_sti(0x3f);
128 #endif
129 }
130
131 #define local_irq_save_hw_notrace(flags)                \
132         do {                                            \
133                 local_irq_save_ptr_hw(&(flags));        \
134         } while (0)
135
136 static inline void local_irq_restore_hw_notrace(unsigned long flags)
137 {
138         if (!irqs_disabled_flags_hw(flags))
139                 local_irq_enable_hw_notrace();
140 }
141
142 #ifdef CONFIG_IPIPE_TRACE_IRQSOFF
143 # define local_irq_disable_hw()                         \
144         do {                                            \
145                 if (!irqs_disabled_hw()) {              \
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
179 #else /* CONFIG_IPIPE */
180
181 static inline void raw_local_irq_disable(void)
182 {
183         bfin_cli();
184 }
185 static inline void raw_local_irq_enable(void)
186 {
187         bfin_sti(bfin_irq_flags);
188 }
189
190 static inline unsigned long arch_local_save_flags(void)
191 {
192         return bfin_read_IMASK();
193 }
194
195 #define raw_local_save_flags(flags) do { (flags) = arch_local_save_flags(); } while (0)
196
197 #define raw_irqs_disabled_flags(flags) (((flags) & ~0x3f) == 0)
198
199 static inline unsigned long __raw_local_irq_save(void)
200 {
201         unsigned long flags = bfin_cli();
202 #ifdef CONFIG_DEBUG_HWERR
203         bfin_sti(0x3f);
204 #endif
205         return flags;
206 }
207 #define raw_local_irq_save(flags) do { (flags) = __raw_local_irq_save(); } while (0)
208
209 #define local_irq_save_hw(flags)        raw_local_irq_save(flags)
210 #define local_irq_restore_hw(flags)     raw_local_irq_restore(flags)
211 #define local_irq_enable_hw()           raw_local_irq_enable()
212 #define local_irq_disable_hw()          raw_local_irq_disable()
213 #define irqs_disabled_hw()              irqs_disabled()
214
215 #endif /* !CONFIG_IPIPE */
216
217 static inline void raw_local_irq_restore(unsigned long flags)
218 {
219         if (!raw_irqs_disabled_flags(flags))
220                 raw_local_irq_enable();
221 }
222
223 #endif