Merge master.kernel.org:/home/rmk/linux-2.6-arm
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 296bc03..91d5ef3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -324,7 +324,7 @@
 
 config SMP
 	bool "Symmetric Multi-Processing (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && BROKEN #&& n
+	depends on EXPERIMENTAL && REALVIEW_MPCORE
 	help
 	  This enables support for systems with more than one CPU. If you have
 	  a system with only one CPU, like most personal computers, say N. If
@@ -585,7 +585,7 @@
 
 config FPE_NWFPE_XP
 	bool "Support extended precision"
-	depends on FPE_NWFPE && !CPU_BIG_ENDIAN
+	depends on FPE_NWFPE
 	help
 	  Say Y to include 80-bit support in the kernel floating-point
 	  emulator.  Otherwise, only 32 and 64-bit support is compiled in.
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index df14096..6851aba 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -84,63 +84,54 @@
 		.virtual	= IXP2000_CAP_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_CAP_PHYS_BASE),
 		.length		= IXP2000_CAP_SIZE,
-		.type		= MT_DEVICE
+		.type		= MT_IXP2000_DEVICE,
 	}, {
 		.virtual	= IXP2000_INTCTL_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE),
 		.length		= IXP2000_INTCTL_SIZE,
-		.type		= MT_DEVICE
+		.type		= MT_IXP2000_DEVICE,
 	}, {
 		.virtual	= IXP2000_PCI_CREG_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE),
 		.length		= IXP2000_PCI_CREG_SIZE,
-		.type		= MT_DEVICE
+		.type		= MT_IXP2000_DEVICE,
 	}, {
 		.virtual	= IXP2000_PCI_CSR_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE),
 		.length		= IXP2000_PCI_CSR_SIZE,
-		.type		= MT_DEVICE
+		.type		= MT_IXP2000_DEVICE,
 	}, {
 		.virtual	= IXP2000_MSF_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_MSF_PHYS_BASE),
 		.length		= IXP2000_MSF_SIZE,
-		.type		= MT_DEVICE
+		.type		= MT_IXP2000_DEVICE,
 	}, {
 		.virtual	= IXP2000_PCI_IO_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE),
 		.length		= IXP2000_PCI_IO_SIZE,
-		.type		= MT_DEVICE
+		.type		= MT_IXP2000_DEVICE,
 	}, {
 		.virtual	= IXP2000_PCI_CFG0_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE),
 		.length		= IXP2000_PCI_CFG0_SIZE,
-		.type		= MT_DEVICE
+		.type		= MT_IXP2000_DEVICE,
 	}, {
 		.virtual	= IXP2000_PCI_CFG1_VIRT_BASE,
 		.pfn		= __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE),
 		.length		= IXP2000_PCI_CFG1_SIZE,
-		.type		= MT_DEVICE
+		.type		= MT_IXP2000_DEVICE,
 	}
 };
 
 void __init ixp2000_map_io(void)
 {
-	extern unsigned int processor_id;
-
 	/*
-	 * On IXP2400 CPUs we need to use MT_IXP2000_DEVICE for
-	 * tweaking the PMDs so XCB=101. On IXP2800s we use the normal
-	 * PMD flags.
+	 * On IXP2400 CPUs we need to use MT_IXP2000_DEVICE so that
+	 * XCB=101 (to avoid triggering erratum #66), and given that
+	 * this mode speeds up I/O accesses and we have write buffer
+	 * flushes in the right places anyway, it doesn't hurt to use
+	 * XCB=101 for all IXP2000s.
 	 */
-	if ((processor_id & 0xfffffff0) == 0x69054190) {
-		int i;
-
-		printk(KERN_INFO "Enabling IXP2400 erratum #66 workaround\n");
-
-		for(i=0;i<ARRAY_SIZE(ixp2000_io_desc);i++)
-			ixp2000_io_desc[i].type = MT_IXP2000_DEVICE;
-	}
-
 	iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc));
 
 	/* Set slowport to 8-bit mode.  */
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index 4b63dc9..1299768 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -8,4 +8,13 @@
 	help
 	  Include support for the ARM(R) RealView Emulation Baseboard platform.
 
