Merge "msm_fb: display: Update Toshiba DSI-to-LVDS to support WUXGA panel." into msm-3.0
diff --git a/Documentation/devicetree/bindings/spmi/msm-spmi.txt b/Documentation/devicetree/bindings/spmi/msm-spmi.txt
new file mode 100644
index 0000000..fa91514
--- /dev/null
+++ b/Documentation/devicetree/bindings/spmi/msm-spmi.txt
@@ -0,0 +1,72 @@
+* SPMI
+
+The spmi Device Tree support interprets up to two levels of Device Tree
+topology. The first level is required and specifies only a slave address.
+The second level is optional and allows for the specification of different
+offsets within the same 16-bit address space underneath a particular SPMI
+slave ID. Within the second level, any number of address ranges can be
+associated with a particular device within that 16-bit range.
+
+First level
+
+Required properites :
+
+ - reg: SPMI Slave ID (0-15) with no size cell.
+ - compatible : "qcom," prefixed string to match against the driver.
+
+Recommended properties :
+
+ - interrupts : <a b c> where a is the slave ID, b is the peripheral ID,
+   c is the device interrupt number (0-7). Each device supports any arbitrary
+   number of interrupts.
+ - interrupt-parent : the phandle for the interrupt controller that
+   services interrupts for this device.
+
+Second level
+
+Required properties :
+ - spmi-dev-container: Used by the parser to understand that this is the second
+   level of the tree.
+ - reg: <a b> where a is < 65536 and b is a size. Each device supports an
+   arbitrary number of address ranges.
+ - compatible : "qcom," prefixed string to match against the driver.
+
+Recommended properties :
+
+ - interrupts : <a b c> where a is the slave ID, b is is the peripheral ID,
+   c is the device interrupt number (0-7). Each device supports any arbitrary
+   number of interrupts.
+ - interrupt-parent : the phandle for the interrupt controller that
+   services interrupts for this device.
+
+Example:
+
+/ {
+	qcom,spmi@fc4c0000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		interrupt-parent = <&qpnpint>;
+		pmic8941@d {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0xd>;
+			spmi-dev-container;
+
+			coincell@2800 {
+				compatible = "qcom,qpnp-coincell";
+				reg = <0x2800 0x4000>;
+				interrupts = <0xd 0x28 0x6  0xd 0x28 0x3>;
+
+			};
+			pon@800 {
+				compatible = "qcom,qpnp-pon";
+				reg = <0x800 0x4000>;
+			};
+		};
+		customer_dev@2 {
+			compatible = "qcom,qpnp-pon";
+			reg = <0x2>;
+			interrupts = <0x2 0x08 0x1  0x2 0x8 0x3>;
+		};
+	};
+};
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 860e2bf..eca2ffa 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -66,6 +66,7 @@
 CONFIG_MSM_PIL_QDSP6V4=y
 CONFIG_MSM_PIL_RIVA=y
 CONFIG_MSM_PIL_TZAPPS=y
+CONFIG_MSM_PIL_GSS=y
 CONFIG_MSM_SUBSYSTEM_RESTART=y
 CONFIG_MSM_MODEM_8960=y
 CONFIG_MSM_LPASS_8960=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index eb4244f..18e9085 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -66,6 +66,7 @@
 CONFIG_MSM_PIL_QDSP6V4=y
 CONFIG_MSM_PIL_RIVA=y
 CONFIG_MSM_PIL_TZAPPS=y
+CONFIG_MSM_PIL_GSS=y
 CONFIG_MSM_SUBSYSTEM_RESTART=y
 CONFIG_MSM_MODEM_8960=y
 CONFIG_MSM_LPASS_8960=y
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 761c29e..c3b841a 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -27,6 +27,7 @@
 #include <asm/byteorder.h>
 #include <asm/memory.h>
 #include <asm/system.h>
+#include <mach/msm_rtb.h>
 
 /*
  * ISA I/O bus memory addresses are 1:1 with the physical address.
@@ -47,13 +48,85 @@
 extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen);
 extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
 
-#define __raw_writeb(v,a)	(__chk_io_ptr(a), *(volatile unsigned char __force  *)(a) = (v))
-#define __raw_writew(v,a)	(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))
-#define __raw_writel(v,a)	(__chk_io_ptr(a), *(volatile unsigned int __force   *)(a) = (v))
+/*
+ * There may be cases when clients don't want to support or can't support the
+ * logging. The appropriate functions can be used but clients should carefully
+ * consider why they can't support the logging.
+ */
 
-#define __raw_readb(a)		(__chk_io_ptr(a), *(volatile unsigned char __force  *)(a))
-#define __raw_readw(a)		(__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
-#define __raw_readl(a)		(__chk_io_ptr(a), *(volatile unsigned int __force   *)(a))
+#define __raw_writeb_no_log(v, a)	(__chk_io_ptr(a), *(volatile unsigned char __force  *)(a) = (v))
+#define __raw_writew_no_log(v, a)	(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))
+#define __raw_writel_no_log(v, a)	(__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v))
+
+#define __raw_writeb(v, a)	({ \
+	int _ret; \
+	void *_addr = (void *)(a); \
+	_ret = uncached_logk(LOGK_WRITEL, _addr); \
+	ETB_WAYPOINT; \
+	__raw_writeb_no_log(v, _addr); \
+	if (_ret) \
+		LOG_BARRIER; \
+	})
+
+#define __raw_writew(v, a)	({ \
+	int _ret; \
+	void *_addr = (void *)(a); \
+	_ret = uncached_logk(LOGK_WRITEL, _addr); \
+	ETB_WAYPOINT; \
+	__raw_writew_no_log(v, _addr); \
+	if (_ret) \
+		LOG_BARRIER; \
+	})
+
+#define __raw_writel(v, a)	({ \
+	int _ret; \
+	void *_addr = (void *)(a); \
+	_ret = uncached_logk(LOGK_WRITEL, _addr); \
+	ETB_WAYPOINT; \
+	__raw_writel_no_log(v, _addr); \
+	if (_ret) \
+		LOG_BARRIER; \
+	})
+
+#define __raw_readb_no_log(a)		(__chk_io_ptr(a), *(volatile unsigned char __force  *)(a))
+#define __raw_readw_no_log(a)		(__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
+#define __raw_readl_no_log(a)		(__chk_io_ptr(a), *(volatile unsigned int __force *)(a))
+
+#define __raw_readb(a)		({ \
+	unsigned char __a; \
+	void *_addr = (void *)(a); \
+	int _ret; \
+	_ret = uncached_logk(LOGK_READL, _addr); \
+	ETB_WAYPOINT; \
+	__a = __raw_readb_no_log(_addr);\
+	if (_ret) \
+		LOG_BARRIER; \
+	__a; \
+	})
+
+#define __raw_readw(a)		({ \
+	unsigned short __a; \
+	void *_addr = (void *)(a); \
+	int _ret; \
+	_ret = uncached_logk(LOGK_READL, _addr); \
+	ETB_WAYPOINT; \
+	__a = __raw_readw_no_log(_addr);\
+	if (_ret) \
+		LOG_BARRIER; \
+	__a; \
+	})
+
+#define __raw_readl(a)		({ \
+	unsigned int __a; \
+	void *_addr = (void *)(a); \
+	int _ret; \
+	_ret = uncached_logk(LOGK_READL, _addr); \
+	ETB_WAYPOINT; \
+	__a = __raw_readl_no_log(_addr);\
+	if (_ret) \
+		LOG_BARRIER; \
+	__a; \
+	})
 
 /*
  * Architecture ioremap implementation.
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 3f04ce0..904839b 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1705,6 +1705,13 @@
 	  used to decrypt data and perform secure operations on the behalf of
 	  the kernel.
 
+config MSM_PIL_GSS
+	tristate "GSS (Coretx A5) Boot Support"
+	depends on MSM_PIL
+	help
+	  Support for booting and shutting down Cortex A5 processors which run
+	  GPS subsystem firmware.
+
 config MSM_SCM
 	bool "Secure Channel Manager (SCM) support"
 	default n
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 939b036..19a316e 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -71,6 +71,7 @@
 obj-$(CONFIG_MSM_PIL_RIVA) += pil-riva.o
 obj-$(CONFIG_MSM_PIL_TZAPPS) += pil-tzapps.o
 obj-$(CONFIG_MSM_PIL_MODEM) += pil-modem.o
+obj-$(CONFIG_MSM_PIL_GSS) += pil-gss.o
 obj-$(CONFIG_ARCH_QSD8X50) += sirc.o
 obj-$(CONFIG_ARCH_FSM9XXX) += sirc-fsm9xxx.o
 obj-$(CONFIG_MSM_FIQ_SUPPORT) += fiq_glue.o
diff --git a/arch/arm/mach-msm/acpuclock-7201.c b/arch/arm/mach-msm/acpuclock-7201.c
index 23d03ef..6140559 100644
--- a/arch/arm/mach-msm/acpuclock-7201.c
+++ b/arch/arm/mach-msm/acpuclock-7201.c
@@ -369,34 +369,39 @@
 };
 
 #ifdef CONFIG_CPU_FREQ_MSM
-static struct cpufreq_frequency_table freq_table[20];
+static struct cpufreq_frequency_table freq_table[NR_CPUS][20];
 
 static void __init cpufreq_table_init(void)
 {
-	unsigned int i;
-	unsigned int freq_cnt = 0;
+	int cpu;
+	for_each_possible_cpu(cpu) {
+		unsigned int i, freq_cnt = 0;
 
-	/* Construct the freq_table table from acpu_freq_tbl since the
-	 * freq_table values need to match frequencies specified in
-	 * acpu_freq_tbl and acpu_freq_tbl needs to be fixed up during init.
-	 */
-	for (i = 0; acpu_freq_tbl[i].a11clk_khz != 0
-			&& freq_cnt < ARRAY_SIZE(freq_table)-1; i++) {
-		if (acpu_freq_tbl[i].use_for_scaling) {
-			freq_table[freq_cnt].index = freq_cnt;
-			freq_table[freq_cnt].frequency
-				= acpu_freq_tbl[i].a11clk_khz;
-			freq_cnt++;
+		/* Construct the freq_table table from acpu_freq_tbl since
+		 * the freq_table values need to match frequencies specified
+		 * in acpu_freq_tbl and acpu_freq_tbl needs to be fixed up
+		 * during init.
+		 */
+		for (i = 0; acpu_freq_tbl[i].a11clk_khz != 0
+				&& freq_cnt < ARRAY_SIZE(*freq_table)-1; i++) {
+			if (acpu_freq_tbl[i].use_for_scaling) {
+				freq_table[cpu][freq_cnt].index = freq_cnt;
+				freq_table[cpu][freq_cnt].frequency
+					= acpu_freq_tbl[i].a11clk_khz;
+				freq_cnt++;
+			}
 		}
+
+		/* freq_table not big enough to store all usable freqs. */
+		BUG_ON(acpu_freq_tbl[i].a11clk_khz != 0);
+
+		freq_table[cpu][freq_cnt].index = freq_cnt;
+		freq_table[cpu][freq_cnt].frequency = CPUFREQ_TABLE_END;
+		/* Register table with CPUFreq. */
+		cpufreq_frequency_table_get_attr(freq_table[cpu], cpu);
+		pr_info("CPU%d: %d scaling frequencies supported.\n",
+			cpu, freq_cnt);
 	}
-
-	/* freq_table not big enough to store all usable freqs. */
-	BUG_ON(acpu_freq_tbl[i].a11clk_khz != 0);
-
-	freq_table[freq_cnt].index = freq_cnt;
-	freq_table[freq_cnt].frequency = CPUFREQ_TABLE_END;
-
-	pr_info("%d scaling frequencies supported.\n", freq_cnt);
 }
 #endif
 
@@ -995,7 +1000,6 @@
 
 #ifdef CONFIG_CPU_FREQ_MSM
 	cpufreq_table_init();
-	cpufreq_frequency_table_get_attr(freq_table, smp_processor_id());
 #endif
 	return 0;
 }
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index 57f4a0a..de80a3e 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -21,6 +21,7 @@
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/gpiomux.h>
+#include <mach/socinfo.h>
 #include "devices.h"
 #include "board-8064.h"
 
@@ -34,17 +35,24 @@
 /* The SPI configurations apply to GSBI 5*/
 static struct gpiomux_setting gpio_spi_config = {
 	.func = GPIOMUX_FUNC_2,
-	.drv = GPIOMUX_DRV_8MA,
+	.drv = GPIOMUX_DRV_12MA,
 	.pull = GPIOMUX_PULL_NONE,
 };
 
 /* The SPI configurations apply to GSBI 5 chip select 2*/
 static struct gpiomux_setting gpio_spi_cs2_config = {
 	.func = GPIOMUX_FUNC_3,
-	.drv = GPIOMUX_DRV_8MA,
+	.drv = GPIOMUX_DRV_12MA,
 	.pull = GPIOMUX_PULL_NONE,
 };
 
+/* Chip selects for SPI clients */
+static struct gpiomux_setting gpio_spi_cs_config = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_12MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
 struct msm_gpiomux_config apq8064_ethernet_configs[] = {
 	{
 		.gpio = 43,
@@ -89,6 +97,45 @@
 	.pull = GPIOMUX_PULL_NONE,
 };
 
+static struct gpiomux_setting ext_regulator_config = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+	.dir = GPIOMUX_OUT_LOW,
+};
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+static struct gpiomux_setting hsic_act_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting hsic_sus_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_DOWN,
+	.dir = GPIOMUX_OUT_LOW,
+};
+
+static struct msm_gpiomux_config apq8064_hsic_configs[] = {
+	{
+		.gpio = 88,               /*HSIC_STROBE */
+		.settings = {
+			[GPIOMUX_ACTIVE] = &hsic_act_cfg,
+			[GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
+		},
+	},
+	{
+		.gpio = 89,               /* HSIC_DATA */
+		.settings = {
+			[GPIOMUX_ACTIVE] = &hsic_act_cfg,
+			[GPIOMUX_SUSPENDED] = &hsic_sus_cfg,
+		},
+	},
+};
+#endif
+
 static struct msm_gpiomux_config apq8064_gsbi_configs[] __initdata = {
 	{
 		.gpio      = 18,		/* GSBI1 UART TX */
@@ -116,6 +163,12 @@
 		},
 	},
 	{
+		.gpio      = 53,		/* Funny CS0 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
 		.gpio      = 31,		/* GSBI5 QUP SPI_CS2_N */
 		.settings = {
 			[GPIOMUX_SUSPENDED] = &gpio_spi_cs2_config,
@@ -128,6 +181,24 @@
 		},
 	},
 #endif
+	{
+		.gpio      = 30,		/* FP CS */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_cs_config,
+		},
+	},
+	{
+		.gpio      = 32,		/* EPM CS */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_cs_config,
+		},
+	},
+	{
+		.gpio      = 53,		/* NOR CS */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_cs_config,
+		},
+	},
 };
 
 static struct msm_gpiomux_config apq8064_slimbus_config[] __initdata = {
@@ -185,6 +256,78 @@
 	},
 };
 
+/* External 3.3 V regulator enable */
+static struct msm_gpiomux_config apq8064_ext_regulator_configs[] __initdata = {
+	{
+		.gpio = APQ8064_EXT_3P3V_REG_EN_GPIO,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &ext_regulator_config,
+		},
+	},
+};
+
+static struct gpiomux_setting ap2mdm_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting mdm2ap_status_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting mdm2ap_errfatal_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_16MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting ap2mdm_pon_reset_n_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct msm_gpiomux_config mdm_configs[] __initdata = {
+	/* AP2MDM_STATUS */
+	{
+		.gpio = 48,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
+		}
+	},
+	/* MDM2AP_STATUS */
+	{
+		.gpio = 49,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &mdm2ap_status_cfg,
+		}
+	},
+	/* MDM2AP_ERRFATAL */
+	{
+		.gpio = 19,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &mdm2ap_errfatal_cfg,
+		}
+	},
+	/* AP2MDM_ERRFATAL */
+	{
+		.gpio = 18,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &ap2mdm_cfg,
+		}
+	},
+	/* AP2MDM_PON_RESET_N */
+	{
+		.gpio = 27,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &ap2mdm_pon_reset_n_cfg,
+		}
+	}
+};
+
 void __init apq8064_init_gpiomux(void)
 {
 	int rc;
@@ -211,4 +354,16 @@
 
 	msm_gpiomux_install(apq8064_audio_auxpcm_configs,
 			ARRAY_SIZE(apq8064_audio_auxpcm_configs));
+
+	msm_gpiomux_install(apq8064_ext_regulator_configs,
+			ARRAY_SIZE(apq8064_ext_regulator_configs));
+
+	if (machine_is_apq8064_mtp())
+		msm_gpiomux_install(mdm_configs,
+			ARRAY_SIZE(mdm_configs));
+
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+	msm_gpiomux_install(apq8064_hsic_configs,
+			ARRAY_SIZE(apq8064_hsic_configs));
+#endif
 }
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index 2182079..5204e48 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, 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
@@ -15,15 +15,236 @@
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 #include <linux/bootmem.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
+#include <linux/leds.h>
+#include <linux/leds-pm8xxx.h>
+#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
 #include <asm/mach-types.h>
 #include <asm/mach/mmc.h>
 #include <mach/msm_bus_board.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/gpiomux.h>
+#include <mach/restart.h>
 #include "devices.h"
 #include "board-8064.h"
 
+struct pm8xxx_gpio_init {
+	unsigned			gpio;
+	struct pm_gpio			config;
+};
+
+struct pm8xxx_mpp_init {
+	unsigned			mpp;
+	struct pm8xxx_mpp_config_data	config;
+};
+
+#define PM8921_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
+			_func, _inv, _disable) \
+{ \
+	.gpio	= PM8921_GPIO_PM_TO_SYS(_gpio), \
+	.config	= { \
+		.direction	= _dir, \
+		.output_buffer	= _buf, \
+		.output_value	= _val, \
+		.pull		= _pull, \
+		.vin_sel	= _vin, \
+		.out_strength	= _out_strength, \
+		.function	= _func, \
+		.inv_int_pol	= _inv, \
+		.disable_pin	= _disable, \
+	} \
+}
+
+#define PM8921_MPP_INIT(_mpp, _type, _level, _control) \
+{ \
+	.mpp	= PM8921_MPP_PM_TO_SYS(_mpp), \
+	.config	= { \
+		.type		= PM8XXX_MPP_TYPE_##_type, \
+		.level		= _level, \
+		.control	= PM8XXX_MPP_##_control, \
+	} \
+}
+
+#define PM8821_MPP_INIT(_mpp, _type, _level, _control) \
+{ \
+	.mpp	= PM8821_MPP_PM_TO_SYS(_mpp), \
+	.config	= { \
+		.type		= PM8XXX_MPP_TYPE_##_type, \
+		.level		= _level, \
+		.control	= PM8XXX_MPP_##_control, \
+	} \
+}
+
+#define PM8921_GPIO_DISABLE(_gpio) \
+	PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, 0, PM_GPIO_VIN_S4, \
+			 0, 0, 0, 1)
+
+#define PM8921_GPIO_OUTPUT(_gpio, _val, _strength) \
+	PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+			PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
+			PM_GPIO_STRENGTH_##_strength, \
+			PM_GPIO_FUNC_NORMAL, 0, 0)
+
+#define PM8921_GPIO_INPUT(_gpio, _pull) \
+	PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, PM_GPIO_OUT_BUF_CMOS, 0, \
+			_pull, PM_GPIO_VIN_S4, \
+			PM_GPIO_STRENGTH_NO, \
+			PM_GPIO_FUNC_NORMAL, 0, 0)
+
+#define PM8921_GPIO_OUTPUT_FUNC(_gpio, _val, _func) \
+	PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+			PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
+			PM_GPIO_STRENGTH_HIGH, \
+			_func, 0, 0)
+
+#define PM8921_GPIO_OUTPUT_VIN(_gpio, _val, _vin) \
+	PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+			PM_GPIO_PULL_NO, _vin, \
+			PM_GPIO_STRENGTH_HIGH, \
+			PM_GPIO_FUNC_NORMAL, 0, 0)
+
+/* Initial PM8921 GPIO configurations */
+static struct pm8xxx_gpio_init pm8921_gpios[] __initdata = {
+};
+
+/* Initial PM8XXX MPP configurations */
+static struct pm8xxx_mpp_init pm8xxx_mpps[] __initdata = {
+	/* External 5V regulator enable; shared by HDMI and USB_OTG switches. */
+	PM8921_MPP_INIT(7, D_INPUT, PM8921_MPP_DIG_LEVEL_VPH, DIN_TO_INT),
+};
+
+void __init apq8064_pm8xxx_gpio_mpp_init(void)
+{
+	int i, rc;
+
+	for (i = 0; i < ARRAY_SIZE(pm8921_gpios); i++) {
+		rc = pm8xxx_gpio_config(pm8921_gpios[i].gpio,
+					&pm8921_gpios[i].config);
+		if (rc) {
+			pr_err("%s: pm8xxx_gpio_config: rc=%d\n", __func__, rc);
+			break;
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(pm8xxx_mpps); i++) {
+		rc = pm8xxx_mpp_config(pm8xxx_mpps[i].mpp,
+					&pm8xxx_mpps[i].config);
+		if (rc) {
+			pr_err("%s: pm8xxx_mpp_config: rc=%d\n", __func__, rc);
+			break;
+		}
+	}
+}
+
+static struct pm8xxx_pwrkey_platform_data apq8064_pm8921_pwrkey_pdata = {
+	.pull_up		= 1,
+	.kpd_trigger_delay_us	= 15625,
+	.wakeup			= 1,
+};
+
+static struct pm8xxx_misc_platform_data apq8064_pm8921_misc_pdata = {
+	.priority		= 0,
+};
+
+#define PM8921_LC_LED_MAX_CURRENT	4	/* I = 4mA */
+#define PM8921_LC_LED_LOW_CURRENT	1	/* I = 1mA */
+#define PM8XXX_LED_PWM_PERIOD		1000
+#define PM8XXX_LED_PWM_DUTY_MS		20
+/**
+ * PM8XXX_PWM_CHANNEL_NONE shall be used when LED shall not be
+ * driven using PWM feature.
+ */
+#define PM8XXX_PWM_CHANNEL_NONE		-1
+
+static struct led_info pm8921_led_info[] = {
+	[0] = {
+		.name			= "led:red",
+		.default_trigger	= "ac-online",
+	},
+};
+
+static struct led_platform_data pm8921_led_core_pdata = {
+	.num_leds = ARRAY_SIZE(pm8921_led_info),
+	.leds = pm8921_led_info,
+};
+
+static int pm8921_led0_pwm_duty_pcts[56] = {
+	1, 4, 8, 12, 16, 20, 24, 28, 32, 36,
+	40, 44, 46, 52, 56, 60, 64, 68, 72, 76,
+	80, 84, 88, 92, 96, 100, 100, 100, 98, 95,
+	92, 88, 84, 82, 78, 74, 70, 66, 62, 58,
+	58, 54, 50, 48, 42, 38, 34, 30, 26, 22,
+	14, 10, 6, 4, 1
+};
+
+static struct pm8xxx_pwm_duty_cycles pm8921_led0_pwm_duty_cycles = {
+	.duty_pcts = (int *)&pm8921_led0_pwm_duty_pcts,
+	.num_duty_pcts = ARRAY_SIZE(pm8921_led0_pwm_duty_pcts),
+	.duty_ms = PM8XXX_LED_PWM_DUTY_MS,
+	.start_idx = 0,
+};
+
+static struct pm8xxx_led_config pm8921_led_configs[] = {
+	[0] = {
+		.id = PM8XXX_ID_LED_0,
+		.mode = PM8XXX_LED_MODE_PWM2,
+		.max_current = PM8921_LC_LED_MAX_CURRENT,
+		.pwm_channel = 5,
+		.pwm_period_us = PM8XXX_LED_PWM_PERIOD,
+		.pwm_duty_cycles = &pm8921_led0_pwm_duty_cycles,
+	},
+};
+
+static struct pm8xxx_led_platform_data apq8064_pm8921_leds_pdata = {
+		.led_core = &pm8921_led_core_pdata,
+		.configs = pm8921_led_configs,
+		.num_configs = ARRAY_SIZE(pm8921_led_configs),
+};
+
+static struct pm8xxx_adc_amux apq8064_pm8921_adc_channels_data[] = {
+	{"vcoin", CHANNEL_VCOIN, CHAN_PATH_SCALING2, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"vbat", CHANNEL_VBAT, CHAN_PATH_SCALING2, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"dcin", CHANNEL_DCIN, CHAN_PATH_SCALING4, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"ichg", CHANNEL_ICHG, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"vph_pwr", CHANNEL_VPH_PWR, CHAN_PATH_SCALING2, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"ibat", CHANNEL_IBAT, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"batt_therm", CHANNEL_BATT_THERM, CHAN_PATH_SCALING1, AMUX_RSV2,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_BATT_THERM},
+	{"batt_id", CHANNEL_BATT_ID, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"usbin", CHANNEL_USBIN, CHAN_PATH_SCALING3, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"pmic_therm", CHANNEL_DIE_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_PMIC_THERM},
+	{"625mv", CHANNEL_625MV, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"125v", CHANNEL_125V, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"chg_temp", CHANNEL_CHG_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
+	{"xo_therm", CHANNEL_MUXOFF, CHAN_PATH_SCALING1, AMUX_RSV0,
+		ADC_DECIMATION_TYPE2, ADC_SCALE_XOTHERM},
+};
+
+static struct pm8xxx_adc_properties apq8064_pm8921_adc_data = {
+	.adc_vdd_reference	= 1800, /* milli-voltage for this adc */
+	.bitresolution		= 15,
+	.bipolar                = 0,
+};
+
+static struct pm8xxx_adc_platform_data apq8064_pm8921_adc_pdata = {
+	.adc_channel		= apq8064_pm8921_adc_channels_data,
+	.adc_num_board_channel	= ARRAY_SIZE(apq8064_pm8921_adc_channels_data),
+	.adc_prop		= &apq8064_pm8921_adc_data,
+	.adc_mpp_base		= PM8921_MPP_PM_TO_SYS(1),
+};
 
 static struct pm8xxx_mpp_platform_data
 apq8064_pm8921_mpp_pdata __devinitdata = {
@@ -49,6 +270,48 @@
 	.rtc_alarm_powerup      = false,
 };
 
+static int apq8064_pm8921_therm_mitigation[] = {
+	1100,
+	700,
+	600,
+	325,
+};
+
+#define MAX_VOLTAGE_MV          4200
+static struct pm8921_charger_platform_data
+apq8064_pm8921_chg_pdata __devinitdata = {
+	.safety_time		= 180,
+	.update_time		= 60000,
+	.max_voltage		= MAX_VOLTAGE_MV,
+	.min_voltage		= 3200,
+	.resume_voltage_delta	= 100,
+	.term_current		= 100,
+	.cool_temp		= 10,
+	.warm_temp		= 40,
+	.temp_check_period	= 1,
+	.max_bat_chg_current	= 1100,
+	.cool_bat_chg_current	= 350,
+	.warm_bat_chg_current	= 350,
+	.cool_bat_voltage	= 4100,
+	.warm_bat_voltage	= 4100,
+	.thermal_mitigation	= apq8064_pm8921_therm_mitigation,
+	.thermal_levels		= ARRAY_SIZE(apq8064_pm8921_therm_mitigation),
+};
+
+static struct pm8xxx_ccadc_platform_data
+apq8064_pm8xxx_ccadc_pdata = {
+	.r_sense		= 10,
+};
+
+static struct pm8921_bms_platform_data
+apq8064_pm8921_bms_pdata __devinitdata = {
+	.r_sense		= 10,
+	.i_test			= 2500,
+	.v_failure		= 3000,
+	.calib_delay_ms		= 600000,
+	.max_voltage_uv		= MAX_VOLTAGE_MV * 1000,
+};
+
 static struct pm8921_platform_data
 apq8064_pm8921_platform_data __devinitdata = {
 	.regulator_pdatas	= msm8064_pm8921_regulator_pdata,
@@ -56,12 +319,19 @@
 	.gpio_pdata		= &apq8064_pm8921_gpio_pdata,
 	.mpp_pdata		= &apq8064_pm8921_mpp_pdata,
 	.rtc_pdata		= &apq8064_pm8921_rtc_pdata,
+	.pwrkey_pdata		= &apq8064_pm8921_pwrkey_pdata,
+	.misc_pdata		= &apq8064_pm8921_misc_pdata,
+	.leds_pdata		= &apq8064_pm8921_leds_pdata,
+	.adc_pdata		= &apq8064_pm8921_adc_pdata,
+	.charger_pdata		= &apq8064_pm8921_chg_pdata,
+	.bms_pdata		= &apq8064_pm8921_bms_pdata,
+	.ccadc_pdata		= &apq8064_pm8xxx_ccadc_pdata,
 };
 
 static struct pm8xxx_irq_platform_data
 apq8064_pm8821_irq_pdata __devinitdata = {
 	.irq_base		= PM8821_IRQ_BASE,
-	.devirq			= PM8821_USR_IRQ_N,
+	.devirq			= PM8821_SEC_IRQ_N,
 	.irq_trigger_flag	= IRQF_TRIGGER_HIGH,
 	.dev_id			= 1,
 };
@@ -95,6 +365,8 @@
 
 void __init apq8064_init_pmic(void)
 {
+	pmic_reset_irq = PM8921_IRQ_BASE + PM8921_RESOUT_IRQ;
+
 	apq8064_device_ssbi_pmic1.dev.platform_data =
 						&apq8064_ssbi_pm8921_pdata;
 	apq8064_device_ssbi_pmic2.dev.platform_data =
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 7267f96..f3eebce 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -129,6 +129,7 @@
 	REGULATOR_SUPPLY("HSUSB_VDDCX",		"msm_otg"),
 	REGULATOR_SUPPLY("HSUSB_VDDCX",		"msm_ehci_host.0"),
 	REGULATOR_SUPPLY("HSUSB_VDDCX",		"msm_ehci_host.1"),
+	REGULATOR_SUPPLY("HSIC_VDDCX",		"msm_hsic_host"),
 	REGULATOR_SUPPLY("riva_vddcx",		"wcnss_wlan.0"),
 };
 VREG_CONSUMERS(S4) = {
@@ -179,6 +180,7 @@
 };
 VREG_CONSUMERS(USB_OTG) = {
 	REGULATOR_SUPPLY("8921_usb_otg",	NULL),
+	REGULATOR_SUPPLY("vbus_otg",		"msm_otg"),
 };
 VREG_CONSUMERS(HDMI_MVS) = {
 	REGULATOR_SUPPLY("8921_hdmi_mvs",	NULL),
@@ -194,6 +196,14 @@
 	REGULATOR_SUPPLY("8821_s1",		NULL),
 	REGULATOR_SUPPLY("krait3",		NULL),
 };
+VREG_CONSUMERS(EXT_5V) = {
+	REGULATOR_SUPPLY("ext_5v",		NULL),
+};
+VREG_CONSUMERS(EXT_3P3V) = {
+	REGULATOR_SUPPLY("ext_3p3v",		NULL),
+	REGULATOR_SUPPLY("vdd_io",		"spi0.2"),
+	REGULATOR_SUPPLY("mhl_ext_3p3v",	"msm_otg"),
+};
 
 #define PM8XXX_VREG_INIT(_id, _name, _min_uV, _max_uV, _modes, _ops, \
 			 _apply_uV, _pull_down, _always_on, _supply_regulator, \
@@ -290,6 +300,22 @@
 		.pin_ctrl	= _pin_ctrl, \
 	}
 
+#define GPIO_VREG(_id, _reg_name, _gpio_label, _gpio, _supply_regulator) \
+	[GPIO_VREG_ID_##_id] = { \
+		.init_data = { \
+			.constraints = { \
+				.valid_ops_mask	= REGULATOR_CHANGE_STATUS, \
+			}, \
+			.num_consumer_supplies	= \
+					ARRAY_SIZE(vreg_consumers_##_id), \
+			.consumer_supplies	= vreg_consumers_##_id, \
+			.supply_regulator	= _supply_regulator, \
+		}, \
+		.regulator_name = _reg_name, \
+		.gpio_label	= _gpio_label, \
+		.gpio		= _gpio, \
+	}
+
 #define SAW_VREG_INIT(_id, _name, _min_uV, _max_uV) \
 	{ \
 		.constraints = { \
@@ -302,6 +328,15 @@
 		.consumer_supplies	= vreg_consumers_##_id, \
 	}
 
+/* GPIO regulator constraints */
+struct gpio_regulator_platform_data
+apq8064_gpio_regulator_pdata[] __devinitdata = {
+	/*        ID      vreg_name gpio_label   gpio                  supply */
+	GPIO_VREG(EXT_5V, "ext_5v", "ext_5v_en", PM8921_MPP_PM_TO_SYS(7), NULL),
+	GPIO_VREG(EXT_3P3V, "ext_3p3v", "ext_3p3v_en",
+		  APQ8064_EXT_3P3V_REG_EN_GPIO, NULL),
+};
+
 /* SAW regulator constraints */
 struct regulator_init_data msm8064_saw_regulator_pdata_8921_s5 =
 	/*	      ID  vreg_name	       min_uV   max_uV */
@@ -329,7 +364,7 @@
 		3),
 	PM8XXX_SMPS(S4, "8921_s4",  1, 1, 1800000, 1800000, 500, NULL, 100000,
 		4),
-	PM8XXX_SMPS(S7, "8921_s7",  0, 1, 1200000, 1200000, 500, NULL, 100000,
+	PM8XXX_SMPS(S7, "8921_s7",  0, 1, 1300000, 1300000, 500, NULL, 100000,
 		5),
 
 	PM8XXX_LDO(L1,  "8921_l1",  1, 1, 1100000, 1100000, 200, "8921_s4", 0,
@@ -337,10 +372,11 @@
 	PM8XXX_LDO(L2,  "8921_l2",  0, 1, 1200000, 1200000, 200, "8921_s4", 0,
 		7),
 	PM8XXX_LDO(L3,  "8921_l3",  0, 1, 3075000, 3075000, 200, NULL, 0, 8),
-	PM8XXX_LDO(L4,  "8921_l4",  1, 1, 1800000, 1800000, 200, NULL, 0, 9),
+	PM8XXX_LDO(L4,  "8921_l4",  1, 1, 1800000, 1800000, 200, NULL, 10000,
+		9),
 	PM8XXX_LDO(L5,  "8921_l5",  0, 1, 2950000, 2950000, 200, NULL, 0, 10),
 	PM8XXX_LDO(L6,  "8921_l6",  0, 1, 2950000, 2950000, 200, NULL, 0, 11),
-	PM8XXX_LDO(L7,  "8921_l7",  1, 1, 1850000, 2950000, 200, NULL, 0, 12),
+	PM8XXX_LDO(L7,  "8921_l7",  0, 1, 1850000, 2950000, 200, NULL, 0, 12),
 	PM8XXX_LDO(L8,  "8921_l8",  0, 1, 2800000, 2800000, 200, NULL, 0, 13),
 	PM8XXX_LDO(L9,  "8921_l9",  0, 1, 2850000, 2850000, 200, NULL, 0, 14),
 	PM8XXX_LDO(L10, "8921_l10", 0, 1, 2900000, 2900000, 200, NULL, 0, 15),
@@ -358,10 +394,10 @@
 	PM8XXX_NLDO1200(L24, "8921_l24", 1, 1, 1150000, 1150000, 200, "8921_s1",
 		10000, 25),
 	PM8XXX_NLDO1200(L25, "8921_l25", 1, 1, 1225000, 1225000, 200, "8921_s1",
-		0, 26),
+		10000, 26),
 	PM8XXX_NLDO1200(L26, "8921_l26", 0, 1, 1050000, 1050000, 200, "8921_s7",
 		0, 27),
-	PM8XXX_NLDO1200(L27, "8921_l27", 0, 1, 1000000, 1000000, 200, "8921_s7",
+	PM8XXX_NLDO1200(L27, "8921_l27", 0, 1, 1100000, 1100000, 200, "8921_s7",
 		0, 28),
 	PM8XXX_NLDO1200(L28, "8921_l28", 0, 1, 1050000, 1050000, 200, "8921_s7",
 		0, 29),
@@ -375,8 +411,8 @@
 	PM8XXX_VS(LVS6,    "8921_lvs6", 0, 1,                 0, "8921_s4", 35),
 	PM8XXX_VS(LVS7,    "8921_lvs7", 1, 1,                 0, "8921_s4", 36),
 
-	PM8XXX_VS300(USB_OTG,  "8921_usb_otg",  0, 1,         0, NULL, 37),
-	PM8XXX_VS300(HDMI_MVS, "8921_hdmi_mvs", 0, 1,         0, NULL, 38),
+	PM8XXX_VS300(USB_OTG,  "8921_usb_otg",  0, 0,         0, "ext_5v", 37),
+	PM8XXX_VS300(HDMI_MVS, "8921_hdmi_mvs", 0, 1,         0, "ext_5v", 38),
 
 	/*         ID   name  always_on   min_uV   max_uV  en_t supply reg_ID */
 	PM8XXX_NCP(NCP,	"8921_ncp", 0,    1800000, 1800000, 200, "8921_l6", 39),
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index a95d733..febc55d 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -50,6 +50,7 @@
 #include <mach/dma.h>
 #include <mach/msm_bus_board.h>
 #include <mach/cpuidle.h>
+#include <mach/mdm2.h>
 
 #include "msm_watchdog.h"
 #include "board-8064.h"
@@ -374,15 +375,85 @@
 	msm_reserve();
 }
 
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
+static struct msm_hsic_host_platform_data msm_hsic_pdata = {
+	.strobe		= 88,
+	.data		= 89,
+};
+#else
+static struct msm_hsic_host_platform_data msm_hsic_pdata;
+#endif
+
+#define PID_MAGIC_ID		0x71432909
+#define SERIAL_NUM_MAGIC_ID	0x61945374
+#define SERIAL_NUMBER_LENGTH	127
+#define DLOAD_USB_BASE_ADD	0x2A03F0C8
+
+struct magic_num_struct {
+	uint32_t pid;
+	uint32_t serial_num;
+};
+
+struct dload_struct {
+	uint32_t	reserved1;
+	uint32_t	reserved2;
+	uint32_t	reserved3;
+	uint16_t	reserved4;
+	uint16_t	pid;
+	char		serial_number[SERIAL_NUMBER_LENGTH];
+	uint16_t	reserved5;
+	struct magic_num_struct magic_struct;
+};
+
+static int usb_diag_update_pid_and_serial_num(uint32_t pid, const char *snum)
+{
+	struct dload_struct __iomem *dload = 0;
+
+	dload = ioremap(DLOAD_USB_BASE_ADD, sizeof(*dload));
+	if (!dload) {
+		pr_err("%s: cannot remap I/O memory region: %08x\n",
+					__func__, DLOAD_USB_BASE_ADD);
+		return -ENXIO;
+	}
+
+	pr_debug("%s: dload:%p pid:%x serial_num:%s\n",
+				__func__, dload, pid, snum);
+	/* update pid */
+	dload->magic_struct.pid = PID_MAGIC_ID;
+	dload->pid = pid;
+
+	/* update serial number */
+	dload->magic_struct.serial_num = 0;
+	if (!snum) {
+		memset(dload->serial_number, 0, SERIAL_NUMBER_LENGTH);
+		goto out;
+	}
+
+	dload->magic_struct.serial_num = SERIAL_NUM_MAGIC_ID;
+	strlcpy(dload->serial_number, snum, SERIAL_NUMBER_LENGTH);
+out:
+	iounmap(dload);
+	return 0;
+}
+
+static struct android_usb_platform_data android_usb_pdata = {
+	.update_pid_and_serial_num = usb_diag_update_pid_and_serial_num,
+};
+
 static struct platform_device android_usb_device = {
-	.name = "android_usb",
-	.id = -1,
+	.name	= "android_usb",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &android_usb_pdata,
+	},
 };
 
 static struct msm_otg_platform_data msm_otg_pdata = {
-	.mode			= USB_PERIPHERAL,
-	.otg_control		= OTG_PHY_CONTROL,
+	.mode			= USB_OTG,
+	.otg_control		= OTG_PMIC_CONTROL,
 	.phy_type		= SNPS_28NM_INTEGRATED_PHY,
+	.pmic_id_irq		= PM8921_USB_ID_IN_IRQ(PM8921_IRQ_BASE),
+	.power_budget		= 750,
 };
 
 #define TABLA_INTERRUPT_BASE (NR_MSM_IRQS + NR_GPIO_IRQS + NR_PM8921_IRQS)
@@ -567,6 +638,11 @@
 };
 #endif
 
+static struct mdm_platform_data mdm_platform_data = {
+	.mdm_version = "3.0",
+	.ramdump_delay_ms = 2000,
+	.peripheral_platform_device = &apq8064_device_hsic_host,
+};
 
 #define MSM_SHARED_RAM_PHYS 0x80000000
 static void __init apq8064_map_io(void)
@@ -1006,16 +1082,38 @@
 	msm_bus_8064_cpss_fpb.dev.platform_data = &msm_bus_8064_cpss_fpb_pdata;
 }
 
