summary refs log tree commit diff
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-19 13:35:07 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-19 13:35:07 -0700
commite4e47eb15b7884963efe7f98231009c5770a2c3d (patch)
treeebd3536a3aa728089168f072c88858578535046d /arch
parent711f77f53c5ff6aa61dbe8e5f518e50d6306e89d (diff)
parent7b52161d14fa8a22a2387f4aa2fb7b854587830d (diff)
downloadlinux-e4e47eb15b7884963efe7f98231009c5770a2c3d.tar.gz
Merge branch 'msm-core' of git://codeaurora.org/quic/kernel/dwalker/linux-msm
* 'msm-core' of git://codeaurora.org/quic/kernel/dwalker/linux-msm: (72 commits)
  msm: 7x30 Kconfig and makefile changes
  msm: clock support for the MSM7x30 CPU.
  msm: physical offset for MSM7X30
  msm: io: add io support for 7x30
  msm: Add extern for 7x30 clock list.
  msm: dma: add 7x30 security domain abstraction
  msm: update basic board layout for MSM7x30
  msm: add devices-msm7x30.c
  msm: add msm_iomap-7x30.h for MSM7x30 support
  msm: irqs: add irqs-7x30.h for MSM7x30 support
  msm: 8x50 Kconfig changes
  msm: physical offset for QSD8x50
  msm: io: add io support for 8x50
  msm: add extern for 8x50 clock list.
  msm: add devices-qsd8x50.c
  msm: update basic board layout for QSD8x50
  msm: add msm_iomap-8x50.h for QSD8x50 support
  msm: irqs: add irqs-8x50.h for QSD8x50 support
  msm: timer: allow MSM_DGT_BASE to be overriden
  msm: add Qualcomm 7x30 interrupt controller driver.
  ...
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-msm/Kconfig92
-rw-r--r--arch/arm/mach-msm/Makefile23
-rw-r--r--arch/arm/mach-msm/acpuclock-arm11.c526
-rw-r--r--arch/arm/mach-msm/acpuclock.h32
-rw-r--r--arch/arm/mach-msm/board-halibut.c17
-rw-r--r--arch/arm/mach-msm/board-mahimahi.c87
-rw-r--r--arch/arm/mach-msm/board-msm7x27.c179
-rw-r--r--arch/arm/mach-msm/board-msm7x30.c120
-rw-r--r--arch/arm/mach-msm/board-qsd8x50.c94
-rw-r--r--arch/arm/mach-msm/board-sapphire.c118
-rw-r--r--arch/arm/mach-msm/board-trout.c (renamed from arch/arm/mach-msm/board-dream.c)8
-rw-r--r--arch/arm/mach-msm/board-trout.h (renamed from arch/arm/mach-msm/board-dream.h)0
-rw-r--r--arch/arm/mach-msm/clock-7x01a.c126
-rw-r--r--arch/arm/mach-msm/clock-7x30.h168
-rw-r--r--arch/arm/mach-msm/clock-pcom.c131
-rw-r--r--arch/arm/mach-msm/clock-pcom.h153
-rw-r--r--arch/arm/mach-msm/clock.c258
-rw-r--r--arch/arm/mach-msm/clock.h71
-rw-r--r--arch/arm/mach-msm/devices-msm7x00.c (renamed from arch/arm/mach-msm/devices.c)125
-rw-r--r--arch/arm/mach-msm/devices-msm7x30.c128
-rw-r--r--arch/arm/mach-msm/devices-qsd8x50.c92
-rw-r--r--arch/arm/mach-msm/devices.h11
-rw-r--r--arch/arm/mach-msm/dma.c23
-rw-r--r--arch/arm/mach-msm/gpio.c85
-rw-r--r--arch/arm/mach-msm/include/mach/board.h14
-rw-r--r--arch/arm/mach-msm/include/mach/clk.h57
-rw-r--r--arch/arm/mach-msm/include/mach/dma.h32
-rw-r--r--arch/arm/mach-msm/include/mach/gpio.h142
-rw-r--r--arch/arm/mach-msm/include/mach/io.h5
-rw-r--r--arch/arm/mach-msm/include/mach/irqs-7x00.h75
-rw-r--r--arch/arm/mach-msm/include/mach/irqs-7x30.h170
-rw-r--r--arch/arm/mach-msm/include/mach/irqs-8x50.h105
-rw-r--r--arch/arm/mach-msm/include/mach/irqs.h81
-rw-r--r--arch/arm/mach-msm/include/mach/memory.h8
-rw-r--r--arch/arm/mach-msm/include/mach/msm_fb.h147
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-7x00.h139
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-7x30.h122
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-8x50.h147
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap.h95
-rw-r--r--arch/arm/mach-msm/include/mach/msm_smd.h109
-rw-r--r--arch/arm/mach-msm/include/mach/sirc.h115
-rw-r--r--arch/arm/mach-msm/include/mach/system.h5
-rw-r--r--arch/arm/mach-msm/include/mach/vreg.h2
-rw-r--r--arch/arm/mach-msm/io.c75
-rw-r--r--arch/arm/mach-msm/irq-vic.c365
-rw-r--r--arch/arm/mach-msm/irq.c4
-rw-r--r--arch/arm/mach-msm/last_radio_log.c82
-rw-r--r--arch/arm/mach-msm/proc_comm.c26
-rw-r--r--arch/arm/mach-msm/proc_comm.h105
-rw-r--r--arch/arm/mach-msm/sirc.c177
-rw-r--r--arch/arm/mach-msm/smd.c1046
-rw-r--r--arch/arm/mach-msm/smd_debug.c315
-rw-r--r--arch/arm/mach-msm/smd_private.h403
-rw-r--r--arch/arm/mach-msm/timer.c2
-rw-r--r--arch/arm/mach-msm/vreg.c154
55 files changed, 6538 insertions, 453 deletions
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index b9fd5c528e5b..47264a76eeb3 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1,7 +1,80 @@
 if ARCH_MSM
 
-comment "MSM Board Type"
+choice
+	prompt "Qualcomm MSM SoC Type"
+	default ARCH_MSM7X00A
+
+config ARCH_MSM7X00A
+	bool "MSM7x00A / MSM7x01A"
+	select ARCH_MSM_ARM11
+	select MSM_SMD
+	select MSM_SMD_PKG3
+	select CPU_V6
+
+config ARCH_MSM7X30
+	bool "MSM7x30"
+	select ARCH_MSM_SCORPION
+	select MSM_SMD
+	select MSM_VIC
+	select CPU_V7
+	select MSM_REMOTE_SPINLOCK_DEKKERS
+
+config ARCH_QSD8X50
+	bool "QSD8X50"
+	select ARCH_MSM_SCORPION
+	select MSM_SMD
+	select MSM_VIC
+	select CPU_V7
+	select MSM_REMOTE_SPINLOCK_LDREX
+endchoice
+
+config MSM_SOC_REV_A
+	bool
+
+config  ARCH_MSM_ARM11
+	bool
+config  ARCH_MSM_SCORPION
+	bool
+
+config  MSM_VIC
+	bool
+
+menu "Qualcomm MSM Board Type"
+
+config MACH_HALIBUT
 	depends on ARCH_MSM
+	depends on ARCH_MSM7X00A
+	bool "Halibut Board (QCT SURF7201A)"
+	help
+	  Support for the Qualcomm SURF7201A eval board.
+
+config MACH_TROUT
+	depends on ARCH_MSM
+	depends on ARCH_MSM7X00A
+	bool "HTC Dream (aka trout)"
+	help
+	  Support for the HTC Dream, T-Mobile G1, Android ADP1 devices.
+
+config MACH_MSM7X30_SURF
+	depends on ARCH_MSM7X30
+	bool "MSM7x30 SURF"
+	help
+	  Support for the Qualcomm MSM7x30 SURF eval board.
+
+config MACH_QSD8X50_SURF
+	depends on ARCH_QSD8X50
+	bool "QSD8x50 SURF"
+	help
+	  Support for the Qualcomm QSD8x50 SURF eval board.
+
+config MACH_QSD8X50A_ST1_5
+	depends on ARCH_QSD8X50
+	select MSM_SOC_REV_A
+	bool "QSD8x50A ST1.5"
+	help
+	  Support for the Qualcomm ST1.5.
+
+endmenu
 
 config MSM_DEBUG_UART
 	int
@@ -27,19 +100,10 @@ choice
 		bool "UART3"
 endchoice
 
-config MACH_HALIBUT
-	depends on ARCH_MSM
-	select CPU_V6
-	default y
-	bool "Halibut Board (QCT SURF7201A)"
-	help
-	  Support for the Qualcomm SURF7201A eval board.
+config MSM_SMD_PKG3
+	bool
 
-config MACH_TROUT
-	select CPU_V6
-	default y
-	bool "HTC Dream (aka trout)"
-	help
-	  Support for the HTC Dream, T-Mobile G1, Android ADP1 devices.
+config MSM_SMD
+	bool
 
 endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 91e6f5c95dc1..66677f0acaed 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -1,9 +1,22 @@
-obj-y += io.o idle.o irq.o timer.o dma.o
-obj-y += devices.o
 obj-y += proc_comm.o
+obj-y += io.o idle.o timer.o dma.o
 obj-y += vreg.o
-obj-y += clock.o clock-7x01a.o
+obj-y += acpuclock-arm11.o
+obj-y += clock.o clock-pcom.o
+obj-y += gpio.o
 
-obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o
+ifdef CONFIG_MSM_VIC
+obj-y += irq-vic.o
+else
+obj-y += irq.o
+endif
+
+obj-$(CONFIG_ARCH_QSD8X50) += sirc.o
+obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
+obj-$(CONFIG_MSM_SMD) += last_radio_log.o
+
+obj-$(CONFIG_MACH_TROUT) += board-trout.o devices-msm7x00.o
+obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
+obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
+obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
 
