Merge master.kernel.org:/home/rmk/linux-2.6-arm

* master.kernel.org:/home/rmk/linux-2.6-arm: (27 commits)
  [ARM] 3433/1: ARM: OMAP: 8/8 Update board files
  [ARM] 3455/1: ARM: OMAP: 7/8 Misc updates, take 2
  [ARM] 3454/1: ARM: OMAP: 6/8 Update framebuffer low-level init code, take 2
  [ARM] 3430/1: ARM: OMAP: 5/8 Update PM
  [ARM] 3429/1: ARM: OMAP: 4/8 Update GPIO
  [ARM] 3428/1: ARM: OMAP: 3/8 Update pin multiplexing
  [ARM] 3427/1: ARM: OMAP: 2/8 Update timers
  [ARM] 3426/1: ARM: OMAP: 1/8 Update clock framework
  [ARM] 3396/2: AT91RM9200 Platform devices update
  [ARM] 3395/2: AT91RM9200 Dataflash Card vs MMC selection
  [ARM] 3393/2: AT91RM9200 LED support
  [ARM] 3453/1: Poodle: Correctly set the memory size
  [ARM] 3446/1: i.MX: MMC/SD SDHC controller registration for i.MX/MX1 MX1ADS board
  [ARM] 3444/1: i.MX: Scatter-gather DMA emulation for i.MX/MX1
  [ARM] 3451/1: ep93xx: use the m48t86 rtc driver on the ts72xx platform
  [ARM] 3450/1: ep93xx: use the ep93xx rtc driver
  [ARM] 3452/1: [S3C2410] RX3715 - add nand information
  [ARM] 3449/1: [S3C2410] Anubis - fix NAND timings
  [ARM] 3448/1: [S3C2410] Settle delay when _enabling_ USB PLL
  [ARM] 3442/1: [S3C2410] SMDK: NAND device setup
  ...
diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig
index 1fe73d1..9e1c1cc 100644
--- a/arch/arm/configs/at91rm9200dk_defconfig
+++ b/arch/arm/configs/at91rm9200dk_defconfig
@@ -379,7 +379,7 @@
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
 CONFIG_MTD_AT91_DATAFLASH=y
-CONFIG_MTD_AT91_DATAFLASH_CARD=y
+# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
 
 #
 # NAND Flash Device Drivers
diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig
index b7d934c..6e0805a 100644
--- a/arch/arm/configs/at91rm9200ek_defconfig
+++ b/arch/arm/configs/at91rm9200ek_defconfig
@@ -370,7 +370,7 @@
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
 CONFIG_MTD_AT91_DATAFLASH=y
-CONFIG_MTD_AT91_DATAFLASH_CARD=y
+# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
 
 #
 # NAND Flash Device Drivers
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 1574941..ee083b3 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -100,23 +100,12 @@
 #endif
 
 	/* string / mem functions */
-EXPORT_SYMBOL(strcpy);
-EXPORT_SYMBOL(strncpy);
-EXPORT_SYMBOL(strcat);
-EXPORT_SYMBOL(strncat);
-EXPORT_SYMBOL(strcmp);
-EXPORT_SYMBOL(strncmp);
 EXPORT_SYMBOL(strchr);
-EXPORT_SYMBOL(strlen);
-EXPORT_SYMBOL(strnlen);
 EXPORT_SYMBOL(strpbrk);
 EXPORT_SYMBOL(strrchr);
-EXPORT_SYMBOL(strstr);
 EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memmove);
-EXPORT_SYMBOL(memcmp);
-EXPORT_SYMBOL(memscan);
 EXPORT_SYMBOL(memchr);
 EXPORT_SYMBOL(__memzero);
 
@@ -190,8 +179,6 @@
 
 	/* syscalls */
 EXPORT_SYMBOL(sys_write);
-EXPORT_SYMBOL(sys_read);
 EXPORT_SYMBOL(sys_lseek);
-EXPORT_SYMBOL(sys_open);
 EXPORT_SYMBOL(sys_exit);
 EXPORT_SYMBOL(sys_wait4);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index b7cd280..4375284 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -252,6 +252,9 @@
 			dump_cache("cache", cpu, CACHE_ISIZE(info));
 		}
 	}
+
+	if (arch_is_coherent())
+		printk("Cache coherency enabled\n");
 }
 
 int cpu_architecture(void)
diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile
index 75e6ee3..ef88c41 100644
--- a/arch/arm/mach-at91rm9200/Makefile
+++ b/arch/arm/mach-at91rm9200/Makefile
@@ -16,11 +16,12 @@
 #obj-$(CONFIG_MACH_KB9200)	+= board-kb9202.o
 
 # LEDs support
-#led-$(CONFIG_ARCH_AT91RM9200DK)	+= leds.o
-#led-$(CONFIG_MACH_AT91RM9200EK)	+= leds.o
-#led-$(CONFIG_MACH_CSB337)	+= leds.o
-#led-$(CONFIG_MACH_CSB637)	+= leds.o
+led-$(CONFIG_ARCH_AT91RM9200DK)	+= leds.o
+led-$(CONFIG_MACH_AT91RM9200EK)	+= leds.o
+led-$(CONFIG_MACH_CSB337)	+= leds.o
+led-$(CONFIG_MACH_CSB637)	+= leds.o
 #led-$(CONFIG_MACH_KB9200)	+= leds.o
+#led-$(CONFIG_MACH_KAFA)	+= leds.o
 obj-$(CONFIG_LEDS) += $(led-y)
 
 # VGA support
diff --git a/arch/arm/mach-at91rm9200/board-csb337.c b/arch/arm/mach-at91rm9200/board-csb337.c
index 54022e5..f45104c 100644
--- a/arch/arm/mach-at91rm9200/board-csb337.c
+++ b/arch/arm/mach-at91rm9200/board-csb337.c
@@ -67,6 +67,9 @@
 	/* Initialize clocks: 3.6864 MHz crystal */
 	at91_clock_init(3686400);
 
+	/* Setup the LEDs */
+	at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
+
 #ifdef CONFIG_SERIAL_AT91
 	at91_console_port = CSB337_SERIAL_CONSOLE;
 	memcpy(at91_serial_map, serial, sizeof(serial));
diff --git a/arch/arm/mach-at91rm9200/board-csb637.c b/arch/arm/mach-at91rm9200/board-csb637.c
index 8195f9d..f2c2d6e 100644
--- a/arch/arm/mach-at91rm9200/board-csb637.c
+++ b/arch/arm/mach-at91rm9200/board-csb637.c
@@ -67,6 +67,9 @@
 	/* Initialize clocks: 3.6864 MHz crystal */
 	at91_clock_init(3686400);
 
+	/* Setup the LEDs */
+	at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
+
 #ifdef CONFIG_SERIAL_AT91
 	at91_console_port = CSB637_SERIAL_CONSOLE;
 	memcpy(at91_serial_map, serial, sizeof(serial));
diff --git a/arch/arm/mach-at91rm9200/board-dk.c b/arch/arm/mach-at91rm9200/board-dk.c
index 8a78336..2d7200e 100644
--- a/arch/arm/mach-at91rm9200/board-dk.c
+++ b/arch/arm/mach-at91rm9200/board-dk.c
@@ -70,6 +70,9 @@
 	/* Initialize clocks: 18.432 MHz crystal */
 	at91_clock_init(18432000);
 
+	/* Setup the LEDs */
+	at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
+
 #ifdef CONFIG_SERIAL_AT91
 	at91_console_port = DK_SERIAL_CONSOLE;
 	memcpy(at91_serial_map, serial, sizeof(serial));
@@ -118,9 +121,14 @@
 	at91_add_device_udc(&dk_udc_data);
 	/* Compact Flash */
 	at91_add_device_cf(&dk_cf_data);
+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+	/* DataFlash card */
+	at91_set_gpio_output(AT91_PIN_PB7, 0);
+#else
 	/* MMC */
-	at91_set_gpio_output(AT91_PIN_PB7, 1);	/* this MMC card slot can optionally use SPI signaling (CS3). default: MMC */
+	at91_set_gpio_output(AT91_PIN_PB7, 1);	/* this MMC card slot can optionally use SPI signaling (CS3). */
 	at91_add_device_mmc(&dk_mmc_data);
+#endif
 	/* VGA */
 //	dk_add_device_video();
 }
diff --git a/arch/arm/mach-at91rm9200/board-ek.c b/arch/arm/mach-at91rm9200/board-ek.c
index fd0752e..80d90f5 100644
--- a/arch/arm/mach-at91rm9200/board-ek.c
+++ b/arch/arm/mach-at91rm9200/board-ek.c
@@ -70,6 +70,9 @@
 	/* Initialize clocks: 18.432 MHz crystal */
 	at91_clock_init(18432000);
 
+	/* Setup the LEDs */
+	at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2);
+
 #ifdef CONFIG_SERIAL_AT91
 	at91_console_port = EK_SERIAL_CONSOLE;
 	memcpy(at91_serial_map, serial, sizeof(serial));
@@ -111,9 +114,14 @@
 	at91_add_device_usbh(&ek_usbh_data);
 	/* USB Device */
 	at91_add_device_udc(&ek_udc_data);
+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+	/* DataFlash card */
+	at91_set_gpio_output(AT91_PIN_PB22, 0);
+#else
 	/* MMC */
-	at91_set_gpio_output(AT91_PIN_PB22, 1);	/* this MMC card slot can optionally use SPI signaling (CS3). default: MMC */
+	at91_set_gpio_output(AT91_PIN_PB22, 1);	/* this MMC card slot can optionally use SPI signaling (CS3). */
 	at91_add_device_mmc(&ek_mmc_data);
+#endif
 	/* VGA */
 //	ek_add_device_video();
 }
diff --git a/arch/arm/mach-at91rm9200/devices.c b/arch/arm/mach-at91rm9200/devices.c
index 57eedd5..1781b8f 100644
--- a/arch/arm/mach-at91rm9200/devices.c
+++ b/arch/arm/mach-at91rm9200/devices.c
@@ -28,10 +28,10 @@
 static u64 ohci_dmamask = 0xffffffffUL;
 static struct at91_usbh_data usbh_data;
 
-static struct resource at91rm9200_usbh_resource[] = {
+static struct resource at91_usbh_resource[] = {
 	[0] = {
 		.start	= AT91_UHP_BASE,
-		.end	= AT91_UHP_BASE + SZ_1M -1,
+		.end	= AT91_UHP_BASE + SZ_1M - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -49,8 +49,8 @@
 				.coherent_dma_mask	= 0xffffffff,
 				.platform_data		= &usbh_data,
 	},
-	.resource	= at91rm9200_usbh_resource,
-	.num_resources	= ARRAY_SIZE(at91rm9200_usbh_resource),
+	.resource	= at91_usbh_resource,
+	.num_resources	= ARRAY_SIZE(at91_usbh_resource),
 };
 
 void __init at91_add_device_usbh(struct at91_usbh_data *data)
@@ -121,6 +121,19 @@
 static u64 eth_dmamask = 0xffffffffUL;
 static struct at91_eth_data eth_data;
 
+static struct resource at91_eth_resources[] = {
+	[0] = {
+		.start	= AT91_BASE_EMAC,
+		.end	= AT91_BASE_EMAC + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91_ID_EMAC,
+		.end	= AT91_ID_EMAC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
 static struct platform_device at91rm9200_eth_device = {
 	.name		= "at91_ether",
 	.id		= -1,
@@ -129,7 +142,8 @@
 				.coherent_dma_mask	= 0xffffffff,
 				.platform_data		= &eth_data,
 	},
-	.num_resources	= 0,
+	.resource	= at91_eth_resources,
+	.num_resources	= ARRAY_SIZE(at91_eth_resources),
 };
 
 void __init at91_add_device_eth(struct at91_eth_data *data)
@@ -224,15 +238,20 @@
 static struct at91_mmc_data mmc_data;
 
 static struct resource at91_mmc_resources[] = {
-	{
+	[0] = {
 		.start	= AT91_BASE_MCI,
 		.end	= AT91_BASE_MCI + SZ_16K - 1,
 		.flags	= IORESOURCE_MEM,
-	}
+	},
+	[1] = {
+		.start	= AT91_ID_MCI,
+		.end	= AT91_ID_MCI,
+		.flags	= IORESOURCE_IRQ,
+	},
 };
 
 static struct platform_device at91rm9200_mmc_device = {
-	.name		= "at91rm9200_mci",
+	.name		= "at91_mci",
 	.id		= -1,
 	.dev		= {
 				.dma_mask		= &mmc_dmamask,
@@ -290,4 +309,123 @@
 void __init at91_add_device_mmc(struct at91_mmc_data *data) {}
 #endif
 
+/* --------------------------------------------------------------------
+ *  NAND / SmartMedia
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE)
+static struct at91_nand_data nand_data;
+
+static struct resource at91_nand_resources[] = {
+	{
+		.start	= AT91_SMARTMEDIA_BASE,
+		.end	= AT91_SMARTMEDIA_BASE + SZ_8M - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device at91_nand_device = {
+	.name		= "at91_nand",
+	.id		= -1,
+	.dev		= {
+				.platform_data	= &nand_data,
+	},
+	.resource	= at91_nand_resources,
+	.num_resources	= ARRAY_SIZE(at91_nand_resources),
+};
+
+void __init at91_add_device_nand(struct at91_nand_data *data)
+{
+	if (!data)
+		return;
+
+	/* enable pin */
+	if (data->enable_pin)
+		at91_set_gpio_output(data->enable_pin, 1);
+
+	/* ready/busy pin */
+	if (data->rdy_pin)
+		at91_set_gpio_input(data->rdy_pin, 1);
+
+	/* card detect pin */
+	if (data->det_pin)
+		at91_set_gpio_input(data->det_pin, 1);
+
+	at91_set_A_periph(AT91_PIN_PC1, 0);		/* SMOE */
+	at91_set_A_periph(AT91_PIN_PC3, 0);		/* SMWE */
+
+	nand_data = *data;
+	platform_device_register(&at91_nand_device);
+}
+#else
+void __init at91_add_device_nand(struct at91_nand_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  TWI (i2c)
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+static struct platform_device at91rm9200_twi_device = {
+	.name		= "at91_i2c",
+	.id		= -1,
+	.num_resources	= 0,
+};
+
+void __init at91_add_device_i2c(void)
+{
+	/* pins used for TWI interface */
+	at91_set_A_periph(AT91_PIN_PA25, 0);		/* TWD */
+	at91_set_multi_drive(AT91_PIN_PA25, 1);
+
+	at91_set_A_periph(AT91_PIN_PA26, 0);		/* TWCK */
+	at91_set_multi_drive(AT91_PIN_PA26, 1);
+
+	platform_device_register(&at91rm9200_twi_device);
+}
+#else
+void __init at91_add_device_i2c(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  RTC
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91_RTC) || defined(CONFIG_AT91_RTC_MODULE)
+static struct platform_device at91rm9200_rtc_device = {
+	.name		= "at91_rtc",
+	.id		= -1,
+	.num_resources	= 0,
+};
+
+void __init at91_add_device_rtc(void)
+{
+	platform_device_register(&at91rm9200_rtc_device);
+}
+#else
+void __init at91_add_device_rtc(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  LEDs
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_LEDS)
+u8 at91_leds_cpu;
+u8 at91_leds_timer;
+
+void __init at91_init_leds(u8 cpu_led, u8 timer_led)
+{
+	at91_leds_cpu   = cpu_led;
+	at91_leds_timer = timer_led;
+}
+
+#else
+void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
+#endif
+
+
 /* -------------------------------------------------------------------- */
diff --git a/arch/arm/mach-at91rm9200/leds.c b/arch/arm/mach-at91rm9200/leds.c
new file mode 100644
index 0000000..28150e8
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/leds.c
@@ -0,0 +1,100 @@
+/*
+ * LED driver for Atmel AT91-based boards.
+ *
+ *  Copyright (C) SAN People (Pty) Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+*/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <asm/mach-types.h>
+#include <asm/leds.h>
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+
+
+static inline void at91_led_on(unsigned int led)
+{
+	at91_set_gpio_value(led, 0);
+}
+
+static inline void at91_led_off(unsigned int led)
+{
+	at91_set_gpio_value(led, 1);
+}
+
+static inline void at91_led_toggle(unsigned int led)
+{
+	unsigned long is_off = at91_get_gpio_value(led);
+	if (is_off)
+		at91_led_on(led);
+	else
+		at91_led_off(led);
+}
+
+
+/*
+ * Handle LED events.
+ */
+static void at91_leds_event(led_event_t evt)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	switch(evt) {
+	case led_start:		/* System startup */
+		at91_led_on(at91_leds_cpu);
+		break;
+
+	case led_stop:		/* System stop / suspend */
+		at91_led_off(at91_leds_cpu);
+		break;
+
+#ifdef CONFIG_LEDS_TIMER
+	case led_timer:		/* Every 50 timer ticks */
+		at91_led_toggle(at91_leds_timer);
+		break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+	case led_idle_start:	/* Entering idle state */
+		at91_led_off(at91_leds_cpu);
+		break;
+
+	case led_idle_end:	/* Exit idle state */
+		at91_led_on(at91_leds_cpu);
+		break;
+#endif
+
+	default:
+		break;
+	}
+
+	local_irq_restore(flags);
+}
+
+
+static int __init leds_init(void)
+{
+	if (!at91_leds_timer || !at91_leds_cpu)
+		return -ENODEV;
+
+	/* Enable PIO to access the LEDs */
+	at91_set_gpio_output(at91_leds_timer, 1);
+	at91_set_gpio_output(at91_leds_cpu, 1);
+
+	leds_event = at91_leds_event;
+
+	leds_event(led_start);
+	return 0;
+}
+
+__initcall(leds_init);
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 2d892e4..dcd4176 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -424,6 +424,14 @@
 	.periphid	= 0x00041010,
 };
 
+
+static struct platform_device ep93xx_rtc_device = {
+       .name           = "ep93xx-rtc",
+       .id             = -1,
+       .num_resources  = 0,
+};
+
+
 void __init ep93xx_init_devices(void)
 {
 	unsigned int v;
@@ -439,4 +447,6 @@
 	amba_device_register(&uart1_device, &iomem_resource);
 	amba_device_register(&uart2_device, &iomem_resource);
 	amba_device_register(&uart3_device, &iomem_resource);
+
+	platform_device_register(&ep93xx_rtc_device);
 }
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index 777e75d..9be01b0c 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -17,6 +17,8 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/m48t86.h>
 #include <asm/io.h>
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
@@ -39,6 +41,16 @@
 		.pfn		= __phys_to_pfn(TS72XX_OPTIONS2_PHYS_BASE),
 		.length		= TS72XX_OPTIONS2_SIZE,
 		.type		= MT_DEVICE,
+	}, {
+		.virtual	= TS72XX_RTC_INDEX_VIRT_BASE,
+		.pfn		= __phys_to_pfn(TS72XX_RTC_INDEX_PHYS_BASE),
+		.length		= TS72XX_RTC_INDEX_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= TS72XX_RTC_DATA_VIRT_BASE,
+		.pfn		= __phys_to_pfn(TS72XX_RTC_DATA_PHYS_BASE),
+		.length		= TS72XX_RTC_DATA_SIZE,
+		.type		= MT_DEVICE,
 	}
 };
 
@@ -99,11 +111,38 @@
 	}
 }
 
+static unsigned char ts72xx_rtc_readb(unsigned long addr)
+{
+	__raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
+	return __raw_readb(TS72XX_RTC_DATA_VIRT_BASE);
+}
+
+static void ts72xx_rtc_writeb(unsigned char value, unsigned long addr)
+{
+	__raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
+	__raw_writeb(value, TS72XX_RTC_DATA_VIRT_BASE);
+}
+
+static struct m48t86_ops ts72xx_rtc_ops = {
+	.readb			= ts72xx_rtc_readb,
+	.writeb			= ts72xx_rtc_writeb,
+};
+
+static struct platform_device ts72xx_rtc_device = {
+	.name			= "rtc-m48t86",
+	.id			= -1,
+	.dev			= {
+		.platform_data		= &ts72xx_rtc_ops,
+	},
+	.num_resources		= 0,
+};
+
 static void __init ts72xx_init_machine(void)
 {
 	ep93xx_init_devices();
 	if (board_is_ts7200())
 		physmap_configure(TS72XX_NOR_PHYS_BASE, 0x01000000, 1, NULL);
+	platform_device_register(&ts72xx_rtc_device);
 }
 
 MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
diff --git a/arch/arm/mach-imx/dma.c b/arch/arm/mach-imx/dma.c
index 71a59e1..4ca51dc 100644
--- a/arch/arm/mach-imx/dma.c
+++ b/arch/arm/mach-imx/dma.c
@@ -7,11 +7,18 @@
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
  *
- *  03/03/2004 Sascha Hauer <sascha@saschahauer.de>
+ *  2004-03-03 Sascha Hauer <sascha@saschahauer.de>
  *             initial version heavily inspired by
  *             linux/arch/arm/mach-pxa/dma.c
+ *
+ *  2005-04-17 Pavel Pisa <pisa@cmp.felk.cvut.cz>
+ *             Changed to support scatter gather DMA
+ *             by taking Russell's code from RiscPC
+ *
  */
 
+#undef DEBUG
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -22,69 +29,368 @@
 #include <asm/irq.h>
 #include <asm/hardware.h>
 #include <asm/dma.h>
+#include <asm/arch/imx-dma.h>
 
-static struct dma_channel {
-	char *name;
-	void (*irq_handler) (int, void *, struct pt_regs *);
-	void (*err_handler) (int, void *, struct pt_regs *);
-	void *data;
-} dma_channels[11];
+struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS];
 
-/* set err_handler to NULL to have the standard info-only error handler */
-int
-imx_request_dma(char *name, imx_dma_prio prio,
-		void (*irq_handler) (int, void *, struct pt_regs *),
-		void (*err_handler) (int, void *, struct pt_regs *), void *data)
+/*
+ * imx_dma_sg_next - prepare next chunk for scatter-gather DMA emulation
+ * @dma_ch: i.MX DMA channel number
+ * @lastcount: number of bytes transferred during last transfer
+ *
+ * Functions prepares DMA controller for next sg data chunk transfer.
+ * The @lastcount argument informs function about number of bytes transferred
+ * during last block. Zero value can be used for @lastcount to setup DMA
+ * for the first chunk.
+ */
+static inline int imx_dma_sg_next(imx_dmach_t dma_ch, unsigned int lastcount)
 {
-	unsigned long flags;
-	int i, found = 0;
+	struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
+	unsigned int nextcount;
+	unsigned int nextaddr;
 
-	/* basic sanity checks */
-	if (!name || !irq_handler)
-		return -EINVAL;
+	if (!imxdma->name) {
+		printk(KERN_CRIT "%s: called for  not allocated channel %d\n",
+		       __FUNCTION__, dma_ch);
+		return 0;
+	}
 
-	local_irq_save(flags);
+	imxdma->resbytes -= lastcount;
 
-	/* try grabbing a DMA channel with the requested priority */
-	for (i = prio; i < prio + (prio == DMA_PRIO_LOW) ? 8 : 4; i++) {
-		if (!dma_channels[i].name) {
-			found = 1;
-			break;
+	if (!imxdma->sg) {
+		pr_debug("imxdma%d: no sg data\n", dma_ch);
+		return 0;
+	}
+
+	imxdma->sgbc += lastcount;
+	if ((imxdma->sgbc >= imxdma->sg->length) || !imxdma->resbytes) {
+		if ((imxdma->sgcount <= 1) || !imxdma->resbytes) {
+			pr_debug("imxdma%d: sg transfer limit reached\n",
+				 dma_ch);
+			imxdma->sgcount=0;
+			imxdma->sg = NULL;
+			return 0;
+		} else {
+			imxdma->sgcount--;
+			imxdma->sg++;
+			imxdma->sgbc = 0;
 		}
 	}
+	nextcount = imxdma->sg->length - imxdma->sgbc;
+	nextaddr = imxdma->sg->dma_address + imxdma->sgbc;
 
-	if (!found) {
-		/* requested prio group is full, try hier priorities */
-		for (i = prio - 1; i >= 0; i--) {
-			if (!dma_channels[i].name) {
-				found = 1;
-				break;
-			}
-		}
-	}
+	if(imxdma->resbytes < nextcount)
+		nextcount = imxdma->resbytes;
 
-	if (found) {
-		DIMR &= ~(1 << i);
-		dma_channels[i].name = name;
-		dma_channels[i].irq_handler = irq_handler;
-		dma_channels[i].err_handler = err_handler;
-		dma_channels[i].data = data;
-	} else {
-		printk(KERN_WARNING "No more available DMA channels for %s\n",
-		       name);
-		i = -ENODEV;
-	}
+	if ((imxdma->dma_mode & DMA_MODE_MASK) == DMA_MODE_READ)
+		DAR(dma_ch) = nextaddr;
+	else
+		SAR(dma_ch) = nextaddr;
 
-	local_irq_restore(flags);
-	return i;
+	CNTR(dma_ch) = nextcount;
+	pr_debug("imxdma%d: next sg chunk dst 0x%08x, src 0x%08x, size 0x%08x\n",
+		 dma_ch, DAR(dma_ch), SAR(dma_ch), CNTR(dma_ch));
+
+	return nextcount;
 }
 
-void
-imx_free_dma(int dma_ch)
+/*
+ * imx_dma_setup_sg_base - scatter-gather DMA emulation
+ * @dma_ch: i.MX DMA channel number
+ * @sg: pointer to the scatter-gather list/vector
+ * @sgcount: scatter-gather list hungs count
+ *
+ * Functions sets up i.MX DMA state for emulated scatter-gather transfer
+ * and sets up channel registers to be ready for the first chunk
+ */
+static int
+imx_dma_setup_sg_base(imx_dmach_t dma_ch,
+		      struct scatterlist *sg, unsigned int sgcount)
+{
+	struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
+
+	imxdma->sg = sg;
+	imxdma->sgcount = sgcount;
+	imxdma->sgbc = 0;
+	return imx_dma_sg_next(dma_ch, 0);
+}
+
+/**
+ * imx_dma_setup_single - setup i.MX DMA channel for linear memory to/from device transfer
+ * @dma_ch: i.MX DMA channel number
+ * @dma_address: the DMA/physical memory address of the linear data block
+ *		to transfer
+ * @dma_length: length of the data block in bytes
+ * @dev_addr: physical device port address
+ * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory
+ *           or %DMA_MODE_WRITE from memory to the device
+ *
+ * The function setups DMA channel source and destination addresses for transfer
+ * specified by provided parameters. The scatter-gather emulation is disabled,
+ * because linear data block
+ * form the physical address range is transfered.
+ * Return value: if incorrect parameters are provided -%EINVAL.
+ *		Zero indicates success.
+ */
+int
+imx_dma_setup_single(imx_dmach_t dma_ch, dma_addr_t dma_address,
+		     unsigned int dma_length, unsigned int dev_addr,
+		     dmamode_t dmamode)
+{
+	struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
+
+	imxdma->sg = NULL;
+	imxdma->sgcount = 0;
+	imxdma->dma_mode = dmamode;
+	imxdma->resbytes = dma_length;
+
+	if (!dma_address) {
+		printk(KERN_ERR "imxdma%d: imx_dma_setup_single null address\n",
+		       dma_ch);
+		return -EINVAL;
+	}
+
+	if (!dma_length) {
+		printk(KERN_ERR "imxdma%d: imx_dma_setup_single zero length\n",
+		       dma_ch);
+		return -EINVAL;
+	}
+
+	if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) {
+		pr_debug("imxdma%d: mx_dma_setup_single2dev dma_addressg=0x%08x dma_length=%d dev_addr=0x%08x for read\n",
+			dma_ch, (unsigned int)dma_address, dma_length,
+			dev_addr);
+		SAR(dma_ch) = dev_addr;
+		DAR(dma_ch) = (unsigned int)dma_address;
+	} else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
+		pr_debug("imxdma%d: mx_dma_setup_single2dev dma_addressg=0x%08x dma_length=%d dev_addr=0x%08x for write\n",
+			dma_ch, (unsigned int)dma_address, dma_length,
+			dev_addr);
+		SAR(dma_ch) = (unsigned int)dma_address;
+		DAR(dma_ch) = dev_addr;
+	} else {
+		printk(KERN_ERR "imxdma%d: imx_dma_setup_single bad dmamode\n",
+		       dma_ch);
+		return -EINVAL;
+	}
+
+	CNTR(dma_ch) = dma_length;
+
+	return 0;
+}
+
+/**
+ * imx_dma_setup_sg - setup i.MX DMA channel SG list to/from device transfer
+ * @dma_ch: i.MX DMA channel number
+ * @sg: pointer to the scatter-gather list/vector
+ * @sgcount: scatter-gather list hungs count
+ * @dma_length: total length of the transfer request in bytes
+ * @dev_addr: physical device port address
+ * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory
+ *           or %DMA_MODE_WRITE from memory to the device
+ *
+ * The function setups DMA channel state and registers to be ready for transfer
+ * specified by provided parameters. The scatter-gather emulation is set up
+ * according to the parameters.
+ *
+ * The full preparation of the transfer requires setup of more register
+ * by the caller before imx_dma_enable() can be called.
+ *
+ * %BLR(dma_ch) holds transfer burst length in bytes, 0 means 64 bytes
+ *
+ * %RSSR(dma_ch) has to be set to the DMA request line source %DMA_REQ_xxx
+ *
+ * %CCR(dma_ch) has to specify transfer parameters, the next settings is typical
+ * for linear or simple scatter-gather transfers if %DMA_MODE_READ is specified
+ *
+ * %CCR_DMOD_LINEAR | %CCR_DSIZ_32 | %CCR_SMOD_FIFO | %CCR_SSIZ_x
+ *
+ * The typical setup for %DMA_MODE_WRITE is specified by next options combination
+ *
+ * %CCR_SMOD_LINEAR | %CCR_SSIZ_32 | %CCR_DMOD_FIFO | %CCR_DSIZ_x
+ *
+ * Be carefull there and do not mistakenly mix source and target device
+ * port sizes constants, they are really different:
+ * %CCR_SSIZ_8, %CCR_SSIZ_16, %CCR_SSIZ_32,
+ * %CCR_DSIZ_8, %CCR_DSIZ_16, %CCR_DSIZ_32
+ *
+ * Return value: if incorrect parameters are provided -%EINVAL.
+ * Zero indicates success.
+ */
+int
+imx_dma_setup_sg(imx_dmach_t dma_ch,
+		 struct scatterlist *sg, unsigned int sgcount, unsigned int dma_length,
+		 unsigned int dev_addr, dmamode_t dmamode)
+{
+	int res;
+	struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
+
+	imxdma->sg = NULL;
+	imxdma->sgcount = 0;
+	imxdma->dma_mode = dmamode;
+	imxdma->resbytes = dma_length;
+
+	if (!sg || !sgcount) {
+		printk(KERN_ERR "imxdma%d: imx_dma_setup_sg epty sg list\n",
+		       dma_ch);
+		return -EINVAL;
+	}
+
+	if (!sg->length) {
+		printk(KERN_ERR "imxdma%d: imx_dma_setup_sg zero length\n",
+		       dma_ch);
+		return -EINVAL;
+	}
+
+	if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) {
+		pr_debug("imxdma%d: mx_dma_setup_sg2dev sg=%p sgcount=%d total length=%d dev_addr=0x%08x for read\n",
+			dma_ch, sg, sgcount, dma_length, dev_addr);
+		SAR(dma_ch) = dev_addr;
+	} else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
+		pr_debug("imxdma%d: mx_dma_setup_sg2dev sg=%p sgcount=%d total length=%d dev_addr=0x%08x for write\n",
+			dma_ch, sg, sgcount, dma_length, dev_addr);
+		DAR(dma_ch) = dev_addr;
+	} else {
+		printk(KERN_ERR "imxdma%d: imx_dma_setup_sg bad dmamode\n",
+		       dma_ch);
+		return -EINVAL;
+	}
+
+	res = imx_dma_setup_sg_base(dma_ch, sg, sgcount);
+	if (res <= 0) {
+		printk(KERN_ERR "imxdma%d: no sg chunk ready\n", dma_ch);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * imx_dma_setup_handlers - setup i.MX DMA channel end and error notification handlers
+ * @dma_ch: i.MX DMA channel number
+ * @irq_handler: the pointer to the function called if the transfer
+ *		ends successfully
+ * @err_handler: the pointer to the function called if the premature
+ *		end caused by error occurs
+ * @data: user specified value to be passed to the handlers
+ */
+int
+imx_dma_setup_handlers(imx_dmach_t dma_ch,
+		       void (*irq_handler) (int, void *, struct pt_regs *),
+		       void (*err_handler) (int, void *, struct pt_regs *),
+		       void *data)
+{
+	struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
+	unsigned long flags;
+
+	if (!imxdma->name) {
+		printk(KERN_CRIT "%s: called for  not allocated channel %d\n",
+		       __FUNCTION__, dma_ch);
+		return -ENODEV;
+	}
+
+	local_irq_save(flags);
+	DISR = (1 << dma_ch);
+	imxdma->irq_handler = irq_handler;
+	imxdma->err_handler = err_handler;
+	imxdma->data = data;
+	local_irq_restore(flags);
+	return 0;
+}
+
+/**
+ * imx_dma_enable - function to start i.MX DMA channel operation
+ * @dma_ch: i.MX DMA channel number
+ *
+ * The channel has to be allocated by driver through imx_dma_request()
+ * or imx_dma_request_by_prio() function.
+ * The transfer parameters has to be set to the channel registers through
+ * call of the imx_dma_setup_single() or imx_dma_setup_sg() function
+ * and registers %BLR(dma_ch), %RSSR(dma_ch) and %CCR(dma_ch) has to
+ * be set prior this function call by the channel user.
+ */
+void imx_dma_enable(imx_dmach_t dma_ch)
+{
+	struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
+	unsigned long flags;
+
+	pr_debug("imxdma%d: imx_dma_enable\n", dma_ch);
+
+	if (!imxdma->name) {
+		printk(KERN_CRIT "%s: called for  not allocated channel %d\n",
+		       __FUNCTION__, dma_ch);
+		return;
+	}
+
+	local_irq_save(flags);
+	DISR = (1 << dma_ch);
+	DIMR &= ~(1 << dma_ch);
+	CCR(dma_ch) |= CCR_CEN;
+	local_irq_restore(flags);
+}
+
+/**
+ * imx_dma_disable - stop, finish i.MX DMA channel operatin
+ * @dma_ch: i.MX DMA channel number
+ */
+void imx_dma_disable(imx_dmach_t dma_ch)
 {
 	unsigned long flags;
 
-	if (!dma_channels[dma_ch].name) {
+	pr_debug("imxdma%d: imx_dma_disable\n", dma_ch);
+
+	local_irq_save(flags);
+	DIMR |= (1 << dma_ch);
+	CCR(dma_ch) &= ~CCR_CEN;
+	DISR = (1 << dma_ch);
+	local_irq_restore(flags);
+}
+
+/**
+ * imx_dma_request - request/allocate specified channel number
+ * @dma_ch: i.MX DMA channel number
+ * @name: the driver/caller own non-%NULL identification
+ */
+int imx_dma_request(imx_dmach_t dma_ch, const char *name)
+{
+	struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
+	unsigned long flags;
+
+	/* basic sanity checks */
+	if (!name)
+		return -EINVAL;
+
+	if (dma_ch >= IMX_DMA_CHANNELS) {
+		printk(KERN_CRIT "%s: called for  non-existed channel %d\n",
+		       __FUNCTION__, dma_ch);
+		return -EINVAL;
+	}
+
+	local_irq_save(flags);
+	if (imxdma->name) {
+		local_irq_restore(flags);
+		return -ENODEV;
+	}
+
+	imxdma->name = name;
+	imxdma->irq_handler = NULL;
+	imxdma->err_handler = NULL;
+	imxdma->data = NULL;
+	imxdma->sg = NULL;
+	local_irq_restore(flags);
+	return 0;
+}
+
+/**
+ * imx_dma_free - release previously acquired channel
+ * @dma_ch: i.MX DMA channel number
+ */
+void imx_dma_free(imx_dmach_t dma_ch)
+{
+	unsigned long flags;
+	struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
+
+	if (!imxdma->name) {
 		printk(KERN_CRIT
 		       "%s: trying to free channel %d which is already freed\n",
 		       __FUNCTION__, dma_ch);
@@ -92,27 +398,84 @@
 	}
 
 	local_irq_save(flags);
-	DIMR &= ~(1 << dma_ch);
-	dma_channels[dma_ch].name = NULL;
+	/* Disable interrupts */
+	DIMR |= (1 << dma_ch);
+	CCR(dma_ch) &= ~CCR_CEN;
+	imxdma->name = NULL;
 	local_irq_restore(flags);
 }
 
-static irqreturn_t
-dma_err_handler(int irq, void *dev_id, struct pt_regs *regs)
+/**
+ * imx_dma_request_by_prio - find and request some of free channels best suiting requested priority
+ * @dma_ch: i.MX DMA channel number
+ * @name: the driver/caller own non-%NULL identification
+ * @prio: one of the hardware distinguished priority level:
+ *        %DMA_PRIO_HIGH, %DMA_PRIO_MEDIUM, %DMA_PRIO_LOW
+ *
+ * This function tries to find free channel in the specified priority group
+ * if the priority cannot be achieved it tries to look for free channel
+ * in the higher and then even lower priority groups.
+ *
+ * Return value: If there is no free channel to allocate, -%ENODEV is returned.
+ *               Zero value indicates successful channel allocation.
+ */
+int
+imx_dma_request_by_prio(imx_dmach_t * pdma_ch, const char *name,
+			imx_dma_prio prio)
+{
+	int i;
+	int best;
+
+	switch (prio) {
+	case (DMA_PRIO_HIGH):
+		best = 8;
+		break;
+	case (DMA_PRIO_MEDIUM):
+		best = 4;
+		break;
+	case (DMA_PRIO_LOW):
+	default:
+		best = 0;
+		break;
+	}
+
+	for (i = best; i < IMX_DMA_CHANNELS; i++) {
+		if (!imx_dma_request(i, name)) {
+			*pdma_ch = i;
+			return 0;
+		}
+	}
+
+	for (i = best - 1; i >= 0; i--) {
+		if (!imx_dma_request(i, name)) {
+			*pdma_ch = i;
+			return 0;
+		}
+	}
+
+	printk(KERN_ERR "%s: no free DMA channel found\n", __FUNCTION__);
+
+	return -ENODEV;
+}
+
+static irqreturn_t dma_err_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
 	int i, disr = DISR;
-	struct dma_channel *channel;
+	struct imx_dma_channel *channel;
 	unsigned int err_mask = DBTOSR | DRTOSR | DSESR | DBOSR;
 
 	DISR = disr;
-	for (i = 0; i < 11; i++) {
-		channel = &dma_channels[i];
+	for (i = 0; i < IMX_DMA_CHANNELS; i++) {
+		channel = &imx_dma_channels[i];
 
-		if ( (err_mask & 1<<i) && channel->name && channel->err_handler) {
+		if ((err_mask & 1 << i) && channel->name
+		    && channel->err_handler) {
 			channel->err_handler(i, channel->data, regs);
 			continue;
 		}
 
+		imx_dma_channels[i].sg = NULL;
+
 		if (DBTOSR & (1 << i)) {
 			printk(KERN_WARNING
 			       "Burst timeout on channel %d (%s)\n",
@@ -141,17 +504,27 @@
 	return IRQ_HANDLED;
 }
 
-static irqreturn_t
-dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
 	int i, disr = DISR;
 
+	pr_debug("imxdma: dma_irq_handler called, disr=0x%08x\n",
+		     disr);
+
 	DISR = disr;
-	for (i = 0; i < 11; i++) {
+	for (i = 0; i < IMX_DMA_CHANNELS; i++) {
 		if (disr & (1 << i)) {
-			struct dma_channel *channel = &dma_channels[i];
-			if (channel->name && channel->irq_handler) {
-				channel->irq_handler(i, channel->data, regs);
+			struct imx_dma_channel *channel = &imx_dma_channels[i];
+			if (channel->name) {
+				if (imx_dma_sg_next(i, CNTR(i))) {
+					CCR(i) &= ~CCR_CEN;
+					mb();
+					CCR(i) |= CCR_CEN;
+				} else {
+					if (channel->irq_handler)
+						channel->irq_handler(i,
+							channel->data, regs);
+				}
 			} else {
 				/*
 				 * IRQ for an unregistered DMA channel:
@@ -165,10 +538,10 @@
 	return IRQ_HANDLED;
 }
 
-static int __init
-imx_dma_init(void)
+static int __init imx_dma_init(void)
 {
 	int ret;
+	int i;
 
 	/* reset DMA module */
 	DCR = DCR_DRST;
@@ -189,15 +562,27 @@
 	DCR = DCR_DEN;
 
 	/* clear all interrupts */
-	DISR = 0x3ff;
+	DISR = (1 << IMX_DMA_CHANNELS) - 1;
 
 	/* enable interrupts */
-	DIMR = 0;
+	DIMR = (1 << IMX_DMA_CHANNELS) - 1;
+
+	for (i = 0; i < IMX_DMA_CHANNELS; i++) {
+		imx_dma_channels[i].sg = NULL;
+		imx_dma_channels[i].dma_num = i;
+	}
 
 	return ret;
 }
 
 arch_initcall(imx_dma_init);
 
-EXPORT_SYMBOL(imx_request_dma);
-EXPORT_SYMBOL(imx_free_dma);
+EXPORT_SYMBOL(imx_dma_setup_single);
+EXPORT_SYMBOL(imx_dma_setup_sg);
+EXPORT_SYMBOL(imx_dma_setup_handlers);
+EXPORT_SYMBOL(imx_dma_enable);
+EXPORT_SYMBOL(imx_dma_disable);
+EXPORT_SYMBOL(imx_dma_request);
+EXPORT_SYMBOL(imx_dma_free);
+EXPORT_SYMBOL(imx_dma_request_by_prio);
+EXPORT_SYMBOL(imx_dma_channels);
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c
index 8ab1b04..e34d0df 100644
--- a/arch/arm/mach-imx/mx1ads.c
+++ b/arch/arm/mach-imx/mx1ads.c
@@ -25,6 +25,7 @@
 #include <asm/mach-types.h>
 
 #include <asm/mach/arch.h>
+#include <asm/arch/mmc.h>
 #include <linux/interrupt.h>
 #include "generic.h"
 
@@ -51,12 +52,29 @@
 	&cs89x0_device,
 };
 
+#ifdef CONFIG_MMC_IMX
+static int mx1ads_mmc_card_present(void)
+{
+	/* MMC/SD Card Detect is PB 20 on MX1ADS V1.0.7 */
+	return (SSR(1) & (1 << 20) ? 0 : 1);
+}
+
+static struct imxmmc_platform_data mx1ads_mmc_info = {
+       .card_present = mx1ads_mmc_card_present,
+};
+#endif
+
 static void __init
 mx1ads_init(void)
 {
 #ifdef CONFIG_LEDS
 	imx_gpio_mode(GPIO_PORTA | GPIO_OUT | 2);
 #endif
+#ifdef CONFIG_MMC_IMX
+	/* SD/MMC card detect */
+	imx_gpio_mode(GPIO_PORTB | GPIO_GIUS | GPIO_IN | 20);
+	imx_set_mmc_info(&mx1ads_mmc_info);
+#endif
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
diff --git a/arch/arm/mach-ixp23xx/espresso.c b/arch/arm/mach-ixp23xx/espresso.c
index 2327c97..bf688c1 100644
--- a/arch/arm/mach-ixp23xx/espresso.c
+++ b/arch/arm/mach-ixp23xx/espresso.c
@@ -44,6 +44,15 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/pci.h>
 
+static int __init espresso_pci_init(void)
+{
+	if (machine_is_espresso())
+		ixp23xx_pci_slave_init();
+
+	return 0;
+};
+subsys_initcall(espresso_pci_init);
+
 static void __init espresso_init(void)
 {
 	physmap_configure(0x90000000, 0x02000000, 2, NULL);
diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c
index 5330ad7..ac72f94 100644
--- a/arch/arm/mach-ixp23xx/pci.c
+++ b/arch/arm/mach-ixp23xx/pci.c
@@ -201,7 +201,7 @@
 	return 0;
 }
 
-void __init ixp23xx_pci_preinit(void)
+static void __init ixp23xx_pci_common_init(void)
 {
 #ifdef __ARMEB__
 	*IXP23XX_PCI_CONTROL |= 0x20000;	/* set I/O swapping */
@@ -219,7 +219,18 @@
 		*IXP23XX_PCI_CPP_ADDR_BITS &= ~(1 << 1);
 	} else {
 		*IXP23XX_PCI_CPP_ADDR_BITS |= (1 << 1);
+
+		/*
+		 * Enable coherency on A2 silicon.
+		 */
+		if (arch_is_coherent())
+			*IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_COH_OFF;
 	}
+}
+
+void __init ixp23xx_pci_preinit(void)
+{
+	ixp23xx_pci_common_init();
 
 	hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS,
 			"PCI config cycle to non-existent device");
@@ -273,3 +284,8 @@
 
 	return 1;
 }
+
+void ixp23xx_pci_slave_init(void)
+{
+	ixp23xx_pci_common_init();
+}
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index 86a0f0d..f8d716c 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -69,12 +69,6 @@
 	  Support for Voiceblue GSM/VoIP gateway. Say Y here if you have
 	  such a board.
 
-config MACH_NETSTAR
-	bool "NetStar"
-	depends on ARCH_OMAP1 && ARCH_OMAP15XX
-	help
-	  Support for NetStar PBX. Say Y here if you have such a board.
-
 config MACH_OMAP_PALMTE
 	bool "Palm Tungsten E"
 	depends on ARCH_OMAP1 && ARCH_OMAP15XX
@@ -85,6 +79,20 @@
           informations.
           Say Y here if you have such a PDA, say NO otherwise.
 
+config MACH_NOKIA770
+	bool "Nokia 770"
+	depends on ARCH_OMAP1 && ARCH_OMAP16XX
+	help
+	  Support for the Nokia 770 Internet Tablet. Say Y here if you
+	  have such a device.
+
+config MACH_AMS_DELTA
+	bool "Amstrad E3 (Delta)"
+	depends on ARCH_OMAP1 && ARCH_OMAP15XX
+	help
+	  Support for the Amstrad E3 (codename Delta) videophone. Say Y here
+	  if you have such a device.
+
 config MACH_OMAP_GENERIC
 	bool "Generic OMAP board"
 	depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index b0b0015..9ea7195 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -3,7 +3,13 @@
 #
 
 # Common support
-obj-y := io.o id.o clock.o irq.o time.o mux.o serial.o devices.o
+obj-y := io.o id.o clock.o irq.o mux.o serial.o devices.o
+
+obj-$(CONFIG_OMAP_MPU_TIMER)		+= time.o
+
+# Power Management
+obj-$(CONFIG_PM) += pm.o sleep.o
+
 led-y := leds.o
 
 # Specific board support
@@ -14,8 +20,9 @@
 obj-$(CONFIG_MACH_OMAP_OSK)		+= board-osk.o
 obj-$(CONFIG_MACH_OMAP_H3)		+= board-h3.o
 obj-$(CONFIG_MACH_VOICEBLUE)		+= board-voiceblue.o
-obj-$(CONFIG_MACH_NETSTAR)		+= board-netstar.o
 obj-$(CONFIG_MACH_OMAP_PALMTE)		+= board-palmte.o
+obj-$(CONFIG_MACH_NOKIA770)		+= board-nokia770.o
+obj-$(CONFIG_MACH_AMS_DELTA)		+= board-ams-delta.o
 
 ifeq ($(CONFIG_ARCH_OMAP15XX),y)
 # Innovator-1510 FPGA
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
new file mode 100644
index 0000000..6178f04
--- /dev/null
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -0,0 +1,116 @@
+/*
+ * linux/arch/arm/mach-omap1/board-ams-delta.c
+ *
+ * Modified from board-generic.c
+ *
+ * Board specific inits for the Amstrad E3 (codename Delta) videophone
+ *
+ * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/board-ams-delta.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/board.h>
+#include <asm/arch/common.h>
+
+static u8 ams_delta_latch1_reg;
+static u16 ams_delta_latch2_reg;
+
+void ams_delta_latch1_write(u8 mask, u8 value)
+{
+	ams_delta_latch1_reg &= ~mask;
+	ams_delta_latch1_reg |= value;
+	*(volatile __u8 *) AMS_DELTA_LATCH1_VIRT = ams_delta_latch1_reg;
+}
+
+void ams_delta_latch2_write(u16 mask, u16 value)
+{
+	ams_delta_latch2_reg &= ~mask;
+	ams_delta_latch2_reg |= value;
+	*(volatile __u16 *) AMS_DELTA_LATCH2_VIRT = ams_delta_latch2_reg;
+}
+
+static void __init ams_delta_init_irq(void)
+{
+	omap1_init_common_hw();
+	omap_init_irq();
+	omap_gpio_init();
+}
+
+static struct map_desc ams_delta_io_desc[] __initdata = {
+	// AMS_DELTA_LATCH1
+	{
+		.virtual	= AMS_DELTA_LATCH1_VIRT,
+		.pfn		= __phys_to_pfn(AMS_DELTA_LATCH1_PHYS),
+		.length		= 0x01000000,
+		.type		= MT_DEVICE
+	},
+	// AMS_DELTA_LATCH2
+	{
+		.virtual	= AMS_DELTA_LATCH2_VIRT,
+		.pfn		= __phys_to_pfn(AMS_DELTA_LATCH2_PHYS),
+		.length		= 0x01000000,
+		.type		= MT_DEVICE
+	},
+	// AMS_DELTA_MODEM
+	{
+		.virtual	= AMS_DELTA_MODEM_VIRT,
+		.pfn		= __phys_to_pfn(AMS_DELTA_MODEM_PHYS),
+		.length		= 0x01000000,
+		.type		= MT_DEVICE
+	}
+};
+
+static struct omap_uart_config ams_delta_uart_config __initdata = {
+	.enabled_uarts = 1,
+};
+
+static struct omap_board_config_kernel ams_delta_config[] = {
+	{ OMAP_TAG_UART,	&ams_delta_uart_config },
+};
+
+static void __init ams_delta_init(void)
+{
+	iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc));
+
+	omap_board_config = ams_delta_config;
+	omap_board_config_size = ARRAY_SIZE(ams_delta_config);
+	omap_serial_init();
+
+	/* Clear latch2 (NAND, LCD, modem enable) */
+	ams_delta_latch2_write(~0, 0);
+}
+
+static void __init ams_delta_map_io(void)
+{
+	omap1_map_common_io();
+}
+
+MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
+	/* Maintainer: Jonathan McDowell <noodles@earth.li> */
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= ams_delta_map_io,
+	.init_irq	= ams_delta_init_irq,
+	.init_machine	= ams_delta_init,
+	.timer		= &omap_timer,
+MACHINE_END
+
+EXPORT_SYMBOL(ams_delta_latch1_write);
+EXPORT_SYMBOL(ams_delta_latch2_write);
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index a177e78..33d01ad 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -88,7 +88,7 @@
 static void __init omap_generic_init(void)
 {
 #ifdef CONFIG_ARCH_OMAP15XX
-	if (cpu_is_omap1510()) {
+	if (cpu_is_omap15xx()) {
 		generic_config[0].data = &generic1510_usb_config;
 	}
 #endif
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 89f0cc7..cd3a06d 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -24,7 +24,9 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/input.h>
 
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
@@ -35,12 +37,55 @@
 #include <asm/arch/gpio.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/tc.h>
+#include <asm/arch/irda.h>
 #include <asm/arch/usb.h>
+#include <asm/arch/keypad.h>
 #include <asm/arch/common.h>
+#include <asm/arch/mcbsp.h>
+#include <asm/arch/omap-alsa.h>
 
 extern int omap_gpio_init(void);
 
-static struct mtd_partition h2_partitions[] = {
+static int h2_keymap[] = {
+	KEY(0, 0, KEY_LEFT),
+	KEY(0, 1, KEY_RIGHT),
+	KEY(0, 2, KEY_3),
+	KEY(0, 3, KEY_F10),
+	KEY(0, 4, KEY_F5),
+	KEY(0, 5, KEY_9),
+	KEY(1, 0, KEY_DOWN),
+	KEY(1, 1, KEY_UP),
+	KEY(1, 2, KEY_2),
+	KEY(1, 3, KEY_F9),
+	KEY(1, 4, KEY_F7),
+	KEY(1, 5, KEY_0),
+	KEY(2, 0, KEY_ENTER),
+	KEY(2, 1, KEY_6),
+	KEY(2, 2, KEY_1),
+	KEY(2, 3, KEY_F2),
+	KEY(2, 4, KEY_F6),
+	KEY(2, 5, KEY_HOME),
+	KEY(3, 0, KEY_8),
+	KEY(3, 1, KEY_5),
+	KEY(3, 2, KEY_F12),
+	KEY(3, 3, KEY_F3),
+	KEY(3, 4, KEY_F8),
+	KEY(3, 5, KEY_END),
+	KEY(4, 0, KEY_7),
+	KEY(4, 1, KEY_4),
+	KEY(4, 2, KEY_F11),
+	KEY(4, 3, KEY_F1),
+	KEY(4, 4, KEY_F4),
+	KEY(4, 5, KEY_ESC),
+	KEY(5, 0, KEY_F13),
+	KEY(5, 1, KEY_F14),
+	KEY(5, 2, KEY_F15),
+	KEY(5, 3, KEY_F16),
+	KEY(5, 4, KEY_SLEEP),
+	0
+};
+
+static struct mtd_partition h2_nor_partitions[] = {
 	/* bootloader (U-Boot, etc) in first sector */
 	{
 	      .name		= "bootloader",
@@ -71,26 +116,26 @@
 	}
 };
 
-static struct flash_platform_data h2_flash_data = {
+static struct flash_platform_data h2_nor_data = {
 	.map_name	= "cfi_probe",
 	.width		= 2,
-	.parts		= h2_partitions,
-	.nr_parts	= ARRAY_SIZE(h2_partitions),
+	.parts		= h2_nor_partitions,
+	.nr_parts	= ARRAY_SIZE(h2_nor_partitions),
 };
 
-static struct resource h2_flash_resource = {
+static struct resource h2_nor_resource = {
 	/* This is on CS3, wherever it's mapped */
 	.flags		= IORESOURCE_MEM,
 };
 
-static struct platform_device h2_flash_device = {
+static struct platform_device h2_nor_device = {
 	.name		= "omapflash",
 	.id		= 0,
 	.dev		= {
-		.platform_data	= &h2_flash_data,
+		.platform_data	= &h2_nor_data,
 	},
 	.num_resources	= 1,
-	.resource	= &h2_flash_resource,
+	.resource	= &h2_nor_resource,
 };
 
 static struct resource h2_smc91x_resources[] = {
@@ -113,9 +158,119 @@
 	.resource	= h2_smc91x_resources,
 };
 
+static struct resource h2_kp_resources[] = {
+	[0] = {
+		.start	= INT_KEYBOARD,
+		.end	= INT_KEYBOARD,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct omap_kp_platform_data h2_kp_data = {
+	.rows	= 8,
+	.cols	= 8,
+	.keymap = h2_keymap,
+	.rep	= 1,
+};
+
+static struct platform_device h2_kp_device = {
+	.name		= "omap-keypad",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &h2_kp_data,
+	},
+	.num_resources	= ARRAY_SIZE(h2_kp_resources),
+	.resource	= h2_kp_resources,
+};
+
+#define H2_IRDA_FIRSEL_GPIO_PIN	17
+
+#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
+static int h2_transceiver_mode(struct device *dev, int state)
+{
+	if (state & IR_SIRMODE)
+		omap_set_gpio_dataout(H2_IRDA_FIRSEL_GPIO_PIN, 0);
+	else    /* MIR/FIR */
+		omap_set_gpio_dataout(H2_IRDA_FIRSEL_GPIO_PIN, 1);
+
+	return 0;
+}
+#endif
+
+static struct omap_irda_config h2_irda_data = {
+	.transceiver_cap	= IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
+	.rx_channel		= OMAP_DMA_UART3_RX,
+	.tx_channel		= OMAP_DMA_UART3_TX,
+	.dest_start		= UART3_THR,
+	.src_start		= UART3_RHR,
+	.tx_trigger		= 0,
+	.rx_trigger		= 0,
+};
+
+static struct resource h2_irda_resources[] = {
+	[0] = {
+		.start	= INT_UART3,
+		.end	= INT_UART3,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+static struct platform_device h2_irda_device = {
+	.name		= "omapirda",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &h2_irda_data,
+	},
+	.num_resources	= ARRAY_SIZE(h2_irda_resources),
+	.resource	= h2_irda_resources,
+};
+
+static struct platform_device h2_lcd_device = {
+	.name		= "lcd_h2",
+	.id		= -1,
+};
+
+static struct omap_mcbsp_reg_cfg mcbsp_regs = {
+	.spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
+	.spcr1 = RINTM(3) | RRST,
+	.rcr2  = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
+                RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(1),
+	.rcr1  = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
+	.xcr2  = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
+                XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(1) | XFIG,
+	.xcr1  = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
+	.srgr1 = FWID(15),
+	.srgr2 = GSYNC | CLKSP | FSGM | FPER(31),
+
+	.pcr0  = CLKXM | CLKRM | FSXP | FSRP | CLKXP | CLKRP,
+	//.pcr0 = CLKXP | CLKRP,        /* mcbsp: slave */
+};
+
+static struct omap_alsa_codec_config alsa_config = {
+	.name                   = "H2 TSC2101",
+	.mcbsp_regs_alsa        = &mcbsp_regs,
+	.codec_configure_dev    = NULL, // tsc2101_configure,
+	.codec_set_samplerate   = NULL, // tsc2101_set_samplerate,
+	.codec_clock_setup      = NULL, // tsc2101_clock_setup,
+	.codec_clock_on         = NULL, // tsc2101_clock_on,
+	.codec_clock_off        = NULL, // tsc2101_clock_off,
+	.get_default_samplerate = NULL, // tsc2101_get_default_samplerate,
+};
+
+static struct platform_device h2_mcbsp1_device = {
+	.name	= "omap_alsa_mcbsp",
+	.id	= 1,
+	.dev = {
+		.platform_data	= &alsa_config,
+	},
+};
+
 static struct platform_device *h2_devices[] __initdata = {
-	&h2_flash_device,
+	&h2_nor_device,
 	&h2_smc91x_device,
+	&h2_irda_device,
+	&h2_kp_device,
+	&h2_lcd_device,
+	&h2_mcbsp1_device,
 };
 
 static void __init h2_init_smc91x(void)
@@ -164,7 +319,6 @@
 };
 
 static struct omap_lcd_config h2_lcd_config __initdata = {
-	.panel_name	= "h2",
 	.ctrl_name	= "internal",
 };
 
@@ -177,16 +331,34 @@
 
 static void __init h2_init(void)
 {
-	/* NOTE: revC boards support NAND-boot, which can put NOR on CS2B
-	 * and NAND (either 16bit or 8bit) on CS3.
+	/* Here we assume the NOR boot config:  NOR on CS3 (possibly swapped
+	 * to address 0 by a dip switch), NAND on CS2B.  The NAND driver will
+	 * notice whether a NAND chip is enabled at probe time.
+	 *
+	 * FIXME revC boards (and H3) support NAND-boot, with a dip switch to
+	 * put NOR on CS2B and NAND (which on H2 may be 16bit) on CS3.  Try
+	 * detecting that in code here, to avoid probing every possible flash
+	 * configuration...
 	 */
-	h2_flash_resource.end = h2_flash_resource.start = omap_cs3_phys();
-	h2_flash_resource.end += SZ_32M - 1;
+	h2_nor_resource.end = h2_nor_resource.start = omap_cs3_phys();
+	h2_nor_resource.end += SZ_32M - 1;
+
+	omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
+	omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
 
 	/* MMC:  card detect and WP */
 	// omap_cfg_reg(U19_ARMIO1);		/* CD */
 	omap_cfg_reg(BALLOUT_V8_ARMIO3);	/* WP */
 
+	/* Irda */
+#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
+	omap_writel(omap_readl(FUNC_MUX_CTRL_A) | 7, FUNC_MUX_CTRL_A);
+	if (!(omap_request_gpio(H2_IRDA_FIRSEL_GPIO_PIN))) {
+		omap_set_gpio_direction(H2_IRDA_FIRSEL_GPIO_PIN, 0);
+		h2_irda_data.transceiver_mode = h2_transceiver_mode;
+	}
+#endif
+
 	platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
 	omap_board_config = h2_config;
 	omap_board_config_size = ARRAY_SIZE(h2_config);
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index d9f3862..4b8d0ec 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -21,8 +21,11 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/errno.h>
+#include <linux/workqueue.h>
 #include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/input.h>
 
 #include <asm/setup.h>
 #include <asm/page.h>
@@ -33,15 +36,59 @@
 #include <asm/mach/map.h>
 
 #include <asm/arch/gpio.h>
+#include <asm/arch/gpioexpander.h>
 #include <asm/arch/irqs.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/tc.h>
+#include <asm/arch/irda.h>
 #include <asm/arch/usb.h>
+#include <asm/arch/keypad.h>
+#include <asm/arch/dma.h>
 #include <asm/arch/common.h>
 
 extern int omap_gpio_init(void);
 
-static struct mtd_partition h3_partitions[] = {
+static int h3_keymap[] = {
+	KEY(0, 0, KEY_LEFT),
+	KEY(0, 1, KEY_RIGHT),
+	KEY(0, 2, KEY_3),
+	KEY(0, 3, KEY_F10),
+	KEY(0, 4, KEY_F5),
+	KEY(0, 5, KEY_9),
+	KEY(1, 0, KEY_DOWN),
+	KEY(1, 1, KEY_UP),
+	KEY(1, 2, KEY_2),
+	KEY(1, 3, KEY_F9),
+	KEY(1, 4, KEY_F7),
+	KEY(1, 5, KEY_0),
+	KEY(2, 0, KEY_ENTER),
+	KEY(2, 1, KEY_6),
+	KEY(2, 2, KEY_1),
+	KEY(2, 3, KEY_F2),
+	KEY(2, 4, KEY_F6),
+	KEY(2, 5, KEY_HOME),
+	KEY(3, 0, KEY_8),
+	KEY(3, 1, KEY_5),
+	KEY(3, 2, KEY_F12),
+	KEY(3, 3, KEY_F3),
+	KEY(3, 4, KEY_F8),
+	KEY(3, 5, KEY_END),
+	KEY(4, 0, KEY_7),
+	KEY(4, 1, KEY_4),
+	KEY(4, 2, KEY_F11),
+	KEY(4, 3, KEY_F1),
+	KEY(4, 4, KEY_F4),
+	KEY(4, 5, KEY_ESC),
+	KEY(5, 0, KEY_F13),
+	KEY(5, 1, KEY_F14),
+	KEY(5, 2, KEY_F15),
+	KEY(5, 3, KEY_F16),
+	KEY(5, 4, KEY_SLEEP),
+	0
+};
+
+
+static struct mtd_partition nor_partitions[] = {
 	/* bootloader (U-Boot, etc) in first sector */
 	{
 	      .name		= "bootloader",
@@ -72,26 +119,80 @@
 	}
 };
 
-static struct flash_platform_data h3_flash_data = {
+static struct flash_platform_data nor_data = {
 	.map_name	= "cfi_probe",
 	.width		= 2,
-	.parts		= h3_partitions,
-	.nr_parts	= ARRAY_SIZE(h3_partitions),
+	.parts		= nor_partitions,
+	.nr_parts	= ARRAY_SIZE(nor_partitions),
 };
 
-static struct resource h3_flash_resource = {
+static struct resource nor_resource = {
 	/* This is on CS3, wherever it's mapped */
 	.flags		= IORESOURCE_MEM,
 };
 
-static struct platform_device flash_device = {
+static struct platform_device nor_device = {
 	.name		= "omapflash",
 	.id		= 0,
 	.dev		= {
-		.platform_data	= &h3_flash_data,
+		.platform_data	= &nor_data,
 	},
 	.num_resources	= 1,
-	.resource	= &h3_flash_resource,
+	.resource	= &nor_resource,
+};
+
+static struct mtd_partition nand_partitions[] = {
+#if 0
+	/* REVISIT: enable these partitions if you make NAND BOOT work */
+	{
+		.name		= "xloader",
+		.offset		= 0,
+		.size		= 64 * 1024,
+		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
+	},
+	{
+		.name		= "bootloader",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 256 * 1024,
+		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
+	},
+	{
+		.name		= "params",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 192 * 1024,
+	},
+	{
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 2 * SZ_1M,
+	},
+#endif
+	{
+		.name		= "filesystem",
+		.size		= MTDPART_SIZ_FULL,
+		.offset		= MTDPART_OFS_APPEND,
+	},
+};
+
+/* dip switches control NAND chip access:  8 bit, 16 bit, or neither */
+static struct nand_platform_data nand_data = {
+	.options	= NAND_SAMSUNG_LP_OPTIONS,
+	.parts		= nand_partitions,
+	.nr_parts	= ARRAY_SIZE(nand_partitions),
+};
+
+static struct resource nand_resource = {
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device nand_device = {
+	.name		= "omapnand",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &nand_data,
+	},
+	.num_resources	= 1,
+	.resource	= &nand_resource,
 };
 
 static struct resource smc91x_resources[] = {
@@ -138,10 +239,136 @@
 	.resource       = intlat_resources,
 };
 
+static struct resource h3_kp_resources[] = {
+	[0] = {
+		.start	= INT_KEYBOARD,
+		.end	= INT_KEYBOARD,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct omap_kp_platform_data h3_kp_data = {
+	.rows	= 8,
+	.cols	= 8,
+	.keymap = h3_keymap,
+	.rep	= 1,
+};
+
+static struct platform_device h3_kp_device = {
+	.name		= "omap-keypad",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &h3_kp_data,
+	},
+	.num_resources	= ARRAY_SIZE(h3_kp_resources),
+	.resource	= h3_kp_resources,
+};
+
+
+/* Select between the IrDA and aGPS module
+ */
+static int h3_select_irda(struct device *dev, int state)
+{
+	unsigned char expa;
+	int err = 0;
+
+	if ((err = read_gpio_expa(&expa, 0x26))) {
+		printk(KERN_ERR "Error reading from I/O EXPANDER \n");
+		return err;
+	}
+
+	/* 'P6' enable/disable IRDA_TX and IRDA_RX */
+	if (state & IR_SEL) { /* IrDA */
+		if ((err = write_gpio_expa(expa | 0x40, 0x26))) {
+			printk(KERN_ERR "Error writing to I/O EXPANDER \n");
+			return err;
+		}
+	} else {
+		if ((err = write_gpio_expa(expa & ~0x40, 0x26))) {
+			printk(KERN_ERR "Error writing to I/O EXPANDER \n");
+			return err;
+		}
+	}
+	return err;
+}
+
+static void set_trans_mode(void *data)
+{
+	int *mode = data;
+	unsigned char expa;
+	int err = 0;
+
+	if ((err = read_gpio_expa(&expa, 0x27)) != 0) {
+		printk(KERN_ERR "Error reading from I/O expander\n");
+	}
+
+	expa &= ~0x03;
+
+	if (*mode & IR_SIRMODE) {
+		expa |= 0x01;
+	} else { /* MIR/FIR */
+		expa |= 0x03;
+	}
+
+	if ((err = write_gpio_expa(expa, 0x27)) != 0) {
+		printk(KERN_ERR "Error writing to I/O expander\n");
+	}
+}
+
+static int h3_transceiver_mode(struct device *dev, int mode)
+{
+	struct omap_irda_config *irda_config = dev->platform_data;
+
+	cancel_delayed_work(&irda_config->gpio_expa);
+	PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode);
+	schedule_work(&irda_config->gpio_expa);
+
+	return 0;
+}
+
+static struct omap_irda_config h3_irda_data = {
+	.transceiver_cap	= IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
+	.transceiver_mode	= h3_transceiver_mode,
+	.select_irda	 	= h3_select_irda,
+	.rx_channel		= OMAP_DMA_UART3_RX,
+	.tx_channel		= OMAP_DMA_UART3_TX,
+	.dest_start		= UART3_THR,
+	.src_start		= UART3_RHR,
+	.tx_trigger		= 0,
+	.rx_trigger		= 0,
+};
+
+static struct resource h3_irda_resources[] = {
+	[0] = {
+		.start	= INT_UART3,
+		.end	= INT_UART3,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device h3_irda_device = {
+	.name		= "omapirda",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &h3_irda_data,
+	},
+	.num_resources	= ARRAY_SIZE(h3_irda_resources),
+	.resource	= h3_irda_resources,
+};
+
+static struct platform_device h3_lcd_device = {
+	.name		= "lcd_h3",
+	.id		= -1,
+};
+
 static struct platform_device *devices[] __initdata = {
-	&flash_device,
+	&nor_device,
+	&nand_device,
         &smc91x_device,
 	&intlat_device,
+	&h3_irda_device,
+	&h3_kp_device,
+	&h3_lcd_device,
 };
 
 static struct omap_usb_config h3_usb_config __initdata = {
@@ -171,7 +398,6 @@
 };
 
 static struct omap_lcd_config h3_lcd_config __initdata = {
-	.panel_name	= "h3",
 	.ctrl_name	= "internal",
 };
 
@@ -182,11 +408,36 @@
 	{ OMAP_TAG_LCD,		&h3_lcd_config },
 };
 
+#define H3_NAND_RB_GPIO_PIN	10
+
+static int nand_dev_ready(struct nand_platform_data *data)
+{
+	return omap_get_gpio_datain(H3_NAND_RB_GPIO_PIN);
+}
+
 static void __init h3_init(void)
 {
-	h3_flash_resource.end = h3_flash_resource.start = omap_cs3_phys();
-	h3_flash_resource.end += OMAP_CS3_SIZE - 1;
-	(void) platform_add_devices(devices, ARRAY_SIZE(devices));
+	/* Here we assume the NOR boot config:  NOR on CS3 (possibly swapped
+	 * to address 0 by a dip switch), NAND on CS2B.  The NAND driver will
+	 * notice whether a NAND chip is enabled at probe time.
+	 *
+	 * H3 support NAND-boot, with a dip switch to put NOR on CS2B and NAND
+	 * (which on H2 may be 16bit) on CS3.  Try detecting that in code here,
+	 * to avoid probing every possible flash configuration...
+	 */
+	nor_resource.end = nor_resource.start = omap_cs3_phys();
+	nor_resource.end += SZ_32M - 1;
+
+	nand_resource.end = nand_resource.start = OMAP_CS2B_PHYS;
+	nand_resource.end += SZ_4K - 1;
+	if (!(omap_request_gpio(H3_NAND_RB_GPIO_PIN)))
+		nand_data.dev_ready = nand_dev_ready;
+
+	/* GPIO10 Func_MUX_CTRL reg bit 29:27, Configure V2 to mode1 as GPIO */
+	/* GPIO10 pullup/down register, Enable pullup on GPIO10 */
+	omap_cfg_reg(V2_1710_GPIO10);
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
 	omap_board_config = h3_config;
 	omap_board_config_size = ARRAY_SIZE(h3_config);
 	omap_serial_init();
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index a04e433..e90c137 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -22,6 +22,7 @@
 #include <linux/delay.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/input.h>
 
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
@@ -34,8 +35,22 @@
 #include <asm/arch/gpio.h>
 #include <asm/arch/tc.h>
 #include <asm/arch/usb.h>
+#include <asm/arch/keypad.h>
 #include <asm/arch/common.h>
 
+static int innovator_keymap[] = {
+	KEY(0, 0, KEY_F1),
+	KEY(0, 3, KEY_DOWN),
+	KEY(1, 1, KEY_F2),
+	KEY(1, 2, KEY_RIGHT),
+	KEY(2, 0, KEY_F3),
+	KEY(2, 1, KEY_F4),
+	KEY(2, 2, KEY_UP),
+	KEY(3, 2, KEY_ENTER),
+	KEY(3, 3, KEY_LEFT),
+	0
+};
+
 static struct mtd_partition innovator_partitions[] = {
 	/* bootloader (U-Boot, etc) in first sector */
 	{
@@ -97,6 +112,31 @@
 	.resource	= &innovator_flash_resource,
 };
 
+static struct resource innovator_kp_resources[] = {
+	[0] = {
+		.start	= INT_KEYBOARD,
+		.end	= INT_KEYBOARD,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct omap_kp_platform_data innovator_kp_data = {
+	.rows	= 8,
+	.cols	= 8,
+	.keymap = innovator_keymap,
+};
+
+static struct platform_device innovator_kp_device = {
+	.name		= "omap-keypad",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &innovator_kp_data,
+	},
+	.num_resources	= ARRAY_SIZE(innovator_kp_resources),
+	.resource	= innovator_kp_resources,
+};
+
+
 #ifdef CONFIG_ARCH_OMAP15XX
 
 /* Only FPGA needs to be mapped here. All others are done with ioremap */
@@ -129,9 +169,16 @@
 	.resource	= innovator1510_smc91x_resources,
 };
 
+static struct platform_device innovator1510_lcd_device = {
+	.name		= "lcd_inn1510",
+	.id		= -1,
+};
+
 static struct platform_device *innovator1510_devices[] __initdata = {
 	&innovator_flash_device,
 	&innovator1510_smc91x_device,
+	&innovator_kp_device,
+	&innovator1510_lcd_device,
 };
 
 #endif /* CONFIG_ARCH_OMAP15XX */
@@ -158,9 +205,16 @@
 	.resource	= innovator1610_smc91x_resources,
 };
 
+static struct platform_device innovator1610_lcd_device = {
+	.name		= "inn1610_lcd",
+	.id		= -1,
+};
+
 static struct platform_device *innovator1610_devices[] __initdata = {
 	&innovator_flash_device,
 	&innovator1610_smc91x_device,
+	&innovator_kp_device,
+	&innovator1610_lcd_device,
 };
 
 #endif /* CONFIG_ARCH_OMAP16XX */
@@ -206,7 +260,6 @@
 };
 
 static struct omap_lcd_config innovator1510_lcd_config __initdata = {
-	.panel_name	= "inn1510",
 	.ctrl_name	= "internal",
 };
 #endif
@@ -228,7 +281,6 @@
 };
 
 static struct omap_lcd_config innovator1610_lcd_config __initdata = {
-	.panel_name	= "inn1610",
 	.ctrl_name	= "internal",
 };
 #endif
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c
deleted file mode 100644
index 7520e60..0000000
--- a/arch/arm/mach-omap1/board-netstar.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Modified from board-generic.c
- *
- * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
- *
- * Code for Netstar OMAP board.
- *
- * 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/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <asm/arch/gpio.h>
-#include <asm/arch/mux.h>
-#include <asm/arch/usb.h>
-#include <asm/arch/common.h>
-
-extern void __init omap_init_time(void);
-extern int omap_gpio_init(void);
-
-static struct resource netstar_smc91x_resources[] = {
-	[0] = {
-		.start	= OMAP_CS1_PHYS + 0x300,
-		.end	= OMAP_CS1_PHYS + 0x300 + 16,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= OMAP_GPIO_IRQ(8),
-		.end	= OMAP_GPIO_IRQ(8),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device netstar_smc91x_device = {
-	.name		= "smc91x",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(netstar_smc91x_resources),
-	.resource	= netstar_smc91x_resources,
-};
-
-static struct platform_device *netstar_devices[] __initdata = {
-	&netstar_smc91x_device,
-};
-
-static struct omap_uart_config netstar_uart_config __initdata = {
-	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
-};
-
-static struct omap_board_config_kernel netstar_config[] = {
-	{ OMAP_TAG_UART,	&netstar_uart_config },
-};
-
-static void __init netstar_init_irq(void)
-{
-	omap1_init_common_hw();
-	omap_init_irq();
-	omap_gpio_init();
-}
-
-static void __init netstar_init(void)
-{
-	/* green LED */
-	omap_request_gpio(4);
-	omap_set_gpio_direction(4, 0);
-	/* smc91x reset */
-	omap_request_gpio(7);
-	omap_set_gpio_direction(7, 0);
-	omap_set_gpio_dataout(7, 1);
-	udelay(2);	/* wait at least 100ns */
-	omap_set_gpio_dataout(7, 0);
-	mdelay(50);	/* 50ms until PHY ready */
-	/* smc91x interrupt pin */
-	omap_request_gpio(8);
-
-	omap_request_gpio(12);
-	omap_request_gpio(13);
-	omap_request_gpio(14);
-	omap_request_gpio(15);
-	set_irq_type(OMAP_GPIO_IRQ(12), IRQT_FALLING);
-	set_irq_type(OMAP_GPIO_IRQ(13), IRQT_FALLING);
-	set_irq_type(OMAP_GPIO_IRQ(14), IRQT_FALLING);
-	set_irq_type(OMAP_GPIO_IRQ(15), IRQT_FALLING);
-
-	platform_add_devices(netstar_devices, ARRAY_SIZE(netstar_devices));
-
-	/* Switch on green LED */
-	omap_set_gpio_dataout(4, 0);
-	/* Switch off red LED */
-	omap_writeb(0x00, OMAP_LPG1_PMR);	/* Disable clock */
-	omap_writeb(0x80, OMAP_LPG1_LCR);
-
-	omap_board_config = netstar_config;
-	omap_board_config_size = ARRAY_SIZE(netstar_config);
-	omap_serial_init();
-}
-
-static void __init netstar_map_io(void)
-{
-	omap1_map_common_io();
-}
-
-#define MACHINE_PANICED		1
-#define MACHINE_REBOOTING	2
-#define MACHINE_REBOOT		4
-static unsigned long machine_state;
-
-static int panic_event(struct notifier_block *this, unsigned long event,
-	 void *ptr)
-{
-	if (test_and_set_bit(MACHINE_PANICED, &machine_state))
-		return NOTIFY_DONE;
-
-	/* Switch off green LED */
-	omap_set_gpio_dataout(4, 1);
-	/* Flash red LED */
-	omap_writeb(0x78, OMAP_LPG1_LCR);
-	omap_writeb(0x01, OMAP_LPG1_PMR);	/* Enable clock */
-
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block panic_block = {
-	.notifier_call	= panic_event,
-};
-
-static int __init netstar_late_init(void)
-{
-	/* TODO: Setup front panel switch here */
-
-	/* Setup panic notifier */
-	atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
-
-	return 0;
-}
-
-postcore_initcall(netstar_late_init);
-
-MACHINE_START(NETSTAR, "NetStar OMAP5910")
-	/* Maintainer: Ladislav Michl <michl@2n.cz> */
-	.phys_io	= 0xfff00000,
-	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
-	.boot_params	= 0x10000100,
-	.map_io		= netstar_map_io,
-	.init_irq	= netstar_init_irq,
-	.init_machine	= netstar_init,
-	.timer		= &omap_timer,
-MACHINE_END
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
new file mode 100644
index 0000000..02b980d
--- /dev/null
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -0,0 +1,268 @@
+/*
+ * linux/arch/arm/mach-omap1/board-nokia770.c
+ *
+ * Modified from board-generic.c
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/clk.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/board.h>
+#include <asm/arch/keypad.h>
+#include <asm/arch/common.h>
+#include <asm/arch/dsp_common.h>
+#include <asm/arch/aic23.h>
+#include <asm/arch/gpio.h>
+
+static void __init omap_nokia770_init_irq(void)
+{
+	/* On Nokia 770, the SleepX signal is masked with an
+	 * MPUIO line by default.  It has to be unmasked for it
+	 * to become functional */
+
+	/* SleepX mask direction */
+	omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008);
+	/* Unmask SleepX signal */
+	omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004);
+
+	omap1_init_common_hw();
+	omap_init_irq();
+}
+
+static int nokia770_keymap[] = {
+	KEY(0, 1, GROUP_0 | KEY_UP),
+	KEY(0, 2, GROUP_1 | KEY_F5),
+	KEY(1, 0, GROUP_0 | KEY_LEFT),
+	KEY(1, 1, GROUP_0 | KEY_ENTER),
+	KEY(1, 2, GROUP_0 | KEY_RIGHT),
+	KEY(2, 0, GROUP_1 | KEY_ESC),
+	KEY(2, 1, GROUP_0 | KEY_DOWN),
+	KEY(2, 2, GROUP_1 | KEY_F4),
+	KEY(3, 0, GROUP_2 | KEY_F7),
+	KEY(3, 1, GROUP_2 | KEY_F8),
+	KEY(3, 2, GROUP_2 | KEY_F6),
+	0
+};
+
+static struct resource nokia770_kp_resources[] = {
+	[0] = {
+		.start	= INT_KEYBOARD,
+		.end	= INT_KEYBOARD,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct omap_kp_platform_data nokia770_kp_data = {
+	.rows   = 8,
+	.cols   = 8,
+	.keymap = nokia770_keymap
+};
+
+static struct platform_device nokia770_kp_device = {
+	.name		= "omap-keypad",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &nokia770_kp_data,
+	},
+	.num_resources	= ARRAY_SIZE(nokia770_kp_resources),
+	.resource	= nokia770_kp_resources,
+};
+
+static struct platform_device *nokia770_devices[] __initdata = {
+        &nokia770_kp_device,
+};
+
+static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = {
+	.x_max		= 0x0fff,
+	.y_max		= 0x0fff,
+	.x_plate_ohms	= 180,
+	.pressure_max	= 255,
+	.debounce_max	= 10,
+	.debounce_tol	= 3,
+};
+
+static struct spi_board_info nokia770_spi_board_info[] __initdata = {
+	[0] = {
+		.modalias       = "lcd_lph8923",
+		.bus_num        = 2,
+		.chip_select    = 3,
+		.max_speed_hz   = 12000000,
+	},
+	[1] = {
+		.modalias       = "ads7846",
+		.bus_num        = 2,
+		.chip_select    = 0,
+		.max_speed_hz   = 2500000,
+		.irq		= OMAP_GPIO_IRQ(15),
+		.platform_data	= &nokia770_ads7846_platform_data,
+	},
+};
+
+
+/* assume no Mini-AB port */
+
+static struct omap_usb_config nokia770_usb_config __initdata = {
+	.otg		= 1,
+	.register_host	= 1,
+	.register_dev	= 1,
+	.hmc_mode	= 16,
+	.pins[0]	= 6,
+};
+
+static struct omap_mmc_config nokia770_mmc_config __initdata = {
+	.mmc[0] = {
+		.enabled	= 0,
+		.wire4		= 0,
+		.wp_pin		= -1,
+		.power_pin	= -1,
+		.switch_pin	= -1,
+	},
+	.mmc[1] = {
+		.enabled	= 0,
+		.wire4		= 0,
+		.wp_pin		= -1,
+		.power_pin	= -1,
+		.switch_pin	= -1,
+	},
+};
+
+static struct omap_board_config_kernel nokia770_config[] = {
+	{ OMAP_TAG_USB,		NULL },
+	{ OMAP_TAG_MMC,		&nokia770_mmc_config },
+};
+
+/*
+ * audio power control
+ */
+#define	HEADPHONE_GPIO		14
+#define	AMPLIFIER_CTRL_GPIO	58
+
+static struct clk *dspxor_ck;
+static DECLARE_MUTEX(audio_pwr_sem);
+/*
+ * audio_pwr_state
+ * +--+-------------------------+---------------------------------------+
+ * |-1|down			|power-up request -> 0			|
+ * +--+-------------------------+---------------------------------------+
+ * | 0|up			|power-down(1) request -> 1		|
+ * |  |				|power-down(2) request -> (ignore)	|
+ * +--+-------------------------+---------------------------------------+
+ * | 1|up,			|power-up request -> 0			|
+ * |  |received down(1) request	|power-down(2) request -> -1		|
+ * +--+-------------------------+---------------------------------------+
+ */
+static int audio_pwr_state = -1;
+
+/*
+ * audio_pwr_up / down should be called under audio_pwr_sem
+ */
+static void nokia770_audio_pwr_up(void)
+{
+	clk_enable(dspxor_ck);
+
+	/* Turn on codec */
+	tlv320aic23_power_up();
+
+	if (omap_get_gpio_datain(HEADPHONE_GPIO))
+		/* HP not connected, turn on amplifier */
+		omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 1);
+	else
+		/* HP connected, do not turn on amplifier */
+		printk("HP connected\n");
+}
+
+static void codec_delayed_power_down(void *arg)
+{
+	down(&audio_pwr_sem);
+	if (audio_pwr_state == -1)
+		tlv320aic23_power_down();
+	clk_disable(dspxor_ck);
+	up(&audio_pwr_sem);
+}
+
+static DECLARE_WORK(codec_power_down_work, codec_delayed_power_down, NULL);
+
+static void nokia770_audio_pwr_down(void)
+{
+	/* Turn off amplifier */
+	omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 0);
+
+	/* Turn off codec: schedule delayed work */
+	schedule_delayed_work(&codec_power_down_work, HZ / 20);	/* 50ms */
+}
+
+void nokia770_audio_pwr_up_request(int stage)
+{
+	down(&audio_pwr_sem);
+	if (audio_pwr_state == -1)
+		nokia770_audio_pwr_up();
+	/* force audio_pwr_state = 0, even if it was 1. */
+	audio_pwr_state = 0;
+	up(&audio_pwr_sem);
+}
+
+void nokia770_audio_pwr_down_request(int stage)
+{
+	down(&audio_pwr_sem);
+	switch (stage) {
+	case 1:
+		if (audio_pwr_state == 0)
+			audio_pwr_state = 1;
+		break;
+	case 2:
+		if (audio_pwr_state == 1) {
+			nokia770_audio_pwr_down();
+			audio_pwr_state = -1;
+		}
+		break;
+	}
+	up(&audio_pwr_sem);
+}
+
+static void __init omap_nokia770_init(void)
+{
+	nokia770_config[0].data = &nokia770_usb_config;
+
+	platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices));
+	spi_register_board_info(nokia770_spi_board_info,
+				ARRAY_SIZE(nokia770_spi_board_info));
+	omap_board_config = nokia770_config;
+	omap_board_config_size = ARRAY_SIZE(nokia770_config);
+	omap_serial_init();
+	omap_dsp_audio_pwr_up_request = nokia770_audio_pwr_up_request;
+	omap_dsp_audio_pwr_down_request = nokia770_audio_pwr_down_request;
+	dspxor_ck = clk_get(0, "dspxor_ck");
+}
+
+static void __init omap_nokia770_map_io(void)
+{
+	omap1_map_common_io();
+}
+
+MACHINE_START(NOKIA770, "Nokia 770")
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= omap_nokia770_map_io,
+	.init_irq	= omap_nokia770_init_irq,
+	.init_machine	= omap_nokia770_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 543fa13..1160093 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -33,6 +33,7 @@
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/input.h>
 
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
@@ -44,7 +45,24 @@
 #include <asm/arch/usb.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/tc.h>
+#include <asm/arch/keypad.h>
 #include <asm/arch/common.h>
+#include <asm/arch/mcbsp.h>
+#include <asm/arch/omap-alsa.h>
+
+static int osk_keymap[] = {
+	KEY(0, 0, KEY_F1),
+	KEY(0, 3, KEY_UP),
+	KEY(1, 1, KEY_LEFTCTRL),
+	KEY(1, 2, KEY_LEFT),
+	KEY(2, 0, KEY_SPACE),
+	KEY(2, 1, KEY_ESC),
+	KEY(2, 2, KEY_DOWN),
+	KEY(3, 2, KEY_ENTER),
+	KEY(3, 3, KEY_RIGHT),
+	0
+};
+
 
 static struct mtd_partition osk_partitions[] = {
 	/* bootloader (U-Boot, etc) in first sector */
@@ -133,9 +151,69 @@
 	.resource	= osk5912_cf_resources,
 };
 
+#define DEFAULT_BITPERSAMPLE 16
+
+static struct omap_mcbsp_reg_cfg mcbsp_regs = {
+	.spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
+	.spcr1 = RINTM(3) | RRST,
+	.rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
+	    RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0),
+	.rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
+	.xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
+	    XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG,
+	.xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
+	.srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1),
+	.srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1),
+	/*.pcr0 = FSXM | FSRM | CLKXM | CLKRM | CLKXP | CLKRP,*/ /* mcbsp: master */
+	.pcr0 = CLKXP | CLKRP,  /* mcbsp: slave */
+};
+
+static struct omap_alsa_codec_config alsa_config = {
+	.name			= "OSK AIC23",
+	.mcbsp_regs_alsa	= &mcbsp_regs,
+	.codec_configure_dev	= NULL, // aic23_configure,
+	.codec_set_samplerate	= NULL, // aic23_set_samplerate,
+	.codec_clock_setup	= NULL, // aic23_clock_setup,
+	.codec_clock_on		= NULL, // aic23_clock_on,
+	.codec_clock_off	= NULL, // aic23_clock_off,
+	.get_default_samplerate	= NULL, // aic23_get_default_samplerate,
+};
+
 static struct platform_device osk5912_mcbsp1_device = {
-	.name		= "omap_mcbsp",
-	.id		= 1,
+	.name	= "omap_alsa_mcbsp",
+ 	.id	= 1,
+	.dev = {
+		.platform_data	= &alsa_config,
+	},
+};
+
+static struct resource osk5912_kp_resources[] = {
+	[0] = {
+		.start	= INT_KEYBOARD,
+		.end	= INT_KEYBOARD,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct omap_kp_platform_data osk_kp_data = {
+	.rows	= 8,
+	.cols	= 8,
+	.keymap = osk_keymap,
+};
+
+static struct platform_device osk5912_kp_device = {
+	.name		= "omap-keypad",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &osk_kp_data,
+	},
+	.num_resources	= ARRAY_SIZE(osk5912_kp_resources),
+	.resource	= osk5912_kp_resources,
+};
+
+static struct platform_device osk5912_lcd_device = {
+	.name		= "lcd_osk",
+	.id		= -1,
 };
 
 static struct platform_device *osk5912_devices[] __initdata = {
@@ -143,6 +221,8 @@
 	&osk5912_smc91x_device,
 	&osk5912_cf_device,
 	&osk5912_mcbsp1_device,
+	&osk5912_kp_device,
+	&osk5912_lcd_device,
 };
 
 static void __init osk_init_smc91x(void)
@@ -197,7 +277,6 @@
 };
 
 static struct omap_lcd_config osk_lcd_config __initdata = {
-	.panel_name	= "osk",
 	.ctrl_name	= "internal",
 };
 
@@ -255,8 +334,18 @@
 static void __init osk_mistral_init(void) { }
 #endif
 
+#define EMIFS_CS3_VAL	(0x88013141)
+
 static void __init osk_init(void)
 {
+	/* Workaround for wrong CS3 (NOR flash) timing
+	 * There are some U-Boot versions out there which configure
+	 * wrong CS3 memory timings. This mainly leads to CRC
+	 * or similiar errors if you use NOR flash (e.g. with JFFS2)
+	 */
+	if (EMIFS_CCS(3) != EMIFS_CS3_VAL)
+		EMIFS_CCS(3) = EMIFS_CS3_VAL;
+
 	osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys();
 	osk_flash_resource.end += SZ_32M - 1;
 	platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices));
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index e488f72..4bc8a62 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -38,6 +38,15 @@
 	omap_init_irq();
 }
 
+static struct platform_device palmte_lcd_device = {
+	.name		= "lcd_palmte",
+	.id		= -1,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&palmte_lcd_device,
+};
+
 static struct omap_usb_config palmte_usb_config __initdata = {
 	.register_dev	= 1,
 	.hmc_mode	= 0,
@@ -55,7 +64,6 @@
 };
 
 static struct omap_lcd_config palmte_lcd_config __initdata = {
-	.panel_name	= "palmte",
 	.ctrl_name	= "internal",
 };
 
@@ -69,6 +77,8 @@
 {
 	omap_board_config = palmte_config;
 	omap_board_config_size = ARRAY_SIZE(palmte_config);
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
 static void __init omap_generic_map_io(void)
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index 3913a3c..64b45d8 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -16,7 +16,9 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/input.h>
 
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
@@ -28,9 +30,44 @@
 #include <asm/arch/gpio.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/fpga.h>
+#include <asm/arch/keypad.h>
 #include <asm/arch/common.h>
 #include <asm/arch/board.h>
 
+static int p2_keymap[] = {
+	KEY(0,0,KEY_UP),
+	KEY(0,1,KEY_RIGHT),
+	KEY(0,2,KEY_LEFT),
+	KEY(0,3,KEY_DOWN),
+	KEY(0,4,KEY_CENTER),
+	KEY(0,5,KEY_0_5),
+	KEY(1,0,KEY_SOFT2),
+	KEY(1,1,KEY_SEND),
+	KEY(1,2,KEY_END),
+	KEY(1,3,KEY_VOLUMEDOWN),
+	KEY(1,4,KEY_VOLUMEUP),
+	KEY(1,5,KEY_RECORD),
+	KEY(2,0,KEY_SOFT1),
+	KEY(2,1,KEY_3),
+	KEY(2,2,KEY_6),
+	KEY(2,3,KEY_9),
+	KEY(2,4,KEY_SHARP),
+	KEY(2,5,KEY_2_5),
+	KEY(3,0,KEY_BACK),
+	KEY(3,1,KEY_2),
+	KEY(3,2,KEY_5),
+	KEY(3,3,KEY_8),
+	KEY(3,4,KEY_0),
+	KEY(3,5,KEY_HEADSETHOOK),
+	KEY(4,0,KEY_HOME),
+	KEY(4,1,KEY_1),
+	KEY(4,2,KEY_4),
+	KEY(4,3,KEY_7),
+	KEY(4,4,KEY_STAR),
+	KEY(4,5,KEY_POWER),
+	0
+};
+
 static struct resource smc91x_resources[] = {
 	[0] = {
 		.start	= H2P2_DBG_FPGA_ETHR_START,	/* Physical */
@@ -44,7 +81,7 @@
 	},
 };
 
-static struct mtd_partition p2_partitions[] = {
+static struct mtd_partition nor_partitions[] = {
 	/* bootloader (U-Boot, etc) in first sector */
 	{
 	      .name		= "bootloader",
@@ -75,27 +112,47 @@
 	},
 };
 
-static struct flash_platform_data p2_flash_data = {
+static struct flash_platform_data nor_data = {
 	.map_name	= "cfi_probe",
 	.width		= 2,
-	.parts		= p2_partitions,
-	.nr_parts	= ARRAY_SIZE(p2_partitions),
+	.parts		= nor_partitions,
+	.nr_parts	= ARRAY_SIZE(nor_partitions),
 };
 
-static struct resource p2_flash_resource = {
+static struct resource nor_resource = {
 	.start		= OMAP_CS0_PHYS,
 	.end		= OMAP_CS0_PHYS + SZ_32M - 1,
 	.flags		= IORESOURCE_MEM,
 };
 
-static struct platform_device p2_flash_device = {
+static struct platform_device nor_device = {
 	.name		= "omapflash",
 	.id		= 0,
 	.dev		= {
-		.platform_data	= &p2_flash_data,
+		.platform_data	= &nor_data,
 	},
 	.num_resources	= 1,
-	.resource	= &p2_flash_resource,
+	.resource	= &nor_resource,
+};
+
+static struct nand_platform_data nand_data = {
+	.options	= NAND_SAMSUNG_LP_OPTIONS,
+};
+
+static struct resource nand_resource = {
+	.start		= OMAP_CS3_PHYS,
+	.end		= OMAP_CS3_PHYS + SZ_4K - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device nand_device = {
+	.name		= "omapnand",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &nand_data,
+	},
+	.num_resources	= 1,
+	.resource	= &nand_resource,
 };
 
 static struct platform_device smc91x_device = {
@@ -105,17 +162,55 @@
 	.resource	= smc91x_resources,
 };
 
-static struct platform_device *devices[] __initdata = {
-	&p2_flash_device,
-	&smc91x_device,
+static struct resource kp_resources[] = {
+	[0] = {
+		.start	= INT_730_MPUIO_KEYPAD,
+		.end	= INT_730_MPUIO_KEYPAD,
+		.flags	= IORESOURCE_IRQ,
+	},
 };
 
+static struct omap_kp_platform_data kp_data = {
+	.rows	= 8,
+	.cols	= 8,
+	.keymap = p2_keymap,
+};
+
+static struct platform_device kp_device = {
+	.name		= "omap-keypad",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &kp_data,
+	},
+	.num_resources	= ARRAY_SIZE(kp_resources),
+	.resource	= kp_resources,
+};
+
+static struct platform_device lcd_device = {
+	.name		= "lcd_p2",
+	.id		= -1,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&nor_device,
+	&nand_device,
+	&smc91x_device,
+	&kp_device,
+	&lcd_device,
+};
+
+#define P2_NAND_RB_GPIO_PIN	62
+
+static int nand_dev_ready(struct nand_platform_data *data)
+{
+	return omap_get_gpio_datain(P2_NAND_RB_GPIO_PIN);
+}
+
 static struct omap_uart_config perseus2_uart_config __initdata = {
 	.enabled_uarts = ((1 << 0) | (1 << 1)),
 };
 
 static struct omap_lcd_config perseus2_lcd_config __initdata = {
-	.panel_name	= "p2",
 	.ctrl_name	= "internal",
 };
 
@@ -126,7 +221,13 @@
 
 static void __init omap_perseus2_init(void)
 {
-	(void) platform_add_devices(devices, ARRAY_SIZE(devices));
+	if (!(omap_request_gpio(P2_NAND_RB_GPIO_PIN)))
+		nand_data.dev_ready = nand_dev_ready;
+
+	omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
+	omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
 
 	omap_board_config = perseus2_config;
 	omap_board_config_size = ARRAY_SIZE(perseus2_config);
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 52e4a9d..447a586 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -155,9 +155,9 @@
 };
 
 static struct omap_board_config_kernel voiceblue_config[] = {
-	{ OMAP_TAG_USB, &voiceblue_usb_config },
-	{ OMAP_TAG_MMC, &voiceblue_mmc_config },
-	{ OMAP_TAG_UART,	&voiceblue_uart_config },
+	{ OMAP_TAG_USB,  &voiceblue_usb_config },
+	{ OMAP_TAG_MMC,  &voiceblue_mmc_config },
+	{ OMAP_TAG_UART, &voiceblue_uart_config },
 };
 
 static void __init voiceblue_init_irq(void)
@@ -235,7 +235,7 @@
 static int __init voiceblue_setup(void)
 {
 	/* Setup panic notifier */
-	atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
+	notifier_chain_register(&panic_notifier_list, &panic_block);
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index 75110ba..619db18 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -345,7 +345,7 @@
 	 */
 	for (dsor = 2; dsor < 96; ++dsor) {
 		if ((dsor & 1) && dsor > 8)
-		  	continue;
+			continue;
 		if (rate >= 96000000 / dsor)
 			break;
 	}
@@ -687,6 +687,11 @@
 			clk_register(*clkp);
 			continue;
 		}
+
+		if (((*clkp)->flags &CLOCK_IN_OMAP310) && cpu_is_omap310()) {
+			clk_register(*clkp);
+			continue;
+		}
 	}
 
 	info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
@@ -784,7 +789,7 @@
 	clk_enable(&armxor_ck.clk);
 	clk_enable(&armtim_ck.clk); /* This should be done by timer code */
 
-	if (cpu_is_omap1510())
+	if (cpu_is_omap15xx())
 		clk_enable(&arm_gpio_ck);
 
 	return 0;
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
index 4f18d1b..b7c6881 100644
--- a/arch/arm/mach-omap1/clock.h
+++ b/arch/arm/mach-omap1/clock.h
@@ -151,7 +151,7 @@
 	.name		= "ck_ref",
 	.rate		= 12000000,
 	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  ALWAYS_ENABLED,
+			  CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
 	.enable		= &omap1_clk_enable_generic,
 	.disable	= &omap1_clk_disable_generic,
 };
@@ -160,7 +160,7 @@
 	.name		= "ck_dpll1",
 	.parent		= &ck_ref,
 	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  RATE_PROPAGATES | ALWAYS_ENABLED,
+			  CLOCK_IN_OMAP310 | RATE_PROPAGATES | ALWAYS_ENABLED,
 	.enable		= &omap1_clk_enable_generic,
 	.disable	= &omap1_clk_disable_generic,
 };
@@ -183,7 +183,8 @@
 	.name		= "arm_ck",
 	.parent		= &ck_dpll1,
 	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
+			  CLOCK_IN_OMAP310 | RATE_CKCTL | RATE_PROPAGATES |
+			  ALWAYS_ENABLED,
 	.rate_offset	= CKCTL_ARMDIV_OFFSET,
 	.recalc		= &omap1_ckctl_recalc,
 	.enable		= &omap1_clk_enable_generic,
@@ -195,7 +196,8 @@
 		.name		= "armper_ck",
 		.parent		= &ck_dpll1,
 		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-				  RATE_CKCTL | CLOCK_IDLE_CONTROL,
+				  CLOCK_IN_OMAP310 | RATE_CKCTL |
+				  CLOCK_IDLE_CONTROL,
 		.enable_reg	= (void __iomem *)ARM_IDLECT2,
 		.enable_bit	= EN_PERCK,
 		.rate_offset	= CKCTL_PERDIV_OFFSET,
@@ -209,7 +211,7 @@
 static struct clk arm_gpio_ck = {
 	.name		= "arm_gpio_ck",
 	.parent		= &ck_dpll1,
-	.flags		= CLOCK_IN_OMAP1510,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
 	.enable_reg	= (void __iomem *)ARM_IDLECT2,
 	.enable_bit	= EN_GPIOCK,
 	.recalc		= &followparent_recalc,
@@ -222,7 +224,7 @@
 		.name		= "armxor_ck",
 		.parent		= &ck_ref,
 		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-				  CLOCK_IDLE_CONTROL,
+				  CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
 		.enable_reg	= (void __iomem *)ARM_IDLECT2,
 		.enable_bit	= EN_XORPCK,
 		.recalc		= &followparent_recalc,
@@ -237,7 +239,7 @@
 		.name		= "armtim_ck",
 		.parent		= &ck_ref,
 		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-				  CLOCK_IDLE_CONTROL,
+				  CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
 		.enable_reg	= (void __iomem *)ARM_IDLECT2,
 		.enable_bit	= EN_TIMCK,
 		.recalc		= &followparent_recalc,
@@ -252,7 +254,7 @@
 		.name		= "armwdt_ck",
 		.parent		= &ck_ref,
 		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-				  CLOCK_IDLE_CONTROL,
+				  CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
 		.enable_reg	= (void __iomem *)ARM_IDLECT2,
 		.enable_bit	= EN_WDTCK,
 		.recalc		= &omap1_watchdog_recalc,
@@ -344,9 +346,9 @@
 		.name		= "tc_ck",
 		.parent		= &ck_dpll1,
 		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-				  CLOCK_IN_OMAP730 | RATE_CKCTL |
-				  RATE_PROPAGATES | ALWAYS_ENABLED |
-				  CLOCK_IDLE_CONTROL,
+				  CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 |
+				  RATE_CKCTL | RATE_PROPAGATES |
+				  ALWAYS_ENABLED | CLOCK_IDLE_CONTROL,
 		.rate_offset	= CKCTL_TCDIV_OFFSET,
 		.recalc		= &omap1_ckctl_recalc,
 		.enable		= &omap1_clk_enable_generic,
@@ -358,7 +360,8 @@
 static struct clk arminth_ck1510 = {
 	.name		= "arminth_ck",
 	.parent		= &tc_ck.clk,
-	.flags		= CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
+			  ALWAYS_ENABLED,
 	.recalc		= &followparent_recalc,
 	/* Note: On 1510 the frequency follows TC_CK
 	 *
@@ -372,7 +375,8 @@
 	/* No-idle controlled by "tc_ck" */
 	.name		= "tibp_ck",
 	.parent		= &tc_ck.clk,
-	.flags		= CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
+			  ALWAYS_ENABLED,
 	.recalc		= &followparent_recalc,
 	.enable		= &omap1_clk_enable_generic,
 	.disable	= &omap1_clk_disable_generic,
@@ -417,7 +421,7 @@
 	.name		= "dma_ck",
 	.parent		= &tc_ck.clk,
 	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  ALWAYS_ENABLED,
+			  CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
 	.recalc		= &followparent_recalc,
 	.enable		= &omap1_clk_enable_generic,
 	.disable	= &omap1_clk_disable_generic,
@@ -437,7 +441,7 @@
 		.name		= "api_ck",
 		.parent		= &tc_ck.clk,
 		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-				  CLOCK_IDLE_CONTROL,
+				  CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
 		.enable_reg	= (void __iomem *)ARM_IDLECT2,
 		.enable_bit	= EN_APICK,
 		.recalc		= &followparent_recalc,
@@ -451,7 +455,8 @@
 	.clk = {
 		.name		= "lb_ck",
 		.parent		= &tc_ck.clk,
-		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IDLE_CONTROL,
+		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
+				  CLOCK_IDLE_CONTROL,
 		.enable_reg	= (void __iomem *)ARM_IDLECT2,
 		.enable_bit	= EN_LBCK,
 		.recalc		= &followparent_recalc,
@@ -495,8 +500,8 @@
 	.clk = {
 		.name		= "lcd_ck",
 		.parent		= &ck_dpll1,
-		.flags		= CLOCK_IN_OMAP1510 | RATE_CKCTL |
-				  CLOCK_IDLE_CONTROL,
+		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
+				  RATE_CKCTL | CLOCK_IDLE_CONTROL,
 		.enable_reg	= (void __iomem *)ARM_IDLECT2,
 		.enable_bit	= EN_LCDCK,
 		.rate_offset	= CKCTL_LCDDIV_OFFSET,
@@ -512,8 +517,9 @@
 	/* Direct from ULPD, no real parent */
 	.parent		= &armper_ck.clk,
 	.rate		= 12000000,
-	.flags		= CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT |
-			  ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
+			  ENABLE_REG_32BIT | ALWAYS_ENABLED |
+			  CLOCK_NO_IDLE_PARENT,
 	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
 	.enable_bit	= 29,	/* Chooses between 12MHz and 48MHz */
 	.set_rate	= &omap1_set_uart_rate,
@@ -544,8 +550,8 @@
 	.parent		= &armper_ck.clk,
 	.rate		= 12000000,
 	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  ENABLE_REG_32BIT | ALWAYS_ENABLED |
-			  CLOCK_NO_IDLE_PARENT,
+			  CLOCK_IN_OMAP310 | ENABLE_REG_32BIT |
+			  ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
 	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
 	.enable_bit	= 30,	/* Chooses between 12MHz and 48MHz */
 	.set_rate	= &omap1_set_uart_rate,
@@ -559,8 +565,9 @@
 	/* Direct from ULPD, no real parent */
 	.parent		= &armper_ck.clk,
 	.rate		= 12000000,
-	.flags		= CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT |
-			  ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
+			  ENABLE_REG_32BIT | ALWAYS_ENABLED |
+			  CLOCK_NO_IDLE_PARENT,
 	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
 	.enable_bit	= 31,	/* Chooses between 12MHz and 48MHz */
 	.set_rate	= &omap1_set_uart_rate,
@@ -590,7 +597,7 @@
 	/* Direct from ULPD, no parent */
 	.rate		= 6000000,
 	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  RATE_FIXED | ENABLE_REG_32BIT,
+			  CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT,
 	.enable_reg	= (void __iomem *)ULPD_CLOCK_CTRL,
 	.enable_bit	= USB_MCLK_EN_BIT,
 	.enable		= &omap1_clk_enable_generic,
@@ -601,7 +608,7 @@
 	.name		= "usb_hhc_ck",
 	/* Direct from ULPD, no parent */
 	.rate		= 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
-	.flags		= CLOCK_IN_OMAP1510 |
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
 			  RATE_FIXED | ENABLE_REG_32BIT,
 	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
 	.enable_bit	= USB_HOST_HHC_UHOST_EN,
@@ -637,7 +644,9 @@
 	.name		= "mclk",
 	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
 	.rate		= 12000000,
-	.flags		= CLOCK_IN_OMAP1510 | RATE_FIXED,
+ 	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED,
+ 	.enable_reg	= (void __iomem *)SOFT_REQ_REG,
+ 	.enable_bit	= 6,
 	.enable		= &omap1_clk_enable_generic,
 	.disable	= &omap1_clk_disable_generic,
 };
@@ -659,7 +668,7 @@
 	.name		= "bclk",
 	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
 	.rate		= 12000000,
-	.flags		= CLOCK_IN_OMAP1510 | RATE_FIXED,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED,
 	.enable		= &omap1_clk_enable_generic,
 	.disable	= &omap1_clk_disable_generic,
 };
@@ -678,12 +687,14 @@
 };
 
 static struct clk mmc1_ck = {
-	.name		= "mmc1_ck",
+	.name		= "mmc_ck",
+	.id		= 1,
 	/* Functional clock is direct from ULPD, interface clock is ARMPER */
 	.parent		= &armper_ck.clk,
 	.rate		= 48000000,
 	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+			  CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT |
+			  CLOCK_NO_IDLE_PARENT,
 	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
 	.enable_bit	= 23,
 	.enable		= &omap1_clk_enable_generic,
@@ -691,7 +702,8 @@
 };
 
 static struct clk mmc2_ck = {
-	.name		= "mmc2_ck",
+	.name		= "mmc_ck",
+	.id		= 2,
 	/* Functional clock is direct from ULPD, interface clock is ARMPER */
 	.parent		= &armper_ck.clk,
 	.rate		= 48000000,
@@ -706,7 +718,7 @@
 static struct clk virtual_ck_mpu = {
 	.name		= "mpu",
 	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  VIRTUAL_CLOCK | ALWAYS_ENABLED,
+			  CLOCK_IN_OMAP310 | VIRTUAL_CLOCK | ALWAYS_ENABLED,
 	.parent		= &arm_ck, /* Is smarter alias for */
 	.recalc		= &followparent_recalc,
 	.set_rate	= &omap1_select_table_rate,
@@ -715,6 +727,20 @@
 	.disable	= &omap1_clk_disable_generic,
 };
 
+/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK
+remains active during MPU idle whenever this is enabled */
+static struct clk i2c_fck = {
+	.name		= "i2c_fck",
+	.id		= 1,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT |
+			  ALWAYS_ENABLED,
+	.parent		= &armxor_ck.clk,
+	.recalc		= &followparent_recalc,
+	.enable		= &omap1_clk_enable_generic,
+	.disable	= &omap1_clk_disable_generic,
+};
+
 static struct clk * onchip_clks[] = {
 	/* non-ULPD clocks */
 	&ck_ref,
@@ -763,6 +789,7 @@
 	&mmc2_ck,
 	/* Virtual clocks */
 	&virtual_ck_mpu,
+	&i2c_fck,
 };
 
 #endif
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index ecbc475..876c38d 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -99,6 +99,45 @@
 static inline void omap_init_rtc(void) {}
 #endif
 
+#if defined(CONFIG_OMAP_STI)
+
+#define OMAP1_STI_BASE		IO_ADDRESS(0xfffea000)
+#define OMAP1_STI_CHANNEL_BASE	(OMAP1_STI_BASE + 0x400)
+
+static struct resource sti_resources[] = {
+	{
+		.start		= OMAP1_STI_BASE,
+		.end		= OMAP1_STI_BASE + SZ_1K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP1_STI_CHANNEL_BASE,
+		.end		= OMAP1_STI_CHANNEL_BASE + SZ_1K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= INT_1610_STI,
+		.flags		= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device sti_device = {
+	.name		= "sti",
+	.id		= -1,
+	.dev = {
+		.release	= omap_nop_release,
+	},
+	.num_resources	= ARRAY_SIZE(sti_resources),
+	.resource	= sti_resources,
+};
+
+static inline void omap_init_sti(void)
+{
+	platform_device_register(&sti_device);
+}
+#else
+static inline void omap_init_sti(void) {}
+#endif
 
 /*-------------------------------------------------------------------------*/
 
@@ -129,6 +168,7 @@
 	 */
 	omap_init_irda();
 	omap_init_rtc();
+	omap_init_sti();
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index 82d556b..be3a2a4 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -18,6 +18,7 @@
 #include <asm/io.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/tc.h>
+#include <asm/arch/omapfb.h>
 
 extern int omap1_clk_init(void);
 extern void omap_check_revision(void);
@@ -110,7 +111,7 @@
 	}
 #endif
 #ifdef CONFIG_ARCH_OMAP15XX
-	if (cpu_is_omap1510()) {
+	if (cpu_is_omap15xx()) {
 		iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
 	}
 #endif
@@ -121,6 +122,7 @@
 #endif
 
 	omap_sram_init();
+	omapfb_reserve_mem();
 }
 
 /*
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index ed65a7d..a0431c0 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -60,7 +60,7 @@
 	unsigned long wake_enable;
 };
 
-static unsigned int irq_bank_count = 0;
+static unsigned int irq_bank_count;
 static struct omap_irq_bank *irq_banks;
 
 static inline unsigned int irq_bank_readl(int bank, int offset)
@@ -142,28 +142,28 @@
 
 #ifdef CONFIG_ARCH_OMAP730
 static struct omap_irq_bank omap730_irq_banks[] = {
-	{ .base_reg = OMAP_IH1_BASE, 		.trigger_map = 0xb3f8e22f },
-	{ .base_reg = OMAP_IH2_BASE, 		.trigger_map = 0xfdb9c1f2 },
+	{ .base_reg = OMAP_IH1_BASE,		.trigger_map = 0xb3f8e22f },
+	{ .base_reg = OMAP_IH2_BASE,		.trigger_map = 0xfdb9c1f2 },
 	{ .base_reg = OMAP_IH2_BASE + 0x100,	.trigger_map = 0x800040f3 },
 };
 #endif
 
 #ifdef CONFIG_ARCH_OMAP15XX
 static struct omap_irq_bank omap1510_irq_banks[] = {
-	{ .base_reg = OMAP_IH1_BASE, 		.trigger_map = 0xb3febfff },
-	{ .base_reg = OMAP_IH2_BASE, 		.trigger_map = 0xffbfffed },
+	{ .base_reg = OMAP_IH1_BASE,		.trigger_map = 0xb3febfff },
+	{ .base_reg = OMAP_IH2_BASE,		.trigger_map = 0xffbfffed },
 };
 static struct omap_irq_bank omap310_irq_banks[] = {
-	{ .base_reg = OMAP_IH1_BASE, 		.trigger_map = 0xb3faefc3 },
-	{ .base_reg = OMAP_IH2_BASE, 		.trigger_map = 0x65b3c061 },
+	{ .base_reg = OMAP_IH1_BASE,		.trigger_map = 0xb3faefc3 },
+	{ .base_reg = OMAP_IH2_BASE,		.trigger_map = 0x65b3c061 },
 };
 #endif
 
 #if defined(CONFIG_ARCH_OMAP16XX)
 
 static struct omap_irq_bank omap1610_irq_banks[] = {
-	{ .base_reg = OMAP_IH1_BASE, 		.trigger_map = 0xb3fefe8f },
-	{ .base_reg = OMAP_IH2_BASE, 		.trigger_map = 0xfdb7c1fd },
+	{ .base_reg = OMAP_IH1_BASE,		.trigger_map = 0xb3fefe8f },
+	{ .base_reg = OMAP_IH2_BASE,		.trigger_map = 0xfdb7c1fd },
 	{ .base_reg = OMAP_IH2_BASE + 0x100,	.trigger_map = 0xffffb7ff },
 	{ .base_reg = OMAP_IH2_BASE + 0x200,	.trigger_map = 0xffffffff },
 };
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c
index d4b8d62..10fe0b3 100644
--- a/arch/arm/mach-omap1/mux.c
+++ b/arch/arm/mach-omap1/mux.c
@@ -35,16 +35,20 @@
 
 #ifdef CONFIG_ARCH_OMAP730
 struct pin_config __initdata_or_module omap730_pins[] = {
-MUX_CFG_730("E2_730_KBR0",	12,   21,    0,	  0,   20,   1,	  NA,	 0,  0)
-MUX_CFG_730("J7_730_KBR1",	12,   25,    0,	  0,   24,   1,	  NA,	 0,  0)
-MUX_CFG_730("E1_730_KBR2",	12,   29,    0,	  0,   28,   1,	  NA,	 0,  0)
-MUX_CFG_730("F3_730_KBR3",	13,    1,    0,	  0,   0,    1,	  NA,	 0,  0)
-MUX_CFG_730("D2_730_KBR4",	13,    5,    0,	  0,   4,    1,	  NA,	 0,  0)
-MUX_CFG_730("C2_730_KBC0",	13,    9,    0,	  0,	8,   1,	  NA,	 0,  0)
-MUX_CFG_730("D3_730_KBC1",	13,   13,    0,	  0,   12,   1,	  NA,	 0,  0)
-MUX_CFG_730("E4_730_KBC2",	13,   17,    0,	  0,   16,   1,	  NA,	 0,  0)
-MUX_CFG_730("F4_730_KBC3",	13,   21,    0,	  0,   20,   1,	  NA,	 0,  0)
-MUX_CFG_730("E3_730_KBC4",	13,   25,    0,	  0,   24,   1,	  NA,	 0,  0)
+MUX_CFG_730("E2_730_KBR0",        12,   21,    0,   20,   1, 0)
+MUX_CFG_730("J7_730_KBR1",        12,   25,    0,   24,   1, 0)
+MUX_CFG_730("E1_730_KBR2",        12,   29,    0,   28,   1, 0)
+MUX_CFG_730("F3_730_KBR3",        13,    1,    0,    0,   1, 0)
+MUX_CFG_730("D2_730_KBR4",        13,    5,    0,    4,   1, 0)
+MUX_CFG_730("C2_730_KBC0",        13,    9,    0,    8,   1, 0)
+MUX_CFG_730("D3_730_KBC1",        13,   13,    0,   12,   1, 0)
+MUX_CFG_730("E4_730_KBC2",        13,   17,    0,   16,   1, 0)
+MUX_CFG_730("F4_730_KBC3",        13,   21,    0,   20,   1, 0)
+MUX_CFG_730("E3_730_KBC4",        13,   25,    0,   24,   1, 0)
+
+MUX_CFG_730("AA17_730_USB_DM",     2,   21,    0,   20,   0, 0)
+MUX_CFG_730("W16_730_USB_PU_EN",   2,   25,    0,   24,   0, 0)
+MUX_CFG_730("W17_730_USB_VBUSI",   2,   29,    0,   28,   0, 0)
 };
 #endif
 
@@ -73,8 +77,8 @@
 MUX_CFG("Y15_1610_UART3_RTS",	 A,    0,    1,	  2,   6,   0,	 NA,	 0,  0)
 
 /* PWT & PWL, conflicts with UART3 */
-MUX_CFG("PWT",		 	 6,    0,    2,	  0,  30,   0,	 NA,	 0,  0)
-MUX_CFG("PWL",		 	 6,    3,    1,	  0,  31,   1,	 NA,	 0,  0)
+MUX_CFG("PWT",			 6,    0,    2,	  0,  30,   0,	 NA,	 0,  0)
+MUX_CFG("PWL",			 6,    3,    1,	  0,  31,   1,	 NA,	 0,  0)
 
 /* USB internal master generic */
 MUX_CFG("R18_USB_VBUS",		 7,    9,    2,	  1,  11,   0,	 NA,	 0,  1)
@@ -151,7 +155,7 @@
 
 /* Misc ballouts */
 MUX_CFG("BALLOUT_V8_ARMIO3",	 B,   18,    0,	  2,  25,   1,	 NA,	 0,  1)
-MUX_CFG("N20_HDQ",	       6,   18,    1,   1,   4,   0,    1,     4,  0)
+MUX_CFG("N20_HDQ",		 6,   18,    1,   1,   4,   0,    1,     4,  0)
 
 /* OMAP-1610 MMC2 */
 MUX_CFG("W8_1610_MMC2_DAT0",	 B,   21,    6,	  2,  23,   1,	  2,	 1,  1)
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
new file mode 100644
index 0000000..ddf6b07
--- /dev/null
+++ b/arch/arm/mach-omap1/pm.c
@@ -0,0 +1,770 @@
+/*
+ * linux/arch/arm/mach-omap1/pm.c
+ *
+ * OMAP Power Management Routines
+ *
+ * Original code for the SA11x0:
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * Modified for the PXA250 by Nicolas Pitre:
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ *
+ * Modified for the OMAP1510 by David Singleton:
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ *
+ * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.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
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * 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/pm.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/pm.h>
+#include <linux/interrupt.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/atomic.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/irqs.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sram.h>
+#include <asm/arch/tc.h>
+#include <asm/arch/pm.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/tps65010.h>
+#include <asm/arch/dma.h>
+#include <asm/arch/dsp_common.h>
+#include <asm/arch/dmtimer.h>
+
+static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
+static unsigned short dsp_sleep_save[DSP_SLEEP_SAVE_SIZE];
+static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
+static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE];
+static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
+static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
+
+static unsigned short enable_dyn_sleep = 1;
+
+static ssize_t omap_pm_sleep_while_idle_show(struct subsystem * subsys, char *buf)
+{
+	return sprintf(buf, "%hu\n", enable_dyn_sleep);
+}
+
+static ssize_t omap_pm_sleep_while_idle_store(struct subsystem * subsys,
+					      const char * buf,
+					      size_t n)
+{
+	unsigned short value;
+	if (sscanf(buf, "%hu", &value) != 1 ||
+	    (value != 0 && value != 1)) {
+		printk(KERN_ERR "idle_sleep_store: Invalid value\n");
+		return -EINVAL;
+	}
+	enable_dyn_sleep = value;
+	return n;
+}
+
+static struct subsys_attribute sleep_while_idle_attr = {
+	.attr   = {
+		.name = __stringify(sleep_while_idle),
+		.mode = 0644,
+	},
+	.show   = omap_pm_sleep_while_idle_show,
+	.store  = omap_pm_sleep_while_idle_store,
+};
+
+extern struct subsystem power_subsys;
+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
+ * going idle we continue to do idle even if we get
+ * a clock tick interrupt . .
+ */
+void omap_pm_idle(void)
+{
+	extern __u32 arm_idlect1_mask;
+	__u32 use_idlect1 = arm_idlect1_mask;
+#ifndef CONFIG_OMAP_MPU_TIMER
+	int do_sleep;
+#endif
+
+	local_irq_disable();
+	local_fiq_disable();
+	if (need_resched()) {
+		local_fiq_enable();
+		local_irq_enable();
+		return;
+	}
+
+	/*
+	 * 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.
+	 */
+	timer_dyn_reprogram();
+
+#ifdef CONFIG_OMAP_MPU_TIMER
+#warning Enable 32kHz OS timer in order to allow sleep states in idle
+	use_idlect1 = use_idlect1 & ~(1 << 9);
+#else
+
+	do_sleep = 0;
+	while (enable_dyn_sleep) {
+
+#ifdef CONFIG_CBUS_TAHVO_USB
+		extern int vbus_active;
+		/* Clock requirements? */
+		if (vbus_active)
+			break;
+#endif
+		do_sleep = 1;
+		break;
+	}
+
+#ifdef CONFIG_OMAP_DM_TIMER
+	use_idlect1 = omap_dm_timer_modify_idlect_mask(use_idlect1);
+#endif
+
+	if (omap_dma_running()) {
+		use_idlect1 &= ~(1 << 6);
+		if (omap_lcd_dma_ext_running())
+			use_idlect1 &= ~(1 << 12);
+	}
+
+	/* We should be able to remove the do_sleep variable and multiple
+	 * tests above as soon as drivers, timer and DMA code have been fixed.
+	 * Even the sleep block count should become obsolete. */
+	if ((use_idlect1 != ~0) || !do_sleep) {
+
+		__u32 saved_idlect1 = omap_readl(ARM_IDLECT1);
+		if (cpu_is_omap15xx())
+			use_idlect1 &= OMAP1510_BIG_SLEEP_REQUEST;
+		else
+			use_idlect1 &= OMAP1610_IDLECT1_SLEEP_VAL;
+		omap_writel(use_idlect1, ARM_IDLECT1);
+		__asm__ volatile ("mcr	p15, 0, r0, c7, c0, 4");
+		omap_writel(saved_idlect1, ARM_IDLECT1);
+
+		local_fiq_enable();
+		local_irq_enable();
+		return;
+	}
+	omap_sram_suspend(omap_readl(ARM_IDLECT1),
+			  omap_readl(ARM_IDLECT2));
+#endif
+
+	local_fiq_enable();
+	local_irq_enable();
+}
+
+/*
+ * Configuration of the wakeup event is board specific. For the
+ * moment we put it into this helper function. Later it may move
+ * to board specific files.
+ */
+static void omap_pm_wakeup_setup(void)
+{
+	u32 level1_wake = 0;
+	u32 level2_wake = OMAP_IRQ_BIT(INT_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_omap730())
+		level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) |
+			OMAP_IRQ_BIT(INT_730_IH2_IRQ);
+	else if (cpu_is_omap15xx())
+		level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
+			OMAP_IRQ_BIT(INT_1510_IH2_IRQ);
+	else if (cpu_is_omap16xx())
+		level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
+			OMAP_IRQ_BIT(INT_1610_IH2_IRQ);
+
+	omap_writel(~level1_wake, OMAP_IH1_MIR);
+
+	if (cpu_is_omap730()) {
+		omap_writel(~level2_wake, OMAP_IH2_0_MIR);
+		omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) |
+				OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)),
+				OMAP_IH2_1_MIR);
+	} else if (cpu_is_omap15xx()) {
+		level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
+		omap_writel(~level2_wake,  OMAP_IH2_MIR);
+	} else if (cpu_is_omap16xx()) {
+		level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
+		omap_writel(~level2_wake, OMAP_IH2_0_MIR);
+
+		/* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
+		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, recalculate in cascade order */
+	omap_writel(1, OMAP_IH2_CONTROL);
+	omap_writel(1, OMAP_IH1_CONTROL);
+}
+
+#define EN_DSPCK	13	/* ARM_CKCTL */
+#define EN_APICK	6	/* ARM_IDLECT2 */
+#define DSP_EN		1	/* ARM_RSTCT1 */
+
+void omap_pm_suspend(void)
+{
+	unsigned long arg0 = 0, arg1 = 0;
+
+	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 (FIXME: NOTE: already disabled)
+	 */
+
+	local_irq_disable();
+	local_fiq_disable();
+
+	/*
+	 * Step 2: save registers
+	 *
+	 * The omap is a strange/beautiful device. The caches, memory
+	 * and register state are preserved across power saves.
+	 * We have to save and restore very little register state to
+	 * idle the omap.
+         *
+	 * Save interrupt, MPUI, ARM and UPLD control registers.
+	 */
+
+	if (cpu_is_omap730()) {
+		MPUI730_SAVE(OMAP_IH1_MIR);
+		MPUI730_SAVE(OMAP_IH2_0_MIR);
+		MPUI730_SAVE(OMAP_IH2_1_MIR);
+		MPUI730_SAVE(MPUI_CTRL);
+		MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
+		MPUI730_SAVE(MPUI_DSP_API_CONFIG);
+		MPUI730_SAVE(EMIFS_CONFIG);
+		MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
+
+	} else if (cpu_is_omap15xx()) {
+		MPUI1510_SAVE(OMAP_IH1_MIR);
+		MPUI1510_SAVE(OMAP_IH2_MIR);
+		MPUI1510_SAVE(MPUI_CTRL);
+		MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
+		MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
+		MPUI1510_SAVE(EMIFS_CONFIG);
+		MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
+	} else if (cpu_is_omap16xx()) {
+		MPUI1610_SAVE(OMAP_IH1_MIR);
+		MPUI1610_SAVE(OMAP_IH2_0_MIR);
+		MPUI1610_SAVE(OMAP_IH2_1_MIR);
+		MPUI1610_SAVE(OMAP_IH2_2_MIR);
+		MPUI1610_SAVE(OMAP_IH2_3_MIR);
+		MPUI1610_SAVE(MPUI_CTRL);
+		MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
+		MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
+		MPUI1610_SAVE(EMIFS_CONFIG);
+		MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
+	}
+
+	ARM_SAVE(ARM_CKCTL);
+	ARM_SAVE(ARM_IDLECT1);
+	ARM_SAVE(ARM_IDLECT2);
+	if (!(cpu_is_omap15xx()))
+		ARM_SAVE(ARM_IDLECT3);
+	ARM_SAVE(ARM_EWUPCT);
+	ARM_SAVE(ARM_RSTCT1);
+	ARM_SAVE(ARM_RSTCT2);
+	ARM_SAVE(ARM_SYSST);
+	ULPD_SAVE(ULPD_CLOCK_CTRL);
+	ULPD_SAVE(ULPD_STATUS_REQ);
+
+	/* (Step 3 removed - we now allow deep sleep by default) */
+
+	/*
+	 * Step 4: OMAP DSP Shutdown
+	 */
+
+	/* stop DSP */
+	omap_writew(omap_readw(ARM_RSTCT1) & ~(1 << DSP_EN), ARM_RSTCT1);
+
+	/* shut down dsp_ck */
+	omap_writew(omap_readw(ARM_CKCTL) & ~(1 << EN_DSPCK), ARM_CKCTL);
+
+	/* temporarily enabling api_ck to access DSP registers */
+	omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
+
+	/* save DSP registers */
+	DSP_SAVE(DSP_IDLECT2);
+
+	/* Stop all DSP domain clocks */
+	__raw_writew(0, DSP_IDLECT2);
+
+	/*
+	 * Step 5: Wakeup Event Setup
+	 */
+
+	omap_pm_wakeup_setup();
+
+	/*
+	 * Step 6: ARM and Traffic controller shutdown
+	 */
+
+	/* disable ARM watchdog */
+	omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
+	omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
+
+	/*
+	 * Step 6b: ARM and Traffic controller shutdown
+	 *
+	 * Step 6 continues here. Prepare jump to power management
+	 * assembly code in internal SRAM.
+	 *
+	 * Since the omap_cpu_suspend routine has been copied to
+	 * SRAM, we'll do an indirect procedure call to it and pass the
+	 * contents of arm_idlect1 and arm_idlect2 so it can restore
+	 * them when it wakes up and it will return.
+	 */
+
+	arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1];
+	arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2];
+
+	/*
+	 * Step 6c: ARM and Traffic controller shutdown
+	 *
+	 * Jump to assembly code. The processor will stay there
+	 * until wake up.
+	 */
+        omap_sram_suspend(arg0, arg1);
+
+	/*
+	 * If we are here, processor is woken up!
+	 */
+
+	/*
+	 * Restore DSP clocks
+	 */
+
+	/* again temporarily enabling api_ck to access DSP registers */
+	omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
+
+	/* Restore DSP domain clocks */
+	DSP_RESTORE(DSP_IDLECT2);
+
+	/*
+	 * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
+	 */
+
+	if (!(cpu_is_omap15xx()))
+		ARM_RESTORE(ARM_IDLECT3);
+	ARM_RESTORE(ARM_CKCTL);
+	ARM_RESTORE(ARM_EWUPCT);
+	ARM_RESTORE(ARM_RSTCT1);
+	ARM_RESTORE(ARM_RSTCT2);
+	ARM_RESTORE(ARM_SYSST);
+	ULPD_RESTORE(ULPD_CLOCK_CTRL);
+	ULPD_RESTORE(ULPD_STATUS_REQ);
+
+	if (cpu_is_omap730()) {
+		MPUI730_RESTORE(EMIFS_CONFIG);
+		MPUI730_RESTORE(EMIFF_SDRAM_CONFIG);
+		MPUI730_RESTORE(OMAP_IH1_MIR);
+		MPUI730_RESTORE(OMAP_IH2_0_MIR);
+		MPUI730_RESTORE(OMAP_IH2_1_MIR);
+	} else if (cpu_is_omap15xx()) {
+		MPUI1510_RESTORE(MPUI_CTRL);
+		MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
+		MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
+		MPUI1510_RESTORE(EMIFS_CONFIG);
+		MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG);
+		MPUI1510_RESTORE(OMAP_IH1_MIR);
+		MPUI1510_RESTORE(OMAP_IH2_MIR);
+	} else if (cpu_is_omap16xx()) {
+		MPUI1610_RESTORE(MPUI_CTRL);
+		MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG);
+		MPUI1610_RESTORE(MPUI_DSP_API_CONFIG);
+		MPUI1610_RESTORE(EMIFS_CONFIG);
+		MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG);
+
+		MPUI1610_RESTORE(OMAP_IH1_MIR);
+		MPUI1610_RESTORE(OMAP_IH2_0_MIR);
+		MPUI1610_RESTORE(OMAP_IH2_1_MIR);
+		MPUI1610_RESTORE(OMAP_IH2_2_MIR);
+		MPUI1610_RESTORE(OMAP_IH2_3_MIR);
+	}
+
+	omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG);
+
+	/*
+	 * Reenable interrupts
+	 */
+
+	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()) {
+		/* Let LED1 (D9) blink again */
+		tps65010_set_led(LED1, BLINK);
+	}
+}
+
+#if defined(DEBUG) && defined(CONFIG_PROC_FS)
+static int g_read_completed;
+
+/*
+ * Read system PM registers for debugging
+ */
+static int omap_pm_read_proc(
+	char *page_buffer,
+	char **my_first_byte,
+	off_t virtual_start,
+	int length,
+	int *eof,
+	void *data)
+{
+	int my_buffer_offset = 0;
+	char * const my_base = page_buffer;
+
+	ARM_SAVE(ARM_CKCTL);
+	ARM_SAVE(ARM_IDLECT1);
+	ARM_SAVE(ARM_IDLECT2);
+	if (!(cpu_is_omap15xx()))
+		ARM_SAVE(ARM_IDLECT3);
+	ARM_SAVE(ARM_EWUPCT);
+	ARM_SAVE(ARM_RSTCT1);
+	ARM_SAVE(ARM_RSTCT2);
+	ARM_SAVE(ARM_SYSST);
+
+	ULPD_SAVE(ULPD_IT_STATUS);
+	ULPD_SAVE(ULPD_CLOCK_CTRL);
+	ULPD_SAVE(ULPD_SOFT_REQ);
+	ULPD_SAVE(ULPD_STATUS_REQ);
+	ULPD_SAVE(ULPD_DPLL_CTRL);
+	ULPD_SAVE(ULPD_POWER_CTRL);
+
+	if (cpu_is_omap730()) {
+		MPUI730_SAVE(MPUI_CTRL);
+		MPUI730_SAVE(MPUI_DSP_STATUS);
+		MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
+		MPUI730_SAVE(MPUI_DSP_API_CONFIG);
+		MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
+		MPUI730_SAVE(EMIFS_CONFIG);
+	} else if (cpu_is_omap15xx()) {
+		MPUI1510_SAVE(MPUI_CTRL);
+		MPUI1510_SAVE(MPUI_DSP_STATUS);
+		MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
+		MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
+		MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
+		MPUI1510_SAVE(EMIFS_CONFIG);
+	} else if (cpu_is_omap16xx()) {
+		MPUI1610_SAVE(MPUI_CTRL);
+		MPUI1610_SAVE(MPUI_DSP_STATUS);
+		MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
+		MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
+		MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
+		MPUI1610_SAVE(EMIFS_CONFIG);
+	}
+
+	if (virtual_start == 0) {
+		g_read_completed = 0;
+
+		my_buffer_offset += sprintf(my_base + my_buffer_offset,
+		   "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"
+		   "ARM_SYSST_REG:            0x%-8x     \n"
+		   "ULPD_IT_STATUS_REG:       0x%-4x     \n"
+		   "ULPD_CLOCK_CTRL_REG:      0x%-4x     \n"
+		   "ULPD_SOFT_REQ_REG:        0x%-4x     \n"
+		   "ULPD_DPLL_CTRL_REG:       0x%-4x     \n"
+		   "ULPD_STATUS_REQ_REG:      0x%-4x     \n"
+		   "ULPD_POWER_CTRL_REG:      0x%-4x     \n",
+		   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),
+		   ARM_SHOW(ARM_SYSST),
+		   ULPD_SHOW(ULPD_IT_STATUS),
+		   ULPD_SHOW(ULPD_CLOCK_CTRL),
+		   ULPD_SHOW(ULPD_SOFT_REQ),
+		   ULPD_SHOW(ULPD_DPLL_CTRL),
+		   ULPD_SHOW(ULPD_STATUS_REQ),
+		   ULPD_SHOW(ULPD_POWER_CTRL));
+
+		if (cpu_is_omap730()) {
+			my_buffer_offset += sprintf(my_base + my_buffer_offset,
+			   "MPUI730_CTRL_REG	     0x%-8x \n"
+			   "MPUI730_DSP_STATUS_REG:      0x%-8x \n"
+			   "MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
+			   "MPUI730_DSP_API_CONFIG_REG:  0x%-8x \n"
+			   "MPUI730_SDRAM_CONFIG_REG:    0x%-8x \n"
+			   "MPUI730_EMIFS_CONFIG_REG:    0x%-8x \n",
+			   MPUI730_SHOW(MPUI_CTRL),
+			   MPUI730_SHOW(MPUI_DSP_STATUS),
+			   MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG),
+			   MPUI730_SHOW(MPUI_DSP_API_CONFIG),
+			   MPUI730_SHOW(EMIFF_SDRAM_CONFIG),
+			   MPUI730_SHOW(EMIFS_CONFIG));
+		} else if (cpu_is_omap15xx()) {
+			my_buffer_offset += sprintf(my_base + my_buffer_offset,
+			   "MPUI1510_CTRL_REG             0x%-8x \n"
+			   "MPUI1510_DSP_STATUS_REG:      0x%-8x \n"
+			   "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
+			   "MPUI1510_DSP_API_CONFIG_REG:  0x%-8x \n"
+			   "MPUI1510_SDRAM_CONFIG_REG:    0x%-8x \n"
+			   "MPUI1510_EMIFS_CONFIG_REG:    0x%-8x \n",
+			   MPUI1510_SHOW(MPUI_CTRL),
+			   MPUI1510_SHOW(MPUI_DSP_STATUS),
+			   MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG),
+			   MPUI1510_SHOW(MPUI_DSP_API_CONFIG),
+			   MPUI1510_SHOW(EMIFF_SDRAM_CONFIG),
+			   MPUI1510_SHOW(EMIFS_CONFIG));
+		} else if (cpu_is_omap16xx()) {
+			my_buffer_offset += sprintf(my_base + my_buffer_offset,
+			   "MPUI1610_CTRL_REG             0x%-8x \n"
+			   "MPUI1610_DSP_STATUS_REG:      0x%-8x \n"
+			   "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
+			   "MPUI1610_DSP_API_CONFIG_REG:  0x%-8x \n"
+			   "MPUI1610_SDRAM_CONFIG_REG:    0x%-8x \n"
+			   "MPUI1610_EMIFS_CONFIG_REG:    0x%-8x \n",
+			   MPUI1610_SHOW(MPUI_CTRL),
+			   MPUI1610_SHOW(MPUI_DSP_STATUS),
+			   MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG),
+			   MPUI1610_SHOW(MPUI_DSP_API_CONFIG),
+			   MPUI1610_SHOW(EMIFF_SDRAM_CONFIG),
+			   MPUI1610_SHOW(EMIFS_CONFIG));
+		}
+
+		g_read_completed++;
+	} else if (g_read_completed >= 1) {
+		 *eof = 1;
+		 return 0;
+	}
+	g_read_completed++;
+
+	*my_first_byte = page_buffer;
+	return  my_buffer_offset;
+}
+
+static void omap_pm_init_proc(void)
+{
+	struct proc_dir_entry *entry;
+
+	entry = create_proc_read_entry("driver/omap_pm",
+				       S_IWUSR | S_IRUGO, NULL,
+				       omap_pm_read_proc, NULL);
+}
+
+#endif /* DEBUG && CONFIG_PROC_FS */
+
+static void (*saved_idle)(void) = NULL;
+
+/*
+ *	omap_pm_prepare - Do preliminary suspend work.
+ *	@state:		suspend state we're entering.
+ *
+ */
+static int omap_pm_prepare(suspend_state_t state)
+{
+	int error = 0;
+
+	/* We cannot sleep in idle until we have resumed */
+	saved_idle = pm_idle;
+	pm_idle = NULL;
+
+	switch (state)
+	{
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		break;
+
+	case PM_SUSPEND_DISK:
+		return -ENOTSUPP;
+
+	default:
+		return -EINVAL;
+	}
+
+	return error;
+}
+
+
+/*
+ *	omap_pm_enter - Actually enter a sleep state.
+ *	@state:		State we're entering.
+ *
+ */
+
+static int omap_pm_enter(suspend_state_t state)
+{
+	switch (state)
+	{
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		omap_pm_suspend();
+		break;
+
+	case PM_SUSPEND_DISK:
+		return -ENOTSUPP;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+/**
+ *	omap_pm_finish - Finish up suspend sequence.
+ *	@state:		State we're coming out of.
+ *
+ *	This is called after we wake back up (or if entering the sleep state
+ *	failed).
+ */
+
+static int omap_pm_finish(suspend_state_t state)
+{
+	pm_idle = saved_idle;
+	return 0;
+}
+
+
+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,
+	.finish		= omap_pm_finish,
+};
+
+static int __init omap_pm_init(void)
+{
+	printk("Power Management for TI OMAP.\n");
+
+	/*
+	 * 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.
+	 */
+	if (cpu_is_omap730()) {
+		omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend,
+						omap730_idle_loop_suspend_sz);
+		omap_sram_suspend = omap_sram_push(omap730_cpu_suspend,
+						   omap730_cpu_suspend_sz);
+	} else if (cpu_is_omap15xx()) {
+		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;
+
+	if (cpu_is_omap730())
+		setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq);
+	else if (cpu_is_omap16xx())
+		setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
+
+	/* 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_omap730())
+		omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3);
+	else 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
+
+	subsys_create_file(&power_subsys, &sleep_while_idle_attr);
+
+	if (cpu_is_omap16xx()) {
+		/* configure LOW_PWR pin */
+		omap_cfg_reg(T20_1610_LOW_PWR);
+	}
+
+	return 0;
+}
+__initcall(omap_pm_init);
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index e924e0c..9b4cd69 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -30,9 +30,9 @@
 #include <asm/arch/pm.h>
 #endif
 
-static struct clk * uart1_ck = NULL;
-static struct clk * uart2_ck = NULL;
-static struct clk * uart3_ck = NULL;
+static struct clk * uart1_ck;
+static struct clk * uart2_ck;
+static struct clk * uart3_ck;
 
 static inline unsigned int omap_serial_in(struct plat_serial8250_port *up,
 					  int offset)
diff --git a/arch/arm/plat-omap/sleep.S b/arch/arm/mach-omap1/sleep.S
similarity index 92%
rename from arch/arm/plat-omap/sleep.S
rename to arch/arm/mach-omap1/sleep.S
index 4cd7d29..e58295e 100644
--- a/arch/arm/plat-omap/sleep.S
+++ b/arch/arm/mach-omap1/sleep.S
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/plat-omap/sleep.S
+ * linux/arch/arm/mach-omap1/sleep.S
  *
  * Low-level OMAP730/1510/1610 sleep/wakeUp support
  *
@@ -383,60 +383,133 @@
 	mcr	p15, 0, r0, c7, c10, 4
 	nop
 
-	@ load base address of Traffic Controller
+	@ Load base address of Traffic Controller
 	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
+	@ Prepare to put SDRAM into self-refresh manually
 	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
+	@ Prepare to put EMIFS to Sleep
 	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
+	@ Load base address of ARM_IDLECT1 and ARM_IDLECT2
 	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
 	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
 	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
 
-	@ turn off clock domains
-	@ do not disable PERCK (0x04)
+	@ Turn off clock domains
+	@ 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
+	@ Request ARM idle
 	mov	r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff
 	orr	r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00
 	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
 
-	@ 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
  */
 	mov	r2, #0
 	mcr	p15, 0, r2, c7, c0, 4		@ wait for interrupt
+
+	@ Errata (HEL3SU467, section 1.4.4) specifies nop-instructions
+	@ according to this formula:
+	@ 2 + (4*DPLL_MULT)/DPLL_DIV/ARMDIV
+	@ Max DPLL_MULT = 18
+	@ DPLL_DIV = 1
+	@ ARMDIV = 1
+	@ => 74 nop-instructions
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop	@10
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop	@20
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop	@30
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop	@40
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop	@50
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop	@60
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop	@70
+	nop
+	nop
+	nop
+	nop	@74
 /*
  * omap1610_cpu_suspend()'s resume point.
  *
  * It will just start executing here, so we'll restore stuff from the
  * stack.
  */
-	@ re-enable Icache
-	mcr	p15, 0, r9, c1, c0, 0
-
-	@ reset the ARM_IDLECT1 and ARM_IDLECT2.
+	@ Restore the ARM_IDLECT1 and ARM_IDLECT2.
 	strh	r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
 	strh	r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
 
@@ -444,7 +517,7 @@
 	str	r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
 	str	r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
 
-	@ restore regs and return
+	@ Restore regs and return
 	ldmfd	sp!, {r0 - r12, pc}
 
 ENTRY(omap1610_cpu_suspend_sz)
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
index cdbf4d7..a85fe60 100644
--- a/arch/arm/mach-omap1/time.c
+++ b/arch/arm/mach-omap1/time.c
@@ -51,8 +51,6 @@
 
 struct sys_timer omap_timer;
 
-#ifdef CONFIG_OMAP_MPU_TIMER
-
 /*
  * ---------------------------------------------------------------------------
  * MPU timer
@@ -222,195 +220,6 @@
 
 	return cycles_2_ns(ticks64);
 }
-#endif	/* CONFIG_OMAP_MPU_TIMER */
-
-#ifdef CONFIG_OMAP_32K_TIMER
-
-#ifdef CONFIG_ARCH_OMAP15XX
-#error OMAP 32KHz timer does not currently work on 15XX!
-#endif
-
-/*
- * ---------------------------------------------------------------------------
- * 32KHz OS timer
- *
- * This currently works only on 16xx, as 1510 does not have the continuous
- * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track
- * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer
- * on 1510 would be possible, but the timer would not be as accurate as
- * with the 32KHz synchronized timer.
- * ---------------------------------------------------------------------------
- */
-#define OMAP_32K_TIMER_BASE		0xfffb9000
-#define OMAP_32K_TIMER_CR		0x08
-#define OMAP_32K_TIMER_TVR		0x00
-#define OMAP_32K_TIMER_TCR		0x04
-
-#define OMAP_32K_TICKS_PER_HZ		(32768 / HZ)
-
-/*
- * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
- * so with HZ = 100, TVR = 327.68.
- */
-#define OMAP_32K_TIMER_TICK_PERIOD	((32768 / HZ) - 1)
-#define TIMER_32K_SYNCHRONIZED		0xfffbc410
-
-#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate)			\
-				(((nr_jiffies) * (clock_rate)) / HZ)
-
-static inline void omap_32k_timer_write(int val, int reg)
-{
-	omap_writew(val, reg + OMAP_32K_TIMER_BASE);
-}
-
-static inline unsigned long omap_32k_timer_read(int reg)
-{
-	return omap_readl(reg + OMAP_32K_TIMER_BASE) & 0xffffff;
-}
-
-/*
- * The 32KHz synchronized timer is an additional timer on 16xx.
- * It is always running.
- */
-static inline unsigned long omap_32k_sync_timer_read(void)
-{
-	return omap_readl(TIMER_32K_SYNCHRONIZED);
-}
-
-static inline void omap_32k_timer_start(unsigned long load_val)
-{
-	omap_32k_timer_write(load_val, OMAP_32K_TIMER_TVR);
-	omap_32k_timer_write(0x0f, OMAP_32K_TIMER_CR);
-}
-
-static inline void omap_32k_timer_stop(void)
-{
-	omap_32k_timer_write(0x0, OMAP_32K_TIMER_CR);
-}
-
-/*
- * Rounds down to nearest usec. Note that this will overflow for larger values.
- */
-static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k)
-{
-	return (ticks_32k * 5*5*5*5*5*5) >> 9;
-}
-
-/*
- * Rounds down to nearest nsec.
- */
-static inline unsigned long long
-omap_32k_ticks_to_nsecs(unsigned long ticks_32k)
-{
-	return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9;
-}
-
-static unsigned long omap_32k_last_tick = 0;
-
-/*
- * Returns elapsed usecs since last 32k timer interrupt
- */
-static unsigned long omap_32k_timer_gettimeoffset(void)
-{
-	unsigned long now = omap_32k_sync_timer_read();
-	return omap_32k_ticks_to_usecs(now - omap_32k_last_tick);
-}
-
-/*
- * Returns current time from boot in nsecs. It's OK for this to wrap
- * around for now, as it's just a relative time stamp.
- */
-unsigned long long sched_clock(void)
-{
-	return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read());
-}
-
-/*
- * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this
- * function is also called from other interrupts to remove latency
- * issues with dynamic tick. In the dynamic tick case, we need to lock
- * with irqsave.
- */
-static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
-					    struct pt_regs *regs)
-{
-	unsigned long flags;
-	unsigned long now;
-
-	write_seqlock_irqsave(&xtime_lock, flags);
-	now = omap_32k_sync_timer_read();
-
-	while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) {
-		omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
-		timer_tick(regs);
-	}
-
-	/* Restart timer so we don't drift off due to modulo or dynamic tick.
-	 * By default we program the next timer to be continuous to avoid
-	 * latencies during high system load. During dynamic tick operation the
-	 * continuous timer can be overridden from pm_idle to be longer.
-	 */
-	omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now);
-	write_sequnlock_irqrestore(&xtime_lock, flags);
-
-	return IRQ_HANDLED;
-}
-
-#ifdef CONFIG_NO_IDLE_HZ
-/*
- * Programs the next timer interrupt needed. Called when dynamic tick is
- * enabled, and to reprogram the ticks to skip from pm_idle. Note that
- * we can keep the timer continuous, and don't need to set it to run in
- * one-shot mode. This is because the timer will get reprogrammed again
- * after next interrupt.
- */
-void omap_32k_timer_reprogram(unsigned long next_tick)
-{
-	omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1);
-}
-
-static struct irqaction omap_32k_timer_irq;
-extern struct timer_update_handler timer_update;
-
-static int omap_32k_timer_enable_dyn_tick(void)
-{
-	/* No need to reprogram timer, just use the next interrupt */
-	return 0;
-}
-
-static int omap_32k_timer_disable_dyn_tick(void)
-{
-	omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
-	return 0;
-}
-
-static struct dyn_tick_timer omap_dyn_tick_timer = {
-	.enable		= omap_32k_timer_enable_dyn_tick,
-	.disable	= omap_32k_timer_disable_dyn_tick,
-	.reprogram	= omap_32k_timer_reprogram,
-	.handler	= omap_32k_timer_interrupt,
-};
-#endif	/* CONFIG_NO_IDLE_HZ */
-
-static struct irqaction omap_32k_timer_irq = {
-	.name		= "32KHz timer",
-	.flags		= SA_INTERRUPT | SA_TIMER,
-	.handler	= omap_32k_timer_interrupt,
-};
-
-static __init void omap_init_32k_timer(void)
-{
-
-#ifdef CONFIG_NO_IDLE_HZ
-	omap_timer.dyn_tick = &omap_dyn_tick_timer;
-#endif
-
-	setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
-	omap_timer.offset  = omap_32k_timer_gettimeoffset;
-	omap_32k_last_tick = omap_32k_sync_timer_read();
-	omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
-}
-#endif	/* CONFIG_OMAP_32K_TIMER */
 
 /*
  * ---------------------------------------------------------------------------
@@ -419,13 +228,7 @@
  */
 static void __init omap_timer_init(void)
 {
-#if defined(CONFIG_OMAP_MPU_TIMER)
 	omap_init_mpu_timer();
-#elif defined(CONFIG_OMAP_32K_TIMER)
-	omap_init_32k_timer();
-#else
-#error No system timer selected in Kconfig!
-#endif
 }
 
 struct sys_timer omap_timer = {
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 5788809..537dd2e 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -20,3 +20,6 @@
 	bool "OMAP 2420 H4 board"
 	depends on ARCH_OMAP2 && ARCH_OMAP24XX
 
+config MACH_OMAP_APOLLON
+	bool "OMAP 2420 Apollon board"
+	depends on ARCH_OMAP2 && ARCH_OMAP24XX
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 4204116..111eaa6 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -3,11 +3,15 @@
 #
 
 # Common support
-obj-y := irq.o id.o io.o sram-fn.o clock.o mux.o devices.o serial.o
+obj-y := irq.o id.o io.o sram-fn.o memory.o prcm.o clock.o mux.o devices.o serial.o
 
 obj-$(CONFIG_OMAP_MPU_TIMER)		+= timer-gp.o
 
+# Power Management
+obj-$(CONFIG_PM) += pm.o sleep.o
+
 # Specific board support
 obj-$(CONFIG_MACH_OMAP_GENERIC)		+= board-generic.o
 obj-$(CONFIG_MACH_OMAP_H4)		+= board-h4.o
+obj-$(CONFIG_MACH_OMAP_APOLLON)		+= board-apollon.o
 
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
new file mode 100644
index 0000000..6c6ba17
--- /dev/null
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -0,0 +1,285 @@
+/*
+ * linux/arch/arm/mach-omap/omap2/board-apollon.c
+ *
+ * Copyright (C) 2005,2006 Samsung Electronics
+ * Author: Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * Modified from mach-omap/omap2/board-h4.c
+ *
+ * Code for apollon OMAP2 board. Should work on many OMAP2 systems where
+ * the bootloader passes the board-specific data to the kernel.
+ * Do not put any board specific code to this file; create a new machine
+ * type if you need custom low-level initializations.
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/onenand.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/board.h>
+#include <asm/arch/common.h>
+#include "prcm-regs.h"
+
+/* LED & Switch macros */
+#define LED0_GPIO13		13
+#define LED1_GPIO14		14
+#define LED2_GPIO15		15
+#define SW_ENTER_GPIO16		16
+#define SW_UP_GPIO17		17
+#define SW_DOWN_GPIO58		58
+
+static struct mtd_partition apollon_partitions[] = {
+	{
+		.name		= "X-Loader + U-Boot",
+		.offset		= 0,
+		.size		= SZ_128K,
+		.mask_flags	= MTD_WRITEABLE,
+	},
+	{
+		.name		= "params",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_128K,
+	},
+	{
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_2M,
+	},
+	{
+		.name		= "rootfs",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_16M,
+	},
+	{
+		.name		= "filesystem00",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_32M,
+	},
+	{
+		.name		= "filesystem01",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct flash_platform_data apollon_flash_data = {
+	.parts		= apollon_partitions,
+	.nr_parts	= ARRAY_SIZE(apollon_partitions),
+};
+
+static struct resource apollon_flash_resource = {
+	.start		= APOLLON_CS0_BASE,
+	.end		= APOLLON_CS0_BASE + SZ_128K,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device apollon_onenand_device = {
+	.name		= "onenand",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &apollon_flash_data,
+	},
+	.num_resources	= ARRAY_SIZE(&apollon_flash_resource),
+	.resource	= &apollon_flash_resource,
+};
+
+static struct resource apollon_smc91x_resources[] = {
+	[0] = {
+		.start	= APOLLON_ETHR_START,		/* Physical */
+		.end	= APOLLON_ETHR_START + 0xf,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
+		.end	= OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device apollon_smc91x_device = {
+	.name		= "smc91x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(apollon_smc91x_resources),
+	.resource	= apollon_smc91x_resources,
+};
+
+static struct platform_device apollon_lcd_device = {
+	.name		= "apollon_lcd",
+	.id		= -1,
+};
+
+static struct platform_device *apollon_devices[] __initdata = {
+	&apollon_onenand_device,
+	&apollon_smc91x_device,
+	&apollon_lcd_device,
+};
+
+static inline void __init apollon_init_smc91x(void)
+{
+	/* Make sure CS1 timings are correct */
+	GPMC_CONFIG1_1 = 0x00011203;
+	GPMC_CONFIG2_1 = 0x001f1f01;
+	GPMC_CONFIG3_1 = 0x00080803;
+	GPMC_CONFIG4_1 = 0x1c091c09;
+	GPMC_CONFIG5_1 = 0x041f1f1f;
+	GPMC_CONFIG6_1 = 0x000004c4;
+	GPMC_CONFIG7_1 = 0x00000f40 | (APOLLON_CS1_BASE >> 24);
+	udelay(100);
+
+	omap_cfg_reg(W4__24XX_GPIO74);
+	if (omap_request_gpio(APOLLON_ETHR_GPIO_IRQ) < 0) {
+		printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
+			APOLLON_ETHR_GPIO_IRQ);
+		return;
+	}
+	omap_set_gpio_direction(APOLLON_ETHR_GPIO_IRQ, 1);
+}
+
+static void __init omap_apollon_init_irq(void)
+{
+	omap2_init_common_hw();
+	omap_init_irq();
+	omap_gpio_init();
+	apollon_init_smc91x();
+}
+
+static struct omap_uart_config apollon_uart_config __initdata = {
+	.enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2),
+};
+
+static struct omap_mmc_config apollon_mmc_config __initdata = {
+	.mmc [0] = {
+		.enabled 	= 0,
+		.wire4		= 0,
+		.wp_pin		= -1,
+		.power_pin	= -1,
+		.switch_pin	= -1,
+	},
+};
+
+static struct omap_lcd_config apollon_lcd_config __initdata = {
+	.ctrl_name	= "internal",
+};
+
+static struct omap_board_config_kernel apollon_config[] = {
+	{ OMAP_TAG_UART,	&apollon_uart_config },
+	{ OMAP_TAG_MMC,		&apollon_mmc_config },
+	{ OMAP_TAG_LCD,		&apollon_lcd_config },
+};
+
+static void __init apollon_led_init(void)
+{
+	/* LED0 - AA10 */
+	omap_cfg_reg(AA10_242X_GPIO13);
+	omap_request_gpio(LED0_GPIO13);
+	omap_set_gpio_direction(LED0_GPIO13, 0);
+	omap_set_gpio_dataout(LED0_GPIO13, 0);
+	/* LED1  - AA6 */
+	omap_cfg_reg(AA6_242X_GPIO14);
+	omap_request_gpio(LED1_GPIO14);
+	omap_set_gpio_direction(LED1_GPIO14, 0);
+	omap_set_gpio_dataout(LED1_GPIO14, 0);
+	/* LED2  - AA4 */
+	omap_cfg_reg(AA4_242X_GPIO15);
+	omap_request_gpio(LED2_GPIO15);
+	omap_set_gpio_direction(LED2_GPIO15, 0);
+	omap_set_gpio_dataout(LED2_GPIO15, 0);
+}
+
+static irqreturn_t apollon_sw_interrupt(int irq, void *ignored, struct pt_regs *regs)
+{
+	static unsigned int led0, led1, led2;
+
+	if (irq == OMAP_GPIO_IRQ(SW_ENTER_GPIO16))
+		omap_set_gpio_dataout(LED0_GPIO13, led0 ^= 1);
+	else if (irq == OMAP_GPIO_IRQ(SW_UP_GPIO17))
+		omap_set_gpio_dataout(LED1_GPIO14, led1 ^= 1);
+	else if (irq == OMAP_GPIO_IRQ(SW_DOWN_GPIO58))
+		omap_set_gpio_dataout(LED2_GPIO15, led2 ^= 1);
+
+	return IRQ_HANDLED;
+}
+
+static void __init apollon_sw_init(void)
+{
+	/* Enter SW - Y11 */
+	omap_cfg_reg(Y11_242X_GPIO16);
+	omap_request_gpio(SW_ENTER_GPIO16);
+	omap_set_gpio_direction(SW_ENTER_GPIO16, 1);
+	/* Up SW - AA12 */
+	omap_cfg_reg(AA12_242X_GPIO17);
+	omap_request_gpio(SW_UP_GPIO17);
+	omap_set_gpio_direction(SW_UP_GPIO17, 1);
+	/* Down SW - AA8 */
+	omap_cfg_reg(AA8_242X_GPIO58);
+	omap_request_gpio(SW_DOWN_GPIO58);
+	omap_set_gpio_direction(SW_DOWN_GPIO58, 1);
+
+	set_irq_type(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), IRQT_RISING);
+	if (request_irq(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), &apollon_sw_interrupt,
+				SA_SHIRQ, "enter sw",
+				&apollon_sw_interrupt))
+		return;
+	set_irq_type(OMAP_GPIO_IRQ(SW_UP_GPIO17), IRQT_RISING);
+	if (request_irq(OMAP_GPIO_IRQ(SW_UP_GPIO17), &apollon_sw_interrupt,
+				SA_SHIRQ, "up sw",
+				&apollon_sw_interrupt))
+		return;
+	set_irq_type(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), IRQT_RISING);
+	if (request_irq(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), &apollon_sw_interrupt,
+				SA_SHIRQ, "down sw",
+				&apollon_sw_interrupt))
+		return;
+}
+
+static void __init omap_apollon_init(void)
+{
+	apollon_led_init();
+	apollon_sw_init();
+
+	/* REVISIT: where's the correct place */
+	omap_cfg_reg(W19_24XX_SYS_NIRQ);
+
+	/*
+ 	 * Make sure the serial ports are muxed on at this point.
+	 * You have to mux them off in device drivers later on
+	 * if not needed.
+	 */
+	platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
+	omap_board_config = apollon_config;
+	omap_board_config_size = ARRAY_SIZE(apollon_config);
+	omap_serial_init();
+}
+
+static void __init omap_apollon_map_io(void)
+{
+	omap2_map_common_io();
+}
+
+MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
+	/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
+	.phys_io	= 0x48000000,
+	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= omap_apollon_map_io,
+	.init_irq	= omap_apollon_init_irq,
+	.init_machine	= omap_apollon_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index a300d63..4933fce 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -17,6 +17,8 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/input.h>
 
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
@@ -25,15 +27,57 @@
 #include <asm/mach/flash.h>
 
 #include <asm/arch/gpio.h>
+#include <asm/arch/gpioexpander.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/usb.h>
+#include <asm/arch/irda.h>
 #include <asm/arch/board.h>
 #include <asm/arch/common.h>
-#include <asm/arch/prcm.h>
+#include <asm/arch/keypad.h>
+#include <asm/arch/menelaus.h>
+#include <asm/arch/dma.h>
+#include "prcm-regs.h"
 
 #include <asm/io.h>
 #include <asm/delay.h>
 
+static unsigned int row_gpios[6] = { 88, 89, 124, 11, 6, 96 };
+static unsigned int col_gpios[7] = { 90, 91, 100, 36, 12, 97, 98 };
+
+static int h4_keymap[] = {
+	KEY(0, 0, KEY_LEFT),
+	KEY(0, 1, KEY_RIGHT),
+	KEY(0, 2, KEY_A),
+	KEY(0, 3, KEY_B),
+	KEY(0, 4, KEY_C),
+	KEY(1, 0, KEY_DOWN),
+	KEY(1, 1, KEY_UP),
+	KEY(1, 2, KEY_E),
+	KEY(1, 3, KEY_F),
+	KEY(1, 4, KEY_G),
+	KEY(2, 0, KEY_ENTER),
+	KEY(2, 1, KEY_I),
+	KEY(2, 2, KEY_J),
+	KEY(2, 3, KEY_K),
+	KEY(2, 4, KEY_3),
+	KEY(3, 0, KEY_M),
+	KEY(3, 1, KEY_N),
+	KEY(3, 2, KEY_O),
+	KEY(3, 3, KEY_P),
+	KEY(3, 4, KEY_Q),
+	KEY(4, 0, KEY_R),
+	KEY(4, 1, KEY_4),
+	KEY(4, 2, KEY_T),
+	KEY(4, 3, KEY_U),
+	KEY(4, 4, KEY_ENTER),
+	KEY(5, 0, KEY_V),
+	KEY(5, 1, KEY_W),
+	KEY(5, 2, KEY_L),
+	KEY(5, 3, KEY_S),
+	KEY(5, 4, KEY_ENTER),
+	0
+};
+
 static struct mtd_partition h4_partitions[] = {
 	/* bootloader (U-Boot, etc) in first sector */
 	{
@@ -108,9 +152,123 @@
 	.resource	= h4_smc91x_resources,
 };
 
+/* Select between the IrDA and aGPS module
+ */
+static int h4_select_irda(struct device *dev, int state)
+{
+	unsigned char expa;
+	int err = 0;
+
+	if ((err = read_gpio_expa(&expa, 0x21))) {
+		printk(KERN_ERR "Error reading from I/O expander\n");
+		return err;
+	}
+
+	/* 'P6' enable/disable IRDA_TX and IRDA_RX */
+	if (state & IR_SEL) {	/* IrDa */
+		if ((err = write_gpio_expa(expa | 0x01, 0x21))) {
+			printk(KERN_ERR "Error writing to I/O expander\n");
+			return err;
+		}
+	} else {
+		if ((err = write_gpio_expa(expa & ~0x01, 0x21))) {
+			printk(KERN_ERR "Error writing to I/O expander\n");
+			return err;
+		}
+	}
+	return err;
+}
+
+static void set_trans_mode(void *data)
+{
+	int *mode = data;
+	unsigned char expa;
+	int err = 0;
+
+	if ((err = read_gpio_expa(&expa, 0x20)) != 0) {
+		printk(KERN_ERR "Error reading from I/O expander\n");
+	}
+
+	expa &= ~0x01;
+
+	if (!(*mode & IR_SIRMODE)) { /* MIR/FIR */
+		expa |= 0x01;
+	}
+
+	if ((err = write_gpio_expa(expa, 0x20)) != 0) {
+		printk(KERN_ERR "Error writing to I/O expander\n");
+	}
+}
+
+static int h4_transceiver_mode(struct device *dev, int mode)
+{
+	struct omap_irda_config *irda_config = dev->platform_data;
+
+	cancel_delayed_work(&irda_config->gpio_expa);
+	PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode);
+	schedule_work(&irda_config->gpio_expa);
+
+	return 0;
+}
+
+static struct omap_irda_config h4_irda_data = {
+	.transceiver_cap	= IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
+	.transceiver_mode	= h4_transceiver_mode,
+	.select_irda	 	= h4_select_irda,
+	.rx_channel		= OMAP24XX_DMA_UART3_RX,
+	.tx_channel		= OMAP24XX_DMA_UART3_TX,
+	.dest_start		= OMAP_UART3_BASE,
+	.src_start		= OMAP_UART3_BASE,
+	.tx_trigger		= OMAP24XX_DMA_UART3_TX,
+	.rx_trigger		= OMAP24XX_DMA_UART3_RX,
+};
+
+static struct resource h4_irda_resources[] = {
+	[0] = {
+		.start	= INT_24XX_UART3_IRQ,
+		.end	= INT_24XX_UART3_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device h4_irda_device = {
+	.name		= "omapirda",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &h4_irda_data,
+	},
+	.num_resources	= 1,
+	.resource	= h4_irda_resources,
+};
+
+static struct omap_kp_platform_data h4_kp_data = {
+	.rows		= 6,
+	.cols		= 7,
+	.keymap 	= h4_keymap,
+	.rep		= 1,
+	.row_gpios 	= row_gpios,
+	.col_gpios 	= col_gpios,
+};
+
+static struct platform_device h4_kp_device = {
+	.name		= "omap-keypad",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &h4_kp_data,
+	},
+};
+
+static struct platform_device h4_lcd_device = {
+	.name		= "lcd_h4",
+	.id		= -1,
+};
+
 static struct platform_device *h4_devices[] __initdata = {
 	&h4_smc91x_device,
 	&h4_flash_device,
+	&h4_irda_device,
+	&h4_kp_device,
+	&h4_lcd_device,
 };
 
 static inline void __init h4_init_smc91x(void)
@@ -157,7 +315,6 @@
 };
 
 static struct omap_lcd_config h4_lcd_config __initdata = {
-	.panel_name	= "h4",
 	.ctrl_name	= "internal",
 };
 
@@ -174,6 +331,19 @@
 	 * You have to mux them off in device drivers later on
 	 * if not needed.
 	 */
+#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
+	omap_cfg_reg(K15_24XX_UART3_TX);
+	omap_cfg_reg(K14_24XX_UART3_RX);
+#endif
+
+#if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE)
+	if (omap_has_menelaus()) {
+		row_gpios[5] = 0;
+		col_gpios[2] = 15;
+		col_gpios[6] = 18;
+	}
+#endif
+
 	platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
 	omap_board_config = h4_config;
 	omap_board_config_size = ARRAY_SIZE(h4_config);
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 180f675..72eb4bf 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -28,14 +28,14 @@
 
 #include <asm/arch/clock.h>
 #include <asm/arch/sram.h>
-#include <asm/arch/prcm.h>
 
+#include "prcm-regs.h"
+#include "memory.h"
 #include "clock.h"
 
 //#define DOWN_VARIABLE_DPLL 1			/* Experimental */
 
 static struct prcm_config *curr_prcm_set;
-static struct memory_timings mem_timings;
 static u32 curr_perf_level = PRCM_FULL_SPEED;
 
 /*-------------------------------------------------------------------------
@@ -54,11 +54,13 @@
 
 static u32 omap2_get_dpll_rate(struct clk * tclk)
 {
-	int dpll_clk, dpll_mult, dpll_div, amult;
+	long long dpll_clk;
+	int dpll_mult, dpll_div, amult;
 
 	dpll_mult = (CM_CLKSEL1_PLL >> 12) & 0x03ff;	/* 10 bits */
 	dpll_div = (CM_CLKSEL1_PLL >> 8) & 0x0f;	/* 4 bits */
-	dpll_clk = (tclk->parent->rate * dpll_mult) / (dpll_div + 1);
+	dpll_clk = (long long)tclk->parent->rate * dpll_mult;
+	do_div(dpll_clk, dpll_div + 1);
 	amult = CM_CLKSEL2_PLL & 0x3;
 	dpll_clk *= amult;
 
@@ -385,75 +387,23 @@
 		return 0;
 }
 
-static void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
-{
-	unsigned long dll_cnt;
-	u32 fast_dll = 0;
-
-	mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */
-
-	/* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
-	 * In the case of 2422, its ok to use CS1 instead of CS0.
-	 */
-
-#if 0	/* FIXME: Enable after 24xx cpu detection works */
-	ctype = get_cpu_type();
-	if (cpu_is_omap2422())
-		mem_timings.base_cs = 1;
-	else
-#endif
-		mem_timings.base_cs = 0;
-
-	if (mem_timings.m_type != M_DDR)
-		return;
-
-	/* With DDR we need to determine the low frequency DLL value */
-	if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL))
-		mem_timings.dll_mode = M_UNLOCK;
-	else
-		mem_timings.dll_mode = M_LOCK;
-
-	if (mem_timings.base_cs == 0) {
-		fast_dll = SDRC_DLLA_CTRL;
-		dll_cnt = SDRC_DLLA_STATUS & 0xff00;
-	} else {
-		fast_dll = SDRC_DLLB_CTRL;
-		dll_cnt = SDRC_DLLB_STATUS & 0xff00;
-	}
-	if (force_lock_to_unlock_mode) {
-		fast_dll &= ~0xff00;
-		fast_dll |= dll_cnt;		/* Current lock mode */
-	}
-	mem_timings.fast_dll_ctrl = fast_dll;
-
-	/* No disruptions, DDR will be offline & C-ABI not followed */
-	omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl,
-			    mem_timings.fast_dll_ctrl,
-			    mem_timings.base_cs,
-			    force_lock_to_unlock_mode);
-	mem_timings.slow_dll_ctrl &= 0xff00;	/* Keep lock value */
-
-	/* Turn status into unlock ctrl */
-	mem_timings.slow_dll_ctrl |=
-		((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2));
-
-	/* 90 degree phase for anything below 133Mhz */
-	mem_timings.slow_dll_ctrl |= (1 << 1);
-}
-
 static u32 omap2_reprogram_sdrc(u32 level, u32 force)
 {
+	u32 slow_dll_ctrl, fast_dll_ctrl, m_type;
 	u32 prev = curr_perf_level, flags;
 
 	if ((curr_perf_level == level) && !force)
 		return prev;
 
+	m_type = omap2_memory_get_type();
+	slow_dll_ctrl = omap2_memory_get_slow_dll_ctrl();
+	fast_dll_ctrl = omap2_memory_get_fast_dll_ctrl();
+
 	if (level == PRCM_HALF_SPEED) {
 		local_irq_save(flags);
 		PRCM_VOLTSETUP = 0xffff;
 		omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED,
-					  mem_timings.slow_dll_ctrl,
-					  mem_timings.m_type);
+					  slow_dll_ctrl, m_type);
 		curr_perf_level = PRCM_HALF_SPEED;
 		local_irq_restore(flags);
 	}
@@ -461,8 +411,7 @@
 		local_irq_save(flags);
 		PRCM_VOLTSETUP = 0xffff;
 		omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED,
-					  mem_timings.fast_dll_ctrl,
-					  mem_timings.m_type);
+					  fast_dll_ctrl, m_type);
 		curr_perf_level = PRCM_FULL_SPEED;
 		local_irq_restore(flags);
 	}
@@ -650,7 +599,7 @@
 		case 13:				/* dss2 */
 			mask = 0x1; break;
 		case 25:				/* usb */
-			mask = 0xf; break;
+			mask = 0x7; break;
 		}
 	}
 
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 6cab20b..6c78d47 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -33,20 +33,6 @@
 #define RATE_IN_242X	(1 << 0)
 #define RATE_IN_243X	(1 << 1)
 
-/* Memory timings */
-#define M_DDR		1
-#define M_LOCK_CTRL	(1 << 2)
-#define M_UNLOCK	0
-#define M_LOCK		1
-
-struct memory_timings {
-	u32 m_type;		/* ddr = 1, sdr = 0 */
-	u32 dll_mode;		/* use lock mode = 1, unlock mode = 0 */
-	u32 slow_dll_ctrl;	/* unlock mode, dll value for slow speed */
-	u32 fast_dll_ctrl;	/* unlock mode, dll value for fast speed */
-	u32 base_cs;		/* base chip select to use for calculations */
-};
-
 /* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated.
  * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP
  * CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM
@@ -731,6 +717,16 @@
 	.recalc		= &omap2_clksel_recalc,
 };
 
+static struct clk emul_ck = {
+	.name		= "emul_ck",
+	.parent		= &func_54m_ck,
+	.flags		= CLOCK_IN_OMAP242X,
+	.enable_reg	= (void __iomem *)&PRCM_CLKEMUL_CTRL,
+	.enable_bit	= 0,
+	.recalc		= &omap2_propagate_rate,
+
+};
+
 /*
  * MPU clock domain
  *	Clocks:
@@ -1702,7 +1698,8 @@
 };
 
 static struct clk i2c2_ick = {
-	.name		= "i2c2_ick",
+	.name		= "i2c_ick",
+	.id		= 2,
 	.parent		= &l4_ck,
 	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
@@ -1711,7 +1708,8 @@
 };
 
 static struct clk i2c2_fck = {
-	.name		= "i2c2_fck",
+	.name		= "i2c_fck",
+	.id		= 2,
 	.parent		= &func_12m_ck,
 	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
@@ -1729,7 +1727,8 @@
 };
 
 static struct clk i2c1_ick = {
-	.name		= "i2c1_ick",
+	.name		= "i2c_ick",
+	.id		= 1,
 	.parent		= &l4_ck,
 	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
@@ -1738,7 +1737,8 @@
 };
 
 static struct clk i2c1_fck = {
-	.name		= "i2c1_fck",
+	.name		= "i2c_fck",
+	.id		= 1,
 	.parent		= &func_12m_ck,
 	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
 	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
@@ -1971,6 +1971,7 @@
 	&wdt1_osc_ck,
 	&sys_clkout,
 	&sys_clkout2,
+	&emul_ck,
 	/* mpu domain clocks */
 	&mpu_ck,
 	/* dsp domain clocks */
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 7181edb..def9e53 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -74,6 +74,47 @@
 
 #endif
 
+#if defined(CONFIG_OMAP_STI)
+
+#define OMAP2_STI_BASE		IO_ADDRESS(0x48068000)
+#define OMAP2_STI_CHANNEL_BASE	0x54000000
+#define OMAP2_STI_IRQ		4
+
+static struct resource sti_resources[] = {
+	{
+		.start		= OMAP2_STI_BASE,
+		.end		= OMAP2_STI_BASE + 0x7ff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP2_STI_CHANNEL_BASE,
+		.end		= OMAP2_STI_CHANNEL_BASE + SZ_64K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP2_STI_IRQ,
+		.flags		= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device sti_device = {
+	.name		= "sti",
+	.id		= -1,
+	.dev = {
+		.release	= omap_nop_release,
+	},
+	.num_resources	= ARRAY_SIZE(sti_resources),
+	.resource	= sti_resources,
+};
+
+static inline void omap_init_sti(void)
+{
+	platform_device_register(&sti_device);
+}
+#else
+static inline void omap_init_sti(void) {}
+#endif
+
 /*-------------------------------------------------------------------------*/
 
 static int __init omap2_init_devices(void)
@@ -82,6 +123,7 @@
 	 * in alphabetical order so they're easier to sort through.
 	 */
 	omap_init_i2c();
+	omap_init_sti();
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 8ea67bf..7d57116 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -16,9 +16,13 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 
-#include <asm/mach/map.h>
+#include <asm/tlb.h>
 #include <asm/io.h>
+
+#include <asm/mach/map.h>
+
 #include <asm/arch/mux.h>
+#include <asm/arch/omapfb.h>
 
 extern void omap_sram_init(void);
 extern int omap2_clk_init(void);
@@ -43,11 +47,24 @@
 	}
 };
 
-void __init omap_map_common_io(void)
+void __init omap2_map_common_io(void)
 {
 	iotable_init(omap2_io_desc, ARRAY_SIZE(omap2_io_desc));
+
+	/* Normally devicemaps_init() would flush caches and tlb after
+	 * mdesc->map_io(), but we must also do it here because of the CPU
+	 * revision check below.
+	 */
+	local_flush_tlb_all();
+	flush_cache_all();
+
 	omap2_check_revision();
 	omap_sram_init();
+	omapfb_reserve_mem();
+}
+
+void __init omap2_init_common_hw(void)
+{
 	omap2_mux_init();
 	omap2_clk_init();
 }
diff --git a/arch/arm/mach-omap2/memory.c b/arch/arm/mach-omap2/memory.c
new file mode 100644
index 0000000..1d925d6
--- /dev/null
+++ b/arch/arm/mach-omap2/memory.c
@@ -0,0 +1,102 @@
+/*
+ * linux/arch/arm/mach-omap2/memory.c
+ *
+ * Memory timing related functions for OMAP24XX
+ *
+ * Copyright (C) 2005 Texas Instruments Inc.
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * 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/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+
+#include <asm/io.h>
+
+#include <asm/arch/clock.h>
+#include <asm/arch/sram.h>
+
+#include "prcm-regs.h"
+#include "memory.h"
+
+static struct memory_timings mem_timings;
+
+u32 omap2_memory_get_slow_dll_ctrl(void)
+{
+	return mem_timings.slow_dll_ctrl;
+}
+
+u32 omap2_memory_get_fast_dll_ctrl(void)
+{
+	return mem_timings.fast_dll_ctrl;
+}
+
+u32 omap2_memory_get_type(void)
+{
+	return mem_timings.m_type;
+}
+
+void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
+{
+	unsigned long dll_cnt;
+	u32 fast_dll = 0;
+
+	mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */
+
+	/* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
+	 * In the case of 2422, its ok to use CS1 instead of CS0.
+	 */
+	if (cpu_is_omap2422())
+		mem_timings.base_cs = 1;
+	else
+		mem_timings.base_cs = 0;
+
+	if (mem_timings.m_type != M_DDR)
+		return;
+
+	/* With DDR we need to determine the low frequency DLL value */
+	if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL))
+		mem_timings.dll_mode = M_UNLOCK;
+	else
+		mem_timings.dll_mode = M_LOCK;
+
+	if (mem_timings.base_cs == 0) {
+		fast_dll = SDRC_DLLA_CTRL;
+		dll_cnt = SDRC_DLLA_STATUS & 0xff00;
+	} else {
+		fast_dll = SDRC_DLLB_CTRL;
+		dll_cnt = SDRC_DLLB_STATUS & 0xff00;
+	}
+	if (force_lock_to_unlock_mode) {
+		fast_dll &= ~0xff00;
+		fast_dll |= dll_cnt;		/* Current lock mode */
+	}
+	/* set fast timings with DLL filter disabled */
+	mem_timings.fast_dll_ctrl = (fast_dll | (3 << 8));
+
+	/* No disruptions, DDR will be offline & C-ABI not followed */
+	omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl,
+			    mem_timings.fast_dll_ctrl,
+			    mem_timings.base_cs,
+			    force_lock_to_unlock_mode);
+	mem_timings.slow_dll_ctrl &= 0xff00;	/* Keep lock value */
+
+	/* Turn status into unlock ctrl */
+	mem_timings.slow_dll_ctrl |=
+		((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2));
+
+	/* 90 degree phase for anything below 133Mhz + disable DLL filter */
+	mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8));
+}
diff --git a/arch/arm/mach-omap2/memory.h b/arch/arm/mach-omap2/memory.h
new file mode 100644
index 0000000..d212eea
--- /dev/null
+++ b/arch/arm/mach-omap2/memory.h
@@ -0,0 +1,34 @@
+/*
+ * linux/arch/arm/mach-omap2/memory.h
+ *
+ * Interface for memory timing related functions for OMAP24XX
+ *
+ * Copyright (C) 2005 Texas Instruments Inc.
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * 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.
+ */
+
+/* Memory timings */
+#define M_DDR		1
+#define M_LOCK_CTRL	(1 << 2)
+#define M_UNLOCK	0
+#define M_LOCK		1
+
+struct memory_timings {
+	u32 m_type;		/* ddr = 1, sdr = 0 */
+	u32 dll_mode;		/* use lock mode = 1, unlock mode = 0 */
+	u32 slow_dll_ctrl;	/* unlock mode, dll value for slow speed */
+	u32 fast_dll_ctrl;	/* unlock mode, dll value for fast speed */
+	u32 base_cs;		/* base chip select to use for calculations */
+};
+
+extern void omap2_init_memory_params(u32 force_lock_to_unlock_mode);
+extern u32 omap2_memory_get_slow_dll_ctrl(void);
+extern u32 omap2_memory_get_fast_dll_ctrl(void);
+extern u32 omap2_memory_get_type(void);
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index ea46548..1197dc3 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -50,9 +50,54 @@
 /* Menelaus interrupt */
 MUX_CFG_24XX("W19_24XX_SYS_NIRQ",	0x12c,	0,	1,	1,	1)
 
+/* 24xx clocks */
+MUX_CFG_24XX("W14_24XX_SYS_CLKOUT",	0x137,	0,	1,	1,	1)
+
+/* 24xx McBSP */
+MUX_CFG_24XX("Y15_24XX_MCBSP2_CLKX",	0x124,	1,	1,	0,	1)
+MUX_CFG_24XX("R14_24XX_MCBSP2_FSX",	0x125,	1,	1,	0,	1)
+MUX_CFG_24XX("W15_24XX_MCBSP2_DR",	0x126,	1,	1,	0,	1)
+MUX_CFG_24XX("V15_24XX_MCBSP2_DX",	0x127,	1,	1,	0,	1)
+
 /* 24xx GPIO */
+MUX_CFG_24XX("M21_242X_GPIO11",	 0x0c9,  3,      1,      1,      1)
+MUX_CFG_24XX("AA10_242X_GPIO13",	0x0e5,  3,      0,      0,      1)
+MUX_CFG_24XX("AA6_242X_GPIO14",	 0x0e6,  3,      0,      0,      1)
+MUX_CFG_24XX("AA4_242X_GPIO15",	 0x0e7,  3,      0,      0,      1)
+MUX_CFG_24XX("Y11_242X_GPIO16",	 0x0e8,  3,      0,      0,      1)
+MUX_CFG_24XX("AA12_242X_GPIO17",	0x0e9,  3,      0,      0,      1)
+MUX_CFG_24XX("AA8_242X_GPIO58",	 0x0ea,  3,      0,      0,      1)
 MUX_CFG_24XX("Y20_24XX_GPIO60",		0x12c,	3,	0,	0,	1)
+MUX_CFG_24XX("W4__24XX_GPIO74",	 0x0f2,  3,      0,      0,      1)
 MUX_CFG_24XX("M15_24XX_GPIO92",		0x10a,	3,	0,	0,	1)
+MUX_CFG_24XX("V14_24XX_GPIO117",	0x128,	3,	1,	0,	1)
+
+/* TSC IRQ */
+MUX_CFG_24XX("P20_24XX_TSC_IRQ",	0x108,	0,	0,	0,	1)
+
+/* UART3  */
+MUX_CFG_24XX("K15_24XX_UART3_TX",	0x118,	0,	0,	0,	1)
+MUX_CFG_24XX("K14_24XX_UART3_RX",	0x119,	0,	0,	0,	1)
+
+/* Keypad GPIO*/
+MUX_CFG_24XX("T19_24XX_KBR0",		0x106,	3,	1,	1,	1)
+MUX_CFG_24XX("R19_24XX_KBR1",		0x107,	3,	1,	1,	1)
+MUX_CFG_24XX("V18_24XX_KBR2",		0x139,	3,	1,	1,	1)
+MUX_CFG_24XX("M21_24XX_KBR3",		0xc9,	3,	1,	1,	1)
+MUX_CFG_24XX("E5__24XX_KBR4",		0x138,	3,	1,	1,	1)
+MUX_CFG_24XX("M18_24XX_KBR5",		0x10e,	3,	1,	1,	1)
+MUX_CFG_24XX("R20_24XX_KBC0",		0x108,	3,	0,	0,	1)
+MUX_CFG_24XX("M14_24XX_KBC1",		0x109,	3,	0,	0,	1)
+MUX_CFG_24XX("H19_24XX_KBC2",		0x114,	3,	0,	0,	1)
+MUX_CFG_24XX("V17_24XX_KBC3",		0x135,	3,	0,	0,	1)
+MUX_CFG_24XX("P21_24XX_KBC4",		0xca,	3,	0,	0,	1)
+MUX_CFG_24XX("L14_24XX_KBC5",		0x10f,	3,	0,	0,	1)
+MUX_CFG_24XX("N19_24XX_KBC6",		0x110,	3,	0,	0,	1)
+
+/* 24xx Menelaus Keypad GPIO */
+MUX_CFG_24XX("B3__24XX_KBR5",		0x30,	3,	1,	1,	1)
+MUX_CFG_24XX("AA4_24XX_KBC2",		0xe7,	3,	0,	0,	1)
+MUX_CFG_24XX("B13_24XX_KBC6",		0x110,	3,	0,	0,	1)
 
 };
 
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
new file mode 100644
index 0000000..562168f
--- /dev/null
+++ b/arch/arm/mach-omap2/pm.c
@@ -0,0 +1,149 @@
+/*
+ * linux/arch/arm/mach-omap2/pm.c
+ *
+ * OMAP2 Power Management Routines
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ * Tony Lindgren <tony@atomide.com>
+ *
+ * Copyright (C) 2005 Texas Instruments, Inc.
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * Based on pm.c for omap1
+ *
+ * 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/pm.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/pm.h>
+#include <linux/interrupt.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/atomic.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/irqs.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sram.h>
+#include <asm/arch/pm.h>
+
+static struct clk *vclk;
+static void (*omap2_sram_idle)(void);
+static void (*omap2_sram_suspend)(int dllctrl, int cpu_rev);
+static void (*saved_idle)(void);
+
+void omap2_pm_idle(void)
+{
+	local_irq_disable();
+	local_fiq_disable();
+	if (need_resched()) {
+		local_fiq_enable();
+		local_irq_enable();
+		return;
+	}
+
+	/*
+	 * 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.
+	 */
+	timer_dyn_reprogram();
+
+	omap2_sram_idle();
+	local_fiq_enable();
+	local_irq_enable();
+}
+
+static int omap2_pm_prepare(suspend_state_t state)
+{
+	int error = 0;
+
+	/* We cannot sleep in idle until we have resumed */
+	saved_idle = pm_idle;
+	pm_idle = NULL;
+
+	switch (state)
+	{
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		break;
+
+	case PM_SUSPEND_DISK:
+		return -ENOTSUPP;
+
+	default:
+		return -EINVAL;
+	}
+
+	return error;
+}
+
+static int omap2_pm_enter(suspend_state_t state)
+{
+	switch (state)
+	{
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		/* FIXME: Add suspend */
+		break;
+
+	case PM_SUSPEND_DISK:
+		return -ENOTSUPP;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int omap2_pm_finish(suspend_state_t state)
+{
+	pm_idle = saved_idle;
+	return 0;
+}
+
+static struct pm_ops omap_pm_ops = {
+	.pm_disk_mode	= 0,
+	.prepare	= omap2_pm_prepare,
+	.enter		= omap2_pm_enter,
+	.finish		= omap2_pm_finish,
+};
+
+int __init omap2_pm_init(void)
+{
+	printk("Power Management for TI OMAP.\n");
+
+	vclk = clk_get(NULL, "virt_prcm_set");
+	if (IS_ERR(vclk)) {
+		printk(KERN_ERR "Could not get PM vclk\n");
+		return -ENODEV;
+	}
+
+	/*
+	 * 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.
+	 */
+	omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend,
+					 omap24xx_idle_loop_suspend_sz);
+
+	omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
+					    omap24xx_cpu_suspend_sz);
+
+	pm_set_ops(&omap_pm_ops);
+	pm_idle = omap2_pm_idle;
+
+	return 0;
+}
+
+__initcall(omap2_pm_init);
diff --git a/arch/arm/mach-omap2/prcm.h b/arch/arm/mach-omap2/prcm-regs.h
similarity index 69%
rename from arch/arm/mach-omap2/prcm.h
rename to arch/arm/mach-omap2/prcm-regs.h
index 2eb89b9..22ac7be 100644
--- a/arch/arm/mach-omap2/prcm.h
+++ b/arch/arm/mach-omap2/prcm-regs.h
@@ -1,5 +1,7 @@
 /*
- * prcm.h - Access definations for use in OMAP24XX clock and power management
+ * linux/arch/arm/mach-omap2/prcm-reg.h
+ *
+ * OMAP24XX Power Reset and Clock Management (PRCM) registers
  *
  * Copyright (C) 2005 Texas Instruments, Inc.
  *
@@ -18,8 +20,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
-#ifndef __ASM_ARM_ARCH_DPM_PRCM_H
-#define __ASM_ARM_ARCH_DPM_PRCM_H
+#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_H
+#define __ARCH_ARM_MACH_OMAP2_PRCM_H
 
 /* SET_PERFORMANCE_LEVEL PARAMETERS */
 #define PRCM_HALF_SPEED 1
@@ -159,54 +161,63 @@
 #define CM_FCLKEN_MDM		PRCM_REG32(0xC00)
 #define CM_ICLKEN_MDM		PRCM_REG32(0xC10)
 #define CM_IDLEST_MDM		PRCM_REG32(0xC20)
+#define CM_AUTOIDLE_MDM		PRCM_REG32(0xC30)
 #define CM_CLKSEL_MDM		PRCM_REG32(0xC40)
+#define CM_CLKSTCTRL_MDM	PRCM_REG32(0xC48)
+#define RM_RSTCTRL_MDM		PRCM_REG32(0xC50)
+#define RM_RSTST_MDM		PRCM_REG32(0xC58)
+#define PM_WKEN_MDM		PRCM_REG32(0xCA0)
+#define PM_WKST_MDM		PRCM_REG32(0xCB0)
+#define PM_WKDEP_MDM		PRCM_REG32(0xCC8)
+#define PM_PWSTCTRL_MDM		PRCM_REG32(0xCE0)
+#define PM_PWSTST_MDM		PRCM_REG32(0xCE4)
 
-/* FIXME: Move to header for 2430 */
-#define DISP_BASE		(OMAP24XX_L4_IO_BASE+0x50000)
+#define OMAP24XX_L4_IO_BASE	0x48000000
+
+#define DISP_BASE		(OMAP24XX_L4_IO_BASE + 0x50000)
 #define DISP_REG32(offset)	__REG32(DISP_BASE + (offset))
 
-#define GPMC_BASE		(OMAP24XX_GPMC_BASE)
-#define GPMC_REG32(offset)	__REG32(GPMC_BASE + (offset))
+#define OMAP24XX_GPMC_BASE	(L3_24XX_BASE + 0xa000)
+#define GPMC_REG32(offset)	__REG32(OMAP24XX_GPMC_BASE + (offset))
 
-#define GPT1_BASE		(OMAP24XX_GPT1)
+/* FIXME: Move these to timer code */
+#define GPT1_BASE		(0x48028000)
 #define GPT1_REG32(offset)	__REG32(GPT1_BASE + (offset))
 
 /* Misc sysconfig */
 #define DISPC_SYSCONFIG		DISP_REG32(0x410)
-#define SPI_BASE		(OMAP24XX_L4_IO_BASE+0x98000)
+#define SPI_BASE		(OMAP24XX_L4_IO_BASE + 0x98000)
 #define MCSPI1_SYSCONFIG	__REG32(SPI_BASE + 0x10)
-#define MCSPI2_SYSCONFIG	__REG32(SPI_BASE+0x2000 + 0x10)
+#define MCSPI2_SYSCONFIG	__REG32(SPI_BASE + 0x2000 + 0x10)
+#define MCSPI3_SYSCONFIG	__REG32(OMAP24XX_L4_IO_BASE + 0xb8010)
 
-//#define DSP_MMU_SYSCONFIG	0x5A000010
-#define CAMERA_MMU_SYSCONFIG	__REG32(DISP_BASE+0x2C10)
-//#define IVA_MMU_SYSCONFIG	0x5D000010
-//#define DSP_DMA_SYSCONFIG	0x00FCC02C
-#define CAMERA_DMA_SYSCONFIG	__REG32(DISP_BASE+0x282C)
-#define SYSTEM_DMA_SYSCONFIG	__REG32(DISP_BASE+0x602C)
+#define CAMERA_MMU_SYSCONFIG	__REG32(DISP_BASE + 0x2C10)
+#define CAMERA_DMA_SYSCONFIG	__REG32(DISP_BASE + 0x282C)
+#define SYSTEM_DMA_SYSCONFIG	__REG32(DISP_BASE + 0x602C)
 #define GPMC_SYSCONFIG		GPMC_REG32(0x010)
-#define MAILBOXES_SYSCONFIG	__REG32(OMAP24XX_L4_IO_BASE+0x94010)
-#define UART1_SYSCONFIG		__REG32(OMAP24XX_L4_IO_BASE+0x6A054)
-#define UART2_SYSCONFIG		__REG32(OMAP24XX_L4_IO_BASE+0x6C054)
-#define UART3_SYSCONFIG		__REG32(OMAP24XX_L4_IO_BASE+0x6E054)
-//#define IVA_SYSCONFIG		0x5C060010
-#define SDRC_SYSCONFIG		__REG32(OMAP24XX_SDRC_BASE+0x10)
-#define SMS_SYSCONFIG		__REG32(OMAP24XX_SMS_BASE+0x10)
-#define SSI_SYSCONFIG		__REG32(DISP_BASE+0x8010)
-//#define VLYNQ_SYSCONFIG	0x67FFFE10
+#define MAILBOXES_SYSCONFIG	__REG32(OMAP24XX_L4_IO_BASE + 0x94010)
+#define UART1_SYSCONFIG		__REG32(OMAP24XX_L4_IO_BASE + 0x6A054)
+#define UART2_SYSCONFIG		__REG32(OMAP24XX_L4_IO_BASE + 0x6C054)
+#define UART3_SYSCONFIG		__REG32(OMAP24XX_L4_IO_BASE + 0x6E054)
+#define SDRC_SYSCONFIG		__REG32(OMAP24XX_SDRC_BASE + 0x10)
+#define OMAP24XX_SMS_BASE	(L3_24XX_BASE + 0x8000)
+#define SMS_SYSCONFIG		__REG32(OMAP24XX_SMS_BASE + 0x10)
+#define SSI_SYSCONFIG		__REG32(DISP_BASE + 0x8010)
 
 /* rkw - good cannidates for PM_ to start what nm was trying */
-#define OMAP24XX_GPT2		(OMAP24XX_L4_IO_BASE+0x2A000)
-#define OMAP24XX_GPT3		(OMAP24XX_L4_IO_BASE+0x78000)
-#define OMAP24XX_GPT4		(OMAP24XX_L4_IO_BASE+0x7A000)
-#define OMAP24XX_GPT5		(OMAP24XX_L4_IO_BASE+0x7C000)
-#define OMAP24XX_GPT6		(OMAP24XX_L4_IO_BASE+0x7E000)
-#define OMAP24XX_GPT7		(OMAP24XX_L4_IO_BASE+0x80000)
-#define OMAP24XX_GPT8		(OMAP24XX_L4_IO_BASE+0x82000)
-#define OMAP24XX_GPT9		(OMAP24XX_L4_IO_BASE+0x84000)
-#define OMAP24XX_GPT10		(OMAP24XX_L4_IO_BASE+0x86000)
-#define OMAP24XX_GPT11		(OMAP24XX_L4_IO_BASE+0x88000)
-#define OMAP24XX_GPT12		(OMAP24XX_L4_IO_BASE+0x8A000)
+#define OMAP24XX_GPT2		(OMAP24XX_L4_IO_BASE + 0x2A000)
+#define OMAP24XX_GPT3		(OMAP24XX_L4_IO_BASE + 0x78000)
+#define OMAP24XX_GPT4		(OMAP24XX_L4_IO_BASE + 0x7A000)
+#define OMAP24XX_GPT5		(OMAP24XX_L4_IO_BASE + 0x7C000)
+#define OMAP24XX_GPT6		(OMAP24XX_L4_IO_BASE + 0x7E000)
+#define OMAP24XX_GPT7		(OMAP24XX_L4_IO_BASE + 0x80000)
+#define OMAP24XX_GPT8		(OMAP24XX_L4_IO_BASE + 0x82000)
+#define OMAP24XX_GPT9		(OMAP24XX_L4_IO_BASE + 0x84000)
+#define OMAP24XX_GPT10		(OMAP24XX_L4_IO_BASE + 0x86000)
+#define OMAP24XX_GPT11		(OMAP24XX_L4_IO_BASE + 0x88000)
+#define OMAP24XX_GPT12		(OMAP24XX_L4_IO_BASE + 0x8A000)
 
+/* FIXME: Move these to timer code */
 #define GPTIMER1_SYSCONFIG	GPT1_REG32(0x010)
 #define GPTIMER2_SYSCONFIG	__REG32(OMAP24XX_GPT2 + 0x10)
 #define GPTIMER3_SYSCONFIG	__REG32(OMAP24XX_GPT3 + 0x10)
@@ -220,12 +231,18 @@
 #define GPTIMER11_SYSCONFIG	__REG32(OMAP24XX_GPT11 + 0x10)
 #define GPTIMER12_SYSCONFIG	__REG32(OMAP24XX_GPT12 + 0x10)
 
-#define GPIOX_BASE(X)		(OMAP24XX_GPIO_BASE+(0x2000*((X)-1)))
+/* FIXME: Move these to gpio code */
+#define OMAP24XX_GPIO_BASE	0x48018000
+#define GPIOX_BASE(X)		(OMAP24XX_GPIO_BASE + (0x2000 * ((X) - 1)))
 
-#define GPIO1_SYSCONFIG		__REG32((GPIOX_BASE(1)+0x10))
-#define GPIO2_SYSCONFIG		__REG32((GPIOX_BASE(2)+0x10))
-#define GPIO3_SYSCONFIG		__REG32((GPIOX_BASE(3)+0x10))
-#define GPIO4_SYSCONFIG		__REG32((GPIOX_BASE(4)+0x10))
+#define GPIO1_SYSCONFIG		__REG32((GPIOX_BASE(1) + 0x10))
+#define GPIO2_SYSCONFIG		__REG32((GPIOX_BASE(2) + 0x10))
+#define GPIO3_SYSCONFIG		__REG32((GPIOX_BASE(3) + 0x10))
+#define GPIO4_SYSCONFIG		__REG32((GPIOX_BASE(4) + 0x10))
+
+#if defined(CONFIG_ARCH_OMAP243X)
+#define GPIO5_SYSCONFIG		__REG32((OMAP24XX_GPIO5_BASE + 0x10))
+#endif
 
 /* GP TIMER 1 */
 #define GPTIMER1_TISTAT		GPT1_REG32(0x014)
@@ -243,15 +260,15 @@
 #define GPTIMER1_TCAR2		GPT1_REG32(0x044)
 
 /* rkw -- base fix up please... */
-#define GPTIMER3_TISR		__REG32(OMAP24XX_L4_IO_BASE+0x78018)
+#define GPTIMER3_TISR		__REG32(OMAP24XX_L4_IO_BASE + 0x78018)
 
 /* SDRC */
-#define SDRC_DLLA_CTRL		__REG32(OMAP24XX_SDRC_BASE+0x060)
-#define SDRC_DLLA_STATUS	__REG32(OMAP24XX_SDRC_BASE+0x064)
-#define SDRC_DLLB_CTRL		__REG32(OMAP24XX_SDRC_BASE+0x068)
-#define SDRC_DLLB_STATUS	__REG32(OMAP24XX_SDRC_BASE+0x06C)
-#define SDRC_POWER		__REG32(OMAP24XX_SDRC_BASE+0x070)
-#define SDRC_MR_0		__REG32(OMAP24XX_SDRC_BASE+0x084)
+#define SDRC_DLLA_CTRL		__REG32(OMAP24XX_SDRC_BASE + 0x060)
+#define SDRC_DLLA_STATUS	__REG32(OMAP24XX_SDRC_BASE + 0x064)
+#define SDRC_DLLB_CTRL		__REG32(OMAP24XX_SDRC_BASE + 0x068)
+#define SDRC_DLLB_STATUS	__REG32(OMAP24XX_SDRC_BASE + 0x06C)
+#define SDRC_POWER		__REG32(OMAP24XX_SDRC_BASE + 0x070)
+#define SDRC_MR_0		__REG32(OMAP24XX_SDRC_BASE + 0x084)
 
 /* GPIO 1 */
 #define GPIO1_BASE		GPIOX_BASE(1)
@@ -278,6 +295,8 @@
 #define GPIO2_DATAIN		GPIO2_REG32(0x038)
 #define GPIO2_OE		GPIO2_REG32(0x034)
 #define GPIO2_DATAOUT		GPIO2_REG32(0x03C)
+#define GPIO2_DEBOUNCENABLE	GPIO2_REG32(0x050)
+#define GPIO2_DEBOUNCINGTIME	GPIO2_REG32(0x054)
 
 /* GPIO 3 */
 #define GPIO3_BASE		GPIOX_BASE(3)
@@ -294,6 +313,8 @@
 #define GPIO3_DATAOUT		GPIO3_REG32(0x03C)
 #define GPIO3_DEBOUNCENABLE	GPIO3_REG32(0x050)
 #define GPIO3_DEBOUNCINGTIME	GPIO3_REG32(0x054)
+#define GPIO3_DEBOUNCENABLE	GPIO3_REG32(0x050)
+#define GPIO3_DEBOUNCINGTIME	GPIO3_REG32(0x054)
 
 /* GPIO 4 */
 #define GPIO4_BASE		GPIOX_BASE(4)
@@ -311,10 +332,26 @@
 #define GPIO4_DEBOUNCENABLE	GPIO4_REG32(0x050)
 #define GPIO4_DEBOUNCINGTIME	GPIO4_REG32(0x054)
 
+#if defined(CONFIG_ARCH_OMAP243X)
+/* GPIO 5 */
+#define GPIO5_REG32(offset)	__REG32((OMAP24XX_GPIO5_BASE + (offset)))
+#define GPIO5_IRQENABLE1	GPIO5_REG32(0x01C)
+#define GPIO5_IRQSTATUS1	GPIO5_REG32(0x018)
+#define GPIO5_IRQENABLE2	GPIO5_REG32(0x02C)
+#define GPIO5_IRQSTATUS2	GPIO5_REG32(0x028)
+#define GPIO5_WAKEUPENABLE	GPIO5_REG32(0x020)
+#define GPIO5_RISINGDETECT	GPIO5_REG32(0x048)
+#define GPIO5_FALLINGDETECT	GPIO5_REG32(0x04C)
+#define GPIO5_DATAIN		GPIO5_REG32(0x038)
+#define GPIO5_OE		GPIO5_REG32(0x034)
+#define GPIO5_DATAOUT		GPIO5_REG32(0x03C)
+#define GPIO5_DEBOUNCENABLE	GPIO5_REG32(0x050)
+#define GPIO5_DEBOUNCINGTIME	GPIO5_REG32(0x054)
+#endif
 
 /* IO CONFIG */
-#define CONTROL_BASE		(OMAP24XX_CTRL_BASE)
-#define CONTROL_REG32(offset)	__REG32(CONTROL_BASE + (offset))
+#define OMAP24XX_CTRL_BASE		(L4_24XX_BASE)
+#define CONTROL_REG32(offset)		__REG32(OMAP24XX_CTRL_BASE + (offset))
 
 #define CONTROL_PADCONF_SPI1_NCS2	CONTROL_REG32(0x104)
 #define CONTROL_PADCONF_SYS_XTALOUT	CONTROL_REG32(0x134)
@@ -322,15 +359,18 @@
 #define CONTROL_PADCONF_MCBSP1_DX	CONTROL_REG32(0x10C)
 #define CONTROL_PADCONF_GPMC_NCS4	CONTROL_REG32(0x090)
 #define CONTROL_PADCONF_DSS_D5		CONTROL_REG32(0x0B8)
-#define CONTROL_PADCONF_DSS_D9		CONTROL_REG32(0x0BC)
+#define CONTROL_PADCONF_DSS_D9		CONTROL_REG32(0x0BC)	/* 2420 */
 #define CONTROL_PADCONF_DSS_D13		CONTROL_REG32(0x0C0)
 #define CONTROL_PADCONF_DSS_VSYNC	CONTROL_REG32(0x0CC)
+#define CONTROL_PADCONF_SYS_NIRQW0	CONTROL_REG32(0x0BC)	/* 2430 */
+#define CONTROL_PADCONF_SSI1_FLAG_TX	CONTROL_REG32(0x108)	/* 2430 */
 
 /* CONTROL */
 #define CONTROL_DEVCONF		CONTROL_REG32(0x274)
+#define CONTROL_DEVCONF1	CONTROL_REG32(0x2E8)
 
 /* INTERRUPT CONTROLLER */
-#define INTC_BASE		(OMAP24XX_L4_IO_BASE+0xfe000)
+#define INTC_BASE		((L4_24XX_BASE) + 0xfe000)
 #define INTC_REG32(offset)	__REG32(INTC_BASE + (offset))
 
 #define INTC1_U_BASE		INTC_REG32(0x000)
@@ -348,10 +388,12 @@
 #define INTC_ISR_CLEAR2		INTC_REG32(0x0D4)
 #define INTC_SIR_IRQ		INTC_REG32(0x040)
 #define INTC_CONTROL		INTC_REG32(0x048)
-#define INTC_ILR11		INTC_REG32(0x12C)
+#define INTC_ILR11		INTC_REG32(0x12C)	/* PRCM on MPU PIC */
+#define INTC_ILR30		INTC_REG32(0x178)
+#define INTC_ILR31		INTC_REG32(0x17C)
 #define INTC_ILR32		INTC_REG32(0x180)
-#define INTC_ILR37		INTC_REG32(0x194)
-#define INTC_SYSCONFIG		INTC_REG32(0x010)
+#define INTC_ILR37		INTC_REG32(0x194)	/* GPIO4 on MPU PIC */
+#define INTC_SYSCONFIG		INTC_REG32(0x010)	/* GPT1 on MPU PIC */
 
 /* RAM FIREWALL */
 #define RAMFW_BASE		(0x68005000)
@@ -373,6 +415,24 @@
 #define GPMC_CONFIG6_0		GPMC_REG32(0x074)
 #define GPMC_CONFIG7_0		GPMC_REG32(0x078)
 
+/* GPMC CS1 */
+#define GPMC_CONFIG1_1		GPMC_REG32(0x090)
+#define GPMC_CONFIG2_1		GPMC_REG32(0x094)
+#define GPMC_CONFIG3_1		GPMC_REG32(0x098)
+#define GPMC_CONFIG4_1		GPMC_REG32(0x09C)
+#define GPMC_CONFIG5_1		GPMC_REG32(0x0a0)
+#define GPMC_CONFIG6_1		GPMC_REG32(0x0a4)
+#define GPMC_CONFIG7_1		GPMC_REG32(0x0a8)
+
+/* GPMC CS3 */
+#define GPMC_CONFIG1_3		GPMC_REG32(0x0F0)
+#define GPMC_CONFIG2_3		GPMC_REG32(0x0F4)
+#define GPMC_CONFIG3_3		GPMC_REG32(0x0F8)
+#define GPMC_CONFIG4_3		GPMC_REG32(0x0FC)
+#define GPMC_CONFIG5_3		GPMC_REG32(0x100)
+#define GPMC_CONFIG6_3		GPMC_REG32(0x104)
+#define GPMC_CONFIG7_3		GPMC_REG32(0x108)
+
 /* DSS */
 #define DSS_CONTROL		DISP_REG32(0x040)
 #define DISPC_CONTROL		DISP_REG32(0x440)
@@ -405,11 +465,15 @@
 #define DISPC_DATA_CYCLE2	DISP_REG32(0x5D8)
 #define DISPC_DATA_CYCLE3	DISP_REG32(0x5DC)
 
-/* Wake up define for board */
-#define GPIO97			(1 << 1)
-#define GPIO88			(1 << 24)
+/* HSUSB Suspend */
+#define HSUSB_CTRL		__REG8(0x480AC001)
+#define USBOTG_POWER		__REG32(0x480AC000)
 
-#endif /* __ASSEMBLER__ */
+/* HS MMC */
+#define MMCHS1_SYSCONFIG	__REG32(0x4809C010)
+#define MMCHS2_SYSCONFIG	__REG32(0x480b4010)
+
+#endif	/* __ASSEMBLER__ */
 
 #endif
 
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
new file mode 100644
index 0000000..8893479
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm.c
@@ -0,0 +1,40 @@
+/*
+ * linux/arch/arm/mach-omap2/prcm.c
+ *
+ * OMAP 24xx Power Reset and Clock Management (PRCM) functions
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ *
+ * Written by Tony Lindgren <tony.lindgren@nokia.com>
+ *
+ * Some pieces of code Copyright (C) 2005 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+
+#include "prcm-regs.h"
+
+u32 omap_prcm_get_reset_sources(void)
+{
+	return RM_RSTST_WKUP & 0x7f;
+}
+EXPORT_SYMBOL(omap_prcm_get_reset_sources);
+
+/* Resets clock rates and reboots the system. Only called from system.h */
+void omap_prcm_arch_reset(char mode)
+{
+	u32 rate;
+	struct clk *vclk, *sclk;
+
+	vclk = clk_get(NULL, "virt_prcm_set");
+	sclk = clk_get(NULL, "sys_ck");
+	rate = clk_get_rate(sclk);
+	clk_set_rate(vclk, rate);	/* go to bypass for OMAP limitation */
+	RM_RSTCTRL_WKUP |= 2;
+}
diff --git a/arch/arm/mach-omap2/sleep.S b/arch/arm/mach-omap2/sleep.S
new file mode 100644
index 0000000..00299cb
--- /dev/null
+++ b/arch/arm/mach-omap2/sleep.S
@@ -0,0 +1,144 @@
+/*
+ * linux/arch/arm/mach-omap2/sleep.S
+ *
+ * (C) Copyright 2004
+ * Texas Instruments, <www.ti.com>
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/arch/io.h>
+#include <asm/arch/pm.h>
+
+#define A_32KSYNC_CR_V		IO_ADDRESS(OMAP_TIMER32K_BASE+0x10)
+#define A_PRCM_VOLTCTRL_V	IO_ADDRESS(OMAP24XX_PRCM_BASE+0x50)
+#define A_PRCM_CLKCFG_CTRL_V	IO_ADDRESS(OMAP24XX_PRCM_BASE+0x80)
+#define A_CM_CLKEN_PLL_V	IO_ADDRESS(OMAP24XX_PRCM_BASE+0x500)
+#define A_CM_IDLEST_CKGEN_V	IO_ADDRESS(OMAP24XX_PRCM_BASE+0x520)
+#define A_CM_CLKSEL1_PLL_V	IO_ADDRESS(OMAP24XX_PRCM_BASE+0x540)
+#define A_CM_CLKSEL2_PLL_V	IO_ADDRESS(OMAP24XX_PRCM_BASE+0x544)
+
+#define A_SDRC_DLLA_CTRL_V	IO_ADDRESS(OMAP24XX_SDRC_BASE+0x60)
+#define	A_SDRC_POWER_V		IO_ADDRESS(OMAP24XX_SDRC_BASE+0x70)
+#define A_SDRC_RFR_CTRL_V	IO_ADDRESS(OMAP24XX_SDRC_BASE+0xA4)
+#define A_SDRC0_V		(0xC0000000)
+#define A_SDRC_MANUAL_V		IO_ADDRESS(OMAP24XX_SDRC_BASE+0xA8)
+
+	.text
+
+/*
+ * Forces OMAP into idle state
+ *
+ * omap24xx_idle_loop_suspend() - This bit of code just executes the WFI
+ * for normal idles.
+ *
+ * Note: This code get's copied to internal SRAM at boot. When the OMAP
+ *	 wakes up it continues execution at the point it went to sleep.
+ */
+ENTRY(omap24xx_idle_loop_suspend)
+	stmfd	sp!, {r0, lr}		@ save registers on stack
+	mov	r0, #0			@ clear for mcr setup
+	mcr	p15, 0, r0, c7, c0, 4	@ wait for interrupt
+	ldmfd	sp!, {r0, pc}		@ restore regs and return
+
+ENTRY(omap24xx_idle_loop_suspend_sz)
+	.word	. - omap24xx_idle_loop_suspend
+
+/*
+ * omap242x_cpu_suspend() - Forces OMAP into deep sleep state by completing
+ * SDRC shutdown then ARM shutdown.  Upon wake MPU is back on so just restore
+ * SDRC.
+ *
+ * Input:
+ * R0 :	DLL ctrl value pre-Sleep
+ * R1 : Processor+Revision
+ *	2420: 0x21 = 242xES1, 0x26 = 242xES2.2
+ *	2430: 0x31 = 2430ES1, 0x32 = 2430ES2
+ *
+ * The if the DPLL is going to AutoIdle. It seems like the DPLL may be back on
+ * when we get called, but the DLL probably isn't.  We will wait a bit more in
+ * case the DPLL isn't quite there yet. The code will wait on DLL for DDR even
+ * if in unlocked mode.
+ *
+ * For less than 242x-ES2.2 upon wake from a sleep mode where the external
+ * oscillator was stopped, a timing bug exists where a non-stabilized 12MHz
+ * clock can pass into the PRCM can cause problems at DSP and IVA.
+ * To work around this the code will switch to the 32kHz source prior to sleep.
+ * Post sleep we will shift back to using the DPLL.  Apparently,
+ * CM_IDLEST_CLKGEN does not reflect the full clock change so you need to wait
+ * 3x12MHz + 3x32kHz clocks for a full switch.
+ *
+ * The DLL load value is not kept in RETENTION or OFF.	It needs to be restored
+ * at wake
+ */
+ENTRY(omap24xx_cpu_suspend)
+	stmfd	sp!, {r0 - r12, lr}	@ save registers on stack
+	mov	r3, #0x0		@ clear for mrc call
+	mcr	p15, 0, r3, c7, c10, 4	@ memory barrier, hope SDR/DDR finished
+	nop
+	nop
+	ldr	r3, A_SDRC_POWER	@ addr of sdrc power
+	ldr	r4, [r3]		@ value of sdrc power
+	orr	r4, r4, #0x40		@ enable self refresh on idle req
+	mov	r5, #0x2000		@ set delay (DPLL relock + DLL relock)
+	str	r4, [r3]		@ make it so
+	mov	r2, #0
+	nop
+	mcr	p15, 0, r2, c7, c0, 4	@ wait for interrupt
+	nop
+loop:
+	subs	r5, r5, #0x1		@ awake, wait just a bit
+	bne	loop
+
+	/* The DPLL has on before we take the DDR out of self refresh */
+	bic	r4, r4, #0x40		@ now clear self refresh bit.
+	str	r4, [r3]		@ put vlaue back.
+	ldr	r4, A_SDRC0		@ make a clock happen
+	ldr	r4, [r4]
+	nop				@ start auto refresh only after clk ok
+	movs	r0, r0			@ see if DDR or SDR
+	ldrne	r1, A_SDRC_DLLA_CTRL_S	@ get addr of DLL ctrl
+	strne	r0, [r1]		@ rewrite DLLA to force DLL reload
+	addne	r1, r1, #0x8		@ move to DLLB
+	strne	r0, [r1]		@ rewrite DLLB to force DLL reload
+
+	mov	r5, #0x1000
+loop2:
+	subs	r5, r5, #0x1
+	bne	loop2
+	/* resume*/
+	ldmfd	sp!, {r0 - r12, pc}	@ restore regs and return
+
+A_SDRC_POWER:
+	.word A_SDRC_POWER_V
+A_SDRC0:
+	.word A_SDRC0_V
+A_CM_CLKSEL2_PLL_S:
+	.word A_CM_CLKSEL2_PLL_V
+A_CM_CLKEN_PLL:
+	.word A_CM_CLKEN_PLL_V
+A_SDRC_DLLA_CTRL_S:
+	.word A_SDRC_DLLA_CTRL_V
+A_SDRC_MANUAL_S:
+	.word A_SDRC_MANUAL_V
+
+ENTRY(omap24xx_cpu_suspend_sz)
+	.word	. - omap24xx_cpu_suspend
+
diff --git a/arch/arm/mach-omap2/sram-fn.S b/arch/arm/mach-omap2/sram-fn.S
index 2a869e2..d261e4f 100644
--- a/arch/arm/mach-omap2/sram-fn.S
+++ b/arch/arm/mach-omap2/sram-fn.S
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap1/sram.S
+ * linux/arch/arm/mach-omap2/sram.S
  *
  * Omap2 specific functions that need to be run in internal SRAM
  *
@@ -28,7 +28,7 @@
 #include <asm/arch/io.h>
 #include <asm/hardware.h>
 
-#include <asm/arch/prcm.h>
+#include "prcm-regs.h"
 
 #define TIMER_32KSYNCT_CR_V	IO_ADDRESS(OMAP24XX_32KSYNCT_BASE + 0x010)
 
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index b45560a..a042473 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -307,6 +307,10 @@
 		struct tag *tags, char **cmdline, struct meminfo *mi)
 {
 	sharpsl_save_param();
+	mi->nr_banks=1;
+	mi->bank[0].start = 0xa0000000;
+	mi->bank[0].node = 0;
+	mi->bank[0].size = (32*1024*1024);
 }
 
 MACHINE_START(POODLE, "SHARP Poodle")
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index ed07c41..ce7d810 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -50,9 +50,15 @@
 
 	  <http://zoo.weinigel.se/n30>.
 
+config MACH_SMDK
+	bool
+	help
+	  Common machine code for SMDK2410 and SMDK2440
+
 config ARCH_SMDK2410
 	bool "SMDK2410/A9M2410"
 	select CPU_S3C2410
+	select MACH_SMDK
 	help
 	   Say Y here if you are using the SMDK2410 or the derived module A9M2410
            <http://www.fsforth.de>
@@ -60,6 +66,7 @@
 config ARCH_S3C2440
 	bool "SMDK2440"
 	select CPU_S3C2440
+	select MACH_SMDK
 	help
 	  Say Y here if you are using the SMDK2440.
 
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
index 1b3b476..3e5712d 100644
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -48,3 +48,5 @@
 obj-$(CONFIG_MACH_RX3715)	+= mach-rx3715.o
 obj-$(CONFIG_MACH_OTOM)		+= mach-otom.o
 obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
+
+obj-$(CONFIG_MACH_SMDK)		+= common-smdk.o
\ No newline at end of file
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index fec02c9..b7f85e6 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -249,7 +249,7 @@
 
 	/* if we started the UPLL, then allow to settle */
 
-	if (enable && !(orig & S3C2410_CLKSLOW_UCLK_OFF))
+	if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))
 		udelay(200);
 
 	return 0;
diff --git a/arch/arm/mach-s3c2410/common-smdk.c b/arch/arm/mach-s3c2410/common-smdk.c
new file mode 100644
index 0000000..36b8291
--- /dev/null
+++ b/arch/arm/mach-s3c2410/common-smdk.c
@@ -0,0 +1,134 @@
+/* linux/arch/arm/mach-s3c2410/common-smdk.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Common code for SMDK2410 and SMDK2440 boards
+ *
+ * http://www.fluff.org/ben/smdk2440/
+ *
+ * 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/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/regs-gpio.h>
+
+#include <asm/arch/nand.h>
+
+#include "devs.h"
+#include "pm.h"
+
+/* NAND parititon from 2.4.18-swl5 */
+
+static struct mtd_partition smdk_default_nand_part[] = {
+	[0] = {
+		.name	= "Boot Agent",
+		.size	= SZ_16K,
+		.offset	= 0,
+	},
+	[1] = {
+		.name	= "S3C2410 flash parition 1",
+		.offset = 0,
+		.size	= SZ_2M,
+	},
+	[2] = {
+		.name	= "S3C2410 flash partition 2",
+		.offset = SZ_4M,
+		.size	= SZ_4M,
+	},
+	[3] = {
+		.name	= "S3C2410 flash partition 3",
+		.offset	= SZ_8M,
+		.size	= SZ_2M,
+	},
+	[4] = {
+		.name	= "S3C2410 flash partition 4",
+		.offset = SZ_1M * 10,
+		.size	= SZ_4M,
+	},
+	[5] = {
+		.name	= "S3C2410 flash partition 5",
+		.offset	= SZ_1M * 14,
+		.size	= SZ_1M * 10,
+	},
+	[6] = {
+		.name	= "S3C2410 flash partition 6",
+		.offset	= SZ_1M * 24,
+		.size	= SZ_1M * 24,
+	},
+	[7] = {
+		.name	= "S3C2410 flash partition 7",
+		.offset = SZ_1M * 48,
+		.size	= SZ_16M,
+	}
+};
+
+static struct s3c2410_nand_set smdk_nand_sets[] = {
+	[0] = {
+		.name		= "NAND",
+		.nr_chips	= 1,
+		.nr_partitions	= ARRAY_SIZE(smdk_default_nand_part),
+		.partitions	= smdk_default_nand_part,
+	},
+};
+
+/* choose a set of timings which should suit most 512Mbit
+ * chips and beyond.
+*/
+
+static struct s3c2410_platform_nand smdk_nand_info = {
+	.tacls		= 20,
+	.twrph0		= 60,
+	.twrph1		= 20,
+	.nr_sets	= ARRAY_SIZE(smdk_nand_sets),
+	.sets		= smdk_nand_sets,
+};
+
+/* devices we initialise */
+
+static struct platform_device __initdata *smdk_devs[] = {
+	&s3c_device_nand,
+};
+
+void __init smdk_machine_init(void)
+{
+	/* Configure the LEDs (even if we have no LED support)*/
+
+	s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);
+	s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP);
+	s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);
+	s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP);
+
+	s3c2410_gpio_setpin(S3C2410_GPF4, 1);
+	s3c2410_gpio_setpin(S3C2410_GPF5, 1);
+	s3c2410_gpio_setpin(S3C2410_GPF6, 1);
+	s3c2410_gpio_setpin(S3C2410_GPF7, 1);
+
+	s3c_device_nand.dev.platform_data = &smdk_nand_info;
+
+	platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));
+
+	s3c2410_pm_init();
+}
diff --git a/arch/arm/mach-s3c2410/common-smdk.h b/arch/arm/mach-s3c2410/common-smdk.h
new file mode 100644
index 0000000..0e3a3be
--- /dev/null
+++ b/arch/arm/mach-s3c2410/common-smdk.h
@@ -0,0 +1,15 @@
+/* linux/arch/arm/mach-s3c2410/common-smdk.h
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Common code for SMDK2410 and SMDK2440 boards
+ *
+ * http://www.fluff.org/ben/smdk2440/
+ *
+ * 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.
+*/
+
+extern void smdk_machine_init(void);
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c
index 3e327b8..cc97fbf 100644
--- a/arch/arm/mach-s3c2410/mach-anubis.c
+++ b/arch/arm/mach-s3c2410/mach-anubis.c
@@ -232,8 +232,8 @@
 
 static struct s3c2410_platform_nand anubis_nand_info = {
 	.tacls		= 25,
-	.twrph0		= 80,
-	.twrph1		= 80,
+	.twrph0		= 55,
+	.twrph1		= 40,
 	.nr_sets	= ARRAY_SIZE(anubis_nand_sets),
 	.sets		= anubis_nand_sets,
 	.select_chip	= anubis_nand_select,
diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c
index 0260ed5..306afc1 100644
--- a/arch/arm/mach-s3c2410/mach-rx3715.c
+++ b/arch/arm/mach-s3c2410/mach-rx3715.c
@@ -32,6 +32,11 @@
 #include <linux/serial_core.h>
 #include <linux/serial.h>
 
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
@@ -46,6 +51,7 @@
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-lcd.h>
 
+#include <asm/arch/nand.h>
 #include <asm/arch/fb.h>
 
 #include "clock.h"
@@ -170,12 +176,39 @@
 	},
 };
 
+static struct mtd_partition rx3715_nand_part[] = {
+	[0] = {
+		.name		= "Whole Flash",
+		.offset		= 0,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= MTD_WRITEABLE,
+	}
+};
+
+static struct s3c2410_nand_set rx3715_nand_sets[] = {
+	[0] = {
+		.name		= "Internal",
+		.nr_chips	= 1,
+		.nr_partitions	= ARRAY_SIZE(rx3715_nand_part),
+		.partitions	= rx3715_nand_part,
+	},
+};
+
+static struct s3c2410_platform_nand rx3715_nand_info = {
+	.tacls		= 25,
+	.twrph0		= 50,
+	.twrph1		= 15,
+	.nr_sets	= ARRAY_SIZE(rx3715_nand_sets),
+	.sets		= rx3715_nand_sets,
+};
+
 static struct platform_device *rx3715_devices[] __initdata = {
 	&s3c_device_usb,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c,
 	&s3c_device_iis,
+	&s3c_device_nand,
 };
 
 static struct s3c24xx_board rx3715_board __initdata = {
@@ -185,6 +218,8 @@
 
 static void __init rx3715_map_io(void)
 {
+	s3c_device_nand.dev.platform_data = &rx3715_nand_info;
+
 	s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
 	s3c24xx_init_clocks(16934000);
 	s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
index 1e76e1f..2db932d 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -28,7 +28,8 @@
  * Ben Dooks <ben@simtec.co.uk>
  *
  * 10-Mar-2005 LCVR  Changed S3C2410_VA to S3C24XX_VA
- * 20-Sep-2005 BJD  Added static to non-exported items
+ * 20-Sep-2005 BJD   Added static to non-exported items
+ * 01-Apr-2006 BJD   Moved init code to common smdk
  *
  ***********************************************************************/
 
@@ -54,6 +55,8 @@
 #include "devs.h"
 #include "cpu.h"
 
+#include "common-smdk.h"
+
 static struct map_desc smdk2410_iodesc[] __initdata = {
   /* nothing here yet */
 };
@@ -107,11 +110,6 @@
 	s3c24xx_set_board(&smdk2410_board);
 }
 
-static void __init smdk2410_init_irq(void)
-{
-	s3c24xx_init_irq();
-}
-
 MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
 				    * to SMDK2410 */
 	/* Maintainer: Jonas Dietsche */
@@ -119,7 +117,8 @@
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= smdk2410_map_io,
-	.init_irq	= smdk2410_init_irq,
+	.init_irq	= s3c24xx_init_irq,
+	.init_machine	= smdk_machine_init,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c
index f431572..5fffd1d 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2440.c
@@ -53,7 +53,8 @@
 #include "clock.h"
 #include "devs.h"
 #include "cpu.h"
-#include "pm.h"
+
+#include "common-smdk.h"
 
 static struct map_desc smdk2440_iodesc[] __initdata = {
 	/* ISA IO Space map (memory space selected by A24) */
@@ -197,21 +198,9 @@
 
 static void __init smdk2440_machine_init(void)
 {
-	/* Configure the LEDs (even if we have no LED support)*/
-
-	s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);
-	s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP);
-	s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);
-	s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP);
-
-	s3c2410_gpio_setpin(S3C2410_GPF4, 0);
-	s3c2410_gpio_setpin(S3C2410_GPF5, 0);
-	s3c2410_gpio_setpin(S3C2410_GPF6, 0);
-	s3c2410_gpio_setpin(S3C2410_GPF7, 0);
-
 	s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg);
 
-	s3c2410_pm_init();
+	smdk_machine_init();
 }
 
 MACHINE_START(S3C2440, "SMDK2440")
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 1024540..676b5c5 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -11,7 +11,8 @@
  * published by the Free Software Foundation.
  *
  * ChangeLog:
- *  03-06-2004 John Lenz <jelenz@wisc.edu>
+ *  2006 Pavel Machek <pavel@suse.cz>
+ *  03-06-2004 John Lenz <lenz@cs.wisc.edu>
  *  06-04-2002 Chris Larson <kergoth@digitalnemesis.net>
  *  04-16-2001 Lineo Japan,Inc. ...
  */
@@ -87,12 +88,75 @@
 	.sclk_rate      = 11981000,
 };
 
+#ifdef CONFIG_SHARP_LOCOMO
+/*
+ * low-level UART features.
+ */
+static struct locomo_dev *uart_dev = NULL;
+
+static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+ 	if (!uart_dev) return;
+
+ 	if (mctrl & TIOCM_RTS)
+		locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 0);
+ 	else
+		locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 1);
+
+ 	if (mctrl & TIOCM_DTR)
+		locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 0);
+ 	else
+		locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 1);
+}
+
+static u_int collie_uart_get_mctrl(struct uart_port *port)
+{
+	int ret = TIOCM_CD;
+	unsigned int r;
+	if (!uart_dev) return ret;
+
+	r = locomo_gpio_read_output(uart_dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR);
+	if (r & LOCOMO_GPIO_CTS)
+		ret |= TIOCM_CTS;
+	if (r & LOCOMO_GPIO_DSR)
+		ret |= TIOCM_DSR;
+
+	return ret;
+}
 
 static struct sa1100_port_fns collie_port_fns __initdata = {
 	.set_mctrl	= collie_uart_set_mctrl,
 	.get_mctrl	= collie_uart_get_mctrl,
 };
 
+static int collie_uart_probe(struct locomo_dev *dev)
+{
+	uart_dev = dev;
+	return 0;
+}
+
+static int collie_uart_remove(struct locomo_dev *dev)
+{
+	uart_dev = NULL;
+	return 0;
+}
+
+static struct locomo_driver collie_uart_driver = {
+	.drv = {
+		.name = "collie_uart",
+	},
+	.devid	= LOCOMO_DEVID_UART,
+	.probe	= collie_uart_probe,
+	.remove	= collie_uart_remove,
+};
+
+static int __init collie_uart_init(void) {
+	return locomo_driver_register(&collie_uart_driver);
+}
+device_initcall(collie_uart_init);
+
+#endif
+
 
 static struct resource locomo_resources[] = {
 	[0] = {
@@ -218,6 +282,12 @@
 {
 	sa1100_map_io();
 	iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc));
+
+#ifdef CONFIG_SHARP_LOCOMO
+	sa1100_register_uart_fns(&collie_port_fns);
+#endif
+	sa1100_register_uart(0, 3);
+	sa1100_register_uart(1, 1);
 }
 
 MACHINE_START(COLLIE, "Sharp-Collie")
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index 8a1bfcd..50e6b6b 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -18,6 +18,7 @@
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 
+#include <asm/memory.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 #include <asm/sizes.h>
@@ -272,6 +273,17 @@
 void *
 dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
 {
+	if (arch_is_coherent()) {
+		void *virt;
+
+		virt = kmalloc(size, gfp);
+		if (!virt)
+			return NULL;
+		*handle =  virt_to_dma(dev, virt);
+
+		return virt;
+	}
+
 	return __dma_alloc(dev, size, handle, gfp,
 			   pgprot_noncached(pgprot_kernel));
 }
@@ -350,6 +362,11 @@
 
 	WARN_ON(irqs_disabled());
 
+	if (arch_is_coherent()) {
+		kfree(cpu_addr);
+		return;
+	}
+
 	size = PAGE_ALIGN(size);
 
 	spin_lock_irqsave(&consistent_lock, flags);
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index 5e5d05b..f14b2d0 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -389,6 +389,17 @@
 	kern_pgprot = user_pgprot = cp->pte;
 
 	/*
+	 * Enable CPU-specific coherency if supported.
+	 * (Only available on XSC3 at the moment.)
+	 */
+	if (arch_is_coherent()) {
+		if (cpu_is_xsc3()) {
+			mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
+			mem_types[MT_MEMORY].prot_pte |= L_PTE_COHERENT;
+		}
+	}
+
+	/*
 	 * ARMv6 and above have extended page tables.
 	 */
 	if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) {
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index b9dfce5..80873b3 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -371,7 +371,7 @@
 ENTRY(cpu_xsc3_set_pte)
 	str	r1, [r0], #-2048		@ linux version
 
-	bic	r2, r1, #0xff0
+	bic	r2, r1, #0xdf0			@ Keep C, B, coherency bits
 	orr	r2, r2, #PTE_TYPE_EXT		@ extended page
 
 	eor	r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 0887bb2..ec49495 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -70,13 +70,13 @@
 
 config OMAP_32K_TIMER
 	bool "Use 32KHz timer"
-	depends on ARCH_OMAP16XX
+	depends on ARCH_OMAP16XX || ARCH_OMAP24XX
 	help
 	  Select this option if you want to enable the OMAP 32KHz timer.
 	  This timer saves power compared to the OMAP_MPU_TIMER, and has
 	  support for no tick during idle. The 32KHz timer provides less
 	  intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is
-	  currently only available for OMAP-16xx.
+	  currently only available for OMAP16XX and 24XX.
 
 endchoice
 
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 9ccf194..2896b45 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -3,16 +3,16 @@
 #
 
 # Common support
-obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o
+obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o fb.o
 obj-m :=
 obj-n :=
 obj-  :=
 
+obj-$(CONFIG_OMAP_32K_TIMER)	+= timer32k.o
+
 # OCPI interconnect support for 1710, 1610 and 5912
 obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
 
-# Power Management
-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 3c2bfc0..06485c1 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -21,6 +21,7 @@
 #include <linux/string.h>
 #include <linux/clk.h>
 #include <linux/mutex.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/semaphore.h>
@@ -37,17 +38,37 @@
  * Standard clock functions defined in include/linux/clk.h
  *-------------------------------------------------------------------------*/
 
+/*
+ * Returns a clock. Note that we first try to use device id on the bus
+ * and clock name. If this fails, we try to use clock name only.
+ */
 struct clk * clk_get(struct device *dev, const char *id)
 {
 	struct clk *p, *clk = ERR_PTR(-ENOENT);
+	int idno;
+
+	if (dev == NULL || dev->bus != &platform_bus_type)
+		idno = -1;
+	else
+		idno = to_platform_device(dev)->id;
 
 	mutex_lock(&clocks_mutex);
+
+	list_for_each_entry(p, &clocks, node) {
+		if (p->id == idno &&
+		    strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
+			clk = p;
+			break;
+		}
+	}
+
 	list_for_each_entry(p, &clocks, node) {
 		if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
 			clk = p;
 			break;
 		}
 	}
+
 	mutex_unlock(&clocks_mutex);
 
 	return clk;
@@ -59,6 +80,9 @@
 	unsigned long flags;
 	int ret = 0;
 
+	if (clk == NULL || IS_ERR(clk))
+		return -EINVAL;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
 	if (arch_clock->clk_enable)
 		ret = arch_clock->clk_enable(clk);
@@ -72,6 +96,9 @@
 {
 	unsigned long flags;
 
+	if (clk == NULL || IS_ERR(clk))
+		return;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
 	if (arch_clock->clk_disable)
 		arch_clock->clk_disable(clk);
@@ -84,6 +111,9 @@
 	unsigned long flags;
 	int ret = 0;
 
+	if (clk == NULL || IS_ERR(clk))
+		return 0;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
 	ret = clk->usecount;
 	spin_unlock_irqrestore(&clockfw_lock, flags);
@@ -97,6 +127,9 @@
 	unsigned long flags;
 	unsigned long ret = 0;
 
+	if (clk == NULL || IS_ERR(clk))
+		return 0;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
 	ret = clk->rate;
 	spin_unlock_irqrestore(&clockfw_lock, flags);
@@ -121,6 +154,9 @@
 	unsigned long flags;
 	long ret = 0;
 
+	if (clk == NULL || IS_ERR(clk))
+		return ret;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
 	if (arch_clock->clk_round_rate)
 		ret = arch_clock->clk_round_rate(clk, rate);
@@ -133,7 +169,10 @@
 int clk_set_rate(struct clk *clk, unsigned long rate)
 {
 	unsigned long flags;
-	int ret = 0;
+	int ret = -EINVAL;
+
+	if (clk == NULL || IS_ERR(clk))
+		return ret;
 
 	spin_lock_irqsave(&clockfw_lock, flags);
 	if (arch_clock->clk_set_rate)
@@ -147,7 +186,10 @@
 int clk_set_parent(struct clk *clk, struct clk *parent)
 {
 	unsigned long flags;
-	int ret = 0;
+	int ret = -EINVAL;
+
+	if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent))
+		return ret;
 
 	spin_lock_irqsave(&clockfw_lock, flags);
 	if (arch_clock->clk_set_parent)
@@ -163,6 +205,9 @@
 	unsigned long flags;
 	struct clk * ret = NULL;
 
+	if (clk == NULL || IS_ERR(clk))
+		return ret;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
 	if (arch_clock->clk_get_parent)
 		ret = arch_clock->clk_get_parent(clk);
@@ -199,6 +244,9 @@
 /* Used for clocks that always have same value as the parent clock */
 void followparent_recalc(struct clk *clk)
 {
+	if (clk == NULL || IS_ERR(clk))
+		return;
+
 	clk->rate = clk->parent->rate;
 }
 
@@ -207,6 +255,9 @@
 {
 	struct clk *clkp;
 
+	if (tclk == NULL || IS_ERR(tclk))
+		return;
+
 	list_for_each_entry(clkp, &clocks, node) {
 		if (likely(clkp->parent != tclk))
 			continue;
@@ -217,6 +268,9 @@
 
 int clk_register(struct clk *clk)
 {
+	if (clk == NULL || IS_ERR(clk))
+		return -EINVAL;
+
 	mutex_lock(&clocks_mutex);
 	list_add(&clk->node, &clocks);
 	if (clk->init)
@@ -229,6 +283,9 @@
 
 void clk_unregister(struct clk *clk)
 {
+	if (clk == NULL || IS_ERR(clk))
+		return;
+
 	mutex_lock(&clocks_mutex);
 	list_del(&clk->node);
 	mutex_unlock(&clocks_mutex);
@@ -239,6 +296,9 @@
 {
 	unsigned long flags;
 
+	if (clk == NULL || IS_ERR(clk))
+		return;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
 	if (arch_clock->clk_deny_idle)
 		arch_clock->clk_deny_idle(clk);
@@ -250,6 +310,9 @@
 {
 	unsigned long flags;
 
+	if (clk == NULL || IS_ERR(clk))
+		return;
+
 	spin_lock_irqsave(&clockfw_lock, flags);
 	if (arch_clock->clk_allow_idle)
 		arch_clock->clk_allow_idle(clk);
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 9dcce90..079b67d 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -24,6 +24,7 @@
 #include <asm/arch/board.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/gpio.h>
+#include <asm/arch/menelaus.h>
 
 
 void omap_nop_release(struct device *dev)
@@ -98,6 +99,62 @@
 #endif
 
 /*-------------------------------------------------------------------------*/
+#if	defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE)
+
+static void omap_init_kp(void)
+{
+	if (machine_is_omap_h2() || machine_is_omap_h3()) {
+		omap_cfg_reg(F18_1610_KBC0);
+		omap_cfg_reg(D20_1610_KBC1);
+		omap_cfg_reg(D19_1610_KBC2);
+		omap_cfg_reg(E18_1610_KBC3);
+		omap_cfg_reg(C21_1610_KBC4);
+
+		omap_cfg_reg(G18_1610_KBR0);
+		omap_cfg_reg(F19_1610_KBR1);
+		omap_cfg_reg(H14_1610_KBR2);
+		omap_cfg_reg(E20_1610_KBR3);
+		omap_cfg_reg(E19_1610_KBR4);
+		omap_cfg_reg(N19_1610_KBR5);
+	} else if (machine_is_omap_perseus2()) {
+		omap_cfg_reg(E2_730_KBR0);
+		omap_cfg_reg(J7_730_KBR1);
+		omap_cfg_reg(E1_730_KBR2);
+		omap_cfg_reg(F3_730_KBR3);
+		omap_cfg_reg(D2_730_KBR4);
+
+		omap_cfg_reg(C2_730_KBC0);
+		omap_cfg_reg(D3_730_KBC1);
+		omap_cfg_reg(E4_730_KBC2);
+		omap_cfg_reg(F4_730_KBC3);
+		omap_cfg_reg(E3_730_KBC4);
+	} else if (machine_is_omap_h4()) {
+		omap_cfg_reg(T19_24XX_KBR0);
+		omap_cfg_reg(R19_24XX_KBR1);
+		omap_cfg_reg(V18_24XX_KBR2);
+		omap_cfg_reg(M21_24XX_KBR3);
+		omap_cfg_reg(E5__24XX_KBR4);
+		if (omap_has_menelaus()) {
+			omap_cfg_reg(B3__24XX_KBR5);
+			omap_cfg_reg(AA4_24XX_KBC2);
+			omap_cfg_reg(B13_24XX_KBC6);
+		} else {
+			omap_cfg_reg(M18_24XX_KBR5);
+			omap_cfg_reg(H19_24XX_KBC2);
+			omap_cfg_reg(N19_24XX_KBC6);
+		}
+		omap_cfg_reg(R20_24XX_KBC0);
+		omap_cfg_reg(M14_24XX_KBC1);
+		omap_cfg_reg(V17_24XX_KBC3);
+		omap_cfg_reg(P21_24XX_KBC4);
+		omap_cfg_reg(L14_24XX_KBC5);
+	}
+}
+#else
+static inline void omap_init_kp(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
 
 #if	defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
 
@@ -240,6 +297,55 @@
 static inline void omap_init_mmc(void) {}
 #endif
 
+/*-------------------------------------------------------------------------*/
+
+/* Numbering for the SPI-capable controllers when used for SPI:
+ * spi		= 1
+ * uwire	= 2
+ * mmc1..2	= 3..4
+ * mcbsp1..3	= 5..7
+ */
+
+#if defined(CONFIG_SPI_OMAP_UWIRE) || defined(CONFIG_SPI_OMAP_UWIRE_MODULE)
+
+#define	OMAP_UWIRE_BASE		0xfffb3000
+
+static struct resource uwire_resources[] = {
+	{
+		.start		= OMAP_UWIRE_BASE,
+		.end		= OMAP_UWIRE_BASE + 0x20,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device omap_uwire_device = {
+	.name	   = "omap_uwire",
+	.id	     = -1,
+	.dev = {
+		.release	= omap_nop_release,
+	},
+	.num_resources	= ARRAY_SIZE(uwire_resources),
+	.resource	= uwire_resources,
+};
+
+static void omap_init_uwire(void)
+{
+	/* FIXME define and use a boot tag; not all boards will be hooking
+	 * up devices to the microwire controller, and multi-board configs
+	 * mean that CONFIG_SPI_OMAP_UWIRE may be configured anyway...
+	 */
+
+	/* board-specific code must configure chipselects (only a few
+	 * are normally used) and SCLK/SDI/SDO (each has two choices).
+	 */
+	(void) platform_device_register(&omap_uwire_device);
+}
+#else
+static inline void omap_init_uwire(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
 #if	defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
 
 #ifdef CONFIG_ARCH_OMAP24XX
@@ -310,40 +416,6 @@
 static inline void omap_init_rng(void) {}
 #endif
 
-#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
-
-static struct omap_lcd_config omap_fb_conf;
-
-static u64 omap_fb_dma_mask = ~(u32)0;
-
-static struct platform_device omap_fb_device = {
-	.name		= "omapfb",
-	.id		= -1,
-	.dev = {
-		.release		= omap_nop_release,
-		.dma_mask		= &omap_fb_dma_mask,
-		.coherent_dma_mask	= ~(u32)0,
-		.platform_data		= &omap_fb_conf,
-	},
-	.num_resources = 0,
-};
-
-static inline void omap_init_fb(void)
-{
-	const struct omap_lcd_config *conf;
-
-	conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
-	if (conf != NULL)
-		omap_fb_conf = *conf;
-	platform_device_register(&omap_fb_device);
-}
-
-#else
-
-static inline void omap_init_fb(void) {}
-
-#endif
-
 /*
  * This gets called after board-specific INIT_MACHINE, and initializes most
  * on-chip peripherals accessible on this board (except for few like USB):
@@ -369,9 +441,10 @@
 	/* please keep these calls, and their implementations above,
 	 * in alphabetical order so they're easier to sort through.
 	 */
-	omap_init_fb();
 	omap_init_i2c();
+	omap_init_kp();
 	omap_init_mmc();
+	omap_init_uwire();
 	omap_init_wdt();
 	omap_init_rng();
 
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index a4e5ac7..5dac423 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -1258,6 +1258,11 @@
 	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
 }
 
+int omap_lcd_dma_ext_running(void)
+{
+	return lcd_dma.ext_ctrl && lcd_dma.active;
+}
+
 /*----------------------------------------------------------------------------*/
 
 static int __init omap_init_dma(void)
@@ -1389,6 +1394,7 @@
 EXPORT_SYMBOL(omap_enable_lcd_dma);
 EXPORT_SYMBOL(omap_setup_lcd_dma);
 EXPORT_SYMBOL(omap_stop_lcd_dma);
+EXPORT_SYMBOL(omap_lcd_dma_ext_running);
 EXPORT_SYMBOL(omap_set_lcd_dma_b1);
 EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
 EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 38d7ebf..eba3cb5 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -97,6 +97,32 @@
 }
 
 
+/**
+ * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR
+ * @inputmask: current value of idlect mask
+ */
+__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
+{
+	int n;
+
+	/* If ARMXOR cannot be idled this function call is unnecessary */
+	if (!(inputmask & (1 << 1)))
+		return inputmask;
+
+	/* If any active timer is using ARMXOR return modified mask */
+	for (n = 0; dm_timers[n].base; ++n)
+		if (omap_dm_timer_read_reg(&dm_timers[n], OMAP_TIMER_CTRL_REG)&
+		    OMAP_TIMER_CTRL_ST) {
+			if (((omap_readl(MOD_CONF_CTRL_1)>>(n*2)) & 0x03) == 0)
+				inputmask &= ~(1 << 1);
+			else
+				inputmask &= ~(1 << 2);
+		}
+
+	return inputmask;
+}
+
+
 void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 {
 	int n = (timer - dm_timers) << 1;
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
new file mode 100644
index 0000000..305e9b9
--- /dev/null
+++ b/arch/arm/plat-omap/fb.c
@@ -0,0 +1,80 @@
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/sram.h>
+#include <asm/arch/omapfb.h>
+
+#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
+
+static struct omapfb_platform_data omapfb_config;
+
+static u64 omap_fb_dma_mask = ~(u32)0;
+
+static struct platform_device omap_fb_device = {
+	.name		= "omapfb",
+	.id		= -1,
+	.dev = {
+		.dma_mask		= &omap_fb_dma_mask,
+		.coherent_dma_mask	= ~(u32)0,
+		.platform_data		= &omapfb_config,
+	},
+	.num_resources = 0,
+};
+
+/* called from map_io */
+void omapfb_reserve_mem(void)
+{
+	const struct omap_fbmem_config *fbmem_conf;
+
+	omapfb_config.fbmem.fb_sram_start = omap_fb_sram_start;
+	omapfb_config.fbmem.fb_sram_size = omap_fb_sram_size;
+
+	fbmem_conf = omap_get_config(OMAP_TAG_FBMEM, struct omap_fbmem_config);
+
+	if (fbmem_conf != NULL) {
+		/* indicate that the bootloader already initialized the
+		 * fb device, so we'll skip that part in the fb driver
+		 */
+		omapfb_config.fbmem.fb_sdram_start = fbmem_conf->fb_sdram_start;
+		omapfb_config.fbmem.fb_sdram_size = fbmem_conf->fb_sdram_size;
+		if (fbmem_conf->fb_sdram_size) {
+			pr_info("Reserving %u bytes SDRAM for frame buffer\n",
+				fbmem_conf->fb_sdram_size);
+			reserve_bootmem(fbmem_conf->fb_sdram_start,
+					fbmem_conf->fb_sdram_size);
+		}
+	}
+}
+
+static inline int omap_init_fb(void)
+{
+	const struct omap_lcd_config *conf;
+
+	conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
+	if (conf == NULL)
+		return 0;
+
+	omapfb_config.lcd = *conf;
+
+	return platform_device_register(&omap_fb_device);
+}
+
+arch_initcall(omap_init_fb);
+
+#else
+
+void omapfb_reserve_mem(void) {}
+
+#endif
+
+
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index b4d5b9e..d3c8ea7 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -174,7 +174,7 @@
 static inline struct gpio_bank *get_gpio_bank(int gpio)
 {
 #ifdef CONFIG_ARCH_OMAP15XX
-	if (cpu_is_omap1510()) {
+	if (cpu_is_omap15xx()) {
 		if (OMAP_GPIO_IS_MPUIO(gpio))
 			return &gpio_bank[0];
 		return &gpio_bank[1];
@@ -223,7 +223,7 @@
 		return 0;
 	}
 #ifdef CONFIG_ARCH_OMAP15XX
-	if (cpu_is_omap1510() && gpio < 16)
+	if (cpu_is_omap15xx() && gpio < 16)
 		return 0;
 #endif
 #if defined(CONFIG_ARCH_OMAP16XX)
@@ -402,13 +402,13 @@
 	u32 gpio_bit = 1 << gpio;
 
 	MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
-		trigger & IRQT_LOW);
+		trigger & __IRQT_LOWLVL);
 	MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
-		trigger & IRQT_HIGH);
+		trigger & __IRQT_HIGHLVL);
 	MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
-		trigger & IRQT_RISING);
+		trigger & __IRQT_RISEDGE);
 	MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
-		trigger & IRQT_FALLING);
+		trigger & __IRQT_FALEDGE);
 	/* FIXME: Possibly do 'set_irq_handler(j, do_level_IRQ)' if only level
 	 * triggering requested. */
 }
@@ -422,9 +422,9 @@
 	case METHOD_MPUIO:
 		reg += OMAP_MPUIO_GPIO_INT_EDGE;
 		l = __raw_readl(reg);
-		if (trigger == IRQT_RISING)
+		if (trigger & __IRQT_RISEDGE)
 			l |= 1 << gpio;
-		else if (trigger == IRQT_FALLING)
+		else if (trigger & __IRQT_FALEDGE)
 			l &= ~(1 << gpio);
 		else
 			goto bad;
@@ -432,9 +432,9 @@
 	case METHOD_GPIO_1510:
 		reg += OMAP1510_GPIO_INT_CONTROL;
 		l = __raw_readl(reg);
-		if (trigger == IRQT_RISING)
+		if (trigger & __IRQT_RISEDGE)
 			l |= 1 << gpio;
-		else if (trigger == IRQT_FALLING)
+		else if (trigger & __IRQT_FALEDGE)
 			l &= ~(1 << gpio);
 		else
 			goto bad;
@@ -446,20 +446,21 @@
 			reg += OMAP1610_GPIO_EDGE_CTRL1;
 		gpio &= 0x07;
 		/* We allow only edge triggering, i.e. two lowest bits */
-		if (trigger & ~IRQT_BOTHEDGE)
+		if (trigger & (__IRQT_LOWLVL | __IRQT_HIGHLVL))
 			BUG();
-		/* NOTE: knows __IRQT_{FAL,RIS}EDGE match OMAP hardware */
-		trigger &= 0x03;
 		l = __raw_readl(reg);
 		l &= ~(3 << (gpio << 1));
-		l |= trigger << (gpio << 1);
+		if (trigger & __IRQT_RISEDGE)
+			l |= 2 << (gpio << 1);
+		if (trigger & __IRQT_FALEDGE)
+			l |= 1 << (gpio << 1);
 		break;
 	case METHOD_GPIO_730:
 		reg += OMAP730_GPIO_INT_CONTROL;
 		l = __raw_readl(reg);
-		if (trigger == IRQT_RISING)
+		if (trigger & __IRQT_RISEDGE)
 			l |= 1 << gpio;
-		else if (trigger == IRQT_FALLING)
+		else if (trigger & __IRQT_FALEDGE)
 			l &= ~(1 << gpio);
 		else
 			goto bad;
@@ -491,7 +492,9 @@
 	if (check_gpio(gpio) < 0)
 		return -EINVAL;
 
-	if (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL|IRQT_PROBE))
+	if (type & IRQT_PROBE)
+		return -EINVAL;
+	if (!cpu_is_omap24xx() && (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL)))
 		return -EINVAL;
 
 	bank = get_gpio_bank(gpio);
@@ -755,13 +758,32 @@
 	if (bank->method == METHOD_GPIO_24XX)
 		isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
 #endif
-
 	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);
+		u32 isr_saved, level_mask = 0;
+
+		isr_saved = isr = __raw_readl(isr_reg);
+
+		if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
+			isr &= 0x0000ffff;
+
+		if (cpu_is_omap24xx())
+			level_mask =
+				__raw_readl(bank->base +
+					OMAP24XX_GPIO_LEVELDETECT0) |
+				__raw_readl(bank->base +
+					OMAP24XX_GPIO_LEVELDETECT1);
+
+		/* clear edge sensitive interrupts before handler(s) are
+		called so that we don't miss any interrupt occurred while
+		executing them */
+		_enable_gpio_irqbank(bank, isr_saved & ~level_mask, 0);
+		_clear_gpio_irqbank(bank, isr_saved & ~level_mask);
+		_enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1);
+
+		/* if there is only edge sensitive GPIO pin interrupts
+		configured, we could unmask GPIO bank interrupt immediately */
+		if (!level_mask)
+			desc->chip->unmask(irq);
 
 		if (!isr)
 			break;
@@ -774,6 +796,20 @@
 			d = irq_desc + gpio_irq;
 			desc_handle_irq(gpio_irq, d, regs);
 		}
+
+		if (cpu_is_omap24xx()) {
+			/* clear level sensitive interrupts after handler(s) */
+			_enable_gpio_irqbank(bank, isr_saved & level_mask, 0);
+			_clear_gpio_irqbank(bank, isr_saved & level_mask);
+			_enable_gpio_irqbank(bank, isr_saved & level_mask, 1);
+		}
+
+		/* if bank has any level sensitive GPIO pin interrupt
+		configured, we must unmask the bank interrupt only after
+		handler(s) are executed in order to avoid spurious bank
+		interrupt */
+		if (level_mask)
+			desc->chip->unmask(irq);
 	}
 }
 
@@ -848,7 +884,7 @@
 
 	initialized = 1;
 
-	if (cpu_is_omap1510()) {
+	if (cpu_is_omap15xx()) {
 		gpio_ick = clk_get(NULL, "arm_gpio_ck");
 		if (IS_ERR(gpio_ick))
 			printk("Could not get arm_gpio_ck\n");
@@ -869,7 +905,7 @@
 	}
 
 #ifdef CONFIG_ARCH_OMAP15XX
-	if (cpu_is_omap1510()) {
+	if (cpu_is_omap15xx()) {
 		printk(KERN_INFO "OMAP1510 GPIO hardware\n");
 		gpio_bank_count = 2;
 		gpio_bank = gpio_bank_1510;
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 1cd2cac..196aac3 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -34,7 +34,7 @@
 #ifdef CONFIG_MCBSP_DEBUG
 #define DBG(x...)	printk(x)
 #else
-#define DBG(x...)	do { } while (0)
+#define DBG(x...)			do { } while (0)
 #endif
 
 struct omap_mcbsp {
@@ -44,6 +44,7 @@
 	omap_mcbsp_word_length       rx_word_length;
 	omap_mcbsp_word_length       tx_word_length;
 
+	omap_mcbsp_io_type_t         io_type; /* IRQ or poll */
 	/* IRQ based TX/RX */
 	int                          rx_irq;
 	int                          tx_irq;
@@ -64,10 +65,19 @@
 };
 
 static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];
+#ifdef CONFIG_ARCH_OMAP1
 static struct clk *mcbsp_dsp_ck = 0;
 static struct clk *mcbsp_api_ck = 0;
 static struct clk *mcbsp_dspxor_ck = 0;
-
+#endif
+#ifdef CONFIG_ARCH_OMAP2
+static struct clk *mcbsp1_ick = 0;
+static struct clk *mcbsp1_fck = 0;
+static struct clk *mcbsp2_ick = 0;
+static struct clk *mcbsp2_fck = 0;
+static struct clk *sys_ck = 0;
+static struct clk *sys_clkout = 0;
+#endif
 
 static void omap_mcbsp_dump_reg(u8 id)
 {
@@ -88,7 +98,6 @@
 	DBG("***********************\n");
 }
 
-
 static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id);
@@ -109,7 +118,6 @@
 	return IRQ_HANDLED;
 }
 
-
 static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
 {
 	struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data);
@@ -176,7 +184,7 @@
 		return 0;
 	}
 
-	if (cpu_is_omap1510() || cpu_is_omap16xx()) {
+	if (cpu_is_omap15xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) {
 		if (id > OMAP_MAX_MCBSP_COUNT) {
 			printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
 			return -1;
@@ -187,9 +195,10 @@
 	return -1;
 }
 
+#ifdef CONFIG_ARCH_OMAP1
 static void omap_mcbsp_dsp_request(void)
 {
-	if (cpu_is_omap1510() || cpu_is_omap16xx()) {
+	if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
 		clk_enable(mcbsp_dsp_ck);
 		clk_enable(mcbsp_api_ck);
 
@@ -207,12 +216,49 @@
 
 static void omap_mcbsp_dsp_free(void)
 {
-	if (cpu_is_omap1510() || cpu_is_omap16xx()) {
+	if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
 		clk_disable(mcbsp_dspxor_ck);
 		clk_disable(mcbsp_dsp_ck);
 		clk_disable(mcbsp_api_ck);
 	}
 }
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2
+static void omap2_mcbsp2_mux_setup(void)
+{
+	omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
+	omap_cfg_reg(R14_24XX_MCBSP2_FSX);
+	omap_cfg_reg(W15_24XX_MCBSP2_DR);
+	omap_cfg_reg(V15_24XX_MCBSP2_DX);
+	omap_cfg_reg(V14_24XX_GPIO117);
+	omap_cfg_reg(W14_24XX_SYS_CLKOUT);
+}
+#endif
+
+/*
+ * We can choose between IRQ based or polled IO.
+ * This needs to be called before omap_mcbsp_request().
+ */
+int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
+{
+	if (omap_mcbsp_check(id) < 0)
+		return -EINVAL;
+
+	spin_lock(&mcbsp[id].lock);
+
+	if (!mcbsp[id].free) {
+		printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1);
+		spin_unlock(&mcbsp[id].lock);
+		return -EINVAL;
+	}
+
+	mcbsp[id].io_type = io_type;
+
+	spin_unlock(&mcbsp[id].lock);
+
+	return 0;
+}
 
 int omap_mcbsp_request(unsigned int id)
 {
@@ -221,12 +267,26 @@
 	if (omap_mcbsp_check(id) < 0)
 		return -EINVAL;
 
+#ifdef CONFIG_ARCH_OMAP1
 	/*
 	 * On 1510, 1610 and 1710, McBSP1 and McBSP3
 	 * are DSP public peripherals.
 	 */
 	if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
 		omap_mcbsp_dsp_request();
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2
+	if (cpu_is_omap24xx()) {
+		if (id == OMAP_MCBSP1) {
+			clk_enable(mcbsp1_ick);
+			clk_enable(mcbsp1_fck);
+		} else {
+			clk_enable(mcbsp2_ick);
+			clk_enable(mcbsp2_fck);
+		}
+	}
+#endif
 
 	spin_lock(&mcbsp[id].lock);
 	if (!mcbsp[id].free) {
@@ -238,30 +298,33 @@
 	mcbsp[id].free = 0;
 	spin_unlock(&mcbsp[id].lock);
 
-	/* We need to get IRQs here */
-	err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0,
-			  "McBSP",
-			  (void *) (&mcbsp[id]));
-	if (err != 0) {
-		printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n",
-		       mcbsp[id].tx_irq, mcbsp[id].id);
-		return err;
+	if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) {
+		/* We need to get IRQs here */
+		err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0,
+				  "McBSP",
+				  (void *) (&mcbsp[id]));
+		if (err != 0) {
+			printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n",
+			       mcbsp[id].tx_irq, mcbsp[id].id);
+			return err;
+		}
+
+		init_completion(&(mcbsp[id].tx_irq_completion));
+
+
+		err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0,
+				  "McBSP",
+				  (void *) (&mcbsp[id]));
+		if (err != 0) {
+			printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n",
+			       mcbsp[id].rx_irq, mcbsp[id].id);
+			free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
+			return err;
+		}
+
+		init_completion(&(mcbsp[id].rx_irq_completion));
 	}
 
-	init_completion(&(mcbsp[id].tx_irq_completion));
-
-
-	err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0,
-			  "McBSP",
-			  (void *) (&mcbsp[id]));
-	if (err != 0) {
-		printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n",
-		       mcbsp[id].rx_irq, mcbsp[id].id);
-		free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
-		return err;
-	}
-
-	init_completion(&(mcbsp[id].rx_irq_completion));
 	return 0;
 
 }
@@ -271,8 +334,24 @@
 	if (omap_mcbsp_check(id) < 0)
 		return;
 
-	if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
-		omap_mcbsp_dsp_free();
+#ifdef CONFIG_ARCH_OMAP1
+	if (cpu_class_is_omap1()) {
+		if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
+			omap_mcbsp_dsp_free();
+	}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2
+	if (cpu_is_omap24xx()) {
+		if (id == OMAP_MCBSP1) {
+			clk_disable(mcbsp1_ick);
+			clk_disable(mcbsp1_fck);
+		} else {
+			clk_disable(mcbsp2_ick);
+			clk_disable(mcbsp2_fck);
+		}
+	}
+#endif
 
 	spin_lock(&mcbsp[id].lock);
 	if (mcbsp[id].free) {
@@ -284,9 +363,11 @@
 	mcbsp[id].free = 1;
 	spin_unlock(&mcbsp[id].lock);
 
-	/* Free IRQs */
-	free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id]));
-	free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
+	if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) {
+		/* Free IRQs */
+		free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id]));
+		free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
+	}
 }
 
 /*
@@ -461,6 +542,115 @@
 }
 
 
+int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
+{
+	u32 io_base = mcbsp[id].io_base;
+	omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length;
+	omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length;
+	u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
+
+	if (tx_word_length != rx_word_length)
+		return -EINVAL;
+
+	/* First we wait for the transmitter to be ready */
+	spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
+	while (!(spcr2 & XRDY)) {
+		spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
+		if (attempts++ > 1000) {
+			/* We must reset the transmitter */
+			OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST));
+			udelay(10);
+			OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
+			udelay(10);
+			printk("McBSP transmitter not ready\n");
+			return -EAGAIN;
+		}
+	}
+
+	/* Now we can push the data */
+	if (tx_word_length > OMAP_MCBSP_WORD_16)
+		OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
+	OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
+
+	/* We wait for the receiver to be ready */
+	spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
+	while (!(spcr1 & RRDY)) {
+		spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
+		if (attempts++ > 1000) {
+			/* We must reset the receiver */
+			OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST));
+			udelay(10);
+			OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
+			udelay(10);
+			printk("McBSP receiver not ready\n");
+			return -EAGAIN;
+		}
+	}
+
+	/* Receiver is ready, let's read the dummy data */
+	if (rx_word_length > OMAP_MCBSP_WORD_16)
+		word_msb = OMAP_MCBSP_READ(io_base, DRR2);
+	word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
+
+	return 0;
+}
+
+int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word)
+{
+	u32 io_base = mcbsp[id].io_base, clock_word = 0;
+	omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length;
+	omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length;
+	u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
+
+	if (tx_word_length != rx_word_length)
+		return -EINVAL;
+
+	/* First we wait for the transmitter to be ready */
+	spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
+	while (!(spcr2 & XRDY)) {
+		spcr2 = OMAP_MCBSP_READ(io_base, SPCR2);
+		if (attempts++ > 1000) {
+			/* We must reset the transmitter */
+			OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST));
+			udelay(10);
+			OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
+			udelay(10);
+			printk("McBSP transmitter not ready\n");
+			return -EAGAIN;
+		}
+	}
+
+	/* We first need to enable the bus clock */
+	if (tx_word_length > OMAP_MCBSP_WORD_16)
+		OMAP_MCBSP_WRITE(io_base, DXR2, clock_word >> 16);
+	OMAP_MCBSP_WRITE(io_base, DXR1, clock_word & 0xffff);
+
+	/* We wait for the receiver to be ready */
+	spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
+	while (!(spcr1 & RRDY)) {
+		spcr1 = OMAP_MCBSP_READ(io_base, SPCR1);
+		if (attempts++ > 1000) {
+			/* We must reset the receiver */
+			OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST));
+			udelay(10);
+			OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
+			udelay(10);
+			printk("McBSP receiver not ready\n");
+			return -EAGAIN;
+		}
+	}
+
+	/* Receiver is ready, there is something for us */
+	if (rx_word_length > OMAP_MCBSP_WORD_16)
+		word_msb = OMAP_MCBSP_READ(io_base, DRR2);
+	word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
+
+	word[0] = (word_lsb | (word_msb << 16));
+
+	return 0;
+}
+
+
 /*
  * Simple DMA based buffer rx/tx routines.
  * Nothing fancy, just a single buffer tx/rx through DMA.
@@ -471,6 +661,9 @@
 int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
 {
 	int dma_tx_ch;
+	int src_port = 0;
+	int dest_port = 0;
+	int sync_dev = 0;
 
 	if (omap_mcbsp_check(id) < 0)
 		return -EINVAL;
@@ -487,20 +680,27 @@
 
 	init_completion(&(mcbsp[id].tx_dma_completion));
 
+	if (cpu_class_is_omap1()) {
+		src_port = OMAP_DMA_PORT_TIPB;
+		dest_port = OMAP_DMA_PORT_EMIFF;
+	}
+	if (cpu_is_omap24xx())
+		sync_dev = mcbsp[id].dma_tx_sync;
+
 	omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
 				     OMAP_DMA_DATA_TYPE_S16,
 				     length >> 1, 1,
 				     OMAP_DMA_SYNC_ELEMENT,
-				     0, 0);
+	 sync_dev, 0);
 
 	omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
-				 OMAP_DMA_PORT_TIPB,
+				 src_port,
 				 OMAP_DMA_AMODE_CONSTANT,
 				 mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1,
 				 0, 0);
 
 	omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
-				OMAP_DMA_PORT_EMIFF,
+				dest_port,
 				OMAP_DMA_AMODE_POST_INC,
 				buffer,
 				0, 0);
@@ -514,6 +714,9 @@
 int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
 {
 	int dma_rx_ch;
+	int src_port = 0;
+	int dest_port = 0;
+	int sync_dev = 0;
 
 	if (omap_mcbsp_check(id) < 0)
 		return -EINVAL;
@@ -530,20 +733,27 @@
 
 	init_completion(&(mcbsp[id].rx_dma_completion));
 
+	if (cpu_class_is_omap1()) {
+		src_port = OMAP_DMA_PORT_TIPB;
+		dest_port = OMAP_DMA_PORT_EMIFF;
+	}
+	if (cpu_is_omap24xx())
+		sync_dev = mcbsp[id].dma_rx_sync;
+
 	omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
 				     OMAP_DMA_DATA_TYPE_S16,
 				     length >> 1, 1,
 				     OMAP_DMA_SYNC_ELEMENT,
-				     0, 0);
+	 sync_dev, 0);
 
 	omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
-				OMAP_DMA_PORT_TIPB,
+				src_port,
 				OMAP_DMA_AMODE_CONSTANT,
 				mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1,
 				0, 0);
 
 	omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
-				 OMAP_DMA_PORT_EMIFF,
+				 dest_port,
 				 OMAP_DMA_AMODE_POST_INC,
 				 buffer,
 				 0, 0);
@@ -688,6 +898,23 @@
 };
 #endif
 
+#if defined(CONFIG_ARCH_OMAP24XX)
+static const struct omap_mcbsp_info mcbsp_24xx[] = {
+	[0] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE),
+		.dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
+		.dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
+		.rx_irq = INT_24XX_MCBSP1_IRQ_RX,
+		.tx_irq = INT_24XX_MCBSP1_IRQ_TX,
+		},
+	[1] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE),
+		.dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
+		.dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
+		.rx_irq = INT_24XX_MCBSP2_IRQ_RX,
+		.tx_irq = INT_24XX_MCBSP2_IRQ_TX,
+		},
+};
+#endif
+
 static int __init omap_mcbsp_init(void)
 {
 	int mcbsp_count = 0, i;
@@ -695,6 +922,7 @@
 
 	printk("Initializing OMAP McBSP system\n");
 
+#ifdef CONFIG_ARCH_OMAP1
 	mcbsp_dsp_ck = clk_get(0, "dsp_ck");
 	if (IS_ERR(mcbsp_dsp_ck)) {
 		printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n");
@@ -710,6 +938,29 @@
 		printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n");
 		return PTR_ERR(mcbsp_dspxor_ck);
 	}
+#endif
+#ifdef CONFIG_ARCH_OMAP2
+	mcbsp1_ick = clk_get(0, "mcbsp1_ick");
+	if (IS_ERR(mcbsp1_ick)) {
+		printk(KERN_ERR "mcbsp: could not acquire mcbsp1_ick handle.\n");
+		return PTR_ERR(mcbsp1_ick);
+	}
+	mcbsp1_fck = clk_get(0, "mcbsp1_fck");
+	if (IS_ERR(mcbsp1_fck)) {
+		printk(KERN_ERR "mcbsp: could not acquire mcbsp1_fck handle.\n");
+		return PTR_ERR(mcbsp1_fck);
+	}
+	mcbsp2_ick = clk_get(0, "mcbsp2_ick");
+	if (IS_ERR(mcbsp2_ick)) {
+		printk(KERN_ERR "mcbsp: could not acquire mcbsp2_ick handle.\n");
+		return PTR_ERR(mcbsp2_ick);
+	}
+	mcbsp2_fck = clk_get(0, "mcbsp2_fck");
+	if (IS_ERR(mcbsp2_fck)) {
+		printk(KERN_ERR "mcbsp: could not acquire mcbsp2_fck handle.\n");
+		return PTR_ERR(mcbsp2_fck);
+	}
+#endif
 
 #ifdef CONFIG_ARCH_OMAP730
 	if (cpu_is_omap730()) {
@@ -718,7 +969,7 @@
 	}
 #endif
 #ifdef CONFIG_ARCH_OMAP15XX
-	if (cpu_is_omap1510()) {
+	if (cpu_is_omap15xx()) {
 		mcbsp_info = mcbsp_1510;
 		mcbsp_count = ARRAY_SIZE(mcbsp_1510);
 	}
@@ -729,6 +980,19 @@
 		mcbsp_count = ARRAY_SIZE(mcbsp_1610);
 	}
 #endif
+#if defined(CONFIG_ARCH_OMAP24XX)
+	if (cpu_is_omap24xx()) {
+		mcbsp_info = mcbsp_24xx;
+		mcbsp_count = ARRAY_SIZE(mcbsp_24xx);
+
+		/* REVISIT: where's the right place? */
+		omap2_mcbsp2_mux_setup();
+		sys_ck = clk_get(0, "sys_ck");
+		sys_clkout = clk_get(0, "sys_clkout");
+		clk_set_parent(sys_clkout, sys_ck);
+		clk_enable(sys_clkout);
+	}
+#endif
 	for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) {
 		if (i >= mcbsp_count) {
 			mcbsp[i].io_base = 0;
@@ -741,6 +1005,7 @@
 		mcbsp[i].dma_rx_lch = -1;
 
 		mcbsp[i].io_base = mcbsp_info[i].virt_base;
+		mcbsp[i].io_type = OMAP_MCBSP_IRQ_IO; /* Default I/O is IRQ based */
 		mcbsp[i].tx_irq = mcbsp_info[i].tx_irq;
 		mcbsp[i].rx_irq = mcbsp_info[i].rx_irq;
 		mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync;
@@ -751,11 +1016,11 @@
 	return 0;
 }
 
-
 arch_initcall(omap_mcbsp_init);
 
 EXPORT_SYMBOL(omap_mcbsp_config);
 EXPORT_SYMBOL(omap_mcbsp_request);
+EXPORT_SYMBOL(omap_mcbsp_set_io_type);
 EXPORT_SYMBOL(omap_mcbsp_free);
 EXPORT_SYMBOL(omap_mcbsp_start);
 EXPORT_SYMBOL(omap_mcbsp_stop);
@@ -763,4 +1028,6 @@
 EXPORT_SYMBOL(omap_mcbsp_recv_word);
 EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
 EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
+EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
+EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll);
 EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c
index 5cc6775..37792d4 100644
--- a/arch/arm/plat-omap/ocpi.c
+++ b/arch/arm/plat-omap/ocpi.c
@@ -62,9 +62,6 @@
 	if (!cpu_is_omap16xx())
 		return -ENODEV;
 
-	/* Make sure there's clock for OCPI */
-	clk_enable(ocpi_ck);
-
 	/* Enable access for OHCI in OCPI */
 	val = omap_readl(OCPI_PROT);
 	val &= ~0xff;
diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c
index 093efd7..1a24e2c 100644
--- a/arch/arm/plat-omap/pm.c
+++ b/arch/arm/plat-omap/pm.c
@@ -38,6 +38,7 @@
 #include <linux/pm.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
+#include <linux/pm.h>
 #include <linux/interrupt.h>
 
 #include <asm/io.h>
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index ee82763..b7bf09b 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -16,24 +16,94 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 
-#include <asm/mach/map.h>
 #include <asm/tlb.h>
 #include <asm/io.h>
 #include <asm/cacheflush.h>
 
+#include <asm/mach/map.h>
+
 #include <asm/arch/sram.h>
+#include <asm/arch/board.h>
 
 #define OMAP1_SRAM_PA		0x20000000
 #define OMAP1_SRAM_VA		0xd0000000
 #define OMAP2_SRAM_PA		0x40200000
+#define OMAP2_SRAM_PUB_PA	0x4020f800
 #define OMAP2_SRAM_VA		0xd0000000
+#define OMAP2_SRAM_PUB_VA	0xd0000800
 
+#if defined(CONFIG_ARCH_OMAP24XX)
+#define SRAM_BOOTLOADER_SZ	0x00
+#else
 #define SRAM_BOOTLOADER_SZ	0x80
+#endif
+
+#define VA_REQINFOPERM0		IO_ADDRESS(0x68005048)
+#define VA_READPERM0		IO_ADDRESS(0x68005050)
+#define VA_WRITEPERM0		IO_ADDRESS(0x68005058)
+#define VA_CONTROL_STAT		IO_ADDRESS(0x480002F8)
+#define GP_DEVICE		0x300
+#define TYPE_MASK		0x700
+
+#define ROUND_DOWN(value,boundary)	((value) & (~((boundary)-1)))
 
 static unsigned long omap_sram_base;
 static unsigned long omap_sram_size;
 static unsigned long omap_sram_ceil;
 
+unsigned long omap_fb_sram_start;
+unsigned long omap_fb_sram_size;
+
+/* Depending on the target RAMFS firewall setup, the public usable amount of
+ * SRAM varies.  The default accessable size for all device types is 2k. A GP
+ * device allows ARM11 but not other initators for full size. This
+ * functionality seems ok until some nice security API happens.
+ */
+static int is_sram_locked(void)
+{
+	int type = 0;
+
+	if (cpu_is_omap242x())
+		type = __raw_readl(VA_CONTROL_STAT) & TYPE_MASK;
+
+	if (type == GP_DEVICE) {
+		/* RAMFW: R/W access to all initators for all qualifier sets */
+		if (cpu_is_omap242x()) {
+			__raw_writel(0xFF, VA_REQINFOPERM0); /* all q-vects */
+			__raw_writel(0xCFDE, VA_READPERM0);  /* all i-read */
+			__raw_writel(0xCFDE, VA_WRITEPERM0); /* all i-write */
+		}
+		return 0;
+	} else
+		return 1; /* assume locked with no PPA or security driver */
+}
+
+void get_fb_sram_conf(unsigned long start_avail, unsigned size_avail,
+		      unsigned long *start, unsigned long *size)
+{
+	const struct omap_fbmem_config *fbmem_conf;
+
+	fbmem_conf = omap_get_config(OMAP_TAG_FBMEM, struct omap_fbmem_config);
+	if (fbmem_conf != NULL) {
+		*start = fbmem_conf->fb_sram_start;
+		*size = fbmem_conf->fb_sram_size;
+	} else {
+		*size = 0;
+		*start = 0;
+	}
+
+	if (*size && (
+	    *start < start_avail ||
+	    *start + *size > start_avail + size_avail)) {
+		printk(KERN_ERR "invalid FB SRAM configuration\n");
+		*start = start_avail;
+		*size = size_avail;
+	}
+
+	if (*size)
+		pr_info("Reserving %lu bytes SRAM for frame buffer\n", *size);
+}
+
 /*
  * The amount of SRAM depends on the core type.
  * Note that we cannot try to test for SRAM here because writes
@@ -42,26 +112,45 @@
  */
 void __init omap_detect_sram(void)
 {
-	if (!cpu_is_omap24xx())
+	unsigned long sram_start;
+
+	if (cpu_is_omap24xx()) {
+		if (is_sram_locked()) {
+			omap_sram_base = OMAP2_SRAM_PUB_VA;
+			sram_start = OMAP2_SRAM_PUB_PA;
+			omap_sram_size = 0x800; /* 2K */
+		} else {
+			omap_sram_base = OMAP2_SRAM_VA;
+			sram_start = OMAP2_SRAM_PA;
+			if (cpu_is_omap242x())
+				omap_sram_size = 0xa0000; /* 640K */
+			else if (cpu_is_omap243x())
+				omap_sram_size = 0x10000; /* 64K */
+		}
+	} else {
 		omap_sram_base = OMAP1_SRAM_VA;
-	else
-		omap_sram_base = OMAP2_SRAM_VA;
+		sram_start = OMAP1_SRAM_PA;
 
-	if (cpu_is_omap730())
-		omap_sram_size = 0x32000;	/* 200K */
-	else if (cpu_is_omap15xx())
-		omap_sram_size = 0x30000;	/* 192K */
-	else if (cpu_is_omap1610() || cpu_is_omap1621() || cpu_is_omap1710())
-		omap_sram_size = 0x4000;	/* 16K */
-	else if (cpu_is_omap1611())
-		omap_sram_size = 0x3e800;	/* 250K */
-	else if (cpu_is_omap2420())
-		omap_sram_size = 0xa0014;	/* 640K */
-	else {
-		printk(KERN_ERR "Could not detect SRAM size\n");
-		omap_sram_size = 0x4000;
+		if (cpu_is_omap730())
+			omap_sram_size = 0x32000;	/* 200K */
+		else if (cpu_is_omap15xx())
+			omap_sram_size = 0x30000;	/* 192K */
+		else if (cpu_is_omap1610() || cpu_is_omap1621() ||
+		     cpu_is_omap1710())
+			omap_sram_size = 0x4000;	/* 16K */
+		else if (cpu_is_omap1611())
+			omap_sram_size = 0x3e800;	/* 250K */
+		else {
+			printk(KERN_ERR "Could not detect SRAM size\n");
+			omap_sram_size = 0x4000;
+		}
 	}
-
+	get_fb_sram_conf(sram_start + SRAM_BOOTLOADER_SZ,
+			 omap_sram_size - SRAM_BOOTLOADER_SZ,
+			 &omap_fb_sram_start, &omap_fb_sram_size);
+	if (omap_fb_sram_size)
+		omap_sram_size -= sram_start + omap_sram_size -
+				  omap_fb_sram_start;
 	omap_sram_ceil = omap_sram_base + omap_sram_size;
 }
 
@@ -80,12 +169,20 @@
  */
 void __init omap_map_sram(void)
 {
+	unsigned long base;
+
 	if (omap_sram_size == 0)
 		return;
 
 	if (cpu_is_omap24xx()) {
 		omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA;
-		omap_sram_io_desc[0].pfn = __phys_to_pfn(OMAP2_SRAM_PA);
+
+		if (is_sram_locked())
+			base = OMAP2_SRAM_PUB_PA;
+		else
+			base = OMAP2_SRAM_PA;
+		base = ROUND_DOWN(base, PAGE_SIZE);
+		omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
 	}
 
 	omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE;
@@ -93,7 +190,8 @@
 	iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc));
 
 	printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n",
-	       omap_sram_io_desc[0].pfn, omap_sram_io_desc[0].virtual,
+	__pfn_to_phys(omap_sram_io_desc[0].pfn),
+	omap_sram_io_desc[0].virtual,
 	       omap_sram_io_desc[0].length);
 
 	/*
@@ -118,8 +216,9 @@
 		printk(KERN_ERR "Not enough space in SRAM\n");
 		return NULL;
 	}
+
 	omap_sram_ceil -= size;
-	omap_sram_ceil &= ~0x3;
+	omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *));
 	memcpy((void *)omap_sram_ceil, start, size);
 
 	return (void *)omap_sram_ceil;
diff --git a/arch/arm/plat-omap/timer32k.c b/arch/arm/plat-omap/timer32k.c
new file mode 100644
index 0000000..b2a943b
--- /dev/null
+++ b/arch/arm/plat-omap/timer32k.c
@@ -0,0 +1,325 @@
+/*
+ * linux/arch/arm/plat-omap/timer32k.c
+ *
+ * OMAP 32K Timer
+ *
+ * Copyright (C) 2004 - 2005 Nokia Corporation
+ * Partial timer rewrite and additional dynamic tick timer support by
+ * Tony Lindgen <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * MPU timer code based on the older MPU timer code for OMAP
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.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
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * 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/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+struct sys_timer omap_timer;
+
+/*
+ * ---------------------------------------------------------------------------
+ * 32KHz OS timer
+ *
+ * This currently works only on 16xx, as 1510 does not have the continuous
+ * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track
+ * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer
+ * on 1510 would be possible, but the timer would not be as accurate as
+ * with the 32KHz synchronized timer.
+ * ---------------------------------------------------------------------------
+ */
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+#define TIMER_32K_SYNCHRONIZED		0xfffbc410
+#elif defined(CONFIG_ARCH_OMAP24XX)
+#define TIMER_32K_SYNCHRONIZED		0x48004010
+#else
+#error OMAP 32KHz timer does not currently work on 15XX!
+#endif
+
+/* 16xx specific defines */
+#define OMAP1_32K_TIMER_BASE		0xfffb9000
+#define OMAP1_32K_TIMER_CR		0x08
+#define OMAP1_32K_TIMER_TVR		0x00
+#define OMAP1_32K_TIMER_TCR		0x04
+
+/* 24xx specific defines */
+#define OMAP2_GP_TIMER_BASE		0x48028000
+#define CM_CLKSEL_WKUP			0x48008440
+#define GP_TIMER_TIDR			0x00
+#define GP_TIMER_TISR			0x18
+#define GP_TIMER_TIER			0x1c
+#define GP_TIMER_TCLR			0x24
+#define GP_TIMER_TCRR			0x28
+#define GP_TIMER_TLDR			0x2c
+#define GP_TIMER_TTGR			0x30
+#define GP_TIMER_TSICR			0x40
+
+#define OMAP_32K_TICKS_PER_HZ		(32768 / HZ)
+
+/*
+ * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
+ * so with HZ = 128, TVR = 255.
+ */
+#define OMAP_32K_TIMER_TICK_PERIOD	((32768 / HZ) - 1)
+
+#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate)			\
+				(((nr_jiffies) * (clock_rate)) / HZ)
+
+static inline void omap_32k_timer_write(int val, int reg)
+{
+	if (cpu_class_is_omap1())
+		omap_writew(val, OMAP1_32K_TIMER_BASE + reg);
+
+	if (cpu_is_omap24xx())
+		omap_writel(val, OMAP2_GP_TIMER_BASE + reg);
+}
+
+static inline unsigned long omap_32k_timer_read(int reg)
+{
+	if (cpu_class_is_omap1())
+		return omap_readl(OMAP1_32K_TIMER_BASE + reg) & 0xffffff;
+
+	if (cpu_is_omap24xx())
+		return omap_readl(OMAP2_GP_TIMER_BASE + reg);
+}
+
+/*
+ * The 32KHz synchronized timer is an additional timer on 16xx.
+ * It is always running.
+ */
+static inline unsigned long omap_32k_sync_timer_read(void)
+{
+	return omap_readl(TIMER_32K_SYNCHRONIZED);
+}
+
+static inline void omap_32k_timer_start(unsigned long load_val)
+{
+	if (cpu_class_is_omap1()) {
+		omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR);
+		omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR);
+	}
+
+	if (cpu_is_omap24xx()) {
+		omap_32k_timer_write(0xffffffff - load_val, GP_TIMER_TCRR);
+		omap_32k_timer_write((1 << 1), GP_TIMER_TIER);
+		omap_32k_timer_write((1 << 1) | 1, GP_TIMER_TCLR);
+	}
+}
+
+static inline void omap_32k_timer_stop(void)
+{
+	if (cpu_class_is_omap1())
+		omap_32k_timer_write(0x0, OMAP1_32K_TIMER_CR);
+
+	if (cpu_is_omap24xx())
+		omap_32k_timer_write(0x0, GP_TIMER_TCLR);
+}
+
+/*
+ * Rounds down to nearest usec. Note that this will overflow for larger values.
+ */
+static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k)
+{
+	return (ticks_32k * 5*5*5*5*5*5) >> 9;
+}
+
+/*
+ * Rounds down to nearest nsec.
+ */
+static inline unsigned long long
+omap_32k_ticks_to_nsecs(unsigned long ticks_32k)
+{
+	return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9;
+}
+
+static unsigned long omap_32k_last_tick = 0;
+
+/*
+ * Returns elapsed usecs since last 32k timer interrupt
+ */
+static unsigned long omap_32k_timer_gettimeoffset(void)
+{
+	unsigned long now = omap_32k_sync_timer_read();
+	return omap_32k_ticks_to_usecs(now - omap_32k_last_tick);
+}
+
+/*
+ * Returns current time from boot in nsecs. It's OK for this to wrap
+ * around for now, as it's just a relative time stamp.
+ */
+unsigned long long sched_clock(void)
+{
+	return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read());
+}
+
+/*
+ * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this
+ * function is also called from other interrupts to remove latency
+ * issues with dynamic tick. In the dynamic tick case, we need to lock
+ * with irqsave.
+ */
+static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
+					    struct pt_regs *regs)
+{
+	unsigned long flags;
+	unsigned long now;
+
+	write_seqlock_irqsave(&xtime_lock, flags);
+
+	if (cpu_is_omap24xx()) {
+		u32 status = omap_32k_timer_read(GP_TIMER_TISR);
+		omap_32k_timer_write(status, GP_TIMER_TISR);
+	}
+
+	now = omap_32k_sync_timer_read();
+
+	while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) {
+		omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
+		timer_tick(regs);
+	}
+
+	/* Restart timer so we don't drift off due to modulo or dynamic tick.
+	 * By default we program the next timer to be continuous to avoid
+	 * latencies during high system load. During dynamic tick operation the
+	 * continuous timer can be overridden from pm_idle to be longer.
+	 */
+	omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now);
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NO_IDLE_HZ
+/*
+ * Programs the next timer interrupt needed. Called when dynamic tick is
+ * enabled, and to reprogram the ticks to skip from pm_idle. Note that
+ * we can keep the timer continuous, and don't need to set it to run in
+ * one-shot mode. This is because the timer will get reprogrammed again
+ * after next interrupt.
+ */
+void omap_32k_timer_reprogram(unsigned long next_tick)
+{
+	omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1);
+}
+
+static struct irqaction omap_32k_timer_irq;
+extern struct timer_update_handler timer_update;
+
+static int omap_32k_timer_enable_dyn_tick(void)
+{
+	/* No need to reprogram timer, just use the next interrupt */
+	return 0;
+}
+
+static int omap_32k_timer_disable_dyn_tick(void)
+{
+	omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
+	return 0;
+}
+
+static struct dyn_tick_timer omap_dyn_tick_timer = {
+	.enable		= omap_32k_timer_enable_dyn_tick,
+	.disable	= omap_32k_timer_disable_dyn_tick,
+	.reprogram	= omap_32k_timer_reprogram,
+	.handler	= omap_32k_timer_interrupt,
+};
+#endif	/* CONFIG_NO_IDLE_HZ */
+
+static struct irqaction omap_32k_timer_irq = {
+	.name		= "32KHz timer",
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= omap_32k_timer_interrupt,
+};
+
+static struct clk * gpt1_ick;
+static struct clk * gpt1_fck;
+
+static __init void omap_init_32k_timer(void)
+{
+#ifdef CONFIG_NO_IDLE_HZ
+	omap_timer.dyn_tick = &omap_dyn_tick_timer;
+#endif
+
+	if (cpu_class_is_omap1())
+		setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
+	if (cpu_is_omap24xx())
+		setup_irq(37, &omap_32k_timer_irq);
+	omap_timer.offset  = omap_32k_timer_gettimeoffset;
+	omap_32k_last_tick = omap_32k_sync_timer_read();
+
+	/* REVISIT: Check 24xx TIOCP_CFG settings after idle works */
+	if (cpu_is_omap24xx()) {
+		omap_32k_timer_write(0, GP_TIMER_TCLR);
+		omap_writel(0, CM_CLKSEL_WKUP);		/* 32KHz clock source */
+
+		gpt1_ick = clk_get(NULL, "gpt1_ick");
+		if (IS_ERR(gpt1_ick))
+			printk(KERN_ERR "Could not get gpt1_ick\n");
+		else
+			clk_enable(gpt1_ick);
+
+		gpt1_fck = clk_get(NULL, "gpt1_fck");
+		if (IS_ERR(gpt1_fck))
+			printk(KERN_ERR "Could not get gpt1_fck\n");
+		else
+			clk_enable(gpt1_fck);
+
+		mdelay(100);		/* Wait for clocks to stabilize */
+
+		omap_32k_timer_write(0x7, GP_TIMER_TISR);
+	}
+
+	omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * Timer initialization
+ * ---------------------------------------------------------------------------
+ */
+static void __init omap_timer_init(void)
+{
+	omap_init_32k_timer();
+}
+
+struct sys_timer omap_timer = {
+	.init		= omap_timer_init,
+	.offset		= NULL,		/* Initialized later */
+};
diff --git a/include/asm-arm/arch-at91rm9200/board.h b/include/asm-arm/arch-at91rm9200/board.h
index 2e7d113..4fdef13 100644
--- a/include/asm-arm/arch-at91rm9200/board.h
+++ b/include/asm-arm/arch-at91rm9200/board.h
@@ -38,6 +38,8 @@
 extern int at91_serial_map[AT91_NR_UART];
 extern int at91_console_port;
 
+#include <linux/mtd/partitions.h>
+
  /* USB Device */
 struct at91_udc_data {
 	u8	vbus_pin;		/* high == host powering us */
@@ -77,4 +79,26 @@
 };
 extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
 
+ /* NAND / SmartMedia */
+struct at91_nand_data {
+	u8		enable_pin;	/* chip enable */
+	u8		det_pin;	/* card detect */
+	u8		rdy_pin;	/* ready/busy */
+	u8		ale;		/* address line number connected to ALE */
+	u8		cle;		/* address line number connected to CLE */
+        struct mtd_partition* (*partition_info)(int, int*);
+};
+extern void __init at91_add_device_nand(struct at91_nand_data *data);
+
+ /* I2C*/
+void __init at91_add_device_i2c(void);
+
+ /* RTC */
+void __init at91_add_device_rtc(void);
+
+ /* LEDs */
+extern u8 at91_leds_cpu;
+extern u8 at91_leds_timer;
+extern void __init at91_init_leds(u8 cpu_led, u8 timer_led);
+
 #endif
diff --git a/include/asm-arm/arch-ep93xx/ts72xx.h b/include/asm-arm/arch-ep93xx/ts72xx.h
index 412215e..a94f63f 100644
--- a/include/asm-arm/arch-ep93xx/ts72xx.h
+++ b/include/asm-arm/arch-ep93xx/ts72xx.h
@@ -12,6 +12,8 @@
  * febfc000	[67]0000000	4K	NAND data register
  * febfb000	[67]0400000	4K	NAND control register
  * febfa000	[67]0800000	4K	NAND busy register
+ * febf9000	10800000	4K	TS-5620 RTC index register
+ * febf8000	11700000	4K	TS-5620 RTC data register
  */
 
 #define TS72XX_MODEL_PHYS_BASE		0x22000000
@@ -58,6 +60,15 @@
 #define TS72XX_NAND_BUSY_SIZE		0x00001000
 
 
+#define TS72XX_RTC_INDEX_VIRT_BASE	0xfebf9000
+#define TS72XX_RTC_INDEX_PHYS_BASE	0x10800000
+#define TS72XX_RTC_INDEX_SIZE		0x00001000
+
+#define TS72XX_RTC_DATA_VIRT_BASE	0xfebf8000
+#define TS72XX_RTC_DATA_PHYS_BASE	0x11700000
+#define TS72XX_RTC_DATA_SIZE		0x00001000
+
+
 #ifndef __ASSEMBLY__
 #include <asm/io.h>
 
diff --git a/include/asm-arm/arch-imx/dma.h b/include/asm-arm/arch-imx/dma.h
index b45fa36..621ff2c 100644
--- a/include/asm-arm/arch-imx/dma.h
+++ b/include/asm-arm/arch-imx/dma.h
@@ -17,27 +17,16 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+
 #ifndef __ASM_ARCH_DMA_H
 #define __ASM_ARCH_DMA_H
 
-/*
- * DMA registration
- */
-
 typedef enum {
 	DMA_PRIO_HIGH = 0,
-	DMA_PRIO_MEDIUM = 3,
-	DMA_PRIO_LOW = 6
+	DMA_PRIO_MEDIUM = 1,
+	DMA_PRIO_LOW = 2
 } imx_dma_prio;
 
-int imx_request_dma(char *name, imx_dma_prio prio,
-		    void (*irq_handler) (int, void *, struct pt_regs *),
-		    void (*err_handler) (int, void *, struct pt_regs *),
-		    void *data);
-
-void imx_free_dma(int dma_ch);
-
-
 #define DMA_REQ_UART3_T        2
 #define DMA_REQ_UART3_R        3
 #define DMA_REQ_SSI2_T         4
diff --git a/include/asm-arm/arch-imx/imx-dma.h b/include/asm-arm/arch-imx/imx-dma.h
new file mode 100644
index 0000000..f2063c1
--- /dev/null
+++ b/include/asm-arm/arch-imx/imx-dma.h
@@ -0,0 +1,90 @@
+/*
+ *  linux/include/asm-arm/imxads/dma.h
+ *
+ *  Copyright (C) 1997,1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <asm/dma.h>
+
+#ifndef __ASM_ARCH_IMX_DMA_H
+#define __ASM_ARCH_IMX_DMA_H
+
+#define IMX_DMA_CHANNELS  11
+
+/*
+ * struct imx_dma_channel - i.MX specific DMA extension
+ * @name: name specified by DMA client
+ * @irq_handler: client callback for end of transfer
+ * @err_handler: client callback for error condition
+ * @data: clients context data for callbacks
+ * @dma_mode: direction of the transfer %DMA_MODE_READ or %DMA_MODE_WRITE
+ * @sg: pointer to the actual read/written chunk for scatter-gather emulation
+ * @sgbc: counter of processed bytes in the actual read/written chunk
+ * @resbytes: total residual number of bytes to transfer
+ *            (it can be lower or same as sum of SG mapped chunk sizes)
+ * @sgcount: number of chunks to be read/written
+ *
+ * Structure is used for IMX DMA processing. It would be probably good
+ * @struct dma_struct in the future for external interfacing and use
+ * @struct imx_dma_channel only as extension to it.
+ */
+
+struct imx_dma_channel {
+	const char *name;
+	void (*irq_handler) (int, void *, struct pt_regs *);
+	void (*err_handler) (int, void *, struct pt_regs *);
+	void *data;
+	dmamode_t  dma_mode;
+	struct scatterlist *sg;
+	unsigned int sgbc;
+	unsigned int sgcount;
+	unsigned int resbytes;
+	int dma_num;
+};
+
+extern struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS];
+
+
+/* The type to distinguish channel numbers parameter from ordinal int type */
+typedef int imx_dmach_t;
+
+int
+imx_dma_setup_single(imx_dmach_t dma_ch, dma_addr_t dma_address,
+		unsigned int dma_length, unsigned int dev_addr, dmamode_t dmamode);
+
+int
+imx_dma_setup_sg(imx_dmach_t dma_ch,
+		 struct scatterlist *sg, unsigned int sgcount, unsigned int dma_length,
+		 unsigned int dev_addr, dmamode_t dmamode);
+
+int
+imx_dma_setup_handlers(imx_dmach_t dma_ch,
+		void (*irq_handler) (int, void *, struct pt_regs *),
+		void (*err_handler) (int, void *, struct pt_regs *), void *data);
+
+void imx_dma_enable(imx_dmach_t dma_ch);
+
+void imx_dma_disable(imx_dmach_t dma_ch);
+
+int imx_dma_request(imx_dmach_t dma_ch, const char *name);
+
+void imx_dma_free(imx_dmach_t dma_ch);
+
+int imx_dma_request_by_prio(imx_dmach_t *pdma_ch, const char *name, imx_dma_prio prio);
+
+
+#endif	/* _ASM_ARCH_IMX_DMA_H */
diff --git a/include/asm-arm/arch-ixp23xx/memory.h b/include/asm-arm/arch-ixp23xx/memory.h
index bebcf0a..6e19f46 100644
--- a/include/asm-arm/arch-ixp23xx/memory.h
+++ b/include/asm-arm/arch-ixp23xx/memory.h
@@ -28,6 +28,7 @@
  *		to an address that the kernel can use.
  */
 #ifndef __ASSEMBLY__
+#include <asm/mach-types.h>
 
 #define __virt_to_bus(v)						\
 	({ unsigned int ret;						\
@@ -40,6 +41,22 @@
 	data = *((volatile int *)IXP23XX_PCI_SDRAM_BAR);		\
 	 __phys_to_virt((((b - (data & 0xfffffff0)) + 0x00000000))); })
 
+/*
+ * Coherency support.  Only supported on A2 CPUs or on A1
+ * systems that have the cache coherency workaround.
+ */
+static inline int __ixp23xx_arch_is_coherent(void)
+{
+	extern unsigned int processor_id;
+
+	if (((processor_id & 15) >= 2) || machine_is_roadrunner())
+		return 1;
+
+	return 0;
+}
+
+#define arch_is_coherent()	__ixp23xx_arch_is_coherent()
+
 #endif
 
 
diff --git a/include/asm-arm/arch-ixp23xx/platform.h b/include/asm-arm/arch-ixp23xx/platform.h
index f85b468..e4d9906 100644
--- a/include/asm-arm/arch-ixp23xx/platform.h
+++ b/include/asm-arm/arch-ixp23xx/platform.h
@@ -22,6 +22,7 @@
 int ixp23xx_pci_setup(int, struct pci_sys_data *);
 void ixp23xx_pci_preinit(void);
 struct pci_bus *ixp23xx_pci_scan_bus(int, struct pci_sys_data*);
+void ixp23xx_pci_slave_init(void);
 
 extern struct sys_timer ixp23xx_timer;
 
diff --git a/include/asm-arm/arch-omap/aic23.h b/include/asm-arm/arch-omap/aic23.h
index 590bac2..6513065 100644
--- a/include/asm-arm/arch-omap/aic23.h
+++ b/include/asm-arm/arch-omap/aic23.h
@@ -57,6 +57,7 @@
 #define LHV_MIN				0x0000
 
 // Analog audio path control register
+#define STA_REG(x)			((x)<<6)
 #define STE_ENABLED			0x0020
 #define DAC_SELECTED			0x0010
 #define BYPASS_ON			0x0008
@@ -109,4 +110,7 @@
 #define TLV320AIC23ID1                  (0x1a)	// cs low
 #define TLV320AIC23ID2                  (0x1b)	// cs high
 
+void tlv320aic23_power_up(void);
+void tlv320aic23_power_down(void);
+
 #endif /* __ASM_ARCH_AIC23_H */
diff --git a/include/asm-arm/arch-omap/board-ams-delta.h b/include/asm-arm/arch-omap/board-ams-delta.h
new file mode 100644
index 0000000..0070f6d
--- /dev/null
+++ b/include/asm-arm/arch-omap/board-ams-delta.h
@@ -0,0 +1,65 @@
+/*
+ * linux/include/asm-arm/arch-omap/board-ams-delta.h
+ *
+ * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
+ *
+ * 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
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __ASM_ARCH_OMAP_AMS_DELTA_H
+#define __ASM_ARCH_OMAP_AMS_DELTA_H
+
+#if defined (CONFIG_MACH_AMS_DELTA)
+
+#define AMS_DELTA_LATCH1_PHYS		0x01000000
+#define AMS_DELTA_LATCH1_VIRT		0xEA000000
+#define AMS_DELTA_MODEM_PHYS		0x04000000
+#define AMS_DELTA_MODEM_VIRT		0xEB000000
+#define AMS_DELTA_LATCH2_PHYS		0x08000000
+#define AMS_DELTA_LATCH2_VIRT		0xEC000000
+
+#define AMS_DELTA_LATCH1_LED_CAMERA	0x01
+#define AMS_DELTA_LATCH1_LED_ADVERT	0x02
+#define AMS_DELTA_LATCH1_LED_EMAIL	0x04
+#define AMS_DELTA_LATCH1_LED_HANDSFREE	0x08
+#define AMS_DELTA_LATCH1_LED_VOICEMAIL	0x10
+#define AMS_DELTA_LATCH1_LED_VOICE	0x20
+
+#define AMS_DELTA_LATCH2_LCD_VBLEN	0x0001
+#define AMS_DELTA_LATCH2_LCD_NDISP	0x0002
+#define AMS_DELTA_LATCH2_NAND_NCE	0x0004
+#define AMS_DELTA_LATCH2_NAND_NRE	0x0008
+#define AMS_DELTA_LATCH2_NAND_NWP	0x0010
+#define AMS_DELTA_LATCH2_NAND_NWE	0x0020
+#define AMS_DELTA_LATCH2_NAND_ALE	0x0040
+#define AMS_DELTA_LATCH2_NAND_CLE	0x0080
+#define AMS_DELTA_LATCH2_MODEM_NRESET	0x1000
+#define AMS_DELTA_LATCH2_MODEM_CODEC	0x2000
+
+#define AMS_DELTA_GPIO_PIN_NAND_RB	12
+
+#ifndef __ASSEMBLY__
+void ams_delta_latch1_write(u8 mask, u8 value);
+void ams_delta_latch2_write(u16 mask, u16 value);
+#endif
+
+#endif /* CONFIG_MACH_AMS_DELTA */
+
+#endif /* __ASM_ARCH_OMAP_AMS_DELTA_H */
diff --git a/include/asm-arm/arch-omap/board-apollon.h b/include/asm-arm/arch-omap/board-apollon.h
new file mode 100644
index 0000000..de0c5b7
--- /dev/null
+++ b/include/asm-arm/arch-omap/board-apollon.h
@@ -0,0 +1,45 @@
+/*
+ * linux/include/asm-arm/arch-omap/board-apollon.h
+ *
+ * Hardware definitions for Samsung OMAP24XX Apollon board.
+ *
+ * Initial creation by Kyungmin Park <kyungmin.park@samsung.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
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_ARCH_OMAP_APOLLON_H
+#define __ASM_ARCH_OMAP_APOLLON_H
+
+/* Placeholder for APOLLON specific defines */
+/* GPMC CS0 */
+#define APOLLON_CS0_BASE		0x00000000
+/* GPMC CS1 */
+#define APOLLON_CS1_BASE		0x08000000
+#define APOLLON_ETHR_START		(APOLLON_CS1_BASE + 0x300)
+#define APOLLON_ETHR_GPIO_IRQ		74
+/* GPMC CS2 - reserved for OneNAND */
+#define APOLLON_CS2_BASE		0x10000000
+/* GPMC CS3 - reserved for NOR or NAND */
+#define APOLLON_CS3_BASE		0x18000000
+
+#endif /*  __ASM_ARCH_OMAP_APOLLON_H */
+
diff --git a/include/asm-arm/arch-omap/board-h2.h b/include/asm-arm/arch-omap/board-h2.h
index 39ca5a3..b2888ef 100644
--- a/include/asm-arm/arch-omap/board-h2.h
+++ b/include/asm-arm/arch-omap/board-h2.h
@@ -34,9 +34,5 @@
 /* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
 #define OMAP1610_ETHR_START		0x04000300
 
-/* Samsung NAND flash at CS2B or CS3(NAND Boot) */
-#define OMAP_NAND_FLASH_START1           0x0A000000 /* CS2B */
-#define OMAP_NAND_FLASH_START2           0x0C000000 /* CS3 */
-
 #endif /*  __ASM_ARCH_OMAP_H2_H */
 
diff --git a/include/asm-arm/arch-omap/board-h3.h b/include/asm-arm/arch-omap/board-h3.h
index 1b12c1d..761ea0a 100644
--- a/include/asm-arm/arch-omap/board-h3.h
+++ b/include/asm-arm/arch-omap/board-h3.h
@@ -30,10 +30,6 @@
 /* In OMAP1710 H3 the Ethernet is directly connected to CS1 */
 #define OMAP1710_ETHR_START		0x04000300
 
-/* Samsung NAND flash at CS2B or CS3(NAND Boot) */
-#define OMAP_NAND_FLASH_START1           0x0A000000 /* CS2B */
-#define OMAP_NAND_FLASH_START2           0x0C000000 /* CS3 */
-
 #define MAXIRQNUM			(IH_BOARD_BASE)
 #define MAXFIQNUM			MAXIRQNUM
 #define MAXSWINUM			MAXIRQNUM
diff --git a/include/asm-arm/arch-omap/board-h4.h b/include/asm-arm/arch-omap/board-h4.h
index 33ea29a..7ef664b 100644
--- a/include/asm-arm/arch-omap/board-h4.h
+++ b/include/asm-arm/arch-omap/board-h4.h
@@ -33,12 +33,6 @@
 /* GPMC CS1 */
 #define OMAP24XX_ETHR_START             0x08000300
 #define OMAP24XX_ETHR_GPIO_IRQ		92
-
-#define H4_CS0_BASE		     0x04000000
-
-#define H4_CS0_BASE		     0x04000000
-
-#define H4_CS0_BASE		     0x04000000
-
+#define H4_CS0_BASE			0x04000000
 #endif /*  __ASM_ARCH_OMAP_H4_H */
 
diff --git a/include/asm-arm/arch-omap/board-netstar.h b/include/asm-arm/arch-omap/board-netstar.h
deleted file mode 100644
index 77cc0fb..0000000
--- a/include/asm-arm/arch-omap/board-netstar.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
- *
- * Hardware definitions for OMAP5910 based NetStar board.
- *
- * 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 __ASM_ARCH_NETSTAR_H
-#define __ASM_ARCH_NETSTAR_H
-
-#include <asm/arch/tc.h>
-
-#define OMAP_NAND_FLASH_START1		OMAP_CS1_PHYS + (1 << 23)
-#define OMAP_NAND_FLASH_START2		OMAP_CS1_PHYS + (2 << 23)
-
-#endif /*  __ASM_ARCH_NETSTAR_H */
diff --git a/include/asm-arm/arch-omap/board-nokia.h b/include/asm-arm/arch-omap/board-nokia.h
new file mode 100644
index 0000000..72deea2
--- /dev/null
+++ b/include/asm-arm/arch-omap/board-nokia.h
@@ -0,0 +1,54 @@
+/*
+ *  linux/include/asm-arm/arch-omap/board-nokia.h
+ *
+ *  Information structures for Nokia-specific board config data
+ *
+ *  Copyright (C) 2005	Nokia Corporation
+ */
+
+#ifndef _OMAP_BOARD_NOKIA_H
+#define _OMAP_BOARD_NOKIA_H
+
+#include <linux/types.h>
+
+#define OMAP_TAG_NOKIA_BT	0x4e01
+#define OMAP_TAG_WLAN_CX3110X	0x4e02
+#define OMAP_TAG_CBUS		0x4e03
+#define OMAP_TAG_EM_ASIC_BB5	0x4e04
+
+
+#define BT_CHIP_CSR		1
+#define BT_CHIP_TI		2
+
+#define BT_SYSCLK_12		1
+#define BT_SYSCLK_38_4		2
+
+struct omap_bluetooth_config {
+	u8    chip_type;
+	u8    bt_wakeup_gpio;
+	u8    host_wakeup_gpio;
+	u8    reset_gpio;
+	u8    bt_uart;
+	u8    bd_addr[6];
+	u8    bt_sysclk;
+};
+
+struct omap_wlan_cx3110x_config {
+	u8  chip_type;
+	s16 power_gpio;
+	s16 irq_gpio;
+	s16 spi_cs_gpio;
+};
+
+struct omap_cbus_config {
+	s16 clk_gpio;
+	s16 dat_gpio;
+	s16 sel_gpio;
+};
+
+struct omap_em_asic_bb5_config {
+	s16 retu_irq_gpio;
+	s16 tahvo_irq_gpio;
+};
+
+#endif
diff --git a/include/asm-arm/arch-omap/board-perseus2.h b/include/asm-arm/arch-omap/board-perseus2.h
index 691e52a..eb74420 100644
--- a/include/asm-arm/arch-omap/board-perseus2.h
+++ b/include/asm-arm/arch-omap/board-perseus2.h
@@ -42,8 +42,4 @@
 
 #define NR_IRQS			(MAXIRQNUM + 1)
 
-/* Samsung NAND flash at CS2B or CS3(NAND Boot) */
-#define OMAP_NAND_FLASH_START1	   0x0A000000 /* CS2B */
-#define OMAP_NAND_FLASH_START2	   0x0C000000 /* CS3 */
-
 #endif
diff --git a/include/asm-arm/arch-omap/board.h b/include/asm-arm/arch-omap/board.h
index a0040cd..6d6240a 100644
--- a/include/asm-arm/arch-omap/board.h
+++ b/include/asm-arm/arch-omap/board.h
@@ -21,9 +21,12 @@
 #define OMAP_TAG_LCD		0x4f05
 #define OMAP_TAG_GPIO_SWITCH	0x4f06
 #define OMAP_TAG_UART		0x4f07
+#define OMAP_TAG_FBMEM		0x4f08
+#define OMAP_TAG_STI_CONSOLE	0x4f09
 
 #define OMAP_TAG_BOOT_REASON    0x4f80
 #define OMAP_TAG_FLASH_PART	0x4f81
+#define OMAP_TAG_VERSION_STR	0x4f82
 
 struct omap_clock_config {
 	/* 0 for 12 MHz, 1 for 13 MHz and 2 for 19.2 MHz */
@@ -54,6 +57,11 @@
 	u32 console_speed;
 };
 
+struct omap_sti_console_config {
+	unsigned enable:1;
+	u8 channel;
+};
+
 struct omap_usb_config {
 	/* Configure drivers according to the connectors on your board:
 	 *  - "A" connector (rectagular)
@@ -87,6 +95,13 @@
 	char ctrl_name[16];
 };
 
+struct omap_fbmem_config {
+	u32 fb_sram_start;
+	u32 fb_sram_size;
+	u32 fb_sdram_start;
+	u32 fb_sdram_size;
+};
+
 /* Cover:
  *      high -> closed
  *      low  -> open
@@ -106,6 +121,12 @@
 	int key_code:24; /* Linux key code */
 };
 
+struct omap_uart_config {
+	/* Bit field of UARTs present; bit 0 --> UART1 */
+	unsigned int enabled_uarts;
+};
+
+
 struct omap_flash_part_config {
 	char part_table[0];
 };
@@ -114,11 +135,14 @@
 	char reason_str[12];
 };
 
-struct omap_uart_config {
-	/* Bit field of UARTs present; bit 0 --> UART1 */
-	unsigned int enabled_uarts;
+struct omap_version_config {
+	char component[12];
+	char version[12];
 };
 
+
+#include <asm-arm/arch-omap/board-nokia.h>
+
 struct omap_board_config_entry {
 	u16 tag;
 	u16 len;
diff --git a/include/asm-arm/arch-omap/clock.h b/include/asm-arm/arch-omap/clock.h
index 46a0402..3c4eb9f 100644
--- a/include/asm-arm/arch-omap/clock.h
+++ b/include/asm-arm/arch-omap/clock.h
@@ -19,6 +19,7 @@
 	struct list_head	node;
 	struct module		*owner;
 	const char		*name;
+	int			id;
 	struct clk		*parent;
 	unsigned long		rate;
 	__u32			flags;
@@ -57,6 +58,7 @@
 extern void followparent_recalc(struct clk * clk);
 extern void clk_allow_idle(struct clk *clk);
 extern void clk_deny_idle(struct clk *clk);
+extern int clk_get_usecount(struct clk *clk);
 
 /* Clock flags */
 #define RATE_CKCTL		(1 << 0)	/* Main fixed ratio clocks */
@@ -80,10 +82,11 @@
 #define CM_PLL_SEL1		(1 << 18)
 #define CM_PLL_SEL2		(1 << 19)
 #define CM_SYSCLKOUT_SEL1	(1 << 20)
-#define CLOCK_IN_OMAP730	(1 << 21)
-#define CLOCK_IN_OMAP1510	(1 << 22)
-#define CLOCK_IN_OMAP16XX	(1 << 23)
-#define CLOCK_IN_OMAP242X	(1 << 24)
-#define CLOCK_IN_OMAP243X	(1 << 25)
+#define CLOCK_IN_OMAP310	(1 << 21)
+#define CLOCK_IN_OMAP730	(1 << 22)
+#define CLOCK_IN_OMAP1510	(1 << 23)
+#define CLOCK_IN_OMAP16XX	(1 << 24)
+#define CLOCK_IN_OMAP242X	(1 << 25)
+#define CLOCK_IN_OMAP243X	(1 << 26)
 
 #endif
diff --git a/include/asm-arm/arch-omap/dma.h b/include/asm-arm/arch-omap/dma.h
index d4e73ef..ca12023 100644
--- a/include/asm-arm/arch-omap/dma.h
+++ b/include/asm-arm/arch-omap/dma.h
@@ -404,6 +404,7 @@
 extern void omap_setup_lcd_dma(void);
 extern void omap_enable_lcd_dma(void);
 extern void omap_stop_lcd_dma(void);
+extern int  omap_lcd_dma_ext_running(void);
 extern void omap_set_lcd_dma_ext_controller(int external);
 extern void omap_set_lcd_dma_single_transfer(int single);
 extern void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
diff --git a/include/asm-arm/arch-omap/dmtimer.h b/include/asm-arm/arch-omap/dmtimer.h
index 11772c7..e6522e6 100644
--- a/include/asm-arm/arch-omap/dmtimer.h
+++ b/include/asm-arm/arch-omap/dmtimer.h
@@ -88,5 +88,6 @@
 void omap_dm_timer_reset_counter(struct omap_dm_timer *timer);
 
 int omap_dm_timers_active(void);
+u32 omap_dm_timer_modify_idlect_mask(u32 inputmask);
 
 #endif /* __ASM_ARCH_TIMER_H */
diff --git a/include/asm-arm/arch-omap/dsp.h b/include/asm-arm/arch-omap/dsp.h
index 57bf4f3..06dad83 100644
--- a/include/asm-arm/arch-omap/dsp.h
+++ b/include/asm-arm/arch-omap/dsp.h
@@ -181,10 +181,16 @@
 #define OMAP_DSP_MBCMD_PM_ENABLE	0x01
 
 #define OMAP_DSP_MBCMD_KFUNC_FBCTL	0x00
+#define OMAP_DSP_MBCMD_KFUNC_AUDIO_PWR	0x01
 
+#define OMAP_DSP_MBCMD_FBCTL_UPD	0x0000
 #define OMAP_DSP_MBCMD_FBCTL_ENABLE	0x0002
 #define OMAP_DSP_MBCMD_FBCTL_DISABLE	0x0003
 
+#define OMAP_DSP_MBCMD_AUDIO_PWR_UP	0x0000
+#define OMAP_DSP_MBCMD_AUDIO_PWR_DOWN1	0x0001
+#define OMAP_DSP_MBCMD_AUDIO_PWR_DOWN2	0x0002
+
 #define OMAP_DSP_MBCMD_TDEL_SAFE	0x0000
 #define OMAP_DSP_MBCMD_TDEL_KILL	0x0001
 
diff --git a/include/asm-arm/arch-omap/dsp_common.h b/include/asm-arm/arch-omap/dsp_common.h
index 4fcce69..16a459d 100644
--- a/include/asm-arm/arch-omap/dsp_common.h
+++ b/include/asm-arm/arch-omap/dsp_common.h
@@ -27,11 +27,12 @@
 #ifndef ASM_ARCH_DSP_COMMON_H
 #define ASM_ARCH_DSP_COMMON_H
 
-void omap_dsp_pm_suspend(void);
-void omap_dsp_pm_resume(void);
-void omap_dsp_request_mpui(void);
-void omap_dsp_release_mpui(void);
-int omap_dsp_request_mem(void);
-int omap_dsp_release_mem(void);
+extern void omap_dsp_request_mpui(void);
+extern void omap_dsp_release_mpui(void);
+extern int omap_dsp_request_mem(void);
+extern int omap_dsp_release_mem(void);
+
+extern void (*omap_dsp_audio_pwr_up_request)(int stage);
+extern void (*omap_dsp_audio_pwr_down_request)(int stage);
 
 #endif /* ASM_ARCH_DSP_COMMON_H */
diff --git a/include/asm-arm/arch-omap/gpioexpander.h b/include/asm-arm/arch-omap/gpioexpander.h
new file mode 100644
index 0000000..7a43b0a
--- /dev/null
+++ b/include/asm-arm/arch-omap/gpioexpander.h
@@ -0,0 +1,24 @@
+/*
+ * linux/include/asm-arm/arch-omap/gpioexpander.h
+ *
+ *
+ * Copyright (C) 2004 Texas Instruments, Inc.
+ *
+ * This package 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.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef __ASM_ARCH_OMAP_GPIOEXPANDER_H
+#define __ASM_ARCH_OMAP_GPIOEXPANDER_H
+
+/* Function Prototypes for GPIO Expander functions */
+
+int read_gpio_expa(u8 *, int);
+int write_gpio_expa(u8 , int);
+
+#endif /* __ASM_ARCH_OMAP_GPIOEXPANDER_H */
diff --git a/include/asm-arm/arch-omap/hardware.h b/include/asm-arm/arch-omap/hardware.h
index 5406b87..7909b72 100644
--- a/include/asm-arm/arch-omap/hardware.h
+++ b/include/asm-arm/arch-omap/hardware.h
@@ -306,6 +306,10 @@
 #include "board-h4.h"
 #endif
 
+#ifdef CONFIG_MACH_OMAP_APOLLON
+#include "board-apollon.h"
+#endif
+
 #ifdef CONFIG_MACH_OMAP_OSK
 #include "board-osk.h"
 #endif
@@ -314,10 +318,6 @@
 #include "board-voiceblue.h"
 #endif
 
-#ifdef CONFIG_MACH_NETSTAR
-#include "board-netstar.h"
-#endif
-
 #endif /* !__ASSEMBLER__ */
 
 #endif	/* __ASM_ARCH_OMAP_HARDWARE_H */
diff --git a/include/asm-arm/arch-omap/irda.h b/include/asm-arm/arch-omap/irda.h
new file mode 100644
index 0000000..805ae35
--- /dev/null
+++ b/include/asm-arm/arch-omap/irda.h
@@ -0,0 +1,36 @@
+/*
+ *  linux/include/asm-arm/arch-omap/irda.h
+ *
+ *  Copyright (C) 2005-2006 Komal Shah <komal_shah802003@yahoo.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.
+ */
+#ifndef ASMARM_ARCH_IRDA_H
+#define ASMARM_ARCH_IRDA_H
+
+/* board specific transceiver capabilities */
+
+#define IR_SEL		1	/* Selects IrDA */
+#define IR_SIRMODE	2
+#define IR_FIRMODE	4
+#define IR_MIRMODE	8
+
+struct omap_irda_config {
+	int transceiver_cap;
+	int (*transceiver_mode)(struct device *dev, int mode);
+	int (*select_irda)(struct device *dev, int state);
+	/* Very specific to the needs of some platforms (h3,h4)
+	 * having calls which can sleep in irda_set_speed.
+	 */
+	struct work_struct gpio_expa;
+	int rx_channel;
+	int tx_channel;
+	unsigned long dest_start;
+	unsigned long src_start;
+	int tx_trigger;
+	int rx_trigger;
+};
+
+#endif
diff --git a/include/asm-arm/arch-omap/irqs.h b/include/asm-arm/arch-omap/irqs.h
index 4ffce1d..42098d9 100644
--- a/include/asm-arm/arch-omap/irqs.h
+++ b/include/asm-arm/arch-omap/irqs.h
@@ -242,6 +242,11 @@
 #define INT_24XX_GPIO_BANK2	30
 #define INT_24XX_GPIO_BANK3	31
 #define INT_24XX_GPIO_BANK4	32
+#define INT_24XX_MCBSP1_IRQ_TX	59
+#define INT_24XX_MCBSP1_IRQ_RX	60
+#define INT_24XX_MCBSP2_IRQ_TX	62
+#define INT_24XX_MCBSP2_IRQ_RX	63
+#define INT_24XX_UART3_IRQ	74
 
 /* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730) and
  * 16 MPUIO lines */
diff --git a/include/asm-arm/arch-omap/keypad.h b/include/asm-arm/arch-omap/keypad.h
new file mode 100644
index 0000000..8a023a9
--- /dev/null
+++ b/include/asm-arm/arch-omap/keypad.h
@@ -0,0 +1,36 @@
+/*
+ *  linux/include/asm-arm/arch-omap/keypad.h
+ *
+ *  Copyright (C) 2006 Komal Shah <komal_shah802003@yahoo.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.
+ */
+#ifndef ASMARM_ARCH_KEYPAD_H
+#define ASMARM_ARCH_KEYPAD_H
+
+struct omap_kp_platform_data {
+	int rows;
+	int cols;
+	int *keymap;
+	unsigned int rep:1;
+	/* specific to OMAP242x*/
+	unsigned int *row_gpios;
+	unsigned int *col_gpios;
+};
+
+/* Group (0..3) -- when multiple keys are pressed, only the
+ * keys pressed in the same group are considered as pressed. This is
+ * in order to workaround certain crappy HW designs that produce ghost
+ * keypresses. */
+#define GROUP_0		(0 << 16)
+#define GROUP_1		(1 << 16)
+#define GROUP_2		(2 << 16)
+#define GROUP_3		(3 << 16)
+#define GROUP_MASK	GROUP_3
+
+#define KEY(col, row, val) (((col) << 28) | ((row) << 24) | (val))
+
+#endif
+
diff --git a/include/asm-arm/arch-omap/lcd_lph8923.h b/include/asm-arm/arch-omap/lcd_lph8923.h
new file mode 100644
index 0000000..004e67e
--- /dev/null
+++ b/include/asm-arm/arch-omap/lcd_lph8923.h
@@ -0,0 +1,14 @@
+#ifndef __LCD_LPH8923_H
+#define __LCD_LPH8923_H
+
+enum lcd_lph8923_test_num {
+	LCD_LPH8923_TEST_RGB_LINES,
+};
+
+enum lcd_lph8923_test_result {
+	LCD_LPH8923_TEST_SUCCESS,
+	LCD_LPH8923_TEST_INVALID,
+	LCD_LPH8923_TEST_FAILED,
+};
+
+#endif
diff --git a/include/asm-arm/arch-omap/mcbsp.h b/include/asm-arm/arch-omap/mcbsp.h
index e79d98a..ed0dde4 100644
--- a/include/asm-arm/arch-omap/mcbsp.h
+++ b/include/asm-arm/arch-omap/mcbsp.h
@@ -37,6 +37,11 @@
 #define OMAP1610_MCBSP2_BASE	0xfffb1000
 #define OMAP1610_MCBSP3_BASE	0xe1017000
 
+#define OMAP24XX_MCBSP1_BASE	0x48074000
+#define OMAP24XX_MCBSP2_BASE	0x48076000
+
+#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730)
+
 #define OMAP_MCBSP_REG_DRR2	0x00
 #define OMAP_MCBSP_REG_DRR1	0x02
 #define OMAP_MCBSP_REG_DXR2	0x04
@@ -71,9 +76,62 @@
 
 #define OMAP_MAX_MCBSP_COUNT 3
 
+#define AUDIO_MCBSP_DATAWRITE	(OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1)
+#define AUDIO_MCBSP_DATAREAD	(OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1)
+
+#define AUDIO_MCBSP		OMAP_MCBSP1
+#define AUDIO_DMA_TX		OMAP_DMA_MCBSP1_TX
+#define AUDIO_DMA_RX		OMAP_DMA_MCBSP1_RX
+
+#elif defined(CONFIG_ARCH_OMAP24XX)
+
+#define OMAP_MCBSP_REG_DRR2	0x00
+#define OMAP_MCBSP_REG_DRR1	0x04
+#define OMAP_MCBSP_REG_DXR2	0x08
+#define OMAP_MCBSP_REG_DXR1	0x0C
+#define OMAP_MCBSP_REG_SPCR2	0x10
+#define OMAP_MCBSP_REG_SPCR1	0x14
+#define OMAP_MCBSP_REG_RCR2	0x18
+#define OMAP_MCBSP_REG_RCR1	0x1C
+#define OMAP_MCBSP_REG_XCR2	0x20
+#define OMAP_MCBSP_REG_XCR1	0x24
+#define OMAP_MCBSP_REG_SRGR2	0x28
+#define OMAP_MCBSP_REG_SRGR1	0x2C
+#define OMAP_MCBSP_REG_MCR2	0x30
+#define OMAP_MCBSP_REG_MCR1	0x34
+#define OMAP_MCBSP_REG_RCERA	0x38
+#define OMAP_MCBSP_REG_RCERB	0x3C
+#define OMAP_MCBSP_REG_XCERA	0x40
+#define OMAP_MCBSP_REG_XCERB	0x44
+#define OMAP_MCBSP_REG_PCR0	0x48
+#define OMAP_MCBSP_REG_RCERC	0x4C
+#define OMAP_MCBSP_REG_RCERD	0x50
+#define OMAP_MCBSP_REG_XCERC	0x54
+#define OMAP_MCBSP_REG_XCERD	0x58
+#define OMAP_MCBSP_REG_RCERE	0x5C
+#define OMAP_MCBSP_REG_RCERF	0x60
+#define OMAP_MCBSP_REG_XCERE	0x64
+#define OMAP_MCBSP_REG_XCERF	0x68
+#define OMAP_MCBSP_REG_RCERG	0x6C
+#define OMAP_MCBSP_REG_RCERH	0x70
+#define OMAP_MCBSP_REG_XCERG	0x74
+#define OMAP_MCBSP_REG_XCERH	0x78
+
+#define OMAP_MAX_MCBSP_COUNT 2
+
+#define AUDIO_MCBSP_DATAWRITE	(OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1)
+#define AUDIO_MCBSP_DATAREAD	(OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1)
+
+#define AUDIO_MCBSP		OMAP_MCBSP2
+#define AUDIO_DMA_TX		OMAP24XX_DMA_MCBSP2_TX
+#define AUDIO_DMA_RX		OMAP24XX_DMA_MCBSP2_RX
+
+#endif
+
 #define OMAP_MCBSP_READ(base, reg)		__raw_readw((base) + OMAP_MCBSP_REG_##reg)
 #define OMAP_MCBSP_WRITE(base, reg, val)	__raw_writew((val), (base) + OMAP_MCBSP_REG_##reg)
 
+
 /************************** McBSP SPCR1 bit definitions ***********************/
 #define RRST			0x0001
 #define RRDY			0x0002
@@ -195,6 +253,10 @@
 	OMAP_MCBSP3,
 } omap_mcbsp_id;
 
+typedef int __bitwise omap_mcbsp_io_type_t;
+#define OMAP_MCBSP_IRQ_IO ((__force omap_mcbsp_io_type_t) 1)
+#define OMAP_MCBSP_POLL_IO ((__force omap_mcbsp_io_type_t) 2)
+
 typedef enum {
 	OMAP_MCBSP_WORD_8 = 0,
 	OMAP_MCBSP_WORD_12,
@@ -246,6 +308,9 @@
 
 int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length);
 int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length);
+int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word);
+int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word);
+
 
 /* SPI specific API */
 void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg);
diff --git a/include/asm-arm/arch-omap/mcspi.h b/include/asm-arm/arch-omap/mcspi.h
new file mode 100644
index 0000000..9e7f40a
--- /dev/null
+++ b/include/asm-arm/arch-omap/mcspi.h
@@ -0,0 +1,16 @@
+#ifndef _OMAP2_MCSPI_H
+#define _OMAP2_MCSPI_H
+
+struct omap2_mcspi_platform_config {
+	unsigned long	base;
+	unsigned short	num_cs;
+};
+
+struct omap2_mcspi_device_config {
+	unsigned turbo_mode:1;
+
+	/* Do we want one channel enabled at the same time? */
+	unsigned single_channel:1;
+};
+
+#endif
diff --git a/include/asm-arm/arch-omap/menelaus.h b/include/asm-arm/arch-omap/menelaus.h
index 46be8b8..88cd4c8 100644
--- a/include/asm-arm/arch-omap/menelaus.h
+++ b/include/asm-arm/arch-omap/menelaus.h
@@ -7,7 +7,7 @@
 #ifndef __ASM_ARCH_MENELAUS_H
 #define __ASM_ARCH_MENELAUS_H
 
-extern void menelaus_mmc_register(void (*callback)(u8 card_mask),
+extern void menelaus_mmc_register(void (*callback)(unsigned long data, u8 card_mask),
 				  unsigned long data);
 extern void menelaus_mmc_remove(void);
 extern void menelaus_mmc_opendrain(int enable);
diff --git a/include/asm-arm/arch-omap/mux.h b/include/asm-arm/arch-omap/mux.h
index 13415a9..0dc24d4 100644
--- a/include/asm-arm/arch-omap/mux.h
+++ b/include/asm-arm/arch-omap/mux.h
@@ -112,14 +112,13 @@
  *   as mux config
  */
 #define MUX_CFG_730(desc, mux_reg, mode_offset, mode,	\
-		   pull_reg, pull_bit, pull_status,	\
-		   pu_pd_reg, pu_pd_status, debug_status)\
+		   pull_bit, pull_status, debug_status)\
 {							\
 	.name =	 desc,					\
 	.debug = debug_status,				\
 	MUX_REG_730(mux_reg, mode_offset, mode)		\
 	PULL_REG_730(mux_reg, pull_bit, pull_status)	\
-	PU_PD_REG(pu_pd_reg, pu_pd_status)		\
+	PU_PD_REG(NA, 0)		\
 },
 
 #define MUX_CFG_24XX(desc, reg_offset, mode,			\
@@ -172,6 +171,11 @@
 	E4_730_KBC2,
 	F4_730_KBC3,
 	E3_730_KBC4,
+
+	/* USB */
+	AA17_730_USB_DM,
+	W16_730_USB_PU_EN,
+	W17_730_USB_VBUSI,
 };
 
 enum omap1xxx_index {
@@ -403,9 +407,53 @@
 	/* 24xx Menelaus interrupt */
 	W19_24XX_SYS_NIRQ,
 
+	/* 24xx clock */
+	W14_24XX_SYS_CLKOUT,
+
+	/* 242X McBSP */
+	Y15_24XX_MCBSP2_CLKX,
+	R14_24XX_MCBSP2_FSX,
+	W15_24XX_MCBSP2_DR,
+	V15_24XX_MCBSP2_DX,
+
 	/* 24xx GPIO */
+	M21_242X_GPIO11,
+	AA10_242X_GPIO13,
+	AA6_242X_GPIO14,
+	AA4_242X_GPIO15,
+	Y11_242X_GPIO16,
+	AA12_242X_GPIO17,
+	AA8_242X_GPIO58,
 	Y20_24XX_GPIO60,
+	W4__24XX_GPIO74,
 	M15_24XX_GPIO92,
+	V14_24XX_GPIO117,
+
+	P20_24XX_TSC_IRQ,
+
+	/* UART3 */
+	K15_24XX_UART3_TX,
+	K14_24XX_UART3_RX,
+
+	/* Keypad GPIO*/
+	T19_24XX_KBR0,
+	R19_24XX_KBR1,
+	V18_24XX_KBR2,
+	M21_24XX_KBR3,
+	E5__24XX_KBR4,
+	M18_24XX_KBR5,
+	R20_24XX_KBC0,
+	M14_24XX_KBC1,
+	H19_24XX_KBC2,
+	V17_24XX_KBC3,
+	P21_24XX_KBC4,
+	L14_24XX_KBC5,
+	N19_24XX_KBC6,
+
+	/* 24xx Menelaus Keypad GPIO */
+	B3__24XX_KBR5,
+	AA4_24XX_KBC2,
+	B13_24XX_KBC6,
 };
 
 #ifdef	CONFIG_OMAP_MUX
diff --git a/include/asm-arm/arch-omap/omap-alsa.h b/include/asm-arm/arch-omap/omap-alsa.h
new file mode 100644
index 0000000..df46954
--- /dev/null
+++ b/include/asm-arm/arch-omap/omap-alsa.h
@@ -0,0 +1,124 @@
+/*
+ * linux/include/asm-arm/arch-omap/omap-alsa.h
+ *
+ * Alsa Driver for AIC23 and TSC2101 codecs on OMAP platform boards.
+ *
+ * Copyright (C) 2006 Mika Laitio <lamikr@cc.jyu.fi>
+ *
+ * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus Brazil
+ * Written by Daniel Petrini, David Cohen, Anderson Briglia
+ *            {daniel.petrini, david.cohen, anderson.briglia}@indt.org.br
+ *
+ * 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
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * 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.
+ *
+ *  History
+ *  -------
+ *
+ *  2005/07/25 INdT-10LE Kernel Team - 	Alsa driver for omap osk,
+ *  					original version based in sa1100 driver
+ *  					and omap oss driver.
+ */
+
+#ifndef __OMAP_ALSA_H
+#define __OMAP_ALSA_H
+
+#include <sound/driver.h>
+#include <asm/arch/dma.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <asm/arch/mcbsp.h>
+#include <linux/platform_device.h>
+
+#define DMA_BUF_SIZE	(1024 * 8)
+
+/*
+ * Buffer management for alsa and dma
+ */
+struct audio_stream {
+	char *id;		/* identification string */
+	int stream_id;		/* numeric identification */
+	int dma_dev;		/* dma number of that device */
+	int *lch;		/* Chain of channels this stream is linked to */
+	char started;		/* to store if the chain was started or not */
+	int dma_q_head;		/* DMA Channel Q Head */
+	int dma_q_tail;		/* DMA Channel Q Tail */
+	char dma_q_count;	/* DMA Channel Q Count */
+	int active:1;		/* we are using this stream for transfer now */
+	int period;		/* current transfer period */
+	int periods;		/* current count of periods registerd in the DMA engine */
+	spinlock_t dma_lock;	/* for locking in DMA operations */
+	snd_pcm_substream_t *stream;	/* the pcm stream */
+	unsigned linked:1;	/* dma channels linked */
+	int offset;		/* store start position of the last period in the alsa buffer */
+	int (*hw_start)(void);  /* interface to start HW interface, e.g. McBSP */
+	int (*hw_stop)(void);   /* interface to stop HW interface, e.g. McBSP */
+};
+
+/*
+ * Alsa card structure for aic23
+ */
+struct snd_card_omap_codec {
+	snd_card_t *card;
+	snd_pcm_t *pcm;
+	long samplerate;
+	struct audio_stream s[2];	/* playback & capture */
+};
+
+/* Codec specific information and function pointers.
+ * Codec (omap-alsa-aic23.c and omap-alsa-tsc2101.c)
+ * are responsible for defining the function pointers.
+ */
+struct omap_alsa_codec_config {
+	char 	*name;
+	struct	omap_mcbsp_reg_cfg *mcbsp_regs_alsa;
+	snd_pcm_hw_constraint_list_t *hw_constraints_rates;
+	snd_pcm_hardware_t *snd_omap_alsa_playback;
+	snd_pcm_hardware_t *snd_omap_alsa_capture;
+	void	(*codec_configure_dev)(void);
+	void	(*codec_set_samplerate)(long);
+	void	(*codec_clock_setup)(void);
+	int	(*codec_clock_on)(void);
+	int 	(*codec_clock_off)(void);
+	int	(*get_default_samplerate)(void);
+};
+
+/*********** Mixer function prototypes *************************/
+int snd_omap_mixer(struct snd_card_omap_codec *);
+void snd_omap_init_mixer(void);
+
+#ifdef CONFIG_PM
+void snd_omap_suspend_mixer(void);
+void snd_omap_resume_mixer(void);
+#endif
+
+int snd_omap_alsa_post_probe(struct platform_device *pdev, struct omap_alsa_codec_config *config);
+int snd_omap_alsa_remove(struct platform_device *pdev);
+#ifdef CONFIG_PM
+int snd_omap_alsa_suspend(struct platform_device *pdev, pm_message_t state);
+int snd_omap_alsa_resume(struct platform_device *pdev);
+#else
+#define snd_omap_alsa_suspend	NULL
+#define snd_omap_alsa_resume	NULL
+#endif
+
+void callback_omap_alsa_sound_dma(void *);
+
+#endif
diff --git a/include/asm-arm/arch-omap/omapfb.h b/include/asm-arm/arch-omap/omapfb.h
index 4ba2622..fccdb3d 100644
--- a/include/asm-arm/arch-omap/omapfb.h
+++ b/include/asm-arm/arch-omap/omapfb.h
@@ -34,9 +34,10 @@
 #define OMAPFB_MIRROR		OMAP_IOW(31, int)
 #define OMAPFB_SYNC_GFX		OMAP_IO(37)
 #define OMAPFB_VSYNC		OMAP_IO(38)
-#define OMAPFB_SET_UPDATE_MODE	OMAP_IOW(40, enum omapfb_update_mode)
+#define OMAPFB_SET_UPDATE_MODE	OMAP_IOW(40, int)
+#define OMAPFB_UPDATE_WINDOW_OLD OMAP_IOW(41, struct omapfb_update_window_old)
 #define OMAPFB_GET_CAPS		OMAP_IOR(42, unsigned long)
-#define OMAPFB_GET_UPDATE_MODE	OMAP_IOW(43, enum omapfb_update_mode)
+#define OMAPFB_GET_UPDATE_MODE	OMAP_IOW(43, int)
 #define OMAPFB_LCD_TEST		OMAP_IOW(45, int)
 #define OMAPFB_CTRL_TEST	OMAP_IOW(46, int)
 #define OMAPFB_UPDATE_WINDOW	OMAP_IOW(47, struct omapfb_update_window)
@@ -66,9 +67,14 @@
 };
 
 struct omapfb_update_window {
-	u32 x, y;
-	u32 width, height;
-	u32 format;
+	__u32 x, y;
+	__u32 width, height;
+	__u32 format;
+};
+
+struct omapfb_update_window_old {
+	__u32 x, y;
+	__u32 width, height;
 };
 
 enum omapfb_plane {
@@ -83,17 +89,17 @@
 };
 
 struct omapfb_setup_plane {
-	u8  plane;
-	u8  channel_out;
-	u32 offset;
-	u32 pos_x, pos_y;
-	u32 width, height;
-	u32 color_mode;
+	__u8  plane;
+	__u8  channel_out;
+	__u32 offset;
+	__u32 pos_x, pos_y;
+	__u32 width, height;
+	__u32 color_mode;
 };
 
 struct omapfb_enable_plane {
-	u8  plane;
-	u8  enable;
+	__u8  plane;
+	__u8  enable;
 };
 
 enum omapfb_color_key_type {
@@ -103,10 +109,10 @@
 };
 
 struct omapfb_color_key {
-	u8  channel_out;
-	u32 background;
-	u32 trans_key;
-	u8  key_type;
+	__u8  channel_out;
+	__u32 background;
+	__u32 trans_key;
+	__u8  key_type;
 };
 
 enum omapfb_update_mode {
@@ -120,6 +126,9 @@
 #include <linux/completion.h>
 #include <linux/interrupt.h>
 #include <linux/fb.h>
+#include <linux/mutex.h>
+
+#include <asm/arch/board.h>
 
 #define OMAP_LCDC_INV_VSYNC             0x0001
 #define OMAP_LCDC_INV_HSYNC             0x0002
@@ -184,19 +193,38 @@
 	int re_cycle_time;
 	int cs_pulse_width;
 	int access_time;
+
+	int clk_div;
+
+	u32 tim[5];		/* set by extif->convert_timings */
+
+	int converted;
 };
 
 struct lcd_ctrl_extif {
 	int  (*init)		(void);
 	void (*cleanup)		(void);
+	void (*get_clk_info)	(u32 *clk_period, u32 *max_clk_div);
+	int  (*convert_timings)	(struct extif_timings *timings);
 	void (*set_timings)	(const struct extif_timings *timings);
-	void (*write_command)	(u32 cmd);
-	u32  (*read_data)	(void);
-	void (*write_data)	(u32 data);
+	void (*set_bits_per_cycle)(int bpc);
+	void (*write_command)	(const void *buf, unsigned int len);
+	void (*read_data)	(void *buf, unsigned int len);
+	void (*write_data)	(const void *buf, unsigned int len);
 	void (*transfer_area)	(int width, int height,
 				 void (callback)(void * data), void *data);
+	unsigned long		max_transmit_size;
 };
 
+struct omapfb_notifier_block {
+	struct notifier_block	nb;
+	void			*data;
+};
+
+typedef int (*omapfb_notifier_callback_t)(struct omapfb_notifier_block *,
+					   unsigned long event,
+					   struct omapfb_device *fbdev);
+
 struct lcd_ctrl {
 	const char	*name;
 	void		*data;
@@ -204,9 +232,11 @@
 	int		(*init)		  (struct omapfb_device *fbdev,
 					   int ext_mode, int req_vram_size);
 	void		(*cleanup)	  (void);
+	void		(*bind_client)	  (struct omapfb_notifier_block *nb);
 	void		(*get_vram_layout)(unsigned long *size,
 					   void **virt_base,
 					   dma_addr_t *phys_base);
+	int		(*mmap)		  (struct vm_area_struct *vma);
 	unsigned long	(*get_caps)	  (void);
 	int		(*set_update_mode)(enum omapfb_update_mode mode);
 	enum omapfb_update_mode (*get_update_mode)(void);
@@ -240,7 +270,7 @@
 	int			state;
 	int                     ext_lcdc;               /* Using external
                                                            LCD controller */
-	struct semaphore	rqueue_sema;
+	struct mutex		rqueue_mutex;
 
 	void			*vram_virt_base;
 	dma_addr_t		vram_phys_base;
@@ -261,12 +291,13 @@
 	struct device		*dev;
 };
 
-extern struct lcd_panel h3_panel;
-extern struct lcd_panel h2_panel;
-extern struct lcd_panel p2_panel;
-extern struct lcd_panel osk_panel;
-extern struct lcd_panel innovator1610_panel;
-extern struct lcd_panel innovator1510_panel;
+struct omapfb_platform_data {
+	struct omap_lcd_config   lcd;
+	struct omap_fbmem_config fbmem;
+};
+
+#define OMAPFB_EVENT_READY	1
+#define OMAPFB_EVENT_DISABLED	2
 
 #ifdef CONFIG_ARCH_OMAP1
 extern struct lcd_ctrl omap1_lcd_ctrl;
@@ -274,7 +305,20 @@
 extern struct lcd_ctrl omap2_disp_ctrl;
 #endif
 
+extern void omapfb_register_panel(struct lcd_panel *panel);
 extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval);
+extern void omapfb_notify_clients(struct omapfb_device *fbdev,
+				  unsigned long event);
+extern int  omapfb_register_client(struct omapfb_notifier_block *nb,
+				    omapfb_notifier_callback_t callback,
+				    void *callback_data);
+extern int  omapfb_unregister_client(struct omapfb_notifier_block *nb);
+extern int  omapfb_update_window_async(struct omapfb_update_window *win,
+					void (*callback)(void *),
+					void *callback_data);
+
+/* in arch/arm/plat-omap/devices.c */
+extern void omapfb_reserve_mem(void);
 
 #endif /* __KERNEL__ */
 
diff --git a/include/asm-arm/arch-omap/param.h b/include/asm-arm/arch-omap/param.h
new file mode 100644
index 0000000..face9ad
--- /dev/null
+++ b/include/asm-arm/arch-omap/param.h
@@ -0,0 +1,8 @@
+/*
+ *  linux/include/asm-arm/arch-omap/param.h
+ *
+ */
+
+#ifdef CONFIG_OMAP_32K_TIMER_HZ
+#define HZ	CONFIG_OMAP_32K_TIMER_HZ
+#endif
diff --git a/include/asm-arm/arch-omap/pm.h b/include/asm-arm/arch-omap/pm.h
index 7c79042..05b003f 100644
--- a/include/asm-arm/arch-omap/pm.h
+++ b/include/asm-arm/arch-omap/pm.h
@@ -49,7 +49,7 @@
 
 /*
  * ----------------------------------------------------------------------------
- * Powermanagement bitmasks
+ * Power management bitmasks
  * ----------------------------------------------------------------------------
  */
 #define IDLE_WAIT_CYCLES		0x00000fff
@@ -112,32 +112,59 @@
 #endif
 
 #ifndef __ASSEMBLER__
+
+#include <linux/clk.h>
+
+extern void prevent_idle_sleep(void);
+extern void allow_idle_sleep(void);
+
+/**
+ * clk_deny_idle - Prevents the clock from being idled during MPU idle
+ * @clk: clock signal handle
+ */
+void clk_deny_idle(struct clk *clk);
+
+/**
+ * clk_allow_idle - Counters previous clk_deny_idle
+ * @clk: clock signal handle
+ */
+void clk_deny_idle(struct clk *clk);
+
 extern void omap_pm_idle(void);
 extern void omap_pm_suspend(void);
 extern void omap730_cpu_suspend(unsigned short, unsigned short);
 extern void omap1510_cpu_suspend(unsigned short, unsigned short);
 extern void omap1610_cpu_suspend(unsigned short, unsigned short);
+extern void omap24xx_cpu_suspend(u32 dll_ctrl, u32 cpu_revision);
 extern void omap730_idle_loop_suspend(void);
 extern void omap1510_idle_loop_suspend(void);
 extern void omap1610_idle_loop_suspend(void);
+extern void omap24xx_idle_loop_suspend(void);
+
+extern unsigned int omap730_cpu_suspend_sz;
+extern unsigned int omap1510_cpu_suspend_sz;
+extern unsigned int omap1610_cpu_suspend_sz;
+extern unsigned int omap24xx_cpu_suspend_sz;
+extern unsigned int omap730_idle_loop_suspend_sz;
+extern unsigned int omap1510_idle_loop_suspend_sz;
+extern unsigned int omap1610_idle_loop_suspend_sz;
+extern unsigned int omap24xx_idle_loop_suspend_sz;
 
 #ifdef CONFIG_OMAP_SERIAL_WAKE
 extern void omap_serial_wake_trigger(int enable);
 #else
+#define omap_serial_wakeup_init()	{}
 #define omap_serial_wake_trigger(x)	{}
 #endif	/* CONFIG_OMAP_SERIAL_WAKE */
 
-extern unsigned int omap730_cpu_suspend_sz;
-extern unsigned int omap730_idle_loop_suspend_sz;
-extern unsigned int omap1510_cpu_suspend_sz;
-extern unsigned int omap1510_idle_loop_suspend_sz;
-extern unsigned int omap1610_cpu_suspend_sz;
-extern unsigned int omap1610_idle_loop_suspend_sz;
-
 #define ARM_SAVE(x) arm_sleep_save[ARM_SLEEP_SAVE_##x] = omap_readl(x)
 #define ARM_RESTORE(x) omap_writel((arm_sleep_save[ARM_SLEEP_SAVE_##x]), (x))
 #define ARM_SHOW(x) arm_sleep_save[ARM_SLEEP_SAVE_##x]
 
+#define DSP_SAVE(x) dsp_sleep_save[DSP_SLEEP_SAVE_##x] = __raw_readw(x)
+#define DSP_RESTORE(x) __raw_writew((dsp_sleep_save[DSP_SLEEP_SAVE_##x]), (x))
+#define DSP_SHOW(x) dsp_sleep_save[DSP_SLEEP_SAVE_##x]
+
 #define ULPD_SAVE(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x] = omap_readw(x)
 #define ULPD_RESTORE(x) omap_writew((ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]), (x))
 #define ULPD_SHOW(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]
@@ -154,6 +181,10 @@
 #define MPUI1610_RESTORE(x) omap_writel((mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x]), (x))
 #define MPUI1610_SHOW(x) mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x]
 
+#define OMAP24XX_SAVE(x) omap24xx_sleep_save[OMAP24XX_SLEEP_SAVE_##x] = x
+#define OMAP24XX_RESTORE(x) x = omap24xx_sleep_save[OMAP24XX_SLEEP_SAVE_##x]
+#define OMAP24XX_SHOW(x) omap24xx_sleep_save[OMAP24XX_SLEEP_SAVE_##x]
+
 /*
  * List of global OMAP registers to preserve.
  * More ones like CP and general purpose register values are preserved
@@ -176,6 +207,15 @@
 	ARM_SLEEP_SAVE_SIZE
 };
 
+enum dsp_save_state {
+	DSP_SLEEP_SAVE_START = 0,
+	/*
+	 * DSP registers 16 bits
+	 */
+	DSP_SLEEP_SAVE_DSP_IDLECT2,
+	DSP_SLEEP_SAVE_SIZE
+};
+
 enum ulpd_save_state {
 	ULPD_SLEEP_SAVE_START = 0,
 	/*
@@ -254,5 +294,30 @@
 #endif
 };
 
+enum omap24xx_save_state {
+	OMAP24XX_SLEEP_SAVE_START = 0,
+	OMAP24XX_SLEEP_SAVE_INTC_MIR0,
+	OMAP24XX_SLEEP_SAVE_INTC_MIR1,
+	OMAP24XX_SLEEP_SAVE_INTC_MIR2,
+	OMAP24XX_SLEEP_SAVE_CM_FCLKEN1_CORE,
+	OMAP24XX_SLEEP_SAVE_CM_FCLKEN2_CORE,
+	OMAP24XX_SLEEP_SAVE_CM_ICLKEN1_CORE,
+	OMAP24XX_SLEEP_SAVE_CM_ICLKEN2_CORE,
+	OMAP24XX_SLEEP_SAVE_CM_ICLKEN4_CORE,
+	OMAP24XX_SLEEP_SAVE_GPIO1_IRQENABLE1,
+	OMAP24XX_SLEEP_SAVE_GPIO2_IRQENABLE1,
+	OMAP24XX_SLEEP_SAVE_GPIO3_IRQENABLE1,
+	OMAP24XX_SLEEP_SAVE_GPIO4_IRQENABLE1,
+	OMAP24XX_SLEEP_SAVE_GPIO3_OE,
+	OMAP24XX_SLEEP_SAVE_GPIO4_OE,
+	OMAP24XX_SLEEP_SAVE_GPIO3_RISINGDETECT,
+	OMAP24XX_SLEEP_SAVE_GPIO3_FALLINGDETECT,
+	OMAP24XX_SLEEP_SAVE_CONTROL_PADCONF_SPI1_NCS2,
+	OMAP24XX_SLEEP_SAVE_CONTROL_PADCONF_MCBSP1_DX,
+	OMAP24XX_SLEEP_SAVE_CONTROL_PADCONF_SSI1_FLAG_TX,
+	OMAP24XX_SLEEP_SAVE_CONTROL_PADCONF_SYS_NIRQW0,
+	OMAP24XX_SLEEP_SAVE_SIZE
+};
+
 #endif /* ASSEMBLER */
 #endif /* __ASM_ARCH_OMAP_PM_H */
diff --git a/include/asm-arm/arch-omap/prcm.h b/include/asm-arm/arch-omap/prcm.h
index 7b48a5c..7bcaf94 100644
--- a/include/asm-arm/arch-omap/prcm.h
+++ b/include/asm-arm/arch-omap/prcm.h
@@ -1,5 +1,7 @@
 /*
- * prcm.h - Access definations for use in OMAP24XX clock and power management
+ * linux/include/asm-arm/arch-omap/prcm.h
+ *
+ * Access definations for use in OMAP24XX clock and power management
  *
  * Copyright (C) 2005 Texas Instruments, Inc.
  *
@@ -21,405 +23,7 @@
 #ifndef __ASM_ARM_ARCH_DPM_PRCM_H
 #define __ASM_ARM_ARCH_DPM_PRCM_H
 
-/* SET_PERFORMANCE_LEVEL PARAMETERS */
-#define PRCM_HALF_SPEED 1
-#define PRCM_FULL_SPEED 2
-
-#ifndef __ASSEMBLER__
-
-#define PRCM_REG32(offset)	__REG32(OMAP24XX_PRCM_BASE + (offset))
-
-#define PRCM_REVISION		PRCM_REG32(0x000)
-#define PRCM_SYSCONFIG		PRCM_REG32(0x010)
-#define PRCM_IRQSTATUS_MPU	PRCM_REG32(0x018)
-#define PRCM_IRQENABLE_MPU	PRCM_REG32(0x01C)
-#define PRCM_VOLTCTRL		PRCM_REG32(0x050)
-#define PRCM_VOLTST		PRCM_REG32(0x054)
-#define PRCM_CLKSRC_CTRL	PRCM_REG32(0x060)
-#define PRCM_CLKOUT_CTRL	PRCM_REG32(0x070)
-#define PRCM_CLKEMUL_CTRL	PRCM_REG32(0x078)
-#define PRCM_CLKCFG_CTRL	PRCM_REG32(0x080)
-#define PRCM_CLKCFG_STATUS	PRCM_REG32(0x084)
-#define PRCM_VOLTSETUP		PRCM_REG32(0x090)
-#define PRCM_CLKSSETUP		PRCM_REG32(0x094)
-#define PRCM_POLCTRL		PRCM_REG32(0x098)
-
-/* GENERAL PURPOSE */
-#define GENERAL_PURPOSE1	PRCM_REG32(0x0B0)
-#define GENERAL_PURPOSE2	PRCM_REG32(0x0B4)
-#define GENERAL_PURPOSE3	PRCM_REG32(0x0B8)
-#define GENERAL_PURPOSE4	PRCM_REG32(0x0BC)
-#define GENERAL_PURPOSE5	PRCM_REG32(0x0C0)
-#define GENERAL_PURPOSE6	PRCM_REG32(0x0C4)
-#define GENERAL_PURPOSE7	PRCM_REG32(0x0C8)
-#define GENERAL_PURPOSE8	PRCM_REG32(0x0CC)
-#define GENERAL_PURPOSE9	PRCM_REG32(0x0D0)
-#define GENERAL_PURPOSE10	PRCM_REG32(0x0D4)
-#define GENERAL_PURPOSE11	PRCM_REG32(0x0D8)
-#define GENERAL_PURPOSE12	PRCM_REG32(0x0DC)
-#define GENERAL_PURPOSE13	PRCM_REG32(0x0E0)
-#define GENERAL_PURPOSE14	PRCM_REG32(0x0E4)
-#define GENERAL_PURPOSE15	PRCM_REG32(0x0E8)
-#define GENERAL_PURPOSE16	PRCM_REG32(0x0EC)
-#define GENERAL_PURPOSE17	PRCM_REG32(0x0F0)
-#define GENERAL_PURPOSE18	PRCM_REG32(0x0F4)
-#define GENERAL_PURPOSE19	PRCM_REG32(0x0F8)
-#define GENERAL_PURPOSE20	PRCM_REG32(0x0FC)
-
-/* MPU */
-#define CM_CLKSEL_MPU		PRCM_REG32(0x140)
-#define CM_CLKSTCTRL_MPU	PRCM_REG32(0x148)
-#define RM_RSTST_MPU		PRCM_REG32(0x158)
-#define PM_WKDEP_MPU		PRCM_REG32(0x1C8)
-#define PM_EVGENCTRL_MPU	PRCM_REG32(0x1D4)
-#define PM_EVEGENONTIM_MPU	PRCM_REG32(0x1D8)
-#define PM_EVEGENOFFTIM_MPU	PRCM_REG32(0x1DC)
-#define PM_PWSTCTRL_MPU		PRCM_REG32(0x1E0)
-#define PM_PWSTST_MPU		PRCM_REG32(0x1E4)
-
-/* CORE */
-#define CM_FCLKEN1_CORE		PRCM_REG32(0x200)
-#define CM_FCLKEN2_CORE		PRCM_REG32(0x204)
-#define CM_FCLKEN3_CORE		PRCM_REG32(0x208)
-#define CM_ICLKEN1_CORE		PRCM_REG32(0x210)
-#define CM_ICLKEN2_CORE		PRCM_REG32(0x214)
-#define CM_ICLKEN3_CORE		PRCM_REG32(0x218)
-#define CM_ICLKEN4_CORE		PRCM_REG32(0x21C)
-#define CM_IDLEST1_CORE		PRCM_REG32(0x220)
-#define CM_IDLEST2_CORE		PRCM_REG32(0x224)
-#define CM_IDLEST3_CORE		PRCM_REG32(0x228)
-#define CM_IDLEST4_CORE		PRCM_REG32(0x22C)
-#define CM_AUTOIDLE1_CORE	PRCM_REG32(0x230)
-#define CM_AUTOIDLE2_CORE	PRCM_REG32(0x234)
-#define CM_AUTOIDLE3_CORE	PRCM_REG32(0x238)
-#define CM_AUTOIDLE4_CORE	PRCM_REG32(0x23C)
-#define CM_CLKSEL1_CORE		PRCM_REG32(0x240)
-#define CM_CLKSEL2_CORE		PRCM_REG32(0x244)
-#define CM_CLKSTCTRL_CORE	PRCM_REG32(0x248)
-#define PM_WKEN1_CORE		PRCM_REG32(0x2A0)
-#define PM_WKEN2_CORE		PRCM_REG32(0x2A4)
-#define PM_WKST1_CORE		PRCM_REG32(0x2B0)
-#define PM_WKST2_CORE		PRCM_REG32(0x2B4)
-#define PM_WKDEP_CORE		PRCM_REG32(0x2C8)
-#define PM_PWSTCTRL_CORE	PRCM_REG32(0x2E0)
-#define PM_PWSTST_CORE		PRCM_REG32(0x2E4)
-
-/* GFX */
-#define CM_FCLKEN_GFX		PRCM_REG32(0x300)
-#define CM_ICLKEN_GFX		PRCM_REG32(0x310)
-#define CM_IDLEST_GFX		PRCM_REG32(0x320)
-#define CM_CLKSEL_GFX		PRCM_REG32(0x340)
-#define CM_CLKSTCTRL_GFX	PRCM_REG32(0x348)
-#define RM_RSTCTRL_GFX		PRCM_REG32(0x350)
-#define RM_RSTST_GFX		PRCM_REG32(0x358)
-#define PM_WKDEP_GFX		PRCM_REG32(0x3C8)
-#define PM_PWSTCTRL_GFX		PRCM_REG32(0x3E0)
-#define PM_PWSTST_GFX		PRCM_REG32(0x3E4)
-
-/* WAKE-UP */
-#define CM_FCLKEN_WKUP		PRCM_REG32(0x400)
-#define CM_ICLKEN_WKUP		PRCM_REG32(0x410)
-#define CM_IDLEST_WKUP		PRCM_REG32(0x420)
-#define CM_AUTOIDLE_WKUP	PRCM_REG32(0x430)
-#define CM_CLKSEL_WKUP		PRCM_REG32(0x440)
-#define RM_RSTCTRL_WKUP		PRCM_REG32(0x450)
-#define RM_RSTTIME_WKUP		PRCM_REG32(0x454)
-#define RM_RSTST_WKUP		PRCM_REG32(0x458)
-#define PM_WKEN_WKUP		PRCM_REG32(0x4A0)
-#define PM_WKST_WKUP		PRCM_REG32(0x4B0)
-
-/* CLOCKS */
-#define CM_CLKEN_PLL		PRCM_REG32(0x500)
-#define CM_IDLEST_CKGEN		PRCM_REG32(0x520)
-#define CM_AUTOIDLE_PLL		PRCM_REG32(0x530)
-#define CM_CLKSEL1_PLL		PRCM_REG32(0x540)
-#define CM_CLKSEL2_PLL		PRCM_REG32(0x544)
-
-/* DSP */
-#define CM_FCLKEN_DSP		PRCM_REG32(0x800)
-#define CM_ICLKEN_DSP		PRCM_REG32(0x810)
-#define CM_IDLEST_DSP		PRCM_REG32(0x820)
-#define CM_AUTOIDLE_DSP		PRCM_REG32(0x830)
-#define CM_CLKSEL_DSP		PRCM_REG32(0x840)
-#define CM_CLKSTCTRL_DSP	PRCM_REG32(0x848)
-#define RM_RSTCTRL_DSP		PRCM_REG32(0x850)
-#define RM_RSTST_DSP		PRCM_REG32(0x858)
-#define PM_WKEN_DSP		PRCM_REG32(0x8A0)
-#define PM_WKDEP_DSP		PRCM_REG32(0x8C8)
-#define PM_PWSTCTRL_DSP		PRCM_REG32(0x8E0)
-#define PM_PWSTST_DSP		PRCM_REG32(0x8E4)
-#define PRCM_IRQSTATUS_DSP	PRCM_REG32(0x8F0)
-#define PRCM_IRQENABLE_DSP	PRCM_REG32(0x8F4)
-
-/* IVA */
-#define PRCM_IRQSTATUS_IVA	PRCM_REG32(0x8F8)
-#define PRCM_IRQENABLE_IVA	PRCM_REG32(0x8FC)
-
-/* Modem on 2430 */
-#define CM_FCLKEN_MDM		PRCM_REG32(0xC00)
-#define CM_ICLKEN_MDM		PRCM_REG32(0xC10)
-#define CM_IDLEST_MDM		PRCM_REG32(0xC20)
-#define CM_CLKSEL_MDM		PRCM_REG32(0xC40)
-
-/* FIXME: Move to header for 2430 */
-#define DISP_BASE		(OMAP24XX_L4_IO_BASE+0x50000)
-#define DISP_REG32(offset)	__REG32(DISP_BASE + (offset))
-
-#define OMAP24XX_GPMC_BASE	(L3_24XX_BASE + 0xa000)
-#define GPMC_BASE		(OMAP24XX_GPMC_BASE)
-#define GPMC_REG32(offset)	__REG32(GPMC_BASE + (offset))
-
-#define GPT1_BASE		(OMAP24XX_GPT1)
-#define GPT1_REG32(offset)	__REG32(GPT1_BASE + (offset))
-
-/* Misc sysconfig */
-#define DISPC_SYSCONFIG		DISP_REG32(0x410)
-#define SPI_BASE		(OMAP24XX_L4_IO_BASE+0x98000)
-#define MCSPI1_SYSCONFIG	__REG32(SPI_BASE + 0x10)
-#define MCSPI2_SYSCONFIG	__REG32(SPI_BASE+0x2000 + 0x10)
-
-//#define DSP_MMU_SYSCONFIG	0x5A000010
-#define CAMERA_MMU_SYSCONFIG	__REG32(DISP_BASE+0x2C10)
-//#define IVA_MMU_SYSCONFIG	0x5D000010
-//#define DSP_DMA_SYSCONFIG	0x00FCC02C
-#define CAMERA_DMA_SYSCONFIG	__REG32(DISP_BASE+0x282C)
-#define SYSTEM_DMA_SYSCONFIG	__REG32(DISP_BASE+0x602C)
-#define GPMC_SYSCONFIG		GPMC_REG32(0x010)
-#define MAILBOXES_SYSCONFIG	__REG32(OMAP24XX_L4_IO_BASE+0x94010)
-#define UART1_SYSCONFIG		__REG32(OMAP24XX_L4_IO_BASE+0x6A054)
-#define UART2_SYSCONFIG		__REG32(OMAP24XX_L4_IO_BASE+0x6C054)
-#define UART3_SYSCONFIG		__REG32(OMAP24XX_L4_IO_BASE+0x6E054)
-//#define IVA_SYSCONFIG		0x5C060010
-#define SDRC_SYSCONFIG		__REG32(OMAP24XX_SDRC_BASE+0x10)
-#define SMS_SYSCONFIG		__REG32(OMAP24XX_SMS_BASE+0x10)
-#define SSI_SYSCONFIG		__REG32(DISP_BASE+0x8010)
-//#define VLYNQ_SYSCONFIG	0x67FFFE10
-
-/* rkw - good cannidates for PM_ to start what nm was trying */
-#define OMAP24XX_GPT2		(OMAP24XX_L4_IO_BASE+0x2A000)
-#define OMAP24XX_GPT3		(OMAP24XX_L4_IO_BASE+0x78000)
-#define OMAP24XX_GPT4		(OMAP24XX_L4_IO_BASE+0x7A000)
-#define OMAP24XX_GPT5		(OMAP24XX_L4_IO_BASE+0x7C000)
-#define OMAP24XX_GPT6		(OMAP24XX_L4_IO_BASE+0x7E000)
-#define OMAP24XX_GPT7		(OMAP24XX_L4_IO_BASE+0x80000)
-#define OMAP24XX_GPT8		(OMAP24XX_L4_IO_BASE+0x82000)
-#define OMAP24XX_GPT9		(OMAP24XX_L4_IO_BASE+0x84000)
-#define OMAP24XX_GPT10		(OMAP24XX_L4_IO_BASE+0x86000)
-#define OMAP24XX_GPT11		(OMAP24XX_L4_IO_BASE+0x88000)
-#define OMAP24XX_GPT12		(OMAP24XX_L4_IO_BASE+0x8A000)
-
-#define GPTIMER1_SYSCONFIG	GPT1_REG32(0x010)
-#define GPTIMER2_SYSCONFIG	__REG32(OMAP24XX_GPT2 + 0x10)
-#define GPTIMER3_SYSCONFIG	__REG32(OMAP24XX_GPT3 + 0x10)
-#define GPTIMER4_SYSCONFIG	__REG32(OMAP24XX_GPT4 + 0x10)
-#define GPTIMER5_SYSCONFIG	__REG32(OMAP24XX_GPT5 + 0x10)
-#define GPTIMER6_SYSCONFIG	__REG32(OMAP24XX_GPT6 + 0x10)
-#define GPTIMER7_SYSCONFIG	__REG32(OMAP24XX_GPT7 + 0x10)
-#define GPTIMER8_SYSCONFIG	__REG32(OMAP24XX_GPT8 + 0x10)
-#define GPTIMER9_SYSCONFIG	__REG32(OMAP24XX_GPT9 + 0x10)
-#define GPTIMER10_SYSCONFIG	__REG32(OMAP24XX_GPT10 + 0x10)
-#define GPTIMER11_SYSCONFIG	__REG32(OMAP24XX_GPT11 + 0x10)
-#define GPTIMER12_SYSCONFIG	__REG32(OMAP24XX_GPT12 + 0x10)
-
-#define GPIOX_BASE(X)		(OMAP24XX_GPIO_BASE+(0x2000*((X)-1)))
-
-#define GPIO1_SYSCONFIG		__REG32((GPIOX_BASE(1)+0x10))
-#define GPIO2_SYSCONFIG		__REG32((GPIOX_BASE(2)+0x10))
-#define GPIO3_SYSCONFIG		__REG32((GPIOX_BASE(3)+0x10))
-#define GPIO4_SYSCONFIG		__REG32((GPIOX_BASE(4)+0x10))
-
-/* GP TIMER 1 */
-#define GPTIMER1_TISTAT		GPT1_REG32(0x014)
-#define GPTIMER1_TISR		GPT1_REG32(0x018)
-#define GPTIMER1_TIER		GPT1_REG32(0x01C)
-#define GPTIMER1_TWER		GPT1_REG32(0x020)
-#define GPTIMER1_TCLR		GPT1_REG32(0x024)
-#define GPTIMER1_TCRR		GPT1_REG32(0x028)
-#define GPTIMER1_TLDR		GPT1_REG32(0x02C)
-#define GPTIMER1_TTGR		GPT1_REG32(0x030)
-#define GPTIMER1_TWPS		GPT1_REG32(0x034)
-#define GPTIMER1_TMAR		GPT1_REG32(0x038)
-#define GPTIMER1_TCAR1		GPT1_REG32(0x03C)
-#define GPTIMER1_TSICR		GPT1_REG32(0x040)
-#define GPTIMER1_TCAR2		GPT1_REG32(0x044)
-
-/* rkw -- base fix up please... */
-#define GPTIMER3_TISR		__REG32(OMAP24XX_L4_IO_BASE+0x78018)
-
-/* SDRC */
-#define SDRC_DLLA_CTRL		__REG32(OMAP24XX_SDRC_BASE+0x060)
-#define SDRC_DLLA_STATUS	__REG32(OMAP24XX_SDRC_BASE+0x064)
-#define SDRC_DLLB_CTRL		__REG32(OMAP24XX_SDRC_BASE+0x068)
-#define SDRC_DLLB_STATUS	__REG32(OMAP24XX_SDRC_BASE+0x06C)
-#define SDRC_POWER		__REG32(OMAP24XX_SDRC_BASE+0x070)
-#define SDRC_MR_0		__REG32(OMAP24XX_SDRC_BASE+0x084)
-
-/* GPIO 1 */
-#define GPIO1_BASE		GPIOX_BASE(1)
-#define GPIO1_REG32(offset)	__REG32(GPIO1_BASE + (offset))
-#define GPIO1_IRQENABLE1	GPIO1_REG32(0x01C)
-#define GPIO1_IRQSTATUS1	GPIO1_REG32(0x018)
-#define GPIO1_IRQENABLE2	GPIO1_REG32(0x02C)
-#define GPIO1_IRQSTATUS2	GPIO1_REG32(0x028)
-#define GPIO1_WAKEUPENABLE	GPIO1_REG32(0x020)
-#define GPIO1_RISINGDETECT	GPIO1_REG32(0x048)
-#define GPIO1_DATAIN		GPIO1_REG32(0x038)
-#define GPIO1_OE		GPIO1_REG32(0x034)
-#define GPIO1_DATAOUT		GPIO1_REG32(0x03C)
-
-/* GPIO2 */
-#define GPIO2_BASE		GPIOX_BASE(2)
-#define GPIO2_REG32(offset)	__REG32(GPIO2_BASE + (offset))
-#define GPIO2_IRQENABLE1	GPIO2_REG32(0x01C)
-#define GPIO2_IRQSTATUS1	GPIO2_REG32(0x018)
-#define GPIO2_IRQENABLE2	GPIO2_REG32(0x02C)
-#define GPIO2_IRQSTATUS2	GPIO2_REG32(0x028)
-#define GPIO2_WAKEUPENABLE	GPIO2_REG32(0x020)
-#define GPIO2_RISINGDETECT	GPIO2_REG32(0x048)
-#define GPIO2_DATAIN		GPIO2_REG32(0x038)
-#define GPIO2_OE		GPIO2_REG32(0x034)
-#define GPIO2_DATAOUT		GPIO2_REG32(0x03C)
-
-/* GPIO 3 */
-#define GPIO3_BASE		GPIOX_BASE(3)
-#define GPIO3_REG32(offset)	__REG32(GPIO3_BASE + (offset))
-#define GPIO3_IRQENABLE1	GPIO3_REG32(0x01C)
-#define GPIO3_IRQSTATUS1	GPIO3_REG32(0x018)
-#define GPIO3_IRQENABLE2	GPIO3_REG32(0x02C)
-#define GPIO3_IRQSTATUS2	GPIO3_REG32(0x028)
-#define GPIO3_WAKEUPENABLE	GPIO3_REG32(0x020)
-#define GPIO3_RISINGDETECT	GPIO3_REG32(0x048)
-#define GPIO3_FALLINGDETECT	GPIO3_REG32(0x04C)
-#define GPIO3_DATAIN		GPIO3_REG32(0x038)
-#define GPIO3_OE		GPIO3_REG32(0x034)
-#define GPIO3_DATAOUT		GPIO3_REG32(0x03C)
-#define GPIO3_DEBOUNCENABLE	GPIO3_REG32(0x050)
-#define GPIO3_DEBOUNCINGTIME	GPIO3_REG32(0x054)
-
-/* GPIO 4 */
-#define GPIO4_BASE		GPIOX_BASE(4)
-#define GPIO4_REG32(offset)	__REG32(GPIO4_BASE + (offset))
-#define GPIO4_IRQENABLE1	GPIO4_REG32(0x01C)
-#define GPIO4_IRQSTATUS1	GPIO4_REG32(0x018)
-#define GPIO4_IRQENABLE2	GPIO4_REG32(0x02C)
-#define GPIO4_IRQSTATUS2	GPIO4_REG32(0x028)
-#define GPIO4_WAKEUPENABLE	GPIO4_REG32(0x020)
-#define GPIO4_RISINGDETECT	GPIO4_REG32(0x048)
-#define GPIO4_FALLINGDETECT	GPIO4_REG32(0x04C)
-#define GPIO4_DATAIN		GPIO4_REG32(0x038)
-#define GPIO4_OE		GPIO4_REG32(0x034)
-#define GPIO4_DATAOUT		GPIO4_REG32(0x03C)
-#define GPIO4_DEBOUNCENABLE	GPIO4_REG32(0x050)
-#define GPIO4_DEBOUNCINGTIME	GPIO4_REG32(0x054)
-
-
-/* IO CONFIG */
-#define CONTROL_BASE		(OMAP24XX_CTRL_BASE)
-#define CONTROL_REG32(offset)	__REG32(CONTROL_BASE + (offset))
-
-#define CONTROL_PADCONF_SPI1_NCS2	CONTROL_REG32(0x104)
-#define CONTROL_PADCONF_SYS_XTALOUT	CONTROL_REG32(0x134)
-#define CONTROL_PADCONF_UART1_RX	CONTROL_REG32(0x0C8)
-#define CONTROL_PADCONF_MCBSP1_DX	CONTROL_REG32(0x10C)
-#define CONTROL_PADCONF_GPMC_NCS4	CONTROL_REG32(0x090)
-#define CONTROL_PADCONF_DSS_D5		CONTROL_REG32(0x0B8)
-#define CONTROL_PADCONF_DSS_D9		CONTROL_REG32(0x0BC)
-#define CONTROL_PADCONF_DSS_D13		CONTROL_REG32(0x0C0)
-#define CONTROL_PADCONF_DSS_VSYNC	CONTROL_REG32(0x0CC)
-
-/* CONTROL */
-#define CONTROL_DEVCONF		CONTROL_REG32(0x274)
-
-/* INTERRUPT CONTROLLER */
-#define INTC_BASE		(OMAP24XX_L4_IO_BASE+0xfe000)
-#define INTC_REG32(offset)	__REG32(INTC_BASE + (offset))
-
-#define INTC1_U_BASE		INTC_REG32(0x000)
-#define INTC_MIR0		INTC_REG32(0x084)
-#define INTC_MIR_SET0		INTC_REG32(0x08C)
-#define INTC_MIR_CLEAR0		INTC_REG32(0x088)
-#define INTC_ISR_CLEAR0		INTC_REG32(0x094)
-#define INTC_MIR1		INTC_REG32(0x0A4)
-#define INTC_MIR_SET1		INTC_REG32(0x0AC)
-#define INTC_MIR_CLEAR1		INTC_REG32(0x0A8)
-#define INTC_ISR_CLEAR1		INTC_REG32(0x0B4)
-#define INTC_MIR2		INTC_REG32(0x0C4)
-#define INTC_MIR_SET2		INTC_REG32(0x0CC)
-#define INTC_MIR_CLEAR2		INTC_REG32(0x0C8)
-#define INTC_ISR_CLEAR2		INTC_REG32(0x0D4)
-#define INTC_SIR_IRQ		INTC_REG32(0x040)
-#define INTC_CONTROL		INTC_REG32(0x048)
-#define INTC_ILR11		INTC_REG32(0x12C)
-#define INTC_ILR32		INTC_REG32(0x180)
-#define INTC_ILR37		INTC_REG32(0x194)
-#define INTC_SYSCONFIG		INTC_REG32(0x010)
-
-/* RAM FIREWALL */
-#define RAMFW_BASE		(0x68005000)
-#define RAMFW_REG32(offset)	__REG32(RAMFW_BASE + (offset))
-
-#define RAMFW_REQINFOPERM0	RAMFW_REG32(0x048)
-#define RAMFW_READPERM0		RAMFW_REG32(0x050)
-#define RAMFW_WRITEPERM0	RAMFW_REG32(0x058)
-
-/* GPMC CS1 FPGA ON USER INTERFACE MODULE */
-//#define DEBUG_BOARD_LED_REGISTER 0x04000014
-
-/* GPMC CS0 */
-#define GPMC_CONFIG1_0		GPMC_REG32(0x060)
-#define GPMC_CONFIG2_0		GPMC_REG32(0x064)
-#define GPMC_CONFIG3_0		GPMC_REG32(0x068)
-#define GPMC_CONFIG4_0		GPMC_REG32(0x06C)
-#define GPMC_CONFIG5_0		GPMC_REG32(0x070)
-#define GPMC_CONFIG6_0		GPMC_REG32(0x074)
-#define GPMC_CONFIG7_0		GPMC_REG32(0x078)
-
-/* GPMC CS1 */
-#define GPMC_CONFIG1_1		GPMC_REG32(0x090)
-#define GPMC_CONFIG2_1		GPMC_REG32(0x094)
-#define GPMC_CONFIG3_1		GPMC_REG32(0x098)
-#define GPMC_CONFIG4_1		GPMC_REG32(0x09C)
-#define GPMC_CONFIG5_1		GPMC_REG32(0x0a0)
-#define GPMC_CONFIG6_1		GPMC_REG32(0x0a4)
-#define GPMC_CONFIG7_1		GPMC_REG32(0x0a8)
-
-/* DSS */
-#define DSS_CONTROL		DISP_REG32(0x040)
-#define DISPC_CONTROL		DISP_REG32(0x440)
-#define DISPC_SYSSTATUS		DISP_REG32(0x414)
-#define DISPC_IRQSTATUS		DISP_REG32(0x418)
-#define DISPC_IRQENABLE		DISP_REG32(0x41C)
-#define DISPC_CONFIG		DISP_REG32(0x444)
-#define DISPC_DEFAULT_COLOR0	DISP_REG32(0x44C)
-#define DISPC_DEFAULT_COLOR1	DISP_REG32(0x450)
-#define DISPC_TRANS_COLOR0	DISP_REG32(0x454)
-#define DISPC_TRANS_COLOR1	DISP_REG32(0x458)
-#define DISPC_LINE_NUMBER	DISP_REG32(0x460)
-#define DISPC_TIMING_H		DISP_REG32(0x464)
-#define DISPC_TIMING_V		DISP_REG32(0x468)
-#define DISPC_POL_FREQ		DISP_REG32(0x46C)
-#define DISPC_DIVISOR		DISP_REG32(0x470)
-#define DISPC_SIZE_DIG		DISP_REG32(0x478)
-#define DISPC_SIZE_LCD		DISP_REG32(0x47C)
-#define DISPC_GFX_BA0		DISP_REG32(0x480)
-#define DISPC_GFX_BA1		DISP_REG32(0x484)
-#define DISPC_GFX_POSITION	DISP_REG32(0x488)
-#define DISPC_GFX_SIZE		DISP_REG32(0x48C)
-#define DISPC_GFX_ATTRIBUTES	DISP_REG32(0x4A0)
-#define DISPC_GFX_FIFO_THRESHOLD	DISP_REG32(0x4A4)
-#define DISPC_GFX_ROW_INC	DISP_REG32(0x4AC)
-#define DISPC_GFX_PIXEL_INC	DISP_REG32(0x4B0)
-#define DISPC_GFX_WINDOW_SKIP	DISP_REG32(0x4B4)
-#define DISPC_GFX_TABLE_BA	DISP_REG32(0x4B8)
-#define DISPC_DATA_CYCLE1	DISP_REG32(0x5D4)
-#define DISPC_DATA_CYCLE2	DISP_REG32(0x5D8)
-#define DISPC_DATA_CYCLE3	DISP_REG32(0x5DC)
-
-/* Wake up define for board */
-#define GPIO97			(1 << 1)
-#define GPIO88			(1 << 24)
-
-#endif /* __ASSEMBLER__ */
+u32 omap_prcm_get_reset_sources(void);
 
 #endif
 
diff --git a/include/asm-arm/arch-omap/sram.h b/include/asm-arm/arch-omap/sram.h
index e72ccbf..6fc0dd5 100644
--- a/include/asm-arm/arch-omap/sram.h
+++ b/include/asm-arm/arch-omap/sram.h
@@ -20,6 +20,8 @@
 				      u32 mem_type);
 extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
 
+extern unsigned long omap_fb_sram_start;
+extern unsigned long omap_fb_sram_size;
 
 /* Do not use these */
 extern void sram_reprogram_clock(u32 ckctl, u32 dpllctl);
diff --git a/include/asm-arm/arch-omap/system.h b/include/asm-arm/arch-omap/system.h
index 6724a81..67970d1 100644
--- a/include/asm-arm/arch-omap/system.h
+++ b/include/asm-arm/arch-omap/system.h
@@ -9,12 +9,13 @@
 
 #include <asm/mach-types.h>
 #include <asm/hardware.h>
-#include <asm/arch/prcm.h>
 
 #ifndef CONFIG_MACH_VOICEBLUE
 #define voiceblue_reset()		do {} while (0)
 #endif
 
+extern void omap_prcm_arch_reset(char mode);
+
 static inline void arch_idle(void)
 {
 	cpu_do_idle();
@@ -38,24 +39,12 @@
 		omap_writew(1, ARM_RSTCT1);
 }
 
-static inline void omap2_arch_reset(char mode)
-{
-	u32 rate;
-	struct clk *vclk, *sclk;
-
-	vclk = clk_get(NULL, "virt_prcm_set");
-	sclk = clk_get(NULL, "sys_ck");
-	rate = clk_get_rate(sclk);
-	clk_set_rate(vclk, rate);	/* go to bypass for OMAP limitation */
-	RM_RSTCTRL_WKUP |= 2;
-}
-
 static inline void arch_reset(char mode)
 {
 	if (!cpu_is_omap24xx())
 		omap1_arch_reset(mode);
 	else
-		omap2_arch_reset(mode);
+		omap_prcm_arch_reset(mode);
 }
 
 #endif
diff --git a/include/asm-arm/arch-s3c2410/entry-macro.S b/include/asm-arm/arch-s3c2410/entry-macro.S
index cc06b1b..894c35c 100644
--- a/include/asm-arm/arch-s3c2410/entry-macro.S
+++ b/include/asm-arm/arch-s3c2410/entry-macro.S
@@ -6,116 +6,83 @@
  * This file is licensed under  the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
+*/
 
- * Modifications:
- *     10-Mar-2005 LCVR  Changed S3C2410_VA to S3C24XX_VA
- */
+/* We have a problem that the INTOFFSET register does not always
+ * show one interrupt. Occasionally we get two interrupts through
+ * the prioritiser, and this causes the INTOFFSET register to show
+ * what looks like the logical-or of the two interrupt numbers.
+ *
+ * Thanks to Klaus, Shannon, et al for helping to debug this problem
+*/
+
+#define INTPND		(0x10)
+#define INTOFFSET	(0x14)
+#define EXTINTPEND	(0xa8)
+#define EXTINTMASK	(0xa4)
+
 #include <asm/hardware.h>
 #include <asm/arch/irqs.h>
 
-
 	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
 
-		mov	\tmp, #S3C24XX_VA_IRQ
-		ldr	\irqnr, [ \tmp, #0x14 ]		@ get irq no
-30000:
-		teq	\irqnr, #4
-		teqne	\irqnr, #5
-		beq	1002f				@ external irq reg
+		mov	\base, #S3C24XX_VA_IRQ
 
-		@ debug check to see if interrupt reported is the same
-		@ as the offset....
+		ldr	\irqstat, [ \base, #INTPND]
+		bics	\irqnr, \irqstat, #3<<4		@@ only an GPIO IRQ
+		beq	2000f
 
-		teq	\irqnr, #0
-		beq	20002f
-		ldr	\irqstat, [ \tmp, #0x10 ]	@ INTPND
-		mov	\irqstat, \irqstat, lsr \irqnr
-		tst	\irqstat, #1
-		bne	20002f
+		@@ try the interrupt offset register, since it is there
 
-		/* debug/warning if we get an invalud response from the
-		 * INTOFFSET register */
-#if 1
-		stmfd	r13!, { r0 - r4 , r8-r12, r14 }
-		ldr	r1,	[ \tmp, #0x14 ]		@ INTOFFSET
-		ldr	r2,	[ \tmp, #0x10 ]		@ INTPND
-		ldr	r3,	[ \tmp, #0x00 ]		@ SRCPND
-		adr	r0, 20003f
-		bl	printk
-		b	20004f
+		ldr	\irqnr, [ \base, #INTOFFSET ]
+		mov	\tmp, #1
+		tst	\irqstat, \tmp, lsl \irqnr
+		addne	\irqnr, \irqnr, #IRQ_EINT0
+		bne	1001f
 
-20003:
-		.ascii	"<7>irq: err - bad offset %d, intpnd=%08x, srcpnd=%08x\n"
-		.byte	0
-		.align	4
-20004:
-		mov	r1, #1
-		mov	\tmp, #S3C24XX_VA_IRQ
-		ldmfd	r13!, { r0 - r4 , r8-r12, r14 }
-#endif
+		@@ the number specified is not a valid irq, so try
+		@@ and work it out for ourselves
 
-		@ try working out interrupt number for ourselves
-		mov	\irqnr, #0
-		ldr	\irqstat, [ \tmp, #0x10 ]	@ INTPND
-10021:
-		movs	\irqstat, \irqstat, lsr#1
-		bcs	30000b		@ try and re-start the proccess
-		add	\irqnr, \irqnr, #1
-		cmp	\irqnr, #32
-		ble	10021b
+		mov	\irqnr, #IRQ_EINT0		@@ start here
+		b	3000f
 
-		@ found no interrupt, set Z flag and leave
-		movs	\irqnr, #0
-		b	1001f
+2000:
+		@@ load the GPIO interrupt register, and check it
 
-20005:
-20002:		@ exit
-		@ we base the s3c2410x interrupts at 16 and above to allow
-		@ isa peripherals to have their standard interrupts, also
-		@ ensure that Z flag is un-set on exit
+		add	\tmp, \base, #S3C24XX_VA_GPIO - S3C24XX_VA_IRQ
+		ldr	\irqstat, [ \tmp, # EXTINTPEND ]
+		ldr	\irqnr,   [ \tmp, # EXTINTMASK ]
+		bics	\irqstat, \irqstat, \irqnr
+		beq	1001f
 
-		@ note, we cannot be sure if we get IRQ_EINT0 (0) that
-		@ there is simply no interrupt pending, so in all other
-		@ cases we jump to say we have found something, otherwise
-		@ we check to see if the interrupt really is assrted
-		adds	\irqnr, \irqnr, #IRQ_EINT0
-		teq	\irqnr, #IRQ_EINT0
-		bne	1001f				@ exit
-		ldr	\irqstat, [ \tmp, #0x10 ]	@ INTPND
-		teq	\irqstat, #0
-		moveq	\irqnr, #0
-		b	1001f
+		mov	\irqnr, #(IRQ_EINT4 - 4)
 
-		@ we get here from no main or external interrupts pending
-1002:
-		add	\tmp, \tmp, #S3C24XX_VA_GPIO - S3C24XX_VA_IRQ
-		ldr	\irqstat, [ \tmp, # 0xa8 ]	@ EXTINTPEND
-		ldr	\irqnr, [ \tmp, # 0xa4 ]	@ EXTINTMASK
+		@@ work out which irq (if any) we got
+3000:
+		movs	\tmp, \irqstat, lsl#16
+		addeq	\irqnr, \irqnr, #16
+		moveq	\irqstat, \irqstat, lsr#16
+		tst	\irqstat, #0xff
+		addeq	\irqnr, \irqnr, #8
+		moveq	\irqstat, \irqstat, lsr#8
+		tst	\irqstat, #0xf
+		addeq	\irqnr, \irqnr, #4
+		moveq	\irqstat, \irqstat, lsr#4
+		tst	\irqstat, #0x3
+		addeq	\irqnr, \irqnr, #2
+		moveq	\irqstat, \irqstat, lsr#2
+		tst	\irqstat, #0x1
+		addeq	\irqnr, \irqnr, #1
 
-		bic	\irqstat, \irqstat, \irqnr	@ clear masked irqs
+		@@ we have the value
+		movs	\irqnr, \irqnr
 
-		mov	\irqnr, #IRQ_EINT4		@ start extint nos
-		mov	\irqstat, \irqstat, lsr#4	@ ignore bottom 4 bits
-10021:
-		movs	\irqstat, \irqstat, lsr#1
-		bcs	1004f
-		add	\irqnr, \irqnr, #1
-		cmp	\irqnr, #IRQ_EINT23
-		ble	10021b
-
-		@ found no interrupt, set Z flag and leave
-		movs	\irqnr, #0
-
-1004:		@ ensure Z flag clear in case our MOVS shifted out the last bit
-		teq	\irqnr, #0
 1001:
-		@ exit irq routine
-		.endm
+		@@ exit here, Z flag unset if IRQ
 
+	.endm
 
 		/* currently don't need an disable_fiq macro */
 
 		.macro	disable_fiq
 		.endm
-
-
diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h
index e3e8541..63ca741 100644
--- a/include/asm-arm/dma-mapping.h
+++ b/include/asm-arm/dma-mapping.h
@@ -47,7 +47,7 @@
 
 static inline int dma_is_consistent(dma_addr_t handle)
 {
-	return 0;
+	return !!arch_is_coherent();
 }
 
 /*
@@ -145,7 +145,9 @@
 dma_map_single(struct device *dev, void *cpu_addr, size_t size,
 	       enum dma_data_direction dir)
 {
-	consistent_sync(cpu_addr, size, dir);
+	if (!arch_is_coherent())
+		consistent_sync(cpu_addr, size, dir);
+
 	return virt_to_dma(dev, (unsigned long)cpu_addr);
 }
 #else
@@ -255,7 +257,9 @@
 
 		sg->dma_address = page_to_dma(dev, sg->page) + sg->offset;
 		virt = page_address(sg->page) + sg->offset;
-		consistent_sync(virt, sg->length, dir);
+
+		if (!arch_is_coherent())
+			consistent_sync(virt, sg->length, dir);
 	}
 
 	return nents;
@@ -310,14 +314,16 @@
 dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size,
 			enum dma_data_direction dir)
 {
-	consistent_sync((void *)dma_to_virt(dev, handle), size, dir);
+	if (!arch_is_coherent())
+		consistent_sync((void *)dma_to_virt(dev, handle), size, dir);
 }
 
 static inline void
 dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size,
 			   enum dma_data_direction dir)
 {
-	consistent_sync((void *)dma_to_virt(dev, handle), size, dir);
+	if (!arch_is_coherent())
+		consistent_sync((void *)dma_to_virt(dev, handle), size, dir);
 }
 #else
 extern void dma_sync_single_for_cpu(struct device*, dma_addr_t, size_t, enum dma_data_direction);
@@ -347,7 +353,8 @@
 
 	for (i = 0; i < nents; i++, sg++) {
 		char *virt = page_address(sg->page) + sg->offset;
-		consistent_sync(virt, sg->length, dir);
+		if (!arch_is_coherent())
+			consistent_sync(virt, sg->length, dir);
 	}
 }
 
@@ -359,7 +366,8 @@
 
 	for (i = 0; i < nents; i++, sg++) {
 		char *virt = page_address(sg->page) + sg->offset;
-		consistent_sync(virt, sg->length, dir);
+		if (!arch_is_coherent())
+			consistent_sync(virt, sg->length, dir);
 	}
 }
 #else
diff --git a/include/asm-arm/memory.h b/include/asm-arm/memory.h
index afa5c3e..2b3cf69 100644
--- a/include/asm-arm/memory.h
+++ b/include/asm-arm/memory.h
@@ -234,6 +234,14 @@
 #define virt_to_dma(dev, addr)		(__arch_virt_to_dma(dev, addr))
 #endif
 
+/*
+ * Optional coherency support.  Currently used only by selected
+ * Intel XSC3-based systems.
+ */
+#ifndef arch_is_coherent
+#define arch_is_coherent()		0
+#endif
+
 #endif
 
 #include <asm-generic/memory_model.h>
diff --git a/include/asm-arm/pgtable-hwdef.h b/include/asm-arm/pgtable-hwdef.h
index 1d03349..1bc1f99 100644
--- a/include/asm-arm/pgtable-hwdef.h
+++ b/include/asm-arm/pgtable-hwdef.h
@@ -73,6 +73,7 @@
 #define PTE_EXT_AP_URW_SRW	(PTE_EXT_AP1|PTE_EXT_AP0)
 #define PTE_EXT_TEX(x)		((x) << 6)	/* v5 */
 #define PTE_EXT_APX		(1 << 9)	/* v6 */
+#define PTE_EXT_COHERENT	(1 << 9)	/* XScale3 */
 #define PTE_EXT_SHARED		(1 << 10)	/* v6 */
 #define PTE_EXT_NG		(1 << 11)	/* v6 */
 
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
index e595ae2..e85c08d 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -156,6 +156,7 @@
 #define L_PTE_WRITE		(1 << 5)
 #define L_PTE_EXEC		(1 << 6)
 #define L_PTE_DIRTY		(1 << 7)
+#define L_PTE_COHERENT		(1 << 9)	/* I/O coherent (xsc3) */
 #define L_PTE_SHARED		(1 << 10)	/* shared between CPUs (v6) */
 #define L_PTE_ASID		(1 << 11)	/* non-global (use ASID, v6) */