Merge changes Ibe1b5c65,Ic16b4028,Ia1f664a3 into msm-3.4

* changes:
  defconfig: 8974: Enable DLOAD mode for 8974
  msm: restart: Add support for download mode on 8974
  defconfig: 8974: Configure panic timeout for 8974
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
index 6db1150..82e76fc 100644
--- a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
@@ -14,6 +14,16 @@
 - qcom,mdss-pan-bpp:			Specifies the panel bits per pixel. Default value is 24(rgb888).
 					18 = for rgb666
 					16 = for rgb565
+- qcom,panel-phy-regulatorSettings:	An array of length 8 that specifies the PHY
+					regulator settings for the panel.
+- qcom,panel-phy-timingSettings:	An array of length 12 that specifies the PHY
+					timing settings for the panel.
+- qcom,panel-phy-strengthCtrl:		An array of length 2 that specifies the PHY
+					strengthCtrl settings for the panel.
+- qcom,panel-phy-bistCtrl:		An array of length 6 that specifies the PHY
+					BIST ctrl settings for the panel.
+- qcom,panel-phy-laneConfig:		An array of length 45 that specifies the PHY
+					lane configuration settings for the panel.
 - qcom,mdss-panel-on-cmds:		An array of variable length that lists the init commands
 					of the panel. Each command will have the format specified
 					as below:
@@ -42,9 +52,16 @@
 
 Optional properties:
 - label:		        	A string used as a descriptive name of the panel
+- qcom,enable-gpio:			Specifies the panel lcd/display enable gpio.
+- qcom,rst-gpio:			Specifies the panel reset gpio.
 - qcom,mdss-pan-porch-values:		An array of size 6 that specifies the panel blanking values.
 - qcom,mdss-pan-underflow-clr:		Specifies the controller settings for the panel underflow clear
 					settings. Default value is 0xff.
+- qcom,mdss-pan-bl-ctrl:		A string that specifies the implementation of backlight
+					control for this panel.
+					"bl_ctrl_pwm" = Backlight controlled by PWM gpio.
+					"bl_ctrl_wled" = Backlight controlled by WLED.
+					"bl_ctrl_dcs_cmds" = Backlight controlled by DCS commands.
 - qcom,mdss-pan-bl-levels:		Specifies the backlight levels supported by the panel.
 					Default range is 1 to 255.
 
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index ed84219..62258ca 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -60,7 +60,9 @@
 - reg  : pairs of physical base addresses and region sizes
             of all the memory mapped BAM devices present
 - reg-names : Register region name(s) referenced in reg above
-            SSUSB BAM expects "ssusb" and "hsusb" for HSSUB BAM
+            SSUSB BAM expects "ssusb" and "hsusb" for HSSUB BAM.
+            Specify "qscratch_ram1_reg" to provide QSCRATCH's RAM1
+            register to control USB3 private memory for uses as BAM FIFOs.
 - interrupts: IRQ lines for BAM devices
 - interrupt-names: BAM interrupt name(s) referenced in interrupts above
             SSUSB BAM expects "ssusb" and "hsusb" for HSSUB BAM
@@ -98,8 +100,9 @@
 	qcom,usbbam@f9304000 {
 		compatible = "qcom,usb-bam-msm";
 		reg = <0xf9304000 0x5000>,
-		      <0xf9a44000 0x11000>;
-		reg-names = "ssusb", "hsusb";
+		      <0xf9a44000 0x11000>,
+		      <0xf92f880c 0x4>;
+		reg-names = "ssusb", "hsusb", "qscratch_ram1_reg";
 		interrupts = <0 132 0 0 135 0>;
 		interrupt-names = "ssusb", "hsusb";
 		qcom,usb-active-bam = <0>;
@@ -138,7 +141,7 @@
 		qcom,pipe3 {
 			label = "usb-to-peri-qdss-hsusb";
 			qcom,usb-bam-type = <1>;
-			qcom,usb-bam-mem-type = <2>;
+			qcom,usb-bam-mem-type = <1>;
 			qcom,src-bam-physical-address = <0>;
 			qcom,src-bam-pipe-index = <0>;
 			qcom,dst-bam-physical-address = <0>;
@@ -152,14 +155,14 @@
 		qcom,pipe4 {
 			label = "peri-to-usb-qdss-hsusb";
 			qcom,usb-bam-type = <1>;
-			qcom,usb-bam-mem-type = <2>;
+			qcom,usb-bam-mem-type = <1>;
 			qcom,src-bam-physical-address = <0xfc37c000>;
 			qcom,src-bam-pipe-index = <0>;
 			qcom,dst-bam-physical-address = <0xf9a44000>;
 			qcom,dst-bam-pipe-index = <2>;
-			qcom,data-fifo-offset = <0>;
-			qcom,data-fifo-size = <0x4000>;
-			qcom,descriptor-fifo-offset = <0>;
-			qcom,descriptor-fifo-size = <0x1400>;
+			qcom,data-fifo-offset = <0xf4000>;
+			qcom,data-fifo-size = <0x1000>;
+			qcom,descriptor-fifo-offset = <0xf5000>;
+			qcom,descriptor-fifo-size = <0x400>;
 		};
 	};
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index d92d2f6..415122b 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -815,8 +815,9 @@
 	qcom,usbbam@f9304000 {
 		compatible = "qcom,usb-bam-msm";
 		reg = <0xf9304000 0x5000>,
-		      <0xf9a44000 0x11000>;
-		reg-names = "ssusb", "hsusb";
+		      <0xf9a44000 0x11000>,
+		      <0xf92f880c 0x4>;
+		reg-names = "ssusb", "hsusb", "qscratch_ram1_reg";
 		interrupts = <0 132 0 0 135 0>;
 		interrupt-names = "ssusb", "hsusb";
 		qcom,usb-active-bam = <0>;
@@ -855,7 +856,7 @@
 		qcom,pipe3 {
 			label = "usb-to-peri-qdss-hsusb";
 			qcom,usb-bam-type = <1>;
-			qcom,usb-bam-mem-type = <2>;
+			qcom,usb-bam-mem-type = <1>;
 			qcom,src-bam-physical-address = <0>;
 			qcom,src-bam-pipe-index = <0>;
 			qcom,dst-bam-physical-address = <0>;
@@ -869,15 +870,15 @@
 		qcom,pipe4 {
 			label = "peri-to-usb-qdss-hsusb";
 			qcom,usb-bam-type = <1>;
-			qcom,usb-bam-mem-type = <2>;
+			qcom,usb-bam-mem-type = <1>;
 			qcom,src-bam-physical-address = <0xfc37c000>;
 			qcom,src-bam-pipe-index = <0>;
 			qcom,dst-bam-physical-address = <0xf9a44000>;
 			qcom,dst-bam-pipe-index = <2>;
-			qcom,data-fifo-offset = <0>;
-			qcom,data-fifo-size = <0x4000>;
-			qcom,descriptor-fifo-offset = <0>;
-			qcom,descriptor-fifo-size = <0x1400>;
+			qcom,data-fifo-offset = <0xf4000>;
+			qcom,data-fifo-size = <0x1000>;
+			qcom,descriptor-fifo-offset = <0xf5000>;
+			qcom,descriptor-fifo-size = <0x400>;
 		};
 	};
 
diff --git a/arch/arm/mach-msm/acpuclock-8960ab.c b/arch/arm/mach-msm/acpuclock-8960ab.c
index 6366376..1097907 100644
--- a/arch/arm/mach-msm/acpuclock-8960ab.c
+++ b/arch/arm/mach-msm/acpuclock-8960ab.c
@@ -142,6 +142,7 @@
 	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
 	.bus_scale = &bus_scale_data,
 	.qfprom_phys_base = 0x00700000,
+	.stby_khz = 384000,
 };
 
 static int __init acpuclk_8960ab_probe(struct platform_device *pdev)
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index 5780ca1..d7568ab 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -62,6 +62,7 @@
 #define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME "mipi_video_toshiba_wsvga"
 #define MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME "mipi_video_chimei_wxga"
 #define HDMI_PANEL_NAME "hdmi_msm"
+#define MHL_PANEL_NAME "hdmi_msm,mhl_8334"
 #define TVOUT_PANEL_NAME "tvout_msm"
 
 #define LVDS_PIXEL_MAP_PATTERN_1	1
@@ -73,11 +74,18 @@
 static unsigned char hdmi_is_primary;
 #endif
 
+static unsigned char mhl_display_enabled;
+
 unsigned char apq8064_hdmi_as_primary_selected(void)
 {
 	return hdmi_is_primary;
 }
 
+unsigned char apq8064_mhl_display_enabled(void)
+{
+	return mhl_display_enabled;
+}
+
 static void set_mdp_clocks_for_wuxga(void);
 
 static int msm_fb_detect_panel(const char *name)
@@ -1067,7 +1075,15 @@
 			PANEL_NAME_MAX_LEN);
 		pr_debug("msm_fb_pdata.ext_panel_name %s\n",
 			msm_fb_pdata.ext_panel_name);
+
+		if (!strncmp((char *)msm_fb_pdata.ext_panel_name,
+			MHL_PANEL_NAME, strnlen(MHL_PANEL_NAME,
+				PANEL_NAME_MAX_LEN))) {
+			pr_debug("MHL is external display by boot parameter\n");
+			mhl_display_enabled = 1;
+		}
 	}
 
 	msm_fb_pdata.ext_resolution = resolution;
+	hdmi_msm_data.is_mhl_enabled = mhl_display_enabled;
 }
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index 2258b8d..50885ad 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -84,6 +84,7 @@
 #define APQ_8064_GSBI5_QUP_I2C_BUS_ID 5
 
 unsigned char apq8064_hdmi_as_primary_selected(void);
+unsigned char apq8064_mhl_display_enabled(void);
 void apq8064_init_fb(void);
 void apq8064_allocate_fb_region(void);
 void apq8064_mdp_writeback(struct memtype_reserve *reserve_table);
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index e9a034e..6add371 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -2761,21 +2761,17 @@
 		msm_kgsl_3d0.dev.platform_data;
 	uint32_t soc_platform_version = socinfo_get_version();
 
-	if (SOCINFO_VERSION_MAJOR(soc_platform_version) == 1) {
-		kgsl_3d0_pdata->pwrlevel[0].gpu_freq = 320000000;
-		kgsl_3d0_pdata->pwrlevel[1].gpu_freq = 266667000;
-	}
 	if (cpu_is_msm8960ab()) {
 		kgsl_3d0_pdata->chipid = ADRENO_CHIPID(3, 2, 1, 0);
-	} else {
-
+	} else if (SOCINFO_VERSION_MAJOR(soc_platform_version) == 1) {
+		kgsl_3d0_pdata->pwrlevel[0].gpu_freq = 320000000;
+		kgsl_3d0_pdata->pwrlevel[1].gpu_freq = 266667000;
+	} else if (SOCINFO_VERSION_MAJOR(soc_platform_version) >= 3) {
 		/* 8960v3 GPU registers returns 5 for patch release
 		 * but it should be 6, so dummy up the chipid here
 		 * based the platform type
 		 */
-
-		if (SOCINFO_VERSION_MAJOR(soc_platform_version) >= 3)
-			kgsl_3d0_pdata->chipid = ADRENO_CHIPID(2, 2, 0, 6);
+		kgsl_3d0_pdata->chipid = ADRENO_CHIPID(2, 2, 0, 6);
 	}
 }
 
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index b67d982..e00f150 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -63,6 +63,13 @@
 #define PMEM_KERNEL_EBI1_SIZE	0x3A000
 #define MSM_PMEM_AUDIO_SIZE	0x1F4000
 
+#define SNDDEV_CAP_NONE 0x0
+#define SNDDEV_CAP_RX 0x1 /* RX direction */
+#define SNDDEV_CAP_TX 0x2 /* TX direction */
+#define SNDDEV_CAP_VOICE 0x4 /* Support voice call */
+#define SNDDEV_CAP_FM 0x10 /* Support FM radio */
+#define SNDDEV_CAP_TTY 0x20 /* Support TTY */
+
 #if defined(CONFIG_GPIO_SX150X)
 enum {
 	SX150X_CORE,
@@ -494,7 +501,6 @@
 	SND(FM_ANALOG_STEREO_HEADSET_CODEC, 36),
 };
 #undef SND
-
 static struct msm_snd_endpoints msm_device_snd_endpoints = {
 	.endpoints = snd_endpoints_list,
 	.num = sizeof(snd_endpoints_list) / sizeof(struct snd_endpoint)
@@ -508,6 +514,55 @@
 	},
 };
 
+#define CAD(desc, num, cap) { .name = #desc, .id = num, .capability = cap, }
+static struct cad_endpoint cad_endpoints_list[] = {
+	CAD(NONE, 0, SNDDEV_CAP_NONE),
+	CAD(HANDSET_SPKR, 1, (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE)),
+	CAD(HANDSET_MIC, 2, (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE)),
+	CAD(HEADSET_MIC, 3, (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE)),
+	CAD(HEADSET_SPKR_MONO, 4, (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE)),
+	CAD(HEADSET_SPKR_STEREO, 5, (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE)),
+	CAD(SPEAKER_PHONE_MIC, 6, (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE)),
+	CAD(SPEAKER_PHONE_MONO, 7, (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE)),
+	CAD(SPEAKER_PHONE_STEREO, 8, (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE)),
+	CAD(BT_SCO_MIC, 9, (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE)),
+	CAD(BT_SCO_SPKR, 10, (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE)),
+	CAD(BT_A2DP_SPKR, 11, (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE)),
+	CAD(TTY_HEADSET_MIC, 12, (SNDDEV_CAP_TX | \
+			SNDDEV_CAP_VOICE | SNDDEV_CAP_TTY)),
+	CAD(TTY_HEADSET_SPKR, 13, (SNDDEV_CAP_RX | \
+			SNDDEV_CAP_VOICE | SNDDEV_CAP_TTY)),
+	CAD(HEADSET_STEREO_PLUS_SPKR_MONO_RX, 19, (SNDDEV_CAP_TX | \
+				SNDDEV_CAP_VOICE)),
+	CAD(LP_FM_HEADSET_SPKR_STEREO_RX, 25, (SNDDEV_CAP_TX | SNDDEV_CAP_FM)),
+	CAD(I2S_RX, 26, (SNDDEV_CAP_RX)),
+	CAD(SPEAKER_PHONE_MIC_ENDFIRE, 45, (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE)),
+	CAD(HANDSET_MIC_ENDFIRE, 46, (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE)),
+	CAD(I2S_TX, 48, (SNDDEV_CAP_TX)),
+	CAD(LP_FM_HEADSET_SPKR_STEREO_PLUS_HEADSET_SPKR_STEREO_RX, 57, \
+			(SNDDEV_CAP_FM | SNDDEV_CAP_RX)),
+	CAD(FM_DIGITAL_HEADSET_SPKR_STEREO, 65, \
+			(SNDDEV_CAP_FM | SNDDEV_CAP_RX)),
+	CAD(FM_DIGITAL_SPEAKER_PHONE_MONO, 67, \
+			(SNDDEV_CAP_FM | SNDDEV_CAP_RX)),
+	CAD(FM_DIGITAL_BT_A2DP_SPKR, 69, \
+			(SNDDEV_CAP_FM | SNDDEV_CAP_RX)),
+	CAD(MAX, 80, SNDDEV_CAP_NONE),
+};
+#undef CAD
+static struct msm_cad_endpoints msm_device_cad_endpoints = {
+	.endpoints = cad_endpoints_list,
+	.num = sizeof(cad_endpoints_list) / sizeof(struct cad_endpoint)
+};
+
+static struct platform_device msm_device_cad = {
+	.name = "msm_cad",
+	.id = -1,
+	.dev    = {
+		.platform_data = &msm_device_cad_endpoints
+	},
+};
+
 #define DEC0_FORMAT ((1<<MSM_ADSP_CODEC_MP3)| \
 	(1<<MSM_ADSP_CODEC_AAC)|(1<<MSM_ADSP_CODEC_WMA)| \
 	(1<<MSM_ADSP_CODEC_WMAPRO)|(1<<MSM_ADSP_CODEC_AMRWB)| \
@@ -814,6 +869,7 @@
 	&android_pmem_audio_device,
 	&msm_device_nand,
 	&msm_device_snd,
+	&msm_device_cad,
 	&msm_device_adspdec,
 	&asoc_msm_pcm,
 	&asoc_msm_dai0,
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 7556931..1da9ede 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -75,6 +75,13 @@
 #define I2C_PIN_CTL       0x15
 #define I2C_NORMAL        0x40
 
+#define SNDDEV_CAP_NONE 0x0
+#define SNDDEV_CAP_RX 0x1 /* RX direction */
+#define SNDDEV_CAP_TX 0x2 /* TX direction */
+#define SNDDEV_CAP_VOICE 0x4 /* Support voice call */
+#define SNDDEV_CAP_FM 0x10 /* Support FM radio */
+#define SNDDEV_CAP_TTY 0x20 /* Support TTY */
+
 static struct platform_device msm_wlan_ar6000_pm_device = {
 	.name           = "wlan_ar6000_pm_dev",
 	.id             = -1,
@@ -454,6 +461,56 @@
 	},
 };
 
+#define CAD(desc, num, cap) { .name = #desc, .id = num, .capability = cap, }
+static struct cad_endpoint cad_endpoints_list[] = {
+	CAD(NONE, 0, SNDDEV_CAP_NONE),
+	CAD(HANDSET_SPKR, 1, (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE)),
+	CAD(HANDSET_MIC, 2, (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE)),
+	CAD(HEADSET_MIC, 3, (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE)),
+	CAD(HEADSET_SPKR_MONO, 4, (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE)),
+	CAD(HEADSET_SPKR_STEREO, 5, (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE)),
+	CAD(SPEAKER_PHONE_MIC, 6, (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE)),
+	CAD(SPEAKER_PHONE_MONO, 7, (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE)),
+	CAD(SPEAKER_PHONE_STEREO, 8, (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE)),
+	CAD(BT_SCO_MIC, 9, (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE)),
+	CAD(BT_SCO_SPKR, 10, (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE)),
+	CAD(BT_A2DP_SPKR, 11, (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE)),
+	CAD(TTY_HEADSET_MIC, 12, (SNDDEV_CAP_TX | \
+			SNDDEV_CAP_VOICE | SNDDEV_CAP_TTY)),
+	CAD(TTY_HEADSET_SPKR, 13, (SNDDEV_CAP_RX | \
+			SNDDEV_CAP_VOICE | SNDDEV_CAP_TTY)),
+	CAD(HEADSET_STEREO_PLUS_SPKR_MONO_RX, 19, (SNDDEV_CAP_TX | \
+				SNDDEV_CAP_VOICE)),
+	CAD(LP_FM_HEADSET_SPKR_STEREO_RX, 25, (SNDDEV_CAP_TX | SNDDEV_CAP_FM)),
+	CAD(I2S_RX, 26, (SNDDEV_CAP_RX)),
+	CAD(SPEAKER_PHONE_MIC_ENDFIRE, 45, (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE)),
+	CAD(HANDSET_MIC_ENDFIRE, 46, (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE)),
+	CAD(I2S_TX, 48, (SNDDEV_CAP_TX)),
+	CAD(LP_FM_HEADSET_SPKR_STEREO_PLUS_HEADSET_SPKR_STEREO_RX, 57, \
+				(SNDDEV_CAP_FM | SNDDEV_CAP_RX)),
+	CAD(FM_DIGITAL_HEADSET_SPKR_STEREO, 65, \
+			(SNDDEV_CAP_FM | SNDDEV_CAP_RX)),
+	CAD(FM_DIGITAL_SPEAKER_PHONE_MONO, 67, \
+			(SNDDEV_CAP_FM | SNDDEV_CAP_RX)),
+	CAD(FM_DIGITAL_BT_A2DP_SPKR, 69, \
+			(SNDDEV_CAP_FM | SNDDEV_CAP_RX)),
+	CAD(MAX, 80, SNDDEV_CAP_NONE),
+};
+#undef CAD
+
+static struct msm_cad_endpoints msm_device_cad_endpoints = {
+	.endpoints = cad_endpoints_list,
+	.num = sizeof(cad_endpoints_list) / sizeof(struct cad_endpoint)
+};
+
+static struct platform_device msm_device_cad = {
+	.name = "msm_cad",
+	.id = -1,
+	.dev    = {
+		.platform_data = &msm_device_cad_endpoints
+	},
+};
+
 #define DEC0_FORMAT ((1<<MSM_ADSP_CODEC_MP3)| \
 	(1<<MSM_ADSP_CODEC_AAC)|(1<<MSM_ADSP_CODEC_WMA)| \
 	(1<<MSM_ADSP_CODEC_WMAPRO)|(1<<MSM_ADSP_CODEC_AMRWB)| \
@@ -702,6 +759,7 @@
 	&msm_batt_device,
 	&msm_device_adspdec,
 	&msm_device_snd,
+	&msm_device_cad,
 	&asoc_msm_pcm,
 	&asoc_msm_dai0,
 	&asoc_msm_dai1,
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 41bc229..dc05dcf 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -122,6 +122,10 @@
 #define USB_HSIC_CMD_RCGR              0x0440
 #define USB_HSIC_IO_CAL_CMD_RCGR       0x0458
 #define USB_HS_SYSTEM_CMD_RCGR         0x0490
+#define SYS_NOC_USB3_AXI_CBCR	       0x0108
+#define USB30_SLEEP_CBCR	       0x03CC
+#define USB2A_PHY_SLEEP_CBCR	       0x04AC
+#define USB2B_PHY_SLEEP_CBCR	       0x04B4
 #define SDCC1_APPS_CMD_RCGR            0x04D0
 #define SDCC2_APPS_CMD_RCGR            0x0510
 #define SDCC3_APPS_CMD_RCGR            0x0550
@@ -2198,6 +2202,51 @@
 	},
 };
 
+struct branch_clk gcc_sys_noc_usb3_axi_clk = {
+	.cbcr_reg = SYS_NOC_USB3_AXI_CBCR,
+	.parent = &usb30_master_clk_src.c,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_sys_noc_usb3_axi_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_sys_noc_usb3_axi_clk.c),
+	},
+};
+
+struct branch_clk gcc_usb30_sleep_clk = {
+	.cbcr_reg = USB30_SLEEP_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb30_sleep_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb30_sleep_clk.c),
+	},
+};
+
+struct branch_clk gcc_usb2a_phy_sleep_clk = {
+	.cbcr_reg = USB2A_PHY_SLEEP_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb2a_phy_sleep_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb2a_phy_sleep_clk.c),
+	},
+};
+
+struct branch_clk gcc_usb2b_phy_sleep_clk = {
+	.cbcr_reg = USB2B_PHY_SLEEP_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb2b_phy_sleep_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb2b_phy_sleep_clk.c),
+	},
+};
+
 static struct branch_clk gcc_usb_hs_ahb_clk = {
 	.cbcr_reg = USB_HS_AHB_CBCR,
 	.has_sibling = 1,
@@ -4552,6 +4601,10 @@
 	{&gcc_blsp1_qup1_i2c_apps_clk.c,	GCC_BASE, 0x008b},
 	{&gcc_blsp2_uart6_apps_clk.c,		GCC_BASE, 0x00c3},
 	{&gcc_sdcc2_ahb_clk.c,			GCC_BASE, 0x0071},
+	{&gcc_usb30_sleep_clk.c,		GCC_BASE, 0x0051},
+	{&gcc_usb2a_phy_sleep_clk.c,		GCC_BASE, 0x0063},
+	{&gcc_usb2b_phy_sleep_clk.c,		GCC_BASE, 0x0064},
+	{&gcc_sys_noc_usb3_axi_clk.c,		GCC_BASE, 0x0001},
 	{&gcc_ocmem_noc_cfg_ahb_clk.c,		GCC_BASE, 0x0029},
 	{&gcc_ce1_clk.c,			GCC_BASE, 0x0138},
 	{&gcc_lpass_q6_axi_clk.c,		GCC_BASE, 0x0160},
@@ -4648,7 +4701,7 @@
 	{&q6ss_ahb_lfabif_clk.c,		LPASS_BASE, 0x001e},
 	{&q6ss_ahbm_clk.c,			LPASS_BASE, 0x001d},
 	{&audio_core_ixfabric_clk.c,		LPASS_BASE, 0x0059},
-	{&mss_bus_q6_clk.c,			MSS_BASE, 0x003c},
+	{&mss_bus_q6_clk.c,			MSS_BASE, 0x003b},
 	{&mss_xo_q6_clk.c,			MSS_BASE, 0x0007},
 
 	{&l2_m_clk,				APCS_BASE, 0x0081},
@@ -4684,18 +4737,15 @@
 	clk->sample_ticks = 0x10000;
 	clk->multiplier = 1;
 
-	writel_relaxed(0, MSS_REG_BASE(MSS_DEBUG_CLK_CTL_REG));
-	writel_relaxed(0, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL_REG));
-	writel_relaxed(0, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL_REG));
-	writel_relaxed(0, GCC_REG_BASE(GCC_DEBUG_CLK_CTL_REG));
-
 	switch (measure_mux[i].base) {
 
 	case GCC_BASE:
+		writel_relaxed(0, GCC_REG_BASE(GCC_DEBUG_CLK_CTL_REG));
 		clk_sel = measure_mux[i].debug_mux;
 		break;
 
 	case MMSS_BASE:
+		writel_relaxed(0, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL_REG));
 		clk_sel = 0x02C;
 		regval = BVAL(11, 0, measure_mux[i].debug_mux);
 		writel_relaxed(regval, MMSS_REG_BASE(MMSS_DEBUG_CLK_CTL_REG));
@@ -4706,6 +4756,7 @@
 		break;
 
 	case LPASS_BASE:
+		writel_relaxed(0, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL_REG));
 		clk_sel = 0x161;
 		regval = BVAL(11, 0, measure_mux[i].debug_mux);
 		writel_relaxed(regval, LPASS_REG_BASE(LPASS_DEBUG_CLK_CTL_REG));
@@ -4716,6 +4767,7 @@
 		break;
 
 	case MSS_BASE:
+		writel_relaxed(0, MSS_REG_BASE(MSS_DEBUG_CLK_CTL_REG));
 		clk_sel = 0x32;
 		regval = BVAL(5, 0, measure_mux[i].debug_mux);
 		writel_relaxed(regval, MSS_REG_BASE(MSS_DEBUG_CLK_CTL_REG));
@@ -4985,8 +5037,14 @@
 	CLK_LOOKUP("iface_clk", gcc_tsif_ahb_clk.c, ""),
 	CLK_LOOKUP("ref_clk", gcc_tsif_ref_clk.c, ""),
 
+	CLK_LOOKUP("mem_clk", gcc_usb30_master_clk.c,           "usb_bam"),
+	CLK_LOOKUP("mem_iface_clk", gcc_sys_noc_usb3_axi_clk.c, "usb_bam"),
 	CLK_LOOKUP("core_clk", gcc_usb30_master_clk.c,    "msm_dwc3"),
 	CLK_LOOKUP("utmi_clk", gcc_usb30_mock_utmi_clk.c, "msm_dwc3"),
