aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/kernel/entry.S1
-rw-r--r--arch/ia64/kernel/gate.lds.S1
-rw-r--r--arch/ia64/kernel/iosapic.c265
-rw-r--r--arch/ia64/kernel/palinfo.c8
-rw-r--r--arch/ia64/kernel/time.c2
-rw-r--r--arch/ia64/kernel/topology.c367
-rw-r--r--arch/ia64/kernel/vmlinux.lds.S18
-rw-r--r--arch/ia64/mm/init.c8
-rw-r--r--arch/ia64/mm/ioremap.c6
-rw-r--r--arch/ia64/mm/tlb.c12
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_hwperf.c8
11 files changed, 568 insertions, 128 deletions
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 0e3eda99e549..750e8e7fbdc3 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1605,5 +1605,6 @@ sys_call_table:
1605 data8 sys_ni_syscall // reserved for pselect 1605 data8 sys_ni_syscall // reserved for pselect
1606 data8 sys_ni_syscall // 1295 reserved for ppoll 1606 data8 sys_ni_syscall // 1295 reserved for ppoll
1607 data8 sys_unshare 1607 data8 sys_unshare
1608 data8 sys_splice
1608 1609
1609 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls 1610 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
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
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 }
@@ -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/palinfo.c b/arch/ia64/kernel/palinfo.c
index 89faa603c6be..6386f63c413e 100644
--- a/arch/ia64/kernel/palinfo.c
+++ b/arch/ia64/kernel/palinfo.c
@@ -240,7 +240,7 @@ cache_info(char *page)
240 } 240 }
241 p += sprintf(p, 241 p += sprintf(p,
242 "%s Cache level %lu:\n" 242 "%s Cache level %lu:\n"
243 "\tSize : %lu bytes\n" 243 "\tSize : %u bytes\n"
244 "\tAttributes : ", 244 "\tAttributes : ",
245 cache_types[j+cci.pcci_unified], i+1, 245 cache_types[j+cci.pcci_unified], i+1,
246 cci.pcci_cache_size); 246 cci.pcci_cache_size);
@@ -648,9 +648,9 @@ frequency_info(char *page)
648 if (ia64_pal_freq_ratios(&proc, &bus, &itc) != 0) return 0; 648 if (ia64_pal_freq_ratios(&proc, &bus, &itc) != 0) return 0;
649 649
650 p += sprintf(p, 650 p += sprintf(p,
651 "Processor/Clock ratio : %ld/%ld\n" 651 "Processor/Clock ratio : %d/%d\n"
652 "Bus/Clock ratio : %ld/%ld\n" 652 "Bus/Clock ratio : %d/%d\n"
653 "ITC/Clock ratio : %ld/%ld\n", 653 "ITC/Clock ratio : %d/%d\n",
654 proc.num, proc.den, bus.num, bus.den, itc.num, itc.den); 654 proc.num, proc.den, bus.num, bus.den, itc.num, itc.den);
655 655
656 return p - page; 656 return p - page;
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index ac167436e936..49958904045b 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -188,7 +188,7 @@ ia64_init_itm (void)
188 itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den; 188 itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den;
189 189
190 local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ; 190 local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ;
191 printk(KERN_DEBUG "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, " 191 printk(KERN_DEBUG "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%u/%u, "
192 "ITC freq=%lu.%03luMHz", smp_processor_id(), 192 "ITC freq=%lu.%03luMHz", smp_processor_id(),
193 platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000, 193 platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000,
194 itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000); 194 itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000);
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
index 3b6fd798c4d6..b47476d655f1 100644
--- a/arch/ia64/kernel/topology.c
+++ b/arch/ia64/kernel/topology.c
@@ -9,6 +9,8 @@
9 * 2002/08/07 Erich Focht <efocht@ess.nec.de> 9 * 2002/08/07 Erich Focht <efocht@ess.nec.de>
10 * Populate cpu entries in sysfs for non-numa systems as well 10 * Populate cpu entries in sysfs for non-numa systems as well
11 * Intel Corporation - Ashok Raj 11 * Intel Corporation - Ashok Raj
12 * 02/27/2006 Zhang, Yanmin
13 * Populate cpu cache entries in sysfs for cpu cache info
12 */ 14 */
13 15
14#include <linux/config.h> 16#include <linux/config.h>
@@ -19,6 +21,7 @@
19#include <linux/init.h> 21#include <linux/init.h>
20#include <linux/bootmem.h> 22#include <linux/bootmem.h>
21#include <linux/nodemask.h> 23#include <linux/nodemask.h>
24#include <linux/notifier.h>
22#include <asm/mmzone.h> 25#include <asm/mmzone.h>
23#include <asm/numa.h> 26#include <asm/numa.h>
24#include <asm/cpu.h> 27#include <asm/cpu.h>
@@ -101,3 +104,367 @@ out:
101} 104}
102 105
103subsys_initcall(topology_init); 106subsys_initcall(topology_init);
107
108
109/*
110 * Export cpu cache information through sysfs
111 */
112
113/*
114 * A bunch of string array to get pretty printing
115 */
116static const char *cache_types[] = {
117 "", /* not used */
118 "Instruction",
119 "Data",
120 "Unified" /* unified */
121};
122
123static const char *cache_mattrib[]={
124 "WriteThrough",
125 "WriteBack",
126 "", /* reserved */
127 "" /* reserved */
128};
129
130struct cache_info {
131 pal_cache_config_info_t cci;
132 cpumask_t shared_cpu_map;
133 int level;
134 int type;
135 struct kobject kobj;
136};
137
138struct cpu_cache_info {
139 struct cache_info *cache_leaves;
140 int num_cache_leaves;
141 struct kobject kobj;
142};
143
144static struct cpu_cache_info all_cpu_cache_info[NR_CPUS];
145#define LEAF_KOBJECT_PTR(x,y) (&all_cpu_cache_info[x].cache_leaves[y])
146
147#ifdef CONFIG_SMP
148static void cache_shared_cpu_map_setup( unsigned int cpu,
149 struct cache_info * this_leaf)
150{
151 pal_cache_shared_info_t csi;
152 int num_shared, i = 0;
153 unsigned int j;
154
155 if (cpu_data(cpu)->threads_per_core <= 1 &&
156 cpu_data(cpu)->cores_per_socket <= 1) {
157 cpu_set(cpu, this_leaf->shared_cpu_map);
158 return;
159 }
160
161 if (ia64_pal_cache_shared_info(this_leaf->level,
162 this_leaf->type,
163 0,
164 &csi) != PAL_STATUS_SUCCESS)
165 return;
166
167 num_shared = (int) csi.num_shared;
168 do {
169 for_each_cpu(j)
170 if (cpu_data(cpu)->socket_id == cpu_data(j)->socket_id
171 && cpu_data(j)->core_id == csi.log1_cid
172 && cpu_data(j)->thread_id == csi.log1_tid)
173 cpu_set(j, this_leaf->shared_cpu_map);
174
175 i++;
176 } while (i < num_shared &&
177 ia64_pal_cache_shared_info(this_leaf->level,
178 this_leaf->type,
179 i,
180 &csi) == PAL_STATUS_SUCCESS);
181}
182#else
183static void cache_shared_cpu_map_setup(unsigned int cpu,
184 struct cache_info * this_leaf)
185{
186 cpu_set(cpu, this_leaf->shared_cpu_map);
187 return;
188}
189#endif
190
191static ssize_t show_coherency_line_size(struct cache_info *this_leaf,
192 char *buf)
193{
194 return sprintf(buf, "%u\n", 1 << this_leaf->cci.pcci_line_size);
195}
196
197static ssize_t show_ways_of_associativity(struct cache_info *this_leaf,
198 char *buf)
199{
200 return sprintf(buf, "%u\n", this_leaf->cci.pcci_assoc);
201}
202
203static ssize_t show_attributes(struct cache_info *this_leaf, char *buf)
204{
205 return sprintf(buf,
206 "%s\n",
207 cache_mattrib[this_leaf->cci.pcci_cache_attr]);
208}
209
210static ssize_t show_size(struct cache_info *this_leaf, char *buf)
211{
212 return sprintf(buf, "%uK\n", this_leaf->cci.pcci_cache_size / 1024);
213}
214
215static ssize_t show_number_of_sets(struct cache_info *this_leaf, char *buf)
216{
217 unsigned number_of_sets = this_leaf->cci.pcci_cache_size;
218 number_of_sets /= this_leaf->cci.pcci_assoc;
219 number_of_sets /= 1 << this_leaf->cci.pcci_line_size;
220
221 return sprintf(buf, "%u\n", number_of_sets);
222}
223
224static ssize_t show_shared_cpu_map(struct cache_info *this_leaf, char *buf)
225{
226 ssize_t len;
227 cpumask_t shared_cpu_map;
228
229 cpus_and(shared_cpu_map, this_leaf->shared_cpu_map, cpu_online_map);
230 len = cpumask_scnprintf(buf, NR_CPUS+1, shared_cpu_map);
231 len += sprintf(buf+len, "\n");
232 return len;
233}
234
235static ssize_t show_type(struct cache_info *this_leaf, char *buf)
236{
237 int type = this_leaf->type + this_leaf->cci.pcci_unified;
238 return sprintf(buf, "%s\n", cache_types[type]);
239}
240
241static ssize_t show_level(struct cache_info *this_leaf, char *buf)
242{
243 return sprintf(buf, "%u\n", this_leaf->level);
244}
245
246struct cache_attr {
247 struct attribute attr;
248 ssize_t (*show)(struct cache_info *, char *);
249 ssize_t (*store)(struct cache_info *, const char *, size_t count);
250};
251
252#ifdef define_one_ro
253 #undef define_one_ro
254#endif
255#define define_one_ro(_name) \
256 static struct cache_attr _name = \
257__ATTR(_name, 0444, show_##_name, NULL)
258
259define_one_ro(level);
260define_one_ro(type);
261define_one_ro(coherency_line_size);
262define_one_ro(ways_of_associativity);
263define_one_ro(size);
264define_one_ro(number_of_sets);
265define_one_ro(shared_cpu_map);
266define_one_ro(attributes);
267
268static struct attribute * cache_default_attrs[] = {
269 &type.attr,
270 &level.attr,
271 &coherency_line_size.attr,
272 &ways_of_associativity.attr,
273 &attributes.attr,
274 &size.attr,
275 &number_of_sets.attr,
276 &shared_cpu_map.attr,
277 NULL
278};
279
280#define to_object(k) container_of(k, struct cache_info, kobj)
281#define to_attr(a) container_of(a, struct cache_attr, attr)
282
283static ssize_t cache_show(struct kobject * kobj, struct attribute * attr, char * buf)
284{
285 struct cache_attr *fattr = to_attr(attr);
286 struct cache_info *this_leaf = to_object(kobj);
287 ssize_t ret;
288
289 ret = fattr->show ? fattr->show(this_leaf, buf) : 0;
290 return ret;
291}
292
293static struct sysfs_ops cache_sysfs_ops = {
294 .show = cache_show
295};
296
297static struct kobj_type cache_ktype = {
298 .sysfs_ops = &cache_sysfs_ops,
299 .default_attrs = cache_default_attrs,
300};
301
302static struct kobj_type cache_ktype_percpu_entry = {
303 .sysfs_ops = &cache_sysfs_ops,
304};
305
306static void __cpuinit cpu_cache_sysfs_exit(unsigned int cpu)
307{
308 if (all_cpu_cache_info[cpu].cache_leaves) {
309 kfree(all_cpu_cache_info[cpu].cache_leaves);
310 all_cpu_cache_info[cpu].cache_leaves = NULL;
311 }
312 all_cpu_cache_info[cpu].num_cache_leaves = 0;
313 memset(&all_cpu_cache_info[cpu].kobj, 0, sizeof(struct kobject));
314
315 return;
316}
317
318static int __cpuinit cpu_cache_sysfs_init(unsigned int cpu)
319{
320 u64 i, levels, unique_caches;
321 pal_cache_config_info_t cci;
322 int j;
323 s64 status;
324 struct cache_info *this_cache;
325 int num_cache_leaves = 0;
326
327 if ((status = ia64_pal_cache_summary(&levels, &unique_caches)) != 0) {
328 printk(KERN_ERR "ia64_pal_cache_summary=%ld\n", status);
329 return -1;
330 }
331
332 this_cache=kzalloc(sizeof(struct cache_info)*unique_caches,
333 GFP_KERNEL);
334 if (this_cache == NULL)
335 return -ENOMEM;
336
337 for (i=0; i < levels; i++) {
338 for (j=2; j >0 ; j--) {
339 if ((status=ia64_pal_cache_config_info(i,j, &cci)) !=
340 PAL_STATUS_SUCCESS)
341 continue;
342
343 this_cache[num_cache_leaves].cci = cci;
344 this_cache[num_cache_leaves].level = i + 1;
345 this_cache[num_cache_leaves].type = j;
346
347 cache_shared_cpu_map_setup(cpu,
348 &this_cache[num_cache_leaves]);
349 num_cache_leaves ++;
350 }
351 }
352
353 all_cpu_cache_info[cpu].cache_leaves = this_cache;
354 all_cpu_cache_info[cpu].num_cache_leaves = num_cache_leaves;
355
356 memset(&all_cpu_cache_info[cpu].kobj, 0, sizeof(struct kobject));
357
358 return 0;
359}
360
361/* Add cache interface for CPU device */
362static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
363{
364 unsigned int cpu = sys_dev->id;
365 unsigned long i, j;
366 struct cache_info *this_object;
367 int retval = 0;
368 cpumask_t oldmask;
369
370 if (all_cpu_cache_info[cpu].kobj.parent)
371 return 0;
372
373 oldmask = current->cpus_allowed;
374 retval = set_cpus_allowed(current, cpumask_of_cpu(cpu));
375 if (unlikely(retval))
376 return retval;
377
378 retval = cpu_cache_sysfs_init(cpu);
379 set_cpus_allowed(current, oldmask);
380 if (unlikely(retval < 0))
381 return retval;
382
383 all_cpu_cache_info[cpu].kobj.parent = &sys_dev->kobj;
384 kobject_set_name(&all_cpu_cache_info[cpu].kobj, "%s", "cache");
385 all_cpu_cache_info[cpu].kobj.ktype = &cache_ktype_percpu_entry;
386 retval = kobject_register(&all_cpu_cache_info[cpu].kobj);
387
388 for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++) {
389 this_object = LEAF_KOBJECT_PTR(cpu,i);
390 this_object->kobj.parent = &all_cpu_cache_info[cpu].kobj;
391 kobject_set_name(&(this_object->kobj), "index%1lu", i);
392 this_object->kobj.ktype = &cache_ktype;
393 retval = kobject_register(&(this_object->kobj));
394 if (unlikely(retval)) {
395 for (j = 0; j < i; j++) {
396 kobject_unregister(
397 &(LEAF_KOBJECT_PTR(cpu,j)->kobj));
398 }
399 kobject_unregister(&all_cpu_cache_info[cpu].kobj);
400 cpu_cache_sysfs_exit(cpu);
401 break;
402 }
403 }
404 return retval;
405}
406
407/* Remove cache interface for CPU device */
408static int __cpuinit cache_remove_dev(struct sys_device * sys_dev)
409{
410 unsigned int cpu = sys_dev->id;
411 unsigned long i;
412
413 for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++)
414 kobject_unregister(&(LEAF_KOBJECT_PTR(cpu,i)->kobj));
415
416 if (all_cpu_cache_info[cpu].kobj.parent) {
417 kobject_unregister(&all_cpu_cache_info[cpu].kobj);
418 memset(&all_cpu_cache_info[cpu].kobj,
419 0,
420 sizeof(struct kobject));
421 }
422
423 cpu_cache_sysfs_exit(cpu);
424
425 return 0;
426}
427
428/*
429 * When a cpu is hot-plugged, do a check and initiate
430 * cache kobject if necessary
431 */
432static int __cpuinit cache_cpu_callback(struct notifier_block *nfb,
433 unsigned long action, void *hcpu)
434{
435 unsigned int cpu = (unsigned long)hcpu;
436 struct sys_device *sys_dev;
437
438 sys_dev = get_cpu_sysdev(cpu);
439 switch (action) {
440 case CPU_ONLINE:
441 cache_add_dev(sys_dev);
442 break;
443 case CPU_DEAD:
444 cache_remove_dev(sys_dev);
445 break;
446 }
447 return NOTIFY_OK;
448}
449
450static struct notifier_block cache_cpu_notifier =
451{
452 .notifier_call = cache_cpu_callback
453};
454
455static int __cpuinit cache_sysfs_init(void)
456{
457 int i;
458
459 for_each_online_cpu(i) {
460 cache_cpu_callback(&cache_cpu_notifier, CPU_ONLINE,
461 (void *)(long)i);
462 }
463
464 register_cpu_notifier(&cache_cpu_notifier);
465
466 return 0;
467}
468
469device_initcall(cache_sysfs_init);
470
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)
21void __iomem * 21void __iomem *
22ioremap (unsigned long offset, unsigned long size) 22ioremap (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}
172EXPORT_SYMBOL(flush_tlb_range); 174EXPORT_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 }