Merge "hwmon: pm8xxx-adc: Limit BTM interval period" into msm-3.0
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2097e0a..0a7fe5f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -222,6 +222,10 @@
 	  to allow physical memory down to a theoretical minimum of 64K
 	  boundaries.
 
+config GENERIC_BUG
+	def_bool y
+	depends on BUG
+
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index 255d06e..bf01b40 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -62,6 +62,7 @@
 CONFIG_MSM_RMT_STORAGE_CLIENT=y
 CONFIG_MSM_SDIO_SMEM=y
 # CONFIG_MSM_HW3D is not set
+CONFIG_MSM_PIL_QDSP6V3=y
 CONFIG_MSM_SUBSYSTEM_RESTART=y
 CONFIG_MSM_RPM_LOG=y
 CONFIG_MSM_RPM_STATS_LOG=y
@@ -433,6 +434,7 @@
 CONFIG_TIMER_STATS=y
 # CONFIG_DEBUG_PREEMPT is not set
 CONFIG_DEBUG_INFO=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
 CONFIG_CRYPTO_SHA256=y
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index 0a88039..0472ad7 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -54,6 +54,7 @@
 # CONFIG_MSM_RPCSERVER_HANDSET is not set
 CONFIG_MSM_RMT_STORAGE_CLIENT=y
 # CONFIG_MSM_HW3D is not set
+CONFIG_MSM_PIL_QDSP6V3=y
 CONFIG_MSM_SUBSYSTEM_RESTART=y
 CONFIG_MSM_RPM_LOG=y
 CONFIG_MSM_RPM_STATS_LOG=y
@@ -428,6 +429,7 @@
 CONFIG_DEBUG_LIST=y
 CONFIG_DEBUG_SG=y
 CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index bb94d2a..748b8ca 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -296,6 +296,7 @@
 CONFIG_MSM_CAMERA_SENSOR=y
 CONFIG_MSM_ACTUATOR=y
 CONFIG_MSM_GEMINI=y
+CONFIG_MT9M114=y
 CONFIG_RADIO_IRIS=y
 CONFIG_RADIO_IRIS_TRANSPORT=m
 CONFIG_ION=y
diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h
index 4d88425..9abe7a0 100644
--- a/arch/arm/include/asm/bug.h
+++ b/arch/arm/include/asm/bug.h
@@ -3,21 +3,58 @@
 
 
 #ifdef CONFIG_BUG
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-extern void __bug(const char *file, int line) __attribute__((noreturn));
 
-/* give file/line information */
-#define BUG()		__bug(__FILE__, __LINE__)
-
+/*
+ * Use a suitable undefined instruction to use for ARM/Thumb2 bug handling.
+ * We need to be careful not to conflict with those used by other modules and
+ * the register_undef_hook() system.
+ */
+#ifdef CONFIG_THUMB2_KERNEL
+#define BUG_INSTR_VALUE 0xde02
+#define BUG_INSTR_TYPE ".hword "
 #else
-
-/* this just causes an oops */
-#define BUG()		do { *(int *)0 = 0; } while (1)
-
+#define BUG_INSTR_VALUE 0xe7f001f2
+#define BUG_INSTR_TYPE ".word "
 #endif
 
+
+#define BUG() _BUG(__FILE__, __LINE__, BUG_INSTR_VALUE)
+#define _BUG(file, line, value) __BUG(file, line, value)
+
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+
+/*
+ * The extra indirection is to ensure that the __FILE__ string comes through
+ * OK. Many version of gcc do not support the asm %c parameter which would be
+ * preferable to this unpleasantness. We use mergeable string sections to
+ * avoid multiple copies of the string appearing in the kernel image.
+ */
+
+#define __BUG(__file, __line, __value)				\
+do {								\
+	BUILD_BUG_ON(sizeof(struct bug_entry) != 12);		\
+	asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n"	\
+		".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \
+		"2:\t.asciz " #__file "\n" 			\
+		".popsection\n" 				\
+		".pushsection __bug_table,\"a\"\n"		\
+		"3:\t.word 1b, 2b\n"				\
+		"\t.hword " #__line ", 0\n"			\
+		".popsection");					\
+	unreachable();						\
+} while (0)
+
+#else  /* not CONFIG_DEBUG_BUGVERBOSE */
+
+#define __BUG(__file, __line, __value)				\
+do {								\
+	asm volatile(BUG_INSTR_TYPE #__value);			\
+	unreachable();						\
+} while (0)
+#endif  /* CONFIG_DEBUG_BUGVERBOSE */
+
 #define HAVE_ARCH_BUG
-#endif
+#endif  /* CONFIG_BUG */
 
 #include <asm-generic/bug.h>
 
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 2f8bf62..b0c57a9 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -398,6 +398,15 @@
 	mcr	p15, 0, r0, c1, c0, 0		@ write control reg
 	mrc	p15, 0, r3, c0, c0, 0		@ read id reg
 	mov	r3, r3
+#ifdef CONFIG_ARCH_MSM_KRAIT
+	ldr	r3, =0xff00fc00
+	and	r3, r9, r3
+	ldr 	r4, =0x51000400
+	cmp	r3, r4
+	mrceq	p15, 7, r3, c15, c0, 2
+	biceq	r3, r3, #0x400
+	mcreq	p15, 7, r3, c15, c0, 2
+#endif
 	mov	r3, r13
 	mov	pc, r3
 __enable_mmu_end:
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index c063c56..ef37557 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -21,6 +21,7 @@
 #include <linux/kdebug.h>
 #include <linux/module.h>
 #include <linux/kexec.h>
+#include <linux/bug.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/sched.h>
@@ -270,6 +271,8 @@
 	raw_spin_lock_irq(&die_lock);
 	console_verbose();
 	bust_spinlocks(1);
+	if (!user_mode(regs))
+		report_bug(regs->ARM_pc, regs);
 	ret = __die(str, err, thread, regs);
 
 	if (regs && kexec_should_crash(thread->task))
@@ -301,6 +304,24 @@
 	}
 }
 
+#ifdef CONFIG_GENERIC_BUG
+
+int is_valid_bugaddr(unsigned long pc)
+{
+#ifdef CONFIG_THUMB2_KERNEL
+	unsigned short bkpt;
+#else
+	unsigned long bkpt;
+#endif
+
+	if (probe_kernel_address((unsigned *)pc, bkpt))
+		return 0;
+
+	return bkpt == BUG_INSTR_VALUE;
+}
+
+#endif
+
 static LIST_HEAD(undef_hook);
 static DEFINE_RAW_SPINLOCK(undef_lock);
 
@@ -697,16 +718,6 @@
 	arm_notify_die("unknown data abort code", regs, &info, instr, 0);
 }
 
-void __attribute__((noreturn)) __bug(const char *file, int line)
-{
-	printk(KERN_CRIT"kernel BUG at %s:%d!\n", file, line);
-	*(int *)0 = 0;
-
-	/* Avoid "noreturn function does return" */
-	for (;;);
-}
-EXPORT_SYMBOL(__bug);
-
 void __readwrite_bug(const char *fn)
 {
 	printk("%s called, but not implemented\n", fn);
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 8652d45..6530fa3 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -24,7 +24,8 @@
 #define ARM_CPU_KEEP(x)
 #endif
 
-#if defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)
+#if (defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)) || \
+	defined(CONFIG_GENERIC_BUG)
 #define ARM_EXIT_KEEP(x)	x
 #else
 #define ARM_EXIT_KEEP(x)
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 204aa5d..7aeb560 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1580,6 +1580,13 @@
 
 	  Say yes to support these devices.
 
+config MSM_PIL_QDSP6V3
+	tristate "QDSP6v3 (Hexagon) Boot Support"
+	depends on MSM_PIL
+	help
+	  Support for booting and shutting down QDSP6v3 processors (hexagon).
+	  The QDSP6 is a low power DSP used in audio software applications.
+
 config MSM_PIL_QDSP6V4
 	tristate "QDSP6v4 (Hexagon) Boot Support"
 	depends on MSM_PIL
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 05f4ab4..5fda40c 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -71,6 +71,7 @@
 obj-$(CONFIG_ARCH_MSM8X60) += peripheral-reset.o
 obj-$(CONFIG_ARCH_MSM8960) += peripheral-reset-8960.o
 endif
+obj-$(CONFIG_MSM_PIL_QDSP6V3) += pil-q6v3.o
 obj-$(CONFIG_MSM_PIL_QDSP6V4) += pil-q6v4.o
 obj-$(CONFIG_ARCH_QSD8X50) += sirc.o
 obj-$(CONFIG_ARCH_FSM9XXX) += sirc-fsm9xxx.o
@@ -231,7 +232,7 @@
 obj-$(CONFIG_ARCH_APQ8064) += devices-8960.o devices-8064.o
 board-8960-all-objs += board-8960.o board-8960-camera.o board-8960-display.o board-8960-pmic.o board-8960-storage.o board-8960-gpiomux.o
 board-8930-all-objs += board-8930.o board-8930-camera.o board-8930-display.o board-8930-pmic.o board-8930-storage.o board-8930-gpiomux.o
-board-8064-all-objs += board-8064.o board-8064-storage.o
+board-8064-all-objs += board-8064.o board-8064-pmic.o board-8064-storage.o board-8064-gpiomux.o
 obj-$(CONFIG_MACH_MSM8960_SIM) += board-8960-all.o board-8960-regulator.o
 obj-$(CONFIG_MACH_MSM8960_RUMI3) += board-8960-all.o board-8960-regulator.o
 obj-$(CONFIG_MACH_MSM8960_CDP) += board-8960-all.o board-8960-regulator.o
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index 86a80a9..82d8173 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -147,7 +147,7 @@
 			.vreg[VREG_DIG]  = { "krait0_dig", 1150000,
 					     RPM_VREG_VOTER1,
 					     RPM_VREG_ID_PM8921_S3 },
-			.vreg[VREG_HFPLL_A] = { "hfpll", 2200000,
+			.vreg[VREG_HFPLL_A] = { "hfpll", 2100000,
 					     RPM_VREG_VOTER1,
 					     RPM_VREG_ID_PM8921_S8 },
 			.vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
@@ -165,7 +165,7 @@
 			.vreg[VREG_DIG]  = { "krait0_dig", 1150000,
 					     RPM_VREG_VOTER2,
 					     RPM_VREG_ID_PM8921_S3 },
-			.vreg[VREG_HFPLL_A] = { "hfpll", 2200000,
+			.vreg[VREG_HFPLL_A] = { "hfpll", 2100000,
 					     RPM_VREG_VOTER2,
 					     RPM_VREG_ID_PM8921_S8 },
 			.vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
@@ -176,7 +176,7 @@
 			.hfpll_base   = MSM_HFPLL_BASE    + 0x400,
 			.aux_clk_sel  = MSM_APCS_GCC_BASE + 0x028,
 			.l2cpmr_iaddr = L2CPMR_IADDR,
-			.vreg[VREG_HFPLL_A] = { "hfpll", 2200000,
+			.vreg[VREG_HFPLL_A] = { "hfpll", 2100000,
 					     RPM_VREG_VOTER6,
 					     RPM_VREG_ID_PM8921_S8 },
 			.vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
@@ -529,14 +529,14 @@
 
 	if (cpu_is_msm8960()) {
 		rc = rpm_vreg_set_voltage(sc->vreg[VREG_HFPLL_A].rpm_vreg_id,
-				sc->vreg[VREG_HFPLL_A].rpm_vreg_voter, 2200000,
-				2200000, 0);
+				sc->vreg[VREG_HFPLL_A].rpm_vreg_voter, 2100000,
+				sc->vreg[VREG_HFPLL_A].max_vdd, 0);
 		if (rc)
 			pr_err("%s regulator enable failed (%d)\n",
 				sc->vreg[VREG_HFPLL_A].name, rc);
 		rc = rpm_vreg_set_voltage(sc->vreg[VREG_HFPLL_B].rpm_vreg_id,
 				sc->vreg[VREG_HFPLL_B].rpm_vreg_voter, 1800000,
-				1800000, 0);
+				sc->vreg[VREG_HFPLL_B].max_vdd, 0);
 		if (rc)
 			pr_err("%s regulator enable failed (%d)\n",
 				sc->vreg[VREG_HFPLL_B].name, rc);
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
new file mode 100644
index 0000000..50673b4
--- /dev/null
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -0,0 +1,154 @@
+/* Copyright (c) 2011, 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/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.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 "devices.h"
+#include "board-8064.h"
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+static struct gpiomux_setting gpio_eth_config = {
+	.pull = GPIOMUX_PULL_NONE,
+	.drv = GPIOMUX_DRV_8MA,
+	.func = GPIOMUX_FUNC_GPIO,
+};
+
+/* The SPI configurations apply to GSBI 5*/
+static struct gpiomux_setting gpio_spi_config = {
+	.func = GPIOMUX_FUNC_2,
+	.drv = GPIOMUX_DRV_8MA,
+	.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,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+struct msm_gpiomux_config apq8064_ethernet_configs[] = {
+	{
+		.gpio = 43,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_eth_config,
+			[GPIOMUX_ACTIVE] = &gpio_eth_config,
+		}
+	},
+};
+#endif
+
+static struct gpiomux_setting audio_auxpcm[] = {
+	/* Suspended state */
+	{
+		.func = GPIOMUX_FUNC_GPIO,
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_NONE,
+	},
+	/* Active state */
+	{
+		.func = GPIOMUX_FUNC_1,
+		.drv = GPIOMUX_DRV_2MA,
+		.pull = GPIOMUX_PULL_NONE,
+	},
+};
+
+static struct msm_gpiomux_config apq8064_gsbi_configs[] __initdata = {
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+	{
+		.gpio      = 51,		/* GSBI5 QUP SPI_DATA_MOSI */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
+		.gpio      = 52,		/* GSBI5 QUP SPI_DATA_MISO */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+	{
+		.gpio      = 31,		/* GSBI5 QUP SPI_CS2_N */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_cs2_config,
+		},
+	},
+	{
+		.gpio      = 54,		/* GSBI5 QUP SPI_CLK */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
+		},
+	},
+#endif
+};
+
+static struct msm_gpiomux_config apq8064_audio_auxpcm_configs[] __initdata = {
+	{
+		.gpio = 43,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+		},
+	},
+	{
+		.gpio = 44,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+		},
+	},
+	{
+		.gpio = 45,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+		},
+	},
+	{
+		.gpio = 46,
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
+			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
+		},
+	},
+};
+
+void __init apq8064_init_gpiomux(void)
+{
+	int rc;
+
+	rc = msm_gpiomux_init(NR_GPIO_IRQS);
+	if (rc) {
+		pr_err(KERN_ERR "msm_gpiomux_init failed %d\n", rc);
+		return;
+	}
+
+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
+	msm_gpiomux_install(apq8064_ethernet_configs,
+			ARRAY_SIZE(apq8064_ethernet_configs));
+#endif
+
+	msm_gpiomux_install(apq8064_gsbi_configs,
+			ARRAY_SIZE(apq8064_gsbi_configs));
+
+	msm_gpiomux_install(apq8064_audio_auxpcm_configs,
+			ARRAY_SIZE(apq8064_audio_auxpcm_configs));
+}
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
new file mode 100644
index 0000000..032d8da
--- /dev/null
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -0,0 +1,102 @@
+/* Copyright (c) 2011, 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/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.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 "devices.h"
+#include "board-8064.h"
+
+
+static struct pm8xxx_mpp_platform_data
+apq8064_pm8921_mpp_pdata __devinitdata = {
+	.mpp_base	= PM8921_MPP_PM_TO_SYS(1),
+};
+
+static struct pm8xxx_gpio_platform_data
+apq8064_pm8921_gpio_pdata __devinitdata = {
+	.gpio_base	= PM8921_GPIO_PM_TO_SYS(1),
+};
+
+static struct pm8xxx_irq_platform_data
+apq8064_pm8921_irq_pdata __devinitdata = {
+	.irq_base		= PM8921_IRQ_BASE,
+	.devirq			= PM8921_USR_IRQ_N,
+	.irq_trigger_flag	= IRQF_TRIGGER_HIGH,
+	.dev_id			= 0,
+};
+
+static struct pm8921_platform_data
+apq8064_pm8921_platform_data __devinitdata = {
+	.regulator_pdatas	= msm8064_pm8921_regulator_pdata,
+	.irq_pdata		= &apq8064_pm8921_irq_pdata,
+	.gpio_pdata		= &apq8064_pm8921_gpio_pdata,
+	.mpp_pdata		= &apq8064_pm8921_mpp_pdata,
+};
+
+static struct pm8xxx_irq_platform_data
+apq8064_pm8821_irq_pdata __devinitdata = {
+	.irq_base		= PM8821_IRQ_BASE,
+	.devirq			= PM8821_USR_IRQ_N,
+	.irq_trigger_flag	= IRQF_TRIGGER_HIGH,
+	.dev_id			= 1,
+};
+
+static struct pm8xxx_mpp_platform_data
+apq8064_pm8821_mpp_pdata __devinitdata = {
+	.mpp_base	= PM8821_MPP_PM_TO_SYS(1),
+};
+
+static struct pm8821_platform_data
+apq8064_pm8821_platform_data __devinitdata = {
+	.irq_pdata	= &apq8064_pm8821_irq_pdata,
+	.mpp_pdata	= &apq8064_pm8821_mpp_pdata,
+};
+
+static struct msm_ssbi_platform_data apq8064_ssbi_pm8921_pdata __devinitdata = {
+	.controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
+	.slave	= {
+		.name		= "pm8921-core",
+		.platform_data	= &apq8064_pm8921_platform_data,
+	},
+};
+
+static struct msm_ssbi_platform_data apq8064_ssbi_pm8821_pdata __devinitdata = {
+	.controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
+	.slave	= {
+		.name		= "pm8821-core",
+		.platform_data	= &apq8064_pm8821_platform_data,
+	},
+};
+
+void __init apq8064_init_pmic(void)
+{
+	apq8064_device_ssbi_pmic1.dev.platform_data =
+						&apq8064_ssbi_pm8921_pdata;
+	apq8064_device_ssbi_pmic2.dev.platform_data =
+				&apq8064_ssbi_pm8821_pdata;
+	apq8064_pm8921_platform_data.num_regulators =
+					msm8064_pm8921_regulator_pdata_len;
+
+	if (machine_is_apq8064_rumi3()) {
+		apq8064_pm8921_irq_pdata.devirq = 0;
+		apq8064_pm8821_irq_pdata.devirq = 0;
+	}
+}
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 6e2c044..4dcc626 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -152,7 +152,6 @@
 	apq8064_reserve_table[p->memory_type].size += p->size;
 }
 
-
 static void __init reserve_pmem_memory(void)
 {
 	reserve_memory_for(&android_pmem_adsp_pdata);
@@ -521,130 +520,6 @@
 	},
 };
 
-#ifdef CONFIG_KS8851
-static struct gpiomux_setting gpio_eth_config = {
-	.pull = GPIOMUX_PULL_NONE,
-	.drv = GPIOMUX_DRV_8MA,
-	.func = GPIOMUX_FUNC_GPIO,
-};
-
-/* The SPI configurations apply to GSBI 5*/
-static struct gpiomux_setting gpio_spi_config = {
-	.func = GPIOMUX_FUNC_2,
-	.drv = GPIOMUX_DRV_8MA,
-	.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,
-	.pull = GPIOMUX_PULL_NONE,
-};
-#endif
-
-struct msm_gpiomux_config apq8064_ethernet_configs[NR_GPIO_IRQS] = {
-#ifdef CONFIG_KS8851
-	{
-		.gpio = KS8851_IRQ_GPIO,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gpio_eth_config,
-			[GPIOMUX_ACTIVE] = &gpio_eth_config,
-		}
-	},
-#endif
-};
-
-static struct msm_gpiomux_config apq8064_gsbi_configs[] __initdata = {
-#ifdef CONFIG_KS8851
-	{
-		.gpio      = 51,		/* GSBI5 QUP SPI_DATA_MOSI */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
-		},
-	},
-	{
-		.gpio      = 52,		/* GSBI5 QUP SPI_DATA_MISO */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
-		},
-	},
-	{
-		.gpio      = 31,		/* GSBI5 QUP SPI_CS2_N */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gpio_spi_cs2_config,
-		},
-	},
-	{
-		.gpio      = 54,		/* GSBI5 QUP SPI_CLK */
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gpio_spi_config,
-		},
-	},
-#endif
-};
-
-static struct pm8xxx_mpp_platform_data
-apq8064_pm8921_mpp_pdata __devinitdata = {
-	.mpp_base	= PM8921_MPP_PM_TO_SYS(1),
-};
-
-static struct pm8xxx_gpio_platform_data
-apq8064_pm8921_gpio_pdata __devinitdata = {
-	.gpio_base	= PM8921_GPIO_PM_TO_SYS(1),
-};
-
-static struct pm8xxx_irq_platform_data
-apq8064_pm8921_irq_pdata __devinitdata = {
-	.irq_base		= PM8921_IRQ_BASE,
-	.devirq			= PM8921_USR_IRQ_N,
-	.irq_trigger_flag	= IRQF_TRIGGER_HIGH,
-	.dev_id			= 0,
-};
-
-static struct pm8921_platform_data
-apq8064_pm8921_platform_data __devinitdata = {
-	.regulator_pdatas	= msm8064_pm8921_regulator_pdata,
-	.irq_pdata		= &apq8064_pm8921_irq_pdata,
-	.gpio_pdata		= &apq8064_pm8921_gpio_pdata,
-	.mpp_pdata		= &apq8064_pm8921_mpp_pdata,
-};
-
-static struct pm8xxx_irq_platform_data
-apq8064_pm8821_irq_pdata __devinitdata = {
-	.irq_base		= PM8821_IRQ_BASE,
-	.devirq			= PM8821_USR_IRQ_N,
-	.irq_trigger_flag	= IRQF_TRIGGER_HIGH,
-	.dev_id			= 1,
-};
-
-static struct pm8xxx_mpp_platform_data
-apq8064_pm8821_mpp_pdata __devinitdata = {
-	.mpp_base	= PM8821_MPP_PM_TO_SYS(1),
-};
-
-static struct pm8821_platform_data
-apq8064_pm8821_platform_data __devinitdata = {
-	.irq_pdata	= &apq8064_pm8821_irq_pdata,
-	.mpp_pdata	= &apq8064_pm8821_mpp_pdata,
-};
-
-static struct msm_ssbi_platform_data apq8064_ssbi_pm8921_pdata __devinitdata = {
-	.controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
-	.slave	= {
-		.name		= "pm8921-core",
-		.platform_data	= &apq8064_pm8921_platform_data,
-	},
-};
-
-static struct msm_ssbi_platform_data apq8064_ssbi_pm8821_pdata __devinitdata = {
-	.controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
-	.slave	= {
-		.name		= "pm8821-core",
-		.platform_data	= &apq8064_pm8821_platform_data,
-	},
-};
-
 static struct slim_boardinfo apq8064_slim_devices[] = {
 	{
 	.bus_num = 1,
@@ -658,77 +533,12 @@
 	.src_clk_rate = 24000000,
 };
 
-
-static struct gpiomux_setting audio_auxpcm[] = {
-	/* Suspended state */
-	{
-		.func = GPIOMUX_FUNC_GPIO,
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_NONE,
-	},
-	/* Active state */
-	{
-		.func = GPIOMUX_FUNC_1,
-		.drv = GPIOMUX_DRV_2MA,
-		.pull = GPIOMUX_PULL_NONE,
-	},
-};
-static struct msm_gpiomux_config apq8064_audio_auxpcm_configs[] __initdata = {
-	{
-		.gpio = 43,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
-			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
-		},
-	},
-	{
-		.gpio = 44,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
-			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
-		},
-	},
-	{
-		.gpio = 45,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
-			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
-		},
-	},
-	{
-		.gpio = 46,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &audio_auxpcm[0],
-			[GPIOMUX_ACTIVE] = &audio_auxpcm[1],
-		},
-	},
-};
-
 static void __init apq8064_i2c_init(void)
 {
 	apq8064_device_qup_i2c_gsbi4.dev.platform_data =
 					&apq8064_i2c_qup_gsbi4_pdata;
 }
 
-static int __init gpiomux_init(void)
-{
-	int rc;
-
-	rc = msm_gpiomux_init(NR_GPIO_IRQS);
-	if (rc) {
-		pr_err(KERN_ERR "msm_gpiomux_init failed %d\n", rc);
-		return rc;
-	}
-	msm_gpiomux_install(apq8064_ethernet_configs,
-			ARRAY_SIZE(apq8064_ethernet_configs));
-
-	msm_gpiomux_install(apq8064_gsbi_configs,
-			ARRAY_SIZE(apq8064_gsbi_configs));
-	msm_gpiomux_install(apq8064_audio_auxpcm_configs,
-			ARRAY_SIZE(apq8064_audio_auxpcm_configs));
-	return 0;
-}
-
 #ifdef CONFIG_KS8851
 static int ethernet_init(void)
 {
@@ -763,18 +573,13 @@
 	if (socinfo_init() < 0)
 		pr_err("socinfo_init() failed!\n");
 	apq8064_clock_init();
-	gpiomux_init();
+	apq8064_init_gpiomux();
 	apq8064_i2c_init();
 
 	apq8064_device_qup_spi_gsbi5.dev.platform_data =
 						&apq8064_qup_spi_gsbi5_pdata;
-	apq8064_device_ssbi_pmic1.dev.platform_data =
-						&apq8064_ssbi_pm8921_pdata;
-	apq8064_device_ssbi_pmic2.dev.platform_data =
-				&apq8064_ssbi_pm8821_pdata;
+	apq8064_init_pmic();
 	apq8064_device_otg.dev.platform_data = &msm_otg_pdata;
-	apq8064_pm8921_platform_data.num_regulators =
-					msm8064_pm8921_regulator_pdata_len;
 	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
 	apq8064_init_mmc();
 	slim_register_board_info(apq8064_slim_devices,
@@ -793,8 +598,6 @@
 
 static void __init apq8064_rumi3_init(void)
 {
-	apq8064_pm8921_irq_pdata.devirq = 0;
-	apq8064_pm8821_irq_pdata.devirq = 0;
 	apq8064_common_init();
 	ethernet_init();
 	platform_add_devices(rumi3_devices, ARRAY_SIZE(rumi3_devices));
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index d9da00a..4a48897 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -42,4 +42,6 @@
 		struct mmc_platform_data *plat);
 
 void apq8064_init_mmc(void);
+void apq8064_init_gpiomux(void);
+void apq8064_init_pmic(void);
 #endif
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index e827b2b..9e97e3f 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -415,6 +415,35 @@
 	},
 };
 #endif
+
+#ifdef CONFIG_MT9M114
+static struct msm_camera_sensor_flash_data flash_mt9m114 = {
+	.flash_type = MSM_CAMERA_FLASH_NONE
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_mt9m114 = {
+	.mount_angle = 90,
+	.sensor_reset = 107,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_mt9m114_data = {
+	.sensor_name = "mt9m114",
+	.pdata = &msm_camera_csi_device_data[0],
+	.flash_data = &flash_mt9m114,
+	.sensor_platform_info = &sensor_board_info_mt9m114,
+	.gpio_conf = &gpio_conf,
+	.csi_if = 1,
+	.camera_type = BACK_CAMERA_2D,
+};
+
+struct platform_device msm8960_camera_sensor_mt9m114 = {
+	.name = "msm_camera_mt9m114",
+	.dev = {
+		.platform_data = &msm_camera_sensor_mt9m114_data,
+	},
+};
+#endif
+
 #ifdef CONFIG_OV2720
 static struct msm_camera_sensor_flash_data flash_ov2720 = {
 	.flash_type	= MSM_CAMERA_FLASH_NONE,
@@ -455,6 +484,9 @@
 	int i;
 	struct platform_device *cam_dev[] = {
 		&msm8960_camera_sensor_imx074,
+#ifdef CONFIG_MT9M114
+		&msm8960_camera_sensor_mt9m114,
+#endif
 		&msm8960_camera_sensor_ov2720,
 	};
 
diff --git a/arch/arm/mach-msm/board-8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
index 5e1ea0d..c5d47f4 100644
--- a/arch/arm/mach-msm/board-8960-pmic.c
+++ b/arch/arm/mach-msm/board-8960-pmic.c
@@ -403,10 +403,11 @@
 	325,
 };
 
+#define MAX_VOLTAGE_MV		4200
 static struct pm8921_charger_platform_data pm8921_chg_pdata __devinitdata = {
 	.safety_time		= 180,
 	.update_time		= 60000,
-	.max_voltage		= 4200,
+	.max_voltage		= MAX_VOLTAGE_MV,
 	.min_voltage		= 3200,
 	.resume_voltage_delta	= 100,
 	.term_current		= 100,
@@ -431,6 +432,7 @@
 	.i_test			= 2500,
 	.v_failure		= 3000,
 	.calib_delay_ms		= 600000,
+	.max_voltage_uv		= MAX_VOLTAGE_MV * 1000,
 };
 
 #define	PM8921_LC_LED_MAX_CURRENT	4	/* I = 4mA */
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index f3e4f20..de4a6d6 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -32,6 +32,7 @@
 	REGULATOR_SUPPLY("dsi_vdda",		"mipi_dsi.1"),
 	REGULATOR_SUPPLY("mipi_csi_vdd",	"msm_camera_imx074.0"),
 	REGULATOR_SUPPLY("mipi_csi_vdd",	"msm_camera_ov2720.0"),
+	REGULATOR_SUPPLY("mipi_csi_vdd",	"msm_camera_mt9m114.0"),
 };
 VREG_CONSUMERS(L3) = {
 	REGULATOR_SUPPLY("8921_l3",		NULL),
@@ -71,11 +72,13 @@
 	REGULATOR_SUPPLY("8921_l11",		NULL),
 	REGULATOR_SUPPLY("cam_vana",		"msm_camera_imx074.0"),
 	REGULATOR_SUPPLY("cam_vana",		"msm_camera_ov2720.0"),
+	REGULATOR_SUPPLY("cam_vana",		"msm_camera_mt9m114.0"),
 };
 VREG_CONSUMERS(L12) = {
 	REGULATOR_SUPPLY("8921_l12",		NULL),
 	REGULATOR_SUPPLY("cam_vdig",		"msm_camera_imx074.0"),
 	REGULATOR_SUPPLY("cam_vdig",		"msm_camera_ov2720.0"),
+	REGULATOR_SUPPLY("cam_vdig",		"msm_camera_mt9m114.0"),
 };
 VREG_CONSUMERS(L14) = {
 	REGULATOR_SUPPLY("8921_l14",		NULL),
@@ -88,6 +91,7 @@
 	REGULATOR_SUPPLY("8921_l16",		NULL),
 	REGULATOR_SUPPLY("cam_vaf",		"msm_camera_imx074.0"),
 	REGULATOR_SUPPLY("cam_vaf",		"msm_camera_ov2720.0"),
+	REGULATOR_SUPPLY("cam_vaf",		"msm_camera_mt9m114.0"),
 };
 VREG_CONSUMERS(L17) = {
 	REGULATOR_SUPPLY("8921_l17",		NULL),
@@ -197,6 +201,7 @@
 	REGULATOR_SUPPLY("8921_lvs5",		NULL),
 	REGULATOR_SUPPLY("cam_vio",		"msm_camera_imx074.0"),
 	REGULATOR_SUPPLY("cam_vio",		"msm_camera_ov2720.0"),
+	REGULATOR_SUPPLY("cam_vio",		"msm_camera_mt9m114.0"),
 };
 VREG_CONSUMERS(LVS6) = {
 	REGULATOR_SUPPLY("8921_lvs6",		NULL),
@@ -482,7 +487,7 @@
 	RPM_SMPS(S3,	 0, 1, 1,  500000, 1150000, NULL, 100000, 4p80),
 	RPM_SMPS(S4,	 1, 1, 0, 1800000, 1800000, NULL, 100000, 3p20),
 	RPM_SMPS(S7,	 0, 1, 0, 1150000, 1150000, NULL, 100000, 3p20),
-	RPM_SMPS(S8,	 1, 1, 1, 2200000, 2200000, NULL, 100000, 1p60),
+	RPM_SMPS(S8,	 1, 1, 1, 2100000, 2100000, NULL, 100000, 1p60),
 
 	/*	ID     a_on pd ss min_uV   max_uV  supply  sys_uA init_ip */
 	RPM_LDO(L1,	 1, 1, 0, 1050000, 1050000, "8921_s4", 0, 10000),
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 0cf0fa7..be5e02a 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -114,11 +114,20 @@
 		.io_open_drain_ena = 0x0,
 		.irq_summary       = -1,
 	},
+	[SX150X_LIQUID] = {
+		.gpio_base         = GPIO_LIQUID_EXPANDER_BASE,
+		.oscio_is_gpo      = false,
+		.io_pullup_ena     = 0x0c08,
+		.io_pulldn_ena     = 0x4060,
+		.io_open_drain_ena = 0x000c,
+		.io_polarity       = 0,
+		.irq_summary       = -1,
+	},
 };
 
 #endif
 
-#define MSM_PMEM_ADSP_SIZE         0x3800000
+#define MSM_PMEM_ADSP_SIZE         0x4200000
 #define MSM_PMEM_AUDIO_SIZE        0x28B000
 #ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
 #define MSM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
@@ -1922,6 +1931,11 @@
 	I2C_BOARD_INFO("ov2720", 0x6C),
 	},
 #endif
+#ifdef CONFIG_MT9M114
+	{
+	I2C_BOARD_INFO("mt9m114", 0x48),
+	},
+#endif
 #ifdef CONFIG_MSM_CAMERA_FLASH_SC628A
 	{
 	I2C_BOARD_INFO("sc628a", 0x6E),
@@ -1981,6 +1995,13 @@
 };
 #endif /* CONFIG_ISL9519_CHARGER */
 
+static struct i2c_board_info liquid_io_expander_i2c_info[] __initdata = {
+	{
+		I2C_BOARD_INFO("sx1508q", 0x20),
+		.platform_data = &msm8960_sx150x_data[SX150X_LIQUID]
+	},
+};
+
 static struct i2c_registry msm8960_i2c_devices[] __initdata = {
 #ifdef CONFIG_MSM_CAMERA
 	{
@@ -2022,6 +2043,12 @@
 		msm_isa1200_board_info,
 		ARRAY_SIZE(msm_isa1200_board_info),
 	},
+	{
+		I2C_LIQUID,
+		MSM_8960_GSBI10_QUP_I2C_BUS_ID,
+		liquid_io_expander_i2c_info,
+		ARRAY_SIZE(liquid_io_expander_i2c_info),
+	},
 };
 #endif /* CONFIG_I2C */
 
diff --git a/arch/arm/mach-msm/board-8960.h b/arch/arm/mach-msm/board-8960.h
index 56fa3ca..e22868f 100644
--- a/arch/arm/mach-msm/board-8960.h
+++ b/arch/arm/mach-msm/board-8960.h
@@ -57,12 +57,13 @@
 	GPIO_CAM_GP_XMT_FLASH_INT,
 	GPIO_CAM_GP_LED_EN1,
 	GPIO_CAM_GP_LED_EN2,
