summary refs log tree commit diff
path: root/arch/arm
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2008-10-22 19:34:09 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-10-22 19:34:09 +0100
commitf20e3b5fe7ead0615309433260b9784d8da0bbbd (patch)
treeeabb2e47a0355ac4e8024b7087b4e7cb9f324358 /arch/arm
parentbcbfe664e7af019e698cef2feb85ac2b4f1ac11d (diff)
parentf030d7b65e4e6399f23de2a41a58d1b607b6bd89 (diff)
downloadlinux-f20e3b5fe7ead0615309433260b9784d8da0bbbd.tar.gz
Merge branch 'for-rmk' of git://git.android.com/kernel into devel
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig11
-rw-r--r--arch/arm/Makefile2
-rw-r--r--arch/arm/configs/msm_defconfig2
-rw-r--r--arch/arm/mach-iop13xx/include/mach/time.h4
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x00.c4
-rw-r--r--arch/arm/mach-msm/Kconfig17
-rw-r--r--arch/arm/mach-msm/Makefile7
-rw-r--r--arch/arm/mach-msm/board-halibut.c38
-rw-r--r--arch/arm/mach-msm/clock-7x01a.c126
-rw-r--r--arch/arm/mach-msm/clock.c218
-rw-r--r--arch/arm/mach-msm/clock.h48
-rw-r--r--arch/arm/mach-msm/common.c116
-rw-r--r--arch/arm/mach-msm/devices.c267
-rw-r--r--arch/arm/mach-msm/devices.h36
-rw-r--r--arch/arm/mach-msm/dma.c72
-rw-r--r--arch/arm/mach-msm/include/mach/board.h1
-rw-r--r--arch/arm/mach-msm/include/mach/debug-macro.S8
-rw-r--r--arch/arm/mach-msm/include/mach/dma.h24
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap.h69
-rw-r--r--arch/arm/mach-msm/include/mach/vreg.h29
-rw-r--r--arch/arm/mach-msm/io.c12
-rw-r--r--arch/arm/mach-msm/irq.c10
-rw-r--r--arch/arm/mach-msm/proc_comm.c110
-rw-r--r--arch/arm/mach-msm/proc_comm.h165
-rw-r--r--arch/arm/mach-msm/timer.c2
-rw-r--r--arch/arm/mach-msm/vreg.c143
-rw-r--r--arch/arm/mach-omap2/irq.c8
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa3xx_nand.h44
-rw-r--r--arch/arm/mach-pxa/include/mach/tosa.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/zylonite.h4
-rw-r--r--arch/arm/mach-pxa/tosa.c37
-rw-r--r--arch/arm/mach-sa1100/include/mach/ide.h75
-rw-r--r--arch/arm/mm/Kconfig4
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_nand.h27
-rw-r--r--arch/arm/plat-omap/include/mach/onenand.h6
35 files changed, 1414 insertions, 334 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 6c73e963d976..6ea097f0890f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -192,6 +192,8 @@ config VECTORS_BASE
 
 source "init/Kconfig"
 
+source "kernel/Kconfig.freezer"
+
 menu "System Type"
 
 choice
@@ -538,16 +540,15 @@ config ARCH_OMAP
 	help
 	  Support for TI's OMAP platform (OMAP1 and OMAP2).
 
-config ARCH_MSM7X00A
-	bool "Qualcomm MSM7X00A"
+config ARCH_MSM
+	bool "Qualcomm MSM"
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	help
-	  Support for Qualcomm MSM7X00A based systems.  This runs on the ARM11
-	  apps processor of the MSM7X00A and depends on a shared memory
+	  Support for Qualcomm MSM7K based systems.  This runs on the ARM11
+	  apps processor of the MSM7K and depends on a shared memory
 	  interface to the ARM9 modem processor which runs the baseband stack
 	  and controls some vital subsystems (clock and power control, etc).
-	  <http://www.cdmatech.com/products/msm7200_chipset_solution.jsp>
 
 endchoice
 
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 7d5121260fda..bd6e28115ebb 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -141,7 +141,7 @@ endif
  machine-$(CONFIG_ARCH_MX3)	   := mx3
  machine-$(CONFIG_ARCH_ORION5X)	   := orion5x
     plat-$(CONFIG_PLAT_ORION)	   := orion
- machine-$(CONFIG_ARCH_MSM7X00A)   := msm
+ machine-$(CONFIG_ARCH_MSM)	   := msm
  machine-$(CONFIG_ARCH_LOKI)       := loki
  machine-$(CONFIG_ARCH_MV78XX0)    := mv78xx0
 
diff --git a/arch/arm/configs/msm_defconfig b/arch/arm/configs/msm_defconfig
index ae4c5e62086a..3b4ecf2a90dd 100644
--- a/arch/arm/configs/msm_defconfig
+++ b/arch/arm/configs/msm_defconfig
@@ -133,7 +133,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-CONFIG_ARCH_MSM7X00A=y
+CONFIG_ARCH_MSM=y
 
 #
 # Boot options
diff --git a/arch/arm/mach-iop13xx/include/mach/time.h b/arch/arm/mach-iop13xx/include/mach/time.h
index 49213d9d7cad..d6d52527589d 100644
--- a/arch/arm/mach-iop13xx/include/mach/time.h
+++ b/arch/arm/mach-iop13xx/include/mach/time.h
@@ -41,7 +41,7 @@ static inline unsigned long iop13xx_core_freq(void)
 		return 1200000000;
 	default:
 		printk("%s: warning unknown frequency, defaulting to 800Mhz\n",
-			__FUNCTION__);
+			__func__);
 	}
 
 	return 800000000;
@@ -60,7 +60,7 @@ static inline unsigned long iop13xx_xsi_bus_ratio(void)
 		return 4;
 	default:
 		printk("%s: warning unknown ratio, defaulting to 2\n",
-			__FUNCTION__);
+			__func__);
 	}
 
 	return 2;
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
index b0653a87159a..30451300751b 100644
--- a/arch/arm/mach-ixp2000/ixdp2x00.c
+++ b/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -143,7 +143,7 @@ static struct irq_chip ixdp2x00_cpld_irq_chip = {
 	.unmask	= ixdp2x00_irq_unmask
 };
 