+	CLK_LOOKUP("iface_clk", gcc_sys_noc_usb3_axi_clk.c, "msm_dwc3"),
+	CLK_LOOKUP("sleep_clk", gcc_usb30_sleep_clk.c, "msm_dwc3"),
+	CLK_LOOKUP("sleep_a_clk", gcc_usb2a_phy_sleep_clk.c, "msm_dwc3"),
+	CLK_LOOKUP("sleep_b_clk", gcc_usb2b_phy_sleep_clk.c, "msm_dwc3"),
 	CLK_LOOKUP("iface_clk", gcc_usb_hs_ahb_clk.c,     "msm_otg"),
 	CLK_LOOKUP("core_clk", gcc_usb_hs_system_clk.c,   "msm_otg"),
 	CLK_LOOKUP("iface_clk", gcc_usb_hsic_ahb_clk.c,	  "msm_hsic_host"),
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index d5ee35b..42b36f6 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -110,20 +110,26 @@
 void set_rate_hid(struct rcg_clk *rcg, struct clk_freq_tbl *nf)
 {
 	u32 cfg_regval;
+	unsigned long flags;
 
+	spin_lock_irqsave(&local_clock_reg_lock, flags);
 	cfg_regval = readl_relaxed(CFG_RCGR_REG(rcg));
 	cfg_regval &= ~(CFG_RCGR_DIV_MASK | CFG_RCGR_SRC_SEL_MASK);
 	cfg_regval |= nf->div_src_val;
 	writel_relaxed(cfg_regval, CFG_RCGR_REG(rcg));
 
 	rcg_update_config(rcg);
+	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 }
 
 /* RCG set rate function for clocks with MND & Half Integer Dividers. */
 void set_rate_mnd(struct rcg_clk *rcg, struct clk_freq_tbl *nf)
 {
 	u32 cfg_regval;
+	unsigned long flags;
 
+	spin_lock_irqsave(&local_clock_reg_lock, flags);
+	cfg_regval = readl_relaxed(CFG_RCGR_REG(rcg));
 	writel_relaxed(nf->m_val, M_REG(rcg));
 	writel_relaxed(nf->n_val, N_REG(rcg));
 	writel_relaxed(nf->d_val, D_REG(rcg));
@@ -139,6 +145,7 @@
 	writel_relaxed(cfg_regval, CFG_RCGR_REG(rcg));
 
 	rcg_update_config(rcg);
+	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 }
 
 static int rcg_clk_enable(struct clk *c)
@@ -157,7 +164,6 @@
 	struct clk_freq_tbl *cf, *nf;
 	struct rcg_clk *rcg = to_rcg_clk(c);
 	int rc = 0;
-	unsigned long flags;
 
 	for (nf = rcg->freq_tbl; nf->freq_hz != FREQ_END
 			&& nf->freq_hz != rate; nf++)
@@ -178,13 +184,9 @@
 
 	BUG_ON(!rcg->set_rate);
 
-	spin_lock_irqsave(&local_clock_reg_lock, flags);
-
 	/* Perform clock-specific frequency switch operations. */
 	rcg->set_rate(rcg, nf);
 
-	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
-
 	/* Release source requirements of the old freq. */
 	if (rcg->c.count)
 		clk_disable(cf->src_clk);
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index c6a0441..3b262bc 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -2848,26 +2848,6 @@
 struct msm_iommu_domain_name apq8064_iommu_ctx_names[] = {
 	/* Camera */
 	{
-		.name = "vpe_src",
-		.domain = CAMERA_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name = "vpe_dst",
-		.domain = CAMERA_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name = "vfe_imgwr",
-		.domain = CAMERA_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name = "vfe_misc",
-		.domain = CAMERA_DOMAIN,
-	},
-	/* Camera */
-	{
 		.name = "ijpeg_src",
 		.domain = CAMERA_DOMAIN,
 	},
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index eac2140..a257a9c 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -853,26 +853,6 @@
 struct msm_iommu_domain_name msm8930_iommu_ctx_names[] = {
 	/* Camera */
 	{
-		.name = "vpe_src",
-		.domain = CAMERA_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name = "vpe_dst",
-		.domain = CAMERA_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name = "vfe_imgwr",
-		.domain = CAMERA_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name = "vfe_misc",
-		.domain = CAMERA_DOMAIN,
-	},
-	/* Camera */
-	{
 		.name = "ijpeg_src",
 		.domain = CAMERA_DOMAIN,
 	},
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index d121c3e..377ecae 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -4061,26 +4061,6 @@
 struct msm_iommu_domain_name msm8960_iommu_ctx_names[] = {
 	/* Camera */
 	{
-		.name = "vpe_src",
-		.domain = CAMERA_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name = "vpe_dst",
-		.domain = CAMERA_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name = "vfe_imgwr",
-		.domain = CAMERA_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name = "vfe_misc",
-		.domain = CAMERA_DOMAIN,
-	},
-	/* Camera */
-	{
 		.name = "ijpeg_src",
 		.domain = CAMERA_DOMAIN,
 	},
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 5295cbc..e7d652b 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -1263,8 +1263,8 @@
 	},
 	{
 		.name	= "dma_chnl",
-		.start	= DMOV_SDC3_CHAN,
-		.end	= DMOV_SDC3_CHAN,
+		.start	= DMOV_NAND_CHAN,
+		.end	= DMOV_NAND_CHAN,
 		.flags	= IORESOURCE_DMA,
 	},
 	{
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index a6473c6..45486f4 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -1329,7 +1329,7 @@
 static struct kgsl_device_platform_data kgsl_2d0_pdata = {
 	.pwrlevel = {
 		{
-			.gpu_freq = 192000000,
+			.gpu_freq = 0,
 			.bus_freq = 192000000,
 		},
 	},
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index 9f31a18..57d7f08 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -3003,26 +3003,6 @@
 struct msm_iommu_domain_name msm8660_iommu_ctx_names[] = {
 	/* Camera */
 	{
-		.name = "vpe_src",
-		.domain = CAMERA_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name = "vpe_dst",
-		.domain = CAMERA_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name = "vfe_imgwr",
-		.domain = CAMERA_DOMAIN,
-	},
-	/* Camera */
-	{
-		.name = "vfe_misc",
-		.domain = CAMERA_DOMAIN,
-	},
-	/* Camera */
-	{
 		.name = "ijpeg_src",
 		.domain = CAMERA_DOMAIN,
 	},
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 1060a9d..d8f8480 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -296,6 +296,17 @@
 	unsigned num;
 };
 
+struct cad_endpoint {
+	int id;
+	const char *name;
+	uint32_t capability;
+};
+
+struct msm_cad_endpoints {
+	struct cad_endpoint *endpoints;
+	unsigned num;
+};
+
 #define MSM_MAX_DEC_CNT 14
 /* 7k target ADSP information */
 /* Bit 23:0, for codec identification like mp3, wav etc *
diff --git a/arch/arm/mach-msm/include/mach/socinfo.h b/arch/arm/mach-msm/include/mach/socinfo.h
index f7ba507..d80cc02 100644
--- a/arch/arm/mach-msm/include/mach/socinfo.h
+++ b/arch/arm/mach-msm/include/mach/socinfo.h
@@ -97,6 +97,7 @@
 const int cpu_is_krait(void);
 const int cpu_is_krait_v1(void);
 const int cpu_is_krait_v2(void);
+const int cpu_is_krait_v3(void);
 
 static inline int cpu_is_msm7x01(void)
 {
diff --git a/arch/arm/mach-msm/include/mach/sps.h b/arch/arm/mach-msm/include/mach/sps.h
index edc4b39..000ffe4 100644
--- a/arch/arm/mach-msm/include/mach/sps.h
+++ b/arch/arm/mach-msm/include/mach/sps.h
@@ -75,6 +75,8 @@
 #define SPS_BAM_OPT_BAMDMA          (1UL << 2)
 /* BAM IRQ is registered for apps wakeup */
 #define SPS_BAM_OPT_IRQ_WAKEUP      (1UL << 3)
+/* Ignore external block pipe reset */
+#define SPS_BAM_NO_EXT_P_RST        (1UL << 4)
 
 /* BAM device management flags */
 
diff --git a/arch/arm/mach-msm/mdm2.c b/arch/arm/mach-msm/mdm2.c
index 2073856..43c85bb 100644
--- a/arch/arm/mach-msm/mdm2.c
+++ b/arch/arm/mach-msm/mdm2.c
@@ -108,6 +108,8 @@
 	int soft_reset_direction =
 		mdm_drv->pdata->soft_reset_inverted ? 1 : 0;
 
+	mdm_peripheral_disconnect(mdm_drv);
+
 	/* Wait for the modem to complete its power down actions. */
 	for (i = 20; i > 0; i--) {
 		if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
@@ -127,7 +129,6 @@
 		*/
 		msleep(4000);
 	}
-	mdm_peripheral_disconnect(mdm_drv);
 }
 
 static void mdm_do_first_power_on(struct mdm_modem_drv *mdm_drv)
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
index 9ba9f7b1..70bb406 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
@@ -21,7 +21,7 @@
 #include <mach/rpm.h>
 #include "msm_bus_core.h"
 
-#define NMASTERS 45
+#define NMASTERS 55
 #define NSLAVES 75
 #define NFAB_8960 5
 
diff --git a/arch/arm/mach-msm/msm_watchdog_v2.c b/arch/arm/mach-msm/msm_watchdog_v2.c
index ea408f7..af903f8 100644
--- a/arch/arm/mach-msm/msm_watchdog_v2.c
+++ b/arch/arm/mach-msm/msm_watchdog_v2.c
@@ -19,6 +19,8 @@
 #include <linux/jiffies.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/percpu.h>
 #include <linux/of.h>
 #include <linux/cpu.h>
 #include <linux/platform_device.h>
@@ -54,6 +56,8 @@
 	cpumask_t alive_mask;
 	struct work_struct init_dogwork_struct;
 	struct delayed_work dogwork_struct;
+	bool irq_ppi;
+	struct msm_watchdog_data __percpu **wdog_cpu_dd;
 	struct notifier_block panic_blk;
 };
 
@@ -199,7 +203,7 @@
 		ping_other_cpus(wdog_dd);
 	pet_watchdog(wdog_dd);
 	if (enable)
-		schedule_delayed_work(&wdog_dd->dogwork_struct,
+		schedule_delayed_work_on(0, &wdog_dd->dogwork_struct,
 							delay_time);
 }
 
@@ -218,6 +222,8 @@
 		/* In case we got suspended mid-exit */
 		__raw_writel(0, wdog_dd->base + WDT0_EN);
 	}
+	if (wdog_dd->irq_ppi)
+		free_percpu(wdog_dd->wdog_cpu_dd);
 	printk(KERN_INFO "MSM Watchdog Exit - Deactivated\n");
 	kzfree(wdog_dd);
 	return 0;
@@ -242,6 +248,13 @@
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t wdog_ppi_bark(int irq, void *dev_id)
+{
+	struct msm_watchdog_data *wdog_dd =
+			*(struct msm_watchdog_data **)(dev_id);
+	return wdog_bark_handler(irq, wdog_dd);
+}
+
 static void configure_bark_dump(struct msm_watchdog_data *wdog_dd)
 {
 	int ret;
@@ -287,6 +300,32 @@
 							init_dogwork_struct);
 	unsigned long delay_time;
 	u64 timeout;
+	int ret;
+
+	if (wdog_dd->irq_ppi) {
+		wdog_dd->wdog_cpu_dd = alloc_percpu(struct msm_watchdog_data *);
+		if (!wdog_dd->wdog_cpu_dd) {
+			dev_err(wdog_dd->dev, "fail to allocate cpu data\n");
+			return;
+		}
+		*__this_cpu_ptr(wdog_dd->wdog_cpu_dd) = wdog_dd;
+		ret = request_percpu_irq(wdog_dd->bark_irq, wdog_ppi_bark,
+					"apps_wdog_bark",
+					wdog_dd->wdog_cpu_dd);
+		if (ret) {
+			dev_err(wdog_dd->dev, "failed to request bark irq\n");
+			free_percpu(wdog_dd->wdog_cpu_dd);
+			return;
+		}
+	} else {
+		ret = devm_request_irq(wdog_dd->dev, wdog_dd->bark_irq,
+				wdog_bark_handler, IRQF_TRIGGER_RISING,
+						"apps_wdog_bark", wdog_dd);
+		if (ret) {
+			dev_err(wdog_dd->dev, "failed to request bark irq\n");
+			return;
+		}
+	}
 	delay_time = msecs_to_jiffies(wdog_dd->pet_time);
 	wdog_dd->min_slack_ticks = UINT_MAX;
 	wdog_dd->min_slack_ns = ULLONG_MAX;
@@ -298,12 +337,14 @@
 	wdog_dd->panic_blk.notifier_call = panic_wdog_handler;
 	atomic_notifier_chain_register(&panic_notifier_list,
 				       &wdog_dd->panic_blk);
-	schedule_delayed_work(&wdog_dd->dogwork_struct, delay_time);
+	schedule_delayed_work_on(0, &wdog_dd->dogwork_struct, delay_time);
 
 	__raw_writel(1, wdog_dd->base + WDT0_EN);
 	__raw_writel(1, wdog_dd->base + WDT0_RST);
 	wdog_dd->last_pet = sched_clock();
 	printk(KERN_INFO "MSM Watchdog Initialized\n");
+	if (wdog_dd->irq_ppi)
+		enable_percpu_irq(wdog_dd->bark_irq, 0);
 	return;
 }
 
@@ -377,6 +418,7 @@
 								__func__);
 		return -ENXIO;
 	}
+	pdata->irq_ppi = irq_is_per_cpu(pdata->bark_irq);
 	dump_pdata(pdata);
 	return 0;
 }
@@ -396,13 +438,6 @@
 		goto err;
 	wdog_dd->dev = &pdev->dev;
 	platform_set_drvdata(pdev, wdog_dd);
-	ret = devm_request_irq(&pdev->dev, wdog_dd->bark_irq, wdog_bark_handler,
-				IRQF_TRIGGER_RISING, "apps_wdog_bark", wdog_dd);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to request bark irq\n");
-		ret = -ENXIO;
-		goto err;
-	}
 	cpumask_clear(&wdog_dd->alive_mask);
 	INIT_WORK(&wdog_dd->init_dogwork_struct, init_watchdog_work);
 	INIT_DELAYED_WORK(&wdog_dd->dogwork_struct, pet_watchdog_work);
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index 39fbba8..8e0113c 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -830,3 +830,17 @@
 		return 0;
 	};
 }
+
+const int cpu_is_krait_v3(void)
+{
+	switch (read_cpuid_id()) {
+	case 0x512F04D0:
+	case 0x511F06F0:
+	case 0x511F06F1:
+	case 0x510F05D0:
+		return 1;
+
+	default:
+		return 0;
+	};
+}
diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c
index cfcacff..50b3362 100644
--- a/drivers/bluetooth/hci_ath.c
+++ b/drivers/bluetooth/hci_ath.c
@@ -93,7 +93,7 @@
 
 static void hostwake_interrupt(unsigned long data)
 {
-	printk(KERN_INFO " wakeup host\n");
+	BT_INFO(" wakeup host\n");
 }
 
 static void modify_timer_task(void)
@@ -109,7 +109,7 @@
 {
 	int status = 0;
 	if (test_bit(BT_TXEXPIRED, &flags)) {
-		printk(KERN_INFO "wakeup device\n");
+		BT_INFO("wakeup device\n");
 		gpio_set_value(bsi->ext_wake, 0);
 		msleep(20);
 		gpio_set_value(bsi->ext_wake, 1);
@@ -138,12 +138,114 @@
 	hci_uart_tx_wakeup(hu);
 }
 
+static irqreturn_t bluesleep_hostwake_isr(int irq, void *dev_id)
+{
+	/* schedule a tasklet to handle the change in the host wake line */
+	tasklet_schedule(&hostwake_task);
+	return IRQ_HANDLED;
+}
+
+static int ath_bluesleep_gpio_config(int on)
+{
+	int ret = 0;
+
+	BT_INFO("%s config: %d", __func__, on);
+	if (!on) {
+		if (disable_irq_wake(bsi->host_wake_irq))
+			BT_ERR("Couldn't disable hostwake IRQ wakeup mode\n");
+		goto free_host_wake_irq;
+	}
+
+	ret = gpio_request(bsi->host_wake, "bt_host_wake");
+	if (ret < 0) {
+		BT_ERR("failed to request gpio pin %d, error %d\n",
+			bsi->host_wake, ret);
+		goto gpio_config_failed;
+	}
+
+	/* configure host_wake as input */
+	ret = gpio_direction_input(bsi->host_wake);
+	if (ret < 0) {
+		BT_ERR("failed to config GPIO %d as input pin, err %d\n",
+			bsi->host_wake, ret);
+		goto gpio_host_wake;
+	}
+
+	ret = gpio_request(bsi->ext_wake, "bt_ext_wake");
+	if (ret < 0) {
+		BT_ERR("failed to request gpio pin %d, error %d\n",
+			bsi->ext_wake, ret);
+		goto gpio_host_wake;
+	}
+
+	ret = gpio_direction_output(bsi->ext_wake, 1);
+	if (ret < 0) {
+		BT_ERR("failed to config GPIO %d as output pin, err %d\n",
+			bsi->ext_wake, ret);
+		goto gpio_ext_wake;
+	}
+
+	gpio_set_value(bsi->ext_wake, 1);
+
+	/* Initialize spinlock. */
+	spin_lock_init(&rw_lock);
+
+	/* Initialize timer */
+	init_timer(&tx_timer);
+	tx_timer.function = bluesleep_tx_timer_expire;
+	tx_timer.data = 0;
+
+	/* initialize host wake tasklet */
+	tasklet_init(&hostwake_task, hostwake_interrupt, 0);
+
+	if (bsi->irq_polarity == POLARITY_LOW) {
+		ret = request_irq(bsi->host_wake_irq, bluesleep_hostwake_isr,
+				IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+				"bluetooth hostwake", NULL);
+	} else  {
+		ret = request_irq(bsi->host_wake_irq, bluesleep_hostwake_isr,
+				IRQF_DISABLED | IRQF_TRIGGER_RISING,
+				"bluetooth hostwake", NULL);
+	}
+	if (ret  < 0) {
+		BT_ERR("Couldn't acquire BT_HOST_WAKE IRQ");
+		goto delete_timer;
+	}
+
+	ret = enable_irq_wake(bsi->host_wake_irq);
+	if (ret < 0) {
+		BT_ERR("Couldn't enable BT_HOST_WAKE as wakeup interrupt");
+		goto free_host_wake_irq;
+	}
+
+	return 0;
+
+free_host_wake_irq:
+	free_irq(bsi->host_wake_irq, NULL);
+delete_timer:
+	del_timer(&tx_timer);
+gpio_ext_wake:
+	gpio_free(bsi->ext_wake);
+gpio_host_wake:
+	gpio_free(bsi->host_wake);
+gpio_config_failed:
+	return ret;
+}
+
 /* Initialize protocol */
 static int ath_open(struct hci_uart *hu)
 {
 	struct ath_struct *ath;
 
-	BT_DBG("hu %p", hu);
+	BT_DBG("hu %p, bsi %p", hu, bsi);
+
+	if (!bsi)
+		return -EIO;
+
+	if (ath_bluesleep_gpio_config(1) < 0) {
+		BT_ERR("HCIATH3K GPIO Config failed");
+		return -EIO;
+	}
 
 	ath = kzalloc(sizeof(*ath), GFP_ATOMIC);
 	if (!ath)
@@ -190,6 +292,9 @@
 	hu->priv = NULL;
 	kfree(ath);
 
+	if (bsi)
+		ath_bluesleep_gpio_config(0);
+
 	return 0;
 }
 
@@ -200,6 +305,8 @@
 {
 	struct ath_struct *ath = hu->priv;
 
+	BT_DBG("");
+
 	if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) {
 		kfree_skb(skb);
 		return 0;
@@ -243,6 +350,8 @@
 	struct ath_struct *ath = hu->priv;
 	unsigned int type;
 
+	BT_DBG("");
+
 	if (hci_recv_stream_fragment(hu->hdev, data, count) < 0)
 		BT_ERR("Frame Reassembly Failed");
 
@@ -260,7 +369,7 @@
 
 		if (type == HCI_EVENT_PKT) {
 			clear_bit(BT_SLEEPCMD, &flags);
-			printk(KERN_INFO "cur_sleep:%d\n", ath->cur_sleep);
+			BT_INFO("cur_sleep:%d\n", ath->cur_sleep);
 			if (ath->cur_sleep == 1)
 				set_bit(BT_SLEEPENABLE, &flags);
 			else
@@ -276,19 +385,11 @@
 {
 	if (!test_bit(BT_SLEEPENABLE, &flags))
 		return;
-	BT_DBG("Tx timer expired");
-	printk(KERN_INFO "Tx timer expired\n");
+	BT_INFO("Tx timer expired\n");
 
 	set_bit(BT_TXEXPIRED, &flags);
 }
 
-static irqreturn_t bluesleep_hostwake_isr(int irq, void *dev_id)
-{
-	/* schedule a tasklet to handle the change in the host wake line */
-	tasklet_schedule(&hostwake_task);
-	return IRQ_HANDLED;
-}
-
 static struct hci_uart_proto athp = {
 	.id = HCI_UART_ATH3K,
 	.open = ath_open,
@@ -304,6 +405,8 @@
 	int ret;
 	struct resource *res;
 
+	BT_DBG("");
+
 	bsi = kzalloc(sizeof(struct bluesleep_info), GFP_KERNEL);
 	if (!bsi) {
 		ret = -ENOMEM;
@@ -319,107 +422,35 @@
 	}
 	bsi->host_wake = res->start;
 
-	ret = gpio_request(bsi->host_wake, "bt_host_wake");
-	if (ret)
-		goto free_bsi;
-
-	/* configure host_wake as input */
-	ret = gpio_direction_input(bsi->host_wake);
-	if (ret < 0) {
-		pr_err("%s: gpio_direction_input failed for GPIO %d, error %d\n",
-			__func__, bsi->host_wake, ret);
-		gpio_free(bsi->host_wake);
-		goto free_bsi;
-	}
-
 	res = platform_get_resource_byname(pdev, IORESOURCE_IO,
 						"gpio_ext_wake");
 	if (!res) {
 		BT_ERR("couldn't find ext_wake gpio\n");
 		ret = -ENODEV;
-		goto free_bt_host_wake;
+		goto free_bsi;
 	}
 	bsi->ext_wake = res->start;
 
-	ret = gpio_request(bsi->ext_wake, "bt_ext_wake");
-	if (ret)
-		goto free_bt_host_wake;
-
-	/* configure ext_wake as output mode*/
-	ret = gpio_direction_output(bsi->ext_wake, 1);
-	if (ret < 0) {
-		pr_err("%s: gpio_direction_output failed for GPIO %d, error %d\n",
-			__func__, bsi->ext_wake, ret);
-		gpio_free(bsi->ext_wake);
-		goto free_bt_host_wake;
-	}
-	gpio_set_value(bsi->ext_wake, 1);
-
 	bsi->host_wake_irq = platform_get_irq_byname(pdev, "host_wake");
 	if (bsi->host_wake_irq < 0) {
 		BT_ERR("couldn't find host_wake irq\n");
 		ret = -ENODEV;
-		goto free_bt_ext_wake;
+		goto free_bsi;
 	}
 
 	bsi->irq_polarity = POLARITY_LOW;	/* low edge (falling edge) */
 
-	/* Initialize spinlock. */
-	spin_lock_init(&rw_lock);
-
-	/* Initialize timer */
-	init_timer(&tx_timer);
-	tx_timer.function = bluesleep_tx_timer_expire;
-	tx_timer.data = 0;
-
-	/* initialize host wake tasklet */
-	tasklet_init(&hostwake_task, hostwake_interrupt, 0);
-
-	if (bsi->irq_polarity == POLARITY_LOW) {
-		ret = request_irq(bsi->host_wake_irq, bluesleep_hostwake_isr,
-				IRQF_DISABLED | IRQF_TRIGGER_FALLING,
-				"bluetooth hostwake", NULL);
-	} else  {
-		ret = request_irq(bsi->host_wake_irq, bluesleep_hostwake_isr,
-				IRQF_DISABLED | IRQF_TRIGGER_RISING,
-				"bluetooth hostwake", NULL);
-	}
-	if (ret  < 0) {
-		BT_ERR("Couldn't acquire BT_HOST_WAKE IRQ");
-		goto free_bt_timer;
-	}
-
-	ret = enable_irq_wake(bsi->host_wake_irq);
-	if (ret < 0) {
-		BT_ERR("Couldn't enable BT_HOST_WAKE as wakeup interrupt");
-		free_irq(bsi->host_wake_irq, NULL);
-		goto free_bt_timer;
-	}
-
 	return 0;
 
-free_bt_timer:
-	del_timer(&tx_timer);
-free_bt_ext_wake:
-	gpio_free(bsi->ext_wake);
-free_bt_host_wake:
-	gpio_free(bsi->host_wake);
 free_bsi:
 	kfree(bsi);
+	bsi = NULL;
 failed:
 	return ret;
 }
 
 static int bluesleep_remove(struct platform_device *pdev)
 {
-	/* assert bt wake */
-	gpio_set_value(bsi->ext_wake, 0);
-	if (disable_irq_wake(bsi->host_wake_irq))
-		BT_ERR("Couldn't disable hostwake IRQ wakeup mode\n");
-	free_irq(bsi->host_wake_irq, NULL);
-	del_timer_sync(&tx_timer);
-	gpio_free(bsi->host_wake);
-	gpio_free(bsi->ext_wake);
 	kfree(bsi);
 	return 0;
 }
diff --git a/drivers/bluetooth/hci_ibs.c b/drivers/bluetooth/hci_ibs.c
index fb084f5..6253605 100644
--- a/drivers/bluetooth/hci_ibs.c
+++ b/drivers/bluetooth/hci_ibs.c
@@ -112,6 +112,13 @@
 	unsigned long rx_vote;		/* clock must be on for RX */
 	struct	timer_list tx_idle_timer;
 	struct	timer_list wake_retrans_timer;
+	struct	workqueue_struct *workqueue;
+	struct	work_struct ws_awake_rx;
+	struct	work_struct ws_awake_device;
+	struct	work_struct ws_rx_vote_off;
+	struct	work_struct ws_tx_vote_off;
+	void *ibs_hu; /* keeps the hci_uart pointer for reference */
+
 	/* debug */
 	unsigned long ibs_sent_wacks;
 	unsigned long ibs_sent_slps;
@@ -242,12 +249,90 @@
 	return err;
 }
 
+static void ibs_wq_awake_device(struct work_struct *work)
+{
+	struct ibs_struct *ibs = container_of(work, struct ibs_struct,
+					ws_awake_device);
+	struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu;
+
+	BT_DBG(" %p ", hu);
+
+	/* Vote for serial clock */
+	ibs_msm_serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_ON, hu);
+
+	spin_lock(&ibs->hci_ibs_lock);
+
+	/* send wake indication to device */
+	if (send_hci_ibs_cmd(HCI_IBS_WAKE_IND, hu) < 0)
+		BT_ERR("cannot send WAKE to device");
+
+	ibs->ibs_sent_wakes++; /* debug */
+
+	/* start retransmit timer */
+	mod_timer(&ibs->wake_retrans_timer, jiffies + wake_retrans);
+
+	spin_unlock(&ibs->hci_ibs_lock);
+}
+
+static void ibs_wq_awake_rx(struct work_struct *work)
+{
+	struct ibs_struct *ibs = container_of(work, struct ibs_struct,
+					ws_awake_rx);
+	struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu;
+
+	BT_DBG(" %p ", hu);
+
+	ibs_msm_serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_ON, hu);
+
+	spin_lock(&ibs->hci_ibs_lock);
+	ibs->rx_ibs_state = HCI_IBS_RX_AWAKE;
+	/* Always acknowledge device wake up,
+	 * sending IBS message doesn't count as TX ON
+	 */
+	if (send_hci_ibs_cmd(HCI_IBS_WAKE_ACK, hu) < 0)
+		BT_ERR("cannot acknowledge device wake up");
+
+	ibs->ibs_sent_wacks++; /* debug */
+
+	spin_unlock(&ibs->hci_ibs_lock);
+	/* actually send the packets */
+	hci_uart_tx_wakeup(hu);
+
+}
+
+static void ibs_wq_serial_rx_clock_vote_off(struct work_struct *work)
+{
+	struct ibs_struct *ibs = container_of(work, struct ibs_struct,
+					ws_rx_vote_off);
+	struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu;
+
+	BT_DBG(" %p ", hu);
+
+	ibs_msm_serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_OFF, hu);
+
+}
+
+static void ibs_wq_serial_tx_clock_vote_off(struct work_struct *work)
+{
+	struct ibs_struct *ibs = container_of(work, struct ibs_struct,
+					ws_tx_vote_off);
+	struct hci_uart *hu = (struct hci_uart *)ibs->ibs_hu;
+
+	BT_DBG(" %p ", hu);
+
+	hci_uart_tx_wakeup(hu);  /* run HCI tx handling unlocked */
+
+	/* now that message queued to tty driver, vote for tty clocks off */
+	/* It is up to the tty driver to pend the clocks off until tx done. */
+	ibs_msm_serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_OFF, hu);
+
+}
+
 static void hci_ibs_tx_idle_timeout(unsigned long arg)
 {
 	struct hci_uart *hu = (struct hci_uart *) arg;
 	struct ibs_struct *ibs = hu->priv;
 	unsigned long flags;
-	unsigned long vote_tx_sleep = 0;
 
 	BT_DBG("hu %p idle timeout in %lu state", hu, ibs->tx_ibs_state);
 
@@ -267,22 +352,11 @@
 		}
 		ibs->tx_ibs_state = HCI_IBS_TX_ASLEEP;
 		ibs->ibs_sent_slps++; /* debug */
