Merge "msm: mdss: Enable solid fill on pipe"
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index 714311e..623a23c 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -91,6 +91,8 @@
 	runs using PNOC clock and synchronous to it. Hence it is must to have proper
 	"qcom,msm_bus,vectors" to have high bus frequency. User shouldn't try to
 	enable this feature without proper bus voting.
+-qcom,disable-retention-with-vdd-min: If present dont allow phy retention but allow
+	vdd min.
 
 Example HSUSB OTG controller device node :
 	usb@f9690000 {
@@ -115,6 +117,7 @@
                 HSUSB_3p3-supply = <&pm8226_l20>;
 		qcom,vdd-voltage-level = <1 5 7>;
 		qcom,dp-manual-pullup;
+		qcom,disable-retention-with-vdd-min;
 		qcom,hsusb-otg-dpsehv-int = <49>;
 		qcom,hsusb-otg-dmsehv-int = <58>;
 		qcom,msm_bus,name = "usb2";
diff --git a/arch/arm/boot/dts/dsi-panel-orise-720p-video.dtsi b/arch/arm/boot/dts/dsi-panel-orise-720p-video.dtsi
index 30eda91..5393756 100644
--- a/arch/arm/boot/dts/dsi-panel-orise-720p-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-orise-720p-video.dtsi
@@ -34,7 +34,7 @@
 		qcom,mdss-pan-dsi-stream = <0>;
 		qcom,mdss-pan-dsi-mdp-tr = <0x0>;
 		qcom,mdss-pan-dsi-dma-tr = <0x04>;
-		qcom,mdss-pan-dsi-frame-rate = <60>;
+		qcom,mdss-pan-dsi-framerate = <60>;
 		qcom,panel-phy-regulatorSettings = [03 01 01 00  /* Regualotor settings */
 						    20 00 01];
 		qcom,panel-phy-timingSettings = [69 29 1f 00 55 55
diff --git a/arch/arm/boot/dts/msm8610-mtp.dtsi b/arch/arm/boot/dts/msm8610-mtp.dtsi
index 6ce0109..3b0f2a2 100644
--- a/arch/arm/boot/dts/msm8610-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8610-mtp.dtsi
@@ -142,7 +142,7 @@
 				0x2800>;
 			capella,ps_close_thd_set = <0xa>;
 			capella,ps_away_thd_set = <0x5>;
-			capella,ls_cmd = <0x44>; /* PS_IT=160ms, INT_PERS=2*/
+			capella,ls_cmd = <0x04>; /* ALS_IT=80ms, INT_PERS=2*/
 			capella,ps_conf1_val = <0x0006>;
 			capella,ps_conf3_val = <0x3010>;
 		};
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 1619d1f..9ee96a7 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -240,6 +240,7 @@
 		qcom,hsusb-otg-disable-reset;
 		qcom,dp-manual-pullup;
 		qcom,ahb-async-bridge-bypass;
+		qcom,disable-retention-with-vdd-min;
 
 		qcom,msm-bus,name = "usb2";
 		qcom,msm-bus,num-cases = <2>;
diff --git a/arch/arm/configs/msm8610-perf_defconfig b/arch/arm/configs/msm8610-perf_defconfig
index 8366a41..84dee5d 100644
--- a/arch/arm/configs/msm8610-perf_defconfig
+++ b/arch/arm/configs/msm8610-perf_defconfig
@@ -80,6 +80,7 @@
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_COMPACTION=y
+CONFIG_KSM=y
 CONFIG_CC_STACKPROTECTOR=y
 CONFIG_ENABLE_VMALLOC_SAVING=y
 CONFIG_CP_ACCESS=y
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index 02db2f2..e094a23 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -81,6 +81,7 @@
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_COMPACTION=y
+CONFIG_KSM=y
 CONFIG_CC_STACKPROTECTOR=y
 CONFIG_ENABLE_VMALLOC_SAVING=y
 CONFIG_CP_ACCESS=y
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index c95726f..d41b52b 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -578,17 +578,6 @@
 			| BVAL(10, 8, s##_mm_source_val), \
 	}
 
-#define F_HDMI(f, s, div, m, n) \
-	{ \
-		.freq_hz = (f), \
-		.src_clk = &s##_clk_src, \
-		.m_val = (m), \
-		.n_val = ~((n)-(m)) * !!(n), \
-		.d_val = ~(n),\
-		.div_src_val = BVAL(4, 0, (int)(2*(div) - 1)) \
-			| BVAL(10, 8, s##_mm_source_val), \
-	}
-
 #define F_MDSS(f, s, div, m, n) \
 	{ \
 		.freq_hz = (f), \
@@ -3255,60 +3244,19 @@
 	},
 };
 
-static int hdmi_pll_clk_enable(struct clk *c)
-{
-	return hdmi_pll_enable();
-}
-
-static void hdmi_pll_clk_disable(struct clk *c)
-{
-	hdmi_pll_disable();
-}
-
-static int hdmi_pll_clk_set_rate(struct clk *c, unsigned long rate)
-{
-	return hdmi_pll_set_rate(rate);
-}
-
-static struct clk_ops clk_ops_hdmi_pll = {
-	.enable = hdmi_pll_clk_enable,
-	.disable = hdmi_pll_clk_disable,
-	.set_rate = hdmi_pll_clk_set_rate,
-};
-
-static struct clk hdmipll_clk_src = {
-	.parent = &cxo_clk_src.c,
-	.dbg_name = "hdmipll_clk_src",
-	.ops = &clk_ops_hdmi_pll,
-	CLK_INIT(hdmipll_clk_src),
-};
-
 static struct clk_freq_tbl ftbl_mdss_extpclk_clk[] = {
-	/*
-	 * The zero rate is required since suspend/resume wipes out the HDMI PHY
-	 * registers. This entry allows the HDMI driver to switch the cached
-	 * rate to zero before suspend and back to the real rate after resume.
-	 */
-	F_HDMI(        0, hdmipll, 1, 0, 0),
-	F_HDMI( 25200000, hdmipll, 1, 0, 0),
-	F_HDMI( 27000000, hdmipll, 1, 0, 0),
-	F_HDMI( 27030000, hdmipll, 1, 0, 0),
-	F_HDMI( 65000000, hdmipll, 1, 0, 0),
-	F_HDMI( 74250000, hdmipll, 1, 0, 0),
-	F_HDMI(108000000, hdmipll, 1, 0, 0),
-	F_HDMI(148500000, hdmipll, 1, 0, 0),
-	F_HDMI(268500000, hdmipll, 1, 0, 0),
-	F_HDMI(297000000, hdmipll, 1, 0, 0),
+	F_MM(148500000, hdmipll, 1, 0, 0),
 	F_END
 };
 
 static struct rcg_clk extpclk_clk_src = {
 	.cmd_rcgr_reg = EXTPCLK_CMD_RCGR,
 	.freq_tbl = ftbl_mdss_extpclk_clk,
-	.current_freq = &rcg_dummy_freq,
+	.current_freq = ftbl_mdss_extpclk_clk,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
 		.dbg_name = "extpclk_clk_src",
+		.parent = &hdmipll_clk_src.c,
 		.ops = &clk_ops_rcg_hdmi,
 		VDD_DIG_FMAX_MAP2(LOW, 148500000, NOMINAL, 297000000),
 		CLK_INIT(extpclk_clk_src.c),
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index 4488869..62ecfa8 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -774,27 +774,35 @@
  */
 static int rcg_clk_set_rate_hdmi(struct clk *c, unsigned long rate)
 {
-	struct clk_freq_tbl *nf;
 	struct rcg_clk *rcg = to_rcg_clk(c);
+	struct clk_freq_tbl *nf = rcg->freq_tbl;
 	int rc;
 
-	for (nf = rcg->freq_tbl; nf->freq_hz != rate; nf++)
-		if (nf->freq_hz == FREQ_END) {
-			rc = -EINVAL;
-			goto out;
-		}
-
 	rc = clk_set_rate(nf->src_clk, rate);
 	if (rc < 0)
 		goto out;
 	set_rate_hid(rcg, nf);
 
 	rcg->current_freq = nf;
-	c->parent = nf->src_clk;
 out:
 	return rc;
 }
 
+static struct clk *rcg_hdmi_clk_get_parent(struct clk *c)
+{
+	struct rcg_clk *rcg = to_rcg_clk(c);
+	struct clk_freq_tbl *freq = rcg->freq_tbl;
+	u32 cmd_rcgr_regval;
+
+	/* Is there a pending configuration? */
+	cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg));
+	if (cmd_rcgr_regval & CMD_RCGR_CONFIG_DIRTY_MASK)
+		return NULL;
+
+	rcg->current_freq->freq_hz = clk_get_rate(c->parent);
+
+	return freq->src_clk;
+}
 
 #define ENABLE_REG(x)	(*(x)->base + (x)->enable_reg)
 #define SELECT_REG(x)	(*(x)->base + (x)->select_reg)
@@ -987,7 +995,7 @@
 	.list_rate = rcg_clk_list_rate,
 	.round_rate = rcg_clk_round_rate,
 	.handoff = rcg_clk_handoff,
-	.get_parent = rcg_clk_get_parent,
+	.get_parent = rcg_hdmi_clk_get_parent,
 };
 
 struct clk_ops clk_ops_branch = {
diff --git a/arch/arm/mach-msm/clock-mdss-8974.c b/arch/arm/mach-msm/clock-mdss-8974.c
index cf2df18..343a6c6 100644
--- a/arch/arm/mach-msm/clock-mdss-8974.c
+++ b/arch/arm/mach-msm/clock-mdss-8974.c
@@ -167,23 +167,71 @@
 		(!(readl_relaxed(gdsc_base) & BIT(0)));
 }
 
-void hdmi_pll_disable(void)
+/* Auto PLL calibaration */
+static int mdss_ahb_clk_enable(int enable)
 {
-	clk_enable(mdss_ahb_clk);
+	int rc = 0;
+
+	/* todo: Ideally, we should enable/disable GDSC whenever we are
+	 * attempting to enable/disable MDSS AHB clock.
+	 * For now, just return error if  GDSC is not enabled.
+	 */
+	if (!mdss_gdsc_enabled()) {
+		pr_err("%s: mdss GDSC is not enabled\n", __func__);
+		return -EPERM;
+	}
+
+	if (enable)
+		rc = clk_prepare_enable(mdss_ahb_clk);
+	else
+		clk_disable_unprepare(mdss_ahb_clk);
+
+	return rc;
+}
+
+static void hdmi_vco_disable(struct clk *c)
+{
+	u32 rc;
+
+	if (!mdss_gdsc_enabled()) {
+		pr_err("%s: mdss GDSC is not enabled\n", __func__);
+		return;
+	}
+
+	rc = clk_enable(mdss_ahb_clk);
+	if (rc) {
+		pr_err("%s: failed to enable mdss ahb clock. rc=%d\n",
+			__func__, rc);
+		return;
+	}
+
 	REG_W(0x0, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
 	udelay(5);
 	REG_W(0x0, hdmi_phy_base + HDMI_PHY_GLB_CFG);
+
 	clk_disable(mdss_ahb_clk);
 
 	hdmi_pll_on = 0;
-} /* hdmi_pll_disable */
+} /* hdmi_vco_disable */
 
-int hdmi_pll_enable(void)
+static int hdmi_vco_enable(struct clk *c)
 {
 	u32 status;
+	u32 rc;
 	u32 max_reads, timeout_us;
 
-	clk_enable(mdss_ahb_clk);
+	if (!mdss_gdsc_enabled()) {
+		pr_err("%s: mdss GDSC is not enabled\n", __func__);
+		return -EPERM;
+	}
+
+	rc = clk_enable(mdss_ahb_clk);
+	if (rc) {
+		pr_err("%s: failed to enable mdss ahb clock. rc=%d\n",
+			__func__, rc);
+		return rc;
+	}
+
 	/* Global Enable */
 	REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
 	/* Power up power gen */
@@ -208,7 +256,7 @@
 		status, ((status & BIT(0)) == 1), max_reads, timeout_us)) {
 		pr_err("%s: hdmi phy pll status=%x failed to Lock\n",
 		       __func__, status);
-		hdmi_pll_disable();
+		hdmi_vco_disable(c);
 		clk_disable(mdss_ahb_clk);
 		return -EINVAL;
 	}
@@ -222,7 +270,7 @@
 		status, ((status & BIT(0)) == 1), max_reads, timeout_us)) {
 		pr_err("%s: hdmi phy status=%x failed to Lock\n",
 		       __func__, status);
-		hdmi_pll_disable();
+		hdmi_vco_disable(c);
 		clk_disable(mdss_ahb_clk);
 		return -EINVAL;
 	}
@@ -232,25 +280,173 @@
 	hdmi_pll_on = 1;
 
 	return 0;
-} /* hdmi_pll_enable */
+} /* hdmi_vco_enable */
 