-void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_irqs)
+void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_of_irqs)
 {
 	unsigned int irq;
 
@@ -154,7 +154,7 @@ void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigne
 
 	board_irq_stat = stat_reg;
 	board_irq_mask = mask_reg;
-	board_irq_count = nr_irqs;
+	board_irq_count = nr_of_irqs;
 
 	*board_irq_mask = 0xffffffff;
 
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 3553babbbf05..d140abca690a 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1,18 +1,13 @@
-if ARCH_MSM7X00A
+if ARCH_MSM
 
-comment "MSM7X00A Board Type"
-	depends on ARCH_MSM7X00A
+comment "MSM Board Type"
+	depends on ARCH_MSM
 
 config MACH_HALIBUT
-	depends on ARCH_MSM7X00A
+	depends on ARCH_MSM
 	default y
-	bool "Halibut Board (QCT SURF7200A)"
+	bool "Halibut Board (QCT SURF7201A)"
 	help
-	  Support for the Qualcomm SURF7200A eval board.
-
-config MSM7X00A_IDLE
-	depends on ARCH_MSM7X00A
-	default y
-	bool "Idle Support for MSM7X00A"
+	  Support for the Qualcomm SURF7201A eval board.
 
 endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index d12f23655850..1aa47001aa3b 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -1,7 +1,8 @@
 obj-y += io.o idle.o irq.o timer.o dma.o
-
-# Common code for board init
-obj-y += common.o
+obj-y += devices.o
+obj-y += proc_comm.o
+obj-y += vreg.o
+obj-y += clock.o clock-7x01a.o
 
 obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o
 
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c
index a24259133e07..c2a96e3965a6 100644
--- a/arch/arm/mach-msm/board-halibut.c
+++ b/arch/arm/mach-msm/board-halibut.c
@@ -33,6 +33,8 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 
+#include "devices.h"
+
 static struct resource smc91x_resources[] = {
 	[0] = {
 		.start	= 0x9C004300,
@@ -53,31 +55,12 @@ static struct platform_device smc91x_device = {
 	.resource	= smc91x_resources,
 };
 
-static void mddi0_panel_power(int on)
-{
-}
-
-static struct msm_mddi_platform_data msm_mddi0_pdata = {
-	.panel_power	= mddi0_panel_power,
-	.has_vsync_irq	= 0,
-};
-
-static struct platform_device msm_mddi0_device = {
-	.name	= "msm_mddi",
-	.id	= 0,
-	.dev	= {
-		.platform_data = &msm_mddi0_pdata
-	},
-};
-
-static struct platform_device msm_serial0_device = {
-	.name	= "msm_serial",
-	.id	= 0,
-};
-
 static struct platform_device *devices[] __initdata = {
-	&msm_serial0_device,
-	&msm_mddi0_device,
+	&msm_device_uart3,
+	&msm_device_smd,
+	&msm_device_nand,
+	&msm_device_hsusb,
+	&msm_device_i2c,
 	&smc91x_device,
 };
 
@@ -91,20 +74,15 @@ static void __init halibut_init_irq(void)
 static void __init halibut_init(void)
 {
 	platform_add_devices(devices, ARRAY_SIZE(devices));
-	msm_add_devices();
 }
 
 static void __init halibut_map_io(void)
 {
 	msm_map_common_io();
+	msm_clock_init();
 }
 
 MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)")
-
-/* UART for LL DEBUG */
-	.phys_io	= MSM_UART1_PHYS,
-	.io_pg_offst	= ((MSM_UART1_BASE) >> 18) & 0xfffc,
-
 	.boot_params	= 0x10000100,
 	.map_io		= halibut_map_io,
 	.init_irq	= halibut_init_irq,
diff --git a/arch/arm/mach-msm/clock-7x01a.c b/arch/arm/mach-msm/clock-7x01a.c
new file mode 100644
index 000000000000..62230a3428ee
--- /dev/null
+++ b/arch/arm/mach-msm/clock-7x01a.c
@@ -0,0 +1,126 @@
+/* arch/arm/mach-msm/clock-7x01a.c
+ *
+ * Clock tables for MSM7X01A
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include "clock.h"
+#include "devices.h"
+
+/* clock IDs used by the modem processor */
+
+#define ACPU_CLK	0   /* Applications processor clock */
+#define ADM_CLK		1   /* Applications data mover clock */
+#define ADSP_CLK	2   /* ADSP clock */
+#define EBI1_CLK	3   /* External bus interface 1 clock */
+#define EBI2_CLK	4   /* External bus interface 2 clock */
+#define ECODEC_CLK	5   /* External CODEC clock */
+#define EMDH_CLK	6   /* External MDDI host clock */
+#define GP_CLK		7   /* General purpose clock */
+#define GRP_CLK		8   /* Graphics clock */
+#define I2C_CLK		9   /* I2C clock */
+#define ICODEC_RX_CLK	10  /* Internal CODEX RX clock */
+#define ICODEC_TX_CLK	11  /* Internal CODEX TX clock */
+#define IMEM_CLK	12  /* Internal graphics memory clock */
+#define MDC_CLK		13  /* MDDI client clock */
+#define MDP_CLK		14  /* Mobile display processor clock */
+#define PBUS_CLK	15  /* Peripheral bus clock */
+#define PCM_CLK		16  /* PCM clock */
+#define PMDH_CLK	17  /* Primary MDDI host clock */
+#define SDAC_CLK	18  /* Stereo DAC clock */
+#define SDC1_CLK	19  /* Secure Digital Card clocks */
+#define SDC1_PCLK	20
+#define SDC2_CLK	21
+#define SDC2_PCLK	22
+#define SDC3_CLK	23
+#define SDC3_PCLK	24
+#define SDC4_CLK	25
+#define SDC4_PCLK	26
+#define TSIF_CLK	27  /* Transport Stream Interface clocks */
+#define TSIF_REF_CLK	28
+#define TV_DAC_CLK	29  /* TV clocks */
+#define TV_ENC_CLK	30
+#define UART1_CLK	31  /* UART clocks */
+#define UART2_CLK	32
+#define UART3_CLK	33
+#define UART1DM_CLK	34
+#define UART2DM_CLK	35
+#define USB_HS_CLK	36  /* High speed USB core clock */
+#define USB_HS_PCLK	37  /* High speed USB pbus clock */
+#define USB_OTG_CLK	38  /* Full speed USB clock */
+#define VDC_CLK		39  /* Video controller clock */
+#define VFE_CLK		40  /* Camera / Video Front End clock */
+#define VFE_MDC_CLK	41  /* VFE MDDI client clock */
+
+#define NR_CLKS		42
+
+#define CLOCK(clk_name, clk_id, clk_dev, clk_flags) {	\
+	.name = clk_name, \
+	.id = clk_id, \
+	.flags = clk_flags, \
+	.dev = clk_dev, \
+	}
+
+#define OFF CLKFLAG_AUTO_OFF
+#define MINMAX CLKFLAG_USE_MIN_MAX_TO_SET
+
+struct clk msm_clocks[] = {
+	CLOCK("adm_clk",	ADM_CLK,	NULL, 0),
+	CLOCK("adsp_clk",	ADSP_CLK,	NULL, 0),
+	CLOCK("ebi1_clk",	EBI1_CLK,	NULL, 0),
+	CLOCK("ebi2_clk",	EBI2_CLK,	NULL, 0),
+	CLOCK("ecodec_clk",	ECODEC_CLK,	NULL, 0),
+	CLOCK("emdh_clk",	EMDH_CLK,	NULL, OFF),
+	CLOCK("gp_clk",		GP_CLK,		NULL, 0),
+	CLOCK("grp_clk",	GRP_CLK,	NULL, OFF),
+	CLOCK("i2c_clk",	I2C_CLK,	&msm_device_i2c.dev, 0),
+	CLOCK("icodec_rx_clk",	ICODEC_RX_CLK,	NULL, 0),
+	CLOCK("icodec_tx_clk",	ICODEC_TX_CLK,	NULL, 0),
+	CLOCK("imem_clk",	IMEM_CLK,	NULL, OFF),
+	CLOCK("mdc_clk",	MDC_CLK,	NULL, 0),
+	CLOCK("mdp_clk",	MDP_CLK,	NULL, OFF),
+	CLOCK("pbus_clk",	PBUS_CLK,	NULL, 0),
+	CLOCK("pcm_clk",	PCM_CLK,	NULL, 0),
+	CLOCK("pmdh_clk",	PMDH_CLK,	NULL, OFF | MINMAX),
+	CLOCK("sdac_clk",	SDAC_CLK,	NULL, OFF),
+	CLOCK("sdc_clk",	SDC1_CLK,	&msm_device_sdc1.dev, OFF),
+	CLOCK("sdc_pclk",	SDC1_PCLK,	&msm_device_sdc1.dev, OFF),
+	CLOCK("sdc_clk",	SDC2_CLK,	&msm_device_sdc2.dev, OFF),
+	CLOCK("sdc_pclk",	SDC2_PCLK,	&msm_device_sdc2.dev, OFF),
+	CLOCK("sdc_clk",	SDC3_CLK,	&msm_device_sdc3.dev, OFF),
+	CLOCK("sdc_pclk",	SDC3_PCLK,	&msm_device_sdc3.dev, OFF),
+	CLOCK("sdc_clk",	SDC4_CLK,	&msm_device_sdc4.dev, OFF),
+	CLOCK("sdc_pclk",	SDC4_PCLK,	&msm_device_sdc4.dev, OFF),
+	CLOCK("tsif_clk",	TSIF_CLK,	NULL, 0),
+	CLOCK("tsif_ref_clk",	TSIF_REF_CLK,	NULL, 0),
+	CLOCK("tv_dac_clk",	TV_DAC_CLK,	NULL, 0),
+	CLOCK("tv_enc_clk",	TV_ENC_CLK,	NULL, 0),
+	CLOCK("uart_clk",	UART1_CLK,	&msm_device_uart1.dev, OFF),
+	CLOCK("uart_clk",	UART2_CLK,	&msm_device_uart2.dev, 0),
+	CLOCK("uart_clk",	UART3_CLK,	&msm_device_uart3.dev, OFF),
+	CLOCK("uart1dm_clk",	UART1DM_CLK,	NULL, OFF),
+	CLOCK("uart2dm_clk",	UART2DM_CLK,	NULL, 0),
+	CLOCK("usb_hs_clk",	USB_HS_CLK,	&msm_device_hsusb.dev, OFF),
+	CLOCK("usb_hs_pclk",	USB_HS_PCLK,	&msm_device_hsusb.dev, OFF),
+	CLOCK("usb_otg_clk",	USB_OTG_CLK,	NULL, 0),
+	CLOCK("vdc_clk",	VDC_CLK,	NULL, OFF | MINMAX),
+	CLOCK("vfe_clk",	VFE_CLK,	NULL, OFF),
+	CLOCK("vfe_mdc_clk",	VFE_MDC_CLK,	NULL, OFF),
+};
+
+unsigned msm_num_clocks = ARRAY_SIZE(msm_clocks);
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
new file mode 100644
index 000000000000..3b1ce36f1032
--- /dev/null
+++ b/arch/arm/mach-msm/clock.c
@@ -0,0 +1,218 @@
+/* arch/arm/mach-msm/clock.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+
+#include "clock.h"
+#include "proc_comm.h"
+
+static DEFINE_MUTEX(clocks_mutex);
+static DEFINE_SPINLOCK(clocks_lock);
+static LIST_HEAD(clocks);
+
+/*
+ * glue for the proc_comm interface
+ */
+static inline int pc_clk_enable(unsigned id)
+{
+	return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL);
+}
+
+static inline void pc_clk_disable(unsigned id)
+{
+	msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
+}
+
+static inline int pc_clk_set_rate(unsigned id, unsigned rate)
+{
+	return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
+}
+
+static inline int pc_clk_set_min_rate(unsigned id, unsigned rate)
+{
+	return msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
+}
+
+static inline int pc_clk_set_max_rate(unsigned id, unsigned rate)
+{
+	return msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate);
+}
+
+static inline int pc_clk_set_flags(unsigned id, unsigned flags)
+{
+	return msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags);
+}
+
+static inline unsigned pc_clk_get_rate(unsigned id)
+{
+	if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL))
+		return 0;
+	else
+		return id;
+}
+
+static inline unsigned pc_clk_is_enabled(unsigned id)
+{
+	if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL))
+		return 0;
+	else
+		return id;
+}
+
+static inline int pc_pll_request(unsigned id, unsigned on)
+{
+	on = !!on;
+	return msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on);
+}
+
+/*
+ * Standard clock functions defined in include/linux/clk.h
+ */
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	struct clk *clk;
+
+	mutex_lock(&clocks_mutex);
+
+	list_for_each_entry(clk, &clocks, list)
+		if (!strcmp(id, clk->name) && clk->dev == dev)
+			goto found_it;
+
+	list_for_each_entry(clk, &clocks, list)
+		if (!strcmp(id, clk->name) && clk->dev == NULL)
+			goto found_it;
+
+	clk = ERR_PTR(-ENOENT);
+found_it:
+	mutex_unlock(&clocks_mutex);
+	return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
+
+int clk_enable(struct clk *clk)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&clocks_lock, flags);
+	clk->count++;
+	if (clk->count == 1)
+		pc_clk_enable(clk->id);
+	spin_unlock_irqrestore(&clocks_lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&clocks_lock, flags);
+	BUG_ON(clk->count == 0);
+	clk->count--;
+	if (clk->count == 0)
+		pc_clk_disable(clk->id);
+	spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return pc_clk_get_rate(clk->id);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	int ret;
+	if (clk->flags & CLKFLAG_USE_MIN_MAX_TO_SET) {
+		ret = pc_clk_set_max_rate(clk->id, rate);
+		if (ret)
+			return ret;
+		return pc_clk_set_min_rate(clk->id, rate);
+	}
+	return pc_clk_set_rate(clk->id, rate);
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	return -ENOSYS;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+	return ERR_PTR(-ENOSYS);
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+int clk_set_flags(struct clk *clk, unsigned long flags)
+{
+	if (clk == NULL || IS_ERR(clk))
+		return -EINVAL;
+	return pc_clk_set_flags(clk->id, flags);
+}
+EXPORT_SYMBOL(clk_set_flags);
+
+
+void __init msm_clock_init(void)
+{
+	unsigned n;
+
+	spin_lock_init(&clocks_lock);
+	mutex_lock(&clocks_mutex);
+	for (n = 0; n < msm_num_clocks; n++)
+		list_add_tail(&msm_clocks[n].list, &clocks);
+	mutex_unlock(&clocks_mutex);
+}
+
+/* The bootloader and/or AMSS may have left various clocks enabled.
+ * Disable any clocks that belong to us (CLKFLAG_AUTO_OFF) but have
+ * not been explicitly enabled by a clk_enable() call.
+ */
+static int __init clock_late_init(void)
+{
+	unsigned long flags;
+	struct clk *clk;
+	unsigned count = 0;
+
+	mutex_lock(&clocks_mutex);
+	list_for_each_entry(clk, &clocks, list) {
+		if (clk->flags & CLKFLAG_AUTO_OFF) {
+			spin_lock_irqsave(&clocks_lock, flags);
+			if (!clk->count) {
+				count++;
+				pc_clk_disable(clk->id);
+			}
+			spin_unlock_irqrestore(&clocks_lock, flags);
+		}
+	}
+	mutex_unlock(&clocks_mutex);
+	pr_info("clock_late_init() disabled %d unused clocks\n", count);
+	return 0;
+}
+
+late_initcall(clock_late_init);
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
new file mode 100644
index 000000000000..f875e1544e5f
--- /dev/null
+++ b/arch/arm/mach-msm/clock.h
@@ -0,0 +1,48 @@
+/* arch/arm/mach-msm/clock.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_CLOCK_H
+#define __ARCH_ARM_MACH_MSM_CLOCK_H
+
+#include <linux/list.h>
+
+#define CLKFLAG_INVERT			0x00000001
+#define CLKFLAG_NOINVERT		0x00000002
+#define CLKFLAG_NONEST			0x00000004
+#define CLKFLAG_NORESET			0x00000008
+
+#define CLK_FIRST_AVAILABLE_FLAG	0x00000100
+#define CLKFLAG_USE_MIN_MAX_TO_SET	0x00000200
+#define CLKFLAG_AUTO_OFF		0x00000400
+
+struct clk {
+	uint32_t id;
+	uint32_t count;
+	uint32_t flags;
+	const char *name;
+	struct list_head list;
+	struct device *dev;
+};
+
+#define A11S_CLK_CNTL_ADDR		(MSM_CSR_BASE + 0x100)
+#define A11S_CLK_SEL_ADDR		(MSM_CSR_BASE + 0x104)
+#define A11S_VDD_SVS_PLEVEL_ADDR	(MSM_CSR_BASE + 0x124)
+
+extern struct clk msm_clocks[];
+extern unsigned msm_num_clocks;
+
+#endif
+
diff --git a/arch/arm/mach-msm/common.c b/arch/arm/mach-msm/common.c
deleted file mode 100644
index 604f8ade9587..000000000000
--- a/arch/arm/mach-msm/common.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/* linux/arch/arm/mach-msm/common.c
- *
- * Common setup code for MSM7K Boards
- *
- * Copyright (C) 2007 Google, Inc.
- * Author: Brian Swetland <swetland@google.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <asm/mach/flash.h>
-
-#include <asm/setup.h>
-
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-
-#include <mach/msm_iomap.h>
-
-#include <mach/board.h>
-
-struct flash_platform_data msm_nand_data = {
-	.parts		= 0,
-	.nr_parts	= 0,
-};
-
-static struct resource msm_nand_resources[] = {
-	[0] = {
-		.start	= 7,
-		.end	= 7,
-		.flags	= IORESOURCE_DMA,
-	},
-};
-
-static struct platform_device msm_nand_device = {
-	.name		= "msm_nand",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(msm_nand_resources),
-	.resource	= msm_nand_resources,
-	.dev		= {
-		.platform_data	= &msm_nand_data,
-	},
-};
-
-static struct platform_device msm_smd_device = {
-	.name	= "msm_smd",
-	.id	= -1,
-};
-
-static struct resource msm_i2c_resources[] = {
-	{
-		.start	= MSM_I2C_BASE,
-		.end	= MSM_I2C_BASE + MSM_I2C_SIZE - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.start	= INT_PWB_I2C,
-		.end	= INT_PWB_I2C,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device msm_i2c_device = {
-	.name		= "msm_i2c",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(msm_i2c_resources),
-	.resource	= msm_i2c_resources,
-};
-
-static struct resource usb_resources[] = {
-	{
-		.start	= MSM_HSUSB_PHYS,
-		.end	= MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.start	= INT_USB_HS,
-		.end	= INT_USB_HS,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device msm_hsusb_device = {
-	.name		= "msm_hsusb",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(usb_resources),
-	.resource	= usb_resources,
-	.dev		= {
-		.coherent_dma_mask	= 0xffffffff,
-	},
-};
-
-static struct platform_device *devices[] __initdata = {
-	&msm_nand_device,
-	&msm_smd_device,
-	&msm_i2c_device,
-	&msm_hsusb_device,
-};
-
-void __init msm_add_devices(void)
-{
-	platform_add_devices(devices, ARRAY_SIZE(devices));
-}
diff --git a/arch/arm/mach-msm/devices.c b/arch/arm/mach-msm/devices.c
new file mode 100644
index 000000000000..f2a74b92a97f
--- /dev/null
+++ b/arch/arm/mach-msm/devices.c
@@ -0,0 +1,267 @@
+/* linux/arch/arm/mach-msm/devices.c
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <mach/msm_iomap.h>
+#include "devices.h"
+
+#include <asm/mach/flash.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+static struct resource resources_uart1[] = {
+	{
+		.start	= INT_UART1,
+		.end	= INT_UART1,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= MSM_UART1_PHYS,
+		.end	= MSM_UART1_PHYS + MSM_UART1_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct resource resources_uart2[] = {
+	{
+		.start	= INT_UART2,
+		.end	= INT_UART2,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= MSM_UART2_PHYS,
+		.end	= MSM_UART2_PHYS + MSM_UART2_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct resource resources_uart3[] = {
+	{
+		.start	= INT_UART3,
+		.end	= INT_UART3,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= MSM_UART3_PHYS,
+		.end	= MSM_UART3_PHYS + MSM_UART3_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+struct platform_device msm_device_uart1 = {
+	.name	= "msm_serial",
+	.id	= 0,
+	.num_resources	= ARRAY_SIZE(resources_uart1),
+	.resource	= resources_uart1,
+};
+
+struct platform_device msm_device_uart2 = {
+	.name	= "msm_serial",
+	.id	= 1,
+	.num_resources	= ARRAY_SIZE(resources_uart2),
+	.resource	= resources_uart2,
+};
+
+struct platform_device msm_device_uart3 = {
+	.name	= "msm_serial",
+	.id	= 2,
+	.num_resources	= ARRAY_SIZE(resources_uart3),
+	.resource	= resources_uart3,
+};
+
+static struct resource resources_i2c[] = {
+	{
+		.start	= MSM_I2C_PHYS,
+		.end	= MSM_I2C_PHYS + MSM_I2C_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_PWB_I2C,
+		.end	= INT_PWB_I2C,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device msm_device_i2c = {
+	.name		= "msm_i2c",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(resources_i2c),
+	.resource	= resources_i2c,
+};
+
+static struct resource resources_hsusb[] = {
+	{
+		.start	= MSM_HSUSB_PHYS,
+		.end	= MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_USB_HS,
+		.end	= INT_USB_HS,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device msm_device_hsusb = {
+	.name		= "msm_hsusb",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(resources_hsusb),
+	.resource	= resources_hsusb,
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffff,
+	},
+};
+
+struct flash_platform_data msm_nand_data = {
+	.parts		= NULL,
+	.nr_parts	= 0,
+};
+
+static struct resource resources_nand[] = {
+	[0] = {
+		.start	= 7,
+		.end	= 7,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+struct platform_device msm_device_nand = {
+	.name		= "msm_nand",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(resources_nand),
+	.resource	= resources_nand,
+	.dev		= {
+		.platform_data	= &msm_nand_data,
+	},
+};
+
+struct platform_device msm_device_smd = {
+	.name	= "msm_smd",
+	.id	= -1,
+};
+
+static struct resource resources_sdc1[] = {
+	{
+		.start	= MSM_SDC1_PHYS,
+		.end	= MSM_SDC1_PHYS + MSM_SDC1_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_SDC1_0,
+		.end	= INT_SDC1_1,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= 8,
+		.end	= 8,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct resource resources_sdc2[] = {
+	{
+		.start	= MSM_SDC2_PHYS,
+		.end	= MSM_SDC2_PHYS + MSM_SDC2_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_SDC2_0,
+		.end	= INT_SDC2_1,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= 8,
+		.end	= 8,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct resource resources_sdc3[] = {
+	{
+		.start	= MSM_SDC3_PHYS,
+		.end	= MSM_SDC3_PHYS + MSM_SDC3_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_SDC3_0,
+		.end	= INT_SDC3_1,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= 8,
+		.end	= 8,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct resource resources_sdc4[] = {
+	{
+		.start	= MSM_SDC4_PHYS,
+		.end	= MSM_SDC4_PHYS + MSM_SDC4_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_SDC4_0,
+		.end	= INT_SDC4_1,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= 8,
+		.end	= 8,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+struct platform_device msm_device_sdc1 = {
+	.name		= "msm_sdcc",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(resources_sdc1),
+	.resource	= resources_sdc1,
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffff,
+	},
+};
+
+struct platform_device msm_device_sdc2 = {
+	.name		= "msm_sdcc",
+	.id		= 2,
+	.num_resources	= ARRAY_SIZE(resources_sdc2),
+	.resource	= resources_sdc2,
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffff,
+	},
+};
+
+struct platform_device msm_device_sdc3 = {
+	.name		= "msm_sdcc",
+	.id		= 3,
+	.num_resources	= ARRAY_SIZE(resources_sdc3),
+	.resource	= resources_sdc3,
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffff,
+	},
+};
+
+struct platform_device msm_device_sdc4 = {
+	.name		= "msm_sdcc",
+	.id		= 4,
+	.num_resources	= ARRAY_SIZE(resources_sdc4),
+	.resource	= resources_sdc4,
+	.dev		= {
+		.coherent_dma_mask	= 0xffffffff,
+	},
+};
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
new file mode 100644
index 000000000000..0744c4a27d6a
--- /dev/null
+++ b/arch/arm/mach-msm/devices.h
@@ -0,0 +1,36 @@
+/* linux/arch/arm/mach-msm/devices.h
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_DEVICES_H
+#define __ARCH_ARM_MACH_MSM_DEVICES_H
+
+extern struct platform_device msm_device_uart1;
+extern struct platform_device msm_device_uart2;
+extern struct platform_device msm_device_uart3;
+
+extern struct platform_device msm_device_sdc1;
+extern struct platform_device msm_device_sdc2;
+extern struct platform_device msm_device_sdc3;
+extern struct platform_device msm_device_sdc4;
+
+extern struct platform_device msm_device_hsusb;
+
+extern struct platform_device msm_device_i2c;
+
+extern struct platform_device msm_device_smd;
+
+extern struct platform_device msm_device_nand;
+
+#endif
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index 0c8f252637e1..f5420f9585c5 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -26,7 +26,7 @@ enum {
 };
 
 static DEFINE_SPINLOCK(msm_dmov_lock);
-static struct msm_dmov_cmd active_command;
+static unsigned int channel_active;
 static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
 static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
 unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
@@ -43,6 +43,11 @@ unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
 #define PRINT_FLOW(format, args...) \
 	MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_FLOW, format, args);
 
+void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
+{
+	writel((graceful << 31), DMOV_FLUSH0(id));
+}
+
 void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
 {
 	unsigned long irq_flags;
@@ -60,6 +65,9 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
 #endif
 		PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n", id, status);
 		list_add_tail(&cmd->list, &active_commands[id]);
+		if (!channel_active)
+			enable_irq(INT_ADM_AARM);
+		channel_active |= 1U << id;
 		writel(cmd->cmdptr, DMOV_CMD_PTR(id));
 	} else {
 		if (list_empty(&active_commands[id]))
@@ -76,21 +84,19 @@ struct msm_dmov_exec_cmdptr_cmd {
 	struct completion complete;
 	unsigned id;
 	unsigned int result;
-	unsigned int flush[6];
+	struct msm_dmov_errdata err;
 };
 
-static void dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd, unsigned int result)
+static void
+dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd,
+			       unsigned int result,
+			       struct msm_dmov_errdata *err)
 {
 	struct msm_dmov_exec_cmdptr_cmd *cmd = container_of(_cmd, struct msm_dmov_exec_cmdptr_cmd, dmov_cmd);
 	cmd->result = result;
-	if (result != 0x80000002) {
-		cmd->flush[0] = readl(DMOV_FLUSH0(cmd->id));
-		cmd->flush[1] = readl(DMOV_FLUSH1(cmd->id));
-		cmd->flush[2] = readl(DMOV_FLUSH2(cmd->id));
-		cmd->flush[3] = readl(DMOV_FLUSH3(cmd->id));
-		cmd->flush[4] = readl(DMOV_FLUSH4(cmd->id));
-		cmd->flush[5] = readl(DMOV_FLUSH5(cmd->id));
-	}
+	if (result != 0x80000002 && err)
+		memcpy(&cmd->err, err, sizeof(struct msm_dmov_errdata));
+
 	complete(&cmd->complete);
 }
 
@@ -111,7 +117,7 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
 	if (cmd.result != 0x80000002) {
 		PRINT_ERROR("dmov_exec_cmdptr(%d): ERROR, result: %x\n", id, cmd.result);
 		PRINT_ERROR("dmov_exec_cmdptr(%d):  flush: %x %x %x %x\n",
-			id, cmd.flush[0], cmd.flush[1], cmd.flush[2], cmd.flush[3]);
+			id, cmd.err.flush[0], cmd.err.flush[1], cmd.err.flush[2], cmd.err.flush[3]);
 		return -EIO;
 	}
 	PRINT_FLOW("dmov_exec_cmdptr(%d, %x) done\n", id, cmdptr);
@@ -159,25 +165,40 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
 					"for %p, result %x\n", id, cmd, ch_result);
 				if (cmd) {
 					list_del(&cmd->list);
-					cmd->complete_func(cmd, ch_result);
+					cmd->complete_func(cmd, ch_result, NULL);
 				}
 			}
 			if (ch_result & DMOV_RSLT_FLUSH) {
-				unsigned int flush0 = readl(DMOV_FLUSH0(id));
+				struct msm_dmov_errdata errdata;
+
+				errdata.flush[0] = readl(DMOV_FLUSH0(id));
+				errdata.flush[1] = readl(DMOV_FLUSH1(id));
+				errdata.flush[2] = readl(DMOV_FLUSH2(id));
+				errdata.flush[3] = readl(DMOV_FLUSH3(id));
+				errdata.flush[4] = readl(DMOV_FLUSH4(id));
+				errdata.flush[5] = readl(DMOV_FLUSH5(id));
 				PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
-				PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, flush0);
+				PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
 				if (cmd) {
 					list_del(&cmd->list);
-					cmd->complete_func(cmd, ch_result);
+					cmd->complete_func(cmd, ch_result, &errdata);
 				}
 			}
 			if (ch_result & DMOV_RSLT_ERROR) {
-				unsigned int flush0 = readl(DMOV_FLUSH0(id));
+				struct msm_dmov_errdata errdata;
+
+				errdata.flush[0] = readl(DMOV_FLUSH0(id));
+				errdata.flush[1] = readl(DMOV_FLUSH1(id));
+				errdata.flush[2] = readl(DMOV_FLUSH2(id));
+				errdata.flush[3] = readl(DMOV_FLUSH3(id));
+				errdata.flush[4] = readl(DMOV_FLUSH4(id));
+				errdata.flush[5] = readl(DMOV_FLUSH5(id));
+
 				PRINT_ERROR("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
-				PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, flush0);
+				PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
 				if (cmd) {
 					list_del(&cmd->list);
-					cmd->complete_func(cmd, ch_result);
+					cmd->complete_func(cmd, ch_result, &errdata);
 				}
 				/* this does not seem to work, once we get an error */
 				/* the datamover will no longer accept commands */