-obj-$(CONFIG_MACH_TROUT) += board-dream.o
diff --git a/arch/arm/mach-msm/acpuclock-arm11.c b/arch/arm/mach-msm/acpuclock-arm11.c
new file mode 100644
index 000000000000..af5e85b91d02
--- /dev/null
+++ b/arch/arm/mach-msm/acpuclock-arm11.c
@@ -0,0 +1,526 @@
+/* arch/arm/mach-msm/acpuclock.c
+ *
+ * MSM architecture clock driver
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ * Author: San Mehat <san@android.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/version.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+
+#include "proc_comm.h"
+#include "acpuclock.h"
+
+
+#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)
+
+/*
+ * ARM11 clock configuration for specific ACPU speeds
+ */
+
+#define ACPU_PLL_TCXO	-1
+#define ACPU_PLL_0	0
+#define ACPU_PLL_1	1
+#define ACPU_PLL_2	2
+#define ACPU_PLL_3	3
+
+#define PERF_SWITCH_DEBUG 0
+#define PERF_SWITCH_STEP_DEBUG 0
+
+struct clock_state
+{
+	struct clkctl_acpu_speed	*current_speed;
+	struct mutex			lock;
+	uint32_t			acpu_switch_time_us;
+	uint32_t			max_speed_delta_khz;
+	uint32_t			vdd_switch_time_us;
+	unsigned long			power_collapse_khz;
+	unsigned long			wait_for_irq_khz;
+};
+
+static struct clk *ebi1_clk;
+static struct clock_state drv_state = { 0 };
+
+static void __init acpuclk_init(void);
+
+/* MSM7201A Levels 3-6 all correspond to 1.2V, level 7 corresponds to 1.325V. */
+enum {
+	VDD_0 = 0,
+	VDD_1 = 1,
+	VDD_2 = 2,
+	VDD_3 = 3,
+	VDD_4 = 3,
+	VDD_5 = 3,
+	VDD_6 = 3,
+	VDD_7 = 7,
+	VDD_END
+};
+
+struct clkctl_acpu_speed {
+	unsigned int	a11clk_khz;
+	int		pll;
+	unsigned int	a11clk_src_sel;
+	unsigned int	a11clk_src_div;
+	unsigned int	ahbclk_khz;
+	unsigned int	ahbclk_div;
+	int		vdd;
+	unsigned int 	axiclk_khz;
+	unsigned long	lpj; /* loops_per_jiffy */
+/* Index in acpu_freq_tbl[] for steppings. */
+	short		down;
+	short		up;
+};
+
+/*
+ * ACPU speed table. Complete table is shown but certain speeds are commented
+ * out to optimized speed switching. Initalize loops_per_jiffy to 0.
+ *
+ * Table stepping up/down is optimized for 256mhz jumps while staying on the
+ * same PLL.
+ */
+#if (0)
+static struct clkctl_acpu_speed  acpu_freq_tbl[] = {
+	{ 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, VDD_0, 30720, 0, 0, 8 },
+	{ 61440, ACPU_PLL_0,  4, 3, 61440,  0, VDD_0, 30720,  0, 0, 8 },
+	{ 81920, ACPU_PLL_0,  4, 2, 40960,  1, VDD_0, 61440,  0, 0, 8 },
+	{ 96000, ACPU_PLL_1,  1, 7, 48000,  1, VDD_0, 61440,  0, 0, 9 },
+	{ 122880, ACPU_PLL_0, 4, 1, 61440,  1, VDD_3, 61440,  0, 0, 8 },
+	{ 128000, ACPU_PLL_1, 1, 5, 64000,  1, VDD_3, 61440,  0, 0, 12 },
+	{ 176000, ACPU_PLL_2, 2, 5, 88000,  1, VDD_3, 61440,  0, 0, 11 },
+	{ 192000, ACPU_PLL_1, 1, 3, 64000,  2, VDD_3, 61440,  0, 0, 12 },
+	{ 245760, ACPU_PLL_0, 4, 0, 81920,  2, VDD_4, 61440,  0, 0, 12 },
+	{ 256000, ACPU_PLL_1, 1, 2, 128000, 2, VDD_5, 128000, 0, 0, 12 },
+	{ 264000, ACPU_PLL_2, 2, 3, 88000,  2, VDD_5, 128000, 0, 6, 13 },
+	{ 352000, ACPU_PLL_2, 2, 2, 88000,  3, VDD_5, 128000, 0, 6, 13 },
+	{ 384000, ACPU_PLL_1, 1, 1, 128000, 2, VDD_6, 128000, 0, 5, -1 },
+	{ 528000, ACPU_PLL_2, 2, 1, 132000, 3, VDD_7, 128000, 0, 11, -1 },
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+};
+#else /* Table of freq we currently use. */
+static struct clkctl_acpu_speed  acpu_freq_tbl[] = {
+	{ 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, VDD_0, 30720, 0, 0, 4 },
+	{ 122880, ACPU_PLL_0, 4, 1, 61440, 1, VDD_3, 61440, 0, 0, 4 },
+	{ 128000, ACPU_PLL_1, 1, 5, 64000, 1, VDD_3, 61440, 0, 0, 6 },
+	{ 176000, ACPU_PLL_2, 2, 5, 88000, 1, VDD_3, 61440, 0, 0, 5 },
+	{ 245760, ACPU_PLL_0, 4, 0, 81920, 2, VDD_4, 61440, 0, 0, 5 },
+	{ 352000, ACPU_PLL_2, 2, 2, 88000, 3, VDD_5, 128000, 0, 3, 7 },
+	{ 384000, ACPU_PLL_1, 1, 1, 128000, 2, VDD_6, 128000, 0, 2, -1 },
+	{ 528000, ACPU_PLL_2, 2, 1, 132000, 3, VDD_7, 128000, 0, 5, -1 },
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+};
+#endif
+
+
+#ifdef CONFIG_CPU_FREQ_TABLE
+static struct cpufreq_frequency_table freq_table[] = {
+	{ 0, 122880 },
+	{ 1, 128000 },
+	{ 2, 245760 },
+	{ 3, 384000 },
+	{ 4, 528000 },
+	{ 5, CPUFREQ_TABLE_END },
+};
+#endif
+
+static int pc_pll_request(unsigned id, unsigned on)
+{
+	int res;
+	on = !!on;
+
+#if PERF_SWITCH_DEBUG
+	if (on)
+		printk(KERN_DEBUG "Enabling PLL %d\n", id);
+	else
+		printk(KERN_DEBUG "Disabling PLL %d\n", id);
+#endif
+
+	res = msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on);
+	if (res < 0)
+		return res;
+
+#if PERF_SWITCH_DEBUG
+	if (on)
+		printk(KERN_DEBUG "PLL %d enabled\n", id);
+	else
+		printk(KERN_DEBUG "PLL %d disabled\n", id);
+#endif
+	return res;
+}
+
+
+/*----------------------------------------------------------------------------
+ * ARM11 'owned' clock control
+ *---------------------------------------------------------------------------*/
+
+unsigned long acpuclk_power_collapse(void) {
+	int ret = acpuclk_get_rate();
+	ret *= 1000;
+	if (ret > drv_state.power_collapse_khz)
+		acpuclk_set_rate(drv_state.power_collapse_khz, 1);
+	return ret;
+}
+
+unsigned long acpuclk_get_wfi_rate(void)
+{
+	return drv_state.wait_for_irq_khz;
+}
+
+unsigned long acpuclk_wait_for_irq(void) {
+	int ret = acpuclk_get_rate();
+	ret *= 1000;
+	if (ret > drv_state.wait_for_irq_khz)
+		acpuclk_set_rate(drv_state.wait_for_irq_khz, 1);
+	return ret;
+}
+
+static int acpuclk_set_vdd_level(int vdd)
+{
+	uint32_t current_vdd;
+
+	current_vdd = readl(A11S_VDD_SVS_PLEVEL_ADDR) & 0x07;
+
+#if PERF_SWITCH_DEBUG
+	printk(KERN_DEBUG "acpuclock: Switching VDD from %u -> %d\n",
+	       current_vdd, vdd);
+#endif
+	writel((1 << 7) | (vdd << 3), A11S_VDD_SVS_PLEVEL_ADDR);
+	udelay(drv_state.vdd_switch_time_us);
+	if ((readl(A11S_VDD_SVS_PLEVEL_ADDR) & 0x7) != vdd) {
+#if PERF_SWITCH_DEBUG
+		printk(KERN_ERR "acpuclock: VDD set failed\n");
+#endif
+		return -EIO;
+	}
+
+#if PERF_SWITCH_DEBUG
+	printk(KERN_DEBUG "acpuclock: VDD switched\n");
+#endif
+	return 0;
+}
+
+/* Set proper dividers for the given clock speed. */
+static void acpuclk_set_div(const struct clkctl_acpu_speed *hunt_s) {
+	uint32_t reg_clkctl, reg_clksel, clk_div;
+
+	/* AHB_CLK_DIV */
+	clk_div = (readl(A11S_CLK_SEL_ADDR) >> 1) & 0x03;
+	/*
+	 * If the new clock divider is higher than the previous, then
+	 * program the divider before switching the clock
+	 */
+	if (hunt_s->ahbclk_div > clk_div) {
+		reg_clksel = readl(A11S_CLK_SEL_ADDR);
+		reg_clksel &= ~(0x3 << 1);
+		reg_clksel |= (hunt_s->ahbclk_div << 1);
+		writel(reg_clksel, A11S_CLK_SEL_ADDR);
+	}
+	if ((readl(A11S_CLK_SEL_ADDR) & 0x01) == 0) {
+		/* SRC0 */
+
+		/* Program clock source */
+		reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
+		reg_clkctl &= ~(0x07 << 4);
+		reg_clkctl |= (hunt_s->a11clk_src_sel << 4);
+		writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
+
+		/* Program clock divider */
+		reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
+		reg_clkctl &= ~0xf;
+		reg_clkctl |= hunt_s->a11clk_src_div;
+		writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
+
+		/* Program clock source selection */
+		reg_clksel = readl(A11S_CLK_SEL_ADDR);
+		reg_clksel |= 1; /* CLK_SEL_SRC1NO  == SRC1 */
+		writel(reg_clksel, A11S_CLK_SEL_ADDR);
+	} else {
+		/* SRC1 */
+
+		/* Program clock source */
+		reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
+		reg_clkctl &= ~(0x07 << 12);
+		reg_clkctl |= (hunt_s->a11clk_src_sel << 12);
+		writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
+
+		/* Program clock divider */
+		reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
+		reg_clkctl &= ~(0xf << 8);
+		reg_clkctl |= (hunt_s->a11clk_src_div << 8);
+		writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
+
+		/* Program clock source selection */
+		reg_clksel = readl(A11S_CLK_SEL_ADDR);
+		reg_clksel &= ~1; /* CLK_SEL_SRC1NO  == SRC0 */
+		writel(reg_clksel, A11S_CLK_SEL_ADDR);
+	}
+
+	/*
+	 * If the new clock divider is lower than the previous, then
+	 * program the divider after switching the clock
+	 */
+	if (hunt_s->ahbclk_div < clk_div) {
+		reg_clksel = readl(A11S_CLK_SEL_ADDR);
+		reg_clksel &= ~(0x3 << 1);
+		reg_clksel |= (hunt_s->ahbclk_div << 1);
+		writel(reg_clksel, A11S_CLK_SEL_ADDR);
+	}
+}
+
+int acpuclk_set_rate(unsigned long rate, int for_power_collapse)
+{
+	uint32_t reg_clkctl;
+	struct clkctl_acpu_speed *cur_s, *tgt_s, *strt_s;
+	int rc = 0;
+	unsigned int plls_enabled = 0, pll;
+
+	strt_s = cur_s = drv_state.current_speed;
+
+	WARN_ONCE(cur_s == NULL, "acpuclk_set_rate: not initialized\n");
+	if (cur_s == NULL)
+		return -ENOENT;
+
+	if (rate == (cur_s->a11clk_khz * 1000))
+		return 0;
+
+	for (tgt_s = acpu_freq_tbl; tgt_s->a11clk_khz != 0; tgt_s++) {
+		if (tgt_s->a11clk_khz == (rate / 1000))
+			break;
+	}
+
+	if (tgt_s->a11clk_khz == 0)
+		return -EINVAL;
+
+	/* Choose the highest speed speed at or below 'rate' with same PLL. */
+	if (for_power_collapse && tgt_s->a11clk_khz < cur_s->a11clk_khz) {
+		while (tgt_s->pll != ACPU_PLL_TCXO && tgt_s->pll != cur_s->pll)
+			tgt_s--;
+	}
+
+	if (strt_s->pll != ACPU_PLL_TCXO)
+		plls_enabled |= 1 << strt_s->pll;
+
+	if (!for_power_collapse) {
+		mutex_lock(&drv_state.lock);
+		if (strt_s->pll != tgt_s->pll && tgt_s->pll != ACPU_PLL_TCXO) {
+			rc = pc_pll_request(tgt_s->pll, 1);
+			if (rc < 0) {
+				pr_err("PLL%d enable failed (%d)\n",
+					tgt_s->pll, rc);
+				goto out;
+			}
+			plls_enabled |= 1 << tgt_s->pll;
+		}
+		/* Increase VDD if needed. */
+		if (tgt_s->vdd > cur_s->vdd) {
+			if ((rc = acpuclk_set_vdd_level(tgt_s->vdd)) < 0) {
+				printk(KERN_ERR "Unable to switch ACPU vdd\n");
+				goto out;
+			}
+		}
+	}
+
+	/* Set wait states for CPU inbetween frequency changes */
+	reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
+	reg_clkctl |= (100 << 16); /* set WT_ST_CNT */
+	writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
+
+#if PERF_SWITCH_DEBUG
+	printk(KERN_INFO "acpuclock: Switching from ACPU rate %u -> %u\n",
+	       strt_s->a11clk_khz * 1000, tgt_s->a11clk_khz * 1000);
+#endif
+
+	while (cur_s != tgt_s) {
+		/*
+		 * Always jump to target freq if within 256mhz, regulardless of
+		 * PLL. If differnece is greater, use the predefinied
+		 * steppings in the table.
+		 */
+		int d = abs((int)(cur_s->a11clk_khz - tgt_s->a11clk_khz));
+		if (d > drv_state.max_speed_delta_khz) {
+			/* Step up or down depending on target vs current. */
+			int clk_index = tgt_s->a11clk_khz > cur_s->a11clk_khz ?
+				cur_s->up : cur_s->down;
+			if (clk_index < 0) { /* This should not happen. */
+				printk(KERN_ERR "cur:%u target: %u\n",
+					cur_s->a11clk_khz, tgt_s->a11clk_khz);
+				rc = -EINVAL;
+				goto out;
+			}
+			cur_s = &acpu_freq_tbl[clk_index];
+		} else {
+			cur_s = tgt_s;
+		}
+#if PERF_SWITCH_STEP_DEBUG
+		printk(KERN_DEBUG "%s: STEP khz = %u, pll = %d\n",
+			__FUNCTION__, cur_s->a11clk_khz, cur_s->pll);
+#endif
+		if (!for_power_collapse&& cur_s->pll != ACPU_PLL_TCXO
+		    && !(plls_enabled & (1 << cur_s->pll))) {
+			rc = pc_pll_request(cur_s->pll, 1);
+			if (rc < 0) {
+				pr_err("PLL%d enable failed (%d)\n",
+					cur_s->pll, rc);
+				goto out;
+			}
+			plls_enabled |= 1 << cur_s->pll;
+		}
+
+		acpuclk_set_div(cur_s);
+		drv_state.current_speed = cur_s;
+		/* Re-adjust lpj for the new clock speed. */
+		loops_per_jiffy = cur_s->lpj;
+		udelay(drv_state.acpu_switch_time_us);
+	}
+
+	/* Nothing else to do for power collapse. */
+	if (for_power_collapse)
+		return 0;
+
+	/* Disable PLLs we are not using anymore. */
+	plls_enabled &= ~(1 << tgt_s->pll);
+	for (pll = ACPU_PLL_0; pll <= ACPU_PLL_2; pll++)
+		if (plls_enabled & (1 << pll)) {
+			rc = pc_pll_request(pll, 0);
+			if (rc < 0) {
+				pr_err("PLL%d disable failed (%d)\n", pll, rc);
+				goto out;
+			}
+		}
+
+	/* Change the AXI bus frequency if we can. */
+	if (strt_s->axiclk_khz != tgt_s->axiclk_khz) {
+		rc = clk_set_rate(ebi1_clk, tgt_s->axiclk_khz * 1000);
+		if (rc < 0)
+			pr_err("Setting AXI min rate failed!\n");
+	}
+
+	/* Drop VDD level if we can. */
+	if (tgt_s->vdd < strt_s->vdd) {
+		if (acpuclk_set_vdd_level(tgt_s->vdd) < 0)
+			printk(KERN_ERR "acpuclock: Unable to drop ACPU vdd\n");
+	}
+
+#if PERF_SWITCH_DEBUG
+	printk(KERN_DEBUG "%s: ACPU speed change complete\n", __FUNCTION__);
+#endif
+out:
+	if (!for_power_collapse)
+		mutex_unlock(&drv_state.lock);
+	return rc;
+}
+
+static void __init acpuclk_init(void)
+{
+	struct clkctl_acpu_speed *speed;
+	uint32_t div, sel;
+	int rc;
+
+	/*
+	 * Determine the rate of ACPU clock
+	 */
+
+	if (!(readl(A11S_CLK_SEL_ADDR) & 0x01)) { /* CLK_SEL_SRC1N0 */
+		/* CLK_SRC0_SEL */
+		sel = (readl(A11S_CLK_CNTL_ADDR) >> 12) & 0x7;
+		/* CLK_SRC0_DIV */
+		div = (readl(A11S_CLK_CNTL_ADDR) >> 8) & 0x0f;
+	} else {
+		/* CLK_SRC1_SEL */
+		sel = (readl(A11S_CLK_CNTL_ADDR) >> 4) & 0x07;
+		/* CLK_SRC1_DIV */
+		div = readl(A11S_CLK_CNTL_ADDR) & 0x0f;
+	}
+
+	for (speed = acpu_freq_tbl; speed->a11clk_khz != 0; speed++) {
+		if (speed->a11clk_src_sel == sel
+		 && (speed->a11clk_src_div == div))
+			break;
+	}
+	if (speed->a11clk_khz == 0) {
+		printk(KERN_WARNING "Warning - ACPU clock reports invalid speed\n");
+		return;
+	}
+
+	drv_state.current_speed = speed;
+
+	rc = clk_set_rate(ebi1_clk, speed->axiclk_khz * 1000);
+	if (rc < 0)
+		pr_err("Setting AXI min rate failed!\n");
+
+	printk(KERN_INFO "ACPU running at %d KHz\n", speed->a11clk_khz);
+}
+
+unsigned long acpuclk_get_rate(void)
+{
+	WARN_ONCE(drv_state.current_speed == NULL,
+		  "acpuclk_get_rate: not initialized\n");
+	if (drv_state.current_speed)
+		return drv_state.current_speed->a11clk_khz;
+	else
+		return 0;
+}
+
+uint32_t acpuclk_get_switch_time(void)
+{
+	return drv_state.acpu_switch_time_us;
+}
+
+/*----------------------------------------------------------------------------
+ * Clock driver initialization
+ *---------------------------------------------------------------------------*/
+
+/* Initalize the lpj field in the acpu_freq_tbl. */
+static void __init lpj_init(void)
+{
+	int i;
+	const struct clkctl_acpu_speed *base_clk = drv_state.current_speed;
+	for (i = 0; acpu_freq_tbl[i].a11clk_khz; i++) {
+		acpu_freq_tbl[i].lpj = cpufreq_scale(loops_per_jiffy,
+						base_clk->a11clk_khz,
+						acpu_freq_tbl[i].a11clk_khz);
+	}
+}
+
+void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *clkdata)
+{
+	pr_info("acpu_clock_init()\n");
+
+	ebi1_clk = clk_get(NULL, "ebi1_clk");
+
+	mutex_init(&drv_state.lock);
+	drv_state.acpu_switch_time_us = clkdata->acpu_switch_time_us;
+	drv_state.max_speed_delta_khz = clkdata->max_speed_delta_khz;
+	drv_state.vdd_switch_time_us = clkdata->vdd_switch_time_us;
+	drv_state.power_collapse_khz = clkdata->power_collapse_khz;
+	drv_state.wait_for_irq_khz = clkdata->wait_for_irq_khz;
+	acpuclk_init();
+	lpj_init();
+#ifdef CONFIG_CPU_FREQ_TABLE
+	cpufreq_frequency_table_get_attr(freq_table, smp_processor_id());
+#endif
+}
diff --git a/arch/arm/mach-msm/acpuclock.h b/arch/arm/mach-msm/acpuclock.h
new file mode 100644
index 000000000000..415de2eb9a5e
--- /dev/null
+++ b/arch/arm/mach-msm/acpuclock.h
@@ -0,0 +1,32 @@
+/* arch/arm/mach-msm/acpuclock.h
+ *
+ * MSM architecture clock driver header
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ * Author: San Mehat <san@android.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_ACPUCLOCK_H
+#define __ARCH_ARM_MACH_MSM_ACPUCLOCK_H
+
+int acpuclk_set_rate(unsigned long rate, int for_power_collapse);
+unsigned long acpuclk_get_rate(void);
+uint32_t acpuclk_get_switch_time(void);
+unsigned long acpuclk_wait_for_irq(void);
+unsigned long acpuclk_power_collapse(void);
+unsigned long acpuclk_get_wfi_rate(void);
+
+
+#endif
+
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c
index e61967dde9a1..7bd72e8f127e 100644
--- a/arch/arm/mach-msm/board-halibut.c
+++ b/arch/arm/mach-msm/board-halibut.c
@@ -26,6 +26,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/flash.h>
+#include <asm/setup.h>
 
 #include <mach/irqs.h>
 #include <mach/board.h>
@@ -77,14 +78,28 @@ static void __init halibut_init(void)
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
+static void __init halibut_fixup(struct machine_desc *desc, struct tag *tags,
+				 char **cmdline, struct meminfo *mi)
+{
+	mi->nr_banks=1;
+	mi->bank[0].start = PHYS_OFFSET;
+	mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
+	mi->bank[0].size = (101*1024*1024);
+}
+
 static void __init halibut_map_io(void)
 {
 	msm_map_common_io();
-	msm_clock_init();
+	msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
 }
 
 MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)")
+#ifdef CONFIG_MSM_DEBUG_UART
+	.phys_io        = MSM_DEBUG_UART_PHYS,
+	.io_pg_offst    = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
 	.boot_params	= 0x10000100,
+	.fixup		= halibut_fixup,
 	.map_io		= halibut_map_io,
 	.init_irq	= halibut_init_irq,
 	.init_machine	= halibut_init,
diff --git a/arch/arm/mach-msm/board-mahimahi.c b/arch/arm/mach-msm/board-mahimahi.c
new file mode 100644
index 000000000000..bcbefdfe7b5e
--- /dev/null
+++ b/arch/arm/mach-msm/board-mahimahi.c
@@ -0,0 +1,87 @@
+/* linux/arch/arm/mach-msm/board-mahimahi.c
+ *
+ * Copyright (C) 2009 Google, Inc.
+ * Copyright (C) 2009 HTC Corporation.
+ * Author: Dima Zavin <dima@android.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/gpio.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+
+#include <mach/board.h>
+#include <mach/hardware.h>
+#include <mach/system.h>
+
+#include "board-mahimahi.h"
+#include "devices.h"
+#include "proc_comm.h"
+
+static uint debug_uart;
+
+module_param_named(debug_uart, debug_uart, uint, 0);
+
+static struct platform_device *devices[] __initdata = {
+#if !defined(CONFIG_MSM_SERIAL_DEBUGGER)
+	&msm_device_uart1,
+#endif
+	&msm_device_uart_dm1,
+	&msm_device_nand,
+};
+
+static void __init mahimahi_init(void)
+{
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init mahimahi_fixup(struct machine_desc *desc, struct tag *tags,
+				 char **cmdline, struct meminfo *mi)
+{
+	mi->nr_banks = 2;
+	mi->bank[0].start = PHYS_OFFSET;
+	mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
+	mi->bank[0].size = (219*1024*1024);
+	mi->bank[1].start = MSM_HIGHMEM_BASE;
+	mi->bank[1].node = PHYS_TO_NID(MSM_HIGHMEM_BASE);
+	mi->bank[1].size = MSM_HIGHMEM_SIZE;
+}
+
+static void __init mahimahi_map_io(void)
+{
+	msm_map_common_io();
+	msm_clock_init();
+}
+
+extern struct sys_timer msm_timer;
+
+MACHINE_START(MAHIMAHI, "mahimahi")
+#ifdef CONFIG_MSM_DEBUG_UART
+	.phys_io        = MSM_DEBUG_UART_PHYS,
+	.io_pg_offst    = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+	.boot_params	= 0x20000100,
+	.fixup		= mahimahi_fixup,
+	.map_io		= mahimahi_map_io,
+	.init_irq	= msm_init_irq,
+	.init_machine	= mahimahi_init,
+	.timer		= &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
new file mode 100644
index 000000000000..cccb9f3c9d01
--- /dev/null
+++ b/arch/arm/mach-msm/board-msm7x27.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * 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/input.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/power_supply.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+#include <asm/setup.h>
+#ifdef CONFIG_CACHE_L2X0
+#include <asm/hardware/cache-l2x0.h>
+#endif
+
+#include <mach/vreg.h>
+#include <mach/mpp.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include "devices.h"
+#include "socinfo.h"
+#include "clock.h"
+
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.start	= 0x9C004300,
+		.end	= 0x9C0043ff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= MSM_GPIO_TO_INT(132),
+		.end	= MSM_GPIO_TO_INT(132),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(smc91x_resources),
+	.resource	= smc91x_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&msm_device_uart3,
+	&msm_device_smd,
+	&msm_device_dmov,
+	&msm_device_nand,
+	&smc91x_device,
+};
+
+extern struct sys_timer msm_timer;
+
+static void __init msm7x2x_init_irq(void)
+{
+	msm_init_irq();
+}
+
+static void __init msm7x2x_init(void)
+{
+	if (socinfo_init() < 0)
+		BUG();
+
+	if (machine_is_msm7x25_ffa() || machine_is_msm7x27_ffa()) {
+		smc91x_resources[0].start = 0x98000300;
+		smc91x_resources[0].end = 0x980003ff;
+		smc91x_resources[1].start = MSM_GPIO_TO_INT(85);
+		smc91x_resources[1].end = MSM_GPIO_TO_INT(85);
+		if (gpio_tlmm_config(GPIO_CFG(85, 0,
+					      GPIO_INPUT,
+					      GPIO_PULL_DOWN,
+					      GPIO_2MA),
+				     GPIO_ENABLE)) {
+			printk(KERN_ERR
+			       "%s: Err: Config GPIO-85 INT\n",
+				__func__);
+		}
+	}
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init msm7x2x_map_io(void)
+{
+	msm_map_common_io();
+	/* Technically dependent on the SoC but using machine_is
+	 * macros since socinfo is not available this early and there
+	 * are plans to restructure the code which will eliminate the
+	 * need for socinfo.
+	 */
+	if (machine_is_msm7x27_surf() || machine_is_msm7x27_ffa())
+		msm_clock_init(msm_clocks_7x27, msm_num_clocks_7x27);
+
+	if (machine_is_msm7x25_surf() || machine_is_msm7x25_ffa())
+		msm_clock_init(msm_clocks_7x25, msm_num_clocks_7x25);
+
+#ifdef CONFIG_CACHE_L2X0
+	if (machine_is_msm7x27_surf() || machine_is_msm7x27_ffa()) {
+		/* 7x27 has 256KB L2 cache:
+			64Kb/Way and 4-Way Associativity;
+			R/W latency: 3 cycles;
+			evmon/parity/share disabled. */
+		l2x0_init(MSM_L2CC_BASE, 0x00068012, 0xfe000000);
+	}
+#endif
+}
+
+MACHINE_START(MSM7X27_SURF, "QCT MSM7x27 SURF")
+#ifdef CONFIG_MSM_DEBUG_UART
+	.phys_io        = MSM_DEBUG_UART_PHYS,
+	.io_pg_offst    = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+	.boot_params	= PHYS_OFFSET + 0x100,
+	.map_io		= msm7x2x_map_io,
+	.init_irq	= msm7x2x_init_irq,
+	.init_machine	= msm7x2x_init,
+	.timer		= &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM7X27_FFA, "QCT MSM7x27 FFA")
+#ifdef CONFIG_MSM_DEBUG_UART
+	.phys_io        = MSM_DEBUG_UART_PHYS,
+	.io_pg_offst    = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+	.boot_params	= PHYS_OFFSET + 0x100,
+	.map_io		= msm7x2x_map_io,
+	.init_irq	= msm7x2x_init_irq,
+	.init_machine	= msm7x2x_init,
+	.timer		= &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM7X25_SURF, "QCT MSM7x25 SURF")
+#ifdef CONFIG_MSM_DEBUG_UART
+	.phys_io        = MSM_DEBUG_UART_PHYS,
+	.io_pg_offst    = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+	.boot_params	= PHYS_OFFSET + 0x100,
+	.map_io		= msm7x2x_map_io,
+	.init_irq	= msm7x2x_init_irq,
+	.init_machine	= msm7x2x_init,
+	.timer		= &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM7X25_FFA, "QCT MSM7x25 FFA")
+#ifdef CONFIG_MSM_DEBUG_UART
+	.phys_io        = MSM_DEBUG_UART_PHYS,
+	.io_pg_offst    = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+	.boot_params	= PHYS_OFFSET + 0x100,
+	.map_io		= msm7x2x_map_io,
+	.init_irq	= msm7x2x_init_irq,
+	.init_machine	= msm7x2x_init,
+	.timer		= &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
new file mode 100644
index 000000000000..bac1f3c38a3b
--- /dev/null
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -0,0 +1,120 @@
+/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/setup.h>
+
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/memory.h>
+#include <mach/msm_iomap.h>
+#include <mach/dma.h>
+
+#include <mach/vreg.h>
+#include "devices.h"
+#include "proc_comm.h"
+
+extern struct sys_timer msm_timer;
+
+#ifdef CONFIG_SERIAL_MSM_CONSOLE
+static struct msm_gpio uart2_config_data[] = {
+	{ GPIO_CFG(49, 2, GPIO_OUTPUT,  GPIO_PULL_DOWN, GPIO_2MA), "UART2_RFR"},
+	{ GPIO_CFG(50, 2, GPIO_INPUT,   GPIO_PULL_DOWN, GPIO_2MA), "UART2_CTS"},
+	{ GPIO_CFG(51, 2, GPIO_INPUT,   GPIO_PULL_DOWN, GPIO_2MA), "UART2_Rx"},
+	{ GPIO_CFG(52, 2, GPIO_OUTPUT,  GPIO_PULL_DOWN, GPIO_2MA), "UART2_Tx"},
+};
+
+static void msm7x30_init_uart2(void)
+{
+	msm_gpios_request_enable(uart2_config_data,
+			ARRAY_SIZE(uart2_config_data));
+
+}
+#endif
+
+static struct platform_device *devices[] __initdata = {
+#if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER)
+        &msm_device_uart2,
+#endif
+
+};
+
+static void __init msm7x30_init_irq(void)
+{
+	msm_init_irq();
+}
+
+static void __init msm7x30_init(void)
+{
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+#ifdef CONFIG_SERIAL_MSM_CONSOLE
+	msm7x30_init_uart2();
+#endif
+
+}
+
+static void __init msm7x30_map_io(void)
+{
+	msm_map_msm7x30_io();
+	msm_clock_init(msm_clocks_7x30, msm_num_clocks_7x30);
+}
+
+MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF")
+#ifdef CONFIG_MSM_DEBUG_UART
+	.phys_io  = MSM_DEBUG_UART_PHYS,
+	.io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+	.boot_params = PHYS_OFFSET + 0x100,
+	.map_io = msm7x30_map_io,
+	.init_irq = msm7x30_init_irq,
+	.init_machine = msm7x30_init,
+	.timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA")
+#ifdef CONFIG_MSM_DEBUG_UART
+	.phys_io  = MSM_DEBUG_UART_PHYS,
+	.io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+	.boot_params = PHYS_OFFSET + 0x100,
+	.map_io = msm7x30_map_io,
+	.init_irq = msm7x30_init_irq,
+	.init_machine = msm7x30_init,
+	.timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID")
+#ifdef CONFIG_MSM_DEBUG_UART
+	.phys_io  = MSM_DEBUG_UART_PHYS,
+	.io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+	.boot_params = PHYS_OFFSET + 0x100,
+	.map_io = msm7x30_map_io,
+	.init_irq = msm7x30_init_irq,
+	.init_machine = msm7x30_init,
+	.timer = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
new file mode 100644
index 000000000000..ec4606643d2c
--- /dev/null
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -0,0 +1,94 @@
+/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+#include <linux/delay.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+
+#include <mach/board.h>
+#include <mach/irqs.h>
+#include <mach/sirc.h>
+#include <mach/gpio.h>
+
+#include "devices.h"
+
+extern struct sys_timer msm_timer;
+
+static struct msm_gpio uart3_config_data[] = {
+	{ GPIO_CFG(86, 1, GPIO_INPUT,   GPIO_PULL_DOWN, GPIO_2MA), "UART2_Rx"},
+	{ GPIO_CFG(87, 1, GPIO_OUTPUT,  GPIO_PULL_DOWN, GPIO_2MA), "UART2_Tx"},
+};
+
+static struct platform_device *devices[] __initdata = {
+	&msm_device_uart3,
+};
+
+static void msm8x50_init_uart3(void)
+{
+	msm_gpios_request_enable(uart3_config_data,
+				ARRAY_SIZE(uart3_config_data));
+}
+
+static void __init qsd8x50_map_io(void)
+{
+	msm_map_qsd8x50_io();
+	msm_clock_init(msm_clocks_8x50, msm_num_clocks_8x50);
+}
+
+static void __init qsd8x50_init_irq(void)
+{
+	msm_init_irq();
+	msm_init_sirc();
+}
+
+static void __init qsd8x50_init(void)
+{
+	msm8x50_init_uart3();
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF")
+#ifdef CONFIG_MSM_DEBUG_UART
+	.phys_io  = MSM_DEBUG_UART_PHYS,
+	.io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+	.boot_params = PHYS_OFFSET + 0x100,
+	.map_io = qsd8x50_map_io,
+	.init_irq = qsd8x50_init_irq,
+	.init_machine = qsd8x50_init,
+	.timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(QSD8X50A_ST1_5, "QCT QSD8X50A ST1.5")
+#ifdef CONFIG_MSM_DEBUG_UART
+	.phys_io  = MSM_DEBUG_UART_PHYS,
+	.io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+	.boot_params = PHYS_OFFSET + 0x100,
+	.map_io = qsd8x50_map_io,
+	.init_irq = qsd8x50_init_irq,
+	.init_machine = qsd8x50_init,
+	.timer = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-sapphire.c b/arch/arm/mach-msm/board-sapphire.c
new file mode 100644
index 000000000000..2bc1b9d5623e
--- /dev/null
+++ b/arch/arm/mach-msm/board-sapphire.c
@@ -0,0 +1,118 @@
+/* linux/arch/arm/mach-msm/board-sapphire.c
+ * Copyright (C) 2007-2009 HTC Corporation.
+ * Author: Thomas Tsai <thomas_tsai@htc.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/input.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sysdev.h>
+
+#include <linux/delay.h>
+
+#include <asm/gpio.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+#include <asm/system.h>
+#include <mach/system.h>
+#include <mach/vreg.h>
+#include <mach/board.h>
+
+#include <asm/io.h>
+#include <asm/delay.h>
+#include <asm/setup.h>
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include "gpio_chip.h"
+#include "board-sapphire.h"
+#include "proc_comm.h"
+#include "devices.h"
+
+void msm_init_irq(void);
+void msm_init_gpio(void);
+
+static struct platform_device *devices[] __initdata = {
+	&msm_device_smd,
+	&msm_device_dmov,
+	&msm_device_nand,
+	&msm_device_uart1,
+	&msm_device_uart3,
+};
+
+extern struct sys_timer msm_timer;
+
+static void __init sapphire_init_irq(void)
+{
+	msm_init_irq();
+}
+
+static void __init sapphire_init(void)
+{
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static struct map_desc sapphire_io_desc[] __initdata = {
+	{
+		.virtual = SAPPHIRE_CPLD_BASE,
+		.pfn     = __phys_to_pfn(SAPPHIRE_CPLD_START),
+		.length  = SAPPHIRE_CPLD_SIZE,
+		.type    = MT_DEVICE_NONSHARED
+	}
+};
+
+static void __init sapphire_fixup(struct machine_desc *desc, struct tag *tags,
+				  char **cmdline, struct meminfo *mi)
+{
+	int smi_sz = parse_tag_smi((const struct tag *)tags);
+
+	mi->nr_banks = 1;
+	mi->bank[0].start = PHYS_OFFSET;
+	mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
+	if (smi_sz == 32) {
+		mi->bank[0].size = (84*1024*1024);
+	} else if (smi_sz == 64) {
+		mi->bank[0].size = (101*1024*1024);
+	} else {
+		/* Give a default value when not get smi size */
+		smi_sz = 64;
+		mi->bank[0].size = (101*1024*1024);
+	}
+}
+
+static void __init sapphire_map_io(void)
+{
+	msm_map_common_io();
+	iotable_init(sapphire_io_desc, ARRAY_SIZE(sapphire_io_desc));
+	msm_clock_init();
+}
+
+MACHINE_START(SAPPHIRE, "sapphire")
+/* Maintainer: Brian Swetland <swetland@google.com> */
+#ifdef CONFIG_MSM_DEBUG_UART
+	.phys_io        = MSM_DEBUG_UART_PHYS,
+	.io_pg_offst    = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+	.boot_params    = PHYS_OFFSET + 0x100,
+	.fixup          = sapphire_fixup,
+	.map_io         = sapphire_map_io,
+	.init_irq       = sapphire_init_irq,
+	.init_machine   = sapphire_init,
+	.timer          = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-dream.c b/arch/arm/mach-msm/board-trout.c
index 21afa8513168..dca5a5f062dc 100644
--- a/arch/arm/mach-msm/board-dream.c
+++ b/arch/arm/mach-msm/board-trout.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-msm/board-dream.c
+/* linux/arch/arm/mach-msm/board-trout.c
  *
  * Copyright (C) 2009 Google, Inc.
  * Author: Brian Swetland <swetland@google.com>
@@ -28,7 +28,7 @@
 #include <mach/msm_iomap.h>
 
 #include "devices.h"
-#include "board-dream.h"
+#include "board-trout.h"
 
 static struct platform_device *devices[] __initdata = {
 	&msm_device_uart3,
@@ -78,12 +78,14 @@ static void __init trout_map_io(void)
 	writeb(0x80, TROUT_CPLD_BASE + 0x00);
 #endif
 
-	msm_clock_init();
+	msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
 }
 
 MACHINE_START(TROUT, "HTC Dream")
+#ifdef CONFIG_MSM_DEBUG_UART
 	.phys_io	= MSM_DEBUG_UART_PHYS,
 	.io_pg_offst	= ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
 	.boot_params	= 0x10000100,
 	.fixup		= trout_fixup,
 	.map_io		= trout_map_io,
diff --git a/arch/arm/mach-msm/board-dream.h b/arch/arm/mach-msm/board-trout.h
index 4f345a5a0a61..4f345a5a0a61 100644
--- a/arch/arm/mach-msm/board-dream.h
+++ b/arch/arm/mach-msm/board-trout.h
diff --git a/arch/arm/mach-msm/clock-7x01a.c b/arch/arm/mach-msm/clock-7x01a.c
deleted file mode 100644
index 62230a3428ee..000000000000
--- a/arch/arm/mach-msm/clock-7x01a.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/* 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-7x30.h b/arch/arm/mach-msm/clock-7x30.h
new file mode 100644
index 000000000000..e16f72f32829
--- /dev/null
+++ b/arch/arm/mach-msm/clock-7x30.h
@@ -0,0 +1,168 @@
+/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_CLOCK_7X30_H
+#define __ARCH_ARM_MACH_MSM_CLOCK_7X30_H
+
+enum {
+	L_7X30_NONE_CLK = -1,
+	L_7X30_ADM_CLK,
+	L_7X30_I2C_CLK,
+	L_7X30_I2C_2_CLK,
+	L_7X30_QUP_I2C_CLK,
+	L_7X30_UART1DM_CLK,
+	L_7X30_UART1DM_P_CLK,
+	L_7X30_UART2DM_CLK,
+	L_7X30_UART2DM_P_CLK,
+	L_7X30_EMDH_CLK,
+	L_7X30_EMDH_P_CLK,
+	L_7X30_PMDH_CLK,
+	L_7X30_PMDH_P_CLK,
+	L_7X30_GRP_2D_CLK,
+	L_7X30_GRP_2D_P_CLK,
+	L_7X30_GRP_3D_SRC_CLK,
+	L_7X30_GRP_3D_CLK,
+	L_7X30_GRP_3D_P_CLK,
+	L_7X30_IMEM_CLK,
+	L_7X30_SDC1_CLK,
+	L_7X30_SDC1_P_CLK,
+	L_7X30_SDC2_CLK,
+	L_7X30_SDC2_P_CLK,
+	L_7X30_SDC3_CLK,
+	L_7X30_SDC3_P_CLK,
+	L_7X30_SDC4_CLK,
+	L_7X30_SDC4_P_CLK,
+	L_7X30_MDP_CLK,
+	L_7X30_MDP_P_CLK,
+	L_7X30_MDP_LCDC_PCLK_CLK,
+	L_7X30_MDP_LCDC_PAD_PCLK_CLK,
+	L_7X30_MDP_VSYNC_CLK,
+	L_7X30_MI2S_CODEC_RX_M_CLK,
+	L_7X30_MI2S_CODEC_RX_S_CLK,
+	L_7X30_MI2S_CODEC_TX_M_CLK,
+	L_7X30_MI2S_CODEC_TX_S_CLK,
+	L_7X30_MI2S_M_CLK,
+	L_7X30_MI2S_S_CLK,
+	L_7X30_LPA_CODEC_CLK,
+	L_7X30_LPA_CORE_CLK,
+	L_7X30_LPA_P_CLK,
+	L_7X30_MIDI_CLK,
+	L_7X30_MDC_CLK,
+	L_7X30_ROTATOR_IMEM_CLK,
+	L_7X30_ROTATOR_P_CLK,
+	L_7X30_SDAC_M_CLK,
+	L_7X30_SDAC_CLK,
+	L_7X30_UART1_CLK,
+	L_7X30_UART2_CLK,
+	L_7X30_UART3_CLK,
+	L_7X30_TV_CLK,
+	L_7X30_TV_DAC_CLK,
+	L_7X30_TV_ENC_CLK,
+	L_7X30_HDMI_CLK,
+	L_7X30_TSIF_REF_CLK,
+	L_7X30_TSIF_P_CLK,
+	L_7X30_USB_HS_SRC_CLK,
+	L_7X30_USB_HS_CLK,
+	L_7X30_USB_HS_CORE_CLK,
+	L_7X30_USB_HS_P_CLK,
+	L_7X30_USB_HS2_CLK,
+	L_7X30_USB_HS2_CORE_CLK,
+	L_7X30_USB_HS2_P_CLK,
+	L_7X30_USB_HS3_CLK,
+	L_7X30_USB_HS3_CORE_CLK,
+	L_7X30_USB_HS3_P_CLK,
+	L_7X30_VFE_CLK,
+	L_7X30_VFE_P_CLK,
+	L_7X30_VFE_MDC_CLK,
+	L_7X30_VFE_CAMIF_CLK,
+	L_7X30_CAMIF_PAD_P_CLK,
+	L_7X30_CAM_M_CLK,
+	L_7X30_JPEG_CLK,
+	L_7X30_JPEG_P_CLK,
+	L_7X30_VPE_CLK,
+	L_7X30_MFC_CLK,
+	L_7X30_MFC_DIV2_CLK,
+	L_7X30_MFC_P_CLK,
+	L_7X30_SPI_CLK,
+	L_7X30_SPI_P_CLK,
+	L_7X30_CSI0_CLK,
+	L_7X30_CSI0_VFE_CLK,
+	L_7X30_CSI0_P_CLK,
+	L_7X30_CSI1_CLK,
+	L_7X30_CSI1_VFE_CLK,
+	L_7X30_CSI1_P_CLK,
+	L_7X30_GLBL_ROOT_CLK,
+
+	L_7X30_AXI_LI_VG_CLK,
+	L_7X30_AXI_LI_GRP_CLK,
+	L_7X30_AXI_LI_JPEG_CLK,
+	L_7X30_AXI_GRP_2D_CLK,
+	L_7X30_AXI_MFC_CLK,
+	L_7X30_AXI_VPE_CLK,
+	L_7X30_AXI_LI_VFE_CLK,
+	L_7X30_AXI_LI_APPS_CLK,
+	L_7X30_AXI_MDP_CLK,
+	L_7X30_AXI_IMEM_CLK,
+	L_7X30_AXI_LI_ADSP_A_CLK,
+	L_7X30_AXI_ROTATOR_CLK,
+
+	L_7X30_NR_CLKS
+};
+
+struct clk_ops;
+extern struct clk_ops clk_ops_7x30;
+
+struct clk_ops *clk_7x30_is_local(uint32_t id);
+int clk_7x30_init(void);
+
+void pll_enable(uint32_t pll);
+void pll_disable(uint32_t pll);
+
+extern int internal_pwr_rail_ctl_auto(unsigned rail_id, bool enable);
+
+#define CLK_7X30(clk_name, clk_id, clk_dev, clk_flags) {	\
+	.name = clk_name, \
+	.id = L_7X30_##clk_id, \
+	.remote_id = P_##clk_id, \
+	.flags = clk_flags, \
+	.dev = clk_dev, \
+	.dbg_name = #clk_id, \
+	}
+
+#define CLK_7X30S(clk_name, l_id, r_id, clk_dev, clk_flags) {	\
+	.name = clk_name, \
+	.id = L_7X30_##l_id, \
+	.remote_id = P_##r_id, \
+	.flags = clk_flags, \
+	.dev = clk_dev, \
+	.dbg_name = #l_id, \
+	}
+
+#endif
+
diff --git a/arch/arm/mach-msm/clock-pcom.c b/arch/arm/mach-msm/clock-pcom.c
new file mode 100644
index 000000000000..a3b45627eb4a
--- /dev/null
+++ b/arch/arm/mach-msm/clock-pcom.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
+ *
+ * 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/err.h>
+#include <linux/ctype.h>
+#include <linux/stddef.h>
+#include <mach/clk.h>
+
+#include "proc_comm.h"
+#include "clock.h"
+
+/*
+ * glue for the proc_comm interface
+ */
+int pc_clk_enable(unsigned id)
+{
+	int rc = msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL);
+	if (rc < 0)
+		return rc;
+	else
+		return (int)id < 0 ? -EINVAL : 0;
+}
+
+void pc_clk_disable(unsigned id)
+{
+	msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
+}
+
+int pc_clk_reset(unsigned id, enum clk_reset_action action)
+{
+	int rc;
+
+	if (action == CLK_RESET_ASSERT)
+		rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_ASSERT, &id, NULL);
+	else
+		rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_DEASSERT, &id, NULL);
+
+	if (rc < 0)
+		return rc;
+	else
+		return (int)id < 0 ? -EINVAL : 0;
+}
+
+int pc_clk_set_rate(unsigned id, unsigned rate)
+{
+	/* The rate _might_ be rounded off to the nearest KHz value by the
+	 * remote function. So a return value of 0 doesn't necessarily mean
+	 * that the exact rate was set successfully.
+	 */
+	int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
+	if (rc < 0)
+		return rc;
+	else
+		return (int)id < 0 ? -EINVAL : 0;
+}
+
+int pc_clk_set_min_rate(unsigned id, unsigned rate)
+{
+	int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
+	if (rc < 0)
+		return rc;
+	else
+		return (int)id < 0 ? -EINVAL : 0;
+}
+
+int pc_clk_set_max_rate(unsigned id, unsigned rate)
+{
+	int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate);
+	if (rc < 0)
+		return rc;
+	else
+		return (int)id < 0 ? -EINVAL : 0;
+}
+
+int pc_clk_set_flags(unsigned id, unsigned flags)
+{
+	int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags);
+	if (rc < 0)
+		return rc;
+	else
+		return (int)id < 0 ? -EINVAL : 0;
+}
+
+unsigned pc_clk_get_rate(unsigned id)
+{
+	if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL))
+		return 0;
+	else
+		return id;
+}
+
+unsigned pc_clk_is_enabled(unsigned id)
+{
+	if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL))
+		return 0;
+	else
+		return id;
+}
+
+long pc_clk_round_rate(unsigned id, unsigned rate)
+{
+
+	/* Not really supported; pc_clk_set_rate() does rounding on it's own. */
+	return rate;
+}
+
+struct clk_ops clk_ops_pcom = {
+	.enable = pc_clk_enable,
+	.disable = pc_clk_disable,
+	.auto_off = pc_clk_disable,
+	.reset = pc_clk_reset,
+	.set_rate = pc_clk_set_rate,
+	.set_min_rate = pc_clk_set_min_rate,
+	.set_max_rate = pc_clk_set_max_rate,
+	.set_flags = pc_clk_set_flags,
+	.get_rate = pc_clk_get_rate,
+	.is_enabled = pc_clk_is_enabled,
+	.round_rate = pc_clk_round_rate,
+};
diff --git a/arch/arm/mach-msm/clock-pcom.h b/arch/arm/mach-msm/clock-pcom.h
new file mode 100644
index 000000000000..17d027b23501
--- /dev/null
+++ b/arch/arm/mach-msm/clock-pcom.h
@@ -0,0 +1,153 @@
+/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H
+#define __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H
+
+/* clock IDs used by the modem processor */
+
+#define P_ACPU_CLK	0   /* Applications processor clock */
+#define P_ADM_CLK	1   /* Applications data mover clock */
+#define P_ADSP_CLK	2   /* ADSP clock */
+#define P_EBI1_CLK	3   /* External bus interface 1 clock */
+#define P_EBI2_CLK	4   /* External bus interface 2 clock */
+#define P_ECODEC_CLK	5   /* External CODEC clock */
+#define P_EMDH_CLK	6   /* External MDDI host clock */
+#define P_GP_CLK	7   /* General purpose clock */
+#define P_GRP_3D_CLK	8   /* Graphics clock */
+#define P_I2C_CLK	9   /* I2C clock */
+#define P_ICODEC_RX_CLK	10  /* Internal CODEX RX clock */
+#define P_ICODEC_TX_CLK	11  /* Internal CODEX TX clock */
+#define P_IMEM_CLK	12  /* Internal graphics memory clock */
+#define P_MDC_CLK	13  /* MDDI client clock */
+#define P_MDP_CLK	14  /* Mobile display processor clock */
+#define P_PBUS_CLK	15  /* Peripheral bus clock */
+#define P_PCM_CLK	16  /* PCM clock */
+#define P_PMDH_CLK	17  /* Primary MDDI host clock */
+#define P_SDAC_CLK	18  /* Stereo DAC clock */
+#define P_SDC1_CLK	19  /* Secure Digital Card clocks */
+#define P_SDC1_P_CLK	20
+#define P_SDC2_CLK	21
+#define P_SDC2_P_CLK	22
+#define P_SDC3_CLK	23
+#define P_SDC3_P_CLK	24
+#define P_SDC4_CLK	25
+#define P_SDC4_P_CLK	26
+#define P_TSIF_CLK	27  /* Transport Stream Interface clocks */
+#define P_TSIF_REF_CLK	28
+#define P_TV_DAC_CLK	29  /* TV clocks */
+#define P_TV_ENC_CLK	30
+#define P_UART1_CLK	31  /* UART clocks */
+#define P_UART2_CLK	32
+#define P_UART3_CLK	33
+#define P_UART1DM_CLK	34
+#define P_UART2DM_CLK	35
+#define P_USB_HS_CLK	36  /* High speed USB core clock */
+#define P_USB_HS_P_CLK	37  /* High speed USB pbus clock */
+#define P_USB_OTG_CLK	38  /* Full speed USB clock */
+#define P_VDC_CLK	39  /* Video controller clock */
+#define P_VFE_MDC_CLK	40  /* Camera / Video Front End clock */
+#define P_VFE_CLK	41  /* VFE MDDI client clock */
+#define P_MDP_LCDC_PCLK_CLK	42
+#define P_MDP_LCDC_PAD_PCLK_CLK 43
+#define P_MDP_VSYNC_CLK	44
+#define P_SPI_CLK	45
+#define P_VFE_AXI_CLK	46
+#define P_USB_HS2_CLK	47  /* High speed USB 2 core clock */
+#define P_USB_HS2_P_CLK	48  /* High speed USB 2 pbus clock */
+#define P_USB_HS3_CLK	49  /* High speed USB 3 core clock */
+#define P_USB_HS3_P_CLK	50  /* High speed USB 3 pbus clock */
+#define P_GRP_3D_P_CLK	51  /* Graphics pbus clock */
+#define P_USB_PHY_CLK	52  /* USB PHY clock */
+#define P_USB_HS_CORE_CLK	53  /* High speed USB 1 core clock */
+#define P_USB_HS2_CORE_CLK	54  /* High speed USB 2 core clock */
+#define P_USB_HS3_CORE_CLK	55  /* High speed USB 3 core clock */
+#define P_CAM_M_CLK		56
+#define P_CAMIF_PAD_P_CLK	57
+#define P_GRP_2D_CLK		58
+#define P_GRP_2D_P_CLK		59
+#define P_I2S_CLK		60
+#define P_JPEG_CLK		61
+#define P_JPEG_P_CLK		62
+#define P_LPA_CODEC_CLK		63
+#define P_LPA_CORE_CLK		64
+#define P_LPA_P_CLK		65
+#define P_MDC_IO_CLK		66
+#define P_MDC_P_CLK		67
+#define P_MFC_CLK		68
+#define P_MFC_DIV2_CLK		69
+#define P_MFC_P_CLK		70
+#define P_QUP_I2C_CLK		71
+#define P_ROTATOR_IMEM_CLK	72
+#define P_ROTATOR_P_CLK		73
+#define P_VFE_CAMIF_CLK		74
+#define P_VFE_P_CLK		75
+#define P_VPE_CLK		76
+#define P_I2C_2_CLK		77
+#define P_MI2S_CODEC_RX_S_CLK	78
+#define P_MI2S_CODEC_RX_M_CLK	79
+#define P_MI2S_CODEC_TX_S_CLK	80
+#define P_MI2S_CODEC_TX_M_CLK	81
+#define P_PMDH_P_CLK		82
+#define P_EMDH_P_CLK		83
+#define P_SPI_P_CLK		84
+#define P_TSIF_P_CLK		85
+#define P_MDP_P_CLK		86
+#define P_SDAC_M_CLK		87
+#define P_MI2S_S_CLK		88
+#define P_MI2S_M_CLK		89
+#define P_AXI_ROTATOR_CLK	90
+#define P_HDMI_CLK		91
+#define P_CSI0_CLK		92
+#define P_CSI0_VFE_CLK		93
+#define P_CSI0_P_CLK		94
+#define P_CSI1_CLK		95
+#define P_CSI1_VFE_CLK		96
+#define P_CSI1_P_CLK		97
+#define P_GSBI_CLK		98
+#define P_GSBI_P_CLK		99
+
+#define P_NR_CLKS		100
+
+struct clk_ops;
+extern struct clk_ops clk_ops_pcom;
+
+int pc_clk_reset(unsigned id, enum clk_reset_action action);
+
+#define CLK_PCOM(clk_name, clk_id, clk_dev, clk_flags) {	\
+	.name = clk_name, \
+	.id = P_##clk_id, \
+	.remote_id = P_##clk_id, \
+	.ops = &clk_ops_pcom, \
+	.flags = clk_flags, \
+	.dev = clk_dev, \
+	.dbg_name = #clk_id, \
+	}
+
+#endif
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index 3b1ce36f1032..9cb1276ab749 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/clock.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007 QUALCOMM Incorporated
+ * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -22,68 +22,27 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/spinlock.h>
+#include <linux/debugfs.h>
+#include <linux/ctype.h>
+#include <linux/pm_qos_params.h>
+#include <mach/clk.h>
 
 #include "clock.h"
 #include "proc_comm.h"
+#include "clock-7x30.h"
 
 static DEFINE_MUTEX(clocks_mutex);
 static DEFINE_SPINLOCK(clocks_lock);
 static LIST_HEAD(clocks);
+struct clk *msm_clocks;
+unsigned msm_num_clocks;
 
 /*
- * glue for the proc_comm interface
+ * Bitmap of enabled clocks, excluding ACPU which is always
+ * enabled
  */
