blob: f3ed93144e23e1eaeceb333a507a04af1c8b8aac [file] [log] [blame]
Mike Frysinger8f860012009-06-08 12:49:48 -04001/*
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
David Howells5c748742010-10-07 14:08:51 +010011#include <mach/blackfin.h>
12
Mike Frysinger8f860012009-06-08 12:49:48 -040013#ifdef CONFIG_SMP
14# include <asm/pda.h>
15# include <asm/processor.h>
16/* Forward decl needed due to cdef inter dependencies */
17static 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
21extern unsigned long bfin_irq_flags;
22#endif
23
24static inline void bfin_sti(unsigned long flags)
25{
26 asm volatile("sti %0;" : : "d" (flags));
27}
28
29static inline unsigned long bfin_cli(void)
30{
31 unsigned long flags;
32 asm volatile("cli %0;" : "=d" (flags));
33 return flags;
34}
35
Philippe Gerum06ecc192009-06-16 05:25:37 +020036#ifdef CONFIG_IPIPE
37
Philippe Gerum7d4a0052009-10-27 22:05:32 +010038#include <linux/compiler.h>
Philippe Gerum06ecc192009-06-16 05:25:37 +020039#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
Philippe Gerum7d4a0052009-10-27 22:05:32 +010055#define raw_local_irq_enable() \
56 do { \
57 barrier(); \
58 ipipe_check_context(ipipe_root_domain); \
59 __ipipe_unstall_root(); \
60 } while (0)
Philippe Gerum06ecc192009-06-16 05:25:37 +020061
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
83static 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
92static 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
99static inline void local_irq_disable_hw_notrace(void)
100{
101 bfin_cli();
102}
103
104static 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
123static 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
136static 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
Mike Frysinger8f860012009-06-08 12:49:48 -0400181static inline void raw_local_irq_disable(void)
182{
183 bfin_cli();
184}
185static inline void raw_local_irq_enable(void)
186{
187 bfin_sti(bfin_irq_flags);
188}
189
David Howells5c748742010-10-07 14:08:51 +0100190static 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)
Mike Frysinger8f860012009-06-08 12:49:48 -0400196
197#define raw_irqs_disabled_flags(flags) (((flags) & ~0x3f) == 0)
198
Mike Frysinger8f860012009-06-08 12:49:48 -0400199static 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
Philippe Gerum06ecc192009-06-16 05:25:37 +0200209#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
217static inline void raw_local_irq_restore(unsigned long flags)
218{
219 if (!raw_irqs_disabled_flags(flags))
220 raw_local_irq_enable();
221}
222
Mike Frysinger8f860012009-06-08 12:49:48 -0400223#endif