Merge "mfd: pm8xxx-misc: add pm8xxx_usb_id_pullup API" into msm-3.0
diff --git a/Documentation/genlock.txt b/Documentation/genlock.txt
index d3a44e2..6f24a76 100644
--- a/Documentation/genlock.txt
+++ b/Documentation/genlock.txt
@@ -82,15 +82,13 @@
 Release a handle.
 
 * struct genlock * genlock_create_lock(struct genlock_handle *)
-Create a new lock and attach it to the handle.
+Create a new lock and attach it to the handle.  Once a lock is attached to a
+handle it stays attached until the handle is destroyed.
 
 * struct genlock * genlock_attach_lock(struct genlock_handle *handle, int fd)
 Given a valid file descriptor, get the lock associated with it and attach it to
 the handle.
 
-* void genlock_release_lock(struct genlock_handle *)
-Release a lock attached to a handle.
-
 * int genlock_lock(struct genlock_handle *, int op, int flags, u32 timeout)
 Lock or unlock the lock attached to the handle. A zero timeout value will
 be treated just like if the GENOCK_NOBLOCK flag is passed; if the lock
@@ -155,7 +153,4 @@
 -EINVAL if a zero timeout is passed, or -ETIMEDOUT if the timeout expires.
 
 * GENLOCK_IOC_RELEASE
-Use this to release an existing lock. This is useful if you wish to attach a
-different lock to the same handle. You do not need to call this under normal
-circumstances; when the handle is closed the reference to the lock is released.
-No data is passed from the user for this ioctl.
+This ioctl has been deprecated.  Do not use.
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index 3421fa1..a708fbc 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -33,6 +33,7 @@
 CONFIG_ARCH_MSMCOPPER=y
 CONFIG_MSM_KRAIT_TBB_ABORT_HANDLER=y
 # CONFIG_MSM_STACKED_MEMORY is not set
+CONFIG_KERNEL_PMEM_EBI_REGION=y
 CONFIG_CPU_HAS_L2_PMU=y
 # CONFIG_MSM_FIQ_SUPPORT is not set
 # CONFIG_MSM_PROC_COMM is not set
@@ -99,6 +100,8 @@
 # CONFIG_BATTERY_MSM is not set
 # CONFIG_HWMON is not set
 # CONFIG_MFD_SUPPORT is not set
+CONFIG_ION=y
+CONFIG_ION_MSM=y
 # CONFIG_HID_SUPPORT is not set
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_CI13XXX_MSM=y
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index fc1d81a..76ff09c 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -201,6 +201,7 @@
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=y
 CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 3cf01a1..3ddb0c9 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -201,6 +201,7 @@
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=y
 CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index a872cdc..07aeb32 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -257,6 +257,7 @@
 CONFIG_KEYBOARD_GPIO=y
 CONFIG_KEYBOARD_PMIC8XXX=y
 CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_XPAD=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
 CONFIG_TOUCHSCREEN_CYTTSP_I2C=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 3337d06..47736ea 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -258,6 +258,7 @@
 CONFIG_KEYBOARD_GPIO=y
 CONFIG_KEYBOARD_PMIC8XXX=y
 CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_XPAD=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
 CONFIG_TOUCHSCREEN_CYTTSP_I2C=y
diff --git a/arch/arm/include/asm/fiq.h b/arch/arm/include/asm/fiq.h
index d493d0b..ec4b8b8 100644
--- a/arch/arm/include/asm/fiq.h
+++ b/arch/arm/include/asm/fiq.h
@@ -33,11 +33,22 @@
 	void *dev_id;
 };
 
+#ifdef CONFIG_FIQ
 extern int claim_fiq(struct fiq_handler *f);
 extern void release_fiq(struct fiq_handler *f);
 extern void set_fiq_handler(void *start, unsigned int length);
 extern void enable_fiq(int fiq);
 extern void disable_fiq(int fiq);
+#else
+static inline int claim_fiq(struct fiq_handler *f)
+{
+	return 0;
+}
+static inline void release_fiq(struct fiq_handler *f) { }
+static inline void set_fiq_handler(void *start, unsigned int length) { }
+static inline void enable_fiq(int fiq) { }
+static inline void disable_fiq(int fiq) { }
+#endif
 
 /* helpers defined in fiqasm.S: */
 extern void __set_fiq_regs(unsigned long const *regs);
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 32b4a99..0cec5f2 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -222,6 +222,7 @@
 	select MSM_SCM if SMP
 	select MSM_GPIOMUX
 	select MULTI_IRQ_HANDLER
+	select MSM_MULTIMEDIA_USE_ION
 
 config ARCH_FSM9XXX
 	bool "FSM9XXX"
@@ -763,7 +764,7 @@
 config KERNEL_PMEM_EBI_REGION
 	bool "Enable in-kernel PMEM region for EBI"
 	default y if ARCH_MSM8X60
-	depends on ANDROID_PMEM && (ARCH_MSM8X60 || ARCH_MSM8960)
+	depends on ANDROID_PMEM && (ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_MSMCOPPER)
 	help
 	   Enable the in-kernel PMEM allocator to use EBI memory.
 
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index a3ed7ab..6581619 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -222,11 +222,11 @@
 obj-$(CONFIG_MACH_MSM7X27_SURF) += board-msm7x27.o devices-msm7x27.o
 obj-$(CONFIG_MACH_MSM7X27_FFA) += board-msm7x27.o devices-msm7x27.o
 obj-$(CONFIG_ARCH_MSM7X27A) += clock-pcom-lookup.o devices-msm7x27a.o
