diff options
Diffstat (limited to 'arch/mn10300/kernel/irq.c')
-rw-r--r-- | arch/mn10300/kernel/irq.c | 172 |
1 files changed, 51 insertions, 121 deletions
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c index ac11754ecec5..86af0d7d0771 100644 --- a/arch/mn10300/kernel/irq.c +++ b/arch/mn10300/kernel/irq.c | |||
@@ -37,8 +37,9 @@ atomic_t irq_err_count; | |||
37 | /* | 37 | /* |
38 | * MN10300 interrupt controller operations | 38 | * MN10300 interrupt controller operations |
39 | */ | 39 | */ |
40 | static void mn10300_cpupic_ack(unsigned int irq) | 40 | static void mn10300_cpupic_ack(struct irq_data *d) |
41 | { | 41 | { |
42 | unsigned int irq = d->irq; | ||
42 | unsigned long flags; | 43 | unsigned long flags; |
43 | u16 tmp; | 44 | u16 tmp; |
44 | 45 | ||
@@ -61,13 +62,14 @@ static void __mask_and_set_icr(unsigned int irq, | |||
61 | arch_local_irq_restore(flags); | 62 | arch_local_irq_restore(flags); |
62 | } | 63 | } |
63 | 64 | ||
64 | static void mn10300_cpupic_mask(unsigned int irq) | 65 | static void mn10300_cpupic_mask(struct irq_data *d) |
65 | { | 66 | { |
66 | __mask_and_set_icr(irq, GxICR_LEVEL, 0); | 67 | __mask_and_set_icr(d->irq, GxICR_LEVEL, 0); |
67 | } | 68 | } |
68 | 69 | ||
69 | static void mn10300_cpupic_mask_ack(unsigned int irq) | 70 | static void mn10300_cpupic_mask_ack(struct irq_data *d) |
70 | { | 71 | { |
72 | unsigned int irq = d->irq; | ||
71 | #ifdef CONFIG_SMP | 73 | #ifdef CONFIG_SMP |
72 | unsigned long flags; | 74 | unsigned long flags; |
73 | u16 tmp; | 75 | u16 tmp; |
@@ -85,7 +87,7 @@ static void mn10300_cpupic_mask_ack(unsigned int irq) | |||
85 | tmp2 = GxICR(irq); | 87 | tmp2 = GxICR(irq); |
86 | 88 | ||
87 | irq_affinity_online[irq] = | 89 | irq_affinity_online[irq] = |
88 | any_online_cpu(*irq_desc[irq].affinity); | 90 | any_online_cpu(*d->affinity); |
89 | CROSS_GxICR(irq, irq_affinity_online[irq]) = | 91 | CROSS_GxICR(irq, irq_affinity_online[irq]) = |
90 | (tmp & (GxICR_LEVEL | GxICR_ENABLE)) | GxICR_DETECT; | 92 | (tmp & (GxICR_LEVEL | GxICR_ENABLE)) | GxICR_DETECT; |
91 | tmp = CROSS_GxICR(irq, irq_affinity_online[irq]); | 93 | tmp = CROSS_GxICR(irq, irq_affinity_online[irq]); |
@@ -97,13 +99,14 @@ static void mn10300_cpupic_mask_ack(unsigned int irq) | |||
97 | #endif /* CONFIG_SMP */ | 99 | #endif /* CONFIG_SMP */ |
98 | } | 100 | } |
99 | 101 | ||
100 | static void mn10300_cpupic_unmask(unsigned int irq) | 102 | static void mn10300_cpupic_unmask(struct irq_data *d) |
101 | { | 103 | { |
102 | __mask_and_set_icr(irq, GxICR_LEVEL, GxICR_ENABLE); | 104 | __mask_and_set_icr(d->irq, GxICR_LEVEL, GxICR_ENABLE); |
103 | } | 105 | } |
104 | 106 | ||
105 | static void mn10300_cpupic_unmask_clear(unsigned int irq) | 107 | static void mn10300_cpupic_unmask_clear(struct irq_data *d) |
106 | { | 108 | { |
109 | unsigned int irq = d->irq; | ||
107 | /* the MN10300 PIC latches its interrupt request bit, even after the | 110 | /* the MN10300 PIC latches its interrupt request bit, even after the |
108 | * device has ceased to assert its interrupt line and the interrupt | 111 | * device has ceased to assert its interrupt line and the interrupt |
109 | * channel has been disabled in the PIC, so for level-triggered | 112 | * channel has been disabled in the PIC, so for level-triggered |
@@ -121,7 +124,7 @@ static void mn10300_cpupic_unmask_clear(unsigned int irq) | |||
121 | } else { | 124 | } else { |
122 | tmp = GxICR(irq); | 125 | tmp = GxICR(irq); |
123 | 126 | ||
124 | irq_affinity_online[irq] = any_online_cpu(*irq_desc[irq].affinity); | 127 | irq_affinity_online[irq] = any_online_cpu(*d->affinity); |
125 | CROSS_GxICR(irq, irq_affinity_online[irq]) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT; | 128 | CROSS_GxICR(irq, irq_affinity_online[irq]) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT; |
126 | tmp = CROSS_GxICR(irq, irq_affinity_online[irq]); | 129 | tmp = CROSS_GxICR(irq, irq_affinity_online[irq]); |
127 | } | 130 | } |
@@ -134,7 +137,8 @@ static void mn10300_cpupic_unmask_clear(unsigned int irq) | |||
134 | 137 | ||
135 | #ifdef CONFIG_SMP | 138 | #ifdef CONFIG_SMP |
136 | static int | 139 | static int |
137 | mn10300_cpupic_setaffinity(unsigned int irq, const struct cpumask *mask) | 140 | mn10300_cpupic_setaffinity(struct irq_data *d, const struct cpumask *mask, |
141 | bool force) | ||
138 | { | 142 | { |
139 | unsigned long flags; | 143 | unsigned long flags; |
140 | int err; | 144 | int err; |
@@ -142,14 +146,14 @@ mn10300_cpupic_setaffinity(unsigned int irq, const struct cpumask *mask) | |||
142 | flags = arch_local_cli_save(); | 146 | flags = arch_local_cli_save(); |
143 | 147 | ||
144 | /* check irq no */ | 148 | /* check irq no */ |
145 | switch (irq) { | 149 | switch (d->irq) { |
146 | case TMJCIRQ: | 150 | case TMJCIRQ: |
147 | case RESCHEDULE_IPI: | 151 | case RESCHEDULE_IPI: |
148 | case CALL_FUNC_SINGLE_IPI: | 152 | case CALL_FUNC_SINGLE_IPI: |
149 | case LOCAL_TIMER_IPI: | 153 | case LOCAL_TIMER_IPI: |
150 | case FLUSH_CACHE_IPI: | 154 | case FLUSH_CACHE_IPI: |
151 | case CALL_FUNCTION_NMI_IPI: | 155 | case CALL_FUNCTION_NMI_IPI: |
152 | case GDB_NMI_IPI: | 156 | case DEBUGGER_NMI_IPI: |
153 | #ifdef CONFIG_MN10300_TTYSM0 | 157 | #ifdef CONFIG_MN10300_TTYSM0 |
154 | case SC0RXIRQ: | 158 | case SC0RXIRQ: |
155 | case SC0TXIRQ: | 159 | case SC0TXIRQ: |
@@ -181,7 +185,7 @@ mn10300_cpupic_setaffinity(unsigned int irq, const struct cpumask *mask) | |||
181 | break; | 185 | break; |
182 | 186 | ||
183 | default: | 187 | default: |
184 | set_bit(irq, irq_affinity_request); | 188 | set_bit(d->irq, irq_affinity_request); |
185 | err = 0; | 189 | err = 0; |
186 | break; | 190 | break; |
187 | } | 191 | } |
@@ -202,15 +206,15 @@ mn10300_cpupic_setaffinity(unsigned int irq, const struct cpumask *mask) | |||
202 | * mask_ack() is provided), and mask_ack() just masks. | 206 | * mask_ack() is provided), and mask_ack() just masks. |
203 | */ | 207 | */ |
204 | static struct irq_chip mn10300_cpu_pic_level = { | 208 | static struct irq_chip mn10300_cpu_pic_level = { |
205 | .name = "cpu_l", | 209 | .name = "cpu_l", |
206 | .disable = mn10300_cpupic_mask, | 210 | .irq_disable = mn10300_cpupic_mask, |
207 | .enable = mn10300_cpupic_unmask_clear, | 211 | .irq_enable = mn10300_cpupic_unmask_clear, |
208 | .ack = NULL, | 212 | .irq_ack = NULL, |
209 | .mask = mn10300_cpupic_mask, | 213 | .irq_mask = mn10300_cpupic_mask, |
210 | .mask_ack = mn10300_cpupic_mask, | 214 | .irq_mask_ack = mn10300_cpupic_mask, |
211 | .unmask = mn10300_cpupic_unmask_clear, | 215 | .irq_unmask = mn10300_cpupic_unmask_clear, |
212 | #ifdef CONFIG_SMP | 216 | #ifdef CONFIG_SMP |
213 | .set_affinity = mn10300_cpupic_setaffinity, | 217 | .irq_set_affinity = mn10300_cpupic_setaffinity, |
214 | #endif | 218 | #endif |
215 | }; | 219 | }; |
216 | 220 | ||
@@ -220,15 +224,15 @@ static struct irq_chip mn10300_cpu_pic_level = { | |||
220 | * We use the latch clearing function of the PIC as the 'ACK' function. | 224 | * We use the latch clearing function of the PIC as the 'ACK' function. |
221 | */ | 225 | */ |
222 | static struct irq_chip mn10300_cpu_pic_edge = { | 226 | static struct irq_chip mn10300_cpu_pic_edge = { |
223 | .name = "cpu_e", | 227 | .name = "cpu_e", |
224 | .disable = mn10300_cpupic_mask, | 228 | .irq_disable = mn10300_cpupic_mask, |
225 | .enable = mn10300_cpupic_unmask, | 229 | .irq_enable = mn10300_cpupic_unmask, |
226 | .ack = mn10300_cpupic_ack, | 230 | .irq_ack = mn10300_cpupic_ack, |
227 | .mask = mn10300_cpupic_mask, | 231 | .irq_mask = mn10300_cpupic_mask, |
228 | .mask_ack = mn10300_cpupic_mask_ack, | 232 | .irq_mask_ack = mn10300_cpupic_mask_ack, |
229 | .unmask = mn10300_cpupic_unmask, | 233 | .irq_unmask = mn10300_cpupic_unmask, |
230 | #ifdef CONFIG_SMP | 234 | #ifdef CONFIG_SMP |
231 | .set_affinity = mn10300_cpupic_setaffinity, | 235 | .irq_set_affinity = mn10300_cpupic_setaffinity, |
232 | #endif | 236 | #endif |
233 | }; | 237 | }; |
234 | 238 | ||
@@ -252,31 +256,6 @@ void set_intr_level(int irq, u16 level) | |||
252 | __mask_and_set_icr(irq, GxICR_ENABLE, level); | 256 | __mask_and_set_icr(irq, GxICR_ENABLE, level); |
253 | } | 257 | } |
254 | 258 | ||
255 | void mn10300_intc_set_level(unsigned int irq, unsigned int level) | ||
256 | { | ||
257 | set_intr_level(irq, NUM2GxICR_LEVEL(level) & GxICR_LEVEL); | ||
258 | } | ||
259 | |||
260 | void mn10300_intc_clear(unsigned int irq) | ||
261 | { | ||
262 | __mask_and_set_icr(irq, GxICR_LEVEL | GxICR_ENABLE, GxICR_DETECT); | ||
263 | } | ||
264 | |||
265 | void mn10300_intc_set(unsigned int irq) | ||
266 | { | ||
267 | __mask_and_set_icr(irq, 0, GxICR_REQUEST | GxICR_DETECT); | ||
268 | } | ||
269 | |||
270 | void mn10300_intc_enable(unsigned int irq) | ||
271 | { | ||
272 | mn10300_cpupic_unmask(irq); | ||
273 | } | ||
274 | |||
275 | void mn10300_intc_disable(unsigned int irq) | ||
276 | { | ||
277 | mn10300_cpupic_mask(irq); | ||
278 | } | ||
279 | |||
280 | /* | 259 | /* |
281 | * mark an interrupt to be ACK'd after interrupt handlers have been run rather | 260 | * mark an interrupt to be ACK'd after interrupt handlers have been run rather |
282 | * than before | 261 | * than before |
@@ -284,7 +263,7 @@ void mn10300_intc_disable(unsigned int irq) | |||
284 | */ | 263 | */ |
285 | void mn10300_set_lateack_irq_type(int irq) | 264 | void mn10300_set_lateack_irq_type(int irq) |
286 | { | 265 | { |
287 | set_irq_chip_and_handler(irq, &mn10300_cpu_pic_level, | 266 | irq_set_chip_and_handler(irq, &mn10300_cpu_pic_level, |
288 | handle_level_irq); | 267 | handle_level_irq); |
289 | } | 268 | } |
290 | 269 | ||
@@ -296,12 +275,12 @@ void __init init_IRQ(void) | |||
296 | int irq; | 275 | int irq; |
297 | 276 | ||
298 | for (irq = 0; irq < NR_IRQS; irq++) | 277 | for (irq = 0; irq < NR_IRQS; irq++) |
299 | if (irq_desc[irq].chip == &no_irq_chip) | 278 | if (irq_get_chip(irq) == &no_irq_chip) |
300 | /* due to the PIC latching interrupt requests, even | 279 | /* due to the PIC latching interrupt requests, even |
301 | * when the IRQ is disabled, IRQ_PENDING is superfluous | 280 | * when the IRQ is disabled, IRQ_PENDING is superfluous |
302 | * and we can use handle_level_irq() for edge-triggered | 281 | * and we can use handle_level_irq() for edge-triggered |
303 | * interrupts */ | 282 | * interrupts */ |
304 | set_irq_chip_and_handler(irq, &mn10300_cpu_pic_edge, | 283 | irq_set_chip_and_handler(irq, &mn10300_cpu_pic_edge, |
305 | handle_level_irq); | 284 | handle_level_irq); |
306 | 285 | ||
307 | unit_init_IRQ(); | 286 | unit_init_IRQ(); |
@@ -356,91 +335,42 @@ asmlinkage void do_IRQ(void) | |||
356 | /* | 335 | /* |
357 | * Display interrupt management information through /proc/interrupts | 336 | * Display interrupt management information through /proc/interrupts |
358 | */ | 337 | */ |
359 | int show_interrupts(struct seq_file *p, void *v) | 338 | int arch_show_interrupts(struct seq_file *p, int prec) |
360 | { | 339 | { |
361 | int i = *(loff_t *) v, j, cpu; | ||
362 | struct irqaction *action; | ||
363 | unsigned long flags; | ||
364 | |||
365 | switch (i) { | ||
366 | /* display column title bar naming CPUs */ | ||
367 | case 0: | ||
368 | seq_printf(p, " "); | ||
369 | for (j = 0; j < NR_CPUS; j++) | ||
370 | if (cpu_online(j)) | ||
371 | seq_printf(p, "CPU%d ", j); | ||
372 | seq_putc(p, '\n'); | ||
373 | break; | ||
374 | |||
375 | /* display information rows, one per active CPU */ | ||
376 | case 1 ... NR_IRQS - 1: | ||
377 | raw_spin_lock_irqsave(&irq_desc[i].lock, flags); | ||
378 | |||
379 | action = irq_desc[i].action; | ||
380 | if (action) { | ||
381 | seq_printf(p, "%3d: ", i); | ||
382 | for_each_present_cpu(cpu) | ||
383 | seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu)); | ||
384 | |||
385 | if (i < NR_CPU_IRQS) | ||
386 | seq_printf(p, " %14s.%u", | ||
387 | irq_desc[i].chip->name, | ||
388 | (GxICR(i) & GxICR_LEVEL) >> | ||
389 | GxICR_LEVEL_SHIFT); | ||
390 | else | ||
391 | seq_printf(p, " %14s", | ||
392 | irq_desc[i].chip->name); | ||
393 | |||
394 | seq_printf(p, " %s", action->name); | ||
395 | |||
396 | for (action = action->next; | ||
397 | action; | ||
398 | action = action->next) | ||
399 | seq_printf(p, ", %s", action->name); | ||
400 | |||
401 | seq_putc(p, '\n'); | ||
402 | } | ||
403 | |||
404 | raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); | ||
405 | break; | ||
406 | |||
407 | /* polish off with NMI and error counters */ | ||
408 | case NR_IRQS: | ||
409 | #ifdef CONFIG_MN10300_WD_TIMER | 340 | #ifdef CONFIG_MN10300_WD_TIMER |
410 | seq_printf(p, "NMI: "); | 341 | int j; |
411 | for (j = 0; j < NR_CPUS; j++) | ||
412 | if (cpu_online(j)) | ||
413 | seq_printf(p, "%10u ", nmi_count(j)); | ||
414 | seq_putc(p, '\n'); | ||
415 | #endif | ||
416 | 342 | ||
417 | seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); | 343 | seq_printf(p, "%*s: ", prec, "NMI"); |
418 | break; | 344 | for (j = 0; j < NR_CPUS; j++) |
419 | } | 345 | if (cpu_online(j)) |
346 | seq_printf(p, "%10u ", nmi_count(j)); | ||
347 | seq_putc(p, '\n'); | ||
348 | #endif | ||
420 | 349 | ||
350 | seq_printf(p, "%*s: ", prec, "ERR"); | ||
351 | seq_printf(p, "%10u\n", atomic_read(&irq_err_count)); | ||
421 | return 0; | 352 | return 0; |
422 | } | 353 | } |
423 | 354 | ||
424 | #ifdef CONFIG_HOTPLUG_CPU | 355 | #ifdef CONFIG_HOTPLUG_CPU |
425 | void migrate_irqs(void) | 356 | void migrate_irqs(void) |
426 | { | 357 | { |
427 | irq_desc_t *desc; | ||
428 | int irq; | 358 | int irq; |
429 | unsigned int self, new; | 359 | unsigned int self, new; |
430 | unsigned long flags; | 360 | unsigned long flags; |
431 | 361 | ||
432 | self = smp_processor_id(); | 362 | self = smp_processor_id(); |
433 | for (irq = 0; irq < NR_IRQS; irq++) { | 363 | for (irq = 0; irq < NR_IRQS; irq++) { |
434 | desc = irq_desc + irq; | 364 | struct irq_data *data = irq_get_irq_data(irq); |
435 | 365 | ||
436 | if (desc->status == IRQ_PER_CPU) | 366 | if (irqd_is_per_cpu(data)) |
437 | continue; | 367 | continue; |
438 | 368 | ||
439 | if (cpu_isset(self, irq_desc[irq].affinity) && | 369 | if (cpu_isset(self, data->affinity) && |
440 | !cpus_intersects(irq_affinity[irq], cpu_online_map)) { | 370 | !cpus_intersects(irq_affinity[irq], cpu_online_map)) { |
441 | int cpu_id; | 371 | int cpu_id; |
442 | cpu_id = first_cpu(cpu_online_map); | 372 | cpu_id = first_cpu(cpu_online_map); |
443 | cpu_set(cpu_id, irq_desc[irq].affinity); | 373 | cpu_set(cpu_id, data->affinity); |
444 | } | 374 | } |
445 | /* We need to operate irq_affinity_online atomically. */ | 375 | /* We need to operate irq_affinity_online atomically. */ |
446 | arch_local_cli_save(flags); | 376 | arch_local_cli_save(flags); |
@@ -451,7 +381,7 @@ void migrate_irqs(void) | |||
451 | GxICR(irq) = x & GxICR_LEVEL; | 381 | GxICR(irq) = x & GxICR_LEVEL; |
452 | tmp = GxICR(irq); | 382 | tmp = GxICR(irq); |
453 | 383 | ||
454 | new = any_online_cpu(irq_desc[irq].affinity); | 384 | new = any_online_cpu(data->affinity); |
455 | irq_affinity_online[irq] = new; | 385 | irq_affinity_online[irq] = new; |
456 | 386 | ||
457 | CROSS_GxICR(irq, new) = | 387 | CROSS_GxICR(irq, new) = |