GNU Linux-libre 4.19.211-gnu1
[releases.git] / arch / arm64 / include / asm / irqflags.h
1 /*
2  * Copyright (C) 2012 ARM Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16 #ifndef __ASM_IRQFLAGS_H
17 #define __ASM_IRQFLAGS_H
18
19 #ifdef __KERNEL__
20
21 #include <asm/ptrace.h>
22
23 /*
24  * Aarch64 has flags for masking: Debug, Asynchronous (serror), Interrupts and
25  * FIQ exceptions, in the 'daif' register. We mask and unmask them in 'dai'
26  * order:
27  * Masking debug exceptions causes all other exceptions to be masked too/
28  * Masking SError masks irq, but not debug exceptions. Masking irqs has no
29  * side effects for other flags. Keeping to this order makes it easier for
30  * entry.S to know which exceptions should be unmasked.
31  *
32  * FIQ is never expected, but we mask it when we disable debug exceptions, and
33  * unmask it at all other times.
34  */
35
36 /*
37  * CPU interrupt mask handling.
38  */
39 static inline unsigned long arch_local_irq_save(void)
40 {
41         unsigned long flags;
42         asm volatile(
43                 "mrs    %0, daif                // arch_local_irq_save\n"
44                 "msr    daifset, #2"
45                 : "=r" (flags)
46                 :
47                 : "memory");
48         return flags;
49 }
50
51 static inline void arch_local_irq_enable(void)
52 {
53         asm volatile(
54                 "msr    daifclr, #2             // arch_local_irq_enable"
55                 :
56                 :
57                 : "memory");
58 }
59
60 static inline void arch_local_irq_disable(void)
61 {
62         asm volatile(
63                 "msr    daifset, #2             // arch_local_irq_disable"
64                 :
65                 :
66                 : "memory");
67 }
68
69 /*
70  * Save the current interrupt enable state.
71  */
72 static inline unsigned long arch_local_save_flags(void)
73 {
74         unsigned long flags;
75         asm volatile(
76                 "mrs    %0, daif                // arch_local_save_flags"
77                 : "=r" (flags)
78                 :
79                 : "memory");
80         return flags;
81 }
82
83 /*
84  * restore saved IRQ state
85  */
86 static inline void arch_local_irq_restore(unsigned long flags)
87 {
88         asm volatile(
89                 "msr    daif, %0                // arch_local_irq_restore"
90         :
91         : "r" (flags)
92         : "memory");
93 }
94
95 static inline int arch_irqs_disabled_flags(unsigned long flags)
96 {
97         return flags & PSR_I_BIT;
98 }
99 #endif
100 #endif