-		vote_tx_sleep = 1;
 		break;
 	}
 
-	spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);
+	queue_work(ibs->workqueue, &ibs->ws_tx_vote_off);
 
-	hci_uart_tx_wakeup(hu);  /* run HCI tx handling unlocked */
-
-	if (!vote_tx_sleep)
-		return;
-	/* now that message queued to tty driver, vote for tty clocks off */
-	/* It is up to the tty driver to pend the clocks off until tx done. */
-
-	spin_lock_irqsave_nested(&ibs->hci_ibs_lock,
-					flags, SINGLE_DEPTH_NESTING);
-	ibs_msm_serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_OFF, hu);
 out:
 	spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);
 }
@@ -336,6 +410,19 @@
 	skb_queue_head_init(&ibs->txq);
 	skb_queue_head_init(&ibs->tx_wait_q);
 	spin_lock_init(&ibs->hci_ibs_lock);
+	ibs->workqueue = create_singlethread_workqueue("ibs_wq");
+	if (!ibs->workqueue) {
+		BT_ERR("IBS Workqueue not initialized properly");
+		kfree(ibs);
+		return -ENOMEM;
+	}
+
+	INIT_WORK(&ibs->ws_awake_rx, ibs_wq_awake_rx);
+	INIT_WORK(&ibs->ws_awake_device, ibs_wq_awake_device);
+	INIT_WORK(&ibs->ws_rx_vote_off, ibs_wq_serial_rx_clock_vote_off);
+	INIT_WORK(&ibs->ws_tx_vote_off, ibs_wq_serial_tx_clock_vote_off);
+
+	ibs->ibs_hu = (void *)hu;
 
 	/* Assume we start with both sides asleep -- extra wakes OK */
 	ibs->tx_ibs_state = HCI_IBS_TX_ASLEEP;
@@ -432,6 +519,8 @@
 	skb_queue_purge(&ibs->txq);
 	del_timer(&ibs->tx_idle_timer);
 	del_timer(&ibs->wake_retrans_timer);
+	destroy_workqueue(ibs->workqueue);
+	ibs->ibs_hu = NULL;
 
 	kfree_skb(ibs->rx_skb);
 
@@ -463,9 +552,10 @@
 		/* Make sure clock is on - we may have turned clock off since
 		 * receiving the wake up indicator
 		 */
-		ibs_msm_serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_ON, hu);
-		ibs->rx_ibs_state = HCI_IBS_RX_AWAKE;
-		/* deliberate fall-through */
+		/* awake rx clock */
+		queue_work(ibs->workqueue, &ibs->ws_awake_rx);
+		spin_unlock_irqrestore(&ibs->hci_ibs_lock, flags);
+		return;
 	case HCI_IBS_RX_AWAKE:
 		/* Always acknowledge device wake up,
 		 * sending IBS message doesn't count as TX ON.
@@ -510,7 +600,8 @@
 	case HCI_IBS_RX_AWAKE:
 		/* update state */
 		ibs->rx_ibs_state = HCI_IBS_RX_ASLEEP;
-		ibs_msm_serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_OFF, hu);
+		/* vote off rx clock under workqueue */
+		queue_work(ibs->workqueue, &ibs->ws_rx_vote_off);
 		break;
 	case HCI_IBS_RX_ASLEEP:
 		/* deliberate fall-through */
@@ -595,20 +686,12 @@
 
 	case HCI_IBS_TX_ASLEEP:
 		BT_DBG("device asleep, waking up and queueing packet");
-		ibs_msm_serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_ON, hu);
 		/* save packet for later */
 		skb_queue_tail(&ibs->tx_wait_q, skb);
-		/* awake device */
-		if (send_hci_ibs_cmd(HCI_IBS_WAKE_IND, hu) < 0) {
-			BT_ERR("cannot send WAKE to device");
-			break;
-		}
-		ibs->ibs_sent_wakes++; /* debug */
-
-		/* start retransmit timer */
-		mod_timer(&ibs->wake_retrans_timer, jiffies + wake_retrans);
 
 		ibs->tx_ibs_state = HCI_IBS_TX_WAKING;
+		/* schedule a work queue to wake up device */
+		queue_work(ibs->workqueue, &ibs->ws_awake_device);
 		break;
 
 	case HCI_IBS_TX_WAKING:
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 0febaf3..69783f4 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -272,6 +272,7 @@
 	unsigned char *buf_in_smux;
 	int in_busy_smux;
 	int diag_smux_enabled;
+	int smux_connected;
 	/* HSIC variables */
 	unsigned char *buf_in_hsic;
 	int hsic_ch;
diff --git a/drivers/char/diag/diagfwd_hsic.c b/drivers/char/diag/diagfwd_hsic.c
index fedcf03..81c6afa 100644
--- a/drivers/char/diag/diagfwd_hsic.c
+++ b/drivers/char/diag/diagfwd_hsic.c
@@ -296,7 +296,7 @@
 		usb_diag_free_req(driver->mdm_ch);
 	}
 
-	if (driver->logging_mode != MEMORY_DEVICE_MODE) {
+	if (driver->logging_mode == USB_MODE) {
 		if (driver->hsic_device_enabled) {
 			driver->in_busy_hsic_write_on_device = 1;
 			driver->in_busy_hsic_read_on_device = 1;
@@ -307,6 +307,7 @@
 		} else if (driver->diag_smux_enabled) {
 			driver->in_busy_smux = 1;
 			driver->lcid = LCID_INVALID;
+			driver->smux_connected = 0;
 			/* Turn off communication over usb mdm and smux */
 			msm_smux_close(LCID_VALID);
 		}
@@ -440,7 +441,8 @@
 	int ret;
 	if (driver->diag_smux_enabled) {
 		if (driver->lcid && driver->usb_buf_mdm_out &&
-					 (driver->read_len_mdm > 0)) {
+				(driver->read_len_mdm > 0) &&
+				driver->smux_connected) {
 			ret = msm_smux_write(driver->lcid,  NULL,
 		 driver->usb_buf_mdm_out, driver->read_len_mdm);
 			if (ret)
diff --git a/drivers/char/diag/diagfwd_smux.c b/drivers/char/diag/diagfwd_smux.c
index 8bbc67e..ae90686 100644
--- a/drivers/char/diag/diagfwd_smux.c
+++ b/drivers/char/diag/diagfwd_smux.c
@@ -26,13 +26,17 @@
 
 	switch (event_type) {
 	case SMUX_CONNECTED:
-		pr_debug("diag: SMUX_CONNECTED received\n");
+		pr_info("diag: SMUX_CONNECTED received\n");
+		driver->smux_connected = 1;
 		driver->in_busy_smux = 0;
 		/* read data from USB MDM channel & Initiate first write */
 		queue_work(driver->diag_bridge_wq,
 				 &(driver->diag_read_mdm_work));
 		break;
 	case SMUX_DISCONNECTED:
+		driver->smux_connected = 0;
+		driver->lcid = LCID_INVALID;
+		msm_smux_close(LCID_VALID);
 		pr_info("diag: SMUX_DISCONNECTED received\n");
 		break;
 	case SMUX_WRITE_DONE:
@@ -112,6 +116,7 @@
 			pr_info("diag: open SMUX ch, r = %d\n", ret);
 		} else {
 			pr_err("diag: failed to open SMUX ch, r = %d\n", ret);
+			return ret;
 		}
 	}
 	/* Poll USB channel to check for data*/
@@ -146,8 +151,20 @@
 	return ret;
 }
 
+static int diagfwd_smux_remove(struct platform_device *pdev)
+{
+	driver->lcid = LCID_INVALID;
+	driver->smux_connected = 0;
+	driver->diag_smux_enabled = 0;
+	driver->in_busy_smux = 1;
+	kfree(driver->buf_in_smux);
+	driver->buf_in_smux = NULL;
+	return 0;
+}
+
 struct platform_driver msm_diagfwd_smux_driver = {
 	.probe = diagfwd_smux_probe,
+	.remove = diagfwd_smux_remove,
 	.driver = {
 		   .name = "SMUX_DIAG",
 		   .owner = THIS_MODULE,
diff --git a/drivers/coresight/coresight-etm.c b/drivers/coresight/coresight-etm.c
index e805c7f..46d3e5d 100644
--- a/drivers/coresight/coresight-etm.c
+++ b/drivers/coresight/coresight-etm.c
@@ -1516,6 +1516,12 @@
 	static int etm_count;
 	struct coresight_desc *desc;
 
+	/* Fail probe for Krait pass3 until supported */
+	if (cpu_is_krait_v3()) {
+		dev_info(dev, "ETM: failing probe for Krait pass3\n");
+		return -EINVAL;
+	}
+
 	if (pdev->dev.of_node) {
 		pdata = of_get_coresight_platform_data(dev, pdev->dev.of_node);
 		if (IS_ERR(pdata))
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index b4ae6ef..19dd6dc 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -179,7 +179,7 @@
 		"a300_pm4.fw", "a300_pfp.fw", &adreno_a3xx_gpudev,
 		512, 0, 2, SZ_256K },
 	/* A3XX doesn't use the pix_shader_start */
-	{ ADRENO_REV_A320, 3, 2, 0, ANY_ID,
+	{ ADRENO_REV_A320, 3, 2, ANY_ID, ANY_ID,
 		"a300_pm4.fw", "a300_pfp.fw", &adreno_a3xx_gpudev,
 		512, 0, 2, SZ_512K },
 	{ ADRENO_REV_A330, 3, 3, 0, 0,
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 880fe92..8c45475 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -465,16 +465,17 @@
 			&pwr->power_flags)) {
 			trace_kgsl_clk(device, state);
 			/* High latency clock maintenance. */
-			if ((pwr->pwrlevels[0].gpu_freq > 0) &&
-				(device->state != KGSL_STATE_NAP)) {
+			if (device->state != KGSL_STATE_NAP) {
 				for (i = KGSL_MAX_CLKS - 1; i > 0; i--)
 					if (pwr->grp_clks[i])
 						clk_prepare(pwr->grp_clks[i]);
-				clk_set_rate(pwr->grp_clks[0],
-					pwr->pwrlevels[pwr->active_pwrlevel].
+
+				if (pwr->pwrlevels[0].gpu_freq > 0)
+					clk_set_rate(pwr->grp_clks[0],
+						pwr->pwrlevels
+						[pwr->active_pwrlevel].
 						gpu_freq);
 			}
-
 			/* as last step, enable grp_clk
 			   this is to let GPU interrupt to come */
 			for (i = KGSL_MAX_CLKS - 1; i > 0; i--)
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index c6d568c..0d15f75 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -939,7 +939,6 @@
 		server_q_idx = msm_find_free_queue();
 		if (server_q_idx < 0)
 			return server_q_idx;
-
 		rc = msm_server_begin_session(pcam, server_q_idx);
 		if (rc < 0) {
 			pr_err("%s error starting server session ", __func__);
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 5b618f8..577648f 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -31,6 +31,7 @@
 #include <media/videobuf2-msm-mem.h>
 #include <media/msm_isp.h>
 #include <mach/camera.h>
+#include <mach/iommu.h>
 #include <media/msm_isp.h>
 #include <linux/ion.h>
 #include <linux/iommu.h>
@@ -315,6 +316,10 @@
 	uint32_t ping_imem_cbcr;
 	uint32_t pong_imem_y;
 	uint32_t pong_imem_cbcr;
+
+	/*IOMMU domain for this session*/
+	int domain_num;
+	struct iommu_domain *domain;
 };
 
 struct msm_isp_buf_info {
@@ -417,6 +422,8 @@
 	struct msm_cam_media_controller *p_mctl;
 	struct msm_mem_map_info mem_map;
 	int dev_num;
+	int domain_num;
+	struct iommu_domain *domain;
 };
 
 struct msm_cam_subdev_info {
@@ -576,6 +583,10 @@
 	 * dispatch the irq to the corresponding subdev. */
 	struct v4l2_subdev *subdev_table[MSM_CAM_HW_MAX];
 	struct msm_cam_server_irqmap_entry hw_irqmap[CAMERA_SS_IRQ_MAX];
+
+    /*IOMMU domain (Page table)*/
+	int domain_num;
+	struct iommu_domain *domain;
 };
 
 enum msm_cam_buf_lookup_type {
@@ -623,9 +634,9 @@
 	struct msm_free_buf *free_buf);
 /*Memory(PMEM) functions*/
 int msm_register_pmem(struct hlist_head *ptype, void __user *arg,
-	struct ion_client *client);
+	struct ion_client *client, int domain_num);
 int msm_pmem_table_del(struct hlist_head *ptype, void __user *arg,
-	struct ion_client *client);
+	struct ion_client *client, int domain_num);
 int msm_pmem_region_get_phy_addr(struct hlist_head *ptype,
 	struct msm_mem_map_info *mem_map, int32_t *phyaddr);
 uint8_t msm_pmem_region_lookup(struct hlist_head *ptype,
@@ -647,7 +658,7 @@
 	struct msm_vfe_cfg_cmd *cfgcmd, void *data);
 int msm_vpe_subdev_init(struct v4l2_subdev *sd);
 int msm_gemini_subdev_init(struct v4l2_subdev *gemini_sd);
-void msm_vpe_subdev_release(void);
+void msm_vpe_subdev_release(struct v4l2_subdev *sd);
 void msm_gemini_subdev_release(struct v4l2_subdev *gemini_sd);
 int msm_mctl_is_pp_msg_type(struct msm_cam_media_controller *p_mctl,
 	int msg_type);
@@ -695,9 +706,9 @@
 int msm_mctl_buf_return_buf(struct msm_cam_media_controller *pmctl,
 	int image_mode, struct msm_frame_buffer *buf);
 int msm_mctl_map_user_frame(struct msm_cam_meta_frame *meta_frame,
-	struct ion_client *client);
+	struct ion_client *client, int domain_num);
 int msm_mctl_unmap_user_frame(struct msm_cam_meta_frame *meta_frame,
-	struct ion_client *client);
+	struct ion_client *client, int domain_num);
 int msm_mctl_pp_mctl_divert_done(struct msm_cam_media_controller *p_mctl,
 	void __user *arg);
 void msm_release_ion_client(struct kref *ref);
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index a0cbed5..953f042 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -130,7 +130,8 @@
 			rc = videobuf2_pmem_contig_user_get(mem, &offset,
 				buf_type,
 				pcam_inst->buf_offset[buf_idx][i].addr_offset,
-				pcam_inst->path, pmctl->client);
+				pcam_inst->path, pmctl->client,
+				pmctl->domain_num);
 		else
 			rc = videobuf2_pmem_contig_mmap_get(mem, &offset,
 				buf_type, pcam_inst->path);
@@ -265,7 +266,8 @@
 	}
 	for (i = 0; i < vb->num_planes; i++) {
 		mem = vb2_plane_cookie(vb, i);
-		videobuf2_pmem_contig_user_put(mem, pmctl->client);
+		videobuf2_pmem_contig_user_put(mem, pmctl->client,
+			pmctl->domain_num);
 	}
 	buf->state = MSM_BUFFER_STATE_UNUSED;
 }
@@ -856,21 +858,21 @@
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 /* Unmap using ION APIs */
 static void __msm_mctl_unmap_user_frame(struct msm_cam_meta_frame *meta_frame,
-	struct ion_client *client)
+	struct ion_client *client, int domain_num)
 {
 	int i = 0;
 	for (i = 0; i < meta_frame->frame.num_planes; i++) {
 		D("%s Plane %d handle %p", __func__, i,
 			meta_frame->map[i].handle);
 		ion_unmap_iommu(client, meta_frame->map[i].handle,
-					CAMERA_DOMAIN, GEN_POOL);
+					domain_num, 0);
 		ion_free(client, meta_frame->map[i].handle);
 	}
 }
 
 /* Map using ION APIs */
 static int __msm_mctl_map_user_frame(struct msm_cam_meta_frame *meta_frame,
-	struct ion_client *client)
+	struct ion_client *client, int domain_num)
 {
 	unsigned long paddr = 0;
 	unsigned long len = 0;
@@ -886,7 +888,7 @@
 			for (j = i-1; j >= 0; j--) {
 				ion_unmap_iommu(client,
 					meta_frame->map[j].handle,
-					CAMERA_DOMAIN, GEN_POOL);
+					domain_num, 0);
 				ion_free(client, meta_frame->map[j].handle);
 			}
 			return -EACCES;
@@ -895,7 +897,7 @@
 			meta_frame->frame.mp[i].fd, i,
 			meta_frame->map[i].handle);
 		if (ion_map_iommu(client, meta_frame->map[i].handle,
-				CAMERA_DOMAIN, GEN_POOL, SZ_4K,
+				domain_num, 0, SZ_4K,
 				0, &paddr, &len, UNCACHED, 0) < 0) {
 			pr_err("%s: cannot map address plane %d", __func__, i);
 			ion_free(client, meta_frame->map[i].handle);
@@ -904,7 +906,7 @@
 				if (meta_frame->map[j].handle) {
 					ion_unmap_iommu(client,
 						meta_frame->map[j].handle,
-						CAMERA_DOMAIN, GEN_POOL);
+						domain_num, 0);
 					ion_free(client,
 						meta_frame->map[j].handle);
 				}
@@ -925,7 +927,7 @@
 				if (meta_frame->map[j].handle) {
 					ion_unmap_iommu(client,
 						meta_frame->map[j].handle,
-						CAMERA_DOMAIN, GEN_POOL);
+						domain_num, 0);
 					ion_free(client,
 						meta_frame->map[j].handle);
 				}
@@ -952,7 +954,7 @@
 #else
 /* Unmap using PMEM APIs */
 static int __msm_mctl_unmap_user_frame(struct msm_cam_meta_frame *meta_frame,
-	struct ion_client *client)
+	struct ion_client *client, int domain_num)
 {
 	int i = 0, rc = 0;
 
@@ -965,7 +967,7 @@
 
 /* Map using PMEM APIs */
 static int __msm_mctl_map_user_frame(struct msm_cam_meta_frame *meta_frame,
-	struct ion_client *client)
+	struct ion_client *client, int domain_num)
 {
 	unsigned long kvstart = 0;
 	unsigned long paddr = 0;
@@ -1024,7 +1026,7 @@
 #endif
 
 int msm_mctl_map_user_frame(struct msm_cam_meta_frame *meta_frame,
-	struct ion_client *client)
+	struct ion_client *client, int domain_num)
 {
 
 	if ((NULL == meta_frame) || (NULL == client)) {
@@ -1035,16 +1037,16 @@
 	memset(&meta_frame->map[0], 0,
 		sizeof(struct msm_cam_buf_map_info) * VIDEO_MAX_PLANES);
 
-	return __msm_mctl_map_user_frame(meta_frame, client);
+	return __msm_mctl_map_user_frame(meta_frame, client, domain_num);
 }
 
 int msm_mctl_unmap_user_frame(struct msm_cam_meta_frame *meta_frame,
-	struct ion_client *client)
+	struct ion_client *client, int domain_num)
 {
 	if ((NULL == meta_frame) || (NULL == client)) {
 		pr_err("%s Invalid input ", __func__);
 		return -EINVAL;
 	}
-	__msm_mctl_unmap_user_frame(meta_frame, client);
+	__msm_mctl_unmap_user_frame(meta_frame, client, domain_num);
 	return 0;
 }
diff --git a/drivers/media/video/msm/msm_mem.c b/drivers/media/video/msm/msm_mem.c
index e2e9d1b..5136d9d 100644
--- a/drivers/media/video/msm/msm_mem.c
+++ b/drivers/media/video/msm/msm_mem.c
@@ -116,7 +116,7 @@
 }
 
 static int msm_pmem_table_add(struct hlist_head *ptype,
-	struct msm_pmem_info *info, struct ion_client *client)
+	struct msm_pmem_info *info, struct ion_client *client, int domain_num)
 {
 	unsigned long paddr;
 #ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
@@ -135,7 +135,7 @@
 	region->handle = ion_import_dma_buf(client, info->fd);
 	if (IS_ERR_OR_NULL(region->handle))
 		goto out1;
-	if (ion_map_iommu(client, region->handle, CAMERA_DOMAIN, GEN_POOL,
+	if (ion_map_iommu(client, region->handle, domain_num, 0,
 				  SZ_4K, 0, &paddr, &len, UNCACHED, 0) < 0)
 		goto out2;
 #elif CONFIG_ANDROID_PMEM
@@ -180,7 +180,7 @@
 	return 0;
 out3:
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_unmap_iommu(client, region->handle, CAMERA_DOMAIN, GEN_POOL);
+	ion_unmap_iommu(client, region->handle, domain_num, 0);
 #endif
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 out2:
@@ -195,7 +195,8 @@
 }
 
 static int __msm_register_pmem(struct hlist_head *ptype,
-			struct msm_pmem_info *pinfo, struct ion_client *client)
+			struct msm_pmem_info *pinfo, struct ion_client *client,
+			int domain_num)
 {
 	int rc = 0;
 
@@ -211,7 +212,7 @@
 	case MSM_PMEM_BAYER_GRID:
 	case MSM_PMEM_BAYER_FOCUS:
 	case MSM_PMEM_BAYER_HIST:
-		rc = msm_pmem_table_add(ptype, pinfo, client);
+		rc = msm_pmem_table_add(ptype, pinfo, client, domain_num);
 		break;
 
 	default:
@@ -223,7 +224,8 @@
 }
 
 static int __msm_pmem_table_del(struct hlist_head *ptype,
-			struct msm_pmem_info *pinfo, struct ion_client *client)
+			struct msm_pmem_info *pinfo, struct ion_client *client,
+			int domain_num)
 {
 	int rc = 0;
 	struct msm_pmem_region *region;
@@ -250,7 +252,7 @@
 				hlist_del(node);
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 				ion_unmap_iommu(client, region->handle,
-					CAMERA_DOMAIN, GEN_POOL);
+					domain_num, 0);
 				ion_free(client, region->handle);
 #else
 				put_pmem_file(region->file);
@@ -394,7 +396,8 @@
 }
 
 int msm_register_pmem(struct hlist_head *ptype, void __user *arg,
-					  struct ion_client *client)
+					struct ion_client *client,
+					int domain_num)
 {
 	struct msm_pmem_info info;
 
@@ -403,12 +406,12 @@
 			return -EFAULT;
 	}
 
-	return __msm_register_pmem(ptype, &info, client);
+	return __msm_register_pmem(ptype, &info, client, domain_num);
 }
 //EXPORT_SYMBOL(msm_register_pmem);
 
 int msm_pmem_table_del(struct hlist_head *ptype, void __user *arg,
-					   struct ion_client *client)
+			struct ion_client *client, int domain_num)
 {
 	struct msm_pmem_info info;
 
@@ -417,6 +420,6 @@
 		return -EFAULT;
 	}
 
-	return __msm_pmem_table_del(ptype, &info, client);
+	return __msm_pmem_table_del(ptype, &info, client, domain_num);
 }
 //EXPORT_SYMBOL(msm_pmem_table_del);
diff --git a/drivers/media/video/msm/msm_vpe.c b/drivers/media/video/msm/msm_vpe.c
index 9fa9734..ede0f7a 100644
--- a/drivers/media/video/msm/msm_vpe.c
+++ b/drivers/media/video/msm/msm_vpe.c
@@ -36,8 +36,8 @@
 #define D(fmt, args...) do {} while (0)
 #endif
 
-static int vpe_enable(uint32_t);
-static int vpe_disable(void);
+static int vpe_enable(uint32_t, struct msm_cam_media_controller *);
+static int vpe_disable(struct msm_cam_media_controller *);
 static int vpe_update_scaler(struct msm_pp_crop *pcrop);
 struct vpe_ctrl_type *vpe_ctrl;
 static atomic_t vpe_init_done = ATOMIC_INIT(0);
@@ -520,7 +520,7 @@
 	{"vpe_pclk", -1},
 };
 
