diff options
author | Andi Kleen <ak@suse.de> | 2008-01-30 07:32:48 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:32:48 -0500 |
commit | 96d97cf03b3d68e6c857623da93acd522b2b7e1a (patch) | |
tree | f31885e66849ca2e20d9dffd72ecd556204dbb45 /kernel/irq/proc.c | |
parent | 9e094c17ee2b85130ab7b2ea37456f6867eb687a (diff) |
x86: add /proc/irq/*/spurious to dump the spurious irq debugging state
This is useful to debug problems with interrupt handlers that return
sometimes IRQ_NONE.
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/irq/proc.c')
-rw-r--r-- | kernel/irq/proc.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index 50b81b98046a..c2f2ccb0549a 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c | |||
@@ -75,6 +75,18 @@ static int irq_affinity_write_proc(struct file *file, const char __user *buffer, | |||
75 | 75 | ||
76 | #endif | 76 | #endif |
77 | 77 | ||
78 | static int irq_spurious_read(char *page, char **start, off_t off, | ||
79 | int count, int *eof, void *data) | ||
80 | { | ||
81 | struct irq_desc *d = &irq_desc[(long) data]; | ||
82 | return sprintf(page, "count %u\n" | ||
83 | "unhandled %u\n" | ||
84 | "last_unhandled %u ms\n", | ||
85 | d->irq_count, | ||
86 | d->irqs_unhandled, | ||
87 | jiffies_to_msecs(d->last_unhandled)); | ||
88 | } | ||
89 | |||
78 | #define MAX_NAMELEN 128 | 90 | #define MAX_NAMELEN 128 |
79 | 91 | ||
80 | static int name_unique(unsigned int irq, struct irqaction *new_action) | 92 | static int name_unique(unsigned int irq, struct irqaction *new_action) |
@@ -118,6 +130,7 @@ void register_handler_proc(unsigned int irq, struct irqaction *action) | |||
118 | void register_irq_proc(unsigned int irq) | 130 | void register_irq_proc(unsigned int irq) |
119 | { | 131 | { |
120 | char name [MAX_NAMELEN]; | 132 | char name [MAX_NAMELEN]; |
133 | struct proc_dir_entry *entry; | ||
121 | 134 | ||
122 | if (!root_irq_dir || | 135 | if (!root_irq_dir || |
123 | (irq_desc[irq].chip == &no_irq_chip) || | 136 | (irq_desc[irq].chip == &no_irq_chip) || |
@@ -132,8 +145,6 @@ void register_irq_proc(unsigned int irq) | |||
132 | 145 | ||
133 | #ifdef CONFIG_SMP | 146 | #ifdef CONFIG_SMP |
134 | { | 147 | { |
135 | struct proc_dir_entry *entry; | ||
136 | |||
137 | /* create /proc/irq/<irq>/smp_affinity */ | 148 | /* create /proc/irq/<irq>/smp_affinity */ |
138 | entry = create_proc_entry("smp_affinity", 0600, irq_desc[irq].dir); | 149 | entry = create_proc_entry("smp_affinity", 0600, irq_desc[irq].dir); |
139 | 150 | ||
@@ -144,6 +155,12 @@ void register_irq_proc(unsigned int irq) | |||
144 | } | 155 | } |
145 | } | 156 | } |
146 | #endif | 157 | #endif |
158 | |||
159 | entry = create_proc_entry("spurious", 0444, irq_desc[irq].dir); | ||
160 | if (entry) { | ||
161 | entry->data = (void *)(long)irq; | ||
162 | entry->read_proc = irq_spurious_read; | ||
163 | } | ||
147 | } | 164 | } |
148 | 165 | ||
149 | #undef MAX_NAMELEN | 166 | #undef MAX_NAMELEN |