Merge "radio: iris: Add support for FM Subsystem Restart" into msm-3.0
diff --git a/Documentation/devicetree/bindings/mmc/msm_sdcc.txt b/Documentation/devicetree/bindings/mmc/msm_sdcc.txt
index 4fb653e..084050e 100644
--- a/Documentation/devicetree/bindings/mmc/msm_sdcc.txt
+++ b/Documentation/devicetree/bindings/mmc/msm_sdcc.txt
@@ -24,13 +24,13 @@
 
 Example:
 
-	qcom,sdcc@F9600000 {
+	qcom,sdcc@f9600000 {
 	/* SDC1 used as eMMC slot */
 	cell-index = <1>;
 	compatible = "qcom,msm-sdcc";
-	reg = <0xF9600000 0x800   // SDCC register interface
-		0xF9600800 0x1800  // DML register interface
-		0xF9602000 0x2000> // BAM register interface
+	reg = <0xf9600000 0x800   // SDCC register interface
+		0xf9600800 0x1800  // DML register interface
+		0xf9602000 0x2000> // BAM register interface
 
 	interrupts = <123>;
 	qcom,sdcc-clk-rates = <400000 24000000 48000000>;
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index c1399ae..95ddf34 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -35,16 +35,16 @@
 - qcom,hsusb-otg-pmic-id-irq: ID, routed to PMIC IRQ number
 
 Example HSUSB OTG controller device node :
-	usb@F9690000 {
+	usb@f9690000 {
 		compatible = "qcom,hsusb-otg";
-		reg = <0xF9690000 0x400>;
+		reg = <0xf9690000 0x400>;
 		interrupts = <134>;
 
 		qcom,hsusb-otg-phy-type = <2>;
 		qcom,hsusb-otg-mode = <1>;
 		qcom,hsusb-otg-otg-control = <1>;
 		qcom,hsusb-otg-default-mode = <2>;
-		qcom,hsusb-otg-phy-init-seq = <0x01 0x90 0xFFFFFFFF>;
+		qcom,hsusb-otg-phy-init-seq = <0x01 0x90 0xffffffff>;
 		qcom,hsusb-otg-power-budget = <500>;
 		qcom,hsusb-otg-pclk-src-name = "dfab_usb_clk";
 		qcom,hsusb-otg-pmic-id-irq = <47>
diff --git a/arch/arm/boot/dts/msmcopper.dts b/arch/arm/boot/dts/msmcopper.dts
index 57ad77a..08c16fa 100644
--- a/arch/arm/boot/dts/msmcopper.dts
+++ b/arch/arm/boot/dts/msmcopper.dts
@@ -27,15 +27,15 @@
 		interrupts = <1 2 0>;
 	};
 
-	serial@F991F000 {
+	serial@f991f000 {
 		compatible = "qcom,msm-lsuart-v14";
-		reg = <0xF991F000 0x1000>;
+		reg = <0xf991f000 0x1000>;
 		interrupts = <0 109 0>;
 	};
 
-	usb@F9A55000 {
+	usb@f9a55000 {
 		compatible = "qcom,hsusb-otg";
-		reg = <0xF9A55000 0x400>;
+		reg = <0xf9a55000 0x400>;
 		interrupts = <0 134 0>;
 
 		qcom,hsusb-otg-phy-type = <2>;
@@ -43,10 +43,10 @@
 		qcom,hsusb-otg-otg-control = <1>;
 	};
 
-	qcom,sdcc@F980B000 {
+	qcom,sdcc@f980b000 {
 		cell-index = <1>;
 		compatible = "qcom,msm-sdcc";
-		reg = <0xF980B000 0x1000>;
+		reg = <0xf980b000 0x1000>;
 		interrupts = <0 123 0>;
 
 		qcom,sdcc-clk-rates = <400000 24000000 48000000>;
@@ -56,10 +56,10 @@
 		qcom,sdcc-disable_cmd23;
 	};
 
-	qcom,sdcc@F984B000 {
+	qcom,sdcc@f984b000 {
 		cell-index = <3>;
 		compatible = "qcom,msm-sdcc";
-		reg = <0xF984B000 0x1000>;
+		reg = <0xf984b000 0x1000>;
 		interrupts = <0 127 0>;
 
 		qcom,sdcc-clk-rates = <400000 24000000 48000000>;
@@ -68,10 +68,10 @@
 		qcom,sdcc-disable_cmd23;
 	};
 
-	qcom,sps@F9980000 {
+	qcom,sps@f9980000 {
 		compatible = "qcom,msm_sps";
-		reg = <0xF9984000 0x15000>,
-		      <0xF9999000 0xB000>;
+		reg = <0xf9984000 0x15000>,
+		      <0xf9999000 0xb000>;
 		interrupts = <0 94 0>;
 
 		qcom,bam-dma-res-pipes = <6>;
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 22cf652..95dd09c 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -329,7 +329,7 @@
 CONFIG_FB_MSM_OVERLAY=y
 CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
 CONFIG_FB_MSM_OVERLAY1_WRITEBACK=y
-CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
+CONFIG_FB_MSM_LVDS_MIPI_PANEL_DETECT=y
 CONFIG_FB_MSM_HDMI_MSM_PANEL=y
 CONFIG_FB_MSM_WRITEBACK_MSM_PANEL=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index c38c161..3a70b22 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -331,7 +331,7 @@
 CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
 CONFIG_FB_MSM_OVERLAY1_WRITEBACK=y
 CONFIG_FB_MSM_WRITEBACK_MSM_PANEL=y
-CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
+CONFIG_FB_MSM_LVDS_MIPI_PANEL_DETECT=y
 CONFIG_FB_MSM_HDMI_MSM_PANEL=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/arch/arm/kernel/perf_event_msm.c b/arch/arm/kernel/perf_event_msm.c
index 4a8e276..0ca5164 100644
--- a/arch/arm/kernel/perf_event_msm.c
+++ b/arch/arm/kernel/perf_event_msm.c
@@ -21,6 +21,8 @@
 #define SCORPION_EVT_PREFIX 1
 #define SCORPION_MAX_L1_REG 4
 
+#define SCORPION_EVTYPE_EVENT 0xfffff
+
 static u32 scorpion_evt_type_base[] = {0x4c, 0x50, 0x54, 0x58, 0x5c};
 
 enum scorpion_perf_common {
@@ -380,12 +382,14 @@
 		evtinfo->group_setval = 0x80000000 | (code << (group * 8));
 		evtinfo->groupcode = reg;
 		evtinfo->armv7_evt_type = scorpion_evt_type_base[reg] | group;
+
 		return evtinfo->armv7_evt_type;
 	}
 
 	if (scorpion_evt_type < SCORPION_EVT_START_IDX || scorpion_evt_type >=
 		(ARRAY_SIZE(scorpion_event) + SCORPION_EVT_START_IDX))
 		return -EINVAL;
+
 	idx = scorpion_evt_type - SCORPION_EVT_START_IDX;
 	if (scorpion_event[idx].scorpion_evt_type == scorpion_evt_type) {
 		evtinfo->group_setval = scorpion_event[idx].group_setval;
@@ -594,7 +598,7 @@
 	 */
 	if (idx != ARMV7_CYCLE_COUNTER) {
 		val = hwc->config_base;
-		val &= ARMV7_EVTYPE_EVENT;
+		val &= SCORPION_EVTYPE_EVENT;
 
 		if (val > 0x40) {
 			event = get_scorpion_evtinfo(val, &evtinfo);
@@ -636,7 +640,7 @@
 	 */
 	if (idx != ARMV7_CYCLE_COUNTER) {
 		val = hwc->config_base;
-		val &= ARMV7_EVTYPE_EVENT;
+		val &= SCORPION_EVTYPE_EVENT;
 
 		if (val < 0x40) {
 			armv7_pmnc_write_evtsel(idx, hwc->config_base);
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index f087fbc..0b0f733 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -451,7 +451,15 @@
         default y
         bool "MSM7627A QRD1"
         help
-          Support for the Qualcomm MSM7627A Refrence Design.
+          Support for the Qualcomm MSM7627A Reference Design.
+
+config MACH_MSM7627A_QRD3
+        depends on ARCH_MSM7X27A
+        depends on !MSM_STACKED_MEMORY
+        default y
+        bool "MSM7627A QRD3"
+        help
+          Support for the Qualcomm MSM7627A Reference Design.
 
 config MACH_MSM7627A_EVB
         depends on ARCH_MSM7X27A
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 2394c47..6bca244 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -38,7 +38,12 @@
 	obj-$(CONFIG_MSM_SOC_REV_NONE) += acpuclock-8x50.o
 endif
 
-obj-$(CONFIG_SMP) += headsmp.o platsmp.o
+obj-$(CONFIG_SMP) += headsmp.o
+ifdef CONFIG_ARCH_MSM8625
+	obj-$(CONFIG_SMP) += platsmp-8625.o
+else
+	obj-$(CONFIG_SMP) += platsmp.o
+endif
 obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
 
 obj-$(CONFIG_MSM_CPU_AVS) += avs.o
@@ -218,6 +223,7 @@
 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_QRD3) += 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
diff --git a/arch/arm/mach-msm/acpuclock-7201.c b/arch/arm/mach-msm/acpuclock-7201.c
index 6140559..7ad3f65 100644
--- a/arch/arm/mach-msm/acpuclock-7201.c
+++ b/arch/arm/mach-msm/acpuclock-7201.c
@@ -757,7 +757,7 @@
 	res = clk_set_rate(drv_state.ebi1_clk, speed->axiclk_khz * 1000);
 	if (res < 0)
 		pr_warning("Setting AXI min rate failed (%d)\n", res);
-	res = clk_enable(drv_state.ebi1_clk);
+	res = clk_prepare_enable(drv_state.ebi1_clk);
 	if (res < 0)
 		pr_warning("Enabling AXI clock failed (%d)\n", res);
 
diff --git a/arch/arm/mach-msm/acpuclock-9615.c b/arch/arm/mach-msm/acpuclock-9615.c
index 35eb52b..8882f41 100644
--- a/arch/arm/mach-msm/acpuclock-9615.c
+++ b/arch/arm/mach-msm/acpuclock-9615.c
@@ -323,6 +323,11 @@
 		if (clocks[i].name) {
 			clocks[i].clk = clk_get_sys("acpu", clocks[i].name);
 			BUG_ON(IS_ERR(clocks[i].clk));
+			/*
+			 * Prepare the PLLs because we enable/disable them
+			 * in atomic context during power collapse/restore.
+			 */
+			BUG_ON(clk_prepare(clocks[i].clk));
 		}
 	}
 
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index 5ead88c..604769d 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -15,13 +15,14 @@
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 #include <linux/bootmem.h>
+#include <linux/ion.h>
 #include <asm/mach-types.h>
 #include <mach/msm_memtypes.h>
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/gpiomux.h>
-#include <linux/ion.h>
 #include <mach/ion.h>
+#include <mach/msm_bus_board.h>
 
 #include "devices.h"
 #include "board-8064.h"
@@ -134,6 +135,90 @@
 
 #define MDP_VSYNC_GPIO 0
 
+#ifdef CONFIG_MSM_BUS_SCALING
+static struct msm_bus_vectors mdp_init_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = 0,
+	},
+};
+
+static struct msm_bus_vectors mdp_ui_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 216000000 * 2,
+		.ib = 270000000 * 2,
+	},
+};
+
+static struct msm_bus_vectors mdp_vga_vectors[] = {
+	/* VGA and less video */
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 216000000 * 2,
+		.ib = 270000000 * 2,
+	},
+};
+
+static struct msm_bus_vectors mdp_720p_vectors[] = {
+	/* 720p and less video */
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 230400000 * 2,
+		.ib = 288000000 * 2,
+	},
+};
+
+static struct msm_bus_vectors mdp_1080p_vectors[] = {
+	/* 1080p and less video */
+	{
+		.src = MSM_BUS_MASTER_MDP_PORT0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 334080000 * 2,
+		.ib = 417600000 * 2,
+	},
+};
+
+static struct msm_bus_paths mdp_bus_scale_usecases[] = {
+	{
+		ARRAY_SIZE(mdp_init_vectors),
+		mdp_init_vectors,
+	},
+	{
+		ARRAY_SIZE(mdp_ui_vectors),
+		mdp_ui_vectors,
+	},
+	{
+		ARRAY_SIZE(mdp_ui_vectors),
+		mdp_ui_vectors,
+	},
+	{
+		ARRAY_SIZE(mdp_vga_vectors),
+		mdp_vga_vectors,
+	},
+	{
+		ARRAY_SIZE(mdp_720p_vectors),
+		mdp_720p_vectors,
+	},
+	{
+		ARRAY_SIZE(mdp_1080p_vectors),
+		mdp_1080p_vectors,
+	},
+};
+
+static struct msm_bus_scale_pdata mdp_bus_scale_pdata = {
+	mdp_bus_scale_usecases,
+	ARRAY_SIZE(mdp_bus_scale_usecases),
+	.name = "mdp",
+};
+
+#endif
+
 static int mdp_core_clk_rate_table[] = {
 	200000000,
 	200000000,
@@ -146,6 +231,9 @@
 	.mdp_core_clk_rate = 200000000,
 	.mdp_core_clk_table = mdp_core_clk_rate_table,
 	.num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
+#ifdef CONFIG_MSM_BUS_SCALING
+	.mdp_bus_scale_table = &mdp_bus_scale_pdata,
+#endif
 	.mdp_rev = MDP_REV_44,
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 	.mem_hid = ION_CP_MM_HEAP_ID,
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index 62b7f17..c3cc9eb 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -85,6 +85,20 @@
 	},
 };
 
+
+static struct gpiomux_setting wcnss_5wire_suspend_cfg = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv  = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting wcnss_5wire_active_cfg = {
+	.func = GPIOMUX_FUNC_1,
+	.drv  = GPIOMUX_DRV_6MA,
+	.pull = GPIOMUX_PULL_DOWN,
+};
+
+
 static struct gpiomux_setting slimbus = {
 	.func = GPIOMUX_FUNC_1,
 	.drv = GPIOMUX_DRV_8MA,
@@ -479,6 +493,44 @@
 	},
 };
 
+static struct msm_gpiomux_config wcnss_5wire_interface[] = {
+	{
+		.gpio = 64,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
+			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 65,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
+			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 66,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
+			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 67,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
+			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+		},
+	},
+	{
+		.gpio = 68,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &wcnss_5wire_active_cfg,
+			[GPIOMUX_SUSPENDED] = &wcnss_5wire_suspend_cfg,
+		},
+	},
+};
+
 void __init apq8064_init_gpiomux(void)
 {
 	int rc;
@@ -494,6 +546,9 @@
 			ARRAY_SIZE(apq8064_ethernet_configs));
 #endif
 
+	msm_gpiomux_install(wcnss_5wire_interface,
+			ARRAY_SIZE(wcnss_5wire_interface));
+
 	msm_gpiomux_install(apq8064_gsbi_configs,
 			ARRAY_SIZE(apq8064_gsbi_configs));
 
diff --git a/arch/arm/mach-msm/board-8064-storage.c b/arch/arm/mach-msm/board-8064-storage.c
index 8a3b958..0b336dd 100644
--- a/arch/arm/mach-msm/board-8064-storage.c
+++ b/arch/arm/mach-msm/board-8064-storage.c
@@ -220,7 +220,7 @@
 
 #ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
 static unsigned int sdc3_sup_clk_rates[] = {
-	400000, 24000000, 48000000, 96000000
+	400000, 24000000, 48000000, 96000000, 192000000
 };
 
 static struct mmc_platform_data sdc3_data = {
@@ -230,6 +230,14 @@
 	.sup_clk_cnt	= ARRAY_SIZE(sdc3_sup_clk_rates),
 	.pin_data	= &mmc_slot_pin_data[SDCC3],
 	.vreg_data	= &mmc_slot_vreg_data[SDCC3],
+	.status_gpio	= 26,
+	.status_irq	= MSM_GPIO_TO_INT(26),
+	.irq_flags	= IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+	.is_status_gpio_active_low = 1,
+	.xpc_cap	= 1,
+	.uhs_caps	= (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+			MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 |
+			MMC_CAP_UHS_SDR104 | MMC_CAP_MAX_CURRENT_800),
 };
 static struct mmc_platform_data *apq8064_sdc3_pdata = &sdc3_data;
 #else
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index af2e18c..468c87a 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -30,6 +30,7 @@
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
 #include <asm/mach/mmc.h>
+#include <linux/platform_data/qcom_wcnss_device.h>
 
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
@@ -728,6 +729,48 @@
 	},
 };
 
+#define MSM_WCNSS_PHYS	0x03000000
+#define MSM_WCNSS_SIZE	0x280000
+
+static struct resource resources_wcnss_wlan[] = {
+	{
+		.start	= RIVA_APPS_WLAN_RX_DATA_AVAIL_IRQ,
+		.end	= RIVA_APPS_WLAN_RX_DATA_AVAIL_IRQ,
+		.name	= "wcnss_wlanrx_irq",
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= RIVA_APPS_WLAN_DATA_XFER_DONE_IRQ,
+		.end	= RIVA_APPS_WLAN_DATA_XFER_DONE_IRQ,
+		.name	= "wcnss_wlantx_irq",
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= MSM_WCNSS_PHYS,
+		.end	= MSM_WCNSS_PHYS + MSM_WCNSS_SIZE - 1,
+		.name	= "wcnss_mmio",
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= 64,
+		.end	= 68,
+		.name	= "wcnss_gpios_5wire",
+		.flags	= IORESOURCE_IO,
+	},
+};
+
+static struct qcom_wcnss_opts qcom_wcnss_pdata = {
+	.has_48mhz_xo	= 1,
+};
+
+static struct platform_device msm_device_wcnss_wlan = {
+	.name		= "wcnss_wlan",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(resources_wcnss_wlan),
+	.resource	= resources_wcnss_wlan,
+	.dev		= {.platform_data = &qcom_wcnss_pdata},
+};
+
 #if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
 		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) || \
 		defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
@@ -1182,7 +1225,6 @@
 static struct msm_spm_platform_data msm_spm_l2_data[] __initdata = {
 	[0] = {
 		.reg_base_addr = MSM_SAW_L2_BASE,
-		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
 		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x00A000AE,
@@ -1195,9 +1237,7 @@
 static struct msm_spm_platform_data msm_spm_data[] __initdata = {
 	[0] = {
 		.reg_base_addr = MSM_SAW0_BASE,
-		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
-		.reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
 #if defined(CONFIG_MSM_AVS_HW)
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1212,9 +1252,7 @@
 	},
 	[1] = {
 		.reg_base_addr = MSM_SAW1_BASE,
-		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
-		.reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
 #if defined(CONFIG_MSM_AVS_HW)
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1229,9 +1267,7 @@
 	},
 	[2] = {
 		.reg_base_addr = MSM_SAW2_BASE,
-		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
-		.reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
 #if defined(CONFIG_MSM_AVS_HW)
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1246,9 +1282,7 @@
 	},
 	[3] = {
 		.reg_base_addr = MSM_SAW3_BASE,
-		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
-		.reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
 #if defined(CONFIG_MSM_AVS_HW)
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1340,6 +1374,7 @@
 	&apq8064_device_hsusb_host,
 	&apq8064_device_hsic_host,
 	&android_usb_device,
+	&msm_device_wcnss_wlan,
 #ifdef CONFIG_ANDROID_PMEM
 #ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	&android_pmem_device,
@@ -1398,7 +1433,7 @@
 	&msm_bus_8064_mm_fabric,
 	&msm_bus_8064_sys_fpb,
 	&msm_bus_8064_cpss_fpb,
-	&msm_device_vidc,
+	&apq8064_msm_device_vidc,
 	&msm_8960_riva,
 	&msm_8960_q6_lpass,
 	&msm_gss,
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index 2f59d9d..3f9f976 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -225,6 +225,45 @@
 	.thermal_levels		= ARRAY_SIZE(pm8921_therm_mitigation),
 };
 
+#define PM8038_WLED_MAX_CURRENT		25
+
+static struct led_info pm8038_led_info[] = {
+	[0] = {
+		.name			= "wled",
+	},
+};
+
+static struct led_platform_data pm8038_led_core_pdata = {
+	.num_leds = ARRAY_SIZE(pm8038_led_info),
+	.leds = pm8038_led_info,
+};
+
+static struct wled_config_data wled_cfg = {
+	.dig_mod_gen_en = true,
+	.cs_out_en = true,
+	.ctrl_delay_us = 0,
+	.op_fdbck = true,
+	.ovp_val = WLED_OVP_32V,
+	.boost_curr_lim = WLED_CURR_LIMIT_525mA,
+	.num_strings = 1,
+};
+
+static struct pm8xxx_led_config pm8038_led_configs[] = {
+	[0] = {
+		.id = PM8XXX_ID_WLED,
+		.mode = PM8XXX_LED_MODE_MANUAL,
+		.max_current = PM8038_WLED_MAX_CURRENT,
+		.default_state = 1,
+		.wled_cfg = &wled_cfg,
+	},
+};
+
+static struct pm8xxx_led_platform_data pm8xxx_leds_pdata = {
+	.led_core = &pm8038_led_core_pdata,
+	.configs = pm8038_led_configs,
+	.num_configs = ARRAY_SIZE(pm8038_led_configs),
+};
+
 static struct pm8xxx_ccadc_platform_data pm8xxx_ccadc_pdata = {
 	.r_sense		= 10,
 };
@@ -252,6 +291,7 @@
 	.charger_pdata		= &pm8921_chg_pdata,
 	.bms_pdata		= &pm8921_bms_pdata,
 	.adc_pdata		= &pm8xxx_adc_pdata,
+	.leds_pdata		= &pm8xxx_leds_pdata,
 	.ccadc_pdata		= &pm8xxx_ccadc_pdata,
 };
 
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 90cc3c5..033d92e 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1047,9 +1047,7 @@
 static struct msm_spm_platform_data msm_spm_data[] __initdata = {
 	[0] = {
 		.reg_base_addr = MSM_SAW0_BASE,
-		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
-		.reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
 #if defined(CONFIG_MSM_AVS_HW)
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1064,9 +1062,7 @@
 	},
 	[1] = {
 		.reg_base_addr = MSM_SAW1_BASE,
-		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
-		.reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
 #if defined(CONFIG_MSM_AVS_HW)
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1120,7 +1116,6 @@
 static struct msm_spm_platform_data msm_spm_l2_data[] __initdata = {
 	[0] = {
 		.reg_base_addr = MSM_SAW_L2_BASE,
-		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
 		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x00A000AE,
diff --git a/arch/arm/mach-msm/board-8960-display.c b/arch/arm/mach-msm/board-8960-display.c
index aa8477e..1f6d04f 100644
--- a/arch/arm/mach-msm/board-8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -68,6 +68,7 @@
 #define MIPI_CMD_NOVATEK_QHD_PANEL_NAME	"mipi_cmd_novatek_qhd"
 #define MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME	"mipi_video_novatek_qhd"
 #define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME	"mipi_video_toshiba_wsvga"
+#define MIPI_VIDEO_ASUS_WUXGA_PANEL_NAME	"mipi_video_asus_wuxga"
 #define MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME	"mipi_video_chimei_wxga"
 #define MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME	"mipi_video_chimei_wuxga"
 #define MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME	"mipi_video_simulator_vga"
@@ -81,7 +82,7 @@
 	}
 };
 
-static void set_mdp_clocks_for_liquid_wuxga(void);
+static void set_mdp_clocks_for_wuxga(void);
 
 static int msm_fb_detect_panel(const char *name)
 {
@@ -91,7 +92,7 @@
 			if (!strncmp(name, MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME,
 				     strnlen(MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME,
 						PANEL_NAME_MAX_LEN))) {
-				set_mdp_clocks_for_liquid_wuxga();
+				set_mdp_clocks_for_wuxga();
 				return 0;
 			}
 		} else {
@@ -126,6 +127,13 @@
 				strnlen(MIPI_CMD_RENESAS_FWVGA_PANEL_NAME,
 					PANEL_NAME_MAX_LEN)))
 			return 0;
+
+		if (!strncmp(name, MIPI_VIDEO_ASUS_WUXGA_PANEL_NAME,
+				strnlen(MIPI_VIDEO_ASUS_WUXGA_PANEL_NAME,
+					PANEL_NAME_MAX_LEN))) {
+			set_mdp_clocks_for_wuxga();
+			return 0;
+		}
 #endif
 	}
 
@@ -649,9 +657,9 @@
 
 /**
  * Set MDP clocks to high frequency to avoid DSI underflow
- * when using high resolution 1200x1920 WUXGA panel.
+ * when using high resolution 1200x1920 WUXGA panels
  */
-static void set_mdp_clocks_for_liquid_wuxga(void)
+static void set_mdp_clocks_for_wuxga(void)
 {
 	int i;
 
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 76a27ff..931d7da 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1186,9 +1186,7 @@
 static struct msm_spm_platform_data msm_spm_data[] __initdata = {
 	[0] = {
 		.reg_base_addr = MSM_SAW0_BASE,
-		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
-		.reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0xB0,
 #if defined(CONFIG_MSM_AVS_HW)
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1203,9 +1201,7 @@
 	},
 	[1] = {
 		.reg_base_addr = MSM_SAW1_BASE,
-		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
-		.reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0xB0,
 #if defined(CONFIG_MSM_AVS_HW)
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1259,7 +1255,6 @@
 static struct msm_spm_platform_data msm_spm_l2_data[] __initdata = {
 	[0] = {
 		.reg_base_addr = MSM_SAW_L2_BASE,
-		.reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x00,
 		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
 		.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x00A000AE,
diff --git a/arch/arm/mach-msm/board-msm7627a-bt.c b/arch/arm/mach-msm/board-msm7627a-bt.c
index 5acfcd5..c70b30e 100644
--- a/arch/arm/mach-msm/board-msm7627a-bt.c
+++ b/arch/arm/mach-msm/board-msm7627a-bt.c
@@ -935,6 +935,9 @@
 	int i, rc = 0;
 	struct device *dev;
 
+	if (machine_is_msm7627a_qrd3())
+		return;
+
 	gpio_bt_config();
 
 	i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
diff --git a/arch/arm/mach-msm/board-msm7627a-camera.c b/arch/arm/mach-msm/board-msm7627a-camera.c
index e3f668f..c0b1d16 100644
--- a/arch/arm/mach-msm/board-msm7627a-camera.c
+++ b/arch/arm/mach-msm/board-msm7627a-camera.c
@@ -796,6 +796,8 @@
 				ARRAY_SIZE(camera_devices_qrd));
 	} else if (machine_is_msm7627a_evb())
 		return;
+	else if (machine_is_msm7627a_qrd3())
+		return;
 	else
 		platform_add_devices(camera_devices_msm,
 				ARRAY_SIZE(camera_devices_msm));
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index 15f681d..011a4d4 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -843,6 +843,8 @@
 	else if (machine_is_msm7627a_evb())
 		platform_add_devices(evb_fb_devices,
 				ARRAY_SIZE(evb_fb_devices));
+	else if (machine_is_msm7627a_qrd3())
+		return;
 	else
 		platform_add_devices(msm_fb_devices,
 				ARRAY_SIZE(msm_fb_devices));
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
index 8eb92a4..d5d8edc 100644
--- a/arch/arm/mach-msm/board-msm7x27.c
+++ b/arch/arm/mach-msm/board-msm7x27.c
@@ -1588,15 +1588,17 @@
 
 
 static struct msm_pm_platform_data msm7x25_pm_data[MSM_PM_SLEEP_MODE_NR] = {
-	[MSM_PM_SLEEP_MODE_POWER_COLLAPSE].latency = 16000,
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)].latency = 16000,
 
-	[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN].latency = 12000,
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN)]
+		.latency = 12000,
 
-	[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].latency = 2000,
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT)]
+		.latency = 2000,
 };
 
 static struct msm_pm_platform_data msm7x27_pm_data[MSM_PM_SLEEP_MODE_NR] = {
-	[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = {
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = {
 		.idle_supported = 1,
 		.suspend_supported = 1,
 		.idle_enabled = 1,
@@ -1605,7 +1607,7 @@
 		.residency = 20000,
 	},
 
-	[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = {
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN)] = {
 		.idle_supported = 1,
 		.suspend_supported = 1,
 		.idle_enabled = 1,
@@ -1614,7 +1616,7 @@
 		.residency = 20000,
 	},
 
-	[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] = {
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT)] = {
 		.idle_supported = 1,
 		.suspend_supported = 1,
 		.idle_enabled = 1,
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 0680c44..51da14b 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -326,7 +326,7 @@
 };
 #endif
 static struct msm_pm_platform_data msm7x27a_pm_data[MSM_PM_SLEEP_MODE_NR] = {
-	[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = {
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = {
 					.idle_supported = 1,
 					.suspend_supported = 1,
 					.idle_enabled = 1,
@@ -334,7 +334,7 @@
 					.latency = 16000,
 					.residency = 20000,
 	},
-	[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = {
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN)] = {
 					.idle_supported = 1,
 					.suspend_supported = 1,
 					.idle_enabled = 1,
@@ -342,7 +342,7 @@
 					.latency = 12000,
 					.residency = 20000,
 	},
-	[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] = {
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT)] = {
 					.idle_supported = 1,
 					.suspend_supported = 1,
 					.idle_enabled = 0,
@@ -350,7 +350,7 @@
 					.latency = 2000,
 					.residency = 0,
 	},
-	[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT] = {
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
 					.idle_supported = 1,
 					.suspend_supported = 1,
 					.idle_enabled = 1,
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index e0b3c49..47a4605 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -2907,7 +2907,7 @@
 };
 
 static struct msm_pm_platform_data msm_pm_data[MSM_PM_SLEEP_MODE_NR] = {
-	[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = {
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = {
 		.idle_supported = 1,
 		.suspend_supported = 1,
 		.idle_enabled = 1,
@@ -2915,7 +2915,7 @@
 		.latency = 8594,
 		.residency = 23740,
 	},
-	[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = {
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN)] = {
 		.idle_supported = 1,
 		.suspend_supported = 1,
 		.idle_enabled = 1,
@@ -2923,7 +2923,7 @@
 		.latency = 4594,
 		.residency = 23740,
 	},
-	[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE] = {
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
 #ifdef CONFIG_MSM_STANDALONE_POWER_COLLAPSE
 		.idle_supported = 1,
 		.suspend_supported = 1,
@@ -2938,7 +2938,7 @@
 		.latency = 500,
 		.residency = 6000,
 	},
-	[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] = {
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT)] = {
 		.idle_supported = 1,
 		.suspend_supported = 1,
 		.idle_enabled = 0,
@@ -2946,7 +2946,7 @@
 		.latency = 443,
 		.residency = 1098,
 	},
-	[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT] = {
+	[MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
 		.idle_supported = 1,
 		.suspend_supported = 1,
 		.idle_enabled = 1,
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 1222b67..0427632 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -684,6 +684,10 @@
 	&asoc_msm_dai1,
 };
 
+static struct platform_device *qrd3_devices[] __initdata = {
+	&msm_device_nand,
+};
+
 static unsigned pmem_kernel_ebi1_size = PMEM_KERNEL_EBI1_SIZE;
 static int __init pmem_kernel_ebi1_size_setup(char *p)
 {
@@ -1016,6 +1020,16 @@
 	return platform_device_register(&msm_wlan_ar6000_pm_device);
 }
 
+static void add_platform_devices(void)
+{
+	platform_add_devices(qrd_common_devices,
+			ARRAY_SIZE(qrd_common_devices));
+
+	if (machine_is_msm7627a_qrd3())
+		platform_add_devices(qrd3_devices,
+				ARRAY_SIZE(qrd3_devices));
+}
+
 #define UART1DM_RX_GPIO		45
 static void __init msm_qrd_init(void)
 {
@@ -1035,8 +1049,7 @@
 	msm_device_gadget_peripheral.dev.platform_data =
 		&msm_gadget_pdata;
 
-	platform_add_devices(qrd_common_devices,
-			ARRAY_SIZE(qrd_common_devices));
+	add_platform_devices();
 
 	/* Ensure ar6000pm device is registered before MMC/SDC */
 	msm_qrd_init_ar6000pm();
@@ -1075,6 +1088,16 @@
 	.init_early	= qrd7627a_init_early,
 	.handle_irq	= vic_handle_irq,
 MACHINE_END
+MACHINE_START(MSM7627A_QRD3, "QRD MSM7627a QRD3")
+	.boot_params	= PHYS_OFFSET + 0x100,
+	.map_io		= msm_common_io_init,
+	.reserve	= msm7627a_reserve,
+	.init_irq	= msm_init_irq,
+	.init_machine	= msm_qrd_init,
+	.timer		= &msm_timer,
+	.init_early	= qrd7627a_init_early,
+	.handle_irq	= vic_handle_irq,
+MACHINE_END
 MACHINE_START(MSM7627A_EVB, "QRD MSM7627a EVB")
 	.boot_params	= PHYS_OFFSET + 0x100,
 	.map_io		= msm_common_io_init,
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 2bd0dcd..b0e616c 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5045,7 +5045,7 @@
 	CLK_LOOKUP("i2s_spkr_osr_clk",	spare_i2s_spkr_osr_clk.c, ""),
 	CLK_LOOKUP("pcm_clk",		pcm_clk.c,		""),
 	CLK_LOOKUP("sps_slimbus_clk",	sps_slimbus_clk.c,	""),
-	CLK_LOOKUP("audio_slimbus_clk",	audio_slimbus_clk.c,	NULL),
+	CLK_LOOKUP("core_clk",		audio_slimbus_clk.c, "msm_slim_ctrl.1"),
 	CLK_LOOKUP("core_clk",		jpegd_axi_clk.c,	""),
 	CLK_LOOKUP("core_clk",		vpe_axi_clk.c,		""),
 	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,		""),
@@ -5327,7 +5327,7 @@
 	CLK_LOOKUP("i2s_spkr_osr_clk",	spare_i2s_spkr_osr_clk.c,	NULL),
 	CLK_LOOKUP("pcm_clk",		pcm_clk.c,		NULL),
 	CLK_LOOKUP("sps_slimbus_clk",	sps_slimbus_clk.c,	NULL),
-	CLK_LOOKUP("audio_slimbus_clk",	audio_slimbus_clk.c,	NULL),
+	CLK_LOOKUP("core_clk",		audio_slimbus_clk.c, "msm_slim_ctrl.1"),
 	CLK_LOOKUP("core_clk",		jpegd_axi_clk.c,	"msm_iommu.0"),
 	CLK_LOOKUP("core_clk",		vpe_axi_clk.c,		"msm_iommu.1"),
 	CLK_LOOKUP("core_clk",		mdp_axi_clk.c,		"msm_iommu.2"),
@@ -5599,6 +5599,10 @@
 /* Local clock driver initialization. */
 static void __init msm8960_clock_init(void)
 {
+	/* Copy gfx2d's frequency table because it's modified by both clocks */
+	gfx2d1_clk.freq_tbl = kmemdup(clk_tbl_gfx2d,
+			sizeof(struct clk_freq_tbl) * ARRAY_SIZE(clk_tbl_gfx2d),
+			GFP_KERNEL);
 
 	if (cpu_is_msm8960()) {
 		rpm_vreg_id_vdd_dig = RPM_VREG_ID_PM8921_S3;
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 043cdbc..e53d441 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -3900,6 +3900,11 @@
 	}
 
 	vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
+	/* Copy gfx2d's frequency table because it's modified by both clocks */
+	gfx2d1_clk.freq_tbl = kmemdup(clk_tbl_gfx2d,
+			sizeof(struct clk_freq_tbl) * ARRAY_SIZE(clk_tbl_gfx2d),
+			GFP_KERNEL);
+
 	/* Initialize clock registers. */
 	reg_init();
 
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index ac68d7a..7233a16 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1703,7 +1703,7 @@
 	CLK_LOOKUP("pcm_clk",		pcm_clk.c,			NULL),
 
 	CLK_LOOKUP("sps_slimbus_clk",	sps_slimbus_clk.c,	NULL),
-	CLK_LOOKUP("audio_slimbus_clk",	audio_slimbus_clk.c,	NULL),
+	CLK_LOOKUP("core_clk",		audio_slimbus_clk.c, "msm_slim_ctrl.1"),
 	CLK_LOOKUP("core_clk",		dfab_usb_hs_clk.c,	"msm_otg"),
 	CLK_LOOKUP("bus_clk",		dfab_sdc1_clk.c,	"msm_sdcc.1"),
 	CLK_LOOKUP("bus_clk",		dfab_sdc2_clk.c,	"msm_sdcc.2"),
@@ -1834,6 +1834,14 @@
 	regval = readl_relaxed(PMEM_ACLK_CTL_REG);
 	regval &= ~BIT(6);
 	writel_relaxed(regval, PMEM_ACLK_CTL_REG);
+
+	/*
+	 * Disable hardware clock gating for dma_bam_p_clk, which does
+	 * not have working support for the feature.
+	 */
+	regval = readl_relaxed(DMA_BAM_HCLK_CTL);
+	regval &= ~BIT(6);
+	writel_relaxed(regval, DMA_BAM_HCLK_CTL);
 }
 
 /* Local clock driver initialization. */
diff --git a/arch/arm/mach-msm/cp14.h b/arch/arm/mach-msm/cp14.h
index 9f7241e..d640412 100644
--- a/arch/arm/mach-msm/cp14.h
+++ b/arch/arm/mach-msm/cp14.h
@@ -325,21 +325,21 @@
 #define RCP14_ETMACTR14()		MRC14(1, c0, c14, 2)
 #define RCP14_ETMACTR15()		MRC14(1, c0, c15, 2)
 #define RCP14_ETMDCVR0()		MRC14(1, c0, c0, 3)
-#define RCP14_ETMDCVR1()		MRC14(1, c0, c1, 3)
 #define RCP14_ETMDCVR2()		MRC14(1, c0, c2, 3)
-#define RCP14_ETMDCVR3()		MRC14(1, c0, c3, 3)
 #define RCP14_ETMDCVR4()		MRC14(1, c0, c4, 3)
-#define RCP14_ETMDCVR5()		MRC14(1, c0, c5, 3)
 #define RCP14_ETMDCVR6()		MRC14(1, c0, c6, 3)
-#define RCP14_ETMDCVR7()		MRC14(1, c0, c7, 3)
+#define RCP14_ETMDCVR8()		MRC14(1, c0, c8, 3)
+#define RCP14_ETMDCVR10()		MRC14(1, c0, c10, 3)
+#define RCP14_ETMDCVR12()		MRC14(1, c0, c12, 3)
+#define RCP14_ETMDCVR14()		MRC14(1, c0, c14, 3)
 #define RCP14_ETMDCMR0()		MRC14(1, c0, c0, 4)
-#define RCP14_ETMDCMR1()		MRC14(1, c0, c1, 4)
 #define RCP14_ETMDCMR2()		MRC14(1, c0, c2, 4)
-#define RCP14_ETMDCMR3()		MRC14(1, c0, c3, 4)
 #define RCP14_ETMDCMR4()		MRC14(1, c0, c4, 4)
-#define RCP14_ETMDCMR5()		MRC14(1, c0, c5, 4)
 #define RCP14_ETMDCMR6()		MRC14(1, c0, c6, 4)
-#define RCP14_ETMDCMR7()		MRC14(1, c0, c7, 4)
+#define RCP14_ETMDCMR8()		MRC14(1, c0, c8, 4)
+#define RCP14_ETMDCMR10()		MRC14(1, c0, c10, 4)
+#define RCP14_ETMDCMR12()		MRC14(1, c0, c12, 4)
+#define RCP14_ETMDCMR14()		MRC14(1, c0, c14, 4)
 #define RCP14_ETMCNTRLDVR0()		MRC14(1, c0, c0, 5)
 #define RCP14_ETMCNTRLDVR1()		MRC14(1, c0, c1, 5)
 #define RCP14_ETMCNTRLDVR2()		MRC14(1, c0, c2, 5)
@@ -389,7 +389,7 @@
 #define RCP14_ETMAUXCR()		MRC14(1, c0, c15, 7)
 #define RCP14_ETMTRACEIDR()		MRC14(1, c1, c0, 0)
 #define RCP14_ETMIDR2()			MRC14(1, c1, c2, 0)
-#define RCP14_ETMVMIDCVR()		MRC14(1, c1, c1, 0)
+#define RCP14_ETMVMIDCVR()		MRC14(1, c1, c0, 1)
 #define RCP14_ETMOSLSR()		MRC14(1, c1, c1, 4)
 /* not available in PFTv1.1 */
 #define RCP14_ETMOSSRR()		MRC14(1, c1, c2, 4)
@@ -462,21 +462,21 @@
 #define WCP14_ETMACTR14(val)		MCR14(val, 1, c0, c14, 2)
 #define WCP14_ETMACTR15(val)		MCR14(val, 1, c0, c15, 2)
 #define WCP14_ETMDCVR0(val)		MCR14(val, 1, c0, c0, 3)
-#define WCP14_ETMDCVR1(val)		MCR14(val, 1, c0, c1, 3)
 #define WCP14_ETMDCVR2(val)		MCR14(val, 1, c0, c2, 3)
-#define WCP14_ETMDCVR3(val)		MCR14(val, 1, c0, c3, 3)
 #define WCP14_ETMDCVR4(val)		MCR14(val, 1, c0, c4, 3)
-#define WCP14_ETMDCVR5(val)		MCR14(val, 1, c0, c5, 3)
 #define WCP14_ETMDCVR6(val)		MCR14(val, 1, c0, c6, 3)
-#define WCP14_ETMDCVR7(val)		MCR14(val, 1, c0, c7, 3)
+#define WCP14_ETMDCVR8(val)		MCR14(val, 1, c0, c8, 3)
+#define WCP14_ETMDCVR10(val)		MCR14(val, 1, c0, c10, 3)
+#define WCP14_ETMDCVR12(val)		MCR14(val, 1, c0, c12, 3)
+#define WCP14_ETMDCVR14(val)		MCR14(val, 1, c0, c14, 3)
 #define WCP14_ETMDCMR0(val)		MCR14(val, 1, c0, c0, 4)
-#define WCP14_ETMDCMR1(val)		MCR14(val, 1, c0, c1, 4)
 #define WCP14_ETMDCMR2(val)		MCR14(val, 1, c0, c2, 4)
-#define WCP14_ETMDCMR3(val)		MCR14(val, 1, c0, c3, 4)
 #define WCP14_ETMDCMR4(val)		MCR14(val, 1, c0, c4, 4)
-#define WCP14_ETMDCMR5(val)		MCR14(val, 1, c0, c5, 4)
 #define WCP14_ETMDCMR6(val)		MCR14(val, 1, c0, c6, 4)
-#define WCP14_ETMDCMR7(val)		MCR14(val, 1, c0, c7, 4)
+#define WCP14_ETMDCMR8(val)		MCR14(val, 1, c0, c8, 4)
+#define WCP14_ETMDCMR10(val)		MCR14(val, 1, c0, c10, 4)
+#define WCP14_ETMDCMR12(val)		MCR14(val, 1, c0, c12, 4)
+#define WCP14_ETMDCMR14(val)		MCR14(val, 1, c0, c14, 4)
 #define WCP14_ETMCNTRLDVR0(val)		MCR14(val, 1, c0, c0, 5)
 #define WCP14_ETMCNTRLDVR1(val)		MCR14(val, 1, c0, c1, 5)
 #define WCP14_ETMCNTRLDVR2(val)		MCR14(val, 1, c0, c2, 5)
@@ -525,7 +525,7 @@
 #define WCP14_ETMAUXCR(val)		MCR14(val, 1, c0, c15, 7)
 #define WCP14_ETMTRACEIDR(val)		MCR14(val, 1, c1, c0, 0)
 #define WCP14_ETMIDR2(val)		MCR14(val, 1, c1, c2, 0)
-#define WCP14_ETMVMIDCVR(val)		MCR14(val, 1, c1, c1, 0)
+#define WCP14_ETMVMIDCVR(val)		MCR14(val, 1, c1, c0, 1)
 #define WCP14_ETMOSLAR(val)		MCR14(val, 1, c1, c0, 4)
 /* not available in PFTv1.1 */
 #define WCP14_ETMOSSRR(val)		MCR14(val, 1, c1, c2, 4)
diff --git a/arch/arm/mach-msm/cpufreq.c b/arch/arm/mach-msm/cpufreq.c
index 81d01c2..56778e2 100644
--- a/arch/arm/mach-msm/cpufreq.c
+++ b/arch/arm/mach-msm/cpufreq.c
@@ -173,6 +173,14 @@
 	struct cpufreq_work_struct *cpu_work = NULL;
 #endif
 
+	/*
+	 * In 8625 both cpu core's frequency can not
+	 * be changed independently. Each cpu is bound to
+	 * same frequency. Hence set the cpumask to all cpu.
+	 */
+	if (cpu_is_msm8625())
+		cpumask_setall(policy->cpus);
+
 	table = cpufreq_frequency_get_table(policy->cpu);
 	if (table == NULL)
 		return -ENODEV;
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 912d1b0..7915b5f 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -28,6 +28,7 @@
 #include <mach/msm_bus_board.h>
 #include <mach/rpm.h>
 #include <mach/mdm2.h>
+#include <linux/ion.h>
 #include "clock.h"
 #include "devices.h"
 #include "msm_watchdog.h"
@@ -305,7 +306,7 @@
 };
 
 struct platform_device apq_cpudai_hdmi_rx = {
-	.name	= "msm-dai-q6",
+	.name	= "msm-dai-q6-hdmi",
 	.id	= 8,
 };
 
@@ -590,6 +591,270 @@
 	},
 };
 
+/* MSM Video core device */
+#ifdef CONFIG_MSM_BUS_SCALING
+static struct msm_bus_vectors vidc_init_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VIDEO_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_VIDEO_DEC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 0,
+		.ib  = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = 0,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab = 0,
+		.ib = 0,
+	},
+};
+static struct msm_bus_vectors vidc_venc_vga_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VIDEO_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 54525952,
+		.ib  = 436207616,
+	},
+	{
+		.src = MSM_BUS_MASTER_VIDEO_DEC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 72351744,
+		.ib  = 289406976,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 500000,
+		.ib  = 1000000,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 500000,
+		.ib  = 1000000,
+	},
+};
+static struct msm_bus_vectors vidc_vdec_vga_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VIDEO_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 40894464,
+		.ib  = 327155712,
+	},
+	{
+		.src = MSM_BUS_MASTER_VIDEO_DEC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 48234496,
+		.ib  = 192937984,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 500000,
+		.ib  = 2000000,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 500000,
+		.ib  = 2000000,
+	},
+};
+static struct msm_bus_vectors vidc_venc_720p_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VIDEO_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 163577856,
+		.ib  = 1308622848,
+	},
+	{
+		.src = MSM_BUS_MASTER_VIDEO_DEC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 219152384,
+		.ib  = 876609536,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 1750000,
+		.ib  = 3500000,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 1750000,
+		.ib  = 3500000,
+	},
+};
+static struct msm_bus_vectors vidc_vdec_720p_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VIDEO_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 121634816,
+		.ib  = 973078528,
+	},
+	{
+		.src = MSM_BUS_MASTER_VIDEO_DEC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 155189248,
+		.ib  = 620756992,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 1750000,
+		.ib  = 7000000,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 1750000,
+		.ib  = 7000000,
+	},
+};
+static struct msm_bus_vectors vidc_venc_1080p_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VIDEO_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 372244480,
+		.ib  = 2560000000U,
+	},
+	{
+		.src = MSM_BUS_MASTER_VIDEO_DEC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 501219328,
+		.ib  = 2560000000U,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 2500000,
+		.ib  = 5000000,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 2500000,
+		.ib  = 5000000,
+	},
+};
+static struct msm_bus_vectors vidc_vdec_1080p_vectors[] = {
+	{
+		.src = MSM_BUS_MASTER_VIDEO_ENC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 222298112,
+		.ib  = 2560000000U,
+	},
+	{
+		.src = MSM_BUS_MASTER_VIDEO_DEC,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 330301440,
+		.ib  = 2560000000U,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 2500000,
+		.ib  = 700000000,
+	},
+	{
+		.src = MSM_BUS_MASTER_AMPSS_M0,
+		.dst = MSM_BUS_SLAVE_EBI_CH0,
+		.ab  = 2500000,
+		.ib  = 10000000,
+	},
+};
+
+static struct msm_bus_paths vidc_bus_client_config[] = {
+	{
+		ARRAY_SIZE(vidc_init_vectors),
+		vidc_init_vectors,
+	},
+	{
+		ARRAY_SIZE(vidc_venc_vga_vectors),
+		vidc_venc_vga_vectors,
+	},
+	{
+		ARRAY_SIZE(vidc_vdec_vga_vectors),
+		vidc_vdec_vga_vectors,
+	},
+	{
+		ARRAY_SIZE(vidc_venc_720p_vectors),
+		vidc_venc_720p_vectors,
+	},
+	{
+		ARRAY_SIZE(vidc_vdec_720p_vectors),
+		vidc_vdec_720p_vectors,
+	},
+	{
+		ARRAY_SIZE(vidc_venc_1080p_vectors),
+		vidc_venc_1080p_vectors,
+	},
+	{
+		ARRAY_SIZE(vidc_vdec_1080p_vectors),
+		vidc_vdec_1080p_vectors,
+	},
+};
+
+static struct msm_bus_scale_pdata vidc_bus_client_data = {
+	vidc_bus_client_config,
+	ARRAY_SIZE(vidc_bus_client_config),
+	.name = "vidc",
+};
+#endif
+
+
+#define APQ8064_VIDC_BASE_PHYS 0x04400000
+#define APQ8064_VIDC_BASE_SIZE 0x00100000
+
+static struct resource apq8064_device_vidc_resources[] = {
+	{
+		.start	= APQ8064_VIDC_BASE_PHYS,
+		.end	= APQ8064_VIDC_BASE_PHYS + APQ8064_VIDC_BASE_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= VCODEC_IRQ,
+		.end	= VCODEC_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct msm_vidc_platform_data apq8064_vidc_platform_data = {
+#ifdef CONFIG_MSM_BUS_SCALING
+	.vidc_bus_client_pdata = &vidc_bus_client_data,
+#endif
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	.memtype = ION_CP_MM_HEAP_ID,
+	.enable_ion = 1,
+#else
+	.memtype = MEMTYPE_EBI1,
+	.enable_ion = 0,
+#endif
+	.disable_dmx = 0,
+	.disable_fullhd = 0,
+};
+
+struct platform_device apq8064_msm_device_vidc = {
+	.name = "msm_vidc",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(apq8064_device_vidc_resources),
+	.resource = apq8064_device_vidc_resources,
+	.dev = {
+		.platform_data	= &apq8064_vidc_platform_data,
+	},
+};
 #define MSM_SDC1_BASE         0x12400000
 #define MSM_SDC1_DML_BASE     (MSM_SDC1_BASE + 0x800)
 #define MSM_SDC1_BAM_BASE     (MSM_SDC1_BASE + 0x2000)
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index fc732da..e9b94f6 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -1181,6 +1181,7 @@
 	.set_grp_async = set_grp3d_async,
 	.idle_timeout = HZ/20,
 	.nap_allowed = true,
+	.idle_needed = true,
 	.clk_map = KGSL_CLK_SRC | KGSL_CLK_CORE |
 		KGSL_CLK_IFACE | KGSL_CLK_MEM,
 };
@@ -1223,6 +1224,7 @@
 	.set_grp_async = NULL,
 	.idle_timeout = HZ/10,
 	.nap_allowed = true,
+	.idle_needed = true,
 	.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE,
 };
 