+static struct platform_device apq8064_device_ext_5v_vreg __devinitdata = {
+	.name	= GPIO_REGULATOR_DEV_NAME,
+	.id	= PM8921_MPP_PM_TO_SYS(7),
+	.dev	= {
+		.platform_data
+			= &apq8064_gpio_regulator_pdata[GPIO_VREG_ID_EXT_5V],
+	},
+};
+
+static struct platform_device apq8064_device_ext_3p3v_vreg __devinitdata = {
+	.name	= GPIO_REGULATOR_DEV_NAME,
+	.id	= APQ8064_EXT_3P3V_REG_EN_GPIO,
+	.dev	= {
+		.platform_data =
+			&apq8064_gpio_regulator_pdata[GPIO_VREG_ID_EXT_3P3V],
+	},
+};
+
 static struct platform_device *common_devices[] __initdata = {
 	&apq8064_device_dmov,
 	&apq8064_device_qup_i2c_gsbi4,
 	&apq8064_device_qup_spi_gsbi5,
 	&apq8064_slim_ctrl,
+	&apq8064_device_ext_5v_vreg,
+	&apq8064_device_ext_3p3v_vreg,
 	&apq8064_device_ssbi_pmic1,
 	&apq8064_device_ssbi_pmic2,
 	&msm_device_smd_apq8064,
 	&apq8064_device_otg,
 	&apq8064_device_gadget_peripheral,
+	&apq8064_device_hsusb_host,
+	&apq8064_device_hsic_host,
 	&android_usb_device,
 #ifdef CONFIG_ANDROID_PMEM
 #ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
@@ -1078,6 +1176,7 @@
 	&msm_device_vidc,
 	&msm_8960_riva,
 	&msm_8960_q6_lpass,
+	&msm_gss,
 };
 
 static struct platform_device *sim_devices[] __initdata = {
@@ -1099,7 +1198,7 @@
 };
 
 static struct msm_spi_platform_data apq8064_qup_spi_gsbi5_pdata = {
-	.max_clock_speed = 24000000,
+	.max_clock_speed = 1100000,
 };
 
 #define KS8851_IRQ_GPIO		43
@@ -1138,7 +1237,7 @@
 					&apq8064_i2c_qup_gsbi4_pdata;
 }
 
-#ifdef CONFIG_KS8851
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
 static int ethernet_init(void)
 {
 	int ret;
@@ -1180,9 +1279,13 @@
 	apq8064_device_qup_spi_gsbi5.dev.platform_data =
 						&apq8064_qup_spi_gsbi5_pdata;
 	apq8064_init_pmic();
+	if (machine_is_apq8064_liquid())
+		msm_otg_pdata.mhl_enable = true;
 	apq8064_device_otg.dev.platform_data = &msm_otg_pdata;
+	apq8064_device_hsic_host.dev.platform_data = &msm_hsic_pdata;
 	apq8064_init_buses();
 	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
+	apq8064_pm8xxx_gpio_mpp_init();
 	apq8064_init_mmc();
 	slim_register_board_info(apq8064_slim_devices,
 		ARRAY_SIZE(apq8064_slim_devices));
@@ -1195,6 +1298,10 @@
 				msm_pm_data);
 	BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
 
+	if (machine_is_apq8064_mtp()) {
+		mdm_8064_device.dev.platform_data = &mdm_platform_data;
+		platform_device_register(&mdm_8064_device);
+	}
 }
 
 static void __init apq8064_allocate_memory_regions(void)
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index 4735504..e1451f5 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -13,9 +13,12 @@
 #ifndef __ARCH_ARM_MACH_MSM_BOARD_APQ8064_H
 #define __ARCH_ARM_MACH_MSM_BOARD_APQ8064_H
 
+#include <linux/regulator/gpio-regulator.h>
 #include <linux/mfd/pm8xxx/pm8921.h>
 #include <linux/mfd/pm8xxx/pm8821.h>
 #include <mach/msm_memtypes.h>
+#include <mach/irqs.h>
+
 /* Macros assume PMIC GPIOs and MPPs start at 1 */
 #define PM8921_GPIO_BASE		NR_GPIO_IRQS
 #define PM8921_GPIO_PM_TO_SYS(pm_gpio)	(pm_gpio - 1 + PM8921_GPIO_BASE)
@@ -32,6 +35,14 @@
 
 extern int msm8064_pm8921_regulator_pdata_len __devinitdata;
 
+#define GPIO_VREG_ID_EXT_5V		0
+#define GPIO_VREG_ID_EXT_3P3V		1
+
+#define APQ8064_EXT_3P3V_REG_EN_GPIO	77
+
+extern struct gpio_regulator_platform_data
+	apq8064_gpio_regulator_pdata[] __devinitdata;
+
 extern struct regulator_init_data msm8064_saw_regulator_pdata_8921_s5;
 extern struct regulator_init_data msm8064_saw_regulator_pdata_8921_s6;
 extern struct regulator_init_data msm8064_saw_regulator_pdata_8821_s0;
@@ -54,5 +65,6 @@
 void apq8064_mdp_writeback(struct memtype_reserve *reserve_table);
 
 void apq8064_init_gpu(void);
+void apq8064_pm8xxx_gpio_mpp_init(void);
 
 #endif
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
index 30c912e..8212e15 100644
--- a/arch/arm/mach-msm/board-8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -495,6 +495,34 @@
 };
 #endif
 