+config REALVIEW_MPCORE
+	bool "Support MPcore tile"
+	depends on MACH_REALVIEW_EB
+	help
+	  Enable support for the MPCore tile on the Realview platform.
+	  Since there are device address and interrupt differences, a
+	  kernel built with this option enabled is not compatible with
+	  other tiles.
+
 endmenu
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile
index 8d37ea1..011a85c 100644
--- a/arch/arm/mach-realview/Makefile
+++ b/arch/arm/mach-realview/Makefile
@@ -4,3 +4,4 @@
 
 obj-y					:= core.o clock.o
 obj-$(CONFIG_MACH_REALVIEW_EB)		+= realview_eb.o
+obj-$(CONFIG_SMP)			+= platsmp.o headsmp.o
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
index 575599d..d83e8ba 100644
--- a/arch/arm/mach-realview/core.h
+++ b/arch/arm/mach-realview/core.h
@@ -23,6 +23,7 @@
 #define __ASM_ARCH_REALVIEW_H
 
 #include <asm/hardware/amba.h>
+#include <asm/leds.h>
 #include <asm/io.h>
 
 #define __io_address(n)		__io(IO_ADDRESS(n))
diff --git a/arch/arm/mach-realview/headsmp.S b/arch/arm/mach-realview/headsmp.S
new file mode 100644
index 0000000..4075473
--- /dev/null
+++ b/arch/arm/mach-realview/headsmp.S
@@ -0,0 +1,39 @@
+/*
+ *  linux/arch/arm/mach-realview/headsmp.S
+ *
+ *  Copyright (c) 2003 ARM Limited
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+	__INIT
+
+/*
+ * Realview specific entry point for secondary CPUs.  This provides
+ * a "holding pen" into which all secondary cores are held until we're
+ * ready for them to initialise.
+ */
+ENTRY(realview_secondary_startup)
+	mrc	p15, 0, r0, c0, c0, 5
+	and	r0, r0, #15
+	adr	r4, 1f
+	ldmia	r4, {r5, r6}
+	sub	r4, r4, r5
+	add	r6, r6, r4
+pen:	ldr	r7, [r6]
+	cmp	r7, r0
+	bne	pen
+
+	/*
+	 * we've been released from the holding pen: secondary_stack
+	 * should now contain the SVC stack for this core
+	 */
+	b	secondary_startup
+
+1:	.long	.
+	.long	pen_release
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
new file mode 100644
index 0000000..9844644
--- /dev/null
+++ b/arch/arm/mach-realview/platsmp.c
@@ -0,0 +1,195 @@
+/*
+ *  linux/arch/arm/mach-realview/platsmp.c
+ *
+ *  Copyright (C) 2002 ARM Ltd.
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/arm_scu.h>
+#include <asm/hardware.h>
+
+#include "core.h"
+
+extern void realview_secondary_startup(void);
+
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+volatile int __cpuinitdata pen_release = -1;
+
+static unsigned int __init get_core_count(void)
+{
+	unsigned int ncores;
+
+	ncores = __raw_readl(IO_ADDRESS(REALVIEW_MPCORE_SCU_BASE) + SCU_CONFIG);
+
+	return (ncores & 0x03) + 1;
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+	/*
+	 * the primary core may have used a "cross call" soft interrupt
+	 * to get this processor out of WFI in the BootMonitor - make
+	 * sure that we are no longer being sent this soft interrupt
+	 */
+	smp_cross_call_done(cpumask_of_cpu(cpu));
+
+	/*
+	 * if any interrupts are already enabled for the primary
+	 * core (e.g. timer irq), then they will not have been enabled
+	 * for us: do so
+	 */
+	gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE));
+
+	/*
+	 * let the primary processor know we're out of the
+	 * pen, then head off into the C entry point
+	 */
+	pen_release = -1;
+
+	/*
+	 * Synchronise with the boot thread.
+	 */
+	spin_lock(&boot_lock);
+	spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	unsigned long timeout;
+
+	/*
+	 * set synchronisation state between this boot processor
+	 * and the secondary one
+	 */
+	spin_lock(&boot_lock);
+
+	/*
+	 * The secondary processor is waiting to be released from
+	 * the holding pen - release it, then wait for it to flag
+	 * that it has been released by resetting pen_release.
+	 *
+	 * Note that "pen_release" is the hardware CPU ID, whereas
+	 * "cpu" is Linux's internal ID.
+	 */
+	pen_release = cpu;
+	flush_cache_all();
+
+	/*
+	 * XXX
+	 *
+	 * This is a later addition to the booting protocol: the
+	 * bootMonitor now puts secondary cores into WFI, so
+	 * poke_milo() no longer gets the cores moving; we need
+	 * to send a soft interrupt to wake the secondary core.
+	 * Use smp_cross_call() for this, since there's little
+	 * point duplicating the code here
+	 */
+	smp_cross_call(cpumask_of_cpu(cpu));
+
+	timeout = jiffies + (1 * HZ);
+	while (time_before(jiffies, timeout)) {
+		if (pen_release == -1)
+			break;
+
+		udelay(10);
+	}
+
+	/*
+	 * now the secondary core is starting up let it run its
+	 * calibrations, then wait for it to finish
+	 */
+	spin_unlock(&boot_lock);
+
+	return pen_release != -1 ? -ENOSYS : 0;
+}
+
+static void __init poke_milo(void)
+{
+	extern void secondary_startup(void);
+
+	/* nobody is to be released from the pen yet */
+	pen_release = -1;
+
+	/*
+	 * write the address of secondary startup into the system-wide
+	 * flags register, then clear the bottom two bits, which is what
+	 * BootMonitor is waiting for
+	 */
+#if 1
+#define REALVIEW_SYS_FLAGSS_OFFSET 0x30
+	__raw_writel(virt_to_phys(realview_secondary_startup),
+		     (IO_ADDRESS(REALVIEW_SYS_BASE) +
+		      REALVIEW_SYS_FLAGSS_OFFSET));
+#define REALVIEW_SYS_FLAGSC_OFFSET 0x34
+	__raw_writel(3,
+		     (IO_ADDRESS(REALVIEW_SYS_BASE) +
+		      REALVIEW_SYS_FLAGSC_OFFSET));
+#endif
+
+	mb();
+}
+
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+	unsigned int ncores = get_core_count();
+	unsigned int cpu = smp_processor_id();
+	int i;
+
+	/* sanity check */
+	if (ncores == 0) {
+		printk(KERN_ERR
+		       "Realview: strange CM count of 0? Default to 1\n");
+
+		ncores = 1;
+	}
+
+	if (ncores > NR_CPUS) {
+		printk(KERN_WARNING
+		       "Realview: no. of cores (%d) greater than configured "
+		       "maximum of %d - clipping\n",
+		       ncores, NR_CPUS);
+		ncores = NR_CPUS;
+	}
+
+	smp_store_cpu_info(cpu);
+
+	/*
+	 * are we trying to boot more cores than exist?
+	 */
+	if (max_cpus > ncores)
+		max_cpus = ncores;
+
+	/*
+	 * Initialise the possible/present maps.
+	 * cpu_possible_map describes the set of CPUs which may be present
+	 * cpu_present_map describes the set of CPUs populated
+	 */
+	for (i = 0; i < max_cpus; i++) {
+		cpu_set(i, cpu_possible_map);
+		cpu_set(i, cpu_present_map);
+	}
+
+	/*
+	 * Do we need any more CPUs? If so, then let them know where
+	 * to start. Note that, on modern versions of MILO, the "poke"
+	 * doesn't actually do anything until each individual core is
+	 * sent a soft interrupt to get it out of WFI
+	 */
+	if (max_cpus > 1)
+		poke_milo();
+}
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 267bb07..7dc3250 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -136,6 +136,11 @@
 
 static void __init gic_init_irq(void)
 {
+#ifdef CONFIG_REALVIEW_MPCORE
+	writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK));
+	writel(0x008003c0, __io_address(REALVIEW_SYS_BASE) + 0xd8);
+	writel(0x00000000, __io_address(REALVIEW_SYS_LOCK));
+#endif
 	gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE));
 	gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE));
 }
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index fb5b402..9e50127 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -354,7 +354,7 @@
 {
 	struct cachepolicy *cp;
 	unsigned int cr = get_cr();
-	unsigned int user_pgprot;
+	unsigned int user_pgprot, kern_pgprot;
 	int cpu_arch = cpu_architecture();
 	int i;
 
@@ -381,7 +381,7 @@
 	}
 
 	cp = &cache_policies[cachepolicy];