diff --git a/arch/arm/mach-msm/devices-msm8x60.h b/arch/arm/mach-msm/devices-msm8x60.h
index a2f6a1f..9bfaeee 100644
--- a/arch/arm/mach-msm/devices-msm8x60.h
+++ b/arch/arm/mach-msm/devices-msm8x60.h
@@ -56,6 +56,7 @@
 extern struct platform_device msm_device_smd;
 extern struct platform_device msm_device_gpio;
 extern struct platform_device msm_device_vidc;
+extern struct platform_device apq8064_msm_device_vidc;
 
 extern struct platform_device msm_charm_modem;
 extern struct platform_device msm_device_tz_log;
diff --git a/arch/arm/mach-msm/etm.c b/arch/arm/mach-msm/etm.c
index bee0975..9d04a58 100644
--- a/arch/arm/mach-msm/etm.c
+++ b/arch/arm/mach-msm/etm.c
@@ -377,9 +377,9 @@
 	etm_write(etm_config.etm_addr_access_type[6], ETMACTR6);
 	etm_write(etm_config.etm_addr_access_type[7], ETMACTR7);
 	etm_write(etm_config.etm_data_comp_value[0], ETMDCVR0);
-	etm_write(etm_config.etm_data_comp_value[1], ETMDCVR1);
+	etm_write(etm_config.etm_data_comp_value[1], ETMDCVR2);
 	etm_write(etm_config.etm_data_comp_mask[0], ETMDCMR0);
-	etm_write(etm_config.etm_data_comp_mask[1], ETMDCMR1);
+	etm_write(etm_config.etm_data_comp_mask[1], ETMDCMR2);
 	etm_write(etm_config.etm_counter_reload_value[0], ETMCNTRLDVR0);
 	etm_write(etm_config.etm_counter_reload_value[1], ETMCNTRLDVR1);
 	etm_write(etm_config.etm_counter_enable[0], ETMCNTENR0);
@@ -564,9 +564,9 @@
 	emit_log_word(etm_read(ETMACTR6));
 	emit_log_word(etm_read(ETMACTR7));
 	emit_log_word(etm_read(ETMDCVR0));
-	emit_log_word(etm_read(ETMDCVR1));
+	emit_log_word(etm_read(ETMDCVR2));
 	emit_log_word(etm_read(ETMDCMR0));
-	emit_log_word(etm_read(ETMDCMR1));
+	emit_log_word(etm_read(ETMDCMR2));
 	emit_log_word(etm_read(ETMCNTRLDVR0));
 	emit_log_word(etm_read(ETMCNTRLDVR1));
 	emit_log_word(etm_read(ETMCNTENR0));
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
index 26adec6..616763c 100644
--- a/arch/arm/mach-msm/hotplug.c
+++ b/arch/arm/mach-msm/hotplug.c
@@ -49,6 +49,9 @@
 			/*
 			 * OK, proper wakeup, we're done
 			 */
+			pen_release = -1;
+			dmac_flush_range((void *)&pen_release,
+				(void *)(&pen_release + sizeof(pen_release)));
 			break;
 		}
 
@@ -60,6 +63,8 @@
 		 * possible, since we are currently running incoherently, and
 		 * therefore cannot safely call printk() or anything else
 		 */
+		dmac_inv_range((void *)&pen_release,
+			       (void *)(&pen_release + sizeof(pen_release)));
 		pr_debug("CPU%u: spurious wakeup call\n", cpu);
 	}
 }
diff --git a/arch/arm/mach-msm/idle-v7.S b/arch/arm/mach-msm/idle-v7.S
index 631d520..c274899 100644
--- a/arch/arm/mach-msm/idle-v7.S
+++ b/arch/arm/mach-msm/idle-v7.S
@@ -106,12 +106,6 @@
 	sub	r1, r1, r0
 	bl	v7_flush_kern_dcache_area
 
-	mrc     p15, 0, r4, c1, c0, 0    /* read current CR    */
-	bic     r0, r4, #(1 << 2)        /* clear dcache bit   */
-	bic     r0, r0, #(1 << 12)       /* clear icache bit   */
-	mcr     p15, 0, r0, c1, c0, 0    /* disable d/i cache  */
-
-	dsb
 #ifdef CONFIG_ARCH_MSM_KRAIT
 	ldr	r0, =SCM_SVC_BOOT
 	ldr	r1, =SCM_CMD_TERMINATE_PC
@@ -119,10 +113,18 @@
 	ldr	r2, [r2]
 	bl	scm_call_atomic1
 #else
+	mrc     p15, 0, r4, c1, c0, 0    /* read current CR    */
+	bic     r0, r4, #(1 << 2)        /* clear dcache bit   */
+	bic     r0, r0, #(1 << 12)       /* clear icache bit   */
+	mcr     p15, 0, r0, c1, c0, 0    /* disable d/i cache  */
+	dsb
+
 	wfi
-#endif
+
 	mcr     p15, 0, r4, c1, c0, 0    /* restore d/i cache  */
 	isb
+#endif
+
 
 #if defined(CONFIG_MSM_FIQ_SUPPORT)
 	cpsie   f
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 530d2c1..700e28c 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -52,6 +52,7 @@
 	VFE_MODE_OF_OPERATION_VIDEO,
 	VFE_MODE_OF_OPERATION_RAW_SNAPSHOT,
 	VFE_MODE_OF_OPERATION_ZSL,
+	VFE_MODE_OF_OPERATION_JPEG_SNAPSHOT,
 	VFE_LAST_MODE_OF_OPERATION_ENUM
 };
 
@@ -87,6 +88,7 @@
 	VFE_MSG_V32_START,
 	VFE_MSG_V32_START_RECORDING, /* 20 */
 	VFE_MSG_V32_CAPTURE,
+	VFE_MSG_V32_JPEG_CAPTURE,
 	VFE_MSG_OUTPUT_IRQ,
 	VFE_MSG_V2X_PREVIEW,
 	VFE_MSG_V2X_CAPTURE,
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h b/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
index 88bc3c6..4c26d08 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7xxx.h
@@ -44,9 +44,6 @@
 #define MSM7XXX_TMR_PHYS          MSM7XXX_CSR_PHYS
 #define MSM7XXX_TMR_SIZE          SZ_4K
 
-#define MSM7XXX_TMR0_PHYS         0xC0800000
-#define MSM7XXX_TMR0_SIZE         SZ_4K
-
 #define MSM7XXX_GPIO1_PHYS        0xA9200000
 #define MSM7XXX_GPIO1_SIZE        SZ_4K
 
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8625.h b/arch/arm/mach-msm/include/mach/msm_iomap-8625.h
index 8088a4c..3435c2a 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8625.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8625.h
@@ -48,11 +48,11 @@
 #define MSM8625_SCU_PHYS		0xC0600000
 #define MSM8625_SCU_SIZE		SZ_256
 
-#define MSM8625_SPM0_PHYS		0xC0200000
-#define MSM8625_SPM0_SIZE		SZ_4K
+#define MSM8625_SAW0_PHYS		0xC0200000
+#define MSM8625_SAW0_SIZE		SZ_4K
 
-#define MSM8625_SPM1_PHYS		0xC0700000
-#define MSM8625_SPM1_SIZE		SZ_4K
+#define MSM8625_SAW1_PHYS		0xC0700000
+#define MSM8625_SAW1_SIZE		SZ_4K
 
 #define MSM8625_CFG_CTL_PHYS		0xA9800000
 #define MSM8625_CFG_CTL_SIZE		SZ_4K
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index bb2b019..7715811 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -48,7 +48,7 @@
 #if defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_APQ8064) || \
 	defined(CONFIG_ARCH_MSM8930) || defined(CONFIG_ARCH_MSM9615) || \
 	defined(CONFIG_ARCH_MSMCOPPER) || defined(CONFIG_ARCH_MSM7X27) || \
-	defined(CONFIG_ARCH_MSM7X01A) || defined(CONFIG_ARCH_MSM7X25) || \
+	defined(CONFIG_ARCH_MSM7X25) || defined(CONFIG_ARCH_MSM7X01A) || \
 	defined(CONFIG_ARCH_MSM8625)
 
 /* Unified iomap */
@@ -82,34 +82,33 @@
 #define MSM_APCS_GLB_BASE	IOMEM(0xFA702000)	/*  4K  */
 #define MSM_SAW2_BASE		IOMEM(0xFA703000)	/*  4k  */
 #define MSM_SAW3_BASE		IOMEM(0xFA704000)	/*  4k  */
-#define MSM_VIC_BASE		IOMEM(0xFA705000)	/* 4K */
-#define MSM_CSR_BASE		MSM_TMR_BASE		/* 4K */
-#define MSM_GPIO1_BASE		IOMEM(0xFA706000)	/* 4K */
-#define MSM_GPIO2_BASE		IOMEM(0xFA707000)	/* 4K */
-#define MSM_SCU_BASE		IOMEM(0xFA708000)	/* 4K */
-#define MSM_SPM0_BASE		IOMEM(0xFA709000)	/* 4K */
-#define MSM_SPM1_BASE		IOMEM(0xFA70A000)	/* 4K */
-#define MSM_CFG_CTL_BASE	IOMEM(0xFA70B000)	/* 4K */
-#define MSM_MDC_BASE		IOMEM(0xFA70C000)	/* 4K */
-#define MSM_AD5_BASE		IOMEM(0xFA70D000)	/* 4K */
-
+#define MSM_VIC_BASE		IOMEM(0xFA100000)	/*  4K */
+#define MSM_CSR_BASE		IOMEM(0xFA101000)	/*  4K */
+#define MSM_GPIO1_BASE		IOMEM(0xFA102000)	/*  4K */
+#define MSM_GPIO2_BASE		IOMEM(0xFA103000)	/*  4K */
+#define MSM_SCU_BASE		IOMEM(0xFA102000)	/*  4K */
+#define MSM_CFG_CTL_BASE	IOMEM(0xFA00C000)	/*  4K */
+#define MSM_MDC_BASE		IOMEM(0xFA400000)	/*  1M */
+#define MSM_AD5_BASE		IOMEM(0xFA900000)	/*  13M (D00000)
+							  0xFB600000 */
 
 #define MSM_STRONGLY_ORDERED_PAGE	0xFA0F0000
 #define MSM8625_SECONDARY_PHYS		0x0FE00000
 
+
 #if defined(CONFIG_ARCH_MSM9615) || defined(CONFIG_ARCH_MSM7X27)
 #define MSM_SHARED_RAM_SIZE	SZ_1M
 #else
 #define MSM_SHARED_RAM_SIZE	SZ_2M
 #endif
 
+#include "msm_iomap-7xxx.h"
+#include "msm_iomap-8625.h"
 #include "msm_iomap-8960.h"
 #include "msm_iomap-8930.h"
 #include "msm_iomap-8064.h"
 #include "msm_iomap-9615.h"
 #include "msm_iomap-copper.h"
-#include "msm_iomap-7xxx.h"
-#include "msm_iomap-8625.h"
 
 #else
 /* Legacy single-target iomap */
@@ -123,7 +122,7 @@
 #elif defined(CONFIG_ARCH_FSM9XXX)
 #include "msm_iomap-fsm9xxx.h"
 #else
-#error "Target compiling without iomap"
+#error "Target compiled without IO map\n"
 #endif
 
 #if defined(CONFIG_DEBUG_MSM_UART1)
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 830db1f..507b74b 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -410,8 +410,8 @@
 	MSM_CHIP_DEVICE(SCU, MSM8625),
 	MSM_CHIP_DEVICE(CFG_CTL, MSM8625),
 	MSM_CHIP_DEVICE(CLK_CTL, MSM8625),
-	MSM_CHIP_DEVICE(SPM0, MSM8625),
-	MSM_CHIP_DEVICE(SPM1, MSM8625),
+	MSM_CHIP_DEVICE(SAW0, MSM8625),
+	MSM_CHIP_DEVICE(SAW1, MSM8625),
 #if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \
 	defined(CONFIG_DEBUG_MSM_UART3)
 	MSM_CHIP_DEVICE(DEBUG_UART, MSM7XXX),
diff --git a/arch/arm/mach-msm/jtag.c b/arch/arm/mach-msm/jtag.c
index f720fa9..b75fb38 100644
--- a/arch/arm/mach-msm/jtag.c
+++ b/arch/arm/mach-msm/jtag.c
@@ -22,8 +22,10 @@
 #include "qdss.h"
 #include "cp14.h"
 
+ /* no of dbg regs + 1 (for storing the reg count) */
 #define MAX_DBG_REGS		(90)
 #define MAX_DBG_STATE_SIZE	(MAX_DBG_REGS * num_possible_cpus())
+ /* no of etm regs + 1 (for storing the reg count) */
 #define MAX_ETM_REGS		(78)
 #define MAX_ETM_STATE_SIZE	(MAX_ETM_REGS * num_possible_cpus())
 
@@ -70,7 +72,7 @@
 		break;
 	case 3:
 		state[i++] = dbg_read(DBGBVR3);
-		state[i++] = dbg_read(DBGBVR3);
+		state[i++] = dbg_read(DBGBCR3);
 		break;
 	case 4:
 		state[i++] = dbg_read(DBGBVR4);
@@ -78,7 +80,7 @@
 		break;
 	case 5:
 		state[i++] = dbg_read(DBGBVR5);
-		state[i++] = dbg_read(DBGBVR5);
+		state[i++] = dbg_read(DBGBCR5);
 		break;
 	case 6:
 		state[i++] = dbg_read(DBGBVR6);
@@ -143,7 +145,7 @@
 		break;
 	case 3:
 		dbg_write(state[i++], DBGBVR3);
-		dbg_write(state[i++], DBGBVR3);
+		dbg_write(state[i++], DBGBCR3);
 		break;
 	case 4:
 		dbg_write(state[i++], DBGBVR4);
@@ -151,7 +153,7 @@
 		break;
 	case 5:
 		dbg_write(state[i++], DBGBVR5);
-		dbg_write(state[i++], DBGBVR5);
+		dbg_write(state[i++], DBGBCR5);
 		break;
 	case 6:
 		dbg_write(state[i++], DBGBVR6);
@@ -937,9 +939,9 @@
 		etm_write(etm.state[i++], ETMSQ12EVR);
 		etm_write(etm.state[i++], ETMSQ21EVR);
 		etm_write(etm.state[i++], ETMSQ23EVR);
+		etm_write(etm.state[i++], ETMSQ31EVR);
 		etm_write(etm.state[i++], ETMSQ32EVR);
 		etm_write(etm.state[i++], ETMSQ13EVR);
-		etm_write(etm.state[i++], ETMSQ31EVR);
 		etm_write(etm.state[i++], ETMSQR);
 		for (j = 0; j < etm.nr_ext_out; j++)
 			i = etm_write_extoutevr(etm.state, i, j);
@@ -1046,9 +1048,9 @@
 		pr_info("dbg arch %u not supported\n", dbg.arch);
 		goto dbg_out;
 	}
-	dbg.nr_ctx_cmp = BMVAL(dbgdidr, 20, 23);
-	dbg.nr_bp = BMVAL(dbgdidr, 24, 27);
-	dbg.nr_wp = BMVAL(dbgdidr, 28, 31);
+	dbg.nr_ctx_cmp = BMVAL(dbgdidr, 20, 23) + 1;
+	dbg.nr_bp = BMVAL(dbgdidr, 24, 27) + 1;
+	dbg.nr_wp = BMVAL(dbgdidr, 28, 31) + 1;
 
 	/* Allocate dbg state save space */
 	dbg.state = kzalloc(MAX_DBG_STATE_SIZE * sizeof(uint32_t), GFP_KERNEL);
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index 3b064ff..d26d76b 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/memory.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -226,6 +226,25 @@
 	return unstable_limit - mb->start;
 }
 
+/* stable size of all memory banks contiguous to and below this one */
+static unsigned long total_stable_size(unsigned long bank)
+{
+	int i;
+	struct membank *mb = &meminfo.bank[bank];
+	int memtype = reserve_info->paddr_to_memtype(mb->start);
+	unsigned long size;
+
+	size = stable_size(mb, reserve_info->low_unstable_address);
+	for (i = bank - 1, mb = &meminfo.bank[bank - 1]; i >= 0; i--, mb--) {
+		if (mb->start + mb->size != (mb + 1)->start)
+			break;
+		if (reserve_info->paddr_to_memtype(mb->start) != memtype)
+			break;
+		size += stable_size(mb, reserve_info->low_unstable_address);
+	}
+	return size;
+}
+
 static void __init calculate_reserve_limits(void)
 {
 	int i;
@@ -242,7 +261,7 @@
 			continue;
 		}
 		mt = &reserve_info->memtype_reserve_table[memtype];
-		size = stable_size(mb, reserve_info->low_unstable_address);
+		size = total_stable_size(i);
 		mt->limit = max(mt->limit, size);
 	}
 }
@@ -277,10 +296,11 @@
 		if (mt->flags & MEMTYPE_FLAGS_FIXED || !mt->size)
 			continue;
 
-		/* We know we will find a memory bank of the proper size
+		/* We know we will find memory bank(s) of the proper size
 		 * as we have limited the size of the memory pool for
-		 * each memory type to the size of the largest memory
-		 * bank. Choose the memory bank with the highest physical
+		 * each memory type to the largest total size of the memory
+		 * banks which are contiguous and of the correct memory type.
+		 * Choose the memory bank with the highest physical
 		 * address which is large enough, so that we will not
 		 * take memory from the lowest memory bank which the kernel
 		 * is in (and cause boot problems) and so that we might
@@ -293,9 +313,14 @@
 				reserve_info->paddr_to_memtype(mb->start);
 			if (memtype != membank_type)
 				continue;
-			size = stable_size(mb,
-				reserve_info->low_unstable_address);
+			size = total_stable_size(i);
 			if (size >= mt->size) {
+				size = stable_size(mb,
+					reserve_info->low_unstable_address);
+				/* mt->size may be larger than size, all this
+				 * means is that we are carving the memory pool
+				 * out of multiple contiguous memory banks.
+				 */
 				mt->start = mb->start + (size - mt->size);
 				ret = memblock_remove(mt->start, mt->size);
 				BUG_ON(ret);
