diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2010-12-16 11:21:47 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2011-02-19 06:58:13 -0500 |
commit | c78b9b65faa291def628dbd8539649f58299f0f3 (patch) | |
tree | e5575932182c11373e522160491347dce2e0a003 /kernel | |
parent | 1277a5325adfc53caac7dd3dac5d3d2fd2a125b4 (diff) |
genirq: Implement generic irq_show_interrupts()
All archs implement show_interrupts() in more or less the same
way. That's tons of duplicated code with different bugs with no
value. Implement a generic version and deprecate show_interrupts()
Unfortunately we need some ifdeffery for !GENERIC_HARDIRQ archs.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/irq/Kconfig | 3 | ||||
-rw-r--r-- | kernel/irq/proc.c | 63 |
2 files changed, 66 insertions, 0 deletions
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig index 8e42fec7686d..4cd5d7135e0f 100644 --- a/kernel/irq/Kconfig +++ b/kernel/irq/Kconfig | |||
@@ -20,6 +20,9 @@ config HAVE_SPARSE_IRQ | |||
20 | config GENERIC_IRQ_PROBE | 20 | config GENERIC_IRQ_PROBE |
21 | def_bool n | 21 | def_bool n |
22 | 22 | ||
23 | config GENERIC_IRQ_SHOW | ||
24 | def_bool n | ||
25 | |||
23 | config GENERIC_PENDING_IRQ | 26 | config GENERIC_PENDING_IRQ |
24 | def_bool n | 27 | def_bool n |
25 | 28 | ||
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index a46bd762db47..26449239bb46 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/proc_fs.h> | 11 | #include <linux/proc_fs.h> |
12 | #include <linux/seq_file.h> | 12 | #include <linux/seq_file.h> |
13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
14 | #include <linux/kernel_stat.h> | ||
14 | 15 | ||
15 | #include "internals.h" | 16 | #include "internals.h" |
16 | 17 | ||
@@ -357,3 +358,65 @@ void init_irq_proc(void) | |||
357 | } | 358 | } |
358 | } | 359 | } |
359 | 360 | ||
361 | #ifdef CONFIG_GENERIC_IRQ_SHOW | ||
362 | |||
363 | int __weak arch_show_interrupts(struct seq_file *p, int prec) | ||
364 | { | ||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | int show_interrupts(struct seq_file *p, void *v) | ||
369 | { | ||
370 | static int prec; | ||
371 | |||
372 | unsigned long flags, any_count = 0; | ||
373 | int i = *(loff_t *) v, j; | ||
374 | struct irqaction *action; | ||
375 | struct irq_desc *desc; | ||
376 | |||
377 | if (i > nr_irqs) | ||
378 | return 0; | ||
379 | |||
380 | if (i == nr_irqs) | ||
381 | return arch_show_interrupts(p, prec); | ||
382 | |||
383 | /* print header and calculate the width of the first column */ | ||
384 | if (i == 0) { | ||
385 | for (prec = 3, j = 1000; prec < 10 && j <= nr_irqs; ++prec) | ||
386 | j *= 10; | ||
387 | |||
388 | seq_printf(p, "%*s", prec + 8, ""); | ||
389 | for_each_online_cpu(j) | ||
390 | seq_printf(p, "CPU%-8d", j); | ||
391 | seq_putc(p, '\n'); | ||
392 | } | ||
393 | |||
394 | desc = irq_to_desc(i); | ||
395 | if (!desc) | ||
396 | return 0; | ||
397 | |||
398 | raw_spin_lock_irqsave(&desc->lock, flags); | ||
399 | for_each_online_cpu(j) | ||
400 | any_count |= kstat_irqs_cpu(i, j); | ||
401 | action = desc->action; | ||
402 | if (!action && !any_count) | ||
403 | goto out; | ||
404 | |||
405 | seq_printf(p, "%*d: ", prec, i); | ||
406 | for_each_online_cpu(j) | ||
407 | seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); | ||
408 | seq_printf(p, " %8s", desc->irq_data.chip->name); | ||
409 | seq_printf(p, "-%-8s", desc->name); | ||
410 | |||
411 | if (action) { | ||
412 | seq_printf(p, " %s", action->name); | ||
413 | while ((action = action->next) != NULL) | ||
414 | seq_printf(p, ", %s", action->name); | ||
415 | } | ||
416 | |||
417 | seq_putc(p, '\n'); | ||
418 | out: | ||
419 | raw_spin_unlock_irqrestore(&desc->lock, flags); | ||
420 | return 0; | ||
421 | } | ||
422 | #endif | ||