]> rtime.felk.cvut.cz Git - linux-imx.git/blob - arch/ia64/kernel/iosapic.c
522b13d0bde345dd2698d00ca286a038c3418772
[linux-imx.git] / arch / ia64 / kernel / iosapic.c
1 /*
2  * I/O SAPIC support.
3  *
4  * Copyright (C) 1999 Intel Corp.
5  * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
6  * Copyright (C) 2000-2002 J.I. Lee <jung-ik.lee@intel.com>
7  * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co.
8  *      David Mosberger-Tang <davidm@hpl.hp.com>
9  * Copyright (C) 1999 VA Linux Systems
10  * Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
11  *
12  * 00/04/19     D. Mosberger    Rewritten to mirror more closely the x86 I/O
13  *                              APIC code.  In particular, we now have separate
14  *                              handlers for edge and level triggered
15  *                              interrupts.
16  * 00/10/27     Asit Mallick, Goutham Rao <goutham.rao@intel.com> IRQ vector
17  *                              allocation PCI to vector mapping, shared PCI
18  *                              interrupts.
19  * 00/10/27     D. Mosberger    Document things a bit more to make them more
20  *                              understandable.  Clean up much of the old
21  *                              IOSAPIC cruft.
22  * 01/07/27     J.I. Lee        PCI irq routing, Platform/Legacy interrupts
23  *                              and fixes for ACPI S5(SoftOff) support.
24  * 02/01/23     J.I. Lee        iosapic pgm fixes for PCI irq routing from _PRT
25  * 02/01/07     E. Focht        <efocht@ess.nec.de> Redirectable interrupt
26  *                              vectors in iosapic_set_affinity(),
27  *                              initializations for /proc/irq/#/smp_affinity
28  * 02/04/02     P. Diefenbaugh  Cleaned up ACPI PCI IRQ routing.
29  * 02/04/18     J.I. Lee        bug fix in iosapic_init_pci_irq
30  * 02/04/30     J.I. Lee        bug fix in find_iosapic to fix ACPI PCI IRQ to
31  *                              IOSAPIC mapping error
32  * 02/07/29     T. Kochi        Allocate interrupt vectors dynamically
33  * 02/08/04     T. Kochi        Cleaned up terminology (irq, global system
34  *                              interrupt, vector, etc.)
35  * 02/09/20     D. Mosberger    Simplified by taking advantage of ACPI's
36  *                              pci_irq code.
37  * 03/02/19     B. Helgaas      Make pcat_compat system-wide, not per-IOSAPIC.
38  *                              Remove iosapic_address & gsi_base from
39  *                              external interfaces.  Rationalize
40  *                              __init/__devinit attributes.
41  * 04/12/04 Ashok Raj   <ashok.raj@intel.com> Intel Corporation 2004
42  *                              Updated to work with irq migration necessary
43  *                              for CPU Hotplug
44  */
45 /*
46  * Here is what the interrupt logic between a PCI device and the kernel looks
47  * like:
48  *
49  * (1) A PCI device raises one of the four interrupt pins (INTA, INTB, INTC,
50  *     INTD).  The device is uniquely identified by its bus-, and slot-number
51  *     (the function number does not matter here because all functions share
52  *     the same interrupt lines).
53  *
54  * (2) The motherboard routes the interrupt line to a pin on a IOSAPIC
55  *     controller.  Multiple interrupt lines may have to share the same
56  *     IOSAPIC pin (if they're level triggered and use the same polarity).
57  *     Each interrupt line has a unique Global System Interrupt (GSI) number
58  *     which can be calculated as the sum of the controller's base GSI number
59  *     and the IOSAPIC pin number to which the line connects.
60  *
61  * (3) The IOSAPIC uses an internal routing table entries (RTEs) to map the
62  * IOSAPIC pin into the IA-64 interrupt vector.  This interrupt vector is then
63  * sent to the CPU.
64  *
65  * (4) The kernel recognizes an interrupt as an IRQ.  The IRQ interface is
66  *     used as architecture-independent interrupt handling mechanism in Linux.
67  *     As an IRQ is a number, we have to have
68  *     IA-64 interrupt vector number <-> IRQ number mapping.  On smaller
69  *     systems, we use one-to-one mapping between IA-64 vector and IRQ.  A
70  *     platform can implement platform_irq_to_vector(irq) and
71  *     platform_local_vector_to_irq(vector) APIs to differentiate the mapping.
72  *     Please see also include/asm-ia64/hw_irq.h for those APIs.
73  *
74  * To sum up, there are three levels of mappings involved:
75  *
76  *      PCI pin -> global system interrupt (GSI) -> IA-64 vector <-> IRQ
77  *
78  * Note: The term "IRQ" is loosely used everywhere in Linux kernel to
79  * describeinterrupts.  Now we use "IRQ" only for Linux IRQ's.  ISA IRQ
80  * (isa_irq) is the only exception in this source code.
81  */
82
83 #include <linux/acpi.h>
84 #include <linux/init.h>
85 #include <linux/irq.h>
86 #include <linux/kernel.h>
87 #include <linux/list.h>
88 #include <linux/pci.h>
89 #include <linux/smp.h>
90 #include <linux/string.h>
91 #include <linux/bootmem.h>
92
93 #include <asm/delay.h>
94 #include <asm/hw_irq.h>
95 #include <asm/io.h>
96 #include <asm/iosapic.h>
97 #include <asm/machvec.h>
98 #include <asm/processor.h>
99 #include <asm/ptrace.h>
100 #include <asm/system.h>
101
102 #undef DEBUG_INTERRUPT_ROUTING
103
104 #ifdef DEBUG_INTERRUPT_ROUTING
105 #define DBG(fmt...)     printk(fmt)
106 #else
107 #define DBG(fmt...)
108 #endif
109
110 #define NR_PREALLOCATE_RTE_ENTRIES \
111         (PAGE_SIZE / sizeof(struct iosapic_rte_info))
112 #define RTE_PREALLOCATED        (1)
113
114 static DEFINE_SPINLOCK(iosapic_lock);
115
116 /*
117  * These tables map IA-64 vectors to the IOSAPIC pin that generates this
118  * vector.
119  */
120
121 struct iosapic_rte_info {
122         struct list_head rte_list;      /* node in list of RTEs sharing the
123                                          * same vector */
124         char __iomem    *addr;          /* base address of IOSAPIC */
125         unsigned int    gsi_base;       /* first GSI assigned to this
126                                          * IOSAPIC */
127         char            rte_index;      /* IOSAPIC RTE index */
128         int             refcnt;         /* reference counter */
129         unsigned int    flags;          /* flags */
130 } ____cacheline_aligned;
131
132 static struct iosapic_intr_info {
133         struct list_head rtes;          /* RTEs using this vector (empty =>
134                                          * not an IOSAPIC interrupt) */
135         int             count;          /* # of RTEs that shares this vector */
136         u32             low32;          /* current value of low word of
137                                          * Redirection table entry */
138         unsigned int    dest;           /* destination CPU physical ID */
139         unsigned char   dmode   : 3;    /* delivery mode (see iosapic.h) */
140         unsigned char   polarity: 1;    /* interrupt polarity
141                                          * (see iosapic.h) */
142         unsigned char   trigger : 1;    /* trigger mode (see iosapic.h) */
143 } iosapic_intr_info[IA64_NUM_VECTORS];
144
145 static struct iosapic {
146         char __iomem    *addr;          /* base address of IOSAPIC */
147         unsigned int    gsi_base;       /* first GSI assigned to this
148                                          * IOSAPIC */
149         unsigned short  num_rte;        /* # of RTEs on this IOSAPIC */
150         int             rtes_inuse;     /* # of RTEs in use on this IOSAPIC */
151 #ifdef CONFIG_NUMA
152         unsigned short  node;           /* numa node association via pxm */
153 #endif
154 } iosapic_lists[NR_IOSAPICS];
155
156 static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */
157
158 static int iosapic_kmalloc_ok;
159 static LIST_HEAD(free_rte_list);
160
161 /*
162  * Find an IOSAPIC associated with a GSI
163  */
164 static inline int
165 find_iosapic (unsigned int gsi)
166 {
167         int i;
168
169         for (i = 0; i < NR_IOSAPICS; i++) {
170                 if ((unsigned) (gsi - iosapic_lists[i].gsi_base) <
171                     iosapic_lists[i].num_rte)
172                         return i;
173         }
174
175         return -1;
176 }
177
178 static inline int
179 _gsi_to_vector (unsigned int gsi)
180 {
181         struct iosapic_intr_info *info;
182         struct iosapic_rte_info *rte;
183
184         for (info = iosapic_intr_info; info <
185                      iosapic_intr_info + IA64_NUM_VECTORS; ++info)
186                 list_for_each_entry(rte, &info->rtes, rte_list)
187                         if (rte->gsi_base + rte->rte_index == gsi)
188                                 return info - iosapic_intr_info;
189         return -1;
190 }
191
192 /*
193  * Translate GSI number to the corresponding IA-64 interrupt vector.  If no
194  * entry exists, return -1.
195  */
196 inline int
197 gsi_to_vector (unsigned int gsi)
198 {
199         return _gsi_to_vector(gsi);
200 }
201
202 int
203 gsi_to_irq (unsigned int gsi)
204 {
205         unsigned long flags;
206         int irq;
207         /*
208          * XXX fix me: this assumes an identity mapping between IA-64 vector
209          * and Linux irq numbers...
210          */
211         spin_lock_irqsave(&iosapic_lock, flags);
212         irq = _gsi_to_vector(gsi);
213         spin_unlock_irqrestore(&iosapic_lock, flags);
214
215         return irq;
216 }
217
218 static struct iosapic_rte_info *gsi_vector_to_rte(unsigned int gsi,
219                                                   unsigned int vec)
220 {
221         struct iosapic_rte_info *rte;
222
223         list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list)
224                 if (rte->gsi_base + rte->rte_index == gsi)
225                         return rte;
226         return NULL;
227 }
228
229 static void
230 set_rte (unsigned int gsi, unsigned int vector, unsigned int dest, int mask)
231 {
232         unsigned long pol, trigger, dmode;
233         u32 low32, high32;
234         char __iomem *addr;
235         int rte_index;
236         char redir;
237         struct iosapic_rte_info *rte;
238
239         DBG(KERN_DEBUG"IOSAPIC: routing vector %d to 0x%x\n", vector, dest);
240
241         rte = gsi_vector_to_rte(gsi, vector);
242         if (!rte)
243                 return;         /* not an IOSAPIC interrupt */
244
245         rte_index = rte->rte_index;
246         addr    = rte->addr;
247         pol     = iosapic_intr_info[vector].polarity;
248         trigger = iosapic_intr_info[vector].trigger;
249         dmode   = iosapic_intr_info[vector].dmode;
250
251         redir = (dmode == IOSAPIC_LOWEST_PRIORITY) ? 1 : 0;
252
253 #ifdef CONFIG_SMP
254         {
255                 unsigned int irq;
256
257                 for (irq = 0; irq < NR_IRQS; ++irq)
258                         if (irq_to_vector(irq) == vector) {
259                                 set_irq_affinity_info(irq,
260                                                       (int)(dest & 0xffff),
261                                                       redir);
262                                 break;
263                         }
264         }
265 #endif
266
267         low32 = ((pol << IOSAPIC_POLARITY_SHIFT) |
268                  (trigger << IOSAPIC_TRIGGER_SHIFT) |
269                  (dmode << IOSAPIC_DELIVERY_SHIFT) |
270                  ((mask ? 1 : 0) << IOSAPIC_MASK_SHIFT) |
271                  vector);
272
273         /* dest contains both id and eid */
274         high32 = (dest << IOSAPIC_DEST_SHIFT);
275
276         iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), high32);
277         iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
278         iosapic_intr_info[vector].low32 = low32;
279         iosapic_intr_info[vector].dest = dest;
280 }
281
282 static void
283 nop (unsigned int irq)
284 {
285         /* do nothing... */
286 }
287
288
289 #ifdef CONFIG_KEXEC
290 void
291 kexec_disable_iosapic(void)
292 {
293         struct iosapic_intr_info *info;
294         struct iosapic_rte_info *rte;
295         u8 vec = 0;
296         for (info = iosapic_intr_info; info <
297                         iosapic_intr_info + IA64_NUM_VECTORS; ++info, ++vec) {
298                 list_for_each_entry(rte, &info->rtes,
299                                 rte_list) {
300                         iosapic_write(rte->addr,
301                                         IOSAPIC_RTE_LOW(rte->rte_index),
302                                         IOSAPIC_MASK|vec);
303                         iosapic_eoi(rte->addr, vec);
304                 }
305         }
306 }
307 #endif
308
309 static void
310 mask_irq (unsigned int irq)
311 {
312         unsigned long flags;
313         char __iomem *addr;
314         u32 low32;
315         int rte_index;
316         ia64_vector vec = irq_to_vector(irq);
317         struct iosapic_rte_info *rte;
318
319         if (list_empty(&iosapic_intr_info[vec].rtes))
320                 return;                 /* not an IOSAPIC interrupt! */
321
322         spin_lock_irqsave(&iosapic_lock, flags);
323         /* set only the mask bit */
324         low32 = iosapic_intr_info[vec].low32 |= IOSAPIC_MASK;
325         list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) {
326                 addr = rte->addr;
327                 rte_index = rte->rte_index;
328                 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
329         }
330         spin_unlock_irqrestore(&iosapic_lock, flags);
331 }
332
333 static void
334 unmask_irq (unsigned int irq)
335 {
336         unsigned long flags;
337         char __iomem *addr;
338         u32 low32;
339         int rte_index;
340         ia64_vector vec = irq_to_vector(irq);
341         struct iosapic_rte_info *rte;
342
343         if (list_empty(&iosapic_intr_info[vec].rtes))
344                 return;                 /* not an IOSAPIC interrupt! */
345
346         spin_lock_irqsave(&iosapic_lock, flags);
347         low32 = iosapic_intr_info[vec].low32 &= ~IOSAPIC_MASK;
348         list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) {
349                 addr = rte->addr;
350                 rte_index = rte->rte_index;
351                 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
352         }
353         spin_unlock_irqrestore(&iosapic_lock, flags);
354 }
355
356
357 static void
358 iosapic_set_affinity (unsigned int irq, cpumask_t mask)
359 {
360 #ifdef CONFIG_SMP
361         unsigned long flags;
362         u32 high32, low32;
363         int dest, rte_index;
364         char __iomem *addr;
365         int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0;
366         ia64_vector vec;
367         struct iosapic_rte_info *rte;
368
369         irq &= (~IA64_IRQ_REDIRECTED);
370         vec = irq_to_vector(irq);
371
372         if (cpus_empty(mask))
373                 return;
374
375         dest = cpu_physical_id(first_cpu(mask));
376
377         if (list_empty(&iosapic_intr_info[vec].rtes))
378                 return;                 /* not an IOSAPIC interrupt */
379
380         set_irq_affinity_info(irq, dest, redir);
381
382         /* dest contains both id and eid */
383         high32 = dest << IOSAPIC_DEST_SHIFT;
384
385         spin_lock_irqsave(&iosapic_lock, flags);
386         low32 = iosapic_intr_info[vec].low32 & ~(7 << IOSAPIC_DELIVERY_SHIFT);
387         if (redir)
388                 /* change delivery mode to lowest priority */
389                 low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT);
390         else
391                 /* change delivery mode to fixed */
392                 low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT);
393
394         iosapic_intr_info[vec].low32 = low32;
395         iosapic_intr_info[vec].dest = dest;
396         list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) {
397                 addr = rte->addr;
398                 rte_index = rte->rte_index;
399                 iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), high32);
400                 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
401         }
402         spin_unlock_irqrestore(&iosapic_lock, flags);
403 #endif
404 }
405
406 /*
407  * Handlers for level-triggered interrupts.
408  */
409
410 static unsigned int
411 iosapic_startup_level_irq (unsigned int irq)
412 {
413         unmask_irq(irq);
414         return 0;
415 }
416
417 static void
418 iosapic_end_level_irq (unsigned int irq)
419 {
420         ia64_vector vec = irq_to_vector(irq);
421         struct iosapic_rte_info *rte;
422
423         move_native_irq(irq);
424         list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list)
425                 iosapic_eoi(rte->addr, vec);
426 }
427
428 #define iosapic_shutdown_level_irq      mask_irq
429 #define iosapic_enable_level_irq        unmask_irq
430 #define iosapic_disable_level_irq       mask_irq
431 #define iosapic_ack_level_irq           nop
432
433 struct irq_chip irq_type_iosapic_level = {
434         .name =         "IO-SAPIC-level",
435         .startup =      iosapic_startup_level_irq,
436         .shutdown =     iosapic_shutdown_level_irq,
437         .enable =       iosapic_enable_level_irq,
438         .disable =      iosapic_disable_level_irq,
439         .ack =          iosapic_ack_level_irq,
440         .end =          iosapic_end_level_irq,
441         .mask =         mask_irq,
442         .unmask =       unmask_irq,
443         .set_affinity = iosapic_set_affinity
444 };
445
446 /*
447  * Handlers for edge-triggered interrupts.
448  */
449
450 static unsigned int
451 iosapic_startup_edge_irq (unsigned int irq)
452 {
453         unmask_irq(irq);
454         /*
455          * IOSAPIC simply drops interrupts pended while the
456          * corresponding pin was masked, so we can't know if an
457          * interrupt is pending already.  Let's hope not...
458          */
459         return 0;
460 }
461
462 static void
463 iosapic_ack_edge_irq (unsigned int irq)
464 {
465         irq_desc_t *idesc = irq_desc + irq;
466
467         move_native_irq(irq);
468         /*
469          * Once we have recorded IRQ_PENDING already, we can mask the
470          * interrupt for real. This prevents IRQ storms from unhandled
471          * devices.
472          */
473         if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) ==
474             (IRQ_PENDING|IRQ_DISABLED))
475                 mask_irq(irq);
476 }
477
478 #define iosapic_enable_edge_irq         unmask_irq
479 #define iosapic_disable_edge_irq        nop
480 #define iosapic_end_edge_irq            nop
481
482 struct irq_chip irq_type_iosapic_edge = {
483         .name =         "IO-SAPIC-edge",
484         .startup =      iosapic_startup_edge_irq,
485         .shutdown =     iosapic_disable_edge_irq,
486         .enable =       iosapic_enable_edge_irq,
487         .disable =      iosapic_disable_edge_irq,
488         .ack =          iosapic_ack_edge_irq,
489         .end =          iosapic_end_edge_irq,
490         .mask =         mask_irq,
491         .unmask =       unmask_irq,
492         .set_affinity = iosapic_set_affinity
493 };
494
495 unsigned int
496 iosapic_version (char __iomem *addr)
497 {
498         /*
499          * IOSAPIC Version Register return 32 bit structure like:
500          * {
501          *      unsigned int version   : 8;
502          *      unsigned int reserved1 : 8;
503          *      unsigned int max_redir : 8;
504          *      unsigned int reserved2 : 8;
505          * }
506          */
507         return iosapic_read(addr, IOSAPIC_VERSION);
508 }
509
510 static int iosapic_find_sharable_vector (unsigned long trigger,
511                                          unsigned long pol)
512 {
513         int i, vector = -1, min_count = -1;
514         struct iosapic_intr_info *info;
515
516         /*
517          * shared vectors for edge-triggered interrupts are not
518          * supported yet
519          */
520         if (trigger == IOSAPIC_EDGE)
521                 return -1;
522
523         for (i = IA64_FIRST_DEVICE_VECTOR; i <= IA64_LAST_DEVICE_VECTOR; i++) {
524                 info = &iosapic_intr_info[i];
525                 if (info->trigger == trigger && info->polarity == pol &&
526                     (info->dmode == IOSAPIC_FIXED || info->dmode ==
527                      IOSAPIC_LOWEST_PRIORITY)) {
528                         if (min_count == -1 || info->count < min_count) {
529                                 vector = i;
530                                 min_count = info->count;
531                         }
532                 }
533         }
534
535         return vector;
536 }
537
538 /*
539  * if the given vector is already owned by other,
540  *  assign a new vector for the other and make the vector available
541  */
542 static void __init
543 iosapic_reassign_vector (int vector)
544 {
545         int new_vector;
546
547         if (!list_empty(&iosapic_intr_info[vector].rtes)) {
548                 new_vector = assign_irq_vector(AUTO_ASSIGN);
549                 if (new_vector < 0)
550                         panic("%s: out of interrupt vectors!\n", __FUNCTION__);
551                 printk(KERN_INFO "Reassigning vector %d to %d\n",
552                        vector, new_vector);
553                 memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector],
554                        sizeof(struct iosapic_intr_info));
555                 INIT_LIST_HEAD(&iosapic_intr_info[new_vector].rtes);
556                 list_move(iosapic_intr_info[vector].rtes.next,
557                           &iosapic_intr_info[new_vector].rtes);
558                 memset(&iosapic_intr_info[vector], 0,
559                        sizeof(struct iosapic_intr_info));
560                 iosapic_intr_info[vector].low32 = IOSAPIC_MASK;
561                 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes);
562         }
563 }
564
565 static struct iosapic_rte_info *iosapic_alloc_rte (void)
566 {
567         int i;
568         struct iosapic_rte_info *rte;
569         int preallocated = 0;
570
571         if (!iosapic_kmalloc_ok && list_empty(&free_rte_list)) {
572                 rte = alloc_bootmem(sizeof(struct iosapic_rte_info) *
573                                     NR_PREALLOCATE_RTE_ENTRIES);
574                 if (!rte)
575                         return NULL;
576                 for (i = 0; i < NR_PREALLOCATE_RTE_ENTRIES; i++, rte++)
577                         list_add(&rte->rte_list, &free_rte_list);
578         }
579
580         if (!list_empty(&free_rte_list)) {
581                 rte = list_entry(free_rte_list.next, struct iosapic_rte_info,
582                                  rte_list);
583                 list_del(&rte->rte_list);
584                 preallocated++;
585         } else {
586                 rte = kmalloc(sizeof(struct iosapic_rte_info), GFP_ATOMIC);
587                 if (!rte)
588                         return NULL;
589         }
590
591         memset(rte, 0, sizeof(struct iosapic_rte_info));
592         if (preallocated)
593                 rte->flags |= RTE_PREALLOCATED;
594
595         return rte;
596 }
597
598 static void iosapic_free_rte (struct iosapic_rte_info *rte)
599 {
600         if (rte->flags & RTE_PREALLOCATED)
601                 list_add_tail(&rte->rte_list, &free_rte_list);
602         else
603                 kfree(rte);
604 }
605
606 static inline int vector_is_shared (int vector)
607 {
608         return (iosapic_intr_info[vector].count > 1);
609 }
610
611 static int
612 register_intr (unsigned int gsi, int vector, unsigned char delivery,
613                unsigned long polarity, unsigned long trigger)
614 {
615         irq_desc_t *idesc;
616         struct hw_interrupt_type *irq_type;
617         int rte_index;
618         int index;
619         unsigned long gsi_base;
620         void __iomem *iosapic_address;
621         struct iosapic_rte_info *rte;
622
623         index = find_iosapic(gsi);
624         if (index < 0) {
625                 printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n",
626                        __FUNCTION__, gsi);
627                 return -ENODEV;
628         }
629
630         iosapic_address = iosapic_lists[index].addr;
631         gsi_base = iosapic_lists[index].gsi_base;
632
633         rte = gsi_vector_to_rte(gsi, vector);
634         if (!rte) {
635                 rte = iosapic_alloc_rte();
636                 if (!rte) {
637                         printk(KERN_WARNING "%s: cannot allocate memory\n",
638                                __FUNCTION__);
639                         return -ENOMEM;
640                 }
641
642                 rte_index = gsi - gsi_base;
643                 rte->rte_index  = rte_index;
644                 rte->addr       = iosapic_address;
645                 rte->gsi_base   = gsi_base;
646                 rte->refcnt++;
647                 list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes);
648                 iosapic_intr_info[vector].count++;
649                 iosapic_lists[index].rtes_inuse++;
650         }
651         else if (vector_is_shared(vector)) {
652                 struct iosapic_intr_info *info = &iosapic_intr_info[vector];
653                 if (info->trigger != trigger || info->polarity != polarity) {
654                         printk (KERN_WARNING
655                                 "%s: cannot override the interrupt\n",
656                                 __FUNCTION__);
657                         return -EINVAL;
658                 }
659         }
660
661         iosapic_intr_info[vector].polarity = polarity;
662         iosapic_intr_info[vector].dmode    = delivery;
663         iosapic_intr_info[vector].trigger  = trigger;
664
665         if (trigger == IOSAPIC_EDGE)
666                 irq_type = &irq_type_iosapic_edge;
667         else
668                 irq_type = &irq_type_iosapic_level;
669
670         idesc = irq_desc + vector;
671         if (idesc->chip != irq_type) {
672                 if (idesc->chip != &no_irq_type)
673                         printk(KERN_WARNING
674                                "%s: changing vector %d from %s to %s\n",
675                                __FUNCTION__, vector,
676                                idesc->chip->name, irq_type->name);
677                 idesc->chip = irq_type;
678         }
679         return 0;
680 }
681
682 static unsigned int
683 get_target_cpu (unsigned int gsi, int vector)
684 {
685 #ifdef CONFIG_SMP
686         static int cpu = -1;
687         extern int cpe_vector;
688
689         /*
690          * In case of vector shared by multiple RTEs, all RTEs that
691          * share the vector need to use the same destination CPU.
692          */
693         if (!list_empty(&iosapic_intr_info[vector].rtes))
694                 return iosapic_intr_info[vector].dest;
695
696         /*
697          * If the platform supports redirection via XTP, let it
698          * distribute interrupts.
699          */
700         if (smp_int_redirect & SMP_IRQ_REDIRECTION)
701                 return cpu_physical_id(smp_processor_id());
702
703         /*
704          * Some interrupts (ACPI SCI, for instance) are registered
705          * before the BSP is marked as online.
706          */
707         if (!cpu_online(smp_processor_id()))
708                 return cpu_physical_id(smp_processor_id());
709
710 #ifdef CONFIG_ACPI
711         if (cpe_vector > 0 && vector == IA64_CPEP_VECTOR)
712                 return get_cpei_target_cpu();
713 #endif
714
715 #ifdef CONFIG_NUMA
716         {
717                 int num_cpus, cpu_index, iosapic_index, numa_cpu, i = 0;
718                 cpumask_t cpu_mask;
719
720                 iosapic_index = find_iosapic(gsi);
721                 if (iosapic_index < 0 ||
722                     iosapic_lists[iosapic_index].node == MAX_NUMNODES)
723                         goto skip_numa_setup;
724
725                 cpu_mask = node_to_cpumask(iosapic_lists[iosapic_index].node);
726
727                 for_each_cpu_mask(numa_cpu, cpu_mask) {
728                         if (!cpu_online(numa_cpu))
729                                 cpu_clear(numa_cpu, cpu_mask);
730                 }
731
732                 num_cpus = cpus_weight(cpu_mask);
733
734                 if (!num_cpus)
735                         goto skip_numa_setup;
736
737                 /* Use vector assignment to distribute across cpus in node */
738                 cpu_index = vector % num_cpus;
739
740                 for (numa_cpu = first_cpu(cpu_mask) ; i < cpu_index ; i++)
741                         numa_cpu = next_cpu(numa_cpu, cpu_mask);
742
743                 if (numa_cpu != NR_CPUS)
744                         return cpu_physical_id(numa_cpu);
745         }
746 skip_numa_setup:
747 #endif
748         /*
749          * Otherwise, round-robin interrupt vectors across all the
750          * processors.  (It'd be nice if we could be smarter in the
751          * case of NUMA.)
752          */
753         do {
754                 if (++cpu >= NR_CPUS)
755                         cpu = 0;
756         } while (!cpu_online(cpu));
757
758         return cpu_physical_id(cpu);
759 #else  /* CONFIG_SMP */
760         return cpu_physical_id(smp_processor_id());
761 #endif
762 }
763
764 /*
765  * ACPI can describe IOSAPIC interrupts via static tables and namespace
766  * methods.  This provides an interface to register those interrupts and
767  * program the IOSAPIC RTE.
768  */
769 int
770 iosapic_register_intr (unsigned int gsi,
771                        unsigned long polarity, unsigned long trigger)
772 {
773         int vector, mask = 1, err;
774         unsigned int dest;
775         unsigned long flags;
776         struct iosapic_rte_info *rte;
777         u32 low32;
778 again:
779         /*
780          * If this GSI has already been registered (i.e., it's a
781          * shared interrupt, or we lost a race to register it),
782          * don't touch the RTE.
783          */
784         spin_lock_irqsave(&iosapic_lock, flags);
785         vector = gsi_to_vector(gsi);
786         if (vector > 0) {
787                 rte = gsi_vector_to_rte(gsi, vector);
788                 rte->refcnt++;
789                 spin_unlock_irqrestore(&iosapic_lock, flags);
790                 return vector;
791         }
792         spin_unlock_irqrestore(&iosapic_lock, flags);
793
794         /* If vector is running out, we try to find a sharable vector */
795         vector = assign_irq_vector(AUTO_ASSIGN);
796         if (vector < 0) {
797                 vector = iosapic_find_sharable_vector(trigger, polarity);
798                 if (vector < 0)
799                         return -ENOSPC;
800         }
801
802         spin_lock_irqsave(&irq_desc[vector].lock, flags);
803         spin_lock(&iosapic_lock);
804         if (gsi_to_vector(gsi) > 0) {
805                 if (list_empty(&iosapic_intr_info[vector].rtes))
806                         free_irq_vector(vector);
807                 spin_unlock(&iosapic_lock);
808                 spin_unlock_irqrestore(&irq_desc[vector].lock, flags);
809                 goto again;
810         }
811
812         dest = get_target_cpu(gsi, vector);
813         err = register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
814                             polarity, trigger);
815         if (err < 0) {
816                 spin_unlock(&iosapic_lock);
817                 spin_unlock_irqrestore(&irq_desc[vector].lock, flags);
818                 return err;
819         }
820
821         /*
822          * If the vector is shared and already unmasked for other
823          * interrupt sources, don't mask it.
824          */
825         low32 = iosapic_intr_info[vector].low32;
826         if (vector_is_shared(vector) && !(low32 & IOSAPIC_MASK))
827                 mask = 0;
828         set_rte(gsi, vector, dest, mask);
829         spin_unlock(&iosapic_lock);
830         spin_unlock_irqrestore(&irq_desc[vector].lock, flags);
831
832         printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n",
833                gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
834                (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
835                cpu_logical_id(dest), dest, vector);
836
837         return vector;
838 }
839
840 void
841 iosapic_unregister_intr (unsigned int gsi)
842 {
843         unsigned long flags;
844         int irq, vector, index;
845         irq_desc_t *idesc;
846         u32 low32;
847         unsigned long trigger, polarity;
848         unsigned int dest;
849         struct iosapic_rte_info *rte;
850
851         /*
852          * If the irq associated with the gsi is not found,
853          * iosapic_unregister_intr() is unbalanced. We need to check
854          * this again after getting locks.
855          */
856         irq = gsi_to_irq(gsi);
857         if (irq < 0) {
858                 printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n",
859                        gsi);
860                 WARN_ON(1);
861                 return;
862         }
863         vector = irq_to_vector(irq);
864
865         idesc = irq_desc + irq;
866         spin_lock_irqsave(&idesc->lock, flags);
867         spin_lock(&iosapic_lock);
868         if ((rte = gsi_vector_to_rte(gsi, vector)) == NULL) {
869                 printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n",
870                        gsi);
871                 WARN_ON(1);
872                 goto out;
873         }
874
875         if (--rte->refcnt > 0)
876                 goto out;
877
878         /* Mask the interrupt */
879         low32 = iosapic_intr_info[vector].low32 | IOSAPIC_MASK;
880         iosapic_write(rte->addr, IOSAPIC_RTE_LOW(rte->rte_index), low32);
881
882         /* Remove the rte entry from the list */
883         list_del(&rte->rte_list);
884         iosapic_intr_info[vector].count--;
885         iosapic_free_rte(rte);
886         index = find_iosapic(gsi);
887         iosapic_lists[index].rtes_inuse--;
888         WARN_ON(iosapic_lists[index].rtes_inuse < 0);
889
890         trigger  = iosapic_intr_info[vector].trigger;
891         polarity = iosapic_intr_info[vector].polarity;
892         dest     = iosapic_intr_info[vector].dest;
893         printk(KERN_INFO
894                "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d unregistered\n",
895                gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
896                (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
897                cpu_logical_id(dest), dest, vector);
898
899         if (list_empty(&iosapic_intr_info[vector].rtes)) {
900                 /* Sanity check */
901                 BUG_ON(iosapic_intr_info[vector].count);
902
903                 /* Clear the interrupt controller descriptor */
904                 idesc->chip = &no_irq_type;
905
906 #ifdef CONFIG_SMP
907                 /* Clear affinity */
908                 cpus_setall(idesc->affinity);
909 #endif
910
911                 /* Clear the interrupt information */
912                 memset(&iosapic_intr_info[vector], 0,
913                        sizeof(struct iosapic_intr_info));
914                 iosapic_intr_info[vector].low32 |= IOSAPIC_MASK;
915                 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes);
916
917                 if (idesc->action) {
918                         printk(KERN_ERR
919                                "interrupt handlers still exist on IRQ %u\n",
920                                irq);
921                         WARN_ON(1);
922                 }
923
924                 /* Free the interrupt vector */
925                 free_irq_vector(vector);
926         }
927  out:
928         spin_unlock(&iosapic_lock);
929         spin_unlock_irqrestore(&idesc->lock, flags);
930 }
931
932 /*
933  * ACPI calls this when it finds an entry for a platform interrupt.
934  */
935 int __init
936 iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
937                                 int iosapic_vector, u16 eid, u16 id,
938                                 unsigned long polarity, unsigned long trigger)
939 {
940         static const char * const name[] = {"unknown", "PMI", "INIT", "CPEI"};
941         unsigned char delivery;
942         int vector, mask = 0;
943         unsigned int dest = ((id << 8) | eid) & 0xffff;
944
945         switch (int_type) {
946               case ACPI_INTERRUPT_PMI:
947                 vector = iosapic_vector;
948                 /*
949                  * since PMI vector is alloc'd by FW(ACPI) not by kernel,
950                  * we need to make sure the vector is available
951                  */
952                 iosapic_reassign_vector(vector);
953                 delivery = IOSAPIC_PMI;
954                 break;
955               case ACPI_INTERRUPT_INIT:
956                 vector = assign_irq_vector(AUTO_ASSIGN);
957                 if (vector < 0)
958                         panic("%s: out of interrupt vectors!\n", __FUNCTION__);
959                 delivery = IOSAPIC_INIT;
960                 break;
961               case ACPI_INTERRUPT_CPEI:
962                 vector = IA64_CPE_VECTOR;
963                 delivery = IOSAPIC_LOWEST_PRIORITY;
964                 mask = 1;
965                 break;
966               default:
967                 printk(KERN_ERR "%s: invalid int type 0x%x\n", __FUNCTION__,
968                        int_type);
969                 return -1;
970         }
971
972         register_intr(gsi, vector, delivery, polarity, trigger);
973
974         printk(KERN_INFO
975                "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x)"
976                " vector %d\n",
977                int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown",
978                int_type, gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
979                (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
980                cpu_logical_id(dest), dest, vector);
981
982         set_rte(gsi, vector, dest, mask);
983         return vector;
984 }
985
986 /*
987  * ACPI calls this when it finds an entry for a legacy ISA IRQ override.
988  */
989 void __devinit
990 iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
991                           unsigned long polarity,
992                           unsigned long trigger)
993 {
994         int vector;
995         unsigned int dest = cpu_physical_id(smp_processor_id());
996
997         vector = isa_irq_to_vector(isa_irq);
998
999         register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger);
1000
1001         DBG("ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d\n",
1002             isa_irq, gsi, trigger == IOSAPIC_EDGE ? "edge" : "level",
1003             polarity == IOSAPIC_POL_HIGH ? "high" : "low",
1004             cpu_logical_id(dest), dest, vector);
1005
1006         set_rte(gsi, vector, dest, 1);
1007 }
1008
1009 void __init
1010 iosapic_system_init (int system_pcat_compat)
1011 {
1012         int vector;
1013
1014         for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) {
1015                 iosapic_intr_info[vector].low32 = IOSAPIC_MASK;
1016                 /* mark as unused */
1017                 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes);
1018         }
1019
1020         pcat_compat = system_pcat_compat;
1021         if (pcat_compat) {
1022                 /*
1023                  * Disable the compatibility mode interrupts (8259 style),
1024                  * needs IN/OUT support enabled.
1025                  */
1026                 printk(KERN_INFO
1027                        "%s: Disabling PC-AT compatible 8259 interrupts\n",
1028                        __FUNCTION__);
1029                 outb(0xff, 0xA1);
1030                 outb(0xff, 0x21);
1031         }
1032 }
1033
1034 static inline int
1035 iosapic_alloc (void)
1036 {
1037         int index;
1038
1039         for (index = 0; index < NR_IOSAPICS; index++)
1040                 if (!iosapic_lists[index].addr)
1041                         return index;
1042
1043         printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__);
1044         return -1;
1045 }
1046
1047 static inline void
1048 iosapic_free (int index)
1049 {
1050         memset(&iosapic_lists[index], 0, sizeof(iosapic_lists[0]));
1051 }
1052
1053 static inline int
1054 iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver)
1055 {
1056         int index;
1057         unsigned int gsi_end, base, end;
1058
1059         /* check gsi range */
1060         gsi_end = gsi_base + ((ver >> 16) & 0xff);
1061         for (index = 0; index < NR_IOSAPICS; index++) {
1062                 if (!iosapic_lists[index].addr)
1063                         continue;
1064
1065                 base = iosapic_lists[index].gsi_base;
1066                 end  = base + iosapic_lists[index].num_rte - 1;
1067
1068                 if (gsi_end < base || end < gsi_base)
1069                         continue; /* OK */
1070
1071                 return -EBUSY;
1072         }
1073         return 0;
1074 }
1075
1076 int __devinit
1077 iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
1078 {
1079         int num_rte, err, index;
1080         unsigned int isa_irq, ver;
1081         char __iomem *addr;
1082         unsigned long flags;
1083
1084         spin_lock_irqsave(&iosapic_lock, flags);
1085         addr = ioremap(phys_addr, 0);
1086         ver = iosapic_version(addr);
1087
1088         if ((err = iosapic_check_gsi_range(gsi_base, ver))) {
1089                 iounmap(addr);
1090                 spin_unlock_irqrestore(&iosapic_lock, flags);
1091                 return err;
1092         }
1093
1094         /*
1095          * The MAX_REDIR register holds the highest input pin number
1096          * (starting from 0).  We add 1 so that we can use it for
1097          * number of pins (= RTEs)
1098          */
1099         num_rte = ((ver >> 16) & 0xff) + 1;
1100
1101         index = iosapic_alloc();
1102         iosapic_lists[index].addr = addr;
1103         iosapic_lists[index].gsi_base = gsi_base;
1104         iosapic_lists[index].num_rte = num_rte;
1105 #ifdef CONFIG_NUMA
1106         iosapic_lists[index].node = MAX_NUMNODES;
1107 #endif
1108         spin_unlock_irqrestore(&iosapic_lock, flags);
1109
1110         if ((gsi_base == 0) && pcat_compat) {
1111                 /*
1112                  * Map the legacy ISA devices into the IOSAPIC data.  Some of
1113                  * these may get reprogrammed later on with data from the ACPI
1114                  * Interrupt Source Override table.
1115                  */
1116                 for (isa_irq = 0; isa_irq < 16; ++isa_irq)
1117                         iosapic_override_isa_irq(isa_irq, isa_irq,
1118                                                  IOSAPIC_POL_HIGH,
1119                                                  IOSAPIC_EDGE);
1120         }
1121         return 0;
1122 }
1123
1124 #ifdef CONFIG_HOTPLUG
1125 int
1126 iosapic_remove (unsigned int gsi_base)
1127 {
1128         int index, err = 0;
1129         unsigned long flags;
1130
1131         spin_lock_irqsave(&iosapic_lock, flags);
1132         index = find_iosapic(gsi_base);
1133         if (index < 0) {
1134                 printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n",
1135                        __FUNCTION__, gsi_base);
1136                 goto out;
1137         }
1138
1139         if (iosapic_lists[index].rtes_inuse) {
1140                 err = -EBUSY;
1141                 printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n",
1142                        __FUNCTION__, gsi_base);
1143                 goto out;
1144         }
1145
1146         iounmap(iosapic_lists[index].addr);
1147         iosapic_free(index);
1148  out:
1149         spin_unlock_irqrestore(&iosapic_lock, flags);
1150         return err;
1151 }
1152 #endif /* CONFIG_HOTPLUG */
1153
1154 #ifdef CONFIG_NUMA
1155 void __devinit
1156 map_iosapic_to_node(unsigned int gsi_base, int node)
1157 {
1158         int index;
1159
1160         index = find_iosapic(gsi_base);
1161         if (index < 0) {
1162                 printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n",
1163                        __FUNCTION__, gsi_base);
1164                 return;
1165         }
1166         iosapic_lists[index].node = node;
1167         return;
1168 }
1169 #endif
1170
1171 static int __init iosapic_enable_kmalloc (void)
1172 {
1173         iosapic_kmalloc_ok = 1;
1174         return 0;
1175 }
1176 core_initcall (iosapic_enable_kmalloc);