aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ia64/kernel/iosapic.c260
1 files changed, 161 insertions, 99 deletions
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 8832c553230a..22d845f85366 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -9,54 +9,65 @@
9 * Copyright (C) 1999 VA Linux Systems 9 * Copyright (C) 1999 VA Linux Systems
10 * Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com> 10 * Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
11 * 11 *
12 * 00/04/19 D. Mosberger Rewritten to mirror more closely the x86 I/O APIC code. 12 * 00/04/19 D. Mosberger Rewritten to mirror more closely the x86 I/O
13 * In particular, we now have separate handlers for edge 13 * APIC code. In particular, we now have separate
14 * and level triggered interrupts. 14 * handlers for edge and level triggered
15 * 00/10/27 Asit Mallick, Goutham Rao <goutham.rao@intel.com> IRQ vector allocation 15 * interrupts.
16 * PCI to vector mapping, shared PCI interrupts. 16 * 00/10/27 Asit Mallick, Goutham Rao <goutham.rao@intel.com> IRQ vector
17 * 00/10/27 D. Mosberger Document things a bit more to make them more understandable. 17 * allocation PCI to vector mapping, shared PCI
18 * Clean up much of the old IOSAPIC cruft. 18 * interrupts.
19 * 01/07/27 J.I. Lee PCI irq routing, Platform/Legacy interrupts and fixes for 19 * 00/10/27 D. Mosberger Document things a bit more to make them more
20 * ACPI S5(SoftOff) support. 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.
21 * 02/01/23 J.I. Lee iosapic pgm fixes for PCI irq routing from _PRT 24 * 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 25 * 02/01/07 E. Focht <efocht@ess.nec.de> Redirectable interrupt
23 * iosapic_set_affinity(), initializations for 26 * vectors in iosapic_set_affinity(),
24 * /proc/irq/#/smp_affinity 27 * initializations for /proc/irq/#/smp_affinity
25 * 02/04/02 P. Diefenbaugh Cleaned up ACPI PCI IRQ routing. 28 * 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 29 * 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 30 * 02/04/30 J.I. Lee bug fix in find_iosapic to fix ACPI PCI IRQ to
28 * error 31 * IOSAPIC mapping error
29 * 02/07/29 T. Kochi Allocate interrupt vectors dynamically 32 * 02/07/29 T. Kochi Allocate interrupt vectors dynamically
30 * 02/08/04 T. Kochi Cleaned up terminology (irq, global system interrupt, vector, etc.) 33 * 02/08/04 T. Kochi Cleaned up terminology (irq, global system
31 * 02/09/20 D. Mosberger Simplified by taking advantage of ACPI's pci_irq code. 34 * interrupt, vector, etc.)
35 * 02/09/20 D. Mosberger Simplified by taking advantage of ACPI's
36 * pci_irq code.
32 * 03/02/19 B. Helgaas Make pcat_compat system-wide, not per-IOSAPIC. 37 * 03/02/19 B. Helgaas Make pcat_compat system-wide, not per-IOSAPIC.
33 * Remove iosapic_address & gsi_base from external interfaces. 38 * Remove iosapic_address & gsi_base from
34 * Rationalize __init/__devinit attributes. 39 * external interfaces. Rationalize
40 * __init/__devinit attributes.
35 * 04/12/04 Ashok Raj <ashok.raj@intel.com> Intel Corporation 2004 41 * 04/12/04 Ashok Raj <ashok.raj@intel.com> Intel Corporation 2004
36 * Updated to work with irq migration necessary for CPU Hotplug 42 * Updated to work with irq migration necessary
43 * for CPU Hotplug
37 */ 44 */
38/* 45/*
39 * Here is what the interrupt logic between a PCI device and the kernel looks like: 46 * Here is what the interrupt logic between a PCI device and the kernel looks
47 * like:
40 * 48 *
41 * (1) A PCI device raises one of the four interrupt pins (INTA, INTB, INTC, INTD). The 49 * (1) A PCI device raises one of the four interrupt pins (INTA, INTB, INTC,
42 * device is uniquely identified by its bus--, and slot-number (the function 50 * INTD). The device is uniquely identified by its bus-, and slot-number
43 * number does not matter here because all functions share the same interrupt 51 * (the function number does not matter here because all functions share
44 * lines). 52 * the same interrupt lines).
45 * 53 *
46 * (2) The motherboard routes the interrupt line to a pin on a IOSAPIC controller. 54 * (2) The motherboard routes the interrupt line to a pin on a IOSAPIC
47 * Multiple interrupt lines may have to share the same IOSAPIC pin (if they're level 55 * controller. Multiple interrupt lines may have to share the same
48 * triggered and use the same polarity). Each interrupt line has a unique Global 56 * IOSAPIC pin (if they're level triggered and use the same polarity).
49 * System Interrupt (GSI) number which can be calculated as the sum of the controller's 57 * Each interrupt line has a unique Global System Interrupt (GSI) number
50 * base GSI number and the IOSAPIC pin number to which the line connects. 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.
51 * 60 *
52 * (3) The IOSAPIC uses an internal routing table entries (RTEs) to map the IOSAPIC pin 61 * (3) The IOSAPIC uses an internal routing table entries (RTEs) to map the
53 * into the IA-64 interrupt vector. This interrupt vector is then sent to the CPU. 62 * IOSAPIC pin into the IA-64 interrupt vector. This interrupt vector is then
63 * sent to the CPU.
54 * 64 *
55 * (4) The kernel recognizes an interrupt as an IRQ. The IRQ interface is used as 65 * (4) The kernel recognizes an interrupt as an IRQ. The IRQ interface is
56 * architecture-independent interrupt handling mechanism in Linux. As an 66 * used as architecture-independent interrupt handling mechanism in Linux.
57 * IRQ is a number, we have to have IA-64 interrupt vector number <-> IRQ number 67 * As an IRQ is a number, we have to have
58 * mapping. On smaller systems, we use one-to-one mapping between IA-64 vector and 68 * IA-64 interrupt vector number <-> IRQ number mapping. On smaller
59 * IRQ. A platform can implement platform_irq_to_vector(irq) and 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
60 * platform_local_vector_to_irq(vector) APIs to differentiate the mapping. 71 * platform_local_vector_to_irq(vector) APIs to differentiate the mapping.
61 * Please see also include/asm-ia64/hw_irq.h for those APIs. 72 * Please see also include/asm-ia64/hw_irq.h for those APIs.
62 * 73 *
@@ -64,9 +75,9 @@
64 * 75 *
65 * PCI pin -> global system interrupt (GSI) -> IA-64 vector <-> IRQ 76 * PCI pin -> global system interrupt (GSI) -> IA-64 vector <-> IRQ
66 * 77 *
67 * Note: The term "IRQ" is loosely used everywhere in Linux kernel to describe interrupts. 78 * Note: The term "IRQ" is loosely used everywhere in Linux kernel to
68 * Now we use "IRQ" only for Linux IRQ's. ISA IRQ (isa_irq) is the only exception in this 79 * describeinterrupts. Now we use "IRQ" only for Linux IRQ's. ISA IRQ
69 * source code. 80 * (isa_irq) is the only exception in this source code.
70 */ 81 */
71#include <linux/config.h> 82#include <linux/config.h>
72 83
@@ -90,7 +101,6 @@
90#include <asm/ptrace.h> 101#include <asm/ptrace.h>
91#include <asm/system.h> 102#include <asm/system.h>
92 103
93
94#undef DEBUG_INTERRUPT_ROUTING 104#undef DEBUG_INTERRUPT_ROUTING
95 105
96#ifdef DEBUG_INTERRUPT_ROUTING 106#ifdef DEBUG_INTERRUPT_ROUTING
@@ -99,36 +109,46 @@
99#define DBG(fmt...) 109#define DBG(fmt...)
100#endif 110#endif
101 111
102#define NR_PREALLOCATE_RTE_ENTRIES (PAGE_SIZE / sizeof(struct iosapic_rte_info)) 112#define NR_PREALLOCATE_RTE_ENTRIES \
113 (PAGE_SIZE / sizeof(struct iosapic_rte_info))
103#define RTE_PREALLOCATED (1) 114#define RTE_PREALLOCATED (1)
104 115
105static DEFINE_SPINLOCK(iosapic_lock); 116static DEFINE_SPINLOCK(iosapic_lock);
106 117
107/* These tables map IA-64 vectors to the IOSAPIC pin that generates this vector. */ 118/*
119 * These tables map IA-64 vectors to the IOSAPIC pin that generates this
120 * vector.
121 */
108 122
109struct iosapic_rte_info { 123struct iosapic_rte_info {
110 struct list_head rte_list; /* node in list of RTEs sharing the same vector */ 124 struct list_head rte_list; /* node in list of RTEs sharing the
125 * same vector */
111 char __iomem *addr; /* base address of IOSAPIC */ 126 char __iomem *addr; /* base address of IOSAPIC */
112 unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ 127 unsigned int gsi_base; /* first GSI assigned to this
128 * IOSAPIC */
113 char rte_index; /* IOSAPIC RTE index */ 129 char rte_index; /* IOSAPIC RTE index */
114 int refcnt; /* reference counter */ 130 int refcnt; /* reference counter */
115 unsigned int flags; /* flags */ 131 unsigned int flags; /* flags */
116} ____cacheline_aligned; 132} ____cacheline_aligned;
117 133
118static struct iosapic_intr_info { 134static struct iosapic_intr_info {
119 struct list_head rtes; /* RTEs using this vector (empty => not an IOSAPIC interrupt) */ 135 struct list_head rtes; /* RTEs using this vector (empty =>
136 * not an IOSAPIC interrupt) */
120 int count; /* # of RTEs that shares this vector */ 137 int count; /* # of RTEs that shares this vector */
121 u32 low32; /* current value of low word of Redirection table entry */ 138 u32 low32; /* current value of low word of
139 * Redirection table entry */
122 unsigned int dest; /* destination CPU physical ID */ 140 unsigned int dest; /* destination CPU physical ID */
123 unsigned char dmode : 3; /* delivery mode (see iosapic.h) */ 141 unsigned char dmode : 3; /* delivery mode (see iosapic.h) */
124 unsigned char polarity: 1; /* interrupt polarity (see iosapic.h) */ 142 unsigned char polarity: 1; /* interrupt polarity
143 * (see iosapic.h) */
125 unsigned char trigger : 1; /* trigger mode (see iosapic.h) */ 144 unsigned char trigger : 1; /* trigger mode (see iosapic.h) */
126} iosapic_intr_info[IA64_NUM_VECTORS]; 145} iosapic_intr_info[IA64_NUM_VECTORS];
127 146
128static struct iosapic { 147static struct iosapic {
129 char __iomem *addr; /* base address of IOSAPIC */ 148 char __iomem *addr; /* base address of IOSAPIC */
130 unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ 149 unsigned int gsi_base; /* first GSI assigned to this
131 unsigned short num_rte; /* number of RTE in this IOSAPIC */ 150 * IOSAPIC */
151 unsigned short num_rte; /* # of RTEs on this IOSAPIC */
132 int rtes_inuse; /* # of RTEs in use on this IOSAPIC */ 152 int rtes_inuse; /* # of RTEs in use on this IOSAPIC */
133#ifdef CONFIG_NUMA 153#ifdef CONFIG_NUMA
134 unsigned short node; /* numa node association via pxm */ 154 unsigned short node; /* numa node association via pxm */
@@ -149,7 +169,8 @@ find_iosapic (unsigned int gsi)
149 int i; 169 int i;
150 170
151 for (i = 0; i < NR_IOSAPICS; i++) { 171 for (i = 0; i < NR_IOSAPICS; i++) {
152 if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte) 172 if ((unsigned) (gsi - iosapic_lists[i].gsi_base) <
173 iosapic_lists[i].num_rte)
153 return i; 174 return i;
154 } 175 }
155 176
@@ -162,7 +183,8 @@ _gsi_to_vector (unsigned int gsi)
162 struct iosapic_intr_info *info; 183 struct iosapic_intr_info *info;
163 struct iosapic_rte_info *rte; 184 struct iosapic_rte_info *rte;
164 185
165 for (info = iosapic_intr_info; info < iosapic_intr_info + IA64_NUM_VECTORS; ++info) 186 for (info = iosapic_intr_info; info <
187 iosapic_intr_info + IA64_NUM_VECTORS; ++info)
166 list_for_each_entry(rte, &info->rtes, rte_list) 188 list_for_each_entry(rte, &info->rtes, rte_list)
167 if (rte->gsi_base + rte->rte_index == gsi) 189 if (rte->gsi_base + rte->rte_index == gsi)
168 return info - iosapic_intr_info; 190 return info - iosapic_intr_info;
@@ -185,8 +207,8 @@ gsi_to_irq (unsigned int gsi)
185 unsigned long flags; 207 unsigned long flags;
186 int irq; 208 int irq;
187 /* 209 /*
188 * XXX fix me: this assumes an identity mapping vetween IA-64 vector and Linux irq 210 * XXX fix me: this assumes an identity mapping between IA-64 vector
189 * numbers... 211 * and Linux irq numbers...
190 */ 212 */
191 spin_lock_irqsave(&iosapic_lock, flags); 213 spin_lock_irqsave(&iosapic_lock, flags);
192 { 214 {
@@ -197,7 +219,8 @@ gsi_to_irq (unsigned int gsi)
197 return irq; 219 return irq;
198} 220}
199 221
200static struct iosapic_rte_info *gsi_vector_to_rte(unsigned int gsi, unsigned int vec) 222static struct iosapic_rte_info *gsi_vector_to_rte(unsigned int gsi,
223 unsigned int vec)
201{ 224{
202 struct iosapic_rte_info *rte; 225 struct iosapic_rte_info *rte;
203 226
@@ -237,7 +260,9 @@ set_rte (unsigned int gsi, unsigned int vector, unsigned int dest, int mask)
237 260
238 for (irq = 0; irq < NR_IRQS; ++irq) 261 for (irq = 0; irq < NR_IRQS; ++irq)
239 if (irq_to_vector(irq) == vector) { 262 if (irq_to_vector(irq) == vector) {
240 set_irq_affinity_info(irq, (int)(dest & 0xffff), redir); 263 set_irq_affinity_info(irq,
264 (int)(dest & 0xffff),
265 redir);
241 break; 266 break;
242 } 267 }
243 } 268 }
@@ -259,7 +284,7 @@ set_rte (unsigned int gsi, unsigned int vector, unsigned int dest, int mask)
259} 284}
260 285
261static void 286static void
262nop (unsigned int vector) 287nop (unsigned int irq)
263{ 288{
264 /* do nothing... */ 289 /* do nothing... */
265} 290}
@@ -281,7 +306,8 @@ mask_irq (unsigned int irq)
281 { 306 {
282 /* set only the mask bit */ 307 /* set only the mask bit */
283 low32 = iosapic_intr_info[vec].low32 |= IOSAPIC_MASK; 308 low32 = iosapic_intr_info[vec].low32 |= IOSAPIC_MASK;
284 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { 309 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes,
310 rte_list) {
285 addr = rte->addr; 311 addr = rte->addr;
286 rte_index = rte->rte_index; 312 rte_index = rte->rte_index;
287 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); 313 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
@@ -306,7 +332,8 @@ unmask_irq (unsigned int irq)
306 spin_lock_irqsave(&iosapic_lock, flags); 332 spin_lock_irqsave(&iosapic_lock, flags);
307 { 333 {
308 low32 = iosapic_intr_info[vec].low32 &= ~IOSAPIC_MASK; 334 low32 = iosapic_intr_info[vec].low32 &= ~IOSAPIC_MASK;
309 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { 335 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes,
336 rte_list) {
310 addr = rte->addr; 337 addr = rte->addr;
311 rte_index = rte->rte_index; 338 rte_index = rte->rte_index;
312 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); 339 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
@@ -346,21 +373,25 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask)
346 373
347 spin_lock_irqsave(&iosapic_lock, flags); 374 spin_lock_irqsave(&iosapic_lock, flags);
348 { 375 {
349 low32 = iosapic_intr_info[vec].low32 & ~(7 << IOSAPIC_DELIVERY_SHIFT); 376 low32 = iosapic_intr_info[vec].low32 &
377 ~(7 << IOSAPIC_DELIVERY_SHIFT);
350 378
351 if (redir) 379 if (redir)
352 /* change delivery mode to lowest priority */ 380 /* change delivery mode to lowest priority */
353 low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT); 381 low32 |= (IOSAPIC_LOWEST_PRIORITY <<
382 IOSAPIC_DELIVERY_SHIFT);
354 else 383 else
355 /* change delivery mode to fixed */ 384 /* change delivery mode to fixed */
356 low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT); 385 low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT);
357 386
358 iosapic_intr_info[vec].low32 = low32; 387 iosapic_intr_info[vec].low32 = low32;
359 iosapic_intr_info[vec].dest = dest; 388 iosapic_intr_info[vec].dest = dest;
360 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { 389 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes,
390 rte_list) {
361 addr = rte->addr; 391 addr = rte->addr;
362 rte_index = rte->rte_index; 392 rte_index = rte->rte_index;
363 iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), high32); 393 iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index),
394 high32);
364 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); 395 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
365 } 396 }
366 } 397 }
@@ -433,7 +464,8 @@ iosapic_ack_edge_irq (unsigned int irq)
433 * interrupt for real. This prevents IRQ storms from unhandled 464 * interrupt for real. This prevents IRQ storms from unhandled
434 * devices. 465 * devices.
435 */ 466 */
436 if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) == (IRQ_PENDING|IRQ_DISABLED)) 467 if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) ==
468 (IRQ_PENDING|IRQ_DISABLED))
437 mask_irq(irq); 469 mask_irq(irq);
438} 470}
439 471
@@ -467,7 +499,8 @@ iosapic_version (char __iomem *addr)
467 return iosapic_read(addr, IOSAPIC_VERSION); 499 return iosapic_read(addr, IOSAPIC_VERSION);
468} 500}
469 501
470static int iosapic_find_sharable_vector (unsigned long trigger, unsigned long pol) 502static int iosapic_find_sharable_vector (unsigned long trigger,
503 unsigned long pol)
471{ 504{
472 int i, vector = -1, min_count = -1; 505 int i, vector = -1, min_count = -1;
473 struct iosapic_intr_info *info; 506 struct iosapic_intr_info *info;
@@ -482,7 +515,8 @@ static int iosapic_find_sharable_vector (unsigned long trigger, unsigned long po
482 for (i = IA64_FIRST_DEVICE_VECTOR; i <= IA64_LAST_DEVICE_VECTOR; i++) { 515 for (i = IA64_FIRST_DEVICE_VECTOR; i <= IA64_LAST_DEVICE_VECTOR; i++) {
483 info = &iosapic_intr_info[i]; 516 info = &iosapic_intr_info[i];
484 if (info->trigger == trigger && info->polarity == pol && 517 if (info->trigger == trigger && info->polarity == pol &&
485 (info->dmode == IOSAPIC_FIXED || info->dmode == IOSAPIC_LOWEST_PRIORITY)) { 518 (info->dmode == IOSAPIC_FIXED || info->dmode ==
519 IOSAPIC_LOWEST_PRIORITY)) {
486 if (min_count == -1 || info->count < min_count) { 520 if (min_count == -1 || info->count < min_count) {
487 vector = i; 521 vector = i;
488 min_count = info->count; 522 min_count = info->count;
@@ -506,12 +540,15 @@ iosapic_reassign_vector (int vector)
506 new_vector = assign_irq_vector(AUTO_ASSIGN); 540 new_vector = assign_irq_vector(AUTO_ASSIGN);
507 if (new_vector < 0) 541 if (new_vector < 0)
508 panic("%s: out of interrupt vectors!\n", __FUNCTION__); 542 panic("%s: out of interrupt vectors!\n", __FUNCTION__);
509 printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector); 543 printk(KERN_INFO "Reassigning vector %d to %d\n",
544 vector, new_vector);
510 memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector], 545 memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector],
511 sizeof(struct iosapic_intr_info)); 546 sizeof(struct iosapic_intr_info));
512 INIT_LIST_HEAD(&iosapic_intr_info[new_vector].rtes); 547 INIT_LIST_HEAD(&iosapic_intr_info[new_vector].rtes);
513 list_move(iosapic_intr_info[vector].rtes.next, &iosapic_intr_info[new_vector].rtes); 548 list_move(iosapic_intr_info[vector].rtes.next,
514 memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info)); 549 &iosapic_intr_info[new_vector].rtes);
550 memset(&iosapic_intr_info[vector], 0,
551 sizeof(struct iosapic_intr_info));
515 iosapic_intr_info[vector].low32 = IOSAPIC_MASK; 552 iosapic_intr_info[vector].low32 = IOSAPIC_MASK;
516 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); 553 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes);
517 } 554 }
@@ -524,7 +561,8 @@ static struct iosapic_rte_info *iosapic_alloc_rte (void)
524 int preallocated = 0; 561 int preallocated = 0;
525 562
526 if (!iosapic_kmalloc_ok && list_empty(&free_rte_list)) { 563 if (!iosapic_kmalloc_ok && list_empty(&free_rte_list)) {
527 rte = alloc_bootmem(sizeof(struct iosapic_rte_info) * NR_PREALLOCATE_RTE_ENTRIES); 564 rte = alloc_bootmem(sizeof(struct iosapic_rte_info) *
565 NR_PREALLOCATE_RTE_ENTRIES);
528 if (!rte) 566 if (!rte)
529 return NULL; 567 return NULL;
530 for (i = 0; i < NR_PREALLOCATE_RTE_ENTRIES; i++, rte++) 568 for (i = 0; i < NR_PREALLOCATE_RTE_ENTRIES; i++, rte++)
@@ -532,7 +570,8 @@ static struct iosapic_rte_info *iosapic_alloc_rte (void)
532 } 570 }
533 571
534 if (!list_empty(&free_rte_list)) { 572 if (!list_empty(&free_rte_list)) {
535 rte = list_entry(free_rte_list.next, struct iosapic_rte_info, rte_list); 573 rte = list_entry(free_rte_list.next, struct iosapic_rte_info,
574 rte_list);
536 list_del(&rte->rte_list); 575 list_del(&rte->rte_list);
537 preallocated++; 576 preallocated++;
538 } else { 577 } else {
@@ -575,7 +614,8 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
575 614
576 index = find_iosapic(gsi); 615 index = find_iosapic(gsi);
577 if (index < 0) { 616 if (index < 0) {
578 printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", __FUNCTION__, gsi); 617 printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n",
618 __FUNCTION__, gsi);
579 return -ENODEV; 619 return -ENODEV;
580 } 620 }
581 621
@@ -586,7 +626,8 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
586 if (!rte) { 626 if (!rte) {
587 rte = iosapic_alloc_rte(); 627 rte = iosapic_alloc_rte();
588 if (!rte) { 628 if (!rte) {
589 printk(KERN_WARNING "%s: cannot allocate memory\n", __FUNCTION__); 629 printk(KERN_WARNING "%s: cannot allocate memory\n",
630 __FUNCTION__);
590 return -ENOMEM; 631 return -ENOMEM;
591 } 632 }
592 633
@@ -602,7 +643,9 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
602 else if (vector_is_shared(vector)) { 643 else if (vector_is_shared(vector)) {
603 struct iosapic_intr_info *info = &iosapic_intr_info[vector]; 644 struct iosapic_intr_info *info = &iosapic_intr_info[vector];
604 if (info->trigger != trigger || info->polarity != polarity) { 645 if (info->trigger != trigger || info->polarity != polarity) {
605 printk (KERN_WARNING "%s: cannot override the interrupt\n", __FUNCTION__); 646 printk (KERN_WARNING
647 "%s: cannot override the interrupt\n",
648 __FUNCTION__);
606 return -EINVAL; 649 return -EINVAL;
607 } 650 }
608 } 651 }
@@ -619,8 +662,10 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
619 idesc = irq_descp(vector); 662 idesc = irq_descp(vector);
620 if (idesc->handler != irq_type) { 663 if (idesc->handler != irq_type) {
621 if (idesc->handler != &no_irq_type) 664 if (idesc->handler != &no_irq_type)
622 printk(KERN_WARNING "%s: changing vector %d from %s to %s\n", 665 printk(KERN_WARNING
623 __FUNCTION__, vector, idesc->handler->typename, irq_type->typename); 666 "%s: changing vector %d from %s to %s\n",
667 __FUNCTION__, vector,
668 idesc->handler->typename, irq_type->typename);
624 idesc->handler = irq_type; 669 idesc->handler = irq_type;
625 } 670 }
626 return 0; 671 return 0;
@@ -681,7 +726,7 @@ get_target_cpu (unsigned int gsi, int vector)
681 if (!num_cpus) 726 if (!num_cpus)
682 goto skip_numa_setup; 727 goto skip_numa_setup;
683 728
684 /* Use vector assigment to distribute across cpus in node */ 729 /* Use vector assignment to distribute across cpus in node */
685 cpu_index = vector % num_cpus; 730 cpu_index = vector % num_cpus;
686 731
687 for (numa_cpu = first_cpu(cpu_mask) ; i < cpu_index ; i++) 732 for (numa_cpu = first_cpu(cpu_mask) ; i < cpu_index ; i++)
@@ -703,7 +748,7 @@ skip_numa_setup:
703 } while (!cpu_online(cpu)); 748 } while (!cpu_online(cpu));
704 749
705 return cpu_physical_id(cpu); 750 return cpu_physical_id(cpu);
706#else 751#else /* CONFIG_SMP */
707 return cpu_physical_id(smp_processor_id()); 752 return cpu_physical_id(smp_processor_id());
708#endif 753#endif
709} 754}
@@ -755,7 +800,8 @@ again:
755 if (list_empty(&iosapic_intr_info[vector].rtes)) 800 if (list_empty(&iosapic_intr_info[vector].rtes))
756 free_irq_vector(vector); 801 free_irq_vector(vector);
757 spin_unlock(&iosapic_lock); 802 spin_unlock(&iosapic_lock);
758 spin_unlock_irqrestore(&irq_descp(vector)->lock, flags); 803 spin_unlock_irqrestore(&irq_descp(vector)->lock,
804 flags);
759 goto again; 805 goto again;
760 } 806 }
761 807
@@ -764,7 +810,8 @@ again:
764 polarity, trigger); 810 polarity, trigger);
765 if (err < 0) { 811 if (err < 0) {
766 spin_unlock(&iosapic_lock); 812 spin_unlock(&iosapic_lock);
767 spin_unlock_irqrestore(&irq_descp(vector)->lock, flags); 813 spin_unlock_irqrestore(&irq_descp(vector)->lock,
814 flags);
768 return err; 815 return err;
769 } 816 }
770 817
@@ -806,7 +853,8 @@ iosapic_unregister_intr (unsigned int gsi)
806 */ 853 */
807 irq = gsi_to_irq(gsi); 854 irq = gsi_to_irq(gsi);
808 if (irq < 0) { 855 if (irq < 0) {
809 printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", gsi); 856 printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n",
857 gsi);
810 WARN_ON(1); 858 WARN_ON(1);
811 return; 859 return;
812 } 860 }
@@ -817,7 +865,9 @@ iosapic_unregister_intr (unsigned int gsi)
817 spin_lock(&iosapic_lock); 865 spin_lock(&iosapic_lock);
818 { 866 {
819 if ((rte = gsi_vector_to_rte(gsi, vector)) == NULL) { 867 if ((rte = gsi_vector_to_rte(gsi, vector)) == NULL) {
820 printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", gsi); 868 printk(KERN_ERR
869 "iosapic_unregister_intr(%u) unbalanced\n",
870 gsi);
821 WARN_ON(1); 871 WARN_ON(1);
822 goto out; 872 goto out;
823 } 873 }
@@ -827,7 +877,8 @@ iosapic_unregister_intr (unsigned int gsi)
827 877
828 /* Mask the interrupt */ 878 /* Mask the interrupt */
829 low32 = iosapic_intr_info[vector].low32 | IOSAPIC_MASK; 879 low32 = iosapic_intr_info[vector].low32 | IOSAPIC_MASK;
830 iosapic_write(rte->addr, IOSAPIC_RTE_LOW(rte->rte_index), low32); 880 iosapic_write(rte->addr, IOSAPIC_RTE_LOW(rte->rte_index),
881 low32);
831 882
832 /* Remove the rte entry from the list */ 883 /* Remove the rte entry from the list */
833 list_del(&rte->rte_list); 884 list_del(&rte->rte_list);
@@ -840,7 +891,9 @@ iosapic_unregister_intr (unsigned int gsi)
840 trigger = iosapic_intr_info[vector].trigger; 891 trigger = iosapic_intr_info[vector].trigger;
841 polarity = iosapic_intr_info[vector].polarity; 892 polarity = iosapic_intr_info[vector].polarity;
842 dest = iosapic_intr_info[vector].dest; 893 dest = iosapic_intr_info[vector].dest;
843 printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d unregistered\n", 894 printk(KERN_INFO
895 "GSI %u (%s, %s) -> CPU %d (0x%04x)"
896 " vector %d unregistered\n",
844 gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), 897 gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
845 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), 898 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
846 cpu_logical_id(dest), dest, vector); 899 cpu_logical_id(dest), dest, vector);
@@ -853,12 +906,15 @@ iosapic_unregister_intr (unsigned int gsi)
853 idesc->handler = &no_irq_type; 906 idesc->handler = &no_irq_type;
854 907
855 /* Clear the interrupt information */ 908 /* Clear the interrupt information */
856 memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info)); 909 memset(&iosapic_intr_info[vector], 0,
910 sizeof(struct iosapic_intr_info));
857 iosapic_intr_info[vector].low32 |= IOSAPIC_MASK; 911 iosapic_intr_info[vector].low32 |= IOSAPIC_MASK;
858 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); 912 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes);
859 913
860 if (idesc->action) { 914 if (idesc->action) {
861 printk(KERN_ERR "interrupt handlers still exist on IRQ %u\n", irq); 915 printk(KERN_ERR
916 "interrupt handlers still exist on"
917 "IRQ %u\n", irq);
862 WARN_ON(1); 918 WARN_ON(1);
863 } 919 }
864 920
@@ -873,7 +929,6 @@ iosapic_unregister_intr (unsigned int gsi)
873 929
874/* 930/*
875 * ACPI calls this when it finds an entry for a platform interrupt. 931 * ACPI calls this when it finds an entry for a platform interrupt.
876 * Note that the irq_base and IOSAPIC address must be set in iosapic_init().
877 */ 932 */
878int __init 933int __init
879iosapic_register_platform_intr (u32 int_type, unsigned int gsi, 934iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
@@ -907,13 +962,16 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
907 mask = 1; 962 mask = 1;
908 break; 963 break;
909 default: 964 default:
910 printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type 0x%x\n", int_type); 965 printk(KERN_ERR "%s: invalid int type 0x%x\n", __FUNCTION__,
966 int_type);
911 return -1; 967 return -1;
912 } 968 }
913 969
914 register_intr(gsi, vector, delivery, polarity, trigger); 970 register_intr(gsi, vector, delivery, polarity, trigger);
915 971
916 printk(KERN_INFO "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n", 972 printk(KERN_INFO
973 "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x)"
974 " vector %d\n",
917 int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown", 975 int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown",
918 int_type, gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), 976 int_type, gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
919 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), 977 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
@@ -923,10 +981,8 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
923 return vector; 981 return vector;
924} 982}
925 983
926
927/* 984/*
928 * ACPI calls this when it finds an entry for a legacy ISA IRQ override. 985 * ACPI calls this when it finds an entry for a legacy ISA IRQ override.
929 * Note that the gsi_base and IOSAPIC address must be set in iosapic_init().
930 */ 986 */
931void __init 987void __init
932iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi, 988iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
@@ -955,16 +1011,19 @@ iosapic_system_init (int system_pcat_compat)
955 1011
956 for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) { 1012 for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) {
957 iosapic_intr_info[vector].low32 = IOSAPIC_MASK; 1013 iosapic_intr_info[vector].low32 = IOSAPIC_MASK;
958 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); /* mark as unused */ 1014 /* mark as unused */
1015 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes);
959 } 1016 }
960 1017
961 pcat_compat = system_pcat_compat; 1018 pcat_compat = system_pcat_compat;
962 if (pcat_compat) { 1019 if (pcat_compat) {
963 /* 1020 /*
964 * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support 1021 * Disable the compatibility mode interrupts (8259 style),
965 * enabled. 1022 * needs IN/OUT support enabled.
966 */ 1023 */
967 printk(KERN_INFO "%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__); 1024 printk(KERN_INFO
1025 "%s: Disabling PC-AT compatible 8259 interrupts\n",
1026 __FUNCTION__);
968 outb(0xff, 0xA1); 1027 outb(0xff, 0xA1);
969 outb(0xff, 0x21); 1028 outb(0xff, 0x21);
970 } 1029 }
@@ -1053,12 +1112,14 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
1053 1112
1054 if ((gsi_base == 0) && pcat_compat) { 1113 if ((gsi_base == 0) && pcat_compat) {
1055 /* 1114 /*
1056 * Map the legacy ISA devices into the IOSAPIC data. Some of these may 1115 * Map the legacy ISA devices into the IOSAPIC data. Some of
1057 * get reprogrammed later on with data from the ACPI Interrupt Source 1116 * these may get reprogrammed later on with data from the ACPI
1058 * Override table. 1117 * Interrupt Source Override table.
1059 */ 1118 */
1060 for (isa_irq = 0; isa_irq < 16; ++isa_irq) 1119 for (isa_irq = 0; isa_irq < 16; ++isa_irq)
1061 iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); 1120 iosapic_override_isa_irq(isa_irq, isa_irq,
1121 IOSAPIC_POL_HIGH,
1122 IOSAPIC_EDGE);
1062 } 1123 }
1063 return 0; 1124 return 0;
1064} 1125}
@@ -1081,7 +1142,8 @@ iosapic_remove (unsigned int gsi_base)
1081 1142
1082 if (iosapic_lists[index].rtes_inuse) { 1143 if (iosapic_lists[index].rtes_inuse) {
1083 err = -EBUSY; 1144 err = -EBUSY;
1084 printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n", 1145 printk(KERN_WARNING
1146 "%s: IOSAPIC for GSI base %u is busy\n",
1085 __FUNCTION__, gsi_base); 1147 __FUNCTION__, gsi_base);
1086 goto out; 1148 goto out;
1087 } 1149 }