-	user_pgprot = cp->pte;
+	kern_pgprot = user_pgprot = cp->pte;
 
 	/*
 	 * ARMv6 and above have extended page tables.
@@ -393,6 +393,7 @@
 		 */
 		mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4;
 		mem_types[MT_ROM].prot_sect &= ~PMD_BIT4;
+
 		/*
 		 * Mark cache clean areas and XIP ROM read only
 		 * from SVC mode and no access from userspace.
@@ -412,32 +413,47 @@
 		 * (iow, non-global)
 		 */
 		user_pgprot |= L_PTE_ASID;
+
+#ifdef CONFIG_SMP
+		/*
+		 * Mark memory with the "shared" attribute for SMP systems
+		 */
+		user_pgprot |= L_PTE_SHARED;
+		kern_pgprot |= L_PTE_SHARED;
+		mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
+#endif
 	}
 
+	for (i = 0; i < 16; i++) {
+		unsigned long v = pgprot_val(protection_map[i]);
+		v = (v & ~(L_PTE_BUFFERABLE|L_PTE_CACHEABLE)) | user_pgprot;
+		protection_map[i] = __pgprot(v);
+	}
+
+	mem_types[MT_LOW_VECTORS].prot_pte |= kern_pgprot;
+	mem_types[MT_HIGH_VECTORS].prot_pte |= kern_pgprot;
+
 	if (cpu_arch >= CPU_ARCH_ARMv5) {
-		mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE;
-		mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE;
+#ifndef CONFIG_SMP
+		/*
+		 * Only use write-through for non-SMP systems
+		 */
+		mem_types[MT_LOW_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
+		mem_types[MT_HIGH_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
+#endif
 	} else {
-		mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte;
-		mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte;
 		mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1);
 	}
 
+	pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
+				 L_PTE_DIRTY | L_PTE_WRITE |
+				 L_PTE_EXEC | kern_pgprot);
+
 	mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
 	mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
 	mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
 	mem_types[MT_ROM].prot_sect |= cp->pmd;
 
