summary refs log tree commit diff
path: root/arch/arm
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2005-09-08 01:45:47 -0400
committerLen Brown <len.brown@intel.com>2005-09-08 01:45:47 -0400
commit64e47488c913ac704d465a6af86a26786d1412a5 (patch)
treed3b0148592963dcde26e4bb35ddfec8b1eaf8e23 /arch/arm
parent4a35a46bf1cda4737c428380d1db5d15e2590d18 (diff)
parentcaf39e87cc1182f7dae84eefc43ca14d54c78ef9 (diff)
downloadlinux-64e47488c913ac704d465a6af86a26786d1412a5.tar.gz
Merge linux-2.6 with linux-acpi-2.6
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/boot/compressed/head-sharpsl.S111
-rw-r--r--arch/arm/common/locomo.c24
-rw-r--r--arch/arm/common/sa1111.c8
-rw-r--r--arch/arm/common/scoop.c6
-rw-r--r--arch/arm/configs/omap_h2_1610_defconfig290
-rw-r--r--arch/arm/kernel/ecard.c4
-rw-r--r--arch/arm/kernel/irq.c20
-rw-r--r--arch/arm/kernel/smp.c2
-rw-r--r--arch/arm/kernel/time.c7
-rw-r--r--arch/arm/mach-footbridge/Kconfig1
-rw-r--r--arch/arm/mach-footbridge/isa-irq.c2
-rw-r--r--arch/arm/mach-h720x/common.c2
-rw-r--r--arch/arm/mach-h720x/cpu-h7202.c2
-rw-r--r--arch/arm/mach-imx/irq.c4
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c2
-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.c10
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x00.c2
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x01.c2
-rw-r--r--arch/arm/mach-ixp4xx/common.c16
-rw-r--r--arch/arm/mach-lh7a40x/common.h2
-rw-r--r--arch/arm/mach-omap1/fpga.c2
-rw-r--r--arch/arm/mach-omap1/irq.c8
-rw-r--r--arch/arm/mach-pxa/Makefile2
-rw-r--r--arch/arm/mach-pxa/corgi.c67
-rw-r--r--arch/arm/mach-pxa/corgi_lcd.c396
-rw-r--r--arch/arm/mach-pxa/irq.c12
-rw-r--r--arch/arm/mach-pxa/lubbock.c2
-rw-r--r--arch/arm/mach-pxa/mainstone.c2
-rw-r--r--arch/arm/mach-pxa/poodle.c12
-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/irq.c22
-rw-r--r--arch/arm/mach-s3c2410/mach-anubis.c270
-rw-r--r--arch/arm/mach-s3c2410/mach-n30.c30
-rw-r--r--arch/arm/mach-s3c2410/pm-simtec.c2
-rw-r--r--arch/arm/mach-s3c2410/pm.c6
-rw-r--r--arch/arm/mach-s3c2410/s3c2440-irq.c8
-rw-r--r--arch/arm/mach-s3c2410/time.c2
-rw-r--r--arch/arm/mach-sa1100/irq.c10
-rw-r--r--arch/arm/mach-sa1100/neponset.c6
-rw-r--r--arch/arm/mach-versatile/core.c2
-rw-r--r--arch/arm/mm/proc-arm6_7.S8
-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
62 files changed, 2191 insertions, 722 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 68dfdba71d74..0f2899b4159d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -64,6 +64,9 @@ config GENERIC_CALIBRATE_DELAY
 config GENERIC_BUST_SPINLOCK
 	bool
 
+config ARCH_MAY_HAVE_PC_FDC
+	bool
+
 config GENERIC_ISA_DMA
 	bool
 
@@ -150,6 +153,7 @@ config ARCH_RPC
 	select ARCH_ACORN
 	select FIQ
 	select TIMER_ACORN
+	select ARCH_MAY_HAVE_PC_FDC
 	help
 	  On the Acorn Risc-PC, Linux can support the internal IDE disk and
 	  CD-ROM interface, serial and parallel port, and the floppy drive.
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/common/locomo.c b/arch/arm/common/locomo.c
index 41f12658c8b4..51f430cc2fbf 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -177,7 +177,7 @@ static void locomo_handler(unsigned int irq, struct irqdesc *desc,
 		d = irq_desc + irq;
 		for (i = 0; i <= 3; i++, d++, irq++) {
 			if (req & (0x0100 << i)) {
-				d->handle(irq, d, regs);
+				desc_handle_irq(irq, d, regs);
 			}
 
 		}
@@ -220,7 +220,7 @@ static void locomo_key_handler(unsigned int irq, struct irqdesc *desc,
 
 	if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) {
 		d = irq_desc + LOCOMO_IRQ_KEY_START;
-		d->handle(LOCOMO_IRQ_KEY_START, d, regs);
+		desc_handle_irq(LOCOMO_IRQ_KEY_START, d, regs);
 	}
 }
 
@@ -273,7 +273,7 @@ static void locomo_gpio_handler(unsigned int irq, struct irqdesc *desc,
 		d = irq_desc + LOCOMO_IRQ_GPIO_START;
 		for (i = 0; i <= 15; i++, irq++, d++) {
 			if (req & (0x0001 << i)) {
-				d->handle(irq, d, regs);
+				desc_handle_irq(irq, d, regs);
 			}
 		}
 	}
@@ -328,7 +328,7 @@ static void locomo_lt_handler(unsigned int irq, struct irqdesc *desc,
 
 	if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) {
 		d = irq_desc + LOCOMO_IRQ_LT_START;
-		d->handle(LOCOMO_IRQ_LT_START, d, regs);
+		desc_handle_irq(LOCOMO_IRQ_LT_START, d, regs);
 	}
 }
 
@@ -379,7 +379,7 @@ static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc,
 
 		for (i = 0; i <= 3; i++, irq++, d++) {
 			if (req & (0x0001 << i)) {
-				d->handle(irq, d, regs);
+				desc_handle_irq(irq, d, regs);
 			}
 		}
 	}
@@ -651,15 +651,15 @@ __locomo_probe(struct device *me, struct resource *mem, int irq)
 	return ret;
 }
 