-int hdmi_pll_set_rate(unsigned long rate)
+static inline struct hdmi_pll_vco_clk *to_hdmi_vco_clk(struct clk *clk)
+{
+	return container_of(clk, struct hdmi_pll_vco_clk, c);
+}
+
+static void hdmi_phy_pll_calculator(u32 vco_freq)
+{
+	u32 ref_clk             = 19200000;
+	u32 sdm_mode            = 1;
+	u32 ref_clk_multiplier  = sdm_mode == 1 ? 2 : 1;
+	u32 int_ref_clk_freq    = ref_clk * ref_clk_multiplier;
+	u32 fbclk_pre_div       = 1;
+	u32 ssc_mode            = 0;
+	u32 kvco                = 270;
+	u32 vdd                 = 95;
+	u32 ten_power_six       = 1000000;
+	u32 ssc_ds_ppm          = ssc_mode ? 5000 : 0;
+	u32 sdm_res             = 16;
+	u32 ssc_tri_step        = 32;
+	u32 ssc_freq            = 2;
+	u64 ssc_ds              = vco_freq * ssc_ds_ppm;
+	u32 div_in_freq         = vco_freq / fbclk_pre_div;
+	u64 dc_offset           = (div_in_freq / int_ref_clk_freq - 1) *
+					ten_power_six * 10;
+	u32 ssc_kdiv            = (int_ref_clk_freq / ssc_freq) -
+					ten_power_six;
+	u64 sdm_freq_seed;
+	u32 ssc_tri_inc;
+	u64 fb_div_n;
+
+	u32 val;
+
+	pr_debug("%s: vco_freq = %u\n", __func__, vco_freq);
+
+	do_div(ssc_ds, (u64)ten_power_six);
+
+	fb_div_n = (u64)div_in_freq * (u64)ten_power_six * 10;
+	do_div(fb_div_n, int_ref_clk_freq);
+
+	sdm_freq_seed = ((fb_div_n - dc_offset - ten_power_six * 10) *
+				(1 << sdm_res)  * 10) + 5;
+	do_div(sdm_freq_seed, ((u64)ten_power_six * 100));
+
+	ssc_tri_inc = (u32)ssc_ds;
+	ssc_tri_inc = (ssc_tri_inc / int_ref_clk_freq) * (1 << 16) /
+			ssc_tri_step;
+
+	val = (ref_clk_multiplier == 2 ? 1 : 0) +
+		((fbclk_pre_div == 2 ? 1 : 0) * 16);
+	pr_debug("%s: HDMI_UNI_PLL_REFCLK_CFG = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_REFCLK_CFG);
+
+	REG_W(0x02, hdmi_phy_pll_base + HDMI_UNI_PLL_CHFPUMP_CFG);
+	REG_W(0x19, hdmi_phy_pll_base + HDMI_UNI_PLL_VCOLPF_CFG);
+	REG_W(0x04, hdmi_phy_pll_base + HDMI_UNI_PLL_VREG_CFG);
+	REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_PWRGEN_CFG);
+	REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
+	REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
+	REG_W(0x0E, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFR_CFG);
+	REG_W(0x20, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFC1_CFG);
+	REG_W(0x0D, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFC2_CFG);
+
+	do_div(dc_offset, (u64)ten_power_six * 10);
+	val = sdm_mode == 0 ? 64 + dc_offset : 0;
+	pr_debug("%s: HDMI_UNI_PLL_SDM_CFG0 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG0);
+
+	val = 64 + dc_offset;
+	pr_debug("%s: HDMI_UNI_PLL_SDM_CFG1 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG1);
+
+	val = sdm_freq_seed & 0xFF;
+	pr_debug("%s: HDMI_UNI_PLL_SDM_CFG2 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG2);
+
+	val = (sdm_freq_seed >> 8) & 0xFF;
+	pr_debug("%s: HDMI_UNI_PLL_SDM_CFG3 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG3);
+
+	val = (sdm_freq_seed >> 16) & 0xFF;
+	pr_debug("%s: HDMI_UNI_PLL_SDM_CFG4 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG4);
+
+	val = (ssc_mode == 0 ? 128 : 0) + (ssc_kdiv / ten_power_six);
+	pr_debug("%s: HDMI_UNI_PLL_SSC_CFG0 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SSC_CFG0);
+
+	val = ssc_tri_inc & 0xFF;
+	pr_debug("%s: HDMI_UNI_PLL_SSC_CFG1 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SSC_CFG1);
+
+	val = (ssc_tri_inc >> 8) & 0xFF;
+	pr_debug("%s: HDMI_UNI_PLL_SSC_CFG2 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_SSC_CFG2);
+
+	pr_debug("%s: HDMI_UNI_PLL_SSC_CFG3 = 0x%x\n", __func__, ssc_tri_step);
+	REG_W(ssc_tri_step, hdmi_phy_pll_base + HDMI_UNI_PLL_SSC_CFG3);
+
+	REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
+	REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
+	REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
+	REG_W(0x0A, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG0);
+	REG_W(0x04, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG1);
+	REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
+	REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG3);
+	REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG4);
+	REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG5);
+
+	val = (kvco * vdd * 10000) / 6;
+	val += 500000;
+	val /= ten_power_six;
+	pr_debug("%s: HDMI_UNI_PLL_CAL_CFG6 = 0x%x\n", __func__, val);
+	REG_W(val & 0xFF, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG6);
+
+	val = (kvco * vdd * 10000) / 6;
+	val -= ten_power_six;
+	val /= ten_power_six;
+	val = (val >> 8) & 0xFF;
+	pr_debug("%s: HDMI_UNI_PLL_CAL_CFG7 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG7);
+
+	val = (ref_clk * 5) / ten_power_six;
+	pr_debug("%s: HDMI_UNI_PLL_CAL_CFG8 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG8);
+
+	val = ((ref_clk * 5) / ten_power_six) >> 8;
+	pr_debug("%s: HDMI_UNI_PLL_CAL_CFG9 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG9);
+
+	vco_freq /= ten_power_six;
+	val = vco_freq & 0xFF;
+	pr_debug("%s: HDMI_UNI_PLL_CAL_CFG10 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG10);
+
+	val = vco_freq >> 8;
+	pr_debug("%s: HDMI_UNI_PLL_CAL_CFG11 = 0x%x\n", __func__, val);
+	REG_W(val, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG11);
+} /* hdmi_phy_pll_calculator */
+
+static int hdmi_vco_set_rate(struct clk *c, unsigned long rate)
 {
 	unsigned int set_power_dwn = 0;
+	int rc = 0;
+
+	struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
 
 	if (hdmi_pll_on) {
-		hdmi_pll_disable();
+		hdmi_vco_disable(c);
 		set_power_dwn = 1;
 	}
 
-	clk_enable(mdss_ahb_clk);
+	rc = mdss_ahb_clk_enable(1);
+	if (rc) {
+		pr_err("%s: failed to enable mdss ahb clock. rc=%d\n",
+			__func__, rc);
+		return rc;
+	}
+
 	pr_debug("%s: rate=%ld\n", __func__, rate);
+
 	switch (rate) {
 	case 0:
-		/* This case is needed for suspend/resume. */
-	break;
+		break;
 
-	case 25200000:
+	case 756000000:
 		/* 640x480p60 */
 		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
@@ -267,7 +463,6 @@
 		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
 		REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
 		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x03, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
@@ -295,7 +490,7 @@
 		udelay(200);
 	break;
 
-	case 27000000:
+	case 810000000:
 		/* 576p50/576i50 case */
 		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
@@ -312,7 +507,6 @@
 		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
 		REG_W(0X1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
 		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x03, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
@@ -340,7 +534,7 @@
 		udelay(200);
 	break;
 
-	case 27030000:
+	case 810900000:
 		/* 480p60/480i60 case */
 		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
@@ -357,7 +551,6 @@
 		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
 		REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
 		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x03, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
@@ -384,7 +577,7 @@
 		REG_W(0x05, hdmi_phy_base + HDMI_PHY_TXCAL_CFG3);
 		udelay(200);
 	break;
-	case 65000000:
+	case 650000000:
 		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_REFCLK_CFG);
@@ -400,7 +593,6 @@
 		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
 		REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
 		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
@@ -427,7 +619,7 @@
 		REG_W(0x05, hdmi_phy_base + HDMI_PHY_TXCAL_CFG3);
 		udelay(200);
 	break;
-	case 74250000:
+	case 742500000:
 		/*
 		 * 720p60/720p50/1080i60/1080i50
 		 * 1080p24/1080p30/1080p25 case
@@ -447,7 +639,6 @@
 		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
 		REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
 		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
@@ -475,7 +666,7 @@
 		udelay(200);
 	break;
 
-	case 108000000:
+	case 1080000000:
 		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_REFCLK_CFG);
@@ -491,7 +682,6 @@
 		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
 		REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
 		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
@@ -519,51 +709,7 @@
 		udelay(200);
 	break;
 
-	case 148500000:
-		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
-		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
-		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_REFCLK_CFG);
-		REG_W(0x19, hdmi_phy_pll_base + HDMI_UNI_PLL_VCOLPF_CFG);
-		REG_W(0x0E, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFR_CFG);
-		REG_W(0x20, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFC1_CFG);
-		REG_W(0x0D, hdmi_phy_pll_base + HDMI_UNI_PLL_LPFC2_CFG);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG0);
-		REG_W(0x52, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG1);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG2);
-		REG_W(0x56, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG3);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_SDM_CFG4);
-		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
-		REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
-		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
-		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
-		REG_W(0x60, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG8);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG9);
-		REG_W(0xE6, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG10);
-		REG_W(0x02, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG11);
-		REG_W(0x1F, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
-		udelay(50);
-
-		REG_W(0x0F, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
-		REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL1);
-		REG_W(0x10, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
-		REG_W(0xDB, hdmi_phy_base + HDMI_PHY_ANA_CFG0);
-		REG_W(0x43, hdmi_phy_base + HDMI_PHY_ANA_CFG1);
-		REG_W(0x02, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
-		REG_W(0x00, hdmi_phy_base + HDMI_PHY_ANA_CFG3);
-		REG_W(0x04, hdmi_phy_pll_base + HDMI_UNI_PLL_VREG_CFG);
-		REG_W(0xD0, hdmi_phy_base + HDMI_PHY_DCC_CFG0);
-		REG_W(0x1A, hdmi_phy_base + HDMI_PHY_DCC_CFG1);
-		REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG0);
-		REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG1);
-		REG_W(0x02, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2);
-		REG_W(0x05, hdmi_phy_base + HDMI_PHY_TXCAL_CFG3);
-		udelay(200);
-	break;
-
-	case 268500000:
+	case 1342500000:
 		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_REFCLK_CFG);
@@ -579,7 +725,6 @@
 		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
 		REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
 		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
@@ -607,7 +752,7 @@
 		udelay(200);
 	break;
 
-	case 297000000:
+	case 1485000000:
 		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_REFCLK_CFG);
@@ -623,7 +768,6 @@
 		REG_W(0x10, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG0);
 		REG_W(0x1A, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG1);
 		REG_W(0x05, hdmi_phy_pll_base + HDMI_UNI_PLL_LKDET_CFG2);
-		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV1_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV2_CFG);
 		REG_W(0x00, hdmi_phy_pll_base + HDMI_UNI_PLL_POSTDIV3_CFG);
 		REG_W(0x01, hdmi_phy_pll_base + HDMI_UNI_PLL_CAL_CFG2);
@@ -652,40 +796,68 @@
 	break;
 
 	default:
-		pr_err("%s: not supported rate=%ld\n", __func__, rate);
+		pr_debug("%s: Use pll settings calculator for rate=%ld\n",
+			__func__, rate);
+
+		REG_W(0x81, hdmi_phy_base + HDMI_PHY_GLB_CFG);
+		hdmi_phy_pll_calculator(rate);
+		REG_W(0x1F, hdmi_phy_base + HDMI_PHY_PD_CTRL0);
+		udelay(50);
+
+		REG_W(0x0F, hdmi_phy_pll_base + HDMI_UNI_PLL_GLB_CFG);
+		REG_W(0x00, hdmi_phy_base + HDMI_PHY_PD_CTRL1);
+		REG_W(0x10, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
+		REG_W(0xDB, hdmi_phy_base + HDMI_PHY_ANA_CFG0);
+		REG_W(0x43, hdmi_phy_base + HDMI_PHY_ANA_CFG1);
+
+		if (rate < 825000000) {
+			REG_W(0x01, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
+			REG_W(0x00, hdmi_phy_base + HDMI_PHY_ANA_CFG3);
+		} else if (rate >= 825000000 && rate < 1342500000) {
+			REG_W(0x05, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
+			REG_W(0x03, hdmi_phy_base + HDMI_PHY_ANA_CFG3);
+		} else {
+			REG_W(0x06, hdmi_phy_base + HDMI_PHY_ANA_CFG2);
+			REG_W(0x03, hdmi_phy_base + HDMI_PHY_ANA_CFG3);
+		}
+
+		REG_W(0x04, hdmi_phy_pll_base + HDMI_UNI_PLL_VREG_CFG);
+		REG_W(0xD0, hdmi_phy_base + HDMI_PHY_DCC_CFG0);
+		REG_W(0x1A, hdmi_phy_base + HDMI_PHY_DCC_CFG1);
+		REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG0);
+		REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG1);
+
+		if (rate < 825000000)
+			REG_W(0x01, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2);
+		else
+			REG_W(0x00, hdmi_phy_base + HDMI_PHY_TXCAL_CFG2);
+
+		REG_W(0x05, hdmi_phy_base + HDMI_PHY_TXCAL_CFG3);
+		REG_W(0x62, hdmi_phy_base + HDMI_PHY_BIST_PATN0);
+		REG_W(0x03, hdmi_phy_base + HDMI_PHY_BIST_PATN1);
+		REG_W(0x69, hdmi_phy_base + HDMI_PHY_BIST_PATN2);
+		REG_W(0x02, hdmi_phy_base + HDMI_PHY_BIST_PATN3);
+
+		udelay(200);
+
+		REG_W(0x00, hdmi_phy_base + HDMI_PHY_BIST_CFG1);
+		REG_W(0x00, hdmi_phy_base + HDMI_PHY_BIST_CFG0);
 	}
 
 	/* Make sure writes complete before disabling iface clock */
 	mb();
 
-	clk_disable(mdss_ahb_clk);
+	mdss_ahb_clk_enable(0);
 
 	if (set_power_dwn)
-		hdmi_pll_enable();
+		hdmi_vco_enable(c);
+
+	vco->rate = rate;
+	vco->rate_set = true;
 
 	return 0;
 } /* hdmi_pll_set_rate */
 
-/* Auto PLL calibaration */
-int mdss_ahb_clk_enable(int enable)
-{
-	int rc = 0;
-
-	/* todo: Ideally, we should enable/disable GDSC whenever we are
-	 * attempting to enable/disable MDSS AHB clock.
-	 * For now, just return error if  GDSC is not enabled.
-	 */
-	if (!mdss_gdsc_enabled())
-		return -EPERM;
-
-	if (enable)
-		rc = clk_prepare_enable(mdss_ahb_clk);
-	else
-		clk_disable_unprepare(mdss_ahb_clk);
-
-	return rc;
-}
-
 int set_byte_mux_sel(struct mux_clk *clk, int sel)
 {
 	pr_debug("%s: byte mux set to %s mode\n", __func__,
@@ -1649,6 +1821,271 @@
 	},
 };
 
+/* HDMI PLL DIV CLK */
+
+static unsigned long hdmi_vco_get_rate(struct clk *c)
+{
+	unsigned long freq = 0;
+
+	if (mdss_ahb_clk_enable(1)) {
+		pr_err("%s: Failed to enable mdss ahb clock\n", __func__);
+		return freq;
+	}
+
+	freq = DSS_REG_R(hdmi_phy_pll_base, HDMI_UNI_PLL_CAL_CFG11) << 8 |
+		DSS_REG_R(hdmi_phy_pll_base, HDMI_UNI_PLL_CAL_CFG10);
+
+	switch (freq) {
+	case 742:
+		freq = 742500000;
+		break;
+	case 810:
+		if (DSS_REG_R(hdmi_phy_pll_base, HDMI_UNI_PLL_SDM_CFG3) == 0x18)
+			freq = 810000000;
+		else
+			freq = 810900000;
+		break;
+	case 1342:
+		freq = 1342500000;
+		break;
+	default:
+		freq *= 1000000;
+	}
+
+	mdss_ahb_clk_enable(0);
+
+	return freq;
+}
+
+static long hdmi_vco_round_rate(struct clk *c, unsigned long rate)
+{
+	unsigned long rrate = rate;
+	struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
+
+	if (rate < vco->min_rate)
+		rrate = vco->min_rate;
+	if (rate > vco->max_rate)
+		rrate = vco->max_rate;
+
+	pr_debug("%s: rrate=%ld\n", __func__, rrate);
+
+	return rrate;
+}
+
+static int hdmi_vco_prepare(struct clk *c)
+{
+	struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
+	int ret = 0;
+
+	pr_debug("%s: rate=%ld\n", __func__, vco->rate);
+
+	if (!vco->rate_set && vco->rate)
+		ret = hdmi_vco_set_rate(c, vco->rate);
+
+	if (!ret)
+		ret = clk_prepare(mdss_ahb_clk);
+
+	return ret;
+}
+
+static void hdmi_vco_unprepare(struct clk *c)
+{
+	struct hdmi_pll_vco_clk *vco = to_hdmi_vco_clk(c);
+
+	vco->rate_set = false;
+
+	clk_unprepare(mdss_ahb_clk);
+}
+
+static int hdmi_pll_lock_status(void)
+{
+	u32 status;
+	int pll_locked = 0;
+	int rc;
+
+	rc = mdss_ahb_clk_enable(1);
+	if (rc) {
+		pr_err("%s: failed to enable mdss ahb clock. rc=%d\n",
+			__func__, rc);
+		return 0;
+	}
+	/* poll for PLL ready status */
+	if (readl_poll_timeout_noirq((hdmi_phy_base + HDMI_PHY_STATUS),
+			status, ((status & BIT(0)) == 1),
+			PLL_POLL_MAX_READS, PLL_POLL_TIMEOUT_US)) {
+		pr_debug("%s: HDMI PLL status=%x failed to Lock\n",
+				__func__, status);
+		pll_locked = 0;
+	} else {
+		pll_locked = 1;
+	}
+	mdss_ahb_clk_enable(0);
+
+	return pll_locked;
+}
+
+static enum handoff hdmi_vco_handoff(struct clk *c)
+{
+	enum handoff ret = HANDOFF_DISABLED_CLK;
+
+	if (hdmi_pll_lock_status()) {
+		c->rate = hdmi_vco_get_rate(c);
+		ret = HANDOFF_ENABLED_CLK;
+	}
+
+	pr_debug("%s: done, ret=%d\n", __func__, ret);
+	return ret;
+}
+
+static struct clk_ops hdmi_vco_clk_ops = {
+	.enable = hdmi_vco_enable,
+	.set_rate = hdmi_vco_set_rate,
+	.get_rate = hdmi_vco_get_rate,
+	.round_rate = hdmi_vco_round_rate,
+	.prepare = hdmi_vco_prepare,
+	.unprepare = hdmi_vco_unprepare,
+	.disable = hdmi_vco_disable,
+	.handoff = hdmi_vco_handoff,
+};
+
+static struct hdmi_pll_vco_clk hdmi_vco_clk = {
+	.min_rate = 600000000,
+	.max_rate = 1800000000,
+	.c = {
+		.dbg_name = "hdmi_vco_clk",
+		.ops = &hdmi_vco_clk_ops,
+		CLK_INIT(hdmi_vco_clk.c),
+	},
+};
+
+static struct div_clk hdmipll_div1_clk = {
+	.div = 1,
+	.c = {
+		.parent = &hdmi_vco_clk.c,
+		.dbg_name = "hdmipll_div1_clk",
+		.ops = &clk_ops_div,
+		.flags = CLKFLAG_NO_RATE_CACHE,
+		CLK_INIT(hdmipll_div1_clk.c),
+	},
+};
+
+static struct div_clk hdmipll_div2_clk = {
+	.div = 2,
+	.c = {
+		.parent = &hdmi_vco_clk.c,
+		.dbg_name = "hdmipll_div2_clk",
+		.ops = &clk_ops_div,
+		.flags = CLKFLAG_NO_RATE_CACHE,
+		CLK_INIT(hdmipll_div2_clk.c),
+	},
+};
+
+static struct div_clk hdmipll_div4_clk = {
+	.div = 4,
+	.c = {
+		.parent = &hdmi_vco_clk.c,
+		.dbg_name = "hdmipll_div4_clk",
+		.ops = &clk_ops_div,
+		.flags = CLKFLAG_NO_RATE_CACHE,
+		CLK_INIT(hdmipll_div4_clk.c),
+	},
+};
+
+static struct div_clk hdmipll_div6_clk = {
+	.div = 6,
+	.c = {
+		.parent = &hdmi_vco_clk.c,
+		.dbg_name = "hdmipll_div6_clk",
+		.ops = &clk_ops_div,
+		.flags = CLKFLAG_NO_RATE_CACHE,
+		CLK_INIT(hdmipll_div6_clk.c),
+	},
+};
+
+static int hdmipll_set_mux_sel(struct mux_clk *clk, int mux_sel)
+{
+	int rc;
+
+	if (!mdss_gdsc_enabled()) {
+		pr_err("%s: mdss GDSC is not enabled\n", __func__);
+		return -EPERM;
+	}
+
+	rc = clk_enable(mdss_ahb_clk);
+	if (rc) {
+		pr_err("%s: Failed to enable mdss ahb clock\n", __func__);
+		return rc;
+	}
+
+	pr_debug("%s: mux_sel=%d\n", __func__, mux_sel);
+	DSS_REG_W(hdmi_phy_pll_base, HDMI_UNI_PLL_POSTDIV1_CFG, mux_sel);
+
+	clk_disable(mdss_ahb_clk);
+
+	return 0;
+}
+
+static int hdmipll_get_mux_sel(struct mux_clk *clk)
+{
+	int mux_sel = 0;
+
+	if (mdss_ahb_clk_enable(1)) {
+		pr_err("%s: Failed to enable mdss ahb clock\n", __func__);
+		return mux_sel;
+	}
+
+	mux_sel = DSS_REG_R(hdmi_phy_pll_base, HDMI_UNI_PLL_POSTDIV1_CFG);
+	mux_sel &= 0x03;
+	pr_debug("%s: mux_sel=%d\n", __func__, mux_sel);
+
+	mdss_ahb_clk_enable(0);
+
+	return mux_sel;
+}
+
+static struct clk_mux_ops hdmipll_mux_ops = {
+	.set_mux_sel = hdmipll_set_mux_sel,
+	.get_mux_sel = hdmipll_get_mux_sel,
+};
+
+static struct clk_ops hdmi_mux_ops;
+
+static int hdmi_mux_prepare(struct clk *c)
+{
+	int ret = 0;
+
+	if (c && c->ops && c->ops->set_rate)
+		ret = c->ops->set_rate(c, c->rate);
+
+	return ret;
+}
+
+static struct mux_clk hdmipll_mux_clk = {
+	MUX_SRC_LIST(
+		{ &hdmipll_div1_clk.c, 0 },
+		{ &hdmipll_div2_clk.c, 1 },
+		{ &hdmipll_div4_clk.c, 2 },
+		{ &hdmipll_div6_clk.c, 3 },
+	),
+	.ops = &hdmipll_mux_ops,
+	.c = {
+		.parent = &hdmipll_div1_clk.c,
+		.dbg_name = "hdmipll_mux_clk",
+		.ops = &hdmi_mux_ops,
+		CLK_INIT(hdmipll_mux_clk.c),
+	},
+};
+
+struct div_clk hdmipll_clk_src = {
+	.div = 5,
+	.c = {
+		.parent = &hdmipll_mux_clk.c,
+		.dbg_name = "hdmipll_clk_src",
+		.ops = &clk_ops_div,
+		CLK_INIT(hdmipll_clk_src.c),
+	},
+};
+
 void __init mdss_clk_ctrl_pre_init(struct clk *ahb_clk)
 {
 	BUG_ON(ahb_clk == NULL);
@@ -1682,5 +2119,8 @@
 
 	byte_mux_clk_ops = clk_ops_gen_mux;
 	byte_mux_clk_ops.prepare = mux_prepare;
+
+	hdmi_mux_ops = clk_ops_gen_mux;
+	hdmi_mux_ops.prepare = hdmi_mux_prepare;
 }
 
diff --git a/arch/arm/mach-msm/clock-mdss-8974.h b/arch/arm/mach-msm/clock-mdss-8974.h
index 9fd3026..b1d5b45 100644
--- a/arch/arm/mach-msm/clock-mdss-8974.h
+++ b/arch/arm/mach-msm/clock-mdss-8974.h
@@ -22,9 +22,15 @@
 
 void mdss_clk_ctrl_pre_init(struct clk *ahb_clk);
 void mdss_clk_ctrl_post_init(void);
-int hdmi_pll_enable(void);
-void hdmi_pll_disable(void);
-int hdmi_pll_set_rate(unsigned long rate);
+
+struct hdmi_pll_vco_clk {
+	unsigned long rate;	/* current vco rate */
+	unsigned long min_rate;	/* min vco rate */
+	unsigned long max_rate;	/* max vco rate */
+	bool rate_set;
+
+	struct clk c;
+};
 
 struct lpfr_cfg {
 	unsigned long vco_rate;
@@ -57,4 +63,6 @@
 extern struct mux_clk byte_mux_8226;
 extern struct div_clk byte_clk_src_8226;
 
+extern struct div_clk hdmipll_clk_src;
+
 #endif
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
index 20e3c3b..174a50a 100644
--- a/arch/arm/mach-msm/hotplug.c
+++ b/arch/arm/mach-msm/hotplug.c
@@ -11,6 +11,7 @@
 #include <linux/errno.h>
 #include <linux/smp.h>
 #include <linux/cpu.h>
+#include <linux/ratelimit.h>
 
 #include <asm/cacheflush.h>
 #include <asm/smp_plat.h>
@@ -150,6 +151,29 @@
 	.notifier_call = hotplug_rtb_callback,
 };
 
+static int hotplug_cpu_check_callback(struct notifier_block *nfb,
+				      unsigned long action, void *hcpu)
+{
+	int cpu = (int)hcpu;
+
+	switch (action & (~CPU_TASKS_FROZEN)) {
+	case CPU_DOWN_PREPARE:
+		if (cpu == 0) {
+			pr_err_ratelimited("CPU0 hotplug is not supported\n");
+			return NOTIFY_BAD;
+		}
+		break;
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+static struct notifier_block hotplug_cpu_check_notifier = {
+	.notifier_call = hotplug_cpu_check_callback,
+	.priority = INT_MAX,
+};
+
 int msm_platform_secondary_init(unsigned int cpu)
 {
 	int ret;
@@ -170,6 +194,12 @@
 
 static int __init init_hotplug(void)
 {
-	return register_hotcpu_notifier(&hotplug_rtb_notifier);
+	int rc;
+
+	rc = register_hotcpu_notifier(&hotplug_rtb_notifier);
+	if (rc)
+		return rc;
+
+	return register_hotcpu_notifier(&hotplug_cpu_check_notifier);
 }
 early_initcall(init_hotplug);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
index 5fa7b1b..5bdd10a 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
@@ -1199,6 +1199,7 @@
 	case AUDIO_GET_STATS: {
 		struct msm_audio_stats stats;
 		uint64_t timestamp;
+		memset(&stats, 0, sizeof(struct msm_audio_stats));
 		stats.byte_count = atomic_read(&audio->in_bytes);
 		stats.sample_count = atomic_read(&audio->in_samples);
 		rc = q6asm_get_session_time(audio->ac, &timestamp);
diff --git a/arch/arm/mach-msm/qdsp6v2/q6audio_v2_aio.c b/arch/arm/mach-msm/qdsp6v2/q6audio_v2_aio.c
index 4681437..21040b1 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6audio_v2_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6audio_v2_aio.c
@@ -108,9 +108,7 @@
 		break;
 	case RESET_EVENTS:
 		pr_debug("%s: Received opcode:0x%x\n", __func__, opcode);
-		audio->event_abort = 1;
 		audio->stopped = 1;
-		audio->enabled = 0;
 		wake_up(&audio->event_wait);
 		break;
 	default:
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 921b80c..b64ada1 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -201,7 +201,7 @@
 					me->smmu.domain_id, 0);
 			buf->phys = 0;
 		}
-		if (buf->virt) {
+		if (!IS_ERR_OR_NULL(buf->virt)) {
 			ion_unmap_kernel(me->iclient, buf->handle);
 			buf->virt = 0;
 		}
@@ -214,7 +214,7 @@
 {
 	struct fastrpc_apps *me = &gfa;
 	if (!IS_ERR_OR_NULL(map->handle)) {
-		if (map->virt) {
+		if (!IS_ERR_OR_NULL(map->virt)) {
 			ion_unmap_kernel(me->iclient, map->handle);
 			map->virt = 0;
 		}
@@ -233,13 +233,15 @@
 	unsigned long len;
 	buf->handle = 0;
 	buf->virt = 0;
+	buf->phys = 0;
 	heap = me->smmu.enabled ? ION_HEAP(ION_IOMMU_HEAP_ID) :
 		ION_HEAP(ION_ADSP_HEAP_ID) | ION_HEAP(ION_AUDIO_HEAP_ID);
 	buf->handle = ion_alloc(clnt, buf->size, SZ_4K, heap, ION_FLAG_CACHED);
 	VERIFY(err, 0 == IS_ERR_OR_NULL(buf->handle));
 	if (err)
 		goto bail;
-	VERIFY(err, 0 != (buf->virt = ion_map_kernel(clnt, buf->handle)));
+	buf->virt = ion_map_kernel(clnt, buf->handle);
+	VERIFY(err, 0 == IS_ERR_OR_NULL(buf->virt));
 	if (err)
 		goto bail;
 	if (me->smmu.enabled) {
@@ -358,6 +360,9 @@
 		list[i].num = 0;
 		list[i].pgidx = 0;
 		len = pra[i].buf.len;
+		VERIFY(err, len >= 0);
+		if (err)
+			goto bail;
 		if (!len)
 			continue;
 		buf = pra[i].buf.pv;
@@ -843,7 +848,7 @@
 	context_free(ctx);
 
 	if (me->smmu.enabled) {
-		bufs = REMOTE_SCALARS_LENGTH(sc);
+		bufs = REMOTE_SCALARS_INBUFS(sc) + REMOTE_SCALARS_OUTBUFS(sc);
 		if (fds) {
 			handles = (struct ion_handle **)(fds + bufs);
 			for (i = 0; i < bufs; i++)
@@ -1019,7 +1024,8 @@
 	VERIFY(err, 0 == IS_ERR_OR_NULL(map->handle));
 	if (err)
 		goto bail;
-	VERIFY(err, 0 != (map->virt = ion_map_kernel(clnt, map->handle)));
+	map->virt = ion_map_kernel(clnt, map->handle);
+	VERIFY(err, 0 == IS_ERR_OR_NULL(map->virt));
 	if (err)
 		goto bail;
 	buf = (void *)mmap->vaddrin;
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index 91b90a8..4b6ca12 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -883,7 +883,7 @@
 	void *buf = driver->buf_event_mask_update;
 	int header_size = sizeof(struct diag_ctrl_event_mask);
 	int wr_size = -ENOMEM, retry_count = 0, timer;
-	int ret = DIAG_DCI_NO_ERROR;
+	int ret = DIAG_DCI_NO_ERROR, i;
 
 	mutex_lock(&driver->diag_cntl_mutex);
 	/* send event mask update */
@@ -891,8 +891,14 @@
 	driver->event_mask->data_len = 7 + DCI_EVENT_MASK_SIZE;
 	driver->event_mask->stream_id = DCI_MASK_STREAM;
 	driver->event_mask->status = 3; /* status for valid mask */
-	driver->event_mask->event_config = 1; /* event config */
+	driver->event_mask->event_config = 0; /* event config */
 	driver->event_mask->event_mask_size = DCI_EVENT_MASK_SIZE;
+	for (i = 0; i < DCI_EVENT_MASK_SIZE; i++) {
+		if (dci_cumulative_event_mask[i] != 0) {
+			driver->event_mask->event_config = 1;
+			break;
+		}
+	}
 	memcpy(buf, driver->event_mask, header_size);
 	memcpy(buf+header_size, dci_cumulative_event_mask, DCI_EVENT_MASK_SIZE);
 	if (ch) {
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 5be77c4..12dadb0 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -348,6 +348,7 @@
 	int separate_cmdrsp[NUM_SMD_CONTROL_CHANNELS];
 	unsigned char *usb_buf_out;
 	unsigned char *apps_rsp_buf;
+	unsigned char *user_space_data_buf;
 	/* buffer for updating mask to peripherals */
 	unsigned char *buf_msg_mask_update;
 	unsigned char *buf_log_mask_update;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index f7c0d24..ae92d170c 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -1609,22 +1609,15 @@
 		goto fail_free_hdlc;
 	}
 	if (pkt_type == USER_SPACE_DATA_TYPE) {
-		user_space_data = diagmem_alloc(driver, payload_size,
-								POOL_TYPE_USER);
-		if (!user_space_data) {
-			driver->dropped_count++;
-			return -ENOMEM;
-		}
-		err = copy_from_user(user_space_data, buf + 4,
+		err = copy_from_user(driver->user_space_data_buf, buf + 4,
 							 payload_size);
 		if (err) {
 			pr_err("diag: copy failed for user space data\n");
-			diagmem_free(driver, user_space_data, POOL_TYPE_USER);
-			user_space_data = NULL;
 			return -EIO;
 		}
 		/* Check for proc_type */
-		remote_proc = diag_get_remote(*(int *)user_space_data);
+		remote_proc =
+			diag_get_remote(*(int *)driver->user_space_data_buf);
 
 		if (remote_proc) {
 			token_offset = 4;
@@ -1634,12 +1627,9 @@
 
 		/* Check masks for On-Device logging */
 		if (driver->mask_check) {
-			if (!mask_request_validate(user_space_data +
+			if (!mask_request_validate(driver->user_space_data_buf +
 							 token_offset)) {
 				pr_alert("diag: mask request Invalid\n");
-				diagmem_free(driver, user_space_data,
-							POOL_TYPE_USER);
-				user_space_data = NULL;
 				return -EFAULT;
 			}
 		}
@@ -1647,7 +1637,7 @@
 #ifdef DIAG_DEBUG
 		pr_debug("diag: user space data %d\n", payload_size);
 		for (i = 0; i < payload_size; i++)
-			pr_debug("\t %x", *((user_space_data
+			pr_debug("\t %x", *((driver->user_space_data_buf
 						+ token_offset)+i));
 #endif
 #ifdef CONFIG_DIAG_SDIO_PIPE
@@ -1658,7 +1648,7 @@
 					 payload_size));
 			if (driver->sdio_ch && (payload_size > 0)) {
 				sdio_write(driver->sdio_ch, (void *)
-				   (user_space_data + token_offset),
+				   (driver->user_space_data_buf + token_offset),
 				   payload_size);
 			}
 		}
@@ -1689,8 +1679,8 @@
 				diag_hsic[index].in_busy_hsic_read_on_device =
 									0;
 				err = diag_bridge_write(index,
-						user_space_data + token_offset,
-						payload_size);
+						driver->user_space_data_buf +
+						token_offset, payload_size);
 				if (err) {
 					pr_err("diag: err sending mask to MDM: %d\n",
 					       err);
@@ -1711,14 +1701,12 @@
 						&& driver->lcid) {
 			if (payload_size > 0) {
 				err = msm_smux_write(driver->lcid, NULL,
-					user_space_data + token_offset,
+					driver->user_space_data_buf +
+						token_offset,
 					payload_size);
 				if (err) {
 					pr_err("diag:send mask to MDM err %d",
 							err);
-					diagmem_free(driver, user_space_data,
-								POOL_TYPE_USER);
-					user_space_data = NULL;
 					return err;
 				}
 			}
@@ -1727,9 +1715,8 @@
 		/* send masks to 8k now */
 		if (!remote_proc)
 			diag_process_hdlc((void *)
-				(user_space_data + token_offset), payload_size);
-		diagmem_free(driver, user_space_data, POOL_TYPE_USER);
-		user_space_data = NULL;
+				(driver->user_space_data_buf + token_offset),
+					payload_size);
 		return 0;
 	}
 
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 447cb39..395bea0 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -2520,6 +2520,12 @@
 	    && (driver->hdlc_buf = kzalloc(HDLC_MAX, GFP_KERNEL)) == NULL)
 		goto err;
 	kmemleak_not_leak(driver->hdlc_buf);
+	if (driver->user_space_data_buf == NULL)
+		driver->user_space_data_buf = kzalloc(USER_SPACE_DATA,
+							GFP_KERNEL);
+	if (driver->user_space_data_buf == NULL)
+		goto err;
+	kmemleak_not_leak(driver->user_space_data_buf);
 	if (driver->client_map == NULL &&
 	    (driver->client_map = kzalloc
 	     ((driver->num_clients) * sizeof(struct diag_client_map),
@@ -2607,6 +2613,7 @@
 	kfree(driver->pkt_buf);
 	kfree(driver->usb_read_ptr);
 	kfree(driver->apps_rsp_buf);
+	kfree(driver->user_space_data_buf);
 	if (driver->diag_wq)
 		destroy_workqueue(driver->diag_wq);
 }
@@ -2646,5 +2653,6 @@
 	kfree(driver->pkt_buf);
 	kfree(driver->usb_read_ptr);
 	kfree(driver->apps_rsp_buf);
+	kfree(driver->user_space_data_buf);
 	destroy_workqueue(driver->diag_wq);
 }
diff --git a/drivers/char/hw_random/msm_rng.c b/drivers/char/hw_random/msm_rng.c
index 369477f..4118a7a 100644
--- a/drivers/char/hw_random/msm_rng.c
+++ b/drivers/char/hw_random/msm_rng.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -25,6 +25,9 @@
 #include <mach/msm_iomap.h>
 #include <mach/socinfo.h>
 #include <mach/msm_bus.h>
+#include <linux/qrng.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
 
 #define DRIVER_NAME "msm_rng"
 
@@ -51,6 +54,29 @@
 	uint32_t qrng_perf_client;
 };
 
+struct msm_rng_device msm_rng_device_info;
+
+static long msm_rng_ioctl(struct file *filp, unsigned int cmd,
+				unsigned long arg)
+{
+	long ret = 0;
+
+	pr_debug("ioctl: cmd = %d\n", cmd);
+	switch (cmd) {
+	case QRNG_IOCTL_RESET_BUS_BANDWIDTH:
+		pr_info("calling msm_rng_bus_scale(LOW)\n");
+		ret = msm_bus_scale_client_update_request(
+				msm_rng_device_info.qrng_perf_client, 0);
+		if (ret)
+			pr_err("failed qrng_reset_bus_bw, ret = %ld\n", ret);
+		break;
+	default:
+		pr_err("Unsupported IOCTL call");
+		break;
+	}
+	return ret;
+}
+
 static int msm_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
 {
 	struct msm_rng_device *msm_rng_dev;
@@ -79,12 +105,6 @@
 		dev_err(&pdev->dev, "failed to enable clock in callback\n");
 		return 0;
 	}
-	if (msm_rng_dev->qrng_perf_client) {
-		ret = msm_bus_scale_client_update_request(
-					msm_rng_dev->qrng_perf_client, 1);
-		if (ret)
-			pr_err("bus_scale_client_update_req failed!\n");
-	}
 	/* read random data from h/w */
 	do {
 		/* check status bit if data is available */
@@ -104,9 +124,6 @@
 		if ((maxsize - currsize) < 4)
 			break;
 	} while (currsize < maxsize);
-	if (msm_rng_dev->qrng_perf_client)
-		ret = msm_bus_scale_client_update_request(
-					msm_rng_dev->qrng_perf_client, 0);
 	/* vote to turn off clock */
 	clk_disable_unprepare(msm_rng_dev->prng_clk);
 
@@ -161,19 +178,24 @@
 		mb();
 	}
 	clk_disable_unprepare(msm_rng_dev->prng_clk);
-	if (msm_rng_dev->qrng_perf_client)
-		ret = msm_bus_scale_client_update_request(
-					msm_rng_dev->qrng_perf_client, 0);
-
 	return 0;
 }
 
+static const struct file_operations msm_rng_fops = {
+	.unlocked_ioctl = msm_rng_ioctl,
+};
+static struct class *msm_rng_class;
+static struct cdev msm_rng_cdev;
+
 static int __devinit msm_rng_probe(struct platform_device *pdev)
 {
 	struct resource *res;
 	struct msm_rng_device *msm_rng_dev = NULL;
 	void __iomem *base = NULL;
 	int error = 0;
+	int ret = 0;
+	struct device *dev;
+
 	struct msm_bus_scale_pdata *qrng_platform_support = NULL;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -220,6 +242,8 @@
 		qrng_platform_support = msm_bus_cl_get_pdata(pdev);
 		msm_rng_dev->qrng_perf_client = msm_bus_scale_register_client(
 						qrng_platform_support);
+		msm_rng_device_info.qrng_perf_client =
+					msm_rng_dev->qrng_perf_client;
 		if (!msm_rng_dev->qrng_perf_client)
 			pr_err("Unable to register bus client\n");
 	}
@@ -238,9 +262,27 @@
 		error = -EPERM;
 		goto rollback_clk;
 	}
+	ret = register_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME, &msm_rng_fops);
 
-	return 0;
+	msm_rng_class = class_create(THIS_MODULE, "msm-rng");
+	if (IS_ERR(msm_rng_class)) {
+		pr_err("class_create failed\n");
+		return PTR_ERR(msm_rng_class);
+	}
 
+	dev = device_create(msm_rng_class, NULL, MKDEV(QRNG_IOC_MAGIC, 0),
+				NULL, "msm-rng");
+	if (IS_ERR(dev)) {
+		pr_err("Device create failed\n");
+		error = PTR_ERR(dev);
+		goto unregister_chrdev;
+	}
+	cdev_init(&msm_rng_cdev, &msm_rng_fops);
+
+	return ret;
+
+unregister_chrdev:
+	unregister_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME);
 rollback_clk:
 	clk_put(msm_rng_dev->prng_clk);
 err_clk_get:
@@ -254,7 +296,7 @@
 static int __devexit msm_rng_remove(struct platform_device *pdev)
 {
 	struct msm_rng_device *msm_rng_dev = platform_get_drvdata(pdev);
-
+	unregister_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME);
 	hwrng_unregister(&msm_rng);
 	clk_put(msm_rng_dev->prng_clk);
 	iounmap(msm_rng_dev->base);
diff --git a/drivers/hwmon/qpnp-adc-current.c b/drivers/hwmon/qpnp-adc-current.c
index adaff41..9839595 100644
--- a/drivers/hwmon/qpnp-adc-current.c
+++ b/drivers/hwmon/qpnp-adc-current.c
@@ -147,7 +147,6 @@
 	struct list_head			list;
 	int64_t					die_temp;
 	struct delayed_work			iadc_work;
-	struct mutex				iadc_vadc_lock;
 	bool					iadc_mode_sel;
 	struct qpnp_iadc_comp			iadc_comp;
 	struct qpnp_vadc_chip			*vadc_dev;
@@ -1012,12 +1011,10 @@
 	if (qpnp_iadc_is_valid(iadc) < 0)
 		return -EPROBE_DEFER;
 
-	if (!iadc->iadc_mode_sel) {
-		rc = qpnp_check_pmic_temp(iadc);
-		if (rc) {
-			pr_err("Error checking pmic therm temp\n");
-			return rc;
-		}
+	rc = qpnp_check_pmic_temp(iadc);
+	if (rc) {
+		pr_err("Error checking pmic therm temp\n");
+		return rc;
 	}
 
 	mutex_lock(&iadc->adc->adc_lock);
@@ -1121,24 +1118,21 @@
 	enum qpnp_iadc_channels i_channel, struct qpnp_iadc_result *i_result,
 	enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result)
 {
-	int rc = 0;
+	int rc = 0, mode_sel = 0, num = 0, rsense_n_ohms = 0, sign = 0;
+	uint16_t raw_data;
+	int32_t rsense_u_ohms = 0;
+	int64_t result_current;
 
 	if (qpnp_iadc_is_valid(iadc) < 0)
 		return -EPROBE_DEFER;
 
-	mutex_lock(&iadc->iadc_vadc_lock);
+	mutex_lock(&iadc->adc->adc_lock);
 
 	if (iadc->iadc_poll_eoc) {
 		pr_debug("acquiring iadc eoc wakelock\n");
 		pm_stay_awake(iadc->dev);
 	}
 
-	rc = qpnp_check_pmic_temp(iadc);
-	if (rc) {
-		pr_err("PMIC die temp check failed\n");
-		goto fail;
-	}
-
 	iadc->iadc_mode_sel = true;
 
 	rc = qpnp_vadc_iadc_sync_request(iadc->vadc_dev, v_channel);
@@ -1147,11 +1141,43 @@
 		goto fail;
 	}
 
-	rc = qpnp_iadc_read(iadc, i_channel, i_result);
-	if (rc)
-		pr_err("Configuring IADC failed\n");
-	/* Intentional fall through to release VADC */
+	rc = qpnp_iadc_configure(iadc, i_channel, &raw_data, mode_sel);
+	if (rc < 0) {
+		pr_err("qpnp adc result read failed with %d\n", rc);
+		goto fail_release_vadc;
+	}
 
+	rc = qpnp_iadc_get_rsense(iadc, &rsense_n_ohms);
+	pr_debug("current raw:0%x and rsense:%d\n",
+			raw_data, rsense_n_ohms);
+	rsense_u_ohms = rsense_n_ohms/1000;
+	num = raw_data - iadc->adc->calib.offset_raw;
+	if (num < 0) {
+		sign = 1;
+		num = -num;
+	}
+
+	i_result->result_uv = (num * QPNP_ADC_GAIN_NV)/
+		(iadc->adc->calib.gain_raw - iadc->adc->calib.offset_raw);
+	result_current = i_result->result_uv;
+	result_current *= QPNP_IADC_NANO_VOLTS_FACTOR;
+	/* Intentional fall through. Process the result w/o comp */
+	do_div(result_current, rsense_u_ohms);
+
+	if (sign) {
+		i_result->result_uv = -i_result->result_uv;
+		result_current = -result_current;
+	}
+	result_current *= -1;
+	rc = qpnp_iadc_comp_result(iadc, &result_current);
+	if (rc < 0)
+		pr_err("Error during compensating the IADC\n");
+	rc = 0;
+	result_current *= -1;
+
+	i_result->result_ua = (int32_t) result_current;
+
+fail_release_vadc:
 	rc = qpnp_vadc_iadc_sync_complete_request(iadc->vadc_dev, v_channel,
 							v_result);
 	if (rc)
@@ -1163,7 +1189,7 @@
 		pr_debug("releasing iadc eoc wakelock\n");
 		pm_relax(iadc->dev);
 	}
-	mutex_unlock(&iadc->iadc_vadc_lock);
+	mutex_unlock(&iadc->adc->adc_lock);
 
 	return rc;
 }
@@ -1306,7 +1332,6 @@
 		goto fail;
 	}
 
-	mutex_init(&iadc->iadc_vadc_lock);
 	INIT_WORK(&iadc->trigger_completion_work, qpnp_iadc_trigger_completion);
 	INIT_DELAYED_WORK(&iadc->iadc_work, qpnp_iadc_work);
 	rc = qpnp_iadc_comp_info(iadc);
@@ -1347,7 +1372,6 @@
 	int i = 0;
 
 	cancel_delayed_work(&iadc->iadc_work);
-	mutex_destroy(&iadc->iadc_vadc_lock);
 	for_each_child_of_node(node, child) {
 		device_remove_file(&spmi->dev,
 			&iadc->sens_attr[i].dev_attr);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
index a8da26d..f5529cd 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
@@ -620,7 +620,10 @@
 		msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x1E0);
 		vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
 	} else if (update_state == DISABLE_CAMIF_IMMEDIATELY) {
-		msm_camera_io_w_mb(0x2, vfe_dev->vfe_base + 0x1E0);
+		msm_camera_io_w_mb(0x6, vfe_dev->vfe_base + 0x1E0);
+		vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev);
+		vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev);
+		vfe_dev->hw_info->vfe_ops.core_ops.init_hw_reg(vfe_dev);
 		vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
 	}
 }
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index 9047c40..50a25bd 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -866,7 +866,10 @@
 		msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x2F4);
 		vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
 	} else if (update_state == DISABLE_CAMIF_IMMEDIATELY) {
-		msm_camera_io_w_mb(0x2, vfe_dev->vfe_base + 0x2F4);
+		msm_camera_io_w_mb(0x6, vfe_dev->vfe_base + 0x2F4);
+		vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev);
+		vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev);
+		vfe_dev->hw_info->vfe_ops.core_ops.init_hw_reg(vfe_dev);
 		vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0;
 	}
 }
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index 9c92a7b..3202cdb 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -318,7 +318,8 @@
 				stream_info->state == PAUSED ||
 				stream_info->state == RESUME_PENDING ||
 				stream_info->state == RESUMING) &&
-				stream_cfg_cmd->cmd == STOP_STREAM) {
+				(stream_cfg_cmd->cmd == STOP_STREAM ||
+				stream_cfg_cmd->cmd == STOP_IMMEDIATELY)) {
 				stream_info->state = ACTIVE;
 			} else {
 				pr_err("%s: Invalid stream state: %d\n",
@@ -654,7 +655,9 @@
 		}
 	}
 
-	if (vfe_dev->axi_data.pipeline_update == DISABLE_CAMIF) {
+	if (vfe_dev->axi_data.pipeline_update == DISABLE_CAMIF ||
+		(vfe_dev->axi_data.pipeline_update ==
+		DISABLE_CAMIF_IMMEDIATELY)) {
 		vfe_dev->hw_info->vfe_ops.stats_ops.
 			enable_module(vfe_dev, 0xFF, 0);
 		vfe_dev->axi_data.pipeline_update = NO_UPDATE;
@@ -865,6 +868,10 @@
 			(cur_pix_stream_cnt - pix_stream_cnt) == 0 &&
 			stream_cfg_cmd->cmd == STOP_STREAM)
 			return DISABLE_CAMIF;
+		else if (cur_pix_stream_cnt &&
+			(cur_pix_stream_cnt - pix_stream_cnt) == 0 &&
+			stream_cfg_cmd->cmd == STOP_IMMEDIATELY)
+			return DISABLE_CAMIF_IMMEDIATELY;
 	}
 	return NO_UPDATE;
 }
@@ -1176,6 +1183,9 @@
 	if (camif_update == DISABLE_CAMIF)
 		vfe_dev->hw_info->vfe_ops.core_ops.
 			update_camif_state(vfe_dev, DISABLE_CAMIF);
+	else if (camif_update == DISABLE_CAMIF_IMMEDIATELY)
+		vfe_dev->hw_info->vfe_ops.core_ops.
+			update_camif_state(vfe_dev, DISABLE_CAMIF_IMMEDIATELY);
 	msm_isp_update_camif_output_count(vfe_dev, stream_cfg_cmd);
 
 	for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_common.h b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_common.h
index 04af6b6..634beca 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_common.h
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -20,7 +20,7 @@
 #endif
 
 #define JPEG_PR_ERR   pr_err
-#define JPEG_DBG_HIGH   pr_err
+#define JPEG_DBG_HIGH   pr_debug
 
 enum JPEG_MODE {
 	JPEG_MODE_DISABLE,
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c
index 5d34265..44a4014 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c
@@ -216,15 +216,15 @@
 	if (pingpong_index == 0) {
 		hw_cmd_p = &hw_cmd_we_ping_update[0];
 		hw_cmd_p->data = p_input->y_buffer_addr;
-		JPEG_PR_ERR("%s Output pln0 buffer address is %x\n", __func__,
+		JPEG_DBG_HIGH("%s Output pln0 buffer address is %x\n", __func__,
 			p_input->y_buffer_addr);
 		msm_jpeg_hw_write(hw_cmd_p++, base);
 		hw_cmd_p->data = p_input->cbcr_buffer_addr;
-		JPEG_PR_ERR("%s Output pln1 buffer address is %x\n", __func__,
+		JPEG_DBG_HIGH("%s Output pln1 buffer address is %x\n", __func__,
 			p_input->cbcr_buffer_addr);
 		msm_jpeg_hw_write(hw_cmd_p++, base);
 		hw_cmd_p->data = p_input->pln2_addr;
-		JPEG_PR_ERR("%s Output pln2 buffer address is %x\n", __func__,
+		JPEG_DBG_HIGH("%s Output pln2 buffer address is %x\n", __func__,
 			p_input->pln2_addr);
 		msm_jpeg_hw_write(hw_cmd_p++, base);
 	}
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
index d6fa2b0..8f080ce 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.c
@@ -28,6 +28,19 @@
 #include "msm_jpeg_common.h"
 #include "msm_jpeg_hw.h"
 
+int msm_jpeg_platform_set_clk_rate(struct msm_jpeg_device *pgmn_dev,
+		long clk_rate)
+{
+	struct msm_cam_clk_info jpeg_core_clk_info[] = {
+		{"core_clk", JPEG_CLK_RATE, 0}
+	};
+
+	jpeg_core_clk_info[0].clk_rate = clk_rate;
+
+	return msm_cam_clk_enable(&pgmn_dev->pdev->dev, jpeg_core_clk_info,
+			pgmn_dev->jpeg_clk, ARRAY_SIZE(jpeg_core_clk_info), 1);
+}
+
 void msm_jpeg_platform_p2v(struct msm_jpeg_device *pgmn_dev, struct file  *file,
 	struct ion_handle **ionhandle, int domain_num)
 {
@@ -135,8 +148,8 @@
 	{
 		.src = MSM_BUS_MASTER_JPEG,
 		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab  = JPEG_CLK_RATE * 2.5,
-		.ib  = JPEG_CLK_RATE * 2.5,
+		.ab  = JPEG_MAX_CLK_RATE * 2.5,
+		.ib  = JPEG_MAX_CLK_RATE * 2.5,
 	},
 };
 
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.h b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.h
index a14b8ee..7be9e19 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.h
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_platform.h
@@ -20,7 +20,10 @@
 #include <mach/iommu.h>
 #include "msm_jpeg_sync.h"
 #define JPEG_CLK_RATE 266670000
+#define JPEG_MAX_CLK_RATE 320000000
 
+int msm_jpeg_platform_set_clk_rate(struct msm_jpeg_device *pgmn_dev,
+		long clk_rate);
 void msm_jpeg_platform_p2v(struct msm_jpeg_device *pgmn_dev, struct file *file,
 	struct ion_handle **ionhandle, int domain_num);
 uint32_t msm_jpeg_platform_v2p(struct msm_jpeg_device *pgmn_dev, int fd,
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
index dffdab3..5cc51ff 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
@@ -806,6 +806,36 @@
 	return 0;
 }
 
+int msm_jpeg_ioctl_set_clk_rate(struct msm_jpeg_device *pgmn_dev,
+	unsigned long arg)
+{
+	long clk_rate;
+	int rc;
+
+	if ((pgmn_dev->state != MSM_JPEG_INIT) &&
+		(pgmn_dev->state != MSM_JPEG_RESET)) {
+		JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+	if (get_user(clk_rate, (long __user *)arg)) {
+		JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+	JPEG_DBG("%s:%d] Requested clk rate %ld\n", __func__, __LINE__,
+		clk_rate);
+	if (clk_rate < 0) {
+		JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
+		return -EFAULT;
+	}
+	rc = msm_jpeg_platform_set_clk_rate(pgmn_dev, clk_rate);
+	if (rc < 0) {
+		JPEG_PR_ERR("%s: clk failed rc = %d\n", __func__, rc);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
 long __msm_jpeg_ioctl(struct msm_jpeg_device *pgmn_dev,
 	unsigned int cmd, unsigned long arg)
 {
@@ -875,6 +905,9 @@
 		rc = msm_jpeg_ioctl_test_dump_region(pgmn_dev, arg);
 		break;
 
+	case MSM_JPEG_IOCTL_SET_CLK_RATE:
+		rc = msm_jpeg_ioctl_set_clk_rate(pgmn_dev, arg);
+		break;
 	default:
 		JPEG_PR_ERR(KERN_INFO "%s:%d] cmd = %d not supported\n",
 			__func__, __LINE__, _IOC_NR(cmd));
diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c
index 5140a03..9604a09 100644
--- a/drivers/media/platform/msm/vidc/msm_smem.c
+++ b/drivers/media/platform/msm/vidc/msm_smem.c
@@ -171,8 +171,10 @@
 	mem->smem_priv = hndl;
 	mem->device_addr = iova;
 	mem->size = buffer_size;
-	dprintk(VIDC_DBG, "NOTE: Buffer device address: 0x%lx, size: %d\n",
-		mem->device_addr, mem->size);
+	dprintk(VIDC_DBG,
+		"%s: ion_handle = 0x%p, fd = %d, device_addr = 0x%x, size = %d, kvaddr = 0x%p, buffer_type = %d\n",
+		__func__, mem->smem_priv, fd, (u32)mem->device_addr,
+		mem->size, mem->kvaddr, mem->buffer_type);
 	return rc;
 fail_device_address:
 	ion_free(client->clnt, hndl);
@@ -241,10 +243,11 @@
 		goto fail_device_address;
 	}
 	mem->device_addr = iova;
-	dprintk(VIDC_DBG,
-		"device_address = 0x%lx, kvaddr = 0x%p, size = %d\n",
-		mem->device_addr, mem->kvaddr, size);
 	mem->size = size;
+	dprintk(VIDC_DBG,
+		"%s: ion_handle = 0x%p, device_addr = 0x%x, size = %d, kvaddr = 0x%p, buffer_type = %d\n",
+		__func__, mem->smem_priv, (u32)mem->device_addr,
+		mem->size, mem->kvaddr, mem->buffer_type);
 	return rc;
 fail_device_address:
 	ion_unmap_kernel(client->clnt, hndl);
@@ -258,6 +261,10 @@
 {
 	int domain, partition, rc;
 
+	dprintk(VIDC_DBG,
+		"%s: ion_handle = 0x%p, device_addr = 0x%x, size = %d, kvaddr = 0x%p, buffer_type = %d\n",
+		__func__, mem->smem_priv, (u32)mem->device_addr,
+		mem->size, mem->kvaddr, mem->buffer_type);
 	rc = msm_smem_get_domain_partition((void *)client, mem->flags,
 			mem->buffer_type, &domain, &partition);
 	if (rc) {
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index efa195e..9dd4e93 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -971,6 +971,14 @@
 			rc = -EINVAL;
 			goto err_invalid_fmt;
 		}
+		if (!(get_hal_codec_type(fmt->fourcc) &
+			inst->core->dec_codec_supported)) {
+			dprintk(VIDC_ERR,
+				"Codec(0x%x) not supported\n",
+				get_hal_codec_type(fmt->fourcc));
+			rc = -EINVAL;
+			goto err_invalid_fmt;
+		}
 		inst->fmts[fmt->type] = fmt;
 		rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
 		if (rc) {
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 25917c1..3c18241 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -489,6 +489,7 @@
 			temp->handle[plane]->device_addr + binfo->buff_off[i];
 			b->m.planes[i].m.userptr = binfo->device_addr[i];
 			binfo->mapped[i] = false;
+			binfo->handle[i] = temp->handle[i];
 		} else {
 			if (inst->map_output_buffer) {
 				binfo->handle[i] =
@@ -498,9 +499,6 @@
 					rc = -EINVAL;
 					goto exit;
 				}
-				dprintk(VIDC_DBG,
-					"[MAP] - mapped handle[%d] = %p fd[%d] = %d",
-					i, binfo->handle[i], i, binfo->fd[i]);
 				binfo->mapped[i] = true;
 				binfo->device_addr[i] =
 					binfo->handle[i]->device_addr +
@@ -511,10 +509,6 @@
 				binfo->device_addr[i] =
 					b->m.planes[i].m.userptr;
 			}
-			dprintk(VIDC_DBG, "Registering buffer: %d, %d, %d\n",
-					b->m.planes[i].reserved[0],
-					b->m.planes[i].reserved[1],
-					b->m.planes[i].length);
 		}
 		/* We maintain one ref count for all planes*/
 		if ((i == 0) && is_dynamic_output_buffer_mode(b, inst)) {
@@ -522,8 +516,12 @@
 			if (rc < 0)
 				return rc;
 		}
+		dprintk(VIDC_DBG,
+			"%s: [MAP] binfo = %p, handle[%d] = %p, device_addr = 0x%x, fd = %d, offset = %d, mapped = %d\n",
+			__func__, binfo, i, binfo->handle[i],
+			binfo->device_addr[i], binfo->fd[i],
+			binfo->buff_off[i], binfo->mapped[i]);
 	}
-	dprintk(VIDC_DBG, "[MAP] Adding binfo = %p to list\n", binfo);
 	mutex_lock(&inst->lock);
 	list_add_tail(&binfo->list, &inst->registered_bufs);
 	mutex_unlock(&inst->lock);
@@ -570,6 +568,11 @@
 		goto exit;
 
 	for (i = 0; i < temp->num_planes; i++) {
+		dprintk(VIDC_DBG,
+			"%s: [UNMAP] binfo = %p, handle[%d] = %p, device_addr = 0x%x, fd = %d, offset = %d, mapped = %d\n",
+			__func__, temp, i, temp->handle[i],
+			temp->device_addr[i], temp->fd[i],
+			temp->buff_off[i], temp->mapped[i]);
 		/*
 		* Unmap the handle only if the buffer has been mapped and no
 		* other buffer has a reference to this buffer.
@@ -581,9 +584,6 @@
 		*/
 		if (temp->handle[i] && temp->mapped[i] &&
 			!temp->same_fd_ref[i]) {
-			dprintk(VIDC_DBG,
-				"[UNMAP] - handle[%d] = %p fd[%d] = %d",
-				i, temp->handle[i], i, temp->fd[i]);
 			msm_comm_smem_free(inst,
 				temp->handle[i]);
 		}
@@ -668,7 +668,8 @@
 					__func__, rc);
 				return -EINVAL;
 			}
-		}
+		} else
+			dprintk(VIDC_ERR, "%s: WARN: NULL handle", __func__);
 	}
 	return 0;
 }
@@ -742,11 +743,18 @@
 					buffer_info.m.planes[0].reserved[0],
 					buffer_info.m.planes[0].reserved[1],
 					buffer_info.m.planes[0].length);
+
 			list_del(&bi->list);
 			for (i = 0; i < bi->num_planes; i++) {
-				if (bi->handle[i])
+				if (bi->handle[i] && bi->mapped[i]) {
+					dprintk(VIDC_DBG,
+						"%s: [UNMAP] binfo = %p, handle[%d] = %p, device_addr = 0x%x, fd = %d, offset = %d, mapped = %d\n",
+						__func__, bi, i, bi->handle[i],
+						bi->device_addr[i], bi->fd[i],
+						bi->buff_off[i], bi->mapped[i]);
 					msm_comm_smem_free(inst,
 							bi->handle[i]);
+				}
 			}
 			kfree(bi);
 		}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 239bc34..3eb5f49 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -277,14 +277,17 @@
 		dprintk(VIDC_ERR, "Wrong device_id received\n");
 		return;
 	}
