Merge "arm/dt: apq8084: Add support for Primary SSUSB device"
diff --git a/arch/arm/boot/dts/dsi-panel-nt35590-720p-cmd.dtsi b/arch/arm/boot/dts/dsi-panel-nt35590-720p-cmd.dtsi
new file mode 100644
index 0000000..7942567
--- /dev/null
+++ b/arch/arm/boot/dts/dsi-panel-nt35590-720p-cmd.dtsi
@@ -0,0 +1,530 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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.
+ */
+
+/ {
+	qcom,mdss_dsi_nt35590_720p_cmd {
+		compatible = "qcom,mdss-dsi-panel";
+		label = "nt35590 720p command mode dsi panel";
+		status = "disable";
+		qcom,dsi-ctrl-phandle = <&mdss_dsi0>;
+		qcom,rst-gpio = <&msmgpio 25 0>;
+		qcom,te-gpio = <&msmgpio 24 0>;
+		qcom,mdss-pan-res = <720 1280>;
+		qcom,mdss-pan-bpp = <24>;
+		qcom,mdss-pan-dest = "display_1";
+		qcom,mdss-pan-porch-values = <164 8 140 1 1 6>;
+		qcom,mdss-pan-underflow-clr = <0xff>;
+		qcom,mdss-pan-bl-ctrl = "bl_ctrl_wled";
+		qcom,mdss-pan-bl-levels = <1 4095>;
+		qcom,mdss-pan-dsi-mode = <1>;
+		qcom,mdss-vsync-enable = <1>;
+		qcom,mdss-hw-vsync-mode = <1>;
+		qcom,mdss-pan-dsi-h-pulse-mode = <1>;
+		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 = <2>;
+		qcom,mdss-pan-dsi-dst-format = <8>;
+		qcom,mdss-pan-insert-dcs-cmd = <1>;
+		qcom,mdss-pan-wr-mem-continue = <0x3c>;
+		qcom,mdss-pan-wr-mem-start = <0x2c>;
+		qcom,mdss-pan-te-sel = <1>;
+		qcom,mdss-pan-dsi-vc = <0>;
+		qcom,mdss-pan-dsi-rgb-swap = <0>;
+		qcom,mdss-pan-dsi-data-lanes = <1 1 1 1>; /* 4 lanes */
+		qcom,mdss-pan-dsi-dlane-swap = <0>;
+		qcom,mdss-pan-dsi-t-clk = <0x2c 0x20>;
+		qcom,mdss-pan-dsi-stream = <0>;
+		qcom,mdss-pan-dsi-mdp-tr = <0x0>;
+		qcom,mdss-pan-dsi-dma-tr = <0x04>;
+		qcom,mdss-pan-dsi-frame-rate = <60>;
+		qcom,panel-phy-regulatorSettings = [07 09 03 00  /* Regualotor settings */
+						    20 00 01];
+		qcom,panel-phy-timingSettings = [7d 25 1d 00 37 33
+						    22 27 1e 03 04 00];
+		qcom,panel-phy-strengthCtrl = [ff 06];
+		qcom,panel-phy-bistCtrl = [00 00 b1 ff           /* BIST Ctrl settings */
+					   00 00];
+		qcom,panel-phy-laneConfig = [00 00 00 00 00 00 00 01 97 /* lane0 config */
+					     00 00 00 00 05 00 00 01 97 /* lane1 config */
+					     00 00 00 00 0a 00 00 01 97 /* lane2 config */
+					     00 00 00 00 0f 00 00 01 97 /* lane3 config */
+					     00 c0 00 00 00 00 00 01 bb]; /* Clk ln config */
+		qcom,panel-on-cmds = [29 01 00 00 00 02 FF EE
+					29 01 00 00 00 02 26 08
+					29 01 00 00 00 02 26 00
+					29 01 00 00 10 02 FF 00
+					29 01 00 00 00 02 BA 03
+					29 01 00 00 00 02 C2 08
+					29 01 00 00 00 02 FF 01
+					29 01 00 00 00 02 FB 01
+					29 01 00 00 00 02 00 4A
+					29 01 00 00 00 02 01 33
+					29 01 00 00 00 02 02 53
+					29 01 00 00 00 02 03 55
+					29 01 00 00 00 02 04 55
+					29 01 00 00 00 02 05 33
+					29 01 00 00 00 02 06 22
+					29 01 00 00 00 02 08 56
+					29 01 00 00 00 02 09 8F
+					29 01 00 00 00 02 36 73
+					29 01 00 00 00 02 0B 9F
+					29 01 00 00 00 02 0C 9F
+					29 01 00 00 00 02 0D 2F
+					29 01 00 00 00 02 0E 24
+					29 01 00 00 00 02 11 83
+					29 01 00 00 00 02 12 03
+					29 01 00 00 00 02 71 2C
+					29 01 00 00 00 02 6F 03
+					29 01 00 00 00 02 0F 0A
+					29 01 00 00 00 02 FF 05
+					29 01 00 00 00 02 FB 01
+					29 01 00 00 00 02 01 00
+					29 01 00 00 00 02 02 8B
+					29 01 00 00 00 02 03 82
+					29 01 00 00 00 02 04 82
+					29 01 00 00 00 02 05 30
+					29 01 00 00 00 02 06 33
+					29 01 00 00 00 02 07 01
+					29 01 00 00 00 02 08 00
+					29 01 00 00 00 02 09 46
+					29 01 00 00 00 02 0A 46
+					29 01 00 00 00 02 0D 0B
+					29 01 00 00 00 02 0E 1D
+					29 01 00 00 00 02 0F 08
+					29 01 00 00 00 02 10 53
+					29 01 00 00 00 02 11 00
+					29 01 00 00 00 02 12 00
+					29 01 00 00 00 02 14 01
+					29 01 00 00 00 02 15 00
+					29 01 00 00 00 02 16 05
+					29 01 00 00 00 02 17 00
+					29 01 00 00 00 02 19 7F
+					29 01 00 00 00 02 1A FF
+					29 01 00 00 00 02 1B 0F
+					29 01 00 00 00 02 1C 00
+					29 01 00 00 00 02 1D 00
+					29 01 00 00 00 02 1E 00
+					29 01 00 00 00 02 1F 07
+					29 01 00 00 00 02 20 00
+					29 01 00 00 00 02 21 06
+					29 01 00 00 00 02 22 55
+					29 01 00 00 00 02 23 4D
+					29 01 00 00 00 02 2D 02
+					29 01 00 00 00 02 28 01
+					29 01 00 00 00 02 2F 02
+					29 01 00 00 00 02 83 01
+					29 01 00 00 00 02 9E 58
+					29 01 00 00 00 02 9F 6A
+					29 01 00 00 00 02 A0 01
+					29 01 00 00 00 02 A2 10
+					29 01 00 00 00 02 BB 0A
+					29 01 00 00 00 02 BC 0A
+					29 01 00 00 00 02 32 08
+					29 01 00 00 00 02 33 B8
+					29 01 00 00 00 02 36 01
+					29 01 00 00 00 02 37 00
+					29 01 00 00 00 02 43 00
+					29 01 00 00 00 02 4B 21
+					29 01 00 00 00 02 4C 03
+					29 01 00 00 00 02 50 21
+					29 01 00 00 00 02 51 03
+					29 01 00 00 00 02 58 21
+					29 01 00 00 00 02 59 03
+					29 01 00 00 00 02 5D 21
+					29 01 00 00 00 02 5E 03
+					29 01 00 00 00 02 6C 00
+					29 01 00 00 00 02 6D 00
+					29 01 00 00 00 02 FB 01
+					29 01 00 00 00 02 FF 01
+					29 01 00 00 00 02 FB 01
+					29 01 00 00 00 02 75 00
+					29 01 00 00 00 02 76 7D
+					29 01 00 00 00 02 77 00
+					29 01 00 00 00 02 78 8A
+					29 01 00 00 00 02 79 00
+					29 01 00 00 00 02 7A 9C
+					29 01 00 00 00 02 7B 00
+					29 01 00 00 00 02 7C B1
+					29 01 00 00 00 02 7D 00
+					29 01 00 00 00 02 7E BF
+					29 01 00 00 00 02 7F 00
+					29 01 00 00 00 02 80 CF
+					29 01 00 00 00 02 81 00
+					29 01 00 00 00 02 82 DD
+					29 01 00 00 00 02 83 00
+					29 01 00 00 00 02 84 E8
+					29 01 00 00 00 02 85 00
+					29 01 00 00 00 02 86 F2
+					29 01 00 00 00 02 87 01
+					29 01 00 00 00 02 88 1F
+					29 01 00 00 00 02 89 01
+					29 01 00 00 00 02 8A 41
+					29 01 00 00 00 02 8B 01
+					29 01 00 00 00 02 8C 78
+					29 01 00 00 00 02 8D 01
+					29 01 00 00 00 02 8E A5
+					29 01 00 00 00 02 8F 01
+					29 01 00 00 00 02 90 EE
+					29 01 00 00 00 02 91 02
+					29 01 00 00 00 02 92 29
+					29 01 00 00 00 02 93 02
+					29 01 00 00 00 02 94 2A
+					29 01 00 00 00 02 95 02
+					29 01 00 00 00 02 96 5D
+					29 01 00 00 00 02 97 02
+					29 01 00 00 00 02 98 93
+					29 01 00 00 00 02 99 02
+					29 01 00 00 00 02 9A B8
+					29 01 00 00 00 02 9B 02
+					29 01 00 00 00 02 9C E7
+					29 01 00 00 00 02 9D 03
+					29 01 00 00 00 02 9E 07
+					29 01 00 00 00 02 9F 03
+					29 01 00 00 00 02 A0 37
+					29 01 00 00 00 02 A2 03
+					29 01 00 00 00 02 A3 46
+					29 01 00 00 00 02 A4 03
+					29 01 00 00 00 02 A5 56
+					29 01 00 00 00 02 A6 03
+					29 01 00 00 00 02 A7 66
+					29 01 00 00 00 02 A9 03
+					29 01 00 00 00 02 AA 7A
+					29 01 00 00 00 02 AB 03
+					29 01 00 00 00 02 AC 93
+					29 01 00 00 00 02 AD 03
+					29 01 00 00 00 02 AE A3
+					29 01 00 00 00 02 AF 03
+					29 01 00 00 00 02 B0 B4
+					29 01 00 00 00 02 B1 03
+					29 01 00 00 00 02 B2 CB
+					29 01 00 00 00 02 B3 00
+					29 01 00 00 00 02 B4 7D
+					29 01 00 00 00 02 B5 00
+					29 01 00 00 00 02 B6 8A
+					29 01 00 00 00 02 B7 00
+					29 01 00 00 00 02 B8 9C
+					29 01 00 00 00 02 B9 00
+					29 01 00 00 00 02 BA B1
+					29 01 00 00 00 02 BB 00
+					29 01 00 00 00 02 BC BF
+					29 01 00 00 00 02 BD 00
+					29 01 00 00 00 02 BE CF
+					29 01 00 00 00 02 BF 00
+					29 01 00 00 00 02 C0 DD
+					29 01 00 00 00 02 C1 00
+					29 01 00 00 00 02 C2 E8
+					29 01 00 00 00 02 C3 00
+					29 01 00 00 00 02 C4 F2
+					29 01 00 00 00 02 C5 01
+					29 01 00 00 00 02 C6 1F
+					29 01 00 00 00 02 C7 01
+					29 01 00 00 00 02 C8 41
+					29 01 00 00 00 02 C9 01
+					29 01 00 00 00 02 CA 78
+					29 01 00 00 00 02 CB 01
+					29 01 00 00 00 02 CC A5
+					29 01 00 00 00 02 CD 01
+					29 01 00 00 00 02 CE EE
+					29 01 00 00 00 02 CF 02
+					29 01 00 00 00 02 D0 29
+					29 01 00 00 00 02 D1 02
+					29 01 00 00 00 02 D2 2A
+					29 01 00 00 00 02 D3 02
+					29 01 00 00 00 02 D4 5D
+					29 01 00 00 00 02 D5 02
+					29 01 00 00 00 02 D6 93
+					29 01 00 00 00 02 D7 02
+					29 01 00 00 00 02 D8 B8
+					29 01 00 00 00 02 D9 02
+					29 01 00 00 00 02 DA E7
+					29 01 00 00 00 02 DB 03
+					29 01 00 00 00 02 DC 07
+					29 01 00 00 00 02 DD 03
+					29 01 00 00 00 02 DE 37
+					29 01 00 00 00 02 DF 03
+					29 01 00 00 00 02 E0 46
+					29 01 00 00 00 02 E1 03
+					29 01 00 00 00 02 E2 56
+					29 01 00 00 00 02 E3 03
+					29 01 00 00 00 02 E4 66
+					29 01 00 00 00 02 E5 03
+					29 01 00 00 00 02 E6 7A
+					29 01 00 00 00 02 E7 03
+					29 01 00 00 00 02 E8 93
+					29 01 00 00 00 02 E9 03
+					29 01 00 00 00 02 EA A3
+					29 01 00 00 00 02 EB 03
+					29 01 00 00 00 02 EC B4
+					29 01 00 00 00 02 ED 03
+					29 01 00 00 00 02 EE CB
+					29 01 00 00 00 02 EF 00
+					29 01 00 00 00 02 F0 ED
+					29 01 00 00 00 02 F1 00
+					29 01 00 00 00 02 F2 F3
+					29 01 00 00 00 02 F3 00
+					29 01 00 00 00 02 F4 FE
+					29 01 00 00 00 02 F5 01
+					29 01 00 00 00 02 F6 09
+					29 01 00 00 00 02 F7 01
+					29 01 00 00 00 02 F8 13
+					29 01 00 00 00 02 F9 01
+					29 01 00 00 00 02 FA 1D
+					29 01 00 00 00 02 FF 02
+					29 01 00 00 00 02 FB 01
+					29 01 00 00 00 02 00 01
+					29 01 00 00 00 02 01 26
+					29 01 00 00 00 02 02 01
+					29 01 00 00 00 02 03 2F
+					29 01 00 00 00 02 04 01
+					29 01 00 00 00 02 05 37
+					29 01 00 00 00 02 06 01
+					29 01 00 00 00 02 07 56
+					29 01 00 00 00 02 08 01
+					29 01 00 00 00 02 09 70
+					29 01 00 00 00 02 0A 01
+					29 01 00 00 00 02 0B 9D
+					29 01 00 00 00 02 0C 01
+					29 01 00 00 00 02 0D C2
+					29 01 00 00 00 02 0E 01
+					29 01 00 00 00 02 0F FF
+					29 01 00 00 00 02 10 02
+					29 01 00 00 00 02 11 31
+					29 01 00 00 00 02 12 02
+					29 01 00 00 00 02 13 32
+					29 01 00 00 00 02 14 02
+					29 01 00 00 00 02 15 60
+					29 01 00 00 00 02 16 02
+					29 01 00 00 00 02 17 94
+					29 01 00 00 00 02 18 02
+					29 01 00 00 00 02 19 B5
+					29 01 00 00 00 02 1A 02
+					29 01 00 00 00 02 1B E3
+					29 01 00 00 00 02 1C 03
+					29 01 00 00 00 02 1D 03
+					29 01 00 00 00 02 1E 03
+					29 01 00 00 00 02 1F 2D
+					29 01 00 00 00 02 20 03
+					29 01 00 00 00 02 21 3A
+					29 01 00 00 00 02 22 03
+					29 01 00 00 00 02 23 48
+					29 01 00 00 00 02 24 03
+					29 01 00 00 00 02 25 57
+					29 01 00 00 00 02 26 03
+					29 01 00 00 00 02 27 68
+					29 01 00 00 00 02 28 03
+					29 01 00 00 00 02 29 7B
+					29 01 00 00 00 02 2A 03
+					29 01 00 00 00 02 2B 90
+					29 01 00 00 00 02 2D 03
+					29 01 00 00 00 02 2F A0
+					29 01 00 00 00 02 30 03
+					29 01 00 00 00 02 31 CB
+					29 01 00 00 00 02 32 00
+					29 01 00 00 00 02 33 ED
+					29 01 00 00 00 02 34 00
+					29 01 00 00 00 02 35 F3
+					29 01 00 00 00 02 36 00
+					29 01 00 00 00 02 37 FE
+					29 01 00 00 00 02 38 01
+					29 01 00 00 00 02 39 09
+					29 01 00 00 00 02 3A 01
+					29 01 00 00 00 02 3B 13
+					29 01 00 00 00 02 3D 01
+					29 01 00 00 00 02 3F 1D
+					29 01 00 00 00 02 40 01
+					29 01 00 00 00 02 41 26
+					29 01 00 00 00 02 42 01
+					29 01 00 00 00 02 43 2F
+					29 01 00 00 00 02 44 01
+					29 01 00 00 00 02 45 37
+					29 01 00 00 00 02 46 01
+					29 01 00 00 00 02 47 56
+					29 01 00 00 00 02 48 01
+					29 01 00 00 00 02 49 70
+					29 01 00 00 00 02 4A 01
+					29 01 00 00 00 02 4B 9D
+					29 01 00 00 00 02 4C 01
+					29 01 00 00 00 02 4D C2
+					29 01 00 00 00 02 4E 01
+					29 01 00 00 00 02 4F FF
+					29 01 00 00 00 02 50 02
+					29 01 00 00 00 02 51 31
+					29 01 00 00 00 02 52 02
+					29 01 00 00 00 02 53 32
+					29 01 00 00 00 02 54 02
+					29 01 00 00 00 02 55 60
+					29 01 00 00 00 02 56 02
+					29 01 00 00 00 02 58 94
+					29 01 00 00 00 02 59 02
+					29 01 00 00 00 02 5A B5
+					29 01 00 00 00 02 5B 02
+					29 01 00 00 00 02 5C E3
+					29 01 00 00 00 02 5D 03
+					29 01 00 00 00 02 5E 03
+					29 01 00 00 00 02 5F 03
+					29 01 00 00 00 02 60 2D
+					29 01 00 00 00 02 61 03
+					29 01 00 00 00 02 62 3A
+					29 01 00 00 00 02 63 03
+					29 01 00 00 00 02 64 48
+					29 01 00 00 00 02 65 03
+					29 01 00 00 00 02 66 57
+					29 01 00 00 00 02 67 03
+					29 01 00 00 00 02 68 68
+					29 01 00 00 00 02 69 03
+					29 01 00 00 00 02 6A 7B
+					29 01 00 00 00 02 6B 03
+					29 01 00 00 00 02 6C 90
+					29 01 00 00 00 02 6D 03
+					29 01 00 00 00 02 6E A0
+					29 01 00 00 00 02 6F 03
+					29 01 00 00 00 02 70 CB
+					29 01 00 00 00 02 71 00
+					29 01 00 00 00 02 72 19
+					29 01 00 00 00 02 73 00
+					29 01 00 00 00 02 74 36
+					29 01 00 00 00 02 75 00
+					29 01 00 00 00 02 76 55
+					29 01 00 00 00 02 77 00
+					29 01 00 00 00 02 78 70
+					29 01 00 00 00 02 79 00
+					29 01 00 00 00 02 7A 83
+					29 01 00 00 00 02 7B 00
+					29 01 00 00 00 02 7C 99
+					29 01 00 00 00 02 7D 00
+					29 01 00 00 00 02 7E A8
+					29 01 00 00 00 02 7F 00
+					29 01 00 00 00 02 80 B7
+					29 01 00 00 00 02 81 00
+					29 01 00 00 00 02 82 C5
+					29 01 00 00 00 02 83 00
+					29 01 00 00 00 02 84 F7
+					29 01 00 00 00 02 85 01
+					29 01 00 00 00 02 86 1E
+					29 01 00 00 00 02 87 01
+					29 01 00 00 00 02 88 60
+					29 01 00 00 00 02 89 01
+					29 01 00 00 00 02 8A 95
+					29 01 00 00 00 02 8B 01
+					29 01 00 00 00 02 8C E1
+					29 01 00 00 00 02 8D 02
+					29 01 00 00 00 02 8E 20
+					29 01 00 00 00 02 8F 02
+					29 01 00 00 00 02 90 23
+					29 01 00 00 00 02 91 02
+					29 01 00 00 00 02 92 59
+					29 01 00 00 00 02 93 02
+					29 01 00 00 00 02 94 94
+					29 01 00 00 00 02 95 02
+					29 01 00 00 00 02 96 B4
+					29 01 00 00 00 02 97 02
+					29 01 00 00 00 02 98 E1
+					29 01 00 00 00 02 99 03
+					29 01 00 00 00 02 9A 01
+					29 01 00 00 00 02 9B 03
+					29 01 00 00 00 02 9C 28
+					29 01 00 00 00 02 9D 03
+					29 01 00 00 00 02 9E 30
+					29 01 00 00 00 02 9F 03
+					29 01 00 00 00 02 A0 37
+					29 01 00 00 00 02 A2 03
+					29 01 00 00 00 02 A3 3B
+					29 01 00 00 00 02 A4 03
+					29 01 00 00 00 02 A5 40
+					29 01 00 00 00 02 A6 03
+					29 01 00 00 00 02 A7 50
+					29 01 00 00 00 02 A9 03
+					29 01 00 00 00 02 AA 6D
+					29 01 00 00 00 02 AB 03
+					29 01 00 00 00 02 AC 80
+					29 01 00 00 00 02 AD 03
+					29 01 00 00 00 02 AE CB
+					29 01 00 00 00 02 AF 00
+					29 01 00 00 00 02 B0 19
+					29 01 00 00 00 02 B1 00
+					29 01 00 00 00 02 B2 36
+					29 01 00 00 00 02 B3 00
+					29 01 00 00 00 02 B4 55
+					29 01 00 00 00 02 B5 00
+					29 01 00 00 00 02 B6 70
+					29 01 00 00 00 02 B7 00
+					29 01 00 00 00 02 B8 83
+					29 01 00 00 00 02 B9 00
+					29 01 00 00 00 02 BA 99
+					29 01 00 00 00 02 BB 00
+					29 01 00 00 00 02 BC A8
+					29 01 00 00 00 02 BD 00
+					29 01 00 00 00 02 BE B7
+					29 01 00 00 00 02 BF 00
+					29 01 00 00 00 02 C0 C5
+					29 01 00 00 00 02 C1 00
+					29 01 00 00 00 02 C2 F7
+					29 01 00 00 00 02 C3 01
+					29 01 00 00 00 02 C4 1E
+					29 01 00 00 00 02 C5 01
+					29 01 00 00 00 02 C6 60
+					29 01 00 00 00 02 C7 01
+					29 01 00 00 00 02 C8 95
+					29 01 00 00 00 02 C9 01
+					29 01 00 00 00 02 CA E1
+					29 01 00 00 00 02 CB 02
+					29 01 00 00 00 02 CC 20
+					29 01 00 00 00 02 CD 02
+					29 01 00 00 00 02 CE 23
+					29 01 00 00 00 02 CF 02
+					29 01 00 00 00 02 D0 59
+					29 01 00 00 00 02 D1 02
+					29 01 00 00 00 02 D2 94
+					29 01 00 00 00 02 D3 02
+					29 01 00 00 00 02 D4 B4
+					29 01 00 00 00 02 D5 02
+					29 01 00 00 00 02 D6 E1
+					29 01 00 00 00 02 D7 03
+					29 01 00 00 00 02 D8 01
+					29 01 00 00 00 02 D9 03
+					29 01 00 00 00 02 DA 28
+					29 01 00 00 00 02 DB 03
+					29 01 00 00 00 02 DC 30
+					29 01 00 00 00 02 DD 03
+					29 01 00 00 00 02 DE 37
+					29 01 00 00 00 02 DF 03
+					29 01 00 00 00 02 E0 3B
+					29 01 00 00 00 02 E1 03
+					29 01 00 00 00 02 E2 40
+					29 01 00 00 00 02 E3 03
+					29 01 00 00 00 02 E4 50
+					29 01 00 00 00 02 E5 03
+					29 01 00 00 00 02 E6 6D
+					29 01 00 00 00 02 E7 03
+					29 01 00 00 00 02 E8 80
+					29 01 00 00 00 02 E9 03
+					29 01 00 00 00 02 EA CB
+					29 01 00 00 00 02 FF 01
+					29 01 00 00 00 02 FB 01
+					29 01 00 00 00 02 FF 02
+					29 01 00 00 00 02 FB 01
+					29 01 00 00 00 02 FF 04
+					29 01 00 00 00 02 FB 01
+					29 01 00 00 00 02 FF 00
+					29 01 00 00 64 02 11 00
+					29 01 00 00 00 02 FF EE
+					29 01 00 00 00 02 12 50
+					29 01 00 00 00 02 13 02
+					29 01 00 00 00 02 6A 60
+					29 01 00 00 00 02 FF 00
+					29 01 00 00 78 02 29 00];
+		qcom,on-cmds-dsi-state = "DSI_LP_MODE";
+		qcom,panel-off-cmds = [05 01 00 00 32 02 28 00
+					05 01 00 00 78 02 10 00];
+		qcom,off-cmds-dsi-state = "DSI_HS_MODE";
+	};
+};
diff --git a/arch/arm/boot/dts/msm8226-ion.dtsi b/arch/arm/boot/dts/msm8226-ion.dtsi
index f433a49..9ada271 100644
--- a/arch/arm/boot/dts/msm8226-ion.dtsi
+++ b/arch/arm/boot/dts/msm8226-ion.dtsi
@@ -38,9 +38,7 @@
 		qcom,ion-heap@27 { /* QSECOM HEAP */
 			compatible = "qcom,msm-ion-reserve";
 			reg = <27>;
-			qcom,heap-align = <0x1000>;
-			qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
-			qcom,memory-reservation-size = <0x780000>;
+			linux,contiguous-region = <&qsecom_mem>;
 		};
 
 		qcom,ion-heap@28 { /* AUDIO HEAP */
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index c392428..631d3a3 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -59,6 +59,13 @@
 			reg = <0 0x3800000>;
 			label = "secure_mem";
 		};
