1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * include/asm/irqflags.h
4 *
5 * IRQ flags handling
6 *
7 * This file gets included from lowlevel asm headers too, to provide
8 * wrapped versions of the local_irq_*() APIs, based on the
9 * arch_local_irq_*() functions from the lowlevel headers.
10 */
11 #ifndef _ASM_IRQFLAGS_H
12 #define _ASM_IRQFLAGS_H
13
14 #include <asm/pil.h>
15
16 #ifndef __ASSEMBLY__
17
arch_local_save_flags(void)18 static inline notrace unsigned long arch_local_save_flags(void)
19 {
20 unsigned long flags;
21
22 __asm__ __volatile__(
23 "rdpr %%pil, %0"
24 : "=r" (flags)
25 );
26
27 return flags;
28 }
29
arch_local_irq_restore(unsigned long flags)30 static inline notrace void arch_local_irq_restore(unsigned long flags)
31 {
32 __asm__ __volatile__(
33 "wrpr %0, %%pil"
34 : /* no output */
35 : "r" (flags)
36 : "memory"
37 );
38 }
39
arch_local_irq_disable(void)40 static inline notrace void arch_local_irq_disable(void)
41 {
42 __asm__ __volatile__(
43 "wrpr %0, %%pil"
44 : /* no outputs */
45 : "i" (PIL_NORMAL_MAX)
46 : "memory"
47 );
48 }
49
arch_local_irq_enable(void)50 static inline notrace void arch_local_irq_enable(void)
51 {
52 __asm__ __volatile__(
53 "wrpr 0, %%pil"
54 : /* no outputs */
55 : /* no inputs */
56 : "memory"
57 );
58 }
59
arch_irqs_disabled_flags(unsigned long flags)60 static inline notrace int arch_irqs_disabled_flags(unsigned long flags)
61 {
62 return (flags > 0);
63 }
64
arch_irqs_disabled(void)65 static inline notrace int arch_irqs_disabled(void)
66 {
67 return arch_irqs_disabled_flags(arch_local_save_flags());
68 }
69
arch_local_irq_save(void)70 static inline notrace unsigned long arch_local_irq_save(void)
71 {
72 unsigned long flags, tmp;
73
74 /* Disable interrupts to PIL_NORMAL_MAX unless we already
75 * are using PIL_NMI, in which case PIL_NMI is retained.
76 *
77 * The only values we ever program into the %pil are 0,
78 * PIL_NORMAL_MAX and PIL_NMI.
79 *
80 * Since PIL_NMI is the largest %pil value and all bits are
81 * set in it (0xf), it doesn't matter what PIL_NORMAL_MAX
82 * actually is.
83 */
84 __asm__ __volatile__(
85 "rdpr %%pil, %0\n\t"
86 "or %0, %2, %1\n\t"
87 "wrpr %1, 0x0, %%pil"
88 : "=r" (flags), "=r" (tmp)
89 : "i" (PIL_NORMAL_MAX)
90 : "memory"
91 );
92
93 return flags;
94 }
95
96 #endif /* (__ASSEMBLY__) */
97
98 #endif /* !(_ASM_IRQFLAGS_H) */
99