Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
1f194a4c | 2 | /* |
a53c8fab | 3 | * Copyright IBM Corp. 2006, 2010 |
428aecf6 | 4 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> |
1f194a4c HC |
5 | */ |
6 | ||
7 | #ifndef __ASM_IRQFLAGS_H | |
8 | #define __ASM_IRQFLAGS_H | |
9 | ||
428aecf6 | 10 | #include <linux/types.h> |
1f194a4c | 11 | |
204ee2c5 CB |
12 | #define ARCH_IRQ_ENABLED (3UL << (BITS_PER_LONG - 8)) |
13 | ||
df9ee292 DH |
14 | /* store then OR system mask. */ |
15 | #define __arch_local_irq_stosm(__or) \ | |
94c12cc7 MS |
16 | ({ \ |
17 | unsigned long __mask; \ | |
18 | asm volatile( \ | |
19 | " stosm %0,%1" \ | |
20 | : "=Q" (__mask) : "i" (__or) : "memory"); \ | |
21 | __mask; \ | |
22 | }) | |
23 | ||
df9ee292 DH |
24 | /* store then AND system mask. */ |
25 | #define __arch_local_irq_stnsm(__and) \ | |
94c12cc7 MS |
26 | ({ \ |
27 | unsigned long __mask; \ | |
28 | asm volatile( \ | |
29 | " stnsm %0,%1" \ | |
30 | : "=Q" (__mask) : "i" (__and) : "memory"); \ | |
31 | __mask; \ | |
32 | }) | |
33 | ||
34 | /* set system mask. */ | |
4aca3ab4 | 35 | static __always_inline void __arch_local_irq_ssm(unsigned long flags) |
df9ee292 DH |
36 | { |
37 | asm volatile("ssm %0" : : "Q" (flags) : "memory"); | |
38 | } | |
94c12cc7 | 39 | |
1b301f5f IL |
40 | #ifdef CONFIG_KMSAN |
41 | #define arch_local_irq_attributes noinline notrace __no_sanitize_memory __maybe_unused | |
42 | #else | |
43 | #define arch_local_irq_attributes __always_inline | |
44 | #endif | |
45 | ||
46 | static arch_local_irq_attributes unsigned long arch_local_save_flags(void) | |
94c12cc7 | 47 | { |
81fc77fb | 48 | return __arch_local_irq_stnsm(0xff); |
94c12cc7 | 49 | } |
63f4f9e1 | 50 | |
1b301f5f | 51 | static arch_local_irq_attributes unsigned long arch_local_irq_save(void) |
94c12cc7 | 52 | { |
df9ee292 | 53 | return __arch_local_irq_stnsm(0xfc); |
94c12cc7 MS |
54 | } |
55 | ||
4aca3ab4 | 56 | static __always_inline void arch_local_irq_disable(void) |
df9ee292 DH |
57 | { |
58 | arch_local_irq_save(); | |
59 | } | |
1f194a4c | 60 | |
1b301f5f IL |
61 | static arch_local_irq_attributes void arch_local_irq_enable_external(void) |
62 | { | |
63 | __arch_local_irq_stosm(0x01); | |
64 | } | |
65 | ||
66 | static arch_local_irq_attributes void arch_local_irq_enable(void) | |
94c12cc7 | 67 | { |
df9ee292 | 68 | __arch_local_irq_stosm(0x03); |
94c12cc7 | 69 | } |
1f194a4c | 70 | |
204ee2c5 | 71 | /* This only restores external and I/O interrupt state */ |
4aca3ab4 | 72 | static __always_inline void arch_local_irq_restore(unsigned long flags) |
df9ee292 | 73 | { |
204ee2c5 CB |
74 | /* only disabled->disabled and disabled->enabled is valid */ |
75 | if (flags & ARCH_IRQ_ENABLED) | |
76 | arch_local_irq_enable(); | |
df9ee292 DH |
77 | } |
78 | ||
4aca3ab4 | 79 | static __always_inline bool arch_irqs_disabled_flags(unsigned long flags) |
1f194a4c | 80 | { |
204ee2c5 | 81 | return !(flags & ARCH_IRQ_ENABLED); |
1f194a4c HC |
82 | } |
83 | ||
4aca3ab4 | 84 | static __always_inline bool arch_irqs_disabled(void) |
df9ee292 DH |
85 | { |
86 | return arch_irqs_disabled_flags(arch_local_save_flags()); | |
87 | } | |
1f194a4c | 88 | |
1f194a4c | 89 | #endif /* __ASM_IRQFLAGS_H */ |