ia64/xen-unstable

view linux-2.6-xen-sparse/arch/ia64/kernel/iosapic.c @ 9896:42a8e3101c6c

Define new event-channel and physdev hypercalls with a more extensible
interface (the legacy hypercalls would break if subcommands with large
argument structures were added, as it would grow the size of the
union of all argument structures).

Also, based on a patch from Kevin Tian, add a new physdev op to
signal EOI for a particular irq.

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