diff options
Diffstat (limited to 'arch/powerpc/kernel/irq.c')
-rw-r--r-- | arch/powerpc/kernel/irq.c | 247 |
1 files changed, 167 insertions, 80 deletions
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index e5d121177984..066bd31551d5 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -53,7 +53,6 @@ | |||
53 | #include <linux/bootmem.h> | 53 | #include <linux/bootmem.h> |
54 | #include <linux/pci.h> | 54 | #include <linux/pci.h> |
55 | #include <linux/debugfs.h> | 55 | #include <linux/debugfs.h> |
56 | #include <linux/perf_event.h> | ||
57 | 56 | ||
58 | #include <asm/uaccess.h> | 57 | #include <asm/uaccess.h> |
59 | #include <asm/system.h> | 58 | #include <asm/system.h> |
@@ -70,9 +69,13 @@ | |||
70 | #include <asm/firmware.h> | 69 | #include <asm/firmware.h> |
71 | #include <asm/lv1call.h> | 70 | #include <asm/lv1call.h> |
72 | #endif | 71 | #endif |
72 | #define CREATE_TRACE_POINTS | ||
73 | #include <asm/trace.h> | ||
74 | |||
75 | DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); | ||
76 | EXPORT_PER_CPU_SYMBOL(irq_stat); | ||
73 | 77 | ||
74 | int __irq_offset_value; | 78 | int __irq_offset_value; |
75 | static int ppc_spurious_interrupts; | ||
76 | 79 | ||
77 | #ifdef CONFIG_PPC32 | 80 | #ifdef CONFIG_PPC32 |
78 | EXPORT_SYMBOL(__irq_offset_value); | 81 | EXPORT_SYMBOL(__irq_offset_value); |
@@ -85,7 +88,10 @@ extern int tau_interrupts(int); | |||
85 | #endif /* CONFIG_PPC32 */ | 88 | #endif /* CONFIG_PPC32 */ |
86 | 89 | ||
87 | #ifdef CONFIG_PPC64 | 90 | #ifdef CONFIG_PPC64 |
91 | |||
92 | #ifndef CONFIG_SPARSE_IRQ | ||
88 | EXPORT_SYMBOL(irq_desc); | 93 | EXPORT_SYMBOL(irq_desc); |
94 | #endif | ||
89 | 95 | ||
90 | int distribute_irqs = 1; | 96 | int distribute_irqs = 1; |
91 | 97 | ||
@@ -138,11 +144,6 @@ notrace void raw_local_irq_restore(unsigned long en) | |||
138 | } | 144 | } |
139 | #endif /* CONFIG_PPC_STD_MMU_64 */ | 145 | #endif /* CONFIG_PPC_STD_MMU_64 */ |
140 | 146 | ||
141 | if (test_perf_event_pending()) { | ||
142 | clear_perf_event_pending(); | ||
143 | perf_event_do_pending(); | ||
144 | } | ||
145 | |||
146 | /* | 147 | /* |
147 | * if (get_paca()->hard_enabled) return; | 148 | * if (get_paca()->hard_enabled) return; |
148 | * But again we need to take care that gcc gets hard_enabled directly | 149 | * But again we need to take care that gcc gets hard_enabled directly |
@@ -175,78 +176,135 @@ notrace void raw_local_irq_restore(unsigned long en) | |||
175 | EXPORT_SYMBOL(raw_local_irq_restore); | 176 | EXPORT_SYMBOL(raw_local_irq_restore); |
176 | #endif /* CONFIG_PPC64 */ | 177 | #endif /* CONFIG_PPC64 */ |
177 | 178 | ||
179 | static int show_other_interrupts(struct seq_file *p, int prec) | ||
180 | { | ||
181 | int j; | ||
182 | |||
183 | #if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT) | ||
184 | if (tau_initialized) { | ||
185 | seq_printf(p, "%*s: ", prec, "TAU"); | ||
186 | for_each_online_cpu(j) | ||
187 | seq_printf(p, "%10u ", tau_interrupts(j)); | ||
188 | seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n"); | ||
189 | } | ||
190 | #endif /* CONFIG_PPC32 && CONFIG_TAU_INT */ | ||
191 | |||
192 | seq_printf(p, "%*s: ", prec, "LOC"); | ||
193 | for_each_online_cpu(j) | ||
194 | seq_printf(p, "%10u ", per_cpu(irq_stat, j).timer_irqs); | ||
195 | seq_printf(p, " Local timer interrupts\n"); | ||
196 | |||
197 | seq_printf(p, "%*s: ", prec, "SPU"); | ||
198 | for_each_online_cpu(j) | ||
199 | seq_printf(p, "%10u ", per_cpu(irq_stat, j).spurious_irqs); | ||
200 | seq_printf(p, " Spurious interrupts\n"); | ||
201 | |||
202 | seq_printf(p, "%*s: ", prec, "CNT"); | ||
203 | for_each_online_cpu(j) | ||
204 | seq_printf(p, "%10u ", per_cpu(irq_stat, j).pmu_irqs); | ||
205 | seq_printf(p, " Performance monitoring interrupts\n"); | ||
206 | |||
207 | seq_printf(p, "%*s: ", prec, "MCE"); | ||
208 | for_each_online_cpu(j) | ||
209 | seq_printf(p, "%10u ", per_cpu(irq_stat, j).mce_exceptions); | ||
210 | seq_printf(p, " Machine check exceptions\n"); | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | |||
178 | int show_interrupts(struct seq_file *p, void *v) | 215 | int show_interrupts(struct seq_file *p, void *v) |
179 | { | 216 | { |
180 | int i = *(loff_t *)v, j; | 217 | unsigned long flags, any_count = 0; |
218 | int i = *(loff_t *) v, j, prec; | ||
181 | struct irqaction *action; | 219 | struct irqaction *action; |
182 | struct irq_desc *desc; | 220 | struct irq_desc *desc; |
183 | unsigned long flags; | ||
184 | 221 | ||
222 | if (i > nr_irqs) | ||
223 | return 0; | ||
224 | |||
225 | for (prec = 3, j = 1000; prec < 10 && j <= nr_irqs; ++prec) | ||
226 | j *= 10; | ||
227 | |||
228 | if (i == nr_irqs) | ||
229 | return show_other_interrupts(p, prec); | ||
230 | |||
231 | /* print header */ | ||
185 | if (i == 0) { | 232 | if (i == 0) { |
186 | seq_puts(p, " "); | 233 | seq_printf(p, "%*s", prec + 8, ""); |
187 | for_each_online_cpu(j) | 234 | for_each_online_cpu(j) |
188 | seq_printf(p, "CPU%d ", j); | 235 | seq_printf(p, "CPU%-8d", j); |
189 | seq_putc(p, '\n'); | 236 | seq_putc(p, '\n'); |
190 | } | 237 | } |
191 | 238 | ||
192 | if (i < NR_IRQS) { | 239 | desc = irq_to_desc(i); |
193 | desc = get_irq_desc(i); | 240 | if (!desc) |
194 | spin_lock_irqsave(&desc->lock, flags); | 241 | return 0; |
195 | action = desc->action; | 242 | |
196 | if (!action || !action->handler) | 243 | raw_spin_lock_irqsave(&desc->lock, flags); |
197 | goto skip; | 244 | for_each_online_cpu(j) |
198 | seq_printf(p, "%3d: ", i); | 245 | any_count |= kstat_irqs_cpu(i, j); |
199 | #ifdef CONFIG_SMP | 246 | action = desc->action; |
200 | for_each_online_cpu(j) | 247 | if (!action && !any_count) |
201 | seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); | 248 | goto out; |
202 | #else | 249 | |
203 | seq_printf(p, "%10u ", kstat_irqs(i)); | 250 | seq_printf(p, "%*d: ", prec, i); |
204 | #endif /* CONFIG_SMP */ | 251 | for_each_online_cpu(j) |
205 | if (desc->chip) | 252 | seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); |
206 | seq_printf(p, " %s ", desc->chip->typename); | 253 | |
207 | else | 254 | if (desc->chip) |
208 | seq_puts(p, " None "); | 255 | seq_printf(p, " %-16s", desc->chip->name); |
209 | seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge "); | 256 | else |
210 | seq_printf(p, " %s", action->name); | 257 | seq_printf(p, " %-16s", "None"); |
211 | for (action = action->next; action; action = action->next) | 258 | seq_printf(p, " %-8s", (desc->status & IRQ_LEVEL) ? "Level" : "Edge"); |
259 | |||
260 | if (action) { | ||
261 | seq_printf(p, " %s", action->name); | ||
262 | while ((action = action->next) != NULL) | ||
212 | seq_printf(p, ", %s", action->name); | 263 | seq_printf(p, ", %s", action->name); |
213 | seq_putc(p, '\n'); | ||
214 | skip: | ||
215 | spin_unlock_irqrestore(&desc->lock, flags); | ||
216 | } else if (i == NR_IRQS) { | ||
217 | #if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT) | ||
218 | if (tau_initialized){ | ||
219 | seq_puts(p, "TAU: "); | ||
220 | for_each_online_cpu(j) | ||
221 | seq_printf(p, "%10u ", tau_interrupts(j)); | ||
222 | seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n"); | ||
223 | } | ||
224 | #endif /* CONFIG_PPC32 && CONFIG_TAU_INT*/ | ||
225 | seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts); | ||
226 | } | 264 | } |
265 | |||
266 | seq_putc(p, '\n'); | ||
267 | out: | ||
268 | raw_spin_unlock_irqrestore(&desc->lock, flags); | ||
227 | return 0; | 269 | return 0; |
228 | } | 270 | } |
229 | 271 | ||
272 | /* | ||
273 | * /proc/stat helpers | ||
274 | */ | ||
275 | u64 arch_irq_stat_cpu(unsigned int cpu) | ||
276 | { | ||
277 | u64 sum = per_cpu(irq_stat, cpu).timer_irqs; | ||
278 | |||
279 | sum += per_cpu(irq_stat, cpu).pmu_irqs; | ||
280 | sum += per_cpu(irq_stat, cpu).mce_exceptions; | ||
281 | sum += per_cpu(irq_stat, cpu).spurious_irqs; | ||
282 | |||
283 | return sum; | ||
284 | } | ||
285 | |||
230 | #ifdef CONFIG_HOTPLUG_CPU | 286 | #ifdef CONFIG_HOTPLUG_CPU |
231 | void fixup_irqs(cpumask_t map) | 287 | void fixup_irqs(cpumask_t map) |
232 | { | 288 | { |
289 | struct irq_desc *desc; | ||
233 | unsigned int irq; | 290 | unsigned int irq; |
234 | static int warned; | 291 | static int warned; |
235 | 292 | ||
236 | for_each_irq(irq) { | 293 | for_each_irq(irq) { |
237 | cpumask_t mask; | 294 | cpumask_t mask; |
238 | 295 | ||
239 | if (irq_desc[irq].status & IRQ_PER_CPU) | 296 | desc = irq_to_desc(irq); |
297 | if (desc && desc->status & IRQ_PER_CPU) | ||
240 | continue; | 298 | continue; |
241 | 299 | ||
242 | cpumask_and(&mask, irq_desc[irq].affinity, &map); | 300 | cpumask_and(&mask, desc->affinity, &map); |
243 | if (any_online_cpu(mask) == NR_CPUS) { | 301 | if (any_online_cpu(mask) == NR_CPUS) { |
244 | printk("Breaking affinity for irq %i\n", irq); | 302 | printk("Breaking affinity for irq %i\n", irq); |
245 | mask = map; | 303 | mask = map; |
246 | } | 304 | } |
247 | if (irq_desc[irq].chip->set_affinity) | 305 | if (desc->chip->set_affinity) |
248 | irq_desc[irq].chip->set_affinity(irq, &mask); | 306 | desc->chip->set_affinity(irq, &mask); |
249 | else if (irq_desc[irq].action && !(warned++)) | 307 | else if (desc->action && !(warned++)) |
250 | printk("Cannot set affinity for irq %i\n", irq); | 308 | printk("Cannot set affinity for irq %i\n", irq); |
251 | } | 309 | } |
252 | 310 | ||
@@ -273,7 +331,7 @@ static inline void handle_one_irq(unsigned int irq) | |||
273 | return; | 331 | return; |
274 | } | 332 | } |
275 | 333 | ||
276 | desc = irq_desc + irq; | 334 | desc = irq_to_desc(irq); |
277 | saved_sp_limit = current->thread.ksp_limit; | 335 | saved_sp_limit = current->thread.ksp_limit; |
278 | 336 | ||
279 | irqtp->task = curtp->task; | 337 | irqtp->task = curtp->task; |
@@ -325,6 +383,8 @@ void do_IRQ(struct pt_regs *regs) | |||
325 | struct pt_regs *old_regs = set_irq_regs(regs); | 383 | struct pt_regs *old_regs = set_irq_regs(regs); |
326 | unsigned int irq; | 384 | unsigned int irq; |
327 | 385 | ||
386 | trace_irq_entry(regs); | ||
387 | |||
328 | irq_enter(); | 388 | irq_enter(); |
329 | 389 | ||
330 | check_stack_overflow(); | 390 | check_stack_overflow(); |
@@ -334,8 +394,7 @@ void do_IRQ(struct pt_regs *regs) | |||
334 | if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) | 394 | if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) |
335 | handle_one_irq(irq); | 395 | handle_one_irq(irq); |
336 | else if (irq != NO_IRQ_IGNORE) | 396 | else if (irq != NO_IRQ_IGNORE) |
337 | /* That's not SMP safe ... but who cares ? */ | 397 | __get_cpu_var(irq_stat).spurious_irqs++; |
338 | ppc_spurious_interrupts++; | ||
339 | 398 | ||
340 | irq_exit(); | 399 | irq_exit(); |
341 | set_irq_regs(old_regs); | 400 | set_irq_regs(old_regs); |
@@ -348,6 +407,8 @@ void do_IRQ(struct pt_regs *regs) | |||
348 | timer_interrupt(regs); | 407 | timer_interrupt(regs); |
349 | } | 408 | } |
350 | #endif | 409 | #endif |
410 | |||
411 | trace_irq_exit(regs); | ||
351 | } | 412 | } |
352 | 413 | ||
353 | void __init init_IRQ(void) | 414 | void __init init_IRQ(void) |
@@ -453,7 +514,7 @@ void do_softirq(void) | |||
453 | */ | 514 | */ |
454 | 515 | ||
455 | static LIST_HEAD(irq_hosts); | 516 | static LIST_HEAD(irq_hosts); |
456 | static DEFINE_SPINLOCK(irq_big_lock); | 517 | static DEFINE_RAW_SPINLOCK(irq_big_lock); |
457 | static unsigned int revmap_trees_allocated; | 518 | static unsigned int revmap_trees_allocated; |
458 | static DEFINE_MUTEX(revmap_trees_mutex); | 519 | static DEFINE_MUTEX(revmap_trees_mutex); |
459 | struct irq_map_entry irq_map[NR_IRQS]; | 520 | struct irq_map_entry irq_map[NR_IRQS]; |
@@ -499,14 +560,14 @@ struct irq_host *irq_alloc_host(struct device_node *of_node, | |||
499 | if (host->ops->match == NULL) | 560 | if (host->ops->match == NULL) |
500 | host->ops->match = default_irq_host_match; | 561 | host->ops->match = default_irq_host_match; |
501 | 562 | ||
502 | spin_lock_irqsave(&irq_big_lock, flags); | 563 | raw_spin_lock_irqsave(&irq_big_lock, flags); |
503 | 564 | ||
504 | /* If it's a legacy controller, check for duplicates and | 565 | /* If it's a legacy controller, check for duplicates and |
505 | * mark it as allocated (we use irq 0 host pointer for that | 566 | * mark it as allocated (we use irq 0 host pointer for that |
506 | */ | 567 | */ |
507 | if (revmap_type == IRQ_HOST_MAP_LEGACY) { | 568 | if (revmap_type == IRQ_HOST_MAP_LEGACY) { |
508 | if (irq_map[0].host != NULL) { | 569 | if (irq_map[0].host != NULL) { |
509 | spin_unlock_irqrestore(&irq_big_lock, flags); | 570 | raw_spin_unlock_irqrestore(&irq_big_lock, flags); |
510 | /* If we are early boot, we can't free the structure, | 571 | /* If we are early boot, we can't free the structure, |
511 | * too bad... | 572 | * too bad... |
512 | * this will be fixed once slab is made available early | 573 | * this will be fixed once slab is made available early |
@@ -520,7 +581,7 @@ struct irq_host *irq_alloc_host(struct device_node *of_node, | |||
520 | } | 581 | } |
521 | 582 | ||
522 | list_add(&host->link, &irq_hosts); | 583 | list_add(&host->link, &irq_hosts); |
523 | spin_unlock_irqrestore(&irq_big_lock, flags); | 584 | raw_spin_unlock_irqrestore(&irq_big_lock, flags); |
524 | 585 | ||
525 | /* Additional setups per revmap type */ | 586 | /* Additional setups per revmap type */ |
526 | switch(revmap_type) { | 587 | switch(revmap_type) { |
@@ -535,7 +596,7 @@ struct irq_host *irq_alloc_host(struct device_node *of_node, | |||
535 | smp_wmb(); | 596 | smp_wmb(); |
536 | 597 | ||
537 | /* Clear norequest flags */ | 598 | /* Clear norequest flags */ |
538 | get_irq_desc(i)->status &= ~IRQ_NOREQUEST; | 599 | irq_to_desc(i)->status &= ~IRQ_NOREQUEST; |
539 | 600 | ||
540 | /* Legacy flags are left to default at this point, | 601 | /* Legacy flags are left to default at this point, |
541 | * one can then use irq_create_mapping() to | 602 | * one can then use irq_create_mapping() to |
@@ -571,13 +632,13 @@ struct irq_host *irq_find_host(struct device_node *node) | |||
571 | * the absence of a device node. This isn't a problem so far | 632 | * the absence of a device node. This isn't a problem so far |
572 | * yet though... | 633 | * yet though... |
573 | */ | 634 | */ |
574 | spin_lock_irqsave(&irq_big_lock, flags); | 635 | raw_spin_lock_irqsave(&irq_big_lock, flags); |
575 | list_for_each_entry(h, &irq_hosts, link) | 636 | list_for_each_entry(h, &irq_hosts, link) |
576 | if (h->ops->match(h, node)) { | 637 | if (h->ops->match(h, node)) { |
577 | found = h; | 638 | found = h; |
578 | break; | 639 | break; |
579 | } | 640 | } |
580 | spin_unlock_irqrestore(&irq_big_lock, flags); | 641 | raw_spin_unlock_irqrestore(&irq_big_lock, flags); |
581 | return found; | 642 | return found; |
582 | } | 643 | } |
583 | EXPORT_SYMBOL_GPL(irq_find_host); | 644 | EXPORT_SYMBOL_GPL(irq_find_host); |
@@ -601,8 +662,16 @@ void irq_set_virq_count(unsigned int count) | |||
601 | static int irq_setup_virq(struct irq_host *host, unsigned int virq, | 662 | static int irq_setup_virq(struct irq_host *host, unsigned int virq, |
602 | irq_hw_number_t hwirq) | 663 | irq_hw_number_t hwirq) |
603 | { | 664 | { |
665 | struct irq_desc *desc; | ||
666 | |||
667 | desc = irq_to_desc_alloc_node(virq, 0); | ||
668 | if (!desc) { | ||
669 | pr_debug("irq: -> allocating desc failed\n"); | ||
670 | goto error; | ||
671 | } | ||
672 | |||
604 | /* Clear IRQ_NOREQUEST flag */ | 673 | /* Clear IRQ_NOREQUEST flag */ |
605 | get_irq_desc(virq)->status &= ~IRQ_NOREQUEST; | 674 | desc->status &= ~IRQ_NOREQUEST; |
606 | 675 | ||
607 | /* map it */ | 676 | /* map it */ |
608 | smp_wmb(); | 677 | smp_wmb(); |
@@ -611,11 +680,14 @@ static int irq_setup_virq(struct irq_host *host, unsigned int virq, | |||
611 | 680 | ||
612 | if (host->ops->map(host, virq, hwirq)) { | 681 | if (host->ops->map(host, virq, hwirq)) { |
613 | pr_debug("irq: -> mapping failed, freeing\n"); | 682 | pr_debug("irq: -> mapping failed, freeing\n"); |
614 | irq_free_virt(virq, 1); | 683 | goto error; |
615 | return -1; | ||
616 | } | 684 | } |
617 | 685 | ||
618 | return 0; | 686 | return 0; |
687 | |||
688 | error: | ||
689 | irq_free_virt(virq, 1); | ||
690 | return -1; | ||
619 | } | 691 | } |
620 | 692 | ||
621 | unsigned int irq_create_direct_mapping(struct irq_host *host) | 693 | unsigned int irq_create_direct_mapping(struct irq_host *host) |
@@ -699,7 +771,7 @@ unsigned int irq_create_mapping(struct irq_host *host, | |||
699 | EXPORT_SYMBOL_GPL(irq_create_mapping); | 771 | EXPORT_SYMBOL_GPL(irq_create_mapping); |
700 | 772 | ||
701 | unsigned int irq_create_of_mapping(struct device_node *controller, | 773 | unsigned int irq_create_of_mapping(struct device_node *controller, |
702 | u32 *intspec, unsigned int intsize) | 774 | const u32 *intspec, unsigned int intsize) |
703 | { | 775 | { |
704 | struct irq_host *host; | 776 | struct irq_host *host; |
705 | irq_hw_number_t hwirq; | 777 | irq_hw_number_t hwirq; |
@@ -732,7 +804,7 @@ unsigned int irq_create_of_mapping(struct device_node *controller, | |||
732 | 804 | ||
733 | /* Set type if specified and different than the current one */ | 805 | /* Set type if specified and different than the current one */ |
734 | if (type != IRQ_TYPE_NONE && | 806 | if (type != IRQ_TYPE_NONE && |
735 | type != (get_irq_desc(virq)->status & IRQF_TRIGGER_MASK)) | 807 | type != (irq_to_desc(virq)->status & IRQF_TRIGGER_MASK)) |
736 | set_irq_type(virq, type); | 808 | set_irq_type(virq, type); |
737 | return virq; | 809 | return virq; |
738 | } | 810 | } |
@@ -804,7 +876,7 @@ void irq_dispose_mapping(unsigned int virq) | |||
804 | irq_map[virq].hwirq = host->inval_irq; | 876 | irq_map[virq].hwirq = host->inval_irq; |
805 | 877 | ||
806 | /* Set some flags */ | 878 | /* Set some flags */ |
807 | get_irq_desc(virq)->status |= IRQ_NOREQUEST; | 879 | irq_to_desc(virq)->status |= IRQ_NOREQUEST; |
808 | 880 | ||
809 | /* Free it */ | 881 | /* Free it */ |
810 | irq_free_virt(virq, 1); | 882 | irq_free_virt(virq, 1); |
@@ -935,7 +1007,7 @@ unsigned int irq_alloc_virt(struct irq_host *host, | |||
935 | if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS)) | 1007 | if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS)) |
936 | return NO_IRQ; | 1008 | return NO_IRQ; |
937 | 1009 | ||
938 | spin_lock_irqsave(&irq_big_lock, flags); | 1010 | raw_spin_lock_irqsave(&irq_big_lock, flags); |
939 | 1011 | ||
940 | /* Use hint for 1 interrupt if any */ | 1012 | /* Use hint for 1 interrupt if any */ |
941 | if (count == 1 && hint >= NUM_ISA_INTERRUPTS && | 1013 | if (count == 1 && hint >= NUM_ISA_INTERRUPTS && |
@@ -959,7 +1031,7 @@ unsigned int irq_alloc_virt(struct irq_host *host, | |||
959 | } | 1031 | } |
960 | } | 1032 | } |
961 | if (found == NO_IRQ) { | 1033 | if (found == NO_IRQ) { |
962 | spin_unlock_irqrestore(&irq_big_lock, flags); | 1034 | raw_spin_unlock_irqrestore(&irq_big_lock, flags); |
963 | return NO_IRQ; | 1035 | return NO_IRQ; |
964 | } | 1036 | } |
965 | hint_found: | 1037 | hint_found: |
@@ -968,7 +1040,7 @@ unsigned int irq_alloc_virt(struct irq_host *host, | |||
968 | smp_wmb(); | 1040 | smp_wmb(); |
969 | irq_map[i].host = host; | 1041 | irq_map[i].host = host; |
970 | } | 1042 | } |
971 | spin_unlock_irqrestore(&irq_big_lock, flags); | 1043 | raw_spin_unlock_irqrestore(&irq_big_lock, flags); |
972 | return found; | 1044 | return found; |
973 | } | 1045 | } |
974 | 1046 | ||
@@ -980,7 +1052,7 @@ void irq_free_virt(unsigned int virq, unsigned int count) | |||
980 | WARN_ON (virq < NUM_ISA_INTERRUPTS); | 1052 | WARN_ON (virq < NUM_ISA_INTERRUPTS); |
981 | WARN_ON (count == 0 || (virq + count) > irq_virq_count); | 1053 | WARN_ON (count == 0 || (virq + count) > irq_virq_count); |
982 | 1054 | ||
983 | spin_lock_irqsave(&irq_big_lock, flags); | 1055 | raw_spin_lock_irqsave(&irq_big_lock, flags); |
984 | for (i = virq; i < (virq + count); i++) { | 1056 | for (i = virq; i < (virq + count); i++) { |
985 | struct irq_host *host; | 1057 | struct irq_host *host; |
986 | 1058 | ||
@@ -993,15 +1065,27 @@ void irq_free_virt(unsigned int virq, unsigned int count) | |||
993 | smp_wmb(); | 1065 | smp_wmb(); |
994 | irq_map[i].host = NULL; | 1066 | irq_map[i].host = NULL; |
995 | } | 1067 | } |
996 | spin_unlock_irqrestore(&irq_big_lock, flags); | 1068 | raw_spin_unlock_irqrestore(&irq_big_lock, flags); |
997 | } | 1069 | } |
998 | 1070 | ||
999 | void irq_early_init(void) | 1071 | int arch_early_irq_init(void) |
1000 | { | 1072 | { |
1001 | unsigned int i; | 1073 | struct irq_desc *desc; |
1074 | int i; | ||
1075 | |||
1076 | for (i = 0; i < NR_IRQS; i++) { | ||
1077 | desc = irq_to_desc(i); | ||
1078 | if (desc) | ||
1079 | desc->status |= IRQ_NOREQUEST; | ||
1080 | } | ||
1002 | 1081 | ||
1003 | for (i = 0; i < NR_IRQS; i++) | 1082 | return 0; |
1004 | get_irq_desc(i)->status |= IRQ_NOREQUEST; | 1083 | } |
1084 | |||
1085 | int arch_init_chip_data(struct irq_desc *desc, int node) | ||
1086 | { | ||
1087 | desc->status |= IRQ_NOREQUEST; | ||
1088 | return 0; | ||
1005 | } | 1089 | } |
1006 | 1090 | ||
1007 | /* We need to create the radix trees late */ | 1091 | /* We need to create the radix trees late */ |
@@ -1063,16 +1147,19 @@ static int virq_debug_show(struct seq_file *m, void *private) | |||
1063 | seq_printf(m, "%-5s %-7s %-15s %s\n", "virq", "hwirq", | 1147 | seq_printf(m, "%-5s %-7s %-15s %s\n", "virq", "hwirq", |
1064 | "chip name", "host name"); | 1148 | "chip name", "host name"); |
1065 | 1149 | ||
1066 | for (i = 1; i < NR_IRQS; i++) { | 1150 | for (i = 1; i < nr_irqs; i++) { |
1067 | desc = get_irq_desc(i); | 1151 | desc = irq_to_desc(i); |
1068 | spin_lock_irqsave(&desc->lock, flags); | 1152 | if (!desc) |
1153 | continue; | ||
1154 | |||
1155 | raw_spin_lock_irqsave(&desc->lock, flags); | ||
1069 | 1156 | ||
1070 | if (desc->action && desc->action->handler) { | 1157 | if (desc->action && desc->action->handler) { |
1071 | seq_printf(m, "%5d ", i); | 1158 | seq_printf(m, "%5d ", i); |
1072 | seq_printf(m, "0x%05lx ", virq_to_hw(i)); | 1159 | seq_printf(m, "0x%05lx ", virq_to_hw(i)); |
1073 | 1160 | ||
1074 | if (desc->chip && desc->chip->typename) | 1161 | if (desc->chip && desc->chip->name) |
1075 | p = desc->chip->typename; | 1162 | p = desc->chip->name; |
1076 | else | 1163 | else |
1077 | p = none; | 1164 | p = none; |
1078 | seq_printf(m, "%-15s ", p); | 1165 | seq_printf(m, "%-15s ", p); |
@@ -1084,7 +1171,7 @@ static int virq_debug_show(struct seq_file *m, void *private) | |||
1084 | seq_printf(m, "%s\n", p); | 1171 | seq_printf(m, "%s\n", p); |
1085 | } | 1172 | } |
1086 | 1173 | ||
1087 | spin_unlock_irqrestore(&desc->lock, flags); | 1174 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
1088 | } | 1175 | } |
1089 | 1176 | ||
1090 | return 0; | 1177 | return 0; |