Merge "ARM: dts: msm: Update dump ids for llcc on sdm845"
diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt
index bf93a2a..6451b34 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm.txt
@@ -89,8 +89,8 @@
 - SDM845
   compatible = "qcom,sdm845"
 
-- SDM830
-  compatible = "qcom,sdm830"
+- SDM670
+  compatible = "qcom,sdm670"
 
 - MSM8952
   compatible = "qcom,msm8952"
@@ -267,10 +267,9 @@
 compatible = "qcom,sdm845-mtp"
 compatible = "qcom,sdm845-mtp"
 compatible = "qcom,sdm845-qrd"
-compatible = "qcom,sdm830-sim"
-compatible = "qcom,sdm830-rumi"
-compatible = "qcom,sdm830-cdp"
-compatible = "qcom,sdm830-mtp"
+compatible = "qcom,sdm670-rumi"
+compatible = "qcom,sdm670-cdp"
+compatible = "qcom,sdm670-mtp"
 compatible = "qcom,msm8952-rumi"
 compatible = "qcom,msm8952-sim"
 compatible = "qcom,msm8952-qrd"
diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt b/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt
index da54fb1..176f9e1 100644
--- a/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt
+++ b/Documentation/devicetree/bindings/leds/leds-qpnp-flash-v2.txt
@@ -169,8 +169,15 @@
                           sleep configuration defined for each pin or pin group.
 - qcom,hw-strobe-gpio	: phandle to specify GPIO for hardware strobing. This is used when there is no
 			  pinctrl support or PMIC GPIOs are used.
-- qcom,hw-strobe-sel	: Boolean property to enable hardware strobe. If not defined, software strobe
-			  will be used.
+- qcom,strobe-sel	: Property to select strobe type. If not defined,
+			  software strobe will be used. Allowed options are:
+			  0 - SW strobe
+			  1 - HW strobe
+			  2 - LPG strobe
+			  LPG strobe is supported only for LED3.
+			  If LPG strobe is specified, then strobe control is
+			  configured for active high and level triggered. Also
+			  qcom,hw-strobe-option should be set to 1 or 2.
 - qcom,hw-strobe-edge-trigger	: Boolean property to select trigger type. If defined, hw-strobe is set to
 				  be edge triggered. Otherwise, it is level triggered.
 - qcom,hw-strobe-active-low	: Boolean property to select strobe signal polarity. If defined, hw-strobe
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sdm830-pinctrl b/Documentation/devicetree/bindings/pinctrl/qcom,sdm670-pinctrl
similarity index 95%
rename from Documentation/devicetree/bindings/pinctrl/qcom,sdm830-pinctrl
rename to Documentation/devicetree/bindings/pinctrl/qcom,sdm670-pinctrl
index 0fe8a1b..0eb1043f 100644
--- a/Documentation/devicetree/bindings/pinctrl/qcom,sdm830-pinctrl
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,sdm670-pinctrl
@@ -1,12 +1,12 @@
-Qualcomm Technologies, Inc. SDM830 TLMM block
+Qualcomm Technologies, Inc. SDM670 TLMM block
 
 This binding describes the Top Level Mode Multiplexer block found in the
-SDM830 platform.
+SDM670 platform.
 
 - compatible:
 	Usage: required
 	Value type: <string>
-	Definition: must be "qcom,sdm830-pinctrl"
+	Definition: must be "qcom,sdm670-pinctrl"
 
 - reg:
 	Usage: required
@@ -135,9 +135,9 @@
 
 Example:
 
-	tlmm: pinctrl@03800000 {
-		compatible = "qcom,sdm830-pinctrl";
-		reg = <0x03800000 0xc00000>;
+	tlmm: pinctrl@03400000 {
+		compatible = "qcom,sdm670-pinctrl";
+		reg = <0x03400000 0xc00000>;
 		interrupts = <0 208 0>;
 		gpio-controller;
 		#gpio-cells = <2>;
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index ba1da74..961adc9 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -142,6 +142,7 @@
 		compatible = "qcom,dummycc";
 		clock-output-names = "gcc_clocks";
 		#clock-cells = <1>;
+		#reset-cells = <1>;
 	};
 
 	clock_cpu: qcom,clock-a7@17810008 {
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 445aeb6..dae2f9f 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -128,13 +128,13 @@
 	  This enables support for the SDM845 chipset. If you do not
 	  wish to build a kernel that runs on this chipset, say 'N' here.
 
-config ARCH_SDM830
-	bool "Enable Support for Qualcomm Technologies Inc. SDM830"
+config ARCH_SDM670
+	bool "Enable Support for Qualcomm Technologies Inc. SDM670"
 	depends on ARCH_QCOM
 	select COMMON_CLK_QCOM
 	select QCOM_GDSC
 	help
-	  This enables support for the SDM830 chipset. If you do not
+	  This enables support for the SDM670 chipset. If you do not
 	  wish to build a kernel that runs on this chipset, say 'N' here.
 
 config ARCH_ROCKCHIP
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index cd13516..7ad029a 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -23,10 +23,9 @@
 sdm845-mtp-overlay.dtbo-base := sdm845.dtb
 endif
 
-dtb-$(CONFIG_ARCH_SDM830) += sdm830-sim.dtb \
-	sdm830-rumi.dtb \
-	sdm830-mtp.dtb \
-	sdm830-cdp.dtb
+dtb-$(CONFIG_ARCH_SDM670) += sdm670-rumi.dtb \
+	sdm670-mtp.dtb \
+	sdm670-cdp.dtb
 
 always		:= $(dtb-y)
 subdir-y	:= $(dts-dirs)
diff --git a/arch/arm64/boot/dts/qcom/pmi8998.dtsi b/arch/arm64/boot/dts/qcom/pmi8998.dtsi
index 886e792..5c83802 100644
--- a/arch/arm64/boot/dts/qcom/pmi8998.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi8998.dtsi
@@ -211,7 +211,7 @@
 			compatible = "qcom,qpnp-pdphy";
 			reg = <0x1700 0x100>;
 			vdd-pdphy-supply = <&pm8998_l24>;
-			vbus-supply = <&smb2_vbus>;
+			vbus-supply = <&ext_5v_boost>;
 			vconn-supply = <&smb2_vconn>;
 			interrupts = <0x2 0x17 0x0 IRQ_TYPE_EDGE_RISING>,
 				     <0x2 0x17 0x1 IRQ_TYPE_EDGE_RISING>,
diff --git a/arch/arm64/boot/dts/qcom/sdm830-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm670-cdp.dts
similarity index 70%
copy from arch/arm64/boot/dts/qcom/sdm830-pinctrl.dtsi
copy to arch/arm64/boot/dts/qcom/sdm670-cdp.dts
index 4b3fa93..7e5947b 100644
--- a/arch/arm64/boot/dts/qcom/sdm830-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-cdp.dts
@@ -10,14 +10,14 @@
  * GNU General Public License for more details.
  */
 
-&soc {
-	tlmm: pinctrl@03400000 {
-		compatible = "qcom,sdm830-pinctrl";
-		reg = <0x03400000 0xc00000>;
-		interrupts = <0 208 0>;
-		gpio-controller;
-		#gpio-cells = <2>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
-	};
+
+/dts-v1/;
+
+#include "sdm670.dtsi"
+#include "sdm670-cdp.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM670 CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,board-id = <1 0>;
 };
diff --git a/arch/arm64/boot/dts/qcom/sdm830-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
similarity index 78%
rename from arch/arm64/boot/dts/qcom/sdm830-cdp.dtsi
rename to arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
index c7bbef0..6ea92ee 100644
--- a/arch/arm64/boot/dts/qcom/sdm830-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* 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
@@ -9,6 +9,3 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-
-#include "sdm845-cdp.dtsi"
-#include "sdm830-pinctrl.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/sdm830-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm670-mtp.dts
similarity index 70%
copy from arch/arm64/boot/dts/qcom/sdm830-pinctrl.dtsi
copy to arch/arm64/boot/dts/qcom/sdm670-mtp.dts
index 4b3fa93..1de40b7 100644
--- a/arch/arm64/boot/dts/qcom/sdm830-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-mtp.dts
@@ -10,14 +10,14 @@
  * GNU General Public License for more details.
  */
 
-&soc {
-	tlmm: pinctrl@03400000 {
-		compatible = "qcom,sdm830-pinctrl";
-		reg = <0x03400000 0xc00000>;
-		interrupts = <0 208 0>;
-		gpio-controller;
-		#gpio-cells = <2>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
-	};
+
+/dts-v1/;
+
+#include "sdm670.dtsi"
+#include "sdm670-mtp.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM670 MTP";
+	compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+	qcom,board-id = <8 0>;
 };
diff --git a/arch/arm64/boot/dts/qcom/sdm830-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
similarity index 78%
rename from arch/arm64/boot/dts/qcom/sdm830-mtp.dtsi
rename to arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
index b2d607d..6ea92ee 100644
--- a/arch/arm64/boot/dts/qcom/sdm830-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* 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
@@ -9,6 +9,3 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-
-#include "sdm845-mtp.dtsi"
-#include "sdm830-pinctrl.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/sdm830-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
similarity index 94%
rename from arch/arm64/boot/dts/qcom/sdm830-pinctrl.dtsi
rename to arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
index 4b3fa93..09ce9d2 100644
--- a/arch/arm64/boot/dts/qcom/sdm830-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
@@ -12,7 +12,7 @@
 
 &soc {
 	tlmm: pinctrl@03400000 {
-		compatible = "qcom,sdm830-pinctrl";
+		compatible = "qcom,sdm670-pinctrl";
 		reg = <0x03400000 0xc00000>;
 		interrupts = <0 208 0>;
 		gpio-controller;
diff --git a/arch/arm64/boot/dts/qcom/sdm830-rumi.dts b/arch/arm64/boot/dts/qcom/sdm670-rumi.dts
similarity index 65%
rename from arch/arm64/boot/dts/qcom/sdm830-rumi.dts
rename to arch/arm64/boot/dts/qcom/sdm670-rumi.dts
index 2485051..6201488 100644
--- a/arch/arm64/boot/dts/qcom/sdm830-rumi.dts
+++ b/arch/arm64/boot/dts/qcom/sdm670-rumi.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * 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
@@ -14,12 +14,16 @@
 /dts-v1/;
 /memreserve/ 0x90000000 0x00000100;
 
-#include "sdm830.dtsi"
-#include "sdm830-rumi.dtsi"
-
+#include "sdm670.dtsi"
+#include "sdm670-rumi.dtsi"
 / {
-	model = "Qualcomm Technologies, Inc. SDM830 RUMI";
-	compatible = "qcom,sdm830-rumi", "qcom,sdm830", "qcom,rumi";
+	model = "Qualcomm Technologies, Inc. SDM670 RUMI";
+	compatible = "qcom,sdm670-rumi", "qcom,sdm670", "qcom,rumi";
 	qcom,board-id = <15 0>;
 };
 
+&soc {
+	wdog: qcom,wdt@17980000{
+		status = "disabled";
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm830-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-rumi.dtsi
similarity index 77%
copy from arch/arm64/boot/dts/qcom/sdm830-cdp.dtsi
copy to arch/arm64/boot/dts/qcom/sdm670-rumi.dtsi
index c7bbef0..6ea92ee 100644
--- a/arch/arm64/boot/dts/qcom/sdm830-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-rumi.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* 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
@@ -9,6 +9,3 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-
-#include "sdm845-cdp.dtsi"
-#include "sdm830-pinctrl.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
new file mode 100644
index 0000000..2cbb990
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -0,0 +1,547 @@
+/* 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.
+ */
+
+#include "skeleton64.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM670";
+	compatible = "qcom,sdm670";
+	qcom,msm-id = <336 0x0>;
+	interrupt-parent = <&intc>;
+
+	aliases { };
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		CPU0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			efficiency = <1024>;
+			cache-size = <0x8000>;
+			cpu-release-addr = <0x0 0x90000000>;
+			next-level-cache = <&L2_0>;
+			L2_0: l2-cache {
+				compatible = "arm,arch-cache";
+				cache-size = <0x20000>;
+				cache-level = <2>;
+				next-level-cache = <&L3_0>;
+				L3_0: l3-cache {
+					compatible = "arm,arch-cache";
+					cache-size = <0x100000>;
+					cache-level = <3>;
+				};
+			};
+			L1_I_0: l1-icache {
+				compatible = "arm,arch-cache";
+				qcom,dump-size = <0x9000>;
+			};
+			L1_D_0: l1-dcache {
+				compatible = "arm,arch-cache";
+				qcom,dump-size = <0x9000>;
+			};
+		};
+
+		CPU1: cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			efficiency = <1024>;
+			cache-size = <0x8000>;
+			cpu-release-addr = <0x0 0x90000000>;
+			next-level-cache = <&L2_100>;
+			L2_100: l2-cache {
+				compatible = "arm,arch-cache";
+				cache-size = <0x20000>;
+				cache-level = <2>;
+				next-level-cache = <&L3_0>;
+			};
+			L1_I_100: l1-icache {
+				compatible = "arm,arch-cache";
+				qcom,dump-size = <0x9000>;
+			};
+			L1_D_100: l1-dcache {
+				compatible = "arm,arch-cache";
+				qcom,dump-size = <0x9000>;
+			};
+		};
+
+		CPU2: cpu@200 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x200>;
+			enable-method = "psci";
+			efficiency = <1024>;
+			cache-size = <0x8000>;
+			cpu-release-addr = <0x0 0x90000000>;
+			next-level-cache = <&L2_200>;
+			L2_200: l2-cache {
+				compatible = "arm,arch-cache";
+				cache-size = <0x20000>;
+				cache-level = <2>;
+				next-level-cache = <&L3_0>;
+			};
+			L1_I_200: l1-icache {
+				compatible = "arm,arch-cache";
+				qcom,dump-size = <0x9000>;
+			};
+			L1_D_200: l1-dcache {
+				compatible = "arm,arch-cache";
+				qcom,dump-size = <0x9000>;
+			};
+		};
+
+		CPU3: cpu@300 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x300>;
+			enable-method = "psci";
+			efficiency = <1024>;
+			cache-size = <0x8000>;
+			cpu-release-addr = <0x0 0x90000000>;
+			next-level-cache = <&L2_300>;
+			L2_300: l2-cache {
+				compatible = "arm,arch-cache";
+				cache-size = <0x20000>;
+				cache-level = <2>;
+				next-level-cache = <&L3_0>;
+			};
+			L1_I_300: l1-icache {
+				compatible = "arm,arch-cache";
+				qcom,dump-size = <0x9000>;
+			};
+			L1_D_300: l1-dcache {
+				compatible = "arm,arch-cache";
+				qcom,dump-size = <0x9000>;
+			};
+		};
+
+		CPU4: cpu@400 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x400>;
+			enable-method = "psci";
+			efficiency = <1024>;
+			cache-size = <0x8000>;
+			cpu-release-addr = <0x0 0x90000000>;
+			next-level-cache = <&L2_400>;
+			L2_400: l2-cache {
+				compatible = "arm,arch-cache";
+				cache-size = <0x20000>;
+				cache-level = <2>;
+				next-level-cache = <&L3_0>;
+			};
+			L1_I_400: l1-icache {
+				compatible = "arm,arch-cache";
+				qcom,dump-size = <0x9000>;
+			};
+			L1_D_400: l1-dcache {
+				compatible = "arm,arch-cache";
+				qcom,dump-size = <0x9000>;
+			};
+		};
+
+		CPU5: cpu@500 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x500>;
+			enable-method = "psci";
+			efficiency = <1024>;
+			cache-size = <0x8000>;
+			cpu-release-addr = <0x0 0x90000000>;
+			next-level-cache = <&L2_500>;
+			L2_500: l2-cache {
+				compatible = "arm,arch-cache";
+				cache-size = <0x20000>;
+				cache-level = <2>;
+				next-level-cache = <&L3_0>;
+			};
+			L1_I_500: l1-icache {
+				compatible = "arm,arch-cache";
+				qcom,dump-size = <0x9000>;
+			};
+			L1_D_500: l1-dcache {
+				compatible = "arm,arch-cache";
+				qcom,dump-size = <0x9000>;
+			};
+		};
+
+		CPU6: cpu@600 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x600>;
+			enable-method = "psci";
+			efficiency = <1740>;
+			cache-size = <0x10000>;
+			cpu-release-addr = <0x0 0x90000000>;
+			next-level-cache = <&L2_600>;
+			L2_600: l2-cache {
+				compatible = "arm,arch-cache";
+				cache-size = <0x40000>;
+				cache-level = <2>;
+				next-level-cache = <&L3_0>;
+			};
+			L1_I_600: l1-icache {
+				compatible = "arm,arch-cache";
+				qcom,dump-size = <0x12000>;
+			};
+			L1_D_600: l1-dcache {
+				compatible = "arm,arch-cache";
+				qcom,dump-size = <0x12000>;
+			};
+		};
+
+		CPU7: cpu@700 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x700>;
+			enable-method = "psci";
+			efficiency = <1740>;
+			cache-size = <0x10000>;
+			cpu-release-addr = <0x0 0x90000000>;
+			next-level-cache = <&L2_700>;
+			L2_700: l2-cache {
+				compatible = "arm,arch-cache";
+				cache-size = <0x40000>;
+				cache-level = <2>;
+				next-level-cache = <&L3_0>;
+			};
+			L1_I_700: l1-icache {
+				compatible = "arm,arch-cache";
+				qcom,dump-size = <0x12000>;
+			};
+			L1_D_700: l1-dcache {
+				compatible = "arm,arch-cache";
+				qcom,dump-size = <0x12000>;
+			};
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+
+				core1 {
+					cpu = <&CPU1>;
+				};
+
+				core2 {
+					cpu = <&CPU2>;
+				};
+
+				core3 {
+					cpu = <&CPU3>;
+				};
+
+				core4 {
+					cpu = <&CPU4>;
+				};
+
+				core5 {
+					cpu = <&CPU5>;
+				};
+			};
+			cluster1 {
+				core0 {
+					cpu = <&CPU6>;
+				};
+
+				core1 {
+					cpu = <&CPU7>;
+				};
+			};
+		};
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	soc: soc { };
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+	};
+};
+
+&soc {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges = <0 0 0 0xffffffff>;
+	compatible = "simple-bus";
+
+	intc: interrupt-controller@17a00000 {
+		compatible = "arm,gic-v3";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		#redistributor-regions = <1>;
+		redistributor-stride = <0x0 0x20000>;
+		reg = <0x17a00000 0x10000>,     /* GICD */
+		      <0x17a60000 0x100000>;    /* GICR * 8 */
+		interrupts = <1 9 4>;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 1 0xf08>,
+			     <1 2 0xf08>,
+			     <1 3 0xf08>,
+			     <1 0 0xf08>;
+		clock-frequency = <19200000>;
+	};
+
+	timer@0x17c90000{
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		compatible = "arm,armv7-timer-mem";
+		reg = <0x17c90000 0x1000>;
+		clock-frequency = <19200000>;
+
+		frame@0x17ca0000 {
+			frame-number = <0>;
+			interrupts = <0 7 0x4>,
+				     <0 6 0x4>;
+			reg = <0x17ca0000 0x1000>,
+			      <0x17cb0000 0x1000>;
+		};
+
+		frame@17cc0000 {
+			frame-number = <1>;
+			interrupts = <0 8 0x4>;
+			reg = <0x17cc0000 0x1000>;
+			status = "disabled";
+		};
+
+		frame@17cd0000 {
+			frame-number = <2>;
+			interrupts = <0 9 0x4>;
+			reg = <0x17cd0000 0x1000>;
+			status = "disabled";
+		};
+
+		frame@17ce0000 {
+			frame-number = <3>;
+			interrupts = <0 10 0x4>;
+			reg = <0x17ce0000 0x1000>;
+			status = "disabled";
+		};
+
+		frame@17cf0000 {
+			frame-number = <4>;
+			interrupts = <0 11 0x4>;
+			reg = <0x17cf0000 0x1000>;
+			status = "disabled";
+		};
+
+		frame@17d00000 {
+			frame-number = <5>;
+			interrupts = <0 12 0x4>;
+			reg = <0x17d00000 0x1000>;
+			status = "disabled";
+		};
+
+		frame@17d10000 {
+			frame-number = <6>;
+			interrupts = <0 13 0x4>;
+			reg = <0x17d10000 0x1000>;
+			status = "disabled";
+		};
+	};
+
+	restart@10ac000 {
+		compatible = "qcom,pshold";
+		reg = <0xC264000 0x4>,
+		      <0x1fd3000 0x4>;
+		reg-names = "pshold-base", "tcsr-boot-misc-detect";
+	};
+
+	clock_cpucc: qcom,cpucc {
+		compatible = "qcom,dummycc";
+		clock-output-names = "cpucc_clocks";
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	wdog: qcom,wdt@17980000{
+		compatible = "qcom,msm-watchdog";
+		reg = <0x17980000 0x1000>;
+		reg-names = "wdt-base";
+		interrupts = <0 3 0>, <0 4 0>;
+		qcom,bark-time = <11000>;
+		qcom,pet-time = <10000>;
+		qcom,ipi-ping;
+		qcom,wakeup-enable;
+	};
+
+	qcom,msm-rtb {
+		compatible = "qcom,msm-rtb";
+		qcom,rtb-size = <0x100000>;
+	};
+
+	qcom,msm-imem@146bf000 {
+		compatible = "qcom,msm-imem";
+		reg = <0x146bf000 0x1000>;
+		ranges = <0x0 0x146bf000 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		mem_dump_table@10 {
+			compatible = "qcom,msm-imem-mem_dump_table";
+			reg = <0x10 8>;
+		};
+
+		restart_reason@65c {
+			compatible = "qcom,msm-imem-restart_reason";
+			reg = <0x65c 4>;
+		};
+
+		pil@94c {
+			compatible = "qcom,msm-imem-pil";
+			reg = <0x94c 200>;
+		};
+
+		kaslr_offset@6d0 {
+			compatible = "qcom,msm-imem-kaslr_offset";
+			reg = <0x6d0 12>;
+		};
+	};
+
+	cpuss_dump {
+		compatible = "qcom,cpuss-dump";
+		qcom,l1_i_cache0 {
+			qcom,dump-node = <&L1_I_0>;
+			qcom,dump-id = <0x60>;
+		};
+		qcom,l1_i_cache1 {
+			qcom,dump-node = <&L1_I_100>;
+			qcom,dump-id = <0x61>;
+		};
+		qcom,l1_i_cache2 {
+			qcom,dump-node = <&L1_I_200>;
+			qcom,dump-id = <0x62>;
+		};
+		qcom,l1_i_cache3 {
+			qcom,dump-node = <&L1_I_300>;
+			qcom,dump-id = <0x63>;
+		};
+		qcom,l1_i_cache100 {
+			qcom,dump-node = <&L1_I_400>;
+			qcom,dump-id = <0x64>;
+		};
+		qcom,l1_i_cache101 {
+			qcom,dump-node = <&L1_I_500>;
+			qcom,dump-id = <0x65>;
+		};
+		qcom,l1_i_cache102 {
+			qcom,dump-node = <&L1_I_600>;
+			qcom,dump-id = <0x66>;
+		};
+		qcom,l1_i_cache103 {
+			qcom,dump-node = <&L1_I_700>;
+			qcom,dump-id = <0x67>;
+		};
+		qcom,l1_d_cache0 {
+			qcom,dump-node = <&L1_D_0>;
+			qcom,dump-id = <0x80>;
+		};
+		qcom,l1_d_cache1 {
+			qcom,dump-node = <&L1_D_100>;
+			qcom,dump-id = <0x81>;
+		};
+		qcom,l1_d_cache2 {
+			qcom,dump-node = <&L1_D_200>;
+			qcom,dump-id = <0x82>;
+		};
+		qcom,l1_d_cache3 {
+			qcom,dump-node = <&L1_D_300>;
+			qcom,dump-id = <0x83>;
+		};
+		qcom,l1_d_cache100 {
+			qcom,dump-node = <&L1_D_400>;
+			qcom,dump-id = <0x84>;
+		};
+		qcom,l1_d_cache101 {
+			qcom,dump-node = <&L1_D_500>;
+			qcom,dump-id = <0x85>;
+		};
+		qcom,l1_d_cache102 {
+			qcom,dump-node = <&L1_D_600>;
+			qcom,dump-id = <0x86>;
+		};
+		qcom,l1_d_cache103 {
+			qcom,dump-node = <&L1_D_700>;
+			qcom,dump-id = <0x87>;
+		};
+	};
+
+	kryo3xx-erp {
+		compatible = "arm,arm64-kryo3xx-cpu-erp";
+		interrupts = <1 6 4>,
+			     <1 7 4>,
+			     <0 34 4>,
+			     <0 35 4>;
+
+		interrupt-names = "l1-l2-faultirq",
+				  "l1-l2-errirq",
+				  "l3-scu-errirq",
+				  "l3-scu-faultirq";
+	};
+
+	qcom,chd_sliver {
+		compatible = "qcom,core-hang-detect";
+		label = "silver";
+		qcom,threshold-arr = <0x17e00058 0x17e10058 0x17e20058
+					0x17e30058 0x17e40058 0x17e50058>;
+		qcom,config-arr = <0x17e00060 0x17e10060 0x17e20060
+					0x17e30060 0x17e40060 0x17e50060>;
+	};
+
+	qcom,chd_gold {
+		compatible = "qcom,core-hang-detect";
+		label = "gold";
+		qcom,threshold-arr = <0x17e60058 0x17e70058>;
+		qcom,config-arr = <0x17e60060 0x17e70060>;
+	};
+
+	qcom,ghd {
+		compatible = "qcom,gladiator-hang-detect-v2";
+		qcom,threshold-arr = <0x1799041c 0x17990420>;
+		qcom,config-reg = <0x17990434>;
+	};
+
+	qcom,msm-gladiator-v3@17900000 {
+		compatible = "qcom,msm-gladiator-v3";
+		reg = <0x17900000 0xd080>;
+		reg-names = "gladiator_base";
+		interrupts = <0 17 0>;
+	};
+
+	dcc: dcc_v2@10a2000 {
+		compatible = "qcom,dcc_v2";
+		reg = <0x10a2000 0x1000>,
+		      <0x10ae000 0x2000>;
+		reg-names = "dcc-base", "dcc-ram-base";
+	};
+
+};
+
+#include "sdm670-pinctrl.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/sdm830-cdp.dts b/arch/arm64/boot/dts/qcom/sdm830-cdp.dts
deleted file mode 100644
index dab4a9d..0000000
--- a/arch/arm64/boot/dts/qcom/sdm830-cdp.dts
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Copyright (c) 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.
- */
-
-
-/dts-v1/;
-
-#include "sdm830.dtsi"
-#include "sdm830-cdp.dtsi"
-
-/ {
-	model = "Qualcomm Technologies, Inc. SDM bat v1 CDP";
-	compatible = "qcom,sdm830-cdp", "qcom,sdm830", "qcom,cdp";
-	qcom,board-id = <1 0>;
-};
diff --git a/arch/arm64/boot/dts/qcom/sdm830-mtp.dts b/arch/arm64/boot/dts/qcom/sdm830-mtp.dts
deleted file mode 100644
index 5da16e6..0000000
--- a/arch/arm64/boot/dts/qcom/sdm830-mtp.dts
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Copyright (c) 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.
- */
-
-
-/dts-v1/;
-
-#include "sdm830.dtsi"
-#include "sdm830-mtp.dtsi"
-
-/ {
-	model = "Qualcomm Technologies, Inc. SDM bat v1 MTP";
-	compatible = "qcom,sdm830-mtp", "qcom,sdm830", "qcom,mtp";
-	qcom,board-id = <8 0>;
-};
diff --git a/arch/arm64/boot/dts/qcom/sdm830-rumi.dtsi b/arch/arm64/boot/dts/qcom/sdm830-rumi.dtsi
deleted file mode 100644
index 2bc5f3f..0000000
--- a/arch/arm64/boot/dts/qcom/sdm830-rumi.dtsi
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Copyright (c) 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.
- */
-
-/*
- * As a general rule, only version-specific property overrides should be placed
- * inside this file. Common device definitions should be placed inside the
- * sdm845-rumi.dtsi file.
- */
-
- #include "sdm845-rumi.dtsi"
-
diff --git a/arch/arm64/boot/dts/qcom/sdm830-sim.dts b/arch/arm64/boot/dts/qcom/sdm830-sim.dts
deleted file mode 100644
index 57cd155..0000000
--- a/arch/arm64/boot/dts/qcom/sdm830-sim.dts
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (c) 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.
- */
-
-
-/dts-v1/;
-/memreserve/ 0x90000000 0x00000100;
-
-#include "sdm830.dtsi"
-#include "sdm830-sim.dtsi"
-
-/ {
-	model = "Qualcomm Technologies, Inc. SDM830 SIM";
-	compatible = "qcom,sdm830-sim", "qcom,sdm830", "qcom,sim";
-	qcom,board-id = <16 0>;
-};
-
diff --git a/arch/arm64/boot/dts/qcom/sdm830-sim.dtsi b/arch/arm64/boot/dts/qcom/sdm830-sim.dtsi
deleted file mode 100644
index 85e8075..0000000
--- a/arch/arm64/boot/dts/qcom/sdm830-sim.dtsi
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Copyright (c) 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.
- */
-
-/*
- * As a general rule, only version-specific property overrides should be placed
- * inside this file. Common device definitions should be placed inside the
- * sdm845-sim.dtsi file.
- */
-
- #include "sdm845-sim.dtsi"
-
diff --git a/arch/arm64/boot/dts/qcom/sdm830.dtsi b/arch/arm64/boot/dts/qcom/sdm830.dtsi
deleted file mode 100644
index 81ae913..0000000
--- a/arch/arm64/boot/dts/qcom/sdm830.dtsi
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright (c) 2016-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.
- */
-
-/*
- * As a general rule, only version-specific property overrides should be placed
- * inside this file. Common device definitions should be placed inside the
- * sdm845.dtsi file.
- */
-
- #include "sdm845.dtsi"
-
-/ {
-	model = "Qualcomm Technologies, Inc. SDM830";
-	compatible = "qcom,sdm830";
-	qcom,msm-id = <328 0x0>;
-
-};
-
-&soc {
-	qcom,llcc@1300000 {
-		status = "disabled";
-	};
-
-	qcom,spss@1880000 {
-		status = "disabled";
-	};
-
-	qcom,glink-mailbox-xprt-spss@1885008 {
-		status = "disabled";
-	};
-};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-4k-panel-cdp.dts b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-cdp.dts
index f27b9da..e9b71b9 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-4k-panel-cdp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-cdp.dts
@@ -22,12 +22,12 @@
 	qcom,board-id = <1 1>;
 };
 