-	dprintk(VIDC_DBG, "index = %d\n", index);
-	dprintk(VIDC_DBG, "ptr = %p\n", &(core->completions[index]));
-	complete(&(core->completions[index]));
 	sys_init_msg = response->data;
 	if (!sys_init_msg) {
 		dprintk(VIDC_ERR, "sys_init_done message not proper\n");
 		return;
 	}
+	core->enc_codec_supported = sys_init_msg->enc_codec_supported;
+	core->dec_codec_supported = sys_init_msg->dec_codec_supported;
+	dprintk(VIDC_DBG, "supported_codecs: enc = 0x%x, dec = 0x%x\n",
+		core->enc_codec_supported, core->dec_codec_supported);
+	dprintk(VIDC_DBG, "ptr[%d] = %p\n", index, &(core->completions[index]));
+	complete(&(core->completions[index]));
 }
 
 static void handle_session_release_buf_done(enum command_response cmd,
@@ -941,6 +944,12 @@
 					V4L2_QCOM_BUF_DATA_CORRUPT;
 			}
 		}
+		dprintk(VIDC_DBG,
+			"Got ebd from hal: device_addr: 0x%x, alloc: %d, status: 0x%x, pic_type: 0x%x, flags: 0x%x\n",
+			(u32)empty_buf_done->packet_buffer,
+			empty_buf_done->alloc_len, empty_buf_done->status,
+			empty_buf_done->picture_type, empty_buf_done->flags);
+
 		mutex_lock(&inst->bufq[OUTPUT_PORT].lock);
 		vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
 		mutex_unlock(&inst->bufq[OUTPUT_PORT].lock);
