blob: 3b763d6652a0aee4ba7a81bc591715c2084d1b10 [file] [log] [blame]
Russell King7ad1bcb2006-08-27 12:07:02 +01001#ifndef __ASM_ARM_IRQFLAGS_H
2#define __ASM_ARM_IRQFLAGS_H
3
4#ifdef __KERNEL__
5
6#include <asm/ptrace.h>
7
8/*
9 * CPU interrupt mask handling.
10 */
Catalin Marinas55bdd692010-05-21 18:06:41 +010011#ifdef CONFIG_CPU_V7M
12#define IRQMASK_REG_NAME_R "primask"
13#define IRQMASK_REG_NAME_W "primask"
14#define IRQMASK_I_BIT 1
15#else
16#define IRQMASK_REG_NAME_R "cpsr"
17#define IRQMASK_REG_NAME_W "cpsr_c"
18#define IRQMASK_I_BIT PSR_I_BIT
19#endif
20
Russell King7ad1bcb2006-08-27 12:07:02 +010021#if __LINUX_ARM_ARCH__ >= 6
22
David Howellsdf9ee292010-10-07 14:08:55 +010023static inline unsigned long arch_local_irq_save(void)
24{
25 unsigned long flags;
Russell King7ad1bcb2006-08-27 12:07:02 +010026
David Howellsdf9ee292010-10-07 14:08:55 +010027 asm volatile(
Catalin Marinas55bdd692010-05-21 18:06:41 +010028 " mrs %0, " IRQMASK_REG_NAME_R " @ arch_local_irq_save\n"
David Howellsdf9ee292010-10-07 14:08:55 +010029 " cpsid i"
30 : "=r" (flags) : : "memory", "cc");
31 return flags;
32}
33
34static inline void arch_local_irq_enable(void)
35{
36 asm volatile(
37 " cpsie i @ arch_local_irq_enable"
38 :
39 :
40 : "memory", "cc");
41}
42
43static inline void arch_local_irq_disable(void)
44{
45 asm volatile(
46 " cpsid i @ arch_local_irq_disable"
47 :
48 :
49 : "memory", "cc");
50}
51
Russell King7ad1bcb2006-08-27 12:07:02 +010052#define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc")
53#define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc")
Russell King7ad1bcb2006-08-27 12:07:02 +010054#else
55
56/*
57 * Save the current interrupt enable state & disable IRQs
58 */
David Howellsdf9ee292010-10-07 14:08:55 +010059static inline unsigned long arch_local_irq_save(void)
60{
61 unsigned long flags, temp;
62
63 asm volatile(
64 " mrs %0, cpsr @ arch_local_irq_save\n"
65 " orr %1, %0, #128\n"
66 " msr cpsr_c, %1"
67 : "=r" (flags), "=r" (temp)
68 :
69 : "memory", "cc");
70 return flags;
71}
72
Russell King7ad1bcb2006-08-27 12:07:02 +010073/*
74 * Enable IRQs
75 */
David Howellsdf9ee292010-10-07 14:08:55 +010076static inline void arch_local_irq_enable(void)
77{
78 unsigned long temp;
79 asm volatile(
80 " mrs %0, cpsr @ arch_local_irq_enable\n"
81 " bic %0, %0, #128\n"
82 " msr cpsr_c, %0"
83 : "=r" (temp)
84 :
85 : "memory", "cc");
86}
Russell King7ad1bcb2006-08-27 12:07:02 +010087
88/*
89 * Disable IRQs
90 */
David Howellsdf9ee292010-10-07 14:08:55 +010091static inline void arch_local_irq_disable(void)
92{
93 unsigned long temp;
94 asm volatile(
95 " mrs %0, cpsr @ arch_local_irq_disable\n"
96 " orr %0, %0, #128\n"
97 " msr cpsr_c, %0"
98 : "=r" (temp)
99 :
100 : "memory", "cc");
101}
Russell King7ad1bcb2006-08-27 12:07:02 +0100102
103/*
104 * Enable FIQs
105 */
106#define local_fiq_enable() \
107 ({ \
108 unsigned long temp; \
109 __asm__ __volatile__( \
110 "mrs %0, cpsr @ stf\n" \
111" bic %0, %0, #64\n" \
112" msr cpsr_c, %0" \
113 : "=r" (temp) \
114 : \
115 : "memory", "cc"); \
116 })
117
118/*
119 * Disable FIQs
120 */
121#define local_fiq_disable() \
122 ({ \
123 unsigned long temp; \
124 __asm__ __volatile__( \
125 "mrs %0, cpsr @ clf\n" \
126" orr %0, %0, #64\n" \
127" msr cpsr_c, %0" \
128 : "=r" (temp) \
129 : \
130 : "memory", "cc"); \
131 })
132
133#endif
134
135/*
136 * Save the current interrupt enable state.
137 */
David Howellsdf9ee292010-10-07 14:08:55 +0100138static inline unsigned long arch_local_save_flags(void)
139{
140 unsigned long flags;
141 asm volatile(
Catalin Marinas55bdd692010-05-21 18:06:41 +0100142 " mrs %0, " IRQMASK_REG_NAME_R " @ local_save_flags"
David Howellsdf9ee292010-10-07 14:08:55 +0100143 : "=r" (flags) : : "memory", "cc");
144 return flags;
145}
Russell King7ad1bcb2006-08-27 12:07:02 +0100146
147/*
148 * restore saved IRQ & FIQ state
149 */
David Howellsdf9ee292010-10-07 14:08:55 +0100150static inline void arch_local_irq_restore(unsigned long flags)
151{
152 asm volatile(
Catalin Marinas55bdd692010-05-21 18:06:41 +0100153 " msr " IRQMASK_REG_NAME_W ", %0 @ local_irq_restore"
David Howellsdf9ee292010-10-07 14:08:55 +0100154 :
155 : "r" (flags)
156 : "memory", "cc");
157}
Russell King7ad1bcb2006-08-27 12:07:02 +0100158
David Howellsdf9ee292010-10-07 14:08:55 +0100159static inline int arch_irqs_disabled_flags(unsigned long flags)
160{
Catalin Marinas55bdd692010-05-21 18:06:41 +0100161 return flags & IRQMASK_I_BIT;
David Howellsdf9ee292010-10-07 14:08:55 +0100162}
Russell King7ad1bcb2006-08-27 12:07:02 +0100163
Catalin Marinas55bdd692010-05-21 18:06:41 +0100164#endif /* ifdef __KERNEL__ */
165#endif /* ifndef __ASM_ARM_IRQFLAGS_H */