Merge tag 'nios2-v5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/lftan...
[linux-2.6-block.git] / arch / arm64 / include / asm / daifflags.h
1 /*
2  * Copyright (C) 2017 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_DAIFFLAGS_H
17 #define __ASM_DAIFFLAGS_H
18
19 #include <linux/irqflags.h>
20
21 #define DAIF_PROCCTX            0
22 #define DAIF_PROCCTX_NOIRQ      PSR_I_BIT
23 #define DAIF_ERRCTX             (PSR_I_BIT | PSR_A_BIT)
24
25 /* mask/save/unmask/restore all exceptions, including interrupts. */
26 static inline void local_daif_mask(void)
27 {
28         asm volatile(
29                 "msr    daifset, #0xf           // local_daif_mask\n"
30                 :
31                 :
32                 : "memory");
33         trace_hardirqs_off();
34 }
35
36 static inline unsigned long local_daif_save(void)
37 {
38         unsigned long flags;
39
40         flags = arch_local_save_flags();
41
42         local_daif_mask();
43
44         return flags;
45 }
46
47 static inline void local_daif_unmask(void)
48 {
49         trace_hardirqs_on();
50         asm volatile(
51                 "msr    daifclr, #0xf           // local_daif_unmask"
52                 :
53                 :
54                 : "memory");
55 }
56
57 static inline void local_daif_restore(unsigned long flags)
58 {
59         if (!arch_irqs_disabled_flags(flags))
60                 trace_hardirqs_on();
61
62         arch_local_irq_restore(flags);
63
64         if (arch_irqs_disabled_flags(flags))
65                 trace_hardirqs_off();
66 }
67
68 #endif