genirq: Implement generic irq_show_interrupts()
authorThomas Gleixner <tglx@linutronix.de>
Thu, 16 Dec 2010 16:21:47 +0000 (17:21 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Sat, 19 Feb 2011 11:58:13 +0000 (12:58 +0100)
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>
include/linux/interrupt.h
kernel/irq/Kconfig
kernel/irq/proc.c

index de97b958f478d69a87191132da0897010eb1ecf5..8da6643e39a69e4f066c5304276ab3ba6a14a906 100644 (file)
@@ -671,6 +671,7 @@ static inline void init_irq_proc(void)
 
 struct seq_file;
 int show_interrupts(struct seq_file *p, void *v);
+int arch_show_interrupts(struct seq_file *p, int prec);
 
 extern int early_irq_init(void);
 extern int arch_probe_nr_irqs(void);
index 8e42fec7686d97815c3539d3da260984db63e90f..4cd5d7135e0f5c1ba83211417332430f696f30e7 100644 (file)
@@ -20,6 +20,9 @@ config HAVE_SPARSE_IRQ
 config GENERIC_IRQ_PROBE
        def_bool n
 
+config GENERIC_IRQ_SHOW
+       def_bool n
+
 config GENERIC_PENDING_IRQ
        def_bool n
 
index a46bd762db473065f855d495a370ed32c574ea83..26449239bb46b04448834d0d71b16c459998b182 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
 
 #include "internals.h"
 
@@ -357,3 +358,65 @@ void init_irq_proc(void)
        }
 }
 
+#ifdef CONFIG_GENERIC_IRQ_SHOW
+
+int __weak arch_show_interrupts(struct seq_file *p, int prec)
+{
+       return 0;
+}
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+       static int prec;
+
+       unsigned long flags, any_count = 0;
+       int i = *(loff_t *) v, j;
+       struct irqaction *action;
+       struct irq_desc *desc;
+
+       if (i > nr_irqs)
+               return 0;
+
+       if (i == nr_irqs)
+               return arch_show_interrupts(p, prec);
+
+       /* print header and calculate the width of the first column */
+       if (i == 0) {
+               for (prec = 3, j = 1000; prec < 10 && j <= nr_irqs; ++prec)
+                       j *= 10;
+
+               seq_printf(p, "%*s", prec + 8, "");
+               for_each_online_cpu(j)
+                       seq_printf(p, "CPU%-8d", j);
+               seq_putc(p, '\n');
+       }
+
+       desc = irq_to_desc(i);
+       if (!desc)
+               return 0;
+
+       raw_spin_lock_irqsave(&desc->lock, flags);
+       for_each_online_cpu(j)
+               any_count |= kstat_irqs_cpu(i, j);
+       action = desc->action;
+       if (!action && !any_count)
+               goto out;
+
+       seq_printf(p, "%*d: ", prec, i);
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
+       seq_printf(p, " %8s", desc->irq_data.chip->name);
+       seq_printf(p, "-%-8s", desc->name);
+
+       if (action) {
+               seq_printf(p, "  %s", action->name);
+               while ((action = action->next) != NULL)
+                       seq_printf(p, ", %s", action->name);
+       }
+
+       seq_putc(p, '\n');
+out:
+       raw_spin_unlock_irqrestore(&desc->lock, flags);
+       return 0;
+}
+#endif