aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/irq.c')
-rw-r--r--arch/mips/kernel/irq.c75
1 files changed, 30 insertions, 45 deletions
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index c6345f579a8a..9b734d74ae8e 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -81,48 +81,9 @@ void ack_bad_irq(unsigned int irq)
81 81
82atomic_t irq_err_count; 82atomic_t irq_err_count;
83 83
84/* 84int arch_show_interrupts(struct seq_file *p, int prec)
85 * Generic, controller-independent functions:
86 */
87
88int show_interrupts(struct seq_file *p, void *v)
89{ 85{
90 int i = *(loff_t *) v, j; 86 seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
91 struct irqaction * action;
92 unsigned long flags;
93
94 if (i == 0) {
95 seq_printf(p, " ");
96 for_each_online_cpu(j)
97 seq_printf(p, "CPU%d ", j);
98 seq_putc(p, '\n');
99 }
100
101 if (i < NR_IRQS) {
102 raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
103 action = irq_desc[i].action;
104 if (!action)
105 goto skip;
106 seq_printf(p, "%3d: ", i);
107#ifndef CONFIG_SMP
108 seq_printf(p, "%10u ", kstat_irqs(i));
109#else
110 for_each_online_cpu(j)
111 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
112#endif
113 seq_printf(p, " %14s", irq_desc[i].chip->name);
114 seq_printf(p, " %s", action->name);
115
116 for (action=action->next; action; action = action->next)
117 seq_printf(p, ", %s", action->name);
118
119 seq_putc(p, '\n');
120skip:
121 raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
122 } else if (i == NR_IRQS) {
123 seq_putc(p, '\n');
124 seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
125 }
126 return 0; 87 return 0;
127} 88}
128 89
@@ -141,7 +102,7 @@ void __init init_IRQ(void)
141#endif 102#endif
142 103
143 for (i = 0; i < NR_IRQS; i++) 104 for (i = 0; i < NR_IRQS; i++)
144 set_irq_noprobe(i); 105 irq_set_noprobe(i);
145 106
146 arch_init_irq(); 107 arch_init_irq();
147 108
@@ -151,6 +112,29 @@ void __init init_IRQ(void)
151#endif 112#endif
152} 113}
153 114
115#ifdef DEBUG_STACKOVERFLOW
116static inline void check_stack_overflow(void)
117{
118 unsigned long sp;
119
120 __asm__ __volatile__("move %0, $sp" : "=r" (sp));
121 sp &= THREAD_MASK;
122
123 /*
124 * Check for stack overflow: is there less than STACK_WARN free?
125 * STACK_WARN is defined as 1/8 of THREAD_SIZE by default.
126 */
127 if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
128 printk("do_IRQ: stack overflow: %ld\n",
129 sp - sizeof(struct thread_info));
130 dump_stack();
131 }
132}
133#else
134static inline void check_stack_overflow(void) {}
135#endif
136
137
154/* 138/*
155 * do_IRQ handles all normal device IRQ's (the special 139 * do_IRQ handles all normal device IRQ's (the special
156 * SMP cross-CPU interrupts have their own specific 140 * SMP cross-CPU interrupts have their own specific
@@ -159,8 +143,9 @@ void __init init_IRQ(void)
159void __irq_entry do_IRQ(unsigned int irq) 143void __irq_entry do_IRQ(unsigned int irq)
160{ 144{
161 irq_enter(); 145 irq_enter();
162 __DO_IRQ_SMTC_HOOK(irq); 146 check_stack_overflow();
163 generic_handle_irq(irq); 147 if (!smtc_handle_on_other_cpu(irq))
148 generic_handle_irq(irq);
164 irq_exit(); 149 irq_exit();
165} 150}
166 151
@@ -173,7 +158,7 @@ void __irq_entry do_IRQ(unsigned int irq)
173void __irq_entry do_IRQ_no_affinity(unsigned int irq) 158void __irq_entry do_IRQ_no_affinity(unsigned int irq)
174{ 159{
175 irq_enter(); 160 irq_enter();
176 __NO_AFFINITY_IRQ_SMTC_HOOK(irq); 161 smtc_im_backstop(irq);
177 generic_handle_irq(irq); 162 generic_handle_irq(irq);
178 irq_exit(); 163 irq_exit();
179} 164}