+static struct camera_vreg_t msm_8930_s5k3l1yx_vreg[] = {
+	{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+	{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+	{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+	{"cam_vio", REG_VS, 0, 0, 0},
+	{"cam_vaf", REG_LDO, 2800000, 2800000, 300000},
+};
+
+static struct msm_camera_sensor_flash_data flash_s5k3l1yx = {
+	.flash_type = MSM_CAMERA_FLASH_NONE,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_s5k3l1yx = {
+	.mount_angle  = 0,
+	.cam_vreg = msm_8930_s5k3l1yx_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8930_s5k3l1yx_vreg),
+	.gpio_conf = &msm_8930_back_cam_gpio_conf,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_s5k3l1yx_data = {
+	.sensor_name          = "s5k3l1yx",
+	.pdata                = &msm_camera_csi_device_data[0],
+	.flash_data           = &flash_s5k3l1yx,
+	.sensor_platform_info = &sensor_board_info_s5k3l1yx,
+	.csi_if               = 1,
+	.camera_type          = BACK_CAMERA_2D,
+};
+
 void __init msm8930_init_cam(void)
 {
 	msm_gpiomux_install(msm8930_cam_common_configs,
@@ -527,6 +555,10 @@
 	I2C_BOARD_INFO("mt9m114", 0x48),
 	.platform_data = &msm_camera_sensor_mt9m114_data,
 	},
+	{
+	I2C_BOARD_INFO("s5k3l1yx", 0x20),
+	.platform_data = &msm_camera_sensor_s5k3l1yx_data,
+	},
 #ifdef CONFIG_MSM_CAMERA_FLASH_SC628A
 	{
 	I2C_BOARD_INFO("sc628a", 0x6E),
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
index f55125c..d871e04 100644
--- a/arch/arm/mach-msm/board-8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -228,6 +228,11 @@
 			pr_err("enable l2 failed, rc=%d\n", rc);
 			return -ENODEV;
 		}
+		usleep(10000);
+		gpio_set_value(DISP_RST_GPIO, 1);
+		usleep(10);
+		gpio_set_value(DISP_RST_GPIO, 0);
+		usleep(20);
 		gpio_set_value(DISP_RST_GPIO, 1);
 	} else {
 
@@ -486,6 +491,7 @@
 	.fpga_3d_config_addr  = FPGA_3D_GPIO_CONFIG_ADDR,
 	.fpga_ctrl_mode = FPGA_SPI_INTF,
 	.phy_ctrl_settings = &dsi_novatek_cmd_mode_phy_db,
+	.dlane_swap = 0x1,
 };
 
 static struct platform_device mipi_dsi_novatek_panel_device = {
diff --git a/arch/arm/mach-msm/board-8930-regulator.c b/arch/arm/mach-msm/board-8930-regulator.c
index 0208631..2f9fdcd 100644
--- a/arch/arm/mach-msm/board-8930-regulator.c
+++ b/arch/arm/mach-msm/board-8930-regulator.c
@@ -33,6 +33,7 @@
 	REGULATOR_SUPPLY("mipi_csi_vdd",	"4-001a"),
 	REGULATOR_SUPPLY("mipi_csi_vdd",	"4-006c"),
 	REGULATOR_SUPPLY("mipi_csi_vdd",	"4-0048"),
+	REGULATOR_SUPPLY("mipi_csi_vdd",        "4-0020"),
 };
 VREG_CONSUMERS(L3) = {
 	REGULATOR_SUPPLY("8038_l3",		NULL),
@@ -68,6 +69,8 @@
 	REGULATOR_SUPPLY("cam_vaf",		"4-001a"),
 	REGULATOR_SUPPLY("cam_vaf",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vaf",		"4-0048"),
+	REGULATOR_SUPPLY("cam_vana",            "4-0020"),
+	REGULATOR_SUPPLY("cam_vaf",             "4-0020"),
 };
 VREG_CONSUMERS(L10) = {
 	REGULATOR_SUPPLY("8038_l10",		NULL),
@@ -88,6 +91,7 @@
 	REGULATOR_SUPPLY("cam_vdig",		"4-001a"),
 	REGULATOR_SUPPLY("cam_vdig",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vdig",		"4-0048"),
+	REGULATOR_SUPPLY("cam_vdig",            "4-0020"),
 };
 VREG_CONSUMERS(L14) = {
 	REGULATOR_SUPPLY("8038_l14",		NULL),
@@ -108,6 +112,7 @@
 	REGULATOR_SUPPLY("cam_vio",		"4-001a"),
 	REGULATOR_SUPPLY("cam_vio",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vio",		"4-0048"),
+	REGULATOR_SUPPLY("cam_vio",             "4-0020"),
 };
 VREG_CONSUMERS(L19) = {
 	REGULATOR_SUPPLY("8038_l19",		NULL),
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index 2995679..6c292a4 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -500,6 +500,34 @@
 };
 #endif
 
+static struct camera_vreg_t msm_8960_s5k3l1yx_vreg[] = {
+	{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+	{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+	{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+	{"cam_vio", REG_VS, 0, 0, 0},
+	{"cam_vaf", REG_LDO, 2800000, 2800000, 300000},
+};
+
+static struct msm_camera_sensor_flash_data flash_s5k3l1yx = {
+	.flash_type = MSM_CAMERA_FLASH_NONE,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_s5k3l1yx = {
+	.mount_angle  = 0,
+	.cam_vreg = msm_8960_s5k3l1yx_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8960_s5k3l1yx_vreg),
+	.gpio_conf = &msm_8960_back_cam_gpio_conf,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_s5k3l1yx_data = {
+	.sensor_name          = "s5k3l1yx",
+	.pdata                = &msm_camera_csi_device_data[0],
+	.flash_data           = &flash_s5k3l1yx,
+	.sensor_platform_info = &sensor_board_info_s5k3l1yx,
+	.csi_if               = 1,
+	.camera_type          = BACK_CAMERA_2D,
+};
+
 static struct pm8xxx_mpp_config_data privacy_light_on_config = {
 	.type		= PM8XXX_MPP_TYPE_SINK,
 	.level		= PM8XXX_MPP_CS_OUT_5MA,
@@ -580,6 +608,10 @@
 	I2C_BOARD_INFO("mt9m114", 0x48),
 	.platform_data = &msm_camera_sensor_mt9m114_data,
 	},
+	{
+	I2C_BOARD_INFO("s5k3l1yx", 0x20),
+	.platform_data = &msm_camera_sensor_s5k3l1yx_data,
+	},
 #ifdef CONFIG_MSM_CAMERA_FLASH_SC628A
 	{
 	I2C_BOARD_INFO("sc628a", 0x6E),
diff --git a/arch/arm/mach-msm/board-8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
index 04376bc..0375b84 100644
--- a/arch/arm/mach-msm/board-8960-pmic.c
+++ b/arch/arm/mach-msm/board-8960-pmic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, 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
@@ -98,6 +98,7 @@
 	PM8XXX_GPIO_OUTPUT_VIN(21, 1, PM_GPIO_VIN_VPH),	 /* Backlight Enable */
 	PM8XXX_GPIO_DISABLE(22),			 /* Disable NFC */
 	PM8XXX_GPIO_OUTPUT_FUNC(24, 0, PM_GPIO_FUNC_2),	 /* Bl: Off, PWM mode */
+	PM8XXX_GPIO_OUTPUT_FUNC(25, 0, PM_GPIO_FUNC_2),	 /* TN_CLK */
 	PM8XXX_GPIO_INPUT(26,	    PM_GPIO_PULL_UP_30), /* SD_CARD_DET_N */
 	PM8XXX_GPIO_OUTPUT(43,	    PM_GPIO_PULL_UP_30), /* DISP_RESET_N */
 	PM8XXX_GPIO_OUTPUT(42, 0),                      /* USB 5V reg enable */
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index 6819d5d..0f05af5 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -33,6 +33,7 @@
 	REGULATOR_SUPPLY("mipi_csi_vdd",	"4-001a"),
 	REGULATOR_SUPPLY("mipi_csi_vdd",	"4-006c"),
 	REGULATOR_SUPPLY("mipi_csi_vdd",	"4-0048"),
+	REGULATOR_SUPPLY("mipi_csi_vdd",	"4-0020"),
 };
 VREG_CONSUMERS(L3) = {
 	REGULATOR_SUPPLY("8921_l3",		NULL),
@@ -74,12 +75,14 @@
 	REGULATOR_SUPPLY("cam_vana",		"4-001a"),
 	REGULATOR_SUPPLY("cam_vana",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vana",		"4-0048"),
+	REGULATOR_SUPPLY("cam_vana",		"4-0020"),
 };
 VREG_CONSUMERS(L12) = {
 	REGULATOR_SUPPLY("8921_l12",		NULL),
 	REGULATOR_SUPPLY("cam_vdig",		"4-001a"),
 	REGULATOR_SUPPLY("cam_vdig",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vdig",		"4-0048"),
+	REGULATOR_SUPPLY("cam_vdig",		"4-0020"),
 };
 VREG_CONSUMERS(L14) = {
 	REGULATOR_SUPPLY("8921_l14",		NULL),
@@ -93,6 +96,7 @@
 	REGULATOR_SUPPLY("cam_vaf",		"4-001a"),
 	REGULATOR_SUPPLY("cam_vaf",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vaf",		"4-0048"),
+	REGULATOR_SUPPLY("cam_vaf",		"4-0020"),
 };
 VREG_CONSUMERS(L17) = {
 	REGULATOR_SUPPLY("8921_l17",		NULL),
@@ -207,6 +211,7 @@
 	REGULATOR_SUPPLY("cam_vio",		"4-001a"),
 	REGULATOR_SUPPLY("cam_vio",		"4-006c"),
 	REGULATOR_SUPPLY("cam_vio",		"4-0048"),
+	REGULATOR_SUPPLY("cam_vio",		"4-0020"),
 };
 VREG_CONSUMERS(LVS6) = {
 	REGULATOR_SUPPLY("8921_lvs6",		NULL),
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index 030c129..15f681d 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -226,6 +226,9 @@
 	} else if (machine_is_msm7627a_qrd1()) {
 		if (!strncmp(name, "mipi_video_truly_wvga", 21))
 			ret = 0;
+	} else if (machine_is_msm7627a_evb()) {
+		if (!strncmp(name, "mipi_cmd_nt35510_wvga", 21))
+			ret = 0;
 	}
 
 #if !defined(CONFIG_FB_MSM_LCDC_AUTO_DETECT) && \
@@ -303,6 +306,18 @@
 	}
 };
 
+static struct msm_panel_common_pdata mipi_NT35510_pdata = {
+	.pmic_backlight = NULL,/*mipi_NT35510_set_bl,*/
+};
+
+static struct platform_device mipi_dsi_NT35510_panel_device = {
+	.name = "mipi_NT35510",
+	.id   = 0,
+	.dev  = {
+		.platform_data = &mipi_NT35510_pdata,
+	}
+};
+
 static struct platform_device *msm_fb_devices[] __initdata = {
 	&msm_fb_device,
 	&lcdc_toshiba_panel_device,
@@ -317,7 +332,8 @@
 };
 
 static struct platform_device *evb_fb_devices[] __initdata = {
-
+	&msm_fb_device,
+	&mipi_dsi_NT35510_panel_device,
 };
 
 void __init msm_msm7627a_allocate_memory_regions(void)
@@ -487,12 +503,60 @@
 	return rc;
 }
 
+#define GPIO_QRD3_LCD_BRDG_RESET_N	85
+#define GPIO_QRD3_LCD_BACKLIGHT_EN	96
+#define GPIO_QRD3_LCD_EXT_2V85_EN	35
+#define GPIO_QRD3_LCD_EXT_1V8_EN	40
+
+static unsigned qrd3_mipi_dsi_gpio[] = {
+	GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
+			GPIO_CFG_NO_PULL,
+			GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BRDG_RESET_N */
+	GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0, GPIO_CFG_OUTPUT,
+			GPIO_CFG_NO_PULL,
+			GPIO_CFG_2MA), /* GPIO_QRD3_LCD_BACKLIGHT_EN */
+	GPIO_CFG(GPIO_QRD3_LCD_EXT_2V85_EN, 0, GPIO_CFG_OUTPUT,
+			GPIO_CFG_NO_PULL,
+			GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_2V85_EN */
+	GPIO_CFG(GPIO_QRD3_LCD_EXT_1V8_EN, 0, GPIO_CFG_OUTPUT,
+			GPIO_CFG_NO_PULL,
+			GPIO_CFG_2MA), /* GPIO_QRD3_LCD_EXT_1V8_EN */
+};
+
+static int msm_fb_dsi_client_qrd3_reset(void)
+{
+	int rc = 0;
+
+	rc = gpio_request(GPIO_QRD3_LCD_BRDG_RESET_N, "qrd3_lcd_brdg_reset_n");
+	if (rc < 0) {
+		pr_err("failed to request qrd3 lcd brdg reset_n\n");
+		return rc;
+	}
+
+	rc = gpio_tlmm_config(qrd3_mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
+	if (rc < 0) {
+		pr_err("Failed to enable LCD Bridge reset enable\n");
+		return rc;
+	}
+
+	rc = gpio_direction_output(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
+	if (rc < 0) {
+		pr_err("Failed GPIO bridge Reset\n");
+		gpio_free(GPIO_QRD3_LCD_BRDG_RESET_N);
+		return rc;
+	}
+
+	return rc;
+}
+
 static int msm_fb_dsi_client_reset(void)
 {
 	int rc = 0;
 
 	if (machine_is_msm7627a_qrd1())
 		rc = msm_fb_dsi_client_qrd1_reset();
+	else if (machine_is_msm7627a_evb())
+		rc = msm_fb_dsi_client_qrd3_reset();
 	else
 		rc = msm_fb_dsi_client_msm_reset();
 
@@ -650,7 +714,7 @@
 
 	gpio_set_value_cansleep(QRD_GPIO_BACKLIGHT_EN, !!on);
 
-	if (!on) {
+	if (on) {
 		gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
 		msleep(20);
 		gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
@@ -662,12 +726,99 @@
 	return rc;
 }
 
+static int qrd3_dsi_gpio_initialized;
+
+static int mipi_dsi_panel_qrd3_power(int on)
+{
+	int rc = 0;
+
+	if (!qrd3_dsi_gpio_initialized) {
+		rc = gpio_request(GPIO_QRD3_LCD_BACKLIGHT_EN,
+			"qrd3_gpio_bkl_en");
+		if (rc < 0)
+			return rc;
+
+		rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0,
+			GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+			GPIO_CFG_ENABLE);
+		if (rc < 0) {
+			pr_err("failed QRD3 GPIO_BACKLIGHT_EN tlmm config\n");
+			return rc;
+		}
+		rc = gpio_direction_output(GPIO_QRD3_LCD_BACKLIGHT_EN, 1);
+		if (rc < 0) {
+			pr_err("failed to enable backlight\n");
+			gpio_free(GPIO_QRD3_LCD_BACKLIGHT_EN);
+			return rc;
+		}
+
+		rc = gpio_request(GPIO_QRD3_LCD_EXT_2V85_EN,
+			"qrd3_gpio_ext_2v85_en");
+		if (rc < 0)
+			return rc;
+
+		rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_EXT_2V85_EN, 0,
+			GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+			GPIO_CFG_ENABLE);
+		if (rc < 0) {
+			pr_err("failed QRD3 GPIO_QRD3_LCD_EXT_2V85_EN tlmm config\n");
+			return rc;
+		}
+
+		rc = gpio_direction_output(GPIO_QRD3_LCD_EXT_2V85_EN, 1);
+		if (rc < 0) {
+			pr_err("failed to enable external 2V85\n");
+			gpio_free(GPIO_QRD3_LCD_EXT_2V85_EN);
+			return rc;
+		}
+
+		rc = gpio_request(GPIO_QRD3_LCD_EXT_1V8_EN,
+			"qrd3_gpio_ext_1v8_en");
+		if (rc < 0)
+			return rc;
+
+		rc = gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_EXT_1V8_EN, 0,
+			GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+			GPIO_CFG_ENABLE);
+		if (rc < 0) {
+			pr_err("failed QRD3 GPIO_QRD3_LCD_EXT_1V8_EN tlmm config\n");
+			return rc;
+		}
+
+		rc = gpio_direction_output(GPIO_QRD3_LCD_EXT_1V8_EN, 1);
+		if (rc < 0) {
+			pr_err("failed to enable external 1v8\n");
+			gpio_free(GPIO_QRD3_LCD_EXT_1V8_EN);
+			return rc;
+		}
+
+			qrd3_dsi_gpio_initialized = 1;
+	}
+
+	gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, !!on);
+	gpio_set_value_cansleep(GPIO_QRD3_LCD_EXT_2V85_EN, !!on);
+	gpio_set_value_cansleep(GPIO_QRD3_LCD_EXT_1V8_EN, !!on);
+
+	if (on) {
+		gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
+		msleep(20);
+		gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 0);
+		msleep(20);
+		gpio_set_value_cansleep(GPIO_QRD3_LCD_BRDG_RESET_N, 1);
+		msleep(20);
+	}
+
+		return rc;
+}
+
 static int mipi_dsi_panel_power(int on)
 {
 	int rc = 0;
 
 	if (machine_is_msm7627a_qrd1())
 		rc = mipi_dsi_panel_qrd1_power(on);
+	else if (machine_is_msm7627a_evb())
+		rc = mipi_dsi_panel_qrd3_power(on);
 	else
 		rc = mipi_dsi_panel_msm_power(on);
 	return rc;
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index d2add18..0680c44 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/gpio_event.h>
+#include <linux/memblock.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
@@ -799,6 +800,11 @@
 	msm_reserve();
 }
 
+static void __init msm8625_reserve(void)
+{
+	memblock_remove(MSM8625_SECONDARY_PHYS, SZ_8);
+}
+
 static void __init msm_device_i2c_init(void)
 {
 	if (machine_is_msm8625_rumi3()) {
@@ -1239,6 +1245,7 @@
 MACHINE_START(MSM8625_RUMI3, "QCT MSM8625 RUMI3")
 	.boot_params    = PHYS_OFFSET + 0x100,
 	.map_io         = msm8625_map_io,
+	.reserve        = msm8625_reserve,
 	.init_irq       = msm8625_init_irq,
 	.init_machine   = msm8625_rumi3_init,
 	.timer          = &msm_timer,
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index eb3cb13..a89f378 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -69,6 +69,7 @@
 #define PDM_CLK_NS_REG				REG(0x2CC0)
 /* 8064 name BB_PLL_ENA_APCS_REG */
 #define BB_PLL_ENA_SC0_REG			REG(0x34C0)
+#define BB_PLL_ENA_RPM_REG			REG(0x34A0)
 #define BB_PLL0_STATUS_REG			REG(0x30D8)
 #define BB_PLL5_STATUS_REG			REG(0x30F8)
 #define BB_PLL6_STATUS_REG			REG(0x3118)
@@ -364,6 +365,7 @@
 #define PLL_RATE(l, m, n, v, d, i) { l, m, n, v, (d>>1), i }
 
 static int rpm_vreg_id_vdd_dig;
+static int rpm_vreg_id_vdd_sr2_pll;
 
 enum vdd_dig_levels {
 	VDD_DIG_NONE,
@@ -399,16 +401,16 @@
 	.fmax[VDD_DIG_##l2] = (f2), \
 	.fmax[VDD_DIG_##l3] = (f3)
 
-enum vdd_l23_levels {
-	VDD_L23_OFF,
-	VDD_L23_ON
+enum vdd_sr2_pll_levels {
+	VDD_SR2_PLL_OFF,
+	VDD_SR2_PLL_ON
 };
 
-static int set_vdd_l23(struct clk_vdd_class *vdd_class, int level)
+static int set_vdd_sr2_pll(struct clk_vdd_class *vdd_class, int level)
 {
 	int rc = 0;
 	if (cpu_is_msm8960()) {
-		if (level == VDD_L23_OFF) {
+		if (level == VDD_SR2_PLL_OFF) {
 			rc = rpm_vreg_set_voltage(RPM_VREG_ID_PM8921_L23,
 					RPM_VREG_VOTER3, 0, 0, 1);
 			if (rc)
@@ -429,14 +431,14 @@
 				rpm_vreg_set_voltage(RPM_VREG_ID_PM8921_S8,
 						RPM_VREG_VOTER3, 0, 0, 1);
 		}
-	} else if (cpu_is_msm8930() || cpu_is_msm8627()) {
-		if (level == VDD_L23_OFF) {
-			rc = rpm_vreg_set_voltage(RPM_VREG_ID_PM8038_L23,
+	} else {
+		if (level == VDD_SR2_PLL_OFF) {
+			rc = rpm_vreg_set_voltage(rpm_vreg_id_vdd_sr2_pll,
 					RPM_VREG_VOTER3, 0, 0, 1);
 			if (rc)
 				return rc;
 		} else {
-			rc = rpm_vreg_set_voltage(RPM_VREG_ID_PM8038_L23,
+			rc = rpm_vreg_set_voltage(rpm_vreg_id_vdd_sr2_pll,
 					RPM_VREG_VOTER3, 1800000, 1800000, 1);
 			if (rc)
 				return rc;
@@ -446,7 +448,7 @@
 	return rc;
 }
 
-static DEFINE_VDD_CLASS(vdd_l23, set_vdd_l23);
+static DEFINE_VDD_CLASS(vdd_sr2_pll, set_vdd_sr2_pll);
 
 /*
  * Clock Descriptions
@@ -524,8 +526,8 @@
 	.c = {
 		.dbg_name = "pll3_clk",
 		.ops = &clk_ops_pll,
-		.vdd_class = &vdd_l23,
-		.fmax[VDD_L23_ON] = ULONG_MAX,
+		.vdd_class = &vdd_sr2_pll,
+		.fmax[VDD_SR2_PLL_ON] = ULONG_MAX,
 		CLK_INIT(pll3_clk.c),
 	},
 };
@@ -3323,37 +3325,12 @@
 	F_GFX3D(200000000, pll2, 1,  4),
 	F_GFX3D(228571000, pll2, 2,  7),
 	F_GFX3D(266667000, pll2, 1,  3),
-	F_GFX3D(320000000, pll2, 2,  5),
-	F_END
-};
-
-static struct clk_freq_tbl clk_tbl_gfx3d_8960_v2[] = {
-	F_GFX3D(        0, gnd,  0,  0),
-	F_GFX3D( 27000000, pxo,  0,  0),
-	F_GFX3D( 48000000, pll8, 1,  8),
-	F_GFX3D( 54857000, pll8, 1,  7),
-	F_GFX3D( 64000000, pll8, 1,  6),
-	F_GFX3D( 76800000, pll8, 1,  5),
-	F_GFX3D( 96000000, pll8, 1,  4),
-	F_GFX3D(128000000, pll8, 1,  3),
-	F_GFX3D(145455000, pll2, 2, 11),
-	F_GFX3D(160000000, pll2, 1,  5),
-	F_GFX3D(177778000, pll2, 2,  9),
-	F_GFX3D(200000000, pll2, 1,  4),
-	F_GFX3D(228571000, pll2, 2,  7),
-	F_GFX3D(266667000, pll2, 1,  3),
 	F_GFX3D(300000000, pll3, 1,  4),
 	F_GFX3D(320000000, pll2, 2,  5),
 	F_GFX3D(400000000, pll2, 1,  2),
 	F_END
 };
 
-static unsigned long fmax_gfx3d_8960_v2[MAX_VDD_LEVELS] __initdata = {
-	[VDD_DIG_LOW]     = 128000000,
-	[VDD_DIG_NOMINAL] = 300000000,
-	[VDD_DIG_HIGH]    = 400000000
-};
-
 static struct clk_freq_tbl clk_tbl_gfx3d_8064[] = {
 	F_GFX3D(        0, gnd,   0,  0),
 	F_GFX3D( 27000000, pxo,   0,  0),
@@ -3418,8 +3395,8 @@
 	.c = {
 		.dbg_name = "gfx3d_clk",
 		.ops = &clk_ops_rcg_8960,
-		VDD_DIG_FMAX_MAP3(LOW,  128000000, NOMINAL, 266667000,
-				  HIGH, 320000000),
+		VDD_DIG_FMAX_MAP3(LOW,  128000000, NOMINAL, 300000000,
+				  HIGH, 400000000),
 		CLK_INIT(gfx3d_clk.c),
 		.depends = &gmem_axi_clk.c,
 	},
@@ -3528,12 +3505,6 @@
 	F_END
 };
 
-static unsigned long fmax_ijpeg_8960_v2[MAX_VDD_LEVELS] __initdata = {
-	[VDD_DIG_LOW]     = 110000000,
-	[VDD_DIG_NOMINAL] = 266667000,
-	[VDD_DIG_HIGH]    = 320000000
-};
-
 static unsigned long fmax_ijpeg_8064[MAX_VDD_LEVELS] __initdata = {
 	[VDD_DIG_LOW]     = 128000000,
 	[VDD_DIG_NOMINAL] = 266667000,
@@ -3562,7 +3533,8 @@
 	.c = {
 		.dbg_name = "ijpeg_clk",
 		.ops = &clk_ops_rcg_8960,
-		VDD_DIG_FMAX_MAP2(LOW, 110000000, NOMINAL, 266667000),
+		VDD_DIG_FMAX_MAP3(LOW, 110000000, NOMINAL, 266667000,
+				  HIGH, 320000000),
 		CLK_INIT(ijpeg_clk.c),
 		.depends = &ijpeg_axi_clk.c,
 	},
@@ -4139,12 +4111,6 @@
 	F_END
 };
 
-static unsigned long fmax_vfe_8960_v2[MAX_VDD_LEVELS] __initdata = {
-	[VDD_DIG_LOW]     = 110000000,
-	[VDD_DIG_NOMINAL] = 266667000,
-	[VDD_DIG_HIGH]    = 320000000
-};
-
 static unsigned long fmax_vfe_8064[MAX_VDD_LEVELS] __initdata = {
 	[VDD_DIG_LOW]     = 128000000,
 	[VDD_DIG_NOMINAL] = 266667000,
@@ -4173,7 +4139,8 @@
 	.c = {
 		.dbg_name = "vfe_clk",
 		.ops = &clk_ops_rcg_8960,
-		VDD_DIG_FMAX_MAP2(LOW, 110000000, NOMINAL, 266667000),
+		VDD_DIG_FMAX_MAP3(LOW, 110000000, NOMINAL, 266667000,
+				  HIGH, 320000000),
 		CLK_INIT(vfe_clk.c),
 		.depends = &vfe_axi_clk.c,
 	},
@@ -4475,6 +4442,8 @@
 static DEFINE_CLK_MEASURE(l2_m_clk);
 static DEFINE_CLK_MEASURE(krait0_m_clk);
 static DEFINE_CLK_MEASURE(krait1_m_clk);
+static DEFINE_CLK_MEASURE(krait2_m_clk);
+static DEFINE_CLK_MEASURE(krait3_m_clk);
 static DEFINE_CLK_MEASURE(q6sw_clk);
 static DEFINE_CLK_MEASURE(q6fw_clk);
 static DEFINE_CLK_MEASURE(q6_func_clk);
@@ -4661,8 +4630,8 @@
 	{ TEST_MM_HS(0x32), &csi_rdi2_clk.c },
 	{ TEST_MM_HS(0x33), &vcap_clk.c },
 	{ TEST_MM_HS(0x34), &vcap_npl_clk.c },
-	{ TEST_MM_HS(0x36), &vcap_axi_clk.c },
-	{ TEST_MM_HS(0x39), &gfx3d_axi_clk.c },
+	{ TEST_MM_HS(0x35), &vcap_axi_clk.c },
+	{ TEST_MM_HS(0x38), &gfx3d_axi_clk.c },
 
 	{ TEST_LPA(0x0F), &mi2s_bit_clk.c },
 	{ TEST_LPA(0x10), &codec_i2s_mic_bit_clk.c },
@@ -4677,6 +4646,8 @@
 	{ TEST_CPUL2(0x2), &l2_m_clk },
 	{ TEST_CPUL2(0x0), &krait0_m_clk },
 	{ TEST_CPUL2(0x1), &krait1_m_clk },
+	{ TEST_CPUL2(0x4), &krait2_m_clk },
+	{ TEST_CPUL2(0x5), &krait3_m_clk },
 };
 
 static struct measure_sel *find_measure_sel(struct clk *clk)
@@ -4869,6 +4840,7 @@
 	CLK_LOOKUP("xo",		pxo_clk.c,	"pil_qdsp6v4.0"),
 	CLK_LOOKUP("xo",		cxo_clk.c,	"pil_qdsp6v4.1"),
 	CLK_LOOKUP("xo",		cxo_clk.c,	"pil_qdsp6v4.2"),
+	CLK_LOOKUP("xo",		cxo_clk.c,	"pil_gss"),
 	CLK_LOOKUP("pll2",		pll2_clk.c,	NULL),
 	CLK_LOOKUP("pll8",		pll8_clk.c,	NULL),
 	CLK_LOOKUP("pll4",		pll4_clk.c,	NULL),
@@ -4896,7 +4868,7 @@
 	CLK_LOOKUP("core_clk",		gp0_clk.c,		""),
 	CLK_LOOKUP("core_clk",		gp1_clk.c,		""),
 	CLK_LOOKUP("core_clk",		gp2_clk.c,		""),
-	CLK_LOOKUP("core_clk",		gsbi1_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi1_uart_clk.c, "msm_serial_hsl.0"),
 	CLK_LOOKUP("core_clk",		gsbi2_uart_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi3_uart_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi4_uart_clk.c,	""),
@@ -4907,11 +4879,11 @@
 	CLK_LOOKUP("core_clk",		gsbi2_qup_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi3_qup_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi4_qup_clk.c,	""),
-	CLK_LOOKUP("core_clk",		gsbi5_qup_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi5_qup_clk.c,	"spi_qsd.0"),
 	CLK_LOOKUP("core_clk",		gsbi6_qup_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi7_qup_clk.c,	""),
 	CLK_LOOKUP("core_clk",		pdm_clk.c,		""),
-	CLK_LOOKUP("pmem_clk",		pmem_clk.c,		NULL),
+	CLK_LOOKUP("mem_clk",		pmem_clk.c,		"msm_sps"),
 	CLK_DUMMY("core_clk",           PRNG_CLK,	"msm_rng.0", OFF),
 	CLK_LOOKUP("core_clk",		sdc1_clk.c,		"msm_sdcc.1"),
 	CLK_LOOKUP("core_clk",		sdc2_clk.c,		"msm_sdcc.2"),
@@ -4936,11 +4908,11 @@
 	CLK_LOOKUP("ce3_core_src_clk",	ce3_src_clk.c,		"qce.0"),
 	CLK_LOOKUP("ce3_core_src_clk",	ce3_src_clk.c,		"qcrypto.0"),
 	CLK_LOOKUP("dma_bam_pclk",	dma_bam_p_clk.c,	NULL),
-	CLK_LOOKUP("iface_clk",		gsbi1_p_clk.c,		""),
+	CLK_LOOKUP("iface_clk",		gsbi1_p_clk.c,	"msm_serial_hsl.0"),
 	CLK_LOOKUP("iface_clk",		gsbi2_p_clk.c,		""),
 	CLK_LOOKUP("iface_clk",		gsbi3_p_clk.c,		""),
 	CLK_LOOKUP("iface_clk",		gsbi4_p_clk.c,		""),
-	CLK_LOOKUP("iface_clk",		gsbi5_p_clk.c,		""),
+	CLK_LOOKUP("iface_clk",		gsbi5_p_clk.c,		"spi_qsd.0"),
 	CLK_LOOKUP("iface_clk",		gsbi6_p_clk.c,		""),
 	CLK_LOOKUP("iface_clk",		gsbi7_p_clk.c,		""),
 	CLK_LOOKUP("iface_clk",		tsif_p_clk.c,		""),
@@ -5049,7 +5021,7 @@
 	CLK_LOOKUP("mem_iface_clk",	imem_p_clk.c,	"kgsl-3d0.0"),
 	CLK_LOOKUP("mdp_pclk",		mdp_p_clk.c,		""),
 	CLK_LOOKUP("iface_clk",		mdp_p_clk.c,	"footswitch-8x60.4"),
-	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,		""),
+	CLK_LOOKUP("iface_clk",		smmu_p_clk.c,		"msm_iommu"),
 	CLK_LOOKUP("iface_clk",		rot_p_clk.c,	"msm_rotator.0"),
 	CLK_LOOKUP("iface_clk",		rot_p_clk.c,	"footswitch-8x60.6"),
 	CLK_LOOKUP("iface_clk",		vcodec_p_clk.c,		"msm_vidc.0"),
@@ -5070,7 +5042,7 @@
 	CLK_LOOKUP("i2s_spkr_osr_clk",	spare_i2s_spkr_osr_clk.c, ""),
 	CLK_LOOKUP("pcm_clk",		pcm_clk.c,		""),
 	CLK_LOOKUP("sps_slimbus_clk",	sps_slimbus_clk.c,	""),
-	CLK_LOOKUP("audio_slimbus_clk",	audio_slimbus_clk.c,	""),
+	CLK_LOOKUP("audio_slimbus_clk",	audio_slimbus_clk.c,	NULL),
 	CLK_LOOKUP("core_clk",		jpegd_axi_clk.c,	""),
 	CLK_LOOKUP("core_clk",		vpe_axi_clk.c,		""),
 	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,		""),
@@ -5097,14 +5069,29 @@
 	CLK_LOOKUP("core_clk",	      usb_hsic_system_clk.c,   "msm_hsic_host"),
 	CLK_LOOKUP("iface_clk",	      usb_hsic_p_clk.c,        "msm_hsic_host"),
 
+	CLK_LOOKUP("core_clk",		jpegd_axi_clk.c,	"msm_iommu.0"),
+	CLK_LOOKUP("core_clk",		vpe_axi_clk.c,		"msm_iommu.1"),
+	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,		"msm_iommu.2"),
+	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,		"msm_iommu.3"),
+	CLK_LOOKUP("core_clk",		rot_axi_clk.c,		"msm_iommu.4"),
+	CLK_LOOKUP("core_clk",		ijpeg_axi_clk.c,	"msm_iommu.5"),
+	CLK_LOOKUP("core_clk",		vfe_axi_clk.c,		"msm_iommu.6"),
+	CLK_LOOKUP("core_clk",		vcodec_axi_a_clk.c,	"msm_iommu.7"),
+	CLK_LOOKUP("core_clk",		vcodec_axi_b_clk.c,	"msm_iommu.8"),
+	CLK_LOOKUP("core_clk",		gfx3d_axi_clk.c,	"msm_iommu.9"),
+	CLK_LOOKUP("core_clk",		gfx3d_axi_clk.c,	"msm_iommu.10"),
+	CLK_LOOKUP("core_clk",		vcap_axi_clk.c,		"msm_iommu.11"),
+
 	CLK_LOOKUP("mem_clk",		ebi1_adm_clk.c, "msm_dmov"),
 
 	CLK_LOOKUP("l2_mclk",		l2_m_clk,     ""),
 	CLK_LOOKUP("krait0_mclk",	krait0_m_clk, ""),
 	CLK_LOOKUP("krait1_mclk",	krait1_m_clk, ""),
+	CLK_LOOKUP("krait2_mclk",	krait2_m_clk, ""),
+	CLK_LOOKUP("krait3_mclk",	krait3_m_clk, ""),
 };
 
-static struct clk_lookup msm_clocks_8960_v1[] __initdata = {
+static struct clk_lookup msm_clocks_8960[] = {
 	CLK_LOOKUP("xo",		cxo_clk.c,	"msm_otg"),
 	CLK_LOOKUP("cxo",		cxo_clk.c,	"wcnss_wlan.0"),
 	CLK_LOOKUP("cxo",		cxo_clk.c,	"pil_riva"),
@@ -5182,6 +5169,11 @@
 	CLK_LOOKUP("alt_core_clk",	usb_fs2_xcvr_clk.c,	""),
 	CLK_LOOKUP("sys_clk",		usb_fs2_sys_clk.c,	""),
 	CLK_LOOKUP("src_clk",		usb_fs2_src_clk.c,	""),
+	CLK_LOOKUP("alt_core_clk",    usb_hsic_xcvr_fs_clk.c,  "msm_hsic_host"),
+	CLK_LOOKUP("phy_clk",	      usb_hsic_hsic_clk.c,     "msm_hsic_host"),
+	CLK_LOOKUP("cal_clk",	      usb_hsic_hsio_cal_clk.c, "msm_hsic_host"),
+	CLK_LOOKUP("core_clk",	      usb_hsic_system_clk.c,   "msm_hsic_host"),
+	CLK_LOOKUP("iface_clk",	      usb_hsic_p_clk.c,        "msm_hsic_host"),
 	CLK_LOOKUP("iface_clk",		ce1_p_clk.c,		"qce.0"),
 	CLK_LOOKUP("iface_clk",		ce1_p_clk.c,		"qcrypto.0"),
 	CLK_LOOKUP("core_clk",		ce1_core_clk.c,		"qce.0"),
@@ -5218,6 +5210,8 @@
 	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-001a"),
 	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-006c"),
 	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-0048"),
+	CLK_LOOKUP("cam_clk",		cam2_clk.c,		NULL),
+	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-0020"),
 	CLK_LOOKUP("csi_src_clk",	csi0_src_clk.c,		"msm_csid.0"),
 	CLK_LOOKUP("csi_src_clk",	csi1_src_clk.c,		"msm_csid.1"),
 	CLK_LOOKUP("csi_clk",		csi0_clk.c,		"msm_csid.0"),
@@ -5226,6 +5220,13 @@
 	CLK_LOOKUP("csi_phy_clk",	csi1_phy_clk.c,		"msm_csid.1"),
 	CLK_LOOKUP("csi_pix_clk",	csi_pix_clk.c,		"msm_ispif.0"),
 	CLK_LOOKUP("csi_rdi_clk",	csi_rdi_clk.c,		"msm_ispif.0"),
+	CLK_LOOKUP("csi_src_clk",	csi2_src_clk.c,		NULL),
+	CLK_LOOKUP("csi_clk",		csi2_clk.c,		NULL),
+	CLK_LOOKUP("csi_pix1_clk",	csi_pix1_clk.c,		"msm_ispif.0"),
+	CLK_LOOKUP("csi_rdi1_clk",	csi_rdi1_clk.c,		"msm_ispif.0"),
+	CLK_LOOKUP("csi_rdi2_clk",	csi_rdi2_clk.c,		"msm_ispif.0"),
+	CLK_LOOKUP("csi_phy_clk",	csi2_phy_clk.c,		NULL),
+	CLK_LOOKUP("csi2phy_timer_clk",	csi2phy_timer_clk.c,	NULL),
 	CLK_LOOKUP("csiphy_timer_src_clk",
 			   csiphy_timer_src_clk.c, "msm_csiphy.0"),
 	CLK_LOOKUP("csiphy_timer_src_clk",
@@ -5361,26 +5362,6 @@
 	CLK_LOOKUP("q6_func_clk",	q6_func_clk,  ""),
 };
 
-static struct clk_lookup msm_clocks_8960_v2[] __initdata = {
-	CLK_LOOKUP("cam_clk",		cam2_clk.c,		NULL),
-	CLK_LOOKUP("csi_src_clk",	csi2_src_clk.c,		NULL),
-	CLK_LOOKUP("csi_clk",		csi2_clk.c,		NULL),
-	CLK_LOOKUP("csi_pix1_clk",	csi_pix1_clk.c,		"msm_ispif.0"),
-	CLK_LOOKUP("csi_rdi1_clk",	csi_rdi1_clk.c,		"msm_ispif.0"),
-	CLK_LOOKUP("csi_rdi2_clk",	csi_rdi2_clk.c,		"msm_ispif.0"),
-	CLK_LOOKUP("csi_phy_clk",	csi2_phy_clk.c,		NULL),
-	CLK_LOOKUP("csi2phy_timer_clk",	csi2phy_timer_clk.c,	NULL),
-	CLK_LOOKUP("alt_core_clk",    usb_hsic_xcvr_fs_clk.c,  "msm_hsic_host"),
-	CLK_LOOKUP("phy_clk",	      usb_hsic_hsic_clk.c,     "msm_hsic_host"),
-	CLK_LOOKUP("cal_clk",	      usb_hsic_hsio_cal_clk.c, "msm_hsic_host"),
-	CLK_LOOKUP("core_clk",	      usb_hsic_system_clk.c,   "msm_hsic_host"),
-	CLK_LOOKUP("iface_clk",	      usb_hsic_p_clk.c,        "msm_hsic_host"),
-};
-
-/* Add v2 clocks dynamically at runtime */
-static struct clk_lookup msm_clocks_8960[ARRAY_SIZE(msm_clocks_8960_v1) +
-					 ARRAY_SIZE(msm_clocks_8960_v2)];
-
 /*
  * Miscellaneous clock register initializations
  */
@@ -5430,13 +5411,12 @@
 	 */
 	/*
 	 * Initialize MM AHB registers: Enable the FPB clock and disable HW
-	 * gating on 8960v1/8064 for all clocks. Also set VFE_AHB's
+	 * gating on non-8960 for all clocks. Also set VFE_AHB's
 	 * FORCE_CORE_ON bit to prevent its memory from being collapsed when
 	 * the clock is halted. The sleep and wake-up delays are set to safe
 	 * values.
 	 */
-	if (cpu_is_msm8960() &&
-			SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2) {
+	if (cpu_is_msm8960()) {
 		rmwreg(0x44000000, AHB_EN_REG,  0x6C000103);
 		writel_relaxed(0x3C7097F9, AHB_EN2_REG);
 	} else {
@@ -5466,8 +5446,7 @@
 	rmwreg(0x0027FCFF, MAXI_EN3_REG, 0x003FFFFF);
 	if (cpu_is_apq8064())
 		rmwreg(0x009FE4FF, MAXI_EN5_REG, 0x01FFEFFF);
-	if (cpu_is_msm8960() &&
-			SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2)
+	if (cpu_is_msm8960())
 		rmwreg(0x00003C38, SAXI_EN_REG,  0x00003FFF);
 	else
 		rmwreg(0x000003C7, SAXI_EN_REG,  0x00003FFF);
@@ -5593,6 +5572,11 @@
 			writel_relaxed(regval, BB_PLL8_TEST_CTL_REG);
 
 			set_fsm_mode(BB_PLL8_MODE_REG);
+
+			/* Enable PLL8 by voting from RPM */
+			regval = readl_relaxed(BB_PLL_ENA_RPM_REG);
+			regval |= BIT(8);
+			writel_relaxed(regval, BB_PLL_ENA_RPM_REG);
 		}
 		/* Check if PLL3 is active */
 		is_pll_enabled = readl_relaxed(GPLL1_STATUS_REG) & BIT(16);
@@ -5709,19 +5693,21 @@
 	}
 }
 
-struct clock_init_data msm8960_clock_init_data __initdata;
-
 /* Local clock driver initialization. */
 static void __init msm8960_clock_init(void)
 {
-	size_t num_lookups = ARRAY_SIZE(msm_clocks_8960_v1);
 
-	if (cpu_is_msm8960() || cpu_is_apq8064())
+	if (cpu_is_msm8960()) {
 		rpm_vreg_id_vdd_dig = RPM_VREG_ID_PM8921_S3;
-	else if (cpu_is_msm8930() || cpu_is_msm8627())
+	} else if (cpu_is_apq8064()) {
+		rpm_vreg_id_vdd_dig = RPM_VREG_ID_PM8921_S3;
+		rpm_vreg_id_vdd_sr2_pll = RPM_VREG_ID_PM8921_LVS7;
+	} else if (cpu_is_msm8930() || cpu_is_msm8627()) {
 		rpm_vreg_id_vdd_dig = RPM_VREG_ID_PM8038_S1;
-	else
+		rpm_vreg_id_vdd_sr2_pll = RPM_VREG_ID_PM8038_L23;
+	} else {
 		BUG();
+	}
 
 	xo_pxo = msm_xo_get(MSM_XO_PXO, "clock-8960");
 	if (IS_ERR(xo_pxo)) {
@@ -5734,26 +5720,6 @@
 		BUG();
 	}
 
-	if (cpu_is_msm8960() || cpu_is_msm8930()) {
-		memcpy(msm_clocks_8960, msm_clocks_8960_v1,
-				sizeof(msm_clocks_8960_v1));
-		if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2) {
-			gfx3d_clk.freq_tbl = clk_tbl_gfx3d_8960_v2;
-
-			memcpy(gfx3d_clk.c.fmax, fmax_gfx3d_8960_v2,
-			       sizeof(gfx3d_clk.c.fmax));
-			memcpy(ijpeg_clk.c.fmax, fmax_ijpeg_8960_v2,
-			       sizeof(ijpeg_clk.c.fmax));
-			memcpy(vfe_clk.c.fmax, fmax_vfe_8960_v2,
-			       sizeof(vfe_clk.c.fmax));
-
-			memcpy(msm_clocks_8960 + ARRAY_SIZE(msm_clocks_8960_v1),
-				msm_clocks_8960_v2, sizeof(msm_clocks_8960_v2));
-			num_lookups = ARRAY_SIZE(msm_clocks_8960);
-		}
-		msm8960_clock_init_data.size = num_lookups;
-	}
-
 	/*
 	 * Change the freq tables for and voltage requirements for
 	 * clocks which differ between 8960 and 8064.
@@ -5815,13 +5781,8 @@
 	rcg_clk_disable(&pdm_clk.c);
 	rcg_clk_enable(&tssc_clk.c);
 	rcg_clk_disable(&tssc_clk.c);
-	if (cpu_is_msm8960() &&
-			SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2) {
-		clk_enable(&usb_hsic_hsic_clk.c);
-		clk_disable(&usb_hsic_hsic_clk.c);
-	} else
-		/* CSI2 hardware not present on 8960v1 devices */
-		pix_rdi_mux_map[2] = NULL;
+	clk_enable(&usb_hsic_hsic_clk.c);
+	clk_disable(&usb_hsic_hsic_clk.c);
 }
 
 static int __init msm8960_clock_late_init(void)
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index f3ef2ce..faa9498 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/msm_rotator.h>
 #include <linux/clkdev.h>
+#include <linux/dma-mapping.h>
 #include <mach/irqs-8064.h>
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
@@ -26,6 +27,7 @@
 #include <sound/apr_audio.h>
 #include <mach/msm_bus_board.h>
 #include <mach/rpm.h>
+#include <mach/mdm2.h>
 #include "clock.h"
 #include "devices.h"
 #include "msm_watchdog.h"
@@ -59,8 +61,8 @@
 #define MSM_PMIC_SSBI_SIZE	SZ_4K
 
 /* Address of HS USBOTG1 */
-#define MSM_HSUSB_PHYS		0x12500000
-#define MSM_HSUSB_SIZE		SZ_4K
+#define MSM_HSUSB1_PHYS		0x12500000
+#define MSM_HSUSB1_SIZE		SZ_4K
 
 static struct msm_watchdog_pdata msm_watchdog_pdata = {
 	.pet_time = 10000,
@@ -413,8 +415,8 @@
 
 static struct resource resources_otg[] = {
 	{
-		.start	= MSM_HSUSB_PHYS,
-		.end	= MSM_HSUSB_PHYS + MSM_HSUSB_SIZE - 1,
+		.start	= MSM_HSUSB1_PHYS,
+		.end	= MSM_HSUSB1_PHYS + MSM_HSUSB1_SIZE - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
@@ -436,8 +438,8 @@
 
 static struct resource resources_hsusb[] = {
 	{
-		.start	= MSM_HSUSB_PHYS,
-		.end	= MSM_HSUSB_PHYS + MSM_HSUSB_SIZE - 1,
+		.start	= MSM_HSUSB1_PHYS,
+		.end	= MSM_HSUSB1_PHYS + MSM_HSUSB1_SIZE - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	{
@@ -457,6 +459,61 @@
 	},
 };
 
+static struct resource resources_hsusb_host[] = {
+	{
+		.start  = MSM_HSUSB1_PHYS,
+		.end    = MSM_HSUSB1_PHYS + MSM_HSUSB1_SIZE - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.start  = USB1_HS_IRQ,
+		.end    = USB1_HS_IRQ,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource resources_hsic_host[] = {
+	{
+		.start	= 0x12510000,
+		.end	= 0x12510000 + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= USB2_HSIC_IRQ,
+		.end	= USB2_HSIC_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= MSM_GPIO_TO_INT(49),
+		.end	= MSM_GPIO_TO_INT(49),
+		.name	= "peripheral_status_irq",
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 dma_mask = DMA_BIT_MASK(32);
+struct platform_device apq8064_device_hsusb_host = {
+	.name           = "msm_hsusb_host",
+	.id             = -1,
+	.num_resources  = ARRAY_SIZE(resources_hsusb_host),
+	.resource       = resources_hsusb_host,
+	.dev            = {
+		.dma_mask               = &dma_mask,
+		.coherent_dma_mask      = 0xffffffff,
+	},
+};
+
+struct platform_device apq8064_device_hsic_host = {
+	.name		= "msm_hsic_host",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(resources_hsic_host),
+	.resource	= resources_hsic_host,
+	.dev		= {
+		.dma_mask		= &dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
 #define MSM_SDC1_BASE         0x12400000
 #define MSM_SDC1_DML_BASE     (MSM_SDC1_BASE + 0x800)
 #define MSM_SDC1_BAM_BASE     (MSM_SDC1_BASE + 0x2000)
@@ -754,6 +811,26 @@
 };
 #endif
 
+static struct resource msm_gss_resources[] = {
+	{
+		.start  = 0x10000000,
+		.end    = 0x10000000 + SZ_256 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		.start  = 0x10008000,
+		.end    = 0x10008000 + SZ_256 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device msm_gss = {
+	.name = "pil_gss",
+	.id = -1,
+	.num_resources  = ARRAY_SIZE(msm_gss_resources),
+	.resource       = msm_gss_resources,
+};
+
 static struct clk_lookup msm_clocks_8064_dummy[] = {
 	CLK_DUMMY("pll2",		PLL2,		NULL, 0),
 	CLK_DUMMY("pll8",		PLL8,		NULL, 0),
@@ -1329,3 +1406,50 @@
 
 };
 #endif
+
+#define MDM2AP_ERRFATAL			19
+#define AP2MDM_ERRFATAL			18
+#define MDM2AP_STATUS			49
+#define AP2MDM_STATUS			48
+#define AP2MDM_PMIC_RESET_N		27
+
+static struct resource mdm_resources[] = {
+	{
+		.start	= MDM2AP_ERRFATAL,
+		.end	= MDM2AP_ERRFATAL,
+		.name	= "MDM2AP_ERRFATAL",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= AP2MDM_ERRFATAL,
+		.end	= AP2MDM_ERRFATAL,
+		.name	= "AP2MDM_ERRFATAL",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= MDM2AP_STATUS,
+		.end	= MDM2AP_STATUS,
+		.name	= "MDM2AP_STATUS",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= AP2MDM_STATUS,
+		.end	= AP2MDM_STATUS,
+		.name	= "AP2MDM_STATUS",
+		.flags	= IORESOURCE_IO,
+	},
+	{
+		.start	= AP2MDM_PMIC_RESET_N,
+		.end	= AP2MDM_PMIC_RESET_N,
+		.name	= "AP2MDM_PMIC_RESET_N",
+		.flags	= IORESOURCE_IO,
+	},
+};
+
+struct platform_device mdm_8064_device = {
+	.name		= "mdm2_modem",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(mdm_resources),
+	.resource	= mdm_resources,
+};
+
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index 257f372..c75a4e3 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -39,7 +39,8 @@
 		MSM_RPM_MAP(8930, NOTIFICATION_CONFIGURED_0, NOTIFICATION, 4),
 		MSM_RPM_MAP(8930, NOTIFICATION_REGISTERED_0, NOTIFICATION, 4),
 		MSM_RPM_MAP(8930, INVALIDATE_0, INVALIDATE, 8),
-		MSM_RPM_MAP(8930, TRIGGER_TIMED_0, TRIGGER_TIMED_0, 2),
+		MSM_RPM_MAP(8960, TRIGGER_TIMED_TO, TRIGGER_TIMED, 1),
+		MSM_RPM_MAP(8960, TRIGGER_TIMED_SCLK_COUNT, TRIGGER_TIMED, 1),
 		MSM_RPM_MAP(8930, RPM_CTL, RPM_CTL, 1),
 		MSM_RPM_MAP(8930, CXO_CLK, CXO_CLK, 1),
 		MSM_RPM_MAP(8930, PXO_CLK, PXO_CLK, 1),
@@ -57,7 +58,7 @@
 				APPS_FABRIC_CFG_CLKMOD, 3),
 		MSM_RPM_MAP(8930, APPS_FABRIC_CFG_IOCTL,
 				APPS_FABRIC_CFG_IOCTL, 1),
-		MSM_RPM_MAP(8930, APPS_FABRIC_ARB_0, APPS_FABRIC_ARB, 6),
+		MSM_RPM_MAP(8930, APPS_FABRIC_ARB_0, APPS_FABRIC_ARB, 12),
 		MSM_RPM_MAP(8930, SYS_FABRIC_CFG_HALT_0,
 				SYS_FABRIC_CFG_HALT, 2),
 		MSM_RPM_MAP(8930, SYS_FABRIC_CFG_CLKMOD_0,
@@ -65,14 +66,14 @@
 		MSM_RPM_MAP(8930, SYS_FABRIC_CFG_IOCTL,
 				SYS_FABRIC_CFG_IOCTL, 1),
 		MSM_RPM_MAP(8930, SYSTEM_FABRIC_ARB_0,
-				SYSTEM_FABRIC_ARB, 20),
+				SYSTEM_FABRIC_ARB, 29),
 		MSM_RPM_MAP(8930, MMSS_FABRIC_CFG_HALT_0,
 				MMSS_FABRIC_CFG_HALT, 2),
 		MSM_RPM_MAP(8930, MMSS_FABRIC_CFG_CLKMOD_0,
 				MMSS_FABRIC_CFG_CLKMOD, 3),
 		MSM_RPM_MAP(8930, MMSS_FABRIC_CFG_IOCTL,
 				MMSS_FABRIC_CFG_IOCTL, 1),
-		MSM_RPM_MAP(8930, MM_FABRIC_ARB_0, MM_FABRIC_ARB, 11),
+		MSM_RPM_MAP(8930, MM_FABRIC_ARB_0, MM_FABRIC_ARB, 23),
 		MSM_RPM_MAP(8930, PM8038_S1_0, PM8038_S1, 2),
 		MSM_RPM_MAP(8930, PM8038_S2_0, PM8038_S2, 2),
 		MSM_RPM_MAP(8930, PM8038_S3_0, PM8038_S3, 2),
@@ -217,6 +218,7 @@
 		MSM_RPM_STATUS_ID_MAP(8930, CXO_BUFFERS),
 		MSM_RPM_STATUS_ID_MAP(8930, USB_OTG_SWITCH),
 		MSM_RPM_STATUS_ID_MAP(8930, HDMI_SWITCH),
+		MSM_RPM_STATUS_ID_MAP(8930, QDSS_CLK),
 	},
 	.target_ctrl_id = {
 		MSM_RPM_CTRL_MAP(8930, VERSION_MAJOR),
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index f3a95a6..043375a 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -866,6 +866,24 @@
 	.resource	= gsbi0_msm8625_qup_resources,
 };
 
+static struct resource msm8625_gpio_resources[] = {
+	{
+		.start	= MSM8625_INT_GPIO_GROUP1,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= MSM8625_INT_GPIO_GROUP2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device msm8625_device_gpio = {
+	.name		= "msmgpio",
+	.id		= -1,
+	.resource	= msm8625_gpio_resources,
+	.num_resources	= ARRAY_SIZE(msm8625_gpio_resources),
+};
+
 static struct clk_lookup msm_clock_8625_dummy[] = {
 	CLK_DUMMY("core_clk",		adm_clk.c,	"msm_dmov", 0),
 	CLK_DUMMY("adsp_clk",		adsp_clk.c,	NULL, 0),
@@ -1007,7 +1025,10 @@
 
 static int msm7627a_init_gpio(void)
 {
-	platform_device_register(&msm_device_gpio);
+	if (cpu_is_msm8625())
+		platform_device_register(&msm8625_device_gpio);
+	else
+		platform_device_register(&msm_device_gpio);
 	return 0;
 }
 postcore_initcall(msm7627a_init_gpio);
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 5d42f99..9469de8 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -102,6 +102,8 @@
 extern struct platform_device apq8064_device_otg;
 extern struct platform_device apq8064_usb_diag_device;
 extern struct platform_device apq8064_device_gadget_peripheral;
+extern struct platform_device apq8064_device_hsusb_host;
+extern struct platform_device apq8064_device_hsic_host;
 
 extern struct platform_device msm_device_i2c;
 
@@ -193,6 +195,7 @@
 extern struct platform_device msm_8960_q6_mss_fw;
 extern struct platform_device msm_8960_q6_mss_sw;
 extern struct platform_device msm_8960_riva;
+extern struct platform_device msm_gss;
 
 extern struct platform_device apq_pcm;
 extern struct platform_device apq_pcm_routing;
@@ -292,3 +295,5 @@
 extern struct platform_device msm_bus_8064_mm_fabric;
 extern struct platform_device msm_bus_8064_sys_fpb;
 extern struct platform_device msm_bus_8064_cpss_fpb;
+
+extern struct platform_device mdm_8064_device;
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index c7ef271..6eceea7 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -396,6 +396,7 @@
 	int fpga_3d_config_addr;
 	int *gpio;
 	struct mipi_dsi_phy_ctrl *phy_ctrl_settings;
+	char dlane_swap;
 };
 
 struct msm_fb_platform_data {
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index bb33289..06d214f 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -213,6 +213,7 @@
 #define CSI_DECODE_6BIT 0
 #define CSI_DECODE_8BIT 1
 #define CSI_DECODE_10BIT 2
+#define CSI_DECODE_DPCM_10_8_10 5
 
 struct msm_vfe_phy_info {
 	uint32_t sbuf_phy;
diff --git a/arch/arm/mach-msm/include/mach/irqs-8064.h b/arch/arm/mach-msm/include/mach/irqs-8064.h
index 8597111..a5f78f5 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8064.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8064.h
@@ -57,7 +57,7 @@
 #define TLMM_MSM_DIR_CONN_IRQ_8			(GIC_SPI_START + 12)
 #define TLMM_MSM_DIR_CONN_IRQ_9			(GIC_SPI_START + 13)
 #define PM8921_SEC_IRQ_N			(GIC_SPI_START + 14)
-#define PM8018_SEC_IRQ_N			(GIC_SPI_START + 15)
+#define PM8821_SEC_IRQ_N			(GIC_SPI_START + 15)
 #define TLMM_MSM_SUMMARY_IRQ			(GIC_SPI_START + 16)
 #define SPDM_RT_1_IRQ				(GIC_SPI_START + 17)
 #define SPDM_DIAG_IRQ				(GIC_SPI_START + 18)
diff --git a/arch/arm/mach-msm/include/mach/mdm2.h b/arch/arm/mach-msm/include/mach/mdm2.h
index acfa38a..78ca88f 100644
--- a/arch/arm/mach-msm/include/mach/mdm2.h
+++ b/arch/arm/mach-msm/include/mach/mdm2.h
@@ -15,6 +15,8 @@
 
 struct mdm_platform_data {
 	char *mdm_version;
+	int ramdump_delay_ms;
+	struct platform_device *peripheral_platform_device;
 };
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index ca8daaa..bb2b019 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -95,6 +95,7 @@
 
 
 #define MSM_STRONGLY_ORDERED_PAGE	0xFA0F0000
+#define MSM8625_SECONDARY_PHYS		0x0FE00000
 
 #if defined(CONFIG_ARCH_MSM9615) || defined(CONFIG_ARCH_MSM7X27)
 #define MSM_SHARED_RAM_SIZE	SZ_1M
diff --git a/arch/arm/mach-msm/include/mach/msm_rtb.h b/arch/arm/mach-msm/include/mach/msm_rtb.h
index 2831428..a24e892 100644
--- a/arch/arm/mach-msm/include/mach/msm_rtb.h
+++ b/arch/arm/mach-msm/include/mach/msm_rtb.h
@@ -32,6 +32,22 @@
  */
 int uncached_logk(enum logk_event_type log_type, void *data);
 
+#define ETB_WAYPOINT  do { \
+				BRANCH_TO_NEXT_ISTR; \
+				nop(); \
+				BRANCH_TO_NEXT_ISTR; \
+				nop(); \
+			} while (0)
+
+#define BRANCH_TO_NEXT_ISTR  asm volatile("b .+4\n" : : : "memory")
+/*
+ * both the mb and the isb are needed to ensure enough waypoints for
+ * etb tracing
+ */
+#define LOG_BARRIER	do { \
+				mb(); \
+				isb();\
+			 } while (0)
 #else
 
 static inline int uncached_logk_pc(enum logk_event_type log_type,
@@ -40,5 +56,13 @@
 
 static inline int uncached_logk(enum logk_event_type log_type,
 					void *data) { return 0; }
+
+#define ETB_WAYPOINT
+#define BRANCH_TO_NEXT_ISTR
+/*
+ * Due to a GCC bug, we need to have a nop here in order to prevent an extra
+ * read from being generated after the write.
+ */
+#define LOG_BARRIER		nop()
 #endif
 #endif
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h b/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h
index 68a3c44..d50fe2b 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012, 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
@@ -41,6 +41,7 @@
 	unsigned used;		/* Input usage actual DSP produced PCM size  */
 	unsigned addr;
 };
+struct audio;
 
 #ifdef CONFIG_HAS_EARLYSUSPEND
 struct audio_suspend_ctl {
diff --git a/arch/arm/mach-msm/include/mach/rpm-8930.h b/arch/arm/mach-msm/include/mach/rpm-8930.h
index 304a185..04218b2 100644
--- a/arch/arm/mach-msm/include/mach/rpm-8930.h
+++ b/arch/arm/mach-msm/include/mach/rpm-8930.h
@@ -117,8 +117,8 @@
 	MSM_RPM_8930_ID_INVALIDATE_7 =
 		MSM_RPM_8930_ID_INVALIDATE_0 + 7,
 
-	MSM_RPM_8930_ID_TRIGGER_TIMED_0				= 16,
-	MSM_RPM_8930_ID_TRIGGER_TIMED_1				= 17,
+	MSM_RPM_8930_ID_TRIGGER_TIMED_TO_			= 16,
+	MSM_RPM_8930_ID_TRIGGER_TIMED_SCLK_COUNT		= 17,
 	MSM_RPM_8930_ID_RPM_CTL					= 18,
 	MSM_RPM_8930_ID_RESERVED_0				= 19,
 	MSM_RPM_8930_ID_RESERVED_5 =
@@ -140,106 +140,105 @@
 	MSM_RPM_8930_ID_APPS_FABRIC_CFG_CLKMOD_2		= 39,
 	MSM_RPM_8930_ID_APPS_FABRIC_CFG_IOCTL			= 40,
 	MSM_RPM_8930_ID_APPS_FABRIC_ARB_0			= 41,
-	MSM_RPM_8930_ID_APPS_FABRIC_ARB_5 =
-		MSM_RPM_8930_ID_APPS_FABRIC_ARB_0 + 5,
-	MSM_RPM_8930_ID_SYS_FABRIC_CFG_HALT_0			= 47,
-	MSM_RPM_8930_ID_SYS_FABRIC_CFG_HALT_1			= 48,
-	MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_0			= 49,
-	MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_1			= 50,
-	MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_2			= 51,
-	MSM_RPM_8930_ID_SYS_FABRIC_CFG_IOCTL			= 52,
-	MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_0			= 53,
-	MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_19 =
-		MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_0 + 19,
+	MSM_RPM_8930_ID_APPS_FABRIC_ARB_11 =
+		MSM_RPM_8930_ID_APPS_FABRIC_ARB_0 + 11,
+	MSM_RPM_8930_ID_SYS_FABRIC_CFG_HALT_0			= 53,
+	MSM_RPM_8930_ID_SYS_FABRIC_CFG_HALT_1			= 54,
+	MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_0			= 55,
+	MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_1			= 56,
+	MSM_RPM_8930_ID_SYS_FABRIC_CFG_CLKMOD_2			= 57,
+	MSM_RPM_8930_ID_SYS_FABRIC_CFG_IOCTL			= 58,
+	MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_0			= 59,
+	MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_28 =
+		MSM_RPM_8930_ID_SYSTEM_FABRIC_ARB_0 + 28,
+	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_HALT_0			= 88,
+	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_HALT_1			= 89,
+	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_0		= 90,
+	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_1		= 91,
+	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_2		= 92,
+	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_IOCTL			= 93,
+	MSM_RPM_8930_ID_MM_FABRIC_ARB_0				= 94,
+	MSM_RPM_8930_ID_MM_FABRIC_ARB_22 =
+		MSM_RPM_8930_ID_MM_FABRIC_ARB_0	+ 22,
 
-	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_HALT_0			= 73,
-	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_HALT_1			= 74,
-	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_0		= 75,
-	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_1		= 76,
-	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_CLKMOD_2		= 77,
-	MSM_RPM_8930_ID_MMSS_FABRIC_CFG_IOCTL			= 78,
-	MSM_RPM_8930_ID_MM_FABRIC_ARB_0				= 79,
-	MSM_RPM_8930_ID_MM_FABRIC_ARB_10 =
-		MSM_RPM_8930_ID_MM_FABRIC_ARB_0	+ 10,
-
-	MSM_RPM_8930_ID_PM8038_S1_0				= 90,
-	MSM_RPM_8930_ID_PM8038_S1_1				= 91,
-	MSM_RPM_8930_ID_PM8038_S2_0				= 92,
-	MSM_RPM_8930_ID_PM8038_S2_1				= 93,
-	MSM_RPM_8930_ID_PM8038_S3_0				= 94,
-	MSM_RPM_8930_ID_PM8038_S3_1				= 95,
-	MSM_RPM_8930_ID_PM8038_S4_0				= 96,
-	MSM_RPM_8930_ID_PM8038_S4_1				= 97,
-	MSM_RPM_8930_ID_PM8038_S5_0				= 98,
-	MSM_RPM_8930_ID_PM8038_S5_1				= 99,
-	MSM_RPM_8930_ID_PM8038_S6_0				= 100,
-	MSM_RPM_8930_ID_PM8038_S6_1				= 101,
-	MSM_RPM_8930_ID_PM8038_L1_0				= 102,
-	MSM_RPM_8930_ID_PM8038_L1_1				= 103,
-	MSM_RPM_8930_ID_PM8038_L2_0				= 104,
-	MSM_RPM_8930_ID_PM8038_L2_1				= 105,
-	MSM_RPM_8930_ID_PM8038_L3_0				= 106,
-	MSM_RPM_8930_ID_PM8038_L3_1				= 107,
-	MSM_RPM_8930_ID_PM8038_L4_0				= 108,
-	MSM_RPM_8930_ID_PM8038_L4_1				= 109,
-	MSM_RPM_8930_ID_PM8038_L5_0				= 110,
-	MSM_RPM_8930_ID_PM8038_L5_1				= 111,
-	MSM_RPM_8930_ID_PM8038_L6_0				= 112,
-	MSM_RPM_8930_ID_PM8038_L6_1				= 113,
-	MSM_RPM_8930_ID_PM8038_L7_0				= 114,
-	MSM_RPM_8930_ID_PM8038_L7_1				= 115,
-	MSM_RPM_8930_ID_PM8038_L8_0				= 116,
-	MSM_RPM_8930_ID_PM8038_L8_1				= 117,
-	MSM_RPM_8930_ID_PM8038_L9_0				= 118,
-	MSM_RPM_8930_ID_PM8038_L9_1				= 119,
-	MSM_RPM_8930_ID_PM8038_L10_0				= 120,
-	MSM_RPM_8930_ID_PM8038_L10_1				= 121,
-	MSM_RPM_8930_ID_PM8038_L11_0				= 122,
-	MSM_RPM_8930_ID_PM8038_L11_1				= 123,
-	MSM_RPM_8930_ID_PM8038_L12_0				= 124,
-	MSM_RPM_8930_ID_PM8038_L12_1				= 125,
-	MSM_RPM_8930_ID_PM8038_L13_0				= 126,
-	MSM_RPM_8930_ID_PM8038_L13_1				= 127,
-	MSM_RPM_8930_ID_PM8038_L14_0				= 128,
-	MSM_RPM_8930_ID_PM8038_L14_1				= 129,
-	MSM_RPM_8930_ID_PM8038_L15_0				= 130,
-	MSM_RPM_8930_ID_PM8038_L15_1				= 131,
-	MSM_RPM_8930_ID_PM8038_L16_0				= 132,
-	MSM_RPM_8930_ID_PM8038_L16_1				= 133,
-	MSM_RPM_8930_ID_PM8038_L17_0				= 134,
-	MSM_RPM_8930_ID_PM8038_L17_1				= 135,
-	MSM_RPM_8930_ID_PM8038_L18_0				= 136,
-	MSM_RPM_8930_ID_PM8038_L18_1				= 137,
-	MSM_RPM_8930_ID_PM8038_L19_0				= 138,
-	MSM_RPM_8930_ID_PM8038_L19_1				= 139,
-	MSM_RPM_8930_ID_PM8038_L20_0				= 140,
-	MSM_RPM_8930_ID_PM8038_L20_1				= 141,
-	MSM_RPM_8930_ID_PM8038_L21_0				= 142,
-	MSM_RPM_8930_ID_PM8038_L21_1				= 143,
-	MSM_RPM_8930_ID_PM8038_L22_0				= 144,
-	MSM_RPM_8930_ID_PM8038_L22_1				= 145,
-	MSM_RPM_8930_ID_PM8038_L23_0				= 146,
-	MSM_RPM_8930_ID_PM8038_L23_1				= 147,
-	MSM_RPM_8930_ID_PM8038_L24_0				= 148,
-	MSM_RPM_8930_ID_PM8038_L24_1				= 149,
-	MSM_RPM_8930_ID_PM8038_L25_0				= 150,
-	MSM_RPM_8930_ID_PM8038_L25_1				= 151,
-	MSM_RPM_8930_ID_PM8038_L26_0				= 152,
-	MSM_RPM_8930_ID_PM8038_L26_1				= 153,
-	MSM_RPM_8930_ID_PM8038_L27_0				= 154,
-	MSM_RPM_8930_ID_PM8038_L27_1				= 155,
-	MSM_RPM_8930_ID_PM8038_CLK1_0				= 156,
-	MSM_RPM_8930_ID_PM8038_CLK1_1				= 157,
-	MSM_RPM_8930_ID_PM8038_CLK2_0				= 158,
-	MSM_RPM_8930_ID_PM8038_CLK2_1				= 159,
-	MSM_RPM_8930_ID_PM8038_LVS1				= 160,
-	MSM_RPM_8930_ID_PM8038_LVS2				= 161,
-	MSM_RPM_8930_ID_NCP_0					= 162,
-	MSM_RPM_8930_ID_NCP_1					= 163,
-	MSM_RPM_8930_ID_CXO_BUFFERS				= 164,
-	MSM_RPM_8930_ID_USB_OTG_SWITCH				= 165,
-	MSM_RPM_8930_ID_HDMI_SWITCH				= 166,
-	MSM_RPM_8930_ID_QDSS_CLK				= 167,
+	MSM_RPM_8930_ID_PM8038_S1_0				= 117,
+	MSM_RPM_8930_ID_PM8038_S1_1				= 118,
+	MSM_RPM_8930_ID_PM8038_S2_0				= 119,
+	MSM_RPM_8930_ID_PM8038_S2_1				= 120,
+	MSM_RPM_8930_ID_PM8038_S3_0				= 121,
+	MSM_RPM_8930_ID_PM8038_S3_1				= 122,
+	MSM_RPM_8930_ID_PM8038_S4_0				= 123,
+	MSM_RPM_8930_ID_PM8038_S4_1				= 124,
+	MSM_RPM_8930_ID_PM8038_S5_0				= 125,
+	MSM_RPM_8930_ID_PM8038_S5_1				= 126,
+	MSM_RPM_8930_ID_PM8038_S6_0				= 127,
+	MSM_RPM_8930_ID_PM8038_S6_1				= 128,
+	MSM_RPM_8930_ID_PM8038_L1_0				= 129,
+	MSM_RPM_8930_ID_PM8038_L1_1				= 130,
+	MSM_RPM_8930_ID_PM8038_L2_0				= 131,
+	MSM_RPM_8930_ID_PM8038_L2_1				= 132,
+	MSM_RPM_8930_ID_PM8038_L3_0				= 133,
+	MSM_RPM_8930_ID_PM8038_L3_1				= 134,
+	MSM_RPM_8930_ID_PM8038_L4_0				= 135,
+	MSM_RPM_8930_ID_PM8038_L4_1				= 136,
+	MSM_RPM_8930_ID_PM8038_L5_0				= 137,
+	MSM_RPM_8930_ID_PM8038_L5_1				= 138,
+	MSM_RPM_8930_ID_PM8038_L6_0				= 139,
+	MSM_RPM_8930_ID_PM8038_L6_1				= 140,
+	MSM_RPM_8930_ID_PM8038_L7_0				= 141,
+	MSM_RPM_8930_ID_PM8038_L7_1				= 142,
+	MSM_RPM_8930_ID_PM8038_L8_0				= 143,
+	MSM_RPM_8930_ID_PM8038_L8_1				= 144,
+	MSM_RPM_8930_ID_PM8038_L9_0				= 145,
+	MSM_RPM_8930_ID_PM8038_L9_1				= 146,
+	MSM_RPM_8930_ID_PM8038_L10_0				= 147,
+	MSM_RPM_8930_ID_PM8038_L10_1				= 148,
+	MSM_RPM_8930_ID_PM8038_L11_0				= 149,
+	MSM_RPM_8930_ID_PM8038_L11_1				= 150,
+	MSM_RPM_8930_ID_PM8038_L12_0				= 151,
+	MSM_RPM_8930_ID_PM8038_L12_1				= 152,
+	MSM_RPM_8930_ID_PM8038_L13_0				= 153,
+	MSM_RPM_8930_ID_PM8038_L13_1				= 154,
+	MSM_RPM_8930_ID_PM8038_L14_0				= 155,
+	MSM_RPM_8930_ID_PM8038_L14_1				= 156,
+	MSM_RPM_8930_ID_PM8038_L15_0				= 157,
+	MSM_RPM_8930_ID_PM8038_L15_1				= 158,
+	MSM_RPM_8930_ID_PM8038_L16_0				= 159,
+	MSM_RPM_8930_ID_PM8038_L16_1				= 160,
+	MSM_RPM_8930_ID_PM8038_L17_0				= 161,
+	MSM_RPM_8930_ID_PM8038_L17_1				= 162,
+	MSM_RPM_8930_ID_PM8038_L18_0				= 163,
+	MSM_RPM_8930_ID_PM8038_L18_1				= 164,
+	MSM_RPM_8930_ID_PM8038_L19_0				= 165,
+	MSM_RPM_8930_ID_PM8038_L19_1				= 166,
+	MSM_RPM_8930_ID_PM8038_L20_0				= 167,
+	MSM_RPM_8930_ID_PM8038_L20_1				= 168,
+	MSM_RPM_8930_ID_PM8038_L21_0				= 169,
+	MSM_RPM_8930_ID_PM8038_L21_1				= 170,
+	MSM_RPM_8930_ID_PM8038_L22_0				= 171,
+	MSM_RPM_8930_ID_PM8038_L22_1				= 172,
+	MSM_RPM_8930_ID_PM8038_L23_0				= 173,
+	MSM_RPM_8930_ID_PM8038_L23_1				= 174,
+	MSM_RPM_8930_ID_PM8038_L24_0				= 175,
+	MSM_RPM_8930_ID_PM8038_L24_1				= 176,
+	MSM_RPM_8930_ID_PM8038_L25_0				= 177,
+	MSM_RPM_8930_ID_PM8038_L25_1				= 178,
+	MSM_RPM_8930_ID_PM8038_L26_0				= 179,
+	MSM_RPM_8930_ID_PM8038_L26_1				= 180,
+	MSM_RPM_8930_ID_PM8038_L27_0				= 181,
+	MSM_RPM_8930_ID_PM8038_L27_1				= 182,
+	MSM_RPM_8930_ID_PM8038_CLK1_0				= 183,
+	MSM_RPM_8930_ID_PM8038_CLK1_1				= 184,
+	MSM_RPM_8930_ID_PM8038_CLK2_0				= 185,
+	MSM_RPM_8930_ID_PM8038_CLK2_1				= 186,
+	MSM_RPM_8930_ID_PM8038_LVS1				= 187,
+	MSM_RPM_8930_ID_PM8038_LVS2				= 188,
+	MSM_RPM_8930_ID_NCP_0					= 189,
+	MSM_RPM_8930_ID_NCP_1					= 190,
+	MSM_RPM_8930_ID_CXO_BUFFERS				= 191,
+	MSM_RPM_8930_ID_USB_OTG_SWITCH				= 192,
+	MSM_RPM_8930_ID_HDMI_SWITCH				= 193,
+	MSM_RPM_8930_ID_QDSS_CLK				= 194,
 	MSM_RPM_8930_ID_LAST = MSM_RPM_8930_ID_QDSS_CLK,
 };
 
@@ -284,10 +283,6 @@
 	MSM_RPM_8930_STATUS_ID_PM8038_S3_1			= 36,
 	MSM_RPM_8930_STATUS_ID_PM8038_S4_0			= 37,
 	MSM_RPM_8930_STATUS_ID_PM8038_S4_1			= 38,
-	MSM_RPM_8930_STATUS_ID_PM8038_S5_0			= 39,
-	MSM_RPM_8930_STATUS_ID_PM8038_S5_1			= 40,
-	MSM_RPM_8930_STATUS_ID_PM8038_S6_0			= 41,
-	MSM_RPM_8930_STATUS_ID_PM8038_S6_1			= 42,
 	MSM_RPM_8930_STATUS_ID_PM8038_L1_0			= 43,
 	MSM_RPM_8930_STATUS_ID_PM8038_L1_1			= 44,
 	MSM_RPM_8930_STATUS_ID_PM8038_L2_0			= 45,
@@ -353,7 +348,8 @@
 	MSM_RPM_8930_STATUS_ID_CXO_BUFFERS			= 105,
 	MSM_RPM_8930_STATUS_ID_USB_OTG_SWITCH			= 106,
 	MSM_RPM_8930_STATUS_ID_HDMI_SWITCH			= 107,
-	MSM_RPM_8930_STATUS_ID_LAST = MSM_RPM_8930_STATUS_ID_HDMI_SWITCH,
+	MSM_RPM_8930_STATUS_ID_QDSS_CLK				= 108,
+	MSM_RPM_8930_STATUS_ID_LAST = MSM_RPM_8930_STATUS_ID_QDSS_CLK,
 };
 
 #endif /* __ARCH_ARM_MACH_MSM_RPM_8930_H */
diff --git a/arch/arm/mach-msm/include/mach/rpm.h b/arch/arm/mach-msm/include/mach/rpm.h
index 40a8c9b..80ec683 100644
--- a/arch/arm/mach-msm/include/mach/rpm.h
+++ b/arch/arm/mach-msm/include/mach/rpm.h
@@ -601,6 +601,7 @@
 	MSM_RPM_STATUS_ID_DDR_DMM_1,
 	MSM_RPM_STATUS_ID_EBI1_CH0_RANGE,
 	MSM_RPM_STATUS_ID_EBI1_CH1_RANGE,
+	MSM_RPM_STATUS_ID_QDSS_CLK,
 
 	/* 8660 Specific */
 	MSM_RPM_STATUS_ID_PLL_4,
diff --git a/arch/arm/mach-msm/include/mach/uncompress.h b/arch/arm/mach-msm/include/mach/uncompress.h
index 7560dc2..d46bd77 100644
--- a/arch/arm/mach-msm/include/mach/uncompress.h
+++ b/arch/arm/mach-msm/include/mach/uncompress.h
@@ -1,6 +1,7 @@
 /* arch/arm/mach-msm/include/mach/uncompress.h
  *
  * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2012, 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
@@ -34,18 +35,18 @@
 	 * Wait for TX_READY to be set; but skip it if we have a
 	 * TX underrun.
 	 */
-	if (!(__raw_readl(base + UARTDM_SR_OFFSET) & 0x08))
-		while (!(__raw_readl(base + UARTDM_ISR_OFFSET) & 0x80))
+	if (!(__raw_readl_no_log(base + UARTDM_SR_OFFSET) & 0x08))
+		while (!(__raw_readl_no_log(base + UARTDM_ISR_OFFSET) & 0x80))
 			cpu_relax();
 
-	__raw_writel(0x300, base + UARTDM_CR_OFFSET);
-	__raw_writel(0x1, base + UARTDM_NCF_TX_OFFSET);
-	__raw_writel(c, base + UARTDM_TF_OFFSET);
+	__raw_writel_no_log(0x300, base + UARTDM_CR_OFFSET);
+	__raw_writel_no_log(0x1, base + UARTDM_NCF_TX_OFFSET);
+	__raw_writel_no_log(c, base + UARTDM_TF_OFFSET);
 #else
 	/* Wait for TX_READY to be set */
-	while (!(__raw_readl(base + 0x08) & 0x04))
+	while (!(__raw_readl_no_log(base + 0x08) & 0x04))
 		cpu_relax();
-	__raw_writel(c, base + 0x0c);
+	__raw_writel_no_log(c, base + 0x0c);
 #endif
 #endif
 }
diff --git a/arch/arm/mach-msm/mdm2.c b/arch/arm/mach-msm/mdm2.c
index bf4e6a4..5db8b40 100644
--- a/arch/arm/mach-msm/mdm2.c
+++ b/arch/arm/mach-msm/mdm2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, 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
@@ -33,7 +33,6 @@
 #include <asm/mach-types.h>
 #include <asm/uaccess.h>
 #include <mach/mdm2.h>
-#include <mach/mdm-peripheral.h>
 #include <mach/restart.h>
 #include <mach/subsystem_notif.h>
 #include <mach/subsystem_restart.h>
@@ -46,38 +45,63 @@
 #define MDM_MODEM_TIMEOUT	6000
 #define MDM_HOLD_TIME		4000
 #define MDM_MODEM_DELTA		100
-#define IFLINE_UP			1
-#define IFLINE_DOWN			0
 
 static int mdm_debug_on;
-static struct mdm_callbacks mdm_cb;
+static int first_power_on = 1;
+static int hsic_peripheral_status = 1;
+static DEFINE_MUTEX(hsic_status_lock);
 
-#define MDM_DBG(...)	do { if (mdm_debug_on) \
-					pr_info(__VA_ARGS__); \
-			} while (0);
+static void mdm_peripheral_connect(struct mdm_modem_drv *mdm_drv)
+{
+	mutex_lock(&hsic_status_lock);
+	if (hsic_peripheral_status)
+		goto out;
+	if (mdm_drv->pdata->peripheral_platform_device)
+		platform_device_add(mdm_drv->pdata->peripheral_platform_device);
+	hsic_peripheral_status = 1;
+out:
+	mutex_unlock(&hsic_status_lock);
+}
+
+static void mdm_peripheral_disconnect(struct mdm_modem_drv *mdm_drv)
+{
+	mutex_lock(&hsic_status_lock);
+	if (!hsic_peripheral_status)
+		goto out;
+	if (mdm_drv->pdata->peripheral_platform_device)
+		platform_device_del(mdm_drv->pdata->peripheral_platform_device);
+	hsic_peripheral_status = 0;
+out:
+	mutex_unlock(&hsic_status_lock);
+}
 
 static void power_on_mdm(struct mdm_modem_drv *mdm_drv)
 {
-	peripheral_disconnect();
+	mdm_peripheral_disconnect(mdm_drv);
 
-	/* Pull both ERR_FATAL and RESET low */
-	MDM_DBG("Pulling PWR and RESET gpio's low\n");
+	/* Pull RESET gpio low and wait for it to settle. */
+	pr_debug("Pulling RESET gpio low\n");
 	gpio_direction_output(mdm_drv->ap2mdm_pmic_reset_n_gpio, 0);
-	gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio, 0);
-	/* Wait for them to settle. */
 	usleep(1000);
 
 	/* Deassert RESET first and wait for ir to settle. */
-	MDM_DBG("%s: Pulling RESET gpio high\n", __func__);
+	pr_debug("%s: Pulling RESET gpio high\n", __func__);
 	gpio_direction_output(mdm_drv->ap2mdm_pmic_reset_n_gpio, 1);
 	usleep(1000);
 
-	/* Pull PWR gpio high and wait for it to settle. */
-	MDM_DBG("%s: Powering on mdm modem\n", __func__);
-	gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio, 1);
-	usleep(1000);
-
-	peripheral_connect();
+	/* Pull PWR gpio high and wait for it to settle, but only
+	 * the first time the mdm is powered up.
+	 * Some targets do not use ap2mdm_kpdpwr_n_gpio.
+	 */
+	if (first_power_on) {
+		if (mdm_drv->ap2mdm_kpdpwr_n_gpio > 0) {
+			pr_debug("%s: Powering on mdm modem\n", __func__);
+			gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio, 1);
+			usleep(1000);
+		}
+		first_power_on = 0;
+	}
+	mdm_peripheral_connect(mdm_drv);
 
 	msleep(200);
 }
@@ -92,7 +116,6 @@
 		if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
 			break;
 	}
-
 	if (i <= 0) {
 		pr_err("%s: MDM2AP_STATUS never went low.\n",
 			 __func__);
@@ -103,12 +126,9 @@
 			msleep(MDM_MODEM_DELTA);
 		}
 	}
-
-	peripheral_disconnect();
-}
-
-static void normal_boot_done(struct mdm_modem_drv *mdm_drv)
-{
+	if (mdm_drv->ap2mdm_kpdpwr_n_gpio > 0)
+		gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio, 0);
+	mdm_peripheral_disconnect(mdm_drv);
 }
 
 static void debug_state_changed(int value)
@@ -116,24 +136,25 @@
 	mdm_debug_on = value;
 }
 
-static void mdm_status_changed(int value)
+static void mdm_status_changed(struct mdm_modem_drv *mdm_drv, int value)
 {
-	MDM_DBG("%s: value:%d\n", __func__, value);
+	pr_debug("%s: value:%d\n", __func__, value);
 
 	if (value) {
-		peripheral_disconnect();
-		peripheral_connect();
+		mdm_peripheral_disconnect(mdm_drv);
+		mdm_peripheral_connect(mdm_drv);
 	}
 }
 
+static struct mdm_ops mdm_cb = {
+	.power_on_mdm_cb = power_on_mdm,
+	.power_down_mdm_cb = power_down_mdm,
+	.debug_state_changed_cb = debug_state_changed,
+	.status_cb = mdm_status_changed,
+};
+
 static int __init mdm_modem_probe(struct platform_device *pdev)
 {
-	/* Instantiate driver object. */
-	mdm_cb.power_on_mdm_cb = power_on_mdm;
-	mdm_cb.power_down_mdm_cb = power_down_mdm;
-	mdm_cb.normal_boot_done_cb = normal_boot_done;
-	mdm_cb.debug_state_changed_cb = debug_state_changed;
-	mdm_cb.status_cb = mdm_status_changed;
 	return mdm_common_create(pdev, &mdm_cb);
 }
 
diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index 023df69..b672957 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, 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
@@ -48,10 +48,6 @@
 
 #define EXTERNAL_MODEM "external_modem"
 
-#define MDM_DBG(...)	do { if (mdm_debug_on) \
-					pr_info(__VA_ARGS__); \
-			} while (0);
-
 static struct mdm_modem_drv *mdm_drv;
 
 DECLARE_COMPLETION(mdm_needs_reload);
@@ -70,11 +66,11 @@
 		return -EINVAL;
 	}
 
-	MDM_DBG("%s: Entering ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
+	pr_debug("%s: Entering ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
 	switch (cmd) {
 	case WAKE_CHARM:
-		MDM_DBG("%s: Powering on\n", __func__);
-		mdm_drv->power_on_mdm_cb(mdm_drv);
+		pr_info("%s: Powering on mdm\n", __func__);
+		mdm_drv->ops->power_on_mdm_cb(mdm_drv);
 		break;
 	case CHECK_FOR_BOOT:
 		if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
@@ -83,16 +79,19 @@
 			put_user(0, (unsigned long __user *) arg);
 		break;
 	case NORMAL_BOOT_DONE:
-		MDM_DBG("%s: check if mdm is booted up\n", __func__);
+		pr_debug("%s: check if mdm is booted up\n", __func__);
 		get_user(status, (unsigned long __user *) arg);
-		if (status)
+		if (status) {
+			pr_debug("%s: normal boot failed\n", __func__);
 			mdm_drv->mdm_boot_status = -EIO;
-		else
+		} else {
+			pr_info("%s: normal boot done\n", __func__);
 			mdm_drv->mdm_boot_status = 0;
+		}
 		mdm_drv->mdm_ready = 1;
 
-		if (mdm_drv->normal_boot_done_cb != NULL)
-			mdm_drv->normal_boot_done_cb(mdm_drv);
+		if (mdm_drv->ops->normal_boot_done_cb != NULL)
+			mdm_drv->ops->normal_boot_done_cb(mdm_drv);
 
 		if (!first_boot)
 			complete(&mdm_boot);
@@ -100,16 +99,18 @@
 			first_boot = 0;
 		break;
 	case RAM_DUMP_DONE:
-		MDM_DBG("%s: mdm done collecting RAM dumps\n", __func__);
+		pr_debug("%s: mdm done collecting RAM dumps\n", __func__);
 		get_user(status, (unsigned long __user *) arg);
 		if (status)
 			mdm_drv->mdm_ram_dump_status = -EIO;
-		else
+		else {
+			pr_info("%s: ramdump collection completed\n", __func__);
 			mdm_drv->mdm_ram_dump_status = 0;
+		}
 		complete(&mdm_ram_dumps);
 		break;
 	case WAIT_FOR_RESTART:
-		MDM_DBG("%s: wait for mdm to need images reloaded\n",
+		pr_debug("%s: wait for mdm to need images reloaded\n",
 				__func__);
 		ret = wait_for_completion_interruptible(&mdm_needs_reload);
 		if (!ret)
@@ -128,7 +129,7 @@
 
 static void mdm_fatal_fn(struct work_struct *work)
 {
-	MDM_DBG("%s: Reseting the mdm due to an errfatal\n", __func__);
+	pr_info("%s: Reseting the mdm due to an errfatal\n", __func__);
 	subsystem_restart(EXTERNAL_MODEM);
 }
 
@@ -138,15 +139,15 @@
 {
 	int value = gpio_get_value(mdm_drv->mdm2ap_status_gpio);
 
-	mdm_drv->status_cb(value);
+	mdm_drv->ops->status_cb(mdm_drv, value);
 
-	MDM_DBG("%s: status:%d\n", __func__, value);
+	pr_debug("%s: status:%d\n", __func__, value);
 
 	if ((value == 0) && mdm_drv->mdm_ready) {
-		MDM_DBG("%s: scheduling work now\n", __func__);
+		pr_info("%s: unexpected reset external modem\n", __func__);
 		subsystem_restart(EXTERNAL_MODEM);
 	} else if (value == 1) {
-		MDM_DBG("%s: mdm is now ready\n", __func__);
+		pr_info("%s: status = 1: mdm is now ready\n", __func__);
 	}
 }
 
@@ -161,10 +162,10 @@
 
 static irqreturn_t mdm_errfatal(int irq, void *dev_id)
 {
-	MDM_DBG("%s: mdm got errfatal interrupt\n", __func__);
+	pr_debug("%s: mdm got errfatal interrupt\n", __func__);
 	if (mdm_drv->mdm_ready &&
 		(gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 1)) {
-		MDM_DBG("%s: scheduling work now\n", __func__);
+		pr_debug("%s: scheduling work now\n", __func__);
 		queue_work(mdm_queue, &mdm_fatal_work);
 	}
 	return IRQ_HANDLED;
@@ -193,7 +194,7 @@
 {
 	int i;
 
-	MDM_DBG("%s: setting AP2MDM_ERRFATAL high for a non graceful reset\n",
+	pr_debug("%s: setting AP2MDM_ERRFATAL high for a non graceful reset\n",
 			 __func__);
 	mdm_disable_irqs();
 	gpio_set_value(mdm_drv->ap2mdm_errfatal_gpio, 1);
@@ -218,7 +219,7 @@
 
 static irqreturn_t mdm_status_change(int irq, void *dev_id)
 {
-	MDM_DBG("%s: mdm sent status change interrupt\n", __func__);
+	pr_debug("%s: mdm sent status change interrupt\n", __func__);
 
 	queue_work(mdm_queue, &mdm_status_work);
 
@@ -229,13 +230,19 @@
 {
 	mdm_drv->mdm_ready = 0;
 	gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 1);
-	mdm_drv->power_down_mdm_cb(mdm_drv);
+	if (mdm_drv->pdata->ramdump_delay_ms > 0) {
+		/* Wait for the external modem to complete
+		 * its preparation for ramdumps.
+		 */
+		mdelay(mdm_drv->pdata->ramdump_delay_ms);
+	}
+	mdm_drv->ops->power_down_mdm_cb(mdm_drv);
 	return 0;
 }
 
 static int mdm_subsys_powerup(const struct subsys_data *crashed_subsys)
 {
-	mdm_drv->power_on_mdm_cb(mdm_drv);
+	mdm_drv->ops->power_on_mdm_cb(mdm_drv);
 	mdm_drv->boot_type = CHARM_NORMAL_BOOT;
 	complete(&mdm_needs_reload);
 	wait_for_completion(&mdm_boot);
@@ -254,7 +261,7 @@
 		wait_for_completion(&mdm_ram_dumps);
 		INIT_COMPLETION(mdm_ram_dumps);
 		gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 1);
-		mdm_drv->power_down_mdm_cb(mdm_drv);
+		mdm_drv->ops->power_down_mdm_cb(mdm_drv);
 	}
 	return mdm_drv->mdm_ram_dump_status;
 }
@@ -269,8 +276,8 @@
 static int mdm_debug_on_set(void *data, u64 val)
 {
 	mdm_debug_on = val;
-	if (mdm_drv->debug_state_changed_cb)
-		mdm_drv->debug_state_changed_cb(mdm_debug_on);
+	if (mdm_drv->ops->debug_state_changed_cb)
+		mdm_drv->ops->debug_state_changed_cb(mdm_debug_on);
 	return 0;
 }
 
@@ -298,7 +305,7 @@
 }
 
 static void mdm_modem_initialize_data(struct platform_device  *pdev,
-				struct mdm_callbacks *p_mdm_cb)
+				struct mdm_ops *mdm_ops)
 {
 	struct resource *pres;
 
@@ -352,15 +359,12 @@
 
 	mdm_drv->boot_type                  = CHARM_NORMAL_BOOT;
 
-	mdm_drv->power_on_mdm_cb            = p_mdm_cb->power_on_mdm_cb;
-	mdm_drv->power_down_mdm_cb          = p_mdm_cb->power_down_mdm_cb;
-	mdm_drv->normal_boot_done_cb        = p_mdm_cb->normal_boot_done_cb;
-	mdm_drv->debug_state_changed_cb     = p_mdm_cb->debug_state_changed_cb;
-	mdm_drv->status_cb                  = p_mdm_cb->status_cb;
+	mdm_drv->ops      = mdm_ops;
+	mdm_drv->pdata    = pdev->dev.platform_data;
 }
 
 int mdm_common_create(struct platform_device  *pdev,
-					  struct mdm_callbacks *p_mdm_cb)
+					  struct mdm_ops *p_mdm_cb)
 {
 	int ret = -1, irq;
 
@@ -371,8 +375,8 @@
 	}
 
 	mdm_modem_initialize_data(pdev, p_mdm_cb);
-	if (mdm_drv->debug_state_changed_cb)
-		mdm_drv->debug_state_changed_cb(mdm_debug_on);
+	if (mdm_drv->ops->debug_state_changed_cb)
+		mdm_drv->ops->debug_state_changed_cb(mdm_debug_on);
 
 	gpio_request(mdm_drv->ap2mdm_status_gpio, "AP2MDM_STATUS");
 	gpio_request(mdm_drv->ap2mdm_errfatal_gpio, "AP2MDM_ERRFATAL");
@@ -494,7 +498,7 @@
 
 void mdm_common_modem_shutdown(struct platform_device *pdev)
 {
-	MDM_DBG("%s: setting AP2MDM_STATUS low for a graceful restart\n",
+	pr_debug("%s: setting AP2MDM_STATUS low for a graceful restart\n",
 		__func__);
 
 	mdm_disable_irqs();
@@ -504,7 +508,7 @@
 	if (mdm_drv->ap2mdm_wakeup_gpio > 0)
 		gpio_set_value(mdm_drv->ap2mdm_wakeup_gpio, 1);
 
-	mdm_drv->power_down_mdm_cb(mdm_drv);
+	mdm_drv->ops->power_down_mdm_cb(mdm_drv);
 
 	if (mdm_drv->ap2mdm_wakeup_gpio > 0)
 		gpio_set_value(mdm_drv->ap2mdm_wakeup_gpio, 0);
diff --git a/arch/arm/mach-msm/mdm_private.h b/arch/arm/mach-msm/mdm_private.h
index bc8541e..206bd8b 100644
--- a/arch/arm/mach-msm/mdm_private.h
+++ b/arch/arm/mach-msm/mdm_private.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, 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
@@ -15,6 +15,14 @@
 
 struct mdm_modem_drv;
 
+struct mdm_ops {
+	void (*power_on_mdm_cb)(struct mdm_modem_drv *mdm_drv);
+	void (*normal_boot_done_cb)(struct mdm_modem_drv *mdm_drv);
+	void (*power_down_mdm_cb)(struct mdm_modem_drv *mdm_drv);
+	void (*debug_state_changed_cb)(int value);
+	void (*status_cb)(struct mdm_modem_drv *mdm_drv, int value);
+};
+
 /* Private mdm2 data structure */
 struct mdm_modem_drv {
 	unsigned mdm2ap_errfatal_gpio;
@@ -34,23 +42,12 @@
 	enum charm_boot_type boot_type;
 	int mdm_debug_on;
 
-	void (*power_on_mdm_cb)(struct mdm_modem_drv *mdm_drv);
-	void (*normal_boot_done_cb)(struct mdm_modem_drv *mdm_drv);
-	void (*power_down_mdm_cb)(struct mdm_modem_drv *mdm_drv);
-	void (*debug_state_changed_cb)(int value);
-	void (*status_cb)(int value);
-};
-
-struct mdm_callbacks {
-	void (*power_on_mdm_cb)(struct mdm_modem_drv *mdm_drv);
-	void (*normal_boot_done_cb)(struct mdm_modem_drv *mdm_drv);
-	void (*power_down_mdm_cb)(struct mdm_modem_drv *mdm_drv);
-	void (*debug_state_changed_cb)(int value);
-	void (*status_cb)(int value);
+	struct mdm_ops *ops;
+	struct mdm_platform_data *pdata;
 };
 
 int mdm_common_create(struct platform_device  *pdev,
-					  struct mdm_callbacks *mdm_cb);
+					  struct mdm_ops *mdm_cb);
 int mdm_common_modem_remove(struct platform_device *pdev);
 void mdm_common_modem_shutdown(struct platform_device *pdev);
 void mdm_common_set_debug_state(int value);
diff --git a/arch/arm/mach-msm/pil-gss.c b/arch/arm/mach-msm/pil-gss.c
new file mode 100644
index 0000000..f3e83d9
--- /dev/null
+++ b/arch/arm/mach-msm/pil-gss.c
@@ -0,0 +1,403 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/elf.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/clk.h>
+#include <linux/smp.h>
+
+#include <mach/msm_iomap.h>
+#include <mach/msm_xo.h>
+
+#include "peripheral-loader.h"
+#include "scm-pas.h"
+
+#define GSS_CSR_AHB_CLK_SEL	0x0
+#define GSS_CSR_RESET		0x4
+#define GSS_CSR_CLK_BLK_CONFIG	0x8
+#define GSS_CSR_CLK_ENABLE	0xC
+#define GSS_CSR_BOOT_REMAP	0x14
+#define GSS_CSR_POWER_UP_DOWN	0x18
+#define GSS_CSR_CFG_HID		0x2C
+
+#define GSS_SLP_CLK_CTL		(MSM_CLK_CTL_BASE + 0x2C60)
+#define GSS_RESET		(MSM_CLK_CTL_BASE + 0x2C64)
+#define GSS_CLAMP_ENA		(MSM_CLK_CTL_BASE + 0x2C68)
+#define GSS_CXO_SRC_CTL		(MSM_CLK_CTL_BASE + 0x2C74)
+
+#define PLL5_MODE		(MSM_CLK_CTL_BASE + 0x30E0)
+#define PLL5_L_VAL		(MSM_CLK_CTL_BASE + 0x30E4)
+#define PLL5_M_VAL		(MSM_CLK_CTL_BASE + 0x30E8)
+#define PLL5_N_VAL		(MSM_CLK_CTL_BASE + 0x30EC)
+#define PLL5_CONFIG		(MSM_CLK_CTL_BASE + 0x30F4)
+#define PLL5_STATUS		(MSM_CLK_CTL_BASE + 0x30F8)
+#define PLL_ENA_GSS		(MSM_CLK_CTL_BASE + 0x3480)
+#define PLL_ENA_RPM		(MSM_CLK_CTL_BASE + 0x34A0)
+
+#define PLL5_VOTE		BIT(5)
+#define PLL_STATUS		BIT(16)
+#define REMAP_ENABLE		BIT(16)
+#define A5_POWER_STATUS		BIT(4)
+#define A5_POWER_ENA		BIT(0)
+#define NAV_POWER_ENA		BIT(1)
+#define XO_CLK_BRANCH_ENA	BIT(0)
+#define SLP_CLK_BRANCH_ENA	BIT(4)
+#define A5_RESET		BIT(0)
+
+#define PROXY_VOTE_TIMEOUT	10000
+
+struct gss_data {
+	void __iomem *base;
+	void __iomem *qgic2_base;
+	unsigned long start_addr;
+	struct delayed_work work;
+	struct clk *xo;
+};
+
+static int nop_verify_blob(struct pil_desc *pil, u32 phy_addr, size_t size)
+{
+	return 0;
+}
+
+static int pil_gss_init_image(struct pil_desc *pil, const u8 *metadata,
+		size_t size)
+{
+	const struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
+	struct gss_data *drv = dev_get_drvdata(pil->dev);
+	drv->start_addr = ehdr->e_entry;
+	return 0;
+}
+
+static int make_gss_proxy_votes(struct device *dev)
+{
+	int ret;
+	struct gss_data *drv = dev_get_drvdata(dev);
+
+	ret = clk_prepare_enable(drv->xo);
+	if (ret) {
+		dev_err(dev, "Failed to enable XO\n");
+		return ret;
+	}
+	schedule_delayed_work(&drv->work, msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+	return 0;
+}
+
+static void remove_gss_proxy_votes(struct work_struct *work)
+{
+	struct gss_data *drv = container_of(work, struct gss_data, work.work);
+	clk_disable_unprepare(drv->xo);
+}
+
+static void remove_gss_proxy_votes_now(struct gss_data *drv)
+{
+	flush_delayed_work(&drv->work);
+}
+
+static void gss_init(struct gss_data *drv)
+{
+	void __iomem *base = drv->base;
+
+	/* Supply clocks to GSS. */
+	writel_relaxed(XO_CLK_BRANCH_ENA, GSS_CXO_SRC_CTL);
+	writel_relaxed(SLP_CLK_BRANCH_ENA, GSS_SLP_CLK_CTL);
+
+	/* Deassert GSS reset and clamps. */
+	writel_relaxed(0x0, GSS_RESET);
+	writel_relaxed(0x0, GSS_CLAMP_ENA);
+	mb();
+
+	/*
+	 * Configure clock source and dividers for 288MHz core, 144MHz AXI and
+	 * 72MHz AHB, all derived from the 288MHz PLL.
+	 */
+	writel_relaxed(0x341, base + GSS_CSR_CLK_BLK_CONFIG);
+	writel_relaxed(0x1, base + GSS_CSR_AHB_CLK_SEL);
+
+	/* Assert all GSS resets. */
+	writel_relaxed(0x7F, base + GSS_CSR_RESET);
+
+	/* Enable all bus clocks and wait for resets to propagate. */
+	writel_relaxed(0x1F, base + GSS_CSR_CLK_ENABLE);
+	mb();
+	udelay(1);
+
+	/* Release subsystem from reset, but leave A5 in reset. */
+	writel_relaxed(A5_RESET, base + GSS_CSR_RESET);
+}
+
+static void setup_qgic2_bus_access(void *data)
+{
+	struct gss_data *drv = data;
+	void __iomem *base = drv->base;
+	int i;
+
+	writel_relaxed(0x2, base + GSS_CSR_CFG_HID);
+	for (i = 0; i <= 3; i++)
+		readl_relaxed(drv->qgic2_base);
+}
+
+static int pil_gss_shutdown(struct pil_desc *pil)
+{
+	struct gss_data *drv = dev_get_drvdata(pil->dev);
+	void __iomem *base = drv->base;
+	u32 regval;
+	int ret;
+
+	ret = clk_prepare_enable(drv->xo);
+	if (ret) {
+		dev_err(pil->dev, "Failed to enable XO\n");
+		return ret;
+	}
+
+	/*
+	 * Vote PLL on in GSS's voting register and wait for it to enable.
+	 * The PLL must be enable to switch the GFMUX to a low-power source.
+	 */
+	writel_relaxed(PLL5_VOTE, PLL_ENA_GSS);
+	while ((readl_relaxed(PLL5_STATUS) & PLL_STATUS) == 0)
+		cpu_relax();
+
+	/* Perform one-time GSS initialization. */
+	gss_init(drv);
+
+	/* Assert A5 reset. */
+	regval = readl_relaxed(base + GSS_CSR_RESET);
+	regval |= A5_RESET;
+	writel_relaxed(regval, base + GSS_CSR_RESET);
+
+	/* Power down A5 and NAV. */
+	regval = readl_relaxed(base + GSS_CSR_POWER_UP_DOWN);
+	regval &= ~(A5_POWER_ENA|NAV_POWER_ENA);
+	writel_relaxed(regval, base + GSS_CSR_POWER_UP_DOWN);
+
+	/* Select XO clock source and increase dividers to save power. */
+	regval = readl_relaxed(base + GSS_CSR_CLK_BLK_CONFIG);
+	regval |= 0x3FF;
+	writel_relaxed(regval, base + GSS_CSR_CLK_BLK_CONFIG);
+
+	/* Disable bus clocks. */
+	writel_relaxed(0x1F, base + GSS_CSR_CLK_ENABLE);
+
+	/* Clear GSS PLL votes. */
+	writel_relaxed(0, PLL_ENA_GSS);
+	mb();
+
+	clk_disable_unprepare(drv->xo);
+	remove_gss_proxy_votes_now(drv);
+
+	return 0;
+}
+
+static int pil_gss_reset(struct pil_desc *pil)
+{
+	struct gss_data *drv = dev_get_drvdata(pil->dev);
+	void __iomem *base = drv->base;
+	unsigned long start_addr = drv->start_addr;
+	int ret;
+
+	ret = make_gss_proxy_votes(pil->dev);
+	if (ret)
+		return ret;
+
+	/* Vote PLL on in GSS's voting register and wait for it to enable. */
+	writel_relaxed(PLL5_VOTE, PLL_ENA_GSS);
+	while ((readl_relaxed(PLL5_STATUS) & PLL_STATUS) == 0)
+		cpu_relax();
+
+	/* Perform GSS initialization. */
+	gss_init(drv);
+
+	/* Configure boot address and enable remap. */
+	writel_relaxed(REMAP_ENABLE | (start_addr >> 16),
+			base + GSS_CSR_BOOT_REMAP);
+
+	/* Power up A5 core. */
+	writel_relaxed(A5_POWER_ENA, base + GSS_CSR_POWER_UP_DOWN);
+	while (!(readl_relaxed(base + GSS_CSR_POWER_UP_DOWN) & A5_POWER_STATUS))
+		cpu_relax();
+
+	/*
+	 * Apply a 8064 v1.0 workaround to configure QGIC bus access. This must
+	 * be done from Krait 0 to configure the Master ID correctly.
+	 */
+	ret = smp_call_function_single(0, setup_qgic2_bus_access, drv, 1);
+	if (ret) {
+		pr_err("Failed to configure QGIC2 bus access\n");
+		pil_gss_shutdown(pil);
+		return ret;
+	}
+
+	/* Release A5 from reset. */
+	writel_relaxed(0x0, base + GSS_CSR_RESET);
+
+	return 0;
+}
+
+static struct pil_reset_ops pil_gss_ops = {
+	.init_image = pil_gss_init_image,
+	.verify_blob = nop_verify_blob,
+	.auth_and_reset = pil_gss_reset,
+	.shutdown = pil_gss_shutdown,
+};
+
+static void configure_gss_pll(struct gss_data *drv)
+{
+	u32 regval, is_pll_enabled;
+
+	/* Check if PLL5 is enabled by FSM. */
+	is_pll_enabled = readl_relaxed(PLL5_STATUS) & PLL_STATUS;
+	if (!is_pll_enabled) {
+		/* Enable XO reference for PLL5 */
+		clk_prepare_enable(drv->xo);
+
+		/*
+		 * Assert a vote to hold PLL5 on in RPM register until other
+		 * voters are in place.
+		 */
+		regval = readl_relaxed(PLL_ENA_RPM);
+		regval |= PLL5_VOTE;
+		writel_relaxed(regval, PLL_ENA_RPM);
+
+		/* Ref clk = 27MHz and program pll5 to 288MHz */
+		writel_relaxed(0xF, PLL5_L_VAL);
+		writel_relaxed(0x0, PLL5_M_VAL);
+		writel_relaxed(0x1, PLL5_N_VAL);
+
+		regval = readl_relaxed(PLL5_CONFIG);
+		/* Disable the MN accumulator and enable the main output. */
+		regval &= ~BIT(22);
+		regval |= BIT(23);
+
+		/* Set pre-divider and post-divider values to 1 and 1 */
+		regval &= ~BIT(19);
+		regval &= ~(BIT(21)|BIT(20));
+
+		/* Set VCO frequency */
+		regval &= ~(BIT(17)|BIT(16));
+		writel_relaxed(regval, PLL5_CONFIG);
+
+		regval = readl_relaxed(PLL5_MODE);
+		/* De-assert reset to FSM */
+		regval &= ~BIT(21);
+		writel_relaxed(regval, PLL5_MODE);
+
+		/* Program bias count */
+		regval &= ~(0x3F << 14);
+		regval |= (0x1 << 14);
+		writel_relaxed(regval, PLL5_MODE);
+
+		/* Program lock count */
+		regval &= ~(0x3F << 8);
+		regval |= (0x8 << 8);
+		writel_relaxed(regval, PLL5_MODE);
+
+		/* Enable PLL FSM voting */
+		regval |= BIT(20);
+		writel_relaxed(regval, PLL5_MODE);
+	}
+}
+
+static int __devinit pil_gss_probe(struct platform_device *pdev)
+{
+	struct gss_data *drv;
+	struct resource *res;
+	struct pil_desc *desc;
+	int ret;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -EINVAL;
+
+	drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
+	if (!drv)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, drv);
+
+	drv->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+	if (!drv->base)
+		return -ENOMEM;
+
+	desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
+	if (!desc)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res)
+		return -EINVAL;
+
+	drv->qgic2_base = devm_ioremap(&pdev->dev, res->start,
+					resource_size(res));
+	if (!drv->qgic2_base)
+		return -ENOMEM;
+
+	drv->xo = clk_get(&pdev->dev, "xo");
+	if (IS_ERR(drv->xo))
+		return PTR_ERR(drv->xo);
+
+	desc->name = "gss";
+	desc->dev = &pdev->dev;
+
+	desc->ops = &pil_gss_ops;
+	dev_info(&pdev->dev, "using non-secure boot\n");
+
+	INIT_DELAYED_WORK(&drv->work, remove_gss_proxy_votes);
+
+	/* FIXME: Remove when PLL is configured by bootloaders. */
+	configure_gss_pll(drv);
+
+	ret = msm_pil_register(desc);
+	if (ret) {
+		flush_delayed_work_sync(&drv->work);
+		clk_put(drv->xo);
+	}
+	return ret;
+}
+
+static int __devexit pil_gss_remove(struct platform_device *pdev)
+{
+	struct gss_data *drv = platform_get_drvdata(pdev);
+	flush_delayed_work_sync(&drv->work);
+	clk_put(drv->xo);
+	return 0;
+}
+
+static struct platform_driver pil_gss_driver = {
+	.probe = pil_gss_probe,
+	.remove = __devexit_p(pil_gss_remove),
+	.driver = {
+		.name = "pil_gss",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init pil_gss_init(void)
+{
+	return platform_driver_register(&pil_gss_driver);
+}
+module_init(pil_gss_init);
+
+static void __exit pil_gss_exit(void)
+{
+	platform_driver_unregister(&pil_gss_driver);
+}
+module_exit(pil_gss_exit);
+
+MODULE_DESCRIPTION("Support for booting the GSS processor");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c b/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
index 0ddba89..4b8b7a6 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_adpcm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
  *
@@ -196,8 +196,10 @@
 static void audplay_config_hostpcm(struct audio *audio);
 static void audplay_buffer_refresh(struct audio *audio);
 static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
+#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audadpcm_post_event(struct audio *audio, int type,
 		union msm_audio_event_payload payload);
+#endif
 
 /* must be called with audio->lock held */
 static int audio_enable(struct audio *audio)
@@ -1433,6 +1435,7 @@
 	return 0;
 }
 
+#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audadpcm_post_event(struct audio *audio, int type,
 		union msm_audio_event_payload payload)
 {
@@ -1461,7 +1464,6 @@
 	wake_up(&audio->event_wait);
 }
 
-#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audadpcm_suspend(struct early_suspend *h)
 {
 	struct audadpcm_suspend_ctl *ctl =
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c b/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
index 85a3daa..a09b71b 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_amrnb.c
@@ -1,7 +1,7 @@
 /*
  * amrnb audio decoder device
  *
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
  *
@@ -194,8 +194,10 @@
 static void audamrnb_config_hostpcm(struct audio *audio);
 static void audamrnb_buffer_refresh(struct audio *audio);
 static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg);
+#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audamrnb_post_event(struct audio *audio, int type,
 		union msm_audio_event_payload payload);
+#endif
 
 /* must be called with audio->lock held */
 static int audamrnb_enable(struct audio *audio)
@@ -1330,6 +1332,7 @@
 	return 0;
 }
 
+#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audamrnb_post_event(struct audio *audio, int type,
 		union msm_audio_event_payload payload)
 {
@@ -1358,7 +1361,6 @@
 	wake_up(&audio->event_wait);
 }
 
-#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audamrnb_suspend(struct early_suspend *h)
 {
 	struct audamrnb_suspend_ctl *ctl =
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c b/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
index d6cf21d..48e9a9f 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_amrwb.c
@@ -1,6 +1,6 @@
 /* amrwb audio decoder device
  *
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
  *
@@ -195,8 +195,10 @@
 static void audamrwb_config_hostpcm(struct audio *audio);
 static void audamrwb_buffer_refresh(struct audio *audio);
 static void audamrwb_dsp_event(void *private, unsigned id, uint16_t *msg);
+#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audamrwb_post_event(struct audio *audio, int type,
 		union msm_audio_event_payload payload);
+#endif
 
 /* must be called with audio->lock held */
 static int audamrwb_enable(struct audio *audio)
@@ -1414,6 +1416,7 @@
 	return 0;
 }
 
+#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audamrwb_post_event(struct audio *audio, int type,
 		union msm_audio_event_payload payload)
 {
@@ -1442,7 +1445,6 @@
 	wake_up(&audio->event_wait);
 }
 
-#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audamrwb_suspend(struct early_suspend *h)
 {
 	struct audamrwb_suspend_ctl *ctl =
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_evrc.c b/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
index e5261b5..9b5694d 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_evrc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
  *
  * This code also borrows from audio_aac.c, which is
  * Copyright (C) 2008 Google, Inc.
@@ -189,8 +189,10 @@
 static void audevrc_dsp_event(void *private, unsigned id, uint16_t *msg);
 static void audevrc_config_hostpcm(struct audio *audio);
 static void audevrc_buffer_refresh(struct audio *audio);
+#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audevrc_post_event(struct audio *audio, int type,
 		union msm_audio_event_payload payload);
+#endif
 
 /* must be called with audio->lock held */
 static int audevrc_enable(struct audio *audio)
@@ -1324,6 +1326,7 @@
 	return 0;
 }
 
+#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audevrc_post_event(struct audio *audio, int type,
 		union msm_audio_event_payload payload)
 {
@@ -1352,7 +1355,6 @@
 	wake_up(&audio->event_wait);
 }
 
-#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audevrc_suspend(struct early_suspend *h)
 {
 	struct audevrc_suspend_ctl *ctl =
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_mp3.c b/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
index 0e61e84..c639833 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_mp3.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, 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
@@ -112,6 +112,7 @@
 	int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e));	\
 	res;							\
 })
+struct audio;
 
 struct buffer {
 	void *data;
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_pcm.c b/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
index 139c16c..b22820b 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_pcm.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, 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
@@ -101,6 +101,8 @@
 	res;							\
 })
 
+struct audio;
+
 struct buffer {
 	void *data;
 	unsigned size;
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c b/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
index f3f0619..ce5d421 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_qcelp.c
@@ -1,7 +1,7 @@
 /*
  * qcelp 13k audio decoder device
  *
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
  *
  * This code is based in part on audio_mp3.c, which is
  * Copyright (C) 2008 Google, Inc.
@@ -184,8 +184,10 @@
 static void audqcelp_config_hostpcm(struct audio *audio);
 static void audqcelp_buffer_refresh(struct audio *audio);
 static void audqcelp_dsp_event(void *private, unsigned id, uint16_t *msg);
+#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audqcelp_post_event(struct audio *audio, int type,
 		union msm_audio_event_payload payload);
+#endif
 
 /* must be called with audio->lock held */
 static int audqcelp_enable(struct audio *audio)
@@ -1326,6 +1328,7 @@
 	return 0;
 }
 
+#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audqcelp_post_event(struct audio *audio, int type,
 		union msm_audio_event_payload payload)
 {
@@ -1354,7 +1357,6 @@
 	wake_up(&audio->event_wait);
 }
 
-#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audqcelp_suspend(struct early_suspend *h)
 {
 	struct audqcelp_suspend_ctl *ctl =
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_wma.c b/arch/arm/mach-msm/qdsp5v2/audio_wma.c
index 464f66e..f29b078 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_wma.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_wma.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
  *
@@ -200,9 +200,10 @@
 static void audplay_config_hostpcm(struct audio *audio);
 static void audplay_buffer_refresh(struct audio *audio);
 static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
+#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audwma_post_event(struct audio *audio, int type,
 		union msm_audio_event_payload payload);
-
+#endif
 /* must be called with audio->lock held */
 static int audio_enable(struct audio *audio)
 {
@@ -1472,6 +1473,7 @@
 	return 0;
 }
 
+#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audwma_post_event(struct audio *audio, int type,
 		union msm_audio_event_payload payload)
 {
@@ -1500,7 +1502,6 @@
 	wake_up(&audio->event_wait);
 }
 
-#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audwma_suspend(struct early_suspend *h)
 {
 	struct audwma_suspend_ctl *ctl =
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c b/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
index 878237e..cf25359 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_wmapro.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/audio_mp3.c
  *
@@ -200,8 +200,10 @@
 static void audplay_config_hostpcm(struct audio *audio);
 static void audplay_buffer_refresh(struct audio *audio);
 static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
+#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audwmapro_post_event(struct audio *audio, int type,
 		union msm_audio_event_payload payload);
+#endif
 
 /* must be called with audio->lock held */
 static int audio_enable(struct audio *audio)
@@ -1484,6 +1486,7 @@
 	return 0;
 }
 
+#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audwmapro_post_event(struct audio *audio, int type,
 		union msm_audio_event_payload payload)
 {
@@ -1512,7 +1515,6 @@
 	wake_up(&audio->event_wait);
 }
 
-#ifdef CONFIG_HAS_EARLYSUSPEND
 static void audwmapro_suspend(struct early_suspend *h)
 {
 	struct audwmapro_suspend_ctl *ctl =
diff --git a/arch/arm/mach-msm/rpm_resources.c b/arch/arm/mach-msm/rpm_resources.c
index 609528c..b4c7f29 100644
--- a/arch/arm/mach-msm/rpm_resources.c
+++ b/arch/arm/mach-msm/rpm_resources.c
@@ -1016,12 +1016,13 @@
 
 	/* Initialize listed bitmap for valid resource IDs */
 	for (i = 0; i < ARRAY_SIZE(msm_rpmrs_resources); i++) {
-		for (k = 0; k < msm_rpmrs_resources[i]->size; k++)
+		for (k = 0; k < msm_rpmrs_resources[i]->size; k++) {
 			if (msm_rpmrs_resources[i]->rs[k].id >=
 					MSM_RPM_ID_LAST)
 				continue;
 			set_bit(msm_rpmrs_resources[i]->rs[k].id,
 				msm_rpmrs_listed);
+		}
 	}
 
 	return 0;
diff --git a/arch/arm/mach-msm/spm_devices.c b/arch/arm/mach-msm/spm_devices.c
index 326faef..0aa1358 100644
--- a/arch/arm/mach-msm/spm_devices.c
+++ b/arch/arm/mach-msm/spm_devices.c
@@ -167,23 +167,26 @@
 	uint32_t val = 0;
 	uint32_t timeout = 0;
 	void *reg = NULL;
+	void *saw_bases[] = {
+		0,
+		MSM_SAW1_BASE,
+		MSM_SAW2_BASE,
+		MSM_SAW3_BASE
+	};
 
-	if (cpu >= num_possible_cpus())
+	if (cpu == 0 || cpu >= num_possible_cpus())
 		return -EINVAL;
 
-	switch (cpu) {
-	case 1:
-		reg = MSM_SAW1_BASE;
-		break;
-	case 0:
-	default:
-		return -EFAULT;
-	}
+	reg = saw_bases[cpu];
 
 	if (cpu_is_msm8960() || cpu_is_msm8930()) {
 		val = 0xB0;
 		reg += 0x14;
 		timeout = 512;
+	} else if (cpu_is_apq8064()) {
+		val = 0xA4;
+		reg += 0x14;
+		timeout = 512;
 	} else {
 		return -ENOSYS;
 	}
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index b44dccc..805e2b6 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -565,6 +565,7 @@
 	kgsl_mmu_stop(device);
 
 	device->ftbl->irqctrl(device, 0);
+	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
 
 	/* Power down the device */
 	kgsl_pwrctrl_disable(device);
diff --git a/drivers/media/video/msm/Kconfig b/drivers/media/video/msm/Kconfig
index b1dc87e..ca44c34 100644
--- a/drivers/media/video/msm/Kconfig
+++ b/drivers/media/video/msm/Kconfig
@@ -226,3 +226,11 @@
 	  by QUP in the board file as QUP is used by
 	  applications other than camera.
 
+config S5K3L1YX
+	bool "Sensor S5K3L1YX (BAYER 12M)"
+	depends on MSM_CAMERA
+	---help---
+		Samsung 12 MP Bayer Sensor with auto focus, uses
+		4 mipi lanes, preview config = 1984 * 1508 at 30 fps,
+		snapshot config = 4000 * 3000 at 20 fps,
+		hfr video at 60, 90 and 120 fps.
diff --git a/drivers/media/video/msm/sensors/Makefile b/drivers/media/video/msm/sensors/Makefile
index a9b7bc6..33db124 100644
--- a/drivers/media/video/msm/sensors/Makefile
+++ b/drivers/media/video/msm/sensors/Makefile
@@ -9,3 +9,4 @@
 obj-$(CONFIG_S5K4E1) += s5k4e1_v4l2.o
 obj-$(CONFIG_MT9E013) += mt9e013_v4l2.o
 obj-$(CONFIG_WEBCAM_OV9726) += ov9726_v4l2.o
+obj-$(CONFIG_S5K3L1YX) += s5k3l1yx.o
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 2c296618..1b57350 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -502,6 +502,7 @@
 		goto enable_clk_failed;
 	}
 
+	usleep_range(1000, 2000);
 	if (data->sensor_platform_info->ext_power_ctrl != NULL)
 		data->sensor_platform_info->ext_power_ctrl(1);
 
diff --git a/drivers/media/video/msm/sensors/s5k3l1yx.c b/drivers/media/video/msm/sensors/s5k3l1yx.c
new file mode 100644
index 0000000..2177991
--- /dev/null
+++ b/drivers/media/video/msm/sensors/s5k3l1yx.c
@@ -0,0 +1,695 @@
+/* Copyright (c) 2012, 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.
+ *
+ */
+
+#include "msm_sensor.h"
+#define SENSOR_NAME "s5k3l1yx"
+#define PLATFORM_DRIVER_NAME "msm_camera_s5k3l1yx"
+
+DEFINE_MUTEX(s5k3l1yx_mut);
+static struct msm_sensor_ctrl_t s5k3l1yx_s_ctrl;
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_start_settings[] = {
+	{0x0100, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_stop_settings[] = {
+	{0x0100, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_groupon_settings[] = {
+	{0x104, 0x01},
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_groupoff_settings[] = {
+	{0x104, 0x00},
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_snap_settings[] = {
+	{0x0501, 0x00}, /* compression_algorithim_L(1d) */
+	{0x0112, 0x0A}, /* CCP_data_format_H */
+	{0x0113, 0x0A}, /* CCP_data_format_L raw8=0808 ,DCPM10 -->8= 0A08 */
+	{0x0306, 0x00}, /* pll_multiplier */
+	{0x0307, 0xA5}, /* pll_multiplier */
+	{0x0202, 0x09}, /* coarse_integration_time */
+	{0x0203, 0x32}, /* coarse_integration_time */
+	{0x0340, 0x0B}, /* frame_length_lines */
+	{0x0341, 0xEC}, /* frame_length_lines */
+	{0x0342, 0x14}, /* line_length_pck */
+	{0x0343, 0xD8}, /* line_length_pck */
+	{0x0344, 0x00}, /* x_addr_start */
+	{0x0345, 0x08}, /* x_addr_start */
+	{0x0346, 0x00}, /* y_addr_start */
+	{0x0347, 0x00}, /* y_addr_start */
+	{0x0348, 0x0F}, /* x_addr_end */
+	{0x0349, 0xA7}, /* x_addr_end */
+	{0x034A, 0x0B}, /* y_addr_end */
+	{0x034B, 0xC7}, /* y_addr_end */
+	{0x034C, 0x0F}, /* x_output_size */
+	{0x034D, 0xA0}, /* x_output_size */
+	{0x034E, 0x0B}, /* y_output_size */
+	{0x034F, 0xC8}, /* y_output_size */
+	{0x0380, 0x00}, /* x_even_inc */
+	{0x0381, 0x01}, /* x_even_inc */
+	{0x0382, 0x00}, /* x_odd_inc */
+	{0x0383, 0x01}, /* x_odd_inc */
+	{0x0384, 0x00}, /* y_even_inc */
+	{0x0385, 0x01}, /* y_even_inc */
+	{0x0386, 0x00}, /* y_odd_inc */
+	{0x0387, 0x01}, /* y_odd_inc */
+	{0x0900, 0x00}, /* binning_mode */
+	{0x0901, 0x22}, /* binning_type */
+	{0x0902, 0x01}, /* binning_weighting */
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_prev_settings[] = {
+	{0x0501, 0x00}, /* compression_algorithim_L(1d) */
+	{0x0112, 0x0A}, /* CCP_data_format_H */
+	{0x0113, 0x0A}, /* CCP_data_format_L raw8=0808 ,DCPM10 -->8= 0A08 */
+	{0x0306, 0x00}, /* pll_multiplier */
+	{0x0307, 0xA5}, /* pll_multiplier */
+	{0x0202, 0x06}, /* coarse_integration_time */
+	{0x0203, 0x00}, /* coarse_integration_time */
+	{0x0340, 0x09}, /* frame_length_lines */
+	{0x0341, 0x98}, /* frame_length_lines */
+	{0x0342, 0x11}, /* line_length_pck */
+	{0x0343, 0x80}, /* line_length_pck */
+	{0x0344, 0x00}, /* x_addr_start */
+	{0x0345, 0x18}, /* x_addr_start */
+	{0x0346, 0x00}, /* y_addr_start */
+	{0x0347, 0x00}, /* y_addr_start */
+	{0x0348, 0x0F}, /* x_addr_end */
+	{0x0349, 0x97}, /* x_addr_end */
+	{0x034A, 0x0B}, /* y_addr_end */
+	{0x034B, 0xC7}, /* y_addr_end */
+	{0x034C, 0x07}, /* x_output_size */
+	{0x034D, 0xC0}, /* x_output_size */
+	{0x034E, 0x05}, /* y_output_size */
+	{0x034F, 0xE4}, /* y_output_size */
+	{0x0380, 0x00}, /* x_even_inc */
+	{0x0381, 0x01}, /* x_even_inc */
+	{0x0382, 0x00}, /* x_odd_inc */
+	{0x0383, 0x03}, /* x_odd_inc */
+	{0x0384, 0x00}, /* y_even_inc */
+	{0x0385, 0x01}, /* y_even_inc */
+	{0x0386, 0x00}, /* y_odd_inc */
+	{0x0387, 0x03}, /* y_odd_inc */
+	{0x0900, 0x01}, /* binning_mode */
+	{0x0901, 0x22}, /* binning_type */
+	{0x0902, 0x01}, /* binning_weighting */
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_video_60fps_settings[] = {
+	{0x0501, 0x00}, /* compression_algorithim_L(1d) */
+	{0x0112, 0x0A}, /* CCP_data_format_H */
+	{0x0113, 0x0A}, /* CCP_data_format_L raw8=0808 ,DCPM10 -->8= 0A08 */
+	{0x0306, 0x00}, /* pll_multiplier */
+	{0x0307, 0xA5}, /* pll_multiplier */
+	{0x0202, 0x02}, /* coarse_integration_time */
+	{0x0203, 0x1C}, /* coarse_integration_time */
+	{0x0340, 0x03}, /* frame_length_lines */
+	{0x0341, 0xE0}, /* frame_length_lines */
+	{0x0342, 0x14}, /* line_length_pck */
+	{0x0343, 0xD8}, /* line_length_pck */
+	{0x0344, 0x01}, /* x_addr_start */
+	{0x0345, 0x20}, /* x_addr_start */
+	{0x0346, 0x02}, /* y_addr_start */
+	{0x0347, 0x23}, /* y_addr_start */
+	{0x0348, 0x0E}, /* x_addr_end */
+	{0x0349, 0xA0}, /* x_addr_end */
+	{0x034A, 0x09}, /* y_addr_end */
+	{0x034B, 0xA4}, /* y_addr_end */
+	{0x034C, 0x03}, /* x_output_size */
+	{0x034D, 0x60}, /* x_output_size */
+	{0x034E, 0x01}, /* y_output_size */
+	{0x034F, 0xE0}, /* y_output_size */
+	{0x0380, 0x00}, /* x_even_inc */
+	{0x0381, 0x01}, /* x_even_inc */
+	{0x0382, 0x00}, /* x_odd_inc */
+	{0x0383, 0x07}, /* x_odd_inc */
+	{0x0384, 0x00}, /* y_even_inc */
+	{0x0385, 0x01}, /* y_even_inc */
+	{0x0386, 0x00}, /* y_odd_inc */
+	{0x0387, 0x07}, /* y_odd_inc */
+	{0x0900, 0x01}, /* binning_mode */
+	{0x0901, 0x44}, /* binning_type */
+	{0x0902, 0x01}, /* binning_weighting */
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_video_90fps_settings[] = {
+	{0x0501, 0x00}, /* compression_algorithim_L(1d) */
+	{0x0112, 0x0A}, /* CCP_data_format_H */
+	{0x0113, 0x0A}, /* CCP_data_format_L raw8=0808 ,DCPM10 -->8= 0A08 */
+	{0x0306, 0x00}, /* pll_multiplier */
+	{0x0307, 0xA5}, /* pll_multiplier */
+	{0x0202, 0x02}, /* coarse_integration_time */
+	{0x0203, 0x1C}, /* coarse_integration_time */
+	{0x0340, 0x02}, /* frame_length_lines */
+	{0x0341, 0x98}, /* frame_length_lines */
+	{0x0342, 0x14}, /* line_length_pck */
+	{0x0343, 0xD8}, /* line_length_pck */
+	{0x0344, 0x01}, /* x_addr_start */
+	{0x0345, 0x20}, /* x_addr_start */
+	{0x0346, 0x02}, /* y_addr_start */
+	{0x0347, 0x23}, /* y_addr_start */
+	{0x0348, 0x0E}, /* x_addr_end */
+	{0x0349, 0xA0}, /* x_addr_end */
+	{0x034A, 0x09}, /* y_addr_end */
+	{0x034B, 0xA4}, /* y_addr_end */
+	{0x034C, 0x03}, /* x_output_size */
+	{0x034D, 0x60}, /* x_output_size */
+	{0x034E, 0x01}, /* y_output_size */
+	{0x034F, 0xE0}, /* y_output_size */
+	{0x0380, 0x00}, /* x_even_inc */
+	{0x0381, 0x01}, /* x_even_inc */
+	{0x0382, 0x00}, /* x_odd_inc */
+	{0x0383, 0x07}, /* x_odd_inc */
+	{0x0384, 0x00}, /* y_even_inc */
+	{0x0385, 0x01}, /* y_even_inc */
+	{0x0386, 0x00}, /* y_odd_inc */
+	{0x0387, 0x07}, /* y_odd_inc */
+	{0x0900, 0x01}, /* binning_mode */
+	{0x0901, 0x44}, /* binning_type */
+	{0x0902, 0x01}, /* binning_weighting */
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_video_120fps_settings[] = {
+	{0x0501, 0x00}, /* compression_algorithim_L(1d) */
+	{0x0112, 0x0A}, /* CCP_data_format_H */
+	{0x0113, 0x0A}, /* CCP_data_format_L raw8=0808 ,DCPM10 -->8= 0A08 */
+	{0x0306, 0x00}, /* pll_multiplier */
+	{0x0307, 0xA5}, /* pll_multiplier */
+	{0x0202, 0x02}, /* coarse_integration_time */
+	{0x0203, 0x1C}, /* coarse_integration_time */
+	{0x0340, 0x02}, /* frame_length_lines */
+	{0x0341, 0x0D}, /* frame_length_lines */
+	{0x0342, 0x14}, /* line_length_pck */
+	{0x0343, 0xD8}, /* line_length_pck */
+	{0x0344, 0x01}, /* x_addr_start */
+	{0x0345, 0x20}, /* x_addr_start */
+	{0x0346, 0x02}, /* y_addr_start */
+	{0x0347, 0x23}, /* y_addr_start */
+	{0x0348, 0x0E}, /* x_addr_end */
+	{0x0349, 0xA0}, /* x_addr_end */
+	{0x034A, 0x09}, /* y_addr_end */
+	{0x034B, 0xA4}, /* y_addr_end */
+	{0x034C, 0x03}, /* x_output_size */
+	{0x034D, 0x60}, /* x_output_size */
+	{0x034E, 0x01}, /* y_output_size */
+	{0x034F, 0xE0}, /* y_output_size */
+	{0x0380, 0x00}, /* x_even_inc */
+	{0x0381, 0x01}, /* x_even_inc */
+	{0x0382, 0x00}, /* x_odd_inc */
+	{0x0383, 0x07}, /* x_odd_inc */
+	{0x0384, 0x00}, /* y_even_inc */
+	{0x0385, 0x01}, /* y_even_inc */
+	{0x0386, 0x00}, /* y_odd_inc */
+	{0x0387, 0x07}, /* y_odd_inc */
+	{0x0900, 0x01}, /* binning_mode */
+	{0x0901, 0x44}, /* binning_type */
+	{0x0902, 0x01}, /* binning_weighting */
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_dpcm_settings[] = {
+	{0x0501, 0x01}, /* compression_algorithim_L(1d) */
+	{0x0112, 0x0A}, /* CCP_data_format_H */
+	{0x0113, 0x08}, /* CCP_data_format_L raw8=0808 ,DCPM10 -->8= 0A08 */
+	{0x0306, 0x00}, /* pll_multiplier */
+	{0x0307, 0xA0}, /* pll_multiplier */
+	{0x0202, 0x09}, /* coarse_integration_time */
+	{0x0203, 0x32}, /* coarse_integration_time */
+	{0x0340, 0x0B}, /* frame_length_lines */
+	{0x0341, 0xEC}, /* frame_length_lines */
+	{0x0342, 0x11}, /* line_length_pck */
+	{0x0343, 0x80}, /* line_length_pck */
+	{0x0344, 0x00}, /* x_addr_start */
+	{0x0345, 0x08}, /* x_addr_start */
+	{0x0346, 0x00}, /* y_addr_start */
+	{0x0347, 0x00}, /* y_addr_start */
+	{0x0348, 0x0F}, /* x_addr_end */
+	{0x0349, 0xA7}, /* x_addr_end */
+	{0x034A, 0x0B}, /* y_addr_end */
+	{0x034B, 0xC7}, /* y_addr_end */
+	{0x034C, 0x0F}, /* x_output_size */
+	{0x034D, 0xA0}, /* x_output_size */
+	{0x034E, 0x0B}, /* y_output_size */
+	{0x034F, 0xC8}, /* y_output_size */
+	{0x0380, 0x00}, /* x_even_inc */
+	{0x0381, 0x01}, /* x_even_inc */
+	{0x0382, 0x00}, /* x_odd_inc */
+	{0x0383, 0x01}, /* x_odd_inc */
+	{0x0384, 0x00}, /* y_even_inc */
+	{0x0385, 0x01}, /* y_even_inc */
+	{0x0386, 0x00}, /* y_odd_inc */
+	{0x0387, 0x01}, /* y_odd_inc */
+	{0x0900, 0x00}, /* binning_mode */
+	{0x0901, 0x22}, /* binning_type */
+	{0x0902, 0x01}, /* binning_weighting */
+};
+
+static struct msm_camera_i2c_reg_conf s5k3l1yx_recommend_settings[] = {
+	{0x0100, 0x00},
+	{0x0103, 0x01}, /* software_reset */
+	{0x0104, 0x00}, /* grouped_parameter_hold */
+	{0x0114, 0x03}, /* CSI_lane_mode, 4 lane setting */
+	{0x0120, 0x00}, /* gain_mode, global analogue gain*/
+	{0x0121, 0x00}, /* exposure_mode, global exposure */
+	{0x0136, 0x18}, /* Extclk_frequency_mhz */
+	{0x0137, 0x00}, /* Extclk_frequency_mhz */
+	{0x0200, 0x08}, /* fine_integration_time */
+	{0x0201, 0x88}, /* fine_integration_time */
+	{0x0204, 0x00}, /* analogue_gain_code_global */
+	{0x0205, 0x20}, /* analogue_gain_code_global */
+	{0x020E, 0x01}, /* digital_gain_greenR */
+	{0x020F, 0x00}, /* digital_gain_greenR */
+	{0x0210, 0x01}, /* digital_gain_red */
+	{0x0211, 0x00}, /* digital_gain_red */
+	{0x0212, 0x01}, /* digital_gain_blue */
+	{0x0213, 0x00}, /* digital_gain_blue */
+	{0x0214, 0x01}, /* digital_gain_greenB */
+	{0x0215, 0x00}, /* digital_gain_greenB */
+	{0x0300, 0x00}, /* vt_pix_clk_div */
+	{0x0301, 0x02}, /* vt_pix_clk_div */
+	{0x0302, 0x00}, /* vt_sys_clk_div */
+	{0x0303, 0x01}, /* vt_sys_clk_div */
+	{0x0304, 0x00}, /* pre_pll_clk_div */
+	{0x0305, 0x06}, /* pre_pll_clk_div */
+	{0x0308, 0x00}, /* op_pix_clk_div */
+	{0x0309, 0x02}, /* op_pix_clk_div */
+	{0x030A, 0x00}, /* op_sys_clk_div */
+	{0x030B, 0x01}, /* op_sys_clk_div */
+	{0x0800, 0x00}, /* tclk_post for D-PHY control */
+	{0x0801, 0x00}, /* ths_prepare for D-PHY control */
+	{0x0802, 0x00}, /* ths_zero_min for D-PHY control */
+	{0x0803, 0x00}, /* ths_trail for D-PHY control */
+	{0x0804, 0x00}, /* tclk_trail_min for D-PHY control */
+	{0x0805, 0x00}, /* tclk_prepare for D-PHY control */
+	{0x0806, 0x00}, /* tclk_zero_zero for D-PHY control */
+	{0x0807, 0x00}, /* tlpx for D-PHY control */
+	{0x0820, 0x02}, /* requested_link_bit_rate_mbps */
+	{0x0821, 0x94}, /* requested_link_bit_rate_mbps */
+	{0x0822, 0x00}, /* requested_link_bit_rate_mbps */
+	{0x0823, 0x00}, /* requested_link_bit_rate_mbps */
+	{0x3000, 0x0A},
+	{0x3001, 0xF7},
+	{0x3002, 0x0A},
+	{0x3003, 0xF7},
+	{0x3004, 0x08},
+	{0x3005, 0xF8},
+	{0x3006, 0x5B},
+	{0x3007, 0x73},
+	{0x3008, 0x49},
+	{0x3009, 0x0C},
+	{0x300A, 0xF8},
+	{0x300B, 0x4E},
+	{0x300C, 0x64},
+	{0x300D, 0x5C},
+	{0x300E, 0x71},
+	{0x300F, 0x0C},
+	{0x3010, 0x6A},
+	{0x3011, 0x14},
+	{0x3012, 0x14},
+	{0x3013, 0x0C},
+	{0x3014, 0x24},
+	{0x3015, 0x4F},
+	{0x3016, 0x86},
+	{0x3017, 0x0E},
+	{0x3018, 0x2C},
+	{0x3019, 0x30},
+	{0x301A, 0x31},
+	{0x301B, 0x32},
+	{0x301C, 0xFF},
+	{0x301D, 0x33},
+	{0x301E, 0x5C},
+	{0x301F, 0xFA},
+	{0x3020, 0x36},
+	{0x3021, 0x46},
+	{0x3022, 0x92},
+	{0x3023, 0xF5},
+	{0x3024, 0x6E},
+	{0x3025, 0x19},
+	{0x3026, 0x32},
+	{0x3027, 0x4B},
+	{0x3028, 0x04},
+	{0x3029, 0x50},
+	{0x302A, 0x0C},
+	{0x302B, 0x04},
+	{0x302C, 0xEF},
+	{0x302D, 0xC1},
+	{0x302E, 0x74},
+	{0x302F, 0x40},
+	{0x3030, 0x00},
+	{0x3031, 0x00},
+	{0x3032, 0x00},
+	{0x3033, 0x00},
+	{0x3034, 0x0F},
+	{0x3035, 0x01},
+	{0x3036, 0x00},
+	{0x3037, 0x00},
+	{0x3038, 0x88},
+	{0x3039, 0x98},
+	{0x303A, 0x1F},
+	{0x303B, 0x01},
+	{0x303C, 0x00},
+	{0x303D, 0x03},
+	{0x303E, 0x2F},
+	{0x303F, 0x09},
+	{0x3040, 0xFF},
+	{0x3041, 0x22},
+	{0x3042, 0x03},
+	{0x3043, 0x03},
+	{0x3044, 0x20},
+	{0x3045, 0x10},
+	{0x3046, 0x10},
+	{0x3047, 0x08},
+	{0x3048, 0x10},
+	{0x3049, 0x01},
+	{0x304A, 0x00},
+	{0x304B, 0x80},
+	{0x304C, 0x80},
+	{0x304D, 0x00},
+	{0x304E, 0x00},
+	{0x304F, 0x00},
+	{0x3051, 0x09},
+	{0x3052, 0xC4},
+	{0x305A, 0xE0},
+	{0x323D, 0x04},
+	{0x323E, 0x38},
+	{0x3305, 0xDD},
+	{0x3050, 0x01},
+	{0x3202, 0x01},
+	{0x3203, 0x01},
+	{0x3204, 0x01},
+	{0x3205, 0x01},
+	{0x3206, 0x01},
+	{0x3207, 0x01},
+	{0x320A, 0x05},
+	{0x320B, 0x20},
+	{0x3235, 0xB7},
+	{0x324C, 0x04},
+	{0x324A, 0x07},
+	{0x3902, 0x01},
+	{0x3915, 0x70},
+	{0x3916, 0x80},
+	{0x3A00, 0x01},
+	{0x3A06, 0x03},
+	{0x3B29, 0x01},
+	{0x3C11, 0x08},
+	{0x3C12, 0x7B},
+	{0x3C13, 0xC0},
+	{0x3C14, 0x70},
+	{0x3C15, 0x80},
+	{0x3C20, 0x00},
+	{0x3C23, 0x03},
+	{0x3C24, 0x00},
+	{0x3C50, 0x72},
+	{0x3C51, 0x85},
+	{0x3C53, 0x40},
+	{0x3C55, 0xA0},
+	{0x3D00, 0x00},
+	{0x3D01, 0x00},
+	{0x3D11, 0x01},
+	{0x3486, 0x05},
+	{0x3B35, 0x06},
+	{0x3A05, 0x01},
+	{0x3A07, 0x2B},
+	{0x3A09, 0x01},
+	{0x3940, 0xFF},
+	{0x3300, 0x00},
+	{0x3900, 0xFF},
+	{0x3914, 0x08},
+	{0x3A01, 0x0F},
+	{0x3A02, 0xA0},
+	{0x3A03, 0x0B},
+	{0x3A04, 0xC8},
+	{0x3701, 0x00},
+	{0x3702, 0x00},
+	{0x3703, 0x00},
+	{0x3704, 0x00},
+	{0x0101, 0x00}, /* image_orientation, mirror & flip off*/
+	{0x0105, 0x01}, /* mask_corrupted_frames */
+	{0x0110, 0x00}, /* CSI-2_channel_identifier */
+	{0x3942, 0x01}, /* [0] 1:mipi, 0:pvi */
+	{0x0B00, 0x00},
+};
+
+static struct v4l2_subdev_info s5k3l1yx_subdev_info[] = {
+	{
+	.code   = V4L2_MBUS_FMT_SBGGR10_1X10,
+	.colorspace = V4L2_COLORSPACE_JPEG,
+	.fmt    = 1,
+	.order    = 0,
+	},
+	/* more can be supported, to be added later */
+};
+
+static struct msm_camera_i2c_conf_array s5k3l1yx_init_conf[] = {
+	{&s5k3l1yx_recommend_settings[0],
+	ARRAY_SIZE(s5k3l1yx_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
+};
+
+static struct msm_camera_i2c_conf_array s5k3l1yx_confs[] = {
+	{&s5k3l1yx_snap_settings[0],
+	ARRAY_SIZE(s5k3l1yx_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&s5k3l1yx_prev_settings[0],
+	ARRAY_SIZE(s5k3l1yx_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&s5k3l1yx_video_60fps_settings[0],
+	ARRAY_SIZE(s5k3l1yx_video_60fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&s5k3l1yx_video_90fps_settings[0],
+	ARRAY_SIZE(s5k3l1yx_video_90fps_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{&s5k3l1yx_video_120fps_settings[0],
+	ARRAY_SIZE(s5k3l1yx_video_120fps_settings), 0,
+					MSM_CAMERA_I2C_BYTE_DATA},
+	{&s5k3l1yx_dpcm_settings[0],
+	ARRAY_SIZE(s5k3l1yx_dpcm_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static struct msm_sensor_output_info_t s5k3l1yx_dimensions[] = {
+	/* 20 fps snapshot */
+	{
+		.x_output = 4000,
+		.y_output = 3016,
+		.line_length_pclk = 5336,
+		.frame_length_lines = 3052,
+		.vt_pixel_clk = 330000000,
+		.op_pixel_clk = 320000000,
+		.binning_factor = 1,
+	},
+	/* 30 fps preview */
+	{
+		.x_output = 1984,
+		.y_output = 1508,
+		.line_length_pclk = 4480,
+		.frame_length_lines = 2456,
+		.vt_pixel_clk = 330000000,
+		.op_pixel_clk = 320000000,
+		.binning_factor = 1,
+	},
+	/* 60 fps video */
+	{
+		.x_output = 864,
+		.y_output = 480,
+		.line_length_pclk = 5336,
+		.frame_length_lines = 992,
+		.vt_pixel_clk = 330000000,
+		.op_pixel_clk = 320000000,
+		.binning_factor = 1,
+	},
+	/* 90 fps video */
+	{
+		.x_output = 864,
+		.y_output = 480,
+		.line_length_pclk = 5336,
+		.frame_length_lines = 664,
+		.vt_pixel_clk = 330000000,
+		.op_pixel_clk = 320000000,
+		.binning_factor = 1,
+	},
+	/* 120 fps video */
+	{
+		.x_output = 864,
+		.y_output = 480,
+		.line_length_pclk = 5336,
+		.frame_length_lines = 525,
+		.vt_pixel_clk = 330000000,
+		.op_pixel_clk = 320000000,
+		.binning_factor = 1,
+	},
+	/* 24 fps snapshot */
+	{
+		.x_output = 4000,
+		.y_output = 3016,
+		.line_length_pclk = 4480,
+		.frame_length_lines = 3052,
+		.vt_pixel_clk = 330000000,
+		.op_pixel_clk = 320000000,
+		.binning_factor = 1,
+	},
+};
+
+static struct msm_camera_csid_vc_cfg s5k3l1yx_cid_cfg[] = {
+	{0, CSI_RAW10, CSI_DECODE_10BIT},
+};
+
+static struct msm_camera_csi2_params s5k3l1yx_csi_params = {
+	.csid_params = {
+		.lane_assign = 0xe4,
+		.lane_cnt = 4,
+		.lut_params = {
+			.num_cid = ARRAY_SIZE(s5k3l1yx_cid_cfg),
+			.vc_cfg = s5k3l1yx_cid_cfg,
+		},
+	},
+	.csiphy_params = {
+		.lane_cnt = 4,
+		.settle_cnt = 0x1B,
+	},
+};
+
+static struct msm_camera_csid_vc_cfg s5k3l1yx_cid_dpcm_cfg[] = {
+	{0, CSI_RAW8, CSI_DECODE_DPCM_10_8_10},
+};
+
+static struct msm_camera_csi2_params s5k3l1yx_csi_dpcm_params = {
+	.csid_params = {
+		.lane_assign = 0xe4,
+		.lane_cnt = 4,
+		.lut_params = {
+			.num_cid = ARRAY_SIZE(s5k3l1yx_cid_dpcm_cfg),
+			.vc_cfg = s5k3l1yx_cid_dpcm_cfg,
+		},
+	},
+	.csiphy_params = {
+		.lane_cnt = 4,
+		.settle_cnt = 0x1B,
+	},
+};
+
+static struct msm_camera_csi2_params *s5k3l1yx_csi_params_array[] = {
+	&s5k3l1yx_csi_params,
+	&s5k3l1yx_csi_params,
+	&s5k3l1yx_csi_params,
+	&s5k3l1yx_csi_params,
+	&s5k3l1yx_csi_params,
+	&s5k3l1yx_csi_dpcm_params,
+};
+
+static struct msm_sensor_output_reg_addr_t s5k3l1yx_reg_addr = {
+	.x_output = 0x34C,
+	.y_output = 0x34E,
+	.line_length_pclk = 0x342,
+	.frame_length_lines = 0x340,
+};
+
+static struct msm_sensor_id_info_t s5k3l1yx_id_info = {
+	.sensor_id_reg_addr = 0x0,
+	.sensor_id = 0x3121,
+};
+
+static struct msm_sensor_exp_gain_info_t s5k3l1yx_exp_gain_info = {
+	.coarse_int_time_addr = 0x202,
+	.global_gain_addr = 0x204,
+	.vert_offset = 8,
+};
+
+static const struct i2c_device_id s5k3l1yx_i2c_id[] = {
+	{SENSOR_NAME, (kernel_ulong_t)&s5k3l1yx_s_ctrl},
+	{ }
+};
+
+static struct i2c_driver s5k3l1yx_i2c_driver = {
+	.id_table = s5k3l1yx_i2c_id,
+	.probe  = msm_sensor_i2c_probe,
+	.driver = {
+		.name = SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client s5k3l1yx_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static int __init msm_sensor_init_module(void)
+{
+	return i2c_add_driver(&s5k3l1yx_i2c_driver);
+}
+
+static struct v4l2_subdev_core_ops s5k3l1yx_subdev_core_ops = {
+	.ioctl = msm_sensor_subdev_ioctl,
+	.s_power = msm_sensor_power,
+};
+
+static struct v4l2_subdev_video_ops s5k3l1yx_subdev_video_ops = {
+	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops s5k3l1yx_subdev_ops = {
+	.core = &s5k3l1yx_subdev_core_ops,
+	.video  = &s5k3l1yx_subdev_video_ops,
+};
+
+static struct msm_sensor_fn_t s5k3l1yx_func_tbl = {
+	.sensor_start_stream = msm_sensor_start_stream,
+	.sensor_stop_stream = msm_sensor_stop_stream,
+	.sensor_group_hold_on = msm_sensor_group_hold_on,
+	.sensor_group_hold_off = msm_sensor_group_hold_off,
+	.sensor_set_fps = msm_sensor_set_fps,
+	.sensor_write_exp_gain = msm_sensor_write_exp_gain1,
+	.sensor_write_snapshot_exp_gain = msm_sensor_write_exp_gain1,
+	.sensor_setting = msm_sensor_setting,
+	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
+	.sensor_mode_init = msm_sensor_mode_init,
+	.sensor_get_output_info = msm_sensor_get_output_info,
+	.sensor_config = msm_sensor_config,
+	.sensor_power_up = msm_sensor_power_up,
+	.sensor_power_down = msm_sensor_power_down,
+};
+
+static struct msm_sensor_reg_t s5k3l1yx_regs = {
+	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+	.start_stream_conf = s5k3l1yx_start_settings,
+	.start_stream_conf_size = ARRAY_SIZE(s5k3l1yx_start_settings),
+	.stop_stream_conf = s5k3l1yx_stop_settings,
+	.stop_stream_conf_size = ARRAY_SIZE(s5k3l1yx_stop_settings),
+	.group_hold_on_conf = s5k3l1yx_groupon_settings,
+	.group_hold_on_conf_size = ARRAY_SIZE(s5k3l1yx_groupon_settings),
+	.group_hold_off_conf = s5k3l1yx_groupoff_settings,
+	.group_hold_off_conf_size =
+		ARRAY_SIZE(s5k3l1yx_groupoff_settings),
+	.init_settings = &s5k3l1yx_init_conf[0],
+	.init_size = ARRAY_SIZE(s5k3l1yx_init_conf),
+	.mode_settings = &s5k3l1yx_confs[0],
+	.output_settings = &s5k3l1yx_dimensions[0],
+	.num_conf = ARRAY_SIZE(s5k3l1yx_confs),
+};
+
+static struct msm_sensor_ctrl_t s5k3l1yx_s_ctrl = {
+	.msm_sensor_reg = &s5k3l1yx_regs,
+	.sensor_i2c_client = &s5k3l1yx_sensor_i2c_client,
+	.sensor_i2c_addr = 0x6E,
+	.sensor_output_reg_addr = &s5k3l1yx_reg_addr,
+	.sensor_id_info = &s5k3l1yx_id_info,
+	.sensor_exp_gain_info = &s5k3l1yx_exp_gain_info,
+	.cam_mode = MSM_SENSOR_MODE_INVALID,
+	.csi_params = &s5k3l1yx_csi_params_array[0],
+	.msm_sensor_mutex = &s5k3l1yx_mut,
+	.sensor_i2c_driver = &s5k3l1yx_i2c_driver,
+	.sensor_v4l2_subdev_info = s5k3l1yx_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(s5k3l1yx_subdev_info),
+	.sensor_v4l2_subdev_ops = &s5k3l1yx_subdev_ops,
+	.func_tbl = &s5k3l1yx_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Samsung 12MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/pm8821-core.c b/drivers/mfd/pm8821-core.c
index 8a556bd..ffcef99 100644
--- a/drivers/mfd/pm8821-core.c
+++ b/drivers/mfd/pm8821-core.c
@@ -29,7 +29,7 @@
 #define REG_IRQ_BASE		0x1BB
 
 #define PM8821_VERSION_MASK	0xFFF0
-#define PM8821_VERSION_VALUE	0x07F0
+#define PM8821_VERSION_VALUE	0x0BF0
 #define PM8821_REVISION_MASK	0x000F
 
 #define SINGLE_IRQ_RESOURCE(_name, _irq) \
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index d06a637..a306357 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -75,4 +75,10 @@
 	help
 	  OpenFirmware PCI bus accessors
 
+config OF_SPMI
+	def_tristate SPMI
+	depends on SPMI
+	help
+	  OpenFirmware SPMI bus accessors
+
 endmenu # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index f7861ed..2087c5e 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -10,3 +10,4 @@
 obj-$(CONFIG_OF_SPI)	+= of_spi.o
 obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
 obj-$(CONFIG_OF_PCI)	+= of_pci.o
+obj-$(CONFIG_OF_SPMI)	+= of_spmi.o
diff --git a/drivers/of/of_spmi.c b/drivers/of/of_spmi.c
new file mode 100644
index 0000000..9f2a396
--- /dev/null
+++ b/drivers/of/of_spmi.c
@@ -0,0 +1,160 @@
+/* Copyright (c) 2012, 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.
+ */
+
+#include <linux/spmi.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_spmi.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+/**
+ * Allocate resources for a child of a spmi-container node.
+ */
+static int of_spmi_allocate_resources(struct spmi_controller *ctrl,
+				      struct spmi_boardinfo *info,
+				      struct device_node *node,
+				      uint32_t num_reg)
+{
+	int i, num_irq = 0;
+	uint64_t size;
+	uint32_t flags;
+	struct resource *res;
+	const  __be32 *addrp;
+	struct of_irq oirq;
+
+	while (of_irq_map_one(node, num_irq, &oirq) == 0)
+		num_irq++;
+
+	if (num_irq || num_reg) {
+		res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL);
+		if (!res)
+			return -ENOMEM;
+
+		info->num_resources = num_reg + num_irq;
+		info->resource = res;
+		for (i = 0; i < num_reg; i++, res++) {
+			/* Addresses are always 16 bits */
+			addrp = of_get_address(node, i, &size, &flags);
+			BUG_ON(!addrp);
+			res->start = be32_to_cpup(addrp);
+			res->end = res->start + size - 1;
+			res->flags = flags;
+		}
+		WARN_ON(of_irq_to_resource_table(node, res, num_irq) !=
+								num_irq);
+	}
+
+	return 0;
+}
+
+static int of_spmi_create_device(struct spmi_controller *ctrl,
+				 struct spmi_boardinfo *info,
+			  struct device_node *node)
+{
+	void *result;
+	int rc;
+
+	rc = of_modalias_node(node, info->name, sizeof(info->name));
+	if (rc < 0) {
+		dev_err(&ctrl->dev, "of_spmi modalias failure on %s\n",
+				node->full_name);
+		return rc;
+	}
+
+	info->of_node = of_node_get(node);
+	result = spmi_new_device(ctrl, info);
+
+	if (result == NULL) {
+		dev_err(&ctrl->dev, "of_spmi: Failure registering %s\n",
+				node->full_name);
+		of_node_put(node);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static void of_spmi_walk_container_children(struct spmi_controller *ctrl,
+				     struct spmi_boardinfo *info,
+				     struct device_node *container)
+{
+	struct device_node *node;
+	uint64_t size;
+	uint32_t flags, num_reg = 0;
+	int rc;
+
+	for_each_child_of_node(container, node) {
+		/*
+		 * We can't use of_address_to_resource here since it includes
+		 * address translation; and address translation assumes that no
+		 * parent buses have a size-cell of 0. But SPMI does have a
+		 * size-cell of 0.
+		 */
+		while (of_get_address(node, num_reg, &size, &flags) != NULL)
+			num_reg++;
+
+		rc = of_spmi_allocate_resources(ctrl, info, node, num_reg);
+		if (rc) {
+			dev_err(&ctrl->dev, "%s: unable to allocate"
+						" resources\n", __func__);
+			return;
+		}
+		rc = of_spmi_create_device(ctrl, info, node);
+		if (rc) {
+			dev_err(&ctrl->dev, "%s: unable to create device for"
+				     " node %s\n", __func__, node->full_name);
+			return;
+		}
+	}
+}
+
+int of_spmi_register_devices(struct spmi_controller *ctrl)
+{
+	struct device_node *node;
+
+	/* Only register child devices if the ctrl has a node pointer set */
+	if (!ctrl->dev.of_node)
+		return -ENODEV;
+
+	for_each_child_of_node(ctrl->dev.of_node, node) {
+		struct spmi_boardinfo info = {};
+		const __be32 *slave_id;
+		int len, rc;
+
+		slave_id = of_get_property(node, "reg", &len);
+		if (!slave_id) {
+			dev_err(&ctrl->dev, "of_spmi: invalid sid "
+					"on %s\n", node->full_name);
+			continue;
+		}
+
+		info.slave_id = be32_to_cpup(slave_id);
+
+		if (of_get_property(node, "spmi-dev-container", NULL)) {
+			of_spmi_walk_container_children(ctrl, &info, node);
+			continue;
+		} else {
+			rc = of_spmi_allocate_resources(ctrl, &info, node, 0);
+			if (rc)
+				continue;
+			of_spmi_create_device(ctrl, &info, node);
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(of_spmi_register_devices);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index aa67c8c..6c5b380 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -354,8 +354,13 @@
 static void msm_slim_put_ctrl(struct msm_slim_ctrl *dev)
 {
 #ifdef CONFIG_PM_RUNTIME
+	int ref;
 	pm_runtime_mark_last_busy(dev->dev);
-	pm_runtime_put(dev->dev);
+	ref = atomic_read(&dev->dev->power.usage_count);
+	if (ref <= 0)
+		dev_err(dev->dev, "reference count mismatch:%d", ref);
+	else
+		pm_runtime_put(dev->dev);
 #endif
 }
 
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index f261931..c7759c4 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -174,6 +174,10 @@
         select FB_MSM_MIPI_DSI
         default n
 
+config FB_MSM_MIPI_DSI_NT35510
+	bool
+	select FB_MSM_MIPI_DSI
+
 config FB_MSM_MIPI_DSI_TC358764_DSI2LVDS
 	bool
 	select FB_MSM_MIPI_DSI
@@ -286,6 +290,16 @@
 	select FB_MSM_MIPI_DSI_RENESAS
 	default n
 
+config FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT
+	bool
+	select FB_MSM_MIPI_DSI_NT35510
+	default n
+
+config FB_MSM_MIPI_NT35510_CMD_WVGA_PT
+	bool
+	select FB_MSM_MIPI_DSI_NT35510
+	default n
+
 config FB_MSM_MIPI_CHIMEI_WXGA
 	bool "LVDS Chimei WXGA Panel using Toshiba MIPI DSI-to-LVDS bridge."
 	select FB_MSM_MIPI_DSI_TC358764_DSI2LVDS
@@ -428,6 +442,8 @@
 	select FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT
 	select FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT
 	select FB_MSM_MIPI_NOVATEK_CMD_QHD_PT
+	select FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT
+	select FB_MSM_MIPI_NT35510_CMD_WVGA_PT
 	select FB_MSM_MIPI_SIMULATOR_VIDEO
 	select FB_MSM_MIPI_CHIMEI_WXGA
 	---help---
@@ -463,6 +479,8 @@
 	select FB_MSM_MIPI_RENESAS_CMD_FWVGA_PT
 	select FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT
 	select FB_MSM_MIPI_NOVATEK_CMD_QHD_PT
+	select FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT
+	select FB_MSM_MIPI_NT35510_CMD_WVGA_PT
 	select FB_MSM_MIPI_SIMULATOR_VIDEO
 	---help---
 	  Support for LCDC + MIPI panel auto detect
@@ -529,6 +547,14 @@
 	bool "MIPI Truly Video WVGA PT Panel"
 	select FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT
 
+config FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT_PANEL
+	bool "MIPI NT35510 Video WVGA PT Panel"
+	select FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT
+
+config FB_MSM_MIPI_NT35510_CMD_WVGA_PT_PANEL
+	bool "MIPI NT35510 Command WVGA PT Panel"
+	select FB_MSM_MIPI_NT35510_CMD_WVGA_PT
+
 config FB_MSM_MIPI_SIMULATOR_VIDEO_PANEL
 	bool "MIPI Simulator Video Panel"
 	select FB_MSM_MIPI_SIMULATOR_VIDEO
diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile
index 2d40b15..93205bc 100644
--- a/drivers/video/msm/Makefile
+++ b/drivers/video/msm/Makefile
@@ -76,6 +76,7 @@
 obj-$(CONFIG_FB_MSM_MIPI_DSI_NOVATEK) += mipi_novatek.o
 obj-$(CONFIG_FB_MSM_MIPI_DSI_RENESAS) += mipi_renesas.o
 obj-$(CONFIG_FB_MSM_MIPI_DSI_TRULY) += mipi_truly.o
+obj-$(CONFIG_FB_MSM_MIPI_DSI_NT35510) += mipi_NT35510.o
 obj-$(CONFIG_FB_MSM_MIPI_DSI_SIMULATOR) += mipi_simulator.o
 
 # MIPI Bridge
@@ -116,6 +117,7 @@
 obj-y += mipi_toshiba_video_wvga_pt.o mipi_toshiba_video_wsvga_pt.o
 obj-y += mipi_novatek_video_qhd_pt.o mipi_novatek_cmd_qhd_pt.o
 obj-y += mipi_renesas_video_fwvga_pt.o mipi_renesas_cmd_fwvga_pt.o
+obj-y += mipi_NT35510_video_wvga_pt.o mipi_NT35510_cmd_wvga_pt.o
 obj-y += mipi_chimei_wxga_pt.o
 obj-y += mipi_truly_video_wvga_pt.o
 else
@@ -125,7 +127,10 @@
 obj-$(CONFIG_FB_MSM_MIPI_NOVATEK_CMD_QHD_PT) += mipi_novatek_cmd_qhd_pt.o
 obj-$(CONFIG_FB_MSM_MIPI_RENESAS_VIDEO_FWVGA_PT) += mipi_renesas_video_fwvga_pt.o
 obj-$(CONFIG_FB_MSM_MIPI_RENESAS_CMD_FWVGA_PT) += mipi_renesas_cmd_fwvga_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_RENESAS_VIDEO_FWVGA_PT) += mipi_renesas_video_fwvga_pt.o
 obj-$(CONFIG_FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT) += mipi_truly_video_wvga_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_NT35510_CMD_WVGA_PT) += mipi_NT35510_cmd_wvga_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT) += mipi_NT35510_video_wvga_pt.o
 obj-$(CONFIG_FB_MSM_MIPI_SIMULATOR_VIDEO) += mipi_simulator_video.o
 obj-$(CONFIG_FB_MSM_MIPI_CHIMEI_WXGA) += mipi_chimei_wxga_pt.o
 endif
diff --git a/drivers/video/msm/mipi_NT35510.c b/drivers/video/msm/mipi_NT35510.c
new file mode 100644
index 0000000..ff513d0
--- /dev/null
+++ b/drivers/video/msm/mipi_NT35510.c
@@ -0,0 +1,586 @@
+/* Copyright (c) 2012, 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.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_NT35510.h"
+
+static struct msm_panel_common_pdata *mipi_nt35510_pdata;
+static struct dsi_buf nt35510_tx_buf;
+static struct dsi_buf nt35510_rx_buf;
+
+#define NT35510_SLEEP_OFF_DELAY 150
+#define NT35510_DISPLAY_ON_DELAY 150
+
+/* common setting */
+static char exit_sleep[2] = {0x11, 0x00};
+static char display_on[2] = {0x29, 0x00};
+static char display_off[2] = {0x28, 0x00};
+static char enter_sleep[2] = {0x10, 0x00};
+static char write_ram[2] = {0x2c, 0x00}; /* write ram */
+
+static struct dsi_cmd_desc nt35510_display_off_cmds[] = {
+	{DTYPE_DCS_WRITE, 1, 0, 0, 150, sizeof(display_off), display_off},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 150, sizeof(enter_sleep), enter_sleep}
+};
+
+static char cmd0[6] = {
+	0xF0, 0x55, 0xAA, 0x52,
+	0x08, 0x01,
+};
+static char cmd1[4] = {
+	0xBC, 0x00, 0xA0, 0x00,
+};
+static char cmd2[4] = {
+	0xBD, 0x00, 0xA0, 0x00,
+};
+static char cmd3[3] = {
+	0xBE, 0x00, 0x79,
+};
+static char cmd4[53] = {
+	0xD1, 0x00, 0x00, 0x00,
+	0x14, 0x00, 0x32, 0x00,
+	0x4F, 0x00, 0x65, 0x00,
+	0x8B, 0x00, 0xA8, 0x00,
+	0xD5, 0x00, 0xF7, 0x01,
+	0x2B, 0x01, 0x54, 0x01,
+	0x8E, 0x01, 0xBB, 0x01,
+	0xBC, 0x01, 0xE3, 0x02,
+	0x08, 0x02, 0x1C, 0x02,
+	0x39, 0x02, 0x4F, 0x02,
+	0x76, 0x02, 0xA3, 0x02,
+	0xE3, 0x03, 0x12, 0x03,
+	0x4C, 0x03, 0x66, 0x03,
+	0x9A,
+};
+static char cmd5[53] = {
+	0xD2, 0x00, 0x00, 0x00,
+	0x14, 0x00, 0x32, 0x00,
+	0x4F, 0x00, 0x65, 0x00,
+	0x8B, 0x00, 0xA8, 0x00,
+	0xD5, 0x00, 0xF7, 0x01,
+	0x2B, 0x01, 0x54, 0x01,
+	0x8E, 0x01, 0xBB, 0x01,
+	0xBC, 0x01, 0xE3, 0x02,
+	0x08, 0x02, 0x1C, 0x02,
+	0x39, 0x02, 0x4F, 0x02,
+	0x76, 0x02, 0xA3, 0x02,
+	0xE3, 0x03, 0x12, 0x03,
+	0x4C, 0x03, 0x66, 0x03,
+	0x9A,
+};
+static char cmd6[53] = {
+	0xD3, 0x00, 0x00, 0x00,
+	0x14, 0x00, 0x32, 0x00,
+	0x4F, 0x00, 0x65, 0x00,
+	0x8B, 0x00, 0xA8, 0x00,
+	0xD5, 0x00, 0xF7, 0x01,
+	0x2B, 0x01, 0x54, 0x01,
+	0x8E, 0x01, 0xBB, 0x01,
+	0xBC, 0x01, 0xE3, 0x02,
+	0x08, 0x02, 0x1C, 0x02,
+	0x39, 0x02, 0x4F, 0x02,
+	0x76, 0x02, 0xA3, 0x02,
+	0xE3, 0x03, 0x12, 0x03,
+	0x4C, 0x03, 0x66, 0x03,
+	0x9A,
+};
+static char cmd7[53] = {
+	0xD4, 0x00, 0x00, 0x00,
+	0x14, 0x00, 0x32, 0x00,
+	0x4F, 0x00, 0x65, 0x00,
+	0x8B, 0x00, 0xA8, 0x00,
+	0xD5, 0x00, 0xF7, 0x01,
+	0x2B, 0x01, 0x54, 0x01,
+	0x8E, 0x01, 0xBB, 0x01,
+	0xBC, 0x01, 0xE3, 0x02,
+	0x08, 0x02, 0x1C, 0x02,
+	0x39, 0x02, 0x4F, 0x02,
+	0x76, 0x02, 0xA3, 0x02,
+	0xE3, 0x03, 0x12, 0x03,
+	0x4C, 0x03, 0x66, 0x03,
+	0x9A,
+};
+static char cmd8[53] = {
+	0xD5, 0x00, 0x00, 0x00,
+	0x14, 0x00, 0x32, 0x00,
+	0x4F, 0x00, 0x65, 0x00,
+	0x8B, 0x00, 0xA8, 0x00,
+	0xD5, 0x00, 0xF7, 0x01,
+	0x2B, 0x01, 0x54, 0x01,
+	0x8E, 0x01, 0xBB, 0x01,
+	0xBC, 0x01, 0xE3, 0x02,
+	0x08, 0x02, 0x1C, 0x02,
+	0x39, 0x02, 0x4F, 0x02,
+	0x76, 0x02, 0xA3, 0x02,
+	0xE3, 0x03, 0x12, 0x03,
+	0x4C, 0x03, 0x66, 0x03,
+	0x9A,
+};
+static char cmd9[53] = {
+	0xD6, 0x00, 0x00, 0x00,
+	0x14, 0x00, 0x32, 0x00,
+	0x4F, 0x00, 0x65, 0x00,
+	0x8B, 0x00, 0xA8, 0x00,
+	0xD5, 0x00, 0xF7, 0x01,
+	0x2B, 0x01, 0x54, 0x01,
+	0x8E, 0x01, 0xBB, 0x01,
+	0xBC, 0x01, 0xE3, 0x02,
+	0x08, 0x02, 0x1C, 0x02,
+	0x39, 0x02, 0x4F, 0x02,
+	0x76, 0x02, 0xA3, 0x02,
+	0xE3, 0x03, 0x12, 0x03,
+	0x4C, 0x03, 0x66, 0x03,
+	0x9A,
+};
+static char cmd10[4] = {
+	0xB0, 0x0A, 0x0A, 0x0A,
+};
+static char cmd11[4] = {
+	0xB1, 0x0A, 0x0A, 0x0A,
+};
+static char cmd12[4] = {
+	0xBA, 0x24, 0x24, 0x24,
+};
+static char cmd13[4] = {
+	0xB9, 0x24, 0x24, 0x24,
+};
+static char cmd14[4] = {
+	0xB8, 0x24, 0x24, 0x24,
+};
+static char cmd15[6] = {
+	0xF0, 0x55, 0xAA, 0x52,
+	0x08, 0x00,
+};
+static char cmd16[2] = {
+	0xB3, 0x00,
+};
+static char cmd17[2] = {
+	0xB4, 0x10,
+};
+static char cmd18[2] = {
+	0xB6, 0x02,
+};
+static char cmd19[3] = {
+	0xB1, 0xEC, 0x06,
+};
+static char cmd20[4] = {
+	0xBC, 0x05, 0x05, 0x05,
+};
+static char cmd21[3] = {
+	0xB7, 0x20, 0x20,
+};
+static char cmd22[5] = {
+	0xB8, 0x01, 0x03, 0x03,
+	0x03,
+};
+static char cmd23[19] = {
+	0xC8, 0x01, 0x00, 0x78,
+	0x50, 0x78, 0x50, 0x78,
+	0x50, 0x78, 0x50, 0xC8,
+	0x3C, 0x3C, 0xC8, 0xC8,
+	0x3C, 0x3C, 0xC8,
+};
+static char cmd24[6] = {
+	0xBD, 0x01, 0x84, 0x07,
+	0x31, 0x00,
+};
+static char cmd25[6] = {
+	0xBE, 0x01, 0x84, 0x07,
+	0x31, 0x00,
+};
+static char cmd26[6] = {
+	0xBF, 0x01, 0x84, 0x07,
+	0x31, 0x00,
+};
+static char cmd27[2] = {
+	0x35, 0x00,
+};
+static char config_MADCTL[2] = {0x36, 0xC0};
+static struct dsi_cmd_desc nt35510_cmd_display_on_cmds[] = {
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd0), cmd0},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd1), cmd1},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd2), cmd2},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd3), cmd3},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd4), cmd4},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd5), cmd5},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd6), cmd6},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd7), cmd7},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd8), cmd8},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd9), cmd9},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd10), cmd10},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd11), cmd11},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd12), cmd12},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd13), cmd13},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd14), cmd14},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd15), cmd15},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd16), cmd16},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd17), cmd17},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd18), cmd18},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd19), cmd19},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd20), cmd20},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd21), cmd21},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd22), cmd22},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd23), cmd23},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd24), cmd24},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd25), cmd25},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd26), cmd26},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd27), cmd27},
+
+	{DTYPE_DCS_WRITE, 1, 0, 0, 150,	sizeof(exit_sleep), exit_sleep},
+	{DTYPE_DCS_WRITE, 1, 0, 0, 10,	sizeof(display_on), display_on},
+
+	{DTYPE_DCS_WRITE1, 1, 0, 0, 150,
+		sizeof(config_MADCTL), config_MADCTL},
+
+	{DTYPE_DCS_WRITE, 1, 0, 0, 10,	sizeof(write_ram), write_ram},
+};
+
+static char video0[6] = {
+	0xF0, 0x55, 0xAA, 0x52,
+	0x08, 0x01,
+};
+static char video1[4] = {
+	0xBC, 0x00, 0xA0, 0x00,
+};
+static char video2[4] = {
+	0xBD, 0x00, 0xA0, 0x00,
+};
+static char video3[3] = {
+	0xBE, 0x00, 0x79,
+};
+static char video4[53] = {
+	0xD1, 0x00, 0x00, 0x00,
+	0x14, 0x00, 0x32, 0x00,
+	0x4F, 0x00, 0x65, 0x00,
+	0x8B, 0x00, 0xA8, 0x00,
+	0xD5, 0x00, 0xF7, 0x01,
+	0x2B, 0x01, 0x54, 0x01,
+	0x8E, 0x01, 0xBB, 0x01,
+	0xBC, 0x01, 0xE3, 0x02,
+	0x08, 0x02, 0x1C, 0x02,
+	0x39, 0x02, 0x4F, 0x02,
+	0x76, 0x02, 0xA3, 0x02,
+	0xE3, 0x03, 0x12, 0x03,
+	0x4C, 0x03, 0x66, 0x03,
+	0x9A,
+};
+static char video5[53] = {
+	0xD2, 0x00, 0x00, 0x00,
+	0x14, 0x00, 0x32, 0x00,
+	0x4F, 0x00, 0x65, 0x00,
+	0x8B, 0x00, 0xA8, 0x00,
+	0xD5, 0x00, 0xF7, 0x01,
+	0x2B, 0x01, 0x54, 0x01,
+	0x8E, 0x01, 0xBB, 0x01,
+	0xBC, 0x01, 0xE3, 0x02,
+	0x08, 0x02, 0x1C, 0x02,
+	0x39, 0x02, 0x4F, 0x02,
+	0x76, 0x02, 0xA3, 0x02,
+	0xE3, 0x03, 0x12, 0x03,
+	0x4C, 0x03, 0x66, 0x03,
+	0x9A,
+};
+static char video6[53] = {
+	0xD3, 0x00, 0x00, 0x00,
+	0x14, 0x00, 0x32, 0x00,
+	0x4F, 0x00, 0x65, 0x00,
+	0x8B, 0x00, 0xA8, 0x00,
+	0xD5, 0x00, 0xF7, 0x01,
+	0x2B, 0x01, 0x54, 0x01,
+	0x8E, 0x01, 0xBB, 0x01,
+	0xBC, 0x01, 0xE3, 0x02,
+	0x08, 0x02, 0x1C, 0x02,
+	0x39, 0x02, 0x4F, 0x02,
+	0x76, 0x02, 0xA3, 0x02,
+	0xE3, 0x03, 0x12, 0x03,
+	0x4C, 0x03, 0x66, 0x03,
+	0x9A,
+};
+static char video7[53] = {
+	0xD4, 0x00, 0x00, 0x00,
+	0x14, 0x00, 0x32, 0x00,
+	0x4F, 0x00, 0x65, 0x00,
+	0x8B, 0x00, 0xA8, 0x00,
+	0xD5, 0x00, 0xF7, 0x01,
+	0x2B, 0x01, 0x54, 0x01,
+	0x8E, 0x01, 0xBB, 0x01,
+	0xBC, 0x01, 0xE3, 0x02,
+	0x08, 0x02, 0x1C, 0x02,
+	0x39, 0x02, 0x4F, 0x02,
+	0x76, 0x02, 0xA3, 0x02,
+	0xE3, 0x03, 0x12, 0x03,
+	0x4C, 0x03, 0x66, 0x03,
+	0x9A,
+};
+static char video8[53] = {
+	0xD5, 0x00, 0x00, 0x00,
+	0x14, 0x00, 0x32, 0x00,
+	0x4F, 0x00, 0x65, 0x00,
+	0x8B, 0x00, 0xA8, 0x00,
+	0xD5, 0x00, 0xF7, 0x01,
+	0x2B, 0x01, 0x54, 0x01,
+	0x8E, 0x01, 0xBB, 0x01,
+	0xBC, 0x01, 0xE3, 0x02,
+	0x08, 0x02, 0x1C, 0x02,
+	0x39, 0x02, 0x4F, 0x02,
+	0x76, 0x02, 0xA3, 0x02,
+	0xE3, 0x03, 0x12, 0x03,
+	0x4C, 0x03, 0x66, 0x03,
+	0x9A,
+};
+static char video9[53] = {
+	0xD6, 0x00, 0x00, 0x00,
+	0x14, 0x00, 0x32, 0x00,
+	0x4F, 0x00, 0x65, 0x00,
+	0x8B, 0x00, 0xA8, 0x00,
+	0xD5, 0x00, 0xF7, 0x01,
+	0x2B, 0x01, 0x54, 0x01,
+	0x8E, 0x01, 0xBB, 0x01,
+	0xBC, 0x01, 0xE3, 0x02,
+	0x08, 0x02, 0x1C, 0x02,
+	0x39, 0x02, 0x4F, 0x02,
+	0x76, 0x02, 0xA3, 0x02,
+	0xE3, 0x03, 0x12, 0x03,
+	0x4C, 0x03, 0x66, 0x03,
+	0x9A,
+};
+static char video10[4] = {
+	0xB0, 0x0A, 0x0A, 0x0A,
+};
+static char video11[4] = {
+	0xB1, 0x0A, 0x0A, 0x0A,
+};
+static char video12[4] = {
+	0xBA, 0x24, 0x24, 0x24,
+};
+static char video13[4] = {
+	0xB9, 0x24, 0x24, 0x24,
+};
+static char video14[4] = {
+	0xB8, 0x24, 0x24, 0x24,
+};
+static char video15[6] = {
+	0xF0, 0x55, 0xAA, 0x52,
+	0x08, 0x00,
+};
+static char video16[2] = {
+	0xB3, 0x00,
+};
+static char video17[2] = {
+	0xB4, 0x10,
+};
+static char video18[2] = {
+	0xB6, 0x02,
+};
+static char video19[3] = {
+	0xB1, 0xFC, 0x06,
+};
+static char video20[4] = {
+	0xBC, 0x05, 0x05, 0x05,
+};
+static char video21[3] = {
+	0xB7, 0x20, 0x20,
+};
+static char video22[5] = {
+	0xB8, 0x01, 0x03, 0x03,
+	0x03,
+};
+static char video23[19] = {
+	0xC8, 0x01, 0x00, 0x78,
+	0x50, 0x78, 0x50, 0x78,
+	0x50, 0x78, 0x50, 0xC8,
+	0x3C, 0x3C, 0xC8, 0xC8,
+	0x3C, 0x3C, 0xC8,
+};
+static char video24[6] = {
+	0xBD, 0x01, 0x84, 0x07,
+	0x31, 0x00,
+};
+static char video25[6] = {
+	0xBE, 0x01, 0x84, 0x07,
+	0x31, 0x00,
+};
+static char video26[6] = {
+	0xBF, 0x01, 0x84, 0x07,
+	0x31, 0x00,
+};
+static char video27[2] = {
+	0x35, 0x00,
+};
+static struct dsi_cmd_desc nt35510_video_display_on_cmds[] = {
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video0), video0},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video1), video1},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video2), video2},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video3), video3},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video4), video4},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video5), video5},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video6), video6},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video7), video7},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video8), video8},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video9), video9},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video10), video10},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video11), video11},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video12), video12},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video13), video13},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video14), video14},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video15), video15},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video16), video16},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video17), video17},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video18), video18},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video19), video19},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video20), video20},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video21), video21},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video22), video22},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video23), video23},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video24), video24},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video25), video25},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video26), video26},
+	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(video27), video27},
+	{DTYPE_DCS_WRITE, 1, 0, 0, NT35510_SLEEP_OFF_DELAY, sizeof(exit_sleep),
+			exit_sleep},
+	{DTYPE_DCS_WRITE, 1, 0, 0, NT35510_DISPLAY_ON_DELAY, sizeof(display_on),
+			display_on},
+};
+
+static int mipi_nt35510_lcd_on(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+	struct mipi_panel_info *mipi;
+
+	mfd = platform_get_drvdata(pdev);
+	if (!mfd)
+		return -ENODEV;
+
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	mipi  = &mfd->panel_info.mipi;
+
+	if (mipi->mode == DSI_VIDEO_MODE) {
+		mipi_dsi_cmds_tx(mfd, &nt35510_tx_buf,
+			nt35510_video_display_on_cmds,
+			ARRAY_SIZE(nt35510_video_display_on_cmds));
+	} else if (mipi->mode == DSI_CMD_MODE) {
+		mipi_dsi_cmds_tx(mfd, &nt35510_tx_buf,
+			nt35510_cmd_display_on_cmds,
+			ARRAY_SIZE(nt35510_cmd_display_on_cmds));
+	}
+
+	return 0;
+}
+
+static int mipi_nt35510_lcd_off(struct platform_device *pdev)
+{
+	struct msm_fb_data_type *mfd;
+
+	pr_debug("mipi_nt35510_lcd_off E\n");
+
+	mfd = platform_get_drvdata(pdev);
+
+	if (!mfd)
+		return -ENODEV;
+	if (mfd->key != MFD_KEY)
+		return -EINVAL;
+
+	mipi_dsi_cmds_tx(mfd, &nt35510_tx_buf, nt35510_display_off_cmds,
+			ARRAY_SIZE(nt35510_display_off_cmds));
+
+	pr_debug("mipi_nt35510_lcd_off X\n");
+	return 0;
+}
+
+static int __devinit mipi_nt35510_lcd_probe(struct platform_device *pdev)
+{
+	pr_debug("%s\n", __func__);
+
+	if (pdev->id == 0) {
+		mipi_nt35510_pdata = pdev->dev.platform_data;
+		return 0;
+	}
+
+	msm_fb_add_device(pdev);
+
+	return 0;
+}
+
+static struct platform_driver this_driver = {
+	.probe  = mipi_nt35510_lcd_probe,
+	.driver = {
+		.name   = "mipi_NT35510",
+	},
+};
+
+static void mipi_nt35510_set_backlight(struct msm_fb_data_type *mfd)
+{
+	/* Add backlight changes later*/
+	return;
+}
+
+static struct msm_fb_panel_data nt35510_panel_data = {
+	.on	= mipi_nt35510_lcd_on,
+	.off = mipi_nt35510_lcd_off,
+	.set_backlight = mipi_nt35510_set_backlight,
+};
+
+static int ch_used[3];
+
+static int mipi_nt35510_lcd_init(void)
+{
+	mipi_dsi_buf_alloc(&nt35510_tx_buf, DSI_BUF_SIZE);
+	mipi_dsi_buf_alloc(&nt35510_rx_buf, DSI_BUF_SIZE);
+
+	return platform_driver_register(&this_driver);
+}
+int mipi_nt35510_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel)
+{
+	struct platform_device *pdev = NULL;
+	int ret;
+
+	if ((channel >= 3) || ch_used[channel])
+		return -ENODEV;
+
+	ch_used[channel] = TRUE;
+
+	ret = mipi_nt35510_lcd_init();
+	if (ret) {
+		pr_err("mipi_nt35510_lcd_init() failed with ret %u\n", ret);
+		return ret;
+	}
+
+	pdev = platform_device_alloc("mipi_NT35510", (panel << 8)|channel);
+	if (!pdev)
+		return -ENOMEM;
+
+	nt35510_panel_data.panel_info = *pinfo;
+
+	ret = platform_device_add_data(pdev, &nt35510_panel_data,
+				sizeof(nt35510_panel_data));
+	if (ret) {
+		pr_debug("%s: platform_device_add_data failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	ret = platform_device_add(pdev);
+	if (ret) {
+		pr_debug("%s: platform_device_register failed!\n", __func__);
+		goto err_device_put;
+	}
+
+	return 0;
+
+err_device_put:
+	platform_device_put(pdev);
+	return ret;
+}
diff --git a/drivers/video/msm/mipi_NT35510.h b/drivers/video/msm/mipi_NT35510.h
new file mode 100644
index 0000000..5c81875
--- /dev/null
+++ b/drivers/video/msm/mipi_NT35510.h
@@ -0,0 +1,20 @@
+/* Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef MIPI_NT35510_H
+#define MIPI_NT35510_H
+
+int mipi_nt35510_device_register(struct msm_panel_info *pinfo,
+					u32 channel, u32 panel);
+
+#endif  /* MIPI_NT35510_H */
diff --git a/drivers/video/msm/mipi_NT35510_cmd_wvga_pt.c b/drivers/video/msm/mipi_NT35510_cmd_wvga_pt.c
new file mode 100644
index 0000000..2c4ee3e
--- /dev/null
+++ b/drivers/video/msm/mipi_NT35510_cmd_wvga_pt.c
@@ -0,0 +1,98 @@
+/* Copyright (c) 2012, 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.
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_NT35510.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_cmd_mode_phy_db = {
+	/* DSI Bit Clock at 500 MHz, 2 lane, RGB888 */
+	/* regulator */
+	{0x03, 0x01, 0x01, 0x00},
+	/* timing   */
+	{0xb9, 0x8e, 0x1f, 0x00, 0x98, 0x9c, 0x22, 0x90,
+	0x18, 0x03, 0x04},
+	/* phy ctrl */
+	{0x7f, 0x00, 0x00, 0x00},
+	/* strength */
+	{0xbb, 0x02, 0x06, 0x00},
+	/* pll control */
+	{0x01, 0xec, 0x31, 0xd2, 0x00, 0x40, 0x37, 0x62,
+	0x01, 0x0f, 0x07,
+	0x05, 0x14, 0x03, 0x0, 0x0, 0x0, 0x20, 0x0, 0x02, 0x0},
+};
+
+static int mipi_cmd_nt35510_wvga_pt_init(void)
+{
+	int ret;
+
+	if (msm_fb_detect_client("mipi_cmd_nt35510_wvga"))
+		return 0;
+
+	pinfo.xres = 480;
+	pinfo.yres = 800;
+	pinfo.type = MIPI_CMD_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+	pinfo.lcdc.h_back_porch = 100;
+	pinfo.lcdc.h_front_porch = 100;
+	pinfo.lcdc.h_pulse_width = 8;
+	pinfo.lcdc.v_back_porch = 20;
+	pinfo.lcdc.v_front_porch = 20;
+	pinfo.lcdc.v_pulse_width = 1;
+
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	pinfo.lcdc.hsync_skew = 0;
+	pinfo.bl_max = 100;
+	pinfo.bl_min = 1;
+	pinfo.fb_num = 2;
+
+	pinfo.clk_rate = 499000000;
+
+	pinfo.lcd.vsync_enable = TRUE;
+	pinfo.lcd.hw_vsync_mode = TRUE;
+	pinfo.lcd.refx100 = 6000; /* adjust refx100 to prevent tearing */
+
+	pinfo.mipi.mode = DSI_CMD_MODE;
+	pinfo.mipi.dst_format = DSI_CMD_DST_FORMAT_RGB888;
+	pinfo.mipi.vc = 0;
+	pinfo.mipi.rgb_swap = DSI_RGB_SWAP_RGB;
+	pinfo.mipi.data_lane0 = TRUE;
+	pinfo.mipi.data_lane1 = TRUE;
+	pinfo.mipi.t_clk_post = 0x20;
+	pinfo.mipi.t_clk_pre = 0x2F;
+	pinfo.mipi.stream = 0; /* dma_p */
+	pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.te_sel = 1; /* TE from vsync gpio */
+	pinfo.mipi.interleave_max = 1;
+	pinfo.mipi.insert_dcs_cmd = TRUE;
+	pinfo.mipi.wr_mem_continue = 0x3c;
+	pinfo.mipi.wr_mem_start = 0x2c;
+	pinfo.mipi.dsi_phy_db = &dsi_cmd_mode_phy_db;
+	pinfo.mipi.tx_eot_append = 0x01;
+	pinfo.mipi.rx_eot_ignore = 0x0;
+	pinfo.mipi.dlane_swap = 0x01;
+
+	ret = mipi_nt35510_device_register(&pinfo, MIPI_DSI_PRIM,
+						MIPI_DSI_PANEL_WVGA_PT);
+	if (ret)
+		pr_err("%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mipi_cmd_nt35510_wvga_pt_init);
diff --git a/drivers/video/msm/mipi_NT35510_video_wvga_pt.c b/drivers/video/msm/mipi_NT35510_video_wvga_pt.c
new file mode 100644
index 0000000..82e03b2
--- /dev/null
+++ b/drivers/video/msm/mipi_NT35510_video_wvga_pt.c
@@ -0,0 +1,108 @@
+/* Copyright (c) 2012, 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.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_NT35510.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_video_mode_phy_db = {
+	/* DSI Bit Clock at 500 MHz, 2 lane, RGB888 */
+	/* regulator */
+	{0x03, 0x01, 0x01, 0x00},
+	/* timing   */
+	{0xb9, 0x8e, 0x1f, 0x00, 0x98, 0x9c, 0x22, 0x90,
+	0x18, 0x03, 0x04},
+	/* phy ctrl */
+	{0x7f, 0x00, 0x00, 0x00},
+	/* strength */
+	{0xbb, 0x02, 0x06, 0x00},
+	/* pll control */
+	{0x00, 0xec, 0x31, 0xd2, 0x00, 0x40, 0x37, 0x62,
+	0x01, 0x0f, 0x07,
+	0x05, 0x14, 0x03, 0x0, 0x0, 0x0, 0x20, 0x0, 0x02, 0x0},
+};
+
+static int mipi_video_nt35510_wvga_pt_init(void)
+{
+	int ret;
+
+	if (msm_fb_detect_client("mipi_video_nt35510_wvga"))
+		return 0;
+
+	pinfo.xres = 480;
+	pinfo.yres = 800;
+	pinfo.type = MIPI_VIDEO_PANEL;
+	pinfo.pdest = DISPLAY_1;
+	pinfo.wait_cycle = 0;
+	pinfo.bpp = 24;
+	pinfo.lcdc.h_back_porch = 100;
+	pinfo.lcdc.h_front_porch = 100;
+	pinfo.lcdc.h_pulse_width = 8;
+	pinfo.lcdc.v_back_porch = 20;
+	pinfo.lcdc.v_front_porch = 20;
+	pinfo.lcdc.v_pulse_width = 1;
+	pinfo.lcdc.border_clr = 0;	/* blk */
+	pinfo.lcdc.underflow_clr = 0xff;	/* blue */
+	/* number of dot_clk cycles HSYNC active edge is
+	delayed from VSYNC active edge */
+	pinfo.lcdc.hsync_skew = 0;
+	pinfo.clk_rate = 499000000;
+	pinfo.bl_max = 100; /*16; CHECK THIS!!!*/
+	pinfo.bl_min = 1;
+	pinfo.fb_num = 2;
+
+	pinfo.mipi.mode = DSI_VIDEO_MODE;
+	/* send HSA and HE following VS/VE packet */
+	pinfo.mipi.pulse_mode_hsa_he = TRUE;
+	pinfo.mipi.hfp_power_stop = TRUE; /* LP-11 during the HFP period */
+	pinfo.mipi.hbp_power_stop = TRUE; /* LP-11 during the HBP period */
+	pinfo.mipi.hsa_power_stop = TRUE; /* LP-11 during the HSA period */
+	/* LP-11 or let Command Mode Engine send packets in
+	HS or LP mode for the BLLP of the last line of a frame */
+	pinfo.mipi.eof_bllp_power_stop = TRUE;
+	/* LP-11 or let Command Mode Engine send packets in
+	HS or LP mode for packets sent during BLLP period */
+	pinfo.mipi.bllp_power_stop = TRUE;
+
+	pinfo.mipi.traffic_mode = DSI_BURST_MODE;
+	pinfo.mipi.dst_format =  DSI_VIDEO_DST_FORMAT_RGB888;
+	pinfo.mipi.vc = 0;
+	pinfo.mipi.rgb_swap = DSI_RGB_SWAP_RGB; /* RGB */
+	pinfo.mipi.data_lane0 = TRUE;
+	pinfo.mipi.data_lane1 = TRUE;
+
+	pinfo.mipi.t_clk_post = 0x20;
+	pinfo.mipi.t_clk_pre = 0x2f;
+
+	pinfo.mipi.stream = 0; /* dma_p */
+	pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_NONE;
+	pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+	pinfo.mipi.frame_rate = 60; /* FIXME */
+
+	pinfo.mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+	pinfo.mipi.dlane_swap = 0x01;
+	/* append EOT at the end of data burst */
+	pinfo.mipi.tx_eot_append = 0x01;
+
+	ret = mipi_nt35510_device_register(&pinfo, MIPI_DSI_PRIM,
+						MIPI_DSI_PANEL_WVGA_PT);
+
+	if (ret)
+		pr_err("%s: failed to register device!\n", __func__);
+
+	return ret;
+}
+
+module_init(mipi_video_nt35510_wvga_pt_init);
diff --git a/drivers/video/msm/mipi_novatek.c b/drivers/video/msm/mipi_novatek.c
index caa4114..ed0dee4 100644
--- a/drivers/video/msm/mipi_novatek.c
+++ b/drivers/video/msm/mipi_novatek.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, 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
@@ -461,6 +461,7 @@
 	struct mipi_panel_info *mipi;
 	struct platform_device *current_pdev;
 	static struct mipi_dsi_phy_ctrl *phy_settings;
+	static char dlane_swap;
 
 	if (pdev->id == 0) {
 		mipi_novatek_pdata = pdev->dev.platform_data;
@@ -471,6 +472,11 @@
 		}
 
 		if (mipi_novatek_pdata
+			&& mipi_novatek_pdata->dlane_swap) {
+			dlane_swap = (mipi_novatek_pdata->dlane_swap);
+		}
+
+		if (mipi_novatek_pdata
 			 && mipi_novatek_pdata->fpga_3d_config_addr)
 			mipi_novatek_3d_init(mipi_novatek_pdata
 	->fpga_3d_config_addr, mipi_novatek_pdata->fpga_ctrl_mode);
@@ -499,6 +505,9 @@
 
 		if (phy_settings != NULL)
 			mipi->dsi_phy_db = phy_settings;
+
+		if (dlane_swap)
+			mipi->dlane_swap = dlane_swap;
 	}
 	return 0;
 }
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
index d54c01e..75df48d 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
@@ -10,10 +10,12 @@
  * GNU General Public License for more details.
  *
  */
