[POWERPC] Lazy interrupt disabling for 64-bit machines
[safe/jmp/linux-2.6] / arch / powerpc / kernel / irq.c
1 /*
2  *  Derived from arch/i386/kernel/irq.c
3  *    Copyright (C) 1992 Linus Torvalds
4  *  Adapted from arch/i386 by Gary Thomas
5  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6  *  Updated and modified by Cort Dougan <cort@fsmlabs.com>
7  *    Copyright (C) 1996-2001 Cort Dougan
8  *  Adapted for Power Macintosh by Paul Mackerras
9  *    Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
10  *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version
15  * 2 of the License, or (at your option) any later version.
16  *
17  * This file contains the code used by various IRQ handling routines:
18  * asking for different IRQ's should be done through these routines
19  * instead of just grabbing them. Thus setups with different IRQ numbers
20  * shouldn't result in any weird surprises, and installing new handlers
21  * should be easier.
22  *
23  * The MPC8xx has an interrupt mask in the SIU.  If a bit is set, the
24  * interrupt is _enabled_.  As expected, IRQ0 is bit 0 in the 32-bit
25  * mask register (of which only 16 are defined), hence the weird shifting
26  * and complement of the cached_irq_mask.  I want to be able to stuff
27  * this right into the SIU SMASK register.
28  * Many of the prep/chrp functions are conditional compiled on CONFIG_8xx
29  * to reduce code space and undefined function references.
30  */
31
32 #undef DEBUG
33
34 #include <linux/module.h>
35 #include <linux/threads.h>
36 #include <linux/kernel_stat.h>
37 #include <linux/signal.h>
38 #include <linux/sched.h>
39 #include <linux/ptrace.h>
40 #include <linux/ioport.h>
41 #include <linux/interrupt.h>
42 #include <linux/timex.h>
43 #include <linux/init.h>
44 #include <linux/slab.h>
45 #include <linux/delay.h>
46 #include <linux/irq.h>
47 #include <linux/seq_file.h>
48 #include <linux/cpumask.h>
49 #include <linux/profile.h>
50 #include <linux/bitops.h>
51 #include <linux/list.h>
52 #include <linux/radix-tree.h>
53 #include <linux/mutex.h>
54 #include <linux/bootmem.h>
55 #include <linux/pci.h>
56
57 #include <asm/uaccess.h>
58 #include <asm/system.h>
59 #include <asm/io.h>
60 #include <asm/pgtable.h>
61 #include <asm/irq.h>
62 #include <asm/cache.h>
63 #include <asm/prom.h>
64 #include <asm/ptrace.h>
65 #include <asm/machdep.h>
66 #include <asm/udbg.h>
67 #ifdef CONFIG_PPC64
68 #include <asm/paca.h>
69 #include <asm/firmware.h>
70 #endif
71
72 int __irq_offset_value;
73 static int ppc_spurious_interrupts;
74
75 #ifdef CONFIG_PPC32
76 EXPORT_SYMBOL(__irq_offset_value);
77 atomic_t ppc_n_lost_interrupts;
78
79 #ifndef CONFIG_PPC_MERGE
80 #define NR_MASK_WORDS   ((NR_IRQS + 31) / 32)
81 unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
82 #endif
83
84 #ifdef CONFIG_TAU_INT
85 extern int tau_initialized;
86 extern int tau_interrupts(int);
87 #endif
88 #endif /* CONFIG_PPC32 */
89
90 #if defined(CONFIG_SMP) && !defined(CONFIG_PPC_MERGE)
91 extern atomic_t ipi_recv;
92 extern atomic_t ipi_sent;
93 #endif
94
95 #ifdef CONFIG_PPC64
96 EXPORT_SYMBOL(irq_desc);
97
98 int distribute_irqs = 1;
99
100 void local_irq_restore(unsigned long en)
101 {
102         get_paca()->soft_enabled = en;
103         if (!en)
104                 return;
105
106         if (firmware_has_feature(FW_FEATURE_ISERIES)) {
107                 if (get_paca()->lppaca_ptr->int_dword.any_int)
108                         iseries_handle_interrupts();
109                 return;
110         }
111
112         if (get_paca()->hard_enabled)
113                 return;
114         /* need to hard-enable interrupts here */
115         get_paca()->hard_enabled = en;
116         if ((int)mfspr(SPRN_DEC) < 0)
117                 mtspr(SPRN_DEC, 1);
118         hard_irq_enable();
119 }
120 #endif /* CONFIG_PPC64 */
121
122 int show_interrupts(struct seq_file *p, void *v)
123 {
124         int i = *(loff_t *)v, j;
125         struct irqaction *action;
126         irq_desc_t *desc;
127         unsigned long flags;
128
129         if (i == 0) {
130                 seq_puts(p, "           ");
131                 for_each_online_cpu(j)
132                         seq_printf(p, "CPU%d       ", j);
133                 seq_putc(p, '\n');
134         }
135
136         if (i < NR_IRQS) {
137                 desc = get_irq_desc(i);
138                 spin_lock_irqsave(&desc->lock, flags);
139                 action = desc->action;
140                 if (!action || !action->handler)
141                         goto skip;
142                 seq_printf(p, "%3d: ", i);
143 #ifdef CONFIG_SMP
144                 for_each_online_cpu(j)
145                         seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
146 #else
147                 seq_printf(p, "%10u ", kstat_irqs(i));
148 #endif /* CONFIG_SMP */
149                 if (desc->chip)
150                         seq_printf(p, " %s ", desc->chip->typename);
151                 else
152                         seq_puts(p, "  None      ");
153                 seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge  ");
154                 seq_printf(p, "    %s", action->name);
155                 for (action = action->next; action; action = action->next)
156                         seq_printf(p, ", %s", action->name);
157                 seq_putc(p, '\n');
158 skip:
159                 spin_unlock_irqrestore(&desc->lock, flags);
160         } else if (i == NR_IRQS) {
161 #ifdef CONFIG_PPC32
162 #ifdef CONFIG_TAU_INT
163                 if (tau_initialized){
164                         seq_puts(p, "TAU: ");
165                         for_each_online_cpu(j)
166                                 seq_printf(p, "%10u ", tau_interrupts(j));
167                         seq_puts(p, "  PowerPC             Thermal Assist (cpu temp)\n");
168                 }
169 #endif
170 #if defined(CONFIG_SMP) && !defined(CONFIG_PPC_MERGE)
171                 /* should this be per processor send/receive? */
172                 seq_printf(p, "IPI (recv/sent): %10u/%u\n",
173                                 atomic_read(&ipi_recv), atomic_read(&ipi_sent));
174 #endif
175 #endif /* CONFIG_PPC32 */
176                 seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
177         }
178         return 0;
179 }
180
181 #ifdef CONFIG_HOTPLUG_CPU
182 void fixup_irqs(cpumask_t map)
183 {
184         unsigned int irq;
185         static int warned;
186
187         for_each_irq(irq) {
188                 cpumask_t mask;
189
190                 if (irq_desc[irq].status & IRQ_PER_CPU)
191                         continue;
192
193                 cpus_and(mask, irq_desc[irq].affinity, map);
194                 if (any_online_cpu(mask) == NR_CPUS) {
195                         printk("Breaking affinity for irq %i\n", irq);
196                         mask = map;
197                 }
198                 if (irq_desc[irq].chip->set_affinity)
199                         irq_desc[irq].chip->set_affinity(irq, mask);
200                 else if (irq_desc[irq].action && !(warned++))
201                         printk("Cannot set affinity for irq %i\n", irq);
202         }
203
204         local_irq_enable();
205         mdelay(1);
206         local_irq_disable();
207 }
208 #endif
209
210 void do_IRQ(struct pt_regs *regs)
211 {
212         struct pt_regs *old_regs = set_irq_regs(regs);
213         unsigned int irq;
214 #ifdef CONFIG_IRQSTACKS
215         struct thread_info *curtp, *irqtp;
216 #endif
217
218         irq_enter();
219
220 #ifdef CONFIG_DEBUG_STACKOVERFLOW
221         /* Debugging check for stack overflow: is there less than 2KB free? */
222         {
223                 long sp;
224
225                 sp = __get_SP() & (THREAD_SIZE-1);
226
227                 if (unlikely(sp < (sizeof(struct thread_info) + 2048))) {
228                         printk("do_IRQ: stack overflow: %ld\n",
229                                 sp - sizeof(struct thread_info));
230                         dump_stack();
231                 }
232         }
233 #endif
234
235         /*
236          * Every platform is required to implement ppc_md.get_irq.
237          * This function will either return an irq number or -1 to
238          * indicate there are no more pending.
239          * The value -2 is for buggy hardware and means that this IRQ
240          * has already been handled. -- Tom
241          */
242         irq = ppc_md.get_irq();
243
244         if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) {
245 #ifdef CONFIG_IRQSTACKS
246                 /* Switch to the irq stack to handle this */
247                 curtp = current_thread_info();
248                 irqtp = hardirq_ctx[smp_processor_id()];
249                 if (curtp != irqtp) {
250                         struct irq_desc *desc = irq_desc + irq;
251                         void *handler = desc->handle_irq;
252                         if (handler == NULL)
253                                 handler = &__do_IRQ;
254                         irqtp->task = curtp->task;
255                         irqtp->flags = 0;
256                         call_handle_irq(irq, desc, irqtp, handler);
257                         irqtp->task = NULL;
258                         if (irqtp->flags)
259                                 set_bits(irqtp->flags, &curtp->flags);
260                 } else
261 #endif
262                         generic_handle_irq(irq);
263         } else if (irq != NO_IRQ_IGNORE)
264                 /* That's not SMP safe ... but who cares ? */
265                 ppc_spurious_interrupts++;
266
267         irq_exit();
268         set_irq_regs(old_regs);
269
270 #ifdef CONFIG_PPC_ISERIES
271         if (get_lppaca()->int_dword.fields.decr_int) {
272                 get_lppaca()->int_dword.fields.decr_int = 0;
273                 /* Signal a fake decrementer interrupt */
274                 timer_interrupt(regs);
275         }
276 #endif
277 }
278
279 void __init init_IRQ(void)
280 {
281         ppc_md.init_IRQ();
282 #ifdef CONFIG_PPC64
283         irq_ctx_init();
284 #endif
285 }
286
287
288 #ifdef CONFIG_IRQSTACKS
289 struct thread_info *softirq_ctx[NR_CPUS] __read_mostly;
290 struct thread_info *hardirq_ctx[NR_CPUS] __read_mostly;
291
292 void irq_ctx_init(void)
293 {
294         struct thread_info *tp;
295         int i;
296
297         for_each_possible_cpu(i) {
298                 memset((void *)softirq_ctx[i], 0, THREAD_SIZE);
299                 tp = softirq_ctx[i];
300                 tp->cpu = i;
301                 tp->preempt_count = SOFTIRQ_OFFSET;
302
303                 memset((void *)hardirq_ctx[i], 0, THREAD_SIZE);
304                 tp = hardirq_ctx[i];
305                 tp->cpu = i;
306                 tp->preempt_count = HARDIRQ_OFFSET;
307         }
308 }
309
310 static inline void do_softirq_onstack(void)
311 {
312         struct thread_info *curtp, *irqtp;
313
314         curtp = current_thread_info();
315         irqtp = softirq_ctx[smp_processor_id()];
316         irqtp->task = curtp->task;
317         call_do_softirq(irqtp);
318         irqtp->task = NULL;
319 }
320
321 #else
322 #define do_softirq_onstack()    __do_softirq()
323 #endif /* CONFIG_IRQSTACKS */
324
325 void do_softirq(void)
326 {
327         unsigned long flags;
328
329         if (in_interrupt())
330                 return;
331
332         local_irq_save(flags);
333
334         if (local_softirq_pending())
335                 do_softirq_onstack();
336
337         local_irq_restore(flags);
338 }
339 EXPORT_SYMBOL(do_softirq);
340
341
342 /*
343  * IRQ controller and virtual interrupts
344  */
345
346 #ifdef CONFIG_PPC_MERGE
347
348 static LIST_HEAD(irq_hosts);
349 static spinlock_t irq_big_lock = SPIN_LOCK_UNLOCKED;
350 static DEFINE_PER_CPU(unsigned int, irq_radix_reader);
351 static unsigned int irq_radix_writer;
352 struct irq_map_entry irq_map[NR_IRQS];
353 static unsigned int irq_virq_count = NR_IRQS;
354 static struct irq_host *irq_default_host;
355
356 struct irq_host *irq_alloc_host(unsigned int revmap_type,
357                                 unsigned int revmap_arg,
358                                 struct irq_host_ops *ops,
359                                 irq_hw_number_t inval_irq)
360 {
361         struct irq_host *host;
362         unsigned int size = sizeof(struct irq_host);
363         unsigned int i;
364         unsigned int *rmap;
365         unsigned long flags;
366
367         /* Allocate structure and revmap table if using linear mapping */
368         if (revmap_type == IRQ_HOST_MAP_LINEAR)
369                 size += revmap_arg * sizeof(unsigned int);
370         if (mem_init_done)
371                 host = kzalloc(size, GFP_KERNEL);
372         else {
373                 host = alloc_bootmem(size);
374                 if (host)
375                         memset(host, 0, size);
376         }
377         if (host == NULL)
378                 return NULL;
379
380         /* Fill structure */
381         host->revmap_type = revmap_type;
382         host->inval_irq = inval_irq;
383         host->ops = ops;
384
385         spin_lock_irqsave(&irq_big_lock, flags);
386
387         /* If it's a legacy controller, check for duplicates and
388          * mark it as allocated (we use irq 0 host pointer for that
389          */
390         if (revmap_type == IRQ_HOST_MAP_LEGACY) {
391                 if (irq_map[0].host != NULL) {
392                         spin_unlock_irqrestore(&irq_big_lock, flags);
393                         /* If we are early boot, we can't free the structure,
394                          * too bad...
395                          * this will be fixed once slab is made available early
396                          * instead of the current cruft
397                          */
398                         if (mem_init_done)
399                                 kfree(host);
400                         return NULL;
401                 }
402                 irq_map[0].host = host;
403         }
404
405         list_add(&host->link, &irq_hosts);
406         spin_unlock_irqrestore(&irq_big_lock, flags);
407
408         /* Additional setups per revmap type */
409         switch(revmap_type) {
410         case IRQ_HOST_MAP_LEGACY:
411                 /* 0 is always the invalid number for legacy */
412                 host->inval_irq = 0;
413                 /* setup us as the host for all legacy interrupts */
414                 for (i = 1; i < NUM_ISA_INTERRUPTS; i++) {
415                         irq_map[i].hwirq = 0;
416                         smp_wmb();
417                         irq_map[i].host = host;
418                         smp_wmb();
419
420                         /* Clear norequest flags */
421                         get_irq_desc(i)->status &= ~IRQ_NOREQUEST;
422
423                         /* Legacy flags are left to default at this point,
424                          * one can then use irq_create_mapping() to
425                          * explicitely change them
426                          */
427                         ops->map(host, i, i);
428                 }
429                 break;
430         case IRQ_HOST_MAP_LINEAR:
431                 rmap = (unsigned int *)(host + 1);
432                 for (i = 0; i < revmap_arg; i++)
433                         rmap[i] = IRQ_NONE;
434                 host->revmap_data.linear.size = revmap_arg;
435                 smp_wmb();
436                 host->revmap_data.linear.revmap = rmap;
437                 break;
438         default:
439                 break;
440         }
441
442         pr_debug("irq: Allocated host of type %d @0x%p\n", revmap_type, host);
443
444         return host;
445 }
446
447 struct irq_host *irq_find_host(struct device_node *node)
448 {
449         struct irq_host *h, *found = NULL;
450         unsigned long flags;
451
452         /* We might want to match the legacy controller last since
453          * it might potentially be set to match all interrupts in
454          * the absence of a device node. This isn't a problem so far
455          * yet though...
456          */
457         spin_lock_irqsave(&irq_big_lock, flags);
458         list_for_each_entry(h, &irq_hosts, link)
459                 if (h->ops->match == NULL || h->ops->match(h, node)) {
460                         found = h;
461                         break;
462                 }
463         spin_unlock_irqrestore(&irq_big_lock, flags);
464         return found;
465 }
466 EXPORT_SYMBOL_GPL(irq_find_host);
467
468 void irq_set_default_host(struct irq_host *host)
469 {
470         pr_debug("irq: Default host set to @0x%p\n", host);
471
472         irq_default_host = host;
473 }
474
475 void irq_set_virq_count(unsigned int count)
476 {
477         pr_debug("irq: Trying to set virq count to %d\n", count);
478
479         BUG_ON(count < NUM_ISA_INTERRUPTS);
480         if (count < NR_IRQS)
481                 irq_virq_count = count;
482 }
483
484 /* radix tree not lockless safe ! we use a brlock-type mecanism
485  * for now, until we can use a lockless radix tree
486  */
487 static void irq_radix_wrlock(unsigned long *flags)
488 {
489         unsigned int cpu, ok;
490
491         spin_lock_irqsave(&irq_big_lock, *flags);
492         irq_radix_writer = 1;
493         smp_mb();
494         do {
495                 barrier();
496                 ok = 1;
497                 for_each_possible_cpu(cpu) {
498                         if (per_cpu(irq_radix_reader, cpu)) {
499                                 ok = 0;
500                                 break;
501                         }
502                 }
503                 if (!ok)
504                         cpu_relax();
505         } while(!ok);
506 }
507
508 static void irq_radix_wrunlock(unsigned long flags)
509 {
510         smp_wmb();
511         irq_radix_writer = 0;
512         spin_unlock_irqrestore(&irq_big_lock, flags);
513 }
514
515 static void irq_radix_rdlock(unsigned long *flags)
516 {
517         local_irq_save(*flags);
518         __get_cpu_var(irq_radix_reader) = 1;
519         smp_mb();
520         if (likely(irq_radix_writer == 0))
521                 return;
522         __get_cpu_var(irq_radix_reader) = 0;
523         smp_wmb();
524         spin_lock(&irq_big_lock);
525         __get_cpu_var(irq_radix_reader) = 1;
526         spin_unlock(&irq_big_lock);
527 }
528
529 static void irq_radix_rdunlock(unsigned long flags)
530 {
531         __get_cpu_var(irq_radix_reader) = 0;
532         local_irq_restore(flags);
533 }
534
535
536 unsigned int irq_create_mapping(struct irq_host *host,
537                                 irq_hw_number_t hwirq)
538 {
539         unsigned int virq, hint;
540
541         pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq);
542
543         /* Look for default host if nececssary */
544         if (host == NULL)
545                 host = irq_default_host;
546         if (host == NULL) {
547                 printk(KERN_WARNING "irq_create_mapping called for"
548                        " NULL host, hwirq=%lx\n", hwirq);
549                 WARN_ON(1);
550                 return NO_IRQ;
551         }
552         pr_debug("irq: -> using host @%p\n", host);
553
554         /* Check if mapping already exist, if it does, call
555          * host->ops->map() to update the flags
556          */
557         virq = irq_find_mapping(host, hwirq);
558         if (virq != IRQ_NONE) {
559                 pr_debug("irq: -> existing mapping on virq %d\n", virq);
560                 return virq;
561         }
562
563         /* Get a virtual interrupt number */
564         if (host->revmap_type == IRQ_HOST_MAP_LEGACY) {
565                 /* Handle legacy */
566                 virq = (unsigned int)hwirq;
567                 if (virq == 0 || virq >= NUM_ISA_INTERRUPTS)
568                         return NO_IRQ;
569                 return virq;
570         } else {
571                 /* Allocate a virtual interrupt number */
572                 hint = hwirq % irq_virq_count;
573                 virq = irq_alloc_virt(host, 1, hint);
574                 if (virq == NO_IRQ) {
575                         pr_debug("irq: -> virq allocation failed\n");
576                         return NO_IRQ;
577                 }
578         }
579         pr_debug("irq: -> obtained virq %d\n", virq);
580
581         /* Clear IRQ_NOREQUEST flag */
582         get_irq_desc(virq)->status &= ~IRQ_NOREQUEST;
583
584         /* map it */
585         smp_wmb();
586         irq_map[virq].hwirq = hwirq;
587         smp_mb();
588         if (host->ops->map(host, virq, hwirq)) {
589                 pr_debug("irq: -> mapping failed, freeing\n");
590                 irq_free_virt(virq, 1);
591                 return NO_IRQ;
592         }
593         return virq;
594 }
595 EXPORT_SYMBOL_GPL(irq_create_mapping);
596
597 unsigned int irq_create_of_mapping(struct device_node *controller,
598                                    u32 *intspec, unsigned int intsize)
599 {
600         struct irq_host *host;
601         irq_hw_number_t hwirq;
602         unsigned int type = IRQ_TYPE_NONE;
603         unsigned int virq;
604
605         if (controller == NULL)
606                 host = irq_default_host;
607         else
608                 host = irq_find_host(controller);
609         if (host == NULL) {
610                 printk(KERN_WARNING "irq: no irq host found for %s !\n",
611                        controller->full_name);
612                 return NO_IRQ;
613         }
614
615         /* If host has no translation, then we assume interrupt line */
616         if (host->ops->xlate == NULL)
617                 hwirq = intspec[0];
618         else {
619                 if (host->ops->xlate(host, controller, intspec, intsize,
620                                      &hwirq, &type))
621                         return NO_IRQ;
622         }
623
624         /* Create mapping */
625         virq = irq_create_mapping(host, hwirq);
626         if (virq == NO_IRQ)
627                 return virq;
628
629         /* Set type if specified and different than the current one */
630         if (type != IRQ_TYPE_NONE &&
631             type != (get_irq_desc(virq)->status & IRQF_TRIGGER_MASK))
632                 set_irq_type(virq, type);
633         return virq;
634 }
635 EXPORT_SYMBOL_GPL(irq_create_of_mapping);
636
637 unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
638 {
639         struct of_irq oirq;
640
641         if (of_irq_map_one(dev, index, &oirq))
642                 return NO_IRQ;
643
644         return irq_create_of_mapping(oirq.controller, oirq.specifier,
645                                      oirq.size);
646 }
647 EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
648
649 void irq_dispose_mapping(unsigned int virq)
650 {
651         struct irq_host *host = irq_map[virq].host;
652         irq_hw_number_t hwirq;
653         unsigned long flags;
654
655         WARN_ON (host == NULL);
656         if (host == NULL)
657                 return;
658
659         /* Never unmap legacy interrupts */
660         if (host->revmap_type == IRQ_HOST_MAP_LEGACY)
661                 return;
662
663         /* remove chip and handler */
664         set_irq_chip_and_handler(virq, NULL, NULL);
665
666         /* Make sure it's completed */
667         synchronize_irq(virq);
668
669         /* Tell the PIC about it */
670         if (host->ops->unmap)
671                 host->ops->unmap(host, virq);
672         smp_mb();
673
674         /* Clear reverse map */
675         hwirq = irq_map[virq].hwirq;
676         switch(host->revmap_type) {
677         case IRQ_HOST_MAP_LINEAR:
678                 if (hwirq < host->revmap_data.linear.size)
679                         host->revmap_data.linear.revmap[hwirq] = IRQ_NONE;
680                 break;
681         case IRQ_HOST_MAP_TREE:
682                 /* Check if radix tree allocated yet */
683                 if (host->revmap_data.tree.gfp_mask == 0)
684                         break;
685                 irq_radix_wrlock(&flags);
686                 radix_tree_delete(&host->revmap_data.tree, hwirq);
687                 irq_radix_wrunlock(flags);
688                 break;
689         }
690
691         /* Destroy map */
692         smp_mb();
693         irq_map[virq].hwirq = host->inval_irq;
694
695         /* Set some flags */
696         get_irq_desc(virq)->status |= IRQ_NOREQUEST;
697
698         /* Free it */
699         irq_free_virt(virq, 1);
700 }
701 EXPORT_SYMBOL_GPL(irq_dispose_mapping);
702
703 unsigned int irq_find_mapping(struct irq_host *host,
704                               irq_hw_number_t hwirq)
705 {
706         unsigned int i;
707         unsigned int hint = hwirq % irq_virq_count;
708
709         /* Look for default host if nececssary */
710         if (host == NULL)
711                 host = irq_default_host;
712         if (host == NULL)
713                 return NO_IRQ;
714
715         /* legacy -> bail early */
716         if (host->revmap_type == IRQ_HOST_MAP_LEGACY)
717                 return hwirq;
718
719         /* Slow path does a linear search of the map */
720         if (hint < NUM_ISA_INTERRUPTS)
721                 hint = NUM_ISA_INTERRUPTS;
722         i = hint;
723         do  {
724                 if (irq_map[i].host == host &&
725                     irq_map[i].hwirq == hwirq)
726                         return i;
727                 i++;
728                 if (i >= irq_virq_count)
729                         i = NUM_ISA_INTERRUPTS;
730         } while(i != hint);
731         return NO_IRQ;
732 }
733 EXPORT_SYMBOL_GPL(irq_find_mapping);
734
735
736 unsigned int irq_radix_revmap(struct irq_host *host,
737                               irq_hw_number_t hwirq)
738 {
739         struct radix_tree_root *tree;
740         struct irq_map_entry *ptr;
741         unsigned int virq;
742         unsigned long flags;
743
744         WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE);
745
746         /* Check if the radix tree exist yet. We test the value of
747          * the gfp_mask for that. Sneaky but saves another int in the
748          * structure. If not, we fallback to slow mode
749          */
750         tree = &host->revmap_data.tree;
751         if (tree->gfp_mask == 0)
752                 return irq_find_mapping(host, hwirq);
753
754         /* Now try to resolve */
755         irq_radix_rdlock(&flags);
756         ptr = radix_tree_lookup(tree, hwirq);
757         irq_radix_rdunlock(flags);
758
759         /* Found it, return */
760         if (ptr) {
761                 virq = ptr - irq_map;
762                 return virq;
763         }
764
765         /* If not there, try to insert it */
766         virq = irq_find_mapping(host, hwirq);
767         if (virq != NO_IRQ) {
768                 irq_radix_wrlock(&flags);
769                 radix_tree_insert(tree, hwirq, &irq_map[virq]);
770                 irq_radix_wrunlock(flags);
771         }
772         return virq;
773 }
774
775 unsigned int irq_linear_revmap(struct irq_host *host,
776                                irq_hw_number_t hwirq)
777 {
778         unsigned int *revmap;
779
780         WARN_ON(host->revmap_type != IRQ_HOST_MAP_LINEAR);
781
782         /* Check revmap bounds */
783         if (unlikely(hwirq >= host->revmap_data.linear.size))
784                 return irq_find_mapping(host, hwirq);
785
786         /* Check if revmap was allocated */
787         revmap = host->revmap_data.linear.revmap;
788         if (unlikely(revmap == NULL))
789                 return irq_find_mapping(host, hwirq);
790
791         /* Fill up revmap with slow path if no mapping found */
792         if (unlikely(revmap[hwirq] == NO_IRQ))
793                 revmap[hwirq] = irq_find_mapping(host, hwirq);
794
795         return revmap[hwirq];
796 }
797
798 unsigned int irq_alloc_virt(struct irq_host *host,
799                             unsigned int count,
800                             unsigned int hint)
801 {
802         unsigned long flags;
803         unsigned int i, j, found = NO_IRQ;
804
805         if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS))
806                 return NO_IRQ;
807
808         spin_lock_irqsave(&irq_big_lock, flags);
809
810         /* Use hint for 1 interrupt if any */
811         if (count == 1 && hint >= NUM_ISA_INTERRUPTS &&
812             hint < irq_virq_count && irq_map[hint].host == NULL) {
813                 found = hint;
814                 goto hint_found;
815         }
816
817         /* Look for count consecutive numbers in the allocatable
818          * (non-legacy) space
819          */
820         for (i = NUM_ISA_INTERRUPTS, j = 0; i < irq_virq_count; i++) {
821                 if (irq_map[i].host != NULL)
822                         j = 0;
823                 else
824                         j++;
825
826                 if (j == count) {
827                         found = i - count + 1;
828                         break;
829                 }
830         }
831         if (found == NO_IRQ) {
832                 spin_unlock_irqrestore(&irq_big_lock, flags);
833                 return NO_IRQ;
834         }
835  hint_found:
836         for (i = found; i < (found + count); i++) {
837                 irq_map[i].hwirq = host->inval_irq;
838                 smp_wmb();
839                 irq_map[i].host = host;
840         }
841         spin_unlock_irqrestore(&irq_big_lock, flags);
842         return found;
843 }
844
845 void irq_free_virt(unsigned int virq, unsigned int count)
846 {
847         unsigned long flags;
848         unsigned int i;
849
850         WARN_ON (virq < NUM_ISA_INTERRUPTS);
851         WARN_ON (count == 0 || (virq + count) > irq_virq_count);
852
853         spin_lock_irqsave(&irq_big_lock, flags);
854         for (i = virq; i < (virq + count); i++) {
855                 struct irq_host *host;
856
857                 if (i < NUM_ISA_INTERRUPTS ||
858                     (virq + count) > irq_virq_count)
859                         continue;
860
861                 host = irq_map[i].host;
862                 irq_map[i].hwirq = host->inval_irq;
863                 smp_wmb();
864                 irq_map[i].host = NULL;
865         }
866         spin_unlock_irqrestore(&irq_big_lock, flags);
867 }
868
869 void irq_early_init(void)
870 {
871         unsigned int i;
872
873         for (i = 0; i < NR_IRQS; i++)
874                 get_irq_desc(i)->status |= IRQ_NOREQUEST;
875 }
876
877 /* We need to create the radix trees late */
878 static int irq_late_init(void)
879 {
880         struct irq_host *h;
881         unsigned long flags;
882
883         irq_radix_wrlock(&flags);
884         list_for_each_entry(h, &irq_hosts, link) {
885                 if (h->revmap_type == IRQ_HOST_MAP_TREE)
886                         INIT_RADIX_TREE(&h->revmap_data.tree, GFP_ATOMIC);
887         }
888         irq_radix_wrunlock(flags);
889
890         return 0;
891 }
892 arch_initcall(irq_late_init);
893
894 #endif /* CONFIG_PPC_MERGE */
895
896 #ifdef CONFIG_PCI_MSI
897 int pci_enable_msi(struct pci_dev * pdev)
898 {
899         if (ppc_md.enable_msi)
900                 return ppc_md.enable_msi(pdev);
901         else
902                 return -1;
903 }
904 EXPORT_SYMBOL(pci_enable_msi);
905
906 void pci_disable_msi(struct pci_dev * pdev)
907 {
908         if (ppc_md.disable_msi)
909                 ppc_md.disable_msi(pdev);
910 }
911 EXPORT_SYMBOL(pci_disable_msi);
912
913 void pci_scan_msi_device(struct pci_dev *dev) {}
914 int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) {return -1;}
915 void pci_disable_msix(struct pci_dev *dev) {}
916 void msi_remove_pci_irq_vectors(struct pci_dev *dev) {}
917 void disable_msi_mode(struct pci_dev *dev, int pos, int type) {}
918 void pci_no_msi(void) {}
919 EXPORT_SYMBOL(pci_enable_msix);
920 EXPORT_SYMBOL(pci_disable_msix);
921
922 #endif
923
924 #ifdef CONFIG_PPC64
925 static int __init setup_noirqdistrib(char *str)
926 {
927         distribute_irqs = 0;
928         return 1;
929 }
930
931 __setup("noirqdistrib", setup_noirqdistrib);
932 #endif /* CONFIG_PPC64 */