]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/x86/kernel/irq.c
x86: unify show_interrupts() and proc helpers
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / irq.c
1 /*
2  * Common interrupt code for 32 and 64 bit
3  */
4 #include <linux/cpu.h>
5 #include <linux/interrupt.h>
6 #include <linux/kernel_stat.h>
7 #include <linux/seq_file.h>
8
9 #include <asm/apic.h>
10 #include <asm/io_apic.h>
11 #include <asm/smp.h>
12
13 atomic_t irq_err_count;
14
15 #ifdef CONFIG_X86_32
16 # define irq_stats(x)           (&per_cpu(irq_stat,x))
17 #else
18 # define irq_stats(x)           cpu_pda(x)
19 #endif
20 /*
21  * /proc/interrupts printing:
22  */
23 static int show_other_interrupts(struct seq_file *p)
24 {
25         int j;
26
27         seq_printf(p, "NMI: ");
28         for_each_online_cpu(j)
29                 seq_printf(p, "%10u ", irq_stats(j)->__nmi_count);
30         seq_printf(p, "  Non-maskable interrupts\n");
31 #ifdef CONFIG_X86_LOCAL_APIC
32         seq_printf(p, "LOC: ");
33         for_each_online_cpu(j)
34                 seq_printf(p, "%10u ", irq_stats(j)->apic_timer_irqs);
35         seq_printf(p, "  Local timer interrupts\n");
36 #endif
37 #ifdef CONFIG_SMP
38         seq_printf(p, "RES: ");
39         for_each_online_cpu(j)
40                 seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count);
41         seq_printf(p, "  Rescheduling interrupts\n");
42         seq_printf(p, "CAL: ");
43         for_each_online_cpu(j)
44                 seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
45         seq_printf(p, "  Function call interrupts\n");
46         seq_printf(p, "TLB: ");
47         for_each_online_cpu(j)
48                 seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
49         seq_printf(p, "  TLB shootdowns\n");
50 #endif
51 #ifdef CONFIG_X86_MCE
52         seq_printf(p, "TRM: ");
53         for_each_online_cpu(j)
54                 seq_printf(p, "%10u ", irq_stats(j)->irq_thermal_count);
55         seq_printf(p, "  Thermal event interrupts\n");
56 # ifdef CONFIG_X86_64
57         seq_printf(p, "THR: ");
58         for_each_online_cpu(j)
59                 seq_printf(p, "%10u ", irq_stats(j)->irq_threshold_count);
60         seq_printf(p, "  Threshold APIC interrupts\n");
61 # endif
62 #endif
63 #ifdef CONFIG_X86_LOCAL_APIC
64         seq_printf(p, "SPU: ");
65         for_each_online_cpu(j)
66                 seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count);
67         seq_printf(p, "  Spurious interrupts\n");
68 #endif
69         seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
70 #if defined(CONFIG_X86_IO_APIC)
71         seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
72 #endif
73         return 0;
74 }
75
76 int show_interrupts(struct seq_file *p, void *v)
77 {
78         unsigned long flags, any_count = 0;
79         int i = *(loff_t *) v, j;
80         struct irqaction *action;
81         struct irq_desc *desc;
82
83         if (i > nr_irqs)
84                 return 0;
85
86         if (i == nr_irqs)
87                 return show_other_interrupts(p);
88
89         /* print header */
90         if (i == 0) {
91                 seq_printf(p, "           ");
92                 for_each_online_cpu(j)
93                         seq_printf(p, "CPU%-8d",j);
94                 seq_putc(p, '\n');
95         }
96
97         desc = irq_to_desc(i);
98         spin_lock_irqsave(&desc->lock, flags);
99 #ifndef CONFIG_SMP
100         any_count = kstat_irqs(i);
101 #else
102         for_each_online_cpu(j)
103                 any_count |= kstat_irqs_cpu(i, j);
104 #endif
105         action = desc->action;
106         if (!action && !any_count)
107                 goto out;
108
109         seq_printf(p, "%3d: ", i);
110 #ifndef CONFIG_SMP
111         seq_printf(p, "%10u ", kstat_irqs(i));
112 #else
113         for_each_online_cpu(j)
114                 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
115 #endif
116         seq_printf(p, " %8s", desc->chip->name);
117         seq_printf(p, "-%-8s", desc->name);
118
119         if (action) {
120                 seq_printf(p, "  %s", action->name);
121                 while ((action = action->next) != NULL)
122                         seq_printf(p, ", %s", action->name);
123         }
124
125         seq_putc(p, '\n');
126 out:
127         spin_unlock_irqrestore(&desc->lock, flags);
128         return 0;
129 }
130
131 /*
132  * /proc/stat helpers
133  */
134 u64 arch_irq_stat_cpu(unsigned int cpu)
135 {
136         u64 sum = irq_stats(cpu)->__nmi_count;
137
138 #ifdef CONFIG_X86_LOCAL_APIC
139         sum += irq_stats(cpu)->apic_timer_irqs;
140 #endif
141 #ifdef CONFIG_SMP
142         sum += irq_stats(cpu)->irq_resched_count;
143         sum += irq_stats(cpu)->irq_call_count;
144         sum += irq_stats(cpu)->irq_tlb_count;
145 #endif
146 #ifdef CONFIG_X86_MCE
147         sum += irq_stats(cpu)->irq_thermal_count;
148 # ifdef CONFIG_X86_64
149         sum += irq_stats(cpu)->irq_threshold_count;
150 #endif
151 #endif
152 #ifdef CONFIG_X86_LOCAL_APIC
153         sum += irq_stats(cpu)->irq_spurious_count;
154 #endif
155         return sum;
156 }
157
158 u64 arch_irq_stat(void)
159 {
160         u64 sum = atomic_read(&irq_err_count);
161
162 #ifdef CONFIG_X86_IO_APIC
163         sum += atomic_read(&irq_mis_count);
164 #endif
165         return sum;
166 }