@@ -193,8 +214,14 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
 				writel(cmd->cmdptr, DMOV_CMD_PTR(id));
 			}
 		} while (ch_status & DMOV_STATUS_RSLT_VALID);
+		if (list_empty(&active_commands[id]) && list_empty(&ready_commands[id]))
+			channel_active &= ~(1U << id);
 		PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
 	}
+
+	if (!channel_active)
+		disable_irq(INT_ADM_AARM);
+
 	spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
 	return IRQ_HANDLED;
 }
@@ -202,12 +229,17 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
 static int __init msm_init_datamover(void)
 {
 	int i;
+	int ret;
 	for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
 		INIT_LIST_HEAD(&ready_commands[i]);
 		INIT_LIST_HEAD(&active_commands[i]);
 		writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i));
 	}
-	return request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
+	ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
+	if (ret)
+		return ret;
+	disable_irq(INT_ADM_AARM);
+	return 0;
 }
 
 arch_initcall(msm_init_datamover);
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index a7639493c095..264d62e519f3 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -33,5 +33,6 @@ void __init msm_add_devices(void);
 void __init msm_map_common_io(void);
 void __init msm_init_irq(void);
 void __init msm_init_gpio(void);
+void __init msm_clock_init(void);
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/debug-macro.S b/arch/arm/mach-msm/include/mach/debug-macro.S
index 528eef4b605c..1db3c97dbc49 100644
--- a/arch/arm/mach-msm/include/mach/debug-macro.S
+++ b/arch/arm/mach-msm/include/mach/debug-macro.S
@@ -22,18 +22,22 @@
 	mrc	p15, 0, \rx, c1, c0
 	tst	\rx, #1
 	ldreq	\rx, =MSM_UART1_PHYS