-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);
-}
+static DECLARE_BITMAP(clock_map_enabled, NR_CLKS);
+static DEFINE_SPINLOCK(clock_map_lock);
 
 /*
  * Standard clock functions defined in include/linux/clk.h
@@ -119,8 +78,12 @@ 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);
+	if (clk->count == 1) {
+		clk->ops->enable(clk->id);
+		spin_lock(&clock_map_lock);
+		clock_map_enabled[BIT_WORD(clk->id)] |= BIT_MASK(clk->id);
+		spin_unlock(&clock_map_lock);
+	}
 	spin_unlock_irqrestore(&clocks_lock, flags);
 	return 0;
 }
@@ -132,31 +95,54 @@ void clk_disable(struct clk *clk)
 	spin_lock_irqsave(&clocks_lock, flags);
 	BUG_ON(clk->count == 0);
 	clk->count--;
-	if (clk->count == 0)
-		pc_clk_disable(clk->id);
+	if (clk->count == 0) {
+		clk->ops->disable(clk->id);
+		spin_lock(&clock_map_lock);
+		clock_map_enabled[BIT_WORD(clk->id)] &= ~BIT_MASK(clk->id);
+		spin_unlock(&clock_map_lock);
+	}
 	spin_unlock_irqrestore(&clocks_lock, flags);
 }
 EXPORT_SYMBOL(clk_disable);
 
+int clk_reset(struct clk *clk, enum clk_reset_action action)
+{
+	if (!clk->ops->reset)
+		clk->ops->reset = &pc_clk_reset;
+	return clk->ops->reset(clk->remote_id, action);
+}
+EXPORT_SYMBOL(clk_reset);
+
 unsigned long clk_get_rate(struct clk *clk)
 {
-	return pc_clk_get_rate(clk->id);
+	return clk->ops->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);
+	return clk->ops->set_rate(clk->id, rate);
 }
 EXPORT_SYMBOL(clk_set_rate);
 
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	return clk->ops->round_rate(clk->id, rate);
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_min_rate(struct clk *clk, unsigned long rate)
+{
+	return clk->ops->set_min_rate(clk->id, rate);
+}
+EXPORT_SYMBOL(clk_set_min_rate);
+
+int clk_set_max_rate(struct clk *clk, unsigned long rate)
+{
+	return clk->ops->set_max_rate(clk->id, rate);
+}
+EXPORT_SYMBOL(clk_set_max_rate);
+
 int clk_set_parent(struct clk *clk, struct clk *parent)
 {
 	return -ENOSYS;
@@ -173,22 +159,153 @@ 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);
+	return clk->ops->set_flags(clk->id, flags);
 }
 EXPORT_SYMBOL(clk_set_flags);
 
+/* EBI1 is the only shared clock that several clients want to vote on as of
+ * this commit. If this changes in the future, then it might be better to
+ * make clk_min_rate handle the voting or make ebi1_clk_set_min_rate more
+ * generic to support different clocks.
+ */
+static struct clk *ebi1_clk;
 
-void __init msm_clock_init(void)
+static void __init set_clock_ops(struct clk *clk)
+{
+	if (!clk->ops) {
+		clk->ops = &clk_ops_pcom;
+		clk->id = clk->remote_id;
+	}
+}
+
+void __init msm_clock_init(struct clk *clock_tbl, unsigned num_clocks)
 {
 	unsigned n;
 
 	spin_lock_init(&clocks_lock);
 	mutex_lock(&clocks_mutex);
-	for (n = 0; n < msm_num_clocks; n++)
+	msm_clocks = clock_tbl;
+	msm_num_clocks = num_clocks;
+	for (n = 0; n < msm_num_clocks; n++) {
+		set_clock_ops(&msm_clocks[n]);
 		list_add_tail(&msm_clocks[n].list, &clocks);
+	}
 	mutex_unlock(&clocks_mutex);
+
+	ebi1_clk = clk_get(NULL, "ebi1_clk");
+	BUG_ON(ebi1_clk == NULL);
+
+}
+
+#if defined(CONFIG_DEBUG_FS)
+static struct clk *msm_clock_get_nth(unsigned index)
+{
+	if (index < msm_num_clocks)
+		return msm_clocks + index;
+	else
+		return 0;
+}
+
+static int clock_debug_rate_set(void *data, u64 val)
+{
+	struct clk *clock = data;
+	int ret;
+
+	/* Only increases to max rate will succeed, but that's actually good
+	 * for debugging purposes. So we don't check for error. */
+	if (clock->flags & CLK_MAX)
+		clk_set_max_rate(clock, val);
+	if (clock->flags & CLK_MIN)
+		ret = clk_set_min_rate(clock, val);
+	else
+		ret = clk_set_rate(clock, val);
+	if (ret != 0)
+		printk(KERN_ERR "clk_set%s_rate failed (%d)\n",
+			(clock->flags & CLK_MIN) ? "_min" : "", ret);
+	return ret;
+}
+
+static int clock_debug_rate_get(void *data, u64 *val)
+{
+	struct clk *clock = data;
+	*val = clk_get_rate(clock);
+	return 0;
+}
+
+static int clock_debug_enable_set(void *data, u64 val)
+{
+	struct clk *clock = data;
+	int rc = 0;
+
+	if (val)
+		rc = clock->ops->enable(clock->id);
+	else
+		clock->ops->disable(clock->id);
+
+	return rc;
 }
 
+static int clock_debug_enable_get(void *data, u64 *val)
+{
+	struct clk *clock = data;
+
+	*val = clock->ops->is_enabled(clock->id);
+
+	return 0;
+}
+
+static int clock_debug_local_get(void *data, u64 *val)
+{
+	struct clk *clock = data;
+
+	*val = clock->ops != &clk_ops_pcom;
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_debug_rate_get,
+			clock_debug_rate_set, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(clock_enable_fops, clock_debug_enable_get,
+			clock_debug_enable_set, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(clock_local_fops, clock_debug_local_get,
+			NULL, "%llu\n");
+
+static int __init clock_debug_init(void)
+{
+	struct dentry *dent_rate, *dent_enable, *dent_local;
+	struct clk *clock;
+	unsigned n = 0;
+	char temp[50], *ptr;
+
+	dent_rate = debugfs_create_dir("clk_rate", 0);
+	if (IS_ERR(dent_rate))
+		return PTR_ERR(dent_rate);
+
+	dent_enable = debugfs_create_dir("clk_enable", 0);
+	if (IS_ERR(dent_enable))
+		return PTR_ERR(dent_enable);
+
+	dent_local = debugfs_create_dir("clk_local", NULL);
+	if (IS_ERR(dent_local))
+		return PTR_ERR(dent_local);
+
+	while ((clock = msm_clock_get_nth(n++)) != 0) {
+		strncpy(temp, clock->dbg_name, ARRAY_SIZE(temp)-1);
+		for (ptr = temp; *ptr; ptr++)
+			*ptr = tolower(*ptr);
+		debugfs_create_file(temp, 0644, dent_rate,
+				    clock, &clock_rate_fops);
+		debugfs_create_file(temp, 0644, dent_enable,
+				    clock, &clock_enable_fops);
+		debugfs_create_file(temp, S_IRUGO, dent_local,
+				    clock, &clock_local_fops);
+	}
+	return 0;
+}
+
+device_initcall(clock_debug_init);
+#endif
+
 /* 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.
@@ -205,7 +322,7 @@ static int __init clock_late_init(void)
 			spin_lock_irqsave(&clocks_lock, flags);
 			if (!clk->count) {
 				count++;
-				pc_clk_disable(clk->id);
+				clk->ops->auto_off(clk->id);
 			}
 			spin_unlock_irqrestore(&clocks_lock, flags);
 		}
@@ -216,3 +333,4 @@ static int __init clock_late_init(void)
 }
 
 late_initcall(clock_late_init);
+
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index f875e1544e5f..c270b552ed13 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/clock.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007 QUALCOMM Incorporated
+ * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -18,6 +18,10 @@
 #define __ARCH_ARM_MACH_MSM_CLOCK_H
 
 #include <linux/list.h>
+#include <mach/clk.h>
+
+#include "clock-pcom.h"
+#include "clock-7x30.h"
 
 #define CLKFLAG_INVERT			0x00000001
 #define CLKFLAG_NOINVERT		0x00000002
@@ -25,14 +29,32 @@
 #define CLKFLAG_NORESET			0x00000008
 
 #define CLK_FIRST_AVAILABLE_FLAG	0x00000100
-#define CLKFLAG_USE_MIN_MAX_TO_SET	0x00000200
-#define CLKFLAG_AUTO_OFF		0x00000400
+#define CLKFLAG_AUTO_OFF		0x00000200
+#define CLKFLAG_MIN			0x00000400
+#define CLKFLAG_MAX			0x00000800
+
+struct clk_ops {
+	int (*enable)(unsigned id);
+	void (*disable)(unsigned id);
+	void (*auto_off)(unsigned id);
+	int (*reset)(unsigned id, enum clk_reset_action action);
+	int (*set_rate)(unsigned id, unsigned rate);
+	int (*set_min_rate)(unsigned id, unsigned rate);
+	int (*set_max_rate)(unsigned id, unsigned rate);
+	int (*set_flags)(unsigned id, unsigned flags);
+	unsigned (*get_rate)(unsigned id);
+	unsigned (*is_enabled)(unsigned id);
+	long (*round_rate)(unsigned id, unsigned rate);
+};
 
 struct clk {
 	uint32_t id;
+	uint32_t remote_id;
 	uint32_t count;
 	uint32_t flags;
 	const char *name;
+	struct clk_ops *ops;
+	const char *dbg_name;
 	struct list_head list;
 	struct device *dev;
 };
@@ -41,8 +63,47 @@ struct clk {
 #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;
+#ifdef CONFIG_DEBUG_FS
+#define CLOCK_DBG_NAME(x) .dbg_name = x,
+#else
+#define CLOCK_DBG_NAME(x)
+#endif
+
+#define CLOCK(clk_name, clk_id, clk_dev, clk_flags) {	\
+	.name = clk_name, \
+	.id = clk_id, \
+	.flags = clk_flags, \
+	.dev = clk_dev, \
+	 CLOCK_DBG_NAME(#clk_id) \
+	}
+
+#define OFF CLKFLAG_AUTO_OFF
+#define CLK_MIN CLKFLAG_MIN
+#define CLK_MAX CLKFLAG_MAX
+#define CLK_MINMAX (CLK_MIN | CLK_MAX)
+#define NR_CLKS	P_NR_CLKS
+
+enum {
+	PLL_0 = 0,
+	PLL_1,
+	PLL_2,
+	PLL_3,
+	PLL_4,
+	PLL_5,
+	PLL_6,
+	NUM_PLL
+};
+
+enum clkvote_client {
+	CLKVOTE_ACPUCLK = 0,
+	CLKVOTE_PMQOS,
+	CLKVOTE_MAX,
+};
+
+int msm_clock_require_tcxo(unsigned long *reason, int nbits);
+int msm_clock_get_name(uint32_t id, char *name, uint32_t size);
+int ebi1_clk_set_min_rate(enum clkvote_client client, unsigned long rate);
+unsigned long clk_get_max_axi_khz(void);
 
 #endif
 
diff --git a/arch/arm/mach-msm/devices.c b/arch/arm/mach-msm/devices-msm7x00.c
index 31b6b30e98bf..fde9d8f69f10 100644
--- a/arch/arm/mach-msm/devices.c
+++ b/arch/arm/mach-msm/devices-msm7x00.c
@@ -24,6 +24,10 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 
+
+#include "clock.h"
+#include <mach/mmc.h>
+
 static struct resource resources_uart1[] = {
 	{
 		.start	= INT_UART1,
@@ -163,8 +167,19 @@ static struct resource resources_sdc1[] = {
 	},
 	{
 		.start	= INT_SDC1_0,
+		.end	= INT_SDC1_0,
+		.flags	= IORESOURCE_IRQ,
+		.name	= "cmd_irq",
+	},
+	{
+		.start	= INT_SDC1_1,
 		.end	= INT_SDC1_1,
 		.flags	= IORESOURCE_IRQ,
+		.name	= "pio_irq",
+	},
+	{
+		.flags	= IORESOURCE_IRQ | IORESOURCE_DISABLED,
+		.name	= "status_irq"
 	},
 	{
 		.start	= 8,
@@ -181,8 +196,19 @@ static struct resource resources_sdc2[] = {
 	},
 	{
 		.start	= INT_SDC2_0,
+		.end	= INT_SDC2_0,
+		.flags	= IORESOURCE_IRQ,
+		.name	= "cmd_irq",
+	},
+		{
+		.start	= INT_SDC2_1,
 		.end	= INT_SDC2_1,
 		.flags	= IORESOURCE_IRQ,
+		.name	= "pio_irq",
+	},
+	{
+		.flags	= IORESOURCE_IRQ | IORESOURCE_DISABLED,
+		.name	= "status_irq"
 	},
 	{
 		.start	= 8,
@@ -199,8 +225,19 @@ static struct resource resources_sdc3[] = {
 	},
 	{
 		.start	= INT_SDC3_0,
+		.end	= INT_SDC3_0,
+		.flags	= IORESOURCE_IRQ,
+		.name	= "cmd_irq",
+	},
+		{
+		.start	= INT_SDC3_1,
 		.end	= INT_SDC3_1,
 		.flags	= IORESOURCE_IRQ,
+		.name	= "pio_irq",
+	},
+	{
+		.flags	= IORESOURCE_IRQ | IORESOURCE_DISABLED,
+		.name	= "status_irq"
 	},
 	{
 		.start	= 8,
@@ -217,8 +254,19 @@ static struct resource resources_sdc4[] = {
 	},
 	{
 		.start	= INT_SDC4_0,
+		.end	= INT_SDC4_0,
+		.flags	= IORESOURCE_IRQ,
+		.name	= "cmd_irq",
+	},
+		{
+		.start	= INT_SDC4_1,
 		.end	= INT_SDC4_1,
 		.flags	= IORESOURCE_IRQ,
+		.name	= "pio_irq",
+	},
+	{
+		.flags	= IORESOURCE_IRQ | IORESOURCE_DISABLED,
+		.name	= "status_irq"
 	},
 	{
 		.start	= 8,
@@ -266,3 +314,80 @@ struct platform_device msm_device_sdc4 = {
 		.coherent_dma_mask	= 0xffffffff,
 	},
 };
+
+static struct platform_device *msm_sdcc_devices[] __initdata = {
+	&msm_device_sdc1,
+	&msm_device_sdc2,
+	&msm_device_sdc3,
+	&msm_device_sdc4,
+};
+
+int __init msm_add_sdcc(unsigned int controller, struct mmc_platform_data *plat,
+			unsigned int stat_irq, unsigned long stat_irq_flags)
+{
+	struct platform_device	*pdev;
+	struct resource *res;
+
+	if (controller < 1 || controller > 4)
+		return -EINVAL;
+
+	pdev = msm_sdcc_devices[controller-1];
+	pdev->dev.platform_data = plat;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "status_irq");
+	if (!res)
+		return -EINVAL;
+	else if (stat_irq) {
+		res->start = res->end = stat_irq;
+		res->flags &= ~IORESOURCE_DISABLED;
+		res->flags |= stat_irq_flags;
+	}
+
+	return platform_device_register(pdev);
+}
+
+struct clk msm_clocks_7x01a[] = {
+	CLK_PCOM("adm_clk",	ADM_CLK,	NULL, 0),
+	CLK_PCOM("adsp_clk",	ADSP_CLK,	NULL, 0),
+	CLK_PCOM("ebi1_clk",	EBI1_CLK,	NULL, 0),
+	CLK_PCOM("ebi2_clk",	EBI2_CLK,	NULL, 0),
+	CLK_PCOM("ecodec_clk",	ECODEC_CLK,	NULL, 0),
+	CLK_PCOM("emdh_clk",	EMDH_CLK,	NULL, OFF),
+	CLK_PCOM("gp_clk",		GP_CLK,		NULL, 0),
+	CLK_PCOM("grp_clk",	GRP_3D_CLK,	NULL, OFF),
+	CLK_PCOM("i2c_clk",	I2C_CLK,	&msm_device_i2c.dev, 0),
+	CLK_PCOM("icodec_rx_clk",	ICODEC_RX_CLK,	NULL, 0),
+	CLK_PCOM("icodec_tx_clk",	ICODEC_TX_CLK,	NULL, 0),
+	CLK_PCOM("imem_clk",	IMEM_CLK,	NULL, OFF),
+	CLK_PCOM("mdc_clk",	MDC_CLK,	NULL, 0),
+	CLK_PCOM("mdp_clk",	MDP_CLK,	NULL, OFF),
+	CLK_PCOM("pbus_clk",	PBUS_CLK,	NULL, 0),
+	CLK_PCOM("pcm_clk",	PCM_CLK,	NULL, 0),
+	CLK_PCOM("pmdh_clk",	PMDH_CLK,	NULL, OFF ),
+	CLK_PCOM("sdac_clk",	SDAC_CLK,	NULL, OFF),
+	CLK_PCOM("sdc_clk",	SDC1_CLK,	&msm_device_sdc1.dev, OFF),
+	CLK_PCOM("sdc_pclk",	SDC1_P_CLK,	&msm_device_sdc1.dev, OFF),
+	CLK_PCOM("sdc_clk",	SDC2_CLK,	&msm_device_sdc2.dev, OFF),
+	CLK_PCOM("sdc_pclk",	SDC2_P_CLK,	&msm_device_sdc2.dev, OFF),
+	CLK_PCOM("sdc_clk",	SDC3_CLK,	&msm_device_sdc3.dev, OFF),
+	CLK_PCOM("sdc_pclk",	SDC3_P_CLK,	&msm_device_sdc3.dev, OFF),
+	CLK_PCOM("sdc_clk",	SDC4_CLK,	&msm_device_sdc4.dev, OFF),
+	CLK_PCOM("sdc_pclk",	SDC4_P_CLK,	&msm_device_sdc4.dev, OFF),
+	CLK_PCOM("tsif_clk",	TSIF_CLK,	NULL, 0),
+	CLK_PCOM("tsif_ref_clk",	TSIF_REF_CLK,	NULL, 0),
+	CLK_PCOM("tv_dac_clk",	TV_DAC_CLK,	NULL, 0),
+	CLK_PCOM("tv_enc_clk",	TV_ENC_CLK,	NULL, 0),
+	CLK_PCOM("uart_clk",	UART1_CLK,	&msm_device_uart1.dev, OFF),
+	CLK_PCOM("uart_clk",	UART2_CLK,	&msm_device_uart2.dev, 0),
+	CLK_PCOM("uart_clk",	UART3_CLK,	&msm_device_uart3.dev, OFF),
+	CLK_PCOM("uart1dm_clk",	UART1DM_CLK,	NULL, OFF),
+	CLK_PCOM("uart2dm_clk",	UART2DM_CLK,	NULL, 0),
+	CLK_PCOM("usb_hs_clk",	USB_HS_CLK,	&msm_device_hsusb.dev, OFF),
+	CLK_PCOM("usb_hs_pclk",	USB_HS_P_CLK,	&msm_device_hsusb.dev, OFF),
+	CLK_PCOM("usb_otg_clk",	USB_OTG_CLK,	NULL, 0),
+	CLK_PCOM("vdc_clk",	VDC_CLK,	NULL, OFF ),
+	CLK_PCOM("vfe_clk",	VFE_CLK,	NULL, OFF),
+	CLK_PCOM("vfe_mdc_clk",	VFE_MDC_CLK,	NULL, OFF),
+};
+
+unsigned msm_num_clocks_7x01a = ARRAY_SIZE(msm_clocks_7x01a);
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
new file mode 100644
index 000000000000..b449e8ad2904
--- /dev/null
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ *
+ * 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 <linux/dma-mapping.h>
+#include <mach/irqs.h>
+#include <mach/msm_iomap.h>
+#include <mach/dma.h>
+#include <mach/board.h>
+
+#include "devices.h"
+#include "smd_private.h"
+
+#include <asm/mach/flash.h>
+
+#include "clock-pcom.h"
+
+#include <mach/mmc.h>
+
+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,
+	},
+};
+
+struct platform_device msm_device_uart2 = {
+	.name	= "msm_serial",
+	.id	= 1,
+	.num_resources	= ARRAY_SIZE(resources_uart2),
+	.resource	= resources_uart2,
+};
+
+struct clk msm_clocks_7x30[] = {
+	CLK_PCOM("adm_clk",	ADM_CLK,	NULL, 0),
+	CLK_PCOM("adsp_clk",	ADSP_CLK,	NULL, 0),
+	CLK_PCOM("cam_m_clk",	CAM_M_CLK,	NULL, 0),
+	CLK_PCOM("camif_pad_pclk",	CAMIF_PAD_P_CLK,	NULL, OFF),
+	CLK_PCOM("ebi1_clk",	EBI1_CLK,	NULL, CLK_MIN),
+	CLK_PCOM("ecodec_clk",	ECODEC_CLK,	NULL, 0),
+	CLK_PCOM("emdh_clk",	EMDH_CLK,	NULL, OFF | CLK_MINMAX),
+	CLK_PCOM("emdh_pclk",	EMDH_P_CLK,	NULL, OFF),
+	CLK_PCOM("gp_clk",	GP_CLK,		NULL, 0),
+	CLK_PCOM("grp_2d_clk",	GRP_2D_CLK,	NULL, 0),
+	CLK_PCOM("grp_2d_pclk",	GRP_2D_P_CLK,	NULL, 0),
+	CLK_PCOM("grp_clk",	GRP_3D_CLK,	NULL, 0),
+	CLK_PCOM("grp_pclk",	GRP_3D_P_CLK,	NULL, 0),
+	CLK_7X30S("grp_src_clk", GRP_3D_SRC_CLK, GRP_3D_CLK,	NULL, 0),
+	CLK_PCOM("hdmi_clk",	HDMI_CLK,	NULL, 0),
+	CLK_PCOM("imem_clk",	IMEM_CLK,	NULL, OFF),
+	CLK_PCOM("jpeg_clk",	JPEG_CLK,	NULL, OFF),
+	CLK_PCOM("jpeg_pclk",	JPEG_P_CLK,	NULL, OFF),
+	CLK_PCOM("lpa_codec_clk",	LPA_CODEC_CLK,		NULL, 0),
+	CLK_PCOM("lpa_core_clk",	LPA_CORE_CLK,		NULL, 0),
+	CLK_PCOM("lpa_pclk",		LPA_P_CLK,		NULL, 0),
+	CLK_PCOM("mdc_clk",	MDC_CLK,	NULL, 0),
+	CLK_PCOM("mddi_clk",	PMDH_CLK,	NULL, OFF | CLK_MINMAX),
+	CLK_PCOM("mddi_pclk",	PMDH_P_CLK,	NULL, 0),
+	CLK_PCOM("mdp_clk",	MDP_CLK,	NULL, OFF),
+	CLK_PCOM("mdp_pclk",	MDP_P_CLK,	NULL, 0),
+	CLK_PCOM("mdp_lcdc_pclk_clk", MDP_LCDC_PCLK_CLK, NULL, 0),
+	CLK_PCOM("mdp_lcdc_pad_pclk_clk", MDP_LCDC_PAD_PCLK_CLK, NULL, 0),
+	CLK_PCOM("mdp_vsync_clk",	MDP_VSYNC_CLK,  NULL, 0),
+	CLK_PCOM("mfc_clk",		MFC_CLK,		NULL, 0),
+	CLK_PCOM("mfc_div2_clk",	MFC_DIV2_CLK,		NULL, 0),
+	CLK_PCOM("mfc_pclk",		MFC_P_CLK,		NULL, 0),
+	CLK_PCOM("mi2s_m_clk",		MI2S_M_CLK,  		NULL, 0),
+	CLK_PCOM("mi2s_s_clk",		MI2S_S_CLK,  		NULL, 0),
+	CLK_PCOM("mi2s_codec_rx_m_clk",	MI2S_CODEC_RX_M_CLK,  NULL, 0),
+	CLK_PCOM("mi2s_codec_rx_s_clk",	MI2S_CODEC_RX_S_CLK,  NULL, 0),
+	CLK_PCOM("mi2s_codec_tx_m_clk",	MI2S_CODEC_TX_M_CLK,  NULL, 0),
+	CLK_PCOM("mi2s_codec_tx_s_clk",	MI2S_CODEC_TX_S_CLK,  NULL, 0),
+	CLK_PCOM("pbus_clk",	PBUS_CLK,	NULL, CLK_MIN),
+	CLK_PCOM("pcm_clk",	PCM_CLK,	NULL, 0),
+	CLK_PCOM("rotator_clk",	AXI_ROTATOR_CLK,		NULL, 0),
+	CLK_PCOM("rotator_imem_clk",	ROTATOR_IMEM_CLK,	NULL, OFF),
+	CLK_PCOM("rotator_pclk",	ROTATOR_P_CLK,		NULL, OFF),
+	CLK_PCOM("sdac_clk",	SDAC_CLK,	NULL, OFF),
+	CLK_PCOM("spi_clk",	SPI_CLK,	NULL, 0),
+	CLK_PCOM("spi_pclk",	SPI_P_CLK,	NULL, 0),
+	CLK_7X30S("tv_src_clk",	TV_CLK, 	TV_ENC_CLK,	NULL, 0),
+	CLK_PCOM("tv_dac_clk",	TV_DAC_CLK,	NULL, 0),
+	CLK_PCOM("tv_enc_clk",	TV_ENC_CLK,	NULL, 0),
+	CLK_PCOM("uart_clk",	UART2_CLK,	&msm_device_uart2.dev, 0),
+	CLK_PCOM("usb_hs_clk",		USB_HS_CLK,		NULL, OFF),
+	CLK_PCOM("usb_hs_pclk",		USB_HS_P_CLK,		NULL, OFF),
+	CLK_PCOM("usb_hs_core_clk",	USB_HS_CORE_CLK,	NULL, OFF),
+	CLK_PCOM("usb_hs2_clk",		USB_HS2_CLK,		NULL, OFF),
+	CLK_PCOM("usb_hs2_pclk",	USB_HS2_P_CLK,		NULL, OFF),
+	CLK_PCOM("usb_hs2_core_clk",	USB_HS2_CORE_CLK,	NULL, OFF),
+	CLK_PCOM("usb_hs3_clk",		USB_HS3_CLK,		NULL, OFF),
+	CLK_PCOM("usb_hs3_pclk",	USB_HS3_P_CLK,		NULL, OFF),
+	CLK_PCOM("usb_hs3_core_clk",	USB_HS3_CORE_CLK,	NULL, OFF),
+	CLK_PCOM("vdc_clk",	VDC_CLK,	NULL, OFF | CLK_MIN),
+	CLK_PCOM("vfe_camif_clk",	VFE_CAMIF_CLK, 	NULL, 0),
+	CLK_PCOM("vfe_clk",	VFE_CLK,	NULL, 0),
+	CLK_PCOM("vfe_mdc_clk",	VFE_MDC_CLK,	NULL, 0),
+	CLK_PCOM("vfe_pclk",	VFE_P_CLK,	NULL, OFF),
+	CLK_PCOM("vpe_clk",	VPE_CLK,	NULL, 0),
+
+	/* 7x30 v2 hardware only. */
+	CLK_PCOM("csi_clk",	CSI0_CLK,	NULL, 0),
+	CLK_PCOM("csi_pclk",	CSI0_P_CLK,	NULL, 0),
+	CLK_PCOM("csi_vfe_clk",	CSI0_VFE_CLK,	NULL, 0),
+};
+
+unsigned msm_num_clocks_7x30 = ARRAY_SIZE(msm_clocks_7x30);
+
diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c
new file mode 100644
index 000000000000..4d4a50785e34
--- /dev/null
+++ b/arch/arm/mach-msm/devices-qsd8x50.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ *
+ * 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 <linux/dma-mapping.h>
+#include <mach/irqs.h>
+#include <mach/msm_iomap.h>
+#include <mach/dma.h>
+#include <mach/board.h>
+
+#include "devices.h"
+
+#include <asm/mach/flash.h>
+
+#include <mach/mmc.h>
+
+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_uart3 = {
+	.name	= "msm_serial",
+	.id	= 2,
+	.num_resources	= ARRAY_SIZE(resources_uart3),
+	.resource	= resources_uart3,
+};
+
+struct clk msm_clocks_8x50[] = {
+	CLK_PCOM("adm_clk",	ADM_CLK,	NULL, 0),
+	CLK_PCOM("ebi1_clk",	EBI1_CLK,	NULL, CLK_MIN),
+	CLK_PCOM("ebi2_clk",	EBI2_CLK,	NULL, 0),
+	CLK_PCOM("ecodec_clk",	ECODEC_CLK,	NULL, 0),
+	CLK_PCOM("emdh_clk",	EMDH_CLK,	NULL, OFF | CLK_MINMAX),
+	CLK_PCOM("gp_clk",	GP_CLK,		NULL, 0),
+	CLK_PCOM("grp_clk",	GRP_3D_CLK,	NULL, 0),
+	CLK_PCOM("icodec_rx_clk",	ICODEC_RX_CLK,	NULL, 0),
+	CLK_PCOM("icodec_tx_clk",	ICODEC_TX_CLK,	NULL, 0),
+	CLK_PCOM("imem_clk",	IMEM_CLK,	NULL, OFF),
+	CLK_PCOM("mdc_clk",	MDC_CLK,	NULL, 0),
+	CLK_PCOM("mddi_clk",	PMDH_CLK,	NULL, OFF | CLK_MINMAX),
+	CLK_PCOM("mdp_clk",	MDP_CLK,	NULL, OFF),
+	CLK_PCOM("mdp_lcdc_pclk_clk", MDP_LCDC_PCLK_CLK, NULL, 0),
+	CLK_PCOM("mdp_lcdc_pad_pclk_clk", MDP_LCDC_PAD_PCLK_CLK, NULL, 0),
+	CLK_PCOM("mdp_vsync_clk",	MDP_VSYNC_CLK,	NULL, 0),
+	CLK_PCOM("pbus_clk",	PBUS_CLK,	NULL, CLK_MIN),
+	CLK_PCOM("pcm_clk",	PCM_CLK,	NULL, 0),
+	CLK_PCOM("sdac_clk",	SDAC_CLK,	NULL, OFF),
+	CLK_PCOM("spi_clk",	SPI_CLK,	NULL, 0),
+	CLK_PCOM("tsif_clk",	TSIF_CLK,	NULL, 0),
+	CLK_PCOM("tsif_ref_clk",	TSIF_REF_CLK,	NULL, 0),
+	CLK_PCOM("tv_dac_clk",	TV_DAC_CLK,	NULL, 0),
+	CLK_PCOM("tv_enc_clk",	TV_ENC_CLK,	NULL, 0),
+	CLK_PCOM("uart_clk",	UART3_CLK,	&msm_device_uart3.dev, OFF),
+	CLK_PCOM("usb_hs_clk",	USB_HS_CLK,	NULL, OFF),
+	CLK_PCOM("usb_hs_pclk",	USB_HS_P_CLK,	NULL, OFF),
+	CLK_PCOM("usb_otg_clk",	USB_OTG_CLK,	NULL, 0),
+	CLK_PCOM("vdc_clk",	VDC_CLK,	NULL, OFF | CLK_MIN),
+	CLK_PCOM("vfe_clk",	VFE_CLK,	NULL, OFF),
+	CLK_PCOM("vfe_mdc_clk",	VFE_MDC_CLK,	NULL, OFF),
+	CLK_PCOM("vfe_axi_clk",	VFE_AXI_CLK,	NULL, OFF),
+	CLK_PCOM("usb_hs2_clk",	USB_HS2_CLK,	NULL, OFF),
+	CLK_PCOM("usb_hs2_pclk",	USB_HS2_P_CLK,	NULL, OFF),
+	CLK_PCOM("usb_hs3_clk",	USB_HS3_CLK,	NULL, OFF),
+	CLK_PCOM("usb_hs3_pclk",	USB_HS3_P_CLK,	NULL, OFF),
+	CLK_PCOM("usb_phy_clk",	USB_PHY_CLK,	NULL, 0),
+};
+
+unsigned msm_num_clocks_8x50 = ARRAY_SIZE(msm_clocks_8x50);
+
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 0744c4a27d6a..568443e76423 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -16,6 +16,8 @@
 #ifndef __ARCH_ARM_MACH_MSM_DEVICES_H
 #define __ARCH_ARM_MACH_MSM_DEVICES_H
 
+#include "clock.h"
+
 extern struct platform_device msm_device_uart1;
 extern struct platform_device msm_device_uart2;
 extern struct platform_device msm_device_uart3;
@@ -33,4 +35,13 @@ extern struct platform_device msm_device_smd;
 
 extern struct platform_device msm_device_nand;
 
+extern struct clk msm_clocks_7x01a[];
+extern unsigned msm_num_clocks_7x01a;
+
+extern struct clk msm_clocks_7x30[];
+extern unsigned msm_num_clocks_7x30;
+
+extern struct clk msm_clocks_8x50[];
+extern unsigned msm_num_clocks_8x50;
+
 #endif
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
index f5420f9585c5..3d725ae518e4 100644
--- a/arch/arm/mach-msm/dma.c
+++ b/arch/arm/mach-msm/dma.c
@@ -13,6 +13,8 @@
  *
  */
 
+#include <linux/clk.h>
+#include <linux/err.h>
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <mach/dma.h>
@@ -26,6 +28,7 @@ enum {
 };
 
 static DEFINE_SPINLOCK(msm_dmov_lock);
+static struct clk *msm_dmov_clk;
 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];
@@ -54,6 +57,9 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
 	unsigned int status;
 
 	spin_lock_irqsave(&msm_dmov_lock, irq_flags);
