Merge "msm: camera: VFE 4.0 bring up changes" into msm-3.4
diff --git a/Documentation/devicetree/bindings/usb/msm-ssusb.txt b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
index a2b7dfc..bff3732 100644
--- a/Documentation/devicetree/bindings/usb/msm-ssusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
@@ -3,6 +3,8 @@
 Required properties :
 - compatible : should be "qcom,dwc-usb3-msm"
 - reg : offset and length of the register set in the memory map
+	offset and length of the TCSR register for routing USB
+	signals to either picoPHY0 or picoPHY1.
 - interrupts: IRQ lines used by this controller
 - interrupt-names : Required interrupt resource entries are:
 	"irq" : Interrupt for DWC3 core
@@ -18,7 +20,8 @@
 Example MSM USB3.0 controller device node :
 	usb@f9200000 {
 		compatible = "qcom,dwc-usb3-msm";
-		reg = <0xF9200000 0xFA000>;
+		reg = <0xF9200000 0xFA000>,
+		      <0xFD4AB000 0x4>;
 		interrupts = <0 131 0 0 179 0>;
 		interrupt-names = "irq", "otg_irq";
 		SSUSB_VDDCX-supply = <&pm8841_s2>;
diff --git a/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi b/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
new file mode 100644
index 0000000..1f7e488
--- /dev/null
+++ b/arch/arm/boot/dts/dsi-panel-toshiba-720p-video.dtsi
@@ -0,0 +1,119 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+&mdss_dsi {
+
+	qcom,mdss_dsi_toshiba_720p_video {
+		compatible = "qcom,mdss-dsi-panel";
+		label = "toshiba 720p video mode dsi panel";
+		status = "disable";
+		qcom,enable-gpio = <&msmgpio 58 0>;
+		qcom,rst-gpio = <&pm8941_gpios 19 0>;
+		qcom,mdss-pan-res = <720 1280>;
+		qcom,mdss-pan-bpp = <24>;
+		qcom,mdss-pan-porch-values = <32 12 144 3 4 9>;
+		qcom,mdss-pan-underflow-clr = <0xff>;
+		qcom,mdss-pan-bl-ctrl = "bl_ctrl_wled";
+		qcom,mdss-pan-bl-levels = <1 255>;
+		qcom,mdss-pan-dsi-mode = <0>;
+		qcom,mdss-pan-dsi-h-pulse-mode = <0>;
+		qcom,mdss-pan-dsi-h-power-stop = <0 0 0>;
+		qcom,mdss-pan-dsi-bllp-power-stop = <1 1>;
+		qcom,mdss-pan-dsi-traffic-mode = <1>;
+		qcom,mdss-pan-dsi-dst-format = <3>;
+		qcom,mdss-pan-dsi-vc = <0>;
+		qcom,mdss-pan-dsi-rgb-swap = <0>;
+		qcom,mdss-pan-dsi-data-lanes = <1 1 1 1>;
+		qcom,mdss-pan-dsi-t-clk = <0x1b 0x04>;
+		qcom,mdss-pan-dsi-stream = <0>;
+		qcom,mdss-pan-dsi-mdp-tr = <0x0>;
+		qcom,mdss-pan-dsi-dma-tr = <0x04>;
+		qcom,mdss-pan-frame-rate = <60>;
+		qcom,panel-phy-regulatorSettings = [03 01 01 00  /* Regualotor settings */
+						    20 00 01 00];
+		qcom,panel-phy-timingSettings = [69 29 1f 00 55 55
+						    19 2a 2a 03 04 00];
+		qcom,panel-phy-strengthCtrl = [77 06];
+		qcom,panel-phy-bistCtrl = [00 00 01 ff           /* BIST Ctrl settings */
+					   00 00];
+		qcom,panel-phy-laneConfig = [05 c2 00 00 00 00 00 01 75 /* lane0 config */
+					     05 c2 00 00 00 00 00 01 75 /* lane1 config */
+					     05 c2 00 00 00 00 00 01 75 /* lane2 config */
+					     05 c2 00 00 00 00 00 01 75 /* lane3 config */
+					     00 c2 00 00 00 00 00 01 97]; /* Clk ln config */
+
+		qcom,panel-on-cmds = [23 01 00 00 0a 02 b0 00
+					23 01 00 00 0a 02 b2 00
+					23 01 00 00 0a 02 b3 0c
+					23 01 00 00 0a 02 b4 02
+					29 01 00 00 00 06
+						c0 40 02 7f c8 08
+					29 01 00 00 00 10
+						c1 00 a8 00 00 00
+						00 00 9d 08 27 00
+						00 00 00 00
+					29 01 00 00 00 06
+						c2 00 00 09 00 00
+					23 01 00 00 0a 02 c3 04
+					29 01 00 00 00 04
+						c4 4d 83 00
+					29 01 00 00 00 0b
+						c6 12 00 08 71 00
+						00 00 80 00 04
+					23 01 00 00 0a 02 c7 22
+					29 01 00 00 00 05
+						c8 4c 0c 0c 0c
+					29 01 00 00 00 0e
+						c9 00 40 00 16 32
+						2e 3a 43 3e 3c 45
+						79 3f
+					29 01 00 00 00 0e
+						ca 00 46 1a 23 21
+						1c 25 31 2d 49 5f
+						7f 3f
+					29 01 00 00 00 0e
+						cb 00 4c 20 3a 42
+						40 47 4b 42 3e 46
+						7e 3f
+					29 01 00 00 00 0e
+						cc 00 41 19 21 1d
+						14 18 1f 1d 25 3f
+						73 3f
+					29 01 00 00 00 0e
+						cd 23 79 5a 5f 57
+						4c 51 51 45 3f 4b
+						7f 3f
+					29 01 00 00 00 0e
+						ce 00 40 14 20 1a
+						0e 0e 13 08 00 05
+						46 1c
+					29 01 00 00 00 04
+						d0 6a 64 01
+					29 01 00 00 00 03 d1 77 d4
+					23 01 00 00 0a 02 d3 33
+					29 01 00 00 00 03 d5 0f 0f
+					29 01 00 00 00 07
+						d8 34 64 23 25 62
+						32
+					29 01 00 00 00 0c
+						de 10 7b 11 0a 00
+						00 00 00 00 00 00
+					29 01 00 00 00 09
+						fd 04 55 53 00 70
+						ff 10 73
+					23 01 00 00 0a 02 e2 00
+					05 01 00 00 78 02 11 00
+					05 01 00 00 32 02 29 00];
+		qcom,panel-off-cmds = [05 01 00 00 32 02 28 00
+					05 01 00 00 78 02 10 00];
+	};
+};
diff --git a/arch/arm/boot/dts/msm8974-cdp.dts b/arch/arm/boot/dts/msm8974-cdp.dts
index 8ae9583..779b4f2 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dts
+++ b/arch/arm/boot/dts/msm8974-cdp.dts
@@ -13,6 +13,7 @@
 /dts-v1/;
 
 /include/ "msm8974.dtsi"
+/include/ "dsi-panel-toshiba-720p-video.dtsi"
 
 / {
 	model = "Qualcomm MSM 8974 CDP";
@@ -22,6 +23,12 @@
 	serial@f991e000 {
 		status = "ok";
 	};
+
+	qcom,mdss_dsi@fd922800 {
+		qcom,mdss_dsi_toshiba_720p_video {
+			status = "ok";
+		};
+	};
 };
 
 &sdcc2 {
diff --git a/arch/arm/boot/dts/msm8974-mdss.dtsi b/arch/arm/boot/dts/msm8974-mdss.dtsi
index de9173c7..dbaa492 100644
--- a/arch/arm/boot/dts/msm8974-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8974-mdss.dtsi
@@ -22,8 +22,11 @@
 
 	mdss_dsi: qcom,mdss_dsi@fd922800 {
 		compatible = "qcom,msm-mdss-dsi";
-		reg = <0xfd922800 0x5ac>,
+		reg = <0xfd922800 0x600>,
 			<0xfd8c2000 0x01000>;
+		vdd-supply = <&pm8941_l22>;
+		vdd_io-supply = <&pm8941_l12>;
+		vreg-supply = <&pm8941_l2>;
 	};
 
 	qcom,mdss_wb_panel {
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 1be0af9..dd8e80d 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -551,7 +551,8 @@
 
 	qcom,ssusb@f9200000 {
 		compatible = "qcom,dwc-usb3-msm";
-		reg = <0xf9200000 0xfc000>;
+		reg = <0xf9200000 0xfc000>,
+			  <0xfd4ab000 0x4>;
 		interrupts = <0 131 0 0 179 0>;
 		interrupt-names = "irq", "otg_irq";
 		SSUSB_VDDCX-supply = <&pm8841_s2>;
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 408175d..1ac8f02 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -293,6 +293,7 @@
 CONFIG_STM_LIS3DH=y
 CONFIG_INPUT_MPU3050=y
 # CONFIG_LEGACY_PTYS is not set
+CONFIG_MSM_IPC_LOGGING=y
 CONFIG_N_SMUX=y
 CONFIG_N_SMUX_LOOPBACK=y
 CONFIG_SMUX_CTL=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 7a4bf08..8ac8f1a 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -297,6 +297,7 @@
 CONFIG_STM_LIS3DH=y
 CONFIG_INPUT_MPU3050=y
 # CONFIG_LEGACY_PTYS is not set
+CONFIG_MSM_IPC_LOGGING=y
 CONFIG_N_SMUX=y
 CONFIG_N_SMUX_LOOPBACK=y
 CONFIG_SMUX_CTL=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index db94f13..b8417fe 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -147,6 +147,10 @@
 CONFIG_IP6_NF_TARGET_REJECT_SKERR=y
 CONFIG_IP6_NF_MANGLE=y
 CONFIG_IP6_NF_RAW=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_NET_CLS_FW=y
 CONFIG_MTD=y
 CONFIG_MTD_TESTS=m
 CONFIG_MTD_CMDLINE_PARTS=y
diff --git a/arch/arm/mach-msm/acpuclock-8960ab.c b/arch/arm/mach-msm/acpuclock-8960ab.c
index 1097907..3c42090 100644
--- a/arch/arm/mach-msm/acpuclock-8960ab.c
+++ b/arch/arm/mach-msm/acpuclock-8960ab.c
@@ -124,6 +124,10 @@
 	{ 0, {  1404000, HFPLL, 1, 0, 0x34 }, L2(9),  1237500 },
 	{ 1, {  1458000, HFPLL, 1, 0, 0x36 }, L2(9),  1237500 },
 	{ 1, {  1512000, HFPLL, 1, 0, 0x38 }, L2(9),  1250000 },
+	{ 1, {  1566000, HFPLL, 1, 0, 0x3A }, L2(9),  1250000 },
+	{ 1, {  1620000, HFPLL, 1, 0, 0x3C }, L2(9),  1250000 },
+	{ 1, {  1674000, HFPLL, 1, 0, 0x3E }, L2(9),  1250000 },
+	{ 1, {  1728000, HFPLL, 1, 0, 0x40 }, L2(9),  1250000 },
 	{ 0, { 0 } }
 };
 
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 4263cd6..962d8d6 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -2324,6 +2324,7 @@
 static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi4_pdata = {
 	.clk_freq = 100000,
 	.src_clk_rate = 24000000,
+	.keep_ahb_clk_on = 1,
 };
 
 static struct msm_i2c_platform_data msm8960_i2c_qup_gsbi3_pdata = {
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index cde6437..34901e8 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -6237,7 +6237,7 @@
 		rmwreg(0x00000003, AHB_EN_REG,  0x6C000103);
 		writel_relaxed(0x000007F9, AHB_EN2_REG);
 	} else {
-		rmwreg(0x44000000, AHB_EN_REG,  0x6C000103);
+		rmwreg(0x40000000, AHB_EN_REG,  0x6C000103);
 		writel_relaxed(0x3C7097F9, AHB_EN2_REG);
 	}
 
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index e21a645..71498d5 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -497,6 +497,7 @@
 #define LPASS_Q6SS_XO_CBCR                       0x26000
 #define LPASS_Q6_AXI_CBCR			 0x11C0
 #define Q6SS_AHBM_CBCR				 0x22004
+#define AUDIO_WRAPPER_BR_CBCR			 0x24000
 #define MSS_XO_Q6_CBCR                           0x108C
 #define MSS_BUS_Q6_CBCR                          0x10A4
 #define MSS_CFG_AHB_CBCR                         0x0280
@@ -634,7 +635,8 @@
 #define MMSSNOC_AHB_ID  0x3
 
 #define BIMC_ID		0x0
-#define OCMEM_ID	0x1
+#define OXILI_ID	0x1
+#define OCMEM_ID	0x2
 
 enum {
 	D0_ID = 1,
@@ -653,6 +655,8 @@
 DEFINE_CLK_RPM_SMD(bimc_clk, bimc_a_clk, RPM_MEM_CLK_TYPE, BIMC_ID, NULL);
 DEFINE_CLK_RPM_SMD(ocmemgx_clk, ocmemgx_a_clk, RPM_MEM_CLK_TYPE, OCMEM_ID,
 			NULL);
+DEFINE_CLK_RPM_SMD(gfx3d_clk_src, gfx3d_a_clk_src, RPM_MEM_CLK_TYPE, OXILI_ID,
+			NULL);
 
 DEFINE_CLK_RPM_SMD_BRANCH(cxo_clk_src, cxo_a_clk_src,
 				RPM_MISC_CLK_TYPE, CXO_ID, 19200000);
@@ -773,7 +777,7 @@
 static DEFINE_CLK_VOTER(bimc_msmbus_clk, &bimc_clk.c, LONG_MAX);
 static DEFINE_CLK_VOTER(bimc_msmbus_a_clk, &bimc_a_clk.c, LONG_MAX);
 static DEFINE_CLK_VOTER(bimc_acpu_a_clk, &bimc_a_clk.c, LONG_MAX);
-static DEFINE_CLK_VOTER(ocmemgx_gfx3d_clk, &ocmemgx_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(oxili_gfx3d_clk_src, &gfx3d_clk_src.c, LONG_MAX);
 static DEFINE_CLK_VOTER(ocmemgx_msmbus_clk, &ocmemgx_clk.c, LONG_MAX);
 static DEFINE_CLK_VOTER(ocmemgx_msmbus_a_clk, &ocmemgx_a_clk.c, LONG_MAX);
 static DEFINE_CLK_VOTER(ocmemgx_core_clk, &ocmemgx_clk.c, LONG_MAX);
@@ -4012,7 +4016,7 @@
 
 static struct branch_clk oxili_gfx3d_clk = {
 	.cbcr_reg = OXILI_GFX3D_CBCR,
-	.parent = &ocmemgx_gfx3d_clk.c,
+	.parent = &oxili_gfx3d_clk_src.c,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
 		.dbg_name = "oxili_gfx3d_clk",
@@ -4494,6 +4498,17 @@
 	},
 };
 
+static struct branch_clk audio_wrapper_br_clk = {
+	.cbcr_reg = AUDIO_WRAPPER_BR_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[LPASS_BASE],
+	.c = {
+		.dbg_name = "audio_wrapper_br_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(audio_wrapper_br_clk.c),
+	},
+};
+
 static struct branch_clk mss_xo_q6_clk = {
 	.cbcr_reg = MSS_XO_Q6_CBCR,
 	.bcr_reg = MSS_Q6SS_BCR,
@@ -4702,6 +4717,7 @@
 	{&q6ss_ahb_lfabif_clk.c,		LPASS_BASE, 0x001e},
 	{&q6ss_ahbm_clk.c,			LPASS_BASE, 0x001d},
 	{&audio_core_ixfabric_clk.c,		LPASS_BASE, 0x0059},
+	{&audio_wrapper_br_clk.c,		LPASS_BASE, 0x0022},
 	{&mss_bus_q6_clk.c,			MSS_BASE, 0x003b},
 	{&mss_xo_q6_clk.c,			MSS_BASE, 0x0007},
 
@@ -5236,7 +5252,7 @@
 						"msm-dai-q6.4106"),
 	CLK_LOOKUP("core_oe_clk", audio_core_lpaif_pcmoe_clk.c,
 						"msm-dai-q6.4106"),
-
+	CLK_LOOKUP("br_clk", audio_wrapper_br_clk.c, "fdd00000.qcom,ocmem"),
 	CLK_LOOKUP("core_clk",       mss_xo_q6_clk.c,  "pil-q6v5-mss"),
 	CLK_LOOKUP("bus_clk", gcc_mss_q6_bimc_axi_clk.c, "pil-q6v5-mss"),
 	CLK_LOOKUP("iface_clk", gcc_mss_cfg_ahb_clk.c, "pil-q6v5-mss"),
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 0331919..27de697 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -1592,6 +1592,47 @@
 	},
 };
 
+enum {
+	MSM8625,
+	MSM8625A,
+	MSM8625AB,
+};
+
+static int __init msm8625_cpu_id(void)
+{
+	int raw_id, cpu;
+
+	raw_id = socinfo_get_raw_id();
+	switch (raw_id) {
+	/* Part number for 1GHz part */
+	case 0x770:
+	case 0x771:
+	case 0x77C:
+	case 0x780:
+	case 0x8D0:
+		cpu = MSM8625;
+		break;
+	/* Part number for 1.2GHz part */
+	case 0x773:
+	case 0x774:
+	case 0x781:
+	case 0x8D1:
+		cpu = MSM8625A;
+		break;
+	case 0x775:
+	case 0x776:
+	case 0x77D:
+	case 0x782:
+	case 0x8D2:
+		cpu = MSM8625AB;
+		break;
+	default:
+		pr_err("Invalid Raw ID\n");
+		return -ENODEV;
+	}
+	return cpu;
+}
+
 static struct resource cpr_resources[] = {
 	{
 		.start = MSM8625_INT_CPR_IRQ0,
@@ -1608,12 +1649,12 @@
  * These are various Vdd levels supported by PMIC
  */
 static uint32_t msm_c2_pmic_mv[] __initdata = {
-	1300, 12875 / 10, 1275, 12625 / 10, 1250,
-	12375 / 10, 1225, 12125 / 10, 1200, 11875 / 10,
-	1175, 11625 / 10, 1150, 11375 / 10, 1125,
-	11125 / 10, 1100, 10875 / 10, 1075, 10625 / 10,
-	1050, 10375 / 10, 1025, 10125 / 10, 0, 0, 0, 0,
-	0, 0, 0, 1000,
+	1300000, 1287500, 1275000, 1262500, 1250000,
+	1237500, 1225000, 1212500, 1200000, 1187500,
+	1175000, 1162500, 1150000, 1137500, 1125000,
+	1112500, 1100000, 1087500, 1075000, 1062500,
+	1050000, 1037500, 1025000, 1012500, 0, 0, 0,
+	0, 0, 0, 0, 1000,
 };
 
 /**
@@ -1633,10 +1674,10 @@
 			},
 			.ring_osc = 0,
 			.step_quot = ~0,
-			.tgt_volt_offset = 1,
-			.Vmax = 1200,
-			.Vmin = 1000,
-			.calibrated_mV = 1100,
+			.tgt_volt_offset = 0,
+			.Vmax = 1200000,
+			.Vmin = 1000000,
+			.calibrated_uV = 1100000,
 	},
 	[TURBO_MODE] = {
 			.ring_osc_data = {
@@ -1651,23 +1692,47 @@
 			},
 			.ring_osc = 0,
 			.step_quot = ~0,
-			.tgt_volt_offset = 1,
-			.Vmax = 1350,
-			.Vmin = 1250,
-			.calibrated_mV = 1300,
+			.tgt_volt_offset = 0,
+			.Vmax = 1350000,
+			.Vmin = 1150000,
+			.calibrated_uV = 1300000,
 	},
 };
 
 struct msm_cpr_vp_data vp_data = {
-	.min_volt = 1000,
-	.max_volt = 1350,
-	.default_volt = 1300,
-	.step_size = (12500 / 1000),
+	.min_volt = 1000000,
+	.max_volt = 1350000,
+	.default_volt = 1300000,
+	.step_size = 12500,
 };
 
+static uint32_t
+msm_cpr_get_quot(uint32_t max_quot, uint32_t max_freq, uint32_t new_freq)
+{
+	uint32_t quot;
+
+	/* This formula is as per chip characterization data */
+	quot = max_quot - ((max_freq / 10 - new_freq / 10) * 9) + 20;
+
+	return quot;
+}
+
+static void msm_cpr_clk_enable(void)
+{
+	uint32_t reg_val;
+
+	/* Select TCXO (19.2MHz) as clock source */
+	reg_val = readl_relaxed(A11S_TEST_BUS_SEL_ADDR);
+	reg_val |= RBCPR_CLK_MUX_SEL;
+	writel_relaxed(reg_val, A11S_TEST_BUS_SEL_ADDR);
+
+	/* Get CPR out of reset */
+	writel_relaxed(0x1, RBCPR_SW_RESET_N);
+}
+
 static struct msm_cpr_config msm_cpr_pdata = {
 	.ref_clk_khz = 19200,
-	.delay_us = 10000,
+	.delay_us = 25000,
 	.irq_line = 0,
 	.cpr_mode_data = msm_cpr_mode_data,
 	.tgt_count_div_N = 1,
@@ -1678,8 +1743,12 @@
 	.dn_threshold = 2,
 	.up_margin = 0,
 	.dn_margin = 0,
-	.nom_freq_limit = 1008000,
+	.max_nom_freq = 700800,
+	.max_freq = 1401600,
+	.max_quot = 0,
 	.vp_data = &vp_data,
+	.get_quot = msm_cpr_get_quot,
+	.clk_enable = msm_cpr_clk_enable,
 };
 
 static struct platform_device msm8625_device_cpr = {
@@ -1701,7 +1770,6 @@
 {
 	struct cpr_info_type *cpr_info = NULL;
 	uint8_t ring_osc = 0;
-	uint32_t reg_val;
 
 	cpr_info = kzalloc(sizeof(struct cpr_info_type), GFP_KERNEL);
 	if (!cpr_info) {
@@ -1728,35 +1796,32 @@
 	msm_cpr_mode_data[TURBO_MODE].ring_osc_data[ring_osc].gcnt = 19;
 	msm_cpr_mode_data[NORMAL_MODE].ring_osc_data[ring_osc].gcnt = 19;
 
-	/* The multiplier and offset are as per PTE data */
-	msm_cpr_mode_data[TURBO_MODE].ring_osc_data[ring_osc].target_count =
-		cpr_info->turbo_quot * 10 + 440;
-	msm_cpr_mode_data[NORMAL_MODE].ring_osc_data[ring_osc].target_count =
-		cpr_info->turbo_quot / msm_cpr_pdata.tgt_count_div_N;
+	/**
+	 * The scaling factor and offset are as per chip characterization data
+	 * This formula is used since available fuse bits in the chip are not
+	 * enough to represent the value of maximum quot
+	 */
+	msm_cpr_pdata.max_quot = cpr_info->turbo_quot * 10 + 610;
 
 	/**
 	 * Bits 4:0 of pvs_fuse provide mapping to the safe boot up voltage.
 	 * Boot up mode is by default Turbo.
 	 */
-	msm_cpr_mode_data[TURBO_MODE].calibrated_mV =
+	msm_cpr_mode_data[TURBO_MODE].calibrated_uV =
 				msm_c2_pmic_mv[cpr_info->pvs_fuse & 0x1F];
 
-	/* TODO: Store the tgt_volt_offset values for the modes from PTE */
-
-
 	pr_debug("%s: cpr: ring_osc: 0x%x\n", __func__,
 		msm_cpr_mode_data[TURBO_MODE].ring_osc);
 	pr_debug("%s: cpr: turbo_quot: 0x%x\n", __func__, cpr_info->turbo_quot);
 	pr_debug("%s: cpr: pvs_fuse: 0x%x\n", __func__, cpr_info->pvs_fuse);
 	kfree(cpr_info);
 
-	/* Select TCXO (19.2MHz) as clock source */
-	reg_val = readl_relaxed(A11S_TEST_BUS_SEL_ADDR);
-	reg_val |= RBCPR_CLK_MUX_SEL;
-	writel_relaxed(reg_val, A11S_TEST_BUS_SEL_ADDR);
+	if (msm8625_cpu_id() == MSM8625A)
+		msm_cpr_pdata.max_freq = 1209600;
+	else if (msm8625_cpu_id() == MSM8625)
+		msm_cpr_pdata.max_freq = 1008000;
 
-	/* Get CPR out of reset */
-	writel_relaxed(0x1, RBCPR_SW_RESET_N);
+	msm_cpr_clk_enable();
 
 	platform_device_register(&msm8625_vp_device);
 	platform_device_register(&msm8625_device_cpr);
@@ -1828,47 +1893,6 @@
 	.table = msm_clock_8625_dummy,
 	.size = ARRAY_SIZE(msm_clock_8625_dummy),
 };
-enum {
-	MSM8625,
-	MSM8625A,
-	MSM8625AB,
-};
-
-static int __init msm8625_cpu_id(void)
-{
-	int raw_id, cpu;
-
-	raw_id = socinfo_get_raw_id();
-	switch (raw_id) {
-	/* Part number for 1GHz part */
-	case 0x770:
-	case 0x771:
-	case 0x77C:
-	case 0x780:
-	case 0x8D0:
-		cpu = MSM8625;
-		break;
-	/* Part number for 1.2GHz part */
-	case 0x773:
-	case 0x774:
-	case 0x779:
-	case 0x781:
-	case 0x8D1:
-		cpu = MSM8625A;
-		break;
-	case 0x775:
-	case 0x776:
-	case 0x77D:
-	case 0x782:
-	case 0x8D2:
-		cpu = MSM8625AB;
-		break;
-	default:
-		pr_err("Invalid Raw ID\n");
-		return -ENODEV;
-	}
-	return cpu;
-}
 
 int __init msm7x2x_misc_init(void)
 {
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index d8f8480..3311ea1 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -515,6 +515,7 @@
 	int aux_dat;
 	int src_clk_rate;
 	int use_gsbi_shared_mode;
+	int keep_ahb_clk_on;
 	void (*msm_i2c_config_gpio)(int iface, int config_type);
 };
 
diff --git a/arch/arm/mach-msm/msm_cpr.c b/arch/arm/mach-msm/msm_cpr.c
index f4272f3..b6c05f4 100644
--- a/arch/arm/mach-msm/msm_cpr.c
+++ b/arch/arm/mach-msm/msm_cpr.c
@@ -36,6 +36,14 @@
 
 #define MODULE_NAME "msm-cpr"
 
+/**
+ * Convert the Delay time to Timer Count Register
+ * e.g if frequency is 19200 kHz and delay required is
+ * 20000us, so timer count will be 19200 * 20000 / 1000
+ */
+#define TIMER_COUNT(freq, delay) ((freq * delay) / 1000)
+#define ALL_CPR_IRQ 0x3F
+
 /* Need platform device handle for suspend and resume APIs */
 static struct platform_device *cpr_pdev;
 
@@ -45,6 +53,7 @@
 	int prev_mode;
 	uint32_t floor;
 	uint32_t ceiling;
+	bool max_volt_set;
 	void __iomem *base;
 	unsigned int irq;
 	struct mutex cpr_mutex;
@@ -157,7 +166,7 @@
 static void
 cpr_2pt_kv_analysis(struct msm_cpr *cpr, struct msm_cpr_mode *chip_data)
 {
-	int32_t tgt_volt_mV = 0, level_uV, rc;
+	int32_t level_uV = 0, rc;
 	uint32_t quot1, quot2;
 
 	/**
@@ -180,15 +189,10 @@
 	 * voltage, offset is always subtracted from it.
 	 *
 	 */
-	if (chip_data->tgt_volt_offset > 0) {
-		tgt_volt_mV = chip_data->calibrated_mV -
-			(chip_data->tgt_volt_offset * cpr->vp->step_size);
-	}
-	pr_debug("tgt_volt_mV = %d, calibrated_mV = %d", tgt_volt_mV,
-			chip_data->calibrated_mV);
+	level_uV = chip_data->Vmax -
+		(chip_data->tgt_volt_offset * cpr->vp->step_size);
+	pr_debug("tgt_volt_uV = %d\n", level_uV);
 
-	/* level_uV = tgt_volt_mV * 1000; */
-	level_uV = 1350000;
 	/* Call the PMIC specific routine to set the voltage */
 	rc = regulator_set_voltage(cpr->vreg_cx, level_uV, level_uV);
 	if (rc) {
@@ -202,10 +206,7 @@
 		return;
 	}
 
-	/* Store the adjusted value of voltage */
-	chip_data->calibrated_mV = 1300;
-
-	/* Take first CPR measurement at a higher voltage to get QUOT1 */
+	/* First CPR measurement at a higher voltage to get QUOT1 */
 
 	/* Enable the Software mode of operation */
 	cpr_modify_reg(cpr, RBCPR_CTL, HW_TO_PMIC_EN_M, SW_MODE);
@@ -231,7 +232,8 @@
 	quot1 = (cpr_read_reg(cpr, RBCPR_DEBUG1) & QUOT_SLOW_M) >> 12;
 
 	/* Take second CPR measurement at a lower voltage to get QUOT2 */
-	level_uV = 1300000;
+	level_uV -= 4 * cpr->vp->step_size;
+	pr_debug("tgt_volt_uV = %d\n", level_uV);
 
 	cpr_modify_reg(cpr, RBCPR_CTL, LOOP_EN_M, DISABLE_CPR);
 	/* Call the PMIC specific routine to set the voltage */
@@ -261,7 +263,7 @@
 	}
 	quot2 = (cpr_read_reg(cpr, RBCPR_DEBUG1) & QUOT_SLOW_M) >> 12;
 	chip_data->step_quot = (quot1 - quot2) / 4;
-	pr_debug("%s: Calculated Step Quot is %d\n",
+	pr_info("%s: Calculated Step Quot is %d\n",
 			__func__, chip_data->step_quot);
 	/* Disable the cpr */
 	cpr_modify_reg(cpr, RBCPR_CTL, LOOP_EN_M, DISABLE_CPR);
@@ -279,7 +281,7 @@
 void cpr_irq_clr_and_ack(struct msm_cpr *cpr, uint32_t mask)
 {
 	/* Clear the interrupt */
-	cpr_write_reg(cpr, RBIF_IRQ_CLEAR, 0x3F);
+	cpr_write_reg(cpr, RBIF_IRQ_CLEAR, ALL_CPR_IRQ);
 	/* Acknowledge the Recommendation */
 	cpr_write_reg(cpr, RBIF_CONT_ACK_CMD, 0x1);
 }
@@ -287,7 +289,7 @@
 static inline
 void cpr_irq_clr_and_nack(struct msm_cpr *cpr, uint32_t mask)
 {
-	cpr_write_reg(cpr, RBIF_IRQ_CLEAR, 0x3F);
+	cpr_write_reg(cpr, RBIF_IRQ_CLEAR, ALL_CPR_IRQ);
 	cpr_write_reg(cpr, RBIF_CONT_NACK_CMD, 0x1);
 }
 
@@ -307,7 +309,7 @@
 static void
 cpr_up_event_handler(struct msm_cpr *cpr, uint32_t new_volt)
 {
-	int rc, set_volt_mV;
+	int rc, set_volt_uV;
 	struct msm_cpr_mode *chip_data;
 
 	chip_data = &cpr->config->cpr_mode_data[cpr->cpr_mode];
@@ -317,26 +319,28 @@
 	 * freq switch handler and CPR interrupt handler here
 	 */
 	/* Set New PMIC voltage */
-	set_volt_mV = (new_volt < chip_data->Vmax ? new_volt
+	set_volt_uV = (new_volt < chip_data->Vmax ? new_volt
 				: chip_data->Vmax);
-	rc = regulator_set_voltage(cpr->vreg_cx, set_volt_mV * 1000,
-					set_volt_mV * 1000);
+	rc = regulator_set_voltage(cpr->vreg_cx, set_volt_uV,
+					set_volt_uV);
 	if (rc) {
-		pr_err("%s: Voltage set at %dmV failed. %d\n",
-			__func__, set_volt_mV, rc);
+		pr_err("%s: Voltage set at %duV failed. %d\n",
+			__func__, set_volt_uV, rc);
 		cpr_irq_clr_and_nack(cpr, BIT(4) | BIT(0));
 		return;
 	}
-	pr_debug("%s: Voltage set at %dmV\n", __func__, set_volt_mV);
+	pr_info("(railway_voltage: %d uV)\n", set_volt_uV);
+
+	cpr->max_volt_set = (set_volt_uV == chip_data->Vmax) ? 1 : 0;
 
 	/**
 	 * Save the new calibrated voltage to be re-used
 	 * whenever we return to same mode after a mode switch.
 	 */
-	chip_data->calibrated_mV = set_volt_mV;
+	chip_data->calibrated_uV = set_volt_uV;
 
 	/* Clear all the interrupts */
-	cpr_write_reg(cpr, RBIF_IRQ_CLEAR, 0x3F);
+	cpr_write_reg(cpr, RBIF_IRQ_CLEAR, ALL_CPR_IRQ);
 
 	/* Disable Auto ACK for Down interrupts */
 	cpr_modify_reg(cpr, RBCPR_CTL, SW_AUTO_CONT_NACK_DN_EN_M, 0);
@@ -353,7 +357,7 @@
 static void
 cpr_dn_event_handler(struct msm_cpr *cpr, uint32_t new_volt)
 {
-	int rc, set_volt_mV;
+	int rc, set_volt_uV;
 	struct msm_cpr_mode *chip_data;
 
 	chip_data = &cpr->config->cpr_mode_data[cpr->cpr_mode];
@@ -363,26 +367,28 @@
 	 * freq switch handler and CPR interrupt handler here
 	 */
 	/* Set New PMIC volt */
-	set_volt_mV = (new_volt > chip_data->Vmin ? new_volt
+	set_volt_uV = (new_volt > chip_data->Vmin ? new_volt
 				: chip_data->Vmin);
-	rc = regulator_set_voltage(cpr->vreg_cx, set_volt_mV * 1000,
-					set_volt_mV * 1000);
+	rc = regulator_set_voltage(cpr->vreg_cx, set_volt_uV,
+					set_volt_uV);
 	if (rc) {
-		pr_err("%s: Voltage at %dmV failed %d\n",
-			__func__, set_volt_mV, rc);
+		pr_err("%s: Voltage at %duV failed %d\n",
+			__func__, set_volt_uV, rc);
 		cpr_irq_clr_and_nack(cpr, BIT(2) | BIT(0));
 		return;
 	}
-	pr_debug("%s: Voltage set at %dmV\n", __func__, set_volt_mV);
+	pr_info("(railway_voltage: %d uV)\n", set_volt_uV);
+
+	cpr->max_volt_set = 0;
 
 	/**
 	 * Save the new calibrated voltage to be re-used
 	 * whenever we return to same mode after a mode switch.
 	 */
-	chip_data->calibrated_mV = set_volt_mV;
+	chip_data->calibrated_uV = set_volt_uV;
 
 	/* Clear all the interrupts */
-	cpr_write_reg(cpr, RBIF_IRQ_CLEAR, 0x3F);
+	cpr_write_reg(cpr, RBIF_IRQ_CLEAR, ALL_CPR_IRQ);
 
 	if (new_volt <= chip_data->Vmin) {
 		/*
@@ -416,16 +422,22 @@
 	chip_data = &cpr->config->cpr_mode_data[cpr->cpr_mode];
 	error_step = cpr_read_reg(cpr, RBCPR_RESULT_0) >> 2;
 	error_step &= 0xF;
-	curr_volt = chip_data->calibrated_mV;
+	curr_volt = chip_data->calibrated_uV;
 
 	if (action == UP) {
+		/* Clear IRQ, ACK and return if Vdd already at Vmax */
+		if (cpr->max_volt_set == 1) {
+			cpr_write_reg(cpr, RBIF_IRQ_CLEAR, ALL_CPR_IRQ);
+			cpr_write_reg(cpr, RBIF_CONT_NACK_CMD, 0x1);
+			return;
+		}
+
 		/**
 		 * Using up margin in the comparison helps avoid having to
 		 * change up threshold values in chip register.
 		 */
 		if (error_step < (cpr->config->up_threshold +
 					cpr->config->up_margin)) {
-			/* FIXME: Avoid repeated dn interrupts if we are here */
 			pr_debug("UP_INT error step too small to set\n");
 			cpr_irq_clr_and_nack(cpr, BIT(4) | BIT(0));
 			return;
@@ -434,6 +446,7 @@
 		/* Calculte new PMIC voltage */
 		new_volt = curr_volt + (error_step * cpr->vp->step_size);
 		pr_debug("UP_INT: new_volt: %d\n", new_volt);
+		pr_info("(UP Voltage recommended by CPR: %d uV)\n", new_volt);
 		cpr_up_event_handler(cpr, new_volt);
 
 	} else if (action == DOWN) {
@@ -443,7 +456,6 @@
 		 */
 		if (error_step < (cpr->config->dn_threshold +
 					cpr->config->dn_margin)) {
-			/* FIXME: Avoid repeated dn interrupts if we are here */
 			pr_debug("DOWN_INT error_step too small to set\n");
 			cpr_irq_clr_and_nack(cpr, BIT(2) | BIT(0));
 			return;
@@ -452,6 +464,7 @@
 		/* Calculte new PMIC voltage */
 		new_volt = curr_volt - (error_step * cpr->vp->step_size);
 		pr_debug("DOWN_INT: new_volt: %d\n", new_volt);
+		pr_info("(DN Voltage recommended by CPR: %d uV)\n", new_volt);
 		cpr_dn_event_handler(cpr, new_volt);
 	}
 }
@@ -513,6 +526,8 @@
 			cpr->config->dn_threshold << 28);
 
 	cpr->curr_osc = chip_data->ring_osc;
+	chip_data->ring_osc_data[cpr->curr_osc].quot =
+		cpr->config->max_quot;
 
 	/**
 	 * Program the gate count and target values
@@ -522,7 +537,7 @@
 		cpr_modify_reg(cpr, RBCPR_GCNT_TARGET(cnt),
 				(GCNT_M | TARGET_M),
 				(chip_data->ring_osc_data[cnt].gcnt << 12 |
-				chip_data->ring_osc_data[cnt].target_count));
+				chip_data->ring_osc_data[cnt].quot));
 		pr_debug("RBCPR_GCNT_TARGET(%d): = 0x%x\n", cnt,
 			readl_relaxed(cpr->base + RBCPR_GCNT_TARGET(cnt)));
 		cnt++;
@@ -536,14 +551,19 @@
 	 * Set with an extra step since it helps as per
 	 * characterization data.
 	 */
-	chip_data->calibrated_mV +=  cpr->vp->step_size;
-	tmp_uV = chip_data->calibrated_mV * 1000;
+	chip_data->calibrated_uV +=  cpr->vp->step_size;
+	tmp_uV = chip_data->calibrated_uV;
 	rc = regulator_set_voltage(cpr->vreg_cx, tmp_uV, tmp_uV);
 	if (rc)
 		pr_err("%s: Voltage set failed %d\n", __func__, rc);
 
-	/* Program the Timer for default delay between CPR measurements */
-	delay_count = 0xFFFF;
+	/*
+	 * Program the Timer Register for delay between CPR measurements
+	 * This is required to allow the device sufficient time for idle
+	 * power collapse.
+	 */
+	delay_count = TIMER_COUNT(cpr->config->ref_clk_khz,
+					cpr->config->delay_us);
 	cpr_write_reg(cpr, RBCPR_TIMER_INTERVAL, delay_count);
 
 	/* Enable the Timer */
@@ -554,53 +574,69 @@
 			SW_AUTO_CONT_ACK_EN);
 }
 
-static void cpr_mode_config(struct msm_cpr *cpr, enum cpr_mode mode)
-{
-	if (cpr->cpr_mode == mode)
-		return;
-
-	cpr->cpr_mode = mode;
-	pr_debug("%s: Switching to %s mode\n", __func__,
-		(mode == TURBO_MODE ? "TURBO" : "NORMAL"));
-
-	/* Configure the new mode */
-	cpr_config(cpr);
-}
-
 static int
 cpr_freq_transition(struct notifier_block *nb, unsigned long val,
 				void *data)
 {
 	struct msm_cpr *cpr = container_of(nb, struct msm_cpr, freq_transition);
 	struct cpufreq_freqs *freqs = data;
+	uint32_t quot, new_freq;
 
 	switch (val) {
 	case CPUFREQ_PRECHANGE:
-		return 0;
 		pr_debug("pre freq change notification to cpr\n");
 
-		disable_irq(cpr->irq);
+		/* Disable Measurement to stop generation of CPR IRQs */
 		cpr_disable(cpr);
+		/* Disable routing of IRQ to App */
+		cpr_irq_set(cpr, INT_MASK & ~MID_INT, 0);
+		disable_irq(cpr->irq);
+		cpr_write_reg(cpr, RBIF_IRQ_CLEAR, ALL_CPR_IRQ);
+		pr_debug("RBCPR_CTL: 0x%x\n",
+			readl_relaxed(cpr->base + RBCPR_CTL));
+		pr_debug("RBIF_IRQ_STATUS: 0x%x\n",
+			cpr_read_reg(cpr, RBIF_IRQ_STATUS));
+		pr_debug("RBIF_IRQ_EN(0): 0x%x\n",
+			cpr_read_reg(cpr, RBIF_IRQ_EN(cpr->config->irq_line)));
+
 		cpr->prev_mode = cpr->cpr_mode;
 		break;
-	case CPUFREQ_POSTCHANGE:
-		return 0;
-		pr_debug("post freq change notification to cpr\n");
 
-		if (freqs->new >= cpr->config->nom_freq_limit)
-			cpr_mode_config(cpr, TURBO_MODE);
-		else
-			cpr_mode_config(cpr, NORMAL_MODE);
+	case CPUFREQ_POSTCHANGE:
+		pr_debug("post freq change notification to cpr\n");
+		/**
+		 * As per chip characterization data, use max nominal freq
+		 * to calculate quot for all lower frequencies too
+		 */
+		new_freq = (freqs->new > cpr->config->max_nom_freq)
+					? freqs->new
+					: cpr->config->max_nom_freq;
+
+		/* Configure CPR for the new frequency */
+		quot = cpr->config->get_quot(cpr->config->max_quot,
+						cpr->config->max_freq / 1000,
+						new_freq / 1000);
+		cpr_modify_reg(cpr, RBCPR_GCNT_TARGET(cpr->curr_osc), TARGET_M,
+				quot);
+		pr_debug("RBCPR_GCNT_TARGET(%d): = 0x%x\n", cpr->curr_osc,
+			readl_relaxed(cpr->base +
+					RBCPR_GCNT_TARGET(cpr->curr_osc)));
+		pr_debug("%s: new_freq: %d, set_freq: %d, quot: %d\n", __func__,
+			freqs->new, new_freq, quot);
+
+		enable_irq(cpr->irq);
 		/**
 		 * Enable all interrupts. One of them could be in a disabled
 		 * state if vdd had hit Vmax / Vmin earlier
 		 */
-		cpr_irq_set(cpr, (UP_INT | DOWN_INT), 1);
-
-		enable_irq(cpr->irq);
-
+		cpr_irq_set(cpr, INT_MASK & ~MID_INT, 1);
+		pr_debug("RBIF_IRQ_EN(0): 0x%x\n",
+			cpr_read_reg(cpr, RBIF_IRQ_EN(cpr->config->irq_line)));
+		pr_debug("RBCPR_CTL: 0x%x\n",
+			readl_relaxed(cpr->base + RBCPR_CTL));
+		pr_debug("RBIF_IRQ_STATUS: 0x%x\n",
+			cpr_read_reg(cpr, RBIF_IRQ_STATUS));
 		cpr_enable(cpr);
-
 		break;
 	default:
 		break;
@@ -614,6 +650,8 @@
 	struct msm_cpr *cpr = dev_get_drvdata(dev);
 	int osc_num = cpr->config->cpr_mode_data->ring_osc;
 
+	cpr->config->clk_enable();
+
 	cpr_write_reg(cpr, RBCPR_TIMER_INTERVAL,
 		cpr_save_state.rbif_timer_interval);
 	cpr_write_reg(cpr, RBIF_IRQ_EN(cpr->config->irq_line),
@@ -628,11 +666,11 @@
 		cpr_save_state.rbcpr_step_quot);
 	cpr_write_reg(cpr, RBIF_SW_VLEVEL,
 		cpr_save_state.rbif_sw_level);
-
-	cpr_enable(cpr);
 	cpr_write_reg(cpr, RBCPR_CTL,
 		cpr_save_state.rbcpr_ctl);
+
 	enable_irq(cpr->irq);
+	cpr_enable(cpr);
 
 	return 0;
 }
@@ -643,6 +681,10 @@
 	struct msm_cpr *cpr = dev_get_drvdata(dev);
 	int osc_num = cpr->config->cpr_mode_data->ring_osc;
 
+	/* Disable CPR measurement before IRQ to avoid pending interrupts */
+	cpr_disable(cpr);
+	disable_irq(cpr->irq);
+
 	cpr_save_state.rbif_timer_interval =
 		cpr_read_reg(cpr, RBCPR_TIMER_INTERVAL);
 	cpr_save_state.rbif_int_en =
@@ -660,9 +702,6 @@
 	cpr_save_state.rbcpr_ctl =
 		cpr_read_reg(cpr, RBCPR_CTL);
 
-	disable_irq(cpr->irq);
-	cpr_disable(cpr);
-
 	return 0;
 }
 
@@ -700,6 +739,7 @@
 	const struct msm_cpr_config *pdata = pdev->dev.platform_data;
 	void __iomem *base;
 	struct resource *mem;
+	struct msm_cpr_mode *chip_data;
 
 	if (!pdata) {
 		pr_err("CPR: Platform data is not available\n");
@@ -766,6 +806,16 @@
 
 	platform_set_drvdata(pdev, cpr);
 
+	chip_data = &cpr->config->cpr_mode_data[cpr->cpr_mode];
+	pr_info("CPR Platform Data (upside_steps: %d) (downside_steps: %d) ",
+		cpr->config->up_threshold, cpr->config->dn_threshold);
+	pr_info("(nominal_voltage: %duV) (turbo_voltage: %duV)\n",
+		cpr->config->cpr_mode_data[NORMAL_MODE].calibrated_uV,
+		cpr->config->cpr_mode_data[TURBO_MODE].calibrated_uV);
+	pr_info("(Current corner: TURBO) (gcnt_target: %d) (quot: %d)\n",
+		chip_data->ring_osc_data[chip_data->ring_osc].gcnt,
+		chip_data->ring_osc_data[chip_data->ring_osc].quot);
+
 	/* Initialze the Debugfs Entry for cpr */
 	res = msm_cpr_debug_init(cpr->base);
 	if (res) {
@@ -793,7 +843,6 @@
 	/* Enable the cpr */
 	cpr_modify_reg(cpr, RBCPR_CTL, LOOP_EN_M, ENABLE_CPR);
 
-
 	cpr->freq_transition.notifier_call = cpr_freq_transition;
 	cpufreq_register_notifier(&cpr->freq_transition,
 					CPUFREQ_TRANSITION_NOTIFIER);
diff --git a/arch/arm/mach-msm/msm_cpr.h b/arch/arm/mach-msm/msm_cpr.h
index 2642b9c..cb665b7 100644
--- a/arch/arm/mach-msm/msm_cpr.h
+++ b/arch/arm/mach-msm/msm_cpr.h
@@ -120,10 +120,10 @@
 
 /**
  * struct msm_vp_data - structure for VP configuration
- * @min_volt_mV: minimum milivolt level for VP
- * @max_volt_mV: maximum milivolt level for VP
- * @default_volt_mV: default milivolt for VP
- * @step_size_mV: step size of voltage
+ * @min_volt: minimum microvolt level for VP
+ * @max_volt: maximum microvolt level for VP
+ * @default_volt: default microvolt for VP
+ * @step_size: step size of voltage in microvolt
  */
 struct msm_cpr_vp_data {
 	int min_volt;
@@ -135,11 +135,11 @@
 /**
  * struct msm_cpr_osc -  Data for CPR ring oscillator
  * @gcnt: gate count value for the oscillator
- * @target_count: target value for ring oscillator
+ * @quot: target value for ring oscillator
  */
 struct msm_cpr_osc {
 	int gcnt;
-	uint32_t target_count;
+	uint32_t quot;
 };
 
 /**
@@ -156,7 +156,7 @@
 	uint32_t step_quot;
 	uint32_t Vmax;
 	uint32_t Vmin;
-	uint32_t calibrated_mV;
+	uint32_t calibrated_uV;
 };
 
 /**
@@ -180,8 +180,13 @@
 	uint32_t dn_threshold;
 	uint32_t up_margin;
 	uint32_t dn_margin;
-	uint32_t nom_freq_limit;
+	uint32_t max_nom_freq;
+	uint32_t max_freq;
+	uint32_t max_quot;
 	struct msm_cpr_vp_data *vp_data;
+	uint32_t (*get_quot)(uint32_t max_quot, uint32_t max_freq,
+				uint32_t new_freq);
+	void (*clk_enable)(void);
 };
 
 /**
diff --git a/arch/arm/mach-msm/rpm-smd.c b/arch/arm/mach-msm/rpm-smd.c
index 5b8284d..cd5556a 100644
--- a/arch/arm/mach-msm/rpm-smd.c
+++ b/arch/arm/mach-msm/rpm-smd.c
@@ -62,7 +62,7 @@
 
 #define DEFAULT_BUFFER_SIZE 256
 #define GFP_FLAG(noirq) (noirq ? GFP_ATOMIC : GFP_KERNEL)
-#define INV_HDR "resource does not exist"
+#define INV_RSC "resource does not exist"
 #define ERR "err\0"
 #define MAX_ERR_BUFFER_SIZE 128
 #define INIT_ERROR 1
@@ -172,8 +172,10 @@
 	int i;
 	int data_size, msg_size;
 
-	if (!handle)
+	if (!handle) {
+		pr_err("%s(): Invalid handle\n", __func__);
 		return -EINVAL;
+	}
 
 	data_size = ALIGN(size, SZ_4);
 	msg_size = data_size + sizeof(struct rpm_request_header);
@@ -191,8 +193,11 @@
 		break;
 	}
 
-	if (i >= handle->num_elements)
+	if (i >= handle->num_elements) {
+		pr_err("%s(): Number of resources exceeds max allocated\n",
+				__func__);
 		return -ENOMEM;
+	}
 
 	if (i == handle->write_idx)
 		handle->write_idx++;
@@ -200,8 +205,10 @@
 	if (!handle->kvp[i].value) {
 		handle->kvp[i].value = kzalloc(data_size, GFP_FLAG(noirq));
 
-		if (!handle->kvp[i].value)
+		if (!handle->kvp[i].value) {
+			pr_err("%s(): Failed malloc\n", __func__);
 			return -ENOMEM;
+		}
 	} else {
 		/* We enter the else case, if a key already exists but the
 		 * data doesn't match. In which case, we should zero the data
@@ -366,13 +373,20 @@
 	return elem;
 }
 
-static int msm_rpm_get_next_msg_id(void)
+static uint32_t msm_rpm_get_next_msg_id(void)
 {
-	int id;
+	uint32_t id;
+
+	/*
+	 * A message id of 0 is used by the driver to indicate a error
+	 * condition. The RPM driver uses a id of 1 to indicate unsent data
+	 * when the data sent over hasn't been modified. This isn't a error
+	 * scenario and wait for ack returns a success when the message id is 1.
+	 */
 
 	do {
 		id = atomic_inc_return(&msm_rpm_msg_id);
-	} while ((id == 0) || msm_rpm_get_entry_from_msg_id(id));
+	} while ((id == 0) || (id == 1) || msm_rpm_get_entry_from_msg_id(id));
 
 	return id;
 }
@@ -459,8 +473,12 @@
 
 	tmp += 2 * sizeof(uint32_t);
 
-	if (!(memcmp(tmp, INV_HDR, min(req_len, sizeof(INV_HDR))-1)))
+	if (!(memcmp(tmp, INV_RSC, min(req_len, sizeof(INV_RSC))-1))) {
+		pr_err("%s(): RPM NACK Unsupported resource\n", __func__);
 		rc = -EINVAL;
+	} else {
+		pr_err("%s(): RPM NACK Invalid header\n", __func__);
+	}
 
 	return rc;
 }
@@ -658,7 +676,8 @@
 	int req_hdr_sz, msg_hdr_sz;
 
 	if (!cdata->msg_hdr.data_len)
-		return 0;
+		return 1;
+
 	req_hdr_sz = sizeof(cdata->req_hdr);
 	msg_hdr_sz = sizeof(cdata->msg_hdr);
 
@@ -676,8 +695,10 @@
 		cdata->buf = kzalloc(msg_size, GFP_FLAG(noirq));
 	}
 
-	if (!cdata->buf)
+	if (!cdata->buf) {
+		pr_err("%s(): Failed malloc\n", __func__);
 		return 0;
+	}
 
 	tmpbuff = cdata->buf;
 
@@ -722,7 +743,7 @@
 	ret = smd_write_avail(msm_rpm_data.ch_info);
 
 	if (ret < 0) {
-		pr_warn("%s(): SMD not initialized\n", __func__);
+		pr_err("%s(): SMD not initialized\n", __func__);
 		spin_unlock_irqrestore(&msm_rpm_data.smd_lock_write, flags);
 		return 0;
 	}
@@ -749,7 +770,7 @@
 	} else if (ret < msg_size) {
 		struct msm_rpm_wait_data *rc;
 		ret = 0;
-		pr_info("Failed to write data msg_size:%d ret:%d\n",
+		pr_err("Failed to write data msg_size:%d ret:%d\n",
 				msg_size, ret);
 		rc = msm_rpm_get_entry_from_msg_id(cdata->msg_hdr.msg_id);
 		if (rc)
@@ -774,8 +795,13 @@
 {
 	struct msm_rpm_wait_data *elem;
 
-	if (!msg_id)
-		return -EINVAL;
+	if (!msg_id) {
+		pr_err("%s(): Invalid msg id\n", __func__);
+		return -ENOMEM;
+	}
+
+	if (msg_id == 1)
+		return 0;
 
 	if (standalone)
 		return 0;
@@ -798,8 +824,13 @@
 	uint32_t id = 0;
 	int count = 0;
 
-	if (!msg_id)
-		return -EINVAL;
+	if (!msg_id)  {
+		pr_err("%s(): Invalid msg id\n", __func__);
+		return -ENOMEM;
+	}
+
+	if (msg_id == 1)
+		return 0;
 
 	if (standalone)
 		return 0;
diff --git a/drivers/gpio/qpnp-pin.c b/drivers/gpio/qpnp-pin.c
index 7bfb208..67a2e6b 100644
--- a/drivers/gpio/qpnp-pin.c
+++ b/drivers/gpio/qpnp-pin.c
@@ -32,11 +32,17 @@
 
 #define Q_REG_STATUS1			0x8
 #define Q_REG_STATUS1_VAL_MASK		0x1
-#define Q_REG_STATUS1_GPIO_EN_MASK	0x2
+#define Q_REG_STATUS1_GPIO_EN_REV0_MASK	0x2
+#define Q_REG_STATUS1_GPIO_EN_MASK	0x80
 #define Q_REG_STATUS1_MPP_EN_MASK	0x80
 
 #define Q_NUM_CTL_REGS			0xD
 
+/* revision registers base address offsets */
+#define Q_REG_DIG_MINOR_REV		0x0
+#define Q_REG_DIG_MAJOR_REV		0x1
+#define Q_REG_ANA_MINOR_REV		0x2
+
 /* type registers base address offsets */
 #define Q_REG_TYPE			0x4
 #define Q_REG_SUBTYPE			0x5
@@ -158,6 +164,7 @@
 	u8 num_ctl_regs;		/* usable number on this pin */
 	u8 type;			/* peripheral type */
 	u8 subtype;			/* peripheral subtype */
+	u8 dig_major_rev;
 	struct device_node *node;
 	enum qpnp_pin_param_type params[Q_NUM_PARAMS];
 	struct qpnp_pin_chip *q_chip;
@@ -646,9 +653,14 @@
 				Q_REG_ADDR(q_spec, Q_REG_STATUS1),
 				&buf[0], 1);
 
-		en_mask = q_spec->type == Q_GPIO_TYPE ?
-				Q_REG_STATUS1_GPIO_EN_MASK :
-				Q_REG_STATUS1_MPP_EN_MASK;
+		if (q_spec->type == Q_GPIO_TYPE && q_spec->dig_major_rev == 0)
+			en_mask = Q_REG_STATUS1_GPIO_EN_REV0_MASK;
+		else if (q_spec->type == Q_GPIO_TYPE &&
+			 q_spec->dig_major_rev > 0)
+			en_mask = Q_REG_STATUS1_GPIO_EN_MASK;
+		else /* MPP */
+			en_mask = Q_REG_STATUS1_MPP_EN_MASK;
+
 		if (!(buf[0] & en_mask))
 			return -EPERM;
 
@@ -1099,6 +1111,28 @@
 }
 #endif
 
+static int qpnp_pin_is_valid_pin(struct qpnp_pin_spec *q_spec)
+{
+	if (q_spec->type == Q_GPIO_TYPE)
+		switch (q_spec->subtype) {
+		case Q_GPIO_SUBTYPE_GPIO_4CH:
+		case Q_GPIO_SUBTYPE_GPIOC_4CH:
+		case Q_GPIO_SUBTYPE_GPIO_8CH:
+		case Q_GPIO_SUBTYPE_GPIOC_8CH:
+			return 1;
+		}
+	else if (q_spec->type == Q_MPP_TYPE)
+		switch (q_spec->subtype) {
+		case Q_MPP_SUBTYPE_4CH_NO_ANA_OUT:
+		case Q_MPP_SUBTYPE_4CH_NO_SINK:
+		case Q_MPP_SUBTYPE_4CH_FULL_FUNC:
+		case Q_MPP_SUBTYPE_8CH_FULL_FUNC:
+			return 1;
+		}
+
+	return 0;
+}
+
 static int qpnp_pin_probe(struct spmi_device *spmi)
 {
 	struct qpnp_pin_chip *q_chip;
@@ -1108,7 +1142,7 @@
 	int i, rc;
 	int lowest_gpio = UINT_MAX, highest_gpio = 0;
 	u32 intspec[3], gpio;
-	char buf[2];
+	char version[Q_REG_SUBTYPE - Q_REG_DIG_MAJOR_REV + 1];
 	const char *dev_name;
 
 	dev_name = spmi_get_primary_dev_name(spmi);
@@ -1218,14 +1252,23 @@
 		q_spec->q_chip = q_chip;
 
 		rc = spmi_ext_register_readl(spmi->ctrl, q_spec->slave,
-				Q_REG_ADDR(q_spec, Q_REG_TYPE), &buf[0], 2);
+				Q_REG_ADDR(q_spec, Q_REG_DIG_MAJOR_REV),
+				&version[0], ARRAY_SIZE(version));
 		if (rc) {
 			dev_err(&spmi->dev, "%s: unable to read type regs\n",
 						__func__);
 			goto err_probe;
 		}
-		q_spec->type	= buf[0];
-		q_spec->subtype = buf[1];
+		q_spec->dig_major_rev = version[Q_REG_DIG_MAJOR_REV -
+						Q_REG_DIG_MAJOR_REV];
+		q_spec->type	= version[Q_REG_TYPE - Q_REG_DIG_MAJOR_REV];
+		q_spec->subtype = version[Q_REG_SUBTYPE - Q_REG_DIG_MAJOR_REV];
+
+		if (!qpnp_pin_is_valid_pin(q_spec)) {
+			dev_err(&spmi->dev, "%s: invalid pin type (type=0x%x subtype=0x%x)\n",
+				       __func__, q_spec->type, q_spec->subtype);
+			goto err_probe;
+		}
 
 		rc = qpnp_pin_ctl_regs_init(q_spec);
 		if (rc)
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index bd22233..74493f4 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -226,6 +226,10 @@
 
 	adreno_idle(device);
 
+	if (adreno_is_a20x(adreno_dev) && adreno_dev->drawctxt_active)
+		kgsl_setstate(&device->mmu, adreno_dev->drawctxt_active->id,
+			KGSL_MMUFLAGS_PTUPDATE);
+
 	kgsl_sharedmem_free(&drawctxt->gpustate);
 	kgsl_sharedmem_free(&drawctxt->context_gmem_shadow.gmemshadow);
 
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index c1617bff..085b632 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -328,12 +328,14 @@
 	dev->clk_state = state;
 	if (state != 0) {
 		clk_enable(dev->clk);
-		clk_enable(dev->pclk);
+		if (!dev->pdata->keep_ahb_clk_on)
+			clk_enable(dev->pclk);
 	} else {
 		qup_update_state(dev, QUP_RESET_STATE);
 		clk_disable(dev->clk);
 		qup_config_core_on_en(dev);
-		clk_disable(dev->pclk);
+		if (!dev->pdata->keep_ahb_clk_on)
+			clk_disable(dev->pclk);
 	}
 }
 
@@ -1325,6 +1327,12 @@
 	dev->clk_state = 0;
 	clk_prepare(dev->clk);
 	clk_prepare(dev->pclk);
+	/* If the same AHB clock is used on Modem side
+	 * switch it on here itself and don't switch it
+	 * on and off during suspend and resume.
+	 */
+	if (dev->pdata->keep_ahb_clk_on)
+		clk_enable(dev->pclk);
 	setup_timer(&dev->pwr_timer, qup_i2c_pwr_timer, (unsigned long) dev);
 
 	pm_runtime_set_active(&pdev->dev);
@@ -1396,9 +1404,11 @@
 	free_irq(dev->err_irq, dev);
 	i2c_del_adapter(&dev->adapter);
 	clk_unprepare(dev->clk);
-	clk_unprepare(dev->pclk);
+	if (!dev->pdata->keep_ahb_clk_on) {
+		clk_unprepare(dev->pclk);
+		clk_put(dev->pclk);
+	}
 	clk_put(dev->clk);
-	clk_put(dev->pclk);
 	qup_i2c_free_gpios(dev);
 	if (dev->gsbi)
 		iounmap(dev->gsbi);
@@ -1434,7 +1444,8 @@
 	if (dev->clk_state != 0)
 		qup_i2c_pwr_mgmt(dev, 0);
 	clk_unprepare(dev->clk);
-	clk_unprepare(dev->pclk);
+	if (!dev->pdata->keep_ahb_clk_on)
+		clk_unprepare(dev->pclk);
 	qup_i2c_free_gpios(dev);
 	return 0;
 }
@@ -1445,7 +1456,8 @@
 	struct qup_i2c_dev *dev = platform_get_drvdata(pdev);
 	BUG_ON(qup_i2c_request_gpios(dev) != 0);
 	clk_prepare(dev->clk);
-	clk_prepare(dev->pclk);
+	if (!dev->pdata->keep_ahb_clk_on)
+		clk_prepare(dev->pclk);
 	dev->suspended = 0;
 	return 0;
 }
diff --git a/drivers/input/misc/mpu3050.c b/drivers/input/misc/mpu3050.c
index d3da652..04a7598 100644
--- a/drivers/input/misc/mpu3050.c
+++ b/drivers/input/misc/mpu3050.c
@@ -123,6 +123,7 @@
 	struct delayed_work input_work;
 	u32    use_poll;
 	u32    poll_interval;
+	u32    dlpf_index;
 };
 
 struct sensor_regulator {
@@ -137,6 +138,39 @@
 	{NULL, "vlogic", 1800000, 1800000},
 };
 
+struct dlpf_cfg_tb {
+	u8  cfg;	/* cfg index */
+	u32 lpf_bw;	/* low pass filter bandwidth in Hz */
+	u32 sample_rate; /* analog sample rate in Khz, 1 or 8 */
+};
+
+static struct dlpf_cfg_tb dlpf_table[] = {
+	{6,   5, 1},
+	{5,  10, 1},
+	{4,  20, 1},
+	{3,  42, 1},
+	{2,  98, 1},
+	{1, 188, 1},
+	{0, 256, 8},
+};
+
+static u8 interval_to_dlpf_cfg(u32 interval)
+{
+	u32 sample_rate = 1000 / interval;
+	u32 i;
+
+	/* the filter bandwidth needs to be greater or
+	 * equal to half of the sample rate
+	 */
+	for (i = 0; i < sizeof(dlpf_table)/sizeof(dlpf_table[0]); i++) {
+		if (dlpf_table[i].lpf_bw * 2 >= sample_rate)
+			return i;
+	}
+
+	/* return the maximum possible */
+	return --i;
+}
+
 static int mpu3050_config_regulator(struct i2c_client *client, bool on)
 {
 	int rc = 0, i;
@@ -217,6 +251,9 @@
 {
 	struct mpu3050_sensor *sensor = dev_get_drvdata(dev);
 	unsigned long interval_ms;
+	unsigned int  dlpf_index;
+	u8  divider, reg;
+	int ret;
 
 	if (kstrtoul(buf, 10, &interval_ms))
 		return -EINVAL;
@@ -224,12 +261,27 @@
 		(interval_ms > MPU3050_MAX_POLL_INTERVAL))
 		return -EINVAL;
 
-	if (sensor)
-		sensor->poll_interval = interval_ms;
+	dlpf_index = interval_to_dlpf_cfg(interval_ms);
+	divider = interval_ms * dlpf_table[dlpf_index].sample_rate - 1;
 
-	/* Output frequency divider. The poll interval */
-	i2c_smbus_write_byte_data(sensor->client, MPU3050_SMPLRT_DIV,
-					interval_ms - 1);
+	if (sensor->dlpf_index != dlpf_index) {
+		/* Set low pass filter and full scale */
+		reg = dlpf_table[dlpf_index].cfg;
+		reg |= MPU3050_DEFAULT_FS_RANGE << 3;
+		reg |= MPU3050_EXT_SYNC_NONE << 5;
+		ret = i2c_smbus_write_byte_data(sensor->client,
+				MPU3050_DLPF_FS_SYNC, reg);
+		if (ret == 0)
+			sensor->dlpf_index = dlpf_index;
+	}
+
+	if (sensor->poll_interval != interval_ms) {
+		/* Output frequency divider. The poll interval */
+		ret = i2c_smbus_write_byte_data(sensor->client,
+				MPU3050_SMPLRT_DIV, divider);
+		if (ret == 0)
+			sensor->poll_interval = interval_ms;
+	}
 
 	return size;
 }
@@ -482,8 +534,8 @@
 		return ret;
 
 	/* Set low pass filter and full scale */
-	reg = MPU3050_DEFAULT_FS_RANGE;
-	reg |= MPU3050_DLPF_CFG_42HZ << 3;
+	reg = MPU3050_DLPF_CFG_42HZ;
+	reg |= MPU3050_DEFAULT_FS_RANGE << 3;
 	reg |= MPU3050_EXT_SYNC_NONE << 5;
 	ret = i2c_smbus_write_byte_data(client, MPU3050_DLPF_FS_SYNC, reg);
 	if (ret < 0)
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 577648f..3dc0fe7 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -332,7 +332,7 @@
 	uint32_t data_offset;
 };
 
-#define MSM_DEV_INST_MAX                    16
+#define MSM_DEV_INST_MAX                    24
 struct msm_cam_v4l2_dev_inst {
 	struct v4l2_fh  eventHandle;
 	struct vb2_queue vid_bufq;
diff --git a/drivers/media/video/vcap_v4l2.c b/drivers/media/video/vcap_v4l2.c
index e8d9e04..407bf2e 100644
--- a/drivers/media/video/vcap_v4l2.c
+++ b/drivers/media/video/vcap_v4l2.c
@@ -1117,6 +1117,12 @@
 		return -ENOTRECOVERABLE;
 	}
 
+	if (!dev->vp_dummy_complete) {
+		pr_err("VCAP Err: %s: VP dummy read not complete",
+			__func__);
+		return -EINVAL;
+	}
+
 	switch (c_data->op_mode) {
 	case VC_VCAP_OP:
 		mutex_lock(&dev->dev_mutex);
@@ -1390,19 +1396,13 @@
 		}
 		dev->vc_resource = 0;
 		mutex_unlock(&dev->dev_mutex);
+		c_data->streaming = 0;
 		rc = vb2_streamoff(&c_data->vc_vidq,
 				V4L2_BUF_TYPE_VIDEO_CAPTURE);
-		if (rc >= 0) {
-			c_data->streaming = 0;
+		if (rc >= 0)
 			atomic_set(&c_data->dev->vc_enabled, 0);
-		}
 		return rc;
 	case VP_VCAP_OP:
-		if (!dev->vp_dummy_complete) {
-			pr_err("VCAP Err: %s: VP dummy read not complete",
-				__func__);
-			return -EINVAL;
-		}
 		if (c_data != dev->vp_client) {
 			pr_err("VCAP Err: %s: VP held by other client",
 				__func__);
@@ -1441,11 +1441,6 @@
 		atomic_set(&c_data->dev->vp_enabled, 0);
 		return rc;
 	case VC_AND_VP_VCAP_OP:
-		if (!dev->vp_dummy_complete) {
-			pr_err("VCAP Err: %s: VP dummy read not complete",
-				__func__);
-			return -EINVAL;
-		}
 		if (c_data != dev->vp_client || c_data != dev->vc_client) {
 			pr_err("VCAP Err: %s: VC/VP held by other client",
 				__func__);
diff --git a/drivers/media/video/vcap_vc.c b/drivers/media/video/vcap_vc.c
index 62cc306..966fa4b 100644
--- a/drivers/media/video/vcap_vc.c
+++ b/drivers/media/video/vcap_vc.c
@@ -120,6 +120,13 @@
 
 	dprintk(1, "%s: irq=0x%08x\n", __func__, irq);
 
+	c_data = dev->vc_client;
+	if (!c_data->streaming) {
+		writel_iowmb(irq, VCAP_VC_INT_CLEAR);
+		pr_err("VC no longer streaming\n");
+		return IRQ_HANDLED;
+	}
+
 	v4l2_evt.id = 0;
 	if (irq & 0x8000200) {
 		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
@@ -161,7 +168,6 @@
 		pr_err("VC: There is no active vc client\n");
 		return IRQ_HANDLED;
 	}
-	c_data = dev->vc_client;
 
 	spin_lock(&dev->vc_client->cap_slock);
 	if (list_empty(&dev->vc_client->vid_vc_action.active)) {
@@ -316,15 +322,34 @@
 void vc_stop_capture(struct vcap_client_data *c_data)
 {
 	struct vcap_dev *dev = c_data->dev;
-	int rc;
+	unsigned int reg;
+	int timeout;
 
-	rc = readl_relaxed(VCAP_VC_CTRL);
-	writel_iowmb(rc & ~(0x1), VCAP_VC_CTRL);
-
-	if (atomic_read(&dev->vc_enabled) == 1)
-		disable_irq(dev->vcirq->start);
-
+	writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
+	writel_iowmb(0x0, VCAP_VC_INT_MASK);
 	flush_workqueue(dev->vcap_wq);
+	if (atomic_read(&dev->vc_enabled) == 1)
+		disable_irq_nosync(dev->vcirq->start);
+
+	writel_iowmb(0x00000000, VCAP_VC_CTRL);
+	writel_iowmb(0x00000001, VCAP_SW_RESET_REQ);
+	timeout = 10000;
+	while (1) {
+		reg = (readl_relaxed(VCAP_SW_RESET_STATUS) & 0x1);
+		if (!reg)
+			break;
+		timeout--;
+		if (timeout == 0) {
+			/* This should not happen */
+			pr_err("VC is not resetting properly\n");
+			writel_iowmb(0x00000000, VCAP_SW_RESET_REQ);
+			break;
+		}
+	}
+
+	reg = readl_relaxed(VCAP_VC_NPL_CTRL);
+	reg = readl_relaxed(VCAP_VC_NPL_CTRL);
+	writel_iowmb(0x00000002, VCAP_VC_NPL_CTRL);
 }
 
 int config_vc_format(struct vcap_client_data *c_data)
@@ -336,21 +361,20 @@
 	dev = c_data->dev;
 
 	/* restart VC */
-	writel_relaxed(0x00000001, VCAP_SW_RESET_REQ);
+	writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
+	writel_iowmb(0x00000001, VCAP_SW_RESET_REQ);
 	timeout = 10000;
 	while (1) {
-		rc = (readl_relaxed(VCAP_SW_RESET_STATUS) & 0x1);
-		if (!rc)
+		if (!(readl_relaxed(VCAP_SW_RESET_STATUS) & 0x1))
 			break;
 		timeout--;
 		if (timeout == 0) {
 			pr_err("VC is not resetting properly\n");
+			writel_iowmb(0x00000002, VCAP_VC_NPL_CTRL);
 			return -EINVAL;
 		}
 	}
-	writel_relaxed(0x00000000, VCAP_SW_RESET_REQ);
 
-	writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
 	rc = readl_relaxed(VCAP_VC_NPL_CTRL);
 	rc = readl_relaxed(VCAP_VC_NPL_CTRL);
 	writel_iowmb(0x00000002, VCAP_VC_NPL_CTRL);
diff --git a/drivers/media/video/vcap_vc.h b/drivers/media/video/vcap_vc.h
index 792fb14..76693bb 100644
--- a/drivers/media/video/vcap_vc.h
+++ b/drivers/media/video/vcap_vc.h
@@ -19,14 +19,8 @@
 
 #define VCAP_HARDWARE_VERSION 0x10000000
 
-#define VCAP_BASE (dev->vcapbase)
-#define VCAP_OFFSET(off) (VCAP_BASE + off)
-
 #define VCAP_HARDWARE_VERSION_REG (VCAP_BASE + 0x0000)
 
-#define VCAP_SW_RESET_REQ (VCAP_BASE + 0x0024)
-#define VCAP_SW_RESET_STATUS (VCAP_BASE + 0x0028)
-
 #define VCAP_VC_CTRL (VCAP_BASE + 0x0800)
 #define VCAP_VC_NPL_CTRL (VCAP_BASE + 0x0804)
 #define VCAP_VC_POLARITY (VCAP_BASE + 0x081c)
diff --git a/drivers/media/video/vcap_vp.c b/drivers/media/video/vcap_vp.c
index ba053f2..f8f27d4 100644
--- a/drivers/media/video/vcap_vp.c
+++ b/drivers/media/video/vcap_vp.c
@@ -74,6 +74,12 @@
 	dev = c_data->dev;
 	dprintk(2, "Start setup buffers\n");
 
+	if (dev->vp_shutdown) {
+		dprintk(1, "%s: VP shutting down, no buf setup\n",
+			__func__);
+		return -EPERM;
+	}
+
 	/* No need to verify vp_client is not NULL caller does so */
 	vp_act = &dev->vp_client->vid_vp_action;
 
@@ -262,6 +268,8 @@
 		writel_relaxed(0x00000000, VCAP_VP_INTERRUPT_ENABLE);
 		writel_iowmb(irq, VCAP_VP_INT_CLEAR);
 		atomic_set(&dev->vp_enabled, 0);
+		if (dev->vp_shutdown)
+			wake_up(&dev->vp_dummy_waitq);
 		return;
 	}
 
@@ -350,30 +358,60 @@
 	return IRQ_HANDLED;
 }
 
+int vp_sw_reset(struct vcap_dev *dev)
+{
+	int timeout;
+	writel_iowmb(0x00000010, VCAP_SW_RESET_REQ);
+	timeout = 10000;
+	while (1) {
+		if (!(readl_relaxed(VCAP_SW_RESET_STATUS) & 0x10))
+			break;
+		timeout--;
+		if (timeout == 0) {
+			/* This should not happen */
+			pr_err("VP is not resetting properly\n");
+			writel_iowmb(0x00000000, VCAP_SW_RESET_REQ);
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
 void vp_stop_capture(struct vcap_client_data *c_data)
 {
 	struct vcap_dev *dev = c_data->dev;
+	int rc;
 
-	writel_iowmb(0x00000000, VCAP_VP_CTRL);
+	dev->vp_shutdown = true;
 	flush_workqueue(dev->vcap_wq);
 
-	if (atomic_read(&dev->vp_enabled) == 1)
-		disable_irq(dev->vpirq->start);
+	if (atomic_read(&dev->vp_enabled) == 1) {
+		rc = wait_event_interruptible_timeout(dev->vp_dummy_waitq,
+				!atomic_read(&dev->vp_enabled),
+				msecs_to_jiffies(50));
+		if (rc == 0 && atomic_read(&dev->vp_enabled) == 1) {
+			/* This should not happen, if it does hw is stuck */
+			pr_err("%s: VP Timeout and VP still running\n",
+				__func__);
+		}
+	}
 
-	writel_iowmb(0x00000001, VCAP_VP_SW_RESET);
-	writel_iowmb(0x00000000, VCAP_VP_SW_RESET);
+	vp_sw_reset(dev);
+	dev->vp_shutdown = false;
 }
 
 int config_vp_format(struct vcap_client_data *c_data)
 {
 	struct vcap_dev *dev = c_data->dev;
+	int rc;
 
 	INIT_WORK(&dev->vp_to_vc_work.work, mov_buf_to_vc);
 	dev->vp_to_vc_work.cd = c_data;
 
 	/* SW restart VP */
-	writel_iowmb(0x00000001, VCAP_VP_SW_RESET);
-	writel_iowmb(0x00000000, VCAP_VP_SW_RESET);
+	rc = vp_sw_reset(dev);
+	if (rc < 0)
+		return rc;
 
 	/* Film Mode related settings */
 	writel_iowmb(0x00000000, VCAP_VP_FILM_PROJECTION_T0);
@@ -668,20 +706,18 @@
 
 	dev->vp_dummy_event = true;
 
+	enable_irq(dev->vpirq->start);
 	writel_relaxed(0x01100101, VCAP_VP_INTERRUPT_ENABLE);
 	writel_iowmb(0x00000000, VCAP_VP_CTRL);
 	writel_iowmb(0x00010000, VCAP_VP_CTRL);
 
-	enable_irq(dev->vpirq->start);
 	rc = wait_event_interruptible_timeout(dev->vp_dummy_waitq,
 		dev->vp_dummy_complete, msecs_to_jiffies(50));
 	if (!rc && !dev->vp_dummy_complete) {
 		pr_err("%s: VP dummy event timeout", __func__);
 		rc = -ETIME;
-		writel_iowmb(0x00000000, VCAP_VP_CTRL);
 
-		writel_iowmb(0x00000001, VCAP_VP_SW_RESET);
-		writel_iowmb(0x00000000, VCAP_VP_SW_RESET);
+		vp_sw_reset(dev);
 		dev->vp_dummy_complete = false;
 	}
 
diff --git a/drivers/media/video/vcap_vp.h b/drivers/media/video/vcap_vp.h
index b2b00e9..2ad5848 100644
--- a/drivers/media/video/vcap_vp.h
+++ b/drivers/media/video/vcap_vp.h
@@ -17,9 +17,6 @@
 
 #include <media/vcap_v4l2.h>
 
-#define VCAP_BASE (dev->vcapbase)
-#define VCAP_OFFSET(off) (VCAP_BASE + off)
-
 #define VCAP_VP_INT_STATUS (VCAP_BASE + 0x404)
 #define VCAP_VP_INT_CLEAR (VCAP_BASE + 0x40C)
 
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 2b278be..a86798d 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1351,9 +1351,11 @@
 		 */
 		if (!(data->mrq->cmd->opcode == MMC_BUS_TEST_W
 			|| data->mrq->cmd->opcode == MMC_BUS_TEST_R)) {
-			pr_err("%s: CMD%d: Data timeout\n",
+			pr_err("%s: CMD%d: Data timeout. DAT0 => %d\n",
 				 mmc_hostname(host->mmc),
-				 data->mrq->cmd->opcode);
+				 data->mrq->cmd->opcode,
+				 (readl_relaxed(host->base
+				 + MCI_TEST_INPUT) & 0x2) ? 1 : 0);
 			data->error = -ETIMEDOUT;
 			msmsdcc_dump_sdcc_state(host);
 		}
@@ -3358,10 +3360,10 @@
 {
 	struct device *dev = mmc_dev(host->mmc);
 
-	pr_info("%s: PM: sdcc_suspended=%d, pending_resume=%d, sdcc_suspending=%d\n",
+	pr_err("%s: PM: sdcc_suspended=%d, pending_resume=%d, sdcc_suspending=%d\n",
 		mmc_hostname(host->mmc), host->sdcc_suspended,
 		host->pending_resume, host->sdcc_suspending);
-	pr_info("%s: RPM: runtime_status=%d, usage_count=%d,"
+	pr_err("%s: RPM: runtime_status=%d, usage_count=%d,"
 		" is_suspended=%d, disable_depth=%d, runtime_error=%d,"
 		" request_pending=%d, request=%d\n",
 		mmc_hostname(host->mmc), dev->power.runtime_status,
@@ -4847,10 +4849,10 @@
 	if (!base)
 		return;
 
-	pr_info("===== %s: Register Dumps @phys_base=0x%x, @virt_base=0x%x"
+	pr_err("===== %s: Register Dumps @phys_base=0x%x, @virt_base=0x%x"
 		" =====\n", name, phys_base, (u32)base);
 	for (i = 0; i < no_of_regs; i = i + 4) {
-		pr_info("Reg=0x%.2x: 0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x\n", i*4,
+		pr_err("Reg=0x%.2x: 0x%.8x, 0x%.8x, 0x%.8x, 0x%.8x\n", i*4,
 			(u32)readl_relaxed(base + i*4),
 			(u32)readl_relaxed(base + ((i+1)*4)),
 			(u32)readl_relaxed(base + ((i+2)*4)),
@@ -4861,25 +4863,29 @@
 static void msmsdcc_dump_sdcc_state(struct msmsdcc_host *host)
 {
 	/* Dump current state of SDCC clocks, power and irq */
-	pr_info("%s: SDCC PWR is %s\n", mmc_hostname(host->mmc),
+	pr_err("%s: SDCC PWR is %s\n", mmc_hostname(host->mmc),
 		(host->pwr ? "ON" : "OFF"));
-	pr_info("%s: SDCC clks are %s, MCLK rate=%d\n",
+	pr_err("%s: SDCC clks are %s, MCLK rate=%d\n",
 		mmc_hostname(host->mmc),
 		(atomic_read(&host->clks_on) ? "ON" : "OFF"),
 		(u32)clk_get_rate(host->clk));
-	pr_info("%s: SDCC irq is %s\n", mmc_hostname(host->mmc),
+	pr_err("%s: SDCC irq is %s\n", mmc_hostname(host->mmc),
 		(host->sdcc_irq_disabled ? "disabled" : "enabled"));
 
 	/* Now dump SDCC registers. Don't print FIFO registers */
-	if (atomic_read(&host->clks_on))
+	if (atomic_read(&host->clks_on)) {
 		msmsdcc_print_regs("SDCC-CORE", host->base,
 				   host->core_memres->start, 28);
+		pr_err("%s: MCI_TEST_INPUT = 0x%.8x\n",
+			mmc_hostname(host->mmc),
+			readl_relaxed(host->base + MCI_TEST_INPUT));
+	}
 
 	if (host->curr.data) {
 		if (!msmsdcc_is_dma_possible(host, host->curr.data))
-			pr_info("%s: PIO mode\n", mmc_hostname(host->mmc));
+			pr_err("%s: PIO mode\n", mmc_hostname(host->mmc));
 		else if (is_dma_mode(host))
-			pr_info("%s: ADM mode: busy=%d, chnl=%d, crci=%d\n",
+			pr_err("%s: ADM mode: busy=%d, chnl=%d, crci=%d\n",
 				mmc_hostname(host->mmc), host->dma.busy,
 				host->dma.channel, host->dma.crci);
 		else if (is_sps_mode(host)) {
@@ -4887,16 +4893,16 @@
 				msmsdcc_print_regs("SDCC-DML", host->dml_base,
 						   host->dml_memres->start,
 						   16);
-			pr_info("%s: SPS mode: busy=%d\n",
+			pr_err("%s: SPS mode: busy=%d\n",
 				mmc_hostname(host->mmc), host->sps.busy);
 		}
 
-		pr_info("%s: xfer_size=%d, data_xfered=%d, xfer_remain=%d\n",
+		pr_err("%s: xfer_size=%d, data_xfered=%d, xfer_remain=%d\n",
 			mmc_hostname(host->mmc), host->curr.xfer_size,
 			host->curr.data_xfered, host->curr.xfer_remain);
 	}
 
-	pr_info("%s: got_dataend=%d, prog_enable=%d,"
+	pr_err("%s: got_dataend=%d, prog_enable=%d,"
 		" wait_for_auto_prog_done=%d, got_auto_prog_done=%d,"
 		" req_tout_ms=%d\n", mmc_hostname(host->mmc),
 		host->curr.got_dataend, host->prog_enable,
diff --git a/drivers/net/ethernet/msm/msm_rmnet_bam.c b/drivers/net/ethernet/msm/msm_rmnet_bam.c
index fbe8d3c..295c55c 100644
--- a/drivers/net/ethernet/msm/msm_rmnet_bam.c
+++ b/drivers/net/ethernet/msm/msm_rmnet_bam.c
@@ -29,6 +29,7 @@
 #include <linux/if_arp.h>
 #include <linux/msm_rmnet.h>
 #include <linux/platform_device.h>
+#include <net/pkt_sched.h>
 
 #ifdef CONFIG_HAS_EARLYSUSPEND
 #include <linux/earlysuspend.h>
@@ -638,6 +639,16 @@
 			dev->name);
 		break;
 
+	case RMNET_IOCTL_FLOW_ENABLE:
+		tc_qdisc_flow_control(dev, (u32)ifr->ifr_data, 1);
+		DBG0("[%s] rmnet_ioctl(): enabled flow", dev->name);
+		break;
+
+	case RMNET_IOCTL_FLOW_DISABLE:
+		tc_qdisc_flow_control(dev, (u32)ifr->ifr_data, 0);
+		DBG0("[%s] rmnet_ioctl(): disabled flow", dev->name);
+		break;
+
 	case RMNET_IOCTL_GET_QOS:           /* Get QoS header state    */
 		ifr->ifr_ifru.ifru_data =
 			(void *)(p->operation_mode & RMNET_MODE_QOS);
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 49e6ee5..6a4e50c 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -3697,24 +3697,9 @@
 						chip->led_src_config, rc);
 	}
 
-	/* Workarounds for die 1.1 and 1.0 */
-	if (pm8xxx_get_revision(chip->dev->parent) < PM8XXX_REVISION_8921_2p0) {
-		pm8xxx_writeb(chip->dev->parent, CHG_BUCK_CTRL_TEST2, 0xF1);
-		pm8xxx_writeb(chip->dev->parent, CHG_BUCK_CTRL_TEST3, 0xCE);
-		pm8xxx_writeb(chip->dev->parent, CHG_BUCK_CTRL_TEST3, 0xD8);
-
-		/* software workaround for correct battery_id detection */
-		pm8xxx_writeb(chip->dev->parent, PSI_TXRX_SAMPLE_DATA_0, 0xFF);
-		pm8xxx_writeb(chip->dev->parent, PSI_TXRX_SAMPLE_DATA_1, 0xFF);
-		pm8xxx_writeb(chip->dev->parent, PSI_TXRX_SAMPLE_DATA_2, 0xFF);
-		pm8xxx_writeb(chip->dev->parent, PSI_TXRX_SAMPLE_DATA_3, 0xFF);
-		pm8xxx_writeb(chip->dev->parent, PSI_CONFIG_STATUS, 0x0D);
-		udelay(100);
-		pm8xxx_writeb(chip->dev->parent, PSI_CONFIG_STATUS, 0x0C);
-	}
-
 	/* Workarounds for die 3.0 */
-	if (pm8xxx_get_revision(chip->dev->parent) == PM8XXX_REVISION_8921_3p0)
+	if (pm8xxx_get_revision(chip->dev->parent) == PM8XXX_REVISION_8921_3p0
+	&& pm8xxx_get_version(chip->dev->parent) == PM8XXX_VERSION_8921)
 		pm8xxx_writeb(chip->dev->parent, CHG_BUCK_CTRL_TEST3, 0xAC);
 
 	/* Enable isub_fine resolution AICL for PM8917 */
diff --git a/drivers/thermal/msm8960_tsens.c b/drivers/thermal/msm8960_tsens.c
index 78a1292..daf0564 100644
--- a/drivers/thermal/msm8960_tsens.c
+++ b/drivers/thermal/msm8960_tsens.c
@@ -159,6 +159,7 @@
 	enum platform_type		hw_type;
 	int				pm_tsens_thr_data;
 	int				pm_tsens_cntl;
+	struct work_struct		tsens_work;
 	struct tsens_tm_device_sensor	sensor[0];
 };
 
@@ -610,9 +611,10 @@
 					NULL, "type");
 }
 
-static irqreturn_t tsens_isr(int irq, void *data)
+static void tsens_scheduler_fn(struct work_struct *work)
 {
-	struct tsens_tm_device *tm = data;
+	struct tsens_tm_device *tm = container_of(work, struct tsens_tm_device,
+					tsens_work);
 	unsigned int threshold, threshold_low, i, code, reg, sensor, mask;
 	unsigned int sensor_addr;
 	bool upper_th_x, lower_th_x;
@@ -627,6 +629,7 @@
 		writel_relaxed(reg | TSENS_LOWER_STATUS_CLR |
 			TSENS_UPPER_STATUS_CLR, TSENS_CNTL_ADDR);
 	}
+
 	mask = ~(TSENS_LOWER_STATUS_CLR | TSENS_UPPER_STATUS_CLR);
 	threshold = readl_relaxed(TSENS_THRESHOLD_ADDR);
 	threshold_low = (threshold & TSENS_THRESHOLD_LOWER_LIMIT_MASK)
@@ -658,9 +661,7 @@
 				/* Notify user space */
 				schedule_work(&tm->sensor[i].work);
 				adc_code = readl_relaxed(sensor_addr);
-				pr_info("\nTrip point triggered by "
-					"current temperature (%d degrees) "
-					"measured by Temperature-Sensor %d\n",
+				pr_debug("Trigger (%d degrees) for sensor %d\n",
 					tsens_tz_code_to_degC(adc_code, i), i);
 			}
 		}
@@ -672,6 +673,12 @@
 	else
 	writel_relaxed(reg & mask, TSENS_CNTL_ADDR);
 	mb();
+}
+
+static irqreturn_t tsens_isr(int irq, void *data)
+{
+	schedule_work(&tmdev->tsens_work);
+
 	return IRQ_HANDLED;
 }
 
@@ -869,8 +876,7 @@
 			tmdev->sensor[TSENS_MAIN_SENSOR].calib_data =
 			tmdev->sensor[TSENS_MAIN_SENSOR].calib_data_backup;
 	if (!tmdev->sensor[TSENS_MAIN_SENSOR].calib_data) {
-		pr_err("%s: No temperature sensor data for calibration"
-				" in QFPROM!\n", __func__);
+		pr_err("QFPROM TSENS calibration data not present\n");
 		return -ENODEV;
 	}
 
@@ -901,8 +907,7 @@
 			tmdev->sensor[i].calib_data =
 				tmdev->sensor[i].calib_data_backup;
 		if (!tmdev->sensor[i].calib_data) {
-			WARN(1, "%s: No temperature sensor:%d data for"
-			" calibration in QFPROM!\n", __func__, i);
+			pr_err("QFPROM TSENS calibration data not present\n");
 			return -ENODEV;
 		}
 		tmdev->sensor[i].offset = (TSENS_CAL_DEGC *
@@ -1026,6 +1031,7 @@
 			thermal_zone_device_unregister(tmdev->sensor[i].tz_dev);
 		goto fail;
 	}
+	INIT_WORK(&tmdev->tsens_work, tsens_scheduler_fn);
 
 	pr_debug("%s: OK\n", __func__);
 	mb();
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 522e3a4..882aa7f 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -1378,6 +1378,7 @@
 	struct platform_device *dwc3;
 	struct dwc3_msm *msm;
 	struct resource *res;
+	void __iomem *tcsr;
 	int ret = 0;
 
 	msm = devm_kzalloc(&pdev->dev, sizeof(*msm), GFP_KERNEL);
@@ -1484,6 +1485,25 @@
 		goto free_hs_ldo_init;
 	}
 
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res) {
+		dev_dbg(&pdev->dev, "missing TCSR memory resource\n");
+	} else {
+		tcsr = devm_ioremap_nocache(&pdev->dev, res->start,
+			resource_size(res));
+		if (!tcsr) {
+			dev_dbg(&pdev->dev, "tcsr ioremap failed\n");
+		} else {
+			/* Enable USB3 on the primary USB port. */
+			writel_relaxed(0x1, tcsr);
+			/*
+			 * Ensure that TCSR write is completed before
+			 * USB registers initialization.
+			 */
+			mb();
+		}
+	}
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		dev_err(&pdev->dev, "missing memory base resource\n");
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index b396593..2126ff0 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -27,6 +27,7 @@
 #include <linux/err.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/wakelock.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 
@@ -58,13 +59,14 @@
 	struct clk		*phy_clk;
 	struct clk		*cal_clk;
 	struct regulator	*hsic_vddcx;
+	bool			async_int;
 	atomic_t                in_lpm;
+	struct wake_lock	wlock;
 	int			peripheral_status_irq;
 	int			wakeup_irq;
 	int			wakeup_gpio;
 	bool			wakeup_irq_enabled;
-	bool			irq_enabled;
-	bool			async_int;
+	atomic_t		pm_usage_cnt;
 	uint32_t		bus_perf_client;
 	uint32_t		wakeup_int_cnt;
 	enum usb_vdd_type	vdd_type;
@@ -624,15 +626,13 @@
 
 	disable_irq(hcd->irq);
 
-	/* make sure we don't race against the root hub being resumed */
-	if (HCD_RH_RUNNING(hcd) || HCD_WAKEUP_PENDING(hcd) ||
+	/* make sure we don't race against a remote wakeup */
+	if (test_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags) ||
 	    readl_relaxed(USB_PORTSC) & PORT_RESUME) {
-		dev_warn(mehci->dev, "%s: Root hub is not suspended\n",
-				__func__);
+		dev_dbg(mehci->dev, "wakeup pending, aborting suspend\n");
 		enable_irq(hcd->irq);
 		return -EBUSY;
 	}
-	mehci->irq_enabled = false;
 
 	/*
 	 * PHY may take some time or even fail to enter into low power
@@ -690,13 +690,14 @@
 	}
 
 	atomic_set(&mehci->in_lpm, 1);
-	mehci->irq_enabled = true;
 	enable_irq(hcd->irq);
 
 	mehci->wakeup_irq_enabled = 1;
 	enable_irq_wake(mehci->wakeup_irq);
 	enable_irq(mehci->wakeup_irq);
 
+	wake_unlock(&mehci->wlock);
+
 	dev_info(mehci->dev, "HSIC-USB in low power mode\n");
 
 	return 0;
@@ -720,6 +721,8 @@
 		mehci->wakeup_irq_enabled = 0;
 	}
 
+	wake_lock(&mehci->wlock);
+
 	if (mehci->bus_perf_client && debug_bus_voting_enabled) {
 		mehci->bus_vote = true;
 		queue_work(ehci_wq, &mehci->bus_vote_w);
@@ -775,14 +778,13 @@
 	if (mehci->async_int) {
 		mehci->async_int = false;
 		pm_runtime_put_noidle(mehci->dev);
-	}
-
-	if (!mehci->irq_enabled) {
 		enable_irq(hcd->irq);
-		mehci->irq_enabled = true;
 	}
 
-	pm_relax(mehci->dev);
+	if (atomic_read(&mehci->pm_usage_cnt)) {
+		atomic_set(&mehci->pm_usage_cnt, 0);
+		pm_runtime_put_noidle(mehci->dev);
+	}
 
 	dev_info(mehci->dev, "HSIC-USB exited from low power mode\n");
 
@@ -809,11 +811,9 @@
 
 	if (atomic_read(&mehci->in_lpm)) {
 		disable_irq_nosync(hcd->irq);
-		mehci->irq_enabled = false;
 		dev_dbg(mehci->dev, "phy async intr\n");
 		mehci->async_int = true;
 		pm_runtime_get(mehci->dev);
-		pm_stay_awake(mehci->dev);
 		return IRQ_HANDLED;
 	}
 
@@ -1030,9 +1030,7 @@
 	dev_dbg(mehci->dev, "%s: hsic remote wakeup interrupt cnt: %u\n",
 			__func__, mehci->wakeup_int_cnt);
 
-	mehci->async_int = true;
-	pm_runtime_get(mehci->dev);
-	pm_stay_awake(mehci->dev);
+	wake_lock(&mehci->wlock);
 
 	if (mehci->wakeup_irq_enabled) {
 		mehci->wakeup_irq_enabled = 0;
@@ -1040,6 +1038,11 @@
 		disable_irq_nosync(irq);
 	}
 
+	if (!atomic_read(&mehci->pm_usage_cnt)) {
+		atomic_set(&mehci->pm_usage_cnt, 1);
+		pm_runtime_get(mehci->dev);
+	}
+
 	return IRQ_HANDLED;
 }
 
@@ -1345,8 +1348,9 @@
 		goto unconfig_gpio;
 	}
 
-	mehci->irq_enabled = true;
 	device_init_wakeup(&pdev->dev, 1);
+	wake_lock_init(&mehci->wlock, WAKE_LOCK_SUSPEND, dev_name(&pdev->dev));
+	wake_lock(&mehci->wlock);
 
 	if (mehci->peripheral_status_irq) {
 		ret = request_threaded_irq(mehci->peripheral_status_irq,
@@ -1460,6 +1464,7 @@
 	msm_hsic_init_vddcx(mehci, 0);
 
 	msm_hsic_init_clocks(mehci, 0);
+	wake_lock_destroy(&mehci->wlock);
 	iounmap(hcd->regs);
 	usb_put_hcd(hcd);
 
diff --git a/drivers/usb/misc/ks_bridge.c b/drivers/usb/misc/ks_bridge.c
index 10cbe59..be8b58b 100644
--- a/drivers/usb/misc/ks_bridge.c
+++ b/drivers/usb/misc/ks_bridge.c
@@ -58,6 +58,7 @@
 	struct list_head	to_mdm_list;
 	struct list_head	to_ks_list;
 	wait_queue_head_t	ks_wait_q;
+	struct miscdevice	*fs_dev;
 
 	/* usb specific */
 	struct usb_device	*udev;
@@ -531,7 +532,6 @@
 	struct usb_endpoint_descriptor	*ep_desc;
 	int				i;
 	struct ks_bridge		*ksb;
-	struct miscdevice		*fs_dev;
 
 	ifc_num = ifc->cur_altsetting->desc.bInterfaceNumber;
 
@@ -585,8 +585,8 @@
 
 	dbg_log_event(ksb, "PID-ATT", id->idProduct, 0);
 
-	fs_dev = (struct miscdevice *)id->driver_info;
-	misc_register(fs_dev);
+	ksb->fs_dev = (struct miscdevice *)id->driver_info;
+	misc_register(ksb->fs_dev);
 
 	usb_enable_autosuspend(ksb->udev);
 
@@ -649,6 +649,7 @@
 	}
 	spin_unlock_irqrestore(&ksb->lock, flags);
 
+	misc_deregister(ksb->fs_dev);
 	usb_put_dev(ksb->udev);
 	ksb->ifc = NULL;
 	usb_set_intfdata(ifc, NULL);
@@ -713,7 +714,8 @@
 		ksb = kzalloc(sizeof(struct ks_bridge), GFP_KERNEL);
 		if (!ksb) {
 			pr_err("unable to allocat mem for ks_bridge");
-			return -ENOMEM;
+			ret =  -ENOMEM;
+			goto dev_free;
 		}
 		__ksb[i] = ksb;
 
diff --git a/include/linux/msm_rmnet.h b/include/linux/msm_rmnet.h
index 9f52464..063a8f1 100644
--- a/include/linux/msm_rmnet.h
+++ b/include/linux/msm_rmnet.h
@@ -40,6 +40,8 @@
 	RMNET_IOCTL_GET_OPMODE       = 0x000089F7, /* Get operation mode     */
 	RMNET_IOCTL_OPEN             = 0x000089F8, /* Open transport port    */
 	RMNET_IOCTL_CLOSE            = 0x000089F9, /* Close transport port   */
+	RMNET_IOCTL_FLOW_ENABLE	     = 0x000089FA, /* Flow enable	     */
+	RMNET_IOCTL_FLOW_DISABLE     = 0x000089FB, /* Flow disable	     */
 	RMNET_IOCTL_MAX
 };
 
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index bd97b86..f95230e 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -824,29 +824,39 @@
 /* extendedmode for the thumb nail image in VIDIOC_S_PARM */
 #define MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL \
 	(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+4)
-#define MSM_V4L2_EXT_CAPTURE_MODE_RAW \
+/* ISP_PIX_OUTPUT1: no pp, directly send output1 buf to user */
+#define MSM_V4L2_EXT_CAPTURE_MODE_ISP_PIX_OUTPUT1 \
 	(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+5)
-#define MSM_V4L2_EXT_CAPTURE_MODE_RDI \
+/* ISP_PIX_OUTPUT2: no pp, directly send output2 buf to user */
+#define MSM_V4L2_EXT_CAPTURE_MODE_ISP_PIX_OUTPUT2 \
 	(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+6)
-#define MSM_V4L2_EXT_CAPTURE_MODE_RDI1 \
+/* raw image type */
+#define MSM_V4L2_EXT_CAPTURE_MODE_RAW \
 	(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+7)
-#define MSM_V4L2_EXT_CAPTURE_MODE_RDI2 \
+/* RDI dump */
+#define MSM_V4L2_EXT_CAPTURE_MODE_RDI \
 	(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+8)
-#define MSM_V4L2_EXT_CAPTURE_MODE_AEC \
+/* RDI dump 1 */
+#define MSM_V4L2_EXT_CAPTURE_MODE_RDI1 \
 	(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+9)
-#define MSM_V4L2_EXT_CAPTURE_MODE_AWB \
+/* RDI dump 2 */
+#define MSM_V4L2_EXT_CAPTURE_MODE_RDI2 \
 	(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+10)
-#define MSM_V4L2_EXT_CAPTURE_MODE_AF \
+#define MSM_V4L2_EXT_CAPTURE_MODE_AEC \
 	(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+11)
-#define MSM_V4L2_EXT_CAPTURE_MODE_IHIST \
+#define MSM_V4L2_EXT_CAPTURE_MODE_AWB \
 	(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+12)
-#define MSM_V4L2_EXT_CAPTURE_MODE_CS \
+#define MSM_V4L2_EXT_CAPTURE_MODE_AF \
 	(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+13)
-#define MSM_V4L2_EXT_CAPTURE_MODE_RS \
+#define MSM_V4L2_EXT_CAPTURE_MODE_IHIST \
 	(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+14)
-#define MSM_V4L2_EXT_CAPTURE_MODE_CSTA \
+#define MSM_V4L2_EXT_CAPTURE_MODE_CS \
 	(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+15)
-#define MSM_V4L2_EXT_CAPTURE_MODE_MAX (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+16)
+#define MSM_V4L2_EXT_CAPTURE_MODE_RS \
+	(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+16)
+#define MSM_V4L2_EXT_CAPTURE_MODE_CSTA \
+	(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+17)
+#define MSM_V4L2_EXT_CAPTURE_MODE_MAX (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+18)
 
 #define MSM_V4L2_PID_MOTION_ISO              V4L2_CID_PRIVATE_BASE
 #define MSM_V4L2_PID_EFFECT                 (V4L2_CID_PRIVATE_BASE+1)
diff --git a/include/media/vcap_v4l2.h b/include/media/vcap_v4l2.h
index cf99435..d56e534 100644
--- a/include/media/vcap_v4l2.h
+++ b/include/media/vcap_v4l2.h
@@ -38,6 +38,12 @@
 		writel_relaxed(val, addr);	\
 	} while (0)
 
+#define VCAP_BASE (dev->vcapbase)
+#define VCAP_OFFSET(off) (VCAP_BASE + off)
+
+#define VCAP_SW_RESET_REQ (VCAP_BASE + 0x024)
+#define VCAP_SW_RESET_STATUS (VCAP_BASE + 0x028)
+
 struct vcap_client_data;
 
 enum rdy_buf {
@@ -167,6 +173,7 @@
 	bool					vp_resource;
 	bool					vp_dummy_event;
 	bool					vp_dummy_complete;
+	bool					vp_shutdown;
 	wait_queue_head_t		vp_dummy_waitq;
 
 	struct workqueue_struct	*vcap_wq;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 71dcb28..e8c0bf3 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1039,7 +1039,7 @@
 int mgmt_connected(u16 index, bdaddr_t *bdaddr, u8 le);
 int mgmt_le_conn_params(u16 index, bdaddr_t *bdaddr, u16 interval,
 						u16 latency, u16 timeout);
-int mgmt_disconnected(u16 index, bdaddr_t *bdaddr);
+int mgmt_disconnected(u16 index, bdaddr_t *bdaddr, u8 reason);
 int mgmt_disconnect_failed(u16 index);
 int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status);
 int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 4a69331..602fe59 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -311,6 +311,7 @@
 #define MGMT_EV_DISCONNECTED		0x000C
 struct mgmt_ev_disconnected {
 	bdaddr_t bdaddr;
+	__u8     reason;
 } __packed;
 
 #define MGMT_EV_CONNECT_FAILED		0x000D
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index fffdc60..95ec28b 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -103,7 +103,8 @@
 			      struct tcf_result *res);
 extern int tc_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 		       struct tcf_result *res);
-
+extern void tc_qdisc_flow_control(struct net_device *dev, u32 tcm_handle,
+				  int flow_enable);
 /* Calculate maximal size of packet seen by hard_start_xmit
    routine of this device.
  */
diff --git a/include/sound/apr_audio.h b/include/sound/apr_audio.h
index 382052b..90872c9 100644
--- a/include/sound/apr_audio.h
+++ b/include/sound/apr_audio.h
@@ -978,6 +978,16 @@
 	u32 sample_rate;
 };
 
+struct asm_amrwbplus_cfg {
+	u32  size_bytes;
+	u32  version;
+	u32  num_channels;
+	u32  amr_band_mode;
+	u32  amr_dtx_mode;
+	u32  amr_frame_fmt;
+	u32  amr_lsf_idx;
+};
+
 struct asm_flac_cfg {
 	u16 stream_info_present;
 	u16 min_blk_size;
@@ -1398,6 +1408,7 @@
 		struct asm_flac_cfg        flac_cfg;
 		struct asm_vorbis_cfg      vorbis_cfg;
 		struct asm_multi_channel_pcm_fmt_blk multi_ch_pcm_cfg;
+		struct asm_amrwbplus_cfg   amrwbplus_cfg;
 	} __attribute__((packed)) write_cfg;
 } __attribute__((packed));
 
diff --git a/include/sound/q6asm.h b/include/sound/q6asm.h
index 01f2fac..323a228 100644
--- a/include/sound/q6asm.h
+++ b/include/sound/q6asm.h
@@ -288,6 +288,9 @@
 int q6asm_media_format_block_aac(struct audio_client *ac,
 			struct asm_aac_cfg *cfg);
 
+int q6asm_media_format_block_amrwbplus(struct audio_client *ac,
+					struct asm_amrwbplus_cfg *cfg);
+
 int q6asm_media_format_block_multi_aac(struct audio_client *ac,
 			struct asm_aac_cfg *cfg);
 
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d3402b7..e5f43ec 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1794,7 +1794,7 @@
 	struct hci_ev_disconn_complete *ev = (void *) skb->data;
 	struct hci_conn *conn;
 
-	BT_DBG("%s status %d", hdev->name, ev->status);
+	BT_DBG("%s status %d reason %d", hdev->name, ev->status, ev->reason);
 
 	if (ev->status) {
 		hci_dev_lock(hdev);
@@ -1812,7 +1812,7 @@
 	conn->state = BT_CLOSED;
 
 	if (conn->type == ACL_LINK || conn->type == LE_LINK)
-		mgmt_disconnected(hdev->id, &conn->dst);
+		mgmt_disconnected(hdev->id, &conn->dst, ev->reason);
 
 	if (conn->type == LE_LINK)
 		del_timer(&conn->smp_timer);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 1702ce3..d7deaaf 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2875,21 +2875,22 @@
 	mgmt_pending_remove(cmd);
 }
 
-int mgmt_disconnected(u16 index, bdaddr_t *bdaddr)
+int mgmt_disconnected(u16 index, bdaddr_t *bdaddr, u8 reason)
 {
 	struct mgmt_ev_disconnected ev;
 	struct sock *sk = NULL;
 	int err;
 
-	mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk);
-
 	bacpy(&ev.bdaddr, bdaddr);
+	ev.reason = reason;
 
 	err = mgmt_event(MGMT_EV_DISCONNECTED, index, &ev, sizeof(ev), sk);
 
 	if (sk)
 		sock_put(sk);
 
+	mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk);
+
 	return err;
 }
 
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 3d8981f..60e2fa9 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1030,6 +1030,35 @@
 }
 
 /*
+ * enable/disable flow on qdisc.
+ */
+void
+tc_qdisc_flow_control(struct net_device *dev, u32 tcm_handle, int enable_flow)
+{
+	struct Qdisc *q;
+	struct __qdisc_change_req {
+		struct nlattr attr;
+		struct tc_prio_qopt data;
+	} req =	{
+		.attr = {sizeof(struct __qdisc_change_req), TCA_OPTIONS},
+		.data = {3, {1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, 1}
+		};
+
+	/* override flow bit */
+	req.data.enable_flow = enable_flow;
+
+	/* look up using tcm handle */
+	q = qdisc_lookup(dev, tcm_handle);
+
+	/* call registered change function */
+	if (q) {
+		if (q->ops->change(q, &(req.attr)) != 0)
+			pr_err("tc_qdisc_flow_control: qdisc change failed");
+	}
+}
+EXPORT_SYMBOL(tc_qdisc_flow_control);
+
+/*
  * Create/change qdisc.
  */
 
diff --git a/sound/soc/msm/mpq8064.c b/sound/soc/msm/mpq8064.c
index 3b880ed..be0395b 100644
--- a/sound/soc/msm/mpq8064.c
+++ b/sound/soc/msm/mpq8064.c
@@ -133,7 +133,7 @@
 static int msm_ext_top_spk_pamp;
 static int msm_slim_0_rx_ch = 1;
 static int msm_slim_0_tx_ch = 1;
-static int msm_hdmi_rx_ch = 2;
+static int msm_hdmi_rx_ch = 8;
 
 static struct clk *codec_clk;
 static int clk_users;
@@ -515,14 +515,15 @@
 static const char *spk_function[] = {"Off", "On"};
 static const char *slim0_rx_ch_text[] = {"One", "Two"};
 static const char *slim0_tx_ch_text[] = {"One", "Two", "Three", "Four"};
-static const char *hdmi_rx_ch_text[] = {"Two", "Three", "Four", "Five", "Six"};
+static const char * const hdmi_rx_ch_text[] = {"Two", "Three", "Four",
+					"Five", "Six", "Seven", "Eight"};
 
 
 static const struct soc_enum msm_enum[] = {
 	SOC_ENUM_SINGLE_EXT(2, spk_function),
 	SOC_ENUM_SINGLE_EXT(2, slim0_rx_ch_text),
 	SOC_ENUM_SINGLE_EXT(4, slim0_tx_ch_text),
-	SOC_ENUM_SINGLE_EXT(5, hdmi_rx_ch_text),
+	SOC_ENUM_SINGLE_EXT(7, hdmi_rx_ch_text),
 
 };
 
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index 42bc979..dd576c4 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -26,6 +26,7 @@
 #include <sound/initval.h>
 #include <sound/control.h>
 #include <sound/q6asm.h>
+#include <sound/pcm_params.h>
 #include <asm/dma.h>
 #include <linux/dma-mapping.h>
 #include <linux/android_pmem.h>
@@ -82,12 +83,12 @@
 	.rate_min =	     8000,
 	.rate_max =	     48000,
 	.channels_min =	 1,
-	.channels_max =	 2,
+	.channels_max =	 8,
 	.buffer_bytes_max =     1200 * 1024 * 2,
-	.period_bytes_min =	4800,
+	.period_bytes_min =	2400,
 	.period_bytes_max =     1200 * 1024,
 	.periods_min =	  2,
-	.periods_max =	  512,
+	.periods_max =	  1024,
 	.fifo_size =	    0,
 };
 
@@ -134,8 +135,6 @@
 			break;
 		} else
 			atomic_set(&prtd->pending_buffer, 0);
-		if (runtime->status->hw_ptr >= runtime->control->appl_ptr)
-			break;
 		buf = prtd->audio_client->port[IN].buf;
 		pr_debug("%s:writing %d bytes of buffer[%d] to dsp 2\n",
 				__func__, prtd->pcm_count, prtd->out_head);
@@ -292,6 +291,7 @@
 	struct asm_aac_cfg aac_cfg;
 	struct asm_wma_cfg wma_cfg;
 	struct asm_wmapro_cfg wma_pro_cfg;
+	struct asm_amrwbplus_cfg amrwb_cfg;
 	int ret;
 
 	pr_debug("compressed stream prepare\n");
@@ -389,6 +389,27 @@
 			return ret;
 		}
 		break;
+	case SND_AUDIOCODEC_AMRWB:
+		pr_debug("SND_AUDIOCODEC_AMRWB\n");
+		ret = q6asm_media_format_block(prtd->audio_client,
+					compr->codec);
+		if (ret < 0) {
+			pr_err("%s: CMD Format block failed\n", __func__);
+			return ret;
+		}
+		break;
+	case SND_AUDIOCODEC_AMRWBPLUS:
+		pr_debug("SND_AUDIOCODEC_AMRWBPLUS\n");
+		memset(&amrwb_cfg, 0x0, sizeof(struct asm_amrwbplus_cfg));
+		amrwb_cfg.size_bytes = sizeof(struct asm_amrwbplus_cfg);
+		pr_debug("calling q6asm_media_format_block_amrwbplus");
+		ret = q6asm_media_format_block_amrwbplus(prtd->audio_client,
+						&amrwb_cfg);
+		if (ret < 0) {
+			pr_err("%s: CMD Format block failed\n", __func__);
+			return ret;
+		}
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -506,7 +527,7 @@
 {
 	pr_debug("%s\n", __func__);
 	/* MP3 Block */
-	compr->info.compr_cap.num_codecs = 1;
+	compr->info.compr_cap.num_codecs = 10;
 	compr->info.compr_cap.min_fragment_size = runtime->hw.period_bytes_min;
 	compr->info.compr_cap.max_fragment_size = runtime->hw.period_bytes_max;
 	compr->info.compr_cap.min_fragments = runtime->hw.periods_min;
@@ -519,6 +540,8 @@
 	compr->info.compr_cap.codecs[5] = SND_AUDIOCODEC_DTS;
 	compr->info.compr_cap.codecs[6] = SND_AUDIOCODEC_DTS_LBR;
 	compr->info.compr_cap.codecs[7] = SND_AUDIOCODEC_DTS_PASS_THROUGH;
+	compr->info.compr_cap.codecs[8] = SND_AUDIOCODEC_AMRWB;
+	compr->info.compr_cap.codecs[9] = SND_AUDIOCODEC_AMRWBPLUS;
 	/* Add new codecs here */
 }
 
@@ -790,7 +813,17 @@
 		pr_err("%s: Set IO mode failed\n", __func__);
 		return -ENOMEM;
 	}
-
+	/* Modifying kernel hardware params based on userspace config */
+	if (params_periods(params) > 0 &&
+		(params_periods(params) != runtime->hw.periods_max)) {
+		runtime->hw.periods_max = params_periods(params);
+	}
+	if (params_period_bytes(params) > 0 &&
+		(params_period_bytes(params) != runtime->hw.period_bytes_min)) {
+		runtime->hw.period_bytes_min = params_period_bytes(params);
+	}
+	runtime->hw.buffer_bytes_max =
+			runtime->hw.period_bytes_min * runtime->hw.periods_max;
 	ret = q6asm_audio_client_buf_alloc_contiguous(dir,
 			prtd->audio_client,
 			runtime->hw.period_bytes_min,
@@ -906,10 +939,17 @@
 			pr_debug("SND_AUDIOCODEC_DTS\n");
 			compr->codec = FORMAT_DTS_LBR;
 			break;
-		default:
-			pr_debug("FORMAT_LINEAR_PCM\n");
-			compr->codec = FORMAT_LINEAR_PCM;
+		case SND_AUDIOCODEC_AMRWB:
+			pr_debug("msm_compr_ioctl SND_AUDIOCODEC_AMRWB\n");
+			compr->codec = FORMAT_AMRWB;
 			break;
+		case SND_AUDIOCODEC_AMRWBPLUS:
+			pr_debug("msm_compr_ioctl SND_AUDIOCODEC_AMRWBPLUS\n");
+			compr->codec = FORMAT_AMR_WB_PLUS;
+			break;
+		default:
+			pr_err("msm_compr_ioctl failed..unknown codec\n");
+			return -EFAULT;
 		}
 		return 0;
 	case SNDRV_PCM_IOCTL1_RESET:
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 011ff29..011912e 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -82,7 +82,7 @@
 					SNDRV_PCM_RATE_KNOT),
 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
 			.channels_min = 1,