-	for (i = 0; i < 16; i++) {
-		unsigned long v = pgprot_val(protection_map[i]);
-		v = (v & ~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot;
-		protection_map[i] = __pgprot(v);
-	}
-
-	pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
-				 L_PTE_DIRTY | L_PTE_WRITE |
-				 L_PTE_EXEC | cp->pte);
-
 	switch (cp->pmd) {
 	case PMD_SECT_WT:
 		mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT;
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 9bb5fff..92f3ca3 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -12,6 +12,7 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 #include <asm/asm-offsets.h>
+#include <asm/hardware/arm_scu.h>
 #include <asm/procinfo.h>
 #include <asm/pgtable.h>
 
@@ -112,6 +113,9 @@
 ENTRY(cpu_v6_switch_mm)
 	mov	r2, #0
 	ldr	r1, [r1, #MM_CONTEXT_ID]	@ get mm->context.id
+#ifdef CONFIG_SMP
+	orr	r0, r0, #2			@ set shared pgtable
+#endif
 	mcr	p15, 0, r2, c7, c5, 6		@ flush BTAC/BTB
 	mcr	p15, 0, r2, c7, c10, 4		@ drain write buffer
 	mcr	p15, 0, r0, c2, c0, 0		@ set TTB 0
@@ -140,7 +144,7 @@
 ENTRY(cpu_v6_set_pte)
 	str	r1, [r0], #-2048		@ linux version
 
-	bic	r2, r1, #0x000007f0
+	bic	r2, r1, #0x000003f0
 	bic	r2, r2, #0x00000003
 	orr	r2, r2, #PTE_EXT_AP0 | 2
 
@@ -191,6 +195,23 @@
  *	- cache type register is implemented
  */
 __v6_setup:
+#ifdef CONFIG_SMP
+	/* Set up the SCU on core 0 only */
+	mrc	p15, 0, r0, c0, c0, 5		@ CPU core number
+	ands	r0, r0, #15
+	moveq	r0, #0x10000000 @ SCU_BASE
+	orreq	r0, r0, #0x00100000
+	ldreq	r5, [r0, #SCU_CTRL]
+	orreq	r5, r5, #1
+	streq	r5, [r0, #SCU_CTRL]
+
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+	mrc	p15, 0, r0, c1, c0, 1		@ Enable SMP/nAMP mode
+	orr	r0, r0, #0x20
+	mcr	p15, 0, r0, c1, c0, 1
+#endif
+#endif
+
 	mov	r0, #0
 	mcr	p15, 0, r0, c7, c14, 0		@ clean+invalidate D cache
 	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
@@ -198,6 +219,9 @@
 	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer
 	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I + D TLBs
 	mcr	p15, 0, r0, c2, c0, 2		@ TTB control register
+#ifdef CONFIG_SMP
+	orr	r4, r4, #2			@ set shared pgtable
+#endif
 	mcr	p15, 0, r4, c2, c0, 1		@ load TTB1
 #ifdef CONFIG_VFP
 	mrc	p15, 0, r0, c1, c0, 2
diff --git a/arch/arm/nwfpe/fpa11.h b/arch/arm/nwfpe/fpa11.h
index 9677ae8..da4c616 100644
--- a/arch/arm/nwfpe/fpa11.h
+++ b/arch/arm/nwfpe/fpa11.h
@@ -60,7 +60,7 @@
 #ifdef CONFIG_FPE_NWFPE_XP
 	floatx80 fExtended;
 #else
-	int padding[3];
+	u32 padding[3];
 #endif
 } FPREG;
 
diff --git a/arch/arm/nwfpe/fpa11_cpdt.c b/arch/arm/nwfpe/fpa11_cpdt.c
index b0db5cb..32859fa 100644
--- a/arch/arm/nwfpe/fpa11_cpdt.c
+++ b/arch/arm/nwfpe/fpa11_cpdt.c
@@ -59,8 +59,13 @@
 	p = (unsigned int *) &fpa11->fpreg[Fn].fExtended;
 	fpa11->fType[Fn] = typeExtended;
 	get_user(p[0], &pMem[0]);	/* sign & exponent */
+#ifdef __ARMEB__
+	get_user(p[1], &pMem[1]);	/* ms bits */
+	get_user(p[2], &pMem[2]);	/* ls bits */
+#else
 	get_user(p[1], &pMem[2]);	/* ls bits */
 	get_user(p[2], &pMem[1]);	/* ms bits */
+#endif
 }
 #endif
 
@@ -177,8 +182,13 @@
 	}
 
 	put_user(val.i[0], &pMem[0]);	/* sign & exp */
+#ifdef __ARMEB__
+	put_user(val.i[1], &pMem[1]);	/* msw */
+	put_user(val.i[2], &pMem[2]);
+#else
 	put_user(val.i[1], &pMem[2]);
 	put_user(val.i[2], &pMem[1]);	/* msw */
+#endif
 }
 #endif
 