+
+		qsecom_mem: qsecom_region {
+			linux,contiguous-region;
+			reg = <0 0x780000>;
+			label = "qsecom_mem";
+		};
+
 	};
 
 	timer {
diff --git a/arch/arm/boot/dts/msm8610-ion.dtsi b/arch/arm/boot/dts/msm8610-ion.dtsi
index 41b58da..7d7d8fd 100644
--- a/arch/arm/boot/dts/msm8610-ion.dtsi
+++ b/arch/arm/boot/dts/msm8610-ion.dtsi
@@ -31,9 +31,7 @@
 		qcom,ion-heap@27 { /* QSECOM HEAP */
 			compatible = "qcom,msm-ion-reserve";
 			reg = <27>;
-			qcom,heap-align = <0x1000>;
-			qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
-			qcom,memory-reservation-size = <0x100000>;
+			linux,contiguous-region = <&qsecom_mem>;
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/msm8610-mdss.dtsi b/arch/arm/boot/dts/msm8610-mdss.dtsi
new file mode 100644
index 0000000..42fa149
--- /dev/null
+++ b/arch/arm/boot/dts/msm8610-mdss.dtsi
@@ -0,0 +1,37 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * 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.
+ */
+
+/ {
+	qcom,mdss_mdp@fd900000 {
+		compatible = "qcom,mdss_mdp3";
+		reg = <0xfd900000 0x100000>;
+		reg-names = "mdp_phys";
+		interrupts = <0 72 0>;
+
+		mdss_fb0: qcom,mdss_fb_primary {
+			cell-index = <0>;
+			compatible = "qcom,mdss-fb";
+			qcom,memory-reservation-type = "EBI1";
+			qcom,memory-reservation-size = <0x800000>;
+		};
+	};
+
+	mdss_dsi0: qcom,mdss_dsi@fdd00000 {
+		compatible = "qcom,msm-dsi-v2";
+		label = "MDSS DSI CTRL->0";
+		cell-index = <0>;
+		reg = <0xfdd00000 0x100000>;
+		interrupts = <0 30 0>;
+		vdda-supply = <&pm8110_l4>;
+		qcom,mdss-fb-map = <&mdss_fb0>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 822c792..84fe7d2 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -19,6 +19,7 @@
 /include/ "msm8610-pm.dtsi"
 /include/ "msm8610-smp2p.dtsi"
 /include/ "msm8610-bus.dtsi"
+/include/ "msm8610-mdss.dtsi"
 
 / {
 	model = "Qualcomm MSM 8610";
@@ -45,6 +46,16 @@
 		qcom,direct-connect-irqs = <8>;
 	};
 
+	memory {
+
+		qsecom_mem: qsecom_region {
+			linux,contiguous-region;
+			reg = <0 0x100000>;
+			label = "qsecom_mem";
+		};
+
+	};
+
 	aliases {
 		spi0 = &spi_0;
 		sdhc1 = &sdhc_1; /* SDC1 eMMC slot */
diff --git a/arch/arm/boot/dts/msm8974-ion.dtsi b/arch/arm/boot/dts/msm8974-ion.dtsi
index 31afd9c..cfe39fc 100644
--- a/arch/arm/boot/dts/msm8974-ion.dtsi
+++ b/arch/arm/boot/dts/msm8974-ion.dtsi
@@ -45,9 +45,7 @@
 		qcom,ion-heap@27 { /* QSECOM HEAP */
 			compatible = "qcom,msm-ion-reserve";
 			reg = <27>;
-			qcom,heap-align = <0x1000>;
-			qcom,memory-reservation-type = "EBI1"; /* reserve EBI memory */
-			qcom,memory-reservation-size = <0x1100000>;
+			linux,contiguous-region = <&qsecom_mem>;
 		};
 
 		qcom,ion-heap@28 { /* AUDIO HEAP */
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index f787cf5..d4f6bb7 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -47,6 +47,13 @@
 			reg = <0 0x2000000>;
 			label = "adsp_mem";
 		};
+
+		qsecom_mem: qsecom_region {
+			linux,contiguous-region;
+			reg = <0 0x1100000>;
+			label = "qseecom_mem";
+		};
+
 	};
 
 	intc: interrupt-controller@F9000000 {
diff --git a/arch/arm/configs/apq8084_defconfig b/arch/arm/configs/apq8084_defconfig
index 5ba76b6..a1fa53c 100644
--- a/arch/arm/configs/apq8084_defconfig
+++ b/arch/arm/configs/apq8084_defconfig
@@ -74,8 +74,6 @@
 CONFIG_MSM_L2_ERP_PORT_PANIC=y
 CONFIG_MSM_L2_ERP_1BIT_PANIC=y
 CONFIG_MSM_L2_ERP_2BIT_PANIC=y
-CONFIG_MSM_CACHE_DUMP=y
-CONFIG_MSM_CACHE_DUMP_ON_PANIC=y
 CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL=y
 CONFIG_ARM_LPAE=y
 CONFIG_NO_HZ=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index a70e6c6..3729448 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1113,14 +1113,14 @@
 config KERNEL_PMEM_SMI_REGION
 	bool "Enable in-kernel PMEM region for SMI"
 	default y if ARCH_MSM8X60
-	depends on ANDROID_PMEM && ((ARCH_QSD8X50 && !PMEM_GPU0) || (ARCH_MSM8X60 && !VCM))
+	depends on (ARCH_QSD8X50 && !PMEM_GPU0) || (ARCH_MSM8X60 && !VCM)
 	help
 	   Enable the in-kernel PMEM allocator to use SMI memory.
 
 config PMEM_GPU0
 	bool "Enable PMEM GPU0 region"
 	default y
-	depends on ARCH_QSD8X50 && ANDROID_PMEM
+	depends on ARCH_QSD8X50
 	help
 	  Enable the PMEM GPU0 device on SMI Memory.
 
@@ -1856,7 +1856,6 @@
 
 config MSM_HW3D
 	tristate "MSM Hardware 3D Register Driver"
-	depends on ANDROID_PMEM
 	help
 	  Provides access to registers needed by the userspace OpenGL|ES
 	  library.
@@ -1864,7 +1863,6 @@
 config MSM_ADSP
 	depends on (ARCH_MSM7X01A || ARCH_MSM7X25 || ARCH_MSM7X27)
 	tristate "MSM ADSP driver"
-	depends on ANDROID_PMEM
 	default y
 	help
 	  Provides access to registers needed by the userspace aDSP library.
@@ -1890,7 +1888,7 @@
 
 config MSM7KV2_AUDIO
 	bool "MSM7K v2 audio"
-	depends on (ARCH_MSM7X30 && ANDROID_PMEM)
+	depends on ARCH_MSM7X30
 	default y
 	help
 	  Enables QDSP5V2-based audio drivers for audio playbacks and
@@ -1906,14 +1904,14 @@
 
 config MSM_QDSP6
 	tristate "QDSP6 support"
-	depends on ARCH_QSD8X50 && ANDROID_PMEM
+	depends on ARCH_QSD8X50
 	default y
 	help
 	  Enable support for qdsp6. This provides audio and video functionality.
 
 config MSM8X60_AUDIO
 	tristate "MSM8X60 audio support"
-	depends on ARCH_MSM8X60 && ANDROID_PMEM
+	depends on ARCH_MSM8X60
 	default y
 	help
 	  Enable support for qdsp6v2. This provides audio functionality.
@@ -1972,7 +1970,7 @@
 
 config QSD_AUDIO
 	bool "QSD audio"
-	depends on ARCH_MSM_SCORPION && MSM_DALRPC && ANDROID_PMEM && !MSM_SMP
+	depends on ARCH_MSM_SCORPION && MSM_DALRPC && !MSM_SMP
 	default y
 	help
 	  Provides PCM, MP3, and AAC audio playback.
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index d5f880a..43b243d 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -7,7 +7,6 @@
 obj-y += clock.o clock-voter.o clock-dummy.o
 obj-y += modem_notifier.o
 obj-$(CONFIG_USE_OF) += board-dt.o
-obj-$(CONFIG_CPU_FREQ_MSM) += cpufreq.o
 obj-$(CONFIG_DEBUG_FS) += nohlt.o clock-debug.o
 obj-$(CONFIG_KEXEC) += msm_kexec.o
 
@@ -429,3 +428,4 @@
 
 obj-$(CONFIG_ARCH_MSM8974) += msm_mpmctr.o
 obj-$(CONFIG_MSM_CPR_REGULATOR) += cpr-regulator.o
+obj-$(CONFIG_CPU_FREQ_MSM) += cpufreq.o
diff --git a/arch/arm/mach-msm/board-8610-gpiomux.c b/arch/arm/mach-msm/board-8610-gpiomux.c
index eada62c..93645c7 100644
--- a/arch/arm/mach-msm/board-8610-gpiomux.c
+++ b/arch/arm/mach-msm/board-8610-gpiomux.c
@@ -208,6 +208,30 @@
 	},
 };
 
+static struct gpiomux_setting sd_card_det_active_config = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_NONE,
+	.dir = GPIOMUX_IN,
+};
+
+static struct gpiomux_setting sd_card_det_suspend_config = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+	.dir = GPIOMUX_IN,
+};
+
+static struct msm_gpiomux_config sd_card_det[] __initdata = {
+	{
+		.gpio = 42,
+		.settings = {
+			[GPIOMUX_ACTIVE]    = &sd_card_det_active_config,
+			[GPIOMUX_SUSPENDED] = &sd_card_det_suspend_config,
+		},
+	},
+};
+
 void __init msm8610_init_gpiomux(void)
 {
 	int rc;
@@ -224,4 +248,5 @@
 	msm_gpiomux_install(msm_lcd_configs, ARRAY_SIZE(msm_lcd_configs));
 	msm_gpiomux_install(msm_keypad_configs,
 				ARRAY_SIZE(msm_keypad_configs));
+	msm_gpiomux_install(sd_card_det, ARRAY_SIZE(sd_card_det));
 }
diff --git a/arch/arm/mach-msm/clock-8610.c b/arch/arm/mach-msm/clock-8610.c
index c13e595..478f77f 100644
--- a/arch/arm/mach-msm/clock-8610.c
+++ b/arch/arm/mach-msm/clock-8610.c
@@ -30,6 +30,7 @@
 #include "clock-rpm.h"
 #include "clock-voter.h"
 #include "clock.h"
+#include "clock-dsi-8610.h"
 
 enum {
 	GCC_BASE,
@@ -1561,21 +1562,85 @@
 static DEFINE_CLK_VOTER(mdp_axi_clk_src, &axi_clk_src.c, 200000000);
 static DEFINE_CLK_VOTER(mmssnoc_axi_clk_src, &axi_clk_src.c, 200000000);
 
-static struct clk_freq_tbl ftbl_dsi_pclk_clk[] = {
-	F_MDSS( 50000000, dsipll, 10, 0, 0),
-	F_MDSS(103330000, dsipll,  9, 0, 0),
-	F_END,
+static struct clk_ops dsi_byte_clk_src_ops;
+static struct clk_ops dsi_pixel_clk_src_ops;
+static struct clk_ops dsi_dsi_clk_src_ops;
+
+static struct dsi_pll_vco_clk dsi_vco  = {
+	.vco_clk_min =  600000000,
+	.vco_clk_max = 1200000000,
+	.pref_div_ratio = 26,
+	.c = {
+		.parent = &gcc_xo_clk_src.c,
+		.dbg_name = "dsi_vco",
+		.ops = &clk_ops_dsi_vco,
+		CLK_INIT(dsi_vco.c),
+	},
 };
 
+static struct clk dsi_pll_byte = {
+	.parent = &dsi_vco.c,
+	.dbg_name = "dsi_pll_byte",
+	.ops = &clk_ops_dsi_byteclk,
+	CLK_INIT(dsi_pll_byte),
+};
+
+static struct clk dsi_pll_pixel = {
+	.parent = &dsi_vco.c,
+	.dbg_name = "dsi_pll_pixel",
+	.ops = &clk_ops_dsi_dsiclk,
+	CLK_INIT(dsi_pll_pixel),
+};
+
+static struct clk_freq_tbl pixel_freq_tbl[] = {
+	{
+		.src_clk = &dsi_pll_pixel,
+		.div_src_val = BVAL(10, 8, dsipll_mm_source_val),
+	},
+	F_END
+};
+
+#define CFG_RCGR_DIV_MASK		BM(4, 0)
+
+static int set_rate_pixel_byte_clk(struct clk *clk, unsigned long rate)
+{
+	struct rcg_clk *rcg = to_rcg_clk(clk);
+	struct clk *pll = clk->parent;
+	unsigned long source_rate, div;
+	struct clk_freq_tbl *cur_freq = rcg->current_freq;
+	int rc;
+
+	if (rate == 0)
+		return clk_set_rate(pll, 0);
+
+	source_rate = clk_round_rate(pll, rate);
+	if (!source_rate || ((2 * source_rate) % rate))
+		return -EINVAL;
+
+	div = ((2 * source_rate)/rate) - 1;
+	if (div > CFG_RCGR_DIV_MASK)
+		return -EINVAL;
+
+	rc = clk_set_rate(pll, source_rate);
+	if (rc)
+		return rc;
+
+	cur_freq->div_src_val &= ~CFG_RCGR_DIV_MASK;
+	cur_freq->div_src_val |= BVAL(4, 0, div);
+	rcg->set_rate(rcg, cur_freq);
+
+	return 0;
+}
+
 static struct rcg_clk dsi_pclk_clk_src = {
 	.cmd_rcgr_reg =  DSI_PCLK_CMD_RCGR,
 	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_dsi_pclk_clk,
-	.current_freq = &rcg_dummy_freq,
+	.current_freq = pixel_freq_tbl,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
+		.parent = &dsi_pll_pixel,
 		.dbg_name = "dsi_pclk_clk_src",
-		.ops = &clk_ops_rcg_mnd,
+		.ops = &dsi_pixel_clk_src_ops,
 		VDD_DIG_FMAX_MAP2(LOW, 50000000, NOMINAL, 103330000),
 		CLK_INIT(dsi_pclk_clk_src.c),
 	},
@@ -1687,41 +1752,60 @@
 	},
 };
 
-static struct clk_freq_tbl ftbl_dsi_clk[] = {
-	F_MDSS(155000000,  dsipll, 6, 0, 0),
-	F_MDSS(310000000,  dsipll, 3, 0, 0),
-	F_END,
+/*
+ * The DSI clock will always use a divider of 1. However, we still
+ * need to set the right voltage and source.
+ */
+static int set_rate_dsi_clk(struct clk *clk, unsigned long rate)
+{
+	struct rcg_clk *rcg = to_rcg_clk(clk);
+	struct clk_freq_tbl *cur_freq = rcg->current_freq;
+
+	rcg->set_rate(rcg, cur_freq);
+
+	return 0;
+}
+
+static struct clk_freq_tbl dsi_freq_tbl[] = {
+	{
+		.src_clk = &dsi_pll_pixel,
+		.div_src_val =  BVAL(4, 0, 0) |
+			BVAL(10, 8, dsipll_mm_source_val),
+	},
+	F_END
 };
 
 static struct rcg_clk dsi_clk_src = {
 	.cmd_rcgr_reg =  DSI_CMD_RCGR,
 	.set_rate = set_rate_mnd,
-	.freq_tbl = ftbl_dsi_clk,
-	.current_freq = &rcg_dummy_freq,
+	.current_freq = dsi_freq_tbl,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
+		.parent = &dsi_pll_pixel,
 		.dbg_name = "dsi_clk_src",
-		.ops = &clk_ops_rcg_mnd,
+		.ops = &dsi_dsi_clk_src_ops,
 		VDD_DIG_FMAX_MAP2(LOW, 155000000, NOMINAL, 310000000),
 		CLK_INIT(dsi_clk_src.c),
 	},
 };
 
-static struct clk_freq_tbl ftbl_dsi_byte_clk[] = {
-	F_MDSS( 62500000, dsipll, 12, 0, 0),
-	F_MDSS(125000000, dsipll,  6, 0, 0),
-	F_END,
+static struct clk_freq_tbl byte_freq_tbl[] = {
+	{
+		.src_clk = &dsi_pll_byte,
+		.div_src_val = BVAL(10, 8, dsipll_mm_source_val),
+	},
+	F_END
 };
 
 static struct rcg_clk dsi_byte_clk_src = {
 	.cmd_rcgr_reg = DSI_BYTE_CMD_RCGR,
 	.set_rate = set_rate_hid,
-	.freq_tbl = ftbl_dsi_byte_clk,
-	.current_freq = &rcg_dummy_freq,
+	.current_freq = byte_freq_tbl,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
+		.parent = &dsi_pll_byte,
 		.dbg_name = "dsi_byte_clk_src",
-		.ops = &clk_ops_rcg,
+		.ops = &dsi_byte_clk_src_ops,
 		VDD_DIG_FMAX_MAP2(LOW, 62500000, NOMINAL, 125000000),
 		CLK_INIT(dsi_byte_clk_src.c),
 	},
@@ -2114,7 +2198,6 @@
 
 static struct branch_clk dsi_pclk_clk = {
 	.cbcr_reg = DSI_PCLK_CBCR,
-	.has_sibling = 1,
 	.base = &virt_bases[MMSS_BASE],
 	.c = {
 		.parent = &dsi_pclk_clk_src.c,
@@ -3075,6 +3158,26 @@
 	clk_set_rate(&mclk1_clk_src.c, mclk1_clk_src.freq_tbl[0].freq_hz);
 }
 
+static void dsi_init(void)
+{
+	dsi_byte_clk_src_ops = clk_ops_rcg;
+	dsi_byte_clk_src_ops.set_rate = set_rate_pixel_byte_clk;
+	dsi_byte_clk_src_ops.handoff = byte_rcg_handoff;
+	dsi_byte_clk_src_ops.get_parent = NULL;
+
+	dsi_dsi_clk_src_ops = clk_ops_rcg_mnd;
+	dsi_dsi_clk_src_ops.set_rate = set_rate_dsi_clk;
+	dsi_dsi_clk_src_ops.handoff = pixel_rcg_handoff;
+	dsi_dsi_clk_src_ops.get_parent = NULL;
+
+	dsi_pixel_clk_src_ops = clk_ops_rcg_mnd;
+	dsi_pixel_clk_src_ops.set_rate = set_rate_pixel_byte_clk;
+	dsi_pixel_clk_src_ops.handoff = pixel_rcg_handoff;
+	dsi_pixel_clk_src_ops.get_parent = NULL;
+
+	dsi_clk_ctrl_init(&dsi_ahb_clk.c);
+}
+
 #define GCC_CC_PHYS		0xFC400000
 #define GCC_CC_SIZE		SZ_16K
 
@@ -3134,6 +3237,8 @@
 
 	reg_init();
 
+	dsi_init();
+
 	/* Maintain the max nominal frequency on the MMSSNOC AHB bus. */
 	clk_set_rate(&mmssnoc_ahb_a_clk.c,  40000000);
 	clk_prepare_enable(&mmssnoc_ahb_a_clk.c);
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index f6c11b0..8915bad 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -667,7 +667,7 @@
 	return HANDOFF_ENABLED_CLK;
 }
 
-static enum handoff byte_rcg_handoff(struct clk *clk)
+enum handoff byte_rcg_handoff(struct clk *clk)
 {
 	struct rcg_clk *rcg = to_rcg_clk(clk);
 	u32 div_val;
@@ -718,7 +718,7 @@
 	return 0;
 }
 
-static enum handoff pixel_rcg_handoff(struct clk *clk)
+enum handoff pixel_rcg_handoff(struct clk *clk)
 {
 	struct rcg_clk *rcg = to_rcg_clk(clk);
 	u32 div_val, mval, nval, cfg_regval;
diff --git a/arch/arm/mach-msm/clock-local2.h b/arch/arm/mach-msm/clock-local2.h
index 7882edb..f33cf9c 100644
--- a/arch/arm/mach-msm/clock-local2.h
+++ b/arch/arm/mach-msm/clock-local2.h
@@ -210,6 +210,9 @@
 extern struct clk_ops clk_ops_byte;
 extern struct clk_ops clk_ops_pixel;
 
+enum handoff pixel_rcg_handoff(struct clk *clk);
+enum handoff byte_rcg_handoff(struct clk *clk);
+
 /*
  * Clock definition macros
  */
diff --git a/arch/arm/mach-msm/cpufreq.c b/arch/arm/mach-msm/cpufreq.c
index d02ab66..24a1e96 100644
--- a/arch/arm/mach-msm/cpufreq.c
+++ b/arch/arm/mach-msm/cpufreq.c
@@ -410,4 +410,4 @@
 	return cpufreq_register_driver(&msm_cpufreq_driver);
 }
 
-late_initcall(msm_cpufreq_register);
+device_initcall(msm_cpufreq_register);
diff --git a/arch/arm/mach-msm/include/mach/ipa.h b/arch/arm/mach-msm/include/mach/ipa.h
index 90757b6..b4fbaee 100644
--- a/arch/arm/mach-msm/include/mach/ipa.h
+++ b/arch/arm/mach-msm/include/mach/ipa.h
@@ -583,6 +583,8 @@
  */
 int ipa_rm_create_resource(struct ipa_rm_create_params *create_params);
 
+int ipa_rm_delete_resource(enum ipa_rm_resource_name resource_name);
+
 int ipa_rm_register(enum ipa_rm_resource_name resource_name,
 			struct ipa_rm_register_params *reg_params);
 
@@ -955,6 +957,12 @@
 	return -EPERM;
 }
 
+static inline int ipa_rm_delete_resource(
+		enum ipa_rm_resource_name resource_name)
+{
+	return -EPERM;
+}
+
 static inline int ipa_rm_register(enum ipa_rm_resource_name resource_name,
 			struct ipa_rm_register_params *reg_params)
 {
diff --git a/arch/arm/mach-msm/include/mach/subsystem_restart.h b/arch/arm/mach-msm/include/mach/subsystem_restart.h
index 67f643e..4d4703f 100644
--- a/arch/arm/mach-msm/include/mach/subsystem_restart.h
+++ b/arch/arm/mach-msm/include/mach/subsystem_restart.h
@@ -55,6 +55,7 @@
 	int (*powerup)(const struct subsys_desc *desc);
 	void (*crash_shutdown)(const struct subsys_desc *desc);
 	int (*ramdump)(int, const struct subsys_desc *desc);
+	unsigned int err_ready_irq;
 };
 
 #if defined(CONFIG_MSM_SUBSYSTEM_RESTART)
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8064.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8064.c
index b45efad..ff3dc21 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8064.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8064.c
@@ -437,10 +437,7 @@
 	},
 };
 