-&dsi_dual_nt35597_truly_cmd_display {
+&dsi_nt35597_truly_dsc_cmd_display {
 	/delete-property/ qcom,dsi-display-active;
 };
 
 &mdss_mdp {
-	connectors = <&sde_rscc &sde_wb &dsi_sharp_4k_dsc_video_display>;
+	connectors = <&sde_rscc &sde_wb>;
 };
 
 &dsi_sharp_4k_dsc_video {
@@ -35,7 +35,7 @@
 	qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
 	qcom,mdss-dsi-bl-min-level = <1>;
 	qcom,mdss-dsi-bl-max-level = <4095>;
-	qcom,mdss-dsi-panel-mode-gpio-state = "dual_port";
+	qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
 	qcom,panel-mode-gpio = <&tlmm 52 0>;
 	qcom,platform-te-gpio = <&tlmm 10 0>;
 	qcom,platform-reset-gpio = <&tlmm 6 0>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-4k-panel-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-mtp.dts
index 4627e60..73df071 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-4k-panel-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-4k-panel-mtp.dts
@@ -22,12 +22,12 @@
 	qcom,board-id = <8 1>;
 };
 
-&dsi_dual_nt35597_truly_cmd_display {
+&dsi_nt35597_truly_dsc_cmd_display {
 	/delete-property/ qcom,dsi-display-active;
 };
 
 &mdss_mdp {
-	connectors = <&sde_rscc &sde_wb &dsi_sharp_4k_dsc_video_display>;
+	connectors = <&sde_rscc &sde_wb>;
 };
 
 &dsi_sharp_4k_dsc_video {
@@ -35,7 +35,7 @@
 	qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
 	qcom,mdss-dsi-bl-min-level = <1>;
 	qcom,mdss-dsi-bl-max-level = <4095>;
-	qcom,mdss-dsi-panel-mode-gpio-state = "dual_port";
+	qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
 	qcom,panel-mode-gpio = <&tlmm 52 0>;
 	qcom,platform-te-gpio = <&tlmm 10 0>;
 	qcom,platform-reset-gpio = <&tlmm 6 0>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-audio.dtsi b/arch/arm64/boot/dts/qcom/sdm845-audio.dtsi
index fcc09a0..628b6cc 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-audio.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-audio.dtsi
@@ -169,6 +169,14 @@
 	qocm,wcd-dsp-glink {
 		compatible = "qcom,wcd-dsp-glink";
 	};
+
+	qcom,wcd-dsp-mgr {
+		compatible = "qcom,wcd-dsp-mgr";
+		qcom,wdsp-components = <&wcd934x_cdc 0>,
+				       <&wcd_spi_0 1>,
+				       <&glink_spi_xprt_wdsp 2>;
+		qcom,img-filename = "cpe_9340";
+	};
 };
 
 &slim_aud {
@@ -229,5 +237,13 @@
 		qcom,cdc-mad-dmic-rate = <600000>;
 
 		qcom,wdsp-cmpnt-dev-name = "tavil_codec";
+
+		wcd_spi_0: wcd_spi {
+			compatible = "qcom,wcd-spi-v2";
+			qcom,master-bus-num = <0>;
+			qcom,chip-select = <0>;
+			qcom,max-frequency = <9600000>;
+			qcom,mem-base-addr = <0x100000>;
+		};
 	};
 };
diff --git a/arch/arm64/boot/dts/qcom/sdm845-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cdp.dtsi
index 7038d48..a1e0e4f 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-cdp.dtsi
@@ -237,7 +237,7 @@
 	qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
 	qcom,mdss-dsi-bl-min-level = <1>;
 	qcom,mdss-dsi-bl-max-level = <4095>;
-	qcom,mdss-dsi-panel-mode-gpio-state = "dual_port";
+	qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
 	qcom,panel-mode-gpio = <&tlmm 52 0>;
 	qcom,platform-reset-gpio = <&tlmm 6 0>;
 };
@@ -247,7 +247,29 @@
 	qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
 	qcom,mdss-dsi-bl-min-level = <1>;
 	qcom,mdss-dsi-bl-max-level = <4095>;
-	qcom,mdss-dsi-panel-mode-gpio-state = "dual_port";
+	qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
+	qcom,panel-mode-gpio = <&tlmm 52 0>;
+	qcom,platform-reset-gpio = <&tlmm 6 0>;
+	qcom,platform-te-gpio = <&tlmm 10 0>;
+};
+
+&dsi_nt35597_truly_dsc_cmd {
+	qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+	qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+	qcom,mdss-dsi-bl-min-level = <1>;
+	qcom,mdss-dsi-bl-max-level = <4095>;
+	qcom,mdss-dsi-mode-sel-gpio-state = "single_port";
+	qcom,panel-mode-gpio = <&tlmm 52 0>;
+	qcom,platform-reset-gpio = <&tlmm 6 0>;
+	qcom,platform-te-gpio = <&tlmm 10 0>;
+};
+
+&dsi_nt35597_truly_dsc_video {
+	qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+	qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+	qcom,mdss-dsi-bl-min-level = <1>;
+	qcom,mdss-dsi-bl-max-level = <4095>;
+	qcom,mdss-dsi-mode-sel-gpio-state = "single_port";
 	qcom,panel-mode-gpio = <&tlmm 52 0>;
 	qcom,platform-reset-gpio = <&tlmm 6 0>;
 };
@@ -276,7 +298,7 @@
 	qcom,platform-reset-gpio = <&tlmm 6 0>;
 };
 
-&dsi_dual_nt35597_truly_cmd_display {
+&dsi_nt35597_truly_dsc_cmd_display {
 	qcom,dsi-display-active;
 };
 
@@ -522,3 +544,7 @@
 &wil6210 {
 	status = "ok";
 };
+
+&ext_5v_boost {
+	status = "ok";
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-coresight.dtsi b/arch/arm64/boot/dts/qcom/sdm845-coresight.dtsi
index 97573ea..e32ec6e 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-coresight.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-coresight.dtsi
@@ -780,7 +780,8 @@
 	};
 
 	tpdm_lpass: tpdm@6844000 {
-		compatible = "qcom,coresight-tpdm";
+		compatible = "arm,primecell";
+		arm,primecell-periphid = <0x0003b968>;
 		reg = <0x6844000 0x1000>;
 		reg-names = "tpdm-base";
 
diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi
index 521fd6b3..85bec57 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi
@@ -89,7 +89,7 @@
 	qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
 	qcom,mdss-dsi-bl-min-level = <1>;
 	qcom,mdss-dsi-bl-max-level = <4095>;
-	qcom,mdss-dsi-panel-mode-gpio-state = "dual_port";
+	qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
 	qcom,panel-mode-gpio = <&tlmm 52 0>;
 	qcom,platform-reset-gpio = <&tlmm 6 0>;
 };
@@ -99,9 +99,31 @@
 	qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
 	qcom,mdss-dsi-bl-min-level = <1>;
 	qcom,mdss-dsi-bl-max-level = <4095>;
-	qcom,mdss-dsi-panel-mode-gpio-state = "dual_port";
+	qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
 	qcom,panel-mode-gpio = <&tlmm 52 0>;
 	qcom,platform-reset-gpio = <&tlmm 6 0>;
+	qcom,platform-te-gpio = <&tlmm 10 0>;
+};
+
+&dsi_nt35597_truly_dsc_video {
+	qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+	qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+	qcom,mdss-dsi-bl-min-level = <1>;
+	qcom,mdss-dsi-bl-max-level = <4095>;
+	qcom,mdss-dsi-mode-sel-gpio-state = "single_port";
+	qcom,panel-mode-gpio = <&tlmm 52 0>;
+	qcom,platform-reset-gpio = <&tlmm 6 0>;
+};
+
+&dsi_nt35597_truly_dsc_cmd {
+	qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+	qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+	qcom,mdss-dsi-bl-min-level = <1>;
+	qcom,mdss-dsi-bl-max-level = <4095>;
+	qcom,mdss-dsi-mode-sel-gpio-state = "single_port";
+	qcom,panel-mode-gpio = <&tlmm 52 0>;
+	qcom,platform-reset-gpio = <&tlmm 6 0>;
+	qcom,platform-te-gpio = <&tlmm 10 0>;
 };
 
 &dsi_sim_vid {
@@ -128,7 +150,7 @@
 	qcom,platform-reset-gpio = <&tlmm 6 0>;
 };
 
-&dsi_dual_nt35597_truly_cmd_display {
+&dsi_nt35597_truly_dsc_cmd_display {
 	qcom,dsi-display-active;
 };
 
@@ -299,6 +321,10 @@
 	status = "okay";
 };
 
+&ext_5v_boost {
+	status = "ok";
+};
+
 &usb_qmp_phy {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi
index f534891..1fbd8a2 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi
@@ -2839,4 +2839,13 @@
 			power-source = <0>;
 		};
 	};
+
+	usb2_ext_5v_boost {
+		usb2_ext_5v_boost_default: usb2_ext_5v_boost_default {
+			pins = "gpio10";
+			function = "normal";
+			output-low;
+			power-source = <0>;
+		};
+	};
 };
diff --git a/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi b/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi
index 3bf1ea4..4dba65b 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi
@@ -169,7 +169,7 @@
 };
 
 &mdss_mdp {
-	connectors = <&sde_rscc &sde_wb &dsi_sharp_4k_dsc_video_display>;
+	connectors = <&sde_rscc &sde_wb>;
 };
 
 &dsi_sharp_4k_dsc_video {
@@ -177,7 +177,7 @@
 	qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
 	qcom,mdss-dsi-bl-min-level = <1>;
 	qcom,mdss-dsi-bl-max-level = <4095>;
-	qcom,mdss-dsi-panel-mode-gpio-state = "dual_port";
+	qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
 	qcom,panel-mode-gpio = <&tlmm 52 0>;
 	qcom,platform-te-gpio = <&tlmm 10 0>;
 	qcom,platform-reset-gpio = <&tlmm 6 0>;
@@ -191,3 +191,7 @@
 &wil6210 {
 	status = "ok";
 };
+
+&ext_5v_boost {
+	status = "ok";
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm845-regulator.dtsi
index 19b8744..7befe3b 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-regulator.dtsi
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  */
 
+#include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
 
 /* Stub regulators */
@@ -1260,8 +1261,12 @@
 		pm8005_s1_level: regulator-s1-level {
 			regulator-name = "pm8005_s1_level";
 			qcom,set = <RPMH_REGULATOR_SET_ALL>;
-			regulator-min-microvolt = <RPMH_REGULATOR_LEVEL_OFF>;
-			regulator-max-microvolt = <RPMH_REGULATOR_LEVEL_MAX>;
+			regulator-min-microvolt
+				= <RPMH_REGULATOR_LEVEL_MIN_SVS>;
+			regulator-max-microvolt
+				= <RPMH_REGULATOR_LEVEL_MAX>;
+			qcom,init-voltage-level
+				= <RPMH_REGULATOR_LEVEL_MIN_SVS>;
 		};
 	};
 
@@ -1290,13 +1295,21 @@
 			qcom,init-voltage = <600000>;
 		};
 	};
+
+	ext_5v_boost: ext_5v_boost {
+		status = "disabled";
+		compatible = "regulator-fixed";
+		regulator-name = "ext_5v_boost";
+		gpio = <&pmi8998_gpios 10 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+
+		regulator-enable-ramp-delay = <1600>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb2_ext_5v_boost_default>;
+	};
 };
 
 &pmi8998_charger {
-	smb2_vbus: qcom,smb2-vbus {
-		regulator-name = "smb2-vbus";
-	};
-
 	smb2_vconn: qcom,smb2-vconn {
 		regulator-name = "smb2-vconn";
 	};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
index 255c0b3..bf58da6 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
@@ -248,10 +248,10 @@
 		label = "dsi_nt35597_truly_dsc_cmd_display";
 		qcom,display-type = "primary";
 
-		qcom,dsi-ctrl = <&mdss_dsi0 &mdss_dsi1>;
-		qcom,dsi-phy = <&mdss_dsi_phy0 &mdss_dsi_phy1>;
-		clocks = <&mdss_dsi0_pll BYTECLK_MUX_0_CLK>,
-			<&mdss_dsi0_pll PCLK_MUX_0_CLK>;
+		qcom,dsi-ctrl = <&mdss_dsi1>;
+		qcom,dsi-phy = <&mdss_dsi_phy1>;
+		clocks = <&mdss_dsi1_pll BYTECLK_MUX_1_CLK>,
+			<&mdss_dsi1_pll PCLK_MUX_1_CLK>;
 		clock-names = "src_byte_clk", "src_pixel_clk";
 
 		pinctrl-names = "panel_active", "panel_suspend";
@@ -272,10 +272,10 @@
 		label = "dsi_nt35597_truly_dsc_video_display";
 		qcom,display-type = "primary";
 
-		qcom,dsi-ctrl = <&mdss_dsi0 &mdss_dsi1>;
-		qcom,dsi-phy = <&mdss_dsi_phy0 &mdss_dsi_phy1>;
-		clocks = <&mdss_dsi0_pll BYTECLK_MUX_0_CLK>,
-			<&mdss_dsi0_pll PCLK_MUX_0_CLK>;
+		qcom,dsi-ctrl = <&mdss_dsi1>;
+		qcom,dsi-phy = <&mdss_dsi_phy1>;
+		clocks = <&mdss_dsi1_pll BYTECLK_MUX_1_CLK>,
+			<&mdss_dsi1_pll PCLK_MUX_1_CLK>;
 		clock-names = "src_byte_clk", "src_pixel_clk";
 
 		pinctrl-names = "panel_active", "panel_suspend";
@@ -371,7 +371,7 @@
 };
 
 &mdss_mdp {
-	connectors = <&sde_rscc &sde_wb &dsi_dual_nt35597_truly_cmd_display>;
+	connectors = <&sde_rscc &sde_wb>;
 };
 
 &dsi_dual_nt35597_truly_video {
@@ -396,7 +396,8 @@
 	qcom,mdss-dsi-panel-phy-timings = [00 15 05 05 20 1f 05 05 03 03 04 00];
 	qcom,mdss-dsi-t-clk-post = <0x0b>;
 	qcom,mdss-dsi-t-clk-pre = <0x23>;
-	qcom,display-topology = <2 2 2>;
+	qcom,display-topology = <1 1 1>,
+				<2 2 1>;
 	qcom,default-topology-index = <0>;
 };
 
@@ -404,7 +405,8 @@
 	qcom,mdss-dsi-panel-phy-timings = [00 15 05 05 20 1f 05 05 03 03 04 00];
 	qcom,mdss-dsi-t-clk-post = <0x0b>;
 	qcom,mdss-dsi-t-clk-pre = <0x23>;
-	qcom,display-topology = <2 2 2>;
+	qcom,display-topology = <1 1 1>,
+				<2 2 1>;
 	qcom,default-topology-index = <0>;
 };
 
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sde.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sde.dtsi
index 76c07b7..c350800 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-sde.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-sde.dtsi
@@ -264,7 +264,19 @@
 		interrupt-parent = <&mdss_mdp>;
 		interrupts = <2 0>;
 
+		/* Offline rotator QoS setting */
 		qcom,mdss-rot-vbif-qos-setting = <3 3 3 3 3 3 3 3>;
+		qcom,mdss-rot-cdp-setting = <1 1>;
+		qcom,mdss-rot-qos-lut = <0x0 0x0 0x0 0x0>;
+		qcom,mdss-rot-danger-lut = <0x0 0x0>;
+		qcom,mdss-rot-safe-lut = <0x0000ffff 0x0000ffff>;
+
+		/* Inline rotator QoS Setting */
+		/* setting default register values for RD - qos/danger/safe */
+		qcom,mdss-inline-rot-qos-lut = <0x44556677 0x00112233
+							0x44556677 0x00112233>;
+		qcom,mdss-inline-rot-danger-lut = <0x0055aaff 0x0000ffff>;
+		qcom,mdss-inline-rot-safe-lut = <0x0000f000 0x0000ff00>;
 
 		qcom,mdss-default-ot-rd-limit = <32>;
 		qcom,mdss-default-ot-wr-limit = <32>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 4527e5a..a38ac59 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -4019,6 +4019,21 @@
 			qcom,dump-id = <0xf1>;
 		};
 