-obj-$(CONFIG_MACH_MSM7X27A_RUMI3) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
-obj-$(CONFIG_MACH_MSM7X27A_SURF) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
-obj-$(CONFIG_MACH_MSM7X27A_FFA) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
-obj-$(CONFIG_MACH_MSM7627A_QRD1) += board-qrd7627a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
-obj-$(CONFIG_MACH_MSM7627A_EVB) += board-qrd7627a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o
+obj-$(CONFIG_MACH_MSM7X27A_RUMI3) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
+obj-$(CONFIG_MACH_MSM7X27A_SURF) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
+obj-$(CONFIG_MACH_MSM7X27A_FFA) += board-msm7x27a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
+obj-$(CONFIG_MACH_MSM7627A_QRD1) += board-qrd7627a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
+obj-$(CONFIG_MACH_MSM7627A_EVB) += board-qrd7627a.o board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o board-msm7627a-display.o board-msm7627a-wlan.o
 obj-$(CONFIG_ARCH_MSM8625) += devices-msm7x27a.o clock-pcom-lookup.o
 obj-$(CONFIG_MACH_MSM8625_RUMI3) += board-msm7x27a.o
 obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o memory_topology.o
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index fa82e34..05c5a2b 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -1795,7 +1795,7 @@
 	if (bam_tx_pipe == NULL) {
 		pr_err("%s: tx alloc endpoint failed\n", __func__);
 		ret = -ENOMEM;
-		goto register_bam_failed;
+		goto tx_alloc_endpoint_failed;
 	}
 	ret = sps_get_config(bam_tx_pipe, &tx_connection);
 	if (ret) {
@@ -1815,7 +1815,7 @@
 	if (tx_desc_mem_buf.base == NULL) {
 		pr_err("%s: tx memory alloc failed\n", __func__);
 		ret = -ENOMEM;
-		goto tx_mem_failed;
+		goto tx_get_config_failed;
 	}
 	tx_desc_mem_buf.phys_base = dma_addr;
 	memset(tx_desc_mem_buf.base, 0x0, tx_desc_mem_buf.size);
@@ -1832,7 +1832,7 @@
 	if (bam_rx_pipe == NULL) {
 		pr_err("%s: rx alloc endpoint failed\n", __func__);
 		ret = -ENOMEM;
-		goto tx_connect_failed;
+		goto rx_alloc_endpoint_failed;
 	}
 	ret = sps_get_config(bam_rx_pipe, &rx_connection);
 	if (ret) {
@@ -1901,15 +1901,16 @@
 	dma_free_coherent(NULL, rx_desc_mem_buf.size, rx_desc_mem_buf.base,
 				rx_desc_mem_buf.phys_base);
 rx_mem_failed:
-	sps_disconnect(bam_tx_pipe);
 rx_get_config_failed:
 	sps_free_endpoint(bam_rx_pipe);
+rx_alloc_endpoint_failed:
+	sps_disconnect(bam_tx_pipe);
 tx_connect_failed:
 	dma_free_coherent(NULL, tx_desc_mem_buf.size, tx_desc_mem_buf.base,
 				tx_desc_mem_buf.phys_base);
 tx_get_config_failed:
 	sps_free_endpoint(bam_tx_pipe);
-tx_mem_failed:
+tx_alloc_endpoint_failed:
 	sps_deregister_bam_device(h);
 	/*
 	 * sps_deregister_bam_device() calls iounmap.  calling iounmap on the
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index f30f0bf..cd84722 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -13,9 +13,9 @@
 
 #include <asm/mach-types.h>
 #include <linux/i2c.h>
+#include <linux/gpio.h>
 #include <mach/board.h>
 #include <mach/msm_bus_board.h>
-#include <mach/gpio.h>
 #include <mach/gpiomux.h>
 
 #include "devices.h"
@@ -157,19 +157,6 @@
 
 #ifdef CONFIG_MSM_CAMERA
 
-static uint16_t msm_cam_gpio_2d_tbl[] = {
-	5, /*CAMIF_MCLK*/
-	10, /*CAMIF_I2C_DATA*/
-	11, /*CAMIF_I2C_CLK*/
-};
-
-static struct msm_camera_gpio_conf gpio_conf = {
-	.cam_gpiomux_conf_tbl = apq8064_cam_2d_configs,
-	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(apq8064_cam_2d_configs),
-	.cam_gpio_tbl = msm_cam_gpio_2d_tbl,
-	.cam_gpio_tbl_size = ARRAY_SIZE(msm_cam_gpio_2d_tbl),
-};
-
 static struct msm_bus_vectors cam_init_vectors[] = {
 	{
 		.src = MSM_BUS_MASTER_VFE,
@@ -306,19 +293,57 @@
 
 static struct msm_camera_device_platform_data msm_camera_csi_device_data[] = {
 	{
-		.ioclk.mclk_clk_rate = 24000000,
-		.ioclk.vfe_clk_rate  = 228570000,
 		.csid_core = 0,
+		.is_csiphy = 1,
+		.is_csid   = 1,
+		.is_ispif  = 1,
+		.is_vpe    = 1,
 		.cam_bus_scale_table = &cam_bus_client_pdata,
 	},
 	{
-		.ioclk.mclk_clk_rate = 24000000,
-		.ioclk.vfe_clk_rate  = 228570000,
 		.csid_core = 1,
+		.is_csiphy = 1,
+		.is_csid   = 1,
+		.is_ispif  = 1,
+		.is_vpe    = 1,
 		.cam_bus_scale_table = &cam_bus_client_pdata,
 	},
 };
 
+static struct camera_vreg_t msm_8064_back_cam_vreg[] = {
+	{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+	{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+	{"cam_vio", REG_LDO, 1800000, 1800000, 16000},
+	{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+	{"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
+};
+
+static struct gpio apq8064_common_cam_gpio[] = {
+	{5, GPIOF_DIR_IN, "CAMIF_MCLK"},
+	{20, GPIOF_DIR_IN, "CAMIF_I2C_DATA"},
+	{21, GPIOF_DIR_IN, "CAMIF_I2C_CLK"},
+};
+
+static struct gpio apq8064_back_cam_gpio[] = {
+	{107, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct msm_gpio_set_tbl apq8064_back_cam_gpio_set_tbl[] = {
+	{107, GPIOF_OUT_INIT_LOW, 1000},
+	{107, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
+static struct msm_camera_gpio_conf apq8064_back_cam_gpio_conf = {
+	.cam_gpiomux_conf_tbl = apq8064_cam_2d_configs,
+	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(apq8064_cam_2d_configs),
+	.cam_gpio_common_tbl = apq8064_common_cam_gpio,
+	.cam_gpio_common_tbl_size = ARRAY_SIZE(apq8064_common_cam_gpio),
+	.cam_gpio_req_tbl = apq8064_back_cam_gpio,
+	.cam_gpio_req_tbl_size = ARRAY_SIZE(apq8064_back_cam_gpio),
+	.cam_gpio_set_tbl = apq8064_back_cam_gpio_set_tbl,
+	.cam_gpio_set_tbl_size = ARRAY_SIZE(apq8064_back_cam_gpio_set_tbl),
+};
+
 #ifdef CONFIG_IMX074
 static struct msm_camera_sensor_flash_data flash_imx074 = {
 	.flash_type	= MSM_CAMERA_FLASH_NONE,
@@ -326,10 +351,9 @@
 
 static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
 	.mount_angle	= 90,
-	.sensor_reset	= 107,
-	.sensor_pwd	= 85,
-	.vcm_pwd	= 0,
-	.vcm_enable	= 1,
+	.cam_vreg = msm_8064_back_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8064_back_cam_vreg),
+	.gpio_conf = &apq8064_back_cam_gpio_conf,
 };
 
 static struct msm_camera_sensor_info msm_camera_sensor_imx074_data = {
@@ -337,7 +361,6 @@
 	.pdata	= &msm_camera_csi_device_data[0],
 	.flash_data	= &flash_imx074,
 	.sensor_platform_info = &sensor_board_info_imx074,
-	.gpio_conf = &gpio_conf,
 	.csi_if	= 1,
 	.camera_type = BACK_CAMERA_2D,
 };
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 02fff0b..29b8afb 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1159,10 +1159,10 @@
 
 static void __init apq8064_clock_init(void)
 {
-	if (machine_is_apq8064_sim())
-		msm_clock_init(&apq8064_clock_init_data);
-	else
+	if (machine_is_apq8064_rumi3())
 		msm_clock_init(&apq8064_dummy_clock_init_data);
+	else
+		msm_clock_init(&apq8064_clock_init_data);
 }
 
 static void __init apq8064_common_init(void)
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
index a32699f..30c912e 100644
--- a/arch/arm/mach-msm/board-8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -12,9 +12,9 @@
  */
 
 #include <asm/mach-types.h>
+#include <linux/gpio.h>
 #include <mach/board.h>
 #include <mach/msm_bus_board.h>
-#include <mach/gpio.h>
 #include <mach/gpiomux.h>
 #include "devices.h"
 #include "board-8930.h"
@@ -95,7 +95,7 @@
 };
 
 
-static struct msm_gpiomux_config msm8960_cam_common_configs[] = {
+static struct msm_gpiomux_config msm8930_cam_common_configs[] = {
 	{
 		.gpio = 2,
 		.settings = {
@@ -140,7 +140,7 @@
 	},
 };
 
-static struct msm_gpiomux_config msm8960_cam_2d_configs[] = {
+static struct msm_gpiomux_config msm8930_cam_2d_configs[] = {
 	{
 		.gpio = 18,
 		.settings = {
@@ -172,20 +172,6 @@
 };
 
 #ifdef CONFIG_MSM_CAMERA
-
-static uint16_t msm_cam_gpio_2d_tbl[] = {
-	5, /*CAMIF_MCLK*/
-	20, /*CAMIF_I2C_DATA*/
-	21, /*CAMIF_I2C_CLK*/
-};
-
-static struct msm_camera_gpio_conf gpio_conf = {
-	.cam_gpiomux_conf_tbl = msm8960_cam_2d_configs,
-	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8960_cam_2d_configs),
-	.cam_gpio_tbl = msm_cam_gpio_2d_tbl,
-	.cam_gpio_tbl_size = ARRAY_SIZE(msm_cam_gpio_2d_tbl),
-};
-
 #define VFE_CAMIF_TIMER1_GPIO 2
 #define VFE_CAMIF_TIMER2_GPIO 3
 #define VFE_CAMIF_TIMER3_GPIO_INT 4
@@ -345,8 +331,6 @@
 
 static struct msm_camera_device_platform_data msm_camera_csi_device_data[] = {
 	{
-		.ioclk.mclk_clk_rate = 24000000,
-		.ioclk.vfe_clk_rate  = 228570000,
 		.csid_core = 0,
 		.is_csiphy = 1,
 		.is_csid   = 1,
@@ -355,8 +339,6 @@
 		.cam_bus_scale_table = &cam_bus_client_pdata,
 	},
 	{
-		.ioclk.mclk_clk_rate = 24000000,
-		.ioclk.vfe_clk_rate  = 228570000,
 		.csid_core = 1,
 		.is_csiphy = 1,
 		.is_csid   = 1,
@@ -366,6 +348,67 @@
 	},
 };
 
+static struct camera_vreg_t msm_8930_back_cam_vreg[] = {
+	{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+	{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+	{"cam_vio", REG_LDO, 1800000, 1800000, 16000},
+	{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+	{"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
+};
+
+static struct camera_vreg_t msm_8930_front_cam_vreg[] = {
+	{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+	{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+	{"cam_vio", REG_LDO, 1800000, 1800000, 16000},
+	{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+};
+
+static struct gpio msm8930_common_cam_gpio[] = {
+	{5, GPIOF_DIR_IN, "CAMIF_MCLK"},
+	{20, GPIOF_DIR_IN, "CAMIF_I2C_DATA"},
+	{21, GPIOF_DIR_IN, "CAMIF_I2C_CLK"},
+};
+
+static struct gpio msm8930_front_cam_gpio[] = {
+	{76, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct gpio msm8930_back_cam_gpio[] = {
+	{107, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct msm_gpio_set_tbl msm8930_front_cam_gpio_set_tbl[] = {
+	{76, GPIOF_OUT_INIT_LOW, 1000},
+	{76, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
+static struct msm_gpio_set_tbl msm8930_back_cam_gpio_set_tbl[] = {
+	{107, GPIOF_OUT_INIT_LOW, 1000},
+	{107, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
+static struct msm_camera_gpio_conf msm_8930_front_cam_gpio_conf = {
+	.cam_gpiomux_conf_tbl = msm8930_cam_2d_configs,
+	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8930_cam_2d_configs),
+	.cam_gpio_common_tbl = msm8930_common_cam_gpio,
+	.cam_gpio_common_tbl_size = ARRAY_SIZE(msm8930_common_cam_gpio),
+	.cam_gpio_req_tbl = msm8930_front_cam_gpio,
+	.cam_gpio_req_tbl_size = ARRAY_SIZE(msm8930_front_cam_gpio),
+	.cam_gpio_set_tbl = msm8930_front_cam_gpio_set_tbl,
+	.cam_gpio_set_tbl_size = ARRAY_SIZE(msm8930_front_cam_gpio_set_tbl),
+};
+
+static struct msm_camera_gpio_conf msm_8930_back_cam_gpio_conf = {
+	.cam_gpiomux_conf_tbl = msm8930_cam_2d_configs,
+	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8930_cam_2d_configs),
+	.cam_gpio_common_tbl = msm8930_common_cam_gpio,
+	.cam_gpio_common_tbl_size = ARRAY_SIZE(msm8930_common_cam_gpio),
+	.cam_gpio_req_tbl = msm8930_back_cam_gpio,
+	.cam_gpio_req_tbl_size = ARRAY_SIZE(msm8930_back_cam_gpio),
+	.cam_gpio_set_tbl = msm8930_back_cam_gpio_set_tbl,
+	.cam_gpio_set_tbl_size = ARRAY_SIZE(msm8930_back_cam_gpio_set_tbl),
+};
+
 #ifdef CONFIG_IMX074_ACT
 static struct i2c_board_info imx074_actuator_i2c_info = {
 	I2C_BOARD_INFO("imx074_act", 0x11),
@@ -389,10 +432,9 @@
 
 static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
 	.mount_angle	= 90,
-	.sensor_reset	= 107,
-	.sensor_pwd	= 85,
-	.vcm_pwd	= 0,
-	.vcm_enable	= 1,
+	.cam_vreg = msm_8930_back_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8930_back_cam_vreg),
+	.gpio_conf = &msm_8930_back_cam_gpio_conf,
 };
 
 static struct msm_camera_sensor_info msm_camera_sensor_imx074_data = {
@@ -401,7 +443,6 @@
 	.flash_data	= &flash_imx074,
 	.strobe_flash_data = &strobe_flash_xenon,
 	.sensor_platform_info = &sensor_board_info_imx074,
-	.gpio_conf = &gpio_conf,
 	.csi_if	= 1,
 	.camera_type = BACK_CAMERA_2D,
 #ifdef CONFIG_IMX074_ACT
@@ -417,7 +458,9 @@
 
 static struct msm_camera_sensor_platform_info sensor_board_info_mt9m114 = {
 	.mount_angle = 90,
-	.sensor_reset = 107,
+	.cam_vreg = msm_8930_back_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8930_back_cam_vreg),
+	.gpio_conf = &msm_8930_back_cam_gpio_conf,
 };
 
 static struct msm_camera_sensor_info msm_camera_sensor_mt9m114_data = {
@@ -425,7 +468,6 @@
 	.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,
 };
@@ -438,10 +480,9 @@
 
 static struct msm_camera_sensor_platform_info sensor_board_info_ov2720 = {
 	.mount_angle	= 0,
-	.sensor_reset	= 76,
-	.sensor_pwd	= 85,
-	.vcm_pwd	= 0,
-	.vcm_enable	= 1,
+	.cam_vreg = msm_8930_front_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8930_front_cam_vreg),
+	.gpio_conf = &msm_8930_front_cam_gpio_conf,
 };
 
 static struct msm_camera_sensor_info msm_camera_sensor_ov2720_data = {
@@ -449,7 +490,6 @@
 	.pdata	= &msm_camera_csi_device_data[1],
 	.flash_data	= &flash_ov2720,
 	.sensor_platform_info = &sensor_board_info_ov2720,
-	.gpio_conf = &gpio_conf,
 	.csi_if	= 1,
 	.camera_type = FRONT_CAMERA_2D,
 };
@@ -457,8 +497,8 @@
 
 void __init msm8930_init_cam(void)
 {
-	msm_gpiomux_install(msm8960_cam_common_configs,
-			ARRAY_SIZE(msm8960_cam_common_configs));
+	msm_gpiomux_install(msm8930_cam_common_configs,
+			ARRAY_SIZE(msm8930_cam_common_configs));
 
 	platform_device_register(&msm8960_device_csiphy0);
 	platform_device_register(&msm8960_device_csiphy1);
diff --git a/arch/arm/mach-msm/board-8930-regulator.c b/arch/arm/mach-msm/board-8930-regulator.c
index c652238..6c01764 100644
--- a/arch/arm/mach-msm/board-8930-regulator.c
+++ b/arch/arm/mach-msm/board-8930-regulator.c
@@ -70,6 +70,9 @@
 	REGULATOR_SUPPLY("iris_vddio",		"wcnss_wlan.0"),
 	REGULATOR_SUPPLY("riva_vddpx",		"wcnss_wlan.0"),
 	REGULATOR_SUPPLY("sdc_vccq",		"msm_sdcc.1"),
+	REGULATOR_SUPPLY("VDDIO_CDC",		"sitar-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_TX",		"sitar-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_RX",		"sitar-slim"),
 };
 VREG_CONSUMERS(L12) = {
 	REGULATOR_SUPPLY("8038_l12",		NULL),
@@ -97,6 +100,8 @@
 };
 VREG_CONSUMERS(L20) = {
 	REGULATOR_SUPPLY("8038_l20",		NULL),
+	REGULATOR_SUPPLY("VDDD_CDC_D",		"sitar-slim"),
+	REGULATOR_SUPPLY("CDC_VDDA_A_1P2V",	"sitar-slim"),
 };
 VREG_CONSUMERS(L21) = {
 	REGULATOR_SUPPLY("8038_l21",		NULL),
@@ -138,6 +143,7 @@
 };
 VREG_CONSUMERS(S4) = {
 	REGULATOR_SUPPLY("8038_s4",		NULL),
+	REGULATOR_SUPPLY("CDC_VDD_CP",		"sitar-slim"),
 };
 VREG_CONSUMERS(S5) = {
 	REGULATOR_SUPPLY("8038_s5",		NULL),
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index 2ad92b3..2995679 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -12,9 +12,9 @@
  */
 
 #include <asm/mach-types.h>
+#include <linux/gpio.h>
 #include <mach/board.h>
 #include <mach/msm_bus_board.h>
-#include <mach/gpio.h>
 #include <mach/gpiomux.h>
 #include "devices.h"
 #include "board-8960.h"
@@ -181,20 +181,6 @@
 };
 
 #ifdef CONFIG_MSM_CAMERA
-
-static uint16_t msm_cam_gpio_2d_tbl[] = {
-	5, /*CAMIF_MCLK*/
-	20, /*CAMIF_I2C_DATA*/
-	21, /*CAMIF_I2C_CLK*/
-};
-
-static struct msm_camera_gpio_conf gpio_conf = {
-	.cam_gpiomux_conf_tbl = msm8960_cam_2d_configs,
-	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8960_cam_2d_configs),
-	.cam_gpio_tbl = msm_cam_gpio_2d_tbl,
-	.cam_gpio_tbl_size = ARRAY_SIZE(msm_cam_gpio_2d_tbl),
-};
-
 #define VFE_CAMIF_TIMER1_GPIO 2
 #define VFE_CAMIF_TIMER2_GPIO 3
 #define VFE_CAMIF_TIMER3_GPIO_INT 4
@@ -350,8 +336,6 @@
 
 static struct msm_camera_device_platform_data msm_camera_csi_device_data[] = {
 	{
-		.ioclk.mclk_clk_rate = 24000000,
-		.ioclk.vfe_clk_rate  = 228570000,
 		.csid_core = 0,
 		.is_csiphy = 1,
 		.is_csid   = 1,
@@ -360,8 +344,6 @@
 		.cam_bus_scale_table = &cam_bus_client_pdata,
 	},
 	{
-		.ioclk.mclk_clk_rate = 24000000,
-		.ioclk.vfe_clk_rate  = 228570000,
 		.csid_core = 1,
 		.is_csiphy = 1,
 		.is_csid   = 1,
@@ -371,6 +353,67 @@
 	},
 };
 
+static struct camera_vreg_t msm_8960_back_cam_vreg[] = {
+	{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+	{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+	{"cam_vio", REG_VS, 0, 0, 0},
+	{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+	{"cam_vaf", REG_LDO, 2800000, 2800000, 300000},
+};
+
+static struct camera_vreg_t msm_8960_front_cam_vreg[] = {
+	{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+	{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+	{"cam_vio", REG_VS, 0, 0, 0},
+	{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+};
+
+static struct gpio msm8960_common_cam_gpio[] = {
+	{5, GPIOF_DIR_IN, "CAMIF_MCLK"},
+	{20, GPIOF_DIR_IN, "CAMIF_I2C_DATA"},
+	{21, GPIOF_DIR_IN, "CAMIF_I2C_CLK"},
+};
+
+static struct gpio msm8960_front_cam_gpio[] = {
+	{76, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct gpio msm8960_back_cam_gpio[] = {
+	{107, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct msm_gpio_set_tbl msm8960_front_cam_gpio_set_tbl[] = {
+	{76, GPIOF_OUT_INIT_LOW, 1000},
+	{76, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
+static struct msm_gpio_set_tbl msm8960_back_cam_gpio_set_tbl[] = {
+	{107, GPIOF_OUT_INIT_LOW, 1000},
+	{107, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
+static struct msm_camera_gpio_conf msm_8960_front_cam_gpio_conf = {
+	.cam_gpiomux_conf_tbl = msm8960_cam_2d_configs,
+	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8960_cam_2d_configs),
+	.cam_gpio_common_tbl = msm8960_common_cam_gpio,
+	.cam_gpio_common_tbl_size = ARRAY_SIZE(msm8960_common_cam_gpio),
+	.cam_gpio_req_tbl = msm8960_front_cam_gpio,
+	.cam_gpio_req_tbl_size = ARRAY_SIZE(msm8960_front_cam_gpio),
+	.cam_gpio_set_tbl = msm8960_front_cam_gpio_set_tbl,
+	.cam_gpio_set_tbl_size = ARRAY_SIZE(msm8960_front_cam_gpio_set_tbl),
+};
+
+static struct msm_camera_gpio_conf msm_8960_back_cam_gpio_conf = {
+	.cam_gpiomux_conf_tbl = msm8960_cam_2d_configs,
+	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8960_cam_2d_configs),
+	.cam_gpio_common_tbl = msm8960_common_cam_gpio,
+	.cam_gpio_common_tbl_size = ARRAY_SIZE(msm8960_common_cam_gpio),
+	.cam_gpio_req_tbl = msm8960_back_cam_gpio,
+	.cam_gpio_req_tbl_size = ARRAY_SIZE(msm8960_back_cam_gpio),
+	.cam_gpio_set_tbl = msm8960_back_cam_gpio_set_tbl,
+	.cam_gpio_set_tbl_size = ARRAY_SIZE(msm8960_back_cam_gpio_set_tbl),
+};
+
 #ifdef CONFIG_IMX074_ACT
 static struct i2c_board_info imx074_actuator_i2c_info = {
 	I2C_BOARD_INFO("imx074_act", 0x11),
@@ -394,10 +437,9 @@
 
 static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
 	.mount_angle	= 90,
-	.sensor_reset	= 107,
-	.sensor_pwd	= 85,
-	.vcm_pwd	= 0,
-	.vcm_enable	= 1,
+	.cam_vreg = msm_8960_back_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8960_back_cam_vreg),
+	.gpio_conf = &msm_8960_back_cam_gpio_conf,
 };
 
 static struct msm_camera_sensor_info msm_camera_sensor_imx074_data = {
@@ -406,7 +448,6 @@
 	.flash_data	= &flash_imx074,
 	.strobe_flash_data = &strobe_flash_xenon,
 	.sensor_platform_info = &sensor_board_info_imx074,
-	.gpio_conf = &gpio_conf,
 	.csi_if	= 1,
 	.camera_type = BACK_CAMERA_2D,
 #ifdef CONFIG_IMX074_ACT
@@ -422,7 +463,9 @@
 
 static struct msm_camera_sensor_platform_info sensor_board_info_mt9m114 = {
 	.mount_angle = 90,
-	.sensor_reset = 107,
+	.cam_vreg = msm_8960_back_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8960_back_cam_vreg),
+	.gpio_conf = &msm_8960_back_cam_gpio_conf,
 };
 
 static struct msm_camera_sensor_info msm_camera_sensor_mt9m114_data = {
@@ -430,7 +473,6 @@
 	.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,
 };
@@ -443,10 +485,9 @@
 
 static struct msm_camera_sensor_platform_info sensor_board_info_ov2720 = {
 	.mount_angle	= 0,
-	.sensor_reset	= 76,
-	.sensor_pwd	= 85,
-	.vcm_pwd	= 0,
-	.vcm_enable	= 1,
+	.cam_vreg = msm_8960_front_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8960_front_cam_vreg),
+	.gpio_conf = &msm_8960_front_cam_gpio_conf,
 };
 
 static struct msm_camera_sensor_info msm_camera_sensor_ov2720_data = {
@@ -454,16 +495,36 @@
 	.pdata	= &msm_camera_csi_device_data[1],
 	.flash_data	= &flash_ov2720,
 	.sensor_platform_info = &sensor_board_info_ov2720,
-	.gpio_conf = &gpio_conf,
 	.csi_if	= 1,
 	.camera_type = FRONT_CAMERA_2D,
 };
 #endif
 
-static struct msm8960_privacy_light_cfg privacy_light_info = {
-	.mpp = PM8921_MPP_PM_TO_SYS(12),
+static struct pm8xxx_mpp_config_data privacy_light_on_config = {
+	.type		= PM8XXX_MPP_TYPE_SINK,
+	.level		= PM8XXX_MPP_CS_OUT_5MA,
+	.control	= PM8XXX_MPP_CS_CTRL_MPP_LOW_EN,
 };
 
+static struct pm8xxx_mpp_config_data privacy_light_off_config = {
+	.type		= PM8XXX_MPP_TYPE_SINK,
+	.level		= PM8XXX_MPP_CS_OUT_5MA,
+	.control	= PM8XXX_MPP_CS_CTRL_DISABLE,
+};
+
+static int32_t msm_camera_8960_ext_power_ctrl(int enable)
+{
+	int rc = 0;
+	if (enable) {
+		rc = pm8xxx_mpp_config(PM8921_MPP_PM_TO_SYS(12),
+			&privacy_light_on_config);
+	} else {
+		rc = pm8xxx_mpp_config(PM8921_MPP_PM_TO_SYS(12),
+			&privacy_light_off_config);
+	}
+	return rc;
+}
+
 void __init msm8960_init_cam(void)
 {
 	msm_gpiomux_install(msm8960_cam_common_configs,
@@ -488,9 +549,8 @@
 		s_info = &msm_camera_sensor_imx074_data;
 		s_info->sensor_platform_info->mount_angle = 180;
 		s_info = &msm_camera_sensor_ov2720_data;
-		s_info->sensor_platform_info->privacy_light = 1;
-		s_info->sensor_platform_info->privacy_light_info =
-			&privacy_light_info;
+		s_info->sensor_platform_info->ext_power_ctrl =
+			msm_camera_8960_ext_power_ctrl;
 	}
 
 	platform_device_register(&msm8960_device_csiphy0);
diff --git a/arch/arm/mach-msm/board-copper.c b/arch/arm/mach-msm/board-copper.c
index c89aee5..1bfb759 100644
--- a/arch/arm/mach-msm/board-copper.c
+++ b/arch/arm/mach-msm/board-copper.c
@@ -19,14 +19,192 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/of_irq.h>
+#ifdef CONFIG_ION_MSM
+#include <linux/ion.h>
+#endif
+#include <linux/memory.h>
+#ifdef CONFIG_ANDROID_PMEM
+#include <linux/android_pmem.h>
+#endif
 #include <asm/mach/map.h>
 #include <asm/hardware/gic.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/gpiomux.h>
 #include <mach/msm_iomap.h>
+#ifdef CONFIG_ION_MSM
+#include <mach/ion.h>
+#endif
+#include <mach/msm_memtypes.h>
 #include "clock.h"
 
+#define MSM_KERNEL_EBI1_MEM_SIZE	0x280000
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+#define MSM_ION_SF_SIZE 0x4000000 /* 64 Mbytes */
+#else
+#define MSM_ION_SF_SIZE 0x2800000 /* 40 Mbytes */
+#endif
+#define MSM_ION_MM_FW_SIZE	0x200000 /* (2MB) */
+#define MSM_ION_MM_SIZE		0x7800000 /* (120MB) */
+#define MSM_ION_QSECOM_SIZE	0x100000 /* (1MB) */
+#define MSM_ION_MFC_SIZE	SZ_8K
+#define MSM_ION_AUDIO_SIZE	0x2B4000
+#define MSM_ION_HEAP_NUM	8
+
+#ifdef CONFIG_KERNEL_PMEM_EBI_REGION
+static unsigned kernel_ebi1_mem_size = MSM_KERNEL_EBI1_MEM_SIZE;
+static int __init kernel_ebi1_mem_size_setup(char *p)
+{
+	kernel_ebi1_mem_size = memparse(p, NULL);
+	return 0;
+}
+early_param("kernel_ebi1_mem_size", kernel_ebi1_mem_size_setup);
+#endif
+
+static struct memtype_reserve msm_copper_reserve_table[] __initdata = {
+	[MEMTYPE_SMI] = {
+	},
+	[MEMTYPE_EBI0] = {
+		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
+	},
+	[MEMTYPE_EBI1] = {
+		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
+	},
+};
+
+static int msm_copper_paddr_to_memtype(unsigned int paddr)
+{
+	return MEMTYPE_EBI1;
+}
+
+#ifdef CONFIG_ION_MSM
+static struct ion_cp_heap_pdata cp_mm_ion_pdata = {
+	.permission_type = IPT_TYPE_MM_CARVEOUT,
+	.align = PAGE_SIZE,
+};
+
+static struct ion_cp_heap_pdata cp_mfc_ion_pdata = {
+	.permission_type = IPT_TYPE_MFC_SHAREDMEM,
+	.align = PAGE_SIZE,
+};
+
+static struct ion_co_heap_pdata co_ion_pdata = {
+	.adjacent_mem_id = INVALID_HEAP_ID,
+	.align = PAGE_SIZE,
+};
+
+static struct ion_co_heap_pdata fw_co_ion_pdata = {
+	.adjacent_mem_id = ION_CP_MM_HEAP_ID,
+	.align = SZ_128K,
+};
+
+static struct ion_platform_data ion_pdata = {
+	.nr = MSM_ION_HEAP_NUM,
+	.heaps = {
+		{
+			.id	= ION_SYSTEM_HEAP_ID,
+			.type	= ION_HEAP_TYPE_SYSTEM,
+			.name	= ION_VMALLOC_HEAP_NAME,
+		},
+		{
+			.id	= ION_SF_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_SF_HEAP_NAME,
+			.size	= MSM_ION_SF_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &co_ion_pdata,
+		},
+		{
+			.id	= ION_CP_MM_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CP,
+			.name	= ION_MM_HEAP_NAME,
+			.size	= MSM_ION_MM_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &cp_mm_ion_pdata,
+		},
+		{
+			.id	= ION_MM_FIRMWARE_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_MM_FIRMWARE_HEAP_NAME,
+			.size	= MSM_ION_MM_FW_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &fw_co_ion_pdata,
+		},
+		{
+			.id	= ION_CP_MFC_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CP,
+			.name	= ION_MFC_HEAP_NAME,
+			.size	= MSM_ION_MFC_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &cp_mfc_ion_pdata,
+		},
+		{
+			.id	= ION_IOMMU_HEAP_ID,
+			.type	= ION_HEAP_TYPE_IOMMU,
+			.name	= ION_IOMMU_HEAP_NAME,
+		},
+		{
+			.id	= ION_QSECOM_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_QSECOM_HEAP_NAME,
+			.size	= MSM_ION_QSECOM_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &co_ion_pdata,
+		},
+		{
+			.id	= ION_AUDIO_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_AUDIO_HEAP_NAME,
+			.size	= MSM_ION_AUDIO_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &co_ion_pdata,
+		},
+	}
+};
+
+static struct platform_device ion_dev = {
+	.name = "ion-msm",
+	.id = 1,
+	.dev = { .platform_data = &ion_pdata },
+};
+
+static void reserve_ion_memory(void)
+{
+	msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_SIZE;
+	msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_FW_SIZE;
+	msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
+	msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MFC_SIZE;
+	msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_QSECOM_SIZE;
+	msm_copper_reserve_table[MEMTYPE_EBI1].size += MSM_ION_AUDIO_SIZE;
+#ifdef CONFIG_KERNEL_PMEM_EBI_REGION
+	msm_copper_reserve_table[MEMTYPE_EBI1].size += kernel_ebi1_mem_size;
+#endif
+}
+#endif
+
+static void __init msm_copper_calculate_reserve_sizes(void)
+{
+#ifdef CONFIG_ION_MSM
+	reserve_ion_memory();
+#endif
+}
+
+static struct reserve_info msm_copper_reserve_info __initdata = {
+	.memtype_reserve_table = msm_copper_reserve_table,
+	.calculate_reserve_sizes = msm_copper_calculate_reserve_sizes,
+	.paddr_to_memtype = msm_copper_paddr_to_memtype,
+};
+
+static void __init msm_copper_early_memory(void)
+{
+	reserve_info = &msm_copper_reserve_info;
+}
+
+void __init msm_copper_reserve(void)
+{
+	msm_reserve();
+}
+
 static int __init gpiomux_init(void)
 {
 	int rc;
@@ -42,6 +220,9 @@
 
 void __init msm_copper_add_devices(void)
 {
+#ifdef CONFIG_ION_MSM
+	platform_device_register(&ion_dev);
+#endif
 }
 
 static struct of_device_id irq_match[] __initdata  = {
@@ -102,3 +283,8 @@
 
 	*adata = msm_copper_auxdata_lookup;
 }
+
+void __init msm_copper_very_early(void)
+{
+	msm_copper_early_memory();
+}
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
index 6c5f74a..51ca29d 100644
--- a/arch/arm/mach-msm/board-dt.c
+++ b/arch/arm/mach-msm/board-dt.c
@@ -90,6 +90,18 @@
 	NULL
 };
 
+static void __init msm_dt_reserve(void)
+{
+	if (early_machine_is_copper())
+		msm_copper_reserve();
+}
+
+static void __init msm_dt_init_very_early(void)
+{
+	if (early_machine_is_copper())
+		msm_copper_very_early();
+}
+
 DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
 	.map_io = msm_dt_map_io,
 	.init_irq = msm_dt_init_irq,
@@ -98,4 +110,6 @@
 	.timer = &msm_dt_timer,
 	.dt_compat = msm_dt_match,
 	.nr_irqs = -1,
+	.reserve = msm_dt_reserve,
+	.init_very_early = msm_dt_init_very_early,
 MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index 8c03d17..030c129 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -602,9 +602,6 @@
 		}
 	} else {
 		gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 1);
-
-		if (pmapp_disp_backlight_set_brightness(0))
-			pr_err("backlight set brightness failed\n");
 	}
 
 	rc = on ? regulator_bulk_enable(ARRAY_SIZE(regs_dsi), regs_dsi) :
diff --git a/arch/arm/mach-msm/board-msm7627a-wlan.c b/arch/arm/mach-msm/board-msm7627a-wlan.c
new file mode 100644
index 0000000..6df7626
--- /dev/null
+++ b/arch/arm/mach-msm/board-msm7627a-wlan.c
@@ -0,0 +1,368 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <asm/mach-types.h>
+#include <mach/rpc_pmapp.h>
+#include "board-msm7627a.h"
+#include "devices-msm7x2xa.h"
+#include "timer.h"
+
+#define GPIO_WLAN_3V3_EN 119
+static const char *id = "WLAN";
+
+enum {
+	WLAN_VREG_S3 = 0,
+	WLAN_VREG_L17,
+	WLAN_VREG_L19
+};
+
+struct wlan_vreg_info {
+	const char *vreg_id;
+	unsigned int level_min;
+	unsigned int level_max;
+	unsigned int pmapp_id;
+	unsigned int is_vreg_pin_controlled;
+	struct regulator *reg;
+};
+
+static struct wlan_vreg_info vreg_info[] = {
+	{"msme1",     1800000, 1800000, 2,  0, NULL},
+	{"bt",        3300000, 3300000, 21, 1, NULL},
+	{"wlan4",     1800000, 1800000, 23, 1, NULL}
+};
+
+int gpio_wlan_sys_rest_en = 134;
+static void gpio_wlan_config(void)
+{
+	if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb())
+		gpio_wlan_sys_rest_en = 124;
+}
+
+static unsigned int qrf6285_init_regs(void)
+{
+	struct regulator_bulk_data regs[ARRAY_SIZE(vreg_info)];
+	int i = 0, rc = 0;
+
+	for (i = 0; i < ARRAY_SIZE(regs); i++) {
+		regs[i].supply = vreg_info[i].vreg_id;
+		regs[i].min_uV = vreg_info[i].level_min;
+		regs[i].max_uV = vreg_info[i].level_max;
+	}
+
+	rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs), regs);
+	if (rc) {
+		pr_err("%s: could not get regulators: %d\n", __func__, rc);
+		goto out;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(regs); i++)
+		vreg_info[i].reg = regs[i].consumer;
+
+out:
+	return rc;
+}
+
+static unsigned int setup_wlan_gpio(bool on)
+{
+	int rc = 0;
+
+	if (on) {
+		rc = gpio_direction_output(gpio_wlan_sys_rest_en, 1);
+		msleep(100);
+	} else {
+		gpio_set_value_cansleep(gpio_wlan_sys_rest_en, 0);
+		rc = gpio_direction_input(gpio_wlan_sys_rest_en);
+		msleep(100);
+	}
+
+	if (rc)
+		pr_err("%s: WLAN sys_reset_en GPIO: Error", __func__);
+
+	return rc;
+}
+
+static unsigned int setup_wlan_clock(bool on)
+{
+	int rc = 0;
+
+	if (on) {
+		/* Vote for A0 clock */
+		rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_A0,
+					PMAPP_CLOCK_VOTE_ON);
+	} else {
+		/* Vote against A0 clock */
+		rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_A0,
+					 PMAPP_CLOCK_VOTE_OFF);
+	}
+
+	if (rc)
+		pr_err("%s: Configuring A0 clock for WLAN: Error", __func__);
+
+	return rc;
+}
+
+static unsigned int wlan_switch_regulators(int on)
+{
+	int rc = 0, index = 0;
+
+	if (machine_is_msm7627a_qrd1())
+		index = 2;
+
+	for ( ; index < ARRAY_SIZE(vreg_info); index++) {
+		if (on) {
+			rc = regulator_set_voltage(vreg_info[index].reg,
+						vreg_info[index].level_min,
+						vreg_info[index].level_max);
+			if (rc) {
+				pr_err("%s:%s set voltage failed %d\n",
+					__func__, vreg_info[index].vreg_id, rc);
+				goto reg_disable;
+			}
+
+			rc = regulator_enable(vreg_info[index].reg);
+			if (rc) {
+				pr_err("%s:%s vreg enable failed %d\n",
+					__func__, vreg_info[index].vreg_id, rc);
+				goto reg_disable;
+			}
+
+			if (vreg_info[index].is_vreg_pin_controlled) {
+				rc = pmapp_vreg_lpm_pincntrl_vote(id,
+						vreg_info[index].pmapp_id,
+						PMAPP_CLOCK_ID_A0, 1);
+				if (rc) {
+					pr_err("%s:%s pincntrl failed %d\n",
+						__func__,
+						vreg_info[index].vreg_id, rc);
+					goto pin_cnt_fail;
+				}
+			}
+		} else {
+			if (vreg_info[index].is_vreg_pin_controlled) {
+				rc = pmapp_vreg_lpm_pincntrl_vote(id,
+						vreg_info[index].pmapp_id,
+						PMAPP_CLOCK_ID_A0, 0);
+				if (rc) {
+					pr_err("%s:%s pincntrl failed %d\n",
+						__func__,
+						vreg_info[index].vreg_id, rc);
+					goto pin_cnt_fail;
+				}
+			}
+
+			rc = regulator_disable(vreg_info[index].reg);
+			if (rc) {
+				pr_err("%s:%s vreg disable failed %d\n",
+					__func__,
+					vreg_info[index].vreg_id, rc);
+				goto reg_disable;
+			}
+		}
+	}
+	return 0;
+pin_cnt_fail:
+	if (on)
+		regulator_disable(vreg_info[index].reg);
+reg_disable:
+	if (!machine_is_msm7627a_qrd1()) {
+		while (index) {
+			if (on) {
+				index--;
+				regulator_disable(vreg_info[index].reg);
+				regulator_put(vreg_info[index].reg);
+			}
+		}
+	}
+	return rc;
+}
+
+static unsigned int msm_AR600X_setup_power(bool on)
+{
+	int rc = 0;
+	static bool init_done;
+
+	if (unlikely(!init_done)) {
+		gpio_wlan_config();
+		rc = qrf6285_init_regs();
+		if (rc) {
+			pr_err("%s: qrf6285 init failed = %d\n", __func__, rc);
+			return rc;
+		} else {
+			init_done = true;
+		}
+	}
+
+	rc = wlan_switch_regulators(on);
+	if (rc) {
+		pr_err("%s: wlan_switch_regulators error = %d\n", __func__, rc);
+		goto out;
+	}
+
+	/* GPIO_WLAN_3V3_EN is only required for the QRD7627a */
+	if (machine_is_msm7627a_qrd1()) {
+		rc = gpio_tlmm_config(GPIO_CFG(GPIO_WLAN_3V3_EN, 0,
+					GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+					GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+		if (rc) {
+			pr_err("%s gpio_tlmm_config 119 failed,error = %d\n",
+				__func__, rc);
+			goto reg_disable;
+		}
+		gpio_set_value(GPIO_WLAN_3V3_EN, 1);
+	}
+
+	/*
+	 * gpio_wlan_sys_rest_en is not from the GPIO expander for QRD7627a,
+	 * EVB1.0 and QRD8625,so the below step is required for those devices.
+	 */
+	if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()) {
+		rc = gpio_tlmm_config(GPIO_CFG(gpio_wlan_sys_rest_en, 0,
+					GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+					GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+		if (rc) {
+			pr_err("%s gpio_tlmm_config 119 failed,error = %d\n",
+				__func__, rc);
+			goto qrd_gpio_fail;
+		}
+		gpio_set_value(gpio_wlan_sys_rest_en, 1);
+	} else {
+		rc = gpio_request(gpio_wlan_sys_rest_en, "WLAN_DEEP_SLEEP_N");
+		if (rc) {
+			pr_err("%s: WLAN sys_rest_en GPIO %d request failed %d\n",
+				__func__,
+				gpio_wlan_sys_rest_en, rc);
+			goto qrd_gpio_fail;
+		}
+		rc = setup_wlan_gpio(on);
+		if (rc) {
+			pr_err("%s: wlan_set_gpio = %d\n", __func__, rc);
+			goto gpio_fail;
+		}
+	}
+
+	/* Enable the A0 clock */
+	rc = setup_wlan_clock(on);
+	if (rc) {
+		pr_err("%s: setup_wlan_clock = %d\n", __func__, rc);
+		goto set_gpio_fail;
+	}
+
+	/* Configure A0 clock to be slave to WLAN_CLK_PWR_REQ */
+	rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_A0,
+				 PMAPP_CLOCK_VOTE_PIN_CTRL);
+	if (rc) {
+		pr_err("%s: Configuring A0 to Pin controllable failed %d\n",
+				__func__, rc);
+		goto set_clock_fail;
+	}
+
+	pr_info("WLAN power-up success\n");
+	return 0;
+set_clock_fail:
+	setup_wlan_clock(0);
+set_gpio_fail:
+	setup_wlan_gpio(0);
+gpio_fail:
+	gpio_free(gpio_wlan_sys_rest_en);
+qrd_gpio_fail:
+	gpio_free(GPIO_WLAN_3V3_EN);
+reg_disable:
+	wlan_switch_regulators(0);
+out:
+	pr_info("WLAN power-up failed\n");
+	return rc;
+}
+
+static unsigned int msm_AR600X_shutdown_power(bool on)
+{
+	int rc = 0;
+
+	/* Disable the A0 clock */
+	rc = setup_wlan_clock(on);
+	if (rc) {
+		pr_err("%s: setup_wlan_clock = %d\n", __func__, rc);
+		goto set_clock_fail;
+	}
+
+	/*
+	 * gpio_wlan_sys_rest_en is not from the GPIO expander for QRD7627a,
+	 * EVB1.0 and QRD8625,so the below step is required for those devices.
+	 */
+	if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()) {
+		rc = gpio_tlmm_config(GPIO_CFG(gpio_wlan_sys_rest_en, 0,
+					GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+					GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+		if (rc) {
+			pr_err("%s gpio_tlmm_config 119 failed,error = %d\n",
+				__func__, rc);
+			goto gpio_fail;
+		}
+		gpio_set_value(gpio_wlan_sys_rest_en, 0);
+	} else {
+		rc = setup_wlan_gpio(on);
+		if (rc) {
+			pr_err("%s: wlan_set_gpio = %d\n", __func__, rc);
+			goto set_gpio_fail;
+		}
+		gpio_free(gpio_wlan_sys_rest_en);
+	}
+
+	/* GPIO_WLAN_3V3_EN is only required for the QRD7627a */
+	if (machine_is_msm7627a_qrd1()) {
+		rc = gpio_tlmm_config(GPIO_CFG(GPIO_WLAN_3V3_EN, 0,
+					GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+					GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+		if (rc) {
+			pr_err("%s gpio_tlmm_config 119 failed,error = %d\n",
+				__func__, rc);
+			goto qrd_gpio_fail;
+		}
+		gpio_set_value(GPIO_WLAN_3V3_EN, 0);
+	}
+
+	rc = wlan_switch_regulators(on);
+	if (rc) {
+		pr_err("%s: wlan_switch_regulators error = %d\n",
+			__func__, rc);
+		goto reg_disable;
+	}
+
+	pr_info("WLAN power-down success\n");
+	return 0;
+set_clock_fail:
+	setup_wlan_clock(0);
+set_gpio_fail:
+	setup_wlan_gpio(0);
+gpio_fail:
+	gpio_free(gpio_wlan_sys_rest_en);
+qrd_gpio_fail:
+	gpio_free(GPIO_WLAN_3V3_EN);
+reg_disable:
+	wlan_switch_regulators(0);
+	pr_info("WLAN power-down failed\n");
+	return rc;
+}
+
+int  ar600x_wlan_power(bool on)
+{
+	if (on)
+		msm_AR600X_setup_power(on);
+	else
+		msm_AR600X_shutdown_power(on);
+
+	return 0;
+}
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 8b50c53..118798b 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -1071,6 +1071,7 @@
 #if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
 static int __init msm7x27a_init_ar6000pm(void)
 {
+	msm_wlan_ar6000_pm_device.dev.platform_data = &ar600x_wlan_power;
 	return platform_device_register(&msm_wlan_ar6000_pm_device);
 }
 #else
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index f7e908b..5052bb0 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -679,7 +679,6 @@
 #ifdef CONFIG_BT
 	&msm_bt_power_device,
 #endif
-	&msm_wlan_ar6000_pm_device,
 	&asoc_msm_pcm,
 	&asoc_msm_dai0,
 	&asoc_msm_dai1,
@@ -1011,6 +1010,12 @@
 	}
 }
 
+static int __init msm_qrd_init_ar6000pm(void)
+{
+	msm_wlan_ar6000_pm_device.dev.platform_data = &ar600x_wlan_power;
+	return platform_device_register(&msm_wlan_ar6000_pm_device);
+}
+
 #define UART1DM_RX_GPIO		45
 static void __init msm_qrd_init(void)
 {
@@ -1033,6 +1038,8 @@
 	platform_add_devices(qrd_common_devices,
 			ARRAY_SIZE(qrd_common_devices));
 
+	/* Ensure ar6000pm device is registered before MMC/SDC */
+	msm_qrd_init_ar6000pm();
 	msm7627a_init_mmc();
 
 #ifdef CONFIG_USB_EHCI_MSM_72K
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index e16cac5..a2abb25 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -4812,13 +4812,16 @@
 };
 
 static struct clk_lookup msm_clocks_8064[] = {
-	CLK_LOOKUP("cxo",		cxo_clk.c,		NULL),
-	CLK_LOOKUP("cxo",		cxo_clk.c,		"wcnss_wlan.0"),
-	CLK_LOOKUP("cxo",		cxo_clk.c,		"pil_riva"),
-	CLK_LOOKUP("pll2",		pll2_clk.c,		NULL),
-	CLK_LOOKUP("pll8",		pll8_clk.c,		NULL),
-	CLK_LOOKUP("pll4",		pll4_clk.c,		NULL),
-	CLK_LOOKUP("measure",		measure_clk.c,		"debug"),
+	CLK_LOOKUP("cxo",		cxo_clk.c,	NULL),
+	CLK_LOOKUP("cxo",		cxo_clk.c,	"wcnss_wlan.0"),
+	CLK_LOOKUP("cxo",		cxo_clk.c,	"pil_riva"),
+	CLK_LOOKUP("xo",		pxo_clk.c,	"pil_qdsp6v4.0"),
+	CLK_LOOKUP("xo",		cxo_clk.c,	"pil_qdsp6v4.1"),
+	CLK_LOOKUP("xo",		cxo_clk.c,	"pil_qdsp6v4.2"),
+	CLK_LOOKUP("pll2",		pll2_clk.c,	NULL),
+	CLK_LOOKUP("pll8",		pll8_clk.c,	NULL),
+	CLK_LOOKUP("pll4",		pll4_clk.c,	NULL),
+	CLK_LOOKUP("measure",		measure_clk.c,	"debug"),
 
 	CLK_DUMMY("bus_clk",		AFAB_CLK,	"msm_apps_fab", 0),
 	CLK_DUMMY("bus_a_clk",		AFAB_A_CLK,	"msm_apps_fab", 0),
@@ -5051,13 +5054,16 @@
 };
 
 static struct clk_lookup msm_clocks_8960_v1[] __initdata = {
-	CLK_LOOKUP("cxo",		cxo_clk.c,		NULL),
-	CLK_LOOKUP("cxo",		cxo_clk.c,		"wcnss_wlan.0"),
-	CLK_LOOKUP("cxo",		cxo_clk.c,		"pil_riva"),
-	CLK_LOOKUP("pll2",		pll2_clk.c,		NULL),
-	CLK_LOOKUP("pll8",		pll8_clk.c,		NULL),
-	CLK_LOOKUP("pll4",		pll4_clk.c,		NULL),
-	CLK_LOOKUP("measure",		measure_clk.c,		"debug"),
+	CLK_LOOKUP("cxo",		cxo_clk.c,	NULL),
+	CLK_LOOKUP("cxo",		cxo_clk.c,	"wcnss_wlan.0"),
+	CLK_LOOKUP("cxo",		cxo_clk.c,	"pil_riva"),
+	CLK_LOOKUP("xo",		pxo_clk.c,	"pil_qdsp6v4.0"),
+	CLK_LOOKUP("xo",		cxo_clk.c,	"pil_qdsp6v4.1"),
+	CLK_LOOKUP("xo",		cxo_clk.c,	"pil_qdsp6v4.2"),
+	CLK_LOOKUP("pll2",		pll2_clk.c,	NULL),
+	CLK_LOOKUP("pll8",		pll8_clk.c,	NULL),
+	CLK_LOOKUP("pll4",		pll4_clk.c,	NULL),
+	CLK_LOOKUP("measure",		measure_clk.c,	"debug"),
 
 	CLK_LOOKUP("bus_clk",		afab_clk.c,		"msm_apps_fab"),
 	CLK_LOOKUP("bus_a_clk",		afab_a_clk.c,		"msm_apps_fab"),
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 94fafda..17f5d01 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -3520,6 +3520,7 @@
 
 static struct clk_lookup msm_clocks_8x60[] = {
 	CLK_LOOKUP("cxo",		cxo_clk.c,	NULL),
+	CLK_LOOKUP("xo",		pxo_clk.c,	"pil_modem"),
 	CLK_LOOKUP("pll4",		pll4_clk.c,	"pil_qdsp6v3"),
 	CLK_LOOKUP("measure",		measure_clk.c,	"debug"),
 
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index 2d5ae78..1bb9c86 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -631,7 +631,8 @@
 			bank_info = &bank_masks->bank1_mask;
 
 		ns_mask = bank_info->ns_mask;
-		md_val = readl_relaxed(bank_info->md_reg);
+		md_val = bank_info->md_reg ?
+				readl_relaxed(bank_info->md_reg) : 0;
 	} else {
 		ns_mask = clk->ns_mask;
 		md_val = clk->md_reg ? readl_relaxed(clk->md_reg) : 0;
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 0ced722..872d9d4 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -30,7 +30,6 @@
 #include <mach/rpm.h>
 #include <mach/msm_bus_board.h>
 #include <mach/msm_memtypes.h>
-#include <mach/msm_xo.h>
 #include <sound/msm-dai-q6.h>
 #include <sound/apr_audio.h>
 #include "clock.h"
@@ -843,7 +842,6 @@
 	.strap_ahb_upper = 0x00290000,
 	.strap_ahb_lower = 0x00000280,
 	.aclk_reg = SFAB_LPASS_Q6_ACLK_CTL,
-	.xo_id = MSM_XO_PXO,
 	.name = "q6",
 	.pas_id = PAS_Q6,
 	.bus_port = MSM_BUS_MASTER_LPASS_PROC,
@@ -881,7 +879,6 @@
 	.strap_ahb_lower = 0x00000080,
 	.aclk_reg = SFAB_MSS_Q6_FW_ACLK_CTL,
 	.jtag_clk_reg = MSS_Q6FW_JTAG_CLK_CTL,
-	.xo_id = MSM_XO_CXO,
 	.name = "modem_fw",
 	.depends = "q6",
 	.pas_id = PAS_MODEM_FW,
@@ -919,7 +916,6 @@
 	.strap_ahb_lower = 0x00000080,
 	.aclk_reg = SFAB_MSS_Q6_SW_ACLK_CTL,
 	.jtag_clk_reg = MSS_Q6SW_JTAG_CLK_CTL,
-	.xo_id = MSM_XO_CXO,
 	.name = "modem",
 	.depends = "modem_fw",
 	.pas_id = PAS_MODEM_SW,
diff --git a/arch/arm/mach-msm/devices-msm7x2xa.h b/arch/arm/mach-msm/devices-msm7x2xa.h
index a59ade3..be6a645 100644
--- a/arch/arm/mach-msm/devices-msm7x2xa.h
+++ b/arch/arm/mach-msm/devices-msm7x2xa.h
@@ -25,4 +25,5 @@
 extern struct platform_device msm7x27a_device_clkctl;
 void __init msm8625_init_irq(void);
 void __init msm8625_map_io(void);
+int  ar600x_wlan_power(bool on);
 #endif
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index d11c13f..c7ef271 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -172,26 +172,43 @@
 	BACK_CAMERA_INT_3D,
 };
 
-struct msm8960_privacy_light_cfg {
-	unsigned mpp;
+enum camera_vreg_type {
+	REG_LDO,
+	REG_VS,
 };
 
-struct msm_camera_sensor_platform_info {
-	int mount_angle;
-	int sensor_reset_enable;
-	int sensor_reset;
-	int sensor_pwd;
-	int vcm_pwd;
-	int vcm_enable;
-	int privacy_light;
-	void *privacy_light_info;
+struct camera_vreg_t {
+	char *reg_name;
+	enum camera_vreg_type type;
+	int min_voltage;
+	int max_voltage;
+	int op_mode;
+};
+
+struct msm_gpio_set_tbl {
+	unsigned gpio;
+	unsigned long flags;
+	uint32_t delay;
 };
 
 struct msm_camera_gpio_conf {
 	void *cam_gpiomux_conf_tbl;
 	uint8_t cam_gpiomux_conf_tbl_size;
-	uint16_t *cam_gpio_tbl;
-	uint8_t cam_gpio_tbl_size;
+	struct gpio *cam_gpio_common_tbl;
+	uint8_t cam_gpio_common_tbl_size;
+	struct gpio *cam_gpio_req_tbl;
+	uint8_t cam_gpio_req_tbl_size;
+	struct msm_gpio_set_tbl *cam_gpio_set_tbl;
+	uint8_t cam_gpio_set_tbl_size;
+};
+
+struct msm_camera_sensor_platform_info {
+	int mount_angle;
+	int sensor_reset;
+	struct camera_vreg_t *cam_vreg;
+	int num_vreg;
+	int32_t (*ext_power_ctrl) (int enable);
+	struct msm_camera_gpio_conf *gpio_conf;
 };
 
 struct msm_actuator_info {
@@ -219,7 +236,6 @@
 	struct msm_camera_csi_params csi_params;
 	struct msm_camera_sensor_strobe_flash_data *strobe_flash_data;
 	char *eeprom_data;
-	struct msm_camera_gpio_conf *gpio_conf;
 	enum msm_camera_type camera_type;
 	struct msm_actuator_info *actuator_info;
 };
@@ -454,6 +470,8 @@
 void msm_init_irq(void);
 void msm_copper_init_irq(void);
 void vic_handle_irq(struct pt_regs *regs);
+void msm_copper_reserve(void);
+void msm_copper_very_early(void);
 
 struct mmc_platform_data;
 int msm_add_sdcc(unsigned int controller,
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 1abfd7b..8c61a42 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -19,6 +19,7 @@
 #include <linux/cdev.h>
 #include <linux/platform_device.h>
 #include <linux/wakelock.h>
+#include <linux/regulator/consumer.h>
 #include "linux/types.h"
 
 #include <mach/board.h>
@@ -687,7 +688,15 @@
 
 int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
 		struct clk **clk_ptr, int num_clk, int enable);
-int msm_sensor_probe_on(struct device *);
-int msm_sensor_probe_off(struct device *);
 int msm_cam_core_reset(void);
+
+int msm_camera_config_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
+		int num_vreg, struct regulator **reg_ptr, int config);
+int msm_camera_enable_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
+		int num_vreg, struct regulator **reg_ptr, int enable);
+
+int msm_camera_config_gpio_table
+	(struct msm_camera_sensor_info *sinfo, int gpio_en);
+int msm_camera_request_gpio_table
+	(struct msm_camera_sensor_info *sinfo, int gpio_en);
 #endif
diff --git a/arch/arm/mach-msm/include/mach/qpnp-int.h b/arch/arm/mach-msm/include/mach/qpnp-int.h
new file mode 100644
index 0000000..a79d2fc
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/qpnp-int.h
@@ -0,0 +1,83 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef QPNPINT_H
+#define QPNPINT_H
+
+#include <linux/spmi.h>
+
+struct qpnp_irq_spec {
+	uint8_t slave; /* 0-15 */
+	uint8_t per; /* 0-255 */
+	uint8_t irq; /* 0-7 */
+};
+
+struct qpnp_local_int {
+	 /* mask - Invoke PMIC Arbiter local mask handler */
+	int (*mask)(struct spmi_controller *spmi_ctrl,
+		    struct qpnp_irq_spec *spec,
+		    uint32_t priv_d);
+	 /* unmask - Invoke PMIC Arbiter local unmask handler */
+	int (*unmask)(struct spmi_controller *spmi_ctrl,
+		      struct qpnp_irq_spec *spec,
+		      uint32_t priv_d);
+	/* register_priv_data - Return per irq priv data */
+	int (*register_priv_data)(struct spmi_controller *spmi_ctrl,
+				  struct qpnp_irq_spec *spec,
+				  uint32_t *priv_d);
+};
+
+#ifdef CONFIG_MSM_QPNP_INT
+/**
+ * qpnpint_of_init() - Device Tree irq initialization
+ *
+ * Standard Device Tree init routine to be called from
+ * of_irq_init().
+ */
+int __init qpnpint_of_init(struct device_node *node,
+			   struct device_node *parent);
+
+/**
+ * qpnpint_register_controller() - Register local interrupt callbacks
+ *
+ * Used by the PMIC Arbiter driver or equivalent to register
+ * callbacks for interrupt events.
+ */
+int qpnpint_register_controller(unsigned int busno,
+				struct qpnp_local_int *li_cb);
+
+/**
+ * qpnpint_handle_irq - Main interrupt handling routine
+ *
+ * Pass a PMIC Arbiter interrupt to Linux.
+ */
+int qpnpint_handle_irq(struct spmi_controller *spmi_ctrl,
+		       struct qpnp_irq_spec *spec);
+#else
+static inline int __init qpnpint_of_init(struct device_node *node,
+				  struct device_node *parent)
+{
+	return -ENXIO;
+}
+static inline int qpnpint_register_controller(unsigned int busno,
+				struct qpnp_local_int *li_cb)
+{
+	return -ENXIO;
+}
+
+static inline int qpnpint_handle_irq(struct spmi_controller *spmi_ctrl,
+		       struct qpnp_irq_spec *spec)
+{
+	return -ENXIO;
+}
+#endif /* CONFIG_MSM_QPNP_INT */
+#endif /* QPNPINT_H */
diff --git a/arch/arm/mach-msm/ipc_socket.c b/arch/arm/mach-msm/ipc_socket.c
index 093d044..4b0d26a 100644
--- a/arch/arm/mach-msm/ipc_socket.c
+++ b/arch/arm/mach-msm/ipc_socket.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -27,6 +27,7 @@
 #include <net/sock.h>
 
 #include <mach/peripheral-loader.h>
+#include <mach/socinfo.h>
 
 #include "ipc_router.h"
 
@@ -46,11 +47,18 @@
 
 static void *msm_ipc_router_load_modem(void)
 {
-	void *pil;
+	void *pil = NULL;
 	int rc;
 
-	pil = pil_get("modem");
-	if (IS_ERR(pil)) {
+	/* Load GNSS for Standalone 8064 but not for Fusion 3 */
+	if (cpu_is_apq8064()) {
+		if (socinfo_get_platform_subtype() == 0x0)
+			pil = pil_get("gnss");
+	} else {
+		pil = pil_get("modem");
+	}
+
+	if (IS_ERR(pil) || !pil) {
 		pr_debug("%s: modem load failed\n", __func__);
 		pil = NULL;
 	} else {
diff --git a/arch/arm/mach-msm/lpass-8960.c b/arch/arm/mach-msm/lpass-8960.c
index 11b9092..5eccf06 100644
--- a/arch/arm/mach-msm/lpass-8960.c
+++ b/arch/arm/mach-msm/lpass-8960.c
@@ -66,6 +66,28 @@
 	.notifier_call = riva_notifier_cb,
 };
 
+static int modem_notifier_cb(struct notifier_block *this, unsigned long code,
+								void *ss_handle)
+{
+	int ret;
+	switch (code) {
+	case SUBSYS_BEFORE_SHUTDOWN:
+		pr_debug("%s: M-Notify: Shutdown started\n", __func__);
+		ret = sysmon_send_event(SYSMON_SS_LPASS, "modem",
+				SUBSYS_BEFORE_SHUTDOWN);
+		if (ret < 0)
+			pr_err("%s: sysmon_send_event error %d", __func__,
+				ret);
+		break;
+	}
+	return NOTIFY_DONE;
+}
+
+static void *ssr_modem_notif_hdle;
+static struct notifier_block mnb = {
+	.notifier_call = modem_notifier_cb,
+};
+
 static void lpass_fatal_fn(struct work_struct *work)
 {
 	pr_err("%s %s: Watchdog bite received from Q6!\n", MODULE_NAME,
@@ -213,6 +235,18 @@
 		goto out;
 	}
 
+	ssr_modem_notif_hdle = subsys_notif_register_notifier("modem",
+							&mnb);
+	if (IS_ERR(ssr_modem_notif_hdle) < 0) {
+		ret = PTR_ERR(ssr_modem_notif_hdle);
+		pr_err("%s: subsys_register_notifier for Modem: err = %d\n",
+			__func__, ret);
+		subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
+		iounmap(q6_wakeup_intr);
+		free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
+		goto out;
+	}
+
 	pr_info("%s: lpass SSR driver init'ed.\n", __func__);
 out:
 	return ret;
@@ -221,6 +255,7 @@
 static void __exit lpass_fatal_exit(void)
 {
 	subsys_notif_unregister_notifier(ssr_notif_hdle, &rnb);
+	subsys_notif_unregister_notifier(ssr_modem_notif_hdle, &mnb);
 	iounmap(q6_wakeup_intr);
 	free_irq(LPASS_Q6SS_WDOG_EXPIRED, NULL);
 }
diff --git a/arch/arm/mach-msm/pil-modem.c b/arch/arm/mach-msm/pil-modem.c
index 5aa3834..1d13508 100644
--- a/arch/arm/mach-msm/pil-modem.c
+++ b/arch/arm/mach-msm/pil-modem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -18,9 +18,10 @@
 #include <linux/elf.h>
 #include <linux/delay.h>
 #include <linux/err.h>
+#include <linux/workqueue.h>
+#include <linux/clk.h>
 
 #include <mach/msm_iomap.h>
-#include <mach/msm_xo.h>
 
 #include "peripheral-loader.h"
 #include "scm-pas.h"
@@ -52,8 +53,8 @@
 struct modem_data {
 	void __iomem *base;
 	unsigned long start_addr;
-	struct msm_xo_voter *pxo;
-	struct timer_list timer;
+	struct clk *xo;
+	struct delayed_work work;
 };
 
 static int nop_verify_blob(struct pil_desc *pil, u32 phy_addr, size_t size)
@@ -61,28 +62,30 @@
 	return 0;
 }
 
-static void remove_proxy_votes(unsigned long data)
-{
-	struct modem_data *drv = (struct modem_data *)data;
-	msm_xo_mode_vote(drv->pxo, MSM_XO_MODE_OFF);
-}
-
-static void make_modem_proxy_votes(struct device *dev)
+static int make_modem_proxy_votes(struct device *dev)
 {
 	int ret;
 	struct modem_data *drv = dev_get_drvdata(dev);
 
-	ret = msm_xo_mode_vote(drv->pxo, MSM_XO_MODE_ON);
-	if (ret)
-		dev_err(dev, "Failed to enable PXO\n");
-	mod_timer(&drv->timer, jiffies + msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+	ret = clk_prepare_enable(drv->xo);
+	if (ret) {
+		dev_err(dev, "Failed to enable XO\n");
+		return ret;
+	}
+	schedule_delayed_work(&drv->work, msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+	return 0;
+}
+
+static void remove_modem_proxy_votes(struct work_struct *work)
+{
+	struct modem_data *drv;
+	drv = container_of(work, struct modem_data, work.work);
+	clk_disable_unprepare(drv->xo);
 }
 
 static void remove_modem_proxy_votes_now(struct modem_data *drv)
 {
-	/* If the proxy vote hasn't been removed yet, remove it immediately. */
-	if (del_timer(&drv->timer))
-		remove_proxy_votes((unsigned long)drv);
+	flush_delayed_work(&drv->work);
 }
 
 static int modem_init_image(struct pil_desc *pil, const u8 *metadata,
@@ -97,9 +100,12 @@
 static int modem_reset(struct pil_desc *pil)
 {
 	u32 reg;
+	int ret;
 	const struct modem_data *drv = dev_get_drvdata(pil->dev);
 
-	make_modem_proxy_votes(pil->dev);
+	ret = make_modem_proxy_votes(pil->dev);
+	if (ret)
+		return ret;
 
 	/* Put modem AHB0,1,2 clocks into reset */
 	writel_relaxed(BIT(0) | BIT(1), MAHB0_SFAB_PORT_RESET);
@@ -235,7 +241,9 @@
 	int ret;
 	struct modem_data *drv = dev_get_drvdata(pil->dev);
 
-	make_modem_proxy_votes(pil->dev);
+	ret = make_modem_proxy_votes(pil->dev);
+	if (ret)
+		return ret;
 
 	ret = pas_auth_and_reset(PAS_MODEM);
 	if (ret)
@@ -269,6 +277,7 @@
 	struct modem_data *drv;
 	struct resource *res;
 	struct pil_desc *desc;
+	int ret;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
@@ -283,15 +292,14 @@
 	if (!drv->base)
 		return -ENOMEM;
 
-	drv->pxo = msm_xo_get(MSM_XO_PXO, dev_name(&pdev->dev));
-	if (IS_ERR(drv->pxo))
-		return PTR_ERR(drv->pxo);
+	drv->xo = clk_get(&pdev->dev, "xo");
+	if (IS_ERR(drv->xo))
+		return PTR_ERR(drv->xo);
 
 	desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL);
 	if (!desc)
 		return -ENOMEM;
 
-	setup_timer(&drv->timer, remove_proxy_votes, (unsigned long)drv);
 	desc->name = "modem";
 	desc->depends_on = "q6";
 	desc->dev = &pdev->dev;
@@ -303,19 +311,21 @@
 		desc->ops = &pil_modem_ops;
 		dev_info(&pdev->dev, "using non-secure boot\n");
 	}
+	INIT_DELAYED_WORK(&drv->work, remove_modem_proxy_votes);
 
-	if (msm_pil_register(desc)) {
-		msm_xo_put(drv->pxo);
-		return -EINVAL;
+	ret = msm_pil_register(desc);
+	if (ret) {
+		flush_delayed_work_sync(&drv->work);
+		clk_put(drv->xo);
 	}
-	return 0;
+	return ret;
 }
 
 static int __devexit pil_modem_driver_exit(struct platform_device *pdev)
 {
 	struct modem_data *drv = platform_get_drvdata(pdev);
-	del_timer_sync(&drv->timer);
-	msm_xo_put(drv->pxo);
+	flush_delayed_work_sync(&drv->work);
+	clk_put(drv->xo);
 	return 0;
 }
 
diff --git a/arch/arm/mach-msm/pil-q6v4.c b/arch/arm/mach-msm/pil-q6v4.c
index cdbfc48..511377d 100644
--- a/arch/arm/mach-msm/pil-q6v4.c
+++ b/arch/arm/mach-msm/pil-q6v4.c
@@ -20,10 +20,10 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/workqueue.h>
+#include <linux/clk.h>
 
 #include <mach/msm_bus.h>
 #include <mach/msm_iomap.h>
-#include <mach/msm_xo.h>
 
 #include "peripheral-loader.h"
 #include "pil-q6v4.h"
@@ -71,7 +71,7 @@
 	struct regulator *vreg;
 	struct regulator *pll_supply;
 	bool vreg_enabled;
-	struct msm_xo_voter *xo;
+	struct clk *xo;
 	struct delayed_work work;
 };
 
@@ -89,18 +89,29 @@
 	return 0;
 }
 
-static void pil_q6v4_make_proxy_votes(struct device *dev)
+static int pil_q6v4_make_proxy_votes(struct device *dev)
 {
 	struct q6v4_data *drv = dev_get_drvdata(dev);
 	int ret;
 
-	msm_xo_mode_vote(drv->xo, MSM_XO_MODE_ON);
+	ret = clk_prepare_enable(drv->xo);
+	if (ret) {
+		dev_err(dev, "Failed to enable XO\n");
+		goto err;
+	}
 	if (drv->pll_supply) {
 		ret = regulator_enable(drv->pll_supply);
-		if (ret)
-			dev_err(dev, "failed to enable pll supply\n");
+		if (ret) {
+			dev_err(dev, "Failed to enable pll supply\n");
+			goto err_regulator;
+		}
 	}
 	schedule_delayed_work(&drv->work, msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+	return 0;
+err_regulator:
+	clk_disable_unprepare(drv->xo);
+err:
+	return ret;
 }
 
 static void pil_q6v4_remove_proxy_votes(struct work_struct *work)
@@ -108,7 +119,7 @@
 	struct q6v4_data *drv = container_of(work, struct q6v4_data, work.work);
 	if (drv->pll_supply)
 		regulator_disable(drv->pll_supply);
-	msm_xo_mode_vote(drv->xo, MSM_XO_MODE_OFF);
+	clk_disable_unprepare(drv->xo);
 }
 
 static void pil_q6v4_remove_proxy_votes_now(struct device *dev)
@@ -191,7 +202,9 @@
 	const struct q6v4_data *drv = dev_get_drvdata(pil->dev);
 	const struct pil_q6v4_pdata *pdata = pil->dev->platform_data;
 
-	pil_q6v4_make_proxy_votes(pil->dev);
+	err = pil_q6v4_make_proxy_votes(pil->dev);
+	if (err)
+		return err;
 
 	err = pil_q6v4_power_up(pil->dev);
 	if (err)
@@ -331,7 +344,9 @@
 	const struct pil_q6v4_pdata *pdata = pil->dev->platform_data;
 	int err;
 
-	pil_q6v4_make_proxy_votes(pil->dev);
+	err = pil_q6v4_make_proxy_votes(pil->dev);
+	if (err)
+		return err;
 
 	err = pil_q6v4_power_up(pil->dev);
 	if (err)
@@ -442,7 +457,7 @@
 		goto err;
 	}
 
-	drv->xo = msm_xo_get(pdata->xo_id, pdata->name);
+	drv->xo = clk_get(&pdev->dev, "xo");
 	if (IS_ERR(drv->xo)) {
 		ret = PTR_ERR(drv->xo);
 		goto err_xo;
@@ -454,8 +469,8 @@
 		goto err_pil;
 	return 0;
 err_pil:
-	cancel_delayed_work_sync(&drv->work);
-	msm_xo_put(drv->xo);
+	flush_delayed_work_sync(&drv->work);
+	clk_put(drv->xo);
 err_xo:
 	regulator_put(drv->vreg);
 err:
@@ -466,8 +481,8 @@
 static int __devexit pil_q6v4_driver_exit(struct platform_device *pdev)
 {
 	struct q6v4_data *drv = platform_get_drvdata(pdev);
-	cancel_delayed_work_sync(&drv->work);
-	msm_xo_put(drv->xo);
+	flush_delayed_work_sync(&drv->work);
+	clk_put(drv->xo);
 	regulator_put(drv->vreg);
 	regulator_put(drv->pll_supply);
 	return 0;
diff --git a/arch/arm/mach-msm/pil-q6v4.h b/arch/arm/mach-msm/pil-q6v4.h
index 54bdf88..b0b97d0 100644
--- a/arch/arm/mach-msm/pil-q6v4.h
+++ b/arch/arm/mach-msm/pil-q6v4.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -18,7 +18,6 @@
 	const unsigned long strap_ahb_lower;
 	void __iomem *aclk_reg;
 	void __iomem *jtag_clk_reg;
-	const int xo_id;
 	const char *name;
 	const char *depends;
 	const unsigned pas_id;
diff --git a/arch/arm/mach-msm/pil-riva.c b/arch/arm/mach-msm/pil-riva.c
index 7e78a15..29a9df9 100644
--- a/arch/arm/mach-msm/pil-riva.c
+++ b/arch/arm/mach-msm/pil-riva.c
@@ -88,20 +88,29 @@
 	struct regulator *pll_supply;
 };
 
-static void pil_riva_make_proxy_votes(struct device *dev)
+static int pil_riva_make_proxy_votes(struct device *dev)
 {
 	struct riva_data *drv = dev_get_drvdata(dev);
 	int ret;
 
+	ret = regulator_enable(drv->pll_supply);
+	if (ret) {
+		dev_err(dev, "failed to enable pll supply\n");
+		goto err;
+	}
 	if (drv->use_cxo) {
 		ret = clk_prepare_enable(drv->xo);
-		if (ret)
+		if (ret) {
 			dev_err(dev, "failed to enable xo\n");
+			goto err_clk;
+		}
 	}
-	ret = regulator_enable(drv->pll_supply);
-	if (ret)
-		dev_err(dev, "failed to enable pll supply\n");
 	schedule_delayed_work(&drv->work, msecs_to_jiffies(PROXY_VOTE_TIMEOUT));
+	return 0;
+err_clk:
+	regulator_disable(drv->pll_supply);
+err:
+	return ret;
 }
 
 static void pil_riva_remove_proxy_votes(struct work_struct *work)
@@ -156,7 +165,14 @@
 	writel_relaxed(reg, base + RIVA_PMU_A2XB_CFG);
 
 	drv->use_cxo = cxo_is_needed(drv);
-	pil_riva_make_proxy_votes(pil->dev);
+	ret = pil_riva_make_proxy_votes(pil->dev);
+	if (ret) {
+		reg &= ~RIVA_PMU_A2XB_CFG_EN;
+		writel_relaxed(reg, base + RIVA_PMU_A2XB_CFG);
+		mb();
+		clk_disable_unprepare(drv->xo);
+		return ret;
+	}
 
 	/* Program PLL 13 to 960 MHz */
 	reg = readl_relaxed(RIVA_PLL_MODE);
@@ -298,8 +314,9 @@
 	if (ret)
 		return ret;
 	/* Proxy-vote for resources RIVA needs */
-	pil_riva_make_proxy_votes(pil->dev);
-	ret = pas_auth_and_reset(PAS_RIVA);
+	ret = pil_riva_make_proxy_votes(pil->dev);
+	if (!ret)
+		ret = pas_auth_and_reset(PAS_RIVA);
 	clk_disable_unprepare(drv->xo);
 	return ret;
 }
@@ -390,7 +407,7 @@
 		goto err_register;
 	return 0;
 err_register:
-	cancel_delayed_work_sync(&drv->work);
+	flush_delayed_work_sync(&drv->work);
 	clk_put(drv->xo);
 err:
 	regulator_put(drv->pll_supply);
@@ -400,7 +417,7 @@
 static int __devexit pil_riva_remove(struct platform_device *pdev)
 {
 	struct riva_data *drv = platform_get_drvdata(pdev);
-	cancel_delayed_work_sync(&drv->work);
+	flush_delayed_work_sync(&drv->work);
 	clk_put(drv->xo);
 	regulator_put(drv->pll_supply);
 	return 0;
diff --git a/arch/arm/mach-msm/qdsp6v2/apr.c b/arch/arm/mach-msm/qdsp6v2/apr.c
index 13d92d1..37428da 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -27,6 +27,7 @@
 #include <linux/sysfs.h>
 #include <linux/device.h>
 #include <linux/slab.h>
+#include <asm/mach-types.h>
 #include <mach/peripheral-loader.h>
 #include <mach/msm_smd.h>
 #include <mach/qdsp6v2/apr.h>
@@ -373,7 +374,11 @@
 		if (!q6.pil) {
 			pr_err("APR: Unable to load q6 image\n");
 			mutex_unlock(&q6.lock);
-			return svc;
+			/* Return failure if not intended for simulator */
+			if (!machine_is_apq8064_sim()) {
+				pr_debug("APR: Not apq8064 sim\n");
+				return svc;
+			}
 		}
 		q6.state = APR_Q6_LOADED;
 	}
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
index 2e61e90..ce5d084 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
@@ -783,6 +783,7 @@
 			pr_err("%s: More Audproc Cal then expected, "
 				"size received: %d\n", __func__, size);
 		store_audvol_cal(TX_CAL, data);
+		break;
 	case AUDIO_SET_AUDPROC_RX_VOL_CAL:
 		if (size > sizeof(struct cal_block))
 			pr_err("%s: More Audproc Cal then expected, "
diff --git a/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h b/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
index 7096669..f02e0a0 100644
--- a/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
+++ b/arch/arm/mach-msm/qdsp6v2/timpani_profile_8x60.h
@@ -1906,6 +1906,7 @@
 	{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0xAC)}, \
 	{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0xAC)}, \
 	{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0x3A, 0x24, 0x24)}, \
+	{ADIE_CODEC_ACTION_DELAY_WAIT, 0x4E1F}, \
 	{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x3C)}, \
 	{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE1, 0xFE, 0x3C)}, \
 	{ADIE_CODEC_ACTION_ENTRY, ADIE_CODEC_PACK_ENTRY(0xE0, 0xFE, 0x1C)}, \
diff --git a/drivers/base/genlock.c b/drivers/base/genlock.c
index 7e25684..1507915 100644
--- a/drivers/base/genlock.c
+++ b/drivers/base/genlock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -110,6 +110,11 @@
 {
 	struct genlock *lock;
 
+	if (IS_ERR_OR_NULL(handle)) {
+		GENLOCK_LOG_ERR("Invalid handle\n");
+		return ERR_PTR(-EINVAL);
+	}
+
 	if (handle->lock != NULL) {
 		GENLOCK_LOG_ERR("Handle already has a lock attached\n");
 		return ERR_PTR(-EINVAL);
@@ -177,6 +182,11 @@
 	struct file *file;
 	struct genlock *lock;
 
+	if (IS_ERR_OR_NULL(handle)) {
+		GENLOCK_LOG_ERR("Invalid handle\n");
+		return ERR_PTR(-EINVAL);
+	}
+
 	if (handle->lock != NULL) {
 		GENLOCK_LOG_ERR("Handle already has a lock attached\n");
 		return ERR_PTR(-EINVAL);
@@ -392,9 +402,17 @@
 int genlock_lock(struct genlock_handle *handle, int op, int flags,
 	uint32_t timeout)
 {
-	struct genlock *lock = handle->lock;
+	struct genlock *lock;
+
 	int ret = 0;
 
+	if (IS_ERR_OR_NULL(handle)) {
+		GENLOCK_LOG_ERR("Invalid handle\n");
+		return -EINVAL;
+	}
+
+	lock = handle->lock;
+
 	if (lock == NULL) {
 		GENLOCK_LOG_ERR("Handle does not have a lock attached\n");
 		return -EINVAL;
@@ -426,11 +444,18 @@
 
 int genlock_wait(struct genlock_handle *handle, uint32_t timeout)
 {
-	struct genlock *lock = handle->lock;
+	struct genlock *lock;
 	unsigned long irqflags;
 	int ret = 0;
 	unsigned int ticks = msecs_to_jiffies(timeout);
 
+	if (IS_ERR_OR_NULL(handle)) {
+		GENLOCK_LOG_ERR("Invalid handle\n");
+		return -EINVAL;
+	}
+
+	lock = handle->lock;
+
 	if (lock == NULL) {
 		GENLOCK_LOG_ERR("Handle does not have a lock attached\n");
 		return -EINVAL;
@@ -471,12 +496,7 @@
 	return ret;
 }
 
-/**
- * genlock_release_lock - Release a lock attached to a handle
- * @handle - Pointer to the handle holding the lock
- */
-
-void genlock_release_lock(struct genlock_handle *handle)
+static void genlock_release_lock(struct genlock_handle *handle)
 {
 	unsigned long flags;
 
@@ -497,7 +517,6 @@
 	handle->lock = NULL;
 	handle->active = 0;
 }
-EXPORT_SYMBOL(genlock_release_lock);
 
 /*
  * Release function called when all references to a handle are released
@@ -589,6 +608,9 @@
 	struct genlock *lock;
 	int ret;
 
+	if (IS_ERR_OR_NULL(handle))
+		return -EINVAL;
+
 	switch (cmd) {
 	case GENLOCK_IOC_NEW: {
 		lock = genlock_create_lock(handle);
@@ -643,8 +665,13 @@
 		return genlock_wait(handle, param.timeout);
 	}
 	case GENLOCK_IOC_RELEASE: {
-		genlock_release_lock(handle);
-		return 0;
+		/*
+		 * Return error - this ioctl has been deprecated.
+		 * Locks should only be released when the handle is
+		 * destroyed
+		 */
+		GENLOCK_LOG_ERR("Deprecated RELEASE ioctl called\n");
+		return -EINVAL;
 	}
 	default:
 		GENLOCK_LOG_ERR("Invalid ioctl\n");
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index 8847a8d..a6c36c8 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -274,6 +274,7 @@
 	return handle;
 }
 
+/* Client lock must be locked when calling */
 static void ion_handle_destroy(struct kref *kref)
 {
 	struct ion_handle *handle = container_of(kref, struct ion_handle, ref);
@@ -282,10 +283,8 @@
 	 */
 	WARN_ON(handle->kmap_cnt || handle->dmap_cnt || handle->usermap_cnt);
 	ion_buffer_put(handle->buffer);
-	mutex_lock(&handle->client->lock);
 	if (!RB_EMPTY_NODE(&handle->node))
 		rb_erase(&handle->node, &handle->client->handles);
-	mutex_unlock(&handle->client->lock);
 	kfree(handle);
 }
 
@@ -448,13 +447,13 @@
 
 	mutex_lock(&client->lock);
 	valid_handle = ion_handle_validate(client, handle);
-	mutex_unlock(&client->lock);
-
 	if (!valid_handle) {
+		mutex_unlock(&client->lock);
 		WARN("%s: invalid handle passed to free.\n", __func__);
 		return;
 	}
 	ion_handle_put(handle);
+	mutex_unlock(&client->lock);
 }
 EXPORT_SYMBOL(ion_free);
 
@@ -1254,7 +1253,9 @@
 		 atomic_read(&client->ref.refcount),
 		 atomic_read(&handle->ref.refcount),
 		 atomic_read(&buffer->ref.refcount));
+	mutex_lock(&client->lock);
 	ion_handle_put(handle);
+	mutex_unlock(&client->lock);
 	ion_client_put(client);
 	pr_debug("%s: %d client_cnt %d handle_cnt %d alloc_cnt %d\n",
 		 __func__, __LINE__,
@@ -1349,7 +1350,9 @@
 	mutex_unlock(&buffer->lock);
 	/* drop the reference to the handle */
 err1:
+	mutex_lock(&client->lock);
 	ion_handle_put(handle);
+	mutex_unlock(&client->lock);
 err:
 	/* drop the reference to the client */
 	ion_client_put(client);
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 4212f18..545c61c 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -3029,6 +3029,11 @@
 	case V4L2_CID_PRIVATE_IRIS_ANTENNA:
 		temp_val = ctrl->value;
 		retval = hci_fm_set_antenna(&temp_val, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Set Antenna failed retval = %x", retval);
+			return retval;
+		}
+		radio->g_antenna =  ctrl->value;
 		break;
 	case V4L2_CID_RDS_TX_PTY:
 		radio->pty = ctrl->value;
diff --git a/drivers/media/video/msm/io/msm_io_util.c b/drivers/media/video/msm/io/msm_io_util.c
index 9f58d6e..0ae247e 100644
--- a/drivers/media/video/msm/io/msm_io_util.c
+++ b/drivers/media/video/msm/io/msm_io_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -12,8 +12,11 @@
 
 #include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
 #include <mach/board.h>
 #include <mach/camera.h>
+#include <mach/gpiomux.h>
 
 int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
 		struct clk **clk_ptr, int num_clk, int enable)
@@ -66,3 +69,183 @@
 	return rc;
 }
 
+int msm_camera_config_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
+		int num_vreg, struct regulator **reg_ptr, int config)
+{
+	int i = 0;
+	int rc = 0;
+	struct camera_vreg_t *curr_vreg;
+	if (config) {
+		for (i = 0; i < num_vreg; i++) {
+			curr_vreg = &cam_vreg[i];
+			reg_ptr[i] = regulator_get(dev,
+				curr_vreg->reg_name);
+			if (IS_ERR(reg_ptr[i])) {
+				pr_err("%s: %s get failed\n",
+				 __func__,
+				 curr_vreg->reg_name);
+				reg_ptr[i] = NULL;
+				goto vreg_get_fail;
+			}
+			if (curr_vreg->type == REG_LDO) {
+				rc = regulator_set_voltage(
+				reg_ptr[i],
+				curr_vreg->min_voltage,
+				curr_vreg->max_voltage);
+				if (rc < 0) {
+					pr_err(
+					"%s: %s set voltage failed\n",
+					__func__,
+					curr_vreg->reg_name);
+					goto vreg_set_voltage_fail;
+				}
+				rc = regulator_set_optimum_mode(
+					reg_ptr[i],
+					curr_vreg->op_mode);
+				if (rc < 0) {
+					pr_err(
+					"%s: %s set optimum mode failed\n",
+					__func__,
+					curr_vreg->reg_name);
+					goto vreg_set_opt_mode_fail;
+				}
+			}
+		}
+	} else {
+		for (i = num_vreg-1; i >= 0; i--) {
+			curr_vreg = &cam_vreg[i];
+			if (reg_ptr[i]) {
+				if (curr_vreg->type == REG_LDO) {
+					regulator_set_optimum_mode(
+						reg_ptr[i], 0);
+					regulator_set_voltage(
+						reg_ptr[i],
+						0, curr_vreg->max_voltage);
+				}
+				regulator_put(reg_ptr[i]);
+				reg_ptr[i] = NULL;
+			}
+		}
+	}
+	return 0;
+
+vreg_unconfig:
+if (curr_vreg->type == REG_LDO)
+	regulator_set_optimum_mode(reg_ptr[i], 0);
+
+vreg_set_opt_mode_fail:
+if (curr_vreg->type == REG_LDO)
+	regulator_set_voltage(reg_ptr[i], 0,
+		curr_vreg->max_voltage);
+
+vreg_set_voltage_fail:
+	regulator_put(reg_ptr[i]);
+	reg_ptr[i] = NULL;
+
+vreg_get_fail:
+	for (i--; i >= 0; i--) {
+		curr_vreg = &cam_vreg[i];
+		goto vreg_unconfig;
+	}
+	return -ENODEV;
+}
+
+int msm_camera_enable_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
+		int num_vreg, struct regulator **reg_ptr, int enable)
+{
+	int i = 0, rc = 0;
+	if (enable) {
+		for (i = 0; i < num_vreg; i++) {
+			if (IS_ERR(reg_ptr[i])) {
+				pr_err("%s: %s null regulator\n",
+				__func__, cam_vreg[i].reg_name);
+				goto disable_vreg;
+			}
+			rc = regulator_enable(reg_ptr[i]);
+			if (rc < 0) {
+				pr_err("%s: %s enable failed\n",
+				__func__, cam_vreg[i].reg_name);
+				goto disable_vreg;
+			}
+		}
+	} else {
+		for (i = num_vreg-1; i >= 0; i--)
+			regulator_disable(reg_ptr[i]);
+	}
+	return rc;
+disable_vreg:
+	for (i--; i >= 0; i--) {
+		regulator_disable(reg_ptr[i]);
+		goto disable_vreg;
+	}
+	return rc;
+}
+
+int msm_camera_request_gpio_table(struct msm_camera_sensor_info *sinfo,
+	int gpio_en)
+{
+	int rc = 0;
+	struct msm_camera_gpio_conf *gpio_conf =
+		sinfo->sensor_platform_info->gpio_conf;
+
+	if (gpio_conf->cam_gpio_req_tbl == NULL ||
+		gpio_conf->cam_gpio_common_tbl == NULL) {
+		pr_err("%s: NULL camera gpio table\n", __func__);
+		return -EFAULT;
+	}
+
+	if (gpio_en) {
+		if (gpio_conf->cam_gpiomux_conf_tbl != NULL) {
+			msm_gpiomux_install(
+				(struct msm_gpiomux_config *)gpio_conf->
+				cam_gpiomux_conf_tbl,
+				gpio_conf->cam_gpiomux_conf_tbl_size);
+		}
+		rc = gpio_request_array(gpio_conf->cam_gpio_common_tbl,
+				gpio_conf->cam_gpio_common_tbl_size);
+		if (rc < 0) {
+			pr_err("%s common gpio request failed\n", __func__);
+			return rc;
+		}
+		rc = gpio_request_array(gpio_conf->cam_gpio_req_tbl,
+				gpio_conf->cam_gpio_req_tbl_size);
+		if (rc < 0) {
+			pr_err("%s camera gpio request failed\n", __func__);
+			gpio_free_array(gpio_conf->cam_gpio_common_tbl,
+				gpio_conf->cam_gpio_common_tbl_size);
+			return rc;
+		}
+	} else {
+		gpio_free_array(gpio_conf->cam_gpio_req_tbl,
+				gpio_conf->cam_gpio_req_tbl_size);
+		gpio_free_array(gpio_conf->cam_gpio_common_tbl,
+			gpio_conf->cam_gpio_common_tbl_size);
+	}
+	return rc;
+}
+
+int msm_camera_config_gpio_table(struct msm_camera_sensor_info *sinfo,
+	int gpio_en)
+{
+	struct msm_camera_gpio_conf *gpio_conf =
+		sinfo->sensor_platform_info->gpio_conf;
+	int rc = 0, i;
+
+	if (gpio_en) {
+		for (i = 0; i < gpio_conf->cam_gpio_set_tbl_size; i++) {
+			gpio_set_value_cansleep(
+				gpio_conf->cam_gpio_set_tbl[i].gpio,
+				gpio_conf->cam_gpio_set_tbl[i].flags);
+			usleep_range(gpio_conf->cam_gpio_set_tbl[i].delay,
+				gpio_conf->cam_gpio_set_tbl[i].delay + 1000);
+		}
+	} else {
+		for (i = gpio_conf->cam_gpio_set_tbl_size - 1; i >= 0; i--) {
+			if (gpio_conf->cam_gpio_set_tbl[i].flags)
+				gpio_set_value_cansleep(
+					gpio_conf->cam_gpio_set_tbl[i].gpio,
+					GPIOF_OUT_INIT_LOW);
+		}
+	}
+	return rc;
+}
diff --git a/drivers/media/video/msm/msm_io_8960.c b/drivers/media/video/msm/msm_io_8960.c
index f35b5f1..79294a3 100644
--- a/drivers/media/video/msm/msm_io_8960.c
+++ b/drivers/media/video/msm/msm_io_8960.c
@@ -27,38 +27,14 @@
 
 #define BUFF_SIZE_128 128
 
-#define CAM_VAF_MINUV                 2800000
-#define CAM_VAF_MAXUV                 2800000
-#define CAM_VDIG_MINUV                    1200000
-#define CAM_VDIG_MAXUV                    1200000
-#define CAM_VANA_MINUV                    2800000
-#define CAM_VANA_MAXUV                    2850000
-#define CAM_CSI_VDD_MINUV                  1200000
-#define CAM_CSI_VDD_MAXUV                  1200000
-
-#define CAM_VAF_LOAD_UA               300000
-#define CAM_VDIG_LOAD_UA                  105000
-#define CAM_VANA_LOAD_UA                  85600
-#define CAM_CSI_LOAD_UA                    20000
-
-static struct clk *camio_cam_clk;
-
 static struct clk *camio_jpeg_clk;
 static struct clk *camio_jpeg_pclk;
 static struct regulator *fs_ijpeg;
-static struct regulator *cam_vana;
-static struct regulator *cam_vio;
-static struct regulator *cam_vdig;
-static struct regulator *cam_vaf;
-static struct regulator *mipi_csi_vdd;
 
-static struct msm_camera_io_clk camio_clk;
 static struct platform_device *camio_dev;
 static struct resource *s3drw_io, *s3dctl_io;
 static struct resource *s3drw_mem, *s3dctl_mem;
 void __iomem *s3d_rw, *s3d_ctl;
-struct msm_bus_scale_pdata *cam_bus_scale_table;
-
 
 void msm_io_w(u32 data, void __iomem *addr)
 {
@@ -136,213 +112,12 @@
 	msm_io_dump(dest_addr, len);
 }
 
-static int msm_camera_vreg_enable(struct device *dev)
-{
-	if (mipi_csi_vdd == NULL) {
-		mipi_csi_vdd = regulator_get(dev, "mipi_csi_vdd");
-		if (IS_ERR(mipi_csi_vdd)) {
-			CDBG("%s: VREG MIPI CSI VDD get failed\n", __func__);
-			mipi_csi_vdd = NULL;
-			return -ENODEV;
-		}
-		if (regulator_set_voltage(mipi_csi_vdd, CAM_CSI_VDD_MINUV,
-			CAM_CSI_VDD_MAXUV)) {
-			CDBG("%s: VREG MIPI CSI VDD set voltage failed\n",
-				__func__);
-			goto mipi_csi_vdd_put;
-		}
-		if (regulator_set_optimum_mode(mipi_csi_vdd,
-			CAM_CSI_LOAD_UA) < 0) {
-			CDBG("%s: VREG MIPI CSI set optimum mode failed\n",
-				__func__);
-			goto mipi_csi_vdd_release;
-		}
-		if (regulator_enable(mipi_csi_vdd)) {
-			CDBG("%s: VREG MIPI CSI VDD enable failed\n",
-				__func__);
-			goto mipi_csi_vdd_disable;
-		}
-	}
-	if (cam_vana == NULL) {
-		cam_vana = regulator_get(dev, "cam_vana");
-		if (IS_ERR(cam_vana)) {
-			CDBG("%s: VREG CAM VANA get failed\n", __func__);
-			cam_vana = NULL;
-			goto mipi_csi_vdd_disable;
-		}
-		if (regulator_set_voltage(cam_vana, CAM_VANA_MINUV,
-			CAM_VANA_MAXUV)) {
-			CDBG("%s: VREG CAM VANA set voltage failed\n",
-				__func__);
-			goto cam_vana_put;
-		}
-		if (regulator_set_optimum_mode(cam_vana,
-			CAM_VANA_LOAD_UA) < 0) {
-			CDBG("%s: VREG CAM VANA set optimum mode failed\n",
-				__func__);
-			goto cam_vana_release;
-		}
-		if (regulator_enable(cam_vana)) {
-			CDBG("%s: VREG CAM VANA enable failed\n", __func__);
-			goto cam_vana_disable;
-		}
-	}
-	if (cam_vio == NULL) {
-		cam_vio = regulator_get(dev, "cam_vio");
-		if (IS_ERR(cam_vio)) {
-			CDBG("%s: VREG VIO get failed\n", __func__);
-			cam_vio = NULL;
-			goto cam_vana_disable;
-		}
-		if (regulator_enable(cam_vio)) {
-			CDBG("%s: VREG VIO enable failed\n", __func__);
-			goto cam_vio_put;
-		}
-	}
-	if (cam_vdig == NULL) {
-		cam_vdig = regulator_get(dev, "cam_vdig");
-		if (IS_ERR(cam_vdig)) {
-			CDBG("%s: VREG CAM VDIG get failed\n", __func__);
-			cam_vdig = NULL;
-			goto cam_vio_disable;
-		}
-		if (regulator_set_voltage(cam_vdig, CAM_VDIG_MINUV,
-			CAM_VDIG_MAXUV)) {
-			CDBG("%s: VREG CAM VDIG set voltage failed\n",
-				__func__);
-			goto cam_vdig_put;
-		}
-		if (regulator_set_optimum_mode(cam_vdig,
-			CAM_VDIG_LOAD_UA) < 0) {
-			CDBG("%s: VREG CAM VDIG set optimum mode failed\n",
-				__func__);
-			goto cam_vdig_release;
-		}
-		if (regulator_enable(cam_vdig)) {
-			CDBG("%s: VREG CAM VDIG enable failed\n", __func__);
-			goto cam_vdig_disable;
-		}
-	}
-	if (cam_vaf == NULL) {
-		cam_vaf = regulator_get(dev, "cam_vaf");
-		if (IS_ERR(cam_vaf)) {
-			CDBG("%s: VREG CAM VAF get failed\n", __func__);
-			cam_vaf = NULL;
-			goto cam_vdig_disable;
-		}
-		if (regulator_set_voltage(cam_vaf, CAM_VAF_MINUV,
-			CAM_VAF_MAXUV)) {
-			CDBG("%s: VREG CAM VAF set voltage failed\n",
-				__func__);
-			goto cam_vaf_put;
-		}
-		if (regulator_set_optimum_mode(cam_vaf,
-			CAM_VAF_LOAD_UA) < 0) {
-			CDBG("%s: VREG CAM VAF set optimum mode failed\n",
-				__func__);
-			goto cam_vaf_release;
-		}
-		if (regulator_enable(cam_vaf)) {
-			CDBG("%s: VREG CAM VAF enable failed\n", __func__);
-			goto cam_vaf_disable;
-		}
-	}
-	return 0;
-
-cam_vaf_disable:
-	regulator_set_optimum_mode(cam_vaf, 0);
-cam_vaf_release:
-	regulator_set_voltage(cam_vaf, 0, CAM_VAF_MAXUV);
-	regulator_disable(cam_vaf);
-cam_vaf_put:
-	regulator_put(cam_vaf);
-	cam_vaf = NULL;
-cam_vdig_disable:
-	regulator_set_optimum_mode(cam_vdig, 0);
-cam_vdig_release:
-	regulator_set_voltage(cam_vdig, 0, CAM_VDIG_MAXUV);
-	regulator_disable(cam_vdig);
-cam_vdig_put:
-	regulator_put(cam_vdig);
-	cam_vdig = NULL;
-cam_vio_disable:
-	regulator_disable(cam_vio);
-cam_vio_put:
-	regulator_put(cam_vio);
-	cam_vio = NULL;
-cam_vana_disable:
-	regulator_set_optimum_mode(cam_vana, 0);
-cam_vana_release:
-	regulator_set_voltage(cam_vana, 0, CAM_VANA_MAXUV);
-	regulator_disable(cam_vana);
-cam_vana_put:
-	regulator_put(cam_vana);
-	cam_vana = NULL;
-mipi_csi_vdd_disable:
-	regulator_set_optimum_mode(mipi_csi_vdd, 0);
-mipi_csi_vdd_release:
-	regulator_set_voltage(mipi_csi_vdd, 0, CAM_CSI_VDD_MAXUV);
-	regulator_disable(mipi_csi_vdd);
-
-mipi_csi_vdd_put:
-	regulator_put(mipi_csi_vdd);
-	mipi_csi_vdd = NULL;
-	return -ENODEV;
-}
-
-static void msm_camera_vreg_disable(void)
-{
-	if (mipi_csi_vdd) {
-		regulator_set_voltage(mipi_csi_vdd, 0, CAM_CSI_VDD_MAXUV);
-		regulator_set_optimum_mode(mipi_csi_vdd, 0);
-		regulator_disable(mipi_csi_vdd);
-		regulator_put(mipi_csi_vdd);
-		mipi_csi_vdd = NULL;
-	}
-
-	if (cam_vana) {
-		regulator_set_voltage(cam_vana, 0, CAM_VANA_MAXUV);
-		regulator_set_optimum_mode(cam_vana, 0);
-		regulator_disable(cam_vana);
-		regulator_put(cam_vana);
-		cam_vana = NULL;
-	}
-
-	if (cam_vio) {
-		regulator_disable(cam_vio);
-		regulator_put(cam_vio);
-		cam_vio = NULL;
-	}
-
-	if (cam_vdig) {
-		regulator_set_voltage(cam_vdig, 0, CAM_VDIG_MAXUV);
-		regulator_set_optimum_mode(cam_vdig, 0);
-		regulator_disable(cam_vdig);
-		regulator_put(cam_vdig);
-		cam_vdig = NULL;
-	}
-
-	if (cam_vaf) {
-		regulator_set_voltage(cam_vaf, 0, CAM_VAF_MAXUV);
-		regulator_set_optimum_mode(cam_vaf, 0);
-		regulator_disable(cam_vaf);
-		regulator_put(cam_vaf);
-		cam_vaf = NULL;
-	}
-}
-
 int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
 {
 	int rc = 0;
 	struct clk *clk = NULL;
 
 	switch (clktype) {
-	case CAMIO_CAM_MCLK_CLK:
-		camio_cam_clk =
-		clk = clk_get(&camio_dev->dev, "cam_clk");
-		msm_camio_clk_rate_set_2(clk, camio_clk.mclk_clk_rate);
-		break;
-
 	case CAMIO_JPEG_CLK:
 		camio_jpeg_clk =
 		clk = clk_get(NULL, "ijpeg_clk");
@@ -375,10 +150,6 @@
 	struct clk *clk = NULL;
 
 	switch (clktype) {
-	case CAMIO_CAM_MCLK_CLK:
-		clk = camio_cam_clk;
-		break;
-
 	case CAMIO_JPEG_CLK:
 		clk = camio_jpeg_clk;
 		break;
@@ -403,12 +174,6 @@
 	return rc;
 }
 
-void msm_camio_clk_rate_set(int rate)
-{
-	struct clk *clk = camio_cam_clk;
-	clk_set_rate(clk, rate);
-}
-
 void msm_camio_clk_rate_set_2(struct clk *clk, int rate)
 {
 	clk_set_rate(clk, rate);
@@ -459,38 +224,6 @@
 	return rc;
 }
 
-static int config_gpio_table(struct msm_camera_sensor_info *sinfo, int gpio_en)
-{
-	struct msm_camera_gpio_conf *gpio_conf = sinfo->gpio_conf;
-	int rc = 0, i = 0;
-
-	if (gpio_conf->cam_gpio_tbl == NULL || gpio_conf->cam_gpiomux_conf_tbl
-		== NULL) {
-		pr_err("%s: Invalid NULL cam gpio config table\n", __func__);
-		return -EFAULT;
-	}
-
-	if (gpio_en) {
-		msm_gpiomux_install((struct msm_gpiomux_config *)gpio_conf->
-			cam_gpiomux_conf_tbl,
-			gpio_conf->cam_gpiomux_conf_tbl_size);
-		for (i = 0; i < gpio_conf->cam_gpio_tbl_size; i++) {
-			rc = gpio_request(gpio_conf->cam_gpio_tbl[i],
-				 "CAM_GPIO");
-			if (rc < 0) {
-				pr_err("%s not able to get gpio\n", __func__);
-				for (i--; i >= 0; i--)
-					gpio_free(gpio_conf->cam_gpio_tbl[i]);
-					break;
-			}
-		}
-	} else {
-		for (i = 0; i < gpio_conf->cam_gpio_tbl_size; i++)
-			gpio_free(gpio_conf->cam_gpio_tbl[i]);
-	}
-	return rc;
-}
-
 int32_t msm_camio_3d_enable(const struct msm_camera_sensor_info *s_info)
 {
 	int32_t val = 0, rc = 0;
@@ -557,61 +290,6 @@
 	release_mem_region(s3drw_mem->start, resource_size(s3drw_mem));
 }
 
-static struct pm8xxx_mpp_config_data privacy_light_on_config = {
-	.type		= PM8XXX_MPP_TYPE_SINK,
-	.level		= PM8XXX_MPP_CS_OUT_5MA,
-	.control	= PM8XXX_MPP_CS_CTRL_MPP_LOW_EN,
-};
-
-static struct pm8xxx_mpp_config_data privacy_light_off_config = {
-	.type		= PM8XXX_MPP_TYPE_SINK,
-	.level		= PM8XXX_MPP_CS_OUT_5MA,
-	.control	= PM8XXX_MPP_CS_CTRL_DISABLE,
-};
-
-static struct msm_cam_clk_info cam_clk_info[] = {
-	{"cam_clk", 24000000},
-};
-
-int msm_sensor_probe_on(struct device *dev)
-{
-	int rc = 0;
-	struct msm_camera_sensor_info *sinfo = dev->platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camio_clk = camdev->ioclk;
-
-	rc = config_gpio_table(sinfo, 1);
-	if (rc < 0)
-		return rc;
-	msm_camera_vreg_enable(dev);
-	if (sinfo->sensor_platform_info->privacy_light) {
-		struct msm8960_privacy_light_cfg *privacy_light_config =
-			sinfo->sensor_platform_info->privacy_light_info;
-		pm8xxx_mpp_config(privacy_light_config->mpp,
-						  &privacy_light_on_config);
-	}
-	return msm_cam_clk_enable(dev, cam_clk_info,
-		&camio_cam_clk, ARRAY_SIZE(cam_clk_info), 1);
-}
-
-int msm_sensor_probe_off(struct device *dev)
-{
-	int rc = 0;
-	struct msm_camera_sensor_info *sinfo = dev->platform_data;
-	if (sinfo->sensor_platform_info->privacy_light) {
-		struct msm8960_privacy_light_cfg *privacy_light_config =
-			sinfo->sensor_platform_info->privacy_light_info;
-		pm8xxx_mpp_config(privacy_light_config->mpp,
-						  &privacy_light_off_config);
-	}
-	msm_camera_vreg_disable();
-	rc = config_gpio_table(sinfo, 0);
-	if (rc < 0)
-		return rc;
-	return msm_cam_clk_enable(dev, cam_clk_info,
-		&camio_cam_clk, ARRAY_SIZE(cam_clk_info), 0);
-}
-
 void msm_camio_mode_config(enum msm_cam_mode mode)
 {
 	uint32_t val;
diff --git a/drivers/media/video/msm/sensors/imx074_v4l2.c b/drivers/media/video/msm/sensors/imx074_v4l2.c
index c77cfc3..f31aece 100644
--- a/drivers/media/video/msm/sensors/imx074_v4l2.c
+++ b/drivers/media/video/msm/sensors/imx074_v4l2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -331,6 +331,7 @@
 	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(imx074_subdev_info),
 	.sensor_v4l2_subdev_ops = &imx074_subdev_ops,
 	.func_tbl = &imx074_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
 };
 
 module_init(msm_sensor_init_module);
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 227e606..2c296618 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -445,26 +445,84 @@
 	return rc;
 }
 
+static struct msm_cam_clk_info cam_clk_info[] = {
+	{"cam_clk", MSM_SENSOR_MCLK_24HZ},
+};
+
 int32_t msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
 {
 	int32_t rc = 0;
 	struct msm_camera_sensor_info *data = s_ctrl->sensordata;
 	CDBG("%s: %d\n", __func__, __LINE__);
-	msm_sensor_probe_on(&s_ctrl->sensor_i2c_client->client->dev);
-	msm_camio_clk_rate_set(MSM_SENSOR_MCLK_24HZ);
-	rc = gpio_request(data->sensor_platform_info->sensor_reset,
-		"SENSOR_NAME");
-	if (!rc) {
-		CDBG("%s: reset sensor\n", __func__);
-		gpio_direction_output(data->sensor_platform_info->sensor_reset,
-			 0);
-		usleep_range(1000, 2000);
-		gpio_set_value_cansleep(data->sensor_platform_info->
-			sensor_reset, 1);
-		usleep_range(4000, 5000);
-	} else {
-		CDBG("%s: gpio request fail", __func__);
+	s_ctrl->reg_ptr = kzalloc(sizeof(struct regulator *)
+			* data->sensor_platform_info->num_vreg, GFP_KERNEL);
+	if (!s_ctrl->reg_ptr) {
+		pr_err("%s: could not allocate mem for regulators\n",
+			__func__);
+		return -ENOMEM;
 	}
+
+	rc = msm_camera_request_gpio_table(data, 1);
+	if (rc < 0) {
+		pr_err("%s: request gpio failed\n", __func__);
+		goto request_gpio_failed;
+	}
+
+	rc = msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+			s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+			s_ctrl->sensordata->sensor_platform_info->num_vreg,
+			s_ctrl->reg_ptr, 1);
+	if (rc < 0) {
+		pr_err("%s: regulator on failed\n", __func__);
+		goto config_vreg_failed;
+	}
+
+	rc = msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+			s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+			s_ctrl->sensordata->sensor_platform_info->num_vreg,
+			s_ctrl->reg_ptr, 1);
+	if (rc < 0) {
+		pr_err("%s: enable regulator failed\n", __func__);
+		goto enable_vreg_failed;
+	}
+
+	rc = msm_camera_config_gpio_table(data, 1);
+	if (rc < 0) {
+		pr_err("%s: config gpio failed\n", __func__);
+		goto config_gpio_failed;
+	}
+
+	if (s_ctrl->clk_rate != 0)
+		cam_clk_info->clk_rate = s_ctrl->clk_rate;
+
+	rc = msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->dev,
+		cam_clk_info, &s_ctrl->cam_clk, ARRAY_SIZE(cam_clk_info), 1);
+	if (rc < 0) {
+		pr_err("%s: clk enable failed\n", __func__);
+		goto enable_clk_failed;
+	}
+
+	if (data->sensor_platform_info->ext_power_ctrl != NULL)
+		data->sensor_platform_info->ext_power_ctrl(1);
+
+	return rc;
+enable_clk_failed:
+		msm_camera_config_gpio_table(data, 0);
+config_gpio_failed:
+	msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+			s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+			s_ctrl->sensordata->sensor_platform_info->num_vreg,
+			s_ctrl->reg_ptr, 0);
+
+enable_vreg_failed:
+	msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+		s_ctrl->sensordata->sensor_platform_info->num_vreg,
+		s_ctrl->reg_ptr, 0);
+config_vreg_failed:
+	msm_camera_request_gpio_table(data, 0);
+request_gpio_failed:
+	kfree(s_ctrl->reg_ptr);
 	return rc;
 }
 
@@ -472,10 +530,21 @@
 {
 	struct msm_camera_sensor_info *data = s_ctrl->sensordata;
 	CDBG("%s\n", __func__);
-	msm_sensor_probe_off(&s_ctrl->sensor_i2c_client->client->dev);
-	gpio_set_value_cansleep(data->sensor_platform_info->sensor_reset, 0);
-	usleep_range(1000, 2000);
-	gpio_free(data->sensor_platform_info->sensor_reset);
+	if (data->sensor_platform_info->ext_power_ctrl != NULL)
+		data->sensor_platform_info->ext_power_ctrl(0);
+	msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->dev,
+		cam_clk_info, &s_ctrl->cam_clk, ARRAY_SIZE(cam_clk_info), 0);
+	msm_camera_config_gpio_table(data, 0);
+	msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+		s_ctrl->sensordata->sensor_platform_info->num_vreg,
+		s_ctrl->reg_ptr, 0);
+	msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+		s_ctrl->sensordata->sensor_platform_info->num_vreg,
+		s_ctrl->reg_ptr, 0);
+	msm_camera_request_gpio_table(data, 0);
+	kfree(s_ctrl->reg_ptr);
 	return 0;
 }
 
@@ -530,6 +599,10 @@
 	}
 
 	s_ctrl->sensordata = client->dev.platform_data;
+	if (s_ctrl->sensordata == NULL) {
+		pr_err("%s: NULL sensor data\n", __func__);
+		return -EFAULT;
+	}
 
 	rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
 	if (rc < 0)
diff --git a/drivers/media/video/msm/sensors/msm_sensor.h b/drivers/media/video/msm/sensors/msm_sensor.h
index ba366e6..2b1be1e 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.h
+++ b/drivers/media/video/msm/sensors/msm_sensor.h
@@ -166,6 +166,9 @@
 	uint8_t sensor_v4l2_subdev_info_size;
 	struct v4l2_subdev_ops *sensor_v4l2_subdev_ops;
 	struct msm_sensor_fn_t *func_tbl;
+	struct regulator **reg_ptr;
+	struct clk *cam_clk;
+	long clk_rate;
 };
 
 void msm_sensor_start_stream(struct msm_sensor_ctrl_t *s_ctrl);
diff --git a/drivers/media/video/msm/sensors/ov2720.c b/drivers/media/video/msm/sensors/ov2720.c
index 6389498..246900e 100644
--- a/drivers/media/video/msm/sensors/ov2720.c
+++ b/drivers/media/video/msm/sensors/ov2720.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -492,6 +492,7 @@
 	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov2720_subdev_info),
 	.sensor_v4l2_subdev_ops = &ov2720_subdev_ops,
 	.func_tbl = &ov2720_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
 };
 
 module_init(msm_sensor_init_module);
diff --git a/drivers/mfd/pm8xxx-pwm.c b/drivers/mfd/pm8xxx-pwm.c
index 523d3b6..05f02c4 100644
--- a/drivers/mfd/pm8xxx-pwm.c
+++ b/drivers/mfd/pm8xxx-pwm.c
@@ -27,8 +27,14 @@
 
 #define PM8XXX_PWM_CHANNELS		3
 
-#define PM8XXX_LPG_BANKS                8
-#define PM8XXX_LPG_PWM_CHANNELS         PM8XXX_LPG_BANKS
+/*
+ * For the lack of better term to distinguish functional
+ * differences, hereby, LPG version 0 (V0, v0) denotes
+ * PM8058/8921, and version 1 (V1, v1) denotes
+ * PM8922/8038.
+ */
+#define PM8XXX_LPG_V0_PWM_CHANNELS	8
+#define PM8XXX_LPG_V1_PWM_CHANNELS	6
 #define PM8XXX_LPG_CTL_REGS		7
 
 /* PM8XXX PWM */
@@ -149,32 +155,32 @@
 #define NSEC_32768HZ	(NSEC_PER_SEC / 32768)
 #define NSEC_19P2MHZ	(NSEC_PER_SEC / 19200000)
 
-#define CLK_PERIOD_MIN	NSEC_19P2MHZ
-#define CLK_PERIOD_MAX	NSEC_1024HZ
-
-#define NUM_LPG_PRE_DIVIDE	3  /* No default support for pre-divide = 6 */
+#define NUM_LPG_PRE_DIVIDE	4
 #define NUM_PWM_PRE_DIVIDE	2
 
-#define PRE_DIVIDE_0		2
-#define PRE_DIVIDE_1		3
-#define PRE_DIVIDE_2		5
-
-#define PRE_DIVIDE_MIN		PRE_DIVIDE_0
-#define PRE_DIVIDE_MAX		PRE_DIVIDE_2
+#define PRE_DIVIDE_1		1	/* v1 */
+#define PRE_DIVIDE_2		2
+#define PRE_DIVIDE_3		3
+#define PRE_DIVIDE_5		5
+#define PRE_DIVIDE_6		6
 
 static unsigned int pt_t[NUM_LPG_PRE_DIVIDE][NUM_CLOCKS] = {
-	{	PRE_DIVIDE_0 * NSEC_1024HZ,
-		PRE_DIVIDE_0 * NSEC_32768HZ,
-		PRE_DIVIDE_0 * NSEC_19P2MHZ,
-	},
-	{	PRE_DIVIDE_1 * NSEC_1024HZ,
-		PRE_DIVIDE_1 * NSEC_32768HZ,
-		PRE_DIVIDE_1 * NSEC_19P2MHZ,
-	},
 	{	PRE_DIVIDE_2 * NSEC_1024HZ,
 		PRE_DIVIDE_2 * NSEC_32768HZ,
 		PRE_DIVIDE_2 * NSEC_19P2MHZ,
 	},
+	{	PRE_DIVIDE_3 * NSEC_1024HZ,
+		PRE_DIVIDE_3 * NSEC_32768HZ,
+		PRE_DIVIDE_3 * NSEC_19P2MHZ,
+	},
+	{	PRE_DIVIDE_5 * NSEC_1024HZ,
+		PRE_DIVIDE_5 * NSEC_32768HZ,
+		PRE_DIVIDE_5 * NSEC_19P2MHZ,
+	},
+	{	PRE_DIVIDE_6 * NSEC_1024HZ,
+		PRE_DIVIDE_6 * NSEC_32768HZ,
+		PRE_DIVIDE_6 * NSEC_19P2MHZ,
+	},
 };
 
 /* Private data */
@@ -1337,11 +1343,19 @@
 
 	if (version == PM8XXX_VERSION_8921 ||
 			version == PM8XXX_VERSION_8058 ||
-			version == PM8XXX_VERSION_8922) {
+			version == PM8XXX_VERSION_8922 ||
+			version == PM8XXX_VERSION_8038) {
 		chip->is_lpg_supported = 1;
 	}
 	if (chip->is_lpg_supported) {
-		chip->pwm_channels = PM8XXX_LPG_PWM_CHANNELS;
+		if (version == PM8XXX_VERSION_8922 ||
+				version == PM8XXX_VERSION_8038) {
+			for (i = 0; i < NUM_CLOCKS; i++)
+				pt_t[0][i] /= PRE_DIVIDE_2;
+			chip->pwm_channels = PM8XXX_LPG_V1_PWM_CHANNELS;
+		} else {
+			chip->pwm_channels = PM8XXX_LPG_V0_PWM_CHANNELS;
+		}
 		chip->pwm_total_pre_divs = NUM_LPG_PRE_DIVIDE;
 	} else {
 		chip->pwm_channels = PM8XXX_PWM_CHANNELS;
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index c40f13e..51ec91c 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -263,6 +263,7 @@
 	enum pm8921_chg_hot_thr		hot_thr;
 };
 
+static int usb_max_current;
 static int charging_disabled;
 static int thermal_mitigation;
 
@@ -575,6 +576,22 @@
 	return 0;
 }
 
+struct usb_ma_limit_entry {
+	int usb_ma;
+	u8  chg_iusb_value;
+};
+
+static struct usb_ma_limit_entry usb_ma_table[] = {
+	{100, 0},
+	{500, 1},
+	{700, 2},
+	{850, 3},
+	{900, 4},
+	{1100, 5},
+	{1300, 6},
+	{1500, 7},
+};
+
 #define PM8921_CHG_IUSB_MASK 0x1C
 #define PM8921_CHG_IUSB_MAX  7
 #define PM8921_CHG_IUSB_MIN  0
@@ -591,6 +608,26 @@
 					 temp);
 }
 
+static int pm_chg_iusbmax_get(struct pm8921_chg_chip *chip, int *mA)
+{
+	u8 temp;
+	int i, rc;
+
+	*mA = 0;
+	rc = pm8xxx_readb(chip->dev->parent, PBL_ACCESS2, &temp);
+	if (rc) {
+		pr_err("err=%d reading PBL_ACCESS2\n", rc);
+		return rc;
+	}
+	temp &= PM8921_CHG_IUSB_MASK;
+	temp = temp >> 2;
+	for (i = ARRAY_SIZE(usb_ma_table) - 1; i >= 0; i--) {
+		if (usb_ma_table[i].chg_iusb_value == temp)
+			*mA = usb_ma_table[i].usb_ma;
+	}
+	return rc;
+}
+
 #define PM8921_CHG_WD_MASK 0x1F
 static int pm_chg_disable_wd(struct pm8921_chg_chip *chip)
 {
@@ -1209,27 +1246,17 @@
 	}
 }
 
-struct usb_ma_limit_entry {
-	int usb_ma;
-	u8  chg_iusb_value;
-};
-
-static struct usb_ma_limit_entry usb_ma_table[] = {
-	{100, 0},
-	{500, 1},
-	{700, 2},
-	{850, 3},
-	{900, 4},
-	{1100, 5},
-	{1300, 6},
-	{1500, 7},
-};
-
 /* assumes vbus_lock is held */
 static void __pm8921_charger_vbus_draw(unsigned int mA)
 {
 	int i, rc;
 
+	if (usb_max_current && mA > usb_max_current) {
+		pr_warn("restricting usb current to %d instead of %d\n",
+					usb_max_current, mA);
+		mA = usb_max_current;
+	}
+
 	if (mA > 0 && mA <= 2) {
 		usb_chg_current = 0;
 		rc = pm_chg_iusbmax_set(the_chip,
@@ -2391,6 +2418,28 @@
 					param_get_uint,
 					&thermal_mitigation, 0644);
 
+static int set_usb_max_current(const char *val, struct kernel_param *kp)
+{
+	int ret, mA;
+	struct pm8921_chg_chip *chip = the_chip;
+
+	ret = param_set_int(val, kp);
+	if (ret) {
+		pr_err("error setting value %d\n", ret);
+		return ret;
+	}
+	if (chip) {
+		pr_warn("setting current max to %d\n", usb_max_current);
+		pm_chg_iusbmax_get(chip, &mA);
+		if (mA > usb_max_current)
+			pm8921_charger_vbus_draw(usb_max_current);
+		return 0;
+	}
+	return -EINVAL;
+}
+module_param_call(usb_max_current, set_usb_max_current, param_get_uint,
+					&usb_max_current, 0644);
+
 static void free_irqs(struct pm8921_chg_chip *chip)
 {
 	int i;
@@ -3200,6 +3249,7 @@
 	enable_irq_wake(chip->pmic_chg_irq[USBIN_UV_IRQ]);
 	enable_irq_wake(chip->pmic_chg_irq[BAT_TEMP_OK_IRQ]);
 	enable_irq_wake(chip->pmic_chg_irq[VBATDET_LOW_IRQ]);
+	enable_irq_wake(chip->pmic_chg_irq[FASTCHG_IRQ]);
 	/*
 	 * if both the cool_temp_dc and warm_temp_dc are invalid device doesnt
 	 * care for jeita compliance
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index 1ac301f..6733396 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -25,6 +25,8 @@
 #define SLIM_HDL_TO_FLOW(hdl)	(((u32)(hdl) & 0xFF0000) >> 16)
 #define SLIM_HDL_TO_PORT(hdl)	((u32)(hdl) & 0xFF)
 
+#define SLIM_HDL_TO_CHIDX(hdl)	((u16)(hdl) & 0xFF)
+
 #define SLIM_SLAVE_PORT(p, la)	(((la)<<16) | (p))
 #define SLIM_MGR_PORT(p)	((0xFF << 16) | (p))
 #define SLIM_LA_MANAGER		0xFF
@@ -1104,75 +1106,117 @@
 }
 
 /*
- * slim_connect_ports: Connect port(s) to channel.
+ * slim_connect_src: Connect source port to channel.
  * @sb: client handle
- * @srch: source handles to be connected to this channel
- * @nrsc: number of source ports
- * @sinkh: sink handle to be connected to this channel
+ * @srch: source handle to be connected to this channel
  * @chanh: Channel with which the ports need to be associated with.
- * Per slimbus specification, a channel may have multiple source-ports and 1
- * sink port.Channel specified in chanh needs to be allocated first.
+ * Per slimbus specification, a channel may have 1 source port.
+ * Channel specified in chanh needs to be allocated first.
+ * Returns -EALREADY if source is already configured for this channel.
+ * Returns -ENOTCONN if channel is not allocated
  */
-int slim_connect_ports(struct slim_device *sb, u32 *srch, int nsrc, u32 sinkh,
-			u16 chanh)
+int slim_connect_src(struct slim_device *sb, u32 srch, u16 chanh)
+{
+	struct slim_controller *ctrl = sb->ctrl;
+	int ret;
+	u8 chan = SLIM_HDL_TO_CHIDX(chanh);
+	struct slim_ich *slc = &ctrl->chans[chan];
+	enum slim_port_flow flow = SLIM_HDL_TO_FLOW(srch);
+
+	if (flow != SLIM_SRC)
+		return -EINVAL;
+
+	mutex_lock(&ctrl->m_ctrl);
+
+	if (slc->state == SLIM_CH_FREE) {
+		ret = -ENOTCONN;
+		goto connect_src_err;
+	}
+	/*
+	 * Once channel is removed, its ports can be considered disconnected
+	 * So its ports can be reassigned. Source port is zeroed
+	 * when channel is deallocated.
+	 */
+	if (slc->srch) {
+		ret = -EALREADY;
+		goto connect_src_err;
+	}
+
+	ret = connect_port_ch(ctrl, chan, srch, SLIM_SRC);
+
+	if (!ret)
+		slc->srch = srch;
+
+connect_src_err:
+	mutex_unlock(&ctrl->m_ctrl);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(slim_connect_src);
+
+/*
+ * slim_connect_sink: Connect sink port(s) to channel.
+ * @sb: client handle
+ * @sinkh: sink handle(s) to be connected to this channel
+ * @nsink: number of sinks
+ * @chanh: Channel with which the ports need to be associated with.
+ * Per slimbus specification, a channel may have multiple sink-ports.
+ * Channel specified in chanh needs to be allocated first.
+ * Returns -EALREADY if sink is already configured for this channel.
+ * Returns -ENOTCONN if channel is not allocated
+ */
+int slim_connect_sink(struct slim_device *sb, u32 *sinkh, int nsink, u16 chanh)
 {
 	struct slim_controller *ctrl = sb->ctrl;
 	int j;
 	int ret = 0;
-	u8 chan = (u8)(chanh & 0xFF);
+	u8 chan = SLIM_HDL_TO_CHIDX(chanh);
 	struct slim_ich *slc = &ctrl->chans[chan];
 
+	if (!sinkh || !nsink)
+		return -EINVAL;
+
 	mutex_lock(&ctrl->m_ctrl);
-	/* Make sure the channel is not already pending reconf. or active */
-	if (slc->state >= SLIM_CH_PENDING_ACTIVE) {
-		dev_err(&ctrl->dev, "Channel %d  already active", chan);
-		ret = -EISCONN;
-		goto connect_port_err;
-	}
 
 	/*
 	 * Once channel is removed, its ports can be considered disconnected
-	 * So its ports can be reassigned. Source port array is freed
-	 * when channel is deallocated.
+	 * So its ports can be reassigned. Sink ports are freed when channel
+	 * is deallocated.
 	 */
-	slc->srch = krealloc(slc->srch, (sizeof(u32) * nsrc), GFP_KERNEL);
-	if (!slc->srch) {
-		ret = -ENOMEM;
-		goto connect_port_err;
+	if (slc->state == SLIM_CH_FREE) {
+		ret = -ENOTCONN;
+		goto connect_sink_err;
 	}
 
-	/* connect source */
-	for (j = 0; j < nsrc; j++) {
-		ret = connect_port_ch(ctrl, chan, srch[j], SLIM_SRC);
+	for (j = 0; j < nsink; j++) {
+		enum slim_port_flow flow = SLIM_HDL_TO_FLOW(sinkh[j]);
+		if (flow != SLIM_SINK)
+			ret = -EINVAL;
+		else
+			ret = connect_port_ch(ctrl, chan, sinkh[j], SLIM_SINK);
 		if (ret) {
-			for ( ; j >= 0 ; j--)
-				disconnect_port_ch(ctrl,
-						srch[j]);
-			kfree(slc->srch);
-			slc->srch = NULL;
-			goto connect_port_err;
+			for (j = j - 1; j >= 0; j--)
+				disconnect_port_ch(ctrl, sinkh[j]);
+			goto connect_sink_err;
 		}
 	}
-	/* connect sink */
-	ret = connect_port_ch(ctrl, chan, sinkh, SLIM_SINK);
-	if (ret) {
-		for (j = 0; j < nsrc; j++)
-			disconnect_port_ch(ctrl, srch[j]);
-		kfree(slc->srch);
-		slc->srch = NULL;
-		goto connect_port_err;
+
+	slc->sinkh = krealloc(slc->sinkh, (sizeof(u32) * (slc->nsink + nsink)),
+				GFP_KERNEL);
+	if (!slc->sinkh) {
+		ret = -ENOMEM;
+		for (j = 0; j < nsink; j++)
+			disconnect_port_ch(ctrl, sinkh[j]);
+		goto connect_sink_err;
 	}
 
-	memcpy(slc->srch, srch, (sizeof(u32) * nsrc));
-	slc->nsrc = nsrc;
-	if (sinkh)
-		slc->sinkh = sinkh;
+	memcpy(slc->sinkh + slc->nsink, sinkh, (sizeof(u32) * nsink));
+	slc->nsink += nsink;
 
-connect_port_err:
+connect_sink_err:
 	mutex_unlock(&ctrl->m_ctrl);
 	return ret;
 }
-EXPORT_SYMBOL_GPL(slim_connect_ports);
+EXPORT_SYMBOL_GPL(slim_connect_sink);
 
 /*
  * slim_disconnect_ports: Disconnect port(s) from channel
@@ -1332,8 +1376,8 @@
 	slc->state = SLIM_CH_ALLOCATED;
 	slc->newintr = 0;
 	slc->newoff = 0;
-	for (i = 0; i < slc->nsrc; i++) {
-		ph = slc->srch[i];
+	for (i = 0; i < slc->nsink; i++) {
+		ph = slc->sinkh[i];
 		la = SLIM_HDL_TO_LA(ph);
 		/*
 		 * For ports managed by manager's ported device, no need to send
@@ -1344,11 +1388,15 @@
 			ctrl->ports[SLIM_HDL_TO_PORT(ph)].state = SLIM_P_UNCFG;
 	}
 
-	ph = slc->sinkh;
+	ph = slc->srch;
 	la = SLIM_HDL_TO_LA(ph);
 	if (la == SLIM_LA_MANAGER)
 		ctrl->ports[SLIM_HDL_TO_PORT(ph)].state = SLIM_P_UNCFG;
 
+	kfree(slc->sinkh);
+	slc->sinkh = NULL;
+	slc->srch = 0;
+	slc->nsink = 0;
 	return 0;
 }
 
@@ -1608,7 +1656,7 @@
 int slim_dealloc_ch(struct slim_device *sb, u16 chanh)
 {
 	struct slim_controller *ctrl = sb->ctrl;
-	u8 chan = (u8)(chanh & 0xFF);
+	u8 chan = SLIM_HDL_TO_CHIDX(chanh);
 	struct slim_ich *slc = &ctrl->chans[chan];
 	if (!ctrl)
 		return -EINVAL;
@@ -1631,8 +1679,6 @@
 		return -EISCONN;
 	}
 	slc->ref--;
-	kfree(slc->srch);
-	slc->srch = NULL;
 	slc->state = SLIM_CH_FREE;
 	mutex_unlock(&ctrl->m_ctrl);
 	dev_dbg(&ctrl->dev, "remove chan:%d,hdl:%d,ref:%d",
@@ -1647,7 +1693,7 @@
  */
 enum slim_ch_state slim_get_ch_state(struct slim_device *sb, u16 chanh)
 {
-	u8 chan = (u8)(chanh & 0xFF);
+	u8 chan = SLIM_HDL_TO_CHIDX(chanh);
 	struct slim_ich *slc = &sb->ctrl->chans[chan];
 	return slc->state;
 }
@@ -1678,7 +1724,7 @@
 		return -EINVAL;
 	mutex_lock(&ctrl->m_ctrl);
 	for (i = 0; i < nchan; i++) {
-		u8 chan = (u8)(chanh[i] & 0xFF);
+		u8 chan = SLIM_HDL_TO_CHIDX(chanh[i]);
 		struct slim_ich *slc = &ctrl->chans[chan];
 		dev_dbg(&ctrl->dev, "define_ch: ch:%d, state:%d", chan,
 				(int)ctrl->chans[chan].state);
@@ -1713,7 +1759,7 @@
 	if (grp)
 		*grph = chanh[0];
 	for (i = 0; i < nchan; i++) {
-		u8 chan = (u8)(chanh[i] & 0xFF);
+		u8 chan = SLIM_HDL_TO_CHIDX(chanh[i]);
 		struct slim_ich *slc = &ctrl->chans[chan];
 		if (slc->state == SLIM_CH_ALLOCATED)
 			slc->state = SLIM_CH_DEFINED;
@@ -2265,7 +2311,7 @@
 	for (; last > 0; last--) {
 		struct slim_ich *slc1 = slc;
 		struct slim_ich *slc2;
-		u8 next = (u8)(slc1->nextgrp & 0xFF);
+		u8 next = SLIM_HDL_TO_CHIDX(slc1->nextgrp);
 		slc2 = &ctrl->chans[next];
 		for (second = 1; second <= last && slc2 &&
 			(slc2->state == SLIM_CH_ACTIVE ||
@@ -2280,7 +2326,7 @@
 				break;
 			}
 			slc1 = slc2;
-			next = (u8)(slc1->nextgrp & 0xFF);
+			next = SLIM_HDL_TO_CHIDX(slc1->nextgrp);
 			slc2 = &ctrl->chans[next];
 		}
 		if (slc2 == NULL)
@@ -2692,7 +2738,7 @@
 	struct slim_ich *slc;
 	int ret = 0;
 	/* Get rid of the group flag in MSB if any */
-	u8 chan = (u8)(chanh & 0xFF);
+	u8 chan = SLIM_HDL_TO_CHIDX(chanh);
 	mutex_lock(&sb->sldev_reconf);
 	mutex_lock(&ctrl->m_ctrl);
 	do {
@@ -2729,7 +2775,7 @@
 		}
 
 		if (!(slc->nextgrp & SLIM_END_GRP))
-			chan = (u8)(slc->nextgrp & 0xFF);
+			chan = SLIM_HDL_TO_CHIDX(slc->nextgrp);
 	} while (!(slc->nextgrp & SLIM_END_GRP));
 	mutex_unlock(&ctrl->m_ctrl);
 	if (!ret && commit == true)
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index ee7a2a9..c0c6c1e 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -1493,6 +1493,7 @@
 }
 
 static struct platform_driver android_platform_driver = {
+	.probe = android_probe,
 	.driver = { .name = "android_usb"},
 };
 
@@ -1527,7 +1528,7 @@
 	composite_driver.setup = android_setup;
 	composite_driver.disconnect = android_disconnect;
 
-	ret = platform_driver_probe(&android_platform_driver, android_probe);
+	ret = platform_driver_register(&android_platform_driver);
 	if (ret) {
 		pr_err("%s(): Failed to register android"
 				 "platform driver\n", __func__);
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index 10a9256..987ae65 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -525,7 +525,6 @@
 	if (rc) {
 		ERROR(dev->cdev, "can't enable %s, result %d\n",
 						dev->in->name, rc);
-		dev->in->driver_data = NULL;
 		return rc;
 	}
 	dev->out->driver_data = dev;
@@ -534,8 +533,6 @@
 		ERROR(dev->cdev, "can't enable %s, result %d\n",
 						dev->out->name, rc);
 		usb_ep_disable(dev->in);
-		dev->in->driver_data = NULL;
-		dev->out->driver_data = NULL;
 		return rc;
 	}
 	schedule_work(&dev->config_work);
diff --git a/drivers/usb/gadget/f_rmnet_smd.c b/drivers/usb/gadget/f_rmnet_smd.c
index f59b683..2049dc0 100644
--- a/drivers/usb/gadget/f_rmnet_smd.c
+++ b/drivers/usb/gadget/f_rmnet_smd.c
@@ -5,7 +5,7 @@
  * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
  * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com)
  * Copyright (C) 2008 Nokia Corporation
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -116,6 +116,8 @@
 	atomic_t		online;
 	atomic_t		notify_count;
 
+	struct platform_driver		pdrv;
+	u8				is_pdrv_used;
 	struct rmnet_smd_ch_info	smd_ctl;
 	struct rmnet_smd_ch_info	smd_data;
 
@@ -134,6 +136,8 @@
 	unsigned long	cpkts_to_modem;
 };
 
+static struct rmnet_smd_dev *rmnet_smd;
+
 static struct usb_interface_descriptor rmnet_smd_interface_desc = {
 	.bLength =		USB_DT_INTERFACE_SIZE,
 	.bDescriptorType =	USB_DT_INTERFACE,
@@ -856,6 +860,10 @@
 		list_add_tail(&qmi->list, &dev->qmi_resp_pool);
 	}
 
+	if (dev->is_pdrv_used) {
+		platform_driver_unregister(&dev->pdrv);
+		dev->is_pdrv_used = 0;
+	}
 }
 
 /* SMD close may sleep
@@ -894,7 +902,18 @@
 	ret = smd_open(rmnet_ctl_ch, &dev->smd_ctl.ch,
 			&dev->smd_ctl, rmnet_smd_event_notify);
 	if (ret) {
-		ERROR(cdev, "Unable to open control smd channel\n");
+		ERROR(cdev, "Unable to open control smd channel: %d\n", ret);
+		/*
+		 * Register platform driver to be notified in case SMD channels
+		 * later becomes ready to be opened.
+		 */
+		ret = platform_driver_register(&dev->pdrv);
+		if (ret)
+			ERROR(cdev, "Platform driver %s register failed %d\n",
+					dev->pdrv.driver.name, ret);
+		else
+			dev->is_pdrv_used = 1;
+
 		return;
 	}
 	wait_event(dev->smd_ctl.wait, test_bit(CH_OPENED,
@@ -916,6 +935,15 @@
 	rmnet_smd_start_rx(dev);
 }
 
+static int rmnet_smd_ch_probe(struct platform_device *pdev)
+{
+	DBG(rmnet_smd->cdev, "Probe called for device: %s\n", pdev->name);
+
+	queue_work(rmnet_smd->wq, &rmnet_smd->connect_work);
+
+	return 0;
+}
+
 /* SMD open may sleep.
  * Schedule a work to open smd channels and enable
  * endpoints if smd channels are opened successfully.
@@ -1272,6 +1300,8 @@
 	if (!dev)
 		return -ENOMEM;
 
+	rmnet_smd = dev;
+
 	dev->wq = create_singlethread_workqueue("k_rmnet_work");
 	if (!dev->wq) {
 		ret = -ENOMEM;
@@ -1299,6 +1329,10 @@
 	init_waitqueue_head(&dev->smd_ctl.wait);
 	init_waitqueue_head(&dev->smd_data.wait);
 
+	dev->pdrv.probe = rmnet_smd_ch_probe;
+	dev->pdrv.driver.name = CONFIG_RMNET_SMD_CTL_CHANNEL;
+	dev->pdrv.driver.owner = THIS_MODULE;
+
 	INIT_LIST_HEAD(&dev->qmi_req_pool);
 	INIT_LIST_HEAD(&dev->qmi_req_q);
 	INIT_LIST_HEAD(&dev->qmi_resp_pool);
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index d9a901b..de8c8ed 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -477,7 +477,6 @@
 	if (gser->notify->driver_data) {
 		DBG(cdev, "reset generic ctl ttyGS%d\n", gser->port_num);
 		usb_ep_disable(gser->notify);
-		gser->notify->driver_data = NULL;
 	}
 	gser->notify_desc = ep_choose(cdev->gadget,
 			gser->hs.notify,
@@ -520,7 +519,6 @@
 #ifdef CONFIG_MODEM_SUPPORT
 	usb_ep_fifo_flush(gser->notify);
 	usb_ep_disable(gser->notify);
-	gser->notify->driver_data = NULL;
 #endif
 	gser->online = 0;
 }
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index ca298cd..0360f56 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -2766,17 +2766,14 @@
 	if (fsg->bulk_in_enabled) {
 		usb_ep_disable(fsg->bulk_in);
 		fsg->bulk_in_enabled = 0;
-		fsg_bulk_in->driver_data = NULL;
 	}
 	if (fsg->bulk_out_enabled) {
 		usb_ep_disable(fsg->bulk_out);
 		fsg->bulk_out_enabled = 0;
-		fsg_bulk_out->driver_data = NULL;
 	}
 	if (fsg->intr_in_enabled) {
 		usb_ep_disable(fsg->intr_in);
 		fsg->intr_in_enabled = 0;
-		fsg_intr_in->driver_data = NULL;
 	}
 
 	fsg->running = 0;
diff --git a/drivers/usb/gadget/u_rmnet_ctrl_smd.c b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
index edba510..a55fc77 100644
--- a/drivers/usb/gadget/u_rmnet_ctrl_smd.c
+++ b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -59,7 +59,7 @@
 	struct grmnet		*port_usb;
 
 	spinlock_t		port_lock;
-	struct work_struct	connect_w;
+	struct delayed_work	connect_w;
 };
 
 static struct rmnet_ctrl_ports {
@@ -320,7 +320,7 @@
 static void grmnet_ctrl_smd_connect_w(struct work_struct *w)
 {
 	struct rmnet_ctrl_port *port =
-			container_of(w, struct rmnet_ctrl_port, connect_w);
+			container_of(w, struct rmnet_ctrl_port, connect_w.work);
 	struct smd_ch_info *c = &port->ctrl_ch;
 	unsigned long flags;
 	int ret;
@@ -332,8 +332,16 @@
 
 	ret = smd_open(c->name, &c->ch, port, grmnet_ctrl_smd_notify);
 	if (ret) {
-		pr_err("%s: Unable to open smd ch:%s err:%d\n",
-				__func__, c->name, ret);
+		if (ret == -EAGAIN) {
+			/* port not ready  - retry */
+			pr_debug("%s: SMD port not ready - rescheduling:%s err:%d\n",
+					__func__, c->name, ret);
+			queue_delayed_work(grmnet_ctrl_wq, &port->connect_w,
+				msecs_to_jiffies(250));
+		} else {
+			pr_err("%s: unable to open smd port:%s err:%d\n",
+					__func__, c->name, ret);
+		}
 		return;
 	}
 
@@ -370,7 +378,7 @@
 	gr->notify_modem = gsmd_ctrl_send_cbits_tomodem;
 	spin_unlock_irqrestore(&port->port_lock, flags);
 
-	queue_work(grmnet_ctrl_wq, &port->connect_w);
+	queue_delayed_work(grmnet_ctrl_wq, &port->connect_w, 0);
 
 	return 0;
 }
@@ -442,7 +450,8 @@
 			/* if usb is online, try opening smd_ch */
 			spin_lock_irqsave(&port->port_lock, flags);
 			if (port->port_usb)
-				queue_work(grmnet_ctrl_wq, &port->connect_w);
+				queue_delayed_work(grmnet_ctrl_wq,
+							&port->connect_w, 0);
 			spin_unlock_irqrestore(&port->port_lock, flags);
 
 			break;
@@ -503,7 +512,7 @@
 	port->port_num = portno;
 
 	spin_lock_init(&port->port_lock);
-	INIT_WORK(&port->connect_w, grmnet_ctrl_smd_connect_w);
+	INIT_DELAYED_WORK(&port->connect_w, grmnet_ctrl_smd_connect_w);
 
 	c = &port->ctrl_ch;
 	c->name = rmnet_ctrl_names[portno];
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index eb76b30..896f21b 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1030,7 +1030,9 @@
 		return;
 
 	if (motg->pdata->vbus_power) {
-		motg->pdata->vbus_power(on);
+		ret = motg->pdata->vbus_power(on);
+		if (!ret)
+			vbus_is_on = on;
 		return;
 	}
 
@@ -1862,7 +1864,6 @@
 					otg->state = OTG_STATE_B_PERIPHERAL;
 					break;
 				case USB_SDP_CHARGER:
-					msm_otg_notify_charger(motg, IUNIT);
 					msm_otg_start_peripheral(otg, 1);
 					otg->state = OTG_STATE_B_PERIPHERAL;
 					break;
diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h
index c47b6ec..de8d490 100644
--- a/drivers/usb/serial/usb-wwan.h
+++ b/drivers/usb/serial/usb-wwan.h
@@ -31,10 +31,10 @@
 
 /* per port private data */
 
-#define N_IN_URB 4
-#define N_OUT_URB 4
-#define IN_BUFLEN 4096
-#define OUT_BUFLEN 4096
+#define N_IN_URB 5
+#define N_OUT_URB 5
+#define IN_BUFLEN 65536
+#define OUT_BUFLEN 65536
 
 struct usb_wwan_intf_private {
 	spinlock_t susp_lock;
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index fcf4b08..2a08101 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -410,6 +410,7 @@
 	tty->raw = 1;
 	tty->real_raw = 1;
 
+	set_bit(TTY_NO_WRITE_SPLIT, &tty->flags);
 	dbg("%s", __func__);
 
 	/* Start reading from the IN endpoint */
@@ -552,7 +553,7 @@
 		init_usb_anchor(&portdata->delayed);
 
 		for (j = 0; j < N_IN_URB; j++) {
-			buffer = (u8 *) __get_free_page(GFP_KERNEL);
+			buffer = kmalloc(IN_BUFLEN, GFP_KERNEL);
 			if (!buffer)
 				goto bail_out_error;
 			portdata->in_buffer[j] = buffer;
@@ -581,8 +582,7 @@
 		kfree(portdata->out_buffer[j]);
 bail_out_error:
 	for (j = 0; j < N_IN_URB; j++)
-		if (portdata->in_buffer[j])
-			free_page((unsigned long)portdata->in_buffer[j]);
+		kfree(portdata->in_buffer[j]);
 	kfree(portdata);
 	return 1;
 }
@@ -628,8 +628,7 @@
 
 		for (j = 0; j < N_IN_URB; j++) {
 			usb_free_urb(portdata->in_urbs[j]);
-			free_page((unsigned long)
-				  portdata->in_buffer[j]);
+			kfree(portdata->in_buffer[j]);
 			portdata->in_urbs[j] = NULL;
 		}
 		for (j = 0; j < N_OUT_URB; j++) {
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 1449c8e..512480c 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -1326,10 +1326,9 @@
 	struct msm_fb_panel_data *pdata = NULL;
 	int rc;
 	resource_size_t  size ;
+	unsigned long flag;
 #ifdef CONFIG_FB_MSM_MDP40
 	int intf, if_no;
-#else
-	unsigned long flag;
 #endif
 #if defined(CONFIG_FB_MSM_MIPI_DSI) && defined(CONFIG_FB_MSM_MDP40)
 	struct mipi_panel_info *mipi;
@@ -1474,6 +1473,17 @@
 			mfd->vsync_gpio = -1;
 
 #ifdef CONFIG_FB_MSM_MDP40
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		spin_lock_irqsave(&mdp_spin_lock, flag);
+		mdp_intr_mask |= INTR_OVERLAY0_DONE;
+		if (mdp_hw_revision < MDP4_REVISION_V2_1) {
+			/* dmas dmap switch */
+			mdp_intr_mask |= INTR_DMA_S_DONE;
+		}
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		spin_unlock_irqrestore(&mdp_spin_lock, flag);
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
 		if (mfd->panel.type == EBI2_PANEL)
 			intf = EBI2_INTF;
 		else
@@ -1530,10 +1540,8 @@
 	case MIPI_CMD_PANEL:
 #ifndef CONFIG_FB_MSM_MDP303
 		mfd->dma_fnc = mdp4_dsi_cmd_overlay;
-#ifdef CONFIG_FB_MSM_MDP40
 		mipi = &mfd->panel_info.mipi;
 		configure_mdp_core_clk_table((mipi->dsi_pclk_rate) * 3 / 2);
-#endif
 		if (mfd->panel_info.pdest == DISPLAY_1) {
 			if_no = PRIMARY_INTF_SEL;
 			mfd->dma = &dma2_data;
@@ -1544,6 +1552,13 @@
 		mfd->lut_update = mdp_lut_update_nonlcdc;
 		mfd->do_histogram = mdp_do_histogram;
 		mdp4_display_intf_sel(if_no, DSI_CMD_INTF);
+
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+		spin_lock_irqsave(&mdp_spin_lock, flag);
+		mdp_intr_mask |= INTR_OVERLAY0_DONE;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		spin_unlock_irqrestore(&mdp_spin_lock, flag);
+		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 #else
 		mfd->dma_fnc = mdp_dma2_update;
 		mfd->do_histogram = mdp_do_histogram;
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index db1580e..3862823 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -130,8 +130,7 @@
 #define INTR_OVERLAY2_DONE		BIT(30)
 
 #ifdef CONFIG_FB_MSM_OVERLAY
-#define MDP4_ANY_INTR_MASK	(INTR_OVERLAY0_DONE|INTR_DMA_S_DONE | \
-					INTR_DMA_P_HISTOGRAM)
+#define MDP4_ANY_INTR_MASK	(INTR_DMA_P_HISTOGRAM)
 #else
 #define MDP4_ANY_INTR_MASK	(INTR_DMA_P_DONE| \
 				INTR_DMA_P_HISTOGRAM)
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index a262cc4..3a1a9aa 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -455,7 +455,7 @@
 	if (!(data & 0x1) || (pipe == NULL))
 		return;
 	wait_for_completion_timeout(&dtv_pipe->comp,
-		msecs_to_jiffies(VSYNC_PERIOD));
+			msecs_to_jiffies(VSYNC_PERIOD*2));
 	mdp_disable_irq(MDP_OVERLAY1_TERM);
 }
 
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index d2969b6..51a72c8 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1457,6 +1457,7 @@
 			vcd_status = VCD_S_SUCCESS;
 		}
 	}
+	break;
 	case VCD_I_INTRA_REFRESH:
 	{
 		struct vcd_property_intra_refresh_mb_number
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
index 795d1e3..c32ac81 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
@@ -255,11 +255,11 @@
 		VCDRES_MSG_LOW("%s(): Enabling the clocks\n", __func__);
 		if (resource_context.vcodec_clk &&
 			resource_context.vcodec_pclk) {
-			if (clk_enable(resource_context.vcodec_pclk)) {
+			if (clk_prepare_enable(resource_context.vcodec_pclk)) {
 				VCDRES_MSG_ERROR("vidc pclk Enable fail\n");
 				goto bail_out;
 			}
-			if (clk_enable(resource_context.vcodec_clk)) {
+			if (clk_prepare_enable(resource_context.vcodec_clk)) {
 				VCDRES_MSG_ERROR("vidc core clk Enable fail\n");
 				goto vidc_disable_pclk;
 			}
@@ -275,7 +275,7 @@
 	mutex_unlock(&resource_context.lock);
 	return true;
 vidc_disable_pclk:
-	clk_disable(resource_context.vcodec_pclk);
+	clk_disable_unprepare(resource_context.vcodec_pclk);
 bail_out:
 	mutex_unlock(&resource_context.lock);
 	return false;
@@ -322,9 +322,9 @@
 		VCDRES_MSG_LOW("%s(): Disabling the clocks ...\n", __func__);
 		resource_context.clock_enabled = 0;
 		if (resource_context.vcodec_clk)
-			clk_disable(resource_context.vcodec_clk);
+			clk_disable_unprepare(resource_context.vcodec_clk);
 		if (resource_context.vcodec_pclk)
-			clk_disable(resource_context.vcodec_pclk);
+			clk_disable_unprepare(resource_context.vcodec_pclk);
 		status = true;
 	}
 	mutex_unlock(&resource_context.lock);
@@ -696,7 +696,7 @@
 			ret = PTR_ERR(vidc_mmu_clks[i].mmu_clk);
 		}
 		if (!ret) {
-			ret = clk_enable(vidc_mmu_clks[i].mmu_clk);
+			ret = clk_prepare_enable(vidc_mmu_clks[i].mmu_clk);
 			if (ret) {
 				clk_put(vidc_mmu_clks[i].mmu_clk);
 				vidc_mmu_clks[i].mmu_clk = NULL;
@@ -704,7 +704,7 @@
 		}
 		if (ret) {
 			for (i--; i >= 0; i--) {
-				clk_disable(vidc_mmu_clks[i].mmu_clk);
+				clk_disable_unprepare(vidc_mmu_clks[i].mmu_clk);
 				clk_put(vidc_mmu_clks[i].mmu_clk);
 				vidc_mmu_clks[i].mmu_clk = NULL;
 			}
@@ -725,7 +725,7 @@
 	}
 	resource_context.mmu_clks_on = 0;
 	for (i = 0; i < ARRAY_SIZE(vidc_mmu_clks); i++) {
-		clk_disable(vidc_mmu_clks[i].mmu_clk);
+		clk_disable_unprepare(vidc_mmu_clks[i].mmu_clk);
 		clk_put(vidc_mmu_clks[i].mmu_clk);
 		vidc_mmu_clks[i].mmu_clk = NULL;
 	}
diff --git a/include/linux/genlock.h b/include/linux/genlock.h
index 2e9f9d6..9351a15 100644
--- a/include/linux/genlock.h
+++ b/include/linux/genlock.h
@@ -12,7 +12,7 @@
 struct genlock *genlock_create_lock(struct genlock_handle *);
 struct genlock *genlock_attach_lock(struct genlock_handle *, int fd);
 int genlock_wait(struct genlock_handle *handle, u32 timeout);
-void genlock_release_lock(struct genlock_handle *);
+/* genlock_release_lock was deprecated */
 int genlock_lock(struct genlock_handle *handle, int op, int flags,
 	u32 timeout);
 #endif
@@ -39,6 +39,8 @@
 	struct genlock_lock)
 #define GENLOCK_IOC_LOCK _IOW(GENLOCK_IOC_MAGIC, 3, \
 	struct genlock_lock)
+
+/* Deprecated */
 #define GENLOCK_IOC_RELEASE _IO(GENLOCK_IOC_MAGIC, 4)
 #define GENLOCK_IOC_WAIT _IOW(GENLOCK_IOC_MAGIC, 5, \
 	struct genlock_lock)
diff --git a/include/linux/mfd/pm8xxx/pwm.h b/include/linux/mfd/pm8xxx/pwm.h
index be3ec65..9169e90 100644
--- a/include/linux/mfd/pm8xxx/pwm.h
+++ b/include/linux/mfd/pm8xxx/pwm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -17,8 +17,8 @@
 
 #define PM8XXX_PWM_DEV_NAME	"pm8xxx-pwm"
 
-#define PM8XXX_PWM_PERIOD_MAX		(327 * USEC_PER_SEC)
-#define PM8XXX_PWM_PERIOD_MIN		7 /* micro seconds */
+#define PM8XXX_PWM_PERIOD_MIN	7 /* usec: 19.2M, n=6, m=0, pre=2 */
+#define PM8XXX_PWM_PERIOD_MAX	(384 * USEC_PER_SEC) /* 1K, n=9, m=7, pre=6 */
 
 #define PM_PWM_LUT_SIZE			64
 #define PM_PWM_LUT_DUTY_TIME_MAX	512	/* ms */
diff --git a/include/linux/slimbus/slimbus.h b/include/linux/slimbus/slimbus.h
index d161d41..448d9ab 100644
--- a/include/linux/slimbus/slimbus.h
+++ b/include/linux/slimbus/slimbus.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -378,9 +378,9 @@
  * @seglen: Segment length of this channel.
  * @rootexp: root exponent of this channel. Rate can be found using rootexp and
  *	coefficient. Used during scheduling.
- * @srch: Source ports used by this channel.
- * @nsrc: number of source ports used by this channel.
- * @sinkh: Sink port used by this channel.
+ * @srch: Source port used by this channel.
+ * @sinkh: Sink ports used by this channel.
+ * @nsink: number of sink ports used by this channel.
  * @chan: Channel number sent on hardware lines for this channel. May not be
  *	equal to array-index into chans if client requested to use number beyond
  *	channel-array for the controller.
@@ -404,9 +404,9 @@
 	u32			newintr;
 	u32			seglen;
 	u8			rootexp;
-	u32			*srch;
-	int			nsrc;
-	u32			sinkh;
+	u32			srch;
+	u32			*sinkh;
+	int			nsink;
 	u8			chan;
 	int			ref;
 	int			def;
@@ -760,19 +760,31 @@
 			u32 ph, u8 **done_buf, u32 *done_len);
 
 /*
- * slim_connect_ports: Connect port(s) to channel.
+ * slim_connect_src: Connect source port to channel.
  * @sb: client handle
- * @srch: source handles to be connected to this channel
- * @nrsc: number of source ports
- * @sinkh: sink handle to be connected to this channel
+ * @srch: source handle to be connected to this channel
  * @chanh: Channel with which the ports need to be associated with.
- * Per slimbus specification, a channel may have multiple source-ports and 1
- * sink port.Channel specified in chanh needs to be allocated first.
+ * Per slimbus specification, a channel may have 1 source port.
+ * Channel specified in chanh needs to be allocated first.
+ * Returns -EALREADY if source is already configured for this channel.
+ * Returns -ENOTCONN if channel is not allocated
  */
-extern int slim_connect_ports(struct slim_device *sb, u32 *srch, int nsrc,
-				u32 sinkh, u16 chanh);
+extern int slim_connect_src(struct slim_device *sb, u32 srch, u16 chanh);
 
 /*
+ * slim_connect_sink: Connect sink port(s) to channel.
+ * @sb: client handle
+ * @sinkh: sink handle(s) to be connected to this channel
+ * @nsink: number of sinks
+ * @chanh: Channel with which the ports need to be associated with.
+ * Per slimbus specification, a channel may have multiple sink-ports.
+ * Channel specified in chanh needs to be allocated first.
+ * Returns -EALREADY if sink is already configured for this channel.
+ * Returns -ENOTCONN if channel is not allocated
+ */
+extern int slim_connect_sink(struct slim_device *sb, u32 *sinkh, int nsink,
+				u16 chanh);
+/*
  * slim_disconnect_ports: Disconnect port(s) from channel
  * @sb: client handle
  * @ph: ports to be disconnected
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index 4918caa..0a3b91d 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -1158,6 +1158,7 @@
 		if (skb->len < sizeof(*grsp))
 			goto cpl_finished;
 		grsp = (struct a2mp_getinfo_rsp *) skb_pull(skb, sizeof(*hdr));
+		skb_pull(skb, sizeof(*grsp));
 		if (grsp->status)
 			goto cpl_finished;
 		if (grsp->id != ctx->d.cpl.remote_id)
@@ -1171,7 +1172,6 @@
 		ctrl->min_latency = le32_to_cpu(grsp->min_latency);
 		ctrl->pal_cap = le16_to_cpu(grsp->pal_cap);
 		ctrl->max_assoc_size = le16_to_cpu(grsp->assoc_size);
-		skb_pull(skb, sizeof(*grsp));
 
 		ctx->d.cpl.max_len = ctrl->max_assoc_size;
 
@@ -1191,8 +1191,6 @@
 			goto cpl_finished;
 		hdr = (void *) skb->data;
 		arsp = (void *) skb_pull(skb, sizeof(*hdr));
-		if (arsp->id != ctx->d.cpl.remote_id)
-			goto cpl_finished;
 		if (arsp->status != 0)
 			goto cpl_finished;
 
@@ -1200,12 +1198,12 @@
 		assoc = (u8 *) skb_pull(skb, sizeof(*arsp));
 		ctx->d.cpl.len_so_far = 0;
 		ctx->d.cpl.rem_len = hdr->len - sizeof(*arsp);
+		skb_pull(skb, ctx->d.cpl.rem_len);
 		rassoc = kmalloc(ctx->d.cpl.rem_len, GFP_ATOMIC);
 		if (!rassoc)
 			goto cpl_finished;
 		memcpy(rassoc, assoc, ctx->d.cpl.rem_len);
 		ctx->d.cpl.remote_assoc = rassoc;
-		skb_pull(skb, ctx->d.cpl.rem_len);
 
 		/* set up CPL command */
 		ctx->d.cpl.phy_handle = physlink_handle(ctx->hdev);
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 92d72b7..0719874 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -523,6 +523,7 @@
 	struct sock *sk = sock->sk;
 	struct hci_dev *hdev;
 	struct sk_buff *skb;
+	int reserve = 0;
 	int err;
 
 	BT_DBG("sock %p sk %p", sock, sk);
@@ -560,10 +561,18 @@
 		goto done;
 	}
 
-	skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
+	/* Allocate extra headroom for Qualcomm PAL */
+	if (hdev->dev_type == HCI_AMP && hdev->manufacturer == 0x001d)
+		reserve = BT_SKB_RESERVE_80211;
+
+	skb = bt_skb_send_alloc(sk, len + reserve,
+					msg->msg_flags & MSG_DONTWAIT, &err);
 	if (!skb)
 		goto done;
 
+	if (reserve)
+		skb_reserve(skb, reserve);
+
 	if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
 		err = -EFAULT;
 		goto drop;
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index 96260ab..27a27ec 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -420,6 +420,7 @@
 	switch (dai->id) {
 	case PRIMARY_I2S_TX:
 	case PRIMARY_I2S_RX:
+	case SECONDARY_I2S_RX:
 		rc = msm_dai_q6_cdc_hw_params(params, dai, substream->stream);
 		break;
 	case MI2S_RX:
@@ -820,6 +821,7 @@
 	case PRIMARY_I2S_TX:
 	case PRIMARY_I2S_RX:
 	case MI2S_RX:
+	case SECONDARY_I2S_RX:
 		rc = msm_dai_q6_cdc_set_fmt(dai, fmt);
 		break;
 	default:
@@ -1086,6 +1088,7 @@
 
 	switch (pdev->id) {
 	case PRIMARY_I2S_RX:
+	case SECONDARY_I2S_RX:
 		rc = snd_soc_register_dai(&pdev->dev, &msm_dai_q6_i2s_rx_dai);
 		break;
 	case PRIMARY_I2S_TX:
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 1331ebf..94ed504 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -118,6 +118,7 @@
 	{ VOICE_RECORD_RX, 0, NULL, 0, 0},
 	{ VOICE_RECORD_TX, 0, NULL, 0, 0},
 	{ MI2S_RX, 0, NULL, 0, 0},
+	{ SECONDARY_I2S_RX, 0, NULL, 0, 0},
 };
 
 
@@ -668,6 +669,21 @@
 	msm_routing_put_audio_mixer),
 };
 
+static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = {
+	SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SEC_I2S_RX ,
+	MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SEC_I2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SEC_I2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SEC_I2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+};
+
 static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
 	SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_0_RX ,
 	MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -824,6 +840,15 @@
 	msm_routing_put_voice_mixer),
 };
 
+static const struct snd_kcontrol_new sec_i2s_rx_voice_mixer_controls[] = {
+	SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SEC_I2S_RX,
+	MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
+	SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_SEC_I2S_RX,
+	MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
+	msm_routing_put_voice_mixer),
+};
+
 static const struct snd_kcontrol_new slimbus_rx_voice_mixer_controls[] = {
 	SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_SLIMBUS_0_RX,
 	MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
@@ -1134,6 +1159,8 @@
 	/* Stream name equals to backend dai link stream name
 	 */
 	SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("SEC_I2S_RX", "Secondary I2S Playback",
+				0, 0, 0 , 0),
 	SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0 , 0),
 	SND_SOC_DAPM_AIF_OUT("MI2S_RX", "MI2S Playback", 0, 0, 0, 0),
@@ -1166,6 +1193,8 @@
 	/* Mixer definitions */
 	SND_SOC_DAPM_MIXER("PRI_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
 	pri_i2s_rx_mixer_controls, ARRAY_SIZE(pri_i2s_rx_mixer_controls)),
+	SND_SOC_DAPM_MIXER("SEC_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
+	sec_i2s_rx_mixer_controls, ARRAY_SIZE(sec_i2s_rx_mixer_controls)),
 	SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
 	slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)),
 	SND_SOC_DAPM_MIXER("HDMI Mixer", SND_SOC_NOPM, 0, 0,
@@ -1186,6 +1215,10 @@
 	SND_SOC_DAPM_MIXER("PRI_RX_Voice Mixer",
 				SND_SOC_NOPM, 0, 0, pri_rx_voice_mixer_controls,
 				ARRAY_SIZE(pri_rx_voice_mixer_controls)),
+	SND_SOC_DAPM_MIXER("SEC_RX_Voice Mixer",
+				SND_SOC_NOPM, 0, 0,
+				sec_i2s_rx_voice_mixer_controls,
+				ARRAY_SIZE(sec_i2s_rx_voice_mixer_controls)),
 	SND_SOC_DAPM_MIXER("SLIM_0_RX_Voice Mixer",
 				SND_SOC_NOPM, 0, 0,
 				slimbus_rx_voice_mixer_controls,
@@ -1230,6 +1263,12 @@
 	{"PRI_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
 	{"PRI_I2S_RX", NULL, "PRI_RX Audio Mixer"},
 
+	{"SEC_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
+	{"SEC_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
+	{"SEC_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+	{"SEC_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"SEC_I2S_RX", NULL, "SEC_RX Audio Mixer"},
+
 	{"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
@@ -1295,6 +1334,10 @@
 	{"PRI_RX_Voice Mixer", "Voip", "VOIP_DL"},
 	{"PRI_I2S_RX", NULL, "PRI_RX_Voice Mixer"},
 
+	{"SEC_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
+	{"SEC_RX_Voice Mixer", "Voip", "VOIP_DL"},
+	{"SEC_I2S_RX", NULL, "SEC_RX_Voice Mixer"},
+
 	{"SLIM_0_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
 	{"SLIM_0_RX_Voice Mixer", "Voip", "VOIP_DL"},
 	{"SLIMBUS_0_RX", NULL, "SLIM_0_RX_Voice Mixer"},
diff --git a/sound/soc/msm/msm-pcm-routing.h b/sound/soc/msm/msm-pcm-routing.h
index a8d2d91..25efb58 100644
--- a/sound/soc/msm/msm-pcm-routing.h
+++ b/sound/soc/msm/msm-pcm-routing.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -29,6 +29,7 @@
 #define LPASS_BE_VOICE_PLAYBACK_TX "(Backend) VOICE_PLAYBACK_TX"
 #define LPASS_BE_INCALL_RECORD_RX "(Backend) INCALL_RECORD_TX"
 #define LPASS_BE_INCALL_RECORD_TX "(Backend) INCALL_RECORD_RX"
+#define LPASS_BE_SEC_I2S_RX "(Backend) SECONDARY_I2S_RX"
 
 #define LPASS_BE_MI2S_RX "(Backend) MI2S_RX"
 
@@ -71,6 +72,7 @@
 	MSM_BACKEND_DAI_INCALL_RECORD_RX,
 	MSM_BACKEND_DAI_INCALL_RECORD_TX,
 	MSM_BACKEND_DAI_MI2S_RX,
+	MSM_BACKEND_DAI_SEC_I2S_RX,
 	MSM_BACKEND_DAI_MAX,
 };
 
diff --git a/sound/soc/msm/qdsp6/q6voice.c b/sound/soc/msm/qdsp6/q6voice.c
index 2acf59e..532d92b 100644
--- a/sound/soc/msm/qdsp6/q6voice.c
+++ b/sound/soc/msm/qdsp6/q6voice.c
@@ -17,6 +17,7 @@
 #include <linux/wait.h>
 #include <linux/mutex.h>
 
+#include <asm/mach-types.h>
 #include <mach/qdsp6v2/audio_acdb.h>
 #include <mach/qdsp6v2/rtac.h>
 
@@ -2070,8 +2071,14 @@
 	mvm_set_voice_timing.hdr.opcode = VSS_ICOMMON_CMD_SET_VOICE_TIMING;
 	mvm_set_voice_timing.timing.mode = 0;
 	mvm_set_voice_timing.timing.enc_offset = 8000;
-	mvm_set_voice_timing.timing.dec_req_offset = 3300;
-	mvm_set_voice_timing.timing.dec_offset = 8300;
+	if (machine_is_apq8064_sim()) {
+		pr_debug("%s: Machine is apq8064 sim\n", __func__);
+		mvm_set_voice_timing.timing.dec_req_offset = 0;
+		mvm_set_voice_timing.timing.dec_offset = 18000;
+	} else {
+		mvm_set_voice_timing.timing.dec_req_offset = 3300;
+		mvm_set_voice_timing.timing.dec_offset = 8300;
+	}
 
 	v->mvm_state = CMD_STATUS_FAIL;