-
+	GPIO_LIQUID_EXPANDER_BASE = GPIO_CAM_EXPANDER_BASE + 8,
 };
 #endif
 
 enum {
 	SX150X_CAM,
+	SX150X_LIQUID,
 };
 
 #endif
diff --git a/arch/arm/mach-msm/board-9615-regulator.c b/arch/arm/mach-msm/board-9615-regulator.c
index c4b7c5a..7cf4a8c 100644
--- a/arch/arm/mach-msm/board-9615-regulator.c
+++ b/arch/arm/mach-msm/board-9615-regulator.c
@@ -75,6 +75,7 @@
 };
 VREG_CONSUMERS(S3) = {
 	REGULATOR_SUPPLY("8018_s3",		NULL),
+	REGULATOR_SUPPLY("wlan_vreg",		"wlan_ar6000_pm_dev"),
 };
 VREG_CONSUMERS(S4) = {
 	REGULATOR_SUPPLY("8018_s4",		NULL),
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index f369c6c..f9beced 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -554,7 +554,7 @@
 };
 static struct bt_vreg_info bt_vregs[] = {
 	{"msme1", 2, 1800000, 1800000, 0, NULL},
-	{"bt", 21, 2900000, 3050000, 1, NULL}
+	{"bt", 21, 2900000, 3300000, 1, NULL}
 };
 
 static int bahama_bt(int on)
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 765f49e..0a539c5 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -5082,6 +5082,7 @@
 static struct platform_device *surf_devices[] __initdata = {
 	&msm_device_smd,
 	&msm_device_uart_dm12,
+	&msm_pil_q6v3,
 #ifdef CONFIG_I2C_QUP
 	&msm_gsbi3_qup_i2c_device,
 	&msm_gsbi4_qup_i2c_device,
@@ -6633,6 +6634,10 @@
 	PM8901_VREG_INIT_VS(HDMI_MVS),
 };
 
+static struct pm8xxx_misc_platform_data pm8901_misc_pdata = {
+	.priority		= 1,
+};
+
 static struct pm8xxx_irq_platform_data pm8901_irq_pdata = {
 	.irq_base		= PM8901_IRQ_BASE,
 	.devirq			= MSM_GPIO_TO_INT(PM8901_GPIO_INT),
@@ -6648,6 +6653,7 @@
 	.mpp_pdata		= &pm8901_mpp_pdata,
 	.regulator_pdatas	= pm8901_vreg_init,
 	.num_regulators		= ARRAY_SIZE(pm8901_vreg_init),
+	.misc_pdata		= &pm8901_misc_pdata,
 };
 
 static struct msm_ssbi_platform_data msm8x60_ssbi_pm8901_pdata __devinitdata = {
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 8685919..ed5f265 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -41,6 +41,7 @@
 #define REG_GCC(off)	(MSM_APCS_GCC_BASE + (off))
 
 /* Peripheral clock registers. */
+#define ADM0_PBUS_CLK_CTL_REG			REG(0x2208)
 #define CE1_HCLK_CTL_REG			REG(0x2720)
 #define CE1_CORE_CLK_CTL_REG			REG(0x2724)
 #define CE3_HCLK_CTL_REG			REG(0x36C4)
@@ -109,6 +110,7 @@
 #define RINGOSC_NS_REG				REG(0x2DC0)
 #define RINGOSC_STATUS_REG			REG(0x2DCC)
 #define RINGOSC_TCXO_CTL_REG			REG(0x2DC4)
+#define RPM_MSG_RAM_HCLK_CTL_REG		REG(0x27E0)
 #define SC0_U_CLK_BRANCH_ENA_VOTE_REG		REG(0x3080)
 #define SDCn_APPS_CLK_MD_REG(n)			REG(0x2828+(0x20*((n)-1)))
 #define SDCn_APPS_CLK_NS_REG(n)			REG(0x282C+(0x20*((n)-1)))
@@ -631,14 +633,12 @@
 	},
 };
 
-static int soc_clk_reset(struct clk *clk, enum clk_reset_action action)
-{
-	return branch_reset(&to_rcg_clk(clk)->b, action);
-}
-
 static struct clk_ops clk_ops_rcg_8960 = {
 	.enable = rcg_clk_enable,
 	.disable = rcg_clk_disable,
+	.enable_hwcg = rcg_clk_enable_hwcg,
+	.disable_hwcg = rcg_clk_disable_hwcg,
+	.in_hwcg_mode = rcg_clk_in_hwcg_mode,
 	.auto_off = rcg_clk_disable,
 	.handoff = rcg_clk_handoff,
 	.set_rate = rcg_clk_set_rate,
@@ -646,7 +646,7 @@
 	.list_rate = rcg_clk_list_rate,
 	.is_enabled = rcg_clk_is_enabled,
 	.round_rate = rcg_clk_round_rate,
-	.reset = soc_clk_reset,
+	.reset = rcg_clk_reset,
 	.is_local = local_clk_is_local,
 	.get_parent = rcg_clk_get_parent,
 };