-int vpe_enable(uint32_t clk_rate)
+int vpe_enable(uint32_t clk_rate, struct msm_cam_media_controller *mctl)
 {
 	int rc = 0;
 	unsigned long flags = 0;
@@ -549,8 +549,27 @@
 	if (rc < 0)
 		goto vpe_clk_failed;
 
+#ifdef CONFIG_MSM_IOMMU
+	rc = iommu_attach_device(mctl->domain, vpe_ctrl->iommu_ctx_src);
+	if (rc < 0) {
+		pr_err("%s: Device attach failed\n", __func__);
+		goto src_attach_failed;
+	}
+	rc = iommu_attach_device(mctl->domain, vpe_ctrl->iommu_ctx_dst);
+	if (rc < 0) {
+		pr_err("%s: Device attach failed\n", __func__);
+		goto dst_attach_failed;
+	}
+#endif
 	return rc;
 
+#ifdef CONFIG_MSM_IOMMU
+dst_attach_failed:
+	iommu_detach_device(mctl->domain, vpe_ctrl->iommu_ctx_src);
+src_attach_failed:
+#endif
+	msm_cam_clk_enable(&vpe_ctrl->pdev->dev, vpe_clk_info,
+		vpe_ctrl->vpe_clk, ARRAY_SIZE(vpe_clk_info), 0);
 vpe_clk_failed:
 	if (vpe_ctrl->fs_vpe)
 		regulator_disable(vpe_ctrl->fs_vpe);
@@ -560,7 +579,7 @@
 	return rc;
 }
 
-int vpe_disable(void)
+int vpe_disable(struct msm_cam_media_controller *mctl)
 {
 	int rc = 0;
 	unsigned long flags = 0;
@@ -572,7 +591,10 @@
 		return rc;
 	}
 	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
-
+#ifdef CONFIG_MSM_IOMMU
+	iommu_detach_device(mctl->domain, vpe_ctrl->iommu_ctx_dst);
+	iommu_detach_device(mctl->domain, vpe_ctrl->iommu_ctx_src);
+#endif
 	disable_irq(vpe_ctrl->vpeirq->start);
 	tasklet_kill(&vpe_tasklet);
 	msm_cam_clk_enable(&vpe_ctrl->pdev->dev, vpe_clk_info,
@@ -655,23 +677,25 @@
 	return rc;  /* this rc should have error code. */
 }
 
-void msm_vpe_subdev_release(void)
+void msm_vpe_subdev_release(struct v4l2_subdev *sd)
 {
+	struct msm_cam_media_controller *mctl;
+	mctl = v4l2_get_subdev_hostdata(sd);
 	if (!atomic_read(&vpe_init_done)) {
 		/* no VPE object created */
 		pr_err("%s: no VPE object to release", __func__);
 		return;
 	}
-
 	vpe_reset();
-	vpe_disable();
+	vpe_disable(mctl);
 	iounmap(vpe_ctrl->vpebase);
 	vpe_ctrl->vpebase = NULL;
 	atomic_set(&vpe_init_done, 0);
 }
 EXPORT_SYMBOL(msm_vpe_subdev_release);
 
-static int msm_vpe_process_vpe_cmd(struct msm_vpe_cfg_cmd *vpe_cmd)
+static int msm_vpe_process_vpe_cmd(struct msm_vpe_cfg_cmd *vpe_cmd,
+				struct msm_cam_media_controller *mctl)
 {
 	int rc = 0;
 
@@ -802,7 +826,7 @@
 		D("%s Mapping Source frame ", __func__);
 		zoom->src_frame.frame = zoom->pp_frame_cmd.src_frame;
 		rc = msm_mctl_map_user_frame(&zoom->src_frame,
-			zoom->p_mctl->client);
+			zoom->p_mctl->client, mctl->domain_num);
 		if (rc < 0) {
 			pr_err("%s Error mapping source buffer rc = %d",
 				__func__, rc);
@@ -813,12 +837,12 @@
 		D("%s Mapping Destination frame ", __func__);
 		zoom->dest_frame.frame = zoom->pp_frame_cmd.dest_frame;
 		rc = msm_mctl_map_user_frame(&zoom->dest_frame,
-			zoom->p_mctl->client);
+			zoom->p_mctl->client, mctl->domain_num);
 		if (rc < 0) {
 			pr_err("%s Error mapping dest buffer rc = %d",
 				__func__, rc);
 			msm_mctl_unmap_user_frame(&zoom->src_frame,
-				zoom->p_mctl->client);
+				zoom->p_mctl->client, mctl->domain_num);
 			kfree(zoom);
 			break;
 		}
@@ -843,13 +867,13 @@
 			return -EFAULT;
 		}
 		turbo_mode = (int)clk_rate.rate;
-		rc = turbo_mode ? vpe_enable(VPE_TURBO_MODE_CLOCK_RATE) :
-				vpe_enable(VPE_NORMAL_MODE_CLOCK_RATE);
+		rc = turbo_mode ? vpe_enable(VPE_TURBO_MODE_CLOCK_RATE, mctl) :
+				vpe_enable(VPE_NORMAL_MODE_CLOCK_RATE, mctl);
 		break;
 		}
 
 	case VPE_CMD_DISABLE:
-		rc = vpe_disable();
+		rc = vpe_disable(mctl);
 		break;
 
 	default:
@@ -864,7 +888,8 @@
 {
 	struct msm_vpe_cfg_cmd *vpe_cmd;
 	int rc = 0;
-
+	struct msm_cam_media_controller *mctl;
+	mctl = v4l2_get_subdev_hostdata(sd);
 	switch (cmd) {
 	case VIDIOC_MSM_VPE_INIT: {
 		msm_vpe_subdev_init(sd);
@@ -872,12 +897,12 @@
 		}
 
 	case VIDIOC_MSM_VPE_RELEASE:
-		msm_vpe_subdev_release();
+		msm_vpe_subdev_release(sd);
 		break;
 
 	case MSM_CAM_V4L2_IOCTL_CFG_VPE: {
 		vpe_cmd = (struct msm_vpe_cfg_cmd *)arg;
-		rc = msm_vpe_process_vpe_cmd(vpe_cmd);
+		rc = msm_vpe_process_vpe_cmd(vpe_cmd, mctl);
 		if (rc < 0) {
 			pr_err("%s Error processing VPE cmd %d ",
 				__func__, vpe_cmd->cmd_type);
@@ -903,9 +928,9 @@
 		D("%s Unmapping source and destination buffers ",
 			__func__);
 		msm_mctl_unmap_user_frame(&pp_frame_info->src_frame,
-			pp_frame_info->p_mctl->client);
+			pp_frame_info->p_mctl->client, mctl->domain_num);
 		msm_mctl_unmap_user_frame(&pp_frame_info->dest_frame,
-			pp_frame_info->p_mctl->client);
+			pp_frame_info->p_mctl->client, mctl->domain_num);
 
 		pp_event_info.event = MCTL_PP_EVENT_CMD_ACK;
 		pp_event_info.ack.cmd = pp_frame_info->user_cmd;
@@ -973,7 +998,8 @@
 {
 	struct vpe_ctrl_type *vpe_ctrl = v4l2_get_subdevdata(sd);
 	struct msm_mctl_pp_frame_info *frame_info = vpe_ctrl->pp_frame_info;
-
+	struct msm_cam_media_controller *mctl;
+	mctl = v4l2_get_subdev_hostdata(sd);
 	if (atomic_read(&vpe_ctrl->active) == 0) {
 		pr_err("%s already closed\n", __func__);
 		return -EINVAL;
@@ -983,9 +1009,9 @@
 	if (frame_info) {
 		D("%s Unmap the pending item from the queue ", __func__);
 		msm_mctl_unmap_user_frame(&frame_info->src_frame,
-			frame_info->p_mctl->client);
+			frame_info->p_mctl->client, mctl->domain_num);
 		msm_mctl_unmap_user_frame(&frame_info->dest_frame,
-			frame_info->p_mctl->client);
+			frame_info->p_mctl->client, mctl->domain_num);
 	}
 	/* Drain the payload queue. */
 	msm_queue_drain(&vpe_ctrl->eventData_q, list_eventdata);
@@ -1066,6 +1092,19 @@
 
 	disable_irq(vpe_ctrl->vpeirq->start);
 
+#ifdef CONFIG_MSM_IOMMU
+	/*get device context for IOMMU*/
+	vpe_ctrl->iommu_ctx_src = msm_iommu_get_ctx("vpe_src"); /*re-confirm*/
+	vpe_ctrl->iommu_ctx_dst = msm_iommu_get_ctx("vpe_dst"); /*re-confirm*/
+	if (!vpe_ctrl->iommu_ctx_src || !vpe_ctrl->iommu_ctx_dst) {
+		release_mem_region(vpe_ctrl->vpemem->start,
+			resource_size(vpe_ctrl->vpemem));
+		pr_err("%s: No iommu fw context found\n", __func__);
+		rc = -ENODEV;
+		goto vpe_no_resource;
+	}
+#endif
+
 	atomic_set(&vpe_ctrl->active, 0);
 	vpe_ctrl->pdev = pdev;
 	sd_info.sdev_type = VPE_DEV;
diff --git a/drivers/media/video/msm/msm_vpe.h b/drivers/media/video/msm/msm_vpe.h
index 6516ea1..aad2380 100644
--- a/drivers/media/video/msm/msm_vpe.h
+++ b/drivers/media/video/msm/msm_vpe.h
@@ -121,6 +121,8 @@
 	struct msm_mctl_pp_frame_info *pp_frame_info;
 	atomic_t active;
 	struct msm_device_queue eventData_q; /*V4L2 Event Payload Queue*/
+	struct device *iommu_ctx_src;
+	struct device *iommu_ctx_dst;
 };
 
 /*
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
index f8c102f..b8a6217 100644
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -160,6 +160,16 @@
 			g_server_dev.interface_map_table[i].mctl_handle = 0;
 }
 
+struct iommu_domain *msm_cam_server_get_domain()
+{
+	return g_server_dev.domain;
+}
+
+int msm_cam_server_get_domain_num()
+{
+	return g_server_dev.domain_num;
+}
+
 uint32_t msm_cam_server_get_mctl_handle(void)
 {
 	uint32_t i;
@@ -1056,7 +1066,7 @@
 {
 	int rc = 0;
 	rc = msm_iommu_map_contig_buffer(
-		(unsigned long)IMEM_Y_PING_OFFSET, CAMERA_DOMAIN, GEN_POOL,
+		(unsigned long)IMEM_Y_PING_OFFSET, mctl->domain_num, 0,
 		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)),
 		SZ_4K, IOMMU_WRITE | IOMMU_READ,
 		(unsigned long *)&mctl->ping_imem_y);
@@ -1068,7 +1078,7 @@
 		mctl->ping_imem_cbcr = 0;
 	}
 	msm_iommu_map_contig_buffer(
-		(unsigned long)IMEM_Y_PONG_OFFSET, CAMERA_DOMAIN, GEN_POOL,
+		(unsigned long)IMEM_Y_PONG_OFFSET, mctl->domain_num, 0,
 		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)),
 		SZ_4K, IOMMU_WRITE | IOMMU_READ,
 		(unsigned long *)&mctl->pong_imem_y);
@@ -1085,10 +1095,10 @@
 static void unmap_imem_addresses(struct msm_cam_media_controller *mctl)
 {
 	msm_iommu_unmap_contig_buffer(mctl->ping_imem_y,
-		CAMERA_DOMAIN, GEN_POOL,
+		mctl->domain_num, 0,
 		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)));
 	msm_iommu_unmap_contig_buffer(mctl->pong_imem_y,
-		CAMERA_DOMAIN, GEN_POOL,
+		mctl->domain_num, 0,
 		((IMEM_Y_SIZE + IMEM_CBCR_SIZE + 4095) & (~4095)));
 	mctl->ping_imem_y = 0;
 	mctl->ping_imem_cbcr = 0;
@@ -1471,6 +1481,10 @@
 		pr_err("%s: invalid mctl controller", __func__);
 		goto error;
 	}
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		pmctl->domain = msm_cam_server_get_domain();
+		pmctl->domain_num = msm_cam_server_get_domain_num();
+#endif
 	rc = map_imem_addresses(pmctl);
 	if (rc < 0) {
 		pr_err("%sFailed to map imem addresses %d\n", __func__, rc);
@@ -2215,6 +2229,23 @@
 	return err;
 }
 
+#ifdef CONFIG_MSM_IOMMU
+static int camera_register_domain(void)
+{
+	struct msm_iova_partition camera_fw_partition = {
+		.start = SZ_128K,
+		.size = SZ_2G - SZ_128K,
+	};
+	struct msm_iova_layout camera_fw_layout = {
+		.partitions = &camera_fw_partition,
+		.npartitions = 1,
+		.client_name = "camera_isp",
+		.domain_flags = 0,
+	};
+
+	return msm_register_domain(&camera_fw_layout);
+}
+#endif
 
 static int msm_setup_server_dev(struct platform_device *pdev)
 {
@@ -2291,6 +2322,21 @@
 		g_server_dev.interface_map_table[i].interface = 0x01 << i;
 		g_server_dev.interface_map_table[i].mctl_handle = 0;
 	}
+#ifdef CONFIG_MSM_IOMMU
+	g_server_dev.domain_num = camera_register_domain();
+	if (g_server_dev.domain_num < 0) {
+		pr_err("%s: could not register domain\n", __func__);
+		rc = -ENODEV;
+		return rc;
+	}
+	g_server_dev.domain =
+		msm_get_iommu_domain(g_server_dev.domain_num);
+	if (!g_server_dev.domain) {
+		pr_err("%s: cannot find domain\n", __func__);
+		rc = -ENODEV;
+		return rc;
+	}
+#endif
 	return rc;
 }
 
@@ -2348,6 +2394,11 @@
 		return rc;
 	}
 
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		pmctl->domain = msm_cam_server_get_domain();
+		pmctl->domain_num = msm_cam_server_get_domain_num();
+#endif
+
 	D("%s: call mctl_open\n", __func__);
 	rc = pmctl->mctl_open(pmctl, MSM_APPS_ID_V4L2);
 
@@ -2620,6 +2671,7 @@
 		pr_err("%s: cannot find mctl\n", __func__);
 		return -ENODEV;
 	}
+
 	INIT_HLIST_HEAD(&config_cam->p_mctl->stats_info.pmem_stats_list);
 	spin_lock_init(&config_cam->p_mctl->stats_info.pmem_stats_spinlock);
 
@@ -2733,13 +2785,15 @@
 	case MSM_CAM_IOCTL_REGISTER_PMEM:
 		return msm_register_pmem(
 			&config_cam->p_mctl->stats_info.pmem_stats_list,
-			(void __user *)arg, config_cam->p_mctl->client);
+			(void __user *)arg, config_cam->p_mctl->client,
+			config_cam->p_mctl->domain_num);
 		break;
 
 	case MSM_CAM_IOCTL_UNREGISTER_PMEM:
 		return msm_pmem_table_del(
 			&config_cam->p_mctl->stats_info.pmem_stats_list,
-			(void __user *)arg, config_cam->p_mctl->client);
+			(void __user *)arg, config_cam->p_mctl->client,
+			config_cam->p_mctl->domain_num);
 		break;
 
 	case VIDIOC_SUBSCRIBE_EVENT:
diff --git a/drivers/media/video/msm/server/msm_cam_server.h b/drivers/media/video/msm/server/msm_cam_server.h
index 42900f3..d38bb98 100644
--- a/drivers/media/video/msm/server/msm_cam_server.h
+++ b/drivers/media/video/msm/server/msm_cam_server.h
@@ -20,6 +20,8 @@
 #include "msm.h"
 
 uint32_t msm_cam_server_get_mctl_handle(void);
+struct iommu_domain *msm_cam_server_get_domain(void);
+int msm_cam_server_get_domain_num(void);
 struct msm_cam_media_controller *msm_cam_server_get_mctl(uint32_t handle);
 void msm_cam_server_free_mctl(uint32_t handle);
 /* Server session control APIs */
diff --git a/drivers/media/video/msm/vfe/msm_vfe31_v4l2.c b/drivers/media/video/msm/vfe/msm_vfe31_v4l2.c
index 0bd7b94..2179282 100644
--- a/drivers/media/video/msm/vfe/msm_vfe31_v4l2.c
+++ b/drivers/media/video/msm/vfe/msm_vfe31_v4l2.c
@@ -401,7 +401,7 @@
 		stats_buf = &bufq->bufs[i];
 		rc = vfe31_ctrl->stats_ops.enqueue_buf(
 				vfe31_ctrl->stats_ops.stats_ctrl,
-				&(stats_buf->info), NULL);
+				&(stats_buf->info), NULL, -1);
 		if (rc < 0) {
 			pr_err("%s: dq stats buf (type = %d) err = %d",
 				__func__, stats_type, rc);
@@ -412,7 +412,7 @@
 }
 
 static unsigned long vfe31_stats_unregbuf(
-	struct msm_stats_reqbuf *req_buf)
+	struct msm_stats_reqbuf *req_buf, int domain_num)
 {
 	int i = 0, rc = 0;
 
@@ -420,7 +420,7 @@
 		rc = vfe31_ctrl->stats_ops.buf_unprepare(
 			vfe31_ctrl->stats_ops.stats_ctrl,
 			req_buf->stats_type, i,
-			vfe31_ctrl->stats_ops.client);
+			vfe31_ctrl->stats_ops.client, domain_num);
 		if (rc < 0) {
 			pr_err("%s: unreg stats buf (type = %d) err = %d",
 				__func__, req_buf->stats_type, rc);
@@ -3296,7 +3296,7 @@
 }
 
 static long vfe_stats_bufq_sub_ioctl(struct msm_vfe_cfg_cmd *cmd,
-	void *ion_client)
+	void *ion_client, int domain_num)
 {
 	long rc = 0;
 	switch (cmd->cmd_type) {
@@ -3344,7 +3344,7 @@
 		}
 		rc = vfe31_ctrl->stats_ops.enqueue_buf(&vfe31_ctrl->stats_ctrl,
 				(struct msm_stats_buf_info *)cmd->value,
-				vfe31_ctrl->stats_ops.client);
+				vfe31_ctrl->stats_ops.client, domain_num);
 	break;
 	case VFE_CMD_STATS_FLUSH_BUFQ: {
 		struct msm_stats_flush_bufq *flush_req = NULL;
@@ -3376,7 +3376,7 @@
 			rc = -EINVAL ;
 			goto end;
 		}
-		rc = vfe31_stats_unregbuf(req_buf);
+		rc = vfe31_stats_unregbuf(req_buf, domain_num);
 	}
 	break;
 	default:
@@ -3630,7 +3630,8 @@
 	case VFE_CMD_STATS_FLUSH_BUFQ:
 	case VFE_CMD_STATS_UNREGBUF:
 		/* for easy porting put in one envelope */
-		rc = vfe_stats_bufq_sub_ioctl(cmd, vfe_params->data);
+		rc = vfe_stats_bufq_sub_ioctl(cmd, vfe_params->data,
+			pmctl->domain_num);
 		return rc;
 	default:
 		if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
@@ -4003,10 +4004,25 @@
 			vfe31_ctrl->vfe_camif_clk,
 			ARRAY_SIZE(vfe_camif_clk_info), 1);
 		if (rc < 0)
-			goto vfe_clk_enable_failed;
+			goto vfe_camif_clk_enable_failed;
 		msm_vfe_camif_pad_reg_reset();
 	}
 
+#ifdef CONFIG_MSM_IOMMU
+	rc = iommu_attach_device(mctl->domain, vfe31_ctrl->iommu_ctx_imgwr);
+	if (rc < 0) {
+		rc = -ENODEV;
+		pr_err("%s: Device attach failed\n", __func__);
+		goto device_imgwr_attach_failed;
+	}
+	rc = iommu_attach_device(mctl->domain, vfe31_ctrl->iommu_ctx_misc);
+	if (rc < 0) {
+		rc = -ENODEV;
+		pr_err("%s: Device attach failed\n", __func__);
+		goto device_misc_attach_failed;
+	}
+#endif
+
 	msm_camio_bus_scale_cfg(
 		mctl->sdata->pdata->cam_bus_scale_table, S_INIT);
 	msm_camio_bus_scale_cfg(
@@ -4017,6 +4033,19 @@
 
 	return rc;
 
+#ifdef CONFIG_MSM_IOMMU
+device_misc_attach_failed:
+	iommu_detach_device(mctl->domain, vfe31_ctrl->iommu_ctx_imgwr);
+device_imgwr_attach_failed:
+#endif
+	if (!mctl->sdata->csi_if)
+		msm_cam_clk_enable(&vfe31_ctrl->pdev->dev,
+			vfe_camif_clk_info,
+			vfe31_ctrl->vfe_camif_clk,
+			ARRAY_SIZE(vfe_camif_clk_info), 0);
+vfe_camif_clk_enable_failed:
+	msm_cam_clk_enable(&vfe31_ctrl->pdev->dev, vfe_clk_info,
+		vfe31_ctrl->vfe_clk, ARRAY_SIZE(vfe_clk_info), 0);
 vfe_clk_enable_failed:
 	regulator_disable(vfe31_ctrl->fs_vfe);
 vfe_fs_failed:
@@ -4025,7 +4054,6 @@
 camif_remap_failed:
 	iounmap(vfe31_ctrl->vfebase);
 vfe_remap_failed:
-	disable_irq(vfe31_ctrl->vfeirq->start);
 mctl_failed:
 	return rc;
 }
@@ -4037,6 +4065,11 @@
 	disable_irq(vfe31_ctrl->vfeirq->start);
 	tasklet_kill(&vfe31_tasklet);
 
+#ifdef CONFIG_MSM_IOMMU
+	iommu_detach_device(pmctl->domain, vfe31_ctrl->iommu_ctx_misc);
+	iommu_detach_device(pmctl->domain, vfe31_ctrl->iommu_ctx_imgwr);
+#endif
+
 	if (!pmctl->sdata->csi_if)
 		msm_cam_clk_enable(&vfe31_ctrl->pdev->dev,
 			vfe_camif_clk_info,
@@ -4140,6 +4173,25 @@
 
 	disable_irq(vfe31_ctrl->vfeirq->start);
 
+#ifdef CONFIG_MSM_IOMMU
+	/*get device context for IOMMU*/
+	vfe31_ctrl->iommu_ctx_imgwr =
+		msm_iommu_get_ctx("vfe_imgwr"); /*re-confirm*/
+	vfe31_ctrl->iommu_ctx_misc =
+		msm_iommu_get_ctx("vfe_misc"); /*re-confirm*/
+	if (!vfe31_ctrl->iommu_ctx_imgwr || !vfe31_ctrl->iommu_ctx_misc) {
+		if (vfe31_ctrl->camifmem) {
+			release_mem_region(vfe31_ctrl->camifmem->start,
+				resource_size(vfe31_ctrl->camifmem));
+		}
+		release_mem_region(vfe31_ctrl->vfemem->start,
+			resource_size(vfe31_ctrl->vfemem));
+		pr_err("%s: No iommu fw context found\n", __func__);
+		rc = -ENODEV;
+		goto vfe31_no_resource;
+	}
+#endif
+
 	vfe31_ctrl->pdev = pdev;
 	vfe31_ctrl->fs_vfe = regulator_get(&vfe31_ctrl->pdev->dev, "vdd");
 	if (IS_ERR(vfe31_ctrl->fs_vfe)) {
diff --git a/drivers/media/video/msm/vfe/msm_vfe31_v4l2.h b/drivers/media/video/msm/vfe/msm_vfe31_v4l2.h
index 60db8e5..97ecd6e 100644
--- a/drivers/media/video/msm/vfe/msm_vfe31_v4l2.h
+++ b/drivers/media/video/msm/vfe/msm_vfe31_v4l2.h
@@ -928,6 +928,8 @@
 	uint32_t snapshot_frame_cnt;
 	struct msm_stats_bufq_ctrl stats_ctrl;
 	struct msm_stats_ops stats_ops;
+	struct device *iommu_ctx_imgwr;
+	struct device *iommu_ctx_misc;
 };
 
 enum VFE31_STATS_NUM {
diff --git a/drivers/media/video/msm/vfe/msm_vfe32.c b/drivers/media/video/msm/vfe/msm_vfe32.c
index 84a36b9..908f3fb 100644
--- a/drivers/media/video/msm/vfe/msm_vfe32.c
+++ b/drivers/media/video/msm/vfe/msm_vfe32.c
@@ -995,7 +995,7 @@
 		stats_buf = &bufq->bufs[i];
 		rc = vfe32_ctrl->stats_ops.enqueue_buf(
 				vfe32_ctrl->stats_ops.stats_ctrl,
-				&(stats_buf->info), NULL);
+				&(stats_buf->info), NULL, -1);
 		if (rc < 0) {
 			pr_err("%s: dq stats buf (type = %d) err = %d",
 				 __func__, stats_type, rc);
@@ -1008,7 +1008,7 @@
 
 static unsigned long vfe32_stats_unregbuf(
 	struct vfe32_ctrl_type *vfe32_ctrl,
-	struct msm_stats_reqbuf *req_buf)
+	struct msm_stats_reqbuf *req_buf, int domain_num)
 {
 	int i = 0, rc = 0;
 
@@ -1016,7 +1016,7 @@
 		rc = vfe32_ctrl->stats_ops.buf_unprepare(
 			vfe32_ctrl->stats_ops.stats_ctrl,
 			req_buf->stats_type, i,
-			vfe32_ctrl->stats_ops.client);
+			vfe32_ctrl->stats_ops.client, domain_num);
 		if (rc < 0) {
 			pr_err("%s: unreg stats buf (type = %d) err = %d",
 				__func__, req_buf->stats_type, rc);
@@ -4910,7 +4910,7 @@
 
 static long vfe_stats_bufq_sub_ioctl(
 	struct vfe32_ctrl_type *vfe_ctrl,
-	struct msm_vfe_cfg_cmd *cmd, void *ion_client)
+	struct msm_vfe_cfg_cmd *cmd, void *ion_client, int domain_num)
 {
 	long rc = 0;
 	switch (cmd->cmd_type) {
@@ -4959,7 +4959,7 @@
 	rc = vfe_ctrl->stats_ops.enqueue_buf(
 			&vfe_ctrl->stats_ctrl,
 			(struct msm_stats_buf_info *)cmd->value,
-			vfe_ctrl->stats_ops.client);
+			vfe_ctrl->stats_ops.client, domain_num);
 	break;
 	case VFE_CMD_STATS_FLUSH_BUFQ:
 	{
@@ -4993,7 +4993,7 @@
 			rc = -EINVAL ;
 			goto end;
 		}
-		rc = vfe32_stats_unregbuf(vfe_ctrl, req_buf);
+		rc = vfe32_stats_unregbuf(vfe_ctrl, req_buf, domain_num);
 	}
 	break;
 	default:
@@ -5048,7 +5048,7 @@
 	case VFE_CMD_STATS_UNREGBUF:
 		/* for easy porting put in one envelope */
 		rc = vfe_stats_bufq_sub_ioctl(vfe32_ctrl,
-				cmd, vfe_params->data);
+				cmd, vfe_params->data, pmctl->domain_num);
 		return rc;
 	default:
 		if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
@@ -5273,6 +5273,21 @@
 	if (rc < 0)
 		goto clk_enable_failed;
 