@@ -1099,6 +1108,7 @@
 	struct vb2_buffer *vb = NULL;
 	struct vidc_hal_fbd *fill_buf_done;
 	enum hal_buffer buffer_type;
+	int64_t time_usec = 0;
 
 	if (!response) {
 		dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
@@ -1138,7 +1148,7 @@
 		if (!(fill_buf_done->flags1 &
 			HAL_BUFFERFLAG_TIMESTAMPINVALID) &&
 			fill_buf_done->filled_len1) {
-			int64_t time_usec = fill_buf_done->timestamp_hi;
+			time_usec = fill_buf_done->timestamp_hi;
 			time_usec = (time_usec << 32) |
 				fill_buf_done->timestamp_lo;
 			vb->v4l2_buf.timestamp =
@@ -1191,10 +1201,14 @@
 			msm_vidc_debugfs_update(inst,
 				MSM_VIDC_DEBUGFS_EVENT_FBD);
 
-		dprintk(VIDC_DBG, "Filled length = %d; offset = %d; flags %x\n",
-				vb->v4l2_planes[0].bytesused,
-				vb->v4l2_planes[0].data_offset,
-				vb->v4l2_buf.flags);
+		dprintk(VIDC_DBG,
+		"Got fbd from hal: device_addr: 0x%x, alloc: %d, filled: %d, offset: %d, ts: %lld, flags: 0x%x, crop: %d %d %d %d, pic_type: 0x%x\n",
+		(u32)fill_buf_done->packet_buffer1, fill_buf_done->alloc_len1,
+		fill_buf_done->filled_len1, fill_buf_done->offset1, time_usec,
+		fill_buf_done->flags1, fill_buf_done->start_x_coord,
+		fill_buf_done->start_y_coord, fill_buf_done->frame_width,
+		fill_buf_done->frame_height, fill_buf_done->picture_type);
+
 		mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
 		vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
 		mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
@@ -1598,7 +1612,7 @@
 	return domain;
 }
 
-static enum hal_video_codec get_hal_codec_type(int fourcc)
+enum hal_video_codec get_hal_codec_type(int fourcc)
 {
 	enum hal_video_codec codec;
 	dprintk(VIDC_DBG, "codec is 0x%x", fourcc);
@@ -2430,11 +2444,10 @@
 				V4L2_QCOM_BUF_TIMESTAMP_INVALID)
 				frame_data.timestamp = LLONG_MAX;
 			dprintk(VIDC_DBG,
-				"Sending etb to hal: device_addr: 0x%x"
-				"Alloc: %d, filled: %d, offset: %d\n",
-				frame_data.device_addr,
-				frame_data.alloc_len, frame_data.filled_len,
-				frame_data.offset);
+				"Sending etb to hal: device_addr: 0x%x, alloc: %d, filled: %d, offset: %d, ts: %lld, flags = 0x%x\n",
+				frame_data.device_addr, frame_data.alloc_len,
+				frame_data.filled_len, frame_data.offset,
+				frame_data.timestamp, frame_data.flags);
 			rc = call_hfi_op(hdev, session_etb, (void *)
 					inst->session, &frame_data);
 			if (!rc)
@@ -2456,11 +2469,10 @@
 				frame_data.extradata_addr =
 					vb->v4l2_planes[extra_idx].m.userptr;
 			dprintk(VIDC_DBG,
-				"Sending ftb to hal: Alloc: %d :filled: %d",
-				frame_data.alloc_len, frame_data.filled_len);
-			dprintk(VIDC_DBG,
-				" extradata_addr: %d\n",
-				frame_data.extradata_addr);
+				"Sending ftb to hal: device_addr: 0x%x, alloc: %d, buffer_type: %d, ts: %lld, flags = 0x%x\n",
+				frame_data.device_addr, frame_data.alloc_len,
+				frame_data.buffer_type, frame_data.timestamp,
+				frame_data.flags);
 			if (!inst->ftb_count &&
 			   inst->session_type == MSM_VIDC_ENCODER) {
 				seq_hdr.seq_hdr = (u8 *) vb->v4l2_planes[0].
@@ -2476,9 +2488,9 @@
 			} else {
 				rc = call_hfi_op(hdev, session_ftb,
 					(void *) inst->session, &frame_data);
-			if (!rc)
-				msm_vidc_debugfs_update(inst,
-					MSM_VIDC_DEBUGFS_EVENT_FTB);
+				if (!rc)
+					msm_vidc_debugfs_update(inst,
+						MSM_VIDC_DEBUGFS_EVENT_FTB);
 			}
 			inst->ftb_count++;
 		} else {
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.h b/drivers/media/platform/msm/vidc/msm_vidc_common.h
index 0861c91..e2f7b61 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.h
@@ -63,4 +63,5 @@
 int msm_comm_smem_get_domain_partition(struct msm_vidc_inst *inst,
 			u32 flags, enum hal_buffer buffer_type,
 			int *domain_num, int *partition_num);
+enum hal_video_codec get_hal_codec_type(int fourcc);
 #endif
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 2b1471c..e4f920f 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -207,6 +207,8 @@
 	struct completion completions[SYS_MSG_END - SYS_MSG_START + 1];
 	enum msm_vidc_hfi_type hfi_type;
 	struct msm_vidc_platform_resources resources;
+	u32 enc_codec_supported;
+	u32 dec_codec_supported;
 };
 
 struct msm_vidc_inst {
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 735b783..a8178f7 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -29,6 +29,7 @@
 #include "venus_hfi.h"
 #include "vidc_hfi_io.h"
 #include "msm_vidc_debug.h"
+#include <linux/iopoll.h>
 
 #define FIRMWARE_SIZE			0X00A00000
 #define REG_ADDR_OFFSET_BITMASK	0x000FFFFF
@@ -77,6 +78,8 @@
 
 static int venus_hfi_power_enable(void *dev);
 
+static inline int venus_hfi_clk_gating_off(struct venus_hfi_device *device);
+
 static void venus_hfi_dump_packet(u8 *packet)
 {
 	u32 c = 0, packet_size = *(u32 *)packet;
@@ -875,6 +878,34 @@
 
 static DECLARE_COMPLETION(pc_prep_done);
 
+static int venus_hfi_halt_axi(struct venus_hfi_device *device)
+{
+	u32 reg;
+	int rc = 0;
+	if (!device) {
+		dprintk(VIDC_ERR, "Invalid input: %p\n", device);
+		return -EINVAL;
+	}
+	if (venus_hfi_clk_gating_off(device)) {
+		dprintk(VIDC_ERR, "Failed to turn off clk gating\n");
+		return -EIO;
+	}
+	/* Halt AXI and AXI OCMEM VBIF Access */
+	reg = venus_hfi_read_register(device, VENUS_VBIF_AXI_HALT_CTRL0);
+	reg |= VENUS_VBIF_AXI_HALT_CTRL0_HALT_REQ;
+	venus_hfi_write_register(device, VENUS_VBIF_AXI_HALT_CTRL0, reg, 0);
+
+	/* Request for AXI bus port halt */
+	rc = readl_poll_timeout((u32)device->hal_data->register_base_addr
+			+ VENUS_VBIF_AXI_HALT_CTRL1,
+			reg, reg & VENUS_VBIF_AXI_HALT_CTRL1_HALT_ACK,
+			POLL_INTERVAL_US,
+			VENUS_VBIF_AXI_HALT_ACK_TIMEOUT_US);
+	if (rc)
+		dprintk(VIDC_WARN, "AXI bus port halt timeout\n");
+	return rc;
+}
+
 static inline int venus_hfi_power_off(struct venus_hfi_device *device)
 {
 	int rc = 0;
@@ -3306,15 +3337,21 @@
 	if (device->resources.fw.cookie) {
 		flush_workqueue(device->vidc_workq);
 		flush_workqueue(device->venus_pm_workq);
+		subsystem_put(device->resources.fw.cookie);
+		venus_hfi_interface_queues_release(dev);
+		/* IOMMU operations need to be done before AXI halt.*/
+		venus_hfi_iommu_detach(device);
+		/* Halt the AXI to make sure there are no pending transactions.
+		 * Clocks should be unprepared after making sure axi is halted.
+		 */
+		if(venus_hfi_halt_axi(device))
+			dprintk(VIDC_WARN, "Failed to halt AXI\n");
 		venus_hfi_disable_clks(device);
 		mutex_lock(&device->clk_pwr_lock);
-		subsystem_put(device->resources.fw.cookie);
 		regulator_disable(device->gdsc);
 		device->power_enabled = 0;
 		--device->pwr_cnt;
 		mutex_unlock(&device->clk_pwr_lock);
-		venus_hfi_interface_queues_release(dev);
-		venus_hfi_iommu_detach(device);
 		device->resources.fw.cookie = NULL;
 	}
 }
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_io.h b/drivers/media/platform/msm/vidc/vidc_hfi_io.h
index 6377fbf..176db4a 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_io.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_io.h
@@ -131,6 +131,15 @@
 #define VIDC_VBIF_AT_OLD_HIGH           (VIDC_VBIF_BASE_OFFS + 0xC08)
 #define VIDC_VBIF_AT_NEW_BASE           (VIDC_VBIF_BASE_OFFS + 0xC10)
 #define VIDC_VBIF_AT_NEW_HIGH           (VIDC_VBIF_BASE_OFFS + 0xC18)
+#define VENUS_VBIF_AXI_HALT_CTRL0   (VIDC_VBIF_BASE_OFFS + 0x208)
+#define VENUS_VBIF_AXI_HALT_CTRL1   (VIDC_VBIF_BASE_OFFS + 0x20C)
+
+#define VENUS_VBIF_AXI_HALT_CTRL0_HALT_REQ		BIT(0)
+#define VENUS_VBIF_AXI_HALT_CTRL1_HALT_ACK		BIT(0)
+#define VENUS_VBIF_AXI_HALT_ACK_TIMEOUT_US		500000
+/* Poll interval in uS */
+#define POLL_INTERVAL_US                                50
+
 
 #define VIDC_VENUS0_WRAPPER_VBIF_REQ_PRIORITY \
 	(VIDC_WRAPPER_BASE_OFFS + 0x20)
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 2162294..84ac1c3 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -871,6 +871,8 @@
 		struct qseecom_client_send_service_ireq *send_svc_ireq_ptr)
 {
 	int ret = 0;
+	void *req_buf = NULL;
+
 	if ((req_ptr == NULL) || (send_svc_ireq_ptr == NULL)) {
 		pr_err("Error with pointer: req_ptr = %p, send_svc_ptr = %p\n",
 			req_ptr, send_svc_ireq_ptr);
@@ -880,9 +882,29 @@
 		pr_err("Invalid req/resp buffer, exiting\n");
 		return -EINVAL;
 	}
+
+	if (((uint32_t)req_ptr->cmd_req_buf <
+			data_ptr->client.user_virt_sb_base)
+			|| ((uint32_t)req_ptr->cmd_req_buf >=
+			(data_ptr->client.user_virt_sb_base +
+			data_ptr->client.sb_length))) {
+		pr_err("cmd buffer address not within shared bufffer\n");
+		return -EINVAL;
+	}
+
+
+	if (((uint32_t)req_ptr->resp_buf < data_ptr->client.user_virt_sb_base)
+			|| ((uint32_t)req_ptr->resp_buf >=
+			(data_ptr->client.user_virt_sb_base +
+			data_ptr->client.sb_length))){
+		pr_err("response buffer address not within shared bufffer\n");
+		return -EINVAL;
+	}
+
+	req_buf = data_ptr->client.sb_virt;
 	send_svc_ireq_ptr->qsee_cmd_id = req_ptr->cmd_id;
 	send_svc_ireq_ptr->key_type =
-	((struct qseecom_rpmb_provision_key *)req_ptr->cmd_req_buf)->key_type;
+		((struct qseecom_rpmb_provision_key *)req_buf)->key_type;
 	send_svc_ireq_ptr->req_len = req_ptr->cmd_req_len;
 	send_svc_ireq_ptr->rsp_ptr = (void *)(__qseecom_uvirt_to_kphys(data_ptr,
 					(uint32_t)req_ptr->resp_buf));
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 9d23e84..0eab568 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -347,7 +347,6 @@
 	void __iomem *wlan_tx_phy_aborts;
 	void __iomem *wlan_brdg_err_source;
 	void __iomem *fiq_reg;
-	int	ssr_boot;
 	int	nv_downloaded;
 	unsigned char *fw_cal_data;
 	unsigned char *user_cal_data;
@@ -762,8 +761,6 @@
 	case SMD_EVENT_CLOSE:
 		pr_debug("wcnss: closing WCNSS SMD channel :%s",
 				WCNSS_CTRL_CHANNEL);
-		/* This SMD is closed only during SSR */
-		penv->ssr_boot = true;
 		penv->nv_downloaded = 0;
 		break;
 
@@ -1355,6 +1352,17 @@
 		goto exit;
 	}
 
+	if (penv->fw_cal_available) {
+		/* ignore cal upload from SSR */
+		smd_read(penv->smd_ch, NULL, calhdr.frag_size);
+		penv->fw_cal_exp_frag++;
+		if (calhdr.msg_flags & LAST_FRAGMENT) {
+			penv->fw_cal_exp_frag = 0;
+			goto exit;
+		}
+		return;
+	}
+
 	if (0 == calhdr.frag_number) {
 		if (calhdr.total_size > MAX_CALIBRATED_DATA_SIZE) {
 			pr_err("wcnss: Invalid cal data size %d",
@@ -1528,7 +1536,6 @@
 		break;
 
 	case WCNSS_CALDATA_UPLD_REQ:
-		penv->fw_cal_available = 0;
 		extract_cal_data(len);
 		break;
 
@@ -1778,21 +1785,12 @@
 		while (!penv->user_cal_available && retry++ < 5)
 			msleep(500);
 	}
-
-	/* only cal data is sent during ssr (if available) */
-	if (penv->fw_cal_available && penv->ssr_boot) {
-		pr_info_ratelimited("wcnss: cal download during SSR, using fw cal");
-		wcnss_caldata_dnld(penv->fw_cal_data, penv->fw_cal_rcvd, false);
-		return;
-
-	} else if (penv->user_cal_available && penv->ssr_boot) {
-		pr_info_ratelimited("wcnss: cal download during SSR, using user cal");
-		wcnss_caldata_dnld(penv->user_cal_data,
-		penv->user_cal_rcvd, false);
-		return;
+	if (penv->fw_cal_available) {
+		pr_info_ratelimited("wcnss: cal download, using fw cal");
+		wcnss_caldata_dnld(penv->fw_cal_data, penv->fw_cal_rcvd, true);
 
 	} else if (penv->user_cal_available) {
-		pr_info_ratelimited("wcnss: cal download during cold boot, using user cal");
+		pr_info_ratelimited("wcnss: cal download, using user cal");
 		wcnss_caldata_dnld(penv->user_cal_data,
 		penv->user_cal_rcvd, true);
 	}
diff --git a/drivers/of/of_batterydata.c b/drivers/of/of_batterydata.c
index b0d40f1..32aae74 100644
--- a/drivers/of/of_batterydata.c
+++ b/drivers/of/of_batterydata.c
@@ -228,7 +228,7 @@
 	OF_PROP_READ(batt_data->rbatt_capacitive_mohm,
 			"rbatt-capacitive-mohm", node, rc, false);
 	OF_PROP_READ(batt_data->flat_ocv_threshold_uv,
-			"flat-ocv-threshold", node, rc, true);
+			"flat-ocv-threshold-uv", node, rc, true);
 	OF_PROP_READ(batt_data->max_voltage_uv,
 			"max-voltage-uv", node, rc, true);
 	OF_PROP_READ(batt_data->cutoff_uv, "v-cutoff-uv", node, rc, true);
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 095fddf..25c0237 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -70,8 +70,9 @@
 #define CHGR_IBAT_TERM_CHGR			0x5B
 #define CHGR_IBAT_TERM_BMS			0x5C
 #define CHGR_VBAT_DET				0x5D
+#define CHGR_TTRKL_MAX_EN			0x5E
 #define CHGR_TTRKL_MAX				0x5F
-#define CHGR_TTRKL_MAX_EN			0x60
+#define CHGR_TCHG_MAX_EN			0x60
 #define CHGR_TCHG_MAX				0x61
 #define CHGR_CHG_WDOG_TIME			0x62
 #define CHGR_CHG_WDOG_DLY			0x63
@@ -1187,9 +1188,16 @@
 qpnp_chg_usb_chg_gone_irq_handler(int irq, void *_chip)
 {
 	struct qpnp_chg_chip *chip = _chip;
+	u8 usb_sts;
+	int rc;
+
+	rc = qpnp_chg_read(chip, &usb_sts,
+			INT_RT_STS(chip->usb_chgpth_base), 1);
+	if (rc)
+		pr_err("failed to read usb_chgpth_sts rc=%d\n", rc);
 
 	pr_debug("chg_gone triggered\n");
-	if (qpnp_chg_is_usb_chg_plugged_in(chip)) {
+	if (qpnp_chg_is_usb_chg_plugged_in(chip) && (usb_sts & CHG_GONE_IRQ)) {
 		qpnp_chg_charge_en(chip, 0);
 		qpnp_chg_force_run_on_batt(chip, 1);
 		schedule_delayed_work(&chip->arb_stop_work,
@@ -2406,21 +2414,44 @@
 }
 
 #define QPNP_CHG_TCHG_MASK	0x7F
+#define QPNP_CHG_TCHG_EN_MASK	0x80
 #define QPNP_CHG_TCHG_MIN	4
 #define QPNP_CHG_TCHG_MAX	512
 #define QPNP_CHG_TCHG_STEP	4
 static int qpnp_chg_tchg_max_set(struct qpnp_chg_chip *chip, int minutes)
 {
 	u8 temp;
+	int rc;
 
 	if (minutes < QPNP_CHG_TCHG_MIN || minutes > QPNP_CHG_TCHG_MAX) {
 		pr_err("bad max minutes =%d asked to set\n", minutes);
 		return -EINVAL;
 	}
 
-	temp = (minutes - 1)/QPNP_CHG_TCHG_STEP;
-	return qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_TCHG_MAX,
+	rc = qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_TCHG_MAX_EN,
+			QPNP_CHG_TCHG_EN_MASK, 0, 1);
+	if (rc) {
+		pr_err("failed write tchg_max_en rc=%d\n", rc);
+		return rc;
+	}
+
+	temp = minutes / QPNP_CHG_TCHG_STEP - 1;
+
+	rc = qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_TCHG_MAX,
 			QPNP_CHG_TCHG_MASK, temp, 1);
+	if (rc) {
+		pr_err("failed write tchg_max_en rc=%d\n", rc);
+		return rc;
+	}
+
+	rc = qpnp_chg_masked_write(chip, chip->chgr_base + CHGR_TCHG_MAX_EN,
+			QPNP_CHG_TCHG_EN_MASK, QPNP_CHG_TCHG_EN_MASK, 1);
+	if (rc) {
+		pr_err("failed write tchg_max_en rc=%d\n", rc);
+		return rc;
+	}
+
+	return 0;
 }
 
 static int
@@ -4708,6 +4739,7 @@
 		goto unregister_dc_psy;
 	}
 
+	qpnp_chg_usb_chg_gone_irq_handler(chip->chg_gone.irq, chip);
 	qpnp_chg_usb_usbin_valid_irq_handler(chip->usbin_valid.irq, chip);
 	qpnp_chg_dc_dcin_valid_irq_handler(chip->dcin_valid.irq, chip);
 	power_supply_set_present(chip->usb_psy,
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index 4251968..1ad0054 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -40,6 +40,7 @@
 #include <linux/mutex.h>
 #include <linux/delay.h>
 #include <linux/swap.h>
+#include <linux/fs.h>
 
 #ifdef CONFIG_HIGHMEM
 #define _ZONE ZONE_HIGHMEM
@@ -246,8 +247,14 @@
 	}
 
 	other_free = global_page_state(NR_FREE_PAGES);
-	other_file = global_page_state(NR_FILE_PAGES) -
-						global_page_state(NR_SHMEM);
+
+	if (global_page_state(NR_SHMEM) + total_swapcache_pages <
+		global_page_state(NR_FILE_PAGES))
+		other_file = global_page_state(NR_FILE_PAGES) -
+						global_page_state(NR_SHMEM) -
+						total_swapcache_pages;
+	else
+		other_file = 0;
 
 	tune_lmk_param(&other_free, &other_file, sc);
 
diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c
index 523b937..41a6803 100644
--- a/drivers/staging/zsmalloc/zsmalloc-main.c
+++ b/drivers/staging/zsmalloc/zsmalloc-main.c
@@ -430,7 +430,12 @@
 	return next;
 }
 
-/* Encode <page, obj_idx> as a single handle value */
+/*
+ * Encode <page, obj_idx> as a single handle value.
+ * On hardware platforms with physical memory starting at 0x0 the pfn
+ * could be 0 so we ensure that the handle will never be 0 by adjusting the
+ * encoded obj_idx value before encoding.
+ */
 static void *obj_location_to_handle(struct page *page, unsigned long obj_idx)
 {
 	unsigned long handle;
@@ -441,17 +446,21 @@
 	}
 
 	handle = page_to_pfn(page) << OBJ_INDEX_BITS;
-	handle |= (obj_idx & OBJ_INDEX_MASK);
+	handle |= ((obj_idx + 1) & OBJ_INDEX_MASK);
 
 	return (void *)handle;
 }
 
-/* Decode <page, obj_idx> pair from the given object handle */
+/*
+ * Decode <page, obj_idx> pair from the given object handle. We adjust the
+ * decoded obj_idx back to its original value since it was adjusted in
+ * obj_location_to_handle().
+ */
 static void obj_handle_to_location(unsigned long handle, struct page **page,
 				unsigned long *obj_idx)
 {
 	*page = pfn_to_page(handle >> OBJ_INDEX_BITS);
-	*obj_idx = handle & OBJ_INDEX_MASK;
+	*obj_idx = (handle & OBJ_INDEX_MASK) - 1;
 }
 
 static unsigned long obj_idx_to_offset(struct page *page,
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 078929b..ecfacc0 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -67,14 +67,65 @@
 #include <mach/sps.h>
 #include <mach/msm_serial_hs.h>
 #include <mach/msm_bus.h>
-
+#include <mach/msm_ipc_logging.h>
 #include "msm_serial_hs_hwreg.h"
 #define UART_SPS_CONS_PERIPHERAL 0
 #define UART_SPS_PROD_PERIPHERAL 1
 
-static int hs_serial_debug_mask = 1;
+static void *ipc_msm_hs_log_ctxt;
+#define IPC_MSM_HS_LOG_PAGES 5
+
+/* If the debug_mask gets set to FATAL_LEV,
+ * a fatal error has happened and further IPC logging
+ * is disabled so that this problem can be detected
+ */
+enum {
+	FATAL_LEV = 0U,
+	ERR_LEV = 1U,
+	WARN_LEV = 2U,
+	INFO_LEV = 3U,
+	DBG_LEV = 4U,
+};
+
+/* Default IPC log level INFO */
+static int hs_serial_debug_mask = INFO_LEV;
 module_param_named(debug_mask, hs_serial_debug_mask,
 		   int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+#define MSM_HS_DBG(x...) do { \
+	if (hs_serial_debug_mask >= DBG_LEV) { \
+		pr_debug(x); \
+		if (ipc_msm_hs_log_ctxt) \
+			ipc_log_string(ipc_msm_hs_log_ctxt, x); \
+	} \
+} while (0)
+
+#define MSM_HS_INFO(x...) do { \
+	if (hs_serial_debug_mask >= INFO_LEV) {\
+		pr_info(x); \
+		if (ipc_msm_hs_log_ctxt) \
+			ipc_log_string(ipc_msm_hs_log_ctxt, x); \
+	} \
+} while (0)
+
+/* warnings and errors show up on console always */
+#define MSM_HS_WARN(x...) do { \
+	pr_warn(x); \
+	if (ipc_msm_hs_log_ctxt && hs_serial_debug_mask >= WARN_LEV) \
+		ipc_log_string(ipc_msm_hs_log_ctxt, x); \
+} while (0)
+
+/* ERROR condition in the driver sets the hs_serial_debug_mask
+ * to ERR_FATAL level, so that this message can be seen
+ * in IPC logging. Further errors continue to log on the console
+ */
+#define MSM_HS_ERR(x...) do { \
+	pr_err(x); \
+	if (ipc_msm_hs_log_ctxt && hs_serial_debug_mask >= ERR_LEV) { \
+		ipc_log_string(ipc_msm_hs_log_ctxt, x); \
+		hs_serial_debug_mask = FATAL_LEV; \
+	} \
+} while (0)
 /*
  * There are 3 different kind of UART Core available on MSM.
  * High Speed UART (i.e. Legacy HSUART), GSBI based HSUART
@@ -316,19 +367,19 @@
 
 	switch (cmd) {
 	case MSM_ENABLE_UART_CLOCK: {
-		pr_debug("%s():ENABLE UART CLOCK: cmd=%d\n", __func__, cmd);
+		MSM_HS_DBG("%s():ENABLE UART CLOCK: cmd=%d\n", __func__, cmd);
 		msm_hs_request_clock_on(&msm_uport->uport);
 		break;
 	}
 	case MSM_DISABLE_UART_CLOCK: {
-		pr_debug("%s():DISABLE UART CLOCK: cmd=%d\n", __func__, cmd);
+		MSM_HS_DBG("%s():DISABLE UART CLOCK: cmd=%d\n", __func__, cmd);
 		msm_hs_request_clock_off(&msm_uport->uport);
 		break;
 	}
 	case MSM_GET_UART_CLOCK_STATUS: {
 		/* Return value 0 - UART CLOCK is OFF
 		 * Return value 1 - UART CLOCK is ON */