+	if (!channel_active)
+		clk_enable(msm_dmov_clk);
+	dsb();
 	status = readl(DMOV_STATUS(id));
 	if (list_empty(&ready_commands[id]) &&
 		(status & DMOV_STATUS_CMD_PTR_RDY)) {
@@ -70,6 +76,8 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
 		channel_active |= 1U << id;
 		writel(cmd->cmdptr, DMOV_CMD_PTR(id));
 	} else {
+		if (!channel_active)
+			clk_disable(msm_dmov_clk);
 		if (list_empty(&active_commands[id]))
 			PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status);
 
@@ -165,6 +173,7 @@ 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);
+					dsb();
 					cmd->complete_func(cmd, ch_result, NULL);
 				}
 			}
@@ -181,6 +190,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
 				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);
+					dsb();
 					cmd->complete_func(cmd, ch_result, &errdata);
 				}
 			}
@@ -198,6 +208,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
 				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);
+					dsb();
 					cmd->complete_func(cmd, ch_result, &errdata);
 				}
 				/* this does not seem to work, once we get an error */
@@ -219,8 +230,10 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
 		PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
 	}
 
-	if (!channel_active)
-		disable_irq(INT_ADM_AARM);
+	if (!channel_active) {
+		disable_irq_nosync(INT_ADM_AARM);
+		clk_disable(msm_dmov_clk);
+	}
 
 	spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
 	return IRQ_HANDLED;
@@ -230,11 +243,17 @@ static int __init msm_init_datamover(void)
 {
 	int i;
 	int ret;
+	struct clk *clk;
+
 	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));
 	}
+	clk = clk_get(NULL, "adm_clk");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+	msm_dmov_clk = clk;
 	ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
 	if (ret)
 		return ret;
diff --git a/arch/arm/mach-msm/gpio.c b/arch/arm/mach-msm/gpio.c
new file mode 100644
index 000000000000..bc32c845c7b0
--- /dev/null
+++ b/arch/arm/mach-msm/gpio.c
@@ -0,0 +1,85 @@
+/* linux/arch/arm/mach-msm/gpio.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ *
+ * 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/module.h>
+#include <mach/gpio.h>
+#include "proc_comm.h"
+
+int gpio_tlmm_config(unsigned config, unsigned disable)
+{
+	return msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, &disable);
+}
+EXPORT_SYMBOL(gpio_tlmm_config);
+
+int msm_gpios_enable(const struct msm_gpio *table, int size)
+{
+	int rc;
+	int i;
+	const struct msm_gpio *g;
+	for (i = 0; i < size; i++) {
+		g = table + i;
+		rc = gpio_tlmm_config(g->gpio_cfg, GPIO_ENABLE);
+		if (rc) {
+			pr_err("gpio_tlmm_config(0x%08x, GPIO_ENABLE)"
+			       " <%s> failed: %d\n",
+			       g->gpio_cfg, g->label ?: "?", rc);
+			pr_err("pin %d func %d dir %d pull %d drvstr %d\n",
+			       GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg),
+			       GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg),
+			       GPIO_DRVSTR(g->gpio_cfg));
+			goto err;
+		}
+	}
+	return 0;
+err:
+	msm_gpios_disable(table, i);
+	return rc;
+}
+EXPORT_SYMBOL(msm_gpios_enable);
+
+void msm_gpios_disable(const struct msm_gpio *table, int size)
+{
+	int rc;
+	int i;
+	const struct msm_gpio *g;
+	for (i = size-1; i >= 0; i--) {
+		g = table + i;
+		rc = gpio_tlmm_config(g->gpio_cfg, GPIO_DISABLE);
+		if (rc) {
+			pr_err("gpio_tlmm_config(0x%08x, GPIO_DISABLE)"
+			       " <%s> failed: %d\n",
+			       g->gpio_cfg, g->label ?: "?", rc);
+			pr_err("pin %d func %d dir %d pull %d drvstr %d\n",
+			       GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg),
+			       GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg),
+			       GPIO_DRVSTR(g->gpio_cfg));
+		}
+	}
+}
+EXPORT_SYMBOL(msm_gpios_disable);
+
+int msm_gpios_request_enable(const struct msm_gpio *table, int size)
+{
+	int rc = msm_gpios_enable(table, size);
+	return rc;
+}
+EXPORT_SYMBOL(msm_gpios_request_enable);
+
+void msm_gpios_disable_free(const struct msm_gpio *table, int size)
+{
+	msm_gpios_disable(table, size);
+}
+EXPORT_SYMBOL(msm_gpios_disable_free);
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 264d62e519f3..e302fbdc439b 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -21,18 +21,24 @@
 
 /* platform device data structures */
 
-struct msm_mddi_platform_data
+struct msm_acpu_clock_platform_data
 {
-	void (*panel_power)(int on);
-	unsigned has_vsync_irq:1;
+	uint32_t acpu_switch_time_us;
+	uint32_t max_speed_delta_khz;
+	uint32_t vdd_switch_time_us;
+	unsigned long power_collapse_khz;
+	unsigned long wait_for_irq_khz;
 };
 
+struct clk;
+
 /* common init routines for use by arch/arm/mach-msm/board-*.c */
 
 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);
+void __init msm_clock_init(struct clk *clock_tbl, unsigned num_clocks);
+void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *);
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/clk.h b/arch/arm/mach-msm/include/mach/clk.h
new file mode 100644
index 000000000000..c05ca40478c7
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/clk.h
@@ -0,0 +1,57 @@
+/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef __MACH_CLK_H
+#define __MACH_CLK_H
+
+/* Magic rate value for use with PM QOS to request the board's maximum
+ * supported AXI rate. PM QOS will only pass positive s32 rate values
+ * through to the clock driver, so INT_MAX is used.
+ */
+#define MSM_AXI_MAX_FREQ	LONG_MAX
+
+enum clk_reset_action {
+	CLK_RESET_DEASSERT	= 0,
+	CLK_RESET_ASSERT	= 1
+};
+
+struct clk;
+
+/* Rate is minimum clock rate in Hz */
+int clk_set_min_rate(struct clk *clk, unsigned long rate);
+
+/* Rate is maximum clock rate in Hz */
+int clk_set_max_rate(struct clk *clk, unsigned long rate);
+
+/* Assert/Deassert reset to a hardware block associated with a clock */
+int clk_reset(struct clk *clk, enum clk_reset_action action);
+
+/* Set clock-specific configuration parameters */
+int clk_set_flags(struct clk *clk, unsigned long flags);
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index 5ab5bdffab07..04c51cc04f31 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -41,40 +41,42 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
 #define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2))
 #define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2))
 
-/* only security domain 3 is available to the ARM11
- * SD0 -> mARM trusted, SD1 -> mARM nontrusted, SD2 -> aDSP, SD3 -> aARM
- */
+#if defined(CONFIG_ARCH_MSM7X30)
+#define DMOV_SD_AARM DMOV_SD2
+#else
+#define DMOV_SD_AARM DMOV_SD3
+#endif
 
-#define DMOV_CMD_PTR(ch)      DMOV_SD3(0x000, ch)
+#define DMOV_CMD_PTR(ch)      DMOV_SD_AARM(0x000, ch)
 #define DMOV_CMD_LIST         (0 << 29) /* does not work */
 #define DMOV_CMD_PTR_LIST     (1 << 29) /* works */
 #define DMOV_CMD_INPUT_CFG    (2 << 29) /* untested */
 #define DMOV_CMD_OUTPUT_CFG   (3 << 29) /* untested */
 #define DMOV_CMD_ADDR(addr)   ((addr) >> 3)
 
-#define DMOV_RSLT(ch)         DMOV_SD3(0x040, ch)
+#define DMOV_RSLT(ch)         DMOV_SD_AARM(0x040, ch)
 #define DMOV_RSLT_VALID       (1 << 31) /* 0 == host has empties result fifo */
 #define DMOV_RSLT_ERROR       (1 << 3)
 #define DMOV_RSLT_FLUSH       (1 << 2)
 #define DMOV_RSLT_DONE        (1 << 1)  /* top pointer done */
 #define DMOV_RSLT_USER        (1 << 0)  /* command with FR force result */
 
-#define DMOV_FLUSH0(ch)       DMOV_SD3(0x080, ch)
-#define DMOV_FLUSH1(ch)       DMOV_SD3(0x0C0, ch)
-#define DMOV_FLUSH2(ch)       DMOV_SD3(0x100, ch)
-#define DMOV_FLUSH3(ch)       DMOV_SD3(0x140, ch)
-#define DMOV_FLUSH4(ch)       DMOV_SD3(0x180, ch)
-#define DMOV_FLUSH5(ch)       DMOV_SD3(0x1C0, ch)
+#define DMOV_FLUSH0(ch)       DMOV_SD_AARM(0x080, ch)
+#define DMOV_FLUSH1(ch)       DMOV_SD_AARM(0x0C0, ch)
+#define DMOV_FLUSH2(ch)       DMOV_SD_AARM(0x100, ch)
+#define DMOV_FLUSH3(ch)       DMOV_SD_AARM(0x140, ch)
+#define DMOV_FLUSH4(ch)       DMOV_SD_AARM(0x180, ch)
+#define DMOV_FLUSH5(ch)       DMOV_SD_AARM(0x1C0, ch)
 
-#define DMOV_STATUS(ch)       DMOV_SD3(0x200, ch)
+#define DMOV_STATUS(ch)       DMOV_SD_AARM(0x200, ch)
 #define DMOV_STATUS_RSLT_COUNT(n)    (((n) >> 29))
 #define DMOV_STATUS_CMD_COUNT(n)     (((n) >> 27) & 3)
 #define DMOV_STATUS_RSLT_VALID       (1 << 1)
 #define DMOV_STATUS_CMD_PTR_RDY      (1 << 0)
 
-#define DMOV_ISR              DMOV_SD3(0x380, 0)
-
-#define DMOV_CONFIG(ch)       DMOV_SD3(0x300, ch)
+#define DMOV_ISR              DMOV_SD_AARM(0x380, 0)
+  
+#define DMOV_CONFIG(ch)       DMOV_SD_AARM(0x300, ch)
 #define DMOV_CONFIG_FORCE_TOP_PTR_RSLT (1 << 2)
 #define DMOV_CONFIG_FORCE_FLUSH_RSLT   (1 << 1)
 #define DMOV_CONFIG_IRQ_EN             (1 << 0)
diff --git a/arch/arm/mach-msm/include/mach/gpio.h b/arch/arm/mach-msm/include/mach/gpio.h
new file mode 100644
index 000000000000..262b441b4374
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/gpio.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ * Author: Mike Lockwood <lockwood@android.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 __ASM_ARCH_MSM_GPIO_H
+#define __ASM_ARCH_MSM_GPIO_H
+
+/**
+ * struct msm_gpio - GPIO pin description
+ * @gpio_cfg - configuration bitmap, as per gpio_tlmm_config()
+ * @label - textual label
+ *
+ * Usually, GPIO's are operated by sets.
+ * This struct accumulate all GPIO information in single source
+ * and facilitete group operations provided by msm_gpios_xxx()
+ */
+struct msm_gpio {
+	u32 gpio_cfg;
+	const char *label;
+};
+
+/**
+ * msm_gpios_request_enable() - request and enable set of GPIOs
+ *
+ * Request and configure set of GPIO's
+ * In case of error, all operations rolled back.
+ * Return error code.
+ *
+ * @table: GPIO table
+ * @size:  number of entries in @table
+ */
+int msm_gpios_request_enable(const struct msm_gpio *table, int size);
+
+/**
+ * msm_gpios_disable_free() - disable and free set of GPIOs
+ *
+ * @table: GPIO table
+ * @size:  number of entries in @table
+ */
+void msm_gpios_disable_free(const struct msm_gpio *table, int size);
+
+/**
+ * msm_gpios_request() - request set of GPIOs
+ * In case of error, all operations rolled back.
+ * Return error code.
+ *
+ * @table: GPIO table
+ * @size:  number of entries in @table
+ */
+int msm_gpios_request(const struct msm_gpio *table, int size);
+
+/**
+ * msm_gpios_free() - free set of GPIOs
+ *
+ * @table: GPIO table
+ * @size:  number of entries in @table
+ */
+void msm_gpios_free(const struct msm_gpio *table, int size);
+
+/**
+ * msm_gpios_enable() - enable set of GPIOs
+ * In case of error, all operations rolled back.
+ * Return error code.
+ *
+ * @table: GPIO table
+ * @size:  number of entries in @table
+ */
+int msm_gpios_enable(const struct msm_gpio *table, int size);
+
+/**
+ * msm_gpios_disable() - disable set of GPIOs
+ *
+ * @table: GPIO table
+ * @size:  number of entries in @table
+ */
+void msm_gpios_disable(const struct msm_gpio *table, int size);
+
+/* GPIO TLMM (Top Level Multiplexing) Definitions */
+
+/* GPIO TLMM: Function -- GPIO specific */
+
+/* GPIO TLMM: Direction */
+enum {
+	GPIO_INPUT,
+	GPIO_OUTPUT,
+};
+
+/* GPIO TLMM: Pullup/Pulldown */
+enum {
+	GPIO_NO_PULL,
+	GPIO_PULL_DOWN,
+	GPIO_KEEPER,
+	GPIO_PULL_UP,
+};
+
+/* GPIO TLMM: Drive Strength */
+enum {
+	GPIO_2MA,
+	GPIO_4MA,
+	GPIO_6MA,
+	GPIO_8MA,
+	GPIO_10MA,
+	GPIO_12MA,
+	GPIO_14MA,
+	GPIO_16MA,
+};
+
+enum {
+	GPIO_ENABLE,
+	GPIO_DISABLE,
+};
+
+#define GPIO_CFG(gpio, func, dir, pull, drvstr) \
+	((((gpio) & 0x3FF) << 4)        |	  \
+	 ((func) & 0xf)                  |	  \
+	 (((dir) & 0x1) << 14)           |	  \
+	 (((pull) & 0x3) << 15)          |	  \
+	 (((drvstr) & 0xF) << 17))
+
+/**
+ * extract GPIO pin from bit-field used for gpio_tlmm_config
+ */
+#define GPIO_PIN(gpio_cfg)    (((gpio_cfg) >>  4) & 0x3ff)
+#define GPIO_FUNC(gpio_cfg)   (((gpio_cfg) >>  0) & 0xf)
+#define GPIO_DIR(gpio_cfg)    (((gpio_cfg) >> 14) & 0x1)
+#define GPIO_PULL(gpio_cfg)   (((gpio_cfg) >> 15) & 0x3)
+#define GPIO_DRVSTR(gpio_cfg) (((gpio_cfg) >> 17) & 0xf)
+
+int gpio_tlmm_config(unsigned config, unsigned disable);
+
+#endif /* __ASM_ARCH_MSM_GPIO_H */
diff --git a/arch/arm/mach-msm/include/mach/io.h b/arch/arm/mach-msm/include/mach/io.h
index aab964591db4..c35b29f9ac0f 100644
--- a/arch/arm/mach-msm/include/mach/io.h
+++ b/arch/arm/mach-msm/include/mach/io.h
@@ -26,4 +26,9 @@ void __iomem *__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int m
 #define __io(a)		__typesafe_io(a)
 #define __mem_pci(a)    (a)
 
+void msm_map_qsd8x50_io(void);
+void msm_map_msm7x30_io(void);
+
+extern unsigned int msm_shared_ram_phys;
+
 #endif
diff --git a/arch/arm/mach-msm/include/mach/irqs-7x00.h b/arch/arm/mach-msm/include/mach/irqs-7x00.h
new file mode 100644
index 000000000000..f1fe70612fe9
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/irqs-7x00.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Author: Brian Swetland <swetland@google.com>
+ */
+
+#ifndef __ASM_ARCH_MSM_IRQS_7X00_H
+#define __ASM_ARCH_MSM_IRQS_7X00_H
+
+/* MSM ARM11 Interrupt Numbers */
+/* See 80-VE113-1 A, pp219-221     */
+
+#define INT_A9_M2A_0         0
+#define INT_A9_M2A_1         1
+#define INT_A9_M2A_2         2
+#define INT_A9_M2A_3         3
+#define INT_A9_M2A_4         4
+#define INT_A9_M2A_5         5
+#define INT_A9_M2A_6         6
+#define INT_GP_TIMER_EXP     7
+#define INT_DEBUG_TIMER_EXP  8
+#define INT_UART1            9
+#define INT_UART2            10
+#define INT_UART3            11
+#define INT_UART1_RX         12
+#define INT_UART2_RX         13
+#define INT_UART3_RX         14
+#define INT_USB_OTG          15
+#define INT_MDDI_PRI         16
+#define INT_MDDI_EXT         17
+#define INT_MDDI_CLIENT      18
+#define INT_MDP              19
+#define INT_GRAPHICS         20
+#define INT_ADM_AARM         21
+#define INT_ADSP_A11         22
+#define INT_ADSP_A9_A11      23
+#define INT_SDC1_0           24
+#define INT_SDC1_1           25
+#define INT_SDC2_0           26
+#define INT_SDC2_1           27
+#define INT_KEYSENSE         28
+#define INT_TCHSCRN_SSBI     29
+#define INT_TCHSCRN1         30
+#define INT_TCHSCRN2         31
+
+#define INT_GPIO_GROUP1      (32 + 0)
+#define INT_GPIO_GROUP2      (32 + 1)
+#define INT_PWB_I2C          (32 + 2)
+#define INT_SOFTRESET        (32 + 3)
+#define INT_NAND_WR_ER_DONE  (32 + 4)
+#define INT_NAND_OP_DONE     (32 + 5)
+#define INT_PBUS_ARM11       (32 + 6)
+#define INT_AXI_MPU_SMI      (32 + 7)
+#define INT_AXI_MPU_EBI1     (32 + 8)
+#define INT_AD_HSSD          (32 + 9)
+#define INT_ARM11_PMU        (32 + 10)
+#define INT_ARM11_DMA        (32 + 11)
+#define INT_TSIF_IRQ         (32 + 12)
+#define INT_UART1DM_IRQ      (32 + 13)
+#define INT_UART1DM_RX       (32 + 14)
+#define INT_USB_HS           (32 + 15)
+#define INT_SDC3_0           (32 + 16)
+#define INT_SDC3_1           (32 + 17)
+#define INT_SDC4_0           (32 + 18)
+#define INT_SDC4_1           (32 + 19)
+#define INT_UART2DM_RX       (32 + 20)
+#define INT_UART2DM_IRQ      (32 + 21)
+
+/* 22-31 are reserved */
+
+#define NR_MSM_IRQS 64
+#define NR_GPIO_IRQS 122
+#define NR_BOARD_IRQS 64
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs-7x30.h b/arch/arm/mach-msm/include/mach/irqs-7x30.h
new file mode 100644
index 000000000000..67c5396514fe
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/irqs-7x30.h
@@ -0,0 +1,170 @@
+/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IRQS_7X30_H
+#define __ASM_ARCH_MSM_IRQS_7X30_H
+
+/* MSM ACPU Interrupt Numbers */
+
+#define INT_DEBUG_TIMER_EXP	0
+#define INT_GPT0_TIMER_EXP	1
+#define INT_GPT1_TIMER_EXP	2
+#define INT_WDT0_ACCSCSSBARK	3
+#define INT_WDT1_ACCSCSSBARK	4
+#define INT_AVS_SVIC		5
+#define INT_AVS_SVIC_SW_DONE	6
+#define INT_SC_DBG_RX_FULL	7
+#define INT_SC_DBG_TX_EMPTY	8
+#define INT_ARM11_PM		9
+#define INT_AVS_REQ_DOWN	10
+#define INT_AVS_REQ_UP		11
+#define INT_SC_ACG		12
+/* SCSS_VICFIQSTS0[13:15] are RESERVED */
+#define INT_L2_SVICCPUIRPTREQ	16
+#define INT_L2_SVICDMANSIRPTREQ 17
+#define INT_L2_SVICDMASIRPTREQ  18
+#define INT_L2_SVICSLVIRPTREQ	19
+#define INT_AD5A_MPROC_APPS_0	20
+#define INT_AD5A_MPROC_APPS_1	21
+#define INT_A9_M2A_0		22
+#define INT_A9_M2A_1		23
+#define INT_A9_M2A_2		24
+#define INT_A9_M2A_3		25
+#define INT_A9_M2A_4		26
+#define INT_A9_M2A_5		27
+#define INT_A9_M2A_6		28
+#define INT_A9_M2A_7		29
+#define INT_A9_M2A_8		30
+#define INT_A9_M2A_9		31
+
+#define INT_AXI_EBI1_SC		(32 + 0)
+#define INT_IMEM_ERR		(32 + 1)
+#define INT_AXI_EBI0_SC		(32 + 2)
+#define INT_PBUS_SC_IRQC	(32 + 3)
+#define INT_PERPH_BUS_BPM	(32 + 4)
+#define INT_CC_TEMP_SENSE	(32 + 5)
+#define INT_UXMC_EBI0		(32 + 6)
+#define INT_UXMC_EBI1		(32 + 7)
+#define INT_EBI2_OP_DONE	(32 + 8)
+#define INT_EBI2_WR_ER_DONE	(32 + 9)
+#define INT_TCSR_SPSS_CE	(32 + 10)
+#define INT_EMDH		(32 + 11)
+#define INT_PMDH		(32 + 12)
+#define INT_MDC			(32 + 13)
+#define INT_MIDI_TO_SUPSS	(32 + 14)
+#define INT_LPA_2		(32 + 15)
+#define INT_GPIO_GROUP1_SECURE	(32 + 16)
+#define INT_GPIO_GROUP2_SECURE	(32 + 17)
+#define INT_GPIO_GROUP1		(32 + 18)
+#define INT_GPIO_GROUP2		(32 + 19)
+#define INT_MPRPH_SOFTRESET	(32 + 20)
+#define INT_PWB_I2C		(32 + 21)
+#define INT_PWB_I2C_2		(32 + 22)
+#define INT_TSSC_SAMPLE		(32 + 23)
+#define INT_TSSC_PENUP		(32 + 24)
+#define INT_TCHSCRN_SSBI	(32 + 25)
+#define INT_FM_RDS		(32 + 26)
+#define INT_KEYSENSE 		(32 + 27)
+#define INT_USB_OTG_HS		(32 + 28)
+#define INT_USB_OTG_HS2		(32 + 29)
+#define INT_USB_OTG_HS3		(32 + 30)
+#define INT_CSI			(32 + 31)
+
+#define INT_SPI_OUTPUT		(64 + 0)
+#define INT_SPI_INPUT		(64 + 1)
+#define INT_SPI_ERROR		(64 + 2)
+#define INT_UART1		(64 + 3)
+#define INT_UART1_RX		(64 + 4)
+#define INT_UART2		(64 + 5)
+#define INT_UART2_RX		(64 + 6)
+#define INT_UART3		(64 + 7)
+#define INT_UART3_RX		(64 + 8)
+#define INT_UART1DM_IRQ		(64 + 9)
+#define INT_UART1DM_RX		(64 + 10)
+#define INT_UART2DM_IRQ		(64 + 11)
+#define INT_UART2DM_RX		(64 + 12)
+#define INT_TSIF		(64 + 13)
+#define INT_ADM_SC1		(64 + 14)
+#define INT_ADM_SC2		(64 + 15)
+#define INT_MDP			(64 + 16)
+#define INT_VPE			(64 + 17)
+#define INT_GRP_2D		(64 + 18)
+#define INT_GRP_3D		(64 + 19)
+#define INT_ROTATOR		(64 + 20)
+#define INT_MFC720		(64 + 21)
+#define INT_JPEG		(64 + 22)
+#define INT_VFE			(64 + 23)
+#define INT_TV_ENC		(64 + 24)
+#define INT_PMIC_SSBI		(64 + 25)
+#define INT_MPM_1		(64 + 26)
+#define INT_TCSR_SPSS_SAMPLE	(64 + 27)
+#define INT_TCSR_SPSS_PENUP	(64 + 28)
+#define INT_MPM_2		(64 + 29)
+#define INT_SDC1_0		(64 + 30)
+#define INT_SDC1_1		(64 + 31)
+
+#define INT_SDC3_0		(96 + 0)
+#define INT_SDC3_1		(96 + 1)
+#define INT_SDC2_0		(96 + 2)
+#define INT_SDC2_1		(96 + 3)
+#define INT_SDC4_0		(96 + 4)
+#define INT_SDC4_1		(96 + 5)
+#define INT_PWB_QUP_IN		(96 + 6)
+#define INT_PWB_QUP_OUT		(96 + 7)
+#define INT_PWB_QUP_ERR		(96 + 8)
+#define INT_SCSS_WDT0_BITE	(96 + 9)
+/* SCSS_VICFIQSTS3[10:31] are RESERVED */
+
+/* Retrofit universal macro names */
+#define INT_ADM_AARM		INT_ADM_SC2
+#define INT_USB_HS   		INT_USB_OTG_HS
+#define INT_USB_OTG   		INT_USB_OTG_HS
+#define INT_TCHSCRN1 		INT_TSSC_SAMPLE
+#define INT_TCHSCRN2 		INT_TSSC_PENUP
+#define INT_GP_TIMER_EXP 	INT_GPT0_TIMER_EXP
+#define INT_ADSP_A11 		INT_AD5A_MPROC_APPS_0
+#define INT_ADSP_A9_A11 	INT_AD5A_MPROC_APPS_1
+#define INT_MDDI_EXT		INT_EMDH
+#define INT_MDDI_PRI		INT_PMDH
+#define INT_MDDI_CLIENT		INT_MDC
+#define INT_NAND_WR_ER_DONE	INT_EBI2_WR_ER_DONE
+#define INT_NAND_OP_DONE	INT_EBI2_OP_DONE
+
+#define NR_MSM_IRQS		128
+#define NR_GPIO_IRQS		182
+#define PMIC8058_IRQ_BASE	(NR_MSM_IRQS + NR_GPIO_IRQS)
+#define NR_PMIC8058_GPIO_IRQS	40
+#define NR_PMIC8058_MPP_IRQS	12
+#define NR_PMIC8058_MISC_IRQS	8
+#define NR_PMIC8058_IRQS	(NR_PMIC8058_GPIO_IRQS +\
+				NR_PMIC8058_MPP_IRQS +\
+				NR_PMIC8058_MISC_IRQS)
+#define NR_BOARD_IRQS		NR_PMIC8058_IRQS
+
+#endif /* __ASM_ARCH_MSM_IRQS_7X30_H */
diff --git a/arch/arm/mach-msm/include/mach/irqs-8x50.h b/arch/arm/mach-msm/include/mach/irqs-8x50.h
new file mode 100644
index 000000000000..de3d8fe24e4e
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/irqs-8x50.h
@@ -0,0 +1,105 @@
+/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IRQS_8XXX_H
+#define __ASM_ARCH_MSM_IRQS_8XXX_H
+
+/* MSM ACPU Interrupt Numbers */
+
+#define INT_A9_M2A_0         0
+#define INT_A9_M2A_1         1
+#define INT_A9_M2A_2         2
+#define INT_A9_M2A_3         3
+#define INT_A9_M2A_4         4
+#define INT_A9_M2A_5         5
+#define INT_A9_M2A_6         6
+#define INT_GP_TIMER_EXP     7
+#define INT_DEBUG_TIMER_EXP  8
+#define INT_SIRC_0           9
+#define INT_SDC3_0           10
+#define INT_SDC3_1           11
+#define INT_SDC4_0           12
+#define INT_SDC4_1           13
+#define INT_AD6_EXT_VFR      14
+#define INT_USB_OTG          15
+#define INT_MDDI_PRI         16
+#define INT_MDDI_EXT         17
+#define INT_MDDI_CLIENT      18
+#define INT_MDP              19
+#define INT_GRAPHICS         20
+#define INT_ADM_AARM         21
+#define INT_ADSP_A11         22
+#define INT_ADSP_A9_A11      23
+#define INT_SDC1_0           24
+#define INT_SDC1_1           25
+#define INT_SDC2_0           26
+#define INT_SDC2_1           27
+#define INT_KEYSENSE         28
+#define INT_TCHSCRN_SSBI     29
+#define INT_TCHSCRN1         30
+#define INT_TCHSCRN2         31
+
+#define INT_TCSR_MPRPH_SC1   (32 + 0)
+#define INT_USB_FS2          (32 + 1)
+#define INT_PWB_I2C          (32 + 2)
+#define INT_SOFTRESET        (32 + 3)
+#define INT_NAND_WR_ER_DONE  (32 + 4)
+#define INT_NAND_OP_DONE     (32 + 5)
+#define INT_TCSR_MPRPH_SC2   (32 + 6)
+#define INT_OP_PEN           (32 + 7)
+#define INT_AD_HSSD          (32 + 8)
+#define INT_ARM11_PM         (32 + 9)
+#define INT_SDMA_NON_SECURE  (32 + 10)
+#define INT_TSIF_IRQ         (32 + 11)
+#define INT_UART1DM_IRQ      (32 + 12)
+#define INT_UART1DM_RX       (32 + 13)
+#define INT_SDMA_SECURE      (32 + 14)
+#define INT_SI2S_SLAVE       (32 + 15)
+#define INT_SC_I2CPU         (32 + 16)
+#define INT_SC_DBG_RDTRFULL  (32 + 17)
+#define INT_SC_DBG_WDTRFULL  (32 + 18)
+#define INT_SCPLL_CTL_DONE   (32 + 19)
+#define INT_UART2DM_IRQ      (32 + 20)
+#define INT_UART2DM_RX       (32 + 21)
+#define INT_VDC_MEC          (32 + 22)
+#define INT_VDC_DB           (32 + 23)
+#define INT_VDC_AXI          (32 + 24)
+#define INT_VFE              (32 + 25)
+#define INT_USB_HS           (32 + 26)
+#define INT_AUDIO_OUT0       (32 + 27)
+#define INT_AUDIO_OUT1       (32 + 28)
+#define INT_CRYPTO           (32 + 29)
+#define INT_AD6M_IDLE        (32 + 30)
+#define INT_SIRC_1           (32 + 31)
+
+#define NR_GPIO_IRQS 165
+#define NR_MSM_IRQS 64
+#define NR_BOARD_IRQS 64
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs.h b/arch/arm/mach-msm/include/mach/irqs.h
index 9dd4cf8a2693..164d355c96ea 100644
--- a/arch/arm/mach-msm/include/mach/irqs.h
+++ b/arch/arm/mach-msm/include/mach/irqs.h
@@ -1,6 +1,6 @@
-/* arch/arm/mach-msm/include/mach/irqs.h
- *
+/*
  * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -17,74 +17,21 @@
 #ifndef __ASM_ARCH_MSM_IRQS_H
 #define __ASM_ARCH_MSM_IRQS_H
 
-/* MSM ARM11 Interrupt Numbers */
-/* See 80-VE113-1 A, pp219-221     */
-
-#define INT_A9_M2A_0         0
-#define INT_A9_M2A_1         1
-#define INT_A9_M2A_2         2
-#define INT_A9_M2A_3         3
-#define INT_A9_M2A_4         4
-#define INT_A9_M2A_5         5
-#define INT_A9_M2A_6         6
-#define INT_GP_TIMER_EXP     7
-#define INT_DEBUG_TIMER_EXP  8
-#define INT_UART1            9
-#define INT_UART2            10
-#define INT_UART3            11
-#define INT_UART1_RX         12
-#define INT_UART2_RX         13
-#define INT_UART3_RX         14
-#define INT_USB_OTG          15
-#define INT_MDDI_PRI         16
-#define INT_MDDI_EXT         17
-#define INT_MDDI_CLIENT      18
-#define INT_MDP              19
-#define INT_GRAPHICS         20
-#define INT_ADM_AARM         21
-#define INT_ADSP_A11         22
-#define INT_ADSP_A9_A11      23
-#define INT_SDC1_0           24
-#define INT_SDC1_1           25
-#define INT_SDC2_0           26
-#define INT_SDC2_1           27
-#define INT_KEYSENSE         28
-#define INT_TCHSCRN_SSBI     29
-#define INT_TCHSCRN1         30
-#define INT_TCHSCRN2         31
-
-#define INT_GPIO_GROUP1      (32 + 0)
-#define INT_GPIO_GROUP2      (32 + 1)
-#define INT_PWB_I2C          (32 + 2)
-#define INT_SOFTRESET        (32 + 3)
-#define INT_NAND_WR_ER_DONE  (32 + 4)
-#define INT_NAND_OP_DONE     (32 + 5)
-#define INT_PBUS_ARM11       (32 + 6)
-#define INT_AXI_MPU_SMI      (32 + 7)
-#define INT_AXI_MPU_EBI1     (32 + 8)
-#define INT_AD_HSSD          (32 + 9)
-#define INT_ARM11_PMU        (32 + 10)
-#define INT_ARM11_DMA        (32 + 11)
-#define INT_TSIF_IRQ         (32 + 12)
-#define INT_UART1DM_IRQ      (32 + 13)
-#define INT_UART1DM_RX       (32 + 14)
-#define INT_USB_HS           (32 + 15)
-#define INT_SDC3_0           (32 + 16)
-#define INT_SDC3_1           (32 + 17)
-#define INT_SDC4_0           (32 + 18)
-#define INT_SDC4_1           (32 + 19)
-#define INT_UART2DM_RX       (32 + 20)
-#define INT_UART2DM_IRQ      (32 + 21)
-
-/* 22-31 are reserved */
-
 #define MSM_IRQ_BIT(irq)     (1 << ((irq) & 31))
 
