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 
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 
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 
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 
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 
60 static inline notrace int arch_irqs_disabled_flags(unsigned long flags)
61 {
62 	return (flags > 0);
63 }
64 
65 static inline notrace int arch_irqs_disabled(void)
66 {
67 	return arch_irqs_disabled_flags(arch_local_save_flags());
68 }
69 
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