+		tmc_etr_reg_dump {
+			qcom,dump-size = <0x1000>;
+			qcom,dump-id = <0x100>;
+		};
+
+		tmc_etf_reg_dump {
+			qcom,dump-size = <0x1000>;
+			qcom,dump-id = <0x101>;
+		};
+
+		tmc_etf_swao_reg_dump {
+			qcom,dump-size = <0x1000>;
+			qcom,dump-id = <0x102>;
+		};
+
 		misc_data_dump {
 			qcom,dump-size = <0x1000>;
 			qcom,dump-id = <0xe8>;
diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig
index 12b1f09..8c20b3f 100644
--- a/arch/arm64/configs/sdm845-perf_defconfig
+++ b/arch/arm64/configs/sdm845-perf_defconfig
@@ -47,7 +47,7 @@
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_ARCH_QCOM=y
 CONFIG_ARCH_SDM845=y
-CONFIG_ARCH_SDM830=y
+CONFIG_ARCH_SDM670=y
 CONFIG_PCI=y
 CONFIG_PCI_MSM=y
 CONFIG_SCHED_MC=y
@@ -222,6 +222,7 @@
 CONFIG_CFG80211=y
 CONFIG_CFG80211_INTERNAL_REGDB=y
 CONFIG_RFKILL=y
+CONFIG_NFC_NQ=y
 CONFIG_IPC_ROUTER=y
 CONFIG_IPC_ROUTER_SECURITY=y
 CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
@@ -296,7 +297,7 @@
 CONFIG_SPMI=y
 CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y
 CONFIG_PINCTRL_SDM845=y
-CONFIG_PINCTRL_SDM830=y
+CONFIG_PINCTRL_SDM670=y
 CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig
index 23b1215..0bebc63b 100644
--- a/arch/arm64/configs/sdm845_defconfig
+++ b/arch/arm64/configs/sdm845_defconfig
@@ -52,7 +52,7 @@
 # CONFIG_IOSCHED_DEADLINE is not set
 CONFIG_ARCH_QCOM=y
 CONFIG_ARCH_SDM845=y
-CONFIG_ARCH_SDM830=y
+CONFIG_ARCH_SDM670=y
 CONFIG_PCI=y
 CONFIG_PCI_MSM=y
 CONFIG_SCHED_MC=y
@@ -232,6 +232,7 @@
 CONFIG_CFG80211_INTERNAL_REGDB=y
 # CONFIG_CFG80211_CRDA_SUPPORT is not set
 CONFIG_RFKILL=y
+CONFIG_NFC_NQ=y
 CONFIG_IPC_ROUTER=y
 CONFIG_IPC_ROUTER_SECURITY=y
 CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
@@ -305,7 +306,7 @@
 CONFIG_SPMI=y
 CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y
 CONFIG_PINCTRL_SDM845=y
-CONFIG_PINCTRL_SDM830=y
+CONFIG_PINCTRL_SDM670=y
 CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
diff --git a/drivers/devfreq/governor_msm_adreno_tz.c b/drivers/devfreq/governor_msm_adreno_tz.c
index 43d8fef..e8bfff2 100644
--- a/drivers/devfreq/governor_msm_adreno_tz.c
+++ b/drivers/devfreq/governor_msm_adreno_tz.c
@@ -548,10 +548,6 @@ static int tz_handler(struct devfreq *devfreq, unsigned int event, void *data)
 					(devfreq->profile),
 					struct msm_adreno_extended_profile,
 					profile);