-static int mport_mdp[] = {
-	MSM_BUS_MASTER_PORT_MDP_PORT0,
-	MSM_BUS_MASTER_PORT_MDP_PORT1,
-};
+static int mport_mdp[] = {MSM_BUS_MASTER_PORT_MDP_PORT0,};
 static int mport_mdp1[] = {MSM_BUS_MASTER_PORT_MDP_PORT1,};
 static int mport_rotator[] = {MSM_BUS_MASTER_PORT_ROTATOR,};
 static int mport_graphics_3d_port0[] = {MSM_BUS_MASTER_PORT_GRAPHICS_3D_PORT0,};
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8930.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8930.c
index 91d106e..af51355 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8930.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8930.c
@@ -377,10 +377,7 @@
 	},
 };
 
-static int mport_mdp[] = {
-	MSM_BUS_MASTER_PORT_MDP_PORT0,
-	MSM_BUS_MASTER_PORT_MDP_PORT1,
-};
+static int mport_mdp[] = {MSM_BUS_MASTER_PORT_MDP_PORT0,};
 static int mport_mdp1[] = {MSM_BUS_MASTER_PORT_MDP_PORT1,};
 static int mport_rotator[] = {MSM_BUS_MASTER_PORT_ROTATOR,};
 static int mport_graphics_3d[] = {MSM_BUS_MASTER_PORT_GRAPHICS_3D,};
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
index 158dee3..295b91b 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
@@ -440,10 +440,7 @@
 	},
 };
 
-static int mport_mdp[] = {
-	MSM_BUS_MASTER_PORT_MDP_PORT0,
-	MSM_BUS_MASTER_PORT_MDP_PORT1,
-};
+static int mport_mdp[] = {MSM_BUS_MASTER_PORT_MDP_PORT0,};
 static int mport_mdp1[] = {MSM_BUS_MASTER_PORT_MDP_PORT1,};
 static int mport_rotator[] = {MSM_BUS_MASTER_PORT_ROTATOR,};
 static int mport_graphics_3d[] = {MSM_BUS_MASTER_PORT_GRAPHICS_3D,};
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index a39e38b..4fca346 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -1368,7 +1368,7 @@
 	if (!data)
 		return -EINVAL;
 
-	if (!bufu || count < 0)
+	if (!bufu)
 		return -EINVAL;
 
 	if (!access_ok(VERIFY_WRITE, bufu, count))
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index 5fe7a29..fb44e16 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -31,6 +31,7 @@
 #include <linux/idr.h>
 #include <linux/debugfs.h>
 #include <linux/miscdevice.h>
+#include <linux/interrupt.h>
 
 #include <asm/current.h>
 
@@ -132,6 +133,7 @@
  * @restart_order: order of other devices this devices restarts with
  * @dentry: debugfs directory for this device
  * @do_ramdump_on_put: ramdump on subsystem_put() if true
+ * @err_ready: completion variable to record error ready from subsystem
  */
 struct subsys_device {
 	struct subsys_desc *desc;
@@ -154,6 +156,7 @@
 	bool do_ramdump_on_put;
 	struct miscdevice misc_dev;
 	char miscdevice_name[32];
+	struct completion err_ready;
 };
 
 static struct subsys_device *to_subsys(struct device *d)
@@ -412,6 +415,21 @@
 	}
 }
 