-	ldrne	\rx, =MSM_UART1_BASE
+	movne	\rx, #0
 	.endm
 
 	.macro	senduart,rd,rx
-	str	\rd, [\rx, #0x0C]
+	teq	\rx, #0
+	strne	\rd, [\rx, #0x0C]
 	.endm
 
 	.macro	waituart,rd,rx
 	@ wait for TX_READY
+	teq	\rx, #0
+	bne	2f
 1:	ldr	\rd, [\rx, #0x08]
 	tst	\rd, #0x04
 	beq	1b
+2:
 	.endm
 
 	.macro	busyuart,rd,rx
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index ad1c87f86d10..5ab5bdffab07 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -1,4 +1,4 @@
-/* arch/arm/mach-msm/include/mach/dma.h
+/* linux/include/asm-arm/arch-msm/dma.h
  *
  * Copyright (C) 2007 Google, Inc.
  *
@@ -18,17 +18,21 @@
 #include <linux/list.h>
 #include <mach/msm_iomap.h>
 
+struct msm_dmov_errdata {
+	uint32_t flush[6];
+};
+
 struct msm_dmov_cmd {
 	struct list_head list;
 	unsigned int cmdptr;
-	void (*complete_func)(struct msm_dmov_cmd *cmd, unsigned int result);
-/*	void (*user_result_func)(struct msm_dmov_cmd *cmd); */
+	void (*complete_func)(struct msm_dmov_cmd *cmd,
+			      unsigned int result,
+			      struct msm_dmov_errdata *err);
 };
 
 void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
-void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd);
+void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful);
 int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