-			.channels_max = 6,
+			.channels_max = 8,
 			.rate_min =     8000,
 			.rate_max =	48000,
 		},
@@ -173,7 +173,7 @@
 					SNDRV_PCM_RATE_KNOT),
 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
 			.channels_min = 1,
-			.channels_max = 6,
+			.channels_max = 8,
 			.rate_min =	8000,
 			.rate_max = 48000,
 		},
diff --git a/sound/soc/msm/msm-dai-q6-hdmi.c b/sound/soc/msm/msm-dai-q6-hdmi.c
index c082ed7..2b3dd5f 100644
--- a/sound/soc/msm/msm-dai-q6-hdmi.c
+++ b/sound/soc/msm/msm-dai-q6-hdmi.c
@@ -111,6 +111,13 @@
 		dai_data->port_config.hdmi_multi_ch.channel_allocation =
 				channel_allocation;
 		break;
+	case 8:
+		channel_allocation  = 0x1F;
+		hdmi_msm_audio_info_setup(1, MSM_HDMI_AUDIO_CHANNEL_8,
+				channel_allocation, level_shift, down_mix);
+		dai_data->port_config.hdmi_multi_ch.channel_allocation =
+				channel_allocation;
+		break;
 	default:
 		dev_err(dai->dev, "invalid Channels = %u\n",
 				dai_data->channels);
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index 89b709f..ee1ab79 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -465,6 +465,9 @@
 	dai_data->channels = params_channels(params);
 	switch (dai_data->channels) {
 	case 2:
+	case 4:
+	case 6:
+	case 8:
 		dai_data->port_config.mi2s.channel = MSM_AFE_STEREO;
 		break;
 	case 1:
diff --git a/sound/soc/msm/msm-multi-ch-pcm-q6.c b/sound/soc/msm/msm-multi-ch-pcm-q6.c
index a13d4da..10b8f7a 100644
--- a/sound/soc/msm/msm-multi-ch-pcm-q6.c
+++ b/sound/soc/msm/msm-multi-ch-pcm-q6.c
@@ -83,7 +83,7 @@
 	.rate_min =             8000,
 	.rate_max =             48000,
 	.channels_min =         1,
-	.channels_max =         6,
+	.channels_max =         8,
 	.buffer_bytes_max =     PLAYBACK_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE,
 	.period_bytes_min =     PLAYBACK_MIN_PERIOD_SIZE,
 	.period_bytes_max =     PLAYBACK_MAX_PERIOD_SIZE,
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 374357d..5f0a20e 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -1302,6 +1302,9 @@
 	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_BT_SCO_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT_BT_SCO_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new int_fm_rx_mixer_controls[] = {
@@ -1317,6 +1320,9 @@
 	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_INT_FM_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_INT_FM_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = {
@@ -1332,6 +1338,9 @@
 	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AFE_PCM_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_AFE_PCM_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = {
@@ -1347,6 +1356,9 @@
 	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_AUXPCM_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_AUXPCM_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = {
@@ -1407,6 +1419,18 @@
 	SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
 	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 
@@ -2322,6 +2346,7 @@
 	{"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
 	{"MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"MI2S_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
 	{"MI2S_RX", NULL, "MI2S_RX Audio Mixer"},
 
 	{"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"},
@@ -2336,24 +2361,30 @@
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
 	{"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX Audio Mixer"},
 
 	{"INTERNAL_FM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"INTERNAL_FM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"INTERNAL_FM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
 	{"INTERNAL_FM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"INTERNAL_FM_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
 	{"INT_FM_RX", NULL, "INTERNAL_FM_RX Audio Mixer"},
 
 	{"AFE_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"AFE_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"AFE_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
 	{"AFE_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"AFE_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
 	{"PCM_RX", NULL, "AFE_PCM_RX Audio Mixer"},
 
 	{"MultiMedia1 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+	{"MultiMedia5 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
 	{"MultiMedia1 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
+	{"MultiMedia5 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
 
 	{"MultiMedia1 Mixer", "AFE_PCM_TX", "PCM_TX"},
+	{"MultiMedia5 Mixer", "AFE_PCM_TX", "PCM_TX"},
 	{"MM_UL1", NULL, "MultiMedia1 Mixer"},
 	{"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
 	{"MM_UL2", NULL, "MultiMedia2 Mixer"},
@@ -2364,6 +2395,7 @@
 	{"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"AUX_PCM_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
 	{"AUX_PCM_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"AUX_PCM_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
 	{"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"},
 
 	{"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 76940ee..1aac158 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -1526,6 +1526,14 @@
 	case FORMAT_DTS_LBR:
 		open.format = DTS_LBR;
 		break;
+	case FORMAT_AMRWB:
+		open.format = AMRWB_FS;
+		pr_debug("q6asm_open_write FORMAT_AMRWB");
+		break;
+	case FORMAT_AMR_WB_PLUS:
+		open.format = AMR_WB_PLUS;
+		pr_debug("q6asm_open_write FORMAT_AMR_WB_PLUS");
+		break;
 	default:
 		pr_err("%s: Invalid format[%d]\n", __func__, format);
 		goto fail_cmd;
@@ -2372,7 +2380,56 @@
 	return -EINVAL;
 }
 
+int q6asm_media_format_block_amrwbplus(struct audio_client *ac,
+					struct asm_amrwbplus_cfg *cfg)
+{
+	struct asm_stream_media_format_update fmt;
+	int rc = 0;
+	pr_debug("q6asm_media_format_block_amrwbplus");
 
+	pr_debug("%s:session[%d]band-mode[%d]frame-fmt[%d]ch[%d]\n",
+		__func__,
+		ac->session,
+		cfg->amr_band_mode,
+		cfg->amr_frame_fmt,
+		cfg->num_channels);
+
+	q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
+
+	fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FORMAT_UPDATE;
+
+	fmt.format = AMR_WB_PLUS;
+	fmt.cfg_size = cfg->size_bytes;
+
+	fmt.write_cfg.amrwbplus_cfg.size_bytes    = cfg->size_bytes;
+	fmt.write_cfg.amrwbplus_cfg.version       = cfg->version;
+	fmt.write_cfg.amrwbplus_cfg.num_channels  = cfg->num_channels;
+	fmt.write_cfg.amrwbplus_cfg.amr_band_mode = cfg->amr_band_mode;
+	fmt.write_cfg.amrwbplus_cfg.amr_dtx_mode  = cfg->amr_dtx_mode;
+	fmt.write_cfg.amrwbplus_cfg.amr_frame_fmt = cfg->amr_frame_fmt;
+	fmt.write_cfg.amrwbplus_cfg.amr_lsf_idx   = cfg->amr_lsf_idx;
+
+	pr_debug("%s: num_channels=%x amr_band_mode=%d amr_frame_fmt=%d\n",
+			__func__,
+			cfg->num_channels,
+			cfg->amr_band_mode,
+			cfg->amr_frame_fmt);
+
+	rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
+	if (rc < 0) {
+		pr_err("%s:Comamnd media format update failed..\n", __func__);
+		goto fail_cmd;
+	}
+	rc = wait_event_timeout(ac->cmd_wait,
+				(atomic_read(&ac->cmd_state) == 0), 5*HZ);
+	if (!rc) {
+		pr_err("%s:timeout. waited for FORMAT_UPDATE\n", __func__);
+		goto fail_cmd;
+	}
+	return 0;
+fail_cmd:
+	return -EINVAL;
+}
 int q6asm_media_format_block_multi_aac(struct audio_client *ac,
 				struct asm_aac_cfg *cfg)
 {
@@ -2444,6 +2501,9 @@
 	case FORMAT_AMRWB:
 		fmt.format = AMRWB_FS;
 		break;
+	case FORMAT_AMR_WB_PLUS:
+		fmt.format = AMR_WB_PLUS;
+		break;
 	case FORMAT_AMRNB:
 		fmt.format = AMRNB_FS;
 		break;