-#define NR_MSM_IRQS 64
-#define NR_GPIO_IRQS 122
-#define NR_BOARD_IRQS 64
-#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS)
+#if defined(CONFIG_ARCH_MSM7X30)
+#include "irqs-7x30.h"
+#elif defined(CONFIG_ARCH_QSD8X50)
+#include "irqs-8x50.h"
+#include "sirc.h"
+#elif defined(CONFIG_ARCH_MSM_ARM11)
+#include "irqs-7x00.h"
+#else
+#error "Unknown architecture specification"
+#endif
 
+#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS)
 #define MSM_GPIO_TO_INT(n) (NR_MSM_IRQS + (n))
+#define MSM_INT_TO_REG(base, irq) (base + irq / 32)
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h
index f4698baec976..50c7847e6002 100644
--- a/arch/arm/mach-msm/include/mach/memory.h
+++ b/arch/arm/mach-msm/include/mach/memory.h
@@ -17,7 +17,15 @@
 #define __ASM_ARCH_MEMORY_H
 
 /* physical offset of RAM */
+#if defined(CONFIG_ARCH_QSD8X50) && defined(CONFIG_MSM_SOC_REV_A)
+#define PHYS_OFFSET		UL(0x00000000)
+#elif defined(CONFIG_ARCH_QSD8X50)
+#define PHYS_OFFSET		UL(0x20000000)
+#elif defined(CONFIG_ARCH_MSM7X30)
+#define PHYS_OFFSET		UL(0x00200000)
+#else
 #define PHYS_OFFSET		UL(0x10000000)
+#endif
 
 #endif
 
diff --git a/arch/arm/mach-msm/include/mach/msm_fb.h b/arch/arm/mach-msm/include/mach/msm_fb.h
new file mode 100644
index 000000000000..1f4fc81b3d8f
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_fb.h
@@ -0,0 +1,147 @@
+/* arch/arm/mach-msm/include/mach/msm_fb.h
+ *
+ * Internal shared definitions for various MSM framebuffer parts.
+ *
+ * Copyright (C) 2007 Google 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 _MSM_FB_H_
+#define _MSM_FB_H_
+
+#include <linux/device.h>
+
+struct mddi_info;
+
+struct msm_fb_data {
+	int xres;	/* x resolution in pixels */
+	int yres;	/* y resolution in pixels */
+	int width;	/* disply width in mm */
+	int height;	/* display height in mm */
+	unsigned output_format;
+};
+
+struct msmfb_callback {
+	void (*func)(struct msmfb_callback *);
+};
+
+enum {
+	MSM_MDDI_PMDH_INTERFACE,
+	MSM_MDDI_EMDH_INTERFACE,
+	MSM_EBI2_INTERFACE,
+};
+
+#define MSMFB_CAP_PARTIAL_UPDATES	(1 << 0)
+
+struct msm_panel_data {
+	/* turns off the fb memory */
+	int (*suspend)(struct msm_panel_data *);
+	/* turns on the fb memory */
+	int (*resume)(struct msm_panel_data *);
+	/* turns off the panel */
+	int (*blank)(struct msm_panel_data *);
+	/* turns on the panel */
+	int (*unblank)(struct msm_panel_data *);
+	void (*wait_vsync)(struct msm_panel_data *);
+	void (*request_vsync)(struct msm_panel_data *, struct msmfb_callback *);
+	void (*clear_vsync)(struct msm_panel_data *);
+	/* from the enum above */
+	unsigned interface_type;
+	/* data to be passed to the fb driver */
+	struct msm_fb_data *fb_data;
+
+	/* capabilities supported by the panel */
+	uint32_t caps;
+};
+
+struct msm_mddi_client_data {
+	void (*suspend)(struct msm_mddi_client_data *);
+	void (*resume)(struct msm_mddi_client_data *);
+	void (*activate_link)(struct msm_mddi_client_data *);
+	void (*remote_write)(struct msm_mddi_client_data *, uint32_t val,
+			     uint32_t reg);
+	uint32_t (*remote_read)(struct msm_mddi_client_data *, uint32_t reg);
+	void (*auto_hibernate)(struct msm_mddi_client_data *, int);
+	/* custom data that needs to be passed from the board file to a 
+	 * particular client */
+	void *private_client_data;
+	struct resource *fb_resource;
+	/* from the list above */
+	unsigned interface_type;
+};
+
+struct msm_mddi_platform_data {
+	unsigned int clk_rate;
+	void (*power_client)(struct msm_mddi_client_data *, int on);
+
+	/* fixup the mfr name, product id */
+	void (*fixup)(uint16_t *mfr_name, uint16_t *product_id);
+
+	struct resource *fb_resource; /*optional*/
+	/* number of clients in the list that follows */
+	int num_clients;
+	/* array of client information of clients */
+	struct {
+		unsigned product_id; /* mfr id in top 16 bits, product id
+				      * in lower 16 bits
+				      */
+		char *name;	/* the device name will be the platform
+				 * device name registered for the client,
+				 * it should match the name of the associated
+				 * driver
+				 */
+		unsigned id;	/* id for mddi client device node, will also
+				 * be used as device id of panel devices, if
+				 * the client device will have multiple panels
+				 * space must be left here for them
+				 */
+		void *client_data;	/* required private client data */
+		unsigned int clk_rate;	/* optional: if the client requires a
+					* different mddi clk rate
+					*/
+	} client_platform_data[];
+};
+
+struct mdp_blit_req;
+struct fb_info;
+struct mdp_device {
+	struct device dev;
+	void (*dma)(struct mdp_device *mpd, uint32_t addr,
+		    uint32_t stride, uint32_t w, uint32_t h, uint32_t x,
+		    uint32_t y, struct msmfb_callback *callback, int interface);
+	void (*dma_wait)(struct mdp_device *mdp);
+	int (*blit)(struct mdp_device *mdp, struct fb_info *fb,
+		    struct mdp_blit_req *req);
+	void (*set_grp_disp)(struct mdp_device *mdp, uint32_t disp_id);
+};
+
+struct class_interface;
+int register_mdp_client(struct class_interface *class_intf);
+
+/**** private client data structs go below this line ***/
+
+struct msm_mddi_bridge_platform_data {
+	/* from board file */
+	int (*init)(struct msm_mddi_bridge_platform_data *,
+		    struct msm_mddi_client_data *);
+	int (*uninit)(struct msm_mddi_bridge_platform_data *,
+		      struct msm_mddi_client_data *);
+	/* passed to panel for use by the fb driver */
+	int (*blank)(struct msm_mddi_bridge_platform_data *,
+		     struct msm_mddi_client_data *);
+	int (*unblank)(struct msm_mddi_bridge_platform_data *,
+		       struct msm_mddi_client_data *);
+	struct msm_fb_data fb_data;
+};
+
+
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h
new file mode 100644
index 000000000000..cfff0e74f128
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h
@@ -0,0 +1,139 @@
+/* arch/arm/mach-msm/include/mach/msm_iomap.h
+ *
+ * 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.
+ *
+ *
+ * The MSM peripherals are spread all over across 768MB of physical
+ * space, which makes just having a simple IO_ADDRESS macro to slide
+ * them into the right virtual location rough.  Instead, we will
+ * provide a master phys->virt mapping for peripherals here.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IOMAP_7X00_H
+#define __ASM_ARCH_MSM_IOMAP_7X00_H
+
+#include <asm/sizes.h>
+
+/* Physical base address and size of peripherals.
+ * Ordered by the virtual base addresses they will be mapped at.
+ *
+ * MSM_VIC_BASE must be an value that can be loaded via a "mov"
+ * instruction, otherwise entry-macro.S will not compile.
+ *
+ * If you add or remove entries here, you'll want to edit the
+ * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
+ * changes.
+ *
+ */
+
+#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          IOMEM(0xE0001000)
+#define MSM_CSR_PHYS          0xC0100000
+#define MSM_CSR_SIZE          SZ_4K
+
+#define MSM_GPT_PHYS          MSM_CSR_PHYS
+#define MSM_GPT_BASE          MSM_CSR_BASE
+#define MSM_GPT_SIZE          SZ_4K
+
+#define MSM_DMOV_BASE         IOMEM(0xE0002000)
+#define MSM_DMOV_PHYS         0xA9700000
+#define MSM_DMOV_SIZE         SZ_4K
+
+#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_PHYS        0xA9B00000
+#define MSM_UART2_SIZE        SZ_4K
+
+#define MSM_UART3_PHYS        0xA9C00000
+#define MSM_UART3_SIZE        SZ_4K
+
+#ifdef CONFIG_MSM_DEBUG_UART
+#define MSM_DEBUG_UART_BASE   0xE1000000
+#if CONFIG_MSM_DEBUG_UART == 1
+#define MSM_DEBUG_UART_PHYS   MSM_UART1_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 2
+#define MSM_DEBUG_UART_PHYS   MSM_UART2_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 3
+#define MSM_DEBUG_UART_PHYS   MSM_UART3_PHYS
+#endif
+#define MSM_DEBUG_UART_SIZE   SZ_4K
+#endif
+
+#define MSM_SDC1_PHYS         0xA0400000
+#define MSM_SDC1_SIZE         SZ_4K
+
+#define MSM_SDC2_PHYS         0xA0500000
+#define MSM_SDC2_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_PHYS        0xA0800000
+#define MSM_HSUSB_SIZE        SZ_4K
+
+#define MSM_PMDH_PHYS         0xAA600000
+#define MSM_PMDH_SIZE         SZ_4K
+
+#define MSM_EMDH_PHYS         0xAA700000
+#define MSM_EMDH_SIZE         SZ_4K
+
+#define MSM_MDP_PHYS          0xAA200000
+#define MSM_MDP_SIZE          0x000F0000
+
+#define MSM_MDC_PHYS	      0xAA500000
+#define MSM_MDC_SIZE	      SZ_1M
+
+#define MSM_AD5_PHYS          0xAC000000
+#define MSM_AD5_SIZE          (SZ_1M*13)
+
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#define MSM_GCC_BASE          IOMEM(0xF8009000)
+#define MSM_GCC_PHYS          0xC0182000
+#define MSM_GCC_SIZE          SZ_4K
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
new file mode 100644
index 000000000000..8a00c2defbc1
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * 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.
+ *
+ *
+ * The MSM peripherals are spread all over across 768MB of physical
+ * space, which makes just having a simple IO_ADDRESS macro to slide
+ * them into the right virtual location rough.  Instead, we will
+ * provide a master phys->virt mapping for peripherals here.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IOMAP_7X30_H
+#define __ASM_ARCH_MSM_IOMAP_7X30_H
+
+/* Physical base address and size of peripherals.
+ * Ordered by the virtual base addresses they will be mapped at.
+ *
+ * MSM_VIC_BASE must be an value that can be loaded via a "mov"
+ * instruction, otherwise entry-macro.S will not compile.
+ *
+ * If you add or remove entries here, you'll want to edit the
+ * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
+ * changes.
+ *
+ */
+
+#define MSM_VIC_BASE          IOMEM(0xE0000000)
+#define MSM_VIC_PHYS          0xC0080000
+#define MSM_VIC_SIZE          SZ_4K
+
+#define MSM_CSR_BASE          IOMEM(0xE0001000)
+#define MSM_CSR_PHYS          0xC0100000
+#define MSM_CSR_SIZE          SZ_4K
+
+#define MSM_TMR_PHYS          MSM_CSR_PHYS
+#define MSM_TMR_BASE          MSM_CSR_BASE
+#define MSM_TMR_SIZE          SZ_4K
+
+#define MSM_GPT_BASE 	      (MSM_TMR_BASE + 0x4)
+#define MSM_DGT_BASE 	      (MSM_TMR_BASE + 0x24)
+
+#define MSM_DMOV_BASE         IOMEM(0xE0002000)
+#define MSM_DMOV_PHYS         0xAC400000
+#define MSM_DMOV_SIZE         SZ_4K
+
+#define MSM_GPIO1_BASE        IOMEM(0xE0003000)
+#define MSM_GPIO1_PHYS        0xAC001000
+#define MSM_GPIO1_SIZE        SZ_4K
+
+#define MSM_GPIO2_BASE        IOMEM(0xE0004000)
+#define MSM_GPIO2_PHYS        0xAC101000
+#define MSM_GPIO2_SIZE        SZ_4K
+
+#define MSM_CLK_CTL_BASE      IOMEM(0xE0005000)
+#define MSM_CLK_CTL_PHYS      0xAB800000
+#define MSM_CLK_CTL_SIZE      SZ_4K
+
+#define MSM_CLK_CTL_SH2_BASE  IOMEM(0xE0006000)
+#define MSM_CLK_CTL_SH2_PHYS  0xABA01000
+#define MSM_CLK_CTL_SH2_SIZE  SZ_4K
+
+#define MSM_ACC_BASE          IOMEM(0xE0007000)
+#define MSM_ACC_PHYS          0xC0101000
+#define MSM_ACC_SIZE          SZ_4K
+
+#define MSM_SAW_BASE          IOMEM(0xE0008000)
+#define MSM_SAW_PHYS          0xC0102000
+#define MSM_SAW_SIZE          SZ_4K
+
+#define MSM_GCC_BASE	      IOMEM(0xE0009000)
+#define MSM_GCC_PHYS	      0xC0182000
+#define MSM_GCC_SIZE	      SZ_4K
+
+#define MSM_TCSR_BASE	      IOMEM(0xE000A000)
+#define MSM_TCSR_PHYS	      0xAB600000
+#define MSM_TCSR_SIZE	      SZ_4K
+
+#define MSM_SHARED_RAM_BASE   IOMEM(0xE0100000)
+#define MSM_SHARED_RAM_PHYS   0x00100000
+#define MSM_SHARED_RAM_SIZE   SZ_1M
+
+#define MSM_UART1_PHYS        0xACA00000
+#define MSM_UART1_SIZE        SZ_4K
+
+#define MSM_UART2_PHYS        0xACB00000
+#define MSM_UART2_SIZE        SZ_4K
+
+#define MSM_UART3_PHYS        0xACC00000
+#define MSM_UART3_SIZE        SZ_4K
+
+#ifdef CONFIG_MSM_DEBUG_UART
+#define MSM_DEBUG_UART_BASE   0xE1000000
+#if CONFIG_MSM_DEBUG_UART == 1
+#define MSM_DEBUG_UART_PHYS   MSM_UART1_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 2
+#define MSM_DEBUG_UART_PHYS   MSM_UART2_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 3
+#define MSM_DEBUG_UART_PHYS   MSM_UART3_PHYS
+#endif
+#define MSM_DEBUG_UART_SIZE   SZ_4K
+#endif
+
+#define MSM_MDC_BASE	      IOMEM(0xE0200000)
+#define MSM_MDC_PHYS	      0xAA500000
+#define MSM_MDC_SIZE	      SZ_1M
+
+#define MSM_AD5_BASE          IOMEM(0xE0300000)
+#define MSM_AD5_PHYS          0xA7000000
+#define MSM_AD5_SIZE          (SZ_1M*13)
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
new file mode 100644
index 000000000000..acc819eb76e5
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * 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.
+ *
+ *
+ * The MSM peripherals are spread all over across 768MB of physical
+ * space, which makes just having a simple IO_ADDRESS macro to slide
+ * them into the right virtual location rough.  Instead, we will
+ * provide a master phys->virt mapping for peripherals here.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IOMAP_8X50_H
+#define __ASM_ARCH_MSM_IOMAP_8X50_H
+
+/* Physical base address and size of peripherals.
+ * Ordered by the virtual base addresses they will be mapped at.
+ *
+ * MSM_VIC_BASE must be an value that can be loaded via a "mov"
+ * instruction, otherwise entry-macro.S will not compile.
+ *
+ * If you add or remove entries here, you'll want to edit the
+ * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
+ * changes.
+ *
+ */
+
+#define MSM_VIC_BASE          IOMEM(0xE0000000)
+#define MSM_VIC_PHYS          0xAC000000
+#define MSM_VIC_SIZE          SZ_4K
+
+#define MSM_CSR_BASE          IOMEM(0xE0001000)
+#define MSM_CSR_PHYS          0xAC100000
+#define MSM_CSR_SIZE          SZ_4K
+
+#define MSM_TMR_PHYS          MSM_CSR_PHYS
+#define MSM_TMR_BASE          MSM_CSR_BASE
+#define MSM_TMR_SIZE          SZ_4K
+
+#define MSM_GPT_BASE          MSM_TMR_BASE
+#define MSM_DGT_BASE          (MSM_TMR_BASE + 0x10)
+
+#define MSM_DMOV_BASE         IOMEM(0xE0002000)
+#define MSM_DMOV_PHYS         0xA9700000
+#define MSM_DMOV_SIZE         SZ_4K
+
+#define MSM_GPIO1_BASE        IOMEM(0xE0003000)
+#define MSM_GPIO1_PHYS        0xA9000000
+#define MSM_GPIO1_SIZE        SZ_4K
+
+#define MSM_GPIO2_BASE        IOMEM(0xE0004000)
+#define MSM_GPIO2_PHYS        0xA9100000
+#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_SIRC_BASE         IOMEM(0xE1006000)
+#define MSM_SIRC_PHYS         0xAC200000
+#define MSM_SIRC_SIZE         SZ_4K
+
+#define MSM_SCPLL_BASE        IOMEM(0xE1007000)
+#define MSM_SCPLL_PHYS        0xA8800000
+#define MSM_SCPLL_SIZE        SZ_4K
+
+#ifdef CONFIG_MSM_SOC_REV_A
+#define MSM_SMI_BASE 0xE0000000
+#else
+#define MSM_SMI_BASE 0x00000000
+#endif
+
+#define MSM_SHARED_RAM_BASE   IOMEM(0xE0100000)
+#define MSM_SHARED_RAM_PHYS (MSM_SMI_BASE + 0x00100000)
+#define MSM_SHARED_RAM_SIZE   SZ_1M
+
+#define MSM_UART1_PHYS        0xA9A00000
+#define MSM_UART1_SIZE        SZ_4K
+
+#define MSM_UART2_PHYS        0xA9B00000
+#define MSM_UART2_SIZE        SZ_4K
+
+#define MSM_UART3_PHYS        0xA9C00000
+#define MSM_UART3_SIZE        SZ_4K
+
+#ifdef CONFIG_MSM_DEBUG_UART
+#define MSM_DEBUG_UART_BASE   0xE1000000
+#if CONFIG_MSM_DEBUG_UART == 1
+#define MSM_DEBUG_UART_PHYS   MSM_UART1_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 2
+#define MSM_DEBUG_UART_PHYS   MSM_UART2_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 3
+#define MSM_DEBUG_UART_PHYS   MSM_UART3_PHYS
+#endif
+#define MSM_DEBUG_UART_SIZE   SZ_4K
+#endif
+
+#define MSM_MDC_BASE	      IOMEM(0xE0200000)
+#define MSM_MDC_PHYS	      0xAA500000
+#define MSM_MDC_SIZE	      SZ_1M
+
+#define MSM_AD5_BASE          IOMEM(0xE0300000)
+#define MSM_AD5_PHYS          0xAC000000
+#define MSM_AD5_SIZE          (SZ_1M*13)
+
+
+#define MSM_I2C_SIZE          SZ_4K
+#define MSM_I2C_PHYS          0xA9900000
+
+#define MSM_HSUSB_PHYS        0xA0800000
+#define MSM_HSUSB_SIZE        SZ_1K
+
+#define MSM_NAND_PHYS           0xA0A00000
+
+
+#define MSM_TSIF_PHYS        (0xa0100000)
+#define MSM_TSIF_SIZE        (0x200)
+
+#define MSM_TSSC_PHYS         0xAA300000
+
+#define MSM_UART1DM_PHYS      0xA0200000
+#define MSM_UART2DM_PHYS      0xA0900000
+
+
+#define MSM_SDC1_PHYS          0xA0400000
+#define MSM_SDC1_SIZE          SZ_4K
+
+#define MSM_SDC2_PHYS          0xA0500000
+#define MSM_SDC2_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
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index 9dae1a98c77a..e6b1821cc4ea 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -1,6 +1,6 @@
-/* arch/arm/mach-msm/include/mach/msm_iomap.h
- *
+/*
  * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -43,91 +43,12 @@
 #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          IOMEM(0xE0001000)
-#define MSM_CSR_PHYS          0xC0100000
-#define MSM_CSR_SIZE          SZ_4K
-
-#define MSM_GPT_PHYS          MSM_CSR_PHYS
-#define MSM_GPT_BASE          MSM_CSR_BASE
-#define MSM_GPT_SIZE          SZ_4K
-
-#define MSM_DMOV_BASE         IOMEM(0xE0002000)
-#define MSM_DMOV_PHYS         0xA9700000
-#define MSM_DMOV_SIZE         SZ_4K
-
-#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_PHYS        0xA9B00000
-#define MSM_UART2_SIZE        SZ_4K
-
-#define MSM_UART3_PHYS        0xA9C00000
-#define MSM_UART3_SIZE        SZ_4K
-
-#ifdef CONFIG_MSM_DEBUG_UART
-#define MSM_DEBUG_UART_BASE   0xE1000000
-#if CONFIG_MSM_DEBUG_UART == 1
-#define MSM_DEBUG_UART_PHYS   MSM_UART1_PHYS
-#elif CONFIG_MSM_DEBUG_UART == 2
-#define MSM_DEBUG_UART_PHYS   MSM_UART2_PHYS
-#elif CONFIG_MSM_DEBUG_UART == 3
-#define MSM_DEBUG_UART_PHYS   MSM_UART3_PHYS
-#endif
-#define MSM_DEBUG_UART_SIZE   SZ_4K
+#if defined(CONFIG_ARCH_MSM7X30)
+#include "msm_iomap-7x30.h"
+#elif defined(CONFIG_ARCH_QSD8X50)
+#include "msm_iomap-8x50.h"
+#else
+#include "msm_iomap-7x00.h"
 #endif
 
-#define MSM_SDC1_PHYS         0xA0400000
-#define MSM_SDC1_SIZE         SZ_4K
-
-#define MSM_SDC2_PHYS         0xA0500000
-#define MSM_SDC2_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_PHYS        0xA0800000
-#define MSM_HSUSB_SIZE        SZ_4K
-
-#define MSM_PMDH_PHYS         0xAA600000
-#define MSM_PMDH_SIZE         SZ_4K
-
-#define MSM_EMDH_PHYS         0xAA700000
-#define MSM_EMDH_SIZE         SZ_4K
-
-#define MSM_MDP_PHYS          0xAA200000
-#define MSM_MDP_SIZE          0x000F0000
-
-#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/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h
new file mode 100644
index 000000000000..029463ec8756
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_smd.h
@@ -0,0 +1,109 @@
+/* linux/include/asm-arm/arch-msm/msm_smd.h
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_SMD_H
+#define __ASM_ARCH_MSM_SMD_H
+
+typedef struct smd_channel smd_channel_t;
+
+extern int (*msm_check_for_modem_crash)(void);
+
+/* warning: notify() may be called before open returns */
+int smd_open(const char *name, smd_channel_t **ch, void *priv,
+	     void (*notify)(void *priv, unsigned event));
+
+#define SMD_EVENT_DATA 1
+#define SMD_EVENT_OPEN 2
+#define SMD_EVENT_CLOSE 3
+
+int smd_close(smd_channel_t *ch);
+
+/* passing a null pointer for data reads and discards */
+int smd_read(smd_channel_t *ch, void *data, int len);
+
+/* Write to stream channels may do a partial write and return
+** the length actually written.
+** Write to packet channels will never do a partial write --
+** it will return the requested length written or an error.
+*/
+int smd_write(smd_channel_t *ch, const void *data, int len);
+int smd_write_atomic(smd_channel_t *ch, const void *data, int len);
+
+int smd_write_avail(smd_channel_t *ch);
+int smd_read_avail(smd_channel_t *ch);
+
+/* Returns the total size of the current packet being read.
+** Returns 0 if no packets available or a stream channel.
+*/
+int smd_cur_packet_size(smd_channel_t *ch);
+
+/* used for tty unthrottling and the like -- causes the notify()
+** callback to be called from the same lock context as is used
+** when it is called from channel updates
+*/
+void smd_kick(smd_channel_t *ch);
+
+
+#if 0
+/* these are interruptable waits which will block you until the specified
+** number of bytes are readable or writable.
+*/
+int smd_wait_until_readable(smd_channel_t *ch, int bytes);
+int smd_wait_until_writable(smd_channel_t *ch, int bytes);
+#endif
+
+typedef enum {
+	SMD_PORT_DS = 0,
+	SMD_PORT_DIAG,
+	SMD_PORT_RPC_CALL,
+	SMD_PORT_RPC_REPLY,
+	SMD_PORT_BT,
+	SMD_PORT_CONTROL,
+	SMD_PORT_MEMCPY_SPARE1,
+	SMD_PORT_DATA1,
+	SMD_PORT_DATA2,
+	SMD_PORT_DATA3,
+	SMD_PORT_DATA4,
+	SMD_PORT_DATA5,
+	SMD_PORT_DATA6,
+	SMD_PORT_DATA7,
+	SMD_PORT_DATA8,
+	SMD_PORT_DATA9,
+	SMD_PORT_DATA10,
+	SMD_PORT_DATA11,
+	SMD_PORT_DATA12,
+	SMD_PORT_DATA13,
+	SMD_PORT_DATA14,
+	SMD_PORT_DATA15,
+	SMD_PORT_DATA16,
+	SMD_PORT_DATA17,
+	SMD_PORT_DATA18,
+	SMD_PORT_DATA19,
+	SMD_PORT_DATA20,
+	SMD_PORT_GPS_NMEA,
+	SMD_PORT_BRIDGE_1,
+	SMD_PORT_BRIDGE_2,
+	SMD_PORT_BRIDGE_3,
+	SMD_PORT_BRIDGE_4,
+	SMD_PORT_BRIDGE_5,
+	SMD_PORT_LOOPBACK,
+	SMD_PORT_CS_APPS_MODEM,
+	SMD_PORT_CS_APPS_DSP,
+	SMD_PORT_CS_MODEM_DSP,
+	SMD_NUM_PORTS,
+} smd_port_id_type;
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/sirc.h b/arch/arm/mach-msm/include/mach/sirc.h
new file mode 100644
index 000000000000..7281337ee28d
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/sirc.h
@@ -0,0 +1,115 @@
+/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_SIRC_H
+#define __ASM_ARCH_MSM_SIRC_H
+
+struct sirc_regs_t {
+	void    *int_enable;
+	void    *int_enable_clear;
+	void    *int_enable_set;
+	void    *int_type;
+	void    *int_polarity;
+	void    *int_clear;
+};
+
+struct sirc_cascade_regs {
+	void    *int_status;
+	unsigned int    cascade_irq;
+};
+
+void msm_init_sirc(void);
+void msm_sirc_enter_sleep(void);
+void msm_sirc_exit_sleep(void);
+
+#if defined(CONFIG_ARCH_MSM_SCORPION)
+
+#include <mach/msm_iomap.h>
+
+/*
+ * Secondary interrupt controller interrupts
+ */
+
+#define FIRST_SIRC_IRQ (NR_MSM_IRQS + NR_GPIO_IRQS)
+
+#define INT_UART1                     (FIRST_SIRC_IRQ + 0)
+#define INT_UART2                     (FIRST_SIRC_IRQ + 1)
+#define INT_UART3                     (FIRST_SIRC_IRQ + 2)
+#define INT_UART1_RX                  (FIRST_SIRC_IRQ + 3)
+#define INT_UART2_RX                  (FIRST_SIRC_IRQ + 4)
+#define INT_UART3_RX                  (FIRST_SIRC_IRQ + 5)
+#define INT_SPI_INPUT                 (FIRST_SIRC_IRQ + 6)
+#define INT_SPI_OUTPUT                (FIRST_SIRC_IRQ + 7)
+#define INT_SPI_ERROR                 (FIRST_SIRC_IRQ + 8)
+#define INT_GPIO_GROUP1               (FIRST_SIRC_IRQ + 9)
+#define INT_GPIO_GROUP2               (FIRST_SIRC_IRQ + 10)
+#define INT_GPIO_GROUP1_SECURE        (FIRST_SIRC_IRQ + 11)
+#define INT_GPIO_GROUP2_SECURE        (FIRST_SIRC_IRQ + 12)
+#define INT_AVS_SVIC                  (FIRST_SIRC_IRQ + 13)
+#define INT_AVS_REQ_UP                (FIRST_SIRC_IRQ + 14)
+#define INT_AVS_REQ_DOWN              (FIRST_SIRC_IRQ + 15)
+#define INT_PBUS_ERR                  (FIRST_SIRC_IRQ + 16)
+#define INT_AXI_ERR                   (FIRST_SIRC_IRQ + 17)
+#define INT_SMI_ERR                   (FIRST_SIRC_IRQ + 18)
+#define INT_EBI1_ERR                  (FIRST_SIRC_IRQ + 19)
+#define INT_IMEM_ERR                  (FIRST_SIRC_IRQ + 20)
+#define INT_TEMP_SENSOR               (FIRST_SIRC_IRQ + 21)
+#define INT_TV_ENC                    (FIRST_SIRC_IRQ + 22)
+#define INT_GRP2D                     (FIRST_SIRC_IRQ + 23)
+#define INT_GSBI_QUP                  (FIRST_SIRC_IRQ + 24)
+#define INT_SC_ACG                    (FIRST_SIRC_IRQ + 25)
+#define INT_WDT0                      (FIRST_SIRC_IRQ + 26)
+#define INT_WDT1                      (FIRST_SIRC_IRQ + 27)
+
+#if defined(CONFIG_MSM_SOC_REV_A)
+#define NR_SIRC_IRQS                  28
+#define SIRC_MASK                     0x0FFFFFFF
+#else
+#define NR_SIRC_IRQS                  23
+#define SIRC_MASK                     0x007FFFFF
+#endif
+
+#define LAST_SIRC_IRQ                 (FIRST_SIRC_IRQ + NR_SIRC_IRQS - 1)
+
+#define SPSS_SIRC_INT_SELECT          (MSM_SIRC_BASE + 0x00)
+#define SPSS_SIRC_INT_ENABLE          (MSM_SIRC_BASE + 0x04)
+#define SPSS_SIRC_INT_ENABLE_CLEAR    (MSM_SIRC_BASE + 0x08)
+#define SPSS_SIRC_INT_ENABLE_SET      (MSM_SIRC_BASE + 0x0C)
+#define SPSS_SIRC_INT_TYPE            (MSM_SIRC_BASE + 0x10)
+#define SPSS_SIRC_INT_POLARITY        (MSM_SIRC_BASE + 0x14)
+#define SPSS_SIRC_SECURITY            (MSM_SIRC_BASE + 0x18)
+#define SPSS_SIRC_IRQ_STATUS          (MSM_SIRC_BASE + 0x1C)
+#define SPSS_SIRC_IRQ1_STATUS         (MSM_SIRC_BASE + 0x20)
+#define SPSS_SIRC_RAW_STATUS          (MSM_SIRC_BASE + 0x24)
+#define SPSS_SIRC_INT_CLEAR           (MSM_SIRC_BASE + 0x28)
+#define SPSS_SIRC_SOFT_INT            (MSM_SIRC_BASE + 0x2C)
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/system.h b/arch/arm/mach-msm/include/mach/system.h
index 574ccc493daf..d2e83f42ba16 100644
--- a/arch/arm/mach-msm/include/mach/system.h
+++ b/arch/arm/mach-msm/include/mach/system.h
@@ -21,3 +21,8 @@ static inline void arch_reset(char mode, const char *cmd)
 {
 	for (;;) ;  /* depends on IPC w/ other core */
 }
+
+/* low level hardware reset hook -- for example, hitting the
+ * PSHOLD line on the PMIC to hard reset the system
+ */
+extern void (*msm_hw_reset_hook)(void);
diff --git a/arch/arm/mach-msm/include/mach/vreg.h b/arch/arm/mach-msm/include/mach/vreg.h
index 9f9e25cb718e..6626e7864e28 100644
--- a/arch/arm/mach-msm/include/mach/vreg.h
+++ b/arch/arm/mach-msm/include/mach/vreg.h
@@ -23,7 +23,7 @@ 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_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 05f96b780aa6..1c05060b5f3b 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -1,8 +1,9 @@
 /* arch/arm/mach-msm/io.c
  *
- * MSM7K io support
+ * MSM7K, QSD io support
  *
  * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -34,6 +35,8 @@
 		.type = MT_DEVICE_NONSHARED, \
 	 }
 
+#if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_MSM7X27) \
+	|| defined(CONFIG_ARCH_MSM7X25)
 static struct map_desc msm_io_desc[] __initdata = {
 	MSM_DEVICE(VIC),
 	MSM_DEVICE(CSR),
@@ -45,9 +48,12 @@ static struct map_desc msm_io_desc[] __initdata = {
 #ifdef CONFIG_MSM_DEBUG_UART
 	MSM_DEVICE(DEBUG_UART),
 #endif
+#ifdef CONFIG_ARCH_MSM7X30
+	MSM_DEVICE(GCC),
+#endif
 	{
 		.virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
-		.pfn =      __phys_to_pfn(MSM_SHARED_RAM_PHYS),
+		.pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS),
 		.length =   MSM_SHARED_RAM_SIZE,
 		.type =     MT_DEVICE,
 	},
@@ -60,9 +66,72 @@ void __init msm_map_common_io(void)
 	 * pages are peripheral interface or not.
 	 */
 	asm("mcr p15, 0, %0, c15, c2, 4" : : "r" (0));