+static int wait_for_err_ready(struct subsys_device *subsys)
+{
+	int ret;
+
+	if (!subsys->desc->err_ready_irq)
+		return 0;
+
+	ret = wait_for_completion_timeout(&subsys->err_ready,
+					  msecs_to_jiffies(10000));
+	if (!ret)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
 static void subsystem_shutdown(struct subsys_device *dev, void *data)
 {
 	const char *name = dev->desc->name;
@@ -436,10 +454,17 @@
 static void subsystem_powerup(struct subsys_device *dev, void *data)
 {
 	const char *name = dev->desc->name;
+	int ret;
 
 	pr_info("[%p]: Powering up %s\n", current, name);
+	init_completion(&dev->err_ready);
 	if (dev->desc->powerup(dev->desc) < 0)
-		panic("[%p]: Failed to powerup %s!", current, name);
+		panic("[%p]: Powerup error: %s!", current, name);
+
+	ret = wait_for_err_ready(dev);
+	if (ret)
+		panic("[%p]: Timed out waiting for error ready: %s!",
+			current, name);
 	subsys_set_state(dev, SUBSYS_ONLINE);
 }
 
@@ -465,8 +490,18 @@
 {
 	int ret;
 
+	init_completion(&subsys->err_ready);
 	ret = subsys->desc->start(subsys->desc);
-	if (!ret)
+	if (ret)
+		return ret;
+
+	ret = wait_for_err_ready(subsys);
+	if (ret)
+		/* pil-boot succeeded but we need to shutdown
+		 * the device because error ready timed out.
+		 */
+		subsys->desc->stop(subsys->desc);
+	else
 		subsys_set_state(subsys, SUBSYS_ONLINE);
 
 	return ret;
@@ -895,6 +930,14 @@
 	ida_simple_remove(&subsys_ida, subsys->id);
 	kfree(subsys);
 }
+static irqreturn_t subsys_err_ready_intr_handler(int irq, void *subsys)
+{
+	struct subsys_device *subsys_dev = subsys;
+	pr_info("Error ready interrupt occured for %s\n",
+		 subsys_dev->desc->name);
+	complete(&subsys_dev->err_ready);
+	return IRQ_HANDLED;
+}
 
 static int subsys_misc_device_add(struct subsys_device *subsys_dev)
 {
@@ -971,8 +1014,24 @@
 		goto err_register;
 	}
 
+	if (subsys->desc->err_ready_irq) {
+		ret = devm_request_irq(&subsys->dev,
+					subsys->desc->err_ready_irq,
+					subsys_err_ready_intr_handler,
+					IRQF_TRIGGER_RISING,
+					"error_ready_interrupt", subsys);
+		if (ret < 0) {
+			dev_err(&subsys->dev,
+				"[%s]: Unable to register err ready handler\n",
+				subsys->desc->name);
+			goto err_misc_device;
+		}
+	}
+
 	return subsys;
 
+err_misc_device:
+	subsys_misc_device_remove(subsys);
 err_register:
 	subsys_debugfs_remove(subsys);
 err_debugfs:
diff --git a/drivers/gpu/ion/Kconfig b/drivers/gpu/ion/Kconfig
index 39133b5..5bb254b 100644
--- a/drivers/gpu/ion/Kconfig
+++ b/drivers/gpu/ion/Kconfig
@@ -16,12 +16,3 @@
 	depends on ARCH_MSM && ION
 	help
 	  Choose this option if you wish to use ion on an MSM target.
-
-config ION_LEAK_CHECK
-	bool "Check for leaked Ion buffers (debugging)"
-	depends on ION
-	help
-	  Choose this option if you wish to enable checking for leaked
-	  ion buffers at runtime. Choosing this option will also add a
-	  debugfs node under the ion directory that can be used to
-	  enable/disable the leak checking.
diff --git a/drivers/gpu/ion/Makefile b/drivers/gpu/ion/Makefile
index d7ff73a..0e460c8 100644
--- a/drivers/gpu/ion/Makefile
+++ b/drivers/gpu/ion/Makefile
@@ -1,6 +1,5 @@
-obj-$(CONFIG_ION) +=	ion.o ion_heap.o ion_system_heap.o ion_carveout_heap.o \
-			ion_iommu_heap.o ion_cp_heap.o ion_removed_heap.o \
-			ion_page_pool.o ion_chunk_heap.o
+obj-$(CONFIG_ION) +=	ion.o ion_heap.o ion_page_pool.o ion_system_heap.o \
+			ion_carveout_heap.o ion_chunk_heap.o
 obj-$(CONFIG_CMA) += ion_cma_heap.o ion_cma_secure_heap.o
 obj-$(CONFIG_ION_TEGRA) += tegra/
-obj-$(CONFIG_ION_MSM) += msm/
+obj-$(CONFIG_ION_MSM) += ion_iommu_heap.o ion_cp_heap.o ion_removed_heap.o msm/
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index fbe4da0..250b387 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -16,7 +16,6 @@
  *
  */
 
-#include <linux/module.h>
 #include <linux/device.h>
 #include <linux/file.h>
 #include <linux/freezer.h>
@@ -27,6 +26,7 @@
 #include <linux/list.h>
 #include <linux/memblock.h>
 #include <linux/miscdevice.h>
+#include <linux/export.h>
 #include <linux/mm.h>
 #include <linux/mm_types.h>
 #include <linux/rbtree.h>
@@ -41,7 +41,6 @@
 #include <trace/events/kmem.h>
 
 
-#include <mach/iommu_domains.h>
 #include "ion_priv.h"
 
 /**
@@ -83,7 +82,6 @@
 	struct ion_device *dev;
 	struct rb_root handles;
 	struct mutex lock;
-	unsigned int heap_type_mask;
 	char *name;
 	struct task_struct *task;
 	pid_t pid;
@@ -108,7 +106,6 @@
 	struct ion_buffer *buffer;
 	struct rb_node node;
 	unsigned int kmap_cnt;
-	unsigned int iommu_map_cnt;
 };
 
 bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer)
@@ -545,8 +542,8 @@
 	mutex_lock(&client->lock);
 	valid_handle = ion_handle_validate(client, handle);
 	if (!valid_handle) {
-		mutex_unlock(&client->lock);
 		WARN(1, "%s: invalid handle passed to free.\n", __func__);
+		mutex_unlock(&client->lock);
 		return;
 	}
 	ion_handle_put(handle);
@@ -678,30 +675,21 @@
 	struct ion_client *client = s->private;
 	struct rb_node *n;
 
-	seq_printf(s, "%16.16s: %16.16s : %16.16s : %12.12s : %12.12s : %s\n",
+	seq_printf(s, "%16.16s: %16.16s : %16.16s : %12.12s\n",
 			"heap_name", "size_in_bytes", "handle refcount",
-			"buffer", "physical", "[domain,partition] - virt");
+			"buffer");
 
 	mutex_lock(&client->lock);
 	for (n = rb_first(&client->handles); n; n = rb_next(n)) {
 		struct ion_handle *handle = rb_entry(n, struct ion_handle,
 						     node);
 
-		enum ion_heap_type type = handle->buffer->heap->type;
-
 		seq_printf(s, "%16.16s: %16x : %16d : %12p",
 				handle->buffer->heap->name,
 				handle->buffer->size,
 				atomic_read(&handle->ref.refcount),
 				handle->buffer);
 
-		if (type == ION_HEAP_TYPE_SYSTEM_CONTIG ||
-			type == ION_HEAP_TYPE_CARVEOUT ||
-			type == (enum ion_heap_type) ION_HEAP_TYPE_CP)
-			seq_printf(s, " : %12pa", &handle->buffer->priv_phys);
-		else
-			seq_printf(s, " : %12s", "N/A");
-
 		seq_printf(s, "\n");
 	}
 	mutex_unlock(&client->lock);
@@ -1287,8 +1275,8 @@
 		ion_free(client, data.handle);
 		break;
 	}
-	case ION_IOC_MAP:
 	case ION_IOC_SHARE:
+	case ION_IOC_MAP:
 	{
 		struct ion_fd_data data;
 		if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
@@ -1391,7 +1379,7 @@
 };
 
 static size_t ion_debug_heap_total(struct ion_client *client,
-				   enum ion_heap_ids id)
+				   unsigned int id)
 {
 	size_t size = 0;
 	struct rb_node *n;
@@ -1560,7 +1548,6 @@
 	size_t total_size = 0;
 	size_t total_orphaned_size = 0;
 
-	mutex_lock(&dev->buffer_lock);
 	seq_printf(s, "%16.s %16.s %16.s\n", "client", "pid", "size");
 	seq_printf(s, "----------------------------------------------------\n");
 
@@ -1584,25 +1571,31 @@
 	seq_printf(s, "----------------------------------------------------\n");
 	seq_printf(s, "orphaned allocations (info is from last known client):"
 		   "\n");
+	mutex_lock(&dev->buffer_lock);
 	for (n = rb_first(&dev->buffers); n; n = rb_next(n)) {
 		struct ion_buffer *buffer = rb_entry(n, struct ion_buffer,
 						     node);
-		if (buffer->heap->type == heap->type)
-			total_size += buffer->size;
+		if (buffer->heap->id != heap->id)
+			continue;
+		total_size += buffer->size;
 		if (!buffer->handle_count) {
-			seq_printf(s, "%16.s %16u %16u\n", buffer->task_comm,
-				   buffer->pid, buffer->size);
+			seq_printf(s, "%16.s %16u %16u %d %d\n", buffer->task_comm,
+				   buffer->pid, buffer->size, buffer->kmap_cnt,
+				   atomic_read(&buffer->ref.refcount));
 			total_orphaned_size += buffer->size;
 		}
 	}
+	mutex_unlock(&dev->buffer_lock);
 	seq_printf(s, "----------------------------------------------------\n");
 	seq_printf(s, "%16.s %16u\n", "total orphaned",
 		   total_orphaned_size);
 	seq_printf(s, "%16.s %16u\n", "total ", total_size);
 	seq_printf(s, "----------------------------------------------------\n");
 
+	if (heap->debug_show)
+		heap->debug_show(heap, s, unused);
+
 	ion_heap_print_debug(s, heap);
-	mutex_unlock(&dev->buffer_lock);
 	return 0;
 }
 
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index 0dd3054..08921299 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -37,7 +37,6 @@
 	ion_phys_addr_t base;
 	unsigned long allocated_bytes;
 	unsigned long total_size;
-	unsigned int has_outer_cache;
 };
 
 ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap,
@@ -254,7 +253,6 @@
 	carveout_heap->heap.type = ION_HEAP_TYPE_CARVEOUT;
 	carveout_heap->allocated_bytes = 0;
 	carveout_heap->total_size = heap_data->size;
-	carveout_heap->has_outer_cache = heap_data->has_outer_cache;
 
 	return &carveout_heap->heap;
 }
diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/gpu/ion/ion_priv.h
index 4b724df..e3fbbda 100644
--- a/drivers/gpu/ion/ion_priv.h
+++ b/drivers/gpu/ion/ion_priv.h
@@ -247,14 +247,12 @@
 				      unsigned long align);
 void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr,
 		       unsigned long size);
-
 /**
  * The carveout heap returns physical addresses, since 0 may be a valid
  * physical address, this is used to indicate allocation failed
  */
 #define ION_CARVEOUT_ALLOCATE_FAIL -1
 
-
 /**
  * functions for creating and destroying a heap pool -- allows you
  * to keep a pool of pre allocated memory to use from your heap.  Keeping
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index a44011f..fb6dc2d 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -26,9 +26,6 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include "ion_priv.h"
-#include <mach/memory.h>
-#include <asm/cacheflush.h>
-#include <linux/msm_ion.h>
 #include <linux/dma-mapping.h>
 #include <trace/events/kmem.h>
 
@@ -265,7 +262,27 @@
 	.map_user = ion_heap_map_user,
 };
 
-struct ion_heap *ion_system_heap_create(struct ion_platform_heap *pheap)
+static int ion_system_heap_debug_show(struct ion_heap *heap, struct seq_file *s,
+				      void *unused)
+{
+
+	struct ion_system_heap *sys_heap = container_of(heap,
+							struct ion_system_heap,
+							heap);
+	int i;
+	for (i = 0; i < num_orders; i++) {
+		struct ion_page_pool *pool = sys_heap->pools[i];
+		seq_printf(s, "%d order %u highmem pages in pool = %lu total\n",
+			   pool->high_count, pool->order,
+			   (1 << pool->order) * PAGE_SIZE * pool->high_count);
+		seq_printf(s, "%d order %u lowmem pages in pool = %lu total\n",
+			   pool->low_count, pool->order,
+			   (1 << pool->order) * PAGE_SIZE * pool->low_count);
+	}
+	return 0;
+}
+
+struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused)
 {
 	struct ion_system_heap *heap;
 	int i;
@@ -291,6 +308,7 @@
 			goto err_create_pool;
 		heap->pools[i] = pool;
 	}
+	heap->heap.debug_show = ion_system_heap_debug_show;
 	return &heap->heap;
 err_create_pool:
 	for (i = 0; i < num_orders; i++)
@@ -378,7 +396,7 @@
 	.map_user = ion_heap_map_user,
 };
 
-struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *pheap)
+struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *unused)
 {
 	struct ion_heap *heap;
 
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index f43d276..4a45313 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -89,7 +89,7 @@
 	},
 	{
 		.id	= ION_QSECOM_HEAP_ID,
-		.type	= ION_HEAP_TYPE_CARVEOUT,
+		.type	= ION_HEAP_TYPE_DMA,
 		.name	= ION_QSECOM_HEAP_NAME,
 	},
 	{
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 08791a3..e6c345b 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -2323,7 +2323,7 @@
 	}
 
 	/* Check if we detected a long running IB, if false return */
-	if (adreno_dev->long_ib) {
+	if ((adreno_context) && (adreno_dev->long_ib)) {
 		long_ib = _adreno_check_long_ib(device);
 		if (!long_ib) {
 			adreno_context->flags &= ~CTXT_FLAGS_GPU_HANG;
diff --git a/drivers/hwmon/qpnp-adc-voltage.c b/drivers/hwmon/qpnp-adc-voltage.c
index 68cff09..d78d2ea 100644
--- a/drivers/hwmon/qpnp-adc-voltage.c
+++ b/drivers/hwmon/qpnp-adc-voltage.c
@@ -431,12 +431,32 @@
 	return 0;
 }
 
-static uint32_t qpnp_vadc_calib_device(void)
+static void qpnp_vadc_625mv_channel_sel(uint32_t *ref_channel_sel)
+{
+	struct qpnp_vadc_drv *vadc = qpnp_vadc;
+	uint32_t dt_index = 0;
+
+	/* Check if the buffered 625mV channel exists */
+	while ((vadc->adc->adc_channels[dt_index].channel_num
+		!= SPARE1) && (dt_index < vadc->max_channels_available))
+		dt_index++;
+
+	if (dt_index >= vadc->max_channels_available) {
+		pr_debug("Use default 625mV ref channel\n");
+		*ref_channel_sel = REF_625MV;
+	} else {
+		pr_debug("Use buffered 625mV ref channel\n");
+		*ref_channel_sel = SPARE1;
+	}
+}
+
+static int32_t qpnp_vadc_calib_device(void)
 {
 	struct qpnp_vadc_drv *vadc = qpnp_vadc;
 	struct qpnp_adc_amux_properties conv;
 	int rc, calib_read_1, calib_read_2, count = 0;
 	u8 status1 = 0;
+	uint32_t ref_channel_sel = 0;
 
 	conv.amux_channel = REF_125V;
 	conv.decimation = DECIMATION_TYPE2;
@@ -470,7 +490,8 @@
 		goto calib_fail;
 	}
 
-	conv.amux_channel = REF_625MV;
+	qpnp_vadc_625mv_channel_sel(&ref_channel_sel);
+	conv.amux_channel = ref_channel_sel;
 	conv.decimation = DECIMATION_TYPE2;
 	conv.mode_sel = ADC_OP_NORMAL_MODE << QPNP_VADC_OP_MODE_SHIFT;
 	conv.hw_settle_time = ADC_CHANNEL_HW_SETTLE_DELAY_0US;
@@ -647,6 +668,7 @@
 {
 	struct qpnp_vadc_drv *vadc = qpnp_vadc;
 	int rc = 0, scale_type, amux_prescaling, dt_index = 0;
+	uint32_t ref_channel;
 
 	if (!vadc || !vadc->vadc_initialized)
 		return -EPROBE_DEFER;
@@ -666,6 +688,11 @@
 			vadc->vadc_init_calib = true;
 	}
 
+	if (channel == REF_625MV) {
+		qpnp_vadc_625mv_channel_sel(&ref_channel);
+		channel = ref_channel;
+	}
+
 	vadc->adc->amux_prop->amux_channel = channel;
 
 	while ((vadc->adc->adc_channels[dt_index].channel_num
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
index 8ea1a00..59858b5 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -256,6 +256,13 @@
 				buf_info->state ==
 					MSM_ISP_BUFFER_STATE_INITIALIZED)
 			continue;
+
+		if (!BUF_SRC(bufq->stream_id)) {
+			if (buf_info->state == MSM_ISP_BUFFER_STATE_DEQUEUED ||
+			buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED)
+				buf_mgr->vb2_ops->put_buf(buf_info->vb2_buf,
+					bufq->session_id, bufq->stream_id);
+		}
 		msm_isp_unprepare_v4l2_buf(buf_mgr, buf_info);
 	}
 	return 0;
@@ -378,7 +385,6 @@
 	switch (buf_info->state) {
 	case MSM_ISP_BUFFER_STATE_PREPARED:
 	case MSM_ISP_BUFFER_STATE_DEQUEUED:
-	case MSM_ISP_BUFFER_STATE_DISPATCHED:
 	case MSM_ISP_BUFFER_STATE_DIVERTED:
 		if (BUF_SRC(bufq->stream_id))
 			list_add_tail(&buf_info->list, &bufq->head);
@@ -388,6 +394,13 @@
 		buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED;
 		rc = 0;
 		break;
+	case MSM_ISP_BUFFER_STATE_DISPATCHED:
+		buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED;
+		rc = 0;
+		break;
+	case MSM_ISP_BUFFER_STATE_QUEUED:
+		rc = 0;
+		break;
 	default:
 		pr_err("%s: incorrect state = %d",
 			__func__, buf_info->state);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
index a251f0a..679c5cb 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
@@ -142,14 +142,13 @@
 		return;
 
 	if (irq_status0 & BIT(0)) {
-		ISP_DBG("%s: PIX0 frame id: %lu\n", __func__,
-			vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id);
-		msm_isp_sof_notify(vfe_dev, VFE_PIX_0, ts);
 		ISP_DBG("%s: SOF IRQ\n", __func__);
 		if (vfe_dev->axi_data.src_info[VFE_PIX_0].raw_stream_count > 0
 			&& vfe_dev->axi_data.src_info[VFE_PIX_0].
 			pix_stream_count == 0) {
 			msm_isp_sof_notify(vfe_dev, VFE_PIX_0, ts);
+			if (vfe_dev->axi_data.stream_update)
+				msm_isp_axi_stream_update(vfe_dev);
 			msm_isp_update_framedrop_reg(vfe_dev);
 		}
 	}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index 5a17635..731056b 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -299,6 +299,8 @@
 			&& vfe_dev->axi_data.src_info[VFE_PIX_0].
 			pix_stream_count == 0) {
 			msm_isp_sof_notify(vfe_dev, VFE_PIX_0, ts);
+			if (vfe_dev->axi_data.stream_update)
+				msm_isp_axi_stream_update(vfe_dev);
 			msm_isp_update_framedrop_reg(vfe_dev);
 		}
 	}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index 728e172..f50812c 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -706,35 +706,60 @@
 	}
 }
 
-enum msm_isp_camif_update_state
-	msm_isp_update_camif_output_count(
-	struct vfe_device *vfe_dev,
+static enum msm_isp_camif_update_state
+	msm_isp_get_camif_update_state(struct vfe_device *vfe_dev,
 	struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd)
 {
 	int i;
 	struct msm_vfe_axi_stream *stream_info;
 	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
-	uint8_t cur_pix_count = axi_data->src_info[VFE_PIX_0].
-		pix_stream_count;
-	uint8_t cur_raw_count = axi_data->src_info[VFE_PIX_0].
-		raw_stream_count;
-	uint8_t pix_stream_cnt = 0;
+	uint8_t pix_stream_cnt = 0, cur_pix_stream_cnt;
+	cur_pix_stream_cnt =
+		axi_data->src_info[VFE_PIX_0].pix_stream_count +
+		axi_data->src_info[VFE_PIX_0].raw_stream_count;
 	for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
 		stream_info =
 			&axi_data->stream_info[
 			HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
 		if (stream_info->stream_src  < RDI_INTF_0)
 			pix_stream_cnt++;
+	}
+
+	if (pix_stream_cnt) {
+		if (cur_pix_stream_cnt == 0 && pix_stream_cnt &&
+			stream_cfg_cmd->cmd == START_STREAM)
+			return ENABLE_CAMIF;
+		else if (cur_pix_stream_cnt &&
+			(cur_pix_stream_cnt - pix_stream_cnt) == 0 &&
+			stream_cfg_cmd->cmd == STOP_STREAM)
+			return DISABLE_CAMIF;
+	}
+	return NO_UPDATE;
+}
+
+static void msm_isp_update_camif_output_count(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd)
+{
+	int i;
+	struct msm_vfe_axi_stream *stream_info;
+	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+	for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
+		stream_info =
+			&axi_data->stream_info[
+			HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
+		if (stream_info->stream_src >= RDI_INTF_0)
+			return;
 		if (stream_info->stream_src == PIX_ENCODER ||
-				stream_info->stream_src == PIX_VIEWFINDER) {
+			stream_info->stream_src == PIX_VIEWFINDER ||
+			stream_info->stream_src == IDEAL_RAW) {
 			if (stream_cfg_cmd->cmd == START_STREAM)
 				vfe_dev->axi_data.src_info[VFE_PIX_0].
 					pix_stream_count++;
 			else
 				vfe_dev->axi_data.src_info[VFE_PIX_0].
 					pix_stream_count--;
-		} else if (stream_info->stream_src == CAMIF_RAW ||
-				stream_info->stream_src == IDEAL_RAW) {
+		} else if (stream_info->stream_src == CAMIF_RAW) {
 			if (stream_cfg_cmd->cmd == START_STREAM)
 				vfe_dev->axi_data.src_info[VFE_PIX_0].
 					raw_stream_count++;
@@ -743,25 +768,6 @@
 					raw_stream_count--;
 		}
 	}
-	if (pix_stream_cnt) {
-		if ((cur_pix_count + cur_raw_count == 0) &&
-				(axi_data->src_info[VFE_PIX_0].
-				pix_stream_count +
-				axi_data->src_info[VFE_PIX_0].
-					raw_stream_count != 0)) {
-			return ENABLE_CAMIF;
-		}
-
-		if ((cur_pix_count + cur_raw_count != 0) &&
-				(axi_data->src_info[VFE_PIX_0].
-				pix_stream_count +
-				axi_data->src_info[VFE_PIX_0].
-					raw_stream_count == 0)) {
-			return DISABLE_CAMIF;
-		}
-	}
-
-	return NO_UPDATE;
 }
 
 void msm_camera_io_dump_2(void __iomem *addr, int size)
@@ -886,6 +892,20 @@
 	return rc;
 }
 
+static void msm_isp_deinit_stream_ping_pong_reg(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_axi_stream *stream_info)
+{
+	int i;
+	for (i = 0; i < 2; i++) {
+		struct msm_isp_buffer *buf;
+		buf = stream_info->buf[i];
+		if (buf)
+			vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr,
+				buf->bufq_handle, buf->buf_idx);
+	}
+}
+
 static void msm_isp_get_stream_wm_mask(
 	struct msm_vfe_axi_stream *stream_info,
 	uint32_t *wm_reload_mask)
@@ -937,6 +957,7 @@
 	vfe_dev->hw_info->vfe_ops.axi_ops.reload_wm(vfe_dev, wm_reload_mask);
 	vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev);
 
+	msm_isp_update_camif_output_count(vfe_dev, stream_cfg_cmd);
 	if (camif_update == ENABLE_CAMIF)
 		vfe_dev->hw_info->vfe_ops.core_ops.
 			update_camif_state(vfe_dev, camif_update);
@@ -969,6 +990,13 @@
 	if (camif_update == DISABLE_CAMIF)
 		vfe_dev->hw_info->vfe_ops.core_ops.
 			update_camif_state(vfe_dev, DISABLE_CAMIF);
+	msm_isp_update_camif_output_count(vfe_dev, stream_cfg_cmd);
+
+	for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
+		stream_info = &axi_data->stream_info[
+			HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
+		msm_isp_deinit_stream_ping_pong_reg(vfe_dev, stream_info);
+	}
 	return rc;
 }
 
@@ -990,8 +1018,7 @@
 		/*Configure UB*/
 		vfe_dev->hw_info->vfe_ops.axi_ops.cfg_ub(vfe_dev);
 	}
-	camif_update =
-		msm_isp_update_camif_output_count(vfe_dev, stream_cfg_cmd);
+	camif_update = msm_isp_get_camif_update_state(vfe_dev, stream_cfg_cmd);
 
 	if (stream_cfg_cmd->cmd == START_STREAM)
 		rc = msm_isp_start_axi_stream(
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
index e08dea2..77ed03e 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
@@ -277,6 +277,20 @@
 	return rc;
 }
 
+static void msm_isp_deinit_stats_ping_pong_reg(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_stats_stream *stream_info)
+{
+	int i;
+	struct msm_isp_buffer *buf;
+	for (i = 0; i < 2; i++) {
+		buf = stream_info->buf[i];
+		if (buf)
+			vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr,
+				buf->bufq_handle, buf->buf_idx);
+	}
+}
+
 void msm_isp_stats_stream_update(struct vfe_device *vfe_dev)
 {
 	int i;
@@ -415,6 +429,12 @@
 		vfe_dev->hw_info->vfe_ops.stats_ops.cfg_comp_mask(
 		   vfe_dev, comp_stats_mask, 0);
 	}
+
+	for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
+		idx = STATS_IDX(stream_cfg_cmd->stream_handle[i]);
+		stream_info = &stats_data->stream_info[idx];
+		msm_isp_deinit_stats_ping_pong_reg(vfe_dev, stream_info);
+	}
 	return rc;
 }
 
diff --git a/drivers/media/platform/msm/wfd/enc-mfc-subdev.c b/drivers/media/platform/msm/wfd/enc-mfc-subdev.c
index ceb0149..26e24da 100644
--- a/drivers/media/platform/msm/wfd/enc-mfc-subdev.c
+++ b/drivers/media/platform/msm/wfd/enc-mfc-subdev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -20,6 +20,7 @@
 #include <media/msm/vcd_property.h>
 #include <linux/time.h>
 #include <linux/ktime.h>
+#include <linux/slab.h>
 
 #define VID_ENC_MAX_ENCODER_CLIENTS 1
 #define MAX_NUM_CTRLS 20
diff --git a/drivers/media/platform/msm/wfd/enc-venus-subdev.c b/drivers/media/platform/msm/wfd/enc-venus-subdev.c
index 4f7fb44..722aa8f 100644
--- a/drivers/media/platform/msm/wfd/enc-venus-subdev.c
+++ b/drivers/media/platform/msm/wfd/enc-venus-subdev.c
@@ -18,6 +18,7 @@
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/wait.h>
+#include <linux/slab.h>
 #include <mach/iommu_domains.h>
 #include <media/msm_vidc.h>
 #include <media/v4l2-subdev.h>
diff --git a/drivers/media/platform/msm/wfd/mdp-4-subdev.c b/drivers/media/platform/msm/wfd/mdp-4-subdev.c
index 465ec21..2d79622 100644
--- a/drivers/media/platform/msm/wfd/mdp-4-subdev.c
+++ b/drivers/media/platform/msm/wfd/mdp-4-subdev.c
@@ -11,6 +11,7 @@
 *
 */
 #include <linux/msm_mdp.h>
