Merge "ARM: dts: msm: Add UART support for sdxpoorwills"
diff --git a/Documentation/devicetree/bindings/usb/msm-phy.txt b/Documentation/devicetree/bindings/usb/msm-phy.txt
index 9ee2cc6..6716785 100644
--- a/Documentation/devicetree/bindings/usb/msm-phy.txt
+++ b/Documentation/devicetree/bindings/usb/msm-phy.txt
@@ -176,6 +176,8 @@
  - qcom,hold-reset: Indicates that hold QUSB PHY into reset state.
  - qcom,phy-clk-scheme: Should be one of "cml" or "cmos" if ref_clk_addr is provided.
  - qcom,major-rev: provide major revision number to differentiate power up sequence. default is 2.0
+ - pinctrl-names/pinctrl-0/1: The GPIOs configured as output function. Names represents "active"
+   state when attached in host mode and "suspend" state when detached.
 
 Example:
 	qusb_phy: qusb@f9b39000 {
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi
index 908c388..7819d26 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi
@@ -59,7 +59,7 @@
 		bcm_ip0: bcm-ip0 {
 			cell-id = <MSM_BUS_BCM_IP0>;
 			label = "IP0";
-			qcom,bcm-name = "CE";
+			qcom,bcm-name = "IP0";
 			qcom,rscs = <&rsc_apps>;
 			qcom,bcm-dev;
 		};
@@ -261,7 +261,7 @@
 		mas_llcc_mc: mas-llcc-mc {
 			cell-id = <MSM_BUS_MASTER_LLCC>;
 			label = "mas-llcc-mc";
-			qcom,buswidth = <16>;
+			qcom,buswidth = <4>;
 			qcom,agg-ports = <1>;
 			qcom,connections = <&slv_ebi>;
 			qcom,bus-dev = <&fab_mc_virt>;
@@ -573,7 +573,7 @@
 		slv_ebi:slv-ebi {
 			cell-id = <MSM_BUS_SLAVE_EBI_CH0>;
 			label = "slv-ebi";
-			qcom,buswidth = <16>;
+			qcom,buswidth = <4>;
 			qcom,agg-ports = <1>;
 			qcom,bus-dev = <&fab_mc_virt>;
 			qcom,bcms = <&bcm_mc0>;
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dts
index e45f523..30484fb 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dts
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dts
@@ -20,7 +20,7 @@
 	model = "Qualcomm Technologies, Inc. SDXPOORWILLS CDP";
 	compatible = "qcom,sdxpoorwills-cdp",
 		"qcom,sdxpoorwills", "qcom,cdp";
-	qcom,board-id = <1 0x0>, <1 0x100>;
+	qcom,board-id = <1 0x0>, <1 0x100>, <1 0x2>, <1 0x102>;
 };
 
 &serial_uart {
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts
index 083ccf8..73adbdc 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts
@@ -20,7 +20,7 @@
 	model = "Qualcomm Technologies, Inc. SDXPOORWILLS MTP";
 	compatible = "qcom,sdxpoorwills-mtp",
 		"qcom,sdxpoorwills", "qcom,mtp";
-	qcom,board-id = <8 0x0>, <8 0x100>;
+	qcom,board-id = <8 0x0>, <8 0x100>, <8 0x2>, <8 0x102>;
 };
 
 &serial_uart {
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index a000878..ce38838 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -523,6 +523,7 @@
 		qcom,ipa-hw-mode = <0>;
 		qcom,ee = <0>;
 		qcom,use-ipa-tethering-bridge;
+		qcom,mhi-event-ring-id-limits = <9 10>; /* start and end */
 		qcom,modem-cfg-emb-pipe-flt;
 		qcom,use-ipa-pm;
 		qcom,bandwidth-vote-for-ipa;
@@ -694,7 +695,7 @@
 		reg = <0xc300000 0x400>,
 			<0x17811008 0x4>;
 		reg-names = "msgram", "irq-reg-base";
-		qcom,irq-mask = <0x1>;
+		qcom,irq-mask = <0x2>;
 		interrupts = <GIC_SPI 221 IRQ_TYPE_EDGE_RISING>;
 		priority = <0>;
 		mbox-desc-offset = <0x0>;
diff --git a/arch/arm64/boot/dts/qcom/batterydata-ascent-3450mAh.dtsi b/arch/arm64/boot/dts/qcom/batterydata-ascent-3450mAh.dtsi
new file mode 100644
index 0000000..3eed42a
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/batterydata-ascent-3450mAh.dtsi
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015, 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,ascent-3450mah {
+	/* #Ascent_860_82209_0000_3450mAh_averaged_MasterSlave_Sept28th2015*/
+	qcom,max-voltage-uv = <4350000>;
+	qcom,nom-batt-capacity-mah = <3450>;
+	qcom,batt-id-kohm = <60>;
+	qcom,battery-beta = <3435>;
+	qcom,battery-type = "ascent_3450mah";
+	qcom,chg-rslow-comp-c1 = <6834679>;
+	qcom,chg-rslow-comp-c2 = <20647220>;
+	qcom,chg-rs-to-rslow = <915002>;
+	qcom,chg-rslow-comp-thr = <0xD5>;
+	qcom,checksum = <0xE50C>;
+	qcom,fg-profile-data = [
+		 C5 83 25 77
+		 AB 7B CA 74
+		 4C 83 7F 5B
+		 EB 80 ED 8C
+		 EA 81 61 9B
+		 A6 BE 2B D0
+		 55 0E D6 83
+		 09 77 25 7B
+		 03 74 49 83
+		 CC 70 0C 70
+		 0C 85 67 82
+		 E6 93 27 B5
+		 61 C0 58 10
+		 23 0D 50 59
+		 CE 6E 71 FD
+		 CD 15 CC 3F
+		 1D 36 00 00
+		 B9 47 29 3B
+		 1D 2E 00 00
+		 00 00 00 00
+		 00 00 00 00
+		 D8 6A E7 69
+		 B3 7C 4E 7A
+		 7E 77 77 70
+		 40 77 0D 73
+		 22 76 96 6A
+		 71 65 20 B0
+		 2C 97 63 12
+		 64 A0 71 0C
+		 28 00 FF 36
+		 F0 11 30 03
+		 00 00 00 0C
+	];
+};
diff --git a/arch/arm64/boot/dts/qcom/batterydata-itech-3000mah.dtsi b/arch/arm64/boot/dts/qcom/batterydata-itech-3000mah.dtsi
new file mode 100644
index 0000000..24b4626
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/batterydata-itech-3000mah.dtsi
@@ -0,0 +1,61 @@
+/* Copyright (c) 2014-2015, 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,itech-3000mah {
+	/* #Itech_B00826LF_3000mAh_Feb24th_Averaged*/
+	qcom,max-voltage-uv = <4350000>;
+	qcom,v-cutoff-uv = <3400000>;
+	qcom,chg-term-ua = <100000>;
+	qcom,batt-id-kohm = <100>;
+	qcom,battery-type = "itech_3000mah";
+	qcom,chg-rslow-comp-c1 = <4365000>;
+	qcom,chg-rslow-comp-c2 = <8609000>;
+	qcom,chg-rslow-comp-thr = <0xBE>;
+	qcom,chg-rs-to-rslow = <761000>;
+	qcom,fastchg-current-ma = <2000>;
+	qcom,fg-cc-cv-threshold-mv = <4340>;
+	qcom,checksum = <0x0B7C>;
+	qcom,fg-profile-data = [
+		F0 83 6B 7D
+		66 81 EC 77
+		43 83 E3 5A
+		7C 81 33 8D
+		E1 81 EC 98
+		7B B5 F8 BB
+		5B 12 E2 83
+		4A 7C 63 80
+		CF 75 50 83
+		FD 5A 83 82
+		E6 8E 12 82
+		B6 9A 1A BE
+		BE CB 55 0E
+		96 0B E0 5A
+		CE 6E 71 FD
+		2A 31 7E 47
+		CF 40 00 00
+		DB 45 0F 32
+		AF 31 00 00
+		00 00 00 00
+		00 00 00 00
+		E3 6A 60 69
+		9E 6D 47 83
+		13 7C 23 70
+		0B 74 8F 80
+		DB 75 17 68
+		BA 75 BF B3
+		21 5B 69 B5
+		6C A0 71 0C
+		28 00 FF 36
+		F0 11 30 03
+		00 00 00 0E
+	];
+};
diff --git a/arch/arm64/boot/dts/qcom/batterydata-qrd-sku1-4v4-2800mah.dtsi b/arch/arm64/boot/dts/qcom/batterydata-qrd-sku1-4v4-2800mah.dtsi
new file mode 100644
index 0000000..da52039
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/batterydata-qrd-sku1-4v4-2800mah.dtsi
@@ -0,0 +1,62 @@
+/* Copyright (c) 2015-2016, 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,qrd_msm8937_sku1_2920mah {
+	/* #QRD8937_2800mAh_China_data_averaged_MasterSlave_Oct30th2015*/
+	qcom,max-voltage-uv = <4400000>;
+	qcom,nom-batt-capacity-mah = <2800>;
+	qcom,batt-id-kohm = <90>;
+	qcom,battery-beta = <3380>;
+	qcom,battery-type = "qrd_msm8937_sku1_2800mah";
+	qcom,fastchg-current-ma = <2600>;
+	qcom,fg-cc-cv-threshold-mv = <4390>;
+	qcom,chg-rslow-comp-c1 = <6733839>;
+	qcom,chg-rslow-comp-c2 = <23336040>;
+	qcom,chg-rs-to-rslow = <1049243>;
+	qcom,chg-rslow-comp-thr = <0xDB>;
+	qcom,checksum = <0x7E2A>;
+	qcom,gui-version = "PMI8950GUI - 2.0.0.14";
+	qcom,fg-profile-data = [
+		C6 83 8A 77
+		3E 80 84 75
+		72 83 A1 7C
+		A0 90 FC 97
+		3F 82 09 99
+		92 B7 97 C3
+		4C 14 EB 83
+		A7 7C CE 80
+		79 76 60 83
+		3B 64 34 88
+		19 94 49 82
+		07 9A 7F BD
+		BF CA 53 0D
+		32 0B 68 59
+		14 70 71 FD
+		8C 28 9C 45
+		3F 21 00 00
+		B6 47 FE 30
+		0B 40 00 00
+		00 00 00 00
+		00 00 00 00
+		3A 70 78 6B
+		F7 77 7F 88
+		32 7C F2 70
+		64 75 0B 79
+		2B 77 F3 6B
+		CA 70 7D B1
+		21 57 6B 6B
+		6D A0 71 0C
+		28 00 FF 36
+		F0 11 30 03
+		00 00 00 0C
+	];
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-cpu.dtsi b/arch/arm64/boot/dts/qcom/msm8953-cpu.dtsi
index 1b78fdd..8d80a40 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-cpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-cpu.dtsi
@@ -58,6 +58,7 @@
 			reg = <0x0>;
 			enable-method = "psci";
 			efficiency = <1024>;
+			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
 			next-level-cache = <&L2_0>;
 			L2_0: l2-cache {
 			      compatible = "arm,arch-cache";
@@ -81,6 +82,7 @@
 			enable-method = "psci";
 			reg = <0x1>;
 			efficiency = <1024>;
+			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
 			next-level-cache = <&L2_0>;
 			L1_I_1: l1-icache {
 			      compatible = "arm,arch-cache";
@@ -98,6 +100,7 @@
 			enable-method = "psci";
 			reg = <0x2>;
 			efficiency = <1024>;
+			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
 			next-level-cache = <&L2_0>;
 			L1_I_2: l1-icache {
 			      compatible = "arm,arch-cache";
@@ -115,6 +118,7 @@
 			enable-method = "psci";
 			reg = <0x3>;
 			efficiency = <1024>;
+			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
 			next-level-cache = <&L2_0>;
 			L1_I_3: l1-icache {
 			      compatible = "arm,arch-cache";
@@ -132,6 +136,7 @@
 			enable-method = "psci";
 			reg = <0x100>;
 			efficiency = <1126>;
+			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
 			next-level-cache = <&L2_1>;
 			L2_1: l2-cache {
 			      compatible = "arm,arch-cache";
@@ -155,6 +160,7 @@
 			enable-method = "psci";
 			reg = <0x101>;
 			efficiency = <1126>;
+			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
 			next-level-cache = <&L2_1>;
 			L1_I_101: l1-icache {
 			      compatible = "arm,arch-cache";
@@ -172,6 +178,7 @@
 			enable-method = "psci";
 			reg = <0x102>;
 			efficiency = <1126>;
+			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
 			next-level-cache = <&L2_1>;
 			L1_I_102: l1-icache {
 			      compatible = "arm,arch-cache";
@@ -189,6 +196,7 @@
 			enable-method = "psci";
 			reg = <0x103>;
 			efficiency = <1126>;
+			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
 			next-level-cache = <&L2_1>;
 			L1_I_103: l1-icache {
 			      compatible = "arm,arch-cache";
@@ -200,6 +208,77 @@
 			};
 		};
 	};
+
+	energy_costs: energy-costs {
+		compatible = "sched-energy";
+
+		CPU_COST_0: core-cost0 {
+			busy-cost-data = <
+				 652800   5
+				 883200   8
+				1036800  10
+				1248000  13
+				1401600  16
+				1536000  19
+				1689600  22
+				1804800  26
+				1843200  27
+				1958400  33
+				2016000  36
+				2150400  43
+				2208000  44
+				2304000  54
+				2400000  65
+			>;
+			idle-cost-data = <
+				4 3 2 1
+			>;
+		};
+		CLUSTER_COST_0: cluster-cost0 {
+			busy-cost-data = <
+				 652800   69
+				 883200   72
+				1036800   74
+				1248000   77
+				1401600   80
+				1536000   90
+				1689600  100
+				1804800  110
+				1843200  120
+				1958400  130
+				2016000  140
+				2150400  150
+				2208000  160
+				2304000  170
+				2400000  180
+			>;
+			idle-cost-data = <
+				4 3 2 1
+			>;
+		};
+		CLUSTER_COST_1: cluster-cost1 {
+			busy-cost-data = <
+				 652800    5
+				 883200    8
+				1036800   10
+				1248000   13
+				1401600   16
+				1536000   85
+				1689600   95
+				1804800  105
+				1843200  115
+				1958400  125
+				2016000  135
+				2150400  145
+				2208000  155
+				2304000  165
+				2400000  175
+			>;
+			idle-cost-data = <
+				4 3 2 1
+			>;
+		};
+	};
 };
 
 &soc {
diff --git a/arch/arm64/boot/dts/qcom/msm8953-mtp.dts b/arch/arm64/boot/dts/qcom/msm8953-mtp.dts
index 1e8b0f0..12b039c 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/msm8953-mtp.dts
@@ -14,7 +14,9 @@
 /dts-v1/;
 
 #include "msm8953.dtsi"
+#include "pmi8950.dtsi"
 #include "msm8953-mtp.dtsi"
+#include "msm8953-pmi8950.dtsi"
 
 / {
 	model = "Qualcomm Technologies, Inc. MSM8953 + PMI8950 MTP";
@@ -22,3 +24,21 @@
 	qcom,board-id= <8 0>;
 	qcom,pmic-id = <0x010016 0x010011 0x0 0x0>;
 };
+
+/{
+	mtp_batterydata: qcom,battery-data {
+		qcom,batt-id-range-pct = <15>;
+		#include "batterydata-itech-3000mah.dtsi"
+		#include "batterydata-ascent-3450mAh.dtsi"
+	};
+};
+
+&pmi8950_fg {
+	qcom,battery-data = <&mtp_batterydata>;
+};
+
+&pmi8950_charger {
+	qcom,battery-data = <&mtp_batterydata>;
+	qcom,chg-led-sw-controls;
+	qcom,chg-led-support;
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-pmi8950.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pmi8950.dtsi
new file mode 100644
index 0000000..6270223
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8953-pmi8950.dtsi
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+&soc {
+	led_flash0: qcom,camera-flash {
+		cell-index = <0>;
+		compatible = "qcom,camera-flash";
+		qcom,flash-type = <1>;
+		qcom,flash-source = <&pmi8950_flash0 &pmi8950_flash1>;
+		qcom,torch-source = <&pmi8950_torch0 &pmi8950_torch1>;
+		qcom,switch-source = <&pmi8950_switch>;
+	};
+};
+
+&labibb {
+	status = "ok";
+	qpnp,qpnp-labibb-mode = "lcd";
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-regulator.dtsi b/arch/arm64/boot/dts/qcom/msm8953-regulator.dtsi
new file mode 100644
index 0000000..e4634c4
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8953-regulator.dtsi
@@ -0,0 +1,928 @@
+/*
+ * Copyright (c) 2015-2017, 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.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+&rpm_bus {
+	rpm-regulator-smpa1 {
+		status = "okay";
+		pm8953_s1: regulator-s1 {
+			regulator-min-microvolt = <870000>;
+			regulator-max-microvolt = <1156000>;
+			qcom,init-voltage = <1000000>;
+			status = "okay";
+		};
+	};
+
+	/* PM8953 S2 - VDD_CX supply */
+	rpm-regulator-smpa2 {
+		status = "okay";
+		pm8953_s2_level: regulator-s2-level {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_s2_level";
+			qcom,set = <3>;
+			regulator-min-microvolt =
+					<RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+			regulator-max-microvolt =
+					<RPM_SMD_REGULATOR_LEVEL_TURBO>;
+			qcom,use-voltage-level;
+		};
+
+		pm8953_s2_floor_level: regulator-s2-floor-level {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_s2_floor_level";
+			qcom,set = <3>;
+			regulator-min-microvolt =
+					<RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+			regulator-max-microvolt =
+					<RPM_SMD_REGULATOR_LEVEL_TURBO>;
+			qcom,use-voltage-floor-level;
+			qcom,always-send-voltage;
+		};
+
+		pm8953_s2_level_ao: regulator-s2-level-ao {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_s2_level_ao";
+			qcom,set = <1>;
+			regulator-min-microvolt =
+					<RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+			regulator-max-microvolt =
+					<RPM_SMD_REGULATOR_LEVEL_TURBO>;
+			qcom,use-voltage-level;
+		};
+	};
+
+	rpm-regulator-smpa3 {
+		status = "okay";
+		pm8953_s3: regulator-s3 {
+			regulator-min-microvolt = <1225000>;
+			regulator-max-microvolt = <1225000>;
+			qcom,init-voltage = <1225000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-smpa4 {
+		status = "okay";
+		pm8953_s4: regulator-s4 {
+			regulator-min-microvolt = <1900000>;
+			regulator-max-microvolt = <2050000>;
+			qcom,init-voltage = <1900000>;
+			status = "okay";
+		};
+	};
+
+	/* VDD_MX supply */
+	rpm-regulator-smpa7 {
+		status = "okay";
+		pm8953_s7_level: regulator-s7-level {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_s7_level";
+			qcom,set = <3>;
+			regulator-min-microvolt =
+					<RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+			regulator-max-microvolt =
+					<RPM_SMD_REGULATOR_LEVEL_TURBO>;
+			qcom,init-voltage-level =
+					<RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+			qcom,use-voltage-level;
+			qcom,always-send-voltage;
+		};
+
+		pm8953_s7_level_ao: regulator-s7-level-ao {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_s7_level_ao";
+			qcom,set = <1>;
+			regulator-min-microvolt =
+					<RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+			regulator-max-microvolt =
+					<RPM_SMD_REGULATOR_LEVEL_TURBO>;
+			qcom,use-voltage-level;
+			qcom,always-send-voltage;
+		};
+
+		pm8953_s7_level_so: regulator-s7-level-so {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_s7_level_so";
+			qcom,set = <2>;
+			regulator-min-microvolt =
+					<RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+			regulator-max-microvolt =
+					<RPM_SMD_REGULATOR_LEVEL_TURBO>;
+			qcom,init-voltage-level =
+					<RPM_SMD_REGULATOR_LEVEL_RETENTION>;
+			qcom,use-voltage-level;
+		};
+	};
+
+	rpm-regulator-ldoa1 {
+		status = "okay";
+		pm8953_l1: regulator-l1 {
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1100000>;
+			qcom,init-voltage = <1000000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa2 {
+		status = "okay";
+		pm8953_l2: regulator-l2 {
+			regulator-min-microvolt = <975000>;
+			regulator-max-microvolt = <1225000>;
+			qcom,init-voltage = <975000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa3 {
+		status = "okay";
+		pm8953_l3: regulator-l3 {
+			regulator-min-microvolt = <925000>;
+			regulator-max-microvolt = <925000>;
+			qcom,init-voltage = <925000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa5 {
+		status = "okay";
+		pm8953_l5: regulator-l5 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,init-voltage = <1800000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa6 {
+		status = "okay";
+		pm8953_l6: regulator-l6 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,init-voltage = <1800000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa7 {
+		status = "okay";
+		pm8953_l7: regulator-l7 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1900000>;
+			qcom,init-voltage = <1800000>;
+			status = "okay";
+		};
+
+		pm8953_l7_ao: regulator-l7-ao {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l7_ao";
+			qcom,set = <1>;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1900000>;
+			qcom,init-voltage = <1800000>;
+		};
+	};
+
+	rpm-regulator-ldoa8 {
+		status = "okay";
+		pm8953_l8: regulator-l8 {
+			regulator-min-microvolt = <2900000>;
+			regulator-max-microvolt = <2900000>;
+			qcom,init-voltage = <2900000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa9 {
+		status = "okay";
+		pm8953_l9: regulator-l9 {
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3300000>;
+			qcom,init-voltage = <3000000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa10 {
+		status = "okay";
+		pm8953_l10: regulator-l10 {
+			regulator-min-microvolt = <2850000>;
+			regulator-max-microvolt = <2850000>;
+			qcom,init-voltage = <2850000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa11 {
+		status = "okay";
+		pm8953_l11: regulator-l11 {
+			regulator-min-microvolt = <2950000>;
+			regulator-max-microvolt = <2950000>;
+			qcom,init-voltage = <2950000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa12 {
+		status = "okay";
+		pm8953_l12: regulator-l12 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2950000>;
+			qcom,init-voltage = <1800000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa13 {
+		status = "okay";
+		pm8953_l13: regulator-l13 {
+			regulator-min-microvolt = <3125000>;
+			regulator-max-microvolt = <3125000>;
+			qcom,init-voltage = <3125000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa16 {
+		status = "okay";
+		pm8953_l16: regulator-l16 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,init-voltage = <1800000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa17 {
+		status = "okay";
+		pm8953_l17: regulator-l17 {
+			regulator-min-microvolt = <2850000>;
+			regulator-max-microvolt = <2850000>;
+			qcom,init-voltage = <2850000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa19 {
+		status = "okay";
+		pm8953_l19: regulator-l19 {
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1350000>;
+			qcom,init-voltage = <1200000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa22 {
+		status = "okay";
+		pm8953_l22: regulator-l22 {
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2850000>;
+			qcom,init-voltage = <2800000>;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa23 {
+		status = "okay";
+		pm8953_l23: regulator-l23 {
+			regulator-min-microvolt = <975000>;
+			regulator-max-microvolt = <1225000>;
+			qcom,init-voltage = <975000>;
+			status = "okay";
+		};
+	};
+};
+
+&spmi_bus {
+	qcom,pm8953@1 {
+		/* PM8953 S5 + S6 = VDD_APC supply */
+		pm8953_s5: spm-regulator@2000 {
+			compatible = "qcom,spm-regulator";
+			reg = <0x2000 0x100>;
+			regulator-name = "pm8953_s5";
+			regulator-min-microvolt = <400000>;
+			regulator-max-microvolt = <1140000>;
+
+			pm8953_s5_limit: avs-limit-regulator {
+				regulator-name = "pm8953_s5_avs_limit";
+				regulator-min-microvolt = <400000>;
+				regulator-max-microvolt = <1140000>;
+			};
+		};
+	};
+};
+
+&soc {
+	apc_mem_acc_vreg: regulator@19461d4 {
+		compatible = "qcom,mem-acc-regulator";
+		reg = <0x019461d4 0x4>, <0x019461d8 0x4>;
+		reg-names = "acc-sel-l1", "acc-sel-l2";
+		regulator-name = "apc_mem_acc_corner";
+		regulator-min-microvolt = <1>;
+		regulator-max-microvolt = <2>;
+
+		qcom,corner-acc-map = <0x1 0x0>;
+		qcom,acc-sel-l1-bit-pos = <0>;
+		qcom,acc-sel-l1-bit-size = <1>;
+		qcom,acc-sel-l2-bit-pos = <0>;
+		qcom,acc-sel-l2-bit-size = <1>;
+	};
+
+	apc_cpr: cpr4-ctrl@b018000 {
+		compatible = "qcom,cpr4-msm8953-apss-regulator";
+		reg = <0xb018000 0x4000>, <0xa4000 0x1000>;
+		reg-names = "cpr_ctrl", "fuse_base";
+		interrupts = <GIC_SPI 15 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "cpr";
+
+		qcom,cpr-ctrl-name = "apc";
+
+		qcom,cpr-sensor-time = <1000>;
+		qcom,cpr-loop-time = <5000000>;
+		qcom,cpr-idle-cycles = <15>;
+		qcom,cpr-step-quot-init-min = <12>;
+		qcom,cpr-step-quot-init-max = <14>;
+		qcom,cpr-count-mode = <0>;		/* All-at-once */
+		qcom,cpr-count-repeat = <14>;
+		qcom,cpr-down-error-step-limit = <1>;
+		qcom,cpr-up-error-step-limit = <1>;
+
+		qcom,apm-ctrl = <&apc_apm>;
+		qcom,apm-threshold-voltage = <850000>;
+		qcom,apm-hysteresis-voltage = <5000>;
+
+		vdd-supply = <&pm8953_s5>;
+		qcom,voltage-step = <5000>;
+		vdd-limit-supply = <&pm8953_s5_limit>;
+		mem-acc-supply = <&apc_mem_acc_vreg>;
+
+		qcom,cpr-enable;
+		qcom,cpr-hw-closed-loop;
+
+		qcom,cpr-panic-reg-addr-list =
+			<0xb1d2c18 0xb1d2900 0x0b1112b0 0xb018798>;
+		qcom,cpr-panic-reg-name-list =
+			"CCI_SAW4_PMIC_STS", "CCI_SAW4_VCTL",
+			"APCS_ALIAS0_APM_CTLER_STATUS",
+			"APCS0_CPR_CORE_ADJ_MODE_REG";
+
+		qcom,cpr-temp-point-map = <250 650 850>;
+		qcom,cpr-initial-temp-band = <0>;
+
+		/* Turbo (corner 6) ceiling voltage */
+		qcom,cpr-aging-ref-voltage = <990000>;
+
+		thread@0 {
+			qcom,cpr-thread-id = <0>;
+			qcom,cpr-consecutive-up = <0>;
+			qcom,cpr-consecutive-down = <2>;
+			qcom,cpr-up-threshold = <2>;
+			qcom,cpr-down-threshold = <1>;
+
+			apc_vreg: regulator {
+				regulator-name = "apc_corner";
+				regulator-min-microvolt = <1>;
+				regulator-max-microvolt = <9>;
+
+				qcom,cpr-fuse-corners = <4>;
+				qcom,cpr-fuse-combos = <64>;
+				qcom,cpr-speed-bins = <8>;
+				qcom,cpr-speed-bin-corners =
+					<9 0 7 0 0 0 7 9>;
+				qcom,cpr-corners =
+					/* Speed bin 0 */
+					<9 9 9 9 9 9 9 9>,
+
+					/* Speed bin 1 */
+					<0 0 0 0 0 0 0 0>,
+
+					/* Speed bin 2 */
+					<7 7 7 7 7 7 7 7>,
+
+					/* Speed bin 3..5 */
+					<0 0 0 0 0 0 0 0>,
+					<0 0 0 0 0 0 0 0>,
+					<0 0 0 0 0 0 0 0>,
+
+					/* Speed bin 6 */
+					<7 7 7 7 7 7 7 7>,
+
+					/* Speed bin 7 */
+					<9 9 9 9 9 9 9 9>;
+
+				qcom,cpr-corner-fmax-map =
+					/* Speed bin 0 */
+					<1 2 4 9>,
+
+					/* Speed bin 1 */
+					<0 0 0 0>,
+
+					/* Speed bin 2 */
+					<1 2 4 7>,
+
+					/* Speed bin 3..5 */
+					<0 0 0 0>,
+					<0 0 0 0>,
+					<0 0 0 0>,
+
+					/* Speed bin 6 */
+					<1 2 4 7>,
+
+					/* Speed bin 7 */
+					<1 2 4 9>;
+
+				qcom,cpr-voltage-ceiling =
+					/* Speed bin 0 */
+					<715000  790000 860000 865000 920000
+					 990000 1065000 1065000 1065000>,
+
+					/* Speed bin 2 */
+					<715000  790000 860000 865000 920000
+					 990000 1065000>,
+
+					/* Speed bin 6 */
+					<715000  790000 860000 865000 920000
+					 990000 1065000>,
+
+					/* Speed bin 7 */
+					<715000  790000 860000 865000 920000
+					 990000 1065000 1065000 1065000>;
+
+				qcom,cpr-voltage-floor =
+					/* Speed bin 0 */
+					<500000  500000 500000 500000 500000
+					 500000  500000 500000 500000>,
+
+					/* Speed bin 2 */
+					<500000  500000 500000 500000 500000
+					 500000  500000>,
+
+					/* Speed bin 6 */
+					<500000  500000 500000 500000 500000
+					 500000  500000>,
+
+					/* Speed bin 7 */
+					<500000  500000 500000 500000 500000
+					 500000  500000 500000 500000>;
+
+				qcom,cpr-floor-to-ceiling-max-range =
+					/* Speed bin 0; CPR rev 0..7 */
+					 <    0     0     0     0     0
+					      0     0     0     0>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000 50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000 50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000 50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000 50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000 50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000 50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000 50000 50000>,
+
+					/* Speed bin 2; CPR rev 0..7 */
+					 <    0     0     0     0     0
+					      0     0>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000>,
+
+					/* Speed bin 6; CPR rev 0..7 */
+					 <    0     0     0     0     0
+					      0     0>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000>,
+
+					/* Speed bin 7; CPR rev 0..7 */
+					 <    0     0     0     0     0
+					      0     0     0     0>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000 50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000 50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000 50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000 50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000 50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000 50000 50000>,
+					 <50000 50000 50000 50000 50000
+					  50000 50000 50000 50000>;
+
+				qcom,cpr-misc-fuse-voltage-adjustment =
+					/* Speed bin 0; misc fuse 0..1 */
+					<    0     0     0     0      0
+					     0     0     0     0>,
+					<    0     0 30000     0      0
+					     0     0     0     0>,
+
+					/* Speed bin 2; misc fuse 0..1 */
+					<    0     0     0     0      0
+					     0     0>,
+					<    0     0 30000     0      0
+					     0     0>,
+
+					/* Speed bin 6; misc fuse 0..1 */
+					<    0     0     0     0      0
+					     0     0>,
+					<    0     0 30000     0      0
+					     0     0>,
+
+					/* Speed bin 7; misc fuse 0..1 */
+					<    0     0     0     0      0
+					     0     0     0     0>,
+					<    0     0 30000     0      0
+					     0     0     0     0>;
+
+				qcom,mem-acc-voltage =
+					/* Speed bin 0 */
+					<1 1 2 2 2 2 2 2 2>,
+
+					/* Speed bin 2 */
+					<1 1 2 2 2 2 2>,
+
+					/* Speed bin 6 */
+					<1 1 2 2 2 2 2>,
+
+					/* Speed bin 7 */
+					<1 1 2 2 2 2 2 2 2>;
+
+				qcom,corner-frequencies =
+					/* Speed bin 0 */
+					<652800000 1036800000 1401600000
+					1689600000 1804800000 1958400000
+					2016000000 2150400000 2208000000>,
+
+					/* Speed bin 2 */
+					<652800000 1036800000 1401600000
+					1689600000 1804800000 1958400000
+					2016000000>,
+
+					/* Speed bin 6 */
+					<652800000 1036800000 1401600000
+					1689600000 1804800000 1958400000
+					2016000000>,
+
+					/* Speed bin 7 */
+					<652800000 1036800000 1401600000
+					1689600000 1804800000 1958400000
+					2016000000 2150400000 2208000000>;
+
+				qcom,cpr-open-loop-voltage-fuse-adjustment =
+					/* Speed bin 0; CPR rev 0..7 */
+					<     0      0      0     0>,
+					< 25000      0   5000 40000>,
+					< 25000      0   5000 40000>,
+					< 25000      0   5000 40000>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+
+					/* Speed bin 1; CPR rev 0..7 */
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+
+					/* Speed bin 2; CPR rev 0..7 */
+					<     0      0      0     0>,
+					< 25000      0   5000 40000>,
+					< 25000      0   5000 40000>,
+					< 25000      0   5000 40000>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+
+					/* Speed bin 3; CPR rev 0..7 */
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+
+					/* Speed bin 4; CPR rev 0..7 */
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+
+					/* Speed bin 5; CPR rev 0..7 */
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+
+					/* Speed bin 6; CPR rev 0..7 */
+					<     0      0      0     0>,
+					< 25000      0   5000 40000>,
+					< 25000      0   5000 40000>,
+					< 25000      0   5000 40000>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+
+					/* Speed bin 7; CPR rev 0..7 */
+					<     0      0      0     0>,
+					< 25000      0   5000 40000>,
+					< 25000      0   5000 40000>,
+					< 25000      0   5000 40000>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>,
+					<     0      0      0     0>;
+
+				qcom,cpr-closed-loop-voltage-fuse-adjustment =
+					/* Speed bin 0; CPR rev 0..7 */
+					<      0        0        0      0>,
+					<  10000 (-15000)        0  25000>,
+					<  10000 (-15000)        0  25000>,
+					<(-5000) (-30000) (-15000)  10000>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+
+					/* Speed bin 1; CPR rev 0..7 */
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+
+					/* Speed bin 2; CPR rev 0..7 */
+					<      0        0        0      0>,
+					<  10000 (-15000)        0  25000>,
+					<  10000 (-15000)        0  25000>,
+					<(-5000) (-30000) (-15000)  10000>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+
+					/* Speed bin 3; CPR rev 0..7 */
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+
+					/* Speed bin 4; CPR rev 0..7 */
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+
+					/* Speed bin 5; CPR rev 0..7 */
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+
+					/* Speed bin 6; CPR rev 0..7 */
+					<      0        0        0      0>,
+					<  10000 (-15000)        0  25000>,
+					<  10000 (-15000)        0  25000>,
+					<(-5000) (-30000) (-15000)  10000>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+
+					/* Speed bin 7; CPR rev 0..7 */
+					<      0        0        0      0>,
+					<  10000 (-15000)        0  25000>,
+					<  10000 (-15000)        0  25000>,
+					<(-5000) (-30000) (-15000)  10000>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>,
+					<      0        0        0      0>;
+
+				qcom,cpr-ro-scaling-factor =
+				      <3610 3790    0 2200 2450 2310 2170 2210
+				       2330 2210 2470 2340  780 2700 2450 2090>,
+				      <3610 3790    0 2200 2450 2310 2170 2210
+				       2330 2210 2470 2340  780 2700 2450 2090>,
+				      <3610 3790    0 2200 2450 2310 2170 2210
+				       2330 2210 2470 2340  780 2700 2450 2090>,
+				      <3610 3790    0 2200 2450 2310 2170 2210
+				       2330 2210 2470 2340  780 2700 2450 2090>;
+
+				qcom,allow-voltage-interpolation;
+				qcom,allow-quotient-interpolation;
+				qcom,cpr-scaled-open-loop-voltage-as-ceiling;
+
+				qcom,corner-allow-temp-adjustment =
+					/* Speed bin 0; CPR rev 0..7 */
+					<0 0 0 0 0 0 0 0 0>,
+					<0 0 0 0 0 0 0 0 0>,
+					<0 0 0 0 0 0 0 0 0>,
+					<1 1 1 1 0 0 0 0 0>,
+					<1 1 1 1 0 0 0 0 0>,
+					<1 1 1 1 0 0 0 0 0>,
+					<1 1 1 1 0 0 0 0 0>,
+					<1 1 1 1 0 0 0 0 0>,
+
+					/* Speed bin 2; CPR rev 0..7 */
+					<0 0 0 0 0 0 0>,
+					<0 0 0 0 0 0 0>,
+					<0 0 0 0 0 0 0>,
+					<1 1 1 1 0 0 0>,
+					<1 1 1 1 0 0 0>,
+					<1 1 1 1 0 0 0>,
+					<1 1 1 1 0 0 0>,
+					<1 1 1 1 0 0 0>,
+
+					/* Speed bin 6; CPR rev 0..7 */
+					<0 0 0 0 0 0 0>,
+					<0 0 0 0 0 0 0>,
+					<0 0 0 0 0 0 0>,
+					<1 1 1 1 0 0 0>,
+					<1 1 1 1 0 0 0>,
+					<1 1 1 1 0 0 0>,
+					<1 1 1 1 0 0 0>,
+					<1 1 1 1 0 0 0>,
+
+					/* Speed bin 7; CPR rev 0..7 */
+					<0 0 0 0 0 0 0 0 0>,
+					<0 0 0 0 0 0 0 0 0>,
+					<0 0 0 0 0 0 0 0 0>,
+					<1 1 1 1 0 0 0 0 0>,
+					<1 1 1 1 0 0 0 0 0>,
+					<1 1 1 1 0 0 0 0 0>,
+					<1 1 1 1 0 0 0 0 0>,
+					<1 1 1 1 0 0 0 0 0>;
+
+				qcom,cpr-corner1-temp-core-voltage-adjustment =
+					<(0) (-5000) (-15000) (-20000)>;
+
+				qcom,cpr-corner2-temp-core-voltage-adjustment =
+					<(0) (-5000) (-15000) (-15000)>;
+
+				qcom,cpr-corner3-temp-core-voltage-adjustment =
+					<(0) (-5000) (-15000)      (0)>;
+
+				qcom,cpr-corner4-temp-core-voltage-adjustment =
+					<(0) (-5000) (-15000)      (0)>;
+
+				qcom,cpr-aging-max-voltage-adjustment = <15000>;
+				qcom,cpr-aging-ref-corner = <6>; /* Turbo */
+				qcom,cpr-aging-ro-scaling-factor = <2800>;
+				qcom,allow-aging-voltage-adjustment =
+					/* Speed bin 0 */
+					<0 0 0 1 1 1 1 1>,
+
+					/* Speed bin 1 */
+					<0 0 0 0 0 0 0 0>,
+
+					/* Speed bin 2 */
+					<0 0 0 1 1 1 1 1>,
+
+					/* Speed bin 3..5 */
+					<0 0 0 0 0 0 0 0>,
+					<0 0 0 0 0 0 0 0>,
+					<0 0 0 0 0 0 0 0>,
+
+					/* Speed bin 6 */
+					<0 0 0 1 1 1 1 1>,
+
+					/* Speed bin 7 */
+					<0 0 0 1 1 1 1 1>;
+			};
+		};
+	};
+
+	gfx_mem_acc: regulator@194415c {
+		compatible = "qcom,mem-acc-regulator";
+		reg = <0x0194415c 0x4>;
+		reg-names = "acc-sel-l1";
+		regulator-name = "gfx_mem_acc_corner";
+		regulator-min-microvolt = <1>;
+		regulator-max-microvolt = <2>;
+
+		qcom,acc-sel-l1-bit-pos = <0>;
+		qcom,acc-sel-l1-bit-size = <1>;
+		qcom,corner-acc-map = <0x1 0x0>;
+	};
+
+	gfx_vreg_corner: ldo@185f000 {
+		compatible = "qcom,msm8953-gfx-ldo";
+		reg = <0x0185f000 0x30>, <0xa4000 0x1000>;
+		reg-names = "ldo_addr", "efuse_addr";
+
+		regulator-name = "msm_gfx_ldo";
+		regulator-min-microvolt = <1>;
+		regulator-max-microvolt = <7>;
+
+		qcom,ldo-voltage-ceiling = <620000 680000 750000>;
+		qcom,ldo-voltage-floor =   <510000 510000 600000>;
+
+		qcom,num-corners = <7>;
+		qcom,num-ldo-corners = <3>;
+		qcom,ldo-enable-corner-map = <1 1 1 0 0 0 0>;
+		qcom,init-corner = <4>;
+
+		vdd-cx-supply = <&pm8953_s2_level>;
+		qcom,vdd-cx-corner-map = <RPM_SMD_REGULATOR_LEVEL_LOW_SVS>,
+					<RPM_SMD_REGULATOR_LEVEL_LOW_SVS>,
+					<RPM_SMD_REGULATOR_LEVEL_SVS>,
+					<RPM_SMD_REGULATOR_LEVEL_SVS_PLUS>,
+					<RPM_SMD_REGULATOR_LEVEL_NOM>,
+					<RPM_SMD_REGULATOR_LEVEL_NOM_PLUS>,
+					<RPM_SMD_REGULATOR_LEVEL_TURBO>;
+
+		mem-acc-supply = <&gfx_mem_acc>;
+		qcom,mem-acc-corner-map = <1 1 1 2 2 2 2>;
+		qcom,ldo-init-voltage-adjustment = <35000 25000 0>;
+	};
+
+	eldo2_8953: eldo2 {
+		compatible = "regulator-fixed";
+		regulator-name = "eldo2_8953";
+		startup-delay-us = <0>;
+		enable-active-high;
+		gpio = <&tlmm 50 0>;
+		regulator-always-on;
+	};
+
+	adv_vreg: adv_vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "adv_vreg";
+		startup-delay-us = <400>;
+		enable-active-high;
+		gpio = <&pm8953_gpios 5 0>;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi
index e99b9ac..a9ca87c 100644
--- a/arch/arm64/boot/dts/qcom/msm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
@@ -13,7 +13,9 @@
 
 #include "skeleton64.dtsi"
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/spmi/spmi.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/regulator/qcom,rpm-smd-regulator.h>
 
 / {
 	model = "Qualcomm Technologies, Inc. MSM 8953";
@@ -769,3 +771,7 @@
 		cell-index = <0>;
 	};
 };
+
+#include "pm8953-rpm-regulator.dtsi"
+#include "pm8953.dtsi"
+#include "msm8953-regulator.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/pm8953-rpm-regulator.dtsi b/arch/arm64/boot/dts/qcom/pm8953-rpm-regulator.dtsi
new file mode 100644
index 0000000..1e594c6
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pm8953-rpm-regulator.dtsi
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2015-2017, 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.
+ */
+
+&rpm_bus {
+	rpm-regulator-smpa1 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "smpa";
+		qcom,resource-id = <1>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+		status = "disabled";
+
+		regulator-s1 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_s1";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-smpa2 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "smpa";
+		qcom,resource-id = <2>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+		status = "disabled";
+
+		regulator-s2 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_s2";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-smpa3 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "smpa";
+		qcom,resource-id = <3>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+		status = "disabled";
+
+		regulator-s3 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_s3";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-smpa4 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "smpa";
+		qcom,resource-id = <4>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+		status = "disabled";
+
+		regulator-s4 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_s4";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-smpa7 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "smpa";
+		qcom,resource-id = <7>;
+		qcom,regulator-type = <1>;
+		qcom,hpm-min-load = <100000>;
+		status = "disabled";
+
+		regulator-s7 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_s7";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa1 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <1>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l1 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l1";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa2 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <2>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l2 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l2";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa3 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <3>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l3 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l3";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa5 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <5>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l5 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l5";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa6 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <6>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l6 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l6";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa7 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <7>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l7 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l7";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa8 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <8>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l8 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l8";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa9 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <9>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l9 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l9";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa10 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <10>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l10 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l10";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa11 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <11>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l11 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l11";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa12 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <12>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l12 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l12";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa13 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <13>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <5000>;
+		status = "disabled";
+
+		regulator-l13 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l13";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa16 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <16>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <5000>;
+		status = "disabled";
+
+		regulator-l16 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l16";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa17 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <17>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l17 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l17";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa19 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <19>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l19 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l19";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa22 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <22>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l22 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l22";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	rpm-regulator-ldoa23 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <23>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "disabled";
+
+		regulator-l23 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l23";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+
+	/* Regulator to notify APC corner to RPM */
+	rpm-regulator-clk0 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "clk0";
+		qcom,resource-id = <3>;
+		qcom,regulator-type = <1>;
+		status = "disabled";
+
+		regulator-clk0 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "rpm_apc";
+			qcom,set = <3>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/pm8953.dtsi b/arch/arm64/boot/dts/qcom/pm8953.dtsi
new file mode 100644
index 0000000..60162e3
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pm8953.dtsi
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2015-2017, 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.
+ */
+
+&spmi_bus {
+
+	qcom,pm8953@0 {
+		compatible = "qcom,spmi-pmic";
+		reg = <0x0 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		pm8953_revid: qcom,revid@100 {
+			compatible = "qcom,qpnp-revid";
+			reg = <0x100 0x100>;
+		};
+
+		qcom,power-on@800 {
+			compatible = "qcom,qpnp-power-on";
+			reg = <0x800 0x100>;
+			interrupts = <0x0 0x8 0x0 IRQ_TYPE_NONE>,
+				<0x0 0x8 0x1 IRQ_TYPE_NONE>,
+				<0x0 0x8 0x4 IRQ_TYPE_NONE>,
+				<0x0 0x8 0x5 IRQ_TYPE_NONE>;
+			interrupt-names = "kpdpwr", "resin",
+				"resin-bark", "kpdpwr-resin-bark";
+			qcom,pon-dbc-delay = <15625>;
+			qcom,system-reset;
+
+			qcom,pon_1 {
+				qcom,pon-type = <0>;
+				qcom,pull-up = <1>;
+				linux,code = <116>;
+			};
+
+			qcom,pon_2 {
+				qcom,pon-type = <1>;
+				qcom,pull-up = <1>;
+				linux,code = <114>;
+			};
+		};
+
+		pm8953_temp_alarm: qcom,temp-alarm@2400 {
+			compatible = "qcom,qpnp-temp-alarm";
+			reg = <0x2400 0x100>;
+			interrupts = <0x0 0x24 0x0 IRQ_TYPE_EDGE_RISING>;
+			label = "pm8953_tz";
+			qcom,channel-num = <8>;
+			qcom,threshold-set = <0>;
+			qcom,temp_alarm-vadc = <&pm8953_vadc>;
+		};
+
+		pm8953_coincell: qcom,coincell@2800 {
+			compatible = "qcom,qpnp-coincell";
+			reg = <0x2800 0x100>;
+		};
+
+		pm8953_mpps: mpps {
+			compatible = "qcom,qpnp-pin";
+			spmi-dev-container;
+			gpio-controller;
+			#gpio-cells = <2>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			label = "pm8953-mpp";
+
+			mpp@a000 {
+				reg = <0xa000 0x100>;
+				qcom,pin-num = <1>;
+				status = "disabled";
+			};
+
+			mpp@a100 {
+				reg = <0xa100 0x100>;
+				qcom,pin-num = <2>;
+			};
+
+			mpp@a200 {
+				reg = <0xa200 0x100>;
+				qcom,pin-num = <3>;
+				status = "disabled";
+			};
+
+			mpp@a300 {
+				reg = <0xa300 0x100>;
+				qcom,pin-num = <4>;
+			};
+		};
+
+		pm8953_gpios: gpios {
+			spmi-dev-container;
+			compatible = "qcom,qpnp-pin";
+			gpio-controller;
+			#gpio-cells = <2>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			label = "pm8953-gpio";
+
+			gpio@c000 {
+				reg = <0xc000 0x100>;
+				qcom,pin-num = <1>;
+				status = "disabled";
+			};
+
+			gpio@c100 {
+				reg = <0xc100 0x100>;
+				qcom,pin-num = <2>;
+				status = "disabled";
+			};
+
+			gpio@c200 {
+				reg = <0xc200 0x100>;
+				qcom,pin-num = <3>;
+				status = "disabled";
+			};
+
+			gpio@c300 {
+				reg = <0xc300 0x100>;
+				qcom,pin-num = <4>;
+				status = "disabled";
+			};
+
+			gpio@c400 {
+				reg = <0xc400 0x100>;
+				qcom,pin-num = <5>;
+				status = "disabled";
+			};
+
+			gpio@c500 {
+				reg = <0xc500 0x100>;
+				qcom,pin-num = <6>;
+				status = "disabled";
+			};
+
+			gpio@c600 {
+				reg = <0xc600 0x100>;
+				qcom,pin-num = <7>;
+				status = "disabled";
+			};
+
+			gpio@c700 {
+				reg = <0xc700 0x100>;
+				qcom,pin-num = <8>;
+				status = "disabled";
+			};
+		};
+
+		pm8953_vadc: vadc@3100 {
+			compatible = "qcom,qpnp-vadc";
+			reg = <0x3100 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "eoc-int-en-set";
+			qcom,adc-bit-resolution = <15>;
+			qcom,adc-vdd-reference = <1800>;
+			qcom,vadc-poll-eoc;
+
+			chan@8 {
+				label = "die_temp";
+				reg = <8>;
+				qcom,decimation = <0>;
+				qcom,pre-div-channel-scaling = <0>;
+				qcom,calibration-type = "absolute";
+				qcom,scale-function = <3>;
+				qcom,hw-settle-time = <0>;
+				qcom,fast-avg-setup = <0>;
+			};
+
+			chan@9 {
+				label = "ref_625mv";
+				reg = <9>;
+				qcom,decimation = <0>;
+				qcom,pre-div-channel-scaling = <0>;
+				qcom,calibration-type = "absolute";
+				qcom,scale-function = <0>;
+				qcom,hw-settle-time = <0>;
+				qcom,fast-avg-setup = <0>;
+			};
+
+			chan@a {
+				label = "ref_1250v";
+				reg = <0xa>;
+				qcom,decimation = <0>;
+				qcom,pre-div-channel-scaling = <0>;
+				qcom,calibration-type = "absolute";
+				qcom,scale-function = <0>;
+				qcom,hw-settle-time = <0>;
+				qcom,fast-avg-setup = <0>;
+			};
+
+			chan@c {
+				label = "ref_buf_625mv";
+				reg = <0xc>;
+				qcom,decimation = <0>;
+				qcom,pre-div-channel-scaling = <0>;
+				qcom,calibration-type = "absolute";
+				qcom,scale-function = <0>;
+				qcom,hw-settle-time = <0>;
+				qcom,fast-avg-setup = <0>;
+			};
+		};
+
+		pm8953_adc_tm: vadc@3400 {
+			compatible = "qcom,qpnp-adc-tm";
+			reg = <0x3400 0x100>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts =	<0x0 0x34 0x0 IRQ_TYPE_EDGE_RISING>,
+					<0x0 0x34 0x3 IRQ_TYPE_EDGE_RISING>,
+					<0x0 0x34 0x4 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names =	"eoc-int-en-set",
+						"high-thr-en-set",
+						"low-thr-en-set";
+			qcom,adc-bit-resolution = <15>;
+			qcom,adc-vdd-reference = <1800>;
+			qcom,adc_tm-vadc = <&pm8953_vadc>;
+
+		};
+
+		pm8953_rtc: qcom,pm8953_rtc {
+			spmi-dev-container;
+			compatible = "qcom,qpnp-rtc";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			qcom,qpnp-rtc-write = <0>;
+			qcom,qpnp-rtc-alarm-pwrup = <0>;
+
+			qcom,pm8953_rtc_rw@6000 {
+				reg = <0x6000 0x100>;
+			};
+
+			qcom,pm8953_rtc_alarm@6100 {
+				reg = <0x6100 0x100>;
+				interrupts = <0x0 0x61 0x1 IRQ_TYPE_NONE>;
+			};
+		};
+
+		pm8953_typec: qcom,pm8953_typec@bf00 {
+			compatible = "qcom,qpnp-typec";
+			reg = <0xbf00 0x100>;
+			interrupts =    <0x0 0xbf 0x0 IRQ_TYPE_EDGE_RISING>,
+					<0x0 0xbf 0x1 IRQ_TYPE_EDGE_RISING>,
+					<0x0 0xbf 0x2 IRQ_TYPE_EDGE_RISING>,
+					<0x0 0xbf 0x3 IRQ_TYPE_EDGE_RISING>,
+					<0x0 0xbf 0x4 IRQ_TYPE_EDGE_RISING>,
+					<0x0 0xbf 0x6 IRQ_TYPE_EDGE_RISING>,
+					<0x0 0xbf 0x7 IRQ_TYPE_EDGE_RISING>;
+
+			interrupt-names =       "vrd-change",
+						"ufp-detect",
+						"ufp-detach",
+						"dfp-detect",
+						"dfp-detach",
+						"vbus-err",
+						"vconn-oc";
+		};
+	};
+
+	pm8953_1: qcom,pm8953@1 {
+		compatible = "qcom,spmi-pmic";
+		reg = <0x1 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		pm8953_pwm: pwm@bc00 {
+			status = "disabled";
+			compatible = "qcom,qpnp-pwm";
+			reg = <0xbc00 0x100>;
+			reg-names = "qpnp-lpg-channel-base";
+			qcom,channel-id = <0>;
+			qcom,supported-sizes = <6>, <9>;
+			#pwm-cells = <2>;
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/pmi8950.dtsi b/arch/arm64/boot/dts/qcom/pmi8950.dtsi
index 4223cfe..8b4fccb 100644
--- a/arch/arm64/boot/dts/qcom/pmi8950.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi8950.dtsi
@@ -43,7 +43,7 @@
 			reg = <0x3100 0x100>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			interrupts = <0x2 0x31 0x0>;
+			interrupts = <0x2 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
 			interrupt-names = "eoc-int-en-set";
 			qcom,adc-bit-resolution = <15>;
 			qcom,adc-vdd-reference = <1800>;
@@ -140,7 +140,6 @@
 		};
 
 		pmi8950_gpios: gpios {
-			spmi-dev-container;
 			compatible = "qcom,qpnp-pin";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -162,7 +161,6 @@
 		};
 
 		pmi8950_mpps: mpps {
-			spmi-dev-container;
 			compatible = "qcom,qpnp-pin";
 			gpio-controller;
 			#gpio-cells = <2>;
@@ -196,7 +194,6 @@
 		};
 
 		pmi8950_charger: qcom,qpnp-smbcharger {
-			spmi-dev-container;
 			compatible = "qcom,qpnp-smbcharger";
 			#address-cells = <1>;
 			#size-cells = <1>;
@@ -218,14 +215,14 @@
 
 			qcom,chgr@1000 {
 				reg = <0x1000 0x100>;
-				interrupts =	<0x2 0x10 0x0>,
-						<0x2 0x10 0x1>,
-						<0x2 0x10 0x2>,
-						<0x2 0x10 0x3>,
-						<0x2 0x10 0x4>,
-						<0x2 0x10 0x5>,
-						<0x2 0x10 0x6>,
-						<0x2 0x10 0x7>;
+				interrupts =	<0x2 0x10 0x0 IRQ_TYPE_NONE>,
+						<0x2 0x10 0x1 IRQ_TYPE_NONE>,
+						<0x2 0x10 0x2 IRQ_TYPE_NONE>,
+						<0x2 0x10 0x3 IRQ_TYPE_NONE>,
+						<0x2 0x10 0x4 IRQ_TYPE_NONE>,
+						<0x2 0x10 0x5 IRQ_TYPE_NONE>,
+						<0x2 0x10 0x6 IRQ_TYPE_NONE>,
+						<0x2 0x10 0x7 IRQ_TYPE_NONE>;
 
 				interrupt-names =	"chg-error",
 							"chg-inhibit",
@@ -239,9 +236,9 @@
 
 			qcom,otg@1100 {
 				reg = <0x1100 0x100>;
-				interrupts =	<0x2 0x11 0x0>,
-						<0x2 0x11 0x1>,
-						<0x2 0x11 0x3>;
+				interrupts =	<0x2 0x11 0x0 IRQ_TYPE_NONE>,
+						<0x2 0x11 0x1 IRQ_TYPE_NONE>,
+						<0x2 0x11 0x3 IRQ_TYPE_NONE>;
 				interrupt-names =	"otg-fail",
 							"otg-oc",
 						"usbid-change";
@@ -249,14 +246,14 @@
 
 			qcom,bat-if@1200 {
 				reg = <0x1200 0x100>;
-				interrupts =	<0x2 0x12 0x0>,
-						<0x2 0x12 0x1>,
-						<0x2 0x12 0x2>,
-						<0x2 0x12 0x3>,
-					<0x2 0x12 0x4>,
-						<0x2 0x12 0x5>,
-						<0x2 0x12 0x6>,
-						<0x2 0x12 0x7>;
+				interrupts =	<0x2 0x12 0x0 IRQ_TYPE_NONE>,
+						<0x2 0x12 0x1 IRQ_TYPE_NONE>,
+						<0x2 0x12 0x2 IRQ_TYPE_NONE>,
+						<0x2 0x12 0x3 IRQ_TYPE_NONE>,
+						<0x2 0x12 0x4 IRQ_TYPE_NONE>,
+						<0x2 0x12 0x5 IRQ_TYPE_NONE>,
+						<0x2 0x12 0x6 IRQ_TYPE_NONE>,
+						<0x2 0x12 0x7 IRQ_TYPE_NONE>;
 
 				interrupt-names =	"batt-hot",
 							"batt-warm",
@@ -270,10 +267,10 @@
 
 			qcom,usb-chgpth@1300 {
 				reg = <0x1300 0x100>;
-				interrupts =	<0x2 0x13 0x0>,
-						<0x2 0x13 0x1>,
-					<0x2 0x13 0x2>,
-						<0x2 0x13 0x5>;
+				interrupts =	<0x2 0x13 0x0 IRQ_TYPE_NONE>,
+						<0x2 0x13 0x1 IRQ_TYPE_NONE>,
+						<0x2 0x13 0x2 IRQ_TYPE_NONE>,
+						<0x2 0x13 0x5 IRQ_TYPE_NONE>;
 
 				interrupt-names =	"usbin-uv",
 						"usbin-ov",
@@ -283,20 +280,20 @@
 
 			qcom,dc-chgpth@1400 {
 				reg = <0x1400 0x100>;
-				interrupts =	<0x2 0x14 0x0>,
-						<0x2 0x14 0x1>;
+				interrupts =	<0x2 0x14 0x0 IRQ_TYPE_NONE>,
+						<0x2 0x14 0x1 IRQ_TYPE_NONE>;
 				interrupt-names =	"dcin-uv",
 							"dcin-ov";
 			};
 
 			qcom,chgr-misc@1600 {
 				reg = <0x1600 0x100>;
-				interrupts =	<0x2 0x16 0x0>,
-						<0x2 0x16 0x1>,
-						<0x2 0x16 0x2>,
-					<0x2 0x16 0x3>,
-						<0x2 0x16 0x4>,
-						<0x2 0x16 0x5>;
+				interrupts =	<0x2 0x16 0x0 IRQ_TYPE_NONE>,
+						<0x2 0x16 0x1 IRQ_TYPE_NONE>,
+						<0x2 0x16 0x2 IRQ_TYPE_NONE>,
+						<0x2 0x16 0x3 IRQ_TYPE_NONE>,
+						<0x2 0x16 0x4 IRQ_TYPE_NONE>,
+						<0x2 0x16 0x5 IRQ_TYPE_NONE>;
 
 				interrupt-names =	"power-ok",
 							"temp-shutdown",
@@ -312,7 +309,6 @@
 		};
 
 		pmi8950_fg: qcom,fg {
-			spmi-dev-container;
 			compatible = "qcom,qpnp-fg";
 			#address-cells = <1>;
 			#size-cells = <1>;
@@ -330,13 +326,13 @@
 			qcom,fg-soc@4000 {
 			status = "okay";
 				reg = <0x4000 0x100>;
-				interrupts =	<0x2 0x40 0x0>,
-						<0x2 0x40 0x1>,
-						<0x2 0x40 0x2>,
-						<0x2 0x40 0x3>,
-						<0x2 0x40 0x4>,
-						<0x2 0x40 0x5>,
-						<0x2 0x40 0x6>;
+				interrupts =	<0x2 0x40 0x0 IRQ_TYPE_NONE>,
+						<0x2 0x40 0x1 IRQ_TYPE_NONE>,
+						<0x2 0x40 0x2 IRQ_TYPE_NONE>,
+						<0x2 0x40 0x3 IRQ_TYPE_NONE>,
+						<0x2 0x40 0x4 IRQ_TYPE_NONE>,
+						<0x2 0x40 0x5 IRQ_TYPE_NONE>,
+						<0x2 0x40 0x6 IRQ_TYPE_NONE>;
 
 				interrupt-names =	"high-soc",
 							"low-soc",
@@ -349,14 +345,14 @@
 
 			qcom,fg-batt@4100 {
 				reg = <0x4100 0x100>;
-				interrupts =	<0x2 0x41 0x0>,
-						<0x2 0x41 0x1>,
-					<0x2 0x41 0x2>,
-						<0x2 0x41 0x3>,
-						<0x2 0x41 0x4>,
-						<0x2 0x41 0x5>,
-						<0x2 0x41 0x6>,
-						<0x2 0x41 0x7>;
+				interrupts =	<0x2 0x41 0x0 IRQ_TYPE_NONE>,
+						<0x2 0x41 0x1 IRQ_TYPE_NONE>,
+						<0x2 0x41 0x2 IRQ_TYPE_NONE>,
+						<0x2 0x41 0x3 IRQ_TYPE_NONE>,
+						<0x2 0x41 0x4 IRQ_TYPE_NONE>,
+						<0x2 0x41 0x5 IRQ_TYPE_NONE>,
+						<0x2 0x41 0x6 IRQ_TYPE_NONE>,
+						<0x2 0x41 0x7 IRQ_TYPE_NONE>;
 
 				interrupt-names =	"soft-cold",
 							"soft-hot",
@@ -375,8 +371,8 @@
 			qcom,fg-memif@4400 {
 				status = "okay";
 				reg = <0x4400 0x100>;
-				interrupts =	<0x2 0x44 0x0>,
-						<0x2 0x44 0x2>;
+				interrupts =	<0x2 0x44 0x0 IRQ_TYPE_NONE>,
+						<0x2 0x44 0x2 IRQ_TYPE_NONE>;
 
 				interrupt-names =	"mem-avail",
 							"data-rcvry-sug";
@@ -387,8 +383,8 @@
 			compatible = "qcom,msm-bcl";
 			reg = <0x4200 0xFF 0x88E 0x2>;
 			reg-names = "fg_user_adc", "pon_spare";
-			interrupts = <0x2 0x42 0x0>,
-					<0x2 0x42 0x1>;
+			interrupts = <0x2 0x42 0x0 IRQ_TYPE_NONE>,
+					<0x2 0x42 0x1 IRQ_TYPE_NONE>;
 			interrupt-names = "bcl-high-ibat-int",
 					"bcl-low-vbat-int";
 			qcom,vbat-scaling-factor = <39000>;
@@ -429,7 +425,6 @@
 
 		labibb: qpnp-labibb-regulator {
 			status = "disabled";
-			spmi-dev-container;
 			compatible = "qcom,qpnp-labibb-regulator";
 			#address-cells = <1>;
 			#size-cells = <1>;
@@ -512,7 +507,7 @@
 					"qpnp-wled-sink-base",
 					"qpnp-wled-ibb-base",
 					"qpnp-wled-lab-base";
-			interrupts = <0x3 0xd8 0x2>;
+			interrupts = <0x3 0xd8 0x2 IRQ_TYPE_EDGE_RISING>;
 			interrupt-names = "sc-irq";
 			status = "okay";
 			linux,name = "wled";
@@ -531,6 +526,7 @@
 			qcom,fs-curr-ua = <20000>;
 			qcom,led-strings-list = [00 01];
 			qcom,en-ext-pfet-sc-pro;
+			qcom,pmic-revid = <&pmi8950_revid>;
 			qcom,cons-sync-write-delay-us = <1000>;
 		};
 
@@ -617,8 +613,8 @@
 		pmi_haptic: qcom,haptic@c000 {
 			compatible = "qcom,qpnp-haptic";
 			reg = <0xc000 0x100>;
-			interrupts = <0x3 0xc0 0x0>,
-					<0x3 0xc0 0x1>;
+			interrupts = <0x3 0xc0 0x0 IRQ_TYPE_EDGE_BOTH>,
+					<0x3 0xc0 0x1 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "sc-irq", "play-irq";
 			qcom,pmic-revid = <&pmi8950_revid>;
 			vcc_pon-supply = <&pon_perph_reg>;
diff --git a/arch/arm64/boot/dts/qcom/sdm670-coresight.dtsi b/arch/arm64/boot/dts/qcom/sdm670-coresight.dtsi
index 8323476..f8a8e15 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-coresight.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-coresight.dtsi
@@ -63,6 +63,9 @@
 		clocks = <&clock_aop QDSS_CLK>;
 		clock-names = "apb_pclk";
 
+		interrupts = <GIC_SPI 270 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "byte-cntr-irq";
+
 		port {
 			tmc_etr_in_replicator: endpoint {
 				slave-mode;
diff --git a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
index e9924e2..c136752 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
@@ -371,4 +371,7 @@
 	xo-therm-mdm-step {
 		status = "disabled";
 	};
+	xo-therm-batt-step {
+		status = "disabled";
+	};
 };
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi b/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi
index 0a7e25d..5d3975c 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi
@@ -385,3 +385,63 @@
 	vbus_dwc3-supply = <&smb2_vbus>;
 	qcom,no-vbus-vote-with-type-C;
 };
+
+&thermal_zones {
+	xo-therm-batt-step {
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm660_adc_tm 0x4c>;
+		thermal-governor = "step_wise";
+
+		trips {
+			batt_trip1: batt-trip1 {
+				temperature = <40000>;
+				hysteresis = <2000>;
+				type = "passive";
+			};
+			batt_trip2: batt-trip2 {
+				temperature = <45000>;
+				hysteresis = <2000>;
+				type = "passive";
+			};
+			batt_trip3: batt-trip3 {
+				temperature = <48000>;
+				hysteresis = <3000>;
+				type = "passive";
+			};
+			batt_trip4: batt-trip4 {
+				temperature = <50000>;
+				hysteresis = <2000>;
+				type = "passive";
+			};
+			batt_trip5: batt-trip5 {
+				temperature = <52000>;
+				hysteresis = <2000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			battery_lvl1 {
+				trip = <&batt_trip1>;
+				cooling-device = <&pm660_charger 1 1>;
+			};
+			battery_lvl2 {
+				trip = <&batt_trip2>;
+				cooling-device = <&pm660_charger 2 2>;
+			};
+			battery_lvl3 {
+				trip = <&batt_trip3>;
+				cooling-device = <&pm660_charger 3 3>;
+			};
+			battery_lvl4 {
+				trip = <&batt_trip4>;
+				cooling-device = <&pm660_charger 4 4>;
+			};
+			battery_lvl5 {
+				trip = <&batt_trip5>;
+				cooling-device = <&pm660_charger 5 5>;
+			};
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
index 3c84314..9898ada 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
@@ -459,9 +459,9 @@
 		pm660_l19: regulator-pm660-l19 {
 			regulator-name = "pm660_l19";
 			qcom,set = <RPMH_REGULATOR_SET_ALL>;
-			regulator-min-microvolt = <3312000>;
+			regulator-min-microvolt = <3000000>;
 			regulator-max-microvolt = <3312000>;
-			qcom,init-voltage = <3312000>;
+			qcom,init-voltage = <3000000>;
 			qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
 		};
 	};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-thermal.dtsi b/arch/arm64/boot/dts/qcom/sdm670-thermal.dtsi
index 6324b64..8cbc84f 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-thermal.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-thermal.dtsi
@@ -1539,7 +1539,7 @@
 				type = "passive";
 			};
 			silver_trip1: silver-trip1 {
-				temperature = <48000>;
+				temperature = <50000>;
 				hysteresis = <0>;
 				type = "passive";
 			};
@@ -1606,7 +1606,7 @@
 			};
 			modem_trip2: modem-trip2 {
 				temperature = <48000>;
-				hysteresis = <2000>;
+				hysteresis = <3000>;
 				type = "passive";
 			};
 			modem_trip3: modem-trip3 {
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 4065954..0b8ddf3 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -571,6 +571,8 @@
 
 #include "sdm670-smp2p.dtsi"
 
+#include "msm-rdbg.dtsi"
+
 #include "sdm670-qupv3.dtsi"
 
 #include "sdm670-coresight.dtsi"
@@ -1114,7 +1116,7 @@
 		reg-names = "wdt-base";
 		interrupts = <0 0 0>, <0 1 0>;
 		qcom,bark-time = <11000>;
-		qcom,pet-time = <10000>;
+		qcom,pet-time = <9360>;
 		qcom,ipi-ping;
 		qcom,wakeup-enable;
 	};
@@ -2475,6 +2477,7 @@
 		vdd-1.8-xo-supply = <&pm660_l9>;
 		vdd-1.3-rfa-supply = <&pm660_l6>;
 		vdd-3.3-ch0-supply = <&pm660_l19>;
+		qcom,vdd-3.3-ch0-config = <3000000 3312000>;
 		qcom,wlan-msa-memory = <0x100000>;
 		qcom,smmu-s1-bypass;
 	};
diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig
index b95fdc2..2539aa2 100644
--- a/arch/arm64/configs/msm8953-perf_defconfig
+++ b/arch/arm64/configs/msm8953-perf_defconfig
@@ -280,6 +280,7 @@
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_HBTP_INPUT=y
+CONFIG_INPUT_QPNP_POWER_ON=y
 CONFIG_INPUT_UINPUT=y
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_VT is not set
@@ -302,10 +303,17 @@
 CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_QPNP_PIN=y
+CONFIG_GPIO_QPNP_PIN_DEBUG=y
 CONFIG_POWER_RESET_QCOM=y
 CONFIG_QCOM_DLOAD_MODE=y
 CONFIG_POWER_RESET_XGENE=y
 CONFIG_POWER_RESET_SYSCON=y
+CONFIG_QPNP_FG=y
+CONFIG_SMB135X_CHARGER=y
+CONFIG_SMB1351_USB_CHARGER=y
+CONFIG_QPNP_SMBCHARGER=y
+CONFIG_MSM_APM=y
 CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_QPNP=y
@@ -313,10 +321,16 @@
 CONFIG_THERMAL_TSENS=y
 CONFIG_MSM_BCL_PERIPHERAL_CTL=y
 CONFIG_QTI_THERMAL_LIMITS_DCVS=y
+CONFIG_MFD_SPMI_PMIC=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_CPR4_APSS=y
 CONFIG_REGULATOR_CPRH_KBSS=y
+CONFIG_REGULATOR_MEM_ACC=y
+CONFIG_REGULATOR_MSM_GFX_LDO=y
 CONFIG_REGULATOR_QPNP_LABIBB=y
 CONFIG_REGULATOR_QPNP=y
+CONFIG_REGULATOR_RPM_SMD=y
+CONFIG_REGULATOR_SPM=y
 CONFIG_REGULATOR_STUB=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
@@ -372,7 +386,9 @@
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_QPNP=y
+CONFIG_LEDS_QPNP_FLASH=y
 CONFIG_LEDS_QPNP_WLED=y
+CONFIG_LEDS_QPNP_HAPTICS=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_EDAC=y
 CONFIG_EDAC_MM_EDAC=y
@@ -401,6 +417,8 @@
 CONFIG_REMOTE_SPINLOCK_MSM=y
 CONFIG_MAILBOX=y
 CONFIG_ARM_SMMU=y
+CONFIG_MSM_SPM=y
+CONFIG_MSM_L2_SPM=y
 CONFIG_MSM_BOOT_STATS=y
 CONFIG_QCOM_EUD=y
 CONFIG_QCOM_WATCHDOG_V2=y
diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig
index 04bdb9b..52f9976 100644
--- a/arch/arm64/configs/msm8953_defconfig
+++ b/arch/arm64/configs/msm8953_defconfig
@@ -290,6 +290,7 @@
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_HBTP_INPUT=y
+CONFIG_INPUT_QPNP_POWER_ON=y
 CONFIG_INPUT_UINPUT=y
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_VT is not set
@@ -312,10 +313,17 @@
 CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_QPNP_PIN=y
+CONFIG_GPIO_QPNP_PIN_DEBUG=y
 CONFIG_POWER_RESET_QCOM=y
 CONFIG_QCOM_DLOAD_MODE=y
 CONFIG_POWER_RESET_XGENE=y
 CONFIG_POWER_RESET_SYSCON=y
+CONFIG_QPNP_FG=y
+CONFIG_SMB135X_CHARGER=y
+CONFIG_SMB1351_USB_CHARGER=y
+CONFIG_QPNP_SMBCHARGER=y
+CONFIG_MSM_APM=y
 CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_QPNP=y
@@ -323,10 +331,16 @@
 CONFIG_THERMAL_TSENS=y
 CONFIG_MSM_BCL_PERIPHERAL_CTL=y
 CONFIG_QTI_THERMAL_LIMITS_DCVS=y
+CONFIG_MFD_SPMI_PMIC=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_CPR4_APSS=y
 CONFIG_REGULATOR_CPRH_KBSS=y
+CONFIG_REGULATOR_MEM_ACC=y
+CONFIG_REGULATOR_MSM_GFX_LDO=y
 CONFIG_REGULATOR_QPNP_LABIBB=y
 CONFIG_REGULATOR_QPNP=y
+CONFIG_REGULATOR_RPM_SMD=y
+CONFIG_REGULATOR_SPM=y
 CONFIG_REGULATOR_STUB=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
@@ -384,7 +398,9 @@
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_QPNP=y
+CONFIG_LEDS_QPNP_FLASH=y
 CONFIG_LEDS_QPNP_WLED=y
+CONFIG_LEDS_QPNP_HAPTICS=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_EDAC=y
 CONFIG_EDAC_MM_EDAC=y
@@ -415,6 +431,8 @@
 CONFIG_IOMMU_DEBUG=y
 CONFIG_IOMMU_DEBUG_TRACKING=y
 CONFIG_IOMMU_TESTS=y
+CONFIG_MSM_SPM=y
+CONFIG_MSM_L2_SPM=y
 CONFIG_MSM_BOOT_STATS=y
 CONFIG_MSM_CORE_HANG_DETECT=y
 CONFIG_MSM_GLADIATOR_HANG_DETECT=y
diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig
index 822324d..ab7268f 100644
--- a/arch/arm64/configs/sdm670_defconfig
+++ b/arch/arm64/configs/sdm670_defconfig
@@ -314,6 +314,7 @@
 CONFIG_HW_RANDOM_MSM_LEGACY=y
 # CONFIG_DEVPORT is not set
 CONFIG_MSM_ADSPRPC=y
+CONFIG_MSM_RDBG=m
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_QCOM_GENI=y
 CONFIG_SPI=y
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 35eea02..8a28212 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -238,13 +238,13 @@
 	int ramdumpenabled;
 	void *remoteheap_ramdump_dev;
 	struct fastrpc_glink_info link;
-	struct mutex mut;
 };
 
 struct fastrpc_apps {
 	struct fastrpc_channel_ctx *channel;
 	struct cdev cdev;
 	struct class *class;
+	struct mutex smd_mutex;
 	struct smq_phy_page range;
 	struct hlist_head maps;
 	uint32_t staticpd_flags;
@@ -654,10 +654,6 @@
 		if (err)
 			goto bail;
 
-		map->uncached = !ION_IS_CACHED(flags);
-		if (map->attr & FASTRPC_ATTR_NOVA)
-			map->uncached = 1;
-
 		map->secure = flags & ION_FLAG_SECURE;
 		if (map->secure) {
 			if (!fl->secsctx)
@@ -670,9 +666,15 @@
 			sess = fl->secsctx;
 		else
 			sess = fl->sctx;
+
 		VERIFY(err, !IS_ERR_OR_NULL(sess));
 		if (err)
 			goto bail;
+
+		map->uncached = !ION_IS_CACHED(flags);
+		if (map->attr & FASTRPC_ATTR_NOVA && !sess->smmu.coherent)
+			map->uncached = 1;
+
 		VERIFY(err, !IS_ERR_OR_NULL(map->buf = dma_buf_get(fd)));
 		if (err)
 			goto bail;
@@ -1496,12 +1498,12 @@
 
 	INIT_HLIST_HEAD(&me->drivers);
 	spin_lock_init(&me->hlock);
+	mutex_init(&me->smd_mutex);
 	me->channel = &gcinfo[0];
 	for (i = 0; i < NUM_CHANNELS; i++) {
 		init_completion(&me->channel[i].work);
 		init_completion(&me->channel[i].workport);
 		me->channel[i].sesscount = 0;
-		mutex_init(&me->channel[i].mut);
 	}
 }
 
@@ -1619,7 +1621,7 @@
 	int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
 	int hlosVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
 
-	VERIFY(err, !fastrpc_channel_open(fl));
+	VERIFY(err, 0 == (err = fastrpc_channel_open(fl)));
 	if (err)
 		goto bail;
 	if (init->flags == FASTRPC_INIT_ATTACH) {
@@ -2122,7 +2124,7 @@
 	ctx->chan = NULL;
 	glink_unregister_link_state_cb(ctx->link.link_notify_handle);
 	ctx->link.link_notify_handle = NULL;
-	mutex_unlock(&ctx->mut);
+	mutex_unlock(&me->smd_mutex);
 	pr_info("'closed /dev/%s c %d %d'\n", gcinfo[cid].name,
 						MAJOR(me->dev_no), cid);
 }
@@ -2215,15 +2217,6 @@
 		link->port_state = FASTRPC_LINK_DISCONNECTED;
 		break;
 	case GLINK_REMOTE_DISCONNECTED:
-		mutex_lock(&me->channel[cid].mut);
-		if (me->channel[cid].chan) {
-			link->port_state = FASTRPC_LINK_REMOTE_DISCONNECTING;
-			fastrpc_glink_close(me->channel[cid].chan, cid);
-			me->channel[cid].chan = NULL;
-		} else {
-			link->port_state = FASTRPC_LINK_DISCONNECTED;
-		}
-		mutex_unlock(&me->channel[cid].mut);
 		break;
 	default:
 		break;
@@ -2234,20 +2227,23 @@
 					struct fastrpc_session_ctx **session)
 {
 	int err = 0;
+	struct fastrpc_apps *me = &gfa;
 
-	mutex_lock(&chan->mut);
+	mutex_lock(&me->smd_mutex);
 	if (!*session)
 		err = fastrpc_session_alloc_locked(chan, secure, session);
-	mutex_unlock(&chan->mut);
+	mutex_unlock(&me->smd_mutex);
 	return err;
 }
 
 static void fastrpc_session_free(struct fastrpc_channel_ctx *chan,
 				struct fastrpc_session_ctx *session)
 {
-	mutex_lock(&chan->mut);
+	struct fastrpc_apps *me = &gfa;
+
+	mutex_lock(&me->smd_mutex);
 	session->used = 0;
-	mutex_unlock(&chan->mut);
+	mutex_unlock(&me->smd_mutex);
 }
 
 static int fastrpc_file_free(struct fastrpc_file *fl)
@@ -2280,7 +2276,7 @@
 	}
 	if (fl->ssrcount == fl->apps->channel[cid].ssrcount)
 		kref_put_mutex(&fl->apps->channel[cid].kref,
-			fastrpc_channel_close, &fl->apps->channel[cid].mut);
+				fastrpc_channel_close, &fl->apps->smd_mutex);
 	if (fl->sctx)
 		fastrpc_session_free(&fl->apps->channel[cid], fl->sctx);
 	if (fl->secsctx)
@@ -2357,20 +2353,6 @@
 	return err;
 }
 
-static void fastrpc_glink_stop(int cid)
-{
-	int err = 0;
-	struct fastrpc_glink_info *link;
-
-	VERIFY(err, (cid >= 0 && cid < NUM_CHANNELS));
-	if (err)
-		return;
-	link = &gfa.channel[cid].link;
-
-	if (link->port_state == FASTRPC_LINK_CONNECTED)
-		link->port_state = FASTRPC_LINK_REMOTE_DISCONNECTING;
-}
-
 static void fastrpc_glink_close(void *chan, int cid)
 {
 	int err = 0;
@@ -2548,20 +2530,23 @@
 	struct fastrpc_apps *me = &gfa;
 	int cid, err = 0;
 
+	mutex_lock(&me->smd_mutex);
+
 	VERIFY(err, fl && fl->sctx);
 	if (err)
-		return err;
+		goto bail;
 	cid = fl->cid;
 	VERIFY(err, cid >= 0 && cid < NUM_CHANNELS);
 	if (err)
 		goto bail;
-	mutex_lock(&me->channel[cid].mut);
 	if (me->channel[cid].ssrcount !=
 				 me->channel[cid].prevssrcount) {
 		if (!me->channel[cid].issubsystemup) {
 			VERIFY(err, 0);
-			if (err)
+			if (err) {
+				err = -ENOTCONN;
 				goto bail;
+			}
 		}
 	}
 	fl->ssrcount = me->channel[cid].ssrcount;
@@ -2574,11 +2559,9 @@
 		if (err)
 			goto bail;
 
-		mutex_unlock(&me->channel[cid].mut);
 		VERIFY(err,
 			 wait_for_completion_timeout(&me->channel[cid].workport,
 						RPC_TIMEOUT));
-		mutex_lock(&me->channel[cid].mut);
 		if (err) {
 			me->channel[cid].chan = NULL;
 			goto bail;
@@ -2603,7 +2586,7 @@
 	}
 
 bail:
-	mutex_unlock(&me->channel[cid].mut);
+	mutex_unlock(&me->smd_mutex);
 	return err;
 }
 
@@ -2866,7 +2849,7 @@
 			p.init.init.memlen < INIT_MEMLEN_MAX);
 		if (err)
 			goto bail;
-		VERIFY(err, 0 == fastrpc_init_process(fl, &p.init));
+		VERIFY(err, 0 == (err = fastrpc_init_process(fl, &p.init)));
 		if (err)
 			goto bail;
 		break;
@@ -2892,14 +2875,16 @@
 	ctx = container_of(nb, struct fastrpc_channel_ctx, nb);
 	cid = ctx - &me->channel[0];
 	if (code == SUBSYS_BEFORE_SHUTDOWN) {
-		mutex_lock(&ctx->mut);
+		mutex_lock(&me->smd_mutex);
 		ctx->ssrcount++;
 		ctx->issubsystemup = 0;
-		pr_info("'restart notifier: /dev/%s c %d %d'\n",
-			 gcinfo[cid].name, MAJOR(me->dev_no), cid);
-		if (ctx->chan)
-			fastrpc_glink_stop(cid);
-		mutex_unlock(&ctx->mut);
+		if (ctx->chan) {
+			fastrpc_glink_close(ctx->chan, cid);
+			ctx->chan = NULL;
+			pr_info("'restart notifier: closed /dev/%s c %d %d'\n",
+				 gcinfo[cid].name, MAJOR(me->dev_no), cid);
+		}
+		mutex_unlock(&me->smd_mutex);
 		if (cid == 0)
 			me->staticpd_flags = 0;
 		fastrpc_notify_drivers(me, cid);
@@ -3071,15 +3056,15 @@
 
 static void fastrpc_deinit(void)
 {
+	struct fastrpc_apps *me = &gfa;
 	struct fastrpc_channel_ctx *chan = gcinfo;
 	int i, j;
 
 	for (i = 0; i < NUM_CHANNELS; i++, chan++) {
 		if (chan->chan) {
 			kref_put_mutex(&chan->kref,
-				fastrpc_channel_close, &chan->mut);
+				fastrpc_channel_close, &me->smd_mutex);
 			chan->chan = NULL;
-			mutex_destroy(&chan->mut);
 		}
 		for (j = 0; j < NUM_SESSIONS; j++) {
 			struct fastrpc_session_ctx *sess = &chan->session[j];
diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index bf9b99d..514c0ad 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -401,8 +401,8 @@
 {
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
 	const struct pll_vco *vco;
-	u32 l, off = pll->offset;
-	u64 a;
+	u32 l = 0, off = pll->offset;
+	u64 a = 0;
 
 	rate = alpha_pll_round_rate(pll, rate, prate, &l, &a);
 	vco = alpha_pll_find_vco(pll, rate);
@@ -668,9 +668,9 @@
 {
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
 	unsigned long rrate;
-	u32 regval, l, off = pll->offset;
-	u64 a;
-	int ret;
+	u32 regval = 0, l = 0, off = pll->offset;
+	u64 a = 0;
+	int ret = 0;
 
 	ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &regval);
 	if (ret)
@@ -1146,8 +1146,8 @@
 	unsigned long rrate;
 	bool is_enabled;
 	int ret;
-	u32 l, val, off = pll->offset;
-	u64 a;
+	u32 l = 0, val = 0, off = pll->offset;
+	u64 a = 0;
 
 	rrate = alpha_pll_round_rate(pll, rate, prate, &l, &a);
 	/*
diff --git a/drivers/clk/qcom/gcc-sdxpoorwills.c b/drivers/clk/qcom/gcc-sdxpoorwills.c
index fcf3601..a62a9a8 100644
--- a/drivers/clk/qcom/gcc-sdxpoorwills.c
+++ b/drivers/clk/qcom/gcc-sdxpoorwills.c
@@ -1353,6 +1353,19 @@
 	},
 };
 
+static struct clk_branch gcc_pcie_0_clkref_clk = {
+	.halt_reg = 0x88004,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x88004,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gcc_pcie_0_clkref_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
 static struct clk_branch gcc_pcie_aux_clk = {
 	.halt_reg = 0x37020,
 	.halt_check = BRANCH_HALT_VOTED,
@@ -1695,14 +1708,26 @@
 	},
 };
 
-static struct clk_branch gcc_usb3_phy_pipe_clk = {
-	.halt_reg = 0xb054,
-	.halt_check = BRANCH_HALT,
+static struct clk_gate2 gcc_usb3_phy_pipe_clk = {
+	.udelay = 500,
 	.clkr = {
 		.enable_reg = 0xb054,
 		.enable_mask = BIT(0),
 		.hw.init = &(struct clk_init_data){
 			.name = "gcc_usb3_phy_pipe_clk",
+			.ops = &clk_gate2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb3_prim_clkref_clk = {
+	.halt_reg = 0x88000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x88000,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gcc_usb3_prim_clkref_clk",
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -1782,6 +1807,7 @@
 	[GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr,
 	[GCC_MSS_GPLL0_DIV_CLK_SRC] = &gcc_mss_gpll0_div_clk_src.clkr,
 	[GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr,
+	[GCC_PCIE_0_CLKREF_CLK] = &gcc_pcie_0_clkref_clk.clkr,
 	[GCC_PCIE_AUX_CLK] = &gcc_pcie_aux_clk.clkr,
 	[GCC_PCIE_AUX_PHY_CLK_SRC] = &gcc_pcie_aux_phy_clk_src.clkr,
 	[GCC_PCIE_CFG_AHB_CLK] = &gcc_pcie_cfg_ahb_clk.clkr,
@@ -1813,6 +1839,7 @@
 	[GCC_USB3_PHY_AUX_CLK] = &gcc_usb3_phy_aux_clk.clkr,
 	[GCC_USB3_PHY_AUX_CLK_SRC] = &gcc_usb3_phy_aux_clk_src.clkr,
 	[GCC_USB3_PHY_PIPE_CLK] = &gcc_usb3_phy_pipe_clk.clkr,
+	[GCC_USB3_PRIM_CLKREF_CLK] = &gcc_usb3_prim_clkref_clk.clkr,
 	[GCC_USB_PHY_CFG_AHB2PHY_CLK] = &gcc_usb_phy_cfg_ahb2phy_clk.clkr,
 	[GPLL0] = &gpll0.clkr,
 	[GPLL0_OUT_EVEN] = &gpll0_out_even.clkr,
@@ -1837,6 +1864,8 @@
 	[GCC_SDCC1_BCR] = { 0xf000 },
 	[GCC_SPMI_FETCHER_BCR] = { 0x3f000 },
 	[GCC_USB30_BCR] = { 0xb000 },
+	[GCC_USB3_PHY_BCR] = { 0xc000 },
+	[GCC_USB3PHY_PHY_BCR] = { 0xc004 },
 	[GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0xe000 },
 };
 
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c
index 0ddb47f..f2c2985 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c
@@ -83,6 +83,7 @@
 			dsi_ctrl_hw_14_reg_dump_to_buffer;
 		ctrl->ops.schedule_dma_cmd = NULL;
 		ctrl->ops.get_cont_splash_status = NULL;
+		ctrl->ops.kickoff_command_non_embedded_mode = NULL;
 		break;
 	case DSI_CTRL_VERSION_2_0:
 		ctrl->ops.setup_lane_map = dsi_ctrl_hw_20_setup_lane_map;
@@ -97,6 +98,7 @@
 		ctrl->ops.clamp_disable = NULL;
 		ctrl->ops.schedule_dma_cmd = NULL;
 		ctrl->ops.get_cont_splash_status = NULL;
+		ctrl->ops.kickoff_command_non_embedded_mode = NULL;
 		break;
 	case DSI_CTRL_VERSION_2_2:
 		ctrl->ops.phy_reset_config = dsi_ctrl_hw_22_phy_reset_config;
@@ -113,6 +115,8 @@
 		ctrl->ops.clamp_enable = NULL;
 		ctrl->ops.clamp_disable = NULL;
 		ctrl->ops.schedule_dma_cmd = dsi_ctrl_hw_22_schedule_dma_cmd;
+		ctrl->ops.kickoff_command_non_embedded_mode =
+			dsi_ctrl_hw_kickoff_non_embedded_mode;
 		break;
 	default:
 		break;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h
index 735f61f..f7756dc 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h
@@ -213,6 +213,9 @@
 ssize_t dsi_ctrl_hw_20_reg_dump_to_buffer(struct dsi_ctrl_hw *ctrl,
 					  char *buf,
 					  u32 size);
+void dsi_ctrl_hw_kickoff_non_embedded_mode(struct dsi_ctrl_hw *ctrl,
+					struct dsi_ctrl_cmd_dma_info *cmd,
+					u32 flags);
 
 /* Definitions specific to 2.2 DSI controller hardware */
 bool dsi_ctrl_hw_22_get_cont_splash_status(struct dsi_ctrl_hw *ctrl);
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index 1f10e3c..609ae52 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -940,6 +940,62 @@
 	udelay(sleep_ms * 1000);
 }
 
+void dsi_message_setup_tx_mode(struct dsi_ctrl *dsi_ctrl,
+		u32 cmd_len,
+		u32 *flags)
+{
+	/**
+	 * Setup the mode of transmission
+	 * override cmd fetch mode during secure session
+	 */
+	if (dsi_ctrl->secure_mode) {
+		*flags &= ~DSI_CTRL_CMD_FETCH_MEMORY;
+		*flags |= DSI_CTRL_CMD_FIFO_STORE;
+		pr_debug("[%s] override to TPG during secure session\n",
+				dsi_ctrl->name);
+		return;
+	}
+
+	/* Check to see if cmd len plus header is greater than fifo size */
+	if ((cmd_len + 4) > DSI_EMBEDDED_MODE_DMA_MAX_SIZE_BYTES) {
+		*flags |= DSI_CTRL_CMD_NON_EMBEDDED_MODE;
+		pr_debug("[%s] override to non-embedded mode,cmd len =%d\n",
+				dsi_ctrl->name, cmd_len);
+		return;
+	}
+}
+
+int dsi_message_validate_tx_mode(struct dsi_ctrl *dsi_ctrl,
+		u32 cmd_len,
+		u32 *flags)
+{
+	int rc = 0;
+
+	if (*flags & DSI_CTRL_CMD_FIFO_STORE) {
+		/* if command size plus header is greater than fifo size */
+		if ((cmd_len + 4) > DSI_CTRL_MAX_CMD_FIFO_STORE_SIZE) {
+			pr_err("Cannot transfer Cmd in FIFO config\n");
+			return -ENOTSUPP;
+		}
+		if (!dsi_ctrl->hw.ops.kickoff_fifo_command) {
+			pr_err("Cannot transfer command,ops not defined\n");
+			return -ENOTSUPP;
+		}
+	}
+
+	if (*flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+		if (*flags & DSI_CTRL_CMD_BROADCAST) {
+			pr_err("Non embedded not supported with broadcast\n");
+			return -ENOTSUPP;
+		}
+		if (!dsi_ctrl->hw.ops.kickoff_command_non_embedded_mode) {
+			pr_err(" Cannot transfer command,ops not defined\n");
+			return -ENOTSUPP;
+		}
+	}
+	return rc;
+}
+
 static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
 			  const struct mipi_dsi_msg *msg,
 			  u32 flags)
@@ -955,12 +1011,34 @@
 	u8 *cmdbuf;
 	struct dsi_mode_info *timing;
 
-	/* override cmd fetch mode during secure session */
-	if (dsi_ctrl->secure_mode) {
-		flags &= ~DSI_CTRL_CMD_FETCH_MEMORY;
-		flags |= DSI_CTRL_CMD_FIFO_STORE;
-		pr_debug("[%s] override to TPG during secure session\n",
-				dsi_ctrl->name);
+	/* Select the tx mode to transfer the command */
+	dsi_message_setup_tx_mode(dsi_ctrl, msg->tx_len, &flags);
+
+	/* Validate the mode before sending the command */
+	rc = dsi_message_validate_tx_mode(dsi_ctrl, msg->tx_len, &flags);
+	if (rc) {
+		pr_err(" Cmd tx validation failed, cannot transfer cmd\n");
+		rc = -ENOTSUPP;
+		goto error;
+	}
+
+	if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+		cmd_mem.offset = dsi_ctrl->cmd_buffer_iova;
+		cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ?
+			true : false;
+		cmd_mem.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ?
+			true : false;
+		cmd_mem.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ?
+			true : false;
+		cmd_mem.datatype = msg->type;
+		cmd_mem.length = msg->tx_len;
+
+		dsi_ctrl->cmd_len = msg->tx_len;
+		memcpy(dsi_ctrl->vaddr, msg->tx_buf, msg->tx_len);
+		pr_debug(" non-embedded mode , size of command =%zd\n",
+					msg->tx_len);
+
+		goto kickoff;
 	}
 
 	rc = mipi_dsi_create_packet(&packet, msg);
@@ -969,16 +1047,6 @@
 		goto error;
 	}
 
-	/* fail cmds more than the supported size in TPG mode */
-	if ((flags & DSI_CTRL_CMD_FIFO_STORE) &&
-			(msg->tx_len > DSI_CTRL_MAX_CMD_FIFO_STORE_SIZE)) {
-		pr_err("[%s] TPG cmd size:%zd not supported, secure:%d\n",
-				dsi_ctrl->name, msg->tx_len,
-				dsi_ctrl->secure_mode);
-		rc = -ENOTSUPP;
-		goto error;
-	}
-
 	rc = dsi_ctrl_copy_and_pad_cmd(dsi_ctrl,
 			&packet,
 			&buffer,
@@ -993,6 +1061,7 @@
 		buffer[3] |= BIT(7);//set the last cmd bit in header.
 
 	if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
+		/* Embedded mode config is selected */
 		cmd_mem.offset = dsi_ctrl->cmd_buffer_iova;
 		cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ?
 			true : false;
@@ -1026,6 +1095,7 @@
 				  true : false;
 	}
 
+kickoff:
 	timing = &(dsi_ctrl->host_config.video_timing);
 	if (timing)
 		line_no += timing->v_back_porch + timing->v_sync_width +
@@ -1045,9 +1115,18 @@
 
 	if (flags & DSI_CTRL_CMD_DEFER_TRIGGER) {
 		if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
-			dsi_ctrl->hw.ops.kickoff_command(&dsi_ctrl->hw,
+			if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+				dsi_ctrl->hw.ops.
+					kickoff_command_non_embedded_mode(
+							&dsi_ctrl->hw,
 							&cmd_mem,
 							hw_flags);
+			} else {
+				dsi_ctrl->hw.ops.kickoff_command(
+						&dsi_ctrl->hw,
+						&cmd_mem,
+						hw_flags);
+			}
 		} else if (flags & DSI_CTRL_CMD_FIFO_STORE) {
 			dsi_ctrl->hw.ops.kickoff_fifo_command(&dsi_ctrl->hw,
 							      &cmd,
@@ -1065,9 +1144,18 @@
 		reinit_completion(&dsi_ctrl->irq_info.cmd_dma_done);
 
 		if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
-			dsi_ctrl->hw.ops.kickoff_command(&dsi_ctrl->hw,
-						      &cmd_mem,
-						      hw_flags);
+			if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+				dsi_ctrl->hw.ops.
+					kickoff_command_non_embedded_mode(
+							&dsi_ctrl->hw,
+							&cmd_mem,
+							hw_flags);
+			} else {
+				dsi_ctrl->hw.ops.kickoff_command(
+						&dsi_ctrl->hw,
+						&cmd_mem,
+						hw_flags);
+			}
 		} else if (flags & DSI_CTRL_CMD_FIFO_STORE) {
 			dsi_ctrl->hw.ops.kickoff_fifo_command(&dsi_ctrl->hw,
 							      &cmd,
@@ -1106,6 +1194,16 @@
 			dsi_ctrl->hw.ops.mask_error_intr(&dsi_ctrl->hw,
 					BIT(DSI_FIFO_OVERFLOW), false);
 		dsi_ctrl->hw.ops.reset_cmd_fifo(&dsi_ctrl->hw);
+
+		/*
+		 * DSI 2.2 needs a soft reset whenever we send non-embedded
+		 * mode command followed by embedded mode. Otherwise it will
+		 * result in smmu write faults with DSI as client.
+		 */
+		if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+			dsi_ctrl->hw.ops.soft_reset(&dsi_ctrl->hw);
+			dsi_ctrl->cmd_len = 0;
+		}
 	}
 error:
 	if (buffer)
@@ -2682,6 +2780,11 @@
 		if (dsi_ctrl->hw.ops.mask_error_intr)
 			dsi_ctrl->hw.ops.mask_error_intr(&dsi_ctrl->hw,
 					BIT(DSI_FIFO_OVERFLOW), false);
+
+		if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
+			dsi_ctrl->hw.ops.soft_reset(&dsi_ctrl->hw);
+			dsi_ctrl->cmd_len = 0;
+		}
 	}
 
 	mutex_unlock(&dsi_ctrl->ctrl_lock);
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
index f5b08a0..80b91ca 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
@@ -37,6 +37,7 @@
  *				   and transfer it.
  * @DSI_CTRL_CMD_LAST_COMMAND:     Trigger the DMA cmd transfer if this is last
  *				   command in the batch.
+ * @DSI_CTRL_CMD_NON_EMBEDDED_MODE:Trasfer cmd packets in non embedded mode.
  */
 #define DSI_CTRL_CMD_READ             0x1
 #define DSI_CTRL_CMD_BROADCAST        0x2
@@ -45,6 +46,12 @@
 #define DSI_CTRL_CMD_FIFO_STORE       0x10
 #define DSI_CTRL_CMD_FETCH_MEMORY     0x20
 #define DSI_CTRL_CMD_LAST_COMMAND     0x40
+#define DSI_CTRL_CMD_NON_EMBEDDED_MODE 0x80
+
+/* DSI embedded mode fifo size
+ * If the command is greater than 256 bytes it is sent in non-embedded mode.
+ */
+#define DSI_EMBEDDED_MODE_DMA_MAX_SIZE_BYTES 256
 
 /* max size supported for dsi cmd transfer using TPG */
 #define DSI_CTRL_MAX_CMD_FIFO_STORE_SIZE 64
@@ -680,4 +687,20 @@
  */
 int dsi_ctrl_vid_engine_en(struct dsi_ctrl *dsi_ctrl, bool on);
 
+/**
+ * @dsi_ctrl:        DSI controller handle.
+ * cmd_len:	     Length of command.
+ * flags:	     Config mode flags.
+ */
+void dsi_message_setup_tx_mode(struct dsi_ctrl *dsi_ctrl, u32 cmd_len,
+		u32 *flags);
+
+/**
+ * @dsi_ctrl:        DSI controller handle.
+ * cmd_len:	     Length of command.
+ * flags:	     Config mode flags.
+ */
+int dsi_message_validate_tx_mode(struct dsi_ctrl *dsi_ctrl, u32 cmd_len,
+		u32 *flags);
+
 #endif /* _DSI_CTRL_H_ */
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h
index c77065c..567f289 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h
@@ -296,6 +296,7 @@
  * struct dsi_ctrl_cmd_dma_info - command buffer information
  * @offset:        IOMMU VA for command buffer address.
  * @length:        Length of the command buffer.
+ * @datatype:      Datatype of cmd.
  * @en_broadcast:  Enable broadcast mode if set to true.
  * @is_master:     Is master in broadcast mode.
  * @use_lpm:       Use low power mode for command transmission.
@@ -303,6 +304,7 @@
 struct dsi_ctrl_cmd_dma_info {
 	u32 offset;
 	u32 length;
+	u8  datatype;
 	bool en_broadcast;
 	bool is_master;
 	bool use_lpm;
@@ -497,6 +499,25 @@
 				u32 flags);
 
 	/**
+	 * kickoff_command_non_embedded_mode() - cmd in non embedded mode
+	 * @ctrl:          Pointer to the controller host hardware.
+	 * @cmd:           Command information.
+	 * @flags:         Modifiers for command transmission.
+	 *
+	 * If command length is greater than DMA FIFO size of 256 bytes we use
+	 * this non- embedded mode.
+	 * The controller hardware is programmed with address and size of the
+	 * command buffer. The transmission is kicked off if
+	 * DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER flag is not set. If this flag is
+	 * set, caller should make a separate call to trigger_command_dma() to
+	 * transmit the command.
+	 */
+
+	void (*kickoff_command_non_embedded_mode)(struct dsi_ctrl_hw *ctrl,
+				struct dsi_ctrl_cmd_dma_info *cmd,
+				u32 flags);
+
+	/**
 	 * kickoff_fifo_command() - transmits a command using FIFO in dsi
 	 *                          hardware.
 	 * @ctrl:          Pointer to the controller host hardware.
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_2_2.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_2_2.c
index 650c2e0..d94d6f7b 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_2_2.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_2_2.c
@@ -79,3 +79,48 @@
 	reg = DSI_R32(ctrl, DSI_SCRATCH_REGISTER_1);
 	return reg == 0x1 ? true : false;
 }
+
+/*
+ * dsi_ctrl_hw_kickoff_non_embedded_mode()-Kickoff cmd  in non-embedded mode
+ * @ctrl:                  - Pointer to the controller host hardware.
+ * @dsi_ctrl_cmd_dma_info: - command buffer information.
+ * @flags:		   - DSI CTRL Flags.
+ */
+void dsi_ctrl_hw_kickoff_non_embedded_mode(struct dsi_ctrl_hw *ctrl,
+				    struct dsi_ctrl_cmd_dma_info *cmd,
+				    u32 flags)
+{
+	u32 reg = 0;
+
+	reg = DSI_R32(ctrl, DSI_COMMAND_MODE_DMA_CTRL);
+
+	reg &= ~BIT(31);/* disable broadcast */
+	reg &= ~BIT(30);
+
+	if (cmd->use_lpm)
+		reg |= BIT(26);
+	else
+		reg &= ~BIT(26);
+
+	/* Select non EMBEDDED_MODE, pick the packet header from register */
+	reg &= ~BIT(28);
+	reg |= BIT(24);/* long packet */
+	reg |= BIT(29);/* wc_sel = 1 */
+	reg |= (((cmd->datatype) & 0x03f) << 16);/* data type */
+	DSI_W32(ctrl, DSI_COMMAND_MODE_DMA_CTRL, reg);
+
+	/* Enable WRITE_WATERMARK_DISABLE and READ_WATERMARK_DISABLE bits */
+	reg = DSI_R32(ctrl, DSI_DMA_FIFO_CTRL);
+	reg |= BIT(20);
+	reg |= BIT(16);
+	DSI_W32(ctrl, DSI_DMA_FIFO_CTRL, reg);
+
+	DSI_W32(ctrl, DSI_DMA_CMD_OFFSET, cmd->offset);
+	DSI_W32(ctrl, DSI_DMA_CMD_LENGTH, ((cmd->length) & 0xFFFFFF));
+
+	/* wait for writes to complete before kick off */
+	wmb();
+
+	if (!(flags & DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER))
+		DSI_W32(ctrl, DSI_CMD_MODE_DMA_SW_TRIGGER, 0x1);
+}
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
index c2c8f57..c753c80 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
@@ -612,9 +612,17 @@
 	else
 		reg &= ~BIT(26);
 
-	reg |= BIT(28);
+	reg |= BIT(28);/* Select embedded mode */
+	reg &= ~BIT(24);/* packet type */
+	reg &= ~BIT(29);/* WC_SEL to 0 */
 	DSI_W32(ctrl, DSI_COMMAND_MODE_DMA_CTRL, reg);
 
+	reg = DSI_R32(ctrl, DSI_DMA_FIFO_CTRL);
+	reg &= ~BIT(20);/* Enable write watermark*/
+	reg &= ~BIT(16);/* Enable read watermark */
+
+
+	DSI_W32(ctrl, DSI_DMA_FIFO_CTRL, reg);
 	DSI_W32(ctrl, DSI_DMA_CMD_OFFSET, cmd->offset);
 	DSI_W32(ctrl, DSI_DMA_CMD_LENGTH, (cmd->length & 0xFFFFFF));
 
diff --git a/drivers/gpu/drm/msm/sde/sde_core_perf.c b/drivers/gpu/drm/msm/sde/sde_core_perf.c
index 6b36745..3879d4d 100644
--- a/drivers/gpu/drm/msm/sde/sde_core_perf.c
+++ b/drivers/gpu/drm/msm/sde/sde_core_perf.c
@@ -170,6 +170,15 @@
 	}
 
 	SDE_EVT32(crtc->base.id, perf->core_clk_rate);
+	trace_sde_perf_calc_crtc(crtc->base.id,
+			perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC],
+			perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_LLCC],
+			perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_EBI],
+			perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_MNOC],
+			perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_LLCC],
+			perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_EBI],
+			perf->core_clk_rate);
+
 	SDE_DEBUG(
 		"crtc=%d clk_rate=%llu core_ib=%llu core_ab=%llu llcc_ib=%llu llcc_ab=%llu mem_ib=%llu mem_ab=%llu\n",
 			crtc->base.id, perf->core_clk_rate,
@@ -552,19 +561,32 @@
 			 * 2. new bandwidth vote - "ab or ib vote" is lower
 			 *    than current vote at end of commit or stop.
 			 */
-			if ((params_changed && ((new->bw_ctl[i] >
-						old->bw_ctl[i]) ||
-				  (new->max_per_pipe_ib[i] >
-						old->max_per_pipe_ib[i]))) ||
-			    (!params_changed && ((new->bw_ctl[i] <
-						old->bw_ctl[i]) ||
-				  (new->max_per_pipe_ib[i] <
-						old->max_per_pipe_ib[i])))) {
+
+			if ((params_changed &&
+				(new->bw_ctl[i] > old->bw_ctl[i])) ||
+			    (!params_changed &&
+				(new->bw_ctl[i] < old->bw_ctl[i]))) {
+
 				SDE_DEBUG(
 					"crtc=%d p=%d new_bw=%llu,old_bw=%llu\n",
 					crtc->base.id, params_changed,
 					new->bw_ctl[i], old->bw_ctl[i]);
 				old->bw_ctl[i] = new->bw_ctl[i];
+				update_bus |= BIT(i);
+			}
+
+			if ((params_changed &&
+				(new->max_per_pipe_ib[i] >
+				 old->max_per_pipe_ib[i])) ||
+			    (!params_changed &&
+				(new->max_per_pipe_ib[i] <
+				old->max_per_pipe_ib[i]))) {
+
+				SDE_DEBUG(
+					"crtc=%d p=%d new_ib=%llu,old_ib=%llu\n",
+					crtc->base.id, params_changed,
+					new->max_per_pipe_ib[i],
+					old->max_per_pipe_ib[i]);
 				old->max_per_pipe_ib[i] =
 						new->max_per_pipe_ib[i];
 				update_bus |= BIT(i);
@@ -608,11 +630,14 @@
 		update_clk = 1;
 	}
 	trace_sde_perf_crtc_update(crtc->base.id,
-				new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC],
-				new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_LLCC],
-				new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_EBI],
-				new->core_clk_rate, stop_req,
-				update_bus, update_clk);
+		new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC],
+		new->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_MNOC],
+		new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_LLCC],
+		new->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_LLCC],
+		new->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_EBI],
+		new->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_EBI],
+		new->core_clk_rate, stop_req,
+		update_bus, update_clk, params_changed);
 
 	for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++) {
 		if (update_bus & BIT(i))
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index df65ea3..b6888df 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -1512,6 +1512,7 @@
 	struct drm_crtc *primary_crtc;
 	int pipe = -1;
 	int rc = 0;
+	int wait_refcount;
 
 	if (!drm_enc || !drm_enc->dev) {
 		SDE_ERROR("invalid encoder arguments\n");
@@ -1599,6 +1600,12 @@
 		return ret;
 	}
 
+	if (wait_vblank_crtc_id)
+		wait_refcount =
+			sde_rsc_client_get_vsync_refcount(sde_enc->rsc_client);
+	SDE_EVT32_VERBOSE(DRMID(drm_enc), wait_vblank_crtc_id, wait_refcount,
+			SDE_EVTLOG_FUNC_ENTRY);
+
 	if (crtc->base.id != wait_vblank_crtc_id) {
 		primary_crtc = drm_crtc_find(drm_enc->dev, wait_vblank_crtc_id);
 		if (!primary_crtc) {
@@ -1636,6 +1643,11 @@
 		SDE_EVT32(DRMID(drm_enc), wait_vblank_crtc_id, wait_count,
 				SDE_EVTLOG_ERROR);
 
+	if (wait_refcount)
+		sde_rsc_client_reset_vsync_refcount(sde_enc->rsc_client);
+	SDE_EVT32_VERBOSE(DRMID(drm_enc), wait_vblank_crtc_id, wait_refcount,
+			SDE_EVTLOG_FUNC_EXIT);
+
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/msm/sde/sde_trace.h b/drivers/gpu/drm/msm/sde/sde_trace.h
index ef4cdeb..2909778 100644
--- a/drivers/gpu/drm/msm/sde/sde_trace.h
+++ b/drivers/gpu/drm/msm/sde/sde_trace.h
@@ -93,21 +93,24 @@
 )
 
 TRACE_EVENT(sde_perf_update_bus,
-	TP_PROTO(int client, unsigned long long ab_quota,
+	TP_PROTO(int client, u32 bus_id, unsigned long long ab_quota,
 	unsigned long long ib_quota),
-	TP_ARGS(client, ab_quota, ib_quota),
+	TP_ARGS(client, bus_id, ab_quota, ib_quota),
 	TP_STRUCT__entry(
 			__field(int, client)
+			__field(u32, bus_id);
 			__field(u64, ab_quota)
 			__field(u64, ib_quota)
 	),
 	TP_fast_assign(
 			__entry->client = client;
+			__entry->bus_id = bus_id;
 			__entry->ab_quota = ab_quota;
 			__entry->ib_quota = ib_quota;
 	),
-	TP_printk("Request client:%d ab=%llu ib=%llu",
+	TP_printk("Request client:%d bus_id:%d ab=%llu ib=%llu",
 			__entry->client,
+			__entry->bus_id,
 			__entry->ab_quota,
 			__entry->ib_quota)
 )
@@ -209,41 +212,111 @@
 )
 
 TRACE_EVENT(sde_perf_crtc_update,
-	TP_PROTO(u32 crtc, u64 bw_ctl_mnoc, u64 bw_ctl_llcc,
-			u64 bw_ctl_ebi, u32 core_clk_rate,
-			bool stop_req, u32 update_bus, u32 update_clk),
-	TP_ARGS(crtc, bw_ctl_mnoc, bw_ctl_llcc, bw_ctl_ebi, core_clk_rate,
-		stop_req, update_bus, update_clk),
+	TP_PROTO(u32 crtc,
+			u64 bw_ctl_mnoc, u64 per_pipe_ib_mnoc,
+			u64 bw_ctl_llcc, u64 per_pipe_ib_llcc,
+			u64 bw_ctl_ebi, u64 per_pipe_ib_ebi,
+			u32 core_clk_rate, bool stop_req,
+			u32 update_bus, u32 update_clk, int params),
+	TP_ARGS(crtc,
+		bw_ctl_mnoc, per_pipe_ib_mnoc,
+		bw_ctl_llcc, per_pipe_ib_llcc,
+		bw_ctl_ebi, per_pipe_ib_ebi,
+		core_clk_rate, stop_req,
+		update_bus, update_clk, params),
+	TP_STRUCT__entry(
+			__field(u32, crtc)
+			__field(u64, bw_ctl_mnoc)
+			__field(u64, per_pipe_ib_mnoc)
+			__field(u64, bw_ctl_llcc)
+			__field(u64, per_pipe_ib_llcc)
+			__field(u64, bw_ctl_ebi)
+			__field(u64, per_pipe_ib_ebi)
+			__field(u32, core_clk_rate)
+			__field(bool, stop_req)
+			__field(u32, update_bus)
+			__field(u32, update_clk)
+			__field(int, params)
+	),
+	TP_fast_assign(
+			__entry->crtc = crtc;
+			__entry->bw_ctl_mnoc = bw_ctl_mnoc;
+			__entry->per_pipe_ib_mnoc = per_pipe_ib_mnoc;
+			__entry->bw_ctl_llcc = bw_ctl_llcc;
+			__entry->per_pipe_ib_llcc = per_pipe_ib_llcc;
+			__entry->bw_ctl_ebi = bw_ctl_ebi;
+			__entry->per_pipe_ib_ebi = per_pipe_ib_ebi;
+			__entry->core_clk_rate = core_clk_rate;
+			__entry->stop_req = stop_req;
+			__entry->update_bus = update_bus;
+			__entry->update_clk = update_clk;
+			__entry->params = params;
+	),
+	 TP_printk(
+		"crtc=%d mnoc=[%llu %llu] llcc=[%llu %llu] ebi=[%llu %llu] clk=%u stop=%d ubus=%d uclk=%d %d",
+			__entry->crtc,
+			__entry->bw_ctl_mnoc,
+			__entry->per_pipe_ib_mnoc,
+			__entry->bw_ctl_llcc,
+			__entry->per_pipe_ib_llcc,
+			__entry->bw_ctl_ebi,
+			__entry->per_pipe_ib_ebi,
+			__entry->core_clk_rate,
+			__entry->stop_req,
+			__entry->update_bus,
+			__entry->update_clk,
+			__entry->params)
+);
+
+TRACE_EVENT(sde_perf_calc_crtc,
+	TP_PROTO(u32 crtc,
+			u64 bw_ctl_mnoc,
+			u64 bw_ctl_llcc,
+			u64 bw_ctl_ebi,
+			u64 ib_mnoc,
+			u64 ib_llcc,
+			u64 ib_ebi,
+			u32 core_clk_rate
+			),
+	TP_ARGS(crtc,
+			bw_ctl_mnoc,
+			bw_ctl_llcc,
+			bw_ctl_ebi,
+			ib_mnoc,
+			ib_llcc,
+			ib_ebi,
+			core_clk_rate),
 	TP_STRUCT__entry(
 			__field(u32, crtc)
 			__field(u64, bw_ctl_mnoc)
 			__field(u64, bw_ctl_llcc)
 			__field(u64, bw_ctl_ebi)
+			__field(u64, ib_mnoc)
+			__field(u64, ib_llcc)
+			__field(u64, ib_ebi)
 			__field(u32, core_clk_rate)
-			__field(bool, stop_req)
-			__field(u32, update_bus)
-			__field(u32, update_clk)
+
 	),
 	TP_fast_assign(
 			__entry->crtc = crtc;
 			__entry->bw_ctl_mnoc = bw_ctl_mnoc;
 			__entry->bw_ctl_llcc = bw_ctl_llcc;
 			__entry->bw_ctl_ebi = bw_ctl_ebi;
+			__entry->ib_mnoc = ib_mnoc;
+			__entry->ib_llcc = ib_llcc;
+			__entry->ib_ebi = ib_ebi;
 			__entry->core_clk_rate = core_clk_rate;
-			__entry->stop_req = stop_req;
-			__entry->update_bus = update_bus;
-			__entry->update_clk = update_clk;
 	),
 	 TP_printk(
-		"crtc=%d bw_mnoc=%llu bw_llcc=%llu bw_ebi=%llu clk_rate=%u stop_req=%d u_bus=%d u_clk=%d",
+		"crtc=%d mnoc=[%llu, %llu] llcc=[%llu %llu] ebi=[%llu, %llu] clk_rate=%u",
 			__entry->crtc,
 			__entry->bw_ctl_mnoc,
+			__entry->ib_mnoc,
 			__entry->bw_ctl_llcc,
+			__entry->ib_llcc,
 			__entry->bw_ctl_ebi,
-			__entry->core_clk_rate,
-			__entry->stop_req,
-			__entry->update_bus,
-			__entry->update_clk)
+			__entry->ib_ebi,
+			__entry->core_clk_rate)
 );
 
 #define SDE_ATRACE_END(name) trace_tracing_mark_write(current->tgid, name, 0)
diff --git a/drivers/gpu/drm/msm/sde_power_handle.c b/drivers/gpu/drm/msm/sde_power_handle.c
index 34a826d..4244c00 100644
--- a/drivers/gpu/drm/msm/sde_power_handle.c
+++ b/drivers/gpu/drm/msm/sde_power_handle.c
@@ -470,7 +470,7 @@
 
 	pclient->ab[bus_client] = ab_quota;
 	pclient->ib[bus_client] = ib_quota;
-	trace_sde_perf_update_bus(bus_client, ab_quota, ib_quota);
+	trace_sde_perf_update_bus(bus_client, bus_id, ab_quota, ib_quota);
 
 	list_for_each_entry(client, &phandle->power_client_clist, list) {
 		for (i = 0; i < SDE_POWER_HANDLE_DATA_BUS_CLIENT_MAX; i++) {
diff --git a/drivers/gpu/drm/msm/sde_rsc.c b/drivers/gpu/drm/msm/sde_rsc.c
index 82b1199..429ab01 100644
--- a/drivers/gpu/drm/msm/sde_rsc.c
+++ b/drivers/gpu/drm/msm/sde_rsc.c
@@ -561,6 +561,23 @@
 			msleep(PRIMARY_VBLANK_WORST_CASE_MS);
 		} else {
 			*wait_vblank_crtc_id = rsc->primary_client->crtc_id;
+
+			/* increase refcount, so we wait for the next vsync */
+			atomic_inc(&rsc->rsc_vsync_wait);
+			SDE_EVT32(atomic_read(&rsc->rsc_vsync_wait));
+		}
+	} else if (atomic_read(&rsc->rsc_vsync_wait)) {
+		SDE_EVT32(rsc->primary_client, rsc->current_state,
+			atomic_read(&rsc->rsc_vsync_wait));
+
+		/* Wait for the vsync, if the refcount is set */
+		rc = wait_event_timeout(rsc->rsc_vsync_waitq,
+			atomic_read(&rsc->rsc_vsync_wait) == 0,
+			msecs_to_jiffies(PRIMARY_VBLANK_WORST_CASE_MS*2));
+		if (!rc) {
+			pr_err("Timeout waiting for vsync\n");
+			SDE_EVT32(atomic_read(&rsc->rsc_vsync_wait),
+				SDE_EVTLOG_ERROR);
 		}
 	}
 end:
@@ -600,6 +617,23 @@
 			msleep(PRIMARY_VBLANK_WORST_CASE_MS);
 		} else {
 			*wait_vblank_crtc_id = rsc->primary_client->crtc_id;
+
+			/* increase refcount, so we wait for the next vsync */
+			atomic_inc(&rsc->rsc_vsync_wait);
+			SDE_EVT32(atomic_read(&rsc->rsc_vsync_wait));
+		}
+	} else if (atomic_read(&rsc->rsc_vsync_wait)) {
+		SDE_EVT32(rsc->primary_client, rsc->current_state,
+			atomic_read(&rsc->rsc_vsync_wait));
+
+		/* Wait for the vsync, if the refcount is set */
+		rc = wait_event_timeout(rsc->rsc_vsync_waitq,
+			atomic_read(&rsc->rsc_vsync_wait) == 0,
+			msecs_to_jiffies(PRIMARY_VBLANK_WORST_CASE_MS*2));
+		if (!rc) {
+			pr_err("Timeout waiting for vsync\n");
+			SDE_EVT32(atomic_read(&rsc->rsc_vsync_wait),
+				SDE_EVTLOG_ERROR);
 		}
 	}
 
@@ -608,6 +642,65 @@
 }
 
 /**
+ * sde_rsc_client_get_vsync_refcount() - returns the status of the vsync
+ * refcount, to signal if the client needs to reset the refcounting logic
+ * @client:	 Client pointer provided by sde_rsc_client_create().
+ *
+ * Return: value of the vsync refcount.
+ */
+int sde_rsc_client_get_vsync_refcount(
+		struct sde_rsc_client *caller_client)
+{
+	struct sde_rsc_priv *rsc;
+
+	if (!caller_client) {
+		pr_err("invalid client for rsc state update\n");
+		return -EINVAL;
+	} else if (caller_client->rsc_index >= MAX_RSC_COUNT) {
+		pr_err("invalid rsc index\n");
+		return -EINVAL;
+	}
+
+	rsc = rsc_prv_list[caller_client->rsc_index];
+	if (!rsc)
+		return 0;
+
+	return atomic_read(&rsc->rsc_vsync_wait);
+}
+
+/**
+ * sde_rsc_client_reset_vsync_refcount() - reduces the refcounting
+ * logic that waits for the vsync.
+ * @client:	 Client pointer provided by sde_rsc_client_create().
+ *
+ * Return: zero if refcount was already zero.
+ */
+int sde_rsc_client_reset_vsync_refcount(
+		struct sde_rsc_client *caller_client)
+{
+	struct sde_rsc_priv *rsc;
+	int ret;
+
+	if (!caller_client) {
+		pr_err("invalid client for rsc state update\n");
+		return -EINVAL;
+	} else if (caller_client->rsc_index >= MAX_RSC_COUNT) {
+		pr_err("invalid rsc index\n");
+		return -EINVAL;
+	}
+
+	rsc = rsc_prv_list[caller_client->rsc_index];
+	if (!rsc)
+		return 0;
+
+	ret = atomic_add_unless(&rsc->rsc_vsync_wait, -1, 0);
+	wake_up_all(&rsc->rsc_vsync_waitq);
+	SDE_EVT32(atomic_read(&rsc->rsc_vsync_wait));
+
+	return ret;
+}
+
+/**
  * sde_rsc_client_is_state_update_complete() - check if state update is complete
  * RSC state transition is not complete until HW receives VBLANK signal. This
  * function checks RSC HW to determine whether that signal has been received.
@@ -1307,6 +1400,7 @@
 	INIT_LIST_HEAD(&rsc->client_list);
 	INIT_LIST_HEAD(&rsc->event_list);
 	mutex_init(&rsc->client_lock);
+	init_waitqueue_head(&rsc->rsc_vsync_waitq);
 
 	pr_info("sde rsc index:%d probed successfully\n",
 				SDE_RSC_INDEX + counter);
diff --git a/drivers/gpu/drm/msm/sde_rsc_priv.h b/drivers/gpu/drm/msm/sde_rsc_priv.h
index 64b0216..5c62466 100644
--- a/drivers/gpu/drm/msm/sde_rsc_priv.h
+++ b/drivers/gpu/drm/msm/sde_rsc_priv.h
@@ -149,6 +149,8 @@
  *			and ab/ib vote on display rsc
  * master_drm:		Primary client waits for vsync on this drm object based
  *			on crtc id
+ * rsc_vsync_wait:   Refcount to indicate if we have to wait for the vsync.
+ * rsc_vsync_waitq:   Queue to wait for the vsync.
  */
 struct sde_rsc_priv {
 	u32 version;
@@ -177,6 +179,8 @@
 	struct sde_rsc_client *primary_client;
 
 	struct drm_device *master_drm;
+	atomic_t rsc_vsync_wait;
+	wait_queue_head_t rsc_vsync_waitq;
 };
 
 /**
diff --git a/drivers/gpu/msm/adreno_a6xx_snapshot.c b/drivers/gpu/msm/adreno_a6xx_snapshot.c
index 3f92f75..589417f 100644
--- a/drivers/gpu/msm/adreno_a6xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a6xx_snapshot.c
@@ -195,6 +195,35 @@
 	unsigned int ctxt_id;
 };
 
+static const unsigned int a6xx_hlsq_non_ctx_registers[] = {
+	0xBE00, 0xBE01, 0xBE04, 0xBE05, 0xBE08, 0xBE09, 0xBE10, 0xBE15,
+	0xBE20, 0xBE23,
+};
+
+static const unsigned int a6xx_sp_non_ctx_registers[] = {
+	0xAE00, 0xAE04, 0xAE0C, 0xAE0C, 0xAE0F, 0xAE2B, 0xAE30, 0xAE32,
+	0xAE35, 0xAE35, 0xAE3A, 0xAE3F, 0xAE50, 0xAE52,
+};
+
+static const unsigned int a6xx_tp_non_ctx_registers[] = {
+	0xB600, 0xB601, 0xB604, 0xB605, 0xB610, 0xB61B, 0xB620, 0xB623,
+};
+
+static struct a6xx_non_ctx_dbgahb_registers {
+	unsigned int regbase;
+	unsigned int statetype;
+	const unsigned int *regs;
+	unsigned int num_sets;
+	unsigned int offset;
+} a6xx_non_ctx_dbgahb[] = {
+	{ 0x0002F800, 0x40, a6xx_hlsq_non_ctx_registers,
+		ARRAY_SIZE(a6xx_hlsq_non_ctx_registers) / 2 },
+	{ 0x0002B800, 0x20, a6xx_sp_non_ctx_registers,
+		ARRAY_SIZE(a6xx_sp_non_ctx_registers) / 2 },
+	{ 0x0002D800, 0x0, a6xx_tp_non_ctx_registers,
+		ARRAY_SIZE(a6xx_tp_non_ctx_registers) / 2 },
+};
+
 static const unsigned int a6xx_vbif_ver_20xxxxxx_registers[] = {
 	/* VBIF */
 	0x3000, 0x3007, 0x300C, 0x3014, 0x3018, 0x302D, 0x3030, 0x3031,
@@ -308,15 +337,6 @@
 	/* VFD */
 	0xA600, 0xA601, 0xA603, 0xA603, 0xA60A, 0xA60A, 0xA610, 0xA617,
 	0xA630, 0xA630,
-	/* SP */
-	0xAE00, 0xAE04, 0xAE0C, 0xAE0C, 0xAE0F, 0xAE2B, 0xAE30, 0xAE32,
-	0xAE35, 0xAE35, 0xAE3A, 0xAE3F, 0xAE50, 0xAE52,
-	/* TP */
-	0xB600, 0xB601, 0xB604, 0xB605, 0xB610, 0xB61B, 0xB620, 0xB623,
-	/* HLSQ */
-	0xBE00, 0xBE01, 0xBE04, 0xBE05, 0xBE08, 0xBE09, 0xBE10, 0xBE15,
-	0xBE20, 0xBE23,
-
 };
 
 /*
@@ -832,6 +852,106 @@
 	return data_size + sizeof(*header);
 }
 
+static size_t a6xx_legacy_snapshot_non_ctx_dbgahb(struct kgsl_device *device,
+				u8 *buf, size_t remain, void *priv)
+{
+	struct kgsl_snapshot_regs *header =
+				(struct kgsl_snapshot_regs *)buf;
+	struct a6xx_non_ctx_dbgahb_registers *regs =
+				(struct a6xx_non_ctx_dbgahb_registers *)priv;
+	unsigned int *data = (unsigned int *)(buf + sizeof(*header));
+	int count = 0;
+	unsigned int read_sel;
+	int i, j;
+
+	if (!device->snapshot_legacy)
+		return 0;
+
+	/* Figure out how many registers we are going to dump */
+	for (i = 0; i < regs->num_sets; i++) {
+		int start = regs->regs[i * 2];
+		int end = regs->regs[i * 2 + 1];
+
+		count += (end - start + 1);
+	}
+
+	if (remain < (count * 8) + sizeof(*header)) {
+		SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
+		return 0;
+	}
+
+	header->count = count;
+
+	read_sel = (regs->statetype & 0xff) << 8;
+	kgsl_regwrite(device, A6XX_HLSQ_DBG_READ_SEL, read_sel);
+
+	for (i = 0; i < regs->num_sets; i++) {
+		unsigned int start = regs->regs[2 * i];
+		unsigned int end = regs->regs[2 * i + 1];
+
+		for (j = start; j <= end; j++) {
+			unsigned int val;
+
+			val = a6xx_read_dbgahb(device, regs->regbase, j);
+			*data++ = j;
+			*data++ = val;
+
+		}
+	}
+	return (count * 8) + sizeof(*header);
+}
+
+static size_t a6xx_snapshot_non_ctx_dbgahb(struct kgsl_device *device, u8 *buf,
+				size_t remain, void *priv)
+{
+	struct kgsl_snapshot_regs *header =
+				(struct kgsl_snapshot_regs *)buf;
+	struct a6xx_non_ctx_dbgahb_registers *regs =
+				(struct a6xx_non_ctx_dbgahb_registers *)priv;
+	unsigned int count = 0;
+	unsigned int *data = (unsigned int *)(buf + sizeof(*header));
+	unsigned int i, k;
+	unsigned int *src;
+
+	if (crash_dump_valid == false)
+		return a6xx_legacy_snapshot_non_ctx_dbgahb(device, buf, remain,
+				regs);
+
+	if (remain < sizeof(*header)) {
+		SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
+		return 0;
+	}
+
+	remain -= sizeof(*header);
+
+	src = (unsigned int *)(a6xx_crashdump_registers.hostptr + regs->offset);
+
+	for (i = 0; i < regs->num_sets; i++) {
+		unsigned int start;
+		unsigned int end;
+
+		start = regs->regs[2 * i];
+		end = regs->regs[(2 * i) + 1];
+
+		if (remain < (end - start + 1) * 8) {
+			SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
+			goto out;
+		}
+
+		remain -= ((end - start) + 1) * 8;
+
+		for (k = start; k <= end; k++, count++) {
+			*data++ = k;
+			*data++ = *src++;
+		}
+	}
+out:
+	header->count = count;
+
+	/* Return the size of the section */
+	return (count * 8) + sizeof(*header);
+}
+
 static void a6xx_snapshot_dbgahb_regs(struct kgsl_device *device,
 				struct kgsl_snapshot *snapshot)
 {
@@ -851,6 +971,12 @@
 				a6xx_snapshot_cluster_dbgahb, &info);
 		}
 	}
+
+	for (i = 0; i < ARRAY_SIZE(a6xx_non_ctx_dbgahb); i++) {
+		kgsl_snapshot_add_section(device,
+			KGSL_SNAPSHOT_SECTION_REGS, snapshot,
+			a6xx_snapshot_non_ctx_dbgahb, &a6xx_non_ctx_dbgahb[i]);
+	}
 }
 
 static size_t a6xx_legacy_snapshot_mvc(struct kgsl_device *device, u8 *buf,
@@ -1622,6 +1748,40 @@
 	return qwords;
 }
 
+static int _a6xx_crashdump_init_non_ctx_dbgahb(uint64_t *ptr, uint64_t *offset)
+{
+	int qwords = 0;
+	unsigned int i, k;
+	unsigned int count;
+
+	for (i = 0; i < ARRAY_SIZE(a6xx_non_ctx_dbgahb); i++) {
+		struct a6xx_non_ctx_dbgahb_registers *regs =
+				&a6xx_non_ctx_dbgahb[i];
+
+		regs->offset = *offset;
+
+		/* Program the aperture */
+		ptr[qwords++] = (regs->statetype & 0xff) << 8;
+		ptr[qwords++] =	(((uint64_t)A6XX_HLSQ_DBG_READ_SEL << 44)) |
+					(1 << 21) | 1;
+
+		for (k = 0; k < regs->num_sets; k++) {
+			unsigned int start = regs->regs[2 * k];
+
+			count = REG_PAIR_COUNT(regs->regs, k);
+			ptr[qwords++] =
+				a6xx_crashdump_registers.gpuaddr + *offset;
+			ptr[qwords++] =
+				(((uint64_t)(A6XX_HLSQ_DBG_AHB_READ_APERTURE +
+					start - regs->regbase / 4) << 44)) |
+							count;
+
+			*offset += count * sizeof(unsigned int);
+		}
+	}
+	return qwords;
+}
+
 void a6xx_crashdump_init(struct adreno_device *adreno_dev)
 {
 	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
@@ -1713,6 +1873,26 @@
 		}
 	}
 
+	/*
+	 * Calculate the script and data size for non context debug
+	 * AHB registers
+	 */
+	for (i = 0; i < ARRAY_SIZE(a6xx_non_ctx_dbgahb); i++) {
+		struct a6xx_non_ctx_dbgahb_registers *regs =
+				&a6xx_non_ctx_dbgahb[i];
+
+		/* 16 bytes for programming the aperture */
+		script_size += 16;
+
+		/* Reading each pair of registers takes 16 bytes */
+		script_size += 16 * regs->num_sets;
+
+		/* A dword per register read from the cluster list */
+		for (k = 0; k < regs->num_sets; k++)
+			data_size += REG_PAIR_COUNT(regs->regs, k) *
+				sizeof(unsigned int);
+	}
+
 	/* Now allocate the script and data buffers */
 
 	/* The script buffers needs 2 extra qwords on the end */
@@ -1763,6 +1943,8 @@
 
 	ptr += _a6xx_crashdump_init_ctx_dbgahb(ptr, &offset);
 
+	ptr += _a6xx_crashdump_init_non_ctx_dbgahb(ptr, &offset);
+
 	*ptr++ = 0;
 	*ptr++ = 0;
 }
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index b81be8f..6876796 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -424,16 +424,6 @@
 		return ERR_PTR(ret);
 	}
 
-	if (gpudev->preemption_context_init) {
-		ret = gpudev->preemption_context_init(&drawctxt->base);
-		if (ret != 0) {
-			kgsl_context_detach(&drawctxt->base);
-			kgsl_context_put(&drawctxt->base);
-			kfree(drawctxt);
-			return ERR_PTR(ret);
-		}
-	}
-
 	kgsl_sharedmem_writel(device, &device->memstore,
 			KGSL_MEMSTORE_OFFSET(drawctxt->base.id, soptimestamp),
 			0);
@@ -445,6 +435,14 @@
 
 	INIT_LIST_HEAD(&drawctxt->active_node);
 
+	if (gpudev->preemption_context_init) {
+		ret = gpudev->preemption_context_init(&drawctxt->base);
+		if (ret != 0) {
+			kgsl_context_detach(&drawctxt->base);
+			return ERR_PTR(ret);
+		}
+	}
+
 	/* copy back whatever flags we dediced were valid */
 	*flags = drawctxt->base.flags;
 	return &drawctxt->base;
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index ab3ab31..b354ef2 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -796,7 +796,7 @@
 	struct kgsl_iommu_context *ctx;
 	u64 ptbase;
 	u32 contextidr;
-	pid_t tid = 0;
+	pid_t pid = 0;
 	pid_t ptname;
 	struct _mem_entry prev, next;
 	int write;
@@ -851,7 +851,7 @@
 	if (context != NULL) {
 		/* save pagefault timestamp for GFT */
 		set_bit(KGSL_CONTEXT_PRIV_PAGEFAULT, &context->priv);
-		tid = context->tid;
+		pid = context->proc_priv->pid;
 	}
 
 	ctx->fault = 1;
@@ -872,7 +872,7 @@
 	contextidr = KGSL_IOMMU_GET_CTX_REG(ctx, CONTEXTIDR);
 
 	ptname = MMU_FEATURE(mmu, KGSL_MMU_GLOBAL_PAGETABLE) ?
-		KGSL_MMU_GLOBAL_PT : tid;
+		KGSL_MMU_GLOBAL_PT : pid;
 	/*
 	 * Trace needs to be logged before searching the faulting
 	 * address in free list as it takes quite long time in
diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c
index 5bd52e4..1a2aea9 100644
--- a/drivers/leds/leds-qpnp-flash-v2.c
+++ b/drivers/leds/leds-qpnp-flash-v2.c
@@ -731,7 +731,8 @@
 #define FLASH_VDIP_MARGIN	50000
 #define BOB_EFFICIENCY		900LL
 #define VIN_FLASH_MIN_UV	3300000LL
-static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led)
+static int qpnp_flash_led_calc_max_current(struct qpnp_flash_led *led,
+					int *max_current)
 {
 	int ocv_uv, ibat_now, voltage_hdrm_mv, rc;
 	int rbatt_uohm = 0;
@@ -747,8 +748,10 @@
 	}
 
 	/* If no battery is connected, return max possible flash current */
-	if (!rbatt_uohm)
-		return FLASH_LED_MAX_TOTAL_CURRENT_MA;
+	if (!rbatt_uohm) {
+		*max_current = FLASH_LED_MAX_TOTAL_CURRENT_MA;
+		return 0;
+	}
 
 	rc = get_property_from_fg(led, POWER_SUPPLY_PROP_VOLTAGE_OCV, &ocv_uv);
 	if (rc < 0) {
@@ -785,7 +788,7 @@
 		/* Wait for LMH mitigation to take effect */
 		udelay(100);
 
-		return qpnp_flash_led_calc_max_current(led);
+		return qpnp_flash_led_calc_max_current(led, max_current);
 	}
 
 	/*
@@ -825,13 +828,14 @@
 	avail_flash_ua = div64_s64(avail_flash_power_fw, vin_flash_uv * MCONV);
 	pr_debug("avail_iflash=%lld, ocv=%d, ibat=%d, rbatt=%d, trigger_lmh=%d\n",
 		avail_flash_ua, ocv_uv, ibat_now, rbatt_uohm, led->trigger_lmh);
-	return min(FLASH_LED_MAX_TOTAL_CURRENT_MA,
+	*max_current = min(FLASH_LED_MAX_TOTAL_CURRENT_MA,
 			(int)(div64_s64(avail_flash_ua, MCONV)));
+	return 0;
 }
 
-static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led)
+static int qpnp_flash_led_calc_thermal_current_lim(struct qpnp_flash_led *led,
+						int *thermal_current_lim)
 {
-	int thermal_current_lim = 0;
 	int rc;
 	u8 thermal_thrsh1, thermal_thrsh2, thermal_thrsh3, otst_status;
 
@@ -888,7 +892,7 @@
 
 	/* Look up current limit based on THERMAL_OTST status */
 	if (otst_status)
-		thermal_current_lim =
+		*thermal_current_lim =
 			led->pdata->thermal_derate_current[otst_status >> 1];
 
 	/* Restore THERMAL_THRESHx registers to original values */
@@ -913,23 +917,36 @@
 	if (rc < 0)
 		return rc;
 
-	return thermal_current_lim;
+	return 0;
 }
 
-static int qpnp_flash_led_get_max_avail_current(struct qpnp_flash_led *led)
+static int qpnp_flash_led_get_max_avail_current(struct qpnp_flash_led *led,
+						int *max_avail_current)
 {
-	int max_avail_current, thermal_current_lim = 0;
+	int thermal_current_lim = 0, rc;
 
 	led->trigger_lmh = false;
-	max_avail_current = qpnp_flash_led_calc_max_current(led);
-	if (led->pdata->thermal_derate_en)
-		thermal_current_lim =
-			qpnp_flash_led_calc_thermal_current_lim(led);
+	rc = qpnp_flash_led_calc_max_current(led, max_avail_current);
+	if (rc < 0) {
+		pr_err("Couldn't calculate max_avail_current, rc=%d\n", rc);
+		return rc;
+	}
+
+	if (led->pdata->thermal_derate_en) {
+		rc = qpnp_flash_led_calc_thermal_current_lim(led,
+			&thermal_current_lim);
+		if (rc < 0) {
+			pr_err("Couldn't calculate thermal_current_lim, rc=%d\n",
+				rc);
+			return rc;
+		}
+	}
 
 	if (thermal_current_lim)
-		max_avail_current = min(max_avail_current, thermal_current_lim);
+		*max_avail_current = min(*max_avail_current,
+					thermal_current_lim);
 
-	return max_avail_current;
+	return 0;
 }
 
 static void qpnp_flash_led_aggregate_max_current(struct flash_node_data *fnode)
@@ -1237,12 +1254,11 @@
 	}
 
 	if (options & QUERY_MAX_CURRENT) {
-		rc = qpnp_flash_led_get_max_avail_current(led);
+		rc = qpnp_flash_led_get_max_avail_current(led, max_current);
 		if (rc < 0) {
 			pr_err("query max current failed, rc=%d\n", rc);
 			return rc;
 		}
-		*max_current = rc;
 	}
 
 	return 0;
@@ -1291,7 +1307,7 @@
 static ssize_t qpnp_flash_led_max_current_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
-	int rc;
+	int rc, max_current = 0;
 	struct flash_switch_data *snode;
 	struct qpnp_flash_led *led;
 	struct led_classdev *led_cdev = dev_get_drvdata(dev);
@@ -1299,11 +1315,11 @@
 	snode = container_of(led_cdev, struct flash_switch_data, cdev);
 	led = dev_get_drvdata(&snode->pdev->dev);
 
-	rc = qpnp_flash_led_get_max_avail_current(led);
+	rc = qpnp_flash_led_get_max_avail_current(led, &max_current);
 	if (rc < 0)
 		pr_err("query max current failed, rc=%d\n", rc);
 
-	return snprintf(buf, PAGE_SIZE, "%d\n", rc);
+	return snprintf(buf, PAGE_SIZE, "%d\n", max_current);
 }
 
 /* sysfs attributes exported by flash_led */
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index 9dc85cd..620cc7e 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -53,17 +53,16 @@
 	return idx;
 }
 
-static void msg_submit(struct mbox_chan *chan)
+static int __msg_submit(struct mbox_chan *chan)
 {
 	unsigned count, idx;
 	unsigned long flags;
 	void *data;
 	int err = -EBUSY;
 
-again:
 	spin_lock_irqsave(&chan->lock, flags);
 
-	if (!chan->msg_count || (chan->active_req && err != -EAGAIN))
+	if (!chan->msg_count || chan->active_req)
 		goto exit;
 
 	count = chan->msg_count;
@@ -86,15 +85,23 @@
 exit:
 	spin_unlock_irqrestore(&chan->lock, flags);
 
+	return err;
+}
+
+static void msg_submit(struct mbox_chan *chan)
+{
+	int err = 0;
+
 	/*
 	 * If the controller returns -EAGAIN, then it means, our spinlock
 	 * here is preventing the controller from receiving its interrupt,
 	 * that would help clear the controller channels that are currently
 	 * blocked waiting on the interrupt response.
-	 * Unlock and retry again.
+	 * Retry again.
 	 */
-	if (err == -EAGAIN)
-		goto again;
+	do {
+		err = __msg_submit(chan);
+	} while (err == -EAGAIN);
 
 	if (!err && (chan->txdone_method & TXDONE_BY_POLL))
 		/* kick start the timer immediately to avoid delays */
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index ba49f24..7bb6d89 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -2274,11 +2274,8 @@
 	struct hal_frame_size blur_res;
 	struct hal_quantization_range qp_range;
 	struct hal_quantization qp;
-	struct hal_hdr10_pq_sei hdr10_sei_params;
-	struct msm_vidc_mastering_display_colour_sei_payload *mdisp_sei
-		= &(hdr10_sei_params.disp_color_sei);
-	struct msm_vidc_content_light_level_sei_payload *cll_sei
-		= &(hdr10_sei_params.cll_sei);
+	struct msm_vidc_mastering_display_colour_sei_payload *mdisp_sei = NULL;
+	struct msm_vidc_content_light_level_sei_payload *cll_sei = NULL;
 
 	if (!inst || !inst->core || !inst->core->device || !ctrl) {
 		dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
@@ -2293,6 +2290,9 @@
 
 	control = ctrl->controls;
 
+	mdisp_sei = &(inst->hdr10_sei_params.disp_color_sei);
+	cll_sei = &(inst->hdr10_sei_params.cll_sei);
+
 	for (i = 0; i < ctrl->count; i++) {
 		switch (control[i].id) {
 		case V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE:
@@ -2429,9 +2429,9 @@
 			break;
 		case V4L2_CID_MPEG_VIDC_VENC_HDR_INFO:
 			if (control[i].value ==
-				V4L2_MPEG_VIDC_VENC_HDR_INFO_DISABLED)
+				V4L2_MPEG_VIDC_VENC_HDR_INFO_DISABLED ||
+					!mdisp_sei || !cll_sei)
 				break;
-			memset(&hdr10_sei_params, 0, sizeof(hdr10_sei_params));
 			i++;
 			while (i < ctrl->count) {
 				switch (control[i].id) {
@@ -2494,7 +2494,7 @@
 			}
 			property_id =
 				HAL_PARAM_VENC_HDR10_PQ_SEI;
-			pdata = &hdr10_sei_params;
+			pdata = &inst->hdr10_sei_params;
 			break;
 		default:
 			dprintk(VIDC_ERR, "Invalid id set: %d\n",
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
index 1d22077..dc9302e 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
@@ -640,8 +640,8 @@
 		else if (temp->clk_data.core_id == VIDC_CORE_ID_2)
 			freq_core_2 += temp->clk_data.min_freq;
 		else if (temp->clk_data.core_id == VIDC_CORE_ID_3) {
-			freq_core_1 += temp->clk_data.min_freq / 2;
-			freq_core_2 += temp->clk_data.min_freq / 2;
+			freq_core_1 += temp->clk_data.min_freq;
+			freq_core_2 += temp->clk_data.min_freq;
 		}
 
 		freq_core_max = max_t(unsigned long, freq_core_1, freq_core_2);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 4c000b7..7d4e4a1 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -5488,8 +5488,9 @@
 	input_height = inst->prop.height[OUTPUT_PORT];
 	input_width = inst->prop.width[OUTPUT_PORT];
 
-	if (input_width % 2 != 0 || input_height % 2 != 0 ||
-			output_width % 2 != 0 || output_height % 2 != 0) {
+	if (inst->session_type == MSM_VIDC_ENCODER && (input_width % 2 != 0 ||
+			input_height % 2 != 0 || output_width % 2 != 0 ||
+			output_height % 2 != 0)) {
 		dprintk(VIDC_ERR,
 			"Height and Width should be even numbers for NV12\n");
 		dprintk(VIDC_ERR,
@@ -5682,7 +5683,7 @@
 		handle = msm_smem_get_handle(inst->mem_client, dma_buf);
 
 		offset = b->m.planes[i].data_offset;
-		size = b->m.planes[i].length;
+		size = b->m.planes[i].length - offset;
 		cache_ops = SMEM_CACHE_INVALIDATE;
 		skip = false;
 
@@ -5751,7 +5752,7 @@
 		handle = msm_smem_get_handle(inst->mem_client, dma_buf);
 
 		offset = b->m.planes[i].data_offset;
-		size = b->m.planes[i].length;
+		size = b->m.planes[i].length - offset;
 		cache_ops = SMEM_CACHE_INVALIDATE;
 		skip = false;
 
@@ -5771,8 +5772,15 @@
 				skip = true;
 			} else if (b->type ==
 					V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-				if (!i) /* bitstream */
-					skip = true;
+				if (!i) { /* bitstream */
+					/*
+					 * Include vp8e header bytes as well
+					 * by making offset equal to zero
+					 */
+					offset = 0;
+					size = b->m.planes[i].bytesused +
+						b->m.planes[i].data_offset;
+				}
 			}
 		}
 
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 0b6331c..98b5714 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -410,6 +410,7 @@
 	u32 level;
 	u32 entropy_mode;
 	struct msm_vidc_codec_data *codec_data;
+	struct hal_hdr10_pq_sei hdr10_sei_params;
 };
 
 extern struct msm_vidc_drv *vidc_driver;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_platform.c b/drivers/media/platform/msm/vidc/msm_vidc_platform.c
index d7641c3..c84490f 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_platform.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_platform.c
@@ -199,11 +199,11 @@
 	},
 	{
 		.key = "qcom,power-collapse-delay",
-		.value = 500,
+		.value = 1500,
 	},
 	{
 		.key = "qcom,hw-resp-timeout",
-		.value = 250,
+		.value = 1000,
 	},
 };
 
@@ -250,11 +250,11 @@
 	},
 	{
 		.key = "qcom,power-collapse-delay",
-		.value = 500,
+		.value = 1500,
 	},
 	{
 		.key = "qcom,hw-resp-timeout",
-		.value = 250,
+		.value = 1000,
 	},
 };
 
diff --git a/drivers/platform/msm/msm_11ad/msm_11ad.c b/drivers/platform/msm/msm_11ad/msm_11ad.c
index 4c0b38d..4c0531f 100644
--- a/drivers/platform/msm/msm_11ad/msm_11ad.c
+++ b/drivers/platform/msm/msm_11ad/msm_11ad.c
@@ -33,16 +33,14 @@
 #include "wil_platform.h"
 #include "msm_11ad.h"
 
-#define WIGIG_VENDOR (0x1ae9)
-#define WIGIG_DEVICE (0x0310)
-
 #define SMMU_BASE	0x20000000 /* Device address range base */
 #define SMMU_SIZE	((SZ_1G * 4ULL) - SMMU_BASE)
 
 #define WIGIG_ENABLE_DELAY	50
 
 #define WIGIG_SUBSYS_NAME	"WIGIG"
-#define WIGIG_RAMDUMP_SIZE    0x200000 /* maximum ramdump size */
+#define WIGIG_RAMDUMP_SIZE_SPARROW	0x200000 /* maximum ramdump size */
+#define WIGIG_RAMDUMP_SIZE_TALYN	0x400000 /* maximum ramdump size */
 #define WIGIG_DUMP_FORMAT_VER   0x1
 #define WIGIG_DUMP_MAGIC_VER_V1 0x57474947
 #define VDD_MIN_UV	1028000
@@ -61,6 +59,18 @@
 static const char * const gpio_en_name = "qcom,wigig-en";
 static const char * const sleep_clk_en_name = "qcom,sleep-clk-en";
 
+struct wigig_pci {
+	struct pci_device_id pci_dev;
+	u32 ramdump_sz;
+};
+
+static const struct wigig_pci wigig_pci_tbl[] = {
+	{ .pci_dev = { PCI_DEVICE(0x1ae9, 0x0310) },
+	  .ramdump_sz = WIGIG_RAMDUMP_SIZE_SPARROW},
+	{ .pci_dev = { PCI_DEVICE(0x17cb, 0x1201) },
+	  .ramdump_sz = WIGIG_RAMDUMP_SIZE_TALYN},
+};
+
 struct msm11ad_vreg {
 	const char *name;
 	struct regulator *reg;
@@ -113,6 +123,7 @@
 	void *ramdump_addr;
 	struct msm_dump_data dump_data;
 	struct ramdump_device *ramdump_dev;
+	u32 ramdump_size;
 
 	/* external vregs and clocks */
 	struct msm11ad_vreg vdd;
@@ -859,7 +870,7 @@
 {
 	if (ctx->rops.ramdump && ctx->wil_handle) {
 		int rc = ctx->rops.ramdump(ctx->wil_handle, ctx->ramdump_addr,
-					   WIGIG_RAMDUMP_SIZE);
+					   ctx->ramdump_size);
 		if (rc) {
 			dev_err(ctx->dev, "ramdump failed : %d\n", rc);
 			return -EINVAL;
@@ -898,7 +909,7 @@
 
 	memset(&segment, 0, sizeof(segment));
 	segment.v_address = ctx->ramdump_addr;
-	segment.size = WIGIG_RAMDUMP_SIZE;
+	segment.size = ctx->ramdump_size;
 
 	return do_ramdump(ctx->ramdump_dev, &segment, 1);
 }
@@ -961,14 +972,14 @@
 	}
 
 	/* register ramdump area */
-	ctx->ramdump_addr = kmalloc(WIGIG_RAMDUMP_SIZE, GFP_KERNEL);
+	ctx->ramdump_addr = kmalloc(ctx->ramdump_size, GFP_KERNEL);
 	if (!ctx->ramdump_addr) {
 		rc = -ENOMEM;
 		goto out_rc;
 	}
 
 	ctx->dump_data.addr = virt_to_phys(ctx->ramdump_addr);
-	ctx->dump_data.len = WIGIG_RAMDUMP_SIZE;
+	ctx->dump_data.len = ctx->ramdump_size;
 	dump_entry.id = MSM_DUMP_DATA_WIGIG;
 	dump_entry.addr = virt_to_phys(&ctx->dump_data);
 
@@ -1031,8 +1042,9 @@
 	struct device_node *rc_node;
 	struct pci_dev *pcidev = NULL;
 	u32 smmu_mapping[2];
-	int rc;
+	int rc, i;
 	u32 val;
+	bool pcidev_found = false;
 
 	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
 	if (!ctx)
@@ -1161,21 +1173,32 @@
 		goto out_rc;
 	}
 	/* search for PCIE device in our domain */
-	do {
-		pcidev = pci_get_device(WIGIG_VENDOR, WIGIG_DEVICE, pcidev);
-		if (!pcidev)
-			break;
+	for (i = 0; i < ARRAY_SIZE(wigig_pci_tbl); ++i) {
+		do {
+			pcidev = pci_get_device(wigig_pci_tbl[i].pci_dev.vendor,
+						wigig_pci_tbl[i].pci_dev.device,
+						pcidev);
+			if (!pcidev)
+				break;
 
-		if (pci_domain_nr(pcidev->bus) == ctx->rc_index)
+			if (pci_domain_nr(pcidev->bus) == ctx->rc_index) {
+				ctx->ramdump_size = wigig_pci_tbl[i].ramdump_sz;
+				pcidev_found = true;
+				break;
+			}
+		} while (true);
+
+		if (pcidev_found)
 			break;
-	} while (true);
-	if (!pcidev) {
+	}
+	if (!pcidev_found) {
 		rc = -ENODEV;
-		dev_err(ctx->dev, "Wigig device %4x:%4x not found\n",
-			WIGIG_VENDOR, WIGIG_DEVICE);
+		dev_err(ctx->dev, "Wigig device not found\n");
 		goto out_rc;
 	}
 	ctx->pcidev = pcidev;
+	dev_dbg(ctx->dev, "Wigig device %4x:%4x found\n",
+		ctx->pcidev->vendor, ctx->pcidev->device);
 
 	rc = msm_pcie_pm_control(MSM_PCIE_RESUME, pcidev->bus->number,
 				 pcidev, NULL, 0);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index e463117..1f60635 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -4184,6 +4184,7 @@
 		debugfs_remove_recursive(rdev->debugfs);
 		if (rdev->debug_consumer)
 			rdev->debug_consumer->debugfs = NULL;
+		rdev->debugfs = NULL;
 		regulator_put(rdev->debug_consumer);
 	}
 }
@@ -4225,9 +4226,10 @@
 
 	regulator = regulator_get(NULL, rdev_get_name(rdev));
 	if (IS_ERR(regulator)) {
-		debugfs_remove_recursive(rdev->debugfs);
-		rdev_err(rdev, "regulator get failed, ret=%ld\n",
-			PTR_ERR(regulator));
+		rdev_deinit_debugfs(rdev);
+		if (PTR_ERR(regulator) != -EPROBE_DEFER)
+			rdev_err(rdev, "regulator get failed, ret=%ld\n",
+				 PTR_ERR(regulator));
 		return;
 	}
 	rdev->debug_consumer = regulator;
diff --git a/drivers/soc/qcom/peripheral-loader.c b/drivers/soc/qcom/peripheral-loader.c
index 9d22925..e0df954 100644
--- a/drivers/soc/qcom/peripheral-loader.c
+++ b/drivers/soc/qcom/peripheral-loader.c
@@ -511,11 +511,12 @@
 }
 
 static int pil_alloc_region(struct pil_priv *priv, phys_addr_t min_addr,
-				phys_addr_t max_addr, size_t align)
+				phys_addr_t max_addr, size_t align,
+				size_t mdt_size)
 {
 	void *region;
 	size_t size = max_addr - min_addr;
-	size_t aligned_size;
+	size_t aligned_size = max(size, mdt_size);
 
 	/* Don't reallocate due to fragmentation concerns, just sanity check */
 	if (priv->region) {
@@ -526,9 +527,11 @@
 	}
 
 	if (align > SZ_4M)
-		aligned_size = ALIGN(size, SZ_4M);
+		aligned_size = ALIGN(aligned_size, SZ_4M);
+	else if (align > SZ_1M)
+		aligned_size = ALIGN(aligned_size, SZ_1M);
 	else
-		aligned_size = ALIGN(size, SZ_1M);
+		aligned_size = ALIGN(aligned_size, SZ_4K);
 
 	priv->desc->attrs = 0;
 	priv->desc->attrs |= DMA_ATTR_SKIP_ZEROING | DMA_ATTR_NO_KERNEL_MAPPING;
@@ -553,7 +556,8 @@
 	return 0;
 }
 
-static int pil_setup_region(struct pil_priv *priv, const struct pil_mdt *mdt)
+static int pil_setup_region(struct pil_priv *priv, const struct pil_mdt *mdt,
+				size_t mdt_size)
 {
 	const struct elf32_phdr *phdr;
 	phys_addr_t min_addr_r, min_addr_n, max_addr_r, max_addr_n, start, end;
@@ -598,7 +602,8 @@
 	max_addr_r = ALIGN(max_addr_r, SZ_4K);
 
 	if (relocatable) {
-		ret = pil_alloc_region(priv, min_addr_r, max_addr_r, align);
+		ret = pil_alloc_region(priv, min_addr_r, max_addr_r, align,
+					mdt_size);
 	} else {
 		priv->region_start = min_addr_n;
 		priv->region_end = max_addr_n;
@@ -629,14 +634,15 @@
 	return ret;
 }
 
-static int pil_init_mmap(struct pil_desc *desc, const struct pil_mdt *mdt)
+static int pil_init_mmap(struct pil_desc *desc, const struct pil_mdt *mdt,
+			size_t mdt_size)
 {
 	struct pil_priv *priv = desc->priv;
 	const struct elf32_phdr *phdr;
 	struct pil_seg *seg;
 	int i, ret;
 
-	ret = pil_setup_region(priv, mdt);
+	ret = pil_setup_region(priv, mdt, mdt_size);
 	if (ret)
 		return ret;
 
@@ -922,7 +928,7 @@
 		goto release_fw;
 	}
 
-	ret = pil_init_mmap(desc, mdt);
+	ret = pil_init_mmap(desc, mdt, fw->size);
 	if (ret)
 		goto release_fw;
 
@@ -935,7 +941,8 @@
 
 	trace_pil_event("before_init_image", desc);
 	if (desc->ops->init_image)
-		ret = desc->ops->init_image(desc, fw->data, fw->size);
+		ret = desc->ops->init_image(desc, fw->data, fw->size,
+				priv->region_start, priv->region);
 	if (ret) {
 		pil_err(desc, "Initializing image failed(rc:%d)\n", ret);
 		goto err_boot;
diff --git a/drivers/soc/qcom/peripheral-loader.h b/drivers/soc/qcom/peripheral-loader.h
index f09adf5..27ed336 100644
--- a/drivers/soc/qcom/peripheral-loader.h
+++ b/drivers/soc/qcom/peripheral-loader.h
@@ -119,7 +119,7 @@
  */
 struct pil_reset_ops {
 	int (*init_image)(struct pil_desc *pil, const u8 *metadata,
-			  size_t size);
+			  size_t size, phys_addr_t mdata_phys, void *region);
 	int (*mem_setup)(struct pil_desc *pil, phys_addr_t addr, size_t size);
 	int (*verify_blob)(struct pil_desc *pil, phys_addr_t phy_addr,
 			   size_t size);
diff --git a/drivers/soc/qcom/pil-msa.c b/drivers/soc/qcom/pil-msa.c
index a3eb551..ce31d66 100644
--- a/drivers/soc/qcom/pil-msa.c
+++ b/drivers/soc/qcom/pil-msa.c
@@ -769,7 +769,8 @@
 }
 
 static int pil_msa_auth_modem_mdt(struct pil_desc *pil, const u8 *metadata,
-					size_t size)
+					size_t size, phys_addr_t region_start,
+					void *region)
 {
 	struct modem_data *drv = dev_get_drvdata(pil->dev);
 	void *mdata_virt;
@@ -851,7 +852,8 @@
 }
 
 static int pil_msa_mss_reset_mba_load_auth_mdt(struct pil_desc *pil,
-				  const u8 *metadata, size_t size)
+				const u8 *metadata, size_t size,
+				phys_addr_t region_start, void *region)
 {
 	int ret;
 
@@ -859,7 +861,8 @@
 	if (ret)
 		return ret;
 
-	return pil_msa_auth_modem_mdt(pil, metadata, size);
+	return pil_msa_auth_modem_mdt(pil, metadata, size, region_start,
+								region);
 }
 
 static int pil_msa_mba_verify_blob(struct pil_desc *pil, phys_addr_t phy_addr,
diff --git a/drivers/soc/qcom/subsys-pil-tz.c b/drivers/soc/qcom/subsys-pil-tz.c
index 01b4790..d3819b6 100644
--- a/drivers/soc/qcom/subsys-pil-tz.c
+++ b/drivers/soc/qcom/subsys-pil-tz.c
@@ -47,6 +47,13 @@
 #define desc_to_data(d) container_of(d, struct pil_tz_data, desc)
 #define subsys_to_data(d) container_of(d, struct pil_tz_data, subsys_desc)
 
+struct pil_map_fw_info {
+	void *region;
+	unsigned long attrs;
+	phys_addr_t base_addr;
+	struct device *dev;
+};
+
 /**
  * struct reg_info - regulator info
  * @reg: regulator handle
@@ -586,7 +593,8 @@
 }
 
 static int pil_init_image_trusted(struct pil_desc *pil,
-		const u8 *metadata, size_t size)
+		const u8 *metadata, size_t size, phys_addr_t mdata_phys,
+		void *region)
 {
 	struct pil_tz_data *d = desc_to_data(pil);
 	struct pas_init_image_req {
@@ -595,11 +603,15 @@
 	} request;
 	u32 scm_ret = 0;
 	void *mdata_buf;
-	dma_addr_t mdata_phys;
 	int ret;
-	unsigned long attrs = 0;
-	struct device dev = {0};
 	struct scm_desc desc = {0};
+	struct pil_map_fw_info map_fw_info = {
+		.attrs = pil->attrs,
+		.region = region,
+		.base_addr = mdata_phys,
+		.dev = pil->dev,
+	};
+	void *map_data = pil->map_data ? pil->map_data : &map_fw_info;
 
 	if (d->subsys_desc.no_auth)
 		return 0;
@@ -607,15 +619,10 @@
 	ret = scm_pas_enable_bw();
 	if (ret)
 		return ret;
-	arch_setup_dma_ops(&dev, 0, 0, NULL, 0);
 
-	dev.coherent_dma_mask =
-		DMA_BIT_MASK(sizeof(dma_addr_t) * 8);
-	attrs |= DMA_ATTR_STRONGLY_ORDERED;
-	mdata_buf = dma_alloc_attrs(&dev, size, &mdata_phys, GFP_KERNEL,
-					attrs);
+	mdata_buf = pil->map_fw_mem(mdata_phys, size, map_data);
 	if (!mdata_buf) {
-		pr_err("scm-pas: Allocation for metadata failed.\n");
+		dev_err(pil->dev, "Failed to map memory for metadata.\n");
 		scm_pas_disable_bw();
 		return -ENOMEM;
 	}
@@ -637,7 +644,7 @@
 		scm_ret = desc.ret[0];
 	}
 
-	dma_free_attrs(&dev, size, mdata_buf, mdata_phys, attrs);
+	pil->unmap_fw_mem(mdata_buf, size, map_data);
 	scm_pas_disable_bw();
 	if (ret)
 		return ret;
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 874499d..3b92db9 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -3989,7 +3989,10 @@
 
 	psy_type = get_psy_type(mdwc);
 	if (psy_type == POWER_SUPPLY_TYPE_USB_FLOAT) {
-		pval.intval = -ETIMEDOUT;
+		if (!mA)
+			pval.intval = -ETIMEDOUT;
+		else
+			pval.intval = 1000 * mA;
 		goto set_prop;
 	}
 
diff --git a/drivers/usb/gadget/function/f_gsi.h b/drivers/usb/gadget/function/f_gsi.h
index bdd0dfa..295f681 100644
--- a/drivers/usb/gadget/function/f_gsi.h
+++ b/drivers/usb/gadget/function/f_gsi.h
@@ -572,7 +572,7 @@
 static struct usb_endpoint_descriptor rndis_gsi_fs_in_desc = {
 	.bLength =		USB_DT_ENDPOINT_SIZE,
 	.bDescriptorType =	USB_DT_ENDPOINT,
-
+	.wMaxPacketSize =	cpu_to_le16(64),
 	.bEndpointAddress =	USB_DIR_IN,
 	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
 };
@@ -580,7 +580,7 @@
 static struct usb_endpoint_descriptor rndis_gsi_fs_out_desc = {
 	.bLength =		USB_DT_ENDPOINT_SIZE,
 	.bDescriptorType =	USB_DT_ENDPOINT,
-
+	.wMaxPacketSize =	cpu_to_le16(64),
 	.bEndpointAddress =	USB_DIR_OUT,
 	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
 };
diff --git a/drivers/usb/gadget/function/f_mtp.c b/drivers/usb/gadget/function/f_mtp.c
index aea32e4..239d9bf 100644
--- a/drivers/usb/gadget/function/f_mtp.c
+++ b/drivers/usb/gadget/function/f_mtp.c
@@ -1464,6 +1464,7 @@
 		mtp_ss_out_comp_desc.bMaxBurst = max_burst;
 	}
 
+	fi_mtp->func_inst.f = &dev->function;
 	DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n",
 		gadget_is_superspeed(c->cdev->gadget) ? "super" :
 		(gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full"),
@@ -1475,9 +1476,10 @@
 mtp_function_unbind(struct usb_configuration *c, struct usb_function *f)
 {
 	struct mtp_dev	*dev = func_to_mtp(f);
+	struct mtp_instance *fi_mtp;
 	struct usb_request *req;
 	int i;
-
+	fi_mtp = container_of(f->fi, struct mtp_instance, func_inst);
 	mtp_string_defs[INTERFACE_STRING_INDEX].id = 0;
 	mutex_lock(&dev->read_mutex);
 	while ((req = mtp_req_get(dev, &dev->tx_idle)))
@@ -1490,6 +1492,7 @@
 	dev->state = STATE_OFFLINE;
 	kfree(f->os_desc_table);
 	f->os_desc_n = 0;
+	fi_mtp->func_inst.f = NULL;
 }
 
 static int mtp_function_set_alt(struct usb_function *f,
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 5434902..643e087 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -23,6 +23,7 @@
 #include <linux/gfp.h>
 #include <linux/slab.h>
 #include <asm/unaligned.h>
+#include <linux/usb/phy.h>
 
 #include "xhci.h"
 #include "xhci-trace.h"
@@ -1065,6 +1066,7 @@
 	u16 wake_mask = 0;
 	u16 timeout = 0;
 	u16 test_mode = 0;
+	enum usb_device_speed s = hcd->self.root_hub->speed;
 
 	max_ports = xhci_get_ports(hcd, &port_array);
 	bus_state = &xhci->bus_state[hcd_index(hcd)];
@@ -1314,6 +1316,10 @@
 			writel(temp, port_array[wIndex]);
 
 			temp = readl(port_array[wIndex]);
+
+			if (s == USB_SPEED_HIGH)
+				usb_phy_start_port_reset(hcd->usb_phy);
+
 			xhci_dbg(xhci, "set port reset, actual port %d status  = 0x%x\n", wIndex, temp);
 			break;
 		case USB_PORT_FEAT_REMOTE_WAKE_MASK:
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ab3633c..ae8a727 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -138,7 +138,13 @@
 {
 	u32 temp;
 	int ret;
+	struct usb_hcd *hcd = xhci_to_hcd(xhci);
 
+	/*
+	 * disable irq to avoid xhci_irq flooding due to unhandeled port
+	 * change event in halt state, as soon as xhci_start clears halt bit
+	 */
+	disable_irq(hcd->irq);
 	temp = readl(&xhci->op_regs->command);
 	temp |= (CMD_RUN);
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Turn on HC, cmd = 0x%x.",
@@ -159,6 +165,8 @@
 		/* clear state flags. Including dying, halted or removing */
 		xhci->xhc_state = 0;
 
+	enable_irq(hcd->irq);
+
 	return ret;
 }
 
diff --git a/drivers/usb/phy/phy-msm-qusb-v2.c b/drivers/usb/phy/phy-msm-qusb-v2.c
index 81c39a3..cce17e0 100644
--- a/drivers/usb/phy/phy-msm-qusb-v2.c
+++ b/drivers/usb/phy/phy-msm-qusb-v2.c
@@ -27,6 +27,7 @@
 #include <linux/usb/phy.h>
 #include <linux/reset.h>
 #include <linux/debugfs.h>
+#include <linux/hrtimer.h>
 
 /* QUSB2PHY_PWR_CTRL1 register related bits */
 #define PWR_CTRL1_POWR_DOWN		BIT(0)
@@ -126,6 +127,10 @@
 	u32			sq_ctrl2_default;
 	bool			chirp_disable;
 
+	struct pinctrl		*pinctrl;
+	struct pinctrl_state	*atest_usb13_suspend;
+	struct pinctrl_state	*atest_usb13_active;
+
 	/* emulation targets specific */
 	void __iomem		*emu_phy_base;
 	bool			emulation;
@@ -139,6 +144,8 @@
 	/* override TUNEX registers value */
 	struct dentry		*root;
 	u8			tune[5];
+
+	struct hrtimer		timer;
 };
 
 static void qusb_phy_enable_clocks(struct qusb_phy *qphy, bool on)
@@ -511,6 +518,42 @@
 	return 0;
 }
 
+static enum hrtimer_restart qusb_dis_ext_pulldown_timer(struct hrtimer *timer)
+{
+	struct qusb_phy *qphy = container_of(timer, struct qusb_phy, timer);
+	int ret = 0;
+
+	if (qphy->pinctrl && qphy->atest_usb13_suspend) {
+		ret = pinctrl_select_state(qphy->pinctrl,
+				qphy->atest_usb13_suspend);
+		if (ret < 0)
+			dev_err(qphy->phy.dev,
+				"pinctrl state suspend select failed\n");
+	}
+
+	return HRTIMER_NORESTART;
+}
+
+static void qusb_phy_enable_ext_pulldown(struct usb_phy *phy)
+{
+	struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
+	int ret = 0;
+
+	dev_dbg(phy->dev, "%s\n", __func__);
+
+	if (qphy->pinctrl && qphy->atest_usb13_active) {
+		ret = pinctrl_select_state(qphy->pinctrl,
+				qphy->atest_usb13_active);
+		if (ret < 0) {
+			dev_err(phy->dev,
+					"pinctrl state active select failed\n");
+			return;
+		}
+
+		hrtimer_start(&qphy->timer, ms_to_ktime(10), HRTIMER_MODE_REL);
+	}
+}
+
 static void qusb_phy_shutdown(struct usb_phy *phy)
 {
 	struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
@@ -1082,6 +1125,30 @@
 		return PTR_ERR(qphy->vdda18);
 	}
 
+	qphy->pinctrl = devm_pinctrl_get(dev);
+	if (IS_ERR(qphy->pinctrl)) {
+		ret = PTR_ERR(qphy->pinctrl);
+		if (ret == -EPROBE_DEFER)
+			return ret;
+		dev_err(dev, "pinctrl not available\n");
+		goto skip_pinctrl_config;
+	}
+	qphy->atest_usb13_suspend = pinctrl_lookup_state(qphy->pinctrl,
+							"atest_usb13_suspend");
+	if (IS_ERR(qphy->atest_usb13_suspend)) {
+		dev_err(dev, "pinctrl lookup atest_usb13_suspend failed\n");
+		goto skip_pinctrl_config;
+	}
+
+	qphy->atest_usb13_active = pinctrl_lookup_state(qphy->pinctrl,
+							"atest_usb13_active");
+	if (IS_ERR(qphy->atest_usb13_active))
+		dev_err(dev, "pinctrl lookup atest_usb13_active failed\n");
+
+	hrtimer_init(&qphy->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	qphy->timer.function = qusb_dis_ext_pulldown_timer;
+
+skip_pinctrl_config:
 	mutex_init(&qphy->lock);
 	platform_set_drvdata(pdev, qphy);
 
@@ -1093,6 +1160,7 @@
 	qphy->phy.notify_connect        = qusb_phy_notify_connect;
 	qphy->phy.notify_disconnect     = qusb_phy_notify_disconnect;
 	qphy->phy.disable_chirp		= qusb_phy_disable_chirp;
+	qphy->phy.start_port_reset	= qusb_phy_enable_ext_pulldown;
 
 	ret = usb_add_phy_dev(&qphy->phy);
 	if (ret)
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 7d4b557..6cb3a8c 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -276,11 +276,11 @@
 	goto loop;
 
 end_loop:
-	write_unlock(&journal->j_state_lock);
 	del_timer_sync(&journal->j_commit_timer);
 	journal->j_task = NULL;
 	wake_up(&journal->j_wait_done_commit);
 	jbd_debug(1, "Journal thread exiting.\n");
+	write_unlock(&journal->j_state_lock);
 	return 0;
 }
 
diff --git a/include/dt-bindings/clock/qcom,gcc-sdxpoorwills.h b/include/dt-bindings/clock/qcom,gcc-sdxpoorwills.h
index 950811f..7e1394c 100644
--- a/include/dt-bindings/clock/qcom,gcc-sdxpoorwills.h
+++ b/include/dt-bindings/clock/qcom,gcc-sdxpoorwills.h
@@ -65,43 +65,44 @@
 #define GCC_MSS_CFG_AHB_CLK					47
 #define GCC_MSS_GPLL0_DIV_CLK_SRC				48
 #define GCC_MSS_SNOC_AXI_CLK					49
-#define GCC_PCIE_AUX_CLK					50
-#define GCC_PCIE_AUX_PHY_CLK_SRC				51
-#define GCC_PCIE_CFG_AHB_CLK					52
-#define GCC_PCIE_MSTR_AXI_CLK					53
-#define GCC_PCIE_PHY_REFGEN_CLK					54
-#define GCC_PCIE_PHY_REFGEN_CLK_SRC				55
-#define GCC_PCIE_PIPE_CLK					56
-#define GCC_PCIE_SLEEP_CLK					57
-#define GCC_PCIE_SLV_AXI_CLK					58
-#define GCC_PCIE_SLV_Q2A_AXI_CLK				59
-#define GCC_PDM2_CLK						60
-#define GCC_PDM2_CLK_SRC					61
-#define GCC_PDM_AHB_CLK						62
-#define GCC_PDM_XO4_CLK						63
-#define GCC_PRNG_AHB_CLK					64
-#define GCC_SDCC1_AHB_CLK					65
-#define GCC_SDCC1_APPS_CLK					66
-#define GCC_SDCC1_APPS_CLK_SRC					67
-#define GCC_SPMI_FETCHER_AHB_CLK				68
-#define GCC_SPMI_FETCHER_CLK					69
-#define GCC_SPMI_FETCHER_CLK_SRC				70
-#define GCC_SYS_NOC_CPUSS_AHB_CLK				71
-#define GCC_SYS_NOC_USB3_CLK					72
-#define GCC_USB30_MASTER_CLK					73
-#define GCC_USB30_MASTER_CLK_SRC				74
-#define GCC_USB30_MOCK_UTMI_CLK					75
-#define GCC_USB30_MOCK_UTMI_CLK_SRC				76
-#define GCC_USB30_SLEEP_CLK					77
-#define GCC_USB3_PHY_AUX_CLK					78
-#define GCC_USB3_PHY_AUX_CLK_SRC				79
-#define GCC_USB3_PHY_PIPE_CLK					80
-#define GCC_USB_PHY_CFG_AHB2PHY_CLK				81
-#define GPLL0							82
-#define GPLL0_OUT_EVEN						83
-#define GPLL4							84
-#define GPLL4_OUT_EVEN						85
-#define GCC_USB3_PRIM_CLKREF_CLK				86
+#define GCC_PCIE_0_CLKREF_CLK					50
+#define GCC_PCIE_AUX_CLK					51
+#define GCC_PCIE_AUX_PHY_CLK_SRC				52
+#define GCC_PCIE_CFG_AHB_CLK					53
+#define GCC_PCIE_MSTR_AXI_CLK					54
+#define GCC_PCIE_PHY_REFGEN_CLK					55
+#define GCC_PCIE_PHY_REFGEN_CLK_SRC				56
+#define GCC_PCIE_PIPE_CLK					57
+#define GCC_PCIE_SLEEP_CLK					58
+#define GCC_PCIE_SLV_AXI_CLK					59
+#define GCC_PCIE_SLV_Q2A_AXI_CLK				60
+#define GCC_PDM2_CLK						61
+#define GCC_PDM2_CLK_SRC					62
+#define GCC_PDM_AHB_CLK						63
+#define GCC_PDM_XO4_CLK						64
+#define GCC_PRNG_AHB_CLK					65
+#define GCC_SDCC1_AHB_CLK					66
+#define GCC_SDCC1_APPS_CLK					67
+#define GCC_SDCC1_APPS_CLK_SRC					68
+#define GCC_SPMI_FETCHER_AHB_CLK				69
+#define GCC_SPMI_FETCHER_CLK					70
+#define GCC_SPMI_FETCHER_CLK_SRC				71
+#define GCC_SYS_NOC_CPUSS_AHB_CLK				72
+#define GCC_SYS_NOC_USB3_CLK					73
+#define GCC_USB30_MASTER_CLK					74
+#define GCC_USB30_MASTER_CLK_SRC				75
+#define GCC_USB30_MOCK_UTMI_CLK					76
+#define GCC_USB30_MOCK_UTMI_CLK_SRC				77
+#define GCC_USB30_SLEEP_CLK					78
+#define GCC_USB3_PHY_AUX_CLK					79
+#define GCC_USB3_PHY_AUX_CLK_SRC				80
+#define GCC_USB3_PHY_PIPE_CLK					81
+#define GCC_USB3_PRIM_CLKREF_CLK				82
+#define GCC_USB_PHY_CFG_AHB2PHY_CLK				83
+#define GPLL0							84
+#define GPLL0_OUT_EVEN						85
+#define GPLL4							86
+#define GPLL4_OUT_EVEN						87
 
 /* CPU clocks */
 #define CLOCK_A7SS						0
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 9b21e2a..907e029 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1164,8 +1164,6 @@
 	struct address_space *check_mapping;	/* Check page->mapping if set */
 	pgoff_t	first_index;			/* Lowest page->index to unmap */
 	pgoff_t last_index;			/* Highest page->index to unmap */
-	bool ignore_dirty;			/* Ignore dirty pages */
-	bool check_swap_entries;		/* Check also swap entries */
 };
 
 struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
diff --git a/include/linux/sde_rsc.h b/include/linux/sde_rsc.h
index cda2654..d2c1a95 100644
--- a/include/linux/sde_rsc.h
+++ b/include/linux/sde_rsc.h
@@ -186,6 +186,26 @@
 	int *wait_vblank_crtc_id);
 
 /**
+ * sde_rsc_client_get_vsync_refcount() - returns the status of the vsync
+ * refcount, to signal if the client needs to reset the refcounting logic
+ * @client:	 Client pointer provided by sde_rsc_client_create().
+ *
+ * Return: true if the state update has completed.
+ */
+int sde_rsc_client_get_vsync_refcount(
+		struct sde_rsc_client *caller_client);
+
+/**
+ * sde_rsc_client_reset_vsync_refcount() - reduces the refcounting
+ * logic that waits for the vsync.
+ * @client:	 Client pointer provided by sde_rsc_client_create().
+ *
+ * Return: true if the state update has completed.
+ */
+int sde_rsc_client_reset_vsync_refcount(
+		struct sde_rsc_client *caller_client);
+
+/**
  * sde_rsc_client_is_state_update_complete() - check if state update is complete
  * RSC state transition is not complete until HW receives VBLANK signal. This
  * function checks RSC HW to determine whether that signal has been received.
@@ -265,6 +285,18 @@
 	return 0;
 }
 
+int sde_rsc_client_get_vsync_refcount(
+		struct sde_rsc_client *caller_client)
+{
+	return 0;
+}
+
+int sde_rsc_client_reset_vsync_refcount(
+		struct sde_rsc_client *caller_client)
+{
+	return 0;
+}
+
 static inline bool sde_rsc_client_is_state_update_complete(
 		struct sde_rsc_client *caller_client)
 {
diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h
index 092c32e..742ef8d 100644
--- a/include/linux/usb/phy.h
+++ b/include/linux/usb/phy.h
@@ -114,6 +114,8 @@
 
 	/* enable/disable VBUS */
 	int	(*set_vbus)(struct usb_phy *x, int on);
+	/* callback to indicate port is being reset or reset the port */
+	void	(*start_port_reset)(struct usb_phy *x);
 
 	/* effective for B devices, ignored for A-peripheral */
 	int	(*set_power)(struct usb_phy *x,
@@ -213,6 +215,15 @@
 	return x->set_vbus(x, false);
 }
 
+static inline void
+usb_phy_start_port_reset(struct usb_phy *x)
+{
+	if (!x || !x->start_port_reset)
+		return;
+
+	x->start_port_reset(x);
+}
+
 static inline int
 usb_phy_reset(struct usb_phy *x)
 {
diff --git a/include/trace/events/oom.h b/include/trace/events/oom.h
index 1e97498..beddb19 100644
--- a/include/trace/events/oom.h
+++ b/include/trace/events/oom.h
@@ -27,6 +27,85 @@
 		__entry->pid, __entry->comm, __entry->oom_score_adj)
 );
 
+TRACE_EVENT(mark_victim,
+	TP_PROTO(int pid),
+
+	TP_ARGS(pid),
+
+	TP_STRUCT__entry(
+		__field(int, pid)
+	),
+
+	TP_fast_assign(
+		__entry->pid = pid;
+	),
+
+	TP_printk("pid=%d", __entry->pid)
+);
+
+TRACE_EVENT(wake_reaper,
+	TP_PROTO(int pid),
+
+	TP_ARGS(pid),
+
+	TP_STRUCT__entry(
+		__field(int, pid)
+	),
+
+	TP_fast_assign(
+		__entry->pid = pid;
+	),
+
+	TP_printk("pid=%d", __entry->pid)
+);
+
+TRACE_EVENT(start_task_reaping,
+	TP_PROTO(int pid),
+
+	TP_ARGS(pid),
+
+	TP_STRUCT__entry(
+		__field(int, pid)
+	),
+
+	TP_fast_assign(
+		__entry->pid = pid;
+	),
+
+	TP_printk("pid=%d", __entry->pid)
+);
+
+TRACE_EVENT(finish_task_reaping,
+	TP_PROTO(int pid),
+
+	TP_ARGS(pid),
+
+	TP_STRUCT__entry(
+		__field(int, pid)
+	),
+
+	TP_fast_assign(
+		__entry->pid = pid;
+	),
+
+	TP_printk("pid=%d", __entry->pid)
+);
+
+TRACE_EVENT(skip_task_reaping,
+	TP_PROTO(int pid),
+
+	TP_ARGS(pid),
+
+	TP_STRUCT__entry(
+		__field(int, pid)
+	),
+
+	TP_fast_assign(
+		__entry->pid = pid;
+	),
+
+	TP_printk("pid=%d", __entry->pid)
+);
 #endif
 
 /* This part must be outside protection */
diff --git a/kernel/fork.c b/kernel/fork.c
index 610aded..b83adf9 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -879,7 +879,6 @@
 	}
 	if (mm->binfmt)
 		module_put(mm->binfmt->module);
-	set_bit(MMF_OOM_SKIP, &mm->flags);
 	mmdrop(mm);
 }
 
diff --git a/mm/internal.h b/mm/internal.h
index 0ee4f54..6aa1c51 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -41,6 +41,11 @@
 void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma,
 		unsigned long floor, unsigned long ceiling);
 
+static inline bool can_madv_dontneed_vma(struct vm_area_struct *vma)
+{
+	return !(vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_PFNMAP));
+}
+
 void unmap_page_range(struct mmu_gather *tlb,
 			     struct vm_area_struct *vma,
 			     unsigned long addr, unsigned long end,
diff --git a/mm/madvise.c b/mm/madvise.c
index 088a5b22..8b25167 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -25,6 +25,8 @@
 
 #include <asm/tlb.h>
 
+#include "internal.h"
+
 /*
  * Any behaviour which results in changes to the vma->vm_flags needs to
  * take mmap_sem for writing. Others, which simply traverse vmas, need
@@ -474,7 +476,7 @@
 			     unsigned long start, unsigned long end)
 {
 	*prev = vma;
-	if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_PFNMAP))
+	if (!can_madv_dontneed_vma(vma))
 		return -EINVAL;
 
 	zap_page_range(vma, start, end - start, NULL);
diff --git a/mm/memory.c b/mm/memory.c
index 378ebc0..82d2000 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1154,12 +1154,6 @@
 
 			if (!PageAnon(page)) {
 				if (pte_dirty(ptent)) {
-					/*
-					 * oom_reaper cannot tear down dirty
-					 * pages
-					 */
-					if (unlikely(details && details->ignore_dirty))
-						continue;
 					force_flush = 1;
 					set_page_dirty(page);
 				}
@@ -1179,8 +1173,8 @@
 			}
 			continue;
 		}