+#ifdef CONFIG_MSM_IOMMU
+	rc = iommu_attach_device(mctl->domain, axi_ctrl->iommu_ctx_imgwr);
+	if (rc < 0) {
+		pr_err("%s: imgwr attach failed rc = %d\n", __func__, rc);
+		rc = -ENODEV;
+		goto device_imgwr_attach_failed;
+	}
+	rc = iommu_attach_device(mctl->domain, axi_ctrl->iommu_ctx_misc);
+	if (rc < 0) {
+		pr_err("%s: misc attach failed rc = %d\n", __func__, rc);
+		rc = -ENODEV;
+		goto device_misc_attach_failed;
+	}
+#endif
+
 	msm_camio_bus_scale_cfg(
 		mctl->sdata->pdata->cam_bus_scale_table, S_INIT);
 	msm_camio_bus_scale_cfg(
@@ -5293,6 +5308,13 @@
 
 	return rc;
 
+#ifdef CONFIG_MSM_IOMMU
+device_misc_attach_failed:
+	iommu_detach_device(mctl->domain, axi_ctrl->iommu_ctx_imgwr);
+device_imgwr_attach_failed:
+#endif
+	msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe32_clk_info,
+			axi_ctrl->vfe_clk, ARRAY_SIZE(vfe32_clk_info), 0);
 clk_enable_failed:
 	if (axi_ctrl->fs_vfe)
 		regulator_disable(axi_ctrl->fs_vfe);
@@ -5300,7 +5322,6 @@
 	iounmap(axi_ctrl->share_ctrl->vfebase);
 	axi_ctrl->share_ctrl->vfebase = NULL;
 remap_failed:
-	disable_irq(axi_ctrl->vfeirq->start);
 mctl_failed:
 	return rc;
 }
@@ -5344,6 +5365,10 @@
 		return;
 	disable_irq(axi_ctrl->vfeirq->start);
 	tasklet_kill(&axi_ctrl->vfe32_tasklet);
+#ifdef CONFIG_MSM_IOMMU
+	iommu_detach_device(pmctl->domain, axi_ctrl->iommu_ctx_misc);
+	iommu_detach_device(pmctl->domain, axi_ctrl->iommu_ctx_imgwr);
+#endif
 	msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe32_clk_info,
 			axi_ctrl->vfe_clk, ARRAY_SIZE(vfe32_clk_info), 0);
 	if (axi_ctrl->fs_vfe)
@@ -6396,6 +6421,21 @@
 		goto vfe32_no_resource;
 	}
 
+#ifdef CONFIG_MSM_IOMMU
+	/*get device context for IOMMU*/
+	axi_ctrl->iommu_ctx_imgwr =
+		msm_iommu_get_ctx("vfe_imgwr"); /*re-confirm*/
+	axi_ctrl->iommu_ctx_misc =
+		msm_iommu_get_ctx("vfe_misc"); /*re-confirm*/
+	if (!axi_ctrl->iommu_ctx_imgwr || !axi_ctrl->iommu_ctx_misc) {
+		release_mem_region(axi_ctrl->vfemem->start,
+			resource_size(axi_ctrl->vfemem));
+		pr_err("%s: No iommu fw context found\n", __func__);
+		rc = -ENODEV;
+		goto vfe32_no_resource;
+	}
+#endif
+
 	tasklet_init(&axi_ctrl->vfe32_tasklet,
 		axi32_do_tasklet, (unsigned long)axi_ctrl);
 
diff --git a/drivers/media/video/msm/vfe/msm_vfe32.h b/drivers/media/video/msm/vfe/msm_vfe32.h
index 81df0d5..985493e 100644
--- a/drivers/media/video/msm/vfe/msm_vfe32.h
+++ b/drivers/media/video/msm/vfe/msm_vfe32.h
@@ -1006,6 +1006,8 @@
 	struct clk *vfe_clk[3];
 	struct tasklet_struct vfe32_tasklet;
 	struct vfe_share_ctrl_t *share_ctrl;
+	struct device *iommu_ctx_imgwr;
+	struct device *iommu_ctx_misc;
 };
 
 struct vfe32_ctrl_type {
diff --git a/drivers/media/video/msm/vfe/msm_vfe40.c b/drivers/media/video/msm/vfe/msm_vfe40.c
index 1aee087..875e034 100644
--- a/drivers/media/video/msm/vfe/msm_vfe40.c
+++ b/drivers/media/video/msm/vfe/msm_vfe40.c
@@ -415,7 +415,7 @@
 		stats_buf = &bufq->bufs[i];
 		rc = vfe40_ctrl->stats_ops.enqueue_buf(
 				vfe40_ctrl->stats_ops.stats_ctrl,
-				&(stats_buf->info), NULL);
+				&(stats_buf->info), NULL, -1);
 		if (rc < 0) {
 			pr_err("%s: dq stats buf (type = %d) err = %d",
 				 __func__, stats_type, rc);
@@ -3308,7 +3308,7 @@
 
 static long vfe_stats_bufq_sub_ioctl(
 	struct vfe40_ctrl_type *vfe_ctrl,
-	struct msm_vfe_cfg_cmd *cmd, void *ion_client)
+	struct msm_vfe_cfg_cmd *cmd, void *ion_client, int domain_num)
 {
 	long rc = 0;
 	switch (cmd->cmd_type) {
@@ -3357,7 +3357,7 @@
 	rc = vfe_ctrl->stats_ops.enqueue_buf(
 			&vfe_ctrl->stats_ctrl,
 			(struct msm_stats_buf_info *)cmd->value,
-			vfe_ctrl->stats_ops.client);
+			vfe_ctrl->stats_ops.client, domain_num);
 	break;
 	case VFE_CMD_STATS_FLUSH_BUFQ:
 	{
@@ -3419,7 +3419,7 @@
 	case VFE_CMD_STATS_FLUSH_BUFQ:
 		/* for easy porting put in one envelope */
 		rc = vfe_stats_bufq_sub_ioctl(vfe40_ctrl,
-				cmd, vfe_params->data);
+				cmd, vfe_params->data, pmctl->domain_num);
 		return rc;
 	default:
 		if (cmd->cmd_type != CMD_CONFIG_PING_ADDR &&
diff --git a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
index 460eb07..75d9293 100644
--- a/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
+++ b/drivers/media/video/msm/vfe/msm_vfe7x27a_v4l2.c
@@ -395,7 +395,7 @@
 		stats_buf = &bufq->bufs[i];
 		rc = vfe2x_ctrl->stats_ops.enqueue_buf(
 				vfe2x_ctrl->stats_ops.stats_ctrl,
-				&(stats_buf->info), NULL);
+				&(stats_buf->info), NULL, -1);
 			if (rc < 0) {
 				pr_err("%s: dq stats buf (type = %d) err = %d",
 					 __func__, stats_type, rc);
@@ -414,7 +414,7 @@
 		rc = vfe2x_ctrl->stats_ops.buf_unprepare(
 			vfe2x_ctrl->stats_ops.stats_ctrl,
 			req_buf->stats_type, i,
-			vfe2x_ctrl->stats_ops.client);
+			vfe2x_ctrl->stats_ops.client, -1);
 		if (rc < 0) {
 			pr_err("%s: unreg stats buf (type = %d) err = %d",
 				__func__, req_buf->stats_type, rc);
@@ -473,7 +473,7 @@
 		stats_buf->state == MSM_STATS_BUFFER_STATE_PREPARED) {
 		rc = vfe2x_ctrl->stats_ops.enqueue_buf(
 				&vfe2x_ctrl->stats_ctrl,
-				info, vfe2x_ctrl->stats_ops.client);
+				info, vfe2x_ctrl->stats_ops.client, -1);
 		if (rc < 0) {
 			pr_err("%s: enqueue_buf (type = %d), index : %d, err = %d",
 				 __func__, info->type, info->buf_idx, rc);
@@ -555,7 +555,7 @@
 		rc = vfe2x_ctrl->stats_ops.enqueue_buf(
 				&vfe2x_ctrl->stats_ctrl,
 				(struct msm_stats_buf_info *)cmd->value,
-				vfe2x_ctrl->stats_ops.client);
+				vfe2x_ctrl->stats_ops.client, -1);
 	}
 	break;
 	case VFE_CMD_STATS_FLUSH_BUFQ: {
@@ -2352,7 +2352,7 @@
 	return 0;
 }
 
-void msm_vpe_subdev_release(void)
+void msm_vpe_subdev_release(struct v4l2_subdev *sd)
 {
 	return;
 }
diff --git a/drivers/media/video/msm/vfe/msm_vfe_stats_buf.c b/drivers/media/video/msm/vfe/msm_vfe_stats_buf.c
index 5fbcdb1..5820d76 100644
--- a/drivers/media/video/msm/vfe/msm_vfe_stats_buf.c
+++ b/drivers/media/video/msm/vfe/msm_vfe_stats_buf.c
@@ -182,7 +182,8 @@
 #endif
 
 static int msm_stats_buf_prepare(struct msm_stats_bufq_ctrl *stats_ctrl,
-	struct msm_stats_buf_info *info, struct ion_client *client)
+	struct msm_stats_buf_info *info, struct ion_client *client,
+	int domain_num)
 {
 	unsigned long paddr;
 #ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
@@ -219,7 +220,7 @@
 		goto out1;
 	}
 	if (ion_map_iommu(client, stats_buf->handle,
-			CAMERA_DOMAIN, GEN_POOL, SZ_4K,
+			domain_num, 0, SZ_4K,
 			0, &paddr, &len, UNCACHED, 0) < 0) {
 		rc = -EINVAL;
 		pr_err("%s: cannot map address", __func__);
@@ -257,7 +258,7 @@
 	return 0;
 out3:
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_unmap_iommu(client, stats_buf->handle, CAMERA_DOMAIN, GEN_POOL);
+	ion_unmap_iommu(client, stats_buf->handle, domain_num, 0);
 #endif
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 out2:
@@ -270,7 +271,7 @@
 }
 static int msm_stats_buf_unprepare(struct msm_stats_bufq_ctrl *stats_ctrl,
 	enum msm_stats_enum_type stats_type, int buf_idx,
-	struct ion_client *client)
+	struct ion_client *client, int domain_num)
 {
 	int rc = 0;
 	struct msm_stats_bufq *bufq = NULL;
@@ -292,7 +293,7 @@
 	}
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 	ion_unmap_iommu(client, stats_buf->handle,
-					CAMERA_DOMAIN, GEN_POOL);
+					domain_num, 0);
 	ion_free(client, stats_buf->handle);
 #else
 	put_pmem_file(stats_buf->file);
@@ -472,12 +473,13 @@
 	return rc;
 }
 static int msm_stats_enqueue_buf(struct msm_stats_bufq_ctrl *stats_ctrl,
-	struct msm_stats_buf_info *info, struct ion_client *client)
+	struct msm_stats_buf_info *info, struct ion_client *client,
+	int domain_num)
 {
 	int rc = 0;
 	D("%s: stats type : %d, idx : %d\n", __func__,
 		info->type, info->buf_idx);
-	rc = msm_stats_buf_prepare(stats_ctrl, info, client);
+	rc = msm_stats_buf_prepare(stats_ctrl, info, client, domain_num);
 	if (rc < 0) {
 		pr_err("%s: buf_prepare failed, rc = %d", __func__, rc);
 		return -EINVAL;
diff --git a/drivers/media/video/msm/vfe/msm_vfe_stats_buf.h b/drivers/media/video/msm/vfe/msm_vfe_stats_buf.h
index 18fd425..bf3e70e 100644
--- a/drivers/media/video/msm/vfe/msm_vfe_stats_buf.h
+++ b/drivers/media/video/msm/vfe/msm_vfe_stats_buf.h
@@ -55,8 +55,8 @@
 	struct msm_stats_bufq_ctrl *stats_ctrl;
 	struct ion_client *client;
 	int (*enqueue_buf) (struct msm_stats_bufq_ctrl *stats_ctrl,
-						struct msm_stats_buf_info *info,
-						struct ion_client *client);
+				struct msm_stats_buf_info *info,
+				struct ion_client *client, int domain_num);
 	int (*qbuf) (struct msm_stats_bufq_ctrl *stats_ctrl,
 				 enum msm_stats_enum_type stats_type,
 				 int buf_idx);
@@ -69,10 +69,10 @@
 	int (*buf_unprepare) (struct msm_stats_bufq_ctrl *stats_ctrl,
 		enum msm_stats_enum_type stats_type,
 		int buf_idx,
-		struct ion_client *client);
+		struct ion_client *client, int domain_num);
 	int (*buf_prepare) (struct msm_stats_bufq_ctrl *stats_ctrl,
-						struct msm_stats_buf_info *info,
-						struct ion_client *client);
+				struct msm_stats_buf_info *info,
+				struct ion_client *client, int domain_num);
 	int (*reqbuf) (struct msm_stats_bufq_ctrl *stats_ctrl,
 				   struct msm_stats_reqbuf *reqbuf,
 				   struct ion_client *client);
diff --git a/drivers/media/video/msm_vidc/msm_smem.c b/drivers/media/video/msm_vidc/msm_smem.c
index d48240a..16fb14d 100644
--- a/drivers/media/video/msm_vidc/msm_smem.c
+++ b/drivers/media/video/msm_vidc/msm_smem.c
@@ -81,12 +81,11 @@
 		goto fail_device_address;
 	}
 
-	mem->kvaddr += offset;
 	mem->mem_type = client->mem_type;
 	mem->smem_priv = hndl;
-	mem->device_addr = iova + offset;
+	mem->device_addr = iova;
 	mem->size = buffer_size;
-	pr_debug("Buffer device address: 0x%lx, size: %d\n",
+	pr_err("NOTE: Buffer device address: 0x%lx, size: %d\n",
 		mem->device_addr, mem->size);
 	return rc;
 fail_device_address:
@@ -145,8 +144,8 @@
 		goto fail_device_address;
 	}
 	mem->device_addr = iova;
-	pr_debug("device_address = 0x%lx, kvaddr = 0x%p\n",
-		mem->device_addr, mem->kvaddr);
+	pr_err("NOTE: device_address = 0x%lx, kvaddr = 0x%p, size = %d\n",
+		mem->device_addr, mem->kvaddr, size);
 	mem->size = size;
 	return rc;
 fail_device_address:
diff --git a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
index bab7642..4e810dc 100644
--- a/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
+++ b/drivers/media/video/msm_vidc/msm_v4l2_vidc.c
@@ -165,6 +165,7 @@
 	int buff_off;
 	int size;
 	u32 uvaddr;
+	u32 device_addr;
 	struct msm_smem *handle;
 };
 
@@ -230,6 +231,28 @@
 	return ret;
 }
 
+struct buffer_info *get_same_fd_buffer(struct list_head *list,
+		int fd)
+{
+	struct buffer_info *temp;
+	struct buffer_info *ret = NULL;
+	if (!list || fd < 0) {
+		pr_err("%s Invalid input\n", __func__);
+		goto err_invalid_input;
+	}
+	if (!list_empty(list)) {
+		list_for_each_entry(temp, list, list) {
+			if (temp && temp->fd == fd)  {
+				pr_err("Found same fd buffer\n");
+				ret = temp;
+				break;
+			}
+		}
+	}
+err_invalid_input:
+	return ret;
+}
+
 static int msm_v4l2_open(struct file *filp)
 {
 	int rc = 0;
@@ -362,8 +385,9 @@
 				rc = msm_vidc_release_buf(&v4l2_inst->vidc_inst,
 					&buffer_info);
 				list_del(&bi->list);
-				msm_smem_free(v4l2_inst->mem_client,
-					bi->handle);
+				if (bi->handle)
+					msm_smem_free(v4l2_inst->mem_client,
+							bi->handle);
 				kfree(bi);
 			}
 		}
@@ -374,8 +398,9 @@
 int msm_v4l2_prepare_buf(struct file *file, void *fh,
 				struct v4l2_buffer *b)
 {
-	struct msm_smem *handle;
+	struct msm_smem *handle = NULL;
 	struct buffer_info *binfo;
+	struct buffer_info *temp;
 	struct msm_vidc_inst *vidc_inst;
 	struct msm_v4l2_vid_inst *v4l2_inst;
 	int i, rc = 0;
@@ -402,28 +427,43 @@
 			rc = -ENOMEM;
 			goto exit;
 		}
-		handle = msm_smem_user_to_kernel(v4l2_inst->mem_client,
+		temp = get_same_fd_buffer(&v4l2_inst->registered_bufs,
+				b->m.planes[i].reserved[0]);
+		if (temp) {
+			binfo->type = b->type;
+			binfo->fd = b->m.planes[i].reserved[0];
+			binfo->buff_off = b->m.planes[i].reserved[1];
+			binfo->size = b->m.planes[i].length;
+			binfo->uvaddr = b->m.planes[i].m.userptr;
+			binfo->device_addr =
+				temp->handle->device_addr + binfo->buff_off;
+			binfo->handle = NULL;
+		} else {
+			handle = msm_smem_user_to_kernel(v4l2_inst->mem_client,
 			b->m.planes[i].reserved[0],
 			b->m.planes[i].reserved[1],
 			vidc_inst->core->resources.io_map[NS_MAP].domain,
 			0);
-		if (!handle) {
-			pr_err("Failed to get device buffer address\n");
-			kfree(binfo);
-			goto exit;
+			if (!handle) {
+				pr_err("Failed to get device buffer address\n");
+				kfree(binfo);
+				goto exit;
+			}
+			binfo->type = b->type;
+			binfo->fd = b->m.planes[i].reserved[0];
+			binfo->buff_off = b->m.planes[i].reserved[1];
+			binfo->size = b->m.planes[i].length;
+			binfo->uvaddr = b->m.planes[i].m.userptr;
+			binfo->device_addr =
+				handle->device_addr + binfo->buff_off;
+			binfo->handle = handle;
+			pr_debug("Registering buffer: %d, %d, %d\n",
+					b->m.planes[i].reserved[0],
+					b->m.planes[i].reserved[1],
+					b->m.planes[i].length);
 		}
-		binfo->type = b->type;
-		binfo->fd = b->m.planes[i].reserved[0];
-		binfo->buff_off = b->m.planes[i].reserved[1];
-		binfo->size = b->m.planes[i].length;
-		binfo->uvaddr = b->m.planes[i].m.userptr;
-		binfo->handle = handle;
-		pr_debug("Registering buffer: %d, %d, %d\n",
-				b->m.planes[i].reserved[0],
-				b->m.planes[i].reserved[1],
-				b->m.planes[i].length);
 		list_add_tail(&binfo->list, &v4l2_inst->registered_bufs);
-		b->m.planes[i].m.userptr = handle->device_addr;
+		b->m.planes[i].m.userptr = binfo->device_addr;
 	}
 	rc = msm_vidc_prepare_buf(&v4l2_inst->vidc_inst, b);
 exit:
@@ -453,14 +493,16 @@
 			rc = -EINVAL;
 			goto err_invalid_buff;
 		}
-		b->m.planes[i].m.userptr = binfo->handle->device_addr;
-		pr_debug("Queueing device address = %ld\n",
-				binfo->handle->device_addr);
-		rc = msm_smem_clean_invalidate(v4l2_inst->mem_client,
-				binfo->handle);
-		if (rc) {
-			pr_err("Failed to clean caches: %d\n", rc);
-			goto err_invalid_buff;
+		b->m.planes[i].m.userptr = binfo->device_addr;
+		pr_debug("Queueing device address = 0x%x\n",
+				binfo->device_addr);
+		if (binfo->handle) {
+			rc = msm_smem_clean_invalidate(v4l2_inst->mem_client,
+					binfo->handle);
+			if (rc) {
+				pr_err("Failed to clean caches: %d\n", rc);
+				goto err_invalid_buff;
+			}
 		}
 	}
 	rc = msm_vidc_qbuf(&v4l2_inst->vidc_inst, b);
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index ffa873f..7f83625 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -469,8 +469,8 @@
 		return -EINVAL;
 	}
 	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-		inst->prop.width = f->fmt.pix_mp.width;
-		inst->prop.height = f->fmt.pix_mp.height;
+		struct hal_frame_size frame_sz;
+
 		fmt = msm_comm_get_pixel_fmt_fourcc(vdec_formats,
 			ARRAY_SIZE(vdec_formats), f->fmt.pix_mp.pixelformat,
 			CAPTURE_PORT);
@@ -480,6 +480,21 @@
 			rc = -EINVAL;
 			goto err_invalid_fmt;
 		}
+
+		inst->prop.width = f->fmt.pix_mp.width;
+		inst->prop.height = f->fmt.pix_mp.height;
+
+		frame_sz.buffer_type = HAL_BUFFER_OUTPUT;
+		frame_sz.width = inst->prop.width;
+		frame_sz.height = inst->prop.height;
+		pr_debug("width = %d, height = %d\n",
+				frame_sz.width, frame_sz.height);
+		rc = vidc_hal_session_set_property((void *)inst->session,
+				HAL_PARAM_FRAME_SIZE, &frame_sz);
+		if (rc) {
+			pr_err("Failed to set hal property for framesize\n");
+			goto err_invalid_fmt;
+		}
 	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		fmt = msm_comm_get_pixel_fmt_fourcc(vdec_formats,
 			ARRAY_SIZE(vdec_formats), f->fmt.pix_mp.pixelformat,
@@ -570,7 +585,6 @@
 {
 	int i, rc = 0;
 	struct msm_vidc_inst *inst;
-	struct hal_frame_size frame_sz;
 	unsigned long flags;
 	if (!q || !q->drv_priv) {
 		pr_err("Invalid input, q = %p\n", q);
@@ -595,27 +609,42 @@
 			pr_err("Failed to open instance\n");
 			break;
 		}
-		frame_sz.buffer_type = HAL_BUFFER_OUTPUT;
-		frame_sz.width = inst->prop.width;
-		frame_sz.height = inst->prop.height;
-		pr_debug("width = %d, height = %d\n",
-				frame_sz.width, frame_sz.height);
-		rc = vidc_hal_session_set_property((void *)inst->session,
-				HAL_PARAM_FRAME_SIZE, &frame_sz);
-		if (rc) {
-			pr_err("Failed to set hal property for framesize\n");
-			break;
-		}
+
 		rc = msm_comm_try_get_bufreqs(inst);
 		if (rc) {
 			pr_err("Failed to get buffer requirements: %d\n", rc);
 			break;
 		}
 		*num_planes = 1;
+
 		spin_lock_irqsave(&inst->lock, flags);
-		*num_buffers = inst->buff_req.buffer[1].buffer_count_actual;
+		if (*num_buffers && *num_buffers >
+			inst->buff_req.buffer[HAL_BUFFER_OUTPUT].
+				buffer_count_actual) {
+			struct hal_buffer_count_actual new_buf_count;
+			enum hal_property property_id =
+				HAL_PARAM_BUFFER_COUNT_ACTUAL;
+
+			new_buf_count.buffer_type = HAL_BUFFER_OUTPUT;
+			new_buf_count.buffer_count_actual = *num_buffers;
+			rc = vidc_hal_session_set_property(inst->session,
+					property_id, &new_buf_count);
+
+			spin_unlock_irqrestore(&inst->lock, flags);
+			if (!rc && msm_comm_try_get_bufreqs(inst)) {
+				/* We are allowed to reject clients' request for
+				 * more buffers and suggest our own bufreq */
+				pr_warn("Unable to increase the number of output buffers to %d\n",
+						*num_buffers);
+			}
+			spin_lock_irqsave(&inst->lock, flags);
+		}
+		*num_buffers = inst->buff_req.buffer[HAL_BUFFER_OUTPUT].
+							buffer_count_actual;
 		spin_unlock_irqrestore(&inst->lock, flags);
-		pr_debug("size = %d, alignment = %d\n",
+
+		pr_debug("count =  %d, size = %d, alignment = %d\n",
+				inst->buff_req.buffer[1].buffer_count_actual,
 				inst->buff_req.buffer[1].buffer_size,
 				inst->buff_req.buffer[1].buffer_alignment);
 		for (i = 0; i < *num_planes; i++) {
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index d69ed53..0d62ccc 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -430,6 +430,7 @@
 	struct msm_vidc_cb_cmd_done *response = data;
 	struct msm_vidc_inst *inst;
 	unsigned long flags;
+	int i;
 	if (!response || !response->data) {
 		pr_err("Failed to get valid response for prop info\n");
 		return;
@@ -439,6 +440,12 @@
 	memcpy(&inst->buff_req, response->data,
 			sizeof(struct buffer_requirements));
 	spin_unlock_irqrestore(&inst->lock, flags);
+	for (i = 0; i < 8; i++) {
+		pr_err("NOTE: buffer type: %d, count : %d, size: %d\n",
+			inst->buff_req.buffer[i].buffer_type,
+			inst->buff_req.buffer[i].buffer_count_actual,
+			inst->buff_req.buffer[i].buffer_size);
+	}
 	signal_session_msg_receipt(cmd, inst);
 }
 
diff --git a/drivers/media/video/vcap_vp.c b/drivers/media/video/vcap_vp.c
index 9f2ead4..ba053f2 100644
--- a/drivers/media/video/vcap_vp.c
+++ b/drivers/media/video/vcap_vp.c
@@ -320,7 +320,7 @@
 	}
 
 	dprintk(1, "%s: irq=0x%08x\n", __func__, irq);
-	if (!(irq & (VP_PIC_DONE || VP_MODE_CHANGE))) {
+	if (!(irq & (VP_PIC_DONE | VP_MODE_CHANGE))) {
 		writel_relaxed(irq, VCAP_VP_INT_CLEAR);
 		pr_err("VP IRQ shows some error\n");
 		return IRQ_HANDLED;
@@ -789,7 +789,7 @@
 		top_field = 1;
 #endif
 	vp_act->vp_state = VP_FRAME2;
-	writel_relaxed(0x01100101, VCAP_VP_INTERRUPT_ENABLE);
+	writel_relaxed(0x01100001, VCAP_VP_INTERRUPT_ENABLE);
 #ifdef TOP_FIELD_FIX
 	writel_iowmb(0x00000000 | vp_act->top_field << 0, VCAP_VP_CTRL);
 	writel_iowmb(0x00010000 | vp_act->top_field << 0, VCAP_VP_CTRL);
@@ -836,7 +836,7 @@
 #endif
 
 	/* Config VP & Enable Interrupt */
-	writel_relaxed(0x01100101, VCAP_VP_INTERRUPT_ENABLE);
+	writel_relaxed(0x01100001, VCAP_VP_INTERRUPT_ENABLE);
 #ifdef TOP_FIELD_FIX
 	writel_iowmb(0x00000000 | vp_act->top_field << 0, VCAP_VP_CTRL);
 	writel_iowmb(0x00010000 | vp_act->top_field << 0, VCAP_VP_CTRL);
diff --git a/drivers/media/video/videobuf2-msm-mem.c b/drivers/media/video/videobuf2-msm-mem.c
index 740d183..c1a392e2 100644
--- a/drivers/media/video/videobuf2-msm-mem.c
+++ b/drivers/media/video/videobuf2-msm-mem.c
@@ -62,7 +62,7 @@
 		goto alloc_failed;
 	}
 	rc = ion_map_iommu(mem->client, mem->ion_handle,
-			CAMERA_DOMAIN, GEN_POOL, SZ_4K, 0,
+			-1, 0, SZ_4K, 0,
 			(unsigned long *)&phyaddr,
 			(unsigned long *)&len, UNCACHED, 0);
 	if (rc < 0) {
@@ -87,7 +87,7 @@
 {
 	int32_t rc = 0;
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	ion_unmap_iommu(mem->client, mem->ion_handle, CAMERA_DOMAIN, GEN_POOL);
+	ion_unmap_iommu(mem->client, mem->ion_handle, -1, 0);
 	ion_free(mem->client, mem->ion_handle);
 	ion_client_destroy(mem->client);
 #else
@@ -174,7 +174,8 @@
 					struct videobuf2_msm_offset *offset,
 					enum videobuf2_buffer_type buffer_type,
 					uint32_t addr_offset, int path,
-					struct ion_client *client)
+					struct ion_client *client,
+					int domain_num)
 {
 	unsigned long len;
 	int rc = 0;
@@ -190,7 +191,7 @@
 		pr_err("%s ION import failed\n", __func__);
 		return PTR_ERR(mem->ion_handle);
 	}
-	rc = ion_map_iommu(client, mem->ion_handle, CAMERA_DOMAIN, GEN_POOL,
+	rc = ion_map_iommu(client, mem->ion_handle, domain_num, 0,
 		SZ_4K, 0, (unsigned long *)&mem->phyaddr, &len, UNCACHED, 0);
 	if (rc < 0)
 		ion_free(client, mem->ion_handle);
@@ -220,12 +221,12 @@
 EXPORT_SYMBOL_GPL(videobuf2_pmem_contig_user_get);
 
 void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem,
-					struct ion_client *client)
+				struct ion_client *client, int domain_num)
 {
 	if (mem->is_userptr) {
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 		ion_unmap_iommu(client, mem->ion_handle,
-				CAMERA_DOMAIN, GEN_POOL);
+				domain_num, 0);
 		ion_free(client, mem->ion_handle);
 #elif CONFIG_ANDROID_PMEM
 		put_pmem_file(mem->file);
diff --git a/drivers/mfd/wcd9xxx-slimslave.c b/drivers/mfd/wcd9xxx-slimslave.c
index 71c68ac..b4cf435 100644
--- a/drivers/mfd/wcd9xxx-slimslave.c
+++ b/drivers/mfd/wcd9xxx-slimslave.c
@@ -535,7 +535,6 @@
 				unsigned int ch_cnt)
 {
 	u16 grph = 0;
-	u32 sph[SLIM_MAX_RX_PORTS] = {0};
 	int i = 0 , idx = 0;
 	int ret = 0;
 	struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx;
@@ -549,10 +548,9 @@
 			ret = -EINVAL;
 			goto err;
 		}
-		sph[i] = rx[idx].sph;
 		grph = rx[idx].grph;
-		pr_debug("%s: ch_num[%d] %d, idx %d, sph[%d] %x, grph %x\n",
-			 __func__, i, ch_num[i], idx, i, sph[i], grph);
+		pr_debug("%s: ch_num[%d] %d, idx %d, grph %x\n",
+			 __func__, i, ch_num[i], idx, grph);
 	}
 
 	/* slim_control_ch (REMOVE) */
@@ -561,12 +559,6 @@
 		pr_err("%s: slim_control_ch failed ret[%d]\n", __func__, ret);
 		goto err;
 	}
-	/* slim_disconnect_port */
-	ret = slim_disconnect_ports(wcd9xxx->slim, sph, ch_cnt);
-	if (ret < 0) {
-		pr_err("%s: slim_disconnect_ports failed ret[%d]\n",
-			 __func__, ret);
-	}
 	for (i = 0; i < ch_cnt; i++) {
 		idx = (ch_num[i] - BASE_CH_NUM - sh_ch.rx_port_start_offset);
 		rx[idx].grph = 0;
@@ -580,7 +572,6 @@
 			      unsigned int ch_cnt)
 {
 	u16 grph = 0;
-	u32 sph[SLIM_MAX_TX_PORTS] = {0};
 	int ret = 0;
 	int i = 0 , idx = 0;
 	struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx;
@@ -594,15 +585,8 @@
 			ret = -EINVAL;
 			goto err;
 		}
-		sph[i] = tx[idx].sph;
 		grph = tx[idx].grph;
 	}
