summaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/ia32/sys_ia32.c28
-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/mca_asm.S2
-rw-r--r--arch/ia64/kernel/perfmon.c11
-rw-r--r--arch/ia64/kernel/topology.c18
-rw-r--r--arch/ia64/kernel/unaligned.c3
-rw-r--r--arch/ia64/kernel/uncached.c1
-rw-r--r--arch/ia64/pci/pci.c10
-rw-r--r--arch/ia64/sn/include/xtalk/hubdev.h9
-rw-r--r--arch/ia64/sn/kernel/io_init.c60
-rw-r--r--arch/ia64/sn/kernel/mca.c7
-rw-r--r--arch/ia64/sn/kernel/xp_main.c17
-rw-r--r--arch/ia64/sn/kernel/xpc_channel.c40
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c17
-rw-r--r--arch/ia64/sn/pci/pci_dma.c4
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_provider.c12
21 files changed, 236 insertions, 155 deletions
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index 3945d37..70dba1f 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -52,9 +52,9 @@
#include <linux/compat.h>
#include <linux/vfs.h>
#include <linux/mman.h>
+#include <linux/mutex.h>
#include <asm/intrinsics.h>
-#include <asm/semaphore.h>
#include <asm/types.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -86,7 +86,7 @@
* while doing so.
*/
/* XXX make per-mm: */
-static DECLARE_MUTEX(ia32_mmap_sem);
+static DEFINE_MUTEX(ia32_mmap_mutex);
asmlinkage long
sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __user *envp,
@@ -895,11 +895,11 @@ ia32_do_mmap (struct file *file, unsigned long addr, unsigned long len, int prot
prot = get_prot32(prot);
#if PAGE_SHIFT > IA32_PAGE_SHIFT
- down(&ia32_mmap_sem);
+ mutex_lock(&ia32_mmap_mutex);
{
addr = emulate_mmap(file, addr, len, prot, flags, offset);
}
- up(&ia32_mmap_sem);
+ mutex_unlock(&ia32_mmap_mutex);
#else
down_write(&current->mm->mmap_sem);
{
@@ -1000,11 +1000,9 @@ sys32_munmap (unsigned int start, unsigned int len)
if (start >= end)
return 0;
- down(&ia32_mmap_sem);
- {
- ret = sys_munmap(start, end - start);
- }
- up(&ia32_mmap_sem);
+ mutex_lock(&ia32_mmap_mutex);
+ ret = sys_munmap(start, end - start);
+ mutex_unlock(&ia32_mmap_mutex);
#endif
return ret;
}
@@ -1056,7 +1054,7 @@ sys32_mprotect (unsigned int start, unsigned int len, int prot)
if (retval < 0)
return retval;
- down(&ia32_mmap_sem);
+ mutex_lock(&ia32_mmap_mutex);
{
if (offset_in_page(start)) {
/* start address is 4KB aligned but not page aligned. */
@@ -1080,7 +1078,7 @@ sys32_mprotect (unsigned int start, unsigned int len, int prot)
retval = sys_mprotect(start, end - start, prot);
}
out:
- up(&ia32_mmap_sem);
+ mutex_unlock(&ia32_mmap_mutex);
return retval;
#endif
}
@@ -1124,11 +1122,9 @@ sys32_mremap (unsigned int addr, unsigned int old_len, unsigned int new_len,
old_len = PAGE_ALIGN(old_end) - addr;
new_len = PAGE_ALIGN(new_end) - addr;
- down(&ia32_mmap_sem);
- {
- ret = sys_mremap(addr, old_len, new_len, flags, new_addr);
- }
- up(&ia32_mmap_sem);
+ mutex_lock(&ia32_mmap_mutex);
+ ret = sys_mremap(addr, old_len, new_len, flags, new_addr);
+ mutex_unlock(&ia32_mmap_mutex);
if ((ret >= 0) && (old_len < new_len)) {
/* mremap expanded successfully */
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 307514f..09a0dbc 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 13a5b3b..4a5574f 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 0000000..e683630
--- /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 9ad94dd..d2702c4 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 f748d34..4838f2a 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 da4d5cf..5a1bf81 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/mca_asm.S b/arch/ia64/kernel/mca_asm.S
index 403a80a..60a464b 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/perfmon.c b/arch/ia64/kernel/perfmon.c
index 2ea4b39..9c5194b 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -40,6 +40,7 @@
#include <linux/bitops.h>
#include <linux/capability.h>
#include <linux/rcupdate.h>
+#include <linux/completion.h>
#include <asm/errno.h>
#include <asm/intrinsics.h>
@@ -286,7 +287,7 @@ typedef struct pfm_context {
unsigned long ctx_ovfl_regs[4]; /* which registers overflowed (notification) */
- struct semaphore ctx_restart_sem; /* use for blocking notification mode */
+ struct completion ctx_restart_done; /* use for blocking notification mode */
unsigned long ctx_used_pmds[4]; /* bitmask of PMD used */
unsigned long ctx_all_pmds[4]; /* bitmask of all accessible PMDs */
@@ -1991,7 +1992,7 @@ pfm_close(struct inode *inode, struct file *filp)
/*
* force task to wake up from MASKED state
*/
- up(&ctx->ctx_restart_sem);
+ complete(&ctx->ctx_restart_done);
DPRINT(("waking up ctx_state=%d\n", state));
@@ -2706,7 +2707,7 @@ pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
/*
* init restart semaphore to locked
*/
- sema_init(&ctx->ctx_restart_sem, 0);
+ init_completion(&ctx->ctx_restart_done);
/*
* activation is used in SMP only
@@ -3687,7 +3688,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
*/
if (CTX_OVFL_NOBLOCK(ctx) == 0 && state == PFM_CTX_MASKED) {
DPRINT(("unblocking [%d] \n", task->pid));
- up(&ctx->ctx_restart_sem);
+ complete(&ctx->ctx_restart_done);
} else {
DPRINT(("[%d] armed exit trap\n", task->pid));
@@ -5089,7 +5090,7 @@ pfm_handle_work(void)
* may go through without blocking on SMP systems
* if restart has been received already by the time we call down()
*/
- ret = down_interruptible(&ctx->ctx_restart_sem);
+ ret = wait_for_completion_interruptible(&ctx->ctx_restart_done);
DPRINT(("after block sleeping ret=%d\n", ret));
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
index 706b773..6e5eea1 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 43b45b6..f9e0ae9 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/kernel/uncached.c b/arch/ia64/kernel/uncached.c
index b631cf8..fcd2bad 100644
--- a/arch/ia64/kernel/uncached.c
+++ b/arch/ia64/kernel/uncached.c
@@ -210,6 +210,7 @@ uncached_build_memmap(unsigned long start, unsigned long end, void *arg)
dprintk(KERN_ERR "uncached_build_memmap(%lx %lx)\n", start, end);
+ touch_softlockup_watchdog();
memset((char *)start, 0, length);
node = paddr_to_nid(start - __IA64_UNCACHED_OFFSET);
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index d27ecdc..0b30ca0 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/include/xtalk/hubdev.h b/arch/ia64/sn/include/xtalk/hubdev.h
index 7c88e9a..8182583 100644
--- a/arch/ia64/sn/include/xtalk/hubdev.h
+++ b/arch/ia64/sn/include/xtalk/hubdev.h
@@ -51,6 +51,15 @@ struct sn_flush_device_kernel {
struct sn_flush_device_common *common;
};
+/* 01/16/06 This struct is the old PROM/kernel struct and needs to be included
+ * for older official PROMs to function on the new kernel base. This struct
+ * will be removed when the next official PROM release occurs. */
+
+struct sn_flush_device_war {
+ struct sn_flush_device_common common;
+ u32 filler; /* older PROMs expect the default size of a spinlock_t */
+};
+
/*
* **widget_p - Used as an array[wid_num][device] of sn_flush_device_kernel.
*/
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 233d551..a4c7815 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>
@@ -165,8 +166,46 @@ sn_pcidev_info_get(struct pci_dev *dev)
return NULL;
}
+/* Older PROM flush WAR
+ *
+ * 01/16/06 -- This war will be in place until a new official PROM is released.
+ * Additionally note that the struct sn_flush_device_war also has to be
+ * removed from arch/ia64/sn/include/xtalk/hubdev.h
+ */
+static u8 war_implemented = 0;
+
+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;
+ struct ia64_sal_retval isrv = {0,0,0,0};
+
+ if (!war_implemented) {
+ printk(KERN_WARNING "PROM version < 4.50 -- implementing old "
+ "PROM flush WAR\n");
+ war_implemented = 1;
+ }
+
+ war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL);
+ if (!war_list)
+ BUG();
+
+ SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST,
+ nasid, widget, __pa(war_list), 0, 0, 0 ,0);
+ if (isrv.status)
+ panic("sn_device_fixup_war failed: %s\n",
+ ia64_sal_strerror(isrv.status));
+
+ 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
+ * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for
* each node in the system.
*/
static void sn_fixup_ionodes(void)
@@ -242,12 +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)
- BUG();
+ else
+ status = sn_device_fixup_war(nasid,
+ widget,
+ device,
+ dev_entry->common);
+ if (status != SALRET_OK)
+ panic("SAL call failed: %s\n",
+ ia64_sal_strerror(status));
spin_lock_init(&dev_entry->sfdl_flush_lock);
}
diff --git a/arch/ia64/sn/kernel/mca.c b/arch/ia64/sn/kernel/mca.c
index 6546db6..9ab684d 100644
--- a/arch/ia64/sn/kernel/mca.c
+++ b/arch/ia64/sn/kernel/mca.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/vmalloc.h>
+#include <linux/mutex.h>
#include <asm/mca.h>
#include <asm/sal.h>
#include <asm/sn/sn_sal.h>
@@ -27,7 +28,7 @@ void sn_init_cpei_timer(void);
/* Printing oemdata from mca uses data that is not passed through SAL, it is
* global. Only one user at a time.
*/
-static DECLARE_MUTEX(sn_oemdata_mutex);
+static DEFINE_MUTEX(sn_oemdata_mutex);
static u8 **sn_oemdata;
static u64 *sn_oemdata_size, sn_oemdata_bufsize;
@@ -89,7 +90,7 @@ static int
sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata,
u64 * oemdata_size)
{
- down(&sn_oemdata_mutex);
+ mutex_lock(&sn_oemdata_mutex);
sn_oemdata = oemdata;
sn_oemdata_size = oemdata_size;
sn_oemdata_bufsize = 0;
@@ -107,7 +108,7 @@ sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata,
*sn_oemdata_size = 0;
ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header);
}
- up(&sn_oemdata_mutex);
+ mutex_unlock(&sn_oemdata_mutex);
return 0;
}
diff --git a/arch/ia64/sn/kernel/xp_main.c b/arch/ia64/sn/kernel/xp_main.c
index 3be52a3..b7ea466 100644
--- a/arch/ia64/sn/kernel/xp_main.c
+++ b/arch/ia64/sn/kernel/xp_main.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <asm/sn/intr.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/xp.h>
@@ -136,13 +137,13 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
registration = &xpc_registrations[ch_number];
- if (down_interruptible(&registration->sema) != 0) {
+ if (mutex_lock_interruptible(&registration->mutex) != 0) {
return xpcInterrupted;
}
/* if XPC_CHANNEL_REGISTERED(ch_number) */
if (registration->func != NULL) {
- up(&registration->sema);
+ mutex_unlock(&registration->mutex);
return xpcAlreadyRegistered;
}
@@ -154,7 +155,7 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
registration->key = key;
registration->func = func;
- up(&registration->sema);
+ mutex_unlock(&registration->mutex);
xpc_interface.connect(ch_number);
@@ -190,11 +191,11 @@ xpc_disconnect(int ch_number)
* figured XPC's users will just turn around and call xpc_disconnect()
* again anyways, so we might as well wait, if need be.
*/
- down(&registration->sema);
+ mutex_lock(&registration->mutex);
/* if !XPC_CHANNEL_REGISTERED(ch_number) */
if (registration->func == NULL) {
- up(&registration->sema);
+ mutex_unlock(&registration->mutex);
return;
}
@@ -208,7 +209,7 @@ xpc_disconnect(int ch_number)
xpc_interface.disconnect(ch_number);
- up(&registration->sema);
+ mutex_unlock(&registration->mutex);
return;
}
@@ -250,9 +251,9 @@ xp_init(void)
xp_nofault_PIOR_target = SH1_IPI_ACCESS;
}
- /* initialize the connection registration semaphores */
+ /* initialize the connection registration mutex */
for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++) {
- sema_init(&xpc_registrations[ch_number].sema, 1); /* mutex */
+ mutex_init(&xpc_registrations[ch_number].mutex);
}
return 0;
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
index 0c0a689..36e5437 100644
--- a/arch/ia64/sn/kernel/xpc_channel.c
+++ b/arch/ia64/sn/kernel/xpc_channel.c
@@ -22,6 +22,8 @@
#include <linux/cache.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/completion.h>
#include <asm/sn/bte.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/xpc.h>
@@ -56,8 +58,8 @@ xpc_initialize_channels(struct xpc_partition *part, partid_t partid)
atomic_set(&ch->n_to_notify, 0);
spin_lock_init(&ch->lock);
- sema_init(&ch->msg_to_pull_sema, 1); /* mutex */
- sema_init(&ch->wdisconnect_sema, 0); /* event wait */
+ mutex_init(&ch->msg_to_pull_mutex);
+ init_completion(&ch->wdisconnect_wait);
atomic_set(&ch->n_on_msg_allocate_wq, 0);
init_waitqueue_head(&ch->msg_allocate_wq);
@@ -445,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;
@@ -453,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;
@@ -500,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;
@@ -534,7 +536,6 @@ static enum xpc_retval
xpc_allocate_msgqueues(struct xpc_channel *ch)
{
unsigned long irq_flags;
- int i;
enum xpc_retval ret;
@@ -552,11 +553,6 @@ xpc_allocate_msgqueues(struct xpc_channel *ch)
return ret;
}
- for (i = 0; i < ch->local_nentries; i++) {
- /* use a semaphore as an event wait queue */
- sema_init(&ch->notify_queue[i].sema, 0);
- }
-
spin_lock_irqsave(&ch->lock, irq_flags);
ch->flags |= XPC_C_SETUP;
spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -799,10 +795,8 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
}
if (ch->flags & XPC_C_WDISCONNECT) {
- spin_unlock_irqrestore(&ch->lock, *irq_flags);
- up(&ch->wdisconnect_sema);
- spin_lock_irqsave(&ch->lock, *irq_flags);
-
+ /* we won't lose the CPU since we're holding ch->lock */
+ complete(&ch->wdisconnect_wait);
} else if (ch->delayed_IPI_flags) {
if (part->act_state != XPC_P_DEACTIVATING) {
/* time to take action on any delayed IPI flags */
@@ -1092,12 +1086,12 @@ xpc_connect_channel(struct xpc_channel *ch)
struct xpc_registration *registration = &xpc_registrations[ch->number];
- if (down_trylock(&registration->sema) != 0) {
+ if (mutex_trylock(&registration->mutex) == 0) {
return xpcRetry;
}
if (!XPC_CHANNEL_REGISTERED(ch->number)) {
- up(&registration->sema);
+ mutex_unlock(&registration->mutex);
return xpcUnregistered;
}
@@ -1108,7 +1102,7 @@ xpc_connect_channel(struct xpc_channel *ch)
if (ch->flags & XPC_C_DISCONNECTING) {
spin_unlock_irqrestore(&ch->lock, irq_flags);
- up(&registration->sema);
+ mutex_unlock(&registration->mutex);
return ch->reason;
}
@@ -1140,7 +1134,7 @@ xpc_connect_channel(struct xpc_channel *ch)
* channel lock be locked and will unlock and relock
* the channel lock as needed.
*/
- up(&registration->sema);
+ mutex_unlock(&registration->mutex);
XPC_DISCONNECT_CHANNEL(ch, xpcUnequalMsgSizes,
&irq_flags);
spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -1155,7 +1149,7 @@ xpc_connect_channel(struct xpc_channel *ch)
atomic_inc(&xpc_partitions[ch->partid].nchannels_active);
}
- up(&registration->sema);
+ mutex_unlock(&registration->mutex);
/* initiate the connection */
@@ -2089,7 +2083,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
enum xpc_retval ret;
- if (down_interruptible(&ch->msg_to_pull_sema) != 0) {
+ if (mutex_lock_interruptible(&ch->msg_to_pull_mutex) != 0) {
/* we were interrupted by a signal */
return NULL;
}
@@ -2125,7 +2119,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
XPC_DEACTIVATE_PARTITION(part, ret);
- up(&ch->msg_to_pull_sema);
+ mutex_unlock(&ch->msg_to_pull_mutex);
return NULL;
}
@@ -2134,7 +2128,7 @@ xpc_pull_remote_msg(struct xpc_channel *ch, s64 get)
ch->next_msg_to_pull += nmsgs;
}
- up(&ch->msg_to_pull_sema);
+ mutex_unlock(&ch->msg_to_pull_mutex);
/* return the message we were looking for */
msg_offset = (get % ch->remote_nentries) * ch->msg_size;
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index 8930586e..c75f8ae 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -55,6 +55,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/reboot.h>
+#include <linux/completion.h>
#include <asm/sn/intr.h>
#include <asm/sn/sn_sal.h>
#include <asm/kdebug.h>
@@ -177,10 +178,10 @@ static DECLARE_WAIT_QUEUE_HEAD(xpc_act_IRQ_wq);
static unsigned long xpc_hb_check_timeout;
/* notification that the xpc_hb_checker thread has exited */
-static DECLARE_MUTEX_LOCKED(xpc_hb_checker_exited);
+static DECLARE_COMPLETION(xpc_hb_checker_exited);
/* notification that the xpc_discovery thread has exited */
-static DECLARE_MUTEX_LOCKED(xpc_discovery_exited);
+static DECLARE_COMPLETION(xpc_discovery_exited);
static struct timer_list xpc_hb_timer;
@@ -321,7 +322,7 @@ xpc_hb_checker(void *ignore)
/* mark this thread as having exited */
- up(&xpc_hb_checker_exited);
+ complete(&xpc_hb_checker_exited);
return 0;
}
@@ -341,7 +342,7 @@ xpc_initiate_discovery(void *ignore)
dev_dbg(xpc_part, "discovery thread is exiting\n");
/* mark this thread as having exited */
- up(&xpc_discovery_exited);
+ complete(&xpc_discovery_exited);
return 0;
}
@@ -893,7 +894,7 @@ xpc_disconnect_wait(int ch_number)
continue;
}
- (void) down(&ch->wdisconnect_sema);
+ wait_for_completion(&ch->wdisconnect_wait);
spin_lock_irqsave(&ch->lock, irq_flags);
DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED));
@@ -946,10 +947,10 @@ xpc_do_exit(enum xpc_retval reason)
free_irq(SGI_XPC_ACTIVATE, NULL);
/* wait for the discovery thread to exit */
- down(&xpc_discovery_exited);
+ wait_for_completion(&xpc_discovery_exited);
/* wait for the heartbeat checker thread to exit */
- down(&xpc_hb_checker_exited);
+ wait_for_completion(&xpc_hb_checker_exited);
/* sleep for a 1/3 of a second or so */
@@ -1367,7 +1368,7 @@ xpc_init(void)
dev_err(xpc_part, "failed while forking discovery thread\n");
/* mark this new thread as a non-starter */
- up(&xpc_discovery_exited);
+ complete(&xpc_discovery_exited);
xpc_do_exit(xpcUnloading);
return -EBUSY;
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index 9bf9f23..5a36292 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/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
index 77a1262..2fac270 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
@@ -24,13 +24,15 @@ sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp)
{
struct ia64_sal_retval ret_stuff;
u64 busnum;
+ u64 segment;
ret_stuff.status = 0;
ret_stuff.v0 = 0;
+ segment = soft->pbi_buscommon.bs_persist_segment;
busnum = soft->pbi_buscommon.bs_persist_busnum;
- SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, (u64) busnum,
- (u64) device, (u64) resp, 0, 0, 0, 0);
+ SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, segment,
+ busnum, (u64) device, (u64) resp, 0, 0, 0);
return (int)ret_stuff.v0;
}
@@ -41,14 +43,16 @@ sal_pcibr_slot_disable(struct pcibus_info *soft, int device, int action,
{
struct ia64_sal_retval ret_stuff;
u64 busnum;
+ u64 segment;
ret_stuff.status = 0;
ret_stuff.v0 = 0;
+ segment = soft->pbi_buscommon.bs_persist_segment;
busnum = soft->pbi_buscommon.bs_persist_busnum;
SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_DISABLE,
- (u64) busnum, (u64) device, (u64) action,
- (u64) resp, 0, 0, 0);
+ segment, busnum, (u64) device, (u64) action,
+ (u64) resp, 0, 0);
return (int)ret_stuff.v0;
}
OpenPOWER on IntegriCloud