diff options
Diffstat (limited to 'arch/mips/include/asm/irq.h')
-rw-r--r-- | arch/mips/include/asm/irq.h | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h new file mode 100644 index 000000000000..a58f0eecc68f --- /dev/null +++ b/arch/mips/include/asm/irq.h | |||
@@ -0,0 +1,163 @@ | |||
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 by Waldorf GMBH, written by Ralf Baechle | ||
7 | * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01, 02, 03 by Ralf Baechle | ||
8 | */ | ||
9 | #ifndef _ASM_IRQ_H | ||
10 | #define _ASM_IRQ_H | ||
11 | |||
12 | #include <linux/linkage.h> | ||
13 | |||
14 | #include <asm/mipsmtregs.h> | ||
15 | |||
16 | #include <irq.h> | ||
17 | |||
18 | #ifdef CONFIG_I8259 | ||
19 | static inline int irq_canonicalize(int irq) | ||
20 | { | ||
21 | return ((irq == I8259A_IRQ_BASE + 2) ? I8259A_IRQ_BASE + 9 : irq); | ||
22 | } | ||
23 | #else | ||
24 | #define irq_canonicalize(irq) (irq) /* Sane hardware, sane code ... */ | ||
25 | #endif | ||
26 | |||
27 | #ifdef CONFIG_MIPS_MT_SMTC | ||
28 | |||
29 | struct irqaction; | ||
30 | |||
31 | extern unsigned long irq_hwmask[]; | ||
32 | extern int setup_irq_smtc(unsigned int irq, struct irqaction * new, | ||
33 | unsigned long hwmask); | ||
34 | |||
35 | static inline void smtc_im_ack_irq(unsigned int irq) | ||
36 | { | ||
37 | if (irq_hwmask[irq] & ST0_IM) | ||
38 | set_c0_status(irq_hwmask[irq] & ST0_IM); | ||
39 | } | ||
40 | |||
41 | #else | ||
42 | |||
43 | static inline void smtc_im_ack_irq(unsigned int irq) | ||
44 | { | ||
45 | } | ||
46 | |||
47 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
48 | |||
49 | #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF | ||
50 | #include <linux/cpumask.h> | ||
51 | |||
52 | extern void plat_set_irq_affinity(unsigned int irq, cpumask_t affinity); | ||
53 | extern void smtc_forward_irq(unsigned int irq); | ||
54 | |||
55 | /* | ||
56 | * IRQ affinity hook invoked at the beginning of interrupt dispatch | ||
57 | * if option is enabled. | ||
58 | * | ||
59 | * Up through Linux 2.6.22 (at least) cpumask operations are very | ||
60 | * inefficient on MIPS. Initial prototypes of SMTC IRQ affinity | ||
61 | * used a "fast path" per-IRQ-descriptor cache of affinity information | ||
62 | * to reduce latency. As there is a project afoot to optimize the | ||
63 | * cpumask implementations, this version is optimistically assuming | ||
64 | * that cpumask.h macro overhead is reasonable during interrupt dispatch. | ||
65 | */ | ||
66 | #define IRQ_AFFINITY_HOOK(irq) \ | ||
67 | do { \ | ||
68 | if (!cpu_isset(smp_processor_id(), irq_desc[irq].affinity)) { \ | ||
69 | smtc_forward_irq(irq); \ | ||
70 | irq_exit(); \ | ||
71 | return; \ | ||
72 | } \ | ||
73 | } while (0) | ||
74 | |||
75 | #else /* Not doing SMTC affinity */ | ||
76 | |||
77 | #define IRQ_AFFINITY_HOOK(irq) do { } while (0) | ||
78 | |||
79 | #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ | ||
80 | |||
81 | #ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP | ||
82 | |||
83 | /* | ||
84 | * Clear interrupt mask handling "backstop" if irq_hwmask | ||
85 | * entry so indicates. This implies that the ack() or end() | ||
86 | * functions will take over re-enabling the low-level mask. | ||
87 | * Otherwise it will be done on return from exception. | ||
88 | */ | ||
89 | #define __DO_IRQ_SMTC_HOOK(irq) \ | ||
90 | do { \ | ||
91 | IRQ_AFFINITY_HOOK(irq); \ | ||
92 | if (irq_hwmask[irq] & 0x0000ff00) \ | ||
93 | write_c0_tccontext(read_c0_tccontext() & \ | ||
94 | ~(irq_hwmask[irq] & 0x0000ff00)); \ | ||
95 | } while (0) | ||
96 | |||
97 | #define __NO_AFFINITY_IRQ_SMTC_HOOK(irq) \ | ||
98 | do { \ | ||
99 | if (irq_hwmask[irq] & 0x0000ff00) \ | ||
100 | write_c0_tccontext(read_c0_tccontext() & \ | ||
101 | ~(irq_hwmask[irq] & 0x0000ff00)); \ | ||
102 | } while (0) | ||
103 | |||
104 | #else | ||
105 | |||
106 | #define __DO_IRQ_SMTC_HOOK(irq) \ | ||
107 | do { \ | ||
108 | IRQ_AFFINITY_HOOK(irq); \ | ||
109 | } while (0) | ||
110 | #define __NO_AFFINITY_IRQ_SMTC_HOOK(irq) do { } while (0) | ||
111 | |||
112 | #endif | ||
113 | |||
114 | /* | ||
115 | * do_IRQ handles all normal device IRQ's (the special | ||
116 | * SMP cross-CPU interrupts have their own specific | ||
117 | * handlers). | ||
118 | * | ||
119 | * Ideally there should be away to get this into kernel/irq/handle.c to | ||
120 | * avoid the overhead of a call for just a tiny function ... | ||
121 | */ | ||
122 | #define do_IRQ(irq) \ | ||
123 | do { \ | ||
124 | irq_enter(); \ | ||
125 | __DO_IRQ_SMTC_HOOK(irq); \ | ||
126 | generic_handle_irq(irq); \ | ||
127 | irq_exit(); \ | ||
128 | } while (0) | ||
129 | |||
130 | #ifdef CONFIG_MIPS_MT_SMTC_IRQAFF | ||
131 | /* | ||
132 | * To avoid inefficient and in some cases pathological re-checking of | ||
133 | * IRQ affinity, we have this variant that skips the affinity check. | ||
134 | */ | ||
135 | |||
136 | |||
137 | #define do_IRQ_no_affinity(irq) \ | ||
138 | do { \ | ||
139 | irq_enter(); \ | ||
140 | __NO_AFFINITY_IRQ_SMTC_HOOK(irq); \ | ||
141 | generic_handle_irq(irq); \ | ||
142 | irq_exit(); \ | ||
143 | } while (0) | ||
144 | |||
145 | #endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ | ||
146 | |||
147 | extern void arch_init_irq(void); | ||
148 | extern void spurious_interrupt(void); | ||
149 | |||
150 | extern int allocate_irqno(void); | ||
151 | extern void alloc_legacy_irqno(void); | ||
152 | extern void free_irqno(unsigned int irq); | ||
153 | |||
154 | /* | ||
155 | * Before R2 the timer and performance counter interrupts were both fixed to | ||
156 | * IE7. Since R2 their number has to be read from the c0_intctl register. | ||
157 | */ | ||
158 | #define CP0_LEGACY_COMPARE_IRQ 7 | ||
159 | |||
160 | extern int cp0_compare_irq; | ||
161 | extern int cp0_perfcount_irq; | ||
162 | |||
163 | #endif /* _ASM_IRQ_H */ | ||