-/* int msm_dmov_exec_cmd_etc(unsigned id, unsigned int cmdptr, int timeout, int interruptible); */
 
 
 
@@ -122,6 +126,16 @@ typedef struct {
 	unsigned _reserved;
 } dmov_sg;
 
+/* Box mode */
+typedef struct {
+	uint32_t cmd;
+	uint32_t src_row_addr;
+	uint32_t dst_row_addr;
+	uint32_t src_dst_len;
+	uint32_t num_rows;
+	uint32_t row_offset;
+} dmov_box;
+
 /* bits for the cmd field of the above structures */
 
 #define CMD_LC      (1 << 31)  /* last command */
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index e221f58ceea3..2f7b4c8620d9 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -37,11 +37,17 @@
  *
  */
 
-#define MSM_VIC_BASE          0xE0000000
+#ifdef __ASSEMBLY__
+#define IOMEM(x)	x
+#else
+#define IOMEM(x)	((void __force __iomem *)(x))
+#endif
+
+#define MSM_VIC_BASE          IOMEM(0xE0000000)
 #define MSM_VIC_PHYS          0xC0000000
 #define MSM_VIC_SIZE          SZ_4K
 
-#define MSM_CSR_BASE          0xE0001000
+#define MSM_CSR_BASE          IOMEM(0xE0001000)
 #define MSM_CSR_PHYS          0xC0100000
 #define MSM_CSR_SIZE          SZ_4K
 
@@ -49,56 +55,67 @@
 #define MSM_GPT_BASE          MSM_CSR_BASE
 #define MSM_GPT_SIZE          SZ_4K
 
-#define MSM_DMOV_BASE         0xE0002000
+#define MSM_DMOV_BASE         IOMEM(0xE0002000)
 #define MSM_DMOV_PHYS         0xA9700000
 #define MSM_DMOV_SIZE         SZ_4K
 
-#define MSM_UART1_BASE        0xE0003000
+#define MSM_GPIO1_BASE        IOMEM(0xE0003000)
+#define MSM_GPIO1_PHYS        0xA9200000
+#define MSM_GPIO1_SIZE        SZ_4K
+
+#define MSM_GPIO2_BASE        IOMEM(0xE0004000)
+#define MSM_GPIO2_PHYS        0xA9300000
+#define MSM_GPIO2_SIZE        SZ_4K
+
+#define MSM_CLK_CTL_BASE      IOMEM(0xE0005000)
+#define MSM_CLK_CTL_PHYS      0xA8600000
+#define MSM_CLK_CTL_SIZE      SZ_4K
+
+#define MSM_SHARED_RAM_BASE   IOMEM(0xE0100000)
+#define MSM_SHARED_RAM_PHYS   0x01F00000
+#define MSM_SHARED_RAM_SIZE   SZ_1M
+
 #define MSM_UART1_PHYS        0xA9A00000
 #define MSM_UART1_SIZE        SZ_4K
 
-#define MSM_UART2_BASE        0xE0004000
 #define MSM_UART2_PHYS        0xA9B00000
 #define MSM_UART2_SIZE        SZ_4K
 
-#define MSM_UART3_BASE        0xE0005000
 #define MSM_UART3_PHYS        0xA9C00000
 #define MSM_UART3_SIZE        SZ_4K
 
-#define MSM_I2C_BASE          0xE0006000
-#define MSM_I2C_PHYS          0xA9900000
-#define MSM_I2C_SIZE          SZ_4K
+#define MSM_SDC1_PHYS         0xA0400000
+#define MSM_SDC1_SIZE         SZ_4K
 
-#define MSM_GPIO1_BASE        0xE0007000
-#define MSM_GPIO1_PHYS        0xA9200000
-#define MSM_GPIO1_SIZE        SZ_4K
+#define MSM_SDC2_PHYS         0xA0500000
+#define MSM_SDC2_SIZE         SZ_4K
 
-#define MSM_GPIO2_BASE        0xE0008000
-#define MSM_GPIO2_PHYS        0xA9300000
-#define MSM_GPIO2_SIZE        SZ_4K
+#define MSM_SDC3_PHYS         0xA0600000
+#define MSM_SDC3_SIZE         SZ_4K
+
+#define MSM_SDC4_PHYS         0xA0700000
+#define MSM_SDC4_SIZE         SZ_4K
+
+#define MSM_I2C_PHYS          0xA9900000
+#define MSM_I2C_SIZE          SZ_4K
 
-#define MSM_HSUSB_BASE        0xE0009000
 #define MSM_HSUSB_PHYS        0xA0800000
 #define MSM_HSUSB_SIZE        SZ_4K
 
-#define MSM_CLK_CTL_BASE      0xE000A000
-#define MSM_CLK_CTL_PHYS      0xA8600000
-#define MSM_CLK_CTL_SIZE      SZ_4K
-
-#define MSM_PMDH_BASE         0xE000B000
 #define MSM_PMDH_PHYS         0xAA600000
 #define MSM_PMDH_SIZE         SZ_4K
 
-#define MSM_EMDH_BASE         0xE000C000
 #define MSM_EMDH_PHYS         0xAA700000
 #define MSM_EMDH_SIZE         SZ_4K
 
-#define MSM_MDP_BASE          0xE0010000
 #define MSM_MDP_PHYS          0xAA200000
 #define MSM_MDP_SIZE          0x000F0000
 
