Commit | Line | Data |
---|---|---|
df9ee292 DH |
1 | /* |
2 | * Xtensa IRQ flags handling functions | |
3 | * | |
4 | * This file is subject to the terms and conditions of the GNU General Public | |
5 | * License. See the file "COPYING" in the main directory of this archive | |
6 | * for more details. | |
7 | * | |
8 | * Copyright (C) 2001 - 2005 Tensilica Inc. | |
38fef73c | 9 | * Copyright (C) 2015 Cadence Design Systems Inc. |
df9ee292 DH |
10 | */ |
11 | ||
12 | #ifndef _XTENSA_IRQFLAGS_H | |
13 | #define _XTENSA_IRQFLAGS_H | |
14 | ||
15 | #include <linux/types.h> | |
16 | ||
17 | static inline unsigned long arch_local_save_flags(void) | |
18 | { | |
19 | unsigned long flags; | |
bc5378fc | 20 | asm volatile("rsr %0, ps" : "=a" (flags)); |
df9ee292 DH |
21 | return flags; |
22 | } | |
23 | ||
24 | static inline unsigned long arch_local_irq_save(void) | |
25 | { | |
26 | unsigned long flags; | |
38fef73c MF |
27 | #if XTENSA_FAKE_NMI |
28 | #if defined(CONFIG_DEBUG_KERNEL) && (LOCKLEVEL | TOPLEVEL) >= XCHAL_DEBUGLEVEL | |
29 | unsigned long tmp; | |
30 | ||
31 | asm volatile("rsr %0, ps\t\n" | |
32 | "extui %1, %0, 0, 4\t\n" | |
33 | "bgei %1, "__stringify(LOCKLEVEL)", 1f\t\n" | |
34 | "rsil %0, "__stringify(LOCKLEVEL)"\n" | |
35 | "1:" | |
36 | : "=a" (flags), "=a" (tmp) :: "memory"); | |
37 | #else | |
38 | asm volatile("rsr %0, ps\t\n" | |
39 | "or %0, %0, %1\t\n" | |
40 | "xsr %0, ps\t\n" | |
41 | "rsync" | |
42 | : "=&a" (flags) : "a" (LOCKLEVEL) : "memory"); | |
43 | #endif | |
44 | #else | |
45 | asm volatile("rsil %0, "__stringify(LOCKLEVEL) | |
df9ee292 | 46 | : "=a" (flags) :: "memory"); |
38fef73c | 47 | #endif |
df9ee292 DH |
48 | return flags; |
49 | } | |
50 | ||
51 | static inline void arch_local_irq_disable(void) | |
52 | { | |
53 | arch_local_irq_save(); | |
54 | } | |
55 | ||
56 | static inline void arch_local_irq_enable(void) | |
57 | { | |
58 | unsigned long flags; | |
59 | asm volatile("rsil %0, 0" : "=a" (flags) :: "memory"); | |
60 | } | |
61 | ||
62 | static inline void arch_local_irq_restore(unsigned long flags) | |
63 | { | |
bc5378fc | 64 | asm volatile("wsr %0, ps; rsync" |
df9ee292 DH |
65 | :: "a" (flags) : "memory"); |
66 | } | |
67 | ||
68 | static inline bool arch_irqs_disabled_flags(unsigned long flags) | |
69 | { | |
031d0112 MF |
70 | #if XCHAL_EXCM_LEVEL < LOCKLEVEL || (1 << PS_EXCM_BIT) < LOCKLEVEL |
71 | #error "XCHAL_EXCM_LEVEL and 1<<PS_EXCM_BIT must be no less than LOCKLEVEL" | |
72 | #endif | |
73 | return (flags & (PS_INTLEVEL_MASK | (1 << PS_EXCM_BIT))) >= LOCKLEVEL; | |
df9ee292 DH |
74 | } |
75 | ||
76 | static inline bool arch_irqs_disabled(void) | |
77 | { | |
78 | return arch_irqs_disabled_flags(arch_local_save_flags()); | |
79 | } | |
80 | ||
81 | #endif /* _XTENSA_IRQFLAGS_H */ |