Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
new file mode 100644
index 0000000..405a55f
--- /dev/null
+++ b/arch/arm/mach-pxa/Kconfig
@@ -0,0 +1,77 @@
+if ARCH_PXA
+
+menu "Intel PXA2xx Implementations"
+
+choice
+	prompt "Select target board"
+
+config ARCH_LUBBOCK
+	bool "Intel DBPXA250 Development Platform"
+	select PXA25x
+	select SA1111
+
+config MACH_MAINSTONE
+	bool "Intel HCDDBBVA0 Development Platform"
+	select PXA27x
+	select IWMMXT
+
+config ARCH_PXA_IDP
+	bool "Accelent Xscale IDP"
+	select PXA25x
+
+config PXA_SHARPSL
+	bool "SHARP SL-5600 and SL-C7xx Models"
+	select PXA25x
+	select SHARP_SCOOP
+	select SHARP_PARAM
+	help
+	  Say Y here if you intend to run this kernel on a
+	  Sharp SL-5600 (Poodle), Sharp SL-C700 (Corgi),
+	  SL-C750 (Shepherd) or a Sharp SL-C760 (Husky)
+	  handheld computer.
+
+endchoice
+
+endmenu
+
+config MACH_POODLE
+	bool "Enable Sharp SL-5600 (Poodle) Support"
+	depends PXA_SHARPSL
+	select SHARP_LOCOMO
+
+config MACH_CORGI
+	bool "Enable Sharp SL-C700 (Corgi) Support"
+	depends PXA_SHARPSL
+	select PXA_SHARP_C7xx
+
+config MACH_SHEPHERD
+	bool "Enable Sharp SL-C750 (Shepherd) Support"
+	depends PXA_SHARPSL
+	select PXA_SHARP_C7xx
+
+config MACH_HUSKY
+	bool "Enable Sharp SL-C760 (Husky) Support"
+	depends PXA_SHARPSL
+	select PXA_SHARP_C7xx
+
+config PXA25x
+	bool
+	help
+	  Select code specific to PXA21x/25x/26x variants
+
+config PXA27x
+	bool
+	help
+	  Select code specific to PXA27x variants
+
+config IWMMXT
+	bool
+	help
+	  Enable support for iWMMXt
+
+config PXA_SHARP_C7xx
+	bool
+	help
+	  Enable support for all Sharp C7xx models
+
+endif
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
new file mode 100644
index 0000000..c4e6d25
--- /dev/null
+++ b/arch/arm/mach-pxa/Makefile
@@ -0,0 +1,26 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support (must be linked before board specific support)
+obj-y += generic.o irq.o dma.o time.o
+obj-$(CONFIG_PXA25x) += pxa25x.o
+obj-$(CONFIG_PXA27x) += pxa27x.o
+
+# Specific board support
+obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
+obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
+obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
+obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.o corgi_ssp.o ssp.o
+obj-$(CONFIG_MACH_POODLE)	+= poodle.o
+
+# Support for blinky lights
+led-y := leds.o
+led-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o
+led-$(CONFIG_MACH_MAINSTONE) += leds-mainstone.o
+led-$(CONFIG_ARCH_PXA_IDP) += leds-idp.o
+
+obj-$(CONFIG_LEDS) += $(led-y)
+
+# Misc features
+obj-$(CONFIG_PM) += pm.o sleep.o
diff --git a/arch/arm/mach-pxa/Makefile.boot b/arch/arm/mach-pxa/Makefile.boot
new file mode 100644
index 0000000..1ead671
--- /dev/null
+++ b/arch/arm/mach-pxa/Makefile.boot
@@ -0,0 +1,2 @@
+   zreladdr-y	:= 0xa0008000
+
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
new file mode 100644
index 0000000..f691cf7
--- /dev/null
+++ b/arch/arm/mach-pxa/corgi.c
@@ -0,0 +1,320 @@
+/*
+ * Support for Sharp SL-C7xx PDAs
+ * Models: SL-C700 (Corgi), SL-C750 (Shepherd), SL-C760 (Husky)
+ *
+ * Copyright (c) 2004-2005 Richard Purdie
+ *
+ * Based on Sharp's 2.4 kernel patches/lubbock.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/device.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/mmc/host.h>
+
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/irq.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/udc.h>
+#include <asm/arch/corgi.h>
+
+#include <asm/mach/sharpsl_param.h>
+#include <asm/hardware/scoop.h>
+#include <video/w100fb.h>
+
+#include "generic.h"
+
+
+/*
+ * Corgi SCOOP Device
+ */
+static struct resource corgi_scoop_resources[] = {
+	[0] = {
+		.start		= 0x10800000,
+		.end		= 0x10800fff,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct scoop_config corgi_scoop_setup = {
+	.io_dir 	= CORGI_SCOOP_IO_DIR,
+	.io_out		= CORGI_SCOOP_IO_OUT,
+};
+
+struct platform_device corgiscoop_device = {
+	.name		= "sharp-scoop",
+	.id		= -1,
+	.dev		= {
+ 		.platform_data	= &corgi_scoop_setup,
+	},
+	.num_resources	= ARRAY_SIZE(corgi_scoop_resources),
+	.resource	= corgi_scoop_resources,
+};
+
+
+/*
+ * Corgi SSP Device
+ *
+ * Set the parent as the scoop device because a lot of SSP devices
+ * also use scoop functions and this makes the power up/down order
+ * work correctly.
+ */
+static struct platform_device corgissp_device = {
+	.name		= "corgi-ssp",
+	.dev		= {
+ 		.parent = &corgiscoop_device.dev,
+	},
+	.id		= -1,
+};
+
+
+/*
+ * Corgi w100 Frame Buffer Device
+ */
+static struct w100fb_mach_info corgi_fb_info = {
+	.w100fb_ssp_send 	= corgi_ssp_lcdtg_send,
+	.comadj 			= -1,
+	.phadadj 			= -1,
+};
+
+static struct resource corgi_fb_resources[] = {
+	[0] = {
+		.start		= 0x08000000,
+		.end		= 0x08ffffff,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device corgifb_device = {
+	.name		= "w100fb",
+	.id		= -1,
+	.dev		= {
+ 		.platform_data	= &corgi_fb_info,
+ 		.parent = &corgissp_device.dev,
+	},
+	.num_resources	= ARRAY_SIZE(corgi_fb_resources),
+	.resource	= corgi_fb_resources,
+};
+
+
+/*
+ * Corgi Backlight Device
+ */
+static struct platform_device corgibl_device = {
+	.name		= "corgi-bl",
+	.dev		= {
+ 		.parent = &corgifb_device.dev,
+	},
+	.id		= -1,
+};
+
+
+/*
+ * MMC/SD Device
+ *
+ * The card detect interrupt isn't debounced so we delay it by HZ/4
+ * to give the card a chance to fully insert/eject.
+ */
+static struct mmc_detect {
+	struct timer_list detect_timer;
+	void *devid;
+} mmc_detect;
+
+static void mmc_detect_callback(unsigned long data)
+{
+	mmc_detect_change(mmc_detect.devid);
+}
+
+static irqreturn_t corgi_mmc_detect_int(int irq, void *devid, struct pt_regs *regs)
+{
+	mmc_detect.devid=devid;
+	mod_timer(&mmc_detect.detect_timer, jiffies + HZ/4);
+	return IRQ_HANDLED;
+}
+
+static int corgi_mci_init(struct device *dev, irqreturn_t (*unused_detect_int)(int, void *, struct pt_regs *), void *data)
+{
+	int err;
+
+	/* setup GPIO for PXA25x MMC controller	*/
+	pxa_gpio_mode(GPIO6_MMCCLK_MD);
+	pxa_gpio_mode(GPIO8_MMCCS0_MD);
+	pxa_gpio_mode(CORGI_GPIO_nSD_DETECT | GPIO_IN);
+	pxa_gpio_mode(CORGI_GPIO_SD_PWR | GPIO_OUT);
+
+	init_timer(&mmc_detect.detect_timer);
+	mmc_detect.detect_timer.function = mmc_detect_callback;
+	mmc_detect.detect_timer.data = (unsigned long) &mmc_detect;
+
+	err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_mmc_detect_int, SA_INTERRUPT,
+			     "MMC card detect", data);
+	if (err) {
+		printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
+		return -1;
+	}
+
+	set_irq_type(CORGI_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
+
+	return 0;
+}
+
+static void corgi_mci_setpower(struct device *dev, unsigned int vdd)
+{
+	struct pxamci_platform_data* p_d = dev->platform_data;
+
+	if (( 1 << vdd) & p_d->ocr_mask) {
+		printk(KERN_DEBUG "%s: on\n", __FUNCTION__);
+		GPSR1 = GPIO_bit(CORGI_GPIO_SD_PWR);
+	} else {
+		printk(KERN_DEBUG "%s: off\n", __FUNCTION__);
+		GPCR1 = GPIO_bit(CORGI_GPIO_SD_PWR);
+	}
+}
+
+static void corgi_mci_exit(struct device *dev, void *data)
+{
+	free_irq(CORGI_IRQ_GPIO_nSD_DETECT, data);
+	del_timer(&mmc_detect.detect_timer);
+}
+
+static struct pxamci_platform_data corgi_mci_platform_data = {
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init 		= corgi_mci_init,
+	.setpower 	= corgi_mci_setpower,
+	.exit		= corgi_mci_exit,
+};
+
+
+/*
+ * USB Device Controller
+ */
+static void corgi_udc_command(int cmd)
+{
+	switch(cmd)	{
+	case PXA2XX_UDC_CMD_CONNECT:
+		GPSR(CORGI_GPIO_USB_PULLUP) = GPIO_bit(CORGI_GPIO_USB_PULLUP);
+		break;
+	case PXA2XX_UDC_CMD_DISCONNECT:
+		GPCR(CORGI_GPIO_USB_PULLUP) = GPIO_bit(CORGI_GPIO_USB_PULLUP);
+		break;
+	}
+}
+
+static struct pxa2xx_udc_mach_info udc_info __initdata = {
+	/* no connect GPIO; corgi can't tell connection status */
+	.udc_command		= corgi_udc_command,
+};
+
+
+static struct platform_device *devices[] __initdata = {
+	&corgiscoop_device,
+	&corgissp_device,
+	&corgifb_device,
+	&corgibl_device,
+};
+
+static void __init corgi_init(void)
+{
+	corgi_fb_info.comadj=sharpsl_param.comadj;
+	corgi_fb_info.phadadj=sharpsl_param.phadadj;
+
+	pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT);
+ 	pxa_set_udc_info(&udc_info);
+	pxa_set_mci_info(&corgi_mci_platform_data);
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init fixup_corgi(struct machine_desc *desc,
+		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;
+	if (machine_is_corgi())
+		mi->bank[0].size = (32*1024*1024);
+	else
+		mi->bank[0].size = (64*1024*1024);
+}
+
+static void __init corgi_init_irq(void)
+{
+	pxa_init_irq();
+}
+
+static struct map_desc corgi_io_desc[] __initdata = {
+/*    virtual     physical    length      */
+/*	{ 0xf1000000, 0x08000000, 0x01000000, MT_DEVICE },*/ /* LCDC (readable for Qt driver) */
+/*	{ 0xef700000, 0x10800000, 0x00001000, MT_DEVICE },*/  /* SCOOP */
+	{ 0xef800000, 0x00000000, 0x00800000, MT_DEVICE }, /* Boot Flash */
+};
+
+static void __init corgi_map_io(void)
+{
+	pxa_map_io();
+	iotable_init(corgi_io_desc,ARRAY_SIZE(corgi_io_desc));
+
+	/* setup sleep mode values */
+	PWER  = 0x00000002;
+	PFER  = 0x00000000;
+	PRER  = 0x00000002;
+	PGSR0 = 0x0158C000;
+	PGSR1 = 0x00FF0080;
+	PGSR2 = 0x0001C004;
+	/* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
+	PCFR |= PCFR_OPDE;
+}
+
+#ifdef CONFIG_MACH_CORGI
+MACHINE_START(CORGI, "SHARP Corgi")
+	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
+	FIXUP(fixup_corgi)
+	MAPIO(corgi_map_io)
+	INITIRQ(corgi_init_irq)
+	.init_machine = corgi_init,
+	.timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_SHEPHERD
+MACHINE_START(SHEPHERD, "SHARP Shepherd")
+	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
+	FIXUP(fixup_corgi)
+	MAPIO(corgi_map_io)
+	INITIRQ(corgi_init_irq)
+	.init_machine = corgi_init,
+	.timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_HUSKY
+MACHINE_START(HUSKY, "SHARP Husky")
+	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
+	FIXUP(fixup_corgi)
+	MAPIO(corgi_map_io)
+	INITIRQ(corgi_init_irq)
+	.init_machine = corgi_init,
+	.timer = &pxa_timer,
+MACHINE_END
+#endif
+
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
new file mode 100644
index 0000000..8ccffba
--- /dev/null
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -0,0 +1,248 @@
+/*
+ *  SSP control code for Sharp Corgi devices
+ *
+ *  Copyright (c) 2004 Richard Purdie
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/ssp.h>
+#include <asm/arch/corgi.h>
+#include <asm/arch/pxa-regs.h>
+
+static spinlock_t corgi_ssp_lock = SPIN_LOCK_UNLOCKED;
+static struct ssp_dev corgi_ssp_dev;
+static struct ssp_state corgi_ssp_state;
+
+/*
+ * There are three devices connected to the SSP interface:
+ *   1. A touchscreen controller (TI ADS7846 compatible)
+ *   2. An LCD contoller (with some Backlight functionality)
+ *   3. A battery moinitoring IC (Maxim MAX1111)
+ *
+ * Each device uses a different speed/mode of communication.
+ *
+ * The touchscreen is very sensitive and the most frequently used
+ * so the port is left configured for this.
+ *
+ * Devices are selected using Chip Selects on GPIOs.
+ */
+
+/*
+ *  ADS7846 Routines
+ */
+unsigned long corgi_ssp_ads7846_putget(ulong data)
+{
+	unsigned long ret,flag;
+
+	spin_lock_irqsave(&corgi_ssp_lock, flag);
+	GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+
+	ssp_write_word(&corgi_ssp_dev,data);
+	ret = ssp_read_word(&corgi_ssp_dev);
+
+	GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
+
+	return ret;
+}
+
+/*
+ * NOTE: These functions should always be called in interrupt context
+ * and use the _lock and _unlock functions. They are very time sensitive.
+ */
+void corgi_ssp_ads7846_lock(void)
+{
+	spin_lock(&corgi_ssp_lock);
+	GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+}
+
+void corgi_ssp_ads7846_unlock(void)
+{
+	GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+	spin_unlock(&corgi_ssp_lock);
+}
+
+void corgi_ssp_ads7846_put(ulong data)
+{
+	ssp_write_word(&corgi_ssp_dev,data);
+}
+
+unsigned long corgi_ssp_ads7846_get(void)
+{
+	return ssp_read_word(&corgi_ssp_dev);
+}
+
+EXPORT_SYMBOL(corgi_ssp_ads7846_putget);
+EXPORT_SYMBOL(corgi_ssp_ads7846_lock);
+EXPORT_SYMBOL(corgi_ssp_ads7846_unlock);
+EXPORT_SYMBOL(corgi_ssp_ads7846_put);
+EXPORT_SYMBOL(corgi_ssp_ads7846_get);
+
+
+/*
+ *  LCD/Backlight Routines
+ */
+unsigned long corgi_ssp_dac_put(ulong data)
+{
+	unsigned long flag;
+
+	spin_lock_irqsave(&corgi_ssp_lock, flag);
+	GPCR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);
+
+	ssp_disable(&corgi_ssp_dev);
+	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), SSCR1_SPH, 0, SSCR0_SerClkDiv(76));
+	ssp_enable(&corgi_ssp_dev);
+
+	ssp_write_word(&corgi_ssp_dev,data);
+	/* Read null data back from device to prevent SSP overflow */
+	ssp_read_word(&corgi_ssp_dev);
+
+	ssp_disable(&corgi_ssp_dev);
+	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2));
+	ssp_enable(&corgi_ssp_dev);
+	GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);
+	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
+
+	return 0;
+}
+
+void corgi_ssp_lcdtg_send(u8 adrs, u8 data)
+{
+	corgi_ssp_dac_put(((adrs & 0x07) << 5) | (data & 0x1f));
+}
+
+void corgi_ssp_blduty_set(int duty)
+{
+	corgi_ssp_lcdtg_send(0x02,duty);
+}
+
+EXPORT_SYMBOL(corgi_ssp_lcdtg_send);
+EXPORT_SYMBOL(corgi_ssp_blduty_set);
+
+/*
+ *  Max1111 Routines
+ */
+int corgi_ssp_max1111_get(ulong data)
+{
+	unsigned long flag;
+	int voltage,voltage1,voltage2;
+
+	spin_lock_irqsave(&corgi_ssp_lock, flag);
+	GPCR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS);
+	ssp_disable(&corgi_ssp_dev);
+	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(8));
+	ssp_enable(&corgi_ssp_dev);
+
+	udelay(1);
+
+	/* TB1/RB1 */
+	ssp_write_word(&corgi_ssp_dev,data);
+	ssp_read_word(&corgi_ssp_dev); /* null read */
+
+	/* TB12/RB2 */
+	ssp_write_word(&corgi_ssp_dev,0);
+	voltage1=ssp_read_word(&corgi_ssp_dev);
+
+	/* TB13/RB3*/
+	ssp_write_word(&corgi_ssp_dev,0);
+	voltage2=ssp_read_word(&corgi_ssp_dev);
+
+	ssp_disable(&corgi_ssp_dev);
+	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2));
+	ssp_enable(&corgi_ssp_dev);
+	GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS);
+	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
+
+	if (voltage1 & 0xc0 || voltage2 & 0x3f)
+		voltage = -1;
+	else
+		voltage = ((voltage1 << 2) & 0xfc) | ((voltage2 >> 6) & 0x03);
+
+	return voltage;
+}
+
+EXPORT_SYMBOL(corgi_ssp_max1111_get);
+
+/*
+ *  Support Routines
+ */
+int __init corgi_ssp_probe(struct device *dev)
+{
+	int ret;
+
+	/* Chip Select - Disable All */
+	GPDR0 |= GPIO_bit(CORGI_GPIO_LCDCON_CS); /* output */
+	GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);  /* High - Disable LCD Control/Timing Gen */
+	GPDR0 |= GPIO_bit(CORGI_GPIO_MAX1111_CS); /* output */
+	GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS);  /* High - Disable MAX1111*/
+	GPDR0 |= GPIO_bit(CORGI_GPIO_ADS7846_CS);  /* output */
+	GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);   /* High - Disable ADS7846*/
+
+	ret=ssp_init(&corgi_ssp_dev,1);
+
+	if (ret)
+		printk(KERN_ERR "Unable to register SSP handler!\n");
+	else {
+		ssp_disable(&corgi_ssp_dev);
+		ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2));
+		ssp_enable(&corgi_ssp_dev);
+	}
+
+	return ret;
+}
+
+static int corgi_ssp_remove(struct device *dev)
+{
+	ssp_exit(&corgi_ssp_dev);
+	return 0;
+}
+
+static int corgi_ssp_suspend(struct device *dev, pm_message_t state, u32 level)
+{
+	if (level == SUSPEND_POWER_DOWN) {
+		ssp_flush(&corgi_ssp_dev);
+		ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
+	}
+	return 0;
+}
+
+static int corgi_ssp_resume(struct device *dev, u32 level)
+{
+	if (level == RESUME_POWER_ON) {
+		GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);  /* High - Disable LCD Control/Timing Gen */
+		GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); /* High - Disable MAX1111*/
+		GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); /* High - Disable ADS7846*/
+		ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
+		ssp_enable(&corgi_ssp_dev);
+	}
+	return 0;
+}
+
+static struct device_driver corgissp_driver = {
+	.name		= "corgi-ssp",
+	.bus		= &platform_bus_type,
+	.probe		= corgi_ssp_probe,
+	.remove		= corgi_ssp_remove,
+	.suspend	= corgi_ssp_suspend,
+	.resume		= corgi_ssp_resume,
+};
+
+int __init corgi_ssp_init(void)
+{
+	return driver_register(&corgissp_driver);
+}
+
+arch_initcall(corgi_ssp_init);
diff --git a/arch/arm/mach-pxa/dma.c b/arch/arm/mach-pxa/dma.c
new file mode 100644
index 0000000..458112b
--- /dev/null
+++ b/arch/arm/mach-pxa/dma.c
@@ -0,0 +1,133 @@
+/*
+ *  linux/arch/arm/mach-pxa/dma.c
+ *
+ *  PXA DMA registration and IRQ dispatching
+ *
+ *  Author:	Nicolas Pitre
+ *  Created:	Nov 15, 2001
+ *  Copyright:	MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/dma.h>
+
+#include <asm/arch/pxa-regs.h>
+
+static struct dma_channel {
+	char *name;
+	void (*irq_handler)(int, void *, struct pt_regs *);
+	void *data;
+} dma_channels[PXA_DMA_CHANNELS];
+
+
+int pxa_request_dma (char *name, pxa_dma_prio prio,
+			 void (*irq_handler)(int, void *, struct pt_regs *),
+		 	 void *data)
+{
+	unsigned long flags;
+	int i, found = 0;
+
+	/* basic sanity checks */
+	if (!name || !irq_handler)
+		return -EINVAL;
+
+	local_irq_save(flags);
+
+	/* try grabbing a DMA channel with the requested priority */
+	for (i = prio; i < prio + PXA_DMA_NBCH(prio); i++) {
+		if (!dma_channels[i].name) {
+			found = 1;
+			break;
+		}
+	}
+
+	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 (found) {
+		DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
+		dma_channels[i].name = name;
+		dma_channels[i].irq_handler = irq_handler;
+		dma_channels[i].data = data;
+	} else {
+		printk (KERN_WARNING "No more available DMA channels for %s\n", name);
+		i = -ENODEV;
+	}
+
+	local_irq_restore(flags);
+	return i;
+}
+
+void pxa_free_dma (int dma_ch)
+{
+	unsigned long flags;
+
+	if (!dma_channels[dma_ch].name) {
+		printk (KERN_CRIT
+			"%s: trying to free channel %d which is already freed\n",
+			__FUNCTION__, dma_ch);
+		return;
+	}
+
+	local_irq_save(flags);
+	DCSR(dma_ch) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
+	dma_channels[dma_ch].name = NULL;
+	local_irq_restore(flags);
+}
+
+static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int i, dint = DINT;
+
+	for (i = 0; i < PXA_DMA_CHANNELS; i++) {
+		if (dint & (1 << i)) {
+			struct dma_channel *channel = &dma_channels[i];
+			if (channel->name && channel->irq_handler) {
+				channel->irq_handler(i, channel->data, regs);
+			} else {
+				/*
+				 * IRQ for an unregistered DMA channel:
+				 * let's clear the interrupts and disable it.
+				 */
+				printk (KERN_WARNING "spurious IRQ for DMA channel %d\n", i);
+				DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
+			}
+		}
+	}
+	return IRQ_HANDLED;
+}
+
+static int __init pxa_dma_init (void)
+{
+	int ret;
+
+	ret = request_irq (IRQ_DMA, dma_irq_handler, 0, "DMA", NULL);
+	if (ret)
+		printk (KERN_CRIT "Wow!  Can't register IRQ for DMA\n");
+	return ret;
+}
+
+arch_initcall(pxa_dma_init);
+
+EXPORT_SYMBOL(pxa_request_dma);
+EXPORT_SYMBOL(pxa_free_dma);
+
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
new file mode 100644
index 0000000..b1575b8
--- /dev/null
+++ b/arch/arm/mach-pxa/generic.c
@@ -0,0 +1,237 @@
+/*
+ *  linux/arch/arm/mach-pxa/generic.c
+ *
+ *  Author:	Nicolas Pitre
+ *  Created:	Jun 15, 2001
+ *  Copyright:	MontaVista Software Inc.
+ *
+ * Code common to all PXA machines.
+ *
+ * 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.
+ *
+ * Since this file should be linked before any other machine specific file,
+ * the __initcall() here will be executed first.  This serves as default
+ * initialization stuff for PXA machines which can be overridden later if
+ * need be.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/ioport.h>
+#include <linux/pm.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/udc.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/mmc.h>
+
+#include "generic.h"
+
+/*
+ * Handy function to set GPIO alternate functions
+ */
+
+void pxa_gpio_mode(int gpio_mode)
+{
+	unsigned long flags;
+	int gpio = gpio_mode & GPIO_MD_MASK_NR;
+	int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
+	int gafr;
+
+	local_irq_save(flags);
+	if (gpio_mode & GPIO_DFLT_LOW)
+		GPCR(gpio) = GPIO_bit(gpio);
+	else if (gpio_mode & GPIO_DFLT_HIGH)
+		GPSR(gpio) = GPIO_bit(gpio);
+	if (gpio_mode & GPIO_MD_MASK_DIR)
+		GPDR(gpio) |= GPIO_bit(gpio);
+	else
+		GPDR(gpio) &= ~GPIO_bit(gpio);
+	gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
+	GAFR(gpio) = gafr |  (fn  << (((gpio) & 0xf)*2));
+	local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL(pxa_gpio_mode);
+
+/*
+ * Routine to safely enable or disable a clock in the CKEN
+ */
+void pxa_set_cken(int clock, int enable)
+{
+	unsigned long flags;
+	local_irq_save(flags);
+
+	if (enable)
+		CKEN |= clock;
+	else
+		CKEN &= ~clock;
+
+	local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL(pxa_set_cken);
+
+/*
+ * Intel PXA2xx internal register mapping.
+ *
+ * Note 1: not all PXA2xx variants implement all those addresses.
+ *
+ * Note 2: virtual 0xfffe0000-0xffffffff is reserved for the vector table
+ *         and cache flush area.
+ */
+static struct map_desc standard_io_desc[] __initdata = {
+ /* virtual     physical    length      type */
+  { 0xf2000000, 0x40000000, 0x02000000, MT_DEVICE }, /* Devs */
+  { 0xf4000000, 0x44000000, 0x00100000, MT_DEVICE }, /* LCD */
+  { 0xf6000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Mem Ctl */
+  { 0xf8000000, 0x4c000000, 0x00100000, MT_DEVICE }, /* USB host */
+  { 0xfa000000, 0x50000000, 0x00100000, MT_DEVICE }, /* Camera */
+  { 0xfe000000, 0x58000000, 0x00100000, MT_DEVICE }, /* IMem ctl */
+  { 0xff000000, 0x00000000, 0x00100000, MT_DEVICE }  /* UNCACHED_PHYS_0 */
+};
+
+void __init pxa_map_io(void)
+{
+	iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
+	get_clk_frequency_khz(1);
+}
+
+
+static struct resource pxamci_resources[] = {
+	[0] = {
+		.start	= 0x41100000,
+		.end	= 0x41100fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_MMC,
+		.end	= IRQ_MMC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 pxamci_dmamask = 0xffffffffUL;
+
+static struct platform_device pxamci_device = {
+	.name		= "pxa2xx-mci",
+	.id		= -1,
+	.dev		= {
+		.dma_mask = &pxamci_dmamask,
+		.coherent_dma_mask = 0xffffffff,
+	},
+	.num_resources	= ARRAY_SIZE(pxamci_resources),
+	.resource	= pxamci_resources,
+};
+
+void __init pxa_set_mci_info(struct pxamci_platform_data *info)
+{
+	pxamci_device.dev.platform_data = info;
+}
+
+
+static struct pxa2xx_udc_mach_info pxa_udc_info;
+
+void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info)
+{
+	memcpy(&pxa_udc_info, info, sizeof *info);
+}
+
+static struct resource pxa2xx_udc_resources[] = {
+	[0] = {
+		.start	= 0x40600000,
+		.end	= 0x4060ffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_USB,
+		.end	= IRQ_USB,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 udc_dma_mask = ~(u32)0;
+
+static struct platform_device udc_device = {
+	.name		= "pxa2xx-udc",
+	.id		= -1,
+	.resource	= pxa2xx_udc_resources,
+	.num_resources	= ARRAY_SIZE(pxa2xx_udc_resources),
+	.dev		=  {
+		.platform_data	= &pxa_udc_info,
+		.dma_mask	= &udc_dma_mask,
+	}
+};
+
+static struct pxafb_mach_info pxa_fb_info;
+
+void __init set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info)
+{
+	memcpy(&pxa_fb_info,hard_pxa_fb_info,sizeof(struct pxafb_mach_info));
+}
+
+static struct resource pxafb_resources[] = {
+	[0] = {
+		.start	= 0x44000000,
+		.end	= 0x4400ffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_LCD,
+		.end	= IRQ_LCD,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 fb_dma_mask = ~(u64)0;
+
+static struct platform_device pxafb_device = {
+	.name		= "pxa2xx-fb",
+	.id		= -1,
+	.dev		= {
+ 		.platform_data	= &pxa_fb_info,
+		.dma_mask	= &fb_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+	},
+	.num_resources	= ARRAY_SIZE(pxafb_resources),
+	.resource	= pxafb_resources,
+};
+
+static struct platform_device ffuart_device = {
+	.name		= "pxa2xx-uart",
+	.id		= 0,
+};
+static struct platform_device btuart_device = {
+	.name		= "pxa2xx-uart",
+	.id		= 1,
+};
+static struct platform_device stuart_device = {
+	.name		= "pxa2xx-uart",
+	.id		= 2,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&pxamci_device,
+	&udc_device,
+	&pxafb_device,
+	&ffuart_device,
+	&btuart_device,
+	&stuart_device,
+};
+
+static int __init pxa_init(void)
+{
+	return platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+subsys_initcall(pxa_init);
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
new file mode 100644
index 0000000..e54a8dd
--- /dev/null
+++ b/arch/arm/mach-pxa/generic.h
@@ -0,0 +1,24 @@
+/*
+ *  linux/arch/arm/mach-pxa/generic.h
+ *
+ * Author:	Nicolas Pitre
+ * Copyright:	MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+struct sys_timer;
+
+extern struct sys_timer pxa_timer;
+extern void __init pxa_map_io(void);
+extern void __init pxa_init_irq(void);
+
+extern unsigned int get_clk_frequency_khz(int info);
+
+#define SET_BANK(__nr,__start,__size) \
+	mi->bank[__nr].start = (__start), \
+	mi->bank[__nr].size = (__size), \
+	mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27)
+
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
new file mode 100644
index 0000000..c5a66bf
--- /dev/null
+++ b/arch/arm/mach-pxa/idp.c
@@ -0,0 +1,190 @@
+/*
+ *  linux/arch/arm/mach-pxa/idp.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.
+ *
+ *  Copyright (c) 2001 Cliff Brake, Accelent Systems Inc.
+ *
+ *  2001-09-13: Cliff Brake <cbrake@accelent.com>
+ *              Initial code
+ *
+ *  2005-02-15: Cliff Brake <cliff.brake@gmail.com>
+ *  		<http://www.vibren.com> <http://bec-systems.com>
+ *              Updated for 2.6 kernel
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/fb.h>
+
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/idp.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/bitfield.h>
+#include <asm/arch/mmc.h>
+
+#include "generic.h"
+
+/* TODO:
+ * - add pxa2xx_audio_ops_t device structure
+ * - Ethernet interrupt
+ */
+
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.start	= (IDP_ETH_PHYS + 0x300),
+		.end	= (IDP_ETH_PHYS + 0xfffff),
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_GPIO(4),
+		.end	= IRQ_GPIO(4),
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(smc91x_resources),
+	.resource	= smc91x_resources,
+};
+
+static void idp_backlight_power(int on)
+{
+	if (on) {
+		IDP_CPLD_LCD |= (1<<1);
+	} else {
+		IDP_CPLD_LCD &= ~(1<<1);
+	}
+}
+
+static void idp_vlcd(int on)
+{
+	if (on) {
+		IDP_CPLD_LCD |= (1<<2);
+	} else {
+		IDP_CPLD_LCD &= ~(1<<2);
+	}
+}
+
+static void idp_lcd_power(int on)
+{
+	if (on) {
+		IDP_CPLD_LCD |= (1<<0);
+	} else {
+		IDP_CPLD_LCD &= ~(1<<0);
+	}
+
+	/* call idp_vlcd for now as core driver does not support
+	 * both power and vlcd hooks.  Note, this is not technically
+	 * the correct sequence, but seems to work.  Disclaimer:
+	 * this may eventually damage the display.
+	 */
+
+	idp_vlcd(on);
+}
+
+static struct pxafb_mach_info sharp_lm8v31 __initdata = {
+	.pixclock	= 270000,
+	.xres		= 640,
+	.yres		= 480,
+	.bpp		= 16,
+	.hsync_len	= 1,
+	.left_margin	= 3,
+	.right_margin	= 3,
+	.vsync_len	= 1,
+	.upper_margin	= 0,
+	.lower_margin	= 0,
+	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	.cmap_greyscale	= 0,
+	.cmap_inverse	= 0,
+	.cmap_static	= 0,
+	.lccr0		= LCCR0_SDS,
+	.lccr3		= LCCR3_PCP | LCCR3_Acb(255),
+	.pxafb_backlight_power = &idp_backlight_power,
+	.pxafb_lcd_power = &idp_lcd_power
+};
+
+static int idp_mci_init(struct device *dev, irqreturn_t (*idp_detect_int)(int, void *, struct pt_regs *), void *data)
+{
+	/* setup GPIO for PXA25x MMC controller	*/
+	pxa_gpio_mode(GPIO6_MMCCLK_MD);
+	pxa_gpio_mode(GPIO8_MMCCS0_MD);
+
+	return 0;
+}
+
+static struct pxamci_platform_data idp_mci_platform_data = {
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init 		= idp_mci_init,
+};
+
+static void __init idp_init(void)
+{
+	printk("idp_init()\n");
+
+	platform_device_register(&smc91x_device);
+	//platform_device_register(&mst_audio_device);
+	set_pxa_fb_info(&sharp_lm8v31);
+	pxa_set_mci_info(&idp_mci_platform_data);
+}
+
+static void __init idp_init_irq(void)
+{
+
+	pxa_init_irq();
+
+	set_irq_type(TOUCH_PANEL_IRQ, TOUCH_PANEL_IRQ_EDGE);
+}
+
+static struct map_desc idp_io_desc[] __initdata = {
+ /* virtual     physical    length      type */
+
+  { IDP_COREVOLT_VIRT,
+    IDP_COREVOLT_PHYS,
+    IDP_COREVOLT_SIZE,
+    MT_DEVICE },
+  { IDP_CPLD_VIRT,
+    IDP_CPLD_PHYS,
+    IDP_CPLD_SIZE,
+    MT_DEVICE }
+};
+
+static void __init idp_map_io(void)
+{
+	pxa_map_io();
+	iotable_init(idp_io_desc, ARRAY_SIZE(idp_io_desc));
+
+	// serial ports 2 & 3
+	pxa_gpio_mode(GPIO42_BTRXD_MD);
+	pxa_gpio_mode(GPIO43_BTTXD_MD);
+	pxa_gpio_mode(GPIO44_BTCTS_MD);
+	pxa_gpio_mode(GPIO45_BTRTS_MD);
+	pxa_gpio_mode(GPIO46_STRXD_MD);
+	pxa_gpio_mode(GPIO47_STTXD_MD);
+
+}
+
+
+MACHINE_START(PXA_IDP, "Vibren PXA255 IDP")
+	MAINTAINER("Vibren Technologies")
+	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
+	MAPIO(idp_map_io)
+	INITIRQ(idp_init_irq)
+	.timer		= &pxa_timer,
+	INIT_MACHINE(idp_init)
+MACHINE_END
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
new file mode 100644
index 0000000..f3cac43
--- /dev/null
+++ b/arch/arm/mach-pxa/irq.c
@@ -0,0 +1,313 @@
+/*
+ *  linux/arch/arm/mach-pxa/irq.c
+ *
+ *  Generic PXA IRQ handling, GPIO IRQ demultiplexing, etc.
+ *
+ *  Author:	Nicolas Pitre
+ *  Created:	Jun 15, 2001
+ *  Copyright:	MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/pxa-regs.h>
+
+#include "generic.h"
+
+
+/*
+ * This is for peripheral IRQs internal to the PXA chip.
+ */
+
+static void pxa_mask_low_irq(unsigned int irq)
+{
+	ICMR &= ~(1 << (irq + PXA_IRQ_SKIP));
+}
+
+static void pxa_unmask_low_irq(unsigned int irq)
+{
+	ICMR |= (1 << (irq + PXA_IRQ_SKIP));
+}
+
+static struct irqchip pxa_internal_chip_low = {
+	.ack		= pxa_mask_low_irq,
+	.mask		= pxa_mask_low_irq,
+	.unmask		= pxa_unmask_low_irq,
+};
+
+#if PXA_INTERNAL_IRQS > 32
+
+/*
+ * This is for the second set of internal IRQs as found on the PXA27x.
+ */
+
+static void pxa_mask_high_irq(unsigned int irq)
+{
+	ICMR2 &= ~(1 << (irq - 32 + PXA_IRQ_SKIP));
+}
+
+static void pxa_unmask_high_irq(unsigned int irq)
+{
+	ICMR2 |= (1 << (irq - 32 + PXA_IRQ_SKIP));
+}
+
+static struct irqchip pxa_internal_chip_high = {
+	.ack		= pxa_mask_high_irq,
+	.mask		= pxa_mask_high_irq,
+	.unmask		= pxa_unmask_high_irq,
+};
+
+#endif
+
+/*
+ * PXA GPIO edge detection for IRQs:
+ * IRQs are generated on Falling-Edge, Rising-Edge, or both.
+ * Use this instead of directly setting GRER/GFER.
+ */
+
+static long GPIO_IRQ_rising_edge[4];
+static long GPIO_IRQ_falling_edge[4];
+static long GPIO_IRQ_mask[4];
+
+static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
+{
+	int gpio, idx;
+
+	gpio = IRQ_TO_GPIO(irq);
+	idx = gpio >> 5;
+
+	if (type == IRQT_PROBE) {
+	    /* Don't mess with enabled GPIOs using preconfigured edges or
+	       GPIOs set to alternate function during probe */
+		if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx]) &
+		    GPIO_bit(gpio))
+			return 0;
+		if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2)))
+			return 0;
+		type = __IRQT_RISEDGE | __IRQT_FALEDGE;
+	}
+
+	/* printk(KERN_DEBUG "IRQ%d (GPIO%d): ", irq, gpio); */
+
+	pxa_gpio_mode(gpio | GPIO_IN);
+
+	if (type & __IRQT_RISEDGE) {
+		/* printk("rising "); */
+		__set_bit (gpio, GPIO_IRQ_rising_edge);
+	} else
+		__clear_bit (gpio, GPIO_IRQ_rising_edge);
+
+	if (type & __IRQT_FALEDGE) {
+		/* printk("falling "); */
+		__set_bit (gpio, GPIO_IRQ_falling_edge);
+	} else
+		__clear_bit (gpio, GPIO_IRQ_falling_edge);
+
+	/* printk("edges\n"); */
+
+	GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx];
+	GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx];
+	return 0;
+}
+
+/*
+ * GPIO IRQs must be acknowledged.  This is for GPIO 0 and 1.
+ */
+
+static void pxa_ack_low_gpio(unsigned int irq)
+{
+	GEDR0 = (1 << (irq - IRQ_GPIO0));
+}
+
+static struct irqchip pxa_low_gpio_chip = {
+	.ack		= pxa_ack_low_gpio,
+	.mask		= pxa_mask_low_irq,
+	.unmask		= pxa_unmask_low_irq,
+	.type		= pxa_gpio_irq_type,
+};
+
+/*
+ * Demux handler for GPIO>=2 edge detect interrupts
+ */
+
+static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc,
+				   struct pt_regs *regs)
+{
+	unsigned int mask;
+	int loop;
+
+	do {
+		loop = 0;
+
+		mask = GEDR0 & ~3;
+		if (mask) {
+			GEDR0 = mask;
+			irq = IRQ_GPIO(2);
+			desc = irq_desc + irq;
+			mask >>= 2;
+			do {
+				if (mask & 1)
+					desc->handle(irq, desc, regs);
+				irq++;
+				desc++;
+				mask >>= 1;
+			} while (mask);
+			loop = 1;
+		}
+
+		mask = GEDR1;
+		if (mask) {
+			GEDR1 = mask;
+			irq = IRQ_GPIO(32);
+			desc = irq_desc + irq;
+			do {
+				if (mask & 1)
+					desc->handle(irq, desc, regs);
+				irq++;
+				desc++;
+				mask >>= 1;
+			} while (mask);
+			loop = 1;
+		}
+
+		mask = GEDR2;
+		if (mask) {
+			GEDR2 = mask;
+			irq = IRQ_GPIO(64);
+			desc = irq_desc + irq;
+			do {
+				if (mask & 1)
+					desc->handle(irq, desc, regs);
+				irq++;
+				desc++;
+				mask >>= 1;
+			} while (mask);
+			loop = 1;
+		}
+
+#if PXA_LAST_GPIO >= 96
+		mask = GEDR3;
+		if (mask) {
+			GEDR3 = mask;
+			irq = IRQ_GPIO(96);
+			desc = irq_desc + irq;
+			do {
+				if (mask & 1)
+					desc->handle(irq, desc, regs);
+				irq++;
+				desc++;
+				mask >>= 1;
+			} while (mask);
+			loop = 1;
+		}
+#endif
+	} while (loop);
+}
+
+static void pxa_ack_muxed_gpio(unsigned int irq)
+{
+	int gpio = irq - IRQ_GPIO(2) + 2;
+	GEDR(gpio) = GPIO_bit(gpio);
+}
+
+static void pxa_mask_muxed_gpio(unsigned int irq)
+{
+	int gpio = irq - IRQ_GPIO(2) + 2;
+	__clear_bit(gpio, GPIO_IRQ_mask);
+	GRER(gpio) &= ~GPIO_bit(gpio);
+	GFER(gpio) &= ~GPIO_bit(gpio);
+}
+
+static void pxa_unmask_muxed_gpio(unsigned int irq)
+{
+	int gpio = irq - IRQ_GPIO(2) + 2;
+	int idx = gpio >> 5;
+	__set_bit(gpio, GPIO_IRQ_mask);
+	GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx];
+	GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx];
+}
+
+static struct irqchip pxa_muxed_gpio_chip = {
+	.ack		= pxa_ack_muxed_gpio,
+	.mask		= pxa_mask_muxed_gpio,
+	.unmask		= pxa_unmask_muxed_gpio,
+	.type		= pxa_gpio_irq_type,
+};
+
+
+void __init pxa_init_irq(void)
+{
+	int irq;
+
+	/* disable all IRQs */
+	ICMR = 0;
+
+	/* all IRQs are IRQ, not FIQ */
+	ICLR = 0;
+
+	/* clear all GPIO edge detects */
+	GFER0 = 0;
+	GFER1 = 0;
+	GFER2 = 0;
+	GRER0 = 0;
+	GRER1 = 0;
+	GRER2 = 0;
+	GEDR0 = GEDR0;
+	GEDR1 = GEDR1;
+	GEDR2 = GEDR2;
+
+#ifdef CONFIG_PXA27x
+	/* And similarly for the extra regs on the PXA27x */
+	ICMR2 = 0;
+	ICLR2 = 0;
+	GFER3 = 0;
+	GRER3 = 0;
+	GEDR3 = GEDR3;
+#endif
+
+	/* only unmasked interrupts kick us out of idle */
+	ICCR = 1;
+
+	/* GPIO 0 and 1 must have their mask bit always set */
+	GPIO_IRQ_mask[0] = 3;
+
+	for (irq = PXA_IRQ(PXA_IRQ_SKIP); irq <= PXA_IRQ(31); irq++) {
+		set_irq_chip(irq, &pxa_internal_chip_low);
+		set_irq_handler(irq, do_level_IRQ);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+#if PXA_INTERNAL_IRQS > 32
+	for (irq = PXA_IRQ(32); irq < PXA_IRQ(PXA_INTERNAL_IRQS); irq++) {
+		set_irq_chip(irq, &pxa_internal_chip_high);
+		set_irq_handler(irq, do_level_IRQ);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+#endif
+
+	for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
+		set_irq_chip(irq, &pxa_low_gpio_chip);
+		set_irq_handler(irq, do_edge_IRQ);
+		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+	}
+
+	for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(PXA_LAST_GPIO); irq++) {
+		set_irq_chip(irq, &pxa_muxed_gpio_chip);
+		set_irq_handler(irq, do_edge_IRQ);
+		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+	}
+
+	/* Install handler for GPIO>=2 edge detect interrupts */
+	set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low);
+	set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler);
+}
diff --git a/arch/arm/mach-pxa/leds-idp.c b/arch/arm/mach-pxa/leds-idp.c
new file mode 100644
index 0000000..5eba6ea
--- /dev/null
+++ b/arch/arm/mach-pxa/leds-idp.c
@@ -0,0 +1,117 @@
+/*
+ * linux/arch/arm/mach-pxa/leds-idp.c
+ *
+ * Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu>
+ *
+ * Copyright (c) 2001 Jeff Sutherland <jeffs@accelent.com>
+ *
+ * Original (leds-footbridge.c) by Russell King
+ *
+ * Macros for actual LED manipulation should be in machine specific
+ * files in this 'mach' directory.
+ */
+
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/idp.h>
+
+#include "leds.h"
+
+#define LED_STATE_ENABLED	1
+#define LED_STATE_CLAIMED	2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+void idp_leds_event(led_event_t evt)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	switch (evt) {
+	case led_start:
+		hw_led_state = IDP_HB_LED | IDP_BUSY_LED;
+		led_state = LED_STATE_ENABLED;
+		break;
+
+	case led_stop:
+		led_state &= ~LED_STATE_ENABLED;
+		break;
+
+	case led_claim:
+		led_state |= LED_STATE_CLAIMED;
+		hw_led_state = IDP_HB_LED | IDP_BUSY_LED;
+		break;
+
+	case led_release:
+		led_state &= ~LED_STATE_CLAIMED;
+		hw_led_state = IDP_HB_LED | IDP_BUSY_LED;
+		break;
+
+#ifdef CONFIG_LEDS_TIMER
+	case led_timer:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state ^= IDP_HB_LED;
+		break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+	case led_idle_start:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state &= ~IDP_BUSY_LED;
+		break;
+
+	case led_idle_end:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state |= IDP_BUSY_LED;
+		break;
+#endif
+
+	case led_halted:
+		break;
+
+	case led_green_on:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state |= IDP_HB_LED;
+		break;
+
+	case led_green_off:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state &= ~IDP_HB_LED;
+		break;
+
+	case led_amber_on:
+		break;
+
+	case led_amber_off:
+		break;
+
+	case led_red_on:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state |= IDP_BUSY_LED;
+		break;
+
+	case led_red_off:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state &= ~IDP_BUSY_LED;
+		break;
+
+	default:
+		break;
+	}
+
+	if  (led_state & LED_STATE_ENABLED)
+		IDP_CPLD_LED_CONTROL = ( (IDP_CPLD_LED_CONTROL | IDP_LEDS_MASK) & ~hw_led_state);
+	else
+		IDP_CPLD_LED_CONTROL |= IDP_LEDS_MASK;
+
+	local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-pxa/leds-lubbock.c b/arch/arm/mach-pxa/leds-lubbock.c
new file mode 100644
index 0000000..05cf560
--- /dev/null
+++ b/arch/arm/mach-pxa/leds-lubbock.c
@@ -0,0 +1,126 @@
+/*
+ * linux/arch/arm/mach-pxa/leds-lubbock.c
+ *
+ * Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu>
+ *
+ * Copyright (c) 2001 Jeff Sutherland <jeffs@accelent.com>
+ *
+ * Original (leds-footbridge.c) by Russell King
+ *
+ * Major surgery on April 2004 by Nicolas Pitre for less global
+ * namespace collision.  Mostly adapted the Mainstone version.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/lubbock.h>
+
+#include "leds.h"
+
+/*
+ * 8 discrete leds available for general use:
+ *
+ * Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays
+ * so be sure to not monkey with them here.
+ */
+
+#define D28			(1 << 0)
+#define D27			(1 << 1)
+#define D26			(1 << 2)
+#define D25			(1 << 3)
+#define D24			(1 << 4)
+#define D23			(1 << 5)
+#define D22			(1 << 6)
+#define D21			(1 << 7)
+
+#define LED_STATE_ENABLED	1
+#define LED_STATE_CLAIMED	2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+void lubbock_leds_event(led_event_t evt)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	switch (evt) {
+	case led_start:
+		hw_led_state = 0;
+		led_state = LED_STATE_ENABLED;
+		break;
+
+	case led_stop:
+		led_state &= ~LED_STATE_ENABLED;
+		break;
+
+	case led_claim:
+		led_state |= LED_STATE_CLAIMED;
+		hw_led_state = 0;
+		break;
+
+	case led_release:
+		led_state &= ~LED_STATE_CLAIMED;
+		hw_led_state = 0;
+		break;
+
+#ifdef CONFIG_LEDS_TIMER
+	case led_timer:
+		hw_led_state ^= D26;
+		break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+	case led_idle_start:
+		hw_led_state &= ~D27;
+		break;
+
+	case led_idle_end:
+		hw_led_state |= D27;
+		break;
+#endif
+
+	case led_halted:
+		break;
+
+	case led_green_on:
+		hw_led_state |= D21;
+		break;
+
+	case led_green_off:
+		hw_led_state &= ~D21;
+		break;
+
+	case led_amber_on:
+		hw_led_state |= D22;
+		break;
+
+	case led_amber_off:
+		hw_led_state &= ~D22;
+		break;
+
+	case led_red_on:
+		hw_led_state |= D23;
+		break;
+
+	case led_red_off:
+		hw_led_state &= ~D23;
+		break;
+
+	default:
+		break;
+	}
+
+	if  (led_state & LED_STATE_ENABLED)
+		LUB_DISC_BLNK_LED = (LUB_DISC_BLNK_LED | 0xff) & ~hw_led_state;
+	else
+		LUB_DISC_BLNK_LED |= 0xff;
+
+	local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-pxa/leds-mainstone.c b/arch/arm/mach-pxa/leds-mainstone.c
new file mode 100644
index 0000000..bbd3f87
--- /dev/null
+++ b/arch/arm/mach-pxa/leds-mainstone.c
@@ -0,0 +1,121 @@
+/*
+ * linux/arch/arm/mach-pxa/leds-mainstone.c
+ *
+ * Author:     Nicolas Pitre
+ * Created:    Nov 05, 2002
+ * Copyright:  MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/mainstone.h>
+
+#include "leds.h"
+
+
+/* 8 discrete leds available for general use: */
+#define D28			(1 << 0)
+#define D27			(1 << 1)
+#define D26			(1 << 2)
+#define D25			(1 << 3)
+#define D24			(1 << 4)
+#define D23			(1 << 5)
+#define D22			(1 << 6)
+#define D21			(1 << 7)
+
+#define LED_STATE_ENABLED	1
+#define LED_STATE_CLAIMED	2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+void mainstone_leds_event(led_event_t evt)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	switch (evt) {
+	case led_start:
+		hw_led_state = 0;
+		led_state = LED_STATE_ENABLED;
+		break;
+
+	case led_stop:
+		led_state &= ~LED_STATE_ENABLED;
+		break;
+
+	case led_claim:
+		led_state |= LED_STATE_CLAIMED;
+		hw_led_state = 0;
+		break;
+
+	case led_release:
+		led_state &= ~LED_STATE_CLAIMED;
+		hw_led_state = 0;
+		break;
+
+#ifdef CONFIG_LEDS_TIMER
+	case led_timer:
+		hw_led_state ^= D26;
+		break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+	case led_idle_start:
+		hw_led_state &= ~D27;
+		break;
+
+	case led_idle_end:
+		hw_led_state |= D27;
+		break;
+#endif
+
+	case led_halted:
+		break;
+
+	case led_green_on:
+		hw_led_state |= D21;;
+		break;
+
+	case led_green_off:
+		hw_led_state &= ~D21;
+		break;
+
+	case led_amber_on:
+		hw_led_state |= D22;;
+		break;
+
+	case led_amber_off:
+		hw_led_state &= ~D22;
+		break;
+
+	case led_red_on:
+		hw_led_state |= D23;;
+		break;
+
+	case led_red_off:
+		hw_led_state &= ~D23;
+		break;
+
+	default:
+		break;
+	}
+
+	if  (led_state & LED_STATE_ENABLED)
+		MST_LEDCTRL = (MST_LEDCTRL | 0xff) & ~hw_led_state;
+	else
+		MST_LEDCTRL |= 0xff;
+
+	local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-pxa/leds.c b/arch/arm/mach-pxa/leds.c
new file mode 100644
index 0000000..bbe4d5f
--- /dev/null
+++ b/arch/arm/mach-pxa/leds.c
@@ -0,0 +1,32 @@
+/*
+ * linux/arch/arm/mach-pxa/leds.c
+ *
+ * xscale LEDs dispatcher
+ *
+ * Copyright (C) 2001 Nicolas Pitre
+ *
+ * Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc.
+ */
+#include <linux/compiler.h>
+#include <linux/init.h>
+
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+
+#include "leds.h"
+
+static int __init
+pxa_leds_init(void)
+{
+	if (machine_is_lubbock())
+		leds_event = lubbock_leds_event;
+	if (machine_is_mainstone())
+		leds_event = mainstone_leds_event;
+	if (machine_is_pxa_idp())
+		leds_event = idp_leds_event;
+
+	leds_event(led_start);
+	return 0;
+}
+
+core_initcall(pxa_leds_init);
diff --git a/arch/arm/mach-pxa/leds.h b/arch/arm/mach-pxa/leds.h
new file mode 100644
index 0000000..d98f6e9
--- /dev/null
+++ b/arch/arm/mach-pxa/leds.h
@@ -0,0 +1,12 @@
+/*
+ * include/asm-arm/arch-pxa/leds.h
+ *
+ * Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc.
+ *
+ * blinky lights for various PXA-based systems:
+ *
+ */
+
+extern void idp_leds_event(led_event_t evt);
+extern void lubbock_leds_event(led_event_t evt);
+extern void mainstone_leds_event(led_event_t evt);
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
new file mode 100644
index 0000000..dd012d6
--- /dev/null
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -0,0 +1,247 @@
+/*
+ *  linux/arch/arm/mach-pxa/lubbock.c
+ *
+ *  Support for the Intel DBPXA250 Development Platform.
+ *
+ *  Author:	Nicolas Pitre
+ *  Created:	Jun 15, 2001
+ *  Copyright:	MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/major.h>
+#include <linux/fb.h>
+#include <linux/interrupt.h>
+
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware/sa1111.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/lubbock.h>
+#include <asm/arch/udc.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/mmc.h>
+
+#include "generic.h"
+
+
+#define LUB_MISC_WR		__LUB_REG(LUBBOCK_FPGA_PHYS + 0x080)
+
+void lubbock_set_misc_wr(unsigned int mask, unsigned int set)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	LUB_MISC_WR = (LUB_MISC_WR & ~mask) | (set & mask);
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(lubbock_set_misc_wr);
+
+static unsigned long lubbock_irq_enabled;
+
+static void lubbock_mask_irq(unsigned int irq)
+{
+	int lubbock_irq = (irq - LUBBOCK_IRQ(0));
+	LUB_IRQ_MASK_EN = (lubbock_irq_enabled &= ~(1 << lubbock_irq));
+}
+
+static void lubbock_unmask_irq(unsigned int irq)
+{
+	int lubbock_irq = (irq - LUBBOCK_IRQ(0));
+	/* the irq can be acknowledged only if deasserted, so it's done here */
+	LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq);
+	LUB_IRQ_MASK_EN = (lubbock_irq_enabled |= (1 << lubbock_irq));
+}
+
+static struct irqchip lubbock_irq_chip = {
+	.ack		= lubbock_mask_irq,
+	.mask		= lubbock_mask_irq,
+	.unmask		= lubbock_unmask_irq,
+};
+
+static void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc,
+				struct pt_regs *regs)
+{
+	unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
+	do {
+		GEDR(0) = GPIO_bit(0);	/* clear our parent irq */
+		if (likely(pending)) {
+			irq = LUBBOCK_IRQ(0) + __ffs(pending);
+			desc = irq_desc + irq;
+			desc->handle(irq, desc, regs);
+		}
+		pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
+	} while (pending);
+}
+
+static void __init lubbock_init_irq(void)
+{
+	int irq;
+
+	pxa_init_irq();
+
+	/* setup extra lubbock irqs */
+	for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) {
+		set_irq_chip(irq, &lubbock_irq_chip);
+		set_irq_handler(irq, do_level_IRQ);
+		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+	}
+
+	set_irq_chained_handler(IRQ_GPIO(0), lubbock_irq_handler);
+	set_irq_type(IRQ_GPIO(0), IRQT_FALLING);
+}
+
+static int lubbock_udc_is_connected(void)
+{
+	return (LUB_MISC_RD & (1 << 9)) == 0;
+}
+
+static struct pxa2xx_udc_mach_info udc_info __initdata = {
+	.udc_is_connected	= lubbock_udc_is_connected,
+	// no D+ pullup; lubbock can't connect/disconnect in software
+};
+
+static struct resource sa1111_resources[] = {
+	[0] = {
+		.start	= 0x10000000,
+		.end	= 0x10001fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= LUBBOCK_SA1111_IRQ,
+		.end	= LUBBOCK_SA1111_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sa1111_device = {
+	.name		= "sa1111",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(sa1111_resources),
+	.resource	= sa1111_resources,
+};
+
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.name	= "smc91x-regs",
+		.start	= 0x0c000000,
+		.end	= 0x0c0fffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= LUBBOCK_ETH_IRQ,
+		.end	= LUBBOCK_ETH_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.name	= "smc91x-attrib",
+		.start	= 0x0e000000,
+		.end	= 0x0e0fffff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(smc91x_resources),
+	.resource	= smc91x_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&sa1111_device,
+	&smc91x_device,
+};
+
+static struct pxafb_mach_info sharp_lm8v31 __initdata = {
+	.pixclock	= 270000,
+	.xres		= 640,
+	.yres		= 480,
+	.bpp		= 16,
+	.hsync_len	= 1,
+	.left_margin	= 3,
+	.right_margin	= 3,
+	.vsync_len	= 1,
+	.upper_margin	= 0,
+	.lower_margin	= 0,
+	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	.cmap_greyscale	= 0,
+	.cmap_inverse	= 0,
+	.cmap_static	= 0,
+	.lccr0		= LCCR0_SDS,
+	.lccr3		= LCCR3_PCP | LCCR3_Acb(255),
+};
+
+static int lubbock_mci_init(struct device *dev, irqreturn_t (*lubbock_detect_int)(int, void *, struct pt_regs *), void *data)
+{
+	/* setup GPIO for PXA25x MMC controller	*/
+	pxa_gpio_mode(GPIO6_MMCCLK_MD);
+	pxa_gpio_mode(GPIO8_MMCCS0_MD);
+
+	return 0;
+}
+
+static struct pxamci_platform_data lubbock_mci_platform_data = {
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init 		= lubbock_mci_init,
+};
+
+static void __init lubbock_init(void)
+{
+	pxa_set_udc_info(&udc_info);
+	set_pxa_fb_info(&sharp_lm8v31);
+	pxa_set_mci_info(&lubbock_mci_platform_data);
+	(void) platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static struct map_desc lubbock_io_desc[] __initdata = {
+  { LUBBOCK_FPGA_VIRT, LUBBOCK_FPGA_PHYS, 0x00100000, MT_DEVICE }, /* CPLD */
+};
+
+static void __init lubbock_map_io(void)
+{
+	pxa_map_io();
+	iotable_init(lubbock_io_desc, ARRAY_SIZE(lubbock_io_desc));
+
+	/* This enables the BTUART */
+	pxa_gpio_mode(GPIO42_BTRXD_MD);
+	pxa_gpio_mode(GPIO43_BTTXD_MD);
+	pxa_gpio_mode(GPIO44_BTCTS_MD);
+	pxa_gpio_mode(GPIO45_BTRTS_MD);
+
+	/* This is for the SMC chip select */
+	pxa_gpio_mode(GPIO79_nCS_3_MD);
+
+	/* setup sleep mode values */
+	PWER  = 0x00000002;
+	PFER  = 0x00000000;
+	PRER  = 0x00000002;
+	PGSR0 = 0x00008000;
+	PGSR1 = 0x003F0202;
+	PGSR2 = 0x0001C000;
+	PCFR |= PCFR_OPDE;
+}
+
+MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)")
+	MAINTAINER("MontaVista Software Inc.")
+	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
+	MAPIO(lubbock_map_io)
+	INITIRQ(lubbock_init_irq)
+	.timer		= &pxa_timer,
+	INIT_MACHINE(lubbock_init)
+MACHINE_END
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
new file mode 100644
index 0000000..3f95223
--- /dev/null
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -0,0 +1,316 @@
+/*
+ *  linux/arch/arm/mach-pxa/mainstone.c
+ *
+ *  Support for the Intel HCDDBBVA0 Development Platform.
+ *  (go figure how they came up with such name...)
+ *
+ *  Author:	Nicolas Pitre
+ *  Created:	Nov 05, 2002
+ *  Copyright:	MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/bitops.h>
+#include <linux/fb.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/mainstone.h>
+#include <asm/arch/audio.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/mmc.h>
+
+#include "generic.h"
+
+
+static unsigned long mainstone_irq_enabled;
+
+static void mainstone_mask_irq(unsigned int irq)
+{
+	int mainstone_irq = (irq - MAINSTONE_IRQ(0));
+	MST_INTMSKENA = (mainstone_irq_enabled &= ~(1 << mainstone_irq));
+}
+
+static void mainstone_unmask_irq(unsigned int irq)
+{
+	int mainstone_irq = (irq - MAINSTONE_IRQ(0));
+	/* the irq can be acknowledged only if deasserted, so it's done here */
+	MST_INTSETCLR &= ~(1 << mainstone_irq);
+	MST_INTMSKENA = (mainstone_irq_enabled |= (1 << mainstone_irq));
+}
+
+static struct irqchip mainstone_irq_chip = {
+	.ack		= mainstone_mask_irq,
+	.mask		= mainstone_mask_irq,
+	.unmask		= mainstone_unmask_irq,
+};
+
+
+static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc,
+				  struct pt_regs *regs)
+{
+	unsigned long pending = MST_INTSETCLR & mainstone_irq_enabled;
+	do {
+		GEDR(0) = GPIO_bit(0);  /* clear useless edge notification */
+		if (likely(pending)) {
+			irq = MAINSTONE_IRQ(0) + __ffs(pending);
+			desc = irq_desc + irq;
+			desc->handle(irq, desc, regs);
+		}
+		pending = MST_INTSETCLR & mainstone_irq_enabled;
+	} while (pending);
+}
+
+static void __init mainstone_init_irq(void)
+{
+	int irq;
+
+	pxa_init_irq();
+
+	/* setup extra Mainstone irqs */
+	for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) {
+		set_irq_chip(irq, &mainstone_irq_chip);
+		set_irq_handler(irq, do_level_IRQ);
+		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+	}
+	set_irq_flags(MAINSTONE_IRQ(8), 0);
+	set_irq_flags(MAINSTONE_IRQ(12), 0);
+
+	MST_INTMSKENA = 0;
+	MST_INTSETCLR = 0;
+
+	set_irq_chained_handler(IRQ_GPIO(0), mainstone_irq_handler);
+	set_irq_type(IRQ_GPIO(0), IRQT_FALLING);
+}
+
+
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.start	= (MST_ETH_PHYS + 0x300),
+		.end	= (MST_ETH_PHYS + 0xfffff),
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= MAINSTONE_IRQ(3),
+		.end	= MAINSTONE_IRQ(3),
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(smc91x_resources),
+	.resource	= smc91x_resources,
+};
+
+static int mst_audio_startup(snd_pcm_substream_t *substream, void *priv)
+{
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF;
+	return 0;
+}
+
+static void mst_audio_shutdown(snd_pcm_substream_t *substream, void *priv)
+{
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
+}
+
+static long mst_audio_suspend_mask;
+
+static void mst_audio_suspend(void *priv)
+{
+	mst_audio_suspend_mask = MST_MSCWR2;
+	MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
+}
+
+static void mst_audio_resume(void *priv)
+{
+	MST_MSCWR2 &= mst_audio_suspend_mask | ~MST_MSCWR2_AC97_SPKROFF;
+}
+
+static pxa2xx_audio_ops_t mst_audio_ops = {
+	.startup	= mst_audio_startup,
+	.shutdown	= mst_audio_shutdown,
+	.suspend	= mst_audio_suspend,
+	.resume		= mst_audio_resume,
+};
+
+static struct platform_device mst_audio_device = {
+	.name		= "pxa2xx-ac97",
+	.id		= -1,
+	.dev		= { .platform_data = &mst_audio_ops },
+};
+
+static void mainstone_backlight_power(int on)
+{
+	if (on) {
+		pxa_gpio_mode(GPIO16_PWM0_MD);
+		pxa_set_cken(CKEN0_PWM0, 1);
+		PWM_CTRL0 = 0;
+		PWM_PWDUTY0 = 0x3ff;
+		PWM_PERVAL0 = 0x3ff;
+	} else {
+		PWM_CTRL0 = 0;
+		PWM_PWDUTY0 = 0x0;
+		PWM_PERVAL0 = 0x3FF;
+		pxa_set_cken(CKEN0_PWM0, 0);
+	}
+}
+
+static struct pxafb_mach_info toshiba_ltm04c380k __initdata = {
+	.pixclock		= 50000,
+	.xres			= 640,
+	.yres			= 480,
+	.bpp			= 16,
+	.hsync_len		= 1,
+	.left_margin		= 0x9f,
+	.right_margin		= 1,
+	.vsync_len		= 44,
+	.upper_margin		= 0,
+	.lower_margin		= 0,
+	.sync			= FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
+	.lccr0			= LCCR0_Act,
+	.lccr3			= LCCR3_PCP,
+	.pxafb_backlight_power	= mainstone_backlight_power,
+};
+
+static struct pxafb_mach_info toshiba_ltm035a776c __initdata = {
+	.pixclock		= 110000,
+	.xres			= 240,
+	.yres			= 320,
+	.bpp			= 16,
+	.hsync_len		= 4,
+	.left_margin		= 8,
+	.right_margin		= 20,
+	.vsync_len		= 3,
+	.upper_margin		= 1,
+	.lower_margin		= 10,
+	.sync			= FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
+	.lccr0			= LCCR0_Act,
+	.lccr3			= LCCR3_PCP,
+	.pxafb_backlight_power	= mainstone_backlight_power,
+};
+
+static int mainstone_mci_init(struct device *dev, irqreturn_t (*mstone_detect_int)(int, void *, struct pt_regs *), void *data)
+{
+	int err;
+
+	/*
+	 * setup GPIO for PXA27x MMC controller
+	 */
+	pxa_gpio_mode(GPIO32_MMCCLK_MD);
+	pxa_gpio_mode(GPIO112_MMCCMD_MD);
+	pxa_gpio_mode(GPIO92_MMCDAT0_MD);
+	pxa_gpio_mode(GPIO109_MMCDAT1_MD);
+	pxa_gpio_mode(GPIO110_MMCDAT2_MD);
+	pxa_gpio_mode(GPIO111_MMCDAT3_MD);
+
+	/* make sure SD/Memory Stick multiplexer's signals
+	 * are routed to MMC controller
+	 */
+	MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL;
+
+	err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, SA_INTERRUPT,
+			     "MMC card detect", data);
+	if (err) {
+		printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static void mainstone_mci_setpower(struct device *dev, unsigned int vdd)
+{
+	struct pxamci_platform_data* p_d = dev->platform_data;
+
+	if (( 1 << vdd) & p_d->ocr_mask) {
+		printk(KERN_DEBUG "%s: on\n", __FUNCTION__);
+		MST_MSCWR1 |= MST_MSCWR1_MMC_ON;
+		MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL;
+	} else {
+		printk(KERN_DEBUG "%s: off\n", __FUNCTION__);
+		MST_MSCWR1 &= ~MST_MSCWR1_MMC_ON;
+	}
+}
+
+static void mainstone_mci_exit(struct device *dev, void *data)
+{
+	free_irq(MAINSTONE_MMC_IRQ, data);
+}
+
+static struct pxamci_platform_data mainstone_mci_platform_data = {
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init 		= mainstone_mci_init,
+	.setpower 	= mainstone_mci_setpower,
+	.exit		= mainstone_mci_exit,
+};
+
+static void __init mainstone_init(void)
+{
+	/*
+	 * On Mainstone, we route AC97_SYSCLK via GPIO45 to
+	 * the audio daughter card
+	 */
+	pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD);
+
+	platform_device_register(&smc91x_device);
+	platform_device_register(&mst_audio_device);
+
+	/* reading Mainstone's "Virtual Configuration Register"
+	   might be handy to select LCD type here */
+	if (0)
+		set_pxa_fb_info(&toshiba_ltm04c380k);
+	else
+		set_pxa_fb_info(&toshiba_ltm035a776c);
+
+	pxa_set_mci_info(&mainstone_mci_platform_data);
+}
+
+
+static struct map_desc mainstone_io_desc[] __initdata = {
+  { MST_FPGA_VIRT, MST_FPGA_PHYS, 0x00100000, MT_DEVICE }, /* CPLD */
+};
+
+static void __init mainstone_map_io(void)
+{
+	pxa_map_io();
+	iotable_init(mainstone_io_desc, ARRAY_SIZE(mainstone_io_desc));
+
+	/* initialize sleep mode regs (wake-up sources, etc) */
+	PGSR0 = 0x00008800;
+	PGSR1 = 0x00000002;
+	PGSR2 = 0x0001FC00;
+	PGSR3 = 0x00001F81;
+	PWER  = 0xC0000002;
+	PRER  = 0x00000002;
+	PFER  = 0x00000002;
+}
+
+MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
+	MAINTAINER("MontaVista Software Inc.")
+	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
+	MAPIO(mainstone_map_io)
+	INITIRQ(mainstone_init_irq)
+	.timer		= &pxa_timer,
+	INIT_MACHINE(mainstone_init)
+MACHINE_END
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
new file mode 100644
index 0000000..82a4bf3
--- /dev/null
+++ b/arch/arm/mach-pxa/pm.c
@@ -0,0 +1,227 @@
+/*
+ * PXA250/210 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.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+
+#include <asm/hardware.h>
+#include <asm/memory.h>
+#include <asm/system.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/lubbock.h>
+#include <asm/mach/time.h>
+
+
+/*
+ * Debug macros
+ */
+#undef DEBUG
+
+extern void pxa_cpu_suspend(void);
+extern void pxa_cpu_resume(void);
+
+#define SAVE(x)		sleep_save[SLEEP_SAVE_##x] = x
+#define RESTORE(x)	x = sleep_save[SLEEP_SAVE_##x]
+
+#define RESTORE_GPLEVEL(n) do { \
+	GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \
+	GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \
+} while (0)
+
+/*
+ * List of global PXA peripheral registers to preserve.
+ * More ones like CP and general purpose register values are preserved
+ * with the stack pointer in sleep.S.
+ */
+enum {	SLEEP_SAVE_START = 0,
+
+	SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, SLEEP_SAVE_GPLR3,
+	SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, SLEEP_SAVE_GPDR3,
+	SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, SLEEP_SAVE_GRER3,
+	SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, SLEEP_SAVE_GFER3,
+	SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3,
+
+	SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
+	SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U,
+	SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U,
+	SLEEP_SAVE_GAFR3_L, SLEEP_SAVE_GAFR3_U,
+
+	SLEEP_SAVE_PSTR,
+
+	SLEEP_SAVE_ICMR,
+	SLEEP_SAVE_CKEN,
+
+	SLEEP_SAVE_CKSUM,
+
+	SLEEP_SAVE_SIZE
+};
+
+
+static int pxa_pm_enter(suspend_state_t state)
+{
+	unsigned long sleep_save[SLEEP_SAVE_SIZE];
+	unsigned long checksum = 0;
+	struct timespec delta, rtc;
+	int i;
+
+	if (state != PM_SUSPEND_MEM)
+		return -EINVAL;
+
+#ifdef CONFIG_IWMMXT
+	/* force any iWMMXt context to ram **/
+	iwmmxt_task_disable(NULL);
+#endif
+
+	/* preserve current time */
+	rtc.tv_sec = RCNR;
+	rtc.tv_nsec = 0;
+	save_time_delta(&delta, &rtc);
+
+	SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2);
+	SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2);
+	SAVE(GRER0); SAVE(GRER1); SAVE(GRER2);
+	SAVE(GFER0); SAVE(GFER1); SAVE(GFER2);
+	SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2);
+
+	SAVE(GAFR0_L); SAVE(GAFR0_U);
+	SAVE(GAFR1_L); SAVE(GAFR1_U);
+	SAVE(GAFR2_L); SAVE(GAFR2_U);
+
+#ifdef CONFIG_PXA27x
+	SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3);
+	SAVE(GAFR3_L); SAVE(GAFR3_U);
+#endif
+
+	SAVE(ICMR);
+	ICMR = 0;
+
+	SAVE(CKEN);
+	CKEN = 0;
+
+	SAVE(PSTR);
+
+	/* Note: wake up source are set up in each machine specific files */
+
+	/* clear GPIO transition detect  bits */
+	GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2;
+#ifdef CONFIG_PXA27x
+	GEDR3 = GEDR3;
+#endif
+
+	/* Clear sleep reset status */
+	RCSR = RCSR_SMR;
+
+	/* set resume return address */
+	PSPR = virt_to_phys(pxa_cpu_resume);
+
+	/* before sleeping, calculate and save a checksum */
+	for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
+		checksum += sleep_save[i];
+	sleep_save[SLEEP_SAVE_CKSUM] = checksum;
+
+	/* *** go zzz *** */
+	pxa_cpu_suspend();
+
+	/* after sleeping, validate the checksum */
+	checksum = 0;
+	for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
+		checksum += sleep_save[i];
+
+	/* if invalid, display message and wait for a hardware reset */
+	if (checksum != sleep_save[SLEEP_SAVE_CKSUM]) {
+#ifdef CONFIG_ARCH_LUBBOCK
+		LUB_HEXLED = 0xbadbadc5;
+#endif
+		while (1)
+			pxa_cpu_suspend();
+	}
+
+	/* ensure not to come back here if it wasn't intended */
+	PSPR = 0;
+
+	/* restore registers */
+	RESTORE(GAFR0_L); RESTORE(GAFR0_U);
+	RESTORE(GAFR1_L); RESTORE(GAFR1_U);
+	RESTORE(GAFR2_L); RESTORE(GAFR2_U);
+	RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2);
+	RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2);
+	RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2);
+	RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2);
+	RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
+
+#ifdef CONFIG_PXA27x
+	RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3);
+	RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3);
+#endif
+
+	PSSR = PSSR_RDH | PSSR_PH;
+
+	RESTORE(CKEN);
+
+	ICLR = 0;
+	ICCR = 1;
+	RESTORE(ICMR);
+
+	RESTORE(PSTR);
+
+	/* restore current time */
+	rtc.tv_sec = RCNR;
+	restore_time_delta(&delta, &rtc);
+
+#ifdef DEBUG
+	printk(KERN_DEBUG "*** made it back from resume\n");
+#endif
+
+	return 0;
+}
+
+unsigned long sleep_phys_sp(void *sp)
+{
+	return virt_to_phys(sp);
+}
+
+/*
+ * Called after processes are frozen, but before we shut down devices.
+ */
+static int pxa_pm_prepare(suspend_state_t state)
+{
+	return 0;
+}
+
+/*
+ * Called after devices are re-setup, but before processes are thawed.
+ */
+static int pxa_pm_finish(suspend_state_t state)
+{
+	return 0;
+}
+
+/*
+ * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
+ */
+static struct pm_ops pxa_pm_ops = {
+	.pm_disk_mode	= PM_DISK_FIRMWARE,
+	.prepare	= pxa_pm_prepare,
+	.enter		= pxa_pm_enter,
+	.finish		= pxa_pm_finish,
+};
+
+static int __init pxa_pm_init(void)
+{
+	pm_set_ops(&pxa_pm_ops);
+	return 0;
+}
+
+late_initcall(pxa_pm_init);
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
new file mode 100644
index 0000000..b6c746e
--- /dev/null
+++ b/arch/arm/mach-pxa/poodle.c
@@ -0,0 +1,189 @@
+/*
+ * linux/arch/arm/mach-pxa/poodle.c
+ *
+ *  Support for the SHARP Poodle Board.
+ *
+ * Based on:
+ *  linux/arch/arm/mach-pxa/lubbock.c Author:	Nicolas Pitre
+ *
+ *  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.
+ *
+ * Change Log
+ *  12-Dec-2002 Sharp Corporation for Poodle
+ *  John Lenz <lenz@cs.wisc.edu> updates to 2.6
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/fb.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/irq.h>
+#include <asm/arch/poodle.h>
+#include <asm/arch/pxafb.h>
+
+#include <asm/hardware/scoop.h>
+#include <asm/hardware/locomo.h>
+#include <asm/mach/sharpsl_param.h>
+
+#include "generic.h"
+
+static struct resource poodle_scoop_resources[] = {
+	[0] = {
+		.start		= 0x10800000,
+		.end		= 0x10800fff,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct scoop_config poodle_scoop_setup = {
+	.io_dir		= POODLE_SCOOP_IO_DIR,
+	.io_out		= POODLE_SCOOP_IO_OUT,
+};
+
+struct platform_device poodle_scoop_device = {
+	.name		= "sharp-scoop",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &poodle_scoop_setup,
+	},
+	.num_resources	= ARRAY_SIZE(poodle_scoop_resources),
+	.resource	= poodle_scoop_resources,
+};
+
+
+/* LoCoMo device */
+static struct resource locomo_resources[] = {
+	[0] = {
+		.start		= 0x10000000,
+		.end		= 0x10001fff,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= IRQ_GPIO(10),
+		.end		= IRQ_GPIO(10),
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device locomo_device = {
+	.name		= "locomo",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(locomo_resources),
+	.resource	= locomo_resources,
+};
+
+/* PXAFB device */
+static struct pxafb_mach_info poodle_fb_info __initdata = {
+	.pixclock	= 144700,
+
+	.xres		= 320,
+	.yres		= 240,
+	.bpp		= 16,
+
+	.hsync_len	= 7,
+	.left_margin	= 11,
+	.right_margin	= 30,
+
+	.vsync_len	= 2,
+	.upper_margin	= 2,
+	.lower_margin	= 0,
+	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+	.lccr0		= LCCR0_Act | LCCR0_Sngl | LCCR0_Color,
+	.lccr3		= 0,
+
+	.pxafb_backlight_power	= NULL,
+	.pxafb_lcd_power	= NULL,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&locomo_device,
+	&poodle_scoop_device,
+};
+
+static void __init poodle_init(void)
+{
+	int ret = 0;
+
+	/* cpu initialize */
+	/* Pgsr Register */
+  	PGSR0 = 0x0146dd80;
+  	PGSR1 = 0x03bf0890;
+  	PGSR2 = 0x0001c000;
+
+	/* Alternate Register */
+  	GAFR0_L = 0x01001000;
+  	GAFR0_U = 0x591a8010;
+  	GAFR1_L = 0x900a8451;
+  	GAFR1_U = 0xaaa5aaaa;
+  	GAFR2_L = 0x8aaaaaaa;
+  	GAFR2_U = 0x00000002;
+
+	/* Direction Register */
+  	GPDR0 = 0xd3f0904c;
+  	GPDR1 = 0xfcffb7d3;
+  	GPDR2 = 0x0001ffff;
+
+	/* Output Register */
+  	GPCR0 = 0x00000000;
+  	GPCR1 = 0x00000000;
+  	GPCR2 = 0x00000000;
+
+  	GPSR0 = 0x00400000;
+  	GPSR1 = 0x00000000;
+        GPSR2 = 0x00000000;
+
+	set_pxa_fb_info(&poodle_fb_info);
+
+	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+	if (ret) {
+		printk(KERN_WARNING "poodle: Unable to register LoCoMo device\n");
+	}
+}
+
+static void __init fixup_poodle(struct machine_desc *desc,
+		struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+	sharpsl_save_param();
+}
+
+static struct map_desc poodle_io_desc[] __initdata = {
+ /* virtual     physical    length                   */
+  { 0xef800000, 0x00000000, 0x00800000, MT_DEVICE }, /* Boot Flash */
+};
+
+static void __init poodle_map_io(void)
+{
+	pxa_map_io();
+	iotable_init(poodle_io_desc, ARRAY_SIZE(poodle_io_desc));
+
+	/* setup sleep mode values */
+	PWER  = 0x00000002;
+	PFER  = 0x00000000;
+	PRER  = 0x00000002;
+	PGSR0 = 0x00008000;
+	PGSR1 = 0x003F0202;
+	PGSR2 = 0x0001C000;
+	PCFR |= PCFR_OPDE;
+}
+
+MACHINE_START(POODLE, "SHARP Poodle")
+	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
+	FIXUP(fixup_poodle)
+	MAPIO(poodle_map_io)
+	INITIRQ(pxa_init_irq)
+	.timer = &pxa_timer,
+	.init_machine = poodle_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
new file mode 100644
index 0000000..e887b71
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -0,0 +1,104 @@
+/*
+ *  linux/arch/arm/mach-pxa/pxa25x.c
+ *
+ *  Author:	Nicolas Pitre
+ *  Created:	Jun 15, 2001
+ *  Copyright:	MontaVista Software Inc.
+ *
+ * Code specific to PXA21x/25x/26x variants.
+ *
+ * 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.
+ *
+ * Since this file should be linked before any other machine specific file,
+ * the __initcall() here will be executed first.  This serves as default
+ * initialization stuff for PXA machines which can be overridden later if
+ * need be.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/pxa-regs.h>
+
+#include "generic.h"
+
+/*
+ * Various clock factors driven by the CCCR register.
+ */
+
+/* Crystal Frequency to Memory Frequency Multiplier (L) */
+static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, };
+
+/* Memory Frequency to Run Mode Frequency Multiplier (M) */
+static unsigned char M_clk_mult[4] = { 0, 1, 2, 4 };
+
+/* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */
+/* Note: we store the value N * 2 here. */
+static unsigned char N2_clk_mult[8] = { 0, 0, 2, 3, 4, 0, 6, 0 };
+
+/* Crystal clock */
+#define BASE_CLK	3686400
+
+/*
+ * Get the clock frequency as reflected by CCCR and the turbo flag.
+ * We assume these values have been applied via a fcs.
+ * If info is not 0 we also display the current settings.
+ */
+unsigned int get_clk_frequency_khz(int info)
+{
+	unsigned long cccr, turbo;
+	unsigned int l, L, m, M, n2, N;
+
+	cccr = CCCR;
+	asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (turbo) );
+
+	l  =  L_clk_mult[(cccr >> 0) & 0x1f];
+	m  =  M_clk_mult[(cccr >> 5) & 0x03];
+	n2 = N2_clk_mult[(cccr >> 7) & 0x07];
+
+	L = l * BASE_CLK;
+	M = m * L;
+	N = n2 * M / 2;
+
+	if(info)
+	{
+		L += 5000;
+		printk( KERN_INFO "Memory clock: %d.%02dMHz (*%d)\n",
+			L / 1000000, (L % 1000000) / 10000, l );
+		M += 5000;
+		printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n",
+			M / 1000000, (M % 1000000) / 10000, m );
+		N += 5000;
+		printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n",
+			N / 1000000, (N % 1000000) / 10000, n2 / 2, (n2 % 2) * 5,
+			(turbo & 1) ? "" : "in" );
+	}
+
+	return (turbo & 1) ? (N/1000) : (M/1000);
+}
+
+EXPORT_SYMBOL(get_clk_frequency_khz);
+
+/*
+ * Return the current memory clock frequency in units of 10kHz
+ */
+unsigned int get_memclk_frequency_10khz(void)
+{
+	return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK / 10000;
+}
+
+EXPORT_SYMBOL(get_memclk_frequency_10khz);
+
+/*
+ * Return the current LCD clock frequency in units of 10kHz
+ */
+unsigned int get_lcdclk_frequency_10khz(void)
+{
+	return get_memclk_frequency_10khz();
+}
+
+EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
new file mode 100644
index 0000000..7e863af
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -0,0 +1,163 @@
+/*
+ *  linux/arch/arm/mach-pxa/pxa27x.c
+ *
+ *  Author:	Nicolas Pitre
+ *  Created:	Nov 05, 2002
+ *  Copyright:	MontaVista Software Inc.
+ *
+ * Code specific to PXA27x aka Bulverde.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/pxa-regs.h>
+
+#include "generic.h"
+
+/* Crystal clock: 13MHz */
+#define BASE_CLK	13000000
+
+/*
+ * Get the clock frequency as reflected by CCSR and the turbo flag.
+ * We assume these values have been applied via a fcs.
+ * If info is not 0 we also display the current settings.
+ */
+unsigned int get_clk_frequency_khz( int info)
+{
+	unsigned long ccsr, clkcfg;
+	unsigned int l, L, m, M, n2, N, S;
+       	int cccr_a, t, ht, b;
+
+	ccsr = CCSR;
+	cccr_a = CCCR & (1 << 25);
+
+	/* Read clkcfg register: it has turbo, b, half-turbo (and f) */
+	asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) );
+	t  = clkcfg & (1 << 1);
+	ht = clkcfg & (1 << 2);
+	b  = clkcfg & (1 << 3);
+
+	l  = ccsr & 0x1f;
+	n2 = (ccsr>>7) & 0xf;
+	m  = (l <= 10) ? 1 : (l <= 20) ? 2 : 4;
+
+	L  = l * BASE_CLK;
+	N  = (L * n2) / 2;
+	M  = (!cccr_a) ? (L/m) : ((b) ? L : (L/2));
+	S  = (b) ? L : (L/2);
+
+	if (info) {
+		printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n",
+			L / 1000000, (L % 1000000) / 10000, l );
+		printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n",
+			N / 1000000, (N % 1000000)/10000, n2 / 2, (n2 % 2)*5,
+			(t) ? "" : "in" );
+		printk( KERN_INFO "Memory clock: %d.%02dMHz (/%d)\n",
+			M / 1000000, (M % 1000000) / 10000, m );
+		printk( KERN_INFO "System bus clock: %d.%02dMHz \n",
+			S / 1000000, (S % 1000000) / 10000 );
+	}
+
+	return (t) ? (N/1000) : (L/1000);
+}
+
+/*
+ * Return the current mem clock frequency in units of 10kHz as
+ * reflected by CCCR[A], B, and L
+ */
+unsigned int get_memclk_frequency_10khz(void)
+{
+	unsigned long ccsr, clkcfg;
+	unsigned int l, L, m, M;
+       	int cccr_a, b;
+
+	ccsr = CCSR;
+	cccr_a = CCCR & (1 << 25);
+
+	/* Read clkcfg register: it has turbo, b, half-turbo (and f) */
+	asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) );
+	b = clkcfg & (1 << 3);
+
+	l = ccsr & 0x1f;
+	m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4;
+
+	L = l * BASE_CLK;
+	M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2));
+
+	return (M / 10000);
+}
+
+/*
+ * Return the current LCD clock frequency in units of 10kHz as
+ */
+unsigned int get_lcdclk_frequency_10khz(void)
+{
+	unsigned long ccsr;
+	unsigned int l, L, k, K;
+
+	ccsr = CCSR;
+
+	l = ccsr & 0x1f;
+	k = (l <= 7) ? 1 : (l <= 16) ? 2 : 4;
+
+	L = l * BASE_CLK;
+	K = L / k;
+
+	return (K / 10000);
+}
+
+EXPORT_SYMBOL(get_clk_frequency_khz);
+EXPORT_SYMBOL(get_memclk_frequency_10khz);
+EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
+
+
+/*
+ * device registration specific to PXA27x.
+ */
+
+static u64 pxa27x_dmamask = 0xffffffffUL;
+
+static struct resource pxa27x_ohci_resources[] = {
+	[0] = {
+		.start  = 0x4C000000,
+		.end    = 0x4C00ff6f,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = IRQ_USBH1,
+		.end    = IRQ_USBH1,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ohci_device = {
+	.name		= "pxa27x-ohci",
+	.id		= -1,
+	.dev		= {
+		.dma_mask = &pxa27x_dmamask,
+		.coherent_dma_mask = 0xffffffff,
+	},
+	.num_resources  = ARRAY_SIZE(pxa27x_ohci_resources),
+	.resource       = pxa27x_ohci_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&ohci_device,
+};
+
+static int __init pxa27x_init(void)
+{
+	return platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+subsys_initcall(pxa27x_init);
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
new file mode 100644
index 0000000..16cad2c
--- /dev/null
+++ b/arch/arm/mach-pxa/sleep.S
@@ -0,0 +1,194 @@
+/*
+ * Low-level PXA250/210 sleep/wakeUp support
+ *
+ * Initial SA1110 code:
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * Adapted for PXA by Nicolas Pitre:
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/pxa-regs.h>
+
+		.text
+
+/*
+ * pxa_cpu_suspend()
+ *
+ * Forces CPU into sleep state
+ */
+
+ENTRY(pxa_cpu_suspend)
+
+	mra	r2, r3, acc0
+	stmfd	sp!, {r2 - r12, lr}		@ save registers on stack
+
+	@ get coprocessor registers
+	mrc	p14, 0, r3, c6, c0, 0		@ clock configuration, for turbo mode
+	mrc	p15, 0, r4, c15, c1, 0		@ CP access reg
+	mrc	p15, 0, r5, c13, c0, 0		@ PID
+	mrc 	p15, 0, r6, c3, c0, 0		@ domain ID
+	mrc 	p15, 0, r7, c2, c0, 0		@ translation table base addr
+	mrc	p15, 0, r8, c1, c1, 0           @ auxiliary control reg
+	mrc 	p15, 0, r9, c1, c0, 0		@ control reg
+
+	bic	r3, r3, #2			@ clear frequency change bit
+
+	@ store them plus current virtual stack ptr on stack
+	mov	r10, sp
+	stmfd	sp!, {r3 - r10}
+
+	@ preserve phys address of stack
+	mov	r0, sp
+	bl	sleep_phys_sp
+	ldr	r1, =sleep_save_sp
+	str	r0, [r1]
+
+	@ clean data cache
+	bl	xscale_flush_kern_cache_all
+
+	@ Put the processor to sleep
+	@ (also workaround for sighting 28071)
+
+	@ prepare value for sleep mode
+	mov	r1, #3				@ sleep mode
+
+	@ prepare to put SDRAM into self-refresh manually
+	ldr	r4, =MDREFR
+	ldr	r5, [r4]
+	orr	r5, r5, #MDREFR_SLFRSH
+
+	@ prepare pointer to physical address 0 (virtual mapping in generic.c)
+	mov	r2, #UNCACHED_PHYS_0
+
+	@ Intel PXA255 Specification Update notes problems
+	@ about suspending with PXBus operating above 133MHz
+	@ (see Errata 31, GPIO output signals, ... unpredictable in sleep
+	@
+	@ We keep the change-down close to the actual suspend on SDRAM
+	@ as possible to eliminate messing about with the refresh clock
+	@ as the system will restore with the original speed settings
+	@
+	@ Ben Dooks, 13-Sep-2004
+
+	ldr	r6, =CCCR
+	ldr	r8, [r6]		@ keep original value for resume
+
+	@ ensure x1 for run and turbo mode with memory clock
+	bic	r7, r8, #CCCR_M_MASK | CCCR_N_MASK
+	orr	r7, r7, #(1<<5) | (2<<7)
+
+	@ check that the memory frequency is within limits
+	and	r14, r7, #CCCR_L_MASK
+	teq	r14, #1
+	bicne	r7, r7, #CCCR_L_MASK
+	orrne	r7, r7, #1			@@ 99.53MHz
+
+	@ get ready for the change
+
+	@ note, turbo is not preserved over sleep so there is no
+	@ point in preserving it here. we save it on the stack with the
+	@ other CP registers instead.
+	mov	r0, #0
+	mcr	p14, 0, r0, c6, c0, 0
+	orr	r0, r0, #2			@ initiate change bit
+
+	@ align execution to a cache line
+	b	1f
+
+	.ltorg
+	.align	5
+1:
+
+	@ All needed values are now in registers.
+	@ These last instructions should be in cache
+
+	@ initiate the frequency change...
+	str	r7, [r6]
+	mcr	p14, 0, r0, c6, c0, 0
+
+	@ restore the original cpu speed value for resume
+	str	r8, [r6]
+
+	@ put SDRAM into self-refresh
+	str	r5, [r4]
+
+	@ force address lines low by reading at physical address 0
+	ldr	r3, [r2]
+
+	@ enter sleep mode
+	mcr	p14, 0, r1, c7, c0, 0
+
+20:	b	20b				@ loop waiting for sleep
+
+/*
+ * cpu_pxa_resume()
+ *
+ * entry point from bootloader into kernel during resume
+ *
+ * Note: Yes, part of the following code is located into the .data section.
+ *       This is to allow sleep_save_sp to be accessed with a relative load
+ *       while we can't rely on any MMU translation.  We could have put
+ *       sleep_save_sp in the .text section as well, but some setups might
+ *       insist on it to be truly read-only.
+ */
+
+	.data
+	.align 5
+ENTRY(pxa_cpu_resume)
+	mov	r0, #PSR_I_BIT | PSR_F_BIT | MODE_SVC	@ set SVC, irqs off
+	msr	cpsr_c, r0
+
+	ldr	r0, sleep_save_sp		@ stack phys addr
+	ldr	r2, =resume_after_mmu		@ its absolute virtual address
+	ldmfd	r0, {r3 - r9, sp}		@ CP regs + virt stack ptr
+
+	mov	r1, #0
+	mcr	p15, 0, r1, c8, c7, 0   	@ invalidate I & D TLBs
+	mcr	p15, 0, r1, c7, c7, 0		@ invalidate I & D caches, BTB
+
+#ifdef CONFIG_XSCALE_CACHE_ERRATA
+	bic     r9, r9, #0x0004			@ see cpu_xscale_proc_init
+#endif
+
+	mcr	p14, 0, r3, c6, c0, 0		@ clock configuration, turbo mode.
+	mcr	p15, 0, r4, c15, c1, 0		@ CP access reg
+	mcr	p15, 0, r5, c13, c0, 0		@ PID
+	mcr 	p15, 0, r6, c3, c0, 0		@ domain ID
+	mcr 	p15, 0, r7, c2, c0, 0		@ translation table base addr
+	mcr	p15, 0, r8, c1, c1, 0           @ auxiliary control reg
+	b	resume_turn_on_mmu		@ cache align execution
+
+	.align 5
+resume_turn_on_mmu:
+	mcr 	p15, 0, r9, c1, c0, 0		@ turn on MMU, caches, etc.
+
+	@ Let us ensure we jump to resume_after_mmu only when the mcr above
+	@ actually took effect.  They call it the "cpwait" operation.
+	mrc	p15, 0, r1, c2, c0, 0		@ queue a dependency on CP15
+	sub	pc, r2, r1, lsr #32		@ jump to virtual addr
+	nop
+	nop
+	nop
+
+sleep_save_sp:
+	.word	0				@ preserve stack phys ptr here
+
+	.text
+resume_after_mmu:
+#ifdef CONFIG_XSCALE_CACHE_ERRATA
+	bl	cpu_xscale_proc_init
+#endif
+	ldmfd	sp!, {r2, r3}
+	mar	acc0, r2, r3
+	ldmfd	sp!, {r4 - r12, pc}		@ return to caller
+
+
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
new file mode 100644
index 0000000..4d826c0
--- /dev/null
+++ b/arch/arm/mach-pxa/ssp.c
@@ -0,0 +1,363 @@
+/*
+ *  linux/arch/arm/mach-pxa/ssp.c
+ *
+ *  based on linux/arch/arm/mach-sa1100/ssp.c by Russell King
+ *
+ *  Copyright (C) 2003 Russell King.
+ *  Copyright (C) 2003 Wolfson Microelectronics PLC
+ *
+ * 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.
+ *
+ *  PXA2xx SSP driver.  This provides the generic core for simple
+ *  IO-based SSP applications and allows easy port setup for DMA access.
+ *
+ *  Author: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+ *
+ *  Revision history:
+ *   22nd Aug 2003 Initial version.
+ *   20th Dec 2004 Added ssp_config for changing port config without
+ *                 closing the port.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/arch/ssp.h>
+#include <asm/arch/pxa-regs.h>
+
+#define PXA_SSP_PORTS 	3
+
+static DECLARE_MUTEX(sem);
+static int use_count[PXA_SSP_PORTS] = {0, 0, 0};
+
+static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct ssp_dev *dev = (struct ssp_dev*) dev_id;
+	unsigned int status = SSSR_P(dev->port);
+
+	SSSR_P(dev->port) = status; /* clear status bits */
+
+	if (status & SSSR_ROR)
+		printk(KERN_WARNING "SSP(%d): receiver overrun\n", dev->port);
+
+	if (status & SSSR_TUR)
+		printk(KERN_WARNING "SSP(%d): transmitter underrun\n", dev->port);
+
+	if (status & SSSR_BCE)
+		printk(KERN_WARNING "SSP(%d): bit count error\n", dev->port);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * ssp_write_word - write a word to the SSP port
+ * @data: 32-bit, MSB justified data to write.
+ *
+ * Wait for a free entry in the SSP transmit FIFO, and write a data
+ * word to the SSP port.
+ *
+ * The caller is expected to perform the necessary locking.
+ *
+ * Returns:
+ *   %-ETIMEDOUT	timeout occurred (for future)
+ *   0			success
+ */
+int ssp_write_word(struct ssp_dev *dev, u32 data)
+{
+	while (!(SSSR_P(dev->port) & SSSR_TNF))
+		cpu_relax();
+
+	SSDR_P(dev->port) = data;
+
+	return 0;
+}
+
+/**
+ * ssp_read_word - read a word from the SSP port
+ *
+ * Wait for a data word in the SSP receive FIFO, and return the
+ * received data.  Data is LSB justified.
+ *
+ * Note: Currently, if data is not expected to be received, this
+ * function will wait for ever.
+ *
+ * The caller is expected to perform the necessary locking.
+ *
+ * Returns:
+ *   %-ETIMEDOUT	timeout occurred (for future)
+ *   32-bit data	success
+ */
+int ssp_read_word(struct ssp_dev *dev)
+{
+	while (!(SSSR_P(dev->port) & SSSR_RNE))
+		cpu_relax();
+
+	return SSDR_P(dev->port);
+}
+
+/**
+ * ssp_flush - flush the transmit and receive FIFOs
+ *
+ * Wait for the SSP to idle, and ensure that the receive FIFO
+ * is empty.
+ *
+ * The caller is expected to perform the necessary locking.
+ */
+void ssp_flush(struct ssp_dev *dev)
+{
+	do {
+		while (SSSR_P(dev->port) & SSSR_RNE) {
+			(void) SSDR_P(dev->port);
+		}
+	} while (SSSR_P(dev->port) & SSSR_BSY);
+}
+
+/**
+ * ssp_enable - enable the SSP port
+ *
+ * Turn on the SSP port.
+ */
+void ssp_enable(struct ssp_dev *dev)
+{
+	SSCR0_P(dev->port) |= SSCR0_SSE;
+}
+
+/**
+ * ssp_disable - shut down the SSP port
+ *
+ * Turn off the SSP port, optionally powering it down.
+ */
+void ssp_disable(struct ssp_dev *dev)
+{
+	SSCR0_P(dev->port) &= ~SSCR0_SSE;
+}
+
+/**
+ * ssp_save_state - save the SSP configuration
+ * @ssp: pointer to structure to save SSP configuration
+ *
+ * Save the configured SSP state for suspend.
+ */
+void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp)
+{
+	ssp->cr0 = SSCR0_P(dev->port);
+	ssp->cr1 = SSCR1_P(dev->port);
+	ssp->to = SSTO_P(dev->port);
+	ssp->psp = SSPSP_P(dev->port);
+
+	SSCR0_P(dev->port) &= ~SSCR0_SSE;
+}
+
+/**
+ * ssp_restore_state - restore a previously saved SSP configuration
+ * @ssp: pointer to configuration saved by ssp_save_state
+ *
+ * Restore the SSP configuration saved previously by ssp_save_state.
+ */
+void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp)
+{
+	SSSR_P(dev->port) = SSSR_ROR | SSSR_TUR | SSSR_BCE;
+
+	SSCR0_P(dev->port) = ssp->cr0 & ~SSCR0_SSE;
+	SSCR1_P(dev->port) = ssp->cr1;
+	SSTO_P(dev->port) = ssp->to;
+	SSPSP_P(dev->port) = ssp->psp;
+
+	SSCR0_P(dev->port) = ssp->cr0;
+}
+
+/**
+ * ssp_config - configure SSP port settings
+ * @mode: port operating mode
+ * @flags: port config flags
+ * @psp_flags: port PSP config flags
+ * @speed: port speed
+ *
+ * Port MUST be disabled by ssp_disable before making any config changes.
+ */
+int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed)
+{
+	dev->mode = mode;
+	dev->flags = flags;
+	dev->psp_flags = psp_flags;
+	dev->speed = speed;
+
+	/* set up port type, speed, port settings */
+	SSCR0_P(dev->port) = (dev->speed | dev->mode);
+	SSCR1_P(dev->port) = dev->flags;
+	SSPSP_P(dev->port) = dev->psp_flags;
+
+	return 0;
+}
+
+/**
+ * ssp_init - setup the SSP port
+ *
+ * initialise and claim resources for the SSP port.
+ *
+ * Returns:
+ *   %-ENODEV	if the SSP port is unavailable
+ *   %-EBUSY	if the resources are already in use
+ *   %0		on success
+ */
+int ssp_init(struct ssp_dev *dev, u32 port)
+{
+	int ret, irq;
+
+	if (port > PXA_SSP_PORTS || port == 0)
+		return -ENODEV;
+
+	down(&sem);
+	if (use_count[port - 1]) {
+		up(&sem);
+		return -EBUSY;
+	}
+	use_count[port - 1]++;
+
+	if (!request_mem_region(__PREG(SSCR0_P(port)), 0x2c, "SSP")) {
+		use_count[port - 1]--;
+		up(&sem);
+		return -EBUSY;
+	}
+
+	switch (port) {
+		case 1:
+			irq = IRQ_SSP;
+			break;
+#if defined (CONFIG_PXA27x)
+		case 2:
+			irq = IRQ_SSP2;
+			break;
+		case 3:
+			irq = IRQ_SSP3;
+			break;
+#else
+		case 2:
+			irq = IRQ_NSSP;
+			break;
+		case 3:
+			irq = IRQ_ASSP;
+			break;
+#endif
+		default:
+			return -ENODEV;
+	}
+
+	dev->port = port;
+
+	ret = request_irq(irq, ssp_interrupt, 0, "SSP", dev);
+	if (ret)
+		goto out_region;
+
+	/* turn on SSP port clock */
+	switch (dev->port) {
+#if defined (CONFIG_PXA27x)
+		case 1:
+			pxa_set_cken(CKEN23_SSP1, 1);
+			break;
+		case 2:
+			pxa_set_cken(CKEN3_SSP2, 1);
+			break;
+		case 3:
+			pxa_set_cken(CKEN4_SSP3, 1);
+			break;
+#else
+		case 1:
+			pxa_set_cken(CKEN3_SSP, 1);
+			break;
+		case 2:
+			pxa_set_cken(CKEN9_NSSP, 1);
+			break;
+		case 3:
+			pxa_set_cken(CKEN10_ASSP, 1);
+			break;
+#endif
+	}
+
+	up(&sem);
+	return 0;
+
+out_region:
+	release_mem_region(__PREG(SSCR0_P(port)), 0x2c);
+	use_count[port - 1]--;
+	up(&sem);
+	return ret;
+}
+
+/**
+ * ssp_exit - undo the effects of ssp_init
+ *
+ * release and free resources for the SSP port.
+ */
+void ssp_exit(struct ssp_dev *dev)
+{
+	int irq;
+
+	down(&sem);
+	SSCR0_P(dev->port) &= ~SSCR0_SSE;
+
+	/* find irq, save power and turn off SSP port clock */
+	switch (dev->port) {
+#if defined (CONFIG_PXA27x)
+		case 1:
+			irq = IRQ_SSP;
+			pxa_set_cken(CKEN23_SSP1, 0);
+			break;
+		case 2:
+			irq = IRQ_SSP2;
+			pxa_set_cken(CKEN3_SSP2, 0);
+			break;
+		case 3:
+			irq = IRQ_SSP3;
+			pxa_set_cken(CKEN4_SSP3, 0);
+			break;
+#else
+		case 1:
+			irq = IRQ_SSP;
+			pxa_set_cken(CKEN3_SSP, 0);
+			break;
+		case 2:
+			irq = IRQ_NSSP;
+			pxa_set_cken(CKEN9_NSSP, 0);
+			break;
+		case 3:
+			irq = IRQ_ASSP;
+			pxa_set_cken(CKEN10_ASSP, 0);
+			break;
+#endif
+		default:
+			printk(KERN_WARNING "SSP: tried to close invalid port\n");
+			return;
+	}
+
+	free_irq(irq, dev);
+	release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c);
+	use_count[dev->port - 1]--;
+	up(&sem);
+}
+
+EXPORT_SYMBOL(ssp_write_word);
+EXPORT_SYMBOL(ssp_read_word);
+EXPORT_SYMBOL(ssp_flush);
+EXPORT_SYMBOL(ssp_enable);
+EXPORT_SYMBOL(ssp_disable);
+EXPORT_SYMBOL(ssp_save_state);
+EXPORT_SYMBOL(ssp_restore_state);
+EXPORT_SYMBOL(ssp_init);
+EXPORT_SYMBOL(ssp_exit);
+EXPORT_SYMBOL(ssp_config);
+
+MODULE_DESCRIPTION("PXA SSP driver");
+MODULE_AUTHOR("Liam Girdwood");
+MODULE_LICENSE("GPL");
+
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
new file mode 100644
index 0000000..473fb61
--- /dev/null
+++ b/arch/arm/mach-pxa/time.c
@@ -0,0 +1,164 @@
+/*
+ * arch/arm/mach-pxa/time.c
+ *
+ * Author:	Nicolas Pitre
+ * Created:	Jun 15, 2001
+ * Copyright:	MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/sched.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>
+#include <asm/arch/pxa-regs.h>
+
+
+static inline unsigned long pxa_get_rtc_time(void)
+{
+	return RCNR;
+}
+
+static int pxa_set_rtc(void)
+{
+	unsigned long current_time = xtime.tv_sec;
+
+	if (RTSR & RTSR_ALE) {
+		/* make sure not to forward the clock over an alarm */
+		unsigned long alarm = RTAR;
+		if (current_time >= alarm && alarm >= RCNR)
+			return -ERESTARTSYS;
+	}
+	RCNR = current_time;
+	return 0;
+}
+
+/* IRQs are disabled before entering here from do_gettimeofday() */
+static unsigned long pxa_gettimeoffset (void)
+{
+	long ticks_to_match, elapsed, usec;
+
+	/* Get ticks before next timer match */
+	ticks_to_match = OSMR0 - OSCR;
+
+	/* We need elapsed ticks since last match */
+	elapsed = LATCH - ticks_to_match;
+
+	/* don't get fooled by the workaround in pxa_timer_interrupt() */
+	if (elapsed <= 0)
+		return 0;
+
+	/* Now convert them to usec */
+	usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
+
+	return usec;
+}
+
+static irqreturn_t
+pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int next_match;
+
+	write_seqlock(&xtime_lock);
+
+	/* Loop until we get ahead of the free running timer.
+	 * This ensures an exact clock tick count and time accuracy.
+	 * IRQs are disabled inside the loop to ensure coherence between
+	 * lost_ticks (updated in do_timer()) and the match reg value, so we
+	 * can use do_gettimeofday() from interrupt handlers.
+	 *
+	 * HACK ALERT: it seems that the PXA timer regs aren't updated right
+	 * away in all cases when a write occurs.  We therefore compare with
+	 * 8 instead of 0 in the while() condition below to avoid missing a
+	 * match if OSCR has already reached the next OSMR value.
+	 * Experience has shown that up to 6 ticks are needed to work around
+	 * this problem, but let's use 8 to be conservative.  Note that this
+	 * affect things only when the timer IRQ has been delayed by nearly
+	 * exactly one tick period which should be a pretty rare event.
+	 */
+	do {
+		timer_tick(regs);
+		OSSR = OSSR_M0;  /* Clear match on timer 0 */
+		next_match = (OSMR0 += LATCH);
+	} while( (signed long)(next_match - OSCR) <= 8 );
+
+	write_sequnlock(&xtime_lock);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction pxa_timer_irq = {
+	.name		= "PXA Timer Tick",
+	.flags		= SA_INTERRUPT,
+	.handler	= pxa_timer_interrupt
+};
+
+static void __init pxa_timer_init(void)
+{
+	struct timespec tv;
+
+	set_rtc = pxa_set_rtc;
+
+	tv.tv_nsec = 0;
+	tv.tv_sec = pxa_get_rtc_time();
+	do_settimeofday(&tv);
+
+	OSMR0 = 0;		/* set initial match at 0 */
+	OSSR = 0xf;		/* clear status on all timers */
+	setup_irq(IRQ_OST0, &pxa_timer_irq);
+	OIER |= OIER_E0;	/* enable match on timer 0 to cause interrupts */
+	OSCR = 0;		/* initialize free-running timer, force first match */
+}
+
+#ifdef CONFIG_PM
+static unsigned long osmr[4], oier;
+
+static void pxa_timer_suspend(void)
+{
+	osmr[0] = OSMR0;
+	osmr[1] = OSMR1;
+	osmr[2] = OSMR2;
+	osmr[3] = OSMR3;
+	oier = OIER;
+}
+
+static void pxa_timer_resume(void)
+{
+	OSMR0 = osmr[0];
+	OSMR1 = osmr[1];
+	OSMR2 = osmr[2];
+	OSMR3 = osmr[3];
+	OIER = oier;
+
+	/*
+	 * OSMR0 is the system timer: make sure OSCR is sufficiently behind
+	 */
+	OSCR = OSMR0 - LATCH;
+}
+#else
+#define pxa_timer_suspend NULL
+#define pxa_timer_resume NULL
+#endif
+
+struct sys_timer pxa_timer = {
+	.init		= pxa_timer_init,
+	.suspend	= pxa_timer_suspend,
+	.resume		= pxa_timer_resume,
+	.offset		= pxa_gettimeoffset,
+};