-	/* slim_disconnect_port */
-	ret = slim_disconnect_ports(wcd9xxx->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(wcd9xxx->slim, grph, SLIM_CH_REMOVE, true);
 	if (ret < 0) {
@@ -633,3 +617,48 @@
 	return ret;
 }
 EXPORT_SYMBOL_GPL(wcd9xxx_get_slave_port);
+
+int wcd9xxx_disconnect_port(struct wcd9xxx *wcd9xxx, unsigned int *ch_num,
+				unsigned int ch_cnt, unsigned int rx_tx)
+{
+	u32 sph[SLIM_MAX_TX_PORTS] = {0};
+	int i = 0 , idx = 0;
+	int ret = 0;
+	struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx;
+	struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx;
+
+	pr_debug("%s: ch_cnt[%d], rx_tx flag = %d\n", __func__, ch_cnt, rx_tx);
+	for (i = 0; i < ch_cnt; i++) {
+		/* rx_tx will be 1 for rx, 0 for tx */
+		if (rx_tx) {
+			idx = (ch_num[i] - BASE_CH_NUM -
+				sh_ch.rx_port_start_offset);
+			if (idx < 0) {
+				pr_err("%s: Invalid index found for RX = %d\n",
+					__func__, idx);
+				ret = -EINVAL;
+				goto err;
+			}
+			sph[i] = rx[idx].sph;
+		} else {
+			idx = (ch_num[i] - BASE_CH_NUM);
+			if (idx < 0) {
+				pr_err("%s:Invalid index found for TX = %d\n",
+					__func__, idx);
+				ret = -EINVAL;
+				goto err;
+			}
+			sph[i] = tx[idx].sph;
+		}
+	}
+
+	/* slim_disconnect_port */
+	ret = slim_disconnect_ports(wcd9xxx->slim, sph, ch_cnt);
+	if (ret < 0) {
+		pr_err("%s: slim_disconnect_ports failed ret[%d]\n",
+			__func__, ret);
+	}
+err:
+	return ret;
+}
+EXPORT_SYMBOL_GPL(wcd9xxx_disconnect_port);
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 590aa58..d82c353 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -409,7 +409,6 @@
 	if (index == EXT_CSD_BKOPS_START)
 		return 0;
 
-	mmc_delay(1);
 	/* Must check status to be sure of no errors */
 	do {
 		err = mmc_send_status(card, &status);
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index b8db530..cd97701 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -3358,6 +3358,9 @@
 {
 	struct device *dev = mmc_dev(host->mmc);
 
+	pr_info("%s: PM: sdcc_suspended=%d, pending_resume=%d, sdcc_suspending=%d\n",
+		mmc_hostname(host->mmc), host->sdcc_suspended,
+		host->pending_resume, host->sdcc_suspending);
 	pr_info("%s: RPM: runtime_status=%d, usage_count=%d,"
 		" is_suspended=%d, disable_depth=%d, runtime_error=%d,"
 		" request_pending=%d, request=%d\n",
@@ -3379,8 +3382,7 @@
 	if (mmc->card && mmc_card_sdio(mmc->card))
 		goto out;
 
-	if (host->sdcc_suspended && host->pending_resume &&
-			!pm_runtime_suspended(dev)) {
+	if (host->sdcc_suspended && host->pending_resume) {
 		host->pending_resume = false;
 		pm_runtime_get_noresume(dev);
 		rc = msmsdcc_runtime_resume(dev);
@@ -3401,8 +3403,8 @@
 
 skip_get_sync:
 	if (rc < 0) {
-		pr_info("%s: %s: failed with error %d", mmc_hostname(mmc),
-				__func__, rc);
+		WARN(1, "%s: %s: failed with error %d\n", mmc_hostname(mmc),
+		     __func__, rc);
 		msmsdcc_print_rpm_info(host);
 		return rc;
 	}
@@ -3428,15 +3430,9 @@
 
 	rc = pm_runtime_put_sync(mmc->parent);
 
-	/*
-	 * Ignore -EAGAIN as that is not fatal, it means that
-	 * either runtime usage count is non-zero or the runtime
-	 * pm itself is disabled or not in proper state to process
-	 * idle notification.
-	 */
-	if (rc < 0 && (rc != -EAGAIN)) {
-		pr_info("%s: %s: failed with error %d", mmc_hostname(mmc),
-				__func__, rc);
+	if (rc < 0) {
+		WARN(1, "%s: %s: failed with error %d\n", mmc_hostname(mmc),
+		     __func__, rc);
 		msmsdcc_print_rpm_info(host);
 		return rc;
 	}
@@ -6324,6 +6320,7 @@
 
 		wake_unlock(&host->sdio_suspend_wlock);
 	}
+	host->pending_resume = false;
 	pr_debug("%s: %s: end\n", mmc_hostname(mmc), __func__);
 	return 0;
 }
@@ -6396,7 +6393,13 @@
 
 	if (mmc->card && mmc_card_sdio(mmc->card))
 		rc = msmsdcc_runtime_resume(dev);
-	else
+	/*
+	 * As runtime PM is enabled before calling the device's platform resume
+	 * callback, we use the pm_runtime_suspended API to know if SDCC is
+	 * really runtime suspended or not and set the pending_resume flag only
+	 * if its not runtime suspended.
+	 */
+	else if (!pm_runtime_suspended(dev))
 		host->pending_resume = true;
 
 	if (host->plat->status_irq) {
diff --git a/drivers/platform/msm/sps/bam.c b/drivers/platform/msm/sps/bam.c
index 2873a5f..7924578 100644
--- a/drivers/platform/msm/sps/bam.c
+++ b/drivers/platform/msm/sps/bam.c
@@ -643,10 +643,10 @@
  */
 int bam_init(void *base, u32 ee,
 		u16 summing_threshold,
-		u32 irq_mask, u32 *version, u32 *num_pipes)
+		u32 irq_mask, u32 *version,
+		u32 *num_pipes, u32 p_rst)
 {
-	/* disable bit#11 because of HW bug */
-	u32 cfg_bits = 0xffffffff & ~(1 << 11);
+	u32 cfg_bits;
 	u32 ver = 0;
 
 	SPS_DBG2("sps:%s:bam=0x%x(va).ee=%d.", __func__, (u32) base, ee);
@@ -667,6 +667,11 @@
 				"use default 4.\n", (u32) base);
 	}
 
+	if (p_rst)
+		cfg_bits = 0xffffffff & ~(3 << 11);
+	else
+		cfg_bits = 0xffffffff & ~(1 << 11);
+
 	bam_write_reg_field(base, CTRL, BAM_SW_RST, 1);
 	/* No delay needed */
 	bam_write_reg_field(base, CTRL, BAM_SW_RST, 0);
diff --git a/drivers/platform/msm/sps/bam.h b/drivers/platform/msm/sps/bam.h
index 3521ffa..c183fcd 100644
--- a/drivers/platform/msm/sps/bam.h
+++ b/drivers/platform/msm/sps/bam.h
@@ -102,13 +102,16 @@
  *
  * @num_pipes - return number of pipes
  *
+ * @p_rst - ignore external block pipe reset
+ *
  * @return 0 on success, negative value on error
  *
  */
 int bam_init(void *base,
 		u32 ee,
 		u16 summing_threshold,
-		u32 irq_mask, u32 *version, u32 *num_pipes);
+		u32 irq_mask, u32 *version,
+		u32 *num_pipes, u32 p_rst);
 
 /**
  * Initialize BAM device security execution environment
diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c
index de7fb75..e3be11d 100644
--- a/drivers/platform/msm/sps/sps_bam.c
+++ b/drivers/platform/msm/sps/sps_bam.c
@@ -254,7 +254,8 @@
 				  dev->props.ee,
 				  (u16) dev->props.summing_threshold,
 				  irq_mask,
-				  &dev->version, &num_pipes);
+				  &dev->version, &num_pipes,
+				  dev->props.options & SPS_BAM_NO_EXT_P_RST);
 	else
 		/* No, so just verify that it is enabled */
 		rc = bam_check(dev->base, &dev->version, &num_pipes);
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index f6b50a0..a347984 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -15,6 +15,7 @@
 #include <linux/list.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/stat.h>
 #include <linux/module.h>
@@ -54,11 +55,14 @@
 static struct usb_bam_connect_info usb_bam_connections[CONNECTIONS_NUM];
 static struct usb_bam_pipe_connect ***msm_usb_bam_connections_info;
 static struct usb_bam_pipe_connect *bam_connection_arr;
+void __iomem *qscratch_ram1_reg;
+struct clk *mem_clk;
+struct clk *mem_iface_clk;
 
 static int connect_pipe(u8 conn_idx, enum usb_bam_pipe_dir pipe_dir,
 						u32 *usb_pipe_idx)
 {
-	int ret;
+	int ret, ram1_value;
 	struct sps_pipe **pipe = &sps_pipes[conn_idx][pipe_dir];
 	struct sps_connect *connection =
 		&sps_connections[conn_idx][pipe_dir];
@@ -77,13 +81,13 @@
 	ret = sps_get_config(*pipe, connection);
 	if (ret) {
 		pr_err("%s: tx get config failed %d\n", __func__, ret);
-		goto get_config_failed;
+		goto free_sps_endpoint;
 	}
 
 	ret = sps_phy2h(pipe_connection->src_phy_addr, &(connection->source));
 	if (ret) {
 		pr_err("%s: sps_phy2h failed (src BAM) %d\n", __func__, ret);
-		goto get_config_failed;
+		goto free_sps_endpoint;
 	}
 
 	connection->src_pipe_index = pipe_connection->src_pipe_index;
@@ -91,7 +95,7 @@
 					&(connection->destination));
 	if (ret) {
 		pr_err("%s: sps_phy2h failed (dst BAM) %d\n", __func__, ret);
-		goto get_config_failed;
+		goto free_sps_endpoint;
 	}
 	connection->dest_pipe_index = pipe_connection->dst_pipe_index;
 
@@ -113,7 +117,7 @@
 		if (ret) {
 			pr_err("%s: data fifo setup failure %d\n", __func__,
 				ret);
-			goto fifo_setup_error;
+			goto free_sps_endpoint;
 		}
 
 		ret = sps_setup_bam2bam_fifo(
@@ -123,11 +127,33 @@
 		if (ret) {
 			pr_err("%s: desc. fifo setup failure %d\n", __func__,
 				ret);
-			goto fifo_setup_error;
+			goto free_sps_endpoint;
 		}
 	} else if (pipe_connection->mem_type == USB_PRIVATE_MEM) {
 		pr_debug("%s: USB BAM using private memory\n", __func__);
-		/* BAM is using dedicated USB private memory, map it */
+
+		if (IS_ERR(mem_clk) || IS_ERR(mem_iface_clk)) {
+			pr_err("%s: Failed to enable USB mem_clk\n", __func__);
+			ret = IS_ERR(mem_clk);
+			goto free_sps_endpoint;
+		}
+
+		clk_prepare_enable(mem_clk);
+		clk_prepare_enable(mem_iface_clk);
+
+		/*
+		 * Enable USB PRIVATE RAM to be used for BAM FIFOs
+		 * HSUSB: Only RAM13 is used for BAM FIFOs
+		 * SSUSB: RAM11, 12, 13 are used for BAM FIFOs
+		 */
+		if (pdata->usb_active_bam == HSUSB_BAM)
+			ram1_value = 0x4;
+		else
+			ram1_value = 0x7;
+
+		pr_debug("Writing 0x%x to QSCRATCH_RAM1\n", ram1_value);
+		writel_relaxed(ram1_value, qscratch_ram1_reg);
+
 		data_mem_buf[conn_idx][pipe_dir].phys_base =
 			pipe_connection->data_fifo_base_offset +
 				pdata->usb_base_address;
@@ -187,8 +213,7 @@
 
 error:
 	sps_disconnect(*pipe);
-fifo_setup_error:
-get_config_failed:
+free_sps_endpoint:
 	sps_free_endpoint(*pipe);
 	return ret;
 }
@@ -215,6 +240,13 @@
 			  connection->data.base, connection->data.phys_base);
 		dma_free_coherent(&usb_bam_pdev->dev, connection->desc.size,
 			  connection->desc.base, connection->desc.phys_base);
+	} else if (pipe_connection->mem_type == USB_PRIVATE_MEM) {
+		pr_debug("Freeing USB private memory used by BAM PIPE\n");
+		writel_relaxed(0x0, qscratch_ram1_reg);
+		iounmap(connection->data.base);
+		iounmap(connection->desc.base);
+		clk_disable_unprepare(mem_clk);
+		clk_disable_unprepare(mem_iface_clk);
 	}
 
 	connection->options &= ~SPS_O_AUTO_ENABLE;
@@ -597,7 +629,9 @@
 	void *usb_virt_addr;
 	struct msm_usb_bam_platform_data *pdata =
 		usb_bam_pdev->dev.platform_data;
-	struct resource *res;
+	struct usb_bam_pipe_connect *pipe_connection =
+		&msm_usb_bam_connections_info[pdata->usb_active_bam][0][0];
+	struct resource *res, *ram_resource;
 	int irq;
 
 	res = platform_get_resource_byname(usb_bam_pdev, IORESOURCE_MEM,
@@ -614,11 +648,35 @@
 		return irq;
 	}
 
-	usb_virt_addr = ioremap(res->start, resource_size(res));
+	usb_virt_addr = devm_ioremap(&usb_bam_pdev->dev, res->start,
+							 resource_size(res));
 	if (!usb_virt_addr) {
 		pr_err("%s: ioremap failed\n", __func__);
 		return -ENOMEM;
 	}
+
+	/* Check if USB3 pipe memory needs to be enabled */
+	if (pipe_connection->mem_type == USB_PRIVATE_MEM) {
+		pr_debug("%s: Enabling USB private memory for: %s\n", __func__,
+				bam_enable_strings[pdata->usb_active_bam]);
+
+		ram_resource = platform_get_resource_byname(usb_bam_pdev,
+					 IORESOURCE_MEM, "qscratch_ram1_reg");
+		if (!res) {
+			dev_err(&usb_bam_pdev->dev, "Unable to get qscratch\n");
+			ret = -ENODEV;
+			goto free_bam_regs;
+		}
+
+		qscratch_ram1_reg = devm_ioremap(&usb_bam_pdev->dev,
+						ram_resource->start,
+						resource_size(ram_resource));
+		if (!qscratch_ram1_reg) {
+			pr_err("%s: ioremap failed for qscratch\n", __func__);
+			ret = -ENOMEM;
+			goto free_bam_regs;
+		}
+	}
 	usb_props.phys_addr = res->start;
 	usb_props.virt_addr = usb_virt_addr;
 	usb_props.virt_size = resource_size(res);
@@ -630,10 +688,18 @@
 	ret = sps_register_bam_device(&usb_props, &h_usb);
 	if (ret < 0) {
 		pr_err("%s: register bam error %d\n", __func__, ret);
-		return -EFAULT;
+		ret = -EFAULT;
+		goto free_qscratch_reg;
 	}
 
 	return 0;
+
+free_qscratch_reg:
+	iounmap(qscratch_ram1_reg);
+free_bam_regs:
+	iounmap(usb_virt_addr);
+
+	return ret;
 }
 
 static ssize_t
@@ -698,6 +764,14 @@
 			usb_bam_wake_work);
 	}
 
+	mem_clk = devm_clk_get(&pdev->dev, "mem_clk");
+	if (IS_ERR(mem_clk))
+		dev_dbg(&pdev->dev, "failed to get mem_clock\n");
+
+	mem_iface_clk = devm_clk_get(&pdev->dev, "mem_iface_clk");
+	if (IS_ERR(mem_iface_clk))
+		dev_dbg(&pdev->dev, "failed to get mem_iface_clock\n");
+
 	if (pdev->dev.of_node) {
 		dev_dbg(&pdev->dev, "device tree enabled\n");
 		pdata = usb_bam_dt_to_pdata(pdev);
diff --git a/drivers/regulator/qpnp-regulator.c b/drivers/regulator/qpnp-regulator.c
index 0e836c7..44fdbc1 100644
--- a/drivers/regulator/qpnp-regulator.c
+++ b/drivers/regulator/qpnp-regulator.c
@@ -56,7 +56,7 @@
 };
 
 enum qpnp_regulator_type {
-	QPNP_REGULATOR_TYPE_HF_BUCK		= 0x03,
+	QPNP_REGULATOR_TYPE_BUCK		= 0x03,
 	QPNP_REGULATOR_TYPE_LDO			= 0x04,
 	QPNP_REGULATOR_TYPE_VS			= 0x05,
 	QPNP_REGULATOR_TYPE_BOOST		= 0x1B,
@@ -87,6 +87,7 @@
 };
 
 enum qpnp_common_regulator_registers {
+	QPNP_COMMON_REG_DIG_MAJOR_REV		= 0x01,
 	QPNP_COMMON_REG_TYPE			= 0x04,
 	QPNP_COMMON_REG_SUBTYPE			= 0x05,
 	QPNP_COMMON_REG_VOLTAGE_RANGE		= 0x40,
@@ -106,7 +107,7 @@
 };
 
 enum qpnp_boost_registers {
-	QPNP_BOOST_REG_CURRENT_LIMIT		= 0x40,
+	QPNP_BOOST_REG_CURRENT_LIMIT		= 0x4A,
 };
 
 /* Used for indexing into ctrl_reg.  These are offets from 0x40 */
@@ -117,10 +118,6 @@
 	QPNP_COMMON_IDX_ENABLE			= 6,
 };
 
-enum qpnp_boost_control_register_index {
-	QPNP_BOOST_IDX_CURRENT_LIMIT		= 0,
-};
-
 /* Common regulator control register layout */
 #define QPNP_COMMON_ENABLE_MASK			0x80
 #define QPNP_COMMON_ENABLE			0x80
@@ -190,6 +187,8 @@
 	enum qpnp_regulator_type		type;
 	enum qpnp_regulator_subtype		subtype;
 	enum qpnp_regulator_logical_type	logical_type;
+	u32					revision_min;
+	u32					revision_max;
 	struct regulator_ops			*ops;
 	struct qpnp_voltage_set_points		*set_points;
 	int					hpm_min_load;
@@ -213,11 +212,13 @@
 	u8					ctrl_reg[8];
 };
 
-#define QPNP_VREG_MAP(_type, _subtype, _logical_type, _ops_val, \
-		      _set_points_val, _hpm_min_load) \
+#define QPNP_VREG_MAP(_type, _subtype, _dig_major_min, _dig_major_max, \
+		      _logical_type, _ops_val, _set_points_val, _hpm_min_load) \
 	{ \
 		.type		= QPNP_REGULATOR_TYPE_##_type, \
 		.subtype	= QPNP_REGULATOR_SUBTYPE_##_subtype, \
+		.revision_min	= _dig_major_min, \
+		.revision_max	= _dig_major_max, \
 		.logical_type	= QPNP_REGULATOR_LOGICAL_TYPE_##_logical_type, \
 		.ops		= &qpnp_##_ops_val##_ops, \
 		.set_points	= &_set_points_val##_set_points, \
@@ -262,6 +263,10 @@
 	VOLTAGE_RANGE(2,  750000,  775000, 1537500, 12500),
 };
 
+static struct qpnp_voltage_range nldo3_ranges[] = {
+	VOLTAGE_RANGE(0,  375000,  375000, 1537500, 12500),
+};
+
 static struct qpnp_voltage_range smps_ranges[] = {
 	VOLTAGE_RANGE(0,  375000,  375000, 1562500, 12500),
 	VOLTAGE_RANGE(1, 1550000, 1575000, 3125000, 25000),
@@ -281,6 +286,8 @@
 					= SET_POINTS(nldo1_ranges);
 static struct qpnp_voltage_set_points nldo2_set_points
 					= SET_POINTS(nldo2_ranges);
+static struct qpnp_voltage_set_points nldo3_set_points
+					= SET_POINTS(nldo3_ranges);
 static struct qpnp_voltage_set_points smps_set_points = SET_POINTS(smps_ranges);
 static struct qpnp_voltage_set_points ftsmps_set_points
 					= SET_POINTS(ftsmps_ranges);
@@ -292,6 +299,7 @@
 	&pldo_set_points,
 	&nldo1_set_points,
 	&nldo2_set_points,
+	&nldo3_set_points,
 	&smps_set_points,
 	&ftsmps_set_points,
 	&boost_set_points,
@@ -959,24 +967,30 @@
 	.enable_time		= qpnp_regulator_common_enable_time,
 };
 
+/* Maximum possible digital major revision value */
+#define INF 0xFF
+
 static const struct qpnp_regulator_mapping supported_regulators[] = {
-	QPNP_VREG_MAP(HF_BUCK,  GP_CTL,    SMPS,   smps,   smps,   100000),
-	QPNP_VREG_MAP(LDO,      N300,      LDO,    ldo,    nldo1,   10000),
-	QPNP_VREG_MAP(LDO,      N600,      LDO,    ldo,    nldo2,   10000),
-	QPNP_VREG_MAP(LDO,      N1200,     LDO,    ldo,    nldo2,   10000),
-	QPNP_VREG_MAP(LDO,      P50,       LDO,    ldo,    pldo,     5000),
-	QPNP_VREG_MAP(LDO,      P150,      LDO,    ldo,    pldo,    10000),
-	QPNP_VREG_MAP(LDO,      P300,      LDO,    ldo,    pldo,    10000),
-	QPNP_VREG_MAP(LDO,      P600,      LDO,    ldo,    pldo,    10000),
-	QPNP_VREG_MAP(LDO,      P1200,     LDO,    ldo,    pldo,    10000),
-	QPNP_VREG_MAP(VS,       LV100,     VS,     vs,     none,        0),
-	QPNP_VREG_MAP(VS,       LV300,     VS,     vs,     none,        0),
-	QPNP_VREG_MAP(VS,       MV300,     VS,     vs,     none,        0),
-	QPNP_VREG_MAP(VS,       MV500,     VS,     vs,     none,        0),
-	QPNP_VREG_MAP(VS,       HDMI,      VS,     vs,     none,        0),
-	QPNP_VREG_MAP(VS,       OTG,       VS,     vs,     none,        0),
-	QPNP_VREG_MAP(BOOST,    5V_BOOST,  BOOST,  boost,  boost,       0),
-	QPNP_VREG_MAP(FTS,      FTS_CTL,   FTSMPS, ftsmps, ftsmps, 100000),
+	/*           type subtype dig_min dig_max ltype ops setpoints hpm_min */
+	QPNP_VREG_MAP(BUCK,  GP_CTL,   0, INF, SMPS,   smps,   smps,   100000),
+	QPNP_VREG_MAP(LDO,   N300,     0, INF, LDO,    ldo,    nldo1,   10000),
+	QPNP_VREG_MAP(LDO,   N600,     0,   0, LDO,    ldo,    nldo2,   10000),
+	QPNP_VREG_MAP(LDO,   N1200,    0,   0, LDO,    ldo,    nldo2,   10000),
+	QPNP_VREG_MAP(LDO,   N600,     1, INF, LDO,    ldo,    nldo3,   10000),
+	QPNP_VREG_MAP(LDO,   N1200,    1, INF, LDO,    ldo,    nldo3,   10000),
+	QPNP_VREG_MAP(LDO,   P50,      0, INF, LDO,    ldo,    pldo,     5000),
+	QPNP_VREG_MAP(LDO,   P150,     0, INF, LDO,    ldo,    pldo,    10000),
+	QPNP_VREG_MAP(LDO,   P300,     0, INF, LDO,    ldo,    pldo,    10000),
+	QPNP_VREG_MAP(LDO,   P600,     0, INF, LDO,    ldo,    pldo,    10000),
+	QPNP_VREG_MAP(LDO,   P1200,    0, INF, LDO,    ldo,    pldo,    10000),
+	QPNP_VREG_MAP(VS,    LV100,    0, INF, VS,     vs,     none,        0),
+	QPNP_VREG_MAP(VS,    LV300,    0, INF, VS,     vs,     none,        0),
+	QPNP_VREG_MAP(VS,    MV300,    0, INF, VS,     vs,     none,        0),
+	QPNP_VREG_MAP(VS,    MV500,    0, INF, VS,     vs,     none,        0),
+	QPNP_VREG_MAP(VS,    HDMI,     0, INF, VS,     vs,     none,        0),
+	QPNP_VREG_MAP(VS,    OTG,      0, INF, VS,     vs,     none,        0),
+	QPNP_VREG_MAP(BOOST, 5V_BOOST, 0, INF, BOOST,  boost,  boost,       0),
+	QPNP_VREG_MAP(FTS,   FTS_CTL,  0, INF, FTSMPS, ftsmps, ftsmps, 100000),
 };
 
 static int qpnp_regulator_match(struct qpnp_regulator *vreg)