-#define MSM_SHARED_RAM_BASE   0xE0100000
-#define MSM_SHARED_RAM_PHYS   0x01F00000
-#define MSM_SHARED_RAM_SIZE   SZ_1M
+#define MSM_MDC_PHYS	      0xAA500000
+#define MSM_MDC_SIZE	      SZ_1M
+
+#define MSM_AD5_PHYS          0xAC000000
+#define MSM_AD5_SIZE          (SZ_1M*13)
+
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/vreg.h b/arch/arm/mach-msm/include/mach/vreg.h
new file mode 100644
index 000000000000..9f9e25cb718e
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/vreg.h
@@ -0,0 +1,29 @@
+/* linux/include/asm-arm/arch-msm/vreg.h
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_VREG_H
+#define __ARCH_ARM_MACH_MSM_VREG_H
+
+struct vreg;
+
+struct vreg *vreg_get(struct device *dev, const char *id);
+void vreg_put(struct vreg *vreg);
+
+int vreg_enable(struct vreg *vreg);
+void vreg_disable(struct vreg *vreg);
+int vreg_set_level(struct vreg *vreg, unsigned mv);
+
+#endif
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 7999e4ba8e20..6e7692ff6f2c 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -28,7 +28,7 @@
 #include <mach/board.h>
 
 #define MSM_DEVICE(name) { \
-		.virtual = MSM_##name##_BASE, \
+		.virtual = (unsigned long) MSM_##name##_BASE, \
 		.pfn = __phys_to_pfn(MSM_##name##_PHYS), \
 		.length = MSM_##name##_SIZE, \
 		.type = MT_DEVICE_NONSHARED, \
@@ -39,19 +39,11 @@ static struct map_desc msm_io_desc[] __initdata = {
 	MSM_DEVICE(CSR),
 	MSM_DEVICE(GPT),
 	MSM_DEVICE(DMOV),
-	MSM_DEVICE(UART1),
-	MSM_DEVICE(UART2),
-	MSM_DEVICE(UART3),
-	MSM_DEVICE(I2C),
 	MSM_DEVICE(GPIO1),
 	MSM_DEVICE(GPIO2),
-	MSM_DEVICE(HSUSB),
 	MSM_DEVICE(CLK_CTL),
-	MSM_DEVICE(PMDH),
-	MSM_DEVICE(EMDH),
-	MSM_DEVICE(MDP),
 	{
-		.virtual =  MSM_SHARED_RAM_BASE,
+		.virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
 		.pfn =      __phys_to_pfn(MSM_SHARED_RAM_PHYS),
 		.length =   MSM_SHARED_RAM_SIZE,
 		.type =     MT_DEVICE,
diff --git a/arch/arm/mach-msm/irq.c b/arch/arm/mach-msm/irq.c
index 04b8d182ff8a..69ca0dd79bdf 100644
--- a/arch/arm/mach-msm/irq.c
+++ b/arch/arm/mach-msm/irq.c
@@ -66,20 +66,20 @@
 
 static void msm_irq_ack(unsigned int irq)
 {
-	unsigned reg = VIC_INT_CLEAR0 + ((irq & 32) ? 4 : 0);
+	void __iomem *reg = VIC_INT_CLEAR0 + ((irq & 32) ? 4 : 0);
 	irq = 1 << (irq & 31);
 	writel(irq, reg);
 }
 
 static void msm_irq_mask(unsigned int irq)
 {
-	unsigned reg = VIC_INT_ENCLEAR0 + ((irq & 32) ? 4 : 0);
+	void __iomem *reg = VIC_INT_ENCLEAR0 + ((irq & 32) ? 4 : 0);
 	writel(1 << (irq & 31), reg);
 }
 
 static void msm_irq_unmask(unsigned int irq)
 {
-	unsigned reg = VIC_INT_ENSET0 + ((irq & 32) ? 4 : 0);
+	void __iomem *reg = VIC_INT_ENSET0 + ((irq & 32) ? 4 : 0);
 	writel(1 << (irq & 31), reg);
 }
 
@@ -90,8 +90,8 @@ static int msm_irq_set_wake(unsigned int irq, unsigned int on)
 
 static int msm_irq_set_type(unsigned int irq, unsigned int flow_type)
 {
-	unsigned treg = VIC_INT_TYPE0 + ((irq & 32) ? 4 : 0);
-	unsigned preg = VIC_INT_POLARITY0 + ((irq & 32) ? 4 : 0);
+	void __iomem *treg = VIC_INT_TYPE0 + ((irq & 32) ? 4 : 0);
+	void __iomem *preg = VIC_INT_POLARITY0 + ((irq & 32) ? 4 : 0);
 	int b = 1 << (irq & 31);
 
 	if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
diff --git a/arch/arm/mach-msm/proc_comm.c b/arch/arm/mach-msm/proc_comm.c
new file mode 100644
index 000000000000..915ee704ed3c
--- /dev/null
+++ b/arch/arm/mach-msm/proc_comm.c
@@ -0,0 +1,110 @@
+/* arch/arm/mach-msm/proc_comm.c
+ *
+ * Copyright (C) 2007-2008 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <mach/msm_iomap.h>
+#include <mach/system.h>
+
+#include "proc_comm.h"
+
+#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4)
+
+static inline void notify_other_proc_comm(void)
+{
+	writel(1, MSM_A2M_INT(6));
+}
+
+#define APP_COMMAND 0x00
+#define APP_STATUS  0x04
+#define APP_DATA1   0x08
+#define APP_DATA2   0x0C
+
+#define MDM_COMMAND 0x10
+#define MDM_STATUS  0x14
+#define MDM_DATA1   0x18
+#define MDM_DATA2   0x1C
+
+static DEFINE_SPINLOCK(proc_comm_lock);
+
+/* The higher level SMD support will install this to
+ * provide a way to check for and handle modem restart.
+ */
+int (*msm_check_for_modem_crash)(void);
+
+/* Poll for a state change, checking for possible
+ * modem crashes along the way (so we don't wait
+ * forever while the ARM9 is blowing up).
+ *
+ * Return an error in the event of a modem crash and
+ * restart so the msm_proc_comm() routine can restart
+ * the operation from the beginning.
+ */
+static int proc_comm_wait_for(void __iomem *addr, unsigned value)
+{
+	for (;;) {
+		if (readl(addr) == value)
+			return 0;
+
+		if (msm_check_for_modem_crash)
+			if (msm_check_for_modem_crash())
+				return -EAGAIN;
+	}
+}
+
+int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2)
+{
+	void __iomem *base = MSM_SHARED_RAM_BASE;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&proc_comm_lock, flags);
+
+	for (;;) {
+		if (proc_comm_wait_for(base + MDM_STATUS, PCOM_READY))
+			continue;
+
+		writel(cmd, base + APP_COMMAND);
+		writel(data1 ? *data1 : 0, base + APP_DATA1);
+		writel(data2 ? *data2 : 0, base + APP_DATA2);
+
+		notify_other_proc_comm();
+
+		if (proc_comm_wait_for(base + APP_COMMAND, PCOM_CMD_DONE))
+			continue;
+
+		if (readl(base + APP_STATUS) != PCOM_CMD_FAIL) {
+			if (data1)
+				*data1 = readl(base + APP_DATA1);
+			if (data2)
+				*data2 = readl(base + APP_DATA2);
+			ret = 0;
+		} else {
+			ret = -EIO;
+		}
+		break;
+	}
+
+	writel(PCOM_CMD_IDLE, base + APP_COMMAND);
+
+	spin_unlock_irqrestore(&proc_comm_lock, flags);
+
+	return ret;
+}
+
+
diff --git a/arch/arm/mach-msm/proc_comm.h b/arch/arm/mach-msm/proc_comm.h
new file mode 100644
index 000000000000..834760f25692
--- /dev/null
+++ b/arch/arm/mach-msm/proc_comm.h
@@ -0,0 +1,165 @@
+/* arch/arm/mach-msm/proc_comm.h
+ *
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _ARCH_ARM_MACH_MSM_PROC_COMM_H_
+#define _ARCH_ARM_MACH_MSM_PROC_COMM_H_
+
+enum {
+	PCOM_CMD_IDLE = 0x0,
+	PCOM_CMD_DONE,
+	PCOM_RESET_APPS,
+	PCOM_RESET_CHIP,
+	PCOM_CONFIG_NAND_MPU,
+	PCOM_CONFIG_USB_CLKS,
+	PCOM_GET_POWER_ON_STATUS,
+	PCOM_GET_WAKE_UP_STATUS,
+	PCOM_GET_BATT_LEVEL,
+	PCOM_CHG_IS_CHARGING,
+	PCOM_POWER_DOWN,
+	PCOM_USB_PIN_CONFIG,
+	PCOM_USB_PIN_SEL,
+	PCOM_SET_RTC_ALARM,
+	PCOM_NV_READ,
+	PCOM_NV_WRITE,
+	PCOM_GET_UUID_HIGH,
+	PCOM_GET_UUID_LOW,
+	PCOM_GET_HW_ENTROPY,
+	PCOM_RPC_GPIO_TLMM_CONFIG_REMOTE,
+	PCOM_CLKCTL_RPC_ENABLE,
+	PCOM_CLKCTL_RPC_DISABLE,
+	PCOM_CLKCTL_RPC_RESET,
+	PCOM_CLKCTL_RPC_SET_FLAGS,
+	PCOM_CLKCTL_RPC_SET_RATE,
+	PCOM_CLKCTL_RPC_MIN_RATE,
+	PCOM_CLKCTL_RPC_MAX_RATE,
+	PCOM_CLKCTL_RPC_RATE,
+	PCOM_CLKCTL_RPC_PLL_REQUEST,
+	PCOM_CLKCTL_RPC_ENABLED,
+	PCOM_VREG_SWITCH,
+	PCOM_VREG_SET_LEVEL,
+	PCOM_GPIO_TLMM_CONFIG_GROUP,
+	PCOM_GPIO_TLMM_UNCONFIG_GROUP,
+	PCOM_NV_WRITE_BYTES_4_7,
+	PCOM_CONFIG_DISP,
+	PCOM_GET_FTM_BOOT_COUNT,
+	PCOM_RPC_GPIO_TLMM_CONFIG_EX,
+	PCOM_PM_MPP_CONFIG,
+	PCOM_GPIO_IN,
+	PCOM_GPIO_OUT,
+	PCOM_RESET_MODEM,
+	PCOM_RESET_CHIP_IMM,
+	PCOM_PM_VID_EN,
+	PCOM_VREG_PULLDOWN,
+	PCOM_NUM_CMDS,
+};
+
+enum {
+	 PCOM_INVALID_STATUS = 0x0,
+	 PCOM_READY,
+	 PCOM_CMD_RUNNING,
+	 PCOM_CMD_SUCCESS,
+	 PCOM_CMD_FAIL,
+};
+
+/* List of VREGs that support the Pull Down Resistor setting. */
+enum {
+	PM_VREG_PDOWN_MSMA_ID,
+	PM_VREG_PDOWN_MSMP_ID,
+	PM_VREG_PDOWN_MSME1_ID,	/* Not supported in Panoramix */
+	PM_VREG_PDOWN_MSMC1_ID,	/* Not supported in PM6620 */
+	PM_VREG_PDOWN_MSMC2_ID,	/* Supported in PM7500 only */
+	PM_VREG_PDOWN_GP3_ID,	/* Supported in PM7500 only */
+	PM_VREG_PDOWN_MSME2_ID,	/* Supported in PM7500 and Panoramix only */
+	PM_VREG_PDOWN_GP4_ID,	/* Supported in PM7500 only */
+	PM_VREG_PDOWN_GP1_ID,	/* Supported in PM7500 only */
+	PM_VREG_PDOWN_TCXO_ID,
+	PM_VREG_PDOWN_PA_ID,
+	PM_VREG_PDOWN_RFTX_ID,
+	PM_VREG_PDOWN_RFRX1_ID,
+	PM_VREG_PDOWN_RFRX2_ID,
+	PM_VREG_PDOWN_SYNT_ID,
+	PM_VREG_PDOWN_WLAN_ID,
+	PM_VREG_PDOWN_USB_ID,
+	PM_VREG_PDOWN_MMC_ID,
+	PM_VREG_PDOWN_RUIM_ID,
+	PM_VREG_PDOWN_MSMC0_ID,	/* Supported in PM6610 only */
+	PM_VREG_PDOWN_GP2_ID,	/* Supported in PM7500 only */
+	PM_VREG_PDOWN_GP5_ID,	/* Supported in PM7500 only */
+	PM_VREG_PDOWN_GP6_ID,	/* Supported in PM7500 only */
+	PM_VREG_PDOWN_RF_ID,
+	PM_VREG_PDOWN_RF_VCO_ID,
+	PM_VREG_PDOWN_MPLL_ID,
+	PM_VREG_PDOWN_S2_ID,
+	PM_VREG_PDOWN_S3_ID,
+	PM_VREG_PDOWN_RFUBM_ID,
+
+	/* new for HAN */
+	PM_VREG_PDOWN_RF1_ID,
+	PM_VREG_PDOWN_RF2_ID,
+	PM_VREG_PDOWN_RFA_ID,
+	PM_VREG_PDOWN_CDC2_ID,
+	PM_VREG_PDOWN_RFTX2_ID,
+	PM_VREG_PDOWN_USIM_ID,
+	PM_VREG_PDOWN_USB2P6_ID,
+	PM_VREG_PDOWN_USB3P3_ID,
+	PM_VREG_PDOWN_INVALID_ID,
+
+	/* backward compatible enums only */
+	PM_VREG_PDOWN_CAM_ID = PM_VREG_PDOWN_GP1_ID,
+	PM_VREG_PDOWN_MDDI_ID = PM_VREG_PDOWN_GP2_ID,
+	PM_VREG_PDOWN_RUIM2_ID = PM_VREG_PDOWN_GP3_ID,
+	PM_VREG_PDOWN_AUX_ID = PM_VREG_PDOWN_GP4_ID,
+	PM_VREG_PDOWN_AUX2_ID = PM_VREG_PDOWN_GP5_ID,
+	PM_VREG_PDOWN_BT_ID = PM_VREG_PDOWN_GP6_ID,
+
+	PM_VREG_PDOWN_MSME_ID = PM_VREG_PDOWN_MSME1_ID,
+	PM_VREG_PDOWN_MSMC_ID = PM_VREG_PDOWN_MSMC1_ID,
+	PM_VREG_PDOWN_RFA1_ID = PM_VREG_PDOWN_RFRX2_ID,
+	PM_VREG_PDOWN_RFA2_ID = PM_VREG_PDOWN_RFTX2_ID,
+	PM_VREG_PDOWN_XO_ID = PM_VREG_PDOWN_TCXO_ID
+};
+
+/* gpio info for PCOM_RPC_GPIO_TLMM_CONFIG_EX */
+
+#define GPIO_ENABLE	0
+#define GPIO_DISABLE	1
+
+#define GPIO_INPUT	0
+#define GPIO_OUTPUT	1
+
+#define GPIO_NO_PULL	0
+#define GPIO_PULL_DOWN	1
+#define GPIO_KEEPER	2
+#define GPIO_PULL_UP	3
+
+#define GPIO_2MA	0
+#define GPIO_4MA	1
+#define GPIO_6MA	2
+#define GPIO_8MA	3
+#define GPIO_10MA	4
+#define GPIO_12MA	5
+#define GPIO_14MA	6
+#define GPIO_16MA	7
+
+#define PCOM_GPIO_CFG(gpio, func, dir, pull, drvstr) \
+		((((gpio) & 0x3FF) << 4)	| \
+		((func) & 0xf)			| \
+		(((dir) & 0x1) << 14)		| \
+		(((pull) & 0x3) << 15)		| \
+		(((drvstr) & 0xF) << 17))
+
+int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2);
+
+#endif
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 2bffe9b7e9fe..345a14cb73c3 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -45,7 +45,7 @@ struct msm_clock {
 	struct clock_event_device   clockevent;
 	struct clocksource          clocksource;
 	struct irqaction            irq;
-	uint32_t                    regbase;
+	void __iomem                *regbase;
 	uint32_t                    freq;
 	uint32_t                    shift;
 };
