summary refs log tree commit diff
path: root/arch
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-03-29 13:24:50 +1100
committerPaul Mackerras <paulus@samba.org>2006-03-29 13:24:50 +1100
commitbac30d1a78d0f11c613968fc8b351a91ed465386 (patch)
treee52f3c876522a2f6047a6ec1c27df2e8a79486b8 /arch
parente8222502ee6157e2713da9e0792c21f4ad458d50 (diff)
parentca9ba4471c1203bb6e759b76e83167fec54fe590 (diff)
downloadlinux-bac30d1a78d0f11c613968fc8b351a91ed465386.tar.gz
Merge ../linux-2.6
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/kernel/setup.c14
-rw-r--r--arch/alpha/kernel/time.c3
-rw-r--r--arch/alpha/mm/numa.c4
-rw-r--r--arch/arm/Kconfig14
-rw-r--r--arch/arm/Makefile2
-rw-r--r--arch/arm/boot/compressed/Makefile4
-rw-r--r--arch/arm/boot/compressed/ice-dcc.S17
-rw-r--r--arch/arm/boot/compressed/misc.c41
-rw-r--r--arch/arm/common/rtctime.c108
-rw-r--r--arch/arm/configs/ixp23xx_defconfig1302
-rw-r--r--arch/arm/lib/Makefile2
-rw-r--r--arch/arm/lib/copy_template.S2
-rw-r--r--arch/arm/mach-ep93xx/core.c68
-rw-r--r--arch/arm/mach-footbridge/time.c17
-rw-r--r--arch/arm/mach-integrator/core.c46
-rw-r--r--arch/arm/mach-integrator/time.c16
-rw-r--r--arch/arm/mach-ixp23xx/Kconfig25
-rw-r--r--arch/arm/mach-ixp23xx/Makefile11
-rw-r--r--arch/arm/mach-ixp23xx/Makefile.boot2
-rw-r--r--arch/arm/mach-ixp23xx/core.c431
-rw-r--r--arch/arm/mach-ixp23xx/espresso.c69
-rw-r--r--arch/arm/mach-ixp23xx/ixdp2351.c325
-rw-r--r--arch/arm/mach-ixp23xx/pci.c275
-rw-r--r--arch/arm/mach-ixp23xx/roadrunner.c164
-rw-r--r--arch/arm/mach-omap1/board-netstar.c2
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c2
-rw-r--r--arch/arm/mach-pxa/Kconfig5
-rw-r--r--arch/arm/mach-pxa/Makefile1
-rw-r--r--arch/arm/mach-pxa/generic.c6
-rw-r--r--arch/arm/mach-pxa/lpd270.c393
-rw-r--r--arch/arm/mach-pxa/spitz.c2
-rw-r--r--arch/arm/mach-sa1100/Kconfig2
-rw-r--r--arch/arm/mach-sa1100/cpu-sa1100.c2
-rw-r--r--arch/arm/mach-sa1100/generic.c6
-rw-r--r--arch/arm/mm/Kconfig19
-rw-r--r--arch/arm/mm/Makefile2
-rw-r--r--arch/arm/mm/copypage-xsc3.S97
-rw-r--r--arch/arm/mm/mm-armv.c3
-rw-r--r--arch/arm/mm/proc-v6.S16
-rw-r--r--arch/arm/mm/proc-xsc3.S498
-rw-r--r--arch/arm26/mm/init.c7
-rw-r--r--arch/cris/kernel/setup.c5
-rw-r--r--arch/i386/Kconfig9
-rw-r--r--arch/i386/boot/video.S2
-rw-r--r--arch/i386/kernel/cpu/common.c10
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k8.c7
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k8.h4
-rw-r--r--arch/i386/kernel/cpu/intel_cacheinfo.c77
-rw-r--r--arch/i386/kernel/io_apic.c4
-rw-r--r--arch/i386/kernel/microcode.c17
-rw-r--r--arch/i386/kernel/nmi.c9
-rw-r--r--arch/i386/kernel/setup.c1
-rw-r--r--arch/i386/kernel/smpboot.c24
-rw-r--r--arch/i386/kernel/syscall_table.S2
-rw-r--r--arch/i386/kernel/timers/timer_pm.c104
-rw-r--r--arch/i386/kernel/traps.c17
-rw-r--r--arch/i386/mach-voyager/voyager_smp.c2
-rw-r--r--arch/i386/mm/discontig.c12
-rw-r--r--arch/i386/mm/pgtable.c2
-rw-r--r--arch/i386/oprofile/nmi_int.c2
-rw-r--r--arch/ia64/kernel/traps.c6
-rw-r--r--arch/ia64/mm/discontig.c33
-rw-r--r--arch/ia64/mm/init.c2
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_proc_fs.c39
-rw-r--r--arch/m32r/kernel/setup.c1
-rw-r--r--arch/m32r/mm/discontig.c7
-rw-r--r--arch/m32r/mm/init.c3
-rw-r--r--arch/m68k/mvme16x/rtc.c4
-rw-r--r--arch/mips/au1000/common/setup.c2
-rw-r--r--arch/mips/ddb5xxx/common/rtc_ds1386.c4
-rw-r--r--arch/mips/dec/time.c51
-rw-r--r--arch/mips/ite-boards/generic/time.c4
-rw-r--r--arch/mips/ite-boards/ivr/init.c3
-rw-r--r--arch/mips/ite-boards/qed-4n-s01b/init.c3
-rw-r--r--arch/mips/jmr3927/common/rtc_ds1742.c4
-rw-r--r--arch/mips/kernel/setup.c9
-rw-r--r--arch/mips/kernel/time.c22
-rw-r--r--arch/mips/lasat/setup.c7
-rw-r--r--arch/mips/mips-boards/atlas/atlas_setup.c2
-rw-r--r--arch/mips/mips-boards/generic/memory.c7
-rw-r--r--arch/mips/mips-boards/malta/malta_setup.c2
-rw-r--r--arch/mips/mips-boards/sim/sim_mem.c7
-rw-r--r--arch/mips/mm/init.c4
-rw-r--r--arch/mips/momentum/jaguar_atx/setup.c4
-rw-r--r--arch/mips/momentum/ocelot_3/setup.c38
-rw-r--r--arch/mips/momentum/ocelot_c/setup.c4
-rw-r--r--arch/mips/pmc-sierra/yosemite/setup.c4
-rw-r--r--arch/mips/sgi-ip22/ip22-reset.c2
-rw-r--r--arch/mips/sgi-ip22/ip22-time.c4
-rw-r--r--arch/mips/sgi-ip27/ip27-memory.c3
-rw-r--r--arch/mips/sgi-ip32/ip32-reset.c2
-rw-r--r--arch/mips/sgi-ip32/ip32-setup.c4
-rw-r--r--arch/mips/sibyte/swarm/setup.c8
-rw-r--r--arch/mips/sni/setup.c4
-rw-r--r--arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c4
-rw-r--r--arch/mips/tx4938/common/rtc_rx5c348.c16
-rw-r--r--arch/parisc/kernel/pdc_chassis.c3
-rw-r--r--arch/powerpc/kernel/setup_64.c3
-rw-r--r--arch/powerpc/kernel/traps.c16
-rw-r--r--arch/powerpc/mm/mem.c4
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c2
-rw-r--r--arch/powerpc/platforms/chrp/time.c22
-rw-r--r--arch/powerpc/platforms/maple/time.c24
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c10
-rw-r--r--arch/ppc/kernel/ppc_htab.c2
-rw-r--r--arch/ppc/platforms/prep_setup.c2
-rw-r--r--arch/s390/kernel/process.c11
-rw-r--r--arch/sh/boards/mpc1211/rtc.c50
-rw-r--r--arch/sh/boards/sh03/rtc.c13
-rw-r--r--arch/sh/kernel/cpu/rtc.c10
-rw-r--r--arch/sh/kernel/setup.c5
-rw-r--r--arch/sh64/kernel/setup.c1
-rw-r--r--arch/sh64/kernel/time.c9
-rw-r--r--arch/sparc64/kernel/time.c16
-rw-r--r--arch/sparc64/kernel/traps.c17
-rw-r--r--arch/sparc64/mm/fault.c4
-rw-r--r--arch/um/drivers/mconsole_kern.c3
-rw-r--r--arch/um/drivers/ubd_kern.c76
-rw-r--r--arch/um/include/irq_user.h15
-rw-r--r--arch/um/include/kern.h2
-rw-r--r--arch/um/include/misc_constants.h6
-rw-r--r--arch/um/include/os.h36
-rw-r--r--arch/um/include/sigio.h3
-rw-r--r--arch/um/include/skas/mode-skas.h1
-rw-r--r--arch/um/include/skas/skas.h1
-rw-r--r--arch/um/include/user_util.h1
-rw-r--r--arch/um/kernel/Makefile9
-rw-r--r--arch/um/kernel/exec_kern.c2
-rw-r--r--arch/um/kernel/irq.c294
-rw-r--r--arch/um/kernel/irq_user.c412
-rw-r--r--arch/um/kernel/physmem.c3
-rw-r--r--arch/um/kernel/sigio_kern.c10
-rw-r--r--arch/um/kernel/smp.c14
-rw-r--r--arch/um/kernel/um_arch.c12
-rw-r--r--arch/um/os-Linux/Makefile13
-rw-r--r--arch/um/os-Linux/irq.c162
-rw-r--r--arch/um/os-Linux/sigio.c (renamed from arch/um/kernel/sigio_user.c)233
-rw-r--r--arch/um/os-Linux/start_up.c128
-rw-r--r--arch/um/os-Linux/tt.c10
-rw-r--r--arch/um/os-Linux/tty_log.c (renamed from arch/um/kernel/tty_log.c)18
-rw-r--r--arch/um/os-Linux/umid.c33
-rw-r--r--arch/um/sys-i386/ptrace.c15
-rw-r--r--arch/um/sys-i386/signal.c59
-rw-r--r--arch/um/sys-i386/user-offsets.c10
-rw-r--r--arch/um/sys-x86_64/ptrace.c22
-rw-r--r--arch/um/sys-x86_64/signal.c56
-rw-r--r--arch/um/sys-x86_64/user-offsets.c6
-rw-r--r--arch/x86_64/Kconfig13
-rw-r--r--arch/x86_64/ia32/ia32entry.S2
-rw-r--r--arch/x86_64/kernel/process.c17
-rw-r--r--arch/x86_64/kernel/setup.c3
-rw-r--r--arch/x86_64/kernel/smpboot.c24
-rw-r--r--arch/x86_64/kernel/time.c41
-rw-r--r--arch/x86_64/kernel/traps.c18
-rw-r--r--arch/x86_64/mm/init.c2
-rw-r--r--arch/x86_64/mm/numa.c15
-rw-r--r--arch/xtensa/platform-iss/setup.c2
157 files changed, 5236 insertions, 1448 deletions
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index b4e5f8ff2b25..dd8769670596 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -34,6 +34,7 @@
 #include <linux/root_dev.h>
 #include <linux/initrd.h>
 #include <linux/eisa.h>
+#include <linux/pfn.h>
 #ifdef CONFIG_MAGIC_SYSRQ
 #include <linux/sysrq.h>
 #include <linux/reboot.h>
@@ -42,7 +43,7 @@
 #include <asm/setup.h>
 #include <asm/io.h>
 
-extern struct notifier_block *panic_notifier_list;
+extern struct atomic_notifier_head panic_notifier_list;
 static int alpha_panic_event(struct notifier_block *, unsigned long, void *);
 static struct notifier_block alpha_panic_block = {
 	alpha_panic_event,
@@ -241,9 +242,6 @@ reserve_std_resources(void)
 		request_resource(io, standard_io_resources+i);
 }
 
-#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x)	((x) << PAGE_SHIFT)
 #define PFN_MAX		PFN_DOWN(0x80000000)
 #define for_each_mem_cluster(memdesc, cluster, i)		\
 	for ((cluster) = (memdesc)->cluster, (i) = 0;		\
@@ -472,11 +470,6 @@ page_is_ram(unsigned long pfn)
 	return 0;
 }
 
-#undef PFN_UP
-#undef PFN_DOWN
-#undef PFN_PHYS
-#undef PFN_MAX
-
 void __init
 setup_arch(char **cmdline_p)
 {
@@ -507,7 +500,8 @@ setup_arch(char **cmdline_p)
 	}
 
 	/* Register a call for panic conditions. */
-	notifier_chain_register(&panic_notifier_list, &alpha_panic_block);
+	atomic_notifier_chain_register(&panic_notifier_list,
+			&alpha_panic_block);
 
 #ifdef CONFIG_ALPHA_GENERIC
 	/* Assume that we've booted from SRM if we haven't booted from MILO.
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index 6b2921be1909..3859749810b4 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -314,10 +314,11 @@ time_init(void)
 	if (!est_cycle_freq)
 		est_cycle_freq = validate_cc_value(calibrate_cc_with_pit());
 
-	cc1 = rpcc_after_update_in_progress();
+	cc1 = rpcc();
 
 	/* Calibrate CPU clock -- attempt #2.  */
 	if (!est_cycle_freq) {
+		cc1 = rpcc_after_update_in_progress();
 		cc2 = rpcc_after_update_in_progress();
 		est_cycle_freq = validate_cc_value(cc2 - cc1);
 		cc1 = cc2;
diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c
index 6d5251254f68..bf6b65c81bef 100644
--- a/arch/alpha/mm/numa.c
+++ b/arch/alpha/mm/numa.c
@@ -13,6 +13,7 @@
 #include <linux/bootmem.h>
 #include <linux/swap.h>
 #include <linux/initrd.h>
+#include <linux/pfn.h>
 
 #include <asm/hwrpb.h>
 #include <asm/pgalloc.h>
@@ -27,9 +28,6 @@ bootmem_data_t node_bdata[MAX_NUMNODES];
 #define DBGDCONT(args...)
 #endif
 
-#define PFN_UP(x)       (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define PFN_DOWN(x)     ((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x)     ((x) << PAGE_SHIFT)
 #define for_each_mem_cluster(memdesc, cluster, i)		\
 	for ((cluster) = (memdesc)->cluster, (i) = 0;		\
 	     (i) < (memdesc)->numclusters; (i)++, (cluster)++)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index bf2e72698d02..ba46d779ede7 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -8,6 +8,7 @@ mainmenu "Linux Kernel Configuration"
 config ARM
 	bool
 	default y
+	select RTC_LIB
 	help
 	  The ARM series is a line of low-power-consumption RISC chip designs
 	  licensed by ARM Ltd and targeted at embedded applications and
@@ -152,6 +153,12 @@ config ARCH_IXP2000
 	help
 	  Support for Intel's IXP2400/2800 (XScale) family of processors.
 
+config ARCH_IXP23XX
+ 	bool "IXP23XX-based"
+ 	select PCI
+	help
+	  Support for Intel's IXP23xx (XScale) family of processors.
+
 config ARCH_L7200
 	bool "LinkUp-L7200"
 	select FIQ
@@ -273,6 +280,8 @@ source "arch/arm/mach-ixp4xx/Kconfig"
 
 source "arch/arm/mach-ixp2000/Kconfig"
 
+source "arch/arm/mach-ixp23xx/Kconfig"
+
 source "arch/arm/mach-pxa/Kconfig"
 
 source "arch/arm/mach-sa1100/Kconfig"
@@ -791,7 +800,8 @@ source "drivers/acorn/block/Kconfig"
 
 if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \
 	|| ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \
-	|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE
+	|| ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \
+	|| ARCH_IXP23XX
 source "drivers/ide/Kconfig"
 endif
 
@@ -839,6 +849,8 @@ source "drivers/usb/Kconfig"
 
 source "drivers/mmc/Kconfig"
 
+source "drivers/rtc/Kconfig"
+
 endmenu
 
 source "fs/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 99c0d323719a..ce3e804ea0f3 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -57,6 +57,7 @@ tune-$(CONFIG_CPU_ARM926T)	:=-mtune=arm9tdmi
 tune-$(CONFIG_CPU_SA110)	:=-mtune=strongarm110
 tune-$(CONFIG_CPU_SA1100)	:=-mtune=strongarm1100
 tune-$(CONFIG_CPU_XSCALE)	:=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
+tune-$(CONFIG_CPU_XSC3)		:=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
 tune-$(CONFIG_CPU_V6)		:=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
 
 ifeq ($(CONFIG_AEABI),y)
@@ -97,6 +98,7 @@ endif
  machine-$(CONFIG_ARCH_IOP3XX)	   := iop3xx
  machine-$(CONFIG_ARCH_IXP4XX)	   := ixp4xx
  machine-$(CONFIG_ARCH_IXP2000)    := ixp2000
+ machine-$(CONFIG_ARCH_IXP23XX)    := ixp23xx
  machine-$(CONFIG_ARCH_OMAP1)	   := omap1
  machine-$(CONFIG_ARCH_OMAP2)	   := omap2
   incdir-$(CONFIG_ARCH_OMAP)	   := omap
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 35ffe0f4ece7..2adc1527e0eb 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -50,10 +50,6 @@ ifeq ($(CONFIG_ARCH_AT91RM9200),y)
 OBJS		+= head-at91rm9200.o
 endif
 
-ifeq ($(CONFIG_DEBUG_ICEDCC),y)
-OBJS            += ice-dcc.o
-endif
-
 ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
 OBJS		+= big-endian.o
 endif
diff --git a/arch/arm/boot/compressed/ice-dcc.S b/arch/arm/boot/compressed/ice-dcc.S
deleted file mode 100644
index 104377a199bb..000000000000
--- a/arch/arm/boot/compressed/ice-dcc.S
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-	.text
-
-	.global	icedcc_putc
-
-icedcc_putc:
-	mov	r2, #0x4000000
-1:
-	subs	r2, r2, #1
-	movlt	pc, r14
-	mrc	p14, 0, r1, c0, c0, 0
-	tst	r1, #2
-	bne	1b
-
-	mcr	p14, 0, r0, c1, c0, 0
-	mov	pc, r14
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index 5ab94584baee..0af3772efcb7 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -20,24 +20,45 @@ unsigned int __machine_arch_type;
 
 #include <linux/string.h>
 
-#include <asm/arch/uncompress.h>
-
 #ifdef STANDALONE_DEBUG
 #define putstr printf
-#endif
+#else
+
+static void putstr(const char *ptr);
+
+#include <linux/compiler.h>
+#include <asm/arch/uncompress.h>
 
 #ifdef CONFIG_DEBUG_ICEDCC
-#define putstr icedcc_putstr
-#define putc icedcc_putc
+static void icedcc_putc(int ch)
+{
+	int status, i = 0x4000000;
 
-extern void icedcc_putc(int ch);
+	do {
+		if (--i < 0)
+			return;
 
-static void
-icedcc_putstr(const char *ptr)
+		asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (status));
+	} while (status & 2);
+
+	asm("mcr p15, 0, %0, c1, c0, 0" : : "r" (ch));
+}
+
+#define putc(ch)	icedcc_putc(ch)
+#define flush()	do { } while (0)
+#endif
+
+static void putstr(const char *ptr)
 {
-	for (; *ptr != '\0'; ptr++) {
-		icedcc_putc(*ptr);
+	char c;
+
+	while ((c = *ptr++) != '\0') {
+		if (c == '\n')
+			putc('\r');
+		putc(c);
 	}
+
+	flush();
 }
 
 #endif
diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c
index e851d86c212c..35c9a64ac14c 100644
--- a/arch/arm/common/rtctime.c
+++ b/arch/arm/common/rtctime.c
@@ -20,6 +20,7 @@
 #include <linux/capability.h>
 #include <linux/device.h>
 #include <linux/mutex.h>
+#include <linux/rtc.h>
 
 #include <asm/rtc.h>
 #include <asm/semaphore.h>
@@ -42,89 +43,6 @@ static struct rtc_ops *rtc_ops;
 
 #define rtc_epoch 1900UL
 
-static const unsigned char days_in_month[] = {
-	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-};
-
-#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
-#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400))
-
-static int month_days(unsigned int month, unsigned int year)
-{
-	return days_in_month[month] + (LEAP_YEAR(year) && month == 1);
-}
-
-/*
- * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
- */
-void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
-{
-	int days, month, year;
-
-	days = time / 86400;
-	time -= days * 86400;
-
-	tm->tm_wday = (days + 4) % 7;
-
-	year = 1970 + days / 365;
-	days -= (year - 1970) * 365
-	        + LEAPS_THRU_END_OF(year - 1)
-	        - LEAPS_THRU_END_OF(1970 - 1);
-	if (days < 0) {
-		year -= 1;
-		days += 365 + LEAP_YEAR(year);
-	}
-	tm->tm_year = year - 1900;
-	tm->tm_yday = days + 1;
-
-	for (month = 0; month < 11; month++) {
-		int newdays;
-
-		newdays = days - month_days(month, year);
-		if (newdays < 0)
-			break;
-		days = newdays;
-	}
-	tm->tm_mon = month;
-	tm->tm_mday = days + 1;
-
-	tm->tm_hour = time / 3600;
-	time -= tm->tm_hour * 3600;
-	tm->tm_min = time / 60;
-	tm->tm_sec = time - tm->tm_min * 60;
-}
-EXPORT_SYMBOL(rtc_time_to_tm);
-
-/*
- * Does the rtc_time represent a valid date/time?
- */
-int rtc_valid_tm(struct rtc_time *tm)
-{
-	if (tm->tm_year < 70 ||
-	    tm->tm_mon >= 12 ||
-	    tm->tm_mday < 1 ||
-	    tm->tm_mday > month_days(tm->tm_mon, tm->tm_year + 1900) ||
-	    tm->tm_hour >= 24 ||
-	    tm->tm_min >= 60 ||
-	    tm->tm_sec >= 60)
-		return -EINVAL;
-
-	return 0;
-}
-EXPORT_SYMBOL(rtc_valid_tm);
-
-/*
- * Convert Gregorian date to seconds since 01-01-1970 00:00:00.
- */
-int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
-{
-	*time = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
-		       tm->tm_hour, tm->tm_min, tm->tm_sec);
-
-	return 0;
-}
-EXPORT_SYMBOL(rtc_tm_to_time);
-
 /*
  * Calculate the next alarm time given the requested alarm time mask
  * and the current time.
@@ -151,13 +69,13 @@ void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc
 	}
 }
 
-static inline int rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm)
+static inline int rtc_arm_read_time(struct rtc_ops *ops, struct rtc_time *tm)
 {
 	memset(tm, 0, sizeof(struct rtc_time));
 	return ops->read_time(tm);
 }
 
-static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm)
+static inline int rtc_arm_set_time(struct rtc_ops *ops, struct rtc_time *tm)
 {
 	int ret;
 
@@ -168,7 +86,7 @@ static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm)
 	return ret;
 }
 
-static inline int rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
+static inline int rtc_arm_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
 {
 	int ret = -EINVAL;
 	if (ops->read_alarm) {
@@ -178,7 +96,7 @@ static inline int rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
 	return ret;
 }
 
-static inline int rtc_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
+static inline int rtc_arm_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
 {
 	int ret = -EINVAL;
 	if (ops->set_alarm)
@@ -266,7 +184,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 
 	switch (cmd) {
 	case RTC_ALM_READ:
-		ret = rtc_read_alarm(ops, &alrm);
+		ret = rtc_arm_read_alarm(ops, &alrm);
 		if (ret)
 			break;
 		ret = copy_to_user(uarg, &alrm.time, sizeof(tm));
@@ -288,11 +206,11 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 		alrm.time.tm_wday = -1;
 		alrm.time.tm_yday = -1;
 		alrm.time.tm_isdst = -1;
-		ret = rtc_set_alarm(ops, &alrm);
+		ret = rtc_arm_set_alarm(ops, &alrm);
 		break;
 
 	case RTC_RD_TIME:
-		ret = rtc_read_time(ops, &tm);
+		ret = rtc_arm_read_time(ops, &tm);
 		if (ret)
 			break;
 		ret = copy_to_user(uarg, &tm, sizeof(tm));
@@ -310,7 +228,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 			ret = -EFAULT;
 			break;
 		}
-		ret = rtc_set_time(ops, &tm);
+		ret = rtc_arm_set_time(ops, &tm);
 		break;
 
 	case RTC_EPOCH_SET:
@@ -341,11 +259,11 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 			ret = -EFAULT;
 			break;
 		}
-		ret = rtc_set_alarm(ops, &alrm);
+		ret = rtc_arm_set_alarm(ops, &alrm);
 		break;
 
 	case RTC_WKALM_RD:
-		ret = rtc_read_alarm(ops, &alrm);
+		ret = rtc_arm_read_alarm(ops, &alrm);
 		if (ret)
 			break;
 		ret = copy_to_user(uarg, &alrm, sizeof(alrm));
@@ -435,7 +353,7 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo
 	struct rtc_time tm;
 	char *p = page;
 
-	if (rtc_read_time(ops, &tm) == 0) {
+	if (rtc_arm_read_time(ops, &tm) == 0) {
 		p += sprintf(p,
 			"rtc_time\t: %02d:%02d:%02d\n"
 			"rtc_date\t: %04d-%02d-%02d\n"
@@ -445,7 +363,7 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo
 			rtc_epoch);
 	}
 
-	if (rtc_read_alarm(ops, &alrm) == 0) {
+	if (rtc_arm_read_alarm(ops, &alrm) == 0) {
 		p += sprintf(p, "alrm_time\t: ");
 		if ((unsigned int)alrm.time.tm_hour <= 24)
 			p += sprintf(p, "%02d:", alrm.time.tm_hour);
diff --git a/arch/arm/configs/ixp23xx_defconfig b/arch/arm/configs/ixp23xx_defconfig
new file mode 100644
index 000000000000..1a2751e9ab05
--- /dev/null
+++ b/arch/arm/configs/ixp23xx_defconfig
@@ -0,0 +1,1302 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.16
+# Tue Mar 21 03:27:20 2006
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP3XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+CONFIG_ARCH_IXP23XX=y
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_AT91RM9200 is not set
+CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
+
+#
+# Intel IXP23xx Implementation Options
+#
+
+#
+# IXP23xx Platforms
+#
+CONFIG_MACH_ESPRESSO=y
+CONFIG_MACH_IXDP2351=y
+CONFIG_MACH_ROADRUNNER=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSC3=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_IO_36=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+CONFIG_CPU_BIG_ENDIAN=y
+
+#
+# Bus support
+#
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+# CONFIG_APM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
+CONFIG_MTD_REDBOOT_PARTS_READONLY=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x0
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=1
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+CONFIG_BLK_DEV_SIIMAGE=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+CONFIG_WAN=y
+# CONFIG_DSCC4 is not set
+# CONFIG_LANMEDIA is not set
+# CONFIG_SYNCLINK_SYNCPPP is not set
+CONFIG_HDLC=y
+CONFIG_HDLC_RAW=y
+# CONFIG_HDLC_RAW_ETH is not set
+CONFIG_HDLC_CISCO=y
+CONFIG_HDLC_FR=y
+CONFIG_HDLC_PPP=y
+
+#
+# X.25/LAPB support is disabled
+#
+# CONFIG_PCI200SYN is not set
+# CONFIG_WANXL is not set
+# CONFIG_PC300 is not set
+# CONFIG_FARSYNC is not set
+CONFIG_DLCI=y
+CONFIG_DLCI_COUNT=24
+CONFIG_DLCI_MAX=8
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+CONFIG_SENSORS_EEPROM=y
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=y
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+# CONFIG_VFAT_FS is not set
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 391f3ab3ff32..7b726b627ea5 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -18,7 +18,7 @@ lib-y		:= backtrace.o changebit.o csumipv6.o csumpartial.o   \
 
 # the code in uaccess.S is not preemption safe and
 # probably faster on ARMv3 only
-ifeq ($CONFIG_PREEMPT,y)
+ifeq ($(CONFIG_PREEMPT),y)
   lib-y	+= copy_from_user.o copy_to_user.o
 else
 ifneq ($(CONFIG_CPU_32v3),y)
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S
index 838e435e4922..cab355c0c1f7 100644
--- a/arch/arm/lib/copy_template.S
+++ b/arch/arm/lib/copy_template.S
@@ -236,7 +236,7 @@
 
 
 /*
- * Abort preanble and completion macros.
+ * Abort preamble and completion macros.
  * If a fixup handler is required then those macros must surround it.
  * It is assumed that the fixup code will handle the private part of
  * the exit macro.
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 865427bfad7e..2d892e4daa07 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -30,7 +30,9 @@
 #include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/delay.h>
+#include <linux/termios.h>
 #include <linux/amba/bus.h>
+#include <linux/amba/serial.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
@@ -360,6 +362,68 @@ void __init ep93xx_init_irq(void)
 /*************************************************************************
  * EP93xx peripheral handling
  *************************************************************************/
+#define EP93XX_UART_MCR_OFFSET		(0x0100)
+
+static void ep93xx_uart_set_mctrl(struct amba_device *dev,
+				  void __iomem *base, unsigned int mctrl)
+{
+	unsigned int mcr;
+
+	mcr = 0;
+	if (!(mctrl & TIOCM_RTS))
+		mcr |= 2;
+	if (!(mctrl & TIOCM_DTR))
+		mcr |= 1;
+
+	__raw_writel(mcr, base + EP93XX_UART_MCR_OFFSET);
+}
+
+static struct amba_pl010_data ep93xx_uart_data = {
+	.set_mctrl	= ep93xx_uart_set_mctrl,
+};
+
+static struct amba_device uart1_device = {
+	.dev		= {
+		.bus_id		= "apb:uart1",
+		.platform_data	= &ep93xx_uart_data,
+	},
+	.res		= {
+		.start	= EP93XX_UART1_PHYS_BASE,
+		.end	= EP93XX_UART1_PHYS_BASE + 0x0fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	.irq		= { IRQ_EP93XX_UART1, NO_IRQ },
+	.periphid	= 0x00041010,
+};
+
+static struct amba_device uart2_device = {
+	.dev		= {
+		.bus_id		= "apb:uart2",
+		.platform_data	= &ep93xx_uart_data,
+	},
+	.res		= {
+		.start	= EP93XX_UART2_PHYS_BASE,
+		.end	= EP93XX_UART2_PHYS_BASE + 0x0fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	.irq		= { IRQ_EP93XX_UART2, NO_IRQ },
+	.periphid	= 0x00041010,
+};
+
+static struct amba_device uart3_device = {
+	.dev		= {
+		.bus_id		= "apb:uart3",
+		.platform_data	= &ep93xx_uart_data,
+	},
+	.res		= {
+		.start	= EP93XX_UART3_PHYS_BASE,
+		.end	= EP93XX_UART3_PHYS_BASE + 0x0fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	.irq		= { IRQ_EP93XX_UART3, NO_IRQ },
+	.periphid	= 0x00041010,
+};
+
 void __init ep93xx_init_devices(void)
 {
 	unsigned int v;
@@ -371,4 +435,8 @@ void __init ep93xx_init_devices(void)
 	v &= ~EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE;
 	__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
 	__raw_writel(v, EP93XX_SYSCON_DEVICE_CONFIG);
+
+	amba_device_register(&uart1_device, &iomem_resource);
+	amba_device_register(&uart2_device, &iomem_resource);
+	amba_device_register(&uart3_device, &iomem_resource);
 }
diff --git a/arch/arm/mach-footbridge/time.c b/arch/arm/mach-footbridge/time.c
index 2c64a0b0502e..5d02e95dede3 100644
--- a/arch/arm/mach-footbridge/time.c
+++ b/arch/arm/mach-footbridge/time.c
@@ -34,27 +34,12 @@ static int rtc_base;
 static unsigned long __init get_isa_cmos_time(void)
 {
 	unsigned int year, mon, day, hour, min, sec;
-	int i;
 
 	// check to see if the RTC makes sense.....
 	if ((CMOS_READ(RTC_VALID) & RTC_VRT) == 0)
 		return mktime(1970, 1, 1, 0, 0, 0);
 
-	/* The Linux interpretation of the CMOS clock register contents:
-	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
-	 * RTC registers show the second which has precisely just started.
-	 * Let's hope other operating systems interpret the RTC the same way.
-	 */
-	/* read RTC exactly on falling edge of update flag */
-	for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
-		if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
-			break;
-
-	for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
-		if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
-			break;
-
-	do { /* Isn't this overkill ? UIP above should guarantee consistency */
+	do {
 		sec  = CMOS_READ(RTC_SECONDS);
 		min  = CMOS_READ(RTC_MINUTES);
 		hour = CMOS_READ(RTC_HOURS);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 20071a2767cc..576a5e979c00 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -15,7 +15,9 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
+#include <linux/termios.h>
 #include <linux/amba/bus.h>
+#include <linux/amba/serial.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
@@ -28,6 +30,8 @@
 
 #include "common.h"
 
+static struct amba_pl010_data integrator_uart_data;
+
 static struct amba_device rtc_device = {
 	.dev		= {
 		.bus_id	= "mb:15",
@@ -44,6 +48,7 @@ static struct amba_device rtc_device = {
 static struct amba_device uart0_device = {
 	.dev		= {
 		.bus_id	= "mb:16",
+		.platform_data = &integrator_uart_data,
 	},
 	.res		= {
 		.start	= INTEGRATOR_UART0_BASE,
@@ -57,6 +62,7 @@ static struct amba_device uart0_device = {
 static struct amba_device uart1_device = {
 	.dev		= {
 		.bus_id	= "mb:17",
+		.platform_data = &integrator_uart_data,
 	},
 	.res		= {
 		.start	= INTEGRATOR_UART1_BASE,
@@ -115,6 +121,46 @@ static int __init integrator_init(void)
 
 arch_initcall(integrator_init);
 
+/*
+ * On the Integrator platform, the port RTS and DTR are provided by
+ * bits in the following SC_CTRLS register bits:
+ *        RTS  DTR
+ *  UART0  7    6
+ *  UART1  5    4
+ */
+#define SC_CTRLC	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
+#define SC_CTRLS	(IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
+
+static void integrator_uart_set_mctrl(struct amba_device *dev, void __iomem *base, unsigned int mctrl)
+{
+	unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask;
+
+	if (dev == &uart0_device) {
+		rts_mask = 1 << 4;
+		dtr_mask = 1 << 5;
+	} else {
+		rts_mask = 1 << 6;
+		dtr_mask = 1 << 7;
+	}
+
+	if (mctrl & TIOCM_RTS)
+		ctrlc |= rts_mask;
+	else
+		ctrls |= rts_mask;
+
+	if (mctrl & TIOCM_DTR)
+		ctrlc |= dtr_mask;
+	else
+		ctrls |= dtr_mask;
+
+	__raw_writel(ctrls, SC_CTRLS);
+	__raw_writel(ctrlc, SC_CTRLC);
+}
+
+static struct amba_pl010_data integrator_uart_data = {
+	.set_mctrl = integrator_uart_set_mctrl,
+};
+
 #define CM_CTRL	IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_CTRL_OFFSET
 
 static DEFINE_SPINLOCK(cm_lock);
diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c
index 3c22c16b38bf..bc07f52a6fd7 100644
--- a/arch/arm/mach-integrator/time.c
+++ b/arch/arm/mach-integrator/time.c
@@ -40,13 +40,13 @@ static int integrator_set_rtc(void)
 	return 1;
 }
 
-static int rtc_read_alarm(struct rtc_wkalrm *alrm)
+static int integrator_rtc_read_alarm(struct rtc_wkalrm *alrm)
 {
 	rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time);
 	return 0;
 }
 
-static inline int rtc_set_alarm(struct rtc_wkalrm *alrm)
+static inline int integrator_rtc_set_alarm(struct rtc_wkalrm *alrm)
 {
 	unsigned long time;
 	int ret;
@@ -62,7 +62,7 @@ static inline int rtc_set_alarm(struct rtc_wkalrm *alrm)
 	return ret;
 }
 
-static int rtc_read_time(struct rtc_time *tm)
+static int integrator_rtc_read_time(struct rtc_time *tm)
 {
 	rtc_time_to_tm(readl(rtc_base + RTC_DR), tm);
 	return 0;
@@ -76,7 +76,7 @@ static int rtc_read_time(struct rtc_time *tm)
  * edge of the 1Hz clock, we must write the time one second
  * in advance.
  */
-static inline int rtc_set_time(struct rtc_time *tm)
+static inline int integrator_rtc_set_time(struct rtc_time *tm)
 {
 	unsigned long time;
 	int ret;
@@ -90,10 +90,10 @@ static inline int rtc_set_time(struct rtc_time *tm)
 
 static struct rtc_ops rtc_ops = {
 	.owner		= THIS_MODULE,
-	.read_time	= rtc_read_time,
-	.set_time	= rtc_set_time,
-	.read_alarm	= rtc_read_alarm,
-	.set_alarm	= rtc_set_alarm,
+	.read_time	= integrator_rtc_read_time,
+	.set_time	= integrator_rtc_set_time,
+	.read_alarm	= integrator_rtc_read_alarm,
+	.set_alarm	= integrator_rtc_set_alarm,
 };
 
 static irqreturn_t arm_rtc_interrupt(int irq, void *dev_id,
diff --git a/arch/arm/mach-ixp23xx/Kconfig b/arch/arm/mach-ixp23xx/Kconfig
new file mode 100644
index 000000000000..982670ec3866
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/Kconfig
@@ -0,0 +1,25 @@
+if ARCH_IXP23XX
+
+config ARCH_SUPPORTS_BIG_ENDIAN
+	bool
+	default y
+
+menu "Intel IXP23xx Implementation Options"
+
+comment "IXP23xx Platforms"
+
+config MACH_ESPRESSO
+	bool "Support IP Fabrics Double Espresso platform"
+	help
+
+config MACH_IXDP2351
+	bool "Support Intel IXDP2351 platform"
+	help
+
+config MACH_ROADRUNNER
+	bool "Support ADI RoadRunner platform"
+	help
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-ixp23xx/Makefile b/arch/arm/mach-ixp23xx/Makefile
new file mode 100644
index 000000000000..288b371b6d03
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the linux kernel.
+#
+obj-y			:= core.o pci.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+obj-$(CONFIG_MACH_ESPRESSO)	+= espresso.o
+obj-$(CONFIG_MACH_IXDP2351)	+= ixdp2351.o
+obj-$(CONFIG_MACH_ROADRUNNER)	+= roadrunner.o
diff --git a/arch/arm/mach-ixp23xx/Makefile.boot b/arch/arm/mach-ixp23xx/Makefile.boot
new file mode 100644
index 000000000000..d5561ad15bad
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/Makefile.boot
@@ -0,0 +1,2 @@
+   zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c
new file mode 100644
index 000000000000..092ee12ced42
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/core.c
@@ -0,0 +1,431 @@
+/*
+ * arch/arm/mach-ixp23xx/core.c
+ *
+ * Core routines for IXP23xx chips
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2005 (c) MontaVista Software, Inc.
+ *
+ * Based on 2.4 code Copyright 2004 (c) Intel Corporation
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/bitops.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/tlbflush.h>
+#include <asm/pgtable.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+
+
+/*************************************************************************
+ * Chip specific mappings shared by all IXP23xx systems
+ *************************************************************************/
+static struct map_desc ixp23xx_io_desc[] __initdata = {
+	{ /* XSI-CPP CSRs */
+	 	.virtual	= IXP23XX_XSI2CPP_CSR_VIRT,
+	 	.pfn		= __phys_to_pfn(IXP23XX_XSI2CPP_CSR_PHYS),
+	 	.length		= IXP23XX_XSI2CPP_CSR_SIZE,
+		.type		= MT_DEVICE,
+	}, { /* Expansion Bus Config */
+	 	.virtual	= IXP23XX_EXP_CFG_VIRT,
+	 	.pfn		= __phys_to_pfn(IXP23XX_EXP_CFG_PHYS),
+	 	.length		= IXP23XX_EXP_CFG_SIZE,
+		.type		= MT_DEVICE,
+	}, { /* UART, Interrupt ctrl, GPIO, timers, NPEs, MACS,.... */
+	 	.virtual	= IXP23XX_PERIPHERAL_VIRT,
+	 	.pfn		= __phys_to_pfn(IXP23XX_PERIPHERAL_PHYS),
+	 	.length		= IXP23XX_PERIPHERAL_SIZE,
+		.type		= MT_DEVICE,
+	}, { /* CAP CSRs */
+	 	.virtual	= IXP23XX_CAP_CSR_VIRT,
+	 	.pfn		= __phys_to_pfn(IXP23XX_CAP_CSR_PHYS),
+	 	.length		= IXP23XX_CAP_CSR_SIZE,
+		.type		= MT_DEVICE,
+	}, { /* MSF CSRs */
+	 	.virtual	= IXP23XX_MSF_CSR_VIRT,
+	 	.pfn		= __phys_to_pfn(IXP23XX_MSF_CSR_PHYS),
+	 	.length		= IXP23XX_MSF_CSR_SIZE,
+		.type		= MT_DEVICE,
+	}, { /* PCI I/O Space */
+	 	.virtual	= IXP23XX_PCI_IO_VIRT,
+	 	.pfn		= __phys_to_pfn(IXP23XX_PCI_IO_PHYS),
+	 	.length		= IXP23XX_PCI_IO_SIZE,
+		.type		= MT_DEVICE,
+	}, { /* PCI Config Space */
+	 	.virtual	= IXP23XX_PCI_CFG_VIRT,
+	 	.pfn		= __phys_to_pfn(IXP23XX_PCI_CFG_PHYS),
+	 	.length		= IXP23XX_PCI_CFG_SIZE,
+		.type		= MT_DEVICE,
+	}, { /* PCI local CFG CSRs */
+	 	.virtual	= IXP23XX_PCI_CREG_VIRT,
+	 	.pfn		= __phys_to_pfn(IXP23XX_PCI_CREG_PHYS),
+	 	.length		= IXP23XX_PCI_CREG_SIZE,
+		.type		= MT_DEVICE,
+	}, { /* PCI MEM Space */
+	 	.virtual	= IXP23XX_PCI_MEM_VIRT,
+	 	.pfn		= __phys_to_pfn(IXP23XX_PCI_MEM_PHYS),
+	 	.length		= IXP23XX_PCI_MEM_SIZE,
+		.type		= MT_DEVICE,
+	}
+};
+
+void __init ixp23xx_map_io(void)
+{
+	iotable_init(ixp23xx_io_desc, ARRAY_SIZE(ixp23xx_io_desc));
+}
+
+
+/***************************************************************************
+ * IXP23xx Interrupt Handling
+ ***************************************************************************/
+enum ixp23xx_irq_type {
+	IXP23XX_IRQ_LEVEL, IXP23XX_IRQ_EDGE
+};
+
+static void ixp23xx_config_irq(unsigned int, enum ixp23xx_irq_type);
+
+static int ixp23xx_irq_set_type(unsigned int irq, unsigned int type)
+{
+	int line = irq - IRQ_IXP23XX_GPIO6 + 6;
+	u32 int_style;
+	enum ixp23xx_irq_type irq_type;
+	volatile u32 *int_reg;
+
+	/*
+	 * Only GPIOs 6-15 are wired to interrupts on IXP23xx
+	 */
+	if (line < 6 || line > 15)
+		return -EINVAL;
+
+	switch (type) {
+	case IRQT_BOTHEDGE:
+		int_style = IXP23XX_GPIO_STYLE_TRANSITIONAL;
+		irq_type = IXP23XX_IRQ_EDGE;
+		break;
+	case IRQT_RISING:
+		int_style = IXP23XX_GPIO_STYLE_RISING_EDGE;
+		irq_type = IXP23XX_IRQ_EDGE;
+		break;
+	case IRQT_FALLING:
+		int_style = IXP23XX_GPIO_STYLE_FALLING_EDGE;
+		irq_type = IXP23XX_IRQ_EDGE;
+		break;
+	case IRQT_HIGH:
+		int_style = IXP23XX_GPIO_STYLE_ACTIVE_HIGH;
+		irq_type = IXP23XX_IRQ_LEVEL;
+		break;
+	case IRQT_LOW:
+		int_style = IXP23XX_GPIO_STYLE_ACTIVE_LOW;
+		irq_type = IXP23XX_IRQ_LEVEL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ixp23xx_config_irq(irq, irq_type);
+
+	if (line >= 8) {	/* pins 8-15 */
+		line -= 8;
+		int_reg = (volatile u32 *)IXP23XX_GPIO_GPIT2R;
+	} else {		/* pins 0-7 */
+		int_reg = (volatile u32 *)IXP23XX_GPIO_GPIT1R;
+	}
+
+	/*
+	 * Clear pending interrupts
+	 */
+	*IXP23XX_GPIO_GPISR = (1 << line);
+
+	/* Clear the style for the appropriate pin */
+	*int_reg &= ~(IXP23XX_GPIO_STYLE_MASK <<
+			(line * IXP23XX_GPIO_STYLE_SIZE));
+
+	/* Set the new style */
+	*int_reg |= (int_style << (line * IXP23XX_GPIO_STYLE_SIZE));
+
+	return 0;
+}
+
+static void ixp23xx_irq_mask(unsigned int irq)
+{
+	volatile unsigned long *intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
+
+	*intr_reg &= ~(1 << (irq % 32));
+}
+
+static void ixp23xx_irq_ack(unsigned int irq)
+{
+	int line = irq - IRQ_IXP23XX_GPIO6 + 6;
+
+	if ((line < 6) || (line > 15))
+		return;
+
+	*IXP23XX_GPIO_GPISR = (1 << line);
+}
+
+/*
+ * Level triggered interrupts on GPIO lines can only be cleared when the
+ * interrupt condition disappears.
+ */
+static void ixp23xx_irq_level_unmask(unsigned int irq)
+{
+	volatile unsigned long *intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
+
+	ixp23xx_irq_ack(irq);
+
+	*intr_reg |= (1 << (irq % 32));
+}
+
+static void ixp23xx_irq_edge_unmask(unsigned int irq)
+{
+	volatile unsigned long *intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
+
+	*intr_reg |= (1 << (irq % 32));
+}
+
+static struct irqchip ixp23xx_irq_level_chip = {
+	.ack		= ixp23xx_irq_mask,
+	.mask		= ixp23xx_irq_mask,
+	.unmask		= ixp23xx_irq_level_unmask,
+	.set_type	= ixp23xx_irq_set_type
+};
+
+static struct irqchip ixp23xx_irq_edge_chip = {
+	.ack		= ixp23xx_irq_ack,
+	.mask		= ixp23xx_irq_mask,
+	.unmask		= ixp23xx_irq_edge_unmask,
+	.set_type	= ixp23xx_irq_set_type
+};
+
+static void ixp23xx_pci_irq_mask(unsigned int irq)
+{
+	*IXP23XX_PCI_XSCALE_INT_ENABLE &= ~(1 << (IRQ_IXP23XX_INTA + 27 - irq));
+}
+
+static void ixp23xx_pci_irq_unmask(unsigned int irq)
+{
+	*IXP23XX_PCI_XSCALE_INT_ENABLE |= (1 << (IRQ_IXP23XX_INTA + 27 - irq));
+}
+
+/*
+ * TODO: Should this just be done at ASM level?
+ */
+static void pci_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+{
+	u32 pci_interrupt;
+	unsigned int irqno;
+	struct irqdesc *int_desc;
+
+	pci_interrupt = *IXP23XX_PCI_XSCALE_INT_STATUS;
+
+	desc->chip->ack(irq);
+
+	/* See which PCI_INTA, or PCI_INTB interrupted */
+	if (pci_interrupt & (1 << 26)) {
+		irqno = IRQ_IXP23XX_INTB;
+	} else if (pci_interrupt & (1 << 27)) {
+		irqno = IRQ_IXP23XX_INTA;
+	} else {
+		BUG();
+	}
+
+	int_desc = irq_desc + irqno;
+	int_desc->handle(irqno, int_desc, regs);
+
+	desc->chip->unmask(irq);
+}
+
+static struct irqchip ixp23xx_pci_irq_chip = {
+	.ack	= ixp23xx_pci_irq_mask,
+	.mask	= ixp23xx_pci_irq_mask,
+	.unmask	= ixp23xx_pci_irq_unmask
+};
+
+static void ixp23xx_config_irq(unsigned int irq, enum ixp23xx_irq_type type)
+{
+	switch (type) {
+	case IXP23XX_IRQ_LEVEL:
+		set_irq_chip(irq, &ixp23xx_irq_level_chip);
+		set_irq_handler(irq, do_level_IRQ);
+		break;
+	case IXP23XX_IRQ_EDGE:
+		set_irq_chip(irq, &ixp23xx_irq_edge_chip);
+		set_irq_handler(irq, do_edge_IRQ);
+		break;
+	}
+	set_irq_flags(irq, IRQF_VALID);
+}
+
+void __init ixp23xx_init_irq(void)
+{
+	int irq;
+
+	/* Route everything to IRQ */
+	*IXP23XX_INTR_SEL1 = 0x0;
+	*IXP23XX_INTR_SEL2 = 0x0;
+	*IXP23XX_INTR_SEL3 = 0x0;
+	*IXP23XX_INTR_SEL4 = 0x0;
+
+	/* Mask all sources */
+	*IXP23XX_INTR_EN1 = 0x0;
+	*IXP23XX_INTR_EN2 = 0x0;
+	*IXP23XX_INTR_EN3 = 0x0;
+	*IXP23XX_INTR_EN4 = 0x0;
+
+	/*
+	 * Configure all IRQs for level-sensitive operation
+	 */
+	for (irq = 0; irq <= NUM_IXP23XX_RAW_IRQS; irq++) {
+		ixp23xx_config_irq(irq, IXP23XX_IRQ_LEVEL);
+	}
+
+	for (irq = IRQ_IXP23XX_INTA; irq <= IRQ_IXP23XX_INTB; irq++) {
+		set_irq_chip(irq, &ixp23xx_pci_irq_chip);
+		set_irq_handler(irq, do_level_IRQ);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	set_irq_chained_handler(IRQ_IXP23XX_PCI_INT_RPH, pci_handler);
+}
+
+
+/*************************************************************************
+ * Timer-tick functions for IXP23xx
+ *************************************************************************/
+#define CLOCK_TICKS_PER_USEC	CLOCK_TICK_RATE / (USEC_PER_SEC)
+
+static unsigned long next_jiffy_time;
+
+static unsigned long
+ixp23xx_gettimeoffset(void)
+{
+	unsigned long elapsed;
+
+	elapsed = *IXP23XX_TIMER_CONT - (next_jiffy_time - LATCH);
+
+	return elapsed / CLOCK_TICKS_PER_USEC;
+}
+
+static irqreturn_t
+ixp23xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* Clear Pending Interrupt by writing '1' to it */
+	*IXP23XX_TIMER_STATUS = IXP23XX_TIMER1_INT_PEND;
+	while ((*IXP23XX_TIMER_CONT - next_jiffy_time) > LATCH) {
+		timer_tick(regs);
+		next_jiffy_time += LATCH;
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction ixp23xx_timer_irq = {
+	.name		= "IXP23xx Timer Tick",
+	.handler	= ixp23xx_timer_interrupt,
+	.flags		= SA_INTERRUPT | SA_TIMER,
+};
+
+void __init ixp23xx_init_timer(void)
+{
+	/* Clear Pending Interrupt by writing '1' to it */
+	*IXP23XX_TIMER_STATUS = IXP23XX_TIMER1_INT_PEND;
+
+	/* Setup the Timer counter value */
+	*IXP23XX_TIMER1_RELOAD =
+		(LATCH & ~IXP23XX_TIMER_RELOAD_MASK) | IXP23XX_TIMER_ENABLE;
+
+	*IXP23XX_TIMER_CONT = 0;
+	next_jiffy_time = LATCH;
+
+	/* Connect the interrupt handler and enable the interrupt */
+	setup_irq(IRQ_IXP23XX_TIMER1, &ixp23xx_timer_irq);
+}
+
+struct sys_timer ixp23xx_timer = {
+	.init		= ixp23xx_init_timer,
+	.offset		= ixp23xx_gettimeoffset,
+};
+
+
+/*************************************************************************
+ * IXP23xx Platform Initializaion
+ *************************************************************************/
+static struct resource ixp23xx_uart_resources[] = {
+	{
+		.start		= IXP23XX_UART1_PHYS,
+		.end		= IXP23XX_UART1_PHYS + 0x0fff,
+		.flags		= IORESOURCE_MEM
+	}, {
+		.start		= IXP23XX_UART2_PHYS,
+		.end		= IXP23XX_UART2_PHYS + 0x0fff,
+		.flags		= IORESOURCE_MEM
+	}
+};
+
+static struct plat_serial8250_port ixp23xx_uart_data[] = {
+	{
+		.mapbase	= IXP23XX_UART1_PHYS,
+		.membase	= (char *)(IXP23XX_UART1_VIRT + 3),
+		.irq		= IRQ_IXP23XX_UART1,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= IXP23XX_UART_XTAL,
+	}, {
+		.mapbase	= IXP23XX_UART2_PHYS,
+		.membase	= (char *)(IXP23XX_UART2_VIRT + 3),
+		.irq		= IRQ_IXP23XX_UART2,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= IXP23XX_UART_XTAL,
+	},
+	{ },
+};
+
+static struct platform_device ixp23xx_uart = {
+	.name			= "serial8250",
+	.id			= 0,
+	.dev.platform_data	= ixp23xx_uart_data,
+	.num_resources		= 2,
+	.resource		= ixp23xx_uart_resources,
+};
+
+static struct platform_device *ixp23xx_devices[] __initdata = {
+	&ixp23xx_uart,
+};
+
+void __init ixp23xx_sys_init(void)
+{
+	platform_add_devices(ixp23xx_devices, ARRAY_SIZE(ixp23xx_devices));
+}
diff --git a/arch/arm/mach-ixp23xx/espresso.c b/arch/arm/mach-ixp23xx/espresso.c
new file mode 100644
index 000000000000..2327c9790416
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/espresso.c
@@ -0,0 +1,69 @@
+/*
+ * arch/arm/mach-ixp23xx/espresso.c
+ *
+ * Double Espresso-specific routines
+ *
+ * Author: Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/bitops.h>
+#include <linux/ioport.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/tlbflush.h>
+#include <asm/pgtable.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/pci.h>
+
+static void __init espresso_init(void)
+{
+	physmap_configure(0x90000000, 0x02000000, 2, NULL);
+
+	/*
+	 * Mark flash as writeable.
+	 */
+	IXP23XX_EXP_CS0[0] |= IXP23XX_FLASH_WRITABLE;
+	IXP23XX_EXP_CS0[1] |= IXP23XX_FLASH_WRITABLE;
+
+	ixp23xx_sys_init();
+}
+
+MACHINE_START(ESPRESSO, "IP Fabrics Double Espresso")
+	/* Maintainer: Lennert Buytenhek */
+	.phys_io	= IXP23XX_PERIPHERAL_PHYS,
+	.io_pg_offst	= ((IXP23XX_PERIPHERAL_VIRT >> 18)) & 0xfffc,
+	.map_io		= ixp23xx_map_io,
+	.init_irq	= ixp23xx_init_irq,
+	.timer		= &ixp23xx_timer,
+	.boot_params	= 0x00000100,
+	.init_machine	= espresso_init,
+MACHINE_END
diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c
new file mode 100644
index 000000000000..00146c35daac
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/ixdp2351.c
@@ -0,0 +1,325 @@
+/*
+ * arch/arm/mach-ixp23xx/ixdp2351.c
+ *
+ * IXDP2351 board-specific routines
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2005 (c) MontaVista Software, Inc.
+ *
+ * Based on 2.4 code Copyright 2004 (c) Intel Corporation
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/bitops.h>
+#include <linux/ioport.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/tlbflush.h>
+#include <asm/pgtable.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/pci.h>
+
+/*
+ * IXDP2351 Interrupt Handling
+ */
+static void ixdp2351_inta_mask(unsigned int irq)
+{
+	*IXDP2351_CPLD_INTA_MASK_SET_REG = IXDP2351_INTA_IRQ_MASK(irq);
+}
+
+static void ixdp2351_inta_unmask(unsigned int irq)
+{
+	*IXDP2351_CPLD_INTA_MASK_CLR_REG = IXDP2351_INTA_IRQ_MASK(irq);
+}
+
+static void ixdp2351_inta_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+{
+	u16 ex_interrupt =
+		*IXDP2351_CPLD_INTA_STAT_REG & IXDP2351_INTA_IRQ_VALID;
+	int i;
+
+	desc->chip->mask(irq);
+
+	for (i = 0; i < IXDP2351_INTA_IRQ_NUM; i++) {
+		if (ex_interrupt & (1 << i)) {
+			struct irqdesc *cpld_desc;
+			int cpld_irq =
+				IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE + i);
+			cpld_desc = irq_desc + cpld_irq;
+			cpld_desc->handle(cpld_irq, cpld_desc, regs);
+		}
+	}
+
+	desc->chip->unmask(irq);
+}
+
+static struct irqchip ixdp2351_inta_chip = {
+	.ack	= ixdp2351_inta_mask,
+	.mask	= ixdp2351_inta_mask,
+	.unmask	= ixdp2351_inta_unmask
+};
+
+static void ixdp2351_intb_mask(unsigned int irq)
+{
+	*IXDP2351_CPLD_INTB_MASK_SET_REG = IXDP2351_INTB_IRQ_MASK(irq);
+}
+
+static void ixdp2351_intb_unmask(unsigned int irq)
+{
+	*IXDP2351_CPLD_INTB_MASK_CLR_REG = IXDP2351_INTB_IRQ_MASK(irq);
+}
+
+static void ixdp2351_intb_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
+{
+	u16 ex_interrupt =
+		*IXDP2351_CPLD_INTB_STAT_REG & IXDP2351_INTB_IRQ_VALID;
+	int i;
+
+	desc->chip->ack(irq);
+
+	for (i = 0; i < IXDP2351_INTB_IRQ_NUM; i++) {
+		if (ex_interrupt & (1 << i)) {
+			struct irqdesc *cpld_desc;
+			int cpld_irq =
+				IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + i);
+			cpld_desc = irq_desc + cpld_irq;
+			cpld_desc->handle(cpld_irq, cpld_desc, regs);
+		}
+	}
+
+	desc->chip->unmask(irq);
+}
+
+static struct irqchip ixdp2351_intb_chip = {
+	.ack	= ixdp2351_intb_mask,
+	.mask	= ixdp2351_intb_mask,
+	.unmask	= ixdp2351_intb_unmask
+};
+
+void ixdp2351_init_irq(void)
+{
+	int irq;
+
+	/* Mask all interrupts from CPLD, disable simulation */
+	*IXDP2351_CPLD_INTA_MASK_SET_REG = (u16) -1;
+	*IXDP2351_CPLD_INTB_MASK_SET_REG = (u16) -1;
+	*IXDP2351_CPLD_INTA_SIM_REG = 0;
+	*IXDP2351_CPLD_INTB_SIM_REG = 0;
+
+	ixp23xx_init_irq();
+
+	for (irq = IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE);
+	     irq <
+	     IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE + IXDP2351_INTA_IRQ_NUM);
+	     irq++) {
+		if (IXDP2351_INTA_IRQ_MASK(irq) & IXDP2351_INTA_IRQ_VALID) {
+			set_irq_flags(irq, IRQF_VALID);
+			set_irq_handler(irq, do_level_IRQ);
+			set_irq_chip(irq, &ixdp2351_inta_chip);
+		}
+	}
+
+	for (irq = IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE);
+	     irq <
+	     IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + IXDP2351_INTB_IRQ_NUM);
+	     irq++) {
+		if (IXDP2351_INTB_IRQ_MASK(irq) & IXDP2351_INTB_IRQ_VALID) {
+			set_irq_flags(irq, IRQF_VALID);
+			set_irq_handler(irq, do_level_IRQ);
+			set_irq_chip(irq, &ixdp2351_intb_chip);
+		}
+	}
+
+	set_irq_chained_handler(IRQ_IXP23XX_INTA, &ixdp2351_inta_handler);
+	set_irq_chained_handler(IRQ_IXP23XX_INTB, &ixdp2351_intb_handler);
+}
+
+/*
+ * IXDP2351 PCI
+ */
+
+/*
+ * This board does not do normal PCI IRQ routing, or any
+ * sort of swizzling, so we just need to check where on the
+ * bus the device is and figure out what CPLD pin it is
+ * being routed to.
+ */
+#define DEVPIN(dev, pin) ((pin) | ((dev) << 3))
+
+static int __init ixdp2351_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	u8 bus = dev->bus->number;
+	u32 devpin = DEVPIN(PCI_SLOT(dev->devfn), pin);
+	struct pci_bus *tmp_bus = dev->bus;
+
+	/* Primary bus, no interrupts here */
+	if (!bus)
+		return -1;
+
+	/* Lookup first leaf in bus tree */
+	while ((tmp_bus->parent != NULL) && (tmp_bus->parent->parent != NULL))
+		tmp_bus = tmp_bus->parent;
+
+	/* Select between known bridges */
+	switch (tmp_bus->self->devfn | (tmp_bus->self->bus->number << 8)) {
+		/* Device is located after first bridge */
+	case 0x0008:
+		if (tmp_bus == dev->bus) {
+			/* Device is located directy after first bridge */
+			switch (devpin) {
+				/* Onboard 82546 */
+			case DEVPIN(1, 1):	/* Onboard 82546 ch 0 */
+				return IRQ_IXDP2351_INTA_82546;
+			case DEVPIN(1, 2):	/* Onboard 82546 ch 1 */
+				return IRQ_IXDP2351_INTB_82546;
+				/* PMC SLOT */
+			case DEVPIN(0, 1):	/* PMCP INTA# */
+			case DEVPIN(2, 4):	/* PMCS INTD# */
+				return IRQ_IXDP2351_SPCI_PMC_INTA;
+			case DEVPIN(0, 2):	/* PMCP INTB# */
+			case DEVPIN(2, 1):	/* PMCS INTA# */
+				return IRQ_IXDP2351_SPCI_PMC_INTB;
+			case DEVPIN(0, 3):	/* PMCP INTC# */
+			case DEVPIN(2, 2):	/* PMCS INTB# */
+				return IRQ_IXDP2351_SPCI_PMC_INTC;
+			case DEVPIN(0, 4):	/* PMCP INTD# */
+			case DEVPIN(2, 3):	/* PMCS INTC# */
+				return IRQ_IXDP2351_SPCI_PMC_INTD;
+			}
+		} else {
+			/* Device is located indirectly after first bridge */
+			/* Not supported now */
+			return -1;
+		}
+		break;
+	case 0x0010:
+		if (tmp_bus == dev->bus) {
+			/* Device is located directy after second bridge */
+			/* Secondary bus of second bridge */
+			switch (devpin) {
+			case DEVPIN(0, 1):	/* DB#0 */
+			case DEVPIN(0, 2):
+			case DEVPIN(0, 3):
+			case DEVPIN(0, 4):
+				return IRQ_IXDP2351_SPCI_DB_0;
+			case DEVPIN(1, 1):	/* DB#1 */
+			case DEVPIN(1, 2):
+			case DEVPIN(1, 3):
+			case DEVPIN(1, 4):
+				return IRQ_IXDP2351_SPCI_DB_1;
+			case DEVPIN(2, 1):	/* FIC1 */
+			case DEVPIN(2, 2):
+			case DEVPIN(2, 3):
+			case DEVPIN(2, 4):
+			case DEVPIN(3, 1):	/* FIC2 */
+			case DEVPIN(3, 2):
+			case DEVPIN(3, 3):
+			case DEVPIN(3, 4):
+				return IRQ_IXDP2351_SPCI_FIC;
+			}
+		} else {
+			/* Device is located indirectly after second bridge */
+			/* Not supported now */
+			return -1;
+		}
+		break;
+	}
+
+	return -1;
+}
+
+struct hw_pci ixdp2351_pci __initdata = {
+	.nr_controllers	= 1,
+	.preinit	= ixp23xx_pci_preinit,
+	.setup		= ixp23xx_pci_setup,
+	.scan		= ixp23xx_pci_scan_bus,
+	.map_irq	= ixdp2351_map_irq,
+};
+
+int __init ixdp2351_pci_init(void)
+{
+	if (machine_is_ixdp2351())
+		pci_common_init(&ixdp2351_pci);
+
+	return 0;
+}
+
+subsys_initcall(ixdp2351_pci_init);
+
+/*
+ * IXDP2351 Static Mapped I/O
+ */
+static struct map_desc ixdp2351_io_desc[] __initdata = {
+	{
+		.virtual	= IXDP2351_NP_VIRT_BASE,
+		.pfn		= __phys_to_pfn((u64)IXDP2351_NP_PHYS_BASE),
+		.length		= IXDP2351_NP_PHYS_SIZE,
+		.type		= MT_DEVICE
+	}, {
+		.virtual	= IXDP2351_BB_BASE_VIRT,
+		.pfn		= __phys_to_pfn((u64)IXDP2351_BB_BASE_PHYS),
+		.length		= IXDP2351_BB_SIZE,
+		.type		= MT_DEVICE
+	}
+};
+
+static void __init ixdp2351_map_io(void)
+{
+	ixp23xx_map_io();
+	iotable_init(ixdp2351_io_desc, ARRAY_SIZE(ixdp2351_io_desc));
+}
+
+static void __init ixdp2351_init(void)
+{
+	physmap_configure(0x90000000, 0x04000000, 1, NULL);
+
+	/*
+	 * Mark flash as writeable
+	 */
+	IXP23XX_EXP_CS0[0] |= IXP23XX_FLASH_WRITABLE;
+	IXP23XX_EXP_CS0[1] |= IXP23XX_FLASH_WRITABLE;
+	IXP23XX_EXP_CS0[2] |= IXP23XX_FLASH_WRITABLE;
+	IXP23XX_EXP_CS0[3] |= IXP23XX_FLASH_WRITABLE;
+
+	ixp23xx_sys_init();
+}
+
+MACHINE_START(IXDP2351, "Intel IXDP2351 Development Platform")
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_io	= IXP23XX_PERIPHERAL_PHYS,
+	.io_pg_offst	= ((IXP23XX_PERIPHERAL_VIRT >> 18)) & 0xfffc,
+	.map_io		= ixdp2351_map_io,
+	.init_irq	= ixdp2351_init_irq,
+	.timer		= &ixp23xx_timer,
+	.boot_params	= 0x00000100,
+	.init_machine	= ixdp2351_init,
+MACHINE_END
diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c
new file mode 100644
index 000000000000..5330ad78c1bb
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/pci.c
@@ -0,0 +1,275 @@
+/*
+ * arch/arm/mach-ixp23xx/pci.c
+ *
+ * PCI routines for IXP23XX based systems
+ *
+ * Copyright (c) 2005 MontaVista Software, Inc.
+ *
+ * based on original code:
+ *
+ * Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ * Copyright 2002-2005 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+
+extern int (*external_fault) (unsigned long, struct pt_regs *);
+
+static int pci_master_aborts = 0;
+
+#ifdef DEBUG
+#define DBG(x...)	printk(x)
+#else
+#define DBG(x...)
+#endif
+
+int clear_master_aborts(void);
+
+static u32
+*ixp23xx_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where)
+{
+	u32 *paddress;
+
+	/*
+	 * Must be dword aligned
+	 */
+	where &= ~3;
+
+	/*
+	 * For top bus, generate type 0, else type 1
+	 */
+	if (!bus_nr) {
+		if (PCI_SLOT(devfn) >= 8)
+			return 0;
+
+		paddress = (u32 *) (IXP23XX_PCI_CFG0_VIRT
+				    | (1 << (PCI_SLOT(devfn) + 16))
+				    | (PCI_FUNC(devfn) << 8) | where);
+	} else {
+		paddress = (u32 *) (IXP23XX_PCI_CFG1_VIRT
+				    | (bus_nr << 16)
+				    | (PCI_SLOT(devfn) << 11)
+				    | (PCI_FUNC(devfn) << 8) | where);
+	}
+
+	return paddress;
+}
+
+/*
+ * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes.
+ * 0 and 3 are not valid indexes...
+ */
+static u32 bytemask[] = {
+	/*0*/	0,
+	/*1*/	0xff,
+	/*2*/	0xffff,
+	/*3*/	0,
+	/*4*/	0xffffffff,
+};
+
+static int ixp23xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
+				int where, int size, u32 *value)
+{
+	u32 n;
+	u32 *addr;
+
+	n = where % 4;
+
+	DBG("In config_read(%d) %d from dev %d:%d:%d\n", size, where,
+		bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
+
+	addr = ixp23xx_pci_config_addr(bus->number, devfn, where);
+	if (!addr)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	pci_master_aborts = 0;
+	*value = (*addr >> (8*n)) & bytemask[size];
+	if (pci_master_aborts) {
+			pci_master_aborts = 0;
+			*value = 0xffffffff;
+			return PCIBIOS_DEVICE_NOT_FOUND;
+		}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * We don't do error checking on the address for writes.
+ * It's assumed that the user checked for the device existing first
+ * by doing a read first.
+ */
+static int ixp23xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
+					int where, int size, u32 value)
+{
+	u32 mask;
+	u32 *addr;
+	u32 temp;
+
+	mask = ~(bytemask[size] << ((where % 0x4) * 8));
+	addr = ixp23xx_pci_config_addr(bus->number, devfn, where);
+	if (!addr)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	temp = (u32) (value) << ((where % 0x4) * 8);
+	*addr = (*addr & mask) | temp;
+
+	clear_master_aborts();
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops ixp23xx_pci_ops = {
+	.read	= ixp23xx_pci_read_config,
+	.write	= ixp23xx_pci_write_config,
+};
+
+struct pci_bus *ixp23xx_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
+{
+	return pci_scan_bus(sysdata->busnr, &ixp23xx_pci_ops, sysdata);
+}
+
+int ixp23xx_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+	volatile unsigned long temp;
+	unsigned long flags;
+
+	pci_master_aborts = 1;
+
+	local_irq_save(flags);
+	temp = *IXP23XX_PCI_CONTROL;
+
+	/*
+	 * master abort and cmd tgt err
+	 */
+	if (temp & ((1 << 8) | (1 << 5)))
+		*IXP23XX_PCI_CONTROL = temp;
+
+	temp = *IXP23XX_PCI_CMDSTAT;
+
+	if (temp & (1 << 29))
+		*IXP23XX_PCI_CMDSTAT = temp;
+	local_irq_restore(flags);
+
+	/*
+	 * If it was an imprecise abort, then we need to correct the
+	 * return address to be _after_ the instruction.
+	 */
+	if (fsr & (1 << 10))
+		regs->ARM_pc += 4;
+
+	return 0;
+}
+
+int clear_master_aborts(void)
+{
+	volatile u32 temp;
+
+	temp = *IXP23XX_PCI_CONTROL;
+
+	/*
+	 * master abort and cmd tgt err
+	 */
+	if (temp & ((1 << 8) | (1 << 5)))
+		*IXP23XX_PCI_CONTROL = temp;
+
+	temp = *IXP23XX_PCI_CMDSTAT;
+
+	if (temp & (1 << 29))
+		*IXP23XX_PCI_CMDSTAT = temp;
+
+	return 0;
+}
+
+void __init ixp23xx_pci_preinit(void)
+{
+#ifdef __ARMEB__
+	*IXP23XX_PCI_CONTROL |= 0x20000;	/* set I/O swapping */
+#endif
+	/*
+	 * ADDR_31 needs to be clear for PCI memory access to CPP memory
+	 */
+	*IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_ADDR_31;
+	*IXP23XX_CPP2XSI_CURR_XFER_REG3 |= IXP23XX_CPP2XSI_PSH_OFF;
+
+	/*
+	 * Select correct memory for PCI inbound transactions
+	 */
+	if (ixp23xx_cpp_boot()) {
+		*IXP23XX_PCI_CPP_ADDR_BITS &= ~(1 << 1);
+	} else {
+		*IXP23XX_PCI_CPP_ADDR_BITS |= (1 << 1);
+	}
+
+	hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS,
+			"PCI config cycle to non-existent device");
+
+	*IXP23XX_PCI_ADDR_EXT = 0x0000e000;
+}
+
+/*
+ * Prevent PCI layer from seeing the inbound host-bridge resources
+ */
+static void __devinit pci_fixup_ixp23xx(struct pci_dev *dev)
+{
+	int i;
+
+	dev->class &= 0xff;
+	dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
+	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+		dev->resource[i].start = 0;
+		dev->resource[i].end   = 0;
+		dev->resource[i].flags = 0;
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9002, pci_fixup_ixp23xx);
+
+/*
+ * IXP2300 systems often have large resource requirements, so we just
+ * use our own resource space.
+ */
+static struct resource ixp23xx_pci_mem_space = {
+	.start	= IXP23XX_PCI_MEM_START,
+	.end	= IXP23XX_PCI_MEM_START + IXP23XX_PCI_MEM_SIZE - 1,
+	.flags	= IORESOURCE_MEM,
+	.name	= "PCI Mem Space"
+};
+
+static struct resource ixp23xx_pci_io_space = {
+	.start	= 0x00000100,
+	.end	= 0x01ffffff,
+	.flags	= IORESOURCE_IO,
+	.name	= "PCI I/O Space"
+};
+
+int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys)
+{
+	if (nr >= 1)
+		return 0;
+
+	sys->resource[0] = &ixp23xx_pci_io_space;
+	sys->resource[1] = &ixp23xx_pci_mem_space;
+	sys->resource[2] = NULL;
+
+	return 1;
+}
diff --git a/arch/arm/mach-ixp23xx/roadrunner.c b/arch/arm/mach-ixp23xx/roadrunner.c
new file mode 100644
index 000000000000..43c14e740794
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/roadrunner.c
@@ -0,0 +1,164 @@
+/*
+ * arch/arm/mach-ixp23xx/roadrunner.c
+ *
+ * RoadRunner board-specific routines
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2005 (c) MontaVista Software, Inc.
+ *
+ * Based on 2.4 code Copyright 2005 (c) ADI Engineering Corporation
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/bitops.h>
+#include <linux/ioport.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/tlbflush.h>
+#include <asm/pgtable.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/pci.h>
+
+/*
+ * Interrupt mapping
+ */
+#define INTA		IRQ_ROADRUNNER_PCI_INTA
+#define INTB		IRQ_ROADRUNNER_PCI_INTB
+#define INTC		IRQ_ROADRUNNER_PCI_INTC
+#define INTD		IRQ_ROADRUNNER_PCI_INTD
+
+#define INTC_PIN	IXP23XX_GPIO_PIN_11
+#define INTD_PIN	IXP23XX_GPIO_PIN_12
+
+static int __init roadrunner_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
+{
+	static int pci_card_slot_irq[] = {INTB, INTC, INTD, INTA};
+	static int pmc_card_slot_irq[] = {INTA, INTB, INTC, INTD};
+	static int usb_irq[] = {INTB, INTC, INTD, -1};
+	static int mini_pci_1_irq[] = {INTB, INTC, -1, -1};
+	static int mini_pci_2_irq[] = {INTC, INTD, -1, -1};
+
+	switch(dev->bus->number) {
+		case 0:
+			switch(dev->devfn) {
+			case 0x0: // PCI-PCI bridge
+				break;
+			case 0x8: // PCI Card Slot
+				return pci_card_slot_irq[pin - 1];
+			case 0x10: // PMC Slot
+				return pmc_card_slot_irq[pin - 1];
+			case 0x18: // PMC Slot Secondary Agent
+				break;
+			case 0x20: // IXP Processor
+				break;
+			default:
+				return NO_IRQ;
+			}
+			break;
+
+		case 1:
+			switch(dev->devfn) {
+			case 0x0: // IDE Controller
+				return (pin == 1) ? INTC : -1;
+			case 0x8: // USB fun 0
+			case 0x9: // USB fun 1
+			case 0xa: // USB fun 2
+				return usb_irq[pin - 1];
+			case 0x10: // Mini PCI 1
+				return mini_pci_1_irq[pin-1];
+			case 0x18: // Mini PCI 2
+				return mini_pci_2_irq[pin-1];
+			case 0x20: // MEM slot
+				return (pin == 1) ? INTA : -1;
+			default:
+				return NO_IRQ;
+			}
+			break;
+
+		default:
+			return NO_IRQ;
+	}
+
+	return NO_IRQ;
+}
+
+static void roadrunner_pci_preinit(void)
+{
+	set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQT_LOW);
+	set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQT_LOW);
+
+	ixp23xx_pci_preinit();
+}
+
+static struct hw_pci roadrunner_pci __initdata = {
+	.nr_controllers	= 1,
+	.preinit	= roadrunner_pci_preinit,
+	.setup		= ixp23xx_pci_setup,
+	.scan		= ixp23xx_pci_scan_bus,
+	.map_irq	= roadrunner_map_irq,
+};
+
+static int __init roadrunner_pci_init(void)
+{
+	if (machine_is_roadrunner())
+		pci_common_init(&roadrunner_pci);
+
+	return 0;
+};
+
+subsys_initcall(roadrunner_pci_init);
+
+static void __init roadrunner_init(void)
+{
+	physmap_configure(0x90000000, 0x04000000, 2, NULL);
+
+	/*
+	 * Mark flash as writeable
+	 */
+	IXP23XX_EXP_CS0[0] |= IXP23XX_FLASH_WRITABLE;
+	IXP23XX_EXP_CS0[1] |= IXP23XX_FLASH_WRITABLE;
+	IXP23XX_EXP_CS0[2] |= IXP23XX_FLASH_WRITABLE;
+	IXP23XX_EXP_CS0[3] |= IXP23XX_FLASH_WRITABLE;
+
+	ixp23xx_sys_init();
+}
+
+MACHINE_START(ROADRUNNER, "ADI Engineering RoadRunner Development Platform")
+	/* Maintainer: Deepak Saxena */
+	.phys_io	= IXP23XX_PERIPHERAL_PHYS,
+	.io_pg_offst	= ((IXP23XX_PERIPHERAL_VIRT >> 18)) & 0xfffc,
+	.map_io		= ixp23xx_map_io,
+	.init_irq	= ixp23xx_init_irq,
+	.timer		= &ixp23xx_timer,
+	.boot_params	= 0x00000100,
+	.init_machine	= roadrunner_init,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c
index 60d5f8a3339c..7520e602d7a2 100644
--- a/arch/arm/mach-omap1/board-netstar.c
+++ b/arch/arm/mach-omap1/board-netstar.c
@@ -141,7 +141,7 @@ static int __init netstar_late_init(void)
 	/* TODO: Setup front panel switch here */
 
 	/* Setup panic notifier */
-	notifier_chain_register(&panic_notifier_list, &panic_block);
+	atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index bfd5fdd1a875..52e4a9d69642 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -235,7 +235,7 @@ static struct notifier_block panic_block = {
 static int __init voiceblue_setup(void)
 {
 	/* Setup panic notifier */
-	notifier_chain_register(&panic_notifier_list, &panic_block);
+	atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
 
 	return 0;
 }
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index c1d77f5b3823..0104fd142e70 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -10,6 +10,11 @@ config ARCH_LUBBOCK
 	select PXA25x
 	select SA1111
 
+config MACH_LOGICPD_PXA270
+	bool "LogicPD PXA270 Card Engine Development Platform"
+	select PXA27x
+	select IWMMXT
+
 config MACH_MAINSTONE
 	bool "Intel HCDDBBVA0 Development Platform"
 	select PXA27x
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 382644401a4d..4e8a983e2b83 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_PXA27x) += pxa27x.o
 
 # Specific board support
 obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
+obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o
 obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
 obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
 obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 9b48a90aefce..5efa84749f37 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -319,6 +319,11 @@ void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
 	pxaficp_device.dev.platform_data = info;
 }
 
+static struct platform_device pxartc_device = {
+	.name		= "sa1100-rtc",
+	.id		= -1,
+};
+
 static struct platform_device *devices[] __initdata = {
 	&pxamci_device,
 	&udc_device,
@@ -329,6 +334,7 @@ static struct platform_device *devices[] __initdata = {
 	&pxaficp_device,
 	&i2c_device,
 	&i2s_device,
+	&pxartc_device,
 };
 
 static int __init pxa_init(void)
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
new file mode 100644
index 000000000000..ec0f43a102c7
--- /dev/null
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -0,0 +1,393 @@
+/*
+ * linux/arch/arm/mach-pxa/lpd270.c
+ *
+ * Support for the LogicPD PXA270 Card Engine.
+ * Derived from the mainstone code, which carries these notices:
+ *
+ * Author:	Nicolas Pitre
+ * Created:	Nov 05, 2002
+ * Copyright:	MontaVista Software Inc.
+ *
+ * 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/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/bitops.h>
+#include <linux/fb.h>
+#include <linux/ioport.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/lpd270.h>
+#include <asm/arch/audio.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/irda.h>
+#include <asm/arch/ohci.h>
+
+#include "generic.h"
+
+
+static unsigned int lpd270_irq_enabled;
+
+static void lpd270_mask_irq(unsigned int irq)
+{
+	int lpd270_irq = irq - LPD270_IRQ(0);
+
+	__raw_writew(~(1 << lpd270_irq), LPD270_INT_STATUS);
+
+	lpd270_irq_enabled &= ~(1 << lpd270_irq);
+	__raw_writew(lpd270_irq_enabled, LPD270_INT_MASK);
+}
+
+static void lpd270_unmask_irq(unsigned int irq)
+{
+	int lpd270_irq = irq - LPD270_IRQ(0);
+
+	lpd270_irq_enabled |= 1 << lpd270_irq;
+	__raw_writew(lpd270_irq_enabled, LPD270_INT_MASK);
+}
+
+static struct irqchip lpd270_irq_chip = {
+	.ack		= lpd270_mask_irq,
+	.mask		= lpd270_mask_irq,
+	.unmask		= lpd270_unmask_irq,
+};
+
+static void lpd270_irq_handler(unsigned int irq, struct irqdesc *desc,
+				  struct pt_regs *regs)
+{
+	unsigned long pending;
+
+	pending = __raw_readw(LPD270_INT_STATUS) & lpd270_irq_enabled;
+	do {
+		GEDR(0) = GPIO_bit(0);  /* clear useless edge notification */
+		if (likely(pending)) {
+			irq = LPD270_IRQ(0) + __ffs(pending);
+			desc = irq_desc + irq;
+			desc_handle_irq(irq, desc, regs);
+
+			pending = __raw_readw(LPD270_INT_STATUS) &
+						lpd270_irq_enabled;
+		}
+	} while (pending);
+}
+
+static void __init lpd270_init_irq(void)
+{
+	int irq;
+
+	pxa_init_irq();
+
+	__raw_writew(0, LPD270_INT_MASK);
+	__raw_writew(0, LPD270_INT_STATUS);
+
+	/* setup extra LogicPD PXA270 irqs */
+	for (irq = LPD270_IRQ(2); irq <= LPD270_IRQ(4); irq++) {
+		set_irq_chip(irq, &lpd270_irq_chip);
+		set_irq_handler(irq, do_level_IRQ);
+		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+	}
+	set_irq_chained_handler(IRQ_GPIO(0), lpd270_irq_handler);
+	set_irq_type(IRQ_GPIO(0), IRQT_FALLING);
+}
+
+
+#ifdef CONFIG_PM
+static int lpd270_irq_resume(struct sys_device *dev)
+{
+	__raw_writew(lpd270_irq_enabled, LPD270_INT_MASK);
+	return 0;
+}
+
+static struct sysdev_class lpd270_irq_sysclass = {
+	set_kset_name("cpld_irq"),
+	.resume = lpd270_irq_resume,
+};
+
+static struct sys_device lpd270_irq_device = {
+	.cls = &lpd270_irq_sysclass,
+};
+
+static int __init lpd270_irq_device_init(void)
+{
+	int ret = sysdev_class_register(&lpd270_irq_sysclass);
+	if (ret == 0)
+		ret = sysdev_register(&lpd270_irq_device);
+	return ret;
+}
+
+device_initcall(lpd270_irq_device_init);
+#endif
+
+
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.start	= LPD270_ETH_PHYS,
+		.end	= (LPD270_ETH_PHYS + 0xfffff),
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= LPD270_ETHERNET_IRQ,
+		.end	= LPD270_ETHERNET_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(smc91x_resources),
+	.resource	= smc91x_resources,
+};
+
+static struct platform_device lpd270_audio_device = {
+	.name		= "pxa2xx-ac97",
+	.id		= -1,
+};
+
+static struct resource lpd270_flash_resources[] = {
+	[0] = {
+		.start	= PXA_CS0_PHYS,
+		.end	= PXA_CS0_PHYS + SZ_64M - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= PXA_CS1_PHYS,
+		.end	= PXA_CS1_PHYS + SZ_64M - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct mtd_partition lpd270_flash0_partitions[] = {
+	{
+		.name =		"Bootloader",
+		.size =		0x00040000,
+		.offset =	0,
+		.mask_flags =	MTD_WRITEABLE  /* force read-only */
+	}, {
+		.name =		"Kernel",
+		.size =		0x00400000,
+		.offset =	0x00040000,
+	}, {
+		.name =		"Filesystem",
+		.size =		MTDPART_SIZ_FULL,
+		.offset =	0x00440000
+	},
+};
+
+static struct flash_platform_data lpd270_flash_data[2] = {
+	{
+		.name		= "processor-flash",
+		.map_name	= "cfi_probe",
+		.parts		= lpd270_flash0_partitions,
+		.nr_parts	= ARRAY_SIZE(lpd270_flash0_partitions),
+	}, {
+		.name		= "mainboard-flash",
+		.map_name	= "cfi_probe",
+		.parts		= NULL,
+		.nr_parts	= 0,
+	}
+};
+
+static struct platform_device lpd270_flash_device[2] = {
+	{
+		.name		= "pxa2xx-flash",
+		.id		= 0,
+		.dev = {
+			.platform_data	= &lpd270_flash_data[0],
+		},
+		.resource	= &lpd270_flash_resources[0],
+		.num_resources	= 1,
+	}, {
+		.name		= "pxa2xx-flash",
+		.id		= 1,
+		.dev = {
+			.platform_data	= &lpd270_flash_data[1],
+		},
+		.resource	= &lpd270_flash_resources[1],
+		.num_resources	= 1,
+	},
+};
+
+static void lpd270_backlight_power(int on)
+{
+	if (on) {
+		pxa_gpio_mode(GPIO16_PWM0_MD);
+		pxa_set_cken(CKEN0_PWM0, 1);
+		PWM_CTRL0 = 0;
+		PWM_PWDUTY0 = 0x3ff;
+		PWM_PERVAL0 = 0x3ff;
+	} else {
+		PWM_CTRL0 = 0;
+		PWM_PWDUTY0 = 0x0;
+		PWM_PERVAL0 = 0x3FF;
+		pxa_set_cken(CKEN0_PWM0, 0);
+	}
+}
+
+/* 5.7" TFT QVGA (LoLo display number 1) */
+static struct pxafb_mach_info sharp_lq057q3dc02 __initdata = {
+	.pixclock		= 100000,
+	.xres			= 240,
+	.yres			= 320,
+	.bpp			= 16,
+	.hsync_len		= 64,
+	.left_margin		= 0x27,
+	.right_margin		= 0x09,
+	.vsync_len		= 0x04,
+	.upper_margin		= 0x08,
+	.lower_margin		= 0x14,
+	.sync			= 0,
+	.lccr0			= 0x07800080,
+	.lccr3			= 0x04400007,
+	.pxafb_backlight_power	= lpd270_backlight_power,
+};
+
+/* 6.4" TFT VGA (LoLo display number 5) */
+static struct pxafb_mach_info sharp_lq64d343 __initdata = {
+	.pixclock		= 20000,
+	.xres			= 640,
+	.yres			= 480,
+	.bpp			= 16,
+	.hsync_len		= 49,
+	.left_margin		= 0x89,
+	.right_margin		= 0x19,
+	.vsync_len		= 18,
+	.upper_margin		= 0x22,
+	.lower_margin		= 0,
+	.sync			= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	.lccr0			= 0x07800080,
+	.lccr3			= 0x04400001,
+	.pxafb_backlight_power	= lpd270_backlight_power,
+};
+
+/* 3.5" TFT QVGA (LoLo display number 8) */
+static struct pxafb_mach_info sharp_lq035q7db02_20 __initdata = {
+	.pixclock		= 100000,
+	.xres			= 240,
+	.yres			= 320,
+	.bpp			= 16,
+	.hsync_len		= 0x34,
+	.left_margin		= 0x09,
+	.right_margin		= 0x09,
+	.vsync_len		= 0x08,
+	.upper_margin		= 0x05,
+	.lower_margin		= 0x14,
+	.sync			= 0,
+	.lccr0			= 0x07800080,
+	.lccr3			= 0x04400007,
+	.pxafb_backlight_power	= lpd270_backlight_power,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+	&smc91x_device,
+	&lpd270_audio_device,
+	&lpd270_flash_device[0],
+	&lpd270_flash_device[1],
+};
+
+static int lpd270_ohci_init(struct device *dev)
+{
+	/* setup Port1 GPIO pin. */
+	pxa_gpio_mode(88 | GPIO_ALT_FN_1_IN);	/* USBHPWR1 */
+	pxa_gpio_mode(89 | GPIO_ALT_FN_2_OUT);	/* USBHPEN1 */
+
+	/* Set the Power Control Polarity Low and Power Sense
+	   Polarity Low to active low. */
+	UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
+		~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
+
+	return 0;
+}
+
+static struct pxaohci_platform_data lpd270_ohci_platform_data = {
+	.port_mode	= PMM_PERPORT_MODE,
+	.init		= lpd270_ohci_init,
+};
+
+static void __init lpd270_init(void)
+{
+	lpd270_flash_data[0].width = (BOOT_DEF & 1) ? 2 : 4;
+	lpd270_flash_data[1].width = 4;
+
+	/*
+	 * System bus arbiter setting:
+	 * - Core_Park
+	 * - LCD_wt:DMA_wt:CORE_Wt = 2:3:4
+	 */
+	ARB_CNTRL = ARB_CORE_PARK | 0x234;
+
+	/*
+	 * On LogicPD PXA270, we route AC97_SYSCLK via GPIO45.
+	 */
+	pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD);
+
+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+	// set_pxa_fb_info(&sharp_lq057q3dc02);
+	set_pxa_fb_info(&sharp_lq64d343);
+	// set_pxa_fb_info(&sharp_lq035q7db02_20);
+
+	pxa_set_ohci_info(&lpd270_ohci_platform_data);
+}
+
+
+static struct map_desc lpd270_io_desc[] __initdata = {
+	{
+		.virtual	= LPD270_CPLD_VIRT,
+		.pfn		= __phys_to_pfn(LPD270_CPLD_PHYS),
+		.length		= LPD270_CPLD_SIZE,
+		.type		= MT_DEVICE,
+	},
+};
+
+static void __init lpd270_map_io(void)
+{
+	pxa_map_io();
+	iotable_init(lpd270_io_desc, ARRAY_SIZE(lpd270_io_desc));
+
+	/* initialize sleep mode regs (wake-up sources, etc) */
+	PGSR0 = 0x00008800;
+	PGSR1 = 0x00000002;
+	PGSR2 = 0x0001FC00;
+	PGSR3 = 0x00001F81;
+	PWER  = 0xC0000002;
+	PRER  = 0x00000002;
+	PFER  = 0x00000002;
+
+	/* for use I SRAM as framebuffer.  */
+	PSLR |= 0x00000F04;
+	PCFR  = 0x00000066;
+}
+
+MACHINE_START(LOGICPD_PXA270, "LogicPD PXA270 Card Engine")
+	/* Maintainer: Peter Barada */
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= lpd270_map_io,
+	.init_irq	= lpd270_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= lpd270_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 30ec317bbb97..0dbb079ecd25 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -467,6 +467,8 @@ struct platform_device akitaioexp_device = {
 	.id		= -1,
 };
 
+EXPORT_SYMBOL_GPL(akitaioexp_device);
+
 static void __init akita_init(void)
 {
 	spitz_ficp_platform_data.transceiver_mode = akita_irda_transceiver_mode;
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index 6923316b3d0d..cd67ab1b217b 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -111,7 +111,7 @@ config SA1100_LART
 	bool "LART"
 	help
 	  Say Y here if you are using the Linux Advanced Radio Terminal
-	  (also known as the LART).  See <http://www.lart.tudelft.nl/> for
+	  (also known as the LART).  See <http://www.lartmaker.nl/> for
 	  information on the LART.
 
 config SA1100_PLEB
diff --git a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c
index 6435b2e48ffa..d68630b74d78 100644
--- a/arch/arm/mach-sa1100/cpu-sa1100.c
+++ b/arch/arm/mach-sa1100/cpu-sa1100.c
@@ -11,7 +11,7 @@
  *     linux-2.4.5-rmk1
  *
  * This software has been developed while working on the LART
- * computing board (http://www.lart.tudelft.nl/), which is
+ * computing board (http://www.lartmaker.nl/), which is
  * sponsored by the Mobile Multi-media Communications
  * (http://www.mmc.tudelft.nl/) and Ubiquitous Communications 
  * (http://www.ubicom.tudelft.nl/) projects.
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 2abdc419e984..9ea71551fc04 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -324,6 +324,11 @@ void sa11x0_set_irda_data(struct irda_platform_data *irda)
 	sa11x0ir_device.dev.platform_data = irda;
 }
 
+static struct platform_device sa11x0rtc_device = {
+	.name		= "sa1100-rtc",
+	.id		= -1,
+};
+
 static struct platform_device *sa11x0_devices[] __initdata = {
 	&sa11x0udc_device,
 	&sa11x0uart1_device,
@@ -333,6 +338,7 @@ static struct platform_device *sa11x0_devices[] __initdata = {
 	&sa11x0pcmcia_device,
 	&sa11x0fb_device,
 	&sa11x0mtd_device,
+	&sa11x0rtc_device,
 };
 
 static int __init sa1100_init(void)
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index e680c5fd93b5..c55b739e10ba 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -239,6 +239,17 @@ config CPU_XSCALE
 	select CPU_CACHE_VIVT
 	select CPU_TLB_V4WBI
 
+# XScale Core Version 3
+config CPU_XSC3
+	bool
+	depends on ARCH_IXP23XX
+	default y
+	select CPU_32v5
+	select CPU_ABRT_EV5T
+	select CPU_CACHE_VIVT
+	select CPU_TLB_V4WBI
+	select IO_36
+
 # ARMv6
 config CPU_V6
 	bool "Support ARM V6 processor"
@@ -361,11 +372,17 @@ config CPU_TLB_V4WBI
 config CPU_TLB_V6
 	bool
 
+#
+# CPU supports 36-bit I/O
+#
+config IO_36
+	bool
+
 comment "Processor Features"
 
 config ARM_THUMB
 	bool "Support Thumb user binaries"
-	depends on CPU_ARM720T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_V6
+	depends on CPU_ARM720T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6
 	default y
 	help
 	  Say Y if you want to include kernel support for running user space
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index ffe73ba2bf17..07a538505784 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_CPU_COPY_V4WB)	+= copypage-v4wb.o
 obj-$(CONFIG_CPU_COPY_V6)	+= copypage-v6.o mmu.o
 obj-$(CONFIG_CPU_SA1100)	+= copypage-v4mc.o
 obj-$(CONFIG_CPU_XSCALE)	+= copypage-xscale.o
+obj-$(CONFIG_CPU_XSC3)		+= copypage-xsc3.o
 
 obj-$(CONFIG_CPU_TLB_V3)	+= tlb-v3.o
 obj-$(CONFIG_CPU_TLB_V4WT)	+= tlb-v4.o
@@ -51,4 +52,5 @@ 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_XSC3)		+= proc-xsc3.o
 obj-$(CONFIG_CPU_V6)		+= proc-v6.o
diff --git a/arch/arm/mm/copypage-xsc3.S b/arch/arm/mm/copypage-xsc3.S
new file mode 100644
index 000000000000..9a2cb4332b4c
--- /dev/null
+++ b/arch/arm/mm/copypage-xsc3.S
@@ -0,0 +1,97 @@
+/*
+ *  linux/arch/arm/lib/copypage-xsc3.S
+ *
+ *  Copyright (C) 2004 Intel Corp.
+ *
+ * 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.
+ *
+ * Adapted for 3rd gen XScale core, no more mini-dcache
+ * Author: Matt Gilbert (matthew.m.gilbert@intel.com)
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/asm-offsets.h>
+
+/*
+ * General note:
+ *  We don't really want write-allocate cache behaviour for these functions
+ *  since that will just eat through 8K of the cache.
+ */
+
+	.text
+	.align	5
+/*
+ * XSC3 optimised copy_user_page
+ *  r0 = destination
+ *  r1 = source
+ *  r2 = virtual user address of ultimate destination page
+ *
+ * The source page may have some clean entries in the cache already, but we
+ * can safely ignore them - break_cow() will flush them out of the cache
+ * if we eventually end up using our copied page.
+ *
+ */
+ENTRY(xsc3_mc_copy_user_page)
+	stmfd	sp!, {r4, r5, lr}
+	mov	lr, #PAGE_SZ/64-1
+
+	pld	[r1, #0]
+	pld	[r1, #32]
+1:	pld	[r1, #64]
+	pld	[r1, #96]
+
+2:	ldrd	r2, [r1], #8
+	mov	ip, r0
+	ldrd	r4, [r1], #8
+	mcr	p15, 0, ip, c7, c6, 1		@ invalidate
+	strd	r2, [r0], #8
+	ldrd	r2, [r1], #8
+	strd	r4, [r0], #8
+	ldrd	r4, [r1], #8
+	strd	r2, [r0], #8
+	strd	r4, [r0], #8
+	ldrd	r2, [r1], #8
+	mov	ip, r0
+	ldrd	r4, [r1], #8
+	mcr	p15, 0, ip, c7, c6, 1		@ invalidate
+	strd	r2, [r0], #8
+	ldrd	r2, [r1], #8
+	subs	lr, lr, #1
+	strd	r4, [r0], #8
+	ldrd	r4, [r1], #8
+	strd	r2, [r0], #8
+	strd	r4, [r0], #8
+	bgt	1b
+	beq	2b
+
+	ldmfd	sp!, {r4, r5, pc}
+
+	.align	5
+/*
+ * XScale optimised clear_user_page
+ *  r0 = destination
+ *  r1 = virtual user address of ultimate destination page
+ */
+ENTRY(xsc3_mc_clear_user_page)
+	mov	r1, #PAGE_SZ/32
+	mov	r2, #0
+	mov	r3, #0
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate line
+	strd	r2, [r0], #8
+	strd	r2, [r0], #8
+	strd	r2, [r0], #8
+	strd	r2, [r0], #8
+	subs	r1, r1, #1
+	bne	1b
+	mov	pc, lr
+
+	__INITDATA
+
+	.type	xsc3_mc_user_fns, #object
+ENTRY(xsc3_mc_user_fns)
+	.long	xsc3_mc_clear_user_page
+	.long	xsc3_mc_copy_user_page
+	.size	xsc3_mc_user_fns, . - xsc3_mc_user_fns
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index ef8d30a185a9..5e5d05bcad50 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -557,7 +557,8 @@ void __init create_mapping(struct map_desc *md)
 	 *	supersections are only allocated for domain 0 regardless
 	 *	of the actual domain assignments in use.
 	 */
-	if (cpu_architecture() >= CPU_ARCH_ARMv6 && domain == 0) {
+	if ((cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())
+		&& domain == 0) {
 		/*
 		 * Align to supersection boundary if !high pages.
 		 * High pages have already been checked for proper
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 9a7e7c096aa9..ee6f15298735 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -21,6 +21,14 @@
 
 #define D_CACHE_LINE_SIZE	32
 
+#define TTB_C		(1 << 0)
+#define TTB_S		(1 << 1)
+#define TTB_IMP		(1 << 2)
+#define TTB_RGN_NC	(0 << 3)
+#define TTB_RGN_WBWA	(1 << 3)
+#define TTB_RGN_WT	(2 << 3)
+#define TTB_RGN_WB	(3 << 3)
+
 	.macro	cpsie, flags
 	.ifc \flags, f
 	.long	0xf1080040
@@ -115,7 +123,7 @@ 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
+	orr	r0, r0, #TTB_RGN_WBWA|TTB_S	@ mark PTWs shared, outer cacheable
 #endif
 	mcr	p15, 0, r2, c7, c5, 6		@ flush BTAC/BTB
 	mcr	p15, 0, r2, c7, c10, 4		@ drain write buffer
@@ -161,8 +169,8 @@ ENTRY(cpu_v6_set_pte)
 	tst	r1, #L_PTE_YOUNG
 	biceq	r2, r2, #PTE_EXT_APX | PTE_EXT_AP_MASK
 
-@	tst	r1, #L_PTE_EXEC
-@	orreq	r2, r2, #PTE_EXT_XN
+	tst	r1, #L_PTE_EXEC
+	orreq	r2, r2, #PTE_EXT_XN
 
 	tst	r1, #L_PTE_PRESENT
 	moveq	r2, #0
@@ -221,7 +229,7 @@ __v6_setup:
 	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
+	orr	r4, r4, #TTB_RGN_WBWA|TTB_S	@ mark PTWs shared, outer cacheable
 #endif
 	mcr	p15, 0, r4, c2, c0, 1		@ load TTB1
 #ifdef CONFIG_VFP
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
new file mode 100644
index 000000000000..f90513e9af0c
--- /dev/null
+++ b/arch/arm/mm/proc-xsc3.S
@@ -0,0 +1,498 @@
+/*
+ * linux/arch/arm/mm/proc-xsc3.S
+ *
+ * Original Author: Matthew Gilbert
+ * Current Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2004 (C) Intel Corp.
+ * Copyright 2005 (c) MontaVista Software, Inc.
+ *
+ * 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.
+ *
+ * MMU functions for the Intel XScale3 Core (XSC3).  The XSC3 core is an
+ * extension to Intel's original XScale core that adds the following
+ * features:
+ *
+ * - ARMv6 Supersections
+ * - Low Locality Reference pages (replaces mini-cache)
+ * - 36-bit addressing
+ * - L2 cache
+ * - Cache-coherency if chipset supports it
+ *
+ * Based on orignal XScale code by Nicolas Pitre
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/procinfo.h>
+#include <asm/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include "proc-macros.S"
+
+/*
+ * This is the maximum size of an area which will be flushed.  If the
+ * area is larger than this, then we flush the whole cache.
+ */
+#define MAX_AREA_SIZE	32768
+
+/*
+ * The cache line size of the I and D cache.
+ */
+#define CACHELINESIZE	32
+
+/*
+ * The size of the data cache.
+ */
+#define CACHESIZE	32768
+
+/*
+ * Run with L2 enabled.
+ */
+#define L2_CACHE_ENABLE	1
+
+/*
+ * Enable the Branch Target Buffer (can cause crashes, see erratum #42.)
+ */
+#define BTB_ENABLE	0
+
+/*
+ * This macro is used to wait for a CP15 write and is needed
+ * when we have to ensure that the last operation to the co-pro
+ * was completed before continuing with operation.
+ */
+	.macro	cpwait_ret, lr, rd
+	mrc	p15, 0, \rd, c2, c0, 0		@ arbitrary read of cp15
+	sub	pc, \lr, \rd, LSR #32		@ wait for completion and
+						@ flush instruction pipeline
+	.endm
+
+/*
+ * This macro cleans & invalidates the entire xsc3 dcache by set & way.
+ */
+
+ 	.macro  clean_d_cache rd, rs
+	mov	\rd, #0x1f00
+	orr	\rd, \rd, #0x00e0
+1:	mcr	p15, 0, \rd, c7, c14, 2		@ clean/inv set/way
+	adds	\rd, \rd, #0x40000000
+	bcc	1b
+	subs	\rd, \rd, #0x20
+	bpl	1b
+	.endm
+
+	.text
+
+/*
+ * cpu_xsc3_proc_init()
+ *
+ * Nothing too exciting at the moment
+ */
+ENTRY(cpu_xsc3_proc_init)
+	mov	pc, lr
+
+/*
+ * cpu_xsc3_proc_fin()
+ */
+ENTRY(cpu_xsc3_proc_fin)
+	str	lr, [sp, #-4]!
+	mov	r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
+	msr	cpsr_c, r0
+	bl	xsc3_flush_kern_cache_all	@ clean caches
+	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
+	bic	r0, r0, #0x1800			@ ...IZ...........
+	bic	r0, r0, #0x0006			@ .............CA.
+	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+	ldr	pc, [sp], #4
+
+/*
+ * cpu_xsc3_reset(loc)
+ *
+ * Perform a soft reset of the system.  Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+	.align	5
+ENTRY(cpu_xsc3_reset)
+	mov	r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
+	msr	cpsr_c, r1			@ reset CPSR
+	mrc	p15, 0, r1, c1, c0, 0		@ ctrl register
+	bic	r1, r1, #0x0086			@ ........B....CA.
+	bic	r1, r1, #0x3900			@ ..VIZ..S........
+	mcr	p15, 0, r1, c1, c0, 0		@ ctrl register
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches & BTB
+	bic	r1, r1, #0x0001			@ ...............M
+	mcr	p15, 0, r1, c1, c0, 0		@ ctrl register
+	@ CAUTION: MMU turned off from this point.  We count on the pipeline
+	@ already containing those two last instructions to survive.
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, r0
+
+/*
+ * cpu_xsc3_do_idle()
+ *
+ * Cause the processor to idle
+ *
+ * For now we do nothing but go to idle mode for every case
+ *
+ * XScale supports clock switching, but using idle mode support
+ * allows external hardware to react to system state changes.
+
+ MMG: Come back to this one.
+ */
+	.align	5
+
+ENTRY(cpu_xsc3_do_idle)
+	mov	r0, #1
+	mcr	p14, 0, r0, c7, c0, 0		@ Go to IDLE
+	mov	pc, lr
+
+/* ================================= CACHE ================================ */
+
+/*
+ *	flush_user_cache_all()
+ *
+ *	Invalidate all cache entries in a particular address
+ *	space.
+ */
+ENTRY(xsc3_flush_user_cache_all)
+	/* FALLTHROUGH */
+
+/*
+ *	flush_kern_cache_all()
+ *
+ *	Clean and invalidate the entire cache.
+ */
+ENTRY(xsc3_flush_kern_cache_all)
+	mov	r2, #VM_EXEC
+	mov	ip, #0
+__flush_whole_cache:
+	clean_d_cache r0, r1
+	tst	r2, #VM_EXEC
+	mcrne	p15, 0, ip, c7, c5, 0		@ Invalidate I cache & BTB
+	mcrne	p15, 0, ip, c7, c10, 4		@ Drain Write Buffer
+	mcrne	p15, 0, ip, c7, c5, 4		@ Prefetch Flush
+	mov	pc, lr
+
+/*
+ *	flush_user_cache_range(start, end, vm_flags)
+ *
+ *	Invalidate a range of cache entries in the specified
+ *	address space.
+ *
+ *	- start - start address (may not be aligned)
+ *	- end	- end address (exclusive, may not be aligned)
+ *	- vma	- vma_area_struct describing address space
+ */
+	.align	5
+ENTRY(xsc3_flush_user_cache_range)
+	mov	ip, #0
+	sub	r3, r1, r0			@ calculate total size
+	cmp	r3, #MAX_AREA_SIZE
+	bhs	__flush_whole_cache
+
+1:	tst	r2, #VM_EXEC
+	mcrne	p15, 0, r0, c7, c5, 1		@ Invalidate I cache line
+	mcr	p15, 0, r0, c7, c14, 1		@ Clean/invalidate D cache line
+	add	r0, r0, #CACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+	tst	r2, #VM_EXEC
+	mcrne	p15, 0, ip, c7, c5, 6		@ Invalidate BTB
+	mcrne	p15, 0, ip, c7, c10, 4		@ Drain Write Buffer
+	mcrne	p15, 0, ip, c7, c5, 4		@ Prefetch Flush
+	mov	pc, lr
+
+/*
+ *	coherent_kern_range(start, end)
+ *
+ *	Ensure coherency between the Icache and the Dcache in the
+ *	region described by start.  If you have non-snooping
+ *	Harvard caches, you need to implement this function.
+ *
+ *	- start  - virtual start address
+ *	- end	 - virtual end address
+ *
+ *	Note: single I-cache line invalidation isn't used here since
+ *	it also trashes the mini I-cache used by JTAG debuggers.
+ */
+ENTRY(xsc3_coherent_kern_range)
+/* FALLTHROUGH */
+ENTRY(xsc3_coherent_user_range)
+	bic	r0, r0, #CACHELINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #CACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 0		@ Invalidate I cache & BTB
+	mcr	p15, 0, r0, c7, c10, 4		@ Drain Write Buffer
+	mcr	p15, 0, r0, c7, c5, 4		@ Prefetch Flush
+	mov	pc, lr
+
+/*
+ *	flush_kern_dcache_page(void *page)
+ *
+ *	Ensure no D cache aliasing occurs, either with itself or
+ *	the I cache
+ *
+ *	- addr	- page aligned address
+ */
+ENTRY(xsc3_flush_kern_dcache_page)
+	add	r1, r0, #PAGE_SZ
+1:	mcr	p15, 0, r0, c7, c14, 1		@ Clean/Invalidate D Cache line
+	add	r0, r0, #CACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 0		@ Invalidate I cache & BTB
+	mcr	p15, 0, r0, c7, c10, 4		@ Drain Write Buffer
+	mcr	p15, 0, r0, c7, c5, 4		@ Prefetch Flush
+	mov	pc, lr
+
+/*
+ *	dma_inv_range(start, end)
+ *
+ *	Invalidate (discard) the specified virtual address range.
+ *	May not write back any entries.  If 'start' or 'end'
+ *	are not cache line aligned, those lines must be written
+ *	back.
+ *
+ *	- start  - virtual start address
+ *	- end	 - virtual end address
+ */
+ENTRY(xsc3_dma_inv_range)
+	tst	r0, #CACHELINESIZE - 1
+	bic	r0, r0, #CACHELINESIZE - 1
+	mcrne	p15, 0, r0, c7, c10, 1		@ clean L1 D entry
+	mcrne	p15, 1, r0, c7, c11, 1		@ clean L2 D entry
+	tst	r1, #CACHELINESIZE - 1
+	mcrne	p15, 0, r1, c7, c10, 1		@ clean L1 D entry
+	mcrne	p15, 1, r1, c7, c11, 1		@ clean L2 D entry
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate L1 D entry
+	mcr	p15, 1, r0, c7, c7, 1		@ Invalidate L2 D cache line
+	add	r0, r0, #CACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+	mcr	p15, 0, r0, c7, c10, 4		@ Drain Write Buffer
+	mov	pc, lr
+
+/*
+ *	dma_clean_range(start, end)
+ *
+ *	Clean the specified virtual address range.
+ *
+ *	- start  - virtual start address
+ *	- end	 - virtual end address
+ */
+ENTRY(xsc3_dma_clean_range)
+	bic	r0, r0, #CACHELINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean L1 D entry
+	mcr	p15, 1, r0, c7, c11, 1		@ clean L2 D entry
+	add	r0, r0, #CACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+	mcr	p15, 0, r0, c7, c10, 4		@ Drain Write Buffer
+	mov	pc, lr
+
+/*
+ *	dma_flush_range(start, end)
+ *
+ *	Clean and invalidate the specified virtual address range.
+ *
+ *	- start  - virtual start address
+ *	- end	 - virtual end address
+ */
+ENTRY(xsc3_dma_flush_range)
+	bic	r0, r0, #CACHELINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c14, 1	@ Clean/invalidate L1 D cache line
+	mcr	p15, 1, r0, c7, c11, 1	@ Clean L2 D cache line
+	mcr	p15, 1, r0, c7, c7, 1	@ Invalidate L2 D cache line
+	add	r0, r0, #CACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+	mcr	p15, 0, r0, c7, c10, 4		@ Drain Write Buffer
+	mov	pc, lr
+
+ENTRY(xsc3_cache_fns)
+	.long	xsc3_flush_kern_cache_all
+	.long	xsc3_flush_user_cache_all
+	.long	xsc3_flush_user_cache_range
+	.long	xsc3_coherent_kern_range
+	.long	xsc3_coherent_user_range
+	.long	xsc3_flush_kern_dcache_page
+	.long	xsc3_dma_inv_range
+	.long	xsc3_dma_clean_range
+	.long	xsc3_dma_flush_range
+
+ENTRY(cpu_xsc3_dcache_clean_area)
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #CACHELINESIZE
+	subs	r1, r1, #CACHELINESIZE
+	bhi	1b
+	mov	pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_xsc3_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+	.align	5
+ENTRY(cpu_xsc3_switch_mm)
+	clean_d_cache r1, r2
+	mcr	p15, 0, ip, c7, c5, 0		@ Invalidate I cache & BTB
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write Buffer
+	mcr	p15, 0, ip, c7, c5, 4		@ Prefetch Flush
+#ifdef L2_CACHE_ENABLE
+	orr	r0, r0, #0x18			@ cache the page table in L2
+#endif
+	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	cpwait_ret lr, ip
+
+/*
+ * cpu_xsc3_set_pte(ptep, pte)
+ *
+ * Set a PTE and flush it out
+ *
+ */
+	.align	5
+ENTRY(cpu_xsc3_set_pte)
+	str	r1, [r0], #-2048		@ linux version
+
+	bic	r2, r1, #0xff0
+	orr	r2, r2, #PTE_TYPE_EXT		@ extended page
+
+	eor	r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
+
+	tst	r3, #L_PTE_USER			@ User?
+	orrne	r2, r2, #PTE_EXT_AP_URO_SRW	@ yes -> user r/o, system r/w
+
+	tst	r3, #L_PTE_WRITE | L_PTE_DIRTY	@ Write and Dirty?
+	orreq	r2, r2, #PTE_EXT_AP_UNO_SRW	@ yes -> user n/a, system r/w
+						@ combined with user -> user r/w
+
+#if L2_CACHE_ENABLE
+	@ If its cacheable it needs to be in L2 also.
+	eor	ip, r1, #L_PTE_CACHEABLE
+	tst	ip, #L_PTE_CACHEABLE
+	orreq	r2, r2, #PTE_EXT_TEX(0x5)
+#endif
+
+	tst	r3, #L_PTE_PRESENT | L_PTE_YOUNG	@ Present and Young?
+	movne	r2, #0				@ no -> fault
+
+	str	r2, [r0]			@ hardware version
+	mov	ip, #0
+	mcr	p15, 0, r0, c7, c10, 1		@ Clean D cache line mcr
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write Buffer
+	mov	pc, lr
+
+	.ltorg
+
+	.align
+
+	__INIT
+
+	.type	__xsc3_setup, #function
+__xsc3_setup:
+	mov	r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
+	msr	cpsr_c, r0
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I, D caches & BTB
+	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write Buffer
+	mcr	p15, 0, ip, c7, c5, 4		@ Prefetch Flush
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I, D TLBs
+#if L2_CACHE_ENABLE
+	orr	r4, r4, #0x18			@ cache the page table in L2
+#endif
+	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
+	mov	r0, #1				@ Allow access to CP0 and CP13
+	orr	r0, r0, #1 << 13		@ Its undefined whether this
+	mcr	p15, 0, r0, c15, c1, 0		@ affects USR or SVC modes
+	mrc	p15, 0, r0, c1, c0, 1		@ get auxiliary control reg
+	and	r0, r0, #2			@ preserve bit P bit setting
+#if L2_CACHE_ENABLE
+	orr	r0, r0, #(1 << 10)		@ enable L2 for LLR cache
+#endif
+	mcr	p15, 0, r0, c1, c0, 1		@ set auxiliary control reg
+	mrc	p15, 0, r0, c1, c0, 0		@ get control register
+	bic	r0, r0, #0x0200			@ .... ..R. .... ....
+	bic	r0, r0, #0x0002			@ .... .... .... ..A.
+	orr	r0, r0, #0x0005			@ .... .... .... .C.M
+#if BTB_ENABLE
+	orr	r0, r0, #0x3900			@ ..VI Z..S .... ....
+#else
+	orr	r0, r0, #0x3100			@ ..VI ...S .... ....
+#endif
+#if L2_CACHE_ENABLE
+	orr 	r0, r0, #0x4000000		@ L2 enable
+#endif
+	mov	pc, lr
+
+	.size	__xsc3_setup, . - __xsc3_setup
+
+	__INITDATA
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+
+	.type	xsc3_processor_functions, #object
+ENTRY(xsc3_processor_functions)
+	.word	v5t_early_abort
+	.word	cpu_xsc3_proc_init
+	.word	cpu_xsc3_proc_fin
+	.word	cpu_xsc3_reset
+	.word	cpu_xsc3_do_idle
+	.word	cpu_xsc3_dcache_clean_area
+	.word	cpu_xsc3_switch_mm
+	.word	cpu_xsc3_set_pte
+	.size	xsc3_processor_functions, . - xsc3_processor_functions
+
+	.section ".rodata"
+
+	.type	cpu_arch_name, #object
+cpu_arch_name:
+	.asciz	"armv5te"
+	.size	cpu_arch_name, . - cpu_arch_name
+
+	.type	cpu_elf_name, #object
+cpu_elf_name:
+	.asciz	"v5"
+	.size	cpu_elf_name, . - cpu_elf_name
+
+	.type	cpu_xsc3_name, #object
+cpu_xsc3_name:
+	.asciz	"XScale-Core3"
+	.size	cpu_xsc3_name, . - cpu_xsc3_name
+
+	.align
+
+	.section ".proc.info.init", #alloc, #execinstr
+
+	.type	__xsc3_proc_info,#object
+__xsc3_proc_info:
+	.long	0x69056000
+	.long	0xffffe000
+	.long	0x00000c0e
+	b	__xsc3_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+	.long	cpu_xsc3_name
+	.long	xsc3_processor_functions
+	.long	v4wbi_tlb_fns
+	.long	xsc3_mc_user_fns
+	.long	xsc3_cache_fns
+	.size	__xsc3_proc_info, . - __xsc3_proc_info
diff --git a/arch/arm26/mm/init.c b/arch/arm26/mm/init.c
index e3ecaa453747..7da8a5205678 100644
--- a/arch/arm26/mm/init.c
+++ b/arch/arm26/mm/init.c
@@ -23,6 +23,7 @@
 #include <linux/initrd.h>
 #include <linux/bootmem.h>
 #include <linux/blkdev.h>
+#include <linux/pfn.h>
 
 #include <asm/segment.h>
 #include <asm/mach-types.h>
@@ -101,12 +102,6 @@ struct node_info {
 	int bootmap_pages;
 };
 
-#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
-#define PFN_UP(x)	(PAGE_ALIGN(x) >> PAGE_SHIFT)
-#define PFN_SIZE(x)	((x) >> PAGE_SHIFT)
-#define PFN_RANGE(s,e)	PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \
-				(((unsigned long)(s)) & PAGE_MASK))
-
 /*
  * FIXME: We really want to avoid allocating the bootmap bitmap
  * over the top of the initrd.  Hopefully, this is located towards
diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c
index 1ba57efff60d..619a6eefd893 100644
--- a/arch/cris/kernel/setup.c
+++ b/arch/cris/kernel/setup.c
@@ -18,6 +18,7 @@
 #include <linux/seq_file.h>
 #include <linux/tty.h>
 #include <linux/utsname.h>
+#include <linux/pfn.h>
 
 #include <asm/setup.h>
 
@@ -88,10 +89,6 @@ setup_arch(char **cmdline_p)
 	init_mm.end_data =   (unsigned long) &_edata;
 	init_mm.brk =        (unsigned long) &_end;
 
-#define PFN_UP(x)       (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define PFN_DOWN(x)     ((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x)     ((x) << PAGE_SHIFT)
-
 	/* min_low_pfn points to the start of DRAM, start_pfn points
 	 * to the first DRAM pages after the kernel, and max_low_pfn
 	 * to the end of DRAM.
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index f7db71d0b913..f17bd1d2707e 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -231,6 +231,15 @@ config SCHED_SMT
 	  cost of slightly increased overhead in some places. If unsure say
 	  N here.
 
+config SCHED_MC
+	bool "Multi-core scheduler support"
+	depends on SMP
+	default y
+	help
+	  Multi-core scheduler support improves the CPU scheduler's decision
+	  making when dealing with multi-core CPU chips at a cost of slightly
+	  increased overhead in some places. If unsure say N here.
+
 source "kernel/Kconfig.preempt"
 
 config X86_UP_APIC
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S
index 2ac40c8244c4..0000a2674537 100644
--- a/arch/i386/boot/video.S
+++ b/arch/i386/boot/video.S
@@ -1924,6 +1924,7 @@ skip10:	movb	%ah, %al
 	ret
 
 store_edid:
+#ifdef CONFIG_FB_FIRMWARE_EDID
 	pushw	%es				# just save all registers
 	pushw	%ax
 	pushw	%bx
@@ -1954,6 +1955,7 @@ store_edid:
 	popw	%bx
 	popw	%ax
 	popw	%es
+#endif
 	ret
 
 # VIDEO_SELECT-only variables
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 7e3d6b6a4e96..a06a49075f10 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -266,7 +266,7 @@ static void __init early_cpu_detect(void)
 void __cpuinit generic_identify(struct cpuinfo_x86 * c)
 {
 	u32 tfms, xlvl;
-	int junk;
+	int ebx;
 
 	if (have_cpuid_p()) {
 		/* Get vendor name */
@@ -282,7 +282,7 @@ void __cpuinit generic_identify(struct cpuinfo_x86 * c)
 		/* Intel-defined flags: level 0x00000001 */
 		if ( c->cpuid_level >= 0x00000001 ) {
 			u32 capability, excap;
-			cpuid(0x00000001, &tfms, &junk, &excap, &capability);
+			cpuid(0x00000001, &tfms, &ebx, &excap, &capability);
 			c->x86_capability[0] = capability;
 			c->x86_capability[4] = excap;
 			c->x86 = (tfms >> 8) & 15;
@@ -292,6 +292,11 @@ void __cpuinit generic_identify(struct cpuinfo_x86 * c)
 			if (c->x86 >= 0x6)
 				c->x86_model += ((tfms >> 16) & 0xF) << 4;
 			c->x86_mask = tfms & 15;
+#ifdef CONFIG_SMP
+			c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0);
+#else
+			c->apicid = (ebx >> 24) & 0xFF;
+#endif
 		} else {
 			/* Have CPUID level 0 only - unheard of */
 			c->x86 = 4;
@@ -474,7 +479,6 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c)
 
 	cpuid(1, &eax, &ebx, &ecx, &edx);
 
-	c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0);
 
 	if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
 		return;
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
index 1e70823e1cb5..712a26bd4457 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
@@ -1095,10 +1095,15 @@ static int __devexit powernowk8_cpu_exit (struct cpufreq_policy *pol)
 
 static unsigned int powernowk8_get (unsigned int cpu)
 {
-	struct powernow_k8_data *data = powernow_data[cpu];
+	struct powernow_k8_data *data;
 	cpumask_t oldmask = current->cpus_allowed;
 	unsigned int khz = 0;
 
+	data = powernow_data[first_cpu(cpu_core_map[cpu])];
+
+	if (!data)
+		return -EINVAL;
+
 	set_cpus_allowed(current, cpumask_of_cpu(cpu));
 	if (smp_processor_id() != cpu) {
 		printk(KERN_ERR PFX "limiting to CPU %d failed in powernowk8_get\n", cpu);
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
index 00ea899c17e1..79a7c5c87edc 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
@@ -182,10 +182,6 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid);
 
 static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index);
 
-#ifndef for_each_cpu_mask
-#define for_each_cpu_mask(i,mask) for (i=0;i<1;i++)
-#endif
-
 #ifdef CONFIG_SMP
 static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[])
 {
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c
index ce61921369e5..9df87b03612c 100644
--- a/arch/i386/kernel/cpu/intel_cacheinfo.c
+++ b/arch/i386/kernel/cpu/intel_cacheinfo.c
@@ -173,6 +173,10 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
 	unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
 	unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
 	unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
+	unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
+#ifdef CONFIG_SMP
+	unsigned int cpu = (c == &boot_cpu_data) ? 0 : (c - cpu_data);
+#endif
 
 	if (c->cpuid_level > 3) {
 		static int is_initialized;
@@ -205,9 +209,15 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
 					break;
 				    case 2:
 					new_l2 = this_leaf.size/1024;
+					num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
+					index_msb = get_count_order(num_threads_sharing);
+					l2_id = c->apicid >> index_msb;
 					break;
 				    case 3:
 					new_l3 = this_leaf.size/1024;
+					num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
+					index_msb = get_count_order(num_threads_sharing);
+					l3_id = c->apicid >> index_msb;
 					break;
 				    default:
 					break;
@@ -215,11 +225,19 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
 			}
 		}
 	}
-	if (c->cpuid_level > 1) {
+	/*
+	 * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
+	 * trace cache
+	 */
+	if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
 		/* supports eax=2  call */
 		int i, j, n;
 		int regs[4];
 		unsigned char *dp = (unsigned char *)regs;
+		int only_trace = 0;
+
+		if (num_cache_leaves != 0 && c->x86 == 15)
+			only_trace = 1;
 
 		/* Number of times to iterate */
 		n = cpuid_eax(2) & 0xFF;
@@ -241,6 +259,8 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
 				while (cache_table[k].descriptor != 0)
 				{
 					if (cache_table[k].descriptor == des) {
+						if (only_trace && cache_table[k].cache_type != LVL_TRACE)
+							break;
 						switch (cache_table[k].cache_type) {
 						case LVL_1_INST:
 							l1i += cache_table[k].size;
@@ -266,34 +286,45 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
 				}
 			}
 		}
+	}
 
-		if (new_l1d)
-			l1d = new_l1d;
+	if (new_l1d)
+		l1d = new_l1d;
 
-		if (new_l1i)
-			l1i = new_l1i;
+	if (new_l1i)
+		l1i = new_l1i;
 
-		if (new_l2)
-			l2 = new_l2;
+	if (new_l2) {
+		l2 = new_l2;
+#ifdef CONFIG_SMP
+		cpu_llc_id[cpu] = l2_id;
+#endif
+	}
 
-		if (new_l3)
-			l3 = new_l3;
+	if (new_l3) {
+		l3 = new_l3;
+#ifdef CONFIG_SMP
+		cpu_llc_id[cpu] = l3_id;
+#endif
+	}
 
-		if ( trace )
-			printk (KERN_INFO "CPU: Trace cache: %dK uops", trace);
-		else if ( l1i )
-			printk (KERN_INFO "CPU: L1 I cache: %dK", l1i);
-		if ( l1d )
-			printk(", L1 D cache: %dK\n", l1d);
-		else
-			printk("\n");
-		if ( l2 )
-			printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
-		if ( l3 )
-			printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
+	if (trace)
+		printk (KERN_INFO "CPU: Trace cache: %dK uops", trace);
+	else if ( l1i )
+		printk (KERN_INFO "CPU: L1 I cache: %dK", l1i);
 
-		c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
-	}
+	if (l1d)
+		printk(", L1 D cache: %dK\n", l1d);
+	else
+		printk("\n");
+
+	if (l2)
+		printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
+
+	if (l3)
+		printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
+
+	c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
 
 	return l2;
 }
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 311b4e7266f1..3b329af4afc5 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -381,7 +381,7 @@ static void do_irq_balance(void)
 	unsigned long imbalance = 0;
 	cpumask_t allowed_mask, target_cpu_mask, tmp;
 
-	for_each_cpu(i) {
+	for_each_possible_cpu(i) {
 		int package_index;
 		CPU_IRQ(i) = 0;
 		if (!cpu_online(i))
@@ -632,7 +632,7 @@ static int __init balanced_irq_init(void)
 	else 
 		printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq");
 failed:
-	for_each_cpu(i) {
+	for_each_possible_cpu(i) {
 		kfree(irq_cpu_data[i].irq_delta);
 		irq_cpu_data[i].irq_delta = NULL;
 		kfree(irq_cpu_data[i].last_irq);
diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c
index dd780a00553f..e7c138f66c5a 100644
--- a/arch/i386/kernel/microcode.c
+++ b/arch/i386/kernel/microcode.c
@@ -459,26 +459,9 @@ static ssize_t microcode_write (struct file *file, const char __user *buf, size_
 	return ret;
 }
 
-static int microcode_ioctl (struct inode *inode, struct file *file, 
-		unsigned int cmd, unsigned long arg)
-{
-	switch (cmd) {
-		/* 
-		 *  XXX: will be removed after microcode_ctl 
-		 *  is updated to ignore failure of this ioctl()
-		 */
-		case MICROCODE_IOCFREE:
-			return 0;
-		default:
-			return -EINVAL;
-	}
-	return -EINVAL;
-}
-
 static struct file_operations microcode_fops = {
 	.owner		= THIS_MODULE,
 	.write		= microcode_write,
-	.ioctl		= microcode_ioctl,
 	.open		= microcode_open,
 };
 
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index 9074818b9473..d43b498ec745 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -138,12 +138,12 @@ static int __init check_nmi_watchdog(void)
 	if (nmi_watchdog == NMI_LOCAL_APIC)
 		smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0);
 
-	for_each_cpu(cpu)
+	for_each_possible_cpu(cpu)
 		prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count;
 	local_irq_enable();
 	mdelay((10*1000)/nmi_hz); // wait 10 ticks
 
-	for_each_cpu(cpu) {
+	for_each_possible_cpu(cpu) {
 #ifdef CONFIG_SMP
 		/* Check cpu_callin_map here because that is set
 		   after the timer is started. */
@@ -510,7 +510,7 @@ void touch_nmi_watchdog (void)
 	 * Just reset the alert counters, (other CPUs might be
 	 * spinning on locks we hold):
 	 */
-	for_each_cpu(i)
+	for_each_possible_cpu(i)
 		alert_counter[i] = 0;
 
 	/*
@@ -529,7 +529,8 @@ void nmi_watchdog_tick (struct pt_regs * regs)
 	 * always switch the stack NMI-atomically, it's safe to use
 	 * smp_processor_id().
 	 */
-	int sum, cpu = smp_processor_id();
+	unsigned int sum;
+	int cpu = smp_processor_id();
 
 	sum = per_cpu(irq_stat, cpu).apic_timer_irqs;
 
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 6917daa159ab..8c08660b4e5d 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -46,6 +46,7 @@
 #include <linux/kexec.h>
 #include <linux/crash_dump.h>
 #include <linux/dmi.h>
+#include <linux/pfn.h>
 
 #include <video/edid.h>
 
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 82371d83bfa9..a6969903f2d6 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -72,6 +72,9 @@ int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
 /* Core ID of each logical CPU */
 int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
 
+/* Last level cache ID of each logical CPU */
+int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};
+
 /* representing HT siblings of each logical CPU */
 cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
 EXPORT_SYMBOL(cpu_sibling_map);
@@ -440,6 +443,18 @@ static void __devinit smp_callin(void)
 
 static int cpucount;
 
+/* maps the cpu to the sched domain representing multi-core */
+cpumask_t cpu_coregroup_map(int cpu)
+{
+	struct cpuinfo_x86 *c = cpu_data + cpu;
+	/*
+	 * For perf, we return last level cache shared map.
+	 * TBD: when power saving sched policy is added, we will return
+	 *      cpu_core_map when power saving policy is enabled
+	 */
+	return c->llc_shared_map;
+}
+
 /* representing cpus for which sibling maps can be computed */
 static cpumask_t cpu_sibling_setup_map;
 
@@ -459,12 +474,16 @@ set_cpu_sibling_map(int cpu)
 				cpu_set(cpu, cpu_sibling_map[i]);
 				cpu_set(i, cpu_core_map[cpu]);
 				cpu_set(cpu, cpu_core_map[i]);
+				cpu_set(i, c[cpu].llc_shared_map);
+				cpu_set(cpu, c[i].llc_shared_map);
 			}
 		}
 	} else {
 		cpu_set(cpu, cpu_sibling_map[cpu]);
 	}
 
+	cpu_set(cpu, c[cpu].llc_shared_map);
+
 	if (current_cpu_data.x86_max_cores == 1) {
 		cpu_core_map[cpu] = cpu_sibling_map[cpu];
 		c[cpu].booted_cores = 1;
@@ -472,6 +491,11 @@ set_cpu_sibling_map(int cpu)
 	}
 
 	for_each_cpu_mask(i, cpu_sibling_setup_map) {
+		if (cpu_llc_id[cpu] != BAD_APICID &&
+		    cpu_llc_id[cpu] == cpu_llc_id[i]) {
+			cpu_set(i, c[cpu].llc_shared_map);
+			cpu_set(cpu, c[i].llc_shared_map);
+		}
 		if (phys_proc_id[cpu] == phys_proc_id[i]) {
 			cpu_set(i, cpu_core_map[cpu]);
 			cpu_set(cpu, cpu_core_map[i]);
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
index ac687d00a1ce..326595f3fa4d 100644
--- a/arch/i386/kernel/syscall_table.S
+++ b/arch/i386/kernel/syscall_table.S
@@ -310,3 +310,5 @@ ENTRY(sys_call_table)
 	.long sys_pselect6
 	.long sys_ppoll
 	.long sys_unshare		/* 310 */
+	.long sys_set_robust_list
+	.long sys_get_robust_list
diff --git a/arch/i386/kernel/timers/timer_pm.c b/arch/i386/kernel/timers/timer_pm.c
index 264edaaac315..144e94a04933 100644
--- a/arch/i386/kernel/timers/timer_pm.c
+++ b/arch/i386/kernel/timers/timer_pm.c
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/pci.h>
 #include <asm/types.h>
 #include <asm/timer.h>
 #include <asm/smp.h>
@@ -45,24 +46,31 @@ static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
 
 #define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */
 
+static int pmtmr_need_workaround __read_mostly = 1;
+
 /*helper function to safely read acpi pm timesource*/
 static inline u32 read_pmtmr(void)
 {
-	u32 v1=0,v2=0,v3=0;
-	/* It has been reported that because of various broken
-	 * chipsets (ICH4, PIIX4 and PIIX4E) where the ACPI PM time
-	 * source is not latched, so you must read it multiple
-	 * times to insure a safe value is read.
-	 */
-	do {
-		v1 = inl(pmtmr_ioport);
-		v2 = inl(pmtmr_ioport);
-		v3 = inl(pmtmr_ioport);
-	} while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
-			|| (v3 > v1 && v3 < v2));
-
-	/* mask the output to 24 bits */
-	return v2 & ACPI_PM_MASK;
+	if (pmtmr_need_workaround) {
+		u32 v1, v2, v3;
+
+		/* It has been reported that because of various broken
+		 * chipsets (ICH4, PIIX4 and PIIX4E) where the ACPI PM time
+		 * source is not latched, so you must read it multiple
+		 * times to insure a safe value is read.
+		 */
+		do {
+			v1 = inl(pmtmr_ioport);
+			v2 = inl(pmtmr_ioport);
+			v3 = inl(pmtmr_ioport);
+		} while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
+			 || (v3 > v1 && v3 < v2));
+
+		/* mask the output to 24 bits */
+		return v2 & ACPI_PM_MASK;
+	}
+
+	return inl(pmtmr_ioport) & ACPI_PM_MASK;
 }
 
 
@@ -263,6 +271,72 @@ struct init_timer_opts __initdata timer_pmtmr_init = {
 	.opts = &timer_pmtmr,
 };
 
+#ifdef CONFIG_PCI
+/*
+ * PIIX4 Errata:
+ *
+ * The power management timer may return improper results when read.
+ * Although the timer value settles properly after incrementing,
+ * while incrementing there is a 3 ns window every 69.8 ns where the
+ * timer value is indeterminate (a 4.2% chance that the data will be
+ * incorrect when read). As a result, the ACPI free running count up
+ * timer specification is violated due to erroneous reads.
+ */
+static int __init pmtmr_bug_check(void)
+{
+	static struct pci_device_id gray_list[] __initdata = {
+		/* these chipsets may have bug. */
+		{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
+				PCI_DEVICE_ID_INTEL_82801DB_0) },
+		{ },
+	};
+	struct pci_dev *dev;
+	int pmtmr_has_bug = 0;
+	u8 rev;
+
+	if (cur_timer != &timer_pmtmr || !pmtmr_need_workaround)
+		return 0;
+
+	dev = pci_get_device(PCI_VENDOR_ID_INTEL,
+			     PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
+	if (dev) {
+		pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
+		/* the bug has been fixed in PIIX4M */
+		if (rev < 3) {
+			printk(KERN_WARNING "* Found PM-Timer Bug on this "
+				"chipset. Due to workarounds for a bug,\n"
+				"* this time source is slow.  Consider trying "
+				"other time sources (clock=)\n");
+			pmtmr_has_bug = 1;
+		}
+		pci_dev_put(dev);
+	}
+
+	if (pci_dev_present(gray_list)) {
+		printk(KERN_WARNING "* This chipset may have PM-Timer Bug.  Due"
+			" to workarounds for a bug,\n"
+			"* this time source is slow. If you are sure your timer"
+			" does not have\n"
+			"* this bug, please use \"pmtmr_good\" to disable the "
+			"workaround\n");
+		pmtmr_has_bug = 1;
+	}
+
+	if (!pmtmr_has_bug)
+		pmtmr_need_workaround = 0;
+
+	return 0;
+}
+device_initcall(pmtmr_bug_check);
+#endif
+
+static int __init pmtr_good_setup(char *__str)
+{
+	pmtmr_need_workaround = 0;
+	return 1;
+}
+__setup("pmtmr_good", pmtr_good_setup);
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
 MODULE_DESCRIPTION("Power Management Timer (PMTMR) as primary timing source for x86");
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 4624f8ca2459..6b63a5aa1e46 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -92,22 +92,21 @@ asmlinkage void spurious_interrupt_bug(void);
 asmlinkage void machine_check(void);
 
 static int kstack_depth_to_print = 24;
-struct notifier_block *i386die_chain;
-static DEFINE_SPINLOCK(die_notifier_lock);
+ATOMIC_NOTIFIER_HEAD(i386die_chain);
 
 int register_die_notifier(struct notifier_block *nb)
 {
-	int err = 0;
-	unsigned long flags;
-
 	vmalloc_sync_all();
-	spin_lock_irqsave(&die_notifier_lock, flags);
-	err = notifier_chain_register(&i386die_chain, nb);
-	spin_unlock_irqrestore(&die_notifier_lock, flags);
-	return err;
+	return atomic_notifier_chain_register(&i386die_chain, nb);
 }
 EXPORT_SYMBOL(register_die_notifier);
 
+int unregister_die_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_unregister(&i386die_chain, nb);
+}
+EXPORT_SYMBOL(unregister_die_notifier);
+
 static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
 {
 	return	p > (void *)tinfo &&
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
index 8165626a5c30..70e560a1b79a 100644
--- a/arch/i386/mach-voyager/voyager_smp.c
+++ b/arch/i386/mach-voyager/voyager_smp.c
@@ -1700,7 +1700,7 @@ after_handle_vic_irq(unsigned int irq)
 
 			printk("VOYAGER SMP: CPU%d lost interrupt %d\n",
 			       cpu, irq);
-			for_each_cpu(real_cpu, mask) {
+			for_each_possible_cpu(real_cpu, mask) {
 
 				outb(VIC_CPU_MASQUERADE_ENABLE | real_cpu,
 				     VIC_PROCESSOR_ID);
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
index c4af9638dbfa..fe6eb901326e 100644
--- a/arch/i386/mm/discontig.c
+++ b/arch/i386/mm/discontig.c
@@ -31,6 +31,7 @@
 #include <linux/nodemask.h>
 #include <linux/module.h>
 #include <linux/kexec.h>
+#include <linux/pfn.h>
 
 #include <asm/e820.h>
 #include <asm/setup.h>
@@ -352,17 +353,6 @@ void __init zone_sizes_init(void)
 {
 	int nid;
 
-	/*
-	 * Insert nodes into pgdat_list backward so they appear in order.
-	 * Clobber node 0's links and NULL out pgdat_list before starting.
-	 */
-	pgdat_list = NULL;
-	for (nid = MAX_NUMNODES - 1; nid >= 0; nid--) {
-		if (!node_online(nid))
-			continue;
-		NODE_DATA(nid)->pgdat_next = pgdat_list;
-		pgdat_list = NODE_DATA(nid);
-	}
 
 	for_each_online_node(nid) {
 		unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c
index 9db3242103be..2889567e21a1 100644
--- a/arch/i386/mm/pgtable.c
+++ b/arch/i386/mm/pgtable.c
@@ -36,7 +36,7 @@ void show_mem(void)
 	printk(KERN_INFO "Mem-info:\n");
 	show_free_areas();
 	printk(KERN_INFO "Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
-	for_each_pgdat(pgdat) {
+	for_each_online_pgdat(pgdat) {
 		pgdat_resize_lock(pgdat, &flags);
 		for (i = 0; i < pgdat->node_spanned_pages; ++i) {
 			page = pgdat_page_nr(pgdat, i);
diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
index 1accce50c2c7..1a2076ce6f6a 100644
--- a/arch/i386/oprofile/nmi_int.c
+++ b/arch/i386/oprofile/nmi_int.c
@@ -122,7 +122,7 @@ static void nmi_save_registers(void * dummy)
 static void free_msrs(void)
 {
 	int i;
-	for_each_cpu(i) {
+	for_each_possible_cpu(i) {
 		kfree(cpu_msrs[i].counters);
 		cpu_msrs[i].counters = NULL;
 		kfree(cpu_msrs[i].controls);
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index dabd6c32641e..7c1ddc8ac443 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -30,19 +30,19 @@ extern spinlock_t timerlist_lock;
 fpswa_interface_t *fpswa_interface;
 EXPORT_SYMBOL(fpswa_interface);
 
-struct notifier_block *ia64die_chain;
+ATOMIC_NOTIFIER_HEAD(ia64die_chain);
 
 int
 register_die_notifier(struct notifier_block *nb)
 {
-	return notifier_chain_register(&ia64die_chain, nb);
+	return atomic_notifier_chain_register(&ia64die_chain, nb);
 }
 EXPORT_SYMBOL_GPL(register_die_notifier);
 
 int
 unregister_die_notifier(struct notifier_block *nb)
 {
-	return notifier_chain_unregister(&ia64die_chain, nb);
+	return atomic_notifier_chain_unregister(&ia64die_chain, nb);
 }
 EXPORT_SYMBOL_GPL(unregister_die_notifier);
 
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index 2f5e44862e91..ec9eeb89975d 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -379,31 +379,6 @@ static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize)
 }
 
 /**
- * pgdat_insert - insert the pgdat into global pgdat_list
- * @pgdat: the pgdat for a node.
- */
-static void __init pgdat_insert(pg_data_t *pgdat)
-{
-	pg_data_t *prev = NULL, *next;
-
-	for_each_pgdat(next)
-		if (pgdat->node_id < next->node_id)
-			break;
-		else
-			prev = next;
-
-	if (prev) {
-		prev->pgdat_next = pgdat;
-		pgdat->pgdat_next = next;
-	} else {
-		pgdat->pgdat_next = pgdat_list;
-		pgdat_list = pgdat;
-	}
-
-	return;
-}
-
-/**
  * memory_less_nodes - allocate and initialize CPU only nodes pernode
  *	information.
  */
@@ -560,7 +535,7 @@ void show_mem(void)
 	printk("Mem-info:\n");
 	show_free_areas();
 	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
-	for_each_pgdat(pgdat) {
+	for_each_online_pgdat(pgdat) {
 		unsigned long present;
 		unsigned long flags;
 		int shared = 0, cached = 0, reserved = 0;
@@ -745,11 +720,5 @@ void __init paging_init(void)
 				    pfn_offset, zholes_size);
 	}
 
-	/*
-	 * Make memory less nodes become a member of the known nodes.
-	 */
-	for_each_node_mask(node, memory_less_mask)
-		pgdat_insert(mem_data[node].pgdat);
-
 	zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
 }
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index ff4f31fcd330..2ef1151cde90 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -600,7 +600,7 @@ mem_init (void)
 	kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START);
 	kclist_add(&kcore_kernel, _stext, _end - _stext);
 
-	for_each_pgdat(pgdat)
+	for_each_online_pgdat(pgdat)
 		if (pgdat->bdata->node_bootmem_map)
 			totalram_pages += free_all_bootmem_node(pgdat);
 
diff --git a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
index c686d9c12f7b..5100261310f7 100644
--- a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
+++ b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
@@ -93,19 +93,22 @@ static int coherence_id_open(struct inode *inode, struct file *file)
 static struct proc_dir_entry
 *sn_procfs_create_entry(const char *name, struct proc_dir_entry *parent,
 			int (*openfunc)(struct inode *, struct file *),
-			int (*releasefunc)(struct inode *, struct file *))
+	int (*releasefunc)(struct inode *, struct file *),
+	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *))
 {
 	struct proc_dir_entry *e = create_proc_entry(name, 0444, parent);
 
 	if (e) {
-		e->proc_fops = (struct file_operations *)kmalloc(
-			sizeof(struct file_operations), GFP_KERNEL);
-		if (e->proc_fops) {
-			memset(e->proc_fops, 0, sizeof(struct file_operations));
-			e->proc_fops->open = openfunc;
-			e->proc_fops->read = seq_read;
-			e->proc_fops->llseek = seq_lseek;
-			e->proc_fops->release = releasefunc;
+		struct file_operations *f;
+
+		f = kzalloc(sizeof(*f), GFP_KERNEL);
+		if (f) {
+			f->open = openfunc;
+			f->read = seq_read;
+			f->llseek = seq_lseek;
+			f->release = releasefunc;
+			f->write = write;
+			e->proc_fops = f;
 		}
 	}
 
@@ -119,31 +122,29 @@ extern int sn_topology_release(struct inode *, struct file *);
 void register_sn_procfs(void)
 {
 	static struct proc_dir_entry *sgi_proc_dir = NULL;
-	struct proc_dir_entry *e;
 
 	BUG_ON(sgi_proc_dir != NULL);
 	if (!(sgi_proc_dir = proc_mkdir("sgi_sn", NULL)))
 		return;
 
 	sn_procfs_create_entry("partition_id", sgi_proc_dir,
-			       partition_id_open, single_release);
+		partition_id_open, single_release, NULL);
 
 	sn_procfs_create_entry("system_serial_number", sgi_proc_dir,
-			       system_serial_number_open, single_release);
+		system_serial_number_open, single_release, NULL);
 
 	sn_procfs_create_entry("licenseID", sgi_proc_dir, 
-			       licenseID_open, single_release);
+		licenseID_open, single_release, NULL);
 
-	e = sn_procfs_create_entry("sn_force_interrupt", sgi_proc_dir, 
-				   sn_force_interrupt_open, single_release);
-	if (e) 
-		e->proc_fops->write = sn_force_interrupt_write_proc;
+	sn_procfs_create_entry("sn_force_interrupt", sgi_proc_dir,
+		sn_force_interrupt_open, single_release,
+		sn_force_interrupt_write_proc);
 
 	sn_procfs_create_entry("coherence_id", sgi_proc_dir, 
-			       coherence_id_open, single_release);
+		coherence_id_open, single_release, NULL);
 	
 	sn_procfs_create_entry("sn_topology", sgi_proc_dir,
-			       sn_topology_open, sn_topology_release);
+		sn_topology_open, sn_topology_release, NULL);
 }
 
 #endif /* CONFIG_PROC_FS */
diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c
index d742037a7ccb..0d78942b4c76 100644
--- a/arch/m32r/kernel/setup.c
+++ b/arch/m32r/kernel/setup.c
@@ -24,6 +24,7 @@
 #include <linux/tty.h>
 #include <linux/cpu.h>
 #include <linux/nodemask.h>
+#include <linux/pfn.h>
 
 #include <asm/processor.h>
 #include <asm/pgtable.h>
diff --git a/arch/m32r/mm/discontig.c b/arch/m32r/mm/discontig.c
index 08e727955555..cf610a7c5ff0 100644
--- a/arch/m32r/mm/discontig.c
+++ b/arch/m32r/mm/discontig.c
@@ -13,6 +13,7 @@
 #include <linux/initrd.h>
 #include <linux/nodemask.h>
 #include <linux/module.h>
+#include <linux/pfn.h>
 
 #include <asm/setup.h>
 
@@ -137,12 +138,6 @@ unsigned long __init zone_sizes_init(void)
 	int nid, i;
 	mem_prof_t *mp;
 
-	pgdat_list = NULL;
-	for (nid = num_online_nodes() - 1 ; nid >= 0 ; nid--) {
-		NODE_DATA(nid)->pgdat_next = pgdat_list;
-		pgdat_list = NODE_DATA(nid);
-	}
-
 	for_each_online_node(nid) {
 		mp = &mem_prof[nid];
 		for (i = 0 ; i < MAX_NR_ZONES ; i++) {
diff --git a/arch/m32r/mm/init.c b/arch/m32r/mm/init.c
index c9e7dad860b7..b71348fec1f4 100644
--- a/arch/m32r/mm/init.c
+++ b/arch/m32r/mm/init.c
@@ -18,6 +18,7 @@
 #include <linux/highmem.h>
 #include <linux/bitops.h>
 #include <linux/nodemask.h>
+#include <linux/pfn.h>
 #include <asm/types.h>
 #include <asm/processor.h>
 #include <asm/page.h>
@@ -47,7 +48,7 @@ void show_mem(void)
 	printk("Mem-info:\n");
 	show_free_areas();
 	printk("Free swap:       %6ldkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
-	for_each_pgdat(pgdat) {
+	for_each_online_pgdat(pgdat) {
 		unsigned long flags;
 		pgdat_resize_lock(pgdat, &flags);
 		for (i = 0; i < pgdat->node_spanned_pages; ++i) {
diff --git a/arch/m68k/mvme16x/rtc.c b/arch/m68k/mvme16x/rtc.c
index a69fe3048edc..b0e4c084df8a 100644
--- a/arch/m68k/mvme16x/rtc.c
+++ b/arch/m68k/mvme16x/rtc.c
@@ -17,6 +17,7 @@
 #include <linux/poll.h>
 #include <linux/mc146818rtc.h>	/* For struct rtc_time and ioctls, etc */
 #include <linux/smp_lock.h>
+#include <linux/bcd.h>
 #include <asm/mvme16xhw.h>
 
 #include <asm/io.h>
@@ -31,9 +32,6 @@
  *	ioctls.
  */
 
-#define BCD2BIN(val) (((val)&15) + ((val)>>4)*10)
-#define BIN2BCD(val) ((((val)/10)<<4) + (val)%10)
-
 static const unsigned char days_in_mo[] =
 {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c
index 1080558c8100..307e98c29ddc 100644
--- a/arch/mips/au1000/common/setup.c
+++ b/arch/mips/au1000/common/setup.c
@@ -94,7 +94,7 @@ void __init plat_setup(void)
 
 	argptr = prom_getcmdline();
 
-#if defined(CONFIG_SERIAL_AU1X00_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE)
+#ifdef CONFIG_SERIAL_8250_CONSOLE
 	if ((argptr = strstr(argptr, "console=")) == NULL) {
 		argptr = prom_getcmdline();
 		strcat(argptr, " console=ttyS0,115200");
diff --git a/arch/mips/ddb5xxx/common/rtc_ds1386.c b/arch/mips/ddb5xxx/common/rtc_ds1386.c
index 995896ac0e39..5dc34daa7150 100644
--- a/arch/mips/ddb5xxx/common/rtc_ds1386.c
+++ b/arch/mips/ddb5xxx/common/rtc_ds1386.c
@@ -165,6 +165,6 @@ rtc_ds1386_init(unsigned long base)
 	WRITE_RTC(0xB, byte);
 
 	/* set the function pointers */
-	rtc_get_time = rtc_ds1386_get_time;
-	rtc_set_time = rtc_ds1386_set_time;
+	rtc_mips_get_time = rtc_ds1386_get_time;
+	rtc_mips_set_time = rtc_ds1386_set_time;
 }
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c
index 174822344131..74cb055d4bf6 100644
--- a/arch/mips/dec/time.c
+++ b/arch/mips/dec/time.c
@@ -36,41 +36,13 @@
 #include <asm/dec/ioasic_addrs.h>
 #include <asm/dec/machtype.h>
 
-
-/*
- * Returns true if a clock update is in progress
- */
-static inline unsigned char dec_rtc_is_updating(void)
-{
-	unsigned char uip;
-	unsigned long flags;
-
-	spin_lock_irqsave(&rtc_lock, flags);
-	uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
-	spin_unlock_irqrestore(&rtc_lock, flags);
-	return uip;
-}
-
 static unsigned long dec_rtc_get_time(void)
 {
 	unsigned int year, mon, day, hour, min, sec, real_year;
-	int i;
 	unsigned long flags;
 
-	/* The Linux interpretation of the DS1287 clock register contents:
-	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
-	 * RTC registers show the second which has precisely just started.
-	 * Let's hope other operating systems interpret the RTC the same way.
-	 */
-	/* read RTC exactly on falling edge of update flag */
-	for (i = 0; i < 1000000; i++)	/* may take up to 1 second... */
-		if (dec_rtc_is_updating())
-			break;
-	for (i = 0; i < 1000000; i++)	/* must try at least 2.228 ms */
-		if (!dec_rtc_is_updating())
-			break;
 	spin_lock_irqsave(&rtc_lock, flags);
-	/* Isn't this overkill?  UIP above should guarantee consistency */
+
 	do {
 		sec = CMOS_READ(RTC_SECONDS);
 		min = CMOS_READ(RTC_MINUTES);
@@ -78,7 +50,16 @@ static unsigned long dec_rtc_get_time(void)
 		day = CMOS_READ(RTC_DAY_OF_MONTH);
 		mon = CMOS_READ(RTC_MONTH);
 		year = CMOS_READ(RTC_YEAR);
+		/*
+		 * The PROM will reset the year to either '72 or '73.
+		 * Therefore we store the real year separately, in one
+		 * of unused BBU RAM locations.
+		 */
+		real_year = CMOS_READ(RTC_DEC_YEAR);
 	} while (sec != CMOS_READ(RTC_SECONDS));
+
+	spin_unlock_irqrestore(&rtc_lock, flags);
+
 	if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
 		sec = BCD2BIN(sec);
 		min = BCD2BIN(min);
@@ -87,13 +68,7 @@ static unsigned long dec_rtc_get_time(void)
 		mon = BCD2BIN(mon);
 		year = BCD2BIN(year);
 	}
-	/*
-	 * The PROM will reset the year to either '72 or '73.
-	 * Therefore we store the real year separately, in one
-	 * of unused BBU RAM locations.
-	 */
-	real_year = CMOS_READ(RTC_DEC_YEAR);
-	spin_unlock_irqrestore(&rtc_lock, flags);
+
 	year += real_year - 72 + 2000;
 
 	return mktime(year, mon, day, hour, min, sec);
@@ -193,8 +168,8 @@ static void dec_ioasic_hpt_init(unsigned int count)
 
 void __init dec_time_init(void)
 {
-	rtc_get_time = dec_rtc_get_time;
-	rtc_set_mmss = dec_rtc_set_mmss;
+	rtc_mips_get_time = dec_rtc_get_time;
+	rtc_mips_set_mmss = dec_rtc_set_mmss;
 
 	mips_timer_state = dec_timer_state;
 	mips_timer_ack = dec_timer_ack;
diff --git a/arch/mips/ite-boards/generic/time.c b/arch/mips/ite-boards/generic/time.c
index f5d67ee21ac6..b79817bb6cce 100644
--- a/arch/mips/ite-boards/generic/time.c
+++ b/arch/mips/ite-boards/generic/time.c
@@ -227,8 +227,8 @@ void __init it8172_time_init(void)
 
 	local_irq_restore(flags);
 
-	rtc_get_time = it8172_rtc_get_time;
-	rtc_set_time = it8172_rtc_set_time;
+	rtc_mips_get_time = it8172_rtc_get_time;
+	rtc_mips_set_time = it8172_rtc_set_time;
 }
 
 #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
diff --git a/arch/mips/ite-boards/ivr/init.c b/arch/mips/ite-boards/ivr/init.c
index ea4e1935fec5..b774db035b31 100644
--- a/arch/mips/ite-boards/ivr/init.c
+++ b/arch/mips/ite-boards/ivr/init.c
@@ -45,9 +45,6 @@ extern void  __init prom_init_cmdline(void);
 extern unsigned long __init prom_get_memsize(void);
 extern void __init it8172_init_ram_resource(unsigned long memsize);
 
-#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define PFN_ALIGN(x)	(((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
-
 const char *get_system_type(void)
 {
 	return "Globespan IVR";
diff --git a/arch/mips/ite-boards/qed-4n-s01b/init.c b/arch/mips/ite-boards/qed-4n-s01b/init.c
index 56dca7e0c21d..e8ec8be66a80 100644
--- a/arch/mips/ite-boards/qed-4n-s01b/init.c
+++ b/arch/mips/ite-boards/qed-4n-s01b/init.c
@@ -45,9 +45,6 @@ extern void  __init prom_init_cmdline(void);
 extern unsigned long __init prom_get_memsize(void);
 extern void __init it8172_init_ram_resource(unsigned long memsize);
 
-#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define PFN_ALIGN(x)	(((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
-
 const char *get_system_type(void)
 {
 	return "ITE QED-4N-S01B";
diff --git a/arch/mips/jmr3927/common/rtc_ds1742.c b/arch/mips/jmr3927/common/rtc_ds1742.c
index 9a8bff153d80..a6bd3f4d3049 100644
--- a/arch/mips/jmr3927/common/rtc_ds1742.c
+++ b/arch/mips/jmr3927/common/rtc_ds1742.c
@@ -159,8 +159,8 @@ rtc_ds1742_init(unsigned long base)
 	db_assert((rtc_base & 0xe0000000) == KSEG1);
 
 	/* set the function pointers */
-	rtc_get_time = rtc_ds1742_get_time;
-	rtc_set_time = rtc_ds1742_set_time;
+	rtc_mips_get_time = rtc_ds1742_get_time;
+	rtc_mips_set_time = rtc_ds1742_set_time;
 
 	/* clear oscillator stop bit */
 	CMOS_WRITE(RTC_READ, RTC_CONTROL);
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 0cb3b6097e0e..dcbfd27071f0 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -34,6 +34,7 @@
 #include <linux/highmem.h>
 #include <linux/console.h>
 #include <linux/mmzone.h>
+#include <linux/pfn.h>
 
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
@@ -257,10 +258,6 @@ static inline int parse_rd_cmdline(unsigned long* rd_start, unsigned long* rd_en
 	return 0;
 }
 
-#define PFN_UP(x)	(((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
-#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x)	((x) << PAGE_SHIFT)
-
 #define MAXMEM		HIGHMEM_START
 #define MAXMEM_PFN	PFN_DOWN(MAXMEM)
 
@@ -493,10 +490,6 @@ static inline void resource_init(void)
 	}
 }
 
-#undef PFN_UP
-#undef PFN_DOWN
-#undef PFN_PHYS
-
 #undef MAXMEM
 #undef MAXMEM_PFN
 
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 51273b7297a7..5e51a2d8f3f0 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -65,9 +65,9 @@ static int null_rtc_set_time(unsigned long sec)
 	return 0;
 }
 
-unsigned long (*rtc_get_time)(void) = null_rtc_get_time;
-int (*rtc_set_time)(unsigned long) = null_rtc_set_time;
-int (*rtc_set_mmss)(unsigned long);
+unsigned long (*rtc_mips_get_time)(void) = null_rtc_get_time;
+int (*rtc_mips_set_time)(unsigned long) = null_rtc_set_time;
+int (*rtc_mips_set_mmss)(unsigned long);
 
 
 /* usecs per counter cycle, shifted to left by 32 bits */
@@ -440,14 +440,14 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 	/*
 	 * If we have an externally synchronized Linux clock, then update
-	 * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be
+	 * CMOS clock accordingly every ~11 minutes. rtc_mips_set_time() has to be
 	 * called as close as possible to 500 ms before the new second starts.
 	 */
 	if (ntp_synced() &&
 	    xtime.tv_sec > last_rtc_update + 660 &&
 	    (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
 	    (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
-		if (rtc_set_mmss(xtime.tv_sec) == 0) {
+		if (rtc_mips_set_mmss(xtime.tv_sec) == 0) {
 			last_rtc_update = xtime.tv_sec;
 		} else {
 			/* do it again in 60 s */
@@ -565,7 +565,7 @@ asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs)
  *      b) (optional) calibrate and set the mips_hpt_frequency
  *	    (only needed if you intended to use fixed_rate_gettimeoffset
  *	     or use cpu counter as timer interrupt source)
- * 2) setup xtime based on rtc_get_time().
+ * 2) setup xtime based on rtc_mips_get_time().
  * 3) choose a appropriate gettimeoffset routine.
  * 4) calculate a couple of cached variables for later usage
  * 5) board_timer_setup() -
@@ -633,10 +633,10 @@ void __init time_init(void)
 	if (board_time_init)
 		board_time_init();
 
-	if (!rtc_set_mmss)
-		rtc_set_mmss = rtc_set_time;
+	if (!rtc_mips_set_mmss)
+		rtc_mips_set_mmss = rtc_mips_set_time;
 
-	xtime.tv_sec = rtc_get_time();
+	xtime.tv_sec = rtc_mips_get_time();
 	xtime.tv_nsec = 0;
 
 	set_normalized_timespec(&wall_to_monotonic,
@@ -772,8 +772,8 @@ void to_tm(unsigned long tim, struct rtc_time *tm)
 
 EXPORT_SYMBOL(rtc_lock);
 EXPORT_SYMBOL(to_tm);
-EXPORT_SYMBOL(rtc_set_time);
-EXPORT_SYMBOL(rtc_get_time);
+EXPORT_SYMBOL(rtc_mips_set_time);
+EXPORT_SYMBOL(rtc_mips_get_time);
 
 unsigned long long sched_clock(void)
 {
diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c
index 83eb08b7a072..bb70a8240e61 100644
--- a/arch/mips/lasat/setup.c
+++ b/arch/mips/lasat/setup.c
@@ -165,7 +165,8 @@ void __init plat_setup(void)
 
 	/* Set up panic notifier */
 	for (i = 0; i < sizeof(lasat_panic_block) / sizeof(struct notifier_block); i++)
-		notifier_chain_register(&panic_notifier_list, &lasat_panic_block[i]);
+		atomic_notifier_chain_register(&panic_notifier_list,
+				&lasat_panic_block[i]);
 
 	lasat_reboot_setup();
 
@@ -174,8 +175,8 @@ void __init plat_setup(void)
 
 #ifdef CONFIG_DS1603
 	ds1603 = &ds_defs[mips_machtype];
-	rtc_get_time = ds1603_read;
-	rtc_set_time = ds1603_set;
+	rtc_mips_get_time = ds1603_read;
+	rtc_mips_set_time = ds1603_set;
 #endif
 
 #ifdef DYNAMIC_SERIAL_INIT
diff --git a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c
index 873cf3141a31..c20d401ecf80 100644
--- a/arch/mips/mips-boards/atlas/atlas_setup.c
+++ b/arch/mips/mips-boards/atlas/atlas_setup.c
@@ -65,7 +65,7 @@ void __init plat_setup(void)
 
 	board_time_init = mips_time_init;
 	board_timer_setup = mips_timer_setup;
-	rtc_get_time = mips_rtc_get_time;
+	rtc_mips_get_time = mips_rtc_get_time;
 }
 
 static void __init serial_init(void)
diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c
index ee5e70c95cf3..32c9210373ac 100644
--- a/arch/mips/mips-boards/generic/memory.c
+++ b/arch/mips/mips-boards/generic/memory.c
@@ -49,9 +49,6 @@ static char *mtypes[3] = {
 /* References to section boundaries */
 extern char _end;
 
-#define PFN_ALIGN(x)    (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
-
-
 struct prom_pmemblock * __init prom_getmdesc(void)
 {
 	char *memsize_str;
@@ -109,10 +106,10 @@ struct prom_pmemblock * __init prom_getmdesc(void)
 
 	mdesc[3].type = yamon_dontuse;
 	mdesc[3].base = 0x00100000;
-	mdesc[3].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[3].base;
+	mdesc[3].size = CPHYSADDR(PAGE_ALIGN(&_end)) - mdesc[3].base;
 
 	mdesc[4].type = yamon_free;
-	mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end));
+	mdesc[4].base = CPHYSADDR(PAGE_ALIGN(&_end));
 	mdesc[4].size = memsize - mdesc[4].base;
 
 	return &mdesc[0];
diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c
index 2209e8a9de34..b8488aab6df1 100644
--- a/arch/mips/mips-boards/malta/malta_setup.c
+++ b/arch/mips/mips-boards/malta/malta_setup.c
@@ -225,5 +225,5 @@ void __init plat_setup(void)
 
 	board_time_init = mips_time_init;
 	board_timer_setup = mips_timer_setup;
-	rtc_get_time = mips_rtc_get_time;
+	rtc_mips_get_time = mips_rtc_get_time;
 }
diff --git a/arch/mips/mips-boards/sim/sim_mem.c b/arch/mips/mips-boards/sim/sim_mem.c
index 1ec4e75656bd..e57f737bab10 100644
--- a/arch/mips/mips-boards/sim/sim_mem.c
+++ b/arch/mips/mips-boards/sim/sim_mem.c
@@ -42,9 +42,6 @@ static char *mtypes[3] = {
 /* References to section boundaries */
 extern char _end;
 
-#define PFN_ALIGN(x)    (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
-
-
 struct prom_pmemblock * __init prom_getmdesc(void)
 {
 	unsigned int memsize;
@@ -64,10 +61,10 @@ struct prom_pmemblock * __init prom_getmdesc(void)
 
 	mdesc[2].type = simmem_reserved;
 	mdesc[2].base = 0x00100000;
-	mdesc[2].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[2].base;
+	mdesc[2].size = CPHYSADDR(PAGE_ALIGN(&_end)) - mdesc[2].base;
 
 	mdesc[3].type = simmem_free;
-	mdesc[3].base = CPHYSADDR(PFN_ALIGN(&_end));
+	mdesc[3].base = CPHYSADDR(PAGE_ALIGN(&_end));
 	mdesc[3].size = memsize - mdesc[3].base;
 
 	return &mdesc[0];
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 52f7d59fe612..ad89c442f299 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -25,6 +25,7 @@
 #include <linux/highmem.h>
 #include <linux/swap.h>
 #include <linux/proc_fs.h>
+#include <linux/pfn.h>
 
 #include <asm/bootinfo.h>
 #include <asm/cachectl.h>
@@ -177,9 +178,6 @@ void __init paging_init(void)
 	free_area_init(zones_size);
 }
 
-#define PFN_UP(x)	(((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
-#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
-
 static inline int page_is_ram(unsigned long pagenr)
 {
 	int i;
diff --git a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c
index 3784c898db1a..91d9637143d7 100644
--- a/arch/mips/momentum/jaguar_atx/setup.c
+++ b/arch/mips/momentum/jaguar_atx/setup.c
@@ -229,8 +229,8 @@ void momenco_time_init(void)
 	mips_hpt_frequency = cpu_clock / 2;
 	board_timer_setup = momenco_timer_setup;
 
-	rtc_get_time = m48t37y_get_time;
-	rtc_set_time = m48t37y_set_time;
+	rtc_mips_get_time = m48t37y_get_time;
+	rtc_mips_set_time = m48t37y_set_time;
 }
 
 static struct resource mv_pci_io_mem0_resource = {
diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c
index f95677f4f06f..370e75d0e75c 100644
--- a/arch/mips/momentum/ocelot_3/setup.c
+++ b/arch/mips/momentum/ocelot_3/setup.c
@@ -58,6 +58,7 @@
 #include <linux/bootmem.h>
 #include <linux/mv643xx.h>
 #include <linux/pm.h>
+#include <linux/bcd.h>
 
 #include <asm/time.h>
 #include <asm/page.h>
@@ -131,9 +132,6 @@ void setup_wired_tlb_entries(void)
 	add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), (signed)0xfc000000, PM_16M);
 }
 
-#define CONV_BCD_TO_BIN(val)	(((val) & 0xf) + (((val) >> 4) * 10))
-#define CONV_BIN_TO_BCD(val)	(((val) % 10) + (((val) / 10) << 4))
-
 unsigned long m48t37y_get_time(void)
 {
 	unsigned int year, month, day, hour, min, sec;
@@ -143,16 +141,16 @@ unsigned long m48t37y_get_time(void)
 	/* stop the update */
 	rtc_base[0x7ff8] = 0x40;
 
-	year = CONV_BCD_TO_BIN(rtc_base[0x7fff]);
-	year += CONV_BCD_TO_BIN(rtc_base[0x7ff1]) * 100;
+	year = BCD2BIN(rtc_base[0x7fff]);
+	year += BCD2BIN(rtc_base[0x7ff1]) * 100;
 
-	month = CONV_BCD_TO_BIN(rtc_base[0x7ffe]);
+	month = BCD2BIN(rtc_base[0x7ffe]);
 
-	day = CONV_BCD_TO_BIN(rtc_base[0x7ffd]);
+	day = BCD2BIN(rtc_base[0x7ffd]);
 
-	hour = CONV_BCD_TO_BIN(rtc_base[0x7ffb]);
-	min = CONV_BCD_TO_BIN(rtc_base[0x7ffa]);
-	sec = CONV_BCD_TO_BIN(rtc_base[0x7ff9]);
+	hour = BCD2BIN(rtc_base[0x7ffb]);
+	min = BCD2BIN(rtc_base[0x7ffa]);
+	sec = BCD2BIN(rtc_base[0x7ff9]);
 
 	/* start the update */
 	rtc_base[0x7ff8] = 0x00;
@@ -175,22 +173,22 @@ int m48t37y_set_time(unsigned long sec)
 	rtc_base[0x7ff8] = 0x80;
 
 	/* year */
-	rtc_base[0x7fff] = CONV_BIN_TO_BCD(tm.tm_year % 100);
-	rtc_base[0x7ff1] = CONV_BIN_TO_BCD(tm.tm_year / 100);
+	rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100);
+	rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100);
 
 	/* month */
-	rtc_base[0x7ffe] = CONV_BIN_TO_BCD(tm.tm_mon);
+	rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon);
 
 	/* day */
-	rtc_base[0x7ffd] = CONV_BIN_TO_BCD(tm.tm_mday);
+	rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday);
 
 	/* hour/min/sec */
-	rtc_base[0x7ffb] = CONV_BIN_TO_BCD(tm.tm_hour);
-	rtc_base[0x7ffa] = CONV_BIN_TO_BCD(tm.tm_min);
-	rtc_base[0x7ff9] = CONV_BIN_TO_BCD(tm.tm_sec);
+	rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour);
+	rtc_base[0x7ffa] = BIN2BCD(tm.tm_min);
+	rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec);
 
 	/* day of week -- not really used, but let's keep it up-to-date */
-	rtc_base[0x7ffc] = CONV_BIN_TO_BCD(tm.tm_wday + 1);
+	rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1);
 
 	/* disable writing */
 	rtc_base[0x7ff8] = 0x00;
@@ -215,8 +213,8 @@ void momenco_time_init(void)
 	mips_hpt_frequency = cpu_clock / 2;
 	board_timer_setup = momenco_timer_setup;
 
-	rtc_get_time = m48t37y_get_time;
-	rtc_set_time = m48t37y_set_time;
+	rtc_mips_get_time = m48t37y_get_time;
+	rtc_mips_set_time = m48t37y_set_time;
 }
 
 /*
diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c
index bd02e60d037a..a3e6f5575592 100644
--- a/arch/mips/momentum/ocelot_c/setup.c
+++ b/arch/mips/momentum/ocelot_c/setup.c
@@ -227,8 +227,8 @@ void momenco_time_init(void)
 	printk("momenco_time_init cpu_clock=%d\n", cpu_clock);
 	board_timer_setup = momenco_timer_setup;
 
-	rtc_get_time = m48t37y_get_time;
-	rtc_set_time = m48t37y_set_time;
+	rtc_mips_get_time = m48t37y_get_time;
+	rtc_mips_set_time = m48t37y_set_time;
 }
 
 void __init plat_setup(void)
diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c
index 8bce711575de..3f724d661bdb 100644
--- a/arch/mips/pmc-sierra/yosemite/setup.c
+++ b/arch/mips/pmc-sierra/yosemite/setup.c
@@ -198,8 +198,8 @@ static void __init py_rtc_setup(void)
 	if (!m48t37_base)
 		printk(KERN_ERR "Mapping the RTC failed\n");
 
-	rtc_get_time = m48t37y_get_time;
-	rtc_set_time = m48t37y_set_time;
+	rtc_mips_get_time = m48t37y_get_time;
+	rtc_mips_set_time = m48t37y_set_time;
 
 	write_seqlock(&xtime_lock);
 	xtime.tv_sec = m48t37y_get_time();
diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c
index 92a3b3c15ed3..a9c58e067b53 100644
--- a/arch/mips/sgi-ip22/ip22-reset.c
+++ b/arch/mips/sgi-ip22/ip22-reset.c
@@ -238,7 +238,7 @@ static int __init reboot_setup(void)
 	request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL);
 	init_timer(&blink_timer);
 	blink_timer.function = blink_timeout;
-	notifier_chain_register(&panic_notifier_list, &panic_block);
+	atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
 
 	return 0;
 }
diff --git a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c
index b7300cc5c5ad..cca688ad64ad 100644
--- a/arch/mips/sgi-ip22/ip22-time.c
+++ b/arch/mips/sgi-ip22/ip22-time.c
@@ -212,8 +212,8 @@ static void indy_timer_setup(struct irqaction *irq)
 void __init ip22_time_init(void)
 {
 	/* setup hookup functions */
-	rtc_get_time = indy_rtc_get_time;
-	rtc_set_time = indy_rtc_set_time;
+	rtc_mips_get_time = indy_rtc_get_time;
+	rtc_mips_set_time = indy_rtc_set_time;
 
 	board_time_init = indy_time_init;
 	board_timer_setup = indy_timer_setup;
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c
index e0d095daa5ed..6c00dce9f73f 100644
--- a/arch/mips/sgi-ip27/ip27-memory.c
+++ b/arch/mips/sgi-ip27/ip27-memory.c
@@ -19,6 +19,7 @@
 #include <linux/nodemask.h>
 #include <linux/swap.h>
 #include <linux/bootmem.h>
+#include <linux/pfn.h>
 #include <asm/page.h>
 #include <asm/sections.h>
 
@@ -28,8 +29,6 @@
 #include <asm/sn/sn_private.h>
 
 
-#define PFN_UP(x)		(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-
 #define SLOT_PFNSHIFT           (SLOT_SHIFT - PAGE_SHIFT)
 #define PFN_NASIDSHFT           (NASID_SHFT - PAGE_SHIFT)
 
diff --git a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c
index 0c948008b023..ab9d9cef089e 100644
--- a/arch/mips/sgi-ip32/ip32-reset.c
+++ b/arch/mips/sgi-ip32/ip32-reset.c
@@ -193,7 +193,7 @@ static __init int ip32_reboot_setup(void)
 
 	init_timer(&blink_timer);
 	blink_timer.function = blink_timeout;
-	notifier_chain_register(&panic_notifier_list, &panic_block);
+	atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
 
 	request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL);
 
diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c
index 2f50c79b7887..a2dd8ae1ea8f 100644
--- a/arch/mips/sgi-ip32/ip32-setup.c
+++ b/arch/mips/sgi-ip32/ip32-setup.c
@@ -91,8 +91,8 @@ void __init plat_setup(void)
 {
 	board_be_init = ip32_be_init;
 
-	rtc_get_time = mc146818_get_cmos_time;
-	rtc_set_mmss = mc146818_set_rtc_mmss;
+	rtc_mips_get_time = mc146818_get_cmos_time;
+	rtc_mips_set_mmss = mc146818_set_rtc_mmss;
 
 	board_time_init = ip32_time_init;
 	board_timer_setup = ip32_timer_setup;
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index b661d2425a36..4b5f74ff3edd 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -121,14 +121,14 @@ void __init plat_setup(void)
 
 	if (xicor_probe()) {
 		printk("swarm setup: Xicor 1241 RTC detected.\n");
-		rtc_get_time = xicor_get_time;
-		rtc_set_time = xicor_set_time;
+		rtc_mips_get_time = xicor_get_time;
+		rtc_mips_set_time = xicor_set_time;
 	}
 
 	if (m41t81_probe()) {
 		printk("swarm setup: M41T81 RTC detected.\n");
-		rtc_get_time = m41t81_get_time;
-		rtc_set_time = m41t81_set_time;
+		rtc_mips_get_time = m41t81_get_time;
+		rtc_mips_set_time = m41t81_set_time;
 	}
 
 	printk("This kernel optimized for "
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
index 1141fcd13a59..01ba6c581e3d 100644
--- a/arch/mips/sni/setup.c
+++ b/arch/mips/sni/setup.c
@@ -164,8 +164,8 @@ static struct pci_controller sni_controller = {
 
 static inline void sni_pcimt_time_init(void)
 {
-	rtc_get_time = mc146818_get_cmos_time;
-	rtc_set_time = mc146818_set_rtc_mmss;
+	rtc_mips_get_time = mc146818_get_cmos_time;
+	rtc_mips_set_time = mc146818_set_rtc_mmss;
 }
 
 void __init plat_setup(void)
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
index 2ad6401d2af4..6dcf077f61a0 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -1036,8 +1036,8 @@ toshiba_rbtx4927_time_init(void)
 
 #ifdef CONFIG_RTC_DS1742
 
-	rtc_get_time = rtc_ds1742_get_time;
-	rtc_set_time = rtc_ds1742_set_time;
+	rtc_mips_get_time = rtc_ds1742_get_time;
+	rtc_mips_set_time = rtc_ds1742_set_time;
 
 	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT,
 				       ":rtc_ds1742_init()-\n");
diff --git a/arch/mips/tx4938/common/rtc_rx5c348.c b/arch/mips/tx4938/common/rtc_rx5c348.c
index d249edbb6af4..07f782fc0725 100644
--- a/arch/mips/tx4938/common/rtc_rx5c348.c
+++ b/arch/mips/tx4938/common/rtc_rx5c348.c
@@ -14,6 +14,7 @@
 #include <linux/string.h>
 #include <linux/rtc.h>
 #include <linux/time.h>
+#include <linux/bcd.h>
 #include <asm/time.h>
 #include <asm/tx4938/spi.h>
 
@@ -77,17 +78,6 @@ spi_rtc_io(unsigned char *inbuf, unsigned char *outbuf, unsigned int count)
 			   inbufs, incounts, outbufs, outcounts, 0);
 }
 
-/*
- * Conversion between binary and BCD.
- */
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-#endif
-
 /* RTC-dependent code for time.c */
 
 static int
@@ -197,6 +187,6 @@ rtc_rx5c348_init(int chipid)
 		srtc_24h = 1;
 
 	/* set the function pointers */
-	rtc_get_time = rtc_rx5c348_get_time;
-	rtc_set_time = rtc_rx5c348_set_time;
+	rtc_mips_get_time = rtc_rx5c348_get_time;
+	rtc_mips_set_time = rtc_rx5c348_set_time;
 }
diff --git a/arch/parisc/kernel/pdc_chassis.c b/arch/parisc/kernel/pdc_chassis.c
index 2a01fe1bdc98..0cea6958f427 100644
--- a/arch/parisc/kernel/pdc_chassis.c
+++ b/arch/parisc/kernel/pdc_chassis.c
@@ -150,7 +150,8 @@ void __init parisc_pdc_chassis_init(void)
 
 		if (handle) {
 			/* initialize panic notifier chain */
-			notifier_chain_register(&panic_notifier_list, &pdc_chassis_panic_block);
+			atomic_notifier_chain_register(&panic_notifier_list,
+					&pdc_chassis_panic_block);
 
 			/* initialize reboot notifier chain */
 			register_reboot_notifier(&pdc_chassis_reboot_block);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 6aea1fb74b69..05b152299396 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -537,7 +537,8 @@ void __init setup_arch(char **cmdline_p)
 	panic_timeout = 180;
 
 	if (ppc_md.panic)
-		notifier_chain_register(&panic_notifier_list, &ppc64_panic_block);
+		atomic_notifier_chain_register(&panic_notifier_list,
+				&ppc64_panic_block);
 
 	init_mm.start_code = PAGE_OFFSET;
 	init_mm.end_code = (unsigned long) _etext;
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 27600c9432bc..4cbde211eb69 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -74,19 +74,19 @@ EXPORT_SYMBOL(__debugger_dabr_match);
 EXPORT_SYMBOL(__debugger_fault_handler);
 #endif
 
-struct notifier_block *powerpc_die_chain;
-static DEFINE_SPINLOCK(die_notifier_lock);
+ATOMIC_NOTIFIER_HEAD(powerpc_die_chain);
 
 int register_die_notifier(struct notifier_block *nb)
 {
-	int err = 0;
-	unsigned long flags;
+	return atomic_notifier_chain_register(&powerpc_die_chain, nb);
+}
+EXPORT_SYMBOL(register_die_notifier);
 
-	spin_lock_irqsave(&die_notifier_lock, flags);
-	err = notifier_chain_register(&powerpc_die_chain, nb);
-	spin_unlock_irqrestore(&die_notifier_lock, flags);
-	return err;
+int unregister_die_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_unregister(&powerpc_die_chain, nb);
 }
+EXPORT_SYMBOL(unregister_die_notifier);
 
 /*
  * Trap & Exception support
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 4737f84bb19e..741dd8802d49 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -195,7 +195,7 @@ void show_mem(void)
 	printk("Mem-info:\n");
 	show_free_areas();
 	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
-	for_each_pgdat(pgdat) {
+	for_each_online_pgdat(pgdat) {
 		unsigned long flags;
 		pgdat_resize_lock(pgdat, &flags);
 		for (i = 0; i < pgdat->node_spanned_pages; i++) {
@@ -351,7 +351,7 @@ void __init mem_init(void)
 	max_mapnr = max_pfn;
 	totalram_pages += free_all_bootmem();
 #endif
-	for_each_pgdat(pgdat) {
+	for_each_online_pgdat(pgdat) {
 		for (i = 0; i < pgdat->node_spanned_pages; i++) {
 			if (!pfn_valid(pgdat->node_start_pfn + i))
 				continue;
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 61e70d35d808..d9554199afa7 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -103,7 +103,7 @@ spufs_setattr(struct dentry *dentry, struct iattr *attr)
 
 static int
 spufs_new_file(struct super_block *sb, struct dentry *dentry,
-		struct file_operations *fops, int mode,
+		const struct file_operations *fops, int mode,
 		struct spu_context *ctx)
 {
 	static struct inode_operations spufs_file_iops = {
diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c
index 12c6f689b1aa..7d7889026936 100644
--- a/arch/powerpc/platforms/chrp/time.c
+++ b/arch/powerpc/platforms/chrp/time.c
@@ -120,33 +120,15 @@ int chrp_set_rtc_time(struct rtc_time *tmarg)
 void chrp_get_rtc_time(struct rtc_time *tm)
 {
 	unsigned int year, mon, day, hour, min, sec;
-	int uip, i;
 
-	/* The Linux interpretation of the CMOS clock register contents:
-	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
-	 * RTC registers show the second which has precisely just started.
-	 * Let's hope other operating systems interpret the RTC the same way.
-	 */
-
-	/* Since the UIP flag is set for about 2.2 ms and the clock
-	 * is typically written with a precision of 1 jiffy, trying
-	 * to obtain a precision better than a few milliseconds is
-	 * an illusion. Only consistency is interesting, this also
-	 * allows to use the routine for /dev/rtc without a potential
-	 * 1 second kernel busy loop triggered by any reader of /dev/rtc.
-	 */
-
-	for ( i = 0; i<1000000; i++) {
-		uip = chrp_cmos_clock_read(RTC_FREQ_SELECT);
+	do {
 		sec = chrp_cmos_clock_read(RTC_SECONDS);
 		min = chrp_cmos_clock_read(RTC_MINUTES);
 		hour = chrp_cmos_clock_read(RTC_HOURS);
 		day = chrp_cmos_clock_read(RTC_DAY_OF_MONTH);
 		mon = chrp_cmos_clock_read(RTC_MONTH);
 		year = chrp_cmos_clock_read(RTC_YEAR);
-		uip |= chrp_cmos_clock_read(RTC_FREQ_SELECT);
-		if ((uip & RTC_UIP)==0) break;
-	}
+	} while (sec != chrp_cmos_clock_read(RTC_SECONDS));
 
 	if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
 		BCD_TO_BIN(sec);
diff --git a/arch/powerpc/platforms/maple/time.c b/arch/powerpc/platforms/maple/time.c
index 5e6981d17379..b9a2b3d4bf33 100644
--- a/arch/powerpc/platforms/maple/time.c
+++ b/arch/powerpc/platforms/maple/time.c
@@ -60,34 +60,14 @@ static void maple_clock_write(unsigned long val, int addr)
 
 void maple_get_rtc_time(struct rtc_time *tm)
 {
-	int uip, i;
-
-	/* The Linux interpretation of the CMOS clock register contents:
-	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
-	 * RTC registers show the second which has precisely just started.
-	 * Let's hope other operating systems interpret the RTC the same way.
-	 */
-
-	/* Since the UIP flag is set for about 2.2 ms and the clock
-	 * is typically written with a precision of 1 jiffy, trying
-	 * to obtain a precision better than a few milliseconds is
-	 * an illusion. Only consistency is interesting, this also
-	 * allows to use the routine for /dev/rtc without a potential
-	 * 1 second kernel busy loop triggered by any reader of /dev/rtc.
-	 */
-
-	for (i = 0; i<1000000; i++) {
-		uip = maple_clock_read(RTC_FREQ_SELECT);
+	do {
 		tm->tm_sec = maple_clock_read(RTC_SECONDS);
 		tm->tm_min = maple_clock_read(RTC_MINUTES);
 		tm->tm_hour = maple_clock_read(RTC_HOURS);
 		tm->tm_mday = maple_clock_read(RTC_DAY_OF_MONTH);
 		tm->tm_mon = maple_clock_read(RTC_MONTH);
 		tm->tm_year = maple_clock_read(RTC_YEAR);
-		uip |= maple_clock_read(RTC_FREQ_SELECT);
-		if ((uip & RTC_UIP)==0)
-			break;
-	}
+	} while (tm->tm_sec != maple_clock_read(RTC_SECONDS));
 
 	if (!(maple_clock_read(RTC_CONTROL) & RTC_DM_BINARY)
 	    || RTC_ALWAYS_BCD) {
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 9a4b592e40bc..1773103354be 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -95,16 +95,16 @@ static struct device_node *derive_parent(const char *path)
 	return parent;
 }
 
-static struct notifier_block *pSeries_reconfig_chain;
+static BLOCKING_NOTIFIER_HEAD(pSeries_reconfig_chain);
 
 int pSeries_reconfig_notifier_register(struct notifier_block *nb)
 {
-	return notifier_chain_register(&pSeries_reconfig_chain, nb);
+	return blocking_notifier_chain_register(&pSeries_reconfig_chain, nb);
 }
 
 void pSeries_reconfig_notifier_unregister(struct notifier_block *nb)
 {
-	notifier_chain_unregister(&pSeries_reconfig_chain, nb);
+	blocking_notifier_chain_unregister(&pSeries_reconfig_chain, nb);
 }
 
 static int pSeries_reconfig_add_node(const char *path, struct property *proplist)
@@ -132,7 +132,7 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist
 		goto out_err;
 	}
 
-	err = notifier_call_chain(&pSeries_reconfig_chain,
+	err = blocking_notifier_call_chain(&pSeries_reconfig_chain,
 				  PSERIES_RECONFIG_ADD, np);
 	if (err == NOTIFY_BAD) {
 		printk(KERN_ERR "Failed to add device node %s\n", path);
@@ -172,7 +172,7 @@ static int pSeries_reconfig_remove_node(struct device_node *np)
 
 	remove_node_proc_entries(np);
 
-	notifier_call_chain(&pSeries_reconfig_chain,
+	blocking_notifier_call_chain(&pSeries_reconfig_chain,
 			    PSERIES_RECONFIG_REMOVE, np);
 	of_detach_node(np);
 
diff --git a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c
index eabac6cad1f5..75c645043746 100644
--- a/arch/ppc/kernel/ppc_htab.c
+++ b/arch/ppc/kernel/ppc_htab.c
@@ -52,7 +52,7 @@ static int ppc_htab_open(struct inode *inode, struct file *file)
 	return single_open(file, ppc_htab_show, NULL);
 }
 
-struct file_operations ppc_htab_operations = {
+const struct file_operations ppc_htab_operations = {
 	.open		= ppc_htab_open,
 	.read		= seq_read,
 	.llseek		= seq_lseek,
diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
index fa46f8ce5c71..e86f6156d589 100644
--- a/arch/ppc/platforms/prep_setup.c
+++ b/arch/ppc/platforms/prep_setup.c
@@ -736,7 +736,7 @@ ibm_statusled_progress(char *s, unsigned short hex)
 		hex = 0xfff;
 		if (!notifier_installed) {
 			++notifier_installed;
-			notifier_chain_register(&panic_notifier_list,
+			atomic_notifier_chain_register(&panic_notifier_list,
 						&ibm_statusled_block);
 		}
 	}
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 99182a415fe7..4a0f5a1551ea 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -76,17 +76,17 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
 /*
  * Need to know about CPUs going idle?
  */
-static struct notifier_block *idle_chain;
+static ATOMIC_NOTIFIER_HEAD(idle_chain);
 
 int register_idle_notifier(struct notifier_block *nb)
 {
-	return notifier_chain_register(&idle_chain, nb);
+	return atomic_notifier_chain_register(&idle_chain, nb);
 }
 EXPORT_SYMBOL(register_idle_notifier);
 
 int unregister_idle_notifier(struct notifier_block *nb)
 {
-	return notifier_chain_unregister(&idle_chain, nb);
+	return atomic_notifier_chain_unregister(&idle_chain, nb);
 }
 EXPORT_SYMBOL(unregister_idle_notifier);
 
@@ -95,7 +95,7 @@ void do_monitor_call(struct pt_regs *regs, long interruption_code)
 	/* disable monitor call class 0 */
 	__ctl_clear_bit(8, 15);
 
-	notifier_call_chain(&idle_chain, CPU_NOT_IDLE,
+	atomic_notifier_call_chain(&idle_chain, CPU_NOT_IDLE,
 			    (void *)(long) smp_processor_id());
 }
 
@@ -116,7 +116,8 @@ static void default_idle(void)
 		return;
 	}
 
-	rc = notifier_call_chain(&idle_chain, CPU_IDLE, (void *)(long) cpu);
+	rc = atomic_notifier_call_chain(&idle_chain,
+			CPU_IDLE, (void *)(long) cpu);
 	if (rc != NOTIFY_OK && rc != NOTIFY_DONE)
 		BUG();
 	if (rc != NOTIFY_OK) {
diff --git a/arch/sh/boards/mpc1211/rtc.c b/arch/sh/boards/mpc1211/rtc.c
index 4d100f048072..a76c655dceee 100644
--- a/arch/sh/boards/mpc1211/rtc.c
+++ b/arch/sh/boards/mpc1211/rtc.c
@@ -9,36 +9,16 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/time.h>
+#include <linux/bcd.h>
 #include <linux/mc146818rtc.h>
 
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-#endif
-
-/* arc/i386/kernel/time.c */
 unsigned long get_cmos_time(void)
 {
 	unsigned int year, mon, day, hour, min, sec;
-	int i;
 
 	spin_lock(&rtc_lock);
-	/* The Linux interpretation of the CMOS clock register contents:
-	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
-	 * RTC registers show the second which has precisely just started.
-	 * Let's hope other operating systems interpret the RTC the same way.
-	 */
-	/* read RTC exactly on falling edge of update flag */
-	for (i = 0 ; i < 1000000 ; i++)	/* may take up to 1 second... */
-		if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
-			break;
-	for (i = 0 ; i < 1000000 ; i++)	/* must try at least 2.228 ms */
-		if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
-			break;
-	do { /* Isn't this overkill ? UIP above should guarantee consistency */
+
+	do {
 		sec = CMOS_READ(RTC_SECONDS);
 		min = CMOS_READ(RTC_MINUTES);
 		hour = CMOS_READ(RTC_HOURS);
@@ -46,18 +26,22 @@ unsigned long get_cmos_time(void)
 		mon = CMOS_READ(RTC_MONTH);
 		year = CMOS_READ(RTC_YEAR);
 	} while (sec != CMOS_READ(RTC_SECONDS));
-	if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
-	  {
-	    BCD_TO_BIN(sec);
-	    BCD_TO_BIN(min);
-	    BCD_TO_BIN(hour);
-	    BCD_TO_BIN(day);
-	    BCD_TO_BIN(mon);
-	    BCD_TO_BIN(year);
-	  }
+
+	if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+		BCD_TO_BIN(sec);
+		BCD_TO_BIN(min);
+		BCD_TO_BIN(hour);
+		BCD_TO_BIN(day);
+		BCD_TO_BIN(mon);
+		BCD_TO_BIN(year);
+	}
+
 	spin_unlock(&rtc_lock);
-	if ((year += 1900) < 1970)
+
+	year += 1900;
+	if (year < 1970)
 		year += 100;
+
 	return mktime(year, mon, day, hour, min, sec);
 }
 
diff --git a/arch/sh/boards/sh03/rtc.c b/arch/sh/boards/sh03/rtc.c
index cbeca7037ba5..d609863cfe53 100644
--- a/arch/sh/boards/sh03/rtc.c
+++ b/arch/sh/boards/sh03/rtc.c
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/time.h>
+#include <linux/bcd.h>
 #include <asm/io.h>
 #include <linux/rtc.h>
 #include <linux/spinlock.h>
@@ -33,14 +34,6 @@
 #define RTC_BUSY	1
 #define RTC_STOP	2
 
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val)	((val)=(((val)/10)<<4) + (val)%10)
-#endif
-
 extern void (*rtc_get_time)(struct timespec *);
 extern int (*rtc_set_time)(const time_t);
 extern spinlock_t rtc_lock;
@@ -48,13 +41,9 @@ extern spinlock_t rtc_lock;
 unsigned long get_cmos_time(void)
 {
 	unsigned int year, mon, day, hour, min, sec;
-	int i;
 
 	spin_lock(&rtc_lock);
  again:
-	for (i = 0 ; i < 1000000 ; i++)	/* may take up to 1 second... */
-		if (!(ctrl_inb(RTC_CTL) & RTC_BUSY))
-			break;
 	do {
 		sec  = (ctrl_inb(RTC_SEC1) & 0xf) + (ctrl_inb(RTC_SEC10) & 0x7) * 10;
 		min  = (ctrl_inb(RTC_MIN1) & 0xf) + (ctrl_inb(RTC_MIN10) & 0xf) * 10;
diff --git a/arch/sh/kernel/cpu/rtc.c b/arch/sh/kernel/cpu/rtc.c
index f8361f5e788b..4304cf75cfa2 100644
--- a/arch/sh/kernel/cpu/rtc.c
+++ b/arch/sh/kernel/cpu/rtc.c
@@ -9,18 +9,10 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/time.h>
-
+#include <linux/bcd.h>
 #include <asm/io.h>
 #include <asm/rtc.h>
 
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-#endif
-
 void sh_rtc_gettimeofday(struct timespec *ts)
 {
 	unsigned int sec128, sec, sec2, min, hr, wk, day, mon, yr, yr100, cf_bit;
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index c0e79843f580..7ee4ca203616 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -20,6 +20,7 @@
 #include <linux/root_dev.h>
 #include <linux/utsname.h>
 #include <linux/cpu.h>
+#include <linux/pfn.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/sections.h>
@@ -275,10 +276,6 @@ void __init setup_arch(char **cmdline_p)
 
 	sh_mv_setup(cmdline_p);
 
-#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x)	((x) << PAGE_SHIFT)
-
 	/*
 	 * Find the highest page frame number we have available
 	 */
diff --git a/arch/sh64/kernel/setup.c b/arch/sh64/kernel/setup.c
index c7a7b816a30f..d2711c9c9d13 100644
--- a/arch/sh64/kernel/setup.c
+++ b/arch/sh64/kernel/setup.c
@@ -48,6 +48,7 @@
 #include <linux/root_dev.h>
 #include <linux/cpu.h>
 #include <linux/initrd.h>
+#include <linux/pfn.h>
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
diff --git a/arch/sh64/kernel/time.c b/arch/sh64/kernel/time.c
index 0773c9f389f3..6b8f4d22abc6 100644
--- a/arch/sh64/kernel/time.c
+++ b/arch/sh64/kernel/time.c
@@ -30,6 +30,7 @@
 #include <linux/profile.h>
 #include <linux/smp.h>
 #include <linux/module.h>
+#include <linux/bcd.h>
 
 #include <asm/registers.h>	 /* required by inline __asm__ stmt. */
 
@@ -105,14 +106,6 @@
 #define RCR1    	rtc_base+0x38
 #define RCR2    	rtc_base+0x3c
 
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-#endif
-
 #define TICK_SIZE (tick_nsec / 1000)
 
 extern unsigned long wall_jiffies;
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 7d61f1bfd3d3..e55b5c6ece02 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -641,23 +641,8 @@ static void __init set_system_time(void)
 		mon = MSTK_REG_MONTH(mregs);
 		year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
 	} else {
-		int i;
-
 		/* Dallas 12887 RTC chip. */
 
-		/* Stolen from arch/i386/kernel/time.c, see there for
-		 * credits and descriptive comments.
-		 */
-		for (i = 0; i < 1000000; i++) {
-			if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
-				break;
-			udelay(10);
-		}
-		for (i = 0; i < 1000000; i++) {
-			if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
-				break;
-			udelay(10);
-		}
 		do {
 			sec  = CMOS_READ(RTC_SECONDS);
 			min  = CMOS_READ(RTC_MINUTES);
@@ -666,6 +651,7 @@ static void __init set_system_time(void)
 			mon  = CMOS_READ(RTC_MONTH);
 			year = CMOS_READ(RTC_YEAR);
 		} while (sec != CMOS_READ(RTC_SECONDS));
+
 		if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
 			BCD_TO_BIN(sec);
 			BCD_TO_BIN(min);
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index df612e4f75f9..ff090bb9734b 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -43,18 +43,19 @@
 #include <linux/kmod.h>
 #endif
 
-struct notifier_block *sparc64die_chain;
-static DEFINE_SPINLOCK(die_notifier_lock);
+ATOMIC_NOTIFIER_HEAD(sparc64die_chain);
 
 int register_die_notifier(struct notifier_block *nb)
 {
-	int err = 0;
-	unsigned long flags;
-	spin_lock_irqsave(&die_notifier_lock, flags);
-	err = notifier_chain_register(&sparc64die_chain, nb);
-	spin_unlock_irqrestore(&die_notifier_lock, flags);
-	return err;
+	return atomic_notifier_chain_register(&sparc64die_chain, nb);
 }
+EXPORT_SYMBOL(register_die_notifier);
+
+int unregister_die_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_unregister(&sparc64die_chain, nb);
+}
+EXPORT_SYMBOL(unregister_die_notifier);
 
 /* When an irrecoverable trap occurs at tl > 0, the trap entry
  * code logs the trap state registers at every level in the trap
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index d21ff3230c02..0db2f7d9fab5 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -413,12 +413,12 @@ good_area:
 #ifdef CONFIG_HUGETLB_PAGE
 	mm_rss -= (mm->context.huge_pte_count * (HPAGE_SIZE / PAGE_SIZE));
 #endif
-	if (unlikely(mm_rss >=
+	if (unlikely(mm_rss >
 		     mm->context.tsb_block[MM_TSB_BASE].tsb_rss_limit))
 		tsb_grow(mm, MM_TSB_BASE, mm_rss);
 #ifdef CONFIG_HUGETLB_PAGE
 	mm_rss = mm->context.huge_pte_count;
-	if (unlikely(mm_rss >=
+	if (unlikely(mm_rss >
 		     mm->context.tsb_block[MM_TSB_HUGE].tsb_rss_limit))
 		tsb_grow(mm, MM_TSB_HUGE, mm_rss);
 #endif
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 54388d10bcf9..1488816588ea 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -762,7 +762,8 @@ static struct notifier_block panic_exit_notifier = {
 
 static int add_notifier(void)
 {
-	notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
+	atomic_notifier_chain_register(&panic_notifier_list,
+			&panic_exit_notifier);
 	return(0);
 }
 
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index fa617e0719ab..0336575d2448 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
@@ -71,7 +71,7 @@ struct io_thread_req {
 	int error;
 };
 
-extern int open_ubd_file(char *file, struct openflags *openflags,
+extern int open_ubd_file(char *file, struct openflags *openflags, int shared,
 			 char **backing_file_out, int *bitmap_offset_out,
 			 unsigned long *bitmap_len_out, int *data_offset_out,
 			 int *create_cow_out);
@@ -137,7 +137,7 @@ static int fake_major = MAJOR_NR;
 
 static struct gendisk *ubd_gendisk[MAX_DEV];
 static struct gendisk *fake_gendisk[MAX_DEV];
- 
+
 #ifdef CONFIG_BLK_DEV_UBD_SYNC
 #define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
 					 .cl = 1 })
@@ -168,6 +168,7 @@ struct ubd {
 	__u64 size;
 	struct openflags boot_openflags;
 	struct openflags openflags;
+	int shared;
 	int no_cow;
 	struct cow cow;
 	struct platform_device pdev;
@@ -189,6 +190,7 @@ struct ubd {
 	.boot_openflags =	OPEN_FLAGS, \
 	.openflags =		OPEN_FLAGS, \
         .no_cow =               0, \
+	.shared =		0, \
         .cow =			DEFAULT_COW, \
 }
 
@@ -305,7 +307,7 @@ static int ubd_setup_common(char *str, int *index_out)
 		}
 		major = simple_strtoul(str, &end, 0);
 		if((*end != '\0') || (end == str)){
-			printk(KERN_ERR 
+			printk(KERN_ERR
 			       "ubd_setup : didn't parse major number\n");
 			return(1);
 		}
@@ -316,7 +318,7 @@ static int ubd_setup_common(char *str, int *index_out)
  			printk(KERN_ERR "Can't assign a fake major twice\n");
  			goto out1;
  		}
- 
+
  		fake_major = major;
 
 		printk(KERN_INFO "Setting extra ubd major number to %d\n",
@@ -351,7 +353,7 @@ static int ubd_setup_common(char *str, int *index_out)
 	if (index_out)
 		*index_out = n;
 
-	for (i = 0; i < 4; i++) {
+	for (i = 0; i < sizeof("rscd="); i++) {
 		switch (*str) {
 		case 'r':
 			flags.w = 0;
@@ -362,11 +364,14 @@ static int ubd_setup_common(char *str, int *index_out)
 		case 'd':
 			dev->no_cow = 1;
 			break;
+		case 'c':
+			dev->shared = 1;
+			break;
 		case '=':
 			str++;
 			goto break_loop;
 		default:
-			printk(KERN_ERR "ubd_setup : Expected '=' or flag letter (r,s or d)\n");
+			printk(KERN_ERR "ubd_setup : Expected '=' or flag letter (r, s, c, or d)\n");
 			goto out;
 		}
 		str++;
@@ -515,7 +520,7 @@ static void ubd_handler(void)
 		spin_unlock(&ubd_io_lock);
 		return;
 	}
-        
+
 	ubd_finish(rq, req.error);
 	reactivate_fd(thread_fd, UBD_IRQ);	
 	do_ubd_request(ubd_queue);
@@ -532,7 +537,7 @@ static int io_pid = -1;
 
 void kill_io_thread(void)
 {
-	if(io_pid != -1) 
+	if(io_pid != -1)
 		os_kill_process(io_pid, 1);
 }
 
@@ -567,14 +572,15 @@ static int ubd_open_dev(struct ubd *dev)
 	create_cow = 0;
 	create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
 	back_ptr = dev->no_cow ? NULL : &dev->cow.file;
-	dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr,
-				&dev->cow.bitmap_offset, &dev->cow.bitmap_len, 
-				&dev->cow.data_offset, create_ptr);
+	dev->fd = open_ubd_file(dev->file, &dev->openflags, dev->shared,
+				back_ptr, &dev->cow.bitmap_offset,
+				&dev->cow.bitmap_len, &dev->cow.data_offset,
+				create_ptr);
 
 	if((dev->fd == -ENOENT) && create_cow){
-		dev->fd = create_cow_file(dev->file, dev->cow.file, 
+		dev->fd = create_cow_file(dev->file, dev->cow.file,
 					  dev->openflags, 1 << 9, PAGE_SIZE,
-					  &dev->cow.bitmap_offset, 
+					  &dev->cow.bitmap_offset,
 					  &dev->cow.bitmap_len,
 					  &dev->cow.data_offset);
 		if(dev->fd >= 0){
@@ -598,16 +604,16 @@ static int ubd_open_dev(struct ubd *dev)
 		}
 		flush_tlb_kernel_vm();
 
-		err = read_cow_bitmap(dev->fd, dev->cow.bitmap, 
-				      dev->cow.bitmap_offset, 
+		err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
+				      dev->cow.bitmap_offset,
 				      dev->cow.bitmap_len);
 		if(err < 0)
 			goto error;
 
 		flags = dev->openflags;
 		flags.w = 0;
-		err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL, 
-				    NULL, NULL);
+		err = open_ubd_file(dev->cow.file, &flags, dev->shared, NULL,
+				    NULL, NULL, NULL, NULL);
 		if(err < 0) goto error;
 		dev->cow.fd = err;
 	}
@@ -685,11 +691,11 @@ static int ubd_add(int n)
 	dev->size = ROUND_BLOCK(dev->size);
 
 	err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
-	if(err) 
+	if(err)
 		goto out_close;
- 
+
 	if(fake_major != MAJOR_NR)
-		ubd_new_disk(fake_major, dev->size, n, 
+		ubd_new_disk(fake_major, dev->size, n,
 			     &fake_gendisk[n]);
 
 	/* perhaps this should also be under the "if (fake_major)" above */
@@ -854,7 +860,7 @@ int ubd_init(void)
 			return -1;
 	}
 	platform_driver_register(&ubd_driver);
-	for (i = 0; i < MAX_DEV; i++) 
+	for (i = 0; i < MAX_DEV; i++)
 		ubd_add(i);
 	return 0;
 }
@@ -872,16 +878,16 @@ int ubd_driver_init(void){
 		 * enough. So use anyway the io thread. */
 	}
 	stack = alloc_stack(0, 0);
-	io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *), 
+	io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
 				 &thread_fd);
 	if(io_pid < 0){
-		printk(KERN_ERR 
+		printk(KERN_ERR
 		       "ubd : Failed to start I/O thread (errno = %d) - "
 		       "falling back to synchronous I/O\n", -io_pid);
 		io_pid = -1;
 		return(0);
 	}
-	err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, 
+	err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
 			     SA_INTERRUPT, "ubd", ubd_dev);
 	if(err != 0)
 		printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
@@ -978,7 +984,7 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
 	if(req->op == UBD_READ) {
 		for(i = 0; i < req->length >> 9; i++){
 			if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
-				ubd_set_bit(i, (unsigned char *) 
+				ubd_set_bit(i, (unsigned char *)
 					    &req->sector_mask);
                 }
 	}
@@ -999,7 +1005,7 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
 
 	/* This should be impossible now */
 	if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
-		printk("Write attempted on readonly ubd device %s\n", 
+		printk("Write attempted on readonly ubd device %s\n",
 		       disk->disk_name);
 		end_request(req, 0);
 		return(1);
@@ -1182,7 +1188,7 @@ int read_cow_bitmap(int fd, void *buf, int offset, int len)
 	return(0);
 }
 
-int open_ubd_file(char *file, struct openflags *openflags,
+int open_ubd_file(char *file, struct openflags *openflags, int shared,
 		  char **backing_file_out, int *bitmap_offset_out,
 		  unsigned long *bitmap_len_out, int *data_offset_out,
 		  int *create_cow_out)
@@ -1206,10 +1212,14 @@ int open_ubd_file(char *file, struct openflags *openflags,
 			return fd;
         }
 
-	err = os_lock_file(fd, openflags->w);
-	if(err < 0){
-		printk("Failed to lock '%s', err = %d\n", file, -err);
-		goto out_close;
+	if(shared)
+		printk("Not locking \"%s\" on the host\n", file);
+	else {
+		err = os_lock_file(fd, openflags->w);
+		if(err < 0){
+			printk("Failed to lock '%s', err = %d\n", file, -err);
+			goto out_close;
+		}
 	}
 
 	/* Succesful return case! */
@@ -1260,7 +1270,7 @@ int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
 	int err, fd;
 
 	flags.c = 1;
-	fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
+	fd = open_ubd_file(cow_file, &flags, 0, NULL, NULL, NULL, NULL, NULL);
 	if(fd < 0){
 		err = fd;
 		printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
diff --git a/arch/um/include/irq_user.h b/arch/um/include/irq_user.h
index b61deb8b362a..69a93c804f0e 100644
--- a/arch/um/include/irq_user.h
+++ b/arch/um/include/irq_user.h
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
@@ -6,6 +6,17 @@
 #ifndef __IRQ_USER_H__
 #define __IRQ_USER_H__
 
+struct irq_fd {
+	struct irq_fd *next;
+	void *id;
+	int fd;
+	int type;
+	int irq;
+	int pid;
+	int events;
+	int current_events;
+};
+
 enum { IRQ_READ, IRQ_WRITE };
 
 extern void sigio_handler(int sig, union uml_pt_regs *regs);
@@ -16,8 +27,6 @@ extern void reactivate_fd(int fd, int irqnum);
 extern void deactivate_fd(int fd, int irqnum);
 extern int deactivate_all_fds(void);
 extern void forward_interrupts(int pid);
-extern void init_irq_signals(int on_sigstack);
-extern void forward_ipi(int fd, int pid);
 extern int activate_ipi(int fd, int pid);
 extern unsigned long irq_lock(void);
 extern void irq_unlock(unsigned long flags);
diff --git a/arch/um/include/kern.h b/arch/um/include/kern.h
index 7d223beccbc0..4ce3fc650e57 100644
--- a/arch/um/include/kern.h
+++ b/arch/um/include/kern.h
@@ -29,7 +29,7 @@ extern int getuid(void);
 extern int getgid(void);
 extern int pause(void);
 extern int write(int, const void *, int);
-extern int exit(int);
+extern void exit(int);
 extern int close(int);
 extern int read(unsigned int, char *, int);
 extern int pipe(int *);
diff --git a/arch/um/include/misc_constants.h b/arch/um/include/misc_constants.h
new file mode 100644
index 000000000000..989bc08de36e
--- /dev/null
+++ b/arch/um/include/misc_constants.h
@@ -0,0 +1,6 @@
+#ifndef __MISC_CONSTANT_H_
+#define __MISC_CONSTANT_H_
+
+#include <user_constants.h>
+
+#endif
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 2a1c64d8d0bf..d3d1bc6074ef 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -12,6 +12,7 @@
 #include "sysdep/ptrace.h"
 #include "kern_util.h"
 #include "skas/mm_id.h"
+#include "irq_user.h"
 
 #define OS_TYPE_FILE 1 
 #define OS_TYPE_DIR 2 
@@ -121,6 +122,7 @@ static inline struct openflags of_cloexec(struct openflags flags)
 	return(flags); 
 }
   
+/* file.c */
 extern int os_stat_file(const char *file_name, struct uml_stat *buf);
 extern int os_stat_fd(const int fd, struct uml_stat *buf);
 extern int os_access(const char *file, int mode);
@@ -156,10 +158,20 @@ extern int os_connect_socket(char *name);
 extern int os_file_type(char *file);
 extern int os_file_mode(char *file, struct openflags *mode_out);
 extern int os_lock_file(int fd, int excl);
+extern void os_flush_stdout(void);
+extern int os_stat_filesystem(char *path, long *bsize_out,
+			      long long *blocks_out, long long *bfree_out,
+			      long long *bavail_out, long long *files_out,
+			      long long *ffree_out, void *fsid_out,
+			      int fsid_size, long *namelen_out,
+			      long *spare_out);
+extern int os_change_dir(char *dir);
+extern int os_fchange_dir(int fd);
 
 /* start_up.c */
 extern void os_early_checks(void);
 extern int can_do_skas(void);
+extern void os_check_bugs(void);
 
 /* Make sure they are clear when running in TT mode. Required by
  * SEGV_MAYBE_FIXABLE */
@@ -198,6 +210,8 @@ extern void os_flush_stdout(void);
 /* tt.c
  * for tt mode only (will be deleted in future...)
  */
+extern void forward_ipi(int fd, int pid);
+extern void kill_child_dead(int pid);
 extern void stop(void);
 extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
 extern int protect_memory(unsigned long addr, unsigned long len,
@@ -294,4 +308,26 @@ extern void initial_thread_cb_skas(void (*proc)(void *),
 extern void halt_skas(void);
 extern void reboot_skas(void);
 
+/* irq.c */
+extern int os_waiting_for_events(struct irq_fd *active_fds);
+extern int os_isatty(int fd);
+extern int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds);
+extern void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg,
+		struct irq_fd *active_fds, struct irq_fd ***last_irq_ptr2);
+extern void os_free_irq_later(struct irq_fd *active_fds,
+		int irq, void *dev_id);
+extern int os_get_pollfd(int i);
+extern void os_set_pollfd(int i, int fd);
+extern void os_set_ioignore(void);
+extern void init_irq_signals(int on_sigstack);
+
+/* sigio.c */
+extern void write_sigio_workaround(void);
+extern int add_sigio_fd(int fd, int read);
+extern int ignore_sigio_fd(int fd);
+
+/* skas/trap */
+extern void sig_handler_common_skas(int sig, void *sc_ptr);
+extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
+
 #endif
diff --git a/arch/um/include/sigio.h b/arch/um/include/sigio.h
index 37d76e29a147..fe99ea163c2e 100644
--- a/arch/um/include/sigio.h
+++ b/arch/um/include/sigio.h
@@ -8,9 +8,6 @@
 
 extern int write_sigio_irq(int fd);
 extern int register_sigio_fd(int fd);
-extern int read_sigio_fd(int fd);
-extern int add_sigio_fd(int fd, int read);
-extern int ignore_sigio_fd(int fd);
 extern void sigio_lock(void);
 extern void sigio_unlock(void);
 
diff --git a/arch/um/include/skas/mode-skas.h b/arch/um/include/skas/mode-skas.h
index 260065cfeef1..8bc6916bbbb1 100644
--- a/arch/um/include/skas/mode-skas.h
+++ b/arch/um/include/skas/mode-skas.h
@@ -13,7 +13,6 @@ extern unsigned long exec_fp_regs[];
 extern unsigned long exec_fpx_regs[];
 extern int have_fpx_regs;
 
-extern void sig_handler_common_skas(int sig, void *sc_ptr);
 extern void kill_off_processes_skas(void);
 
 #endif
diff --git a/arch/um/include/skas/skas.h b/arch/um/include/skas/skas.h
index 86357282d681..853b26f148c5 100644
--- a/arch/um/include/skas/skas.h
+++ b/arch/um/include/skas/skas.h
@@ -17,7 +17,6 @@ extern int user_thread(unsigned long stack, int flags);
 extern void new_thread_proc(void *stack, void (*handler)(int sig));
 extern void new_thread_handler(int sig);
 extern void handle_syscall(union uml_pt_regs *regs);
-extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
 extern int new_mm(unsigned long stack);
 extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
 extern long execute_syscall_skas(void *r);
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index a6f1f176cf84..992a7e1e0fca 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -58,7 +58,6 @@ extern int attach(int pid);
 extern void kill_child_dead(int pid);
 extern int cont(int pid);
 extern void check_sigio(void);
-extern void write_sigio_workaround(void);
 extern void arch_check_bugs(void);
 extern int cpu_feature(char *what, char *buf, int len);
 extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 693018ba80f1..fe08971b64cf 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -7,23 +7,20 @@ extra-y := vmlinux.lds
 clean-files :=
 
 obj-y = config.o exec_kern.o exitcode.o \
-	init_task.o irq.o irq_user.o ksyms.o mem.o physmem.o \
-	process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \
+	init_task.o irq.o ksyms.o mem.o physmem.o \
+	process_kern.o ptrace.o reboot.o resource.o sigio_kern.o \
 	signal_kern.o smp.o syscall_kern.o sysrq.o \
 	time_kern.o tlb.o trap_kern.o uaccess.o um_arch.o umid.o
 
 obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
 obj-$(CONFIG_GPROF)	+= gprof_syms.o
 obj-$(CONFIG_GCOV)	+= gmon_syms.o
-obj-$(CONFIG_TTY_LOG)	+= tty_log.o
 obj-$(CONFIG_SYSCALL_DEBUG) += syscall.o
 
 obj-$(CONFIG_MODE_TT) += tt/
 obj-$(CONFIG_MODE_SKAS) += skas/
 
-user-objs-$(CONFIG_TTY_LOG) += tty_log.o
-
-USER_OBJS := $(user-objs-y) config.o tty_log.o
+USER_OBJS := config.o
 
 include arch/um/scripts/Makefile.rules
 
diff --git a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c
index c264e1c05ab3..1ca84319317d 100644
--- a/arch/um/kernel/exec_kern.c
+++ b/arch/um/kernel/exec_kern.c
@@ -30,8 +30,6 @@ void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
 	CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
 }
 
-extern void log_exec(char **argv, void *tty);
-
 static long execve1(char *file, char __user * __user *argv,
 		    char __user *__user *env)
 {
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index bbf94bf2921e..c39ea3abeda4 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -31,6 +31,8 @@
 #include "irq_user.h"
 #include "irq_kern.h"
 #include "os.h"
+#include "sigio.h"
+#include "misc_constants.h"
 
 /*
  * Generic, controller-independent functions:
@@ -77,6 +79,298 @@ skip:
 	return 0;
 }
 
+struct irq_fd *active_fds = NULL;
+static struct irq_fd **last_irq_ptr = &active_fds;
+
+extern void free_irqs(void);
+
+void sigio_handler(int sig, union uml_pt_regs *regs)
+{
+	struct irq_fd *irq_fd;
+	int n;
+
+	if(smp_sigio_handler()) return;
+	while(1){
+		n = os_waiting_for_events(active_fds);
+		if (n <= 0) {
+			if(n == -EINTR) continue;
+			else break;
+		}
+
+		for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
+			if(irq_fd->current_events != 0){
+				irq_fd->current_events = 0;
+				do_IRQ(irq_fd->irq, regs);
+			}
+		}
+	}
+
+	free_irqs();
+}
+
+static void maybe_sigio_broken(int fd, int type)
+{
+	if(os_isatty(fd)){
+		if((type == IRQ_WRITE) && !pty_output_sigio){
+			write_sigio_workaround();
+			add_sigio_fd(fd, 0);
+		}
+		else if((type == IRQ_READ) && !pty_close_sigio){
+			write_sigio_workaround();
+			add_sigio_fd(fd, 1);
+		}
+	}
+}
+
+
+int activate_fd(int irq, int fd, int type, void *dev_id)
+{
+	struct pollfd *tmp_pfd;
+	struct irq_fd *new_fd, *irq_fd;
+	unsigned long flags;
+	int pid, events, err, n;
+
+	pid = os_getpid();
+	err = os_set_fd_async(fd, pid);
+	if(err < 0)
+		goto out;
+
+	new_fd = um_kmalloc(sizeof(*new_fd));
+	err = -ENOMEM;
+	if(new_fd == NULL)
+		goto out;
+
+	if(type == IRQ_READ) events = UM_POLLIN | UM_POLLPRI;
+	else events = UM_POLLOUT;
+	*new_fd = ((struct irq_fd) { .next  		= NULL,
+				     .id 		= dev_id,
+				     .fd 		= fd,
+				     .type 		= type,
+				     .irq 		= irq,
+				     .pid  		= pid,
+				     .events 		= events,
+				     .current_events 	= 0 } );
+
+	/* Critical section - locked by a spinlock because this stuff can
+	 * be changed from interrupt handlers.  The stuff above is done
+	 * outside the lock because it allocates memory.
+	 */
+
+	/* Actually, it only looks like it can be called from interrupt
+	 * context.  The culprit is reactivate_fd, which calls
+	 * maybe_sigio_broken, which calls write_sigio_workaround,
+	 * which calls activate_fd.  However, write_sigio_workaround should
+	 * only be called once, at boot time.  That would make it clear that
+	 * this is called only from process context, and can be locked with
+	 * a semaphore.
+	 */
+	flags = irq_lock();
+	for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
+		if((irq_fd->fd == fd) && (irq_fd->type == type)){
+			printk("Registering fd %d twice\n", fd);
+			printk("Irqs : %d, %d\n", irq_fd->irq, irq);
+			printk("Ids : 0x%p, 0x%p\n", irq_fd->id, dev_id);
+			goto out_unlock;
+		}
+	}
+
+	/*-------------*/
+	if(type == IRQ_WRITE)
+		fd = -1;
+
+	tmp_pfd = NULL;
+	n = 0;
+
+	while(1){
+		n = os_create_pollfd(fd, events, tmp_pfd, n);
+		if (n == 0)
+			break;
+
+		/* n > 0
+		 * It means we couldn't put new pollfd to current pollfds
+		 * and tmp_fds is NULL or too small for new pollfds array.
+		 * Needed size is equal to n as minimum.
+		 *
+		 * Here we have to drop the lock in order to call
+		 * kmalloc, which might sleep.
+		 * If something else came in and changed the pollfds array
+		 * so we will not be able to put new pollfd struct to pollfds
+		 * then we free the buffer tmp_fds and try again.
+		 */
+		irq_unlock(flags);
+		if (tmp_pfd != NULL) {
+			kfree(tmp_pfd);
+			tmp_pfd = NULL;
+		}
+
+		tmp_pfd = um_kmalloc(n);
+		if (tmp_pfd == NULL)
+			goto out_kfree;
+
+		flags = irq_lock();
+	}
+	/*-------------*/
+
+	*last_irq_ptr = new_fd;
+	last_irq_ptr = &new_fd->next;
+
+	irq_unlock(flags);
+
+	/* This calls activate_fd, so it has to be outside the critical
+	 * section.
+	 */
+	maybe_sigio_broken(fd, type);
+
+	return(0);
+
+ out_unlock:
+	irq_unlock(flags);
+ out_kfree:
+	kfree(new_fd);
+ out:
+	return(err);
+}
+
+static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
+{
+	unsigned long flags;
+
+	flags = irq_lock();
+	os_free_irq_by_cb(test, arg, active_fds, &last_irq_ptr);
+	irq_unlock(flags);
+}
+
+struct irq_and_dev {
+	int irq;
+	void *dev;
+};
+
+static int same_irq_and_dev(struct irq_fd *irq, void *d)
+{
+	struct irq_and_dev *data = d;
+
+	return((irq->irq == data->irq) && (irq->id == data->dev));
+}
+
+void free_irq_by_irq_and_dev(unsigned int irq, void *dev)
+{
+	struct irq_and_dev data = ((struct irq_and_dev) { .irq  = irq,
+							  .dev  = dev });
+
+	free_irq_by_cb(same_irq_and_dev, &data);
+}
+
+static int same_fd(struct irq_fd *irq, void *fd)
+{
+	return(irq->fd == *((int *) fd));
+}
+
+void free_irq_by_fd(int fd)
+{
+	free_irq_by_cb(same_fd, &fd);
+}
+
+static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
+{
+	struct irq_fd *irq;
+	int i = 0;
+	int fdi;
+
+	for(irq=active_fds; irq != NULL; irq = irq->next){
+		if((irq->fd == fd) && (irq->irq == irqnum)) break;
+		i++;
+	}
+	if(irq == NULL){
+		printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
+		goto out;
+	}
+	fdi = os_get_pollfd(i);
+	if((fdi != -1) && (fdi != fd)){
+		printk("find_irq_by_fd - mismatch between active_fds and "
+		       "pollfds, fd %d vs %d, need %d\n", irq->fd,
+		       fdi, fd);
+		irq = NULL;
+		goto out;
+	}
+	*index_out = i;
+ out:
+	return(irq);
+}
+
+void reactivate_fd(int fd, int irqnum)
+{
+	struct irq_fd *irq;
+	unsigned long flags;
+	int i;
+
+	flags = irq_lock();
+	irq = find_irq_by_fd(fd, irqnum, &i);
+	if(irq == NULL){
+		irq_unlock(flags);
+		return;
+	}
+	os_set_pollfd(i, irq->fd);
+	irq_unlock(flags);
+
+	/* This calls activate_fd, so it has to be outside the critical
+	 * section.
+	 */
+	maybe_sigio_broken(fd, irq->type);
+}
+
+void deactivate_fd(int fd, int irqnum)
+{
+	struct irq_fd *irq;
+	unsigned long flags;
+	int i;
+
+	flags = irq_lock();
+	irq = find_irq_by_fd(fd, irqnum, &i);
+	if(irq == NULL)
+		goto out;
+	os_set_pollfd(i, -1);
+ out:
+	irq_unlock(flags);
+}
+
+int deactivate_all_fds(void)
+{
+	struct irq_fd *irq;
+	int err;
+
+	for(irq=active_fds;irq != NULL;irq = irq->next){
+		err = os_clear_fd_async(irq->fd);
+		if(err)
+			return(err);
+	}
+	/* If there is a signal already queued, after unblocking ignore it */
+	os_set_ioignore();
+
+	return(0);
+}
+
+void forward_interrupts(int pid)
+{
+	struct irq_fd *irq;
+	unsigned long flags;
+	int err;
+
+	flags = irq_lock();
+	for(irq=active_fds;irq != NULL;irq = irq->next){
+		err = os_set_owner(irq->fd, pid);
+		if(err < 0){
+			/* XXX Just remove the irq rather than
+			 * print out an infinite stream of these
+			 */
+			printk("Failed to forward %d to pid %d, err = %d\n",
+			       irq->fd, pid, -err);
+		}
+
+		irq->pid = pid;
+	}
+	irq_unlock(flags);
+}
+
 /*
  * do_IRQ handles all normal device IRQ's (the special
  * SMP cross-CPU interrupts have their own specific
diff --git a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c
deleted file mode 100644
index 0e32f5f4a887..000000000000
--- a/arch/um/kernel/irq_user.c
+++ /dev/null
@@ -1,412 +0,0 @@
-/* 
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include <string.h>
-#include <sys/poll.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include "user_util.h"
-#include "kern_util.h"
-#include "user.h"
-#include "process.h"
-#include "sigio.h"
-#include "irq_user.h"
-#include "os.h"
-
-struct irq_fd {
-	struct irq_fd *next;
-	void *id;
-	int fd;
-	int type;
-	int irq;
-	int pid;
-	int events;
-	int current_events;
-};
-
-static struct irq_fd *active_fds = NULL;
-static struct irq_fd **last_irq_ptr = &active_fds;
-
-static struct pollfd *pollfds = NULL;
-static int pollfds_num = 0;
-static int pollfds_size = 0;
-
-extern int io_count, intr_count;
-
-extern void free_irqs(void);
-
-void sigio_handler(int sig, union uml_pt_regs *regs)
-{
-	struct irq_fd *irq_fd;
-	int i, n;
-
-	if(smp_sigio_handler()) return;
-	while(1){
-		n = poll(pollfds, pollfds_num, 0);
-		if(n < 0){
-			if(errno == EINTR) continue;
-			printk("sigio_handler : poll returned %d, "
-			       "errno = %d\n", n, errno);
-			break;
-		}
-		if(n == 0) break;
-
-		irq_fd = active_fds;
-		for(i = 0; i < pollfds_num; i++){
-			if(pollfds[i].revents != 0){
-				irq_fd->current_events = pollfds[i].revents;
-				pollfds[i].fd = -1;
-			}
-			irq_fd = irq_fd->next;
-		}
-
-		for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
-			if(irq_fd->current_events != 0){
-				irq_fd->current_events = 0;
-				do_IRQ(irq_fd->irq, regs);
-			}
-		}
-	}
-
-	free_irqs();
-}
-
-int activate_ipi(int fd, int pid)
-{
-	return(os_set_fd_async(fd, pid));
-}
-
-static void maybe_sigio_broken(int fd, int type)
-{
-	if(isatty(fd)){
-		if((type == IRQ_WRITE) && !pty_output_sigio){
-			write_sigio_workaround();
-			add_sigio_fd(fd, 0);
-		}
-		else if((type == IRQ_READ) && !pty_close_sigio){
-			write_sigio_workaround();
-			add_sigio_fd(fd, 1);			
-		}
-	}
-}
-
-int activate_fd(int irq, int fd, int type, void *dev_id)
-{
-	struct pollfd *tmp_pfd;
-	struct irq_fd *new_fd, *irq_fd;
-	unsigned long flags;
-	int pid, events, err, n, size;
-
-	pid = os_getpid();
-	err = os_set_fd_async(fd, pid);
-	if(err < 0)
-		goto out;
-
-	new_fd = um_kmalloc(sizeof(*new_fd));
-	err = -ENOMEM;
-	if(new_fd == NULL)
-		goto out;
-
-	if(type == IRQ_READ) events = POLLIN | POLLPRI;
-	else events = POLLOUT;
-	*new_fd = ((struct irq_fd) { .next  		= NULL,
-				     .id 		= dev_id,
-				     .fd 		= fd,
-				     .type 		= type,
-				     .irq 		= irq,
-				     .pid  		= pid,
-				     .events 		= events,
-				     .current_events 	= 0 } );
-
-	/* Critical section - locked by a spinlock because this stuff can
-	 * be changed from interrupt handlers.  The stuff above is done 
-	 * outside the lock because it allocates memory.
-	 */
-
-	/* Actually, it only looks like it can be called from interrupt
-	 * context.  The culprit is reactivate_fd, which calls 
-	 * maybe_sigio_broken, which calls write_sigio_workaround,
-	 * which calls activate_fd.  However, write_sigio_workaround should
-	 * only be called once, at boot time.  That would make it clear that
-	 * this is called only from process context, and can be locked with
-	 * a semaphore.
-	 */
-	flags = irq_lock();
-	for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
-		if((irq_fd->fd == fd) && (irq_fd->type == type)){
-			printk("Registering fd %d twice\n", fd);
-			printk("Irqs : %d, %d\n", irq_fd->irq, irq);
-			printk("Ids : 0x%x, 0x%x\n", irq_fd->id, dev_id);
-			goto out_unlock;
-		}
-	}
-
-	n = pollfds_num;
-	if(n == pollfds_size){
-		while(1){
-			/* Here we have to drop the lock in order to call 
-			 * kmalloc, which might sleep.  If something else
-			 * came in and changed the pollfds array, we free
-			 * the buffer and try again.
-			 */
-			irq_unlock(flags);
-			size = (pollfds_num + 1) * sizeof(pollfds[0]);
-			tmp_pfd = um_kmalloc(size);
-			flags = irq_lock();
-			if(tmp_pfd == NULL)
-				goto out_unlock;
-			if(n == pollfds_size)
-				break;
-			kfree(tmp_pfd);
-		}
-		if(pollfds != NULL){
-			memcpy(tmp_pfd, pollfds,
-			       sizeof(pollfds[0]) * pollfds_size);
-			kfree(pollfds);
-		}
-		pollfds = tmp_pfd;
-		pollfds_size++;
-	}
-
-	if(type == IRQ_WRITE) 
-		fd = -1;
-
-	pollfds[pollfds_num] = ((struct pollfd) { .fd 	= fd,
-						  .events 	= events,
-						  .revents 	= 0 });
-	pollfds_num++;
-
-	*last_irq_ptr = new_fd;
-	last_irq_ptr = &new_fd->next;
-
-	irq_unlock(flags);
-
-	/* This calls activate_fd, so it has to be outside the critical
-	 * section.
-	 */
-	maybe_sigio_broken(fd, type);
-
-	return(0);
-
- out_unlock:
-	irq_unlock(flags);
-	kfree(new_fd);
- out:
-	return(err);
-}
-
-static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
-{
-	struct irq_fd **prev;
-	unsigned long flags;
-	int i = 0;
-
-	flags = irq_lock();
-	prev = &active_fds;
-	while(*prev != NULL){
-		if((*test)(*prev, arg)){
-			struct irq_fd *old_fd = *prev;
-			if((pollfds[i].fd != -1) && 
-			   (pollfds[i].fd != (*prev)->fd)){
-				printk("free_irq_by_cb - mismatch between "
-				       "active_fds and pollfds, fd %d vs %d\n",
-				       (*prev)->fd, pollfds[i].fd);
-				goto out;
-			}
-
-			pollfds_num--;
-
-			/* This moves the *whole* array after pollfds[i] (though
-			 * it doesn't spot as such)! */
-
-			memmove(&pollfds[i], &pollfds[i + 1],
-			       (pollfds_num - i) * sizeof(pollfds[0]));
-
-			if(last_irq_ptr == &old_fd->next) 
-				last_irq_ptr = prev;
-			*prev = (*prev)->next;
-			if(old_fd->type == IRQ_WRITE) 
-				ignore_sigio_fd(old_fd->fd);
-			kfree(old_fd);
-			continue;
-		}
-		prev = &(*prev)->next;
-		i++;
-	}
- out:
-	irq_unlock(flags);
-}
-
-struct irq_and_dev {
-	int irq;
-	void *dev;
-};
-
-static int same_irq_and_dev(struct irq_fd *irq, void *d)
-{
-	struct irq_and_dev *data = d;
-
-	return((irq->irq == data->irq) && (irq->id == data->dev));
-}
-
-void free_irq_by_irq_and_dev(unsigned int irq, void *dev)
-{
-	struct irq_and_dev data = ((struct irq_and_dev) { .irq  = irq,
-							  .dev  = dev });
-
-	free_irq_by_cb(same_irq_and_dev, &data);
-}
-
-static int same_fd(struct irq_fd *irq, void *fd)
-{
-	return(irq->fd == *((int *) fd));
-}
-
-void free_irq_by_fd(int fd)
-{
-	free_irq_by_cb(same_fd, &fd);
-}
-
-static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
-{
-	struct irq_fd *irq;
-	int i = 0;
-
-	for(irq=active_fds; irq != NULL; irq = irq->next){
-		if((irq->fd == fd) && (irq->irq == irqnum)) break;
-		i++;
-	}
-	if(irq == NULL){
-		printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
-		goto out;
-	}
-	if((pollfds[i].fd != -1) && (pollfds[i].fd != fd)){
-		printk("find_irq_by_fd - mismatch between active_fds and "
-		       "pollfds, fd %d vs %d, need %d\n", irq->fd, 
-		       pollfds[i].fd, fd);
-		irq = NULL;
-		goto out;
-	}
-	*index_out = i;
- out:
-	return(irq);
-}
-
-void reactivate_fd(int fd, int irqnum)
-{
-	struct irq_fd *irq;
-	unsigned long flags;
-	int i;
-
-	flags = irq_lock();
-	irq = find_irq_by_fd(fd, irqnum, &i);
-	if(irq == NULL){
-		irq_unlock(flags);
-		return;
-	}
-
-	pollfds[i].fd = irq->fd;
-
-	irq_unlock(flags);
-
-	/* This calls activate_fd, so it has to be outside the critical
-	 * section.
-	 */
-	maybe_sigio_broken(fd, irq->type);
-}
-
-void deactivate_fd(int fd, int irqnum)
-{
-	struct irq_fd *irq;
-	unsigned long flags;
-	int i;
-
-	flags = irq_lock();
-	irq = find_irq_by_fd(fd, irqnum, &i);
-	if(irq == NULL)
-		goto out;
-	pollfds[i].fd = -1;
- out:
-	irq_unlock(flags);
-}
-
-int deactivate_all_fds(void)
-{
-	struct irq_fd *irq;
-	int err;
-
-	for(irq=active_fds;irq != NULL;irq = irq->next){
-		err = os_clear_fd_async(irq->fd);
-		if(err)
-			return(err);
-	}
-	/* If there is a signal already queued, after unblocking ignore it */
-	set_handler(SIGIO, SIG_IGN, 0, -1);
-
-	return(0);
-}
-
-void forward_ipi(int fd, int pid)
-{
-	int err;
-
-	err = os_set_owner(fd, pid);
-	if(err < 0)
-		printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
-		       "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
-}
-
-void forward_interrupts(int pid)
-{
-	struct irq_fd *irq;
-	unsigned long flags;
-	int err;
-
-	flags = irq_lock();
-	for(irq=active_fds;irq != NULL;irq = irq->next){
-		err = os_set_owner(irq->fd, pid);
-		if(err < 0){
-			/* XXX Just remove the irq rather than
-			 * print out an infinite stream of these
-			 */
-			printk("Failed to forward %d to pid %d, err = %d\n",
-			       irq->fd, pid, -err);
-		}
-
-		irq->pid = pid;
-	}
-	irq_unlock(flags);
-}
-
-void init_irq_signals(int on_sigstack)
-{
-	__sighandler_t h;
-	int flags;
-
-	flags = on_sigstack ? SA_ONSTACK : 0;
-	if(timer_irq_inited) h = (__sighandler_t) alarm_handler;
-	else h = boot_timer_handler;
-
-	set_handler(SIGVTALRM, h, flags | SA_RESTART, 
-		    SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
-	set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
-		    SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
-	signal(SIGWINCH, SIG_IGN);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index 0e65340eee33..0500800df1c1 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -9,6 +9,7 @@
 #include "linux/vmalloc.h"
 #include "linux/bootmem.h"
 #include "linux/module.h"
+#include "linux/pfn.h"
 #include "asm/types.h"
 #include "asm/pgtable.h"
 #include "kern_util.h"
@@ -316,8 +317,6 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
 	}
 }
 
-#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-
 extern int __syscall_stub_start, __binary_start;
 
 void setup_physmem(unsigned long start, unsigned long reserve_end,
diff --git a/arch/um/kernel/sigio_kern.c b/arch/um/kernel/sigio_kern.c
index 229988463c4c..1c1300fb1e95 100644
--- a/arch/um/kernel/sigio_kern.c
+++ b/arch/um/kernel/sigio_kern.c
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
  * Licensed under the GPL
  */
@@ -12,13 +12,16 @@
 #include "sigio.h"
 #include "irq_user.h"
 #include "irq_kern.h"
+#include "os.h"
 
 /* Protected by sigio_lock() called from write_sigio_workaround */
 static int sigio_irq_fd = -1;
 
 static irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
 {
-	read_sigio_fd(sigio_irq_fd);
+	char c;
+
+	os_read_file(sigio_irq_fd, &c, sizeof(c));
 	reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
 	return(IRQ_HANDLED);
 }
@@ -51,6 +54,9 @@ void sigio_unlock(void)
 	spin_unlock(&sigio_spinlock);
 }
 
+extern void sigio_cleanup(void);
+__uml_exitcall(sigio_cleanup);
+
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
index 72113b0a96e7..c8d8d0ac1a7f 100644
--- a/arch/um/kernel/smp.c
+++ b/arch/um/kernel/smp.c
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
  * Licensed under the GPL
  */
@@ -77,9 +77,9 @@ static int idle_proc(void *cpup)
 	if(err < 0)
 		panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
 
-	activate_ipi(cpu_data[cpu].ipi_pipe[0], 
+	os_set_fd_async(cpu_data[cpu].ipi_pipe[0],
 		     current->thread.mode.tt.extern_pid);
- 
+
 	wmb();
 	if (cpu_test_and_set(cpu, cpu_callin_map)) {
 		printk("huh, CPU#%d already present??\n", cpu);
@@ -106,7 +106,7 @@ static struct task_struct *idle_thread(int cpu)
 		panic("copy_process failed in idle_thread, error = %ld",
 		      PTR_ERR(new_task));
 
-	cpu_tasks[cpu] = ((struct cpu_task) 
+	cpu_tasks[cpu] = ((struct cpu_task)
 		          { .pid = 	new_task->thread.mode.tt.extern_pid,
 			    .task = 	new_task } );
 	idle_threads[cpu] = new_task;
@@ -134,12 +134,12 @@ void smp_prepare_cpus(unsigned int maxcpus)
 	if(err < 0)
 		panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
 
-	activate_ipi(cpu_data[me].ipi_pipe[0],
+	os_set_fd_async(cpu_data[me].ipi_pipe[0],
 		     current->thread.mode.tt.extern_pid);
 
 	for(cpu = 1; cpu < ncpus; cpu++){
 		printk("Booting processor %d...\n", cpu);
-		
+
 		idle = idle_thread(cpu);
 
 		init_idle(idle, cpu);
@@ -223,7 +223,7 @@ void smp_call_function_slave(int cpu)
 	atomic_inc(&scf_finished);
 }
 
-int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, 
+int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic,
 		      int wait)
 {
 	int cpus = num_online_cpus() - 1;
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 80c9c18aae94..7d51dd7201c3 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -421,7 +421,7 @@ int linux_main(int argc, char **argv)
 #ifndef CONFIG_HIGHMEM
 		highmem = 0;
 		printf("CONFIG_HIGHMEM not enabled - physical memory shrunk "
-		       "to %lu bytes\n", physmem_size);
+		       "to %Lu bytes\n", physmem_size);
 #endif
 	}
 
@@ -433,8 +433,8 @@ int linux_main(int argc, char **argv)
 
 	setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
 	if(init_maps(physmem_size, iomem_size, highmem)){
-		printf("Failed to allocate mem_map for %lu bytes of physical "
-		       "memory and %lu bytes of highmem\n", physmem_size,
+		printf("Failed to allocate mem_map for %Lu bytes of physical "
+		       "memory and %Lu bytes of highmem\n", physmem_size,
 		       highmem);
 		exit(1);
 	}
@@ -477,7 +477,8 @@ static struct notifier_block panic_exit_notifier = {
 
 void __init setup_arch(char **cmdline_p)
 {
-	notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);
+	atomic_notifier_chain_register(&panic_notifier_list,
+			&panic_exit_notifier);
 	paging_init();
         strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
  	*cmdline_p = command_line;
@@ -487,8 +488,7 @@ void __init setup_arch(char **cmdline_p)
 void __init check_bugs(void)
 {
 	arch_check_bugs();
-	check_sigio();
-	check_devanon();
+ 	os_check_bugs();
 }
 
 void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 08a4e628b24c..1659386b42bb 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -3,14 +3,17 @@
 # Licensed under the GPL
 #
 
-obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
-	start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o user_syms.o \
-	util.o drivers/ sys-$(SUBARCH)/
+obj-y = aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o sigio.o \
+	signal.o start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o \
+	user_syms.o util.o drivers/ sys-$(SUBARCH)/
 
 obj-$(CONFIG_MODE_SKAS) += skas/
+obj-$(CONFIG_TTY_LOG) += tty_log.o
+user-objs-$(CONFIG_TTY_LOG) += tty_log.o
 
-USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
-	start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o util.o
+USER_OBJS := $(user-objs-y) aio.o elf_aux.o file.o helper.o irq.o main.o mem.o \
+	process.o sigio.o signal.o start_up.o time.o trap.o tt.o tty.o \
+	uaccess.o umid.o util.o
 
 elf_aux.o: $(ARCH_DIR)/kernel-offsets.h
 CFLAGS_elf_aux.o += -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
new file mode 100644
index 000000000000..e599be423da1
--- /dev/null
+++ b/arch/um/os-Linux/irq.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/poll.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include "user_util.h"
+#include "kern_util.h"
+#include "user.h"
+#include "process.h"
+#include "sigio.h"
+#include "irq_user.h"
+#include "os.h"
+
+static struct pollfd *pollfds = NULL;
+static int pollfds_num = 0;
+static int pollfds_size = 0;
+
+int os_waiting_for_events(struct irq_fd *active_fds)
+{
+	struct irq_fd *irq_fd;
+	int i, n, err;
+
+	n = poll(pollfds, pollfds_num, 0);
+	if(n < 0){
+		err = -errno;
+		if(errno != EINTR)
+			printk("sigio_handler: os_waiting_for_events:"
+			       " poll returned %d, errno = %d\n", n, errno);
+		return err;
+	}
+
+	if(n == 0)
+		return 0;
+
+	irq_fd = active_fds;
+
+	for(i = 0; i < pollfds_num; i++){
+		if(pollfds[i].revents != 0){
+			irq_fd->current_events = pollfds[i].revents;
+			pollfds[i].fd = -1;
+		}
+		irq_fd = irq_fd->next;
+	}
+	return n;
+}
+
+int os_isatty(int fd)
+{
+	return(isatty(fd));
+}
+
+int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds)
+{
+	if (pollfds_num == pollfds_size) {
+		if (size_tmpfds <= pollfds_size * sizeof(pollfds[0])) {
+			/* return min size needed for new pollfds area */
+			return((pollfds_size + 1) * sizeof(pollfds[0]));
+		}
+
+		if(pollfds != NULL){
+			memcpy(tmp_pfd, pollfds,
+			       sizeof(pollfds[0]) * pollfds_size);
+			/* remove old pollfds */
+			kfree(pollfds);
+		}
+		pollfds = tmp_pfd;
+		pollfds_size++;
+	} else {
+		/* remove not used tmp_pfd */
+		if (tmp_pfd != NULL)
+			kfree(tmp_pfd);
+	}
+
+	pollfds[pollfds_num] = ((struct pollfd) { .fd 	= fd,
+						  .events 	= events,
+						  .revents 	= 0 });
+	pollfds_num++;
+
+	return(0);
+}
+
+void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg,
+		struct irq_fd *active_fds, struct irq_fd ***last_irq_ptr2)
+{
+	struct irq_fd **prev;
+	int i = 0;
+
+	prev = &active_fds;
+	while(*prev != NULL){
+		if((*test)(*prev, arg)){
+			struct irq_fd *old_fd = *prev;
+			if((pollfds[i].fd != -1) &&
+			   (pollfds[i].fd != (*prev)->fd)){
+				printk("os_free_irq_by_cb - mismatch between "
+				       "active_fds and pollfds, fd %d vs %d\n",
+				       (*prev)->fd, pollfds[i].fd);
+				goto out;
+			}
+
+			pollfds_num--;
+
+			/* This moves the *whole* array after pollfds[i]
+			 * (though it doesn't spot as such)!
+			 */
+
+			memmove(&pollfds[i], &pollfds[i + 1],
+			       (pollfds_num - i) * sizeof(pollfds[0]));
+			if(*last_irq_ptr2 == &old_fd->next)
+				*last_irq_ptr2 = prev;
+
+			*prev = (*prev)->next;
+			if(old_fd->type == IRQ_WRITE)
+				ignore_sigio_fd(old_fd->fd);
+			kfree(old_fd);
+			continue;
+		}
+		prev = &(*prev)->next;
+		i++;
+	}
+ out:
+	return;
+}
+
+
+int os_get_pollfd(int i)
+{
+	return(pollfds[i].fd);
+}
+
+void os_set_pollfd(int i, int fd)
+{
+	pollfds[i].fd = fd;
+}
+
+void os_set_ioignore(void)
+{
+	set_handler(SIGIO, SIG_IGN, 0, -1);
+}
+
+void init_irq_signals(int on_sigstack)
+{
+	__sighandler_t h;
+	int flags;
+
+	flags = on_sigstack ? SA_ONSTACK : 0;
+	if(timer_irq_inited) h = (__sighandler_t) alarm_handler;
+	else h = boot_timer_handler;
+
+	set_handler(SIGVTALRM, h, flags | SA_RESTART,
+		    SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
+	set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
+		    SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
+	signal(SIGWINCH, SIG_IGN);
+}
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/os-Linux/sigio.c
index f7b18e157d35..9ba942947146 100644
--- a/arch/um/kernel/sigio_user.c
+++ b/arch/um/os-Linux/sigio.c
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
@@ -20,128 +20,7 @@
 #include "sigio.h"
 #include "os.h"
 
-/* Changed during early boot */
-int pty_output_sigio = 0;
-int pty_close_sigio = 0;
-
-/* Used as a flag during SIGIO testing early in boot */
-static volatile int got_sigio = 0;
-
-void __init handler(int sig)
-{
-	got_sigio = 1;
-}
-
-struct openpty_arg {
-	int master;
-	int slave;
-	int err;
-};
-
-static void openpty_cb(void *arg)
-{
-	struct openpty_arg *info = arg;
-
-	info->err = 0;
-	if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
-		info->err = -errno;
-}
-
-void __init check_one_sigio(void (*proc)(int, int))
-{
-	struct sigaction old, new;
-	struct openpty_arg pty = { .master = -1, .slave = -1 };
-	int master, slave, err;
-
-	initial_thread_cb(openpty_cb, &pty);
-	if(pty.err){
-		printk("openpty failed, errno = %d\n", -pty.err);
-		return;
-	}
-
-	master = pty.master;
-	slave = pty.slave;
-
-	if((master == -1) || (slave == -1)){
-		printk("openpty failed to allocate a pty\n");
-		return;
-	}
-
-	/* Not now, but complain so we now where we failed. */
-	err = raw(master);
-	if (err < 0)
-		panic("check_sigio : __raw failed, errno = %d\n", -err);
-
-	err = os_sigio_async(master, slave);
-	if(err < 0)
-		panic("tty_fds : sigio_async failed, err = %d\n", -err);
-
-	if(sigaction(SIGIO, NULL, &old) < 0)
-		panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
-	new = old;
-	new.sa_handler = handler;
-	if(sigaction(SIGIO, &new, NULL) < 0)
-		panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
-
-	got_sigio = 0;
-	(*proc)(master, slave);
-		
-	os_close_file(master);
-	os_close_file(slave);
-
-	if(sigaction(SIGIO, &old, NULL) < 0)
-		panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
-}
-
-static void tty_output(int master, int slave)
-{
-	int n;
-	char buf[512];
-
-	printk("Checking that host ptys support output SIGIO...");
-
-	memset(buf, 0, sizeof(buf));
-
-	while(os_write_file(master, buf, sizeof(buf)) > 0) ;
-	if(errno != EAGAIN)
-		panic("check_sigio : write failed, errno = %d\n", errno);
-	while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
-
-	if (got_sigio) {
-		printk("Yes\n");
-		pty_output_sigio = 1;
-	} else if (n == -EAGAIN) {
-		printk("No, enabling workaround\n");
-	} else {
-		panic("check_sigio : read failed, err = %d\n", n);
-	}
-}
-
-static void tty_close(int master, int slave)
-{
-	printk("Checking that host ptys support SIGIO on close...");
-
-	os_close_file(slave);
-	if(got_sigio){
-		printk("Yes\n");
-		pty_close_sigio = 1;
-	}
-	else printk("No, enabling workaround\n");
-}
-
-void __init check_sigio(void)
-{
-	if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
-	   (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
-		printk("No pseudo-terminals available - skipping pty SIGIO "
-		       "check\n");
-		return;
-	}
-	check_one_sigio(tty_output);
-	check_one_sigio(tty_close);
-}
-
-/* Protected by sigio_lock(), also used by sigio_cleanup, which is an 
+/* Protected by sigio_lock(), also used by sigio_cleanup, which is an
  * exitcall.
  */
 static int write_sigio_pid = -1;
@@ -150,8 +29,10 @@ static int write_sigio_pid = -1;
  * the descriptors closed after it is killed.  So, it can't see them change.
  * On the UML side, they are changed under the sigio_lock.
  */
-static int write_sigio_fds[2] = { -1, -1 };
-static int sigio_private[2] = { -1, -1 };
+#define SIGIO_FDS_INIT {-1, -1}
+
+static int write_sigio_fds[2] = SIGIO_FDS_INIT;
+static int sigio_private[2] = SIGIO_FDS_INIT;
 
 struct pollfds {
 	struct pollfd *poll;
@@ -264,13 +145,13 @@ static void update_thread(void)
 	return;
  fail:
 	/* Critical section start */
-	if(write_sigio_pid != -1) 
+	if(write_sigio_pid != -1)
 		os_kill_process(write_sigio_pid, 1);
 	write_sigio_pid = -1;
-	os_close_file(sigio_private[0]);
-	os_close_file(sigio_private[1]);
-	os_close_file(write_sigio_fds[0]);
-	os_close_file(write_sigio_fds[1]);
+	close(sigio_private[0]);
+	close(sigio_private[1]);
+	close(write_sigio_fds[0]);
+	close(write_sigio_fds[1]);
 	/* Critical section end */
 	set_signals(flags);
 }
@@ -281,13 +162,13 @@ int add_sigio_fd(int fd, int read)
 
 	sigio_lock();
 	for(i = 0; i < current_poll.used; i++){
-		if(current_poll.poll[i].fd == fd) 
+		if(current_poll.poll[i].fd == fd)
 			goto out;
 	}
 
 	n = current_poll.used + 1;
 	err = need_poll(n);
-	if(err) 
+	if(err)
 		goto out;
 
 	for(i = 0; i < current_poll.used; i++)
@@ -316,7 +197,7 @@ int ignore_sigio_fd(int fd)
 	}
 	if(i == current_poll.used)
 		goto out;
-	
+
 	err = need_poll(current_poll.used - 1);
 	if(err)
 		goto out;
@@ -337,7 +218,7 @@ int ignore_sigio_fd(int fd)
 	return(err);
 }
 
-static struct pollfd* setup_initial_poll(int fd)
+static struct pollfd *setup_initial_poll(int fd)
 {
 	struct pollfd *p;
 
@@ -377,7 +258,7 @@ void write_sigio_workaround(void)
 	}
 	err = os_pipe(l_sigio_private, 1, 1);
 	if(err < 0){
-		printk("write_sigio_workaround - os_pipe 1 failed, "
+		printk("write_sigio_workaround - os_pipe 2 failed, "
 		       "err = %d\n", -err);
 		goto out_close1;
 	}
@@ -391,76 +272,52 @@ void write_sigio_workaround(void)
 	/* Did we race? Don't try to optimize this, please, it's not so likely
 	 * to happen, and no more than once at the boot. */
 	if(write_sigio_pid != -1)
-		goto out_unlock;
+		goto out_free;
 
-	write_sigio_pid = run_helper_thread(write_sigio_thread, NULL,
-					    CLONE_FILES | CLONE_VM, &stack, 0);
-
-	if (write_sigio_pid < 0)
-		goto out_clear;
+	current_poll = ((struct pollfds) { .poll 	= p,
+					   .used 	= 1,
+					   .size 	= 1 });
 
 	if (write_sigio_irq(l_write_sigio_fds[0]))
-		goto out_kill;
+		goto out_clear_poll;
 
-	/* Success, finally. */
 	memcpy(write_sigio_fds, l_write_sigio_fds, sizeof(l_write_sigio_fds));
 	memcpy(sigio_private, l_sigio_private, sizeof(l_sigio_private));
 
-	current_poll = ((struct pollfds) { .poll 	= p,
-					   .used 	= 1,
-					   .size 	= 1 });
+	write_sigio_pid = run_helper_thread(write_sigio_thread, NULL,
+					    CLONE_FILES | CLONE_VM, &stack, 0);
 
-	sigio_unlock();
-	return;
+	if (write_sigio_pid < 0)
+		goto out_clear;
 
- out_kill:
-	l_write_sigio_pid = write_sigio_pid;
-	write_sigio_pid = -1;
 	sigio_unlock();
-	/* Going to call waitpid, avoid holding the lock. */
-	os_kill_process(l_write_sigio_pid, 1);
-	goto out_free;
+	return;
 
- out_clear:
+out_clear:
 	write_sigio_pid = -1;
- out_unlock:
-	sigio_unlock();
- out_free:
+	write_sigio_fds[0] = -1;
+	write_sigio_fds[1] = -1;
+	sigio_private[0] = -1;
+	sigio_private[1] = -1;
+out_clear_poll:
+	current_poll = ((struct pollfds) { .poll	= NULL,
+					   .size	= 0,
+					   .used	= 0 });
+out_free:
 	kfree(p);
- out_close2:
-	os_close_file(l_sigio_private[0]);
-	os_close_file(l_sigio_private[1]);
- out_close1:
-	os_close_file(l_write_sigio_fds[0]);
-	os_close_file(l_write_sigio_fds[1]);
-	return;
-}
-
-int read_sigio_fd(int fd)
-{
-	int n;
-	char c;
-
-	n = os_read_file(fd, &c, sizeof(c));
-	if(n != sizeof(c)){
-		if(n < 0) {
-			printk("read_sigio_fd - read failed, err = %d\n", -n);
-			return(n);
-		}
-		else {
-			printk("read_sigio_fd - short read, bytes = %d\n", n);
-			return(-EIO);
-		}
-	}
-	return(n);
+	sigio_unlock();
+out_close2:
+	close(l_sigio_private[0]);
+	close(l_sigio_private[1]);
+out_close1:
+	close(l_write_sigio_fds[0]);
+	close(l_write_sigio_fds[1]);
 }
 
-static void sigio_cleanup(void)
+void sigio_cleanup(void)
 {
-	if (write_sigio_pid != -1) {
+	if(write_sigio_pid != -1){
 		os_kill_process(write_sigio_pid, 1);
 		write_sigio_pid = -1;
 	}
 }
-
-__uml_exitcall(sigio_cleanup);
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 829d6b0d8b02..32753131f8d8 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -3,6 +3,7 @@
  * Licensed under the GPL
  */
 
+#include <pty.h>
 #include <stdio.h>
 #include <stddef.h>
 #include <stdarg.h>
@@ -539,3 +540,130 @@ int __init parse_iomem(char *str, int *add)
 	return(1);
 }
 
+
+/* Changed during early boot */
+int pty_output_sigio = 0;
+int pty_close_sigio = 0;
+
+/* Used as a flag during SIGIO testing early in boot */
+static volatile int got_sigio = 0;
+
+static void __init handler(int sig)
+{
+	got_sigio = 1;
+}
+
+struct openpty_arg {
+	int master;
+	int slave;
+	int err;
+};
+
+static void openpty_cb(void *arg)
+{
+	struct openpty_arg *info = arg;
+
+	info->err = 0;
+	if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
+		info->err = -errno;
+}
+
+static void __init check_one_sigio(void (*proc)(int, int))
+{
+	struct sigaction old, new;
+	struct openpty_arg pty = { .master = -1, .slave = -1 };
+	int master, slave, err;
+
+	initial_thread_cb(openpty_cb, &pty);
+	if(pty.err){
+		printk("openpty failed, errno = %d\n", -pty.err);
+		return;
+	}
+
+	master = pty.master;
+	slave = pty.slave;
+
+	if((master == -1) || (slave == -1)){
+		printk("openpty failed to allocate a pty\n");
+		return;
+	}
+
+	/* Not now, but complain so we now where we failed. */
+	err = raw(master);
+	if (err < 0)
+		panic("check_sigio : __raw failed, errno = %d\n", -err);
+
+	err = os_sigio_async(master, slave);
+	if(err < 0)
+		panic("tty_fds : sigio_async failed, err = %d\n", -err);
+
+	if(sigaction(SIGIO, NULL, &old) < 0)
+		panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
+	new = old;
+	new.sa_handler = handler;
+	if(sigaction(SIGIO, &new, NULL) < 0)
+		panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
+
+	got_sigio = 0;
+	(*proc)(master, slave);
+
+	close(master);
+	close(slave);
+
+	if(sigaction(SIGIO, &old, NULL) < 0)
+		panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
+}
+
+static void tty_output(int master, int slave)
+{
+	int n;
+	char buf[512];
+
+	printk("Checking that host ptys support output SIGIO...");
+
+	memset(buf, 0, sizeof(buf));
+
+	while(os_write_file(master, buf, sizeof(buf)) > 0) ;
+	if(errno != EAGAIN)
+		panic("check_sigio : write failed, errno = %d\n", errno);
+	while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
+
+	if(got_sigio){
+		printk("Yes\n");
+		pty_output_sigio = 1;
+	}
+	else if(n == -EAGAIN) printk("No, enabling workaround\n");
+	else panic("check_sigio : read failed, err = %d\n", n);
+}
+
+static void tty_close(int master, int slave)
+{
+	printk("Checking that host ptys support SIGIO on close...");
+
+	close(slave);
+	if(got_sigio){
+		printk("Yes\n");
+		pty_close_sigio = 1;
+	}
+	else printk("No, enabling workaround\n");
+}
+
+void __init check_sigio(void)
+{
+	if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
+	   (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
+		printk("No pseudo-terminals available - skipping pty SIGIO "
+		       "check\n");
+		return;
+	}
+	check_one_sigio(tty_output);
+	check_one_sigio(tty_close);
+}
+
+void os_check_bugs(void)
+{
+	check_ptrace();
+	check_sigio();
+	check_devanon();
+}
+
diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c
index 919d19f11537..5461a065bbb9 100644
--- a/arch/um/os-Linux/tt.c
+++ b/arch/um/os-Linux/tt.c
@@ -110,6 +110,16 @@ int wait_for_stop(int pid, int sig, int cont_type, void *relay)
 	}
 }
 
+void forward_ipi(int fd, int pid)
+{
+	int err;
+
+	err = os_set_owner(fd, pid);
+	if(err < 0)
+		printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
+		       "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
+}
+
 /*
  *-------------------------
  * only for tt mode (will be deleted in future...)
diff --git a/arch/um/kernel/tty_log.c b/arch/um/os-Linux/tty_log.c
index 9ada656f68ce..c6ba56c1560f 100644
--- a/arch/um/kernel/tty_log.c
+++ b/arch/um/os-Linux/tty_log.c
@@ -1,5 +1,5 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and 
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and
  * geoffrey hing <ghing@net.ohio-state.edu>
  * Licensed under the GPL
  */
@@ -58,7 +58,7 @@ int open_tty_log(void *tty, void *current_tty)
 		return(tty_log_fd);
 	}
 
-	sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, 
+	sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec,
  		(unsigned int) tv.tv_usec);
 
 	fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))),
@@ -216,15 +216,3 @@ __uml_setup("tty_log_fd=", set_tty_log_fd,
 "    tty data will be written.  Preconfigure the descriptor with something\n"
 "    like '10>tty_log tty_log_fd=10'.\n\n"
 );
-
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c
index ecf107ae5ac8..198e59163288 100644
--- a/arch/um/os-Linux/umid.c
+++ b/arch/um/os-Linux/umid.c
@@ -143,8 +143,10 @@ static int not_dead_yet(char *dir)
 		goto out_close;
 	}
 
-	if((kill(p, 0) == 0) || (errno != ESRCH))
+	if((kill(p, 0) == 0) || (errno != ESRCH)){
+		printk("umid \"%s\" is already in use by pid %d\n", umid, p);
 		return 1;
+	}
 
 	err = actually_do_remove(dir);
 	if(err)
@@ -234,33 +236,44 @@ int __init make_umid(void)
 	err = mkdir(tmp, 0777);
 	if(err < 0){
 		err = -errno;
-		if(errno != EEXIST)
+		if(err != -EEXIST)
 			goto err;
 
-		if(not_dead_yet(tmp) < 0)
+		/* 1   -> this umid is already in use
+		 * < 0 -> we couldn't remove the umid directory
+		 * In either case, we can't use this umid, so return -EEXIST.
+		 */
+		if(not_dead_yet(tmp) != 0)
 			goto err;
 
 		err = mkdir(tmp, 0777);
 	}
-	if(err < 0){
-		printk("Failed to create '%s' - err = %d\n", umid, err);
-		goto err_rmdir;
+	if(err){
+		err = -errno;
+		printk("Failed to create '%s' - err = %d\n", umid, -errno);
+		goto err;
 	}
 
 	umid_setup = 1;
 
 	create_pid_file();
 
-	return 0;
-
- err_rmdir:
-	rmdir(tmp);
+	err = 0;
  err:
 	return err;
 }
 
 static int __init make_umid_init(void)
 {
+	if(!make_umid())
+		return 0;
+
+	/* If initializing with the given umid failed, then try again with
+	 * a random one.
+	 */
+	printk("Failed to initialize umid \"%s\", trying with a random umid\n",
+	       umid);
+	*umid = '\0';
 	make_umid();
 
 	return 0;
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index e839ce65ad28..8032a105949a 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -6,6 +6,7 @@
 #include <linux/config.h>
 #include <linux/compiler.h>
 #include "linux/sched.h"
+#include "linux/mm.h"
 #include "asm/elf.h"
 #include "asm/ptrace.h"
 #include "asm/uaccess.h"
@@ -26,9 +27,17 @@ int is_syscall(unsigned long addr)
 
 	n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
 	if(n){
-		printk("is_syscall : failed to read instruction from 0x%lx\n",
-		       addr);
-		return(0);
+		/* access_process_vm() grants access to vsyscall and stub,
+		 * while copy_from_user doesn't. Maybe access_process_vm is
+		 * slow, but that doesn't matter, since it will be called only
+		 * in case of singlestepping, if copy_from_user failed.
+		 */
+		n = access_process_vm(current, addr, &instr, sizeof(instr), 0);
+		if(n != sizeof(instr)) {
+			printk("is_syscall : failed to read instruction from "
+			       "0x%lx\n", addr);
+			return(1);
+		}
 	}
 	/* int 0x80 or sysenter */
 	return((instr == 0x80cd) || (instr == 0x340f));
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 7cd1a82dc8c2..33a40f5ef0d2 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -58,7 +58,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
 }
 
 int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
-                         struct pt_regs *regs)
+                         struct pt_regs *regs, unsigned long sp)
 {
   	struct sigcontext sc;
 	unsigned long fpregs[HOST_FP_SIZE];
@@ -72,7 +72,7 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
 	sc.edi = REGS_EDI(regs->regs.skas.regs);
 	sc.esi = REGS_ESI(regs->regs.skas.regs);
 	sc.ebp = REGS_EBP(regs->regs.skas.regs);
-	sc.esp = REGS_SP(regs->regs.skas.regs);
+	sc.esp = sp;
 	sc.ebx = REGS_EBX(regs->regs.skas.regs);
 	sc.edx = REGS_EDX(regs->regs.skas.regs);
 	sc.ecx = REGS_ECX(regs->regs.skas.regs);
@@ -132,7 +132,7 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from,
 }
 
 int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp,
-		       struct sigcontext *from, int fpsize)
+		       struct sigcontext *from, int fpsize, unsigned long sp)
 {
 	struct _fpstate *to_fp, *from_fp;
 	int err;
@@ -140,11 +140,18 @@ int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp,
 	to_fp =	(fp ? fp : (struct _fpstate *) (to + 1));
 	from_fp = from->fpstate;
 	err = copy_to_user(to, from, sizeof(*to));
+
+	/* The SP in the sigcontext is the updated one for the signal
+	 * delivery.  The sp passed in is the original, and this needs
+	 * to be restored, so we stick it in separately.
+	 */
+	err |= copy_to_user(&SC_SP(to), sp, sizeof(sp));
+
 	if(from_fp != NULL){
 		err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate));
 		err |= copy_to_user(to_fp, from_fp, fpsize);
 	}
-	return(err);
+	return err;
 }
 #endif
 
@@ -159,11 +166,11 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from)
 }
 
 static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp,
-			   struct pt_regs *from)
+			   struct pt_regs *from, unsigned long sp)
 {
 	return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
-					      sizeof(*fp)),
-                           copy_sc_to_user_skas(to, fp, from)));
+					      sizeof(*fp), sp),
+                           copy_sc_to_user_skas(to, fp, from, sp)));
 }
 
 static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp,
@@ -174,7 +181,7 @@ static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp,
 	err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
 	err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
 	err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
-	err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs);
+	err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs, sp);
 	err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
 	return(err);
 }
@@ -207,6 +214,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
 {
 	struct sigframe __user *frame;
 	void *restorer;
+	unsigned long save_sp = PT_REGS_SP(regs);
 	int err = 0;
 
 	stack_top &= -8UL;
@@ -218,9 +226,19 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
 	if(ka->sa.sa_flags & SA_RESTORER)
 		restorer = ka->sa.sa_restorer;
 
+	/* Update SP now because the page fault handler refuses to extend
+	 * the stack if the faulting address is too far below the current
+	 * SP, which frame now certainly is.  If there's an error, the original
+	 * value is restored on the way out.
+	 * When writing the sigcontext to the stack, we have to write the
+	 * original value, so that's passed to copy_sc_to_user, which does
+	 * the right thing with it.
+	 */
+	PT_REGS_SP(regs) = (unsigned long) frame;
+
 	err |= __put_user(restorer, &frame->pretcode);
 	err |= __put_user(sig, &frame->sig);
-	err |= copy_sc_to_user(&frame->sc, NULL, regs);
+	err |= copy_sc_to_user(&frame->sc, NULL, regs, save_sp);
 	err |= __put_user(mask->sig[0], &frame->sc.oldmask);
 	if (_NSIG_WORDS > 1)
 		err |= __copy_to_user(&frame->extramask, &mask->sig[1],
@@ -238,7 +256,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
 	err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
 
 	if(err)
-		return(err);
+		goto err;
 
 	PT_REGS_SP(regs) = (unsigned long) frame;
 	PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
@@ -248,7 +266,11 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
 
 	if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
 		ptrace_notify(SIGTRAP);
-	return(0);
+	return 0;
+
+err:
+	PT_REGS_SP(regs) = save_sp;
+	return err;
 }
 
 int setup_signal_stack_si(unsigned long stack_top, int sig,
@@ -257,6 +279,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
 {
 	struct rt_sigframe __user *frame;
 	void *restorer;
+	unsigned long save_sp = PT_REGS_SP(regs);
 	int err = 0;
 
 	stack_top &= -8UL;
@@ -268,13 +291,16 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
 	if(ka->sa.sa_flags & SA_RESTORER)
 		restorer = ka->sa.sa_restorer;
 
+	/* See comment above about why this is here */
+	PT_REGS_SP(regs) = (unsigned long) frame;
+
 	err |= __put_user(restorer, &frame->pretcode);
 	err |= __put_user(sig, &frame->sig);
 	err |= __put_user(&frame->info, &frame->pinfo);
 	err |= __put_user(&frame->uc, &frame->puc);
 	err |= copy_siginfo_to_user(&frame->info, info);
 	err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask,
-				     PT_REGS_SP(regs));
+				     save_sp);
 
 	/*
 	 * This is movl $,%eax ; int $0x80
@@ -288,9 +314,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
 	err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
 
 	if(err)
-		return(err);
+		goto err;
 
-	PT_REGS_SP(regs) = (unsigned long) frame;
 	PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
 	PT_REGS_EAX(regs) = (unsigned long) sig;
 	PT_REGS_EDX(regs) = (unsigned long) &frame->info;
@@ -298,7 +323,11 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
 
 	if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
 		ptrace_notify(SIGTRAP);
-	return(0);
+	return 0;
+
+err:
+	PT_REGS_SP(regs) = save_sp;
+	return err;
 }
 
 long sys_sigreturn(struct pt_regs regs)
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c
index 26b68675053d..6f4ef2b7fa4a 100644
--- a/arch/um/sys-i386/user-offsets.c
+++ b/arch/um/sys-i386/user-offsets.c
@@ -3,12 +3,13 @@
 #include <asm/ptrace.h>
 #include <asm/user.h>
 #include <linux/stddef.h>
+#include <sys/poll.h>
 
 #define DEFINE(sym, val) \
-        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+	asm volatile("\n->" #sym " %0 " #val : : "i" (val))
 
 #define DEFINE_LONGS(sym, val) \
-        asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long)))
+	asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long)))
 
 #define OFFSET(sym, str, mem) \
 	DEFINE(sym, offsetof(struct str, mem));
@@ -67,4 +68,9 @@ void foo(void)
 	DEFINE(HOST_ES, ES);
 	DEFINE(HOST_GS, GS);
 	DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct));
+
+	/* XXX Duplicated between i386 and x86_64 */
+	DEFINE(UM_POLLIN, POLLIN);
+	DEFINE(UM_POLLPRI, POLLPRI);
+	DEFINE(UM_POLLOUT, POLLOUT);
 }
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
index 74eee5c7c6dd..147bbf05cbc2 100644
--- a/arch/um/sys-x86_64/ptrace.c
+++ b/arch/um/sys-x86_64/ptrace.c
@@ -8,6 +8,7 @@
 #include <asm/ptrace.h>
 #include <linux/sched.h>
 #include <linux/errno.h>
+#include <linux/mm.h>
 #include <asm/uaccess.h>
 #include <asm/elf.h>
 
@@ -136,9 +137,28 @@ void arch_switch(void)
 */
 }
 
+/* XXX Mostly copied from sys-i386 */
 int is_syscall(unsigned long addr)
 {
-	panic("is_syscall");
+	unsigned short instr;
+	int n;
+
+	n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
+	if(n){
+		/* access_process_vm() grants access to vsyscall and stub,
+		 * while copy_from_user doesn't. Maybe access_process_vm is
+		 * slow, but that doesn't matter, since it will be called only
+		 * in case of singlestepping, if copy_from_user failed.
+		 */
+		n = access_process_vm(current, addr, &instr, sizeof(instr), 0);
+		if(n != sizeof(instr)) {
+			printk("is_syscall : failed to read instruction from "
+			       "0x%lx\n", addr);
+			return(1);
+		}
+	}
+	/* sysenter */
+	return(instr == 0x050f);
 }
 
 int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
index fe1d065332b1..e75c4e1838b0 100644
--- a/arch/um/sys-x86_64/signal.c
+++ b/arch/um/sys-x86_64/signal.c
@@ -55,7 +55,8 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
 }
 
 int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
-                        struct pt_regs *regs, unsigned long mask)
+			 struct pt_regs *regs, unsigned long mask,
+			 unsigned long sp)
 {
         struct faultinfo * fi = &current->thread.arch.faultinfo;
 	int err = 0;
@@ -70,7 +71,11 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
 	err |= PUTREG(regs, RDI, to, rdi);
 	err |= PUTREG(regs, RSI, to, rsi);
 	err |= PUTREG(regs, RBP, to, rbp);
-	err |= PUTREG(regs, RSP, to, rsp);
+        /* Must use orignal RSP, which is passed in, rather than what's in
+         * the pt_regs, because that's already been updated to point at the
+         * signal frame.
+         */
+	err |= __put_user(sp, &to->rsp);
 	err |= PUTREG(regs, RBX, to, rbx);
 	err |= PUTREG(regs, RDX, to, rdx);
 	err |= PUTREG(regs, RCX, to, rcx);
@@ -102,7 +107,7 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
 
 #ifdef CONFIG_MODE_TT
 int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from,
-                        int fpsize)
+			 int fpsize)
 {
 	struct _fpstate *to_fp, *from_fp;
 	unsigned long sigs;
@@ -120,7 +125,7 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from,
 }
 
 int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp,
-                      struct sigcontext *from, int fpsize)
+		       struct sigcontext *from, int fpsize, unsigned long sp)
 {
 	struct _fpstate *to_fp, *from_fp;
 	int err;
@@ -128,11 +133,17 @@ int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp,
 	to_fp = (fp ? fp : (struct _fpstate *) (to + 1));
 	from_fp = from->fpstate;
 	err = copy_to_user(to, from, sizeof(*to));
+	/* The SP in the sigcontext is the updated one for the signal
+	 * delivery.  The sp passed in is the original, and this needs
+	 * to be restored, so we stick it in separately.
+	 */
+	err |= copy_to_user(&SC_SP(to), sp, sizeof(sp));
+
 	if(from_fp != NULL){
 		err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate));
 		err |= copy_to_user(to_fp, from_fp, fpsize);
 	}
-	return(err);
+	return err;
 }
 
 #endif
@@ -148,11 +159,12 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from)
 }
 
 static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp,
-                          struct pt_regs *from, unsigned long mask)
+			   struct pt_regs *from, unsigned long mask,
+			   unsigned long sp)
 {
        return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
-                                             sizeof(*fp)),
-                          copy_sc_to_user_skas(to, fp, from, mask)));
+                                             sizeof(*fp), sp),
+                          copy_sc_to_user_skas(to, fp, from, mask, sp)));
 }
 
 struct rt_sigframe
@@ -170,6 +182,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
 {
 	struct rt_sigframe __user *frame;
 	struct _fpstate __user *fp = NULL;
+	unsigned long save_sp = PT_REGS_RSP(regs);
 	int err = 0;
 	struct task_struct *me = current;
 
@@ -193,14 +206,25 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
 			goto out;
 	}
 
+	/* Update SP now because the page fault handler refuses to extend
+	 * the stack if the faulting address is too far below the current
+	 * SP, which frame now certainly is.  If there's an error, the original
+	 * value is restored on the way out.
+	 * When writing the sigcontext to the stack, we have to write the
+	 * original value, so that's passed to copy_sc_to_user, which does
+	 * the right thing with it.
+	 */
+	PT_REGS_RSP(regs) = (unsigned long) frame;
+
 	/* Create the ucontext.  */
 	err |= __put_user(0, &frame->uc.uc_flags);
 	err |= __put_user(0, &frame->uc.uc_link);
 	err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-	err |= __put_user(sas_ss_flags(PT_REGS_SP(regs)),
+	err |= __put_user(sas_ss_flags(save_sp),
 			  &frame->uc.uc_stack.ss_flags);
 	err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
-	err |= copy_sc_to_user(&frame->uc.uc_mcontext, fp, regs, set->sig[0]);
+	err |= copy_sc_to_user(&frame->uc.uc_mcontext, fp, regs, set->sig[0],
+		save_sp);
 	err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
 	if (sizeof(*set) == 16) {
 		__put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
@@ -217,10 +241,10 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
 		err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
 	else
 		/* could use a vstub here */
-		goto out;
+		goto restore_sp;
 
 	if (err)
-		goto out;
+		goto restore_sp;
 
 	/* Set up registers for signal handler */
 	{
@@ -238,10 +262,12 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
 	PT_REGS_RSI(regs) = (unsigned long) &frame->info;
 	PT_REGS_RDX(regs) = (unsigned long) &frame->uc;
 	PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler;
-
-	PT_REGS_RSP(regs) = (unsigned long) frame;
  out:
-	return(err);
+	return err;
+
+restore_sp:
+	PT_REGS_RSP(regs) = save_sp;
+	return err;
 }
 
 long sys_rt_sigreturn(struct pt_regs *regs)
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
index 7bd54a921cf7..899cebb57c3f 100644
--- a/arch/um/sys-x86_64/user-offsets.c
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <stddef.h>
 #include <signal.h>
+#include <sys/poll.h>
 #define __FRAME_OFFSETS
 #include <asm/ptrace.h>
 #include <asm/types.h>
@@ -88,4 +89,9 @@ void foo(void)
 	DEFINE_LONGS(HOST_IP, RIP);
 	DEFINE_LONGS(HOST_SP, RSP);
 	DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct));
+
+	/* XXX Duplicated between i386 and x86_64 */
+	DEFINE(UM_POLLIN, POLLIN);
+	DEFINE(UM_POLLPRI, POLLPRI);
+	DEFINE(UM_POLLOUT, POLLOUT);
 }
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 45efe0ca88f8..4310b4a311a5 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -250,6 +250,15 @@ config SCHED_SMT
 	  cost of slightly increased overhead in some places. If unsure say
 	  N here.
 
+config SCHED_MC
+	bool "Multi-core scheduler support"
+	depends on SMP
+	default y
+	help
+	  Multi-core scheduler support improves the CPU scheduler's decision
+	  making when dealing with multi-core CPU chips at a cost of slightly
+	  increased overhead in some places. If unsure say N here.
+
 source "kernel/Kconfig.preempt"
 
 config NUMA
@@ -325,6 +334,10 @@ config HAVE_ARCH_EARLY_PFN_TO_NID
 	def_bool y
 	depends on NUMA
 
+config OUT_OF_LINE_PFN_TO_PAGE
+	def_bool y
+	depends on DISCONTIGMEM
+
 config NR_CPUS
 	int "Maximum number of CPUs (2-256)"
 	range 2 255
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index 7549a4389fbf..35b2faccdc6c 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -688,6 +688,8 @@ ia32_sys_call_table:
 	.quad sys_ni_syscall		/* pselect6 for now */
 	.quad sys_ni_syscall		/* ppoll for now */
 	.quad sys_unshare		/* 310 */
+	.quad compat_sys_set_robust_list
+	.quad compat_sys_get_robust_list
 ia32_syscall_end:		
 	.rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
 		.quad ni_syscall
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 0370720515f1..70dd8e5c6889 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -66,24 +66,17 @@ EXPORT_SYMBOL(boot_option_idle_override);
 void (*pm_idle)(void);
 static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
 
-static struct notifier_block *idle_notifier;
-static DEFINE_SPINLOCK(idle_notifier_lock);
+static ATOMIC_NOTIFIER_HEAD(idle_notifier);
 
 void idle_notifier_register(struct notifier_block *n)
 {
-	unsigned long flags;
-	spin_lock_irqsave(&idle_notifier_lock, flags);
-	notifier_chain_register(&idle_notifier, n);
-	spin_unlock_irqrestore(&idle_notifier_lock, flags);
+	atomic_notifier_chain_register(&idle_notifier, n);
 }
 EXPORT_SYMBOL_GPL(idle_notifier_register);
 
 void idle_notifier_unregister(struct notifier_block *n)
 {
-	unsigned long flags;
-	spin_lock_irqsave(&idle_notifier_lock, flags);
-	notifier_chain_unregister(&idle_notifier, n);
-	spin_unlock_irqrestore(&idle_notifier_lock, flags);
+	atomic_notifier_chain_unregister(&idle_notifier, n);
 }
 EXPORT_SYMBOL(idle_notifier_unregister);
 
@@ -93,13 +86,13 @@ static DEFINE_PER_CPU(enum idle_state, idle_state) = CPU_NOT_IDLE;
 void enter_idle(void)
 {
 	__get_cpu_var(idle_state) = CPU_IDLE;
-	notifier_call_chain(&idle_notifier, IDLE_START, NULL);
+	atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL);
 }
 
 static void __exit_idle(void)
 {
 	__get_cpu_var(idle_state) = CPU_NOT_IDLE;
-	notifier_call_chain(&idle_notifier, IDLE_END, NULL);
+	atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL);
 }
 
 /* Called from interrupts to signify idle end */
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index a57eec8311a7..d1f3e9272c05 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -962,7 +962,6 @@ static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
 
 	cpuid(1, &eax, &ebx, &ecx, &edx);
 
-	c->apicid = phys_pkg_id(0);
 
 	if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
 		return;
@@ -1171,6 +1170,8 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
 			c->x86_capability[2] = cpuid_edx(0x80860001);
 	}
 
+	c->apicid = phys_pkg_id(0);
+
 	/*
 	 * Vendor-specific initialization.  In this section we
 	 * canonicalize the feature flags, meaning if there are
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 66e98659d077..ea48fa638070 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -68,6 +68,9 @@ u8 phys_proc_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
 /* core ID of each logical CPU */
 u8 cpu_core_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
 
+/* Last level cache ID of each logical CPU */
+u8 cpu_llc_id[NR_CPUS] __cpuinitdata  = {[0 ... NR_CPUS-1] = BAD_APICID};
+
 /* Bitmask of currently online CPUs */
 cpumask_t cpu_online_map __read_mostly;
 
@@ -445,6 +448,18 @@ void __cpuinit smp_callin(void)
 	cpu_set(cpuid, cpu_callin_map);
 }
 
+/* maps the cpu to the sched domain representing multi-core */
+cpumask_t cpu_coregroup_map(int cpu)
+{
+	struct cpuinfo_x86 *c = cpu_data + cpu;
+	/*
+	 * For perf, we return last level cache shared map.
+	 * TBD: when power saving sched policy is added, we will return
+	 *      cpu_core_map when power saving policy is enabled
+	 */
+	return c->llc_shared_map;
+}
+
 /* representing cpus for which sibling maps can be computed */
 static cpumask_t cpu_sibling_setup_map;
 
@@ -463,12 +478,16 @@ static inline void set_cpu_sibling_map(int cpu)
 				cpu_set(cpu, cpu_sibling_map[i]);
 				cpu_set(i, cpu_core_map[cpu]);
 				cpu_set(cpu, cpu_core_map[i]);
+				cpu_set(i, c[cpu].llc_shared_map);
+				cpu_set(cpu, c[i].llc_shared_map);
 			}
 		}
 	} else {
 		cpu_set(cpu, cpu_sibling_map[cpu]);
 	}
 
+	cpu_set(cpu, c[cpu].llc_shared_map);
+
 	if (current_cpu_data.x86_max_cores == 1) {
 		cpu_core_map[cpu] = cpu_sibling_map[cpu];
 		c[cpu].booted_cores = 1;
@@ -476,6 +495,11 @@ static inline void set_cpu_sibling_map(int cpu)
 	}
 
 	for_each_cpu_mask(i, cpu_sibling_setup_map) {
+		if (cpu_llc_id[cpu] != BAD_APICID &&
+		    cpu_llc_id[cpu] == cpu_llc_id[i]) {
+			cpu_set(i, c[cpu].llc_shared_map);
+			cpu_set(cpu, c[i].llc_shared_map);
+		}
 		if (phys_proc_id[cpu] == phys_proc_id[i]) {
 			cpu_set(i, cpu_core_map[cpu]);
 			cpu_set(cpu, cpu_core_map[i]);
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 7f58fa682491..473b514b66e4 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -504,42 +504,25 @@ unsigned long long sched_clock(void)
 
 static unsigned long get_cmos_time(void)
 {
-	unsigned int timeout = 1000000, year, mon, day, hour, min, sec;
-	unsigned char uip = 0, this = 0;
+	unsigned int year, mon, day, hour, min, sec;
 	unsigned long flags;
 	unsigned extyear = 0;
 
-/*
- * The Linux interpretation of the CMOS clock register contents: When the
- * Update-In-Progress (UIP) flag goes from 1 to 0, the RTC registers show the
- * second which has precisely just started. Waiting for this can take up to 1
- * second, we timeout approximately after 2.4 seconds on a machine with
- * standard 8.3 MHz ISA bus.
- */
-
 	spin_lock_irqsave(&rtc_lock, flags);
 
-	while (timeout && (!uip || this)) {
-		uip |= this;
-		this = CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP;
-		timeout--;
-	}
-
-	/*
-	 * Here we are safe to assume the registers won't change for a whole
-	 * second, so we just go ahead and read them.
- 	 */
-	sec = CMOS_READ(RTC_SECONDS);
-	min = CMOS_READ(RTC_MINUTES);
-	hour = CMOS_READ(RTC_HOURS);
-	day = CMOS_READ(RTC_DAY_OF_MONTH);
-	mon = CMOS_READ(RTC_MONTH);
-	year = CMOS_READ(RTC_YEAR);
-
+	do {
+		sec = CMOS_READ(RTC_SECONDS);
+		min = CMOS_READ(RTC_MINUTES);
+		hour = CMOS_READ(RTC_HOURS);
+		day = CMOS_READ(RTC_DAY_OF_MONTH);
+		mon = CMOS_READ(RTC_MONTH);
+		year = CMOS_READ(RTC_YEAR);
 #ifdef CONFIG_ACPI
-	if (acpi_fadt.revision >= FADT2_REVISION_ID && acpi_fadt.century)
-		extyear = CMOS_READ(acpi_fadt.century);
+		if (acpi_fadt.revision >= FADT2_REVISION_ID &&
+					acpi_fadt.century)
+			extyear = CMOS_READ(acpi_fadt.century);
 #endif
+	} while (sec != CMOS_READ(RTC_SECONDS));
 
 	spin_unlock_irqrestore(&rtc_lock, flags);
 
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 7b148309c529..edaa9fe654dc 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -69,20 +69,20 @@ asmlinkage void alignment_check(void);
 asmlinkage void machine_check(void);
 asmlinkage void spurious_interrupt_bug(void);
 
-struct notifier_block *die_chain;
-static DEFINE_SPINLOCK(die_notifier_lock);
+ATOMIC_NOTIFIER_HEAD(die_chain);
 
 int register_die_notifier(struct notifier_block *nb)
 {
-	int err = 0;
-	unsigned long flags;
-
 	vmalloc_sync_all();
-	spin_lock_irqsave(&die_notifier_lock, flags);
-	err = notifier_chain_register(&die_chain, nb);
-	spin_unlock_irqrestore(&die_notifier_lock, flags);
-	return err;
+	return atomic_notifier_chain_register(&die_chain, nb);
+}
+EXPORT_SYMBOL(register_die_notifier);
+
+int unregister_die_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_unregister(&die_chain, nb);
 }
+EXPORT_SYMBOL(unregister_die_notifier);
 
 static inline void conditional_sti(struct pt_regs *regs)
 {
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index b04415625442..e5f7f1c34462 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -72,7 +72,7 @@ void show_mem(void)
 	show_free_areas();
 	printk(KERN_INFO "Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
 
-	for_each_pgdat(pgdat) {
+	for_each_online_pgdat(pgdat) {
                for (i = 0; i < pgdat->node_spanned_pages; ++i) {
 			page = pfn_to_page(pgdat->node_start_pfn + i);
 			total++;
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
index 63c72641b737..4be82d6e2b48 100644
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -377,21 +377,6 @@ EXPORT_SYMBOL(node_data);
  * Should do that.
  */
 
-/* Requires pfn_valid(pfn) to be true */
-struct page *pfn_to_page(unsigned long pfn)
-{
-	int nid = phys_to_nid(((unsigned long)(pfn)) << PAGE_SHIFT);
-	return (pfn - node_start_pfn(nid)) + NODE_DATA(nid)->node_mem_map;
-}
-EXPORT_SYMBOL(pfn_to_page);
-
-unsigned long page_to_pfn(struct page *page)
-{
-	return (long)(((page) - page_zone(page)->zone_mem_map) +
-		      page_zone(page)->zone_start_pfn);
-}
-EXPORT_SYMBOL(page_to_pfn);
-
 int pfn_valid(unsigned long pfn)
 {
 	unsigned nid;
diff --git a/arch/xtensa/platform-iss/setup.c b/arch/xtensa/platform-iss/setup.c
index 2e6dcbf0cc04..23790a5610e2 100644
--- a/arch/xtensa/platform-iss/setup.c
+++ b/arch/xtensa/platform-iss/setup.c
@@ -108,5 +108,5 @@ static struct notifier_block iss_panic_block = {
 
 void __init platform_setup(char **p_cmdline)
 {
-	notifier_chain_register(&panic_notifier_list, &iss_panic_block);
+	atomic_notifier_chain_register(&panic_notifier_list, &iss_panic_block);
 }