diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-30 15:38:18 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-30 15:38:18 -0500 |
commit | d1127e40e8d75cd3855e35424937c73d0bcec558 (patch) | |
tree | 093f020e971827c63d3eed1d646022c581ded2ea | |
parent | 5abc97aa25b2c41413b3a520faee83f2282d9f18 (diff) | |
parent | c1c57d767100417f63c18da52d7e96f82b2b9e1a (diff) |
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6:
[IA64] ioremap() should prefer WB over UC
[IA64] Add __mca_table to the DISCARD list in gate.lds
[IA64] Move __mca_table out of the __init section
[IA64] simplify some condition checks in iosapic_check_gsi_range
[IA64] correct some messages and fixes some minor things
[IA64-SGI] fix for-loop in sn_hwperf_geoid_to_cnode()
[IA64-SGI] sn_hwperf use of num_online_cpus()
[IA64] optimize flush_tlb_range on large numa box
[IA64] lazy_mmu_prot_update needs to be aware of huge pages
-rw-r--r-- | arch/ia64/kernel/gate.lds.S | 1 | ||||
-rw-r--r-- | arch/ia64/kernel/iosapic.c | 265 | ||||
-rw-r--r-- | arch/ia64/kernel/vmlinux.lds.S | 18 | ||||
-rw-r--r-- | arch/ia64/mm/init.c | 8 | ||||
-rw-r--r-- | arch/ia64/mm/ioremap.c | 6 | ||||
-rw-r--r-- | arch/ia64/mm/tlb.c | 12 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/sn2/sn_hwperf.c | 8 | ||||
-rw-r--r-- | include/asm-ia64/asmmacro.h | 4 |
8 files changed, 199 insertions, 123 deletions
diff --git a/arch/ia64/kernel/gate.lds.S b/arch/ia64/kernel/gate.lds.S index e1e4aba9ecd0..7c99e6ec3daf 100644 --- a/arch/ia64/kernel/gate.lds.S +++ b/arch/ia64/kernel/gate.lds.S | |||
@@ -59,6 +59,7 @@ SECTIONS | |||
59 | *(.dynbss) | 59 | *(.dynbss) |
60 | *(.bss .bss.* .gnu.linkonce.b.*) | 60 | *(.bss .bss.* .gnu.linkonce.b.*) |
61 | *(__ex_table) | 61 | *(__ex_table) |
62 | *(__mca_table) | ||
62 | } | 63 | } |
63 | } | 64 | } |
64 | 65 | ||
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 8832c553230a..7956eb9058fc 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 | ||
105 | static DEFINE_SPINLOCK(iosapic_lock); | 116 | static 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 | ||
109 | struct iosapic_rte_info { | 123 | struct 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 | ||
118 | static struct iosapic_intr_info { | 134 | static 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 | ||
128 | static struct iosapic { | 147 | static 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 | ||
200 | static struct iosapic_rte_info *gsi_vector_to_rte(unsigned int gsi, unsigned int vec) | 222 | static 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 | ||
261 | static void | 286 | static void |
262 | nop (unsigned int vector) | 287 | nop (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 | ||
470 | static int iosapic_find_sharable_vector (unsigned long trigger, unsigned long pol) | 502 | static 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 | */ |
878 | int __init | 933 | int __init |
879 | iosapic_register_platform_intr (u32 int_type, unsigned int gsi, | 934 | iosapic_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 | */ |
931 | void __init | 987 | void __init |
932 | iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi, | 988 | iosapic_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 | } |
@@ -1004,10 +1063,7 @@ iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver) | |||
1004 | base = iosapic_lists[index].gsi_base; | 1063 | base = iosapic_lists[index].gsi_base; |
1005 | end = base + iosapic_lists[index].num_rte - 1; | 1064 | end = base + iosapic_lists[index].num_rte - 1; |
1006 | 1065 | ||
1007 | if (gsi_base < base && gsi_end < base) | 1066 | if (gsi_end < base || end < gsi_base) |
1008 | continue;/* OK */ | ||
1009 | |||
1010 | if (gsi_base > end && gsi_end > end) | ||
1011 | continue; /* OK */ | 1067 | continue; /* OK */ |
1012 | 1068 | ||
1013 | return -EBUSY; | 1069 | return -EBUSY; |
@@ -1053,12 +1109,14 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base) | |||
1053 | 1109 | ||
1054 | if ((gsi_base == 0) && pcat_compat) { | 1110 | if ((gsi_base == 0) && pcat_compat) { |
1055 | /* | 1111 | /* |
1056 | * Map the legacy ISA devices into the IOSAPIC data. Some of these may | 1112 | * Map the legacy ISA devices into the IOSAPIC data. Some of |
1057 | * get reprogrammed later on with data from the ACPI Interrupt Source | 1113 | * these may get reprogrammed later on with data from the ACPI |
1058 | * Override table. | 1114 | * Interrupt Source Override table. |
1059 | */ | 1115 | */ |
1060 | for (isa_irq = 0; isa_irq < 16; ++isa_irq) | 1116 | for (isa_irq = 0; isa_irq < 16; ++isa_irq) |
1061 | iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); | 1117 | iosapic_override_isa_irq(isa_irq, isa_irq, |
1118 | IOSAPIC_POL_HIGH, | ||
1119 | IOSAPIC_EDGE); | ||
1062 | } | 1120 | } |
1063 | return 0; | 1121 | return 0; |
1064 | } | 1122 | } |
@@ -1081,7 +1139,8 @@ iosapic_remove (unsigned int gsi_base) | |||
1081 | 1139 | ||
1082 | if (iosapic_lists[index].rtes_inuse) { | 1140 | if (iosapic_lists[index].rtes_inuse) { |
1083 | err = -EBUSY; | 1141 | err = -EBUSY; |
1084 | printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n", | 1142 | printk(KERN_WARNING |
1143 | "%s: IOSAPIC for GSI base %u is busy\n", | ||
1085 | __FUNCTION__, gsi_base); | 1144 | __FUNCTION__, gsi_base); |
1086 | goto out; | 1145 | goto out; |
1087 | } | 1146 | } |
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index 0b9e56dd7f05..783600fe52b2 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S | |||
@@ -70,6 +70,15 @@ SECTIONS | |||
70 | __stop___ex_table = .; | 70 | __stop___ex_table = .; |
71 | } | 71 | } |
72 | 72 | ||
73 | /* MCA table */ | ||
74 | . = ALIGN(16); | ||
75 | __mca_table : AT(ADDR(__mca_table) - LOAD_OFFSET) | ||
76 | { | ||
77 | __start___mca_table = .; | ||
78 | *(__mca_table) | ||
79 | __stop___mca_table = .; | ||
80 | } | ||
81 | |||
73 | /* Global data */ | 82 | /* Global data */ |
74 | _data = .; | 83 | _data = .; |
75 | 84 | ||
@@ -130,15 +139,6 @@ SECTIONS | |||
130 | __initcall_end = .; | 139 | __initcall_end = .; |
131 | } | 140 | } |
132 | 141 | ||
133 | /* MCA table */ | ||
134 | . = ALIGN(16); | ||
135 | __mca_table : AT(ADDR(__mca_table) - LOAD_OFFSET) | ||
136 | { | ||
137 | __start___mca_table = .; | ||
138 | *(__mca_table) | ||
139 | __stop___mca_table = .; | ||
140 | } | ||
141 | |||
142 | .data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET) | 142 | .data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET) |
143 | { | 143 | { |
144 | __start___vtop_patchlist = .; | 144 | __start___vtop_patchlist = .; |
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 2ef1151cde90..cafa8776a53d 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c | |||
@@ -109,6 +109,7 @@ lazy_mmu_prot_update (pte_t pte) | |||
109 | { | 109 | { |
110 | unsigned long addr; | 110 | unsigned long addr; |
111 | struct page *page; | 111 | struct page *page; |
112 | unsigned long order; | ||
112 | 113 | ||
113 | if (!pte_exec(pte)) | 114 | if (!pte_exec(pte)) |
114 | return; /* not an executable page... */ | 115 | return; /* not an executable page... */ |
@@ -119,7 +120,12 @@ lazy_mmu_prot_update (pte_t pte) | |||
119 | if (test_bit(PG_arch_1, &page->flags)) | 120 | if (test_bit(PG_arch_1, &page->flags)) |
120 | return; /* i-cache is already coherent with d-cache */ | 121 | return; /* i-cache is already coherent with d-cache */ |
121 | 122 | ||
122 | flush_icache_range(addr, addr + PAGE_SIZE); | 123 | if (PageCompound(page)) { |
124 | order = (unsigned long) (page[1].lru.prev); | ||
125 | flush_icache_range(addr, addr + (1UL << order << PAGE_SHIFT)); | ||
126 | } | ||
127 | else | ||
128 | flush_icache_range(addr, addr + PAGE_SIZE); | ||
123 | set_bit(PG_arch_1, &page->flags); /* mark page as clean */ | 129 | set_bit(PG_arch_1, &page->flags); /* mark page as clean */ |
124 | } | 130 | } |
125 | 131 | ||
diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c index 62328621f99c..643ccc6960ce 100644 --- a/arch/ia64/mm/ioremap.c +++ b/arch/ia64/mm/ioremap.c | |||
@@ -21,12 +21,12 @@ __ioremap (unsigned long offset, unsigned long size) | |||
21 | void __iomem * | 21 | void __iomem * |
22 | ioremap (unsigned long offset, unsigned long size) | 22 | ioremap (unsigned long offset, unsigned long size) |
23 | { | 23 | { |
24 | if (efi_mem_attribute_range(offset, size, EFI_MEMORY_UC)) | ||
25 | return __ioremap(offset, size); | ||
26 | |||
27 | if (efi_mem_attribute_range(offset, size, EFI_MEMORY_WB)) | 24 | if (efi_mem_attribute_range(offset, size, EFI_MEMORY_WB)) |
28 | return phys_to_virt(offset); | 25 | return phys_to_virt(offset); |
29 | 26 | ||
27 | if (efi_mem_attribute_range(offset, size, EFI_MEMORY_UC)) | ||
28 | return __ioremap(offset, size); | ||
29 | |||
30 | /* | 30 | /* |
31 | * Someday this should check ACPI resources so we | 31 | * Someday this should check ACPI resources so we |
32 | * can do the right thing for hot-plugged regions. | 32 | * can do the right thing for hot-plugged regions. |
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index 6a4eec9113e8..4dbbca0b5e9c 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c | |||
@@ -156,17 +156,19 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, | |||
156 | nbits = purge.max_bits; | 156 | nbits = purge.max_bits; |
157 | start &= ~((1UL << nbits) - 1); | 157 | start &= ~((1UL << nbits) - 1); |
158 | 158 | ||
159 | # ifdef CONFIG_SMP | ||
160 | platform_global_tlb_purge(mm, start, end, nbits); | ||
161 | # else | ||
162 | preempt_disable(); | 159 | preempt_disable(); |
160 | #ifdef CONFIG_SMP | ||
161 | if (mm != current->active_mm || cpus_weight(mm->cpu_vm_mask) != 1) { | ||
162 | platform_global_tlb_purge(mm, start, end, nbits); | ||
163 | preempt_enable(); | ||
164 | return; | ||
165 | } | ||
166 | #endif | ||
163 | do { | 167 | do { |
164 | ia64_ptcl(start, (nbits<<2)); | 168 | ia64_ptcl(start, (nbits<<2)); |
165 | start += (1UL << nbits); | 169 | start += (1UL << nbits); |
166 | } while (start < end); | 170 | } while (start < end); |
167 | preempt_enable(); | 171 | preempt_enable(); |
168 | # endif | ||
169 | |||
170 | ia64_srlz_i(); /* srlz.i implies srlz.d */ | 172 | ia64_srlz_i(); /* srlz.i implies srlz.d */ |
171 | } | 173 | } |
172 | EXPORT_SYMBOL(flush_tlb_range); | 174 | EXPORT_SYMBOL(flush_tlb_range); |
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 70db21f3df21..d917afa30b27 100644 --- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c | |||
@@ -110,7 +110,11 @@ static int sn_hwperf_geoid_to_cnode(char *location) | |||
110 | if (sn_hwperf_location_to_bpos(location, &rack, &bay, &slot, &slab)) | 110 | if (sn_hwperf_location_to_bpos(location, &rack, &bay, &slot, &slab)) |
111 | return -1; | 111 | return -1; |
112 | 112 | ||
113 | for_each_node(cnode) { | 113 | /* |
114 | * FIXME: replace with cleaner for_each_XXX macro which addresses | ||
115 | * both compute and IO nodes once ACPI3.0 is available. | ||
116 | */ | ||
117 | for (cnode = 0; cnode < num_cnodes; cnode++) { | ||
114 | geoid = cnodeid_get_geoid(cnode); | 118 | geoid = cnodeid_get_geoid(cnode); |
115 | module_id = geo_module(geoid); | 119 | module_id = geo_module(geoid); |
116 | this_rack = MODULE_GET_RACK(module_id); | 120 | this_rack = MODULE_GET_RACK(module_id); |
@@ -605,7 +609,7 @@ static int sn_hwperf_op_cpu(struct sn_hwperf_op_info *op_info) | |||
605 | op_info->a->arg &= SN_HWPERF_ARG_OBJID_MASK; | 609 | op_info->a->arg &= SN_HWPERF_ARG_OBJID_MASK; |
606 | 610 | ||
607 | if (cpu != SN_HWPERF_ARG_ANY_CPU) { | 611 | if (cpu != SN_HWPERF_ARG_ANY_CPU) { |
608 | if (cpu >= num_online_cpus() || !cpu_online(cpu)) { | 612 | if (cpu >= NR_CPUS || !cpu_online(cpu)) { |
609 | r = -EINVAL; | 613 | r = -EINVAL; |
610 | goto out; | 614 | goto out; |
611 | } | 615 | } |
diff --git a/include/asm-ia64/asmmacro.h b/include/asm-ia64/asmmacro.h index d4cec32083d8..edf2cebb2969 100644 --- a/include/asm-ia64/asmmacro.h +++ b/include/asm-ia64/asmmacro.h | |||
@@ -38,6 +38,10 @@ name: | |||
38 | 38 | ||
39 | /* | 39 | /* |
40 | * Helper macros for accessing user memory. | 40 | * Helper macros for accessing user memory. |
41 | * | ||
42 | * When adding any new .section/.previous entries here, make sure to | ||
43 | * also add it to the DISCARD section in arch/ia64/kernel/gate.lds.S or | ||
44 | * unpleasant things will happen. | ||
41 | */ | 45 | */ |
42 | 46 | ||
43 | .section "__ex_table", "a" // declare section & section attributes | 47 | .section "__ex_table", "a" // declare section & section attributes |