diff --git a/arch/arm/mach-msm/vreg.c b/arch/arm/mach-msm/vreg.c
new file mode 100644
index 000000000000..fcb0b9f25684
--- /dev/null
+++ b/arch/arm/mach-msm/vreg.c
@@ -0,0 +1,143 @@
+/* arch/arm/mach-msm/vreg.c
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/debugfs.h>
+#include <mach/vreg.h>
+
+#include "proc_comm.h"
+
+struct vreg {
+	const char *name;
+	unsigned id;
+};
+
+#define VREG(_name, _id) { .name = _name, .id = _id, }
+
+static struct vreg vregs[] = {
+	VREG("msma",	0),
+	VREG("msmp",	1),
+	VREG("msme1",	2),
+	VREG("msmc1",	3),
+	VREG("msmc2",	4),
+	VREG("gp3",	5),
+	VREG("msme2",	6),
+	VREG("gp4",	7),
+	VREG("gp1",	8),
+	VREG("tcxo",	9),
+	VREG("pa",	10),
+	VREG("rftx",	11),
+	VREG("rfrx1",	12),
+	VREG("rfrx2",	13),
+	VREG("synt",	14),
+	VREG("wlan",	15),
+	VREG("usb",	16),
+	VREG("boost",	17),
+	VREG("mmc",	18),
+	VREG("ruim",	19),
+	VREG("msmc0",	20),
+	VREG("gp2",	21),
+	VREG("gp5",	22),
+	VREG("gp6",	23),
+	VREG("rf",	24),
+	VREG("rf_vco",	26),
+	VREG("mpll",	27),
+	VREG("s2",	28),
+	VREG("s3",	29),
+	VREG("rfubm",	30),
+	VREG("ncp",	31),
+};
+
+struct vreg *vreg_get(struct device *dev, const char *id)
+{
+	int n;
+	for (n = 0; n < ARRAY_SIZE(vregs); n++) {
+		if (!strcmp(vregs[n].name, id))
+			return vregs + n;
+	}
+	return 0;
+}
+
+void vreg_put(struct vreg *vreg)
+{
+}
+
+int vreg_enable(struct vreg *vreg)
+{
+	unsigned id = vreg->id;
+	unsigned enable = 1;
+	return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+}
+
+void vreg_disable(struct vreg *vreg)
+{
+	unsigned id = vreg->id;
+	unsigned enable = 0;
+	msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+}
+
+int vreg_set_level(struct vreg *vreg, unsigned mv)
+{
+	unsigned id = vreg->id;
+	return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);
+}
+
+#if defined(CONFIG_DEBUG_FS)
+
+static int vreg_debug_set(void *data, u64 val)
+{
+	struct vreg *vreg = data;
+	switch (val) {
+	case 0:
+		vreg_disable(vreg);
+		break;
+	case 1:
+		vreg_enable(vreg);
+		break;
+	default:
+		vreg_set_level(vreg, val);
+		break;
+	}
+	return 0;
+}
+
+static int vreg_debug_get(void *data, u64 *val)
+{
+	return -ENOSYS;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n");
+
+static int __init vreg_debug_init(void)
+{
+	struct dentry *dent;
+	int n;
+
+	dent = debugfs_create_dir("vreg", 0);
+	if (IS_ERR(dent))
+		return 0;
+
+	for (n = 0; n < ARRAY_SIZE(vregs); n++)
+		(void) debugfs_create_file(vregs[n].name, 0644,
+					   dent, vregs + n, &vreg_fops);
+
+	return 0;
+}
+
+device_initcall(vreg_debug_init);
+#endif
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index d354e0fe4477..c40fc378a251 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -119,7 +119,7 @@ static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
 
 void __init omap_init_irq(void)
 {
-	unsigned long nr_irqs = 0;
+	unsigned long nr_of_irqs = 0;
 	unsigned int nr_banks = 0;
 	int i;
 
@@ -133,14 +133,14 @@ void __init omap_init_irq(void)
 
 		omap_irq_bank_init_one(bank);
 
-		nr_irqs += bank->nr_irqs;
+		nr_of_irqs += bank->nr_irqs;
 		nr_banks++;
 	}
 
 	printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n",
-	       nr_irqs, nr_banks, nr_banks > 1 ? "s" : "");
+	       nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : "");
 
-	for (i = 0; i < nr_irqs; i++) {
+	for (i = 0; i < nr_of_irqs; i++) {
 		set_irq_chip(i, &omap_irq_chip);
 		set_irq_handler(i, handle_level_irq);
 		set_irq_flags(i, IRQF_VALID);
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h b/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h
index eb4b190b6657..eb35fca9aea5 100644
--- a/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h
+++ b/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h
@@ -4,6 +4,43 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 
+struct pxa3xx_nand_timing {
+	unsigned int	tCH;  /* Enable signal hold time */
+	unsigned int	tCS;  /* Enable signal setup time */
+	unsigned int	tWH;  /* ND_nWE high duration */
+	unsigned int	tWP;  /* ND_nWE pulse time */
+	unsigned int	tRH;  /* ND_nRE high duration */
+	unsigned int	tRP;  /* ND_nRE pulse width */
+	unsigned int	tR;   /* ND_nWE high to ND_nRE low for read */
+	unsigned int	tWHR; /* ND_nWE high to ND_nRE low for status read */
+	unsigned int	tAR;  /* ND_ALE low to ND_nRE low delay */
+};
+
+struct pxa3xx_nand_cmdset {
+	uint16_t	read1;
+	uint16_t	read2;
+	uint16_t	program;
+	uint16_t	read_status;
+	uint16_t	read_id;
+	uint16_t	erase;
+	uint16_t	reset;
+	uint16_t	lock;
+	uint16_t	unlock;
+	uint16_t	lock_status;
+};
+
+struct pxa3xx_nand_flash {
+	const struct pxa3xx_nand_timing *timing; /* NAND Flash timing */
+	const struct pxa3xx_nand_cmdset *cmdset;
+
+	uint32_t page_per_block;/* Pages per block (PG_PER_BLK) */
+	uint32_t page_size;	/* Page size in bytes (PAGE_SZ) */
+	uint32_t flash_width;	/* Width of Flash memory (DWIDTH_M) */
+	uint32_t dfc_width;	/* Width of flash controller(DWIDTH_C) */
+	uint32_t num_blocks;	/* Number of physical blocks in Flash */
+	uint32_t chip_id;
+};
+
 struct pxa3xx_nand_platform_data {
 
 	/* the data flash bus is shared between the Static Memory
@@ -12,8 +49,11 @@ struct pxa3xx_nand_platform_data {
 	 */
 	int	enable_arbiter;
 
-	struct mtd_partition *parts;
-	unsigned int	nr_parts;
+	const struct mtd_partition		*parts;
+	unsigned int				nr_parts;
+
+	const struct pxa3xx_nand_flash * 	flash;
+	size_t					num_flash;
 };
 
 extern void pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info);
