1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2006 Atmark Techno, Inc.
4  */
5 
6 #ifndef _ASM_MICROBLAZE_IRQFLAGS_H
7 #define _ASM_MICROBLAZE_IRQFLAGS_H
8 
9 #include <linux/types.h>
10 #include <asm/registers.h>
11 
12 #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
13 
arch_local_irq_save(void)14 static inline notrace unsigned long arch_local_irq_save(void)
15 {
16 	unsigned long flags;
17 	asm volatile("	msrclr %0, %1	\n"
18 		     "	nop		\n"
19 		     : "=r"(flags)
20 		     : "i"(MSR_IE)
21 		     : "memory");
22 	return flags;
23 }
24 
arch_local_irq_disable(void)25 static inline notrace void arch_local_irq_disable(void)
26 {
27 	/* this uses r0 without declaring it - is that correct? */
28 	asm volatile("	msrclr r0, %0	\n"
29 		     "	nop		\n"
30 		     :
31 		     : "i"(MSR_IE)
32 		     : "memory");
33 }
34 
arch_local_irq_enable(void)35 static inline notrace void arch_local_irq_enable(void)
36 {
37 	/* this uses r0 without declaring it - is that correct? */
38 	asm volatile("	msrset	r0, %0	\n"
39 		     "	nop		\n"
40 		     :
41 		     : "i"(MSR_IE)
42 		     : "memory");
43 }
44 
45 #else /* !CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
46 
arch_local_irq_save(void)47 static inline notrace unsigned long arch_local_irq_save(void)
48 {
49 	unsigned long flags, tmp;
50 	asm volatile ("	mfs	%0, rmsr	\n"
51 		      "	nop			\n"
52 		      "	andi	%1, %0, %2	\n"
53 		      "	mts	rmsr, %1	\n"
54 		      "	nop			\n"
55 		      : "=r"(flags), "=r"(tmp)
56 		      : "i"(~MSR_IE)
57 		      : "memory");
58 	return flags;
59 }
60 
arch_local_irq_disable(void)61 static inline notrace void arch_local_irq_disable(void)
62 {
63 	unsigned long tmp;
64 	asm volatile("	mfs	%0, rmsr	\n"
65 		     "	nop			\n"
66 		     "	andi	%0, %0, %1	\n"
67 		     "	mts	rmsr, %0	\n"
68 		     "	nop			\n"
69 		     : "=r"(tmp)
70 		     : "i"(~MSR_IE)
71 		     : "memory");
72 }
73 
arch_local_irq_enable(void)74 static inline notrace void arch_local_irq_enable(void)
75 {
76 	unsigned long tmp;
77 	asm volatile("	mfs	%0, rmsr	\n"
78 		     "	nop			\n"
79 		     "	ori	%0, %0, %1	\n"
80 		     "	mts	rmsr, %0	\n"
81 		     "	nop			\n"
82 		     : "=r"(tmp)
83 		     : "i"(MSR_IE)
84 		     : "memory");
85 }
86 
87 #endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
88 
arch_local_save_flags(void)89 static inline notrace unsigned long arch_local_save_flags(void)
90 {
91 	unsigned long flags;
92 	asm volatile("	mfs	%0, rmsr	\n"
93 		     "	nop			\n"
94 		     : "=r"(flags)
95 		     :
96 		     : "memory");
97 	return flags;
98 }
99 
arch_local_irq_restore(unsigned long flags)100 static inline notrace void arch_local_irq_restore(unsigned long flags)
101 {
102 	asm volatile("	mts	rmsr, %0	\n"
103 		     "	nop			\n"
104 		     :
105 		     : "r"(flags)
106 		     : "memory");
107 }
108 
arch_irqs_disabled_flags(unsigned long flags)109 static inline notrace bool arch_irqs_disabled_flags(unsigned long flags)
110 {
111 	return (flags & MSR_IE) == 0;
112 }
113 
arch_irqs_disabled(void)114 static inline notrace bool arch_irqs_disabled(void)
115 {
116 	return arch_irqs_disabled_flags(arch_local_save_flags());
117 }
118 
119 #endif /* _ASM_MICROBLAZE_IRQFLAGS_H */
120