-		pr_debug("%s():GET UART CLOCK STATUS: cmd=%d\n", __func__, cmd);
+		MSM_HS_DBG("%s():GET UART CLOCK STATUS: cmd=%d\n", __func__, cmd);
 		spin_lock_irqsave(&msm_uport->uport.lock, flags);
 		clk_state = msm_uport->clk_state;
 		spin_unlock_irqrestore(&msm_uport->uport.lock, flags);
@@ -338,7 +389,7 @@
 		break;
 	}
 	default: {
-		pr_debug("%s():Unknown cmd specified: cmd=%d\n", __func__, cmd);
+		MSM_HS_DBG("%s():Unknown cmd specified: cmd=%d\n", __func__, cmd);
 		ret = -ENOIOCTLCMD;
 		break;
 	}
@@ -470,11 +521,11 @@
 	int ret;
 
 	if (is_blsp_uart(msm_uport) && msm_uport->bus_perf_client) {
-		pr_debug("Bus voting:%d\n", vote);
+		MSM_HS_DBG("Bus voting:%d\n", vote);
 		ret = msm_bus_scale_client_update_request(
 				msm_uport->bus_perf_client, vote);
 		if (ret)
-			pr_err("%s(): Failed for Bus voting: %d\n",
+			MSM_HS_ERR("%s(): Failed for Bus voting: %d\n",
 							__func__, vote);
 	}
 }
@@ -500,6 +551,37 @@
 	writel_relaxed(value, uport->membase + offset);
 }
 
+static void hex_dump_ipc(char *prefix, char *string, int size)
+{
+	char linebuf[512];
+
+	hex_dump_to_buffer(string, size, 16, 1, linebuf, sizeof(linebuf), 1);
+	MSM_HS_DBG("%s : %s", prefix, linebuf);
+}
+
+/*
+ * This API read and provides UART Core registers information.
+*/
+static void dump_uart_hs_registers(struct msm_hs_port *msm_uport)
+{
+	msm_hs_clock_vote(msm_uport);
+	MSM_HS_DBG("============= UART Registers ================\n");
+	MSM_HS_DBG("UART_DM_MR1:%x\n", msm_hs_read(&(msm_uport->uport),
+		UART_DM_MR1));
+	MSM_HS_DBG("UART_DM_MR2:%x\n", msm_hs_read(&(msm_uport->uport),
+		UART_DM_MR2));
+	MSM_HS_DBG("UART_DM_IPR:%x\n", msm_hs_read(&(msm_uport->uport),
+		UART_DM_IPR));
+	MSM_HS_DBG("UART_DM_RFWR:%x\n", msm_hs_read(&(msm_uport->uport),
+		UART_DM_RFWR));
+	MSM_HS_DBG("UART_DM_SR:%x\n", msm_hs_read(&(msm_uport->uport),
+		UART_DM_SR));
+	MSM_HS_DBG("UART_DM_IMR: %x\n", msm_hs_read(&(msm_uport->uport),
+		UART_DM_IMR));
+	MSM_HS_DBG("=============================================\n");
+	msm_hs_clock_unvote(msm_uport);
+}
+
 static void msm_hs_release_port(struct uart_port *port)
 {
 	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(port);
@@ -626,7 +708,7 @@
 						&loopback_enable_fops);
 
 	if (IS_ERR_OR_NULL(msm_uport->loopback_dir))
-		pr_err("%s(): Cannot create loopback.%d debug entry",
+		MSM_HS_ERR("%s(): Cannot create loopback.%d debug entry",
 							__func__, id);
 }
 
@@ -637,7 +719,7 @@
 	struct device *dev;
 
 	if (pdev->id < 0 || pdev->id >= UARTDM_NR) {
-		printk(KERN_ERR "Invalid plaform device ID = %d\n", pdev->id);
+		MSM_HS_ERR(KERN_ERR "Invalid plaform device ID = %d\n", pdev->id);
 		return -EINVAL;
 	}
 
@@ -691,13 +773,13 @@
 	/* Set up the MREG/NREG/DREG/MNDREG */
 	ret = clk_set_rate(msm_uport->clk, uport->uartclk);
 	if (ret) {
-		printk(KERN_WARNING "Error setting clock rate on UART\n");
+		MSM_HS_WARN("Error setting clock rate on UART\n");
 		return ret;
 	}
 
 	ret = msm_hs_clock_vote(msm_uport);
 	if (ret) {
-		printk(KERN_ERR "Error could not turn on UART clk\n");
+		MSM_HS_ERR("Error could not turn on UART clk\n");
 		return ret;
 	}
 
@@ -728,14 +810,14 @@
 	/* Establish connection between peripheral and memory endpoint */
 	ret = sps_connect(sps_pipe_handle, sps_config);
 	if (ret) {
-		pr_err("msm_serial_hs: sps_connect() failed for tx!!\n"
+		MSM_HS_ERR("msm_serial_hs: sps_connect() failed for tx!!\n"
 		"pipe_handle=0x%x ret=%d", (u32)sps_pipe_handle, ret);
 		return ret;
 	}
 	/* Register callback event for EOT (End of transfer) event. */
 	ret = sps_register_event(sps_pipe_handle, sps_event);
 	if (ret) {
-		pr_err("msm_serial_hs: sps_connect() failed for tx!!\n"
+		MSM_HS_ERR("msm_serial_hs: sps_connect() failed for tx!!\n"
 		"pipe_handle=0x%x ret=%d", (u32)sps_pipe_handle, ret);
 		goto reg_event_err;
 	}
@@ -769,14 +851,14 @@
 	/* Establish connection between peripheral and memory endpoint */
 	ret = sps_connect(sps_pipe_handle, sps_config);
 	if (ret) {
-		pr_err("msm_serial_hs: sps_connect() failed for rx!!\n"
+		MSM_HS_ERR("msm_serial_hs: sps_connect() failed for rx!!\n"
 		"pipe_handle=0x%x ret=%d", (u32)sps_pipe_handle, ret);
 		return ret;
 	}
 	/* Register callback event for DESC_DONE event. */
 	ret = sps_register_event(sps_pipe_handle, sps_event);
 	if (ret) {
-		pr_err("msm_serial_hs: sps_connect() failed for rx!!\n"
+		MSM_HS_ERR("msm_serial_hs: sps_connect() failed for rx!!\n"
 		"pipe_handle=0x%x ret=%d", (u32)sps_pipe_handle, ret);
 		goto reg_event_err;
 	}
@@ -909,7 +991,7 @@
 	}
 
 	if (clk_set_rate(msm_uport->clk, uport->uartclk)) {
-		printk(KERN_WARNING "Error setting clock rate on UART\n");
+		MSM_HS_WARN("Error setting clock rate on UART\n");
 		WARN_ON(1);
 	}
 
@@ -998,6 +1080,9 @@
 	mutex_lock(&msm_uport->clk_mutex);
 	msm_hs_write(uport, UART_DM_IMR, 0);
 
+	MSM_HS_DBG("Entering %s\n", __func__);
+	dump_uart_hs_registers(msm_uport);
+
 	/* Clear the Rx Ready Ctl bit - This ensures that
 	* flow control lines stop the other side from sending
 	* data while we change the parameters
@@ -1108,7 +1193,7 @@
 					RX_FLUSH_COMPLETE_TIMEOUT);
 			ret = sps_disconnect(sps_pipe_handle);
 			if (ret)
-				pr_err("%s(): sps_disconnect failed\n",
+				MSM_HS_ERR("%s(): sps_disconnect failed\n",
 							__func__);
 			msm_hs_spsconnect_rx(uport);
 			msm_serial_hs_rx_tlet((unsigned long) &rx->tlet);
@@ -1116,13 +1201,13 @@
 			msm_uport->rx_discard_flush_issued = true;
 			/* do discard flush */
 			msm_dmov_flush(msm_uport->dma_rx_channel, 0);
-			pr_debug("%s(): wainting for flush completion.\n",
+			MSM_HS_DBG("%s(): wainting for flush completion.\n",
 								__func__);
 			ret = wait_event_timeout(msm_uport->rx.wait,
 				msm_uport->rx_discard_flush_issued == false,
 				RX_FLUSH_COMPLETE_TIMEOUT);
 			if (!ret)
-				pr_err("%s(): Discard flush pending.\n",
+				MSM_HS_ERR("%s(): Discard flush pending.\n",
 								__func__);
 		}
 	}
@@ -1144,6 +1229,8 @@
 	msm_hs_write(uport, UART_DM_IMR, msm_uport->imr_reg);
 	mb();
 	mutex_unlock(&msm_uport->clk_mutex);
+	MSM_HS_DBG("Exit %s\n", __func__);
+	dump_uart_hs_registers(msm_uport);
 }
 
 /*
@@ -1157,7 +1244,7 @@
 	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
 
 	msm_hs_clock_vote(msm_uport);
-	data = msm_hs_read(uport, UARTDM_SR_ADDR);
+	data = msm_hs_read(uport, UART_DM_SR);
 	msm_hs_clock_unvote(msm_uport);
 
 	if (data & UARTDM_SR_TXEMT_BMSK)
@@ -1190,7 +1277,7 @@
 
 	ret = sps_disconnect(sps_pipe_handle);
 	if (ret)
-		pr_err("%s(): sps_disconnect failed\n", __func__);
+		MSM_HS_ERR("%s(): sps_disconnect failed\n", __func__);
 
 	wake_lock_timeout(&msm_uport->rx.wake_lock, HZ / 2);
 	msm_uport->rx.flush = FLUSH_SHUTDOWN;
@@ -1268,7 +1355,8 @@
 
 	if (tx_count > left)
 		tx_count = left;
-
+	MSM_HS_DBG("%s(): [UART_TX]<%d>\n", __func__, tx_count);
+	hex_dump_ipc("HSUART write: ", &tx_buf->buf[tx_buf->tail], tx_count);
 	src_addr = tx->dma_base + tx_buf->tail;
 	/* Mask the src_addr to align on a cache
 	 * and add those bytes to tx_count */
@@ -1316,7 +1404,10 @@
 			sizeof(u32), DMA_TO_DEVICE);
 
 		msm_dmov_enqueue_cmd(msm_uport->dma_tx_channel, &tx->xfer);
+
 	}
+	MSM_HS_DBG("%s:Enqueue Tx Cmd\n", __func__);
+	dump_uart_hs_registers(msm_uport);
 }
 
 /* Start to receive the next chunk of data */
@@ -1331,7 +1422,7 @@
 
 	msm_uport->rx.buffer_pending = 0;
 	if (buffer_pending && hs_serial_debug_mask)
-		printk(KERN_ERR "Error: rx started in buffer state = %x",
+		MSM_HS_ERR("Error: rx started in buffer state = %x",
 		       buffer_pending);
 
 	msm_hs_write(uport, UART_DM_CR, RESET_STALE_INT);
@@ -1383,6 +1474,8 @@
 		msm_dmov_enqueue_cmd(msm_uport->dma_rx_channel,
 				&msm_uport->rx.xfer);
 	}
+	MSM_HS_DBG("%s:Enqueue Rx Cmd\n", __func__);
+	dump_uart_hs_registers(msm_uport);
 }
 
 static void flip_insert_work(struct work_struct *work)
