aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2009-06-15 06:10:03 -0400
committerMike Frysinger <vapier@gentoo.org>2009-06-22 21:15:40 -0400
commit26579216f3cdf1ae05f0af8412b444870a167510 (patch)
tree6774806c22c4914430930e522367e9df8c1192af /arch/blackfin
parenta200ad22bb15fe01cf222fa631687876baad5e01 (diff)
Blackfin: redo handling of bad irqs
With the common IRQ code initializing much more of the irq_desc state, we can't blindly initialize it ourselves to the local bad_irq state. If we do, we end up wrongly clobbering many fields. So punt most of the bad irq code as the common layers will handle the default state, and simply call handle_bad_irq() directly when the IRQ we are processing is invalid. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin')
-rw-r--r--arch/blackfin/kernel/irqchip.c53
1 files changed, 11 insertions, 42 deletions
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 6e31e935bb31..36bba3027735 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -38,38 +38,15 @@
38#include <asm/pda.h> 38#include <asm/pda.h>
39 39
40static atomic_t irq_err_count; 40static atomic_t irq_err_count;
41static spinlock_t irq_controller_lock;
42
43/*
44 * Dummy mask/unmask handler
45 */
46void dummy_mask_unmask_irq(unsigned int irq)
47{
48}
49
50void ack_bad_irq(unsigned int irq) 41void ack_bad_irq(unsigned int irq)
51{ 42{
52 atomic_inc(&irq_err_count); 43 atomic_inc(&irq_err_count);
53 printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq); 44 printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
54} 45}
55 46
56static struct irq_chip bad_chip = {
57 .ack = dummy_mask_unmask_irq,
58 .mask = dummy_mask_unmask_irq,
59 .unmask = dummy_mask_unmask_irq,
60};
61
62static int bad_stats;
63static struct irq_desc bad_irq_desc = { 47static struct irq_desc bad_irq_desc = {
64 .status = IRQ_DISABLED,
65 .chip = &bad_chip,
66 .handle_irq = handle_bad_irq, 48 .handle_irq = handle_bad_irq,
67 .depth = 1,
68 .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock), 49 .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
69 .kstat_irqs = &bad_stats,
70#ifdef CONFIG_SMP
71 .affinity = CPU_MASK_ALL
72#endif
73}; 50};
74 51
75#ifdef CONFIG_CPUMASK_OFFSTACK 52#ifdef CONFIG_CPUMASK_OFFSTACK
@@ -119,21 +96,13 @@ __attribute__((l1_text))
119#endif 96#endif
120asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) 97asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
121{ 98{
122 struct pt_regs *old_regs;
123 struct irq_desc *desc = irq_desc + irq;
124#ifndef CONFIG_IPIPE 99#ifndef CONFIG_IPIPE
125 unsigned short pending, other_ints; 100 unsigned short pending, other_ints;
126#endif 101#endif
127 old_regs = set_irq_regs(regs); 102 struct pt_regs *old_regs = set_irq_regs(regs);
128
129 /*
130 * Some hardware gives randomly wrong interrupts. Rather
131 * than crashing, do something sensible.
132 */
133 if (irq >= NR_IRQS)
134 desc = &bad_irq_desc;
135 103
136 irq_enter(); 104 irq_enter();
105
137#ifdef CONFIG_DEBUG_STACKOVERFLOW 106#ifdef CONFIG_DEBUG_STACKOVERFLOW
138 /* Debugging check for stack overflow: is there less than STACK_WARN free? */ 107 /* Debugging check for stack overflow: is there less than STACK_WARN free? */
139 { 108 {
@@ -149,7 +118,15 @@ asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
149 } 118 }
150 } 119 }
151#endif 120#endif
152 generic_handle_irq(irq); 121
122 /*
123 * Some hardware gives randomly wrong interrupts. Rather
124 * than crashing, do something sensible.
125 */
126 if (irq >= NR_IRQS)
127 handle_bad_irq(irq, &bad_irq_desc);
128 else
129 generic_handle_irq(irq);
153 130
154#ifndef CONFIG_IPIPE 131#ifndef CONFIG_IPIPE
155 /* 132 /*
@@ -173,14 +150,6 @@ asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
173 150
174void __init init_IRQ(void) 151void __init init_IRQ(void)
175{ 152{
176 struct irq_desc *desc;
177 int irq;
178
179 spin_lock_init(&irq_controller_lock);
180 for (irq = 0, desc = irq_desc; irq < NR_IRQS; irq++, desc++) {
181 *desc = bad_irq_desc;
182 }
183
184 init_arch_irq(); 153 init_arch_irq();
185 154
186#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND 155#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND