summary refs log tree commit diff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-09-07 17:00:53 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-07 17:00:53 -0700
commit1077682b2f97cee76a79cf38bab3fa022a97d9f8 (patch)
treee0e7dff35e3f38b9e360e702903e132c991f3f22
parentdc9ca2af4917ce4e545fa3eb1d845c555128cabc (diff)
parentbafa49cc1b800df4748b29e2b038ff029d7c8747 (diff)
downloadlinux-1077682b2f97cee76a79cf38bab3fa022a97d9f8.tar.gz
Merge master.kernel.org:/home/rmk/linux-2.6-arm
-rw-r--r--arch/arm/boot/compressed/head-sharpsl.S111
-rw-r--r--arch/arm/configs/omap_h2_1610_defconfig290
-rw-r--r--arch/arm/mach-iop3xx/iop321-time.c2
-rw-r--r--arch/arm/mach-iop3xx/iop331-time.c2
-rw-r--r--arch/arm/mach-ixp2000/core.c2
-rw-r--r--arch/arm/mach-ixp4xx/common.c16
-rw-r--r--arch/arm/mach-omap1/irq.c8
-rw-r--r--arch/arm/mach-s3c2410/Kconfig15
-rw-r--r--arch/arm/mach-s3c2410/Makefile5
-rw-r--r--arch/arm/mach-s3c2410/bast-irq.c77
-rw-r--r--arch/arm/mach-s3c2410/mach-anubis.c270
-rw-r--r--arch/arm/mach-s3c2410/pm-simtec.c2
-rw-r--r--arch/arm/mach-s3c2410/time.c2
-rw-r--r--arch/arm/plat-omap/Kconfig16
-rw-r--r--arch/arm/plat-omap/Makefile4
-rw-r--r--arch/arm/plat-omap/clock.c39
-rw-r--r--arch/arm/plat-omap/common.c7
-rw-r--r--arch/arm/plat-omap/dma.c25
-rw-r--r--arch/arm/plat-omap/dmtimer.c260
-rw-r--r--arch/arm/plat-omap/gpio.c524
-rw-r--r--arch/arm/plat-omap/mcbsp.c9
-rw-r--r--arch/arm/plat-omap/mux.c3
-rw-r--r--arch/arm/plat-omap/ocpi.c1
-rw-r--r--arch/arm/plat-omap/pm.c255
-rw-r--r--arch/arm/plat-omap/sleep.S83
-rw-r--r--arch/arm/plat-omap/sram-fn.S58
-rw-r--r--arch/arm/plat-omap/sram.c116
-rw-r--r--arch/arm/plat-omap/sram.h21
-rw-r--r--arch/arm/plat-omap/usb.c1
-rw-r--r--include/asm-arm/arch-omap/board-h4.h3
-rw-r--r--include/asm-arm/arch-omap/board-innovator.h25
-rw-r--r--include/asm-arm/arch-omap/board-perseus2.h17
-rw-r--r--include/asm-arm/arch-omap/board-voiceblue.h5
-rw-r--r--include/asm-arm/arch-omap/board.h19
-rw-r--r--include/asm-arm/arch-omap/cpu.h187
-rw-r--r--include/asm-arm/arch-omap/debug-macro.S13
-rw-r--r--include/asm-arm/arch-omap/dma.h1
-rw-r--r--include/asm-arm/arch-omap/dmtimer.h92
-rw-r--r--include/asm-arm/arch-omap/dsp.h244
-rw-r--r--include/asm-arm/arch-omap/dsp_common.h37
-rw-r--r--include/asm-arm/arch-omap/entry-macro.S28
-rw-r--r--include/asm-arm/arch-omap/gpio.h28
-rw-r--r--include/asm-arm/arch-omap/hardware.h39
-rw-r--r--include/asm-arm/arch-omap/io.h26
-rw-r--r--include/asm-arm/arch-omap/irqs.h6
-rw-r--r--include/asm-arm/arch-omap/memory.h14
-rw-r--r--include/asm-arm/arch-omap/mtd-xip.h61
-rw-r--r--include/asm-arm/arch-omap/mux.h10
-rw-r--r--include/asm-arm/arch-omap/omap1510.h13
-rw-r--r--include/asm-arm/arch-omap/omap16xx.h16
-rw-r--r--include/asm-arm/arch-omap/omap24xx.h15
-rw-r--r--include/asm-arm/arch-omap/omap730.h4
-rw-r--r--include/asm-arm/arch-omap/pm.h55
-rw-r--r--include/asm-arm/arch-omap/serial.h37
-rw-r--r--include/asm-arm/arch-omap/uncompress.h10
-rw-r--r--include/asm-arm/arch-s3c2410/anubis-cpld.h24
-rw-r--r--include/asm-arm/arch-s3c2410/anubis-irq.h23
-rw-r--r--include/asm-arm/arch-s3c2410/anubis-map.h46
58 files changed, 2498 insertions, 824 deletions
diff --git a/arch/arm/boot/compressed/head-sharpsl.S b/arch/arm/boot/compressed/head-sharpsl.S
index d6bf8a2b090d..59ad69640d6b 100644
--- a/arch/arm/boot/compressed/head-sharpsl.S
+++ b/arch/arm/boot/compressed/head-sharpsl.S
@@ -7,7 +7,8 @@
  * so we have to figure out the machine for ourselves...
  *
  * Support for Poodle, Corgi (SL-C700), Shepherd (SL-C750)
- * and Husky (SL-C760).
+ * Husky (SL-C760), Tosa (SL-C6000), Spitz (SL-C3000),
+ * Akita (SL-C1000) and Borzoi (SL-C3100).
  *
  */
 
@@ -23,6 +24,22 @@
 
 __SharpSL_start:
 
+/* Check for TC6393 - if found we have a Tosa */
+	ldr	r7, .TOSAID
+	mov	r1, #0x10000000		@ Base address of TC6393 chip
+	mov 	r6, #0x03
+	ldrh	r3, [r1, #8]		@ Load TC6393XB Revison: This is 0x0003
+	cmp	r6, r3
+	beq	.SHARPEND		@ Success -> tosa
+
+/* Check for pxa270 - if found, branch */
+	mrc p15, 0, r4, c0, c0		@ Get Processor ID
+	and	r4, r4, #0xffffff00
+	ldr	r3, .PXA270ID
+	cmp	r4, r3
+	beq	.PXA270
+
+/* Check for w100 - if not found we have a Poodle */
 	ldr	r1, .W100ADDR		@ Base address of w100 chip + regs offset
 
 	mov r6, #0x31			@ Load Magic Init value
@@ -30,7 +47,7 @@ __SharpSL_start:
 	mov r5, #0x3000
 .W100LOOP:
 	subs r5, r5, #1
-    bne .W100LOOP
+	bne .W100LOOP
 	mov r6, #0x30			@ Load 2nd Magic Init value
 	str	r6, [r1, #0x280]	@ to SCRATCH_UMSK
 
@@ -40,45 +57,52 @@ __SharpSL_start:
 	cmp	r6, r3
 	bne	.SHARPEND			@ We have no w100 - Poodle
 
-	mrc p15, 0, r6, c0, c0	@ Get Processor ID
-	and	r6, r6, #0xffffff00
+/* Check for pxa250 - if found we have a Corgi */
 	ldr	r7, .CORGIID
 	ldr	r3, .PXA255ID
-	cmp	r6, r3
+	cmp	r4, r3
 	blo	.SHARPEND			@ We have a PXA250 - Corgi
 
-	mov	r1, #0x0c000000		@ Base address of NAND chip
-	ldrb	r3, [r1, #24]	@ Load FLASHCTL
-	bic	r3, r3, #0x11		@ SET NCE
-	orr	r3, r3, #0x0a		@ SET CLR + FLWP
-	strb	r3, [r1, #24]	@ Save to FLASHCTL
-	mov 	r2, #0x90		@ Command "readid"
-	strb	r2, [r1, #20]	@ Save to FLASHIO
-	bic	r3, r3, #2			@ CLR CLE
-	orr	r3, r3, #4			@ SET ALE
-	strb	r3, [r1, #24]	@ Save to FLASHCTL
-	mov		r2, #0			@ Address 0x00
-	strb	r2, [r1, #20]	@ Save to FLASHIO
-	bic	r3, r3, #4			@ CLR ALE
-	strb	r3, [r1, #24]	@ Save to FLASHCTL
-.SHARP1:
-	ldrb	r3, [r1, #24]	@ Load FLASHCTL
-	tst	r3, #32				@ Is chip ready?
-	beq	.SHARP1
-	ldrb	r2, [r1, #20]	@ NAND Manufacturer ID
-	ldrb	r3, [r1, #20]	@ NAND Chip ID
+/* Check for 64MiB flash - if found we have a Shepherd */
+	bl	get_flash_ids
 	ldr	r7, .SHEPHERDID
 	cmp	r3, #0x76			@ 64MiB flash
 	beq	.SHARPEND			@ We have Shepherd
+
+/* Must be a Husky */
 	ldr	r7, .HUSKYID		@ Must be Husky
 	b .SHARPEND
 
+.PXA270:
+/* Check for 16MiB flash - if found we have Spitz */
+	bl	get_flash_ids
+	ldr	r7, .SPITZID
+	cmp	r3, #0x73			@ 16MiB flash
+	beq	.SHARPEND			@ We have Spitz
+
+/* Check for a second SCOOP chip - if found we have Borzoi */
+	ldr	r1, .SCOOP2ADDR
+	ldr	r7, .BORZOIID
+	mov 	r6, #0x0140
+	strh	r6, [r1]
+	ldrh	r6, [r1]
+	cmp	r6, #0x0140
+	beq	.SHARPEND			@ We have Borzoi
+
+/* Must be Akita */
+	ldr	r7, .AKITAID
+	b	.SHARPEND			@ We have Borzoi
+
 .PXA255ID:
 	.word	0x69052d00		@ PXA255 Processor ID
+.PXA270ID:
+	.word	0x69054100		@ PXA270 Processor ID
 .W100ID:
 	.word	0x57411002		@ w100 Chip ID
 .W100ADDR:
 	.word 	0x08010000		@ w100 Chip ID Reg Address
+.SCOOP2ADDR:
+	.word	0x08800040
 .POODLEID:
 	.word	MACH_TYPE_POODLE
 .CORGIID:
@@ -87,6 +111,41 @@ __SharpSL_start:
 	.word	MACH_TYPE_SHEPHERD
 .HUSKYID:
 	.word	MACH_TYPE_HUSKY
-.SHARPEND:
+.TOSAID:
+	.word	MACH_TYPE_TOSA
+.SPITZID:
+	.word	MACH_TYPE_SPITZ
+.AKITAID:
+	.word	MACH_TYPE_AKITA
+.BORZOIID:
+	.word	MACH_TYPE_BORZOI
 
+/*
+ * Return: r2 - NAND Manufacturer ID
+ *         r3 - NAND Chip ID
+ * Corrupts: r1
+ */
+get_flash_ids:
+	mov	r1, #0x0c000000		@ Base address of NAND chip
+	ldrb	r3, [r1, #24]		@ Load FLASHCTL
+	bic	r3, r3, #0x11		@ SET NCE
+	orr	r3, r3, #0x0a		@ SET CLR + FLWP
+	strb	r3, [r1, #24]		@ Save to FLASHCTL
+	mov 	r2, #0x90		@ Command "readid"
+	strb	r2, [r1, #20]		@ Save to FLASHIO
+	bic	r3, r3, #2		@ CLR CLE
+	orr	r3, r3, #4		@ SET ALE
+	strb	r3, [r1, #24]		@ Save to FLASHCTL
+	mov	r2, #0			@ Address 0x00
+	strb	r2, [r1, #20]		@ Save to FLASHIO
+	bic	r3, r3, #4		@ CLR ALE
+	strb	r3, [r1, #24]		@ Save to FLASHCTL
+.fids1:
+	ldrb	r3, [r1, #24]		@ Load FLASHCTL
+	tst	r3, #32			@ Is chip ready?
+	beq	.fids1
+	ldrb	r2, [r1, #20]		@ NAND Manufacturer ID
+	ldrb	r3, [r1, #20]		@ NAND Chip ID
+	mov	pc, lr
 
+.SHARPEND:
diff --git a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig
index 24955263b096..4198677cd394 100644
--- a/arch/arm/configs/omap_h2_1610_defconfig
+++ b/arch/arm/configs/omap_h2_1610_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc2
-# Fri Jul  8 04:49:34 2005
+# Linux kernel version: 2.6.13
+# Mon Sep  5 18:07:12 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -102,9 +102,11 @@ CONFIG_OMAP_MUX_WARNINGS=y
 # CONFIG_OMAP_MPU_TIMER is not set
 CONFIG_OMAP_32K_TIMER=y
 CONFIG_OMAP_32K_TIMER_HZ=128
+# CONFIG_OMAP_DM_TIMER is not set
 CONFIG_OMAP_LL_DEBUG_UART1=y
 # CONFIG_OMAP_LL_DEBUG_UART2 is not set
 # CONFIG_OMAP_LL_DEBUG_UART3 is not set
+CONFIG_OMAP_SERIAL_WAKE=y
 
 #
 # OMAP Core Type
@@ -166,7 +168,6 @@ CONFIG_ISA_DMA_API=y
 #
 # Kernel Features
 #
-# CONFIG_SMP is not set
 CONFIG_PREEMPT=y
 CONFIG_NO_IDLE_HZ=y
 # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
@@ -230,91 +231,82 @@ CONFIG_PM=y
 # CONFIG_APM is not set
 
 #
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
+# Networking
 #
-CONFIG_MTD=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=3
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_NET=y
 
 #
-# User Modules And Translation Layers
+# Networking options
 #
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+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 is not set
+# 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_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
 
 #
-# RAM/ROM/Flash chip drivers
+# SCTP Configuration (EXPERIMENTAL)
 #
-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_XIP is not set
+# CONFIG_IP_SCTP 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
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
 
 #
-# Mapping drivers for chip access
+# Network testing
 #
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_EDB7312 is not set
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
 
 #
-# Self-contained MTD device drivers
+# Device Drivers
 #
-# 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
+# Generic Driver Options
 #
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
-# NAND Flash Device Drivers
+# Memory Technology Devices (MTD)
 #
-# CONFIG_MTD_NAND is not set
+# CONFIG_MTD is not set
 
 #
 # Parallel port support
@@ -403,72 +395,8 @@ CONFIG_SCSI_PROC_FS=y
 #
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-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 is not set
-# 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_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
 #
-# CONFIG_IP_SCTP 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
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -518,6 +446,8 @@ CONFIG_SLIP_COMPRESSED=y
 # CONFIG_SLIP_MODE_SLIP6 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
@@ -615,77 +545,15 @@ CONFIG_WATCHDOG_NOWAYOUT=y
 #
 # I2C support
 #
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-
-#
-# I2C Algorithms
-#
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_ISA is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_PCA_ISA is not set
+# CONFIG_I2C is not set
+# CONFIG_I2C_SENSOR is not set
+CONFIG_ISP1301_OMAP=y
 
 #
-# Hardware Sensors Chip support
+# Hardware Monitoring support
 #
-# CONFIG_I2C_SENSOR 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_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_SMSC47B397 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-
-#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
-# CONFIG_SENSORS_EEPROM is not set
-# 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_ISP1301_OMAP=y
-CONFIG_TPS65010=y
-# CONFIG_SENSORS_MAX6875 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
+CONFIG_HWMON=y
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -756,15 +624,9 @@ CONFIG_SOUND=y
 # Open Sound System
 #
 CONFIG_SOUND_PRIME=y
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
 # CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_TVMIXER is not set
 # CONFIG_SOUND_AD1980 is not set
 
 #
@@ -810,6 +672,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
 
 #
 # XFS support
@@ -817,6 +680,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -857,15 +721,6 @@ CONFIG_RAMFS=y
 # 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=2
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC 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=y
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
@@ -1007,4 +862,3 @@ CONFIG_CRYPTO_DES=y
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/arm/mach-iop3xx/iop321-time.c b/arch/arm/mach-iop3xx/iop321-time.c
index d53af1669502..0039793b694a 100644
--- a/arch/arm/mach-iop3xx/iop321-time.c
+++ b/arch/arm/mach-iop3xx/iop321-time.c
@@ -60,7 +60,7 @@ static unsigned long iop321_gettimeoffset(void)
 	/*
 	 * Now convert them to usec.
 	 */
-	usec = (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH;
+	usec = (unsigned long)(elapsed / (CLOCK_TICK_RATE/1000000));
 
 	return usec;
 }
diff --git a/arch/arm/mach-iop3xx/iop331-time.c b/arch/arm/mach-iop3xx/iop331-time.c
index 1a6d9d661e4b..8eddfac7e2b0 100644
--- a/arch/arm/mach-iop3xx/iop331-time.c
+++ b/arch/arm/mach-iop3xx/iop331-time.c
@@ -58,7 +58,7 @@ static unsigned long iop331_gettimeoffset(void)
 	/*
 	 * Now convert them to usec.
 	 */
-	usec = (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH;
+	usec = (unsigned long)(elapsed / (CLOCK_TICK_RATE/1000000));
 
 	return usec;
 }
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index 781d10ae00b7..098c817a7fb8 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -382,7 +382,7 @@ static void ixp2000_GPIO_irq_unmask(unsigned int irq)
 static struct irqchip ixp2000_GPIO_irq_chip = {
 	.ack		= ixp2000_GPIO_irq_mask_ack,
 	.mask		= ixp2000_GPIO_irq_mask,
-	.unmask		= ixp2000_GPIO_irq_unmask
+	.unmask		= ixp2000_GPIO_irq_unmask,
 	.set_type	= ixp2000_GPIO_irq_type,
 };
 
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 0422e906cc9a..52ad11328e96 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -179,17 +179,17 @@ static void ixp4xx_irq_level_unmask(unsigned int irq)
 }
 
 static struct irqchip ixp4xx_irq_level_chip = {
-	.ack	= ixp4xx_irq_mask,
-	.mask	= ixp4xx_irq_mask,
-	.unmask	= ixp4xx_irq_level_unmask,
-	.type	= ixp4xx_set_irq_type
+	.ack		= ixp4xx_irq_mask,
+	.mask		= ixp4xx_irq_mask,
+	.unmask		= ixp4xx_irq_level_unmask,
+	.set_type	= ixp4xx_set_irq_type,
 };
 
 static struct irqchip ixp4xx_irq_edge_chip = {
-	.ack	= ixp4xx_irq_ack,
-	.mask	= ixp4xx_irq_mask,
-	.unmask	= ixp4xx_irq_unmask,
-	.type	= ixp4xx_set_irq_type
+	.ack		= ixp4xx_irq_ack,
+	.mask		= ixp4xx_irq_mask,
+	.unmask		= ixp4xx_irq_unmask,
+	.set_type	= ixp4xx_set_irq_type,
 };
 
 static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type)
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index a11b6d807352..afd5d67e4ae7 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -165,10 +165,10 @@ static struct omap_irq_bank omap1610_irq_banks[] = {
 #endif
 
 static struct irqchip omap_irq_chip = {
-	.ack    = omap_mask_ack_irq,
-	.mask   = omap_mask_irq,
-	.unmask = omap_unmask_irq,
-	.wake	= omap_wake_irq,
+	.ack		= omap_mask_ack_irq,
+	.mask		= omap_mask_irq,
+	.unmask		= omap_unmask_irq,
+	.set_wake	= omap_wake_irq,
 };
 
 void __init omap_init_irq(void)
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index d4d03d0daaec..06807c6ee68a 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -2,6 +2,13 @@ if ARCH_S3C2410
 
 menu "S3C24XX Implementations"
 
+config MACH_ANUBIS
+	bool "Simtec Electronics ANUBIS"
+	select CPU_S3C2440
+	help
+	  Say Y gere if you are using the Simtec Electronics ANUBIS
+	  development system
+
 config ARCH_BAST
 	bool "Simtec Electronics BAST (EB2410ITX)"
 	select CPU_S3C2410
@@ -11,6 +18,14 @@ config ARCH_BAST
 
 	  Product page: <http://www.simtec.co.uk/products/EB2410ITX/>.
 
+config BAST_PC104_IRQ
+	bool "BAST PC104 IRQ support"
+	depends on ARCH_BAST
+	default y
+	help
+	  Say Y	here to enable the PC104 IRQ routing on the
+	  Simtec BAST (EB2410ITX)
+
 config ARCH_H1940
 	bool "IPAQ H1940"
 	select CPU_S3C2410
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
index 55ed7c7e57da..b4f1e051c768 100644
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -26,8 +26,13 @@ obj-$(CONFIG_CPU_S3C2440)  += s3c2440.o s3c2440-dsc.o
 obj-$(CONFIG_CPU_S3C2440)  += s3c2440-irq.o
 obj-$(CONFIG_CPU_S3C2440)  += s3c2440-clock.o
 
+# bast extras
+
+obj-$(CONFIG_BAST_PC104_IRQ)	+= bast-irq.o
+
 # machine specific support
 
+obj-$(CONFIG_MACH_ANUBIS)	+= mach-anubis.o
 obj-$(CONFIG_ARCH_BAST)		+= mach-bast.o usb-simtec.o
 obj-$(CONFIG_ARCH_H1940)	+= mach-h1940.o
 obj-$(CONFIG_MACH_N30)		+= mach-n30.o
diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c
index 49914709fa09..fbbeb0553006 100644
--- a/arch/arm/mach-s3c2410/bast-irq.c
+++ b/arch/arm/mach-s3c2410/bast-irq.c
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/bast-irq.c
  *
- * Copyright (c) 2004 Simtec Electronics
+ * Copyright (c) 2003,2005 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
  *
  * http://www.simtec.co.uk/products/EB2410ITX/
@@ -21,7 +21,8 @@
  *
  * Modifications:
  *     08-Jan-2003 BJD  Moved from central IRQ code
- */
+ *     21-Aug-2005 BJD  Fixed missing code and compile errors
+*/
 
 
 #include <linux/init.h>
@@ -30,12 +31,19 @@
 #include <linux/ptrace.h>
 #include <linux/sysdev.h>
 
+#include <asm/mach-types.h>
+
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 
 #include <asm/mach/irq.h>
-#include <asm/hardware/s3c2410/irq.h>
+
+#include <asm/arch/regs-irq.h>
+#include <asm/arch/bast-map.h>
+#include <asm/arch/bast-irq.h>
+
+#include "irq.h"
 
 #if 0
 #include <asm/debug-ll.h>
@@ -79,15 +87,15 @@ bast_pc104_mask(unsigned int irqno)
 	temp = __raw_readb(BAST_VA_PC104_IRQMASK);
 	temp &= ~bast_pc104_irqmasks[irqno];
 	__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
-
-	if (temp == 0)
-		bast_extint_mask(IRQ_ISA);
 }
 
 static void
-bast_pc104_ack(unsigned int irqno)
+bast_pc104_maskack(unsigned int irqno)
 {
-	bast_extint_ack(IRQ_ISA);
+	struct irqdesc *desc = irq_desc + IRQ_ISA;
+
+	bast_pc104_mask(irqno);
+	desc->chip->ack(IRQ_ISA);
 }
 
 static void
@@ -98,14 +106,12 @@ bast_pc104_unmask(unsigned int irqno)
 	temp = __raw_readb(BAST_VA_PC104_IRQMASK);
 	temp |= bast_pc104_irqmasks[irqno];
 	__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
-
-	bast_extint_unmask(IRQ_ISA);
 }
 
-static struct bast_pc104_chip = {
+static struct irqchip  bast_pc104_chip = {
 	.mask	     = bast_pc104_mask,
 	.unmask	     = bast_pc104_unmask,
-	.ack	     = bast_pc104_ack
+	.ack	     = bast_pc104_maskack
 };
 
 static void
@@ -119,14 +125,49 @@ bast_irq_pc104_demux(unsigned int irq,
 
 	stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf;
 
-	for (i = 0; i < 4 && stat != 0; i++) {
-		if (stat & 1) {
-			irqno = bast_pc104_irqs[i];
-			desc = irq_desc + irqno;
+	if (unlikely(stat == 0)) {
+		/* ack if we get an irq with nothing (ie, startup) */
+
+		desc = irq_desc + IRQ_ISA;
+		desc->chip->ack(IRQ_ISA);
+	} else {
+		/* handle the IRQ */
+
+		for (i = 0; stat != 0; i++, stat >>= 1) {
+			if (stat & 1) {
+				irqno = bast_pc104_irqs[i];
 
-			desc_handle_irq(irqno, desc, regs);
+				desc_handle_irq(irqno, irq_desc + irqno, regs);
+			}
 		}
+	}
+}
 
-		stat >>= 1;
+static __init int bast_irq_init(void)
+{
+	unsigned int i;
+
+	if (machine_is_bast()) {
+		printk(KERN_INFO "BAST PC104 IRQ routing, (c) 2005 Simtec Electronics\n");
+
+		/* zap all the IRQs */
+
+		__raw_writeb(0x0, BAST_VA_PC104_IRQMASK);
+
+		set_irq_chained_handler(IRQ_ISA, bast_irq_pc104_demux);
+
+		/* reigster our IRQs */
+
+		for (i = 0; i < 4; i++) {
+			unsigned int irqno = bast_pc104_irqs[i];
+
+			set_irq_chip(irqno, &bast_pc104_chip);
+			set_irq_handler(irqno, do_level_IRQ);
+			set_irq_flags(irqno, IRQF_VALID);
+		}
 	}
+
+	return 0;
 }
+
+arch_initcall(bast_irq_init);
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c
new file mode 100644
index 000000000000..f87aa0b669ad
--- /dev/null
+++ b/arch/arm/mach-s3c2410/mach-anubis.c
@@ -0,0 +1,270 @@
+/* linux/arch/arm/mach-s3c2410/mach-anubis.c
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ *
+ *
+ * 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.
+ *
+ * Modifications:
+ *	02-May-2005 BJD  Copied from mach-bast.c
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/anubis-map.h>
+#include <asm/arch/anubis-irq.h>
+#include <asm/arch/anubis-cpld.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-lcd.h>
+#include <asm/arch/nand.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include "clock.h"
+#include "devs.h"
+#include "cpu.h"
+
+#define COPYRIGHT ", (c) 2005 Simtec Electronics"
+
+static struct map_desc anubis_iodesc[] __initdata = {
+  /* ISA IO areas */
+
+  { (u32)S3C24XX_VA_ISA_BYTE, 0x0,	   SZ_16M, MT_DEVICE },
+  { (u32)S3C24XX_VA_ISA_WORD, 0x0,	   SZ_16M, MT_DEVICE },
+
+  /* we could possibly compress the next set down into a set of smaller tables
+   * pagetables, but that would mean using an L2 section, and it still means
+   * we cannot actually feed the same register to an LDR due to 16K spacing
+   */
+
+  /* CPLD control registers */
+
+  { (u32)ANUBIS_VA_CTRL1,	ANUBIS_PA_CTRL1,	SZ_4K, MT_DEVICE },
+  { (u32)ANUBIS_VA_CTRL2,	ANUBIS_PA_CTRL2,	SZ_4K, MT_DEVICE },
+
+  /* IDE drives */
+
+  { (u32)ANUBIS_IDEPRI,		S3C2410_CS3,		SZ_1M, MT_DEVICE },
+  { (u32)ANUBIS_IDEPRIAUX,	S3C2410_CS3+(1<<26),	SZ_1M, MT_DEVICE },
+
+  { (u32)ANUBIS_IDESEC,		S3C2410_CS4,		SZ_1M, MT_DEVICE },
+  { (u32)ANUBIS_IDESECAUX,	S3C2410_CS4+(1<<26),	SZ_1M, MT_DEVICE },
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c24xx_uart_clksrc anubis_serial_clocks[] = {
+	[0] = {
+		.name		= "uclk",
+		.divisor	= 1,
+		.min_baud	= 0,
+		.max_baud	= 0,
+	},
+	[1] = {
+		.name		= "pclk",
+		.divisor	= 1,
+		.min_baud	= 0,
+		.max_baud	= 0.
+	}
+};
+
+
+static struct s3c2410_uartcfg anubis_uartcfgs[] = {
+	[0] = {
+		.hwport	     = 0,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+		.clocks	     = anubis_serial_clocks,
+		.clocks_size = ARRAY_SIZE(anubis_serial_clocks)
+	},
+	[1] = {
+		.hwport	     = 2,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+		.clocks	     = anubis_serial_clocks,
+		.clocks_size = ARRAY_SIZE(anubis_serial_clocks)
+	},
+};
+
+/* NAND Flash on Anubis board */
+
+static int external_map[]   = { 2 };
+static int chip0_map[]      = { 0 };
+static int chip1_map[]      = { 1 };
+
+struct mtd_partition anubis_default_nand_part[] = {
+	[0] = {
+		.name	= "Boot Agent",
+		.size	= SZ_16K,
+		.offset	= 0
+	},
+	[1] = {
+		.name	= "/boot",
+		.size	= SZ_4M - SZ_16K,
+		.offset	= SZ_16K,
+	},
+	[2] = {
+		.name	= "user1",
+		.offset	= SZ_4M,
+		.size	= SZ_32M - SZ_4M,
+	},
+	[3] = {
+		.name	= "user2",
+		.offset	= SZ_32M,
+		.size	= MTDPART_SIZ_FULL,
+	}
+};
+
+/* the Anubis has 3 selectable slots for nand-flash, the two
+ * on-board chip areas, as well as the external slot.
+ *
+ * Note, there is no current hot-plug support for the External
+ * socket.
+*/
+
+static struct s3c2410_nand_set anubis_nand_sets[] = {
+	[1] = {
+		.name		= "External",
+		.nr_chips	= 1,
+		.nr_map		= external_map,
+		.nr_partitions	= ARRAY_SIZE(anubis_default_nand_part),
+		.partitions	= anubis_default_nand_part
+	},
+	[0] = {
+		.name		= "chip0",
+		.nr_chips	= 1,
+		.nr_map		= chip0_map,
+		.nr_partitions	= ARRAY_SIZE(anubis_default_nand_part),
+		.partitions	= anubis_default_nand_part
+	},
+	[2] = {
+		.name		= "chip1",
+		.nr_chips	= 1,
+		.nr_map		= chip1_map,
+		.nr_partitions	= ARRAY_SIZE(anubis_default_nand_part),
+		.partitions	= anubis_default_nand_part
+	},
+};
+
+static void anubis_nand_select(struct s3c2410_nand_set *set, int slot)
+{
+	unsigned int tmp;
+
+	slot = set->nr_map[slot] & 3;
+
+	pr_debug("anubis_nand: selecting slot %d (set %p,%p)\n",
+		 slot, set, set->nr_map);
+
+	tmp = __raw_readb(ANUBIS_VA_CTRL1);
+	tmp &= ~ANUBIS_CTRL1_NANDSEL;
+	tmp |= slot;
+
+	pr_debug("anubis_nand: ctrl1 now %02x\n", tmp);
+
+	__raw_writeb(tmp, ANUBIS_VA_CTRL1);
+}
+
+static struct s3c2410_platform_nand anubis_nand_info = {
+	.tacls		= 25,
+	.twrph0		= 80,
+	.twrph1		= 80,
+	.nr_sets	= ARRAY_SIZE(anubis_nand_sets),
+	.sets		= anubis_nand_sets,
+	.select_chip	= anubis_nand_select,
+};
+
+
+/* Standard Anubis devices */
+
+static struct platform_device *anubis_devices[] __initdata = {
+	&s3c_device_usb,
+	&s3c_device_wdt,
+	&s3c_device_adc,
+	&s3c_device_i2c,
+ 	&s3c_device_rtc,
+	&s3c_device_nand,
+};
+
+static struct clk *anubis_clocks[] = {
+	&s3c24xx_dclk0,
+	&s3c24xx_dclk1,
+	&s3c24xx_clkout0,
+	&s3c24xx_clkout1,
+	&s3c24xx_uclk,
+};
+
+static struct s3c24xx_board anubis_board __initdata = {
+	.devices       = anubis_devices,
+	.devices_count = ARRAY_SIZE(anubis_devices),
+	.clocks	       = anubis_clocks,
+	.clocks_count  = ARRAY_SIZE(anubis_clocks)
+};
+
+void __init anubis_map_io(void)
+{
+	/* initialise the clocks */
+
+	s3c24xx_dclk0.parent = NULL;
+	s3c24xx_dclk0.rate   = 12*1000*1000;
+
+	s3c24xx_dclk1.parent = NULL;
+	s3c24xx_dclk1.rate   = 24*1000*1000;
+
+	s3c24xx_clkout0.parent  = &s3c24xx_dclk0;
+	s3c24xx_clkout1.parent  = &s3c24xx_dclk1;
+
+	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
+
+	s3c_device_nand.dev.platform_data = &anubis_nand_info;
+
+	s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
+	s3c24xx_init_clocks(0);
+	s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
+	s3c24xx_set_board(&anubis_board);
+
+	/* ensure that the GPIO is setup */
+	s3c2410_gpio_setpin(S3C2410_GPA0, 1);
+}
+
+MACHINE_START(ANUBIS, "Simtec-Anubis")
+	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+	.map_io		= anubis_map_io,
+	.init_irq	= s3c24xx_init_irq,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2410/pm-simtec.c b/arch/arm/mach-s3c2410/pm-simtec.c
index 2cb798832223..4c7ccef6c207 100644
--- a/arch/arm/mach-s3c2410/pm-simtec.c
+++ b/arch/arm/mach-s3c2410/pm-simtec.c
@@ -48,7 +48,7 @@ static __init int pm_simtec_init(void)
 
 	/* check which machine we are running on */
 
-	if (!machine_is_bast() && !machine_is_vr1000())
+	if (!machine_is_bast() && !machine_is_vr1000() && !machine_is_anubis())
 		return 0;
 
 	printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n");
diff --git a/arch/arm/mach-s3c2410/time.c b/arch/arm/mach-s3c2410/time.c
index 765a3a9ae032..c0acfb2ad790 100644
--- a/arch/arm/mach-s3c2410/time.c
+++ b/arch/arm/mach-s3c2410/time.c
@@ -164,7 +164,7 @@ static void s3c2410_timer_setup (void)
 
 	/* configure the system for whichever machine is in use */
 
-	if (machine_is_bast() || machine_is_vr1000()) {
+	if (machine_is_bast() || machine_is_vr1000() || machine_is_anubis()) {
 		/* timer is at 12MHz, scaler is 1 */
 		timer_usec_ticks = timer_mask_usec_ticks(1, 12000000);
 		tcnt = 12000000 / HZ;
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 345365852f8c..9693e9b4ffd1 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -91,6 +91,13 @@ config OMAP_32K_TIMER_HZ
 	  Kernel internal timer frequency should be a divisor of 32768,
 	  such as 64 or 128.
 
+config OMAP_DM_TIMER
+	bool "Use dual-mode timer"
+	default n
+	depends on ARCH_OMAP16XX
+	help
+	 Select this option if you want to use OMAP Dual-Mode timers.
+
 choice
 	prompt "Low-level debug console UART"
 	depends on ARCH_OMAP
@@ -107,6 +114,15 @@ config OMAP_LL_DEBUG_UART3
 
 endchoice
 
+config OMAP_SERIAL_WAKE
+	bool "Enable wake-up events for serial ports"
+	depends OMAP_MUX
+	default y
+	help
+	  Select this option if you want to have your system wake up
+	  to data on the serial RX line. This allows you to wake the
+	  system from serial console.
+
 endmenu
 
 endif
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 531e11af54d4..7e144f9cad1c 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -3,7 +3,7 @@
 #
 
 # Common support
-obj-y := common.o dma.o clock.o mux.o gpio.o mcbsp.o usb.o
+obj-y := common.o sram.o sram-fn.o clock.o dma.o mux.o gpio.o mcbsp.o usb.o
 obj-m :=
 obj-n :=
 obj-  :=
@@ -15,3 +15,5 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
 obj-$(CONFIG_PM) += pm.o sleep.o
 
 obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
+obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
+
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 59d91b3262ba..52a58b2da288 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -21,6 +21,7 @@
 #include <asm/arch/usb.h>
 
 #include "clock.h"
+#include "sram.h"
 
 static LIST_HEAD(clocks);
 static DECLARE_MUTEX(clocks_sem);
@@ -141,7 +142,7 @@ static struct clk arm_ck = {
 static struct clk armper_ck = {
 	.name		= "armper_ck",
 	.parent		= &ck_dpll1,
-	.flags		= CLOCK_IN_OMAP730 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
 			  RATE_CKCTL,
 	.enable_reg	= ARM_IDLECT2,
 	.enable_bit	= EN_PERCK,
@@ -385,7 +386,8 @@ static struct clk uart2_ck = {
 	.name		= "uart2_ck",
 	/* Direct from ULPD, no parent */
 	.rate		= 12000000,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ENABLE_REG_32BIT,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ENABLE_REG_32BIT |
+			  ALWAYS_ENABLED,
 	.enable_reg	= MOD_CONF_CTRL_0,
 	.enable_bit	= 30,	/* Chooses between 12MHz and 48MHz */
 	.set_rate	= &set_uart_rate,
@@ -443,6 +445,15 @@ static struct clk usb_hhc_ck16xx = {
 	.enable_bit	= 8 /* UHOST_EN */,
 };
 
+static struct clk usb_dc_ck = {
+	.name		= "usb_dc_ck",
+	/* Direct from ULPD, no parent */
+	.rate		= 48000000,
+	.flags		= CLOCK_IN_OMAP16XX | RATE_FIXED,
+	.enable_reg	= SOFT_REQ_REG,
+	.enable_bit	= 4,
+};
+
 static struct clk mclk_1510 = {
 	.name		= "mclk",
 	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
@@ -552,6 +563,7 @@ static struct clk *  onchip_clks[] = {
 	&uart3_16xx,
 	&usb_clko,
 	&usb_hhc_ck1510, &usb_hhc_ck16xx,
+	&usb_dc_ck,
 	&mclk_1510,  &mclk_16xx,
 	&bclk_1510,  &bclk_16xx,
 	&mmc1_ck,
@@ -946,14 +958,13 @@ static int select_table_rate(struct clk *  clk, unsigned long rate)
 	if (!ptr->rate)
 		return -EINVAL;
 
-	if (!ptr->rate)
-		return -EINVAL;
+	/*
+	 * In most cases we should not need to reprogram DPLL.
+	 * Reprogramming the DPLL is tricky, it must be done from SRAM.
+	 */
+	omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
 
-	if (unlikely(ck_dpll1.rate == 0)) {
-		omap_writew(ptr->dpllctl_val, DPLL_CTL);
-		ck_dpll1.rate = ptr->pll_rate;
-	}
-	omap_writew(ptr->ckctl_val, ARM_CKCTL);
+	ck_dpll1.rate = ptr->pll_rate;
 	propagate_rate(&ck_dpll1);
 	return 0;
 }
@@ -1224,9 +1235,11 @@ int __init clk_init(void)
 #endif
 	/* Cache rates for clocks connected to ck_ref (not dpll1) */
 	propagate_rate(&ck_ref);
-	printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): %ld.%01ld/%ld/%ld MHz\n",
+	printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): "
+		"%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n",
 	       ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
-	       ck_dpll1.rate, arm_ck.rate);
+	       ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,
+	       arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
 
 #ifdef CONFIG_MACH_OMAP_PERSEUS2
 	/* Select slicer output as OMAP input clock */
@@ -1271,7 +1284,9 @@ static int __init omap_late_clk_reset(void)
 	struct clk *p;
 	__u32 regval32;
 
-	omap_writew(0, SOFT_REQ_REG);
+	/* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */
+	regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4);
+	omap_writew(regval32, SOFT_REQ_REG);
 	omap_writew(0, SOFT_REQ_REG2);
 
 	list_for_each_entry(p, &clocks, node) {
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index ea967a8f6ce5..6cb20aea7f51 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -26,6 +26,7 @@
 #include <asm/hardware/clock.h>
 #include <asm/io.h>
 #include <asm/mach-types.h>
+#include <asm/setup.h>
 
 #include <asm/arch/board.h>
 #include <asm/arch/mux.h>
@@ -35,11 +36,11 @@
 
 #define NO_LENGTH_CHECK 0xffffffff
 
-extern int omap_bootloader_tag_len;
-extern u8 omap_bootloader_tag[];
+unsigned char omap_bootloader_tag[512];
+int omap_bootloader_tag_len;
 
 struct omap_board_config_kernel *omap_board_config;
-int omap_board_config_size = 0;
+int omap_board_config_size;
 
 static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out)
 {
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index c0a5c2fa42bd..da7b65145658 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -425,7 +425,7 @@ static int dma_handle_ch(int ch)
 		dma_chan[ch + 6].saved_csr = csr >> 7;
 		csr &= 0x7f;
 	}
-	if (!csr)
+	if ((csr & 0x3f) == 0)
 		return 0;
 	if (unlikely(dma_chan[ch].dev_id == -1)) {
 		printk(KERN_WARNING "Spurious interrupt from DMA channel %d (CSR %04x)\n",
@@ -890,11 +890,11 @@ void omap_enable_lcd_dma(void)
 	w |= 1 << 8;
 	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
 
+	lcd_dma.active = 1;
+
 	w = omap_readw(OMAP1610_DMA_LCD_CCR);
 	w |= 1 << 7;
 	omap_writew(w, OMAP1610_DMA_LCD_CCR);
-
-	lcd_dma.active = 1;
 }
 
 void omap_setup_lcd_dma(void)
@@ -965,8 +965,8 @@ void omap_clear_dma(int lch)
  */
 dma_addr_t omap_get_dma_src_pos(int lch)
 {
-	return (dma_addr_t) (OMAP_DMA_CSSA_L(lch) |
-			     (OMAP_DMA_CSSA_U(lch) << 16));
+	return (dma_addr_t) (omap_readw(OMAP_DMA_CSSA_L(lch)) |
+	(omap_readw(OMAP_DMA_CSSA_U(lch)) << 16));
 }
 
 /*
@@ -979,8 +979,18 @@ dma_addr_t omap_get_dma_src_pos(int lch)
  */
 dma_addr_t omap_get_dma_dst_pos(int lch)
 {
-	return (dma_addr_t) (OMAP_DMA_CDSA_L(lch) |
-			     (OMAP_DMA_CDSA_U(lch) << 16));
+	return (dma_addr_t) (omap_readw(OMAP_DMA_CDSA_L(lch)) |
+	(omap_readw(OMAP_DMA_CDSA_U(lch)) << 16));
+}
+
+/*
+ * Returns current source transfer counting for the given DMA channel.
+ * Can be used to monitor the progress of a transfer inside a  block.
+ * It must be called with disabled interrupts.
+ */
+int omap_get_dma_src_addr_counter(int lch)
+{
+	return (dma_addr_t) omap_readw(OMAP_DMA_CSAC(lch));
 }
 
 int omap_dma_running(void)
@@ -1076,6 +1086,7 @@ arch_initcall(omap_init_dma);
 
 EXPORT_SYMBOL(omap_get_dma_src_pos);
 EXPORT_SYMBOL(omap_get_dma_dst_pos);
+EXPORT_SYMBOL(omap_get_dma_src_addr_counter);
 EXPORT_SYMBOL(omap_clear_dma);
 EXPORT_SYMBOL(omap_set_dma_priority);
 EXPORT_SYMBOL(omap_request_dma);
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
new file mode 100644
index 000000000000..a1468d7326eb
--- /dev/null
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -0,0 +1,260 @@
+/*
+ * linux/arch/arm/plat-omap/dmtimer.c
+ *
+ * OMAP Dual-Mode Timers
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com>
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the  GNU General Public License along
+ * with this program; if not, write  to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/dmtimer.h>
+#include <asm/io.h>
+#include <asm/arch/irqs.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+
+#define OMAP_TIMER_COUNT		8
+
+#define OMAP_TIMER_ID_REG		0x00
+#define OMAP_TIMER_OCP_CFG_REG		0x10
+#define OMAP_TIMER_SYS_STAT_REG		0x14
+#define OMAP_TIMER_STAT_REG		0x18
+#define OMAP_TIMER_INT_EN_REG		0x1c
+#define OMAP_TIMER_WAKEUP_EN_REG	0x20
+#define OMAP_TIMER_CTRL_REG		0x24
+#define OMAP_TIMER_COUNTER_REG		0x28
+#define OMAP_TIMER_LOAD_REG		0x2c
+#define OMAP_TIMER_TRIGGER_REG		0x30
+#define OMAP_TIMER_WRITE_PEND_REG 	0x34
+#define OMAP_TIMER_MATCH_REG		0x38
+#define OMAP_TIMER_CAPTURE_REG		0x3c
+#define OMAP_TIMER_IF_CTRL_REG		0x40
+
+
+static struct dmtimer_info_struct {
+	struct list_head	unused_timers;
+	struct list_head	reserved_timers;
+} dm_timer_info;
+
+static struct omap_dm_timer dm_timers[] = {
+	{ .base=0xfffb1400, .irq=INT_1610_GPTIMER1 },
+	{ .base=0xfffb1c00, .irq=INT_1610_GPTIMER2 },
+	{ .base=0xfffb2400, .irq=INT_1610_GPTIMER3 },
+	{ .base=0xfffb2c00, .irq=INT_1610_GPTIMER4 },
+	{ .base=0xfffb3400, .irq=INT_1610_GPTIMER5 },
+	{ .base=0xfffb3c00, .irq=INT_1610_GPTIMER6 },
+	{ .base=0xfffb4400, .irq=INT_1610_GPTIMER7 },
+	{ .base=0xfffb4c00, .irq=INT_1610_GPTIMER8 },
+	{ .base=0x0 },
+};
+
+
+static spinlock_t dm_timer_lock;
+
+
+inline void omap_dm_timer_write_reg(struct omap_dm_timer *timer, int reg, u32 value)
+{
+	omap_writel(value, timer->base + reg);
+	while (omap_dm_timer_read_reg(timer, OMAP_TIMER_WRITE_PEND_REG))
+		;
+}
+
+u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, int reg)
+{
+	return omap_readl(timer->base + reg);
+}
+
+int omap_dm_timers_active(void)
+{
+	struct omap_dm_timer *timer;
+
+	for (timer = &dm_timers[0]; timer->base; ++timer)
+		if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
+		    OMAP_TIMER_CTRL_ST)
+			return 1;
+
+	return 0;
+}
+
+
+void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
+{
+	int n = (timer - dm_timers) << 1;
+	u32 l;
+
+	l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
+	l |= source << n;
+	omap_writel(l, MOD_CONF_CTRL_1);
+}
+
+
+static void omap_dm_timer_reset(struct omap_dm_timer *timer)
+{
+	/* Reset and set posted mode */
+	omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
+	omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, 0x02);
+
+	omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_ARMXOR);
+}
+
+
+
+struct omap_dm_timer * omap_dm_timer_request(void)
+{
+	struct omap_dm_timer *timer = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dm_timer_lock, flags);
+	if (!list_empty(&dm_timer_info.unused_timers)) {
+		timer = (struct omap_dm_timer *)
+				dm_timer_info.unused_timers.next;
+		list_move_tail((struct list_head *)timer,
+				&dm_timer_info.reserved_timers);
+	}
+	spin_unlock_irqrestore(&dm_timer_lock, flags);
+
+	return timer;
+}
+
+
+void omap_dm_timer_free(struct omap_dm_timer *timer)
+{
+	unsigned long flags;
+
+	omap_dm_timer_reset(timer);
+
+	spin_lock_irqsave(&dm_timer_lock, flags);
+	list_move_tail((struct list_head *)timer, &dm_timer_info.unused_timers);
+	spin_unlock_irqrestore(&dm_timer_lock, flags);
+}
+
+void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
+				unsigned int value)
+{
+	omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value);
+}
+
+unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
+{
+	return omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);
+}
+
+void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
+{
+	omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value);
+}
+
+void omap_dm_timer_enable_autoreload(struct omap_dm_timer *timer)
+{
+	u32 l;
+	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+	l |= OMAP_TIMER_CTRL_AR;
+	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+}
+
+void omap_dm_timer_trigger(struct omap_dm_timer *timer)
+{
+	omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 1);
+}
+
+void omap_dm_timer_set_trigger(struct omap_dm_timer *timer, unsigned int value)
+{
+	u32 l;
+
+	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+	l |= value & 0x3;
+	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+}
+
+void omap_dm_timer_start(struct omap_dm_timer *timer)
+{
+	u32 l;
+
+	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+	l |= OMAP_TIMER_CTRL_ST;
+	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+}
+
+void omap_dm_timer_stop(struct omap_dm_timer *timer)
+{
+	u32 l;
+
+	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+	l &= ~0x1;
+	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+}
+
+unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
+{
+	return omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
+}
+
+void omap_dm_timer_reset_counter(struct omap_dm_timer *timer)
+{
+	omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, 0);
+}
+
+void omap_dm_timer_set_load(struct omap_dm_timer *timer, unsigned int load)
+{
+	omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
+}
+
+void omap_dm_timer_set_match(struct omap_dm_timer *timer, unsigned int match)
+{
+	omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
+}
+
+void omap_dm_timer_enable_compare(struct omap_dm_timer *timer)
+{
+	u32 l;
+
+	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+	l |= OMAP_TIMER_CTRL_CE;
+	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+}
+
+
+static inline void __dm_timer_init(void)
+{
+	struct omap_dm_timer *timer;
+
+	spin_lock_init(&dm_timer_lock);
+	INIT_LIST_HEAD(&dm_timer_info.unused_timers);
+	INIT_LIST_HEAD(&dm_timer_info.reserved_timers);
+
+	timer = &dm_timers[0];
+	while (timer->base) {
+		list_add_tail((struct list_head *)timer, &dm_timer_info.unused_timers);
+		omap_dm_timer_reset(timer);
+		timer++;
+	}
+}
+
+static int __init omap_dm_timer_init(void)
+{
+	if (cpu_is_omap16xx())
+		__dm_timer_init();
+	return 0;
+}
+
+arch_initcall(omap_dm_timer_init);
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index aa481ea3d702..55059a24ad41 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -3,7 +3,7 @@
  *
  * Support functions for OMAP GPIO
  *
- * Copyright (C) 2003 Nokia Corporation
+ * Copyright (C) 2003-2005 Nokia Corporation
  * Written by Juha Yrjölä <juha.yrjola@nokia.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -17,8 +17,11 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/ptrace.h>
+#include <linux/sysdev.h>
+#include <linux/err.h>
 
 #include <asm/hardware.h>
+#include <asm/hardware/clock.h>
 #include <asm/irq.h>
 #include <asm/arch/irqs.h>
 #include <asm/arch/gpio.h>
@@ -29,7 +32,7 @@
 /*
  * OMAP1510 GPIO registers
  */
-#define OMAP1510_GPIO_BASE		0xfffce000
+#define OMAP1510_GPIO_BASE		(void __iomem *)0xfffce000
 #define OMAP1510_GPIO_DATA_INPUT	0x00
 #define OMAP1510_GPIO_DATA_OUTPUT	0x04
 #define OMAP1510_GPIO_DIR_CONTROL	0x08
@@ -43,34 +46,37 @@
 /*
  * OMAP1610 specific GPIO registers
  */
-#define OMAP1610_GPIO1_BASE		0xfffbe400
-#define OMAP1610_GPIO2_BASE		0xfffbec00
-#define OMAP1610_GPIO3_BASE		0xfffbb400
-#define OMAP1610_GPIO4_BASE		0xfffbbc00
+#define OMAP1610_GPIO1_BASE		(void __iomem *)0xfffbe400
+#define OMAP1610_GPIO2_BASE		(void __iomem *)0xfffbec00
+#define OMAP1610_GPIO3_BASE		(void __iomem *)0xfffbb400
+#define OMAP1610_GPIO4_BASE		(void __iomem *)0xfffbbc00
 #define OMAP1610_GPIO_REVISION		0x0000
 #define OMAP1610_GPIO_SYSCONFIG		0x0010
 #define OMAP1610_GPIO_SYSSTATUS		0x0014
 #define OMAP1610_GPIO_IRQSTATUS1	0x0018
 #define OMAP1610_GPIO_IRQENABLE1	0x001c
+#define OMAP1610_GPIO_WAKEUPENABLE	0x0028
 #define OMAP1610_GPIO_DATAIN		0x002c
 #define OMAP1610_GPIO_DATAOUT		0x0030
 #define OMAP1610_GPIO_DIRECTION		0x0034
 #define OMAP1610_GPIO_EDGE_CTRL1	0x0038
 #define OMAP1610_GPIO_EDGE_CTRL2	0x003c
 #define OMAP1610_GPIO_CLEAR_IRQENABLE1	0x009c
+#define OMAP1610_GPIO_CLEAR_WAKEUPENA	0x00a8
 #define OMAP1610_GPIO_CLEAR_DATAOUT	0x00b0
 #define OMAP1610_GPIO_SET_IRQENABLE1	0x00dc
+#define OMAP1610_GPIO_SET_WAKEUPENA	0x00e8
 #define OMAP1610_GPIO_SET_DATAOUT	0x00f0
 
 /*
  * OMAP730 specific GPIO registers
  */
-#define OMAP730_GPIO1_BASE		0xfffbc000
-#define OMAP730_GPIO2_BASE		0xfffbc800
-#define OMAP730_GPIO3_BASE		0xfffbd000
-#define OMAP730_GPIO4_BASE		0xfffbd800
-#define OMAP730_GPIO5_BASE		0xfffbe000
-#define OMAP730_GPIO6_BASE		0xfffbe800
+#define OMAP730_GPIO1_BASE		(void __iomem *)0xfffbc000
+#define OMAP730_GPIO2_BASE		(void __iomem *)0xfffbc800
+#define OMAP730_GPIO3_BASE		(void __iomem *)0xfffbd000
+#define OMAP730_GPIO4_BASE		(void __iomem *)0xfffbd800
+#define OMAP730_GPIO5_BASE		(void __iomem *)0xfffbe000
+#define OMAP730_GPIO6_BASE		(void __iomem *)0xfffbe800
 #define OMAP730_GPIO_DATA_INPUT		0x00
 #define OMAP730_GPIO_DATA_OUTPUT	0x04
 #define OMAP730_GPIO_DIR_CONTROL	0x08
@@ -78,14 +84,43 @@
 #define OMAP730_GPIO_INT_MASK		0x10
 #define OMAP730_GPIO_INT_STATUS		0x14
 
+/*
+ * omap24xx specific GPIO registers
+ */
+#define OMAP24XX_GPIO1_BASE		(void __iomem *)0x48018000
+#define OMAP24XX_GPIO2_BASE		(void __iomem *)0x4801a000
+#define OMAP24XX_GPIO3_BASE		(void __iomem *)0x4801c000
+#define OMAP24XX_GPIO4_BASE		(void __iomem *)0x4801e000
+#define OMAP24XX_GPIO_REVISION		0x0000
+#define OMAP24XX_GPIO_SYSCONFIG		0x0010
+#define OMAP24XX_GPIO_SYSSTATUS		0x0014
+#define OMAP24XX_GPIO_IRQSTATUS1	0x0018
+#define OMAP24XX_GPIO_IRQENABLE1	0x001c
+#define OMAP24XX_GPIO_CTRL		0x0030
+#define OMAP24XX_GPIO_OE		0x0034
+#define OMAP24XX_GPIO_DATAIN		0x0038
+#define OMAP24XX_GPIO_DATAOUT		0x003c
+#define OMAP24XX_GPIO_LEVELDETECT0	0x0040
+#define OMAP24XX_GPIO_LEVELDETECT1	0x0044
+#define OMAP24XX_GPIO_RISINGDETECT	0x0048
+#define OMAP24XX_GPIO_FALLINGDETECT	0x004c
+#define OMAP24XX_GPIO_CLEARIRQENABLE1	0x0060
+#define OMAP24XX_GPIO_SETIRQENABLE1	0x0064
+#define OMAP24XX_GPIO_CLEARWKUENA	0x0080
+#define OMAP24XX_GPIO_SETWKUENA		0x0084
+#define OMAP24XX_GPIO_CLEARDATAOUT	0x0090
+#define OMAP24XX_GPIO_SETDATAOUT	0x0094
+
 #define OMAP_MPUIO_MASK		(~OMAP_MAX_GPIO_LINES & 0xff)
 
 struct gpio_bank {
-	u32 base;
+	void __iomem *base;
 	u16 irq;
 	u16 virtual_irq_start;
-	u8 method;
+	int method;
 	u32 reserved_map;
+	u32 suspend_wakeup;
+	u32 saved_wakeup;
 	spinlock_t lock;
 };
 
@@ -93,8 +128,9 @@ struct gpio_bank {
 #define METHOD_GPIO_1510	1
 #define METHOD_GPIO_1610	2
 #define METHOD_GPIO_730		3
+#define METHOD_GPIO_24XX	4
 
-#if defined(CONFIG_ARCH_OMAP16XX)
+#ifdef CONFIG_ARCH_OMAP16XX
 static struct gpio_bank gpio_bank_1610[5] = {
 	{ OMAP_MPUIO_BASE,     INT_MPUIO,	    IH_MPUIO_BASE,     METHOD_MPUIO},
 	{ OMAP1610_GPIO1_BASE, INT_GPIO_BANK1,	    IH_GPIO_BASE,      METHOD_GPIO_1610 },
@@ -123,6 +159,15 @@ static struct gpio_bank gpio_bank_730[7] = {
 };
 #endif
 
+#ifdef CONFIG_ARCH_OMAP24XX
+static struct gpio_bank gpio_bank_24xx[4] = {
+	{ OMAP24XX_GPIO1_BASE, INT_24XX_GPIO_BANK1, IH_GPIO_BASE,	METHOD_GPIO_24XX },
+	{ OMAP24XX_GPIO2_BASE, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32,	METHOD_GPIO_24XX },
+	{ OMAP24XX_GPIO3_BASE, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64,	METHOD_GPIO_24XX },
+	{ OMAP24XX_GPIO4_BASE, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96,	METHOD_GPIO_24XX },
+};
+#endif
+
 static struct gpio_bank *gpio_bank;
 static int gpio_bank_count;
 
@@ -149,14 +194,23 @@ static inline struct gpio_bank *get_gpio_bank(int gpio)
 		return &gpio_bank[1 + (gpio >> 5)];
 	}
 #endif
+#ifdef CONFIG_ARCH_OMAP24XX
+	if (cpu_is_omap24xx())
+		return &gpio_bank[gpio >> 5];
+#endif
 }
 
 static inline int get_gpio_index(int gpio)
 {
+#ifdef CONFIG_ARCH_OMAP730
 	if (cpu_is_omap730())
 		return gpio & 0x1f;
-	else
-		return gpio & 0x0f;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
+	if (cpu_is_omap24xx())
+		return gpio & 0x1f;
+#endif
+	return gpio & 0x0f;
 }
 
 static inline int gpio_valid(int gpio)
@@ -180,6 +234,10 @@ static inline int gpio_valid(int gpio)
 	if (cpu_is_omap730() && gpio < 192)
 		return 0;
 #endif
+#ifdef CONFIG_ARCH_OMAP24XX
+	if (cpu_is_omap24xx() && gpio < 128)
+		return 0;
+#endif
 	return -1;
 }
 
@@ -195,7 +253,7 @@ static int check_gpio(int gpio)
 
 static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
 {
-	u32 reg = bank->base;
+	void __iomem *reg = bank->base;
 	u32 l;
 
 	switch (bank->method) {
@@ -211,6 +269,9 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
 	case METHOD_GPIO_730:
 		reg += OMAP730_GPIO_DIR_CONTROL;
 		break;
+	case METHOD_GPIO_24XX:
+		reg += OMAP24XX_GPIO_OE;
+		break;
 	}
 	l = __raw_readl(reg);
 	if (is_input)
@@ -234,7 +295,7 @@ void omap_set_gpio_direction(int gpio, int is_input)
 
 static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
 {
-	u32 reg = bank->base;
+	void __iomem *reg = bank->base;
 	u32 l = 0;
 
 	switch (bank->method) {
@@ -269,6 +330,13 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
 		else
 			l &= ~(1 << gpio);
 		break;
+	case METHOD_GPIO_24XX:
+		if (enable)
+			reg += OMAP24XX_GPIO_SETDATAOUT;
+		else
+			reg += OMAP24XX_GPIO_CLEARDATAOUT;
+		l = 1 << gpio;
+		break;
 	default:
 		BUG();
 		return;
@@ -291,7 +359,7 @@ void omap_set_gpio_dataout(int gpio, int enable)
 int omap_get_gpio_datain(int gpio)
 {
 	struct gpio_bank *bank;
-	u32 reg;
+	void __iomem *reg;
 
 	if (check_gpio(gpio) < 0)
 		return -1;
@@ -310,109 +378,132 @@ int omap_get_gpio_datain(int gpio)
 	case METHOD_GPIO_730:
 		reg += OMAP730_GPIO_DATA_INPUT;
 		break;
+	case METHOD_GPIO_24XX:
+		reg += OMAP24XX_GPIO_DATAIN;
+		break;
 	default:
 		BUG();
 		return -1;
 	}
-	return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0;
+	return (__raw_readl(reg)
+			& (1 << get_gpio_index(gpio))) != 0;
 }
 
-static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge)
+#define MOD_REG_BIT(reg, bit_mask, set)	\
+do {	\
+	int l = __raw_readl(base + reg); \
+	if (set) l |= bit_mask; \
+	else l &= ~bit_mask; \
+	__raw_writel(l, base + reg); \
+} while(0)
+
+static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int trigger)
 {
-	u32 reg = bank->base;
-	u32 l;
+	u32 gpio_bit = 1 << gpio;
+
+	MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
+		trigger & IRQT_LOW);
+	MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
+		trigger & IRQT_HIGH);
+	MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
+		trigger & IRQT_RISING);
+	MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
+		trigger & IRQT_FALLING);
+	/* FIXME: Possibly do 'set_irq_handler(j, do_level_IRQ)' if only level
+	 * triggering requested. */
+}
+
+static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
+{
+	void __iomem *reg = bank->base;
+	u32 l = 0;
 
 	switch (bank->method) {
 	case METHOD_MPUIO:
 		reg += OMAP_MPUIO_GPIO_INT_EDGE;
 		l = __raw_readl(reg);
-		if (edge == OMAP_GPIO_RISING_EDGE)
+		if (trigger == IRQT_RISING)
 			l |= 1 << gpio;
-		else
+		else if (trigger == IRQT_FALLING)
 			l &= ~(1 << gpio);
-		__raw_writel(l, reg);
+		else
+			goto bad;
 		break;
 	case METHOD_GPIO_1510:
 		reg += OMAP1510_GPIO_INT_CONTROL;
 		l = __raw_readl(reg);
-		if (edge == OMAP_GPIO_RISING_EDGE)
+		if (trigger == IRQT_RISING)
 			l |= 1 << gpio;
-		else
+		else if (trigger == IRQT_FALLING)
 			l &= ~(1 << gpio);
-		__raw_writel(l, reg);
+		else
+			goto bad;
 		break;
 	case METHOD_GPIO_1610:
-		edge &= 0x03;
 		if (gpio & 0x08)
 			reg += OMAP1610_GPIO_EDGE_CTRL2;
 		else
 			reg += OMAP1610_GPIO_EDGE_CTRL1;
 		gpio &= 0x07;
+		/* We allow only edge triggering, i.e. two lowest bits */
+		if (trigger & ~IRQT_BOTHEDGE)
+			BUG();
+		/* NOTE: knows __IRQT_{FAL,RIS}EDGE match OMAP hardware */
+		trigger &= 0x03;
 		l = __raw_readl(reg);
 		l &= ~(3 << (gpio << 1));
-		l |= edge << (gpio << 1);
-		__raw_writel(l, reg);
+		l |= trigger << (gpio << 1);
 		break;
 	case METHOD_GPIO_730:
 		reg += OMAP730_GPIO_INT_CONTROL;
 		l = __raw_readl(reg);
-		if (edge == OMAP_GPIO_RISING_EDGE)
+		if (trigger == IRQT_RISING)
 			l |= 1 << gpio;
-		else
+		else if (trigger == IRQT_FALLING)
 			l &= ~(1 << gpio);
-		__raw_writel(l, reg);
+		else
+			goto bad;
+		break;
+	case METHOD_GPIO_24XX:
+		set_24xx_gpio_triggering(reg, gpio, trigger);
 		break;
 	default:
 		BUG();
-		return;
+		goto bad;
 	}
+	__raw_writel(l, reg);
+	return 0;
+bad:
+	return -EINVAL;
 }
 
-void omap_set_gpio_edge_ctrl(int gpio, int edge)
+static int gpio_irq_type(unsigned irq, unsigned type)
 {
 	struct gpio_bank *bank;
+	unsigned gpio;
+	int retval;
+
+	if (irq > IH_MPUIO_BASE)
+		gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
+	else
+		gpio = irq - IH_GPIO_BASE;
 
 	if (check_gpio(gpio) < 0)
-		return;
+		return -EINVAL;
+
+	if (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL|IRQT_PROBE))
+		return -EINVAL;
+
 	bank = get_gpio_bank(gpio);
 	spin_lock(&bank->lock);
-	_set_gpio_edge_ctrl(bank, get_gpio_index(gpio), edge);
+	retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type);
 	spin_unlock(&bank->lock);
-}
-
-
-static int _get_gpio_edge_ctrl(struct gpio_bank *bank, int gpio)
-{
-	u32 reg = bank->base, l;
-
-	switch (bank->method) {
-	case METHOD_MPUIO:
-		l = __raw_readl(reg + OMAP_MPUIO_GPIO_INT_EDGE);
-		return (l & (1 << gpio)) ?
-			OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
-	case METHOD_GPIO_1510:
-		l = __raw_readl(reg + OMAP1510_GPIO_INT_CONTROL);
-		return (l & (1 << gpio)) ?
-			OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
-	case METHOD_GPIO_1610:
-		if (gpio & 0x08)
-			reg += OMAP1610_GPIO_EDGE_CTRL2;
-		else
-			reg += OMAP1610_GPIO_EDGE_CTRL1;
-		return (__raw_readl(reg) >> ((gpio & 0x07) << 1)) & 0x03;
-	case METHOD_GPIO_730:
-		l = __raw_readl(reg + OMAP730_GPIO_INT_CONTROL);
-		return (l & (1 << gpio)) ?
-			OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
-	default:
-		BUG();
-		return -1;
-	}
+	return retval;
 }
 
 static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
 {
-	u32 reg = bank->base;
+	void __iomem *reg = bank->base;
 
 	switch (bank->method) {
 	case METHOD_MPUIO:
@@ -428,6 +519,9 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
 	case METHOD_GPIO_730:
 		reg += OMAP730_GPIO_INT_STATUS;
 		break;
+	case METHOD_GPIO_24XX:
+		reg += OMAP24XX_GPIO_IRQSTATUS1;
+		break;
 	default:
 		BUG();
 		return;
@@ -442,7 +536,7 @@ static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
 
 static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable)
 {
-	u32 reg = bank->base;
+	void __iomem *reg = bank->base;
 	u32 l;
 
 	switch (bank->method) {
@@ -477,6 +571,13 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
 		else
 			l |= gpio_mask;
 		break;
+	case METHOD_GPIO_24XX:
+		if (enable)
+			reg += OMAP24XX_GPIO_SETIRQENABLE1;
+		else
+			reg += OMAP24XX_GPIO_CLEARIRQENABLE1;
+		l = gpio_mask;
+		break;
 	default:
 		BUG();
 		return;
@@ -489,6 +590,50 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int ena
 	_enable_gpio_irqbank(bank, 1 << get_gpio_index(gpio), enable);
 }
 
+/*
+ * Note that ENAWAKEUP needs to be enabled in GPIO_SYSCONFIG register.
+ * 1510 does not seem to have a wake-up register. If JTAG is connected
+ * to the target, system will wake up always on GPIO events. While
+ * system is running all registered GPIO interrupts need to have wake-up
+ * enabled. When system is suspended, only selected GPIO interrupts need
+ * to have wake-up enabled.
+ */
+static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
+{
+	switch (bank->method) {
+	case METHOD_GPIO_1610:
+	case METHOD_GPIO_24XX:
+		spin_lock(&bank->lock);
+		if (enable)
+			bank->suspend_wakeup |= (1 << gpio);
+		else
+			bank->suspend_wakeup &= ~(1 << gpio);
+		spin_unlock(&bank->lock);
+		return 0;
+	default:
+		printk(KERN_ERR "Can't enable GPIO wakeup for method %i\n",
+		       bank->method);
+		return -EINVAL;
+	}
+}
+
+/* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
+static int gpio_wake_enable(unsigned int irq, unsigned int enable)
+{
+	unsigned int gpio = irq - IH_GPIO_BASE;
+	struct gpio_bank *bank;
+	int retval;
+
+	if (check_gpio(gpio) < 0)
+		return -ENODEV;
+	bank = get_gpio_bank(gpio);
+	spin_lock(&bank->lock);
+	retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable);
+	spin_unlock(&bank->lock);
+
+	return retval;
+}
+
 int omap_request_gpio(int gpio)
 {
 	struct gpio_bank *bank;
@@ -505,15 +650,33 @@ int omap_request_gpio(int gpio)
 		return -1;
 	}
 	bank->reserved_map |= (1 << get_gpio_index(gpio));
+
+	/* Set trigger to none. You need to enable the trigger after request_irq */
+	_set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE);
+
 #ifdef CONFIG_ARCH_OMAP1510
 	if (bank->method == METHOD_GPIO_1510) {
-		u32 reg;
+		void __iomem *reg;
 
-		/* Claim the pin for the ARM */
+		/* Claim the pin for MPU */
 		reg = bank->base + OMAP1510_GPIO_PIN_CONTROL;
 		__raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg);
 	}
 #endif
+#ifdef CONFIG_ARCH_OMAP16XX
+	if (bank->method == METHOD_GPIO_1610) {
+		/* Enable wake-up during idle for dynamic tick */
+		void __iomem *reg = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
+		__raw_writel(1 << get_gpio_index(gpio), reg);
+	}
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
+	if (bank->method == METHOD_GPIO_24XX) {
+		/* Enable wake-up during idle for dynamic tick */
+		void __iomem *reg = bank->base + OMAP24XX_GPIO_SETWKUENA;
+		__raw_writel(1 << get_gpio_index(gpio), reg);
+	}
+#endif
 	spin_unlock(&bank->lock);
 
 	return 0;
@@ -533,6 +696,20 @@ void omap_free_gpio(int gpio)
 		spin_unlock(&bank->lock);
 		return;
 	}
+#ifdef CONFIG_ARCH_OMAP16XX
+	if (bank->method == METHOD_GPIO_1610) {
+		/* Disable wake-up during idle for dynamic tick */
+		void __iomem *reg = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
+		__raw_writel(1 << get_gpio_index(gpio), reg);
+	}
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
+	if (bank->method == METHOD_GPIO_24XX) {
+		/* Disable wake-up during idle for dynamic tick */
+		void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
+		__raw_writel(1 << get_gpio_index(gpio), reg);
+	}
+#endif
 	bank->reserved_map &= ~(1 << get_gpio_index(gpio));
 	_set_gpio_direction(bank, get_gpio_index(gpio), 1);
 	_set_gpio_irqenable(bank, gpio, 0);
@@ -552,7 +729,7 @@ void omap_free_gpio(int gpio)
 static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
 			     struct pt_regs *regs)
 {
-	u32 isr_reg = 0;
+	void __iomem *isr_reg = NULL;
 	u32 isr;
 	unsigned int gpio_irq;
 	struct gpio_bank *bank;
@@ -574,24 +751,30 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
 	if (bank->method == METHOD_GPIO_730)
 		isr_reg = bank->base + OMAP730_GPIO_INT_STATUS;
 #endif
+#ifdef CONFIG_ARCH_OMAP24XX
+	if (bank->method == METHOD_GPIO_24XX)
+		isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
+#endif
 
-	isr = __raw_readl(isr_reg);
-	_enable_gpio_irqbank(bank, isr, 0);
-	_clear_gpio_irqbank(bank, isr);
-	_enable_gpio_irqbank(bank, isr, 1);
-	desc->chip->unmask(irq);
-
-	if (unlikely(!isr))
-		return;
-
-	gpio_irq = bank->virtual_irq_start;
-	for (; isr != 0; isr >>= 1, gpio_irq++) {
-		struct irqdesc *d;
-		if (!(isr & 1))
-			continue;
-		d = irq_desc + gpio_irq;
-		desc_handle_irq(gpio_irq, d, regs);
-	}
+	while(1) {
+		isr = __raw_readl(isr_reg);
+		_enable_gpio_irqbank(bank, isr, 0);
+		_clear_gpio_irqbank(bank, isr);
+		_enable_gpio_irqbank(bank, isr, 1);
+		desc->chip->unmask(irq);
+
+		if (!isr)
+			break;
+
+		gpio_irq = bank->virtual_irq_start;
+		for (; isr != 0; isr >>= 1, gpio_irq++) {
+			struct irqdesc *d;
+			if (!(isr & 1))
+				continue;
+			d = irq_desc + gpio_irq;
+			desc_handle_irq(gpio_irq, d, regs);
+		}
+        }
 }
 
 static void gpio_ack_irq(unsigned int irq)
@@ -613,14 +796,10 @@ static void gpio_mask_irq(unsigned int irq)
 static void gpio_unmask_irq(unsigned int irq)
 {
 	unsigned int gpio = irq - IH_GPIO_BASE;
+	unsigned int gpio_idx = get_gpio_index(gpio);
 	struct gpio_bank *bank = get_gpio_bank(gpio);
 
-	if (_get_gpio_edge_ctrl(bank, get_gpio_index(gpio)) == OMAP_GPIO_NO_EDGE) {
-		printk(KERN_ERR "OMAP GPIO %d: trying to enable GPIO IRQ while no edge is set\n",
-		       gpio);
-		_set_gpio_edge_ctrl(bank, get_gpio_index(gpio), OMAP_GPIO_RISING_EDGE);
-	}
-	_set_gpio_irqenable(bank, gpio, 1);
+	_set_gpio_irqenable(bank, gpio_idx, 1);
 }
 
 static void mpuio_ack_irq(unsigned int irq)
@@ -645,9 +824,11 @@ static void mpuio_unmask_irq(unsigned int irq)
 }
 
 static struct irqchip gpio_irq_chip = {
-	.ack	= gpio_ack_irq,
-	.mask	= gpio_mask_irq,
-	.unmask = gpio_unmask_irq,
+	.ack		= gpio_ack_irq,
+	.mask		= gpio_mask_irq,
+	.unmask		= gpio_unmask_irq,
+	.set_type	= gpio_irq_type,
+	.set_wake	= gpio_wake_enable,
 };
 
 static struct irqchip mpuio_irq_chip = {
@@ -657,6 +838,7 @@ static struct irqchip mpuio_irq_chip = {
 };
 
 static int initialized = 0;
+static struct clk * gpio_ck = NULL;
 
 static int __init _omap_gpio_init(void)
 {
@@ -665,6 +847,14 @@ static int __init _omap_gpio_init(void)
 
 	initialized = 1;
 
+	if (cpu_is_omap1510()) {
+		gpio_ck = clk_get(NULL, "arm_gpio_ck");
+		if (IS_ERR(gpio_ck))
+			printk("Could not get arm_gpio_ck\n");
+		else
+			clk_use(gpio_ck);
+	}
+
 #ifdef CONFIG_ARCH_OMAP1510
 	if (cpu_is_omap1510()) {
 		printk(KERN_INFO "OMAP1510 GPIO hardware\n");
@@ -674,7 +864,7 @@ static int __init _omap_gpio_init(void)
 #endif
 #if defined(CONFIG_ARCH_OMAP16XX)
 	if (cpu_is_omap16xx()) {
-		int rev;
+		u32 rev;
 
 		gpio_bank_count = 5;
 		gpio_bank = gpio_bank_1610;
@@ -690,6 +880,17 @@ static int __init _omap_gpio_init(void)
 		gpio_bank = gpio_bank_730;
 	}
 #endif
+#ifdef CONFIG_ARCH_OMAP24XX
+	if (cpu_is_omap24xx()) {
+		int rev;
+
+		gpio_bank_count = 4;
+		gpio_bank = gpio_bank_24xx;
+		rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
+		printk(KERN_INFO "OMAP24xx GPIO hardware version %d.%d\n",
+			(rev >> 4) & 0x0f, rev & 0x0f);
+	}
+#endif
 	for (i = 0; i < gpio_bank_count; i++) {
 		int j, gpio_count = 16;
 
@@ -710,6 +911,7 @@ static int __init _omap_gpio_init(void)
 		if (bank->method == METHOD_GPIO_1610) {
 			__raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1);
 			__raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
+			__raw_writew(0x0014, bank->base + OMAP1610_GPIO_SYSCONFIG);
 		}
 #endif
 #ifdef CONFIG_ARCH_OMAP730
@@ -720,6 +922,14 @@ static int __init _omap_gpio_init(void)
 			gpio_count = 32; /* 730 has 32-bit GPIOs */
 		}
 #endif
+#ifdef CONFIG_ARCH_OMAP24XX
+		if (bank->method == METHOD_GPIO_24XX) {
+			__raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1);
+			__raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1);
+
+			gpio_count = 32;
+		}
+#endif
 		for (j = bank->virtual_irq_start;
 		     j < bank->virtual_irq_start + gpio_count; j++) {
 			if (bank->method == METHOD_MPUIO)
@@ -735,12 +945,97 @@ static int __init _omap_gpio_init(void)
 
 	/* Enable system clock for GPIO module.
 	 * The CAM_CLK_CTRL *is* really the right place. */
-	if (cpu_is_omap1610() || cpu_is_omap1710())
+	if (cpu_is_omap16xx())
 		omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
 
 	return 0;
 }
 
+#if defined (CONFIG_ARCH_OMAP16XX) || defined (CONFIG_ARCH_OMAP24XX)
+static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
+{
+	int i;
+
+	if (!cpu_is_omap24xx() && !cpu_is_omap16xx())
+		return 0;
+
+	for (i = 0; i < gpio_bank_count; i++) {
+		struct gpio_bank *bank = &gpio_bank[i];
+		void __iomem *wake_status;
+		void __iomem *wake_clear;
+		void __iomem *wake_set;
+
+		switch (bank->method) {
+		case METHOD_GPIO_1610:
+			wake_status = bank->base + OMAP1610_GPIO_WAKEUPENABLE;
+			wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
+			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
+			break;
+		case METHOD_GPIO_24XX:
+			wake_status = bank->base + OMAP24XX_GPIO_SETWKUENA;
+			wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
+			wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
+			break;
+		default:
+			continue;
+		}
+
+		spin_lock(&bank->lock);
+		bank->saved_wakeup = __raw_readl(wake_status);
+		__raw_writel(0xffffffff, wake_clear);
+		__raw_writel(bank->suspend_wakeup, wake_set);
+		spin_unlock(&bank->lock);
+	}
+
+	return 0;
+}
+
+static int omap_gpio_resume(struct sys_device *dev)
+{
+	int i;
+
+	if (!cpu_is_omap24xx() && !cpu_is_omap16xx())
+		return 0;
+
+	for (i = 0; i < gpio_bank_count; i++) {
+		struct gpio_bank *bank = &gpio_bank[i];
+		void __iomem *wake_clear;
+		void __iomem *wake_set;
+
+		switch (bank->method) {
+		case METHOD_GPIO_1610:
+			wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
+			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
+			break;
+		case METHOD_GPIO_24XX:
+			wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
+			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
+			break;
+		default:
+			continue;
+		}
+
+		spin_lock(&bank->lock);
+		__raw_writel(0xffffffff, wake_clear);
+		__raw_writel(bank->saved_wakeup, wake_set);
+		spin_unlock(&bank->lock);
+	}
+
+	return 0;
+}
+
+static struct sysdev_class omap_gpio_sysclass = {
+	set_kset_name("gpio"),
+	.suspend	= omap_gpio_suspend,
+	.resume		= omap_gpio_resume,
+};
+
+static struct sys_device omap_gpio_device = {
+	.id		= 0,
+	.cls		= &omap_gpio_sysclass,
+};
+#endif
+
 /*
  * This may get called early from board specific init
  */
@@ -752,11 +1047,30 @@ int omap_gpio_init(void)
 		return 0;
 }
 
+static int __init omap_gpio_sysinit(void)
+{
+	int ret = 0;
+
+	if (!initialized)
+		ret = _omap_gpio_init();
+
+#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX)
+	if (cpu_is_omap16xx() || cpu_is_omap24xx()) {
+		if (ret == 0) {
+			ret = sysdev_class_register(&omap_gpio_sysclass);
+			if (ret == 0)
+				ret = sysdev_register(&omap_gpio_device);
+		}
+	}
+#endif
+
+	return ret;
+}
+
 EXPORT_SYMBOL(omap_request_gpio);
 EXPORT_SYMBOL(omap_free_gpio);
 EXPORT_SYMBOL(omap_set_gpio_direction);
 EXPORT_SYMBOL(omap_set_gpio_dataout);
 EXPORT_SYMBOL(omap_get_gpio_datain);
-EXPORT_SYMBOL(omap_set_gpio_edge_ctrl);
 
-arch_initcall(omap_gpio_init);
+arch_initcall(omap_gpio_sysinit);
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 43567d5edddb..9c9b7df3faf6 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -27,6 +27,7 @@
 #include <asm/arch/dma.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/irqs.h>
+#include <asm/arch/dsp_common.h>
 #include <asm/arch/mcbsp.h>
 
 #include <asm/hardware/clock.h>
@@ -187,9 +188,6 @@ static int omap_mcbsp_check(unsigned int id)
 	return -1;
 }
 
-#define EN_XORPCK		1
-#define DSP_RSTCT2              0xe1008014
-
 static void omap_mcbsp_dsp_request(void)
 {
 	if (cpu_is_omap1510() || cpu_is_omap16xx()) {
@@ -198,6 +196,11 @@ static void omap_mcbsp_dsp_request(void)
 
 		/* enable 12MHz clock to mcbsp 1 & 3 */
 		clk_use(mcbsp_dspxor_ck);
+
+		/*
+		 * DSP external peripheral reset
+		 * FIXME: This should be moved to dsp code
+		 */
 		__raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,
 			     DSP_RSTCT2);
 	}
diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c
index ea7b955b9c81..64482040f89e 100644
--- a/arch/arm/plat-omap/mux.c
+++ b/arch/arm/plat-omap/mux.c
@@ -48,6 +48,9 @@ omap_cfg_reg(const reg_cfg_t reg_cfg)
 		pull_orig = 0, pull = 0;
 	unsigned int mask, warn = 0;
 
+	if (cpu_is_omap7xx())
+		return 0;
+
 	if (reg_cfg > ARRAY_SIZE(reg_cfg_table)) {
 		printk(KERN_ERR "MUX: reg_cfg %d\n", reg_cfg);
 		return -EINVAL;
diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c
index 2ede2ee8cae4..1fb16f9edfd5 100644
--- a/arch/arm/plat-omap/ocpi.c
+++ b/arch/arm/plat-omap/ocpi.c
@@ -25,6 +25,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/version.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c
index e6536b16c385..e15c6c1ddec9 100644
--- a/arch/arm/plat-omap/pm.c
+++ b/arch/arm/plat-omap/pm.c
@@ -39,24 +39,32 @@
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
 #include <linux/pm.h>
+#include <linux/interrupt.h>
 
 #include <asm/io.h>
+#include <asm/irq.h>
 #include <asm/mach/time.h>
-#include <asm/mach-types.h>
+#include <asm/mach/irq.h>
 
-#include <asm/arch/omap16xx.h>
+#include <asm/mach-types.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/tc.h>
 #include <asm/arch/pm.h>
 #include <asm/arch/mux.h>
-#include <asm/arch/tc.h>
 #include <asm/arch/tps65010.h>
+#include <asm/arch/dsp_common.h>
 
 #include "clock.h"
+#include "sram.h"
 
 static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
 static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
 static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
 static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
 
+static void (*omap_sram_idle)(void) = NULL;
+static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL;
+
 /*
  * Let's power down on idle, but only if we are really
  * idle, because once we start down the path of
@@ -65,7 +73,6 @@ static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
  */
 void omap_pm_idle(void)
 {
-	int (*func_ptr)(void) = 0;
 	unsigned int mask32 = 0;
 
 	/*
@@ -84,6 +91,13 @@ void omap_pm_idle(void)
 	mask32 = omap_readl(ARM_SYSST);
 
 	/*
+	 * Prevent the ULPD from entering low power state by setting
+	 * POWER_CTRL_REG:4 = 0
+	 */
+	omap_writew(omap_readw(ULPD_POWER_CTRL) &
+		    ~ULPD_DEEP_SLEEP_TRANSITION_EN, ULPD_POWER_CTRL);
+
+	/*
 	 * Since an interrupt may set up a timer, we don't want to
 	 * reprogram the hardware timer with interrupts enabled.
 	 * Re-enable interrupts only after returning from idle.
@@ -92,18 +106,9 @@ void omap_pm_idle(void)
 
 	if ((mask32 & DSP_IDLE) == 0) {
 		__asm__ volatile ("mcr	p15, 0, r0, c7, c0, 4");
-	} else {
-
-		if (cpu_is_omap1510()) {
-			func_ptr = (void *)(OMAP1510_SRAM_IDLE_SUSPEND);
-		} else if (cpu_is_omap1610() || cpu_is_omap1710()) {
-			func_ptr = (void *)(OMAP1610_SRAM_IDLE_SUSPEND);
-		} else if (cpu_is_omap5912()) {
-			func_ptr = (void *)(OMAP5912_SRAM_IDLE_SUSPEND);
-		}
+	} else
+		omap_sram_idle();
 
-		func_ptr();
-	}
 	local_fiq_enable();
 	local_irq_enable();
 }
@@ -115,58 +120,55 @@ void omap_pm_idle(void)
  */
 static void omap_pm_wakeup_setup(void)
 {
-	/*
-	 * Enable ARM XOR clock and release peripheral from reset by
-	 * writing 1 to PER_EN bit in ARM_RSTCT2, this is required
-	 * for UART configuration to use UART2 to wake up.
-	 */
-
-	omap_writel(omap_readl(ARM_IDLECT2) | ENABLE_XORCLK, ARM_IDLECT2);
-	omap_writel(omap_readl(ARM_RSTCT2) | PER_EN, ARM_RSTCT2);
-	omap_writew(MODEM_32K_EN, ULPD_CLOCK_CTRL);
+	u32 level1_wake = OMAP_IRQ_BIT(INT_IH2_IRQ);
+	u32 level2_wake = OMAP_IRQ_BIT(INT_UART2) | OMAP_IRQ_BIT(INT_KEYBOARD);
 
 	/*
-	 * Turn off all interrupts except L1-2nd level cascade,
-	 * and the L2 wakeup interrupts: keypad and UART2.
+	 * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
+	 * and the L2 wakeup interrupts: keypad and UART2. Note that the
+	 * drivers must still separately call omap_set_gpio_wakeup() to
+	 * wake up to a GPIO interrupt.
 	 */
+	if (cpu_is_omap1510() || cpu_is_omap16xx())
+		level1_wake |= OMAP_IRQ_BIT(INT_GPIO_BANK1);
+	else if (cpu_is_omap730())
+		level1_wake |= OMAP_IRQ_BIT(INT_730_GPIO_BANK1);
 
-	omap_writel(~IRQ_LEVEL2, OMAP_IH1_MIR);
+	omap_writel(~level1_wake, OMAP_IH1_MIR);
 
-	if (cpu_is_omap1510()) {
-		omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD),  OMAP_IH2_MIR);
-	}
+	if (cpu_is_omap1510())
+		omap_writel(~level2_wake,  OMAP_IH2_MIR);
 
+	/* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
 	if (cpu_is_omap16xx()) {
-		omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD), OMAP_IH2_0_MIR);
-
-		omap_writel(~0x0, OMAP_IH2_1_MIR);
+		omap_writel(~level2_wake, OMAP_IH2_0_MIR);
+		omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR);
 		omap_writel(~0x0, OMAP_IH2_2_MIR);
 		omap_writel(~0x0, OMAP_IH2_3_MIR);
 	}
 
-	/*  New IRQ agreement */
+	/*  New IRQ agreement, recalculate in cascade order */
+	omap_writel(1, OMAP_IH2_CONTROL);
  	omap_writel(1, OMAP_IH1_CONTROL);
-
-	/* external PULL to down, bit 22 = 0 */
-	omap_writel(omap_readl(PULL_DWN_CTRL_2) & ~(1<<22), PULL_DWN_CTRL_2);
 }
 
 void omap_pm_suspend(void)
 {
-	unsigned int mask32 = 0;
 	unsigned long arg0 = 0, arg1 = 0;
-	int (*func_ptr)(unsigned short, unsigned short) = 0;
-	unsigned short save_dsp_idlect2;
 
-	printk("PM: OMAP%x is entering deep sleep now ...\n", system_rev);
+	printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev);
+
+	omap_serial_wake_trigger(1);
 
 	if (machine_is_omap_osk()) {
 		/* Stop LED1 (D9) blink */
 		tps65010_set_led(LED1, OFF);
 	}
 
+	omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG);
+
 	/*
-	 * Step 1: turn off interrupts
+	 * Step 1: turn off interrupts (FIXME: NOTE: already disabled)
 	 */
 
 	local_irq_disable();
@@ -207,6 +209,8 @@ void omap_pm_suspend(void)
 	ARM_SAVE(ARM_CKCTL);
 	ARM_SAVE(ARM_IDLECT1);
 	ARM_SAVE(ARM_IDLECT2);
+	if (!(cpu_is_omap1510()))
+		ARM_SAVE(ARM_IDLECT3);
 	ARM_SAVE(ARM_EWUPCT);
 	ARM_SAVE(ARM_RSTCT1);
 	ARM_SAVE(ARM_RSTCT2);
@@ -214,42 +218,12 @@ void omap_pm_suspend(void)
 	ULPD_SAVE(ULPD_CLOCK_CTRL);
 	ULPD_SAVE(ULPD_STATUS_REQ);
 
-	/*
-	 * Step 3: LOW_PWR signal enabling
-	 *
-	 * Allow the LOW_PWR signal to be visible on MPUIO5 ball.
-	 */
-	if (cpu_is_omap1510()) {
-		/* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */
-		omap_writew(omap_readw(ULPD_POWER_CTRL) |
-			    OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
-	} else if (cpu_is_omap16xx()) {
-		/* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */
-		omap_writew(omap_readw(ULPD_POWER_CTRL) |
-			    OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
-	}
-
-	/* configure LOW_PWR pin */
-	omap_cfg_reg(T20_1610_LOW_PWR);
+	/* (Step 3 removed - we now allow deep sleep by default) */
 
 	/*
 	 * Step 4: OMAP DSP Shutdown
 	 */
 
-	/* Set DSP_RST = 1 and DSP_EN = 0, put DSP block into reset */
-	omap_writel((omap_readl(ARM_RSTCT1) | DSP_RST) & ~DSP_ENABLE,
-		    ARM_RSTCT1);
-
-	/* Set DSP boot mode to DSP-IDLE, DSP_BOOT_MODE = 0x2 */
-        omap_writel(DSP_IDLE_MODE, MPUI_DSP_BOOT_CONFIG);
-
-	/* Set EN_DSPCK = 0, stop DSP block clock */
-	omap_writel(omap_readl(ARM_CKCTL) & ~DSP_CLOCK_ENABLE, ARM_CKCTL);
-
-	/* Stop any DSP domain clocks */
-	omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2);
-	save_dsp_idlect2 = __raw_readw(DSP_IDLECT2);
-	__raw_writew(0, DSP_IDLECT2);
 
 	/*
 	 * Step 5: Wakeup Event Setup
@@ -258,24 +232,9 @@ void omap_pm_suspend(void)
 	omap_pm_wakeup_setup();
 
 	/*
-	 * Step 6a: ARM and Traffic controller shutdown
-	 *
-	 * Step 6 starts here with clock and watchdog disable
+	 * Step 6: ARM and Traffic controller shutdown
 	 */
 
-	/* stop clocks */
-	mask32 = omap_readl(ARM_IDLECT2);
-	mask32 &= ~(1<<EN_WDTCK);  /* bit 0 -> 0 (WDT clock) */
-	mask32 |=  (1<<EN_XORPCK); /* bit 1 -> 1 (XORPCK clock) */
-	mask32 &= ~(1<<EN_PERCK);  /* bit 2 -> 0 (MPUPER_CK clock) */
-	mask32 &= ~(1<<EN_LCDCK);  /* bit 3 -> 0 (LCDC clock) */
-	mask32 &= ~(1<<EN_LBCK);   /* bit 4 -> 0 (local bus clock) */
-	mask32 |=  (1<<EN_APICK);  /* bit 6 -> 1 (MPUI clock) */
-	mask32 &= ~(1<<EN_TIMCK);  /* bit 7 -> 0 (MPU timer clock) */
-	mask32 &= ~(1<<DMACK_REQ); /* bit 8 -> 0 (DMAC clock) */
-	mask32 &= ~(1<<EN_GPIOCK); /* bit 9 -> 0 (GPIO clock) */
-	omap_writel(mask32, ARM_IDLECT2);
-
 	/* disable ARM watchdog */
 	omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
 	omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
@@ -295,47 +254,24 @@ void omap_pm_suspend(void)
 	arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1];
 	arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2];
 
-	if (cpu_is_omap1510()) {
-		func_ptr = (void *)(OMAP1510_SRAM_API_SUSPEND);
-	} else if (cpu_is_omap1610() || cpu_is_omap1710()) {
-		func_ptr = (void *)(OMAP1610_SRAM_API_SUSPEND);
-	} else if (cpu_is_omap5912()) {
-		func_ptr = (void *)(OMAP5912_SRAM_API_SUSPEND);
-	}
-
 	/*
 	 * Step 6c: ARM and Traffic controller shutdown
 	 *
 	 * Jump to assembly code. The processor will stay there
  	 * until wake up.
 	 */
-
-        func_ptr(arg0, arg1);
+        omap_sram_suspend(arg0, arg1);
 
 	/*
 	 * If we are here, processor is woken up!
 	 */
 
-	if (cpu_is_omap1510()) {
-		/* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */
-		omap_writew(omap_readw(ULPD_POWER_CTRL) &
-			    ~OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
-	} else if (cpu_is_omap16xx()) {
-		/* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */
-		omap_writew(omap_readw(ULPD_POWER_CTRL) &
-			    ~OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
-	}
-
-
-	/* Restore DSP clocks */
-	omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2);
-	__raw_writew(save_dsp_idlect2, DSP_IDLECT2);
-	ARM_RESTORE(ARM_IDLECT2);
-
 	/*
 	 * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
 	 */
 
+	if (!(cpu_is_omap1510()))
+		ARM_RESTORE(ARM_IDLECT3);
 	ARM_RESTORE(ARM_CKCTL);
 	ARM_RESTORE(ARM_EWUPCT);
 	ARM_RESTORE(ARM_RSTCT1);
@@ -366,6 +302,8 @@ void omap_pm_suspend(void)
 		MPUI1610_RESTORE(OMAP_IH2_3_MIR);
 	}
 
+	omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG);
+
 	/*
 	 * Reenable interrupts
 	 */
@@ -373,6 +311,8 @@ void omap_pm_suspend(void)
 	local_irq_enable();
 	local_fiq_enable();
 
+	omap_serial_wake_trigger(0);
+
 	printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev);
 
 	if (machine_is_omap_osk()) {
@@ -401,6 +341,8 @@ static int omap_pm_read_proc(
 	ARM_SAVE(ARM_CKCTL);
 	ARM_SAVE(ARM_IDLECT1);
 	ARM_SAVE(ARM_IDLECT2);
+	if (!(cpu_is_omap1510()))
+		ARM_SAVE(ARM_IDLECT3);
 	ARM_SAVE(ARM_EWUPCT);
 	ARM_SAVE(ARM_RSTCT1);
 	ARM_SAVE(ARM_RSTCT2);
@@ -436,6 +378,7 @@ static int omap_pm_read_proc(
 		   "ARM_CKCTL_REG:            0x%-8x     \n"
 		   "ARM_IDLECT1_REG:          0x%-8x     \n"
 		   "ARM_IDLECT2_REG:          0x%-8x     \n"
+		   "ARM_IDLECT3_REG:	      0x%-8x     \n"
 		   "ARM_EWUPCT_REG:           0x%-8x     \n"
 		   "ARM_RSTCT1_REG:           0x%-8x     \n"
 		   "ARM_RSTCT2_REG:           0x%-8x     \n"
@@ -449,6 +392,7 @@ static int omap_pm_read_proc(
 		   ARM_SHOW(ARM_CKCTL),
 		   ARM_SHOW(ARM_IDLECT1),
 		   ARM_SHOW(ARM_IDLECT2),
+		   ARM_SHOW(ARM_IDLECT3),
 		   ARM_SHOW(ARM_EWUPCT),
 		   ARM_SHOW(ARM_RSTCT1),
 		   ARM_SHOW(ARM_RSTCT2),
@@ -507,7 +451,7 @@ static void omap_pm_init_proc(void)
 
 	entry = create_proc_read_entry("driver/omap_pm",
 				       S_IWUSR | S_IRUGO, NULL,
-				       omap_pm_read_proc, 0);
+	   omap_pm_read_proc, NULL);
 }
 
 #endif /* DEBUG && CONFIG_PROC_FS */
@@ -580,7 +524,21 @@ static int omap_pm_finish(suspend_state_t state)
 }
 
 
-struct pm_ops omap_pm_ops ={
+static irqreturn_t  omap_wakeup_interrupt(int  irq, void *  dev,
+				     struct pt_regs *  regs)
+{
+	return IRQ_HANDLED;
+}
+
+static struct irqaction omap_wakeup_irq = {
+	.name		= "peripheral wakeup",
+	.flags		= SA_INTERRUPT,
+	.handler	= omap_wakeup_interrupt
+};
+
+
+
+static struct pm_ops omap_pm_ops ={
 	.pm_disk_mode = 0,
         .prepare        = omap_pm_prepare,
         .enter          = omap_pm_enter,
@@ -590,42 +548,61 @@ struct pm_ops omap_pm_ops ={
 static int __init omap_pm_init(void)
 {
 	printk("Power Management for TI OMAP.\n");
-	pm_idle = omap_pm_idle;
 	/*
 	 * We copy the assembler sleep/wakeup routines to SRAM.
 	 * These routines need to be in SRAM as that's the only
 	 * memory the MPU can see when it wakes up.
 	 */
-
-#ifdef	CONFIG_ARCH_OMAP1510
 	if (cpu_is_omap1510()) {
-		memcpy((void *)OMAP1510_SRAM_IDLE_SUSPEND,
-		       omap1510_idle_loop_suspend,
-		       omap1510_idle_loop_suspend_sz);
-		memcpy((void *)OMAP1510_SRAM_API_SUSPEND, omap1510_cpu_suspend,
-		       omap1510_cpu_suspend_sz);
-	} else
-#endif
-	if (cpu_is_omap1610() || cpu_is_omap1710()) {
-		memcpy((void *)OMAP1610_SRAM_IDLE_SUSPEND,
-		       omap1610_idle_loop_suspend,
-		       omap1610_idle_loop_suspend_sz);
-		memcpy((void *)OMAP1610_SRAM_API_SUSPEND, omap1610_cpu_suspend,
-		       omap1610_cpu_suspend_sz);
-	} else if (cpu_is_omap5912()) {
-		memcpy((void *)OMAP5912_SRAM_IDLE_SUSPEND,
-		       omap1610_idle_loop_suspend,
-		       omap1610_idle_loop_suspend_sz);
-		memcpy((void *)OMAP5912_SRAM_API_SUSPEND, omap1610_cpu_suspend,
-		       omap1610_cpu_suspend_sz);
+		omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend,
+						omap1510_idle_loop_suspend_sz);
+		omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
+						   omap1510_cpu_suspend_sz);
+	} else if (cpu_is_omap16xx()) {
+		omap_sram_idle = omap_sram_push(omap1610_idle_loop_suspend,
+						omap1610_idle_loop_suspend_sz);
+		omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend,
+						   omap1610_cpu_suspend_sz);
 	}
 
+	if (omap_sram_idle == NULL || omap_sram_suspend == NULL) {
+		printk(KERN_ERR "PM not initialized: Missing SRAM support\n");
+		return -ENODEV;
+	}
+
+	pm_idle = omap_pm_idle;
+
+	setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
+#if 0
+	/* --- BEGIN BOARD-DEPENDENT CODE --- */
+	/* Sleepx mask direction */
+	omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008);
+	/* Unmask sleepx signal */
+	omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004);
+	/* --- END BOARD-DEPENDENT CODE --- */
+#endif
+
+	/* Program new power ramp-up time
+	 * (0 for most boards since we don't lower voltage when in deep sleep)
+	 */
+	omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3);
+
+	/* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */
+	omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
+
+	/* Configure IDLECT3 */
+	if (cpu_is_omap16xx())
+		omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
+
 	pm_set_ops(&omap_pm_ops);
 
 #if defined(DEBUG) && defined(CONFIG_PROC_FS)
 	omap_pm_init_proc();
 #endif
 
+	/* configure LOW_PWR pin */
+	omap_cfg_reg(T20_1610_LOW_PWR);
+
 	return 0;
 }
 __initcall(omap_pm_init);
diff --git a/arch/arm/plat-omap/sleep.S b/arch/arm/plat-omap/sleep.S
index 279490ce772b..9f745836f6aa 100644
--- a/arch/arm/plat-omap/sleep.S
+++ b/arch/arm/plat-omap/sleep.S
@@ -66,7 +66,7 @@ ENTRY(omap1510_idle_loop_suspend)
 	@ get ARM_IDLECT2 into r2
 	ldrh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
 	mov	r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
- 	orr	r5,r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
+	orr	r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
 	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
 
 	@ request ARM idle
@@ -76,7 +76,7 @@ ENTRY(omap1510_idle_loop_suspend)
 	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
 
 	mov	r5, #IDLE_WAIT_CYCLES & 0xff
-	orr     r5, r5, #IDLE_WAIT_CYCLES & 0xff00
+	orr	r5, r5, #IDLE_WAIT_CYCLES & 0xff00
 l_1510:	subs	r5, r5, #1
 	bne	l_1510
 /*
@@ -96,7 +96,7 @@ l_1510:	subs	r5, r5, #1
 	strh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
 	strh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
 
-	ldmfd   sp!, {r0 - r12, pc}     @ restore regs and return
+	ldmfd	sp!, {r0 - r12, pc}		@ restore regs and return
 
 ENTRY(omap1510_idle_loop_suspend_sz)
 	.word	. - omap1510_idle_loop_suspend
@@ -115,8 +115,8 @@ ENTRY(omap1610_idle_loop_suspend)
 	@ turn off clock domains
 	@ get ARM_IDLECT2 into r2
 	ldrh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
-	mov	r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff
- 	orr	r5,r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff00
+	mov	r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff
+	orr	r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00
 	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
 
 	@ request ARM idle
@@ -126,7 +126,7 @@ ENTRY(omap1610_idle_loop_suspend)
 	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
 
 	mov	r5, #IDLE_WAIT_CYCLES & 0xff
-	orr     r5, r5, #IDLE_WAIT_CYCLES & 0xff00
+	orr	r5, r5, #IDLE_WAIT_CYCLES & 0xff00
 l_1610:	subs	r5, r5, #1
 	bne	l_1610
 /*
@@ -146,7 +146,7 @@ l_1610:	subs	r5, r5, #1
 	strh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
 	strh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
 
-	ldmfd   sp!, {r0 - r12, pc}     @ restore regs and return
+	ldmfd	sp!, {r0 - r12, pc}		@ restore regs and return
 
 ENTRY(omap1610_idle_loop_suspend_sz)
 	.word	. - omap1610_idle_loop_suspend
@@ -208,7 +208,7 @@ ENTRY(omap1510_cpu_suspend)
 
 	@ turn off clock domains
 	mov	r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
- 	orr	r5,r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
+	orr	r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
 	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
 
 	@ request ARM idle
@@ -217,7 +217,7 @@ ENTRY(omap1510_cpu_suspend)
 	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
 
 	mov	r5, #IDLE_WAIT_CYCLES & 0xff
-	orr     r5, r5, #IDLE_WAIT_CYCLES & 0xff00
+	orr	r5, r5, #IDLE_WAIT_CYCLES & 0xff00
 l_1510_2:
 	subs	r5, r5, #1
 	bne	l_1510_2
@@ -237,7 +237,7 @@ l_1510_2:
 	strh	r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
 
 	@ restore regs and return
-	ldmfd   sp!, {r0 - r12, pc}
+	ldmfd	sp!, {r0 - r12, pc}
 
 ENTRY(omap1510_cpu_suspend_sz)
 	.word	. - omap1510_cpu_suspend
@@ -249,21 +249,26 @@ ENTRY(omap1610_cpu_suspend)
 	@ save registers on stack
 	stmfd	sp!, {r0 - r12, lr}
 
+	@ Drain write cache
+	mov	r4, #0
+	mcr	p15, 0, r0, c7, c10, 4
+	nop
+
 	@ load base address of Traffic Controller
-	mov	r4, #TCMIF_ASM_BASE & 0xff000000
-	orr	r4, r4, #TCMIF_ASM_BASE & 0x00ff0000
-	orr	r4, r4, #TCMIF_ASM_BASE & 0x0000ff00
+	mov	r6, #TCMIF_ASM_BASE & 0xff000000
+	orr	r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
+	orr	r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
 
 	@ prepare to put SDRAM into self-refresh manually
-	ldr	r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
-	orr	r5, r5, #SELF_REFRESH_MODE & 0xff000000
-	orr	r5, r5, #SELF_REFRESH_MODE & 0x000000ff
-	str	r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+	ldr	r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+	orr	r9, r7, #SELF_REFRESH_MODE & 0xff000000
+	orr	r9, r9, #SELF_REFRESH_MODE & 0x000000ff
+	str	r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
 
 	@ prepare to put EMIFS to Sleep
-	ldr	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
-	orr	r5, r5, #IDLE_EMIFS_REQUEST & 0xff
-	str	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+	ldr	r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+	orr	r9, r8, #IDLE_EMIFS_REQUEST & 0xff
+	str	r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
 
 	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
 	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
@@ -271,26 +276,22 @@ ENTRY(omap1610_cpu_suspend)
 	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
 
 	@ turn off clock domains
-	mov	r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff
- 	orr	r5,r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff00
-	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
-
-	@ work around errata of OMAP1610/5912. Enable (!) peripheral
-	@ clock to let the chip go into deep sleep
-	ldrh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
- 	orr	r5,r5, #EN_PERCK_BIT & 0xff
+	@ do not disable PERCK (0x04)
+	mov	r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff
+	orr	r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00
 	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
 
 	@ request ARM idle
-	mov	r3, #OMAP1610_DEEP_SLEEP_REQUEST & 0xff
-	orr	r3, r3, #OMAP1610_DEEP_SLEEP_REQUEST & 0xff00
+	mov	r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff
+	orr	r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00
 	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
 
-	mov	r5, #IDLE_WAIT_CYCLES & 0xff
-	orr     r5, r5, #IDLE_WAIT_CYCLES & 0xff00
-l_1610_2:
-	subs	r5, r5, #1
-	bne	l_1610_2
+	@ disable instruction cache
+	mrc	p15, 0, r9, c1, c0, 0
+	bic	r2, r9, #0x1000
+	mcr	p15, 0, r2, c1, c0, 0
+	nop
+
 /*
  * Let's wait for the next wake up event to wake us up. r0 can't be
  * used here because r0 holds ARM_IDLECT1
@@ -301,13 +302,21 @@ l_1610_2:
  * omap1610_cpu_suspend()'s resume point.
  *
  * It will just start executing here, so we'll restore stuff from the
- * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
+ * stack.
  */
+	@ re-enable Icache
+	mcr	p15, 0, r9, c1, c0, 0
+
+	@ reset the ARM_IDLECT1 and ARM_IDLECT2.
 	strh	r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
 	strh	r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
 
+	@ Restore EMIFF controls
+	str	r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+	str	r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+
 	@ restore regs and return
-	ldmfd   sp!, {r0 - r12, pc}
+	ldmfd	sp!, {r0 - r12, pc}
 
 ENTRY(omap1610_cpu_suspend_sz)
 	.word	. - omap1610_cpu_suspend
diff --git a/arch/arm/plat-omap/sram-fn.S b/arch/arm/plat-omap/sram-fn.S
new file mode 100644
index 000000000000..4bea36964a00
--- /dev/null
+++ b/arch/arm/plat-omap/sram-fn.S
@@ -0,0 +1,58 @@
+/*
+ * linux/arch/arm/plat-omap/sram.S
+ *
+ * Functions that need to be run in internal SRAM
+ *
+ * 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/config.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/arch/io.h>
+#include <asm/arch/hardware.h>
+
+	.text
+
+/*
+ * Reprograms ULPD and CKCTL.
+ */
+ENTRY(sram_reprogram_clock)
+	stmfd	sp!, {r0 - r12, lr}		@ save registers on stack
+
+	mov	r2, #IO_ADDRESS(DPLL_CTL) & 0xff000000
+	orr	r2, r2, #IO_ADDRESS(DPLL_CTL) & 0x00ff0000
+	orr	r2, r2, #IO_ADDRESS(DPLL_CTL) & 0x0000ff00
+
+	mov	r3, #IO_ADDRESS(ARM_CKCTL) & 0xff000000
+	orr	r3, r3, #IO_ADDRESS(ARM_CKCTL) & 0x00ff0000
+	orr	r3, r3, #IO_ADDRESS(ARM_CKCTL) & 0x0000ff00
+
+	tst	r0, #1 << 4			@ want lock mode?
+	beq	newck				@ nope
+	bic	r0, r0, #1 << 4			@ else clear lock bit
+	strh	r0, [r2]			@ set dpll into bypass mode
+	orr	r0, r0, #1 << 4			@ set lock bit again
+
+newck:
+	strh	r1, [r3]			@ write new ckctl value
+	strh	r0, [r2]			@ write new dpll value
+
+	mov	r4, #0x0700			@ let the clocks settle
+	orr	r4, r4, #0x00ff
+delay:	sub	r4, r4, #1
+	cmp	r4, #0
+	bne	delay
+
+lock:	ldrh	r4, [r2], #0			@ read back dpll value
+	tst	r0, #1 << 4			@ want lock mode?
+	beq	out				@ nope
+	tst	r4, #1 << 0			@ dpll rate locked?
+	beq	lock				@ try again
+
+out:
+	ldmfd	sp!, {r0 - r12, pc}		@ restore regs and return
+ENTRY(sram_reprogram_clock_sz)
+	.word	. - sram_reprogram_clock
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
new file mode 100644
index 000000000000..7719a4062e3a
--- /dev/null
+++ b/arch/arm/plat-omap/sram.c
@@ -0,0 +1,116 @@
+/*
+ * linux/arch/arm/plat-omap/sram.c
+ *
+ * OMAP SRAM detection and management
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * 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/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+#include <asm/io.h>
+#include <asm/cacheflush.h>
+
+#include "sram.h"
+
+#define OMAP1_SRAM_BASE		0xd0000000
+#define OMAP1_SRAM_START	0x20000000
+#define SRAM_BOOTLOADER_SZ	0x80
+
+static unsigned long omap_sram_base;
+static unsigned long omap_sram_size;
+static unsigned long omap_sram_ceil;
+
+/*
+ * The amount of SRAM depends on the core type:
+ * 730 = 200K, 1510 = 512K, 5912 = 256K, 1610 = 16K, 1710 = 16K
+ * Note that we cannot try to test for SRAM here because writes
+ * to secure SRAM will hang the system. Also the SRAM is not
+ * yet mapped at this point.
+ */
+void __init omap_detect_sram(void)
+{
+	omap_sram_base = OMAP1_SRAM_BASE;
+
+	if (cpu_is_omap730())
+		omap_sram_size = 0x32000;
+	else if (cpu_is_omap1510())
+		omap_sram_size = 0x80000;
+	else if (cpu_is_omap1610() || cpu_is_omap1621() || cpu_is_omap1710())
+		omap_sram_size = 0x4000;
+	else if (cpu_is_omap1611())
+		omap_sram_size = 0x3e800;
+	else {
+		printk(KERN_ERR "Could not detect SRAM size\n");
+		omap_sram_size = 0x4000;
+	}
+
+	printk(KERN_INFO "SRAM size: 0x%lx\n", omap_sram_size);
+	omap_sram_ceil = omap_sram_base + omap_sram_size;
+}
+
+static struct map_desc omap_sram_io_desc[] __initdata = {
+	{ OMAP1_SRAM_BASE, OMAP1_SRAM_START, 0, MT_DEVICE }
+};
+
+/*
+ * In order to use last 2kB of SRAM on 1611b, we must round the size
+ * up to multiple of PAGE_SIZE. We cannot use ioremap for SRAM, as
+ * clock init needs SRAM early.
+ */
+void __init omap_map_sram(void)
+{
+	if (omap_sram_size == 0)
+		return;
+
+	omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE;
+	omap_sram_io_desc[0].length *= PAGE_SIZE;
+	iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc));
+
+	/*
+	 * Looks like we need to preserve some bootloader code at the
+	 * beginning of SRAM for jumping to flash for reboot to work...
+	 */
+	memset((void *)omap_sram_base + SRAM_BOOTLOADER_SZ, 0,
+	       omap_sram_size - SRAM_BOOTLOADER_SZ);
+}
+
+static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl) = NULL;
+
+void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
+{
+	if (_omap_sram_reprogram_clock == NULL)
+		panic("Cannot use SRAM");
+
+	return _omap_sram_reprogram_clock(dpllctl, ckctl);
+}
+
+void * omap_sram_push(void * start, unsigned long size)
+{
+	if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) {
+		printk(KERN_ERR "Not enough space in SRAM\n");
+		return NULL;
+	}
+	omap_sram_ceil -= size;
+	omap_sram_ceil &= ~0x3;
+	memcpy((void *)omap_sram_ceil, start, size);
+
+	return (void *)omap_sram_ceil;
+}
+
+void __init omap_sram_init(void)
+{
+	omap_detect_sram();
+	omap_map_sram();
+	_omap_sram_reprogram_clock = omap_sram_push(sram_reprogram_clock,
+						    sram_reprogram_clock_sz);
+}
diff --git a/arch/arm/plat-omap/sram.h b/arch/arm/plat-omap/sram.h
new file mode 100644
index 000000000000..71984efa6ae8
--- /dev/null
+++ b/arch/arm/plat-omap/sram.h
@@ -0,0 +1,21 @@
+/*
+ * linux/arch/arm/plat-omap/sram.h
+ *
+ * Interface for functions that need to be run in internal SRAM
+ *
+ * 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.
+ */
+
+#ifndef __ARCH_ARM_OMAP_SRAM_H
+#define __ARCH_ARM_OMAP_SRAM_H
+
+extern void * omap_sram_push(void * start, unsigned long size);
+extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
+
+/* Do not use these */
+extern void sram_reprogram_clock(u32 ckctl, u32 dpllctl);
+extern unsigned long sram_reprogram_clock_sz;
+
+#endif
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c
index 25bc4a8dd763..98f1c76f8660 100644
--- a/arch/arm/plat-omap/usb.c
+++ b/arch/arm/plat-omap/usb.c
@@ -41,6 +41,7 @@
 
 /* These routines should handle the standard chip-specific modes
  * for usb0/1/2 ports, covering basic mux and transceiver setup.
+ * Call omap_usb_init() once, from INIT_MACHINE().
  *
  * Some board-*.c files will need to set up additional mux options,
  * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup.
diff --git a/include/asm-arm/arch-omap/board-h4.h b/include/asm-arm/arch-omap/board-h4.h
index 79138dcfb4ac..d64ee9211eed 100644
--- a/include/asm-arm/arch-omap/board-h4.h
+++ b/include/asm-arm/arch-omap/board-h4.h
@@ -30,6 +30,9 @@
 #define __ASM_ARCH_OMAP_H4_H
 
 /* Placeholder for H4 specific defines */
+/* GPMC CS1 */
+#define OMAP24XX_ETHR_START             0x08000300
+#define OMAP24XX_ETHR_GPIO_IRQ		92
 
 #endif /*  __ASM_ARCH_OMAP_H4_H */
 
diff --git a/include/asm-arm/arch-omap/board-innovator.h b/include/asm-arm/arch-omap/board-innovator.h
index 0f1abaefe4de..79574e0ed13d 100644
--- a/include/asm-arm/arch-omap/board-innovator.h
+++ b/include/asm-arm/arch-omap/board-innovator.h
@@ -36,31 +36,6 @@
 #define OMAP1510P1_EMIFS_PRI_VALUE		0x00
 #define OMAP1510P1_EMIFF_PRI_VALUE		0x00
 
-/*
- * These definitions define an area of FLASH set aside
- * for the use of MTD/JFFS2. This is the area of flash
- * that a JFFS2 filesystem will reside which is mounted
- * at boot with the "root=/dev/mtdblock/0 rw"
- * command line option. The flash address used here must
- * fall within the legal range defined by rrload for storing
- * the filesystem component. This address will be sufficiently
- * deep into the overall flash range to avoid the other
- * components also stored in flash such as the bootloader,
- * the bootloader params, and the kernel.
- * The SW2 settings for the map below are:
- * 1 off, 2 off, 3 on, 4 off.
- */
-
-/* Intel flash_0, partitioned as expected by rrload */
-#define OMAP_FLASH_0_BASE	0xD8000000
-#define OMAP_FLASH_0_START	0x00000000
-#define OMAP_FLASH_0_SIZE	SZ_16M
-
-/* Intel flash_1, used for cramfs or other flash file systems */
-#define OMAP_FLASH_1_BASE	0xD9000000
-#define OMAP_FLASH_1_START	0x01000000
-#define OMAP_FLASH_1_SIZE	SZ_16M
-
 #define NR_FPGA_IRQS		24
 #define NR_IRQS                 IH_BOARD_BASE + NR_FPGA_IRQS
 
diff --git a/include/asm-arm/arch-omap/board-perseus2.h b/include/asm-arm/arch-omap/board-perseus2.h
index 0c224cc74fe4..691e52a52b43 100644
--- a/include/asm-arm/arch-omap/board-perseus2.h
+++ b/include/asm-arm/arch-omap/board-perseus2.h
@@ -36,23 +36,14 @@
 #define OMAP_SDRAM_DEVICE		D256M_1X16_4B
 #endif
 
-/*
- * These definitions define an area of FLASH set aside
- * for the use of MTD/JFFS2. This is the area of flash
- * that a JFFS2 filesystem will reside which is mounted
- * at boot with the "root=/dev/mtdblock/0 rw"
- * command line option.
- */
-
-/* Intel flash_0, partitioned as expected by rrload */
-#define OMAP_FLASH_0_BASE	0xD8000000	/* VA */
-#define OMAP_FLASH_0_START	0x00000000	/* PA */
-#define OMAP_FLASH_0_SIZE	SZ_32M
-
 #define MAXIRQNUM		IH_BOARD_BASE
 #define MAXFIQNUM		MAXIRQNUM
 #define MAXSWINUM		MAXIRQNUM
 
 #define NR_IRQS			(MAXIRQNUM + 1)
 
+/* Samsung NAND flash at CS2B or CS3(NAND Boot) */
+#define OMAP_NAND_FLASH_START1	   0x0A000000 /* CS2B */
+#define OMAP_NAND_FLASH_START2	   0x0C000000 /* CS3 */
+
 #endif
diff --git a/include/asm-arm/arch-omap/board-voiceblue.h b/include/asm-arm/arch-omap/board-voiceblue.h
index 33977b8956fb..ed6d346ee123 100644
--- a/include/asm-arm/arch-omap/board-voiceblue.h
+++ b/include/asm-arm/arch-omap/board-voiceblue.h
@@ -11,11 +11,6 @@
 #ifndef __ASM_ARCH_VOICEBLUE_H
 #define __ASM_ARCH_VOICEBLUE_H
 
-#if (EXTERNAL_MAX_NR_PORTS < 4)
-#undef EXTERNAL_MAX_NR_PORTS
-#define EXTERNAL_MAX_NR_PORTS	4
-#endif
-
 extern void voiceblue_wdt_enable(void);
 extern void voiceblue_wdt_disable(void);
 extern void voiceblue_wdt_ping(void);
diff --git a/include/asm-arm/arch-omap/board.h b/include/asm-arm/arch-omap/board.h
index 95bd625480c1..a0040cd86639 100644
--- a/include/asm-arm/arch-omap/board.h
+++ b/include/asm-arm/arch-omap/board.h
@@ -30,10 +30,23 @@ struct omap_clock_config {
 	u8 system_clock_type;
 };
 
+struct omap_mmc_conf {
+	unsigned enabled:1;
+	/* nomux means "standard" muxing is wrong on this board, and that
+	 * board-specific code handled it before common init logic.
+	 */
+	unsigned nomux:1;
+	/* switch pin can be for card detect (default) or card cover */
+	unsigned cover:1;
+	/* 4 wire signaling is optional, and is only used for SD/SDIO */
+	unsigned wire4:1;
+	s16 power_pin;
+	s16 switch_pin;
+	s16 wp_pin;
+};
+
 struct omap_mmc_config {
-	u8 mmc_blocks;
-	s16 mmc1_power_pin, mmc2_power_pin;
-	s16 mmc1_switch_pin, mmc2_switch_pin;
+	struct omap_mmc_conf mmc[2];
 };
 
 struct omap_serial_console_config {
diff --git a/include/asm-arm/arch-omap/cpu.h b/include/asm-arm/arch-omap/cpu.h
index e8786713ee5c..1119e2b53e72 100644
--- a/include/asm-arm/arch-omap/cpu.h
+++ b/include/asm-arm/arch-omap/cpu.h
@@ -38,146 +38,179 @@ extern unsigned int system_rev;
 /*
  * Test if multicore OMAP support is needed
  */
-#undef MULTI_OMAP
+#undef MULTI_OMAP1
+#undef MULTI_OMAP2
 #undef OMAP_NAME
 
 #ifdef CONFIG_ARCH_OMAP730
 # ifdef OMAP_NAME
-#  undef  MULTI_OMAP
-#  define MULTI_OMAP
+#  undef  MULTI_OMAP1
+#  define MULTI_OMAP1
 # else
 #  define OMAP_NAME omap730
 # endif
 #endif
 #ifdef CONFIG_ARCH_OMAP1510
 # ifdef OMAP_NAME
-#  undef  MULTI_OMAP
-#  define MULTI_OMAP
+#  undef  MULTI_OMAP1
+#  define MULTI_OMAP1
 # else
 #  define OMAP_NAME omap1510
 # endif
 #endif
 #ifdef CONFIG_ARCH_OMAP16XX
 # ifdef OMAP_NAME
-#  undef  MULTI_OMAP
-#  define MULTI_OMAP
+#  undef  MULTI_OMAP1
+#  define MULTI_OMAP1
 # else
-#  define OMAP_NAME omap1610
+#  define OMAP_NAME omap16xx
 # endif
 #endif
-#ifdef CONFIG_ARCH_OMAP16XX
-# ifdef OMAP_NAME
-#  undef  MULTI_OMAP
-#  define MULTI_OMAP
+#ifdef CONFIG_ARCH_OMAP24XX
+# if (defined(OMAP_NAME) || defined(MULTI_OMAP1))
+#  error "OMAP1 and OMAP2 can't be selected at the same time"
 # else
-#  define OMAP_NAME omap1710
+#  undef  MULTI_OMAP2
+#  define OMAP_NAME omap24xx
 # endif
 #endif
 
 /*
- * Generate various OMAP cpu specific macros, and cpu class
- * specific macros
+ * Macros to group OMAP into cpu classes.
+ * These can be used in most places.
+ * cpu_is_omap7xx():	True for OMAP730
+ * cpu_is_omap15xx():	True for OMAP1510 and OMAP5910
+ * cpu_is_omap16xx():	True for OMAP1610, OMAP5912 and OMAP1710
+ * cpu_is_omap24xx():	True for OMAP2420
  */
-#define GET_OMAP_TYPE	((system_rev >> 24) & 0xff)
 #define GET_OMAP_CLASS	(system_rev & 0xff)
 
-#define IS_OMAP_TYPE(type, id)				\
-static inline int is_omap ##type (void)			\
-{							\
-	return (GET_OMAP_TYPE == (id)) ? 1 : 0;		\
-}
-
 #define IS_OMAP_CLASS(class, id)			\
 static inline int is_omap ##class (void)		\
 {							\
 	return (GET_OMAP_CLASS == (id)) ? 1 : 0;	\
 }
 
-IS_OMAP_TYPE(730, 0x07)
-IS_OMAP_TYPE(1510, 0x15)
-IS_OMAP_TYPE(1610, 0x16)
-IS_OMAP_TYPE(5912, 0x16)
-IS_OMAP_TYPE(1710, 0x17)
-IS_OMAP_TYPE(2420, 0x24)
-
 IS_OMAP_CLASS(7xx, 0x07)
 IS_OMAP_CLASS(15xx, 0x15)
 IS_OMAP_CLASS(16xx, 0x16)
 IS_OMAP_CLASS(24xx, 0x24)
 
-/*
- * Macros to group OMAP types into cpu classes.
- * These can be used in most places.
- * cpu_is_omap15xx():	True for 1510 and 5910
- * cpu_is_omap16xx():	True for 1610, 5912 and 1710
- */
-#if defined(MULTI_OMAP)
-# define cpu_is_omap7xx()		is_omap7xx()
-# define cpu_is_omap15xx()		is_omap15xx()
-# if !(defined(CONFIG_ARCH_OMAP1510) || defined(CONFIG_ARCH_OMAP730))
-#  define cpu_is_omap16xx()		1
-# else
+#define cpu_is_omap7xx()		0
+#define cpu_is_omap15xx()		0
+#define cpu_is_omap16xx()		0
+#define cpu_is_omap24xx()		0
+
+#if defined(MULTI_OMAP1)
+# if defined(CONFIG_ARCH_OMAP730)
+#  undef  cpu_is_omap7xx
+#  define cpu_is_omap7xx()		is_omap7xx()
+# endif
+# if defined(CONFIG_ARCH_OMAP1510)
+#  undef  cpu_is_omap15xx
+#  define cpu_is_omap15xx()		is_omap15xx()
+# endif
+# if defined(CONFIG_ARCH_OMAP16XX)
+#  undef  cpu_is_omap16xx
 #  define cpu_is_omap16xx()		is_omap16xx()
 # endif
 #else
 # if defined(CONFIG_ARCH_OMAP730)
+#  undef  cpu_is_omap7xx
 #  define cpu_is_omap7xx()		1
-# else
-#  define cpu_is_omap7xx()		0
 # endif
 # if defined(CONFIG_ARCH_OMAP1510)
+#  undef  cpu_is_omap15xx
 #  define cpu_is_omap15xx()		1
-# else
-#  define cpu_is_omap15xx()		0
 # endif
 # if defined(CONFIG_ARCH_OMAP16XX)
+#  undef  cpu_is_omap16xx
 #  define cpu_is_omap16xx()		1
-# else
-#  define cpu_is_omap16xx()		0
+# endif
+# if defined(CONFIG_ARCH_OMAP24XX)
+#  undef  cpu_is_omap24xx
+#  define cpu_is_omap24xx()		1
 # endif
 #endif
 
-#if defined(MULTI_OMAP)
-# define cpu_is_omap730()		is_omap730()
-# define cpu_is_omap1510()		is_omap1510()
-# define cpu_is_omap1610()		is_omap1610()
-# define cpu_is_omap5912()		is_omap5912()
-# define cpu_is_omap1710()		is_omap1710()
+/*
+ * Macros to detect individual cpu types.
+ * These are only rarely needed.
+ * cpu_is_omap730():	True for OMAP730
+ * cpu_is_omap1510():	True for OMAP1510
+ * cpu_is_omap1610():	True for OMAP1610
+ * cpu_is_omap1611():	True for OMAP1611
+ * cpu_is_omap5912():	True for OMAP5912
+ * cpu_is_omap1621():	True for OMAP1621
+ * cpu_is_omap1710():	True for OMAP1710
+ * cpu_is_omap2420():	True for OMAP2420
+ */
+#define GET_OMAP_TYPE	((system_rev >> 16) & 0xffff)
+
+#define IS_OMAP_TYPE(type, id)				\
+static inline int is_omap ##type (void)			\
+{							\
+	return (GET_OMAP_TYPE == (id)) ? 1 : 0;		\
+}
+
+IS_OMAP_TYPE(730, 0x0730)
+IS_OMAP_TYPE(1510, 0x1510)
+IS_OMAP_TYPE(1610, 0x1610)
+IS_OMAP_TYPE(1611, 0x1611)
+IS_OMAP_TYPE(5912, 0x1611)
+IS_OMAP_TYPE(1621, 0x1621)
+IS_OMAP_TYPE(1710, 0x1710)
+IS_OMAP_TYPE(2420, 0x2420)
+
+#define cpu_is_omap730()		0
+#define cpu_is_omap1510()		0
+#define cpu_is_omap1610()		0
+#define cpu_is_omap5912()		0
+#define cpu_is_omap1611()		0
+#define cpu_is_omap1621()		0
+#define cpu_is_omap1710()		0
+#define cpu_is_omap2420()		0
+
+#if defined(MULTI_OMAP1)
+# if defined(CONFIG_ARCH_OMAP730)
+#  undef  cpu_is_omap730
+#  define cpu_is_omap730()		is_omap730()
+# endif
+# if defined(CONFIG_ARCH_OMAP1510)
+#  undef  cpu_is_omap1510
+#  define cpu_is_omap1510()		is_omap1510()
+# endif
 #else
 # if defined(CONFIG_ARCH_OMAP730)
+#  undef  cpu_is_omap730
 #  define cpu_is_omap730()		1
-# else
-#  define cpu_is_omap730()		0
 # endif
 # if defined(CONFIG_ARCH_OMAP1510)
+#  undef  cpu_is_omap1510
 #  define cpu_is_omap1510()		1
-# else
-#  define cpu_is_omap1510()		0
 # endif
-# if defined(CONFIG_ARCH_OMAP16XX)
-#  define cpu_is_omap1610()		1
-# else
-#  define cpu_is_omap1610()		0
-# endif
-# if defined(CONFIG_ARCH_OMAP16XX)
-#  define cpu_is_omap5912()		1
-# else
-#  define cpu_is_omap5912()		0
-# endif
-# if defined(CONFIG_ARCH_OMAP16XX)
+#endif
+
+/*
+ * Whether we have MULTI_OMAP1 or not, we still need to distinguish
+ * between 1611B/5912 and 1710.
+ */
+#if defined(CONFIG_ARCH_OMAP16XX)
+# undef  cpu_is_omap1610
+# undef  cpu_is_omap1611
+# undef  cpu_is_omap5912
+# undef  cpu_is_omap1621
+# undef  cpu_is_omap1710
 # define cpu_is_omap1610()		is_omap1610()
+# define cpu_is_omap1611()		is_omap1611()
 # define cpu_is_omap5912()		is_omap5912()
+# define cpu_is_omap1621()		is_omap1621()
 # define cpu_is_omap1710()		is_omap1710()
-# else
-# define cpu_is_omap1610()		0
-# define cpu_is_omap5912()		0
-# define cpu_is_omap1710()		0
-# endif
-# if defined(CONFIG_ARCH_OMAP2420)
+#endif
+
+#if defined(CONFIG_ARCH_OMAP2420)
+#  undef  cpu_is_omap2420
 #  define cpu_is_omap2420()		1
-# else
-#  define cpu_is_omap2420()		0
-# endif
 #endif
 
 #endif
diff --git a/include/asm-arm/arch-omap/debug-macro.S b/include/asm-arm/arch-omap/debug-macro.S
index 83bb458afd0b..ca4f577f9675 100644
--- a/include/asm-arm/arch-omap/debug-macro.S
+++ b/include/asm-arm/arch-omap/debug-macro.S
@@ -14,6 +14,7 @@
 		.macro	addruart,rx
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
+#ifdef CONFIG_ARCH_OMAP1
 		moveq	\rx, #0xff000000	@ physical base address
 		movne	\rx, #0xfe000000	@ virtual base
 		orr	\rx, \rx, #0x00fb0000
@@ -23,6 +24,18 @@
 #if defined(CONFIG_OMAP_LL_DEBUG_UART2) || defined(CONFIG_OMAP_LL_DEBUG_UART3)
 		orr	\rx, \rx, #0x00000800	@ UART 2 & 3
 #endif
+
+#elif  CONFIG_ARCH_OMAP2
+		moveq	\rx, #0x48000000	@ physical base address
+		movne	\rx, #0xd8000000	@ virtual base
+		orr	\rx, \rx, #0x0006a000
+#ifdef CONFIG_OMAP_LL_DEBUG_UART2
+		add	\rx, \rx, #0x00002000	@ UART 2
+#endif
+#ifdef CONFIG_OMAP_LL_DEBUG_UART3
+		add	\rx, \rx, #0x00004000	@ UART 3
+#endif
+#endif
 		.endm
 
 		.macro	senduart,rd,rx
diff --git a/include/asm-arm/arch-omap/dma.h b/include/asm-arm/arch-omap/dma.h
index ce114ce5af5d..04ebef5c6e95 100644
--- a/include/asm-arm/arch-omap/dma.h
+++ b/include/asm-arm/arch-omap/dma.h
@@ -240,6 +240,7 @@ extern void omap_dma_unlink_lch (int lch_head, int lch_queue);
 
 extern dma_addr_t omap_get_dma_src_pos(int lch);
 extern dma_addr_t omap_get_dma_dst_pos(int lch);
+extern int omap_get_dma_src_addr_counter(int lch);
 extern void omap_clear_dma(int lch);
 extern int omap_dma_running(void);
 
diff --git a/include/asm-arm/arch-omap/dmtimer.h b/include/asm-arm/arch-omap/dmtimer.h
new file mode 100644
index 000000000000..11772c792f3e
--- /dev/null
+++ b/include/asm-arm/arch-omap/dmtimer.h
@@ -0,0 +1,92 @@
+/*
+ * linux/include/asm-arm/arm/arch-omap/dmtimer.h
+ *
+ * OMAP Dual-Mode Timers
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com>
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the  GNU General Public License along
+ * with this program; if not, write  to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_ARCH_TIMER_H
+#define __ASM_ARCH_TIMER_H
+
+#include <linux/list.h>
+
+#define OMAP_TIMER_SRC_ARMXOR		0x00
+#define OMAP_TIMER_SRC_32_KHZ		0x01
+#define OMAP_TIMER_SRC_EXT_CLK		0x02
+
+/* timer control reg bits */
+#define OMAP_TIMER_CTRL_CAPTMODE	(1 << 13)
+#define OMAP_TIMER_CTRL_PT		(1 << 12)
+#define OMAP_TIMER_CTRL_TRG_OVERFLOW	(0x1 << 10)
+#define OMAP_TIMER_CTRL_TRG_OFANDMATCH	(0x2 << 10)
+#define OMAP_TIMER_CTRL_TCM_LOWTOHIGH	(0x1 << 8)
+#define OMAP_TIMER_CTRL_TCM_HIGHTOLOW	(0x2 << 8)
+#define OMAP_TIMER_CTRL_TCM_BOTHEDGES	(0x3 << 8)
+#define OMAP_TIMER_CTRL_SCPWM		(1 << 7)
+#define OMAP_TIMER_CTRL_CE		(1 << 6)	/* compare enable */
+#define OMAP_TIMER_CTRL_PRE		(1 << 5)	/* prescaler enable */
+#define OMAP_TIMER_CTRL_PTV_SHIFT	2		/* how much to shift the prescaler value */
+#define OMAP_TIMER_CTRL_AR		(1 << 1)	/* auto-reload enable */
+#define OMAP_TIMER_CTRL_ST		(1 << 0)	/* start timer */
+
+/* timer interrupt enable bits */
+#define OMAP_TIMER_INT_CAPTURE		(1 << 2)
+#define OMAP_TIMER_INT_OVERFLOW		(1 << 1)
+#define OMAP_TIMER_INT_MATCH		(1 << 0)
+
+
+struct omap_dm_timer {
+	struct list_head timer_list;
+
+	u32 base;
+	unsigned int irq;
+};
+
+u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, int reg);
+void omap_dm_timer_write_reg(struct omap_dm_timer *timer, int reg, u32 value);
+
+struct omap_dm_timer * omap_dm_timer_request(void);
+void omap_dm_timer_free(struct omap_dm_timer *timer);
+void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
+
+void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
+void omap_dm_timer_set_trigger(struct omap_dm_timer *timer, unsigned int value);
+void omap_dm_timer_enable_compare(struct omap_dm_timer *timer);
+void omap_dm_timer_enable_autoreload(struct omap_dm_timer *timer);
+
+void omap_dm_timer_trigger(struct omap_dm_timer *timer);
+void omap_dm_timer_start(struct omap_dm_timer *timer);
+void omap_dm_timer_stop(struct omap_dm_timer *timer);
+
+void omap_dm_timer_set_load(struct omap_dm_timer *timer, unsigned int load);
+void omap_dm_timer_set_match(struct omap_dm_timer *timer, unsigned int match);
+
+unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
+void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
+
+unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer);
+void omap_dm_timer_reset_counter(struct omap_dm_timer *timer);
+
+int omap_dm_timers_active(void);
+
+#endif /* __ASM_ARCH_TIMER_H */
diff --git a/include/asm-arm/arch-omap/dsp.h b/include/asm-arm/arch-omap/dsp.h
new file mode 100644
index 000000000000..57bf4f39ca58
--- /dev/null
+++ b/include/asm-arm/arch-omap/dsp.h
@@ -0,0 +1,244 @@
+/*
+ * linux/include/asm-arm/arch-omap/dsp.h
+ *
+ * Header for OMAP DSP driver
+ *
+ * Copyright (C) 2002-2005 Nokia Corporation
+ *
+ * Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * 2005/06/01:  DSP Gateway version 3.3
+ */
+
+#ifndef ASM_ARCH_DSP_H
+#define ASM_ARCH_DSP_H
+
+
+/*
+ * for /dev/dspctl/ctl
+ */
+#define OMAP_DSP_IOCTL_RESET			1
+#define OMAP_DSP_IOCTL_RUN			2
+#define OMAP_DSP_IOCTL_SETRSTVECT		3
+#define OMAP_DSP_IOCTL_CPU_IDLE			4
+#define OMAP_DSP_IOCTL_MPUI_WORDSWAP_ON		5
+#define OMAP_DSP_IOCTL_MPUI_WORDSWAP_OFF	6
+#define OMAP_DSP_IOCTL_MPUI_BYTESWAP_ON		7
+#define OMAP_DSP_IOCTL_MPUI_BYTESWAP_OFF	8
+#define OMAP_DSP_IOCTL_GBL_IDLE			9
+#define OMAP_DSP_IOCTL_DSPCFG			10
+#define OMAP_DSP_IOCTL_DSPUNCFG			11
+#define OMAP_DSP_IOCTL_TASKCNT			12
+#define OMAP_DSP_IOCTL_POLL			13
+#define OMAP_DSP_IOCTL_REGMEMR			40
+#define OMAP_DSP_IOCTL_REGMEMW			41
+#define OMAP_DSP_IOCTL_REGIOR			42
+#define OMAP_DSP_IOCTL_REGIOW			43
+#define OMAP_DSP_IOCTL_GETVAR			44
+#define OMAP_DSP_IOCTL_SETVAR			45
+#define OMAP_DSP_IOCTL_RUNLEVEL			50
+#define OMAP_DSP_IOCTL_SUSPEND			51
+#define OMAP_DSP_IOCTL_RESUME			52
+#define OMAP_DSP_IOCTL_FBEN			53
+#define OMAP_DSP_IOCTL_FBDIS			54
+#define OMAP_DSP_IOCTL_MBSEND			99
+
+/*
+ * for taskdev
+ * (ioctls below should be >= 0x10000)
+ */
+#define OMAP_DSP_TASK_IOCTL_BFLSH	0x10000
+#define OMAP_DSP_TASK_IOCTL_SETBSZ	0x10001
+#define OMAP_DSP_TASK_IOCTL_LOCK	0x10002
+#define OMAP_DSP_TASK_IOCTL_UNLOCK	0x10003
+#define OMAP_DSP_TASK_IOCTL_GETNAME	0x10004
+
+/*
+ * for /dev/dspctl/mem
+ */
+#define OMAP_DSP_MEM_IOCTL_EXMAP	1
+#define OMAP_DSP_MEM_IOCTL_EXUNMAP	2
+#define OMAP_DSP_MEM_IOCTL_EXMAP_FLUSH	3
+#define OMAP_DSP_MEM_IOCTL_FBEXPORT	5
+#define OMAP_DSP_MEM_IOCTL_MMUITACK	7
+#define OMAP_DSP_MEM_IOCTL_MMUINIT	9
+#define OMAP_DSP_MEM_IOCTL_KMEM_RESERVE	11
+#define OMAP_DSP_MEM_IOCTL_KMEM_RELEASE	12
+
+struct omap_dsp_mapinfo {
+	unsigned long dspadr;
+	unsigned long size;
+};
+
+/*
+ * for /dev/dspctl/twch
+ */
+#define OMAP_DSP_TWCH_IOCTL_MKDEV	1
+#define OMAP_DSP_TWCH_IOCTL_RMDEV	2
+#define OMAP_DSP_TWCH_IOCTL_TADD	11
+#define OMAP_DSP_TWCH_IOCTL_TDEL	12
+#define OMAP_DSP_TWCH_IOCTL_TKILL	13
+
+#define OMAP_DSP_DEVSTATE_NOTASK	0x00000001
+#define OMAP_DSP_DEVSTATE_ATTACHED	0x00000002
+#define OMAP_DSP_DEVSTATE_GARBAGE	0x00000004
+#define OMAP_DSP_DEVSTATE_INVALID	0x00000008
+#define OMAP_DSP_DEVSTATE_ADDREQ	0x00000100
+#define OMAP_DSP_DEVSTATE_DELREQ	0x00000200
+#define OMAP_DSP_DEVSTATE_ADDFAIL	0x00001000
+#define OMAP_DSP_DEVSTATE_ADDING	0x00010000
+#define OMAP_DSP_DEVSTATE_DELING	0x00020000
+#define OMAP_DSP_DEVSTATE_KILLING	0x00040000
+#define OMAP_DSP_DEVSTATE_STATE_MASK	0x7fffffff
+#define OMAP_DSP_DEVSTATE_STALE		0x80000000
+
+struct omap_dsp_taddinfo {
+	unsigned char minor;
+	unsigned long taskadr;
+};
+#define OMAP_DSP_TADD_ABORTADR	0xffffffff
+
+
+/*
+ * error cause definition (for error detection device)
+ */
+#define OMAP_DSP_ERRDT_WDT	0x00000001
+#define OMAP_DSP_ERRDT_MMU	0x00000002
+
+
+/*
+ * mailbox protocol definitions
+ */
+
+struct omap_dsp_mailbox_cmd {
+	unsigned short cmd;
+	unsigned short data;
+};
+
+struct omap_dsp_reginfo {
+	unsigned short adr;
+	unsigned short val;
+};
+
+struct omap_dsp_varinfo {
+	unsigned char varid;
+	unsigned short val[0];
+};
+
+#define OMAP_DSP_MBPROT_REVISION	0x0019
+
+#define OMAP_DSP_MBCMD_WDSND	0x10
+#define OMAP_DSP_MBCMD_WDREQ	0x11
+#define OMAP_DSP_MBCMD_BKSND	0x20
+#define OMAP_DSP_MBCMD_BKREQ	0x21
+#define OMAP_DSP_MBCMD_BKYLD	0x23
+#define OMAP_DSP_MBCMD_BKSNDP	0x24
+#define OMAP_DSP_MBCMD_BKREQP	0x25
+#define OMAP_DSP_MBCMD_TCTL	0x30
+#define OMAP_DSP_MBCMD_TCTLDATA	0x31
+#define OMAP_DSP_MBCMD_POLL	0x32
+#define OMAP_DSP_MBCMD_WDT	0x50	/* v3.3: obsolete */
+#define OMAP_DSP_MBCMD_RUNLEVEL	0x51
+#define OMAP_DSP_MBCMD_PM	0x52
+#define OMAP_DSP_MBCMD_SUSPEND	0x53
+#define OMAP_DSP_MBCMD_KFUNC	0x54
+#define OMAP_DSP_MBCMD_TCFG	0x60
+#define OMAP_DSP_MBCMD_TADD	0x62
+#define OMAP_DSP_MBCMD_TDEL	0x63
+#define OMAP_DSP_MBCMD_TSTOP	0x65
+#define OMAP_DSP_MBCMD_DSPCFG	0x70
+#define OMAP_DSP_MBCMD_REGRW	0x72
+#define OMAP_DSP_MBCMD_GETVAR	0x74
+#define OMAP_DSP_MBCMD_SETVAR	0x75
+#define OMAP_DSP_MBCMD_ERR	0x78
+#define OMAP_DSP_MBCMD_DBG	0x79
+
+#define OMAP_DSP_MBCMD_TCTL_TINIT	0x0000
+#define OMAP_DSP_MBCMD_TCTL_TEN		0x0001
+#define OMAP_DSP_MBCMD_TCTL_TDIS	0x0002
+#define OMAP_DSP_MBCMD_TCTL_TCLR	0x0003
+#define OMAP_DSP_MBCMD_TCTL_TCLR_FORCE	0x0004
+
+#define OMAP_DSP_MBCMD_RUNLEVEL_USER		0x01
+#define OMAP_DSP_MBCMD_RUNLEVEL_SUPER		0x0e
+#define OMAP_DSP_MBCMD_RUNLEVEL_RECOVERY	0x10
+
+#define OMAP_DSP_MBCMD_PM_DISABLE	0x00
+#define OMAP_DSP_MBCMD_PM_ENABLE	0x01
+
+#define OMAP_DSP_MBCMD_KFUNC_FBCTL	0x00
+
+#define OMAP_DSP_MBCMD_FBCTL_ENABLE	0x0002
+#define OMAP_DSP_MBCMD_FBCTL_DISABLE	0x0003
+
+#define OMAP_DSP_MBCMD_TDEL_SAFE	0x0000
+#define OMAP_DSP_MBCMD_TDEL_KILL	0x0001
+
+#define OMAP_DSP_MBCMD_DSPCFG_REQ	0x00
+#define OMAP_DSP_MBCMD_DSPCFG_SYSADRH	0x28
+#define OMAP_DSP_MBCMD_DSPCFG_SYSADRL	0x29
+#define OMAP_DSP_MBCMD_DSPCFG_PROTREV	0x70
+#define OMAP_DSP_MBCMD_DSPCFG_ABORT	0x78
+#define OMAP_DSP_MBCMD_DSPCFG_LAST	0x80
+
+#define OMAP_DSP_MBCMD_REGRW_MEMR	0x00
+#define OMAP_DSP_MBCMD_REGRW_MEMW	0x01
+#define OMAP_DSP_MBCMD_REGRW_IOR	0x02
+#define OMAP_DSP_MBCMD_REGRW_IOW	0x03
+#define OMAP_DSP_MBCMD_REGRW_DATA	0x04
+
+#define OMAP_DSP_MBCMD_VARID_ICRMASK	0x00
+#define OMAP_DSP_MBCMD_VARID_LOADINFO	0x01
+
+#define OMAP_DSP_TTYP_ARCV	0x0001
+#define OMAP_DSP_TTYP_ASND	0x0002
+#define OMAP_DSP_TTYP_BKMD	0x0004
+#define OMAP_DSP_TTYP_BKDM	0x0008
+#define OMAP_DSP_TTYP_PVMD	0x0010
+#define OMAP_DSP_TTYP_PVDM	0x0020
+
+#define OMAP_DSP_EID_BADTID	0x10
+#define OMAP_DSP_EID_BADTCN	0x11
+#define OMAP_DSP_EID_BADBID	0x20
+#define OMAP_DSP_EID_BADCNT	0x21
+#define OMAP_DSP_EID_NOTLOCKED	0x22
+#define OMAP_DSP_EID_STVBUF	0x23
+#define OMAP_DSP_EID_BADADR	0x24
+#define OMAP_DSP_EID_BADTCTL	0x30
+#define OMAP_DSP_EID_BADPARAM	0x50
+#define OMAP_DSP_EID_FATAL	0x58
+#define OMAP_DSP_EID_NOMEM	0xc0
+#define OMAP_DSP_EID_NORES	0xc1
+#define OMAP_DSP_EID_IPBFULL	0xc2
+#define OMAP_DSP_EID_WDT	0xd0
+#define OMAP_DSP_EID_TASKNOTRDY	0xe0
+#define OMAP_DSP_EID_TASKBSY	0xe1
+#define OMAP_DSP_EID_TASKERR	0xef
+#define OMAP_DSP_EID_BADCFGTYP	0xf0
+#define OMAP_DSP_EID_DEBUG	0xf8
+#define OMAP_DSP_EID_BADSEQ	0xfe
+#define OMAP_DSP_EID_BADCMD	0xff
+
+#define OMAP_DSP_TNM_LEN	16
+
+#define OMAP_DSP_TID_FREE	0xff
+#define OMAP_DSP_TID_ANON	0xfe
+
+#define OMAP_DSP_BID_NULL	0xffff
+#define OMAP_DSP_BID_PVT	0xfffe
+
+#endif /* ASM_ARCH_DSP_H */
diff --git a/include/asm-arm/arch-omap/dsp_common.h b/include/asm-arm/arch-omap/dsp_common.h
new file mode 100644
index 000000000000..4fcce6944056
--- /dev/null
+++ b/include/asm-arm/arch-omap/dsp_common.h
@@ -0,0 +1,37 @@
+/*
+ * linux/include/asm-arm/arch-omap/dsp_common.h
+ *
+ * Header for OMAP DSP subsystem control
+ *
+ * Copyright (C) 2004,2005 Nokia Corporation
+ *
+ * Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * 2005/06/03:  DSP Gateway version 3.3
+ */
+
+#ifndef ASM_ARCH_DSP_COMMON_H
+#define ASM_ARCH_DSP_COMMON_H
+
+void omap_dsp_pm_suspend(void);
+void omap_dsp_pm_resume(void);
+void omap_dsp_request_mpui(void);
+void omap_dsp_release_mpui(void);
+int omap_dsp_request_mem(void);
+int omap_dsp_release_mem(void);
+
+#endif /* ASM_ARCH_DSP_COMMON_H */
diff --git a/include/asm-arm/arch-omap/entry-macro.S b/include/asm-arm/arch-omap/entry-macro.S
index 57b126889b98..0d29b9c56a95 100644
--- a/include/asm-arm/arch-omap/entry-macro.S
+++ b/include/asm-arm/arch-omap/entry-macro.S
@@ -8,6 +8,8 @@
  * warranty of any kind, whether express or implied.
  */
 