+#include <linux/ion.h>
 #include <mach/msm_memtypes.h>
 #include "vcd_ddl.h"
 #include "vcd_ddl_shared_mem.h"
 
+
 struct ddl_context *ddl_get_context(void)
 {
 	static struct ddl_context ddl_context;
@@ -253,6 +255,15 @@
 				memset(frame[i].vcd_frm.virtual + luma_size,
 					 0x80808080,
 					frame[i].vcd_frm.alloc_len - luma_size);
+				if (frame[i].vcd_frm.ion_flag == CACHED) {
+					clean_and_invalidate_caches(
+					(unsigned long)frame[i].
+					vcd_frm.virtual,
+					(unsigned long)frame[i].
+					vcd_frm.alloc_len,
+					(unsigned long)frame[i].
+					vcd_frm.physical);
+				}
 			} else {
 				DDL_MSG_ERROR("luma size error");
 				return VCD_ERR_FAIL;
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index 8a2f534..b300fbc 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -235,6 +235,7 @@
 	struct file *file;
 	s32 buffer_index = -1;
 	enum vdec_picture pic_type;
+	u32 ion_flag = 0;
 
 	if (!client_ctx || !vcd_frame_data) {
 		ERR("vid_dec_input_frame_done() NULL pointer\n");
@@ -268,7 +269,6 @@
 				      &phy_addr, &pmem_fd, &file,
 				      &buffer_index) ||
 		(vcd_frame_data->flags & VCD_FRAME_FLAG_EOS)) {
-
 		/* Buffer address in user space */
 		vdec_msg->vdec_msg_info.msgdata.output_frame.bufferaddr =
 		    (u8 *) user_vaddr;
@@ -334,7 +334,15 @@
 		ERR("vid_dec_output_frame_done UVA can not be found\n");
 		vdec_msg->vdec_msg_info.status_code = VDEC_S_EFATAL;
 	}
