aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/sn
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/sn')
-rw-r--r--arch/ia64/sn/Makefile2
-rw-r--r--arch/ia64/sn/kernel/Makefile2
-rw-r--r--arch/ia64/sn/kernel/bte.c17
-rw-r--r--arch/ia64/sn/kernel/io_init.c141
-rw-r--r--arch/ia64/sn/kernel/irq.c25
-rw-r--r--arch/ia64/sn/kernel/klconflib.c29
-rw-r--r--arch/ia64/sn/kernel/mca.c5
-rw-r--r--arch/ia64/sn/kernel/setup.c77
-rw-r--r--arch/ia64/sn/kernel/sn2/Makefile2
-rw-r--r--arch/ia64/sn/kernel/sn2/prominfo_proc.c25
-rw-r--r--arch/ia64/sn/kernel/sn2/sn2_smp.c213
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_hwperf.c5
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_proc_fs.c22
-rw-r--r--arch/ia64/sn/kernel/sn2/timer.c19
-rw-r--r--arch/ia64/sn/kernel/sn2/timer_interrupt.c7
-rw-r--r--arch/ia64/sn/kernel/tiocx.c6
-rw-r--r--arch/ia64/sn/kernel/xpc_channel.c14
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c39
-rw-r--r--arch/ia64/sn/pci/Makefile2
-rw-r--r--arch/ia64/sn/pci/pci_dma.c20
-rw-r--r--arch/ia64/sn/pci/pcibr/Makefile2
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_ate.c29
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_dma.c14
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_provider.c9
24 files changed, 343 insertions, 383 deletions
diff --git a/arch/ia64/sn/Makefile b/arch/ia64/sn/Makefile
index a269f6d84c29..79a7df02e812 100644
--- a/arch/ia64/sn/Makefile
+++ b/arch/ia64/sn/Makefile
@@ -9,6 +9,4 @@
9# Makefile for the sn ia64 subplatform 9# Makefile for the sn ia64 subplatform
10# 10#
11 11
12CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
13
14obj-y += kernel/ pci/ 12obj-y += kernel/ pci/
diff --git a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile
index 4351c4ff9845..3e9b4eea7418 100644
--- a/arch/ia64/sn/kernel/Makefile
+++ b/arch/ia64/sn/kernel/Makefile
@@ -7,6 +7,8 @@
7# Copyright (C) 1999,2001-2005 Silicon Graphics, Inc. All Rights Reserved. 7# Copyright (C) 1999,2001-2005 Silicon Graphics, Inc. All Rights Reserved.
8# 8#
9 9
10CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
11
10obj-y += setup.o bte.o bte_error.o irq.o mca.o idle.o \ 12obj-y += setup.o bte.o bte_error.o irq.o mca.o idle.o \
11 huberror.o io_init.o iomv.o klconflib.o sn2/ 13 huberror.o io_init.o iomv.o klconflib.o sn2/
12obj-$(CONFIG_IA64_GENERIC) += machvec.o 14obj-$(CONFIG_IA64_GENERIC) += machvec.o
diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c
index dd73c0cb754b..1f11db470d90 100644
--- a/arch/ia64/sn/kernel/bte.c
+++ b/arch/ia64/sn/kernel/bte.c
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. 6 * Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
7 */ 7 */
8 8
9#include <linux/config.h> 9#include <linux/config.h>
@@ -186,18 +186,13 @@ retry_bteop:
186 186
187 /* Initialize the notification to a known value. */ 187 /* Initialize the notification to a known value. */
188 *bte->most_rcnt_na = BTE_WORD_BUSY; 188 *bte->most_rcnt_na = BTE_WORD_BUSY;
189 notif_phys_addr = TO_PHYS(ia64_tpa((unsigned long)bte->most_rcnt_na)); 189 notif_phys_addr = (u64)bte->most_rcnt_na;
190 190
191 if (is_shub2()) {
192 src = SH2_TIO_PHYS_TO_DMA(src);
193 dest = SH2_TIO_PHYS_TO_DMA(dest);
194 notif_phys_addr = SH2_TIO_PHYS_TO_DMA(notif_phys_addr);
195 }
196 /* Set the source and destination registers */ 191 /* Set the source and destination registers */
197 BTE_PRINTKV(("IBSA = 0x%lx)\n", (TO_PHYS(src)))); 192 BTE_PRINTKV(("IBSA = 0x%lx)\n", src));
198 BTE_SRC_STORE(bte, TO_PHYS(src)); 193 BTE_SRC_STORE(bte, src);
199 BTE_PRINTKV(("IBDA = 0x%lx)\n", (TO_PHYS(dest)))); 194 BTE_PRINTKV(("IBDA = 0x%lx)\n", dest));
200 BTE_DEST_STORE(bte, TO_PHYS(dest)); 195 BTE_DEST_STORE(bte, dest);
201 196
202 /* Set the notification register */ 197 /* Set the notification register */
203 BTE_PRINTKV(("IBNA = 0x%lx)\n", notif_phys_addr)); 198 BTE_PRINTKV(("IBNA = 0x%lx)\n", notif_phys_addr));
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 00700f7e6837..dfb3f2902379 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>
@@ -22,6 +23,10 @@
22#include "xtalk/hubdev.h" 23#include "xtalk/hubdev.h"
23#include "xtalk/xwidgetdev.h" 24#include "xtalk/xwidgetdev.h"
24 25
26
27extern void sn_init_cpei_timer(void);
28extern void register_sn_procfs(void);
29
25static struct list_head sn_sysdata_list; 30static struct list_head sn_sysdata_list;
26 31
27/* sysdata list struct */ 32/* sysdata list struct */
@@ -39,12 +44,12 @@ struct brick {
39 struct slab_info slab_info[MAX_SLABS + 1]; 44 struct slab_info slab_info[MAX_SLABS + 1];
40}; 45};
41 46
42int sn_ioif_inited = 0; /* SN I/O infrastructure initialized? */ 47int sn_ioif_inited; /* SN I/O infrastructure initialized? */
43 48
44struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */ 49struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */
45 50
46static int max_segment_number = 0; /* Default highest segment number */ 51static int max_segment_number; /* Default highest segment number */
47static int max_pcibus_number = 255; /* Default highest pci bus number */ 52static int max_pcibus_number = 255; /* Default highest pci bus number */
48 53
49/* 54/*
50 * Hooks and struct for unsupported pci providers 55 * Hooks and struct for unsupported pci providers
@@ -83,7 +88,6 @@ static inline u64
83sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num, 88sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num,
84 u64 address) 89 u64 address)
85{ 90{
86
87 struct ia64_sal_retval ret_stuff; 91 struct ia64_sal_retval ret_stuff;
88 ret_stuff.status = 0; 92 ret_stuff.status = 0;
89 ret_stuff.v0 = 0; 93 ret_stuff.v0 = 0;
@@ -93,7 +97,6 @@ sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num,
93 (u64) nasid, (u64) widget_num, 97 (u64) nasid, (u64) widget_num,
94 (u64) device_num, (u64) address, 0, 0, 0); 98 (u64) device_num, (u64) address, 0, 0, 0);
95 return ret_stuff.status; 99 return ret_stuff.status;
96
97} 100}
98 101
99/* 102/*
@@ -101,7 +104,6 @@ sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num,
101 */ 104 */
102static inline u64 sal_get_hubdev_info(u64 handle, u64 address) 105static inline u64 sal_get_hubdev_info(u64 handle, u64 address)
103{ 106{
104
105 struct ia64_sal_retval ret_stuff; 107 struct ia64_sal_retval ret_stuff;
106 ret_stuff.status = 0; 108 ret_stuff.status = 0;
107 ret_stuff.v0 = 0; 109 ret_stuff.v0 = 0;
@@ -117,7 +119,6 @@ static inline u64 sal_get_hubdev_info(u64 handle, u64 address)
117 */ 119 */
118static inline u64 sal_get_pcibus_info(u64 segment, u64 busnum, u64 address) 120static inline u64 sal_get_pcibus_info(u64 segment, u64 busnum, u64 address)
119{ 121{
120
121 struct ia64_sal_retval ret_stuff; 122 struct ia64_sal_retval ret_stuff;
122 ret_stuff.status = 0; 123 ret_stuff.status = 0;
123 ret_stuff.v0 = 0; 124 ret_stuff.v0 = 0;
@@ -173,8 +174,8 @@ sn_pcidev_info_get(struct pci_dev *dev)
173 */ 174 */
174static u8 war_implemented = 0; 175static u8 war_implemented = 0;
175 176
176static void sn_device_fixup_war(u64 nasid, u64 widget, int device, 177static 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,22 +199,23 @@ 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/*
206 * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for 208 * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for
207 * each node in the system. 209 * each node in the system.
208 */ 210 */
209static void sn_fixup_ionodes(void) 211static void __init sn_fixup_ionodes(void)
210{ 212{
211 struct sn_flush_device_kernel *sn_flush_device_kernel; 213 struct sn_flush_device_kernel *sn_flush_device_kernel;
212 struct sn_flush_device_kernel *dev_entry; 214 struct sn_flush_device_kernel *dev_entry;
213 struct hubdev_info *hubdev; 215 struct hubdev_info *hubdev;
214 u64 status; 216 u64 status;
215 u64 nasid; 217 u64 nasid;
216 int i, widget, device; 218 int i, widget, device, size;
217 219
218 /* 220 /*
219 * Get SGI Specific HUB chipset information. 221 * Get SGI Specific HUB chipset information.
@@ -249,53 +251,40 @@ static void sn_fixup_ionodes(void)
249 if (!hubdev->hdi_flush_nasid_list.widget_p) 251 if (!hubdev->hdi_flush_nasid_list.widget_p)
250 continue; 252 continue;
251 253
254 size = (HUB_WIDGET_ID_MAX + 1) *
255 sizeof(struct sn_flush_device_kernel *);
252 hubdev->hdi_flush_nasid_list.widget_p = 256 hubdev->hdi_flush_nasid_list.widget_p =
253 kmalloc((HUB_WIDGET_ID_MAX + 1) * 257 kzalloc(size, GFP_KERNEL);
254 sizeof(struct sn_flush_device_kernel *), 258 if (!hubdev->hdi_flush_nasid_list.widget_p)
255 GFP_KERNEL); 259 BUG();
256 memset(hubdev->hdi_flush_nasid_list.widget_p, 0x0,
257 (HUB_WIDGET_ID_MAX + 1) *
258 sizeof(struct sn_flush_device_kernel *));
259 260
260 for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) { 261 for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) {
261 sn_flush_device_kernel = kmalloc(DEV_PER_WIDGET * 262 size = DEV_PER_WIDGET *
262 sizeof(struct 263 sizeof(struct sn_flush_device_kernel);
263 sn_flush_device_kernel), 264 sn_flush_device_kernel = kzalloc(size, GFP_KERNEL);
264 GFP_KERNEL);
265 if (!sn_flush_device_kernel) 265 if (!sn_flush_device_kernel)
266 BUG(); 266 BUG();
267 memset(sn_flush_device_kernel, 0x0,
268 DEV_PER_WIDGET *
269 sizeof(struct sn_flush_device_kernel));
270 267
271 dev_entry = sn_flush_device_kernel; 268 dev_entry = sn_flush_device_kernel;
272 for (device = 0; device < DEV_PER_WIDGET; 269 for (device = 0; device < DEV_PER_WIDGET;
273 device++,dev_entry++) { 270 device++,dev_entry++) {
274 dev_entry->common = kmalloc(sizeof(struct 271 size = sizeof(struct sn_flush_device_common);
275 sn_flush_device_common), 272 dev_entry->common = kzalloc(size, GFP_KERNEL);
276 GFP_KERNEL);
277 if (!dev_entry->common) 273 if (!dev_entry->common)
278 BUG(); 274 BUG();
279 memset(dev_entry->common, 0x0, sizeof(struct 275
280 sn_flush_device_common)); 276 if (sn_prom_feature_available(
281 277 PRF_DEVICE_FLUSH_LIST))
282 status = sal_get_device_dmaflush_list(nasid, 278 status = sal_get_device_dmaflush_list(
283 widget, 279 nasid, widget, device,
284 device, 280 (u64)(dev_entry->common));
285 (u64)(dev_entry->common)); 281 else
286 if (status) { 282 status = sn_device_fixup_war(nasid,
287 if (sn_sal_rev() < 0x0450) { 283 widget, device,
288 /* shortlived WAR for older 284 dev_entry->common);
289 * PROM images 285 if (status != SALRET_OK)
290 */ 286 panic("SAL call failed: %s\n",
291 sn_device_fixup_war(nasid, 287 ia64_sal_strerror(status));
292 widget,
293 device,
294 dev_entry->common);
295 }
296 else
297 BUG();
298 }
299 288
300 spin_lock_init(&dev_entry->sfdl_flush_lock); 289 spin_lock_init(&dev_entry->sfdl_flush_lock);
301 } 290 }
@@ -383,13 +372,12 @@ void sn_pci_fixup_slot(struct pci_dev *dev)
383 372
384 pci_dev_get(dev); /* for the sysdata pointer */ 373 pci_dev_get(dev); /* for the sysdata pointer */
385 pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL); 374 pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL);
386 if (pcidev_info <= 0) 375 if (!pcidev_info)
387 BUG(); /* Cannot afford to run out of memory */ 376 BUG(); /* Cannot afford to run out of memory */
388 377
389 sn_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_KERNEL); 378 sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
390 if (sn_irq_info <= 0) 379 if (!sn_irq_info)
391 BUG(); /* Cannot afford to run out of memory */ 380 BUG(); /* Cannot afford to run out of memory */
392 memset(sn_irq_info, 0, sizeof(struct sn_irq_info));
393 381
394 /* Call to retrieve pci device information needed by kernel. */ 382 /* Call to retrieve pci device information needed by kernel. */
395 status = sal_get_pcidev_info((u64) segment, (u64) dev->bus->number, 383 status = sal_get_pcidev_info((u64) segment, (u64) dev->bus->number,
@@ -467,6 +455,13 @@ void sn_pci_fixup_slot(struct pci_dev *dev)
467 pcidev_info->pdi_sn_irq_info = NULL; 455 pcidev_info->pdi_sn_irq_info = NULL;
468 kfree(sn_irq_info); 456 kfree(sn_irq_info);
469 } 457 }
458
459 /*
460 * MSI currently not supported on altix. Remove this when
461 * the MSI abstraction patches are integrated into the kernel
462 * (sometime after 2.6.16 releases)
463 */
464 dev->no_msi = 1;
470} 465}
471 466
472/* 467/*
@@ -475,13 +470,13 @@ void sn_pci_fixup_slot(struct pci_dev *dev)
475 */ 470 */
476void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) 471void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
477{ 472{
478 int status = 0; 473 int status;
479 int nasid, cnode; 474 int nasid, cnode;
480 struct pci_controller *controller; 475 struct pci_controller *controller;
481 struct sn_pci_controller *sn_controller; 476 struct sn_pci_controller *sn_controller;
482 struct pcibus_bussoft *prom_bussoft_ptr; 477 struct pcibus_bussoft *prom_bussoft_ptr;
483 struct hubdev_info *hubdev_info; 478 struct hubdev_info *hubdev_info;
484 void *provider_soft = NULL; 479 void *provider_soft;
485 struct sn_pcibus_provider *provider; 480 struct sn_pcibus_provider *provider;
486 481
487 status = sal_get_pcibus_info((u64) segment, (u64) busnum, 482 status = sal_get_pcibus_info((u64) segment, (u64) busnum,
@@ -528,6 +523,8 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
528 bus->sysdata = controller; 523 bus->sysdata = controller;
529 if (provider->bus_fixup) 524 if (provider->bus_fixup)
530 provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller); 525 provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller);
526 else
527 provider_soft = NULL;
531 528
532 if (provider_soft == NULL) { 529 if (provider_soft == NULL) {
533 /* fixup failed or not applicable */ 530 /* fixup failed or not applicable */
@@ -610,15 +607,15 @@ void sn_bus_store_sysdata(struct pci_dev *dev)
610void sn_bus_free_sysdata(void) 607void sn_bus_free_sysdata(void)
611{ 608{
612 struct sysdata_el *element; 609 struct sysdata_el *element;
613 struct list_head *list; 610 struct list_head *list, *safe;
614 611
615sn_sysdata_free_start: 612 list_for_each_safe(list, safe, &sn_sysdata_list) {
616 list_for_each(list, &sn_sysdata_list) {
617 element = list_entry(list, struct sysdata_el, entry); 613 element = list_entry(list, struct sysdata_el, entry);
618 list_del(&element->entry); 614 list_del(&element->entry);
615 list_del(&(((struct pcidev_info *)
616 (element->sysdata))->pdi_list));
619 kfree(element->sysdata); 617 kfree(element->sysdata);
620 kfree(element); 618 kfree(element);
621 goto sn_sysdata_free_start;
622 } 619 }
623 return; 620 return;
624} 621}
@@ -631,13 +628,8 @@ sn_sysdata_free_start:
631 628
632static int __init sn_pci_init(void) 629static int __init sn_pci_init(void)
633{ 630{
634 int i = 0; 631 int i, j;
635 int j = 0;
636 struct pci_dev *pci_dev = NULL; 632 struct pci_dev *pci_dev = NULL;
637 extern void sn_init_cpei_timer(void);
638#ifdef CONFIG_PROC_FS
639 extern void register_sn_procfs(void);
640#endif
641 633
642 if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) 634 if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM())
643 return 0; 635 return 0;
@@ -693,32 +685,29 @@ static int __init sn_pci_init(void)
693 */ 685 */
694void hubdev_init_node(nodepda_t * npda, cnodeid_t node) 686void hubdev_init_node(nodepda_t * npda, cnodeid_t node)
695{ 687{
696
697 struct hubdev_info *hubdev_info; 688 struct hubdev_info *hubdev_info;
689 int size;
690 pg_data_t *pg;
691
692 size = sizeof(struct hubdev_info);
698 693
699 if (node >= num_online_nodes()) /* Headless/memless IO nodes */ 694 if (node >= num_online_nodes()) /* Headless/memless IO nodes */
700 hubdev_info = 695 pg = NODE_DATA(0);
701 (struct hubdev_info *)alloc_bootmem_node(NODE_DATA(0),
702 sizeof(struct
703 hubdev_info));
704 else 696 else
705 hubdev_info = 697 pg = NODE_DATA(node);
706 (struct hubdev_info *)alloc_bootmem_node(NODE_DATA(node), 698
707 sizeof(struct 699 hubdev_info = (struct hubdev_info *)alloc_bootmem_node(pg, size);
708 hubdev_info));
709 npda->pdinfo = (void *)hubdev_info;
710 700
701 npda->pdinfo = (void *)hubdev_info;
711} 702}
712 703
713geoid_t 704geoid_t
714cnodeid_get_geoid(cnodeid_t cnode) 705cnodeid_get_geoid(cnodeid_t cnode)
715{ 706{
716
717 struct hubdev_info *hubdev; 707 struct hubdev_info *hubdev;
718 708
719 hubdev = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); 709 hubdev = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo);
720 return hubdev->hdi_geoid; 710 return hubdev->hdi_geoid;
721
722} 711}
723 712
724subsys_initcall(sn_pci_init); 713subsys_initcall(sn_pci_init);
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index ec37084bdc17..c373113d073a 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -5,11 +5,12 @@
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/irq.h> 11#include <linux/irq.h>
12#include <linux/spinlock.h> 12#include <linux/spinlock.h>
13#include <linux/init.h>
13#include <asm/sn/addrs.h> 14#include <asm/sn/addrs.h>
14#include <asm/sn/arch.h> 15#include <asm/sn/arch.h>
15#include <asm/sn/intr.h> 16#include <asm/sn/intr.h>
@@ -76,17 +77,15 @@ static void sn_enable_irq(unsigned int irq)
76 77
77static void sn_ack_irq(unsigned int irq) 78static void sn_ack_irq(unsigned int irq)
78{ 79{
79 u64 event_occurred, mask = 0; 80 u64 event_occurred, mask;
80 81
81 irq = irq & 0xff; 82 irq = irq & 0xff;
82 event_occurred = 83 event_occurred = HUB_L((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED));
83 HUB_L((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED));
84 mask = event_occurred & SH_ALL_INT_MASK; 84 mask = event_occurred & SH_ALL_INT_MASK;
85 HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), 85 HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), mask);
86 mask);
87 __set_bit(irq, (volatile void *)pda->sn_in_service_ivecs); 86 __set_bit(irq, (volatile void *)pda->sn_in_service_ivecs);
88 87
89 move_irq(irq); 88 move_native_irq(irq);
90} 89}
91 90
92static void sn_end_irq(unsigned int irq) 91static void sn_end_irq(unsigned int irq)
@@ -219,9 +218,8 @@ static void register_intr_pda(struct sn_irq_info *sn_irq_info)
219 pdacpu(cpu)->sn_last_irq = irq; 218 pdacpu(cpu)->sn_last_irq = irq;
220 } 219 }
221 220
222 if (pdacpu(cpu)->sn_first_irq == 0 || pdacpu(cpu)->sn_first_irq > irq) { 221 if (pdacpu(cpu)->sn_first_irq == 0 || pdacpu(cpu)->sn_first_irq > irq)
223 pdacpu(cpu)->sn_first_irq = irq; 222 pdacpu(cpu)->sn_first_irq = irq;
224 }
225} 223}
226 224
227static void unregister_intr_pda(struct sn_irq_info *sn_irq_info) 225static void unregister_intr_pda(struct sn_irq_info *sn_irq_info)
@@ -289,7 +287,7 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info)
289 list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); 287 list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]);
290 spin_unlock(&sn_irq_info_lock); 288 spin_unlock(&sn_irq_info_lock);
291 289
292 (void)register_intr_pda(sn_irq_info); 290 register_intr_pda(sn_irq_info);
293} 291}
294 292
295void sn_irq_unfixup(struct pci_dev *pci_dev) 293void sn_irq_unfixup(struct pci_dev *pci_dev)
@@ -301,7 +299,9 @@ void sn_irq_unfixup(struct pci_dev *pci_dev)
301 return; 299 return;
302 300
303 sn_irq_info = SN_PCIDEV_INFO(pci_dev)->pdi_sn_irq_info; 301 sn_irq_info = SN_PCIDEV_INFO(pci_dev)->pdi_sn_irq_info;
304 if (!sn_irq_info || !sn_irq_info->irq_irq) { 302 if (!sn_irq_info)
303 return;
304 if (!sn_irq_info->irq_irq) {
305 kfree(sn_irq_info); 305 kfree(sn_irq_info);
306 return; 306 return;
307 } 307 }
@@ -419,7 +419,7 @@ void sn_lb_int_war_check(void)
419 rcu_read_unlock(); 419 rcu_read_unlock();
420} 420}
421 421
422void sn_irq_lh_init(void) 422void __init sn_irq_lh_init(void)
423{ 423{
424 int i; 424 int i;
425 425
@@ -434,5 +434,4 @@ void sn_irq_lh_init(void)
434 434
435 INIT_LIST_HEAD(sn_irq_lh[i]); 435 INIT_LIST_HEAD(sn_irq_lh[i]);
436 } 436 }
437
438} 437}
diff --git a/arch/ia64/sn/kernel/klconflib.c b/arch/ia64/sn/kernel/klconflib.c
index 0f11a3299cd2..87682b48ef83 100644
--- a/arch/ia64/sn/kernel/klconflib.c
+++ b/arch/ia64/sn/kernel/klconflib.c
@@ -78,31 +78,30 @@ format_module_id(char *buffer, moduleid_t m, int fmt)
78 position = MODULE_GET_BPOS(m); 78 position = MODULE_GET_BPOS(m);
79 79
80 if ((fmt == MODULE_FORMAT_BRIEF) || (fmt == MODULE_FORMAT_LCD)) { 80 if ((fmt == MODULE_FORMAT_BRIEF) || (fmt == MODULE_FORMAT_LCD)) {
81 /* Brief module number format, eg. 002c15 */ 81 /* Brief module number format, eg. 002c15 */
82 82
83 /* Decompress the rack number */ 83 /* Decompress the rack number */
84 *buffer++ = '0' + RACK_GET_CLASS(rack); 84 *buffer++ = '0' + RACK_GET_CLASS(rack);
85 *buffer++ = '0' + RACK_GET_GROUP(rack); 85 *buffer++ = '0' + RACK_GET_GROUP(rack);
86 *buffer++ = '0' + RACK_GET_NUM(rack); 86 *buffer++ = '0' + RACK_GET_NUM(rack);
87 87
88 /* Add the brick type */ 88 /* Add the brick type */
89 *buffer++ = brickchar; 89 *buffer++ = brickchar;
90 } 90 }
91 else if (fmt == MODULE_FORMAT_LONG) { 91 else if (fmt == MODULE_FORMAT_LONG) {
92 /* Fuller hwgraph format, eg. rack/002/bay/15 */ 92 /* Fuller hwgraph format, eg. rack/002/bay/15 */
93 93
94 strcpy(buffer, "rack" "/"); buffer += strlen(buffer); 94 strcpy(buffer, "rack" "/"); buffer += strlen(buffer);
95 95
96 *buffer++ = '0' + RACK_GET_CLASS(rack); 96 *buffer++ = '0' + RACK_GET_CLASS(rack);
97 *buffer++ = '0' + RACK_GET_GROUP(rack); 97 *buffer++ = '0' + RACK_GET_GROUP(rack);
98 *buffer++ = '0' + RACK_GET_NUM(rack); 98 *buffer++ = '0' + RACK_GET_NUM(rack);
99 99
100 strcpy(buffer, "/" "bay" "/"); buffer += strlen(buffer); 100 strcpy(buffer, "/" "bay" "/"); buffer += strlen(buffer);
101 } 101 }
102 102
103 /* Add the bay position, using at least two digits */ 103 /* Add the bay position, using at least two digits */
104 if (position < 10) 104 if (position < 10)
105 *buffer++ = '0'; 105 *buffer++ = '0';
106 sprintf(buffer, "%d", position); 106 sprintf(buffer, "%d", position);
107
108} 107}
diff --git a/arch/ia64/sn/kernel/mca.c b/arch/ia64/sn/kernel/mca.c
index 9ab684d1bb55..3db62f24596c 100644
--- a/arch/ia64/sn/kernel/mca.c
+++ b/arch/ia64/sn/kernel/mca.c
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. 6 * Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
7 */ 7 */
8 8
9#include <linux/types.h> 9#include <linux/types.h>
@@ -137,7 +137,8 @@ int sn_salinfo_platform_oemdata(const u8 *sect_header, u8 **oemdata, u64 *oemdat
137 137
138static int __init sn_salinfo_init(void) 138static int __init sn_salinfo_init(void)
139{ 139{
140 salinfo_platform_oemdata = &sn_salinfo_platform_oemdata; 140 if (ia64_platform_is("sn2"))
141 salinfo_platform_oemdata = &sn_salinfo_platform_oemdata;
141 return 0; 142 return 0;
142} 143}
143 144
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index e510dce9971f..5b84836c2171 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -67,6 +67,7 @@ extern unsigned long last_time_offset;
67extern void (*ia64_mark_idle) (int); 67extern void (*ia64_mark_idle) (int);
68extern void snidle(int); 68extern void snidle(int);
69extern unsigned char acpi_kbd_controller_present; 69extern unsigned char acpi_kbd_controller_present;
70extern unsigned long long (*ia64_printk_clock)(void);
70 71
71unsigned long sn_rtc_cycles_per_second; 72unsigned long sn_rtc_cycles_per_second;
72EXPORT_SYMBOL(sn_rtc_cycles_per_second); 73EXPORT_SYMBOL(sn_rtc_cycles_per_second);
@@ -74,7 +75,7 @@ EXPORT_SYMBOL(sn_rtc_cycles_per_second);
74DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info); 75DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info);
75EXPORT_PER_CPU_SYMBOL(__sn_hub_info); 76EXPORT_PER_CPU_SYMBOL(__sn_hub_info);
76 77
77DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_NUMNODES]); 78DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]);
78EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid); 79EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid);
79 80
80DEFINE_PER_CPU(struct nodepda_s *, __sn_nodepda); 81DEFINE_PER_CPU(struct nodepda_s *, __sn_nodepda);
@@ -125,20 +126,6 @@ struct screen_info sn_screen_info = {
125}; 126};
126 127
127/* 128/*
128 * This is here so we can use the CMOS detection in ide-probe.c to
129 * determine what drives are present. In theory, we don't need this
130 * as the auto-detection could be done via ide-probe.c:do_probe() but
131 * in practice that would be much slower, which is painful when
132 * running in the simulator. Note that passing zeroes in DRIVE_INFO
133 * is sufficient (the IDE driver will autodetect the drive geometry).
134 */
135#ifdef CONFIG_IA64_GENERIC
136extern char drive_info[4 * 16];
137#else
138char drive_info[4 * 16];
139#endif
140
141/*
142 * This routine can only be used during init, since 129 * This routine can only be used during init, since
143 * smp_boot_data is an init data structure. 130 * smp_boot_data is an init data structure.
144 * We have to use smp_boot_data.cpu_phys_id to find 131 * We have to use smp_boot_data.cpu_phys_id to find
@@ -209,7 +196,7 @@ void __init early_sn_setup(void)
209} 196}
210 197
211extern int platform_intr_list[]; 198extern int platform_intr_list[];
212static int __initdata shub_1_1_found = 0; 199static int __initdata shub_1_1_found;
213 200
214/* 201/*
215 * sn_check_for_wars 202 * sn_check_for_wars
@@ -330,6 +317,7 @@ struct pcdp_vga_device {
330#define PCDP_PCI_TRANS_IOPORT 0x02 317#define PCDP_PCI_TRANS_IOPORT 0x02
331#define PCDP_PCI_TRANS_MMIO 0x01 318#define PCDP_PCI_TRANS_MMIO 0x01
332 319
320#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
333static void 321static void
334sn_scan_pcdp(void) 322sn_scan_pcdp(void)
335{ 323{
@@ -371,6 +359,17 @@ sn_scan_pcdp(void)
371 break; /* once we find the primary, we're done */ 359 break; /* once we find the primary, we're done */
372 } 360 }
373} 361}
362#endif
363
364static unsigned long sn2_rtc_initial;
365
366static unsigned long long ia64_sn2_printk_clock(void)
367{
368 unsigned long rtc_now = rtc_time();
369
370 return (rtc_now - sn2_rtc_initial) *
371 (1000000000 / sn_rtc_cycles_per_second);
372}
374 373
375/** 374/**
376 * sn_setup - SN platform setup routine 375 * sn_setup - SN platform setup routine
@@ -386,6 +385,7 @@ void __init sn_setup(char **cmdline_p)
386 u32 version = sn_sal_rev(); 385 u32 version = sn_sal_rev();
387 extern void sn_cpu_init(void); 386 extern void sn_cpu_init(void);
388 387
388 sn2_rtc_initial = rtc_time();
389 ia64_sn_plat_set_error_handling_features(); // obsolete 389 ia64_sn_plat_set_error_handling_features(); // obsolete
390 ia64_sn_set_os_feature(OSF_MCA_SLV_TO_OS_INIT_SLV); 390 ia64_sn_set_os_feature(OSF_MCA_SLV_TO_OS_INIT_SLV);
391 ia64_sn_set_os_feature(OSF_FEAT_LOG_SBES); 391 ia64_sn_set_os_feature(OSF_FEAT_LOG_SBES);
@@ -437,19 +437,6 @@ void __init sn_setup(char **cmdline_p)
437 */ 437 */
438 build_cnode_tables(); 438 build_cnode_tables();
439 439
440 /*
441 * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard
442 * support here so we don't have to listen to failed keyboard probe
443 * messages.
444 */
445 if (version <= 0x0209 && acpi_kbd_controller_present) {
446 printk(KERN_INFO "Disabling legacy keyboard support as prom "
447 "is too old and doesn't provide FADT\n");
448 acpi_kbd_controller_present = 0;
449 }
450
451 printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);
452
453 status = 440 status =
454 ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec, 441 ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
455 &drift); 442 &drift);
@@ -463,6 +450,21 @@ void __init sn_setup(char **cmdline_p)
463 450
464 platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR; 451 platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR;
465 452
453 ia64_printk_clock = ia64_sn2_printk_clock;
454
455 /*
456 * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard
457 * support here so we don't have to listen to failed keyboard probe
458 * messages.
459 */
460 if (version <= 0x0209 && acpi_kbd_controller_present) {
461 printk(KERN_INFO "Disabling legacy keyboard support as prom "
462 "is too old and doesn't provide FADT\n");
463 acpi_kbd_controller_present = 0;
464 }
465
466 printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);
467
466 /* 468 /*
467 * we set the default root device to /dev/hda 469 * we set the default root device to /dev/hda
468 * to make simulation easy 470 * to make simulation easy
@@ -578,13 +580,17 @@ void __init sn_cpu_init(void)
578 sn_prom_type = 2; 580 sn_prom_type = 2;
579 else 581 else
580 sn_prom_type = 1; 582 sn_prom_type = 1;
581 printk("Running on medusa with %s PROM\n", (sn_prom_type == 1) ? "real" : "fake"); 583 printk(KERN_INFO "Running on medusa with %s PROM\n",
584 (sn_prom_type == 1) ? "real" : "fake");
582 } 585 }
583 586
584 memset(pda, 0, sizeof(pda)); 587 memset(pda, 0, sizeof(pda));
585 if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, &sn_hub_info->nasid_bitmask, &sn_hub_info->nasid_shift, 588 if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2,
586 &sn_system_size, &sn_sharing_domain_size, &sn_partition_id, 589 &sn_hub_info->nasid_bitmask,
587 &sn_coherency_id, &sn_region_size)) 590 &sn_hub_info->nasid_shift,
591 &sn_system_size, &sn_sharing_domain_size,
592 &sn_partition_id, &sn_coherency_id,
593 &sn_region_size))
588 BUG(); 594 BUG();
589 sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2; 595 sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2;
590 596
@@ -716,7 +722,8 @@ void __init build_cnode_tables(void)
716 for_each_online_node(node) { 722 for_each_online_node(node) {
717 kl_config_hdr_t *klgraph_header; 723 kl_config_hdr_t *klgraph_header;
718 nasid = cnodeid_to_nasid(node); 724 nasid = cnodeid_to_nasid(node);
719 if ((klgraph_header = ia64_sn_get_klconfig_addr(nasid)) == NULL) 725 klgraph_header = ia64_sn_get_klconfig_addr(nasid);
726 if (klgraph_header == NULL)
720 BUG(); 727 BUG();
721 brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info); 728 brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info);
722 while (brd) { 729 while (brd) {
@@ -734,7 +741,7 @@ nasid_slice_to_cpuid(int nasid, int slice)
734{ 741{
735 long cpu; 742 long cpu;
736 743
737 for (cpu=0; cpu < NR_CPUS; cpu++) 744 for (cpu = 0; cpu < NR_CPUS; cpu++)
738 if (cpuid_to_nasid(cpu) == nasid && 745 if (cpuid_to_nasid(cpu) == nasid &&
739 cpuid_to_slice(cpu) == slice) 746 cpuid_to_slice(cpu) == slice)
740 return cpu; 747 return cpu;
diff --git a/arch/ia64/sn/kernel/sn2/Makefile b/arch/ia64/sn/kernel/sn2/Makefile
index 170bde4549da..99e177693234 100644
--- a/arch/ia64/sn/kernel/sn2/Makefile
+++ b/arch/ia64/sn/kernel/sn2/Makefile
@@ -9,5 +9,7 @@
9# sn2 specific kernel files 9# sn2 specific kernel files
10# 10#
11 11
12CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
13
12obj-y += cache.o io.o ptc_deadlock.o sn2_smp.o sn_proc_fs.o \ 14obj-y += cache.o io.o ptc_deadlock.o sn2_smp.o sn_proc_fs.o \
13 prominfo_proc.o timer.o timer_interrupt.o sn_hwperf.o 15 prominfo_proc.o timer.o timer_interrupt.o sn_hwperf.o
diff --git a/arch/ia64/sn/kernel/sn2/prominfo_proc.c b/arch/ia64/sn/kernel/sn2/prominfo_proc.c
index 81c63b2f8ae9..6ae276d5d50c 100644
--- a/arch/ia64/sn/kernel/sn2/prominfo_proc.c
+++ b/arch/ia64/sn/kernel/sn2/prominfo_proc.c
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 1999,2001-2004 Silicon Graphics, Inc. All Rights Reserved. 6 * Copyright (C) 1999,2001-2004, 2006 Silicon Graphics, Inc. All Rights Reserved.
7 * 7 *
8 * Module to export the system's Firmware Interface Tables, including 8 * Module to export the system's Firmware Interface Tables, including
9 * PROM revision numbers and banners, in /proc 9 * PROM revision numbers and banners, in /proc
@@ -190,7 +190,7 @@ static int
190read_version_entry(char *page, char **start, off_t off, int count, int *eof, 190read_version_entry(char *page, char **start, off_t off, int count, int *eof,
191 void *data) 191 void *data)
192{ 192{
193 int len = 0; 193 int len;
194 194
195 /* data holds the NASID of the node */ 195 /* data holds the NASID of the node */
196 len = dump_version(page, (unsigned long)data); 196 len = dump_version(page, (unsigned long)data);
@@ -202,7 +202,7 @@ static int
202read_fit_entry(char *page, char **start, off_t off, int count, int *eof, 202read_fit_entry(char *page, char **start, off_t off, int count, int *eof,
203 void *data) 203 void *data)
204{ 204{
205 int len = 0; 205 int len;
206 206
207 /* data holds the NASID of the node */ 207 /* data holds the NASID of the node */
208 len = dump_fit(page, (unsigned long)data); 208 len = dump_fit(page, (unsigned long)data);
@@ -229,13 +229,16 @@ int __init prominfo_init(void)
229 struct proc_dir_entry *p; 229 struct proc_dir_entry *p;
230 cnodeid_t cnodeid; 230 cnodeid_t cnodeid;
231 unsigned long nasid; 231 unsigned long nasid;
232 int size;
232 char name[NODE_NAME_LEN]; 233 char name[NODE_NAME_LEN];
233 234
234 if (!ia64_platform_is("sn2")) 235 if (!ia64_platform_is("sn2"))
235 return 0; 236 return 0;
236 237
237 proc_entries = kmalloc(num_online_nodes() * sizeof(struct proc_dir_entry *), 238 size = num_online_nodes() * sizeof(struct proc_dir_entry *);
238 GFP_KERNEL); 239 proc_entries = kzalloc(size, GFP_KERNEL);
240 if (!proc_entries)
241 return -ENOMEM;
239 242
240 sgi_prominfo_entry = proc_mkdir("sgi_prominfo", NULL); 243 sgi_prominfo_entry = proc_mkdir("sgi_prominfo", NULL);
241 244
@@ -244,14 +247,12 @@ int __init prominfo_init(void)
244 sprintf(name, "node%d", cnodeid); 247 sprintf(name, "node%d", cnodeid);
245 *entp = proc_mkdir(name, sgi_prominfo_entry); 248 *entp = proc_mkdir(name, sgi_prominfo_entry);
246 nasid = cnodeid_to_nasid(cnodeid); 249 nasid = cnodeid_to_nasid(cnodeid);
247 p = create_proc_read_entry( 250 p = create_proc_read_entry("fit", 0, *entp, read_fit_entry,
248 "fit", 0, *entp, read_fit_entry, 251 (void *)nasid);
249 (void *)nasid);
250 if (p) 252 if (p)
251 p->owner = THIS_MODULE; 253 p->owner = THIS_MODULE;
252 p = create_proc_read_entry( 254 p = create_proc_read_entry("version", 0, *entp,
253 "version", 0, *entp, read_version_entry, 255 read_version_entry, (void *)nasid);
254 (void *)nasid);
255 if (p) 256 if (p)
256 p->owner = THIS_MODULE; 257 p->owner = THIS_MODULE;
257 entp++; 258 entp++;
@@ -263,7 +264,7 @@ int __init prominfo_init(void)
263void __exit prominfo_exit(void) 264void __exit prominfo_exit(void)
264{ 265{
265 struct proc_dir_entry **entp; 266 struct proc_dir_entry **entp;
266 unsigned cnodeid; 267 unsigned int cnodeid;
267 char name[NODE_NAME_LEN]; 268 char name[NODE_NAME_LEN];
268 269
269 entp = proc_entries; 270 entp = proc_entries;
diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c
index 471bbaa65d1b..b2e1e746b47f 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,24 @@ DECLARE_PER_CPU(struct ptc_stats, ptcstats);
46 46
47static __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock); 47static __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock);
48 48
49void sn2_ptc_deadlock_recovery(short *, short, int, volatile unsigned long *, unsigned long data0, 49extern unsigned long
50 volatile unsigned long *, unsigned long data1); 50sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long,
51 volatile unsigned long *, unsigned long,
52 volatile unsigned long *, unsigned long);
53void
54sn2_ptc_deadlock_recovery(short *, short, short, int,
55 volatile unsigned long *, unsigned long,
56 volatile unsigned long *, unsigned long);
51 57
52#ifdef DEBUG_PTC
53/* 58/*
54 * ptctest: 59 * Note: some is the following is captured here to make degugging easier
55 * 60 * (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 */ 61 */
70
71static unsigned int sn2_ptctest = 0;
72
73static int __init ptc_test(char *str)
74{
75 get_option(&str, &sn2_ptctest);
76 return 1;
77}
78__setup("ptctest=", ptc_test);
79
80static 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
108static 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 62#define sn2_ptctest 0
135 63#define local_node_uses_ptc_ga(sh1) ((sh1) ? 1 : 0)
136static inline int ptc_lock(unsigned long *flagp) 64#define max_active_pio(sh1) ((sh1) ? 32 : 7)
137{ 65#define reset_max_active_on_deadlock() 1
138 spin_lock_irqsave(&sn2_global_ptc_lock, *flagp); 66#define PTC_LOCK(sh1) ((sh1) ? &sn2_global_ptc_lock : &sn_nodepda->ptc_lock)
139 return 0;
140}
141
142static inline void ptc_unlock(unsigned long flags, int opt)
143{
144 spin_unlock_irqrestore(&sn2_global_ptc_lock, flags);
145}
146#endif
147 67
148struct ptc_stats { 68struct ptc_stats {
149 unsigned long ptc_l; 69 unsigned long ptc_l;
@@ -151,27 +71,32 @@ struct ptc_stats {
151 unsigned long shub_ptc_flushes; 71 unsigned long shub_ptc_flushes;
152 unsigned long nodes_flushed; 72 unsigned long nodes_flushed;
153 unsigned long deadlocks; 73 unsigned long deadlocks;
74 unsigned long deadlocks2;
154 unsigned long lock_itc_clocks; 75 unsigned long lock_itc_clocks;
155 unsigned long shub_itc_clocks; 76 unsigned long shub_itc_clocks;
156 unsigned long shub_itc_clocks_max; 77 unsigned long shub_itc_clocks_max;
78 unsigned long shub_ptc_flushes_not_my_mm;
157}; 79};
158 80
81#define sn2_ptctest 0
82
159static inline unsigned long wait_piowc(void) 83static inline unsigned long wait_piowc(void)
160{ 84{
161 volatile unsigned long *piows, zeroval; 85 volatile unsigned long *piows;
162 unsigned long ws; 86 unsigned long zeroval, ws;
163 87
164 piows = pda->pio_write_status_addr; 88 piows = pda->pio_write_status_addr;
165 zeroval = pda->pio_write_status_val; 89 zeroval = pda->pio_write_status_val;
166 do { 90 do {
167 cpu_relax(); 91 cpu_relax();
168 } while (((ws = *piows) & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != zeroval); 92 } while (((ws = *piows) & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != zeroval);
169 return ws; 93 return (ws & SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK) != 0;
170} 94}
171 95
172void sn_tlb_migrate_finish(struct mm_struct *mm) 96void sn_tlb_migrate_finish(struct mm_struct *mm)
173{ 97{
174 if (mm == current->mm) 98 /* flush_tlb_mm is inefficient if more than 1 users of mm */
99 if (mm == current->mm && mm && atomic_read(&mm->mm_users) == 1)
175 flush_tlb_mm(mm); 100 flush_tlb_mm(mm);
176} 101}
177 102
@@ -201,12 +126,14 @@ void
201sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, 126sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
202 unsigned long end, unsigned long nbits) 127 unsigned long end, unsigned long nbits)
203{ 128{
204 int i, opt, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0; 129 int i, ibegin, shub1, cnode, mynasid, cpu, lcpu = 0, nasid;
205 int mymm = (mm == current->active_mm && current->mm); 130 int mymm = (mm == current->active_mm && mm == current->mm);
131 int use_cpu_ptcga;
206 volatile unsigned long *ptc0, *ptc1; 132 volatile unsigned long *ptc0, *ptc1;
207 unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value; 133 unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value, old_rr = 0;
208 short nasids[MAX_NUMNODES], nix; 134 short nasids[MAX_NUMNODES], nix;
209 nodemask_t nodes_flushed; 135 nodemask_t nodes_flushed;
136 int active, max_active, deadlock;
210 137
211 nodes_clear(nodes_flushed); 138 nodes_clear(nodes_flushed);
212 i = 0; 139 i = 0;
@@ -267,41 +194,56 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
267 194
268 195
269 mynasid = get_nasid(); 196 mynasid = get_nasid();
197 use_cpu_ptcga = local_node_uses_ptc_ga(shub1);
198 max_active = max_active_pio(shub1);
270 199
271 itc = ia64_get_itc(); 200 itc = ia64_get_itc();
272 opt = ptc_lock(&flags); 201 spin_lock_irqsave(PTC_LOCK(shub1), flags);
273 itc2 = ia64_get_itc(); 202 itc2 = ia64_get_itc();
203
274 __get_cpu_var(ptcstats).lock_itc_clocks += itc2 - itc; 204 __get_cpu_var(ptcstats).lock_itc_clocks += itc2 - itc;
275 __get_cpu_var(ptcstats).shub_ptc_flushes++; 205 __get_cpu_var(ptcstats).shub_ptc_flushes++;
276 __get_cpu_var(ptcstats).nodes_flushed += nix; 206 __get_cpu_var(ptcstats).nodes_flushed += nix;
207 if (!mymm)
208 __get_cpu_var(ptcstats).shub_ptc_flushes_not_my_mm++;
277 209
210 if (use_cpu_ptcga && !mymm) {
211 old_rr = ia64_get_rr(start);
212 ia64_set_rr(start, (old_rr & 0xff) | (rr_value << 8));
213 ia64_srlz_d();
214 }
215
216 wait_piowc();
278 do { 217 do {
279 if (shub1) 218 if (shub1)
280 data1 = start | (1UL << SH1_PTC_1_START_SHFT); 219 data1 = start | (1UL << SH1_PTC_1_START_SHFT);
281 else 220 else
282 data0 = (data0 & ~SH2_PTC_ADDR_MASK) | (start & SH2_PTC_ADDR_MASK); 221 data0 = (data0 & ~SH2_PTC_ADDR_MASK) | (start & SH2_PTC_ADDR_MASK);
283 for (i = 0; i < nix; i++) { 222 deadlock = 0;
223 active = 0;
224 for (ibegin = 0, i = 0; i < nix; i++) {
284 nasid = nasids[i]; 225 nasid = nasids[i];
285 if ((!(sn2_ptctest & 3)) && unlikely(nasid == mynasid && mymm)) { 226 if (use_cpu_ptcga && unlikely(nasid == mynasid)) {
286 ia64_ptcga(start, nbits << 2); 227 ia64_ptcga(start, nbits << 2);
287 ia64_srlz_i(); 228 ia64_srlz_i();
288 } else { 229 } else {
289 ptc0 = CHANGE_NASID(nasid, ptc0); 230 ptc0 = CHANGE_NASID(nasid, ptc0);
290 if (ptc1) 231 if (ptc1)
291 ptc1 = CHANGE_NASID(nasid, ptc1); 232 ptc1 = CHANGE_NASID(nasid, ptc1);
292 pio_atomic_phys_write_mmrs(ptc0, data0, ptc1, 233 pio_atomic_phys_write_mmrs(ptc0, data0, ptc1, data1);
293 data1); 234 active++;
294 flushed = 1; 235 }
236 if (active >= max_active || i == (nix - 1)) {
237 if ((deadlock = wait_piowc())) {
238 sn2_ptc_deadlock_recovery(nasids, ibegin, i, mynasid, ptc0, data0, ptc1, data1);
239 if (reset_max_active_on_deadlock())
240 max_active = 1;
241 }
242 active = 0;
243 ibegin = i + 1;
295 } 244 }
296 } 245 }
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); 246 start += (1UL << nbits);
304
305 } while (start < end); 247 } while (start < end);
306 248
307 itc2 = ia64_get_itc() - itc2; 249 itc2 = ia64_get_itc() - itc2;
@@ -309,7 +251,12 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
309 if (itc2 > __get_cpu_var(ptcstats).shub_itc_clocks_max) 251 if (itc2 > __get_cpu_var(ptcstats).shub_itc_clocks_max)
310 __get_cpu_var(ptcstats).shub_itc_clocks_max = itc2; 252 __get_cpu_var(ptcstats).shub_itc_clocks_max = itc2;
311 253
312 ptc_unlock(flags, opt); 254 if (old_rr) {
255 ia64_set_rr(start, old_rr);
256 ia64_srlz_d();
257 }
258
259 spin_unlock_irqrestore(PTC_LOCK(shub1), flags);
313 260
314 preempt_enable(); 261 preempt_enable();
315} 262}
@@ -321,27 +268,31 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
321 * TLB flush transaction. The recovery sequence is somewhat tricky & is 268 * TLB flush transaction. The recovery sequence is somewhat tricky & is
322 * coded in assembly language. 269 * coded in assembly language.
323 */ 270 */
324void sn2_ptc_deadlock_recovery(short *nasids, short nix, int mynasid, volatile unsigned long *ptc0, unsigned long data0, 271
325 volatile unsigned long *ptc1, unsigned long data1) 272void
273sn2_ptc_deadlock_recovery(short *nasids, short ib, short ie, int mynasid,
274 volatile unsigned long *ptc0, unsigned long data0,
275 volatile unsigned long *ptc1, unsigned long data1)
326{ 276{
327 extern void sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long,
328 volatile unsigned long *, unsigned long, volatile unsigned long *, unsigned long);
329 short nasid, i; 277 short nasid, i;
330 unsigned long *piows, zeroval; 278 unsigned long *piows, zeroval, n;
331 279
332 __get_cpu_var(ptcstats).deadlocks++; 280 __get_cpu_var(ptcstats).deadlocks++;
333 281
334 piows = (unsigned long *) pda->pio_write_status_addr; 282 piows = (unsigned long *) pda->pio_write_status_addr;
335 zeroval = pda->pio_write_status_val; 283 zeroval = pda->pio_write_status_val;
336 284
337 for (i=0; i < nix; i++) { 285
286 for (i=ib; i <= ie; i++) {
338 nasid = nasids[i]; 287 nasid = nasids[i];
339 if (!(sn2_ptctest & 3) && nasid == mynasid) 288 if (local_node_uses_ptc_ga(is_shub1()) && nasid == mynasid)
340 continue; 289 continue;
341 ptc0 = CHANGE_NASID(nasid, ptc0); 290 ptc0 = CHANGE_NASID(nasid, ptc0);
342 if (ptc1) 291 if (ptc1)
343 ptc1 = CHANGE_NASID(nasid, ptc1); 292 ptc1 = CHANGE_NASID(nasid, ptc1);
344 sn2_ptc_deadlock_recovery_core(ptc0, data0, ptc1, data1, piows, zeroval); 293
294 n = sn2_ptc_deadlock_recovery_core(ptc0, data0, ptc1, data1, piows, zeroval);
295 __get_cpu_var(ptcstats).deadlocks2 += n;
345 } 296 }
346 297
347} 298}
@@ -452,20 +403,22 @@ static int sn2_ptc_seq_show(struct seq_file *file, void *data)
452 cpu = *(loff_t *) data; 403 cpu = *(loff_t *) data;
453 404
454 if (!cpu) { 405 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"); 406 seq_printf(file,
407 "# 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); 408 seq_printf(file, "# ptctest %d\n", sn2_ptctest);
457 } 409 }
458 410
459 if (cpu < NR_CPUS && cpu_online(cpu)) { 411 if (cpu < NR_CPUS && cpu_online(cpu)) {
460 stat = &per_cpu(ptcstats, cpu); 412 stat = &per_cpu(ptcstats, cpu);
461 seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l, 413 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, 414 stat->change_rid, stat->shub_ptc_flushes, stat->nodes_flushed,
463 stat->deadlocks, 415 stat->deadlocks,
464 1000 * stat->lock_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec, 416 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, 417 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); 418 1000 * stat->shub_itc_clocks_max / per_cpu(cpu_info, cpu).cyc_per_usec,
419 stat->shub_ptc_flushes_not_my_mm,
420 stat->deadlocks2);
467 } 421 }
468
469 return 0; 422 return 0;
470} 423}
471 424
@@ -476,7 +429,7 @@ static struct seq_operations sn2_ptc_seq_ops = {
476 .show = sn2_ptc_seq_show 429 .show = sn2_ptc_seq_show
477}; 430};
478 431
479int sn2_ptc_proc_open(struct inode *inode, struct file *file) 432static int sn2_ptc_proc_open(struct inode *inode, struct file *file)
480{ 433{
481 return seq_open(file, &sn2_ptc_seq_ops); 434 return seq_open(file, &sn2_ptc_seq_ops);
482} 435}
@@ -493,7 +446,7 @@ static struct proc_dir_entry *proc_sn2_ptc;
493static int __init sn2_ptc_init(void) 446static int __init sn2_ptc_init(void)
494{ 447{
495 if (!ia64_platform_is("sn2")) 448 if (!ia64_platform_is("sn2"))
496 return -ENOSYS; 449 return 0;
497 450
498 if (!(proc_sn2_ptc = create_proc_entry(PTC_BASENAME, 0444, NULL))) { 451 if (!(proc_sn2_ptc = create_proc_entry(PTC_BASENAME, 0444, NULL))) {
499 printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME); 452 printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME);
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
index 19b54fbcd7ea..70db21f3df21 100644
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 2004-2005 Silicon Graphics, Inc. All rights reserved. 6 * Copyright (C) 2004-2006 Silicon Graphics, Inc. All rights reserved.
7 * 7 *
8 * SGI Altix topology and hardware performance monitoring API. 8 * SGI Altix topology and hardware performance monitoring API.
9 * Mark Goodwin <markgw@sgi.com>. 9 * Mark Goodwin <markgw@sgi.com>.
@@ -973,6 +973,9 @@ static int __devinit sn_hwperf_misc_register_init(void)
973{ 973{
974 int e; 974 int e;
975 975
976 if (!ia64_platform_is("sn2"))
977 return 0;
978
976 sn_hwperf_init(); 979 sn_hwperf_init();
977 980
978 /* 981 /*
diff --git a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
index a06719d752a0..c686d9c12f7b 100644
--- a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
+++ b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
@@ -6,11 +6,11 @@
6 * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved. 6 * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
7 */ 7 */
8#include <linux/config.h> 8#include <linux/config.h>
9#include <asm/uaccess.h>
10 9
11#ifdef CONFIG_PROC_FS 10#ifdef CONFIG_PROC_FS
12#include <linux/proc_fs.h> 11#include <linux/proc_fs.h>
13#include <linux/seq_file.h> 12#include <linux/seq_file.h>
13#include <asm/uaccess.h>
14#include <asm/sn/sn_sal.h> 14#include <asm/sn/sn_sal.h>
15 15
16static int partition_id_show(struct seq_file *s, void *p) 16static int partition_id_show(struct seq_file *s, void *p)
@@ -90,10 +90,10 @@ static int coherence_id_open(struct inode *inode, struct file *file)
90 return single_open(file, coherence_id_show, NULL); 90 return single_open(file, coherence_id_show, NULL);
91} 91}
92 92
93static struct proc_dir_entry *sn_procfs_create_entry( 93static struct proc_dir_entry
94 const char *name, struct proc_dir_entry *parent, 94*sn_procfs_create_entry(const char *name, struct proc_dir_entry *parent,
95 int (*openfunc)(struct inode *, struct file *), 95 int (*openfunc)(struct inode *, struct file *),
96 int (*releasefunc)(struct inode *, struct file *)) 96 int (*releasefunc)(struct inode *, struct file *))
97{ 97{
98 struct proc_dir_entry *e = create_proc_entry(name, 0444, parent); 98 struct proc_dir_entry *e = create_proc_entry(name, 0444, parent);
99 99
@@ -126,24 +126,24 @@ void register_sn_procfs(void)
126 return; 126 return;
127 127
128 sn_procfs_create_entry("partition_id", sgi_proc_dir, 128 sn_procfs_create_entry("partition_id", sgi_proc_dir,
129 partition_id_open, single_release); 129 partition_id_open, single_release);
130 130
131 sn_procfs_create_entry("system_serial_number", sgi_proc_dir, 131 sn_procfs_create_entry("system_serial_number", sgi_proc_dir,
132 system_serial_number_open, single_release); 132 system_serial_number_open, single_release);
133 133
134 sn_procfs_create_entry("licenseID", sgi_proc_dir, 134 sn_procfs_create_entry("licenseID", sgi_proc_dir,
135 licenseID_open, single_release); 135 licenseID_open, single_release);
136 136
137 e = sn_procfs_create_entry("sn_force_interrupt", sgi_proc_dir, 137 e = sn_procfs_create_entry("sn_force_interrupt", sgi_proc_dir,
138 sn_force_interrupt_open, single_release); 138 sn_force_interrupt_open, single_release);
139 if (e) 139 if (e)
140 e->proc_fops->write = sn_force_interrupt_write_proc; 140 e->proc_fops->write = sn_force_interrupt_write_proc;
141 141
142 sn_procfs_create_entry("coherence_id", sgi_proc_dir, 142 sn_procfs_create_entry("coherence_id", sgi_proc_dir,
143 coherence_id_open, single_release); 143 coherence_id_open, single_release);
144 144
145 sn_procfs_create_entry("sn_topology", sgi_proc_dir, 145 sn_procfs_create_entry("sn_topology", sgi_proc_dir,
146 sn_topology_open, sn_topology_release); 146 sn_topology_open, sn_topology_release);
147} 147}
148 148
149#endif /* CONFIG_PROC_FS */ 149#endif /* CONFIG_PROC_FS */
diff --git a/arch/ia64/sn/kernel/sn2/timer.c b/arch/ia64/sn/kernel/sn2/timer.c
index deb9baf4d473..56a88b6df4b4 100644
--- a/arch/ia64/sn/kernel/sn2/timer.c
+++ b/arch/ia64/sn/kernel/sn2/timer.c
@@ -14,6 +14,7 @@
14 14
15#include <asm/hw_irq.h> 15#include <asm/hw_irq.h>
16#include <asm/system.h> 16#include <asm/system.h>
17#include <asm/timex.h>
17 18
18#include <asm/sn/leds.h> 19#include <asm/sn/leds.h>
19#include <asm/sn/shub_mmr.h> 20#include <asm/sn/shub_mmr.h>
@@ -28,9 +29,27 @@ static struct time_interpolator sn2_interpolator = {
28 .source = TIME_SOURCE_MMIO64 29 .source = TIME_SOURCE_MMIO64
29}; 30};
30 31
32/*
33 * sn udelay uses the RTC instead of the ITC because the ITC is not
34 * synchronized across all CPUs, and the thread may migrate to another CPU
35 * if preemption is enabled.
36 */
37static void
38ia64_sn_udelay (unsigned long usecs)
39{
40 unsigned long start = rtc_time();
41 unsigned long end = start +
42 usecs * sn_rtc_cycles_per_second / 1000000;
43
44 while (time_before((unsigned long)rtc_time(), end))
45 cpu_relax();
46}
47
31void __init sn_timer_init(void) 48void __init sn_timer_init(void)
32{ 49{
33 sn2_interpolator.frequency = sn_rtc_cycles_per_second; 50 sn2_interpolator.frequency = sn_rtc_cycles_per_second;
34 sn2_interpolator.addr = RTC_COUNTER_ADDR; 51 sn2_interpolator.addr = RTC_COUNTER_ADDR;
35 register_time_interpolator(&sn2_interpolator); 52 register_time_interpolator(&sn2_interpolator);
53
54 ia64_udelay = &ia64_sn_udelay;
36} 55}
diff --git a/arch/ia64/sn/kernel/sn2/timer_interrupt.c b/arch/ia64/sn/kernel/sn2/timer_interrupt.c
index adf5db2e2afe..fa7f69945917 100644
--- a/arch/ia64/sn/kernel/sn2/timer_interrupt.c
+++ b/arch/ia64/sn/kernel/sn2/timer_interrupt.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * 2 *
3 * 3 *
4 * Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved. 4 * Copyright (c) 2005, 2006 Silicon Graphics, Inc. All Rights Reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of version 2 of the GNU General Public License 7 * under the terms of version 2 of the GNU General Public License
@@ -22,11 +22,6 @@
22 * License along with this program; if not, write the Free Software 22 * License along with this program; if not, write the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
24 * 24 *
25 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
26 * Mountain View, CA 94043, or:
27 *
28 * http://www.sgi.com
29 *
30 * For further information regarding this notice, see: 25 * For further information regarding this notice, see:
31 * 26 *
32 * http://oss.sgi.com/projects/GenInfo/NoticeExplan 27 * http://oss.sgi.com/projects/GenInfo/NoticeExplan
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c
index d263d3e8fbb9..99cb28e74295 100644
--- a/arch/ia64/sn/kernel/tiocx.c
+++ b/arch/ia64/sn/kernel/tiocx.c
@@ -284,12 +284,10 @@ struct sn_irq_info *tiocx_irq_alloc(nasid_t nasid, int widget, int irq,
284 if ((nasid & 1) == 0) 284 if ((nasid & 1) == 0)
285 return NULL; 285 return NULL;
286 286
287 sn_irq_info = kmalloc(sn_irq_size, GFP_KERNEL); 287 sn_irq_info = kzalloc(sn_irq_size, GFP_KERNEL);
288 if (sn_irq_info == NULL) 288 if (sn_irq_info == NULL)
289 return NULL; 289 return NULL;
290 290
291 memset(sn_irq_info, 0x0, sn_irq_size);
292
293 status = tiocx_intr_alloc(nasid, widget, __pa(sn_irq_info), irq, 291 status = tiocx_intr_alloc(nasid, widget, __pa(sn_irq_info), irq,
294 req_nasid, slice); 292 req_nasid, slice);
295 if (status) { 293 if (status) {
@@ -486,7 +484,7 @@ static int __init tiocx_init(void)
486 int found_tiocx_device = 0; 484 int found_tiocx_device = 0;
487 485
488 if (!ia64_platform_is("sn2")) 486 if (!ia64_platform_is("sn2"))
489 return -ENODEV; 487 return 0;
490 488
491 bus_register(&tiocx_bus_type); 489 bus_register(&tiocx_bus_type);
492 490
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
index 8d950c778bb6..cdf6856ce089 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;
@@ -738,7 +738,9 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
738 738
739 /* make sure all activity has settled down first */ 739 /* make sure all activity has settled down first */
740 740
741 if (atomic_read(&ch->references) > 0) { 741 if (atomic_read(&ch->references) > 0 ||
742 ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
743 !(ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE))) {
742 return; 744 return;
743 } 745 }
744 DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0); 746 DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0);
@@ -775,7 +777,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
775 777
776 /* both sides are disconnected now */ 778 /* both sides are disconnected now */
777 779
778 if (ch->flags & XPC_C_CONNECTCALLOUT) { 780 if (ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE) {
779 spin_unlock_irqrestore(&ch->lock, *irq_flags); 781 spin_unlock_irqrestore(&ch->lock, *irq_flags);
780 xpc_disconnect_callout(ch, xpcDisconnected); 782 xpc_disconnect_callout(ch, xpcDisconnected);
781 spin_lock_irqsave(&ch->lock, *irq_flags); 783 spin_lock_irqsave(&ch->lock, *irq_flags);
@@ -1300,7 +1302,7 @@ xpc_process_msg_IPI(struct xpc_partition *part, int ch_number)
1300 "delivered=%d, partid=%d, channel=%d\n", 1302 "delivered=%d, partid=%d, channel=%d\n",
1301 nmsgs_sent, ch->partid, ch->number); 1303 nmsgs_sent, ch->partid, ch->number);
1302 1304
1303 if (ch->flags & XPC_C_CONNECTCALLOUT) { 1305 if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) {
1304 xpc_activate_kthreads(ch, nmsgs_sent); 1306 xpc_activate_kthreads(ch, nmsgs_sent);
1305 } 1307 }
1306 } 1308 }
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index c75f8aeefc2b..8cbf16432570 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -575,18 +575,21 @@ xpc_activate_partition(struct xpc_partition *part)
575 575
576 spin_lock_irqsave(&part->act_lock, irq_flags); 576 spin_lock_irqsave(&part->act_lock, irq_flags);
577 577
578 pid = kernel_thread(xpc_activating, (void *) ((u64) partid), 0);
579
580 DBUG_ON(part->act_state != XPC_P_INACTIVE); 578 DBUG_ON(part->act_state != XPC_P_INACTIVE);
581 579
582 if (pid > 0) { 580 part->act_state = XPC_P_ACTIVATION_REQ;
583 part->act_state = XPC_P_ACTIVATION_REQ; 581 XPC_SET_REASON(part, xpcCloneKThread, __LINE__);
584 XPC_SET_REASON(part, xpcCloneKThread, __LINE__);
585 } else {
586 XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__);
587 }
588 582
589 spin_unlock_irqrestore(&part->act_lock, irq_flags); 583 spin_unlock_irqrestore(&part->act_lock, irq_flags);
584
585 pid = kernel_thread(xpc_activating, (void *) ((u64) partid), 0);
586
587 if (unlikely(pid <= 0)) {
588 spin_lock_irqsave(&part->act_lock, irq_flags);
589 part->act_state = XPC_P_INACTIVE;
590 XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__);
591 spin_unlock_irqrestore(&part->act_lock, irq_flags);
592 }
590} 593}
591 594
592 595
@@ -747,12 +750,16 @@ xpc_daemonize_kthread(void *args)
747 /* let registerer know that connection has been established */ 750 /* let registerer know that connection has been established */
748 751
749 spin_lock_irqsave(&ch->lock, irq_flags); 752 spin_lock_irqsave(&ch->lock, irq_flags);
750 if (!(ch->flags & XPC_C_CONNECTCALLOUT)) { 753 if (!(ch->flags & XPC_C_CONNECTEDCALLOUT)) {
751 ch->flags |= XPC_C_CONNECTCALLOUT; 754 ch->flags |= XPC_C_CONNECTEDCALLOUT;
752 spin_unlock_irqrestore(&ch->lock, irq_flags); 755 spin_unlock_irqrestore(&ch->lock, irq_flags);
753 756
754 xpc_connected_callout(ch); 757 xpc_connected_callout(ch);
755 758
759 spin_lock_irqsave(&ch->lock, irq_flags);
760 ch->flags |= XPC_C_CONNECTEDCALLOUT_MADE;
761 spin_unlock_irqrestore(&ch->lock, irq_flags);
762
756 /* 763 /*
757 * It is possible that while the callout was being 764 * It is possible that while the callout was being
758 * made that the remote partition sent some messages. 765 * made that the remote partition sent some messages.
@@ -774,15 +781,17 @@ xpc_daemonize_kthread(void *args)
774 781
775 if (atomic_dec_return(&ch->kthreads_assigned) == 0) { 782 if (atomic_dec_return(&ch->kthreads_assigned) == 0) {
776 spin_lock_irqsave(&ch->lock, irq_flags); 783 spin_lock_irqsave(&ch->lock, irq_flags);
777 if ((ch->flags & XPC_C_CONNECTCALLOUT) && 784 if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
778 !(ch->flags & XPC_C_DISCONNECTCALLOUT)) { 785 !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) {
779 ch->flags |= XPC_C_DISCONNECTCALLOUT; 786 ch->flags |= XPC_C_DISCONNECTINGCALLOUT;
780 spin_unlock_irqrestore(&ch->lock, irq_flags); 787 spin_unlock_irqrestore(&ch->lock, irq_flags);
781 788
782 xpc_disconnect_callout(ch, xpcDisconnecting); 789 xpc_disconnect_callout(ch, xpcDisconnecting);
783 } else { 790
784 spin_unlock_irqrestore(&ch->lock, irq_flags); 791 spin_lock_irqsave(&ch->lock, irq_flags);
792 ch->flags |= XPC_C_DISCONNECTINGCALLOUT_MADE;
785 } 793 }
794 spin_unlock_irqrestore(&ch->lock, irq_flags);
786 if (atomic_dec_return(&part->nchannels_engaged) == 0) { 795 if (atomic_dec_return(&part->nchannels_engaged) == 0) {
787 xpc_mark_partition_disengaged(part); 796 xpc_mark_partition_disengaged(part);
788 xpc_IPI_send_disengage(part); 797 xpc_IPI_send_disengage(part);
diff --git a/arch/ia64/sn/pci/Makefile b/arch/ia64/sn/pci/Makefile
index 321576b1b425..c6946784a6a8 100644
--- a/arch/ia64/sn/pci/Makefile
+++ b/arch/ia64/sn/pci/Makefile
@@ -7,4 +7,6 @@
7# 7#
8# Makefile for the sn pci general routines. 8# Makefile for the sn pci general routines.
9 9
10CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
11
10obj-y := pci_dma.o tioca_provider.o tioce_provider.o pcibr/ 12obj-y := pci_dma.o tioca_provider.o tioce_provider.o pcibr/
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index 9bf9f23b9a1f..b4b84c269210 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;
@@ -335,10 +335,10 @@ int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
335 */ 335 */
336 336
337 SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE, 337 SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE,
338 pci_domain_nr(bus), bus->number, 338 pci_domain_nr(bus), bus->number,
339 0, /* io */ 339 0, /* io */
340 0, /* read */ 340 0, /* read */
341 port, size, __pa(val)); 341 port, size, __pa(val));
342 342
343 if (isrv.status == 0) 343 if (isrv.status == 0)
344 return size; 344 return size;
@@ -381,10 +381,10 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
381 */ 381 */
382 382
383 SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE, 383 SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE,
384 pci_domain_nr(bus), bus->number, 384 pci_domain_nr(bus), bus->number,
385 0, /* io */ 385 0, /* io */
386 1, /* write */ 386 1, /* write */
387 port, size, __pa(&val)); 387 port, size, __pa(&val));
388 388
389 if (isrv.status == 0) 389 if (isrv.status == 0)
390 return size; 390 return size;
diff --git a/arch/ia64/sn/pci/pcibr/Makefile b/arch/ia64/sn/pci/pcibr/Makefile
index 1850c4a94c41..3b403ea456f9 100644
--- a/arch/ia64/sn/pci/pcibr/Makefile
+++ b/arch/ia64/sn/pci/pcibr/Makefile
@@ -7,5 +7,7 @@
7# 7#
8# Makefile for the sn2 io routines. 8# Makefile for the sn2 io routines.
9 9
10CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
11
10obj-y += pcibr_dma.o pcibr_reg.o \ 12obj-y += pcibr_dma.o pcibr_reg.o \
11 pcibr_ate.o pcibr_provider.o 13 pcibr_ate.o pcibr_provider.o
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/arch/ia64/sn/pci/pcibr/pcibr_ate.c
index aa3fa5152a32..1f0253bfe0a0 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_ate.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_ate.c
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 2001-2004 Silicon Graphics, Inc. All rights reserved. 6 * Copyright (C) 2001-2006 Silicon Graphics, Inc. All rights reserved.
7 */ 7 */
8 8
9#include <linux/types.h> 9#include <linux/types.h>
@@ -12,7 +12,7 @@
12#include <asm/sn/pcibus_provider_defs.h> 12#include <asm/sn/pcibus_provider_defs.h>
13#include <asm/sn/pcidev.h> 13#include <asm/sn/pcidev.h>
14 14
15int pcibr_invalidate_ate = 0; /* by default don't invalidate ATE on free */ 15int pcibr_invalidate_ate; /* by default don't invalidate ATE on free */
16 16
17/* 17/*
18 * mark_ate: Mark the ate as either free or inuse. 18 * mark_ate: Mark the ate as either free or inuse.
@@ -20,14 +20,12 @@ int pcibr_invalidate_ate = 0; /* by default don't invalidate ATE on free */
20static void mark_ate(struct ate_resource *ate_resource, int start, int number, 20static void mark_ate(struct ate_resource *ate_resource, int start, int number,
21 u64 value) 21 u64 value)
22{ 22{
23
24 u64 *ate = ate_resource->ate; 23 u64 *ate = ate_resource->ate;
25 int index; 24 int index;
26 int length = 0; 25 int length = 0;
27 26
28 for (index = start; length < number; index++, length++) 27 for (index = start; length < number; index++, length++)
29 ate[index] = value; 28 ate[index] = value;
30
31} 29}
32 30
33/* 31/*
@@ -37,7 +35,6 @@ static void mark_ate(struct ate_resource *ate_resource, int start, int number,
37static int find_free_ate(struct ate_resource *ate_resource, int start, 35static int find_free_ate(struct ate_resource *ate_resource, int start,
38 int count) 36 int count)
39{ 37{
40
41 u64 *ate = ate_resource->ate; 38 u64 *ate = ate_resource->ate;
42 int index; 39 int index;
43 int start_free; 40 int start_free;
@@ -70,12 +67,10 @@ static int find_free_ate(struct ate_resource *ate_resource, int start,
70static inline void free_ate_resource(struct ate_resource *ate_resource, 67static inline void free_ate_resource(struct ate_resource *ate_resource,
71 int start) 68 int start)
72{ 69{
73
74 mark_ate(ate_resource, start, ate_resource->ate[start], 0); 70 mark_ate(ate_resource, start, ate_resource->ate[start], 0);
75 if ((ate_resource->lowest_free_index > start) || 71 if ((ate_resource->lowest_free_index > start) ||
76 (ate_resource->lowest_free_index < 0)) 72 (ate_resource->lowest_free_index < 0))
77 ate_resource->lowest_free_index = start; 73 ate_resource->lowest_free_index = start;
78
79} 74}
80 75
81/* 76/*
@@ -84,7 +79,6 @@ static inline void free_ate_resource(struct ate_resource *ate_resource,
84static inline int alloc_ate_resource(struct ate_resource *ate_resource, 79static inline int alloc_ate_resource(struct ate_resource *ate_resource,
85 int ate_needed) 80 int ate_needed)
86{ 81{
87
88 int start_index; 82 int start_index;
89 83
90 /* 84 /*
@@ -118,19 +112,12 @@ static inline int alloc_ate_resource(struct ate_resource *ate_resource,
118 */ 112 */
119int pcibr_ate_alloc(struct pcibus_info *pcibus_info, int count) 113int pcibr_ate_alloc(struct pcibus_info *pcibus_info, int count)
120{ 114{
121 int status = 0; 115 int status;
122 u64 flag; 116 unsigned long flags;
123 117
124 flag = pcibr_lock(pcibus_info); 118 spin_lock_irqsave(&pcibus_info->pbi_lock, flags);
125 status = alloc_ate_resource(&pcibus_info->pbi_int_ate_resource, count); 119 status = alloc_ate_resource(&pcibus_info->pbi_int_ate_resource, count);
126 120 spin_unlock_irqrestore(&pcibus_info->pbi_lock, flags);
127 if (status < 0) {
128 /* Failed to allocate */
129 pcibr_unlock(pcibus_info, flag);
130 return -1;
131 }
132
133 pcibr_unlock(pcibus_info, flag);
134 121
135 return status; 122 return status;
136} 123}
@@ -182,7 +169,7 @@ void pcibr_ate_free(struct pcibus_info *pcibus_info, int index)
182 ate_write(pcibus_info, index, count, (ate & ~PCI32_ATE_V)); 169 ate_write(pcibus_info, index, count, (ate & ~PCI32_ATE_V));
183 } 170 }
184 171
185 flags = pcibr_lock(pcibus_info); 172 spin_lock_irqsave(&pcibus_info->pbi_lock, flags);
186 free_ate_resource(&pcibus_info->pbi_int_ate_resource, index); 173 free_ate_resource(&pcibus_info->pbi_int_ate_resource, index);
187 pcibr_unlock(pcibus_info, flags); 174 spin_unlock_irqrestore(&pcibus_info->pbi_lock, flags);
188} 175}
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
index 54ce5b7ceed2..9f86bb6519aa 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
@@ -137,14 +137,12 @@ pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr,
137 pci_addr |= PCI64_ATTR_VIRTUAL; 137 pci_addr |= PCI64_ATTR_VIRTUAL;
138 138
139 return pci_addr; 139 return pci_addr;
140
141} 140}
142 141
143static dma_addr_t 142static dma_addr_t
144pcibr_dmatrans_direct32(struct pcidev_info * info, 143pcibr_dmatrans_direct32(struct pcidev_info * info,
145 u64 paddr, size_t req_size, u64 flags) 144 u64 paddr, size_t req_size, u64 flags)
146{ 145{
147
148 struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info; 146 struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info;
149 struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info-> 147 struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info->
150 pdi_pcibus_info; 148 pdi_pcibus_info;
@@ -171,7 +169,6 @@ pcibr_dmatrans_direct32(struct pcidev_info * info,
171 } 169 }
172 170
173 return PCI32_DIRECT_BASE | offset; 171 return PCI32_DIRECT_BASE | offset;
174
175} 172}
176 173
177/* 174/*
@@ -218,9 +215,8 @@ void sn_dma_flush(u64 addr)
218 u64 flags; 215 u64 flags;
219 u64 itte; 216 u64 itte;
220 struct hubdev_info *hubinfo; 217 struct hubdev_info *hubinfo;
221 volatile struct sn_flush_device_kernel *p; 218 struct sn_flush_device_kernel *p;
222 volatile struct sn_flush_device_common *common; 219 struct sn_flush_device_common *common;
223
224 struct sn_flush_nasid_entry *flush_nasid_list; 220 struct sn_flush_nasid_entry *flush_nasid_list;
225 221
226 if (!sn_ioif_inited) 222 if (!sn_ioif_inited)
@@ -310,8 +306,7 @@ void sn_dma_flush(u64 addr)
310 (common->sfdl_slot - 1)); 306 (common->sfdl_slot - 1));
311 } 307 }
312 } else { 308 } else {
313 spin_lock_irqsave((spinlock_t *)&p->sfdl_flush_lock, 309 spin_lock_irqsave(&p->sfdl_flush_lock, flags);
314 flags);
315 *common->sfdl_flush_addr = 0; 310 *common->sfdl_flush_addr = 0;
316 311
317 /* force an interrupt. */ 312 /* force an interrupt. */
@@ -322,8 +317,7 @@ void sn_dma_flush(u64 addr)
322 cpu_relax(); 317 cpu_relax();
323 318
324 /* okay, everything is synched up. */ 319 /* okay, everything is synched up. */
325 spin_unlock_irqrestore((spinlock_t *)&p->sfdl_flush_lock, 320 spin_unlock_irqrestore(&p->sfdl_flush_lock, flags);
326 flags);
327 } 321 }
328 return; 322 return;
329} 323}
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
index 2fac27049bf6..98f716bd92f0 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
@@ -163,9 +163,12 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
163 /* Setup the PMU ATE map */ 163 /* Setup the PMU ATE map */
164 soft->pbi_int_ate_resource.lowest_free_index = 0; 164 soft->pbi_int_ate_resource.lowest_free_index = 0;
165 soft->pbi_int_ate_resource.ate = 165 soft->pbi_int_ate_resource.ate =
166 kmalloc(soft->pbi_int_ate_size * sizeof(u64), GFP_KERNEL); 166 kzalloc(soft->pbi_int_ate_size * sizeof(u64), GFP_KERNEL);
167 memset(soft->pbi_int_ate_resource.ate, 0, 167
168 (soft->pbi_int_ate_size * sizeof(u64))); 168 if (!soft->pbi_int_ate_resource.ate) {
169 kfree(soft);
170 return NULL;
171 }
169 172
170 if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) { 173 if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) {
171 /* TIO PCI Bridge: find nearest node with CPUs */ 174 /* TIO PCI Bridge: find nearest node with CPUs */