diff --git a/arch/arm/nwfpe/fpopcode.c b/arch/arm/nwfpe/fpopcode.c
index 4c9f570..67ff2ab 100644
--- a/arch/arm/nwfpe/fpopcode.c
+++ b/arch/arm/nwfpe/fpopcode.c
@@ -29,14 +29,14 @@
 
 #ifdef CONFIG_FPE_NWFPE_XP
 const floatx80 floatx80Constant[] = {
-	{0x0000, 0x0000000000000000ULL},	/* extended 0.0 */
-	{0x3fff, 0x8000000000000000ULL},	/* extended 1.0 */
-	{0x4000, 0x8000000000000000ULL},	/* extended 2.0 */
-	{0x4000, 0xc000000000000000ULL},	/* extended 3.0 */
-	{0x4001, 0x8000000000000000ULL},	/* extended 4.0 */
-	{0x4001, 0xa000000000000000ULL},	/* extended 5.0 */
-	{0x3ffe, 0x8000000000000000ULL},	/* extended 0.5 */
-	{0x4002, 0xa000000000000000ULL}		/* extended 10.0 */
+	{ .high = 0x0000, .low = 0x0000000000000000ULL},/* extended 0.0 */
+	{ .high = 0x3fff, .low = 0x8000000000000000ULL},/* extended 1.0 */
+	{ .high = 0x4000, .low = 0x8000000000000000ULL},/* extended 2.0 */
+	{ .high = 0x4000, .low = 0xc000000000000000ULL},/* extended 3.0 */
+	{ .high = 0x4001, .low = 0x8000000000000000ULL},/* extended 4.0 */
+	{ .high = 0x4001, .low = 0xa000000000000000ULL},/* extended 5.0 */
+	{ .high = 0x3ffe, .low = 0x8000000000000000ULL},/* extended 0.5 */
+	{ .high = 0x4002, .low = 0xa000000000000000ULL},/* extended 10.0 */
 };
 #endif
 