+#include <linux/slab.h>
 #include <mach/iommu_domains.h>
 #include <media/videobuf2-core.h>
 #include "enc-subdev.h"
diff --git a/drivers/media/platform/msm/wfd/mdp-5-subdev.c b/drivers/media/platform/msm/wfd/mdp-5-subdev.c
index 3c546d0..6399117 100644
--- a/drivers/media/platform/msm/wfd/mdp-5-subdev.c
+++ b/drivers/media/platform/msm/wfd/mdp-5-subdev.c
@@ -11,6 +11,7 @@
 *
 */
 #include <linux/msm_mdp.h>
+#include <linux/slab.h>
 #include <mach/iommu_domains.h>
 #include <media/videobuf2-core.h>
 #include "enc-subdev.h"
diff --git a/drivers/media/platform/msm/wfd/mdp-dummy-subdev.c b/drivers/media/platform/msm/wfd/mdp-dummy-subdev.c
index 2242c76..10ba3c3 100644
--- a/drivers/media/platform/msm/wfd/mdp-dummy-subdev.c
+++ b/drivers/media/platform/msm/wfd/mdp-dummy-subdev.c
@@ -12,6 +12,7 @@
 */
 #include <linux/list.h>
 #include <linux/msm_mdp.h>
+#include <linux/slab.h>
 #include <media/videobuf2-core.h>
 
 #include "enc-subdev.h"
diff --git a/drivers/media/platform/msm/wfd/vsg-subdev.c b/drivers/media/platform/msm/wfd/vsg-subdev.c
index 90b1957..e0a46cc 100644
--- a/drivers/media/platform/msm/wfd/vsg-subdev.c
+++ b/drivers/media/platform/msm/wfd/vsg-subdev.c
@@ -13,6 +13,7 @@
 #include <linux/hrtimer.h>
 #include <linux/time.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <media/videobuf2-core.h>
 #include "enc-subdev.h"
 #include "vsg-subdev.h"
diff --git a/drivers/media/platform/msm/wfd/wfd-ioctl.c b/drivers/media/platform/msm/wfd/wfd-ioctl.c
index b1b1980..2bb8375 100644
--- a/drivers/media/platform/msm/wfd/wfd-ioctl.c
+++ b/drivers/media/platform/msm/wfd/wfd-ioctl.c
@@ -18,10 +18,10 @@
 #include <linux/init.h>
 #include <linux/version.h>
 #include <linux/platform_device.h>
-
 #include <linux/sched.h>
 #include <linux/kthread.h>
 #include <linux/time.h>
+#include <linux/slab.h>
 #include <mach/board.h>
 
 #include <media/v4l2-dev.h>
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 15e36a8..89730b0 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -2137,6 +2137,7 @@
 	int ret = 0, dead = 0;
 	u32 vdd_max_current;
 	u16 host_version;
+	u32 pwr;
 
 	pr_debug("%s: Enter %s\n", dev_name(&pdev->dev), __func__);
 	msm_host = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_msm_host),
@@ -2245,7 +2246,21 @@
 	}
 
 	/* Set SW_RST bit in POWER register (Offset 0x0) */
-	writel_relaxed(CORE_SW_RST, msm_host->core_mem + CORE_POWER);
+	writel_relaxed(readl_relaxed(msm_host->core_mem + CORE_POWER) |
+			CORE_SW_RST, msm_host->core_mem + CORE_POWER);
+	/*
+	 * SW reset can take upto 10HCLK + 15MCLK cycles.
+	 * Calculating based on min clk rates (hclk = 27MHz,
+	 * mclk = 400KHz) it comes to ~40us. Let's poll for
+	 * max. 1ms for reset completion.
+	 */
+	ret = readl_poll_timeout(msm_host->core_mem + CORE_POWER,
+			pwr, !(pwr & CORE_SW_RST), 100, 10);
+
+	if (ret) {
+		dev_err(&pdev->dev, "reset failed (%d)\n", ret);
+		goto vreg_deinit;
+	}
 	/* Set HC_MODE_EN bit in HC_MODE register */
 	writel_relaxed(HC_MODE_EN, (msm_host->core_mem + CORE_HC_MODE));
 
diff --git a/drivers/platform/msm/ipa/a2_service.c b/drivers/platform/msm/ipa/a2_service.c
index 1b33dc0..bbf9719 100644
--- a/drivers/platform/msm/ipa/a2_service.c
+++ b/drivers/platform/msm/ipa/a2_service.c
@@ -491,10 +491,6 @@
 				__func__);
 		return -EFAULT;
 	}
-	ret = sps_device_reset(a2_mux_ctx->a2_device_handle);
-	if (ret)
-		IPAERR("%s: device reset failed ret = %d\n",
-		       __func__, ret);
 	memset(&connect_params, 0, sizeof(struct ipa_sys_connect_params));
 	connect_params.client = IPA_CLIENT_A2_TETHERED_CONS;
 	connect_params.notify = ipa_tethered_notify;
@@ -606,12 +602,6 @@
 				__func__, ret);
 		return ret;
 	}
-	ret = sps_device_reset(a2_mux_ctx->a2_device_handle);
-	if (ret) {
-		IPAERR("%s: device reset failed ret = %d\n",
-			__func__, ret);
-		return ret;
-	}
 	verify_tx_queue_is_empty(__func__);
 	(void) ipa_rm_release_resource(IPA_RM_RESOURCE_A2_PROD);
 	if (a2_mux_ctx->disconnect_ack)
diff --git a/drivers/platform/msm/ipa/ipa_rm.c b/drivers/platform/msm/ipa/ipa_rm.c
index 1fdd300..88a49c4 100644
--- a/drivers/platform/msm/ipa/ipa_rm.c
+++ b/drivers/platform/msm/ipa/ipa_rm.c
@@ -21,6 +21,7 @@
 struct ipa_rm_context_type {
 	struct ipa_rm_dep_graph *dep_graph;
 	struct workqueue_struct *ipa_rm_wq;
+	rwlock_t lock;
 };
 static struct ipa_rm_context_type *ipa_rm_ctx;
 
@@ -41,10 +42,9 @@
 	struct ipa_rm_resource *resource;
 	int result;
 
-	if (!create_params) {
-		result = -EINVAL;
-		goto bail;
-	}
+	if (!create_params)
+		return -EINVAL;
+	write_lock(&ipa_rm_ctx->lock);
 	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
 					  create_params->name,
 					  &resource) == 0) {
@@ -59,11 +59,51 @@
 	if (result)
 		ipa_rm_resource_delete(resource);
 bail:
+	write_unlock(&ipa_rm_ctx->lock);
 	return result;
 }
 EXPORT_SYMBOL(ipa_rm_create_resource);
 
 /**
+ * ipa_rm_delete_resource() - delete resource
+ * @resource_name: name of resource to be deleted
+ *
+ * Returns: 0 on success, negative on failure
+ *
+ * This function is called by IPA RM client to delete client's resources.
+ *
+ */
+int ipa_rm_delete_resource(enum ipa_rm_resource_name resource_name)
+{
+	struct ipa_rm_resource *resource;
+	int result;
+
+	IPADBG("IPA RM ::ipa_rm_delete_resource num[%d] ENTER\n",
+			resource_name);
+	write_lock(&ipa_rm_ctx->lock);
+	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
+					resource_name,
+						&resource) != 0) {
+		IPADBG("ipa_rm_delete_resource param are bad********\n");
+		result = -EINVAL;
+		goto bail;
+	}
+	result = ipa_rm_resource_delete(resource);
+	if (result) {
+		IPADBG("error in ipa_rm_resource_delete\n");
+		goto bail;
+	}
+	result = ipa_rm_dep_graph_remove(ipa_rm_ctx->dep_graph,
+								resource_name);
+	IPADBG("IPA RM ::ipa_rm_delete_resource [%d] SUCCESS\n",
+								resource_name);
+bail:
+	write_unlock(&ipa_rm_ctx->lock);
+	return result;
+}
+EXPORT_SYMBOL(ipa_rm_delete_resource);
+
+/**
  * ipa_rm_add_dependency() - create dependency
  *					between 2 resources
  * @resource_name: name of dependent resource
@@ -77,13 +117,19 @@
 int ipa_rm_add_dependency(enum ipa_rm_resource_name resource_name,
 			enum ipa_rm_resource_name depends_on_name)
 {
-	return ipa_rm_dep_graph_add_dependency(
-			ipa_rm_ctx->dep_graph,
-			resource_name,
-			depends_on_name);
+	int result;
+
+	read_lock(&ipa_rm_ctx->lock);
+	result = ipa_rm_dep_graph_add_dependency(
+						ipa_rm_ctx->dep_graph,
+						resource_name,
+						depends_on_name);
+	read_unlock(&ipa_rm_ctx->lock);
+	return result;
 }
 EXPORT_SYMBOL(ipa_rm_add_dependency);
 
+
 /**
  * ipa_rm_delete_dependency() - create dependency
  *					between 2 resources
@@ -98,10 +144,14 @@
 int ipa_rm_delete_dependency(enum ipa_rm_resource_name resource_name,
 			enum ipa_rm_resource_name depends_on_name)
 {
-	return ipa_rm_dep_graph_delete_dependency(
-			ipa_rm_ctx->dep_graph,
-			resource_name,
-			depends_on_name);
+	int result;
+	read_lock(&ipa_rm_ctx->lock);
+	result = ipa_rm_dep_graph_delete_dependency(
+			  ipa_rm_ctx->dep_graph,
+			  resource_name,
+			  depends_on_name);
+	read_unlock(&ipa_rm_ctx->lock);
+	return result;
 }
 EXPORT_SYMBOL(ipa_rm_delete_dependency);
 
@@ -120,10 +170,9 @@
 	int result;
 	IPADBG("IPA RM ::ipa_rm_request_resource ENTER\n");
 
-	if (!IPA_RM_RESORCE_IS_PROD(resource_name)) {
-			result = -EINVAL;
-			goto bail;
-	}
+	if (!IPA_RM_RESORCE_IS_PROD(resource_name))
+			return -EINVAL;
+	read_lock(&ipa_rm_ctx->lock);
 	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
 			resource_name,
 			&resource) != 0) {
@@ -136,6 +185,7 @@
 bail:
 	IPADBG("IPA RM ::ipa_rm_request_resource EXIT [%d]\n", result);
 
+	read_unlock(&ipa_rm_ctx->lock);
 	return result;
 }
 EXPORT_SYMBOL(ipa_rm_request_resource);
@@ -155,10 +205,9 @@
 	int result;
 	IPADBG("IPA RM ::ipa_rm_release_resource ENTER\n");
 
-	if (!IPA_RM_RESORCE_IS_PROD(resource_name)) {
-		result = -EINVAL;
-		goto bail;
-	}
+	if (!IPA_RM_RESORCE_IS_PROD(resource_name))
+		return -EINVAL;
+	read_lock(&ipa_rm_ctx->lock);
 	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
 					  resource_name,
 					  &resource) != 0) {
@@ -170,6 +219,7 @@
 
 bail:
 	IPADBG("IPA RM ::ipa_rm_release_resource EXIT [%d]\n", result);
+	read_unlock(&ipa_rm_ctx->lock);
 	return result;
 }
 EXPORT_SYMBOL(ipa_rm_release_resource);
@@ -189,10 +239,10 @@
 {
 	int result;
 	struct ipa_rm_resource *resource;
-	if (!IPA_RM_RESORCE_IS_PROD(resource_name)) {
-		result = -EINVAL;
-		goto bail;
-	}
+
+	if (!IPA_RM_RESORCE_IS_PROD(resource_name))
+		return -EINVAL;
+	read_lock(&ipa_rm_ctx->lock);
 	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
 				resource_name,
 				&resource) != 0) {
@@ -203,6 +253,7 @@
 			(struct ipa_rm_resource_prod *)resource,
 			reg_params);
 bail:
+	read_unlock(&ipa_rm_ctx->lock);
 	return result;
 }
 EXPORT_SYMBOL(ipa_rm_register);
@@ -222,10 +273,10 @@
 {
 	int result;
 	struct ipa_rm_resource *resource;
-	if (!IPA_RM_RESORCE_IS_PROD(resource_name)) {
-		result = -EINVAL;
-		goto bail;
-	}
+
+	if (!IPA_RM_RESORCE_IS_PROD(resource_name))
+		return -EINVAL;
+	read_lock(&ipa_rm_ctx->lock);
 	if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
 			resource_name,
 			&resource) != 0) {
@@ -236,6 +287,7 @@
 			(struct ipa_rm_resource_prod *)resource,
 			reg_params);
 bail:
+	read_unlock(&ipa_rm_ctx->lock);
 	return result;
 }
 EXPORT_SYMBOL(ipa_rm_deregister);
@@ -278,25 +330,32 @@
 	case IPA_RM_WQ_NOTIFY_PROD:
 		if (!IPA_RM_RESORCE_IS_PROD(ipa_rm_work->resource_name))
 			return;
+		read_lock(&ipa_rm_ctx->lock);
 		if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
 						ipa_rm_work->resource_name,
-						&resource) != 0)
+						&resource) != 0){
+			read_unlock(&ipa_rm_ctx->lock);
 			return;
+		}
 		ipa_rm_resource_producer_notify_clients(
 				(struct ipa_rm_resource_prod *)resource,
 				ipa_rm_work->event);
-
+		read_unlock(&ipa_rm_ctx->lock);
 		break;
 	case IPA_RM_WQ_NOTIFY_CONS:
 		break;
 	case IPA_RM_WQ_RESOURCE_CB:
+		read_lock(&ipa_rm_ctx->lock);
 		if (ipa_rm_dep_graph_get_resource(ipa_rm_ctx->dep_graph,
 						ipa_rm_work->resource_name,
-						&resource) != 0)
+						&resource) != 0){
+			read_unlock(&ipa_rm_ctx->lock);
 			return;
+		}
 		ipa_rm_resource_consumer_handle_cb(
 				(struct ipa_rm_resource_cons *)resource,
 				ipa_rm_work->event);
+		read_unlock(&ipa_rm_ctx->lock);
 		break;
 	default:
 		break;
@@ -351,6 +410,7 @@
 	result = ipa_rm_dep_graph_create(&(ipa_rm_ctx->dep_graph));
 	if (result)
 		goto graph_alloc_fail;
+	rwlock_init(&ipa_rm_ctx->lock);
 	IPADBG("IPA RM ipa_rm_initialize SUCCESS\n");
 	return 0;
 
diff --git a/drivers/platform/msm/ipa/ipa_rm_dependency_graph.c b/drivers/platform/msm/ipa/ipa_rm_dependency_graph.c
index 6afab42..8144a42 100644
--- a/drivers/platform/msm/ipa/ipa_rm_dependency_graph.c
+++ b/drivers/platform/msm/ipa/ipa_rm_dependency_graph.c
@@ -39,7 +39,6 @@
 		result = -ENOMEM;
 		goto bail;
 	}
-	rwlock_init(&((*dep_graph)->lock));
 bail:
 	return result;
 }
@@ -55,12 +54,10 @@
 	int resource_index;
 	if (!graph)
 		return;
-	write_lock(&graph->lock);
 	for (resource_index = 0;
 			resource_index < IPA_RM_RESOURCE_MAX;
 			resource_index++)
 		kfree(graph->resource_table[resource_index]);
-	write_unlock(&graph->lock);
 	memset(graph->resource_table, 0, sizeof(graph->resource_table));
 }
 
@@ -88,9 +85,7 @@
 		result = -EINVAL;
 		goto bail;
 	}
-	read_lock(&graph->lock);
 	*resource = graph->resource_table[resource_index];
-	read_unlock(&graph->lock);
 	if (!*resource) {
 		result = -EINVAL;
 		goto bail;
@@ -112,6 +107,7 @@
 {
 	int result = 0;
 	int resource_index;
+
 	if (!graph || !resource) {
 		result = -EINVAL;
 		goto bail;
@@ -121,14 +117,29 @@
 		result = -EINVAL;
 		goto bail;
 	}
-	write_lock(&graph->lock);
 	graph->resource_table[resource_index] = resource;
-	write_unlock(&graph->lock);
 bail:
 	return result;
 }
 
 /**
+ * ipa_rm_dep_graph_remove() - removes resource from graph
+ * @graph: [in] dependency graph
+ * @resource: [in] resource to add
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int ipa_rm_dep_graph_remove(struct ipa_rm_dep_graph *graph,
+		enum ipa_rm_resource_name resource_name)
+{
+	if (!graph)
+		return -EINVAL;
+
+	graph->resource_table[resource_name] = NULL;
+	return 0;
+}
+
+/**
  * ipa_rm_dep_graph_add_dependency() - adds dependency between
  *				two nodes in graph
  * @graph: [in] dependency graph
diff --git a/drivers/platform/msm/ipa/ipa_rm_dependency_graph.h b/drivers/platform/msm/ipa/ipa_rm_dependency_graph.h
index 19d9461..4126819 100644
--- a/drivers/platform/msm/ipa/ipa_rm_dependency_graph.h
+++ b/drivers/platform/msm/ipa/ipa_rm_dependency_graph.h
@@ -19,7 +19,6 @@
 
 struct ipa_rm_dep_graph {
 	struct ipa_rm_resource *resource_table[IPA_RM_RESOURCE_MAX];
-	rwlock_t lock;
 };
 
 int ipa_rm_dep_graph_get_resource(
@@ -34,6 +33,9 @@
 int ipa_rm_dep_graph_add(struct ipa_rm_dep_graph *graph,
 			 struct ipa_rm_resource *resource);
 
+int ipa_rm_dep_graph_remove(struct ipa_rm_dep_graph *graph,
+				enum ipa_rm_resource_name resource_name);
+
 int ipa_rm_dep_graph_add_dependency(struct ipa_rm_dep_graph *graph,
 				enum ipa_rm_resource_name resource_name,
 				enum ipa_rm_resource_name depends_on_name);
diff --git a/drivers/platform/msm/ipa/ipa_rm_resource.c b/drivers/platform/msm/ipa/ipa_rm_resource.c
index 3615952..0fc4826 100644
--- a/drivers/platform/msm/ipa/ipa_rm_resource.c
+++ b/drivers/platform/msm/ipa/ipa_rm_resource.c
@@ -80,8 +80,8 @@
 	int result = 0;
 	int driver_result;
 	unsigned long flags;
-	IPADBG("IPA RM ::ipa_rm_resource_consumer_request %d ENTER\n",
-		consumer->resource.name);
+	IPADBG("IPA RM ::%s name %d ENTER\n",
+	       __func__, consumer->resource.name);
 	spin_lock_irqsave(&consumer->resource.state_lock, flags);
 	switch (consumer->resource.state) {
 	case IPA_RM_RELEASED:
@@ -115,8 +115,7 @@
 	consumer->usage_count++;
 bail:
 	spin_unlock_irqrestore(&consumer->resource.state_lock, flags);
-	IPADBG("IPA RM ::ipa_rm_resource_consumer_request %d EXIT %d\n",
-		consumer->resource.name, result);
+	IPADBG("IPA RM ::ipa_rm_resource_consumer_request EXIT [%d]\n", result);
 	return result;
 }
 
@@ -127,8 +126,8 @@
 	int driver_result;
 	unsigned long flags;
 	enum ipa_rm_resource_state save_state;
-	IPADBG("IPA RM ::ipa_rm_resource_consumer_release %d ENTER\n",
-		consumer->resource.name);
+	IPADBG("IPA RM ::%s name %d ENTER\n",
+	       __func__, consumer->resource.name);
 	spin_lock_irqsave(&consumer->resource.state_lock, flags);
 	switch (consumer->resource.state) {
 	case IPA_RM_RELEASED:
@@ -163,8 +162,7 @@
 	}
 bail:
 	spin_unlock_irqrestore(&consumer->resource.state_lock, flags);
-	IPADBG("IPA RM ::ipa_rm_resource_consumer_release %d EXIT %d\n",
-		consumer->resource.name, result);
+	IPADBG("IPA RM ::ipa_rm_resource_consumer_release EXIT [%d]\n", result);
 	return result;
 }
 
@@ -332,19 +330,56 @@
  * ipa_rm_resource_delete() - deletes resource
  * @resource: [in] resource
  *			for resource initialization with IPA RM
+ *
+ * Returns: 0 on success, negative on failure
  */