diff --git a/arch/arm/mach-pxa/include/mach/tosa.h b/arch/arm/mach-pxa/include/mach/tosa.h
index a72803f0461b..8bce6d8615b9 100644
--- a/arch/arm/mach-pxa/include/mach/tosa.h
+++ b/arch/arm/mach-pxa/include/mach/tosa.h
@@ -59,8 +59,6 @@
  * TC6393XB GPIOs
  */
 #define TOSA_TC6393XB_GPIO_BASE		(NR_BUILTIN_GPIO + 2 * 12)
-#define TOSA_TC6393XB_GPIO(i)		(TOSA_TC6393XB_GPIO_BASE + (i))
-#define TOSA_TC6393XB_GPIO_BIT(gpio)	(1 << (gpio - TOSA_TC6393XB_GPIO_BASE))
 
 #define TOSA_GPIO_TG_ON			(TOSA_TC6393XB_GPIO_BASE + 0)
 #define TOSA_GPIO_L_MUTE		(TOSA_TC6393XB_GPIO_BASE + 1)
diff --git a/arch/arm/mach-pxa/include/mach/zylonite.h b/arch/arm/mach-pxa/include/mach/zylonite.h
index 0d35ca04731e..bf6785adccf4 100644
--- a/arch/arm/mach-pxa/include/mach/zylonite.h
+++ b/arch/arm/mach-pxa/include/mach/zylonite.h
@@ -30,7 +30,7 @@ extern void zylonite_pxa300_init(void);
 static inline void zylonite_pxa300_init(void)
 {
 	if (cpu_is_pxa300() || cpu_is_pxa310())
-		panic("%s: PXA300/PXA310 not supported\n", __FUNCTION__);
+		panic("%s: PXA300/PXA310 not supported\n", __func__);
 }
 #endif
 
@@ -40,7 +40,7 @@ extern void zylonite_pxa320_init(void);
 static inline void zylonite_pxa320_init(void)
 {
 	if (cpu_is_pxa320())
-		panic("%s: PXA320 not supported\n", __FUNCTION__);
+		panic("%s: PXA320 not supported\n", __func__);
 }
 #endif
 
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 130e37e4ebdd..a6c4694359ca 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -706,16 +706,39 @@ static struct tmio_nand_data tosa_tc6393xb_nand_config = {
 	.badblock_pattern = &tosa_tc6393xb_nand_bbt,
 };
 
-static struct tc6393xb_platform_data tosa_tc6393xb_setup = {
+static int tosa_tc6393xb_setup(struct platform_device *dev)
+{
+	int rc;
+
+	rc = gpio_request(TOSA_GPIO_CARD_VCC_ON, "CARD_VCC_ON");
+	if (rc)
+		goto err_req;
+
+	rc = gpio_direction_output(TOSA_GPIO_CARD_VCC_ON, 1);
+	if (rc)
+		goto err_dir;
+
+	return rc;
+
+err_dir:
+	gpio_free(TOSA_GPIO_CARD_VCC_ON);
+err_req:
+	return rc;
+}
+
+static void tosa_tc6393xb_teardown(struct platform_device *dev)
+{
+	gpio_free(TOSA_GPIO_CARD_VCC_ON);
+}
+
+static struct tc6393xb_platform_data tosa_tc6393xb_data = {
 	.scr_pll2cr	= 0x0cc1,
 	.scr_gper	= 0x3300,
-	.scr_gpo_dsr	=
-		TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON),
-	.scr_gpo_doecr	=
-		TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON),
 
 	.irq_base	= IRQ_BOARD_START,
 	.gpio_base	= TOSA_TC6393XB_GPIO_BASE,
+	.setup		= tosa_tc6393xb_setup,
+	.teardown	= tosa_tc6393xb_teardown,
 
 	.enable		= tosa_tc6393xb_enable,
 	.disable	= tosa_tc6393xb_disable,
@@ -723,6 +746,8 @@ static struct tc6393xb_platform_data tosa_tc6393xb_setup = {
 	.resume		= tosa_tc6393xb_resume,
 
 	.nand_data	= &tosa_tc6393xb_nand_config,
+
+	.resume_restore = 1,
 };
 
 
@@ -730,7 +755,7 @@ static struct platform_device tc6393xb_device = {
 	.name	= "tc6393xb",
 	.id	= -1,
 	.dev	= {
-		.platform_data	= &tosa_tc6393xb_setup,
+		.platform_data	= &tosa_tc6393xb_data,
 	},
 	.num_resources	= ARRAY_SIZE(tc6393xb_resources),
 	.resource	= tc6393xb_resources,
diff --git a/arch/arm/mach-sa1100/include/mach/ide.h b/arch/arm/mach-sa1100/include/mach/ide.h
deleted file mode 100644
index 4c99c8f5e617..000000000000
--- a/arch/arm/mach-sa1100/include/mach/ide.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * arch/arm/mach-sa1100/include/mach/ide.h
- *
- * Copyright (c) 1998 Hugo Fiennes & Nicolas Pitre
- *
- * 18-aug-2000: Cleanup by Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
- *              Get rid of the special ide_init_hwif_ports() functions
- *              and make a generalised function that can be used by all
- *              architectures.
- */
-
-#include <asm/irq.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-
-#error "This code is broken and needs update to match with current ide support"
-
-
-/*
- * Set up a hw structure for a specified data port, control port and IRQ.
- * This should follow whatever the default interface uses.
- */
-static inline void ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
-				       unsigned long ctrl_port, int *irq)
-{
-	unsigned long reg = data_port;
-	int i;
-	int regincr = 1;
-
-	/* The Empeg board has the first two address lines unused */
-	if (machine_is_empeg())
-		regincr = 1 << 2;
-
-	/* The LART doesn't use A0 for IDE */
-	if (machine_is_lart())
-		regincr = 1 << 1;
-
-	memset(hw, 0, sizeof(*hw));
-
-	for (i = 0; i <= 7; i++) {
-		hw->io_ports_array[i] = reg;
-		reg += regincr;
-	}
-
-	hw->io_ports.ctl_addr = ctrl_port;
-
-	if (irq)
-		*irq = 0;
-}
-
-/*
- * This registers the standard ports for this architecture with the IDE
- * driver.
- */
-static __inline__ void
-ide_init_default_hwifs(void)
-{
-    if (machine_is_lart()) {
-#ifdef CONFIG_SA1100_LART
-        hw_regs_t hw;
-
-        /* Enable GPIO as interrupt line */
-        GPDR &= ~LART_GPIO_IDE;
-	set_irq_type(LART_IRQ_IDE, IRQ_TYPE_EDGE_RISING);
-
-        /* set PCMCIA interface timing */
-        MECR = 0x00060006;
-
-        /* init the interface */
-	ide_init_hwif_ports(&hw, PCMCIA_IO_0_BASE + 0x0000, PCMCIA_IO_0_BASE + 0x1000, NULL);
-        hw.irq = LART_IRQ_IDE;
-        ide_register_hw(&hw);
-#endif
-    }
-}
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index d1193884d76d..ab5f7a21350b 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -400,9 +400,9 @@ config CPU_FEROCEON_OLD_ID
 # ARMv6
 config CPU_V6
 	bool "Support ARM V6 processor"
-	depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3 || ARCH_MSM7X00A || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176
+	depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3 || ARCH_MSM || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176
 	default y if ARCH_MX3
-	default y if ARCH_MSM7X00A
+	default y if ARCH_MSM
 	select CPU_32v6
 	select CPU_ABRT_EV6
 	select CPU_PABRT_NOIFAR
diff --git a/arch/arm/plat-mxc/include/mach/mxc_nand.h b/arch/arm/plat-mxc/include/mach/mxc_nand.h
new file mode 100644
index 000000000000..2b972df22d12
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_nand.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Sascha Hauer, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_NAND_H
+#define __ASM_ARCH_NAND_H
+
+struct mxc_nand_platform_data {
+	int width;	/* data bus width in bytes */
+	int hw_ecc;	/* 0 if supress hardware ECC */
+};
+#endif /* __ASM_ARCH_NAND_H */
diff --git a/arch/arm/plat-omap/include/mach/onenand.h b/arch/arm/plat-omap/include/mach/onenand.h
index d57f20226b28..4649d302c263 100644
--- a/arch/arm/plat-omap/include/mach/onenand.h
+++ b/arch/arm/plat-omap/include/mach/onenand.h
@@ -16,6 +16,10 @@ struct omap_onenand_platform_data {
 	int			gpio_irq;
 	struct mtd_partition	*parts;
 	int			nr_parts;
-	int                     (*onenand_setup)(void __iomem *);
+	int                     (*onenand_setup)(void __iomem *, int freq);
 	int			dma_channel;
 };
+
+int omap2_onenand_rephase(void);
+
+#define ONENAND_MAX_PARTITIONS 8