-
+	if (vcd_frame_data->data_len > 0) {
+		ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT,
+				pmem_fd, kernel_vaddr, buffer_index);
+		if (ion_flag == CACHED) {
+			invalidate_caches(kernel_vaddr,
+					(unsigned long)vcd_frame_data->data_len,
+					phy_addr);
+		}
+	}
 	mutex_lock(&client_ctx->msg_queue_lock);
 	list_add_tail(&vdec_msg->list, &client_ctx->msg_queue);
 	mutex_unlock(&client_ctx->msg_queue_lock);
@@ -1034,7 +1042,6 @@
 		    __func__, buffer_info->buffer.bufferaddr);
 		return false;
 	}
-
 	vcd_status = vcd_set_buffer(client_ctx->vcd_handle,
 		buffer, (u8 *) kernel_vaddr,
 		buffer_info->buffer.buffer_len);
@@ -1180,6 +1187,7 @@
 	struct file *file;
 	s32 buffer_index = -1;
 	u32 vcd_status = VCD_ERR_FAIL;
+	u32 ion_flag = 0;
 
 	if (!client_ctx || !input_frame_info)
 		return false;
@@ -1207,7 +1215,18 @@
 		vcd_input_buffer.flags = input_frame_info->flags;
 		vcd_input_buffer.desc_buf = desc_buf;
 		vcd_input_buffer.desc_size = desc_size;