-void ipa_rm_resource_delete(struct ipa_rm_resource *resource)
+int ipa_rm_resource_delete(struct ipa_rm_resource *resource)
 {
-	if (!resource)
-		return;
-	if (resource->peers_list)
-		ipa_rm_peers_list_delete(resource->peers_list);
+	struct ipa_rm_resource *consumer, *producer;
+	int i, result = 0;
+
+	IPADBG("IPA RM: %s ENTER\n", __func__);
+
+	if (!resource) {
+		IPADBG("ipa_rm_resource_delete ENTER with invalid param\n");
+		return -EINVAL;
+	}
 	if (resource->type == IPA_RM_PRODUCER) {
+		if (resource->peers_list) {
+			for (i = IPA_RM_RESOURCE_PROD_MAX;
+					i < IPA_RM_RESOURCE_MAX;
+						++i) {
+				consumer = ipa_rm_peers_list_get_resource(
+						i,
+						resource->peers_list);
+				if (consumer) {
+					ipa_rm_resource_delete_dependency(
+						resource,
+						consumer);
+				}
+			}
+			ipa_rm_peers_list_delete(resource->peers_list);
+		}
 		ipa_rm_resource_producer_delete(
 				(struct ipa_rm_resource_prod *) resource);
 		kfree((struct ipa_rm_resource_prod *) resource);
-	} else
+	} else if (resource->type == IPA_RM_CONSUMER) {
+		if (resource->peers_list) {
+			for (i = 0; i < IPA_RM_RESOURCE_PROD_MAX; ++i) {
+				producer = ipa_rm_peers_list_get_resource(
+							i,
+							resource->peers_list);
+				if (producer)
+					ipa_rm_resource_delete_dependency(
+							producer,
+							resource);
+			}
+			ipa_rm_peers_list_delete(resource->peers_list);
+		}
 		kfree((struct ipa_rm_resource_cons *) resource);
+	}
+	IPADBG("ipa_rm_resource_delete SUCCESS\n");
+	return result;
 }
 
 /**
@@ -367,6 +402,8 @@
 		result = -EPERM;
 		goto bail;
 	}
+	IPADBG("IPA RM: %s name %d ENTER\n",
+	       __func__, producer->resource.name);
 	read_lock(&producer->event_listeners_lock);
 	list_for_each(pos, &(producer->event_listeners)) {
 		reg_info = list_entry(pos,
@@ -511,6 +548,10 @@
 	unsigned long flags;
 	if (!resource || !depends_on)
 		return -EINVAL;
+	IPADBG("IPA RM: %s from %d to %d ENTER\n",
+			__func__,
+	       resource->name,
+	       depends_on->name);
 	if (!ipa_rm_peers_list_check_dependency(resource->peers_list,
 			resource->name,
 			depends_on->peers_list,
@@ -539,8 +580,6 @@
 		goto bail;
 	}
 	spin_unlock_irqrestore(&resource->state_lock, flags);
-	(void) ipa_rm_resource_consumer_release(
-			(struct ipa_rm_resource_cons *)depends_on);
 	if (ipa_rm_peers_list_has_last_peer(resource->peers_list)) {
 		(void) ipa_rm_wq_send_cmd(IPA_RM_WQ_NOTIFY_PROD,
 				resource->name,
@@ -551,6 +590,12 @@
 			depends_on->name);
 	ipa_rm_peers_list_remove_peer(depends_on->peers_list,
 			resource->name);
+	(void) ipa_rm_resource_consumer_release(
+			(struct ipa_rm_resource_cons *)depends_on);
+	IPADBG("IPA RM: %s from %d to %d SUCCESS\n",
+		__func__,
+		resource->name,
+		depends_on->name);
 bail:
 	return result;
 }
@@ -568,7 +613,7 @@
 	unsigned long flags;
 	struct ipa_rm_resource *consumer;
 	int consumer_result;
-	IPADBG("IPA RM ::ipa_rm_resource_producer_request %d ENTER\n",
+	IPADBG("IPA RM ::ipa_rm_resource_producer_request [%d] ENTER\n",
 			producer->resource.name);
 	if (ipa_rm_peers_list_is_empty(producer->resource.peers_list)) {
 		spin_lock_irqsave(&producer->resource.state_lock, flags);
@@ -628,12 +673,11 @@
 	if (producer->pending_request == 0)
 		producer->resource.state = IPA_RM_GRANTED;
 	spin_unlock_irqrestore(&producer->resource.state_lock, flags);
-	return result;
+	goto bail;
 unlock_and_bail:
 	spin_unlock_irqrestore(&producer->resource.state_lock, flags);
 bail:
-	IPADBG("IPA RM ::ipa_rm_resource_producer_request %d EXIT %d\n",
-		producer->resource.name, result);
+	IPADBG("IPA RM ::ipa_rm_resource_producer_request EXIT[%d]\n", result);
 	return result;
 }
 
@@ -651,8 +695,9 @@
 	unsigned long flags;
 	struct ipa_rm_resource *consumer;
 	int consumer_result;
-	IPADBG("IPA RM ::ipa_rm_resource_producer_release %d ENTER\n",
-		producer->resource.name);
+	IPADBG("IPA RM: %s name %d ENTER\n",
+			__func__,
+			producer->resource.name);
 	if (ipa_rm_peers_list_is_empty(producer->resource.peers_list)) {
 		spin_lock_irqsave(&producer->resource.state_lock, flags);
 		producer->resource.state = IPA_RM_RELEASED;
@@ -708,8 +753,7 @@
 	return result;
 bail:
 	spin_unlock_irqrestore(&producer->resource.state_lock, flags);
-	IPADBG("IPA RM ::ipa_rm_resource_producer_release %d EXIT %d\n",
-		producer->resource.name, result);
+	IPADBG("IPA RM ::ipa_rm_resource_producer_release EXIT[%d]\n", result);
 	return result;
 }
 
diff --git a/drivers/platform/msm/ipa/ipa_rm_resource.h b/drivers/platform/msm/ipa/ipa_rm_resource.h
index b9c2e91..81ccc53 100644
--- a/drivers/platform/msm/ipa/ipa_rm_resource.h
+++ b/drivers/platform/msm/ipa/ipa_rm_resource.h
@@ -99,7 +99,7 @@
 		struct ipa_rm_create_params *create_params,
 		struct ipa_rm_resource **resource);
 
-void ipa_rm_resource_delete(struct ipa_rm_resource *resource);
+int ipa_rm_resource_delete(struct ipa_rm_resource *resource);
 
 int ipa_rm_resource_producer_register(struct ipa_rm_resource_prod *producer,
 				struct ipa_rm_register_params *reg_params);
diff --git a/drivers/platform/msm/ipa/teth_bridge.c b/drivers/platform/msm/ipa/teth_bridge.c
index 40c8fc7..c28a5ee 100644
--- a/drivers/platform/msm/ipa/teth_bridge.c
+++ b/drivers/platform/msm/ipa/teth_bridge.c
@@ -69,6 +69,13 @@
 #define TETH_TOTAL_FLT_ENTRIES_IP 2
 #define TETH_IP_FAMILIES 2
 
+/**
+ * struct mac_addresses_type - store host PC and device MAC addresses
+ * @host_pc_mac_addr: MAC address of the host PC
+ * @host_pc_mac_addr_known: is the MAC address of the host PC known ?
+ * @device_mac_addr: MAC address of the device
+ * @device_mac_addr_known: is the MAC address of the device known ?
+ */
 struct mac_addresses_type {
 	u8 host_pc_mac_addr[ETH_ALEN];
 	bool host_pc_mac_addr_known;
@@ -76,12 +83,59 @@
 	bool device_mac_addr_known;
 };
 
+/**
+ * struct stats - driver statistics, viewable using debugfs
+ * @a2_to_usb_num_sw_tx_packets: number of packets bridged from A2 to USB using
+ * the SW bridge
+ * @usb_to_a2_num_sw_tx_packets: number of packets bridged from USB to A2 using
+ * the SW bridge
+ * @num_sw_tx_packets_during_resource_wakeup: number of packets bridged during a
+ * resource wakeup period, there is a special treatment for these kind of
+ * packets
+ */
 struct stats {
 	u64 a2_to_usb_num_sw_tx_packets;
 	u64 usb_to_a2_num_sw_tx_packets;
 	u64 num_sw_tx_packets_during_resource_wakeup;
 };
 
+/**
+ * struct teth_bridge_ctx - Tethering bridge driver context information
+ * @class: kernel class pointer
+ * @dev_num: kernel device number
+ * @dev: kernel device struct pointer
+ * @cdev: kernel character device struct
+ * @usb_ipa_pipe_hdl: USB to IPA pipe handle
+ * @ipa_usb_pipe_hdl: IPA to USB pipe handle
+ * @a2_ipa_pipe_hdl: A2 to IPA pipe handle
+ * @ipa_a2_pipe_hdl: IPA to A2 pipe handle
+ * @is_connected: is the tethered bridge connected ?
+ * @link_protocol: IP / Ethernet
+ * @mac_addresses: Struct which holds host pc and device MAC addresses, relevant
+ * in ethernet mode only
+ * @is_hw_bridge_complete: is HW bridge setup ?
+ * @aggr_params: aggregation parmeters
+ * @aggr_params_known: are the aggregation parameters known ?
+ * @tethering_mode: Rmnet / MBIM
+ * @is_bridge_prod_up: completion object signaled when the bridge producer
+ * finished its resource request procedure
+ * @is_bridge_prod_down: completion object signaled when the bridge producer
+ * finished its resource release procedure
+ * @comp_hw_bridge_work: used for setting up the HW bridge using a workqueue
+ * @comp_hw_bridge_in_progress: true when the HW bridge setup is in progress
+ * @aggr_caps: aggregation capabilities
+ * @stats: statistics, how many packets were transmitted using the SW bridge
+ * @teth_wq: dedicated workqueue, used for setting up the HW bridge and for
+ * sending packets using the SW bridge when the system is waking up from power
+ * collapse
+ * @a2_ipa_hdr_len: A2 to IPA header length, used to configure the A2 endpoint
+ * for header removal
+ * @hdr_del: array to store the headers handles in order to delete them later
+ * @routing_del: array of routing rules handles, one array for IPv4 and one for
+ * IPv6
+ * @filtering_del: array of routing rules handles, one array for IPv4 and one
+ * for IPv6
+ */
 struct teth_bridge_ctx {
 	struct class *class;
 	dev_t dev_num;
@@ -117,6 +171,12 @@
 	TETH_A2_TO_USB,
 };
 
+/**
+ * struct teth_work - wrapper for an skb which is sent using a workqueue
+ * @work: used by the workqueue
+ * @skb: pointer to the skb to be sent
+ * @dir: direction of send, A2 to USB or USB to A2
+ */
 struct teth_work {
 	struct work_struct work;
 	struct sk_buff *skb;
@@ -128,6 +188,15 @@
 static char dbg_buff[TETH_MAX_MSG_LEN];
 #endif
 
+/**
+ * add_eth_hdrs() - add Ethernet headers to IPA
+ * @hdr_name_ipv4: header name for IPv4
+ * @hdr_name_ipv6: header name for IPv6
+ * @src_mac_addr: source MAC address
+ * @dst_mac_addr: destination MAC address
+ *
+ * This function is called only when link protocol is Ethernet
+ */
 static int add_eth_hdrs(char *hdr_name_ipv4, char *hdr_name_ipv6,
 			u8 *src_mac_addr, u8 *dst_mac_addr)
 {
@@ -269,6 +338,12 @@
 	return res;
 }
 
+/**
+ * configure_ipa_header_block() - adds headers and configures endpoint registers
+ *
+ * - For IP link protocol and MBIM aggregation, configure MBIM header
+ * - For Ethernet link protocol, configure Ethernet headers
+ */
 static int configure_ipa_header_block(void)
 {
 	int res;
@@ -412,6 +487,14 @@
 	return res;
 }
 
+/**
+ * configure_ipa_routing_block() - Configure the IPA routing block
+ *
+ * This function configures IPA for:
+ * - Route all packets from USB to A2
+ * - Route all packets from A2 to USB
+ * - Use the correct headers in Ethernet or MBIM cases
+ */
 static int configure_ipa_routing_block(void)
 {
 	int res;
@@ -547,6 +630,13 @@
 	return res;
 }
 
+/**
+ * configure_ipa_filtering_block() - Configures IPA filtering block
+ *
+ * This function configures IPA for:
+ * - Filter all traffic coming from USB to A2 pointing routing table
+ * - Filter all traffic coming from A2 to USB pointing routing table
+ */
 static int configure_ipa_filtering_block(void)
 {
 	int res;
@@ -663,6 +753,11 @@
 	}
 }
 
+/**
+ * teth_set_aggregation() - set aggregation parameters to IPA
+ *
+ * The parameters to this function are passed in the context variable ipa_ctx.
+ */
 static int teth_set_aggregation(void)
 {
 	int res;
@@ -727,6 +822,14 @@
 	return res;
 }
 
+/**
+ * teth_request_resource() - wrapper function to
+ * ipa_rm_inactivity_timer_request_resource()
+ *
+ * - initialize the is_bridge_prod_up completion object
+ * - request the resource
+ * - error handling
+ */
 static int teth_request_resource(void)
 {
 	int res;
@@ -744,6 +847,10 @@
 	return 0;
 }
 
+/**
+ * complete_hw_bridge() - setup the HW bridge from USB to A2 and back through
+ * IPA
+ */
 static void complete_hw_bridge(struct work_struct *work)
 {
 	int res;
@@ -812,6 +919,20 @@
 		  mac_addr[4], mac_addr[5]);
 }
 
+/**
+ * check_to_complete_hw_bridge() - can HW bridge be set up ?
+ * @param skb: pointer to socket buffer
+ * @param my_mac_addr: pointer to write 'my' extracted MAC address to
+ * @param my_mac_addr_known: pointer to update whether 'my' extracted MAC
+ * address is known
+ * @param peer_mac_addr_known: pointer to update whether the 'peer' extracted
+ * MAC address is known
+ *
+ * This function is used by both A2 and USB callback functions, therefore the
+ * meaning of 'my' and 'peer' changes according to the context.
+ * Extracts MAC address from the packet in Ethernet link protocol,
+ * Sets up the HW bridge in case all conditions are met.
+ */
 static void check_to_complete_hw_bridge(struct sk_buff *skb,
 					u8 *my_mac_addr,
 					bool *my_mac_addr_known,
@@ -841,6 +962,9 @@
 	}
 }
 
+/**
+ * teth_send_skb_work() - workqueue function for sending a packet
+ */
 static void teth_send_skb_work(struct work_struct *work)
 {
 	struct teth_work *work_data =
@@ -887,6 +1011,15 @@
 	kfree(work_data);
 }
 
+/**
+ * defer_skb_send() - defer sending an skb using the SW bridge to a workqueue
+ * @param skb: pointer to the socket buffer
+ * @param dir: direction of send
+ *
+ * In case where during a packet send, the A2 or USB needs to wake up from power
+ * collapse, defer the send and return the context to IPA driver. This is
+ * important since IPA driver has a single threaded Rx path.
+ */
 static void defer_skb_send(struct sk_buff *skb, enum teth_packet_direction dir)
 {
 	struct teth_work *work = kmalloc(sizeof(struct teth_work), GFP_KERNEL);
@@ -909,6 +1042,30 @@
 	queue_work(teth_ctx->teth_wq, &work->work);
 }
 
+/**
+ * usb_notify_cb() - callback function for sending packets from USB to A2
+ * @param priv: private data
+ * @param evt: event - RECEIVE or WRITE_DONE
+ * @param data: pointer to skb to be sent
+ *
+ * This callback function is installed by the IPA driver, it is invoked in 2
+ * cases:
+ * 1. When a packet comes from the USB pipe and is routed to A5 (SW bridging)
+ * 2. After a packet has been bridged from USB to A2 and its skb should be freed
+ *
+ * Invocation: sps driver --> IPA driver --> bridge driver
+ *
+ * In the event of IPA_RECEIVE:
+ * - Checks whether the HW bridge can be set up..
+ * - Requests the BRIDGE_PROD resource so that A2 and USB are not in power
+ * collapse. In case where the resource is waking up, defer the send operation
+ * to a workqueue in order to not block the IPA driver single threaded Rx path.
+ * - Sends the packets to A2 using a2_service driver API.
+ * - Releases the BRIDGE_PROD resource.
+ *
+ * In the event of IPA_WRITE_DONE:
+ * - Frees the skb memory
+ */
 static void usb_notify_cb(void *priv,
 			  enum ipa_dp_evt_type evt,
 			  unsigned long data)
@@ -969,6 +1126,30 @@
 	return;
 }
 
+/**
+ * a2_notify_cb() - callback function for sending packets from A2 to USB
+ * @param user_data: private data
+ * @param event: event - RECEIVE or WRITE_DONE
+ * @param data: pointer to skb to be sent
+ *
+ * This callback function is installed by the IPA driver, it is invoked in 2
+ * cases:
+ * 1. When a packet comes from the A2 pipe and is routed to A5 (SW bridging)
+ * 2. After a packet has been bridged from A2 to USB and its skb should be freed
+ *
+ * Invocation: sps driver --> IPA driver --> a2_service driver --> bridge driver
+ *
+ * In the event of A2_MUX_RECEIVE:
+ * - Checks whether the HW bridge can be set up..
+ * - Requests the BRIDGE_PROD resource so that A2 and USB are not in power
+ * collapse. In case where the resource is waking up, defer the send operation
+ * to a workqueue in order to not block the IPA driver single threaded Rx path.
+ * - Sends the packets to USB using IPA drivers ipa_tx_dp() API.
+ * - Releases the BRIDGE_PROD resource.
+ *
+ * In the event of A2_MUX_WRITE_DONE:
+ * - Frees the skb memory
+ */
 static void a2_notify_cb(void *user_data,
 			 enum a2_mux_event_type event,
 			 unsigned long data)
@@ -1031,6 +1212,15 @@
 	return;
 }
 
+/**
+ * bridge_prod_notify_cb() - IPA Resource Manager callback function
+ * @param notify_cb_data: private data
+ * @param event: RESOURCE_GRANTED / RESOURCE_RELEASED
+ * @param data: not used in this case
+ *
+ * This callback function is called by IPA resource manager to notify the
+ * BRIDGE_PROD entity of events like RESOURCE_GRANTED and RESOURCE_RELEASED.
+ */
 static void bridge_prod_notify_cb(void *notify_cb_data,
 				  enum ipa_rm_event event,
 				  unsigned long data)