-static void __locomo_remove(struct locomo *lchip)
+static int locomo_remove_child(struct device *dev, void *data)
 {
-	struct list_head *l, *n;
-
-	list_for_each_safe(l, n, &lchip->dev->children) {
-		struct device *d = list_to_dev(l);
+	device_unregister(dev);
+	return 0;
+} 
 
-		device_unregister(d);
-	}
+static void __locomo_remove(struct locomo *lchip)
+{
+	device_for_each_child(lchip->dev, NULL, locomo_remove_child);
 
 	if (lchip->irq != NO_IRQ) {
 		set_irq_chained_handler(lchip->irq, NULL);
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 38c2eb667eb9..1a47fbf9cbbc 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -268,8 +268,8 @@ static struct irqchip sa1111_low_chip = {
 	.mask		= sa1111_mask_lowirq,
 	.unmask		= sa1111_unmask_lowirq,
 	.retrigger	= sa1111_retrigger_lowirq,
-	.type		= sa1111_type_lowirq,
-	.wake		= sa1111_wake_lowirq,
+	.set_type	= sa1111_type_lowirq,
+	.set_wake	= sa1111_wake_lowirq,
 };
 
 static void sa1111_mask_highirq(unsigned int irq)
@@ -364,8 +364,8 @@ static struct irqchip sa1111_high_chip = {
 	.mask		= sa1111_mask_highirq,
 	.unmask		= sa1111_unmask_highirq,
 	.retrigger	= sa1111_retrigger_highirq,
-	.type		= sa1111_type_highirq,
-	.wake		= sa1111_wake_highirq,
+	.set_type	= sa1111_type_highirq,
+	.set_wake	= sa1111_wake_highirq,
 };
 
 static void sa1111_setup_irq(struct sa1111 *sachip)
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index cfd0d3e550d9..688a595598c8 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -17,6 +17,12 @@
 
 #define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr)))
 
+/* PCMCIA to Scoop linkage structures for pxa2xx_sharpsl.c
+   There is no easy way to link multiple scoop devices into one
+   single entity for the pxa2xx_pcmcia device */
+int scoop_num;
+struct scoop_pcmcia_dev *scoop_devs;
+
 struct  scoop_dev {
 	void  *base;
 	spinlock_t scoop_lock;
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/kernel/ecard.c b/arch/arm/kernel/ecard.c
index 6540db691338..dceb826bd216 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -585,7 +585,7 @@ ecard_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
 
 		if (pending) {
 			struct irqdesc *d = irq_desc + ec->irq;
-			d->handle(ec->irq, d, regs);
+			desc_handle_irq(ec->irq, d, regs);
 			called ++;
 		}
 	}
@@ -632,7 +632,7 @@ ecard_irqexp_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *reg
 			 * Serial cards should go in 0/1, ethernet/scsi in 2/3
 			 * otherwise you will lose serial data at high speeds!
 			 */
-			d->handle(ec->irq, d, regs);
+			desc_handle_irq(ec->irq, d, regs);
 		} else {
 			printk(KERN_WARNING "card%d: interrupt from unclaimed "
 			       "card???\n", slot);
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 395137a8fad2..3284118f356b 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -207,8 +207,8 @@ void enable_irq_wake(unsigned int irq)
 	unsigned long flags;
 
 	spin_lock_irqsave(&irq_controller_lock, flags);
-	if (desc->chip->wake)
-		desc->chip->wake(irq, 1);
+	if (desc->chip->set_wake)
+		desc->chip->set_wake(irq, 1);
 	spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
 EXPORT_SYMBOL(enable_irq_wake);
@@ -219,8 +219,8 @@ void disable_irq_wake(unsigned int irq)
 	unsigned long flags;
 
 	spin_lock_irqsave(&irq_controller_lock, flags);
-	if (desc->chip->wake)
-		desc->chip->wake(irq, 0);
+	if (desc->chip->set_wake)
+		desc->chip->set_wake(irq, 0);
 	spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
 EXPORT_SYMBOL(disable_irq_wake);
@@ -517,7 +517,7 @@ static void do_pending_irqs(struct pt_regs *regs)
 		list_for_each_safe(l, n, &head) {
 			desc = list_entry(l, struct irqdesc, pend);
 			list_del_init(&desc->pend);
-			desc->handle(desc - irq_desc, desc, regs);
+			desc_handle_irq(desc - irq_desc, desc, regs);
 		}
 
 		/*
@@ -545,7 +545,7 @@ asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 
 	irq_enter();
 	spin_lock(&irq_controller_lock);
-	desc->handle(irq, desc, regs);
+	desc_handle_irq(irq, desc, regs);
 
 	/*
 	 * Now re-run any pending interrupts.
@@ -624,9 +624,9 @@ int set_irq_type(unsigned int irq, unsigned int type)
 	}
 
 	desc = irq_desc + irq;
-	if (desc->chip->type) {
+	if (desc->chip->set_type) {
 		spin_lock_irqsave(&irq_controller_lock, flags);
-		ret = desc->chip->type(irq, type);
+		ret = desc->chip->set_type(irq, type);
 		spin_unlock_irqrestore(&irq_controller_lock, flags);
 	}
 
@@ -846,8 +846,8 @@ unsigned long probe_irq_on(void)
 
 		irq_desc[i].probing = 1;
 		irq_desc[i].triggered = 0;
-		if (irq_desc[i].chip->type)
-			irq_desc[i].chip->type(i, IRQT_PROBE);
+		if (irq_desc[i].chip->set_type)
+			irq_desc[i].chip->set_type(i, IRQT_PROBE);
 		irq_desc[i].chip->unmask(i);
 		irqs += 1;
 	}
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index b2085735a2ba..826164945747 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -110,7 +110,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
 	 * We need to tell the secondary core where to find
 	 * its stack and the page tables.
 	 */
-	secondary_data.stack = (void *)idle->thread_info + THREAD_SIZE - 8;
+	secondary_data.stack = (void *)idle->thread_info + THREAD_START_SP;
 	secondary_data.pgdir = virt_to_phys(pgd);
 	wmb();
 
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 8880482dcbff..69449a818dcc 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -102,7 +102,7 @@ static unsigned long next_rtc_update;
  */
 static inline void do_set_rtc(void)
 {
-	if (time_status & STA_UNSYNC || set_rtc == NULL)
+	if (!ntp_synced() || set_rtc == NULL)
 		return;
 
 	if (next_rtc_update &&
@@ -292,10 +292,7 @@ int do_settimeofday(struct timespec *tv)
 	set_normalized_timespec(&xtime, sec, nsec);
 	set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
 
-	time_adjust = 0;		/* stop active adjtime() */
-	time_status |= STA_UNSYNC;
-	time_maxerror = NTP_PHASE_LIMIT;
-	time_esterror = NTP_PHASE_LIMIT;
+	ntp_clear();
 	write_sequnlock_irq(&xtime_lock);
 	clock_was_set();
 	return 0;
diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig
index 324d9edeec38..bdd257921cfb 100644
--- a/arch/arm/mach-footbridge/Kconfig
+++ b/arch/arm/mach-footbridge/Kconfig
@@ -87,6 +87,7 @@ config FOOTBRIDGE_ADDIN
 
 # EBSA285 board in either host or addin mode
 config ARCH_EBSA285
+	select ARCH_MAY_HAVE_PC_FDC
 	bool
 
 endif
diff --git a/arch/arm/mach-footbridge/isa-irq.c b/arch/arm/mach-footbridge/isa-irq.c
index b21016070ea3..e1c43b331d64 100644
--- a/arch/arm/mach-footbridge/isa-irq.c
+++ b/arch/arm/mach-footbridge/isa-irq.c
@@ -95,7 +95,7 @@ isa_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
 	}
 
 	desc = irq_desc + isa_irq;
-	desc->handle(isa_irq, desc, regs);
+	desc_handle_irq(isa_irq, desc, regs);
 }
 
 static struct irqaction irq_cascade = { .handler = no_action, .name = "cascade", };
diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c
index 96aa3af70d86..5110e2e65ddd 100644
--- a/arch/arm/mach-h720x/common.c
+++ b/arch/arm/mach-h720x/common.c
@@ -108,7 +108,7 @@ h720x_gpio_handler(unsigned int mask, unsigned int irq,
 	while (mask) {
 		if (mask & 1) {
 			IRQDBG("handling irq %d\n", irq);
-			desc->handle(irq, desc, regs);
+			desc_handle_irq(irq, desc, regs);
 		}
 		irq++;
 		desc++;
diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c
index 593b6a2a30e1..4b3199319e68 100644
--- a/arch/arm/mach-h720x/cpu-h7202.c
+++ b/arch/arm/mach-h720x/cpu-h7202.c
@@ -126,7 +126,7 @@ h7202_timerx_demux_handler(unsigned int irq_unused, struct irqdesc *desc,
 	desc = irq_desc + irq;
 	while (mask) {
 		if (mask & 1)
-			desc->handle(irq, desc, regs);
+			desc_handle_irq(irq, desc, regs);
 		irq++;
 		desc++;
 		mask >>= 1;
diff --git a/arch/arm/mach-imx/irq.c b/arch/arm/mach-imx/irq.c
index 0c2713426dfd..eeb8a6d4a399 100644
--- a/arch/arm/mach-imx/irq.c
+++ b/arch/arm/mach-imx/irq.c
@@ -152,7 +152,7 @@ imx_gpio_handler(unsigned int mask, unsigned int irq,
 	while (mask) {
 		if (mask & 1) {
 			DEBUG_IRQ("handling irq %d\n", irq);
-			desc->handle(irq, desc, regs);
+			desc_handle_irq(irq, desc, regs);
 		}
 		irq++;
 		desc++;
@@ -214,7 +214,7 @@ static struct irqchip imx_gpio_chip = {
 	.ack = imx_gpio_ack_irq,
 	.mask = imx_gpio_mask_irq,
 	.unmask = imx_gpio_unmask_irq,
-	.type = imx_gpio_irq_type,
+	.set_type = imx_gpio_irq_type,
 };
 
 void __init
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 569f328c479d..2be5c03ab87f 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -170,7 +170,7 @@ sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
 		irq += IRQ_SIC_START;
 
 		desc = irq_desc + irq;
-		desc->handle(irq, desc, regs);
+		desc_handle_irq(irq, desc, regs);
 	} while (status);
 }
 
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 45b18658499f..098c817a7fb8 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -317,7 +317,7 @@ static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc, str
 	for (i = 0; i <= 7; i++) {
 		if (status & (1<<i)) {
 			desc = irq_desc + i + IRQ_IXP2000_GPIO0;
-			desc->handle(i + IRQ_IXP2000_GPIO0, desc, regs);
+			desc_handle_irq(i + IRQ_IXP2000_GPIO0, desc, regs);
 		}
 	}
 }
@@ -380,10 +380,10 @@ static void ixp2000_GPIO_irq_unmask(unsigned int irq)
 }
 
 static struct irqchip ixp2000_GPIO_irq_chip = {
-	.type	= ixp2000_GPIO_irq_type,
-	.ack	= ixp2000_GPIO_irq_mask_ack,
-	.mask	= ixp2000_GPIO_irq_mask,
-	.unmask	= ixp2000_GPIO_irq_unmask
+	.ack		= ixp2000_GPIO_irq_mask_ack,
+	.mask		= ixp2000_GPIO_irq_mask,
+	.unmask		= ixp2000_GPIO_irq_unmask,
+	.set_type	= ixp2000_GPIO_irq_type,
 };
 
 static void ixp2000_pci_irq_mask(unsigned int irq)
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
index a43369ad876c..63ba0191aa65 100644
--- a/arch/arm/mach-ixp2000/ixdp2x00.c
+++ b/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -133,7 +133,7 @@ static void ixdp2x00_irq_handler(unsigned int irq, struct irqdesc *desc, struct
 			struct irqdesc *cpld_desc;
 			int cpld_irq = IXP2000_BOARD_IRQ(0) + i;
 			cpld_desc = irq_desc + cpld_irq;
-			cpld_desc->handle(cpld_irq, cpld_desc, regs);
+			desc_handle_irq(cpld_irq, cpld_desc, regs);
 		}
 	}
 
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
index 43447dad1657..7a5109921287 100644
--- a/arch/arm/mach-ixp2000/ixdp2x01.c
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -82,7 +82,7 @@ static void ixdp2x01_irq_handler(unsigned int irq, struct irqdesc *desc, struct
 			struct irqdesc *cpld_desc;
 			int cpld_irq = IXP2000_BOARD_IRQ(0) + i;
 			cpld_desc = irq_desc + cpld_irq;
-			cpld_desc->handle(cpld_irq, cpld_desc, regs);
+			desc_handle_irq(cpld_irq, cpld_desc, regs);
 		}
 	}
 
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-lh7a40x/common.h b/arch/arm/mach-lh7a40x/common.h
index beda7c2602fb..578a52461fdb 100644
--- a/arch/arm/mach-lh7a40x/common.h
+++ b/arch/arm/mach-lh7a40x/common.h
@@ -13,4 +13,4 @@ extern struct sys_timer lh7a40x_timer;
 extern void lh7a400_init_irq (void);
 extern void lh7a404_init_irq (void);
 
-#define IRQ_DISPATCH(irq) irq_desc[irq].handle ((irq), &irq_desc[irq], regs)
+#define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq), regs)
diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c
index 7c08f6c2e1d0..c12a78335625 100644
--- a/arch/arm/mach-omap1/fpga.c
+++ b/arch/arm/mach-omap1/fpga.c
@@ -102,7 +102,7 @@ void innovator_fpga_IRQ_demux(unsigned int irq, struct irqdesc *desc,
 	     fpga_irq++, stat >>= 1) {
 		if (stat & 1) {
 			d = irq_desc + fpga_irq;
-			d->handle(fpga_irq, d, regs);
+			desc_handle_irq(fpga_irq, d, regs);
 		}
 	}
 }
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-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index efc2f657184e..33dae99ec2d8 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_PXA27x) += pxa27x.o
 obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
 obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
 obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
-obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.o corgi_ssp.o ssp.o
+obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.o corgi_ssp.o corgi_lcd.o ssp.o
 obj-$(CONFIG_MACH_POODLE)	+= poodle.o
 
 # Support for blinky lights
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 86b862f56e7e..29185acdd9e1 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -39,7 +39,6 @@
 
 #include <asm/mach/sharpsl_param.h>
 #include <asm/hardware/scoop.h>
-#include <video/w100fb.h>
 
 #include "generic.h"
 
@@ -60,6 +59,15 @@ static struct scoop_config corgi_scoop_setup = {
 	.io_out		= CORGI_SCOOP_IO_OUT,
 };
 
+static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = {
+{
+	.dev        = &corgiscoop_device.dev,
+	.irq        = CORGI_IRQ_GPIO_CF_IRQ,
+	.cd_irq     = CORGI_IRQ_GPIO_CF_CD,
+	.cd_irq_str = "PCMCIA0 CD",
+},
+};
+
 struct platform_device corgiscoop_device = {
 	.name		= "sharp-scoop",
 	.id		= -1,
@@ -78,7 +86,7 @@ struct platform_device corgiscoop_device = {
  * also use scoop functions and this makes the power up/down order
  * work correctly.
  */
-static struct platform_device corgissp_device = {
+struct platform_device corgissp_device = {
 	.name		= "corgi-ssp",
 	.dev		= {
  		.parent = &corgiscoop_device.dev,
@@ -88,41 +96,33 @@ static struct platform_device corgissp_device = {
 
 
 /*
- * Corgi w100 Frame Buffer Device
+ * Corgi Backlight Device
  */
-static struct w100fb_mach_info corgi_fb_info = {
-	.w100fb_ssp_send 	= corgi_ssp_lcdtg_send,
-	.comadj 			= -1,
-	.phadadj 			= -1,
-};
-
-static struct resource corgi_fb_resources[] = {
-	[0] = {
-		.start		= 0x08000000,
-		.end		= 0x08ffffff,
-		.flags		= IORESOURCE_MEM,
+static struct platform_device corgibl_device = {
+	.name		= "corgi-bl",
+	.dev		= {
+ 		.parent = &corgifb_device.dev,
 	},
+	.id		= -1,
 };
 
-static struct platform_device corgifb_device = {
-	.name		= "w100fb",
+
+/*
+ * Corgi Keyboard Device
+ */
+static struct platform_device corgikbd_device = {
+	.name		= "corgi-keyboard",
 	.id		= -1,
-	.dev		= {
- 		.platform_data	= &corgi_fb_info,
- 		.parent = &corgissp_device.dev,
-	},
-	.num_resources	= ARRAY_SIZE(corgi_fb_resources),
-	.resource	= corgi_fb_resources,
 };
 
 
 /*
- * Corgi Backlight Device
+ * Corgi Touch Screen Device
  */
-static struct platform_device corgibl_device = {
-	.name		= "corgi-bl",
+static struct platform_device corgits_device = {
+	.name		= "corgi-ts",
 	.dev		= {
- 		.parent = &corgifb_device.dev,
+ 		.parent = &corgissp_device.dev,
 	},
 	.id		= -1,
 };
@@ -190,6 +190,11 @@ static void corgi_mci_setpower(struct device *dev, unsigned int vdd)
 	}
 }
 
+static int corgi_mci_get_ro(struct device *dev)
+{
+	return GPLR(CORGI_GPIO_nSD_WP) & GPIO_bit(CORGI_GPIO_nSD_WP);
+}
+
 static void corgi_mci_exit(struct device *dev, void *data)
 {
 	free_irq(CORGI_IRQ_GPIO_nSD_DETECT, data);
@@ -199,11 +204,13 @@ static void corgi_mci_exit(struct device *dev, void *data)
 static struct pxamci_platform_data corgi_mci_platform_data = {
 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
 	.init 		= corgi_mci_init,
+	.get_ro		= corgi_mci_get_ro,
 	.setpower 	= corgi_mci_setpower,
 	.exit		= corgi_mci_exit,
 };
 
 
+
 /*
  * USB Device Controller
  */
@@ -229,18 +236,20 @@ static struct platform_device *devices[] __initdata = {
 	&corgiscoop_device,
 	&corgissp_device,
 	&corgifb_device,
+	&corgikbd_device,
 	&corgibl_device,
+	&corgits_device,
 };
 
 static void __init corgi_init(void)
 {
-	corgi_fb_info.comadj=sharpsl_param.comadj;
-	corgi_fb_info.phadadj=sharpsl_param.phadadj;
-
 	pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT);
  	pxa_set_udc_info(&udc_info);
 	pxa_set_mci_info(&corgi_mci_platform_data);
 
+	scoop_num = 1;
+	scoop_devs = &corgi_pcmcia_scoop[0];
+
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
new file mode 100644
index 000000000000..deac29c00290
--- /dev/null
+++ b/arch/arm/mach-pxa/corgi_lcd.c
@@ -0,0 +1,396 @@
+/*
+ * linux/drivers/video/w100fb.c
+ *
+ * Corgi LCD Specific Code for ATI Imageon w100 (Wallaby)
+ *
+ * Copyright (C) 2005 Richard Purdie
+ *
+ * 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/delay.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <asm/arch/corgi.h>
+#include <asm/mach/sharpsl_param.h>
+#include <video/w100fb.h>
+
+/* Register Addresses */
+#define RESCTL_ADRS     0x00
+#define PHACTRL_ADRS    0x01
+#define DUTYCTRL_ADRS   0x02
+#define POWERREG0_ADRS  0x03
+#define POWERREG1_ADRS  0x04
+#define GPOR3_ADRS      0x05
+#define PICTRL_ADRS     0x06
+#define POLCTRL_ADRS    0x07
+
+/* Resgister Bit Definitions */
+#define RESCTL_QVGA     0x01
+#define RESCTL_VGA      0x00
+
+#define POWER1_VW_ON    0x01  /* VW Supply FET ON */
+#define POWER1_GVSS_ON  0x02  /* GVSS(-8V) Power Supply ON */
+#define POWER1_VDD_ON   0x04  /* VDD(8V),SVSS(-4V) Power Supply ON */
+
+#define POWER1_VW_OFF   0x00  /* VW Supply FET OFF */
+#define POWER1_GVSS_OFF 0x00  /* GVSS(-8V) Power Supply OFF */
+#define POWER1_VDD_OFF  0x00  /* VDD(8V),SVSS(-4V) Power Supply OFF */
+
+#define POWER0_COM_DCLK 0x01  /* COM Voltage DC Bias DAC Serial Data Clock */
+#define POWER0_COM_DOUT 0x02  /* COM Voltage DC Bias DAC Serial Data Out */
+#define POWER0_DAC_ON   0x04  /* DAC Power Supply ON */
+#define POWER0_COM_ON   0x08  /* COM Powewr Supply ON */
+#define POWER0_VCC5_ON  0x10  /* VCC5 Power Supply ON */
+
+#define POWER0_DAC_OFF  0x00  /* DAC Power Supply OFF */
+#define POWER0_COM_OFF  0x00  /* COM Powewr Supply OFF */
+#define POWER0_VCC5_OFF 0x00  /* VCC5 Power Supply OFF */
+
+#define PICTRL_INIT_STATE      0x01
+#define PICTRL_INIOFF          0x02
+#define PICTRL_POWER_DOWN      0x04
+#define PICTRL_COM_SIGNAL_OFF  0x08
+#define PICTRL_DAC_SIGNAL_OFF  0x10
+
+#define POLCTRL_SYNC_POL_FALL  0x01
+#define POLCTRL_EN_POL_FALL    0x02
+#define POLCTRL_DATA_POL_FALL  0x04
+#define POLCTRL_SYNC_ACT_H     0x08
+#define POLCTRL_EN_ACT_L       0x10
+
+#define POLCTRL_SYNC_POL_RISE  0x00
+#define POLCTRL_EN_POL_RISE    0x00
+#define POLCTRL_DATA_POL_RISE  0x00
+#define POLCTRL_SYNC_ACT_L     0x00
+#define POLCTRL_EN_ACT_H       0x00
+
+#define PHACTRL_PHASE_MANUAL   0x01
+#define DEFAULT_PHAD_QVGA     (9)
+#define DEFAULT_COMADJ        (125)
+
+/*
+ * This is only a psuedo I2C interface. We can't use the standard kernel
+ * routines as the interface is write only. We just assume the data is acked...
+ */
+static void lcdtg_ssp_i2c_send(u8 data)
+{
+	corgi_ssp_lcdtg_send(POWERREG0_ADRS, data);
+	udelay(10);
+}
+
+static void lcdtg_i2c_send_bit(u8 data)
+{
+	lcdtg_ssp_i2c_send(data);
+	lcdtg_ssp_i2c_send(data | POWER0_COM_DCLK);
+	lcdtg_ssp_i2c_send(data);
+}
+
+static void lcdtg_i2c_send_start(u8 base)
+{
+	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
+	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
+	lcdtg_ssp_i2c_send(base);
+}
+
+static void lcdtg_i2c_send_stop(u8 base)
+{
+	lcdtg_ssp_i2c_send(base);
+	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
+	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
+}
+
+static void lcdtg_i2c_send_byte(u8 base, u8 data)
+{
+	int i;
+	for (i = 0; i < 8; i++) {
+		if (data & 0x80)
+			lcdtg_i2c_send_bit(base | POWER0_COM_DOUT);
+		else
+			lcdtg_i2c_send_bit(base);
+		data <<= 1;
+	}
+}
+
+static void lcdtg_i2c_wait_ack(u8 base)
+{
+	lcdtg_i2c_send_bit(base);
+}
+
+static void lcdtg_set_common_voltage(u8 base_data, u8 data)
+{
+	/* Set Common Voltage to M62332FP via I2C */
+	lcdtg_i2c_send_start(base_data);
+	lcdtg_i2c_send_byte(base_data, 0x9c);
+	lcdtg_i2c_wait_ack(base_data);
+	lcdtg_i2c_send_byte(base_data, 0x00);
+	lcdtg_i2c_wait_ack(base_data);
+	lcdtg_i2c_send_byte(base_data, data);
+	lcdtg_i2c_wait_ack(base_data);
+	lcdtg_i2c_send_stop(base_data);
+}
+
+/* Set Phase Adjuct */
+static void lcdtg_set_phadadj(struct w100fb_par *par)
+{
+	int adj;
+	switch(par->xres) {
+		case 480:
+		case 640:
+			/* Setting for VGA */
+			adj = sharpsl_param.phadadj;
+			if (adj < 0) {
+				adj = PHACTRL_PHASE_MANUAL;
+			} else {
+				adj = ((adj & 0x0f) << 1) | PHACTRL_PHASE_MANUAL;
+			}
+			break;
+		case 240:
+		case 320:
+		default:
+			/* Setting for QVGA */
+			adj = (DEFAULT_PHAD_QVGA << 1) | PHACTRL_PHASE_MANUAL;
+			break;
+	}
+
+	corgi_ssp_lcdtg_send(PHACTRL_ADRS, adj);
+}
+
+static int lcd_inited;
+
+static void lcdtg_hw_init(struct w100fb_par *par)
+{
+	if (!lcd_inited) {
+		int comadj;
+
+		/* Initialize Internal Logic & Port */
+		corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_POWER_DOWN | PICTRL_INIOFF | PICTRL_INIT_STATE
+	  			| PICTRL_COM_SIGNAL_OFF | PICTRL_DAC_SIGNAL_OFF);
+
+		corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF
+				| POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+		corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
+
+		/* VDD(+8V), SVSS(-4V) ON */
+		corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
+		mdelay(3);
+
+		/* DAC ON */
+		corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON
+				| POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+		/* INIB = H, INI = L  */
+		/* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */
+		corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF);
+
+		/* Set Common Voltage */
+		comadj = sharpsl_param.comadj;
+		if (comadj < 0)
+			comadj = DEFAULT_COMADJ;
+		lcdtg_set_common_voltage((POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF), comadj);
+
+		/* VCC5 ON, DAC ON */
+		corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON |
+				POWER0_COM_OFF | POWER0_VCC5_ON);
+
+		/* GVSS(-8V) ON, VDD ON */
+		corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
+		mdelay(2);
+
+		/* COM SIGNAL ON (PICTL[3] = L) */
+		corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE);
+
+		/* COM ON, DAC ON, VCC5_ON */
+		corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON
+				| POWER0_COM_ON | POWER0_VCC5_ON);
+
+		/* VW ON, GVSS ON, VDD ON */
+		corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_ON | POWER1_GVSS_ON | POWER1_VDD_ON);
+
+		/* Signals output enable */
+		corgi_ssp_lcdtg_send(PICTRL_ADRS, 0);
+
+		/* Set Phase Adjuct */
+		lcdtg_set_phadadj(par);
+
+		/* Initialize for Input Signals from ATI */
+		corgi_ssp_lcdtg_send(POLCTRL_ADRS, POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE
+				| POLCTRL_DATA_POL_RISE | POLCTRL_SYNC_ACT_L | POLCTRL_EN_ACT_H);
+		udelay(1000);
+
+		lcd_inited=1;
+	} else {
+		lcdtg_set_phadadj(par);
+	}
+
+	switch(par->xres) {
+		case 480:
+		case 640:
+			/* Set Lcd Resolution (VGA) */
+			corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_VGA);
+			break;
+		case 240:
+		case 320:
+		default:
+			/* Set Lcd Resolution (QVGA) */
+			corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_QVGA);
+			break;
+	}
+}
+
+static void lcdtg_suspend(struct w100fb_par *par)
+{
+	/* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
+	mdelay(34);
+
+	/* (1)VW OFF */
+	corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
+
+	/* (2)COM OFF */
+	corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF);
+	corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON);
+
+	/* (3)Set Common Voltage Bias 0V */
+	lcdtg_set_common_voltage(POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON, 0);
+
+	/* (4)GVSS OFF */
+	corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
+
+	/* (5)VCC5 OFF */
+	corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+	/* (6)Set PDWN, INIOFF, DACOFF */
+	corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF |
+			PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF);
+
+	/* (7)DAC OFF */
+	corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+	/* (8)VDD OFF */
+	corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
+
+	lcd_inited = 0;
+}
+
+static struct w100_tg_info corgi_lcdtg_info = {
+	.change=lcdtg_hw_init,
+	.suspend=lcdtg_suspend,
+	.resume=lcdtg_hw_init,
+};
+
+/*
+ * Corgi w100 Frame Buffer Device
+ */
+
+static struct w100_mem_info corgi_fb_mem = {
+	.ext_cntl          = 0x00040003,
+	.sdram_mode_reg    = 0x00650021,
+	.ext_timing_cntl   = 0x10002a4a,
+	.io_cntl           = 0x7ff87012,
+	.size              = 0x1fffff,
+};
+
+static struct w100_gen_regs corgi_fb_regs = {
+	.lcd_format    = 0x00000003,
+	.lcdd_cntl1    = 0x01CC0000,
+	.lcdd_cntl2    = 0x0003FFFF,
+	.genlcd_cntl1  = 0x00FFFF0D,
+	.genlcd_cntl2  = 0x003F3003,
+	.genlcd_cntl3  = 0x000102aa,
+};
+
+static struct w100_gpio_regs corgi_fb_gpio = {
+	.init_data1   = 0x000000bf,
+	.init_data2   = 0x00000000,
+	.gpio_dir1    = 0x00000000,
+	.gpio_oe1     = 0x03c0feff,
+	.gpio_dir2    = 0x00000000,
+	.gpio_oe2     = 0x00000000,
+};
+
+static struct w100_mode corgi_fb_modes[] = {
+{
+	.xres            = 480,
+	.yres            = 640,
+	.left_margin     = 0x56,
+	.right_margin    = 0x55,
+	.upper_margin    = 0x03,
+	.lower_margin    = 0x00,
+	.crtc_ss         = 0x82360056,
+	.crtc_ls         = 0xA0280000,
+	.crtc_gs         = 0x80280028,
+	.crtc_vpos_gs    = 0x02830002,
+	.crtc_rev        = 0x00400008,
+	.crtc_dclk       = 0xA0000000,
+	.crtc_gclk       = 0x8015010F,
+	.crtc_goe        = 0x80100110,
+	.crtc_ps1_active = 0x41060010,
+	.pll_freq        = 75,
+	.fast_pll_freq   = 100,
+	.sysclk_src      = CLK_SRC_PLL,
+	.sysclk_divider  = 0,
+	.pixclk_src      = CLK_SRC_PLL,
+	.pixclk_divider  = 2,
+	.pixclk_divider_rotated = 6,
+},{
+	.xres            = 240,
+	.yres            = 320,
+	.left_margin     = 0x27,
+	.right_margin    = 0x2e,
+	.upper_margin    = 0x01,
+	.lower_margin    = 0x00,
+	.crtc_ss         = 0x81170027,
+	.crtc_ls         = 0xA0140000,
+	.crtc_gs         = 0xC0140014,
+	.crtc_vpos_gs    = 0x00010141,
+	.crtc_rev        = 0x00400008,
+	.crtc_dclk       = 0xA0000000,
+	.crtc_gclk       = 0x8015010F,
+	.crtc_goe        = 0x80100110,
+	.crtc_ps1_active = 0x41060010,
+	.pll_freq        = 0,
+	.fast_pll_freq   = 0,
+	.sysclk_src      = CLK_SRC_XTAL,
+	.sysclk_divider  = 0,
+	.pixclk_src      = CLK_SRC_XTAL,
+	.pixclk_divider  = 1,
+	.pixclk_divider_rotated = 1,
+},
+
+};
+
+static struct w100fb_mach_info corgi_fb_info = {
+	.tg         = &corgi_lcdtg_info,
+	.init_mode  = INIT_MODE_ROTATED,
+	.mem        = &corgi_fb_mem,
+	.regs       = &corgi_fb_regs,
+	.modelist   = &corgi_fb_modes[0],
+	.num_modes  = 2,
+	.gpio       = &corgi_fb_gpio,
+	.xtal_freq  = 12500000,
+	.xtal_dbl   = 0,
+};
+
+static struct resource corgi_fb_resources[] = {
+	[0] = {
+		.start   = 0x08000000,
+		.end     = 0x08ffffff,
+		.flags   = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device corgifb_device = {
+	.name           = "w100fb",
+	.id             = -1,
+	.num_resources	= ARRAY_SIZE(corgi_fb_resources),
+	.resource	= corgi_fb_resources,
+	.dev            = {
+ 		.platform_data = &corgi_fb_info,
+ 		.parent = &corgissp_device.dev,
+	},
+
+};
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index f3cac43124a5..539b596005fc 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -133,7 +133,7 @@ static struct irqchip pxa_low_gpio_chip = {
 	.ack		= pxa_ack_low_gpio,
 	.mask		= pxa_mask_low_irq,
 	.unmask		= pxa_unmask_low_irq,
-	.type		= pxa_gpio_irq_type,
+	.set_type	= pxa_gpio_irq_type,
 };
 
 /*
@@ -157,7 +157,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc,
 			mask >>= 2;
 			do {
 				if (mask & 1)
-					desc->handle(irq, desc, regs);
+					desc_handle_irq(irq, desc, regs);
 				irq++;
 				desc++;
 				mask >>= 1;
@@ -172,7 +172,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc,
 			desc = irq_desc + irq;
 			do {
 				if (mask & 1)
-					desc->handle(irq, desc, regs);
+					desc_handle_irq(irq, desc, regs);
 				irq++;
 				desc++;
 				mask >>= 1;
@@ -187,7 +187,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc,
 			desc = irq_desc + irq;
 			do {
 				if (mask & 1)
-					desc->handle(irq, desc, regs);
+					desc_handle_irq(irq, desc, regs);
 				irq++;
 				desc++;
 				mask >>= 1;
@@ -203,7 +203,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc,
 			desc = irq_desc + irq;
 			do {
 				if (mask & 1)
-					desc->handle(irq, desc, regs);
+					desc_handle_irq(irq, desc, regs);
 				irq++;
 				desc++;
 				mask >>= 1;
@@ -241,7 +241,7 @@ static struct irqchip pxa_muxed_gpio_chip = {
 	.ack		= pxa_ack_muxed_gpio,
 	.mask		= pxa_mask_muxed_gpio,
 	.unmask		= pxa_unmask_muxed_gpio,
-	.type		= pxa_gpio_irq_type,
+	.set_type	= pxa_gpio_irq_type,
 };
 
 
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 6309853b59be..923f6eb774c0 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -84,7 +84,7 @@ static void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc,
 		if (likely(pending)) {
 			irq = LUBBOCK_IRQ(0) + __ffs(pending);
 			desc = irq_desc + irq;
-			desc->handle(irq, desc, regs);
+			desc_handle_irq(irq, desc, regs);
 		}
 		pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
 	} while (pending);
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 827b7b5a5be8..85fdb5b1470a 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -72,7 +72,7 @@ static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc,
 		if (likely(pending)) {
 			irq = MAINSTONE_IRQ(0) + __ffs(pending);
 			desc = irq_desc + irq;
-			desc->handle(irq, desc, regs);
+			desc_handle_irq(irq, desc, regs);
 		}
 		pending = MST_INTSETCLR & mainstone_irq_enabled;
 	} while (pending);
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 0e4f6fab100a..47cfb8bb8318 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -62,6 +62,15 @@ struct platform_device poodle_scoop_device = {
 	.resource	= poodle_scoop_resources,
 };
 
+static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = {
+{
+	.dev        = &poodle_scoop_device.dev,
+	.irq        = POODLE_IRQ_GPIO_CF_IRQ,
+	.cd_irq     = POODLE_IRQ_GPIO_CF_CD,
+	.cd_irq_str = "PCMCIA0 CD",
+},
+};
+
 
 /* LoCoMo device */
 static struct resource locomo_resources[] = {
@@ -147,6 +156,9 @@ static void __init poodle_init(void)
 
 	set_pxa_fb_info(&poodle_fb_info);
 
+	scoop_num = 1;
+	scoop_devs = &poodle_pcmcia_scoop[0];
+
 	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	if (ret) {
 		printk(KERN_WARNING "poodle: Unable to register LoCoMo device\n");
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 5e5bbe893cbb..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(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/irq.c b/arch/arm/mach-s3c2410/irq.c
index 973a5fe6769c..66d8c068e940 100644
--- a/arch/arm/mach-s3c2410/irq.c
+++ b/arch/arm/mach-s3c2410/irq.c
@@ -184,14 +184,14 @@ struct irqchip s3c_irq_level_chip = {
 	.ack	   = s3c_irq_maskack,
 	.mask	   = s3c_irq_mask,
 	.unmask	   = s3c_irq_unmask,
-	.wake	   = s3c_irq_wake
+	.set_wake	   = s3c_irq_wake
 };
 
 static struct irqchip s3c_irq_chip = {
 	.ack	   = s3c_irq_ack,
 	.mask	   = s3c_irq_mask,
 	.unmask	   = s3c_irq_unmask,
-	.wake	   = s3c_irq_wake
+	.set_wake	   = s3c_irq_wake
 };
 
 /* S3C2410_EINTMASK
@@ -350,16 +350,16 @@ static struct irqchip s3c_irqext_chip = {
 	.mask	    = s3c_irqext_mask,
 	.unmask	    = s3c_irqext_unmask,
 	.ack	    = s3c_irqext_ack,
-	.type	    = s3c_irqext_type,
-	.wake	    = s3c_irqext_wake
+	.set_type    = s3c_irqext_type,
+	.set_wake    = s3c_irqext_wake
 };
 
 static struct irqchip s3c_irq_eint0t4 = {
 	.ack	   = s3c_irq_ack,
 	.mask	   = s3c_irq_mask,
 	.unmask	   = s3c_irq_unmask,
-	.wake	   = s3c_irq_wake,
-	.type	   = s3c_irqext_type,
+	.set_wake  = s3c_irq_wake,
+	.set_type  = s3c_irqext_type,
 };
 
 /* mask values for the parent registers for each of the interrupt types */
@@ -496,11 +496,11 @@ static void s3c_irq_demux_adc(unsigned int irq,
 	if (subsrc != 0) {
 		if (subsrc & 1) {
 			mydesc = irq_desc + IRQ_TC;
-			mydesc->handle( IRQ_TC, mydesc, regs);
+			desc_handle_irq(IRQ_TC, mydesc, regs);
 		}
 		if (subsrc & 2) {
 			mydesc = irq_desc + IRQ_ADC;
-			mydesc->handle(IRQ_ADC, mydesc, regs);
+			desc_handle_irq(IRQ_ADC, mydesc, regs);
 		}
 	}
 }
@@ -529,17 +529,17 @@ static void s3c_irq_demux_uart(unsigned int start,
 		desc = irq_desc + start;
 
 		if (subsrc & 1)
-			desc->handle(start, desc, regs);
+			desc_handle_irq(start, desc, regs);
 
 		desc++;
 
 		if (subsrc & 2)
-			desc->handle(start+1, desc, regs);
+			desc_handle_irq(start+1, desc, regs);
 
 		desc++;
 
 		if (subsrc & 4)
-			desc->handle(start+2, desc, regs);
+			desc_handle_irq(start+2, desc, regs);
 	}
 }
 
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/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 79044d9bce38..66bf5bb2b3db 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -110,34 +110,24 @@ void __init n30_init_irq(void)
 	s3c24xx_init_irq();
 }
 
-
-static int n30_usbstart_thread(void *unused)
-{
-	/* Turn off suspend on both USB ports, and switch the
-	 * selectable USB port to USB device mode. */
-	writel(readl(S3C2410_MISCCR) & ~0x00003008, S3C2410_MISCCR);
-
-	/* Turn off the D+ pull up for 3 seconds so that the USB host
-	 * at the other end will do a rescan of the USB bus.  */
-	s3c2410_gpio_setpin(S3C2410_GPB3, 0);
-
-	msleep_interruptible(3*HZ);
-
-	s3c2410_gpio_setpin(S3C2410_GPB3, 1);
-
-	return 0;
-}
-
+/* GPB3 is the line that controls the pull-up for the USB D+ line */
 
 void __init n30_init(void)
 {
 	s3c_device_i2c.dev.platform_data = &n30_i2ccfg;
 
-	kthread_run(n30_usbstart_thread, NULL, "n30_usbstart");
+	/* Turn off suspend on both USB ports, and switch the
+	 * selectable USB port to USB device mode. */
+
+	s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+			      S3C2410_MISCCR_USBSUSPND0 |
+			      S3C2410_MISCCR_USBSUSPND1, 0x0);
 }
 
 MACHINE_START(N30, "Acer-N30")
-	/* Maintainer: Christer Weinigel <christer@weinigel.se>, Ben Dooks <ben-linux@fluff.org> */
+	/* Maintainer: Christer Weinigel <christer@weinigel.se>,
+				Ben Dooks <ben-linux@fluff.org>
+	*/
 	.phys_ram	= S3C2410_SDRAM_PA,
 	.phys_io	= S3C2410_PA_UART,
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
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/pm.c b/arch/arm/mach-s3c2410/pm.c
index 13a48ee77484..fe57d966a34d 100644
--- a/arch/arm/mach-s3c2410/pm.c
+++ b/arch/arm/mach-s3c2410/pm.c
@@ -585,14 +585,16 @@ static int s3c2410_pm_enter(suspend_state_t state)
 
 	s3c2410_pm_check_store();
 
-	// need to make some form of time-delta
-
 	/* send the cpu to sleep... */
 
 	__raw_writel(0x00, S3C2410_CLKCON);  /* turn off clocks over sleep */
 
 	s3c2410_cpu_suspend(regs_save);
 
+	/* restore the cpu state */
+
+	cpu_init();
+
 	/* unset the return-from-sleep flag, to ensure reset */
 
 	tmp = __raw_readl(S3C2410_GSTATUS2);
diff --git a/arch/arm/mach-s3c2410/s3c2440-irq.c b/arch/arm/mach-s3c2410/s3c2440-irq.c
index 7cb9912242a3..278d0044c85d 100644
--- a/arch/arm/mach-s3c2410/s3c2440-irq.c
+++ b/arch/arm/mach-s3c2410/s3c2440-irq.c
@@ -64,11 +64,11 @@ static void s3c_irq_demux_wdtac97(unsigned int irq,
 	if (subsrc != 0) {
 		if (subsrc & 1) {
 			mydesc = irq_desc + IRQ_S3C2440_WDT;
-			mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs);
+			desc_handle_irq(IRQ_S3C2440_WDT, mydesc, regs);
 		}
 		if (subsrc & 2) {
 			mydesc = irq_desc + IRQ_S3C2440_AC97;
-			mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs);
+			desc_handle_irq(IRQ_S3C2440_AC97, mydesc, regs);
 		}
 	}
 }