-
+		if (vcd_input_buffer.data_len > 0) {
+			ion_flag = vidc_get_fd_info(client_ctx,
+						BUFFER_TYPE_INPUT,
+						pmem_fd,
+						kernel_vaddr,
+						buffer_index);
+			if (ion_flag == CACHED) {
+				clean_caches(kernel_vaddr,
+				(unsigned long)vcd_input_buffer.data_len,
+				phy_addr);
+			}
+		}
 		vcd_status = vcd_decode_frame(client_ctx->vcd_handle,
 					      &vcd_input_buffer);
 		if (!vcd_status)
@@ -1250,7 +1269,10 @@
 		vcd_frame.virtual = (u8 *) kernel_vaddr;
 		vcd_frame.frm_clnt_data = (u32) fill_buffer_cmd->client_data;
 		vcd_frame.alloc_len = fill_buffer_cmd->buffer.buffer_len;
-
+		vcd_frame.ion_flag = vidc_get_fd_info(client_ctx,
+						 BUFFER_TYPE_OUTPUT,
+						pmem_fd, kernel_vaddr,
+						buffer_index);
 		vcd_status = vcd_fill_output_buffer(client_ctx->vcd_handle,
 						    &vcd_frame);
 		if (!vcd_status)
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index 97fc758..cc6606c 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -197,6 +197,7 @@
 	int pmem_fd;
 	struct file *file;
 	s32 buffer_index = -1;