@@ -1075,10 +1265,17 @@
 
 /**
 * teth_bridge_init() - Initialize the Tethering bridge driver
-* @usb_notify_cb_ptr:	Callback function which should be used
-*			by the caller. Output parameter.
-* @private_data_ptr:	Data for the callback function. Should
-*			be used by the caller. Output parameter.
+* @usb_notify_cb_ptr:	Callback function which should be used by the caller.
+* Output parameter.
+* @private_data_ptr:	Data for the callback function. Should be used by the
+* caller. Output parameter.
+*
+* USB driver gets a pointer to a callback function (usb_notify_cb) and an
+* associated data. USB driver installs this callback function in the call to
+* ipa_connect().
+*
+* Builds IPA resource manager dependency graph.
+*
 * Return codes: 0: success,
 *		-EINVAL - Bad parameter
 *		Other negative value - Failure
@@ -1145,6 +1342,9 @@
 }
 EXPORT_SYMBOL(teth_bridge_init);
 
+/**
+ * initialize_context() - Initialize the ipa_ctx struct
+ */
 static void initialize_context(void)
 {
 	TETH_DBG_FUNC_ENTRY();
@@ -1198,10 +1398,6 @@
 
 /**
 * teth_bridge_disconnect() - Disconnect tethering bridge module
-*
-* Return codes:	0: success
-*		-EPERM: Operation not permitted as the bridge is already
-*		disconnected
 */
 int teth_bridge_disconnect(void)
 {
@@ -1384,6 +1580,9 @@
 		   TETH_AGGR_MAX_AGGR_PACKET_SIZE_DEFAULT;
 }
 
+/**
+ * teth_set_bridge_mode() - set the link protocol (IP / Ethernet)
+ */
 static void teth_set_bridge_mode(enum teth_link_protocol_type link_protocol)
 {
 	teth_ctx->link_protocol = link_protocol;
@@ -1391,6 +1590,14 @@
 	memset(&teth_ctx->mac_addresses, 0, sizeof(teth_ctx->mac_addresses));
 }
 
+/**
+ * teth_bridge_set_aggr_params() - kernel API to set aggregation parameters
+ * @param aggr_params: aggregation parmeters for uplink and downlink
+ *
+ * Besides setting the aggregation parameters, the function enforces max tranfer
+ * size which is less then 8K and also forbids Ethernet link protocol with MBIM
+ * aggregation which is not supported by HW.
+ */
 int teth_bridge_set_aggr_params(struct teth_aggr_params *aggr_params)
 {
 	int res;
@@ -1540,6 +1747,10 @@
 	return res;
 }
 
+/**
+ * set_aggr_capabilities() - allocates and fills the aggregation capabilities
+ * struct
+ */
 static int set_aggr_capabilities(void)
 {
 	u16 NUM_PROTOCOLS = 2;
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index 42119aa..dc756bb 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -28,6 +28,7 @@
 #include <linux/of.h>
 #include <linux/sysfs.h>
 #include <linux/types.h>
+#include <linux/android_alarm.h>
 #include <mach/cpufreq.h>
 #include <mach/rpm-regulator.h>
 #include <mach/rpm-regulator-smd.h>
@@ -41,6 +42,10 @@
 static bool core_control_enabled;
 static uint32_t cpus_offlined;
 static DEFINE_MUTEX(core_control_mutex);
+static uint32_t wakeup_ms;
+static struct alarm thermal_rtc;
+static struct kobject *tt_kobj;
+static struct work_struct timer_work;
 
 static int enabled;
 static int rails_cnt;
@@ -58,6 +63,7 @@
 static bool psm_enabled;
 static bool psm_nodes_called;
 static bool psm_probed;
+static int *tsens_id_map;
 static DEFINE_MUTEX(vdd_rstr_mutex);
 static DEFINE_MUTEX(psm_mutex);
 
@@ -395,7 +401,7 @@
 	if (vdd_rstr_en.enabled == 0)
 		goto done_store_level;
 
-	ret = kstrtoint(buf, 10, &val);
+	ret = kstrtouint(buf, 10, &val);
 	if (ret) {
 		pr_err("Invalid input %s for level\n", buf);
 		goto done_store_level;
@@ -468,6 +474,62 @@
 	return count;
 }
 
+
+static int check_sensor_id(int sensor_id)
+{
+	int i = 0;
+	bool hw_id_found;
+	int ret = 0;
+
+	for (i = 0; i < max_tsens_num; i++) {
+		if (sensor_id == tsens_id_map[i]) {
+			hw_id_found = true;
+			break;
+		}
+	}
+	if (!hw_id_found) {
+		pr_err("%s: Invalid sensor hw id :%d\n", __func__, sensor_id);
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+static int create_sensor_id_map(void)
+{
+	int i = 0;
+	int ret = 0;
+
+	tsens_id_map = kzalloc(sizeof(int) * max_tsens_num,
+			GFP_KERNEL);
+	if (!tsens_id_map) {
+		pr_err("%s: Cannot allocate memory for tsens_id_map\n",
+				__func__);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < max_tsens_num; i++) {
+		ret = tsens_get_hw_id_mapping(i, &tsens_id_map[i]);
+		/* If return -ENXIO, hw_id is default in sequence */
+		if (ret) {
+			if (ret == -ENXIO) {
+				tsens_id_map[i] = i;
+				ret = 0;
+			} else {
+				pr_err( \
+				"%s: Failed to get hw id for sw id %d\n",
+				__func__, i);
+				goto fail;
+			}
+		}
+	}
+
+	return ret;
+fail:
+	kfree(tsens_id_map);
+	return ret;
+}
+
 static int msm_thermal_get_freq_table(void)
 {
 	int ret = 0;
@@ -578,7 +640,7 @@
 
 	mutex_lock(&vdd_rstr_mutex);
 	for (i = 0; i < max_tsens_num; i++) {
-		tsens_dev.sensor_num = i;
+		tsens_dev.sensor_num = tsens_id_map[i];
 		ret = tsens_get_temp(&tsens_dev, &temp);
 		if (ret) {
 			pr_debug("%s: Unable to read TSENS sensor %d\n",
@@ -623,7 +685,7 @@
 
 	mutex_lock(&psm_mutex);
 	for (i = 0; i < max_tsens_num; i++) {
-		tsens_dev.sensor_num = i;
+		tsens_dev.sensor_num = tsens_id_map[i];
 		ret = tsens_get_temp(&tsens_dev, &temp);
 		if (ret) {
 			pr_debug("%s: Unable to read TSENS sensor %d\n",
@@ -749,6 +811,39 @@
 	.notifier_call = msm_thermal_cpu_callback,
 };
 
+static void thermal_rtc_setup(void)
+{
+	ktime_t wakeup_time;
+	ktime_t curr_time;
+
+	curr_time = alarm_get_elapsed_realtime();
+	wakeup_time = ktime_add_us(curr_time,
+			(wakeup_ms * USEC_PER_MSEC));
+	alarm_start_range(&thermal_rtc, wakeup_time,
+			wakeup_time);
+	pr_debug("%s: Current Time: %ld %ld, Alarm set to: %ld %ld\n",
+			KBUILD_MODNAME,
+			ktime_to_timeval(curr_time).tv_sec,
+			ktime_to_timeval(curr_time).tv_usec,
+			ktime_to_timeval(wakeup_time).tv_sec,
+			ktime_to_timeval(wakeup_time).tv_usec);
+
+}
+
+static void timer_work_fn(struct work_struct *work)
+{
+	sysfs_notify(tt_kobj, NULL, "wakeup_ms");
+}
+
+static void thermal_rtc_callback(struct alarm *al)
+{
+	struct timeval ts;
+	ts = ktime_to_timeval(alarm_get_elapsed_realtime());
+	schedule_work(&timer_work);
+	pr_debug("%s: Time on alarm expiry: %ld %ld\n", KBUILD_MODNAME,
+			ts.tv_sec, ts.tv_usec);
+}
+
 /**
  * We will reset the cpu frequencies limits here. The core online/offline
  * status will be carried over to the process stopping the msm_thermal, as
@@ -905,6 +1000,52 @@
 	.attrs = cc_attrs,
 };
 
+static ssize_t show_wakeup_ms(struct kobject *kobj,
+		struct kobj_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", wakeup_ms);
+}
+
+static ssize_t store_wakeup_ms(struct kobject *kobj,
+		struct kobj_attribute *attr, const char *buf, size_t count)
+{
+	int ret;
+	ret = kstrtouint(buf, 10, &wakeup_ms);
+
+	if (ret) {
+		pr_err("%s: Trying to set invalid wakeup timer\n",
+				KBUILD_MODNAME);
+		return ret;
+	}
+
+	if (wakeup_ms > 0) {
+		thermal_rtc_setup();
+		pr_debug("%s: Timer started for %ums\n", KBUILD_MODNAME,
+				wakeup_ms);
+	} else {
+		ret = alarm_cancel(&thermal_rtc);
+		if (ret)
+			pr_debug("%s: Timer canceled\n", KBUILD_MODNAME);
+		else
+			pr_debug("%s: No active timer present to cancel\n",
+					KBUILD_MODNAME);
+
+	}
+	return count;
+}
+
+static __cpuinitdata struct kobj_attribute timer_attr =
+__ATTR(wakeup_ms, 0644, show_wakeup_ms, store_wakeup_ms);
+
+static __cpuinitdata struct attribute *tt_attrs[] = {
+	&timer_attr.attr,
+	NULL,
+};
+
+static __cpuinitdata struct attribute_group tt_attr_group = {
+	.attrs = tt_attrs,
+};
+
 static __init int msm_thermal_add_cc_nodes(void)
 {
 	struct kobject *module_kobj = NULL;
@@ -941,15 +1082,54 @@
 	return ret;
 }
 
+static __init int msm_thermal_add_timer_nodes(void)
+{
+	struct kobject *module_kobj = NULL;
+	int ret = 0;
+
+	module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
+	if (!module_kobj) {
+		pr_err("%s: cannot find kobject for module\n",
+			KBUILD_MODNAME);
+		ret = -ENOENT;
+		goto failed;
+	}
+
+	tt_kobj = kobject_create_and_add("thermal_timer", module_kobj);
+	if (!tt_kobj) {
+		pr_err("%s: cannot create timer kobj\n",
+				KBUILD_MODNAME);
+		ret = -ENOMEM;
+		goto failed;
+	}
+
+	ret = sysfs_create_group(tt_kobj, &tt_attr_group);
+	if (ret) {
+		pr_err("%s: cannot create group\n", KBUILD_MODNAME);
+		goto failed;
+	}
+
+	return 0;
+
+failed:
+	if (tt_kobj)
+		kobject_del(tt_kobj);
+	return ret;
+}
+
 int __devinit msm_thermal_init(struct msm_thermal_data *pdata)
 {
 	int ret = 0;
 
 	BUG_ON(!pdata);
 	tsens_get_max_sensor_num(&max_tsens_num);
-	BUG_ON(msm_thermal_info.sensor_id >= max_tsens_num);
 	memcpy(&msm_thermal_info, pdata, sizeof(struct msm_thermal_data));
 
+	if (create_sensor_id_map())
+		return -EINVAL;
+	if (check_sensor_id(msm_thermal_info.sensor_id))
+		return -EINVAL;
+
 	enabled = 1;
 	core_control_enabled = 1;
 	INIT_DELAYED_WORK(&check_temp_work, check_temp);
@@ -1452,6 +1632,10 @@
 	msm_thermal_add_cc_nodes();
 	msm_thermal_add_psm_nodes();
 	msm_thermal_add_vdd_rstr_nodes();
+	alarm_init(&thermal_rtc, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
+			thermal_rtc_callback);
+	INIT_WORK(&timer_work, timer_work_fn);
+	msm_thermal_add_timer_nodes();
 
 	return 0;
 }
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index fed13e6..7363325 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -337,7 +337,7 @@
 	if (pipe && pipe->ndx != req->id) {
 		pr_debug("replacing pnum=%d at stage=%d mux=%d\n",
 				pipe->num, req->z_order, mixer_mux);
-		pipe->params_changed = true;
+		mdss_mdp_mixer_pipe_unstage(pipe);
 	}
 
 	mixer = mdss_mdp_mixer_get(mdp5_data->ctl, mixer_mux);
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index ca7a586..d63232a 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -72,11 +72,9 @@
 #ifdef CONFIG_CMA
 bool is_cma_pageblock(struct page *page);
 #  define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA)
-#  define cma_wmark_pages(zone)	zone->min_cma_pages
 #else
 #  define is_cma_pageblock(page) false
 #  define is_migrate_cma(migratetype) false
-#  define cma_wmark_pages(zone) 0
 #endif
 
 #define for_each_migratetype_order(order, type) \
@@ -385,11 +383,6 @@
 	seqlock_t		span_seqlock;
 #endif
 #ifdef CONFIG_CMA
-	/*
-	 * CMA needs to increase watermark levels during the allocation
-	 * process to make sure that the system is not starved.
-	 */
-	unsigned long		min_cma_pages;
 	bool			cma_alloc;
 #endif
 	struct free_area	free_area[MAX_ORDER];
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 87730b1..f064837 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -6516,6 +6516,11 @@
 #define AANC_HW_BLOCK_VERSION_1				(1)
 #define AANC_HW_BLOCK_VERSION_2				(2)
 
+/*Clip bank selection*/
+#define AFE_API_VERSION_CLIP_BANK_SEL_CFG 0x1
+#define AFE_CLIP_MAX_BANKS		4
+#define AFE_PARAM_ID_CLIP_BANK_SEL_CFG 0x00010242
+
 struct afe_param_aanc_port_cfg {
 	/* Minor version used for tracking the version of the module's
 	* source port configuration.
@@ -6550,6 +6555,18 @@
 	uint32_t aanc_hw_version;
 } __packed;
 
+struct afe_param_id_clip_bank_sel {
+	/* Minor version used for tracking the version of the module's
+	* hw version
+	*/
+	uint32_t minor_version;
+
+	/* Number of banks to be read */
+	uint32_t num_banks;
+
+	uint32_t bank_map[AFE_CLIP_MAX_BANKS];
+} __packed;
+
 /* ERROR CODES */
 /* Success. The operation completed with no errors. */
 #define ADSP_EOK          0x00000000
@@ -6782,6 +6799,8 @@
 	AFE_SLIMBUS_SLAVE_CONFIG,
 	AFE_CDC_REGISTERS_CONFIG,
 	AFE_AANC_VERSION,
+	AFE_CDC_CLIP_REGISTERS_CONFIG,
+	AFE_CLIP_BANK_SEL,
 	AFE_MAX_CONFIG_TYPES,
 };
 
@@ -6903,4 +6922,10 @@
 /* Dolby DAP topology */
 #define DOLBY_ADM_COPP_TOPOLOGY_ID	0x0001033B
 
+struct afe_svc_cmd_set_clip_bank_selection {
+	struct apr_hdr hdr;
+	struct afe_svc_cmd_set_param param;
+	struct afe_port_param_data_v2 pdata;
+	struct afe_param_id_clip_bank_sel bank_sel;
+} __packed;
 #endif /*_APR_AUDIO_V2_H_ */
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 69b9521..798c750 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -785,6 +785,10 @@
 	set_pageblock_migratetype(page, MIGRATE_CMA);
 	__free_pages(page, pageblock_order);
 	totalram_pages += pageblock_nr_pages;
+#ifdef CONFIG_HIGHMEM
+	if (PageHighMem(page))
+		totalhigh_pages += pageblock_nr_pages;
+#endif
 }
 #endif
 
@@ -5199,10 +5203,6 @@
 		zone->watermark[WMARK_LOW]  = min_wmark_pages(zone) + (tmp >> 2);
 		zone->watermark[WMARK_HIGH] = min_wmark_pages(zone) + (tmp >> 1);
 
-		zone->watermark[WMARK_MIN] += cma_wmark_pages(zone);
-		zone->watermark[WMARK_LOW] += cma_wmark_pages(zone);
-		zone->watermark[WMARK_HIGH] += cma_wmark_pages(zone);
-
 		setup_zone_migrate_reserve(zone);
 		spin_unlock_irqrestore(&zone->lock, flags);
 	}
@@ -5820,54 +5820,6 @@
 	return ret > 0 ? 0 : ret;
 }
 
-/*
- * Update zone's cma pages counter used for watermark level calculation.
- */
-static inline void __update_cma_watermarks(struct zone *zone, int count)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&zone->lock, flags);
-	zone->min_cma_pages += count;
-	spin_unlock_irqrestore(&zone->lock, flags);
-	setup_per_zone_wmarks();
-}
-
-/*
- * Trigger memory pressure bump to reclaim some pages in order to be able to
- * allocate 'count' pages in single page units. Does similar work as
- *__alloc_pages_slowpath() function.
- */
-static int __reclaim_pages(struct zone *zone, gfp_t gfp_mask, int count)
-{
-	enum zone_type high_zoneidx = gfp_zone(gfp_mask);
-	struct zonelist *zonelist = node_zonelist(0, gfp_mask);
-	int did_some_progress = 0;
-	int order = 1;
-
-	/*
-	 * Increase level of watermarks to force kswapd do his job
-	 * to stabilise at new watermark level.
-	 */
-	__update_cma_watermarks(zone, count);
-
-	/* Obey watermarks as if the page was being allocated */
-	while (!zone_watermark_ok(zone, 0, low_wmark_pages(zone), 0, 0)) {
-		wake_all_kswapd(order, zonelist, high_zoneidx, zone_idx(zone));
-
-		did_some_progress = __perform_reclaim(gfp_mask, order, zonelist,
-						      NULL);
-		if (!did_some_progress) {
-			/* Exhausted what can be done so it's blamo time */
-			out_of_memory(zonelist, gfp_mask, order, NULL, false);
-		}
-	}
-
-	/* Restore original watermark levels. */
-	__update_cma_watermarks(zone, -count);
-
-	return count;
-}
-
 /**
  * alloc_contig_range() -- tries to allocate given range of pages
  * @start:	start PFN to allocate
@@ -5968,11 +5920,6 @@
 		goto done;
 	}
 
-	/*
-	 * Reclaim enough pages to make sure that contiguous allocation
-	 * will not starve the system.
-	 */
-	__reclaim_pages(zone, GFP_HIGHUSER_MOVABLE, end-start);
 
 	/* Grab isolated pages from freelists. */
 	outer_end = isolate_freepages_range(outer_start, end);
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 43a1042..f9578af 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -110,6 +110,15 @@
 	AANC_FF_GAIN_ADAPTIVE,
 	AANC_FFGAIN_ADAPTIVE_EN,
 	AANC_GAIN_CONTROL,
+	SPKR_CLIP_PIPE_BANK_SEL,
+	SPKR_CLIPDET_VAL0,
+	SPKR_CLIPDET_VAL1,
+	SPKR_CLIPDET_VAL2,
+	SPKR_CLIPDET_VAL3,
+	SPKR_CLIPDET_VAL4,
+	SPKR_CLIPDET_VAL5,
+	SPKR_CLIPDET_VAL6,
+	SPKR_CLIPDET_VAL7,
 	MAX_CFG_REGISTERS,
 };
 
@@ -182,6 +191,74 @@
 		(TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_ANC1_GAIN_CTL),
 		AANC_GAIN_CONTROL, 0xFF, 8, 0
 	},
+	{
+		1,
+		(TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_DESTN3),
+		MAD_CLIP_INT_DEST_SELECT_REG, 0x8, 8, 0
+	},
+	{
+		1,
+		(TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_MASK3),
+		MAD_CLIP_INT_MASK_REG, 0x8, 8, 0
+	},
+	{
+		1,
+		(TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_STATUS3),
+		MAD_CLIP_INT_STATUS_REG, 0x8, 8, 0
+	},
+	{
+		1,
+		(TAIKO_REGISTER_START_OFFSET + TAIKO_A_INTR_CLEAR3),
+		MAD_CLIP_INT_CLEAR_REG, 0x8, 8, 0
+	},
+};
+
+static struct afe_param_cdc_reg_cfg clip_reg_cfg[] = {
+	{
+		1,
+		(TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_B1_CTL),
+		SPKR_CLIP_PIPE_BANK_SEL, 0x1, 8, 0
+	},
+	{
+		1,
+		(TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_VAL0),
+		SPKR_CLIPDET_VAL0, 0x1, 8, 0
+	},
+	{
+		1,
+		(TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_VAL1),
+		SPKR_CLIPDET_VAL1, 0x1, 8, 0
+	},
+	{
+		1,
+		(TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_VAL2),
+		SPKR_CLIPDET_VAL2, 0x1, 8, 0
+	},
+	{
+		1,
+		(TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_VAL3),
+		SPKR_CLIPDET_VAL3, 0x1, 8, 0
+	},
+	{
+		1,
+		(TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_VAL4),
+		SPKR_CLIPDET_VAL4, 0x1, 8, 0
+	},
+	{
+		1,
+		(TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_VAL5),
+		SPKR_CLIPDET_VAL5, 0x1, 8, 0
+	},
+	{
+		1,
+		(TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_VAL6),
+		SPKR_CLIPDET_VAL6, 0x1, 8, 0
+	},
+	{
+		1,
+		(TAIKO_REGISTER_START_OFFSET + TAIKO_A_CDC_SPKR_CLIPDET_VAL7),
+		SPKR_CLIPDET_VAL7, 0x1, 8, 0
+	},
 };
 
 static struct afe_param_cdc_reg_cfg_data taiko_audio_reg_cfg = {
@@ -189,11 +266,22 @@
 	.reg_data = audio_reg_cfg,
 };
 
+static struct afe_param_cdc_reg_cfg_data taiko_clip_reg_cfg = {
+	.num_registers = ARRAY_SIZE(clip_reg_cfg),
+	.reg_data = clip_reg_cfg,
+};
+
 static struct afe_param_id_cdc_aanc_version taiko_cdc_aanc_version = {
 	.cdc_aanc_minor_version = AFE_API_VERSION_CDC_AANC_VERSION,
 	.aanc_hw_version        = AANC_HW_BLOCK_VERSION_2,
 };
 
+static struct afe_param_id_clip_bank_sel clip_bank_sel = {
+	.minor_version = AFE_API_VERSION_CLIP_BANK_SEL_CFG,
+	.num_banks = AFE_CLIP_MAX_BANKS,
+	.bank_map = {0, 1, 2, 3},
+};
+
 module_param_cb(spkr_drv_wrnd, &spkr_drv_wrnd_param_ops, &spkr_drv_wrnd, 0644);
 MODULE_PARM_DESC(spkr_drv_wrnd,
 	       "Run software workaround to avoid leakage on the speaker drive");
@@ -5949,6 +6037,7 @@
 			   enum afe_config_type config_type)
 {
 	struct taiko_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct wcd9xxx *taiko_core = dev_get_drvdata(codec->dev->parent);
 
 	switch (config_type) {
 	case AFE_SLIMBUS_SLAVE_CONFIG:
@@ -5959,6 +6048,16 @@
 		return &taiko_slimbus_slave_port_cfg;
 	case AFE_AANC_VERSION:
 		return &taiko_cdc_aanc_version;
+	case AFE_CLIP_BANK_SEL:
+		if (!TAIKO_IS_1_0(taiko_core->version))
+			return &clip_bank_sel;
+		else
+			return NULL;
+	case AFE_CDC_CLIP_REGISTERS_CONFIG:
+		if (!TAIKO_IS_1_0(taiko_core->version))
+			return &taiko_clip_reg_cfg;
+		else
+			return NULL;
 	default:
 		pr_err("%s: Unknown config_type 0x%x\n", __func__, config_type);
 		return NULL;
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index ffb0f3b..1b51595 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -560,6 +560,34 @@
 		.name = "SEC_I2S_RX_HOSTLESS",
 	},
 	{
+		.capture = {
+			.stream_name = "Primary MI2S_TX Hostless Capture",
+			.aif_name = "PRI_MI2S_UL_HL",
+			.rates = SNDRV_PCM_RATE_8000_48000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 2,
+			.rate_min = 8000,
+			.rate_max = 48000,
+		},
+		.ops = &msm_fe_dai_ops,
+		.name = "PRI_MI2S_TX_HOSTLESS",
+	},
+	{
+		.playback = {
+			.stream_name = "Secondary MI2S_RX Hostless Playback",
+			.aif_name = "SEC_MI2S_DL_HL",
+			.rates = SNDRV_PCM_RATE_8000_48000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 2,
+			.rate_min =	8000,
+			.rate_max =    48000,
+		},
+		.ops = &msm_fe_dai_ops,
+		.name = "SEC_MI2S_RX_HOSTLESS",
+	},
+	{
 		.playback = {
 			.stream_name = "Voice2 Playback",
 			.aif_name = "VOICE2_DL",
diff --git a/sound/soc/msm/msm8x10.c b/sound/soc/msm/msm8x10.c
index 4dd85fc..464e8af 100644
--- a/sound/soc/msm/msm8x10.c
+++ b/sound/soc/msm/msm8x10.c
@@ -28,6 +28,13 @@
 #include <qdsp6v2/msm-pcm-routing-v2.h>
 #include <linux/module.h>
 #define DRV_NAME "msm8x10-asoc-wcd"
+#define BTSCO_RATE_8KHZ 8000
+#define BTSCO_RATE_16KHZ 16000
+
+static int msm_btsco_rate = BTSCO_RATE_8KHZ;
+static int msm_btsco_ch = 1;
+
+static int msm_proxy_rx_ch = 2;
 
 static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 				struct snd_pcm_hw_params *params)
@@ -41,9 +48,24 @@
 	return 0;
 }
 
+static int msm_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+					struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_RATE);
+
+	struct snd_interval *channels = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_CHANNELS);
+
+	rate->min = rate->max = msm_btsco_rate;
+	channels->min = channels->max = msm_btsco_ch;
+
+	return 0;
+}
+
 static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
 {
-	pr_info("%s(), dev_name%s\n", __func__, dev_name(rtd->cpu_dai->dev));
+	pr_debug("%s(), dev_name%s\n", __func__, dev_name(rtd->cpu_dai->dev));
 	return 0;
 }
 