@@ -122,11 +122,11 @@ static void s3c_irq_demux_cam(unsigned int irq,
 	if (subsrc != 0) {
 		if (subsrc & 1) {
 			mydesc = irq_desc + IRQ_S3C2440_CAM_C;
-			mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs);
+			desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc, regs);
 		}
 		if (subsrc & 2) {
 			mydesc = irq_desc + IRQ_S3C2440_CAM_P;
-			mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs);
+			desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc, regs);
 		}
 	}
 }
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/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 66a929cb7bc5..c131a5201b5b 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -98,8 +98,8 @@ static struct irqchip sa1100_low_gpio_chip = {
 	.ack		= sa1100_low_gpio_ack,
 	.mask		= sa1100_low_gpio_mask,
 	.unmask		= sa1100_low_gpio_unmask,
-	.type		= sa1100_gpio_type,
-	.wake		= sa1100_low_gpio_wake,
+	.set_type	= sa1100_gpio_type,
+	.set_wake	= sa1100_low_gpio_wake,
 };
 
 /*
@@ -126,7 +126,7 @@ sa1100_high_gpio_handler(unsigned int irq, struct irqdesc *desc,
 		mask >>= 11;
 		do {
 			if (mask & 1)
-				desc->handle(irq, desc, regs);
+				desc_handle_irq(irq, desc, regs);
 			mask >>= 1;
 			irq++;
 			desc++;
@@ -181,8 +181,8 @@ static struct irqchip sa1100_high_gpio_chip = {
 	.ack		= sa1100_high_gpio_ack,
 	.mask		= sa1100_high_gpio_mask,
 	.unmask		= sa1100_high_gpio_unmask,
-	.type		= sa1100_gpio_type,
-	.wake		= sa1100_high_gpio_wake,
+	.set_type	= sa1100_gpio_type,
+	.set_wake	= sa1100_high_gpio_wake,
 };
 
 /*
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 1405383463ea..fc061641b7be 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -61,12 +61,12 @@ neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *reg
 
 			if (irr & IRR_ETHERNET) {
 				d = irq_desc + IRQ_NEPONSET_SMC9196;
-				d->handle(IRQ_NEPONSET_SMC9196, d, regs);
+				desc_handle_irq(IRQ_NEPONSET_SMC9196, d, regs);
 			}
 
 			if (irr & IRR_USAR) {
 				d = irq_desc + IRQ_NEPONSET_USAR;
-				d->handle(IRQ_NEPONSET_USAR, d, regs);
+				desc_handle_irq(IRQ_NEPONSET_USAR, d, regs);
 			}
 
 			desc->chip->unmask(irq);
@@ -74,7 +74,7 @@ neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *reg
 
 		if (irr & IRR_SA1111) {
 			d = irq_desc + IRQ_NEPONSET_SA1111;
-			d->handle(IRQ_NEPONSET_SA1111, d, regs);
+			desc_handle_irq(IRQ_NEPONSET_SA1111, d, regs);
 		}
 	}
 }
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index f01c0f8a2bb3..3c8862fde51a 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -108,7 +108,7 @@ sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
 		irq += IRQ_SIC_START;
 
 		desc = irq_desc + irq;
-		desc->handle(irq, desc, regs);
+		desc_handle_irq(irq, desc, regs);
 	} while (status);
 }
 
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 0ee214b824ff..189ef6a71ba1 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -38,8 +38,8 @@ ENTRY(cpu_arm7_data_abort)
 	mrc	p15, 0, r1, c5, c0, 0		@ get FSR
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
 	ldr	r8, [r0]			@ read arm instruction
-	tst	r8, #1 << 20			@ L = 1 -> write?
-	orreq	r1, r1, #1 << 8			@ yes.
+	tst	r8, #1 << 20			@ L = 0 -> write?
+	orreq	r1, r1, #1 << 11		@ yes.
 	and	r7, r8, #15 << 24
 	add	pc, pc, r7, lsr #22		@ Now branch to the relevant processing routine
 	nop
@@ -71,8 +71,8 @@ ENTRY(cpu_arm6_data_abort)
 	mrc	p15, 0, r1, c5, c0, 0		@ get FSR
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
 	ldr	r8, [r2]			@ read arm instruction
-	tst	r8, #1 << 20			@ L = 1 -> write?
-	orreq	r1, r1, #1 << 8			@ yes.
+	tst	r8, #1 << 20			@ L = 0 -> write?
+	orreq	r1, r1, #1 << 11		@ yes.
 	and	r7, r8, #14 << 24
 	teq	r7, #8 << 24			@ was it ldm/stm
 	movne	pc, lr
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 1c85b4e536c2..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;
-		d->handle(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.