diff options
Diffstat (limited to 'include/asm-mips/interrupt.h')
-rw-r--r-- | include/asm-mips/interrupt.h | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/include/asm-mips/interrupt.h b/include/asm-mips/interrupt.h new file mode 100644 index 000000000000..e8357f5379fa --- /dev/null +++ b/include/asm-mips/interrupt.h | |||
@@ -0,0 +1,134 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle | ||
7 | * Copyright (C) 1996 by Paul M. Antoine | ||
8 | * Copyright (C) 1999 Silicon Graphics | ||
9 | * Copyright (C) 2000 MIPS Technologies, Inc. | ||
10 | */ | ||
11 | #ifndef _ASM_INTERRUPT_H | ||
12 | #define _ASM_INTERRUPT_H | ||
13 | |||
14 | #include <asm/hazards.h> | ||
15 | |||
16 | __asm__ ( | ||
17 | ".macro\tlocal_irq_enable\n\t" | ||
18 | ".set\tpush\n\t" | ||
19 | ".set\treorder\n\t" | ||
20 | ".set\tnoat\n\t" | ||
21 | "mfc0\t$1,$12\n\t" | ||
22 | "ori\t$1,0x1f\n\t" | ||
23 | "xori\t$1,0x1e\n\t" | ||
24 | "mtc0\t$1,$12\n\t" | ||
25 | "irq_enable_hazard\n\t" | ||
26 | ".set\tpop\n\t" | ||
27 | ".endm"); | ||
28 | |||
29 | static inline void local_irq_enable(void) | ||
30 | { | ||
31 | __asm__ __volatile__( | ||
32 | "local_irq_enable" | ||
33 | : /* no outputs */ | ||
34 | : /* no inputs */ | ||
35 | : "memory"); | ||
36 | } | ||
37 | |||
38 | /* | ||
39 | * For cli() we have to insert nops to make sure that the new value | ||
40 | * has actually arrived in the status register before the end of this | ||
41 | * macro. | ||
42 | * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs | ||
43 | * no nops at all. | ||
44 | */ | ||
45 | __asm__ ( | ||
46 | ".macro\tlocal_irq_disable\n\t" | ||
47 | ".set\tpush\n\t" | ||
48 | ".set\tnoat\n\t" | ||
49 | "mfc0\t$1,$12\n\t" | ||
50 | "ori\t$1,1\n\t" | ||
51 | "xori\t$1,1\n\t" | ||
52 | ".set\tnoreorder\n\t" | ||
53 | "mtc0\t$1,$12\n\t" | ||
54 | "irq_disable_hazard\n\t" | ||
55 | ".set\tpop\n\t" | ||
56 | ".endm"); | ||
57 | |||
58 | static inline void local_irq_disable(void) | ||
59 | { | ||
60 | __asm__ __volatile__( | ||
61 | "local_irq_disable" | ||
62 | : /* no outputs */ | ||
63 | : /* no inputs */ | ||
64 | : "memory"); | ||
65 | } | ||
66 | |||
67 | __asm__ ( | ||
68 | ".macro\tlocal_save_flags flags\n\t" | ||
69 | ".set\tpush\n\t" | ||
70 | ".set\treorder\n\t" | ||
71 | "mfc0\t\\flags, $12\n\t" | ||
72 | ".set\tpop\n\t" | ||
73 | ".endm"); | ||
74 | |||
75 | #define local_save_flags(x) \ | ||
76 | __asm__ __volatile__( \ | ||
77 | "local_save_flags %0" \ | ||
78 | : "=r" (x)) | ||
79 | |||
80 | __asm__ ( | ||
81 | ".macro\tlocal_irq_save result\n\t" | ||
82 | ".set\tpush\n\t" | ||
83 | ".set\treorder\n\t" | ||
84 | ".set\tnoat\n\t" | ||
85 | "mfc0\t\\result, $12\n\t" | ||
86 | "ori\t$1, \\result, 1\n\t" | ||
87 | "xori\t$1, 1\n\t" | ||
88 | ".set\tnoreorder\n\t" | ||
89 | "mtc0\t$1, $12\n\t" | ||
90 | "irq_disable_hazard\n\t" | ||
91 | ".set\tpop\n\t" | ||
92 | ".endm"); | ||
93 | |||
94 | #define local_irq_save(x) \ | ||
95 | __asm__ __volatile__( \ | ||
96 | "local_irq_save\t%0" \ | ||
97 | : "=r" (x) \ | ||
98 | : /* no inputs */ \ | ||
99 | : "memory") | ||
100 | |||
101 | __asm__ ( | ||
102 | ".macro\tlocal_irq_restore flags\n\t" | ||
103 | ".set\tnoreorder\n\t" | ||
104 | ".set\tnoat\n\t" | ||
105 | "mfc0\t$1, $12\n\t" | ||
106 | "andi\t\\flags, 1\n\t" | ||
107 | "ori\t$1, 1\n\t" | ||
108 | "xori\t$1, 1\n\t" | ||
109 | "or\t\\flags, $1\n\t" | ||
110 | "mtc0\t\\flags, $12\n\t" | ||
111 | "irq_disable_hazard\n\t" | ||
112 | ".set\tat\n\t" | ||
113 | ".set\treorder\n\t" | ||
114 | ".endm"); | ||
115 | |||
116 | #define local_irq_restore(flags) \ | ||
117 | do { \ | ||
118 | unsigned long __tmp1; \ | ||
119 | \ | ||
120 | __asm__ __volatile__( \ | ||
121 | "local_irq_restore\t%0" \ | ||
122 | : "=r" (__tmp1) \ | ||
123 | : "0" (flags) \ | ||
124 | : "memory"); \ | ||
125 | } while(0) | ||
126 | |||
127 | #define irqs_disabled() \ | ||
128 | ({ \ | ||
129 | unsigned long flags; \ | ||
130 | local_save_flags(flags); \ | ||
131 | !(flags & 1); \ | ||
132 | }) | ||
133 | |||
134 | #endif /* _ASM_INTERRUPT_H */ | ||