-		/* only check swap_entries if explicitly asked for in details */
-		if (unlikely(details && !details->check_swap_entries))
+		/* If details->check_mapping, we leave swap entries. */
+		if (unlikely(details))
 			continue;
 
 		entry = pte_to_swp_entry(ptent);
diff --git a/mm/mmap.c b/mm/mmap.c
index 6f90f07..7e6c049 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -44,6 +44,7 @@
 #include <linux/userfaultfd_k.h>
 #include <linux/moduleparam.h>
 #include <linux/pkeys.h>
+#include <linux/oom.h>
 
 #include <asm/uaccess.h>
 #include <asm/cacheflush.h>
@@ -2983,6 +2984,23 @@
 	/* Use -1 here to ensure all VMAs in the mm are unmapped */
 	unmap_vmas(&tlb, vma, 0, -1);
 
+	set_bit(MMF_OOM_SKIP, &mm->flags);
+	if (unlikely(tsk_is_oom_victim(current))) {
+		/*
+		 * Wait for oom_reap_task() to stop working on this
+		 * mm. Because MMF_OOM_SKIP is already set before
+		 * calling down_read(), oom_reap_task() will not run
+		 * on this "mm" post up_write().
+		 *
+		 * tsk_is_oom_victim() cannot be set from under us
+		 * either because current->mm is already set to NULL
+		 * under task_lock before calling mmput and oom_mm is
+		 * set not NULL by the OOM killer only if current->mm
+		 * is found not NULL while holding the task_lock.
+		 */
+		down_write(&mm->mmap_sem);
+		up_write(&mm->mmap_sem);
+	}
 	free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, USER_PGTABLES_CEILING);
 	tlb_finish_mmu(&tlb, 0, -1);
 
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 1f13413..af9a8a6 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -470,8 +470,6 @@
 {
 	struct mmu_gather tlb;
 	struct vm_area_struct *vma;
-	struct zap_details details = {.check_swap_entries = true,
-				      .ignore_dirty = true};
 	bool ret = true;
 
 	/*
@@ -492,6 +490,7 @@
 
 	if (!down_read_trylock(&mm->mmap_sem)) {
 		ret = false;
+		trace_skip_task_reaping(tsk->pid);
 		goto unlock_oom;
 	}
 
@@ -511,15 +510,19 @@
 	}
 
 	/*
-	 * increase mm_users only after we know we will reap something so
-	 * that the mmput_async is called only when we have reaped something
-	 * and delayed __mmput doesn't matter that much
+	 * MMF_OOM_SKIP is set by exit_mmap when the OOM reaper can't
+	 * work on the mm anymore. The check for MMF_OOM_SKIP must run
+	 * under mmap_sem for reading because it serializes against the
+	 * down_write();up_write() cycle in exit_mmap().
 	 */
-	if (!mmget_not_zero(mm)) {
+	if (test_bit(MMF_OOM_SKIP, &mm->flags)) {
 		up_read(&mm->mmap_sem);
+		trace_skip_task_reaping(tsk->pid);
 		goto unlock_oom;
 	}
 
+	trace_start_task_reaping(tsk->pid);
+
 	/*
 	 * Tell all users of get_user/copy_from_user etc... that the content
 	 * is no longer stable. No barriers really needed because unmapping
@@ -528,16 +531,8 @@
 	 */
 	set_bit(MMF_UNSTABLE, &mm->flags);
 
-	tlb_gather_mmu(&tlb, mm, 0, -1);
 	for (vma = mm->mmap ; vma; vma = vma->vm_next) {
-		if (is_vm_hugetlb_page(vma))
-			continue;
-
-		/*
-		 * mlocked VMAs require explicit munlocking before unmap.
-		 * Let's keep it simple here and skip such VMAs.
-		 */
-		if (vma->vm_flags & VM_LOCKED)
+		if (!can_madv_dontneed_vma(vma))
 			continue;
 
 		/*
@@ -550,11 +545,13 @@
 		 * we do not want to block exit_mmap by keeping mm ref
 		 * count elevated without a good reason.
 		 */
-		if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED))
+		if (vma_is_anonymous(vma) || !(vma->vm_flags & VM_SHARED)) {
+			tlb_gather_mmu(&tlb, mm, vma->vm_start, vma->vm_end);
 			unmap_page_range(&tlb, vma, vma->vm_start, vma->vm_end,
-					 &details);
+					 NULL);
+			tlb_finish_mmu(&tlb, vma->vm_start, vma->vm_end);
+		}
 	}