diff --git a/arch/arm/mach-msm/platsmp-8625.c b/arch/arm/mach-msm/platsmp-8625.c
new file mode 100644
index 0000000..534fc0e
--- /dev/null
+++ b/arch/arm/mach-msm/platsmp-8625.c
@@ -0,0 +1,202 @@
+/* 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/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/smp_scu.h>
+#include <asm/unified.h>
+#include <mach/msm_iomap.h>
+#include <mach/smp.h>
+#include "pm.h"
+
+#define MSM_CORE1_RESET		0xA8600590
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+int pen_release = -1;
+
+static bool cold_boot_done;
+
+static uint32_t *msm8625_boot_vector;
+
+/*
+ * Write pen_release in a way that is guaranteed to be visible to all
+ * observers, irrespective of whether they're taking part in coherency
+ * or not.  This is necessary for the hotplug code to work reliably.
+ */
+static void __cpuinit write_pen_release(int val)
+{
+	pen_release = val;
+	smp_wmb();
+	__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
+static void __iomem *scu_base_addr(void)
+{
+	return MSM_SCU_BASE;
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+	/*
+	 * if any interrupts are already enabled for the primary
+	 * core (e.g. timer irq), then they will not have been enabled
+	 * for us: do so
+	 */
+	gic_secondary_init(0);
+
+	/*
+	 * let the primary processor know we're out of the
+	 * pen, then head off into the C entry point
+	 */
+	write_pen_release(-1);
+
+	/*
+	 * Synchronise with the boot thread.
+	 */
+	spin_lock(&boot_lock);
+	spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	unsigned long timeout;
+	void __iomem *base_ptr;
+
+	if (cold_boot_done == false) {
+		base_ptr = ioremap_nocache(MSM_CORE1_RESET, SZ_4);
+		if (!base_ptr)
+			return -ENODEV;
+		/* Reset core 1 out of reset */
+		__raw_writel(0x0, base_ptr);
+		mb();
+		cold_boot_done = true;
+		iounmap(base_ptr);
+	}
+
+	/*
+	 * Set synchronisation state between this boot processor
+	 * and the secondary one
+	 */
+	spin_lock(&boot_lock);
+
+	/*
+	 * This is really belt and braces; we hold unintended secondary
+	 * CPUs in the holding pen until we're ready for them.  However,
+	 * since we haven't sent them a soft interrupt, they shouldn't
+	 * be there.
+	 */
+	write_pen_release(cpu);
+
+	/*
+	 * Send the secondary CPU a soft interrupt, thereby causing
+	 * the boot monitor to read the system wide flags register,
+	 * and branch to the address found there.
+	 */
+	gic_raise_softirq(cpumask_of(cpu), 1);
+
+	timeout = jiffies + (1 * HZ);
+	while (time_before(jiffies, timeout)) {
+		smp_rmb();
+		if (pen_release == -1)
+			break;
+
+		udelay(10);
+	}
+
+	/*
+	 * now the secondary core is starting up let it run its
+	 * calibrations, then wait for it to finish
+	 */
+	spin_unlock(&boot_lock);
+
+	return 0;
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+void __init smp_init_cpus(void)
+{
+	void __iomem *scu_base = scu_base_addr();
+
+	unsigned int i, ncores;
+
+	ncores = scu_base ? scu_get_core_count(scu_base) : 1;
+
+	for (i = 0; i < ncores; i++)
+		set_cpu_possible(i, true);
+
+	set_smp_cross_call(gic_raise_softirq);
+}
+
+static void __init msm8625_boot_vector_init(uint32_t *boot_vector,
+		unsigned long entry)
+{
+	if (!boot_vector)
+		return;
+	msm8625_boot_vector = boot_vector;
+
+	msm8625_boot_vector[0] = 0xE51FF004; /* ldr pc, 4 */
+	msm8625_boot_vector[1] = entry;
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+	int i, value;
+	void __iomem *second_ptr;
+
+	/*
+	 * Initialise the present map, which describes the set of CPUs
+	 * actually populated at the present time.
+	 */
+	for (i = 0; i < max_cpus; i++)
+		set_cpu_present(i, true);
+
+	scu_enable(scu_base_addr());
+
+	/*
+	 * Write the address of secondary startup into the
+	 * boot remapper register. The secondary CPU branches to this address.
+	 */
+	__raw_writel(MSM8625_SECONDARY_PHYS, (MSM_CFG_CTL_BASE + 0x34));
+	mb();
+
+	second_ptr = ioremap_nocache(MSM8625_SECONDARY_PHYS, SZ_8);
+	if (!second_ptr) {
+		pr_err("failed to ioremap for secondary core\n");
+		return;
+	}
+
+	msm8625_boot_vector_init(second_ptr,
+			virt_to_phys(msm_secondary_startup));
+	iounmap(second_ptr);
+
+	/* Enable boot remapper address: bit 26 for core1 */
+	value = __raw_readl(MSM_CFG_CTL_BASE + 0x30);
+	__raw_writel(value | (0x4 << 24), MSM_CFG_CTL_BASE + 0x30) ;
+	mb();
+}
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index 4cdd7ae..e1934bb 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -3,7 +3,7 @@
  * MSM Power Management Routines
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012 Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -118,18 +118,6 @@
  * Sleep Modes and Parameters
  *****************************************************************************/
 
-static int msm_pm_sleep_mode = CONFIG_MSM7X00A_SLEEP_MODE;
-module_param_named(
-	sleep_mode, msm_pm_sleep_mode,
-	int, S_IRUGO | S_IWUSR | S_IWGRP
-);
-
-static int msm_pm_idle_sleep_mode = CONFIG_MSM7X00A_IDLE_SLEEP_MODE;
-module_param_named(
-	idle_sleep_mode, msm_pm_idle_sleep_mode,
-	int, S_IRUGO | S_IWUSR | S_IWGRP
-);
-
 static int msm_pm_idle_sleep_min_time = CONFIG_MSM7X00A_IDLE_SLEEP_MIN_TIME;
 module_param_named(
 	idle_sleep_min_time, msm_pm_idle_sleep_min_time,
@@ -166,10 +154,20 @@
 
 static struct msm_pm_platform_data *msm_pm_modes;
 
-static struct kobject *msm_pm_mode_kobjs[MSM_PM_SLEEP_MODE_NR];
-static struct attribute_group *msm_pm_mode_attr_group[MSM_PM_SLEEP_MODE_NR];
-static struct attribute **msm_pm_mode_attrs[MSM_PM_SLEEP_MODE_NR];
-static struct kobj_attribute *msm_pm_mode_kobj_attrs[MSM_PM_SLEEP_MODE_NR];
+struct msm_pm_kobj_attribute {
+	unsigned int cpu;
+	struct kobj_attribute ka;
+};
+
+#define GET_CPU_OF_ATTR(attr) \
+	(container_of(attr, struct msm_pm_kobj_attribute, ka)->cpu)
+
+struct msm_pm_sysfs_sleep_mode {
+	struct kobject *kobj;
+	struct attribute_group attr_group;
+	struct attribute *attrs[MSM_PM_MODE_ATTR_NR + 1];
+	struct msm_pm_kobj_attribute kas[MSM_PM_MODE_ATTR_NR];
+};
 
 /*
  * Write out the attribute.
@@ -182,6 +180,8 @@
 
 	for (i = 0; i < MSM_PM_SLEEP_MODE_NR; i++) {
 		struct kernel_param kp;
+		unsigned int cpu;
+		struct msm_pm_platform_data *mode;
 
 		if (msm_pm_sleep_mode_labels[i] == NULL)
 			continue;
@@ -189,23 +189,28 @@
 		if (strcmp(kobj->name, msm_pm_sleep_mode_labels[i]))
 			continue;
 
+		cpu = GET_CPU_OF_ATTR(attr);
+		mode = &msm_pm_modes[MSM_PM_MODE(cpu, i)];
+
 		if (!strcmp(attr->attr.name,
 			msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_SUSPEND])) {
-			u32 arg = msm_pm_modes[i].suspend_enabled;
+			u32 arg = mode->suspend_enabled;
 			kp.arg = &arg;
 			ret = param_get_ulong(buf, &kp);
 		} else if (!strcmp(attr->attr.name,
 			msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_IDLE])) {
-			u32 arg = msm_pm_modes[i].idle_enabled;
+			u32 arg = mode->idle_enabled;
 			kp.arg = &arg;
 			ret = param_get_ulong(buf, &kp);
 		} else if (!strcmp(attr->attr.name,
 			msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_LATENCY])) {
-			kp.arg = &msm_pm_modes[i].latency;
+			u32 arg = mode->latency;
+			kp.arg = &arg;
 			ret = param_get_ulong(buf, &kp);
 		} else if (!strcmp(attr->attr.name,
 			msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_RESIDENCY])) {
-			kp.arg = &msm_pm_modes[i].residency;
+			u32 arg = mode->residency;
+			kp.arg = &arg;
 			ret = param_get_ulong(buf, &kp);
 		}
 
@@ -213,7 +218,7 @@
 	}
 
 	if (ret > 0) {
-		strcat(buf, "\n");
+		strlcat(buf, "\n", PAGE_SIZE);
 		ret++;
 	}
 
@@ -231,6 +236,8 @@
 
 	for (i = 0; i < MSM_PM_SLEEP_MODE_NR; i++) {
 		struct kernel_param kp;
+		unsigned int cpu;
+		struct msm_pm_platform_data *mode;
 
 		if (msm_pm_sleep_mode_labels[i] == NULL)
 			continue;
@@ -238,21 +245,24 @@
 		if (strcmp(kobj->name, msm_pm_sleep_mode_labels[i]))
 			continue;
 
+		cpu = GET_CPU_OF_ATTR(attr);
+		mode = &msm_pm_modes[MSM_PM_MODE(cpu, i)];
+
 		if (!strcmp(attr->attr.name,
 			msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_SUSPEND])) {
-			kp.arg = &msm_pm_modes[i].suspend_enabled;
+			kp.arg = &mode->suspend_enabled;
 			ret = param_set_byte(buf, &kp);
 		} else if (!strcmp(attr->attr.name,
 			msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_IDLE])) {
-			kp.arg = &msm_pm_modes[i].idle_enabled;
+			kp.arg = &mode->idle_enabled;
 			ret = param_set_byte(buf, &kp);
 		} else if (!strcmp(attr->attr.name,
 			msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_LATENCY])) {
-			kp.arg = &msm_pm_modes[i].latency;
+			kp.arg = &mode->latency;
 			ret = param_set_ulong(buf, &kp);
 		} else if (!strcmp(attr->attr.name,
 			msm_pm_mode_attr_labels[MSM_PM_MODE_ATTR_RESIDENCY])) {
-			kp.arg = &msm_pm_modes[i].residency;
+			kp.arg = &mode->residency;
 			ret = param_set_ulong(buf, &kp);
 		}
 
@@ -262,6 +272,86 @@
 	return ret ? ret : count;
 }
 
+ /* Add sysfs entries for one cpu. */
+static int __init msm_pm_mode_sysfs_add_cpu(
+	unsigned int cpu, struct kobject *modes_kobj)
+{
+	char cpu_name[8];
+	struct kobject *cpu_kobj;
+	struct msm_pm_sysfs_sleep_mode *mode = NULL;
+	int i, j, k;
+	int ret;
+
+	snprintf(cpu_name, sizeof(cpu_name), "cpu%u", cpu);
+	cpu_kobj = kobject_create_and_add(cpu_name, modes_kobj);
+	if (!cpu_kobj) {
+		pr_err("%s: cannot create %s kobject\n", __func__, cpu_name);
+		ret = -ENOMEM;
+		goto mode_sysfs_add_cpu_exit;
+	}
+
+	for (i = 0; i < MSM_PM_SLEEP_MODE_NR; i++) {
+		int idx = MSM_PM_MODE(cpu, i);
+
+		if ((!msm_pm_modes[idx].suspend_supported) &&
+				(!msm_pm_modes[idx].idle_supported))
+			continue;
+
+		mode = kzalloc(sizeof(*mode), GFP_KERNEL);
+		if (!mode) {
+			pr_err("%s: cannot allocate memory for attributes\n",
+				__func__);
+			ret = -ENOMEM;
+			goto mode_sysfs_add_cpu_exit;
+		}
+
+		mode->kobj = kobject_create_and_add(
+				msm_pm_sleep_mode_labels[i], cpu_kobj);
+		if (!mode->kobj) {
+			pr_err("%s: cannot create kobject\n", __func__);
+			ret = -ENOMEM;
+			goto mode_sysfs_add_cpu_exit;
+		}
+
+		for (k = 0, j = 0; k < MSM_PM_MODE_ATTR_NR; k++) {
+			if ((k == MSM_PM_MODE_ATTR_IDLE) &&
+				!msm_pm_modes[idx].idle_supported)
+				continue;
+			if ((k == MSM_PM_MODE_ATTR_SUSPEND) &&
+			     !msm_pm_modes[idx].suspend_supported)
+				continue;
+			mode->kas[j].cpu = cpu;
+			mode->kas[j].ka.attr.mode = 0644;
+			mode->kas[j].ka.show = msm_pm_mode_attr_show;
+			mode->kas[j].ka.store = msm_pm_mode_attr_store;
+			mode->kas[j].ka.attr.name = msm_pm_mode_attr_labels[k];
+			mode->attrs[j] = &mode->kas[j].ka.attr;
+			j++;
+		}
+		mode->attrs[j] = NULL;
+
+		mode->attr_group.attrs = mode->attrs;
+		ret = sysfs_create_group(mode->kobj, &mode->attr_group);
+		if (ret) {
+			printk(KERN_ERR
+				"%s: cannot create kobject attribute group\n",
+				__func__);
+			goto mode_sysfs_add_cpu_exit;
+		}
+	}
+
+	ret = 0;
+
+mode_sysfs_add_cpu_exit:
+	if (ret) {
+		if (mode && mode->kobj)
+			kobject_del(mode->kobj);
+		kfree(mode);
+	}
+
+	return ret;
+}
+
 /*
  * Add sysfs entries for the sleep modes.
  */
@@ -269,13 +359,7 @@
 {
 	struct kobject *module_kobj = NULL;
 	struct kobject *modes_kobj = NULL;
-
-	struct kobject *kobj;
-	struct attribute_group *attr_group;
-	struct attribute **attrs;
-	struct kobj_attribute *kobj_attrs;
-
-	int i, j, k;
+	unsigned int cpu;
 	int ret;
 
 	module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
@@ -283,98 +367,32 @@
 		printk(KERN_ERR "%s: cannot find kobject for module %s\n",
 			__func__, KBUILD_MODNAME);
 		ret = -ENOENT;
-		goto mode_sysfs_add_cleanup;
+		goto mode_sysfs_add_exit;
 	}
 
 	modes_kobj = kobject_create_and_add("modes", module_kobj);
 	if (!modes_kobj) {
 		printk(KERN_ERR "%s: cannot create modes kobject\n", __func__);
 		ret = -ENOMEM;
-		goto mode_sysfs_add_cleanup;
+		goto mode_sysfs_add_exit;
 	}
 
-	for (i = 0; i < ARRAY_SIZE(msm_pm_mode_kobjs); i++) {
-		if (!msm_pm_modes[i].suspend_supported &&
-				!msm_pm_modes[i].idle_supported)
-			continue;
-
-		kobj = kobject_create_and_add(
-				msm_pm_sleep_mode_labels[i], modes_kobj);
-		attr_group = kzalloc(sizeof(*attr_group), GFP_KERNEL);
-		attrs = kzalloc(sizeof(*attrs) * (MSM_PM_MODE_ATTR_NR + 1),
-				GFP_KERNEL);
-		kobj_attrs = kzalloc(sizeof(*kobj_attrs) * MSM_PM_MODE_ATTR_NR,
-				GFP_KERNEL);
-
-		if (!kobj || !attr_group || !attrs || !kobj_attrs) {
-			printk(KERN_ERR
-				"%s: cannot create kobject or attributes\n",
-				__func__);
-			ret = -ENOMEM;
-			goto mode_sysfs_add_abort;
-		}
-
-		for (k = 0, j = 0; k < MSM_PM_MODE_ATTR_NR; k++) {
-			if ((k == MSM_PM_MODE_ATTR_SUSPEND) &&
-				(!msm_pm_modes[i].suspend_supported))
-				continue;
-			if ((k == MSM_PM_MODE_ATTR_IDLE) &&
-				(!msm_pm_modes[i].idle_supported))
-				continue;
-
-			kobj_attrs[j].attr.mode = 0644;
-			kobj_attrs[j].show = msm_pm_mode_attr_show;
-			kobj_attrs[j].store = msm_pm_mode_attr_store;
-			kobj_attrs[j].attr.name = msm_pm_mode_attr_labels[k];
-			attrs[j] = &kobj_attrs[j].attr;
-			j++;
-		}
-		attrs[j] = NULL;
-
-		attr_group->attrs = attrs;
-		ret = sysfs_create_group(kobj, attr_group);
-		if (ret) {
-			printk(KERN_ERR
-				"%s: cannot create kobject attribute group\n",
-				__func__);
-			goto mode_sysfs_add_abort;
-		}
-
-		msm_pm_mode_kobjs[i] = kobj;
-		msm_pm_mode_attr_group[i] = attr_group;
-		msm_pm_mode_attrs[i] = attrs;
-		msm_pm_mode_kobj_attrs[i] = kobj_attrs;
+	for_each_possible_cpu(cpu) {
+		ret = msm_pm_mode_sysfs_add_cpu(cpu, modes_kobj);
+		if (ret)
+			goto mode_sysfs_add_exit;
 	}
 
-	return 0;
+	ret = 0;
 
-mode_sysfs_add_abort:
-	kfree(kobj_attrs);
-	kfree(attrs);
-	kfree(attr_group);
-	kobject_put(kobj);
-
-mode_sysfs_add_cleanup:
-	for (i = ARRAY_SIZE(msm_pm_mode_kobjs) - 1; i >= 0; i--) {
-		if (!msm_pm_mode_kobjs[i])
-			continue;
-
-		sysfs_remove_group(
-			msm_pm_mode_kobjs[i], msm_pm_mode_attr_group[i]);
-
-		kfree(msm_pm_mode_kobj_attrs[i]);
-		kfree(msm_pm_mode_attrs[i]);
-		kfree(msm_pm_mode_attr_group[i]);
-		kobject_put(msm_pm_mode_kobjs[i]);
-	}
-
+mode_sysfs_add_exit:
 	return ret;
 }
 
 void __init msm_pm_set_platform_data(
 	struct msm_pm_platform_data *data, int count)
 {
-	BUG_ON(MSM_PM_SLEEP_MODE_NR != count);
+	BUG_ON(MSM_PM_SLEEP_MODE_NR * num_possible_cpus() > count);
 	msm_pm_modes = data;
 }
 
@@ -674,7 +692,7 @@
 	MSM_PM_STAT_COUNT
 };
 
-static struct msm_pm_time_stats {
+struct msm_pm_time_stats {
 	const char *name;
 	int64_t first_bucket_time;
 	int bucket[CONFIG_MSM_IDLE_STATS_BUCKET_COUNT];
@@ -682,74 +700,37 @@
 	int64_t max_time[CONFIG_MSM_IDLE_STATS_BUCKET_COUNT];
 	int count;
 	int64_t total_time;
-} msm_pm_stats[MSM_PM_STAT_COUNT] = {
-	[MSM_PM_STAT_REQUESTED_IDLE].name = "idle-request",
-	[MSM_PM_STAT_REQUESTED_IDLE].first_bucket_time =
-		CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
-	[MSM_PM_STAT_IDLE_SPIN].name = "idle-spin",
-	[MSM_PM_STAT_IDLE_SPIN].first_bucket_time =
-		CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
-	[MSM_PM_STAT_IDLE_WFI].name = "idle-wfi",
-	[MSM_PM_STAT_IDLE_WFI].first_bucket_time =
-		CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
-	[MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE].name =
-		"idle-standalone-power-collapse",
-	[MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE].first_bucket_time =
-		CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
-	[MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE].name =
-		"idle-failed-standalone-power-collapse",
-	[MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE].first_bucket_time =
-		CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
-	[MSM_PM_STAT_IDLE_SLEEP].name = "idle-sleep",
-	[MSM_PM_STAT_IDLE_SLEEP].first_bucket_time =
-		CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
-	[MSM_PM_STAT_IDLE_FAILED_SLEEP].name = "idle-failed-sleep",
-	[MSM_PM_STAT_IDLE_FAILED_SLEEP].first_bucket_time =
-		CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
-	[MSM_PM_STAT_IDLE_POWER_COLLAPSE].name = "idle-power-collapse",
-	[MSM_PM_STAT_IDLE_POWER_COLLAPSE].first_bucket_time =
-		CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
-	[MSM_PM_STAT_IDLE_FAILED_POWER_COLLAPSE].name =
-		"idle-failed-power-collapse",
-	[MSM_PM_STAT_IDLE_FAILED_POWER_COLLAPSE].first_bucket_time =
-		CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
-	[MSM_PM_STAT_SUSPEND].name = "suspend",
-	[MSM_PM_STAT_SUSPEND].first_bucket_time =
-		CONFIG_MSM_SUSPEND_STATS_FIRST_BUCKET,
-
-	[MSM_PM_STAT_FAILED_SUSPEND].name = "failed-suspend",
-	[MSM_PM_STAT_FAILED_SUSPEND].first_bucket_time =
-		CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
-
-	[MSM_PM_STAT_NOT_IDLE].name = "not-idle",
-	[MSM_PM_STAT_NOT_IDLE].first_bucket_time =
-		CONFIG_MSM_IDLE_STATS_FIRST_BUCKET,
 };
 
+struct msm_pm_cpu_time_stats {
+	struct msm_pm_time_stats stats[MSM_PM_STAT_COUNT];
+};
+
+static DEFINE_PER_CPU_SHARED_ALIGNED(
+		struct msm_pm_cpu_time_stats, msm_pm_stats);
+
 static uint32_t msm_pm_sleep_limit = SLEEP_LIMIT_NONE;
 
+static DEFINE_SPINLOCK(msm_pm_stats_lock);
+
 /*
  * Add the given time data to the statistics collection.
  */
 static void msm_pm_add_stat(enum msm_pm_time_stats_id id, int64_t t)
 {
+	unsigned long flags;
+	struct msm_pm_time_stats *stats;
 	int i;
 	int64_t bt;
 
-	msm_pm_stats[id].total_time += t;
-	msm_pm_stats[id].count++;
+	spin_lock_irqsave(&msm_pm_stats_lock, flags);
+	stats = __get_cpu_var(msm_pm_stats).stats;
+
+	stats[id].total_time += t;
+	stats[id].count++;
 
 	bt = t;
-	do_div(bt, msm_pm_stats[id].first_bucket_time);
+	do_div(bt, stats[id].first_bucket_time);
 
 	if (bt < 1ULL << (CONFIG_MSM_IDLE_STATS_BUCKET_SHIFT *
 				(CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1)))
@@ -758,12 +739,17 @@
 	else
 		i = CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1;
 
-	msm_pm_stats[id].bucket[i]++;
+	if (i >= CONFIG_MSM_IDLE_STATS_BUCKET_COUNT)
+		i = CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1;
 
-	if (t < msm_pm_stats[id].min_time[i] || !msm_pm_stats[id].max_time[i])
-		msm_pm_stats[id].min_time[i] = t;
-	if (t > msm_pm_stats[id].max_time[i])
-		msm_pm_stats[id].max_time[i] = t;
+	stats[id].bucket[i]++;
+
+	if (t < stats[id].min_time[i] || !stats[id].max_time[i])
+		stats[id].min_time[i] = t;
+	if (t > stats[id].max_time[i])
+		stats[id].max_time[i] = t;
+
+	spin_unlock_irqrestore(&msm_pm_stats_lock, flags);
 }
 
 /*
@@ -793,7 +779,8 @@
 static int msm_pm_read_proc
 	(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
-	int i;
+	unsigned int cpu = off / MSM_PM_STAT_COUNT;
+	int id = off % MSM_PM_STAT_COUNT;
 	char *p = page;
 
 	if (count < 1024) {
@@ -809,44 +796,51 @@
 			SNPRINTF(p, count, "for TCXO shutdown\n\n");
 		else
 			SNPRINTF(p, count, "against TCXO shutdown\n\n");
+	}
 
-		*start = (char *) 1;
-		*eof = 0;
-	} else if (--off < ARRAY_SIZE(msm_pm_stats)) {
+	if (cpu < num_possible_cpus()) {
+		unsigned long flags;
+		struct msm_pm_time_stats *stats;
+		int i;
 		int64_t bucket_time;
 		int64_t s;
 		uint32_t ns;
 
-		s = msm_pm_stats[off].total_time;
+		spin_lock_irqsave(&msm_pm_stats_lock, flags);
+		stats = per_cpu(msm_pm_stats, cpu).stats;
+
+		s = stats[id].total_time;
 		ns = do_div(s, NSEC_PER_SEC);
 		SNPRINTF(p, count,
-			"%s:\n"
+			"[cpu %u] %s:\n"
 			"  count: %7d\n"
 			"  total_time: %lld.%09u\n",
-			msm_pm_stats[off].name,
-			msm_pm_stats[off].count,
+			cpu, stats[id].name,
+			stats[id].count,
 			s, ns);
 
-		bucket_time = msm_pm_stats[off].first_bucket_time;
+		bucket_time = stats[id].first_bucket_time;
 		for (i = 0; i < CONFIG_MSM_IDLE_STATS_BUCKET_COUNT - 1; i++) {
 			s = bucket_time;
 			ns = do_div(s, NSEC_PER_SEC);
 			SNPRINTF(p, count,
 				"   <%6lld.%09u: %7d (%lld-%lld)\n",
-				s, ns, msm_pm_stats[off].bucket[i],
-				msm_pm_stats[off].min_time[i],
-				msm_pm_stats[off].max_time[i]);
+				s, ns, stats[id].bucket[i],
+				stats[id].min_time[i],
+				stats[id].max_time[i]);
 
 			bucket_time <<= CONFIG_MSM_IDLE_STATS_BUCKET_SHIFT;
 		}
 
 		SNPRINTF(p, count, "  >=%6lld.%09u: %7d (%lld-%lld)\n",
-			s, ns, msm_pm_stats[off].bucket[i],
-			msm_pm_stats[off].min_time[i],
-			msm_pm_stats[off].max_time[i]);
+			s, ns, stats[id].bucket[i],
+			stats[id].min_time[i],
+			stats[id].max_time[i]);
 
 		*start = (char *) 1;
-		*eof = (off + 1 >= ARRAY_SIZE(msm_pm_stats));
+		*eof = (off + 1 >= MSM_PM_STAT_COUNT * num_possible_cpus());
+
+		spin_unlock_irqrestore(&msm_pm_stats_lock, flags);
 	}
 
 	return p - page;
@@ -864,7 +858,7 @@
 	char buf[sizeof(MSM_PM_STATS_RESET)];
 	int ret;
 	unsigned long flags;
-	int i;
+	unsigned int cpu;
 
 	if (count < strlen(MSM_PM_STATS_RESET)) {
 		ret = -EINVAL;
@@ -881,26 +875,32 @@
 		goto write_proc_failed;
 	}
 
-	local_irq_save(flags);
-	for (i = 0; i < ARRAY_SIZE(msm_pm_stats); i++) {
-		memset(msm_pm_stats[i].bucket,
-			0, sizeof(msm_pm_stats[i].bucket));
-		memset(msm_pm_stats[i].min_time,
-			0, sizeof(msm_pm_stats[i].min_time));
-		memset(msm_pm_stats[i].max_time,
-			0, sizeof(msm_pm_stats[i].max_time));
-		msm_pm_stats[i].count = 0;
-		msm_pm_stats[i].total_time = 0;
-	}
+	spin_lock_irqsave(&msm_pm_stats_lock, flags);
+	for_each_possible_cpu(cpu) {
+		struct msm_pm_time_stats *stats;
+		int i;
 
+		stats = per_cpu(msm_pm_stats, cpu).stats;
+		for (i = 0; i < MSM_PM_STAT_COUNT; i++) {
+			memset(stats[i].bucket,
+				0, sizeof(stats[i].bucket));
+			memset(stats[i].min_time,
+				0, sizeof(stats[i].min_time));
+			memset(stats[i].max_time,
+				0, sizeof(stats[i].max_time));
+			stats[i].count = 0;
+			stats[i].total_time = 0;
+		}
+	}
 	msm_pm_sleep_limit = SLEEP_LIMIT_NONE;
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&msm_pm_stats_lock, flags);
 
 	return count;
 
 write_proc_failed:
 	return ret;
 }
+
 #undef MSM_PM_STATS_RESET
 #endif /* CONFIG_MSM_IDLE_STATS */
 
@@ -1389,16 +1389,19 @@
 	int low_power;
 	int ret;
 	int i;
+	unsigned int cpu;
 
 #ifdef CONFIG_MSM_IDLE_STATS
 	int64_t t1;
 	static int64_t t2;
 	int exit_stat;
-#endif /* CONFIG_MSM_IDLE_STATS */
+ #endif /* CONFIG_MSM_IDLE_STATS */
 
 	if (!atomic_read(&msm_pm_init_done))
 		return;
 
+	cpu = smp_processor_id();
+
 	latency_qos = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
 	timer_expiration = msm_timer_enter_idle();
 
@@ -1406,39 +1409,14 @@
 	t1 = ktime_to_ns(ktime_get());
 	msm_pm_add_stat(MSM_PM_STAT_NOT_IDLE, t1 - t2);
 	msm_pm_add_stat(MSM_PM_STAT_REQUESTED_IDLE, timer_expiration);
+
+	exit_stat = MSM_PM_STAT_IDLE_SPIN;
+	low_power = 0;
 #endif /* CONFIG_MSM_IDLE_STATS */
 
 	for (i = 0; i < ARRAY_SIZE(allow); i++)
 		allow[i] = true;
 
-	switch (msm_pm_idle_sleep_mode) {
-	case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
-		allow[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] =
-			false;
-		/* fall through */
-	case MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT:
-		allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE] = false;
-		/* fall through */
-	case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE:
-		allow[MSM_PM_SLEEP_MODE_APPS_SLEEP] = false;
-		/* fall through */
-	case MSM_PM_SLEEP_MODE_APPS_SLEEP:
-		allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = false;
-		allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = false;
-		/* fall through */
-	case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_SUSPEND:
-	case MSM_PM_SLEEP_MODE_POWER_COLLAPSE:
-		break;
-	default:
-		printk(KERN_ERR "idle sleep mode is invalid: %d\n",
-			msm_pm_idle_sleep_mode);
-#ifdef CONFIG_MSM_IDLE_STATS
-		exit_stat = MSM_PM_STAT_IDLE_SPIN;
-#endif /* CONFIG_MSM_IDLE_STATS */
-		low_power = 0;
-		goto arch_idle_exit;
-	}
-
 	if ((timer_expiration < msm_pm_idle_sleep_min_time) ||
 #ifdef CONFIG_HAS_WAKELOCK
 		has_wake_lock(WAKE_LOCK_IDLE) ||
@@ -1450,7 +1428,8 @@
 	}
 
 	for (i = 0; i < ARRAY_SIZE(allow); i++) {
-		struct msm_pm_platform_data *mode = &msm_pm_modes[i];
+		struct msm_pm_platform_data *mode =
+					&msm_pm_modes[MSM_PM_MODE(cpu, i)];
 		if (!mode->idle_supported || !mode->idle_enabled ||
 			mode->latency >= latency_qos ||
 			mode->residency * 1000ULL >= timer_expiration)
@@ -1564,7 +1543,6 @@
 #endif /* CONFIG_MSM_IDLE_STATS */
 	}
 
-arch_idle_exit:
 	msm_timer_exit_idle(low_power);
 
 #ifdef CONFIG_MSM_IDLE_STATS
@@ -1604,32 +1582,9 @@
 	for (i = 0; i < ARRAY_SIZE(allow); i++)
 		allow[i] = true;
 
-	switch (msm_pm_sleep_mode) {
-	case MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT:
-		allow[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] =
-			false;
-		/* fall through */
-	case MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT:
-		allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE] = false;
-		/* fall through */
-	case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE:
-		allow[MSM_PM_SLEEP_MODE_APPS_SLEEP] = false;
-		/* fall through */
-	case MSM_PM_SLEEP_MODE_APPS_SLEEP:
-		allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = false;
-		allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = false;
-		/* fall through */
-	case MSM_PM_SLEEP_MODE_POWER_COLLAPSE_SUSPEND:
-	case MSM_PM_SLEEP_MODE_POWER_COLLAPSE:
-		break;
-	default:
-		printk(KERN_ERR "suspend sleep mode is invalid: %d\n",
-			msm_pm_sleep_mode);
-		return -EINVAL;
-	}
-
 	for (i = 0; i < ARRAY_SIZE(allow); i++) {
-		struct msm_pm_platform_data *mode = &msm_pm_modes[i];
+		struct msm_pm_platform_data *mode;
+		mode = &msm_pm_modes[MSM_PM_MODE(0, i)];
 		if (!mode->suspend_supported || !mode->suspend_enabled)
 			allow[i] = false;
 	}
@@ -1778,6 +1733,7 @@
 {
 #ifdef CONFIG_MSM_IDLE_STATS
 	struct proc_dir_entry *d_entry;
+	unsigned int cpu;
 #endif
 	int ret;
 #ifdef CONFIG_CPU_V7
@@ -1846,6 +1802,66 @@
 
 	msm_pm_mode_sysfs_add();
 #ifdef CONFIG_MSM_IDLE_STATS
+	for_each_possible_cpu(cpu) {
+		struct msm_pm_time_stats *stats =
+			per_cpu(msm_pm_stats, cpu).stats;
+
+		stats[MSM_PM_STAT_REQUESTED_IDLE].name = "idle-request";
+		stats[MSM_PM_STAT_REQUESTED_IDLE].first_bucket_time =
+			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+		stats[MSM_PM_STAT_IDLE_SPIN].name = "idle-spin";
+		stats[MSM_PM_STAT_IDLE_SPIN].first_bucket_time =
+			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+		stats[MSM_PM_STAT_IDLE_WFI].name = "idle-wfi";
+		stats[MSM_PM_STAT_IDLE_WFI].first_bucket_time =
+			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+		stats[MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE].name =
+			"idle-standalone-power-collapse";
+		stats[MSM_PM_STAT_IDLE_STANDALONE_POWER_COLLAPSE].
+			first_bucket_time =
+			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+		stats[MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE].name =
+			"idle-failed-standalone-power-collapse";
+		stats[MSM_PM_STAT_IDLE_FAILED_STANDALONE_POWER_COLLAPSE].
+			first_bucket_time =
+			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+		stats[MSM_PM_STAT_IDLE_SLEEP].name = "idle-sleep";
+		stats[MSM_PM_STAT_IDLE_SLEEP].first_bucket_time =
+			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+		stats[MSM_PM_STAT_IDLE_FAILED_SLEEP].name =
+			"idle-failed-sleep";
+		stats[MSM_PM_STAT_IDLE_FAILED_SLEEP].first_bucket_time =
+			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+		stats[MSM_PM_STAT_IDLE_POWER_COLLAPSE].name =
+			"idle-power-collapse";
+		stats[MSM_PM_STAT_IDLE_POWER_COLLAPSE].first_bucket_time =
+			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+		stats[MSM_PM_STAT_IDLE_FAILED_POWER_COLLAPSE].name =
+			"idle-failed-power-collapse";
+		stats[MSM_PM_STAT_IDLE_FAILED_POWER_COLLAPSE].
+			first_bucket_time =
+			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+		stats[MSM_PM_STAT_SUSPEND].name = "suspend";
+		stats[MSM_PM_STAT_SUSPEND].first_bucket_time =
+			CONFIG_MSM_SUSPEND_STATS_FIRST_BUCKET;
+
+		stats[MSM_PM_STAT_FAILED_SUSPEND].name = "failed-suspend";
+		stats[MSM_PM_STAT_FAILED_SUSPEND].first_bucket_time =
+			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+
+		stats[MSM_PM_STAT_NOT_IDLE].name = "not-idle";
+		stats[MSM_PM_STAT_NOT_IDLE].first_bucket_time =
+			CONFIG_MSM_IDLE_STATS_FIRST_BUCKET;
+	}
 	d_entry = create_proc_entry("msm_pm_stats",
 			S_IRUGO | S_IWUSR | S_IWGRP, NULL);
 	if (d_entry) {
diff --git a/arch/arm/mach-msm/qdss-ptm.c b/arch/arm/mach-msm/qdss-ptm.c
index 96a727a..c0dc58e 100644
--- a/arch/arm/mach-msm/qdss-ptm.c
+++ b/arch/arm/mach-msm/qdss-ptm.c
@@ -67,9 +67,9 @@
 #define ETMSQ12EVR		(0x180)
 #define ETMSQ21EVR		(0x184)
 #define ETMSQ23EVR		(0x188)
-#define ETMSQ32EVR		(0x18C)
-#define ETMSQ13EVR		(0x190)
-#define ETMSQ31EVR		(0x194)
+#define ETMSQ31EVR		(0x18C)
+#define ETMSQ32EVR		(0x190)
+#define ETMSQ13EVR		(0x194)
 #define ETMSQR			(0x19C)
 #define ETMEXTOUTEVRn(n)	(0x1A0 + (n * 4))
 #define ETMCIDCVRn(n)		(0x1B0 + (n * 4))
@@ -91,7 +91,7 @@
 #define ETMTSEVR		(0x1F8)
 #define ETMAUXCR		(0x1FC)
 #define ETMTRACEIDR		(0x200)
-#define ETMVMIDCVR		(0x204)
+#define ETMVMIDCVR		(0x240)
 /* Management registers (0x300-0x314) */
 #define ETMOSLAR		(0x300)
 #define ETMOSLSR		(0x304)
diff --git a/arch/arm/mach-msm/spm.h b/arch/arm/mach-msm/spm.h
index 78fd922..b155781 100644
--- a/arch/arm/mach-msm/spm.h
+++ b/arch/arm/mach-msm/spm.h
@@ -65,12 +65,7 @@
 #elif defined(CONFIG_MSM_SPM_V2)
 
 enum {
-	MSM_SPM_REG_SAW2_SECURE,
-	MSM_SPM_REG_SAW2_ID,
 	MSM_SPM_REG_SAW2_CFG,
-	MSM_SPM_REG_SAW2_STS0,
-	MSM_SPM_REG_SAW2_STS1,
-	MSM_SPM_REG_SAW2_VCTL,
 	MSM_SPM_REG_SAW2_AVS_CTL,
 	MSM_SPM_REG_SAW2_AVS_HYSTERESIS,
 	MSM_SPM_REG_SAW2_SPM_CTL,
@@ -79,8 +74,13 @@
 	MSM_SPM_REG_SAW2_PMIC_DATA_1,
 	MSM_SPM_REG_SAW2_RST,
 
-	MSM_SPM_REG_NR_INITIALIZE,
-	MSM_SPM_REG_SAW2_SEQ_ENTRY = MSM_SPM_REG_NR_INITIALIZE,
+	MSM_SPM_REG_NR_INITIALIZE = MSM_SPM_REG_SAW2_RST,
+	MSM_SPM_REG_SAW2_ID,
+	MSM_SPM_REG_SAW2_SECURE,
+	MSM_SPM_REG_SAW2_STS0,
+	MSM_SPM_REG_SAW2_STS1,
+	MSM_SPM_REG_SAW2_VCTL,
+	MSM_SPM_REG_SAW2_SEQ_ENTRY ,
 
 	MSM_SPM_REG_NR
 };
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 5cd1b05..3bce534 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -54,9 +54,15 @@
 	and	r1, r1, #7			@ mask of the bits for current cache only
 	cmp	r1, #2				@ see what cache we have at this level
 	blt	skip				@ skip if no cache, or just i-cache
+#ifdef CONFIG_PREEMPT
+	save_and_disable_irqs r9		@ make cssr&csidr read atomic
+#endif
 	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level in cssr
 	isb					@ isb to sych the new cssr&csidr
 	mrc	p15, 1, r1, c0, c0, 0		@ read the new csidr
+#ifdef CONFIG_PREEMPT
+	restore_irqs_notrace r9
+#endif
 	and	r2, r1, #7			@ extract the length of the cache lines
 	add	r2, r2, #4			@ add 4 (line length offset)
 	ldr	r4, =0x3ff
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index a9faff0..7d28604 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -128,6 +128,7 @@
 	struct diag_client_map *client_map;
 	int *data_ready;
 	int num_clients;
+	int polling_reg_flag;
 	struct diag_write_device *buf_tbl;
 
 	/* Memory pool parameters */
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index a703148..e24d896 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -60,8 +60,8 @@
 static unsigned int max_clients = 15;
 static unsigned int threshold_client_limit = 30;
 /* This is the maximum number of pkt registrations supported at initialization*/
-unsigned int diag_max_registration = 500;
-unsigned int diag_threshold_registration = 650;
+unsigned int diag_max_registration = 600;
+unsigned int diag_threshold_registration = 750;
 
 /* Timer variables */
 static struct timer_list drain_timer;
@@ -256,15 +256,49 @@
 	return -ENOMEM;
 }
 
+int diag_find_polling_reg(int i)
+{
+	uint16_t subsys_id, cmd_code_lo, cmd_code_hi;
+
+	subsys_id = driver->table[i].subsys_id;
+	cmd_code_lo = driver->table[i].cmd_code_lo;
+	cmd_code_hi = driver->table[i].cmd_code_hi;
+	if (driver->table[i].cmd_code == 0x0C)
+		return 1;
+	else if (driver->table[i].cmd_code == 0xFF) {
+		if (subsys_id == 0x04 && cmd_code_hi == 0x0E &&
+			 cmd_code_lo == 0x0E)
+			return 1;
+		else if (subsys_id == 0x08 && cmd_code_hi == 0x02 &&
+			 cmd_code_lo == 0x02)
+			return 1;
+		else if (subsys_id == 0x32 && cmd_code_hi == 0x03  &&
+			 cmd_code_lo == 0x03)
+			return 1;
+	}
+	return 0;
+}
+
 void diag_clear_reg(int proc_num)
 {
 	int i;
 
+	mutex_lock(&driver->diagchar_mutex);
+	/* reset polling flag */
+	driver->polling_reg_flag = 0;
 	for (i = 0; i < diag_max_registration; i++) {
 		if (driver->table[i].client_id == proc_num) {
 			driver->table[i].process_id = 0;
 		}
 	}
+	/* re-scan the registration table */
+	for (i = 0; i < diag_max_registration; i++) {
+		if (diag_find_polling_reg(i) == 1) {
+			driver->polling_reg_flag = 1;
+			break;
+		}
+	}
+	mutex_unlock(&driver->diagchar_mutex);
 }
 
 void diag_add_reg(int j, struct bindpkt_params *params,
@@ -275,6 +309,11 @@
 	driver->table[j].subsys_id = params->subsys_id;
 	driver->table[j].cmd_code_lo = params->cmd_code_lo;
 	driver->table[j].cmd_code_hi = params->cmd_code_hi;
+
+	/* check if incoming reg is polling & polling is yet not registered */
+	if (driver->polling_reg_flag == 0)
+		if (diag_find_polling_reg(j) == 1)
+			driver->polling_reg_flag = 1;
 	if (params->proc_id == APPS_PROC) {
 		driver->table[j].process_id = current->tgid;
 		driver->table[j].client_id = APPS_PROC;
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 07322cd..5838bba 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -891,8 +891,8 @@
 	/* Check for polling for Apps only DIAG */
 	else if ((*buf == 0x4b) && (*(buf+1) == 0x32) &&
 		(*(buf+2) == 0x03)) {
-		/* If there is NO MODEM present */
-		if (!(driver->ch)) {
+		/* If no one has registered for polling */
+		if (!(driver->polling_reg_flag)) {
 			/* Respond to polling for Apps only DIAG */
 			for (i = 0; i < 3; i++)
 				driver->apps_rsp_buf[i] = *(buf+i);
@@ -901,13 +901,10 @@
 
 			ENCODE_RSP_AND_SEND(15);
 			return 0;
-		} else {
-			/* Since Modem is present, send error response */
-			return 1;
 		}
 	}
 	 /* Check for ID for NO MODEM present */
-	else if (!(driver->ch)) {
+	else if (!(driver->polling_reg_flag)) {
 		/* respond to 0x0 command */
 		if (*buf == 0x00) {
 			for (i = 0; i < 55; i++)
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index df2cd65..22a2ccb 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -192,6 +192,7 @@
 
 void diagfwd_cntl_init(void)
 {
+	driver->polling_reg_flag = 0;
 	if (driver->buf_in_cntl == NULL) {
 		driver->buf_in_cntl = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
 		if (driver->buf_in_cntl == NULL)
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 9cbebbe..06f4a14 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -834,7 +834,11 @@
 	unsigned int rbbm_status;
 	unsigned long wait_timeout =
 		msecs_to_jiffies(adreno_dev->wait_timeout);
-	unsigned long wait_time = jiffies + wait_timeout;
+	unsigned long wait_time;
+	unsigned long wait_time_part;
+	unsigned int msecs;
+	unsigned int msecs_first;
+	unsigned int msecs_part;
 
 	kgsl_cffdump_regpoll(device->id,
 		adreno_dev->gpudev->reg_rbbm_status << 2,
@@ -844,8 +848,18 @@
 	 */
 retry:
 	if (rb->flags & KGSL_FLAGS_STARTED) {
+		msecs = adreno_dev->wait_timeout;
+		msecs_first = (msecs <= 100) ? ((msecs + 4) / 5) : 100;
+		msecs_part = (msecs - msecs_first + 3) / 4;
+		wait_time = jiffies + wait_timeout;
+		wait_time_part = jiffies + msecs_to_jiffies(msecs_first);
 		adreno_poke(device);
 		do {
+			if (time_after(jiffies, wait_time_part)) {
+				adreno_poke(device);
+				wait_time_part = jiffies +
+					msecs_to_jiffies(msecs_part);
+			}
 			GSL_RB_GET_READPTR(rb, &rb->rptr);
 			if (time_after(jiffies, wait_time)) {
 				KGSL_DRV_ERR(device, "rptr: %x, wptr: %x\n",
@@ -1146,57 +1160,56 @@
 	msecs_first = (msecs <= 100) ? ((msecs + 4) / 5) : 100;
 	msecs_part = (msecs - msecs_first + 3) / 4;
 	for (retries = 0; retries < 5; retries++) {
-		if (!kgsl_check_timestamp(device, timestamp)) {
-			adreno_poke(device);
-			io_cnt = (io_cnt + 1) % 100;
-			if (io_cnt <
-				pwr->pwrlevels[pwr->active_pwrlevel].
-					io_fraction)
-				io = 0;
-			mutex_unlock(&device->mutex);
-			/* We need to make sure that the process is
-			 * placed in wait-q before its condition is called
+		if (kgsl_check_timestamp(device, timestamp)) {
+			/* if the timestamp happens while we're not
+			 * waiting, there's a chance that an interrupt
+			 * will not be generated and thus the timestamp
+			 * work needs to be queued.
 			 */
-			status = kgsl_wait_event_interruptible_timeout(
-					device->wait_queue,
-					kgsl_check_interrupt_timestamp(device,
-						timestamp),
-					msecs_to_jiffies(retries ?
-						msecs_part : msecs_first), io);
-			mutex_lock(&device->mutex);
-
-			if (status > 0) {
-				/*completed before the wait finished */
-				status = 0;
-				goto done;
-			} else if (status < 0) {
-				/*an error occurred*/
-				goto done;
-			}
-			/*this wait timed out*/
+			queue_work(device->work_queue, &device->ts_expired_ws);
+			status = 0;
+			goto done;
 		}
-	}
-	if (!kgsl_check_timestamp(device, timestamp)) {
-		status = -ETIMEDOUT;
-		KGSL_DRV_ERR(device,
-			"Device hang detected while waiting "
-			"for timestamp: %x, last "
-			"submitted(rb->timestamp): %x, wptr: "
-			"%x\n", timestamp,
-			adreno_dev->ringbuffer.timestamp,
-			adreno_dev->ringbuffer.wptr);
-		if (!adreno_dump_and_recover(device)) {
-			/* wait for idle after recovery as the
-			 * timestamp that this process wanted
-			 * to wait on may be invalid */
-			if (!adreno_idle(device,
-				KGSL_TIMEOUT_DEFAULT))
-				status = 0;
-		}
-	} else {
-		status = 0;
-	}
+		adreno_poke(device);
+		io_cnt = (io_cnt + 1) % 100;
+		if (io_cnt <
+		    pwr->pwrlevels[pwr->active_pwrlevel].io_fraction)
+			io = 0;
+		mutex_unlock(&device->mutex);
+		/* We need to make sure that the process is
+		 * placed in wait-q before its condition is called
+		 */
+		status = kgsl_wait_event_interruptible_timeout(
+				device->wait_queue,
+				kgsl_check_interrupt_timestamp(device,
+					timestamp),
+				msecs_to_jiffies(retries ?
+					msecs_part : msecs_first), io);
+		mutex_lock(&device->mutex);
 
+		if (status > 0) {
+			/*completed before the wait finished */
+			status = 0;
+			goto done;
+		} else if (status < 0) {
+			/*an error occurred*/
+			goto done;
+		}
+		/*this wait timed out*/
+	}
+	status = -ETIMEDOUT;
+	KGSL_DRV_ERR(device,
+		     "Device hang detected while waiting for timestamp: %x,"
+		      "last submitted(rb->timestamp): %x, wptr: %x\n",
+		      timestamp, adreno_dev->ringbuffer.timestamp,
+		      adreno_dev->ringbuffer.wptr);
+	if (!adreno_dump_and_recover(device)) {
+		/* wait for idle after recovery as the
+		 * timestamp that this process wanted
+		 * to wait on may be invalid */
+		if (!adreno_idle(device, KGSL_TIMEOUT_DEFAULT))
+			status = 0;
+	}
 done:
 	return (int)status;
 }
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 512a262..1a0a17d 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -102,6 +102,7 @@
 	if (n == &device->events)
 		list_add_tail(&event->list, &device->events);
 
+	queue_work(device->work_queue, &device->ts_expired_ws);
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 1ef71a4..ae50183 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -66,8 +66,17 @@
 		struct kgsl_pwrlevel *pwrlevel = &pwr->pwrlevels[new_level];
 		pwr->active_pwrlevel = new_level;
 		if ((test_bit(KGSL_PWRFLAGS_CLK_ON, &pwr->power_flags)) ||
-			(device->state == KGSL_STATE_NAP))
+			(device->state == KGSL_STATE_NAP)) {
+			/*
+			 * On some platforms, instability is caused on
+			 * changing clock freq when the core is busy.
+			 * Idle the gpu core before changing the clock freq.
+			 */
+			if (pwr->idle_needed == true)
+				device->ftbl->idle(device,
+						KGSL_TIMEOUT_DEFAULT);
 			clk_set_rate(pwr->grp_clks[0], pwrlevel->gpu_freq);
+		}
 		if (test_bit(KGSL_PWRFLAGS_AXI_ON, &pwr->power_flags)) {
 			if (pwr->pcl)
 				msm_bus_scale_client_update_request(pwr->pcl,
@@ -499,6 +508,7 @@
 	pwr->power_flags = 0;
 
 	pwr->nap_allowed = pdata->nap_allowed;
+	pwr->idle_needed = pdata->idle_needed;
 	pwr->interval_timeout = pdata->idle_timeout;
 	pwr->ebi1_clk = clk_get(&pdev->dev, "bus_clk");
 	if (IS_ERR(pwr->ebi1_clk))
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index 23e2bd1..99dbae9 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -50,6 +50,7 @@
 	struct regulator *gpu_reg;
 	uint32_t pcl;
 	unsigned int nap_allowed;
+	unsigned int idle_needed;
 	const char *regulator_name;
 	const char *irq_name;
 	s64 time;
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index c8b4707..4988313 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -324,13 +324,13 @@
 {
 	dev->clk_state = state;
 	if (state != 0) {
-		clk_prepare_enable(dev->clk);
-		clk_prepare_enable(dev->pclk);
+		clk_enable(dev->clk);
+		clk_enable(dev->pclk);
 	} else {
 		qup_update_state(dev, QUP_RESET_STATE);
-		clk_disable_unprepare(dev->clk);
+		clk_disable(dev->clk);
 		qup_config_core_on_en(dev);
-		clk_disable_unprepare(dev->pclk);
+		clk_disable(dev->pclk);
 	}
 }
 
@@ -1285,6 +1285,8 @@
 	dev->suspended = 0;
 	mutex_init(&dev->mlock);
 	dev->clk_state = 0;
+	clk_prepare(dev->clk);
+	clk_prepare(dev->pclk);
 	setup_timer(&dev->pwr_timer, qup_i2c_pwr_timer, (unsigned long) dev);
 
 	pm_runtime_set_active(&pdev->dev);
@@ -1344,6 +1346,8 @@
 	}
 	free_irq(dev->err_irq, dev);
 	i2c_del_adapter(&dev->adapter);
+	clk_unprepare(dev->clk);
+	clk_unprepare(dev->pclk);
 	clk_put(dev->clk);
 	clk_put(dev->pclk);
 	qup_i2c_free_gpios(dev);
@@ -1378,6 +1382,8 @@
 	del_timer_sync(&dev->pwr_timer);
 	if (dev->clk_state != 0)
 		qup_i2c_pwr_mgmt(dev, 0);
+	clk_unprepare(dev->clk);
+	clk_unprepare(dev->pclk);
 	qup_i2c_free_gpios(dev);
 	return 0;
 }
@@ -1387,6 +1393,8 @@
 	struct platform_device *pdev = to_platform_device(device);
 	struct qup_i2c_dev *dev = platform_get_drvdata(pdev);
 	BUG_ON(qup_i2c_request_gpios(dev) != 0);
+	clk_prepare(dev->clk);
+	clk_prepare(dev->pclk);
 	dev->suspended = 0;
 	return 0;
 }
diff --git a/drivers/input/touchscreen/cyttsp-i2c.c b/drivers/input/touchscreen/cyttsp-i2c.c
index a60dbf5..267e481 100644
--- a/drivers/input/touchscreen/cyttsp-i2c.c
+++ b/drivers/input/touchscreen/cyttsp-i2c.c
@@ -710,25 +710,26 @@
 	else if (!(g_bl_data.bl_status & BL_CHECKSUM_MASK) &&
 			(appid_lo == ts->platform_data->correct_fw_ver))
 		fw_upgrade = 1;
-	else
-		if ((appid_hi == g_bl_data.appid_hi) &&
-			(appid_lo == g_bl_data.appid_lo)) {
-			if (appver_hi > g_bl_data.appver_hi) {
+	else if ((appid_hi == g_bl_data.appid_hi) &&
+			(appid_lo == g_bl_data.appid_lo))
+			if (appver_hi > g_bl_data.appver_hi)
 				fw_upgrade = 1;
-			} else if ((appver_hi == g_bl_data.appver_hi) &&
-					 (appver_lo > g_bl_data.appver_lo)) {
-					fw_upgrade = 1;
-				} else {
-					fw_upgrade = 0;
-					pr_info("%s: Firmware version "
-					"lesser/equal to existing firmware, "
-					"upgrade not needed\n", __func__);
-				}
-		} else {
-			fw_upgrade = 0;
-			pr_info("%s: Firware versions do not match, "
-						"cannot upgrade\n", __func__);
-		}
+			else if ((appver_hi == g_bl_data.appver_hi) &&
+					 (appver_lo > g_bl_data.appver_lo))
+				fw_upgrade = 1;
+			else {
+				fw_upgrade = 0;
+				pr_info("%s: Firmware version "
+				"lesser/equal to existing firmware, "
+				"upgrade not needed\n", __func__);
+			}
+	else if (appid_lo == ts->platform_data->correct_fw_ver)
+		fw_upgrade = 1;
+	else {
+		fw_upgrade = 0;
+		pr_info("%s: Firmware versions do not match, "
+					"cannot upgrade\n", __func__);
+	}
 
 	if (fw_upgrade) {
 		pr_info("%s: Starting firmware upgrade\n", __func__);
diff --git a/drivers/leds/leds-pm8xxx.c b/drivers/leds/leds-pm8xxx.c
index 025b756..46199d8 100644
--- a/drivers/leds/leds-pm8xxx.c
+++ b/drivers/leds/leds-pm8xxx.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
@@ -39,6 +39,46 @@
 #define PM8XXX_DRV_LED_CTRL_MASK	0xf8
 #define PM8XXX_DRV_LED_CTRL_SHIFT	0x03
 
+#define SSBI_REG_ADDR_WLED_CTRL_BASE	0x25A
+#define SSBI_REG_ADDR_WLED_CTRL(n)	(SSBI_REG_ADDR_WLED_CTRL_BASE + (n) - 1)
+
+/* wled control registers */
+#define WLED_MOD_CTRL_REG		SSBI_REG_ADDR_WLED_CTRL(1)
+#define WLED_MAX_CURR_CFG_REG(n)	SSBI_REG_ADDR_WLED_CTRL(n + 2)
+#define WLED_BRIGHTNESS_CNTL_REG1(n)	SSBI_REG_ADDR_WLED_CTRL(n + 5)
+#define WLED_BRIGHTNESS_CNTL_REG2(n)	SSBI_REG_ADDR_WLED_CTRL(n + 6)
+#define WLED_SYNC_REG			SSBI_REG_ADDR_WLED_CTRL(11)
+#define WLED_OVP_CFG_REG		SSBI_REG_ADDR_WLED_CTRL(13)
+#define WLED_BOOST_CFG_REG		SSBI_REG_ADDR_WLED_CTRL(14)
+#define WLED_HIGH_POLE_CAP_REG		SSBI_REG_ADDR_WLED_CTRL(16)
+
+#define WLED_STRINGS			0x03
+#define WLED_OVP_VAL_MASK		0x30
+#define WLED_OVP_VAL_BIT_SHFT		0x04
+#define WLED_BOOST_LIMIT_MASK		0xE0
+#define WLED_BOOST_LIMIT_BIT_SHFT	0x05
+#define WLED_EN_MASK			0x01
+#define WLED_CP_SELECT_MAX		0x03
+#define WLED_CP_SELECT_MASK		0x03
+#define WLED_DIG_MOD_GEN_MASK		0x70
+#define WLED_CS_OUT_MASK		0x0E
+#define WLED_CTL_DLY_STEP		200
+#define WLED_CTL_DLY_MAX		1400
+#define WLED_CTL_DLY_MASK		0xE0
+#define WLED_CTL_DLY_BIT_SHFT		0x05
+#define WLED_MAX_CURR			25
+#define WLED_MAX_CURR_MASK		0x1F
+#define WLED_OP_FDBCK_MASK		0x1C
+#define WLED_OP_FDBCK_BIT_SHFT		0x02
+
+#define WLED_MAX_LEVEL			100
+#define WLED_8_BIT_MASK			0xFF
+#define WLED_8_BIT_SHFT			0x08
+#define WLED_MAX_DUTY_CYCLE		0xFFF
+
+#define WLED_SYNC_VAL			0x07
+#define WLED_SYNC_RESET_VAL		0x00
+
 #define MAX_FLASH_LED_CURRENT		300
 #define MAX_LC_LED_CURRENT		40
 #define MAX_KP_BL_LED_CURRENT		300
@@ -81,6 +121,8 @@
 	int			pwm_channel;
 	u32			pwm_period_us;
 	struct pm8xxx_pwm_duty_cycles *pwm_duty_cycles;
+	struct wled_config_data *wled_cfg;
+	int			max_current;
 };
 
 static void led_kp_set(struct pm8xxx_led_data *led, enum led_brightness value)
@@ -145,6 +187,79 @@
 			 led->id, rc);
 }
 
+static int
+led_wled_set(struct pm8xxx_led_data *led, enum led_brightness value)
+{
+	int rc, duty;
+	u8 val, i, num_wled_strings;
+
+	if (value > WLED_MAX_LEVEL)
+		value = WLED_MAX_LEVEL;
+
+	duty = (WLED_MAX_DUTY_CYCLE * value) / WLED_MAX_LEVEL;
+
+	num_wled_strings = led->wled_cfg->num_strings;
+
+	/* program brightness control registers */
+	for (i = 0; i < num_wled_strings; i++) {
+		rc = pm8xxx_readb(led->dev->parent,
+				WLED_BRIGHTNESS_CNTL_REG1(i), &val);
+		if (rc) {
+			dev_err(led->dev->parent, "can't read wled brightnes ctrl"
+				" register1 rc=%d\n", rc);
+			return rc;
+		}
+
+		val = (val & ~WLED_MAX_CURR_MASK) | (duty >> WLED_8_BIT_SHFT);
+		rc = pm8xxx_writeb(led->dev->parent,
+				WLED_BRIGHTNESS_CNTL_REG1(i), val);
+		if (rc) {
+			dev_err(led->dev->parent, "can't write wled brightness ctrl"
+				" register1 rc=%d\n", rc);
+			return rc;
+		}
+
+		val = duty & WLED_8_BIT_MASK;
+		rc = pm8xxx_writeb(led->dev->parent,
+				WLED_BRIGHTNESS_CNTL_REG2(i), val);
+		if (rc) {
+			dev_err(led->dev->parent, "can't write wled brightness ctrl"
+				" register2 rc=%d\n", rc);
+			return rc;
+		}
+	}
+
+	/* sync */
+	val = WLED_SYNC_VAL;
+	rc = pm8xxx_writeb(led->dev->parent, WLED_SYNC_REG, val);
+	if (rc) {
+		dev_err(led->dev->parent,
+			"can't read wled sync register rc=%d\n", rc);
+		return rc;
+	}
+
+	val = WLED_SYNC_RESET_VAL;
+	rc = pm8xxx_writeb(led->dev->parent, WLED_SYNC_REG, val);
+	if (rc) {
+		dev_err(led->dev->parent,
+			"can't read wled sync register rc=%d\n", rc);
+		return rc;
+	}
+	return 0;
+}
+
+static void wled_dump_regs(struct pm8xxx_led_data *led)
+{
+	int i;
+	u8 val;
+
+	for (i = 1; i < 17; i++) {
+		pm8xxx_readb(led->dev->parent,
+				SSBI_REG_ADDR_WLED_CTRL(i), &val);
+		pr_debug("WLED_CTRL_%d = 0x%x\n", i, val);
+	}
+}
+
 static int pm8xxx_led_pwm_work(struct pm8xxx_led_data *led)
 {
 	int duty_us;
@@ -168,21 +283,31 @@
 static void __pm8xxx_led_work(struct pm8xxx_led_data *led,
 					enum led_brightness level)
 {
+	int rc;
+
 	mutex_lock(&led->lock);
 
 	switch (led->id) {
 	case PM8XXX_ID_LED_KB_LIGHT:
 		led_kp_set(led, level);
-	break;
+		break;
 	case PM8XXX_ID_LED_0:
 	case PM8XXX_ID_LED_1:
 	case PM8XXX_ID_LED_2:
 		led_lc_set(led, level);
-	break;
+		break;
 	case PM8XXX_ID_FLASH_LED_0:
 	case PM8XXX_ID_FLASH_LED_1:
 		led_flash_set(led, level);
-	break;
+		break;
+	case PM8XXX_ID_WLED:
+		rc = led_wled_set(led, level);
+		if (rc < 0)
+			pr_err("wled brightness set failed %d\n", rc);
+		break;
+	default:
+		dev_err(led->cdev.dev, "unknown led id %d", led->id);
+		break;
 	}
 
 	mutex_unlock(&led->lock);
@@ -261,6 +386,9 @@
 			break;
 		}
 		break;
+	case PM8XXX_ID_WLED:
+		led->cdev.max_brightness = WLED_MAX_LEVEL;
+		break;
 	default:
 		rc = -EINVAL;
 		pr_err("LED Id is invalid");
@@ -279,6 +407,149 @@
 	return led->cdev.brightness;
 }
 
+static int __devinit init_wled(struct pm8xxx_led_data *led)
+{
+	int rc, i;
+	u8 val, num_wled_strings;
+
+	num_wled_strings = led->wled_cfg->num_strings;
+
+	/* program over voltage protection threshold */
+	if (led->wled_cfg->ovp_val > WLED_OVP_37V) {
+		dev_err(led->dev->parent, "Invalid ovp value");
+		return -EINVAL;
+	}
+
+	rc = pm8xxx_readb(led->dev->parent, WLED_OVP_CFG_REG, &val);
+	if (rc) {
+		dev_err(led->dev->parent, "can't read wled ovp config"
+			" register rc=%d\n", rc);
+		return rc;
+	}
+
+	val = (val & ~WLED_OVP_VAL_MASK) |
+		(led->wled_cfg->ovp_val << WLED_OVP_VAL_BIT_SHFT);
+
+	rc = pm8xxx_writeb(led->dev->parent, WLED_OVP_CFG_REG, val);
+	if (rc) {
+		dev_err(led->dev->parent, "can't write wled ovp config"
+			" register rc=%d\n", rc);
+		return rc;
+	}
+
+	/* program current boost limit and output feedback*/
+	if (led->wled_cfg->boost_curr_lim > WLED_CURR_LIMIT_1680mA) {
+		dev_err(led->dev->parent, "Invalid boost current limit");
+		return -EINVAL;
+	}
+
+	rc = pm8xxx_readb(led->dev->parent, WLED_BOOST_CFG_REG, &val);
+	if (rc) {
+		dev_err(led->dev->parent, "can't read wled boost config"
+			" register rc=%d\n", rc);
+		return rc;
+	}
+
+	val = (val & ~WLED_BOOST_LIMIT_MASK) |
+		(led->wled_cfg->boost_curr_lim << WLED_BOOST_LIMIT_BIT_SHFT);
+
+	val = (val & ~WLED_OP_FDBCK_MASK) |
+		(led->wled_cfg->op_fdbck << WLED_OP_FDBCK_BIT_SHFT);
+
+	rc = pm8xxx_writeb(led->dev->parent, WLED_BOOST_CFG_REG, val);
+	if (rc) {
+		dev_err(led->dev->parent, "can't write wled boost config"
+			" register rc=%d\n", rc);
+		return rc;
+	}
+
+	/* program high pole capacitance */
+	if (led->wled_cfg->cp_select > WLED_CP_SELECT_MAX) {
+		dev_err(led->dev->parent, "Invalid pole capacitance");
+		return -EINVAL;
+	}
+
+	rc = pm8xxx_readb(led->dev->parent, WLED_HIGH_POLE_CAP_REG, &val);
+	if (rc) {
+		dev_err(led->dev->parent, "can't read wled high pole"
+			" capacitance register rc=%d\n", rc);
+		return rc;
+	}
+
+	val = (val & ~WLED_CP_SELECT_MASK) | led->wled_cfg->cp_select;
+
+	rc = pm8xxx_writeb(led->dev->parent, WLED_HIGH_POLE_CAP_REG, val);
+	if (rc) {
+		dev_err(led->dev->parent, "can't write wled high pole"
+			" capacitance register rc=%d\n", rc);
+		return rc;
+	}
+
+	/* program activation delay and maximum current */
+	for (i = 0; i < num_wled_strings; i++) {
+		rc = pm8xxx_readb(led->dev->parent,
+				WLED_MAX_CURR_CFG_REG(i + 2), &val);
+		if (rc) {
+			dev_err(led->dev->parent, "can't read wled max current"
+				" config register rc=%d\n", rc);
+			return rc;
+		}
+
+		if ((led->wled_cfg->ctrl_delay_us % WLED_CTL_DLY_STEP) ||
+			(led->wled_cfg->ctrl_delay_us > WLED_CTL_DLY_MAX)) {
+			dev_err(led->dev->parent, "Invalid control delay\n");
+			return rc;
+		}
+
+		val = val / WLED_CTL_DLY_STEP;
+		val = (val & ~WLED_CTL_DLY_MASK) |
+			(led->wled_cfg->ctrl_delay_us << WLED_CTL_DLY_BIT_SHFT);
+
+		if ((led->max_current > WLED_MAX_CURR)) {
+			dev_err(led->dev->parent, "Invalid max current\n");
+			return -EINVAL;
+		}
+
+		val = (val & ~WLED_MAX_CURR_MASK) | led->max_current;
+
+		rc = pm8xxx_writeb(led->dev->parent,
+				WLED_MAX_CURR_CFG_REG(i + 2), val);
+		if (rc) {
+			dev_err(led->dev->parent, "can't write wled max current"
+				" config register rc=%d\n", rc);
+			return rc;
+		}
+	}
+
+	/* program digital module generator, cs out and enable the module */
+	rc = pm8xxx_readb(led->dev->parent, WLED_MOD_CTRL_REG, &val);
+	if (rc) {
+		dev_err(led->dev->parent, "can't read wled module ctrl"
+			" register rc=%d\n", rc);
+		return rc;
+	}
+
+	if (led->wled_cfg->dig_mod_gen_en)
+		val |= WLED_DIG_MOD_GEN_MASK;
+
+	if (led->wled_cfg->cs_out_en)
+		val |= WLED_CS_OUT_MASK;
+
+	val |= WLED_EN_MASK;
+
+	rc = pm8xxx_writeb(led->dev->parent, WLED_MOD_CTRL_REG, val);
+	if (rc) {
+		dev_err(led->dev->parent, "can't write wled module ctrl"
+			" register rc=%d\n", rc);
+		return rc;
+	}
+
+	/* dump wled registers */
+	wled_dump_regs(led);
+
+	return 0;
+}
+
 static int __devinit get_init_value(struct pm8xxx_led_data *led, u8 *val)
 {
 	int rc, offset;
@@ -300,6 +571,15 @@
 	case PM8XXX_ID_FLASH_LED_1:
 		addr = SSBI_REG_ADDR_FLASH_DRV1;
 		break;
+	case PM8XXX_ID_WLED:
+		rc = init_wled(led);
+		if (rc)
+			dev_err(led->cdev.dev, "can't initialize wled rc=%d\n",
+								rc);
+		return rc;
+	default:
+		dev_err(led->cdev.dev, "unknown led id %d", led->id);
+		return -EINVAL;
 	}
 
 	rc = pm8xxx_readb(led->dev->parent, addr, val);
@@ -351,6 +631,7 @@
 	return rc;
 }
 
+
 static int __devinit pm8xxx_led_probe(struct platform_device *pdev)
 {
 	const struct pm8xxx_led_platform_data *pdata = pdev->dev.platform_data;
@@ -388,9 +669,11 @@
 		led_dat->pwm_channel = led_cfg->pwm_channel;
 		led_dat->pwm_period_us = led_cfg->pwm_period_us;
 		led_dat->pwm_duty_cycles = led_cfg->pwm_duty_cycles;
+		led_dat->wled_cfg = led_cfg->wled_cfg;
+		led_dat->max_current = led_cfg->max_current;
 
 		if (!((led_dat->id >= PM8XXX_ID_LED_KB_LIGHT) &&
-				(led_dat->id <= PM8XXX_ID_FLASH_LED_1))) {
+				(led_dat->id < PM8XXX_ID_MAX))) {
 			dev_err(&pdev->dev, "invalid LED ID (%d) specified\n",
 						 led_dat->id);
 			rc = -EINVAL;
@@ -424,6 +707,12 @@
 			goto fail_id_check;
 		}
 
+		/* configure default state */
+		if (led_cfg->default_state)
+			led->cdev.brightness = led_dat->cdev.max_brightness;
+		else
+			led->cdev.brightness = LED_OFF;
+
 		if (led_cfg->mode != PM8XXX_LED_MODE_MANUAL) {
 			__pm8xxx_led_work(led_dat,
 					led_dat->cdev.max_brightness);
@@ -436,9 +725,10 @@
 					"configure LED, error: %d\n", rc);
 					goto fail_id_check;
 				}
+			schedule_work(&led->work);
 			}
 		} else {
-			__pm8xxx_led_work(led_dat, LED_OFF);
+			__pm8xxx_led_work(led_dat, led->cdev.brightness);
 		}
 	}
 
diff --git a/drivers/media/video/msm/gemini/Makefile b/drivers/media/video/msm/gemini/Makefile
index 3e2fc97..8a7cd93 100644
--- a/drivers/media/video/msm/gemini/Makefile
+++ b/drivers/media/video/msm/gemini/Makefile
@@ -1,2 +1,3 @@
 GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+EXTRA_CFLAGS += -Idrivers/media/video/msm
 obj-$(CONFIG_MSM_GEMINI) += msm_gemini_dev.o msm_gemini_sync.o msm_gemini_core.o msm_gemini_hw.o msm_gemini_platform.o
diff --git a/drivers/media/video/msm/gemini/msm_gemini_dev.c b/drivers/media/video/msm/gemini/msm_gemini_dev.c
index 1156bb0..01d45ed 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_dev.c
+++ b/drivers/media/video/msm/gemini/msm_gemini_dev.c
@@ -20,8 +20,11 @@
 #include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/uaccess.h>
-
 #include <media/msm_gemini.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+
+#include "msm.h"
 #include "msm_gemini_sync.h"
 #include "msm_gemini_common.h"
 
@@ -66,8 +69,8 @@
 	int rc;
 	struct msm_gemini_device *pgmn_dev = filp->private_data;
 
-	GMN_DBG(KERN_INFO "%s:%d] cmd = %d\n", __func__, __LINE__,
-		_IOC_NR(cmd));
+	GMN_DBG("%s:%d] cmd=%d pgmn_dev=0x%x arg=0x%x\n", __func__,
+		__LINE__, _IOC_NR(cmd), (uint32_t)pgmn_dev, (uint32_t)arg);
 
 	rc = __msm_gemini_ioctl(pgmn_dev, cmd, arg);
 
@@ -84,21 +87,78 @@
 
 static struct class *msm_gemini_class;
 static dev_t msm_gemini_devno;
-static struct msm_gemini_device *msm_gemini_device_p;
+struct msm_gemini_device *msm_gemini_device_p;
+
+int msm_gemini_subdev_init(struct v4l2_subdev *gemini_sd)
+{
+	int rc;
+	struct msm_gemini_device *pgmn_dev =
+		(struct msm_gemini_device *)gemini_sd->host_priv;
+
+	GMN_DBG("%s:%d: gemini_sd=0x%x pgmn_dev=0x%x\n",
+		__func__, __LINE__, (uint32_t)gemini_sd, (uint32_t)pgmn_dev);
+	rc = __msm_gemini_open(pgmn_dev);
+	GMN_DBG("%s:%d: rc=%d\n",
+		__func__, __LINE__, rc);
+	return rc;
+}
+
+static long msm_gemini_subdev_ioctl(struct v4l2_subdev *sd,
+	unsigned int cmd, void *arg)
+{
+	long rc;
+	struct msm_gemini_device *pgmn_dev =
+		(struct msm_gemini_device *)sd->host_priv;
+
+	GMN_DBG("%s: cmd=%d\n", __func__, cmd);
+
+	GMN_DBG("%s: pgmn_dev 0x%x", __func__, (uint32_t)pgmn_dev);
+
+	GMN_DBG("%s: Calling __msm_gemini_ioctl\n", __func__);
+
+	rc = __msm_gemini_ioctl(pgmn_dev, cmd, (unsigned long)arg);
+	pr_debug("%s: X\n", __func__);
+	return rc;
+}
+
+void msm_gemini_subdev_release(struct v4l2_subdev *gemini_sd)
+{
+	int rc;
+	struct msm_gemini_device *pgmn_dev =
+		(struct msm_gemini_device *)gemini_sd->host_priv;
+	GMN_DBG("%s:pgmn_dev=0x%x", __func__, (uint32_t)pgmn_dev);
+	rc = __msm_gemini_release(pgmn_dev);
+	GMN_DBG("%s:rc=%d", __func__, rc);
+}
+
+static const struct v4l2_subdev_core_ops msm_gemini_subdev_core_ops = {
+	.ioctl = msm_gemini_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_gemini_subdev_ops = {
+	.core = &msm_gemini_subdev_core_ops,
+};
 
 static int msm_gemini_init(struct platform_device *pdev)
 {
 	int rc = -1;
 	struct device *dev;
 
-	GMN_DBG("%s:%d]\n", __func__, __LINE__);
-
+	GMN_DBG("%s:\n", __func__);
 	msm_gemini_device_p = __msm_gemini_init(pdev);
 	if (msm_gemini_device_p == NULL) {
 		GMN_PR_ERR("%s: initialization failed\n", __func__);
 		goto fail;
 	}
 
+	v4l2_subdev_init(&msm_gemini_device_p->subdev, &msm_gemini_subdev_ops);
+	v4l2_set_subdev_hostdata(&msm_gemini_device_p->subdev,
+		msm_gemini_device_p);
+	pr_debug("%s: msm_gemini_device_p 0x%x", __func__,
+			(uint32_t)msm_gemini_device_p);
+	GMN_DBG("%s:gemini: platform_set_drvdata\n", __func__);
+	platform_set_drvdata(pdev, &msm_gemini_device_p->subdev);
+
 	rc = alloc_chrdev_region(&msm_gemini_devno, 0, 1, MSM_GEMINI_NAME);
 	if (rc < 0) {
 		GMN_PR_ERR("%s: failed to allocate chrdev\n", __func__);
@@ -168,9 +228,7 @@
 
 static int __msm_gemini_probe(struct platform_device *pdev)
 {
-	int rc;
-	rc = msm_gemini_init(pdev);
-	return rc;
+	return msm_gemini_init(pdev);
 }
 
 static int __msm_gemini_remove(struct platform_device *pdev)
@@ -183,7 +241,7 @@
 	.probe  = __msm_gemini_probe,
 	.remove = __msm_gemini_remove,
 	.driver = {
-		.name = "msm_gemini",
+		.name = MSM_GEMINI_DRV_NAME,
 		.owner = THIS_MODULE,
 	},
 };
diff --git a/drivers/media/video/msm/gemini/msm_gemini_sync.h b/drivers/media/video/msm/gemini/msm_gemini_sync.h
index 6c69a92..a47e766 100644
--- a/drivers/media/video/msm/gemini/msm_gemini_sync.h
+++ b/drivers/media/video/msm/gemini/msm_gemini_sync.h
@@ -17,6 +17,8 @@
 #include <linux/list.h>
 #include <linux/cdev.h>
 #include <linux/platform_device.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
 #include "msm_gemini_core.h"
 
 struct msm_gemini_q {
@@ -63,6 +65,8 @@
 	/* input buf queue
 	 */
 	struct msm_gemini_q input_buf_q;
+
+	struct v4l2_subdev subdev;
 };
 
 int __msm_gemini_open(struct msm_gemini_device *pgmn_dev);
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 7680559..40bc160 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -36,7 +36,7 @@
 #define MSM_V4L2_DIMENSION_SIZE 96
 #define MAX_DEV_NAME_LEN 50
 
-#define ERR_USER_COPY(to) pr_err("%s(%d): copy %s user\n", \
+#define ERR_USER_COPY(to) pr_debug("%s(%d): copy %s user\n", \
 				__func__, __LINE__, ((to) ? "to" : "from"))
 #define ERR_COPY_FROM_USER() ERR_USER_COPY(0)
 #define ERR_COPY_TO_USER() ERR_USER_COPY(1)
@@ -47,6 +47,7 @@
 #define MSM_ISPIF_DRV_NAME "msm_ispif"
 #define MSM_VFE_DRV_NAME "msm_vfe"
 #define MSM_VPE_DRV_NAME "msm_vpe"
+#define MSM_GEMINI_DRV_NAME "msm_gemini"
 
 /* msm queue management APIs*/
 
@@ -232,6 +233,7 @@
 	struct v4l2_subdev *csic_sdev; /*csid sub device*/
 	struct v4l2_subdev *ispif_sdev; /* ispif sub device */
 	struct v4l2_subdev *act_sdev; /* actuator sub device */
+	struct v4l2_subdev *gemini_sdev; /* gemini sub device */
 
 	struct pm_qos_request_list pm_qos_req_list;
 	struct msm_mctl_pp_info pp_info;
@@ -248,12 +250,13 @@
 
 	/*int (*isp_init)(struct msm_cam_v4l2_device *pcam);*/
 	int (*isp_open)(struct v4l2_subdev *sd, struct v4l2_subdev *sd_vpe,
-					struct msm_sync *sync);
+		struct v4l2_subdev *gemini_sdev, struct msm_sync *sync);
 	int (*isp_config)(struct msm_cam_media_controller *pmctl,
 		 unsigned int cmd, unsigned long arg);
 	int (*isp_notify)(struct v4l2_subdev *sd,
 		unsigned int notification, void *arg);
-	void (*isp_release)(struct msm_sync *psync);
+	void (*isp_release)(struct msm_sync *psync,
+		struct v4l2_subdev *gemini_sdev);
 	int (*isp_pp_cmd)(struct msm_cam_media_controller *pmctl,
 		 struct msm_mctl_pp_cmd, void *data);
 
@@ -462,7 +465,9 @@
 	struct msm_vfe_cfg_cmd *cfgcmd, void *data);
 int msm_vpe_subdev_init(struct v4l2_subdev *sd, void *data,
 	struct platform_device *pdev);
+int msm_gemini_subdev_init(struct v4l2_subdev *sd);
 void msm_vpe_subdev_release(struct platform_device *pdev);
+void msm_gemini_subdev_release(struct v4l2_subdev *gemini_sd);
 int msm_isp_subdev_ioctl_vpe(struct v4l2_subdev *isp_subdev,
 	struct msm_mctl_pp_cmd *cmd, void *data);
 int msm_mctl_is_pp_msg_type(struct msm_cam_media_controller *p_mctl,
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index bb50d77..16964b2 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -26,6 +26,7 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-device.h>
 #include <media/msm_isp.h>
+#include <media/msm_gemini.h>
 
 #include "msm.h"
 
@@ -34,10 +35,6 @@
 #else
 #define D(fmt, args...) do {} while (0)
 #endif
-#define ERR_USER_COPY(to) pr_err("%s(%d): copy %s user\n", \
-				__func__, __LINE__, ((to) ? "to" : "from"))
-#define ERR_COPY_FROM_USER() ERR_USER_COPY(0)
-#define ERR_COPY_TO_USER() ERR_USER_COPY(1)
 
 #define MSM_FRAME_AXI_MAX_BUF 32
 
@@ -151,7 +148,7 @@
 
 	int vfe_id = vdata->evt_msg.msg_id;
 	if (!pcam) {
-		pr_err("%s pcam is null. return\n", __func__);
+		pr_debug("%s pcam is null. return\n", __func__);
 		msm_isp_sync_free(vdata);
 		return rc;
 	}
@@ -181,7 +178,7 @@
 		break;
 	case VFE_MSG_V32_CAPTURE:
 	case VFE_MSG_V2X_CAPTURE:
-		pr_err("%s Got V32_CAPTURE: getting buffer for id = %d",
+		pr_debug("%s Got V32_CAPTURE: getting buffer for id = %d",
 						__func__, vfe_id);
 		msm_mctl_reserve_free_buf(&pcam->mctl, NULL,
 					image_mode, &free_buf);
@@ -202,6 +199,19 @@
 		vfe_params.data = (void *)&free_buf;
 		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
 		break;
+	case VFE_MSG_V32_JPEG_CAPTURE:
+		free_buf.num_planes = 1;
+		free_buf.ch_paddr[0] = IMEM_Y_OFFSET;
+		free_buf.ch_paddr[1] = IMEM_CBCR_OFFSET;
+		cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR;
+		cfgcmd.value = &vfe_id;
+		vfe_params.vfe_cfg = &cfgcmd;
+		vfe_params.data = (void *)&free_buf;
+		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
+		/* Write the same buffer into PONG */
+		cfgcmd.cmd_type = CMD_CONFIG_PONG_ADDR;
+		rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params);
+		break;
 	case VFE_MSG_OUTPUT_IRQ:
 		D("%s Got OUTPUT_IRQ: Getting free buf id = %d",
 						__func__, vfe_id);
@@ -413,7 +423,7 @@
 
 /* This function is called by open() function, so we need to init HW*/
 static int msm_isp_open(struct v4l2_subdev *sd,
-	struct v4l2_subdev *sd_vpe,
+	struct v4l2_subdev *sd_vpe, struct v4l2_subdev *gemini_sdev,
 	struct msm_sync *sync)
 {
 	/* init vfe and senor, register sync callbacks for init*/
@@ -439,7 +449,8 @@
 	return rc;
 }
 
-static void msm_isp_release(struct msm_sync *psync)
+static void msm_isp_release(struct msm_sync *psync,
+		struct v4l2_subdev *gemini_sdev)
 {
 	D("%s\n", __func__);
 	msm_vfe_subdev_release(psync->pdev);
@@ -447,7 +458,7 @@
 }
 
 static int msm_config_vfe(struct v4l2_subdev *sd,
-		struct msm_sync *sync, void __user *arg)
+	struct msm_sync *sync, void __user *arg)
 {
 	struct msm_vfe_cfg_cmd cfgcmd;
 	struct msm_pmem_region region[8];
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index 13d1daf..54458d1 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -304,7 +304,7 @@
 		pr_err("%s: param is NULL", __func__);
 		return -EINVAL;
 	}
-	D("%s cmd = %d\n", __func__, _IOC_NR(cmd));
+	D("%s:%d: cmd %d\n", __func__, __LINE__, cmd);
 
 	/* ... call sensor, ISPIF or VEF subdev*/
 	switch (cmd) {
@@ -436,6 +436,8 @@
 			/* ISFIF config*/
 	default:
 		/* ISP config*/
+		D("%s:%d: go to default. Calling msm_isp_config\n",
+			__func__, __LINE__);
 		rc = p_mctl->isp_sdev->isp_config(p_mctl, cmd, arg);
 		break;
 	}
@@ -556,6 +558,34 @@
 	}
 
 	rc = 0;
+
+
+	/* register gemini subdev */
+	driver = driver_find(MSM_GEMINI_DRV_NAME, &platform_bus_type);
+	if (!driver) {
+		pr_err("%s:%d:Gemini: Failure: goto out\n",
+			__func__, __LINE__);
+		goto out;
+	}
+	pr_debug("%s:%d:Gemini: driver_find_device Gemini driver 0x%x\n",
+		__func__, __LINE__, (uint32_t)driver);
+	dev = driver_find_device(driver, NULL, NULL,
+				msm_mctl_subdev_match_core);
+	if (!dev) {
+		pr_err("%s:%d:Gemini: Failure goto out_put_driver\n",
+			__func__, __LINE__);
+		goto out_put_driver;
+	}
+	p_mctl->gemini_sdev = dev_get_drvdata(dev);
+	pr_debug("%s:%d:Gemini: After dev_get_drvdata gemini_sdev=0x%x\n",
+		__func__, __LINE__, (uint32_t)p_mctl->gemini_sdev);
+
+	if (p_mctl->gemini_sdev == NULL) {
+		pr_err("%s:%d:Gemini: Failure gemini_sdev is null\n",
+			__func__, __LINE__);
+		goto out_put_driver;
+	}
+	rc = 0;
 	return rc;
 out_put_driver:
 	put_driver(driver);
@@ -629,7 +659,9 @@
 		if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_open)
 			rc = p_mctl->isp_sdev->isp_open(
 				p_mctl->isp_sdev->sd,
-				p_mctl->isp_sdev->sd_vpe, sync);
+				p_mctl->isp_sdev->sd_vpe,
+				p_mctl->gemini_sdev,
+				sync);
 		if (rc < 0) {
 			pr_err("%s: isp init failed: %d\n", __func__, rc);
 			goto msm_open_done;
@@ -691,7 +723,8 @@
 	}
 
 	if (p_mctl->isp_sdev && p_mctl->isp_sdev->isp_release)