-	if (devfreq == NULL) {
-		pr_err(TAG "NULL defvreq passed to tz_handler\n");
-		return -EFAULT;
-	}
 
 	switch (event) {
 	case DEVFREQ_GOV_START:
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 75bce8a..0f6e36f 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -292,6 +292,27 @@ int dp_connector_post_init(struct drm_connector *connector,
 	return 0;
 }
 
+int dp_connector_get_topology(const struct drm_display_mode *drm_mode,
+	struct msm_display_topology *topology, u32 max_mixer_width)
+{
+	const u32 dual_lm = 2;
+	const u32 single_lm = 1;
+	const u32 single_intf = 1;
+	const u32 no_enc = 0;
+
+	if (!drm_mode || !topology || !max_mixer_width) {
+		pr_err("invalid params\n");
+		return -EINVAL;
+	}
+
+	topology->num_lm = (max_mixer_width <= drm_mode->hdisplay) ?
+							dual_lm : single_lm;
+	topology->num_enc = no_enc;
+	topology->num_intf = single_intf;
+
+	return 0;
+}
+
 int dp_connector_get_info(struct msm_display_info *info, void *data)
 {
 	struct dsi_display *display = data;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h
index 4ff1e07..bef3758 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.h
+++ b/drivers/gpu/drm/msm/dp/dp_drm.h
@@ -73,6 +73,17 @@ enum drm_mode_status dp_connector_mode_valid(struct drm_connector *connector,
 		struct drm_display_mode *mode,
 		void *display);
 
+/**
+ * dp_connector_get_topology - retrieve current topology for the mode selected
+ * @drm_mode: Display mode set for the display
+ * @topology: Out parameter. Topology for the mode.
+ * @max_mixer_width: max width supported by HW layer mixer
+ * Returns: zero on success
+ */
+int dp_connector_get_topology(const struct drm_display_mode *drm_mode,
+		struct msm_display_topology *topology,
+		u32 max_mixer_width);
+
 int dp_connector_get_info(struct msm_display_info *info, void *display);
 
 int dp_drm_bridge_init(void *display,
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index 39b797e..da7a7c0 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -879,14 +879,12 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
 	int rc = 0;
 	struct mipi_dsi_packet packet;
 	struct dsi_ctrl_cmd_dma_fifo_info cmd;
+	struct dsi_ctrl_cmd_dma_info cmd_mem;
 	u32 hw_flags = 0;
 	u32 length = 0;
 	u8 *buffer = NULL;
-
-	if (!(flags & DSI_CTRL_CMD_FIFO_STORE)) {
-		pr_err("Memory DMA is not supported, use FIFO\n");
-		goto error;
-	}
+	u32 cnt = 0;
+	u8 *cmdbuf;
 
 	rc = mipi_dsi_create_packet(&packet, msg);
 	if (rc) {
@@ -894,7 +892,32 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
 		goto error;
 	}
 
-	if (flags & DSI_CTRL_CMD_FIFO_STORE) {
+	if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
+		rc = dsi_ctrl_copy_and_pad_cmd(dsi_ctrl,
+				&packet,
+				&buffer,
+				&length);
+
+		if (rc) {
+			pr_err("[%s] failed to copy message, rc=%d\n",
+					dsi_ctrl->name, rc);
+			goto error;
+		}
+
+		cmd_mem.offset = dsi_ctrl->cmd_buffer_iova;
+		cmd_mem.length = length;
+		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;
+
+		cmdbuf = (u8 *)(dsi_ctrl->vaddr);
+		for (cnt = 0; cnt < length; cnt++)
+			cmdbuf[cnt] = buffer[cnt];
+
+	} else if (flags & DSI_CTRL_CMD_FIFO_STORE) {
 		rc = dsi_ctrl_copy_and_pad_cmd(dsi_ctrl,
 					       &packet,
 					       &buffer,
@@ -920,10 +943,15 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
 	if (!(flags & DSI_CTRL_CMD_DEFER_TRIGGER))
 		reinit_completion(&dsi_ctrl->int_info.cmd_dma_done);
 
-	if (flags & DSI_CTRL_CMD_FIFO_STORE)
+	if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
+		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,
 						      hw_flags);
+	}
 
 	if (!(flags & DSI_CTRL_CMD_DEFER_TRIGGER)) {
 		u32 retry = 10;
@@ -2171,14 +2199,14 @@ int dsi_ctrl_set_vid_engine_state(struct dsi_ctrl *dsi_ctrl,
 }
 
 /**
-  * dsi_ctrl_set_ulps() - set ULPS state for DSI lanes.
-  * @dsi_ctrl:		DSI controller handle.
-  * @enable:		enable/disable ULPS.
-  *
-  * ULPS can be enabled/disabled after DSI host engine is turned on.
-  *
-  * Return: error code.
-  */
+ * dsi_ctrl_set_ulps() - set ULPS state for DSI lanes.
+ * @dsi_ctrl:		DSI controller handle.
+ * @enable:		enable/disable ULPS.
+ *
+ * ULPS can be enabled/disabled after DSI host engine is turned on.
+ *
+ * Return: error code.
+ */
 int dsi_ctrl_set_ulps(struct dsi_ctrl *dsi_ctrl, bool enable)
 {
 	int rc = 0;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
index f89cb68..7f36fde 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
@@ -33,12 +33,15 @@
  * @DSI_CTRL_CMD_DEFER_TRIGGER:    Defer the command trigger to later.
  * @DSI_CTRL_CMD_FIFO_STORE:       Use FIFO for command transfer in place of
  *				   reading data from memory.
+ * @DSI_CTRL_CMD_FETCH_MEMORY:     Fetch command from memory through AXI bus
+ *				   and transfer it.
  */
 #define DSI_CTRL_CMD_READ             0x1
 #define DSI_CTRL_CMD_BROADCAST        0x2
 #define DSI_CTRL_CMD_BROADCAST_MASTER 0x4
 #define DSI_CTRL_CMD_DEFER_TRIGGER    0x8
 #define DSI_CTRL_CMD_FIFO_STORE       0x10
+#define DSI_CTRL_CMD_FETCH_MEMORY     0x20
 
 /**
  * enum dsi_power_state - defines power states for dsi controller.
@@ -188,6 +191,8 @@ struct dsi_ctrl_interrupts {
  * @roi:                 Partial update region of interest.
  *                       Origin is top left of this CTRL.
  * @tx_cmd_buf:          Tx command buffer.
+ * @cmd_buffer_iova:     cmd buffer mapped address.
+ * @vaddr:		 CPU virtual address of cmd buffer.
  * @cmd_buffer_size:     Size of command buffer.
  * @debugfs_root:        Root for debugfs entries.
  */
@@ -221,6 +226,8 @@ struct dsi_ctrl {
 	/* Command tx and rx */
 	struct drm_gem_object *tx_cmd_buf;
 	u32 cmd_buffer_size;
+	u32 cmd_buffer_iova;
+	void *vaddr;
 
 	/* Debug Information */
 	struct dentry *debugfs_root;
@@ -377,14 +384,14 @@ int dsi_ctrl_host_init(struct dsi_ctrl *dsi_ctrl);
 int dsi_ctrl_host_deinit(struct dsi_ctrl *dsi_ctrl);
 
 /**
-  * dsi_ctrl_set_ulps() - set ULPS state for DSI lanes.
-  * @dsi_ctrl:		DSI controller handle.
-  * @enable:		enable/disable ULPS.
-  *
-  * ULPS can be enabled/disabled after DSI host engine is turned on.
-  *
-  * Return: error code.
-  */
+ * dsi_ctrl_set_ulps() - set ULPS state for DSI lanes.
+ * @dsi_ctrl:		DSI controller handle.
+ * @enable:		enable/disable ULPS.
+ *
+ * ULPS can be enabled/disabled after DSI host engine is turned on.
+ *
+ * Return: error code.
+ */
 int dsi_ctrl_set_ulps(struct dsi_ctrl *dsi_ctrl, bool enable);
 
 /**
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index c2cf2cb..133dc93 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -16,6 +16,7 @@
 
 #include <linux/list.h>
 #include <linux/of.h>
+#include <linux/err.h>
 
 #include "msm_drv.h"
 #include "dsi_display.h"
@@ -27,10 +28,14 @@
 #include "dsi_pwr.h"
 
 #define to_dsi_display(x) container_of(x, struct dsi_display, host)
+#define INT_BASE_10 10
 
 static DEFINE_MUTEX(dsi_display_list_lock);
 static LIST_HEAD(dsi_display_list);
-
+static char dsi_display_primary[MAX_CMDLINE_PARAM_LEN];
+static char dsi_display_secondary[MAX_CMDLINE_PARAM_LEN];
+static struct dsi_display_boot_param boot_displays[MAX_DSI_ACTIVE_DISPLAY];
+static struct device_node *default_active_node;
 static const struct of_device_id dsi_display_dt_match[] = {
 	{.compatible = "qcom,dsi-display"},
 	{}
@@ -553,6 +558,184 @@ static int dsi_display_ctrl_power_off(struct dsi_display *display)
 	return rc;
 }
 
+static int dsi_display_parse_cmdline_topology(unsigned int display_type)
+{
+	char *str = NULL;
+	int top_index = -1;
+
+	if (display_type >= MAX_DSI_ACTIVE_DISPLAY) {
+		pr_err("display_type=%d not supported\n", display_type);
+		return -EINVAL;
+	}
+	if (display_type == DSI_PRIMARY)
+		str = strnstr(dsi_display_primary,
+			":config", strlen(dsi_display_primary));
+	else
+		str = strnstr(dsi_display_secondary,
+			":config", strlen(dsi_display_secondary));
+	if (!str)
+		return -EINVAL;
+
+	if (kstrtol(str + strlen(":config"), INT_BASE_10,
+				(unsigned long *)&top_index))
+		return -EINVAL;
+
+	return top_index;
+}
+
+/**
+ * dsi_display_name_compare()- compare whether DSI display name matches.
+ * @node:	Pointer to device node structure
+ * @display_name: Name of display to validate
+ *
+ * Return:	returns a bool specifying whether given display is active
+ */
+static bool dsi_display_name_compare(struct device_node *node,
+			const char *display_name, int index)
+{
+	if (index >= MAX_DSI_ACTIVE_DISPLAY) {
+		pr_err("Invalid Index\n");
+		return false;
+	}
+
+	if (boot_displays[index].boot_disp_en) {
+		if (!(strcmp(&boot_displays[index].name[0], display_name))) {
+			boot_displays[index].node = node;
+			return true;
+		}
+	}
+	return false;
+}
+
+/**
+ * dsi_display_parse_boot_display_selection()- Parse DSI boot display name
+ *
+ * Return:	returns error status
+ */
+static int dsi_display_parse_boot_display_selection(void)
+{
+	char *pos = NULL;
+	char disp_buf[MAX_CMDLINE_PARAM_LEN] = {'\0'};
+	int i, j, num_displays;
+
+	if (strlen(dsi_display_primary) == 0)
+		return -EINVAL;
+
+	if ((strlen(dsi_display_secondary) > 0))
+		num_displays = MAX_DSI_ACTIVE_DISPLAY;
+	else {
+		/*
+		 * Initialize secondary dsi variables
+		 * for the senario where dsi_display1
+		 * is null but dsi_display0 is valid
+		 */
+
+		/* Max number of displays will be one->only Primary */
+		num_displays = 1;
+		boot_displays[DSI_SECONDARY].is_primary = false;
+		boot_displays[DSI_SECONDARY].name[0] = '\0';
+	}
+
+	for (i = 0; i < num_displays; i++) {
+		boot_displays[i].is_primary = false;
+		if (i == DSI_PRIMARY) {
+			strlcpy(disp_buf, &dsi_display_primary[0],
+				sizeof(dsi_display_primary));
+			pos = strnstr(disp_buf, ":",
+				sizeof(dsi_display_primary));
+		} else {
+			strlcpy(disp_buf, &dsi_display_secondary[0],
+				sizeof(dsi_display_secondary));
+			pos = strnstr(disp_buf, ":",
+				sizeof(dsi_display_secondary));
+		}
+		/* Use ':' as a delimiter to retrieve the display name */
+		if (!pos) {
+			pr_debug("display name[%s]is not valid\n", disp_buf);
+			continue;
+		}
+
+		for (j = 0; (disp_buf + j) < pos; j++)
+			boot_displays[i].name[j] = *(disp_buf + j);
+		boot_displays[i].name[j] = '\0';
+
+		if (i == DSI_PRIMARY) {
+			boot_displays[i].is_primary = true;
+			/* Currently, secondary DSI display is not supported */
+			boot_displays[i].boot_disp_en = true;
+		}
+	}
+	return 0;
+}
+
+/**
+ * validate_dsi_display_selection()- validate boot DSI display selection
+ *
+ * Return:	returns true when both displays have unique configurations
+ */
+static bool validate_dsi_display_selection(void)
+{
+	int i, j;
+	int rc = 0;
+	int phy_count = 0;
+	int ctrl_count = 0;
+	int index = 0;
+	bool ctrl_flags[MAX_DSI_ACTIVE_DISPLAY] = {false, false};
+	bool phy_flags[MAX_DSI_ACTIVE_DISPLAY] = {false, false};
+	struct device_node *node, *ctrl_node, *phy_node;
+
+	for (i = 0; i < MAX_DSI_ACTIVE_DISPLAY; i++) {
+		node = boot_displays[i].node;
+		ctrl_count = of_count_phandle_with_args(node, "qcom,dsi-ctrl",
+								NULL);
+
+		for (j = 0; j < ctrl_count; j++) {
+			ctrl_node = of_parse_phandle(node, "qcom,dsi-ctrl", j);
+			rc = of_property_read_u32(ctrl_node, "cell-index",
+					&index);
+			of_node_put(ctrl_node);
+			if (rc) {
+				pr_err("cell index not set for ctrl_nodes\n");
+				return false;
+			}
+			if (ctrl_flags[index])
+				return false;
+			ctrl_flags[index] = true;
+		}
+
+		phy_count = of_count_phandle_with_args(node, "qcom,dsi-phy",
+								NULL);
+		for (j = 0; j < phy_count; j++) {
+			phy_node = of_parse_phandle(node, "qcom,dsi-phy", j);
+			rc = of_property_read_u32(phy_node, "cell-index",
+					&index);
+			of_node_put(phy_node);
+			if (rc) {
+				pr_err("cell index not set phy_nodes\n");
+				return false;
+			}
+			if (phy_flags[index])
+				return false;
+			phy_flags[index] = true;
+		}
+	}
+	return true;
+}
+
+struct device_node *dsi_display_get_boot_display(int index)
+{
+
+	pr_err("index = %d\n", index);
+
+	if (boot_displays[index].node)
+		return boot_displays[index].node;
+	else if ((index == (MAX_DSI_ACTIVE_DISPLAY - 1))
+			&& (default_active_node))
+		return default_active_node;
+	else
+		return NULL;
+}
+
 static int dsi_display_phy_power_on(struct dsi_display *display)
 {
 	int rc = 0;
@@ -1004,9 +1187,9 @@ static int dsi_display_broadcast_cmd(struct dsi_display *display,
 	int i;
 
 	m_flags = (DSI_CTRL_CMD_BROADCAST | DSI_CTRL_CMD_BROADCAST_MASTER |
-		   DSI_CTRL_CMD_DEFER_TRIGGER | DSI_CTRL_CMD_FIFO_STORE);
+		   DSI_CTRL_CMD_DEFER_TRIGGER | DSI_CTRL_CMD_FETCH_MEMORY);
 	flags = (DSI_CTRL_CMD_BROADCAST | DSI_CTRL_CMD_DEFER_TRIGGER |
-		 DSI_CTRL_CMD_FIFO_STORE);
+		 DSI_CTRL_CMD_FETCH_MEMORY);
 
 	/*
 	 * 1. Setup commands in FIFO
@@ -1101,8 +1284,8 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host,
 				 const struct mipi_dsi_msg *msg)
 {
 	struct dsi_display *display = to_dsi_display(host);
-
-	int rc = 0;
+	struct dsi_display_ctrl *display_ctrl;
+	int rc = 0, cnt = 0;
 
 	if (!host || !msg) {
 		pr_err("Invalid params\n");
@@ -1131,6 +1314,44 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host,
 		goto error_disable_clks;
 	}
 
+	if (display->tx_cmd_buf == NULL) {
+		mutex_lock(&display->drm_dev->struct_mutex);
+		display->tx_cmd_buf = msm_gem_new(display->drm_dev,
+				SZ_4K,
+				MSM_BO_UNCACHED);
+		mutex_unlock(&display->drm_dev->struct_mutex);
+
+		display->cmd_buffer_size = SZ_4K;
+
+		if ((display->tx_cmd_buf) == NULL) {
+			pr_err("value of display->tx_cmd_buf is NULL");
+			goto error_disable_cmd_engine;
+		}
+		rc = msm_gem_get_iova(display->tx_cmd_buf, 0,
+					&(display->cmd_buffer_iova));
+		if (rc) {
+			pr_err("failed to get the iova rc %d\n", rc);
+			goto free_gem;
+		}
+
+		display->vaddr =
+			(void *) msm_gem_get_vaddr(display->tx_cmd_buf);
+
+		if (IS_ERR_OR_NULL(display->vaddr)) {
+			pr_err("failed to get va rc %d\n", rc);
+			rc = -EINVAL;
+			goto put_iova;
+		}
+
+		for (cnt = 0; cnt < display->ctrl_count; cnt++) {
+			display_ctrl = &display->ctrl[cnt];
+			display_ctrl->ctrl->cmd_buffer_size = SZ_4K;
+			display_ctrl->ctrl->cmd_buffer_iova =
+						display->cmd_buffer_iova;
+			display_ctrl->ctrl->vaddr = display->vaddr;
+		}
+	}
+
 	if (display->ctrl_count > 1 && !(msg->flags & MIPI_DSI_MSG_UNICAST)) {
 		rc = dsi_display_broadcast_cmd(display, msg);
 		if (rc) {
@@ -1143,13 +1364,19 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host,
 				msg->ctrl : 0;
 
 		rc = dsi_ctrl_cmd_transfer(display->ctrl[ctrl_idx].ctrl, msg,
-					  DSI_CTRL_CMD_FIFO_STORE);
+					  DSI_CTRL_CMD_FETCH_MEMORY);
 		if (rc) {
 			pr_err("[%s] cmd transfer failed, rc=%d\n",
 			       display->name, rc);
 			goto error_disable_cmd_engine;
 		}
 	}
+	return rc;
+
+put_iova:
+	msm_gem_put_iova(display->tx_cmd_buf, 0);
+free_gem:
+	msm_gem_free_object(display->tx_cmd_buf);
 error_disable_cmd_engine:
 	(void)dsi_display_cmd_engine_disable(display);
 error_disable_clks:
@@ -1754,7 +1981,8 @@ static int dsi_display_res_init(struct dsi_display *display)
 		}
 	}
 
-	display->panel = dsi_panel_get(&display->pdev->dev, display->panel_of);
+	display->panel = dsi_panel_get(&display->pdev->dev, display->panel_of,
+						display->cmdline_topology);
 	if (IS_ERR_OR_NULL(display->panel)) {
 		rc = PTR_ERR(display->panel);
 		pr_err("failed to get panel, rc=%d\n", rc);
@@ -2419,6 +2647,7 @@ static int dsi_display_bind(struct device *dev,
 		goto error_panel_deinit;
 	}
 
+	pr_info("Successfully bind display panel '%s'\n", display->name);
 	display->drm_dev = drm;
 	goto error;
 
@@ -2516,6 +2745,9 @@ int dsi_display_dev_probe(struct platform_device *pdev)
 {
 	int rc = 0;
 	struct dsi_display *display;
+	static bool display_from_cmdline, boot_displays_parsed;
+	static bool comp_add_success;
+	static struct device_node *primary_np, *secondary_np;
 
 	if (!pdev || !pdev->dev.of_node) {
 		pr_err("pdev not found\n");
@@ -2528,9 +2760,66 @@ int dsi_display_dev_probe(struct platform_device *pdev)
 
 	display->name = of_get_property(pdev->dev.of_node, "label", NULL);
 
-	display->is_active = of_property_read_bool(pdev->dev.of_node,
-						"qcom,dsi-display-active");
+	if (!boot_displays_parsed) {
+		boot_displays[DSI_PRIMARY].boot_disp_en = false;
+		boot_displays[DSI_SECONDARY].boot_disp_en = false;
+		if (dsi_display_parse_boot_display_selection())
+			pr_debug("Display Boot param not valid/available\n");
 
+		boot_displays_parsed = true;
+	}
+
+	/* Initialize cmdline_topology to use default topology */
+	display->cmdline_topology = -1;
+	if ((!display_from_cmdline) &&
+			(boot_displays[DSI_PRIMARY].boot_disp_en)) {
+		display->is_active = dsi_display_name_compare(pdev->dev.of_node,
+						display->name, DSI_PRIMARY);
+		if (display->is_active) {
+			if (comp_add_success) {
+				(void)_dsi_display_dev_deinit(main_display);
+				component_del(&main_display->pdev->dev,
+					      &dsi_display_comp_ops);
+				comp_add_success = false;
+				default_active_node = NULL;
+				pr_debug("removed the existing comp ops\n");
+			}
+			/*
+			 * Need to add component for
+			 * the secondary DSI display
+			 * when more than one DSI display
+			 * is supported.
+			 */
+			pr_debug("cmdline primary dsi: %s\n",
+						display->name);
+			display_from_cmdline = true;
+			display->cmdline_topology =
+				dsi_display_parse_cmdline_topology(DSI_PRIMARY);
+			primary_np = pdev->dev.of_node;
+		}
+	}
+
+	if (boot_displays[DSI_SECONDARY].boot_disp_en) {
+		if (!secondary_np) {
+			if (dsi_display_name_compare(pdev->dev.of_node,
+				display->name, DSI_SECONDARY)) {
+				pr_debug("cmdline secondary dsi: %s\n",
+							display->name);
+				secondary_np = pdev->dev.of_node;
+				if (primary_np) {
+					if (validate_dsi_display_selection()) {
+					display->is_active = true;
+					display->cmdline_topology =
+					dsi_display_parse_cmdline_topology
+							(DSI_SECONDARY);
+					} else {
+						boot_displays[DSI_SECONDARY]
+							.boot_disp_en = false;
+					}
+				}
+			}
+		}
+	}
 	display->display_type = of_get_property(pdev->dev.of_node,
 						"qcom,display-type", NULL);
 	if (!display->display_type)
@@ -2543,6 +2832,10 @@ int dsi_display_dev_probe(struct platform_device *pdev)
 	list_add(&display->list, &dsi_display_list);
 	mutex_unlock(&dsi_display_list_lock);
 
+	if (!display_from_cmdline)
+		display->is_active = of_property_read_bool(pdev->dev.of_node,
+						"qcom,dsi-display-active");
+
 	if (display->is_active) {
 		main_display = display;
 		rc = _dsi_display_dev_init(display);
@@ -2554,6 +2847,11 @@ int dsi_display_dev_probe(struct platform_device *pdev)
 		rc = component_add(&pdev->dev, &dsi_display_comp_ops);
 		if (rc)
 			pr_err("component add failed, rc=%d\n", rc);
+
+		comp_add_success = true;
+		pr_debug("Component_add success: %s\n", display->name);
+		if (!display_from_cmdline)
+			default_active_node = pdev->dev.of_node;
 	}
 	return rc;
 }
@@ -2736,6 +3034,7 @@ int dsi_display_get_info(struct msm_display_info *info, void *disp)
 		goto error;
 	}
 
+	memset(info, 0, sizeof(struct msm_display_info));
 	info->intf_type = DRM_MODE_CONNECTOR_DSI;
 	timing = &display->panel->mode.timing;
 
@@ -3405,6 +3704,13 @@ static void __exit dsi_display_unregister(void)
 	dsi_ctrl_drv_unregister();
 	dsi_phy_drv_unregister();
 }
-
+module_param_string(dsi_display0, dsi_display_primary, MAX_CMDLINE_PARAM_LEN,
+								0600);
+MODULE_PARM_DESC(dsi_display0,
+	"msm_drm.dsi_display0=<display node>:<configX> where <display node> is 'primary dsi display node name' and <configX> where x represents index in the topology list");
+module_param_string(dsi_display1, dsi_display_secondary, MAX_CMDLINE_PARAM_LEN,
+								0600);
+MODULE_PARM_DESC(dsi_display1,
+	"msm_drm.dsi_display1=<display node>:<configX> where <display node> is 'secondary dsi display node name' and <configX> where x represents index in the topology list");
 module_init(dsi_display_register);
 module_exit(dsi_display_unregister);
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
index d2bc7d8..9aa3113 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
@@ -30,6 +30,7 @@
 
 #define MAX_DSI_CTRLS_PER_DISPLAY             2
 #define DSI_CLIENT_NAME_SIZE		20
+#define MAX_CMDLINE_PARAM_LEN	 512
 /*
  * DSI Validate Mode modifiers
  * @DSI_VALIDATE_FLAG_ALLOW_ADJUST:	Allow mode validation to also do fixup
@@ -37,6 +38,18 @@
 #define DSI_VALIDATE_FLAG_ALLOW_ADJUST	0x1
 
 /**
+ * enum dsi_display_selection_type - enumerates DSI display selection types
+ * @DSI_PRIMARY:    primary DSI display selected from module parameter
+ * @DSI_SECONDARY:  Secondary DSI display selected from module parameter
+ * @MAX_DSI_ACTIVE_DISPLAY: Maximum acive displays that can be selected
+ */
+enum dsi_display_selection_type {
+	DSI_PRIMARY = 0,
+	DSI_SECONDARY,
+	MAX_DSI_ACTIVE_DISPLAY,
+};
+
+/**
  * enum dsi_display_type - enumerates DSI display types
  * @DSI_DISPLAY_SINGLE:       A panel connected on a single DSI interface.
  * @DSI_DISPLAY_EXT_BRIDGE:   A bridge is connected between panel and DSI host.
@@ -78,6 +91,22 @@ struct dsi_display_ctrl {
 
 	bool phy_enabled;
 };
+/**
+ * struct dsi_display_boot_param - defines DSI boot display selection
+ * @name:Name of DSI display selected as a boot param.
+ * @boot_disp_en:bool to indicate dtsi availability of display node
+ * @is_primary:bool to indicate whether current display is primary display
+ * @length:length of DSI display.
+ * @cmdline_topology: Display topology shared from kernel command line.
+ */
+struct dsi_display_boot_param {
+	char name[MAX_CMDLINE_PARAM_LEN];
+	bool boot_disp_en;
+	bool is_primary;
+	int length;
+	struct device_node *node;
+	int cmdline_topology;
+};
 
 /**
  * struct dsi_display_clk_info - dsi display clock source information
@@ -113,6 +142,7 @@ struct dsi_display_clk_info {
  * @config:           DSI host configuration information.
  * @lane_map:         Lane mapping between DSI host and Panel.
  * @num_of_modes:     Number of modes supported by display.
+ * @cmdline_topology: Display topology shared from kernel command line.
  * @is_tpg_enabled:   TPG state.
  * @ulps_enabled:     ulps state.
  * @clamp_enabled:    clamp state.
@@ -151,10 +181,15 @@ struct dsi_display {
 	struct dsi_host_config config;
 	struct dsi_lane_map lane_map;
 	u32 num_of_modes;
+	int cmdline_topology;
 	bool is_tpg_enabled;
 	bool ulps_enabled;
 	bool clamp_enabled;
 	bool phy_idle_power_off;
+	struct drm_gem_object *tx_cmd_buf;
+	u32 cmd_buffer_size;
+	u32 cmd_buffer_iova;
+	void *vaddr;
 
 	struct mipi_dsi_host host;
 	struct dsi_bridge    *bridge;
@@ -189,8 +224,16 @@ int dsi_display_get_active_displays(void **display_array,
 		u32 max_display_count);
 
 /**
+  * dsi_display_get_boot_display()- get DSI boot display name
+  * @index:	index of display selection
+  *
+  * Return:	returns the display node pointer
+  */
+struct device_node *dsi_display_get_boot_display(int index);
+
+/**
  * dsi_display_get_display_by_name()- finds display by name
- * @index:      name of the display.
+ * @name:	name of the display.
  *
  * Return: handle to the display or error code.
  */
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
index dcb787b..b8bf7a8 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
@@ -22,9 +22,6 @@
 #include "dsi_panel.h"
 #include "dsi_ctrl_hw.h"
 
-#define MAX_CMDLINE_PARAM_LEN 256
-static char display_config[MAX_CMDLINE_PARAM_LEN];
-
 /**
  * topology is currently defined by a set of following 3 values:
  * 1. num of layer mixers
@@ -32,7 +29,6 @@ static char display_config[MAX_CMDLINE_PARAM_LEN];
  * 3. num of interfaces
  */
 #define TOPOLOGY_SET_LEN 3
-#define INT_BASE_10 10
 #define MAX_TOPOLOGY 5
 
 #define DSI_PANEL_DEFAULT_LABEL  "Default dsi panel"
@@ -2078,31 +2074,9 @@ static int dsi_panel_parse_hdr_config(struct dsi_panel *panel,
 	return 0;
 }
 
-static int dsi_get_cmdline_top_override(void)
-{
-	char *str = display_config;
-	int top_index = -1;
-
-	/*
-	 * This module need to be updated with needed cmd line argument parsing
-	 * for other dsi parameters.
-	 */
-	if (strlcat(str, "\0", sizeof(str)) > sizeof(str))
-		return -EINVAL;
-
-	str = strnstr(display_config, "config", strlen(display_config));
-	if (!str)
-		return -EINVAL;
-
-	if (kstrtol(str + strlen("config"), INT_BASE_10,
-				(unsigned long *)&top_index))
-		return -EINVAL;
-
-	return top_index;
-}
-
 static int dsi_panel_parse_topology(struct dsi_panel *panel,
-		struct device_node *of_node)
+				struct device_node *of_node,
+				int topology_override)
 {
 	struct msm_display_topology *topology;
 	u32 top_count, top_sel, *array = NULL;
@@ -2143,12 +2117,13 @@ static int dsi_panel_parse_topology(struct dsi_panel *panel,
 		top->num_intf = array[i * TOPOLOGY_SET_LEN + 2];
 	};
 
-	top_sel = dsi_get_cmdline_top_override();
-	if (top_sel >= 0 && top_sel < top_count) {
-		pr_info("overidden topology: lm: %d comp_enc:%d intf: %d\n",
-			topology[top_sel].num_lm,
-			topology[top_sel].num_enc,
-			topology[top_sel].num_intf);
+	if (topology_override >= 0 && topology_override < top_count) {
+		pr_info("override topology: cfg:%d lm:%d comp_enc:%d intf:%d\n",
+			topology_override,
+			topology[topology_override].num_lm,
+			topology[topology_override].num_enc,
+			topology[topology_override].num_intf);
+		top_sel = topology_override;
 		goto parse_done;
 	}
 
@@ -2266,7 +2241,8 @@ static int dsi_panel_parse_partial_update_caps(struct dsi_panel *panel,
 }
 
 struct dsi_panel *dsi_panel_get(struct device *parent,
-				struct device_node *of_node)
+				struct device_node *of_node,
+				int topology_override)
 {
 	struct dsi_panel *panel;
 	const char *data;
@@ -2323,7 +2299,7 @@ struct dsi_panel *dsi_panel_get(struct device *parent,
 				    DSI_V_TOTAL(&panel->mode.timing) *
 				    panel->mode.timing.refresh_rate) / 1000;
 
-	rc = dsi_panel_parse_topology(panel, of_node);
+	rc = dsi_panel_parse_topology(panel, of_node, topology_override);
 	if (rc) {
 		pr_err("failed to parse panel topology, rc=%d\n", rc);
 		goto error;
@@ -2970,6 +2946,3 @@ int dsi_panel_post_unprepare(struct dsi_panel *panel)
 	mutex_unlock(&panel->panel_lock);
 	return rc;
 }
-
-module_param_string(display_param, display_config, MAX_CMDLINE_PARAM_LEN, 0600);
-MODULE_PARM_DESC(display_param, "format: configx - x indexes the selected topology from the display topology list. Index 0 corresponds to the first topology in the list");
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h
index f254af5..3569b5b 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.h
@@ -205,7 +205,8 @@ static inline bool dsi_panel_initialized(struct dsi_panel *panel)
 }
 
 struct dsi_panel *dsi_panel_get(struct device *parent,
-				struct device_node *of_node);
+				struct device_node *of_node,
+				int topology_override);
 void dsi_panel_put(struct dsi_panel *panel);
 
 int dsi_panel_drv_init(struct dsi_panel *panel, struct mipi_dsi_host *host);
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index a3a9142..f75be8a 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -45,6 +45,7 @@
 #include "msm_gpu.h"
 #include "msm_kms.h"
 #include "sde_wb.h"
+#include "dsi_display.h"
 
 /*
  * MSM driver version:
@@ -1764,15 +1765,26 @@ static int add_display_components(struct device *dev,
 				  struct component_match **matchptr)
 {
 	struct device *mdp_dev = NULL;
+	struct device_node *node;
+	const char *name;
 	int ret;
 
 	if (of_device_is_compatible(dev->of_node, "qcom,sde-kms")) {
 		struct device_node *np = dev->of_node;
 		unsigned int i;
 
-		for (i = 0; ; i++) {
-			struct device_node *node;
+		for (i = 0; i < MAX_DSI_ACTIVE_DISPLAY; i++) {
+			node = dsi_display_get_boot_display(i);
 
+			if (node != NULL) {
+				name = of_get_property(node, "label", NULL);
+				component_match_add(dev, matchptr, compare_of,
+						node);
+				pr_debug("Added component = %s\n", name);
+			}
+		}
+
+		for (i = 0; ; i++) {
 			node = of_parse_phandle(np, "connectors", i);
 			if (!node)
 				break;
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c
index 24f16c6..53a48c8 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c
@@ -395,37 +395,32 @@ static const struct sde_irq_type sde_irq_map[] = {
 		SDE_INTR_HIST_VIG_1_RSTSEQ_DONE, 2},
 	{ SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
 	{ SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
-	/* irq_idx: 68-71 */
+	/* irq_idx: 72-75 */
 	{ SDE_IRQ_TYPE_HIST_VIG_DONE, SSPP_VIG2, SDE_INTR_HIST_VIG_2_DONE, 2},
 	{ SDE_IRQ_TYPE_HIST_VIG_RSTSEQ, SSPP_VIG2,
 		SDE_INTR_HIST_VIG_2_RSTSEQ_DONE, 2},
 	{ SDE_IRQ_TYPE_HIST_VIG_DONE, SSPP_VIG3, SDE_INTR_HIST_VIG_3_DONE, 2},
 	{ SDE_IRQ_TYPE_HIST_VIG_RSTSEQ, SSPP_VIG3,
 		SDE_INTR_HIST_VIG_3_RSTSEQ_DONE, 2},
-	/* irq_idx: 72-75 */
+	/* irq_idx: 76-79 */
 	{ SDE_IRQ_TYPE_HIST_DSPP_DONE, DSPP_0, SDE_INTR_HIST_DSPP_0_DONE, 2},
 	{ SDE_IRQ_TYPE_HIST_DSPP_RSTSEQ, DSPP_0,
 		SDE_INTR_HIST_DSPP_0_RSTSEQ_DONE, 2},
 	{ SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
 	{ SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
-	/* irq_idx: 76-79 */
+	/* irq_idx: 80-83 */
 	{ SDE_IRQ_TYPE_HIST_DSPP_DONE, DSPP_1, SDE_INTR_HIST_DSPP_1_DONE, 2},
 	{ SDE_IRQ_TYPE_HIST_DSPP_RSTSEQ, DSPP_1,
 		SDE_INTR_HIST_DSPP_1_RSTSEQ_DONE, 2},
 	{ SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
 	{ SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
-	/* irq_idx: 80-83 */
+	/* irq_idx: 84-87 */
 	{ SDE_IRQ_TYPE_HIST_DSPP_DONE, DSPP_2, SDE_INTR_HIST_DSPP_2_DONE, 2},
 	{ SDE_IRQ_TYPE_HIST_DSPP_RSTSEQ, DSPP_2,
 		SDE_INTR_HIST_DSPP_2_RSTSEQ_DONE, 2},
 	{ SDE_IRQ_TYPE_HIST_DSPP_DONE, DSPP_3, SDE_INTR_HIST_DSPP_3_DONE, 2},
 	{ SDE_IRQ_TYPE_HIST_DSPP_RSTSEQ, DSPP_3,
 		SDE_INTR_HIST_DSPP_3_RSTSEQ_DONE, 2},
-	/* irq_idx: 84-87 */
-	{ SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
-	{ SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
-	{ SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
-	{ SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
 	/* irq_idx: 88-91 */
 	{ SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
 	{ SDE_IRQ_TYPE_RESERVED, 0, 0, 2},
@@ -986,7 +981,7 @@ static u32 sde_hw_intr_get_interrupt_status(struct sde_hw_intr *intr,
 			sde_intr_set[reg_idx].status_off) &
 					sde_irq_map[irq_idx].irq_mask;
 	if (intr_status && clear)
-		SDE_REG_WRITE(&intr->hw, sde_intr_set[irq_idx].clr_off,
+		SDE_REG_WRITE(&intr->hw, sde_intr_set[reg_idx].clr_off,
 				intr_status);
 
 	spin_unlock_irqrestore(&intr->mask_lock, irq_flags);
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_top.c b/drivers/gpu/drm/msm/sde/sde_hw_top.c
index bd212e2..19f999e 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_top.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_top.c
@@ -216,10 +216,12 @@ static void sde_hw_setup_vsync_sel(struct sde_hw_mdp *mdp,
 
 	reg = SDE_REG_READ(c, MDP_VSYNC_SEL);
 	for (i = 0; i < cfg->pp_count; i++) {
+		int pp_idx = cfg->ppnumber[i] - PINGPONG_0;
+
 		if (watchdog_te)
-			reg |= 0xF << pp_offset[cfg->ppnumber[i] - 1];
+			reg |= 0xF << pp_offset[pp_idx];
 		else
-			reg &= ~(0xF << pp_offset[cfg->ppnumber[i] - 1]);
+			reg &= ~(0xF << pp_offset[pp_idx]);
 	}
 
 	SDE_REG_WRITE(c, MDP_VSYNC_SEL, reg);
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_top.h b/drivers/gpu/drm/msm/sde/sde_hw_top.h
index 9cb4494..faf25c7 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_top.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_top.h
@@ -80,12 +80,12 @@ struct sde_danger_safe_status {
  * struct sde_watchdog_te_status - configure watchdog timer to generate TE
  * @pp_count: number of ping pongs active
  * @frame_rate: Display frame rate
- * @ppnumber: base address of ping pong info
+ * @ppnumber: ping pong index array
  */
 struct sde_watchdog_te_status {
 	u32 pp_count;
 	u32 frame_rate;
-	u32 ppnumber[];
+	u32 ppnumber[PINGPONG_MAX];
 };
 
 /**
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index e73d647..a7d6ecf 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -608,6 +608,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
 		.get_modes  = dp_connector_get_modes,
 		.mode_valid = dp_connector_mode_valid,
 		.get_info   = dp_connector_get_info,
+		.get_topology   = dp_connector_get_topology,
 	};
 	struct msm_display_info info;
 	struct drm_encoder *encoder;
diff --git a/drivers/gpu/drm/msm/sde/sde_wb.c b/drivers/gpu/drm/msm/sde/sde_wb.c
index b2665be..ceda16e 100644
--- a/drivers/gpu/drm/msm/sde/sde_wb.c
+++ b/drivers/gpu/drm/msm/sde/sde_wb.c
@@ -273,6 +273,7 @@ int sde_wb_get_info(struct msm_display_info *info, void *display)
 		return -EINVAL;
 	}
 
+	memset(info, 0, sizeof(struct msm_display_info));
 	info->intf_type = DRM_MODE_CONNECTOR_VIRTUAL;
 	info->num_of_h_tiles = 1;
 	info->h_tile_instance[0] = sde_wb_get_index(display);
diff --git a/drivers/gpu/msm/a6xx_reg.h b/drivers/gpu/msm/a6xx_reg.h
index 1f76233a..dbacb20 100644
--- a/drivers/gpu/msm/a6xx_reg.h
+++ b/drivers/gpu/msm/a6xx_reg.h
@@ -796,6 +796,10 @@
 #define A6XX_GMU_CM3_FW_BUSY			0x1F81A
 #define A6XX_GMU_CM3_FW_INIT_RESULT		0x1F81C
 #define A6XX_GMU_CM3_CFG			0x1F82D
+#define A6XX_GMU_CX_GMU_POWER_COUNTER_ENABLE	0x1F840
+#define A6XX_GMU_CX_GMU_POWER_COUNTER_SELECT_0	0x1F841
+#define A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L	0x1F844
+#define A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_H	0x1F845
 #define A6XX_GMU_PWR_COL_INTER_FRAME_CTRL	0x1F8C0
 #define A6XX_GMU_PWR_COL_INTER_FRAME_HYST	0x1F8C1
 #define A6XX_GMU_PWR_COL_SPTPRAC_HYST		0x1F8C2
@@ -848,6 +852,7 @@
 #define A6XX_GPU_GMU_AO_GMU_CGC_DELAY_CNTL      0x23B0A
 #define A6XX_GPU_GMU_AO_GMU_CGC_HYST_CNTL       0x23B0B
 #define A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS	0x23B0C
+#define A6XX_GPU_GMU_AO_GPU_CX_BUSY_MASK	0x23B0E
 #define A6XX_GMU_AHB_FENCE_STATUS		0x23B13
 #define A6XX_GMU_RBBM_INT_UNMASKED_STATUS	0x23B15
 #define A6XX_GMU_AO_SPARE_CNTL			0x23B16
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 627b351..f581cff 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -2963,11 +2963,11 @@ static void adreno_pwrlevel_change_settings(struct kgsl_device *device,
 }
 
 static void adreno_clk_set_options(struct kgsl_device *device, const char *name,
-	struct clk *clk)
+	struct clk *clk, bool on)
 {
 	if (ADRENO_GPU_DEVICE(ADRENO_DEVICE(device))->clk_set_options)
 		ADRENO_GPU_DEVICE(ADRENO_DEVICE(device))->clk_set_options(
-			ADRENO_DEVICE(device), name, clk);
+			ADRENO_DEVICE(device), name, clk, on);
 }
 
 static void adreno_iommu_sync(struct kgsl_device *device, bool sync)
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 91f03d0..26c5505 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -851,7 +851,7 @@ struct adreno_gpudev {
 	void (*preemption_schedule)(struct adreno_device *);
 	void (*enable_64bit)(struct adreno_device *);
 	void (*clk_set_options)(struct adreno_device *,
-				const char *, struct clk *);
+				const char *, struct clk *, bool on);
 	void (*llc_configure_gpu_scid)(struct adreno_device *adreno_dev);
 	void (*llc_configure_gpuhtw_scid)(struct adreno_device *adreno_dev);
 	void (*llc_enable_overrides)(struct adreno_device *adreno_dev);
diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c
index 6c8b677..314ac85a 100644
--- a/drivers/gpu/msm/adreno_a5xx.c
+++ b/drivers/gpu/msm/adreno_a5xx.c
@@ -55,7 +55,7 @@ static const struct adreno_vbif_platform a5xx_vbif_platforms[] = {
 	{ adreno_is_a530, a530_vbif },
 	{ adreno_is_a512, a540_vbif },
 	{ adreno_is_a510, a530_vbif },
-	{ adreno_is_a508, a530_vbif },
+	{ adreno_is_a508, a540_vbif },
 	{ adreno_is_a505, a530_vbif },
 	{ adreno_is_a506, a530_vbif },
 };
@@ -1608,11 +1608,15 @@ static void a5xx_pwrlevel_change_settings(struct adreno_device *adreno_dev,
 }
 
 static void a5xx_clk_set_options(struct adreno_device *adreno_dev,
-	const char *name, struct clk *clk)
+	const char *name, struct clk *clk, bool on)
 {
+
+	if (!adreno_is_a540(adreno_dev) && !adreno_is_a512(adreno_dev) &&
+		!adreno_is_a508(adreno_dev))
+		return;
+
 	/* Handle clock settings for GFX PSCBCs */
-	if (adreno_is_a540(adreno_dev) || adreno_is_a512(adreno_dev) ||
-		adreno_is_a508(adreno_dev)) {
+	if (on) {
 		if (!strcmp(name, "mem_iface_clk")) {
 			clk_set_flags(clk, CLKFLAG_NORETAIN_PERIPH);
 			clk_set_flags(clk, CLKFLAG_NORETAIN_MEM);
@@ -1620,6 +1624,11 @@ static void a5xx_clk_set_options(struct adreno_device *adreno_dev,
 			clk_set_flags(clk, CLKFLAG_RETAIN_PERIPH);
 			clk_set_flags(clk, CLKFLAG_RETAIN_MEM);
 		}
+	} else {
+		if (!strcmp(name, "core_clk")) {
+			clk_set_flags(clk, CLKFLAG_NORETAIN_PERIPH);
+			clk_set_flags(clk, CLKFLAG_NORETAIN_MEM);
+		}
 	}
 }
 
diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c
index 9a56bec..314b2d8 100644
--- a/drivers/gpu/msm/adreno_a6xx.c
+++ b/drivers/gpu/msm/adreno_a6xx.c
@@ -2419,6 +2419,13 @@ static struct adreno_perfcount_register a6xx_perfcounters_vbif_pwr[] = {
 		A6XX_VBIF_PERF_PWR_CNT_HIGH2, -1, A6XX_VBIF_PERF_PWR_CNT_EN2 },
 };
 
+static struct adreno_perfcount_register a6xx_perfcounters_pwr[] = {
+	{ KGSL_PERFCOUNTER_BROKEN, 0, 0, 0, 0, -1, 0 },
+	{ KGSL_PERFCOUNTER_NOT_USED, 0, 0,
+		A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L,
+		A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_H, -1, 0 },
+};
+
 static struct adreno_perfcount_register a6xx_perfcounters_alwayson[] = {
 	{ KGSL_PERFCOUNTER_NOT_USED, 0, 0, A6XX_CP_ALWAYS_ON_COUNTER_LO,
 		A6XX_CP_ALWAYS_ON_COUNTER_HI, -1 },
@@ -2451,6 +2458,8 @@ static struct adreno_perfcount_group a6xx_perfcounter_groups
 	A6XX_PERFCOUNTER_GROUP(VBIF, vbif),
 	A6XX_PERFCOUNTER_GROUP_FLAGS(VBIF_PWR, vbif_pwr,
 		ADRENO_PERFCOUNTER_GROUP_FIXED),
+	A6XX_PERFCOUNTER_GROUP_FLAGS(PWR, pwr,
+		ADRENO_PERFCOUNTER_GROUP_FIXED),
 	A6XX_PERFCOUNTER_GROUP_FLAGS(ALWAYSON, alwayson,
 		ADRENO_PERFCOUNTER_GROUP_FIXED),
 };
@@ -2460,6 +2469,30 @@ static struct adreno_perfcounters a6xx_perfcounters = {
 	ARRAY_SIZE(a6xx_perfcounter_groups),
 };
 
+/* Program the GMU power counter to count GPU busy cycles */
+static int a6xx_enable_pwr_counters(struct adreno_device *adreno_dev,
+		unsigned int counter)
+{
+	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
+
+	/*
+	 * We have a limited number of power counters. Since we're not using
+	 * total GPU cycle count, return error if requested.
+	 */
+	if (counter == 0)
+		return -EINVAL;
+
+	if (!device->gmu.pdev)
+		return -ENODEV;
+
+	kgsl_regwrite(device, A6XX_GPU_GMU_AO_GPU_CX_BUSY_MASK, 0);
+	kgsl_regrmw(device,
+		A6XX_GMU_CX_GMU_POWER_COUNTER_SELECT_0, 0xFF, 0x20);
+	kgsl_regwrite(device, A6XX_GMU_CX_GMU_POWER_COUNTER_ENABLE, 0x1);
+
+	return 0;
+}
+
 /* Register offset defines for A6XX, in order of enum adreno_regs */
 static unsigned int a6xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
 
@@ -2581,6 +2614,7 @@ struct adreno_gpudev adreno_a6xx_gpudev = {
 	.regulator_enable = a6xx_sptprac_enable,
 	.regulator_disable = a6xx_sptprac_disable,
 	.perfcounters = &a6xx_perfcounters,
+	.enable_pwr_counters = a6xx_enable_pwr_counters,
 	.microcode_read = a6xx_microcode_read,
 	.enable_64bit = a6xx_enable_64bit,
 	.llc_configure_gpu_scid = a6xx_llc_configure_gpu_scid,
diff --git a/drivers/gpu/msm/adreno_a6xx_snapshot.c b/drivers/gpu/msm/adreno_a6xx_snapshot.c
index 17ee6e6..bca3dd0 100644
--- a/drivers/gpu/msm/adreno_a6xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a6xx_snapshot.c
@@ -1264,59 +1264,14 @@ static void a6xx_snapshot_debugbus(struct kgsl_device *device,
 	}
 }
 
-static size_t a6xx_snapshot_dump_gmu_registers(struct kgsl_device *device,
-		u8 *buf, size_t remain, void *priv)
-{
-	struct kgsl_snapshot_regs *header = (struct kgsl_snapshot_regs *)buf;
-	struct kgsl_snapshot_registers *regs = priv;
-	unsigned int *data = (unsigned int *)(buf + sizeof(*header));
-	int count = 0, j, k;
-
-	/* Figure out how many registers we are going to dump */
-	for (j = 0; j < regs->count; j++) {
-		int start = regs->regs[j * 2];
-		int end = regs->regs[j * 2 + 1];
-
-		count += (end - start + 1);
-	}
-
-	if (remain < (count * 8) + sizeof(*header)) {
-		SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
-		return 0;
-	}
-
-	for (j = 0; j < regs->count; j++) {
-		unsigned int start = regs->regs[j * 2];
-		unsigned int end = regs->regs[j * 2 + 1];
-
-		for (k = start; k <= end; k++) {
-			unsigned int val;
-
-			kgsl_gmu_regread(device, k, &val);
-			*data++ = k;
-			*data++ = val;
-		}
-	}
-
-	header->count = count;
-
-	/* Return the size of the section */
-	return (count * 8) + sizeof(*header);
-}
-
 static void a6xx_snapshot_gmu(struct kgsl_device *device,
 		struct kgsl_snapshot *snapshot)
 {
-	struct kgsl_snapshot_registers gmu_regs = {
-		.regs = a6xx_gmu_registers,
-		.count = ARRAY_SIZE(a6xx_gmu_registers) / 2,
-	};
-
 	if (!kgsl_gmu_isenabled(device))
 		return;
 
-	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
-			snapshot, a6xx_snapshot_dump_gmu_registers, &gmu_regs);
+	adreno_snapshot_registers(device, snapshot, a6xx_gmu_registers,
+					ARRAY_SIZE(a6xx_gmu_registers) / 2);
 }
 
 /* a6xx_snapshot_sqe() - Dump SQE data in snapshot */
diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c
index d01a5e9..e8b1c67 100644
--- a/drivers/gpu/msm/adreno_dispatch.c
+++ b/drivers/gpu/msm/adreno_dispatch.c
@@ -2097,7 +2097,12 @@ static int dispatcher_do_fault(struct adreno_device *adreno_dev)
 	/* Turn off all the timers */
 	del_timer_sync(&dispatcher->timer);
 	del_timer_sync(&dispatcher->fault_timer);
-	del_timer_sync(&adreno_dev->preempt.timer);
+	/*
+	 * Deleting uninitialized timer will block for ever on kernel debug
+	 * disable build. Hence skip del timer if it is not initialized.
+	 */
+	if (adreno_is_preemption_enabled(adreno_dev))
+		del_timer_sync(&adreno_dev->preempt.timer);
 
 	mutex_lock(&device->mutex);
 
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index 9d847ae..bff1fda 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -54,21 +54,10 @@ static void adreno_get_submit_time(struct adreno_device *adreno_dev,
 
 	/* Read always on registers */
 	if (!adreno_is_a3xx(adreno_dev)) {
-		if (kgsl_gmu_isenabled(KGSL_DEVICE(adreno_dev))) {
-			uint32_t val_lo, val_hi;
-
-			adreno_read_gmureg(adreno_dev,
-				ADRENO_REG_RBBM_ALWAYSON_COUNTER_LO, &val_lo);
-			adreno_read_gmureg(adreno_dev,
-				ADRENO_REG_RBBM_ALWAYSON_COUNTER_HI, &val_hi);
-
-			time->ticks = (val_lo | ((uint64_t)val_hi << 32));
-		} else {
-			adreno_readreg64(adreno_dev,
-				ADRENO_REG_RBBM_ALWAYSON_COUNTER_LO,
-				ADRENO_REG_RBBM_ALWAYSON_COUNTER_HI,
-				&time->ticks);
-		}
+		adreno_readreg64(adreno_dev,
+			ADRENO_REG_RBBM_ALWAYSON_COUNTER_LO,
+			ADRENO_REG_RBBM_ALWAYSON_COUNTER_HI,
+			&time->ticks);
 
 		/* Mask hi bits as they may be incorrect on some targets */
 		if (ADRENO_GPUREV(adreno_dev) >= 400 &&
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index d836cbb..6a39792 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -257,6 +257,13 @@ static void _deferred_put(struct work_struct *work)
 	kgsl_mem_entry_put(entry);
 }
 
+static inline void
+kgsl_mem_entry_put_deferred(struct kgsl_mem_entry *entry)
+{
+	if (entry)
+		queue_work(kgsl_driver.mem_workqueue, &entry->work);
+}
+
 static inline struct kgsl_mem_entry *
 kgsl_mem_entry_create(void)
 {
@@ -266,6 +273,7 @@ kgsl_mem_entry_create(void)
 		kref_init(&entry->refcount);
 		/* put this ref in userspace memory alloc and map ioctls */
 		kref_get(&entry->refcount);
+		INIT_WORK(&entry->work, _deferred_put);
 	}
 
 	return entry;
@@ -1244,7 +1252,8 @@ kgsl_sharedmem_find(struct kgsl_process_private *private, uint64_t gpuaddr)
 	spin_lock(&private->mem_lock);
 	idr_for_each_entry(&private->mem_idr, entry, id) {
 		if (GPUADDR_IN_MEMDESC(gpuaddr, &entry->memdesc)) {
-			ret = kgsl_mem_entry_get(entry);
+			if (!entry->pending_free)
+				ret = kgsl_mem_entry_get(entry);
 			break;
 		}
 	}
@@ -1877,7 +1886,7 @@ long kgsl_ioctl_sharedmem_free(struct kgsl_device_private *dev_priv,
 		return -EINVAL;
 
 	ret = gpumem_free_entry(entry);
-	kgsl_mem_entry_put(entry);
+	kgsl_mem_entry_put_deferred(entry);
 
 	return ret;
 }
@@ -1895,7 +1904,7 @@ long kgsl_ioctl_gpumem_free_id(struct kgsl_device_private *dev_priv,
 		return -EINVAL;
 
 	ret = gpumem_free_entry(entry);
-	kgsl_mem_entry_put(entry);
+	kgsl_mem_entry_put_deferred(entry);
 
 	return ret;
 }
@@ -1932,8 +1941,7 @@ static void gpuobj_free_fence_func(void *priv)
 {
 	struct kgsl_mem_entry *entry = priv;
 
-	INIT_WORK(&entry->work, _deferred_put);
-	queue_work(kgsl_driver.mem_workqueue, &entry->work);
+	kgsl_mem_entry_put_deferred(entry);
 }
 
 static long gpuobj_free_on_fence(struct kgsl_device_private *dev_priv,
@@ -1997,7 +2005,7 @@ long kgsl_ioctl_gpuobj_free(struct kgsl_device_private *dev_priv,
 	else
 		ret = -EINVAL;
 
-	kgsl_mem_entry_put(entry);
+	kgsl_mem_entry_put_deferred(entry);
 	return ret;
 }
 
@@ -3377,7 +3385,13 @@ long kgsl_ioctl_sparse_phys_free(struct kgsl_device_private *dev_priv,
 	if (entry == NULL)
 		return -EINVAL;
 
+	if (!kgsl_mem_entry_set_pend(entry)) {
+		kgsl_mem_entry_put(entry);
+		return -EBUSY;
+	}
+
 	if (entry->memdesc.cur_bindings != 0) {
+		kgsl_mem_entry_unset_pend(entry);
 		kgsl_mem_entry_put(entry);
 		return -EINVAL;
 	}
@@ -3386,7 +3400,7 @@ long kgsl_ioctl_sparse_phys_free(struct kgsl_device_private *dev_priv,
 
 	/* One put for find_id(), one put for the kgsl_mem_entry_create() */
 	kgsl_mem_entry_put(entry);
-	kgsl_mem_entry_put(entry);
+	kgsl_mem_entry_put_deferred(entry);
 
 	return 0;
 }
@@ -3446,7 +3460,13 @@ long kgsl_ioctl_sparse_virt_free(struct kgsl_device_private *dev_priv,
 	if (entry == NULL)
 		return -EINVAL;
 
+	if (!kgsl_mem_entry_set_pend(entry)) {
+		kgsl_mem_entry_put(entry);
+		return -EBUSY;
+	}
+
 	if (entry->bind_tree.rb_node != NULL) {
+		kgsl_mem_entry_unset_pend(entry);
 		kgsl_mem_entry_put(entry);
 		return -EINVAL;
 	}
@@ -3455,7 +3475,7 @@ long kgsl_ioctl_sparse_virt_free(struct kgsl_device_private *dev_priv,
 
 	/* One put for find_id(), one put for the kgsl_mem_entry_create() */
 	kgsl_mem_entry_put(entry);
-	kgsl_mem_entry_put(entry);
+	kgsl_mem_entry_put_deferred(entry);
 
 	return 0;
 }
@@ -4853,7 +4873,7 @@ static int __init kgsl_core_init(void)
 		WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS, 0);
 
 	kgsl_driver.mem_workqueue = alloc_workqueue("kgsl-mementry",
-		WQ_UNBOUND | WQ_MEM_RECLAIM, 0);
+		WQ_MEM_RECLAIM, 0);
 
 	kgsl_events_init();
 
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index ee4e7ef..ca1f181 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -179,7 +179,7 @@ struct kgsl_functable {
 		unsigned int prelevel, unsigned int postlevel, bool post);
 	void (*regulator_disable_poll)(struct kgsl_device *device);
 	void (*clk_set_options)(struct kgsl_device *device,
-		const char *name, struct clk *clk);
+		const char *name, struct clk *clk, bool on);
 	void (*gpu_model)(struct kgsl_device *device, char *str,
 		size_t bufsz);
 	void (*stop_fault_timer)(struct kgsl_device *device);
@@ -532,18 +532,49 @@ static inline void kgsl_process_add_stats(struct kgsl_process_private *priv,
 		priv->stats[type].max = priv->stats[type].cur;
 }
 
+static inline bool kgsl_is_register_offset(struct kgsl_device *device,
+				unsigned int offsetwords)
+{
+	return ((offsetwords * sizeof(uint32_t)) < device->reg_len);
+}
+
+static inline bool kgsl_is_gmu_offset(struct kgsl_device *device,
+				unsigned int offsetwords)
+{
+	struct gmu_device *gmu = &device->gmu;
+
+	return (gmu->pdev &&
+		(offsetwords >= gmu->gmu2gpu_offset) &&
+		((offsetwords - gmu->gmu2gpu_offset) * sizeof(uint32_t) <
+			gmu->reg_len));
+}
+
 static inline void kgsl_regread(struct kgsl_device *device,
 				unsigned int offsetwords,
 				unsigned int *value)
 {
-	device->ftbl->regread(device, offsetwords, value);
+	if (kgsl_is_register_offset(device, offsetwords))
+		device->ftbl->regread(device, offsetwords, value);
+	else if (device->ftbl->gmu_regread &&
+			kgsl_is_gmu_offset(device, offsetwords))
+		device->ftbl->gmu_regread(device, offsetwords, value);
+	else {
+		WARN(1, "Out of bounds register read: 0x%x\n", offsetwords);
+		*value = 0;
+	}
 }
 
 static inline void kgsl_regwrite(struct kgsl_device *device,
 				 unsigned int offsetwords,
 				 unsigned int value)
 {
-	device->ftbl->regwrite(device, offsetwords, value);
+	if (kgsl_is_register_offset(device, offsetwords))
+		device->ftbl->regwrite(device, offsetwords, value);
+	else if (device->ftbl->gmu_regwrite &&
+			kgsl_is_gmu_offset(device, offsetwords))
+		device->ftbl->gmu_regwrite(device, offsetwords, value);
+	else
+		WARN(1, "Out of bounds register write: 0x%x\n", offsetwords);
 }
 
 static inline void kgsl_gmu_regread(struct kgsl_device *device,
@@ -570,9 +601,9 @@ static inline void kgsl_regrmw(struct kgsl_device *device,
 {
 	unsigned int val = 0;
 
-	device->ftbl->regread(device, offsetwords, &val);
+	kgsl_regread(device, offsetwords, &val);
 	val &= ~mask;
-	device->ftbl->regwrite(device, offsetwords, val | bits);
+	kgsl_regwrite(device, offsetwords, val | bits);
 }
 
 static inline void kgsl_gmu_regrmw(struct kgsl_device *device,
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 7ffb42b..4dd7b8e 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -156,9 +156,6 @@ static void _ab_buslevel_update(struct kgsl_pwrctrl *pwr,
 		*ab = pwr->bus_ab_mbytes;
 	else
 		*ab = (pwr->bus_percent_ab * max_bw) / 100;
-
-	if (*ab > ib)
-		*ab = ib;
 }
 
 /**
@@ -2052,10 +2049,6 @@ static int _get_clocks(struct kgsl_device *device)
 
 			if (!strcmp(name, "isense_clk"))
 				pwr->isense_clk_indx = i;
-
-			if (device->ftbl->clk_set_options)
-				device->ftbl->clk_set_options(device, name,
-					pwr->grp_clks[i]);
 			break;
 		}
 	}
@@ -2480,6 +2473,22 @@ static void kgsl_pwrctrl_disable(struct kgsl_device *device)
 	kgsl_pwrctrl_pwrrail(device, KGSL_PWRFLAGS_OFF);
 }
 
+static void
+kgsl_pwrctrl_clk_set_options(struct kgsl_device *device, bool on)
+{
+	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
+	int i;
+
+	for (i = 0; i < KGSL_MAX_CLKS; i++) {
+		if (pwr->grp_clks[i] == NULL)
+			continue;
+
+		if (device->ftbl->clk_set_options)
+			device->ftbl->clk_set_options(device, clocks[i],
+				pwr->grp_clks[i], on);
+	}
+}
+
 /**
  * _init() - Get the GPU ready to start, but don't turn anything on
  * @device - Pointer to the kgsl_device struct
@@ -2529,6 +2538,7 @@ static int _wake(struct kgsl_device *device)
 		device->ftbl->resume(device);
 		/* fall through */
 	case KGSL_STATE_SLUMBER:
+		kgsl_pwrctrl_clk_set_options(device, true);
 		status = device->ftbl->start(device,
 				device->pwrctrl.superfast);
 		device->pwrctrl.superfast = false;
@@ -2565,6 +2575,7 @@ static int _wake(struct kgsl_device *device)
 				device->pwrctrl.interval_timeout);
 		break;
 	case KGSL_STATE_AWARE:
+		kgsl_pwrctrl_clk_set_options(device, true);
 		/* Enable state before turning on irq */
 		kgsl_pwrctrl_set_state(device, KGSL_STATE_ACTIVE);
 		kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
@@ -2689,6 +2700,7 @@ _slumber(struct kgsl_device *device)
 		status = kgsl_pwrctrl_enable(device);
 		device->ftbl->suspend_context(device);
 		device->ftbl->stop(device);
+		kgsl_pwrctrl_clk_set_options(device, false);
 		kgsl_pwrctrl_disable(device);
 		kgsl_pwrscale_sleep(device);
 		kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c
index fdc4b30..2678a00 100644
--- a/drivers/leds/leds-qpnp-flash-v2.c
+++ b/drivers/leds/leds-qpnp-flash-v2.c
@@ -63,11 +63,13 @@
 #define	FLASH_LED_REG_MITIGATION_SEL(base)	(base + 0x6E)
 #define	FLASH_LED_REG_MITIGATION_SW(base)	(base + 0x6F)
 #define	FLASH_LED_REG_LMH_LEVEL(base)		(base + 0x70)
+#define	FLASH_LED_REG_MULTI_STROBE_CTRL(base)	(base + 0x71)
+#define	FLASH_LED_REG_LPG_INPUT_CTRL(base)	(base + 0x72)
 #define	FLASH_LED_REG_CURRENT_DERATE_EN(base)	(base + 0x76)
 
 #define	FLASH_LED_HDRM_VOL_MASK			GENMASK(7, 4)
 #define	FLASH_LED_CURRENT_MASK			GENMASK(6, 0)
-#define	FLASH_LED_ENABLE_MASK			GENMASK(2, 0)
+#define	FLASH_LED_STROBE_MASK			GENMASK(1, 0)
 #define	FLASH_HW_STROBE_MASK			GENMASK(2, 0)
 #define	FLASH_LED_ISC_WARMUP_DELAY_MASK		GENMASK(1, 0)
 #define	FLASH_LED_CURRENT_DERATE_EN_MASK	GENMASK(2, 0)
@@ -91,6 +93,9 @@
 #define	THERMAL_DERATE_SLOW_SHIFT		4
 #define	THERMAL_DERATE_SLOW_MASK		GENMASK(6, 4)
 #define	THERMAL_DERATE_FAST_MASK		GENMASK(2, 0)
+#define	LED1N2_FLASH_ONCE_ONLY_BIT		BIT(0)
+#define	LED3_FLASH_ONCE_ONLY_BIT		BIT(1)
+#define	LPG_INPUT_SEL_BIT			BIT(0)
 
 #define	VPH_DROOP_DEBOUNCE_US_TO_VAL(val_us)	(val_us / 8)
 #define	VPH_DROOP_HYST_MV_TO_VAL(val_mv)	(val_mv / 25)
@@ -127,11 +132,11 @@
 #define	FLASH_LED_LMH_MITIGATION_DISABLE	0
 #define	FLASH_LED_CHGR_MITIGATION_ENABLE	BIT(4)
 #define	FLASH_LED_CHGR_MITIGATION_DISABLE	0
-#define	FLASH_LED_MITIGATION_SEL_DEFAULT	2
+#define	FLASH_LED_LMH_MITIGATION_SEL_DEFAULT	2
 #define	FLASH_LED_MITIGATION_SEL_MAX		2
 #define	FLASH_LED_CHGR_MITIGATION_SEL_SHIFT	4
-#define	FLASH_LED_MITIGATION_THRSH_DEFAULT	0xA
-#define	FLASH_LED_MITIGATION_THRSH_MAX		0x1F
+#define	FLASH_LED_CHGR_MITIGATION_THRSH_DEFAULT	0xA
+#define	FLASH_LED_CHGR_MITIGATION_THRSH_MAX	0x1F
 #define	FLASH_LED_LMH_OCV_THRESH_DEFAULT_UV	3700000
 #define	FLASH_LED_LMH_RBATT_THRESH_DEFAULT_UOHM	400000
 #define	FLASH_LED_IRES_BASE			3
@@ -152,12 +157,17 @@
 #define	FLASH_LED_MOD_ENABLE			BIT(7)
 #define	FLASH_LED_DISABLE			0x00
 #define	FLASH_LED_SAFETY_TMR_DISABLED		0x13
-#define	FLASH_LED_MIN_CURRENT_MA		25
 #define	FLASH_LED_MAX_TOTAL_CURRENT_MA		3750
 
 /* notifier call chain for flash-led irqs */
 static ATOMIC_NOTIFIER_HEAD(irq_notifier_list);
 
+enum flash_charger_mitigation {
+	FLASH_DISABLE_CHARGER_MITIGATION,
+	FLASH_HW_CHARGER_MITIGATION_BY_ILED_THRSHLD,
+	FLASH_SW_CHARGER_MITIGATION,
+};
+
 enum flash_led_type {
 	FLASH_LED_TYPE_FLASH,
 	FLASH_LED_TYPE_TORCH,
@@ -169,6 +179,12 @@ enum {
 	LED3,
 };
 
+enum strobe_type {
+	SW_STROBE = 0,
+	HW_STROBE,
+	LPG_STROBE,
+};
+
 /*
  * Configurations for each individual LED
  */
@@ -182,13 +198,15 @@ struct flash_node_data {
 	int				ires_ua;
 	int				max_current;
 	int				current_ma;
+	int				prev_current_ma;
 	u8				duration;
 	u8				id;
 	u8				type;
 	u8				ires;
 	u8				hdrm_val;
 	u8				current_reg_val;
-	u8				trigger;
+	u8				strobe_ctrl;
+	u8				strobe_sel;
 	bool				led_on;
 };
 
@@ -226,6 +244,7 @@ struct flash_led_platform_data {
 	int			thermal_thrsh1;
 	int			thermal_thrsh2;
 	int			thermal_thrsh3;
+	int			hw_strobe_option;
 	u32			led1n2_iclamp_low_ma;
 	u32			led1n2_iclamp_mid_ma;
 	u32			led3_iclamp_low_ma;
@@ -240,7 +259,6 @@ struct flash_led_platform_data {
 	u8			chgr_mitigation_sel;
 	u8			lmh_level;
 	u8			iled_thrsh_val;
-	u8			hw_strobe_option;
 	bool			hdrm_auto_mode_en;
 	bool			thermal_derate_en;
 	bool			otst_ramp_bkup_en;
@@ -261,6 +279,7 @@ struct qpnp_flash_led {
 	int				num_fnodes;
 	int				num_snodes;
 	int				enable;
+	int				total_current_ma;
 	u16				base;
 	bool				trigger_lmh;
 	bool				trigger_chgr;
@@ -487,10 +506,12 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
 	if (rc < 0)
 		return rc;
 
+	val = led->pdata->chgr_mitigation_sel
+				<< FLASH_LED_CHGR_MITIGATION_SEL_SHIFT;
 	rc = qpnp_flash_led_masked_write(led,
 			FLASH_LED_REG_MITIGATION_SEL(led->base),
 			FLASH_LED_CHGR_MITIGATION_SEL_MASK,
-			led->pdata->chgr_mitigation_sel);
+			val);
 	if (rc < 0)
 		return rc;
 
@@ -548,6 +569,28 @@ static int qpnp_flash_led_init_settings(struct qpnp_flash_led *led)
 			return rc;
 	}
 
+	if (led->pdata->hw_strobe_option > 0) {
+		rc = qpnp_flash_led_masked_write(led,
+				FLASH_LED_REG_STROBE_CFG(led->base),
+				FLASH_LED_STROBE_MASK,
+				led->pdata->hw_strobe_option);
+		if (rc < 0)
+			return rc;
+	}
+
+	if (led->fnode[LED3].strobe_sel == LPG_STROBE) {
+		rc = qpnp_flash_led_masked_write(led,
+			FLASH_LED_REG_MULTI_STROBE_CTRL(led->base),
+			LED3_FLASH_ONCE_ONLY_BIT, 0);
+		if (rc < 0)
+			return rc;
+
+		rc = qpnp_flash_led_masked_write(led,
+			FLASH_LED_REG_LPG_INPUT_CTRL(led->base),
+			LPG_INPUT_SEL_BIT, LPG_INPUT_SEL_BIT);
+		if (rc < 0)
+			return rc;
+	}
 	return 0;
 }
 
@@ -877,14 +920,29 @@ static int qpnp_flash_led_get_max_avail_current(struct qpnp_flash_led *led)
 	return max_avail_current;
 }
 
+static void qpnp_flash_led_aggregate_max_current(struct flash_node_data *fnode)
+{
+	struct qpnp_flash_led *led = dev_get_drvdata(&fnode->pdev->dev);
+
+	if (fnode->current_ma)
+		led->total_current_ma += fnode->current_ma
+						- fnode->prev_current_ma;
+	else
+		led->total_current_ma -= fnode->prev_current_ma;
+
+	fnode->prev_current_ma = fnode->current_ma;
+}
+
 static void qpnp_flash_led_node_set(struct flash_node_data *fnode, int value)
 {
 	int prgm_current_ma = value;
+	int min_ma = fnode->ires_ua / 1000;
+	struct qpnp_flash_led *led = dev_get_drvdata(&fnode->pdev->dev);
 
 	if (value <= 0)
 		prgm_current_ma = 0;
-	else if (value < FLASH_LED_MIN_CURRENT_MA)
-		prgm_current_ma = FLASH_LED_MIN_CURRENT_MA;
+	else if (value < min_ma)
+		prgm_current_ma = min_ma;
 
 	prgm_current_ma = min(prgm_current_ma, fnode->max_current);
 	fnode->current_ma = prgm_current_ma;
@@ -892,6 +950,13 @@ static void qpnp_flash_led_node_set(struct flash_node_data *fnode, int value)
 	fnode->current_reg_val = CURRENT_MA_TO_REG_VAL(prgm_current_ma,
 					fnode->ires_ua);
 	fnode->led_on = prgm_current_ma != 0;
+
+	if (led->pdata->chgr_mitigation_sel == FLASH_SW_CHARGER_MITIGATION) {
+		qpnp_flash_led_aggregate_max_current(fnode);
+		led->trigger_chgr = false;
+		if (led->total_current_ma >= 1000)
+			led->trigger_chgr = true;
+	}
 }
 
 static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode)
@@ -950,7 +1015,7 @@ static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode)
 
 		led->fnode[i].led_on = false;
 
-		if (led->fnode[i].trigger & FLASH_LED_HW_SW_STROBE_SEL_BIT) {
+		if (led->fnode[i].strobe_sel == HW_STROBE) {
 			rc = qpnp_flash_led_hw_strobe_enable(&led->fnode[i],
 					led->pdata->hw_strobe_option, false);
 			if (rc < 0) {
@@ -1004,13 +1069,6 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
 	if (rc < 0)
 		return rc;
 
-	rc = qpnp_flash_led_masked_write(led,
-					FLASH_LED_REG_STROBE_CFG(led->base),
-					FLASH_LED_ENABLE_MASK,
-					led->pdata->hw_strobe_option);
-	if (rc < 0)
-		return rc;
-
 	val = 0;
 	for (i = 0; i < led->num_fnodes; i++) {
 		if (!led->fnode[i].led_on ||
@@ -1018,13 +1076,13 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
 			continue;
 
 		addr_offset = led->fnode[i].id;
-		if (led->fnode[i].trigger & FLASH_LED_HW_SW_STROBE_SEL_BIT)
-			mask = FLASH_HW_STROBE_MASK;
-		else
+		if (led->fnode[i].strobe_sel == SW_STROBE)
 			mask = FLASH_LED_HW_SW_STROBE_SEL_BIT;
+		else
+			mask = FLASH_HW_STROBE_MASK;
 		rc = qpnp_flash_led_masked_write(led,
 			FLASH_LED_REG_STROBE_CTRL(led->base + addr_offset),
-			mask, led->fnode[i].trigger);
+			mask, led->fnode[i].strobe_ctrl);
 		if (rc < 0)
 			return rc;
 
@@ -1042,7 +1100,7 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
 
 		val |= FLASH_LED_ENABLE << led->fnode[i].id;
 
-		if (led->fnode[i].trigger & FLASH_LED_HW_SW_STROBE_SEL_BIT) {
+		if (led->fnode[i].strobe_sel == HW_STROBE) {
 			rc = qpnp_flash_led_hw_strobe_enable(&led->fnode[i],
 					led->pdata->hw_strobe_option, true);
 			if (rc < 0) {
@@ -1159,10 +1217,6 @@ int qpnp_flash_led_prepare(struct led_trigger *trig, int options,
 		*max_current = rc;
 	}
 
-	led->trigger_chgr = false;
-	if (options & PRE_FLASH)
-		led->trigger_chgr = true;
-
 	return 0;
 }
 
@@ -1336,9 +1390,9 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
 			struct flash_node_data *fnode, struct device_node *node)
 {
 	const char *temp_string;
-	int rc;
+	int rc, min_ma;
 	u32 val;
-	bool strobe_sel = 0, edge_trigger = 0, active_high = 0;
+	bool hw_strobe = 0, edge_trigger = 0, active_high = 0;
 
 	fnode->pdev = led->pdev;
 	fnode->cdev.brightness_set = qpnp_flash_led_brightness_set;
@@ -1392,10 +1446,11 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
 		return rc;
 	}
 
+	min_ma = fnode->ires_ua / 1000;
 	rc = of_property_read_u32(node, "qcom,max-current", &val);
 	if (!rc) {
-		if (val < FLASH_LED_MIN_CURRENT_MA)
-			val = FLASH_LED_MIN_CURRENT_MA;
+		if (val < min_ma)
+			val = min_ma;
 		fnode->max_current = val;
 		fnode->cdev.max_brightness = val;
 	} else {
@@ -1405,11 +1460,10 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
 
 	rc = of_property_read_u32(node, "qcom,current-ma", &val);
 	if (!rc) {
-		if (val < FLASH_LED_MIN_CURRENT_MA ||
-				val > fnode->max_current)
+		if (val < min_ma || val > fnode->max_current)
 			pr_warn("Invalid operational current specified, capping it\n");
-		if (val < FLASH_LED_MIN_CURRENT_MA)
-			val = FLASH_LED_MIN_CURRENT_MA;
+		if (val < min_ma)
+			val = min_ma;
 		if (val > fnode->max_current)
 			val = fnode->max_current;
 		fnode->current_ma = val;
@@ -1457,14 +1511,52 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
 		return rc;
 	}
 
-	strobe_sel = of_property_read_bool(node, "qcom,hw-strobe-sel");
-	if (strobe_sel) {
+	fnode->strobe_sel = SW_STROBE;
+	rc = of_property_read_u32(node, "qcom,strobe-sel", &val);
+	if (rc < 0) {
+		if (rc != -EINVAL) {
+			pr_err("Unable to read qcom,strobe-sel property\n");
+			return rc;
+		}
+	} else {
+		if (val < SW_STROBE || val > LPG_STROBE) {
+			pr_err("Incorrect strobe selection specified %d\n",
+				val);
+			return -EINVAL;
+		}
+		fnode->strobe_sel = (u8)val;
+	}
+
+	/*
+	 * LPG strobe is allowed only for LED3 and HW strobe option should be
+	 * option 2 or 3.
+	 */
+	if (fnode->strobe_sel == LPG_STROBE) {
+		if (led->pdata->hw_strobe_option ==
+				FLASH_LED_HW_STROBE_OPTION_1) {
+			pr_err("Incorrect strobe option for LPG strobe\n");
+			return -EINVAL;
+		}
+		if (fnode->id != LED3) {
+			pr_err("Incorrect LED chosen for LPG strobe\n");
+			return -EINVAL;
+		}
+	}
+
+	if (fnode->strobe_sel == HW_STROBE) {
 		edge_trigger = of_property_read_bool(node,
 						"qcom,hw-strobe-edge-trigger");
 		active_high = !of_property_read_bool(node,
 						"qcom,hw-strobe-active-low");
+		hw_strobe = 1;
+	} else if (fnode->strobe_sel == LPG_STROBE) {
+		/* LPG strobe requires level trigger and active high */
+		edge_trigger = 0;
+		active_high =  1;
+		hw_strobe = 1;
 	}
-	fnode->trigger = (strobe_sel << 2) | (edge_trigger << 1) | active_high;
+	fnode->strobe_ctrl = (hw_strobe << 2) | (edge_trigger << 1) |
+				active_high;
 
 	rc = led_classdev_register(&led->pdev->dev, &fnode->cdev);
 	if (rc < 0) {
@@ -1480,7 +1572,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
 		fnode->strobe_pinctrl = NULL;
 	}
 
-	if (fnode->trigger & FLASH_LED_HW_SW_STROBE_SEL_BIT) {
+	if (fnode->strobe_sel == HW_STROBE) {
 		if (of_find_property(node, "qcom,hw-strobe-gpio", NULL)) {
 			fnode->hw_strobe_gpio = of_get_named_gpio(node,
 						"qcom,hw-strobe-gpio", 0);
@@ -1860,9 +1952,10 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
 
 	led->pdata->vph_droop_hysteresis <<= FLASH_LED_VPH_DROOP_HYST_SHIFT;
 
+	led->pdata->hw_strobe_option = -EINVAL;
 	rc = of_property_read_u32(node, "qcom,hw-strobe-option", &val);
 	if (!rc) {
-		led->pdata->hw_strobe_option = (u8)val;
+		led->pdata->hw_strobe_option = val;
 	} else if (rc != -EINVAL) {
 		pr_err("Unable to parse hw strobe option, rc=%d\n", rc);
 		return rc;
@@ -1957,7 +2050,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
 		return rc;
 	}
 
-	led->pdata->lmh_mitigation_sel = FLASH_LED_MITIGATION_SEL_DEFAULT;
+	led->pdata->lmh_mitigation_sel = FLASH_LED_LMH_MITIGATION_SEL_DEFAULT;
 	rc = of_property_read_u32(node, "qcom,lmh-mitigation-sel", &val);
 	if (!rc) {
 		led->pdata->lmh_mitigation_sel = val;
@@ -1971,7 +2064,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
 		return -EINVAL;
 	}
 
-	led->pdata->chgr_mitigation_sel = FLASH_LED_MITIGATION_SEL_DEFAULT;
+	led->pdata->chgr_mitigation_sel = FLASH_SW_CHARGER_MITIGATION;
 	rc = of_property_read_u32(node, "qcom,chgr-mitigation-sel", &val);
 	if (!rc) {
 		led->pdata->chgr_mitigation_sel = val;
@@ -1985,9 +2078,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
 		return -EINVAL;
 	}
 
-	led->pdata->chgr_mitigation_sel <<= FLASH_LED_CHGR_MITIGATION_SEL_SHIFT;
-
-	led->pdata->iled_thrsh_val = FLASH_LED_MITIGATION_THRSH_DEFAULT;
+	led->pdata->iled_thrsh_val = FLASH_LED_CHGR_MITIGATION_THRSH_DEFAULT;
 	rc = of_property_read_u32(node, "qcom,iled-thrsh-ma", &val);
 	if (!rc) {
 		led->pdata->iled_thrsh_val = MITIGATION_THRSH_MA_TO_VAL(val);
@@ -1996,7 +2087,7 @@ static int qpnp_flash_led_parse_common_dt(struct qpnp_flash_led *led,
 		return rc;
 	}
 
-	if (led->pdata->iled_thrsh_val > FLASH_LED_MITIGATION_THRSH_MAX) {
+	if (led->pdata->iled_thrsh_val > FLASH_LED_CHGR_MITIGATION_THRSH_MAX) {
 		pr_err("Invalid iled_thrsh_val specified\n");
 		return -EINVAL;
 	}
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c
index 13affe9..1a8356a 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.c
@@ -461,6 +461,27 @@ static int cam_video_device_setup(void)
 	return rc;
 }
 
+int cam_req_mgr_notify_frame_message(struct cam_req_mgr_message *msg,
+	uint32_t id,
+	uint32_t type)
+{
+	struct v4l2_event event;
+	struct cam_req_mgr_message *ev_header;
+
+	if (!msg)
+		return -EINVAL;
+
+	event.id = id;
+	event.type = type;
+	ev_header = CAM_REQ_MGR_GET_PAYLOAD_PTR(event,
+		struct cam_req_mgr_message);
+	memcpy(ev_header, msg, sizeof(struct cam_req_mgr_message));
+	v4l2_event_queue(g_dev.video, &event);
+
+	return 0;
+}
+EXPORT_SYMBOL(cam_req_mgr_notify_frame_message);
+
 void cam_video_device_cleanup(void)
 {
 	video_unregister_device(g_dev.video);
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.h b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.h
index 430e46e..77faed9 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.h
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_dev.h
@@ -40,4 +40,11 @@ struct cam_req_mgr_device {
 	spinlock_t cam_eventq_lock;
 };
 
+#define CAM_REQ_MGR_GET_PAYLOAD_PTR(ev, type)        \
+	(type *)((char *)ev.u.data)
+
+int cam_req_mgr_notify_frame_message(struct cam_req_mgr_message *msg,
+	uint32_t id,
+	uint32_t type);
+
 #endif /* _CAM_REQ_MGR_DEV_H_ */
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
index 6ebfc1a..17fa2cc 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
@@ -351,12 +351,12 @@ static u32 sde_hw_rotator_v4_outpixfmts[] = {
 	SDE_PIX_FMT_Y_CBCR_H2V2_UBWC,
 	SDE_PIX_FMT_RGBA_1010102,
 	SDE_PIX_FMT_RGBX_1010102,
-	/* SDE_PIX_FMT_ARGB_2101010 */
-	/* SDE_PIX_FMT_XRGB_2101010 */
+	SDE_PIX_FMT_ARGB_2101010,
+	SDE_PIX_FMT_XRGB_2101010,
 	SDE_PIX_FMT_BGRA_1010102,
 	SDE_PIX_FMT_BGRX_1010102,
-	/* SDE_PIX_FMT_ABGR_2101010 */
-	/* SDE_PIX_FMT_XBGR_2101010 */
+	SDE_PIX_FMT_ABGR_2101010,
+	SDE_PIX_FMT_XBGR_2101010,
 	SDE_PIX_FMT_RGBA_1010102_UBWC,
 	SDE_PIX_FMT_RGBX_1010102_UBWC,
 	SDE_PIX_FMT_Y_CBCR_H2V2_P010,
diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
index c5c4269..7802d31 100644
--- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
@@ -785,6 +785,8 @@ static int __init msm_vidc_init(void)
 	if (rc) {
 		dprintk(VIDC_ERR,
 			"Failed to register platform driver\n");
+		msm_vidc_debugfs_deinit_drv();
+		debugfs_remove_recursive(vidc_driver->debugfs_root);
 		kfree(vidc_driver);
 		vidc_driver = NULL;
 	}
@@ -795,6 +797,7 @@ static int __init msm_vidc_init(void)
 static void __exit msm_vidc_exit(void)
 {
 	platform_driver_unregister(&msm_vidc_driver);
+	msm_vidc_debugfs_deinit_drv();
 	debugfs_remove_recursive(vidc_driver->debugfs_root);
 	mutex_destroy(&vidc_driver->lock);
 	kfree(vidc_driver);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
index 22491f6..8ffbf50 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
@@ -31,11 +31,12 @@ int msm_vidc_firmware_unload_delay = 15000;
 bool msm_vidc_thermal_mitigation_disabled = !true;
 bool msm_vidc_clock_scaling = true;
 bool msm_vidc_debug_timeout = !true;
-bool msm_vidc_syscache_disable = true;
+bool msm_vidc_syscache_disable = !true;
 
 #define MAX_DBG_BUF_SIZE 4096
 
 struct debug_buffer {
+	struct mutex lock;
 	char ptr[MAX_DBG_BUF_SIZE];
 	char *curr;
 	u32 filled_size;
@@ -63,8 +64,11 @@ static u32 write_str(struct debug_buffer *buffer, const char *fmt, ...)
 	va_list args;
 	u32 size;
 
+	char *curr = buffer->curr;
+	char *end = buffer->ptr + MAX_DBG_BUF_SIZE;
+
 	va_start(args, fmt);
-	size = vscnprintf(buffer->curr, MAX_DBG_BUF_SIZE - 1, fmt, args);
+	size = vscnprintf(curr, end - curr, fmt, args);
 	va_end(args);
 	buffer->curr += size;
 	buffer->filled_size += size;
@@ -78,12 +82,15 @@ static ssize_t core_info_read(struct file *file, char __user *buf,
 	struct hfi_device *hdev;
 	struct hal_fw_info fw_info = { {0} };
 	int i = 0, rc = 0;
+	ssize_t len = 0;
 
 	if (!core || !core->device) {
 		dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core);
 		return 0;
 	}
 	hdev = core->device;
+
+	mutex_lock(&dbg_buf.lock);
 	INIT_DBG_BUF(dbg_buf);
 	write_str(&dbg_buf, "===============================\n");
 	write_str(&dbg_buf, "CORE %d: %pK\n", core->id, core);
@@ -107,8 +114,11 @@ static ssize_t core_info_read(struct file *file, char __user *buf,
 			completion_done(&core->completions[SYS_MSG_INDEX(i)]) ?
 			"pending" : "done");
 	}
-	return simple_read_from_buffer(buf, count, ppos,
+	len = simple_read_from_buffer(buf, count, ppos,
 			dbg_buf.ptr, dbg_buf.filled_size);
+
+	mutex_unlock(&dbg_buf.lock);
+	return len;
 }
 
 static const struct file_operations core_info_fops = {
@@ -150,8 +160,10 @@ static const struct file_operations ssr_fops = {
 struct dentry *msm_vidc_debugfs_init_drv(void)
 {
 	bool ok = false;
-	struct dentry *dir = debugfs_create_dir("msm_vidc", NULL);
+	struct dentry *dir = NULL;
 
+	mutex_init(&dbg_buf.lock);
+	dir = debugfs_create_dir("msm_vidc", NULL);
 	if (IS_ERR_OR_NULL(dir)) {
 		dir = NULL;
 		goto failed_create_dir;
@@ -274,11 +286,14 @@ static ssize_t inst_info_read(struct file *file, char __user *buf,
 {
 	struct msm_vidc_inst *inst = file->private_data;
 	int i, j;
+	ssize_t len = 0;
 
 	if (!inst) {
 		dprintk(VIDC_ERR, "Invalid params, inst %pK\n", inst);
 		return 0;
 	}
+
+	mutex_lock(&dbg_buf.lock);
 	INIT_DBG_BUF(dbg_buf);
 	write_str(&dbg_buf, "===============================\n");
 	write_str(&dbg_buf, "INSTANCE: %pK (%s)\n", inst,
@@ -333,8 +348,10 @@ static ssize_t inst_info_read(struct file *file, char __user *buf,
 
 	publish_unreleased_reference(inst);
 
-	return simple_read_from_buffer(buf, count, ppos,
+	len = simple_read_from_buffer(buf, count, ppos,
 		dbg_buf.ptr, dbg_buf.filled_size);
+	mutex_unlock(&dbg_buf.lock);
+	return len;
 }
 
 static const struct file_operations inst_info_fops = {
@@ -417,3 +434,8 @@ void msm_vidc_debugfs_update(struct msm_vidc_inst *inst,
 	}
 }
 
+void msm_vidc_debugfs_deinit_drv(void)
+{
+	mutex_destroy(&dbg_buf.lock);
+}
+
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.h b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
index c23ff82..8fd895d 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
@@ -128,6 +128,7 @@ struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst,
 		struct dentry *parent);
 void msm_vidc_debugfs_update(struct msm_vidc_inst *inst,
 		enum msm_vidc_debugfs_event e);
+void msm_vidc_debugfs_deinit_drv(void);
 
 static inline void tic(struct msm_vidc_inst *i, enum profiling_points p,
 				 char *b)
diff --git a/drivers/mfd/wcd9xxx-irq.c b/drivers/mfd/wcd9xxx-irq.c
index 30ad689e..0502e39d 100644
--- a/drivers/mfd/wcd9xxx-irq.c
+++ b/drivers/mfd/wcd9xxx-irq.c
@@ -293,7 +293,7 @@ static irqreturn_t wcd9xxx_irq_thread(int irq, void *data)
 	static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 1);
 	struct wcd9xxx_core_resource *wcd9xxx_res = data;
 	int num_irq_regs = wcd9xxx_res->num_irq_regs;
-	u8 status[num_irq_regs], status1[num_irq_regs];
+	u8 status[4], status1[4] = {0}, unmask_status[4] = {0};
 
 	if (unlikely(wcd9xxx_lock_sleep(wcd9xxx_res) == false)) {
 		dev_err(wcd9xxx_res->dev, "Failed to hold suspend\n");
@@ -317,6 +317,23 @@ static irqreturn_t wcd9xxx_irq_thread(int irq, void *data)
 				"Failed to read interrupt status: %d\n", ret);
 		goto err_disable_irq;
 	}
+	/*
+	 * If status is 0 return without clearing.
+	 * status contains: HW status - masked interrupts
+	 * status1 contains: unhandled interrupts - masked interrupts
+	 * unmasked_status contains: unhandled interrupts
+	 */
+	if (unlikely(!memcmp(status, status1, sizeof(status)))) {
+		pr_debug("%s: status is 0\n", __func__);
+		wcd9xxx_unlock_sleep(wcd9xxx_res);
+		return IRQ_HANDLED;
+	}
+
+	/*
+	 * Copy status to unmask_status before masking, otherwise SW may miss
+	 * to clear masked interrupt in corner case.
+	 */
+	memcpy(unmask_status, status, sizeof(unmask_status));
 
 	/* Apply masking */
 	for (i = 0; i < num_irq_regs; i++)
@@ -340,6 +357,8 @@ static irqreturn_t wcd9xxx_irq_thread(int irq, void *data)
 			wcd9xxx_irq_dispatch(wcd9xxx_res, &irqdata);
 			status1[BIT_BYTE(irqdata.intr_num)] &=
 					~BYTE_BIT_MASK(irqdata.intr_num);
+			unmask_status[BIT_BYTE(irqdata.intr_num)] &=
+					~BYTE_BIT_MASK(irqdata.intr_num);
 		}
 	}
 
@@ -361,12 +380,13 @@ static irqreturn_t wcd9xxx_irq_thread(int irq, void *data)
 					   linebuf, sizeof(linebuf), false);
 			pr_warn("%s: status1 : %s\n", __func__, linebuf);
 		}
-
-		memset(status, 0xff, num_irq_regs);
-
+		/*
+		 * unmask_status contains unhandled interrupts, hence clear all
+		 * unhandled interrupts.
+		 */
 		ret = regmap_bulk_write(wcd9xxx_res->wcd_core_regmap,
 			wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLEAR_BASE],
-			status, num_irq_regs);
+			unmask_status, num_irq_regs);
 		if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
 			regmap_write(wcd9xxx_res->wcd_core_regmap,
 				wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLR_COMMIT],
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index 304e206..40ee647 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -88,14 +88,14 @@
 	  Qualcomm Technologies Inc TLMM block found on the Qualcomm
 	  Technologies Inc SDM845 platform.
 
-config PINCTRL_SDM830
-	tristate "Qualcomm Technologies Inc SDM830 pin controller driver"
+config PINCTRL_SDM670
+	tristate "Qualcomm Technologies Inc SDM670 pin controller driver"
 	depends on GPIOLIB && OF
 	select PINCTRL_MSM
 	help
 	  This is the pinctrl, pinmux, pinconf and gpiolib driver for the
 	  Qualcomm Technologies Inc TLMM block found on the Qualcomm
-	  Technologies Inc SDM830 platform.
+	  Technologies Inc SDM670 platform.
 
 config PINCTRL_SDXPOORWILLS
 	tristate "Qualcomm Technologies Inc SDXPOORWILLS pin controller driver"
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
index 4786960..6a49671 100644
--- a/drivers/pinctrl/qcom/Makefile
+++ b/drivers/pinctrl/qcom/Makefile
@@ -16,7 +16,7 @@
 obj-$(CONFIG_PINCTRL_QCOM_SSBI_PMIC) += pinctrl-ssbi-gpio.o
 obj-$(CONFIG_PINCTRL_QCOM_SSBI_PMIC) += pinctrl-ssbi-mpp.o
 obj-$(CONFIG_PINCTRL_SDM845) += pinctrl-sdm845.o
-obj-$(CONFIG_PINCTRL_SDM830) += pinctrl-sdm830.o
+obj-$(CONFIG_PINCTRL_SDM670) += pinctrl-sdm670.o
 obj-$(CONFIG_PINCTRL_SDXPOORWILLS)	+= pinctrl-sdxpoorwills.o
 obj-$(CONFIG_PINCTRL_WCD)	+= pinctrl-wcd.o
 obj-$(CONFIG_PINCTRL_LPI)	+= pinctrl-lpi.o
diff --git a/drivers/pinctrl/qcom/pinctrl-sdm830.c b/drivers/pinctrl/qcom/pinctrl-sdm670.c
similarity index 96%
rename from drivers/pinctrl/qcom/pinctrl-sdm830.c
rename to drivers/pinctrl/qcom/pinctrl-sdm670.c
index fc3d0ad..c93628e 100644
--- a/drivers/pinctrl/qcom/pinctrl-sdm830.c
+++ b/drivers/pinctrl/qcom/pinctrl-sdm670.c
@@ -29,7 +29,6 @@
 #define SOUTH	0x00900000
 #define WEST	0x00100000
 #define REG_SIZE 0x1000
-
 #define PINGROUP(id, base, f1, f2, f3, f4, f5, f6, f7, f8, f9)	\
 	{						\
 		.name = "gpio" #id,			\
@@ -118,7 +117,7 @@
 		.intr_detection_bit = -1,		\
 		.intr_detection_width = -1,		\
 	}
-static const struct pinctrl_pin_desc sdm830_pins[] = {
+static const struct pinctrl_pin_desc sdm670_pins[] = {
 	PINCTRL_PIN(0, "GPIO_0"),
 	PINCTRL_PIN(1, "GPIO_1"),
 	PINCTRL_PIN(2, "GPIO_2"),
@@ -255,9 +254,12 @@ static const struct pinctrl_pin_desc sdm830_pins[] = {
 	PINCTRL_PIN(147, "GPIO_147"),
 	PINCTRL_PIN(148, "GPIO_148"),
 	PINCTRL_PIN(149, "GPIO_149"),
-	PINCTRL_PIN(150, "SDC2_CLK"),
-	PINCTRL_PIN(151, "SDC2_CMD"),
-	PINCTRL_PIN(152, "SDC2_DATA"),
+	PINCTRL_PIN(150, "SDC1_CLK"),
+	PINCTRL_PIN(151, "SDC1_CMD"),
+	PINCTRL_PIN(152, "SDC1_DATA"),
+	PINCTRL_PIN(153, "SDC2_CLK"),
+	PINCTRL_PIN(154, "SDC2_CMD"),
+	PINCTRL_PIN(155, "SDC2_DATA"),
 };
 
 #define DECLARE_MSM_GPIO_PINS(pin) \
@@ -399,11 +401,14 @@ DECLARE_MSM_GPIO_PINS(147);
 DECLARE_MSM_GPIO_PINS(148);
 DECLARE_MSM_GPIO_PINS(149);
 
-static const unsigned int sdc2_clk_pins[] = { 150 };
-static const unsigned int sdc2_cmd_pins[] = { 151 };
-static const unsigned int sdc2_data_pins[] = { 152 };
+static const unsigned int sdc1_clk_pins[] = { 150 };
+static const unsigned int sdc1_cmd_pins[] = { 151 };
+static const unsigned int sdc1_data_pins[] = { 152 };
+static const unsigned int sdc2_clk_pins[] = { 153 };
+static const unsigned int sdc2_cmd_pins[] = { 154 };
+static const unsigned int sdc2_data_pins[] = { 155 };
 
-enum sdm830_functions {
+enum sdm670_functions {
 	msm_mux_qup0,
 	msm_mux_gpio,
 	msm_mux_reserved0,
@@ -456,6 +461,16 @@ enum sdm830_functions {
 	msm_mux_qup1,
 	msm_mux_qdss_gpio4,
 	msm_mux_reserved17,
+	msm_mux_qdss_gpio5,
+	msm_mux_reserved18,
+	msm_mux_qdss_gpio6,
+	msm_mux_reserved19,
+	msm_mux_qdss_gpio7,
+	msm_mux_reserved20,
+	msm_mux_cci_timer0,
+	msm_mux_gcc_gp2,
+	msm_mux_qdss_gpio8,
+	msm_mux_reserved21,
 	msm_mux_cci_timer1,
 	msm_mux_gcc_gp3,
 	msm_mux_qdss_gpio,
@@ -470,16 +485,6 @@ enum sdm830_functions {
 	msm_mux_cci_timer4,
 	msm_mux_qdss_gpio11,
 	msm_mux_reserved25,
-	msm_mux_qdss_gpio5,
-	msm_mux_reserved18,
-	msm_mux_qdss_gpio6,
-	msm_mux_reserved19,
-	msm_mux_qdss_gpio7,
-	msm_mux_reserved20,
-	msm_mux_cci_timer0,
-	msm_mux_gcc_gp2,
-	msm_mux_qdss_gpio8,
-	msm_mux_reserved21,
 	msm_mux_qdss_gpio12,
 	msm_mux_JITTER_BIST,
 	msm_mux_reserved26,
@@ -894,6 +899,36 @@ static const char * const qdss_gpio4_groups[] = {
 static const char * const reserved17_groups[] = {
 	"gpio17",
 };
+static const char * const qdss_gpio5_groups[] = {
+	"gpio18", "gpio122",
+};
+static const char * const reserved18_groups[] = {
+	"gpio18",
+};
+static const char * const qdss_gpio6_groups[] = {
+	"gpio19", "gpio41",
+};
+static const char * const reserved19_groups[] = {
+	"gpio19",
+};
+static const char * const qdss_gpio7_groups[] = {
+	"gpio20", "gpio42",
+};
+static const char * const reserved20_groups[] = {
+	"gpio20",
+};
+static const char * const cci_timer0_groups[] = {
+	"gpio21",
+};
+static const char * const gcc_gp2_groups[] = {
+	"gpio21",
+};
+static const char * const qdss_gpio8_groups[] = {
+	"gpio21", "gpio75",
+};
+static const char * const reserved21_groups[] = {
+	"gpio21",
+};
 static const char * const cci_timer1_groups[] = {
 	"gpio22",
 };
@@ -936,36 +971,6 @@ static const char * const qdss_gpio11_groups[] = {
 static const char * const reserved25_groups[] = {
 	"gpio25",
 };
-static const char * const qdss_gpio5_groups[] = {
-	"gpio18", "gpio122",
-};
-static const char * const reserved18_groups[] = {
-	"gpio18",
-};
-static const char * const qdss_gpio6_groups[] = {
-	"gpio19", "gpio41",
-};
-static const char * const reserved19_groups[] = {
-	"gpio19",
-};
-static const char * const qdss_gpio7_groups[] = {
-	"gpio20", "gpio42",
-};
-static const char * const reserved20_groups[] = {
-	"gpio20",
-};
-static const char * const cci_timer0_groups[] = {
-	"gpio21",
-};
-static const char * const gcc_gp2_groups[] = {
-	"gpio21",
-};
-static const char * const qdss_gpio8_groups[] = {
-	"gpio21", "gpio75",
-};
-static const char * const reserved21_groups[] = {
-	"gpio21",
-};
 static const char * const qdss_gpio12_groups[] = {
 	"gpio26", "gpio80",
 };
@@ -1680,7 +1685,7 @@ static const char * const reserved123_groups[] = {
 	"gpio123",
 };
 
-static const struct msm_function sdm830_functions[] = {
+static const struct msm_function sdm670_functions[] = {
 	FUNCTION(qup0),
 	FUNCTION(gpio),
 	FUNCTION(reserved0),
@@ -1733,6 +1738,16 @@ static const struct msm_function sdm830_functions[] = {
 	FUNCTION(qup1),
 	FUNCTION(qdss_gpio4),
 	FUNCTION(reserved17),
+	FUNCTION(qdss_gpio5),
+	FUNCTION(reserved18),
+	FUNCTION(qdss_gpio6),
+	FUNCTION(reserved19),
+	FUNCTION(qdss_gpio7),
+	FUNCTION(reserved20),
+	FUNCTION(cci_timer0),
+	FUNCTION(gcc_gp2),
+	FUNCTION(qdss_gpio8),
+	FUNCTION(reserved21),
 	FUNCTION(cci_timer1),
 	FUNCTION(gcc_gp3),
 	FUNCTION(qdss_gpio),
@@ -1747,16 +1762,6 @@ static const struct msm_function sdm830_functions[] = {
 	FUNCTION(cci_timer4),
 	FUNCTION(qdss_gpio11),
 	FUNCTION(reserved25),
-	FUNCTION(qdss_gpio5),
-	FUNCTION(reserved18),
-	FUNCTION(qdss_gpio6),
-	FUNCTION(reserved19),
-	FUNCTION(qdss_gpio7),
-	FUNCTION(reserved20),
-	FUNCTION(cci_timer0),
-	FUNCTION(gcc_gp2),
-	FUNCTION(qdss_gpio8),
-	FUNCTION(reserved21),
 	FUNCTION(qdss_gpio12),
 	FUNCTION(JITTER_BIST),
 	FUNCTION(reserved26),
@@ -1996,7 +2001,7 @@ static const struct msm_function sdm830_functions[] = {
 	FUNCTION(reserved123),
 };
 
-static const struct msm_pingroup sdm830_groups[] = {
+static const struct msm_pingroup sdm670_groups[] = {
 	PINGROUP(0, SOUTH, qup0, NA, reserved0, NA, NA, NA, NA, NA, NA),
 	PINGROUP(1, SOUTH, qup0, NA, reserved1, NA, NA, NA, NA, NA, NA),
 	PINGROUP(2, SOUTH, qup0, NA, reserved2, NA, NA, NA, NA, NA, NA),
@@ -2108,9 +2113,9 @@ static const struct msm_pingroup sdm830_groups[] = {
 		 QUP_L5, reserved76, NA, NA, NA),
 	PINGROUP(77, NORTH, ter_mi2s, phase_flag4, qdss_gpio10, atest_usb20,
 		 QUP_L6, reserved77, NA, NA, NA),
-	PINGROUP(78, NORTH, ter_mi2s, gcc_gp1, reserved78, NA, NA, NA, NA, NA,
+	PINGROUP(78, NORTH, ter_mi2s, gcc_gp1, NA, reserved78, NA, NA, NA, NA,
 		 NA),
-	PINGROUP(79, NORTH, sec_mi2s, GP_PDM2, NA, qdss_gpio11, reserved79, NA,
+	PINGROUP(79, NORTH, sec_mi2s, GP_PDM2, NA, qdss_gpio11, NA, reserved79,
 		 NA, NA, NA),
 	PINGROUP(80, NORTH, sec_mi2s, NA, qdss_gpio12, reserved80, NA, NA, NA,
 		 NA, NA),
@@ -2231,53 +2236,56 @@ static const struct msm_pingroup sdm830_groups[] = {
 	PINGROUP(147, WEST, NA, NA, reserved147, NA, NA, NA, NA, NA, NA),
 	PINGROUP(148, WEST, NA, reserved148, NA, NA, NA, NA, NA, NA, NA),
 	PINGROUP(149, WEST, NA, reserved149, NA, NA, NA, NA, NA, NA, NA),
-	SDC_QDSD_PINGROUP(sdc2_clk, 0x59a000, 14, 6),
-	SDC_QDSD_PINGROUP(sdc2_cmd, 0x59a000, 11, 3),
-	SDC_QDSD_PINGROUP(sdc2_data, 0x59a000, 9, 0),
+	SDC_QDSD_PINGROUP(sdc1_clk, 0x599000, 13, 6),
+	SDC_QDSD_PINGROUP(sdc1_cmd, 0x599000, 11, 3),
+	SDC_QDSD_PINGROUP(sdc1_data, 0x599000, 9, 0),
+	SDC_QDSD_PINGROUP(sdc2_clk, 0x99a000, 14, 6),
+	SDC_QDSD_PINGROUP(sdc2_cmd, 0x99a000, 11, 3),
+	SDC_QDSD_PINGROUP(sdc2_data, 0x99a000, 9, 0),
 };
 
-static const struct msm_pinctrl_soc_data sdm830_pinctrl = {
-	.pins = sdm830_pins,
-	.npins = ARRAY_SIZE(sdm830_pins),
-	.functions = sdm830_functions,
-	.nfunctions = ARRAY_SIZE(sdm830_functions),
-	.groups = sdm830_groups,
-	.ngroups = ARRAY_SIZE(sdm830_groups),
+static const struct msm_pinctrl_soc_data sdm670_pinctrl = {
+	.pins = sdm670_pins,
+	.npins = ARRAY_SIZE(sdm670_pins),
+	.functions = sdm670_functions,
+	.nfunctions = ARRAY_SIZE(sdm670_functions),
+	.groups = sdm670_groups,
+	.ngroups = ARRAY_SIZE(sdm670_groups),
 	.ngpios = 136,
 };
 
-static int sdm830_pinctrl_probe(struct platform_device *pdev)
+static int sdm670_pinctrl_probe(struct platform_device *pdev)
 {
-	return msm_pinctrl_probe(pdev, &sdm830_pinctrl);
+	return msm_pinctrl_probe(pdev, &sdm670_pinctrl);
 }
 
-static const struct of_device_id sdm830_pinctrl_of_match[] = {
-	{ .compatible = "qcom,sdm830-pinctrl", },
+static const struct of_device_id sdm670_pinctrl_of_match[] = {
+	{ .compatible = "qcom,sdm670-pinctrl", },
 	{ },
 };
 
-static struct platform_driver sdm830_pinctrl_driver = {
+static struct platform_driver sdm670_pinctrl_driver = {
 	.driver = {
-		.name = "sdm830-pinctrl",
+		.name = "sdm670-pinctrl",
 		.owner = THIS_MODULE,
-		.of_match_table = sdm830_pinctrl_of_match,
+		.of_match_table = sdm670_pinctrl_of_match,
 	},
-	.probe = sdm830_pinctrl_probe,
+	.probe = sdm670_pinctrl_probe,
 	.remove = msm_pinctrl_remove,
 };
 
-static int __init sdm830_pinctrl_init(void)
+static int __init sdm670_pinctrl_init(void)
 {
-	return platform_driver_register(&sdm830_pinctrl_driver);
+	return platform_driver_register(&sdm670_pinctrl_driver);
 }
-arch_initcall(sdm830_pinctrl_init);
+arch_initcall(sdm670_pinctrl_init);
 
-static void __exit sdm830_pinctrl_exit(void)
+static void __exit sdm670_pinctrl_exit(void)
 {
-	platform_driver_unregister(&sdm830_pinctrl_driver);
+	platform_driver_unregister(&sdm670_pinctrl_driver);
 }
-module_exit(sdm830_pinctrl_exit);
+module_exit(sdm670_pinctrl_exit);
 
-MODULE_DESCRIPTION("QTI sdm830 pinctrl driver");
+MODULE_DESCRIPTION("QTI sdm670 pinctrl driver");
 MODULE_LICENSE("GPL v2");
-MODULE_DEVICE_TABLE(of, sdm830_pinctrl_of_match);
+MODULE_DEVICE_TABLE(of, sdm670_pinctrl_of_match);
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa.c b/drivers/platform/msm/ipa/ipa_v2/ipa.c
index 947a54c..53ab299 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa.c
@@ -1836,6 +1836,7 @@ static int ipa_q6_clean_q6_tables(void)
 	struct ipa_mem_buffer mem = { 0 };
 	u32 *entry;
 	u32 max_cmds = ipa_get_max_flt_rt_cmds(ipa_ctx->ipa_num_pipes);
+	gfp_t flag = GFP_KERNEL | (ipa_ctx->use_dma_zone ? GFP_DMA : 0);
 
 	mem.base = dma_alloc_coherent(ipa_ctx->pdev, 4, &mem.phys_base,
 		GFP_ATOMIC);
@@ -1856,7 +1857,7 @@ static int ipa_q6_clean_q6_tables(void)
 	}
 
 	cmd = kcalloc(max_cmds, sizeof(struct ipa_hw_imm_cmd_dma_shared_mem),
-		GFP_KERNEL);
+		flag);
 	if (!cmd) {
 		IPAERR("failed to allocate memory\n");
 		retval = -ENOMEM;
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c
index 0196815..80b97e7 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c
@@ -420,15 +420,17 @@ int ipa_send(struct ipa_sys_context *sys, u32 num_desc, struct ipa_desc *desc,
 	int i = 0;
 	int j;
 	int result;
-	int fail_dma_wrap = 0;
 	uint size = num_desc * sizeof(struct sps_iovec);
-	u32 mem_flag = GFP_ATOMIC;
+	gfp_t mem_flag = GFP_ATOMIC;
 	struct sps_iovec iov;
 	int ret;
+	gfp_t flag;
 
 	if (unlikely(!in_atomic))
 		mem_flag = GFP_KERNEL;
 
+	flag = mem_flag | (ipa_ctx->use_dma_zone ? GFP_DMA : 0);
+
 	if (num_desc == IPA_NUM_DESC_PER_SW_TX) {
 		transfer.iovec = dma_pool_alloc(ipa_ctx->dma_pool, mem_flag,
 				&dma_addr);
@@ -437,7 +439,7 @@ int ipa_send(struct ipa_sys_context *sys, u32 num_desc, struct ipa_desc *desc,
 			return -EFAULT;
 		}
 	} else {
-		transfer.iovec = kmalloc(size, mem_flag);
+		transfer.iovec = kmalloc(size, flag);
 		if (!transfer.iovec) {
 			IPAERR("fail to alloc mem for sps xfr buff ");
 			IPAERR("num_desc = %d size = %d\n", num_desc, size);
@@ -457,7 +459,6 @@ int ipa_send(struct ipa_sys_context *sys, u32 num_desc, struct ipa_desc *desc,
 	spin_lock_bh(&sys->spinlock);
 
 	for (i = 0; i < num_desc; i++) {
-		fail_dma_wrap = 0;
 		tx_pkt = kmem_cache_zalloc(ipa_ctx->tx_pkt_wrapper_cache,
 					   mem_flag);
 		if (!tx_pkt) {
@@ -493,15 +494,6 @@ int ipa_send(struct ipa_sys_context *sys, u32 num_desc, struct ipa_desc *desc,
 					tx_pkt->mem.base,
 					tx_pkt->mem.size,
 					DMA_TO_DEVICE);
-
-				if (dma_mapping_error(ipa_ctx->pdev,
-					tx_pkt->mem.phys_base)) {
-					IPAERR("dma_map_single ");
-					IPAERR("failed\n");
-					fail_dma_wrap = 1;
-					goto failure;
-				}
-
 			} else {
 				tx_pkt->mem.phys_base = desc[i].dma_address;
 				tx_pkt->no_unmap_dma = true;
@@ -522,10 +514,9 @@ int ipa_send(struct ipa_sys_context *sys, u32 num_desc, struct ipa_desc *desc,
 			}
 		}
 
-		if (!tx_pkt->mem.phys_base) {
-			IPAERR("failed to alloc tx wrapper\n");
-			fail_dma_wrap = 1;
-			goto failure;
+		if (dma_mapping_error(ipa_ctx->pdev, tx_pkt->mem.phys_base)) {
+			IPAERR("dma_map_single failed\n");
+			goto failure_dma_map;
 		}
 
 		tx_pkt->sys = sys;
@@ -580,27 +571,30 @@ int ipa_send(struct ipa_sys_context *sys, u32 num_desc, struct ipa_desc *desc,
 	spin_unlock_bh(&sys->spinlock);
 	return 0;
 
+failure_dma_map:
+	kmem_cache_free(ipa_ctx->tx_pkt_wrapper_cache, tx_pkt);
+
 failure:
 	tx_pkt = transfer.user;
 	for (j = 0; j < i; j++) {
 		next_pkt = list_next_entry(tx_pkt, link);
 		list_del(&tx_pkt->link);
-		if (desc[j].type != IPA_DATA_DESC_SKB_PAGED) {
-			dma_unmap_single(ipa_ctx->pdev, tx_pkt->mem.phys_base,
-				tx_pkt->mem.size,
-				DMA_TO_DEVICE);
-		} else {
-			dma_unmap_page(ipa_ctx->pdev, tx_pkt->mem.phys_base,
-				tx_pkt->mem.size,
-				DMA_TO_DEVICE);
+		if (!tx_pkt->no_unmap_dma) {
+			if (desc[j].type != IPA_DATA_DESC_SKB_PAGED) {
+				dma_unmap_single(ipa_ctx->pdev,
+					tx_pkt->mem.phys_base,
+					tx_pkt->mem.size,
+					DMA_TO_DEVICE);
+			} else {
+				dma_unmap_page(ipa_ctx->pdev,
+					tx_pkt->mem.phys_base,
+					tx_pkt->mem.size,
+					DMA_TO_DEVICE);
+			}
 		}
 		kmem_cache_free(ipa_ctx->tx_pkt_wrapper_cache, tx_pkt);
 		tx_pkt = next_pkt;
 	}
-	if (j < num_desc)
-		/* last desc failed */
-		if (fail_dma_wrap)
-			kmem_cache_free(ipa_ctx->tx_pkt_wrapper_cache, tx_pkt);
 	if (transfer.iovec_phys) {
 		if (num_desc == IPA_NUM_DESC_PER_SW_TX) {
 			dma_pool_free(ipa_ctx->dma_pool, transfer.iovec,
@@ -1658,6 +1652,7 @@ int ipa2_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
 	struct ipa_sys_context *sys;
 	int src_ep_idx;
 	int num_frags, f;
+	gfp_t flag = GFP_ATOMIC | (ipa_ctx->use_dma_zone ? GFP_DMA : 0);
 
 	if (unlikely(!ipa_ctx)) {
 		IPAERR("IPA driver was not initialized\n");
@@ -1723,7 +1718,7 @@ int ipa2_tx_dp(enum ipa_client_type dst, struct sk_buff *skb,
 
 	if (dst_ep_idx != -1) {
 		/* SW data path */
-		cmd = kzalloc(sizeof(struct ipa_ip_packet_init), GFP_ATOMIC);
+		cmd = kzalloc(sizeof(struct ipa_ip_packet_init), flag);
 		if (!cmd) {
 			IPAERR("failed to alloc immediate command object\n");
 			goto fail_gen;
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
index b60c7a6..3418896 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
@@ -651,6 +651,7 @@ int __ipa_commit_flt_v1_1(enum ipa_ip_type ip)
 	struct ipa_ip_v6_filter_init *v6;
 	u16 avail;
 	u16 size;
+	gfp_t flag = GFP_KERNEL | (ipa_ctx->use_dma_zone ? GFP_DMA : 0);
 
 	mem = kmalloc(sizeof(struct ipa_mem_buffer), GFP_KERNEL);
 	if (!mem) {
@@ -667,7 +668,7 @@ int __ipa_commit_flt_v1_1(enum ipa_ip_type ip)
 			IPA_MEM_PART(v6_flt_size_ddr);
 		size = sizeof(struct ipa_ip_v6_filter_init);
 	}
-	cmd = kmalloc(size, GFP_KERNEL);
+	cmd = kmalloc(size, flag);
 	if (!cmd) {
 		IPAERR("failed to alloc immediate command object\n");
 		goto fail_alloc_cmd;
@@ -840,6 +841,7 @@ int __ipa_commit_flt_v2(enum ipa_ip_type ip)
 	int num_desc = 0;
 	int i;
 	u16 avail;
+	gfp_t flag = GFP_ATOMIC | (ipa_ctx->use_dma_zone ? GFP_DMA : 0);
 
 	desc = kzalloc(16 * sizeof(*desc), GFP_ATOMIC);
 	if (desc == NULL) {
@@ -848,7 +850,7 @@ int __ipa_commit_flt_v2(enum ipa_ip_type ip)
 		goto fail_desc;
 	}
 
-	cmd = kzalloc(16 * sizeof(*cmd), GFP_ATOMIC);
+	cmd = kzalloc(16 * sizeof(*cmd), flag);
 	if (cmd == NULL) {
 		IPAERR("fail to alloc cmd blob ip %d\n", ip);
 		rc = -ENOMEM;
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c
index 046f77f..d657a06 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c
@@ -176,6 +176,7 @@ int __ipa_commit_hdr_v1_1(void)
 	struct ipa_mem_buffer *mem;
 	struct ipa_hdr_init_local *cmd;
 	u16 len;
+	gfp_t flag = GFP_KERNEL | (ipa_ctx->use_dma_zone ? GFP_DMA : 0);
 
 	mem = kmalloc(sizeof(struct ipa_mem_buffer), GFP_KERNEL);
 	if (!mem) {
@@ -190,7 +191,7 @@ int __ipa_commit_hdr_v1_1(void)
 	 * we can use init_local ptr for init_system due to layout of the
 	 * struct
 	 */
-	cmd = kmalloc(len, GFP_KERNEL);
+	cmd = kmalloc(len, flag);
 	if (!cmd) {
 		IPAERR("failed to alloc immediate command object\n");
 		goto fail_alloc_cmd;
@@ -663,6 +664,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
 	struct ipa_hdr_tbl *htbl = &ipa_ctx->hdr_tbl;
 	int id;
 	int mem_size;
+	gfp_t flag = GFP_KERNEL | (ipa_ctx->use_dma_zone ? GFP_DMA : 0);
 
 	if (hdr->hdr_len == 0 || hdr->hdr_len > IPA_HDR_MAX_SIZE) {
 		IPAERR("bad parm\n");
@@ -674,7 +676,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
 		goto error;
 	}
 
-	entry = kmem_cache_zalloc(ipa_ctx->hdr_cache, GFP_KERNEL);
+	entry = kmem_cache_zalloc(ipa_ctx->hdr_cache, flag);
 	if (!entry) {
 		IPAERR("failed to alloc hdr object\n");
 		goto error;
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c
index 96e0125..a7f983e 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -325,6 +325,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init)
 	int result;
 	u32 offset = 0;
 	size_t tmp;
+	gfp_t flag = GFP_KERNEL | (ipa_ctx->use_dma_zone ? GFP_DMA : 0);
 
 	IPADBG("\n");
 	if (init->table_entries == 0) {
@@ -410,7 +411,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init)
 
 	memset(&desc, 0, sizeof(desc));
 	/* NO-OP IC for ensuring that IPA pipeline is empty */
-	reg_write_nop = kzalloc(sizeof(*reg_write_nop), GFP_KERNEL);
+	reg_write_nop = kzalloc(sizeof(*reg_write_nop), flag);
 	if (!reg_write_nop) {
 		IPAERR("no mem\n");
 		result = -ENOMEM;
@@ -428,7 +429,7 @@ int ipa2_nat_init_cmd(struct ipa_ioc_v4_nat_init *init)
 	desc[0].pyld = (void *)reg_write_nop;
 	desc[0].len = sizeof(*reg_write_nop);
 
-	cmd = kmalloc(size, GFP_KERNEL);
+	cmd = kmalloc(size, flag);
 	if (!cmd) {
 		IPAERR("Failed to alloc immediate command object\n");
 		result = -ENOMEM;
@@ -573,6 +574,7 @@ int ipa2_nat_dma_cmd(struct ipa_ioc_nat_dma_cmd *dma)
 	struct ipa_desc *desc = NULL;
 	u16 size = 0, cnt = 0;
 	int ret = 0;
+	gfp_t flag = GFP_KERNEL | (ipa_ctx->use_dma_zone ? GFP_DMA : 0);
 
 	IPADBG("\n");
 	if (dma->entries <= 0) {
@@ -656,7 +658,7 @@ int ipa2_nat_dma_cmd(struct ipa_ioc_nat_dma_cmd *dma)
 	}
 
 	size = sizeof(struct ipa_nat_dma);
-	cmd = kzalloc(size, GFP_KERNEL);
+	cmd = kzalloc(size, flag);
 	if (cmd == NULL) {
 		IPAERR("Failed to alloc memory\n");
 		ret = -ENOMEM;
@@ -664,7 +666,7 @@ int ipa2_nat_dma_cmd(struct ipa_ioc_nat_dma_cmd *dma)
 	}
 
 	/* NO-OP IC for ensuring that IPA pipeline is empty */
-	reg_write_nop = kzalloc(sizeof(*reg_write_nop), GFP_KERNEL);
+	reg_write_nop = kzalloc(sizeof(*reg_write_nop), flag);
 	if (!reg_write_nop) {
 		IPAERR("Failed to alloc memory\n");
 		ret = -ENOMEM;
@@ -758,6 +760,7 @@ int ipa2_nat_del_cmd(struct ipa_ioc_v4_nat_del *del)
 	u8 mem_type = IPA_NAT_SHARED_MEMORY;
 	u32 base_addr = IPA_NAT_PHYS_MEM_OFFSET;
 	int result;
+	gfp_t flag = GFP_KERNEL | (ipa_ctx->use_dma_zone ? GFP_DMA : 0);
 
 	IPADBG("\n");
 	if (ipa_ctx->nat_mem.is_tmp_mem) {
@@ -774,7 +777,7 @@ int ipa2_nat_del_cmd(struct ipa_ioc_v4_nat_del *del)
 
 	memset(&desc, 0, sizeof(desc));
 	/* NO-OP IC for ensuring that IPA pipeline is empty */
-	reg_write_nop = kzalloc(sizeof(*reg_write_nop), GFP_KERNEL);
+	reg_write_nop = kzalloc(sizeof(*reg_write_nop), flag);
 	if (!reg_write_nop) {
 		IPAERR("no mem\n");
 		result = -ENOMEM;
@@ -792,7 +795,7 @@ int ipa2_nat_del_cmd(struct ipa_ioc_v4_nat_del *del)
 	desc[0].pyld = (void *)reg_write_nop;
 	desc[0].len = sizeof(*reg_write_nop);
 
-	cmd = kmalloc(size, GFP_KERNEL);
+	cmd = kmalloc(size, flag);
 	if (cmd == NULL) {
 		IPAERR("Failed to alloc immediate command object\n");
 		result = -ENOMEM;
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
index 21fdec0..5b70853 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
@@ -522,6 +522,7 @@ int __ipa_commit_rt_v1_1(enum ipa_ip_type ip)
 	struct ipa_ip_v6_routing_init *v6;
 	u16 avail;
 	u16 size;
+	gfp_t flag = GFP_KERNEL | (ipa_ctx->use_dma_zone ? GFP_DMA : 0);
 
 	mem = kmalloc(sizeof(struct ipa_mem_buffer), GFP_KERNEL);
 	if (!mem) {
@@ -538,7 +539,7 @@ int __ipa_commit_rt_v1_1(enum ipa_ip_type ip)
 			IPA_MEM_PART(v6_rt_size_ddr);
 		size = sizeof(struct ipa_ip_v6_routing_init);
 	}
-	cmd = kmalloc(size, GFP_KERNEL);
+	cmd = kmalloc(size, flag);
 	if (!cmd) {
 		IPAERR("failed to alloc immediate command object\n");
 		goto fail_alloc_cmd;
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
index da62b77..bec4264 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
@@ -4440,6 +4440,7 @@ int ipa_tag_process(struct ipa_desc desc[],
 	int res;
 	struct ipa_tag_completion *comp;
 	int ep_idx;
+	gfp_t flag = GFP_KERNEL | (ipa_ctx->use_dma_zone ? GFP_DMA : 0);
 
 	/* Not enough room for the required descriptors for the tag process */
 	if (IPA_TAG_MAX_DESC - descs_num < REQUIRED_TAG_PROCESS_DESCRIPTORS) {
@@ -4457,7 +4458,7 @@ int ipa_tag_process(struct ipa_desc desc[],
 	}
 	sys = ipa_ctx->ep[ep_idx].sys;
 
-	tag_desc = kzalloc(sizeof(*tag_desc) * IPA_TAG_MAX_DESC, GFP_KERNEL);
+	tag_desc = kzalloc(sizeof(*tag_desc) * IPA_TAG_MAX_DESC, flag);
 	if (!tag_desc) {
 		IPAERR("failed to allocate memory\n");
 		res = -ENOMEM;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index 23c8241..ab26893 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -1110,7 +1110,7 @@ static const struct ipa_ep_configuration ipa3_ep_mapping
 			true,
 			IPA_DPS_HPS_SEQ_TYPE_DMA_ONLY,
 			QMB_MASTER_SELECT_DDR,
-			{ 0, 1, 8, 16, IPA_EE_AP } },
+			{ 1, 0, 8, 16, IPA_EE_AP } },
 	[IPA_4_0][IPA_CLIENT_ETHERNET_PROD]	  = {
 			true, IPA_v4_0_GROUP_UL_DL,
 			true,
diff --git a/drivers/regulator/rpmh-regulator.c b/drivers/regulator/rpmh-regulator.c
index 2987ed2..4f5f86c 100644
--- a/drivers/regulator/rpmh-regulator.c
+++ b/drivers/regulator/rpmh-regulator.c
@@ -393,10 +393,15 @@ static void rpmh_regulator_handle_arc_enable(struct rpmh_aggr_vreg *aggr_vreg,
 	 * Mask the voltage level if "off" level is supported and the regulator
 	 * has not been enabled.
 	 */
-	if (aggr_vreg->level[0] == RPMH_REGULATOR_LEVEL_OFF &&
-	    (!(req->valid & BIT(RPMH_REGULATOR_REG_ARC_PSEUDO_ENABLE)) ||
-	     !req->reg[RPMH_REGULATOR_REG_ARC_PSEUDO_ENABLE]))
-		req->reg[RPMH_REGULATOR_REG_ARC_LEVEL] = 0;
+	if (aggr_vreg->level[0] == RPMH_REGULATOR_LEVEL_OFF) {
+		if (req->valid & BIT(RPMH_REGULATOR_REG_ARC_PSEUDO_ENABLE)) {
+			if (!req->reg[RPMH_REGULATOR_REG_ARC_PSEUDO_ENABLE])
+				req->reg[RPMH_REGULATOR_REG_ARC_LEVEL] = 0;
+		} else {
+			/* Invalidate voltage level if enable is invalid. */
+			req->valid &= ~BIT(RPMH_REGULATOR_REG_ARC_LEVEL);
+		}
+	}
 
 	/*
 	 * Mark the pseudo enable bit as invalid so that it is not accidentally
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 9a7262e..4c59ca6 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -1,3 +1,4 @@
+KASAN_SANITIZE_scm.o := n
 obj-$(CONFIG_QCOM_CPUSS_DUMP) += cpuss_dump.o
 obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
 obj-$(CONFIG_QCOM_LLCC) += llcc-core.o llcc-slice.o
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index 8aff84c..c252040 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -564,12 +564,12 @@ static struct msm_soc_info cpu_of_id[] = {
 	/* sdm845 ID */
 	[321] = {MSM_CPU_SDM845, "SDM845"},
 
-	/* Bat ID */
-	[328] = {MSM_CPU_SDM830, "SDM830"},
-
 	/* sdxpoorwills ID */
 	[334] = {SDX_CPU_SDXPOORWILLS, "SDXPOORWILLS"},
 
+	/* SDM670 ID */
+	[336] = {MSM_CPU_SDM670, "SDM670"},
+
 	/* Uninitialized IDs are not known to run Linux.
 	 * MSM_CPU_UNKNOWN is set to 0 to ensure these IDs are
 	 * considered as unknown CPU.
@@ -1398,9 +1398,9 @@ static void * __init setup_dummy_socinfo(void)
 		dummy_socinfo.id = 321;
 		strlcpy(dummy_socinfo.build_id, "sdm845 - ",
 			sizeof(dummy_socinfo.build_id));
-	} else if (early_machine_is_sdm830()) {
-		dummy_socinfo.id = 328;
-		strlcpy(dummy_socinfo.build_id, "sdm830 - ",
+	} else if (early_machine_is_sdm670()) {
+		dummy_socinfo.id = 336;
+		strlcpy(dummy_socinfo.build_id, "sdm670 - ",
 			sizeof(dummy_socinfo.build_id));
 	} else if (early_machine_is_sdxpoorwills()) {
 		dummy_socinfo.id = 334;
diff --git a/include/linux/leds-qpnp-flash.h b/include/linux/leds-qpnp-flash.h
index 4b5a339..1fe6e17 100644
--- a/include/linux/leds-qpnp-flash.h
+++ b/include/linux/leds-qpnp-flash.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-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
@@ -18,7 +18,6 @@
 #define ENABLE_REGULATOR	BIT(0)
 #define DISABLE_REGULATOR	BIT(1)
 #define QUERY_MAX_CURRENT	BIT(2)
-#define PRE_FLASH		BIT(3)
 
 #define FLASH_LED_PREPARE_OPTIONS_MASK	GENMASK(3, 0)
 
diff --git a/include/soc/qcom/socinfo.h b/include/soc/qcom/socinfo.h
index b54eefc..dc404e4 100644
--- a/include/soc/qcom/socinfo.h
+++ b/include/soc/qcom/socinfo.h
@@ -100,8 +100,8 @@
 	of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,sdxpoorwills")
 #define early_machine_is_sdm845()	\
 	of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,sdm845")
-#define early_machine_is_sdm830()	\
-	of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,sdm830")
+#define early_machine_is_sdm670()	\
+	of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,sdm670")
 #else
 #define of_board_is_sim()		0
 #define of_board_is_rumi()		0
@@ -141,7 +141,7 @@
 #define early_machine_is_msmfalcon()	0
 #define early_machine_is_sdxpoorwills()	0
 #define early_machine_is_sdm845()	0
-#define early_machine_is_sdm830()	0
+#define early_machine_is_sdm670()	0
 #endif
 
 #define PLATFORM_SUBTYPE_MDM	1
@@ -203,7 +203,7 @@ enum msm_cpu {
 	MSM_CPU_FALCON,
 	SDX_CPU_SDXPOORWILLS,
 	MSM_CPU_SDM845,
-	MSM_CPU_SDM830,
+	MSM_CPU_SDM670,
 };
 
 struct msm_soc_info {
diff --git a/include/uapi/media/cam_req_mgr.h b/include/uapi/media/cam_req_mgr.h
index b736755..e6c1a45 100644
--- a/include/uapi/media/cam_req_mgr.h
+++ b/include/uapi/media/cam_req_mgr.h
@@ -325,4 +325,55 @@ struct cam_mem_cache_ops_cmd {
 	uint32_t mem_cache_ops;
 };
 
+/**
+ * Request Manager : error message type
+ * @CAM_REQ_MGR_ERROR_TYPE_DEVICE: Device error message, fatal to session
+ * @CAM_REQ_MGR_ERROR_TYPE_REQUEST: Error on a single request, not fatal
+ * @CAM_REQ_MGR_ERROR_TYPE_BUFFER: Buffer was not filled, not fatal
+ */
+#define CAM_REQ_MGR_ERROR_TYPE_DEVICE           0
+#define CAM_REQ_MGR_ERROR_TYPE_REQUEST          1
+#define CAM_REQ_MGR_ERROR_TYPE_BUFFER           2
+
+/**
+ * struct cam_req_mgr_error_msg
+ * @error_type: type of error
+ * @request_id: request id of frame
+ * @device_hdl: device handle
+ * @reserved: reserved field
+ * @resource_size: size of the resource
+ */
+struct cam_req_mgr_error_msg {
+	uint32_t error_type;
+	uint32_t request_id;
+	int32_t device_hdl;
+	int32_t reserved;
+	uint64_t resource_size;
+};
+
+/**
+ * struct cam_req_mgr_frame_msg
+ * @request_id: request id of frame
+ * @frame_count: running count of frames
+ * @timestamp: timestamp of frame
+ */
+struct cam_req_mgr_frame_msg {
+	uint64_t request_id;
+	uint64_t frame_count;
+	uint64_t timestamp;
+};
+
+/**
+ * struct cam_req_mgr_message
+ * @session_hdl: session to which the frame belongs to
+ * @reserved: reserved field
+ * @u: union which can either be error or frame message
+ */
+struct cam_req_mgr_message {
+	int32_t session_hdl;
+	union {
+		struct cam_req_mgr_error_msg err_msg;
+		struct cam_req_mgr_frame_msg frame_msg;
+	} u;
+};
 #endif /* __UAPI_LINUX_CAM_REQ_MGR_H */
diff --git a/kernel/sched/core_ctl.c b/kernel/sched/core_ctl.c
index 005d15e..e594804 100644
--- a/kernel/sched/core_ctl.c
+++ b/kernel/sched/core_ctl.c
@@ -44,6 +44,7 @@ struct cluster_data {
 	bool pending;
 	spinlock_t pending_lock;
 	bool is_big_cluster;
+	bool enable;
 	int nrrun;
 	struct task_struct *core_ctl_thread;
 	unsigned int first_cpu;
@@ -247,6 +248,29 @@ static ssize_t show_is_big_cluster(const struct cluster_data *state, char *buf)
 	return snprintf(buf, PAGE_SIZE, "%u\n", state->is_big_cluster);
 }
 
+static ssize_t store_enable(struct cluster_data *state,
+				const char *buf, size_t count)
+{
+	unsigned int val;
+	bool bval;
+
+	if (sscanf(buf, "%u\n", &val) != 1)
+		return -EINVAL;
+
+	bval = !!val;
+	if (bval != state->enable) {
+		state->enable = bval;
+		apply_need(state);
+	}
+
+	return count;
+}
+
+static ssize_t show_enable(const struct cluster_data *state, char *buf)
+{
+	return scnprintf(buf, PAGE_SIZE, "%u\n", state->enable);
+}
+
 static ssize_t show_need_cpus(const struct cluster_data *state, char *buf)
 {
 	return snprintf(buf, PAGE_SIZE, "%u\n", state->need_cpus);
@@ -377,6 +401,7 @@ core_ctl_attr_ro(need_cpus);
 core_ctl_attr_ro(active_cpus);
 core_ctl_attr_ro(global_state);
 core_ctl_attr_rw(not_preferred);
+core_ctl_attr_rw(enable);
 
 static struct attribute *default_attrs[] = {
 	&min_cpus.attr,
@@ -386,6 +411,7 @@ static struct attribute *default_attrs[] = {
 	&busy_down_thres.attr,
 	&task_thres.attr,
 	&is_big_cluster.attr,
+	&enable.attr,
 	&need_cpus.attr,
 	&active_cpus.attr,
 	&global_state.attr,
@@ -529,7 +555,7 @@ static bool eval_need(struct cluster_data *cluster)
 
 	spin_lock_irqsave(&state_lock, flags);
 
-	if (cluster->boost) {
+	if (cluster->boost || !cluster->enable) {
 		need_cpus = cluster->max_cpus;
 	} else {
 		cluster->active_cpus = get_active_cpu_count(cluster);
@@ -1020,6 +1046,7 @@ static int cluster_init(const struct cpumask *mask)
 	cluster->offline_delay_ms = 100;
 	cluster->task_thres = UINT_MAX;
 	cluster->nrrun = cluster->num_cpus;
+	cluster->enable = true;
 	INIT_LIST_HEAD(&cluster->lru);
 	spin_lock_init(&cluster->pending_lock);