aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/kernel/armksyms.c1
-rw-r--r--arch/arm/kernel/entry-common.S3
-rw-r--r--arch/arm/kernel/signal.c25
-rw-r--r--arch/arm/kernel/vmlinux.lds.S6
-rw-r--r--arch/arm/lib/getuser.S11
-rw-r--r--arch/arm/mach-clps7500/core.c2
-rw-r--r--arch/arm/mach-pxa/tosa.c2
-rw-r--r--arch/arm/mach-sa1100/assabet.c3
-rw-r--r--arch/arm/mm/Makefile2
-rw-r--r--arch/arm/mm/blockops.c185
-rw-r--r--arch/arm/mm/init.c24
-rw-r--r--arch/arm/mm/ioremap.c3
-rw-r--r--arch/i386/kernel/acpi/boot.c4
-rw-r--r--arch/i386/kernel/mpparse.c5
-rw-r--r--arch/ia64/sn/kernel/bte.c1
-rw-r--r--arch/ia64/sn/kernel/sn2/sn2_smp.c3
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_hwperf.c3
-rw-r--r--arch/parisc/kernel/drivers.c8
-rw-r--r--arch/parisc/kernel/entry.S1
-rw-r--r--arch/parisc/kernel/inventory.c2
-rw-r--r--arch/parisc/kernel/ioctl32.c546
-rw-r--r--arch/parisc/kernel/irq.c110
-rw-r--r--arch/parisc/kernel/perf.c33
-rw-r--r--arch/parisc/kernel/ptrace.c5
-rw-r--r--arch/parisc/kernel/signal.c1
-rw-r--r--arch/parisc/kernel/smp.c24
-rw-r--r--arch/parisc/kernel/syscall.S3
-rw-r--r--arch/powerpc/kernel/pci_64.c18
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c3
-rw-r--r--arch/powerpc/kernel/ptrace-common.h164
-rw-r--r--arch/powerpc/kernel/ptrace.c3
-rw-r--r--arch/powerpc/kernel/ptrace32.c3
-rw-r--r--arch/powerpc/mm/imalloc.c3
-rw-r--r--arch/powerpc/mm/init_64.c3
-rw-r--r--arch/powerpc/mm/mmu_decl.h14
-rw-r--r--arch/powerpc/mm/pgtable_64.c3
-rw-r--r--arch/powerpc/platforms/powermac/smp.c6
-rw-r--r--arch/powerpc/sysdev/mpic.c13
38 files changed, 390 insertions, 859 deletions
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 7a3261f0bf7..9997098009a 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -120,7 +120,6 @@ EXPORT_SYMBOL(__arch_strncpy_from_user);
EXPORT_SYMBOL(__get_user_1);
EXPORT_SYMBOL(__get_user_2);
EXPORT_SYMBOL(__get_user_4);
-EXPORT_SYMBOL(__get_user_8);
EXPORT_SYMBOL(__put_user_1);
EXPORT_SYMBOL(__put_user_2);
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 066597f4345..f7f18307523 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -48,8 +48,7 @@ work_pending:
mov r0, sp @ 'regs'
mov r2, why @ 'syscall'
bl do_notify_resume
- disable_irq @ disable interrupts
- b no_work_pending
+ b ret_slow_syscall @ Check work again
work_resched:
bl schedule
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index a917e3dd366..765922bcf9e 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -595,23 +595,22 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
*/
ret |= !valid_user_regs(regs);
- /*
- * Block the signal if we were unsuccessful.
- */
if (ret != 0) {
- spin_lock_irq(&tsk->sighand->siglock);
- sigorsets(&tsk->blocked, &tsk->blocked,
- &ka->sa.sa_mask);
- if (!(ka->sa.sa_flags & SA_NODEFER))
- sigaddset(&tsk->blocked, sig);
- recalc_sigpending();
- spin_unlock_irq(&tsk->sighand->siglock);
+ force_sigsegv(sig, tsk);
+ return;
}
- if (ret == 0)
- return;
+ /*
+ * Block the signal if we were successful.
+ */
+ spin_lock_irq(&tsk->sighand->siglock);
+ sigorsets(&tsk->blocked, &tsk->blocked,
+ &ka->sa.sa_mask);
+ if (!(ka->sa.sa_flags & SA_NODEFER))
+ sigaddset(&tsk->blocked, sig);
+ recalc_sigpending();
+ spin_unlock_irq(&tsk->sighand->siglock);
- force_sigsegv(sig, tsk);
}
/*
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 80c8e4c8cef..9a47770114d 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -172,6 +172,10 @@ SECTIONS
.comment 0 : { *(.comment) }
}
-/* those must never be empty */
+/*
+ * These must never be empty
+ * If you have to comment these two assert statements out, your
+ * binutils is too old (for other reasons as well)
+ */
ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")
ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index d204018070a..c03ea8e666b 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -54,15 +54,6 @@ __get_user_4:
mov r0, #0
mov pc, lr
- .global __get_user_8
-__get_user_8:
-5: ldrt r2, [r0], #4
-6: ldrt r3, [r0]
- mov r0, #0
- mov pc, lr
-
-__get_user_bad_8:
- mov r3, #0
__get_user_bad:
mov r2, #0
mov r0, #-EFAULT
@@ -73,6 +64,4 @@ __get_user_bad:
.long 2b, __get_user_bad
.long 3b, __get_user_bad
.long 4b, __get_user_bad
- .long 5b, __get_user_bad_8
- .long 6b, __get_user_bad_8
.previous
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
index 0364ba4b539..d869af0023f 100644
--- a/arch/arm/mach-clps7500/core.c
+++ b/arch/arm/mach-clps7500/core.c
@@ -260,7 +260,7 @@ static void __init clps7500_init_irq(void)
static struct map_desc cl7500_io_desc[] __initdata = {
{ /* IO space */
- .virtual = IO_BASE,
+ .virtual = (unsigned long)IO_BASE,
.pfn = __phys_to_pfn(IO_START),
.length = IO_SIZE,
.type = MT_DEVICE
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index c312054dfb8..e4f92efc616 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -14,7 +14,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 75efb5da5b6..a66ac61233a 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -293,7 +293,8 @@ static void __init get_assabet_scr(void)
GPDR |= 0x3fc; /* Configure GPIO 9:2 as outputs */
GPSR = 0x3fc; /* Write 0xFF to GPIO 9:2 */
GPDR &= ~(0x3fc); /* Configure GPIO 9:2 as inputs */
- for(i = 100; i--; scr = GPLR); /* Read GPIO 9:2 */
+ for(i = 100; i--; ) /* Read GPIO 9:2 */
+ scr = GPLR;
GPDR |= 0x3fc; /* restore correct pin direction */
scr &= 0x3fc; /* save as system configuration byte. */
SCR_value = scr;
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 59f47d4c2df..ffe73ba2bf1 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -51,4 +51,4 @@ obj-$(CONFIG_CPU_ARM1026) += proc-arm1026.o
obj-$(CONFIG_CPU_SA110) += proc-sa110.o
obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o
obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o
-obj-$(CONFIG_CPU_V6) += proc-v6.o blockops.o
+obj-$(CONFIG_CPU_V6) += proc-v6.o
diff --git a/arch/arm/mm/blockops.c b/arch/arm/mm/blockops.c
deleted file mode 100644
index 4f5ee2d0899..00000000000
--- a/arch/arm/mm/blockops.c
+++ /dev/null
@@ -1,185 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-
-#include <asm/memory.h>
-#include <asm/ptrace.h>
-#include <asm/cacheflush.h>
-#include <asm/traps.h>
-
-extern struct cpu_cache_fns blk_cache_fns;
-
-#define HARVARD_CACHE
-
-/*
- * blk_flush_kern_dcache_page(kaddr)
- *
- * Ensure that the data held in the page kaddr is written back
- * to the page in question.
- *
- * - kaddr - kernel address (guaranteed to be page aligned)
- */
-static void __attribute__((naked))
-blk_flush_kern_dcache_page(void *kaddr)
-{
- asm(
- "add r1, r0, %0 \n\
- sub r1, r1, %1 \n\
-1: .word 0xec401f0e @ mcrr p15, 0, r0, r1, c14, 0 @ blocking \n\
- mov r0, #0 \n\
- mcr p15, 0, r0, c7, c5, 0 \n\
- mcr p15, 0, r0, c7, c10, 4 \n\
- mov pc, lr"
- :
- : "I" (PAGE_SIZE), "I" (L1_CACHE_BYTES));
-}
-
-/*
- * blk_dma_inv_range(start,end)
- *
- * Invalidate the data cache within the specified region; we will
- * be performing a DMA operation in this region and we want to
- * purge old data in the cache.
- *
- * - start - virtual start address of region
- * - end - virtual end address of region
- */
-static void __attribute__((naked))
-blk_dma_inv_range_unified(unsigned long start, unsigned long end)
-{
- asm(
- "tst r0, %0 \n\
- mcrne p15, 0, r0, c7, c11, 1 @ clean unified line \n\
- tst r1, %0 \n\
- mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line\n\
- .word 0xec401f06 @ mcrr p15, 0, r1, r0, c6, 0 @ blocking \n\
- mov r0, #0 \n\
- mcr p15, 0, r0, c7, c10, 4 @ drain write buffer \n\
- mov pc, lr"
- :
- : "I" (L1_CACHE_BYTES - 1));
-}
-
-static void __attribute__((naked))
-blk_dma_inv_range_harvard(unsigned long start, unsigned long end)
-{
- asm(
- "tst r0, %0 \n\
- mcrne p15, 0, r0, c7, c10, 1 @ clean D line \n\
- tst r1, %0 \n\
- mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line \n\
- .word 0xec401f06 @ mcrr p15, 0, r1, r0, c6, 0 @ blocking \n\
- mov r0, #0 \n\
- mcr p15, 0, r0, c7, c10, 4 @ drain write buffer \n\
- mov pc, lr"
- :
- : "I" (L1_CACHE_BYTES - 1));
-}
-
-/*
- * blk_dma_clean_range(start,end)
- * - start - virtual start address of region
- * - end - virtual end address of region
- */
-static void __attribute__((naked))
-blk_dma_clean_range(unsigned long start, unsigned long end)
-{
- asm(
- ".word 0xec401f0c @ mcrr p15, 0, r1, r0, c12, 0 @ blocking \n\
- mov r0, #0 \n\
- mcr p15, 0, r0, c7, c10, 4 @ drain write buffer \n\
- mov pc, lr");
-}
-
-/*
- * blk_dma_flush_range(start,end)
- * - start - virtual start address of region
- * - end - virtual end address of region
- */
-static void __attribute__((naked))
-blk_dma_flush_range(unsigned long start, unsigned long end)
-{
- asm(
- ".word 0xec401f0e @ mcrr p15, 0, r1, r0, c14, 0 @ blocking \n\
- mov pc, lr");
-}
-
-static int blockops_trap(struct pt_regs *regs, unsigned int instr)
-{
- regs->ARM_r4 |= regs->ARM_r2;
- regs->ARM_pc += 4;
- return 0;
-}
-
-static char *func[] = {
- "Prefetch data range",
- "Clean+Invalidate data range",
- "Clean data range",
- "Invalidate data range",
- "Invalidate instr range"
-};
-
-static struct undef_hook blockops_hook __initdata = {
- .instr_mask = 0x0fffffd0,
- .instr_val = 0x0c401f00,
- .cpsr_mask = PSR_T_BIT,
- .cpsr_val = 0,
- .fn = blockops_trap,
-};
-
-static int __init blockops_check(void)
-{
- register unsigned int err asm("r4") = 0;
- unsigned int err_pos = 1;
- unsigned int cache_type;
- int i;
-
- asm("mrc p15, 0, %0, c0, c0, 1" : "=r" (cache_type));
-
- printk("Checking V6 block cache operations:\n");
- register_undef_hook(&blockops_hook);
-
- __asm__ ("mov r0, %0\n\t"
- "mov r1, %1\n\t"
- "mov r2, #1\n\t"
- ".word 0xec401f2c @ mcrr p15, 0, r1, r0, c12, 2\n\t"
- "mov r2, #2\n\t"
- ".word 0xec401f0e @ mcrr p15, 0, r1, r0, c14, 0\n\t"
- "mov r2, #4\n\t"
- ".word 0xec401f0c @ mcrr p15, 0, r1, r0, c12, 0\n\t"
- "mov r2, #8\n\t"
- ".word 0xec401f06 @ mcrr p15, 0, r1, r0, c6, 0\n\t"
- "mov r2, #16\n\t"
- ".word 0xec401f05 @ mcrr p15, 0, r1, r0, c5, 0\n\t"
- :
- : "r" (PAGE_OFFSET), "r" (PAGE_OFFSET + 128)
- : "r0", "r1", "r2");
-
- unregister_undef_hook(&blockops_hook);
-
- for (i = 0; i < ARRAY_SIZE(func); i++, err_pos <<= 1)
- printk("%30s: %ssupported\n", func[i], err & err_pos ? "not " : "");
-
- if ((err & 8) == 0) {
- printk(" --> Using %s block cache invalidate\n",
- cache_type & (1 << 24) ? "harvard" : "unified");
- if (cache_type & (1 << 24))
- cpu_cache.dma_inv_range = blk_dma_inv_range_harvard;
- else
- cpu_cache.dma_inv_range = blk_dma_inv_range_unified;
- }
- if ((err & 4) == 0) {
- printk(" --> Using block cache clean\n");
- cpu_cache.dma_clean_range = blk_dma_clean_range;
- }
- if ((err & 2) == 0) {
- printk(" --> Using block cache clean+invalidate\n");
- cpu_cache.dma_flush_range = blk_dma_flush_range;
- cpu_cache.flush_kern_dcache_page = blk_flush_kern_dcache_page;
- }
-
- return 0;
-}
-
-__initcall(blockops_check);
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index c168f322ef8..8b276ee38ac 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -420,7 +420,8 @@ static void __init bootmem_init(struct meminfo *mi)
* Set up device the mappings. Since we clear out the page tables for all
* mappings above VMALLOC_END, we will remove any debug device mappings.
* This means you have to be careful how you debug this function, or any
- * called function. (Do it by code inspection!)
+ * called function. This means you can't use any function or debugging
+ * method which may touch any device, otherwise the kernel _will_ crash.
*/
static void __init devicemaps_init(struct machine_desc *mdesc)
{
@@ -428,6 +429,12 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
unsigned long addr;
void *vectors;
+ /*
+ * Allocate the vector page early.
+ */
+ vectors = alloc_bootmem_low_pages(PAGE_SIZE);
+ BUG_ON(!vectors);
+
for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
pmd_clear(pmd_off_k(addr));
@@ -461,12 +468,6 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
create_mapping(&map);
#endif
- flush_cache_all();
- local_flush_tlb_all();
-
- vectors = alloc_bootmem_low_pages(PAGE_SIZE);
- BUG_ON(!vectors);
-
/*
* Create a mapping for the machine vectors at the high-vectors
* location (0xffff0000). If we aren't using high-vectors, also
@@ -491,12 +492,13 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
mdesc->map_io();
/*
- * Finally flush the tlb again - this ensures that we're in a
- * consistent state wrt the writebuffer if the writebuffer needs
- * draining. After this point, we can start to touch devices
- * again.
+ * Finally flush the caches and tlb to ensure that we're in a
+ * consistent state wrt the writebuffer. This also ensures that
+ * any write-allocated cache lines in the vector page are written
+ * back. After this point, we can start to touch devices again.
*/
local_flush_tlb_all();
+ flush_cache_all();
}
/*
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 0f128c28fee..10901398e4a 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -130,8 +130,7 @@ remap_area_pages(unsigned long start, unsigned long phys_addr,
* mapping. See include/asm-arm/proc-armv/pgtable.h for more information.
*/
void __iomem *
-__ioremap(unsigned long phys_addr, size_t size, unsigned long flags,
- unsigned long align)
+__ioremap(unsigned long phys_addr, size_t size, unsigned long flags)
{
void * addr;
struct vm_struct * area;
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index f36677241ec..76b1135d401 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -248,9 +248,7 @@ acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end)
acpi_table_print_madt_entry(header);
- /* no utility in registering a disabled processor */
- if (processor->flags.enabled == 0)
- return 0;
+ /* Register even disabled CPUs for cpu hotplug */
x86_acpiid_to_apicid[processor->acpi_id] = processor->id;
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 8f767d9aa45..1ca5269b1e8 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -220,8 +220,9 @@ static void __devinit MP_processor_info (struct mpc_config_processor *m)
num_processors++;
if ((num_processors > 8) &&
- APIC_XAPIC(ver) &&
- (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL))
+ ((APIC_XAPIC(ver) &&
+ (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)) ||
+ (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)))
def_to_bigsmp = 1;
else
def_to_bigsmp = 0;
diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c
index d71f4de44f7..dd73c0cb754 100644
--- a/arch/ia64/sn/kernel/bte.c
+++ b/arch/ia64/sn/kernel/bte.c
@@ -137,6 +137,7 @@ retry_bteop:
bte = bte_if_on_node(nasid_to_try[nasid_index],bte_if_index);
if (bte == NULL) {
+ nasid_index++;
continue;
}
diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c
index 49b530c39a4..5d54f5f4e92 100644
--- a/arch/ia64/sn/kernel/sn2/sn2_smp.c
+++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c
@@ -492,6 +492,9 @@ static struct proc_dir_entry *proc_sn2_ptc;
static int __init sn2_ptc_init(void)
{
+ if (!ia64_platform_is("sn2"))
+ return -ENOSYS;
+
if (!(proc_sn2_ptc = create_proc_entry(PTC_BASENAME, 0444, NULL))) {
printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME);
return -EINVAL;
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
index 6c6fbca3229..19b54fbcd7e 100644
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
@@ -743,13 +743,14 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, u64 arg)
if ((r = sn_hwperf_enum_objects(&nobj, &objs)) == 0) {
memset(p, 0, a.sz);
for (i = 0; i < nobj; i++) {
+ int cpuobj_index = 0;
if (!SN_HWPERF_IS_NODE(objs + i))
continue;
node = sn_hwperf_obj_to_cnode(objs + i);
for_each_online_cpu(j) {
if (node != cpu_to_node(j))
continue;
- cpuobj = (struct sn_hwperf_object_info *) p + j;
+ cpuobj = (struct sn_hwperf_object_info *) p + cpuobj_index++;
slice = 'a' + cpuid_to_slice(j);
cdata = cpu_data(j);
cpuobj->id = j;
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index 988844a169e..d016d672ec2 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -499,8 +499,12 @@ alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path)
dev = create_parisc_device(mod_path);
if (dev->id.hw_type != HPHW_FAULTY) {
- printk("Two devices have hardware path %s. Please file a bug with HP.\n"
- "In the meantime, you could try rearranging your cards.\n", parisc_pathname(dev));
+ printk(KERN_ERR "Two devices have hardware path [%s]. "
+ "IODC data for second device: "
+ "%02x%02x%02x%02x%02x%02x\n"
+ "Rearranging GSC cards sometimes helps\n",
+ parisc_pathname(dev), iodc_data[0], iodc_data[1],
+ iodc_data[3], iodc_data[4], iodc_data[5], iodc_data[6]);
return NULL;
}
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index c7e66ee5b08..9af4b22a6d7 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -1846,6 +1846,7 @@ sys_clone_wrapper:
ldo -16(%r30),%r29 /* Reference param save area */
#endif
+ /* WARNING - Clobbers r19 and r21, userspace must save these! */
STREG %r2,PT_GR19(%r1) /* save for child */
STREG %r30,PT_GR21(%r1)
BL sys_clone,%r2
diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c
index 1a1c6642273..8f563871e83 100644
--- a/arch/parisc/kernel/inventory.c
+++ b/arch/parisc/kernel/inventory.c
@@ -188,7 +188,7 @@ pat_query_module(ulong pcell_loc, ulong mod_index)
temp = pa_pdc_cell.cba;
dev = alloc_pa_dev(PAT_GET_CBA(temp), &pa_pdc_cell.mod_path);
if (!dev) {
- return PDC_NE_MOD;
+ return PDC_OK;
}
/* alloc_pa_dev sets dev->hpa */
diff --git a/arch/parisc/kernel/ioctl32.c b/arch/parisc/kernel/ioctl32.c
index 0a331104ad5..4eada1bb27f 100644
--- a/arch/parisc/kernel/ioctl32.c
+++ b/arch/parisc/kernel/ioctl32.c
@@ -19,536 +19,6 @@
#define CODE
#include "compat_ioctl.c"
-/* Use this to get at 32-bit user passed pointers.
- See sys_sparc32.c for description about these. */
-#define A(__x) ((unsigned long)(__x))
-/* The same for use with copy_from_user() and copy_to_user(). */
-#define B(__x) ((void *)(unsigned long)(__x))
-
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-/* This really belongs in include/linux/drm.h -DaveM */
-#include "../../../drivers/char/drm/drm.h"
-
-typedef struct drm32_version {
- int version_major; /* Major version */
- int version_minor; /* Minor version */
- int version_patchlevel;/* Patch level */
- int name_len; /* Length of name buffer */
- u32 name; /* Name of driver */
- int date_len; /* Length of date buffer */
- u32 date; /* User-space buffer to hold date */
- int desc_len; /* Length of desc buffer */
- u32 desc; /* User-space buffer to hold desc */
-} drm32_version_t;
-#define DRM32_IOCTL_VERSION DRM_IOWR(0x00, drm32_version_t)
-
-static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_version_t *uversion = (drm32_version_t *)arg;
- char *name_ptr, *date_ptr, *desc_ptr;
- u32 tmp1, tmp2, tmp3;
- drm_version_t kversion;
- mm_segment_t old_fs;
- int ret;
-
- memset(&kversion, 0, sizeof(kversion));
- if (get_user(kversion.name_len, &uversion->name_len) ||
- get_user(kversion.date_len, &uversion->date_len) ||
- get_user(kversion.desc_len, &uversion->desc_len) ||
- get_user(tmp1, &uversion->name) ||
- get_user(tmp2, &uversion->date) ||
- get_user(tmp3, &uversion->desc))
- return -EFAULT;
-
- name_ptr = (char *) A(tmp1);
- date_ptr = (char *) A(tmp2);
- desc_ptr = (char *) A(tmp3);
-
- ret = -ENOMEM;
- if (kversion.name_len && name_ptr) {
- kversion.name = kmalloc(kversion.name_len, GFP_KERNEL);
- if (!kversion.name)
- goto out;
- }
- if (kversion.date_len && date_ptr) {
- kversion.date = kmalloc(kversion.date_len, GFP_KERNEL);
- if (!kversion.date)
- goto out;
- }
- if (kversion.desc_len && desc_ptr) {
- kversion.desc = kmalloc(kversion.desc_len, GFP_KERNEL);
- if (!kversion.desc)
- goto out;
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl (fd, DRM_IOCTL_VERSION, (unsigned long)&kversion);
- set_fs(old_fs);
-
- if (!ret) {
- if ((kversion.name &&
- copy_to_user(name_ptr, kversion.name, kversion.name_len)) ||
- (kversion.date &&
- copy_to_user(date_ptr, kversion.date, kversion.date_len)) ||
- (kversion.desc &&
- copy_to_user(desc_ptr, kversion.desc, kversion.desc_len)))
- ret = -EFAULT;
- if (put_user(kversion.version_major, &uversion->version_major) ||
- put_user(kversion.version_minor, &uversion->version_minor) ||
- put_user(kversion.version_patchlevel, &uversion->version_patchlevel) ||
- put_user(kversion.name_len, &uversion->name_len) ||
- put_user(kversion.date_len, &uversion->date_len) ||
- put_user(kversion.desc_len, &uversion->desc_len))
- ret = -EFAULT;
- }
-
-out:
- kfree(kversion.name);
- kfree(kversion.date);
- kfree(kversion.desc);
- return ret;
-}
-
-typedef struct drm32_unique {
- int unique_len; /* Length of unique */
- u32 unique; /* Unique name for driver instantiation */
-} drm32_unique_t;
-#define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
-#define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
-
-static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_unique_t *uarg = (drm32_unique_t *)arg;
- drm_unique_t karg;
- mm_segment_t old_fs;
- char *uptr;
- u32 tmp;
- int ret;
-
- if (get_user(karg.unique_len, &uarg->unique_len))
- return -EFAULT;
- karg.unique = NULL;
-
- if (get_user(tmp, &uarg->unique))
- return -EFAULT;
-
- uptr = (char *) A(tmp);
-
- if (uptr) {
- karg.unique = kmalloc(karg.unique_len, GFP_KERNEL);
- if (!karg.unique)
- return -ENOMEM;
- if (cmd == DRM32_IOCTL_SET_UNIQUE &&
- copy_from_user(karg.unique, uptr, karg.unique_len)) {
- kfree(karg.unique);
- return -EFAULT;
- }
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- if (cmd == DRM32_IOCTL_GET_UNIQUE)
- ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)&karg);
- else
- ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)&karg);
- set_fs(old_fs);
-
- if (!ret) {
- if (cmd == DRM32_IOCTL_GET_UNIQUE &&
- uptr != NULL &&
- copy_to_user(uptr, karg.unique, karg.unique_len))
- ret = -EFAULT;
- if (put_user(karg.unique_len, &uarg->unique_len))
- ret = -EFAULT;
- }
-
- kfree(karg.unique);
- return ret;
-}
-
-typedef struct drm32_map {
- u32 offset; /* Requested physical address (0 for SAREA)*/
- u32 size; /* Requested physical size (bytes) */
- drm_map_type_t type; /* Type of memory to map */
- drm_map_flags_t flags; /* Flags */
- u32 handle; /* User-space: "Handle" to pass to mmap */
- /* Kernel-space: kernel-virtual address */
- int mtrr; /* MTRR slot used */
- /* Private data */
-} drm32_map_t;
-#define DRM32_IOCTL_ADD_MAP DRM_IOWR(0x15, drm32_map_t)
-
-static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_map_t *uarg = (drm32_map_t *) arg;
- drm_map_t karg;
- mm_segment_t old_fs;
- u32 tmp;
- int ret;
-
- ret = get_user(karg.offset, &uarg->offset);
- ret |= get_user(karg.size, &uarg->size);
- ret |= get_user(karg.type, &uarg->type);
- ret |= get_user(karg.flags, &uarg->flags);
- ret |= get_user(tmp, &uarg->handle);
- ret |= get_user(karg.mtrr, &uarg->mtrr);
- if (ret)
- return -EFAULT;
-
- karg.handle = (void *) A(tmp);
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- ret = put_user(karg.offset, &uarg->offset);
- ret |= put_user(karg.size, &uarg->size);
- ret |= put_user(karg.type, &uarg->type);
- ret |= put_user(karg.flags, &uarg->flags);
- tmp = (u32) (long)karg.handle;
- ret |= put_user(tmp, &uarg->handle);
- ret |= put_user(karg.mtrr, &uarg->mtrr);
- if (ret)
- ret = -EFAULT;
- }
-
- return ret;
-}
-
-typedef struct drm32_buf_info {
- int count; /* Entries in list */
- u32 list; /* (drm_buf_desc_t *) */
-} drm32_buf_info_t;
-#define DRM32_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm32_buf_info_t)
-
-static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_buf_info_t *uarg = (drm32_buf_info_t *)arg;
- drm_buf_desc_t *ulist;
- drm_buf_info_t karg;
- mm_segment_t old_fs;
- int orig_count, ret;
- u32 tmp;
-
- if (get_user(karg.count, &uarg->count) ||
- get_user(tmp, &uarg->list))
- return -EFAULT;
-
- ulist = (drm_buf_desc_t *) A(tmp);
-
- orig_count = karg.count;
-
- karg.list = kmalloc(karg.count * sizeof(drm_buf_desc_t), GFP_KERNEL);
- if (!karg.list)
- return -EFAULT;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- if (karg.count <= orig_count &&
- (copy_to_user(ulist, karg.list,
- karg.count * sizeof(drm_buf_desc_t))))
- ret = -EFAULT;
- if (put_user(karg.count, &uarg->count))
- ret = -EFAULT;
- }
-
- kfree(karg.list);
- return ret;
-}
-
-typedef struct drm32_buf_free {
- int count;
- u32 list; /* (int *) */
-} drm32_buf_free_t;
-#define DRM32_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm32_buf_free_t)
-
-static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_buf_free_t *uarg = (drm32_buf_free_t *)arg;
- drm_buf_free_t karg;
- mm_segment_t old_fs;
- int *ulist;
- int ret;
- u32 tmp;
-
- if (get_user(karg.count, &uarg->count) ||
- get_user(tmp, &uarg->list))
- return -EFAULT;
-
- ulist = (int *) A(tmp);
-
- karg.list = kmalloc(karg.count * sizeof(int), GFP_KERNEL);
- if (!karg.list)
- return -ENOMEM;
-
- ret = -EFAULT;
- if (copy_from_user(karg.list, ulist, (karg.count * sizeof(int))))
- goto out;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long) &karg);
- set_fs(old_fs);
-
-out:
- kfree(karg.list);
- return ret;
-}
-
-typedef struct drm32_buf_pub {
- int idx; /* Index into master buflist */
- int total; /* Buffer size */
- int used; /* Amount of buffer in use (for DMA) */
- u32 address; /* Address of buffer (void *) */
-} drm32_buf_pub_t;
-
-typedef struct drm32_buf_map {
- int count; /* Length of buflist */
- u32 virtual; /* Mmaped area in user-virtual (void *) */
- u32 list; /* Buffer information (drm_buf_pub_t *) */
-} drm32_buf_map_t;
-#define DRM32_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm32_buf_map_t)
-
-static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_buf_map_t *uarg = (drm32_buf_map_t *)arg;
- drm32_buf_pub_t *ulist;
- drm_buf_map_t karg;
- mm_segment_t old_fs;
- int orig_count, ret, i;
- u32 tmp1, tmp2;
-
- if (get_user(karg.count, &uarg->count) ||
- get_user(tmp1, &uarg->virtual) ||
- get_user(tmp2, &uarg->list))
- return -EFAULT;
-
- karg.virtual = (void *) A(tmp1);
- ulist = (drm32_buf_pub_t *) A(tmp2);
-
- orig_count = karg.count;
-
- karg.list = kmalloc(karg.count * sizeof(drm_buf_pub_t), GFP_KERNEL);
- if (!karg.list)
- return -ENOMEM;
-
- ret = -EFAULT;
- for (i = 0; i < karg.count; i++) {
- if (get_user(karg.list[i].idx, &ulist[i].idx) ||
- get_user(karg.list[i].total, &ulist[i].total) ||
- get_user(karg.list[i].used, &ulist[i].used) ||
- get_user(tmp1, &ulist[i].address))
- goto out;
-
- karg.list[i].address = (void *) A(tmp1);
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- for (i = 0; i < orig_count; i++) {
- tmp1 = (u32) (long) karg.list[i].address;
- if (put_user(karg.list[i].idx, &ulist[i].idx) ||
- put_user(karg.list[i].total, &ulist[i].total) ||
- put_user(karg.list[i].used, &ulist[i].used) ||
- put_user(tmp1, &ulist[i].address)) {
- ret = -EFAULT;
- goto out;
- }
- }
- if (put_user(karg.count, &uarg->count))
- ret = -EFAULT;
- }
-
-out:
- kfree(karg.list);
- return ret;
-}
-
-typedef struct drm32_dma {
- /* Indices here refer to the offset into
- buflist in drm_buf_get_t. */
- int context; /* Context handle */
- int send_count; /* Number of buffers to send */
- u32 send_indices; /* List of handles to buffers (int *) */
- u32 send_sizes; /* Lengths of data to send (int *) */
- drm_dma_flags_t flags; /* Flags */
- int request_count; /* Number of buffers requested */
- int request_size; /* Desired size for buffers */
- u32 request_indices; /* Buffer information (int *) */
- u32 request_sizes; /* (int *) */
- int granted_count; /* Number of buffers granted */
-} drm32_dma_t;
-#define DRM32_IOCTL_DMA DRM_IOWR(0x29, drm32_dma_t)
-
-/* RED PEN The DRM layer blindly dereferences the send/request
- * indice/size arrays even though they are userland
- * pointers. -DaveM
- */
-static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_dma_t *uarg = (drm32_dma_t *) arg;
- int *u_si, *u_ss, *u_ri, *u_rs;
- drm_dma_t karg;
- mm_segment_t old_fs;
- int ret;
- u32 tmp1, tmp2, tmp3, tmp4;
-
- karg.send_indices = karg.send_sizes = NULL;
- karg.request_indices = karg.request_sizes = NULL;
-
- if (get_user(karg.context, &uarg->context) ||
- get_user(karg.send_count, &uarg->send_count) ||
- get_user(tmp1, &uarg->send_indices) ||
- get_user(tmp2, &uarg->send_sizes) ||
- get_user(karg.flags, &uarg->flags) ||
- get_user(karg.request_count, &uarg->request_count) ||
- get_user(karg.request_size, &uarg->request_size) ||
- get_user(tmp3, &uarg->request_indices) ||
- get_user(tmp4, &uarg->request_sizes) ||
- get_user(karg.granted_count, &uarg->granted_count))
- return -EFAULT;
-
- u_si = (int *) A(tmp1);
- u_ss = (int *) A(tmp2);
- u_ri = (int *) A(tmp3);
- u_rs = (int *) A(tmp4);
-
- if (karg.send_count) {
- karg.send_indices = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
- karg.send_sizes = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
-
- ret = -ENOMEM;
- if (!karg.send_indices || !karg.send_sizes)
- goto out;
-
- ret = -EFAULT;
- if (copy_from_user(karg.send_indices, u_si,
- (karg.send_count * sizeof(int))) ||
- copy_from_user(karg.send_sizes, u_ss,
- (karg.send_count * sizeof(int))))
- goto out;
- }
-
- if (karg.request_count) {
- karg.request_indices = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
- karg.request_sizes = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
-
- ret = -ENOMEM;
- if (!karg.request_indices || !karg.request_sizes)
- goto out;
-
- ret = -EFAULT;
- if (copy_from_user(karg.request_indices, u_ri,
- (karg.request_count * sizeof(int))) ||
- copy_from_user(karg.request_sizes, u_rs,
- (karg.request_count * sizeof(int))))
- goto out;
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- if (put_user(karg.context, &uarg->context) ||
- put_user(karg.send_count, &uarg->send_count) ||
- put_user(karg.flags, &uarg->flags) ||
- put_user(karg.request_count, &uarg->request_count) ||
- put_user(karg.request_size, &uarg->request_size) ||
- put_user(karg.granted_count, &uarg->granted_count))
- ret = -EFAULT;
-
- if (karg.send_count) {
- if (copy_to_user(u_si, karg.send_indices,
- (karg.send_count * sizeof(int))) ||
- copy_to_user(u_ss, karg.send_sizes,
- (karg.send_count * sizeof(int))))
- ret = -EFAULT;
- }
- if (karg.request_count) {
- if (copy_to_user(u_ri, karg.request_indices,
- (karg.request_count * sizeof(int))) ||
- copy_to_user(u_rs, karg.request_sizes,
- (karg.request_count * sizeof(int))))
- ret = -EFAULT;
- }
- }
-
-out:
- kfree(karg.send_indices);
- kfree(karg.send_sizes);
- kfree(karg.request_indices);
- kfree(karg.request_sizes);
- return ret;
-}
-
-typedef struct drm32_ctx_res {
- int count;
- u32 contexts; /* (drm_ctx_t *) */
-} drm32_ctx_res_t;
-#define DRM32_IOCTL_RES_CTX DRM_IOWR(0x26, drm32_ctx_res_t)
-
-static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- drm32_ctx_res_t *uarg = (drm32_ctx_res_t *) arg;
- drm_ctx_t *ulist;
- drm_ctx_res_t karg;
- mm_segment_t old_fs;
- int orig_count, ret;
- u32 tmp;
-
- karg.contexts = NULL;
- if (get_user(karg.count, &uarg->count) ||
- get_user(tmp, &uarg->contexts))
- return -EFAULT;
-
- ulist = (drm_ctx_t *) A(tmp);
-
- orig_count = karg.count;
- if (karg.count && ulist) {
- karg.contexts = kmalloc((karg.count * sizeof(drm_ctx_t)), GFP_KERNEL);
- if (!karg.contexts)
- return -ENOMEM;
- if (copy_from_user(karg.contexts, ulist,
- (karg.count * sizeof(drm_ctx_t)))) {
- kfree(karg.contexts);
- return -EFAULT;
- }
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long) &karg);
- set_fs(old_fs);
-
- if (!ret) {
- if (orig_count) {
- if (copy_to_user(ulist, karg.contexts,
- (orig_count * sizeof(drm_ctx_t))))
- ret = -EFAULT;
- }
- if (put_user(karg.count, &uarg->count))
- ret = -EFAULT;
- }
-
- kfree(karg.contexts);
- return ret;
-}
-
-#endif
-
#define HANDLE_IOCTL(cmd, handler) { cmd, (ioctl_trans_handler_t)handler, NULL },
#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd, sys_ioctl)
@@ -561,11 +31,6 @@ IOCTL_TABLE_START
#define DECLARES
#include "compat_ioctl.c"
-/* PA-specific ioctls */
-COMPATIBLE_IOCTL(PA_PERF_ON)
-COMPATIBLE_IOCTL(PA_PERF_OFF)
-COMPATIBLE_IOCTL(PA_PERF_VERSION)
-
/* And these ioctls need translation */
HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc)
HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc)
@@ -590,17 +55,6 @@ HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
COMPATIBLE_IOCTL(RTC_EPOCH_SET)
#endif
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version);
-HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique);
-HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique);
-HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap);
-HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma);
-HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx);
-#endif /* DRM */
IOCTL_TABLE_END
int ioctl_table_size = ARRAY_SIZE(ioctl_start);
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index 006385dbee6..197936d9359 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -30,6 +30,9 @@
#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <linux/types.h>
+#include <asm/io.h>
+
+#include <asm/smp.h>
#undef PARISC_IRQ_CR16_COUNTS
@@ -43,26 +46,34 @@ extern irqreturn_t ipi_interrupt(int, void *, struct pt_regs *);
*/
static volatile unsigned long cpu_eiem = 0;
-static void cpu_set_eiem(void *info)
-{
- set_eiem((unsigned long) info);
-}
-
-static inline void cpu_disable_irq(unsigned int irq)
+static void cpu_disable_irq(unsigned int irq)
{
unsigned long eirr_bit = EIEM_MASK(irq);
cpu_eiem &= ~eirr_bit;
- on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
+ /* Do nothing on the other CPUs. If they get this interrupt,
+ * The & cpu_eiem in the do_cpu_irq_mask() ensures they won't
+ * handle it, and the set_eiem() at the bottom will ensure it
+ * then gets disabled */
}
static void cpu_enable_irq(unsigned int irq)
{
unsigned long eirr_bit = EIEM_MASK(irq);
- mtctl(eirr_bit, 23); /* clear EIRR bit before unmasking */
cpu_eiem |= eirr_bit;
- on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
+
+ /* FIXME: while our interrupts aren't nested, we cannot reset
+ * the eiem mask if we're already in an interrupt. Once we
+ * implement nested interrupts, this can go away
+ */
+ if (!in_interrupt())
+ set_eiem(cpu_eiem);
+
+ /* This is just a simple NOP IPI. But what it does is cause
+ * all the other CPUs to do a set_eiem(cpu_eiem) at the end
+ * of the interrupt handler */
+ smp_send_all_nop();
}
static unsigned int cpu_startup_irq(unsigned int irq)
@@ -74,6 +85,35 @@ static unsigned int cpu_startup_irq(unsigned int irq)
void no_ack_irq(unsigned int irq) { }
void no_end_irq(unsigned int irq) { }
+#ifdef CONFIG_SMP
+int cpu_check_affinity(unsigned int irq, cpumask_t *dest)
+{
+ int cpu_dest;
+
+ /* timer and ipi have to always be received on all CPUs */
+ if (irq == TIMER_IRQ || irq == IPI_IRQ) {
+ /* Bad linux design decision. The mask has already
+ * been set; we must reset it */
+ irq_affinity[irq] = CPU_MASK_ALL;
+ return -EINVAL;
+ }
+
+ /* whatever mask they set, we just allow one CPU */
+ cpu_dest = first_cpu(*dest);
+ *dest = cpumask_of_cpu(cpu_dest);
+
+ return 0;
+}
+
+static void cpu_set_affinity_irq(unsigned int irq, cpumask_t dest)
+{
+ if (cpu_check_affinity(irq, &dest))
+ return;
+
+ irq_affinity[irq] = dest;
+}
+#endif
+
static struct hw_interrupt_type cpu_interrupt_type = {
.typename = "CPU",
.startup = cpu_startup_irq,
@@ -82,7 +122,9 @@ static struct hw_interrupt_type cpu_interrupt_type = {
.disable = cpu_disable_irq,
.ack = no_ack_irq,
.end = no_end_irq,
-// .set_affinity = cpu_set_affinity_irq,
+#ifdef CONFIG_SMP
+ .set_affinity = cpu_set_affinity_irq,
+#endif
};
int show_interrupts(struct seq_file *p, void *v)
@@ -219,6 +261,17 @@ int txn_alloc_irq(unsigned int bits_wide)
return -1;
}
+
+unsigned long txn_affinity_addr(unsigned int irq, int cpu)
+{
+#ifdef CONFIG_SMP
+ irq_affinity[irq] = cpumask_of_cpu(cpu);
+#endif
+
+ return cpu_data[cpu].txn_addr;
+}
+
+
unsigned long txn_alloc_addr(unsigned int virt_irq)
{
static int next_cpu = -1;
@@ -233,7 +286,7 @@ unsigned long txn_alloc_addr(unsigned int virt_irq)
if (next_cpu >= NR_CPUS)
next_cpu = 0; /* nothing else, assign monarch */
- return cpu_data[next_cpu].txn_addr;
+ return txn_affinity_addr(virt_irq, next_cpu);
}
@@ -250,10 +303,11 @@ void do_cpu_irq_mask(struct pt_regs *regs)
irq_enter();
/*
- * Only allow interrupt processing to be interrupted by the
- * timer tick
+ * Don't allow TIMER or IPI nested interrupts.
+ * Allowing any single interrupt to nest can lead to that CPU
+ * handling interrupts with all enabled interrupts unmasked.
*/
- set_eiem(EIEM_MASK(TIMER_IRQ));
+ set_eiem(0UL);
/* 1) only process IRQs that are enabled/unmasked (cpu_eiem)
* 2) We loop here on EIRR contents in order to avoid
@@ -267,23 +321,41 @@ void do_cpu_irq_mask(struct pt_regs *regs)
if (!eirr_val)
break;
- if (eirr_val & EIEM_MASK(TIMER_IRQ))
- set_eiem(0);
-
mtctl(eirr_val, 23); /* reset bits we are going to process */
/* Work our way from MSb to LSb...same order we alloc EIRs */
for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) {
+#ifdef CONFIG_SMP
+ cpumask_t dest = irq_affinity[irq];
+#endif
if (!(bit & eirr_val))
continue;
/* clear bit in mask - can exit loop sooner */
eirr_val &= ~bit;
+#ifdef CONFIG_SMP
+ /* FIXME: because generic set affinity mucks
+ * with the affinity before sending it to us
+ * we can get the situation where the affinity is
+ * wrong for our CPU type interrupts */
+ if (irq != TIMER_IRQ && irq != IPI_IRQ &&
+ !cpu_isset(smp_processor_id(), dest)) {
+ int cpu = first_cpu(dest);
+
+ printk(KERN_DEBUG "redirecting irq %d from CPU %d to %d\n",
+ irq, smp_processor_id(), cpu);
+ gsc_writel(irq + CPU_IRQ_BASE,
+ cpu_data[cpu].hpa);
+ continue;
+ }
+#endif
+
__do_IRQ(irq, regs);
}
}
- set_eiem(cpu_eiem);
+
+ set_eiem(cpu_eiem); /* restore original mask */
irq_exit();
}
@@ -291,12 +363,14 @@ void do_cpu_irq_mask(struct pt_regs *regs)
static struct irqaction timer_action = {
.handler = timer_interrupt,
.name = "timer",
+ .flags = SA_INTERRUPT,
};
#ifdef CONFIG_SMP
static struct irqaction ipi_action = {
.handler = ipi_interrupt,
.name = "IPI",
+ .flags = SA_INTERRUPT,
};
#endif
diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c
index 44670d6e06f..f6fec62b6a2 100644
--- a/arch/parisc/kernel/perf.c
+++ b/arch/parisc/kernel/perf.c
@@ -196,8 +196,7 @@ static int perf_open(struct inode *inode, struct file *file);
static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos);
static ssize_t perf_write(struct file *file, const char __user *buf, size_t count,
loff_t *ppos);
-static int perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg);
+static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
static void perf_start_counters(void);
static int perf_stop_counters(uint32_t *raddr);
static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num);
@@ -438,48 +437,56 @@ static void perf_patch_images(void)
* must be running on the processor that you wish to change.
*/
-static int perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg)
+static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
long error_start;
- uint32_t raddr[4];
+ uint32_t raddr[4];
+ int error = 0;
+ lock_kernel();
switch (cmd) {
case PA_PERF_ON:
/* Start the counters */
perf_start_counters();
- return 0;
+ break;
case PA_PERF_OFF:
error_start = perf_stop_counters(raddr);
if (error_start != 0) {
printk(KERN_ERR "perf_off: perf_stop_counters = %ld\n", error_start);
- return -EFAULT;
+ error = -EFAULT;
+ break;
}
/* copy out the Counters */
if (copy_to_user((void __user *)arg, raddr,
sizeof (raddr)) != 0) {
- return -EFAULT;
+ error = -EFAULT;
+ break;
}
- return 0;
+ break;
case PA_PERF_VERSION:
/* Return the version # */
- return put_user(PERF_VERSION, (int *)arg);
+ error = put_user(PERF_VERSION, (int *)arg);
+ break;
default:
- break;
+ error = -ENOTTY;
}
- return -ENOTTY;
+
+ unlock_kernel();
+
+ return error;
}
static struct file_operations perf_fops = {
.llseek = no_llseek,
.read = perf_read,
.write = perf_write,
- .ioctl = perf_ioctl,
+ .unlocked_ioctl = perf_ioctl,
+ .compat_ioctl = perf_ioctl,
.open = perf_open,
.release = perf_release
};
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index b6fe202a620..27160e8bf15 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -264,6 +264,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
* sigkill. perhaps it should be put in the status
* that it wants to exit.
*/
+ ret = 0;
DBG("sys_ptrace(KILL)\n");
if (child->exit_state == EXIT_ZOMBIE) /* already dead */
goto out_tsk;
@@ -344,11 +345,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case PTRACE_GETEVENTMSG:
ret = put_user(child->ptrace_message, (unsigned int __user *) data);
- goto out;
+ goto out_tsk;
default:
ret = ptrace_request(child, request, addr, data);
- goto out;
+ goto out_tsk;
}
out_wake_notrap:
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 82c24e62ab6..3a25a7bd673 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -296,7 +296,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
struct rt_sigframe __user *frame;
unsigned long rp, usp;
unsigned long haddr, sigframe_size;
- struct siginfo si;
int err = 0;
#ifdef __LP64__
compat_int_t compat_val;
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index a9ecf646578..ce89da0f654 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -181,12 +181,19 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
while (ops) {
unsigned long which = ffz(~ops);
+ ops &= ~(1 << which);
+
switch (which) {
+ case IPI_NOP:
+#if (kDEBUG>=100)
+ printk(KERN_DEBUG "CPU%d IPI_NOP\n",this_cpu);
+#endif /* kDEBUG */
+ break;
+
case IPI_RESCHEDULE:
#if (kDEBUG>=100)
printk(KERN_DEBUG "CPU%d IPI_RESCHEDULE\n",this_cpu);
#endif /* kDEBUG */
- ops &= ~(1 << IPI_RESCHEDULE);
/*
* Reschedule callback. Everything to be
* done is done by the interrupt return path.
@@ -197,7 +204,6 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#if (kDEBUG>=100)
printk(KERN_DEBUG "CPU%d IPI_CALL_FUNC\n",this_cpu);
#endif /* kDEBUG */
- ops &= ~(1 << IPI_CALL_FUNC);
{
volatile struct smp_call_struct *data;
void (*func)(void *info);
@@ -231,7 +237,6 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#if (kDEBUG>=100)
printk(KERN_DEBUG "CPU%d IPI_CPU_START\n",this_cpu);
#endif /* kDEBUG */
- ops &= ~(1 << IPI_CPU_START);
#ifdef ENTRY_SYS_CPUS
p->state = STATE_RUNNING;
#endif
@@ -241,7 +246,6 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#if (kDEBUG>=100)
printk(KERN_DEBUG "CPU%d IPI_CPU_STOP\n",this_cpu);
#endif /* kDEBUG */
- ops &= ~(1 << IPI_CPU_STOP);
#ifdef ENTRY_SYS_CPUS
#else
halt_processor();
@@ -252,13 +256,11 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#if (kDEBUG>=100)
printk(KERN_DEBUG "CPU%d is alive!\n",this_cpu);
#endif /* kDEBUG */
- ops &= ~(1 << IPI_CPU_TEST);
break;
default:
printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n",
this_cpu, which);
- ops &= ~(1 << which);
return IRQ_NONE;
} /* Switch */
} /* while (ops) */
@@ -312,6 +314,12 @@ smp_send_start(void) { send_IPI_allbutself(IPI_CPU_START); }
void
smp_send_reschedule(int cpu) { send_IPI_single(cpu, IPI_RESCHEDULE); }
+void
+smp_send_all_nop(void)
+{
+ send_IPI_allbutself(IPI_NOP);
+}
+
/**
* Run a function on all other CPUs.
@@ -338,6 +346,10 @@ smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
/* Can deadlock when called with interrupts disabled */
WARN_ON(irqs_disabled());
+
+ /* can also deadlock if IPIs are disabled */
+ WARN_ON((get_eiem() & (1UL<<(CPU_IRQ_MAX - IPI_IRQ))) == 0);
+
data.func = func;
data.info = info;
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index b29b76b42bb..d6616349289 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -164,7 +164,7 @@ linux_gateway_entry:
#endif
STREG %r2, TASK_PT_GR30(%r1) /* ... and save it */
- STREG %r20, TASK_PT_GR20(%r1)
+ STREG %r20, TASK_PT_GR20(%r1) /* Syscall number */
STREG %r21, TASK_PT_GR21(%r1)
STREG %r22, TASK_PT_GR22(%r1)
STREG %r23, TASK_PT_GR23(%r1) /* 4th argument */
@@ -527,6 +527,7 @@ lws_compare_and_swap:
We *must* giveup this call and fail.
*/
ldw 4(%sr2,%r20), %r28 /* Load thread register */
+ /* WARNING: If cr27 cycles to the same value we have problems */
mfctl %cr27, %r21 /* Get current thread register */
cmpb,<>,n %r21, %r28, cas_lock /* Called recursive? */
b lws_exit /* Return error! */
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 5a5b2468508..8b6008ab217 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -40,7 +40,7 @@
#endif
unsigned long pci_probe_only = 1;
-unsigned long pci_assign_all_buses = 0;
+int pci_assign_all_buses = 0;
/*
* legal IO pages under MAX_ISA_PORT. This is to ensure we don't touch
@@ -55,11 +55,6 @@ static void fixup_resource(struct resource *res, struct pci_dev *dev);
static void do_bus_setup(struct pci_bus *bus);
#endif
-unsigned int pcibios_assign_all_busses(void)
-{
- return pci_assign_all_buses;
-}
-
/* pci_io_base -- the base address from which io bars are offsets.
* This is the lowest I/O base address (so bar values are always positive),
* and it *must* be the start of ISA space if an ISA bus exists because
@@ -1186,17 +1181,6 @@ void phbs_remap_io(void)
remap_bus_range(hose->bus);
}
-/*
- * ppc64 can have multifunction devices that do not respond to function 0.
- * In this case we must scan all functions.
- * XXX this can go now, we use the OF device tree in all the
- * cases that caused problems. -- paulus
- */
-int pcibios_scan_all_fns(struct pci_bus *bus, int devfn)
-{
- return 0;
-}
-
static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
{
struct pci_controller *hose = pci_bus_to_host(dev->bus);
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 59846b40d52..af4d1bc9a2e 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -146,9 +146,6 @@ EXPORT_SYMBOL(pci_bus_io_base);
EXPORT_SYMBOL(pci_bus_io_base_phys);
EXPORT_SYMBOL(pci_bus_mem_base_phys);
EXPORT_SYMBOL(pci_bus_to_hose);
-EXPORT_SYMBOL(pci_resource_to_bus);
-EXPORT_SYMBOL(pci_phys_to_bus);
-EXPORT_SYMBOL(pci_bus_to_phys);
#endif /* CONFIG_PCI */
#ifdef CONFIG_NOT_COHERENT_CACHE
diff --git a/arch/powerpc/kernel/ptrace-common.h b/arch/powerpc/kernel/ptrace-common.h
new file mode 100644
index 00000000000..b1babb72967
--- /dev/null
+++ b/arch/powerpc/kernel/ptrace-common.h
@@ -0,0 +1,164 @@
+/*
+ * linux/arch/ppc64/kernel/ptrace-common.h
+ *
+ * Copyright (c) 2002 Stephen Rothwell, IBM Coproration
+ * Extracted from ptrace.c and ptrace32.c
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file README.legal in the main directory of
+ * this archive for more details.
+ */
+
+#ifndef _PPC64_PTRACE_COMMON_H
+#define _PPC64_PTRACE_COMMON_H
+
+#include <linux/config.h>
+#include <asm/system.h>
+
+/*
+ * Set of msr bits that gdb can change on behalf of a process.
+ */
+#define MSR_DEBUGCHANGE (MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1)
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+static inline unsigned long get_reg(struct task_struct *task, int regno)
+{
+ unsigned long tmp = 0;
+
+ /*
+ * Put the correct FP bits in, they might be wrong as a result
+ * of our lazy FP restore.
+ */
+ if (regno == PT_MSR) {
+ tmp = ((unsigned long *)task->thread.regs)[PT_MSR];
+ tmp |= task->thread.fpexc_mode;
+ } else if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) {
+ tmp = ((unsigned long *)task->thread.regs)[regno];
+ }
+
+ return tmp;
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+static inline int put_reg(struct task_struct *task, int regno,
+ unsigned long data)
+{
+ if (regno < PT_SOFTE) {
+ if (regno == PT_MSR)
+ data = (data & MSR_DEBUGCHANGE)
+ | (task->thread.regs->msr & ~MSR_DEBUGCHANGE);
+ ((unsigned long *)task->thread.regs)[regno] = data;
+ return 0;
+ }
+ return -EIO;
+}
+
+static inline void set_single_step(struct task_struct *task)
+{
+ struct pt_regs *regs = task->thread.regs;
+ if (regs != NULL)
+ regs->msr |= MSR_SE;
+ set_ti_thread_flag(task->thread_info, TIF_SINGLESTEP);
+}
+
+static inline void clear_single_step(struct task_struct *task)
+{
+ struct pt_regs *regs = task->thread.regs;
+ if (regs != NULL)
+ regs->msr &= ~MSR_SE;
+ clear_ti_thread_flag(task->thread_info, TIF_SINGLESTEP);
+}
+
+#ifdef CONFIG_ALTIVEC
+/*
+ * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
+ * The transfer totals 34 quadword. Quadwords 0-31 contain the
+ * corresponding vector registers. Quadword 32 contains the vscr as the
+ * last word (offset 12) within that quadword. Quadword 33 contains the
+ * vrsave as the first word (offset 0) within the quadword.
+ *
+ * This definition of the VMX state is compatible with the current PPC32
+ * ptrace interface. This allows signal handling and ptrace to use the
+ * same structures. This also simplifies the implementation of a bi-arch
+ * (combined (32- and 64-bit) gdb.
+ */
+
+/*
+ * Get contents of AltiVec register state in task TASK
+ */
+static inline int get_vrregs(unsigned long __user *data,
+ struct task_struct *task)
+{
+ unsigned long regsize;
+
+ /* copy AltiVec registers VR[0] .. VR[31] */
+ regsize = 32 * sizeof(vector128);
+ if (copy_to_user(data, task->thread.vr, regsize))
+ return -EFAULT;
+ data += (regsize / sizeof(unsigned long));
+
+ /* copy VSCR */
+ regsize = 1 * sizeof(vector128);
+ if (copy_to_user(data, &task->thread.vscr, regsize))
+ return -EFAULT;
+ data += (regsize / sizeof(unsigned long));
+
+ /* copy VRSAVE */
+ if (put_user(task->thread.vrsave, (u32 __user *)data))
+ return -EFAULT;
+
+ return 0;
+}
+
+/*
+ * Write contents of AltiVec register state into task TASK.
+ */
+static inline int set_vrregs(struct task_struct *task,
+ unsigned long __user *data)
+{
+ unsigned long regsize;
+
+ /* copy AltiVec registers VR[0] .. VR[31] */
+ regsize = 32 * sizeof(vector128);
+ if (copy_from_user(task->thread.vr, data, regsize))
+ return -EFAULT;
+ data += (regsize / sizeof(unsigned long));
+
+ /* copy VSCR */
+ regsize = 1 * sizeof(vector128);
+ if (copy_from_user(&task->thread.vscr, data, regsize))
+ return -EFAULT;
+ data += (regsize / sizeof(unsigned long));
+
+ /* copy VRSAVE */
+ if (get_user(task->thread.vrsave, (u32 __user *)data))
+ return -EFAULT;
+
+ return 0;
+}
+#endif
+
+static inline int ptrace_set_debugreg(struct task_struct *task,
+ unsigned long addr, unsigned long data)
+{
+ /* We only support one DABR and no IABRS at the moment */
+ if (addr > 0)
+ return -EINVAL;
+
+ /* The bottom 3 bits are flags */
+ if ((data & ~0x7UL) >= TASK_SIZE)
+ return -EIO;
+
+ /* Ensure translation is on */
+ if (data && !(data & DABR_TRANSLATION))
+ return -EIO;
+
+ task->thread.dabr = data;
+ return 0;
+}
+
+#endif /* _PPC64_PTRACE_COMMON_H */
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 3d2abd95c7a..400793c7130 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -36,8 +36,9 @@
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/system.h>
+
#ifdef CONFIG_PPC64
-#include <asm/ptrace-common.h>
+#include "ptrace-common.h"
#endif
#ifdef CONFIG_PPC32
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index 91eb952e029..61762640b87 100644
--- a/arch/powerpc/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -33,7 +33,8 @@
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/system.h>
-#include <asm/ptrace-common.h>
+
+#include "ptrace-common.h"
/*
* does not yet catch signals sent when the child dies.
diff --git a/arch/powerpc/mm/imalloc.c b/arch/powerpc/mm/imalloc.c
index f4ca29cf536..f9587bcc6a4 100644
--- a/arch/powerpc/mm/imalloc.c
+++ b/arch/powerpc/mm/imalloc.c
@@ -14,9 +14,10 @@
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/semaphore.h>
-#include <asm/imalloc.h>
#include <asm/cacheflush.h>
+#include "mmu_decl.h"
+
static DECLARE_MUTEX(imlist_sem);
struct vm_struct * imlist = NULL;
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 1134f70f231..81cfb0c2ec5 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -64,7 +64,8 @@
#include <asm/iommu.h>
#include <asm/abs_addr.h>
#include <asm/vdso.h>
-#include <asm/imalloc.h>
+
+#include "mmu_decl.h"
#ifdef DEBUG
#define DBG(fmt...) printk(fmt)
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index a4d7a327c0e..bea2d21ac6f 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -33,7 +33,6 @@ extern void invalidate_tlbcam_entry(int index);
extern int __map_without_bats;
extern unsigned long ioremap_base;
-extern unsigned long ioremap_bot;
extern unsigned int rtas_data, rtas_size;
extern PTE *Hash, *Hash_end;
@@ -42,6 +41,7 @@ extern unsigned long Hash_size, Hash_mask;
extern unsigned int num_tlbcam_entries;
#endif
+extern unsigned long ioremap_bot;
extern unsigned long __max_low_memory;
extern unsigned long __initial_memory_limit;
extern unsigned long total_memory;
@@ -84,4 +84,16 @@ static inline void flush_HPTE(unsigned context, unsigned long va,
else
_tlbie(va);
}
+#else /* CONFIG_PPC64 */
+/* imalloc region types */
+#define IM_REGION_UNUSED 0x1
+#define IM_REGION_SUBSET 0x2
+#define IM_REGION_EXISTS 0x4
+#define IM_REGION_OVERLAP 0x8
+#define IM_REGION_SUPERSET 0x10
+
+extern struct vm_struct * im_get_free_area(unsigned long size);
+extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
+ int region_type);
+extern void im_free(void *addr);
#endif
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index c7f7bb6f30b..2ffca63602c 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -64,7 +64,8 @@
#include <asm/iommu.h>
#include <asm/abs_addr.h>
#include <asm/vdso.h>
-#include <asm/imalloc.h>
+
+#include "mmu_decl.h"
unsigned long ioremap_bot = IMALLOC_BASE;
static unsigned long phbs_io_bot = PHBS_IO_BASE;
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 957b0910342..fb2a7c798e8 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -34,6 +34,7 @@
#include <linux/errno.h>
#include <linux/hardirq.h>
#include <linux/cpu.h>
+#include <linux/compiler.h>
#include <asm/ptrace.h>
#include <asm/atomic.h>
@@ -631,8 +632,9 @@ void smp_core99_give_timebase(void)
mb();
/* wait for the secondary to have taken it */
- for (t = 100000; t > 0 && sec_tb_reset; --t)
- udelay(10);
+ /* note: can't use udelay here, since it needs the timebase running */
+ for (t = 10000000; t > 0 && sec_tb_reset; --t)
+ barrier();
if (sec_tb_reset)
/* XXX BUG_ON here? */
printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 105f05341a4..58d1cc2023c 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -361,7 +361,8 @@ static void mpic_enable_irq(unsigned int irq)
DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
- mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & ~MPIC_VECPRI_MASK);
+ mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
+ ~MPIC_VECPRI_MASK);
/* make sure mask gets to controller before we return to user */
do {
@@ -381,7 +382,8 @@ static void mpic_disable_irq(unsigned int irq)
DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
- mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | MPIC_VECPRI_MASK);
+ mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
+ MPIC_VECPRI_MASK);
/* make sure mask gets to controller before we return to user */
do {
@@ -735,12 +737,13 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
spin_lock_irqsave(&mpic_lock, flags);
if (is_ipi) {
- reg = mpic_ipi_read(irq - mpic->ipi_offset) & MPIC_VECPRI_PRIORITY_MASK;
+ reg = mpic_ipi_read(irq - mpic->ipi_offset) &
+ ~MPIC_VECPRI_PRIORITY_MASK;
mpic_ipi_write(irq - mpic->ipi_offset,
reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
} else {
- reg = mpic_irq_read(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI)
- & MPIC_VECPRI_PRIORITY_MASK;
+ reg = mpic_irq_read(irq - mpic->irq_offset,MPIC_IRQ_VECTOR_PRI)
+ & ~MPIC_VECPRI_PRIORITY_MASK;
mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI,
reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
}