Merge branch 'fix/hda' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
[pandora-kernel.git] / arch / x86 / include / asm / irqflags.h
1 #ifndef _X86_IRQFLAGS_H_
2 #define _X86_IRQFLAGS_H_
3
4 #include <asm/processor-flags.h>
5
6 #ifndef __ASSEMBLY__
7 /*
8  * Interrupt control:
9  */
10
11 static inline unsigned long native_save_fl(void)
12 {
13         unsigned long flags;
14
15         /*
16          * Note: this needs to be "=r" not "=rm", because we have the
17          * stack offset from what gcc expects at the time the "pop" is
18          * executed, and so a memory reference with respect to the stack
19          * would end up using the wrong address.
20          */
21         asm volatile("# __raw_save_flags\n\t"
22                      "pushf ; pop %0"
23                      : "=r" (flags)
24                      : /* no input */
25                      : "memory");
26
27         return flags;
28 }
29
30 static inline void native_restore_fl(unsigned long flags)
31 {
32         asm volatile("push %0 ; popf"
33                      : /* no output */
34                      :"g" (flags)
35                      :"memory", "cc");
36 }
37
38 static inline void native_irq_disable(void)
39 {
40         asm volatile("cli": : :"memory");
41 }
42
43 static inline void native_irq_enable(void)
44 {
45         asm volatile("sti": : :"memory");
46 }
47
48 static inline void native_safe_halt(void)
49 {
50         asm volatile("sti; hlt": : :"memory");
51 }
52
53 static inline void native_halt(void)
54 {
55         asm volatile("hlt": : :"memory");
56 }
57
58 #endif
59
60 #ifdef CONFIG_PARAVIRT
61 #include <asm/paravirt.h>
62 #else
63 #ifndef __ASSEMBLY__
64
65 static inline unsigned long __raw_local_save_flags(void)
66 {
67         return native_save_fl();
68 }
69
70 static inline void raw_local_irq_restore(unsigned long flags)
71 {
72         native_restore_fl(flags);
73 }
74
75 static inline void raw_local_irq_disable(void)
76 {
77         native_irq_disable();
78 }
79
80 static inline void raw_local_irq_enable(void)
81 {
82         native_irq_enable();
83 }
84
85 /*
86  * Used in the idle loop; sti takes one instruction cycle
87  * to complete:
88  */
89 static inline void raw_safe_halt(void)
90 {
91         native_safe_halt();
92 }
93
94 /*
95  * Used when interrupts are already enabled or to
96  * shutdown the processor:
97  */
98 static inline void halt(void)
99 {
100         native_halt();
101 }
102
103 /*
104  * For spinlocks, etc:
105  */
106 static inline unsigned long __raw_local_irq_save(void)
107 {
108         unsigned long flags = __raw_local_save_flags();
109
110         raw_local_irq_disable();
111
112         return flags;
113 }
114 #else
115
116 #define ENABLE_INTERRUPTS(x)    sti
117 #define DISABLE_INTERRUPTS(x)   cli
118
119 #ifdef CONFIG_X86_64
120 #define SWAPGS  swapgs
121 /*
122  * Currently paravirt can't handle swapgs nicely when we
123  * don't have a stack we can rely on (such as a user space
124  * stack).  So we either find a way around these or just fault
125  * and emulate if a guest tries to call swapgs directly.
126  *
127  * Either way, this is a good way to document that we don't
128  * have a reliable stack. x86_64 only.
129  */
130 #define SWAPGS_UNSAFE_STACK     swapgs
131
132 #define PARAVIRT_ADJUST_EXCEPTION_FRAME /*  */
133
134 #define INTERRUPT_RETURN        iretq
135 #define USERGS_SYSRET64                         \
136         swapgs;                                 \
137         sysretq;
138 #define USERGS_SYSRET32                         \
139         swapgs;                                 \
140         sysretl
141 #define ENABLE_INTERRUPTS_SYSEXIT32             \
142         swapgs;                                 \
143         sti;                                    \
144         sysexit
145
146 #else
147 #define INTERRUPT_RETURN                iret
148 #define ENABLE_INTERRUPTS_SYSEXIT       sti; sysexit
149 #define GET_CR0_INTO_EAX                movl %cr0, %eax
150 #endif
151
152
153 #endif /* __ASSEMBLY__ */
154 #endif /* CONFIG_PARAVIRT */
155
156 #ifndef __ASSEMBLY__
157 #define raw_local_save_flags(flags)                             \
158         do { (flags) = __raw_local_save_flags(); } while (0)
159
160 #define raw_local_irq_save(flags)                               \
161         do { (flags) = __raw_local_irq_save(); } while (0)
162
163 static inline int raw_irqs_disabled_flags(unsigned long flags)
164 {
165         return !(flags & X86_EFLAGS_IF);
166 }
167
168 static inline int raw_irqs_disabled(void)
169 {
170         unsigned long flags = __raw_local_save_flags();
171
172         return raw_irqs_disabled_flags(flags);
173 }
174
175 #else
176
177 #ifdef CONFIG_X86_64
178 #define ARCH_LOCKDEP_SYS_EXIT           call lockdep_sys_exit_thunk
179 #define ARCH_LOCKDEP_SYS_EXIT_IRQ       \
180         TRACE_IRQS_ON; \
181         sti; \
182         SAVE_REST; \
183         LOCKDEP_SYS_EXIT; \
184         RESTORE_REST; \
185         cli; \
186         TRACE_IRQS_OFF;
187
188 #else
189 #define ARCH_LOCKDEP_SYS_EXIT                   \
190         pushl %eax;                             \
191         pushl %ecx;                             \
192         pushl %edx;                             \
193         call lockdep_sys_exit;                  \
194         popl %edx;                              \
195         popl %ecx;                              \
196         popl %eax;
197
198 #define ARCH_LOCKDEP_SYS_EXIT_IRQ
199 #endif
200
201 #ifdef CONFIG_TRACE_IRQFLAGS
202 #  define TRACE_IRQS_ON         call trace_hardirqs_on_thunk;
203 #  define TRACE_IRQS_OFF        call trace_hardirqs_off_thunk;
204 #else
205 #  define TRACE_IRQS_ON
206 #  define TRACE_IRQS_OFF
207 #endif
208 #ifdef CONFIG_DEBUG_LOCK_ALLOC
209 #  define LOCKDEP_SYS_EXIT      ARCH_LOCKDEP_SYS_EXIT
210 #  define LOCKDEP_SYS_EXIT_IRQ  ARCH_LOCKDEP_SYS_EXIT_IRQ
211 # else
212 #  define LOCKDEP_SYS_EXIT
213 #  define LOCKDEP_SYS_EXIT_IRQ
214 # endif
215
216 #endif /* __ASSEMBLY__ */
217 #endif