+#if defined(CONFIG_ARCH_OMAP1)
+
  		.macro	disable_fiq
 		.endm
 
@@ -30,3 +32,29 @@
 1510:
 		.endm
 
+#elif defined(CONFIG_ARCH_OMAP24XX)
+
+#include <asm/arch/omap24xx.h>
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\base, =VA_IC_BASE
+		ldr	\irqnr, [\base, #0x98] /* IRQ pending reg 1 */
+		cmp	\irqnr, #0x0
+		bne	2222f
+		ldr	\irqnr, [\base, #0xb8] /* IRQ pending reg 2 */
+		cmp	\irqnr, #0x0
+		bne	2222f
+		ldr	\irqnr, [\base, #0xd8] /* IRQ pending reg 3 */
+		cmp	\irqnr, #0x0
+2222:
+		ldrne	\irqnr, [\base, #IRQ_SIR_IRQ]
+
+		.endm
+
+		.macro	irq_prio_table
+		.endm
+
+#endif
diff --git a/include/asm-arm/arch-omap/gpio.h b/include/asm-arm/arch-omap/gpio.h
index fad2fc93ee70..74cb2b93b700 100644
--- a/include/asm-arm/arch-omap/gpio.h
+++ b/include/asm-arm/arch-omap/gpio.h
@@ -3,7 +3,7 @@
  *
  * OMAP GPIO handling defines and functions
  *
- * Copyright (C) 2003 Nokia Corporation
+ * Copyright (C) 2003-2005 Nokia Corporation
  *
  * Written by Juha Yrjölä <juha.yrjola@nokia.com>
  *
@@ -30,7 +30,23 @@
 #include <asm/arch/irqs.h>
 #include <asm/io.h>
 
-#define OMAP_MPUIO_BASE			0xfffb5000
+#define OMAP_MPUIO_BASE			(void __iomem *)0xfffb5000
+
+#ifdef CONFIG_ARCH_OMAP730
+#define OMAP_MPUIO_INPUT_LATCH		0x00
+#define OMAP_MPUIO_OUTPUT		0x02
+#define OMAP_MPUIO_IO_CNTL		0x04
+#define OMAP_MPUIO_KBR_LATCH		0x08
+#define OMAP_MPUIO_KBC			0x0a
+#define OMAP_MPUIO_GPIO_EVENT_MODE	0x0c
+#define OMAP_MPUIO_GPIO_INT_EDGE	0x0e
+#define OMAP_MPUIO_KBD_INT		0x10
+#define OMAP_MPUIO_GPIO_INT		0x12
+#define OMAP_MPUIO_KBD_MASKIT		0x14
+#define OMAP_MPUIO_GPIO_MASKIT		0x16
+#define OMAP_MPUIO_GPIO_DEBOUNCING	0x18
+#define OMAP_MPUIO_LATCH		0x1a
+#else
 #define OMAP_MPUIO_INPUT_LATCH		0x00
 #define OMAP_MPUIO_OUTPUT		0x04
 #define OMAP_MPUIO_IO_CNTL		0x08
@@ -44,6 +60,7 @@
 #define OMAP_MPUIO_GPIO_MASKIT		0x2c
 #define OMAP_MPUIO_GPIO_DEBOUNCING	0x30
 #define OMAP_MPUIO_LATCH		0x34
+#endif
 
 #define OMAP_MPUIO(nr)		(OMAP_MAX_GPIO_LINES + (nr))
 #define OMAP_GPIO_IS_MPUIO(nr)	((nr) >= OMAP_MAX_GPIO_LINES)
@@ -52,18 +69,11 @@
 				 IH_MPUIO_BASE + ((nr) & 0x0f) : \
 				 IH_GPIO_BASE + ((nr) & 0x3f))
 
-/* For EDGECTRL */
-#define OMAP_GPIO_NO_EDGE	  0x00
-#define OMAP_GPIO_FALLING_EDGE	  0x01
-#define OMAP_GPIO_RISING_EDGE	  0x02
-#define OMAP_GPIO_BOTH_EDGES	  0x03
-
 extern int omap_gpio_init(void);	/* Call from board init only */
 extern int omap_request_gpio(int gpio);
 extern void omap_free_gpio(int gpio);
 extern void omap_set_gpio_direction(int gpio, int is_input);
 extern void omap_set_gpio_dataout(int gpio, int enable);
 extern int omap_get_gpio_datain(int gpio);
-extern void omap_set_gpio_edge_ctrl(int gpio, int edge);
 
 #endif
diff --git a/include/asm-arm/arch-omap/hardware.h b/include/asm-arm/arch-omap/hardware.h
index 48258c7f6541..60201e1dd6ad 100644
--- a/include/asm-arm/arch-omap/hardware.h
+++ b/include/asm-arm/arch-omap/hardware.h
@@ -43,6 +43,7 @@
 #include <asm/arch/cpu.h>
 #endif
 #include <asm/arch/io.h>
+#include <asm/arch/serial.h>
 
 /*
  * ---------------------------------------------------------------------------
@@ -89,11 +90,12 @@
 /* DPLL control registers */
 #define DPLL_CTL		(0xfffecf00)
 
-/* DSP clock control */
+/* DSP clock control. Must use __raw_readw() and __raw_writew() with these */
 #define DSP_CONFIG_REG_BASE     (0xe1008000)
 #define DSP_CKCTL		(DSP_CONFIG_REG_BASE + 0x0)
 #define DSP_IDLECT1		(DSP_CONFIG_REG_BASE + 0x4)
 #define DSP_IDLECT2		(DSP_CONFIG_REG_BASE + 0x8)
+#define DSP_RSTCT2		(DSP_CONFIG_REG_BASE + 0x14)
 
 /*
  * ---------------------------------------------------------------------------
@@ -142,6 +144,13 @@
  * Interrupts
  * ---------------------------------------------------------------------------
  */
+#ifdef CONFIG_ARCH_OMAP1
+
+/*
+ * XXX: These probably want to be moved to arch/arm/mach-omap/omap1/irq.c
+ * or something similar.. -- PFM.
+ */
+
 #define OMAP_IH1_BASE		0xfffecb00
 #define OMAP_IH2_BASE		0xfffe0000
 
@@ -170,6 +179,8 @@
 #define IRQ_ILR0_REG_OFFSET	0x1c
 #define IRQ_GMR_REG_OFFSET	0xa0
 
+#endif
+
 /*
  * ----------------------------------------------------------------------------
  * System control registers
@@ -260,32 +271,17 @@
 
 /*
  * ---------------------------------------------------------------------------
- * Serial ports
- * ---------------------------------------------------------------------------
- */
-#define OMAP_UART1_BASE		(unsigned char *)0xfffb0000
-#define OMAP_UART2_BASE		(unsigned char *)0xfffb0800
-#define OMAP_UART3_BASE		(unsigned char *)0xfffb9800
-#define OMAP_MAX_NR_PORTS	3
-#define OMAP1510_BASE_BAUD	(12000000/16)
-#define OMAP16XX_BASE_BAUD	(48000000/16)
-
-#define is_omap_port(p)	({int __ret = 0;			\
-			if (p == IO_ADDRESS(OMAP_UART1_BASE) ||	\
-			    p == IO_ADDRESS(OMAP_UART2_BASE) ||	\
-			    p == IO_ADDRESS(OMAP_UART3_BASE))	\
-				__ret = 1;			\
-			__ret;					\
-			})
-
-/*
- * ---------------------------------------------------------------------------
  * Processor specific defines
  * ---------------------------------------------------------------------------
  */
 
 #include "omap730.h"
 #include "omap1510.h"
+
+#ifdef CONFIG_ARCH_OMAP24XX
+#include "omap24xx.h"
+#endif
+
 #include "omap16xx.h"
 
 /*
@@ -312,7 +308,6 @@
 
 #ifdef CONFIG_MACH_OMAP_H4
 #include "board-h4.h"
-#error "Support for H4 board not yet implemented."
 #endif
 
 #ifdef CONFIG_MACH_OMAP_OSK
diff --git a/include/asm-arm/arch-omap/io.h b/include/asm-arm/arch-omap/io.h
index 1c8c9fcc766e..11fbf629bf75 100644
--- a/include/asm-arm/arch-omap/io.h
+++ b/include/asm-arm/arch-omap/io.h
@@ -49,16 +49,24 @@
  * I/O mapping
  * ----------------------------------------------------------------------------
  */
-#define IO_PHYS			0xFFFB0000
-#define IO_OFFSET		0x01000000	/* Virtual IO = 0xfefb0000 */
-#define IO_VIRT			(IO_PHYS - IO_OFFSET)
-#define IO_SIZE			0x40000
-#define IO_ADDRESS(x)		((x) - IO_OFFSET)
 
-#define PCIO_BASE		0
+#if defined(CONFIG_ARCH_OMAP1)
+#define IO_PHYS		0xFFFB0000
+#define IO_OFFSET      -0x01000000	/* Virtual IO = 0xfefb0000 */
+#define IO_SIZE		0x40000
 
-#define io_p2v(x)               ((x) - IO_OFFSET)
-#define io_v2p(x)               ((x) + IO_OFFSET)
+#elif defined(CONFIG_ARCH_OMAP2)
+#define IO_PHYS		0x48000000	/* L4 peripherals; other stuff has to be mapped *
+					 * manually. */
+#define IO_OFFSET	0x90000000	/* Virtual IO = 0xd8000000 */
+#define IO_SIZE		0x08000000
+#endif
+
+#define IO_VIRT		(IO_PHYS + IO_OFFSET)
+#define IO_ADDRESS(x)	((x) + IO_OFFSET)
+#define PCIO_BASE	0
+#define io_p2v(x)	((x) + IO_OFFSET)
+#define io_v2p(x)	((x) - IO_OFFSET)
 
 #ifndef __ASSEMBLER__
 
@@ -96,6 +104,8 @@ typedef struct { volatile u32 offset[4096]; } __regbase32;
 					->offset[((vaddr)&4095)>>2]
 #define __REG32(paddr)		__REGV32(io_p2v(paddr))
 
+extern void omap_map_common_io(void);
+
 #else
 
 #define __REG8(paddr)		io_p2v(paddr)
diff --git a/include/asm-arm/arch-omap/irqs.h b/include/asm-arm/arch-omap/irqs.h
index 0d05a7c957d1..74e108ccac16 100644
--- a/include/asm-arm/arch-omap/irqs.h
+++ b/include/asm-arm/arch-omap/irqs.h
@@ -135,7 +135,6 @@
 /*
  * OMAP-1510 specific IRQ numbers for interrupt handler 2
  */
-#define INT_1510_OS_32kHz_TIMER (22 + IH2_BASE)
 #define INT_1510_COM_SPI_RO	(31 + IH2_BASE)
 
 /*
@@ -232,6 +231,11 @@
 #define INT_730_DMA_CH15	(62 + IH2_BASE)
 #define INT_730_NAND		(63 + IH2_BASE)
 
+#define INT_24XX_GPIO_BANK1	29
+#define INT_24XX_GPIO_BANK2	30
+#define INT_24XX_GPIO_BANK3	31
+#define INT_24XX_GPIO_BANK4	32
+
 /* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730) and
  * 16 MPUIO lines */
 #define OMAP_MAX_GPIO_LINES	192
diff --git a/include/asm-arm/arch-omap/memory.h b/include/asm-arm/arch-omap/memory.h
index f6b57dd846a3..84f81e315a25 100644
--- a/include/asm-arm/arch-omap/memory.h
+++ b/include/asm-arm/arch-omap/memory.h
@@ -36,12 +36,11 @@
 /*
  * Physical DRAM offset.
  */
+#if defined(CONFIG_ARCH_OMAP1)
 #define PHYS_OFFSET		(0x10000000UL)
-
-/*
- * OMAP-1510 Local Bus address offset
- */
-#define OMAP1510_LB_OFFSET	(0x30000000UL)
+#elif defined(CONFIG_ARCH_OMAP2)
+#define PHYS_OFFSET		(0x80000000UL)
+#endif
 
 /*
  * Conversion between SDRAM and fake PCI bus, used by USB
@@ -64,6 +63,11 @@
  */
 #ifdef CONFIG_ARCH_OMAP1510
 
+/*
+ * OMAP-1510 Local Bus address offset
+ */
+#define OMAP1510_LB_OFFSET	(0x30000000UL)
+
 #define virt_to_lbus(x)		((x) - PAGE_OFFSET + OMAP1510_LB_OFFSET)
 #define lbus_to_virt(x)		((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET)
 #define is_lbus_device(dev)	(cpu_is_omap1510() && dev && (strncmp(dev->bus_id, "ohci", 4) == 0))
diff --git a/include/asm-arm/arch-omap/mtd-xip.h b/include/asm-arm/arch-omap/mtd-xip.h
new file mode 100644
index 000000000000..a73a28571fee
--- /dev/null
+++ b/include/asm-arm/arch-omap/mtd-xip.h
@@ -0,0 +1,61 @@
+/*
+ * MTD primitives for XIP support. Architecture specific functions.
+ *
+ * Do not include this file directly. It's included from linux/mtd/xip.h
+ *
+ * Author: Vladimir Barinov <vbarinov@ru.mvista.com>
+ *
+ * (c) 2005 MontaVista Software, Inc.  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.
+ */
+
+#ifndef __ARCH_OMAP_MTD_XIP_H__
+#define __ARCH_OMAP_MTD_XIP_H__
+
+#include <asm/hardware.h>
+#define OMAP_MPU_TIMER_BASE	(0xfffec500)
+#define OMAP_MPU_TIMER_OFFSET	0x100
+
+typedef struct {
+	u32 cntl;			/* CNTL_TIMER, R/W */
+	u32 load_tim;			/* LOAD_TIM,   W */
+	u32 read_tim;			/* READ_TIM,   R */
+} xip_omap_mpu_timer_regs_t;
+
+#define xip_omap_mpu_timer_base(n)					\
+((volatile xip_omap_mpu_timer_regs_t*)IO_ADDRESS(OMAP_MPU_TIMER_BASE +	\
+	(n)*OMAP_MPU_TIMER_OFFSET))
+
+static inline unsigned long xip_omap_mpu_timer_read(int nr)
+{
+	volatile xip_omap_mpu_timer_regs_t* timer = xip_omap_mpu_timer_base(nr);
+	return timer->read_tim;
+}
+
+#define xip_irqpending()	\
+	(omap_readl(OMAP_IH1_ITR) & ~omap_readl(OMAP_IH1_MIR))
+#define xip_currtime()		(~xip_omap_mpu_timer_read(0))
+
+/*
+ * It's permitted to do approxmation for xip_elapsed_since macro
+ * (see linux/mtd/xip.h)
+ */
+
+#ifdef CONFIG_MACH_OMAP_PERSEUS2
+#define xip_elapsed_since(x)	(signed)((~xip_omap_mpu_timer_read(0) - (x)) / 7)
+#else
+#define xip_elapsed_since(x)	(signed)((~xip_omap_mpu_timer_read(0) - (x)) / 6)
+#endif
+
+/*
+ * xip_cpu_idle() is used when waiting for a delay equal or larger than
+ * the system timer tick period.  This should put the CPU into idle mode
+ * to save power and to be woken up only when some interrupts are pending.
+ * As above, this should not rely upon standard kernel code.
+ */
+
+#define xip_cpu_idle()  asm volatile ("mcr p15, 0, %0, c7, c0, 4" :: "r" (1))
+
+#endif /* __ARCH_OMAP_MTD_XIP_H__ */
diff --git a/include/asm-arm/arch-omap/mux.h b/include/asm-arm/arch-omap/mux.h
index 5bd3f0097fc6..1b1ad4105349 100644
--- a/include/asm-arm/arch-omap/mux.h
+++ b/include/asm-arm/arch-omap/mux.h
@@ -185,6 +185,7 @@ typedef enum {
 
 	/* MPUIO */
 	MPUIO2,
+	N15_1610_MPUIO2,
 	MPUIO4,
 	MPUIO5,
 	T20_1610_MPUIO5,
@@ -210,6 +211,7 @@ typedef enum {
 
 	/* Misc ballouts */
 	BALLOUT_V8_ARMIO3,
+	N20_HDQ,
 
 	/* OMAP-1610 MMC2 */
 	W8_1610_MMC2_DAT0,
@@ -235,6 +237,7 @@ typedef enum {
 	P20_1610_GPIO4,
 	V9_1610_GPIO7,
 	W8_1610_GPIO9,
+	N20_1610_GPIO11,
 	N19_1610_GPIO13,
 	P10_1610_GPIO22,
 	V5_1610_GPIO24,
@@ -250,7 +253,7 @@ typedef enum {
 	U18_1610_UWIRE_SDI,
 	W21_1610_UWIRE_SDO,
 	N14_1610_UWIRE_CS0,
-	P15_1610_UWIRE_CS0,
+	P15_1610_UWIRE_CS3,
 	N15_1610_UWIRE_CS1,
 
 	/* OMAP-1610 Flash */
@@ -411,7 +414,8 @@ MUX_CFG("N21_1710_GPIO14",       6,    9,    0,   1,   1,   1,    1,     1,  1)
 MUX_CFG("W15_1710_GPIO40",       9,   27,    7,   2,   5,   1,    2,     1,  1)
 
 /* MPUIO */
-MUX_CFG("MPUIO2",		 7,   18,    0,	  1,   1,   1,	 NA,	 0,  1)
+MUX_CFG("MPUIO2",		 7,   18,    0,	  1,  14,   1,	 NA,	 0,  1)
+MUX_CFG("N15_1610_MPUIO2",	 7,   18,    0,	  1,  14,   1,	  1,	 0,  1)
 MUX_CFG("MPUIO4",		 7,   15,    0,	  1,  13,   1,	 NA,	 0,  1)
 MUX_CFG("MPUIO5",		 7,   12,    0,	  1,  12,   1,	 NA,	 0,  1)
 
@@ -438,6 +442,7 @@ MUX_CFG("MCBSP3_CLKX",		 9,    3,    1,	  1,  29,   0,	 NA,	 0,  1)
 
 /* Misc ballouts */
 MUX_CFG("BALLOUT_V8_ARMIO3",	 B,   18,    0,	  2,  25,   1,	 NA,	 0,  1)
+MUX_CFG("N20_HDQ",	       6,   18,    1,   1,   4,   0,    1,     4,  0)
 
 /* OMAP-1610 MMC2 */
 MUX_CFG("W8_1610_MMC2_DAT0",	 B,   21,    6,	  2,  23,   1,	  2,	 1,  1)
@@ -463,6 +468,7 @@ MUX_CFG("J18_1610_ETM_D7",	 5,   27,    1,	  0,  19,   0,	  0,	 0,  1)
 MUX_CFG("P20_1610_GPIO4",	 6,   27,    0,	  1,   7,   0,	  1,	 1,  1)
 MUX_CFG("V9_1610_GPIO7",	 B,   12,    1,	  2,  20,   0,	  2,	 1,  1)
 MUX_CFG("W8_1610_GPIO9",	 B,   21,    0,	  2,  23,   0,	  2,	 1,  1)
+MUX_CFG("N20_1610_GPIO11",       6,   18,    0,   1,   4,   0,    1,     1,  1)
 MUX_CFG("N19_1610_GPIO13",	 6,   12,    0,	  1,   2,   0,	  1,	 1,  1)
 MUX_CFG("P10_1610_GPIO22",	 C,    0,    7,	  2,  26,   0,	  2,	 1,  1)
 MUX_CFG("V5_1610_GPIO24",	 B,   15,    7,	  2,  21,   0,	  2,	 1,  1)
diff --git a/include/asm-arm/arch-omap/omap1510.h b/include/asm-arm/arch-omap/omap1510.h
index f491a48ef2e1..f086a3933906 100644
--- a/include/asm-arm/arch-omap/omap1510.h
+++ b/include/asm-arm/arch-omap/omap1510.h
@@ -36,10 +36,6 @@
 
 /* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
 
-#define OMAP1510_SRAM_BASE	0xD0000000
-#define OMAP1510_SRAM_SIZE	(SZ_128K + SZ_64K)
-#define OMAP1510_SRAM_START	0x20000000
-
 #define OMAP1510_DSP_BASE	0xE0000000
 #define OMAP1510_DSP_SIZE	0x28000
 #define OMAP1510_DSP_START	0xE0000000
@@ -48,14 +44,5 @@
 #define OMAP1510_DSPREG_SIZE	SZ_128K
 #define OMAP1510_DSPREG_START	0xE1000000
 
-/*
- * ----------------------------------------------------------------------------
- * Memory used by power management
- * ----------------------------------------------------------------------------
- */
-
-#define OMAP1510_SRAM_IDLE_SUSPEND	(OMAP1510_SRAM_BASE + OMAP1510_SRAM_SIZE - 0x200)
-#define OMAP1510_SRAM_API_SUSPEND	(OMAP1510_SRAM_IDLE_SUSPEND + 0x100)
-
 #endif /*  __ASM_ARCH_OMAP1510_H */
 
diff --git a/include/asm-arm/arch-omap/omap16xx.h b/include/asm-arm/arch-omap/omap16xx.h
index 38a9b95e6a33..f0c7f0fb4dc0 100644
--- a/include/asm-arm/arch-omap/omap16xx.h
+++ b/include/asm-arm/arch-omap/omap16xx.h
@@ -36,11 +36,6 @@
 
 /* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
 
-#define OMAP16XX_SRAM_BASE	0xD0000000
-#define OMAP1610_SRAM_SIZE	(SZ_16K)
-#define OMAP5912_SRAM_SIZE	0x3E800
-#define OMAP16XX_SRAM_START	0x20000000
-
 #define OMAP16XX_DSP_BASE	0xE0000000
 #define OMAP16XX_DSP_SIZE	0x28000
 #define OMAP16XX_DSP_START	0xE0000000
@@ -50,17 +45,6 @@
 #define OMAP16XX_DSPREG_START	0xE1000000
 
 /*
- * ----------------------------------------------------------------------------
- * Memory used by power management
- * ----------------------------------------------------------------------------
- */
-
-#define OMAP1610_SRAM_IDLE_SUSPEND	(OMAP16XX_SRAM_BASE + OMAP1610_SRAM_SIZE - 0x200)
-#define OMAP1610_SRAM_API_SUSPEND	(OMAP1610_SRAM_IDLE_SUSPEND + 0x100)
-#define OMAP5912_SRAM_IDLE_SUSPEND	(OMAP16XX_SRAM_BASE + OMAP5912_SRAM_SIZE - 0x200)
-#define OMAP5912_SRAM_API_SUSPEND	(OMAP5912_SRAM_IDLE_SUSPEND + 0x100)
-
-/*
  * ---------------------------------------------------------------------------
  * Interrupts
  * ---------------------------------------------------------------------------
diff --git a/include/asm-arm/arch-omap/omap24xx.h b/include/asm-arm/arch-omap/omap24xx.h
new file mode 100644
index 000000000000..a9105466a417
--- /dev/null
+++ b/include/asm-arm/arch-omap/omap24xx.h
@@ -0,0 +1,15 @@
+#ifndef __ASM_ARCH_OMAP24XX_H
+#define __ASM_ARCH_OMAP24XX_H
+
+#define OMAP24XX_L4_IO_BASE	0x48000000
+
+/* interrupt controller */
+#define OMAP24XX_IC_BASE	(OMAP24XX_L4_IO_BASE + 0xfe000)
+#define VA_IC_BASE		IO_ADDRESS(OMAP24XX_IC_BASE)
+
+#define OMAP24XX_IVA_INTC_BASE	0x40000000
+
+#define IRQ_SIR_IRQ		0x0040
+
+#endif /* __ASM_ARCH_OMAP24XX_H */
+
diff --git a/include/asm-arm/arch-omap/omap730.h b/include/asm-arm/arch-omap/omap730.h
index 599ab00f5488..755b64c5e9f0 100644
--- a/include/asm-arm/arch-omap/omap730.h
+++ b/include/asm-arm/arch-omap/omap730.h
@@ -36,10 +36,6 @@
 
 /* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
 
-#define OMAP730_SRAM_BASE	0xD0000000
-#define OMAP730_SRAM_SIZE	(SZ_128K + SZ_64K + SZ_8K)
-#define OMAP730_SRAM_START	0x20000000
-
 #define OMAP730_DSP_BASE	0xE0000000
 #define OMAP730_DSP_SIZE	0x50000
 #define OMAP730_DSP_START	0xE0000000
diff --git a/include/asm-arm/arch-omap/pm.h b/include/asm-arm/arch-omap/pm.h
index f209fc0953fb..fbd742d0c499 100644
--- a/include/asm-arm/arch-omap/pm.h
+++ b/include/asm-arm/arch-omap/pm.h
@@ -61,7 +61,10 @@
 #define PER_EN				0x1
 
 #define CPU_SUSPEND_SIZE		200
-#define ULPD_LOW_POWER_EN		0x0001
+#define ULPD_LOW_PWR_EN			0x0001
+#define ULPD_DEEP_SLEEP_TRANSITION_EN	0x0010
+#define ULPD_SETUP_ANALOG_CELL_3_VAL	0
+#define ULPD_POWER_CTRL_REG_VAL		0x0219
 
 #define DSP_IDLE_DELAY			10
 #define DSP_IDLE			0x0040
@@ -86,46 +89,35 @@
 #define OMAP1510_BIG_SLEEP_REQUEST	0x0cc5
 #define OMAP1510_IDLE_LOOP_REQUEST	0x0c00
 #define OMAP1510_IDLE_CLOCK_DOMAINS	0x2
-#define OMAP1510_ULPD_LOW_POWER_REQ	0x0001
 
-#define OMAP1610_DEEP_SLEEP_REQUEST	0x17c7
-#define OMAP1610_BIG_SLEEP_REQUEST	TBD
+/* Both big sleep and deep sleep use same values. Difference is in ULPD. */
+#define OMAP1610_IDLECT1_SLEEP_VAL	0x13c7
+#define OMAP1610_IDLECT2_SLEEP_VAL	0x09c7
+#define OMAP1610_IDLECT3_VAL		0x3f
+#define OMAP1610_IDLECT3_SLEEP_ORMASK	0x2c
+#define OMAP1610_IDLECT3		0xfffece24
 #define OMAP1610_IDLE_LOOP_REQUEST	0x0400
-#define OMAP1610_IDLE_CLOCK_DOMAINS	0x09c7
-#define OMAP1610_ULPD_LOW_POWER_REQ	0x3
-
-#ifndef OMAP1510_SRAM_IDLE_SUSPEND
-#define OMAP1510_SRAM_IDLE_SUSPEND 0
-#endif
-#ifndef OMAP1610_SRAM_IDLE_SUSPEND
-#define OMAP1610_SRAM_IDLE_SUSPEND 0
-#endif
-#ifndef OMAP5912_SRAM_IDLE_SUSPEND
-#define OMAP5912_SRAM_IDLE_SUSPEND 0
-#endif
-
-#ifndef OMAP1510_SRAM_API_SUSPEND
-#define OMAP1510_SRAM_API_SUSPEND 0
-#endif
-#ifndef OMAP1610_SRAM_API_SUSPEND
-#define OMAP1610_SRAM_API_SUSPEND 0
-#endif
-#ifndef OMAP5912_SRAM_API_SUSPEND
-#define OMAP5912_SRAM_API_SUSPEND 0
-#endif
 
 #if     !defined(CONFIG_ARCH_OMAP1510) && \
-	!defined(CONFIG_ARCH_OMAP16XX)
+	!defined(CONFIG_ARCH_OMAP16XX) && \
+	!defined(CONFIG_ARCH_OMAP24XX)
 #error "Power management for this processor not implemented yet"
 #endif
 
 #ifndef __ASSEMBLER__
 extern void omap_pm_idle(void);
 extern void omap_pm_suspend(void);
-extern int omap1510_cpu_suspend(unsigned short, unsigned short);
-extern int omap1610_cpu_suspend(unsigned short, unsigned short);
-extern int omap1510_idle_loop_suspend(void);
-extern int omap1610_idle_loop_suspend(void);
+extern void omap1510_cpu_suspend(unsigned short, unsigned short);
+extern void omap1610_cpu_suspend(unsigned short, unsigned short);
+extern void omap1510_idle_loop_suspend(void);
+extern void omap1610_idle_loop_suspend(void);
+
+#ifdef CONFIG_OMAP_SERIAL_WAKE
+extern void omap_serial_wake_trigger(int enable);
+#else
+#define omap_serial_wake_trigger(x)	{}
+#endif	/* CONFIG_OMAP_SERIAL_WAKE */
+
 extern unsigned int omap1510_cpu_suspend_sz;
 extern unsigned int omap1510_idle_loop_suspend_sz;
 extern unsigned int omap1610_cpu_suspend_sz;
@@ -161,6 +153,7 @@ enum arm_save_state {
 	ARM_SLEEP_SAVE_ARM_CKCTL,
 	ARM_SLEEP_SAVE_ARM_IDLECT1,
 	ARM_SLEEP_SAVE_ARM_IDLECT2,
+	ARM_SLEEP_SAVE_ARM_IDLECT3,
 	ARM_SLEEP_SAVE_ARM_EWUPCT,
 	ARM_SLEEP_SAVE_ARM_RSTCT1,
 	ARM_SLEEP_SAVE_ARM_RSTCT2,
diff --git a/include/asm-arm/arch-omap/serial.h b/include/asm-arm/arch-omap/serial.h
new file mode 100644
index 000000000000..79a5297af9fc
--- /dev/null
+++ b/include/asm-arm/arch-omap/serial.h
@@ -0,0 +1,37 @@
+/*
+ *  linux/include/asm-arm/arch-omap/serial.h
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#if defined(CONFIG_ARCH_OMAP1)
+/* OMAP1 serial ports */
+#define OMAP_UART1_BASE		0xfffb0000
+#define OMAP_UART2_BASE		0xfffb0800
+#define OMAP_UART3_BASE		0xfffb9800
+#elif defined(CONFIG_ARCH_OMAP2)
+/* OMAP2 serial ports */
+#define OMAP_UART1_BASE		0x4806a000
+#define OMAP_UART2_BASE		0x4806c000
+#define OMAP_UART3_BASE		0x4806e000
+#endif
+
+#define OMAP_MAX_NR_PORTS	3
+#define OMAP1510_BASE_BAUD	(12000000/16)
+#define OMAP16XX_BASE_BAUD	(48000000/16)
+
+#define is_omap_port(p)	({int __ret = 0;			\
+			if (p == IO_ADDRESS(OMAP_UART1_BASE) ||	\
+			    p == IO_ADDRESS(OMAP_UART2_BASE) ||	\
+			    p == IO_ADDRESS(OMAP_UART3_BASE))	\
+				__ret = 1;			\
+			__ret;					\
+			})
+
+#endif
diff --git a/include/asm-arm/arch-omap/uncompress.h b/include/asm-arm/arch-omap/uncompress.h
index 3e640aba8c20..3545c86859cc 100644
--- a/include/asm-arm/arch-omap/uncompress.h
+++ b/include/asm-arm/arch-omap/uncompress.h
@@ -20,7 +20,7 @@
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/serial_reg.h>
-#include <asm/arch/hardware.h>
+#include <asm/arch/serial.h>
 
 unsigned int system_rev;
 
@@ -34,8 +34,9 @@ static void
 putstr(const char *s)
 {
 	volatile u8 * uart = 0;
-	int shift;
+	int shift = 2;
 
+#ifdef CONFIG_ARCH_OMAP
 #ifdef	CONFIG_OMAP_LL_DEBUG_UART3
 	uart = (volatile u8 *)(OMAP_UART3_BASE);
 #elif	CONFIG_OMAP_LL_DEBUG_UART2
@@ -44,6 +45,7 @@ putstr(const char *s)
 	uart = (volatile u8 *)(OMAP_UART1_BASE);
 #endif
 
+#ifdef CONFIG_ARCH_OMAP1
 	/* Determine which serial port to use */
 	do {
 		/* MMU is not on, so cpu_is_omapXXXX() won't work here */
@@ -51,14 +53,14 @@ putstr(const char *s)
 
 		if (omap_id == OMAP_ID_730)
 			shift = 0;
-		else
-			shift = 2;
 
 		if (check_port(uart, shift))
 			break;
 		/* Silent boot if no serial ports are enabled. */
 		return;
 	} while (0);
+#endif /* CONFIG_ARCH_OMAP1 */
+#endif
 
 	/*
 	 * Now, xmit each character
diff --git a/include/asm-arm/arch-s3c2410/anubis-cpld.h b/include/asm-arm/arch-s3c2410/anubis-cpld.h
new file mode 100644
index 000000000000..5675b1796b55
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/anubis-cpld.h
@@ -0,0 +1,24 @@
+/* linux/include/asm-arm/arch-s3c2410/anubis-cpld.h
+ *
+ * (c) 2005 Simtec Electronics
+ *	http://www.simtec.co.uk/products/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * ANUBIS - CPLD control constants
+ *
+ * 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.
+ *
+ * Changelog:
+ *
+*/
+
+#ifndef __ASM_ARCH_ANUBISCPLD_H
+#define __ASM_ARCH_ANUBISCPLD_H
+
+/* CTRL2 - NAND WP control, IDE Reset assert/check */
+
+#define ANUBIS_CTRL1_NANDSEL		(0x3)
+
+#endif /* __ASM_ARCH_ANUBISCPLD_H */
diff --git a/include/asm-arm/arch-s3c2410/anubis-irq.h b/include/asm-arm/arch-s3c2410/anubis-irq.h
new file mode 100644
index 000000000000..82f15dbd97e8
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/anubis-irq.h
@@ -0,0 +1,23 @@
+/* linux/include/asm-arm/arch-s3c2410/anubis-irq.h
+ *
+ * (c) 2005 Simtec Electronics
+ *	http://www.simtec.co.uk/products/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ *  ANUBIS - IRQ Number definitions
+ *
+ * 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.
+ *
+ * Changelog:
+ */
+
+#ifndef __ASM_ARCH_ANUBISIRQ_H
+#define __ASM_ARCH_ANUBISIRQ_H
+
+#define IRQ_IDE0       IRQ_EINT2
+#define IRQ_IDE1       IRQ_EINT3
+#define IRQ_ASIX       IRQ_EINT1
+
+#endif /* __ASM_ARCH_ANUBISIRQ_H */
diff --git a/include/asm-arm/arch-s3c2410/anubis-map.h b/include/asm-arm/arch-s3c2410/anubis-map.h
new file mode 100644
index 000000000000..97741d6e506a
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/anubis-map.h
@@ -0,0 +1,46 @@
+/* linux/include/asm-arm/arch-s3c2410/anubis-map.h
+ *
+ * (c) 2005 Simtec Electronics
+ *	http://www.simtec.co.uk/products/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * ANUBIS - Memory map definitions
+ *
+ * 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.
+ *
+ * Changelog:
+*/
+
+/* needs arch/map.h including with this */
+
+#ifndef __ASM_ARCH_ANUBISMAP_H
+#define __ASM_ARCH_ANUBISMAP_H
+
+/* start peripherals off after the S3C2410 */
+
+#define ANUBIS_IOADDR(x)	(S3C2410_ADDR((x) + 0x02000000))
+
+#define ANUBIS_PA_CPLD		(S3C2410_CS1 | (1<<26))
+
+/* we put the CPLD registers next, to get them out of the way */
+
+#define ANUBIS_VA_CTRL1	    ANUBIS_IOADDR(0x00000000)	 /* 0x01300000 */
+#define ANUBIS_PA_CTRL1	    (ANUBIS_PA_CPLD)
+
+#define ANUBIS_VA_CTRL2	    ANUBIS_IOADDR(0x00100000)	 /* 0x01400000 */
+#define ANUBIS_PA_CTRL2	    (ANUBIS_PA_CPLD)
+
+#define ANUBIS_VA_CTRL3	    ANUBIS_IOADDR(0x00200000)	 /* 0x01500000 */
+#define ANUBIS_PA_CTRL3	    (ANUBIS_PA_CPLD)
+
+#define ANUBIS_VA_CTRL4	    ANUBIS_IOADDR(0x00300000)	 /* 0x01600000 */
+#define ANUBIS_PA_CTRL4	    (ANUBIS_PA_CPLD)
+
+#define ANUBIS_IDEPRI	    ANUBIS_IOADDR(0x01000000)
+#define ANUBIS_IDEPRIAUX    ANUBIS_IOADDR(0x01100000)
+#define ANUBIS_IDESEC	    ANUBIS_IOADDR(0x01200000)
+#define ANUBIS_IDESECAUX    ANUBIS_IOADDR(0x01300000)
+
+#endif /* __ASM_ARCH_ANUBISMAP_H */