@@ -984,29 +998,39 @@
 	const struct qpnp_regulator_mapping *mapping;
 	struct device_node *node = vreg->spmi_dev->dev.of_node;
 	int rc, i;
-	u8 raw_type[2], type, subtype;
-	u32 type_reg[2];
+	u32 type_reg[2], dig_major_rev;
+	u8 version[QPNP_COMMON_REG_SUBTYPE - QPNP_COMMON_REG_DIG_MAJOR_REV + 1];
+	u8 type, subtype;
 
-	rc = of_property_read_u32_array(node, "qcom,force-type",
-								type_reg, 2);
+	rc = qpnp_vreg_read(vreg, QPNP_COMMON_REG_DIG_MAJOR_REV, version,
+		ARRAY_SIZE(version));
+	if (rc) {
+		vreg_err(vreg, "could not read version registers, rc=%d\n", rc);
+		return rc;
+	}
+	dig_major_rev	= version[QPNP_COMMON_REG_DIG_MAJOR_REV
+					- QPNP_COMMON_REG_DIG_MAJOR_REV];
+	type		= version[QPNP_COMMON_REG_TYPE
+					- QPNP_COMMON_REG_DIG_MAJOR_REV];
+	subtype		= version[QPNP_COMMON_REG_SUBTYPE
+					- QPNP_COMMON_REG_DIG_MAJOR_REV];
+
+	/*
+	 * Override type and subtype register values if qcom,force-type is
+	 * present in the device tree node.
+	 */
+	rc = of_property_read_u32_array(node, "qcom,force-type", type_reg, 2);
 	if (!rc) {
 		type = type_reg[0];
 		subtype = type_reg[1];
-	} else {
-		rc = qpnp_vreg_read(vreg, QPNP_COMMON_REG_TYPE, raw_type, 2);
-		if (rc) {
-			vreg_err(vreg,
-				"could not read type register, rc=%d\n", rc);
-			return rc;
-		}
-		type = raw_type[0];
-		subtype = raw_type[1];
 	}
 
 	rc = -ENODEV;
 	for (i = 0; i < ARRAY_SIZE(supported_regulators); i++) {
 		mapping = &supported_regulators[i];
-		if (mapping->type == type && mapping->subtype == subtype) {
+		if (mapping->type == type && mapping->subtype == subtype
+		    && mapping->revision_min <= dig_major_rev
+		    && mapping->revision_max >= dig_major_rev) {
 			vreg->logical_type	= mapping->logical_type;
 			vreg->set_points	= mapping->set_points;
 			vreg->hpm_min_load	= mapping->hpm_min_load;
@@ -1096,10 +1120,14 @@
 	if (type == QPNP_REGULATOR_LOGICAL_TYPE_BOOST
 		&& pdata->boost_current_limit
 			!= QPNP_BOOST_CURRENT_LIMIT_HW_DEFAULT) {
-		ctrl_reg[QPNP_BOOST_IDX_CURRENT_LIMIT] &=
-			~QPNP_BOOST_CURRENT_LIMIT_MASK;
-		ctrl_reg[QPNP_BOOST_IDX_CURRENT_LIMIT] |=
-		     pdata->boost_current_limit & QPNP_BOOST_CURRENT_LIMIT_MASK;
+		reg = pdata->boost_current_limit;
+		mask = QPNP_BOOST_CURRENT_LIMIT_MASK;
+		rc = qpnp_vreg_masked_read_write(vreg,
+			QPNP_BOOST_REG_CURRENT_LIMIT, reg, mask);
+		if (rc) {
+			vreg_err(vreg, "spmi write failed, rc=%d\n", rc);
+			return rc;
+		}
 	}
 
 	/* Write back any control register values that were modified. */
diff --git a/drivers/usb/gadget/f_adb.c b/drivers/usb/gadget/f_adb.c
index b997a3f..9778673 100644
--- a/drivers/usb/gadget/f_adb.c
+++ b/drivers/usb/gadget/f_adb.c
@@ -48,7 +48,6 @@
 	atomic_t read_excl;
 	atomic_t write_excl;
 	atomic_t open_excl;
-	struct delayed_work adb_release_w;
 
 	struct list_head tx_idle;
 
@@ -410,11 +409,6 @@
 	return r;
 }
 
-static void adb_release_work(struct work_struct *w)
-{
-	adb_closed_callback();
-}
-
 static int adb_open(struct inode *ip, struct file *fp)
 {
 	pr_info("adb_open\n");
@@ -429,8 +423,7 @@
 	/* clear the error latch */
 	atomic_set(&_adb_dev->error, 0);
 
-	if (!cancel_delayed_work_sync(&_adb_dev->adb_release_w))
-		adb_ready_callback();
+	adb_ready_callback();
 
 	return 0;
 }
@@ -439,16 +432,7 @@
 {
 	pr_info("adb_release\n");
 
-	/*
-	 * When USB cable is plugged out, adb reader is unblocked and
-	 * -EIO is returned to user space. adb daemon reopen the port
-	 * which would disable and enable USB configuration unnecessarily.
-	 *
-	 * Delay notifying the adb close event to android by 1 sec. If
-	 * ADB daemon opens the port with in 1 sec, USB configuration
-	 * re-enable does not happen.
-	 */
-	schedule_delayed_work(&_adb_dev->adb_release_w, msecs_to_jiffies(1000));
+	adb_closed_callback();
 
 	adb_unlock(&_adb_dev->open_excl);
 	return 0;
@@ -624,7 +608,6 @@
 	atomic_set(&dev->read_excl, 0);
 	atomic_set(&dev->write_excl, 0);
 
-	INIT_DELAYED_WORK(&dev->adb_release_w, adb_release_work);
 	INIT_LIST_HEAD(&dev->tx_idle);
 
 	_adb_dev = dev;
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index eebda9e..7af0afd 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -354,21 +354,33 @@
 static int ulpi_read(struct msm_hsic_hcd *mehci, u32 reg)
 {
 	struct usb_hcd *hcd = hsic_to_hcd(mehci);
-	unsigned long timeout;
+	int cnt = 0;
 
 	/* initiate read operation */
 	writel_relaxed(ULPI_RUN | ULPI_READ | ULPI_ADDR(reg),
 	       USB_ULPI_VIEWPORT);
 
 	/* wait for completion */
-	timeout = jiffies + usecs_to_jiffies(ULPI_IO_TIMEOUT_USEC);
-	while (readl_relaxed(USB_ULPI_VIEWPORT) & ULPI_RUN) {
-		if (time_after(jiffies, timeout)) {
-			dev_err(mehci->dev, "ulpi_read: timeout %08x\n",
-				readl_relaxed(USB_ULPI_VIEWPORT));
-			return -ETIMEDOUT;
-		}
+	while (cnt < ULPI_IO_TIMEOUT_USEC) {
+		if (!(readl_relaxed(USB_ULPI_VIEWPORT) & ULPI_RUN))
+			break;
 		udelay(1);
+		cnt++;
+	}
+
+	if (cnt >= ULPI_IO_TIMEOUT_USEC) {
+		dev_err(mehci->dev, "ulpi_read: timeout ULPI_VIEWPORT: %08x\n",
+				readl_relaxed(USB_ULPI_VIEWPORT));
+		dev_err(mehci->dev, "PORTSC: %08x USBCMD: %08x FRINDEX: %08x\n",
+				readl_relaxed(USB_PORTSC),
+				readl_relaxed(USB_USBCMD),
+				readl_relaxed(USB_FRINDEX));
+
+		/*frame counter increments afte 125us*/
+		udelay(130);
+		dev_err(mehci->dev, "ulpi_read: FRINDEX: %08x\n",
+				readl_relaxed(USB_FRINDEX));
+		return -ETIMEDOUT;
 	}
 
 	return ULPI_DATA_READ(readl_relaxed(USB_ULPI_VIEWPORT));
@@ -393,7 +405,17 @@
 	}
 
 	if (cnt >= ULPI_IO_TIMEOUT_USEC) {
-		dev_err(mehci->dev, "ulpi_write: timeout\n");
+		dev_err(mehci->dev, "ulpi_write: timeout ULPI_VIEWPORT: %08x\n",
+				readl_relaxed(USB_ULPI_VIEWPORT));
+		dev_err(mehci->dev, "PORTSC: %08x USBCMD: %08x FRINDEX: %08x\n",
+				readl_relaxed(USB_PORTSC),
+				readl_relaxed(USB_USBCMD),
+				readl_relaxed(USB_FRINDEX));
+
+		/*frame counter increments afte 125us*/
+		udelay(130);
+		dev_err(mehci->dev, "ulpi_write: FRINDEX: %08x\n",
+				readl_relaxed(USB_FRINDEX));
 		return -ETIMEDOUT;
 	}
 
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index 0976fc6..c6ffaf2 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -1418,7 +1418,7 @@
 		video_format, video_format_2string(video_format),
 		supported ? "Supported" : "Not-Supported");
 	if (supported) {
-		if (mhl_is_connected()) {
+		if (mhl_is_enabled()) {
 			const struct hdmi_disp_mode_timing_type *mhl_timing =
 				hdmi_mhl_get_supported_mode(video_format);
 			boolean mhl_supported = mhl_timing != NULL;
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 26e5687..a5e72fe 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -4448,6 +4448,11 @@
 	return 0;
 }
 
+bool mhl_is_enabled(void)
+{
+	return hdmi_msm_state->is_mhl_enabled;
+}
+
 static int __devinit hdmi_msm_probe(struct platform_device *pdev)
 {
 	int rc;
@@ -4620,6 +4625,12 @@
 	if (switch_dev_register(&external_common_state->sdev) < 0)
 		DEV_ERR("Hdmi switch registration failed\n");
 
+	/* Set the default video resolution for MHL-enabled display */
+	if (hdmi_msm_state->is_mhl_enabled) {
+		DEV_DBG("MHL Enabled. Restricting default video resolution\n");
+		external_common_state->video_resolution =
+			HDMI_VFRMT_1920x1080p30_16_9;
+	}
 	return 0;
 
 error:
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index 6325fd9..6f78305 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -338,7 +338,7 @@
 		if (pipe->pipe_used) {
 			cnt++;
 			real_pipe = mdp4_overlay_ndx2pipe(pipe->pipe_ndx);
-			if (real_pipe->pipe_used) {
+			if (real_pipe && real_pipe->pipe_used) {
 				/* pipe not unset */
 				mdp4_overlay_vsync_commit(pipe);
 			}
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index 517f103..cac6962 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -214,7 +214,7 @@
 		if (pipe->pipe_used) {
 			cnt++;
 			real_pipe = mdp4_overlay_ndx2pipe(pipe->pipe_ndx);
-			if (real_pipe->pipe_used) {
+			if (real_pipe && real_pipe->pipe_used) {
 				/* pipe not unset */
 				mdp4_overlay_vsync_commit(pipe);
 			}
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index 972e2ea..00f44d4 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -199,7 +199,7 @@
 		if (pipe->pipe_used) {
 			cnt++;
 			real_pipe = mdp4_overlay_ndx2pipe(pipe->pipe_ndx);
-			if (real_pipe->pipe_used) {
+			if (real_pipe && real_pipe->pipe_used) {
 				/* pipe not unset */
 				mdp4_overlay_vsync_commit(pipe);
 			}
@@ -796,8 +796,6 @@
 	vctrl->vsync_time = ktime_get();
 	schedule_work(&vctrl->vsync_work);
 
-	pr_debug("%s: cpu=%d\n", __func__, smp_processor_id());
-
 	spin_lock(&vctrl->spin_lock);
 	if (vctrl->wait_vsync_cnt) {
 		complete_all(&vctrl->vsync_comp);
@@ -823,6 +821,7 @@
 
 	vctrl = &vsync_ctrl_db[cndx];
 	pipe = vctrl->base_pipe;
+	pr_debug("%s: cpu=%d\n", __func__, smp_processor_id());
 
 	spin_lock(&vctrl->spin_lock);
 	if (vctrl->blt_change) {
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index 54452b0..08c3815 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -218,7 +218,7 @@
 		if (pipe->pipe_used) {
 			cnt++;
 			real_pipe = mdp4_overlay_ndx2pipe(pipe->pipe_ndx);
-			if (real_pipe->pipe_used) {
+			if (real_pipe && real_pipe->pipe_used) {
 				/* pipe not unset */
 				mdp4_overlay_vsync_commit(pipe);
 			}
diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
index f012e2e..8c61be9 100644
--- a/drivers/video/msm/mdss/mdss_dsi.c
+++ b/drivers/video/msm/mdss/mdss_dsi.c
@@ -119,7 +119,12 @@
 			return ret;
 		}
 
+		mdss_dsi_panel_reset(1);
+
 	} else {
+
+		mdss_dsi_panel_reset(0);
+
 		ret = regulator_disable(dsi_drv.vdd_vreg);
 		if (ret) {
 			pr_err("%s: Failed to disable regulator.\n", __func__);
@@ -180,7 +185,7 @@
 	}
 
 	spin_lock_bh(&dsi_clk_lock);
-	mdss_dsi_clk_disable();
+	mdss_dsi_clk_disable(pdata);
 
 	/* disable dsi engine */
 	MIPI_OUTP(mdss_dsi_base + 0x0004, 0);
@@ -212,15 +217,18 @@
 
 	pinfo = &pdata->panel_info;
 
-	cont_splash_clk_ctrl(0);
+	MIPI_OUTP(mdss_dsi_base + 0x118, 1);
+	MIPI_OUTP(mdss_dsi_base + 0x118, 0);
+
+	mdss_dsi_phy_sw_reset(pdata);
+	mdss_dsi_phy_enable(pdata, 1);
+	mdss_dsi_phy_init(pdata);
+
 	mdss_dsi_prepare_clocks();
 
 	spin_lock_bh(&dsi_clk_lock);
 
-	MIPI_OUTP(mdss_dsi_base + 0x118, 1);
-	MIPI_OUTP(mdss_dsi_base + 0x118, 0);
-
-	mdss_dsi_clk_enable();
+	mdss_dsi_clk_enable(pdata);
 	spin_unlock_bh(&dsi_clk_lock);
 
 	clk_rate = pdata->panel_info.clk_rate;
@@ -496,6 +504,7 @@
 
 	pdata->dsi_base = mdss_dsi_base;
 	pdata->mmss_cc_base = mmss_cc_base;
+	pdata->set_backlight = panel_data->bl_ctrl;
 
 	/*
 	 * register in mdp driver
diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h
index 0af4371..6acb8d5 100644
--- a/drivers/video/msm/mdss/mdss_dsi.h
+++ b/drivers/video/msm/mdss/mdss_dsi.h
@@ -76,6 +76,12 @@
 	DSI_CMD_MODE_MDP,
 };
 
+enum dsi_panel_bl_ctrl {
+	BL_PWM,
+	BL_WLED,
+	BL_DCS_CMD,
+};
+
 #define DSI_NON_BURST_SYNCH_PULSE	0
 #define DSI_NON_BURST_SYNCH_EVENT	1
 #define DSI_BURST_MODE			2
@@ -241,6 +247,7 @@
 	struct mdss_panel_info panel_info;
 	int (*on) (struct mdss_panel_data *pdata);
 	int (*off) (struct mdss_panel_data *pdata);
+	void (*bl_ctrl) (u32 bl_level);
 };
 
 struct mdss_dsi_drv_pdata {
@@ -279,8 +286,8 @@
 void mdss_dsi_cmd_mdp_start(void);
 void mdss_dsi_cmd_bta_sw_trigger(struct mdss_panel_data *pdata);
 void mdss_dsi_ack_err_status(unsigned char *dsi_base);
-void mdss_dsi_clk_enable(void);
-void mdss_dsi_clk_disable(void);
+void mdss_dsi_clk_enable(struct mdss_panel_data *pdata);
+void mdss_dsi_clk_disable(struct mdss_panel_data *pdata);
 void mdss_dsi_controller_cfg(int enable,
 				struct mdss_panel_data *pdata);
 void mdss_dsi_sw_reset(struct mdss_panel_data *pdata);
@@ -294,6 +301,10 @@
 void mdss_dsi_clk_deinit(struct device *dev);
 void mdss_dsi_prepare_clocks(void);
 void mdss_dsi_unprepare_clocks(void);
-void cont_splash_clk_ctrl(int enable);
 unsigned char *mdss_dsi_get_base_adr(void);
+void mdss_dsi_panel_reset(int enable);
+void mdss_dsi_phy_enable(struct mdss_panel_data *pdata, int on);
+void mdss_dsi_phy_init(struct mdss_panel_data *pdata);
+void mdss_dsi_phy_sw_reset(struct mdss_panel_data *pdata);
+
 #endif /* MDSS_DSI_H */
diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c
index bfb7fae..e4b1867 100644
--- a/drivers/video/msm/mdss/mdss_dsi_panel.c
+++ b/drivers/video/msm/mdss/mdss_dsi_panel.c
@@ -13,7 +13,12 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include <linux/qpnp/pin.h>
+#include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/leds.h>
 
 #include "mdss_dsi.h"
 
@@ -28,6 +33,68 @@
 static int num_of_off_cmds;
 static char *on_cmds, *off_cmds;
 
+static char bl_ctrl;
+DEFINE_LED_TRIGGER(bl_led_trigger);
+
+static struct mdss_dsi_phy_ctrl phy_params;
+
+static int rst_gpio;
+static int disp_en;
+
+struct qpnp_pin_cfg param = {
+	.mode = QPNP_PIN_MODE_DIG_OUT,
+	.output_type = QPNP_PIN_OUT_BUF_OPEN_DRAIN_NMOS,
+	.invert = QPNP_PIN_INVERT_ENABLE,
+	.pull = QPNP_PIN_MPP_PULL_UP_30KOHM,
+	.vin_sel = QPNP_PIN_VIN3,
+	.out_strength = QPNP_PIN_OUT_STRENGTH_HIGH,
+	.select = QPNP_PIN_SEL_DTEST3,
+	.master_en = QPNP_PIN_MASTER_ENABLE,
+	.aout_ref = QPNP_PIN_AOUT_0V625,
+	.ain_route = QPNP_PIN_AIN_AMUX_CH7,
+	.cs_out = QPNP_PIN_CS_OUT_20MA,
+};
+
+void mdss_dsi_panel_reset(int enable)
+{
+	if (!disp_en)
+		pr_debug("%s:%d, reset line not configured\n",
+			   __func__, __LINE__);
+
+	if (!rst_gpio)
+		pr_debug("%s:%d, reset line not configured\n",
+			   __func__, __LINE__);
+
+	if (enable) {
+		gpio_set_value(disp_en, 1);
+		gpio_set_value(rst_gpio, 1);
+		usleep(10);
+		gpio_set_value(rst_gpio, 0);
+		usleep(200);
+		gpio_set_value(rst_gpio, 1);
+	} else {
+		gpio_set_value(rst_gpio, 0);
+		gpio_set_value(disp_en, 0);
+	}
+}
+
+static void mdss_dsi_panel_bl_ctrl(u32 bl_level)
+{
+	if (bl_ctrl) {
+		switch (bl_ctrl) {
+		case BL_WLED:
+			led_trigger_event(bl_led_trigger, bl_level);
+			break;
+
+		default:
+			pr_err("%s: Unknown bl_ctrl configuration\n",
+				__func__);
+			break;
+		}
+	} else
+		pr_err("%s:%d, bl_ctrl not configured", __func__, __LINE__);
+}
+
 static int mdss_dsi_panel_on(struct mdss_panel_data *pdata)
 {
 	struct mipi_panel_info *mipi;
@@ -37,6 +104,8 @@
 	pr_debug("%s:%d, debug info (mode) : %d\n", __func__, __LINE__,
 		 mipi->mode);
 
+	mdss_dsi_panel_reset(1);
+
 	if (mipi->mode == DSI_VIDEO_MODE) {
 		mdss_dsi_cmds_tx(pdata, &dsi_panel_tx_buf, dsi_panel_on_cmds,
 			num_of_on_cmds);
@@ -64,6 +133,8 @@
 		return -EINVAL;
 	}
 
+	mdss_dsi_panel_reset(0);
+
 	return 0;
 }
 
@@ -75,6 +146,7 @@
 	int rc, i, len;
 	int cmd_plen, data_offset;
 	const char *data;
+	static const char *bl_ctrl_type;
 
 	rc = of_property_read_u32_array(np, "qcom,mdss-pan-res", res, 2);
 	if (rc) {
@@ -85,6 +157,59 @@
 	panel_data->panel_info.xres = (!rc ? res[0] : 640);
 	panel_data->panel_info.yres = (!rc ? res[1] : 480);
 
+	rc = of_property_read_u32_array(np, "qcom,mdss-pan-active-res", res, 2);
+	if (rc == 0) {
+		panel_data->panel_info.lcdc.xres_pad =
+			panel_data->panel_info.xres - res[0];
+		panel_data->panel_info.lcdc.yres_pad =
+			panel_data->panel_info.yres - res[1];
+	}
+
+	disp_en = of_get_named_gpio(np, "qcom,enable-gpio", 0);
+	if (!gpio_is_valid(disp_en)) {
+		pr_err("%s:%d, Disp_en gpio not specified\n",
+						__func__, __LINE__);
+		return -ENODEV;
+	}
+
+	rc = gpio_request(disp_en, "disp_enable");
+	if (rc) {
+		pr_err("request reset gpio failed, rc=%d\n",
+			rc);
+		gpio_free(disp_en);
+		return -ENODEV;
+	}
+	rc = gpio_direction_output(disp_en, 1);
+	if (rc) {
+		pr_err("set_direction for disp_en gpio failed, rc=%d\n",
+			rc);
+		gpio_free(disp_en);
+		return -ENODEV;
+	}
+
+	rst_gpio = of_get_named_gpio(np, "qcom,rst-gpio", 0);
+	if (!gpio_is_valid(rst_gpio)) {
+		pr_err("%s:%d, reset gpio not specified\n",
+						__func__, __LINE__);
+	} else {
+	  rc = qpnp_pin_config(rst_gpio, &param);
+		if (rc) {
+			pr_err("request reset gpio failed, rc=%d\n",
+				rc);
+			gpio_free(disp_en);
+			return rc;
+		}
+
+		rc = gpio_request(rst_gpio, "disp_rst_n");
+		if (rc) {
+			pr_err("request reset gpio failed, rc=%d\n",
+				rc);
+			gpio_free(rst_gpio);
+			gpio_free(disp_en);
+			return -ENODEV;
+		}
+	}
+
 	rc = of_property_read_u32(np, "qcom,mdss-pan-bpp", &tmp);
 	if (rc) {
 		pr_err("%s:%d, panel bpp not specified\n",
@@ -106,6 +231,14 @@
 		"qcom,mdss-pan-underflow-clr", &tmp);
 	panel_data->panel_info.lcdc.underflow_clr = (!rc ? tmp : 0xff);
 
+	bl_ctrl_type = of_get_property(pdev->dev.of_node,
+				  "qcom,mdss-pan-bl-ctrl", NULL);
+	if (!strncmp(bl_ctrl_type, "bl_ctrl_wled", 12)) {
+		led_trigger_register_simple("bkl-trigger", &bl_led_trigger);
+		pr_debug("%s: SUCCESS-> WLED TRIGGER register\n", __func__);
+		bl_ctrl = BL_WLED;
+	}
+
 	rc = of_property_read_u32_array(np,
 		"qcom,mdss-pan-bl-levels", res, 2);
 	panel_data->panel_info.bl_min = (!rc ? res[0] : 0);
@@ -184,6 +317,53 @@
 	rc = of_property_read_u32(np, "qcom,mdss-pan-dsi-frame-rate", &tmp);
 	panel_data->panel_info.mipi.frame_rate = (!rc ? tmp : 60);
 
+	data = of_get_property(np, "qcom,panel-phy-regulatorSettings", &len);
+	if ((!data) || (len != 8)) {
+		pr_err("%s:%d, Unable to read Phy regulator settings",
+		       __func__, __LINE__);
+		goto error;
+	}
+	for (i = 0; i < len; i++)
+		phy_params.regulator[i] = data[i];
+
+	data = of_get_property(np, "qcom,panel-phy-timingSettings", &len);
+	if ((!data) || (len != 12)) {
+		pr_err("%s:%d, Unable to read Phy timing settings",
+		       __func__, __LINE__);
+		goto error;
+	}
+	for (i = 0; i < len; i++)
+		phy_params.timing[i] = data[i];
+
+	data = of_get_property(np, "qcom,panel-phy-strengthCtrl", &len);
+	if ((!data) || (len != 2)) {
+		pr_err("%s:%d, Unable to read Phy Strength ctrl settings",
+		       __func__, __LINE__);
+		goto error;
+	}
+	phy_params.strength[0] = data[0];
+	phy_params.strength[1] = data[1];
+
+	data = of_get_property(np, "qcom,panel-phy-bistCtrl", &len);
+	if ((!data) || (len != 6)) {
+		pr_err("%s:%d, Unable to read Phy Bist Ctrl settings",
+		       __func__, __LINE__);
+		goto error;
+	}
+	for (i = 0; i < len; i++)
+		phy_params.bistCtrl[i] = data[i];
+
+	data = of_get_property(np, "qcom,panel-phy-laneConfig", &len);
+	if ((!data) || (len != 45)) {
+		pr_err("%s:%d, Unable to read Phy lane configure settings",
+		       __func__, __LINE__);
+		goto error;
+	}
+	for (i = 0; i < len; i++)
+		phy_params.laneCfg[i] = data[i];
+
+	panel_data->panel_info.mipi.dsi_phy_db = &phy_params;
+
 	data = of_get_property(np, "qcom,panel-on-cmds", &len);
 	if (!data) {
 		pr_err("%s:%d, Unable to read ON cmds", __func__, __LINE__);
@@ -288,6 +468,10 @@
 	kfree(dsi_panel_off_cmds);
 	kfree(on_cmds);
 	kfree(off_cmds);
+	if (rst_gpio)
+		gpio_free(rst_gpio);
+	if (disp_en)
+		gpio_free(disp_en);
 
 	return -EINVAL;
 }
@@ -295,7 +479,7 @@
 static int __devinit mdss_dsi_panel_probe(struct platform_device *pdev)
 {
 	int rc = 0;
-	struct mdss_panel_common_pdata *vendor_pdata = NULL;
+	static struct mdss_panel_common_pdata vendor_pdata;
 	static const char *panel_name;
 
 	if (pdev->dev.parent == NULL) {
@@ -314,21 +498,15 @@
 	else
 		pr_info("%s: Panel Name = %s\n", __func__, panel_name);
 
-	vendor_pdata = devm_kzalloc(&pdev->dev,
-			sizeof(*vendor_pdata), GFP_KERNEL);
-	if (!vendor_pdata)
-		return -ENOMEM;
-
-	rc = mdss_panel_parse_dt(pdev, vendor_pdata);
-	if (rc) {
-		devm_kfree(&pdev->dev, vendor_pdata);
-		vendor_pdata = NULL;
+	rc = mdss_panel_parse_dt(pdev, &vendor_pdata);
+	if (rc)
 		return rc;
-	}
-	vendor_pdata->on = mdss_dsi_panel_on;
-	vendor_pdata->off = mdss_dsi_panel_off;
 
-	rc = dsi_panel_device_register(pdev, vendor_pdata);
+	vendor_pdata.on = mdss_dsi_panel_on;
+	vendor_pdata.off = mdss_dsi_panel_off;
+	vendor_pdata.bl_ctrl = mdss_dsi_panel_bl_ctrl;
+
+	rc = dsi_panel_device_register(pdev, &vendor_pdata);
 	if (rc)
 		return rc;
 
diff --git a/drivers/video/msm/mdss/mdss_panel.h b/drivers/video/msm/mdss/mdss_panel.h
index 91010f4..5d23548 100644
--- a/drivers/video/msm/mdss/mdss_panel.h
+++ b/drivers/video/msm/mdss/mdss_panel.h
@@ -83,6 +83,18 @@
 	u32 yres_pad;
 };
 
+
+/* DSI PHY configuration */
+struct mdss_dsi_phy_ctrl {
+	uint32_t regulator[8];
+	uint32_t timing[12];
+	uint32_t ctrl[4];
+	uint32_t strength[2];
+	char bistCtrl[6];
+	uint32_t pll[21];
+	char laneCfg[45];
+};
+
 struct mipi_panel_info {
 	char mode;		/* video/cmd */
 	char interleave_mode;
@@ -103,7 +115,7 @@
 	char t_clk_post; /* 0xc0, DSI_CLKOUT_TIMING_CTRL */
 	char t_clk_pre;  /* 0xc0, DSI_CLKOUT_TIMING_CTRL */
 	char vc;	/* virtual channel */
-	struct mipi_dsi_phy_ctrl *dsi_phy_db;
+	struct mdss_dsi_phy_ctrl *dsi_phy_db;
 	/* video mode */
 	char pulse_mode_hsa_he;
 	char hfp_power_stop;
diff --git a/drivers/video/msm/mdss/msm_mdss_io_8974.c b/drivers/video/msm/mdss/msm_mdss_io_8974.c
index c766ec7..9d9a366 100644
--- a/drivers/video/msm/mdss/msm_mdss_io_8974.c
+++ b/drivers/video/msm/mdss/msm_mdss_io_8974.c
@@ -12,6 +12,7 @@
  */
 #include <linux/clk.h>
 #include <linux/interrupt.h>
+#include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/io.h>
 
@@ -26,8 +27,9 @@
 
 static struct dsi_clk_desc dsi_pclk;
 
-static struct clk *dsi_byte_div_clk;
+static struct clk *dsi_byte_clk;
 static struct clk *dsi_esc_clk;
+static struct clk *dsi_pixel_clk;
 
 int mdss_dsi_clk_on;
 
@@ -35,16 +37,23 @@
 {
 	struct device *dev = &pdev->dev;
 
-	dsi_byte_div_clk = clk_get(dev, "byte_clk");
-	if (IS_ERR(dsi_byte_div_clk)) {
-		pr_err("can't find dsi_byte_div_clk\n");
-		dsi_byte_div_clk = NULL;
+	dsi_byte_clk = clk_get(dev, "byte_clk");
+	if (IS_ERR(dsi_byte_clk)) {
+		pr_err("can't find dsi_byte_clk\n");
+		dsi_byte_clk = NULL;
+		goto mdss_dsi_clk_err;
+	}
+
+	dsi_pixel_clk = clk_get(dev, "pixel_clk");
+	if (IS_ERR(dsi_pixel_clk)) {
+		pr_err("can't find dsi_pixel_clk\n");
+		dsi_pixel_clk = NULL;
 		goto mdss_dsi_clk_err;
 	}
 
 	dsi_esc_clk = clk_get(dev, "core_clk");
 	if (IS_ERR(dsi_esc_clk)) {
-		printk(KERN_ERR "can't find dsi_esc_clk\n");
+		pr_err("can't find dsi_esc_clk\n");
 		dsi_esc_clk = NULL;
 		goto mdss_dsi_clk_err;
 	}
@@ -58,10 +67,12 @@
 
 void mdss_dsi_clk_deinit(struct device *dev)
 {
-	if (dsi_byte_div_clk)
-		clk_put(dsi_byte_div_clk);
+	if (dsi_byte_clk)
+		clk_put(dsi_byte_clk);
 	if (dsi_esc_clk)
 		clk_put(dsi_esc_clk);
+	if (dsi_pixel_clk)
+		clk_put(dsi_pixel_clk);
 }
 
 #define PREF_DIV_RATIO 27
@@ -143,57 +154,145 @@
 	return 0;
 }
 
-void cont_splash_clk_ctrl(int enable)
-{
-	static int cont_splash_clks_enabled;
-	if (enable && !cont_splash_clks_enabled) {
-			clk_prepare_enable(dsi_byte_div_clk);
-			clk_prepare_enable(dsi_esc_clk);
-			cont_splash_clks_enabled = 1;
-	} else if (!enable && cont_splash_clks_enabled) {
-			clk_disable_unprepare(dsi_byte_div_clk);
-			clk_disable_unprepare(dsi_esc_clk);
-			cont_splash_clks_enabled = 0;
-	}
-}
-
 void mdss_dsi_prepare_clocks(void)
 {
-	clk_prepare(dsi_byte_div_clk);
+	clk_prepare(dsi_byte_clk);
 	clk_prepare(dsi_esc_clk);
+	clk_prepare(dsi_pixel_clk);
 }
 
 void mdss_dsi_unprepare_clocks(void)
 {
 	clk_unprepare(dsi_esc_clk);
-	clk_unprepare(dsi_byte_div_clk);
+	clk_unprepare(dsi_pixel_clk);
+	clk_unprepare(dsi_byte_clk);
 }
 
-void mdss_dsi_clk_enable(void)
+void mdss_dsi_clk_enable(struct mdss_panel_data *pdata)
 {
 	if (mdss_dsi_clk_on) {
 		pr_info("%s: mdss_dsi_clks already ON\n", __func__);
 		return;
 	}
 
-	if (clk_set_rate(dsi_byte_div_clk, 1) < 0)	/* divided by 1 */
-		pr_err("%s: dsi_byte_div_clk - clk_set_rate failed\n",
-					__func__);
-	if (clk_set_rate(dsi_esc_clk, 2) < 0) /* divided by 2 */
+	if (clk_set_rate(dsi_esc_clk, 19200000) < 0)
 		pr_err("%s: dsi_esc_clk - clk_set_rate failed\n",
 					__func__);
-	clk_enable(dsi_byte_div_clk);
+
+	if (clk_set_rate(dsi_byte_clk, 53000000) < 0)
+		pr_err("%s: dsi_byte_clk - clk_set_rate failed\n",
+					__func__);
+
+	if (clk_set_rate(dsi_pixel_clk, 70000000) < 0)
+		pr_err("%s: dsi_pixel_clk - clk_set_rate failed\n",
+					__func__);
+
 	clk_enable(dsi_esc_clk);
+	clk_enable(dsi_byte_clk);
+	clk_enable(dsi_pixel_clk);
+
 	mdss_dsi_clk_on = 1;
 }
 
-void mdss_dsi_clk_disable(void)
+void mdss_dsi_clk_disable(struct mdss_panel_data *pdata)
 {
 	if (mdss_dsi_clk_on == 0) {
 		pr_info("%s: mdss_dsi_clks already OFF\n", __func__);
 		return;
 	}
+
+	clk_disable(dsi_pixel_clk);
+	clk_disable(dsi_byte_clk);
 	clk_disable(dsi_esc_clk);
-	clk_disable(dsi_byte_div_clk);
+
 	mdss_dsi_clk_on = 0;
 }
+
+void mdss_dsi_phy_sw_reset(struct mdss_panel_data *pdata)
+{
+	/* start phy sw reset */
+	MIPI_OUTP((pdata->dsi_base) + 0x12c, 0x0001);
+	wmb();
+	usleep(1);
+	/* end phy sw reset */
+	MIPI_OUTP((pdata->dsi_base) + 0x12c, 0x0000);
+	wmb();
+	usleep(1);
+}
+
+void mdss_dsi_phy_enable(struct mdss_panel_data *pdata, int on)
+{
+	if (on) {
+		MIPI_OUTP((pdata->dsi_base) + 0x0220, 0x006);
+		usleep(10);
+		MIPI_OUTP((pdata->dsi_base) + 0x0268, 0x001);
+		usleep(10);
+		MIPI_OUTP((pdata->dsi_base) + 0x0268, 0x000);
+		usleep(10);
+		MIPI_OUTP((pdata->dsi_base) + 0x0220, 0x007);
+		wmb();
+
+		/* MMSS_DSI_0_PHY_DSIPHY_CTRL_0 */
+		MIPI_OUTP((pdata->dsi_base) + 0x0470, 0x07e);
+		MIPI_OUTP((pdata->dsi_base) + 0x0470, 0x06e);
+		MIPI_OUTP((pdata->dsi_base) + 0x0470, 0x06c);
+		MIPI_OUTP((pdata->dsi_base) + 0x0470, 0x064);
+		MIPI_OUTP((pdata->dsi_base) + 0x0470, 0x065);
+		MIPI_OUTP((pdata->dsi_base) + 0x0470, 0x075);
+		MIPI_OUTP((pdata->dsi_base) + 0x0470, 0x077);
+		MIPI_OUTP((pdata->dsi_base) + 0x0470, 0x07f);
+		wmb();
+
+	} else {
+		MIPI_OUTP((pdata->dsi_base) + 0x0220, 0x006);
+		usleep(10);
+		MIPI_OUTP((pdata->dsi_base) + 0x0470, 0x000);
+		wmb();
+	}
+}
+
+void mdss_dsi_phy_init(struct mdss_panel_data *pdata)
+{
+	struct mdss_dsi_phy_ctrl *pd;
+	int i, off, ln, offset;
+
+	pd = (pdata->panel_info.mipi).dsi_phy_db;
+
+	off = 0x0580;	/* phy regulator ctrl settings */
+	for (i = 0; i < 8; i++) {
+		MIPI_OUTP((pdata->dsi_base) + off, pd->regulator[i]);
+		wmb();
+		off += 4;
+	}
+
+	off = 0x0440;	/* phy timing ctrl 0 - 11 */
+	for (i = 0; i < 12; i++) {
+		MIPI_OUTP((pdata->dsi_base) + off, pd->timing[i]);
+		wmb();
+		off += 4;
+	}
+
+	/* Strength ctrl 0 - 1 */
+	MIPI_OUTP((pdata->dsi_base) + 0x0484, pd->strength[0]);
+	MIPI_OUTP((pdata->dsi_base) + 0x0488, pd->strength[1]);
+	wmb();
+
+	off = 0x04b4;	/* phy BIST ctrl 0 - 5 */
+	for (i = 0; i < 6; i++) {
+		MIPI_OUTP((pdata->dsi_base) + off, pd->bistCtrl[i]);
+		wmb();
+		off += 4;
+	}
+
+	/* 4 lanes + clk lane configuration */
+	/* lane config n * (0 - 4) & DataPath setup */
+	for (ln = 0; ln < 5; ln++) {
+		off = 0x0300 + (ln * 0x40);
+		for (i = 0; i < 9; i++) {
+			offset = i + (ln * 9);
+			MIPI_OUTP((pdata->dsi_base) + off, pd->laneCfg[offset]);
+			wmb();
+			off += 4;
+		}
+	}
+}
diff --git a/drivers/video/msm/mhl/mhl_8334.c b/drivers/video/msm/mhl/mhl_8334.c
index 646dd29..4347dc7 100644
--- a/drivers/video/msm/mhl/mhl_8334.c
+++ b/drivers/video/msm/mhl/mhl_8334.c
@@ -224,12 +224,6 @@
 	return 0;
 }
 
-bool mhl_is_connected(void)
-{
-	return true;
-}
-
-
 /*  USB_HANDSHAKING FUNCTIONS */
 
 int mhl_device_discovery(const char *name, int *result)
@@ -547,6 +541,11 @@
 	pr_debug("MHL: mhl_msm_state->mhl_data->irq=[%d]\n",
 		mhl_msm_state->mhl_data->irq);
 
+	if (!mhl_msm_state->mhl_data->mhl_enabled) {
+		pr_info("MHL Display not enabled\n");
+		return -ENODEV;
+	}
+
 	/* Init GPIO stuff here */
 	ret = mhl_sii_gpio_setup(1);
 	if (ret == -1) {
diff --git a/drivers/video/msm/mhl_api.h b/drivers/video/msm/mhl_api.h
index a4364ea..7fdbaa9 100644
--- a/drivers/video/msm/mhl_api.h
+++ b/drivers/video/msm/mhl_api.h
@@ -15,9 +15,9 @@
 #define __MHL_API_H__
 
 #ifdef CONFIG_FB_MSM_HDMI_MHL_8334
-bool mhl_is_connected(void);
+bool mhl_is_enabled(void);
 #else
-static bool mhl_is_connected(void)
+static bool mhl_is_enabled(void)
 {
 	return false;
 }
diff --git a/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h b/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h
index 9619527..0d5d058 100644
--- a/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h
+++ b/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h
@@ -116,4 +116,6 @@
 			unsigned int *rx_ch,
 			unsigned int *tx_ch);
 int wcd9xxx_get_slave_port(unsigned int ch_num);
+int wcd9xxx_disconnect_port(struct wcd9xxx *wcd9xxx, unsigned int *ch_num,
+				unsigned int tot_ch, unsigned int rx_tx);
 #endif /* __WCD9310_SLIMSLAVE_H_ */
diff --git a/include/linux/usb/msm_hsusb_hw.h b/include/linux/usb/msm_hsusb_hw.h
index 516f764..a040d49 100644
--- a/include/linux/usb/msm_hsusb_hw.h
+++ b/include/linux/usb/msm_hsusb_hw.h
@@ -29,6 +29,7 @@
 
 #define USBCMD_RESET   2
 #define USB_USBINTR          (MSM_USB_BASE + 0x0148)
+#define USB_FRINDEX          (MSM_USB_BASE + 0x014C)
 
 #define PORTSC_PHCD            (1 << 23) /* phy suspend mode */
 #define PORTSC_PTS_MASK         (3 << 30)
diff --git a/include/media/videobuf2-msm-mem.h b/include/media/videobuf2-msm-mem.h
index 84e2bea..5285997 100644
--- a/include/media/videobuf2-msm-mem.h
+++ b/include/media/videobuf2-msm-mem.h
@@ -72,9 +72,10 @@
 					struct videobuf2_msm_offset *offset,
 					enum videobuf2_buffer_type,
 					uint32_t addr_offset, int path,
-					struct ion_client *client);
+					struct ion_client *client,
+					int domain_num);
 void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem,
-					struct ion_client *client);
+				struct ion_client *client, int domain_num);
 unsigned long videobuf2_to_pmem_contig(struct vb2_buffer *buf,
 					unsigned int plane_no);
 
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 4758829..9881640 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -4472,8 +4472,8 @@
 			pr_err("%s: Slim close tx/rx wait timeout\n",
 				__func__);
 			ret = -EINVAL;
-		}
-		ret = 0;
+		} else
+			ret = 0;
 		break;
 	}
 	return ret;
@@ -4486,7 +4486,7 @@
 	struct snd_soc_codec *codec = w->codec;
 	struct tabla_priv *tabla_p = snd_soc_codec_get_drvdata(codec);
 	u32  j = 0;
-	u32  ret = 0;
+	int  ret = 0;
 	codec->control_data = dev_get_drvdata(codec->dev->parent);
 	tabla = codec->control_data;
 
@@ -4543,13 +4543,22 @@
 			ret = wcd9xxx_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;
 			ret = tabla_codec_enable_chmask(tabla_p,
 							SND_SOC_DAPM_POST_PMD,
 							j);
+			if (ret < 0) {
+				ret = wcd9xxx_disconnect_port(tabla,
+							tabla_p->dai[j].ch_num,
+							tabla_p->dai[j].ch_tot,
+							1);
+				pr_info("%s: Disconnect RX port ret = %d\n",
+					__func__, ret);
+			}
+			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;
+
 			if ((tabla != NULL) &&
 			    (tabla->dev != NULL) &&
 			    (tabla->dev->parent != NULL)) {
@@ -4569,7 +4578,7 @@
 	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;
+	int  ret = 0;
 
 	codec->control_data = dev_get_drvdata(codec->dev->parent);
 	tabla = codec->control_data;
@@ -4626,13 +4635,21 @@
 			ret = wcd9xxx_close_slim_sch_tx(tabla,
 						tabla_p->dai[j].ch_num,
 						tabla_p->dai[j].ch_tot);
+			ret = tabla_codec_enable_chmask(tabla_p,
+						SND_SOC_DAPM_POST_PMD,
+						j);
+			if (ret < 0) {
+				ret = wcd9xxx_disconnect_port(tabla,
+						tabla_p->dai[j].ch_num,
+						tabla_p->dai[j].ch_tot, 0);
+				pr_info("%s: Disconnect TX port, ret = %d\n",
+					__func__, ret);
+			}
+
 			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;
-			ret = tabla_codec_enable_chmask(tabla_p,
-							SND_SOC_DAPM_POST_PMD,
-							j);
 			if ((tabla != NULL) &&
 			    (tabla->dev != NULL) &&
 			    (tabla->dev->parent != NULL)) {
diff --git a/sound/soc/msm/mpq8064.c b/sound/soc/msm/mpq8064.c
index f5bbf56..7c5bba8 100644
--- a/sound/soc/msm/mpq8064.c
+++ b/sound/soc/msm/mpq8064.c
@@ -627,7 +627,7 @@
 #undef S
 #define S(X, Y) ((TABLA_MBHC_CAL_PLUG_TYPE_PTR(tabla_cal)->X) = (Y))
 	S(v_no_mic, 30);
-	S(v_hs_max, 1550);
+	S(v_hs_max, 2400);
 #undef S
 #define S(X, Y) ((TABLA_MBHC_CAL_BTN_DET_PTR(tabla_cal)->X) = (Y))
 	S(c[0], 62);
@@ -645,24 +645,24 @@
 	btn_low = tabla_mbhc_cal_btn_det_mp(btn_cfg, TABLA_BTN_DET_V_BTN_LOW);
 	btn_high = tabla_mbhc_cal_btn_det_mp(btn_cfg, TABLA_BTN_DET_V_BTN_HIGH);
 	btn_low[0] = -50;
-	btn_high[0] = 10;
-	btn_low[1] = 11;
-	btn_high[1] = 38;
-	btn_low[2] = 39;
-	btn_high[2] = 64;
-	btn_low[3] = 65;
-	btn_high[3] = 91;
-	btn_low[4] = 92;
-	btn_high[4] = 115;
-	btn_low[5] = 116;
-	btn_high[5] = 141;
-	btn_low[6] = 142;
-	btn_high[6] = 163;
-	btn_low[7] = 164;
-	btn_high[7] = 250;
+	btn_high[0] = 20;
+	btn_low[1] = 21;
+	btn_high[1] = 62;
+	btn_low[2] = 62;
+	btn_high[2] = 104;
+	btn_low[3] = 105;
+	btn_high[3] = 143;
+	btn_low[4] = 144;
+	btn_high[4] = 181;
+	btn_low[5] = 182;
+	btn_high[5] = 218;
+	btn_low[6] = 219;
+	btn_high[6] = 254;
+	btn_low[7] = 255;
+	btn_high[7] = 330;
 	n_ready = tabla_mbhc_cal_btn_det_mp(btn_cfg, TABLA_BTN_DET_N_READY);
-	n_ready[0] = 48;
-	n_ready[1] = 38;
+	n_ready[0] = 80;
+	n_ready[1] = 68;
 	n_cic = tabla_mbhc_cal_btn_det_mp(btn_cfg, TABLA_BTN_DET_N_CIC);
 	n_cic[0] = 60;
 	n_cic[1] = 47;
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index 1dbd698..42bc979 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -548,7 +548,6 @@
 	}
 	prtd = &compr->prtd;
 	prtd->substream = substream;
-	prtd->audio_client->perf_mode = false;
 	prtd->audio_client = q6asm_audio_client_alloc(
 				(app_cb)compr_event_handler, compr);
 	if (!prtd->audio_client) {
@@ -556,7 +555,7 @@
 		kfree(prtd);
 		return -ENOMEM;
 	}
-
+	prtd->audio_client->perf_mode = false;
 	pr_info("%s: session ID %d\n", __func__, prtd->audio_client->session);
 
 	prtd->session_id = prtd->audio_client->session;
diff --git a/sound/soc/msm/msm-multi-ch-pcm-q6.c b/sound/soc/msm/msm-multi-ch-pcm-q6.c
index 2d23b48..a13d4da 100644
--- a/sound/soc/msm/msm-multi-ch-pcm-q6.c
+++ b/sound/soc/msm/msm-multi-ch-pcm-q6.c
@@ -330,7 +330,6 @@
 		return -ENOMEM;
 	}
 	prtd->substream = substream;
-	prtd->audio_client->perf_mode = false;
 	prtd->audio_client = q6asm_audio_client_alloc(
 				(app_cb)event_handler, prtd);
 	if (!prtd->audio_client) {
@@ -338,6 +337,7 @@
 		kfree(prtd);
 		return -ENOMEM;
 	}
+	prtd->audio_client->perf_mode = false;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		runtime->hw = msm_pcm_hardware_playback;
 		ret = q6asm_open_write(prtd->audio_client,
diff --git a/sound/soc/msm/msm-pcm-lpa.c b/sound/soc/msm/msm-pcm-lpa.c
index 116ce3e..ff0fb3b 100644
--- a/sound/soc/msm/msm-pcm-lpa.c
+++ b/sound/soc/msm/msm-pcm-lpa.c
@@ -282,7 +282,6 @@
 	}
 	runtime->hw = msm_pcm_hardware;
 	prtd->substream = substream;
-	prtd->audio_client->perf_mode = false;
 	prtd->audio_client = q6asm_audio_client_alloc(
 				(app_cb)event_handler, prtd);
 	if (!prtd->audio_client) {
@@ -290,6 +289,7 @@
 		kfree(prtd);
 		return -ENOMEM;
 	}
+	prtd->audio_client->perf_mode = false;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		ret = q6asm_open_write(prtd->audio_client, FORMAT_LINEAR_PCM);
 		if (ret < 0) {
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index 040bbe0..a1be978 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -1754,11 +1754,18 @@
 		return ret;
 	}
 
-	if (msm8960_configure_headset_mic_gpios()) {
-		pr_err("%s Fail to configure headset mic gpios\n", __func__);
+	if (cpu_is_msm8960()) {
+		if (msm8960_configure_headset_mic_gpios()) {
+			pr_err("%s Fail to configure headset mic gpios\n",
+								__func__);
+			msm8960_headset_gpios_configured = 0;
+		} else
+			msm8960_headset_gpios_configured = 1;
+	} else {
 		msm8960_headset_gpios_configured = 0;
-	} else
-		msm8960_headset_gpios_configured = 1;
+		pr_debug("%s headset GPIO 23 and 35 not configured msm960ab",
+								__func__);
+	}
 
 	mutex_init(&cdc_mclk_mutex);
 
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 4522d15..79016b5 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3231,6 +3231,7 @@
 	card->instantiated = 0;
 	mutex_init(&card->mutex);
 	mutex_init(&card->dpcm_mutex);
+	mutex_init(&card->dapm_power_mutex);
 
 	mutex_lock(&client_mutex);
 	list_add(&card->list, &card_list);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 729142f..5ac643416 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1290,7 +1290,7 @@
 		/* Do we need to apply any queued changes? */
 		if (sort[w->id] != cur_sort || w->reg != cur_reg ||
 		    w->dapm != cur_dapm || w->subseq != cur_subseq) {
-			if (!list_empty(&pending))
+			if (cur_dapm && !list_empty(&pending))
 				dapm_seq_run_coalesced(cur_dapm, &pending);
 
 			if (cur_dapm && cur_dapm->seq_notifier) {
@@ -1350,7 +1350,7 @@
 				"Failed to apply widget power: %d\n", ret);
 	}
 
-	if (!list_empty(&pending))
+	if (cur_dapm && !list_empty(&pending))
 		dapm_seq_run_coalesced(cur_dapm, &pending);
 
 	if (cur_dapm && cur_dapm->seq_notifier) {
@@ -1567,6 +1567,8 @@
 
 	trace_snd_soc_dapm_start(card);
 
+	mutex_lock(&card->dapm_power_mutex);
+
 	list_for_each_entry(d, &card->dapm_list, list) {
 		if (d->n_widgets || d->codec == NULL) {
 			if (d->idle_bias_off)
@@ -1682,6 +1684,8 @@
 		"DAPM sequencing finished, waiting %dms\n", card->pop_time);
 	pop_wait(card->pop_time);
 
+	mutex_unlock(&card->dapm_power_mutex);
+
 	trace_snd_soc_dapm_done(card);
 
 	return 0;
@@ -3092,9 +3096,9 @@
 	if (stream == NULL)
 		return 0;
 
-	//mutex_lock(&codec->mutex);
+	mutex_lock(&codec->mutex);
 	soc_dapm_stream_event(&codec->dapm, stream, event);
-	//mutex_unlock(&codec->mutex);
+	mutex_unlock(&codec->mutex);
 
 	return 0;
 }