-		p_mctl->isp_sdev->isp_release(&p_mctl->sync);
+		p_mctl->isp_sdev->isp_release(&p_mctl->sync,
+				p_mctl->gemini_sdev);
 
 	if (camdev->is_csid) {
 		v4l2_subdev_call(p_mctl->csid_sdev, core, ioctl,
diff --git a/drivers/media/video/msm/msm_mem.c b/drivers/media/video/msm/msm_mem.c
index 0ba1c0f..54b4efb 100644
--- a/drivers/media/video/msm/msm_mem.c
+++ b/drivers/media/video/msm/msm_mem.c
@@ -36,13 +36,6 @@
 #define D(fmt, args...) do {} while (0)
 #endif
 
-
-#define ERR_USER_COPY(to) pr_err("%s(%d): copy %s user\n", \
-				__func__, __LINE__, ((to) ? "to" : "from"))
-#define ERR_COPY_FROM_USER() ERR_USER_COPY(0)
-#define ERR_COPY_TO_USER() ERR_USER_COPY(1)
-
-
 #define PAD_TO_WORD(a)	  (((a) + 3) & ~3)
 
 #define __CONTAINS(r, v, l, field) ({			   \
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index 99d9911..89bdf0f 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -702,8 +702,6 @@
 	msm_io_w(VFE_IMASK_WHILE_STOPPING_1,
 		vfe32_ctrl->vfebase + VFE_IRQ_MASK_1);
 
-	msm_io_dump(vfe32_ctrl->vfebase, vfe32_ctrl->register_total * 4);
-
 	/* Ensure the write order while writing
 	to the command register using the barrier */
 	msm_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
@@ -851,7 +849,9 @@
 	/* capture command is valid for both idle and active state. */
 	vfe32_ctrl->outpath.out1.capture_cnt = num_frames_capture;
 	if (vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
-		vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) {
+		vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN ||
+		vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
+		vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) {
 		vfe32_ctrl->outpath.out0.capture_cnt =
 			num_frames_capture;
 	}
@@ -887,6 +887,9 @@
 				vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]);
 		}
 	}
