diff options
Diffstat (limited to 'kernel/irq/spurious.c')
-rw-r--r-- | kernel/irq/spurious.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index ea3ceed362da..5eae7bf3c347 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c | |||
@@ -16,22 +16,20 @@ static int irqfixup __read_mostly; | |||
16 | /* | 16 | /* |
17 | * Recovery handler for misrouted interrupts. | 17 | * Recovery handler for misrouted interrupts. |
18 | */ | 18 | */ |
19 | |||
20 | static int misrouted_irq(int irq, struct pt_regs *regs) | 19 | static int misrouted_irq(int irq, struct pt_regs *regs) |
21 | { | 20 | { |
22 | int i; | 21 | int i; |
23 | irq_desc_t *desc; | ||
24 | int ok = 0; | 22 | int ok = 0; |
25 | int work = 0; /* Did we do work for a real IRQ */ | 23 | int work = 0; /* Did we do work for a real IRQ */ |
26 | 24 | ||
27 | for(i = 1; i < NR_IRQS; i++) { | 25 | for (i = 1; i < NR_IRQS; i++) { |
26 | struct irq_desc *desc = irq_desc + i; | ||
28 | struct irqaction *action; | 27 | struct irqaction *action; |
29 | 28 | ||
30 | if (i == irq) /* Already tried */ | 29 | if (i == irq) /* Already tried */ |
31 | continue; | 30 | continue; |
32 | desc = &irq_desc[i]; | 31 | |
33 | spin_lock(&desc->lock); | 32 | spin_lock(&desc->lock); |
34 | action = desc->action; | ||
35 | /* Already running on another processor */ | 33 | /* Already running on another processor */ |
36 | if (desc->status & IRQ_INPROGRESS) { | 34 | if (desc->status & IRQ_INPROGRESS) { |
37 | /* | 35 | /* |
@@ -45,7 +43,9 @@ static int misrouted_irq(int irq, struct pt_regs *regs) | |||
45 | } | 43 | } |
46 | /* Honour the normal IRQ locking */ | 44 | /* Honour the normal IRQ locking */ |
47 | desc->status |= IRQ_INPROGRESS; | 45 | desc->status |= IRQ_INPROGRESS; |
46 | action = desc->action; | ||
48 | spin_unlock(&desc->lock); | 47 | spin_unlock(&desc->lock); |
48 | |||
49 | while (action) { | 49 | while (action) { |
50 | /* Only shared IRQ handlers are safe to call */ | 50 | /* Only shared IRQ handlers are safe to call */ |
51 | if (action->flags & SA_SHIRQ) { | 51 | if (action->flags & SA_SHIRQ) { |
@@ -62,9 +62,8 @@ static int misrouted_irq(int irq, struct pt_regs *regs) | |||
62 | 62 | ||
63 | /* | 63 | /* |
64 | * While we were looking for a fixup someone queued a real | 64 | * While we were looking for a fixup someone queued a real |
65 | * IRQ clashing with our walk | 65 | * IRQ clashing with our walk: |
66 | */ | 66 | */ |
67 | |||
68 | while ((desc->status & IRQ_PENDING) && action) { | 67 | while ((desc->status & IRQ_PENDING) && action) { |
69 | /* | 68 | /* |
70 | * Perform real IRQ processing for the IRQ we deferred | 69 | * Perform real IRQ processing for the IRQ we deferred |
@@ -80,7 +79,7 @@ static int misrouted_irq(int irq, struct pt_regs *regs) | |||
80 | * If we did actual work for the real IRQ line we must let the | 79 | * If we did actual work for the real IRQ line we must let the |
81 | * IRQ controller clean up too | 80 | * IRQ controller clean up too |
82 | */ | 81 | */ |
83 | if(work) | 82 | if (work) |
84 | desc->chip->end(i); | 83 | desc->chip->end(i); |
85 | spin_unlock(&desc->lock); | 84 | spin_unlock(&desc->lock); |
86 | } | 85 | } |
@@ -113,6 +112,7 @@ __report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) | |||
113 | } | 112 | } |
114 | dump_stack(); | 113 | dump_stack(); |
115 | printk(KERN_ERR "handlers:\n"); | 114 | printk(KERN_ERR "handlers:\n"); |
115 | |||
116 | action = desc->action; | 116 | action = desc->action; |
117 | while (action) { | 117 | while (action) { |
118 | printk(KERN_ERR "[<%p>]", action->handler); | 118 | printk(KERN_ERR "[<%p>]", action->handler); |
@@ -123,7 +123,8 @@ __report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) | |||
123 | } | 123 | } |
124 | } | 124 | } |
125 | 125 | ||
126 | static void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) | 126 | static void |
127 | report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) | ||
127 | { | 128 | { |
128 | static int count = 100; | 129 | static int count = 100; |
129 | 130 | ||
@@ -134,7 +135,7 @@ static void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t actio | |||
134 | } | 135 | } |
135 | 136 | ||
136 | void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret, | 137 | void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret, |
137 | struct pt_regs *regs) | 138 | struct pt_regs *regs) |
138 | { | 139 | { |
139 | if (unlikely(action_ret != IRQ_HANDLED)) { | 140 | if (unlikely(action_ret != IRQ_HANDLED)) { |
140 | desc->irqs_unhandled++; | 141 | desc->irqs_unhandled++; |
@@ -177,6 +178,7 @@ int __init noirqdebug_setup(char *str) | |||
177 | { | 178 | { |
178 | noirqdebug = 1; | 179 | noirqdebug = 1; |
179 | printk(KERN_INFO "IRQ lockup detection disabled\n"); | 180 | printk(KERN_INFO "IRQ lockup detection disabled\n"); |
181 | |||
180 | return 1; | 182 | return 1; |
181 | } | 183 | } |
182 | 184 | ||
@@ -187,6 +189,7 @@ static int __init irqfixup_setup(char *str) | |||
187 | irqfixup = 1; | 189 | irqfixup = 1; |
188 | printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n"); | 190 | printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n"); |
189 | printk(KERN_WARNING "This may impact system performance.\n"); | 191 | printk(KERN_WARNING "This may impact system performance.\n"); |
192 | |||
190 | return 1; | 193 | return 1; |
191 | } | 194 | } |
192 | 195 | ||