+	u32 ion_flag = 0;
 
 	if (!client_ctx || !vcd_frame_data) {
 		ERR("vid_enc_input_frame_done() NULL pointer\n");
@@ -259,7 +260,15 @@
 		venc_msg->venc_msg_info.statuscode =
 			VEN_S_EFATAL;
 	}
-
+	if (venc_msg->venc_msg_info.buf.len > 0) {
+		ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT,
+					pmem_fd, kernel_vaddr, buffer_index);
+		if (ion_flag == CACHED) {
+			clean_and_invalidate_caches(kernel_vaddr,
+				(unsigned long)venc_msg->venc_msg_info.buf.len,
+				phy_addr);
+		}
+	}
 	mutex_lock(&client_ctx->msg_queue_lock);
 	list_add_tail(&venc_msg->list, &client_ctx->msg_queue);
 	mutex_unlock(&client_ctx->msg_queue_lock);
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.c b/drivers/video/msm/vidc/common/enc/venc_internal.c
index 47b0f66..e3bb9db 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.c
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.c
@@ -1609,6 +1609,7 @@
 	int pmem_fd;
 	struct file *file;
 	s32 buffer_index = -1;
+	u32 ion_flag = 0;
 
 	u32 vcd_status = VCD_ERR_FAIL;
 
@@ -1640,6 +1641,18 @@
 		/* Rely on VCD using the same flags as OMX */
 		vcd_input_buffer.flags = input_frame_info->flags;
 