diff --git a/arch/arm/nwfpe/softfloat-specialize b/arch/arm/nwfpe/softfloat-specialize
index acf4091..d4a4c8e 100644
--- a/arch/arm/nwfpe/softfloat-specialize
+++ b/arch/arm/nwfpe/softfloat-specialize
@@ -332,6 +332,7 @@
 
     z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
     z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
+    z.__padding = 0;
     return z;
 
 }
diff --git a/arch/arm/nwfpe/softfloat.c b/arch/arm/nwfpe/softfloat.c
index f9f0491..0f9656e 100644
--- a/arch/arm/nwfpe/softfloat.c
+++ b/arch/arm/nwfpe/softfloat.c
@@ -531,6 +531,7 @@
 
     z.low = zSig;
     z.high = ( ( (bits16) zSign )<<15 ) + zExp;
+    z.__padding = 0;
     return z;
 
 }
@@ -2831,6 +2832,7 @@
         roundData->exception |= float_flag_invalid;
         z.low = floatx80_default_nan_low;
         z.high = floatx80_default_nan_high;
+        z.__padding = 0;
         return z;
     }
     if ( aExp == 0 ) {
@@ -2950,6 +2952,7 @@
             roundData->exception |= float_flag_invalid;
             z.low = floatx80_default_nan_low;
             z.high = floatx80_default_nan_high;
+            z.__padding = 0;
             return z;
         }
         return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
@@ -3015,6 +3018,7 @@
                 roundData->exception |= float_flag_invalid;
                 z.low = floatx80_default_nan_low;
                 z.high = floatx80_default_nan_high;
+                z.__padding = 0;
                 return z;
             }
             roundData->exception |= float_flag_divbyzero;
