blob: 43908146a5cf05c473967d603247a792f73b5663 [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
Daniel Thompson6fb18ac2015-06-10 12:25:15 +010023#define arch_local_irq_save arch_local_irq_save
David Howellsdf9ee292010-10-07 14:08:55 +010024static inline unsigned long arch_local_irq_save(void)
25{
26 unsigned long flags;
Russell King7ad1bcb2006-08-27 12:07:02 +010027
David Howellsdf9ee292010-10-07 14:08:55 +010028 asm volatile(
Catalin Marinas55bdd692010-05-21 18:06:41 +010029 " mrs %0, " IRQMASK_REG_NAME_R " @ arch_local_irq_save\n"
David Howellsdf9ee292010-10-07 14:08:55 +010030 " cpsid i"
31 : "=r" (flags) : : "memory", "cc");
32 return flags;
33}
34
Daniel Thompson6fb18ac2015-06-10 12:25:15 +010035#define arch_local_irq_enable arch_local_irq_enable
David Howellsdf9ee292010-10-07 14:08:55 +010036static inline void arch_local_irq_enable(void)
37{
38 asm volatile(
39 " cpsie i @ arch_local_irq_enable"
40 :
41 :
42 : "memory", "cc");
43}
44
Daniel Thompson6fb18ac2015-06-10 12:25:15 +010045#define arch_local_irq_disable arch_local_irq_disable
David Howellsdf9ee292010-10-07 14:08:55 +010046static inline void arch_local_irq_disable(void)
47{
48 asm volatile(
49 " cpsid i @ arch_local_irq_disable"
50 :
51 :
52 : "memory", "cc");
53}
54
Russell King7ad1bcb2006-08-27 12:07:02 +010055#define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc")
56#define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc")
Russell King7ad1bcb2006-08-27 12:07:02 +010057#else
58
59/*
60 * Save the current interrupt enable state & disable IRQs
61 */
Daniel Thompson6fb18ac2015-06-10 12:25:15 +010062#define arch_local_irq_save arch_local_irq_save
David Howellsdf9ee292010-10-07 14:08:55 +010063static inline unsigned long arch_local_irq_save(void)
64{
65 unsigned long flags, temp;
66
67 asm volatile(
68 " mrs %0, cpsr @ arch_local_irq_save\n"
69 " orr %1, %0, #128\n"
70 " msr cpsr_c, %1"
71 : "=r" (flags), "=r" (temp)
72 :
73 : "memory", "cc");
74 return flags;
75}
76
Russell King7ad1bcb2006-08-27 12:07:02 +010077/*
78 * Enable IRQs
79 */
Daniel Thompson6fb18ac2015-06-10 12:25:15 +010080#define arch_local_irq_enable arch_local_irq_enable
David Howellsdf9ee292010-10-07 14:08:55 +010081static inline void arch_local_irq_enable(void)
82{
83 unsigned long temp;
84 asm volatile(
85 " mrs %0, cpsr @ arch_local_irq_enable\n"
86 " bic %0, %0, #128\n"
87 " msr cpsr_c, %0"
88 : "=r" (temp)
89 :
90 : "memory", "cc");
91}
Russell King7ad1bcb2006-08-27 12:07:02 +010092
93/*
94 * Disable IRQs
95 */
Daniel Thompson6fb18ac2015-06-10 12:25:15 +010096#define arch_local_irq_disable arch_local_irq_disable
David Howellsdf9ee292010-10-07 14:08:55 +010097static inline void arch_local_irq_disable(void)
98{
99 unsigned long temp;
100 asm volatile(
101 " mrs %0, cpsr @ arch_local_irq_disable\n"
102 " orr %0, %0, #128\n"
103 " msr cpsr_c, %0"
104 : "=r" (temp)
105 :
106 : "memory", "cc");
107}
Russell King7ad1bcb2006-08-27 12:07:02 +0100108
109/*
110 * Enable FIQs
111 */
112#define local_fiq_enable() \
113 ({ \
114 unsigned long temp; \
115 __asm__ __volatile__( \
116 "mrs %0, cpsr @ stf\n" \
117" bic %0, %0, #64\n" \
118" msr cpsr_c, %0" \
119 : "=r" (temp) \
120 : \
121 : "memory", "cc"); \
122 })
123
124/*
125 * Disable FIQs
126 */
127#define local_fiq_disable() \
128 ({ \
129 unsigned long temp; \
130 __asm__ __volatile__( \
131 "mrs %0, cpsr @ clf\n" \
132" orr %0, %0, #64\n" \
133" msr cpsr_c, %0" \
134 : "=r" (temp) \
135 : \
136 : "memory", "cc"); \
137 })
138
139#endif
140
141/*
142 * Save the current interrupt enable state.
143 */
Daniel Thompson6fb18ac2015-06-10 12:25:15 +0100144#define arch_local_save_flags arch_local_save_flags
David Howellsdf9ee292010-10-07 14:08:55 +0100145static inline unsigned long arch_local_save_flags(void)
146{
147 unsigned long flags;
148 asm volatile(
Catalin Marinas55bdd692010-05-21 18:06:41 +0100149 " mrs %0, " IRQMASK_REG_NAME_R " @ local_save_flags"
David Howellsdf9ee292010-10-07 14:08:55 +0100150 : "=r" (flags) : : "memory", "cc");
151 return flags;
152}
Russell King7ad1bcb2006-08-27 12:07:02 +0100153
154/*
155 * restore saved IRQ & FIQ state
156 */
Daniel Thompson6fb18ac2015-06-10 12:25:15 +0100157#define arch_local_irq_restore arch_local_irq_restore
David Howellsdf9ee292010-10-07 14:08:55 +0100158static inline void arch_local_irq_restore(unsigned long flags)
159{
160 asm volatile(
Catalin Marinas55bdd692010-05-21 18:06:41 +0100161 " msr " IRQMASK_REG_NAME_W ", %0 @ local_irq_restore"
David Howellsdf9ee292010-10-07 14:08:55 +0100162 :
163 : "r" (flags)
164 : "memory", "cc");
165}
Russell King7ad1bcb2006-08-27 12:07:02 +0100166
Daniel Thompson6fb18ac2015-06-10 12:25:15 +0100167#define arch_irqs_disabled_flags arch_irqs_disabled_flags
David Howellsdf9ee292010-10-07 14:08:55 +0100168static inline int arch_irqs_disabled_flags(unsigned long flags)
169{
Catalin Marinas55bdd692010-05-21 18:06:41 +0100170 return flags & IRQMASK_I_BIT;
David Howellsdf9ee292010-10-07 14:08:55 +0100171}
Russell King7ad1bcb2006-08-27 12:07:02 +0100172
Daniel Thompson6fb18ac2015-06-10 12:25:15 +0100173#include <asm-generic/irqflags.h>
174
Catalin Marinas55bdd692010-05-21 18:06:41 +0100175#endif /* ifdef __KERNEL__ */
176#endif /* ifndef __ASM_ARM_IRQFLAGS_H */