@@ -69,6 +91,34 @@
 		 substream->name, substream->stream);
 }
 
+
+static int msm_proxy_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+					struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_RATE);
+
+	struct snd_interval *channels = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_CHANNELS);
+
+	pr_debug("%s: msm_proxy_rx_ch =%d\n", __func__, msm_proxy_rx_ch);
+
+	if (channels->max < 2)
+		channels->min = channels->max = 2;
+	channels->min = channels->max = msm_proxy_rx_ch;
+	rate->min = rate->max = 48000;
+	return 0;
+}
+
+static int msm_proxy_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+					struct snd_pcm_hw_params *params)
+{
+	struct snd_interval *rate = hw_param_interval(params,
+					SNDRV_PCM_HW_PARAM_RATE);
+
+	rate->min = rate->max = 48000;
+	return 0;
+}
 static struct snd_soc_ops msm8x10_be_ops = {
 	.startup = msm_snd_startup,
 	.hw_params = msm_snd_hw_params,
@@ -78,11 +128,11 @@
 /* Digital audio interface glue - connects codec <---> CPU */
 static struct snd_soc_dai_link msm8x10_dai[] = {
 	/* FrontEnd DAI Links */
-	{
+	{/* hw:x,0 */
 		.name = "MSM8X10 Media1",
 		.stream_name = "MultiMedia1",
 		.cpu_dai_name	= "MultiMedia1",
-		.platform_name  = "msm-pcm-dsp",
+		.platform_name  = "msm-pcm-dsp.0",
 		.dynamic = 1,
 		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
 			SND_SOC_DPCM_TRIGGER_POST},
@@ -93,11 +143,11 @@
 		.ignore_pmdown_time = 1,
 		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA1
 	},
-	{
+	{/* hw:x,1 */
 		.name = "MSM8X10 Media2",
 		.stream_name = "MultiMedia2",
 		.cpu_dai_name   = "MultiMedia2",
-		.platform_name  = "msm-pcm-dsp",
+		.platform_name  = "msm-pcm-dsp.0",
 		.dynamic = 1,
 		.codec_dai_name = "snd-soc-dummy-dai",
 		.codec_name = "snd-soc-dummy",
@@ -108,31 +158,308 @@
 		.ignore_pmdown_time = 1,
 		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA2,
 	},
+	{/* hw:x,2 */
+		.name = "Circuit-Switch Voice",
+		.stream_name = "CS-Voice",
+		.cpu_dai_name   = "CS-VOICE",
+		.platform_name  = "msm-pcm-voice",
+		.dynamic = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST},
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.be_id = MSM_FRONTEND_DAI_CS_VOICE,
+	},
+	{/* hw:x,3 */
+		.name = "MSM VoIP",
+		.stream_name = "VoIP",
+		.cpu_dai_name	= "VoIP",
+		.platform_name  = "msm-voip-dsp",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST},
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.ignore_suspend = 1,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.be_id = MSM_FRONTEND_DAI_VOIP,
+	},
+	{/* hw:x,4 */
+		.name = "MSM8X10 LPA",
+		.stream_name = "LPA",
+		.cpu_dai_name	= "MultiMedia3",
+		.platform_name  = "msm-pcm-lpa",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST},
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.ignore_suspend = 1,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA3,
+	},
+	/* Hostless PCM purpose */
+	{/* hw:x,5 */
+		.name = "Secondary MI2S RX Hostless",
+		.stream_name = "Secondary MI2S_RX Hostless Playback",
+		.cpu_dai_name = "SEC_MI2S_RX_HOSTLESS",
+		.platform_name	= "msm-pcm-hostless",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			    SND_SOC_DPCM_TRIGGER_POST},
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		 /* This dainlink has MI2S support */
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+	{/* hw:x,6 */
+		.name = "INT_FM Hostless",
+		.stream_name = "INT_FM Hostless",
+		.cpu_dai_name	= "INT_FM_HOSTLESS",
+		.platform_name  = "msm-pcm-hostless",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST},
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+	{/* hw:x,7 */
+		.name = "MSM AFE-PCM RX",
+		.stream_name = "AFE-PROXY RX",
+		.cpu_dai_name = "msm-dai-q6-dev.241",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-rx",
+		.platform_name  = "msm-pcm-afe",
+		.ignore_suspend = 1,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+	},
+	{/* hw:x,8 */
+		.name = "MSM AFE-PCM TX",
+		.stream_name = "AFE-PROXY TX",
+		.cpu_dai_name = "msm-dai-q6-dev.240",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-tx",
+		.platform_name  = "msm-pcm-afe",
+		.ignore_suspend = 1,
+	},
+	{/* hw:x,9 */
+		.name = "MSM8X10 Compr",
+		.stream_name = "COMPR",
+		.cpu_dai_name	= "MultiMedia4",
+		.platform_name  = "msm-compr-dsp",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			 SND_SOC_DPCM_TRIGGER_POST},
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		 /* this dainlink has playback support */
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA4,
+	},
+	{/* hw:x,10 */
+		.name = "AUXPCM Hostless",
+		.stream_name = "AUXPCM Hostless",
+		.cpu_dai_name   = "AUXPCM_HOSTLESS",
+		.platform_name  = "msm-pcm-hostless",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST},
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+	{/* hw:x,11 */
+		.name = "Primary MI2S TX Hostless",
+		.stream_name = "Primary MI2S_TX Hostless Capture",
+		.cpu_dai_name = "PRI_MI2S_TX_HOSTLESS",
+		.platform_name  = "msm-pcm-hostless",
+		.dynamic = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			    SND_SOC_DPCM_TRIGGER_POST},
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		 /* This dainlink has MI2S support */
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+	{/* hw:x,12 */
+		.name = "MSM8x10 LowLatency",
+		.stream_name = "MultiMedia5",
+		.cpu_dai_name   = "MultiMedia5",
+		.platform_name  = "msm-pcm-dsp.1",
+		.dynamic = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+				SND_SOC_DPCM_TRIGGER_POST},
+		.ignore_suspend = 1,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.be_id = MSM_FRONTEND_DAI_MULTIMEDIA5,
+	},
 	/* Backend I2S DAI Links */
 	{
-		.name = LPASS_BE_MI2S_RX,
-		.stream_name = "Primary MI2S Playback",
-		.cpu_dai_name = "msm-dai-q6-mi2s.0",
+		.name = LPASS_BE_SEC_MI2S_RX,
+		.stream_name = "Secondary MI2S Playback",
+		.cpu_dai_name = "msm-dai-q6-mi2s.1",
 		.platform_name = "msm-pcm-routing",
-		.codec_name     = "msm8x10-wcd-i2c-core.1-000d",
+		.codec_name     = "msm8x10-wcd-i2c-core.5-000d",
 		.codec_dai_name = "msm8x10_wcd_i2s_rx1",
 		.no_pcm = 1,
-		.be_id = MSM_BACKEND_DAI_MI2S_RX,
+		.be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
 		.init = &msm_audrx_init,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
 		.ops = &msm8x10_be_ops,
+		.ignore_suspend = 1,
 	},
 	{
-		.name = LPASS_BE_SEC_MI2S_TX,
-		.stream_name = "Secondary MI2S Capture",
-		.cpu_dai_name = "msm-dai-q6-mi2s.1",
+		.name = LPASS_BE_PRI_MI2S_TX,
+		.stream_name = "Primary MI2S Capture",
+		.cpu_dai_name = "msm-dai-q6-mi2s.0",
 		.platform_name = "msm-pcm-routing",
-		.codec_name     = "msm8x10-wcd-i2c-core.1-000d",
+		.codec_name     = "msm8x10-wcd-i2c-core.5-000d",
 		.codec_dai_name = "msm8x10_wcd_i2s_tx1",
 		.no_pcm = 1,
-		.be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
+		.be_id = MSM_BACKEND_DAI_PRI_MI2S_TX,
+		.init = &msm_audrx_init,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
 		.ops = &msm8x10_be_ops,
+		.ignore_suspend = 1,
+	},
+	{
+		.name = LPASS_BE_INT_BT_SCO_RX,
+		.stream_name = "Internal BT-SCO Playback",
+		.cpu_dai_name = "msm-dai-q6-dev.12288",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name	= "msm-stub-rx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_INT_BT_SCO_RX,
+		.be_hw_params_fixup = msm_btsco_be_hw_params_fixup,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.ignore_suspend = 1,
+	},
+	{
+		.name = LPASS_BE_INT_BT_SCO_TX,
+		.stream_name = "Internal BT-SCO Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.12289",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name	= "msm-stub-tx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_INT_BT_SCO_TX,
+		.be_hw_params_fixup = msm_btsco_be_hw_params_fixup,
+		.ignore_suspend = 1,
+	},
+	{
+		.name = LPASS_BE_INT_FM_RX,
+		.stream_name = "Internal FM Playback",
+		.cpu_dai_name = "msm-dai-q6-dev.12292",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-rx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_INT_FM_RX,
+		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.ignore_suspend = 1,
+	},
+	{
+		.name = LPASS_BE_INT_FM_TX,
+		.stream_name = "Internal FM Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.12293",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-tx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_INT_FM_TX,
+		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ignore_suspend = 1,
+	},
+	{
+		.name = LPASS_BE_AFE_PCM_RX,
+		.stream_name = "AFE Playback",
+		.cpu_dai_name = "msm-dai-q6-dev.224",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-rx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_AFE_PCM_RX,
+		.be_hw_params_fixup = msm_proxy_rx_be_hw_params_fixup,
+		/* this dainlink has playback support */
+		.ignore_pmdown_time = 1,
+		.ignore_suspend = 1,
+	},
+	{
+		.name = LPASS_BE_AFE_PCM_TX,
+		.stream_name = "AFE Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.225",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-tx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_AFE_PCM_TX,
+		.be_hw_params_fixup = msm_proxy_tx_be_hw_params_fixup,
+		.ignore_suspend = 1,
+	},
+	/* Incall Record Uplink BACK END DAI Link */
+	{
+		.name = LPASS_BE_INCALL_RECORD_TX,
+		.stream_name = "Voice Uplink Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.32772",
+		.platform_name = "msm-pcm-routing",
+		.codec_name     = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-tx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_INCALL_RECORD_TX,
+		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ignore_suspend = 1,
+	},
+	/* Incall Record Downlink BACK END DAI Link */
+	{
+		.name = LPASS_BE_INCALL_RECORD_RX,
+		.stream_name = "Voice Downlink Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.32771",
+		.platform_name = "msm-pcm-routing",
+		.codec_name     = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-tx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_INCALL_RECORD_RX,
+		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ignore_suspend = 1,
+	},
+	/* Incall Music BACK END DAI Link */
+	{
+		.name = LPASS_BE_VOICE_PLAYBACK_TX,
+		.stream_name = "Voice Farend Playback",
+		.cpu_dai_name = "msm-dai-q6-dev.32773",
+		.platform_name = "msm-pcm-routing",
+		.codec_name     = "msm-stub-codec.1",
+		.codec_dai_name = "msm-stub-rx",
+		.no_pcm = 1,
+		.be_id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
+		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ignore_suspend = 1,
 	},
 };
 
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index 717e63b..9fbf749 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -420,6 +420,12 @@
 	}
 
 	data = q6asm_is_cpu_buf_avail(IN, prtd->audio_client, &size, &idx);
+	if (size < fbytes) {
+		pr_err("%s: size mismatch error size %d fbytes %d\n",
+		__func__ , size , fbytes);
+		ret = -EFAULT;
+		goto fail;
+	}
 	bufptr = data;
 	if (bufptr) {
 		pr_debug("%s:fbytes =%d: xfer=%d size=%d\n",
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index e7c4a8a..85dc219 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -1423,6 +1423,15 @@
 	msm_routing_put_audio_mixer),
 };
 
+static const struct snd_kcontrol_new mi2s_hl_mixer_controls[] = {
+	SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+	MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer,
+	msm_routing_put_port_mixer),
+	SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+	MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer,
+	msm_routing_put_port_mixer),
+};
+
 static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = {
 	SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_MI2S_RX ,
 	MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -2516,12 +2525,19 @@
 	SND_SOC_DAPM_AIF_IN("HDMI_DL_HL", "HDMI_HOSTLESS Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("SEC_I2S_DL_HL", "SEC_I2S_RX_HOSTLESS Playback",
 		0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_IN("SEC_MI2S_DL_HL",
+		"Secondary MI2S_RX Hostless Playback",
+		0, 0, 0, 0),
+
 	SND_SOC_DAPM_AIF_IN("AUXPCM_DL_HL", "AUXPCM_HOSTLESS Playback",
 		0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("AUXPCM_UL_HL", "AUXPCM_HOSTLESS Capture",
 		0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("MI2S_UL_HL", "MI2S_TX_HOSTLESS Capture",
 		0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("PRI_MI2S_UL_HL",
+		"Primary MI2S_TX Hostless Capture",
+		0, 0, 0, 0),
 
 	SND_SOC_DAPM_AIF_OUT("MI2S_DL_HL", "MI2S_RX_HOSTLESS Playback",
 		0, 0, 0, 0),
@@ -2549,6 +2565,8 @@
 	SND_SOC_DAPM_AIF_IN("MI2S_TX", "MI2S Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX", "Quaternary MI2S Capture",
 						0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_IN("PRI_MI2S_TX", "Primary MI2S Capture",
+			    0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX", "Secondary MI2S Capture",
 			    0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0),
@@ -2627,6 +2645,9 @@
 	SND_SOC_DAPM_MIXER("SEC_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
 			   secondary_mi2s_rx_mixer_controls,
 			   ARRAY_SIZE(secondary_mi2s_rx_mixer_controls)),
+	SND_SOC_DAPM_MIXER("SEC_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0,
+			   mi2s_hl_mixer_controls,
+			   ARRAY_SIZE(mi2s_hl_mixer_controls)),
 	SND_SOC_DAPM_MIXER("PRI_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
 			   primary_mi2s_rx_mixer_controls,
 			   ARRAY_SIZE(primary_mi2s_rx_mixer_controls)),
@@ -2814,6 +2835,9 @@
 	{"SEC_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
 	{"SEC_MI2S_RX", NULL, "SEC_MI2S_RX Audio Mixer"},
 
+	{"SEC_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+	{"SEC_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
+
 	{"PRI_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"PRI_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"PRI_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
@@ -3014,6 +3038,9 @@
 	{"PCM_RX", NULL, "PCM_RX_DL_HL"},
 	{"MI2S_UL_HL", NULL, "MI2S_TX"},
 	{"SEC_I2S_RX", NULL, "SEC_I2S_DL_HL"},
+	{"PRI_MI2S_UL_HL", NULL, "PRI_MI2S_TX"},
+	{"SEC_MI2S_RX", NULL, "SEC_MI2S_DL_HL"},
+
 	{"SLIMBUS_0_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
 	{"SLIMBUS_0_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
 	{"SLIMBUS_0_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},