@@ -1397,7 +1490,7 @@
 	spin_lock_irqsave(&msm_uport->uport.lock, flags);
 	if (msm_uport->rx.buffer_pending == NONE_PENDING) {
 		if (hs_serial_debug_mask)
-			printk(KERN_ERR "Error: No buffer pending in %s",
+			MSM_HS_ERR("Error: No buffer pending in %s",
 			       __func__);
 		return;
 	}
@@ -1429,11 +1522,7 @@
 	else
 		if ((msm_uport->clk_state == MSM_HS_CLK_ON) &&
 		    (msm_uport->rx.flush <= FLUSH_IGNORE)) {
-			if (hs_serial_debug_mask)
-				printk(KERN_WARNING
-				       "msm_serial_hs: "
-				       "Pending buffers cleared. "
-				       "Restarting\n");
+		MSM_HS_WARN("Pending buffers cleared,restarting\n");
 			msm_hs_start_rx_locked(&msm_uport->uport);
 		}
 	spin_unlock_irqrestore(&msm_uport->uport.lock, flags);
@@ -1470,6 +1559,9 @@
 	if (!is_blsp_uart(msm_uport))
 		msm_hs_write(uport, UART_DM_CR, STALE_EVENT_DISABLE);
 
+	MSM_HS_DBG("In %s\n", __func__);
+	dump_uart_hs_registers(msm_uport);
+
 	/* overflow is not connect to data in a FIFO */
 	if (unlikely((status & UARTDM_SR_OVERRUN_BMSK) &&
 		     (uport->read_status_mask & CREAD))) {
@@ -1486,7 +1578,7 @@
 	if (unlikely(status & UARTDM_SR_PAR_FRAME_BMSK)) {
 		/* Can not tell difference between parity & frame error */
 		if (hs_serial_debug_mask)
-			printk(KERN_WARNING "msm_serial_hs: parity error\n");
+			MSM_HS_WARN("msm_serial_hs: parity error\n");
 		uport->icount.parity++;
 		error_f = 1;
 		if (!(uport->ignore_status_mask & IGNPAR)) {
@@ -1498,7 +1590,7 @@
 
 	if (unlikely(status & UARTDM_SR_RX_BREAK_BMSK)) {
 		if (hs_serial_debug_mask)
-			printk(KERN_WARNING "msm_serial_hs: Rx break\n");
+			MSM_HS_WARN("msm_serial_hs: Rx break\n");
 		uport->icount.brk++;
 		error_f = 1;
 		if (!(uport->ignore_status_mask & IGNBRK)) {
@@ -1533,15 +1625,20 @@
 		rmb();
 	}
 
+	MSM_HS_DBG("%s():[UART_RX]<%d>\n", __func__, rx_count);
+	hex_dump_ipc("HSUART Read: ", msm_uport->rx.buffer, rx_count);
 	if (0 != (uport->read_status_mask & CREAD)) {
 		retval = tty_insert_flip_string(tty, msm_uport->rx.buffer,
 						rx_count);
 		if (retval != rx_count) {
+			MSM_HS_DBG("%s(): retval %d rx_count %d", __func__,
+					retval, rx_count);
 			msm_uport->rx.buffer_pending |= CHARS_NORMAL |
 				retval << 5 | (rx_count - retval) << 16;
 		}
 	}
 
+	MSM_HS_DBG("%s() read rx buffer complete", __func__);
 	/* order the read of rx.buffer and the start of next rx xfer */
 	wmb();
 
@@ -1561,11 +1658,7 @@
 	}
 out:
 	if (msm_uport->rx.buffer_pending) {
-		if (hs_serial_debug_mask)
-			printk(KERN_WARNING
-			       "msm_serial_hs: "
-			       "tty buffer exhausted. "
-			       "Stalling\n");
+		MSM_HS_WARN("tty buffer exhausted.Stalling\n");
 		schedule_delayed_work(&msm_uport->rx.flip_insert_work
 				      , msecs_to_jiffies(RETRY_TIMEOUT));
 	}
@@ -1606,7 +1699,7 @@
 		((struct sps_event_notify *)notify)->user;
 
 	msm_uport->notify = *notify;
-	pr_debug("%s: sps ev_id=%d, addr=0x%x, size=0x%x, flags=0x%x\n",
+	MSM_HS_DBG("%s: sps ev_id=%d, addr=0x%x, size=0x%x, flags=0x%x\n",
 		__func__, notify->event_id,
 		notify->data.transfer.iovec.addr,
 		notify->data.transfer.iovec.size,
@@ -1659,6 +1752,8 @@
 	mb();
 
 	spin_unlock_irqrestore(&(msm_uport->uport.lock), flags);
+	MSM_HS_DBG("In %s()\n", __func__);
+	dump_uart_hs_registers(msm_uport);
 }
 
 /**
@@ -1681,7 +1776,7 @@
 
 	uport = &(msm_uport->uport);
 	msm_uport->notify = *notify;
-	pr_debug("%s: sps ev_id=%d, addr=0x%x, size=0x%x, flags=0x%x\n",
+	MSM_HS_DBG("%s: sps ev_id=%d, addr=0x%x, size=0x%x, flags=0x%x\n",
 		__func__, notify->event_id,
 		notify->data.transfer.iovec.addr,
 		notify->data.transfer.iovec.size,
@@ -1713,7 +1808,7 @@
 	msm_uport = container_of(cmd_ptr, struct msm_hs_port, rx.xfer);
 	uport = &(msm_uport->uport);
 
-	pr_debug("%s(): called result:%x\n", __func__, result);
+	MSM_HS_DBG("%s(): called result:%x\n", __func__, result);
 	if (!(result & DMOV_RSLT_ERROR)) {
 		if (result & DMOV_RSLT_FLUSH) {
 			if (msm_uport->rx_discard_flush_issued) {
@@ -1935,13 +2030,13 @@
 
 		spin_unlock_irqrestore(&uport->lock, flags);
 		if (msm_uport->rx_discard_flush_issued) {
-			pr_debug("%s(): wainting for flush completion.\n",
+			MSM_HS_DBG("%s(): wainting for flush completion.\n",
 								__func__);
 			ret = wait_event_timeout(msm_uport->rx.wait,
 				msm_uport->rx_discard_flush_issued == false,
 				RX_FLUSH_COMPLETE_TIMEOUT);
 			if (!ret)
-				pr_err("%s(): Flush complete pending.\n",
+				MSM_HS_ERR("%s(): Flush complete pending.\n",
 								__func__);
 		}
 
@@ -2005,10 +2100,13 @@
 	spin_lock_irqsave(&uport->lock, flags);
 
 	isr_status = msm_hs_read(uport, UART_DM_MISR);
+	MSM_HS_DBG("%s:UART_DM_MISR %lx", __func__, isr_status);
+	dump_uart_hs_registers(msm_uport);
 
 	/* Uart RX starting */
 	if (isr_status & UARTDM_ISR_RXLEV_BMSK) {
 		wake_lock(&rx->wake_lock);  /* hold wakelock while rx dma */
+		MSM_HS_DBG("%s:UARTDM_ISR_RXLEV_BMSK\n", __func__);
 		msm_uport->imr_reg &= ~UARTDM_ISR_RXLEV_BMSK;
 		msm_hs_write(uport, UART_DM_IMR, msm_uport->imr_reg);
 		/* Complete device write for IMR. Hence mb() requires. */
@@ -2023,6 +2121,7 @@
 		 * mb() requires here.
 		 */
 		mb();
+		MSM_HS_DBG("%s:Stal Interrupt\n", __func__);
 
 		if (msm_uport->clk_req_off_state ==
 					CLK_REQ_OFF_RXSTALE_ISSUED)
@@ -2036,6 +2135,7 @@
 	}
 	/* tx ready interrupt */
 	if (isr_status & UARTDM_ISR_TX_READY_BMSK) {
+		MSM_HS_DBG("%s: ISR_TX_READY Interrupt\n", __func__);
 		/* Clear  TX Ready */
 		msm_hs_write(uport, UART_DM_CR, CLEAR_TX_READY);
 
@@ -2114,7 +2214,7 @@
 		msm_uport->clk_state = MSM_HS_CLK_REQUEST_OFF;
 		msm_uport->clk_req_off_state = CLK_REQ_OFF_START;
 		msm_uport->imr_reg |= UARTDM_ISR_TXLEV_BMSK;
-		msm_hs_write(uport, UARTDM_IMR, msm_uport->imr_reg);
+		msm_hs_write(uport, UART_DM_IMR, msm_uport->imr_reg);
 		/*
 		 * Complete device write before retuning back.
 		 * Hence mb() requires here.
@@ -2252,7 +2352,7 @@
 		if (gpio_is_valid(pdata->uart_rfr_gpio))
 			gpio_free(pdata->uart_rfr_gpio);
 	} else {
-		pr_err("Error:Pdata is NULL.\n");
+		MSM_HS_ERR("Error:Pdata is NULL.\n");
 	}
 }
 
@@ -2272,7 +2372,7 @@
 			ret = gpio_request(pdata->uart_tx_gpio,
 							"UART_TX_GPIO");
 			if (unlikely(ret)) {
-				pr_err("gpio request failed for:%d\n",
+				MSM_HS_ERR("gpio request failed for:%d\n",
 					pdata->uart_tx_gpio);
 				goto exit_uart_config;
 			}
@@ -2282,7 +2382,7 @@
 			ret = gpio_request(pdata->uart_rx_gpio,
 							"UART_RX_GPIO");
 			if (unlikely(ret)) {
-				pr_err("gpio request failed for:%d\n",
+				MSM_HS_ERR("gpio request failed for:%d\n",
 					pdata->uart_rx_gpio);
 				goto uart_tx_unconfig;
 			}
@@ -2292,7 +2392,7 @@
 			ret = gpio_request(pdata->uart_cts_gpio,
 							"UART_CTS_GPIO");
 			if (unlikely(ret)) {
-				pr_err("gpio request failed for:%d\n",
+				MSM_HS_ERR("gpio request failed for:%d\n",
 					pdata->uart_cts_gpio);
 				goto uart_rx_unconfig;
 			}
@@ -2302,13 +2402,13 @@
 			ret = gpio_request(pdata->uart_rfr_gpio,
 							"UART_RFR_GPIO");
 			if (unlikely(ret)) {
-				pr_err("gpio request failed for:%d\n",
+				MSM_HS_ERR("gpio request failed for:%d\n",
 					pdata->uart_rfr_gpio);
 				goto uart_cts_unconfig;
 			}
 		}
 	} else {
-		pr_err("Pdata is NULL.\n");
+		MSM_HS_ERR("Pdata is NULL.\n");
 		ret = -EINVAL;
 	}
 	return ret;
@@ -2354,7 +2454,7 @@
 	/* turn on uart clk */
 	ret = msm_hs_init_clk(uport);
 	if (unlikely(ret)) {
-		pr_err("Turning ON uartclk error\n");
+		MSM_HS_ERR("Turning ON uartclk error\n");
 		wake_unlock(&msm_uport->dma_wake_lock);
 		return ret;
 	}
@@ -2362,7 +2462,7 @@
 	if (is_blsp_uart(msm_uport)) {
 		ret = msm_hs_config_uart_gpios(uport);
 		if (ret) {
-			pr_err("Uart GPIO request failed\n");
+			MSM_HS_ERR("Uart GPIO request failed\n");
 			goto deinit_uart_clk;
 		}
 	} else {
@@ -2376,14 +2476,14 @@
 		/* SPS connect for TX */
 		ret = msm_hs_spsconnect_tx(uport);
 		if (ret) {
-			pr_err("msm_serial_hs: SPS connect failed for TX");
+			MSM_HS_ERR("msm_serial_hs: SPS connect failed for TX");
 			goto unconfig_uart_gpios;
 		}
 
 		/* SPS connect for RX */
 		ret = msm_hs_spsconnect_rx(uport);
 		if (ret) {
-			pr_err("msm_serial_hs: SPS connect failed for RX");
+			MSM_HS_ERR("msm_serial_hs: SPS connect failed for RX");
 			goto sps_disconnect_tx;
 		}
 	}
@@ -2461,7 +2561,7 @@
 	if (use_low_power_wakeup(msm_uport)) {
 		ret = irq_set_irq_wake(msm_uport->wakeup.irq, 1);
 		if (unlikely(ret)) {
-			pr_err("%s():Err setting wakeup irq\n", __func__);
+			MSM_HS_ERR("%s():Err setting wakeup irq\n", __func__);
 			goto sps_disconnect_rx;
 		}
 	}
@@ -2469,7 +2569,7 @@
 	ret = request_irq(uport->irq, msm_hs_isr, IRQF_TRIGGER_HIGH,
 			  "msm_hs_uart", msm_uport);
 	if (unlikely(ret)) {
-		pr_err("%s():Error getting uart irq\n", __func__);
+		MSM_HS_ERR("%s():Error getting uart irq\n", __func__);
 		goto free_wake_irq;
 	}
 	if (use_low_power_wakeup(msm_uport)) {
@@ -2480,7 +2580,7 @@
 					"msm_hs_wakeup", msm_uport);
 
 		if (unlikely(ret)) {
-			pr_err("%s():Err getting uart wakeup_irq\n", __func__);
+			MSM_HS_ERR("%s():Err getting uart wakeup_irq\n", __func__);
 			goto free_uart_irq;
 		}
 		disable_irq(msm_uport->wakeup.irq);
@@ -2543,14 +2643,14 @@
 	rx->pool = dma_pool_create("rx_buffer_pool", uport->dev,
 				   UARTDM_RX_BUF_SIZE, 16, 0);
 	if (!rx->pool) {
-		pr_err("%s(): cannot allocate rx_buffer_pool", __func__);
+		MSM_HS_ERR("%s(): cannot allocate rx_buffer_pool", __func__);
 		ret = -ENOMEM;
 		goto exit_tasket_init;
 	}
 
 	rx->buffer = dma_pool_alloc(rx->pool, GFP_KERNEL, &rx->rbuffer);
 	if (!rx->buffer) {
-		pr_err("%s(): cannot allocate rx->buffer", __func__);
+		MSM_HS_ERR("%s(): cannot allocate rx->buffer", __func__);
 		ret = -ENOMEM;
 		goto free_pool;
 	}
@@ -2589,14 +2689,15 @@
 	/* Allocate the command pointer. Needs to be 64 bit aligned */
 	rx->command_ptr = kmalloc(sizeof(dmov_box), GFP_KERNEL | __GFP_DMA);
 	if (!rx->command_ptr) {
-		pr_err("%s(): cannot allocate rx->command_ptr", __func__);
+		MSM_HS_ERR("%s(): cannot allocate rx->command_ptr", __func__);
 		ret = -ENOMEM;
 		goto free_tx_command_ptr_ptr;
 	}
 
 	rx->command_ptr_ptr = kmalloc(sizeof(u32), GFP_KERNEL | __GFP_DMA);
 	if (!rx->command_ptr_ptr) {
-		pr_err("%s(): cannot allocate rx->command_ptr_ptr", __func__);
+		MSM_HS_ERR("%s(): cannot allocate rx->command_ptr_ptr",
+			 __func__);
 		ret = -ENOMEM;
 		goto free_rx_command_ptr;
 	}
@@ -2664,7 +2765,7 @@
 
 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata) {
-		pr_err("unable to allocate memory for platform data\n");
+		MSM_HS_ERR("unable to allocate memory for platform data\n");
 		return ERR_PTR(-ENOMEM);
 	}
 
@@ -2672,25 +2773,25 @@
 	pdata->uart_tx_gpio = of_get_named_gpio(node,
 					"qcom,tx-gpio", 0);
 	if (pdata->uart_tx_gpio < 0)
-		pr_debug("uart_tx_gpio is not available\n");
+		MSM_HS_DBG("uart_tx_gpio is not available\n");
 
 	/* UART RX GPIO */
 	pdata->uart_rx_gpio = of_get_named_gpio(node,
 					"qcom,rx-gpio", 0);
 	if (pdata->uart_rx_gpio < 0)
-		pr_debug("uart_rx_gpio is not available\n");
+		MSM_HS_DBG("uart_rx_gpio is not available\n");
 
 	/* UART CTS GPIO */
 	pdata->uart_cts_gpio = of_get_named_gpio(node,
 					"qcom,cts-gpio", 0);
 	if (pdata->uart_cts_gpio < 0)
-		pr_debug("uart_cts_gpio is not available\n");
+		MSM_HS_DBG("uart_cts_gpio is not available\n");
 
 	/* UART RFR GPIO */
 	pdata->uart_rfr_gpio = of_get_named_gpio(node,
 					"qcom,rfr-gpio", 0);
 	if (pdata->uart_rfr_gpio < 0)
-		pr_debug("uart_rfr_gpio is not available\n");
+		MSM_HS_DBG("uart_rfr_gpio is not available\n");
 
 	pdata->inject_rx_on_wakeup = of_property_read_bool(node,
 				"qcom,inject-rx-on-wakeup");
@@ -2699,7 +2800,7 @@
 		ret = of_property_read_u32(node, "qcom,rx-char-to-inject",
 						&rx_to_inject);
 		if (ret < 0) {
-			pr_err("Error: Rx_char_to_inject not specified.\n");
+			MSM_HS_ERR("Error: Rx_char_to_inject not specified.\n");
 			return ERR_PTR(ret);
 		}
 		pdata->rx_to_inject = (char)rx_to_inject;
@@ -2708,30 +2809,30 @@
 	ret = of_property_read_u32(node, "qcom,bam-tx-ep-pipe-index",
 				&pdata->bam_tx_ep_pipe_index);
 	if (ret < 0) {
-		pr_err("Error: Getting UART BAM TX EP Pipe Index.\n");
+		MSM_HS_ERR("Error: Getting UART BAM TX EP Pipe Index.\n");
 		return ERR_PTR(ret);
 	}
 
 	if (!(pdata->bam_tx_ep_pipe_index >= BAM_PIPE_MIN &&
 		pdata->bam_tx_ep_pipe_index <= BAM_PIPE_MAX)) {
-		pr_err("Error: Invalid UART BAM TX EP Pipe Index.\n");
+		MSM_HS_ERR("Error: Invalid UART BAM TX EP Pipe Index.\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	ret = of_property_read_u32(node, "qcom,bam-rx-ep-pipe-index",
 					&pdata->bam_rx_ep_pipe_index);
 	if (ret < 0) {
-		pr_err("Error: Getting UART BAM RX EP Pipe Index.\n");
+		MSM_HS_ERR("Error: Getting UART BAM RX EP Pipe Index.\n");
 		return ERR_PTR(ret);
 	}
 
 	if (!(pdata->bam_rx_ep_pipe_index >= BAM_PIPE_MIN &&
 		pdata->bam_rx_ep_pipe_index <= BAM_PIPE_MAX)) {
-		pr_err("Error: Invalid UART BAM RX EP Pipe Index.\n");
+		MSM_HS_ERR("Error: Invalid UART BAM RX EP Pipe Index.\n");
 		return ERR_PTR(-EINVAL);
 	}
 
-	pr_debug("tx_ep_pipe_index:%d rx_ep_pipe_index:%d\n"
+	MSM_HS_DBG("tx_ep_pipe_index:%d rx_ep_pipe_index:%d\n"
 		"tx_gpio:%d rx_gpio:%d rfr_gpio:%d cts_gpio:%d",
 		pdata->bam_tx_ep_pipe_index, pdata->bam_rx_ep_pipe_index,
 		pdata->uart_tx_gpio, pdata->uart_rx_gpio, pdata->uart_cts_gpio,
@@ -2787,7 +2888,7 @@
 	/* Allocate endpoint context */
 	sps_pipe_handle = sps_alloc_endpoint();
 	if (!sps_pipe_handle) {
-		pr_err("msm_serial_hs: sps_alloc_endpoint() failed!!\n"
+		MSM_HS_ERR("msm_serial_hs: sps_alloc_endpoint() failed!!\n"
 			"is_producer=%d", is_producer);
 		rc = -ENOMEM;
 		goto out;
@@ -2796,7 +2897,7 @@
 	/* Get default connection configuration for an endpoint */
 	rc = sps_get_config(sps_pipe_handle, sps_config);
 	if (rc) {
-		pr_err("msm_serial_hs: sps_get_config() failed!!\n"
+		MSM_HS_ERR("msm_serial_hs: sps_get_config() failed!!\n"
 		"pipe_handle=0x%x rc=%d", (u32)sps_pipe_handle, rc);
 		goto get_config_err;
 	}
@@ -2832,7 +2933,7 @@
 						GFP_KERNEL);
 	if (!sps_config->desc.base) {
 		rc = -ENOMEM;
-		pr_err("msm_serial_hs: dma_alloc_coherent() failed!!\n");
+		MSM_HS_ERR("msm_serial_hs: dma_alloc_coherent() failed!!\n");
 		goto get_config_err;
 	}
 	memset(sps_config->desc.base, 0x00, sps_config->desc.size);
@@ -2851,7 +2952,7 @@
 
 	/* Now save the sps pipe handle */
 	ep->pipe_handle = sps_pipe_handle;
-	pr_debug("msm_serial_hs: success !! %s: pipe_handle=0x%x\n"
+	MSM_HS_DBG("msm_serial_hs: success !! %s: pipe_handle=0x%x\n"
 		"desc_fifo.phys_base=0x%llx\n",
 		is_producer ? "READ" : "WRITE",
 		(u32) sps_pipe_handle, (u64) sps_config->desc.phys_base);
@@ -2895,18 +2996,18 @@
 		bam.irq = (u32)msm_uport->bam_irq;
 		bam.manage = SPS_BAM_MGR_DEVICE_REMOTE;
 
-		pr_debug("msm_serial_hs: bam physical base=0x%x\n",
+		MSM_HS_DBG("msm_serial_hs: bam physical base=0x%x\n",
 							(u32)bam.phys_addr);
-		pr_debug("msm_serial_hs: bam virtual base=0x%x\n",
+		MSM_HS_DBG("msm_serial_hs: bam virtual base=0x%x\n",
 							(u32)bam.virt_addr);
 
 		/* Register UART Peripheral BAM device to SPS driver */
 		rc = sps_register_bam_device(&bam, &bam_handle);
 		if (rc) {
-			pr_err("msm_serial_hs: BAM device register failed\n");
+			MSM_HS_ERR("msm_serial_hs: BAM device register failed\n");
 			return rc;
 		}
-		pr_info("msm_serial_hs: BAM device registered. bam_handle=0x%x",
+		MSM_HS_INFO("msm_serial_hs: BAM device registered. bam_handle=0x%x",
 							msm_uport->bam_handle);
 	}
 	msm_uport->bam_handle = bam_handle;
@@ -2914,14 +3015,14 @@
 	rc = msm_hs_sps_init_ep_conn(msm_uport, &msm_uport->rx.prod,
 				UART_SPS_PROD_PERIPHERAL);
 	if (rc) {
-		pr_err("%s: Failed to Init Producer BAM-pipe", __func__);
+		MSM_HS_ERR("%s: Failed to Init Producer BAM-pipe", __func__);
 		goto deregister_bam;
 	}
 
 	rc = msm_hs_sps_init_ep_conn(msm_uport, &msm_uport->tx.cons,
 				UART_SPS_CONS_PERIPHERAL);
 	if (rc) {
-		pr_err("%s: Failed to Init Consumer BAM-pipe", __func__);
+		MSM_HS_ERR("%s: Failed to Init Consumer BAM-pipe", __func__);
 		goto deinit_ep_conn_prod;
 	}
 	return 0;
@@ -2973,7 +3074,7 @@
 				if (deviceid[alias_num] == 0) {
 					pdev->id = alias_num;
 				} else {
-					pr_err("alias_num=%d already used\n",
+					MSM_HS_ERR("alias_num=%d already used\n",
 								alias_num);
 					return -EINVAL;
 				}
@@ -2986,7 +3087,7 @@
 	}
 
 	if (pdev->id < 0 || pdev->id >= UARTDM_NR) {
-		pr_err("Invalid plaform device ID = %d\n", pdev->id);
+		MSM_HS_ERR("Invalid plaform device ID = %d\n", pdev->id);
 		return -EINVAL;
 	}
 
@@ -3014,39 +3115,39 @@
 		wakeup_irqres = platform_get_irq_byname(pdev, "wakeup_irq");
 
 		if (!core_resource) {
-			pr_err("Invalid core HSUART Resources.\n");
+			MSM_HS_ERR("Invalid core HSUART Resources.\n");
 			return -ENXIO;
 		}
 
 		if (!bam_resource) {
-			pr_err("Invalid BAM HSUART Resources.\n");
+			MSM_HS_ERR("Invalid BAM HSUART Resources.\n");
 			return -ENXIO;
 		}
 
 		if (!core_irqres) {
-			pr_err("Invalid core irqres Resources.\n");
+			MSM_HS_ERR("Invalid core irqres Resources.\n");
 			return -ENXIO;
 		}
 		if (!bam_irqres) {
-			pr_err("Invalid bam irqres Resources.\n");
+			MSM_HS_ERR("Invalid bam irqres Resources.\n");
 			return -ENXIO;
 		}
 		if (!wakeup_irqres)
-			pr_debug("Wakeup irq not specified.\n");
+			MSM_HS_DBG("Wakeup irq not specified.\n");
 
 		uport->mapbase = core_resource->start;
 
 		uport->membase = ioremap(uport->mapbase,
 					resource_size(core_resource));
 		if (unlikely(!uport->membase)) {
-			pr_err("UART Resource ioremap Failed.\n");
+			MSM_HS_ERR("UART Resource ioremap Failed.\n");
 			return -ENOMEM;
 		}
 		msm_uport->bam_mem = bam_resource->start;
 		msm_uport->bam_base = ioremap(msm_uport->bam_mem,
 					resource_size(bam_resource));
 		if (unlikely(!msm_uport->bam_base)) {
-			pr_err("UART BAM Resource ioremap Failed.\n");
+			MSM_HS_ERR("UART BAM Resource ioremap Failed.\n");
 			iounmap(uport->membase);
 			return -ENOMEM;
 		}
@@ -3057,13 +3158,13 @@
 
 		msm_uport->bus_scale_table = msm_bus_cl_get_pdata(pdev);
 		if (!msm_uport->bus_scale_table) {
-			pr_err("BLSP UART: Bus scaling is disabled.\n");
+			MSM_HS_ERR("BLSP UART: Bus scaling is disabled.\n");
 		} else {
 			msm_uport->bus_perf_client =
 				msm_bus_scale_register_client
 					(msm_uport->bus_scale_table);
 			if (IS_ERR(&msm_uport->bus_perf_client)) {
-				pr_err("%s(): Bus client register failed.\n",
+				MSM_HS_ERR("%s(): Bus client register failed.\n",
 								__func__);
 				ret = -EINVAL;
 				goto unmap_memory;
@@ -3082,7 +3183,7 @@
 
 		uport->irq = platform_get_irq(pdev, 0);
 		if (unlikely((int)uport->irq < 0)) {
-			pr_err("UART IRQ Failed.\n");
+			MSM_HS_ERR("UART IRQ Failed.\n");
 			iounmap(uport->membase);
 			return -ENXIO;
 		}
@@ -3155,14 +3256,14 @@
 
 	ret = clk_set_rate(msm_uport->clk, uport->uartclk);
 	if (ret) {
-		printk(KERN_WARNING "Error setting clock rate on UART\n");
+		MSM_HS_WARN("Error setting clock rate on UART\n");
 		goto put_clk;
 	}
 
 	msm_uport->hsuart_wq = alloc_workqueue("k_hsuart",
 					WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
 	if (!msm_uport->hsuart_wq) {
-		pr_err("%s(): Unable to create workqueue hsuart_wq\n",
+		MSM_HS_ERR("%s(): Unable to create workqueue hsuart_wq\n",
 								__func__);
 		ret =  -ENOMEM;
 		goto put_clk;
@@ -3181,7 +3282,7 @@
 	if (is_blsp_uart(msm_uport)) {
 		ret = msm_hs_sps_init(msm_uport);
 		if (unlikely(ret)) {
-			pr_err("SPS Initialization failed ! err=%d", ret);
+			MSM_HS_ERR("SPS Initialization failed ! err=%d", ret);
 			goto destroy_mutex;
 		}
 	}
@@ -3254,28 +3355,33 @@
 	int ret;
 	int i;
 
+	ipc_msm_hs_log_ctxt = ipc_log_context_create(IPC_MSM_HS_LOG_PAGES,
+							"msm_serial_hs");
+	if (!ipc_msm_hs_log_ctxt)
+		MSM_HS_WARN("%s: error creating logging context", __func__);
+
 	/* Init all UARTS as non-configured */
 	for (i = 0; i < UARTDM_NR; i++)
 		q_uart_port[i].uport.type = PORT_UNKNOWN;
 
 	ret = uart_register_driver(&msm_hs_driver);
 	if (unlikely(ret)) {
-		printk(KERN_ERR "%s failed to load\n", __FUNCTION__);
+		MSM_HS_WARN("%s failed to load\n", __func__);
 		return ret;
 	}
 	debug_base = debugfs_create_dir("msm_serial_hs", NULL);
 	if (IS_ERR_OR_NULL(debug_base))
-		pr_info("msm_serial_hs: Cannot create debugfs dir\n");
+		MSM_HS_INFO("msm_serial_hs: Cannot create debugfs dir\n");
 
 	ret = platform_driver_register(&msm_serial_hs_platform_driver);
 	if (ret) {
-		printk(KERN_ERR "%s failed to load\n", __FUNCTION__);
+		MSM_HS_ERR("%s failed to load\n", __FUNCTION__);
 		debugfs_remove_recursive(debug_base);
 		uart_unregister_driver(&msm_hs_driver);
 		return ret;
 	}
 
-	printk(KERN_INFO "msm_serial_hs module loaded\n");
+	MSM_HS_INFO("msm_serial_hs module loaded\n");
 	return ret;
 }
 
@@ -3318,12 +3424,12 @@
 			ret = wait_event_timeout(msm_uport->tx.wait,
 				msm_uport->tx.flush == FLUSH_SHUTDOWN, 100);
 			if (!ret)
-				pr_err("%s():HSUART TX Stalls.\n", __func__);
+				MSM_HS_ERR("%s():HSUART TX Stalls.\n", __func__);
 		} else {
 			/* BAM Disconnect for TX */
 			ret = sps_disconnect(sps_pipe_handle);
 			if (ret)
-				pr_err("%s(): sps_disconnect failed\n",
+				MSM_HS_ERR("%s(): sps_disconnect failed\n",
 							__func__);
 		}
 	}
@@ -3378,7 +3484,7 @@
 
 static void __exit msm_serial_hs_exit(void)
 {
-	printk(KERN_INFO "msm_serial_hs module removed\n");
+	MSM_HS_INFO("msm_serial_hs module removed\n");
 	debugfs_remove_recursive(debug_base);
 	platform_driver_unregister(&msm_serial_hs_platform_driver);
 	uart_unregister_driver(&msm_hs_driver);
diff --git a/drivers/usb/misc/diag_bridge.c b/drivers/usb/misc/diag_bridge.c
index 22e2a25..ccd48ca 100644
--- a/drivers/usb/misc/diag_bridge.c
+++ b/drivers/usb/misc/diag_bridge.c
@@ -464,12 +464,7 @@
 		pr_err("unable to allocate dev");
 		return -ENOMEM;
 	}
-	dev->pdev = platform_device_alloc("diag_bridge", devid);
-	if (!dev->pdev) {
-		pr_err("unable to allocate platform device");
-		kfree(dev);
-		return -ENOMEM;
-	}
+
 	__dev[devid] = dev;
 	dev->id = devid;
 
@@ -498,7 +493,13 @@
 
 	usb_set_intfdata(ifc, dev);
 	diag_bridge_debugfs_init();
-	platform_device_add(dev->pdev);
+	dev->pdev = platform_device_register_simple("diag_bridge", devid,
+						    NULL, 0);
+	if (IS_ERR(dev->pdev)) {
+		pr_err("unable to allocate platform device");
+		ret = PTR_ERR(dev->pdev);
+		goto error;
+	}
 
 	dev_dbg(&dev->ifc->dev, "%s: complete\n", __func__);
 
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 45fbfa8..8287ad7 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -629,6 +629,10 @@
 		pm8xxx_usb_id_pullup(1);
 	}
 
+	if (motg->caps & ALLOW_VDD_MIN_WITH_RETENTION_DISABLED)
+		writel_relaxed(readl_relaxed(USB_OTGSC) & ~(OTGSC_IDPU),
+								USB_OTGSC);
+
 	return 0;
 }
 
@@ -889,6 +893,7 @@
 	u32 phy_ctrl_val = 0, cmd_val;
 	unsigned ret;
 	u32 portsc, config2;
+	u32 func_ctrl;
 
 	if (atomic_read(&motg->in_lpm))
 		return 0;
@@ -956,6 +961,15 @@
 		ulpi_write(phy, 0x08, 0x09);
 	}
 
+	if (motg->caps & ALLOW_VDD_MIN_WITH_RETENTION_DISABLED) {
+		/* put the controller in non-driving mode */
+		func_ctrl = ulpi_read(phy, ULPI_FUNC_CTRL);
+		func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK;
+		func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING;
+		ulpi_write(phy, func_ctrl, ULPI_FUNC_CTRL);
+		ulpi_write(phy, ULPI_IFC_CTRL_AUTORESUME,
+				ULPI_CLR(ULPI_IFC_CTRL));
+	}
 
 	/* Set the PHCD bit, only if it is not set by the controller.
 	 * PHY may take some time or even fail to enter into low power
@@ -1021,8 +1035,13 @@
 		}
 		if (host_bus_suspend)
 			phy_ctrl_val |= PHY_CLAMP_DPDMSE_EN;
-		writel_relaxed(phy_ctrl_val & ~PHY_RETEN, USB_PHY_CTRL);
-		motg->lpm_flags |= PHY_RETENTIONED;
+
+		if (!(motg->caps & ALLOW_VDD_MIN_WITH_RETENTION_DISABLED)) {
+			writel_relaxed(phy_ctrl_val & ~PHY_RETEN, USB_PHY_CTRL);
+			motg->lpm_flags |= PHY_RETENTIONED;
+		} else {
+			writel_relaxed(phy_ctrl_val, USB_PHY_CTRL);
+		}
 	}
 
 	/* Ensure that above operation is completed before turning off clocks */
@@ -1063,7 +1082,8 @@
 		motg->lpm_flags |= PHY_REGULATORS_LPM;
 	}
 
-	if (motg->lpm_flags & PHY_RETENTIONED) {
+	if (motg->lpm_flags & PHY_RETENTIONED ||
+		(motg->caps & ALLOW_VDD_MIN_WITH_RETENTION_DISABLED)) {
 		msm_hsusb_config_vddcx(0);
 		msm_hsusb_mhl_switch_enable(motg, 0);
 	}
@@ -1116,6 +1136,7 @@
 	unsigned temp;
 	u32 phy_ctrl_val = 0;
 	unsigned ret;
+	u32 func_ctrl;
 
 	if (!atomic_read(&motg->in_lpm))
 		return 0;
@@ -1159,7 +1180,8 @@
 		motg->lpm_flags &= ~PHY_REGULATORS_LPM;
 	}
 
-	if (motg->lpm_flags & PHY_RETENTIONED) {
+	if (motg->lpm_flags & PHY_RETENTIONED ||
+		(motg->caps & ALLOW_VDD_MIN_WITH_RETENTION_DISABLED)) {
 		msm_hsusb_mhl_switch_enable(motg, 1);
 		msm_hsusb_config_vddcx(1);
 		phy_ctrl_val = readl_relaxed(USB_PHY_CTRL);
@@ -1205,6 +1227,14 @@
 	}
 
 skip_phy_resume:
+	if (motg->caps & ALLOW_VDD_MIN_WITH_RETENTION_DISABLED) {
+		/* put the controller in normal mode */
+		func_ctrl = ulpi_read(phy, ULPI_FUNC_CTRL);
+		func_ctrl &= ~ULPI_FUNC_CTRL_OPMODE_MASK;
+		func_ctrl |= ULPI_FUNC_CTRL_OPMODE_NORMAL;
+		ulpi_write(phy, func_ctrl, ULPI_FUNC_CTRL);
+	}
+
 	if (device_may_wakeup(phy->dev)) {
 		if (motg->async_irq)
 			disable_irq_wake(motg->async_irq);
@@ -4183,6 +4213,8 @@
 				"qcom,hsusb-l1-supported");
 	pdata->enable_ahb2ahb_bypass = of_property_read_bool(node,
 				"qcom,ahb-async-bridge-bypass");
+	pdata->disable_retention_with_vdd_min = of_property_read_bool(node,
+				"qcom,disable-retention-with-vdd-min");
 
 	return pdata;
 }
@@ -4568,6 +4600,9 @@
 	if (motg->pdata->enable_lpm_on_dev_suspend)
 		motg->caps |= ALLOW_LPM_ON_DEV_SUSPEND;
 
+	if (motg->pdata->disable_retention_with_vdd_min)
+		motg->caps |= ALLOW_VDD_MIN_WITH_RETENTION_DISABLED;
+
 	wake_lock(&motg->wlock);
 	pm_runtime_set_active(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index 31e93a5..f26570d 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -203,11 +203,13 @@
 		fromoff = to->start - from->start;
 	else
 		tooff = from->start - to->start;
+	if ((to->len <= tooff) || (from->len <= fromoff))
+		return -EINVAL;
+
 	size = to->len - tooff;
+
 	if (size > (int) (from->len - fromoff))
 		size = from->len - fromoff;
-	if (size <= 0)
-		return -EINVAL;
 	size *= sizeof(u16);
 
 	if (from->red && to->red)
diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c
index 03dbd4d..df7915a 100644
--- a/drivers/video/msm/mdss/mdss_dsi_panel.c
+++ b/drivers/video/msm/mdss/mdss_dsi_panel.c
@@ -837,9 +837,9 @@
 		pinfo->mode_gpio_state = MODE_GPIO_NOT_VALID;
 	}
 
-	rc = of_property_read_u32(np, "qcom,mdss-dsi-panel-frame-rate", &tmp);
+	rc = of_property_read_u32(np, "qcom,mdss-dsi-panel-framerate", &tmp);
 	pinfo->mipi.frame_rate = (!rc ? tmp : 60);
-	rc = of_property_read_u32(np, "qcom,mdss-dsi-panel-clock-rate", &tmp);
+	rc = of_property_read_u32(np, "qcom,mdss-dsi-panel-clockrate", &tmp);
 	pinfo->clk_rate = (!rc ? tmp : 0);
 	data = of_get_property(np, "qcom,mdss-dsi-panel-timings", &len);
 	if ((!data) || (len != 12)) {
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 81473db..96d8be0 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -1176,9 +1176,12 @@
 	struct mdss_fb_proc_info *pinfo = NULL, *temp_pinfo = NULL;
 	int ret = 0;
 	int pid = current->tgid;
+	bool unknown_pid = true, release_needed = false;
+	struct task_struct *task = current->group_leader;
 
 	if (!mfd->ref_cnt) {
-		pr_info("try to close unopened fb %d!\n", mfd->index);
+		pr_info("try to close unopened fb %d! from %s\n", mfd->index,
+			task->comm);
 		return -EINVAL;
 	}
 
@@ -1190,12 +1193,15 @@
 		if (!release_all && (pinfo->pid != pid))
 			continue;
 
-		pr_debug("found process entry pid=%d ref=%d\n", pinfo->pid,
-			pinfo->ref_cnt);
+		unknown_pid = false;
+
+		pr_debug("found process %s pid=%d mfd->ref=%d pinfo->ref=%d\n",
+			task->comm, mfd->ref_cnt, pinfo->pid, pinfo->ref_cnt);
 
 		do {
 			if (mfd->ref_cnt < pinfo->ref_cnt)
-				pr_warn("WARN:mfd->ref_cnt < pinfo->ref_cnt\n");
+				pr_warn("WARN:mfd->ref=%d < pinfo->ref=%d\n",
+					mfd->ref_cnt, pinfo->ref_cnt);
 			else
 				mfd->ref_cnt--;
 
@@ -1204,14 +1210,37 @@
 		} while (release_all && pinfo->ref_cnt);
 
 		if (pinfo->ref_cnt == 0) {
-			if (mfd->mdp.release_fnc) {
-				ret = mfd->mdp.release_fnc(mfd);
-				if (ret)
-					pr_err("error releasing fb%d pid=%d\n",
-						mfd->index, pinfo->pid);
-			}
 			list_del(&pinfo->list);
 			kfree(pinfo);
+			release_needed = !release_all;
+		}
+
+		if (!release_all)
+			break;
+	}
+
+	if (release_needed) {
+		pr_debug("known process %s pid=%d mfd->ref=%d\n",
+			task->comm, pid, mfd->ref_cnt);
+
+		if (mfd->mdp.release_fnc) {
+			ret = mfd->mdp.release_fnc(mfd, false);
+			if (ret)
+				pr_err("error releasing fb%d pid=%d\n",
+					mfd->index, pid);
+		}
+	} else if (unknown_pid || release_all) {
+		pr_warn("unknown process %s pid=%d mfd->ref=%d\n",
+			task->comm, pid, mfd->ref_cnt);
+
+		if (mfd->ref_cnt)
+			mfd->ref_cnt--;
+
+		if (mfd->mdp.release_fnc) {
+			ret = mfd->mdp.release_fnc(mfd, true);
+			if (ret)
+				pr_err("error fb%d release process %s pid=%d\n",
+					mfd->index, task->comm, pid);
 		}
 	}
 
@@ -1219,8 +1248,8 @@
 		ret = mdss_fb_blank_sub(FB_BLANK_POWERDOWN, info,
 			mfd->op_enable);
 		if (ret) {
-			pr_err("can't turn off fb%d! rc=%d\n",
-				mfd->index, ret);
+			pr_err("can't turn off fb%d! rc=%d process %s pid=%d\n",
+				mfd->index, ret, task->comm, pid);
 			return ret;
 		}
 	}
diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
index 8213dbe..80e6581 100644
--- a/drivers/video/msm/mdss/mdss_fb.h
+++ b/drivers/video/msm/mdss/mdss_fb.h
@@ -106,7 +106,7 @@
 	int (*on_fnc)(struct msm_fb_data_type *mfd);
 	int (*off_fnc)(struct msm_fb_data_type *mfd);
 	/* called to release resources associated to the process */
-	int (*release_fnc)(struct msm_fb_data_type *mfd);
+	int (*release_fnc)(struct msm_fb_data_type *mfd, bool release_all);
 	int (*kickoff_fnc)(struct msm_fb_data_type *mfd,
 					struct mdp_display_commit *data);
 	int (*ioctl_handler)(struct msm_fb_data_type *mfd, u32 cmd, void *arg);
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index 87b7526..466b8d2 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -1718,8 +1718,6 @@
 	} else {
 		msm_dss_enable_clk(power_data->clk_config,
 			power_data->num_clk, 0);
-		msm_dss_clk_set_rate(power_data->clk_config,
-			power_data->num_clk);
 		msm_dss_enable_gpio(power_data->gpio_config,
 			power_data->num_gpio, 0);
 		msm_dss_enable_vreg(power_data->vreg_config,
@@ -2473,12 +2471,6 @@
 
 	hdmi_tx_powerdown_phy(hdmi_ctrl);
 
-	/*
-	 * this is needed to avoid pll lock failure due to
-	 * clk framework's rate caching.
-	 */
-	hdmi_ctrl->pdata.power_data[HDMI_TX_CORE_PM].clk_config[0].rate = 0;
-
 	hdmi_cec_deconfig(hdmi_ctrl->feature_data[HDMI_TX_FEAT_CEC]);
 
 	hdmi_tx_core_off(hdmi_ctrl);
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index cb29be2..1198897 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -1784,6 +1784,11 @@
 {
 	int ret;
 
+	if (!ctl) {
+		pr_err("invalid ctl\n");
+		return -ENODEV;
+	}
+
 	ret = mutex_lock_interruptible(&ctl->lock);
 	if (ret)
 		return ret;
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index a867240..1bac176 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -565,10 +565,14 @@
 
 	if ((pipe->flags & MDP_DEINTERLACE) && !pipe->scale.enable_pxl_ext) {
 		if (pipe->flags & MDP_SOURCE_ROTATED_90) {
+			pipe->src.x = DIV_ROUND_UP(pipe->src.x, 2);
+			pipe->src.x &= ~1;
 			pipe->src.w /= 2;
 			pipe->img_width /= 2;
 		} else {
 			pipe->src.h /= 2;
+			pipe->src.y = DIV_ROUND_UP(pipe->src.y, 2);
+			pipe->src.y &= ~1;
 		}
 	}
 
@@ -1158,11 +1162,13 @@
 /**
  * mdss_mdp_overlay_release_all() - release any overlays associated with fb dev
  * @mfd:	Msm frame buffer structure associated with fb device
+ * @release_all: ignore pid and release all the pipes
  *
  * Release any resources allocated by calling process, this can be called
  * on fb_release to release any overlays/rotator sessions left open.
  */
-static int __mdss_mdp_overlay_release_all(struct msm_fb_data_type *mfd)
+static int __mdss_mdp_overlay_release_all(struct msm_fb_data_type *mfd,
+	bool release_all)
 {
 	struct mdss_mdp_pipe *pipe;
 	struct mdss_mdp_rotator_session *rot, *tmp;
@@ -1176,7 +1182,7 @@
 	mutex_lock(&mdp5_data->ov_lock);
 	mutex_lock(&mfd->lock);
 	list_for_each_entry(pipe, &mdp5_data->pipes_used, used_list) {
-		if (!mfd->ref_cnt || (pipe->pid == pid)) {
+		if (release_all || (pipe->pid == pid)) {
 			unset_ndx |= pipe->ndx;
 			cnt++;
 		}
@@ -1188,6 +1194,9 @@
 		cnt++;
 	}
 
+	pr_debug("release_all=%d mfd->ref_cnt=%d unset_ndx=0x%x cnt=%d\n",
+		release_all, mfd->ref_cnt, unset_ndx, cnt);
+
 	mutex_unlock(&mfd->lock);
 
 	if (unset_ndx) {
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index 78e7d29..0abd4d5 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -166,7 +166,7 @@
 	struct mdss_mdp_plane_sizes ps;
 	int i;
 	int rc = 0, rot_mode = 0;
-	u32 nlines;
+	u32 nlines, format;
 	u16 width;
 
 	width = pipe->src.w >> pipe->horz_deci;
@@ -179,8 +179,25 @@
 		pr_debug("BWC SMP strides ystride0=%x ystride1=%x\n",
 			ps.ystride[0], ps.ystride[1]);
 	} else {
-		rc = mdss_mdp_get_plane_sizes(pipe->src_fmt->format,
-			width, pipe->src.h, &ps, 0);
+		format = pipe->src_fmt->format;
+		/*
+		 * when decimation block is present, all chroma planes
+		 * are fetched on a single SMP plane for chroma pixels
+		 */
+		if (mdata->has_decimation) {
+			switch (pipe->src_fmt->chroma_sample) {
+			case MDSS_MDP_CHROMA_H2V1:
+				format = MDP_Y_CRCB_H2V1;
+				break;
+			case MDSS_MDP_CHROMA_420:
+				format = MDP_Y_CBCR_H2V2;
+				break;
+			default:
+				break;
+			}
+		}
+		rc = mdss_mdp_get_plane_sizes(format, width, pipe->src.h,
+			&ps, 0);
 		if (rc)
 			return rc;
 
@@ -191,15 +208,6 @@
 				max(pipe->mixer->width, width);
 		} else if (mdata->has_decimation) {
 			/*
-			 * when decimation block is used, all chroma planes
-			 * are fetched on a single SMP plane for chroma pixels
-			 */
-			if (ps.num_planes == 3) {
-				ps.num_planes = 2;
-				ps.ystride[1] += ps.ystride[2];
-			}
-
-			/*
 			 * To avoid quailty loss, MDP does one less decimation
 			 * on chroma components if they are subsampled.
 			 * Account for this to have enough SMPs for latency
diff --git a/drivers/video/msm/mdss/mdss_mdp_rotator.c b/drivers/video/msm/mdss/mdss_mdp_rotator.c
index 057914b..e2e41bb 100644
--- a/drivers/video/msm/mdss/mdss_mdp_rotator.c
+++ b/drivers/video/msm/mdss/mdss_mdp_rotator.c
@@ -437,6 +437,7 @@
 		rot->flags |= MDP_DEINTERLACE;
 		rot->src_rect.h /= 2;
 		rot->src_rect.y = DIV_ROUND_UP(rot->src_rect.y, 2);
+		rot->src_rect.y &= ~1;
 	}
 
 	rot->dst = rot->src_rect;
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
old mode 100644
new mode 100755
index f66a034..d9b1ef7
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -325,6 +325,7 @@
 header-y += ptrace.h
 header-y += qnx4_fs.h
 header-y += qnxtypes.h
+header-y += qrng.h
 header-y += quota.h
 header-y += radeonfb.h
 header-y += random.h
diff --git a/include/linux/qrng.h b/include/linux/qrng.h
new file mode 100644
index 0000000..35708e3
--- /dev/null
+++ b/include/linux/qrng.h
@@ -0,0 +1,12 @@
+#ifndef __QRNG_H_
+#define __QRNG_H_
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define QRNG_IOC_MAGIC    0x100
+
+#define QRNG_IOCTL_RESET_BUS_BANDWIDTH\
+	_IO(QRNG_IOC_MAGIC, 1)
+
+#endif /* __QRNG_H_ */
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 9eb9cd8..045a58b 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -232,6 +232,8 @@
  *		connected on data lines or not.
  * @enable_ahb2ahb_bypass: Indicates whether enable AHB2AHB BYPASS
  *		mode with controller in device mode.
+ * @disable_retention_with_vdd_min: Indicates whether to enable allowing
+ *		VDD min without putting PHY into retention
  */
 struct msm_otg_platform_data {
 	int *phy_init_seq;
@@ -261,6 +263,7 @@
 	bool l1_supported;
 	bool dpdm_pulldown_added;
 	bool enable_ahb2ahb_bypass;
+	bool disable_retention_with_vdd_min;
 };
 
 /* phy related flags */
@@ -427,6 +430,11 @@
 	 * voltage regulator(VDDCX) during host mode.
 	 */
 #define ALLOW_HOST_PHY_RETENTION	BIT(4)
+	/*
+	* Allow VDD minimization without putting PHY into retention
+	* for fixing PHY current leakage issue when LDOs are turned off.
+	*/
+#define ALLOW_VDD_MIN_WITH_RETENTION_DISABLED BIT(5)
 	unsigned long lpm_flags;
 #define PHY_PWR_COLLAPSED		BIT(0)
 #define PHY_RETENTIONED			BIT(1)
diff --git a/include/media/msm_jpeg.h b/include/media/msm_jpeg.h
index 56829f1..99f0de0 100644
--- a/include/media/msm_jpeg.h
+++ b/include/media/msm_jpeg.h
@@ -55,6 +55,9 @@
 #define MSM_JPEG_IOCTL_TEST_DUMP_REGION \
 	_IOW(MSM_JPEG_IOCTL_MAGIC, 15, unsigned long)
 
+#define MSM_JPEG_IOCTL_SET_CLK_RATE \
+	_IOW(MSM_JPEG_IOCTL_MAGIC, 16, unsigned long)
+
 #define MSM_JPEG_MODE_REALTIME_ENCODE 0
 #define MSM_JPEG_MODE_OFFLINE_ENCODE 1
 #define MSM_JPEG_MODE_REALTIME_ROTATION 2
diff --git a/include/media/msmb_isp.h b/include/media/msmb_isp.h
index 7b0ad14..568a3fa 100644
--- a/include/media/msmb_isp.h
+++ b/include/media/msmb_isp.h
@@ -152,6 +152,7 @@
 enum msm_vfe_axi_stream_cmd {
 	STOP_STREAM,
 	START_STREAM,
+	STOP_IMMEDIATELY,
 };
 
 struct msm_vfe_axi_stream_cfg_cmd {
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index 41f8607..c549831 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -242,6 +242,56 @@
 		__entry->status ? "online" : "offline", __entry->error)
 );
 
+/*
+ * Tracepoint for load balancing:
+ */
+#if NR_CPUS > 32
+#error "Unsupported NR_CPUS for lb tracepoint."
+#endif
+TRACE_EVENT(sched_load_balance,
+
+	TP_PROTO(int cpu, enum cpu_idle_type idle, int balance,
+		 unsigned long group_mask, int busiest_nr_running,
+		 unsigned long imbalance, unsigned int env_flags, int ld_moved,
+		 unsigned int balance_interval),
+
+	TP_ARGS(cpu, idle, balance, group_mask, busiest_nr_running,
+		imbalance, env_flags, ld_moved, balance_interval),
+
+	TP_STRUCT__entry(
+		__field(	int,			cpu)
+		__field(	enum cpu_idle_type,	idle)
+		__field(	int,			balance)
+		__field(	unsigned long,		group_mask)
+		__field(	int,			busiest_nr_running)
+		__field(	unsigned long,		imbalance)
+		__field(	unsigned int,		env_flags)
+		__field(	int,			ld_moved)
+		__field(	unsigned int,		balance_interval)
+	),
+
+	TP_fast_assign(
+		__entry->cpu			= cpu;
+		__entry->idle			= idle;
+		__entry->balance		= balance;
+		__entry->group_mask		= group_mask;
+		__entry->busiest_nr_running	= busiest_nr_running;
+		__entry->imbalance		= imbalance;
+		__entry->env_flags		= env_flags;
+		__entry->ld_moved		= ld_moved;
+		__entry->balance_interval	= balance_interval;
+	),
+
+	TP_printk("cpu=%d state=%s balance=%d group=%#lx busy_nr=%d imbalance=%ld flags=%#x ld_moved=%d bal_int=%d",
+		  __entry->cpu,
+		  __entry->idle == CPU_IDLE ? "idle" :
+		  (__entry->idle == CPU_NEWLY_IDLE ? "newly_idle" : "busy"),
+		  __entry->balance,
+		  __entry->group_mask, __entry->busiest_nr_running,
+		  __entry->imbalance, __entry->env_flags, __entry->ld_moved,
+		  __entry->balance_interval)
+);
+
 DECLARE_EVENT_CLASS(sched_process_template,
 
 	TP_PROTO(struct task_struct *p),
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 627dab1..89a5395 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -621,7 +621,19 @@
 static inline bool got_nohz_idle_kick(void)
 {
 	int cpu = smp_processor_id();
-	return idle_cpu(cpu) && test_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu));
+
+	if (!test_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu)))
+		return false;
+
+	if (idle_cpu(cpu) && !need_resched())
+		return true;
+
+	/*
+	 * We can't run Idle Load Balance on this CPU for this time so we
+	 * cancel it and clear NOHZ_BALANCE_KICK
+	 */
+	clear_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu));
+	return false;
 }
 
 #else /* CONFIG_NO_HZ */
@@ -1519,7 +1531,7 @@
 	/*
 	 * Check if someone kicked us for doing the nohz idle load balance.
 	 */
-	if (unlikely(got_nohz_idle_kick() && !need_resched())) {
+	if (unlikely(got_nohz_idle_kick())) {
 		this_rq()->idle_balance = 1;
 		raise_softirq_irqoff(SCHED_SOFTIRQ);
 	}
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 2e98983..08497b0 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -4422,7 +4422,7 @@
 	int ld_moved, active_balance = 0;
 	struct sched_group *group;
 	unsigned long imbalance;
-	struct rq *busiest;
+	struct rq *busiest = NULL;
 	unsigned long flags;
 	struct cpumask *cpus = __get_cpu_var(load_balance_tmpmask);
 
@@ -4591,6 +4591,10 @@
 
 	ld_moved = 0;
 out:
+	trace_sched_load_balance(this_cpu, idle, *balance,
+				 group ? group->cpumask[0] : 0,
+				 busiest ? busiest->nr_running : 0, imbalance,
+				 env.flags, ld_moved, sd->balance_interval);
 	return ld_moved;
 }
 
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index e598400..04cfc69 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -191,7 +191,7 @@
 	size = SKB_DATA_ALIGN(size);
 	size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 	data = kmalloc_node_track_caller(size, gfp_mask, node);
-	if (!data)
+	if (unlikely(ZERO_OR_NULL_PTR(data)))
 		goto nodata;
 	/* kmalloc(size) might give us more room than requested.
 	 * Put skb_shared_info exactly at the end of allocated zone,
diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c
index abc628b..4076f19 100644
--- a/sound/soc/codecs/wcd9306.c
+++ b/sound/soc/codecs/wcd9306.c
@@ -2853,7 +2853,7 @@
 
 	{"DAC1", "Switch", "CLASS_H_DSM MUX"},
 	{"HPHL DAC", "Switch", "CLASS_H_DSM MUX"},
-	{"HPHR DAC", NULL, "RX2 CHAIN"},
+	{"HPHR DAC", NULL, "RDAC3 MUX"},
 
 	{"LINEOUT1", NULL, "LINEOUT1 PA"},
 	{"LINEOUT2", NULL, "LINEOUT2 PA"},
@@ -2864,11 +2864,14 @@
 	{"LINEOUT2 PA", NULL, "LINEOUT2_PA_MIXER"},
 	{"LINEOUT2_PA_MIXER", NULL, "LINEOUT2 DAC"},
 
-	{"LINEOUT1 DAC", NULL, "RX3 MIX1"},
 
 	{"RDAC5 MUX", "DEM3_INV", "RX3 MIX1"},
 	{"LINEOUT2 DAC", NULL, "RDAC5 MUX"},
 
+	{"RDAC4 MUX", "DEM3", "RX3 MIX1"},
+	{"RDAC4 MUX", "DEM2", "RX2 CHAIN"},
+	{"LINEOUT1 DAC", NULL, "RDAC4 MUX"},
+
 	{"SPK PA", NULL, "SPK DAC"},
 	{"SPK DAC", NULL, "VDD_SPKDRV"},
 
@@ -2881,7 +2884,7 @@
 	{"LINEOUT1 DAC", NULL, "CDC_CP_VDD"},
 	{"LINEOUT2 DAC", NULL, "CDC_CP_VDD"},
 
-	{"RDAC3 MUX", "DEM2", "RX2 MIX1"},
+	{"RDAC3 MUX", "DEM2", "RX2 CHAIN"},
 	{"RDAC3 MUX", "DEM1", "RX1 CHAIN"},
 
 	{"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
@@ -3016,9 +3019,6 @@
 static const struct snd_soc_dapm_route wcd9302_map[] = {
 	{"SPK DAC", "Switch", "RX3 MIX1"},
 
-	{"RDAC4 MUX", "DEM3", "RX3 MIX1"},
-	{"RDAC4 MUX", "DEM2", "RX2 CHAIN"},
-	{"LINEOUT1 DAC", NULL, "RDAC4 MUX"},
 
 	{"RDAC5 MUX", "DEM4", "RX3 MIX1"},
 	{"RDAC5 MUX", "DEM3_INV", "RDAC4 MUX"},
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index db7a34c..397295b 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -2065,8 +2065,11 @@
 	pr_debug("%s: enter\n", __func__);
 
 	WCD9XXX_BCL_ASSERT_LOCKED(mbhc->resmgr);
-	current_source_enable = ((mbhc->mbhc_cfg->cs_enable_flags &
-				  (1 << MBHC_CS_ENABLE_INSERTION)) != 0);
+
+	current_source_enable = (((mbhc->mbhc_cfg->cs_enable_flags &
+		      (1 << MBHC_CS_ENABLE_INSERTION)) != 0) &&
+		     (!(snd_soc_read(mbhc->codec,
+				     mbhc->mbhc_bias_regs.ctl_reg) & 0x80)));
 
 	if (current_source_enable) {
 		wcd9xxx_turn_onoff_current_source(mbhc, true, false);
@@ -2191,9 +2194,10 @@
 	unsigned long retry = 0, timeout;
 	bool cs_enable;
 
-	cs_enable = ((mbhc->mbhc_cfg->cs_enable_flags &
-		      (1 << MBHC_CS_ENABLE_REMOVAL)) != 0);
-
+	cs_enable = (((mbhc->mbhc_cfg->cs_enable_flags &
+		      (1 << MBHC_CS_ENABLE_REMOVAL)) != 0) &&
+		     (!(snd_soc_read(mbhc->codec,
+				     mbhc->mbhc_bias_regs.ctl_reg) & 0x80)));
 	if (cs_enable)
 		wcd9xxx_turn_onoff_current_source(mbhc, true, false);
 
@@ -2705,8 +2709,11 @@
 
 	mbhc = container_of(work, struct wcd9xxx_mbhc, correct_plug_swch);
 	codec = mbhc->codec;
-	current_source_enable = ((mbhc->mbhc_cfg->cs_enable_flags &
-				  (1 << MBHC_CS_ENABLE_POLLING)) != 0);
+
+	current_source_enable = (((mbhc->mbhc_cfg->cs_enable_flags &
+		      (1 << MBHC_CS_ENABLE_POLLING)) != 0) &&
+		     (!(snd_soc_read(codec,
+				     mbhc->mbhc_bias_regs.ctl_reg) & 0x80)));
 
 	wcd9xxx_onoff_ext_mclk(mbhc, true);
 
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 1b4fae9..d56ad2b 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -54,6 +54,11 @@
 #define SESSION_TYPE_RX 0
 #define SESSION_TYPE_TX 1
 
+#define EC_PORT_ID_PRIMARY_MI2S_TX    1
+#define EC_PORT_ID_SECONDARY_MI2S_TX  2
+#define EC_PORT_ID_TERTIARY_MI2S_TX   3
+#define EC_PORT_ID_QUATERNARY_MI2S_TX 4
+
 static struct mutex routing_lock;
 
 static int fm_switch_enable;
@@ -63,6 +68,7 @@
 static int slim0_rx_aanc_fb_port;
 static int msm_route_ec_ref_rx = 3; /* NONE */
 static uint32_t voc_session_id = ALL_SESSION_VSID;
+static int msm_route_ext_ec_ref = AFE_PORT_INVALID;
 
 enum {
 	MADNONE,
@@ -1369,6 +1375,76 @@
 		     msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put),
 };
 
+static int msm_routing_ext_ec_get(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s: ext_ec_ref_rx  = %x\n", __func__, msm_route_ext_ec_ref);
+
+	mutex_lock(&routing_lock);
+	ucontrol->value.integer.value[0] = msm_route_ext_ec_ref;
+	mutex_unlock(&routing_lock);
+	return 0;
+}
+
+static int msm_routing_ext_ec_put(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
+	int mux = ucontrol->value.enumerated.item[0];
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	int ret = 0;
+	bool state = false;
+
+	pr_debug("%s: msm_route_ec_ref_rx = %d value = %ld\n",
+		 __func__, msm_route_ext_ec_ref,
+		 ucontrol->value.integer.value[0]);
+
+	mutex_lock(&routing_lock);
+	switch (ucontrol->value.integer.value[0]) {
+	case EC_PORT_ID_PRIMARY_MI2S_TX:
+		msm_route_ext_ec_ref = AFE_PORT_ID_PRIMARY_MI2S_TX;
+		state = true;
+		break;
+	case EC_PORT_ID_SECONDARY_MI2S_TX:
+		msm_route_ext_ec_ref = AFE_PORT_ID_SECONDARY_MI2S_TX;
+		state = true;
+		break;
+	case EC_PORT_ID_TERTIARY_MI2S_TX:
+		msm_route_ext_ec_ref = AFE_PORT_ID_TERTIARY_MI2S_TX;
+		state = true;
+		break;
+	case EC_PORT_ID_QUATERNARY_MI2S_TX:
+		msm_route_ext_ec_ref = AFE_PORT_ID_QUATERNARY_MI2S_TX;
+		state = true;
+		break;
+	default:
+		msm_route_ext_ec_ref = AFE_PORT_INVALID;
+		break;
+	}
+	if (voc_set_ext_ec_ref(msm_route_ext_ec_ref, state)) {
+		mutex_unlock(&routing_lock);
+		snd_soc_dapm_mux_update_power(widget, kcontrol, 1, mux, e);
+	} else {
+		ret = -EINVAL;
+		mutex_unlock(&routing_lock);
+	}
+	return ret;
+}
+
+static const char * const ext_ec_ref_rx[] = {"NONE", "PRI_MI2S_TX",
+					     "SEC_MI2S_TX", "TERT_MI2S_TX",
+					     "QUAT_MI2S_TX"};
+
+static const struct soc_enum msm_route_ext_ec_ref_rx_enum[] = {
+	SOC_ENUM_SINGLE_EXT(5, ext_ec_ref_rx),
+};
+
+static const struct snd_kcontrol_new voc_ext_ec_mux =
+	SOC_DAPM_ENUM_EXT("VOC_EXT_EC MUX Mux", msm_route_ext_ec_ref_rx_enum[0],
+			  msm_routing_ext_ec_get, msm_routing_ext_ec_put);
+
+
 static const struct snd_kcontrol_new pri_i2s_rx_mixer_controls[] = {
 	SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_I2S_RX ,
 	MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -3235,6 +3311,8 @@
 
 	SND_SOC_DAPM_MUX("SLIM0_RX_VI_FB_LCH_MUX", SND_SOC_NOPM, 0, 0,
 				&slim0_rx_vi_fb_lch_mux),
+	SND_SOC_DAPM_MUX("VOC_EXT_EC MUX", SND_SOC_NOPM, 0, 0,
+			 &voc_ext_ec_mux),
 
 };
 
@@ -3524,6 +3602,12 @@
 	{"MI2S_RX_Voice Mixer", "QCHAT", "QCHAT_DL"},
 	{"MI2S_RX", NULL, "MI2S_RX_Voice Mixer"},
 
+	{"VOC_EXT_EC MUX", "PRI_MI2S_TX" , "PRI_MI2S_TX"},
+	{"VOC_EXT_EC MUX", "SEC_MI2S_TX" , "SEC_MI2S_TX"},
+	{"VOC_EXT_EC MUX", "TERT_MI2S_TX" , "TERT_MI2S_TX"},
+	{"VOC_EXT_EC MUX", "QUAT_MI2S_TX" , "QUAT_MI2S_TX"},
+	{"CS-VOICE_UL1", NULL, "VOC_EXT_EC MUX"},
+
 	{"Voice_Tx Mixer", "PRI_TX_Voice", "PRI_I2S_TX"},
 	{"Voice_Tx Mixer", "PRI_MI2S_TX_Voice", "PRI_MI2S_TX"},
 	{"Voice_Tx Mixer", "MI2S_TX_Voice", "MI2S_TX"},
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 7a5efb0..3d1b896 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -1777,7 +1777,7 @@
 	struct asm_stream_cmd_open_readwrite_v2 open;
 
 	if ((ac == NULL) || (ac->apr == NULL)) {
-		pr_err("APR handle NULL\n");
+		pr_err("%s: APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	pr_debug("%s: session[%d]", __func__, ac->session);
@@ -1889,7 +1889,7 @@
 	struct asm_session_cmd_run_v2 run;
 	int rc;
 	if (!ac || ac->apr == NULL) {
-		pr_err("APR handle NULL\n");
+		pr_err("%s: APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	pr_debug("%s session[%d]", __func__, ac->session);
@@ -2794,7 +2794,7 @@
 	int	cmd_size = 0;
 
 	if (!ac || ac->mmap_apr == NULL) {
-		pr_err("APR handle NULL\n");
+		pr_err("%s: APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	pr_debug("%s: Session[%d]\n", __func__, ac->session);
@@ -2871,7 +2871,7 @@
 	int rc = 0;
 
 	if (!ac || this_mmap.apr == NULL) {
-		pr_err("APR handle NULL\n");
+		pr_err("%s: APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	pr_debug("%s: Session[%d]\n", __func__, ac->session);
@@ -2941,7 +2941,7 @@
 	uint32_t bufsz_t;
 
 	if (!ac || ac->mmap_apr == NULL) {
-		pr_err("APR handle NULL\n");
+		pr_err("%s: APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	pr_debug("%s: Session[%d]\n", __func__, ac->session);
@@ -3050,7 +3050,7 @@
 	int	cmd_size = 0;
 
 	if (!ac || ac->mmap_apr == NULL) {
-		pr_err("APR handle NULL\n");
+		pr_err("%s: APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	pr_debug("%s: Session[%d]\n", __func__, ac->session);
@@ -3436,7 +3436,7 @@
 	struct audio_port_data     *port;
 	int rc;
 	if (!ac || ac->apr == NULL) {
-		pr_err("APR handle NULL\n");
+		pr_err("%s: APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	if (ac->io_mode & SYNC_IO_MODE) {
@@ -3499,7 +3499,7 @@
 	struct audio_port_data     *port;
 	int rc;
 	if (!ac || ac->apr == NULL) {
-		pr_err("APR handle NULL\n");
+		pr_err("%s: APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	if (ac->io_mode & SYNC_IO_MODE) {
@@ -3696,7 +3696,7 @@
 	int dsp_buf = 0;
 
 	if (!ac || ac->apr == NULL) {
-		pr_err("APR handle NULL\n");
+		pr_err("%s: APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	pr_debug("%s: session[%d] len=%d", __func__, ac->session, len);
@@ -3764,7 +3764,7 @@
 	int dsp_buf = 0;
 
 	if (!ac || ac->apr == NULL) {
-		pr_err("APR handle NULL\n");
+		pr_err("%s: APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	pr_debug("%s: session[%d] len=%d", __func__, ac->session, len);
@@ -3823,7 +3823,7 @@
 	int rc;
 
 	if (!ac || ac->apr == NULL || tstamp == NULL) {
-		pr_err("APR handle NULL or tstamp NULL\n");
+		pr_err("%s: APR handle NULL or tstamp NULL\n", __func__);
 		return -EINVAL;
 	}
 	q6asm_add_hdr(ac, &hdr, sizeof(hdr), TRUE);
@@ -3861,7 +3861,7 @@
 	int cnt = 0;
 
 	if (!ac || ac->apr == NULL) {
-		pr_err("APR handle NULL\n");
+		pr_err("%s: APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	q6asm_add_hdr(ac, &hdr, sizeof(hdr), TRUE);
@@ -4011,7 +4011,7 @@
 	int rc;
 
 	if (!ac || ac->apr == NULL) {
-		pr_err("APR handle NULL\n");
+		pr_err("%s: APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	pr_debug("%s:session[%d]enable[%d]\n", __func__,
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 673ecff..5aadfa5 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -1861,10 +1861,18 @@
 
 	cvp_setdev_cmd.cvp_set_device_v2.tx_port_id = v->dev_tx.port_id;
 	cvp_setdev_cmd.cvp_set_device_v2.rx_port_id = v->dev_rx.port_id;
-	cvp_setdev_cmd.cvp_set_device_v2.vocproc_mode =
+
+	if (common.ec_ref_ext) {
+		cvp_setdev_cmd.cvp_set_device_v2.vocproc_mode =
+				VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING;
+		cvp_setdev_cmd.cvp_set_device_v2.ec_ref_port_id =
+				common.ec_port_id;
+	} else {
+		cvp_setdev_cmd.cvp_set_device_v2.vocproc_mode =
 				    VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING;
-	cvp_setdev_cmd.cvp_set_device_v2.ec_ref_port_id =
+		cvp_setdev_cmd.cvp_set_device_v2.ec_ref_port_id =
 				    VSS_IVOCPROC_PORT_ID_NONE;
+	}
 	pr_debug("topology=%d , tx_port_id=%d, rx_port_id=%d\n",
 		cvp_setdev_cmd.cvp_set_device_v2.tx_topology_id,
 		cvp_setdev_cmd.cvp_set_device_v2.tx_port_id,
@@ -3026,10 +3034,17 @@
 	cvp_session_cmd.cvp_session.rx_port_id = v->dev_rx.port_id;
 	cvp_session_cmd.cvp_session.profile_id =
 					 VSS_ICOMMON_CAL_NETWORK_ID_NONE;
-	cvp_session_cmd.cvp_session.vocproc_mode =
+	if (common.ec_ref_ext) {
+		cvp_session_cmd.cvp_session.vocproc_mode =
+				VSS_IVOCPROC_VOCPROC_MODE_EC_EXT_MIXING;
+		cvp_session_cmd.cvp_session.ec_ref_port_id =
+					common.ec_port_id;
+	} else {
+		cvp_session_cmd.cvp_session.vocproc_mode =
 				 VSS_IVOCPROC_VOCPROC_MODE_EC_INT_MIXING;
-	cvp_session_cmd.cvp_session.ec_ref_port_id =
+		cvp_session_cmd.cvp_session.ec_ref_port_id =
 						 VSS_IVOCPROC_PORT_ID_NONE;
+	}
 
 	pr_debug("tx_topology: %d tx_port_id=%d, rx_port_id=%d, mode: 0x%x\n",
 		cvp_session_cmd.cvp_session.tx_topology_id,
@@ -4313,7 +4328,8 @@
 
 		v->voc_state = VOC_CHANGE;
 	}
-
+	if (common.ec_ref_ext)
+		voc_set_ext_ec_ref(AFE_PORT_INVALID, false);
 fail:	mutex_unlock(&v->lock);
 
 	return ret;
@@ -4756,6 +4772,8 @@
 
 		ret = -EINVAL;
 	}
+	if (common.ec_ref_ext)
+		voc_set_ext_ec_ref(AFE_PORT_INVALID, false);
 
 	mutex_unlock(&v->lock);
 	return ret;
@@ -4973,6 +4991,28 @@
 	return ret;
 }
 
+int voc_set_ext_ec_ref(uint16_t port_id, bool state)
+{
+	int ret = 0;
+
+	mutex_lock(&common.common_lock);
+	if (state == true) {
+		if (port_id == AFE_PORT_INVALID) {
+			pr_err("%s: Invalid port id", __func__);
+			ret = -EINVAL;
+			goto exit;
+		}
+		common.ec_port_id = port_id;
+		common.ec_ref_ext = true;
+	} else {
+		common.ec_ref_ext = false;
+		common.ec_port_id = port_id;
+	}
+exit:
+	mutex_unlock(&common.common_lock);
+	return ret;
+}
+
 void voc_register_mvs_cb(ul_cb_fn ul_cb,
 			   dl_cb_fn dl_cb,
 			   void *private_data)
@@ -5807,7 +5847,7 @@
 	common.default_vol_step_val = 0;
 	common.default_vol_ramp_duration_ms = DEFAULT_VOLUME_RAMP_DURATION;
 	common.default_mute_ramp_duration_ms = DEFAULT_MUTE_RAMP_DURATION;
-
+	common.ec_ref_ext = false;
 	/* Initialize MVS info. */
 	common.mvs_info.network_type = VSS_NETWORK_ID_DEFAULT;
 
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index 39f0986..5c0cf21 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -1328,6 +1328,8 @@
 	uint32_t default_vol_step_val;
 	uint32_t default_vol_ramp_duration_ms;
 	uint32_t default_mute_ramp_duration_ms;
+	bool ec_ref_ext;
+	uint16_t ec_port_id;
 
 	/* APR to MVM in the Q6 */
 	void *apr_q6_mvm;
@@ -1462,5 +1464,6 @@
 int voc_start_playback(uint32_t set, uint16_t port_id);
 int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id);
 int voice_get_idx_for_session(u32 session_id);
+int voc_set_ext_ec_ref(uint16_t port_id, bool state);
 
 #endif