+		ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_INPUT,
+				pmem_fd, kernel_vaddr, buffer_index);
+
+		if (vcd_input_buffer.data_len > 0) {
+			if (ion_flag == CACHED) {
+				clean_caches(
+				(unsigned long) vcd_input_buffer.virtual,
+				(unsigned long) vcd_input_buffer.data_len,
+				(phy_addr + input_frame_info->offset));
+			}
+		}
+
 		vcd_status = vcd_encode_frame(client_ctx->vcd_handle,
 		&vcd_input_buffer);
 		if (!vcd_status)
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index d24d43c..cd3f954 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -364,6 +364,26 @@
 }
 EXPORT_SYMBOL(vidc_release_firmware);
 
+u32 vidc_get_fd_info(struct video_client_ctx *client_ctx,
+		enum buffer_dir buffer, int pmem_fd,
+		unsigned long kvaddr, int index)
+{
+	struct buf_addr_table *buf_addr_table;
+	u32 rc = 0;
+	if (!client_ctx)
+		return false;
+	if (buffer == BUFFER_TYPE_INPUT)
+		buf_addr_table = client_ctx->input_buf_addr_table;
+	else
+		buf_addr_table = client_ctx->output_buf_addr_table;
+	if (buf_addr_table[index].pmem_fd == pmem_fd) {
+		if (buf_addr_table[index].kernel_vaddr == kvaddr)
+			rc = buf_addr_table[index].buff_ion_flag;
+	}
+	return rc;
+}
+EXPORT_SYMBOL(vidc_get_fd_info);
+
 u32 vidc_lookup_addr_table(struct video_client_ctx *client_ctx,
 	enum buffer_dir buffer,
 	u32 search_with_user_vaddr,
@@ -459,7 +479,7 @@
 	struct msm_mapped_buffer *mapped_buffer = NULL;
 	size_t ion_len;
 	struct ion_handle *buff_ion_handle = NULL;
-	unsigned long ionflag;
+	unsigned long ionflag = 0;
 
 	if (!client_ctx || !length)
 		return false;
@@ -556,10 +576,13 @@
 		buf_addr_table[*num_of_buffers].phy_addr = phys_addr;
 		buf_addr_table[*num_of_buffers].buff_ion_handle =
 						buff_ion_handle;
+		buf_addr_table[*num_of_buffers].buff_ion_flag =
+						ionflag;
 		*num_of_buffers = *num_of_buffers + 1;
 		DBG("%s() : client_ctx = %p, user_virt_addr = 0x%08lx, "
-			"kernel_vaddr = 0x%08lx inserted!", __func__,
-			client_ctx, user_vaddr, *kernel_vaddr);
+			"kernel_vaddr = 0x%08lx phys_addr=%lu inserted!",
+			__func__, client_ctx, user_vaddr, *kernel_vaddr,
+			phys_addr);
 	}
 	mutex_unlock(&client_ctx->enrty_queue_lock);
 	return true;
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.h b/drivers/video/msm/vidc/common/init/vidc_init.h
index 717d0c8..ced99ff 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.h
+++ b/drivers/video/msm/vidc/common/init/vidc_init.h
@@ -28,6 +28,7 @@
 	unsigned long user_vaddr;
 	unsigned long kernel_vaddr;
 	unsigned long phy_addr;
+	unsigned long buff_ion_flag;
 	struct ion_handle *buff_ion_handle;
 	int pmem_fd;
 	struct file *file;
@@ -63,6 +64,9 @@
 void __iomem *vidc_get_ioaddr(void);
 int vidc_load_firmware(void);
 void vidc_release_firmware(void);
+u32 vidc_get_fd_info(struct video_client_ctx *client_ctx,
+		enum buffer_dir buffer, int pmem_fd,
+		unsigned long kvaddr, int index);
 u32 vidc_lookup_addr_table(struct video_client_ctx *client_ctx,
 	enum buffer_dir buffer, u32 search_with_user_vaddr,
 	unsigned long *user_vaddr, unsigned long *kernel_vaddr,
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_api.h b/drivers/video/msm/vidc/common/vcd/vcd_api.h
index badab1e..9580ece 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_api.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_api.h
@@ -56,6 +56,7 @@
 struct vcd_frame_data {
 	u8 *virtual;
 	u8 *physical;
+	u32 ion_flag;
 	u32 alloc_len;
 	u32 data_len;
 	u32 offset;
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index b5fcc1c..509b897 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -188,6 +188,36 @@
 
 }
 
+u32 vcd_get_ion_flag(struct video_client_ctx *client_ctx,
+			  unsigned long kernel_vaddr)
+{
+	unsigned long phy_addr, user_vaddr;
+	int pmem_fd;
+	struct file *file;
+	s32 buffer_index = -1;
+	u32 ion_flag = 0;
+
+	if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_INPUT,
+					  false, &user_vaddr, &kernel_vaddr,
+					  &phy_addr, &pmem_fd, &file,
+					  &buffer_index)) {
+
+		ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_INPUT,
+				pmem_fd, kernel_vaddr, buffer_index);
+		return ion_flag;
+	} else if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT,
+		false, &user_vaddr, &kernel_vaddr, &phy_addr, &pmem_fd, &file,
+		&buffer_index)) {
+		ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT,
+				pmem_fd, kernel_vaddr, buffer_index);
+		return ion_flag;
+	} else {
+		VCD_MSG_ERROR("Couldn't get ion flag");
+		return 0;
+	}
+
+}
+
 void vcd_reset_device_channels(struct vcd_dev_ctxt *dev_ctxt)
 {
 	dev_ctxt->ddl_frame_ch_free = dev_ctxt->ddl_frame_ch_depth;
@@ -523,6 +553,7 @@
 {
 	struct vcd_buffer_entry *buf_entry;
 	u8 *physical;
+	u32 ion_flag = 0;
 
 	buf_entry = vcd_find_buffer_pool_entry(buf_pool, buffer);
 	if (buf_entry) {
@@ -534,6 +565,9 @@
 	physical = (u8 *) vcd_pmem_get_physical(
 		cctxt->client_data, (unsigned long)buffer);
 
+	ion_flag = vcd_get_ion_flag(cctxt->client_data,
+				(unsigned long)buffer);
+
 	if (!physical) {
 		VCD_MSG_ERROR("Couldn't get physical address");
 		return VCD_ERR_BAD_POINTER;
@@ -548,7 +582,6 @@
 		VCD_MSG_ERROR("Can't allocate buffer pool is full");
 		return VCD_ERR_FAIL;
 	}
-
 	buf_entry->virtual = buffer;
 	buf_entry->physical = physical;
 	buf_entry->sz = buf_size;
@@ -557,6 +590,7 @@
 
 	buf_entry->frame.virtual = buf_entry->virtual;
 	buf_entry->frame.physical = buf_entry->physical;
+	buf_entry->frame.ion_flag = ion_flag;
 
 	buf_pool->validated++;
 
diff --git a/include/linux/of_spmi.h b/include/linux/of_spmi.h
new file mode 100644
index 0000000..d07ce63
--- /dev/null
+++ b/include/linux/of_spmi.h
@@ -0,0 +1,23 @@
+/* Copyright (c) 2012, 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.
+ */
+
+#include <linux/spmi.h>
+#include <linux/of_irq.h>
+
+#ifdef CONFIG_OF_SPMI
+int of_spmi_register_devices(struct spmi_controller *ctrl);
+#else
+static int of_spmi_register_devices(struct spmi_controller *ctrl)
+{
+	return -ENXIO;
+}
+#endif /* CONFIG_OF_SPMI */
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index fea11d9..42e7935 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -249,6 +249,28 @@
 		.ops = &msm_fe_dai_ops,
 		.name = "HDMI_HOSTLESS"
 	},
+	{
+		.playback = {
+			.stream_name = "AUXPCM Hostless Playback",
+			.rates = SNDRV_PCM_RATE_8000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 1,
+			.rate_min =     8000,
+			.rate_max =     8000,
+		},
+		.capture = {
+			.stream_name = "AUXPCM Hostless Capture",
+			.rates = SNDRV_PCM_RATE_8000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 1,
+			.rate_min =     8000,
+			.rate_max =    48000,
+		},
+		.ops = &msm_fe_dai_ops,
+		.name = "AUXPCM_HOSTLESS",
+	},
 };
 
 static __devinit int msm_fe_dai_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index 27a27ec..c7d7004 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -23,7 +23,6 @@
 #include <sound/soc.h>
 #include <sound/apr_audio.h>
 #include <sound/q6afe.h>
-#include <sound/q6adm.h>
 #include <sound/msm-dai-q6.h>
 #include <mach/clk.h>
 
@@ -466,10 +465,6 @@
 	struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
 	int rc = 0;
 
-	rc = adm_close(dai->id);
-	if (IS_ERR_VALUE(rc))
-		dev_err(dai->dev, "fail to close ADM COPP\n");
-
 	pr_debug("%s: dai->id = %d", __func__, dai->id);
 
 	if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 94ed504..2b4999f 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -937,6 +937,18 @@
 	SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
 	MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer,
 	msm_routing_put_port_mixer),
+	SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SLIMBUS_0_RX,
+	MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer,
+	msm_routing_put_port_mixer),
+};
+
+static const struct snd_kcontrol_new auxpcm_rx_port_mixer_controls[] = {
+	SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_RX,
+	MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer,
+	msm_routing_put_port_mixer),
+	SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_AUXPCM_RX,
+	MSM_BACKEND_DAI_SLIMBUS_0_TX, 1, 0, msm_routing_get_port_mixer,
+	msm_routing_put_port_mixer),
 };
 
 static const struct snd_kcontrol_new fm_switch_mixer_controls =
@@ -1154,6 +1166,10 @@
 	SND_SOC_DAPM_AIF_OUT("INTFM_UL_HL", "INT_FM_HOSTLESS Capture",
 		0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("HDMI_DL_HL", "HDMI_HOSTLESS Playback", 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_IN("AUXPCM_DL_HL", "AUXPCM_HOSTLESS Playback",
+		0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("AUXPCM_UL_HL", "AUXPCM_HOSTLESS Capture",
+		0, 0, 0, 0),
 
 	/* Backend AIF */
 	/* Stream name equals to backend dai link stream name
@@ -1254,6 +1270,9 @@
 	SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Port Mixer",
 	SND_SOC_NOPM, 0, 0, sbus_0_rx_port_mixer_controls,
 	ARRAY_SIZE(sbus_0_rx_port_mixer_controls)),
+	SND_SOC_DAPM_MIXER("AUXPCM_RX Port Mixer",
+	SND_SOC_NOPM, 0, 0, auxpcm_rx_port_mixer_controls,
+	ARRAY_SIZE(auxpcm_rx_port_mixer_controls)),
 };
 
 static const struct snd_soc_dapm_route intercon[] = {
@@ -1377,9 +1396,16 @@
 	{"SLIM0_UL_HL", NULL, "SLIMBUS_0_TX"},
 	{"INT_FM_RX", NULL, "INTFM_DL_HL"},
 	{"INTFM_UL_HL", NULL, "INT_FM_TX"},
+	{"AUX_PCM_RX", NULL, "AUXPCM_DL_HL"},
+	{"AUXPCM_UL_HL", NULL, "AUX_PCM_TX"},
 	{"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
 	{"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+	{"SLIMBUS_0_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
 	{"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Port Mixer"},
+
+	{"AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+	{"AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+	{"AUX_PCM_RX", NULL, "AUXPCM_RX Port Mixer"},
 };
 
 static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream,
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index 75bb75f..578f819 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -716,16 +716,8 @@
 	},
 };
 
-static struct snd_soc_dsp_link slimbus0_hl_media = {
-	.playback = true,
-	.capture = true,
-	.trigger = {
-		SND_SOC_DSP_TRIGGER_POST,
-		SND_SOC_DSP_TRIGGER_POST
-	},
-};
-
-static struct snd_soc_dsp_link int_fm_hl_media = {
+/* bi-directional media definition for hostless PCM device */
+static struct snd_soc_dsp_link bidir_hl_media = {
 	.playback = true,
 	.capture = true,
 	.trigger = {
@@ -985,7 +977,7 @@
 		.cpu_dai_name	= "SLIMBUS0_HOSTLESS",
 		.platform_name  = "msm-pcm-hostless",
 		.dynamic = 1,
-		.dsp_link = &slimbus0_hl_media,
+		.dsp_link = &bidir_hl_media,
 		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
 		.ignore_suspend = 1,
 		/* .be_id = do not care */
@@ -996,7 +988,7 @@
 		.cpu_dai_name	= "INT_FM_HOSTLESS",
 		.platform_name  = "msm-pcm-hostless",
 		.dynamic = 1,
-		.dsp_link = &int_fm_hl_media,
+		.dsp_link = &bidir_hl_media,
 		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
 		.ignore_suspend = 1,
 		/* .be_id = do not care */
@@ -1028,6 +1020,16 @@
 		.dsp_link = &lpa_fe_media,
 		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA4,
 	},
+	{
+		.name = "AUXPCM Hostless",
+		.stream_name = "AUXPCM Hostless",
+		.cpu_dai_name	= "AUXPCM_HOSTLESS",
+		.platform_name  = "msm-pcm-hostless",
+		.dynamic = 1,
+		.dsp_link = &bidir_hl_media,
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+	},
 	/* HDMI Hostless */
 	{
 		.name = "HDMI_RX_HOSTLESS",