+
+	vfe32_ctrl->vfe_capture_count = num_frames_capture;
+
 	msm_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
 	msm_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
 	msm_camio_bus_scale_cfg(
@@ -1286,16 +1289,31 @@
 		rc = vfe32_capture_raw(snapshot_cnt);
 		break;
 	case VFE_CMD_CAPTURE:
-		pr_info("vfe32_proc_general: cmdID = %s\n",
-			vfe32_general_cmd[cmd->id]);
+		CDBG("vfe32_proc_general: cmdID = %s op mode = %d\n",
+			vfe32_general_cmd[cmd->id], vfe32_ctrl->operation_mode);
 		if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value),
 				sizeof(uint32_t))) {
 			rc = -EFAULT;
 			goto proc_general_done;
 		}
-		/* Configure primary channel */
-		rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_CAPTURE,
-						  VFE_MSG_OUTPUT_PRIMARY);
+
+		if (vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
+		vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) {
+			if (snapshot_cnt != 1) {
+				pr_err("only support 1 inline snapshot\n");
+				rc = -EINVAL;
+				goto proc_general_done;
+			}
+			/* Configure primary channel for JPEG */
+			rc = vfe32_configure_pingpong_buffers(
+				VFE_MSG_V32_JPEG_CAPTURE,
+				VFE_MSG_OUTPUT_PRIMARY);
+		} else {
+			/* Configure primary channel */
+			rc = vfe32_configure_pingpong_buffers(
+				VFE_MSG_V32_CAPTURE,
+				VFE_MSG_OUTPUT_PRIMARY);
+		}
 		if (rc < 0) {
 			pr_err("%s error configuring pingpong buffers"
 				   " for primary output", __func__);
@@ -2610,7 +2628,9 @@
 	}
 
 	if ((vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) ||
-		(vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB)) {
+		(vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB) ||
+		(vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) ||
+		(vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB)) {
 		/* in snapshot mode */
 		/* later we need to add check for live snapshot mode. */
 		if (vfe32_ctrl->frame_skip_pattern & (0x1 <<
@@ -2858,6 +2878,8 @@
 	*/
 	out_bool = ((vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN ||
 		vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB ||
+		vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG ||
+		vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB ||
 		vfe32_ctrl->operation_mode == VFE_OUTPUTS_RAW ||
 		vfe32_ctrl->liveshot_state == VFE_STATE_STARTED ||
 		vfe32_ctrl->liveshot_state == VFE_STATE_STOP_REQUESTED ||
@@ -2899,6 +2921,10 @@
 			vfe32_ctrl->operation_mode ==
 				VFE_OUTPUTS_MAIN_AND_THUMB ||
 			vfe32_ctrl->operation_mode ==
+				VFE_OUTPUTS_THUMB_AND_JPEG ||
+			vfe32_ctrl->operation_mode ==
+				VFE_OUTPUTS_JPEG_AND_THUMB ||
+			vfe32_ctrl->operation_mode ==
 				VFE_OUTPUTS_RAW ||
 			vfe32_ctrl->liveshot_state == VFE_STATE_STOPPED)
 			vfe32_ctrl->outpath.out0.capture_cnt--;
@@ -3392,6 +3418,10 @@
 				vfe32_ctrl->operation_mode ==
 					VFE_OUTPUTS_MAIN_AND_THUMB ||
 				vfe32_ctrl->operation_mode ==
+					VFE_OUTPUTS_THUMB_AND_JPEG ||
+				vfe32_ctrl->operation_mode ==
+					VFE_OUTPUTS_JPEG_AND_THUMB ||
+				vfe32_ctrl->operation_mode ==
 					VFE_OUTPUTS_RAW) {
 				if ((vfe32_ctrl->outpath.out0.capture_cnt == 0)
 						&& (vfe32_ctrl->outpath.out1.
diff --git a/drivers/media/video/msm/sensors/Makefile b/drivers/media/video/msm/sensors/Makefile
index 33db124..047226e 100644
--- a/drivers/media/video/msm/sensors/Makefile
+++ b/drivers/media/video/msm/sensors/Makefile
@@ -5,8 +5,8 @@
 obj-$(CONFIG_MSM_CAMERA_SENSOR) += msm_sensor.o
 obj-$(CONFIG_IMX074) += imx074_v4l2.o
 obj-$(CONFIG_MT9M114) += mt9m114_v4l2.o
+obj-$(CONFIG_S5K3L1YX) += s5k3l1yx.o
 obj-$(CONFIG_OV2720) += ov2720.o
 obj-$(CONFIG_S5K4E1) += s5k4e1_v4l2.o
 obj-$(CONFIG_MT9E013) += mt9e013_v4l2.o
 obj-$(CONFIG_WEBCAM_OV9726) += ov9726_v4l2.o
-obj-$(CONFIG_S5K3L1YX) += s5k3l1yx.o
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 30192d9..c8fcf5f 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -69,7 +69,7 @@
 obj-$(CONFIG_MCP_UCB1200)	+= ucb1x00-core.o
 obj-$(CONFIG_MCP_UCB1200_TS)	+= ucb1x00-ts.o
 
-obj-$(CONFIG_WCD9310_CODEC)       += wcd9310-core.o wcd9310-irq.o
+obj-$(CONFIG_WCD9310_CODEC)       += wcd9310-core.o wcd9310-irq.o wcd9310-slimslave.o
 
 ifeq ($(CONFIG_SA1100_ASSABET),y)
 obj-$(CONFIG_MCP_UCB1200)	+= ucb1x00-assabet.o
diff --git a/drivers/mfd/wcd9310-core.c b/drivers/mfd/wcd9310-core.c
index 588f950..87abcda 100644
--- a/drivers/mfd/wcd9310-core.c
+++ b/drivers/mfd/wcd9310-core.c
@@ -14,8 +14,8 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/mfd/core.h>
+#include <linux/mfd/wcd9310/wcd9310-slimslave.h>
 #include <linux/mfd/pm8xxx/pm8921.h>
-#include <linux/mfd/wcd9310/core.h>
 #include <linux/mfd/wcd9310/pdata.h>
 #include <linux/mfd/wcd9310/registers.h>
 #include <linux/delay.h>
@@ -921,7 +921,7 @@
 		pr_err("%s: error, initializing device failed\n", __func__);
 		goto err_slim_add;
 	}
-
+	tabla_init_slimslave(tabla, tabla_pgd_la);
 #ifdef CONFIG_DEBUG_FS
 	debugTabla = tabla;
 
@@ -963,6 +963,7 @@
 #endif
 
 	tabla = slim_get_devicedata(pdev);
+	tabla_deinit_slimslave(tabla);
 	tabla_device_exit(tabla);
 	tabla_disable_supplies(tabla);
 	slim_remove_device(tabla->slim_slave);
diff --git a/drivers/mfd/wcd9310-slimslave.c b/drivers/mfd/wcd9310-slimslave.c
new file mode 100644
index 0000000..dd586fa
--- /dev/null
+++ b/drivers/mfd/wcd9310-slimslave.c
@@ -0,0 +1,522 @@
+/* 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/slab.h>
+#include <linux/mutex.h>
+#include <linux/mfd/wcd9310/wcd9310-slimslave.h>
+
+struct tabla_slim_sch_rx {
+	u32 sph;
+	u32 ch_num;
+	u16 ch_h;
+	u16 grph;
+};
+
+struct tabla_slim_sch_tx {
+	u32 sph;
+	u32 ch_num;
+	u16 ch_h;
+	u16 grph;
+};
+
+struct tabla_slim_sch {
+	struct tabla_slim_sch_rx rx[SLIM_MAX_RX_PORTS];
+	struct tabla_slim_sch_tx tx[SLIM_MAX_TX_PORTS];
+};
+
+static struct tabla_slim_sch sh_ch;
+
+static int tabla_alloc_slim_sh_ch_rx(struct tabla *tabla, u8 tabla_pgd_la);
+static int tabla_alloc_slim_sh_ch_tx(struct tabla *tabla, u8 tabla_pgd_la);
+static int tabla_dealloc_slim_sh_ch_rx(struct tabla *tab);
+static int tabla_dealloc_slim_sh_ch_tx(struct tabla *tab);
+
+int tabla_init_slimslave(struct tabla *tabla, u8 tabla_pgd_la)
+{
+	int ret = 0;
+
+	ret = tabla_alloc_slim_sh_ch_rx(tabla, tabla_pgd_la);
+	if (ret) {
+		pr_err("%s: Failed to alloc rx slimbus shared channels\n",
+								__func__);
+		goto rx_err;
+	}
+	ret = tabla_alloc_slim_sh_ch_tx(tabla, tabla_pgd_la);
+	if (ret) {
+		pr_err("%s: Failed to alloc tx slimbus shared channels\n",
+								__func__);
+		goto tx_err;
+	}
+	return 0;
+tx_err:
+	tabla_dealloc_slim_sh_ch_rx(tabla);
+rx_err:
+	return ret;
+}
+
+
+int tabla_deinit_slimslave(struct tabla *tabla)
+{
+	int ret = 0;
+	ret = tabla_dealloc_slim_sh_ch_rx(tabla);
+	if (ret < 0) {
+		pr_err("%s: fail to dealloc rx slim ports\n", __func__);
+		goto err;
+	}
+	ret = tabla_dealloc_slim_sh_ch_tx(tabla);
+	if (ret < 0) {
+		pr_err("%s: fail to dealloc tx slim ports\n", __func__);
+		goto err;
+	}
+err:
+	return ret;
+}
+
+int tabla_get_channel(struct tabla *tabla,
+		unsigned int *rx_ch,
+		unsigned int *tx_ch)
+{
+	int ch_idx = 0;
+	struct tabla_slim_sch_rx *rx = sh_ch.rx;
+	struct tabla_slim_sch_tx *tx = sh_ch.tx;
+
+	for (ch_idx = 0; ch_idx < SLIM_MAX_RX_PORTS; ch_idx++)
+		rx_ch[ch_idx] = rx[ch_idx].ch_num;
+	for (ch_idx = 0; ch_idx < SLIM_MAX_TX_PORTS; ch_idx++)
+		tx_ch[ch_idx] = tx[ch_idx].ch_num;
+	return 0;
+}
+
+static int tabla_alloc_slim_sh_ch_rx(struct tabla *tabla, u8 tabla_pgd_la)
+{
+	int ret = 0;
+	u8 ch_idx ;
+	u16 slave_port_id = 0;
+	struct tabla_slim_sch_rx *rx = sh_ch.rx;
+
+	/* DSP requires channel number to be between 128 and 255. For RX port
+	 * use channel numbers from 138 to 144, for TX port
+	 * use channel numbers from 128 to 137
+	 */
+	pr_debug("%s: pgd_la[%d]\n", __func__, tabla_pgd_la);
+	for (ch_idx = 0; ch_idx < SLIM_MAX_RX_PORTS; ch_idx++) {
+		slave_port_id = (ch_idx + 1 +
+				SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS);
+		rx[ch_idx].ch_num = slave_port_id + BASE_CH_NUM;
+		ret = slim_get_slaveport(tabla_pgd_la, slave_port_id,
+					&rx[ch_idx].sph, SLIM_SINK);
+		if (ret < 0) {
+			pr_err("%s: slave port failure id[%d] ret[%d]\n",
+					__func__, slave_port_id, ret);
+			goto err;
+		}
+
+		ret = slim_query_ch(tabla->slim, rx[ch_idx].ch_num,
+							&rx[ch_idx].ch_h);
+		if (ret < 0) {
+			pr_err("%s: slim_query_ch failed ch-num[%d] ret[%d]\n",
+					__func__, rx[ch_idx].ch_num, ret);
+			goto err;
+		}
+	}
+err:
+	return ret;
+}
+
+static int tabla_alloc_slim_sh_ch_tx(struct tabla *tabla, u8 tabla_pgd_la)
+{
+	int ret = 0;
+	u8 ch_idx ;
+	struct tabla_slim_sch_tx *tx = sh_ch.tx;
+	u16 slave_port_id = 0;
+
+	pr_debug("%s: pgd_la[%d]\n", __func__, tabla_pgd_la);
+	/* DSP requires channel number to be between 128 and 255. For RX port
+	 * use channel numbers from 138 to 144, for TX port
+	 * use channel numbers from 128 to 137
+	 */
+	for (ch_idx = 0; ch_idx < SLIM_MAX_TX_PORTS; ch_idx++) {
+		slave_port_id = ch_idx;
+		tx[ch_idx].ch_num = slave_port_id + BASE_CH_NUM;
+		ret = slim_get_slaveport(tabla_pgd_la, slave_port_id,
+					&tx[ch_idx].sph, SLIM_SRC);
+		if (ret < 0) {
+			pr_err("%s: slave port failure id[%d] ret[%d]\n",
+					__func__, slave_port_id, ret);
+			goto err;
+		}
+		ret = slim_query_ch(tabla->slim, tx[ch_idx].ch_num,
+							&tx[ch_idx].ch_h);
+		if (ret < 0) {
+			pr_err("%s: slim_query_ch failed ch-num[%d] ret[%d]\n",
+					__func__, tx[ch_idx].ch_num, ret);
+			goto err;
+		}
+	}
+err:
+	return ret;
+}
+
+static int tabla_dealloc_slim_sh_ch_rx(struct tabla *tab)
+{
+	int idx = 0;
+	int ret = 0;
+	struct tabla_slim_sch_rx *rx = sh_ch.rx;
+	/* slim_dealloc_ch */
+	for (idx = 0; idx < SLIM_MAX_RX_PORTS; idx++) {
+		ret = slim_dealloc_ch(tab->slim, rx[idx].ch_h);
+		if (ret < 0) {
+			pr_err("%s: slim_dealloc_ch fail ret[%d] ch_h[%d]\n",
+				__func__, ret, rx[idx].ch_h);
+		}
+	}
+	memset(sh_ch.rx, 0, sizeof(sh_ch.rx));
+	return ret;
+}
+
+static int tabla_dealloc_slim_sh_ch_tx(struct tabla *tab)
+{
+	int idx = 0;
+	int ret = 0;
+	struct tabla_slim_sch_tx *tx = sh_ch.tx;
+	/* slim_dealloc_ch */
+	for (idx = 0; idx < SLIM_MAX_TX_PORTS; idx++) {
+		ret = slim_dealloc_ch(tab->slim, tx[idx].ch_h);
+		if (ret < 0) {
+			pr_err("%s: slim_dealloc_ch fail ret[%d] ch_h[%d]\n",
+				__func__, ret, tx[idx].ch_h);
+		}
+	}
+	memset(sh_ch.tx, 0, sizeof(sh_ch.tx));
+	return ret;
+}
+
+/* Enable slimbus slave device for RX path */
+int tabla_cfg_slim_sch_rx(struct tabla *tab, unsigned int *ch_num,
+				unsigned int ch_cnt, unsigned int rate)
+{
+	u8 i = 0;
+	u16 grph;
+	u32 sph[SLIM_MAX_RX_PORTS] = {0};
+	u16 ch_h[SLIM_MAX_RX_PORTS] = {0};
+	u16 slave_port_id;
+	u8  payload_rx = 0, wm_payload = 0;
+	int ret, idx = 0;
+	unsigned short  multi_chan_cfg_reg_addr;
+	struct tabla_slim_sch_rx *rx = sh_ch.rx;
+	struct slim_ch prop;
+
+	/* Configure slave interface device */
+	pr_debug("%s: ch_cnt[%d] rate=%d\n", __func__, ch_cnt, rate);
+
+	for (i = 0; i < ch_cnt; i++) {
+		idx = (ch_num[i] - BASE_CH_NUM -
+				SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
+		ch_h[i] = rx[idx].ch_h;
+		sph[i] = rx[idx].sph;
+		slave_port_id = idx + 1;
+		if ((slave_port_id > SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS) ||
+			(slave_port_id == 0)) {
+			pr_err("Slimbus: invalid slave port id: %d",
+							slave_port_id);
+			ret = -EINVAL;
+			goto err;
+		}
+		slave_port_id += SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS;
+		/* look for the valid port range and chose the
+		 * payload accordingly
+		 */
+		if ((slave_port_id >
+				SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID) &&
+			(slave_port_id <
+			 SB_PGD_RX_PORT_MULTI_CHANNEL_0_END_PORT_ID)) {
+				payload_rx = payload_rx  |
+				(1 <<
+				(slave_port_id -
+				SB_PGD_RX_PORT_MULTI_CHANNEL_0_START_PORT_ID));
+		} else {
+			ret = -EINVAL;
+			goto err;
+		}
+		multi_chan_cfg_reg_addr =
+				SB_PGD_RX_PORT_MULTI_CHANNEL_0(slave_port_id);
+		/* write to interface device */
+		ret = tabla_interface_reg_write(tab, multi_chan_cfg_reg_addr,
+				payload_rx);
+		if (ret < 0) {
+			pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
+							__func__,
+							multi_chan_cfg_reg_addr,
+							payload_rx, ret);
+			goto err;
+		}
+		/* configure the slave port for water mark and enable*/
+		wm_payload = (SLAVE_PORT_WATER_MARK_VALUE <<
+				SLAVE_PORT_WATER_MARK_SHIFT) +
+				SLAVE_PORT_ENABLE;
+		ret = tabla_interface_reg_write(tab,
+				SB_PGD_PORT_CFG_BYTE_ADDR(slave_port_id),
+				wm_payload);
+		if (ret < 0) {
+			pr_err("%s:watermark set failure for port[%d] ret[%d]",
+						__func__, slave_port_id, ret);
+		}
+	}
+
+	/* slim_define_ch api */
+	prop.prot = SLIM_AUTO_ISO;
+	prop.baser = SLIM_RATE_4000HZ;
+	prop.dataf = SLIM_CH_DATAF_NOT_DEFINED;
+	prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE;
+	prop.ratem = (rate/4000);
+	prop.sampleszbits = 16;
+
+	ret = slim_define_ch(tab->slim, &prop, ch_h, ch_cnt,
+					true, &grph);
+	if (ret < 0) {
+		pr_err("%s: slim_define_ch failed ret[%d]\n",
+					__func__, ret);
+		goto err;
+	}
+	for (i = 0; i < ch_cnt; i++) {
+		ret = slim_connect_sink(tab->slim, &sph[i],
+							1, ch_h[i]);
+		if (ret < 0) {
+			pr_err("%s: slim_connect_sink failed ret[%d]\n",
+						__func__, ret);
+			goto err_close_slim_sch;
+		}
+	}
+	/* slim_control_ch */
+	ret = slim_control_ch(tab->slim, grph, SLIM_CH_ACTIVATE,
+					true);
+	if (ret < 0) {
+		pr_err("%s: slim_control_ch failed ret[%d]\n",
+				__func__, ret);
+		goto err_close_slim_sch;
+	}
+	for (i = 0; i < ch_cnt; i++) {
+		idx = (ch_num[i] - BASE_CH_NUM -
+				SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
+		rx[idx].grph = grph;
+	}
+	return 0;
+
+err_close_slim_sch:
+	/*  release all acquired handles */
+	tabla_close_slim_sch_rx(tab, ch_num, ch_cnt);
+err:
+	return ret;
+}
+EXPORT_SYMBOL_GPL(tabla_cfg_slim_sch_rx);
+
+/* Enable slimbus slave device for RX path */
+int tabla_cfg_slim_sch_tx(struct tabla *tab, unsigned int *ch_num,
+				unsigned int ch_cnt, unsigned int rate)
+{
+	u8 i = 0;
+	u8  payload_tx_0 = 0, payload_tx_1 = 0, wm_payload = 0;
+	u16 grph;
+	u32 sph[SLIM_MAX_TX_PORTS] = {0};
+	u16 ch_h[SLIM_MAX_TX_PORTS] = {0};
+	u16 idx = 0, slave_port_id;
+	int ret = 0;
+	unsigned short  multi_chan_cfg_reg_addr;
+
+	struct tabla_slim_sch_tx *tx = sh_ch.tx;
+	struct slim_ch prop;
+
+	pr_debug("%s: ch_cnt[%d] rate[%d]\n", __func__, ch_cnt, rate);
+	for (i = 0; i < ch_cnt; i++) {
+		idx = (ch_num[i] - BASE_CH_NUM);
+		ch_h[i] = tx[idx].ch_h;
+		sph[i] = tx[idx].sph;
+		slave_port_id = idx ;
+		if ((slave_port_id > SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS) ||
+		(slave_port_id == 0)) {
+			pr_err("SLIMbus: invalid slave port id: %d",
+							slave_port_id);
+			ret = -EINVAL;
+			goto err;
+		}
+		/* look for the valid port range and chose the
+		 *  payload accordingly
+		 */
+		if (slave_port_id <=
+			SB_PGD_TX_PORT_MULTI_CHANNEL_0_END_PORT_ID) {
+			payload_tx_0 = payload_tx_0 | (1 << slave_port_id);
+		} else if (slave_port_id <
+				SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID) {
+				payload_tx_1 = payload_tx_1 |
+				(1 <<
+				(slave_port_id -
+				SB_PGD_TX_PORT_MULTI_CHANNEL_1_START_PORT_ID));
+		} else {
+			ret = -EINVAL;
+			goto err;
+		}
+		multi_chan_cfg_reg_addr =
+				SB_PGD_TX_PORT_MULTI_CHANNEL_0(slave_port_id);
+		/* write to interface device */
+		ret = tabla_interface_reg_write(tab, multi_chan_cfg_reg_addr,
+				payload_tx_0);
+		if (ret < 0) {
+			pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
+								__func__,
+						multi_chan_cfg_reg_addr,
+						payload_tx_0, ret);
+			goto err;
+		}
+		multi_chan_cfg_reg_addr =
+				SB_PGD_TX_PORT_MULTI_CHANNEL_1(slave_port_id);
+		/* ports 8,9 */
+		ret = tabla_interface_reg_write(tab, multi_chan_cfg_reg_addr,
+				payload_tx_1);
+		if (ret < 0) {
+			pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
+								__func__,
+						multi_chan_cfg_reg_addr,
+						payload_tx_1, ret);
+			goto err;
+		}
+		/* configure the slave port for water mark and enable*/
+		wm_payload = (SLAVE_PORT_WATER_MARK_VALUE <<
+				SLAVE_PORT_WATER_MARK_SHIFT) +
+				SLAVE_PORT_ENABLE;
+		ret = tabla_interface_reg_write(tab,
+				SB_PGD_PORT_CFG_BYTE_ADDR(slave_port_id),
+				wm_payload);
+		if (ret < 0) {
+			pr_err("%s:watermark set failure for port[%d] ret[%d]",
+						__func__,
+						slave_port_id, ret);
+		}
+	}
+
+	/* slim_define_ch api */
+	prop.prot = SLIM_AUTO_ISO;
+	prop.baser = SLIM_RATE_4000HZ;
+	prop.dataf = SLIM_CH_DATAF_NOT_DEFINED;
+	prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE;
+	prop.ratem = (rate/4000);
+	prop.sampleszbits = 16;
+	ret = slim_define_ch(tab->slim, &prop, ch_h, ch_cnt,
+					true, &grph);
+	if (ret < 0) {
+		pr_err("%s: slim_define_ch failed ret[%d]\n",
+					__func__, ret);
+		goto err;
+	}
+	for (i = 0; i < ch_cnt; i++) {
+		ret = slim_connect_src(tab->slim, sph[i],
+							ch_h[i]);
+		if (ret < 0) {
+			pr_err("%s: slim_connect_src failed ret[%d]\n",
+						__func__, ret);
+			goto err;
+		}
+	}
+	/* slim_control_ch */
+	ret = slim_control_ch(tab->slim, grph, SLIM_CH_ACTIVATE,
+					true);
+	if (ret < 0) {
+		pr_err("%s: slim_control_ch failed ret[%d]\n",
+				__func__, ret);
+		goto err;
+	}
+	for (i = 0; i < ch_cnt; i++) {
+		idx = (ch_num[i] - BASE_CH_NUM);
+		tx[idx].grph = grph;
+	}
+	return 0;
+err:
+	/* release all acquired handles */
+	tabla_close_slim_sch_tx(tab, ch_num, ch_cnt);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(tabla_cfg_slim_sch_tx);
+
+int tabla_close_slim_sch_rx(struct tabla *tab, unsigned int *ch_num,
+				unsigned int ch_cnt)
+{
+	u16 grph = 0;
+	u32 sph[SLIM_MAX_RX_PORTS] = {0};
+	int i = 0 , idx = 0;
+	int ret = 0;
+	struct tabla_slim_sch_rx *rx = sh_ch.rx;
+
+	pr_debug("%s: ch_cnt[%d]\n", __func__, ch_cnt);
+	for (i = 0; i < ch_cnt; i++) {
+		idx = (ch_num[i] - BASE_CH_NUM -
+				SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
+		sph[i] = rx[idx].sph;
+		grph = rx[idx].grph;
+	}
+
+	/* slim_disconnect_port */
+	ret = slim_disconnect_ports(tab->slim, sph, ch_cnt);
+	if (ret < 0) {
+		pr_err("%s: slim_disconnect_ports failed ret[%d]\n",
+				__func__, ret);
+	}
+	/* slim_control_ch (REMOVE) */
+	ret = slim_control_ch(tab->slim, grph, SLIM_CH_REMOVE, true);
+	if (ret < 0) {
+		pr_err("%s: slim_control_ch failed ret[%d]\n",
+				__func__, ret);
+		goto err;
+	}
+	for (i = 0; i < ch_cnt; i++) {
+		idx = (ch_num[i] - BASE_CH_NUM -
+				SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
+		rx[idx].grph = 0;
+	}
+err:
+	return ret;
+}
+EXPORT_SYMBOL_GPL(tabla_close_slim_sch_rx);
+
+int tabla_close_slim_sch_tx(struct tabla *tab, unsigned int *ch_num,
+				unsigned int ch_cnt)
+{
+	u16 grph = 0;
+	u32 sph[SLIM_MAX_TX_PORTS] = {0};
+	int ret = 0;
+	int i = 0 , idx = 0;
+	struct tabla_slim_sch_tx *tx = sh_ch.tx;
+
+	pr_debug("%s: ch_cnt[%d]\n", __func__, ch_cnt);
+	for (i = 0; i < ch_cnt; i++) {
+		idx = (ch_num[i] - BASE_CH_NUM);
+		sph[i] = tx[idx].sph;
+		grph = tx[idx].grph;
+	}
+	/* slim_disconnect_port */
+	ret = slim_disconnect_ports(tab->slim, sph, ch_cnt);
+	if (ret < 0) {
+		pr_err("%s: slim_disconnect_ports failed ret[%d]\n",
+				__func__, ret);
+	}
+	/* slim_control_ch (REMOVE) */
+	ret = slim_control_ch(tab->slim, grph, SLIM_CH_REMOVE, true);
+	if (ret < 0) {
+		pr_err("%s: slim_control_ch failed ret[%d]\n",
+				__func__, ret);
+		goto err;
+	}
+	for (i = 0; i < ch_cnt; i++) {
+		idx = (ch_num[i] - BASE_CH_NUM);
+		tx[idx].grph = 0;
+	}
+err:
+	return ret;
+}
+EXPORT_SYMBOL_GPL(tabla_close_slim_sch_tx);
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 8f42e5b..1ecf2f3 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1002,6 +1002,12 @@
 		}
 	}
 
+	/* Clear CDR_EN bit for write operations */
+	if (host->tuning_needed && cmd->mrq->data &&
+			(cmd->mrq->data->flags & MMC_DATA_WRITE))
+		writel_relaxed((readl_relaxed(host->base + MCI_DLL_CONFIG) &
+				~MCI_CDR_EN), host->base + MCI_DLL_CONFIG);
+
 	if ((cmd->flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
 		*c |= MCI_CPSM_PROGENA;
 		host->prog_enable = 1;
@@ -1036,8 +1042,6 @@
 	host->curr.got_dataend = 0;
 	host->curr.got_auto_prog_done = 0;
 
-	memset(&host->pio, 0, sizeof(host->pio));
-
 	datactrl = MCI_DPSM_ENABLE | (data->blksz << 4);
 
 	if (host->curr.wait_for_auto_prog_done)
@@ -1072,17 +1076,21 @@
 
 	/* Is data transfer in PIO mode required? */
 	if (!(datactrl & MCI_DPSM_DMAENABLE)) {
-		host->pio.sg = data->sg;
-		host->pio.sg_len = data->sg_len;
-		host->pio.sg_off = 0;
+		unsigned int sg_miter_flags = SG_MITER_ATOMIC;
 
 		if (data->flags & MMC_DATA_READ) {
+			sg_miter_flags |= SG_MITER_TO_SG;
 			pio_irqmask = MCI_RXFIFOHALFFULLMASK;
 			if (host->curr.xfer_remain < MCI_FIFOSIZE)
 				pio_irqmask |= MCI_RXDATAAVLBLMASK;
-		} else
+		} else {
+			sg_miter_flags |= SG_MITER_FROM_SG;
 			pio_irqmask = MCI_TXFIFOHALFEMPTYMASK |
 					MCI_TXFIFOEMPTYMASK;
+		}
+
+		sg_miter_start(&host->sg_miter, data->sg, data->sg_len,
+				sg_miter_flags);
 	}
 
 	if (data->flags & MMC_DATA_READ)
@@ -1248,6 +1256,7 @@
 	struct msmsdcc_host	*host = dev_id;
 	void __iomem		*base = host->base;
 	uint32_t		status;
+	unsigned long flags;
 
 	spin_lock(&host->lock);
 
@@ -1262,9 +1271,10 @@
 #if IRQ_DEBUG
 	msmsdcc_print_status(host, "irq1-r", status);
 #endif
+	local_irq_save(flags);
 
-	do {
-		unsigned long flags;
+	while (sg_miter_next(&host->sg_miter)) {
+
 		unsigned int remain, len;
 		char *buffer;
 
@@ -1272,12 +1282,8 @@
 				| MCI_RXDATAAVLBL)))
 			break;
 
-		/* Map the current scatter buffer */
-		local_irq_save(flags);
-		buffer = kmap_atomic(sg_page(host->pio.sg),
-				     KM_BIO_SRC_IRQ) + host->pio.sg->offset;
-		buffer += host->pio.sg_off;
-		remain = host->pio.sg->length - host->pio.sg_off;
+		buffer = host->sg_miter.addr;
+		remain = host->sg_miter.length;
 
 		len = 0;
 		if (status & MCI_RXACTIVE)
@@ -1288,11 +1294,7 @@
 		if (len > remain)
 			len = remain;
 
-		/* Unmap the buffer */
-		kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
-		local_irq_restore(flags);
-
-		host->pio.sg_off += len;
+		host->sg_miter.consumed = len;
 		host->curr.xfer_remain -= len;
 		host->curr.data_xfered += len;
 		remain -= len;
@@ -1300,20 +1302,11 @@
 		if (remain) /* Done with this page? */
 			break; /* Nope */
 
-		if (status & MCI_RXACTIVE && host->curr.user_pages)
-			flush_dcache_page(sg_page(host->pio.sg));
-
-		if (!--host->pio.sg_len) {
-			memset(&host->pio, 0, sizeof(host->pio));
-			break;
-		}
-
-		/* Advance to next sg */
-		host->pio.sg++;
-		host->pio.sg_off = 0;
-
 		status = readl_relaxed(base + MMCISTATUS);
-	} while (1);
+	}
+
+	sg_miter_stop(&host->sg_miter);
+	local_irq_restore(flags);
 
 	if (status & MCI_RXACTIVE && host->curr.xfer_remain < MCI_FIFOSIZE) {
 		writel_relaxed((readl_relaxed(host->base + MMCIMASK0) &
@@ -2876,22 +2869,21 @@
  * Select the 3/4 of the range and configure the DLL with the
  * selected DLL clock output phase.
 */
-
 static u8 find_most_appropriate_phase(struct msmsdcc_host *host,
 				u8 *phase_table, u8 total_phases)
 {
-	u8 ret, temp;
-	u8 ranges[16][16] = { {0}, {0} };
+	u8 ret, ranges[16][16] = { {0}, {0} };
 	u8 phases_per_row[16] = {0};
 	int row_index = 0, col_index = 0, selected_row_index = 0, curr_max = 0;
-	int cnt;
+	int i, cnt, phase_0_raw_index = 0, phase_15_raw_index = 0;
+	bool phase_0_found = false, phase_15_found = false;
 
-	for (cnt = 0; cnt <= total_phases; cnt++) {
+	for (cnt = 0; cnt < total_phases; cnt++) {
 		ranges[row_index][col_index] = phase_table[cnt];
 		phases_per_row[row_index] += 1;
 		col_index++;
 
-		if ((cnt + 1) > total_phases) {
+		if ((cnt + 1) == total_phases) {
 			continue;
 		/* check if next phase in phase_table is consecutive or not */
 		} else if ((phase_table[cnt] + 1) != phase_table[cnt + 1]) {
@@ -2900,15 +2892,50 @@
 		}
 	}
 
-	for (cnt = 0; cnt <= total_phases; cnt++) {
+	/* Check if phase-0 is present in first valid window? */
+	if (!ranges[0][0]) {
+		phase_0_found = true;
+		phase_0_raw_index = 0;
+		/* Check if cycle exist between 2 valid windows */
+		for (cnt = 1; cnt <= row_index; cnt++) {
+			if (phases_per_row[cnt]) {
+				for (i = 0; i <= phases_per_row[cnt]; i++) {
+					if (ranges[cnt][i] == 15) {
+						phase_15_found = true;
+						phase_15_raw_index = cnt;
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	/* If 2 valid windows form cycle then merge them as single window */
+	if (phase_0_found && phase_15_found) {
+		/* number of phases in raw where phase 0 is present */
+		u8 phases_0 = phases_per_row[phase_0_raw_index];
+		/* number of phases in raw where phase 15 is present */
+		u8 phases_15 = phases_per_row[phase_15_raw_index];
+
+		cnt = 0;
+		for (i = phases_15; i < (phases_15 + phases_0); i++) {
+			ranges[phase_15_raw_index][i] =
+				ranges[phase_0_raw_index][cnt];
+			cnt++;
+		}
+		phases_per_row[phase_0_raw_index] = 0;
+		phases_per_row[phase_15_raw_index] = phases_15 + phases_0;
+	}
+
+	for (cnt = 0; cnt <= row_index; cnt++) {
 		if (phases_per_row[cnt] > curr_max) {
 			curr_max = phases_per_row[cnt];
 			selected_row_index = cnt;
 		}
 	}
 
-	temp = ((curr_max * 3) / 4);
-	ret = ranges[selected_row_index][temp];
+	i = ((curr_max * 3) / 4) - 1;
+	ret = ranges[selected_row_index][i];
 
 	return ret;
 }
@@ -2981,11 +3008,12 @@
 			!memcmp(data_buf, cmd19_tuning_block, 64)) {
 			/* tuning is successful with this tuning point */
 			tuned_phases[tuned_phase_cnt++] = phase;
+			pr_debug("%s: %s: found good phase = %d\n",
+				mmc_hostname(mmc), __func__, phase);
 		}
 	} while (++phase < 16);
 
 	if (tuned_phase_cnt) {
-		tuned_phase_cnt--;
 		phase = find_most_appropriate_phase(host, tuned_phases,
 							tuned_phase_cnt);
 		/*
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index ee7a3e5..319d721 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -361,7 +361,7 @@
 	struct msmsdcc_sps_data sps;
 	bool			is_dma_mode;
 	bool			is_sps_mode;
-	struct msmsdcc_pio_data	pio;
+	struct sg_mapping_iter sg_miter;
 
 #ifdef CONFIG_HAS_EARLYSUSPEND
 	struct early_suspend early_suspend;
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index 02d1c39..d053cd6 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -1886,7 +1886,7 @@
 	}
 
 
-	dev->rclk = clk_get(dev->dev, "audio_slimbus_clk");
+	dev->rclk = clk_get(dev->dev, "core_clk");
 	if (!dev->rclk) {
 		dev_err(dev->dev, "slimbus clock not found");
 		goto err_clk_get_failed;
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index ed80b1b..ef28844 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -51,10 +51,7 @@
 	cpu_policy->user_policy.max = max_freq;
 
 	ret = cpufreq_update_policy(cpu);
-	if (ret)
-		pr_err("msm_thermal: cpufreq update to core%d %d err:%d\n",
-				cpu, max_freq, ret);
-	else
+	if (!ret)
 		pr_info("msm_thermal: Limiting core%d max frequency to %d\n",
 			cpu, max_freq);
 
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 84cb3f5..3aa4553 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -3,7 +3,7 @@
  * MSM 7k High speed uart driver
  *
  * Copyright (c) 2008 Google Inc.
- * Copyright (c) 2007-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
  * Modified: Nick Pelly <npelly@google.com>
  *
  * All source code in this file is licensed under the following license
@@ -656,7 +656,6 @@
 	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
 
 	spin_lock_irqsave(&uport->lock, flags);
-	clk_enable(msm_uport->clk);
 
 	/*
 	 * Disable Rx channel of UARTDM
@@ -764,9 +763,7 @@
 	}
 
 	msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg);
-	/* calling other hardware component here clk_disable API. */
 	mb();
-	clk_disable(msm_uport->clk);
 	spin_unlock_irqrestore(&uport->lock, flags);
 }
 
@@ -778,16 +775,11 @@
 {
 	unsigned int data;
 	unsigned int ret = 0;
-	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
-
-	clk_enable(msm_uport->clk);
 
 	data = msm_hs_read(uport, UARTDM_SR_ADDR);
 	if (data & UARTDM_SR_TXEMT_BMSK)
 		ret = TIOCSER_TEMT;
 
-	clk_disable(msm_uport->clk);
-
 	return ret;
 }
 EXPORT_SYMBOL(msm_hs_tx_empty);
@@ -817,8 +809,6 @@
 	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
 	unsigned int data;
 
-	clk_enable(msm_uport->clk);
-
 	/* disable dlink */
 	data = msm_hs_read(uport, UARTDM_DMEN_ADDR);
 	data &= ~UARTDM_RX_DM_EN_BMSK;
@@ -835,8 +825,6 @@
 	}
 	if (msm_uport->rx.flush != FLUSH_SHUTDOWN)
 		msm_uport->rx.flush = FLUSH_STOP;
-
-	clk_disable(msm_uport->clk);
 }
 
 /*  Transmit the next chunk of data */
@@ -1011,7 +999,6 @@
 
 	spin_lock_irqsave(&uport->lock, flags);
 
-	clk_enable(msm_uport->clk);
 	msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_DISABLE);
 
 	/* overflow is not connect to data in a FIFO */
@@ -1085,7 +1072,6 @@
 		schedule_delayed_work(&msm_uport->rx.flip_insert_work
 				      , msecs_to_jiffies(RETRY_TIMEOUT));
 	}
-	clk_disable(msm_uport->clk);
 	/* release wakelock in 500ms, not immediately, because higher layers
 	 * don't always take wakelocks when they should */
 	wake_lock_timeout(&msm_uport->rx.wake_lock, HZ / 2);
@@ -1100,15 +1086,11 @@
 {
 	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
 
-	clk_enable(msm_uport->clk);
-
 	if (msm_uport->tx.tx_ready_int_en == 0) {
 		msm_uport->tx.tx_ready_int_en = 1;
 		if (msm_uport->tx.dma_in_flight == 0)
 			msm_hs_submit_tx_locked(uport);
 	}
-
-	clk_disable(msm_uport->clk);
 }
 
 /*
@@ -1138,14 +1120,12 @@
 				tlet_ptr, struct msm_hs_port, tx.tlet);
 
 	spin_lock_irqsave(&(msm_uport->uport.lock), flags);
-	clk_enable(msm_uport->clk);
 
 	msm_uport->imr_reg |= UARTDM_ISR_TX_READY_BMSK;
 	msm_hs_write(&(msm_uport->uport), UARTDM_IMR_ADDR, msm_uport->imr_reg);
 	/* Calling clk API. Hence mb() requires. */
 	mb();
 
-	clk_disable(msm_uport->clk);
 	spin_unlock_irqrestore(&(msm_uport->uport.lock), flags);
 }
 
@@ -1198,9 +1178,6 @@
 {
 	unsigned int set_rts;
 	unsigned int data;
-	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
-
-	clk_enable(msm_uport->clk);
 
 	/* RTS is active low */
 	set_rts = TIOCM_RTS & mctrl ? 0 : 1;
@@ -1217,9 +1194,7 @@
 		data |= UARTDM_MR1_RX_RDY_CTL_BMSK;
 		msm_hs_write(uport, UARTDM_MR1_ADDR, data);
 	}
-	/* Calling CLOCK API. Hence mb() requires. */
 	mb();
-	clk_disable(msm_uport->clk);
 }
 
 void msm_hs_set_mctrl(struct uart_port *uport,
@@ -1238,16 +1213,11 @@
 {
 	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
 
-	clk_enable(msm_uport->clk);
-
 	/* Enable DELTA_CTS Interrupt */
 	msm_uport->imr_reg |= UARTDM_ISR_DELTA_CTS_BMSK;
 	msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg);
-	/* Calling CLOCK API. Hence mb() requires here. */
 	mb();
 
-	clk_disable(msm_uport->clk);
-
 }
 
 /*
@@ -1259,14 +1229,10 @@
 static void msm_hs_break_ctl(struct uart_port *uport, int ctl)
 {
 	unsigned long flags;
-	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
 
 	spin_lock_irqsave(&uport->lock, flags);
-	clk_enable(msm_uport->clk);
 	msm_hs_write(uport, UARTDM_CR_ADDR, ctl ? START_BREAK : STOP_BREAK);
-	/* Calling CLOCK API. Hence mb() requires here. */
 	mb();
-	clk_disable(msm_uport->clk);
 	spin_unlock_irqrestore(&uport->lock, flags);
 }
 
@@ -1295,18 +1261,12 @@
 /*  Handle CTS changes (Called from interrupt handler) */
 static void msm_hs_handle_delta_cts_locked(struct uart_port *uport)
 {
-	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
-
-	clk_enable(msm_uport->clk);
-
 	/* clear interrupt */
 	msm_hs_write(uport, UARTDM_CR_ADDR, RESET_CTS);
 	/* Calling CLOCK API. Hence mb() requires here. */
 	mb();
 	uport->icount.cts++;
 
-	clk_disable(msm_uport->clk);
-
 	/* clear the IOCTL TIOCMIWAIT if called */
 	wake_up_interruptible(&uport->state->port.delta_msr_wait);
 }
@@ -1999,8 +1959,6 @@
 	tasklet_kill(&msm_uport->rx.tlet);
 	cancel_delayed_work_sync(&msm_uport->rx.flip_insert_work);
 
-	clk_enable(msm_uport->clk);
-
 	pm_runtime_disable(uport->dev);
 	pm_runtime_set_suspended(uport->dev);
 
@@ -2018,7 +1976,6 @@
 	 */
 	mb();
 
-	clk_disable(msm_uport->clk);  /* to balance local clk_enable() */
 	if (msm_uport->clk_state != MSM_HS_CLK_OFF) {
 		clk_disable(msm_uport->clk);  /* to balance clk_state */
 		if (msm_uport->pclk)
diff --git a/drivers/tty/serial/msm_serial_hs_lite.c b/drivers/tty/serial/msm_serial_hs_lite.c
index 6e3982e..f49769d 100644
--- a/drivers/tty/serial/msm_serial_hs_lite.c
+++ b/drivers/tty/serial/msm_serial_hs_lite.c
@@ -142,20 +142,21 @@
 
 	if (enable) {
 
-		ret = clk_enable(msm_hsl_port->clk);
+		ret = clk_prepare_enable(msm_hsl_port->clk);
 		if (ret)
 			goto err;
 		if (msm_hsl_port->pclk) {
-			ret = clk_enable(msm_hsl_port->pclk);
+			ret = clk_prepare_enable(msm_hsl_port->pclk);
 			if (ret) {
-				clk_disable(msm_hsl_port->clk);
+				clk_disable_unprepare(msm_hsl_port->clk);
 				goto err;
 			}
 		}
 	} else {
-		clk_disable(msm_hsl_port->clk);
+
+		clk_disable_unprepare(msm_hsl_port->clk);
 		if (msm_hsl_port->pclk)
-			clk_disable(msm_hsl_port->pclk);
+			clk_disable_unprepare(msm_hsl_port->pclk);
 	}
 err:
 	return ret;
@@ -245,53 +246,37 @@
 {
 	struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port);
 
-	clk_en(port, 1);
-
 	msm_hsl_port->imr &= ~UARTDM_ISR_TXLEV_BMSK;
 	msm_hsl_write(port, msm_hsl_port->imr,
 		regmap[msm_hsl_port->ver_id][UARTDM_IMR]);
-
-	clk_en(port, 0);
 }
 
 static void msm_hsl_start_tx(struct uart_port *port)
 {
 	struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port);
 
-	clk_en(port, 1);
-
 	msm_hsl_port->imr |= UARTDM_ISR_TXLEV_BMSK;
 	msm_hsl_write(port, msm_hsl_port->imr,
 		regmap[msm_hsl_port->ver_id][UARTDM_IMR]);
-
-	clk_en(port, 0);
 }
 
 static void msm_hsl_stop_rx(struct uart_port *port)
 {
 	struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port);
 
-	clk_en(port, 1);
-
 	msm_hsl_port->imr &= ~(UARTDM_ISR_RXLEV_BMSK |
 			       UARTDM_ISR_RXSTALE_BMSK);
 	msm_hsl_write(port, msm_hsl_port->imr,
 		regmap[msm_hsl_port->ver_id][UARTDM_IMR]);
-
-	clk_en(port, 0);
 }
 
 static void msm_hsl_enable_ms(struct uart_port *port)
 {
 	struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port);
 
-	clk_en(port, 1);
-
 	msm_hsl_port->imr |= UARTDM_ISR_DELTA_CTS_BMSK;
 	msm_hsl_write(port, msm_hsl_port->imr,
 		regmap[msm_hsl_port->ver_id][UARTDM_IMR]);
-
-	clk_en(port, 0);
 }
 
 static void handle_rx(struct uart_port *port, unsigned int misr)
@@ -460,7 +445,6 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&port->lock, flags);
-	clk_en(port, 1);
 	vid = msm_hsl_port->ver_id;
 	misr = msm_hsl_read(port, regmap[vid][UARTDM_MISR]);
 	/* disable interrupt */
