aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/Kconfig4
-rw-r--r--arch/ia64/dig/setup.c10
-rw-r--r--arch/ia64/kernel/Makefile5
-rw-r--r--arch/ia64/kernel/acpi-ext.c22
-rw-r--r--arch/ia64/kernel/acpi-processor.c67
-rw-r--r--arch/ia64/kernel/acpi.c6
-rw-r--r--arch/ia64/kernel/cpufreq/Makefile1
-rw-r--r--arch/ia64/kernel/cpufreq/acpi-cpufreq.c51
-rw-r--r--arch/ia64/kernel/efi.c16
-rw-r--r--arch/ia64/kernel/head.S1
-rw-r--r--arch/ia64/kernel/mca_asm.S2
-rw-r--r--arch/ia64/kernel/sal.c75
-rw-r--r--arch/ia64/kernel/setup.c4
-rw-r--r--arch/ia64/kernel/time.c27
-rw-r--r--arch/ia64/kernel/topology.c18
-rw-r--r--arch/ia64/kernel/unaligned.c3
-rw-r--r--arch/ia64/pci/pci.c10
-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.c45
-rw-r--r--arch/ia64/sn/kernel/irq.c21
-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.c73
-rw-r--r--arch/ia64/sn/kernel/sn2/Makefile2
-rw-r--r--arch/ia64/sn/kernel/sn2/sn2_smp.c196
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_hwperf.c5
-rw-r--r--arch/ia64/sn/kernel/xpc_channel.c6
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c19
-rw-r--r--arch/ia64/sn/pci/Makefile2
-rw-r--r--arch/ia64/sn/pci/pci_dma.c4
-rw-r--r--arch/ia64/sn/pci/pcibr/Makefile2
33 files changed, 419 insertions, 333 deletions
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 199eeaf0f4e3..845cd0902a50 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -194,7 +194,6 @@ config IA64_L1_CACHE_SHIFT
default "7" if MCKINLEY
default "6" if ITANIUM
-# align cache-sensitive data to 64 bytes
config IA64_CYCLONE
bool "Cyclone (EXA) Time Source support"
help
@@ -374,6 +373,9 @@ config IA64_PALINFO
To use this option, you have to ensure that the "/proc file system
support" (CONFIG_PROC_FS) is enabled, too.
+config SGI_SN
+ def_bool y if (IA64_SGI_SN2 || IA64_GENERIC)
+
source "drivers/firmware/Kconfig"
source "fs/Kconfig.binfmt"
diff --git a/arch/ia64/dig/setup.c b/arch/ia64/dig/setup.c
index d58003f1ad02..c9104bfff667 100644
--- a/arch/ia64/dig/setup.c
+++ b/arch/ia64/dig/setup.c
@@ -25,16 +25,6 @@
#include <asm/machvec.h>
#include <asm/system.h>
-/*
- * This is here so we can use the CMOS detection in ide-probe.c to
- * determine what drives are present. In theory, we don't need this
- * as the auto-detection could be done via ide-probe.c:do_probe() but
- * in practice that would be much slower, which is painful when
- * running in the simulator. Note that passing zeroes in DRIVE_INFO
- * is sufficient (the IDE driver will autodetect the drive geometry).
- */
-char drive_info[4*16];
-
void __init
dig_setup (char **cmdline_p)
{
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
obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o
obj-$(CONFIG_IA64_HP_ZX1) += acpi-ext.o
obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += acpi-ext.o
+
+ifneq ($(CONFIG_ACPI_PROCESSOR),)
+obj-y += acpi-processor.o
+endif
+
obj-$(CONFIG_IA64_PALINFO) += palinfo.o
obj-$(CONFIG_IOSAPIC) += iosapic.o
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)
struct acpi_vendor_info *info = (struct acpi_vendor_info *)context;
struct acpi_resource_vendor *vendor;
struct acpi_vendor_descriptor *descriptor;
- u32 length;
+ u32 byte_length;
- if (resource->id != ACPI_RSTYPE_VENDOR)
+ if (resource->type != ACPI_RESOURCE_TYPE_VENDOR)
return AE_OK;
vendor = (struct acpi_resource_vendor *)&resource->data;
- descriptor = (struct acpi_vendor_descriptor *)vendor->reserved;
- if (vendor->length <= sizeof(*info->descriptor) ||
+ descriptor = (struct acpi_vendor_descriptor *)vendor->byte_data;
+ if (vendor->byte_length <= sizeof(*info->descriptor) ||
descriptor->guid_id != info->descriptor->guid_id ||
efi_guidcmp(descriptor->guid, info->descriptor->guid))
return AE_OK;
- length = vendor->length - sizeof(struct acpi_vendor_descriptor);
- info->data = acpi_os_allocate(length);
+ byte_length = vendor->byte_length - sizeof(struct acpi_vendor_descriptor);
+ info->data = acpi_os_allocate(byte_length);
if (!info->data)
return AE_NO_MEMORY;
memcpy(info->data,
- vendor->reserved + sizeof(struct acpi_vendor_descriptor),
- length);
- info->length = length;
+ vendor->byte_data + sizeof(struct acpi_vendor_descriptor),
+ byte_length);
+ info->length = byte_length;
return AE_CTRL_TERMINATE;
}
acpi_status
acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id,
- u8 ** data, u32 * length)
+ u8 ** data, u32 * byte_length)
{
struct acpi_vendor_info info;
@@ -72,7 +72,7 @@ acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id,
return AE_NOT_FOUND;
*data = info.data;
- *length = info.length;
+ *byte_length = info.length;
return AE_OK;
}
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 @@
+/*
+ * arch/ia64/kernel/cpufreq/processor.c
+ *
+ * Copyright (C) 2005 Intel Corporation
+ * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ * - Added _PDC for platforms with Intel CPUs
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/acpi.h>
+
+#include <acpi/processor.h>
+#include <asm/acpi.h>
+
+static void init_intel_pdc(struct acpi_processor *pr)
+{
+ struct acpi_object_list *obj_list;
+ union acpi_object *obj;
+ u32 *buf;
+
+ /* allocate and initialize pdc. It will be used later. */
+ obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
+ if (!obj_list) {
+ printk(KERN_ERR "Memory allocation error\n");
+ return;
+ }
+
+ obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+ if (!obj) {
+ printk(KERN_ERR "Memory allocation error\n");
+ kfree(obj_list);
+ return;
+ }
+
+ buf = kmalloc(12, GFP_KERNEL);
+ if (!buf) {
+ printk(KERN_ERR "Memory allocation error\n");
+ kfree(obj);
+ kfree(obj_list);
+ return;
+ }
+
+ buf[0] = ACPI_PDC_REVISION_ID;
+ buf[1] = 1;
+ buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP;
+
+ obj->type = ACPI_TYPE_BUFFER;
+ obj->buffer.length = 12;
+ obj->buffer.pointer = (u8 *) buf;
+ obj_list->count = 1;
+ obj_list->pointer = obj;
+ pr->pdc = obj_list;
+
+ return;
+}
+
+/* Initialize _PDC data based on the CPU vendor */
+void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
+{
+ pr->pdc = NULL;
+ init_intel_pdc(pr);
+ return;
+}
+
+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)
* success: return IRQ number (>=0)
* failure: return < 0
*/
-int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
+int acpi_register_gsi(u32 gsi, int triggering, int polarity)
{
if (has_8259 && gsi < 16)
return isa_irq_to_vector(gsi);
return iosapic_register_intr(gsi,
- (active_high_low ==
+ (polarity ==
ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH :
IOSAPIC_POL_LOW,
- (edge_level ==
+ (triggering ==
ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE :
IOSAPIC_LEVEL);
}
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 @@
obj-$(CONFIG_IA64_ACPI_CPUFREQ) += acpi-cpufreq.o
+
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 (
}
-/*
- * processor_init_pdc - let BIOS know about the SMP capabilities
- * of this driver
- * @perf: processor-specific acpi_io_data struct
- * @cpu: CPU being initialized
- *
- * To avoid issues with legacy OSes, some BIOSes require to be informed of
- * the SMP capabilities of OS P-state driver. Here we set the bits in _PDC
- * accordingly. Actual call to _PDC is done in driver/acpi/processor.c
- */
-static void
-processor_init_pdc (
- struct acpi_processor_performance *perf,
- unsigned int cpu,
- struct acpi_object_list *obj_list
- )
-{
- union acpi_object *obj;
- u32 *buf;
-
- dprintk("processor_init_pdc\n");
-
- perf->pdc = NULL;
- /* Initialize pdc. It will be used later. */
- if (!obj_list)
- return;
-
- if (!(obj_list->count && obj_list->pointer))
- return;
-
- obj = obj_list->pointer;
- if ((obj->buffer.length == 12) && obj->buffer.pointer) {
- buf = (u32 *)obj->buffer.pointer;
- buf[0] = ACPI_PDC_REVISION_ID;
- buf[1] = 1;
- buf[2] = ACPI_PDC_EST_CAPABILITY_SMP;
- perf->pdc = obj_list;
- }
- return;
-}
-
-
static int
acpi_cpufreq_cpu_init (
struct cpufreq_policy *policy)
@@ -320,14 +278,7 @@ acpi_cpufreq_cpu_init (
struct cpufreq_acpi_io *data;
unsigned int result = 0;
- union acpi_object arg0 = {ACPI_TYPE_BUFFER};
- u32 arg0_buf[3];
- struct acpi_object_list arg_list = {1, &arg0};
-
dprintk("acpi_cpufreq_cpu_init\n");
- /* setup arg_list for _PDC settings */
- arg0.buffer.length = 12;
- arg0.buffer.pointer = (u8 *) arg0_buf;
data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
if (!data)
@@ -337,9 +288,7 @@ acpi_cpufreq_cpu_init (
acpi_io_data[cpu] = data;
- processor_init_pdc(&data->acpi_data, cpu, &arg_list);
result = acpi_processor_register_performance(&data->acpi_data, cpu);
- data->acpi_data.pdc = NULL;
if (result)
goto err_free;
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index c485a3b32ba8..9990320b6f9a 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -410,24 +410,16 @@ efi_init (void)
efi_config_table_t *config_tables;
efi_char16_t *c16;
u64 efi_desc_size;
- char *cp, *end, vendor[100] = "unknown";
+ char *cp, vendor[100] = "unknown";
extern char saved_command_line[];
int i;
/* it's too early to be able to use the standard kernel command line support... */
for (cp = saved_command_line; *cp; ) {
if (memcmp(cp, "mem=", 4) == 0) {
- cp += 4;
- mem_limit = memparse(cp, &end);
- if (end != cp)
- break;
- cp = end;
+ mem_limit = memparse(cp + 4, &cp);
} else if (memcmp(cp, "max_addr=", 9) == 0) {
- cp += 9;
- max_addr = GRANULEROUNDDOWN(memparse(cp, &end));
- if (end != cp)
- break;
- cp = end;
+ max_addr = GRANULEROUNDDOWN(memparse(cp + 9, &cp));
} else {
while (*cp != ' ' && *cp)
++cp;
@@ -458,7 +450,7 @@ efi_init (void)
/* Show what we know for posterity */
c16 = __va(efi.systab->fw_vendor);
if (c16) {
- for (i = 0;i < (int) sizeof(vendor) && *c16; ++i)
+ for (i = 0;i < (int) sizeof(vendor) - 1 && *c16; ++i)
vendor[i] = *c16++;
vendor[i] = '\0';
}
diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S
index fbc7ea35dd57..f1778a84ea61 100644
--- a/arch/ia64/kernel/head.S
+++ b/arch/ia64/kernel/head.S
@@ -352,6 +352,7 @@ start_ap:
mov ar.rsc=0 // place RSE in enforced lazy mode
;;
loadrs // clear the dirty partition
+ mov IA64_KR(PER_CPU_DATA)=r0 // clear physical per-CPU base
;;
mov ar.bspstore=r2 // establish the new RSE stack
;;
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:
st8 [temp1]=r12 // os_status, default is cold boot
mov r6=IA64_MCA_SAME_CONTEXT
;;
- st8 [temp1]=r6 // context, default is same context
+ st8 [temp2]=r6 // context, default is same context
// Save the pt_regs data that is not in minstate. The previous code
// 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 @@
#include <linux/spinlock.h>
#include <linux/string.h>
+#include <asm/delay.h>
#include <asm/page.h>
#include <asm/sal.h>
#include <asm/pal.h>
@@ -214,6 +215,78 @@ chk_nointroute_opt(void)
static void __init sal_desc_ap_wakeup(void *p) { }
#endif
+/*
+ * HP rx5670 firmware polls for interrupts during SAL_CACHE_FLUSH by reading
+ * cr.ivr, but it never writes cr.eoi. This leaves any interrupt marked as
+ * "in-service" and masks other interrupts of equal or lower priority.
+ *
+ * HP internal defect reports: F1859, F2775, F3031.
+ */
+static int sal_cache_flush_drops_interrupts;
+
+static void __init
+check_sal_cache_flush (void)
+{
+ unsigned long flags, itv;
+ int cpu;
+ u64 vector;
+
+ cpu = get_cpu();
+ local_irq_save(flags);
+
+ /*
+ * Schedule a timer interrupt, wait until it's reported, and see if
+ * SAL_CACHE_FLUSH drops it.
+ */
+ itv = ia64_get_itv();
+ BUG_ON((itv & (1 << 16)) == 0);
+
+ ia64_set_itv(IA64_TIMER_VECTOR);
+ ia64_set_itm(ia64_get_itc() + 1000);
+
+ while (!ia64_get_irr(IA64_TIMER_VECTOR))
+ cpu_relax();
+
+ ia64_sal_cache_flush(3);
+
+ if (ia64_get_irr(IA64_TIMER_VECTOR)) {
+ vector = ia64_get_ivr();
+ ia64_eoi();
+ WARN_ON(vector != IA64_TIMER_VECTOR);
+ } else {
+ sal_cache_flush_drops_interrupts = 1;
+ printk(KERN_ERR "SAL: SAL_CACHE_FLUSH drops interrupts; "
+ "PAL_CACHE_FLUSH will be used instead\n");
+ ia64_eoi();
+ }
+
+ ia64_set_itv(itv);
+ local_irq_restore(flags);
+ put_cpu();
+}
+
+s64
+ia64_sal_cache_flush (u64 cache_type)
+{
+ struct ia64_sal_retval isrv;
+
+ if (sal_cache_flush_drops_interrupts) {
+ unsigned long flags;
+ u64 progress;
+ s64 rc;
+
+ progress = 0;
+ local_irq_save(flags);
+ rc = ia64_pal_cache_flush(cache_type,
+ PAL_CACHE_FLUSH_INVALIDATE, &progress, NULL);
+ local_irq_restore(flags);
+ return rc;
+ }
+
+ SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0);
+ return isrv.status;
+}
+
void __init
ia64_sal_init (struct ia64_sal_systab *systab)
{
@@ -262,6 +335,8 @@ ia64_sal_init (struct ia64_sal_systab *systab)
}
p += SAL_DESC_SIZE(*p);
}
+
+ check_sal_cache_flush();
}
int
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index c0766575a3a2..35f7835294a3 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -71,6 +71,8 @@ unsigned long __per_cpu_offset[NR_CPUS];
EXPORT_SYMBOL(__per_cpu_offset);
#endif
+extern void ia64_setup_printk_clock(void);
+
DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info);
DEFINE_PER_CPU(unsigned long, local_per_cpu_offset);
DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8);
@@ -445,6 +447,8 @@ setup_arch (char **cmdline_p)
/* process SAL system table: */
ia64_sal_init(efi.sal_systab);
+ ia64_setup_printk_clock();
+
#ifdef CONFIG_SMP
cpu_physical_id(0) = hard_smp_processor_id();
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 028a2b95936c..a094ec49ccfa 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -278,3 +278,30 @@ udelay (unsigned long usecs)
}
}
EXPORT_SYMBOL(udelay);
+
+static unsigned long long ia64_itc_printk_clock(void)
+{
+ if (ia64_get_kr(IA64_KR_PER_CPU_DATA))
+ return sched_clock();
+ return 0;
+}
+
+static unsigned long long ia64_default_printk_clock(void)
+{
+ return (unsigned long long)(jiffies_64 - INITIAL_JIFFIES) *
+ (1000000000/HZ);
+}
+
+unsigned long long (*ia64_printk_clock)(void) = &ia64_default_printk_clock;
+
+unsigned long long printk_clock(void)
+{
+ return ia64_printk_clock();
+}
+
+void __init
+ia64_setup_printk_clock(void)
+{
+ if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT))
+ ia64_printk_clock = ia64_itc_printk_clock;
+}
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
index 706b7734e191..6e5eea19fa67 100644
--- a/arch/ia64/kernel/topology.c
+++ b/arch/ia64/kernel/topology.c
@@ -71,31 +71,33 @@ static int __init topology_init(void)
int i, err = 0;
#ifdef CONFIG_NUMA
- sysfs_nodes = kmalloc(sizeof(struct node) * MAX_NUMNODES, GFP_KERNEL);
+ sysfs_nodes = kzalloc(sizeof(struct node) * MAX_NUMNODES, GFP_KERNEL);
if (!sysfs_nodes) {
err = -ENOMEM;
goto out;
}
- memset(sysfs_nodes, 0, sizeof(struct node) * MAX_NUMNODES);
- /* MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes? */
- for_each_online_node(i)
+ /*
+ * MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes?
+ */
+ for_each_online_node(i) {
if ((err = register_node(&sysfs_nodes[i], i, 0)))
goto out;
+ }
#endif
- sysfs_cpus = kmalloc(sizeof(struct ia64_cpu) * NR_CPUS, GFP_KERNEL);
+ sysfs_cpus = kzalloc(sizeof(struct ia64_cpu) * NR_CPUS, GFP_KERNEL);
if (!sysfs_cpus) {
err = -ENOMEM;
goto out;
}
- memset(sysfs_cpus, 0, sizeof(struct ia64_cpu) * NR_CPUS);
- for_each_present_cpu(i)
+ for_each_present_cpu(i) {
if((err = arch_register_cpu(i)))
goto out;
+ }
out:
return err;
}
-__initcall(topology_init);
+subsys_initcall(topology_init);
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)
if (jiffies - last_time > 5*HZ)
count = 0;
- if (++count < 5) {
+ if (count < 5) {
last_time = jiffies;
+ count++;
return 1;
}
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)
goto free_resource;
}
- min = addr->min_address_range;
+ min = addr->minimum;
max = min + addr->address_length - 1;
- if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
+ if (addr->info.io.translation_type == ACPI_SPARSE_TRANSLATION)
sparse = 1;
- space_nr = new_space(addr->address_translation_offset, sparse);
+ space_nr = new_space(addr->translation_offset, sparse);
if (space_nr == ~0)
goto free_name;
@@ -285,7 +285,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
if (addr.resource_type == ACPI_MEMORY_RANGE) {
flags = IORESOURCE_MEM;
root = &iomem_resource;
- offset = addr.address_translation_offset;
+ offset = addr.translation_offset;
} else if (addr.resource_type == ACPI_IO_RANGE) {
flags = IORESOURCE_IO;
root = &ioport_resource;
@@ -298,7 +298,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
window = &info->controller->window[info->controller->windows++];
window->resource.name = info->name;
window->resource.flags = flags;
- window->resource.start = addr.min_address_range + offset;
+ window->resource.start = addr.minimum + offset;
window->resource.end = window->resource.start + addr.address_length - 1;
window->resource.child = NULL;
window->offset = offset;
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 @@
# Makefile for the sn ia64 subplatform
#
-CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
-
obj-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 @@
# Copyright (C) 1999,2001-2005 Silicon Graphics, Inc. All Rights Reserved.
#
+CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
+
obj-y += setup.o bte.o bte_error.o irq.o mca.o idle.o \
huberror.o io_init.o iomv.o klconflib.o sn2/
obj-$(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 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
*/
#include <linux/config.h>
@@ -186,18 +186,13 @@ retry_bteop:
/* Initialize the notification to a known value. */
*bte->most_rcnt_na = BTE_WORD_BUSY;
- notif_phys_addr = TO_PHYS(ia64_tpa((unsigned long)bte->most_rcnt_na));
+ notif_phys_addr = (u64)bte->most_rcnt_na;
- if (is_shub2()) {
- src = SH2_TIO_PHYS_TO_DMA(src);
- dest = SH2_TIO_PHYS_TO_DMA(dest);
- notif_phys_addr = SH2_TIO_PHYS_TO_DMA(notif_phys_addr);
- }
/* Set the source and destination registers */
- BTE_PRINTKV(("IBSA = 0x%lx)\n", (TO_PHYS(src))));
- BTE_SRC_STORE(bte, TO_PHYS(src));
- BTE_PRINTKV(("IBDA = 0x%lx)\n", (TO_PHYS(dest))));
- BTE_DEST_STORE(bte, TO_PHYS(dest));
+ BTE_PRINTKV(("IBSA = 0x%lx)\n", src));
+ BTE_SRC_STORE(bte, src);
+ BTE_PRINTKV(("IBDA = 0x%lx)\n", dest));
+ BTE_DEST_STORE(bte, dest);
/* Set the notification register */
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..d7e4d79e16a8 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -10,6 +10,7 @@
#include <linux/nodemask.h>
#include <asm/sn/types.h>
#include <asm/sn/addrs.h>
+#include <asm/sn/sn_feature_sets.h>
#include <asm/sn/geo.h>
#include <asm/sn/io.h>
#include <asm/sn/pcibr_provider.h>
@@ -173,8 +174,8 @@ sn_pcidev_info_get(struct pci_dev *dev)
*/
static u8 war_implemented = 0;
-static void sn_device_fixup_war(u64 nasid, u64 widget, int device,
- struct sn_flush_device_common *common)
+static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device,
+ struct sn_flush_device_common *common)
{
struct sn_flush_device_war *war_list;
struct sn_flush_device_war *dev_entry;
@@ -198,15 +199,16 @@ static void sn_device_fixup_war(u64 nasid, u64 widget, int device,
dev_entry = war_list + device;
memcpy(common,dev_entry, sizeof(*common));
-
kfree(war_list);
+
+ return isrv.status;
}
/*
* sn_fixup_ionodes() - This routine initializes the HUB data strcuture for
* each node in the system.
*/
-static void sn_fixup_ionodes(void)
+static void __init sn_fixup_ionodes(void)
{
struct sn_flush_device_kernel *sn_flush_device_kernel;
struct sn_flush_device_kernel *dev_entry;
@@ -279,23 +281,21 @@ static void sn_fixup_ionodes(void)
memset(dev_entry->common, 0x0, sizeof(struct
sn_flush_device_common));
- status = sal_get_device_dmaflush_list(nasid,
- widget,
- device,
+ if (sn_prom_feature_available(
+ PRF_DEVICE_FLUSH_LIST))
+ status = sal_get_device_dmaflush_list(
+ nasid,
+ widget,
+ device,
(u64)(dev_entry->common));
- if (status) {
- if (sn_sal_rev() < 0x0450) {
- /* shortlived WAR for older
- * PROM images
- */
- sn_device_fixup_war(nasid,
- widget,
- device,
+ else
+ status = sn_device_fixup_war(nasid,
+ widget,
+ device,
dev_entry->common);
- }
- else
- BUG();
- }
+ if (status != SALRET_OK)
+ panic("SAL call failed: %s\n",
+ ia64_sal_strerror(status));
spin_lock_init(&dev_entry->sfdl_flush_lock);
}
@@ -467,6 +467,13 @@ void sn_pci_fixup_slot(struct pci_dev *dev)
pcidev_info->pdi_sn_irq_info = NULL;
kfree(sn_irq_info);
}
+
+ /*
+ * MSI currently not supported on altix. Remove this when
+ * the MSI abstraction patches are integrated into the kernel
+ * (sometime after 2.6.16 releases)
+ */
+ dev->no_msi = 1;
}
/*
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index ec37084bdc17..74d87d903d5d 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -5,11 +5,12 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
*/
#include <linux/irq.h>
#include <linux/spinlock.h>
+#include <linux/init.h>
#include <asm/sn/addrs.h>
#include <asm/sn/arch.h>
#include <asm/sn/intr.h>
@@ -76,17 +77,15 @@ static void sn_enable_irq(unsigned int irq)
static void sn_ack_irq(unsigned int irq)
{
- u64 event_occurred, mask = 0;
+ u64 event_occurred, mask;
irq = irq & 0xff;
- event_occurred =
- HUB_L((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED));
+ event_occurred = HUB_L((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED));
mask = event_occurred & SH_ALL_INT_MASK;
- HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS),
- mask);
+ HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), mask);
__set_bit(irq, (volatile void *)pda->sn_in_service_ivecs);
- move_irq(irq);
+ move_native_irq(irq);
}
static void sn_end_irq(unsigned int irq)
@@ -219,9 +218,8 @@ static void register_intr_pda(struct sn_irq_info *sn_irq_info)
pdacpu(cpu)->sn_last_irq = irq;
}
- if (pdacpu(cpu)->sn_first_irq == 0 || pdacpu(cpu)->sn_first_irq > irq) {
+ if (pdacpu(cpu)->sn_first_irq == 0 || pdacpu(cpu)->sn_first_irq > irq)
pdacpu(cpu)->sn_first_irq = irq;
- }
}
static 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)
list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]);
spin_unlock(&sn_irq_info_lock);
- (void)register_intr_pda(sn_irq_info);
+ register_intr_pda(sn_irq_info);
}
void sn_irq_unfixup(struct pci_dev *pci_dev)
@@ -419,7 +417,7 @@ void sn_lb_int_war_check(void)
rcu_read_unlock();
}
-void sn_irq_lh_init(void)
+void __init sn_irq_lh_init(void)
{
int i;
@@ -434,5 +432,4 @@ void sn_irq_lh_init(void)
INIT_LIST_HEAD(sn_irq_lh[i]);
}
-
}
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)
position = MODULE_GET_BPOS(m);
if ((fmt == MODULE_FORMAT_BRIEF) || (fmt == MODULE_FORMAT_LCD)) {
- /* Brief module number format, eg. 002c15 */
+ /* Brief module number format, eg. 002c15 */
- /* Decompress the rack number */
- *buffer++ = '0' + RACK_GET_CLASS(rack);
- *buffer++ = '0' + RACK_GET_GROUP(rack);
- *buffer++ = '0' + RACK_GET_NUM(rack);
+ /* Decompress the rack number */
+ *buffer++ = '0' + RACK_GET_CLASS(rack);
+ *buffer++ = '0' + RACK_GET_GROUP(rack);
+ *buffer++ = '0' + RACK_GET_NUM(rack);
- /* Add the brick type */
- *buffer++ = brickchar;
+ /* Add the brick type */
+ *buffer++ = brickchar;
}
else if (fmt == MODULE_FORMAT_LONG) {
- /* Fuller hwgraph format, eg. rack/002/bay/15 */
+ /* Fuller hwgraph format, eg. rack/002/bay/15 */
- strcpy(buffer, "rack" "/"); buffer += strlen(buffer);
+ strcpy(buffer, "rack" "/"); buffer += strlen(buffer);
- *buffer++ = '0' + RACK_GET_CLASS(rack);
- *buffer++ = '0' + RACK_GET_GROUP(rack);
- *buffer++ = '0' + RACK_GET_NUM(rack);
+ *buffer++ = '0' + RACK_GET_CLASS(rack);
+ *buffer++ = '0' + RACK_GET_GROUP(rack);
+ *buffer++ = '0' + RACK_GET_NUM(rack);
- strcpy(buffer, "/" "bay" "/"); buffer += strlen(buffer);
+ strcpy(buffer, "/" "bay" "/"); buffer += strlen(buffer);
}
/* Add the bay position, using at least two digits */
if (position < 10)
- *buffer++ = '0';
+ *buffer++ = '0';
sprintf(buffer, "%d", position);
-
}
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 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
*/
#include <linux/types.h>
@@ -137,7 +137,8 @@ int sn_salinfo_platform_oemdata(const u8 *sect_header, u8 **oemdata, u64 *oemdat
static int __init sn_salinfo_init(void)
{
- salinfo_platform_oemdata = &sn_salinfo_platform_oemdata;
+ if (ia64_platform_is("sn2"))
+ salinfo_platform_oemdata = &sn_salinfo_platform_oemdata;
return 0;
}
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index e510dce9971f..48645ac120fc 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;
extern void (*ia64_mark_idle) (int);
extern void snidle(int);
extern unsigned char acpi_kbd_controller_present;
+extern unsigned long long (*ia64_printk_clock)(void);
unsigned long sn_rtc_cycles_per_second;
EXPORT_SYMBOL(sn_rtc_cycles_per_second);
@@ -125,20 +126,6 @@ struct screen_info sn_screen_info = {
};
/*
- * This is here so we can use the CMOS detection in ide-probe.c to
- * determine what drives are present. In theory, we don't need this
- * as the auto-detection could be done via ide-probe.c:do_probe() but
- * in practice that would be much slower, which is painful when
- * running in the simulator. Note that passing zeroes in DRIVE_INFO
- * is sufficient (the IDE driver will autodetect the drive geometry).
- */
-#ifdef CONFIG_IA64_GENERIC
-extern char drive_info[4 * 16];
-#else
-char drive_info[4 * 16];
-#endif
-
-/*
* This routine can only be used during init, since
* smp_boot_data is an init data structure.
* We have to use smp_boot_data.cpu_phys_id to find
@@ -209,7 +196,7 @@ void __init early_sn_setup(void)
}
extern int platform_intr_list[];
-static int __initdata shub_1_1_found = 0;
+static int __initdata shub_1_1_found;
/*
* sn_check_for_wars
@@ -372,6 +359,16 @@ sn_scan_pcdp(void)
}
}
+static unsigned long sn2_rtc_initial;
+
+static unsigned long long ia64_sn2_printk_clock(void)
+{
+ unsigned long rtc_now = rtc_time();
+
+ return (rtc_now - sn2_rtc_initial) *
+ (1000000000 / sn_rtc_cycles_per_second);
+}
+
/**
* sn_setup - SN platform setup routine
* @cmdline_p: kernel command line
@@ -386,6 +383,7 @@ void __init sn_setup(char **cmdline_p)
u32 version = sn_sal_rev();
extern void sn_cpu_init(void);
+ sn2_rtc_initial = rtc_time();
ia64_sn_plat_set_error_handling_features(); // obsolete
ia64_sn_set_os_feature(OSF_MCA_SLV_TO_OS_INIT_SLV);
ia64_sn_set_os_feature(OSF_FEAT_LOG_SBES);
@@ -437,19 +435,6 @@ void __init sn_setup(char **cmdline_p)
*/
build_cnode_tables();
- /*
- * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard
- * support here so we don't have to listen to failed keyboard probe
- * messages.
- */
- if (version <= 0x0209 && acpi_kbd_controller_present) {
- printk(KERN_INFO "Disabling legacy keyboard support as prom "
- "is too old and doesn't provide FADT\n");
- acpi_kbd_controller_present = 0;
- }
-
- printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);
-
status =
ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
&drift);
@@ -463,6 +448,21 @@ void __init sn_setup(char **cmdline_p)
platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR;
+ ia64_printk_clock = ia64_sn2_printk_clock;
+
+ /*
+ * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard
+ * support here so we don't have to listen to failed keyboard probe
+ * messages.
+ */
+ if (version <= 0x0209 && acpi_kbd_controller_present) {
+ printk(KERN_INFO "Disabling legacy keyboard support as prom "
+ "is too old and doesn't provide FADT\n");
+ acpi_kbd_controller_present = 0;
+ }
+
+ printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);
+
/*
* we set the default root device to /dev/hda
* to make simulation easy
@@ -578,13 +578,17 @@ void __init sn_cpu_init(void)
sn_prom_type = 2;
else
sn_prom_type = 1;
- printk("Running on medusa with %s PROM\n", (sn_prom_type == 1) ? "real" : "fake");
+ printk(KERN_INFO "Running on medusa with %s PROM\n",
+ (sn_prom_type == 1) ? "real" : "fake");
}
memset(pda, 0, sizeof(pda));
- if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, &sn_hub_info->nasid_bitmask, &sn_hub_info->nasid_shift,
- &sn_system_size, &sn_sharing_domain_size, &sn_partition_id,
- &sn_coherency_id, &sn_region_size))
+ if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2,
+ &sn_hub_info->nasid_bitmask,
+ &sn_hub_info->nasid_shift,
+ &sn_system_size, &sn_sharing_domain_size,
+ &sn_partition_id, &sn_coherency_id,
+ &sn_region_size))
BUG();
sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2;
@@ -716,7 +720,8 @@ void __init build_cnode_tables(void)
for_each_online_node(node) {
kl_config_hdr_t *klgraph_header;
nasid = cnodeid_to_nasid(node);
- if ((klgraph_header = ia64_sn_get_klconfig_addr(nasid)) == NULL)
+ klgraph_header = ia64_sn_get_klconfig_addr(nasid);
+ if (klgraph_header == NULL)
BUG();
brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info);
while (brd) {
@@ -734,7 +739,7 @@ nasid_slice_to_cpuid(int nasid, int slice)
{
long cpu;
- for (cpu=0; cpu < NR_CPUS; cpu++)
+ for (cpu = 0; cpu < NR_CPUS; cpu++)
if (cpuid_to_nasid(cpu) == nasid &&
cpuid_to_slice(cpu) == slice)
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 @@
# sn2 specific kernel files
#
+CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
+
obj-y += cache.o io.o ptc_deadlock.o sn2_smp.o sn_proc_fs.o \
prominfo_proc.o timer.o timer_interrupt.o sn_hwperf.o
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 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2006 Silicon Graphics, Inc. All rights reserved.
*/
#include <linux/init.h>
@@ -46,104 +46,28 @@ DECLARE_PER_CPU(struct ptc_stats, ptcstats);
static __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock);
-void sn2_ptc_deadlock_recovery(short *, short, int, volatile unsigned long *, unsigned long data0,
- volatile unsigned long *, unsigned long data1);
+void sn2_ptc_deadlock_recovery(short *, short, short, int, volatile unsigned long *, unsigned long,
+ volatile unsigned long *, unsigned long);
-#ifdef DEBUG_PTC
/*
- * ptctest:
- *
- * xyz - 3 digit hex number:
- * x - Force PTC purges to use shub:
- * 0 - no force
- * 1 - force
- * y - interupt enable
- * 0 - disable interrupts
- * 1 - leave interuupts enabled
- * z - type of lock:
- * 0 - global lock
- * 1 - node local lock
- * 2 - no lock
- *
- * Note: on shub1, only ptctest == 0 is supported. Don't try other values!
+ * Note: some is the following is captured here to make degugging easier
+ * (the macros make more sense if you see the debug patch - not posted)
*/
-
-static unsigned int sn2_ptctest = 0;
-
-static int __init ptc_test(char *str)
-{
- get_option(&str, &sn2_ptctest);
- return 1;
-}
-__setup("ptctest=", ptc_test);
-
-static inline int ptc_lock(unsigned long *flagp)
-{
- unsigned long opt = sn2_ptctest & 255;
-
- switch (opt) {
- case 0x00:
- spin_lock_irqsave(&sn2_global_ptc_lock, *flagp);
- break;
- case 0x01:
- spin_lock_irqsave(&sn_nodepda->ptc_lock, *flagp);
- break;
- case 0x02:
- local_irq_save(*flagp);
- break;
- case 0x10:
- spin_lock(&sn2_global_ptc_lock);
- break;
- case 0x11:
- spin_lock(&sn_nodepda->ptc_lock);
- break;
- case 0x12:
- break;
- default:
- BUG();
- }
- return opt;
-}
-
-static inline void ptc_unlock(unsigned long flags, int opt)
-{
- switch (opt) {
- case 0x00:
- spin_unlock_irqrestore(&sn2_global_ptc_lock, flags);
- break;
- case 0x01:
- spin_unlock_irqrestore(&sn_nodepda->ptc_lock, flags);
- break;
- case 0x02:
- local_irq_restore(flags);
- break;
- case 0x10:
- spin_unlock(&sn2_global_ptc_lock);
- break;
- case 0x11:
- spin_unlock(&sn_nodepda->ptc_lock);
- break;
- case 0x12:
- break;
- default:
- BUG();
- }
-}
-#else
-
#define sn2_ptctest 0
+#define local_node_uses_ptc_ga(sh1) ((sh1) ? 1 : 0)
+#define max_active_pio(sh1) ((sh1) ? 32 : 7)
+#define reset_max_active_on_deadlock() 1
+#define PTC_LOCK(sh1) ((sh1) ? &sn2_global_ptc_lock : &sn_nodepda->ptc_lock)
-static inline int ptc_lock(unsigned long *flagp)
+static inline void ptc_lock(int sh1, unsigned long *flagp)
{
- spin_lock_irqsave(&sn2_global_ptc_lock, *flagp);
- return 0;
+ spin_lock_irqsave(PTC_LOCK(sh1), *flagp);
}
-static inline void ptc_unlock(unsigned long flags, int opt)
+static inline void ptc_unlock(int sh1, unsigned long flags)
{
- spin_unlock_irqrestore(&sn2_global_ptc_lock, flags);
+ spin_unlock_irqrestore(PTC_LOCK(sh1), flags);
}
-#endif
struct ptc_stats {
unsigned long ptc_l;
@@ -151,27 +75,30 @@ struct ptc_stats {
unsigned long shub_ptc_flushes;
unsigned long nodes_flushed;
unsigned long deadlocks;
+ unsigned long deadlocks2;
unsigned long lock_itc_clocks;
unsigned long shub_itc_clocks;
unsigned long shub_itc_clocks_max;
+ unsigned long shub_ptc_flushes_not_my_mm;
};
static inline unsigned long wait_piowc(void)
{
- volatile unsigned long *piows, zeroval;
- unsigned long ws;
+ volatile unsigned long *piows;
+ unsigned long zeroval, ws;
piows = pda->pio_write_status_addr;
zeroval = pda->pio_write_status_val;
do {
cpu_relax();
} while (((ws = *piows) & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != zeroval);
- return ws;
+ return (ws & SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK) != 0;
}
void sn_tlb_migrate_finish(struct mm_struct *mm)
{
- if (mm == current->mm)
+ /* flush_tlb_mm is inefficient if more than 1 users of mm */
+ if (mm == current->mm && mm && atomic_read(&mm->mm_users) == 1)
flush_tlb_mm(mm);
}
@@ -201,12 +128,14 @@ void
sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
unsigned long end, unsigned long nbits)
{
- int i, opt, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0;
- int mymm = (mm == current->active_mm && current->mm);
+ int i, ibegin, shub1, cnode, mynasid, cpu, lcpu = 0, nasid;
+ int mymm = (mm == current->active_mm && mm == current->mm);
+ int use_cpu_ptcga;
volatile unsigned long *ptc0, *ptc1;
- unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value;
+ unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value, old_rr = 0;
short nasids[MAX_NUMNODES], nix;
nodemask_t nodes_flushed;
+ int active, max_active, deadlock;
nodes_clear(nodes_flushed);
i = 0;
@@ -267,41 +196,56 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
mynasid = get_nasid();
+ use_cpu_ptcga = local_node_uses_ptc_ga(shub1);
+ max_active = max_active_pio(shub1);
itc = ia64_get_itc();
- opt = ptc_lock(&flags);
+ ptc_lock(shub1, &flags);
itc2 = ia64_get_itc();
+
__get_cpu_var(ptcstats).lock_itc_clocks += itc2 - itc;
__get_cpu_var(ptcstats).shub_ptc_flushes++;
__get_cpu_var(ptcstats).nodes_flushed += nix;
+ if (!mymm)
+ __get_cpu_var(ptcstats).shub_ptc_flushes_not_my_mm++;
+ if (use_cpu_ptcga && !mymm) {
+ old_rr = ia64_get_rr(start);
+ ia64_set_rr(start, (old_rr & 0xff) | (rr_value << 8));
+ ia64_srlz_d();
+ }
+
+ wait_piowc();
do {
if (shub1)
data1 = start | (1UL << SH1_PTC_1_START_SHFT);
else
data0 = (data0 & ~SH2_PTC_ADDR_MASK) | (start & SH2_PTC_ADDR_MASK);
- for (i = 0; i < nix; i++) {
+ deadlock = 0;
+ active = 0;
+ for (ibegin = 0, i = 0; i < nix; i++) {
nasid = nasids[i];
- if ((!(sn2_ptctest & 3)) && unlikely(nasid == mynasid && mymm)) {
+ if (use_cpu_ptcga && unlikely(nasid == mynasid)) {
ia64_ptcga(start, nbits << 2);
ia64_srlz_i();
} else {
ptc0 = CHANGE_NASID(nasid, ptc0);
if (ptc1)
ptc1 = CHANGE_NASID(nasid, ptc1);
- pio_atomic_phys_write_mmrs(ptc0, data0, ptc1,
- data1);
- flushed = 1;
+ pio_atomic_phys_write_mmrs(ptc0, data0, ptc1, data1);
+ active++;
+ }
+ if (active >= max_active || i == (nix - 1)) {
+ if ((deadlock = wait_piowc())) {
+ sn2_ptc_deadlock_recovery(nasids, ibegin, i, mynasid, ptc0, data0, ptc1, data1);
+ if (reset_max_active_on_deadlock())
+ max_active = 1;
+ }
+ active = 0;
+ ibegin = i + 1;
}
}
- if (flushed
- && (wait_piowc() &
- (SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK))) {
- sn2_ptc_deadlock_recovery(nasids, nix, mynasid, ptc0, data0, ptc1, data1);
- }
-
start += (1UL << nbits);
-
} while (start < end);
itc2 = ia64_get_itc() - itc2;
@@ -309,7 +253,12 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
if (itc2 > __get_cpu_var(ptcstats).shub_itc_clocks_max)
__get_cpu_var(ptcstats).shub_itc_clocks_max = itc2;
- ptc_unlock(flags, opt);
+ if (old_rr) {
+ ia64_set_rr(start, old_rr);
+ ia64_srlz_d();
+ }
+
+ ptc_unlock(shub1, flags);
preempt_enable();
}
@@ -321,27 +270,30 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
* TLB flush transaction. The recovery sequence is somewhat tricky & is
* coded in assembly language.
*/
-void sn2_ptc_deadlock_recovery(short *nasids, short nix, int mynasid, volatile unsigned long *ptc0, unsigned long data0,
+void sn2_ptc_deadlock_recovery(short *nasids, short ib, short ie, int mynasid, volatile unsigned long *ptc0, unsigned long data0,
volatile unsigned long *ptc1, unsigned long data1)
{
- extern void sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long,
+ extern unsigned long sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long,
volatile unsigned long *, unsigned long, volatile unsigned long *, unsigned long);
short nasid, i;
- unsigned long *piows, zeroval;
+ unsigned long *piows, zeroval, n;
__get_cpu_var(ptcstats).deadlocks++;
piows = (unsigned long *) pda->pio_write_status_addr;
zeroval = pda->pio_write_status_val;
- for (i=0; i < nix; i++) {
+
+ for (i=ib; i <= ie; i++) {
nasid = nasids[i];
- if (!(sn2_ptctest & 3) && nasid == mynasid)
+ if (local_node_uses_ptc_ga(is_shub1()) && nasid == mynasid)
continue;
ptc0 = CHANGE_NASID(nasid, ptc0);
if (ptc1)
ptc1 = CHANGE_NASID(nasid, ptc1);
- sn2_ptc_deadlock_recovery_core(ptc0, data0, ptc1, data1, piows, zeroval);
+
+ n = sn2_ptc_deadlock_recovery_core(ptc0, data0, ptc1, data1, piows, zeroval);
+ __get_cpu_var(ptcstats).deadlocks2 += n;
}
}
@@ -452,20 +404,22 @@ static int sn2_ptc_seq_show(struct seq_file *file, void *data)
cpu = *(loff_t *) data;
if (!cpu) {
- seq_printf(file, "# ptc_l change_rid shub_ptc_flushes shub_nodes_flushed deadlocks lock_nsec shub_nsec shub_nsec_max\n");
+ seq_printf(file,
+ "# cpu ptc_l newrid ptc_flushes nodes_flushed deadlocks lock_nsec shub_nsec shub_nsec_max not_my_mm deadlock2\n");
seq_printf(file, "# ptctest %d\n", sn2_ptctest);
}
if (cpu < NR_CPUS && cpu_online(cpu)) {
stat = &per_cpu(ptcstats, cpu);
- seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l,
+ seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l,
stat->change_rid, stat->shub_ptc_flushes, stat->nodes_flushed,
stat->deadlocks,
1000 * stat->lock_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec,
1000 * stat->shub_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec,
- 1000 * stat->shub_itc_clocks_max / per_cpu(cpu_info, cpu).cyc_per_usec);
+ 1000 * stat->shub_itc_clocks_max / per_cpu(cpu_info, cpu).cyc_per_usec,
+ stat->shub_ptc_flushes_not_my_mm,
+ stat->deadlocks2);
}
-
return 0;
}
@@ -476,7 +430,7 @@ static struct seq_operations sn2_ptc_seq_ops = {
.show = sn2_ptc_seq_show
};
-int sn2_ptc_proc_open(struct inode *inode, struct file *file)
+static int sn2_ptc_proc_open(struct inode *inode, struct file *file)
{
return seq_open(file, &sn2_ptc_seq_ops);
}
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 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2004-2005 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2004-2006 Silicon Graphics, Inc. All rights reserved.
*
* SGI Altix topology and hardware performance monitoring API.
* Mark Goodwin <markgw@sgi.com>.
@@ -973,6 +973,9 @@ static int __devinit sn_hwperf_misc_register_init(void)
{
int e;
+ if (!ia64_platform_is("sn2"))
+ return 0;
+
sn_hwperf_init();
/*
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)
nbytes = nentries * ch->msg_size;
ch->local_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes,
- (GFP_KERNEL | GFP_DMA),
+ GFP_KERNEL,
&ch->local_msgqueue_base);
if (ch->local_msgqueue == NULL) {
continue;
@@ -455,7 +455,7 @@ xpc_allocate_local_msgqueue(struct xpc_channel *ch)
memset(ch->local_msgqueue, 0, nbytes);
nbytes = nentries * sizeof(struct xpc_notify);
- ch->notify_queue = kmalloc(nbytes, (GFP_KERNEL | GFP_DMA));
+ ch->notify_queue = kmalloc(nbytes, GFP_KERNEL);
if (ch->notify_queue == NULL) {
kfree(ch->local_msgqueue_base);
ch->local_msgqueue = NULL;
@@ -502,7 +502,7 @@ xpc_allocate_remote_msgqueue(struct xpc_channel *ch)
nbytes = nentries * ch->msg_size;
ch->remote_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes,
- (GFP_KERNEL | GFP_DMA),
+ GFP_KERNEL,
&ch->remote_msgqueue_base);
if (ch->remote_msgqueue == NULL) {
continue;
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index c75f8aeefc2b..9cd460dfe27e 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)
spin_lock_irqsave(&part->act_lock, irq_flags);
- pid = kernel_thread(xpc_activating, (void *) ((u64) partid), 0);
-
DBUG_ON(part->act_state != XPC_P_INACTIVE);
- if (pid > 0) {
- part->act_state = XPC_P_ACTIVATION_REQ;
- XPC_SET_REASON(part, xpcCloneKThread, __LINE__);
- } else {
- XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__);
- }
+ part->act_state = XPC_P_ACTIVATION_REQ;
+ XPC_SET_REASON(part, xpcCloneKThread, __LINE__);
spin_unlock_irqrestore(&part->act_lock, irq_flags);
+
+ pid = kernel_thread(xpc_activating, (void *) ((u64) partid), 0);
+
+ if (unlikely(pid <= 0)) {
+ spin_lock_irqsave(&part->act_lock, irq_flags);
+ part->act_state = XPC_P_INACTIVE;
+ XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__);
+ spin_unlock_irqrestore(&part->act_lock, irq_flags);
+ }
}
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 @@
#
# Makefile for the sn pci general routines.
+CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
+
obj-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..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,
*/
node = pcibus_to_node(pdev->bus);
if (likely(node >=0)) {
- struct page *p = alloc_pages_node(node, GFP_ATOMIC, get_order(size));
+ struct page *p = alloc_pages_node(node, flags, get_order(size));
if (likely(p))
cpuaddr = page_address(p);
else
return NULL;
} else
- cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size));
+ cpuaddr = (void *)__get_free_pages(flags, get_order(size));
if (unlikely(!cpuaddr))
return NULL;
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 @@
#
# Makefile for the sn2 io routines.
+CPPFLAGS += -I$(srctree)/arch/ia64/sn/include
+
obj-y += pcibr_dma.o pcibr_reg.o \
pcibr_ate.o pcibr_provider.o