aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/cavium-octeon/octeon-irq.c1422
-rw-r--r--arch/mips/cavium-octeon/setup.c12
-rw-r--r--arch/mips/cavium-octeon/smp.c39
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/irq.h243
-rw-r--r--arch/mips/include/asm/octeon/octeon.h2
-rw-r--r--arch/mips/pci/msi-octeon.c20
6 files changed, 921 insertions, 817 deletions
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index ce7500cdf5b7..03c081da3df4 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -3,10 +3,13 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 2004-2008, 2009, 2010 Cavium Networks 6 * Copyright (C) 2004-2008, 2009, 2010, 2011 Cavium Networks
7 */ 7 */
8#include <linux/irq.h> 8
9#include <linux/interrupt.h> 9#include <linux/interrupt.h>
10#include <linux/bitops.h>
11#include <linux/percpu.h>
12#include <linux/irq.h>
10#include <linux/smp.h> 13#include <linux/smp.h>
11 14
12#include <asm/octeon/octeon.h> 15#include <asm/octeon/octeon.h>
@@ -14,6 +17,47 @@
14static DEFINE_RAW_SPINLOCK(octeon_irq_ciu0_lock); 17static DEFINE_RAW_SPINLOCK(octeon_irq_ciu0_lock);
15static DEFINE_RAW_SPINLOCK(octeon_irq_ciu1_lock); 18static DEFINE_RAW_SPINLOCK(octeon_irq_ciu1_lock);
16 19
20static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu0_en_mirror);
21static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu1_en_mirror);
22
23static __read_mostly u8 octeon_irq_ciu_to_irq[8][64];
24
25union octeon_ciu_chip_data {
26 void *p;
27 unsigned long l;
28 struct {
29 unsigned int line:6;
30 unsigned int bit:6;
31 } s;
32};
33
34struct octeon_core_chip_data {
35 struct mutex core_irq_mutex;
36 bool current_en;
37 bool desired_en;
38 u8 bit;
39};
40
41#define MIPS_CORE_IRQ_LINES 8
42
43static struct octeon_core_chip_data octeon_irq_core_chip_data[MIPS_CORE_IRQ_LINES];
44
45static void __init octeon_irq_set_ciu_mapping(int irq, int line, int bit,
46 struct irq_chip *chip,
47 irq_flow_handler_t handler)
48{
49 union octeon_ciu_chip_data cd;
50
51 irq_set_chip_and_handler(irq, chip, handler);
52
53 cd.l = 0;
54 cd.s.line = line;
55 cd.s.bit = bit;
56
57 irq_set_chip_data(irq, cd.p);
58 octeon_irq_ciu_to_irq[line][bit] = irq;
59}
60
17static int octeon_coreid_for_cpu(int cpu) 61static int octeon_coreid_for_cpu(int cpu)
18{ 62{
19#ifdef CONFIG_SMP 63#ifdef CONFIG_SMP
@@ -23,9 +67,20 @@ static int octeon_coreid_for_cpu(int cpu)
23#endif 67#endif
24} 68}
25 69
26static void octeon_irq_core_ack(unsigned int irq) 70static int octeon_cpu_for_coreid(int coreid)
71{
72#ifdef CONFIG_SMP
73 return cpu_number_map(coreid);
74#else
75 return smp_processor_id();
76#endif
77}
78
79static void octeon_irq_core_ack(struct irq_data *data)
27{ 80{
28 unsigned int bit = irq - OCTEON_IRQ_SW0; 81 struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
82 unsigned int bit = cd->bit;
83
29 /* 84 /*
30 * We don't need to disable IRQs to make these atomic since 85 * We don't need to disable IRQs to make these atomic since
31 * they are already disabled earlier in the low level 86 * they are already disabled earlier in the low level
@@ -37,131 +92,133 @@ static void octeon_irq_core_ack(unsigned int irq)
37 clear_c0_cause(0x100 << bit); 92 clear_c0_cause(0x100 << bit);
38} 93}
39 94
40static void octeon_irq_core_eoi(unsigned int irq) 95static void octeon_irq_core_eoi(struct irq_data *data)
41{ 96{
42 struct irq_desc *desc = irq_to_desc(irq); 97 struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
43 unsigned int bit = irq - OCTEON_IRQ_SW0; 98
44 /*
45 * If an IRQ is being processed while we are disabling it the
46 * handler will attempt to unmask the interrupt after it has
47 * been disabled.
48 */
49 if ((unlikely(desc->status & IRQ_DISABLED)))
50 return;
51 /* 99 /*
52 * We don't need to disable IRQs to make these atomic since 100 * We don't need to disable IRQs to make these atomic since
53 * they are already disabled earlier in the low level 101 * they are already disabled earlier in the low level
54 * interrupt code. 102 * interrupt code.
55 */ 103 */
56 set_c0_status(0x100 << bit); 104 set_c0_status(0x100 << cd->bit);
57} 105}
58 106
59static void octeon_irq_core_enable(unsigned int irq) 107static void octeon_irq_core_set_enable_local(void *arg)
60{ 108{
61 unsigned long flags; 109 struct irq_data *data = arg;
62 unsigned int bit = irq - OCTEON_IRQ_SW0; 110 struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
111 unsigned int mask = 0x100 << cd->bit;
63 112
64 /* 113 /*
65 * We need to disable interrupts to make sure our updates are 114 * Interrupts are already disabled, so these are atomic.
66 * atomic.
67 */ 115 */
68 local_irq_save(flags); 116 if (cd->desired_en)
69 set_c0_status(0x100 << bit); 117 set_c0_status(mask);
70 local_irq_restore(flags); 118 else
119 clear_c0_status(mask);
120
71} 121}
72 122
73static void octeon_irq_core_disable_local(unsigned int irq) 123static void octeon_irq_core_disable(struct irq_data *data)
74{ 124{
75 unsigned long flags; 125 struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
76 unsigned int bit = irq - OCTEON_IRQ_SW0; 126 cd->desired_en = false;
77 /*
78 * We need to disable interrupts to make sure our updates are
79 * atomic.
80 */
81 local_irq_save(flags);
82 clear_c0_status(0x100 << bit);
83 local_irq_restore(flags);
84} 127}
85 128
86static void octeon_irq_core_disable(unsigned int irq) 129static void octeon_irq_core_enable(struct irq_data *data)
87{ 130{
88#ifdef CONFIG_SMP 131 struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
89 on_each_cpu((void (*)(void *)) octeon_irq_core_disable_local, 132 cd->desired_en = true;
90 (void *) (long) irq, 1);
91#else
92 octeon_irq_core_disable_local(irq);
93#endif
94} 133}
95 134
96static struct irq_chip octeon_irq_chip_core = { 135static void octeon_irq_core_bus_lock(struct irq_data *data)
97 .name = "Core", 136{
98 .enable = octeon_irq_core_enable, 137 struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
99 .disable = octeon_irq_core_disable,
100 .ack = octeon_irq_core_ack,
101 .eoi = octeon_irq_core_eoi,
102};
103 138
139 mutex_lock(&cd->core_irq_mutex);
140}
104 141
105static void octeon_irq_ciu0_ack(unsigned int irq) 142static void octeon_irq_core_bus_sync_unlock(struct irq_data *data)
106{ 143{
107 switch (irq) { 144 struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
108 case OCTEON_IRQ_GMX_DRP0: 145
109 case OCTEON_IRQ_GMX_DRP1: 146 if (cd->desired_en != cd->current_en) {
110 case OCTEON_IRQ_IPD_DRP: 147 on_each_cpu(octeon_irq_core_set_enable_local, data, 1);
111 case OCTEON_IRQ_KEY_ZERO: 148
112 case OCTEON_IRQ_TIMER0: 149 cd->current_en = cd->desired_en;
113 case OCTEON_IRQ_TIMER1:
114 case OCTEON_IRQ_TIMER2:
115 case OCTEON_IRQ_TIMER3:
116 {
117 int index = cvmx_get_core_num() * 2;
118 u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
119 /*
120 * CIU timer type interrupts must be acknoleged by
121 * writing a '1' bit to their sum0 bit.
122 */
123 cvmx_write_csr(CVMX_CIU_INTX_SUM0(index), mask);
124 break;
125 }
126 default:
127 break;
128 } 150 }
129 151
130 /* 152 mutex_unlock(&cd->core_irq_mutex);
131 * In order to avoid any locking accessing the CIU, we
132 * acknowledge CIU interrupts by disabling all of them. This
133 * way we can use a per core register and avoid any out of
134 * core locking requirements. This has the side affect that
135 * CIU interrupts can't be processed recursively.
136 *
137 * We don't need to disable IRQs to make these atomic since
138 * they are already disabled earlier in the low level
139 * interrupt code.
140 */
141 clear_c0_status(0x100 << 2);
142} 153}
143 154
144static void octeon_irq_ciu0_eoi(unsigned int irq) 155
156static void octeon_irq_core_cpu_online(struct irq_data *data)
145{ 157{
146 /* 158 if (irqd_irq_disabled(data))
147 * Enable all CIU interrupts again. We don't need to disable 159 octeon_irq_core_eoi(data);
148 * IRQs to make these atomic since they are already disabled 160}
149 * earlier in the low level interrupt code. 161
150 */ 162static void octeon_irq_core_cpu_offline(struct irq_data *data)
151 set_c0_status(0x100 << 2); 163{
164 if (irqd_irq_disabled(data))
165 octeon_irq_core_ack(data);
152} 166}
153 167
154static int next_coreid_for_irq(struct irq_desc *desc) 168static struct irq_chip octeon_irq_chip_core = {
169 .name = "Core",
170 .irq_enable = octeon_irq_core_enable,
171 .irq_disable = octeon_irq_core_disable,
172 .irq_ack = octeon_irq_core_ack,
173 .irq_eoi = octeon_irq_core_eoi,
174 .irq_bus_lock = octeon_irq_core_bus_lock,
175 .irq_bus_sync_unlock = octeon_irq_core_bus_sync_unlock,
176
177 .irq_cpu_online = octeon_irq_core_cpu_online,
178 .irq_cpu_offline = octeon_irq_core_cpu_offline,
179};
180
181static void __init octeon_irq_init_core(void)
182{
183 int i;
184 int irq;
185 struct octeon_core_chip_data *cd;
186
187 for (i = 0; i < MIPS_CORE_IRQ_LINES; i++) {
188 cd = &octeon_irq_core_chip_data[i];
189 cd->current_en = false;
190 cd->desired_en = false;
191 cd->bit = i;
192 mutex_init(&cd->core_irq_mutex);
193
194 irq = OCTEON_IRQ_SW0 + i;
195 switch (irq) {
196 case OCTEON_IRQ_TIMER:
197 case OCTEON_IRQ_SW0:
198 case OCTEON_IRQ_SW1:
199 case OCTEON_IRQ_5:
200 case OCTEON_IRQ_PERF:
201 irq_set_chip_data(irq, cd);
202 irq_set_chip_and_handler(irq, &octeon_irq_chip_core,
203 handle_percpu_irq);
204 break;
205 default:
206 break;
207 }
208 }
209}
210
211static int next_cpu_for_irq(struct irq_data *data)
155{ 212{
156 213
157#ifdef CONFIG_SMP 214#ifdef CONFIG_SMP
158 int coreid; 215 int cpu;
159 int weight = cpumask_weight(desc->affinity); 216 int weight = cpumask_weight(data->affinity);
160 217
161 if (weight > 1) { 218 if (weight > 1) {
162 int cpu = smp_processor_id(); 219 cpu = smp_processor_id();
163 for (;;) { 220 for (;;) {
164 cpu = cpumask_next(cpu, desc->affinity); 221 cpu = cpumask_next(cpu, data->affinity);
165 if (cpu >= nr_cpu_ids) { 222 if (cpu >= nr_cpu_ids) {
166 cpu = -1; 223 cpu = -1;
167 continue; 224 continue;
@@ -169,83 +226,175 @@ static int next_coreid_for_irq(struct irq_desc *desc)
169 break; 226 break;
170 } 227 }
171 } 228 }
172 coreid = octeon_coreid_for_cpu(cpu);
173 } else if (weight == 1) { 229 } else if (weight == 1) {
174 coreid = octeon_coreid_for_cpu(cpumask_first(desc->affinity)); 230 cpu = cpumask_first(data->affinity);
175 } else { 231 } else {
176 coreid = cvmx_get_core_num(); 232 cpu = smp_processor_id();
177 } 233 }
178 return coreid; 234 return cpu;
179#else 235#else
180 return cvmx_get_core_num(); 236 return smp_processor_id();
181#endif 237#endif
182} 238}
183 239
184static void octeon_irq_ciu0_enable(unsigned int irq) 240static void octeon_irq_ciu_enable(struct irq_data *data)
185{ 241{
186 struct irq_desc *desc = irq_to_desc(irq); 242 int cpu = next_cpu_for_irq(data);
187 int coreid = next_coreid_for_irq(desc); 243 int coreid = octeon_coreid_for_cpu(cpu);
244 unsigned long *pen;
188 unsigned long flags; 245 unsigned long flags;
189 uint64_t en0; 246 union octeon_ciu_chip_data cd;
190 int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */ 247
248 cd.p = irq_data_get_irq_chip_data(data);
191 249
192 raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); 250 if (cd.s.line == 0) {
193 en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); 251 raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
194 en0 |= 1ull << bit; 252 pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
195 cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); 253 set_bit(cd.s.bit, pen);
196 cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); 254 cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
197 raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); 255 raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
256 } else {
257 raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
258 pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
259 set_bit(cd.s.bit, pen);
260 cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
261 raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
262 }
198} 263}
199 264
200static void octeon_irq_ciu0_enable_mbox(unsigned int irq) 265static void octeon_irq_ciu_enable_local(struct irq_data *data)
266{
267 unsigned long *pen;
268 unsigned long flags;
269 union octeon_ciu_chip_data cd;
270
271 cd.p = irq_data_get_irq_chip_data(data);
272
273 if (cd.s.line == 0) {
274 raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
275 pen = &__get_cpu_var(octeon_irq_ciu0_en_mirror);
276 set_bit(cd.s.bit, pen);
277 cvmx_write_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2), *pen);
278 raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
279 } else {
280 raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
281 pen = &__get_cpu_var(octeon_irq_ciu1_en_mirror);
282 set_bit(cd.s.bit, pen);
283 cvmx_write_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1), *pen);
284 raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
285 }
286}
287
288static void octeon_irq_ciu_disable_local(struct irq_data *data)
289{
290 unsigned long *pen;
291 unsigned long flags;
292 union octeon_ciu_chip_data cd;
293
294 cd.p = irq_data_get_irq_chip_data(data);
295
296 if (cd.s.line == 0) {
297 raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
298 pen = &__get_cpu_var(octeon_irq_ciu0_en_mirror);
299 clear_bit(cd.s.bit, pen);
300 cvmx_write_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2), *pen);
301 raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
302 } else {
303 raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
304 pen = &__get_cpu_var(octeon_irq_ciu1_en_mirror);
305 clear_bit(cd.s.bit, pen);
306 cvmx_write_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1), *pen);
307 raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
308 }
309}
310
311static void octeon_irq_ciu_disable_all(struct irq_data *data)
201{ 312{
202 int coreid = cvmx_get_core_num();
203 unsigned long flags; 313 unsigned long flags;
204 uint64_t en0; 314 unsigned long *pen;
205 int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */ 315 int cpu;
316 union octeon_ciu_chip_data cd;
317
318 wmb(); /* Make sure flag changes arrive before register updates. */
206 319
207 raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); 320 cd.p = irq_data_get_irq_chip_data(data);
208 en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); 321
209 en0 |= 1ull << bit; 322 if (cd.s.line == 0) {
210 cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); 323 raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
211 cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); 324 for_each_online_cpu(cpu) {
212 raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags); 325 int coreid = octeon_coreid_for_cpu(cpu);
326 pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
327 clear_bit(cd.s.bit, pen);
328 cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
329 }
330 raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
331 } else {
332 raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
333 for_each_online_cpu(cpu) {
334 int coreid = octeon_coreid_for_cpu(cpu);
335 pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
336 clear_bit(cd.s.bit, pen);
337 cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
338 }
339 raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
340 }
213} 341}
214 342
215static void octeon_irq_ciu0_disable(unsigned int irq) 343static void octeon_irq_ciu_enable_all(struct irq_data *data)
216{ 344{
217 int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
218 unsigned long flags; 345 unsigned long flags;
219 uint64_t en0; 346 unsigned long *pen;
220 int cpu; 347 int cpu;
221 raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); 348 union octeon_ciu_chip_data cd;
222 for_each_online_cpu(cpu) { 349
223 int coreid = octeon_coreid_for_cpu(cpu); 350 cd.p = irq_data_get_irq_chip_data(data);
224 en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); 351
225 en0 &= ~(1ull << bit); 352 if (cd.s.line == 0) {
226 cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); 353 raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
354 for_each_online_cpu(cpu) {
355 int coreid = octeon_coreid_for_cpu(cpu);
356 pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
357 set_bit(cd.s.bit, pen);
358 cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
359 }
360 raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
361 } else {
362 raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
363 for_each_online_cpu(cpu) {
364 int coreid = octeon_coreid_for_cpu(cpu);
365 pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
366 set_bit(cd.s.bit, pen);
367 cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
368 }
369 raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
227 } 370 }
228 /*
229 * We need to do a read after the last update to make sure all
230 * of them are done.
231 */
232 cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
233 raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
234} 371}
235 372
236/* 373/*
237 * Enable the irq on the next core in the affinity set for chips that 374 * Enable the irq on the next core in the affinity set for chips that
238 * have the EN*_W1{S,C} registers. 375 * have the EN*_W1{S,C} registers.
239 */ 376 */
240static void octeon_irq_ciu0_enable_v2(unsigned int irq) 377static void octeon_irq_ciu_enable_v2(struct irq_data *data)
241{ 378{
242 int index; 379 u64 mask;
243 u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); 380 int cpu = next_cpu_for_irq(data);
244 struct irq_desc *desc = irq_to_desc(irq); 381 union octeon_ciu_chip_data cd;
245 382
246 if ((desc->status & IRQ_DISABLED) == 0) { 383 cd.p = irq_data_get_irq_chip_data(data);
247 index = next_coreid_for_irq(desc) * 2; 384 mask = 1ull << (cd.s.bit);
385
386 /*
387 * Called under the desc lock, so these should never get out
388 * of sync.
389 */
390 if (cd.s.line == 0) {
391 int index = octeon_coreid_for_cpu(cpu) * 2;
392 set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu0_en_mirror, cpu));
248 cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); 393 cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
394 } else {
395 int index = octeon_coreid_for_cpu(cpu) * 2 + 1;
396 set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu1_en_mirror, cpu));
397 cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
249 } 398 }
250} 399}
251 400
@@ -253,83 +402,180 @@ static void octeon_irq_ciu0_enable_v2(unsigned int irq)
253 * Enable the irq on the current CPU for chips that 402 * Enable the irq on the current CPU for chips that
254 * have the EN*_W1{S,C} registers. 403 * have the EN*_W1{S,C} registers.
255 */ 404 */
256static void octeon_irq_ciu0_enable_mbox_v2(unsigned int irq) 405static void octeon_irq_ciu_enable_local_v2(struct irq_data *data)
257{ 406{
258 int index; 407 u64 mask;
259 u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); 408 union octeon_ciu_chip_data cd;
409
410 cd.p = irq_data_get_irq_chip_data(data);
411 mask = 1ull << (cd.s.bit);
260 412
261 index = cvmx_get_core_num() * 2; 413 if (cd.s.line == 0) {
262 cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); 414 int index = cvmx_get_core_num() * 2;
415 set_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu0_en_mirror));
416 cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
417 } else {
418 int index = cvmx_get_core_num() * 2 + 1;
419 set_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu1_en_mirror));
420 cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
421 }
422}
423
424static void octeon_irq_ciu_disable_local_v2(struct irq_data *data)
425{
426 u64 mask;
427 union octeon_ciu_chip_data cd;
428
429 cd.p = irq_data_get_irq_chip_data(data);
430 mask = 1ull << (cd.s.bit);
431
432 if (cd.s.line == 0) {
433 int index = cvmx_get_core_num() * 2;
434 clear_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu0_en_mirror));
435 cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
436 } else {
437 int index = cvmx_get_core_num() * 2 + 1;
438 clear_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu1_en_mirror));
439 cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
440 }
263} 441}
264 442
265/* 443/*
266 * Disable the irq on the current core for chips that have the EN*_W1{S,C} 444 * Write to the W1C bit in CVMX_CIU_INTX_SUM0 to clear the irq.
267 * registers.
268 */ 445 */
269static void octeon_irq_ciu0_ack_v2(unsigned int irq) 446static void octeon_irq_ciu_ack(struct irq_data *data)
270{ 447{
271 int index = cvmx_get_core_num() * 2; 448 u64 mask;
272 u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); 449 union octeon_ciu_chip_data cd;
273 450
274 switch (irq) { 451 cd.p = data->chip_data;
275 case OCTEON_IRQ_GMX_DRP0: 452 mask = 1ull << (cd.s.bit);
276 case OCTEON_IRQ_GMX_DRP1: 453
277 case OCTEON_IRQ_IPD_DRP: 454 if (cd.s.line == 0) {
278 case OCTEON_IRQ_KEY_ZERO: 455 int index = cvmx_get_core_num() * 2;
279 case OCTEON_IRQ_TIMER0:
280 case OCTEON_IRQ_TIMER1:
281 case OCTEON_IRQ_TIMER2:
282 case OCTEON_IRQ_TIMER3:
283 /*
284 * CIU timer type interrupts must be acknoleged by
285 * writing a '1' bit to their sum0 bit.
286 */
287 cvmx_write_csr(CVMX_CIU_INTX_SUM0(index), mask); 456 cvmx_write_csr(CVMX_CIU_INTX_SUM0(index), mask);
288 break; 457 } else {
289 default: 458 cvmx_write_csr(CVMX_CIU_INT_SUM1, mask);
290 break;
291 } 459 }
292
293 cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
294} 460}
295 461
296/* 462/*
297 * Enable the irq on the current core for chips that have the EN*_W1{S,C} 463 * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
298 * registers. 464 * registers.
299 */ 465 */
300static void octeon_irq_ciu0_eoi_mbox_v2(unsigned int irq) 466static void octeon_irq_ciu_disable_all_v2(struct irq_data *data)
301{ 467{
302 struct irq_desc *desc = irq_to_desc(irq); 468 int cpu;
303 int index = cvmx_get_core_num() * 2; 469 u64 mask;
304 u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); 470 union octeon_ciu_chip_data cd;
305 471
306 if (likely((desc->status & IRQ_DISABLED) == 0)) 472 wmb(); /* Make sure flag changes arrive before register updates. */
307 cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); 473
474 cd.p = data->chip_data;
475 mask = 1ull << (cd.s.bit);
476
477 if (cd.s.line == 0) {
478 for_each_online_cpu(cpu) {
479 int index = octeon_coreid_for_cpu(cpu) * 2;
480 clear_bit(cd.s.bit, &per_cpu(octeon_irq_ciu0_en_mirror, cpu));
481 cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
482 }
483 } else {
484 for_each_online_cpu(cpu) {
485 int index = octeon_coreid_for_cpu(cpu) * 2 + 1;
486 clear_bit(cd.s.bit, &per_cpu(octeon_irq_ciu1_en_mirror, cpu));
487 cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
488 }
489 }
308} 490}
309 491
310/* 492/*
311 * Disable the irq on the all cores for chips that have the EN*_W1{S,C} 493 * Enable the irq on the all cores for chips that have the EN*_W1{S,C}
312 * registers. 494 * registers.
313 */ 495 */
314static void octeon_irq_ciu0_disable_all_v2(unsigned int irq) 496static void octeon_irq_ciu_enable_all_v2(struct irq_data *data)
315{ 497{
316 u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
317 int index;
318 int cpu; 498 int cpu;
319 for_each_online_cpu(cpu) { 499 u64 mask;
320 index = octeon_coreid_for_cpu(cpu) * 2; 500 union octeon_ciu_chip_data cd;
321 cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); 501
502 cd.p = data->chip_data;
503 mask = 1ull << (cd.s.bit);
504
505 if (cd.s.line == 0) {
506 for_each_online_cpu(cpu) {
507 int index = octeon_coreid_for_cpu(cpu) * 2;
508 set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu0_en_mirror, cpu));
509 cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
510 }
511 } else {
512 for_each_online_cpu(cpu) {
513 int index = octeon_coreid_for_cpu(cpu) * 2 + 1;
514 set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu1_en_mirror, cpu));
515 cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
516 }
322 } 517 }
323} 518}
324 519
520static void octeon_irq_cpu_online_mbox(struct irq_data *data)
521{
522 if (irqd_irq_disabled(data))
523 octeon_irq_ciu_enable_local(data);
524}
525
526static void octeon_irq_cpu_online_mbox_v2(struct irq_data *data)
527{
528 if (irqd_irq_disabled(data))
529 octeon_irq_ciu_enable_local_v2(data);
530}
531
532static void octeon_irq_cpu_offline_mbox(struct irq_data *data)
533{
534 if (irqd_irq_disabled(data))
535 octeon_irq_ciu_disable_local(data);
536}
537
538static void octeon_irq_cpu_offline_mbox_v2(struct irq_data *data)
539{
540 if (irqd_irq_disabled(data))
541 octeon_irq_ciu_disable_local_v2(data);
542}
543
325#ifdef CONFIG_SMP 544#ifdef CONFIG_SMP
326static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest) 545
546static void octeon_irq_cpu_offline_ciu(struct irq_data *data)
547{
548 int cpu = smp_processor_id();
549 cpumask_t new_affinity;
550
551 if (!cpumask_test_cpu(cpu, data->affinity))
552 return;
553
554 if (cpumask_weight(data->affinity) > 1) {
555 /*
556 * It has multi CPU affinity, just remove this CPU
557 * from the affinity set.
558 */
559 cpumask_copy(&new_affinity, data->affinity);
560 cpumask_clear_cpu(cpu, &new_affinity);
561 } else {
562 /* Otherwise, put it on lowest numbered online CPU. */
563 cpumask_clear(&new_affinity);
564 cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity);
565 }
566 __irq_set_affinity_locked(data, &new_affinity);
567}
568
569static int octeon_irq_ciu_set_affinity(struct irq_data *data,
570 const struct cpumask *dest, bool force)
327{ 571{
328 int cpu; 572 int cpu;
329 struct irq_desc *desc = irq_to_desc(irq); 573 struct irq_desc *desc = irq_to_desc(data->irq);
330 int enable_one = (desc->status & IRQ_DISABLED) == 0; 574 int enable_one = (desc->status & IRQ_DISABLED) == 0;
331 unsigned long flags; 575 unsigned long flags;
332 int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */ 576 union octeon_ciu_chip_data cd;
577
578 cd.p = data->chip_data;
333 579
334 /* 580 /*
335 * For non-v2 CIU, we will allow only single CPU affinity. 581 * For non-v2 CIU, we will allow only single CPU affinity.
@@ -339,26 +585,40 @@ static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *
339 if (cpumask_weight(dest) != 1) 585 if (cpumask_weight(dest) != 1)
340 return -EINVAL; 586 return -EINVAL;
341 587
342 raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags); 588 if (desc->status & IRQ_DISABLED)
343 for_each_online_cpu(cpu) { 589 return 0;
344 int coreid = octeon_coreid_for_cpu(cpu); 590
345 uint64_t en0 = 591 if (cd.s.line == 0) {
346 cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); 592 raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
347 if (cpumask_test_cpu(cpu, dest) && enable_one) { 593 for_each_online_cpu(cpu) {
348 enable_one = 0; 594 int coreid = octeon_coreid_for_cpu(cpu);
349 en0 |= 1ull << bit; 595 unsigned long *pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
350 } else { 596
351 en0 &= ~(1ull << bit); 597 if (cpumask_test_cpu(cpu, dest) && enable_one) {
598 enable_one = 0;
599 set_bit(cd.s.bit, pen);
600 } else {
601 clear_bit(cd.s.bit, pen);
602 }
603 cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
604 }
605 raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
606 } else {
607 raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
608 for_each_online_cpu(cpu) {
609 int coreid = octeon_coreid_for_cpu(cpu);
610 unsigned long *pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
611
612 if (cpumask_test_cpu(cpu, dest) && enable_one) {
613 enable_one = 0;
614 set_bit(cd.s.bit, pen);
615 } else {
616 clear_bit(cd.s.bit, pen);
617 }
618 cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
352 } 619 }
353 cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); 620 raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
354 } 621 }
355 /*
356 * We need to do a read after the last update to make sure all
357 * of them are done.
358 */
359 cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
360 raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
361
362 return 0; 622 return 0;
363} 623}
364 624
@@ -366,22 +626,47 @@ static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *
366 * Set affinity for the irq for chips that have the EN*_W1{S,C} 626 * Set affinity for the irq for chips that have the EN*_W1{S,C}
367 * registers. 627 * registers.
368 */ 628 */
369static int octeon_irq_ciu0_set_affinity_v2(unsigned int irq, 629static int octeon_irq_ciu_set_affinity_v2(struct irq_data *data,
370 const struct cpumask *dest) 630 const struct cpumask *dest,
631 bool force)
371{ 632{
372 int cpu; 633 int cpu;
373 int index; 634 struct irq_desc *desc = irq_to_desc(data->irq);
374 struct irq_desc *desc = irq_to_desc(irq);
375 int enable_one = (desc->status & IRQ_DISABLED) == 0; 635 int enable_one = (desc->status & IRQ_DISABLED) == 0;
376 u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); 636 u64 mask;
377 637 union octeon_ciu_chip_data cd;
378 for_each_online_cpu(cpu) { 638
379 index = octeon_coreid_for_cpu(cpu) * 2; 639 if (desc->status & IRQ_DISABLED)
380 if (cpumask_test_cpu(cpu, dest) && enable_one) { 640 return 0;
381 enable_one = 0; 641
382 cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask); 642 cd.p = data->chip_data;
383 } else { 643 mask = 1ull << cd.s.bit;
384 cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); 644
645 if (cd.s.line == 0) {
646 for_each_online_cpu(cpu) {
647 unsigned long *pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
648 int index = octeon_coreid_for_cpu(cpu) * 2;
649 if (cpumask_test_cpu(cpu, dest) && enable_one) {
650 enable_one = 0;
651 set_bit(cd.s.bit, pen);
652 cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
653 } else {
654 clear_bit(cd.s.bit, pen);
655 cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
656 }
657 }
658 } else {
659 for_each_online_cpu(cpu) {
660 unsigned long *pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
661 int index = octeon_coreid_for_cpu(cpu) * 2 + 1;
662 if (cpumask_test_cpu(cpu, dest) && enable_one) {
663 enable_one = 0;
664 set_bit(cd.s.bit, pen);
665 cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
666 } else {
667 clear_bit(cd.s.bit, pen);
668 cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
669 }
385 } 670 }
386 } 671 }
387 return 0; 672 return 0;
@@ -389,80 +674,101 @@ static int octeon_irq_ciu0_set_affinity_v2(unsigned int irq,
389#endif 674#endif
390 675
391/* 676/*
677 * The v1 CIU code already masks things, so supply a dummy version to
678 * the core chip code.
679 */
680static void octeon_irq_dummy_mask(struct irq_data *data)
681{
682 return;
683}
684
685/*
392 * Newer octeon chips have support for lockless CIU operation. 686 * Newer octeon chips have support for lockless CIU operation.
393 */ 687 */
394static struct irq_chip octeon_irq_chip_ciu0_v2 = { 688static struct irq_chip octeon_irq_chip_ciu_v2 = {
395 .name = "CIU0", 689 .name = "CIU",
396 .enable = octeon_irq_ciu0_enable_v2, 690 .irq_enable = octeon_irq_ciu_enable_v2,
397 .disable = octeon_irq_ciu0_disable_all_v2, 691 .irq_disable = octeon_irq_ciu_disable_all_v2,
398 .eoi = octeon_irq_ciu0_enable_v2, 692 .irq_mask = octeon_irq_ciu_disable_local_v2,
693 .irq_unmask = octeon_irq_ciu_enable_v2,
399#ifdef CONFIG_SMP 694#ifdef CONFIG_SMP
400 .set_affinity = octeon_irq_ciu0_set_affinity_v2, 695 .irq_set_affinity = octeon_irq_ciu_set_affinity_v2,
696 .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
401#endif 697#endif
402}; 698};
403 699
404static struct irq_chip octeon_irq_chip_ciu0 = { 700static struct irq_chip octeon_irq_chip_ciu_edge_v2 = {
405 .name = "CIU0", 701 .name = "CIU-E",
406 .enable = octeon_irq_ciu0_enable, 702 .irq_enable = octeon_irq_ciu_enable_v2,
407 .disable = octeon_irq_ciu0_disable, 703 .irq_disable = octeon_irq_ciu_disable_all_v2,
408 .eoi = octeon_irq_ciu0_eoi, 704 .irq_ack = octeon_irq_ciu_ack,
705 .irq_mask = octeon_irq_ciu_disable_local_v2,
706 .irq_unmask = octeon_irq_ciu_enable_v2,
409#ifdef CONFIG_SMP 707#ifdef CONFIG_SMP
410 .set_affinity = octeon_irq_ciu0_set_affinity, 708 .irq_set_affinity = octeon_irq_ciu_set_affinity_v2,
709 .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
411#endif 710#endif
412}; 711};
413 712
414/* The mbox versions don't do any affinity or round-robin. */ 713static struct irq_chip octeon_irq_chip_ciu = {
415static struct irq_chip octeon_irq_chip_ciu0_mbox_v2 = { 714 .name = "CIU",
416 .name = "CIU0-M", 715 .irq_enable = octeon_irq_ciu_enable,
417 .enable = octeon_irq_ciu0_enable_mbox_v2, 716 .irq_disable = octeon_irq_ciu_disable_all,
418 .disable = octeon_irq_ciu0_disable, 717 .irq_mask = octeon_irq_dummy_mask,
419 .eoi = octeon_irq_ciu0_eoi_mbox_v2, 718#ifdef CONFIG_SMP
719 .irq_set_affinity = octeon_irq_ciu_set_affinity,
720 .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
721#endif
420}; 722};
421 723
422static struct irq_chip octeon_irq_chip_ciu0_mbox = { 724static struct irq_chip octeon_irq_chip_ciu_edge = {
423 .name = "CIU0-M", 725 .name = "CIU-E",
424 .enable = octeon_irq_ciu0_enable_mbox, 726 .irq_enable = octeon_irq_ciu_enable,
425 .disable = octeon_irq_ciu0_disable, 727 .irq_disable = octeon_irq_ciu_disable_all,
426 .eoi = octeon_irq_ciu0_eoi, 728 .irq_mask = octeon_irq_dummy_mask,
729 .irq_ack = octeon_irq_ciu_ack,
730#ifdef CONFIG_SMP
731 .irq_set_affinity = octeon_irq_ciu_set_affinity,
732 .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
733#endif
427}; 734};
428 735
429static void octeon_irq_ciu1_ack(unsigned int irq) 736/* The mbox versions don't do any affinity or round-robin. */
430{ 737static struct irq_chip octeon_irq_chip_ciu_mbox_v2 = {
431 /* 738 .name = "CIU-M",
432 * In order to avoid any locking accessing the CIU, we 739 .irq_enable = octeon_irq_ciu_enable_all_v2,
433 * acknowledge CIU interrupts by disabling all of them. This 740 .irq_disable = octeon_irq_ciu_disable_all_v2,
434 * way we can use a per core register and avoid any out of 741 .irq_ack = octeon_irq_ciu_disable_local_v2,
435 * core locking requirements. This has the side affect that 742 .irq_eoi = octeon_irq_ciu_enable_local_v2,
436 * CIU interrupts can't be processed recursively. We don't 743
437 * need to disable IRQs to make these atomic since they are 744 .irq_cpu_online = octeon_irq_cpu_online_mbox_v2,
438 * already disabled earlier in the low level interrupt code. 745 .irq_cpu_offline = octeon_irq_cpu_offline_mbox_v2,
439 */ 746};
440 clear_c0_status(0x100 << 3);
441}
442 747
443static void octeon_irq_ciu1_eoi(unsigned int irq) 748static struct irq_chip octeon_irq_chip_ciu_mbox = {
444{ 749 .name = "CIU-M",
445 /* 750 .irq_enable = octeon_irq_ciu_enable_all,
446 * Enable all CIU interrupts again. We don't need to disable 751 .irq_disable = octeon_irq_ciu_disable_all,
447 * IRQs to make these atomic since they are already disabled
448 * earlier in the low level interrupt code.
449 */
450 set_c0_status(0x100 << 3);
451}
452 752
453static void octeon_irq_ciu1_enable(unsigned int irq) 753 .irq_cpu_online = octeon_irq_cpu_online_mbox,
754 .irq_cpu_offline = octeon_irq_cpu_offline_mbox,
755};
756
757/*
758 * Watchdog interrupts are special. They are associated with a single
759 * core, so we hardwire the affinity to that core.
760 */
761static void octeon_irq_ciu_wd_enable(struct irq_data *data)
454{ 762{
455 struct irq_desc *desc = irq_to_desc(irq);
456 int coreid = next_coreid_for_irq(desc);
457 unsigned long flags; 763 unsigned long flags;
458 uint64_t en1; 764 unsigned long *pen;
459 int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ 765 int coreid = data->irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
766 int cpu = octeon_cpu_for_coreid(coreid);
460 767
461 raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); 768 raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
462 en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); 769 pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
463 en1 |= 1ull << bit; 770 set_bit(coreid, pen);
464 cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1); 771 cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
465 cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
466 raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); 772 raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
467} 773}
468 774
@@ -470,286 +776,281 @@ static void octeon_irq_ciu1_enable(unsigned int irq)
470 * Watchdog interrupts are special. They are associated with a single 776 * Watchdog interrupts are special. They are associated with a single
471 * core, so we hardwire the affinity to that core. 777 * core, so we hardwire the affinity to that core.
472 */ 778 */
473static void octeon_irq_ciu1_wd_enable(unsigned int irq) 779static void octeon_irq_ciu1_wd_enable_v2(struct irq_data *data)
474{ 780{
475 unsigned long flags; 781 int coreid = data->irq - OCTEON_IRQ_WDOG0;
476 uint64_t en1; 782 int cpu = octeon_cpu_for_coreid(coreid);
477 int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
478 int coreid = bit;
479 783
480 raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); 784 set_bit(coreid, &per_cpu(octeon_irq_ciu1_en_mirror, cpu));
481 en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); 785 cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(coreid * 2 + 1), 1ull << coreid);
482 en1 |= 1ull << bit;
483 cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
484 cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
485 raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
486} 786}
487 787
488static void octeon_irq_ciu1_disable(unsigned int irq) 788
789static struct irq_chip octeon_irq_chip_ciu_wd_v2 = {
790 .name = "CIU-W",
791 .irq_enable = octeon_irq_ciu1_wd_enable_v2,
792 .irq_disable = octeon_irq_ciu_disable_all_v2,
793 .irq_mask = octeon_irq_ciu_disable_local_v2,
794 .irq_unmask = octeon_irq_ciu_enable_local_v2,
795};
796
797static struct irq_chip octeon_irq_chip_ciu_wd = {
798 .name = "CIU-W",
799 .irq_enable = octeon_irq_ciu_wd_enable,
800 .irq_disable = octeon_irq_ciu_disable_all,
801 .irq_mask = octeon_irq_dummy_mask,
802};
803
804static void octeon_irq_ip2_v1(void)
489{ 805{
490 int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ 806 const unsigned long core_id = cvmx_get_core_num();
491 unsigned long flags; 807 u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INTX_SUM0(core_id * 2));
492 uint64_t en1; 808
493 int cpu; 809 ciu_sum &= __get_cpu_var(octeon_irq_ciu0_en_mirror);
494 raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); 810 clear_c0_status(STATUSF_IP2);
495 for_each_online_cpu(cpu) { 811 if (likely(ciu_sum)) {
496 int coreid = octeon_coreid_for_cpu(cpu); 812 int bit = fls64(ciu_sum) - 1;
497 en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); 813 int irq = octeon_irq_ciu_to_irq[0][bit];
498 en1 &= ~(1ull << bit); 814 if (likely(irq))
499 cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1); 815 do_IRQ(irq);
816 else
817 spurious_interrupt();
818 } else {
819 spurious_interrupt();
500 } 820 }
501 /* 821 set_c0_status(STATUSF_IP2);
502 * We need to do a read after the last update to make sure all
503 * of them are done.
504 */
505 cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
506 raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
507} 822}
508 823
509/* 824static void octeon_irq_ip2_v2(void)
510 * Enable the irq on the current core for chips that have the EN*_W1{S,C}
511 * registers.
512 */
513static void octeon_irq_ciu1_enable_v2(unsigned int irq)
514{ 825{
515 int index; 826 const unsigned long core_id = cvmx_get_core_num();
516 u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); 827 u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INTX_SUM0(core_id * 2));
517 struct irq_desc *desc = irq_to_desc(irq); 828
518 829 ciu_sum &= __get_cpu_var(octeon_irq_ciu0_en_mirror);
519 if ((desc->status & IRQ_DISABLED) == 0) { 830 if (likely(ciu_sum)) {
520 index = next_coreid_for_irq(desc) * 2 + 1; 831 int bit = fls64(ciu_sum) - 1;
521 cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); 832 int irq = octeon_irq_ciu_to_irq[0][bit];
833 if (likely(irq))
834 do_IRQ(irq);
835 else
836 spurious_interrupt();
837 } else {
838 spurious_interrupt();
522 } 839 }
523} 840}
524 841static void octeon_irq_ip3_v1(void)
525/*
526 * Watchdog interrupts are special. They are associated with a single
527 * core, so we hardwire the affinity to that core.
528 */
529static void octeon_irq_ciu1_wd_enable_v2(unsigned int irq)
530{ 842{
531 int index; 843 u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INT_SUM1);
532 int coreid = irq - OCTEON_IRQ_WDOG0; 844
533 u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); 845 ciu_sum &= __get_cpu_var(octeon_irq_ciu1_en_mirror);
534 struct irq_desc *desc = irq_to_desc(irq); 846 clear_c0_status(STATUSF_IP3);
535 847 if (likely(ciu_sum)) {
536 if ((desc->status & IRQ_DISABLED) == 0) { 848 int bit = fls64(ciu_sum) - 1;
537 index = coreid * 2 + 1; 849 int irq = octeon_irq_ciu_to_irq[1][bit];
538 cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask); 850 if (likely(irq))
851 do_IRQ(irq);
852 else
853 spurious_interrupt();
854 } else {
855 spurious_interrupt();
539 } 856 }
857 set_c0_status(STATUSF_IP3);
540} 858}
541 859
542/* 860static void octeon_irq_ip3_v2(void)
543 * Disable the irq on the current core for chips that have the EN*_W1{S,C}
544 * registers.
545 */
546static void octeon_irq_ciu1_ack_v2(unsigned int irq)
547{ 861{
548 int index = cvmx_get_core_num() * 2 + 1; 862 u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INT_SUM1);
549 u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); 863
550 864 ciu_sum &= __get_cpu_var(octeon_irq_ciu1_en_mirror);
551 cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask); 865 if (likely(ciu_sum)) {
866 int bit = fls64(ciu_sum) - 1;
867 int irq = octeon_irq_ciu_to_irq[1][bit];
868 if (likely(irq))
869 do_IRQ(irq);
870 else
871 spurious_interrupt();
872 } else {
873 spurious_interrupt();
874 }
552} 875}
553 876
554/* 877static void octeon_irq_ip4_mask(void)
555 * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
556 * registers.
557 */
558static void octeon_irq_ciu1_disable_all_v2(unsigned int irq)
559{ 878{
560 u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); 879 clear_c0_status(STATUSF_IP4);
561 int index; 880 spurious_interrupt();
562 int cpu;
563 for_each_online_cpu(cpu) {
564 index = octeon_coreid_for_cpu(cpu) * 2 + 1;
565 cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
566 }
567} 881}
568 882
569#ifdef CONFIG_SMP 883static void (*octeon_irq_ip2)(void);
570static int octeon_irq_ciu1_set_affinity(unsigned int irq, 884static void (*octeon_irq_ip3)(void);
571 const struct cpumask *dest) 885static void (*octeon_irq_ip4)(void);
572{
573 int cpu;
574 struct irq_desc *desc = irq_to_desc(irq);
575 int enable_one = (desc->status & IRQ_DISABLED) == 0;
576 unsigned long flags;
577 int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
578 886
579 /* 887void __cpuinitdata (*octeon_irq_setup_secondary)(void);
580 * For non-v2 CIU, we will allow only single CPU affinity.
581 * This removes the need to do locking in the .ack/.eoi
582 * functions.
583 */
584 if (cpumask_weight(dest) != 1)
585 return -EINVAL;
586 888
587 raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags); 889static void __cpuinit octeon_irq_percpu_enable(void)
588 for_each_online_cpu(cpu) { 890{
589 int coreid = octeon_coreid_for_cpu(cpu); 891 irq_cpu_online();
590 uint64_t en1 = 892}
591 cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); 893
592 if (cpumask_test_cpu(cpu, dest) && enable_one) { 894static void __cpuinit octeon_irq_init_ciu_percpu(void)
593 enable_one = 0; 895{
594 en1 |= 1ull << bit; 896 int coreid = cvmx_get_core_num();
595 } else {
596 en1 &= ~(1ull << bit);
597 }
598 cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
599 }
600 /* 897 /*
601 * We need to do a read after the last update to make sure all 898 * Disable All CIU Interrupts. The ones we need will be
602 * of them are done. 899 * enabled later. Read the SUM register so we know the write
900 * completed.
603 */ 901 */
604 cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1)); 902 cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), 0);
605 raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags); 903 cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0);
606 904 cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0);
607 return 0; 905 cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0);
906 cvmx_read_csr(CVMX_CIU_INTX_SUM0((coreid * 2)));
608} 907}
609 908
610/* 909static void __cpuinit octeon_irq_setup_secondary_ciu(void)
611 * Set affinity for the irq for chips that have the EN*_W1{S,C}
612 * registers.
613 */
614static int octeon_irq_ciu1_set_affinity_v2(unsigned int irq,
615 const struct cpumask *dest)
616{ 910{
617 int cpu;
618 int index;
619 struct irq_desc *desc = irq_to_desc(irq);
620 int enable_one = (desc->status & IRQ_DISABLED) == 0;
621 u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
622 for_each_online_cpu(cpu) {
623 index = octeon_coreid_for_cpu(cpu) * 2 + 1;
624 if (cpumask_test_cpu(cpu, dest) && enable_one) {
625 enable_one = 0;
626 cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
627 } else {
628 cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
629 }
630 }
631 return 0;
632}
633#endif
634 911
635/* 912 __get_cpu_var(octeon_irq_ciu0_en_mirror) = 0;
636 * Newer octeon chips have support for lockless CIU operation. 913 __get_cpu_var(octeon_irq_ciu1_en_mirror) = 0;
637 */
638static struct irq_chip octeon_irq_chip_ciu1_v2 = {
639 .name = "CIU1",
640 .enable = octeon_irq_ciu1_enable_v2,
641 .disable = octeon_irq_ciu1_disable_all_v2,
642 .eoi = octeon_irq_ciu1_enable_v2,
643#ifdef CONFIG_SMP
644 .set_affinity = octeon_irq_ciu1_set_affinity_v2,
645#endif
646};
647 914
648static struct irq_chip octeon_irq_chip_ciu1 = { 915 octeon_irq_init_ciu_percpu();
649 .name = "CIU1", 916 octeon_irq_percpu_enable();
650 .enable = octeon_irq_ciu1_enable,
651 .disable = octeon_irq_ciu1_disable,
652 .eoi = octeon_irq_ciu1_eoi,
653#ifdef CONFIG_SMP
654 .set_affinity = octeon_irq_ciu1_set_affinity,
655#endif
656};
657 917
658static struct irq_chip octeon_irq_chip_ciu1_wd_v2 = { 918 /* Enable the CIU lines */
659 .name = "CIU1-W", 919 set_c0_status(STATUSF_IP3 | STATUSF_IP2);
660 .enable = octeon_irq_ciu1_wd_enable_v2, 920 clear_c0_status(STATUSF_IP4);
661 .disable = octeon_irq_ciu1_disable_all_v2, 921}
662 .eoi = octeon_irq_ciu1_wd_enable_v2,
663};
664 922
665static struct irq_chip octeon_irq_chip_ciu1_wd = { 923static void __init octeon_irq_init_ciu(void)
666 .name = "CIU1-W", 924{
667 .enable = octeon_irq_ciu1_wd_enable, 925 unsigned int i;
668 .disable = octeon_irq_ciu1_disable, 926 struct irq_chip *chip;
669 .eoi = octeon_irq_ciu1_eoi, 927 struct irq_chip *chip_edge;
670}; 928 struct irq_chip *chip_mbox;
929 struct irq_chip *chip_wd;
930
931 octeon_irq_init_ciu_percpu();
932 octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu;
671 933
672static void (*octeon_ciu0_ack)(unsigned int); 934 if (OCTEON_IS_MODEL(OCTEON_CN58XX_PASS2_X) ||
673static void (*octeon_ciu1_ack)(unsigned int); 935 OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) ||
936 OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X) ||
937 OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
938 octeon_irq_ip2 = octeon_irq_ip2_v2;
939 octeon_irq_ip3 = octeon_irq_ip3_v2;
940 chip = &octeon_irq_chip_ciu_v2;
941 chip_edge = &octeon_irq_chip_ciu_edge_v2;
942 chip_mbox = &octeon_irq_chip_ciu_mbox_v2;
943 chip_wd = &octeon_irq_chip_ciu_wd_v2;
944 } else {
945 octeon_irq_ip2 = octeon_irq_ip2_v1;
946 octeon_irq_ip3 = octeon_irq_ip3_v1;
947 chip = &octeon_irq_chip_ciu;
948 chip_edge = &octeon_irq_chip_ciu_edge;
949 chip_mbox = &octeon_irq_chip_ciu_mbox;
950 chip_wd = &octeon_irq_chip_ciu_wd;
951 }
952 octeon_irq_ip4 = octeon_irq_ip4_mask;
953
954 /* Mips internal */
955 octeon_irq_init_core();
956
957 /* CIU_0 */
958 for (i = 0; i < 16; i++)
959 octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq);
960 for (i = 0; i < 16; i++)
961 octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16, chip, handle_level_irq);
962
963 octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq);
964 octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq);
965
966 octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART0, 0, 34, chip, handle_level_irq);
967 octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART1, 0, 35, chip, handle_level_irq);
968
969 for (i = 0; i < 4; i++)
970 octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq);
971 for (i = 0; i < 4; i++)
972 octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq);
973
974 octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI, 0, 45, chip, handle_level_irq);
975 octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq);
976 octeon_irq_set_ciu_mapping(OCTEON_IRQ_TRACE0, 0, 47, chip, handle_level_irq);
977
978 for (i = 0; i < 2; i++)
979 octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GMX_DRP0, 0, i + 48, chip_edge, handle_edge_irq);
980
981 octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD_DRP, 0, 50, chip_edge, handle_edge_irq);
982 octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY_ZERO, 0, 51, chip_edge, handle_edge_irq);
983
984 for (i = 0; i < 4; i++)
985 octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip_edge, handle_edge_irq);
986
987 octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq);
988 octeon_irq_set_ciu_mapping(OCTEON_IRQ_PCM, 0, 57, chip, handle_level_irq);
989 octeon_irq_set_ciu_mapping(OCTEON_IRQ_MPI, 0, 58, chip, handle_level_irq);
990 octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI2, 0, 59, chip, handle_level_irq);
991 octeon_irq_set_ciu_mapping(OCTEON_IRQ_POWIQ, 0, 60, chip, handle_level_irq);
992 octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPDPPTHR, 0, 61, chip, handle_level_irq);
993 octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII0, 0, 62, chip, handle_level_irq);
994 octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq);
995
996 /* CIU_1 */
997 for (i = 0; i < 16; i++)
998 octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq);
999
1000 octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART2, 1, 16, chip, handle_level_irq);
1001 octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq);
1002 octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII1, 1, 18, chip, handle_level_irq);
1003 octeon_irq_set_ciu_mapping(OCTEON_IRQ_NAND, 1, 19, chip, handle_level_irq);
1004 octeon_irq_set_ciu_mapping(OCTEON_IRQ_MIO, 1, 20, chip, handle_level_irq);
1005 octeon_irq_set_ciu_mapping(OCTEON_IRQ_IOB, 1, 21, chip, handle_level_irq);
1006 octeon_irq_set_ciu_mapping(OCTEON_IRQ_FPA, 1, 22, chip, handle_level_irq);
1007 octeon_irq_set_ciu_mapping(OCTEON_IRQ_POW, 1, 23, chip, handle_level_irq);
1008 octeon_irq_set_ciu_mapping(OCTEON_IRQ_L2C, 1, 24, chip, handle_level_irq);
1009 octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD, 1, 25, chip, handle_level_irq);
1010 octeon_irq_set_ciu_mapping(OCTEON_IRQ_PIP, 1, 26, chip, handle_level_irq);
1011 octeon_irq_set_ciu_mapping(OCTEON_IRQ_PKO, 1, 27, chip, handle_level_irq);
1012 octeon_irq_set_ciu_mapping(OCTEON_IRQ_ZIP, 1, 28, chip, handle_level_irq);
1013 octeon_irq_set_ciu_mapping(OCTEON_IRQ_TIM, 1, 29, chip, handle_level_irq);
1014 octeon_irq_set_ciu_mapping(OCTEON_IRQ_RAD, 1, 30, chip, handle_level_irq);
1015 octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY, 1, 31, chip, handle_level_irq);
1016 octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFA, 1, 32, chip, handle_level_irq);
1017 octeon_irq_set_ciu_mapping(OCTEON_IRQ_USBCTL, 1, 33, chip, handle_level_irq);
1018 octeon_irq_set_ciu_mapping(OCTEON_IRQ_SLI, 1, 34, chip, handle_level_irq);
1019 octeon_irq_set_ciu_mapping(OCTEON_IRQ_DPI, 1, 35, chip, handle_level_irq);
1020
1021 octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGX0, 1, 36, chip, handle_level_irq);
1022
1023 octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGL, 1, 46, chip, handle_level_irq);
1024
1025 octeon_irq_set_ciu_mapping(OCTEON_IRQ_PTP, 1, 47, chip_edge, handle_edge_irq);
1026
1027 octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM0, 1, 48, chip, handle_level_irq);
1028 octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM1, 1, 49, chip, handle_level_irq);
1029 octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO0, 1, 50, chip, handle_level_irq);
1030 octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO1, 1, 51, chip, handle_level_irq);
1031 octeon_irq_set_ciu_mapping(OCTEON_IRQ_LMC0, 1, 52, chip, handle_level_irq);
1032 octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFM, 1, 56, chip, handle_level_irq);
1033 octeon_irq_set_ciu_mapping(OCTEON_IRQ_RST, 1, 63, chip, handle_level_irq);
1034
1035 /* Enable the CIU lines */
1036 set_c0_status(STATUSF_IP3 | STATUSF_IP2);
1037 clear_c0_status(STATUSF_IP4);
1038}
674 1039
675void __init arch_init_irq(void) 1040void __init arch_init_irq(void)
676{ 1041{
677 unsigned int irq;
678 struct irq_chip *chip0;
679 struct irq_chip *chip0_mbox;
680 struct irq_chip *chip1;
681 struct irq_chip *chip1_wd;
682
683#ifdef CONFIG_SMP 1042#ifdef CONFIG_SMP
684 /* Set the default affinity to the boot cpu. */ 1043 /* Set the default affinity to the boot cpu. */
685 cpumask_clear(irq_default_affinity); 1044 cpumask_clear(irq_default_affinity);
686 cpumask_set_cpu(smp_processor_id(), irq_default_affinity); 1045 cpumask_set_cpu(smp_processor_id(), irq_default_affinity);
687#endif 1046#endif
688 1047 octeon_irq_init_ciu();
689 if (NR_IRQS < OCTEON_IRQ_LAST)
690 pr_err("octeon_irq_init: NR_IRQS is set too low\n");
691
692 if (OCTEON_IS_MODEL(OCTEON_CN58XX_PASS2_X) ||
693 OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) ||
694 OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X)) {
695 octeon_ciu0_ack = octeon_irq_ciu0_ack_v2;
696 octeon_ciu1_ack = octeon_irq_ciu1_ack_v2;
697 chip0 = &octeon_irq_chip_ciu0_v2;
698 chip0_mbox = &octeon_irq_chip_ciu0_mbox_v2;
699 chip1 = &octeon_irq_chip_ciu1_v2;
700 chip1_wd = &octeon_irq_chip_ciu1_wd_v2;
701 } else {
702 octeon_ciu0_ack = octeon_irq_ciu0_ack;
703 octeon_ciu1_ack = octeon_irq_ciu1_ack;
704 chip0 = &octeon_irq_chip_ciu0;
705 chip0_mbox = &octeon_irq_chip_ciu0_mbox;
706 chip1 = &octeon_irq_chip_ciu1;
707 chip1_wd = &octeon_irq_chip_ciu1_wd;
708 }
709
710 /* 0 - 15 reserved for i8259 master and slave controller. */
711
712 /* 17 - 23 Mips internal */
713 for (irq = OCTEON_IRQ_SW0; irq <= OCTEON_IRQ_TIMER; irq++) {
714 set_irq_chip_and_handler(irq, &octeon_irq_chip_core,
715 handle_percpu_irq);
716 }
717
718 /* 24 - 87 CIU_INT_SUM0 */
719 for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_BOOTDMA; irq++) {
720 switch (irq) {
721 case OCTEON_IRQ_MBOX0:
722 case OCTEON_IRQ_MBOX1:
723 set_irq_chip_and_handler(irq, chip0_mbox, handle_percpu_irq);
724 break;
725 default:
726 set_irq_chip_and_handler(irq, chip0, handle_fasteoi_irq);
727 break;
728 }
729 }
730
731 /* 88 - 151 CIU_INT_SUM1 */
732 for (irq = OCTEON_IRQ_WDOG0; irq <= OCTEON_IRQ_WDOG15; irq++)
733 set_irq_chip_and_handler(irq, chip1_wd, handle_fasteoi_irq);
734
735 for (irq = OCTEON_IRQ_UART2; irq <= OCTEON_IRQ_RESERVED151; irq++)
736 set_irq_chip_and_handler(irq, chip1, handle_fasteoi_irq);
737
738 set_c0_status(0x300 << 2);
739} 1048}
740 1049
741asmlinkage void plat_irq_dispatch(void) 1050asmlinkage void plat_irq_dispatch(void)
742{ 1051{
743 const unsigned long core_id = cvmx_get_core_num();
744 const uint64_t ciu_sum0_address = CVMX_CIU_INTX_SUM0(core_id * 2);
745 const uint64_t ciu_en0_address = CVMX_CIU_INTX_EN0(core_id * 2);
746 const uint64_t ciu_sum1_address = CVMX_CIU_INT_SUM1;
747 const uint64_t ciu_en1_address = CVMX_CIU_INTX_EN1(core_id * 2 + 1);
748 unsigned long cop0_cause; 1052 unsigned long cop0_cause;
749 unsigned long cop0_status; 1053 unsigned long cop0_status;
750 uint64_t ciu_en;
751 uint64_t ciu_sum;
752 unsigned int irq;
753 1054
754 while (1) { 1055 while (1) {
755 cop0_cause = read_c0_cause(); 1056 cop0_cause = read_c0_cause();
@@ -757,33 +1058,16 @@ asmlinkage void plat_irq_dispatch(void)
757 cop0_cause &= cop0_status; 1058 cop0_cause &= cop0_status;
758 cop0_cause &= ST0_IM; 1059 cop0_cause &= ST0_IM;
759 1060
760 if (unlikely(cop0_cause & STATUSF_IP2)) { 1061 if (unlikely(cop0_cause & STATUSF_IP2))
761 ciu_sum = cvmx_read_csr(ciu_sum0_address); 1062 octeon_irq_ip2();
762 ciu_en = cvmx_read_csr(ciu_en0_address); 1063 else if (unlikely(cop0_cause & STATUSF_IP3))
763 ciu_sum &= ciu_en; 1064 octeon_irq_ip3();
764 if (likely(ciu_sum)) { 1065 else if (unlikely(cop0_cause & STATUSF_IP4))
765 irq = fls64(ciu_sum) + OCTEON_IRQ_WORKQ0 - 1; 1066 octeon_irq_ip4();
766 octeon_ciu0_ack(irq); 1067 else if (likely(cop0_cause))
767 do_IRQ(irq);
768 } else {
769 spurious_interrupt();
770 }
771 } else if (unlikely(cop0_cause & STATUSF_IP3)) {
772 ciu_sum = cvmx_read_csr(ciu_sum1_address);
773 ciu_en = cvmx_read_csr(ciu_en1_address);
774 ciu_sum &= ciu_en;
775 if (likely(ciu_sum)) {
776 irq = fls64(ciu_sum) + OCTEON_IRQ_WDOG0 - 1;
777 octeon_ciu1_ack(irq);
778 do_IRQ(irq);
779 } else {
780 spurious_interrupt();
781 }
782 } else if (likely(cop0_cause)) {
783 do_IRQ(fls(cop0_cause) - 9 + MIPS_CPU_IRQ_BASE); 1068 do_IRQ(fls(cop0_cause) - 9 + MIPS_CPU_IRQ_BASE);
784 } else { 1069 else
785 break; 1070 break;
786 }
787 } 1071 }
788} 1072}
789 1073
@@ -791,83 +1075,7 @@ asmlinkage void plat_irq_dispatch(void)
791 1075
792void fixup_irqs(void) 1076void fixup_irqs(void)
793{ 1077{
794 int irq; 1078 irq_cpu_offline();
795 struct irq_desc *desc;
796 cpumask_t new_affinity;
797 unsigned long flags;
798 int do_set_affinity;
799 int cpu;
800
801 cpu = smp_processor_id();
802
803 for (irq = OCTEON_IRQ_SW0; irq <= OCTEON_IRQ_TIMER; irq++)
804 octeon_irq_core_disable_local(irq);
805
806 for (irq = OCTEON_IRQ_WORKQ0; irq < OCTEON_IRQ_LAST; irq++) {
807 desc = irq_to_desc(irq);
808 switch (irq) {
809 case OCTEON_IRQ_MBOX0:
810 case OCTEON_IRQ_MBOX1:
811 /* The eoi function will disable them on this CPU. */
812 desc->chip->eoi(irq);
813 break;
814 case OCTEON_IRQ_WDOG0:
815 case OCTEON_IRQ_WDOG1:
816 case OCTEON_IRQ_WDOG2:
817 case OCTEON_IRQ_WDOG3:
818 case OCTEON_IRQ_WDOG4:
819 case OCTEON_IRQ_WDOG5:
820 case OCTEON_IRQ_WDOG6:
821 case OCTEON_IRQ_WDOG7:
822 case OCTEON_IRQ_WDOG8:
823 case OCTEON_IRQ_WDOG9:
824 case OCTEON_IRQ_WDOG10:
825 case OCTEON_IRQ_WDOG11:
826 case OCTEON_IRQ_WDOG12:
827 case OCTEON_IRQ_WDOG13:
828 case OCTEON_IRQ_WDOG14:
829 case OCTEON_IRQ_WDOG15:
830 /*
831 * These have special per CPU semantics and
832 * are handled in the watchdog driver.
833 */
834 break;
835 default:
836 raw_spin_lock_irqsave(&desc->lock, flags);
837 /*
838 * If this irq has an action, it is in use and
839 * must be migrated if it has affinity to this
840 * cpu.
841 */
842 if (desc->action && cpumask_test_cpu(cpu, desc->affinity)) {
843 if (cpumask_weight(desc->affinity) > 1) {
844 /*
845 * It has multi CPU affinity,
846 * just remove this CPU from
847 * the affinity set.
848 */
849 cpumask_copy(&new_affinity, desc->affinity);
850 cpumask_clear_cpu(cpu, &new_affinity);
851 } else {
852 /*
853 * Otherwise, put it on lowest
854 * numbered online CPU.
855 */
856 cpumask_clear(&new_affinity);
857 cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity);
858 }
859 do_set_affinity = 1;
860 } else {
861 do_set_affinity = 0;
862 }
863 raw_spin_unlock_irqrestore(&desc->lock, flags);
864
865 if (do_set_affinity)
866 irq_set_affinity(irq, &new_affinity);
867
868 break;
869 }
870 }
871} 1079}
872 1080
873#endif /* CONFIG_HOTPLUG_CPU */ 1081#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index b0c3686c96dd..8b139bf4a1b5 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -420,7 +420,6 @@ void octeon_user_io_init(void)
420void __init prom_init(void) 420void __init prom_init(void)
421{ 421{
422 struct cvmx_sysinfo *sysinfo; 422 struct cvmx_sysinfo *sysinfo;
423 const int coreid = cvmx_get_core_num();
424 int i; 423 int i;
425 int argc; 424 int argc;
426#ifdef CONFIG_CAVIUM_RESERVE32 425#ifdef CONFIG_CAVIUM_RESERVE32
@@ -537,17 +536,6 @@ void __init prom_init(void)
537 536
538 octeon_uart = octeon_get_boot_uart(); 537 octeon_uart = octeon_get_boot_uart();
539 538
540 /*
541 * Disable All CIU Interrupts. The ones we need will be
542 * enabled later. Read the SUM register so we know the write
543 * completed.
544 */
545 cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), 0);
546 cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0);
547 cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0);
548 cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0);
549 cvmx_read_csr(CVMX_CIU_INTX_SUM0((coreid * 2)));
550
551#ifdef CONFIG_SMP 539#ifdef CONFIG_SMP
552 octeon_write_lcd("LinuxSMP"); 540 octeon_write_lcd("LinuxSMP");
553#else 541#else
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c
index 391cefe556b3..ba78b21cc8d0 100644
--- a/arch/mips/cavium-octeon/smp.c
+++ b/arch/mips/cavium-octeon/smp.c
@@ -171,41 +171,19 @@ static void octeon_boot_secondary(int cpu, struct task_struct *idle)
171 * After we've done initial boot, this function is called to allow the 171 * After we've done initial boot, this function is called to allow the
172 * board code to clean up state, if needed 172 * board code to clean up state, if needed
173 */ 173 */
174static void octeon_init_secondary(void) 174static void __cpuinit octeon_init_secondary(void)
175{ 175{
176 const int coreid = cvmx_get_core_num();
177 union cvmx_ciu_intx_sum0 interrupt_enable;
178 unsigned int sr; 176 unsigned int sr;
179 177
180#ifdef CONFIG_HOTPLUG_CPU
181 struct linux_app_boot_info *labi;
182
183 labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER);
184
185 if (labi->labi_signature != LABI_SIGNATURE)
186 panic("The bootloader version on this board is incorrect.");
187#endif
188
189 sr = set_c0_status(ST0_BEV); 178 sr = set_c0_status(ST0_BEV);
190 write_c0_ebase((u32)ebase); 179 write_c0_ebase((u32)ebase);
191 write_c0_status(sr); 180 write_c0_status(sr);
192 181
193 octeon_check_cpu_bist(); 182 octeon_check_cpu_bist();
194 octeon_init_cvmcount(); 183 octeon_init_cvmcount();
195 /* 184
196 pr_info("SMP: CPU%d (CoreId %lu) started\n", cpu, coreid); 185 octeon_irq_setup_secondary();
197 */ 186 raw_local_irq_enable();
198 /* Enable Mailbox interrupts to this core. These are the only
199 interrupts allowed on line 3 */
200 cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), 0xffffffff);
201 interrupt_enable.u64 = 0;
202 interrupt_enable.s.mbox = 0x3;
203 cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), interrupt_enable.u64);
204 cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0);
205 cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0);
206 cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0);
207 /* Enable core interrupt processing for 2,3 and 7 */
208 set_c0_status(0x8c01);
209} 187}
210 188
211/** 189/**
@@ -214,6 +192,15 @@ static void octeon_init_secondary(void)
214 */ 192 */
215void octeon_prepare_cpus(unsigned int max_cpus) 193void octeon_prepare_cpus(unsigned int max_cpus)
216{ 194{
195#ifdef CONFIG_HOTPLUG_CPU
196 struct linux_app_boot_info *labi;
197
198 labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER);
199
200 if (labi->labi_signature != LABI_SIGNATURE)
201 panic("The bootloader version on this board is incorrect.");
202#endif
203
217 cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffffffff); 204 cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffffffff);
218 if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_DISABLED, 205 if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_DISABLED,
219 "mailbox0", mailbox_interrupt)) { 206 "mailbox0", mailbox_interrupt)) {
diff --git a/arch/mips/include/asm/mach-cavium-octeon/irq.h b/arch/mips/include/asm/mach-cavium-octeon/irq.h
index 6ddab8aef644..5b05f186e395 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/irq.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/irq.h
@@ -11,172 +11,91 @@
11#define NR_IRQS OCTEON_IRQ_LAST 11#define NR_IRQS OCTEON_IRQ_LAST
12#define MIPS_CPU_IRQ_BASE OCTEON_IRQ_SW0 12#define MIPS_CPU_IRQ_BASE OCTEON_IRQ_SW0
13 13
14/* 0 - 7 represent the i8259 master */ 14enum octeon_irq {
15#define OCTEON_IRQ_I8259M0 0 15/* 1 - 8 represent the 8 MIPS standard interrupt sources */
16#define OCTEON_IRQ_I8259M1 1 16 OCTEON_IRQ_SW0 = 1,
17#define OCTEON_IRQ_I8259M2 2 17 OCTEON_IRQ_SW1,
18#define OCTEON_IRQ_I8259M3 3 18/* CIU0, CUI2, CIU4 are 3, 4, 5 */
19#define OCTEON_IRQ_I8259M4 4 19 OCTEON_IRQ_5 = 6,
20#define OCTEON_IRQ_I8259M5 5 20 OCTEON_IRQ_PERF,
21#define OCTEON_IRQ_I8259M6 6 21 OCTEON_IRQ_TIMER,
22#define OCTEON_IRQ_I8259M7 7 22/* sources in CIU_INTX_EN0 */
23/* 8 - 15 represent the i8259 slave */ 23 OCTEON_IRQ_WORKQ0,
24#define OCTEON_IRQ_I8259S0 8 24 OCTEON_IRQ_GPIO0 = OCTEON_IRQ_WORKQ0 + 16,
25#define OCTEON_IRQ_I8259S1 9 25 OCTEON_IRQ_WDOG0 = OCTEON_IRQ_GPIO0 + 16,
26#define OCTEON_IRQ_I8259S2 10 26 OCTEON_IRQ_WDOG15 = OCTEON_IRQ_WDOG0 + 15,
27#define OCTEON_IRQ_I8259S3 11 27 OCTEON_IRQ_MBOX0 = OCTEON_IRQ_WDOG0 + 16,
28#define OCTEON_IRQ_I8259S4 12 28 OCTEON_IRQ_MBOX1,
29#define OCTEON_IRQ_I8259S5 13 29 OCTEON_IRQ_UART0,
30#define OCTEON_IRQ_I8259S6 14 30 OCTEON_IRQ_UART1,
31#define OCTEON_IRQ_I8259S7 15 31 OCTEON_IRQ_UART2,
32/* 16 - 23 represent the 8 MIPS standard interrupt sources */ 32 OCTEON_IRQ_PCI_INT0,
33#define OCTEON_IRQ_SW0 16 33 OCTEON_IRQ_PCI_INT1,
34#define OCTEON_IRQ_SW1 17 34 OCTEON_IRQ_PCI_INT2,
35#define OCTEON_IRQ_CIU0 18 35 OCTEON_IRQ_PCI_INT3,
36#define OCTEON_IRQ_CIU1 19 36 OCTEON_IRQ_PCI_MSI0,
37#define OCTEON_IRQ_CIU4 20 37 OCTEON_IRQ_PCI_MSI1,
38#define OCTEON_IRQ_5 21 38 OCTEON_IRQ_PCI_MSI2,
39#define OCTEON_IRQ_PERF 22 39 OCTEON_IRQ_PCI_MSI3,
40#define OCTEON_IRQ_TIMER 23 40
41/* 24 - 87 represent the sources in CIU_INTX_EN0 */ 41 OCTEON_IRQ_TWSI,
42#define OCTEON_IRQ_WORKQ0 24 42 OCTEON_IRQ_TWSI2,
43#define OCTEON_IRQ_WORKQ1 25 43 OCTEON_IRQ_RML,
44#define OCTEON_IRQ_WORKQ2 26 44 OCTEON_IRQ_TRACE0,
45#define OCTEON_IRQ_WORKQ3 27 45 OCTEON_IRQ_GMX_DRP0 = OCTEON_IRQ_TRACE0 + 4,
46#define OCTEON_IRQ_WORKQ4 28 46 OCTEON_IRQ_IPD_DRP = OCTEON_IRQ_GMX_DRP0 + 5,
47#define OCTEON_IRQ_WORKQ5 29 47 OCTEON_IRQ_KEY_ZERO,
48#define OCTEON_IRQ_WORKQ6 30 48 OCTEON_IRQ_TIMER0,
49#define OCTEON_IRQ_WORKQ7 31 49 OCTEON_IRQ_TIMER1,
50#define OCTEON_IRQ_WORKQ8 32 50 OCTEON_IRQ_TIMER2,
51#define OCTEON_IRQ_WORKQ9 33 51 OCTEON_IRQ_TIMER3,
52#define OCTEON_IRQ_WORKQ10 34 52 OCTEON_IRQ_USB0,
53#define OCTEON_IRQ_WORKQ11 35 53 OCTEON_IRQ_USB1,
54#define OCTEON_IRQ_WORKQ12 36 54 OCTEON_IRQ_PCM,
55#define OCTEON_IRQ_WORKQ13 37 55 OCTEON_IRQ_MPI,
56#define OCTEON_IRQ_WORKQ14 38 56 OCTEON_IRQ_POWIQ,
57#define OCTEON_IRQ_WORKQ15 39 57 OCTEON_IRQ_IPDPPTHR,
58#define OCTEON_IRQ_GPIO0 40 58 OCTEON_IRQ_MII0,
59#define OCTEON_IRQ_GPIO1 41 59 OCTEON_IRQ_MII1,
60#define OCTEON_IRQ_GPIO2 42 60 OCTEON_IRQ_BOOTDMA,
61#define OCTEON_IRQ_GPIO3 43 61
62#define OCTEON_IRQ_GPIO4 44 62 OCTEON_IRQ_NAND,
63#define OCTEON_IRQ_GPIO5 45 63 OCTEON_IRQ_MIO, /* Summary of MIO_BOOT_ERR */
64#define OCTEON_IRQ_GPIO6 46 64 OCTEON_IRQ_IOB, /* Summary of IOB_INT_SUM */
65#define OCTEON_IRQ_GPIO7 47 65 OCTEON_IRQ_FPA, /* Summary of FPA_INT_SUM */
66#define OCTEON_IRQ_GPIO8 48 66 OCTEON_IRQ_POW, /* Summary of POW_ECC_ERR */
67#define OCTEON_IRQ_GPIO9 49 67 OCTEON_IRQ_L2C, /* Summary of L2C_INT_STAT */
68#define OCTEON_IRQ_GPIO10 50 68 OCTEON_IRQ_IPD, /* Summary of IPD_INT_SUM */
69#define OCTEON_IRQ_GPIO11 51 69 OCTEON_IRQ_PIP, /* Summary of PIP_INT_REG */
70#define OCTEON_IRQ_GPIO12 52 70 OCTEON_IRQ_PKO, /* Summary of PKO_REG_ERROR */
71#define OCTEON_IRQ_GPIO13 53 71 OCTEON_IRQ_ZIP, /* Summary of ZIP_ERROR */
72#define OCTEON_IRQ_GPIO14 54 72 OCTEON_IRQ_TIM, /* Summary of TIM_REG_ERROR */
73#define OCTEON_IRQ_GPIO15 55 73 OCTEON_IRQ_RAD, /* Summary of RAD_REG_ERROR */
74#define OCTEON_IRQ_MBOX0 56 74 OCTEON_IRQ_KEY, /* Summary of KEY_INT_SUM */
75#define OCTEON_IRQ_MBOX1 57 75 OCTEON_IRQ_DFA, /* Summary of DFA */
76#define OCTEON_IRQ_UART0 58 76 OCTEON_IRQ_USBCTL, /* Summary of USBN0_INT_SUM */
77#define OCTEON_IRQ_UART1 59 77 OCTEON_IRQ_SLI, /* Summary of SLI_INT_SUM */
78#define OCTEON_IRQ_PCI_INT0 60 78 OCTEON_IRQ_DPI, /* Summary of DPI_INT_SUM */
79#define OCTEON_IRQ_PCI_INT1 61 79 OCTEON_IRQ_AGX0, /* Summary of GMX0*+PCS0_INT*_REG */
80#define OCTEON_IRQ_PCI_INT2 62 80 OCTEON_IRQ_AGL = OCTEON_IRQ_AGX0 + 5,
81#define OCTEON_IRQ_PCI_INT3 63 81 OCTEON_IRQ_PTP,
82#define OCTEON_IRQ_PCI_MSI0 64 82 OCTEON_IRQ_PEM0,
83#define OCTEON_IRQ_PCI_MSI1 65 83 OCTEON_IRQ_PEM1,
84#define OCTEON_IRQ_PCI_MSI2 66 84 OCTEON_IRQ_SRIO0,
85#define OCTEON_IRQ_PCI_MSI3 67 85 OCTEON_IRQ_SRIO1,
86#define OCTEON_IRQ_RESERVED68 68 /* Summary of CIU_INT_SUM1 */ 86 OCTEON_IRQ_LMC0,
87#define OCTEON_IRQ_TWSI 69 87 OCTEON_IRQ_DFM = OCTEON_IRQ_LMC0 + 4, /* Summary of DFM */
88#define OCTEON_IRQ_RML 70 88 OCTEON_IRQ_RST,
89#define OCTEON_IRQ_TRACE 71 89};
90#define OCTEON_IRQ_GMX_DRP0 72
91#define OCTEON_IRQ_GMX_DRP1 73
92#define OCTEON_IRQ_IPD_DRP 74
93#define OCTEON_IRQ_KEY_ZERO 75
94#define OCTEON_IRQ_TIMER0 76
95#define OCTEON_IRQ_TIMER1 77
96#define OCTEON_IRQ_TIMER2 78
97#define OCTEON_IRQ_TIMER3 79
98#define OCTEON_IRQ_USB0 80
99#define OCTEON_IRQ_PCM 81
100#define OCTEON_IRQ_MPI 82
101#define OCTEON_IRQ_TWSI2 83
102#define OCTEON_IRQ_POWIQ 84
103#define OCTEON_IRQ_IPDPPTHR 85
104#define OCTEON_IRQ_MII0 86
105#define OCTEON_IRQ_BOOTDMA 87
106/* 88 - 151 represent the sources in CIU_INTX_EN1 */
107#define OCTEON_IRQ_WDOG0 88
108#define OCTEON_IRQ_WDOG1 89
109#define OCTEON_IRQ_WDOG2 90
110#define OCTEON_IRQ_WDOG3 91
111#define OCTEON_IRQ_WDOG4 92
112#define OCTEON_IRQ_WDOG5 93
113#define OCTEON_IRQ_WDOG6 94
114#define OCTEON_IRQ_WDOG7 95
115#define OCTEON_IRQ_WDOG8 96
116#define OCTEON_IRQ_WDOG9 97
117#define OCTEON_IRQ_WDOG10 98
118#define OCTEON_IRQ_WDOG11 99
119#define OCTEON_IRQ_WDOG12 100
120#define OCTEON_IRQ_WDOG13 101
121#define OCTEON_IRQ_WDOG14 102
122#define OCTEON_IRQ_WDOG15 103
123#define OCTEON_IRQ_UART2 104
124#define OCTEON_IRQ_USB1 105
125#define OCTEON_IRQ_MII1 106
126#define OCTEON_IRQ_RESERVED107 107
127#define OCTEON_IRQ_RESERVED108 108
128#define OCTEON_IRQ_RESERVED109 109
129#define OCTEON_IRQ_RESERVED110 110
130#define OCTEON_IRQ_RESERVED111 111
131#define OCTEON_IRQ_RESERVED112 112
132#define OCTEON_IRQ_RESERVED113 113
133#define OCTEON_IRQ_RESERVED114 114
134#define OCTEON_IRQ_RESERVED115 115
135#define OCTEON_IRQ_RESERVED116 116
136#define OCTEON_IRQ_RESERVED117 117
137#define OCTEON_IRQ_RESERVED118 118
138#define OCTEON_IRQ_RESERVED119 119
139#define OCTEON_IRQ_RESERVED120 120
140#define OCTEON_IRQ_RESERVED121 121
141#define OCTEON_IRQ_RESERVED122 122
142#define OCTEON_IRQ_RESERVED123 123
143#define OCTEON_IRQ_RESERVED124 124
144#define OCTEON_IRQ_RESERVED125 125
145#define OCTEON_IRQ_RESERVED126 126
146#define OCTEON_IRQ_RESERVED127 127
147#define OCTEON_IRQ_RESERVED128 128
148#define OCTEON_IRQ_RESERVED129 129
149#define OCTEON_IRQ_RESERVED130 130
150#define OCTEON_IRQ_RESERVED131 131
151#define OCTEON_IRQ_RESERVED132 132
152#define OCTEON_IRQ_RESERVED133 133
153#define OCTEON_IRQ_RESERVED134 134
154#define OCTEON_IRQ_RESERVED135 135
155#define OCTEON_IRQ_RESERVED136 136
156#define OCTEON_IRQ_RESERVED137 137
157#define OCTEON_IRQ_RESERVED138 138
158#define OCTEON_IRQ_RESERVED139 139
159#define OCTEON_IRQ_RESERVED140 140
160#define OCTEON_IRQ_RESERVED141 141
161#define OCTEON_IRQ_RESERVED142 142
162#define OCTEON_IRQ_RESERVED143 143
163#define OCTEON_IRQ_RESERVED144 144
164#define OCTEON_IRQ_RESERVED145 145
165#define OCTEON_IRQ_RESERVED146 146
166#define OCTEON_IRQ_RESERVED147 147
167#define OCTEON_IRQ_RESERVED148 148
168#define OCTEON_IRQ_RESERVED149 149
169#define OCTEON_IRQ_RESERVED150 150
170#define OCTEON_IRQ_RESERVED151 151
171 90
172#ifdef CONFIG_PCI_MSI 91#ifdef CONFIG_PCI_MSI
173/* 152 - 215 represent the MSI interrupts 0-63 */ 92/* 152 - 407 represent the MSI interrupts 0-255 */
174#define OCTEON_IRQ_MSI_BIT0 152 93#define OCTEON_IRQ_MSI_BIT0 (OCTEON_IRQ_RST + 1)
175#define OCTEON_IRQ_MSI_LAST (OCTEON_IRQ_MSI_BIT0 + 255)
176 94
177#define OCTEON_IRQ_LAST (OCTEON_IRQ_MSI_LAST + 1) 95#define OCTEON_IRQ_MSI_LAST (OCTEON_IRQ_MSI_BIT0 + 255)
96#define OCTEON_IRQ_LAST (OCTEON_IRQ_MSI_LAST + 1)
178#else 97#else
179#define OCTEON_IRQ_LAST 152 98#define OCTEON_IRQ_LAST (OCTEON_IRQ_RST + 1)
180#endif 99#endif
181 100
182#endif 101#endif
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
index 6b34afd0d4e7..f72f768cd3a4 100644
--- a/arch/mips/include/asm/octeon/octeon.h
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -257,4 +257,6 @@ extern struct cvmx_bootinfo *octeon_bootinfo;
257 257
258extern uint64_t octeon_bootloader_entry_addr; 258extern uint64_t octeon_bootloader_entry_addr;
259 259
260extern void (*octeon_irq_setup_secondary)(void);
261
260#endif /* __ASM_OCTEON_OCTEON_H */ 262#endif /* __ASM_OCTEON_OCTEON_H */
diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c
index d8080499872a..eebaf5616d26 100644
--- a/arch/mips/pci/msi-octeon.c
+++ b/arch/mips/pci/msi-octeon.c
@@ -259,11 +259,11 @@ static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock);
259static u64 msi_rcv_reg[4]; 259static u64 msi_rcv_reg[4];
260static u64 mis_ena_reg[4]; 260static u64 mis_ena_reg[4];
261 261
262static void octeon_irq_msi_enable_pcie(unsigned int irq) 262static void octeon_irq_msi_enable_pcie(struct irq_data *data)
263{ 263{
264 u64 en; 264 u64 en;
265 unsigned long flags; 265 unsigned long flags;
266 int msi_number = irq - OCTEON_IRQ_MSI_BIT0; 266 int msi_number = data->irq - OCTEON_IRQ_MSI_BIT0;
267 int irq_index = msi_number >> 6; 267 int irq_index = msi_number >> 6;
268 int irq_bit = msi_number & 0x3f; 268 int irq_bit = msi_number & 0x3f;
269 269
@@ -275,11 +275,11 @@ static void octeon_irq_msi_enable_pcie(unsigned int irq)
275 raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags); 275 raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
276} 276}
277 277
278static void octeon_irq_msi_disable_pcie(unsigned int irq) 278static void octeon_irq_msi_disable_pcie(struct irq_data *data)
279{ 279{
280 u64 en; 280 u64 en;
281 unsigned long flags; 281 unsigned long flags;
282 int msi_number = irq - OCTEON_IRQ_MSI_BIT0; 282 int msi_number = data->irq - OCTEON_IRQ_MSI_BIT0;
283 int irq_index = msi_number >> 6; 283 int irq_index = msi_number >> 6;
284 int irq_bit = msi_number & 0x3f; 284 int irq_bit = msi_number & 0x3f;
285 285
@@ -293,11 +293,11 @@ static void octeon_irq_msi_disable_pcie(unsigned int irq)
293 293
294static struct irq_chip octeon_irq_chip_msi_pcie = { 294static struct irq_chip octeon_irq_chip_msi_pcie = {
295 .name = "MSI", 295 .name = "MSI",
296 .enable = octeon_irq_msi_enable_pcie, 296 .irq_enable = octeon_irq_msi_enable_pcie,
297 .disable = octeon_irq_msi_disable_pcie, 297 .irq_disable = octeon_irq_msi_disable_pcie,
298}; 298};
299 299
300static void octeon_irq_msi_enable_pci(unsigned int irq) 300static void octeon_irq_msi_enable_pci(struct irq_data *data)
301{ 301{
302 /* 302 /*
303 * Octeon PCI doesn't have the ability to mask/unmask MSI 303 * Octeon PCI doesn't have the ability to mask/unmask MSI
@@ -308,15 +308,15 @@ static void octeon_irq_msi_enable_pci(unsigned int irq)
308 */ 308 */
309} 309}
310 310
311static void octeon_irq_msi_disable_pci(unsigned int irq) 311static void octeon_irq_msi_disable_pci(struct irq_data *data)
312{ 312{
313 /* See comment in enable */ 313 /* See comment in enable */
314} 314}
315 315
316static struct irq_chip octeon_irq_chip_msi_pci = { 316static struct irq_chip octeon_irq_chip_msi_pci = {
317 .name = "MSI", 317 .name = "MSI",
318 .enable = octeon_irq_msi_enable_pci, 318 .irq_enable = octeon_irq_msi_enable_pci,
319 .disable = octeon_irq_msi_disable_pci, 319 .irq_disable = octeon_irq_msi_disable_pci,
320}; 320};
321 321
322/* 322/*