@@ -482,7 +466,6 @@
 
 	/* restore interrupt */
 	msm_hsl_write(port, msm_hsl_port->imr, regmap[vid][UARTDM_IMR]);
-	clk_en(port, 0);
 	spin_unlock_irqrestore(&port->lock, flags);
 
 	return IRQ_HANDLED;
@@ -490,14 +473,11 @@
 
 static unsigned int msm_hsl_tx_empty(struct uart_port *port)
 {
-	unsigned int vid = UART_TO_MSM(port)->ver_id;
 	unsigned int ret;
+	unsigned int vid = UART_TO_MSM(port)->ver_id;
 
-	clk_en(port, 1);
 	ret = (msm_hsl_read(port, regmap[vid][UARTDM_SR]) &
 	       UARTDM_SR_TXEMT_BMSK) ? TIOCSER_TEMT : 0;
-	clk_en(port, 0);
-
 	return ret;
 }
 
@@ -525,8 +505,6 @@
 	unsigned int mr;
 	unsigned int loop_mode;
 
-	clk_en(port, 1);
-
 	mr = msm_hsl_read(port, regmap[vid][UARTDM_MR1]);
 
 	if (!(mctrl & TIOCM_RTS)) {
@@ -551,22 +529,16 @@
 		msm_hsl_write(port, UARTDM_CR_RX_EN_BMSK
 		      | UARTDM_CR_TX_EN_BMSK, regmap[vid][UARTDM_CR]);
 	}
-
-	clk_en(port, 0);
 }
 
 static void msm_hsl_break_ctl(struct uart_port *port, int break_ctl)
 {
 	unsigned int vid = UART_TO_MSM(port)->ver_id;
 
-	clk_en(port, 1);
-
 	if (break_ctl)
 		msm_hsl_write(port, START_BREAK, regmap[vid][UARTDM_CR]);
 	else
 		msm_hsl_write(port, STOP_BREAK, regmap[vid][UARTDM_CR]);
-
-	clk_en(port, 0);
 }
 
 static void msm_hsl_set_baud_rate(struct uart_port *port, unsigned int baud)
@@ -774,14 +746,10 @@
 	const struct msm_serial_hslite_platform_data *pdata =
 					pdev->dev.platform_data;
 
-	clk_en(port, 1);
-
 	msm_hsl_port->imr = 0;
 	/* disable interrupts */
 	msm_hsl_write(port, 0, regmap[msm_hsl_port->ver_id][UARTDM_IMR]);
 
-	clk_en(port, 0);
-
 	free_irq(port->irq, port);
 
 #ifndef CONFIG_PM_RUNTIME
@@ -806,7 +774,6 @@
 	unsigned int vid;
 
 	spin_lock_irqsave(&port->lock, flags);
-	clk_en(port, 1);
 
 	/* calculate and set baud rate */
 	baud = uart_get_baud_rate(port, termios, old, 300, 460800);
@@ -872,7 +839,6 @@
 
 	uart_update_timeout(port, termios->c_cflag, baud);
 
-	clk_en(port, 0);
 	spin_unlock_irqrestore(&port->lock, flags);
 }
 
@@ -971,13 +937,13 @@
 	}
 	if (msm_serial_hsl_has_gsbi(port)) {
 		if (msm_hsl_port->pclk)
-			clk_enable(msm_hsl_port->pclk);
+			clk_prepare_enable(msm_hsl_port->pclk);
 		if ((ioread32(msm_hsl_port->mapped_gsbi + GSBI_CONTROL_ADDR) &
 			GSBI_PROTOCOL_I2C_UART) != GSBI_PROTOCOL_I2C_UART)
 			iowrite32(GSBI_PROTOCOL_I2C_UART,
 				msm_hsl_port->mapped_gsbi + GSBI_CONTROL_ADDR);
 		if (msm_hsl_port->pclk)
-			clk_disable(msm_hsl_port->pclk);
+			clk_disable_unprepare(msm_hsl_port->pclk);
 	}
 }
 
@@ -1384,10 +1350,10 @@
 	 * condition with the earlyprintk handover mechanism.
 	 */
 	if (msm_hsl_port->pclk)
-		clk_enable(msm_hsl_port->pclk);
+		clk_prepare_enable(msm_hsl_port->pclk);
 	ret = uart_add_one_port(&msm_hsl_uart_driver, port);
 	if (msm_hsl_port->pclk)
-		clk_disable(msm_hsl_port->pclk);
+		clk_disable_unprepare(msm_hsl_port->pclk);
 	return ret;
 }
 
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 35327cc..ff4bbad 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -858,6 +858,32 @@
 	*idx = (*idx + 1) & (DBG_DATA_MAX-1);
 }
 
+
+static unsigned int ep_addr_txdbg_mask;
+module_param(ep_addr_txdbg_mask, uint, S_IRUGO | S_IWUSR);
+static unsigned int ep_addr_rxdbg_mask;
+module_param(ep_addr_rxdbg_mask, uint, S_IRUGO | S_IWUSR);
+
+static int allow_dbg_print(u8 addr)
+{
+	int dir, num;
+
+	/* allow bus wide events */
+	if (addr == 0xff)
+		return 1;
+
+	dir = addr & USB_ENDPOINT_DIR_MASK ? TX : RX;
+	num = addr & ~USB_ENDPOINT_DIR_MASK;
+	num = 1 << num;
+
+	if ((dir == TX) && (num & ep_addr_txdbg_mask))
+		return 1;
+	if ((dir == RX) && (num & ep_addr_rxdbg_mask))
+		return 1;
+
+	return 0;
+}
+
 /**
  * dbg_print:  prints the common part of the event
  * @addr:   endpoint address
@@ -871,6 +897,9 @@
 	unsigned int stamp;
 	unsigned long flags;
 
+	if (!allow_dbg_print(addr))
+		return;
+
 	write_lock_irqsave(&dbg_data.lck, flags);
 
 	do_gettimeofday(&tval);
@@ -1407,7 +1436,7 @@
 
 	n = hw_ep_bit(mEp->num, mEp->dir);
 	pr_info("%s: prime:%08x stat:%08x ep#%d dir:%s"
-			"dTD_update_fail_count: %lu"
+			"dTD_update_fail_count: %lu "
 			"mEp->dTD_update_fail_count: %lu\n", __func__,
 			hw_cread(CAP_ENDPTPRIME, ~0),
 			hw_cread(CAP_ENDPTSTAT, ~0),
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 30cbdd8..4e1895f 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -37,6 +37,7 @@
 #include <linux/usb/msm_hsusb_hw.h>
 #include <linux/regulator/consumer.h>
 #include <linux/mfd/pm8xxx/pm8921-charger.h>
+#include <linux/mfd/pm8xxx/misc.h>
 #include <linux/pm_qos_params.h>
 #include <linux/power_supply.h>
 
@@ -571,6 +572,9 @@
 		writel_relaxed(val, USB_OTGSC);
 		ulpi_write(otg, ulpi_val, ULPI_USB_INT_EN_RISE);
 		ulpi_write(otg, ulpi_val, ULPI_USB_INT_EN_FALL);
+	} else if (pdata->otg_control == OTG_PMIC_CONTROL) {
+		/* Enable PMIC pull-up */
+		pm8xxx_usb_id_pullup(1);
 	}
 
 	return 0;
@@ -1307,6 +1311,8 @@
 		ulpi_write(otg, 0x01, 0x0C);
 		ulpi_write(otg, 0x10, 0x0F);
 		ulpi_write(otg, 0x10, 0x12);
+		/* Disable PMIC ID pull-up */
+		pm8xxx_usb_id_pullup(0);
 		/* Enable ACA ID detection */
 		ulpi_write(otg, 0x20, 0x85);
 		aca_id_turned_on = true;
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index b590c41..d3f8b2b 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -495,6 +495,14 @@
 	---help---
 	  Support for LCDC + MIPI panel auto detect
 
+config FB_MSM_LVDS_MIPI_PANEL_DETECT
+	bool "LVDS + MIPI Panel Auto Detect"
+	select FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT
+	select FB_MSM_LVDS_CHIMEI_WXGA
+	select FB_MSM_MIPI_CHIMEI_WXGA
+	---help---
+	  Support for LVDS + MIPI panel auto detect
+
 config FB_MSM_MDDI_PRISM_WVGA
 	bool "MDDI Prism WVGA Panel"
 	select FB_MSM_MDDI
diff --git a/drivers/video/msm/lvds.c b/drivers/video/msm/lvds.c
index 7ef437c..a69c64f 100644
--- a/drivers/video/msm/lvds.c
+++ b/drivers/video/msm/lvds.c
@@ -19,9 +19,10 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 #include <linux/delay.h>
-#include <mach/hardware.h>
 #include <linux/io.h>
-
+#include <mach/hardware.h>
+#include <mach/msm_iomap.h>
+#include <mach/clk.h>
 #include <asm/system.h>
 #include <asm/mach-types.h>
 #include <linux/semaphore.h>
@@ -29,10 +30,9 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
-#include <mach/clk.h>
 
 #include "msm_fb.h"
-
+#include "mdp4.h"
 static int lvds_probe(struct platform_device *pdev);
 static int lvds_remove(struct platform_device *pdev);
 
@@ -57,6 +57,126 @@
 
 static struct lcdc_platform_data *lvds_pdata;
 