-	tlb_finish_mmu(&tlb, 0, -1);
 	pr_info("oom_reaper: reaped process %d (%s), now anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n",
 			task_pid_nr(tsk), tsk->comm,
 			K(get_mm_counter(mm, MM_ANONPAGES)),
@@ -562,12 +559,7 @@
 			K(get_mm_counter(mm, MM_SHMEMPAGES)));
 	up_read(&mm->mmap_sem);
 
-	/*
-	 * Drop our reference but make sure the mmput slow path is called from a
-	 * different context because we shouldn't risk we get stuck there and
-	 * put the oom_reaper out of the way.
-	 */
-	mmput_async(mm);
+	trace_finish_task_reaping(tsk->pid);
 unlock_oom:
 	mutex_unlock(&oom_lock);
 	return ret;
@@ -644,6 +636,7 @@
 	tsk->oom_reaper_list = oom_reaper_list;
 	oom_reaper_list = tsk;
 	spin_unlock(&oom_reaper_lock);
+	trace_wake_reaper(tsk->pid);
 	wake_up(&oom_reaper_wait);
 }
 
@@ -695,6 +688,7 @@
 	 */
 	__thaw_task(tsk);
 	atomic_inc(&oom_victims);
+	trace_mark_victim(tsk->pid);
 }
 
 /**