@@ -654,12 +654,16 @@
 static struct clk_ops clk_ops_branch = {
 	.enable = branch_clk_enable,
 	.disable = branch_clk_disable,
+	.enable_hwcg = branch_clk_enable_hwcg,
+	.disable_hwcg = branch_clk_disable_hwcg,
+	.in_hwcg_mode = branch_clk_in_hwcg_mode,
 	.auto_off = branch_clk_disable,
 	.is_enabled = branch_clk_is_enabled,
 	.reset = branch_clk_reset,
 	.is_local = local_clk_is_local,
 	.get_parent = branch_clk_get_parent,
 	.set_parent = branch_clk_set_parent,
+	.handoff = branch_clk_handoff,
 };
 
 static struct clk_ops clk_ops_reset = {
@@ -686,6 +690,8 @@
 	.b = {
 		.ctl_reg = MAXI_EN_REG,
 		.en_mask = BIT(21),
+		.hwcg_reg = MAXI_EN_REG,
+		.hwcg_mask = BIT(11),
 		.reset_reg = SW_RESET_AXI_REG,
 		.reset_mask = BIT(14),
 		.halt_reg = DBG_BUS_VEC_E_REG,
@@ -702,6 +708,8 @@
 	.b = {
 		.ctl_reg = MAXI_EN_REG,
 		.en_mask = BIT(22),
+		.hwcg_reg = MAXI_EN_REG,
+		.hwcg_mask = BIT(15),
 		.reset_reg = SW_RESET_CORE_REG,
 		.reset_mask = BIT(10),
 		.halt_reg = DBG_BUS_VEC_E_REG,
@@ -732,6 +740,8 @@
 	.b = {
 		.ctl_reg = MAXI_EN4_REG,
 		.en_mask = BIT(23),
+		.hwcg_reg = MAXI_EN4_REG,
+		.hwcg_mask = BIT(22),
 		.halt_reg = DBG_BUS_VEC_I_REG,
 		.halt_bit = 25,
 	},
@@ -746,6 +756,8 @@
 	.b = {
 		.ctl_reg = MAXI_EN4_REG,
 		.en_mask = BIT(25),
+		.hwcg_reg = MAXI_EN4_REG,
+		.hwcg_mask = BIT(24),
 		.halt_reg = DBG_BUS_VEC_I_REG,
 		.halt_bit = 26,
 	},
@@ -761,6 +773,8 @@
 	.b = {
 		.ctl_reg = MAXI_EN_REG,
 		.en_mask = BIT(19),
+		.hwcg_reg = MAXI_EN_REG,
+		.hwcg_mask = BIT(13),
 		.reset_reg = SW_RESET_AXI_REG,
 		.reset_mask = BIT(4)|BIT(5)|BIT(7),
 		.halt_reg = DBG_BUS_VEC_E_REG,
@@ -794,6 +808,8 @@
 	.b = {
 		.ctl_reg = MAXI_EN_REG,
 		.en_mask = BIT(23),
+		.hwcg_reg = MAXI_EN_REG,
+		.hwcg_mask = BIT(16),
 		.reset_reg = SW_RESET_AXI_REG,
 		.reset_mask = BIT(13),
 		.halt_reg = DBG_BUS_VEC_E_REG,
@@ -810,6 +826,8 @@
 	.b = {
 		.ctl_reg = MAXI_EN2_REG,
 		.en_mask = BIT(24),
+		.hwcg_reg = MAXI_EN2_REG,
+		.hwcg_mask = BIT(25),
 		.reset_reg = SW_RESET_AXI_REG,
 		.reset_mask = BIT(6),
 		.halt_reg = DBG_BUS_VEC_E_REG,
@@ -826,6 +844,8 @@
 	.b = {
 		.ctl_reg = MAXI_EN2_REG,
 		.en_mask = BIT(26),
+		.hwcg_reg = MAXI_EN2_REG,
+		.hwcg_mask = BIT(27),
 		.reset_reg = SW_RESET_AXI_REG,
 		.reset_mask = BIT(15),
 		.halt_reg = DBG_BUS_VEC_E_REG,
@@ -922,6 +942,8 @@
 	.b = {
 		.ctl_reg = AHB_EN_REG,
 		.en_mask = BIT(18),
+		.hwcg_reg = AHB_EN2_REG,
+		.hwcg_mask = BIT(20),
 		.reset_reg = SW_RESET_AHB_REG,
 		.reset_mask = BIT(5),
 		.halt_reg = DBG_BUS_VEC_F_REG,
@@ -954,6 +976,8 @@
 	.b = {
 		.ctl_reg = AHB_EN_REG,
 		.en_mask = BIT(22),
+		.hwcg_reg = AHB_EN2_REG,
+		.hwcg_mask = BIT(15),
 		.reset_reg = SW_RESET_AHB2_REG,
 		.reset_mask = BIT(0),
 		.halt_reg = DBG_BUS_VEC_F_REG,
@@ -970,6 +994,8 @@
 	.b = {
 		.ctl_reg = AHB_EN_REG,
 		.en_mask = BIT(19),
+		.hwcg_reg = AHB_EN2_REG,
+		.hwcg_mask = BIT(28),
 		.reset_reg = SW_RESET_AHB_REG,
 		.reset_mask = BIT(12),
 		.halt_reg = DBG_BUS_VEC_F_REG,
@@ -986,6 +1012,8 @@
 	.b = {
 		.ctl_reg = AHB_EN_REG,
 		.en_mask = BIT(2),
+		.hwcg_reg = AHB_EN2_REG,
+		.hwcg_mask = BIT(29),
 		.reset_reg = SW_RESET_AHB_REG,
 		.reset_mask = BIT(11),
 		.halt_reg = DBG_BUS_VEC_F_REG,
@@ -1002,6 +1030,8 @@
 	.b = {
 		.ctl_reg = AHB_EN_REG,
 		.en_mask = BIT(3),
+		.hwcg_reg = AHB_EN2_REG,
+		.hwcg_mask = BIT(27),
 		.reset_reg = SW_RESET_AHB_REG,
 		.reset_mask = BIT(10),
 		.halt_reg = DBG_BUS_VEC_F_REG,
@@ -1018,6 +1048,8 @@
 	.b = {
 		.ctl_reg = AHB_EN_REG,
 		.en_mask = BIT(14),
+		.hwcg_reg = AHB_EN2_REG,
+		.hwcg_mask = BIT(21),
 		.reset_reg = SW_RESET_AHB_REG,
 		.reset_mask = BIT(9),
 		.halt_reg = DBG_BUS_VEC_F_REG,
@@ -1034,6 +1066,8 @@
 	.b = {
 		.ctl_reg = AHB_EN_REG,
 		.en_mask = BIT(4),
+		.hwcg_reg = AHB_EN2_REG,
+		.hwcg_mask = BIT(22),
 		.reset_reg = SW_RESET_AHB_REG,
 		.reset_mask = BIT(9),
 		.halt_reg = DBG_BUS_VEC_F_REG,
@@ -1066,6 +1100,8 @@
 	.b = {
 		.ctl_reg = AHB_EN_REG,
 		.en_mask = BIT(6),
+		.hwcg_reg = AHB_EN2_REG,
+		.hwcg_mask = BIT(12),
 		.reset_reg = SW_RESET_AHB_REG,
 		.reset_mask = BIT(8),
 		.halt_reg = DBG_BUS_VEC_F_REG,
@@ -1130,6 +1166,8 @@
 	.b = {
 		.ctl_reg = AHB_EN_REG,
 		.en_mask = BIT(15),
+		.hwcg_reg = AHB_EN_REG,
+		.hwcg_mask = BIT(26),
 		.halt_reg = DBG_BUS_VEC_F_REG,
 		.halt_bit = 22,
 	},
@@ -1160,6 +1198,8 @@
 	.b = {
 		.ctl_reg = AHB_EN_REG,
 		.en_mask = BIT(11),
+		.hwcg_reg = AHB_EN2_REG,
+		.hwcg_mask = BIT(26),
 		.reset_reg = SW_RESET_AHB_REG,
 		.reset_mask = BIT(1),
 		.halt_reg = DBG_BUS_VEC_F_REG,
@@ -1537,7 +1577,7 @@
 	.list_rate = rcg_clk_list_rate,
 	.is_enabled = rcg_clk_is_enabled,
 	.round_rate = rcg_clk_round_rate,
-	.reset = soc_clk_reset,
+	.reset = rcg_clk_reset,
 	.is_local = local_clk_is_local,
 	.get_parent = rcg_clk_get_parent,
 };
@@ -1707,6 +1747,8 @@
 	.b = {
 		.ctl_reg = PMEM_ACLK_CTL_REG,
 		.en_mask = BIT(4),
+		.hwcg_reg = PMEM_ACLK_CTL_REG,
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_DFAB_STATE_REG,
 		.halt_bit = 20,
 	},
@@ -2133,6 +2175,8 @@
 	.b = {
 		.ctl_reg = CE1_CORE_CLK_CTL_REG,
 		.en_mask = BIT(4),
+		.hwcg_reg = CE1_CORE_CLK_CTL_REG,
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_CFPB_STATEC_REG,
 		.halt_bit = 27,
 	},
@@ -2257,6 +2301,8 @@
 	.b = {
 		.ctl_reg = DMA_BAM_HCLK_CTL,
 		.en_mask = BIT(4),
+		.hwcg_reg = DMA_BAM_HCLK_CTL,
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_DFAB_STATE_REG,
 		.halt_bit = 12,
 	},
@@ -2271,6 +2317,8 @@
 	.b = {
 		.ctl_reg = GSBIn_HCLK_CTL_REG(1),
 		.en_mask = BIT(4),
+		.hwcg_reg = GSBIn_HCLK_CTL_REG(1),
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_CFPB_STATEA_REG,
 		.halt_bit = 11,
 	},
@@ -2285,6 +2333,8 @@
 	.b = {
 		.ctl_reg = GSBIn_HCLK_CTL_REG(2),
 		.en_mask = BIT(4),
+		.hwcg_reg = GSBIn_HCLK_CTL_REG(2),
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_CFPB_STATEA_REG,
 		.halt_bit = 7,
 	},
@@ -2299,6 +2349,8 @@
 	.b = {
 		.ctl_reg = GSBIn_HCLK_CTL_REG(3),
 		.en_mask = BIT(4),
+		.hwcg_reg = GSBIn_HCLK_CTL_REG(3),
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_CFPB_STATEA_REG,
 		.halt_bit = 3,
 	},
@@ -2313,6 +2365,8 @@
 	.b = {
 		.ctl_reg = GSBIn_HCLK_CTL_REG(4),
 		.en_mask = BIT(4),
+		.hwcg_reg = GSBIn_HCLK_CTL_REG(4),
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_CFPB_STATEB_REG,
 		.halt_bit = 27,
 	},
@@ -2327,6 +2381,8 @@
 	.b = {
 		.ctl_reg = GSBIn_HCLK_CTL_REG(5),
 		.en_mask = BIT(4),
+		.hwcg_reg = GSBIn_HCLK_CTL_REG(5),
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_CFPB_STATEB_REG,
 		.halt_bit = 23,
 	},
@@ -2341,6 +2397,8 @@
 	.b = {
 		.ctl_reg = GSBIn_HCLK_CTL_REG(6),
 		.en_mask = BIT(4),
+		.hwcg_reg = GSBIn_HCLK_CTL_REG(6),
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_CFPB_STATEB_REG,
 		.halt_bit = 19,
 	},
@@ -2355,6 +2413,8 @@
 	.b = {
 		.ctl_reg = GSBIn_HCLK_CTL_REG(7),
 		.en_mask = BIT(4),
+		.hwcg_reg = GSBIn_HCLK_CTL_REG(7),
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_CFPB_STATEB_REG,
 		.halt_bit = 15,
 	},
@@ -2369,6 +2429,8 @@
 	.b = {
 		.ctl_reg = GSBIn_HCLK_CTL_REG(8),
 		.en_mask = BIT(4),
+		.hwcg_reg = GSBIn_HCLK_CTL_REG(8),
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_CFPB_STATEB_REG,
 		.halt_bit = 11,
 	},
@@ -2383,6 +2445,8 @@
 	.b = {
 		.ctl_reg = GSBIn_HCLK_CTL_REG(9),
 		.en_mask = BIT(4),
+		.hwcg_reg = GSBIn_HCLK_CTL_REG(9),
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_CFPB_STATEB_REG,
 		.halt_bit = 7,
 	},
@@ -2397,6 +2461,8 @@
 	.b = {
 		.ctl_reg = GSBIn_HCLK_CTL_REG(10),
 		.en_mask = BIT(4),
+		.hwcg_reg = GSBIn_HCLK_CTL_REG(10),
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_CFPB_STATEB_REG,
 		.halt_bit = 3,
 	},
@@ -2411,6 +2477,8 @@
 	.b = {
 		.ctl_reg = GSBIn_HCLK_CTL_REG(11),
 		.en_mask = BIT(4),
+		.hwcg_reg = GSBIn_HCLK_CTL_REG(11),
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_CFPB_STATEC_REG,
 		.halt_bit = 18,
 	},
@@ -2425,6 +2493,8 @@
 	.b = {
 		.ctl_reg = GSBIn_HCLK_CTL_REG(12),
 		.en_mask = BIT(4),
+		.hwcg_reg = GSBIn_HCLK_CTL_REG(12),
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_CFPB_STATEC_REG,
 		.halt_bit = 14,
 	},
@@ -2470,6 +2540,8 @@
 	.b = {
 		.ctl_reg = TSIF_HCLK_CTL_REG,
 		.en_mask = BIT(4),
+		.hwcg_reg = TSIF_HCLK_CTL_REG,
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_CFPB_STATEC_REG,
 		.halt_bit = 7,
 	},
@@ -2512,6 +2584,8 @@
 	.b = {
 		.ctl_reg = USB_HS1_HCLK_CTL_REG,
 		.en_mask = BIT(4),
+		.hwcg_reg = USB_HS1_HCLK_CTL_REG,
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_DFAB_STATE_REG,
 		.halt_bit = 1,
 	},
@@ -2568,6 +2642,8 @@
 	.b = {
 		.ctl_reg = SDCn_HCLK_CTL_REG(1),
 		.en_mask = BIT(4),
+		.hwcg_reg = SDCn_HCLK_CTL_REG(1),
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_DFAB_STATE_REG,
 		.halt_bit = 11,
 	},
@@ -2582,6 +2658,8 @@
 	.b = {
 		.ctl_reg = SDCn_HCLK_CTL_REG(2),
 		.en_mask = BIT(4),
+		.hwcg_reg = SDCn_HCLK_CTL_REG(2),
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_DFAB_STATE_REG,
 		.halt_bit = 10,
 	},
@@ -2596,6 +2674,8 @@
 	.b = {
 		.ctl_reg = SDCn_HCLK_CTL_REG(3),
 		.en_mask = BIT(4),
+		.hwcg_reg = SDCn_HCLK_CTL_REG(3),
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_DFAB_STATE_REG,
 		.halt_bit = 9,
 	},
@@ -2610,6 +2690,8 @@
 	.b = {
 		.ctl_reg = SDCn_HCLK_CTL_REG(4),
 		.en_mask = BIT(4),
+		.hwcg_reg = SDCn_HCLK_CTL_REG(4),
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_DFAB_STATE_REG,
 		.halt_bit = 8,
 	},
@@ -2624,6 +2706,8 @@
 	.b = {
 		.ctl_reg = SDCn_HCLK_CTL_REG(5),
 		.en_mask = BIT(4),
+		.hwcg_reg = SDCn_HCLK_CTL_REG(5),
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_DFAB_STATE_REG,
 		.halt_bit = 7,
 	},
@@ -2654,6 +2738,8 @@
 	.b = {
 		.ctl_reg = SC0_U_CLK_BRANCH_ENA_VOTE_REG,
 		.en_mask = BIT(3),
+		.hwcg_reg = ADM0_PBUS_CLK_CTL_REG,
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_MSS_SMPSS_MISC_STATE_REG,
 		.halt_check = HALT_VOTED,
 		.halt_bit = 13,
@@ -2714,6 +2800,8 @@
 	.b = {
 		.ctl_reg = SC0_U_CLK_BRANCH_ENA_VOTE_REG,
 		.en_mask = BIT(6),
+		.hwcg_reg = RPM_MSG_RAM_HCLK_CTL_REG,
+		.hwcg_mask = BIT(6),
 		.halt_reg = CLK_HALT_SFPB_MISC_STATE_REG,
 		.halt_check = HALT_VOTED,
 		.halt_bit = 12,
@@ -5074,22 +5162,24 @@
 	CLK_LOOKUP("pll4",		pll4_clk.c,		NULL),
 	CLK_LOOKUP("measure",		measure_clk.c,		"debug"),
 
-	CLK_DUMMY("afab_clk",		AFAB_CLK,	NULL, 0),
-	CLK_DUMMY("afab_a_clk",		AFAB_A_CLK,	NULL, 0),
-	CLK_DUMMY("cfpb_clk",		CFPB_CLK,	NULL, 0),
-	CLK_DUMMY("cfpb_a_clk",		CFPB_A_CLK,	NULL, 0),
+	CLK_DUMMY("bus_clk",		AFAB_CLK,	"msm_apps_fab", 0),
+	CLK_DUMMY("bus_a_clk",		AFAB_A_CLK,	"msm_apps_fab", 0),
+	CLK_DUMMY("bus_clk",		SFAB_CLK,	"msm_sys_fab", 0),
+	CLK_DUMMY("bus_a_clk",		SFAB_A_CLK,	"msm_sys_fab", 0),
+	CLK_DUMMY("bus_clk",		SFPB_CLK,	"msm_sys_fpb", 0),
+	CLK_DUMMY("bus_a_clk",		SFPB_A_CLK,	"msm_sys_fpb", 0),
+	CLK_DUMMY("bus_clk",		MMFAB_CLK,	"msm_mm_fab", 0),
+	CLK_DUMMY("bus_a_clk",		MMFAB_A_CLK,	"msm_mm_fab", 0),
+	CLK_DUMMY("bus_clk",		CFPB_CLK,	"msm_cpss_fpb", 0),
+	CLK_DUMMY("bus_a_clk",		CFPB_A_CLK,	"msm_cpss_fpb", 0),
+	CLK_LOOKUP("mem_clk",		ebi1_msmbus_clk.c, "msm_bus"),
+	CLK_DUMMY("mem_a_clk",		EBI1_A_CLK,        "msm_bus", 0),
+
+	CLK_DUMMY("ebi1_clk",		EBI1_CLK,	NULL, 0),
 	CLK_DUMMY("dfab_clk",		DFAB_CLK,	NULL, 0),
 	CLK_DUMMY("dfab_a_clk",		DFAB_A_CLK,	NULL, 0),
-	CLK_DUMMY("ebi1_clk",		EBI1_CLK,	NULL, 0),
-	CLK_DUMMY("ebi1_a_clk",		EBI1_A_CLK,	NULL, 0),
-	CLK_DUMMY("mmfab_clk",		MMFAB_CLK,	NULL, 0),
-	CLK_DUMMY("mmfab_a_clk",	MMFAB_A_CLK,	NULL, 0),
-	CLK_DUMMY("mmfpb_clk",		MMFPB_CLK,	NULL, 0),
-	CLK_DUMMY("mmfpb_a_clk",	MMFPB_A_CLK,	NULL, 0),
-	CLK_DUMMY("sfab_clk",		SFAB_CLK,	NULL, 0),
-	CLK_DUMMY("sfab_a_clk",		SFAB_A_CLK,	NULL, 0),
-	CLK_DUMMY("sfpb_clk",		SFPB_CLK,	NULL, 0),
-	CLK_DUMMY("sfpb_a_clk",		SFPB_A_CLK,	NULL, 0),
+	CLK_DUMMY("bus_clk",		MMFPB_CLK,	NULL, 0),
+	CLK_DUMMY("bus_a_clk",		MMFPB_A_CLK,	NULL, 0),
 
 	CLK_LOOKUP("core_clk",		gp0_clk.c,		NULL),
 	CLK_LOOKUP("core_clk",		gp1_clk.c,		NULL),
@@ -5291,7 +5381,6 @@
 	CLK_LOOKUP("usb_hsic_system_clk", usb_hsic_system_clk.c,	NULL),
 	CLK_LOOKUP("usb_hsic_p_clk",	usb_hsic_p_clk.c,	NULL),
 
-	CLK_LOOKUP("ebi1_msmbus_clk",	ebi1_msmbus_clk.c, NULL),
 	CLK_LOOKUP("mem_clk",		ebi1_adm_clk.c, "msm_dmov"),
 
 	CLK_LOOKUP("l2_mclk",		l2_m_clk,     NULL),
@@ -5306,24 +5395,25 @@
 	CLK_LOOKUP("pll4",		pll4_clk.c,		NULL),
 	CLK_LOOKUP("measure",		measure_clk.c,		"debug"),
 
-	CLK_LOOKUP("afab_clk",		afab_clk.c,	NULL),
-	CLK_LOOKUP("afab_a_clk",	afab_a_clk.c,	NULL),
-	CLK_LOOKUP("cfpb_clk",		cfpb_clk.c,	NULL),
-	CLK_LOOKUP("cfpb_a_clk",	cfpb_a_clk.c,	NULL),
-	CLK_LOOKUP("cfpb_a_clk",	cfpb_a_clk.c,	"clock-8960"),
-	CLK_LOOKUP("dfab_clk",		dfab_clk.c,	NULL),
-	CLK_LOOKUP("dfab_a_clk",	dfab_a_clk.c,	NULL),
-	CLK_LOOKUP("ebi1_clk",		ebi1_clk.c,	NULL),
-	CLK_LOOKUP("ebi1_a_clk",	ebi1_a_clk.c,	NULL),
-	CLK_LOOKUP("mmfab_clk",		mmfab_clk.c,	NULL),
-	CLK_LOOKUP("mmfab_a_clk",	mmfab_a_clk.c,	NULL),
-	CLK_LOOKUP("mmfpb_clk",		mmfpb_clk.c,	NULL),
-	CLK_LOOKUP("mmfpb_a_clk",	mmfpb_a_clk.c,	NULL),
-	CLK_LOOKUP("mmfpb_a_clk",	mmfpb_a_clk.c,	"clock-8960"),
-	CLK_LOOKUP("sfab_clk",		sfab_clk.c,	NULL),
-	CLK_LOOKUP("sfab_a_clk",	sfab_a_clk.c,	NULL),
-	CLK_LOOKUP("sfpb_clk",		sfpb_clk.c,	NULL),
-	CLK_LOOKUP("sfpb_a_clk",	sfpb_a_clk.c,	NULL),
+	CLK_LOOKUP("bus_clk",		afab_clk.c,		"msm_apps_fab"),
+	CLK_LOOKUP("bus_a_clk",		afab_a_clk.c,		"msm_apps_fab"),
+	CLK_LOOKUP("bus_clk",		cfpb_clk.c,		"msm_cpss_fpb"),
+	CLK_LOOKUP("bus_a_clk",		cfpb_a_clk.c,		"msm_cpss_fpb"),
+	CLK_LOOKUP("bus_clk",		sfab_clk.c,		"msm_sys_fab"),
+	CLK_LOOKUP("bus_a_clk",		sfab_a_clk.c,		"msm_sys_fab"),
+	CLK_LOOKUP("bus_clk",		sfpb_clk.c,		"msm_sys_fpb"),
+	CLK_LOOKUP("bus_a_clk",		sfpb_a_clk.c,		"msm_sys_fpb"),
+	CLK_LOOKUP("bus_clk",		mmfab_clk.c,		"msm_mm_fab"),
+	CLK_LOOKUP("bus_a_clk",		mmfab_a_clk.c,		"msm_mm_fab"),
+	CLK_LOOKUP("mem_clk",		ebi1_msmbus_clk.c,	"msm_bus"),
+	CLK_LOOKUP("mem_a_clk",		ebi1_a_clk.c,		"msm_bus"),
+
+	CLK_LOOKUP("ebi1_clk",		ebi1_clk.c,		NULL),
+	CLK_LOOKUP("dfab_clk",		dfab_clk.c,		NULL),
+	CLK_LOOKUP("dfab_a_clk",	dfab_a_clk.c,		NULL),
+	CLK_LOOKUP("mmfpb_clk",		mmfpb_clk.c,		NULL),
+	CLK_LOOKUP("mmfpb_a_clk",	mmfpb_a_clk.c,		"clock-8960"),
+	CLK_LOOKUP("cfpb_a_clk",	cfpb_a_clk.c,		"clock-8960"),
 
 	CLK_LOOKUP("core_clk",		gp0_clk.c,		NULL),
 	CLK_LOOKUP("core_clk",		gp1_clk.c,		NULL),
@@ -5407,6 +5497,7 @@
 	CLK_LOOKUP("cam_clk",		cam0_clk.c,		NULL),
 	CLK_LOOKUP("cam_clk",		cam1_clk.c,		NULL),
 	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"msm_camera_imx074.0"),
+	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"msm_camera_mt9m114.0"),
 	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"msm_camera_ov2720.0"),
 	CLK_LOOKUP("csi_src_clk",	csi0_src_clk.c,		"msm_csid.0"),
 	CLK_LOOKUP("csi_src_clk",	csi1_src_clk.c,		"msm_csid.1"),
@@ -5535,7 +5626,6 @@
 	CLK_LOOKUP("dfab_clk",		dfab_sps_clk.c,	"msm_sps"),
 	CLK_LOOKUP("bus_clk",		dfab_bam_dmux_clk.c,	"BAM_RMNT"),
 
-	CLK_LOOKUP("ebi1_msmbus_clk",	ebi1_msmbus_clk.c, NULL),
 	CLK_LOOKUP("mem_clk",		ebi1_adm_clk.c, "msm_dmov"),
 
 	CLK_LOOKUP("l2_mclk",		l2_m_clk,     NULL),
@@ -5604,6 +5694,7 @@
 
 static void __init reg_init(void)
 {
+	void __iomem *imem_reg;
 	/* Deassert MM SW_RESET_ALL signal. */
 	writel_relaxed(0, SW_RESET_ALL_REG);
 
@@ -5612,12 +5703,21 @@
 	 * reserved bits on the other SoC. Writing to these reserved bits
 	 * should have no effect.
 	 */
-	/* Initialize MM AHB registers: Enable the FPB clock and disable HW
-	 * gating 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. */
-	rmwreg(0x00000003, AHB_EN_REG,  0x6C000103);
-	writel_relaxed(0x000007F9, AHB_EN2_REG);
+	/*
+	 * Initialize MM AHB registers: Enable the FPB clock and disable HW
+	 * gating on 8960v1/8064 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) {
+		rmwreg(0x44000000, AHB_EN_REG,  0x6C000103);
+		writel_relaxed(0x3C7097F9, AHB_EN2_REG);
+	} else {
+		rmwreg(0x00000003, AHB_EN_REG,  0x6C000103);
+		writel_relaxed(0x000007F9, AHB_EN2_REG);
+	}
 	if (cpu_is_apq8064())
 		rmwreg(0x00000000, AHB_EN3_REG, 0x00000001);
 
@@ -5628,14 +5728,31 @@
 	/* Initialize MM AXI registers: Enable HW gating for all clocks that
 	 * support it. Also set FORCE_CORE_ON bits, and any sleep and wake-up
 	 * delays to safe values. */
-	/* TODO: Enable HW Gating */
-	rmwreg(0x000007F9, MAXI_EN_REG,  0x0803FFFF);
-	rmwreg(0x3027FCFF, MAXI_EN2_REG, 0x3A3FFFFF);
+	if (cpu_is_msm8960() &&
+			SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 3) {
+		rmwreg(0x0003AFF9, MAXI_EN_REG,  0x0803FFFF);
+		rmwreg(0x3A27FCFF, MAXI_EN2_REG, 0x3A3FFFFF);
+		rmwreg(0x0027FCFF, MAXI_EN4_REG, 0x017FFFFF);
+	} else {
+		rmwreg(0x000007F9, MAXI_EN_REG,  0x0803FFFF);
+		rmwreg(0x3027FCFF, MAXI_EN2_REG, 0x3A3FFFFF);
+		rmwreg(0x0027FCFF, MAXI_EN4_REG, 0x017FFFFF);
+	}
 	rmwreg(0x0027FCFF, MAXI_EN3_REG, 0x003FFFFF);
-	rmwreg(0x0027FCFF, MAXI_EN4_REG, 0x017FFFFF);
 	if (cpu_is_apq8064())
 		rmwreg(0x009FE4FF, MAXI_EN5_REG, 0x01FFEFFF);
-	rmwreg(0x000003C7, SAXI_EN_REG,  0x00003FFF);
+	if (cpu_is_msm8960() &&
+			SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2)
+		rmwreg(0x00003C38, SAXI_EN_REG,  0x00003FFF);
+	else
+		rmwreg(0x000003C7, SAXI_EN_REG,  0x00003FFF);
+
+	/* Enable IMEM's clk_on signal */
+	imem_reg = ioremap(0x04b00040, 4);
+	if (imem_reg) {
+		writel_relaxed(0x3, imem_reg);
+		iounmap(imem_reg);
+	}
 
 	/* Initialize MM CC registers: Set MM FORCE_CORE_ON bits so that core
 	 * memories retain state even when not clocked. Also, set sleep and
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 454e9cf..45094d9 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -535,11 +535,6 @@
 	writel_relaxed(pll_mode, MM_PLL2_MODE_REG);
 }
 
-static int soc_clk_reset(struct clk *clk, enum clk_reset_action action)
-{
-	return branch_reset(&to_rcg_clk(clk)->b, action);
-}
-
 static struct clk_ops clk_ops_rcg_8x60 = {
 	.enable = rcg_clk_enable,
 	.disable = rcg_clk_disable,
@@ -550,7 +545,7 @@
 	.list_rate = rcg_clk_list_rate,
 	.is_enabled = rcg_clk_is_enabled,
 	.round_rate = rcg_clk_round_rate,
-	.reset = soc_clk_reset,
+	.reset = rcg_clk_reset,
 	.is_local = local_clk_is_local,
 	.get_parent = rcg_clk_get_parent,
 };
@@ -3576,28 +3571,29 @@
 
 static struct clk_lookup msm_clocks_8x60[] = {
 	CLK_LOOKUP("cxo",		cxo_clk.c,	NULL),
-	CLK_LOOKUP("pll4",		pll4_clk.c,	NULL),
-	CLK_LOOKUP("pll4",		pll4_clk.c,	"peripheral-reset"),
+	CLK_LOOKUP("pll4",		pll4_clk.c,	"pil_qdsp6v3"),
 	CLK_LOOKUP("measure",		measure_clk.c,	"debug"),
 
-	CLK_LOOKUP("afab_clk",		afab_clk.c,	NULL),
-	CLK_LOOKUP("afab_a_clk",	afab_a_clk.c,	NULL),
-	CLK_LOOKUP("cfpb_clk",		cfpb_clk.c,	NULL),
-	CLK_LOOKUP("cfpb_a_clk",	cfpb_a_clk.c,	NULL),
+	CLK_LOOKUP("bus_clk",		afab_clk.c,	"msm_apps_fab"),
+	CLK_LOOKUP("bus_a_clk",		afab_a_clk.c,	"msm_apps_fab"),
+	CLK_LOOKUP("bus_clk",		sfab_clk.c,	"msm_sys_fab"),
+	CLK_LOOKUP("bus_a_clk",		sfab_a_clk.c,	"msm_sys_fab"),
+	CLK_LOOKUP("bus_clk",		sfpb_clk.c,	"msm_sys_fpb"),
+	CLK_LOOKUP("bus_a_clk",		sfpb_a_clk.c,	"msm_sys_fpb"),
+	CLK_LOOKUP("bus_clk",		mmfab_clk.c,	"msm_mm_fab"),
+	CLK_LOOKUP("bus_a_clk",		mmfab_a_clk.c,	"msm_mm_fab"),
+	CLK_LOOKUP("bus_clk",		cfpb_clk.c,	"msm_cpss_fpb"),
+	CLK_LOOKUP("bus_a_clk",		cfpb_a_clk.c,	"msm_cpss_fpb"),
+	CLK_LOOKUP("mem_clk",		ebi1_msmbus_clk.c, "msm_bus"),
+	CLK_LOOKUP("mem_a_clk",		ebi1_a_clk.c,	"msm_bus"),
+	CLK_LOOKUP("smi_clk",		smi_clk.c,	"msm_bus"),
+	CLK_LOOKUP("smi_a_clk",		smi_a_clk.c,	"msm_bus"),
+
+	CLK_LOOKUP("ebi1_clk",		ebi1_clk.c,	NULL),
 	CLK_LOOKUP("dfab_clk",		dfab_clk.c,	NULL),
 	CLK_LOOKUP("dfab_a_clk",	dfab_a_clk.c,	NULL),
-	CLK_LOOKUP("ebi1_clk",		ebi1_clk.c,	NULL),
-	CLK_LOOKUP("ebi1_a_clk",	ebi1_a_clk.c,	NULL),
-	CLK_LOOKUP("mmfab_clk",		mmfab_clk.c,	NULL),
-	CLK_LOOKUP("mmfab_a_clk",	mmfab_a_clk.c,	NULL),
 	CLK_LOOKUP("mmfpb_clk",		mmfpb_clk.c,	NULL),
 	CLK_LOOKUP("mmfpb_a_clk",	mmfpb_a_clk.c,	NULL),
-	CLK_LOOKUP("sfab_clk",		sfab_clk.c,	NULL),
-	CLK_LOOKUP("sfab_a_clk",	sfab_a_clk.c,	NULL),
-	CLK_LOOKUP("sfpb_clk",		sfpb_clk.c,	NULL),
-	CLK_LOOKUP("sfpb_a_clk",	sfpb_a_clk.c,	NULL),
-	CLK_LOOKUP("smi_clk",		smi_clk.c,	NULL),
-	CLK_LOOKUP("smi_a_clk",		smi_a_clk.c,	NULL),
 
 	CLK_LOOKUP("core_clk",		gp0_clk.c,		NULL),
 	CLK_LOOKUP("core_clk",		gp1_clk.c,		NULL),
@@ -3793,7 +3789,6 @@
 	CLK_LOOKUP("bus_clk",		dfab_sdc4_clk.c, "msm_sdcc.4"),
 	CLK_LOOKUP("bus_clk",		dfab_sdc5_clk.c, "msm_sdcc.5"),
 
-	CLK_LOOKUP("ebi1_msmbus_clk",	ebi1_msmbus_clk.c, NULL),
 	CLK_LOOKUP("mem_clk",		ebi1_adm0_clk.c, "msm_dmov.0"),
 	CLK_LOOKUP("mem_clk",		ebi1_adm1_clk.c, "msm_dmov.1"),
 
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index 553fb4d..8c5f027 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -414,11 +414,6 @@
 	},
 };
 
-static int soc_clk_reset(struct clk *clk, enum clk_reset_action action)
-{
-	return branch_reset(&to_rcg_clk(clk)->b, action);
-}
-
 static struct clk_ops clk_ops_rcg_9615 = {
 	.enable = rcg_clk_enable,
 	.disable = rcg_clk_disable,
@@ -428,7 +423,7 @@
 	.list_rate = rcg_clk_list_rate,
 	.is_enabled = rcg_clk_is_enabled,
 	.round_rate = rcg_clk_round_rate,
-	.reset = soc_clk_reset,
+	.reset = rcg_clk_reset,
 	.is_local = local_clk_is_local,
 	.get_parent = rcg_clk_get_parent,
 };
@@ -1631,16 +1626,18 @@
 
 	CLK_LOOKUP("measure",	measure_clk.c,	"debug"),
 
-	CLK_LOOKUP("cfpb_clk",		cfpb_clk.c,	NULL),
-	CLK_LOOKUP("cfpb_a_clk",	cfpb_a_clk.c,	NULL),
+	CLK_LOOKUP("bus_clk",		sfab_clk.c,		"msm_sys_fab"),
+	CLK_LOOKUP("bus_a_clk",		sfab_a_clk.c,		"msm_sys_fab"),
+	CLK_LOOKUP("mem_clk",		ebi1_msmbus_clk.c,	"msm_bus"),
+	CLK_LOOKUP("mem_a_clk",		ebi1_a_clk.c,		"msm_bus"),
+
+	CLK_LOOKUP("bus_clk",		sfpb_clk.c,	NULL),
+	CLK_LOOKUP("bus_a_clk",		sfpb_a_clk.c,	NULL),
+	CLK_LOOKUP("bus_clk",		cfpb_clk.c,	NULL),
+	CLK_LOOKUP("bus_a_clk",		cfpb_a_clk.c,	NULL),
+	CLK_LOOKUP("ebi1_clk",		ebi1_clk.c,	NULL),
 	CLK_LOOKUP("dfab_clk",		dfab_clk.c,	NULL),
 	CLK_LOOKUP("dfab_a_clk",	dfab_a_clk.c,	NULL),
-	CLK_LOOKUP("ebi1_clk",		ebi1_clk.c,	NULL),
-	CLK_LOOKUP("ebi1_a_clk",	ebi1_a_clk.c,	NULL),
-	CLK_LOOKUP("sfab_clk",		sfab_clk.c,	NULL),
-	CLK_LOOKUP("sfab_a_clk",	sfab_a_clk.c,	NULL),
-	CLK_LOOKUP("sfpb_clk",		sfpb_clk.c,	NULL),
-	CLK_LOOKUP("sfpb_a_clk",	sfpb_a_clk.c,	NULL),
 
 	CLK_LOOKUP("core_clk",		gp0_clk.c,	NULL),
 	CLK_LOOKUP("core_clk",		gp1_clk.c,	NULL),
@@ -1703,7 +1700,6 @@
 	CLK_LOOKUP("bus_clk",		dfab_sdc2_clk.c,	"msm_sdcc.2"),
 	CLK_LOOKUP("dfab_clk",		dfab_sps_clk.c,		"msm_sps"),
 	CLK_LOOKUP("bus_clk",		dfab_bam_dmux_clk.c,	"BAM_RMNT"),
-	CLK_LOOKUP("ebi1_msmbus_clk",	ebi1_msmbus_clk.c, NULL),
 	CLK_LOOKUP("mem_clk",		ebi1_adm_clk.c, "msm_dmov"),
 
 	CLK_LOOKUP("iface_clk",		ce1_p_clk.c,		"qce.0"),
diff --git a/arch/arm/mach-msm/clock-debug.c b/arch/arm/mach-msm/clock-debug.c
index 4990c81..411a272 100644
--- a/arch/arm/mach-msm/clock-debug.c
+++ b/arch/arm/mach-msm/clock-debug.c
@@ -54,12 +54,31 @@
 
 static int clock_debug_measure_get(void *data, u64 *val)
 {
-	int ret;
 	struct clk *clock = data;
+	int ret, is_hw_gated;
+
+	/* Check to see if the clock is in hardware gating mode */
+	if (clock->flags & CLKFLAG_HWCG)
+		is_hw_gated = clock->ops->in_hwcg_mode(clock);
+	else
+		is_hw_gated = 0;
 
 	ret = clk_set_parent(measure, clock);
-	if (!ret)
+	if (!ret) {
+		/*
+		 * Disable hw gating to get accurate rate measurements. Only do
+		 * this if the clock is explictly enabled by software. This
+		 * allows us to detect errors where clocks are on even though
+		 * software is not requesting them to be on due to broken
+		 * hardware gating signals.
+		 */
+		if (is_hw_gated && clock->count)
+			clock->ops->disable_hwcg(clock);
 		*val = clk_get_rate(measure);
+		/* Reenable hwgating if it was disabled */
+		if (is_hw_gated && clock->count)
+			clock->ops->enable_hwcg(clock);
+	}
 
 	return ret;
 }
@@ -109,6 +128,16 @@
 DEFINE_SIMPLE_ATTRIBUTE(clock_local_fops, clock_debug_local_get,
 			NULL, "%llu\n");
 
+static int clock_debug_hwcg_get(void *data, u64 *val)
+{
+	struct clk *clock = data;
+	*val = !!(clock->flags & CLKFLAG_HWCG);
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(clock_hwcg_fops, clock_debug_hwcg_get,
+			NULL, "%llu\n");
+
 static struct dentry *debugfs_base;
 static u32 debug_suspend;
 static struct clk_lookup *msm_clocks;
@@ -239,6 +268,10 @@
 				&clock_local_fops))
 		goto error;
 
+	if (!debugfs_create_file("has_hw_gating", S_IRUGO, clk_dir, clock,
+				&clock_hwcg_fops))
+		goto error;
+
 	if (measure &&
 	    !clk_set_parent(measure, clock) &&
 	    !debugfs_create_file("measure", S_IRUGO, clk_dir, clock,
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index f8d84be..2a1c013 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -273,6 +273,14 @@
 	return invert ? !status_bit : status_bit;
 }
 
+int branch_in_hwcg_mode(const struct branch *b)
+{
+	if (!b->hwcg_mask)
+		return 0;
+
+	return !!(readl_relaxed(b->hwcg_reg) & b->hwcg_mask);
+}
+
 void __branch_clk_enable_reg(const struct branch *clk, const char *name)
 {
 	u32 reg_val;
@@ -291,6 +299,10 @@
 	 */
 	mb();
 
+	/* Skip checking halt bit if the clock is in hardware gated mode */
+	if (branch_in_hwcg_mode(clk))
+		return;
+
 	/* Wait for clock to enable before returning. */
 	if (clk->halt_check == DELAY)
 		udelay(HALT_CHECK_DELAY_US);
@@ -362,6 +374,10 @@
 	 */
 	mb();
 
+	/* Skip checking halt bit if the clock is in hardware gated mode */
+	if (branch_in_hwcg_mode(clk))
+		return reg_val;
+
 	/* Wait for clock to disable before continuing. */
 	if (clk->halt_check == DELAY || clk->halt_check == ENABLE_VOTED
 				     || clk->halt_check == HALT_VOTED)
@@ -584,12 +600,32 @@
 	return to_rcg_clk(clk)->current_freq->src_clk;
 }
 
+/* Disable hw clock gating if not set at boot */
+static void branch_handoff(struct branch *clk, struct clk *c)
+{
+	if (!branch_in_hwcg_mode(clk)) {
+		clk->hwcg_mask = 0;
+		c->flags &= ~CLKFLAG_HWCG;
+	} else {
+		c->flags |= CLKFLAG_HWCG;
+	}
+}
+
+int branch_clk_handoff(struct clk *c)
+{
+	struct branch_clk *clk = to_branch_clk(c);
+	branch_handoff(&clk->b, &clk->c);
+	return 0;
+}
+
 int rcg_clk_handoff(struct clk *c)
 {
 	struct rcg_clk *clk = to_rcg_clk(c);
 	uint32_t ctl_val, ns_val, md_val, ns_mask;
 	struct clk_freq_tbl *freq;
 
+	branch_handoff(&clk->b, &clk->c);
+
 	ctl_val = readl_relaxed(clk->b.ctl_reg);
 	if (!(ctl_val & clk->root_en_mask))
 		return 0;
@@ -859,35 +895,100 @@
 	return branch->enabled;
 }
 
-int branch_reset(struct branch *clk, enum clk_reset_action action)
+static void branch_enable_hwcg(struct branch *b)
+{
+	unsigned long flags;
+	u32 reg_val;
+
+	spin_lock_irqsave(&local_clock_reg_lock, flags);
+	reg_val = readl_relaxed(b->hwcg_reg);
+	reg_val |= b->hwcg_mask;
+	writel_relaxed(reg_val, b->hwcg_reg);
+	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
+}
+
+static void branch_disable_hwcg(struct branch *b)
+{
+	unsigned long flags;
+	u32 reg_val;
+
+	spin_lock_irqsave(&local_clock_reg_lock, flags);
+	reg_val = readl_relaxed(b->hwcg_reg);
+	reg_val &= ~b->hwcg_mask;
+	writel_relaxed(reg_val, b->hwcg_reg);
+	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
+}
+
+void branch_clk_enable_hwcg(struct clk *clk)
+{
+	struct branch_clk *branch = to_branch_clk(clk);
+	branch_enable_hwcg(&branch->b);
+}
+
+void branch_clk_disable_hwcg(struct clk *clk)
+{
+	struct branch_clk *branch = to_branch_clk(clk);
+	branch_disable_hwcg(&branch->b);
+}
+
+int branch_clk_in_hwcg_mode(struct clk *c)
+{
+	struct branch_clk *clk = to_branch_clk(c);
+	return branch_in_hwcg_mode(&clk->b);
+}
+
+void rcg_clk_enable_hwcg(struct clk *clk)
+{
+	struct rcg_clk *rcg = to_rcg_clk(clk);
+	branch_enable_hwcg(&rcg->b);
+}
+
+void rcg_clk_disable_hwcg(struct clk *clk)
+{
+	struct rcg_clk *rcg = to_rcg_clk(clk);
+	branch_disable_hwcg(&rcg->b);
+}
+
+int rcg_clk_in_hwcg_mode(struct clk *c)
+{
+	struct rcg_clk *clk = to_rcg_clk(c);
+	return branch_in_hwcg_mode(&clk->b);
+}
+
+int branch_reset(struct branch *b, enum clk_reset_action action)
 {
 	int ret = 0;
 	u32 reg_val;
 	unsigned long flags;
 
-	if (!clk->reset_reg)
+	if (!b->reset_reg)
 		return -EPERM;
 
-	spin_lock_irqsave(&local_clock_reg_lock, flags);
+	/* Disable hw gating when asserting a reset */
+	if (b->hwcg_mask && action == CLK_RESET_ASSERT)
+		branch_disable_hwcg(b);
 
-	reg_val = readl_relaxed(clk->reset_reg);
+	spin_lock_irqsave(&local_clock_reg_lock, flags);
+	/* Assert/Deassert reset */
+	reg_val = readl_relaxed(b->reset_reg);
 	switch (action) {
 	case CLK_RESET_ASSERT:
-		reg_val |= clk->reset_mask;
+		reg_val |= b->reset_mask;
 		break;
 	case CLK_RESET_DEASSERT:
-		reg_val &= ~(clk->reset_mask);
+		reg_val &= ~b->reset_mask;
 		break;
 	default:
 		ret = -EINVAL;
 	}
-	writel_relaxed(reg_val, clk->reset_reg);
-
+	writel_relaxed(reg_val, b->reset_reg);
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 
+	/* Enable hw gating when deasserting a reset */
+	if (b->hwcg_mask && action == CLK_RESET_DEASSERT)
+		branch_enable_hwcg(b);
 	/* Make sure write is issued before returning. */
 	mb();
-
 	return ret;
 }
 
@@ -896,6 +997,11 @@
 	return branch_reset(&to_branch_clk(clk)->b, action);
 }
 
+int rcg_clk_reset(struct clk *clk, enum clk_reset_action action)
+{
+	return branch_reset(&to_rcg_clk(clk)->b, action);
+}
+
 static int cdiv_clk_enable(struct clk *c)
 {
 	unsigned long flags;
@@ -967,6 +1073,8 @@
 	struct cdiv_clk *clk = to_cdiv_clk(c);
 	u32 reg_val;
 
+	branch_handoff(&clk->b, &clk->c);
+
 	reg_val = readl_relaxed(clk->ns_reg);
 	if (reg_val & clk->ext_mask) {
 		clk->cur_div = 0;
@@ -978,9 +1086,30 @@
 	return 0;
 }
 
+static void cdiv_clk_enable_hwcg(struct clk *c)
+{
+	struct cdiv_clk *clk = to_cdiv_clk(c);
+	branch_enable_hwcg(&clk->b);
+}
+
+static void cdiv_clk_disable_hwcg(struct clk *c)
+{
+	struct cdiv_clk *clk = to_cdiv_clk(c);
+	branch_disable_hwcg(&clk->b);
+}
+
+static int cdiv_clk_in_hwcg_mode(struct clk *c)
+{
+	struct cdiv_clk *clk = to_cdiv_clk(c);
+	return branch_in_hwcg_mode(&clk->b);
+}
+
 struct clk_ops clk_ops_cdiv = {
 	.enable = cdiv_clk_enable,
 	.disable = cdiv_clk_disable,
+	.in_hwcg_mode = cdiv_clk_in_hwcg_mode,
+	.enable_hwcg = cdiv_clk_enable_hwcg,
+	.disable_hwcg = cdiv_clk_disable_hwcg,
 	.auto_off = cdiv_clk_disable,
 	.handoff = cdiv_clk_handoff,
 	.set_rate = cdiv_clk_set_rate,
diff --git a/arch/arm/mach-msm/clock-local.h b/arch/arm/mach-msm/clock-local.h
index 2123513..a561802d 100644
--- a/arch/arm/mach-msm/clock-local.h
+++ b/arch/arm/mach-msm/clock-local.h
@@ -90,6 +90,8 @@
  * struct branch - branch on/off
  * @ctl_reg: clock control register
  * @en_mask: ORed with @ctl_reg to enable the clock
+ * @hwcg_reg: hardware clock gating register
+ * @hwcg_mask: ORed with @hwcg_reg to enable hardware clock gating
  * @halt_reg: halt register
  * @halt_check: type of halt check to perform
  * @halt_bit: ANDed with @halt_reg to test for clock halted
@@ -100,6 +102,9 @@
 	void __iomem *const ctl_reg;
 	const u32 en_mask;
 
+	void __iomem *hwcg_reg;
+	u32 hwcg_mask;
+
 	void __iomem *const halt_reg;
 	const u16 halt_check;
 	const u16 halt_bit;
@@ -108,9 +113,10 @@
 	const u32 reset_mask;
 };
 
-int branch_reset(struct branch *clk, enum clk_reset_action action);
+int branch_reset(struct branch *b, enum clk_reset_action action);
 void __branch_clk_enable_reg(const struct branch *clk, const char *name);
 u32 __branch_clk_disable_reg(const struct branch *clk, const char *name);
+int branch_clk_handoff(struct clk *c);
 
 /*
  * Generic clock-definition struct and macros
@@ -150,6 +156,10 @@
 long rcg_clk_round_rate(struct clk *clk, unsigned long rate);
 struct clk *rcg_clk_get_parent(struct clk *c);
 int rcg_clk_handoff(struct clk *c);
+int rcg_clk_reset(struct clk *clk, enum clk_reset_action action);
+void rcg_clk_enable_hwcg(struct clk *clk);
+void rcg_clk_disable_hwcg(struct clk *clk);
+int rcg_clk_in_hwcg_mode(struct clk *c);
 
 /**
  * struct cdiv_clk - integer divider clock with external source selection
@@ -286,6 +296,9 @@
 int branch_clk_set_parent(struct clk *clk, struct clk *parent);
 int branch_clk_is_enabled(struct clk *clk);
 int branch_clk_reset(struct clk *c, enum clk_reset_action action);
+void branch_clk_enable_hwcg(struct clk *clk);
+void branch_clk_disable_hwcg(struct clk *clk);
+int branch_clk_in_hwcg_mode(struct clk *c);
 
 /**
  * struct measure_clk - for rate measurement debug use
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index ec8ff6c..91121e6 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -29,6 +29,7 @@
 #define CLKFLAG_NONEST			0x00000004
 #define CLKFLAG_NORESET			0x00000008
 #define CLKFLAG_HANDOFF_RATE		0x00000010
+#define CLKFLAG_HWCG			0x00000020
 #define CLKFLAG_SKIP_AUTO_OFF		0x00000200
 #define CLKFLAG_MIN			0x00000400
 #define CLKFLAG_MAX			0x00000800
@@ -63,6 +64,9 @@
 	int (*enable)(struct clk *clk);
 	void (*disable)(struct clk *clk);
 	void (*auto_off)(struct clk *clk);
+	void (*enable_hwcg)(struct clk *clk);
+	void (*disable_hwcg)(struct clk *clk);
+	int (*in_hwcg_mode)(struct clk *clk);
 	int (*handoff)(struct clk *clk);
 	int (*reset)(struct clk *clk, enum clk_reset_action action);
 	int (*set_rate)(struct clk *clk, unsigned long rate);
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index 72fdcf7..aa9e380 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -188,6 +188,23 @@
 	}
 }
 
+#define MSM_LPASS_QDSP6SS_PHYS 0x28800000
+
+static struct resource msm_8660_q6_resources[] = {
+	{
+		.start  = MSM_LPASS_QDSP6SS_PHYS,
+		.end    = MSM_LPASS_QDSP6SS_PHYS + SZ_256 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device msm_pil_q6v3 = {
+	.name = "pil_qdsp6v3",
+	.id = -1,
+	.num_resources  = ARRAY_SIZE(msm_8660_q6_resources),
+	.resource       = msm_8660_q6_resources,
+};
+
 static struct resource msm_uart1_dm_resources[] = {
 	{
 		.start = MSM_UART1DM_PHYS,
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index ffe22f8..9743ee2 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -174,6 +174,7 @@
 extern struct platform_device msm_pcm_afe;
 extern struct platform_device msm_compr_dsp;
 
+extern struct platform_device msm_pil_q6v3;
 extern struct platform_device msm_8960_q6_lpass;
 extern struct platform_device msm_8960_q6_mss_fw;
 extern struct platform_device msm_8960_q6_mss_sw;
diff --git a/arch/arm/mach-msm/idle-v7.S b/arch/arm/mach-msm/idle-v7.S
index 40e13fa..e855357 100644
--- a/arch/arm/mach-msm/idle-v7.S
+++ b/arch/arm/mach-msm/idle-v7.S
@@ -212,8 +212,17 @@
 	mcr     p15, 0, r3, c8, c7, 0   /* UTLBIALL */
 	mcr     p15, 0, r3, c7, c5, 6   /* BPIALL */
 	dsb
-
 	isb
+#ifdef CONFIG_ARCH_MSM_KRAIT
+	mrc	p15, 0, r1, c0, c0, 0
+	ldr	r3, =0xff00fc00
+	and	r3, r1, r3
+	ldr 	r1, =0x51000400
+	cmp	r3, r1
+	mrceq	p15, 7, r3, c15, c0, 2
+	biceq	r3, r3, #0x400
+	mcreq	p15, 7, r3, c15, c0, 2
+#endif
 	stmfd   sp!, {lr}
 	bl      v7_flush_kern_cache_all
 #ifdef CONFIG_MSM_TRACE_ACROSS_PC
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index b41398e..ae1f753 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -195,6 +195,7 @@
 #define VFE31_OUTPUT_MODE_T (0x1 << 4)
 
 #define CSI_EMBED_DATA 0x12
+#define CSI_YUV422_8  0x1E
 #define CSI_RAW8    0x2A
 #define CSI_RAW10   0x2B
 #define CSI_RAW12   0x2C
@@ -323,7 +324,8 @@
 
 struct msm_actuator_ctrl {
 	int (*a_init_table)(void);
-	int (*a_power_down)(void);
+	int (*a_power_up)(void *);
+	int (*a_power_down)(void *);
 	int (*a_create_subdevice)(void *, void *);
 	int (*a_config)(void __user *);
 };
diff --git a/arch/arm/mach-msm/include/mach/scm.h b/arch/arm/mach-msm/include/mach/scm.h
index e511b2e..a332b67 100644
--- a/arch/arm/mach-msm/include/mach/scm.h
+++ b/arch/arm/mach-msm/include/mach/scm.h
@@ -27,8 +27,8 @@
 extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
 		void *resp_buf, size_t resp_len);
 
-extern u32 scm_call_atomic1(u32 svc, u32 cmd, u32 arg1);
-extern u32 scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2);
+extern s32 scm_call_atomic1(u32 svc, u32 cmd, u32 arg1);
+extern s32 scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2);
 
 #define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
 
@@ -43,12 +43,12 @@
 	return 0;
 }
 
-static inline u32 scm_call_atomic1(u32 svc, u32 cmd, u32 arg1)
+static inline s32 scm_call_atomic1(u32 svc, u32 cmd, u32 arg1)
 {
 	return 0;
 }
 
-static inline u32 scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2)
+static inline s32 scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2)
 {
 	return 0;
 }
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
index fc91291..296c6dc 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
@@ -140,8 +140,8 @@
 		.tier = tiered_slave_ebi,
 		.num_tiers = ARRAY_SIZE(tiered_slave_ebi),
 		.buswidth = 8,
-		.slaveclk[DUAL_CTX] = "ebi1_msmbus_clk",
-		.slaveclk[ACTIVE_CTX] = "ebi1_a_clk",
+		.slaveclk[DUAL_CTX] = "mem_clk",
+		.slaveclk[ACTIVE_CTX] = "mem_a_clk",
 	},
 	{
 		.id = MSM_BUS_SLAVE_AMPSS_L2,
@@ -848,8 +848,8 @@
 	.info = apps_fabric_info,
 	.len = ARRAY_SIZE(apps_fabric_info),
 	.ahb = 0,
-	.fabclk[DUAL_CTX] = "afab_clk",
-	.fabclk[ACTIVE_CTX] = "afab_a_clk",
+	.fabclk[DUAL_CTX] = "bus_clk",
+	.fabclk[ACTIVE_CTX] = "bus_a_clk",
 	.haltid = MSM_RPM_ID_APPS_FABRIC_HALT_0,
 	.offset = MSM_RPM_ID_APPS_FABRIC_ARB_0,
 	.nmasters = 4,
@@ -864,8 +864,8 @@
 	system_fabric_info,
 	ARRAY_SIZE(system_fabric_info),
 	.ahb = 0,
-	.fabclk[DUAL_CTX] = "sfab_clk",
-	.fabclk[ACTIVE_CTX] = "sfab_a_clk",
+	.fabclk[DUAL_CTX] = "bus_clk",
+	.fabclk[ACTIVE_CTX] = "bus_a_clk",
 	.haltid = MSM_RPM_ID_SYSTEM_FABRIC_HALT_0,
 	.offset = MSM_RPM_ID_SYSTEM_FABRIC_ARB_0,
 	.nmasters = 17,
@@ -880,8 +880,8 @@
 	mmss_fabric_info,
 	ARRAY_SIZE(mmss_fabric_info),
 	.ahb = 0,
-	.fabclk[DUAL_CTX] = "mmfab_clk",
-	.fabclk[ACTIVE_CTX] = "mmfab_a_clk",
+	.fabclk[DUAL_CTX] = "bus_clk",
+	.fabclk[ACTIVE_CTX] = "bus_a_clk",
 	.haltid = MSM_RPM_ID_MM_FABRIC_HALT_0,
 	.offset = MSM_RPM_ID_MM_FABRIC_ARB_0,
 	.nmasters = 14,
@@ -896,8 +896,8 @@
 	sys_fpb_fabric_info,
 	ARRAY_SIZE(sys_fpb_fabric_info),
 	.ahb = 1,
-	.fabclk[DUAL_CTX] = "sfpb_clk",
-	.fabclk[ACTIVE_CTX] = "sfpb_a_clk",
+	.fabclk[DUAL_CTX] = "bus_clk",
+	.fabclk[ACTIVE_CTX] = "bus_a_clk",
 	.nmasters = 0,
 	.nslaves = 0,
 	.ntieredslaves = 0,
@@ -910,8 +910,8 @@
 	cpss_fpb_fabric_info,
 	ARRAY_SIZE(cpss_fpb_fabric_info),
 	.ahb = 1,
-	.fabclk[DUAL_CTX] = "cfpb_clk",
-	.fabclk[ACTIVE_CTX] = "cfpb_a_clk",
+	.fabclk[DUAL_CTX] = "bus_clk",
+	.fabclk[ACTIVE_CTX] = "bus_a_clk",
 	.nmasters = 0,
 	.nslaves = 0,
 	.ntieredslaves = 0,
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
index 97a3145..0d265c7 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
@@ -154,8 +154,8 @@
 		.tier = tiered_slave_ebi1_ch0,
 		.num_tiers = ARRAY_SIZE(tiered_slave_ebi1_ch0),
 		.buswidth = 8,
-		.slaveclk[DUAL_CTX] = "ebi1_msmbus_clk",
-		.slaveclk[ACTIVE_CTX] = "ebi1_a_clk",
+		.slaveclk[DUAL_CTX] = "mem_clk",
+		.slaveclk[ACTIVE_CTX] = "mem_a_clk",
 	},
 	{
 		.id = MSM_BUS_SLAVE_EBI_CH1,
@@ -164,8 +164,8 @@
 		.tier = tiered_slave_ebi1_ch1,
 		.num_tiers = ARRAY_SIZE(tiered_slave_ebi1_ch1),
 		.buswidth = 8,
-		.slaveclk[DUAL_CTX] = "ebi1_msmbus_clk",
-		.slaveclk[ACTIVE_CTX] = "ebi1_a_clk",
+		.slaveclk[DUAL_CTX] = "mem_clk",
+		.slaveclk[ACTIVE_CTX] = "mem_a_clk",
 	},
 	{
 		.id = MSM_BUS_SLAVE_AMPSS_L2,
@@ -875,8 +875,8 @@
 	.info = apps_fabric_info,
 	.len = ARRAY_SIZE(apps_fabric_info),
 	.ahb = 0,
-	.fabclk[DUAL_CTX] = "afab_clk",
-	.fabclk[ACTIVE_CTX] = "afab_a_clk",
+	.fabclk[DUAL_CTX] = "bus_clk",
+	.fabclk[ACTIVE_CTX] = "bus_a_clk",
 	.haltid = MSM_RPM_ID_APPS_FABRIC_CFG_HALT_0,
 	.offset = MSM_RPM_ID_APPS_FABRIC_ARB_0,
 	.nmasters = 6,
@@ -891,8 +891,8 @@
 	system_fabric_info,
 	ARRAY_SIZE(system_fabric_info),
 	.ahb = 0,
-	.fabclk[DUAL_CTX] = "sfab_clk",
-	.fabclk[ACTIVE_CTX] = "sfab_a_clk",
+	.fabclk[DUAL_CTX] = "bus_clk",
+	.fabclk[ACTIVE_CTX] = "bus_a_clk",
 	.haltid = MSM_RPM_ID_SYS_FABRIC_CFG_HALT_0,
 	.offset = MSM_RPM_ID_SYSTEM_FABRIC_ARB_0,
 	.nmasters = 15,
@@ -907,8 +907,8 @@
 	mmss_fabric_info,
 	ARRAY_SIZE(mmss_fabric_info),
 	.ahb = 0,
-	.fabclk[DUAL_CTX] = "mmfab_clk",
-	.fabclk[ACTIVE_CTX] = "mmfab_a_clk",
+	.fabclk[DUAL_CTX] = "bus_clk",
+	.fabclk[ACTIVE_CTX] = "bus_a_clk",
 	.haltid = MSM_RPM_ID_MMSS_FABRIC_CFG_HALT_0,
 	.offset = MSM_RPM_ID_MM_FABRIC_ARB_0,
 	.nmasters = 14,
@@ -923,8 +923,8 @@
 	sys_fpb_fabric_info,
 	ARRAY_SIZE(sys_fpb_fabric_info),
 	.ahb = 1,
-	.fabclk[DUAL_CTX] = "sfpb_clk",
-	.fabclk[ACTIVE_CTX] = "sfpb_a_clk",
+	.fabclk[DUAL_CTX] = "bus_clk",
+	.fabclk[ACTIVE_CTX] = "bus_a_clk",
 	.nmasters = 0,
 	.nslaves = 0,
 	.ntieredslaves = 0,
@@ -937,8 +937,8 @@
 	cpss_fpb_fabric_info,
 	ARRAY_SIZE(cpss_fpb_fabric_info),
 	.ahb = 1,
-	.fabclk[DUAL_CTX] = "cfpb_clk",
-	.fabclk[ACTIVE_CTX] = "cfpb_a_clk",
+	.fabclk[DUAL_CTX] = "bus_clk",
+	.fabclk[ACTIVE_CTX] = "bus_a_clk",
 	.nmasters = 0,
 	.nslaves = 0,
 	.ntieredslaves = 0,
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_9615.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_9615.c
index a941a89..5b52cb9 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_9615.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_9615.c
@@ -192,8 +192,8 @@
 		.tier = tiered_slave_ebi1_ch0,
 		.num_tiers = ARRAY_SIZE(tiered_slave_ebi1_ch0),
 		.buswidth = 8,
-		.slaveclk[DUAL_CTX] = "ebi1_msmbus_clk",
-		.slaveclk[ACTIVE_CTX] = "ebi1_a_clk",
+		.slaveclk[DUAL_CTX] = "mem_clk",
+		.slaveclk[ACTIVE_CTX] = "mem_a_clk",
 	},
 	{
 		.id = MSM_BUS_SLAVE_SYSTEM_IMEM,
@@ -285,8 +285,8 @@
 	system_fabric_info,
 	ARRAY_SIZE(system_fabric_info),
 	.ahb = 0,
-	.fabclk[DUAL_CTX] = "sfab_clk",
-	.fabclk[ACTIVE_CTX] = "sfab_a_clk",
+	.fabclk[DUAL_CTX] = "bus_clk",
+	.fabclk[ACTIVE_CTX] = "bus_a_clk",
 	.haltid = MSM_RPM_ID_SYS_FABRIC_CFG_HALT_0,
 	.offset = MSM_RPM_ID_SYSTEM_FABRIC_ARB_0,
 	.nmasters = 12,
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
index fd82111..02dfed6 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
@@ -71,7 +71,7 @@
 			SLAVE_NODE);
 
 	if (info->node_info->slaveclk[DUAL_CTX]) {
-		info->nodeclk[DUAL_CTX].clk = clk_get(NULL,
+		info->nodeclk[DUAL_CTX].clk = clk_get_sys("msm_bus",
 			info->node_info->slaveclk[DUAL_CTX]);
 		if (IS_ERR(info->nodeclk[DUAL_CTX].clk)) {
 			MSM_BUS_ERR("Could not get clock for %s\n",
@@ -144,8 +144,8 @@
 
 		for (ctx = 0; ctx < NUM_CTX; ctx++) {
 			if (info->node_info->slaveclk[ctx]) {
-				info->nodeclk[ctx].clk = clk_get(NULL,
-						info->node_info->slaveclk[ctx]);
+				info->nodeclk[ctx].clk = clk_get_sys("msm_bus",
+					info->node_info->slaveclk[ctx]);
 				if (IS_ERR(info->nodeclk[ctx].clk)) {
 					MSM_BUS_ERR("Couldn't get clk %s\n",
 						info->node_info->slaveclk[ctx]);
@@ -156,7 +156,7 @@
 			}
 		}
 		if (info->node_info->memclk) {
-			info->memclk.clk = clk_get(NULL,
+			info->memclk.clk = clk_get_sys("msm_bus",
 					info->node_info->memclk);
 			if (IS_ERR(info->memclk.clk)) {
 				MSM_BUS_ERR("Couldn't get clk %s\n",
@@ -652,10 +652,21 @@
 		fabric->fabdev.id);
 	fabric->fabdev.board_algo = fabric->pdata->board_algo;
 
+	/*
+	 * clk and bw for fabric->info will contain the max bw and clk
+	 * it will allow. This info will come from the boards file.
+	 */
+	ret = msm_bus_fabric_device_register(&fabric->fabdev);
+	if (ret) {
+		MSM_BUS_ERR("Error registering fabric %d ret %d\n",
+			fabric->fabdev.id, ret);
+		goto err;
+	}
+
 	for (ctx = 0; ctx < NUM_CTX; ctx++) {
 		if (pdata->fabclk[ctx]) {
-			fabric->info.nodeclk[ctx].clk = clk_get(NULL,
-							pdata->fabclk[ctx]);
+			fabric->info.nodeclk[ctx].clk = clk_get(
+				&fabric->fabdev.dev, pdata->fabclk[ctx]);
 			if (IS_ERR(fabric->info.nodeclk[ctx].clk)) {
 				MSM_BUS_ERR("Couldn't get clock %s\n",
 					pdata->fabclk[ctx]);
@@ -687,16 +698,6 @@
 			}
 		}
 	}
-	/*
-	 * clk and bw for fabric->info will contain the max bw and clk
-	 * it will allow. This info will come from the boards file.
-	 */
-	ret = msm_bus_fabric_device_register(&fabric->fabdev);
-	if (ret) {
-		MSM_BUS_ERR("Error registering fabric %d ret %d\n",
-			fabric->fabdev.id, ret);
-		goto err;
-	}
 
 	return ret;
 err:
diff --git a/arch/arm/mach-msm/peripheral-reset.c b/arch/arm/mach-msm/peripheral-reset.c
index f3f5388..2d60a7e 100644
--- a/arch/arm/mach-msm/peripheral-reset.c
+++ b/arch/arm/mach-msm/peripheral-reset.c
@@ -34,7 +34,6 @@
 #define PROXY_VOTE_TIMEOUT		10000
 
 #define MSM_MMS_REGS_BASE		0x10200000
-#define MSM_LPASS_QDSP6SS_BASE		0x28800000
 
 #define MARM_RESET			(MSM_CLK_CTL_BASE + 0x2BD4)
 #define MARM_BOOT_CONTROL		(msm_mms_regs_base + 0x0010)
@@ -58,18 +57,12 @@
 #define PLL8_STATUS			(MSM_CLK_CTL_BASE + 0x3158)
 #define CLK_HALT_MSS_SMPSS_MISC_STATE	(MSM_CLK_CTL_BASE + 0x2FDC)
 
-#define LCC_Q6_FUNC			(MSM_LPASS_CLK_CTL_BASE + 0x001C)
-#define QDSP6SS_RST_EVB			(msm_lpass_qdsp6ss_base + 0x0000)
-#define QDSP6SS_STRAP_TCM		(msm_lpass_qdsp6ss_base + 0x001C)
-#define QDSP6SS_STRAP_AHB		(msm_lpass_qdsp6ss_base + 0x0020)
-
 #define PPSS_RESET			(MSM_CLK_CTL_BASE + 0x2594)
 #define PPSS_PROC_CLK_CTL		(MSM_CLK_CTL_BASE + 0x2588)
 #define CLK_HALT_DFAB_STATE		(MSM_CLK_CTL_BASE + 0x2FC8)
 
-static int modem_start, q6_start, dsps_start;
+static int modem_start, dsps_start;
 static void __iomem *msm_mms_regs_base;
-static void __iomem *msm_lpass_qdsp6ss_base;
 
 static int init_image_modem_trusted(struct pil_desc *pil, const u8 *metadata,
 				    size_t size)
@@ -85,20 +78,6 @@
 	return 0;
 }
 
-static int init_image_q6_trusted(struct pil_desc *pil,
-				 const u8 *metadata, size_t size)
-{
-	return pas_init_image(PAS_Q6, metadata, size);
-}
-
-static int init_image_q6_untrusted(struct pil_desc *pil, const u8 *metadata,
-				   size_t size)
-{
-	struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
-	q6_start = ehdr->e_entry;
-	return 0;
-}
-
 static int init_image_dsps_trusted(struct pil_desc *pil, const u8 *metadata,
 				   size_t size)
 {
@@ -291,154 +270,6 @@
 	return 0;
 }
 
-#define LV_EN 			BIT(27)
-#define STOP_CORE		BIT(26)
-#define CLAMP_IO 		BIT(25)
-#define Q6SS_PRIV_ARES		BIT(24)
-#define Q6SS_SS_ARES		BIT(23)
-#define Q6SS_ISDB_ARES		BIT(22)
-#define Q6SS_ETM_ARES		BIT(21)
-#define Q6_JTAG_CRC_EN		BIT(20)
-#define Q6_JTAG_INV_EN		BIT(19)
-#define Q6_JTAG_CXC_EN		BIT(18)
-#define Q6_PXO_CRC_EN		BIT(17)
-#define Q6_PXO_INV_EN		BIT(16)
-#define Q6_PXO_CXC_EN		BIT(15)
-#define Q6_PXO_SLEEP_EN		BIT(14)
-#define Q6_SLP_CRC_EN		BIT(13)
-#define Q6_SLP_INV_EN		BIT(12)
-#define Q6_SLP_CXC_EN		BIT(11)
-#define CORE_ARES		BIT(10)
-#define CORE_L1_MEM_CORE_EN	BIT(9)
-#define CORE_TCM_MEM_CORE_EN	BIT(8)
-#define CORE_TCM_MEM_PERPH_EN	BIT(7)
-#define CORE_GFM4_CLK_EN	BIT(2)
-#define CORE_GFM4_RES		BIT(1)
-#define RAMP_PLL_SRC_SEL	BIT(0)
-
-#define Q6_STRAP_AHB_UPPER	(0x290 << 12)
-#define Q6_STRAP_AHB_LOWER	0x280
-#define Q6_STRAP_TCM_BASE	(0x28C << 15)
-#define Q6_STRAP_TCM_CONFIG	0x28B
-
-static struct clk *pll4;
-
-static void remove_q6_proxy_votes(unsigned long data)
-{
-	clk_disable(pll4);
-}
-static DEFINE_TIMER(q6_timer, remove_q6_proxy_votes, 0, 0);
-
-static void make_q6_proxy_votes(void)
-{
-	/* Make proxy votes for Q6 and set up timer to disable it. */
-	clk_enable(pll4);
-	mod_timer(&q6_timer, jiffies + msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
-}
-
-static void remove_q6_proxy_votes_now(void)
-{
-	/*
-	 * If the Q6 proxy vote hasn't been removed yet, them remove the
-	 * votes immediately.
-	 */
-	if (del_timer(&q6_timer))
-		remove_q6_proxy_votes(0);
-}
-
-static int reset_q6_untrusted(struct pil_desc *pil)
-{
-	u32 reg;
-
-	make_q6_proxy_votes();
-
-	/* Put Q6 into reset */
-	reg = __raw_readl(LCC_Q6_FUNC);
-	reg |= Q6SS_SS_ARES | Q6SS_ISDB_ARES | Q6SS_ETM_ARES | STOP_CORE |
-		CORE_ARES;
-	reg &= ~CORE_GFM4_CLK_EN;
-	__raw_writel(reg, LCC_Q6_FUNC);
-
-	/* Wait 8 AHB cycles for Q6 to be fully reset (AHB = 1.5Mhz) */
-	usleep_range(20, 30);
-
-	/* Turn on Q6 memory */
-	reg |= CORE_GFM4_CLK_EN | CORE_L1_MEM_CORE_EN | CORE_TCM_MEM_CORE_EN |
-		CORE_TCM_MEM_PERPH_EN;
-	__raw_writel(reg, LCC_Q6_FUNC);
-
-	/* Turn on Q6 core clocks and take core out of reset */
-	reg &= ~(CLAMP_IO | Q6SS_SS_ARES | Q6SS_ISDB_ARES | Q6SS_ETM_ARES |
-			CORE_ARES);
-	__raw_writel(reg, LCC_Q6_FUNC);
-
-	/* Wait for clocks to be enabled */
-	mb();
-	/* Program boot address */
-	__raw_writel((q6_start >> 12) & 0xFFFFF, QDSP6SS_RST_EVB);
-
-	__raw_writel(Q6_STRAP_TCM_CONFIG | Q6_STRAP_TCM_BASE,
-			QDSP6SS_STRAP_TCM);
-	__raw_writel(Q6_STRAP_AHB_UPPER | Q6_STRAP_AHB_LOWER,
-			QDSP6SS_STRAP_AHB);
-
-	/* Wait for addresses to be programmed before starting Q6 */
-	mb();
-
-	/* Start Q6 instruction execution */
-	reg &= ~STOP_CORE;
-	__raw_writel(reg, LCC_Q6_FUNC);
-
-	return 0;
-}
-
-static int reset_q6_trusted(struct pil_desc *pil)
-{
-	make_q6_proxy_votes();
-
-	return pas_auth_and_reset(PAS_Q6);
-}
-
-static int shutdown_q6_untrusted(struct pil_desc *pil)
-{
-	u32 reg;
-
-	/* Put Q6 into reset */
-	reg = __raw_readl(LCC_Q6_FUNC);
-	reg |= Q6SS_SS_ARES | Q6SS_ISDB_ARES | Q6SS_ETM_ARES | STOP_CORE |
-		CORE_ARES;
-	reg &= ~CORE_GFM4_CLK_EN;
-	__raw_writel(reg, LCC_Q6_FUNC);
-
-	/* Wait 8 AHB cycles for Q6 to be fully reset (AHB = 1.5Mhz) */
-	usleep_range(20, 30);
-
-	/* Turn off Q6 memory */
-	reg &= ~(CORE_L1_MEM_CORE_EN | CORE_TCM_MEM_CORE_EN |
-		CORE_TCM_MEM_PERPH_EN);
-	__raw_writel(reg, LCC_Q6_FUNC);
-
-	reg |= CLAMP_IO;
-	__raw_writel(reg, LCC_Q6_FUNC);
-
-	remove_q6_proxy_votes_now();
-
-	return 0;
-}
-
-static int shutdown_q6_trusted(struct pil_desc *pil)
-{
-	int ret;
-
-	ret = pas_shutdown(PAS_Q6);
-	if (ret)
-		return ret;
-
-	remove_q6_proxy_votes_now();
-
-	return 0;
-}
-
 static int reset_dsps_untrusted(struct pil_desc *pil)
 {
 	__raw_writel(0x10, PPSS_PROC_CLK_CTL);
@@ -490,13 +321,6 @@
 	.shutdown = shutdown_modem_untrusted,
 };
 
-struct pil_reset_ops pil_q6_ops = {
-	.init_image = init_image_q6_untrusted,
-	.verify_blob = verify_blob,
-	.auth_and_reset = reset_q6_untrusted,
-	.shutdown = shutdown_q6_untrusted,
-};
-
 struct pil_reset_ops pil_dsps_ops = {
 	.init_image = init_image_dsps_untrusted,
 	.verify_blob = verify_blob,
@@ -522,16 +346,6 @@
 	.ops = &pil_modem_ops,
 };
 
-static struct platform_device pil_q6 = {
-	.name = "pil_q6",
-};
-
-static struct pil_desc pil_q6_desc = {
-	.name = "q6",
-	.dev = &pil_q6.dev,
-	.ops = &pil_q6_ops,
-};
-
 static struct platform_device pil_playready = {
 	.name = "pil_playready",
 };
@@ -558,38 +372,22 @@
 	if (!msm_mms_regs_base)
 		goto err;
 
-	msm_lpass_qdsp6ss_base = ioremap(MSM_LPASS_QDSP6SS_BASE, SZ_256);
-	if (!msm_lpass_qdsp6ss_base)
-		goto err_lpass;
-
 	pxo = msm_xo_get(MSM_XO_PXO, "pil");
 	if (IS_ERR(pxo))
 		goto err_pxo;
 
-	pll4 = clk_get_sys("peripheral-reset", "pll4");
-	if (IS_ERR(pll4))
-		goto err_clk;
-
 	if (pas_supported(PAS_MODEM) > 0) {
 		pil_modem_ops.init_image = init_image_modem_trusted;
 		pil_modem_ops.auth_and_reset = reset_modem_trusted;
 		pil_modem_ops.shutdown = shutdown_modem_trusted;
 	}
 
-	if (pas_supported(PAS_Q6) > 0) {
-		pil_q6_ops.init_image = init_image_q6_trusted;
-		pil_q6_ops.auth_and_reset = reset_q6_trusted;
-		pil_q6_ops.shutdown = shutdown_q6_trusted;
-	}
-
 	if (pas_supported(PAS_DSPS) > 0) {
 		pil_dsps_ops.init_image = init_image_dsps_trusted;
 		pil_dsps_ops.auth_and_reset = reset_dsps_trusted;
 		pil_dsps_ops.shutdown = shutdown_dsps_trusted;
 	}
 
-	BUG_ON(platform_device_register(&pil_q6));
-	BUG_ON(msm_pil_register(&pil_q6_desc));
 	BUG_ON(platform_device_register(&pil_modem));
 	BUG_ON(msm_pil_register(&pil_modem_desc));
 	BUG_ON(platform_device_register(&pil_playready));
@@ -602,11 +400,7 @@
 
 	return 0;
 
-err_clk:
-	msm_xo_put(pxo);
 err_pxo:
-	iounmap(msm_lpass_qdsp6ss_base);
-err_lpass:
 	iounmap(msm_mms_regs_base);
 err:
 	return -ENOMEM;
@@ -615,7 +409,6 @@
 static void __exit msm_peripheral_reset_exit(void)
 {
 	iounmap(msm_mms_regs_base);
-	iounmap(msm_lpass_qdsp6ss_base);
 }
 
 arch_initcall(msm_peripheral_reset_init);
diff --git a/arch/arm/mach-msm/pil-q6v3.c b/arch/arm/mach-msm/pil-q6v3.c
new file mode 100644
index 0000000..7354d93
--- /dev/null
+++ b/arch/arm/mach-msm/pil-q6v3.c
@@ -0,0 +1,299 @@
+/* Copyright (c) 2010-2011, 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/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/elf.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <mach/msm_iomap.h>
+
+#include "peripheral-loader.h"
+#include "scm-pas.h"
+
+#define QDSP6SS_RST_EVB		0x0000
+#define QDSP6SS_STRAP_TCM	0x001C
+#define QDSP6SS_STRAP_AHB	0x0020
+
+#define LCC_Q6_FUNC		(MSM_LPASS_CLK_CTL_BASE + 0x001C)
+#define LV_EN			BIT(27)
+#define STOP_CORE		BIT(26)
+#define CLAMP_IO		BIT(25)
+#define Q6SS_PRIV_ARES		BIT(24)
+#define Q6SS_SS_ARES		BIT(23)
+#define Q6SS_ISDB_ARES		BIT(22)
+#define Q6SS_ETM_ARES		BIT(21)
+#define Q6_JTAG_CRC_EN		BIT(20)
+#define Q6_JTAG_INV_EN		BIT(19)
+#define Q6_JTAG_CXC_EN		BIT(18)
+#define Q6_PXO_CRC_EN		BIT(17)
+#define Q6_PXO_INV_EN		BIT(16)
+#define Q6_PXO_CXC_EN		BIT(15)
+#define Q6_PXO_SLEEP_EN		BIT(14)
+#define Q6_SLP_CRC_EN		BIT(13)
+#define Q6_SLP_INV_EN		BIT(12)
+#define Q6_SLP_CXC_EN		BIT(11)
+#define CORE_ARES		BIT(10)
+#define CORE_L1_MEM_CORE_EN	BIT(9)
+#define CORE_TCM_MEM_CORE_EN	BIT(8)
+#define CORE_TCM_MEM_PERPH_EN	BIT(7)
+#define CORE_GFM4_CLK_EN	BIT(2)
+#define CORE_GFM4_RES		BIT(1)
+#define RAMP_PLL_SRC_SEL	BIT(0)
+
+#define Q6_STRAP_AHB_UPPER	(0x290 << 12)
+#define Q6_STRAP_AHB_LOWER	0x280
+#define Q6_STRAP_TCM_BASE	(0x28C << 15)
+#define Q6_STRAP_TCM_CONFIG	0x28B
+
+#define PROXY_VOTE_TIMEOUT	10000
+
+struct q6v3_data {
+	void __iomem *base;
+	unsigned long start_addr;
+	struct clk *pll;
+	struct timer_list timer;
+};
+
+static int nop_verify_blob(struct pil_desc *pil, u32 phy_addr, size_t size)
+{
+	return 0;
+}
+
+static int pil_q6v3_init_image(struct pil_desc *pil, const u8 *metadata,
+		size_t size)
+{
+	const struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
+	struct q6v3_data *drv = dev_get_drvdata(pil->dev);
+	drv->start_addr = ehdr->e_entry;
+	return 0;
+}
+
+static void q6v3_remove_proxy_votes(unsigned long data)
+{
+	struct q6v3_data *drv = (struct q6v3_data *)data;
+	clk_disable(drv->pll);
+}
+
+static void q6v3_make_proxy_votes(struct device *dev)
+{
+	int ret;
+	struct q6v3_data *drv = dev_get_drvdata(dev);
+
+	ret = clk_enable(drv->pll);
+	if (ret)
+		dev_err(dev, "Failed to enable PLL\n");
+	mod_timer(&drv->timer, jiffies + msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+}
+
+static void q6v3_remove_proxy_votes_now(struct q6v3_data *drv)
+{
+	/* If the proxy vote hasn't been removed yet, remove it immediately. */
+	if (del_timer(&drv->timer))
+		q6v3_remove_proxy_votes((unsigned long)drv);
+}
+
+static int pil_q6v3_reset(struct pil_desc *pil)
+{
+	u32 reg;
+	struct q6v3_data *drv = dev_get_drvdata(pil->dev);
+
+	q6v3_make_proxy_votes(pil->dev);
+
+	/* Put Q6 into reset */
+	reg = readl_relaxed(LCC_Q6_FUNC);
+	reg |= Q6SS_SS_ARES | Q6SS_ISDB_ARES | Q6SS_ETM_ARES | STOP_CORE |
+		CORE_ARES;
+	reg &= ~CORE_GFM4_CLK_EN;
+	writel_relaxed(reg, LCC_Q6_FUNC);
+
+	/* Wait 8 AHB cycles for Q6 to be fully reset (AHB = 1.5Mhz) */
+	usleep_range(20, 30);
+
+	/* Turn on Q6 memory */
+	reg |= CORE_GFM4_CLK_EN | CORE_L1_MEM_CORE_EN | CORE_TCM_MEM_CORE_EN |
+		CORE_TCM_MEM_PERPH_EN;
+	writel_relaxed(reg, LCC_Q6_FUNC);
+
+	/* Turn on Q6 core clocks and take core out of reset */
+	reg &= ~(CLAMP_IO | Q6SS_SS_ARES | Q6SS_ISDB_ARES | Q6SS_ETM_ARES |
+			CORE_ARES);
+	writel_relaxed(reg, LCC_Q6_FUNC);
+
+	/* Wait for clocks to be enabled */
+	mb();
+	/* Program boot address */
+	writel_relaxed((drv->start_addr >> 12) & 0xFFFFF,
+			drv->base + QDSP6SS_RST_EVB);
+
+	writel_relaxed(Q6_STRAP_TCM_CONFIG | Q6_STRAP_TCM_BASE,
+			drv->base + QDSP6SS_STRAP_TCM);
+	writel_relaxed(Q6_STRAP_AHB_UPPER | Q6_STRAP_AHB_LOWER,
+			drv->base + QDSP6SS_STRAP_AHB);
+
+	/* Wait for addresses to be programmed before starting Q6 */
+	mb();
+
+	/* Start Q6 instruction execution */
+	reg &= ~STOP_CORE;
+	writel_relaxed(reg, LCC_Q6_FUNC);
+
+	return 0;
+}
+
+static int pil_q6v3_shutdown(struct pil_desc *pil)
+{
+	u32 reg;
+	struct q6v3_data *drv = dev_get_drvdata(pil->dev);
+
+	/* Put Q6 into reset */
+	reg = readl_relaxed(LCC_Q6_FUNC);
+	reg |= Q6SS_SS_ARES | Q6SS_ISDB_ARES | Q6SS_ETM_ARES | STOP_CORE |
+		CORE_ARES;
+	reg &= ~CORE_GFM4_CLK_EN;
+	writel_relaxed(reg, LCC_Q6_FUNC);
+
+	/* Wait 8 AHB cycles for Q6 to be fully reset (AHB = 1.5Mhz) */
+	usleep_range(20, 30);
+
+	/* Turn off Q6 memory */
+	reg &= ~(CORE_L1_MEM_CORE_EN | CORE_TCM_MEM_CORE_EN |
+		CORE_TCM_MEM_PERPH_EN);
+	writel_relaxed(reg, LCC_Q6_FUNC);
+
+	reg |= CLAMP_IO;
+	writel_relaxed(reg, LCC_Q6_FUNC);
+
+	q6v3_remove_proxy_votes_now(drv);
+
+	return 0;
+}
+
+static struct pil_reset_ops pil_q6v3_ops = {
+	.init_image = pil_q6v3_init_image,
+	.verify_blob = nop_verify_blob,
+	.auth_and_reset = pil_q6v3_reset,
+	.shutdown = pil_q6v3_shutdown,
+};
+
+static int pil_q6v3_init_image_trusted(struct pil_desc *pil,
+		const u8 *metadata, size_t size)
+{
+	return pas_init_image(PAS_Q6, metadata, size);
+}
+
+static int pil_q6v3_reset_trusted(struct pil_desc *pil)
+{
+	q6v3_make_proxy_votes(pil->dev);
+	return pas_auth_and_reset(PAS_Q6);
+}
+
+static int pil_q6v3_shutdown_trusted(struct pil_desc *pil)
+{
+	int ret;
+	struct q6v3_data *drv = dev_get_drvdata(pil->dev);
+
+	ret = pas_shutdown(PAS_Q6);
+	if (ret)
+		return ret;
+
+	q6v3_remove_proxy_votes_now(drv);
+
+	return 0;
+}
+
+static struct pil_reset_ops pil_q6v3_ops_trusted = {
+	.init_image = pil_q6v3_init_image_trusted,
+	.verify_blob = nop_verify_blob,
+	.auth_and_reset = pil_q6v3_reset_trusted,
+	.shutdown = pil_q6v3_shutdown_trusted,
+};
+
+static int __devinit pil_q6v3_driver_probe(struct platform_device *pdev)
+{
+	struct q6v3_data *drv;
+	struct resource *res;
+	struct pil_desc *desc;
+
+	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 (!drv)
+		return -ENOMEM;
+
+	drv->pll = clk_get(&pdev->dev, "pll4");
+	if (IS_ERR(drv->pll))
+		return PTR_ERR(drv->pll);
+
+	setup_timer(&drv->timer, q6v3_remove_proxy_votes, (unsigned long)drv);
+	desc->name = "q6";
+	desc->dev = &pdev->dev;
+
+	if (pas_supported(PAS_Q6) > 0) {
+		desc->ops = &pil_q6v3_ops_trusted;
+		dev_info(&pdev->dev, "using secure boot\n");
+	} else {
+		desc->ops = &pil_q6v3_ops;
+		dev_info(&pdev->dev, "using non-secure boot\n");
+	}
+
+	if (msm_pil_register(desc))
+		return -EINVAL;
+	return 0;
+}
+
+static int __devexit pil_q6v3_driver_exit(struct platform_device *pdev)
+{
+	struct q6v3_data *drv = platform_get_drvdata(pdev);
+	del_timer_sync(&drv->timer);
+	return 0;
+}
+
+static struct platform_driver pil_q6v3_driver = {
+	.probe = pil_q6v3_driver_probe,
+	.remove = __devexit_p(pil_q6v3_driver_exit),
+	.driver = {
+		.name = "pil_qdsp6v3",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init pil_q6v3_init(void)
+{
+	return platform_driver_register(&pil_q6v3_driver);
+}
+module_init(pil_q6v3_init);
+
+static void __exit pil_q6v3_exit(void)
+{
+	platform_driver_unregister(&pil_q6v3_driver);
+}
+module_exit(pil_q6v3_exit);
+
+MODULE_DESCRIPTION("Support for booting QDSP6v3 (Hexagon) processors");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/qdsp6v2/aac_in.c b/arch/arm/mach-msm/qdsp6v2/aac_in.c
index 2519bb7..41d3ff3 100644
--- a/arch/arm/mach-msm/qdsp6v2/aac_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/aac_in.c
@@ -214,7 +214,10 @@
 			rc = -EINVAL;
 			break;
 		}
-		if ((cfg.bit_rate < 24000) || (cfg.bit_rate > 192000)) {
+		/* For aac-lc, min_bit_rate = min(24Kbps, 0.5*SR*num_chan);
+		max_bi_rate = min(192Kbps, 6*SR*num_chan);
+		min_sample_rate = 8000Hz, max_rate=48000 */
+		if ((cfg.bit_rate < 4000) || (cfg.bit_rate > 192000)) {
 			pr_err("%s: ERROR in setting bitrate = %d\n",
 				__func__, cfg.bit_rate);
 			rc = -EINVAL;
diff --git a/arch/arm/mach-msm/restart.c b/arch/arm/mach-msm/restart.c
index 28bf064..06e3d37 100644
--- a/arch/arm/mach-msm/restart.c
+++ b/arch/arm/mach-msm/restart.c
@@ -122,9 +122,6 @@
 #endif
 	pm8xxx_reset_pwr_off(0);
 
-	if (cpu_is_msm8x60())
-		pm8901_reset_pwr_off(0);
-
 	if (lower_pshold) {
 		__raw_writel(0, PSHOLD_CTL_SU);
 		mdelay(10000);
diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
index 19f7290..6794a88 100644
--- a/arch/arm/mach-msm/scm.c
+++ b/arch/arm/mach-msm/scm.c
@@ -282,7 +282,7 @@
  * This shall only be used with commands that are guaranteed to be
  * uninterruptable, atomic and SMP safe.
  */
-u32 scm_call_atomic1(u32 svc, u32 cmd, u32 arg1)
+s32 scm_call_atomic1(u32 svc, u32 cmd, u32 arg1)
 {
 	int context_id;
 	register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 1);
@@ -312,7 +312,7 @@
  * This shall only be used with commands that are guaranteed to be
  * uninterruptable, atomic and SMP safe.
  */
-u32 scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2)
+s32 scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2)
 {
 	int context_id;
 	register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 2);
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 90a1c7e..7e61e8b 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -939,15 +939,17 @@
  * Store the most recent timestamp read from hardware
  * in last_ns. This is useful for debugging crashes.
  */
-static u64 last_ns;
+static atomic64_t last_ns;
 
 unsigned long long notrace sched_clock(void)
 {
 	struct msm_clock *clock = &msm_clocks[msm_global_timer];
 	struct clocksource *cs = &clock->clocksource;
-	u32 cyc = cs->read(cs);
-	last_ns = cyc_to_sched_clock(&cd, cyc, ((u32)~0 >> clock->shift));
-	return last_ns;
+	u64 cyc = cs->read(cs);
+	u64 last_ns_local;
+	last_ns_local = cyc_to_sched_clock(&cd, cyc, ((u32)~0 >> clock->shift));
+	atomic64_set(&last_ns, last_ns_local);
+	return last_ns_local;
 }
 
 static void notrace msm_update_sched_clock(void)
diff --git a/arch/arm/mach-msm/wcnss-ssr-8960.c b/arch/arm/mach-msm/wcnss-ssr-8960.c
index af92d22..07a9241 100644
--- a/arch/arm/mach-msm/wcnss-ssr-8960.c
+++ b/arch/arm/mach-msm/wcnss-ssr-8960.c
@@ -59,14 +59,33 @@
 						MODULE_NAME);
 		return;
 	}
-	if (new_state & SMSM_RESET)
+	if (new_state & SMSM_RESET) {
+		ss_restart_inprogress = true;
 		schedule_work(&riva_smsm_cb_work);
+	}
 }
 
 static void riva_fatal_fn(struct work_struct *work)
 {
-	if (!ss_restart_inprogress)
+	if (!enable_riva_ssr)
 		panic(MODULE_NAME ": Watchdog bite received from Riva");
+	else
+		subsystem_restart("riva");
+}
+
+static irqreturn_t riva_wdog_bite_irq_hdlr(int irq, void *dev_id)
+{
+	int ret;
+
+	if (ss_restart_inprogress) {
+		pr_err("%s: Ignoring riva bite irq, restart in progress\n",
+						MODULE_NAME);
+		return IRQ_HANDLED;
+	}
+	disable_irq_nosync(RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ);
+	ss_restart_inprogress = true;
+	ret = schedule_work(&riva_fatal_work);
+	return IRQ_HANDLED;
 }
 
 /* SMSM reset Riva */
@@ -106,6 +125,9 @@
 	if (!ret)
 		pil_force_boot("wcnss");
 
+	ss_restart_inprogress = false;
+	enable_irq(RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ);
+
 	return ret;
 }
 
@@ -128,8 +150,6 @@
 /* Riva crash handler */
 static void riva_crash_shutdown(const struct subsys_data *subsys)
 {
-	ss_restart_inprogress = true;
-
 	pr_err("%s: crash shutdown : %d\n", MODULE_NAME, riva_crash);
 	if (riva_crash != true)
 		smsm_riva_reset();
@@ -176,6 +196,15 @@
 				" (%d)\n", MODULE_NAME, ret);
 		goto out;
 	}
+	ret = request_irq(RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ,
+			riva_wdog_bite_irq_hdlr, IRQF_TRIGGER_HIGH,
+				"riva_wdog", NULL);
+
+	if (ret < 0) {
+		pr_err("%s: Unable to register for Riva bite interrupt"
+				" (%d)\n", MODULE_NAME, ret);
+		goto out;
+	}
 	ret = riva_restart_init();
 	if (ret < 0) {
 		pr_err("%s: Unable to register with ssr. (%d)\n",
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index e5e3486..db80bd3 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -491,6 +491,17 @@
 	return pages;
 }
 
+/*
+ * Poison init memory with an undefined instruction (ARM) or a branch to an
+ * undefined instruction (Thumb).
+ */
+static inline void poison_init_mem(void *s, size_t count)
+{
+	u32 *p = (u32 *)s;
+	for (; count != 0; count -= 4)
+		*p++ = 0xe7fddef0;
+}
+
 static inline void
 free_memmap(unsigned long start_pfn, unsigned long end_pfn)
 {
@@ -799,12 +810,14 @@
 #ifdef CONFIG_HAVE_TCM
 	extern char __tcm_start, __tcm_end;
 
+	poison_init_mem(&__tcm_start, &__tcm_end - &__tcm_start);
 	totalram_pages += free_area(__phys_to_pfn(__pa(&__tcm_start)),
 				    __phys_to_pfn(__pa(&__tcm_end)),
 				    "TCM link");
 #endif
 
 	if (!machine_is_integrator() && !machine_is_cintegrator()) {
+		poison_init_mem(__init_begin, __init_end - __init_begin);
 		reclaimed_initmem = free_area(__phys_to_pfn(__pa(__init_begin)),
 					    __phys_to_pfn(__pa(__init_end)),
 					    "init");
@@ -850,6 +863,7 @@
 {
 	unsigned long reclaimed_initrd_mem;
 	if (!keep_initrd) {
+		poison_init_mem((void *)start, PAGE_ALIGN(end) - start);
 		reclaimed_initrd_mem = free_area(__phys_to_pfn(__pa(start)),
 					    __phys_to_pfn(__pa(end)),
 					    "initrd");
diff --git a/drivers/media/video/msm/Kconfig b/drivers/media/video/msm/Kconfig
index 0d822bb..aa0e392 100644
--- a/drivers/media/video/msm/Kconfig
+++ b/drivers/media/video/msm/Kconfig
@@ -49,6 +49,11 @@
 	default n
 	---help---
 	  Omni Vision VGA YUV Sensor for QRD Devices
+config MT9M114
+        bool "Sensor MT9M114 (YUV 1.26M)"
+        depends on MSM_CAMERA && ARCH_MSM8960
+        ---help---
+        APTINA 1.26 MP yuv Sensor
 config WEBCAM_OV7692
 	bool "Sensor OV7692 (VGA YUV)"
 	depends on MSM_CAMERA && ARCH_MSM8X60 && !MSM_CAMERA_V4L2
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.c b/drivers/media/video/msm/io/msm_camera_i2c.c
index 23db5f6b..a3cc012 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c.c
+++ b/drivers/media/video/msm/io/msm_camera_i2c.c
@@ -250,42 +250,52 @@
 	int32_t rc = -EFAULT;
 	for (i = 0; i < size; i++) {
 		enum msm_camera_i2c_data_type dt;
-		if (reg_conf_tbl->dt == 0)
-			dt = data_type;
-		else
-			dt = reg_conf_tbl->dt;
+		if (reg_conf_tbl->cmd_type == MSM_CAMERA_I2C_CMD_POLL) {
+			rc = msm_camera_i2c_poll(client, reg_conf_tbl->reg_addr,
+				reg_conf_tbl->reg_addr, reg_conf_tbl->dt);
+		} else {
+			if (reg_conf_tbl->dt == 0)
+				dt = data_type;
+			else
+				dt = reg_conf_tbl->dt;
 
-		switch (dt) {
-		case MSM_CAMERA_I2C_BYTE_DATA:
-		case MSM_CAMERA_I2C_WORD_DATA:
-			rc = msm_camera_i2c_write(
-				client,
-				reg_conf_tbl->reg_addr,
-				reg_conf_tbl->reg_data, dt);
-			break;
-		case MSM_CAMERA_I2C_SET_BYTE_MASK:
-			rc = msm_camera_i2c_set_mask(client,
-				reg_conf_tbl->reg_addr, reg_conf_tbl->reg_data,
-				MSM_CAMERA_I2C_BYTE_DATA, 1);
-			break;
-		case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
-			rc = msm_camera_i2c_set_mask(client,
-				reg_conf_tbl->reg_addr, reg_conf_tbl->reg_data,
-				MSM_CAMERA_I2C_BYTE_DATA, 0);
-			break;
-		case MSM_CAMERA_I2C_SET_WORD_MASK:
-			rc = msm_camera_i2c_set_mask(client,
-				reg_conf_tbl->reg_addr, reg_conf_tbl->reg_data,
-				MSM_CAMERA_I2C_WORD_DATA, 1);
-			break;
-		case MSM_CAMERA_I2C_UNSET_WORD_MASK:
-			rc = msm_camera_i2c_set_mask(client,
-				reg_conf_tbl->reg_addr, reg_conf_tbl->reg_data,
-				MSM_CAMERA_I2C_WORD_DATA, 0);
-			break;
-		default:
-			pr_err("%s: Unsupport data type: %d\n", __func__, dt);
-			break;
+			switch (dt) {
+			case MSM_CAMERA_I2C_BYTE_DATA:
+			case MSM_CAMERA_I2C_WORD_DATA:
+				rc = msm_camera_i2c_write(
+					client,
+					reg_conf_tbl->reg_addr,
+					reg_conf_tbl->reg_data, dt);
+				break;
+			case MSM_CAMERA_I2C_SET_BYTE_MASK:
+				rc = msm_camera_i2c_set_mask(client,
+					reg_conf_tbl->reg_addr,
+					reg_conf_tbl->reg_data,
+					MSM_CAMERA_I2C_BYTE_DATA, 1);
+				break;
+			case MSM_CAMERA_I2C_UNSET_BYTE_MASK:
+				rc = msm_camera_i2c_set_mask(client,
+					reg_conf_tbl->reg_addr,
+					reg_conf_tbl->reg_data,
+					MSM_CAMERA_I2C_BYTE_DATA, 0);
+				break;
+			case MSM_CAMERA_I2C_SET_WORD_MASK:
+				rc = msm_camera_i2c_set_mask(client,
+					reg_conf_tbl->reg_addr,
+					reg_conf_tbl->reg_data,
+					MSM_CAMERA_I2C_WORD_DATA, 1);
+				break;
+			case MSM_CAMERA_I2C_UNSET_WORD_MASK:
+				rc = msm_camera_i2c_set_mask(client,
+					reg_conf_tbl->reg_addr,
+					reg_conf_tbl->reg_data,
+					MSM_CAMERA_I2C_WORD_DATA, 0);
+				break;
+			default:
+				pr_err("%s: Unsupport data type: %d\n",
+					__func__, dt);
+				break;
+			}
 		}
 		if (rc < 0)
 			break;
@@ -364,16 +374,10 @@
 			struct msm_camera_i2c_conf_array *array, uint16_t index)
 {
 	int32_t rc;
-	if (array[index].pre_process != NULL)
-		array[index].pre_process();
 
 	rc = msm_camera_i2c_write_tbl(client,
 		(struct msm_camera_i2c_reg_conf *) array[index].conf,
 		array[index].size, array[index].data_type);
-
-	if (array[index].post_process != NULL)
-		array[index].post_process();
-
 	if (array[index].delay > 20)
 		msleep(array[index].delay);
 	else
@@ -382,6 +386,34 @@
 	return rc;
 }
 
+int32_t msm_sensor_write_enum_conf_array(struct msm_camera_i2c_client *client,
+			struct msm_camera_i2c_enum_conf_array *conf,
+			uint16_t enum_val)
+{
+	int32_t rc = -1, i;
+	for (i = 0; i < conf->num_enum; i++) {
+		if (conf->conf_enum[i] == enum_val)
+			break;
+		if (conf->conf_enum[i] > enum_val)
+			break;
+	}
+	if (i == conf->num_enum)
+		i = conf->num_enum - 1;
+
+	if (i >= conf->num_index)
+		return rc;
+
+	rc = msm_sensor_write_all_conf_array(client,
+		&conf->conf[i*conf->num_conf], conf->num_conf);
+
+	if (conf->delay > 20)
+		msleep(conf->delay);
+	else
+		usleep_range(conf->delay*1000,
+					(conf->delay+1)*1000);
+	return rc;
+}
+
 int32_t msm_sensor_write_all_conf_array(struct msm_camera_i2c_client *client,
 			struct msm_camera_i2c_conf_array *array, uint16_t size)
 {
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.h b/drivers/media/video/msm/io/msm_camera_i2c.h
index 05b3960..2fbf5ca 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c.h
+++ b/drivers/media/video/msm/io/msm_camera_i2c.h
@@ -44,10 +44,16 @@
 	MSM_CAMERA_I2C_UNSET_WORD_MASK,
 };
 
+enum msm_camera_i2c_cmd_type {
+	MSM_CAMERA_I2C_CMD_WRITE,
+	MSM_CAMERA_I2C_CMD_POLL,
+};
+
 struct msm_camera_i2c_reg_conf {
 	uint16_t reg_addr;
 	uint16_t reg_data;
 	enum msm_camera_i2c_data_type dt;
+	enum msm_camera_i2c_cmd_type cmd_type;
 };
 
 struct msm_camera_i2c_conf_array {
@@ -55,8 +61,16 @@
 	uint16_t size;
 	uint16_t delay;
 	enum msm_camera_i2c_data_type data_type;
-	int (*pre_process) (void);
-	int (*post_process) (void);
+};
+
+struct msm_camera_i2c_enum_conf_array {
+	struct msm_camera_i2c_conf_array *conf;
+	int *conf_enum;
+	uint16_t num_enum;
+	uint16_t num_index;
+	uint16_t num_conf;
+	uint16_t delay;
+	enum msm_camera_i2c_data_type data_type;
 };
 
 int32_t msm_camera_i2c_rxdata(struct msm_camera_i2c_client *client,
@@ -98,6 +112,9 @@
 int32_t msm_sensor_write_conf_array(struct msm_camera_i2c_client *client,
 	struct msm_camera_i2c_conf_array *array, uint16_t index);
 
+int32_t msm_sensor_write_enum_conf_array(struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_enum_conf_array *conf, uint16_t enum_val);
+
 int32_t msm_sensor_write_all_conf_array(struct msm_camera_i2c_client *client,
 	struct msm_camera_i2c_conf_array *array, uint16_t size);
 #endif
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 251f12d..579c4d5 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -2407,6 +2407,7 @@
 	adapter = NULL;
 probe_fail:
 	actctrl->a_init_table = NULL;
+	actctrl->a_power_up = NULL;
 	actctrl->a_power_down = NULL;
 	actctrl->a_config = NULL;
 	actctrl->a_create_subdevice = NULL;
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index 73fd383..689a614 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -261,6 +261,45 @@
 			rc = p_mctl->sync.sctrl.s_config(argp);
 			break;
 
+	case MSM_CAM_IOCTL_SENSOR_V4l2_S_CTRL: {
+			struct v4l2_control v4l2_ctrl;
+			CDBG("subdev call\n");
+			if (copy_from_user(&v4l2_ctrl,
+				(void *)argp,
+				sizeof(struct v4l2_control))) {
+				CDBG("copy fail\n");
+				return -EFAULT;
+			}
+			CDBG("subdev call ok\n");
+			rc = v4l2_subdev_call(p_mctl->sensor_sdev,
+				core, s_ctrl, &v4l2_ctrl);
+			break;
+	}
+
+	case MSM_CAM_IOCTL_SENSOR_V4l2_QUERY_CTRL: {
+			struct v4l2_queryctrl v4l2_qctrl;
+			CDBG("query called\n");
+			if (copy_from_user(&v4l2_qctrl,
+				(void *)argp,
+				sizeof(struct v4l2_queryctrl))) {
+				CDBG("copy fail\n");
+				rc = -EFAULT;
+				break;
+			}
+			rc = v4l2_subdev_call(p_mctl->sensor_sdev,
+				core, queryctrl, &v4l2_qctrl);
+			if (rc < 0) {
+				rc = -EFAULT;
+				break;
+			}
+			if (copy_to_user((void *)argp,
+					 &v4l2_qctrl,
+					 sizeof(struct v4l2_queryctrl))) {
+				rc = -EFAULT;
+			}
+			break;
+	}
+
 	case MSM_CAM_IOCTL_ACTUATOR_IO_CFG: {
 		struct msm_actuator_cfg_data act_data;
 		if (p_mctl->sync.actctrl.a_config) {
@@ -504,6 +543,15 @@
 			goto msm_open_done;
 		}
 
+		if (sync->actctrl.a_power_up)
+			rc = sync->actctrl.a_power_up(
+				sync->sdata->actuator_info);
+
+		if (rc < 0) {
+			pr_err("%s: act power failed:%d\n", __func__, rc);
+			goto msm_open_done;
+		}
+
 		pm_qos_add_request(&p_mctl->pm_qos_req_list,
 					PM_QOS_CPU_DMA_LATENCY,
 					PM_QOS_DEFAULT_VALUE);
@@ -537,7 +585,7 @@
 		VIDIOC_MSM_CSIPHY_RELEASE, NULL);
 
 	if (p_mctl->sync.actctrl.a_power_down)
-		p_mctl->sync.actctrl.a_power_down();
+		p_mctl->sync.actctrl.a_power_down(sync->sdata->actuator_info);
 
 	if (p_mctl->sync.sctrl.s_release)
 		p_mctl->sync.sctrl.s_release();
diff --git a/drivers/media/video/msm/sensors/Makefile b/drivers/media/video/msm/sensors/Makefile
index 3e42126..7b22592 100644
--- a/drivers/media/video/msm/sensors/Makefile
+++ b/drivers/media/video/msm/sensors/Makefile
@@ -4,4 +4,5 @@
 EXTRA_CFLAGS += -Idrivers/media/video/msm/csi
 obj-$(CONFIG_MSM_CAMERA_SENSOR) += msm_sensor.o
 obj-$(CONFIG_IMX074) += imx074_v4l2.o
+obj-$(CONFIG_MT9M114) += mt9m114_v4l2.o
 obj-$(CONFIG_OV2720) += ov2720.o
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 7eb3160..e67f9cd 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -578,6 +578,74 @@
 	return 0;
 }
 
+int32_t msm_sensor_v4l2_s_ctrl(struct v4l2_subdev *sd,
+	struct v4l2_control *ctrl)
+{
+	int rc = -1, i = 0;
+	struct msm_sensor_ctrl_t *s_ctrl =
+		(struct msm_sensor_ctrl_t *) sd->dev_priv;
+	struct msm_sensor_v4l2_ctrl_info_t *v4l2_ctrl =
+		s_ctrl->msm_sensor_v4l2_ctrl_info;
+
+	CDBG("%s\n", __func__);
+	CDBG("%d\n", ctrl->id);
+	if (v4l2_ctrl == NULL)
+		return rc;
+
+	for (i = 0; i < s_ctrl->num_v4l2_ctrl; i++) {
+		if (v4l2_ctrl[i].ctrl_id == ctrl->id) {
+			if (v4l2_ctrl[i].s_v4l2_ctrl != NULL) {
+				rc = v4l2_ctrl[i].s_v4l2_ctrl(
+					s_ctrl,
+					&s_ctrl->msm_sensor_v4l2_ctrl_info[i],
+					ctrl->value);
+			}
+			break;
+		}
+	}
+
+	return rc;
+}
+
+int32_t msm_sensor_v4l2_query_ctrl(
+	struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
+{
+	int rc = -1, i = 0;
+	struct msm_sensor_ctrl_t *s_ctrl =
+		(struct msm_sensor_ctrl_t *) sd->dev_priv;
+
+	CDBG("%s\n", __func__);
+	CDBG("%s id: %d\n", __func__, qctrl->id);
+
+	if (s_ctrl->msm_sensor_v4l2_ctrl_info == NULL)
+		return rc;
+
+	for (i = 0; i < s_ctrl->num_v4l2_ctrl; i++) {
+		if (s_ctrl->msm_sensor_v4l2_ctrl_info[i].ctrl_id == qctrl->id) {
+			qctrl->minimum =
+				s_ctrl->msm_sensor_v4l2_ctrl_info[i].min;
+			qctrl->maximum =
+				s_ctrl->msm_sensor_v4l2_ctrl_info[i].max;
+			qctrl->flags = 1;
+			rc = 0;
+			break;
+		}
+	}
+
+	return rc;
+}
+
+int msm_sensor_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
+		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
+{
+	int rc = 0;
+	CDBG("%s enter\n", __func__);
+	rc = msm_sensor_write_enum_conf_array(
+		s_ctrl->sensor_i2c_client,
+		ctrl_info->enum_cfg_settings, value);
+	return rc;
+}
+
 static int msm_sensor_debugfs_stream_s(void *data, u64 val)
 {
 	struct msm_sensor_ctrl_t *s_ctrl = (struct msm_sensor_ctrl_t *) data;
diff --git a/drivers/media/video/msm/sensors/msm_sensor.h b/drivers/media/video/msm/sensors/msm_sensor.h
index e4dc34f..f1a15b2 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.h
+++ b/drivers/media/video/msm/sensors/msm_sensor.h
@@ -93,6 +93,17 @@
 };
 
 struct msm_sensor_ctrl_t;
+
+struct msm_sensor_v4l2_ctrl_info_t {
+	uint32_t ctrl_id;
+	int16_t min;
+	int16_t max;
+	int16_t step;
+	struct msm_camera_i2c_enum_conf_array *enum_cfg_settings;
+	int (*s_v4l2_ctrl) (struct msm_sensor_ctrl_t *,
+		struct msm_sensor_v4l2_ctrl_info_t *, int);
+};
+
 struct msm_sensor_fn_t {
 	void (*sensor_start_stream) (struct msm_sensor_ctrl_t *);
 	void (*sensor_stop_stream) (struct msm_sensor_ctrl_t *);
@@ -137,6 +148,8 @@
 	struct msm_sensor_id_info_t *sensor_id_info;
 	struct msm_sensor_exp_gain_info_t *sensor_exp_gain_info;
 	struct msm_sensor_reg_t *msm_sensor_reg;
+	struct msm_sensor_v4l2_ctrl_info_t *msm_sensor_v4l2_ctrl_info;
+	uint16_t num_v4l2_ctrl;
 
 	uint16_t curr_line_length_pclk;
 	uint16_t curr_frame_length_lines;
@@ -192,6 +205,18 @@
 	const struct msm_camera_sensor_info *info,
 	struct v4l2_subdev *sdev, struct msm_sensor_ctrl *s);
 
+int32_t msm_sensor_v4l2_s_ctrl(struct v4l2_subdev *sd,
+	struct v4l2_control *ctrl);
+
+int32_t msm_sensor_v4l2_query_ctrl(
+	struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl);
+
+int msm_sensor_s_ctrl_by_index(struct msm_sensor_ctrl_t *s_ctrl,
+	struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value);
+
+int msm_sensor_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
+		struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value);
+
 int msm_sensor_v4l2_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
 			enum v4l2_mbus_pixelcode *code);
 
diff --git a/drivers/media/video/msm/sensors/mt9m114_v4l2.c b/drivers/media/video/msm/sensors/mt9m114_v4l2.c
new file mode 100644
index 0000000..fc45705
--- /dev/null
+++ b/drivers/media/video/msm/sensors/mt9m114_v4l2.c
@@ -0,0 +1,1340 @@
+/* Copyright (c) 2011, 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 "mt9m114"
+#define PLATFORM_DRIVER_NAME "msm_camera_mt9m114"
+#define mt9m114_obj mt9m114_##obj
+
+/* Sysctl registers */
+#define MT9M114_COMMAND_REGISTER                0x0080
+#define MT9M114_COMMAND_REGISTER_APPLY_PATCH    (1 << 0)
+#define MT9M114_COMMAND_REGISTER_SET_STATE      (1 << 1)
+#define MT9M114_COMMAND_REGISTER_REFRESH        (1 << 2)
+#define MT9M114_COMMAND_REGISTER_WAIT_FOR_EVENT (1 << 3)
+#define MT9M114_COMMAND_REGISTER_OK             (1 << 15)
+
+DEFINE_MUTEX(mt9m114_mut);
+static struct msm_sensor_ctrl_t mt9m114_s_ctrl;
+
+static struct msm_camera_i2c_reg_conf mt9m114_720p_settings[] = {
+	{0xdc00, 0x50, MSM_CAMERA_I2C_BYTE_DATA, MSM_CAMERA_I2C_CMD_WRITE},
+	{MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_SET_STATE,
+		MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+	{MT9M114_COMMAND_REGISTER, (MT9M114_COMMAND_REGISTER_OK |
+		MT9M114_COMMAND_REGISTER_SET_STATE), MSM_CAMERA_I2C_WORD_DATA,
+		MSM_CAMERA_I2C_CMD_WRITE},
+	{MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_SET_STATE,
+		MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+	{0xDC01, 0x52, MSM_CAMERA_I2C_BYTE_DATA, MSM_CAMERA_I2C_CMD_POLL},
+
+	{0x098E, 0, MSM_CAMERA_I2C_BYTE_DATA},
+	{0xC800, 0x007C,},/*y_addr_start = 124*/
+	{0xC802, 0x0004,},/*x_addr_start = 4*/
+	{0xC804, 0x0353,},/*y_addr_end = 851*/
+	{0xC806, 0x050B,},/*x_addr_end = 1291*/
+	{0xC808, 0x02DC,},/*pixclk = 48000000*/
+	{0xC80A, 0x6C00,},/*pixclk = 48000000*/
+	{0xC80C, 0x0001,},/*row_speed = 1*/
+	{0xC80E, 0x00DB,},/*fine_integ_time_min = 219*/
+	{0xC810, 0x05BD,},/*fine_integ_time_max = 1469*/
+	{0xC812, 0x03E8,},/*frame_length_lines = 1000*/
+	{0xC814, 0x0640,},/*line_length_pck = 1600*/
+	{0xC816, 0x0060,},/*fine_correction = 96*/
+	{0xC818, 0x02D3,},/*cpipe_last_row = 723*/
+	{0xC826, 0x0020,},/*reg_0_data = 32*/
+	{0xC834, 0x0000,},/*sensor_control_read_mode = 0*/
+	{0xC854, 0x0000,},/*crop_window_xoffset = 0*/
+	{0xC856, 0x0000,},/*crop_window_yoffset = 0*/
+	{0xC858, 0x0500,},/*crop_window_width = 1280*/
+	{0xC85A, 0x02D0,},/*crop_window_height = 720*/
+	{0xC85C, 0x03, MSM_CAMERA_I2C_BYTE_DATA},  /*crop_cropmode = 3*/
+	{0xC868, 0x0500,},/*output_width = 1280*/
+	{0xC86A, 0x02D0,},/*output_height = 720*/
+	{0xC878, 0x00, MSM_CAMERA_I2C_BYTE_DATA},  /*aet_aemode = 0*/
+	{0xC88C, 0x1E00,},/*aet_max_frame_rate = 7680*/
+	{0xC88E, 0x1E00,},/*aet_min_frame_rate = 7680*/
+	{0xC914, 0x0000,},/*stat_awb_window_xstart = 0*/
+	{0xC916, 0x0000,},/*stat_awb_window_ystart = 0*/
+	{0xC918, 0x04FF,},/*stat_awb_window_xend = 1279*/
+	{0xC91A, 0x02CF,},/*stat_awb_window_yend = 719*/
+	{0xC91C, 0x0000,},/*stat_ae_window_xstart = 0*/
+	{0xC91E, 0x0000,},/*stat_ae_window_ystart = 0*/
+	{0xC920, 0x00FF,},/*stat_ae_window_xend = 255*/
+	{0xC922, 0x008F,},/*stat_ae_window_yend = 143*/
+};
+
+static struct msm_camera_i2c_reg_conf mt9m114_recommend_settings[] = {
+	{0x301A, 0x0200, MSM_CAMERA_I2C_SET_WORD_MASK},
+	{0x098E, 0, MSM_CAMERA_I2C_BYTE_DATA},
+	/*cam_sysctl_pll_enable = 1*/
+	{0xC97E, 0x01, MSM_CAMERA_I2C_BYTE_DATA},
+	/*cam_sysctl_pll_divider_m_n = 288*/
+	{0xC980, 0x0120,},
+	/*cam_sysctl_pll_divider_p = 1792*/
+	{0xC982, 0x0700,},
+	/*output_control = 32769*/
+	{0xC984, 0x8001,},
+	/*mipi_timing_t_hs_zero = 3840*/
+	{0xC988, 0x0F00,},
+	/*mipi_timing_t_hs_exit_hs_trail = 2823*/
+	{0xC98A, 0x0B07,},
+	/*mipi_timing_t_clk_post_clk_pre = 3329*/
+	{0xC98C, 0x0D01,},
+	/*mipi_timing_t_clk_trail_clk_zero = 1821*/
+	{0xC98E, 0x071D,},
+	/*mipi_timing_t_lpx = 6*/
+	{0xC990, 0x0006,},
+	/*mipi_timing_init_timing = 2572*/
+	{0xC992, 0x0A0C,},
+	{0xC800, 0x007C,},/*y_addr_start = 124*/
+	{0xC802, 0x0004,},/*x_addr_start = 4*/
+	{0xC804, 0x0353,},/*y_addr_end = 851*/
+	{0xC806, 0x050B,},/*x_addr_end = 1291*/
+	{0xC808, 0x02DC,},/*pixclk = 48000000*/
+	{0xC80A, 0x6C00,},/*pixclk = 48000000*/
+	{0xC80C, 0x0001,},/*row_speed = 1*/
+	{0xC80E, 0x00DB,},/*fine_integ_time_min = 219*/
+	{0xC810, 0x05BD,},/*fine_integ_time_max = 1469*/
+	{0xC812, 0x03E8,},/*frame_length_lines = 1000*/
+	{0xC814, 0x0640,},/*line_length_pck = 1600*/
+	{0xC816, 0x0060,},/*fine_correction = 96*/
+	{0xC818, 0x02D3,},/*cpipe_last_row = 723*/
+	{0xC826, 0x0020,},/*reg_0_data = 32*/
+	{0xC834, 0x0000,},/*sensor_control_read_mode = 0*/
+	{0xC854, 0x0000,},/*crop_window_xoffset = 0*/
+	{0xC856, 0x0000,},/*crop_window_yoffset = 0*/
+	{0xC858, 0x0500,},/*crop_window_width = 1280*/
+	{0xC85A, 0x02D0,},/*crop_window_height = 720*/
+	{0xC85C, 0x03, MSM_CAMERA_I2C_BYTE_DATA},  /*crop_cropmode = 3*/
+	{0xC868, 0x0500,},/*output_width = 1280*/
+	{0xC86A, 0x02D0,},/*output_height = 720*/
+	{0xC878, 0x00, MSM_CAMERA_I2C_BYTE_DATA},  /*aet_aemode = 0*/
+	{0xC88C, 0x1E00,},/*aet_max_frame_rate = 7680*/
+	{0xC88E, 0x1E00,},/*aet_min_frame_rate = 7680*/
+	{0xC914, 0x0000,},/*stat_awb_window_xstart = 0*/
+	{0xC916, 0x0000,},/*stat_awb_window_ystart = 0*/
+	{0xC918, 0x04FF,},/*stat_awb_window_xend = 1279*/
+	{0xC91A, 0x02CF,},/*stat_awb_window_yend = 719*/
+	{0xC91C, 0x0000,},/*stat_ae_window_xstart = 0*/
+	{0xC91E, 0x0000,},/*stat_ae_window_ystart = 0*/
+	{0xC920, 0x00FF,},/*stat_ae_window_xend = 255*/
+	{0xC922, 0x008F,},/*stat_ae_window_yend = 143*/
+
+	/*Sensor optimization*/
+	{0x316A, 0x8270,},
+	{0x316C, 0x8270,},
+	{0x3ED0, 0x2305,},
+	{0x3ED2, 0x77CF,},
+	{0x316E, 0x8202,},
+	{0x3180, 0x87FF,},
+	{0x30D4, 0x6080,},
+	{0xA802, 0x0008,},/*AE_TRACK_MODE*/
+	{0x3E14, 0xFF39,},
+	{0x0982, 0x0001,},/*ACCESS_CTL_STAT*/
+	{0x098A, 0x5000,},/*PHYSICAL_ADDRESS_ACCESS*/
+	{0xD000, 0x70CF,},
+	{0xD002, 0xFFFF,},
+	{0xD004, 0xC5D4,},
+	{0xD006, 0x903A,},
+	{0xD008, 0x2144,},
+	{0xD00A, 0x0C00,},
+	{0xD00C, 0x2186,},
+	{0xD00E, 0x0FF3,},
+	{0xD010, 0xB844,},
+	{0xD012, 0xB948,},
+	{0xD014, 0xE082,},
+	{0xD016, 0x20CC,},
+	{0xD018, 0x80E2,},
+	{0xD01A, 0x21CC,},
+	{0xD01C, 0x80A2,},
+	{0xD01E, 0x21CC,},
+	{0xD020, 0x80E2,},
+	{0xD022, 0xF404,},
+	{0xD024, 0xD801,},
+	{0xD026, 0xF003,},
+	{0xD028, 0xD800,},
+	{0xD02A, 0x7EE0,},
+	{0xD02C, 0xC0F1,},
+	{0xD02E, 0x08BA,},
+	{0xD030, 0x0600,},
+	{0xD032, 0xC1A1,},
+	{0xD034, 0x76CF,},
+	{0xD036, 0xFFFF,},
+	{0xD038, 0xC130,},
+	{0xD03A, 0x6E04,},
+	{0xD03C, 0xC040,},
+	{0xD03E, 0x71CF,},
+	{0xD040, 0xFFFF,},
+	{0xD042, 0xC790,},
+	{0xD044, 0x8103,},
+	{0xD046, 0x77CF,},
+	{0xD048, 0xFFFF,},
+	{0xD04A, 0xC7C0,},
+	{0xD04C, 0xE001,},
+	{0xD04E, 0xA103,},
+	{0xD050, 0xD800,},
+	{0xD052, 0x0C6A,},
+	{0xD054, 0x04E0,},
+	{0xD056, 0xB89E,},
+	{0xD058, 0x7508,},
+	{0xD05A, 0x8E1C,},
+	{0xD05C, 0x0809,},
+	{0xD05E, 0x0191,},
+	{0xD060, 0xD801,},
+	{0xD062, 0xAE1D,},
+	{0xD064, 0xE580,},
+	{0xD066, 0x20CA,},
+	{0xD068, 0x0022,},
+	{0xD06A, 0x20CF,},
+	{0xD06C, 0x0522,},
+	{0xD06E, 0x0C5C,},
+	{0xD070, 0x04E2,},
+	{0xD072, 0x21CA,},
+	{0xD074, 0x0062,},
+	{0xD076, 0xE580,},
+	{0xD078, 0xD901,},
+	{0xD07A, 0x79C0,},
+	{0xD07C, 0xD800,},
+	{0xD07E, 0x0BE6,},
+	{0xD080, 0x04E0,},
+	{0xD082, 0xB89E,},
+	{0xD084, 0x70CF,},
+	{0xD086, 0xFFFF,},
+	{0xD088, 0xC8D4,},
+	{0xD08A, 0x9002,},
+	{0xD08C, 0x0857,},
+	{0xD08E, 0x025E,},
+	{0xD090, 0xFFDC,},
+	{0xD092, 0xE080,},
+	{0xD094, 0x25CC,},
+	{0xD096, 0x9022,},
+	{0xD098, 0xF225,},
+	{0xD09A, 0x1700,},
+	{0xD09C, 0x108A,},
+	{0xD09E, 0x73CF,},
+	{0xD0A0, 0xFF00,},
+	{0xD0A2, 0x3174,},
+	{0xD0A4, 0x9307,},
+	{0xD0A6, 0x2A04,},
+	{0xD0A8, 0x103E,},
+	{0xD0AA, 0x9328,},
+	{0xD0AC, 0x2942,},
+	{0xD0AE, 0x7140,},
+	{0xD0B0, 0x2A04,},
+	{0xD0B2, 0x107E,},
+	{0xD0B4, 0x9349,},
+	{0xD0B6, 0x2942,},
+	{0xD0B8, 0x7141,},
+	{0xD0BA, 0x2A04,},
+	{0xD0BC, 0x10BE,},
+	{0xD0BE, 0x934A,},
+	{0xD0C0, 0x2942,},
+	{0xD0C2, 0x714B,},
+	{0xD0C4, 0x2A04,},
+	{0xD0C6, 0x10BE,},
+	{0xD0C8, 0x130C,},
+	{0xD0CA, 0x010A,},
+	{0xD0CC, 0x2942,},
+	{0xD0CE, 0x7142,},
+	{0xD0D0, 0x2250,},
+	{0xD0D2, 0x13CA,},
+	{0xD0D4, 0x1B0C,},
+	{0xD0D6, 0x0284,},
+	{0xD0D8, 0xB307,},
+	{0xD0DA, 0xB328,},
+	{0xD0DC, 0x1B12,},
+	{0xD0DE, 0x02C4,},
+	{0xD0E0, 0xB34A,},
+	{0xD0E2, 0xED88,},
+	{0xD0E4, 0x71CF,},
+	{0xD0E6, 0xFF00,},
+	{0xD0E8, 0x3174,},
+	{0xD0EA, 0x9106,},
+	{0xD0EC, 0xB88F,},
+	{0xD0EE, 0xB106,},
+	{0xD0F0, 0x210A,},
+	{0xD0F2, 0x8340,},
+	{0xD0F4, 0xC000,},
+	{0xD0F6, 0x21CA,},
+	{0xD0F8, 0x0062,},
+	{0xD0FA, 0x20F0,},
+	{0xD0FC, 0x0040,},
+	{0xD0FE, 0x0B02,},
+	{0xD100, 0x0320,},
+	{0xD102, 0xD901,},
+	{0xD104, 0x07F1,},
+	{0xD106, 0x05E0,},
+	{0xD108, 0xC0A1,},
+	{0xD10A, 0x78E0,},
+	{0xD10C, 0xC0F1,},
+	{0xD10E, 0x71CF,},
+	{0xD110, 0xFFFF,},
+	{0xD112, 0xC7C0,},
+	{0xD114, 0xD840,},
+	{0xD116, 0xA900,},
+	{0xD118, 0x71CF,},
+	{0xD11A, 0xFFFF,},
+	{0xD11C, 0xD02C,},
+	{0xD11E, 0xD81E,},
+	{0xD120, 0x0A5A,},
+	{0xD122, 0x04E0,},
+	{0xD124, 0xDA00,},
+	{0xD126, 0xD800,},
+	{0xD128, 0xC0D1,},
+	{0xD12A, 0x7EE0,},
+	{0x098E, 0x0000,},
+
+	{0x0982, 0x0001,},
+	{0x098A, 0x5C10,},
+	{0xDC10, 0xC0F1,},
+	{0xDC12, 0x0CDA,},
+	{0xDC14, 0x0580,},
+	{0xDC16, 0x76CF,},
+	{0xDC18, 0xFF00,},
+	{0xDC1A, 0x2184,},
+	{0xDC1C, 0x9624,},
+	{0xDC1E, 0x218C,},
+	{0xDC20, 0x8FC3,},
+	{0xDC22, 0x75CF,},
+	{0xDC24, 0xFFFF,},
+	{0xDC26, 0xE058,},
+	{0xDC28, 0xF686,},
+	{0xDC2A, 0x1550,},
+	{0xDC2C, 0x1080,},
+	{0xDC2E, 0xE001,},
+	{0xDC30, 0x1D50,},
+	{0xDC32, 0x1002,},
+	{0xDC34, 0x1552,},
+	{0xDC36, 0x1100,},
+	{0xDC38, 0x6038,},
+	{0xDC3A, 0x1D52,},
+	{0xDC3C, 0x1004,},
+	{0xDC3E, 0x1540,},
+	{0xDC40, 0x1080,},
+	{0xDC42, 0x081B,},
+	{0xDC44, 0x00D1,},
+	{0xDC46, 0x8512,},
+	{0xDC48, 0x1000,},
+	{0xDC4A, 0x00C0,},
+	{0xDC4C, 0x7822,},
+	{0xDC4E, 0x2089,},
+	{0xDC50, 0x0FC1,},
+	{0xDC52, 0x2008,},
+	{0xDC54, 0x0F81,},
+	{0xDC56, 0xFFFF,},
+	{0xDC58, 0xFF80,},
+	{0xDC5A, 0x8512,},
+	{0xDC5C, 0x1801,},
+	{0xDC5E, 0x0052,},
+	{0xDC60, 0xA512,},
+	{0xDC62, 0x1544,},
+	{0xDC64, 0x1080,},
+	{0xDC66, 0xB861,},
+	{0xDC68, 0x262F,},
+	{0xDC6A, 0xF007,},
+	{0xDC6C, 0x1D44,},
+	{0xDC6E, 0x1002,},
+	{0xDC70, 0x20CA,},
+	{0xDC72, 0x0021,},
+	{0xDC74, 0x20CF,},
+	{0xDC76, 0x04E1,},
+	{0xDC78, 0x0850,},
+	{0xDC7A, 0x04A1,},
+	{0xDC7C, 0x21CA,},
+	{0xDC7E, 0x0021,},
+	{0xDC80, 0x1542,},
+	{0xDC82, 0x1140,},
+	{0xDC84, 0x8D2C,},
+	{0xDC86, 0x6038,},
+	{0xDC88, 0x1D42,},
+	{0xDC8A, 0x1004,},
+	{0xDC8C, 0x1542,},
+	{0xDC8E, 0x1140,},
+	{0xDC90, 0xB601,},
+	{0xDC92, 0x046D,},
+	{0xDC94, 0x0580,},
+	{0xDC96, 0x78E0,},
+	{0xDC98, 0xD800,},
+	{0xDC9A, 0xB893,},
+	{0xDC9C, 0x002D,},
+	{0xDC9E, 0x04A0,},
+	{0xDCA0, 0xD900,},
+	{0xDCA2, 0x78E0,},
+	{0xDCA4, 0x72CF,},
+	{0xDCA6, 0xFFFF,},
+	{0xDCA8, 0xE058,},
+	{0xDCAA, 0x2240,},
+	{0xDCAC, 0x0340,},
+	{0xDCAE, 0xA212,},
+	{0xDCB0, 0x208A,},
+	{0xDCB2, 0x0FFF,},
+	{0xDCB4, 0x1A42,},
+	{0xDCB6, 0x0004,},
+	{0xDCB8, 0xD830,},
+	{0xDCBA, 0x1A44,},
+	{0xDCBC, 0x0002,},
+	{0xDCBE, 0xD800,},
+	{0xDCC0, 0x1A50,},
+	{0xDCC2, 0x0002,},
+	{0xDCC4, 0x1A52,},
+	{0xDCC6, 0x0004,},
+	{0xDCC8, 0x1242,},
+	{0xDCCA, 0x0140,},
+	{0xDCCC, 0x8A2C,},
+	{0xDCCE, 0x6038,},
+	{0xDCD0, 0x1A42,},
+	{0xDCD2, 0x0004,},
+	{0xDCD4, 0x1242,},
+	{0xDCD6, 0x0141,},
+	{0xDCD8, 0x70CF,},
+	{0xDCDA, 0xFF00,},
+	{0xDCDC, 0x2184,},
+	{0xDCDE, 0xB021,},
+	{0xDCE0, 0xD800,},
+	{0xDCE2, 0xB893,},
+	{0xDCE4, 0x07E5,},
+	{0xDCE6, 0x0460,},
+	{0xDCE8, 0xD901,},
+	{0xDCEA, 0x78E0,},
+	{0xDCEC, 0xC0F1,},
+	{0xDCEE, 0x0BFA,},
+	{0xDCF0, 0x05A0,},
+	{0xDCF2, 0x216F,},
+	{0xDCF4, 0x0043,},
+	{0xDCF6, 0xC1A4,},
+	{0xDCF8, 0x220A,},
+	{0xDCFA, 0x1F80,},
+	{0xDCFC, 0xFFFF,},
+	{0xDCFE, 0xE058,},
+	{0xDD00, 0x2240,},
+	{0xDD02, 0x134F,},
+	{0xDD04, 0x1A48,},
+	{0xDD06, 0x13C0,},
+	{0xDD08, 0x1248,},
+	{0xDD0A, 0x1002,},
+	{0xDD0C, 0x70CF,},
+	{0xDD0E, 0x7FFF,},
+	{0xDD10, 0xFFFF,},
+	{0xDD12, 0xE230,},
+	{0xDD14, 0xC240,},
+	{0xDD16, 0xDA00,},
+	{0xDD18, 0xF00C,},
+	{0xDD1A, 0x1248,},
+	{0xDD1C, 0x1003,},
+	{0xDD1E, 0x1301,},
+	{0xDD20, 0x04CB,},
+	{0xDD22, 0x7261,},
+	{0xDD24, 0x2108,},
+	{0xDD26, 0x0081,},
+	{0xDD28, 0x2009,},
+	{0xDD2A, 0x0080,},
+	{0xDD2C, 0x1A48,},
+	{0xDD2E, 0x10C0,},
+	{0xDD30, 0x1248,},
+	{0xDD32, 0x100B,},
+	{0xDD34, 0xC300,},
+	{0xDD36, 0x0BE7,},
+	{0xDD38, 0x90C4,},
+	{0xDD3A, 0x2102,},
+	{0xDD3C, 0x0003,},
+	{0xDD3E, 0x238C,},
+	{0xDD40, 0x8FC3,},
+	{0xDD42, 0xF6C7,},
+	{0xDD44, 0xDAFF,},
+	{0xDD46, 0x1A05,},
+	{0xDD48, 0x1082,},
+	{0xDD4A, 0xC241,},
+	{0xDD4C, 0xF005,},
+	{0xDD4E, 0x7A6F,},
+	{0xDD50, 0xC241,},
+	{0xDD52, 0x1A05,},
+	{0xDD54, 0x10C2,},
+	{0xDD56, 0x2000,},
+	{0xDD58, 0x8040,},
+	{0xDD5A, 0xDA00,},
+	{0xDD5C, 0x20C0,},
+	{0xDD5E, 0x0064,},
+	{0xDD60, 0x781C,},
+	{0xDD62, 0xC042,},
+	{0xDD64, 0x1C0E,},
+	{0xDD66, 0x3082,},
+	{0xDD68, 0x1A48,},
+	{0xDD6A, 0x13C0,},
+	{0xDD6C, 0x7548,},
+	{0xDD6E, 0x7348,},
+	{0xDD70, 0x7148,},
+	{0xDD72, 0x7648,},
+	{0xDD74, 0xF002,},
+	{0xDD76, 0x7608,},
+	{0xDD78, 0x1248,},
+	{0xDD7A, 0x1000,},
+	{0xDD7C, 0x1400,},
+	{0xDD7E, 0x300B,},
+	{0xDD80, 0x084D,},
+	{0xDD82, 0x02C5,},
+	{0xDD84, 0x1248,},
+	{0xDD86, 0x1000,},
+	{0xDD88, 0xE101,},
+	{0xDD8A, 0x1001,},
+	{0xDD8C, 0x04CB,},
+	{0xDD8E, 0x1A48,},
+	{0xDD90, 0x1000,},
+	{0xDD92, 0x7361,},
+	{0xDD94, 0x1408,},
+	{0xDD96, 0x300B,},
+	{0xDD98, 0x2302,},
+	{0xDD9A, 0x02C0,},
+	{0xDD9C, 0x780D,},
+	{0xDD9E, 0x2607,},
+	{0xDDA0, 0x903E,},
+	{0xDDA2, 0x07D6,},
+	{0xDDA4, 0xFFE3,},
+	{0xDDA6, 0x792F,},
+	{0xDDA8, 0x09CF,},
+	{0xDDAA, 0x8152,},
+	{0xDDAC, 0x1248,},
+	{0xDDAE, 0x100E,},
+	{0xDDB0, 0x2400,},
+	{0xDDB2, 0x334B,},
+	{0xDDB4, 0xE501,},
+	{0xDDB6, 0x7EE2,},
+	{0xDDB8, 0x0DBF,},
+	{0xDDBA, 0x90F2,},
+	{0xDDBC, 0x1B0C,},
+	{0xDDBE, 0x1382,},
+	{0xDDC0, 0xC123,},
+	{0xDDC2, 0x140E,},
+	{0xDDC4, 0x3080,},
+	{0xDDC6, 0x7822,},
+	{0xDDC8, 0x1A07,},
+	{0xDDCA, 0x1002,},
+	{0xDDCC, 0x124C,},
+	{0xDDCE, 0x1000,},
+	{0xDDD0, 0x120B,},
+	{0xDDD2, 0x1081,},
+	{0xDDD4, 0x1207,},
+	{0xDDD6, 0x1083,},
+	{0xDDD8, 0x2142,},
+	{0xDDDA, 0x004B,},
+	{0xDDDC, 0x781B,},
+	{0xDDDE, 0x0B21,},
+	{0xDDE0, 0x02E2,},
+	{0xDDE2, 0x1A4C,},
+	{0xDDE4, 0x1000,},
+	{0xDDE6, 0xE101,},
+	{0xDDE8, 0x0915,},
+	{0xDDEA, 0x00C2,},
+	{0xDDEC, 0xC101,},
+	{0xDDEE, 0x1204,},
+	{0xDDF0, 0x1083,},
+	{0xDDF2, 0x090D,},
+	{0xDDF4, 0x00C2,},
+	{0xDDF6, 0xE001,},
+	{0xDDF8, 0x1A4C,},
+	{0xDDFA, 0x1000,},
+	{0xDDFC, 0x1A06,},
+	{0xDDFE, 0x1002,},
+	{0xDE00, 0x234A,},
+	{0xDE02, 0x1000,},
+	{0xDE04, 0x7169,},
+	{0xDE06, 0xF008,},
+	{0xDE08, 0x2053,},
+	{0xDE0A, 0x0003,},
+	{0xDE0C, 0x6179,},
+	{0xDE0E, 0x781C,},
+	{0xDE10, 0x2340,},
+	{0xDE12, 0x104B,},
+	{0xDE14, 0x1203,},
+	{0xDE16, 0x1083,},
+	{0xDE18, 0x0BF1,},
+	{0xDE1A, 0x90C2,},
+	{0xDE1C, 0x1202,},
+	{0xDE1E, 0x1080,},
+	{0xDE20, 0x091D,},
+	{0xDE22, 0x0004,},
+	{0xDE24, 0x70CF,},
+	{0xDE26, 0xFFFF,},
+	{0xDE28, 0xC644,},
+	{0xDE2A, 0x881B,},
+	{0xDE2C, 0xE0B2,},
+	{0xDE2E, 0xD83C,},
+	{0xDE30, 0x20CA,},
+	{0xDE32, 0x0CA2,},
+	{0xDE34, 0x1A01,},
+	{0xDE36, 0x1002,},
+	{0xDE38, 0x1A4C,},
+	{0xDE3A, 0x1080,},
+	{0xDE3C, 0x02B9,},
+	{0xDE3E, 0x05A0,},
+	{0xDE40, 0xC0A4,},
+	{0xDE42, 0x78E0,},
+	{0xDE44, 0xC0F1,},
+	{0xDE46, 0xFF95,},
+	{0xDE48, 0xD800,},
+	{0xDE4A, 0x71CF,},
+	{0xDE4C, 0xFF00,},
+	{0xDE4E, 0x1FE0,},
+	{0xDE50, 0x19D0,},
+	{0xDE52, 0x001C,},
+	{0xDE54, 0x19D1,},
+	{0xDE56, 0x001C,},
+	{0xDE58, 0x70CF,},
+	{0xDE5A, 0xFFFF,},
+	{0xDE5C, 0xE058,},
+	{0xDE5E, 0x901F,},
+	{0xDE60, 0xB861,},
+	{0xDE62, 0x19D2,},
+	{0xDE64, 0x001C,},
+	{0xDE66, 0xC0D1,},
+	{0xDE68, 0x7EE0,},
+	{0xDE6A, 0x78E0,},
+	{0xDE6C, 0xC0F1,},
+	{0xDE6E, 0x0A7A,},
+	{0xDE70, 0x0580,},
+	{0xDE72, 0x70CF,},
+	{0xDE74, 0xFFFF,},
+	{0xDE76, 0xC5D4,},
+	{0xDE78, 0x9041,},
+	{0xDE7A, 0x9023,},
+	{0xDE7C, 0x75CF,},
+	{0xDE7E, 0xFFFF,},
+	{0xDE80, 0xE058,},
+	{0xDE82, 0x7942,},
+	{0xDE84, 0xB967,},
+	{0xDE86, 0x7F30,},
+	{0xDE88, 0xB53F,},
+	{0xDE8A, 0x71CF,},
+	{0xDE8C, 0xFFFF,},
+	{0xDE8E, 0xC84C,},
+	{0xDE90, 0x91D3,},
+	{0xDE92, 0x108B,},
+	{0xDE94, 0x0081,},
+	{0xDE96, 0x2615,},
+	{0xDE98, 0x1380,},
+	{0xDE9A, 0x090F,},
+	{0xDE9C, 0x0C91,},
+	{0xDE9E, 0x0A8E,},
+	{0xDEA0, 0x05A0,},
+	{0xDEA2, 0xD906,},
+	{0xDEA4, 0x7E10,},
+	{0xDEA6, 0x2615,},
+	{0xDEA8, 0x1380,},
+	{0xDEAA, 0x0A82,},
+	{0xDEAC, 0x05A0,},
+	{0xDEAE, 0xD960,},
+	{0xDEB0, 0x790F,},
+	{0xDEB2, 0x090D,},
+	{0xDEB4, 0x0133,},
+	{0xDEB6, 0xAD0C,},
+	{0xDEB8, 0xD904,},
+	{0xDEBA, 0xAD2C,},
+	{0xDEBC, 0x79EC,},
+	{0xDEBE, 0x2941,},
+	{0xDEC0, 0x7402,},
+	{0xDEC2, 0x71CF,},
+	{0xDEC4, 0xFF00,},
+	{0xDEC6, 0x2184,},
+	{0xDEC8, 0xB142,},
+	{0xDECA, 0x1906,},
+	{0xDECC, 0x0E44,},
+	{0xDECE, 0xFFDE,},
+	{0xDED0, 0x70C9,},
+	{0xDED2, 0x0A5A,},
+	{0xDED4, 0x05A0,},
+	{0xDED6, 0x8D2C,},
+	{0xDED8, 0xAD0B,},
+	{0xDEDA, 0xD800,},
+	{0xDEDC, 0xAD01,},
+	{0xDEDE, 0x0219,},
+	{0xDEE0, 0x05A0,},
+	{0xDEE2, 0xA513,},
+	{0xDEE4, 0xC0F1,},
+	{0xDEE6, 0x71CF,},
+	{0xDEE8, 0xFFFF,},
+	{0xDEEA, 0xC644,},
+	{0xDEEC, 0xA91B,},
+	{0xDEEE, 0xD902,},
+	{0xDEF0, 0x70CF,},
+	{0xDEF2, 0xFFFF,},
+	{0xDEF4, 0xC84C,},
+	{0xDEF6, 0x093E,},
+	{0xDEF8, 0x03A0,},
+	{0xDEFA, 0xA826,},
+	{0xDEFC, 0xFFDC,},
+	{0xDEFE, 0xF1B5,},
+	{0xDF00, 0xC0F1,},
+	{0xDF02, 0x09EA,},
+	{0xDF04, 0x0580,},
+	{0xDF06, 0x75CF,},
+	{0xDF08, 0xFFFF,},
+	{0xDF0A, 0xE058,},
+	{0xDF0C, 0x1540,},
+	{0xDF0E, 0x1080,},
+	{0xDF10, 0x08A7,},
+	{0xDF12, 0x0010,},
+	{0xDF14, 0x8D00,},
+	{0xDF16, 0x0813,},
+	{0xDF18, 0x009E,},
+	{0xDF1A, 0x1540,},
+	{0xDF1C, 0x1081,},
+	{0xDF1E, 0xE181,},
+	{0xDF20, 0x20CA,},
+	{0xDF22, 0x00A1,},
+	{0xDF24, 0xF24B,},
+	{0xDF26, 0x1540,},
+	{0xDF28, 0x1081,},
+	{0xDF2A, 0x090F,},
+	{0xDF2C, 0x0050,},
+	{0xDF2E, 0x1540,},
+	{0xDF30, 0x1081,},
+	{0xDF32, 0x0927,},
+	{0xDF34, 0x0091,},
+	{0xDF36, 0x1550,},
+	{0xDF38, 0x1081,},
+	{0xDF3A, 0xDE00,},
+	{0xDF3C, 0xAD2A,},
+	{0xDF3E, 0x1D50,},
+	{0xDF40, 0x1382,},
+	{0xDF42, 0x1552,},
+	{0xDF44, 0x1101,},
+	{0xDF46, 0x1D52,},
+	{0xDF48, 0x1384,},
+	{0xDF4A, 0xB524,},
+	{0xDF4C, 0x082D,},
+	{0xDF4E, 0x015F,},
+	{0xDF50, 0xFF55,},
+	{0xDF52, 0xD803,},
+	{0xDF54, 0xF033,},
+	{0xDF56, 0x1540,},
+	{0xDF58, 0x1081,},
+	{0xDF5A, 0x0967,},
+	{0xDF5C, 0x00D1,},
+	{0xDF5E, 0x1550,},
+	{0xDF60, 0x1081,},
+	{0xDF62, 0xDE00,},
+	{0xDF64, 0xAD2A,},
+	{0xDF66, 0x1D50,},
+	{0xDF68, 0x1382,},
+	{0xDF6A, 0x1552,},
+	{0xDF6C, 0x1101,},
+	{0xDF6E, 0x1D52,},
+	{0xDF70, 0x1384,},
+	{0xDF72, 0xB524,},
+	{0xDF74, 0x0811,},
+	{0xDF76, 0x019E,},
+	{0xDF78, 0xB8A0,},
+	{0xDF7A, 0xAD00,},
+	{0xDF7C, 0xFF47,},
+	{0xDF7E, 0x1D40,},
+	{0xDF80, 0x1382,},
+	{0xDF82, 0xF01F,},
+	{0xDF84, 0xFF5A,},
+	{0xDF86, 0x8D01,},
+	{0xDF88, 0x8D40,},
+	{0xDF8A, 0xE812,},
+	{0xDF8C, 0x71CF,},
+	{0xDF8E, 0xFFFF,},
+	{0xDF90, 0xC644,},
+	{0xDF92, 0x893B,},
+	{0xDF94, 0x7030,},
+	{0xDF96, 0x22D1,},
+	{0xDF98, 0x8062,},
+	{0xDF9A, 0xF20A,},
+	{0xDF9C, 0x0A0F,},
+	{0xDF9E, 0x009E,},
+	{0xDFA0, 0x71CF,},
+	{0xDFA2, 0xFFFF,},
+	{0xDFA4, 0xC84C,},
+	{0xDFA6, 0x893B,},
+	{0xDFA8, 0xE902,},
+	{0xDFAA, 0xFFCF,},
+	{0xDFAC, 0x8D00,},
+	{0xDFAE, 0xB8E7,},
+	{0xDFB0, 0x26CA,},
+	{0xDFB2, 0x1022,},
+	{0xDFB4, 0xF5E2,},
+	{0xDFB6, 0xFF3C,},
+	{0xDFB8, 0xD801,},
+	{0xDFBA, 0x1D40,},
+	{0xDFBC, 0x1002,},
+	{0xDFBE, 0x0141,},
+	{0xDFC0, 0x0580,},
+	{0xDFC2, 0x78E0,},
+	{0xDFC4, 0xC0F1,},
+	{0xDFC6, 0xC5E1,},
+	{0xDFC8, 0xFF34,},
+	{0xDFCA, 0xDD00,},
+	{0xDFCC, 0x70CF,},
+	{0xDFCE, 0xFFFF,},
+	{0xDFD0, 0xE090,},
+	{0xDFD2, 0xA8A8,},
+	{0xDFD4, 0xD800,},
+	{0xDFD6, 0xB893,},
+	{0xDFD8, 0x0C8A,},
+	{0xDFDA, 0x0460,},
+	{0xDFDC, 0xD901,},
+	{0xDFDE, 0x71CF,},
+	{0xDFE0, 0xFFFF,},
+	{0xDFE2, 0xDC10,},
+	{0xDFE4, 0xD813,},
+	{0xDFE6, 0x0B96,},
+	{0xDFE8, 0x0460,},
+	{0xDFEA, 0x72A9,},
+	{0xDFEC, 0x0119,},
+	{0xDFEE, 0x0580,},
+	{0xDFF0, 0xC0F1,},
+	{0xDFF2, 0x71CF,},
+	{0xDFF4, 0x0000,},
+	{0xDFF6, 0x5BAE,},
+	{0xDFF8, 0x7940,},
+	{0xDFFA, 0xFF9D,},
+	{0xDFFC, 0xF135,},
+	{0xDFFE, 0x78E0,},
+	{0xE000, 0xC0F1,},
+	{0xE002, 0x70CF,},
+	{0xE004, 0x0000,},
+	{0xE006, 0x5CBA,},
+	{0xE008, 0x7840,},
+	{0xE00A, 0x70CF,},
+	{0xE00C, 0xFFFF,},
+	{0xE00E, 0xE058,},
+	{0xE010, 0x8800,},
+	{0xE012, 0x0815,},
+	{0xE014, 0x001E,},
+	{0xE016, 0x70CF,},
+	{0xE018, 0xFFFF,},
+	{0xE01A, 0xC84C,},
+	{0xE01C, 0x881A,},
+	{0xE01E, 0xE080,},
+	{0xE020, 0x0EE0,},
+	{0xE022, 0xFFC1,},
+	{0xE024, 0xF121,},
+	{0xE026, 0x78E0,},
+	{0xE028, 0xC0F1,},
+	{0xE02A, 0xD900,},
+	{0xE02C, 0xF009,},
+	{0xE02E, 0x70CF,},
+	{0xE030, 0xFFFF,},
+	{0xE032, 0xE0AC,},
+	{0xE034, 0x7835,},
+	{0xE036, 0x8041,},
+	{0xE038, 0x8000,},
+	{0xE03A, 0xE102,},
+	{0xE03C, 0xA040,},
+	{0xE03E, 0x09F3,},
+	{0xE040, 0x8114,},
+	{0xE042, 0x71CF,},
+	{0xE044, 0xFFFF,},
+	{0xE046, 0xE058,},
+	{0xE048, 0x70CF,},
+	{0xE04A, 0xFFFF,},
+	{0xE04C, 0xC594,},
+	{0xE04E, 0xB030,},
+	{0xE050, 0xFFDD,},
+	{0xE052, 0xD800,},
+	{0xE054, 0xF109,},
+	{0xE056, 0x0000,},
+	{0xE058, 0x0300,},
+	{0xE05A, 0x0204,},
+	{0xE05C, 0x0700,},
+	{0xE05E, 0x0000,},
+	{0xE060, 0x0000,},
+	{0xE062, 0x0000,},
+	{0xE064, 0x0000,},
+	{0xE066, 0x0000,},
+	{0xE068, 0x0000,},
+	{0xE06A, 0x0000,},
+	{0xE06C, 0x0000,},
+	{0xE06E, 0x0000,},
+	{0xE070, 0x0000,},
+	{0xE072, 0x0000,},
+	{0xE074, 0x0000,},
+	{0xE076, 0x0000,},
+	{0xE078, 0x0000,},
+	{0xE07A, 0x0000,},
+	{0xE07C, 0x0000,},
+	{0xE07E, 0x0000,},
+	{0xE080, 0x0000,},
+	{0xE082, 0x0000,},
+	{0xE084, 0x0000,},
+	{0xE086, 0x0000,},
+	{0xE088, 0x0000,},
+	{0xE08A, 0x0000,},
+	{0xE08C, 0x0000,},
+	{0xE08E, 0x0000,},
+	{0xE090, 0x0000,},
+	{0xE092, 0x0000,},
+	{0xE094, 0x0000,},
+	{0xE096, 0x0000,},
+	{0xE098, 0x0000,},
+	{0xE09A, 0x0000,},
+	{0xE09C, 0x0000,},
+	{0xE09E, 0x0000,},
+	{0xE0A0, 0x0000,},
+	{0xE0A2, 0x0000,},
+	{0xE0A4, 0x0000,},
+	{0xE0A6, 0x0000,},
+	{0xE0A8, 0x0000,},
+	{0xE0AA, 0x0000,},
+	{0xE0AC, 0xFFFF,},
+	{0xE0AE, 0xCB68,},
+	{0xE0B0, 0xFFFF,},
+	{0xE0B2, 0xDFF0,},
+	{0xE0B4, 0xFFFF,},
+	{0xE0B6, 0xCB6C,},
+	{0xE0B8, 0xFFFF,},
+	{0xE0BA, 0xE000,},
+	{0x098E, 0x0000,},
+
+	/*MIPI setting for SOC1040*/
+	{0x3C5A, 0x0009,},
+	{0x3C44, 0x0080,},/*MIPI_CUSTOM_SHORT_PKT*/
+
+	/*[Tuning_settings]*/
+
+	/*[CCM]*/
+	{0xC892, 0x0267,},/*CAM_AWB_CCM_L_0*/
+	{0xC894, 0xFF1A,},/*CAM_AWB_CCM_L_1*/
+	{0xC896, 0xFFB3,},/*CAM_AWB_CCM_L_2*/
+	{0xC898, 0xFF80,},/*CAM_AWB_CCM_L_3*/
+	{0xC89A, 0x0166,},/*CAM_AWB_CCM_L_4*/
+	{0xC89C, 0x0003,},/*CAM_AWB_CCM_L_5*/
+	{0xC89E, 0xFF9A,},/*CAM_AWB_CCM_L_6*/
+	{0xC8A0, 0xFEB4,},/*CAM_AWB_CCM_L_7*/
+	{0xC8A2, 0x024D,},/*CAM_AWB_CCM_L_8*/
+	{0xC8A4, 0x01BF,},/*CAM_AWB_CCM_M_0*/
+	{0xC8A6, 0xFF01,},/*CAM_AWB_CCM_M_1*/
+	{0xC8A8, 0xFFF3,},/*CAM_AWB_CCM_M_2*/
+	{0xC8AA, 0xFF75,},/*CAM_AWB_CCM_M_3*/
+	{0xC8AC, 0x0198,},/*CAM_AWB_CCM_M_4*/
+	{0xC8AE, 0xFFFD,},/*CAM_AWB_CCM_M_5*/
+	{0xC8B0, 0xFF9A,},/*CAM_AWB_CCM_M_6*/
+	{0xC8B2, 0xFEE7,},/*CAM_AWB_CCM_M_7*/
+	{0xC8B4, 0x02A8,},/*CAM_AWB_CCM_M_8*/
+	{0xC8B6, 0x01D9,},/*CAM_AWB_CCM_R_0*/
+	{0xC8B8, 0xFF26,},/*CAM_AWB_CCM_R_1*/
+	{0xC8BA, 0xFFF3,},/*CAM_AWB_CCM_R_2*/
+	{0xC8BC, 0xFFB3,},/*CAM_AWB_CCM_R_3*/
+	{0xC8BE, 0x0132,},/*CAM_AWB_CCM_R_4*/
+	{0xC8C0, 0xFFE8,},/*CAM_AWB_CCM_R_5*/
+	{0xC8C2, 0xFFDA,},/*CAM_AWB_CCM_R_6*/
+	{0xC8C4, 0xFECD,},/*CAM_AWB_CCM_R_7*/
+	{0xC8C6, 0x02C2,},/*CAM_AWB_CCM_R_8*/
+	{0xC8C8, 0x0075,},/*CAM_AWB_CCM_L_RG_GAIN*/
+	{0xC8CA, 0x011C,},/*CAM_AWB_CCM_L_BG_GAIN*/
+	{0xC8CC, 0x009A,},/*CAM_AWB_CCM_M_RG_GAIN*/
+	{0xC8CE, 0x0105,},/*CAM_AWB_CCM_M_BG_GAIN*/
+	{0xC8D0, 0x00A4,},/*CAM_AWB_CCM_R_RG_GAIN*/
+	{0xC8D2, 0x00AC,},/*CAM_AWB_CCM_R_BG_GAIN*/
+	{0xC8D4, 0x0A8C,},/*CAM_AWB_CCM_L_CTEMP*/
+	{0xC8D6, 0x0F0A,},/*CAM_AWB_CCM_M_CTEMP*/
+	{0xC8D8, 0x1964,},/*CAM_AWB_CCM_R_CTEMP*/
+
+	/*[AWB]*/
+	{0xC914, 0x0000,},/*CAM_STAT_AWB_CLIP_WINDOW_XSTART*/
+	{0xC916, 0x0000,},/*CAM_STAT_AWB_CLIP_WINDOW_YSTART*/
+	{0xC918, 0x04FF,},/*CAM_STAT_AWB_CLIP_WINDOW_XEND*/
+	{0xC91A, 0x02CF,},/*CAM_STAT_AWB_CLIP_WINDOW_YEND*/
+	{0xC904, 0x0033,},/*CAM_AWB_AWB_XSHIFT_PRE_ADJ*/
+	{0xC906, 0x0040,},/*CAM_AWB_AWB_YSHIFT_PRE_ADJ*/
+	{0xC8F2, 0x03, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_AWB_XSCALE*/
+	{0xC8F3, 0x02, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_AWB_YSCALE*/
+	{0xC906, 0x003C,},/*CAM_AWB_AWB_YSHIFT_PRE_ADJ*/
+	{0xC8F4, 0x0000,},/*CAM_AWB_AWB_WEIGHTS_0*/
+	{0xC8F6, 0x0000,},/*CAM_AWB_AWB_WEIGHTS_1*/
+	{0xC8F8, 0x0000,},/*CAM_AWB_AWB_WEIGHTS_2*/
+	{0xC8FA, 0xE724,},/*CAM_AWB_AWB_WEIGHTS_3*/
+	{0xC8FC, 0x1583,},/*CAM_AWB_AWB_WEIGHTS_4*/
+	{0xC8FE, 0x2045,},/*CAM_AWB_AWB_WEIGHTS_5*/
+	{0xC900, 0x03FF,},/*CAM_AWB_AWB_WEIGHTS_6*/
+	{0xC902, 0x007C,},/*CAM_AWB_AWB_WEIGHTS_7*/
+	{0xC90C, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_R_L*/
+	{0xC90D, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_G_L*/
+	{0xC90E, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_B_L*/
+	{0xC90F, 0x88, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_R_R*/
+	{0xC910, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_G_R*/
+	{0xC911, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AWB_K_B_R*/
+
+	/*[Step7-CPIPE_Preference]*/
+	{0xC926, 0x0020,},/*CAM_LL_START_BRIGHTNESS*/
+	{0xC928, 0x009A,},/*CAM_LL_STOP_BRIGHTNESS*/
+	{0xC946, 0x0070,},/*CAM_LL_START_GAIN_METRIC*/
+	{0xC948, 0x00F3,},/*CAM_LL_STOP_GAIN_METRIC*/
+	{0xC952, 0x0020,},/*CAM_LL_START_TARGET_LUMA_BM*/
+	{0xC954, 0x009A,},/*CAM_LL_STOP_TARGET_LUMA_BM*/
+	{0xC92A, 0x80, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_SATURATION*/
+	{0xC92B, 0x4B, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_END_SATURATION*/
+	{0xC92C, 0x00, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_DESATURATION*/
+	{0xC92D, 0xFF, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_END_DESATURATION*/
+	{0xC92E, 0x3C, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_DEMOSAIC*/
+	{0xC92F, 0x02, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_AP_GAIN*/
+	{0xC930, 0x06, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_AP_THRESH*/
+	{0xC931, 0x64, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_DEMOSAIC*/
+	{0xC932, 0x01, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_AP_GAIN*/
+	{0xC933, 0x0C, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_AP_THRESH*/
+	{0xC934, 0x3C, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_NR_RED*/
+	{0xC935, 0x3C, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_NR_GREEN*/
+	{0xC936, 0x3C, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_NR_BLUE*/
+	{0xC937, 0x0F, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_NR_THRESH*/
+	{0xC938, 0x64, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_NR_RED*/
+	{0xC939, 0x64, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_NR_GREEN*/
+	{0xC93A, 0x64, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_NR_BLUE*/
+	{0xC93B, 0x32, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_NR_THRESH*/
+	{0xC93C, 0x0020,},/*CAM_LL_START_CONTRAST_BM*/
+	{0xC93E, 0x009A,},/*CAM_LL_STOP_CONTRAST_BM*/
+	{0xC940, 0x00DC,},/*CAM_LL_GAMMA*/
+	/*CAM_LL_START_CONTRAST_GRADIENT*/
+	{0xC942, 0x38, MSM_CAMERA_I2C_BYTE_DATA},
+	/*CAM_LL_STOP_CONTRAST_GRADIENT*/
+	{0xC943, 0x30, MSM_CAMERA_I2C_BYTE_DATA},
+	{0xC944, 0x50, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_START_CONTRAST_LUMA*/
+	{0xC945, 0x19, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_STOP_CONTRAST_LUMA*/
+	{0xC94A, 0x0230,},/*CAM_LL_START_FADE_TO_BLACK_LUMA*/
+	{0xC94C, 0x0010,},/*CAM_LL_STOP_FADE_TO_BLACK_LUMA*/
+	{0xC94E, 0x01CD,},/*CAM_LL_CLUSTER_DC_TH_BM*/
+	{0xC950, 0x05, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_CLUSTER_DC_GATE*/
+	{0xC951, 0x40, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_LL_SUMMING_SENSITIVITY*/
+	/*CAM_AET_TARGET_AVERAGE_LUMA_DARK*/
+	{0xC87B, 0x1B, MSM_CAMERA_I2C_BYTE_DATA},
+	{0xC878, 0x0E, MSM_CAMERA_I2C_BYTE_DATA},/*CAM_AET_AEMODE*/
+	{0xC890, 0x0080,},/*CAM_AET_TARGET_GAIN*/
+	{0xC886, 0x0100,},/*CAM_AET_AE_MAX_VIRT_AGAIN*/
+	{0xC87C, 0x005A,},/*CAM_AET_BLACK_CLIPPING_TARGET*/
+	{0xB42A, 0x05, MSM_CAMERA_I2C_BYTE_DATA},/*CCM_DELTA_GAIN*/
+	/*AE_TRACK_AE_TRACKING_DAMPENING*/
+	{0xA80A, 0x20, MSM_CAMERA_I2C_BYTE_DATA},
+	{0x3C44, 0x0080,},
+	{0x3C40, 0x0004, MSM_CAMERA_I2C_UNSET_WORD_MASK},
+	{0xA802, 0x08, MSM_CAMERA_I2C_SET_BYTE_MASK},
+	{0xC908, 0x01, MSM_CAMERA_I2C_BYTE_DATA},
+	{0xC879, 0x01, MSM_CAMERA_I2C_BYTE_DATA},
+	{0xC909, 0x01, MSM_CAMERA_I2C_UNSET_BYTE_MASK},
+	{0xA80A, 0x18, MSM_CAMERA_I2C_BYTE_DATA},
+	{0xA80B, 0x18, MSM_CAMERA_I2C_BYTE_DATA},
+	{0xAC16, 0x18, MSM_CAMERA_I2C_BYTE_DATA},
+	{0xC878, 0x08, MSM_CAMERA_I2C_SET_BYTE_MASK},
+	{0xBC02, 0x08, MSM_CAMERA_I2C_UNSET_BYTE_MASK},
+};
+
+static struct v4l2_subdev_info mt9m114_subdev_info[] = {
+	{
+	.code   = V4L2_MBUS_FMT_YUYV8_2X8,
+	.colorspace = V4L2_COLORSPACE_JPEG,
+	.fmt    = 1,
+	.order    = 0,
+	},
+	/* more can be supported, to be added later */
+};
+
+static struct msm_camera_i2c_reg_conf mt9m114_config_change_settings[] = {
+	{0xdc00, 0x28, MSM_CAMERA_I2C_BYTE_DATA, MSM_CAMERA_I2C_CMD_WRITE},
+	{MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_SET_STATE,
+		MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+	{MT9M114_COMMAND_REGISTER, (MT9M114_COMMAND_REGISTER_OK |
+		MT9M114_COMMAND_REGISTER_SET_STATE), MSM_CAMERA_I2C_WORD_DATA,
+		MSM_CAMERA_I2C_CMD_WRITE},
+	{MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_SET_STATE,
+		MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+	{0xDC01, 0x31, MSM_CAMERA_I2C_BYTE_DATA},
+};
+
+static void mt9m114_stop_stream(struct msm_sensor_ctrl_t *s_ctrl) {}
+
+static struct msm_camera_i2c_conf_array mt9m114_init_conf[] = {
+	{mt9m114_recommend_settings,
+	ARRAY_SIZE(mt9m114_recommend_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
+	{mt9m114_config_change_settings,
+	ARRAY_SIZE(mt9m114_config_change_settings),
+	0, MSM_CAMERA_I2C_WORD_DATA},
+};
+
+static struct msm_camera_i2c_conf_array mt9m114_confs[] = {
+	{mt9m114_720p_settings,
+	ARRAY_SIZE(mt9m114_720p_settings), 0, MSM_CAMERA_I2C_WORD_DATA},
+};
+
+static struct msm_camera_i2c_reg_conf mt9m114_saturation[][1] = {
+	{{0xCC12, 0x00},},
+	{{0xCC12, 0x1A},},
+	{{0xCC12, 0x34},},
+	{{0xCC12, 0x4E},},
+	{{0xCC12, 0x68},},
+	{{0xCC12, 0x80},},
+	{{0xCC12, 0x9A},},
+	{{0xCC12, 0xB4},},
+	{{0xCC12, 0xCE},},
+	{{0xCC12, 0xE8},},
+	{{0xCC12, 0xFF},},
+};
+
+static struct msm_camera_i2c_reg_conf mt9m114_refresh[] = {
+	{MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_REFRESH,
+		MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+	{MT9M114_COMMAND_REGISTER, (MT9M114_COMMAND_REGISTER_OK |
+		MT9M114_COMMAND_REGISTER_REFRESH), MSM_CAMERA_I2C_WORD_DATA,
+		MSM_CAMERA_I2C_CMD_WRITE},
+	{MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_REFRESH,
+		MSM_CAMERA_I2C_UNSET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+	{MT9M114_COMMAND_REGISTER, MT9M114_COMMAND_REGISTER_OK,
+		MSM_CAMERA_I2C_SET_WORD_MASK, MSM_CAMERA_I2C_CMD_POLL},
+};
+
+static struct msm_camera_i2c_conf_array mt9m114_saturation_confs[][2] = {
+	{{mt9m114_saturation[0],
+		ARRAY_SIZE(mt9m114_saturation[0]), 0, MSM_CAMERA_I2C_WORD_DATA},
+	{mt9m114_refresh,
+		ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+	{{mt9m114_saturation[1],
+		ARRAY_SIZE(mt9m114_saturation[1]), 0, MSM_CAMERA_I2C_WORD_DATA},
+	{mt9m114_refresh,
+		ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+	{{mt9m114_saturation[2],
+		ARRAY_SIZE(mt9m114_saturation[2]), 0, MSM_CAMERA_I2C_WORD_DATA},
+	{mt9m114_refresh,
+		ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+	{{mt9m114_saturation[3],
+		ARRAY_SIZE(mt9m114_saturation[3]), 0, MSM_CAMERA_I2C_WORD_DATA},
+	{mt9m114_refresh,
+		ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+	{{mt9m114_saturation[4],
+		ARRAY_SIZE(mt9m114_saturation[4]), 0, MSM_CAMERA_I2C_WORD_DATA},
+	{mt9m114_refresh,
+		ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+	{{mt9m114_saturation[5],
+		ARRAY_SIZE(mt9m114_saturation[5]), 0, MSM_CAMERA_I2C_WORD_DATA},
+	{mt9m114_refresh,
+		ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+	{{mt9m114_saturation[6],
+		ARRAY_SIZE(mt9m114_saturation[6]), 0, MSM_CAMERA_I2C_WORD_DATA},
+	{mt9m114_refresh,
+		ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+	{{mt9m114_saturation[7],
+		ARRAY_SIZE(mt9m114_saturation[7]), 0, MSM_CAMERA_I2C_WORD_DATA},
+	{mt9m114_refresh,
+		ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+	{{mt9m114_saturation[8],
+		ARRAY_SIZE(mt9m114_saturation[8]), 0, MSM_CAMERA_I2C_WORD_DATA},
+	{mt9m114_refresh,
+		ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+	{{mt9m114_saturation[9],
+		ARRAY_SIZE(mt9m114_saturation[9]), 0, MSM_CAMERA_I2C_WORD_DATA},
+	{mt9m114_refresh,
+		ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+	{{mt9m114_saturation[10],
+		ARRAY_SIZE(mt9m114_saturation[10]),
+		0, MSM_CAMERA_I2C_WORD_DATA},
+	{mt9m114_refresh,
+		ARRAY_SIZE(mt9m114_refresh), 0, MSM_CAMERA_I2C_WORD_DATA},},
+};
+
+static int mt9m114_saturation_enum_map[] = {
+	MSM_V4L2_SATURATION_L0,
+	MSM_V4L2_SATURATION_L1,
+	MSM_V4L2_SATURATION_L2,
+	MSM_V4L2_SATURATION_L3,
+	MSM_V4L2_SATURATION_L4,
+	MSM_V4L2_SATURATION_L5,
+	MSM_V4L2_SATURATION_L6,
+	MSM_V4L2_SATURATION_L7,
+	MSM_V4L2_SATURATION_L8,
+	MSM_V4L2_SATURATION_L9,
+	MSM_V4L2_SATURATION_L10,
+};
+
+static struct msm_camera_i2c_enum_conf_array mt9m114_saturation_enum_confs = {
+	.conf = &mt9m114_saturation_confs[0][0],
+	.conf_enum = mt9m114_saturation_enum_map,
+	.num_enum = ARRAY_SIZE(mt9m114_saturation_enum_map),
+	.num_index = ARRAY_SIZE(mt9m114_saturation_confs),
+	.num_conf = ARRAY_SIZE(mt9m114_saturation_confs[0]),
+	.data_type = MSM_CAMERA_I2C_WORD_DATA,
+};
+
+struct msm_sensor_v4l2_ctrl_info_t mt9m114_v4l2_ctrl_info[] = {
+	{
+		.ctrl_id = V4L2_CID_SATURATION,
+		.min = MSM_V4L2_SATURATION_L0,
+		.max = MSM_V4L2_SATURATION_L10,
+		.step = 1,
+		.enum_cfg_settings = &mt9m114_saturation_enum_confs,
+		.s_v4l2_ctrl = msm_sensor_s_ctrl_by_enum,
+	},
+};
+
+static struct msm_sensor_output_info_t mt9m114_dimensions[] = {
+	{
+		.x_output = 0x500,
+		.y_output = 0x2D0,
+		.line_length_pclk = 0x500,
+		.frame_length_lines = 0x2D0,
+		.vt_pixel_clk = 48000000,
+		.op_pixel_clk = 128000000,
+		.binning_factor = 1,
+	},
+};
+
+static struct msm_camera_csid_vc_cfg mt9m114_cid_cfg[] = {
+	{0, CSI_YUV422_8, CSI_DECODE_8BIT},
+	{1, CSI_EMBED_DATA, CSI_DECODE_8BIT},
+};
+
+static struct msm_camera_csi2_params mt9m114_csi_params = {
+	.csid_params = {
+		.lane_assign = 0xe4,
+		.lane_cnt = 1,
+		.lut_params = {
+			.num_cid = 2,
+			.vc_cfg = mt9m114_cid_cfg,
+		},
+	},
+	.csiphy_params = {
+		.lane_cnt = 1,
+		.settle_cnt = 0x14,
+	},
+};
+
+static struct msm_camera_csi2_params *mt9m114_csi_params_array[] = {
+	&mt9m114_csi_params,
+	&mt9m114_csi_params,
+};
+
+static struct msm_sensor_output_reg_addr_t mt9m114_reg_addr = {
+	.x_output = 0xC868,
+	.y_output = 0xC86A,
+	.line_length_pclk = 0xC868,
+	.frame_length_lines = 0xC86A,
+};
+
+static struct msm_sensor_id_info_t mt9m114_id_info = {
+	.sensor_id_reg_addr = 0x0,
+	.sensor_id = 0x2481,
+};
+
+static int mt9m114_sensor_config(void __user *argp)
+{
+	return msm_sensor_config(&mt9m114_s_ctrl, argp);
+}
+
+static int mt9m114_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	return msm_sensor_open_init(&mt9m114_s_ctrl, data);
+}
+
+static int mt9m114_sensor_release(void)
+{
+	return msm_sensor_release(&mt9m114_s_ctrl);
+}
+
+static const struct i2c_device_id mt9m114_i2c_id[] = {
+	{SENSOR_NAME, (kernel_ulong_t)&mt9m114_s_ctrl},
+	{ }
+};
+
+static struct i2c_driver mt9m114_i2c_driver = {
+	.id_table = mt9m114_i2c_id,
+	.probe  = msm_sensor_i2c_probe,
+	.driver = {
+		.name = SENSOR_NAME,
+	},
+};
+
+static struct msm_camera_i2c_client mt9m114_sensor_i2c_client = {
+	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static int mt9m114_sensor_v4l2_probe(const struct msm_camera_sensor_info *info,
+	struct v4l2_subdev *sdev, struct msm_sensor_ctrl *s)
+{
+	return msm_sensor_v4l2_probe(&mt9m114_s_ctrl, info, sdev, s);
+}
+
+static int mt9m114_probe(struct platform_device *pdev)
+{
+	return msm_sensor_register(pdev, mt9m114_sensor_v4l2_probe);
+}
+
+struct platform_driver mt9m114_driver = {
+	.probe = mt9m114_probe,
+	.driver = {
+		.name = PLATFORM_DRIVER_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_sensor_init_module(void)
+{
+	return platform_driver_register(&mt9m114_driver);
+}
+
+static struct v4l2_subdev_core_ops mt9m114_subdev_core_ops = {
+	.s_ctrl = msm_sensor_v4l2_s_ctrl,
+	.queryctrl = msm_sensor_v4l2_query_ctrl,
+};
+
+static struct v4l2_subdev_video_ops mt9m114_subdev_video_ops = {
+	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops mt9m114_subdev_ops = {
+	.core = &mt9m114_subdev_core_ops,
+	.video  = &mt9m114_subdev_video_ops,
+};
+
+static struct msm_sensor_fn_t mt9m114_func_tbl = {
+	.sensor_start_stream = msm_sensor_start_stream,
+	.sensor_stop_stream = mt9m114_stop_stream,
+	.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 = mt9m114_sensor_config,
+	.sensor_open_init = mt9m114_sensor_open_init,
+	.sensor_release = mt9m114_sensor_release,
+	.sensor_power_up = msm_sensor_power_up,
+	.sensor_power_down = msm_sensor_power_down,
+	.sensor_probe = msm_sensor_probe,
+};
+
+static struct msm_sensor_reg_t mt9m114_regs = {
+	.default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
+	.start_stream_conf = mt9m114_config_change_settings,
+	.start_stream_conf_size = ARRAY_SIZE(mt9m114_config_change_settings),
+	.init_settings = &mt9m114_init_conf[0],
+	.init_size = ARRAY_SIZE(mt9m114_init_conf),
+	.mode_settings = &mt9m114_confs[0],
+	.output_settings = &mt9m114_dimensions[0],
+	.num_conf = ARRAY_SIZE(mt9m114_confs),
+};
+
+static struct msm_sensor_ctrl_t mt9m114_s_ctrl = {
+	.msm_sensor_reg = &mt9m114_regs,
+	.msm_sensor_v4l2_ctrl_info = mt9m114_v4l2_ctrl_info,
+	.num_v4l2_ctrl = ARRAY_SIZE(mt9m114_v4l2_ctrl_info),
+	.sensor_i2c_client = &mt9m114_sensor_i2c_client,
+	.sensor_i2c_addr = 0x90,
+	.sensor_output_reg_addr = &mt9m114_reg_addr,
+	.sensor_id_info = &mt9m114_id_info,
+	.cam_mode = MSM_SENSOR_MODE_INVALID,
+	.csi_params = &mt9m114_csi_params_array[0],
+	.msm_sensor_mutex = &mt9m114_mut,
+	.sensor_i2c_driver = &mt9m114_i2c_driver,
+	.sensor_v4l2_subdev_info = mt9m114_subdev_info,
+	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(mt9m114_subdev_info),
+	.sensor_v4l2_subdev_ops = &mt9m114_subdev_ops,
+	.func_tbl = &mt9m114_func_tbl,
+};
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Aptina 1.26MP YUV sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/pm8xxx-misc.c b/drivers/mfd/pm8xxx-misc.c
index a73a695..7314c7e 100644
--- a/drivers/mfd/pm8xxx-misc.c
+++ b/drivers/mfd/pm8xxx-misc.c
@@ -18,6 +18,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/delay.h>
 #include <linux/mfd/pm8xxx/core.h>
 #include <linux/mfd/pm8xxx/misc.h>
 
@@ -131,6 +132,10 @@
 #define UART_PATH_SEL_MASK			0x60
 #define UART_PATH_SEL_SHIFT			0x5
 
+/* Shutdown/restart delays to allow for LDO 7/dVdd regulator load settling. */
+#define PM8901_DELAY_AFTER_REG_DISABLE_MS	4
+#define PM8901_DELAY_BEFORE_SHUTDOWN_MS		8
+
 struct pm8xxx_misc_chip {
 	struct list_head			link;
 	struct pm8xxx_misc_platform_data	pdata;
@@ -420,10 +425,12 @@
 					"rc=%d\n", rc);
 				goto read_write_err;
 			}
+			mdelay(PM8901_DELAY_AFTER_REG_DISABLE_MS);
 		}
 	}
 
 read_write_err:
+	mdelay(PM8901_DELAY_BEFORE_SHUTDOWN_MS);
 	return rc;
 }
 
diff --git a/drivers/mfd/pmic8901.c b/drivers/mfd/pmic8901.c
index 9e8786e..080a3e3 100644
--- a/drivers/mfd/pmic8901.c
+++ b/drivers/mfd/pmic8901.c
@@ -13,7 +13,6 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/delay.h>
 #include <linux/mfd/core.h>
 #include <linux/msm_ssbi.h>
 #include <linux/mfd/pmic8901.h>
@@ -31,19 +30,6 @@
 #define REG_TEMP_ALRM_CTRL		0x23
 #define REG_TEMP_ALRM_PWM		0x24
 
-/* FTS regulator PMR registers */
-#define SSBI_REG_ADDR_S1_PMR		(0xA7)
-#define SSBI_REG_ADDR_S2_PMR		(0xA8)
-#define SSBI_REG_ADDR_S3_PMR		(0xA9)
-#define SSBI_REG_ADDR_S4_PMR		(0xAA)
-
-#define REGULATOR_PMR_STATE_MASK	0x60
-#define REGULATOR_PMR_STATE_OFF		0x20
-
-/* Shutdown/restart delays to allow for LDO 7/dVdd regulator load settling. */
-#define DELAY_AFTER_REG_DISABLE_MS	4
-#define DELAY_BEFORE_SHUTDOWN_MS	8
-
 #define SINGLE_IRQ_RESOURCE(_name, _irq) \
 { \
 	.name	= _name, \
@@ -60,63 +46,6 @@
 	u8				revision;
 };
 
-static struct pm8901_chip *pmic_chip;
-
-static inline int
-ssbi_read(struct device *dev, u16 addr, u8 *buf, size_t len)
-{
-	return msm_ssbi_read(dev->parent, addr, buf, len);
-}
-
-static inline int
-ssbi_write(struct device *dev, u16 addr, u8 *buf, size_t len)
-{
-	return msm_ssbi_write(dev->parent, addr, buf, len);
-}
-
-int pm8901_reset_pwr_off(int reset)
-{
-	int rc = 0, i;
-	u8 pmr;
-	u8 pmr_addr[4] = {
-		SSBI_REG_ADDR_S2_PMR,
-		SSBI_REG_ADDR_S3_PMR,
-		SSBI_REG_ADDR_S4_PMR,
-		SSBI_REG_ADDR_S1_PMR,
-	};
-
-	if (pmic_chip == NULL)
-		return -ENODEV;
-
-	/* Turn off regulators S1, S2, S3, S4 when shutting down. */
-	if (!reset) {
-		for (i = 0; i < 4; i++) {
-			rc = ssbi_read(pmic_chip->dev, pmr_addr[i], &pmr, 1);
-			if (rc) {
-				pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n",
-				       __func__, pmr_addr[i], rc);
-				goto get_out;
-			}
-
-			pmr &= ~REGULATOR_PMR_STATE_MASK;
-			pmr |= REGULATOR_PMR_STATE_OFF;
-
-			rc = ssbi_write(pmic_chip->dev, pmr_addr[i], &pmr, 1);
-			if (rc) {
-				pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d"
-				       "\n", __func__, pmr_addr[i], pmr, rc);
-				goto get_out;
-			}
-			mdelay(DELAY_AFTER_REG_DISABLE_MS);
-		}
-	}
-
-get_out:
-	mdelay(DELAY_BEFORE_SHUTDOWN_MS);
-	return rc;
-}
-EXPORT_SYMBOL(pm8901_reset_pwr_off);
-
 static int pm8901_readb(const struct device *dev, u16 addr, u8 *val)
 {
 	const struct pm8xxx_drvdata *pm8901_drvdata = dev_get_drvdata(dev);
@@ -191,6 +120,11 @@
 	.pmic_get_revision	= pm8901_get_revision,
 };
 
+static struct mfd_cell misc_cell = {
+	.name		= PM8XXX_MISC_DEV_NAME,
+	.id		= 1,
+};
+
 static struct mfd_cell debugfs_cell = {
 	.name		= "pm8xxx-debug",
 	.id		= 1,
@@ -315,6 +249,17 @@
 		goto bail;
 	}
 
+	if (pdata->misc_pdata) {
+		misc_cell.platform_data = pdata->misc_pdata;
+		misc_cell.pdata_size = sizeof(struct pm8xxx_misc_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &misc_cell, 1, NULL,
+				      irq_base);
+		if (rc) {
+			pr_err("Failed to add  misc subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
 	return rc;
 
 bail:
@@ -346,7 +291,6 @@
 
 	pm8901_drvdata.pm_chip_data = pmic;
 	platform_set_drvdata(pdev, &pm8901_drvdata);
-	pmic_chip = pmic;
 
 	/* Read PMIC chip revision */
 	rc = pm8901_readb(pmic->dev, PM8901_REG_REV, &pmic->revision);
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index eeca25a..4040c32 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -138,8 +138,7 @@
 	unsigned short ret = NR_SG;
 
 	if (host->is_sps_mode) {
-		if (NR_SG > MAX_NR_SG_SPS)
-			ret = MAX_NR_SG_SPS;
+		ret = SPS_MAX_DESCS;
 	} else { /* DMA or PIO mode */
 		if (NR_SG > MAX_NR_SG_DMA_PIO)
 			ret = MAX_NR_SG_DMA_PIO;
@@ -148,28 +147,6 @@
 	return ret;
 }
 
-static inline unsigned int msmsdcc_get_max_seg_size(struct msmsdcc_host *host)
-{
-	unsigned int max_seg_size;
-
-	/*
-	 * SPS BAM has limitation of max. number of descriptors.
-	 * max. # of descriptors = SPS_MAX_DESCS
-	 * each descriptor can point to SPS_MAX_DESC_SIZE (16KB)
-	 * So (nr_sg * max_seg_size) should be limited to the
-	 * max. size that all of the descriptors can point to.
-	 * i.e., (nr_sg * max_seg_size) = (SPS_MAX_DESCS * SPS_MAX_DESC_SIZE).
-	 */
-	if (host->is_sps_mode) {
-		max_seg_size = (SPS_MAX_DESCS * SPS_MAX_DESC_SIZE) /
-			msmsdcc_get_nr_sg(host);
-	} else { /* DMA or PIO mode */
-		max_seg_size = MMC_MAX_REQ_SIZE;
-	}
-
-	return max_seg_size;
-}
-
 #ifdef CONFIG_MMC_MSM_SPS_SUPPORT
 static int msmsdcc_sps_reset_ep(struct msmsdcc_host *host,
 				struct msmsdcc_sps_ep_conn_data *ep);
@@ -4009,7 +3986,7 @@
 	mmc->max_blk_count = MMC_MAX_BLK_CNT;
 
 	mmc->max_req_size = MMC_MAX_REQ_SIZE;
-	mmc->max_seg_size = msmsdcc_get_max_seg_size(host);
+	mmc->max_seg_size = mmc->max_req_size;
 
 	writel_relaxed(0, host->base + MMCIMASK0);
 	writel_relaxed(MCI_CLEAR_STATIC_MASK, host->base + MMCICLEAR);
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index a8332e51..d128984 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -242,8 +242,6 @@
 /* Each descriptor is of length 8 bytes */
 #define SPS_MAX_DESC_LENGTH	8
 #define SPS_MAX_DESCS		(SPS_MAX_DESC_FIFO_SIZE / SPS_MAX_DESC_LENGTH)
-#define SPS_MAX_SG_DESCS	(MAX_SG_SIZE / SPS_MAX_DESC_SIZE)
-#define MAX_NR_SG_SPS		(SPS_MAX_DESCS / SPS_MAX_SG_DESCS)
 
 /*
  * DMA limitations
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 85d8a08..74562bc 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -52,6 +52,26 @@
 	PM_BMS_MAX_INTS,
 };
 
+struct pm8921_soc_params {
+	uint16_t	ocv_for_rbatt_raw;
+	uint16_t	vsense_for_rbatt_raw;
+	uint16_t	vbatt_for_rbatt_raw;
+	uint16_t	last_good_ocv_raw;
+	int		cc;
+
+	int		ocv_for_rbatt_uv;
+	int		vsense_for_rbatt_uv;
+	int		vbatt_for_rbatt_uv;
+	int		last_good_ocv_uv;
+};
+
+/**
+ * struct pm8921_bms_chip -
+ * @bms_output_lock:	lock to prevent concurrent bms reads
+ * @bms_100_lock:	lock to prevent concurrent updates to values that force
+ *			100% charge
+ *
+ */
 struct pm8921_bms_chip {
 	struct device		*dev;
 	struct dentry		*dent;
@@ -77,6 +97,7 @@
 	unsigned int		pmic_bms_irq[PM_BMS_MAX_INTS];
 	DECLARE_BITMAP(enabled_irqs, PM_BMS_MAX_INTS);
 	spinlock_t		bms_output_lock;
+	spinlock_t		bms_100_lock;
 	struct single_row_lut	*adjusted_fcc_temp_lut;
 	unsigned int		charging_began;
 	unsigned int		start_percent;
@@ -84,6 +105,7 @@
 
 	uint16_t		ocv_reading_at_100;
 	int			cc_reading_at_100;
+	int			max_voltage_uv;
 };
 
 static struct pm8921_bms_chip *the_chip;
@@ -129,6 +151,31 @@
 static int bms_fake_battery;
 module_param(bms_fake_battery, int, 0644);
 
+/* bms_start_XXX and bms_end_XXX are read only */
+static int bms_start_percent;
+static int bms_start_ocv_uv;
+static int bms_start_cc_mah;
+static int bms_end_percent;
+static int bms_end_ocv_uv;
+static int bms_end_cc_mah;
+
+static int bms_ro_ops_set(const char *val, const struct kernel_param *kp)
+{
+	return -EINVAL;
+}
+
+static struct kernel_param_ops bms_ro_param_ops = {
+	.set = bms_ro_ops_set,
+	.get = param_get_int,
+};
+module_param_cb(bms_start_percent, &bms_ro_param_ops, &bms_start_percent, 0644);
+module_param_cb(bms_start_ocv_uv, &bms_ro_param_ops, &bms_start_ocv_uv, 0644);
+module_param_cb(bms_start_cc_mah, &bms_ro_param_ops, &bms_start_cc_mah, 0644);
+
+module_param_cb(bms_end_percent, &bms_ro_param_ops, &bms_end_percent, 0644);
+module_param_cb(bms_end_ocv_uv, &bms_ro_param_ops, &bms_end_ocv_uv, 0644);
+module_param_cb(bms_end_cc_mah, &bms_ro_param_ops, &bms_end_cc_mah, 0644);
+
 static int interpolate_fcc(struct pm8921_bms_chip *chip, int batt_temp);
 static void readjust_fcc_table(void)
 {
@@ -314,9 +361,6 @@
 		return rc;
 	}
 
-	/* Output register data must be held (locked) while reading output */
-	WARN_ON(!(reg && HOLD_OREG_DATA));
-
 	rc = pm_bms_masked_write(chip, BMS_CONTROL, SELECT_OUTPUT_DATA,
 					type << SELECT_OUTPUT_TYPE_SHIFT);
 	if (rc) {
@@ -425,96 +469,28 @@
 	}
 	*result = msw << 16 | lsw;
 	pr_debug("msw = %04x lsw = %04x cc = %d\n", msw, lsw, *result);
-	*result = *result - chip->cc_reading_at_100;
 	pr_debug("cc = %d after subtracting %d\n",
 					*result, chip->cc_reading_at_100);
 	return 0;
 }
 
-static int read_last_good_ocv(struct pm8921_bms_chip *chip, uint *result)
+static int convert_vbatt_raw_to_uv(struct pm8921_bms_chip *chip,
+					uint16_t reading, int *result)
 {
-	int rc;
-	uint16_t reading;
-
-	rc = pm_bms_read_output_data(chip, LAST_GOOD_OCV_VALUE, &reading);
-	if (rc) {
-		pr_err("fail to read LAST_GOOD_OCV_VALUE rc = %d\n", rc);
-		return rc;
-	}
-
-	if (chip->ocv_reading_at_100 != reading) {
-		chip->ocv_reading_at_100 = 0;
-		chip->cc_reading_at_100 = 0;
-		*result = xoadc_reading_to_microvolt(reading);
-		pr_debug("raw = %04x ocv_uV = %u\n", reading, *result);
-		*result = adjust_xo_vbatt_reading(chip, *result);
-		pr_debug("after adj ocv_uV = %u\n", *result);
-		if (*result != 0)
-			last_ocv_uv = *result;
-	} else {
-		/*
-		 * force 100% ocv by selecting the highest profiled ocv
-		 * This is the first row last column entry in the ocv
-		 * lookup table
-		 */
-		int cols = chip->pc_temp_ocv_lut->cols;
-
-		pr_debug("Forcing max voltage %d\n",
-				1000 * chip->pc_temp_ocv_lut->ocv[0][cols-1]);
-		*result = 1000 * chip->pc_temp_ocv_lut->ocv[0][cols-1];
-	}
-
-	return 0;
-}
-
-static int read_vbatt_for_rbatt(struct pm8921_bms_chip *chip, uint *result)
-{
-	int rc;
-	uint16_t reading;
-
-	rc = pm_bms_read_output_data(chip, VBATT_FOR_RBATT, &reading);
-	if (rc) {
-		pr_err("fail to read VBATT_FOR_RBATT rc = %d\n", rc);
-		return rc;
-	}
 	*result = xoadc_reading_to_microvolt(reading);
-	pr_debug("raw = %04x vbatt_for_r_microV = %u\n", reading, *result);
+	pr_debug("raw = %04x vbatt = %u\n", reading, *result);
 	*result = adjust_xo_vbatt_reading(chip, *result);
-	pr_debug("after adj vbatt_for_r_uV = %u\n", *result);
+	pr_debug("after adj vbatt = %u\n", *result);
 	return 0;
 }
 
-static int read_vsense_for_rbatt(struct pm8921_bms_chip *chip, uint *result)
+static int convert_vsense_to_uv(struct pm8921_bms_chip *chip,
+					int16_t reading, int *result)
 {
-	int rc;
-	uint16_t reading;
-
-	rc = pm_bms_read_output_data(chip, VSENSE_FOR_RBATT, &reading);
-	if (rc) {
-		pr_err("fail to read VSENSE_FOR_RBATT rc = %d\n", rc);
-		return rc;
-	}
 	*result = pm8xxx_ccadc_reading_to_microvolt(chip->revision, reading);
-	pr_debug("raw = %04x vsense_for_r_uV = %u\n", reading, *result);
+	pr_debug("raw = %04x vsense = %d\n", reading, *result);
 	*result = pm8xxx_cc_adjust_for_gain(*result);
-	pr_debug("after adj vsense_for_r_uV = %u\n", *result);
-	return 0;
-}
-
-static int read_ocv_for_rbatt(struct pm8921_bms_chip *chip, uint *result)
-{
-	int rc;
-	uint16_t reading;
-
-	rc = pm_bms_read_output_data(chip, OCV_FOR_RBATT, &reading);
-	if (rc) {
-		pr_err("fail to read OCV_FOR_RBATT rc = %d\n", rc);
-		return rc;
-	}
-	*result = xoadc_reading_to_microvolt(reading);
-	pr_debug("raw = %04x ocv_for_r_uV = %u\n", reading, *result);
-	*result = adjust_xo_vbatt_reading(chip, *result);
-	pr_debug("after adj ocv_for_r_uV = %u\n", *result);
+	pr_debug("after adj vsense = %d\n", *result);
 	return 0;
 }
 
@@ -528,11 +504,8 @@
 		pr_err("fail to read VSENSE_AVG rc = %d\n", rc);
 		return rc;
 	}
-	*result = pm8xxx_ccadc_reading_to_microvolt(the_chip->revision,
-								reading);
-	pr_debug("raw = %04x vsense = %d\n", reading, *result);
-	*result = pm8xxx_cc_adjust_for_gain((s64)*result);
-	pr_debug("after adj vsense = %d\n", *result);
+
+	convert_vsense_to_uv(chip, reading, result);
 	return 0;
 }
 
@@ -790,37 +763,59 @@
 	return 100;
 }
 
-static int calculate_rbatt(struct pm8921_bms_chip *chip)
+static int read_soc_params_raw(struct pm8921_bms_chip *chip,
+				struct pm8921_soc_params *raw)
 {
-	int rc;
-	unsigned int ocv, vsense, vbatt, r_batt;
+	unsigned long flags;
 
-	rc = read_ocv_for_rbatt(chip, &ocv);
-	if (rc) {
-		pr_err("fail to read ocv_for_rbatt rc = %d\n", rc);
-		ocv = 0;
-	}
+	spin_lock_irqsave(&chip->bms_output_lock, flags);
+	pm_bms_lock_output_data(chip);
 
-	rc = read_vbatt_for_rbatt(chip, &vbatt);
-	if (rc) {
-		pr_err("fail to read vbatt_for_rbatt rc = %d\n", rc);
-		ocv = 0;
-	}
+	pm_bms_read_output_data(chip,
+			OCV_FOR_RBATT, &raw->ocv_for_rbatt_raw);
+	pm_bms_read_output_data(chip,
+			VBATT_FOR_RBATT, &raw->vbatt_for_rbatt_raw);
+	pm_bms_read_output_data(chip,
+			VSENSE_FOR_RBATT, &raw->vsense_for_rbatt_raw);
+	pm_bms_read_output_data(chip,
+			LAST_GOOD_OCV_VALUE, &raw->last_good_ocv_raw);
+	read_cc(chip, &raw->cc);
 
-	rc = read_vsense_for_rbatt(chip, &vsense);
-	if (rc) {
-		pr_err("fail to read vsense_for_rbatt rc = %d\n", rc);
-		ocv = 0;
-	}
-	if (ocv == 0
-		|| ocv == vbatt
-		|| vsense == 0) {
+	pm_bms_unlock_output_data(chip);
+	spin_unlock_irqrestore(&chip->bms_output_lock, flags);
+
+	convert_vbatt_raw_to_uv(chip,
+			raw->vbatt_for_rbatt_raw, &raw->vbatt_for_rbatt_uv);
+	convert_vbatt_raw_to_uv(chip,
+			raw->ocv_for_rbatt_raw, &raw->ocv_for_rbatt_uv);
+	convert_vbatt_raw_to_uv(chip,
+			raw->last_good_ocv_raw, &raw->last_good_ocv_uv);
+	convert_vsense_to_uv(chip,
+			raw->vsense_for_rbatt_raw, &raw->vsense_for_rbatt_uv);
+
+	if (raw->last_good_ocv_uv)
+		last_ocv_uv = raw->last_good_ocv_uv;
+
+	return 0;
+}
+
+static int calculate_rbatt(struct pm8921_bms_chip *chip,
+				struct pm8921_soc_params *raw)
+{
+	unsigned int  r_batt;
+
+	if (raw->ocv_for_rbatt_uv == 0
+		|| raw->ocv_for_rbatt_uv == raw->vbatt_for_rbatt_uv
+		|| raw->vsense_for_rbatt_raw == 0) {
 		pr_debug("rbatt readings unavailable ocv = %d, vbatt = %d,"
 					"vsen = %d\n",
-					ocv, vbatt, vsense);
+					raw->ocv_for_rbatt_uv,
+					raw->vbatt_for_rbatt_uv,
+					raw->vsense_for_rbatt_raw);
 		return -EINVAL;
 	}
-	r_batt = ((ocv - vbatt) * chip->r_sense) / vsense;
+	r_batt = ((raw->ocv_for_rbatt_uv - raw->vbatt_for_rbatt_uv)
+			* chip->r_sense) / raw->vsense_for_rbatt_uv;
 	last_rbatt = r_batt;
 	pr_debug("r_batt = %umilliOhms", r_batt);
 	return r_batt;
@@ -866,6 +861,7 @@
 static int adc_based_ocv(struct pm8921_bms_chip *chip, int *ocv)
 {
 	int vbatt, rbatt, ibatt, rc;
+	struct pm8921_soc_params raw;
 
 	rc = get_battery_uvolts(chip, &vbatt);
 	if (rc) {
@@ -879,7 +875,9 @@
 		return rc;
 	}
 
-	rbatt = calculate_rbatt(the_chip);
+	read_soc_params_raw(chip, &raw);
+
+	rbatt = calculate_rbatt(the_chip, &raw);
 	if (rbatt < 0)
 		rbatt = (last_rbatt < 0) ? DEFAULT_RBATT_MOHMS : last_rbatt;
 	*ocv = vbatt + ibatt * rbatt;
@@ -903,13 +901,13 @@
 	return pc;
 }
 
-static void calculate_cc_mah(struct pm8921_bms_chip *chip, int64_t *val,
+static void calculate_cc_mah(struct pm8921_bms_chip *chip, int cc, int *val,
 			int *coulumb_counter)
 {
-	int rc;
 	int64_t cc_voltage_uv, cc_uvh, cc_mah;
 
-	rc = read_cc(the_chip, coulumb_counter);
+	*coulumb_counter = cc;
+	*coulumb_counter -= chip->cc_reading_at_100;
 	cc_voltage_uv = (int64_t)*coulumb_counter;
 	cc_voltage_uv = cc_to_microvolt(chip, cc_voltage_uv);
 	cc_voltage_uv = pm8xxx_cc_adjust_for_gain(cc_voltage_uv);
@@ -921,11 +919,12 @@
 }
 
 static int calculate_unusable_charge_mah(struct pm8921_bms_chip *chip,
+					struct pm8921_soc_params *raw,
 				 int fcc, int batt_temp, int chargecycles)
 {
 	int rbatt, voltage_unusable_uv, pc_unusable;
 
-	rbatt = calculate_rbatt(chip);
+	rbatt = calculate_rbatt(chip, raw);
 	if (rbatt < 0) {
 		rbatt = (last_rbatt < 0) ? DEFAULT_RBATT_MOHMS : last_rbatt;
 		pr_debug("rbatt unavailable assuming %d\n", rbatt);
@@ -942,16 +941,26 @@
 }
 
 /* calculate remainging charge at the time of ocv */
-static int calculate_remaining_charge_mah(struct pm8921_bms_chip *chip, int fcc,
-						int batt_temp, int chargecycles)
+static int calculate_remaining_charge_mah(struct pm8921_bms_chip *chip,
+						struct pm8921_soc_params *raw,
+						int fcc, int batt_temp,
+						int chargecycles)
 {
-	int rc, ocv, pc;
+	int  ocv, pc;
 
 	/* calculate remainging charge */
 	ocv = 0;
-	rc = read_last_good_ocv(chip, &ocv);
-	if (rc)
-		pr_debug("failed to read ocv rc = %d\n", rc);
+	if (chip->ocv_reading_at_100 != raw->last_good_ocv_raw) {
+		chip->ocv_reading_at_100 = 0;
+		chip->cc_reading_at_100 = 0;
+		ocv = raw->last_good_ocv_uv;
+	} else {
+		/*
+		 * force 100% ocv by selecting the highest voltage the
+		 * battery could every reach
+		 */
+		ocv = chip->max_voltage_uv;
+	}
 
 	if (ocv == 0) {
 		ocv = last_ocv_uv;
@@ -964,11 +973,12 @@
 }
 
 static void calculate_charging_params(struct pm8921_bms_chip *chip,
+						struct pm8921_soc_params *raw,
 						int batt_temp, int chargecycles,
 						int *fcc,
 						int *unusable_charge,
 						int *remaining_charge,
-						int64_t *cc_mah)
+						int *cc_mah)
 {
 	int coulumb_counter;
 	unsigned long flags;
@@ -977,38 +987,35 @@
 	pr_debug("FCC = %umAh batt_temp = %d, cycles = %d",
 					*fcc, batt_temp, chargecycles);
 
-	/* fcc doesnt need to be read from hardware, lock the bms now */
-	spin_lock_irqsave(&chip->bms_output_lock, flags);
-	pm_bms_lock_output_data(chip);
-
-	*unusable_charge = calculate_unusable_charge_mah(chip, *fcc,
+	*unusable_charge = calculate_unusable_charge_mah(chip, raw, *fcc,
 						batt_temp, chargecycles);
 
 	pr_debug("UUC = %umAh", *unusable_charge);
 
+	spin_lock_irqsave(&chip->bms_100_lock, flags);
 	/* calculate remainging charge */
-	*remaining_charge = calculate_remaining_charge_mah(chip, *fcc,
+	*remaining_charge = calculate_remaining_charge_mah(chip, raw, *fcc,
 						batt_temp, chargecycles);
 	pr_debug("RC = %umAh\n", *remaining_charge);
 
 	/* calculate cc milli_volt_hour */
-	calculate_cc_mah(chip, cc_mah, &coulumb_counter);
-	pr_debug("cc_mah = %lldmAh cc = %d\n", *cc_mah, coulumb_counter);
-
-	pm_bms_unlock_output_data(chip);
-	spin_unlock_irqrestore(&chip->bms_output_lock, flags);
+	calculate_cc_mah(chip, raw->cc, cc_mah, &coulumb_counter);
+	pr_debug("cc_mah = %dmAh raw->cc = %x cc = %x\n",
+					*cc_mah, raw->cc, coulumb_counter);
+	spin_unlock_irqrestore(&chip->bms_100_lock, flags);
 }
 
 static int calculate_real_fcc(struct pm8921_bms_chip *chip,
-						int batt_temp, int chargecycles,
-						int *ret_fcc)
+				struct pm8921_soc_params *raw,
+				int batt_temp, int chargecycles,
+				int *ret_fcc)
 {
 	int fcc, unusable_charge;
 	int remaining_charge;
-	int64_t cc_mah;
+	int cc_mah;
 	int real_fcc;
 
-	calculate_charging_params(chip, batt_temp, chargecycles,
+	calculate_charging_params(chip, raw, batt_temp, chargecycles,
 						&fcc,
 						&unusable_charge,
 						&remaining_charge,
@@ -1016,7 +1023,7 @@
 
 	real_fcc = remaining_charge - cc_mah;
 	*ret_fcc = fcc;
-	pr_debug("real_fcc = %d, RC = %d CC = %lld fcc = %d\n",
+	pr_debug("real_fcc = %d, RC = %d CC = %d fcc = %d\n",
 			real_fcc, remaining_charge, cc_mah, fcc);
 	return real_fcc;
 }
@@ -1028,14 +1035,15 @@
  */
 #define BATTERY_POWER_SUPPLY_SOC	53
 static int calculate_state_of_charge(struct pm8921_bms_chip *chip,
-						int batt_temp, int chargecycles)
+					struct pm8921_soc_params *raw,
+					int batt_temp, int chargecycles)
 {
 	int remaining_usable_charge, fcc, unusable_charge;
 	int remaining_charge, soc;
 	int update_userspace = 1;
-	int64_t cc_mah;
+	int cc_mah;
 
-	calculate_charging_params(chip, batt_temp, chargecycles,
+	calculate_charging_params(chip, raw, batt_temp, chargecycles,
 						&fcc,
 						&unusable_charge,
 						&remaining_charge,
@@ -1057,7 +1065,7 @@
 
 	if (soc < 0) {
 		pr_err("bad rem_usb_chg = %d rem_chg %d,"
-				"cc_mah %lld, unusb_chg %d\n",
+				"cc_mah %d, unusb_chg %d\n",
 				remaining_usable_charge, remaining_charge,
 				cc_mah, unusable_charge);
 		pr_err("for bad rem_usb_chg last_ocv_uv = %d"
@@ -1209,6 +1217,7 @@
 {
 	int batt_temp, rc;
 	struct pm8xxx_adc_chan_result result;
+	struct pm8921_soc_params raw;
 
 	if (!the_chip) {
 		pr_err("called before initialization\n");
@@ -1224,7 +1233,10 @@
 	pr_debug("batt_temp phy = %lld meas = 0x%llx", result.physical,
 						result.measurement);
 	batt_temp = (int)result.physical;
-	return calculate_state_of_charge(the_chip,
+
+	read_soc_params_raw(the_chip, &raw);
+
+	return calculate_state_of_charge(the_chip, &raw,
 					batt_temp, last_chargecycles);
 }
 EXPORT_SYMBOL_GPL(pm8921_bms_get_percent_charge);
@@ -1254,7 +1266,28 @@
 
 void pm8921_bms_charging_began(void)
 {
-	the_chip->start_percent = pm8921_bms_get_percent_charge();
+	int batt_temp, coulumb_counter, rc;
+	struct pm8xxx_adc_chan_result result;
+	struct pm8921_soc_params raw;
+
+	rc = pm8xxx_adc_read(the_chip->batt_temp_channel, &result);
+	if (rc) {
+		pr_err("error reading adc channel = %d, rc = %d\n",
+				the_chip->batt_temp_channel, rc);
+		return;
+	}
+	pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
+						result.measurement);
+	batt_temp = (int)result.physical;
+
+	read_soc_params_raw(the_chip, &raw);
+
+	the_chip->start_percent = calculate_state_of_charge(the_chip, &raw,
+					batt_temp, last_chargecycles);
+	bms_start_percent = the_chip->start_percent;
+	bms_start_ocv_uv = raw.last_good_ocv_uv;
+	calculate_cc_mah(the_chip, raw.cc, &bms_start_cc_mah, &coulumb_counter);
+
 	pr_debug("start_percent = %u%%\n", the_chip->start_percent);
 }
 EXPORT_SYMBOL_GPL(pm8921_bms_charging_began);
@@ -1262,22 +1295,27 @@
 #define DELTA_FCC_PERCENT	3
 void pm8921_bms_charging_end(int is_battery_full)
 {
+	int batt_temp, coulumb_counter, rc;
+	struct pm8xxx_adc_chan_result result;
+	struct pm8921_soc_params raw;
+
+	rc = pm8xxx_adc_read(the_chip->batt_temp_channel, &result);
+	if (rc) {
+		pr_err("error reading adc channel = %d, rc = %d\n",
+				the_chip->batt_temp_channel, rc);
+		return;
+	}
+	pr_debug("batt_temp phy = %lld meas = 0x%llx\n", result.physical,
+						result.measurement);
+	batt_temp = (int)result.physical;
+
+	read_soc_params_raw(the_chip, &raw);
+
 	if (is_battery_full && the_chip != NULL) {
 		unsigned long flags;
-		int batt_temp, rc, cc_reading;
 		int fcc, new_fcc, delta_fcc;
-		struct pm8xxx_adc_chan_result result;
 
-		rc = pm8xxx_adc_read(the_chip->batt_temp_channel, &result);
-		if (rc) {
-			pr_err("error reading adc channel = %d, rc = %d\n",
-					the_chip->batt_temp_channel, rc);
-			goto charge_cycle_calculation;
-		}
-		pr_debug("batt_temp phy = %lld meas = 0x%llx", result.physical,
-							result.measurement);
-		batt_temp = (int)result.physical;
-		new_fcc = calculate_real_fcc(the_chip,
+		new_fcc = calculate_real_fcc(the_chip, &raw,
 						batt_temp, last_chargecycles,
 						&fcc);
 		delta_fcc = new_fcc - fcc;
@@ -1296,21 +1334,22 @@
 					delta_fcc, DELTA_FCC_PERCENT, fcc);
 		}
 
-		spin_lock_irqsave(&the_chip->bms_output_lock, flags);
-		pm_bms_lock_output_data(the_chip);
-		pm_bms_read_output_data(the_chip, LAST_GOOD_OCV_VALUE,
-						&the_chip->ocv_reading_at_100);
-		read_cc(the_chip, &cc_reading);
-		pm_bms_unlock_output_data(the_chip);
-		spin_unlock_irqrestore(&the_chip->bms_output_lock, flags);
-		the_chip->cc_reading_at_100 = cc_reading;
-		pr_debug("EOC ocv_reading = 0x%x cc_reading = %d\n",
+		spin_lock_irqsave(&the_chip->bms_100_lock, flags);
+		the_chip->ocv_reading_at_100 = raw.last_good_ocv_raw;
+		the_chip->cc_reading_at_100 = raw.cc;
+		spin_unlock_irqrestore(&the_chip->bms_100_lock, flags);
+		pr_debug("EOC ocv_reading = 0x%x cc = %d\n",
 				the_chip->ocv_reading_at_100,
 				the_chip->cc_reading_at_100);
 	}
 
-charge_cycle_calculation:
-	the_chip->end_percent = pm8921_bms_get_percent_charge();
+	the_chip->end_percent = calculate_state_of_charge(the_chip, &raw,
+					batt_temp, last_chargecycles);
+
+	bms_end_percent = the_chip->end_percent;
+	bms_end_ocv_uv = raw.last_good_ocv_uv;
+	calculate_cc_mah(the_chip, raw.cc, &bms_end_cc_mah, &coulumb_counter);
+
 	if (the_chip->end_percent > the_chip->start_percent) {
 		last_charge_increase =
 			the_chip->end_percent - the_chip->start_percent;
@@ -1472,24 +1511,26 @@
 
 static void check_initial_ocv(struct pm8921_bms_chip *chip)
 {
-	int ocv, rc;
+	int ocv_uv, rc;
+	int16_t ocv_raw;
 
 	/*
 	 * Check if a ocv is available in bms hw,
 	 * if not compute it here at boot time and save it
 	 * in the last_ocv_uv.
 	 */
-	ocv = 0;
-	rc = read_last_good_ocv(chip, &ocv);
-	if (rc || ocv == 0) {
-		rc = adc_based_ocv(chip, &ocv);
+	ocv_uv = 0;
+	pm_bms_read_output_data(chip, LAST_GOOD_OCV_VALUE, &ocv_raw);
+	rc = convert_vbatt_raw_to_uv(chip, ocv_raw, &ocv_uv);
+	if (rc || ocv_uv == 0) {
+		rc = adc_based_ocv(chip, &ocv_uv);
 		if (rc) {
-			pr_err("failed to read adc based ocv rc = %d\n", rc);
-			ocv = DEFAULT_OCV_MICROVOLTS;
+			pr_err("failed to read adc based ocv_uv rc = %d\n", rc);
+			ocv_uv = DEFAULT_OCV_MICROVOLTS;
 		}
-		last_ocv_uv = ocv;
+		last_ocv_uv = ocv_uv;
 	}
-	pr_debug("ocv = %d last_ocv_uv = %d\n", ocv, last_ocv_uv);
+	pr_debug("ocv_uv = %d last_ocv_uv = %d\n", ocv_uv, last_ocv_uv);
 }
 
 static int64_t read_battery_id(struct pm8921_bms_chip *chip)
@@ -1596,13 +1637,16 @@
 {
 	int param = (int)data;
 	int ret = 0;
+	struct pm8921_soc_params raw;
+
+	read_soc_params_raw(the_chip, &raw);
 
 	*val = 0;
 
 	/* global irq number passed in via data */
 	switch (param) {
 	case CALC_RBATT:
-		*val = calculate_rbatt(the_chip);
+		*val = calculate_rbatt(the_chip, &raw);
 		break;
 	case CALC_FCC:
 		*val = calculate_fcc(the_chip, test_batt_temp,
@@ -1613,7 +1657,7 @@
 							test_chargecycle);
 		break;
 	case CALC_SOC:
-		*val = calculate_state_of_charge(the_chip,
+		*val = calculate_state_of_charge(the_chip, &raw,
 					test_batt_temp, test_chargecycle);
 		break;
 	case CALIB_HKADC:
@@ -1637,6 +1681,9 @@
 {
 	int param = (int)data;
 	int ret = 0;
+	struct pm8921_soc_params raw;
+
+	read_soc_params_raw(the_chip, &raw);
 
 	*val = 0;
 
@@ -1644,19 +1691,19 @@
 	switch (param) {
 	case CC_MSB:
 	case CC_LSB:
-		read_cc(the_chip, (int *)val);
+		*val = raw.cc;
 		break;
 	case LAST_GOOD_OCV_VALUE:
-		read_last_good_ocv(the_chip, (uint *)val);
+		*val = raw.last_good_ocv_uv;
 		break;
 	case VBATT_FOR_RBATT:
-		read_vbatt_for_rbatt(the_chip, (uint *)val);
+		*val = raw.vbatt_for_rbatt_uv;
 		break;
 	case VSENSE_FOR_RBATT:
-		read_vsense_for_rbatt(the_chip, (uint *)val);
+		*val = raw.vsense_for_rbatt_uv;
 		break;
 	case OCV_FOR_RBATT:
-		read_ocv_for_rbatt(the_chip, (uint *)val);
+		*val = raw.ocv_for_rbatt_uv;
 		break;
 	case VSENSE_AVG:
 		read_vsense_avg(the_chip, (uint *)val);
@@ -1794,11 +1841,13 @@
 		return -ENOMEM;
 	}
 	spin_lock_init(&chip->bms_output_lock);
+	spin_lock_init(&chip->bms_100_lock);
 	chip->dev = &pdev->dev;
 	chip->r_sense = pdata->r_sense;
 	chip->i_test = pdata->i_test;
 	chip->v_failure = pdata->v_failure;
 	chip->calib_delay_ms = pdata->calib_delay_ms;
+	chip->max_voltage_uv = pdata->max_voltage_uv;
 	rc = set_battery_data(chip);
 	if (rc) {
 		pr_err("%s bad battery data %d\n", __func__, rc);
diff --git a/drivers/power/pm8xxx-ccadc.c b/drivers/power/pm8xxx-ccadc.c
index 5e0f8ec..e40677b 100644
--- a/drivers/power/pm8xxx-ccadc.c
+++ b/drivers/power/pm8xxx-ccadc.c
@@ -76,6 +76,7 @@
 
 static struct pm8xxx_ccadc_chip *the_chip;
 
+#ifdef DEBUG
 static s64 microvolt_to_ccadc_reading_v1(s64 uv)
 {
 	return div_s64(uv * CCADC_READING_RESOLUTION_D_V1,
@@ -98,6 +99,7 @@
 				microvolt_to_ccadc_reading_v1((s64)cc) :
 				microvolt_to_ccadc_reading_v2((s64)cc);
 }
+#endif
 
 static int cc_adjust_for_offset(u16 raw)
 {
@@ -328,7 +330,7 @@
 void pm8xxx_calib_ccadc(void)
 {
 	u8 data_msb, data_lsb, sec_cntrl;
-	int result_offset, voltage_offset, result_gain;
+	int result_offset, result_gain;
 	u16 result;
 	int i, rc;
 
@@ -385,26 +387,11 @@
 
 	result_offset = result_offset / SAMPLE_COUNT;
 
-	voltage_offset = pm8xxx_ccadc_reading_to_microvolt(the_chip->revision,
-			((s64)result_offset - CCADC_INTRINSIC_OFFSET));
 
-	pr_debug("offset result_offset = 0x%x, voltage = %d microVolts\n",
-				result_offset, voltage_offset);
-
-	/* Sanity Check */
-	if (voltage_offset > CCADC_MAX_0UV) {
-		pr_err("offset voltage = %d is huge limiting to %d\n",
-					voltage_offset, CCADC_MAX_0UV);
-		result_offset = CCADC_INTRINSIC_OFFSET
-			+ microvolt_to_ccadc_reading(the_chip,
-							(s64)CCADC_MAX_0UV);
-	} else if (voltage_offset < CCADC_MIN_0UV) {
-		pr_err("offset voltage = %d is too low limiting to %d\n",
-					voltage_offset, CCADC_MIN_0UV);
-		result_offset = CCADC_INTRINSIC_OFFSET
-			+ microvolt_to_ccadc_reading(the_chip,
-							(s64)CCADC_MIN_0UV);
-	}
+	pr_debug("offset result_offset = 0x%x, voltage = %llduV\n",
+			result_offset,
+			pm8xxx_ccadc_reading_to_microvolt(the_chip->revision,
+			((s64)result_offset - CCADC_INTRINSIC_OFFSET)));
 
 	the_chip->ccadc_offset = result_offset;
 	data_msb = the_chip->ccadc_offset >> 8;
@@ -474,22 +461,6 @@
 
 	pr_debug("gain result_gain = 0x%x, voltage = %d microVolts\n",
 					result_gain, the_chip->ccadc_gain_uv);
-	/* Sanity Check */
-	if (the_chip->ccadc_gain_uv > CCADC_MAX_25MV) {
-		pr_err("gain voltage = %d is huge limiting to %d\n",
-					the_chip->ccadc_gain_uv,
-					CCADC_MAX_25MV);
-		the_chip->ccadc_gain_uv = CCADC_MAX_25MV;
-		result_gain = result_offset +
-			microvolt_to_ccadc_reading(the_chip, CCADC_MAX_25MV);
-	} else if (the_chip->ccadc_gain_uv < CCADC_MIN_25MV) {
-		pr_err("gain voltage = %d is too low limiting to %d\n",
-					the_chip->ccadc_gain_uv,
-					CCADC_MIN_25MV);
-		the_chip->ccadc_gain_uv = CCADC_MIN_25MV;
-		result_gain = result_offset +
-			microvolt_to_ccadc_reading(the_chip, CCADC_MIN_25MV);
-	}
 
 	data_msb = result_gain >> 8;
 	data_lsb = result_gain;
diff --git a/drivers/thermal/msm_tsens.c b/drivers/thermal/msm_tsens.c
index d9a6efc..401ad88 100644
--- a/drivers/thermal/msm_tsens.c
+++ b/drivers/thermal/msm_tsens.c
@@ -511,7 +511,6 @@
 	reg = readl_relaxed(TSENS_CNTL_ADDR);
 	writel_relaxed(reg | TSENS_SW_RST, TSENS_CNTL_ADDR);
 	reg |= TSENS_SLP_CLK_ENA | TSENS_EN | (TSENS_MEASURE_PERIOD << 16) |
-		TSENS_LOWER_STATUS_CLR | TSENS_UPPER_STATUS_CLR |
 		TSENS_MIN_STATUS_MASK | TSENS_MAX_STATUS_MASK |
 		(((1 << TSENS_NUM_SENSORS) - 1) << 3);
 
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index af6f351..047df1a 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -373,12 +373,13 @@
 	char *name;
 	char buf[32], *b;
 	int once = 0, err = -1;
-	int (*notify)(uint32_t, const char *) = NULL;
+	int (*notify)(uint32_t, const char *);
 
 	strlcpy(buf, diag_clients, sizeof(buf));
 	b = strim(buf);
 
 	while (b) {
+		notify = NULL;
 		name = strsep(&b, ",");
 		/* Allow only first diag channel to update pid and serial no */
 		if (_android_dev->pdata && !once++)
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index ccfd2e3..f492143 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -515,9 +515,11 @@
 	int rc = 0;
 
 	dev->in_desc = ep_choose(cdev->gadget,
-			&hs_bulk_in_desc, &fs_bulk_in_desc);
+			(struct usb_endpoint_descriptor *)f->hs_descriptors[1],
+			(struct usb_endpoint_descriptor *)f->descriptors[1]);
 	dev->out_desc = ep_choose(cdev->gadget,
-			&hs_bulk_out_desc, &fs_bulk_out_desc);
+			(struct usb_endpoint_descriptor *)f->hs_descriptors[2],
+			(struct usb_endpoint_descriptor *)f->descriptors[2]);
 	dev->in->driver_data = dev;
 	rc = usb_ep_enable(dev->in, dev->in_desc);
 	if (rc) {
@@ -669,10 +671,13 @@
 
 		temp += scnprintf(buf + temp, PAGE_SIZE - temp,
 				"---Name: %s---\n"
+				"endpoints: %s, %s\n"
 				"dpkts_tolaptop: %lu\n"
 				"dpkts_tomodem:  %lu\n"
 				"pkts_tolaptop_pending: %u\n",
-				ch->name, ctxt->dpkts_tolaptop,
+				ch->name,
+				ctxt->in->name, ctxt->out->name,
+				ctxt->dpkts_tolaptop,
 				ctxt->dpkts_tomodem,
 				ctxt->dpkts_tolaptop_pending);
 	}
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 2466246..dc3ff26 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1653,6 +1653,12 @@
 		msm_otg_reset(otg);
 		msm_otg_init_sm(motg);
 		otg->state = OTG_STATE_B_IDLE;
+		if (!test_bit(B_SESS_VLD, &motg->inputs) &&
+				test_bit(ID, &motg->inputs)) {
+			pm_runtime_put_noidle(otg->dev);
+			pm_runtime_suspend(otg->dev);
+			break;
+		}
 		/* FALL THROUGH */
 	case OTG_STATE_B_IDLE:
 		dev_dbg(otg->dev, "OTG_STATE_B_IDLE state\n");
@@ -1978,7 +1984,7 @@
 {
 	struct msm_otg *motg = s->private;
 
-	seq_printf(s, chg_to_string(motg->chg_type));
+	seq_printf(s, "%s\n", chg_to_string(motg->chg_type));
 	return 0;
 }
 
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index e4fad5e..64fc6ea 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -406,6 +406,10 @@
 	portdata = usb_get_serial_port_data(port);
 	intfdata = serial->private;
 
+	/* explicitly set the driver mode to raw */
+	tty->raw = 0;
+	tty->real_raw = 0;
+
 	dbg("%s", __func__);
 
 	/* Start reading from the IN endpoint */
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 0f1d19b..559d8b4 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -3398,18 +3398,6 @@
 	HDMI_OUTP(0x002C, audio_info_ctrl_reg);
 }
 
-static void hdmi_msm_audio_ctrl_setup(boolean enabled, int delay)
-{
-	uint32 audio_pkt_ctrl_reg = 0;
-
-	/* Enable Packet Transmission */
-	audio_pkt_ctrl_reg |= enabled ? 0x00000001 : 0;
-	audio_pkt_ctrl_reg |= (delay << 4);
-
-	/* HDMI_AUDIO_PKT_CTRL1[0x0020] */
-	HDMI_OUTP(0x0020, audio_pkt_ctrl_reg);
-}
-
 static void hdmi_msm_en_gc_packet(boolean av_mute_is_requested)
 {
 	/* HDMI_GC[0x0040] */
@@ -3544,7 +3532,6 @@
 		}
 	}
 	hdmi_msm_audio_info_setup(FALSE, 0, 0, FALSE);
-	hdmi_msm_audio_ctrl_setup(FALSE, 0);
 	hdmi_msm_audio_acr_setup(FALSE, 0, 0, 0);
 	DEV_INFO("HDMI Audio: Disabled\n");
 	return 0;
diff --git a/include/linux/mfd/pm8xxx/pm8921-bms.h b/include/linux/mfd/pm8xxx/pm8921-bms.h
index 5d186df..630e90a 100644
--- a/include/linux/mfd/pm8xxx/pm8921-bms.h
+++ b/include/linux/mfd/pm8xxx/pm8921-bms.h
@@ -109,6 +109,7 @@
 	unsigned int			i_test;
 	unsigned int			v_failure;
 	unsigned int			calib_delay_ms;
+	unsigned int			max_voltage_uv;
 };
 
 #if defined(CONFIG_PM8921_BMS) || defined(CONFIG_PM8921_BMS_MODULE)
diff --git a/include/linux/mfd/pmic8901.h b/include/linux/mfd/pmic8901.h
index 932f8da..f5b34be 100644
--- a/include/linux/mfd/pmic8901.h
+++ b/include/linux/mfd/pmic8901.h
@@ -23,6 +23,7 @@
 #include <linux/mfd/pm8xxx/mpp.h>
 #include <linux/mfd/pm8xxx/tm.h>
 #include <linux/regulator/pmic8901-regulator.h>
+#include <linux/mfd/pm8xxx/misc.h>
 
 #define PM8901_IRQ_BLOCK_BIT(block, bit) ((block) * 8 + (bit))
 
@@ -37,19 +38,12 @@
 #define PM8901_TEMPSTAT_IRQ		PM8901_IRQ_BLOCK_BIT(6, 4)
 #define PM8901_OVERTEMP_IRQ		PM8901_IRQ_BLOCK_BIT(6, 5)
 
-struct pm8901_chip;
-
 struct pm8901_platform_data {
-	struct pm8xxx_irq_platform_data *irq_pdata;
-	struct pm8xxx_mpp_platform_data *mpp_pdata;
-	struct pm8901_vreg_pdata	*regulator_pdatas;
-	int				num_regulators;
+	struct pm8xxx_irq_platform_data		*irq_pdata;
+	struct pm8xxx_mpp_platform_data		*mpp_pdata;
+	struct pm8xxx_misc_platform_data	*misc_pdata;
+	struct pm8901_vreg_pdata		*regulator_pdatas;
+	int					num_regulators;
 };
 
-#ifdef CONFIG_PMIC8901
-int pm8901_reset_pwr_off(int reset);
-#else
-static inline int pm8901_reset_pwr_off(int reset) { return 0; }
-#endif
-
 #endif /* __PMIC8901_H__ */
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 4d5d697..a8b04df 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -159,6 +159,12 @@
 #define MSM_CAM_IOCTL_PICT_PP_DIVERT_DONE \
 	_IOR(MSM_CAM_IOCTL_MAGIC, 47, struct msm_pp_frame *)
 
+#define MSM_CAM_IOCTL_SENSOR_V4l2_S_CTRL \
+	_IOR(MSM_CAM_IOCTL_MAGIC, 48, struct v4l2_control)
+
+#define MSM_CAM_IOCTL_SENSOR_V4l2_QUERY_CTRL \
+	_IOR(MSM_CAM_IOCTL_MAGIC, 49, struct v4l2_queryctrl)
+
 struct msm_mctl_pp_cmd {
 	int32_t  id;
 	uint16_t length;
@@ -821,6 +827,73 @@
 #define CAMERA_EXPOSURE_COMPENSATION_LV3			-6
 #define CAMERA_EXPOSURE_COMPENSATION_LV4			-12
 
+enum msm_v4l2_saturation_level {
+	MSM_V4L2_SATURATION_L0,
+	MSM_V4L2_SATURATION_L1,
+	MSM_V4L2_SATURATION_L2,
+	MSM_V4L2_SATURATION_L3,
+	MSM_V4L2_SATURATION_L4,
+	MSM_V4L2_SATURATION_L5,
+	MSM_V4L2_SATURATION_L6,
+	MSM_V4L2_SATURATION_L7,
+	MSM_V4L2_SATURATION_L8,
+	MSM_V4L2_SATURATION_L9,
+	MSM_V4L2_SATURATION_L10,
+};
+
+enum msm_v4l2_exposure_level {
+	MSM_V4L2_EXPOSURE_N2,
+	MSM_V4L2_EXPOSURE_N1,
+	MSM_V4L2_EXPOSURE_D,
+	MSM_V4L2_EXPOSURE_P1,
+	MSM_V4L2_EXPOSURE_P2,
+};
+
+enum msm_v4l2_sharpness_level {
+	MSM_V4L2_SHARPNESS_L0,
+	MSM_V4L2_SHARPNESS_L1,
+	MSM_V4L2_SHARPNESS_L2,
+	MSM_V4L2_SHARPNESS_L3,
+	MSM_V4L2_SHARPNESS_L4,
+	MSM_V4L2_SHARPNESS_L5,
+	MSM_V4L2_SHARPNESS_L6,
+};
+
+enum msm_v4l2_expo_metering_mode {
+	MSM_V4L2_EXP_FRAME_AVERAGE,
+	MSM_V4L2_EXP_CENTER_WEIGHTED,
+	MSM_V4L2_EXP_SPOT_METERING,
+};
+
+enum msm_v4l2_iso_mode {
+	MSM_V4L2_ISO_AUTO = 0,
+	MSM_V4L2_ISO_DEBLUR,
+	MSM_V4L2_ISO_100,
+	MSM_V4L2_ISO_200,
+	MSM_V4L2_ISO_400,
+	MSM_V4L2_ISO_800,
+	MSM_V4L2_ISO_1600,
+};
+
+enum msm_v4l2_wb_mode {
+	MSM_V4L2_WB_MIN_MINUS_1,
+	MSM_V4L2_WB_AUTO = 1,
+	MSM_V4L2_WB_CUSTOM,
+	MSM_V4L2_WB_INCANDESCENT,
+	MSM_V4L2_WB_FLUORESCENT,
+	MSM_V4L2_WB_DAYLIGHT,
+	MSM_V4L2_WB_CLOUDY_DAYLIGHT,
+	MSM_V4L2_WB_TWILIGHT,
+	MSM_V4L2_WB_SHADE,
+	MSM_V4L2_WB_OFF,
+};
+
+enum msm_v4l2_power_line_frequency {
+	MSM_V4L2_POWER_LINE_OFF,
+	MSM_V4L2_POWER_LINE_60HZ,
+	MSM_V4L2_POWER_LINE_50HZ,
+	MSM_V4L2_POWER_LINE_AUTO,
+};
 
 struct sensor_pict_fps {
 	uint16_t prevfps;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 13d9b71..45aa228 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2708,6 +2708,11 @@
 			ie->data.ssp_mode = (ev->features[0] & 0x01);
 
 		conn->ssp_mode = (ev->features[0] & 0x01);
+		/*In case if remote device ssp supported/2.0 device
+		reduce the security level to MEDIUM if it is HIGH*/
+		if (!conn->ssp_mode &&
+			(conn->pending_sec_level == BT_SECURITY_HIGH))
+			conn->pending_sec_level = BT_SECURITY_MEDIUM;
 	}
 
 	if (conn->state != BT_CONFIG)
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index b254cd8..9a076d6 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -118,7 +118,7 @@
 
 
 /* Track ASM playback & capture sessions of DAI */
-static int fe_dai_map[MSM_FRONTEND_DAI_MAX][2] = {
+static int fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = {
 	/* MULTIMEDIA1 */
 	{INVALID_SESSION, INVALID_SESSION},
 	/* MULTIMEDIA2 */
@@ -158,6 +158,12 @@
 	int i, session_type, path_type, port_type;
 	struct route_payload payload;
 
+	if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
+		/* bad ID assigned in machine driver */
+		pr_err("%s: bad MM ID\n", __func__);
+		return;
+	}
+
 	if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
 		session_type = SESSION_TYPE_RX;
 		path_type = ADM_PATH_PLAYBACK;
@@ -200,6 +206,12 @@
 {
 	int i, port_type, session_type;
 
+	if (fedai_id > MSM_FRONTEND_DAI_MM_MAX_ID) {
+		/* bad ID assigned in machine driver */
+		pr_err("%s: bad MM ID\n", __func__);
+		return;
+	}
+
 	if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) {
 		port_type = MSM_AFE_PORT_TYPE_RX;
 		session_type = SESSION_TYPE_RX;
@@ -229,6 +241,12 @@
 
 	pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
 
+	if (val > MSM_FRONTEND_DAI_MM_MAX_ID) {
+		/* recheck FE ID in the mixer control defined in this file */
+		pr_err("%s: bad MM ID\n", __func__);
+		return;
+	}
+
 	if (afe_get_port_type(msm_bedais[reg].port_id) ==
 		MSM_AFE_PORT_TYPE_RX) {
 		session_type = SESSION_TYPE_RX;
@@ -1253,6 +1271,11 @@
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	unsigned int be_id = rtd->dai_link->be_id;
 
+	if (be_id >= MSM_BACKEND_DAI_MAX) {
+		pr_err("%s: unexpected be_id %d\n", __func__, be_id);
+		return -EINVAL;
+	}
+
 	mutex_lock(&routing_lock);
 	msm_bedais[be_id].hw_params = params;
 	mutex_unlock(&routing_lock);
@@ -1278,7 +1301,7 @@
 
 	mutex_lock(&routing_lock);
 
-	for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MAX) {
+	for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_MAX_ID) {
 		if (fe_dai_map[i][session_type] != INVALID_SESSION)
 			adm_close(bedai->port_id);
 	}
@@ -1332,7 +1355,7 @@
 	 */
 	bedai->active = 1;
 
-	for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MAX) {
+	for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_MAX_ID) {
 		if (fe_dai_map[i][session_type] != INVALID_SESSION) {
 			adm_open(bedai->port_id, path_type,
 				params_rate(bedai->hw_params),
diff --git a/sound/soc/msm/msm-pcm-routing.h b/sound/soc/msm/msm-pcm-routing.h
index b7fc82a..b3a8210 100644
--- a/sound/soc/msm/msm-pcm-routing.h
+++ b/sound/soc/msm/msm-pcm-routing.h
@@ -27,6 +27,12 @@
 #define LPASS_BE_AUXPCM_RX "(Backend) AUX_PCM_RX"
 #define LPASS_BE_AUXPCM_TX "(Backend) AUX_PCM_TX"
 
+/* For multimedia front-ends, asm session is allocated dynamically.
+ * Hence, asm session/multimedia front-end mapping has to be maintained.
+ * Due to this reason, additional multimedia front-end must be placed before
+ * non-multimedia front-ends.
+ */
+
 enum {
 	MSM_FRONTEND_DAI_MULTIMEDIA1 = 0,
 	MSM_FRONTEND_DAI_MULTIMEDIA2,
@@ -39,6 +45,9 @@
 	MSM_FRONTEND_DAI_MAX,
 };
 
+#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA4 + 1)
+#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA4
+
 enum {
 	MSM_BACKEND_DAI_PRI_I2S_RX = 0,
 	MSM_BACKEND_DAI_PRI_I2S_TX,