+static void lvds_init(struct msm_fb_data_type *mfd)
+{
+	unsigned int lvds_intf, lvds_phy_cfg0;
+
+	MDP_OUTP(MDP_BASE + 0xc2034, 0x33);
+	usleep(1000);
+
+	/* LVDS PHY PLL configuration */
+	MDP_OUTP(MDP_BASE + 0xc3000, 0x08);
+	MDP_OUTP(MDP_BASE + 0xc3004, 0x87);
+	MDP_OUTP(MDP_BASE + 0xc3008, 0x30);
+	MDP_OUTP(MDP_BASE + 0xc300c, 0x06);
+	MDP_OUTP(MDP_BASE + 0xc3014, 0x20);
+	MDP_OUTP(MDP_BASE + 0xc3018, 0x0F);
+	MDP_OUTP(MDP_BASE + 0xc301c, 0x01);
+	MDP_OUTP(MDP_BASE + 0xc3020, 0x41);
+	MDP_OUTP(MDP_BASE + 0xc3024, 0x0d);
+	MDP_OUTP(MDP_BASE + 0xc3028, 0x07);
+	MDP_OUTP(MDP_BASE + 0xc302c, 0x00);
+	MDP_OUTP(MDP_BASE + 0xc3030, 0x1c);
+	MDP_OUTP(MDP_BASE + 0xc3034, 0x01);
+	MDP_OUTP(MDP_BASE + 0xc3038, 0x00);
+	MDP_OUTP(MDP_BASE + 0xc3040, 0xC0);
+	MDP_OUTP(MDP_BASE + 0xc3044, 0x00);
+	MDP_OUTP(MDP_BASE + 0xc3048, 0x30);
+	MDP_OUTP(MDP_BASE + 0xc304c, 0x00);
+
+	MDP_OUTP(MDP_BASE + 0xc3000, 0x11);
+	MDP_OUTP(MDP_BASE + 0xc3064, 0x05);
+	MDP_OUTP(MDP_BASE + 0xc3050, 0x20);
+
+	MDP_OUTP(MDP_BASE + 0xc3000, 0x01);
+	/* Wait until LVDS PLL is locked and ready */
+	while (!readl_relaxed(MDP_BASE + 0xc3080))
+		cpu_relax();
+
+	writel_relaxed(0x00, mmss_cc_base + 0x0264);
+	writel_relaxed(0x00, mmss_cc_base + 0x0094);
+
+	writel_relaxed(0x02, mmss_cc_base + 0x00E4);
+
+	writel_relaxed((0x80 | readl_relaxed(mmss_cc_base + 0x00E4)),
+	       mmss_cc_base + 0x00E4);
+	usleep(1000);
+	writel_relaxed((~0x80 & readl_relaxed(mmss_cc_base + 0x00E4)),
+	       mmss_cc_base + 0x00E4);
+
+	writel_relaxed(0x05, mmss_cc_base + 0x0094);
+	writel_relaxed(0x02, mmss_cc_base + 0x0264);
+	/* Wait until LVDS pixel clock output is enabled */
+	mb();
+
+	if (mfd->panel_info.bpp == 24) {
+		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
+		MDP_OUTP(MDP_BASE +  0xc2014, 0x03040508);
+		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
+		MDP_OUTP(MDP_BASE +  0xc2018, 0x00000102);
+		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
+		MDP_OUTP(MDP_BASE +  0xc201c, 0x0c0d1011);
+		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
+		MDP_OUTP(MDP_BASE +  0xc2020, 0x00090a0b);
+		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
+		MDP_OUTP(MDP_BASE +  0xc2024, 0x151a191a);
+		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
+		MDP_OUTP(MDP_BASE +  0xc2028, 0x00121314);
+		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_3_TO_0 */
+		MDP_OUTP(MDP_BASE +  0xc202c, 0x1706071b);
+		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_6_TO_4 */
+		MDP_OUTP(MDP_BASE +  0xc2030, 0x000e0f16);
+
+		if (mfd->panel_info.lvds.channel_mode ==
+			LVDS_DUAL_CHANNEL_MODE) {
+			lvds_intf = 0x0001ff80;
+			lvds_phy_cfg0 = BIT(6) | BIT(7);
+			if (mfd->panel_info.lvds.channel_swap)
+				lvds_intf |= BIT(4);
+		} else {
+			lvds_intf = 0x00010f84;
+			lvds_phy_cfg0 = BIT(6);
+		}
+	} else if (mfd->panel_info.bpp == 18) {
+		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
+		MDP_OUTP(MDP_BASE +  0xc2014, 0x03040508);
+		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
+		MDP_OUTP(MDP_BASE +  0xc2018, 0x00000102);
+		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
+		MDP_OUTP(MDP_BASE +  0xc201c, 0x0c0d1011);
+		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
+		MDP_OUTP(MDP_BASE +  0xc2020, 0x00090a0b);
+		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
+		MDP_OUTP(MDP_BASE +  0xc2024, 0x1518191a);
+		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
+		MDP_OUTP(MDP_BASE +  0xc2028, 0x00121314);
+
+		if (mfd->panel_info.lvds.channel_mode ==
+			LVDS_DUAL_CHANNEL_MODE) {
+			lvds_intf = 0x00017788;
+			lvds_phy_cfg0 = BIT(6) | BIT(7);
+			if (mfd->panel_info.lvds.channel_swap)
+				lvds_intf |= BIT(4);
+		} else {
+			lvds_intf = 0x0001078c;
+			lvds_phy_cfg0 = BIT(6);
+		}
+	}
+
+	/* MDP_LVDSPHY_CFG0 */
+	MDP_OUTP(MDP_BASE +  0xc3100, lvds_phy_cfg0);
+	/* MDP_LCDC_LVDS_INTF_CTL */
+	MDP_OUTP(MDP_BASE +  0xc2000, lvds_intf);
+	MDP_OUTP(MDP_BASE +  0xc3108, 0x30);
+	lvds_phy_cfg0 |= BIT(4);
+
+	/* Wait until LVDS PHY registers are configured */
+	mb();
+	usleep(1);
+	/* MDP_LVDSPHY_CFG0, enable serialization */
+	MDP_OUTP(MDP_BASE +  0xc3100, lvds_phy_cfg0);
+}
+
 static int lvds_off(struct platform_device *pdev)
 {
 	int ret = 0;
@@ -65,7 +185,8 @@
 	mfd = platform_get_drvdata(pdev);
 	ret = panel_next_off(pdev);
 
-	clk_disable(lvds_clk);
+	if (lvds_clk)
+		clk_disable(lvds_clk);
 
 	if (lvds_pdata && lvds_pdata->lcdc_power_save)
 		lvds_pdata->lcdc_power_save(0);
@@ -97,22 +218,24 @@
 #endif
 	mfd = platform_get_drvdata(pdev);
 
-	mfd->fbi->var.pixclock = clk_round_rate(lvds_clk,
-					mfd->fbi->var.pixclock);
-	ret = clk_set_rate(lvds_clk, mfd->fbi->var.pixclock);
-	if (ret) {
-		pr_err("%s: Can't set lvds clock to rate %u\n",
-			__func__, mfd->fbi->var.pixclock);
-		goto out;
+	if (lvds_clk) {
+		mfd->fbi->var.pixclock = clk_round_rate(lvds_clk,
+			mfd->fbi->var.pixclock);
+		ret = clk_set_rate(lvds_clk, mfd->fbi->var.pixclock);
+		if (ret) {
+			pr_err("%s: Can't set lvds clock to rate %u\n",
+				__func__, mfd->fbi->var.pixclock);
+			goto out;
+		}
+		clk_enable(lvds_clk);
 	}
 
-	clk_enable(lvds_clk);
-
 	if (lvds_pdata && lvds_pdata->lcdc_power_save)
 		lvds_pdata->lcdc_power_save(1);
 	if (lvds_pdata && lvds_pdata->lcdc_gpio_config)
 		ret = lvds_pdata->lcdc_gpio_config(1);
 
+	lvds_init(mfd);
 	ret = panel_next_on(pdev);
 
 out:
@@ -182,8 +305,11 @@
 		mfd->fb_imgType = MDP_RGB_565;
 
 	fbi = mfd->fbi;
-	fbi->var.pixclock = clk_round_rate(lvds_clk,
-					mfd->panel_info.clk_rate);
+	if (lvds_clk) {
+		fbi->var.pixclock = clk_round_rate(lvds_clk,
+			mfd->panel_info.clk_rate);
+	}
+
 	fbi->var.left_margin = mfd->panel_info.lcdc.h_back_porch;
 	fbi->var.right_margin = mfd->panel_info.lcdc.h_front_porch;
 	fbi->var.upper_margin = mfd->panel_info.lcdc.v_back_porch;
@@ -224,9 +350,9 @@
 static int __init lvds_driver_init(void)
 {
 	lvds_clk = clk_get(NULL, "lvds_clk");
-	if (IS_ERR(lvds_clk)) {
+	if (IS_ERR_OR_NULL(lvds_clk)) {
 		pr_err("Couldnt find lvds_clk\n");
-		return -EINVAL;
+		lvds_clk = NULL;
 	}
 
 	return lvds_register_driver();
diff --git a/drivers/video/msm/lvds_chimei_wxga.c b/drivers/video/msm/lvds_chimei_wxga.c
index 2c6b6d4..9a385b9 100644
--- a/drivers/video/msm/lvds_chimei_wxga.c
+++ b/drivers/video/msm/lvds_chimei_wxga.c
@@ -11,9 +11,19 @@
  */
 
 #include "msm_fb.h"
+#include <linux/pwm.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
 
-static struct msm_panel_common_pdata *cm_pdata;
+#define LVDS_CHIMEI_PWM_FREQ_HZ 300
+#define LVDS_CHIMEI_PWM_PERIOD_USEC (USEC_PER_SEC / LVDS_CHIMEI_PWM_FREQ_HZ)
+#define LVDS_CHIMEI_PWM_LEVEL 255
+#define LVDS_CHIMEI_PWM_DUTY_LEVEL \
+	(LVDS_CHIMEI_PWM_PERIOD_USEC / LVDS_CHIMEI_PWM_LEVEL)
+
+
+static struct lvds_panel_platform_data *cm_pdata;
 static struct platform_device *cm_fbpdev;
+static struct pwm_device *bl_lpm;
 
 static int lvds_chimei_panel_on(struct platform_device *pdev)
 {
@@ -27,6 +37,26 @@
 
 static void lvds_chimei_set_backlight(struct msm_fb_data_type *mfd)
 {
+	int ret;
+
+	pr_debug("%s: back light level %d\n", __func__, mfd->bl_level);
+
+	if (bl_lpm) {
+		ret = pwm_config(bl_lpm, LVDS_CHIMEI_PWM_DUTY_LEVEL *
+			mfd->bl_level, LVDS_CHIMEI_PWM_PERIOD_USEC);
+		if (ret) {
+			pr_err("pwm_config on lpm failed %d\n", ret);
+			return;
+		}
+		if (mfd->bl_level) {
+			ret = pwm_enable(bl_lpm);
+			if (ret)
+				pr_err("pwm enable/disable on lpm failed"
+					"for bl %d\n",	mfd->bl_level);
+		} else {
+			pwm_disable(bl_lpm);
+		}
+	}
 }
 
 static int __devinit lvds_chimei_probe(struct platform_device *pdev)
@@ -40,6 +70,17 @@
 		return 0;
 	}
 
+	if (cm_pdata != NULL)
+		bl_lpm = pwm_request(cm_pdata->gpio[0],
+			"backlight");
+
+	if (bl_lpm == NULL || IS_ERR(bl_lpm)) {
+		pr_err("%s pwm_request() failed\n", __func__);
+		bl_lpm = NULL;
+	}
+	pr_debug("bl_lpm = %p lpm = %d\n", bl_lpm,
+		cm_pdata->gpio[0]);
+
 	cm_fbpdev = msm_fb_add_device(pdev);
 	if (!cm_fbpdev) {
 		dev_err(&pdev->dev, "failed to add msm_fb device\n");
@@ -85,8 +126,8 @@
 		return ret;
 
 	pinfo = &lvds_chimei_panel_data.panel_info;
-	pinfo->xres = 320;
-	pinfo->yres = 240;
+	pinfo->xres = 1366;
+	pinfo->yres = 768;
 	MSM_FB_SINGLE_MODE_PANEL(pinfo);
 	pinfo->type = LVDS_PANEL;
 	pinfo->pdest = DISPLAY_1;
@@ -94,7 +135,7 @@
 	pinfo->bpp = 24;
 	pinfo->fb_num = 2;
 	pinfo->clk_rate = 75000000;
-	pinfo->bl_max = 15;
+	pinfo->bl_max = 255;
 	pinfo->bl_min = 1;
 
 	/*
@@ -107,12 +148,14 @@
 	pinfo->lcdc.v_back_porch = 0;
 	pinfo->lcdc.v_front_porch = 38;
 	pinfo->lcdc.v_pulse_width = 20;
-	pinfo->lcdc.border_clr = 0xffff00;
 	pinfo->lcdc.underflow_clr = 0xff;
 	pinfo->lcdc.hsync_skew = 0;
 	pinfo->lvds.channel_mode = LVDS_SINGLE_CHANNEL_MODE;
-	pinfo->lcdc.xres_pad = 1046;
-	pinfo->lcdc.yres_pad = 528;
+
+	/* Set border color, padding only for reducing active display region */
+	pinfo->lcdc.border_clr = 0x0;
+	pinfo->lcdc.xres_pad = 0;
+	pinfo->lcdc.yres_pad = 0;
 
 	ret = platform_device_register(&this_device);
 	if (ret)
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 4c443ea..43520e0 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -1221,7 +1221,7 @@
 		return -EINVAL;
 	}
 	if (mdp_bus_scale_handle < 1) {
-		printk(KERN_ERR "%s invalid bus handle\n", __func__);
+		pr_debug("%s invalid bus handle\n", __func__);
 		return -EINVAL;
 	}
 	return msm_bus_scale_client_update_request(mdp_bus_scale_handle,
@@ -1318,7 +1318,7 @@
 	if (IS_ERR(mdp_pclk))
 		mdp_pclk = NULL;
 
-	if (mdp_rev == MDP_REV_42) {
+	if (mdp_rev >= MDP_REV_42) {
 		mdp_lut_clk = clk_get(NULL, "lut_mdp");
 		if (IS_ERR(mdp_lut_clk)) {
 			ret = PTR_ERR(mdp_lut_clk);
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 7b2b2c2..155bc54 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -26,6 +26,7 @@
 extern spinlock_t mdp_spin_lock;
 extern struct mdp4_statistic mdp4_stat;
 extern uint32 mdp4_extn_disp;
+extern char *mmss_cc_base;	/* mutimedia sub system clock control */
 
 #define MDP4_OVERLAYPROC0_BASE	0x10000
 #define MDP4_OVERLAYPROC1_BASE	0x18000
@@ -417,6 +418,7 @@
 			struct mdp4_overlay_pipe *pipe);
 int mdp4_overlay_dtv_unset(struct msm_fb_data_type *mfd,
 			struct mdp4_overlay_pipe *pipe);
+void mdp4_dma_e_done_dtv(void);
 #else
 static inline void  mdp4_overlay_dtv_ov_done_push(struct msm_fb_data_type *mfd,
 			struct mdp4_overlay_pipe *pipe)
@@ -438,6 +440,10 @@
 {
 	return 0;
 }
+static inline void mdp4_dma_e_done_dtv(void)
+{
+	return;
+}
 #endif
 
 #ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
@@ -691,7 +697,6 @@
 		struct mdp4_overlay_pipe *pipe);
 void mdp4_writeback_dma_busy_wait(struct msm_fb_data_type *mfd);
 void mdp4_overlay1_done_writeback(struct mdp_dma_data *dma);
-void mdp4_dma_e_done_dtv(void);
 
 int mdp4_writeback_start(struct fb_info *info);
 int mdp4_writeback_stop(struct fb_info *info);
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index bf53c73..8299202 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -370,17 +370,18 @@
 
 static uint32 mdp4_scale_phase_step(int f_num, uint32 src, uint32 dst)
 {
-	uint32 val;
+	uint32 val, s;
 	int	n;
 
 	n = mdp4_leading_0(src);
 	if (n > f_num)
 		n = f_num;
-	val = src << n;	/* maximum to reduce lose of resolution */
-	val /= dst;
+	s = src << n;	/* maximum to reduce lose of resolution */
+	val = s / dst;
 	if (n < f_num) {
 		n = f_num - n;
 		val <<= n;
+		val |= ((s % dst) << n) / dst;
 	}
 
 	return val;
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index 3a1a9aa..f417110 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -527,7 +527,7 @@
 	*/
 	temp_src_format = inpdw(rgb_base + 0x0050);
 	MDP_OUTP(rgb_base + 0x0050, temp_src_format | BIT(22));
-	mdp4_mixer_stage_up(pipe);
+	mdp4_mixer_stage_up(dtv_pipe);
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
 }
 #endif
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index fdb1ec5..3dece1f 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -45,73 +45,6 @@
 static struct mdp4_overlay_pipe *lcdc_pipe;
 static struct completion lcdc_comp;
 
-static void lvds_init(struct msm_fb_data_type *mfd)
-{
-	unsigned int lvds_intf, lvds_phy_cfg0;
-
-	if (mfd->panel_info.bpp == 24) {
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
-		MDP_OUTP(MDP_BASE +  0xc2014, 0x03040508);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
-		MDP_OUTP(MDP_BASE +  0xc2018, 0x00000102);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
-		MDP_OUTP(MDP_BASE +  0xc201c, 0x0c0d1011);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
-		MDP_OUTP(MDP_BASE +  0xc2020, 0x00090a0b);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
-		MDP_OUTP(MDP_BASE +  0xc2024, 0x1518191a);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
-		MDP_OUTP(MDP_BASE +  0xc2028, 0x00121314);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_3_TO_0 */
-		MDP_OUTP(MDP_BASE +  0xc202c, 0x0f16171b);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D3_6_TO_4 */
-		MDP_OUTP(MDP_BASE +  0xc2030, 0x0006070e);
-
-		if (mfd->panel_info.lvds.channel_mode ==
-			LVDS_DUAL_CHANNEL_MODE) {
-			lvds_intf = 0x0001ff80;
-			lvds_phy_cfg0 = BIT(6) | BIT(7);
-			if (mfd->panel_info.lvds.channel_swap)
-				lvds_intf |= BIT(4);
-		} else {
-			lvds_intf = 0x00010f84;
-			lvds_phy_cfg0 = BIT(6);
-		}
-	} else if (mfd->panel_info.bpp == 18) {
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_3_TO_0 */
-		MDP_OUTP(MDP_BASE +  0xc2014, 0x03040508);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D0_6_TO_4 */
-		MDP_OUTP(MDP_BASE +  0xc2018, 0x00000102);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_3_TO_0 */
-		MDP_OUTP(MDP_BASE +  0xc201c, 0x0c0d1011);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D1_6_TO_4 */
-		MDP_OUTP(MDP_BASE +  0xc2020, 0x00090a0b);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_3_TO_0 */
-		MDP_OUTP(MDP_BASE +  0xc2024, 0x1518191a);
-		/* MDP_LCDC_LVDS_MUX_CTL_FOR_D2_6_TO_4 */
-		MDP_OUTP(MDP_BASE +  0xc2028, 0x00121314);
-
-		if (mfd->panel_info.lvds.channel_mode ==
-			LVDS_DUAL_CHANNEL_MODE) {
-			lvds_intf = 0x00017788;
-			lvds_phy_cfg0 = BIT(6) | BIT(7);
-			if (mfd->panel_info.lvds.channel_swap)
-				lvds_intf |= BIT(4);
-		} else {
-			lvds_intf = 0x0001078c;
-			lvds_phy_cfg0 = BIT(6);
-		}
-	}
-
-	/* MDP_LVDSPHY_CFG0 */
-	MDP_OUTP(MDP_BASE +  0xc3100, lvds_phy_cfg0);
-	/* MDP_LCDC_LVDS_INTF_CTL */
-	MDP_OUTP(MDP_BASE +  0xc2000, lvds_intf);
-	lvds_phy_cfg0 |= BIT(4);
-	/* MDP_LVDSPHY_CFG0, enable serialization */
-	MDP_OUTP(MDP_BASE +  0xc3100, lvds_phy_cfg0);
-}
-
 int mdp_lcdc_on(struct platform_device *pdev)
 {
 	int lcdc_width;
@@ -305,9 +238,6 @@
 #endif
 	mdp_histogram_ctrl(TRUE);
 
-	if (mfd->panel.type == LVDS_PANEL)
-		lvds_init(mfd);
-
 	ret = panel_next_on(pdev);
 	if (ret == 0) {
 		/* enable LCDC block */
diff --git a/drivers/video/msm/mipi_NT35510.c b/drivers/video/msm/mipi_NT35510.c
index ff513d0..930b4e9 100644
--- a/drivers/video/msm/mipi_NT35510.c
+++ b/drivers/video/msm/mipi_NT35510.c
@@ -172,7 +172,7 @@
 	0xB6, 0x02,
 };
 static char cmd19[3] = {
-	0xB1, 0xEC, 0x06,
+	0xB1, 0xEC, 0x00,
 };
 static char cmd20[4] = {
 	0xBC, 0x05, 0x05, 0x05,
@@ -206,7 +206,7 @@
 static char cmd27[2] = {
 	0x35, 0x00,
 };
-static char config_MADCTL[2] = {0x36, 0xC0};
+static char config_MADCTL[2] = {0x36, 0x00};
 static struct dsi_cmd_desc nt35510_cmd_display_on_cmds[] = {
 	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd0), cmd0},
 	{DTYPE_GEN_LWRITE, 1, 0, 0, 50, sizeof(cmd1), cmd1},
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index cd3f954..bf1c112 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -540,9 +540,10 @@
 				client_ctx->user_ion_client,
 				buff_ion_handle,
 				ionflag);
-			if (!(*kernel_vaddr)) {
+			if (IS_ERR_OR_NULL((void *)*kernel_vaddr)) {
 				ERR("%s():ION virtual addr fail\n",
 				 __func__);
+				*kernel_vaddr = (unsigned long)NULL;
 				goto ion_error;
 			}
 			if (ion_phys(client_ctx->user_ion_client,
@@ -587,7 +588,7 @@
 	mutex_unlock(&client_ctx->enrty_queue_lock);
 	return true;
 ion_error:
-	if (*kernel_vaddr)
+	if (*kernel_vaddr && buff_ion_handle)
 		ion_unmap_kernel(client_ctx->user_ion_client, buff_ion_handle);
 	if (!IS_ERR_OR_NULL(buff_ion_handle))
 		ion_free(client_ctx->user_ion_client, buff_ion_handle);
diff --git a/include/linux/leds-pm8xxx.h b/include/linux/leds-pm8xxx.h
index 3f31498..18e6398 100644
--- a/include/linux/leds-pm8xxx.h
+++ b/include/linux/leds-pm8xxx.h
@@ -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
@@ -34,6 +34,8 @@
 	PM8XXX_ID_LED_2,
 	PM8XXX_ID_FLASH_LED_0,
 	PM8XXX_ID_FLASH_LED_1,
+	PM8XXX_ID_WLED,
+	PM8XXX_ID_MAX,
 };
 
 /**
@@ -50,6 +52,48 @@
 	PM8XXX_LED_MODE_DTEST4
 };
 
+/* current boost limit */
+enum wled_current_bost_limit {
+	WLED_CURR_LIMIT_105mA,
+	WLED_CURR_LIMIT_385mA,
+	WLED_CURR_LIMIT_525mA,
+	WLED_CURR_LIMIT_805mA,
+	WLED_CURR_LIMIT_980mA,
+	WLED_CURR_LIMIT_1260mA,
+	WLED_CURR_LIMIT_1400mA,
+	WLED_CURR_LIMIT_1680mA,
+};
+
+/* over voltage protection threshold */
+enum wled_ovp_threshold {
+	WLED_OVP_35V,
+	WLED_OVP_32V,
+	WLED_OVP_29V,
+	WLED_OVP_37V,
+};
+
+/**
+ *  wled_config_data - wled configuration data
+ *  @num_strings - number of wled strings supported
+ *  @ovp_val - over voltage protection threshold
+ *  @boost_curr_lim - boot current limit
+ *  @cp_select - high pole capacitance
+ *  @ctrl_delay_us - delay in activation of led
+ *  @dig_mod_gen_en - digital module generator
+ *  @cs_out_en - current sink output enable
+ *  @op_fdbck - selection of output as feedback for the boost
+ */
+struct wled_config_data {
+	u8	num_strings;
+	u8	ovp_val;
+	u8	boost_curr_lim;
+	u8	cp_select;
+	u8	ctrl_delay_us;
+	bool	dig_mod_gen_en;
+	bool	cs_out_en;
+	bool	op_fdbck;
+};
+
 /**
  * pm8xxx_led_config - led configuration parameters
  * @id - LED id
@@ -57,6 +101,7 @@
  * @max_current - maximum current that LED can sustain
  * @pwm_channel - PWM channel ID the LED is driven to
  * @pwm_period_us - PWM period value in micro seconds
+ * @default_state - default state of the led
  * @pwm_duty_cycles - PWM duty cycle information
  */
 struct pm8xxx_led_config {
@@ -65,7 +110,9 @@
 	u16	max_current;
 	int	pwm_channel;
 	u32	pwm_period_us;
+	bool	default_state;
 	struct pm8xxx_pwm_duty_cycles *pwm_duty_cycles;
+	struct wled_config_data	*wled_cfg;
 };
 
 /**
diff --git a/include/linux/mfd/wcd9310/wcd9310-slimslave.h b/include/linux/mfd/wcd9310/wcd9310-slimslave.h
new file mode 100644
index 0000000..0bbf96f
--- /dev/null
+++ b/include/linux/mfd/wcd9310/wcd9310-slimslave.h
@@ -0,0 +1,102 @@
+/* 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 __WCD9310_SLIMSLAVE_H_
+#define __WCD9310_SLIMSLAVE_H_
+
+#include <linux/slimbus/slimbus.h>
+#include <linux/mfd/wcd9310/core.h>
+
+/* Local to the core only */
+#define SLIM_MAX_RX_PORTS 7
+#define SLIM_MAX_TX_PORTS 10
+
+/* Channel numbers to be used for each port */
+enum {
+	SLIM_TX_1   = 128,
+	SLIM_TX_2   = 129,
+	SLIM_TX_3   = 130,
+	SLIM_TX_4   = 131,
+	SLIM_TX_5   = 132,
+	SLIM_TX_6   = 133,
+	SLIM_TX_7   = 134,
+	SLIM_TX_8   = 135,
+	SLIM_TX_9   = 136,
+	SLIM_TX_10  = 137,
+	SLIM_RX_1   = 138,
+	SLIM_RX_2   = 139,
+	SLIM_RX_3   = 140,
+	SLIM_RX_4   = 141,
+	SLIM_RX_5   = 142,
+	SLIM_RX_6   = 143,
+	SLIM_RX_7   = 144,
+	SLIM_MAX    = 145
+};
+
+/*
+ *  client is expected to give port ids in the range of 1-10 for Tx ports and
+ *  1-7 for Rx ports, we need to add offset for getting the absolute slave
+ *  port id before configuring the HW
+ */
+#define SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS 10
+#define SB_PGD_OFFSET_OF_TX_SLAVE_DEV_PORTS     -1
+#define SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS 7
+#define SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS     9
+
+/* below details are taken from SLIMBUS slave SWI */
+#define SB_PGD_PORT_BASE 0x000
+
+#define SB_PGD_PORT_CFG_BYTE_ADDR(port_num) \
+		(SB_PGD_PORT_BASE + 0x040 + 1*port_num)
+
+#define SB_PGD_TX_PORT_MULTI_CHANNEL_0(port_num) \
+		(SB_PGD_PORT_BASE + 0x100 + 4*port_num)
+#define SB_PGD_TX_PORT_MULTI_CHANNEL_0_START_PORT_ID   0
+#define SB_PGD_TX_PORT_MULTI_CHANNEL_0_END_PORT_ID     7
+
+#define SB_PGD_TX_PORT_MULTI_CHANNEL_1(port_num) \
+		(SB_PGD_PORT_BASE + 0x101 + 4*port_num)
+#define SB_PGD_TX_PORT_MULTI_CHANNEL_1_START_PORT_ID   8
+#define SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID     9
+
+#define SB_PGD_RX_PORT_MULTI_CHANNEL_0(port_num) \
+		(SB_PGD_PORT_BASE + 0x180 + 4*port_num)
+#define SB_PGD_RX_PORT_MULTI_CHANNEL_0_START_PORT_ID   10
+#define SB_PGD_RX_PORT_MULTI_CHANNEL_0_END_PORT_ID     16
+
+/* slave port water mark level
+ *   (0: 6bytes, 1: 9bytes, 2: 12 bytes, 3: 15 bytes)
+ */
+#define SLAVE_PORT_WATER_MARK_VALUE 2
+#define SLAVE_PORT_WATER_MARK_SHIFT 1
+#define SLAVE_PORT_ENABLE           1
+#define SLAVE_PORT_DISABLE          0
+
+#define BASE_CH_NUM 128
+
+
+int tabla_init_slimslave(struct tabla *tabla, u8 tabla_pgd_la);
+
+int tabla_deinit_slimslave(struct tabla *tabla);
+
+int tabla_cfg_slim_sch_rx(struct tabla *tabla, unsigned int *ch_num,
+				unsigned int tot_ch, unsigned int rate);
+int tabla_cfg_slim_sch_tx(struct tabla *tabla, unsigned int *ch_num,
+				unsigned int tot_ch, unsigned int rate);
+int tabla_close_slim_sch_rx(struct tabla *tabla, unsigned int *ch_num,
+				unsigned int tot_ch);
+int tabla_close_slim_sch_tx(struct tabla *tabla, unsigned int *ch_num,
+				unsigned int tot_ch);
+int tabla_get_channel(struct tabla *tabla,
+			unsigned int *rx_ch,
+			unsigned int *tx_ch);
+#endif /* __WCD9310_SLIMSLAVE_H_ */
diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h
index 9eb6dda..37b9d35 100644
--- a/include/linux/msm_kgsl.h
+++ b/include/linux/msm_kgsl.h
@@ -148,6 +148,7 @@
 	unsigned int idle_timeout;
 	unsigned int nap_allowed;
 	unsigned int clk_map;
+	unsigned int idle_needed;
 	struct msm_bus_scale_pdata *bus_scale_table;
 	const char *iommu_user_ctx_name;
 	const char *iommu_priv_ctx_name;
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 87fbbd2..1a6f68f 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -693,6 +693,9 @@
 #define MSM_V4L2_CAM_OP_ZSL             (MSM_V4L2_CAM_OP_DEFAULT+4)
 /* camera operation mode for raw snapshot - one frame output queue */
 #define MSM_V4L2_CAM_OP_RAW             (MSM_V4L2_CAM_OP_DEFAULT+5)
+/* camera operation mode for jpeg snapshot - one frame output queue */
+#define MSM_V4L2_CAM_OP_JPEG_CAPTURE    (MSM_V4L2_CAM_OP_DEFAULT+6)
+
 
 #define MSM_V4L2_VID_CAP_TYPE	0
 #define MSM_V4L2_STREAM_ON		1
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index 5dd1445..07784e2 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -241,6 +241,9 @@
 #define VPE_SCALER_CONFIG_LEN           260
 #define VPE_DIS_OFFSET_CFG_LEN          12
 
+#define IMEM_Y_OFFSET  0x2E000000
+#define IMEM_CBCR_OFFSET  0x2E00FA00
+
 struct msm_vpe_op_mode_cfg {
 	uint8_t op_mode_cfg[VPE_OPERATION_MODE_CFG_LEN];
 };
@@ -311,6 +314,8 @@
 #define VFE_OUTPUTS_PREVIEW		BIT(6)
 #define VFE_OUTPUTS_VIDEO		BIT(7)
 #define VFE_OUTPUTS_RAW			BIT(8)
+#define VFE_OUTPUTS_JPEG_AND_THUMB	BIT(9)
+#define VFE_OUTPUTS_THUMB_AND_JPEG	BIT(10)
 
 #endif /*__MSM_ISP_H__*/
 
diff --git a/include/sound/apr_audio.h b/include/sound/apr_audio.h
index 87bafed..097ba39 100644
--- a/include/sound/apr_audio.h
+++ b/include/sound/apr_audio.h
@@ -272,6 +272,16 @@
 	u16	reserved;
 } __packed;
 
+struct afe_port_slimbus_sch_cfg {
+	u16	slimbus_dev_id;		/* SLIMBUS Device id.*/
+	u16	bit_width;		/**  bit width of the samples, 16, 24.*/
+	u16	data_format;		/** data format.*/
+	u16	num_channels;		/** Number of channels.*/
+	u16	reserved;
+	/** Slave channel  mapping for respective channels.*/
+	u8	slave_ch_mapping[8];
+} __packed;
+
 struct afe_port_rtproxy_cfg {
 	u16	bitwidth;	/* 16,24,32 */
 	u16	interleaved;    /* interleaved = 1 */
@@ -284,16 +294,18 @@
 	int	num_ch;		/* 1 to 8 */
 } __packed;
 
-#define AFE_PORT_AUDIO_IF_CONFIG			0x000100d3
+#define AFE_PORT_AUDIO_IF_CONFIG 0x000100d3
+#define AFE_PORT_AUDIO_SLIM_SCH_CONFIG 0x000100e4
 #define AFE_PORT_MULTI_CHAN_HDMI_AUDIO_IF_CONFIG	0x000100D9
 
 union afe_port_config {
-	struct afe_port_pcm_cfg			pcm;
-	struct afe_port_mi2s_cfg		mi2s;
-	struct afe_port_hdmi_cfg		hdmi;
-	struct afe_port_hdmi_multi_ch_cfg	hdmi_multi_ch;
-	struct afe_port_slimbus_cfg		slimbus;
-	struct afe_port_rtproxy_cfg		rtproxy;
+	struct afe_port_pcm_cfg           pcm;
+	struct afe_port_mi2s_cfg          mi2s;
+	struct afe_port_hdmi_cfg          hdmi;
+	struct afe_port_hdmi_multi_ch_cfg hdmi_multi_ch;
+	struct afe_port_slimbus_cfg	  slimbus;
+	struct afe_port_slimbus_sch_cfg	  slim_sch;
+	struct afe_port_rtproxy_cfg       rtproxy;
 } __attribute__((packed));
 
 struct afe_audioif_config_command {
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index bda171e..f1ce01f 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -2,6 +2,7 @@
  * linux/sound/soc-dai.h -- ALSA SoC Layer
  *
  * Copyright:	2005-2008 Wolfson Microelectronics. PLC.
+ * 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 as
@@ -121,6 +122,10 @@
 	unsigned int tx_num, unsigned int *tx_slot,
 	unsigned int rx_num, unsigned int *rx_slot);
 
+int snd_soc_dai_get_channel_map(struct snd_soc_dai *dai,
+	unsigned int *tx_num, unsigned int *tx_slot,
+	unsigned int *rx_num, unsigned int *rx_slot);
+
 int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
 
 /* Digital Audio Interface mute */
@@ -150,6 +155,9 @@
 		unsigned int rx_num, unsigned int *rx_slot);
 	int (*set_tristate)(struct snd_soc_dai *dai, int tristate);
 
+	int (*get_channel_map)(struct snd_soc_dai *dai,
+		unsigned int *tx_num, unsigned int *tx_slot,
+		unsigned int *rx_num, unsigned int *rx_slot);
 	/*
 	 * DAI digital mute - optional.
 	 * Called by soc-core to minimise any pops.
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 94cacde..468f86c 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -611,8 +611,16 @@
 		case L2CAP_MODE_BASIC:
 			l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE;
 			break;
-		case L2CAP_MODE_ERTM:
 		case L2CAP_MODE_STREAMING:
+			if (!disable_ertm) {
+				/* No fallback to ERTM or Basic mode */
+				l2cap_pi(sk)->conf_state |=
+						L2CAP_CONF_STATE2_DEVICE;
+				break;
+			}
+			err = -EINVAL;
+			break;
+		case L2CAP_MODE_ERTM:
 			if (!disable_ertm)
 				break;
 			/* fall through */
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 7c2073d..ac7f050 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -36,8 +36,6 @@
 #define NUM_DECIMATORS 10
 #define NUM_INTERPOLATORS 7
 #define BITS_PER_REG 8
-#define TABLA_RX_DAI_ID 1
-#define TABLA_TX_DAI_ID 2
 #define TABLA_CFILT_FAST_MODE 0x00
 #define TABLA_CFILT_SLOW_MODE 0x40
 #define MBHC_FW_READ_ATTEMPTS 15
@@ -49,6 +47,17 @@
 
 #define TABLA_OCP_ATTEMPT 1
 
+#define AIF1_PB 1
+#define AIF1_CAP 2
+#define NUM_CODEC_DAIS 2
+
+struct tabla_codec_dai_data {
+	u32 rate;
+	u32 *ch_num;
+	u32 ch_act;
+	u32 ch_tot;
+};
+
 #define TABLA_MCLK_RATE_12288KHZ 12288000
 #define TABLA_MCLK_RATE_9600KHZ 9600000
 
@@ -58,6 +67,7 @@
 static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
 static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
 static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
+static struct snd_soc_dai_driver tabla_dai[];
 
 enum tabla_bandgap_type {
 	TABLA_BANDGAP_OFF = 0,
@@ -194,6 +204,9 @@
 	/* Work to perform MBHC Firmware Read */
 	struct delayed_work mbhc_firmware_dwork;
 	const struct firmware *mbhc_fw;
+
+	/* num of slim ports required */
+	struct tabla_codec_dai_data dai[NUM_CODEC_DAIS];
 };
 
 #ifdef CONFIG_DEBUG_FS
@@ -340,9 +353,9 @@
 				int coeff_idx)
 {
 	/* Address does not automatically update if reading */
-	snd_soc_update_bits(codec,
+	snd_soc_write(codec,
 		(TABLA_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
-		0x1F, band_idx * BAND_MAX + coeff_idx);
+		(band_idx * BAND_MAX + coeff_idx) & 0x1F);
 
 	/* Mask bits top 2 bits since they are reserved */
 	return ((snd_soc_read(codec,
@@ -401,27 +414,27 @@
 {
 	/* Mask top 3 bits, 6-8 are reserved */
 	/* Update address manually each time */
-	snd_soc_update_bits(codec,
+	snd_soc_write(codec,
 		(TABLA_A_CDC_IIR1_COEF_B1_CTL + 16 * iir_idx),
-		0x1F, band_idx * BAND_MAX + coeff_idx);
+		(band_idx * BAND_MAX + coeff_idx) & 0x1F);
 
 	/* Mask top 2 bits, 7-8 are reserved */
-	snd_soc_update_bits(codec,
+	snd_soc_write(codec,
 		(TABLA_A_CDC_IIR1_COEF_B2_CTL + 16 * iir_idx),
-		0x3F, (value >> 24) & 0x3F);
+		(value >> 24) & 0x3F);
 
 	/* Isolate 8bits at a time */
-	snd_soc_update_bits(codec,
+	snd_soc_write(codec,
 		(TABLA_A_CDC_IIR1_COEF_B3_CTL + 16 * iir_idx),
-		0xFF, (value >> 16) & 0xFF);
+		(value >> 16) & 0xFF);
 
-	snd_soc_update_bits(codec,
+	snd_soc_write(codec,
 		(TABLA_A_CDC_IIR1_COEF_B4_CTL + 16 * iir_idx),
-		0xFF, (value >> 8) & 0xFF);
+		(value >> 8) & 0xFF);
 
-	snd_soc_update_bits(codec,
+	snd_soc_write(codec,
 		(TABLA_A_CDC_IIR1_COEF_B5_CTL + 16 * iir_idx),
-		0xFF, value & 0xFF);
+		value & 0xFF);
 }
 
 static int tabla_put_iir_band_audio_mixer(
@@ -1907,306 +1920,6 @@
 	return 0;
 }
 
-static const struct snd_soc_dapm_widget tabla_dapm_widgets[] = {
-	/*RX stuff */
-	SND_SOC_DAPM_OUTPUT("EAR"),
-
-	SND_SOC_DAPM_PGA("EAR PA", TABLA_A_RX_EAR_EN, 4, 0, NULL, 0),
-
-	SND_SOC_DAPM_MIXER("DAC1", TABLA_A_RX_EAR_EN, 6, 0, dac1_switch,
-		ARRAY_SIZE(dac1_switch)),
-
-	SND_SOC_DAPM_AIF_IN("SLIM RX1", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
-	SND_SOC_DAPM_AIF_IN("SLIM RX2", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
-	SND_SOC_DAPM_AIF_IN("SLIM RX3", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
-	SND_SOC_DAPM_AIF_IN("SLIM RX4", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
-
-	/* Headphone */
-	SND_SOC_DAPM_OUTPUT("HEADPHONE"),
-	SND_SOC_DAPM_PGA_E("HPHL", TABLA_A_RX_HPH_CNP_EN, 5, 0, NULL, 0,
-		tabla_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
-			SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MIXER("HPHL DAC", TABLA_A_RX_HPH_L_DAC_CTL, 7, 0,
-		hphl_switch, ARRAY_SIZE(hphl_switch)),
-
-	SND_SOC_DAPM_PGA_E("HPHR", TABLA_A_RX_HPH_CNP_EN, 4, 0, NULL, 0,
-		tabla_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
-			SND_SOC_DAPM_POST_PMD),
-
-	SND_SOC_DAPM_DAC_E("HPHR DAC", NULL, TABLA_A_RX_HPH_R_DAC_CTL, 7, 0,
-		tabla_hphr_dac_event,
-		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
-	/* Speaker */
-	SND_SOC_DAPM_OUTPUT("LINEOUT1"),
-	SND_SOC_DAPM_OUTPUT("LINEOUT2"),
-	SND_SOC_DAPM_OUTPUT("LINEOUT3"),
-	SND_SOC_DAPM_OUTPUT("LINEOUT4"),
-	SND_SOC_DAPM_OUTPUT("LINEOUT5"),
-
-	SND_SOC_DAPM_PGA_E("LINEOUT1 PA", TABLA_A_RX_LINE_CNP_EN, 0, 0, NULL,
-			0, tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
-			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_PGA_E("LINEOUT2 PA", TABLA_A_RX_LINE_CNP_EN, 1, 0, NULL,
-			0, tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
-			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_PGA_E("LINEOUT3 PA", TABLA_A_RX_LINE_CNP_EN, 2, 0, NULL,
-			0, tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
-			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_PGA_E("LINEOUT4 PA", TABLA_A_RX_LINE_CNP_EN, 3, 0, NULL,
-			0, tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
-			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_PGA_E("LINEOUT5 PA", TABLA_A_RX_LINE_CNP_EN, 4, 0, NULL, 0,
-		tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
-	SND_SOC_DAPM_DAC_E("LINEOUT1 DAC", NULL, TABLA_A_RX_LINE_1_DAC_CTL, 7, 0
-		, tabla_lineout_dac_event,
-		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_DAC_E("LINEOUT2 DAC", NULL, TABLA_A_RX_LINE_2_DAC_CTL, 7, 0
-		, tabla_lineout_dac_event,
-		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_DAC_E("LINEOUT3 DAC", NULL, TABLA_A_RX_LINE_3_DAC_CTL, 7, 0
-		, tabla_lineout_dac_event,
-		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_SWITCH("LINEOUT3 DAC GROUND", SND_SOC_NOPM, 0, 0,
-				&lineout3_ground_switch),
-	SND_SOC_DAPM_DAC_E("LINEOUT4 DAC", NULL, TABLA_A_RX_LINE_4_DAC_CTL, 7, 0
-		, tabla_lineout_dac_event,
-		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_SWITCH("LINEOUT4 DAC GROUND", SND_SOC_NOPM, 0, 0,
-				&lineout4_ground_switch),
-	SND_SOC_DAPM_DAC_E("LINEOUT5 DAC", NULL, TABLA_A_RX_LINE_5_DAC_CTL, 7, 0
-		, tabla_lineout_dac_event,
-		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
-	SND_SOC_DAPM_MIXER_E("RX1 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
-		0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
-	SND_SOC_DAPM_MIXER_E("RX2 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL,
-		0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
-	SND_SOC_DAPM_MIXER_E("RX3 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
-		0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
-	SND_SOC_DAPM_MIXER_E("RX4 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 3, 0, NULL,
-		0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
-	SND_SOC_DAPM_MIXER_E("RX5 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 4, 0, NULL,
-		0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
-	SND_SOC_DAPM_MIXER_E("RX6 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 5, 0, NULL,
-		0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
-	SND_SOC_DAPM_MIXER_E("RX7 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 6, 0, NULL,
-		0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
-
-
-	SND_SOC_DAPM_MUX_E("RX4 DSM MUX", TABLA_A_CDC_CLK_RX_B1_CTL, 3, 0,
-		&rx4_dsm_mux, tabla_codec_reset_interpolator,
-		SND_SOC_DAPM_PRE_PMU),
-
-	SND_SOC_DAPM_MUX_E("RX6 DSM MUX", TABLA_A_CDC_CLK_RX_B1_CTL, 5, 0,
-		&rx6_dsm_mux, tabla_codec_reset_interpolator,
-		SND_SOC_DAPM_PRE_PMU),
-
-	SND_SOC_DAPM_MIXER("RX1 CHAIN", TABLA_A_CDC_RX1_B6_CTL, 5, 0, NULL, 0),
-	SND_SOC_DAPM_MIXER("RX2 CHAIN", TABLA_A_CDC_RX2_B6_CTL, 5, 0, NULL, 0),
-
-	SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
-		&rx_mix1_inp1_mux),
-	SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
-		&rx_mix1_inp2_mux),
-	SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0,
-		&rx2_mix1_inp1_mux),
-	SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0,
-		&rx2_mix1_inp2_mux),
-	SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0,
-		&rx3_mix1_inp1_mux),
-	SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0,
-		&rx3_mix1_inp2_mux),
-	SND_SOC_DAPM_MUX("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0,
-		&rx4_mix1_inp1_mux),
-	SND_SOC_DAPM_MUX("RX4 MIX1 INP2", SND_SOC_NOPM, 0, 0,
-		&rx4_mix1_inp2_mux),
-	SND_SOC_DAPM_MUX("RX5 MIX1 INP1", SND_SOC_NOPM, 0, 0,
-		&rx5_mix1_inp1_mux),
-	SND_SOC_DAPM_MUX("RX5 MIX1 INP2", SND_SOC_NOPM, 0, 0,
-		&rx5_mix1_inp2_mux),
-	SND_SOC_DAPM_MUX("RX6 MIX1 INP1", SND_SOC_NOPM, 0, 0,
-		&rx6_mix1_inp1_mux),
-	SND_SOC_DAPM_MUX("RX6 MIX1 INP2", SND_SOC_NOPM, 0, 0,
-		&rx6_mix1_inp2_mux),
-	SND_SOC_DAPM_MUX("RX7 MIX1 INP1", SND_SOC_NOPM, 0, 0,
-		&rx7_mix1_inp1_mux),
-	SND_SOC_DAPM_MUX("RX7 MIX1 INP2", SND_SOC_NOPM, 0, 0,
-		&rx7_mix1_inp2_mux),
-
-	SND_SOC_DAPM_SUPPLY("CP", TABLA_A_CP_EN, 0, 0,
-		tabla_codec_enable_charge_pump, SND_SOC_DAPM_POST_PMU |
-		SND_SOC_DAPM_PRE_PMD),
-
-	SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
-		tabla_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMD),
-
-	/* TX */
-
-	SND_SOC_DAPM_SUPPLY("CDC_CONN", TABLA_A_CDC_CLK_OTHR_CTL, 2, 0, NULL,
-		0),
-
-	SND_SOC_DAPM_SUPPLY("LDO_H", TABLA_A_LDO_H_MODE_1, 7, 0,
-		tabla_codec_enable_ldo_h, SND_SOC_DAPM_POST_PMU),
-
-	SND_SOC_DAPM_INPUT("AMIC1"),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", TABLA_A_MICB_1_CTL, 7, 0,
-		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1", TABLA_A_MICB_1_CTL, 7, 0,
-		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2", TABLA_A_MICB_1_CTL, 7, 0,
-		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_ADC_E("ADC1", NULL, TABLA_A_TX_1_2_EN, 7, 0,
-		tabla_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
-	SND_SOC_DAPM_INPUT("AMIC3"),
-	SND_SOC_DAPM_ADC_E("ADC3", NULL, TABLA_A_TX_3_4_EN, 7, 0,
-		tabla_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
-	SND_SOC_DAPM_INPUT("AMIC4"),
-	SND_SOC_DAPM_ADC_E("ADC4", NULL, TABLA_A_TX_3_4_EN, 3, 0,
-		tabla_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
-	SND_SOC_DAPM_INPUT("AMIC5"),
-	SND_SOC_DAPM_ADC_E("ADC5", NULL, TABLA_A_TX_5_6_EN, 7, 0,
-		tabla_codec_enable_adc, SND_SOC_DAPM_POST_PMU),
-
-	SND_SOC_DAPM_INPUT("AMIC6"),
-	SND_SOC_DAPM_ADC_E("ADC6", NULL, TABLA_A_TX_5_6_EN, 3, 0,
-		tabla_codec_enable_adc, SND_SOC_DAPM_POST_PMU),
-
-	SND_SOC_DAPM_MUX_E("DEC1 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 0, 0,
-		&dec1_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
-	SND_SOC_DAPM_MUX_E("DEC2 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 1, 0,
-		&dec2_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
-	SND_SOC_DAPM_MUX_E("DEC3 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 2, 0,
-		&dec3_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
-	SND_SOC_DAPM_MUX_E("DEC4 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 3, 0,
-		&dec4_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
-	SND_SOC_DAPM_MUX_E("DEC5 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 4, 0,
-		&dec5_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
-	SND_SOC_DAPM_MUX_E("DEC6 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 5, 0,
-		&dec6_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
-	SND_SOC_DAPM_MUX_E("DEC7 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 6, 0,
-		&dec7_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
-	SND_SOC_DAPM_MUX_E("DEC8 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 7, 0,
-		&dec8_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
-	SND_SOC_DAPM_MUX_E("DEC9 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B2_CTL, 0, 0,
-		&dec9_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
-	SND_SOC_DAPM_MUX_E("DEC10 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B2_CTL, 1, 0,
-		&dec10_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
-
-	SND_SOC_DAPM_MUX("ANC1 MUX", SND_SOC_NOPM, 0, 0, &anc1_mux),
-	SND_SOC_DAPM_MUX("ANC2 MUX", SND_SOC_NOPM, 0, 0, &anc2_mux),
-
-	SND_SOC_DAPM_MIXER_E("ANC", SND_SOC_NOPM, 0, 0, NULL, 0,
-		tabla_codec_enable_anc, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMD),
-
-	SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
-
-	SND_SOC_DAPM_INPUT("AMIC2"),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", TABLA_A_MICB_2_CTL, 7, 0,
-		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU |	SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", TABLA_A_MICB_2_CTL, 7, 0,
-		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", TABLA_A_MICB_2_CTL, 7, 0,
-		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", TABLA_A_MICB_2_CTL, 7, 0,
-		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", TABLA_A_MICB_3_CTL, 7, 0,
-		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", TABLA_A_MICB_3_CTL, 7, 0,
-		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", TABLA_A_MICB_3_CTL, 7, 0,
-		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_ADC_E("ADC2", NULL, TABLA_A_TX_1_2_EN, 3, 0,
-		tabla_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
-	SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, 0, 0, &sb_tx1_mux),
-	SND_SOC_DAPM_AIF_OUT("SLIM TX1", "AIF1 Capture", NULL, SND_SOC_NOPM,
-			0, 0),
-
-	SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, 0, 0, &sb_tx5_mux),
-	SND_SOC_DAPM_AIF_OUT("SLIM TX5", "AIF1 Capture", NULL, SND_SOC_NOPM,
-			4, 0),
-
-	SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, 0, 0, &sb_tx6_mux),
-	SND_SOC_DAPM_AIF_OUT("SLIM TX6", "AIF1 Capture", NULL, SND_SOC_NOPM,
-			5, 0),
-
-	SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, 0, 0, &sb_tx7_mux),
-	SND_SOC_DAPM_AIF_OUT("SLIM TX7", "AIF1 Capture", NULL, SND_SOC_NOPM,
-			0, 0),
-
-	SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, 0, 0, &sb_tx8_mux),
-	SND_SOC_DAPM_AIF_OUT("SLIM TX8", "AIF1 Capture", NULL, SND_SOC_NOPM,
-			0, 0),
-
-	SND_SOC_DAPM_MUX("SLIM TX9 MUX", SND_SOC_NOPM, 0, 0, &sb_tx9_mux),
-	SND_SOC_DAPM_AIF_OUT("SLIM TX9", "AIF1 Capture", NULL, SND_SOC_NOPM,
-			0, 0),
-
-	SND_SOC_DAPM_MUX("SLIM TX10 MUX", SND_SOC_NOPM, 0, 0, &sb_tx10_mux),
-	SND_SOC_DAPM_AIF_OUT("SLIM TX10", "AIF1 Capture", NULL, SND_SOC_NOPM,
-			0, 0),
-
-	/* Digital Mic Inputs */
-	SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
-		tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMD),
-
-	SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
-		tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMD),
-
-	SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
-		tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMD),
-
-	SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
-		tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMD),
-
-	SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0,
-		tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMD),
-
-	SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 0, 0,
-		tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
-		SND_SOC_DAPM_POST_PMD),
-
-	/* Sidetone */
-	SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
-	SND_SOC_DAPM_PGA("IIR1", TABLA_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
-};
-
 static const struct snd_soc_dapm_widget tabla_1_x_dapm_widgets[] = {
 	SND_SOC_DAPM_MICBIAS_E("MIC BIAS4 External", TABLA_1_A_MICB_4_CTL, 7,
 			       0, tabla_codec_enable_micbias,
@@ -2675,7 +2388,6 @@
 {
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
 
-	pr_debug("%s: enable = %d\n", __func__, enable);
 	if (enable) {
 		snd_soc_update_bits(codec, TABLA_A_CONFIG_MODE_FREQ, 0x10, 0);
 		snd_soc_write(codec, TABLA_A_BIAS_CONFIG_MODE_BG_CTL, 0x17);
@@ -2880,11 +2592,11 @@
 	case SND_SOC_DAIFMT_CBS_CFS:
 		/* CPU is master */
 		if (tabla->intf_type == TABLA_INTERFACE_TYPE_I2C) {
-			if (dai->id == TABLA_TX_DAI_ID)
+			if (dai->id == AIF1_CAP)
 				snd_soc_update_bits(dai->codec,
 					TABLA_A_CDC_CLK_TX_I2S_CTL,
 					TABLA_I2S_MASTER_MODE_MASK, 0);
-			else if (dai->id == TABLA_RX_DAI_ID)
+			else if (dai->id == AIF1_PB)
 				snd_soc_update_bits(dai->codec,
 					TABLA_A_CDC_CLK_RX_I2S_CTL,
 					TABLA_I2S_MASTER_MODE_MASK, 0);
@@ -2894,10 +2606,10 @@
 	/* CPU is slave */
 		if (tabla->intf_type == TABLA_INTERFACE_TYPE_I2C) {
 			val = TABLA_I2S_MASTER_MODE_MASK;
-			if (dai->id == TABLA_TX_DAI_ID)
+			if (dai->id == AIF1_CAP)
 				snd_soc_update_bits(dai->codec,
 					TABLA_A_CDC_CLK_TX_I2S_CTL, val, val);
-			else if (dai->id == TABLA_RX_DAI_ID)
+			else if (dai->id == AIF1_PB)
 				snd_soc_update_bits(dai->codec,
 					TABLA_A_CDC_CLK_RX_I2S_CTL, val, val);
 		}
@@ -2908,6 +2620,71 @@
 	return 0;
 }
 
+static int tabla_set_channel_map(struct snd_soc_dai *dai,
+				unsigned int tx_num, unsigned int *tx_slot,
+				unsigned int rx_num, unsigned int *rx_slot)
+
+{
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(dai->codec);
+	u32 i = 0;
+	if (!tx_slot && !rx_slot) {
+		pr_err("%s: Invalid\n", __func__);
+		return -EINVAL;
+	}
+	pr_debug("%s: DAI-ID %x %d %d\n", __func__, dai->id, tx_num, rx_num);
+
+	if (dai->id == AIF1_PB) {
+		for (i = 0; i < rx_num; i++) {
+			tabla->dai[dai->id - 1].ch_num[i]  = rx_slot[i];
+			tabla->dai[dai->id - 1].ch_act = 0;
+			tabla->dai[dai->id - 1].ch_tot = rx_num;
+		}
+	} else if (dai->id == AIF1_CAP) {
+		for (i = 0; i < tx_num; i++) {
+			tabla->dai[dai->id - 1].ch_num[i]  = tx_slot[i];
+			tabla->dai[dai->id - 1].ch_act = 0;
+			tabla->dai[dai->id - 1].ch_tot = tx_num;
+		}
+	}
+	return 0;
+}
+
+static int tabla_get_channel_map(struct snd_soc_dai *dai,
+				unsigned int *tx_num, unsigned int *tx_slot,
+				unsigned int *rx_num, unsigned int *rx_slot)
+
+{
+	struct tabla *tabla = dev_get_drvdata(dai->codec->control_data);
+
+	u32 cnt = 0;
+	u32 tx_ch[SLIM_MAX_TX_PORTS];
+	u32 rx_ch[SLIM_MAX_RX_PORTS];
+
+	if (!rx_slot && !tx_slot) {
+		pr_err("%s: Invalid\n", __func__);
+		return -EINVAL;
+	}
+	pr_debug("%s: DAI-ID %x\n", __func__, dai->id);
+	/* for virtual port, codec driver needs to do
+	 * housekeeping, for now should be ok
+	 */
+	tabla_get_channel(tabla, rx_ch, tx_ch);
+	if (dai->id == AIF1_PB) {
+		*rx_num = tabla_dai[dai->id - 1].playback.channels_max;
+		while (cnt < *rx_num) {
+			rx_slot[cnt] = rx_ch[cnt];
+			cnt++;
+		}
+	} else if (dai->id == AIF1_CAP) {
+		*tx_num = tabla_dai[dai->id - 1].capture.channels_max;
+		while (cnt < *tx_num) {
+			tx_slot[cnt] = tx_ch[6 + cnt];
+			cnt++;
+		}
+	}
+	return 0;
+}
+
 static int tabla_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
@@ -2918,7 +2695,8 @@
 	u16 tx_fs_reg, rx_fs_reg;
 	u8 tx_fs_rate, rx_fs_rate, rx_state, tx_state;
 
-	pr_debug("%s: DAI-ID %x\n", __func__, dai->id);
+	pr_debug("%s: DAI-ID %x rate %d\n", __func__, dai->id,
+						params_rate(params));
 
 	switch (params_rate(params)) {
 	case 8000:
@@ -2948,7 +2726,7 @@
 	 * If current dai is a tx dai, set sample rate to
 	 * all the txfe paths that are currently not active
 	 */
-	if (dai->id == TABLA_TX_DAI_ID) {
+	if (dai->id == AIF1_CAP) {
 
 		tx_state = snd_soc_read(codec,
 				TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL);
@@ -2987,9 +2765,10 @@
 			}
 			snd_soc_update_bits(codec, TABLA_A_CDC_CLK_TX_I2S_CTL,
 						0x03, tx_fs_rate);
+		} else {
+			tabla->dai[dai->id - 1].rate   = params_rate(params);
 		}
 	}
-
 	/**
 	 * TODO: Need to handle case where same RX chain takes 2 or more inputs
 	 * with varying sample rates
@@ -2999,7 +2778,7 @@
 	 * If current dai is a rx dai, set sample rate to
 	 * all the rx paths that are currently not active
 	 */
-	if (dai->id == TABLA_RX_DAI_ID) {
+	if (dai->id == AIF1_PB) {
 
 		rx_state = snd_soc_read(codec,
 			TABLA_A_CDC_CLK_RX_B1_CTL);
@@ -3032,6 +2811,8 @@
 			}
 			snd_soc_update_bits(codec, TABLA_A_CDC_CLK_RX_I2S_CTL,
 						0x03, (rx_fs_rate >> 0x05));
+		} else {
+			tabla->dai[dai->id - 1].rate   = params_rate(params);
 		}
 	}
 
@@ -3044,12 +2825,14 @@
 	.hw_params = tabla_hw_params,
 	.set_sysclk = tabla_set_dai_sysclk,
 	.set_fmt = tabla_set_dai_fmt,
+	.set_channel_map = tabla_set_channel_map,
+	.get_channel_map = tabla_get_channel_map,
 };
 
 static struct snd_soc_dai_driver tabla_dai[] = {
 	{
 		.name = "tabla_rx1",
-		.id = 1,
+		.id = AIF1_PB,
 		.playback = {
 			.stream_name = "AIF1 Playback",
 			.rates = WCD9310_RATES,
@@ -3057,13 +2840,13 @@
 			.rate_max = 48000,
 			.rate_min = 8000,
 			.channels_min = 1,
-			.channels_max = 4,
+			.channels_max = 2,
 		},
 		.ops = &tabla_dai_ops,
 	},
 	{
 		.name = "tabla_tx1",
-		.id = 2,
+		.id = AIF1_CAP,
 		.capture = {
 			.stream_name = "AIF1 Capture",
 			.rates = WCD9310_RATES,
@@ -3071,7 +2854,7 @@
 			.rate_max = 48000,
 			.rate_min = 8000,
 			.channels_min = 1,
-			.channels_max = 2,
+			.channels_max = 4,
 		},
 		.ops = &tabla_dai_ops,
 	},
@@ -3107,6 +2890,426 @@
 		.ops = &tabla_dai_ops,
 	},
 };
+
+static int tabla_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct tabla *tabla;
+	struct snd_soc_codec *codec = w->codec;
+	struct tabla_priv *tabla_p = snd_soc_codec_get_drvdata(codec);
+	u32  j = 0;
+	u32  ret = 0;
+	codec->control_data = dev_get_drvdata(codec->dev->parent);
+	tabla = codec->control_data;
+	/* Execute the callback only if interface type is slimbus */
+	if (tabla_p->intf_type != TABLA_INTERFACE_TYPE_SLIMBUS)
+		return 0;
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		for (j = 0; j < ARRAY_SIZE(tabla_dai); j++) {
+			if (tabla_dai[j].id == AIF1_CAP)
+				continue;
+			if (!strncmp(w->sname,
+				tabla_dai[j].playback.stream_name, 13)) {
+				++tabla_p->dai[j].ch_act;
+				break;
+			}
+		}
+		if (tabla_p->dai[j].ch_act == tabla_p->dai[j].ch_tot)
+			ret = tabla_cfg_slim_sch_rx(tabla,
+						tabla_p->dai[j].ch_num,
+						tabla_p->dai[j].ch_tot,
+						tabla_p->dai[j].rate);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		for (j = 0; j < ARRAY_SIZE(tabla_dai); j++) {
+			if (tabla_dai[j].id == AIF1_CAP)
+				continue;
+			if (!strncmp(w->sname,
+				tabla_dai[j].playback.stream_name, 13)) {
+				--tabla_p->dai[j].ch_act;
+				break;
+			}
+		}
+		if (!tabla_p->dai[j].ch_act) {
+			ret = tabla_close_slim_sch_rx(tabla,
+						tabla_p->dai[j].ch_num,
+						tabla_p->dai[j].ch_tot);
+			tabla_p->dai[j].rate = 0;
+			memset(tabla_p->dai[j].ch_num, 0, (sizeof(u32)*
+						tabla_p->dai[j].ch_tot));
+			tabla_p->dai[j].ch_tot = 0;
+		}
+	}
+	return ret;
+}
+
+static int tabla_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event)
+{
+	struct tabla *tabla;
+	struct snd_soc_codec *codec = w->codec;
+	struct tabla_priv *tabla_p = snd_soc_codec_get_drvdata(codec);
+	/* index to the DAI ID, for now hardcoding */
+	u32  j = 0;
+	u32  ret = 0;
+
+	codec->control_data = dev_get_drvdata(codec->dev->parent);
+	tabla = codec->control_data;
+
+	/* Execute the callback only if interface type is slimbus */
+	if (tabla_p->intf_type != TABLA_INTERFACE_TYPE_SLIMBUS)
+		return 0;
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		for (j = 0; j < ARRAY_SIZE(tabla_dai); j++) {
+			if (tabla_dai[j].id == AIF1_PB)
+				continue;
+			if (!strncmp(w->sname,
+				tabla_dai[j].capture.stream_name, 13)) {
+				++tabla_p->dai[j].ch_act;
+				break;
+			}
+		}
+		if (tabla_p->dai[j].ch_act == tabla_p->dai[j].ch_tot)
+			ret = tabla_cfg_slim_sch_tx(tabla,
+						tabla_p->dai[j].ch_num,
+						tabla_p->dai[j].ch_tot,
+						tabla_p->dai[j].rate);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		for (j = 0; j < ARRAY_SIZE(tabla_dai); j++) {
+			if (tabla_dai[j].id == AIF1_PB)
+				continue;
+			if (!strncmp(w->sname,
+				tabla_dai[j].capture.stream_name, 13)) {
+				--tabla_p->dai[j].ch_act;
+				break;
+			}
+		}
+		if (!tabla_p->dai[j].ch_act) {
+			ret = tabla_close_slim_sch_tx(tabla,
+						tabla_p->dai[j].ch_num,
+						tabla_p->dai[j].ch_tot);
+			tabla_p->dai[j].rate = 0;
+			memset(tabla_p->dai[j].ch_num, 0, (sizeof(u32)*
+						tabla_p->dai[j].ch_tot));
+			tabla_p->dai[j].ch_tot = 0;
+		}
+	}
+	return ret;
+}
+
+/* Todo: Have seperate dapm widgets for I2S and Slimbus.
+ * Might Need to have callbacks registered only for slimbus
+ */
+static const struct snd_soc_dapm_widget tabla_dapm_widgets[] = {
+	/*RX stuff */
+	SND_SOC_DAPM_OUTPUT("EAR"),
+
+	SND_SOC_DAPM_PGA("EAR PA", TABLA_A_RX_EAR_EN, 4, 0, NULL, 0),
+
+	SND_SOC_DAPM_MIXER("DAC1", TABLA_A_RX_EAR_EN, 6, 0, dac1_switch,
+		ARRAY_SIZE(dac1_switch)),
+
+	SND_SOC_DAPM_AIF_IN_E("SLIM RX1", "AIF1 Playback", 0, SND_SOC_NOPM, 0,
+				0, tabla_codec_enable_slimrx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_AIF_IN_E("SLIM RX2", "AIF1 Playback", 0, SND_SOC_NOPM, 0,
+				0, tabla_codec_enable_slimrx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_IN("SLIM RX3", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_IN("SLIM RX4", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
+
+	/* Headphone */
+	SND_SOC_DAPM_OUTPUT("HEADPHONE"),
+	SND_SOC_DAPM_PGA_E("HPHL", TABLA_A_RX_HPH_CNP_EN, 5, 0, NULL, 0,
+		tabla_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
+			SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MIXER("HPHL DAC", TABLA_A_RX_HPH_L_DAC_CTL, 7, 0,
+		hphl_switch, ARRAY_SIZE(hphl_switch)),
+
+	SND_SOC_DAPM_PGA_E("HPHR", TABLA_A_RX_HPH_CNP_EN, 4, 0, NULL, 0,
+		tabla_hph_pa_event, SND_SOC_DAPM_PRE_PMU |
+			SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_DAC_E("HPHR DAC", NULL, TABLA_A_RX_HPH_R_DAC_CTL, 7, 0,
+		tabla_hphr_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	/* Speaker */
+	SND_SOC_DAPM_OUTPUT("LINEOUT1"),
+	SND_SOC_DAPM_OUTPUT("LINEOUT2"),
+	SND_SOC_DAPM_OUTPUT("LINEOUT3"),
+	SND_SOC_DAPM_OUTPUT("LINEOUT4"),
+	SND_SOC_DAPM_OUTPUT("LINEOUT5"),
+
+	SND_SOC_DAPM_PGA_E("LINEOUT1 PA", TABLA_A_RX_LINE_CNP_EN, 0, 0, NULL,
+			0, tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
+			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_PGA_E("LINEOUT2 PA", TABLA_A_RX_LINE_CNP_EN, 1, 0, NULL,
+			0, tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
+			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_PGA_E("LINEOUT3 PA", TABLA_A_RX_LINE_CNP_EN, 2, 0, NULL,
+			0, tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
+			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_PGA_E("LINEOUT4 PA", TABLA_A_RX_LINE_CNP_EN, 3, 0, NULL,
+			0, tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
+			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_PGA_E("LINEOUT5 PA", TABLA_A_RX_LINE_CNP_EN, 4, 0, NULL, 0,
+		tabla_codec_enable_lineout, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_DAC_E("LINEOUT1 DAC", NULL, TABLA_A_RX_LINE_1_DAC_CTL, 7, 0
+		, tabla_lineout_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_DAC_E("LINEOUT2 DAC", NULL, TABLA_A_RX_LINE_2_DAC_CTL, 7, 0
+		, tabla_lineout_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_DAC_E("LINEOUT3 DAC", NULL, TABLA_A_RX_LINE_3_DAC_CTL, 7, 0
+		, tabla_lineout_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SWITCH("LINEOUT3 DAC GROUND", SND_SOC_NOPM, 0, 0,
+				&lineout3_ground_switch),
+	SND_SOC_DAPM_DAC_E("LINEOUT4 DAC", NULL, TABLA_A_RX_LINE_4_DAC_CTL, 7, 0
+		, tabla_lineout_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SWITCH("LINEOUT4 DAC GROUND", SND_SOC_NOPM, 0, 0,
+				&lineout4_ground_switch),
+	SND_SOC_DAPM_DAC_E("LINEOUT5 DAC", NULL, TABLA_A_RX_LINE_5_DAC_CTL, 7, 0
+		, tabla_lineout_dac_event,
+		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MIXER_E("RX1 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 0, 0, NULL,
+		0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
+	SND_SOC_DAPM_MIXER_E("RX2 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 1, 0, NULL,
+		0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
+	SND_SOC_DAPM_MIXER_E("RX3 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 2, 0, NULL,
+		0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
+	SND_SOC_DAPM_MIXER_E("RX4 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 3, 0, NULL,
+		0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
+	SND_SOC_DAPM_MIXER_E("RX5 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 4, 0, NULL,
+		0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
+	SND_SOC_DAPM_MIXER_E("RX6 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 5, 0, NULL,
+		0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
+	SND_SOC_DAPM_MIXER_E("RX7 MIX1", TABLA_A_CDC_CLK_RX_B1_CTL, 6, 0, NULL,
+		0, tabla_codec_reset_interpolator, SND_SOC_DAPM_PRE_PMU),
+
+	SND_SOC_DAPM_MUX_E("RX4 DSM MUX", TABLA_A_CDC_CLK_RX_B1_CTL, 3, 0,
+		&rx4_dsm_mux, tabla_codec_reset_interpolator,
+		SND_SOC_DAPM_PRE_PMU),
+
+	SND_SOC_DAPM_MUX_E("RX6 DSM MUX", TABLA_A_CDC_CLK_RX_B1_CTL, 5, 0,
+		&rx6_dsm_mux, tabla_codec_reset_interpolator,
+		SND_SOC_DAPM_PRE_PMU),
+
+	SND_SOC_DAPM_MIXER("RX1 CHAIN", TABLA_A_CDC_RX1_B6_CTL, 5, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER("RX2 CHAIN", TABLA_A_CDC_RX2_B6_CTL, 5, 0, NULL, 0),
+
+	SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+		&rx_mix1_inp1_mux),
+	SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+		&rx_mix1_inp2_mux),
+	SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+		&rx2_mix1_inp1_mux),
+	SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+		&rx2_mix1_inp2_mux),
+	SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+		&rx3_mix1_inp1_mux),
+	SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+		&rx3_mix1_inp2_mux),
+	SND_SOC_DAPM_MUX("RX4 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+		&rx4_mix1_inp1_mux),
+	SND_SOC_DAPM_MUX("RX4 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+		&rx4_mix1_inp2_mux),
+	SND_SOC_DAPM_MUX("RX5 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+		&rx5_mix1_inp1_mux),
+	SND_SOC_DAPM_MUX("RX5 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+		&rx5_mix1_inp2_mux),
+	SND_SOC_DAPM_MUX("RX6 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+		&rx6_mix1_inp1_mux),
+	SND_SOC_DAPM_MUX("RX6 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+		&rx6_mix1_inp2_mux),
+	SND_SOC_DAPM_MUX("RX7 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+		&rx7_mix1_inp1_mux),
+	SND_SOC_DAPM_MUX("RX7 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+		&rx7_mix1_inp2_mux),
+
+	SND_SOC_DAPM_SUPPLY("CP", TABLA_A_CP_EN, 0, 0,
+		tabla_codec_enable_charge_pump, SND_SOC_DAPM_POST_PMU |
+		SND_SOC_DAPM_PRE_PMD),
+
+	SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
+		tabla_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	/* TX */
+
+	SND_SOC_DAPM_SUPPLY("CDC_CONN", TABLA_A_CDC_CLK_OTHR_CTL, 2, 0, NULL,
+		0),
+
+	SND_SOC_DAPM_SUPPLY("LDO_H", TABLA_A_LDO_H_MODE_1, 7, 0,
+		tabla_codec_enable_ldo_h, SND_SOC_DAPM_POST_PMU),
+
+	SND_SOC_DAPM_INPUT("AMIC1"),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", TABLA_A_MICB_1_CTL, 7, 0,
+		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal1", TABLA_A_MICB_1_CTL, 7, 0,
+		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 Internal2", TABLA_A_MICB_1_CTL, 7, 0,
+		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_ADC_E("ADC1", NULL, TABLA_A_TX_1_2_EN, 7, 0,
+		tabla_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_INPUT("AMIC3"),
+	SND_SOC_DAPM_ADC_E("ADC3", NULL, TABLA_A_TX_3_4_EN, 7, 0,
+		tabla_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_INPUT("AMIC4"),
+	SND_SOC_DAPM_ADC_E("ADC4", NULL, TABLA_A_TX_3_4_EN, 3, 0,
+		tabla_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_INPUT("AMIC5"),
+	SND_SOC_DAPM_ADC_E("ADC5", NULL, TABLA_A_TX_5_6_EN, 7, 0,
+		tabla_codec_enable_adc, SND_SOC_DAPM_POST_PMU),
+
+	SND_SOC_DAPM_INPUT("AMIC6"),
+	SND_SOC_DAPM_ADC_E("ADC6", NULL, TABLA_A_TX_5_6_EN, 3, 0,
+		tabla_codec_enable_adc, SND_SOC_DAPM_POST_PMU),
+
+	SND_SOC_DAPM_MUX_E("DEC1 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 0, 0,
+		&dec1_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+	SND_SOC_DAPM_MUX_E("DEC2 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 1, 0,
+		&dec2_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+	SND_SOC_DAPM_MUX_E("DEC3 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 2, 0,
+		&dec3_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+	SND_SOC_DAPM_MUX_E("DEC4 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 3, 0,
+		&dec4_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+	SND_SOC_DAPM_MUX_E("DEC5 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 4, 0,
+		&dec5_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+	SND_SOC_DAPM_MUX_E("DEC6 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 5, 0,
+		&dec6_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+	SND_SOC_DAPM_MUX_E("DEC7 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 6, 0,
+		&dec7_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+	SND_SOC_DAPM_MUX_E("DEC8 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL, 7, 0,
+		&dec8_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+	SND_SOC_DAPM_MUX_E("DEC9 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B2_CTL, 0, 0,
+		&dec9_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+	SND_SOC_DAPM_MUX_E("DEC10 MUX", TABLA_A_CDC_CLK_TX_CLK_EN_B2_CTL, 1, 0,
+		&dec10_mux, tabla_codec_enable_dec, SND_SOC_DAPM_PRE_PMU),
+
+	SND_SOC_DAPM_MUX("ANC1 MUX", SND_SOC_NOPM, 0, 0, &anc1_mux),
+	SND_SOC_DAPM_MUX("ANC2 MUX", SND_SOC_NOPM, 0, 0, &anc2_mux),
+
+	SND_SOC_DAPM_MIXER_E("ANC", SND_SOC_NOPM, 0, 0, NULL, 0,
+		tabla_codec_enable_anc, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
+
+	SND_SOC_DAPM_INPUT("AMIC2"),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 External", TABLA_A_MICB_2_CTL, 7, 0,
+		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU |	SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal1", TABLA_A_MICB_2_CTL, 7, 0,
+		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal2", TABLA_A_MICB_2_CTL, 7, 0,
+		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS2 Internal3", TABLA_A_MICB_2_CTL, 7, 0,
+		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 External", TABLA_A_MICB_3_CTL, 7, 0,
+		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal1", TABLA_A_MICB_3_CTL, 7, 0,
+		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MICBIAS_E("MIC BIAS3 Internal2", TABLA_A_MICB_3_CTL, 7, 0,
+		tabla_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_ADC_E("ADC2", NULL, TABLA_A_TX_1_2_EN, 3, 0,
+		tabla_codec_enable_adc, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, 0, 0, &sb_tx1_mux),
+	SND_SOC_DAPM_AIF_OUT("SLIM TX1", "AIF1 Capture", NULL, SND_SOC_NOPM,
+			0, 0),
+
+	SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, 0, 0, &sb_tx5_mux),
+	SND_SOC_DAPM_AIF_OUT("SLIM TX5", "AIF1 Capture", NULL, SND_SOC_NOPM,
+			4, 0),
+
+	SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, 0, 0, &sb_tx6_mux),
+	SND_SOC_DAPM_AIF_OUT("SLIM TX6", "AIF1 Capture", NULL, SND_SOC_NOPM,
+			5, 0),
+
+	SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, 0, 0, &sb_tx7_mux),
+	SND_SOC_DAPM_AIF_OUT_E("SLIM TX7", "AIF1 Capture", 0, SND_SOC_NOPM, 0,
+				0, tabla_codec_enable_slimtx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, 0, 0, &sb_tx8_mux),
+	SND_SOC_DAPM_AIF_OUT_E("SLIM TX8", "AIF1 Capture", 0, SND_SOC_NOPM, 0,
+				0, tabla_codec_enable_slimtx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX("SLIM TX9 MUX", SND_SOC_NOPM, 0, 0, &sb_tx9_mux),
+	SND_SOC_DAPM_AIF_OUT_E("SLIM TX9", "AIF1 Capture", NULL, SND_SOC_NOPM,
+			0, 0, tabla_codec_enable_slimtx,
+			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_MUX("SLIM TX10 MUX", SND_SOC_NOPM, 0, 0, &sb_tx10_mux),
+	SND_SOC_DAPM_AIF_OUT_E("SLIM TX10", "AIF1 Capture", NULL, SND_SOC_NOPM,
+			0, 0, tabla_codec_enable_slimtx,
+			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	/* Digital Mic Inputs */
+	SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
+		tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0,
+		tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0,
+		tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0,
+		tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0,
+		tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 0, 0,
+		tabla_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+		SND_SOC_DAPM_POST_PMD),
+
+	/* Sidetone */
+	SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
+	SND_SOC_DAPM_PGA("IIR1", TABLA_A_CDC_CLK_SD_CTL, 0, 0, NULL, 0),
+};
+
 static short tabla_codec_read_sta_result(struct snd_soc_codec *codec)
 {
 	u8 bias_msb, bias_lsb;
@@ -4680,6 +4883,7 @@
 	struct snd_soc_dapm_context *dapm = &codec->dapm;
 	int ret = 0;
 	int i;
+	int ch_cnt;
 
 	codec->control_data = dev_get_drvdata(codec->dev->parent);
 	control = codec->control_data;
@@ -4831,6 +5035,20 @@
 		goto err_hphr_ocp_irq;
 	}
 	tabla_disable_irq(codec->control_data, TABLA_IRQ_HPH_PA_OCPR_FAULT);
+	for (i = 0; i < ARRAY_SIZE(tabla_dai); i++) {
+		switch (tabla_dai[i].id) {
+		case AIF1_PB:
+			ch_cnt = tabla_dai[i].playback.channels_max;
+			break;
+		case AIF1_CAP:
+			ch_cnt = tabla_dai[i].capture.channels_max;
+			break;
+		default:
+			continue;
+		}
+		tabla->dai[i].ch_num = kzalloc((sizeof(unsigned int)*
+					ch_cnt), GFP_KERNEL);
+	}
 
 #ifdef CONFIG_DEBUG_FS
 	debug_tabla_priv = tabla;
@@ -4857,6 +5075,7 @@
 }
 static int tabla_codec_remove(struct snd_soc_codec *codec)
 {
+	int i;
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
 	tabla_free_irq(codec->control_data, TABLA_IRQ_SLIMBUS, tabla);
 	tabla_free_irq(codec->control_data, TABLA_IRQ_MBHC_RELEASE, tabla);
@@ -4867,6 +5086,8 @@
 	tabla_codec_enable_bandgap(codec, TABLA_BANDGAP_OFF);
 	if (tabla->mbhc_fw)
 		release_firmware(tabla->mbhc_fw);
+	for (i = 0; i < ARRAY_SIZE(tabla_dai); i++)
+		kfree(tabla->dai[i].ch_num);
 	kfree(tabla);
 	return 0;
 }
diff --git a/sound/soc/codecs/wcd9310.h b/sound/soc/codecs/wcd9310.h
index 6ddc471..9c430b9 100644
--- a/sound/soc/codecs/wcd9310.h
+++ b/sound/soc/codecs/wcd9310.h
@@ -11,6 +11,7 @@
  */
 #include <sound/soc.h>
 #include <sound/jack.h>
+#include <linux/mfd/wcd9310/wcd9310-slimslave.h>
 
 #define TABLA_NUM_REGISTERS 0x400
 #define TABLA_MAX_REGISTER (TABLA_NUM_REGISTERS-1)
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index bd41e0b..e69d134 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -671,6 +671,66 @@
 	return tabla_cal;
 }
 
+static int msm_hw_params(struct snd_pcm_substream *substream,
+				struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	int ret = 0;
+	unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
+	unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0;
+
+	pr_debug("%s: ch=%d\n", __func__,
+					msm_slim_0_rx_ch);
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		ret = snd_soc_dai_get_channel_map(codec_dai,
+				&tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
+		if (ret < 0) {
+			pr_err("%s: failed to get codec chan map\n", __func__);
+			goto end;
+		}
+
+		ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
+				msm_slim_0_rx_ch, rx_ch);
+		if (ret < 0) {
+			pr_err("%s: failed to set cpu chan map\n", __func__);
+			goto end;
+		}
+		ret = snd_soc_dai_set_channel_map(codec_dai, 0, 0,
+				msm_slim_0_rx_ch, rx_ch);
+		if (ret < 0) {
+			pr_err("%s: failed to set codec channel map\n",
+								__func__);
+			goto end;
+		}
+	} else {
+		ret = snd_soc_dai_get_channel_map(codec_dai,
+				&tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
+		if (ret < 0) {
+			pr_err("%s: failed to get codec chan map\n", __func__);
+			goto end;
+		}
+		ret = snd_soc_dai_set_channel_map(cpu_dai,
+				msm_slim_0_tx_ch, tx_ch, 0 , 0);
+		if (ret < 0) {
+			pr_err("%s: failed to set cpu chan map\n", __func__);
+			goto end;
+		}
+		ret = snd_soc_dai_set_channel_map(codec_dai,
+				msm_slim_0_tx_ch, tx_ch, 0, 0);
+		if (ret < 0) {
+			pr_err("%s: failed to set codec channel map\n",
+								__func__);
+			goto end;
+		}
+
+
+	}
+end:
+	return ret;
+}
+
 static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
 {
 	int err;
@@ -805,6 +865,23 @@
 	return 0;
 }
 
+static int msm_hdmi_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+					struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_RATE);
+
+	struct snd_interval *channels = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_CHANNELS);
+
+	pr_debug("%s channels->min %u channels->max %u ()\n", __func__,
+			channels->min, channels->max);
+
+	rate->min = rate->max = 48000;
+
+	return 0;
+}
+
 static int msm_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 					struct snd_pcm_hw_params *params)
 {
@@ -924,6 +1001,7 @@
 
 static struct snd_soc_ops msm_be_ops = {
 	.startup = msm_startup,
+	.hw_params = msm_hw_params,
 	.shutdown = msm_shutdown,
 };
 
@@ -1099,14 +1177,14 @@
 	{
 		.name = LPASS_BE_HDMI,
 		.stream_name = "HDMI Playback",
-		.cpu_dai_name = "msm-dai-q6.8",
+		.cpu_dai_name = "msm-dai-q6-hdmi.8",
 		.platform_name = "msm-pcm-routing",
 		.codec_name     = "msm-stub-codec.1",
 		.codec_dai_name = "msm-stub-rx",
 		.no_pcm = 1,
 		.no_codec = 1,
 		.be_id = MSM_BACKEND_DAI_HDMI_RX,
-		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.be_hw_params_fixup = msm_hdmi_be_hw_params_fixup,
 	},
 	/* Backend AFE DAI Links */
 	{
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index 0951795..aff87ae 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -211,81 +211,28 @@
 				    struct snd_soc_dai *dai, int stream)
 {
 	struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
-	u8 pgd_la, inf_la;
-	u16 *slave_port_mapping;
-
-	memset(dai_data->port_config.slimbus.slave_port_mapping, 0,
-		sizeof(dai_data->port_config.slimbus.slave_port_mapping));
 
 	dai_data->channels = params_channels(params);
-
-	slave_port_mapping = dai_data->port_config.slimbus.slave_port_mapping;
-
-	switch (dai_data->channels) {
-	case 4:
-		if (dai->id == SLIMBUS_0_TX) {
-			slave_port_mapping[0] = 7;
-			slave_port_mapping[1] = 8;
-			slave_port_mapping[2] = 9;
-			slave_port_mapping[3] = 10;
-		} else {
-			return -EINVAL;
-		}
-		break;
-	case 3:
-		if (dai->id == SLIMBUS_0_TX) {
-			slave_port_mapping[0] = 7;
-			slave_port_mapping[1] = 8;
-			slave_port_mapping[2] = 9;
-		} else {
-			return -EINVAL;
-		}
-		break;
-	case 2:
-		if (dai->id == SLIMBUS_0_RX) {
-			slave_port_mapping[0] = 1;
-			slave_port_mapping[1] = 2;
-		} else {
-			slave_port_mapping[0] = 7;
-			slave_port_mapping[1] = 8;
-		}
-		break;
-	case 1:
-		if (dai->id == SLIMBUS_0_RX)
-			slave_port_mapping[0] = 1;
-		else
-			slave_port_mapping[0] = 7;
-		break;
-	default:
-		return -EINVAL;
-		break;
-	}
 	dai_data->rate = params_rate(params);
-	tabla_get_logical_addresses(&pgd_la, &inf_la);
 
 	dai_data->port_config.slimbus.slimbus_dev_id =  AFE_SLIMBUS_DEVICE_1;
-	dai_data->port_config.slimbus.slave_dev_pgd_la = pgd_la;
-	dai_data->port_config.slimbus.slave_dev_intfdev_la = inf_la;
 	/* Q6 only supports 16 as now */
-	dai_data->port_config.slimbus.bit_width = 16;
-	dai_data->port_config.slimbus.data_format = 0;
-	dai_data->port_config.slimbus.num_channels = dai_data->channels;
-	dai_data->port_config.slimbus.reserved = 0;
+	dai_data->port_config.slim_sch.bit_width = 16;
+	dai_data->port_config.slim_sch.data_format = 0;
+	dai_data->port_config.slim_sch.num_channels = dai_data->channels;
+	dai_data->port_config.slim_sch.reserved = 0;
 
-	dev_dbg(dai->dev, "slimbus_dev_id  %hu  slave_dev_pgd_la 0x%hx\n"
-		"slave_dev_intfdev_la 0x%hx   bit_width %hu   data_format %hu\n"
-		"num_channel %hu  slave_port_mapping[0]  %hu\n"
+	dev_dbg(dai->dev, "%s:slimbus_dev_id[%hu] bit_wd[%hu] format[%hu]\n"
+		"num_channel %hu  slave_ch_mapping[0]  %hu\n"
 		"slave_port_mapping[1]  %hu slave_port_mapping[2]  %hu\n"
-		"sample_rate %d\n",
-		dai_data->port_config.slimbus.slimbus_dev_id,
-		dai_data->port_config.slimbus.slave_dev_pgd_la,
-		dai_data->port_config.slimbus.slave_dev_intfdev_la,
-		dai_data->port_config.slimbus.bit_width,
-		dai_data->port_config.slimbus.data_format,
-		dai_data->port_config.slimbus.num_channels,
-		dai_data->port_config.slimbus.slave_port_mapping[0],
-		dai_data->port_config.slimbus.slave_port_mapping[1],
-		dai_data->port_config.slimbus.slave_port_mapping[2],
+		"sample_rate %d\n", __func__,
+		dai_data->port_config.slim_sch.slimbus_dev_id,
+		dai_data->port_config.slim_sch.bit_width,
+		dai_data->port_config.slim_sch.data_format,
+		dai_data->port_config.slim_sch.num_channels,
+		dai_data->port_config.slim_sch.slave_ch_mapping[0],
+		dai_data->port_config.slim_sch.slave_ch_mapping[1],
+		dai_data->port_config.slim_sch.slave_ch_mapping[2],
 		dai_data->rate);
 
 	return 0;
@@ -784,7 +731,8 @@
 {
 	int rc = 0;
 
-	dev_dbg(dai->dev, "enter %s, id = %d\n", __func__, dai->id);
+	dev_dbg(dai->dev, "enter %s, id = %d fmt[%d]\n", __func__,
+							dai->id, fmt);
 	switch (dai->id) {
 	case PRIMARY_I2S_TX:
 	case PRIMARY_I2S_RX:
@@ -801,12 +749,69 @@
 	return rc;
 }
 
+static int msm_dai_q6_set_channel_map(struct snd_soc_dai *dai,
+				unsigned int tx_num, unsigned int *tx_slot,
+				unsigned int rx_num, unsigned int *rx_slot)
+
+{
+	int rc = 0;
+	struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
+	unsigned int i = 0;
+
+	dev_dbg(dai->dev, "enter %s, id = %d\n", __func__,
+							dai->id);
+	if (!tx_slot && !rx_slot)
+		return -EINVAL;
+	switch (dai->id) {
+	case SLIMBUS_0_RX:
+		/* channel number to be between 128 and 255. For RX port
+		 * use channel numbers from 138 to 144, for TX port
+		 * use channel numbers from 128 to 137
+		 */
+		for (i = 0; i < rx_num; i++) {
+			dai_data->port_config.slim_sch.slave_ch_mapping[i] =
+							rx_slot[i];
+			pr_debug("%s: find number of channels[%d] ch[%d]\n",
+							__func__, i,
+							rx_slot[i]);
+		}
+		dai_data->port_config.slim_sch.num_channels = rx_num;
+		pr_debug("%s:SLIMBUS_0_RX cnt[%d] ch[%d %d]\n", __func__,
+		rx_num, dai_data->port_config.slim_sch.slave_ch_mapping[0],
+		dai_data->port_config.slim_sch.slave_ch_mapping[1]);
+
+		break;
+	case SLIMBUS_0_TX:
+		/* channel number to be between 128 and 255. For RX port
+		 * use channel numbers from 138 to 144, for TX port
+		 * use channel numbers from 128 to 137
+		 */
+		for (i = 0; i < tx_num; i++) {
+			dai_data->port_config.slim_sch.slave_ch_mapping[i] =
+							tx_slot[i];
+			pr_debug("%s: find number of channels[%d] ch[%d]\n",
+						__func__, i, tx_slot[i]);
+		}
+		dai_data->port_config.slim_sch.num_channels = tx_num;
+		pr_debug("%s:SLIMBUS_0_TX cnt[%d] ch[%d %d]\n", __func__,
+		tx_num, dai_data->port_config.slim_sch.slave_ch_mapping[0],
+		dai_data->port_config.slim_sch.slave_ch_mapping[1]);
+		break;
+	default:
+		dev_err(dai->dev, "invalid cpu_dai set_fmt\n");
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
+
 static struct snd_soc_dai_ops msm_dai_q6_ops = {
 	.prepare	= msm_dai_q6_prepare,
 	.trigger	= msm_dai_q6_trigger,
 	.hw_params	= msm_dai_q6_hw_params,
 	.shutdown	= msm_dai_q6_shutdown,
 	.set_fmt	= msm_dai_q6_set_fmt,
+	.set_channel_map = msm_dai_q6_set_channel_map,
 };
 
 static struct snd_soc_dai_ops msm_dai_q6_auxpcm_ops = {
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index 1ed73e2..bedfd68 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -643,6 +643,66 @@
 	return tabla_cal;
 }
 
+static int msm8960_hw_params(struct snd_pcm_substream *substream,
+				struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	int ret = 0;
+	unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
+	unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0;
+
+	pr_debug("%s: ch=%d\n", __func__,
+					msm8960_slim_0_rx_ch);
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		ret = snd_soc_dai_get_channel_map(codec_dai,
+				&tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
+		if (ret < 0) {
+			pr_err("%s: failed to get codec chan map\n", __func__);
+			goto end;
+		}
+
+		ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
+				msm8960_slim_0_rx_ch, rx_ch);
+		if (ret < 0) {
+			pr_err("%s: failed to set cpu chan map\n", __func__);
+			goto end;
+		}
+		ret = snd_soc_dai_set_channel_map(codec_dai, 0, 0,
+				msm8960_slim_0_rx_ch, rx_ch);
+		if (ret < 0) {
+			pr_err("%s: failed to set codec channel map\n",
+								__func__);
+			goto end;
+		}
+	} else {
+		ret = snd_soc_dai_get_channel_map(codec_dai,
+				&tx_ch_cnt, tx_ch, &rx_ch_cnt , rx_ch);
+		if (ret < 0) {
+			pr_err("%s: failed to get codec chan map\n", __func__);
+			goto end;
+		}
+		ret = snd_soc_dai_set_channel_map(cpu_dai,
+				msm8960_slim_0_tx_ch, tx_ch, 0 , 0);
+		if (ret < 0) {
+			pr_err("%s: failed to set cpu chan map\n", __func__);
+			goto end;
+		}
+		ret = snd_soc_dai_set_channel_map(codec_dai,
+				msm8960_slim_0_tx_ch, tx_ch, 0, 0);
+		if (ret < 0) {
+			pr_err("%s: failed to set codec channel map\n",
+								__func__);
+			goto end;
+		}
+
+
+	}
+end:
+	return ret;
+}
+
 static int msm8960_audrx_init(struct snd_soc_pcm_runtime *rtd)
 {
 	int err;
@@ -914,6 +974,7 @@
 
 static struct snd_soc_ops msm8960_be_ops = {
 	.startup = msm8960_startup,
+	.hw_params = msm8960_hw_params,
 	.shutdown = msm8960_shutdown,
 };
 
diff --git a/sound/soc/msm/qdsp6/q6afe.c b/sound/soc/msm/qdsp6/q6afe.c
index ef01fb3..59506f1 100644
--- a/sound/soc/msm/qdsp6/q6afe.c
+++ b/sound/soc/msm/qdsp6/q6afe.c
@@ -78,6 +78,7 @@
 			switch (payload[0]) {
 			case AFE_PORT_AUDIO_IF_CONFIG:
 			case AFE_PORT_MULTI_CHAN_HDMI_AUDIO_IF_CONFIG:
+			case AFE_PORT_AUDIO_SLIM_SCH_CONFIG:
 			case AFE_PORT_CMD_STOP:
 			case AFE_PORT_CMD_START:
 			case AFE_PORT_CMD_LOOPBACK:
@@ -285,7 +286,7 @@
 		break;
 	case SLIMBUS_0_RX:
 	case SLIMBUS_0_TX:
-		ret_size = SIZEOF_CFG_CMD(afe_port_slimbus_cfg);
+		ret_size = SIZEOF_CFG_CMD(afe_port_slimbus_sch_cfg);
 		break;
 	case RT_PROXY_PORT_001_RX:
 	case RT_PROXY_PORT_001_TX:
@@ -418,7 +419,23 @@
 		config.hdr.src_port = 0;
 		config.hdr.dest_port = 0;
 		config.hdr.token = 0;
-		config.hdr.opcode = AFE_PORT_AUDIO_IF_CONFIG;
+		switch (port_id) {
+		case SLIMBUS_0_RX:
+		case SLIMBUS_0_TX:
+		case SLIMBUS_1_RX:
+		case SLIMBUS_1_TX:
+		case SLIMBUS_2_RX:
+		case SLIMBUS_2_TX:
+		case SLIMBUS_3_RX:
+		case SLIMBUS_3_TX:
+		case SLIMBUS_4_RX:
+		case SLIMBUS_4_TX:
+			config.hdr.opcode = AFE_PORT_AUDIO_SLIM_SCH_CONFIG;
+		break;
+		default:
+			config.hdr.opcode = AFE_PORT_AUDIO_IF_CONFIG;
+		break;
+		}
 	}
 
 	if (afe_validate_port(port_id) < 0) {
@@ -485,7 +502,7 @@
 		return ret;
 	}
 
-	pr_info("%s: %d %d\n", __func__, port_id, rate);
+	pr_debug("%s: %d %d\n", __func__, port_id, rate);
 
 	if ((port_id == RT_PROXY_DAI_001_RX) ||
 		(port_id == RT_PROXY_DAI_002_TX))
@@ -793,7 +810,7 @@
 	int ret = 0;
 	struct afe_pseudoport_start_command start;
 
-	pr_info("%s: port_id=%d\n", __func__, port_id);
+	pr_debug("%s: port_id=%d\n", __func__, port_id);
 
 	ret = afe_q6_interface_prepare();
 	if (ret != 0)
@@ -866,7 +883,7 @@
 	int ret = 0;
 	struct afe_pseudoport_stop_command stop;
 
-	pr_info("%s: port_id=%d\n", __func__, port_id);
+	pr_debug("%s: port_id=%d\n", __func__, port_id);
 
 	if (this_afe.apr == NULL) {
 		pr_err("%s: AFE is already closed\n", __func__);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 219ae10..d528f4b 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3673,6 +3673,29 @@
 EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map);
 
 /**
+ * snd_soc_dai_get_channel_map - configure DAI audio channel map
+ * @dai: DAI
+ * @tx_num: how many TX channels
+ * @tx_slot: pointer to an array which imply the TX slot number channel
+ *           0~num-1 uses
+ * @rx_num: how many RX channels
+ * @rx_slot: pointer to an array which imply the RX slot number channel
+ *           0~num-1 uses
+ *
+ * configure the relationship between channel number and TDM slot number.
+ */
+int snd_soc_dai_get_channel_map(struct snd_soc_dai *dai,
+	unsigned int *tx_num, unsigned int *tx_slot,
+	unsigned int *rx_num, unsigned int *rx_slot)
+{
+	if (dai->driver && dai->driver->ops->get_channel_map)
+		return dai->driver->ops->get_channel_map(dai, tx_num, tx_slot,
+			rx_num, rx_slot);
+	else
+		return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dai_get_channel_map);
+/**
  * snd_soc_dai_set_tristate - configure DAI system or master clock.
  * @dai: DAI
  * @tristate: tristate enable
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index b462639..c03f7ca7 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -2,6 +2,7 @@
  * soc-dapm.c  --  ALSA SoC Dynamic Audio Power Management
  *
  * Copyright 2005 Wolfson Microelectronics PLC.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Author: Liam Girdwood <lrg@slimlogic.co.uk>
  *
@@ -59,8 +60,6 @@
 	[snd_soc_dapm_pre] = 0,
 	[snd_soc_dapm_supply] = 1,
 	[snd_soc_dapm_micbias] = 2,
-	[snd_soc_dapm_aif_in] = 3,
-	[snd_soc_dapm_aif_out] = 3,
 	[snd_soc_dapm_mic] = 4,
 	[snd_soc_dapm_mux] = 5,
 	[snd_soc_dapm_virt_mux] = 5,
@@ -69,6 +68,8 @@
 	[snd_soc_dapm_mixer] = 7,
 	[snd_soc_dapm_mixer_named_ctl] = 7,
 	[snd_soc_dapm_pga] = 8,
+	[snd_soc_dapm_aif_in] = 8,
+	[snd_soc_dapm_aif_out] = 8,
 	[snd_soc_dapm_adc] = 9,
 	[snd_soc_dapm_out_drv] = 10,
 	[snd_soc_dapm_hp] = 10,
@@ -78,6 +79,8 @@
 
 static int dapm_down_seq[] = {
 	[snd_soc_dapm_pre] = 0,
+	[snd_soc_dapm_aif_in] = 1,
+	[snd_soc_dapm_aif_out] = 1,
 	[snd_soc_dapm_adc] = 1,
 	[snd_soc_dapm_hp] = 2,
 	[snd_soc_dapm_spk] = 2,
@@ -91,8 +94,6 @@
 	[snd_soc_dapm_mux] = 9,
 	[snd_soc_dapm_virt_mux] = 9,
 	[snd_soc_dapm_value_mux] = 9,
-	[snd_soc_dapm_aif_in] = 10,
-	[snd_soc_dapm_aif_out] = 10,
 	[snd_soc_dapm_supply] = 11,
 	[snd_soc_dapm_post] = 12,
 };