diff options
Diffstat (limited to 'arch/ia64')
-rw-r--r-- | arch/ia64/Kconfig | 1 | ||||
-rw-r--r-- | arch/ia64/kernel/Makefile | 5 | ||||
-rw-r--r-- | arch/ia64/kernel/acpi-ext.c | 22 | ||||
-rw-r--r-- | arch/ia64/kernel/acpi-processor.c | 67 | ||||
-rw-r--r-- | arch/ia64/kernel/acpi.c | 6 | ||||
-rw-r--r-- | arch/ia64/kernel/cpufreq/Makefile | 1 | ||||
-rw-r--r-- | arch/ia64/kernel/cpufreq/acpi-cpufreq.c | 51 | ||||
-rw-r--r-- | arch/ia64/kernel/mca_asm.S | 2 | ||||
-rw-r--r-- | arch/ia64/kernel/sal.c | 75 | ||||
-rw-r--r-- | arch/ia64/kernel/unaligned.c | 3 | ||||
-rw-r--r-- | arch/ia64/pci/pci.c | 10 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/io_init.c | 43 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/irq.c | 2 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/sn2/sn2_smp.c | 196 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/xpc_channel.c | 6 | ||||
-rw-r--r-- | arch/ia64/sn/pci/pci_dma.c | 4 |
16 files changed, 276 insertions, 218 deletions
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 8e5517e62c0a..845cd0902a50 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
@@ -194,7 +194,6 @@ config IA64_L1_CACHE_SHIFT | |||
194 | default "7" if MCKINLEY | 194 | default "7" if MCKINLEY |
195 | default "6" if ITANIUM | 195 | default "6" if ITANIUM |
196 | 196 | ||
197 | # align cache-sensitive data to 64 bytes | ||
198 | config IA64_CYCLONE | 197 | config IA64_CYCLONE |
199 | bool "Cyclone (EXA) Time Source support" | 198 | bool "Cyclone (EXA) Time Source support" |
200 | help | 199 | help |
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 307514f7a282..09a0dbc17fb6 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile | |||
@@ -13,6 +13,11 @@ obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o | |||
13 | obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o | 13 | obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o |
14 | obj-$(CONFIG_IA64_HP_ZX1) += acpi-ext.o | 14 | obj-$(CONFIG_IA64_HP_ZX1) += acpi-ext.o |
15 | obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += acpi-ext.o | 15 | obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += acpi-ext.o |
16 | |||
17 | ifneq ($(CONFIG_ACPI_PROCESSOR),) | ||
18 | obj-y += acpi-processor.o | ||
19 | endif | ||
20 | |||
16 | obj-$(CONFIG_IA64_PALINFO) += palinfo.o | 21 | obj-$(CONFIG_IA64_PALINFO) += palinfo.o |
17 | obj-$(CONFIG_IOSAPIC) += iosapic.o | 22 | obj-$(CONFIG_IOSAPIC) += iosapic.o |
18 | obj-$(CONFIG_MODULES) += module.o | 23 | obj-$(CONFIG_MODULES) += module.o |
diff --git a/arch/ia64/kernel/acpi-ext.c b/arch/ia64/kernel/acpi-ext.c index 13a5b3b49bf8..4a5574ff007b 100644 --- a/arch/ia64/kernel/acpi-ext.c +++ b/arch/ia64/kernel/acpi-ext.c | |||
@@ -33,33 +33,33 @@ acpi_vendor_resource_match(struct acpi_resource *resource, void *context) | |||
33 | struct acpi_vendor_info *info = (struct acpi_vendor_info *)context; | 33 | struct acpi_vendor_info *info = (struct acpi_vendor_info *)context; |
34 | struct acpi_resource_vendor *vendor; | 34 | struct acpi_resource_vendor *vendor; |
35 | struct acpi_vendor_descriptor *descriptor; | 35 | struct acpi_vendor_descriptor *descriptor; |
36 | u32 length; | 36 | u32 byte_length; |
37 | 37 | ||
38 | if (resource->id != ACPI_RSTYPE_VENDOR) | 38 | if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) |
39 | return AE_OK; | 39 | return AE_OK; |
40 | 40 | ||
41 | vendor = (struct acpi_resource_vendor *)&resource->data; | 41 | vendor = (struct acpi_resource_vendor *)&resource->data; |
42 | descriptor = (struct acpi_vendor_descriptor *)vendor->reserved; | 42 | descriptor = (struct acpi_vendor_descriptor *)vendor->byte_data; |
43 | if (vendor->length <= sizeof(*info->descriptor) || | 43 | if (vendor->byte_length <= sizeof(*info->descriptor) || |
44 | descriptor->guid_id != info->descriptor->guid_id || | 44 | descriptor->guid_id != info->descriptor->guid_id || |
45 | efi_guidcmp(descriptor->guid, info->descriptor->guid)) | 45 | efi_guidcmp(descriptor->guid, info->descriptor->guid)) |
46 | return AE_OK; | 46 | return AE_OK; |
47 | 47 | ||
48 | length = vendor->length - sizeof(struct acpi_vendor_descriptor); | 48 | byte_length = vendor->byte_length - sizeof(struct acpi_vendor_descriptor); |
49 | info->data = acpi_os_allocate(length); | 49 | info->data = acpi_os_allocate(byte_length); |
50 | if (!info->data) | 50 | if (!info->data) |
51 | return AE_NO_MEMORY; | 51 | return AE_NO_MEMORY; |
52 | 52 | ||
53 | memcpy(info->data, | 53 | memcpy(info->data, |
54 | vendor->reserved + sizeof(struct acpi_vendor_descriptor), | 54 | vendor->byte_data + sizeof(struct acpi_vendor_descriptor), |
55 | length); | 55 | byte_length); |
56 | info->length = length; | 56 | info->length = byte_length; |
57 | return AE_CTRL_TERMINATE; | 57 | return AE_CTRL_TERMINATE; |
58 | } | 58 | } |
59 | 59 | ||
60 | acpi_status | 60 | acpi_status |
61 | acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id, | 61 | acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id, |
62 | u8 ** data, u32 * length) | 62 | u8 ** data, u32 * byte_length) |
63 | { | 63 | { |
64 | struct acpi_vendor_info info; | 64 | struct acpi_vendor_info info; |
65 | 65 | ||
@@ -72,7 +72,7 @@ acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id, | |||
72 | return AE_NOT_FOUND; | 72 | return AE_NOT_FOUND; |
73 | 73 | ||
74 | *data = info.data; | 74 | *data = info.data; |
75 | *length = info.length; | 75 | *byte_length = info.length; |
76 | return AE_OK; | 76 | return AE_OK; |
77 | } | 77 | } |
78 | 78 | ||
diff --git a/arch/ia64/kernel/acpi-processor.c b/arch/ia64/kernel/acpi-processor.c new file mode 100644 index 000000000000..e683630c8ce2 --- /dev/null +++ b/arch/ia64/kernel/acpi-processor.c | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * arch/ia64/kernel/cpufreq/processor.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Intel Corporation | ||
5 | * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> | ||
6 | * - Added _PDC for platforms with Intel CPUs | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/acpi.h> | ||
13 | |||
14 | #include <acpi/processor.h> | ||
15 | #include <asm/acpi.h> | ||
16 | |||
17 | static void init_intel_pdc(struct acpi_processor *pr) | ||
18 | { | ||
19 | struct acpi_object_list *obj_list; | ||
20 | union acpi_object *obj; | ||
21 | u32 *buf; | ||
22 | |||
23 | /* allocate and initialize pdc. It will be used later. */ | ||
24 | obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); | ||
25 | if (!obj_list) { | ||
26 | printk(KERN_ERR "Memory allocation error\n"); | ||
27 | return; | ||
28 | } | ||
29 | |||
30 | obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); | ||
31 | if (!obj) { | ||
32 | printk(KERN_ERR "Memory allocation error\n"); | ||
33 | kfree(obj_list); | ||
34 | return; | ||
35 | } | ||
36 | |||
37 | buf = kmalloc(12, GFP_KERNEL); | ||
38 | if (!buf) { | ||
39 | printk(KERN_ERR "Memory allocation error\n"); | ||
40 | kfree(obj); | ||
41 | kfree(obj_list); | ||
42 | return; | ||
43 | } | ||
44 | |||
45 | buf[0] = ACPI_PDC_REVISION_ID; | ||
46 | buf[1] = 1; | ||
47 | buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; | ||
48 | |||
49 | obj->type = ACPI_TYPE_BUFFER; | ||
50 | obj->buffer.length = 12; | ||
51 | obj->buffer.pointer = (u8 *) buf; | ||
52 | obj_list->count = 1; | ||
53 | obj_list->pointer = obj; | ||
54 | pr->pdc = obj_list; | ||
55 | |||
56 | return; | ||
57 | } | ||
58 | |||
59 | /* Initialize _PDC data based on the CPU vendor */ | ||
60 | void arch_acpi_processor_init_pdc(struct acpi_processor *pr) | ||
61 | { | ||
62 | pr->pdc = NULL; | ||
63 | init_intel_pdc(pr); | ||
64 | return; | ||
65 | } | ||
66 | |||
67 | EXPORT_SYMBOL(arch_acpi_processor_init_pdc); | ||
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 9ad94ddf6687..d2702c419cf8 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
@@ -567,16 +567,16 @@ void __init acpi_numa_arch_fixup(void) | |||
567 | * success: return IRQ number (>=0) | 567 | * success: return IRQ number (>=0) |
568 | * failure: return < 0 | 568 | * failure: return < 0 |
569 | */ | 569 | */ |
570 | int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low) | 570 | int acpi_register_gsi(u32 gsi, int triggering, int polarity) |
571 | { | 571 | { |
572 | if (has_8259 && gsi < 16) | 572 | if (has_8259 && gsi < 16) |
573 | return isa_irq_to_vector(gsi); | 573 | return isa_irq_to_vector(gsi); |
574 | 574 | ||
575 | return iosapic_register_intr(gsi, | 575 | return iosapic_register_intr(gsi, |
576 | (active_high_low == | 576 | (polarity == |
577 | ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : | 577 | ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : |
578 | IOSAPIC_POL_LOW, | 578 | IOSAPIC_POL_LOW, |
579 | (edge_level == | 579 | (triggering == |
580 | ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : | 580 | ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : |
581 | IOSAPIC_LEVEL); | 581 | IOSAPIC_LEVEL); |
582 | } | 582 | } |
diff --git a/arch/ia64/kernel/cpufreq/Makefile b/arch/ia64/kernel/cpufreq/Makefile index f748d34c02f0..4838f2a57c7a 100644 --- a/arch/ia64/kernel/cpufreq/Makefile +++ b/arch/ia64/kernel/cpufreq/Makefile | |||
@@ -1 +1,2 @@ | |||
1 | obj-$(CONFIG_IA64_ACPI_CPUFREQ) += acpi-cpufreq.o | 1 | obj-$(CONFIG_IA64_ACPI_CPUFREQ) += acpi-cpufreq.o |
2 | |||
diff --git a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c index da4d5cf80a48..5a1bf815282d 100644 --- a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c +++ b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c | |||
@@ -269,48 +269,6 @@ acpi_cpufreq_verify ( | |||
269 | } | 269 | } |
270 | 270 | ||
271 | 271 | ||
272 | /* | ||
273 | * processor_init_pdc - let BIOS know about the SMP capabilities | ||
274 | * of this driver | ||
275 | * @perf: processor-specific acpi_io_data struct | ||
276 | * @cpu: CPU being initialized | ||
277 | * | ||
278 | * To avoid issues with legacy OSes, some BIOSes require to be informed of | ||
279 | * the SMP capabilities of OS P-state driver. Here we set the bits in _PDC | ||
280 | * accordingly. Actual call to _PDC is done in driver/acpi/processor.c | ||
281 | */ | ||
282 | static void | ||
283 | processor_init_pdc ( | ||
284 | struct acpi_processor_performance *perf, | ||
285 | unsigned int cpu, | ||
286 | struct acpi_object_list *obj_list | ||
287 | ) | ||
288 | { | ||
289 | union acpi_object *obj; | ||
290 | u32 *buf; | ||
291 | |||
292 | dprintk("processor_init_pdc\n"); | ||
293 | |||
294 | perf->pdc = NULL; | ||
295 | /* Initialize pdc. It will be used later. */ | ||
296 | if (!obj_list) | ||
297 | return; | ||
298 | |||
299 | if (!(obj_list->count && obj_list->pointer)) | ||
300 | return; | ||
301 | |||
302 | obj = obj_list->pointer; | ||
303 | if ((obj->buffer.length == 12) && obj->buffer.pointer) { | ||
304 | buf = (u32 *)obj->buffer.pointer; | ||
305 | buf[0] = ACPI_PDC_REVISION_ID; | ||
306 | buf[1] = 1; | ||
307 | buf[2] = ACPI_PDC_EST_CAPABILITY_SMP; | ||
308 | perf->pdc = obj_list; | ||
309 | } | ||
310 | return; | ||
311 | } | ||
312 | |||
313 | |||
314 | static int | 272 | static int |
315 | acpi_cpufreq_cpu_init ( | 273 | acpi_cpufreq_cpu_init ( |
316 | struct cpufreq_policy *policy) | 274 | struct cpufreq_policy *policy) |
@@ -320,14 +278,7 @@ acpi_cpufreq_cpu_init ( | |||
320 | struct cpufreq_acpi_io *data; | 278 | struct cpufreq_acpi_io *data; |
321 | unsigned int result = 0; | 279 | unsigned int result = 0; |
322 | 280 | ||
323 | union acpi_object arg0 = {ACPI_TYPE_BUFFER}; | ||
324 | u32 arg0_buf[3]; | ||
325 | struct acpi_object_list arg_list = {1, &arg0}; | ||
326 | |||
327 | dprintk("acpi_cpufreq_cpu_init\n"); | 281 | dprintk("acpi_cpufreq_cpu_init\n"); |
328 | /* setup arg_list for _PDC settings */ | ||
329 | arg0.buffer.length = 12; | ||
330 | arg0.buffer.pointer = (u8 *) arg0_buf; | ||
331 | 282 | ||
332 | data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); | 283 | data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); |
333 | if (!data) | 284 | if (!data) |
@@ -337,9 +288,7 @@ acpi_cpufreq_cpu_init ( | |||
337 | 288 | ||
338 | acpi_io_data[cpu] = data; | 289 | acpi_io_data[cpu] = data; |
339 | 290 | ||
340 | processor_init_pdc(&data->acpi_data, cpu, &arg_list); | ||
341 | result = acpi_processor_register_performance(&data->acpi_data, cpu); | 291 | result = acpi_processor_register_performance(&data->acpi_data, cpu); |
342 | data->acpi_data.pdc = NULL; | ||
343 | 292 | ||
344 | if (result) | 293 | if (result) |
345 | goto err_free; | 294 | goto err_free; |
diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S index 403a80a58c13..60a464bfd9e2 100644 --- a/arch/ia64/kernel/mca_asm.S +++ b/arch/ia64/kernel/mca_asm.S | |||
@@ -512,7 +512,7 @@ ia64_state_save: | |||
512 | st8 [temp1]=r12 // os_status, default is cold boot | 512 | st8 [temp1]=r12 // os_status, default is cold boot |
513 | mov r6=IA64_MCA_SAME_CONTEXT | 513 | mov r6=IA64_MCA_SAME_CONTEXT |
514 | ;; | 514 | ;; |
515 | st8 [temp1]=r6 // context, default is same context | 515 | st8 [temp2]=r6 // context, default is same context |
516 | 516 | ||
517 | // Save the pt_regs data that is not in minstate. The previous code | 517 | // Save the pt_regs data that is not in minstate. The previous code |
518 | // left regs at sos. | 518 | // left regs at sos. |
diff --git a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c index acc0f132f86c..056f7a6eedc7 100644 --- a/arch/ia64/kernel/sal.c +++ b/arch/ia64/kernel/sal.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
15 | #include <linux/string.h> | 15 | #include <linux/string.h> |
16 | 16 | ||
17 | #include <asm/delay.h> | ||
17 | #include <asm/page.h> | 18 | #include <asm/page.h> |
18 | #include <asm/sal.h> | 19 | #include <asm/sal.h> |
19 | #include <asm/pal.h> | 20 | #include <asm/pal.h> |
@@ -214,6 +215,78 @@ chk_nointroute_opt(void) | |||
214 | static void __init sal_desc_ap_wakeup(void *p) { } | 215 | static void __init sal_desc_ap_wakeup(void *p) { } |
215 | #endif | 216 | #endif |
216 | 217 | ||
218 | /* | ||
219 | * HP rx5670 firmware polls for interrupts during SAL_CACHE_FLUSH by reading | ||
220 | * cr.ivr, but it never writes cr.eoi. This leaves any interrupt marked as | ||
221 | * "in-service" and masks other interrupts of equal or lower priority. | ||
222 | * | ||
223 | * HP internal defect reports: F1859, F2775, F3031. | ||
224 | */ | ||
225 | static int sal_cache_flush_drops_interrupts; | ||
226 | |||
227 | static void __init | ||
228 | check_sal_cache_flush (void) | ||
229 | { | ||
230 | unsigned long flags, itv; | ||
231 | int cpu; | ||
232 | u64 vector; | ||
233 | |||
234 | cpu = get_cpu(); | ||
235 | local_irq_save(flags); | ||
236 | |||
237 | /* | ||
238 | * Schedule a timer interrupt, wait until it's reported, and see if | ||
239 | * SAL_CACHE_FLUSH drops it. | ||
240 | */ | ||
241 | itv = ia64_get_itv(); | ||
242 | BUG_ON((itv & (1 << 16)) == 0); | ||
243 | |||
244 | ia64_set_itv(IA64_TIMER_VECTOR); | ||
245 | ia64_set_itm(ia64_get_itc() + 1000); | ||
246 | |||
247 | while (!ia64_get_irr(IA64_TIMER_VECTOR)) | ||
248 | cpu_relax(); | ||
249 | |||
250 | ia64_sal_cache_flush(3); | ||
251 | |||
252 | if (ia64_get_irr(IA64_TIMER_VECTOR)) { | ||
253 | vector = ia64_get_ivr(); | ||
254 | ia64_eoi(); | ||
255 | WARN_ON(vector != IA64_TIMER_VECTOR); | ||
256 | } else { | ||
257 | sal_cache_flush_drops_interrupts = 1; | ||
258 | printk(KERN_ERR "SAL: SAL_CACHE_FLUSH drops interrupts; " | ||
259 | "PAL_CACHE_FLUSH will be used instead\n"); | ||
260 | ia64_eoi(); | ||
261 | } | ||
262 | |||
263 | ia64_set_itv(itv); | ||
264 | local_irq_restore(flags); | ||
265 | put_cpu(); | ||
266 | } | ||
267 | |||
268 | s64 | ||
269 | ia64_sal_cache_flush (u64 cache_type) | ||
270 | { | ||
271 | struct ia64_sal_retval isrv; | ||
272 | |||
273 | if (sal_cache_flush_drops_interrupts) { | ||
274 | unsigned long flags; | ||
275 | u64 progress; | ||
276 | s64 rc; | ||
277 | |||
278 | progress = 0; | ||
279 | local_irq_save(flags); | ||
280 | rc = ia64_pal_cache_flush(cache_type, | ||
281 | PAL_CACHE_FLUSH_INVALIDATE, &progress, NULL); | ||
282 | local_irq_restore(flags); | ||
283 | return rc; | ||
284 | } | ||
285 | |||
286 | SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0); | ||
287 | return isrv.status; | ||
288 | } | ||
289 | |||
217 | void __init | 290 | void __init |
218 | ia64_sal_init (struct ia64_sal_systab *systab) | 291 | ia64_sal_init (struct ia64_sal_systab *systab) |
219 | { | 292 | { |
@@ -262,6 +335,8 @@ ia64_sal_init (struct ia64_sal_systab *systab) | |||
262 | } | 335 | } |
263 | p += SAL_DESC_SIZE(*p); | 336 | p += SAL_DESC_SIZE(*p); |
264 | } | 337 | } |
338 | |||
339 | check_sal_cache_flush(); | ||
265 | } | 340 | } |
266 | 341 | ||
267 | int | 342 | int |
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c index 43b45b65ee5a..f9e0ae936d1a 100644 --- a/arch/ia64/kernel/unaligned.c +++ b/arch/ia64/kernel/unaligned.c | |||
@@ -1283,8 +1283,9 @@ within_logging_rate_limit (void) | |||
1283 | 1283 | ||
1284 | if (jiffies - last_time > 5*HZ) | 1284 | if (jiffies - last_time > 5*HZ) |
1285 | count = 0; | 1285 | count = 0; |
1286 | if (++count < 5) { | 1286 | if (count < 5) { |
1287 | last_time = jiffies; | 1287 | last_time = jiffies; |
1288 | count++; | ||
1288 | return 1; | 1289 | return 1; |
1289 | } | 1290 | } |
1290 | return 0; | 1291 | return 0; |
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index d27ecdcb6fca..0b30ca006286 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -193,12 +193,12 @@ add_io_space (struct pci_root_info *info, struct acpi_resource_address64 *addr) | |||
193 | goto free_resource; | 193 | goto free_resource; |
194 | } | 194 | } |
195 | 195 | ||
196 | min = addr->min_address_range; | 196 | min = addr->minimum; |
197 | max = min + addr->address_length - 1; | 197 | max = min + addr->address_length - 1; |
198 | if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION) | 198 | if (addr->info.io.translation_type == ACPI_SPARSE_TRANSLATION) |
199 | sparse = 1; | 199 | sparse = 1; |
200 | 200 | ||
201 | space_nr = new_space(addr->address_translation_offset, sparse); | 201 | space_nr = new_space(addr->translation_offset, sparse); |
202 | if (space_nr == ~0) | 202 | if (space_nr == ~0) |
203 | goto free_name; | 203 | goto free_name; |
204 | 204 | ||
@@ -285,7 +285,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data) | |||
285 | if (addr.resource_type == ACPI_MEMORY_RANGE) { | 285 | if (addr.resource_type == ACPI_MEMORY_RANGE) { |
286 | flags = IORESOURCE_MEM; | 286 | flags = IORESOURCE_MEM; |
287 | root = &iomem_resource; | 287 | root = &iomem_resource; |
288 | offset = addr.address_translation_offset; | 288 | offset = addr.translation_offset; |
289 | } else if (addr.resource_type == ACPI_IO_RANGE) { | 289 | } else if (addr.resource_type == ACPI_IO_RANGE) { |
290 | flags = IORESOURCE_IO; | 290 | flags = IORESOURCE_IO; |
291 | root = &ioport_resource; | 291 | root = &ioport_resource; |
@@ -298,7 +298,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data) | |||
298 | window = &info->controller->window[info->controller->windows++]; | 298 | window = &info->controller->window[info->controller->windows++]; |
299 | window->resource.name = info->name; | 299 | window->resource.name = info->name; |
300 | window->resource.flags = flags; | 300 | window->resource.flags = flags; |
301 | window->resource.start = addr.min_address_range + offset; | 301 | window->resource.start = addr.minimum + offset; |
302 | window->resource.end = window->resource.start + addr.address_length - 1; | 302 | window->resource.end = window->resource.start + addr.address_length - 1; |
303 | window->resource.child = NULL; | 303 | window->resource.child = NULL; |
304 | window->offset = offset; | 304 | window->offset = offset; |
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 00700f7e6837..6dbb7fca1c57 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/nodemask.h> | 10 | #include <linux/nodemask.h> |
11 | #include <asm/sn/types.h> | 11 | #include <asm/sn/types.h> |
12 | #include <asm/sn/addrs.h> | 12 | #include <asm/sn/addrs.h> |
13 | #include <asm/sn/sn_feature_sets.h> | ||
13 | #include <asm/sn/geo.h> | 14 | #include <asm/sn/geo.h> |
14 | #include <asm/sn/io.h> | 15 | #include <asm/sn/io.h> |
15 | #include <asm/sn/pcibr_provider.h> | 16 | #include <asm/sn/pcibr_provider.h> |
@@ -173,8 +174,8 @@ sn_pcidev_info_get(struct pci_dev *dev) | |||
173 | */ | 174 | */ |
174 | static u8 war_implemented = 0; | 175 | static u8 war_implemented = 0; |
175 | 176 | ||
176 | static void sn_device_fixup_war(u64 nasid, u64 widget, int device, | 177 | static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device, |
177 | struct sn_flush_device_common *common) | 178 | struct sn_flush_device_common *common) |
178 | { | 179 | { |
179 | struct sn_flush_device_war *war_list; | 180 | struct sn_flush_device_war *war_list; |
180 | struct sn_flush_device_war *dev_entry; | 181 | struct sn_flush_device_war *dev_entry; |
@@ -198,8 +199,9 @@ static void sn_device_fixup_war(u64 nasid, u64 widget, int device, | |||
198 | 199 | ||
199 | dev_entry = war_list + device; | 200 | dev_entry = war_list + device; |
200 | memcpy(common,dev_entry, sizeof(*common)); | 201 | memcpy(common,dev_entry, sizeof(*common)); |
201 | |||
202 | kfree(war_list); | 202 | kfree(war_list); |
203 | |||
204 | return isrv.status; | ||
203 | } | 205 | } |
204 | 206 | ||
205 | /* | 207 | /* |
@@ -279,23 +281,21 @@ static void sn_fixup_ionodes(void) | |||
279 | memset(dev_entry->common, 0x0, sizeof(struct | 281 | memset(dev_entry->common, 0x0, sizeof(struct |
280 | sn_flush_device_common)); | 282 | sn_flush_device_common)); |
281 | 283 | ||
282 | status = sal_get_device_dmaflush_list(nasid, | 284 | if (sn_prom_feature_available( |
283 | widget, | 285 | PRF_DEVICE_FLUSH_LIST)) |
284 | device, | 286 | status = sal_get_device_dmaflush_list( |
287 | nasid, | ||
288 | widget, | ||
289 | device, | ||
285 | (u64)(dev_entry->common)); | 290 | (u64)(dev_entry->common)); |
286 | if (status) { | 291 | else |
287 | if (sn_sal_rev() < 0x0450) { | 292 | status = sn_device_fixup_war(nasid, |
288 | /* shortlived WAR for older | 293 | widget, |
289 | * PROM images | 294 | device, |
290 | */ | ||
291 | sn_device_fixup_war(nasid, | ||
292 | widget, | ||
293 | device, | ||
294 | dev_entry->common); | 295 | dev_entry->common); |
295 | } | 296 | if (status != SALRET_OK) |
296 | else | 297 | panic("SAL call failed: %s\n", |
297 | BUG(); | 298 | ia64_sal_strerror(status)); |
298 | } | ||
299 | 299 | ||
300 | spin_lock_init(&dev_entry->sfdl_flush_lock); | 300 | spin_lock_init(&dev_entry->sfdl_flush_lock); |
301 | } | 301 | } |
@@ -467,6 +467,13 @@ void sn_pci_fixup_slot(struct pci_dev *dev) | |||
467 | pcidev_info->pdi_sn_irq_info = NULL; | 467 | pcidev_info->pdi_sn_irq_info = NULL; |
468 | kfree(sn_irq_info); | 468 | kfree(sn_irq_info); |
469 | } | 469 | } |
470 | |||
471 | /* | ||
472 | * MSI currently not supported on altix. Remove this when | ||
473 | * the MSI abstraction patches are integrated into the kernel | ||
474 | * (sometime after 2.6.16 releases) | ||
475 | */ | ||
476 | dev->no_msi = 1; | ||
470 | } | 477 | } |
471 | 478 | ||
472 | /* | 479 | /* |
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index ec37084bdc17..928b4ac5e7de 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c | |||
@@ -86,7 +86,7 @@ static void sn_ack_irq(unsigned int irq) | |||
86 | mask); | 86 | mask); |
87 | __set_bit(irq, (volatile void *)pda->sn_in_service_ivecs); | 87 | __set_bit(irq, (volatile void *)pda->sn_in_service_ivecs); |
88 | 88 | ||
89 | move_irq(irq); | 89 | move_native_irq(irq); |
90 | } | 90 | } |
91 | 91 | ||
92 | static void sn_end_irq(unsigned int irq) | 92 | static void sn_end_irq(unsigned int irq) |
diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c index 471bbaa65d1b..f153a4c35c70 100644 --- a/arch/ia64/sn/kernel/sn2/sn2_smp.c +++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
6 | * for more details. | 6 | * for more details. |
7 | * | 7 | * |
8 | * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved. | 8 | * Copyright (C) 2000-2006 Silicon Graphics, Inc. All rights reserved. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
@@ -46,104 +46,28 @@ DECLARE_PER_CPU(struct ptc_stats, ptcstats); | |||
46 | 46 | ||
47 | static __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock); | 47 | static __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock); |
48 | 48 | ||
49 | void sn2_ptc_deadlock_recovery(short *, short, int, volatile unsigned long *, unsigned long data0, | 49 | void sn2_ptc_deadlock_recovery(short *, short, short, int, volatile unsigned long *, unsigned long, |
50 | volatile unsigned long *, unsigned long data1); | 50 | volatile unsigned long *, unsigned long); |
51 | 51 | ||
52 | #ifdef DEBUG_PTC | ||
53 | /* | 52 | /* |
54 | * ptctest: | 53 | * Note: some is the following is captured here to make degugging easier |
55 | * | 54 | * (the macros make more sense if you see the debug patch - not posted) |
56 | * xyz - 3 digit hex number: | ||
57 | * x - Force PTC purges to use shub: | ||
58 | * 0 - no force | ||
59 | * 1 - force | ||
60 | * y - interupt enable | ||
61 | * 0 - disable interrupts | ||
62 | * 1 - leave interuupts enabled | ||
63 | * z - type of lock: | ||
64 | * 0 - global lock | ||
65 | * 1 - node local lock | ||
66 | * 2 - no lock | ||
67 | * | ||
68 | * Note: on shub1, only ptctest == 0 is supported. Don't try other values! | ||
69 | */ | 55 | */ |
70 | |||
71 | static unsigned int sn2_ptctest = 0; | ||
72 | |||
73 | static int __init ptc_test(char *str) | ||
74 | { | ||
75 | get_option(&str, &sn2_ptctest); | ||
76 | return 1; | ||
77 | } | ||
78 | __setup("ptctest=", ptc_test); | ||
79 | |||
80 | static inline int ptc_lock(unsigned long *flagp) | ||
81 | { | ||
82 | unsigned long opt = sn2_ptctest & 255; | ||
83 | |||
84 | switch (opt) { | ||
85 | case 0x00: | ||
86 | spin_lock_irqsave(&sn2_global_ptc_lock, *flagp); | ||
87 | break; | ||
88 | case 0x01: | ||
89 | spin_lock_irqsave(&sn_nodepda->ptc_lock, *flagp); | ||
90 | break; | ||
91 | case 0x02: | ||
92 | local_irq_save(*flagp); | ||
93 | break; | ||
94 | case 0x10: | ||
95 | spin_lock(&sn2_global_ptc_lock); | ||
96 | break; | ||
97 | case 0x11: | ||
98 | spin_lock(&sn_nodepda->ptc_lock); | ||
99 | break; | ||
100 | case 0x12: | ||
101 | break; | ||
102 | default: | ||
103 | BUG(); | ||
104 | } | ||
105 | return opt; | ||
106 | } | ||
107 | |||
108 | static inline void ptc_unlock(unsigned long flags, int opt) | ||
109 | { | ||
110 | switch (opt) { | ||
111 | case 0x00: | ||
112 | spin_unlock_irqrestore(&sn2_global_ptc_lock, flags); | ||
113 | break; | ||
114 | case 0x01: | ||
115 | spin_unlock_irqrestore(&sn_nodepda->ptc_lock, flags); | ||
116 | break; | ||
117 | case 0x02: | ||
118 | local_irq_restore(flags); | ||
119 | break; | ||
120 | case 0x10: | ||
121 | spin_unlock(&sn2_global_ptc_lock); | ||
122 | break; | ||
123 | case 0x11: | ||
124 | spin_unlock(&sn_nodepda->ptc_lock); | ||
125 | break; | ||
126 | case 0x12: | ||
127 | break; | ||
128 | default: | ||
129 | BUG(); | ||
130 | } | ||
131 | } | ||
132 | #else | ||
133 | |||
134 | #define sn2_ptctest 0 | 56 | #define sn2_ptctest 0 |
57 | #define local_node_uses_ptc_ga(sh1) ((sh1) ? 1 : 0) | ||
58 | #define max_active_pio(sh1) ((sh1) ? 32 : 7) | ||
59 | #define reset_max_active_on_deadlock() 1 | ||
60 | #define PTC_LOCK(sh1) ((sh1) ? &sn2_global_ptc_lock : &sn_nodepda->ptc_lock) | ||
135 | 61 | ||
136 | static inline int ptc_lock(unsigned long *flagp) | 62 | static inline void ptc_lock(int sh1, unsigned long *flagp) |
137 | { | 63 | { |
138 | spin_lock_irqsave(&sn2_global_ptc_lock, *flagp); | 64 | spin_lock_irqsave(PTC_LOCK(sh1), *flagp); |
139 | return 0; | ||
140 | } | 65 | } |
141 | 66 | ||
142 | static inline void ptc_unlock(unsigned long flags, int opt) | 67 | static inline void ptc_unlock(int sh1, unsigned long flags) |
143 | { | 68 | { |
144 | spin_unlock_irqrestore(&sn2_global_ptc_lock, flags); | 69 | spin_unlock_irqrestore(PTC_LOCK(sh1), flags); |
145 | } | 70 | } |
146 | #endif | ||
147 | 71 | ||
148 | struct ptc_stats { | 72 | struct ptc_stats { |
149 | unsigned long ptc_l; | 73 | unsigned long ptc_l; |
@@ -151,27 +75,30 @@ struct ptc_stats { | |||
151 | unsigned long shub_ptc_flushes; | 75 | unsigned long shub_ptc_flushes; |
152 | unsigned long nodes_flushed; | 76 | unsigned long nodes_flushed; |
153 | unsigned long deadlocks; | 77 | unsigned long deadlocks; |
78 | unsigned long deadlocks2; | ||
154 | unsigned long lock_itc_clocks; | 79 | unsigned long lock_itc_clocks; |
155 | unsigned long shub_itc_clocks; | 80 | unsigned long shub_itc_clocks; |
156 | unsigned long shub_itc_clocks_max; | 81 | unsigned long shub_itc_clocks_max; |
82 | unsigned long shub_ptc_flushes_not_my_mm; | ||
157 | }; | 83 | }; |
158 | 84 | ||
159 | static inline unsigned long wait_piowc(void) | 85 | static inline unsigned long wait_piowc(void) |
160 | { | 86 | { |
161 | volatile unsigned long *piows, zeroval; | 87 | volatile unsigned long *piows; |
162 | unsigned long ws; | 88 | unsigned long zeroval, ws; |
163 | 89 | ||
164 | piows = pda->pio_write_status_addr; | 90 | piows = pda->pio_write_status_addr; |
165 | zeroval = pda->pio_write_status_val; | 91 | zeroval = pda->pio_write_status_val; |
166 | do { | 92 | do { |
167 | cpu_relax(); | 93 | cpu_relax(); |
168 | } while (((ws = *piows) & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != zeroval); | 94 | } while (((ws = *piows) & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != zeroval); |
169 | return ws; | 95 | return (ws & SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK) != 0; |
170 | } | 96 | } |
171 | 97 | ||
172 | void sn_tlb_migrate_finish(struct mm_struct *mm) | 98 | void sn_tlb_migrate_finish(struct mm_struct *mm) |
173 | { | 99 | { |
174 | if (mm == current->mm) | 100 | /* flush_tlb_mm is inefficient if more than 1 users of mm */ |
101 | if (mm == current->mm && mm && atomic_read(&mm->mm_users) == 1) | ||
175 | flush_tlb_mm(mm); | 102 | flush_tlb_mm(mm); |
176 | } | 103 | } |
177 | 104 | ||
@@ -201,12 +128,14 @@ void | |||
201 | sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, | 128 | sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, |
202 | unsigned long end, unsigned long nbits) | 129 | unsigned long end, unsigned long nbits) |
203 | { | 130 | { |
204 | int i, opt, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0; | 131 | int i, ibegin, shub1, cnode, mynasid, cpu, lcpu = 0, nasid; |
205 | int mymm = (mm == current->active_mm && current->mm); | 132 | int mymm = (mm == current->active_mm && mm == current->mm); |
133 | int use_cpu_ptcga; | ||
206 | volatile unsigned long *ptc0, *ptc1; | 134 | volatile unsigned long *ptc0, *ptc1; |
207 | unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value; | 135 | unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value, old_rr = 0; |
208 | short nasids[MAX_NUMNODES], nix; | 136 | short nasids[MAX_NUMNODES], nix; |
209 | nodemask_t nodes_flushed; | 137 | nodemask_t nodes_flushed; |
138 | int active, max_active, deadlock; | ||
210 | 139 | ||
211 | nodes_clear(nodes_flushed); | 140 | nodes_clear(nodes_flushed); |
212 | i = 0; | 141 | i = 0; |
@@ -267,41 +196,56 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, | |||
267 | 196 | ||
268 | 197 | ||
269 | mynasid = get_nasid(); | 198 | mynasid = get_nasid(); |
199 | use_cpu_ptcga = local_node_uses_ptc_ga(shub1); | ||
200 | max_active = max_active_pio(shub1); | ||
270 | 201 | ||
271 | itc = ia64_get_itc(); | 202 | itc = ia64_get_itc(); |
272 | opt = ptc_lock(&flags); | 203 | ptc_lock(shub1, &flags); |
273 | itc2 = ia64_get_itc(); | 204 | itc2 = ia64_get_itc(); |
205 | |||
274 | __get_cpu_var(ptcstats).lock_itc_clocks += itc2 - itc; | 206 | __get_cpu_var(ptcstats).lock_itc_clocks += itc2 - itc; |
275 | __get_cpu_var(ptcstats).shub_ptc_flushes++; | 207 | __get_cpu_var(ptcstats).shub_ptc_flushes++; |
276 | __get_cpu_var(ptcstats).nodes_flushed += nix; | 208 | __get_cpu_var(ptcstats).nodes_flushed += nix; |
209 | if (!mymm) | ||
210 | __get_cpu_var(ptcstats).shub_ptc_flushes_not_my_mm++; | ||
277 | 211 | ||
212 | if (use_cpu_ptcga && !mymm) { | ||
213 | old_rr = ia64_get_rr(start); | ||
214 | ia64_set_rr(start, (old_rr & 0xff) | (rr_value << 8)); | ||
215 | ia64_srlz_d(); | ||
216 | } | ||
217 | |||
218 | wait_piowc(); | ||
278 | do { | 219 | do { |
279 | if (shub1) | 220 | if (shub1) |
280 | data1 = start | (1UL << SH1_PTC_1_START_SHFT); | 221 | data1 = start | (1UL << SH1_PTC_1_START_SHFT); |
281 | else | 222 | else |
282 | data0 = (data0 & ~SH2_PTC_ADDR_MASK) | (start & SH2_PTC_ADDR_MASK); | 223 | data0 = (data0 & ~SH2_PTC_ADDR_MASK) | (start & SH2_PTC_ADDR_MASK); |
283 | for (i = 0; i < nix; i++) { | 224 | deadlock = 0; |
225 | active = 0; | ||
226 | for (ibegin = 0, i = 0; i < nix; i++) { | ||
284 | nasid = nasids[i]; | 227 | nasid = nasids[i]; |
285 | if ((!(sn2_ptctest & 3)) && unlikely(nasid == mynasid && mymm)) { | 228 | if (use_cpu_ptcga && unlikely(nasid == mynasid)) { |
286 | ia64_ptcga(start, nbits << 2); | 229 | ia64_ptcga(start, nbits << 2); |
287 | ia64_srlz_i(); | 230 | ia64_srlz_i(); |
288 | } else { | 231 | } else { |
289 | ptc0 = CHANGE_NASID(nasid, ptc0); | 232 | ptc0 = CHANGE_NASID(nasid, ptc0); |
290 | if (ptc1) | 233 | if (ptc1) |
291 | ptc1 = CHANGE_NASID(nasid, ptc1); | 234 | ptc1 = CHANGE_NASID(nasid, ptc1); |
292 | pio_atomic_phys_write_mmrs(ptc0, data0, ptc1, | 235 | pio_atomic_phys_write_mmrs(ptc0, data0, ptc1, data1); |
293 | data1); | 236 | active++; |
294 | flushed = 1; | 237 | } |
238 | if (active >= max_active || i == (nix - 1)) { | ||
239 | if ((deadlock = wait_piowc())) { | ||
240 | sn2_ptc_deadlock_recovery(nasids, ibegin, i, mynasid, ptc0, data0, ptc1, data1); | ||
241 | if (reset_max_active_on_deadlock()) | ||
242 | max_active = 1; | ||
243 | } | ||
244 | active = 0; | ||
245 | ibegin = i + 1; | ||
295 | } | 246 | } |
296 | } | 247 | } |
297 | if (flushed | ||
298 | && (wait_piowc() & | ||
299 | (SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK))) { | ||
300 | sn2_ptc_deadlock_recovery(nasids, nix, mynasid, ptc0, data0, ptc1, data1); | ||
301 | } | ||
302 | |||
303 | start += (1UL << nbits); | 248 | start += (1UL << nbits); |
304 | |||
305 | } while (start < end); | 249 | } while (start < end); |
306 | 250 | ||
307 | itc2 = ia64_get_itc() - itc2; | 251 | itc2 = ia64_get_itc() - itc2; |
@@ -309,7 +253,12 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, | |||
309 | if (itc2 > __get_cpu_var(ptcstats).shub_itc_clocks_max) | 253 | if (itc2 > __get_cpu_var(ptcstats).shub_itc_clocks_max) |
310 | __get_cpu_var(ptcstats).shub_itc_clocks_max = itc2; | 254 | __get_cpu_var(ptcstats).shub_itc_clocks_max = itc2; |
311 | 255 | ||
312 | ptc_unlock(flags, opt); | 256 | if (old_rr) { |
257 | ia64_set_rr(start, old_rr); | ||
258 | ia64_srlz_d(); | ||
259 | } | ||
260 | |||
261 | ptc_unlock(shub1, flags); | ||
313 | 262 | ||
314 | preempt_enable(); | 263 | preempt_enable(); |
315 | } | 264 | } |
@@ -321,27 +270,30 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, | |||
321 | * TLB flush transaction. The recovery sequence is somewhat tricky & is | 270 | * TLB flush transaction. The recovery sequence is somewhat tricky & is |
322 | * coded in assembly language. | 271 | * coded in assembly language. |
323 | */ | 272 | */ |
324 | void sn2_ptc_deadlock_recovery(short *nasids, short nix, int mynasid, volatile unsigned long *ptc0, unsigned long data0, | 273 | void sn2_ptc_deadlock_recovery(short *nasids, short ib, short ie, int mynasid, volatile unsigned long *ptc0, unsigned long data0, |
325 | volatile unsigned long *ptc1, unsigned long data1) | 274 | volatile unsigned long *ptc1, unsigned long data1) |
326 | { | 275 | { |
327 | extern void sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long, | 276 | extern unsigned long sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long, |
328 | volatile unsigned long *, unsigned long, volatile unsigned long *, unsigned long); | 277 | volatile unsigned long *, unsigned long, volatile unsigned long *, unsigned long); |
329 | short nasid, i; | 278 | short nasid, i; |
330 | unsigned long *piows, zeroval; | 279 | unsigned long *piows, zeroval, n; |
331 | 280 | ||
332 | __get_cpu_var(ptcstats).deadlocks++; | 281 | __get_cpu_var(ptcstats).deadlocks++; |
333 | 282 | ||
334 | piows = (unsigned long *) pda->pio_write_status_addr; | 283 | piows = (unsigned long *) pda->pio_write_status_addr; |
335 | zeroval = pda->pio_write_status_val; | 284 | zeroval = pda->pio_write_status_val; |
336 | 285 | ||
337 | for (i=0; i < nix; i++) { | 286 | |
287 | for (i=ib; i <= ie; i++) { | ||
338 | nasid = nasids[i]; | 288 | nasid = nasids[i]; |
339 | if (!(sn2_ptctest & 3) && nasid == mynasid) | 289 | if (local_node_uses_ptc_ga(is_shub1()) && nasid == mynasid) |
340 | continue; | 290 | continue; |
341 | ptc0 = CHANGE_NASID(nasid, ptc0); | 291 | ptc0 = CHANGE_NASID(nasid, ptc0); |
342 | if (ptc1) | 292 | if (ptc1) |
343 | ptc1 = CHANGE_NASID(nasid, ptc1); | 293 | ptc1 = CHANGE_NASID(nasid, ptc1); |
344 | sn2_ptc_deadlock_recovery_core(ptc0, data0, ptc1, data1, piows, zeroval); | 294 | |
295 | n = sn2_ptc_deadlock_recovery_core(ptc0, data0, ptc1, data1, piows, zeroval); | ||
296 | __get_cpu_var(ptcstats).deadlocks2 += n; | ||
345 | } | 297 | } |
346 | 298 | ||
347 | } | 299 | } |
@@ -452,20 +404,22 @@ static int sn2_ptc_seq_show(struct seq_file *file, void *data) | |||
452 | cpu = *(loff_t *) data; | 404 | cpu = *(loff_t *) data; |
453 | 405 | ||
454 | if (!cpu) { | 406 | if (!cpu) { |
455 | seq_printf(file, "# ptc_l change_rid shub_ptc_flushes shub_nodes_flushed deadlocks lock_nsec shub_nsec shub_nsec_max\n"); | 407 | seq_printf(file, |
408 | "# cpu ptc_l newrid ptc_flushes nodes_flushed deadlocks lock_nsec shub_nsec shub_nsec_max not_my_mm deadlock2\n"); | ||
456 | seq_printf(file, "# ptctest %d\n", sn2_ptctest); | 409 | seq_printf(file, "# ptctest %d\n", sn2_ptctest); |
457 | } | 410 | } |
458 | 411 | ||
459 | if (cpu < NR_CPUS && cpu_online(cpu)) { | 412 | if (cpu < NR_CPUS && cpu_online(cpu)) { |
460 | stat = &per_cpu(ptcstats, cpu); | 413 | stat = &per_cpu(ptcstats, cpu); |
461 | seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l, | 414 | seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l, |
462 | stat->change_rid, stat->shub_ptc_flushes, stat->nodes_flushed, | 415 | stat->change_rid, stat->shub_ptc_flushes, stat->nodes_flushed, |
463 | stat->deadlocks, | 416 | stat->deadlocks, |
464 | 1000 * stat->lock_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec, | 417 | 1000 * stat->lock_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec, |
465 | 1000 * stat->shub_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec, | 418 | 1000 * stat->shub_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec, |
466 | 1000 * stat->shub_itc_clocks_max / per_cpu(cpu_info, cpu).cyc_per_usec); | 419 | 1000 * stat->shub_itc_clocks_max / per_cpu(cpu_info, cpu).cyc_per_usec, |
420 | stat->shub_ptc_flushes_not_my_mm, | ||
421 | stat->deadlocks2); | ||
467 | } | 422 | } |
468 | |||
469 | return 0; | 423 | return 0; |
470 | } | 424 | } |
471 | 425 | ||
@@ -476,7 +430,7 @@ static struct seq_operations sn2_ptc_seq_ops = { | |||
476 | .show = sn2_ptc_seq_show | 430 | .show = sn2_ptc_seq_show |
477 | }; | 431 | }; |
478 | 432 | ||
479 | int sn2_ptc_proc_open(struct inode *inode, struct file *file) | 433 | static int sn2_ptc_proc_open(struct inode *inode, struct file *file) |
480 | { | 434 | { |
481 | return seq_open(file, &sn2_ptc_seq_ops); | 435 | return seq_open(file, &sn2_ptc_seq_ops); |
482 | } | 436 | } |
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c index 8d950c778bb6..36e5437a0fb6 100644 --- a/arch/ia64/sn/kernel/xpc_channel.c +++ b/arch/ia64/sn/kernel/xpc_channel.c | |||
@@ -447,7 +447,7 @@ xpc_allocate_local_msgqueue(struct xpc_channel *ch) | |||
447 | 447 | ||
448 | nbytes = nentries * ch->msg_size; | 448 | nbytes = nentries * ch->msg_size; |
449 | ch->local_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes, | 449 | ch->local_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes, |
450 | (GFP_KERNEL | GFP_DMA), | 450 | GFP_KERNEL, |
451 | &ch->local_msgqueue_base); | 451 | &ch->local_msgqueue_base); |
452 | if (ch->local_msgqueue == NULL) { | 452 | if (ch->local_msgqueue == NULL) { |
453 | continue; | 453 | continue; |
@@ -455,7 +455,7 @@ xpc_allocate_local_msgqueue(struct xpc_channel *ch) | |||
455 | memset(ch->local_msgqueue, 0, nbytes); | 455 | memset(ch->local_msgqueue, 0, nbytes); |
456 | 456 | ||
457 | nbytes = nentries * sizeof(struct xpc_notify); | 457 | nbytes = nentries * sizeof(struct xpc_notify); |
458 | ch->notify_queue = kmalloc(nbytes, (GFP_KERNEL | GFP_DMA)); | 458 | ch->notify_queue = kmalloc(nbytes, GFP_KERNEL); |
459 | if (ch->notify_queue == NULL) { | 459 | if (ch->notify_queue == NULL) { |
460 | kfree(ch->local_msgqueue_base); | 460 | kfree(ch->local_msgqueue_base); |
461 | ch->local_msgqueue = NULL; | 461 | ch->local_msgqueue = NULL; |
@@ -502,7 +502,7 @@ xpc_allocate_remote_msgqueue(struct xpc_channel *ch) | |||
502 | 502 | ||
503 | nbytes = nentries * ch->msg_size; | 503 | nbytes = nentries * ch->msg_size; |
504 | ch->remote_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes, | 504 | ch->remote_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes, |
505 | (GFP_KERNEL | GFP_DMA), | 505 | GFP_KERNEL, |
506 | &ch->remote_msgqueue_base); | 506 | &ch->remote_msgqueue_base); |
507 | if (ch->remote_msgqueue == NULL) { | 507 | if (ch->remote_msgqueue == NULL) { |
508 | continue; | 508 | continue; |
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index 9bf9f23b9a1f..5a36292388eb 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c | |||
@@ -90,14 +90,14 @@ void *sn_dma_alloc_coherent(struct device *dev, size_t size, | |||
90 | */ | 90 | */ |
91 | node = pcibus_to_node(pdev->bus); | 91 | node = pcibus_to_node(pdev->bus); |
92 | if (likely(node >=0)) { | 92 | if (likely(node >=0)) { |
93 | struct page *p = alloc_pages_node(node, GFP_ATOMIC, get_order(size)); | 93 | struct page *p = alloc_pages_node(node, flags, get_order(size)); |
94 | 94 | ||
95 | if (likely(p)) | 95 | if (likely(p)) |
96 | cpuaddr = page_address(p); | 96 | cpuaddr = page_address(p); |
97 | else | 97 | else |
98 | return NULL; | 98 | return NULL; |
99 | } else | 99 | } else |
100 | cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size)); | 100 | cpuaddr = (void *)__get_free_pages(flags, get_order(size)); |
101 | 101 | ||
102 | if (unlikely(!cpuaddr)) | 102 | if (unlikely(!cpuaddr)) |
103 | return NULL; | 103 | return NULL; |