-
 	iotable_init(msm_io_desc, ARRAY_SIZE(msm_io_desc));
 }
+#endif
+
+#ifdef CONFIG_ARCH_QSD8X50
+static struct map_desc qsd8x50_io_desc[] __initdata = {
+	MSM_DEVICE(VIC),
+	MSM_DEVICE(CSR),
+	MSM_DEVICE(TMR),
+	MSM_DEVICE(DMOV),
+	MSM_DEVICE(GPIO1),
+	MSM_DEVICE(GPIO2),
+	MSM_DEVICE(CLK_CTL),
+	MSM_DEVICE(SIRC),
+	MSM_DEVICE(SCPLL),
+	MSM_DEVICE(AD5),
+	MSM_DEVICE(MDC),
+#ifdef CONFIG_MSM_DEBUG_UART
+	MSM_DEVICE(DEBUG_UART),
+#endif
+	{
+		.virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
+		.pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS),
+		.length =   MSM_SHARED_RAM_SIZE,
+		.type =     MT_DEVICE,
+	},
+};
+
+void __init msm_map_qsd8x50_io(void)
+{
+	iotable_init(qsd8x50_io_desc, ARRAY_SIZE(qsd8x50_io_desc));
+}
+#endif /* CONFIG_ARCH_QSD8X50 */
+
+#ifdef CONFIG_ARCH_MSM7X30
+static struct map_desc msm7x30_io_desc[] __initdata = {
+	MSM_DEVICE(VIC),
+	MSM_DEVICE(CSR),
+	MSM_DEVICE(TMR),
+	MSM_DEVICE(DMOV),
+	MSM_DEVICE(GPIO1),
+	MSM_DEVICE(GPIO2),
+	MSM_DEVICE(CLK_CTL),
+	MSM_DEVICE(CLK_CTL_SH2),
+	MSM_DEVICE(AD5),
+	MSM_DEVICE(MDC),
+	MSM_DEVICE(ACC),
+	MSM_DEVICE(SAW),
+	MSM_DEVICE(GCC),
+	MSM_DEVICE(TCSR),
+#ifdef CONFIG_MSM_DEBUG_UART
+	MSM_DEVICE(DEBUG_UART),
+#endif
+	{
+		.virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
+		.pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS),
+		.length =   MSM_SHARED_RAM_SIZE,
+		.type =     MT_DEVICE,
+	},
+};
+
+void __init msm_map_msm7x30_io(void)
+{
+	iotable_init(msm7x30_io_desc, ARRAY_SIZE(msm7x30_io_desc));
+}
+#endif /* CONFIG_ARCH_MSM7X30 */
 
 void __iomem *
 __msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
diff --git a/arch/arm/mach-msm/irq-vic.c b/arch/arm/mach-msm/irq-vic.c
new file mode 100644
index 000000000000..99f2c3473033
--- /dev/null
+++ b/arch/arm/mach-msm/irq-vic.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/timer.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+
+#include <mach/hardware.h>
+
+#include <mach/msm_iomap.h>
+
+#include "smd_private.h"
+
+enum {
+	IRQ_DEBUG_SLEEP_INT_TRIGGER = 1U << 0,
+	IRQ_DEBUG_SLEEP_INT = 1U << 1,
+	IRQ_DEBUG_SLEEP_ABORT = 1U << 2,
+	IRQ_DEBUG_SLEEP = 1U << 3,
+	IRQ_DEBUG_SLEEP_REQUEST = 1U << 4,
+};
+static int msm_irq_debug_mask;
+module_param_named(debug_mask, msm_irq_debug_mask, int,
+		   S_IRUGO | S_IWUSR | S_IWGRP);
+
+#define VIC_REG(off) (MSM_VIC_BASE + (off))
+#define VIC_INT_TO_REG_ADDR(base, irq) (base + (irq / 32) * 4)
+#define VIC_INT_TO_REG_INDEX(irq) ((irq >> 5) & 3)
+
+#define VIC_INT_SELECT0     VIC_REG(0x0000)  /* 1: FIQ, 0: IRQ */
+#define VIC_INT_SELECT1     VIC_REG(0x0004)  /* 1: FIQ, 0: IRQ */
+#define VIC_INT_SELECT2     VIC_REG(0x0008)  /* 1: FIQ, 0: IRQ */
+#define VIC_INT_SELECT3     VIC_REG(0x000C)  /* 1: FIQ, 0: IRQ */
+#define VIC_INT_EN0         VIC_REG(0x0010)
+#define VIC_INT_EN1         VIC_REG(0x0014)
+#define VIC_INT_EN2         VIC_REG(0x0018)
+#define VIC_INT_EN3         VIC_REG(0x001C)
+#define VIC_INT_ENCLEAR0    VIC_REG(0x0020)
+#define VIC_INT_ENCLEAR1    VIC_REG(0x0024)
+#define VIC_INT_ENCLEAR2    VIC_REG(0x0028)
+#define VIC_INT_ENCLEAR3    VIC_REG(0x002C)
+#define VIC_INT_ENSET0      VIC_REG(0x0030)
+#define VIC_INT_ENSET1      VIC_REG(0x0034)
+#define VIC_INT_ENSET2      VIC_REG(0x0038)
+#define VIC_INT_ENSET3      VIC_REG(0x003C)
+#define VIC_INT_TYPE0       VIC_REG(0x0040)  /* 1: EDGE, 0: LEVEL  */
+#define VIC_INT_TYPE1       VIC_REG(0x0044)  /* 1: EDGE, 0: LEVEL  */
+#define VIC_INT_TYPE2       VIC_REG(0x0048)  /* 1: EDGE, 0: LEVEL  */
+#define VIC_INT_TYPE3       VIC_REG(0x004C)  /* 1: EDGE, 0: LEVEL  */
+#define VIC_INT_POLARITY0   VIC_REG(0x0050)  /* 1: NEG, 0: POS */
+#define VIC_INT_POLARITY1   VIC_REG(0x0054)  /* 1: NEG, 0: POS */
+#define VIC_INT_POLARITY2   VIC_REG(0x0058)  /* 1: NEG, 0: POS */
+#define VIC_INT_POLARITY3   VIC_REG(0x005C)  /* 1: NEG, 0: POS */
+#define VIC_NO_PEND_VAL     VIC_REG(0x0060)
+
+#if defined(CONFIG_ARCH_MSM_SCORPION)
+#define VIC_NO_PEND_VAL_FIQ VIC_REG(0x0064)
+#define VIC_INT_MASTEREN    VIC_REG(0x0068)  /* 1: IRQ, 2: FIQ     */
+#define VIC_CONFIG          VIC_REG(0x006C)  /* 1: USE SC VIC */
+#else
+#define VIC_INT_MASTEREN    VIC_REG(0x0064)  /* 1: IRQ, 2: FIQ     */
+#define VIC_PROTECTION      VIC_REG(0x006C)  /* 1: ENABLE          */
+#define VIC_CONFIG          VIC_REG(0x0068)  /* 1: USE ARM1136 VIC */
+#endif
+
+#define VIC_IRQ_STATUS0     VIC_REG(0x0080)
+#define VIC_IRQ_STATUS1     VIC_REG(0x0084)
+#define VIC_IRQ_STATUS2     VIC_REG(0x0088)
+#define VIC_IRQ_STATUS3     VIC_REG(0x008C)
+#define VIC_FIQ_STATUS0     VIC_REG(0x0090)
+#define VIC_FIQ_STATUS1     VIC_REG(0x0094)
+#define VIC_FIQ_STATUS2     VIC_REG(0x0098)
+#define VIC_FIQ_STATUS3     VIC_REG(0x009C)
+#define VIC_RAW_STATUS0     VIC_REG(0x00A0)
+#define VIC_RAW_STATUS1     VIC_REG(0x00A4)
+#define VIC_RAW_STATUS2     VIC_REG(0x00A8)
+#define VIC_RAW_STATUS3     VIC_REG(0x00AC)
+#define VIC_INT_CLEAR0      VIC_REG(0x00B0)
+#define VIC_INT_CLEAR1      VIC_REG(0x00B4)
+#define VIC_INT_CLEAR2      VIC_REG(0x00B8)
+#define VIC_INT_CLEAR3      VIC_REG(0x00BC)
+#define VIC_SOFTINT0        VIC_REG(0x00C0)
+#define VIC_SOFTINT1        VIC_REG(0x00C4)
+#define VIC_SOFTINT2        VIC_REG(0x00C8)
+#define VIC_SOFTINT3        VIC_REG(0x00CC)
+#define VIC_IRQ_VEC_RD      VIC_REG(0x00D0)  /* pending int # */
+#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4)  /* pending vector addr */
+#define VIC_IRQ_VEC_WR      VIC_REG(0x00D8)
+
+#if defined(CONFIG_ARCH_MSM_SCORPION)
+#define VIC_FIQ_VEC_RD      VIC_REG(0x00DC)
+#define VIC_FIQ_VEC_PEND_RD VIC_REG(0x00E0)
+#define VIC_FIQ_VEC_WR      VIC_REG(0x00E4)
+#define VIC_IRQ_IN_SERVICE  VIC_REG(0x00E8)
+#define VIC_IRQ_IN_STACK    VIC_REG(0x00EC)
+#define VIC_FIQ_IN_SERVICE  VIC_REG(0x00F0)
+#define VIC_FIQ_IN_STACK    VIC_REG(0x00F4)
+#define VIC_TEST_BUS_SEL    VIC_REG(0x00F8)
+#define VIC_IRQ_CTRL_CONFIG VIC_REG(0x00FC)
+#else
+#define VIC_IRQ_IN_SERVICE  VIC_REG(0x00E0)
+#define VIC_IRQ_IN_STACK    VIC_REG(0x00E4)
+#define VIC_TEST_BUS_SEL    VIC_REG(0x00E8)
+#endif
+
+#define VIC_VECTPRIORITY(n) VIC_REG(0x0200+((n) * 4))
+#define VIC_VECTADDR(n)     VIC_REG(0x0400+((n) * 4))
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#define VIC_NUM_REGS	    4
+#else
+#define VIC_NUM_REGS	    2
+#endif
+
+#if VIC_NUM_REGS == 2
+#define DPRINT_REGS(base_reg, format, ...)	      			\
+	printk(KERN_INFO format " %x %x\n", ##__VA_ARGS__,		\
+			readl(base_reg ## 0), readl(base_reg ## 1))
+#define DPRINT_ARRAY(array, format, ...)				\
+	printk(KERN_INFO format " %x %x\n", ##__VA_ARGS__,		\
+			array[0], array[1])
+#elif VIC_NUM_REGS == 4
+#define DPRINT_REGS(base_reg, format, ...) \
+	printk(KERN_INFO format " %x %x %x %x\n", ##__VA_ARGS__,	\
+			readl(base_reg ## 0), readl(base_reg ## 1),	\
+			readl(base_reg ## 2), readl(base_reg ## 3))
+#define DPRINT_ARRAY(array, format, ...)				\
+	printk(KERN_INFO format " %x %x %x %x\n", ##__VA_ARGS__,	\
+			array[0], array[1],				\
+			array[2], array[3])
+#else
+#error "VIC_NUM_REGS set to illegal value"
+#endif
+
+static uint32_t msm_irq_smsm_wake_enable[2];
+static struct {
+	uint32_t int_en[2];
+	uint32_t int_type;
+	uint32_t int_polarity;
+	uint32_t int_select;
+} msm_irq_shadow_reg[VIC_NUM_REGS];
+static uint32_t msm_irq_idle_disable[VIC_NUM_REGS];
+
+#define SMSM_FAKE_IRQ (0xff)
+static uint8_t msm_irq_to_smsm[NR_IRQS] = {
+	[INT_MDDI_EXT] = 1,
+	[INT_MDDI_PRI] = 2,
+	[INT_MDDI_CLIENT] = 3,
+	[INT_USB_OTG] = 4,
+
+	[INT_PWB_I2C] = 5,
+	[INT_SDC1_0] = 6,
+	[INT_SDC1_1] = 7,
+	[INT_SDC2_0] = 8,
+
+	[INT_SDC2_1] = 9,
+	[INT_ADSP_A9_A11] = 10,
+	[INT_UART1] = 11,
+	[INT_UART2] = 12,
+
+	[INT_UART3] = 13,
+	[INT_UART1_RX] = 14,
+	[INT_UART2_RX] = 15,
+	[INT_UART3_RX] = 16,
+
+	[INT_UART1DM_IRQ] = 17,
+	[INT_UART1DM_RX] = 18,
+	[INT_KEYSENSE] = 19,
+#if !defined(CONFIG_ARCH_MSM7X30)
+	[INT_AD_HSSD] = 20,
+#endif
+
+	[INT_NAND_WR_ER_DONE] = 21,
+	[INT_NAND_OP_DONE] = 22,
+	[INT_TCHSCRN1] = 23,
+	[INT_TCHSCRN2] = 24,
+
+	[INT_TCHSCRN_SSBI] = 25,
+	[INT_USB_HS] = 26,
+	[INT_UART2DM_RX] = 27,
+	[INT_UART2DM_IRQ] = 28,
+
+	[INT_SDC4_1] = 29,
+	[INT_SDC4_0] = 30,
+	[INT_SDC3_1] = 31,
+	[INT_SDC3_0] = 32,
+
+	/* fake wakeup interrupts */
+	[INT_GPIO_GROUP1] = SMSM_FAKE_IRQ,
+	[INT_GPIO_GROUP2] = SMSM_FAKE_IRQ,
+	[INT_A9_M2A_0] = SMSM_FAKE_IRQ,
+	[INT_A9_M2A_1] = SMSM_FAKE_IRQ,
+	[INT_A9_M2A_5] = SMSM_FAKE_IRQ,
+	[INT_GP_TIMER_EXP] = SMSM_FAKE_IRQ,
+	[INT_DEBUG_TIMER_EXP] = SMSM_FAKE_IRQ,
+	[INT_ADSP_A11] = SMSM_FAKE_IRQ,
+#ifdef CONFIG_ARCH_QSD8X50
+	[INT_SIRC_0] = SMSM_FAKE_IRQ,
+	[INT_SIRC_1] = SMSM_FAKE_IRQ,
+#endif
+};
+
+static inline void msm_irq_write_all_regs(void __iomem *base, unsigned int val)
+{
+	int i;
+
+	for (i = 0; i < VIC_NUM_REGS; i++)
+		writel(val, base + (i * 4));
+}
+
+static void msm_irq_ack(unsigned int irq)
+{
+	void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_CLEAR0, irq);
+	irq = 1 << (irq & 31);
+	writel(irq, reg);
+}
+
+static void msm_irq_mask(unsigned int irq)
+{
+	void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_ENCLEAR0, irq);
+	unsigned index = VIC_INT_TO_REG_INDEX(irq);
+	uint32_t mask = 1UL << (irq & 31);
+	int smsm_irq = msm_irq_to_smsm[irq];
+
+	msm_irq_shadow_reg[index].int_en[0] &= ~mask;
+	writel(mask, reg);
+	if (smsm_irq == 0)
+		msm_irq_idle_disable[index] &= ~mask;
+	else {
+		mask = 1UL << (smsm_irq - 1);
+		msm_irq_smsm_wake_enable[0] &= ~mask;
+	}
+}
+
+static void msm_irq_unmask(unsigned int irq)
+{
+	void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_ENSET0, irq);
+	unsigned index = VIC_INT_TO_REG_INDEX(irq);
+	uint32_t mask = 1UL << (irq & 31);
+	int smsm_irq = msm_irq_to_smsm[irq];
+
+	msm_irq_shadow_reg[index].int_en[0] |= mask;
+	writel(mask, reg);
+
+	if (smsm_irq == 0)
+		msm_irq_idle_disable[index] |= mask;
+	else {
+		mask = 1UL << (smsm_irq - 1);
+		msm_irq_smsm_wake_enable[0] |= mask;
+	}
+}
+
+static int msm_irq_set_wake(unsigned int irq, unsigned int on)
+{
+	unsigned index = VIC_INT_TO_REG_INDEX(irq);
+	uint32_t mask = 1UL << (irq & 31);
+	int smsm_irq = msm_irq_to_smsm[irq];
+
+	if (smsm_irq == 0) {
+		printk(KERN_ERR "msm_irq_set_wake: bad wakeup irq %d\n", irq);
+		return -EINVAL;
+	}
+	if (on)
+		msm_irq_shadow_reg[index].int_en[1] |= mask;
+	else
+		msm_irq_shadow_reg[index].int_en[1] &= ~mask;
+
+	if (smsm_irq == SMSM_FAKE_IRQ)
+		return 0;
+
+	mask = 1UL << (smsm_irq - 1);
+	if (on)
+		msm_irq_smsm_wake_enable[1] |= mask;
+	else
+		msm_irq_smsm_wake_enable[1] &= ~mask;
+	return 0;
+}
+
+static int msm_irq_set_type(unsigned int irq, unsigned int flow_type)
+{
+	void __iomem *treg = VIC_INT_TO_REG_ADDR(VIC_INT_TYPE0, irq);
+	void __iomem *preg = VIC_INT_TO_REG_ADDR(VIC_INT_POLARITY0, irq);
+	unsigned index = VIC_INT_TO_REG_INDEX(irq);
+	int b = 1 << (irq & 31);
+	uint32_t polarity;
+	uint32_t type;
+
+	polarity = msm_irq_shadow_reg[index].int_polarity;
+	if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
+		polarity |= b;
+	if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH))
+		polarity &= ~b;
+	writel(polarity, preg);
+	msm_irq_shadow_reg[index].int_polarity = polarity;
+
+	type = msm_irq_shadow_reg[index].int_type;
+	if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+		type |= b;
+		irq_desc[irq].handle_irq = handle_edge_irq;
+	}
+	if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) {
+		type &= ~b;
+		irq_desc[irq].handle_irq = handle_level_irq;
+	}
+	writel(type, treg);
+	msm_irq_shadow_reg[index].int_type = type;
+	return 0;
+}
+
+static struct irq_chip msm_irq_chip = {
+	.name      = "msm",
+	.disable   = msm_irq_mask,
+	.ack       = msm_irq_ack,
+	.mask      = msm_irq_mask,
+	.unmask    = msm_irq_unmask,
+	.set_wake  = msm_irq_set_wake,
+	.set_type  = msm_irq_set_type,
+};
+
+void __init msm_init_irq(void)
+{
+	unsigned n;
+
+	/* select level interrupts */
+	msm_irq_write_all_regs(VIC_INT_TYPE0, 0);
+
+	/* select highlevel interrupts */
+	msm_irq_write_all_regs(VIC_INT_POLARITY0, 0);
+
+	/* select IRQ for all INTs */
+	msm_irq_write_all_regs(VIC_INT_SELECT0, 0);
+
+	/* disable all INTs */
+	msm_irq_write_all_regs(VIC_INT_EN0, 0);
+
+	/* don't use vic */
+	writel(0, VIC_CONFIG);
+
+	/* enable interrupt controller */
+	writel(3, VIC_INT_MASTEREN);
+
+	for (n = 0; n < NR_MSM_IRQS; n++) {
+		set_irq_chip(n, &msm_irq_chip);
+		set_irq_handler(n, handle_level_irq);
+		set_irq_flags(n, IRQF_VALID);
+	}
+}
diff --git a/arch/arm/mach-msm/irq.c b/arch/arm/mach-msm/irq.c
index 69ca0dd79bdf..6c8d5f8caef3 100644
--- a/arch/arm/mach-msm/irq.c
+++ b/arch/arm/mach-msm/irq.c
@@ -101,11 +101,11 @@ static int msm_irq_set_type(unsigned int irq, unsigned int flow_type)
 
 	if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
 		writel(readl(treg) | b, treg);
-		set_irq_handler(irq, handle_edge_irq);
+		irq_desc[irq].handle_irq = handle_edge_irq;
 	}
 	if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) {
 		writel(readl(treg) & (~b), treg);
-		set_irq_handler(irq, handle_level_irq);
+		irq_desc[irq].handle_irq = handle_level_irq;
 	}
 	return 0;
 }
diff --git a/arch/arm/mach-msm/last_radio_log.c b/arch/arm/mach-msm/last_radio_log.c
new file mode 100644
index 000000000000..b64ba5a98686
--- /dev/null
+++ b/arch/arm/mach-msm/last_radio_log.c
@@ -0,0 +1,82 @@
+/* arch/arm/mach-msm/last_radio_log.c
+ *
+ * Extract the log from a modem crash though SMEM
+ *
+ * Copyright (C) 2007 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/module.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/uaccess.h>
+
+#include "smd_private.h"
+
+static void *radio_log_base;
+static size_t radio_log_size;
+
+extern void *smem_item(unsigned id, unsigned *size);
+
+static ssize_t last_radio_log_read(struct file *file, char __user *buf,
+			size_t len, loff_t *offset)
+{
+	loff_t pos = *offset;
+	ssize_t count;
+
+	if (pos >= radio_log_size)
+		return 0;
+
+	count = min(len, (size_t)(radio_log_size - pos));
+	if (copy_to_user(buf, radio_log_base + pos, count)) {
+		pr_err("%s: copy to user failed\n", __func__);
+		return -EFAULT;
+	}
+
+	*offset += count;
+	return count;
+}
+
+static struct file_operations last_radio_log_fops = {
+	.read = last_radio_log_read
+};
+
+void msm_init_last_radio_log(struct module *owner)
+{
+	struct proc_dir_entry *entry;
+
+	if (last_radio_log_fops.owner) {
+		pr_err("%s: already claimed\n", __func__);
+		return;
+	}
+
+	radio_log_base = smem_item(SMEM_CLKREGIM_BSP, &radio_log_size);
+	if (!radio_log_base) {
+		pr_err("%s: could not retrieve SMEM_CLKREGIM_BSP\n", __func__);
+		return;
+	}
+
+	entry = create_proc_entry("last_radio_log", S_IFREG | S_IRUGO, NULL);
+	if (!entry) {
+		pr_err("%s: could not create proc entry for radio log\n",
+				__func__);
+		return;
+	}
+
+	pr_err("%s: last radio log is %d bytes long\n", __func__,
+		radio_log_size);
+	last_radio_log_fops.owner = owner;
+	entry->proc_fops = &last_radio_log_fops;
+	entry->size = radio_log_size;
+}
+EXPORT_SYMBOL(msm_init_last_radio_log);
diff --git a/arch/arm/mach-msm/proc_comm.c b/arch/arm/mach-msm/proc_comm.c
index 915ee704ed3c..67e701c7f183 100644
--- a/arch/arm/mach-msm/proc_comm.c
+++ b/arch/arm/mach-msm/proc_comm.c
@@ -23,11 +23,18 @@
 
 #include "proc_comm.h"
 
-#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4)
+static inline void msm_a2m_int(uint32_t irq)
+{
+#if defined(CONFIG_ARCH_MSM7X30)
+	writel(1 << irq, MSM_GCC_BASE + 0x8);
+#else
+	writel(1, MSM_CSR_BASE + 0x400 + (irq * 4));
+#endif
+}
 
 static inline void notify_other_proc_comm(void)
 {
-	writel(1, MSM_A2M_INT(6));
+	msm_a2m_int(6);
 }
 
 #define APP_COMMAND 0x00
@@ -107,4 +114,17 @@ int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2)
 	return ret;
 }
 
-
+/*
+ * We need to wait for the ARM9 to at least partially boot
+ * up before we can continue. Since the ARM9 does resource
+ * allocation, if we dont' wait we could end up crashing or in
+ * and unknown state. This function should be called early to
+ * wait on the ARM9.
+ */
+void __init proc_comm_boot_wait(void)
+{
+	void __iomem *base = MSM_SHARED_RAM_BASE;
+ 
+	proc_comm_wait_for(base + MDM_STATUS, PCOM_READY);
+ 
+}
diff --git a/arch/arm/mach-msm/proc_comm.h b/arch/arm/mach-msm/proc_comm.h
index 834760f25692..12da4cacd4a8 100644
--- a/arch/arm/mach-msm/proc_comm.h
+++ b/arch/arm/mach-msm/proc_comm.h
@@ -16,6 +16,8 @@
 #ifndef _ARCH_ARM_MACH_MSM_PROC_COMM_H_
 #define _ARCH_ARM_MACH_MSM_PROC_COMM_H_
 
