diff options
-rw-r--r-- | arch/x86/kernel/irq_64.c | 6 | ||||
-rw-r--r-- | include/linux/irq.h | 9 | ||||
-rw-r--r-- | init/main.c | 7 | ||||
-rw-r--r-- | kernel/irq/handle.c | 30 |
4 files changed, 47 insertions, 5 deletions
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c index a3e36336d914..f58b995b30ee 100644 --- a/arch/x86/kernel/irq_64.c +++ b/arch/x86/kernel/irq_64.c | |||
@@ -189,6 +189,7 @@ u64 arch_irq_stat(void) | |||
189 | asmlinkage unsigned int do_IRQ(struct pt_regs *regs) | 189 | asmlinkage unsigned int do_IRQ(struct pt_regs *regs) |
190 | { | 190 | { |
191 | struct pt_regs *old_regs = set_irq_regs(regs); | 191 | struct pt_regs *old_regs = set_irq_regs(regs); |
192 | struct irq_desc *desc; | ||
192 | 193 | ||
193 | /* high bit used in ret_from_ code */ | 194 | /* high bit used in ret_from_ code */ |
194 | unsigned vector = ~regs->orig_ax; | 195 | unsigned vector = ~regs->orig_ax; |
@@ -202,8 +203,9 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs) | |||
202 | stack_overflow_check(regs); | 203 | stack_overflow_check(regs); |
203 | #endif | 204 | #endif |
204 | 205 | ||
205 | if (likely(__irq_to_desc(irq))) | 206 | desc = __irq_to_desc(irq); |
206 | generic_handle_irq(irq); | 207 | if (likely(desc)) |
208 | generic_handle_irq_desc(irq, desc); | ||
207 | else { | 209 | else { |
208 | if (!disable_apic) | 210 | if (!disable_apic) |
209 | ack_APIC_irq(); | 211 | ack_APIC_irq(); |
diff --git a/include/linux/irq.h b/include/linux/irq.h index 9de16ca8b8e5..7b59e193a119 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -315,10 +315,8 @@ extern unsigned int __do_IRQ(unsigned int irq); | |||
315 | * irqchip-style controller then we call the ->handle_irq() handler, | 315 | * irqchip-style controller then we call the ->handle_irq() handler, |
316 | * and it calls __do_IRQ() if it's attached to an irqtype-style controller. | 316 | * and it calls __do_IRQ() if it's attached to an irqtype-style controller. |
317 | */ | 317 | */ |
318 | static inline void generic_handle_irq(unsigned int irq) | 318 | static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *desc) |
319 | { | 319 | { |
320 | struct irq_desc *desc = irq_to_desc(irq); | ||
321 | |||
322 | #ifdef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ | 320 | #ifdef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ |
323 | desc->handle_irq(irq, desc); | 321 | desc->handle_irq(irq, desc); |
324 | #else | 322 | #else |
@@ -329,6 +327,11 @@ static inline void generic_handle_irq(unsigned int irq) | |||
329 | #endif | 327 | #endif |
330 | } | 328 | } |
331 | 329 | ||
330 | static inline void generic_handle_irq(unsigned int irq) | ||
331 | { | ||
332 | generic_handle_irq_desc(irq, irq_to_desc(irq)); | ||
333 | } | ||
334 | |||
332 | /* Handling of unhandled and spurious interrupts: */ | 335 | /* Handling of unhandled and spurious interrupts: */ |
333 | extern void note_interrupt(unsigned int irq, struct irq_desc *desc, | 336 | extern void note_interrupt(unsigned int irq, struct irq_desc *desc, |
334 | int action_ret); | 337 | int action_ret); |
diff --git a/init/main.c b/init/main.c index ab97d0877acc..0d2e60144f83 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -590,6 +590,13 @@ void pre_alloc_dyn_array(void) | |||
590 | if (da->init_work) | 590 | if (da->init_work) |
591 | da->init_work(da); | 591 | da->init_work(da); |
592 | } | 592 | } |
593 | #else | ||
594 | #ifdef CONFIF_GENERIC_HARDIRQS | ||
595 | unsigned int i; | ||
596 | |||
597 | for (i = 0; i < NR_IRQS; i++) | ||
598 | irq_desc[i].irq = i; | ||
599 | #endif | ||
593 | #endif | 600 | #endif |
594 | } | 601 | } |
595 | 602 | ||
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 8e55dbe50afc..e1d787e9169b 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c | |||
@@ -197,6 +197,21 @@ struct irq_desc *irq_to_desc(unsigned int irq) | |||
197 | * we run out of pre-allocate ones, allocate more | 197 | * we run out of pre-allocate ones, allocate more |
198 | */ | 198 | */ |
199 | printk(KERN_DEBUG "try to get more irq_desc %d\n", nr_irq_desc); | 199 | printk(KERN_DEBUG "try to get more irq_desc %d\n", nr_irq_desc); |
200 | { | ||
201 | /* double check if some one mess up the list */ | ||
202 | struct irq_desc *desc; | ||
203 | int count = 0; | ||
204 | |||
205 | desc = &sparse_irqs[0]; | ||
206 | while (desc) { | ||
207 | printk(KERN_DEBUG "found irq_desc for irq %d\n", desc->irq); | ||
208 | if (desc->next) | ||
209 | printk(KERN_DEBUG "found irq_desc for irq %d and next will be irq %d\n", desc->irq, desc->next->irq); | ||
210 | desc = desc->next; | ||
211 | count++; | ||
212 | } | ||
213 | printk(KERN_DEBUG "all preallocted %d\n", count); | ||
214 | } | ||
200 | 215 | ||
201 | total_bytes = sizeof(struct irq_desc) * nr_irq_desc; | 216 | total_bytes = sizeof(struct irq_desc) * nr_irq_desc; |
202 | if (after_bootmem) | 217 | if (after_bootmem) |
@@ -221,6 +236,21 @@ struct irq_desc *irq_to_desc(unsigned int irq) | |||
221 | 236 | ||
222 | desc->irq = irq; | 237 | desc->irq = irq; |
223 | desc_pri->next = desc; | 238 | desc_pri->next = desc; |
239 | { | ||
240 | /* double check if some one mess up the list */ | ||
241 | struct irq_desc *desc; | ||
242 | int count = 0; | ||
243 | |||
244 | desc = &sparse_irqs[0]; | ||
245 | while (desc) { | ||
246 | printk(KERN_DEBUG "1 found irq_desc for irq %d\n", desc->irq); | ||
247 | if (desc->next) | ||
248 | printk(KERN_DEBUG "1 found irq_desc for irq %d and next will be irq %d\n", desc->irq, desc->next->irq); | ||
249 | desc = desc->next; | ||
250 | count++; | ||
251 | } | ||
252 | printk(KERN_DEBUG "1 all preallocted %d\n", count); | ||
253 | } | ||
224 | 254 | ||
225 | return desc; | 255 | return desc; |
226 | } | 256 | } |