@@ -3093,6 +3097,7 @@
             roundData->exception |= float_flag_invalid;
             z.low = floatx80_default_nan_low;
             z.high = floatx80_default_nan_high;
+            z.__padding = 0;
             return z;
         }
         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
@@ -3184,6 +3189,7 @@
         roundData->exception |= float_flag_invalid;
         z.low = floatx80_default_nan_low;
         z.high = floatx80_default_nan_high;
+        z.__padding = 0;
         return z;
     }
     if ( aExp == 0 ) {
diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h
index 1415170..978c699 100644
--- a/arch/arm/nwfpe/softfloat.h
+++ b/arch/arm/nwfpe/softfloat.h
@@ -51,11 +51,17 @@
 Software IEC/IEEE floating-point types.
 -------------------------------------------------------------------------------
 */
-typedef unsigned long int float32;
-typedef unsigned long long float64;
+typedef u32 float32;
+typedef u64 float64;
 typedef struct {
-    unsigned short high;
-    unsigned long long low;
+#ifdef __ARMEB__
+    u16 __padding;
+    u16 high;
+#else
+    u16 high;
+    u16 __padding;
+#endif
+    u64 low;
 } floatx80;
 
 /*
diff --git a/include/asm-arm/arch-realview/entry-macro.S b/include/asm-arm/arch-realview/entry-macro.S
index 2712ba7..4df469b 100644
--- a/include/asm-arm/arch-realview/entry-macro.S
+++ b/include/asm-arm/arch-realview/entry-macro.S
@@ -47,3 +47,17 @@
 		cmpcs	\irqnr, \irqnr
 
 		.endm
+
+		/* We assume that irqstat (the raw value of the IRQ acknowledge
+		 * register) is preserved from the macro above.
+		 * If there is an IPI, we immediately signal end of interrupt on the
+		 * controller, since this requires the original irqstat value which
+		 * we won't easily be able to recreate later.
+		 */
+
+		.macro test_for_ipi, irqnr, irqstat, base, tmp
+		bic	\irqnr, \irqstat, #0x1c00
+		cmp	\irqnr, #16
+		strcc	\irqstat, [\base, #GIC_CPU_EOI]
+		cmpcs	\irqnr, \irqnr
+		.endm
diff --git a/include/asm-arm/arch-realview/platform.h b/include/asm-arm/arch-realview/platform.h
index 4b6de13..aef9b36 100644
--- a/include/asm-arm/arch-realview/platform.h
+++ b/include/asm-arm/arch-realview/platform.h
@@ -203,8 +203,14 @@
 	/* Reserved 0x1001A000 - 0x1001FFFF */
 #define REALVIEW_CLCD_BASE            0x10020000	/* CLCD */
 #define REALVIEW_DMAC_BASE            0x10030000	/* DMA controller */
+#ifndef CONFIG_REALVIEW_MPCORE
 #define REALVIEW_GIC_CPU_BASE         0x10040000	/* Generic interrupt controller CPU interface */
 #define REALVIEW_GIC_DIST_BASE        0x10041000	/* Generic interrupt controller distributor */
+#else
+#define REALVIEW_MPCORE_SCU_BASE	0x10100000	/*  SCU registers */
+#define REALVIEW_GIC_CPU_BASE		0x10100100	/* Generic interrupt controller CPU interface */
+#define REALVIEW_GIC_DIST_BASE		0x10101000	/* Generic interrupt controller distributor */
+#endif
 #define REALVIEW_SMC_BASE             0x10080000	/* SMC */
 	/* Reserved 0x10090000 - 0x100EFFFF */
 
@@ -265,6 +271,7 @@
  *  Interrupts - bit assignment (primary)
  * ------------------------------------------------------------------------
  */
+#ifndef CONFIG_REALVIEW_MPCORE
 #define INT_WDOGINT			0	/* Watchdog timer */
 #define INT_SOFTINT			1	/* Software interrupt */
 #define INT_COMMRx			2	/* Debug Comm Rx interrupt */
@@ -297,6 +304,55 @@
 #define INT_USB				29	/* USB controller */
 #define INT_TSPENINT			30	/* Touchscreen pen */
 #define INT_TSKPADINT			31	/* Touchscreen keypad */
+#else
+#define INT_LOCALTIMER			29
+#define INT_LOCALWDOG			30
+
+#define INT_AACI			0
+#define INT_TIMERINT0_1			1
+#define INT_TIMERINT2_3			2
+#define INT_USB				3
+#define INT_UARTINT0			4
+#define INT_UARTINT1			5
+#define INT_RTCINT			6
+#define INT_KMI0			7
+#define INT_KMI1			8
+#define INT_ETH				9
+#define INT_EB_IRQ1			10	/* main GIC */
+#define INT_EB_IRQ2			11	/* tile GIC */
+#define INT_EB_FIQ1			12	/* main GIC */
+#define INT_EB_FIQ2			13	/* tile GIC */
+#define INT_MMCI0A			14
+#define INT_MMCI0B			15
+
+#define INT_PMU_CPU0			17
+#define INT_PMU_CPU1			18
+#define INT_PMU_CPU2			19
+#define INT_PMU_CPU3			20
+#define INT_PMU_SCU0			21
+#define INT_PMU_SCU1			22
+#define INT_PMU_SCU2			23
+#define INT_PMU_SCU3			24
+#define INT_PMU_SCU4			25
+#define INT_PMU_SCU5			26
+#define INT_PMU_SCU6			27
+#define INT_PMU_SCU7			28
+
+#define INT_L220_EVENT			29
+#define INT_L220_SLAVE			30
+#define INT_L220_DECODE			31
+
+#define INT_UARTINT2			-1
+#define INT_UARTINT3			-1
+#define INT_CLCDINT			-1
+#define INT_DMAINT			-1
+#define INT_WDOGINT			-1
+#define INT_GPIOINT0			-1
+#define INT_GPIOINT1			-1
+#define INT_GPIOINT2			-1
+#define INT_SCIINT			-1
+#define INT_SSPINT			-1
+#endif
 
 /* 
  *  Interrupt bit positions
diff --git a/include/asm-arm/arch-realview/smp.h b/include/asm-arm/arch-realview/smp.h
new file mode 100644
index 0000000..fc87783
--- /dev/null
+++ b/include/asm-arm/arch-realview/smp.h
@@ -0,0 +1,31 @@
+#ifndef ASMARM_ARCH_SMP_H
+#define ASMARM_ARCH_SMP_H
+
+#include <linux/config.h>
+
+#include <asm/hardware/gic.h>
+
+#define hard_smp_processor_id()			\
+	({						\
+		unsigned int cpunum;			\
+		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
+			: "=r" (cpunum));		\
+		cpunum &= 0x0F;				\
+	})
+
+/*
+ * We use IRQ1 as the IPI
+ */
+static inline void smp_cross_call(cpumask_t callmap)
+{
+	gic_raise_softirq(callmap, 1);
+}
+
+/*
+ * Do nothing on MPcore.
+ */
+static inline void smp_cross_call_done(cpumask_t callmap)
+{
+}
+
+#endif
diff --git a/include/asm-arm/hardware/arm_scu.h b/include/asm-arm/hardware/arm_scu.h
new file mode 100644
index 0000000..9903f60
--- /dev/null
+++ b/include/asm-arm/hardware/arm_scu.h
@@ -0,0 +1,13 @@
+#ifndef ASMARM_HARDWARE_ARM_SCU_H
+#define ASMARM_HARDWARE_ARM_SCU_H
+
+/*
+ * SCU registers
+ */
+#define SCU_CTRL		0x00
+#define SCU_CONFIG		0x04
+#define SCU_CPU_STATUS		0x08
+#define SCU_INVALIDATE		0x0c
+#define SCU_FPGA_REVISION	0x10
+
+#endif