+#include <linux/init.h>
+
 enum {
 	PCOM_CMD_IDLE = 0x0,
 	PCOM_CMD_DONE,
@@ -62,19 +64,104 @@ enum {
 	PCOM_RESET_CHIP_IMM,
 	PCOM_PM_VID_EN,
 	PCOM_VREG_PULLDOWN,
+	PCOM_GET_MODEM_VERSION,
+	PCOM_CLK_REGIME_SEC_RESET,
+	PCOM_CLK_REGIME_SEC_RESET_ASSERT,
+	PCOM_CLK_REGIME_SEC_RESET_DEASSERT,
+	PCOM_CLK_REGIME_SEC_PLL_REQUEST_WRP,
+	PCOM_CLK_REGIME_SEC_ENABLE,
+	PCOM_CLK_REGIME_SEC_DISABLE,
+	PCOM_CLK_REGIME_SEC_IS_ON,
+	PCOM_CLK_REGIME_SEC_SEL_CLK_INV,
+	PCOM_CLK_REGIME_SEC_SEL_CLK_SRC,
+	PCOM_CLK_REGIME_SEC_SEL_CLK_DIV,
+	PCOM_CLK_REGIME_SEC_ICODEC_CLK_ENABLE,
+	PCOM_CLK_REGIME_SEC_ICODEC_CLK_DISABLE,
+	PCOM_CLK_REGIME_SEC_SEL_SPEED,
+	PCOM_CLK_REGIME_SEC_CONFIG_GP_CLK_WRP,
+	PCOM_CLK_REGIME_SEC_CONFIG_MDH_CLK_WRP,
+	PCOM_CLK_REGIME_SEC_USB_XTAL_ON,
+	PCOM_CLK_REGIME_SEC_USB_XTAL_OFF,
+	PCOM_CLK_REGIME_SEC_SET_QDSP_DME_MODE,
+	PCOM_CLK_REGIME_SEC_SWITCH_ADSP_CLK,
+	PCOM_CLK_REGIME_SEC_GET_MAX_ADSP_CLK_KHZ,
+	PCOM_CLK_REGIME_SEC_GET_I2C_CLK_KHZ,
+	PCOM_CLK_REGIME_SEC_MSM_GET_CLK_FREQ_KHZ,
+	PCOM_CLK_REGIME_SEC_SEL_VFE_SRC,
+	PCOM_CLK_REGIME_SEC_MSM_SEL_CAMCLK,
+	PCOM_CLK_REGIME_SEC_MSM_SEL_LCDCLK,
+	PCOM_CLK_REGIME_SEC_VFE_RAIL_OFF,
+	PCOM_CLK_REGIME_SEC_VFE_RAIL_ON,
+	PCOM_CLK_REGIME_SEC_GRP_RAIL_OFF,
+	PCOM_CLK_REGIME_SEC_GRP_RAIL_ON,
+	PCOM_CLK_REGIME_SEC_VDC_RAIL_OFF,
+	PCOM_CLK_REGIME_SEC_VDC_RAIL_ON,
+	PCOM_CLK_REGIME_SEC_LCD_CTRL,
+	PCOM_CLK_REGIME_SEC_REGISTER_FOR_CPU_RESOURCE,
+	PCOM_CLK_REGIME_SEC_DEREGISTER_FOR_CPU_RESOURCE,
+	PCOM_CLK_REGIME_SEC_RESOURCE_REQUEST_WRP,
+	PCOM_CLK_REGIME_MSM_SEC_SEL_CLK_OWNER,
+	PCOM_CLK_REGIME_SEC_DEVMAN_REQUEST_WRP,
+	PCOM_GPIO_CONFIG,
+	PCOM_GPIO_CONFIGURE_GROUP,
+	PCOM_GPIO_TLMM_SET_PORT,
+	PCOM_GPIO_TLMM_CONFIG_EX,
+	PCOM_SET_FTM_BOOT_COUNT,
+	PCOM_RESERVED0,
+	PCOM_RESERVED1,
+	PCOM_CUSTOMER_CMD1,
+	PCOM_CUSTOMER_CMD2,
+	PCOM_CUSTOMER_CMD3,
+	PCOM_CLK_REGIME_ENTER_APPSBL_CHG_MODE,
+	PCOM_CLK_REGIME_EXIT_APPSBL_CHG_MODE,
+	PCOM_CLK_REGIME_SEC_RAIL_DISABLE,
+	PCOM_CLK_REGIME_SEC_RAIL_ENABLE,
+	PCOM_CLK_REGIME_SEC_RAIL_CONTROL,
+	PCOM_SET_SW_WATCHDOG_STATE,
+	PCOM_PM_MPP_CONFIG_DIGITAL_INPUT,
+	PCOM_PM_MPP_CONFIG_I_SINK,
+	PCOM_RESERVED_101,
+	PCOM_MSM_HSUSB_PHY_RESET,
+	PCOM_GET_BATT_MV_LEVEL,
+	PCOM_CHG_USB_IS_PC_CONNECTED,
+	PCOM_CHG_USB_IS_CHARGER_CONNECTED,
+	PCOM_CHG_USB_IS_DISCONNECTED,
+	PCOM_CHG_USB_IS_AVAILABLE,
+	PCOM_CLK_REGIME_SEC_MSM_SEL_FREQ,
+	PCOM_CLK_REGIME_SEC_SET_PCLK_AXI_POLICY,
+	PCOM_CLKCTL_RPC_RESET_ASSERT,
+	PCOM_CLKCTL_RPC_RESET_DEASSERT,
+	PCOM_CLKCTL_RPC_RAIL_ON,
+	PCOM_CLKCTL_RPC_RAIL_OFF,
+	PCOM_CLKCTL_RPC_RAIL_ENABLE,
+	PCOM_CLKCTL_RPC_RAIL_DISABLE,
+	PCOM_CLKCTL_RPC_RAIL_CONTROL,
+	PCOM_CLKCTL_RPC_MIN_MSMC1,
 	PCOM_NUM_CMDS,
 };
 
 enum {
-	 PCOM_INVALID_STATUS = 0x0,
-	 PCOM_READY,
-	 PCOM_CMD_RUNNING,
-	 PCOM_CMD_SUCCESS,
-	 PCOM_CMD_FAIL,
+	PCOM_INVALID_STATUS = 0x0,
+	PCOM_READY,
+	PCOM_CMD_RUNNING,
+	PCOM_CMD_SUCCESS,
+	PCOM_CMD_FAIL,
+	PCOM_CMD_FAIL_FALSE_RETURNED,
+	PCOM_CMD_FAIL_CMD_OUT_OF_BOUNDS_SERVER,
+	PCOM_CMD_FAIL_CMD_OUT_OF_BOUNDS_CLIENT,
+	PCOM_CMD_FAIL_CMD_UNREGISTERED,
+	PCOM_CMD_FAIL_CMD_LOCKED,
+	PCOM_CMD_FAIL_SERVER_NOT_YET_READY,
+	PCOM_CMD_FAIL_BAD_DESTINATION,
+	PCOM_CMD_FAIL_SERVER_RESET,
+	PCOM_CMD_FAIL_SMSM_NOT_INIT,
+	PCOM_CMD_FAIL_PROC_COMM_BUSY,
+	PCOM_CMD_FAIL_PROC_COMM_NOT_INIT,
+
 };
 
 /* List of VREGs that support the Pull Down Resistor setting. */
-enum {
+enum vreg_pdown_id {
 	PM_VREG_PDOWN_MSMA_ID,
 	PM_VREG_PDOWN_MSMP_ID,
 	PM_VREG_PDOWN_MSME1_ID,	/* Not supported in Panoramix */
@@ -131,6 +218,11 @@ enum {
 	PM_VREG_PDOWN_XO_ID = PM_VREG_PDOWN_TCXO_ID
 };
 
+enum {
+	PCOM_CLKRGM_APPS_RESET_USB_PHY	= 34,
+	PCOM_CLKRGM_APPS_RESET_USBH	= 37,
+};
+
 /* gpio info for PCOM_RPC_GPIO_TLMM_CONFIG_EX */
 
 #define GPIO_ENABLE	0
@@ -161,5 +253,6 @@ enum {
 		(((drvstr) & 0xF) << 17))
 
 int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2);
+void __init proc_comm_boot_wait(void);
 
 #endif
diff --git a/arch/arm/mach-msm/sirc.c b/arch/arm/mach-msm/sirc.c
new file mode 100644
index 000000000000..b0794524ba6e
--- /dev/null
+++ b/arch/arm/mach-msm/sirc.c
@@ -0,0 +1,177 @@
+/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+
+static unsigned int int_enable;
+static unsigned int wake_enable;
+
+static struct sirc_regs_t sirc_regs = {
+	.int_enable       = SPSS_SIRC_INT_ENABLE,
+	.int_enable_clear = SPSS_SIRC_INT_ENABLE_CLEAR,
+	.int_enable_set   = SPSS_SIRC_INT_ENABLE_SET,
+	.int_type         = SPSS_SIRC_INT_TYPE,
+	.int_polarity     = SPSS_SIRC_INT_POLARITY,
+	.int_clear        = SPSS_SIRC_INT_CLEAR,
+};
+
+static struct sirc_cascade_regs sirc_reg_table[] = {
+	{
+		.int_status  = SPSS_SIRC_IRQ_STATUS,
+		.cascade_irq = INT_SIRC_0,
+	}
+};
+
+static unsigned int save_type;
+static unsigned int save_polarity;
+
+/* Mask off the given interrupt. Keep the int_enable mask in sync with
+   the enable reg, so it can be restored after power collapse. */
+static void sirc_irq_mask(unsigned int irq)
+{
+	unsigned int mask;
+
+
+	mask = 1 << (irq - FIRST_SIRC_IRQ);
+	writel(mask, sirc_regs.int_enable_clear);
+	int_enable &= ~mask;
+	return;
+}
+
+/* Unmask the given interrupt. Keep the int_enable mask in sync with
+   the enable reg, so it can be restored after power collapse. */
+static void sirc_irq_unmask(unsigned int irq)
+{
+	unsigned int mask;
+
+	mask = 1 << (irq - FIRST_SIRC_IRQ);
+	writel(mask, sirc_regs.int_enable_set);
+	int_enable |= mask;
+	return;
+}
+
+static void sirc_irq_ack(unsigned int irq)
+{
+	unsigned int mask;
+
+	mask = 1 << (irq - FIRST_SIRC_IRQ);
+	writel(mask, sirc_regs.int_clear);
+	return;
+}
+
+static int sirc_irq_set_wake(unsigned int irq, unsigned int on)
+{
+	unsigned int mask;
+
+	/* Used to set the interrupt enable mask during power collapse. */
+	mask = 1 << (irq - FIRST_SIRC_IRQ);
+	if (on)
+		wake_enable |= mask;
+	else
+		wake_enable &= ~mask;
+
+	return 0;
+}
+
+static int sirc_irq_set_type(unsigned int irq, unsigned int flow_type)
+{
+	unsigned int mask;
+	unsigned int val;
+
+	mask = 1 << (irq - FIRST_SIRC_IRQ);
+	val = readl(sirc_regs.int_polarity);
+
+	if (flow_type & (IRQF_TRIGGER_LOW | IRQF_TRIGGER_FALLING))
+		val |= mask;
+	else
+		val &= ~mask;
+
+	writel(val, sirc_regs.int_polarity);
+
+	val = readl(sirc_regs.int_type);
+	if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+		val |= mask;
+		irq_desc[irq].handle_irq = handle_edge_irq;
+	} else {
+		val &= ~mask;
+		irq_desc[irq].handle_irq = handle_level_irq;
+	}
+
+	writel(val, sirc_regs.int_type);
+
+	return 0;
+}
+
+/* Finds the pending interrupt on the passed cascade irq and redrives it */
+static void sirc_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	unsigned int reg = 0;
+	unsigned int sirq;
+	unsigned int status;
+
+	while ((reg < ARRAY_SIZE(sirc_reg_table)) &&
+		(sirc_reg_table[reg].cascade_irq != irq))
+		reg++;
+
+	status = readl(sirc_reg_table[reg].int_status);
+	status &= SIRC_MASK;
+	if (status == 0)
+		return;
+
+	for (sirq = 0;
+	     (sirq < NR_SIRC_IRQS) && ((status & (1U << sirq)) == 0);
+	     sirq++)
+		;
+	generic_handle_irq(sirq+FIRST_SIRC_IRQ);
+
+	desc->chip->ack(irq);
+}
+
+static struct irq_chip sirc_irq_chip = {
+	.name      = "sirc",
+	.ack       = sirc_irq_ack,
+	.mask      = sirc_irq_mask,
+	.unmask    = sirc_irq_unmask,
+	.set_wake  = sirc_irq_set_wake,
+	.set_type  = sirc_irq_set_type,
+};
+
+void __init msm_init_sirc(void)
+{
+	int i;
+
+	int_enable = 0;
+	wake_enable = 0;
+
+	for (i = FIRST_SIRC_IRQ; i < LAST_SIRC_IRQ; i++) {
+		set_irq_chip(i, &sirc_irq_chip);
+		set_irq_handler(i, handle_edge_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(sirc_reg_table); i++) {
+		set_irq_chained_handler(sirc_reg_table[i].cascade_irq,
+					sirc_irq_handler);
+		set_irq_wake(sirc_reg_table[i].cascade_irq, 1);
+	}
+	return;
+}
+
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
new file mode 100644
index 000000000000..cf11d414b425
--- /dev/null
+++ b/arch/arm/mach-msm/smd.c
@@ -0,0 +1,1046 @@
+/* arch/arm/mach-msm/smd.c
+ *
+ * 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/platform_device.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/wait.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+
+#include <mach/msm_smd.h>
+#include <mach/system.h>
+
+#include "smd_private.h"
+#include "proc_comm.h"
+
+#if defined(CONFIG_ARCH_QSD8X50)
+#define CONFIG_QDSP6 1
+#endif
+
+void (*msm_hw_reset_hook)(void);
+
+#define MODULE_NAME "msm_smd"
+
+enum {
+	MSM_SMD_DEBUG = 1U << 0,
+	MSM_SMSM_DEBUG = 1U << 0,
+};
+
+static int msm_smd_debug_mask;
+
+struct shared_info {
+	int ready;
+	unsigned state;
+};
+
+static unsigned dummy_state[SMSM_STATE_COUNT];
+
+static struct shared_info smd_info = {
+	.state = (unsigned) &dummy_state,
+};
+
+module_param_named(debug_mask, msm_smd_debug_mask,
+		   int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+static unsigned last_heap_free = 0xffffffff;
+
+static inline void notify_other_smsm(void)
+{
+	msm_a2m_int(5);
+#ifdef CONFIG_QDSP6
+	msm_a2m_int(8);
+#endif
+}
+
+static inline void notify_modem_smd(void)
+{
+	msm_a2m_int(0);
+}
+
+static inline void notify_dsp_smd(void)
+{
+	msm_a2m_int(8);
+}
+
+static void smd_diag(void)
+{
+	char *x;
+
+	x = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
+	if (x != 0) {
+		x[SZ_DIAG_ERR_MSG - 1] = 0;
+		pr_info("smem: DIAG '%s'\n", x);
+	}
+}
+
+/* call when SMSM_RESET flag is set in the A9's smsm_state */
+static void handle_modem_crash(void)
+{
+	pr_err("ARM9 has CRASHED\n");
+	smd_diag();
+
+	/* hard reboot if possible */
+	if (msm_hw_reset_hook)
+		msm_hw_reset_hook();
+
+	/* in this case the modem or watchdog should reboot us */
+	for (;;)
+		;
+}
+
+uint32_t raw_smsm_get_state(enum smsm_state_item item)
+{
+	return readl(smd_info.state + item * 4);
+}
+
+static int check_for_modem_crash(void)
+{
+	if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET) {
+		handle_modem_crash();
+		return -1;
+	}
+	return 0;
+}
+
+/* the spinlock is used to synchronize between the
+ * irq handler and code that mutates the channel
+ * list or fiddles with channel state
+ */
+DEFINE_SPINLOCK(smd_lock);
+DEFINE_SPINLOCK(smem_lock);
+
+/* the mutex is used during open() and close()
+ * operations to avoid races while creating or
+ * destroying smd_channel structures
+ */
+static DEFINE_MUTEX(smd_creation_mutex);
+
+static int smd_initialized;
+
+LIST_HEAD(smd_ch_closed_list);
+LIST_HEAD(smd_ch_list_modem);
+LIST_HEAD(smd_ch_list_dsp);
+
+static unsigned char smd_ch_allocated[64];
+static struct work_struct probe_work;
+
+/* how many bytes are available for reading */
+static int smd_stream_read_avail(struct smd_channel *ch)
+{
+	return (ch->recv->head - ch->recv->tail) & ch->fifo_mask;
+}
+
+/* how many bytes we are free to write */
+static int smd_stream_write_avail(struct smd_channel *ch)
+{
+	return ch->fifo_mask -
+		((ch->send->head - ch->send->tail) & ch->fifo_mask);
+}
+
+static int smd_packet_read_avail(struct smd_channel *ch)
+{
+	if (ch->current_packet) {
+		int n = smd_stream_read_avail(ch);
+		if (n > ch->current_packet)
+			n = ch->current_packet;
+		return n;
+	} else {
+		return 0;
+	}
+}
+
+static int smd_packet_write_avail(struct smd_channel *ch)
+{
+	int n = smd_stream_write_avail(ch);
+	return n > SMD_HEADER_SIZE ? n - SMD_HEADER_SIZE : 0;
+}
+
+static int ch_is_open(struct smd_channel *ch)
+{
+	return (ch->recv->state == SMD_SS_OPENED) &&
+		(ch->send->state == SMD_SS_OPENED);
+}
+
+/* provide a pointer and length to readable data in the fifo */
+static unsigned ch_read_buffer(struct smd_channel *ch, void **ptr)
+{
+	unsigned head = ch->recv->head;
+	unsigned tail = ch->recv->tail;
+	*ptr = (void *) (ch->recv_data + tail);
+
+	if (tail <= head)
+		return head - tail;
+	else
+		return ch->fifo_size - tail;
+}
+
+/* advance the fifo read pointer after data from ch_read_buffer is consumed */
+static void ch_read_done(struct smd_channel *ch, unsigned count)
+{
+	BUG_ON(count > smd_stream_read_avail(ch));
+	ch->recv->tail = (ch->recv->tail + count) & ch->fifo_mask;
+	ch->send->fTAIL = 1;
+}
+
+/* basic read interface to ch_read_{buffer,done} used
+ * by smd_*_read() and update_packet_state()
+ * will read-and-discard if the _data pointer is null
+ */
+static int ch_read(struct smd_channel *ch, void *_data, int len)
+{
+	void *ptr;
+	unsigned n;
+	unsigned char *data = _data;
+	int orig_len = len;
+
+	while (len > 0) {
+		n = ch_read_buffer(ch, &ptr);
+		if (n == 0)
+			break;
+
+		if (n > len)
+			n = len;
+		if (_data)
+			memcpy(data, ptr, n);
+
+		data += n;
+		len -= n;
+		ch_read_done(ch, n);
+	}
+
+	return orig_len - len;
+}
+
+static void update_stream_state(struct smd_channel *ch)
+{
+	/* streams have no special state requiring updating */
+}
+
+static void update_packet_state(struct smd_channel *ch)
+{
+	unsigned hdr[5];
+	int r;
+
+	/* can't do anything if we're in the middle of a packet */
+	if (ch->current_packet != 0)
+		return;
+
+	/* don't bother unless we can get the full header */
+	if (smd_stream_read_avail(ch) < SMD_HEADER_SIZE)
+		return;
+
+	r = ch_read(ch, hdr, SMD_HEADER_SIZE);
+	BUG_ON(r != SMD_HEADER_SIZE);
+
+	ch->current_packet = hdr[0];
+}
+
+/* provide a pointer and length to next free space in the fifo */
+static unsigned ch_write_buffer(struct smd_channel *ch, void **ptr)
+{
+	unsigned head = ch->send->head;
+	unsigned tail = ch->send->tail;
+	*ptr = (void *) (ch->send_data + head);
+
+	if (head < tail) {
+		return tail - head - 1;
+	} else {
+		if (tail == 0)
+			return ch->fifo_size - head - 1;
+		else
+			return ch->fifo_size - head;
+	}
+}
+
+/* advace the fifo write pointer after freespace
+ * from ch_write_buffer is filled
+ */
+static void ch_write_done(struct smd_channel *ch, unsigned count)
+{
+	BUG_ON(count > smd_stream_write_avail(ch));
+	ch->send->head = (ch->send->head + count) & ch->fifo_mask;
+	ch->send->fHEAD = 1;
+}
+
+static void ch_set_state(struct smd_channel *ch, unsigned n)
+{
+	if (n == SMD_SS_OPENED) {
+		ch->send->fDSR = 1;
+		ch->send->fCTS = 1;
+		ch->send->fCD = 1;
+	} else {
+		ch->send->fDSR = 0;
+		ch->send->fCTS = 0;
+		ch->send->fCD = 0;
+	}
+	ch->send->state = n;
+	ch->send->fSTATE = 1;
+	ch->notify_other_cpu();
+}
+
+static void do_smd_probe(void)
+{
+	struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+	if (shared->heap_info.free_offset != last_heap_free) {
+		last_heap_free = shared->heap_info.free_offset;
+		schedule_work(&probe_work);
+	}
+}
+
+static void smd_state_change(struct smd_channel *ch,
+			     unsigned last, unsigned next)
+{
+	ch->last_state = next;
+
+	pr_info("SMD: ch %d %d -> %d\n", ch->n, last, next);
+
+	switch (next) {
+	case SMD_SS_OPENING:
+		ch->recv->tail = 0;
+	case SMD_SS_OPENED:
+		if (ch->send->state != SMD_SS_OPENED)
+			ch_set_state(ch, SMD_SS_OPENED);
+		ch->notify(ch->priv, SMD_EVENT_OPEN);
+		break;
+	case SMD_SS_FLUSHING:
+	case SMD_SS_RESET:
+		/* we should force them to close? */
+	default:
+		ch->notify(ch->priv, SMD_EVENT_CLOSE);
+	}
+}
+
+static void handle_smd_irq(struct list_head *list, void (*notify)(void))
+{
+	unsigned long flags;
+	struct smd_channel *ch;
+	int do_notify = 0;
+	unsigned ch_flags;
+	unsigned tmp;
+
+	spin_lock_irqsave(&smd_lock, flags);
+	list_for_each_entry(ch, list, ch_list) {
+		ch_flags = 0;
+		if (ch_is_open(ch)) {
+			if (ch->recv->fHEAD) {
+				ch->recv->fHEAD = 0;
+				ch_flags |= 1;
+				do_notify |= 1;
+			}
+			if (ch->recv->fTAIL) {
+				ch->recv->fTAIL = 0;
+				ch_flags |= 2;
+				do_notify |= 1;
+			}
+			if (ch->recv->fSTATE) {
+				ch->recv->fSTATE = 0;
+				ch_flags |= 4;
+				do_notify |= 1;
+			}
+		}
+		tmp = ch->recv->state;
+		if (tmp != ch->last_state)
+			smd_state_change(ch, ch->last_state, tmp);
+		if (ch_flags) {
+			ch->update_state(ch);
+			ch->notify(ch->priv, SMD_EVENT_DATA);
+		}
+	}
+	if (do_notify)
+		notify();
+	spin_unlock_irqrestore(&smd_lock, flags);
+	do_smd_probe();
+}
+
+static irqreturn_t smd_modem_irq_handler(int irq, void *data)
+{
+	handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
+	return IRQ_HANDLED;
+}
+
+#if defined(CONFIG_QDSP6)
+static irqreturn_t smd_dsp_irq_handler(int irq, void *data)
+{
+	handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
+	return IRQ_HANDLED;
+}
+#endif
+
+static void smd_fake_irq_handler(unsigned long arg)
+{
+	handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
+	handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
+}
+
+static DECLARE_TASKLET(smd_fake_irq_tasklet, smd_fake_irq_handler, 0);
+
+static inline int smd_need_int(struct smd_channel *ch)
+{
+	if (ch_is_open(ch)) {
+		if (ch->recv->fHEAD || ch->recv->fTAIL || ch->recv->fSTATE)
+			return 1;
+		if (ch->recv->state != ch->last_state)
+			return 1;
+	}
+	return 0;
+}
+
+void smd_sleep_exit(void)
+{
+	unsigned long flags;
+	struct smd_channel *ch;
+	int need_int = 0;
+
+	spin_lock_irqsave(&smd_lock, flags);
+	list_for_each_entry(ch, &smd_ch_list_modem, ch_list) {
+		if (smd_need_int(ch)) {
+			need_int = 1;
+			break;
+		}
+	}
+	list_for_each_entry(ch, &smd_ch_list_dsp, ch_list) {
+		if (smd_need_int(ch)) {
+			need_int = 1;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&smd_lock, flags);
+	do_smd_probe();
+
+	if (need_int) {
+		if (msm_smd_debug_mask & MSM_SMD_DEBUG)
+			pr_info("smd_sleep_exit need interrupt\n");
+		tasklet_schedule(&smd_fake_irq_tasklet);
+	}
+}
+
+
+void smd_kick(smd_channel_t *ch)
+{
+	unsigned long flags;
+	unsigned tmp;
+
+	spin_lock_irqsave(&smd_lock, flags);
+	ch->update_state(ch);
+	tmp = ch->recv->state;
+	if (tmp != ch->last_state) {
+		ch->last_state = tmp;
+		if (tmp == SMD_SS_OPENED)
+			ch->notify(ch->priv, SMD_EVENT_OPEN);
+		else
+			ch->notify(ch->priv, SMD_EVENT_CLOSE);
+	}
+	ch->notify(ch->priv, SMD_EVENT_DATA);
+	ch->notify_other_cpu();
+	spin_unlock_irqrestore(&smd_lock, flags);
+}
+
+static int smd_is_packet(int chn, unsigned type)
+{
+	type &= SMD_KIND_MASK;
+	if (type == SMD_KIND_PACKET)
+		return 1;
+	if (type == SMD_KIND_STREAM)
+		return 0;
+
+	/* older AMSS reports SMD_KIND_UNKNOWN always */
+	if ((chn > 4) || (chn == 1))
+		return 1;
+	else
+		return 0;
+}
+
+static int smd_stream_write(smd_channel_t *ch, const void *_data, int len)
+{
+	void *ptr;
+	const unsigned char *buf = _data;
+	unsigned xfer;
+	int orig_len = len;
+
+	if (len < 0)
+		return -EINVAL;
+
+	while ((xfer = ch_write_buffer(ch, &ptr)) != 0) {
+		if (!ch_is_open(ch))
+			break;
+		if (xfer > len)
+			xfer = len;
+		memcpy(ptr, buf, xfer);
+		ch_write_done(ch, xfer);
+		len -= xfer;
+		buf += xfer;
+		if (len == 0)
+			break;
+	}
+
+	ch->notify_other_cpu();
+
+	return orig_len - len;
+}
+
+static int smd_packet_write(smd_channel_t *ch, const void *_data, int len)
+{
+	unsigned hdr[5];
+
+	if (len < 0)
+		return -EINVAL;
+
+	if (smd_stream_write_avail(ch) < (len + SMD_HEADER_SIZE))
+		return -ENOMEM;
+
+	hdr[0] = len;
+	hdr[1] = hdr[2] = hdr[3] = hdr[4] = 0;
+
+	smd_stream_write(ch, hdr, sizeof(hdr));
+	smd_stream_write(ch, _data, len);
+
+	return len;
+}
+
+static int smd_stream_read(smd_channel_t *ch, void *data, int len)
+{
+	int r;
+
+	if (len < 0)
+		return -EINVAL;
+
+	r = ch_read(ch, data, len);
+	if (r > 0)
+		ch->notify_other_cpu();
+
+	return r;
+}
+
+static int smd_packet_read(smd_channel_t *ch, void *data, int len)
+{
+	unsigned long flags;
+	int r;
+
+	if (len < 0)
+		return -EINVAL;
+
+	if (len > ch->current_packet)
+		len = ch->current_packet;
+
+	r = ch_read(ch, data, len);
+	if (r > 0)
+		ch->notify_other_cpu();
+
+	spin_lock_irqsave(&smd_lock, flags);
+	ch->current_packet -= r;
+	update_packet_state(ch);
+	spin_unlock_irqrestore(&smd_lock, flags);
+
+	return r;
+}
+
+static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type)
+{
+	struct smd_channel *ch;
+
+	ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL);
+	if (ch == 0) {
+		pr_err("smd_alloc_channel() out of memory\n");
+		return -1;
+	}
+	ch->n = cid;
+
+	if (_smd_alloc_channel(ch)) {
+		kfree(ch);
+		return -1;
+	}
+
+	ch->fifo_mask = ch->fifo_size - 1;
+	ch->type = type;
+
+	if ((type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM)
+		ch->notify_other_cpu = notify_modem_smd;
+	else
+		ch->notify_other_cpu = notify_dsp_smd;
+
+	if (smd_is_packet(cid, type)) {
+		ch->read = smd_packet_read;
+		ch->write = smd_packet_write;
+		ch->read_avail = smd_packet_read_avail;
+		ch->write_avail = smd_packet_write_avail;
+		ch->update_state = update_packet_state;
+	} else {
+		ch->read = smd_stream_read;
+		ch->write = smd_stream_write;
+		ch->read_avail = smd_stream_read_avail;
+		ch->write_avail = smd_stream_write_avail;
+		ch->update_state = update_stream_state;
+	}
+
+	if ((type & 0xff) == 0)
+		memcpy(ch->name, "SMD_", 4);
+	else
+		memcpy(ch->name, "DSP_", 4);
+	memcpy(ch->name + 4, name, 20);
+	ch->name[23] = 0;
+	ch->pdev.name = ch->name;
+	ch->pdev.id = -1;
+
+	pr_info("smd_alloc_channel() cid=%02d size=%05d '%s'\n",
+		ch->n, ch->fifo_size, ch->name);
+
+	mutex_lock(&smd_creation_mutex);
+	list_add(&ch->ch_list, &smd_ch_closed_list);
+	mutex_unlock(&smd_creation_mutex);
+
+	platform_device_register(&ch->pdev);
+	return 0;
+}
+
+static void smd_channel_probe_worker(struct work_struct *work)
+{
+	struct smd_alloc_elm *shared;
+	unsigned ctype;
+	unsigned type;
+	unsigned n;
+
+	shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64);
+	if (!shared) {
+		pr_err("smd: cannot find allocation table\n");
+		return;
+	}
+	for (n = 0; n < 64; n++) {
+		if (smd_ch_allocated[n])
+			continue;
+		if (!shared[n].ref_count)
+			continue;
+		if (!shared[n].name[0])
+			continue;
+		ctype = shared[n].ctype;
+		type = ctype & SMD_TYPE_MASK;
+
+		/* DAL channels are stream but neither the modem,
+		 * nor the DSP correctly indicate this.  Fixup manually.
+		 */
+		if (!memcmp(shared[n].name, "DAL", 3))
+			ctype = (ctype & (~SMD_KIND_MASK)) | SMD_KIND_STREAM;
+
+		type = shared[n].ctype & SMD_TYPE_MASK;
+		if ((type == SMD_TYPE_APPS_MODEM) ||
+		    (type == SMD_TYPE_APPS_DSP))
+			if (!smd_alloc_channel(shared[n].name, shared[n].cid, ctype))
+				smd_ch_allocated[n] = 1;
+	}
+}
+
+static void do_nothing_notify(void *priv, unsigned flags)
+{
+}
+
+struct smd_channel *smd_get_channel(const char *name)
+{
+	struct smd_channel *ch;
+
+	mutex_lock(&smd_creation_mutex);
+	list_for_each_entry(ch, &smd_ch_closed_list, ch_list) {
+		if (!strcmp(name, ch->name)) {
+			list_del(&ch->ch_list);
+			mutex_unlock(&smd_creation_mutex);
+			return ch;
+		}
+	}
+	mutex_unlock(&smd_creation_mutex);
+
+	return NULL;
+}
+
+int smd_open(const char *name, smd_channel_t **_ch,
+	     void *priv, void (*notify)(void *, unsigned))
+{
+	struct smd_channel *ch;
+	unsigned long flags;
+
+	if (smd_initialized == 0) {
+		pr_info("smd_open() before smd_init()\n");
+		return -ENODEV;
+	}
+
+	ch = smd_get_channel(name);
+	if (!ch)
+		return -ENODEV;
+
+	if (notify == 0)
+		notify = do_nothing_notify;
+
+	ch->notify = notify;
+	ch->current_packet = 0;
+	ch->last_state = SMD_SS_CLOSED;
+	ch->priv = priv;
+
+	*_ch = ch;
+
+	spin_lock_irqsave(&smd_lock, flags);
+
+	if ((ch->type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM)
+		list_add(&ch->ch_list, &smd_ch_list_modem);
+	else
+		list_add(&ch->ch_list, &smd_ch_list_dsp);
+
+	/* If the remote side is CLOSING, we need to get it to
+	 * move to OPENING (which we'll do by moving from CLOSED to
+	 * OPENING) and then get it to move from OPENING to
+	 * OPENED (by doing the same state change ourselves).
+	 *
+	 * Otherwise, it should be OPENING and we can move directly
+	 * to OPENED so that it will follow.
+	 */
+	if (ch->recv->state == SMD_SS_CLOSING) {
+		ch->send->head = 0;
+		ch_set_state(ch, SMD_SS_OPENING);
+	} else {
+		ch_set_state(ch, SMD_SS_OPENED);
+	}
+	spin_unlock_irqrestore(&smd_lock, flags);
+	smd_kick(ch);
+
+	return 0;
+}
+
+int smd_close(smd_channel_t *ch)
+{
+	unsigned long flags;
+
+	pr_info("smd_close(%p)\n", ch);
+
+	if (ch == 0)
+		return -1;
+
+	spin_lock_irqsave(&smd_lock, flags);
+	ch->notify = do_nothing_notify;
+	list_del(&ch->ch_list);
+	ch_set_state(ch, SMD_SS_CLOSED);
+	spin_unlock_irqrestore(&smd_lock, flags);
+
+	mutex_lock(&smd_creation_mutex);
+	list_add(&ch->ch_list, &smd_ch_closed_list);
+	mutex_unlock(&smd_creation_mutex);
+
+	return 0;
+}
+
+int smd_read(smd_channel_t *ch, void *data, int len)
+{
+	return ch->read(ch, data, len);
+}
+
+int smd_write(smd_channel_t *ch, const void *data, int len)
+{
+	return ch->write(ch, data, len);
+}
+
+int smd_write_atomic(smd_channel_t *ch, const void *data, int len)
+{
+	unsigned long flags;
+	int res;
+	spin_lock_irqsave(&smd_lock, flags);
+	res = ch->write(ch, data, len);
+	spin_unlock_irqrestore(&smd_lock, flags);
+	return res;
+}
+
+int smd_read_avail(smd_channel_t *ch)
+{
+	return ch->read_avail(ch);
+}
+
+int smd_write_avail(smd_channel_t *ch)
+{
+	return ch->write_avail(ch);
+}
+
+int smd_wait_until_readable(smd_channel_t *ch, int bytes)
+{
+	return -1;
+}
+
+int smd_wait_until_writable(smd_channel_t *ch, int bytes)
+{
+	return -1;
+}
+
+int smd_cur_packet_size(smd_channel_t *ch)
+{
+	return ch->current_packet;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+void *smem_alloc(unsigned id, unsigned size)
+{
+	return smem_find(id, size);
+}
+
+void *smem_item(unsigned id, unsigned *size)
+{
+	struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+	struct smem_heap_entry *toc = shared->heap_toc;
+
+	if (id >= SMEM_NUM_ITEMS)
+		return 0;
+
+	if (toc[id].allocated) {
+		*size = toc[id].size;
+		return (void *) (MSM_SHARED_RAM_BASE + toc[id].offset);
+	} else {
+		*size = 0;
+	}
+
+	return 0;
+}
+
+void *smem_find(unsigned id, unsigned size_in)
+{
+	unsigned size;
+	void *ptr;
+
+	ptr = smem_item(id, &size);
+	if (!ptr)
+		return 0;
+
+	size_in = ALIGN(size_in, 8);
+	if (size_in != size) {
+		pr_err("smem_find(%d, %d): wrong size %d\n",
+		       id, size_in, size);
+		return 0;
+	}
+
+	return ptr;
+}
+
+static irqreturn_t smsm_irq_handler(int irq, void *data)
+{
+	unsigned long flags;
+	unsigned apps, modm;
+
+	spin_lock_irqsave(&smem_lock, flags);
+
+	apps = raw_smsm_get_state(SMSM_STATE_APPS);
+	modm = raw_smsm_get_state(SMSM_STATE_MODEM);
+
+	if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
+		pr_info("<SM %08x %08x>\n", apps, modm);
+	if (modm & SMSM_RESET)
+		handle_modem_crash();
+
+	do_smd_probe();
+
+	spin_unlock_irqrestore(&smem_lock, flags);
+	return IRQ_HANDLED;
+}
+
+int smsm_change_state(enum smsm_state_item item,
+		      uint32_t clear_mask, uint32_t set_mask)
+{
+	unsigned long addr = smd_info.state + item * 4;
+	unsigned long flags;
+	unsigned state;
+
+	if (!smd_info.ready)
+		return -EIO;
+
+	spin_lock_irqsave(&smem_lock, flags);
+
+	if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET)
+		handle_modem_crash();
+
+	state = (readl(addr) & ~clear_mask) | set_mask;
+	writel(state, addr);
+
+	if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
+		pr_info("smsm_change_state %d %x\n", item, state);
+	notify_other_smsm();
+
+	spin_unlock_irqrestore(&smem_lock, flags);
+
+	return 0;
+}
+
+uint32_t smsm_get_state(enum smsm_state_item item)
+{
+	unsigned long flags;
+	uint32_t rv;
+
+	spin_lock_irqsave(&smem_lock, flags);
+
+	rv = readl(smd_info.state + item * 4);
+
+	if (item == SMSM_STATE_MODEM && (rv & SMSM_RESET))
+		handle_modem_crash();
+
+	spin_unlock_irqrestore(&smem_lock, flags);
+
+	return rv;
+}
+
+#ifdef CONFIG_ARCH_MSM_SCORPION
+
+int smsm_set_sleep_duration(uint32_t delay)
+{
+	struct msm_dem_slave_data *ptr;
+
+	ptr = smem_find(SMEM_APPS_DEM_SLAVE_DATA, sizeof(*ptr));
+	if (ptr == NULL) {
+		pr_err("smsm_set_sleep_duration <SM NO APPS_DEM_SLAVE_DATA>\n");
+		return -EIO;
+	}
+	if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
+		pr_info("smsm_set_sleep_duration %d -> %d\n",
+		       ptr->sleep_time, delay);
+	ptr->sleep_time = delay;
+	return 0;
+}
+
+#else
+
+int smsm_set_sleep_duration(uint32_t delay)
+{
+	uint32_t *ptr;
+
+	ptr = smem_find(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr));
+	if (ptr == NULL) {
+		pr_err("smsm_set_sleep_duration <SM NO SLEEP_DELAY>\n");
+		return -EIO;
+	}
+	if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
+		pr_info("smsm_set_sleep_duration %d -> %d\n",
+		       *ptr, delay);
+	*ptr = delay;
+	return 0;
+}
+
+#endif
+
+int smd_core_init(void)
+{
+	int r;
+	pr_info("smd_core_init()\n");
+
+	/* wait for essential items to be initialized */
+	for (;;) {
+		unsigned size;
+		void *state;
+		state = smem_item(SMEM_SMSM_SHARED_STATE, &size);
+		if (size == SMSM_V1_SIZE || size == SMSM_V2_SIZE) {
+			smd_info.state = (unsigned)state;
+			break;
+		}
+	}
+
+	smd_info.ready = 1;
+
+	r = request_irq(INT_A9_M2A_0, smd_modem_irq_handler,
+			IRQF_TRIGGER_RISING, "smd_dev", 0);
+	if (r < 0)
+		return r;
+	r = enable_irq_wake(INT_A9_M2A_0);
+	if (r < 0)
+		pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_0\n");
+
+	r = request_irq(INT_A9_M2A_5, smsm_irq_handler,
+			IRQF_TRIGGER_RISING, "smsm_dev", 0);
+	if (r < 0) {
+		free_irq(INT_A9_M2A_0, 0);
+		return r;
+	}
+	r = enable_irq_wake(INT_A9_M2A_5);
+	if (r < 0)
+		pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_5\n");
+
+#if defined(CONFIG_QDSP6)
+	r = request_irq(INT_ADSP_A11, smd_dsp_irq_handler,
+			IRQF_TRIGGER_RISING, "smd_dsp", 0);
+	if (r < 0) {
+		free_irq(INT_A9_M2A_0, 0);
+		free_irq(INT_A9_M2A_5, 0);
+		return r;
+	}
+#endif
+
+	/* check for any SMD channels that may already exist */
+	do_smd_probe();
+
+	/* indicate that we're up and running */
+	smsm_change_state(SMSM_STATE_APPS,
+			  ~0, SMSM_INIT | SMSM_SMDINIT | SMSM_RPCINIT | SMSM_RUN);
+#ifdef CONFIG_ARCH_MSM_SCORPION
+	smsm_change_state(SMSM_STATE_APPS_DEM, ~0, 0);
+#endif
+
+	pr_info("smd_core_init() done\n");
+
+	return 0;
+}
+
+static int __init msm_smd_probe(struct platform_device *pdev)
+{
+	pr_info("smd_init()\n");
+
+	/*
+	 * If we haven't waited for the ARM9 to boot up till now,
+	 * then we need to wait here. Otherwise this should just
+	 * return immediately.
+	 */
+	proc_comm_boot_wait();
+
+	INIT_WORK(&probe_work, smd_channel_probe_worker);
+
+	if (smd_core_init()) {
+		pr_err("smd_core_init() failed\n");
+		return -1;
+	}
+
+	do_smd_probe();
+
+	msm_check_for_modem_crash = check_for_modem_crash;
+
+	msm_init_last_radio_log(THIS_MODULE);
+
+	smd_initialized = 1;
+
+	return 0;
+}
+
+static struct platform_driver msm_smd_driver = {
+	.probe = msm_smd_probe,
+	.driver = {
+		.name = MODULE_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_smd_init(void)
+{
+	return platform_driver_register(&msm_smd_driver);
+}
+
+module_init(msm_smd_init);
+
+MODULE_DESCRIPTION("MSM Shared Memory Core");
+MODULE_AUTHOR("Brian Swetland <swetland@google.com>");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c
new file mode 100644
index 000000000000..3b2dd717b788
--- /dev/null
+++ b/arch/arm/mach-msm/smd_debug.c
@@ -0,0 +1,315 @@
+/* arch/arm/mach-msm/smd_debug.c
+ *
+ * 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/debugfs.h>
+#include <linux/list.h>
+
+#include <mach/msm_iomap.h>
+
+#include "smd_private.h"
+
+#if defined(CONFIG_DEBUG_FS)
+
+static char *chstate(unsigned n)
+{
+	switch (n) {
+	case SMD_SS_CLOSED:
+		return "CLOSED";
+	case SMD_SS_OPENING:
+		return "OPENING";
+	case SMD_SS_OPENED:
+		return "OPENED";
+	case SMD_SS_FLUSHING:
+		return "FLUSHING";
+	case SMD_SS_CLOSING:
+		return "CLOSING";
+	case SMD_SS_RESET:
+		return "RESET";
+	case SMD_SS_RESET_OPENING:
+		return "ROPENING";
+	default:
+		return "UNKNOWN";
+	}
+}
+
+
+static int dump_ch(char *buf, int max, struct smd_channel *ch)
+{
+	volatile struct smd_half_channel *s = ch->send;
+	volatile struct smd_half_channel *r = ch->recv;
+
+	return scnprintf(
+		buf, max,
+		"ch%02d:"
+		" %8s(%05d/%05d) %c%c%c%c%c%c%c <->"
+		" %8s(%05d/%05d) %c%c%c%c%c%c%c '%s'\n", ch->n,
+		chstate(s->state), s->tail, s->head,
+		s->fDSR ? 'D' : 'd',
+		s->fCTS ? 'C' : 'c',
+		s->fCD ? 'C' : 'c',
+		s->fRI ? 'I' : 'i',
+		s->fHEAD ? 'W' : 'w',
+		s->fTAIL ? 'R' : 'r',
+		s->fSTATE ? 'S' : 's',
+		chstate(r->state), r->tail, r->head,
+		r->fDSR ? 'D' : 'd',
+		r->fCTS ? 'R' : 'r',
+		r->fCD ? 'C' : 'c',
+		r->fRI ? 'I' : 'i',
+		r->fHEAD ? 'W' : 'w',
+		r->fTAIL ? 'R' : 'r',
+		r->fSTATE ? 'S' : 's',
+		ch->name
+		);
+}
+
+static int debug_read_stat(char *buf, int max)
+{
+	char *msg;
+	int i = 0;
+
+	msg = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
+
+	if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET)
+		i += scnprintf(buf + i, max - i,
+			       "smsm: ARM9 HAS CRASHED\n");
+
+	i += scnprintf(buf + i, max - i, "smsm: a9: %08x a11: %08x\n",
+		       raw_smsm_get_state(SMSM_STATE_MODEM),
+		       raw_smsm_get_state(SMSM_STATE_APPS));
+#ifdef CONFIG_ARCH_MSM_SCORPION
+	i += scnprintf(buf + i, max - i, "smsm dem: apps: %08x modem: %08x "
+		       "qdsp6: %08x power: %08x time: %08x\n",
+		       raw_smsm_get_state(SMSM_STATE_APPS_DEM),
+		       raw_smsm_get_state(SMSM_STATE_MODEM_DEM),
+		       raw_smsm_get_state(SMSM_STATE_QDSP6_DEM),
+		       raw_smsm_get_state(SMSM_STATE_POWER_MASTER_DEM),
+		       raw_smsm_get_state(SMSM_STATE_TIME_MASTER_DEM));
+#endif
+	if (msg) {
+		msg[SZ_DIAG_ERR_MSG - 1] = 0;
+		i += scnprintf(buf + i, max - i, "diag: '%s'\n", msg);
+	}
+	return i;
+}
+
+static int debug_read_mem(char *buf, int max)
+{
+	unsigned n;
+	struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+	struct smem_heap_entry *toc = shared->heap_toc;
+	int i = 0;
+
+	i += scnprintf(buf + i, max - i,
+		       "heap: init=%d free=%d remain=%d\n",
+		       shared->heap_info.initialized,
+		       shared->heap_info.free_offset,
+		       shared->heap_info.heap_remaining);
+
+	for (n = 0; n < SMEM_NUM_ITEMS; n++) {
+		if (toc[n].allocated == 0)
+			continue;
+		i += scnprintf(buf + i, max - i,
+			       "%04d: offset %08x size %08x\n",
+			       n, toc[n].offset, toc[n].size);
+	}
+	return i;
+}
+
+static int debug_read_ch(char *buf, int max)
+{
+	struct smd_channel *ch;
+	unsigned long flags;
+	int i = 0;
+
+	spin_lock_irqsave(&smd_lock, flags);
+	list_for_each_entry(ch, &smd_ch_list_dsp, ch_list)
+		i += dump_ch(buf + i, max - i, ch);
+	list_for_each_entry(ch, &smd_ch_list_modem, ch_list)
+		i += dump_ch(buf + i, max - i, ch);
+	list_for_each_entry(ch, &smd_ch_closed_list, ch_list)
+		i += dump_ch(buf + i, max - i, ch);
+	spin_unlock_irqrestore(&smd_lock, flags);
+
+	return i;
+}
+
+static int debug_read_version(char *buf, int max)
+{
+	struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+	unsigned version = shared->version[VERSION_MODEM];
+	return sprintf(buf, "%d.%d\n", version >> 16, version & 0xffff);
+}
+
+static int debug_read_build_id(char *buf, int max)
+{
+	unsigned size;
+	void *data;
+
+	data = smem_item(SMEM_HW_SW_BUILD_ID, &size);
+	if (!data)
+		return 0;
+
+	if (size >= max)
+		size = max;
+	memcpy(buf, data, size);
+
+	return size;
+}
+
+static int debug_read_alloc_tbl(char *buf, int max)
+{
+	struct smd_alloc_elm *shared;
+	int n, i = 0;
+
+	shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64);
+
+	for (n = 0; n < 64; n++) {
+		if (shared[n].ref_count == 0)
+			continue;
+		i += scnprintf(buf + i, max - i,
+			       "%03d: %-20s cid=%02d type=%03d "
+			       "kind=%02d ref_count=%d\n",
+			       n, shared[n].name, shared[n].cid,
+			       shared[n].ctype & 0xff,
+			       (shared[n].ctype >> 8) & 0xf,
+			       shared[n].ref_count);
+	}
+
+	return i;
+}
+
+#define DEBUG_BUFMAX 4096
+static char debug_buffer[DEBUG_BUFMAX];
+
+static ssize_t debug_read(struct file *file, char __user *buf,
+			  size_t count, loff_t *ppos)
+{
+	int (*fill)(char *buf, int max) = file->private_data;
+	int bsize = fill(debug_buffer, DEBUG_BUFMAX);
+	return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize);
+}
+
+static int debug_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static const struct file_operations debug_ops = {
+	.read = debug_read,
+	.open = debug_open,
+};
+
+static void debug_create(const char *name, mode_t mode,
+			 struct dentry *dent,
+			 int (*fill)(char *buf, int max))
+{
+	debugfs_create_file(name, mode, dent, fill, &debug_ops);
+}
+
+static int smd_debugfs_init(void)
+{
+	struct dentry *dent;
+
+	dent = debugfs_create_dir("smd", 0);
+	if (IS_ERR(dent))
+		return 1;
+
+	debug_create("ch", 0444, dent, debug_read_ch);
+	debug_create("stat", 0444, dent, debug_read_stat);
+	debug_create("mem", 0444, dent, debug_read_mem);
+	debug_create("version", 0444, dent, debug_read_version);
+	debug_create("tbl", 0444, dent, debug_read_alloc_tbl);
+	debug_create("build", 0444, dent, debug_read_build_id);
+
+	return 0;
+}
+
+late_initcall(smd_debugfs_init);
+#endif
+
+
+#define MAX_NUM_SLEEP_CLIENTS		64
+#define MAX_SLEEP_NAME_LEN		8
+
+#define NUM_GPIO_INT_REGISTERS		6
+#define GPIO_SMEM_NUM_GROUPS		2
+#define GPIO_SMEM_MAX_PC_INTERRUPTS	8
+
+struct tramp_gpio_save {
+	unsigned int enable;
+	unsigned int detect;
+	unsigned int polarity;
+};
+
+struct tramp_gpio_smem {
+	uint16_t num_fired[GPIO_SMEM_NUM_GROUPS];
+	uint16_t fired[GPIO_SMEM_NUM_GROUPS][GPIO_SMEM_MAX_PC_INTERRUPTS];
+	uint32_t enabled[NUM_GPIO_INT_REGISTERS];
+	uint32_t detection[NUM_GPIO_INT_REGISTERS];
+	uint32_t polarity[NUM_GPIO_INT_REGISTERS];
+};
+
+
+void smsm_print_sleep_info(void)
+{
+	unsigned long flags;
+	uint32_t *ptr;
+	struct tramp_gpio_smem *gpio;
+	struct smsm_interrupt_info *int_info;
+
+
+	spin_lock_irqsave(&smem_lock, flags);
+
+	ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr));
+	if (ptr)
+		pr_info("SMEM_SMSM_SLEEP_DELAY: %x\n", *ptr);
+
+	ptr = smem_alloc(SMEM_SMSM_LIMIT_SLEEP, sizeof(*ptr));
+	if (ptr)
+		pr_info("SMEM_SMSM_LIMIT_SLEEP: %x\n", *ptr);
+
+	ptr = smem_alloc(SMEM_SLEEP_POWER_COLLAPSE_DISABLED, sizeof(*ptr));
+	if (ptr)
+		pr_info("SMEM_SLEEP_POWER_COLLAPSE_DISABLED: %x\n", *ptr);
+
+#ifndef CONFIG_ARCH_MSM_SCORPION
+	int_info = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*int_info));
+	if (int_info)
+		pr_info("SMEM_SMSM_INT_INFO %x %x %x\n",
+			int_info->interrupt_mask,
+			int_info->pending_interrupts,
+			int_info->wakeup_reason);
+
+	gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*gpio));
+	if (gpio) {
+		int i;
+		for (i = 0; i < NUM_GPIO_INT_REGISTERS; i++)
+			pr_info("SMEM_GPIO_INT: %d: e %x d %x p %x\n",
+				i, gpio->enabled[i], gpio->detection[i],
+				gpio->polarity[i]);
+
+		for (i = 0; i < GPIO_SMEM_NUM_GROUPS; i++)
+			pr_info("SMEM_GPIO_INT: %d: f %d: %d %d...\n",
+				i, gpio->num_fired[i], gpio->fired[i][0],
+				gpio->fired[i][1]);
+	}
+#else
+#endif
+	spin_unlock_irqrestore(&smem_lock, flags);
+}
+
diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h
new file mode 100644
index 000000000000..727bfe68aa9b
--- /dev/null
+++ b/arch/arm/mach-msm/smd_private.h
@@ -0,0 +1,403 @@
+/* arch/arm/mach-msm/smd_private.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_MSM_SMD_PRIVATE_H_
+#define _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_
+
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/io.h>
+
+#include <mach/msm_iomap.h>
+
+struct smem_heap_info {
+	unsigned initialized;
+	unsigned free_offset;
+	unsigned heap_remaining;
+	unsigned reserved;
+};
+
+struct smem_heap_entry {
+	unsigned allocated;
+	unsigned offset;
+	unsigned size;
+	unsigned reserved;
+};
+
+struct smem_proc_comm {
+	unsigned command;
+	unsigned status;
+	unsigned data1;
+	unsigned data2;
+};
+
+#define PC_APPS  0
+#define PC_MODEM 1
+
+#define VERSION_SMD       0
+#define VERSION_QDSP6     4
+#define VERSION_APPS_SBL  6
+#define VERSION_MODEM_SBL 7
+#define VERSION_APPS      8
+#define VERSION_MODEM     9
+
+struct smem_shared {
+	struct smem_proc_comm proc_comm[4];
+	unsigned version[32];
+	struct smem_heap_info heap_info;
+	struct smem_heap_entry heap_toc[512];
+};
+
+#define SMSM_V1_SIZE		(sizeof(unsigned) * 8)
+#define SMSM_V2_SIZE		(sizeof(unsigned) * 4)
+
+#ifdef CONFIG_MSM_SMD_PKG3
+struct smsm_interrupt_info {
+	uint32_t interrupt_mask;
+	uint32_t pending_interrupts;
+	uint32_t wakeup_reason;
+};
+#else
+#define DEM_MAX_PORT_NAME_LEN (20)
+struct msm_dem_slave_data {
+	uint32_t sleep_time;
+	uint32_t interrupt_mask;
+	uint32_t resources_used;
+	uint32_t reserved1;
+
+	uint32_t wakeup_reason;
+	uint32_t pending_interrupts;
+	uint32_t rpc_prog;
+	uint32_t rpc_proc;
+	char     smd_port_name[DEM_MAX_PORT_NAME_LEN];
+	uint32_t reserved2;
+};
+#endif
+
+#define SZ_DIAG_ERR_MSG 0xC8
+#define ID_DIAG_ERR_MSG SMEM_DIAG_ERR_MESSAGE
+#define ID_SMD_CHANNELS SMEM_SMD_BASE_ID
+#define ID_SHARED_STATE SMEM_SMSM_SHARED_STATE
+#define ID_CH_ALLOC_TBL SMEM_CHANNEL_ALLOC_TBL
+
+#define SMSM_INIT		0x00000001
+#define SMSM_SMDINIT		0x00000008
+#define SMSM_RPCINIT		0x00000020
+#define SMSM_RESET		0x00000040
+#define SMSM_RSA		0x00000080
+#define SMSM_RUN		0x00000100
+#define SMSM_PWRC		0x00000200
+#define SMSM_TIMEWAIT		0x00000400
+#define SMSM_TIMEINIT		0x00000800
+#define SMSM_PWRC_EARLY_EXIT	0x00001000
+#define SMSM_WFPI		0x00002000
+#define SMSM_SLEEP		0x00004000
+#define SMSM_SLEEPEXIT		0x00008000
+#define SMSM_APPS_REBOOT	0x00020000
+#define SMSM_SYSTEM_POWER_DOWN	0x00040000
+#define SMSM_SYSTEM_REBOOT	0x00080000
+#define SMSM_SYSTEM_DOWNLOAD	0x00100000
+#define SMSM_PWRC_SUSPEND	0x00200000
+#define SMSM_APPS_SHUTDOWN	0x00400000
+#define SMSM_SMD_LOOPBACK	0x00800000
+#define SMSM_RUN_QUIET		0x01000000
+#define SMSM_MODEM_WAIT		0x02000000
+#define SMSM_MODEM_BREAK	0x04000000
+#define SMSM_MODEM_CONTINUE	0x08000000
+#define SMSM_UNKNOWN		0x80000000
+
+#define SMSM_WKUP_REASON_RPC	0x00000001
+#define SMSM_WKUP_REASON_INT	0x00000002
+#define SMSM_WKUP_REASON_GPIO	0x00000004
+#define SMSM_WKUP_REASON_TIMER	0x00000008
+#define SMSM_WKUP_REASON_ALARM	0x00000010
+#define SMSM_WKUP_REASON_RESET	0x00000020
+
+#ifdef CONFIG_ARCH_MSM7X00A
+enum smsm_state_item {
+	SMSM_STATE_APPS = 1,
+	SMSM_STATE_MODEM = 3,
+	SMSM_STATE_COUNT,
+};
+#else
+enum smsm_state_item {
+	SMSM_STATE_APPS,
+	SMSM_STATE_MODEM,
+	SMSM_STATE_HEXAGON,
+	SMSM_STATE_APPS_DEM,
+	SMSM_STATE_MODEM_DEM,
+	SMSM_STATE_QDSP6_DEM,
+	SMSM_STATE_POWER_MASTER_DEM,
+	SMSM_STATE_TIME_MASTER_DEM,
+	SMSM_STATE_COUNT,
+};
+#endif
+
+void *smem_alloc(unsigned id, unsigned size);
+int smsm_change_state(enum smsm_state_item item, uint32_t clear_mask, uint32_t set_mask);
+uint32_t smsm_get_state(enum smsm_state_item item);
+int smsm_set_sleep_duration(uint32_t delay);
+void smsm_print_sleep_info(void);
+
+#define SMEM_NUM_SMD_CHANNELS        64
+
+typedef enum {
+	/* fixed items */
+	SMEM_PROC_COMM = 0,
+	SMEM_HEAP_INFO,
+	SMEM_ALLOCATION_TABLE,
+	SMEM_VERSION_INFO,
+	SMEM_HW_RESET_DETECT,
+	SMEM_AARM_WARM_BOOT,
+	SMEM_DIAG_ERR_MESSAGE,
+	SMEM_SPINLOCK_ARRAY,
+	SMEM_MEMORY_BARRIER_LOCATION,
+
+	/* dynamic items */
+	SMEM_AARM_PARTITION_TABLE,
+	SMEM_AARM_BAD_BLOCK_TABLE,
+	SMEM_RESERVE_BAD_BLOCKS,
+	SMEM_WM_UUID,
+	SMEM_CHANNEL_ALLOC_TBL,
+	SMEM_SMD_BASE_ID,
+	SMEM_SMEM_LOG_IDX = SMEM_SMD_BASE_ID + SMEM_NUM_SMD_CHANNELS,
+	SMEM_SMEM_LOG_EVENTS,
+	SMEM_SMEM_STATIC_LOG_IDX,
+	SMEM_SMEM_STATIC_LOG_EVENTS,
+	SMEM_SMEM_SLOW_CLOCK_SYNC,
+	SMEM_SMEM_SLOW_CLOCK_VALUE,
+	SMEM_BIO_LED_BUF,
+	SMEM_SMSM_SHARED_STATE,
+	SMEM_SMSM_INT_INFO,
+	SMEM_SMSM_SLEEP_DELAY,
+	SMEM_SMSM_LIMIT_SLEEP,
+	SMEM_SLEEP_POWER_COLLAPSE_DISABLED,
+	SMEM_KEYPAD_KEYS_PRESSED,
+	SMEM_KEYPAD_STATE_UPDATED,
+	SMEM_KEYPAD_STATE_IDX,
+	SMEM_GPIO_INT,
+	SMEM_MDDI_LCD_IDX,
+	SMEM_MDDI_HOST_DRIVER_STATE,
+	SMEM_MDDI_LCD_DISP_STATE,
+	SMEM_LCD_CUR_PANEL,
+	SMEM_MARM_BOOT_SEGMENT_INFO,
+	SMEM_AARM_BOOT_SEGMENT_INFO,
+	SMEM_SLEEP_STATIC,
+	SMEM_SCORPION_FREQUENCY,
+	SMEM_SMD_PROFILES,
+	SMEM_TSSC_BUSY,
+	SMEM_HS_SUSPEND_FILTER_INFO,
+	SMEM_BATT_INFO,
+	SMEM_APPS_BOOT_MODE,
+	SMEM_VERSION_FIRST,
+	SMEM_VERSION_LAST = SMEM_VERSION_FIRST + 24,
+	SMEM_OSS_RRCASN1_BUF1,
+	SMEM_OSS_RRCASN1_BUF2,
+	SMEM_ID_VENDOR0,
+	SMEM_ID_VENDOR1,
+	SMEM_ID_VENDOR2,
+	SMEM_HW_SW_BUILD_ID,
+	SMEM_SMD_BLOCK_PORT_BASE_ID,
+	SMEM_SMD_BLOCK_PORT_PROC0_HEAP = SMEM_SMD_BLOCK_PORT_BASE_ID + SMEM_NUM_SMD_CHANNELS,
+	SMEM_SMD_BLOCK_PORT_PROC1_HEAP = SMEM_SMD_BLOCK_PORT_PROC0_HEAP + SMEM_NUM_SMD_CHANNELS,
+	SMEM_I2C_MUTEX = SMEM_SMD_BLOCK_PORT_PROC1_HEAP + SMEM_NUM_SMD_CHANNELS,
+	SMEM_SCLK_CONVERSION,
+	SMEM_SMD_SMSM_INTR_MUX,
+	SMEM_SMSM_CPU_INTR_MASK,
+	SMEM_APPS_DEM_SLAVE_DATA,
+	SMEM_QDSP6_DEM_SLAVE_DATA,
+	SMEM_CLKREGIM_BSP,
+	SMEM_CLKREGIM_SOURCES,
+	SMEM_SMD_FIFO_BASE_ID,
+	SMEM_USABLE_RAM_PARTITION_TABLE = SMEM_SMD_FIFO_BASE_ID + SMEM_NUM_SMD_CHANNELS,
+	SMEM_POWER_ON_STATUS_INFO,
+	SMEM_DAL_AREA,
+	SMEM_SMEM_LOG_POWER_IDX,
+	SMEM_SMEM_LOG_POWER_WRAP,
+	SMEM_SMEM_LOG_POWER_EVENTS,
+	SMEM_ERR_CRASH_LOG,
+	SMEM_ERR_F3_TRACE_LOG,
+	SMEM_NUM_ITEMS,
+} smem_mem_type;
+
+
+#define SMD_SS_CLOSED		0x00000000
+#define SMD_SS_OPENING		0x00000001
+#define SMD_SS_OPENED		0x00000002
+#define SMD_SS_FLUSHING		0x00000003
+#define SMD_SS_CLOSING		0x00000004
+#define SMD_SS_RESET		0x00000005
+#define SMD_SS_RESET_OPENING	0x00000006
+
+#define SMD_BUF_SIZE		8192
+#define SMD_CHANNELS		64
+
+#define SMD_HEADER_SIZE		20
+
+struct smd_alloc_elm {
+	char name[20];
+	uint32_t cid;
+	uint32_t ctype;
+	uint32_t ref_count;
+};
+
+struct smd_half_channel {
+	unsigned state;
+	unsigned char fDSR;
+	unsigned char fCTS;
+	unsigned char fCD;
+	unsigned char fRI;
+	unsigned char fHEAD;
+	unsigned char fTAIL;
+	unsigned char fSTATE;
+	unsigned char fUNUSED;
+	unsigned tail;
+	unsigned head;
+} __attribute__(( aligned(4), packed ));
+
+/* Only used on SMD package v3 on msm7201a */
+struct smd_shared_v1 {
+	struct smd_half_channel ch0;
+	unsigned char data0[SMD_BUF_SIZE];
+	struct smd_half_channel ch1;
+	unsigned char data1[SMD_BUF_SIZE];
+};
+
+/* Used on SMD package v4 */
+struct smd_shared_v2 {
+	struct smd_half_channel ch0;
+	struct smd_half_channel ch1;
+};
+
+struct smd_channel {
+	volatile struct smd_half_channel *send;
+	volatile struct smd_half_channel *recv;
+	unsigned char *send_data;
+	unsigned char *recv_data;
+
+	unsigned fifo_mask;
+	unsigned fifo_size;
+	unsigned current_packet;
+	unsigned n;
+
+	struct list_head ch_list;
+
+	void *priv;
+	void (*notify)(void *priv, unsigned flags);
+
+	int (*read)(struct smd_channel *ch, void *data, int len);
+	int (*write)(struct smd_channel *ch, const void *data, int len);
+	int (*read_avail)(struct smd_channel *ch);
+	int (*write_avail)(struct smd_channel *ch);
+
+	void (*update_state)(struct smd_channel *ch);
+	unsigned last_state;
+	void (*notify_other_cpu)(void);
+	unsigned type;
+
+	char name[32];
+	struct platform_device pdev;
+};
+
+#define SMD_TYPE_MASK		0x0FF
+#define SMD_TYPE_APPS_MODEM	0x000
+#define SMD_TYPE_APPS_DSP	0x001
+#define SMD_TYPE_MODEM_DSP	0x002
+
+#define SMD_KIND_MASK		0xF00
+#define SMD_KIND_UNKNOWN	0x000
+#define SMD_KIND_STREAM		0x100
+#define SMD_KIND_PACKET		0x200
+
+extern struct list_head smd_ch_closed_list;
+extern struct list_head smd_ch_list_modem;
+extern struct list_head smd_ch_list_dsp;
+
+extern spinlock_t smd_lock;
+extern spinlock_t smem_lock;
+
+void *smem_find(unsigned id, unsigned size);
+void *smem_item(unsigned id, unsigned *size);
+uint32_t raw_smsm_get_state(enum smsm_state_item item);
+
+extern void msm_init_last_radio_log(struct module *);
+
+#ifdef CONFIG_MSM_SMD_PKG3
+/*
+ * This allocator assumes an SMD Package v3 which only exists on
+ * MSM7x00 SoC's.
+ */
+static inline int _smd_alloc_channel(struct smd_channel *ch)
+{
+	struct smd_shared_v1 *shared1;
+
+	shared1 = smem_alloc(ID_SMD_CHANNELS + ch->n, sizeof(*shared1));
+	if (!shared1) {
+		pr_err("smd_alloc_channel() cid %d does not exist\n", ch->n);
+		return -1;
+	}
+	ch->send = &shared1->ch0;
+	ch->recv = &shared1->ch1;
+	ch->send_data = shared1->data0;
+	ch->recv_data = shared1->data1;
+	ch->fifo_size = SMD_BUF_SIZE;
+	return 0;
+}
+#else
+/*
+ * This allocator assumes an SMD Package v4, the most common
+ * and the default.
+ */
+static inline int _smd_alloc_channel(struct smd_channel *ch)
+{
+	struct smd_shared_v2 *shared2;
+	void *buffer;
+	unsigned buffer_sz;
+
+	shared2 = smem_alloc(SMEM_SMD_BASE_ID + ch->n, sizeof(*shared2));
+	buffer = smem_item(SMEM_SMD_FIFO_BASE_ID + ch->n, &buffer_sz);
+
+	if (!buffer)
+		return -1;
+
+	/* buffer must be a power-of-two size */
+	if (buffer_sz & (buffer_sz - 1))
+		return -1;
+
+	buffer_sz /= 2;
+	ch->send = &shared2->ch0;
+	ch->recv = &shared2->ch1;
+	ch->send_data = buffer;
+	ch->recv_data = buffer + buffer_sz;
+	ch->fifo_size = buffer_sz;
+	return 0;
+}
+#endif /* CONFIG_MSM_SMD_PKG3 */
+
+#if defined(CONFIG_ARCH_MSM7X30)
+static inline void msm_a2m_int(uint32_t irq)
+{
+	writel(1 << irq, MSM_GCC_BASE + 0x8);
+}
+#else
+static inline void msm_a2m_int(uint32_t irq)
+{
+	writel(1, MSM_CSR_BASE + 0x400 + (irq * 4));
+}
+#endif /* CONFIG_ARCH_MSM7X30 */
+
+
+#endif
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 4855b8ca5101..dec5ca622d7d 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -25,7 +25,9 @@
 #include <asm/mach/time.h>
 #include <mach/msm_iomap.h>
 
+#ifndef MSM_DGT_BASE
 #define MSM_DGT_BASE (MSM_GPT_BASE + 0x10)
+#endif
 #define MSM_DGT_SHIFT (5)
 
 #define TIMER_MATCH_VAL         0x0000
diff --git a/arch/arm/mach-msm/vreg.c b/arch/arm/mach-msm/vreg.c
index fcb0b9f25684..a9103bc6615f 100644
--- a/arch/arm/mach-msm/vreg.c
+++ b/arch/arm/mach-msm/vreg.c
@@ -1,6 +1,7 @@
 /* arch/arm/mach-msm/vreg.c
  *
  * Copyright (C) 2008 Google, Inc.
+ * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -18,6 +19,7 @@
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/debugfs.h>
+#include <linux/string.h>
 #include <mach/vreg.h>
 
 #include "proc_comm.h"
@@ -25,42 +27,62 @@
 struct vreg {
 	const char *name;
 	unsigned id;
+	int status;
+	unsigned refcnt;
 };
 
-#define VREG(_name, _id) { .name = _name, .id = _id, }
+#define VREG(_name, _id, _status, _refcnt) \
+	{ .name = _name, .id = _id, .status = _status, .refcnt = _refcnt }
 
 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),
+	VREG("msma",	0, 0, 0),
+	VREG("msmp",	1, 0, 0),
+	VREG("msme1",	2, 0, 0),
+	VREG("msmc1",	3, 0, 0),
+	VREG("msmc2",	4, 0, 0),
+	VREG("gp3",	5, 0, 0),
+	VREG("msme2",	6, 0, 0),
+	VREG("gp4",	7, 0, 0),
+	VREG("gp1",	8, 0, 0),
+	VREG("tcxo",	9, 0, 0),
+	VREG("pa",	10, 0, 0),
+	VREG("rftx",	11, 0, 0),
+	VREG("rfrx1",	12, 0, 0),
+	VREG("rfrx2",	13, 0, 0),
+	VREG("synt",	14, 0, 0),
+	VREG("wlan",	15, 0, 0),
+	VREG("usb",	16, 0, 0),
+	VREG("boost",	17, 0, 0),
+	VREG("mmc",	18, 0, 0),
+	VREG("ruim",	19, 0, 0),
+	VREG("msmc0",	20, 0, 0),
+	VREG("gp2",	21, 0, 0),
+	VREG("gp5",	22, 0, 0),
+	VREG("gp6",	23, 0, 0),
+	VREG("rf",	24, 0, 0),
+	VREG("rf_vco",	26, 0, 0),
+	VREG("mpll",	27, 0, 0),
+	VREG("s2",	28, 0, 0),
+	VREG("s3",	29, 0, 0),
+	VREG("rfubm",	30, 0, 0),
+	VREG("ncp",	31, 0, 0),
+	VREG("gp7",	32, 0, 0),
+	VREG("gp8",	33, 0, 0),
+	VREG("gp9",	34, 0, 0),
+	VREG("gp10",	35, 0, 0),
+	VREG("gp11",	36, 0, 0),
+	VREG("gp12",	37, 0, 0),
+	VREG("gp13",	38, 0, 0),
+	VREG("gp14",	39, 0, 0),
+	VREG("gp15",	40, 0, 0),
+	VREG("gp16",	41, 0, 0),
+	VREG("gp17",	42, 0, 0),
+	VREG("s4",	43, 0, 0),
+	VREG("usb2",	44, 0, 0),
+	VREG("wlan2",	45, 0, 0),
+	VREG("xo_out",	46, 0, 0),
+	VREG("lvsw0",	47, 0, 0),
+	VREG("lvsw1",	48, 0, 0),
 };
 
 struct vreg *vreg_get(struct device *dev, const char *id)
@@ -70,7 +92,7 @@ struct vreg *vreg_get(struct device *dev, const char *id)
 		if (!strcmp(vregs[n].name, id))
 			return vregs + n;
 	}
-	return 0;
+	return ERR_PTR(-ENOENT);
 }
 
 void vreg_put(struct vreg *vreg)
@@ -81,20 +103,39 @@ int vreg_enable(struct vreg *vreg)
 {
 	unsigned id = vreg->id;
 	unsigned enable = 1;
-	return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+
+	if (vreg->refcnt == 0)
+		vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+
+	if ((vreg->refcnt < UINT_MAX) && (!vreg->status))
+		vreg->refcnt++;
+
+	return vreg->status;
 }
 
-void vreg_disable(struct vreg *vreg)
+int vreg_disable(struct vreg *vreg)
 {
 	unsigned id = vreg->id;
 	unsigned enable = 0;
-	msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+
+	if (!vreg->refcnt)
+		return 0;
+
+	if (vreg->refcnt == 1)
+		vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+
+	if (!vreg->status)
+		vreg->refcnt--;
+
+	return vreg->status;
 }
 
 int vreg_set_level(struct vreg *vreg, unsigned mv)
 {
 	unsigned id = vreg->id;
-	return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);
+
+	vreg->status = msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);
+	return vreg->status;
 }
 
 #if defined(CONFIG_DEBUG_FS)
@@ -118,24 +159,59 @@ static int vreg_debug_set(void *data, u64 val)
 
 static int vreg_debug_get(void *data, u64 *val)
 {
-	return -ENOSYS;
+	struct vreg *vreg = data;
+
+	if (!vreg->status)
+		*val = 0;
+	else
+		*val = 1;
+
+	return 0;
+}
+
+static int vreg_debug_count_set(void *data, u64 val)
+{
+	struct vreg *vreg = data;
+	if (val > UINT_MAX)
+		val = UINT_MAX;
+	vreg->refcnt = val;
+	return 0;
+}
+
+static int vreg_debug_count_get(void *data, u64 *val)
+{
+	struct vreg *vreg = data;
+
+	*val = vreg->refcnt;
+
+	return 0;
 }
 
 DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(vreg_count_fops, vreg_debug_count_get,
+			vreg_debug_count_set, "%llu\n");
 
 static int __init vreg_debug_init(void)
 {
 	struct dentry *dent;
 	int n;
+	char name[32];
+	const char *refcnt_name = "_refcnt";
 
 	dent = debugfs_create_dir("vreg", 0);
 	if (IS_ERR(dent))
 		return 0;
 
-	for (n = 0; n < ARRAY_SIZE(vregs); n++)
+	for (n = 0; n < ARRAY_SIZE(vregs); n++) {
 		(void) debugfs_create_file(vregs[n].name, 0644,
 					   dent, vregs + n, &vreg_fops);
 
+		strlcpy(name, vregs[n].name, sizeof(name));
+		strlcat(name, refcnt_name, sizeof(name));
+		(void) debugfs_create_file(name, 0644,
+					   dent, vregs + n, &vreg_count_fops);
+	}
+
 	return 0;
 }