Merge e9c5e37030d9e67f0d5260479a4ed2ab0251edf8 on remote branch

Change-Id: I25b67ebf4d8f44cf17f2bde5878dab1a807b2286
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index 534ef89..7acf1f4 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -2152,8 +2152,11 @@
 		should comply with the wsa nodes configurations.
 - qcom,wsa-aux-dev-prefix: This property contains list of wsa codec prefixes.
 - qcom,tdm-i2s-switch-enable: For chipsets where tdm mics are controlled by
-			      switch, drive corresponding gpio to output high
-			      to enable switch.
+			  switch, drive corresponding gpio to output high
+			  to enable switch.
+- qcom,pdm-i2s-switch-enable: For chipsets where pdm mics are controlled by
+			  switch, drive corresponding gpio to output high
+			  to enable switch.
 
 Example:
 	sound {
diff --git a/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts b/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts
index a14ad6f..e1f520d4 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts
+++ b/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts
@@ -19,6 +19,16 @@
 	compatible = "qcom,sa415m-ccard",
 		"qcom,sdxpoorwills", "qcom,ccard";
 	qcom,board-id = <25 1>, <25 0x101>;
+
+	qcom_gadget {
+		compatible = "qcom,usb-gadget";
+		qcom,vid = <0x05c6>;
+
+		composition1 {
+			qcom,pid = <0x9105>;
+			qcom,composition = "diag.diag,gsi.dpl";
+		};
+	};
 };
 
 &usb {
diff --git a/arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts b/arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts
index 29db2d4..cc091b1 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts
+++ b/arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts
@@ -30,11 +30,6 @@
 		};
 
 		composition2 {
-			qcom,pid = <0x9105>;
-			qcom,composition = "diag.diag,gsi.dpl";
-		};
-
-		composition3 {
 			qcom,pid = <0x9107>;
 			qcom,composition = "diag.diag,ipc.ipc,gsi.rmnet.v2x,gsi.ecm,gsi.dpl";
 		};
diff --git a/arch/arm/boot/dts/qcom/sa415m-ccard.dts b/arch/arm/boot/dts/qcom/sa415m-ccard.dts
index a0212fc..65c5761 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ccard.dts
+++ b/arch/arm/boot/dts/qcom/sa415m-ccard.dts
@@ -19,4 +19,14 @@
 	compatible = "qcom,sa415m-ccard",
 		"qcom,sdxpoorwills", "qcom,ccard";
 	qcom,board-id = <25 0>, <25 0x100>;
+
+	qcom_gadget {
+		compatible = "qcom,usb-gadget";
+		qcom,vid = <0x05c6>;
+
+		composition1 {
+			qcom,pid = <0x90dc>;
+			qcom,composition = "diag.diag,cser.dun.0,gsi.rmnet,gsi.dpl,qdss.qdss";
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/qcom/sa415m-ttp-pcie-ep.dts b/arch/arm/boot/dts/qcom/sa415m-ttp-pcie-ep.dts
index 0cbc9e3..619a601 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ttp-pcie-ep.dts
+++ b/arch/arm/boot/dts/qcom/sa415m-ttp-pcie-ep.dts
@@ -20,6 +20,16 @@
 	compatible = "qcom,sa415m-ttp",
 			"qcom,sdxpoorwills", "qcom,ttp";
 	qcom,board-id = <30 0x101>;
+
+	qcom_gadget {
+		compatible = "qcom,usb-gadget";
+		qcom,vid = <0x05c6>;
+
+		composition1 {
+			qcom,pid = <0x9105>;
+			qcom,composition = "diag.diag,gsi.dpl";
+		};
+	};
 };
 
 &mss_mem {
diff --git a/arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts b/arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts
index 7d91330..a907069 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts
+++ b/arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts
@@ -31,11 +31,6 @@
 		};
 
 		composition2 {
-			qcom,pid = <0x9105>;
-			qcom,composition = "diag.diag,gsi.dpl";
-		};
-
-		composition3 {
 			qcom,pid = <0x9107>;
 			qcom,composition = "diag.diag,ipc.ipc,gsi.rmnet.v2x,gsi.ecm,gsi.dpl";
 		};
diff --git a/arch/arm/boot/dts/qcom/sa415m-ttp.dts b/arch/arm/boot/dts/qcom/sa415m-ttp.dts
index d83eb68..578c43c 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ttp.dts
+++ b/arch/arm/boot/dts/qcom/sa415m-ttp.dts
@@ -20,6 +20,16 @@
 	compatible = "qcom,sa415m-ttp",
 		"qcom,sdxpoorwills", "qcom,ttp";
 	qcom,board-id = <30 0x100>;
+
+	qcom_gadget {
+		compatible = "qcom,usb-gadget";
+		qcom,vid = <0x05c6>;
+
+		composition1 {
+			qcom,pid = <0x90dc>;
+			qcom,composition = "diag.diag,cser.dun.0,gsi.rmnet,gsi.dpl,qdss.qdss";
+		};
+	};
 };
 
 &blsp1_uart2b_hs {
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index e9c35d3..57eb1a3 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -1172,7 +1172,7 @@
 		reg-names = "wdt-base";
 		interrupts = <1 3 0>, <1 2 0>;
 		qcom,bark-time = <11000>;
-		qcom,pet-time = <10000>;
+		qcom,pet-time = <9360>;
 	};
 
 	qcom_rng: qrng@793000{
diff --git a/arch/arm/configs/sa415m-perf_defconfig b/arch/arm/configs/sa415m-perf_defconfig
index 192094e..da5078c 100644
--- a/arch/arm/configs/sa415m-perf_defconfig
+++ b/arch/arm/configs/sa415m-perf_defconfig
@@ -230,7 +230,6 @@
 CONFIG_CLD_HL_SDIO_CORE=y
 CONFIG_CLD_LL_CORE=y
 CONFIG_CNSS_UTILS=y
-CONFIG_CNSS_GENL=y
 # CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_KEYBOARD is not set
diff --git a/arch/arm/configs/sa415m_defconfig b/arch/arm/configs/sa415m_defconfig
index 96e21cc..b3f392e 100644
--- a/arch/arm/configs/sa415m_defconfig
+++ b/arch/arm/configs/sa415m_defconfig
@@ -231,7 +231,6 @@
 CONFIG_CLD_HL_SDIO_CORE=y
 CONFIG_CLD_LL_CORE=y
 CONFIG_CNSS_UTILS=y
-CONFIG_CNSS_GENL=y
 # CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_KEYBOARD is not set
diff --git a/arch/arm/configs/sdm429-bg-perf_defconfig b/arch/arm/configs/sdm429-bg-perf_defconfig
index bbb4c4e..db981b6 100644
--- a/arch/arm/configs/sdm429-bg-perf_defconfig
+++ b/arch/arm/configs/sdm429-bg-perf_defconfig
@@ -353,35 +353,9 @@
 CONFIG_MEDIA_CONTROLLER=y
 CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_V4L_PLATFORM_DRIVERS=y
-CONFIG_MSM_CAMERA=y
-CONFIG_MSM_CAMERA_DEBUG=y
-CONFIG_MSMB_CAMERA=y
-CONFIG_MSMB_CAMERA_DEBUG=y
-CONFIG_MSM_CAMERA_SENSOR=y
-CONFIG_MSM_CPP=y
-CONFIG_MSM_CCI=y
-CONFIG_MSM_CSI20_HEADER=y
-CONFIG_MSM_CSI22_HEADER=y
-CONFIG_MSM_CSI30_HEADER=y
-CONFIG_MSM_CSI31_HEADER=y
-CONFIG_MSM_CSIPHY=y
-CONFIG_MSM_CSID=y
-CONFIG_MSM_EEPROM=y
-CONFIG_MSM_ISPIF_V2=y
-CONFIG_IMX134=y
-CONFIG_IMX132=y
-CONFIG_OV9724=y
-CONFIG_OV5648=y
-CONFIG_GC0339=y
-CONFIG_OV8825=y
-CONFIG_OV8865=y
-CONFIG_s5k4e1=y
-CONFIG_OV12830=y
-CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE=y
-CONFIG_MSMB_JPEG=y
-CONFIG_MSM_FD=y
 CONFIG_MSM_VIDC_3X_V4L2=y
 CONFIG_MSM_VIDC_3X_GOVERNORS=y
+CONFIG_ADSP_SHMEM=y
 CONFIG_QCOM_KGSL=y
 CONFIG_FB=y
 CONFIG_FB_VIRTUAL=y
@@ -436,6 +410,8 @@
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_MSM=y
 CONFIG_MMC_SDHCI_MSM_ICE=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_QPNP_HAPTICS=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
@@ -493,7 +469,6 @@
 CONFIG_ICNSS=y
 CONFIG_MSM_PERFORMANCE=y
 CONFIG_MSM_EVENT_TIMER=y
-CONFIG_MSM_AVTIMER=y
 CONFIG_MSM_PM=y
 CONFIG_QCOM_DCC=y
 CONFIG_QTI_RPM_STATS_LOG=y
diff --git a/arch/arm/configs/sdm429-bg_defconfig b/arch/arm/configs/sdm429-bg_defconfig
index 6c345f7..36d92e7 100644
--- a/arch/arm/configs/sdm429-bg_defconfig
+++ b/arch/arm/configs/sdm429-bg_defconfig
@@ -360,35 +360,9 @@
 CONFIG_MEDIA_CONTROLLER=y
 CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_V4L_PLATFORM_DRIVERS=y
-CONFIG_MSM_CAMERA=y
-CONFIG_MSM_CAMERA_DEBUG=y
-CONFIG_MSMB_CAMERA=y
-CONFIG_MSMB_CAMERA_DEBUG=y
-CONFIG_MSM_CAMERA_SENSOR=y
-CONFIG_MSM_CPP=y
-CONFIG_MSM_CCI=y
-CONFIG_MSM_CSI20_HEADER=y
-CONFIG_MSM_CSI22_HEADER=y
-CONFIG_MSM_CSI30_HEADER=y
-CONFIG_MSM_CSI31_HEADER=y
-CONFIG_MSM_CSIPHY=y
-CONFIG_MSM_CSID=y
-CONFIG_MSM_EEPROM=y
-CONFIG_MSM_ISPIF_V2=y
-CONFIG_IMX134=y
-CONFIG_IMX132=y
-CONFIG_OV9724=y
-CONFIG_OV5648=y
-CONFIG_GC0339=y
-CONFIG_OV8825=y
-CONFIG_OV8865=y
-CONFIG_s5k4e1=y
-CONFIG_OV12830=y
-CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE=y
-CONFIG_MSMB_JPEG=y
-CONFIG_MSM_FD=y
 CONFIG_MSM_VIDC_3X_V4L2=y
 CONFIG_MSM_VIDC_3X_GOVERNORS=y
+CONFIG_ADSP_SHMEM=y
 CONFIG_QCOM_KGSL=y
 CONFIG_FB=y
 CONFIG_FB_VIRTUAL=y
@@ -444,6 +418,8 @@
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_MSM=y
 CONFIG_MMC_SDHCI_MSM_ICE=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_QPNP_HAPTICS=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
@@ -507,7 +483,6 @@
 CONFIG_MSM_PIL_MSS_QDSP6V5=y
 CONFIG_MSM_PERFORMANCE=y
 CONFIG_MSM_EVENT_TIMER=y
-CONFIG_MSM_AVTIMER=y
 CONFIG_MSM_PM=y
 CONFIG_QCOM_DCC=y
 CONFIG_QTI_RPM_STATS_LOG=y
diff --git a/arch/arm/mach-qcom/board-sdm429.c b/arch/arm/mach-qcom/board-sdm429.c
index 3638c37..64c1c06 100644
--- a/arch/arm/mach-qcom/board-sdm429.c
+++ b/arch/arm/mach-qcom/board-sdm429.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2018-2020, 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
@@ -19,6 +19,7 @@
 	"qcom,sdm429",
 	"qcom,sda429",
 	"qcom,sdm429w",
+	"qcom,sda429w",
 	NULL
 };
 
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index f6df01c..0dde749 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -401,9 +401,11 @@
 	sda429-spyro-qrd-dvt-overlay.dtbo \
 	sdm429-spyro-qrd-wdp-overlay.dtbo \
 	sdm429-bg-wtp-overlay.dtbo \
+	sdm429-bg-dvt2-wtp-overlay.dtbo \
 	sdm429-bg-wdp-overlay.dtbo \
 	sda429-bg-wdp-overlay.dtbo \
-	sda429-bg-wtp-overlay.dtbo
+	sda429-bg-wtp-overlay.dtbo \
+	sda429-bg-dvt2-wtp-overlay.dtbo
 
 msm8940-mtp-overlay.dtbo-base := msm8940-pmi8950.dtb \
 	msm8940-pmi8937.dtb \
@@ -523,6 +525,8 @@
 sdm429-spyro-qrd-wdp-overlay.dtbo-base := sdm429-spyro-wdp.dtb
 sdm429-bg-wtp-overlay.dtbo-base := sdm429-bg-wtp.dtb
 sda429-bg-wtp-overlay.dtbo-base := sda429-bg-wtp.dtb
+sdm429-bg-dvt2-wtp-overlay.dtbo-base := sdm429-bg-dvt2-wtp.dtb
+sda429-bg-dvt2-wtp-overlay.dtbo-base := sda429-bg-dvt2-wtp.dtb
 sdm429-bg-wdp-overlay.dtbo-base := sdm429-bg-wdp.dtb
 sda429-bg-wdp-overlay.dtbo-base := sda429-bg-wdp.dtb
 else
@@ -608,6 +612,8 @@
 	sdw2500-apq8009w-wtp.dtb \
 	sdw2500-msm8909w-wtp.dtb \
 	msm8905-qrd-skub_qseev4.dtb \
+	msm8905-qrd-skub.dtb \
+	msm8905-qrd-sku3.dtb \
 	msm8909-mtp.dtb \
 	msm8909-1gb-mtp.dtb
 
diff --git a/arch/arm64/boot/dts/qcom/apq8009-robot-som-refboard.dts b/arch/arm64/boot/dts/qcom/apq8009-robot-som-refboard.dts
index 763aa9b..26ce607 100644
--- a/arch/arm64/boot/dts/qcom/apq8009-robot-som-refboard.dts
+++ b/arch/arm64/boot/dts/qcom/apq8009-robot-som-refboard.dts
@@ -59,16 +59,25 @@
 &soc {
 	ext_codec: sound-9335 {
 		compatible = "qcom,apq8009-audio-i2s-codec";
-		qcom,model = "apq8009-tashalite-snd-card-tdm";
 
 		qcom,audio-routing =
 			"AIF4 VI", "MCLK",
 			"RX_BIAS", "MCLK",
 			"MADINPUT", "MCLK",
+			"AMIC2", "MIC BIAS2",
+			"MIC BIAS2", "Headset Mic",
+			"DMIC0", "MIC BIAS1",
+			"MIC BIAS1", "Digital Mic0",
+			"DMIC1", "MIC BIAS1",
+			"MIC BIAS1", "Digital Mic1",
+			"DMIC2", "MIC BIAS3",
+			"MIC BIAS3", "Digital Mic2",
+			"DMIC3", "MIC BIAS3",
+			"MIC BIAS3", "Digital Mic3",
 			"SpkrLeft IN", "SPK1 OUT",
 			"SpkrRight IN", "SPK2 OUT";
 
-		qcom,tdm-i2s-switch-enable = <&msm_gpio 88 0>;
+		qcom,pdm-i2s-switch-enable = <&msm_gpio 88 0>;
 		qcom,pri-mi2s-gpios = <&cdc_pri_mi2s_gpios>;
 		qcom,quat-mi2s-gpios = <&cdc_quat_tdm_gpios>;
 	};
diff --git a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm670.dtsi b/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm670.dtsi
index 5664d3e..ad33fe1 100644
--- a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm670.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018,2020 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -25,7 +25,6 @@
 		#global-interrupts = <2>;
 		qcom,regulator-names = "vdd";
 		vdd-supply = <&gpu_cx_gdsc>;
-		qcom,deferred-regulator-disable-delay = <80>;
 		interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>,
 				<GIC_SPI 231 IRQ_TYPE_LEVEL_HIGH>,
 				<GIC_SPI 364 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/qcom/msm8905-qrd-sku3.dtsi b/arch/arm64/boot/dts/qcom/msm8905-qrd-sku3.dtsi
index e3d390f..467b448 100644
--- a/arch/arm64/boot/dts/qcom/msm8905-qrd-sku3.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8905-qrd-sku3.dtsi
@@ -283,3 +283,12 @@
 	pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>;
 	pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>;
 };
+
+&mdss_dsi {
+	vdda-supply = <&pm8909_l2>;
+	vddio-supply = <&pm8909_l6>;
+	qcom,mdss_dsi_ctrl0@1ac8000 {
+		vdd-supply = <&pm8909_l17>;
+		vddio-supply = <&pm8909_l6>;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8905-qrd-skub.dtsi b/arch/arm64/boot/dts/qcom/msm8905-qrd-skub.dtsi
index f993dbe..8a72765 100644
--- a/arch/arm64/boot/dts/qcom/msm8905-qrd-skub.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8905-qrd-skub.dtsi
@@ -585,3 +585,12 @@
 &pm8909_conga_analog {
 	status = "disabled";
 };
+
+&mdss_dsi {
+	vdda-supply = <&pm8909_l2>;
+	vddio-supply = <&pm8909_l6>;
+	qcom,mdss_dsi_ctrl0@1ac8000 {
+		vdd-supply = <&pm8909_l17>;
+		vddio-supply = <&pm8909_l6>;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-gpu.dtsi b/arch/arm64/boot/dts/qcom/msm8953-gpu.dtsi
index f82b68d..5dc808f 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-gpu.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2018,2020, 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
@@ -76,7 +76,7 @@
 
 		qcom,highest-bank-bit = <14>;
 
-		qcom,snapshot-size = <1048576>; //bytes
+		qcom,snapshot-size = <0x200000>; //bytes
 
 		clocks = <&clock_gcc_gfx clk_gcc_oxili_gfx3d_clk>,
 			<&clock_gcc_gfx clk_gcc_oxili_ahb_clk>,
diff --git a/arch/arm64/boot/dts/qcom/sda429-bg-dvt2-wtp-overlay.dts b/arch/arm64/boot/dts/qcom/sda429-bg-dvt2-wtp-overlay.dts
new file mode 100644
index 0000000..1994c5c
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sda429-bg-dvt2-wtp-overlay.dts
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2019-2020, 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/;
+/plugin/;
+
+#include "sdm429-spyro-qrd-evt.dtsi"
+#include "sdm429-bg-soc.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDA429 BG DVT2 WTP Overlay";
+	compatible = "qcom,sdm429w-qrd", "qcom,sda429w", "qcom,qrd";
+	qcom,msm-id = <437 0x0>;
+	qcom,board-id = <0x00010b 0xA>;
+	qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>;
+};
+
+&mdss_dsi0 {
+	qcom,dsi-pref-prim-pan = <&dsi_auo_416p_amoled_cmd>;
+	/delete-property/ vdd-supply;
+	pinctrl-names = "mdss_default", "mdss_sleep";
+	pinctrl-0 = <&mdss_te_active>;
+	pinctrl-1 = <&mdss_te_suspend>;
+	vddio-supply = <&L11A>;
+	qcom,platform-enable-gpio = <&pm660_gpios 12 0>;
+};
+
+&dsi_pm660_panel_pwr_supply {
+	/delete-node/ qcom,panel-supply-entry@0;
+};
+
+&usb_otg {
+	HSUSB_3p3-supply = <&L16A>;
+};
+
+&msm_dig_codec {
+	cdc-vdd-digital-supply = <&pm660_l11>;
+};
+
+&ext_smart_pa {
+	dvdd-supply = <&pm660_l11>;
+};
+
+&firmware {
+	android {
+		fstab {
+			system {
+				status = "disabled";
+			};
+		};
+	};
+};
+
+&msm_gpu {
+	qcom,initial-pwrlevel = <0>;
+	qcom,gpu-pwrlevels {
+		qcom,gpu-pwrlevel@0 {
+			reg = <0>;
+			qcom,gpu-freq = <320000000>;
+			qcom,bus-freq = <2>;
+			qcom,bus-min = <2>;
+			qcom,bus-max = <2>;
+		};
+		qcom,gpu-pwrlevel@1{
+			reg = <1>;
+			qcom,gpu-freq = <19200000>;
+			qcom,bus-freq = <0>;
+			qcom,bus-min = <0>;
+			qcom,bus-max = <0>;
+		};
+	};
+};
+
+&msm_cpufreq {
+	qcom,cpufreq-table =
+		<  960000 >,
+		< 1305600 >,
+		< 1497600 >,
+		< 1708800 >;
+};
+
+&cpubw {
+	qcom,bw-tbl =
+		<  1611 /*  211.2 MHz */ >,     /*Low SVS*/
+		<  2929 /*  384   MHz */ >,     /* SVS */
+		<  5053 /*  662.4 MHz */ >,     /* SVS+  */
+		<  5712 /*  748.8 MHz */ >;     /* NOM   */
+};
diff --git a/arch/arm64/boot/dts/qcom/sda429-bg-dvt2-wtp.dts b/arch/arm64/boot/dts/qcom/sda429-bg-dvt2-wtp.dts
new file mode 100644
index 0000000..859ca55
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sda429-bg-dvt2-wtp.dts
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2019 - 2020, 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 "sdm429-spyro.dtsi"
+#include "sdm429w-bg-pm660.dtsi"
+#include "sdm429-bg-memory.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDA429 BG DVT2 WTP";
+	compatible = "qcom,sdm429w-qrd", "qcom,sda429w", "qcom,qrd";
+	qcom,msm-id = <437 0x0>;
+	qcom,board-id = <0x00010b 0xA>;
+	qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>;
+};
+
+&msm_gpu {
+	/delete-property/qcom,enable-ca-jump;
+	/delete-property/qcom,ca-busy-penalty;
+	/delete-property/qcom,ca-target-pwrlevel;
+
+	qcom,gpu-pwrlevels {
+		/delete-node/qcom,gpu-pwrlevel@2;
+		/delete-node/qcom,gpu-pwrlevel@3;
+		/delete-node/qcom,gpu-pwrlevel@4;
+		/delete-node/qcom,gpu-pwrlevel@5;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm429-bg-dvt2-wtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm429-bg-dvt2-wtp-overlay.dts
new file mode 100644
index 0000000..b2f9204
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm429-bg-dvt2-wtp-overlay.dts
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2019-2020, 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/;
+/plugin/;
+
+#include "sdm429-spyro-qrd-evt.dtsi"
+#include "sdm429-bg-soc.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM429 BG DVT2 WTP Overlay";
+	compatible = "qcom,sdm429w-qrd", "qcom,sdm429w", "qcom,qrd";
+	qcom,msm-id = <416 0x0>;
+	qcom,board-id = <0x00010b 0xA>;
+	qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>;
+};
+
+&mdss_dsi0 {
+	qcom,dsi-pref-prim-pan = <&dsi_auo_416p_amoled_cmd>;
+	/delete-property/ vdd-supply;
+	vddio-supply = <&L11A>;
+	pinctrl-names = "mdss_default", "mdss_sleep";
+	pinctrl-0 = <&mdss_te_active>;
+	pinctrl-1 = <&mdss_te_suspend>;
+	qcom,platform-enable-gpio = <&pm660_gpios 12 0>;
+};
+
+&dsi_pm660_panel_pwr_supply {
+	/delete-node/ qcom,panel-supply-entry@0;
+};
+
+&usb_otg {
+	HSUSB_3p3-supply = <&L16A>;
+};
+
+&msm_dig_codec {
+	cdc-vdd-digital-supply = <&pm660_l11>;
+};
+
+&ext_smart_pa {
+	dvdd-supply = <&pm660_l11>;
+};
+
+&firmware {
+	android {
+		fstab {
+			system {
+				status = "disabled";
+			};
+		};
+	};
+};
+
+&msm_gpu {
+	qcom,initial-pwrlevel = <0>;
+	qcom,gpu-pwrlevels {
+		qcom,gpu-pwrlevel@0 {
+			reg = <0>;
+			qcom,gpu-freq = <320000000>;
+			qcom,bus-freq = <2>;
+			qcom,bus-min = <2>;
+			qcom,bus-max = <2>;
+		};
+		qcom,gpu-pwrlevel@1{
+			reg = <1>;
+			qcom,gpu-freq = <19200000>;
+			qcom,bus-freq = <0>;
+			qcom,bus-min = <0>;
+			qcom,bus-max = <0>;
+		};
+	};
+};
+
+&msm_cpufreq {
+	qcom,cpufreq-table =
+		<  960000 >,
+		< 1305600 >,
+		< 1497600 >,
+		< 1708800 >;
+};
+&cpubw {
+	qcom,bw-tbl =
+		<  1611 /*  211.2 MHz */ >,     /*Low SVS*/
+		<  2929 /*  384   MHz */ >,     /* SVS */
+		<  5053 /*  662.4 MHz */ >,     /* SVS+  */
+		<  5712 /*  748.8 MHz */ >;     /* NOM   */
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm429-bg-dvt2-wtp.dts b/arch/arm64/boot/dts/qcom/sdm429-bg-dvt2-wtp.dts
new file mode 100644
index 0000000..894986f
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm429-bg-dvt2-wtp.dts
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2019 - 2020, 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 "sdm429-spyro.dtsi"
+#include "sdm429w-bg-pm660.dtsi"
+#include "sdm429-bg-memory.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM429 BG DVT2 WTP";
+	compatible = "qcom,sdm429w-qrd", "qcom,sdm429w", "qcom,qrd";
+	qcom,msm-id = <416 0x0>;
+	qcom,board-id = <0x00010b 0xA>;
+	qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>;
+};
+
+&msm_gpu {
+	/delete-property/qcom,enable-ca-jump;
+	/delete-property/qcom,ca-busy-penalty;
+	/delete-property/qcom,ca-target-pwrlevel;
+
+	qcom,gpu-pwrlevels {
+		/delete-node/qcom,gpu-pwrlevel@2;
+		/delete-node/qcom,gpu-pwrlevel@3;
+		/delete-node/qcom,gpu-pwrlevel@4;
+		/delete-node/qcom,gpu-pwrlevel@5;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm429-bg-iot-wtp.dts b/arch/arm64/boot/dts/qcom/sdm429-bg-iot-wtp.dts
index 70bc00a..b91f161 100644
--- a/arch/arm64/boot/dts/qcom/sdm429-bg-iot-wtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm429-bg-iot-wtp.dts
@@ -22,7 +22,8 @@
 	model = "Qualcomm Technologies, Inc. SDM429 BG IOT WTP";
 	compatible = "qcom,sdm429w-qrd", "qcom,sdm429w", "qcom,qrd";
 	qcom,msm-id = <416 0x0>;
-	qcom,board-id = <0x00010b 8>;
+	qcom,board-id = <0x00010b 8>,
+			<0x00010b 0xA>;
 	qcom,pmic-id = <0x0002001b 0x0 0x0 0x0>;
 };
 
diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi
index 567389a..1f25e56 100644
--- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-evt.dtsi
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, 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
@@ -486,6 +486,7 @@
 		polling-delay = <0>;
 		thermal-governor = "low_limits_floor";
 		thermal-sensors = <&tsens0 0>;
+		wake-capable-sensor;
 		tracks-low;
 
 		trips {
@@ -520,6 +521,7 @@
 		polling-delay = <0>;
 		thermal-governor = "low_limits_floor";
 		thermal-sensors = <&tsens0 1>;
+		wake-capable-sensor;
 		tracks-low;
 
 		trips {
@@ -554,6 +556,7 @@
 		polling-delay = <0>;
 		thermal-governor = "low_limits_floor";
 		thermal-sensors = <&tsens0 2>;
+		wake-capable-sensor;
 		tracks-low;
 
 		trips {
@@ -588,6 +591,7 @@
 		polling-delay = <0>;
 		thermal-governor = "low_limits_floor";
 		thermal-sensors = <&tsens0 3>;
+		wake-capable-sensor;
 		tracks-low;
 
 		trips {
@@ -622,6 +626,7 @@
 		polling-delay = <0>;
 		thermal-governor = "low_limits_floor";
 		thermal-sensors = <&tsens0 4>;
+		wake-capable-sensor;
 		tracks-low;
 
 		trips {
@@ -656,6 +661,7 @@
 		polling-delay = <0>;
 		thermal-governor = "low_limits_floor";
 		thermal-sensors = <&tsens0 5>;
+		wake-capable-sensor;
 		tracks-low;
 
 		trips {
@@ -690,6 +696,7 @@
 		polling-delay = <0>;
 		thermal-governor = "low_limits_floor";
 		thermal-sensors = <&tsens0 6>;
+		wake-capable-sensor;
 		tracks-low;
 
 		trips {
@@ -724,6 +731,7 @@
 		polling-delay = <0>;
 		thermal-governor = "low_limits_floor";
 		thermal-sensors = <&tsens0 7>;
+		wake-capable-sensor;
 		tracks-low;
 
 		trips {
@@ -758,6 +766,7 @@
 		polling-delay = <0>;
 		thermal-governor = "low_limits_floor";
 		thermal-sensors = <&tsens0 8>;
+		wake-capable-sensor;
 		tracks-low;
 
 		trips {
@@ -792,6 +801,7 @@
 		polling-delay = <0>;
 		thermal-governor = "low_limits_floor";
 		thermal-sensors = <&tsens0 9>;
+		wake-capable-sensor;
 		tracks-low;
 
 		trips {
@@ -826,6 +836,7 @@
 		polling-delay = <0>;
 		thermal-governor = "low_limits_floor";
 		thermal-sensors = <&tsens0 10>;
+		wake-capable-sensor;
 		tracks-low;
 
 		trips {
@@ -892,6 +903,7 @@
 		polling-delay = <0>;
 		thermal-sensors = <&pm660_adc_tm 0x51>;
 		thermal-governor = "step_wise";
+		wake-capable-sensor;
 
 		trips {
 			quiet_batt_439_trip1: quiet-batt-trip1 {
diff --git a/arch/arm64/boot/dts/qcom/sxr1130-svr.dtsi b/arch/arm64/boot/dts/qcom/sxr1130-svr.dtsi
index 40aceac..4dfa320 100644
--- a/arch/arm64/boot/dts/qcom/sxr1130-svr.dtsi
+++ b/arch/arm64/boot/dts/qcom/sxr1130-svr.dtsi
@@ -518,3 +518,13 @@
 &cdc_pdm_gpios {
 	status = "disabled";
 };
+
+&lcdb_ldo_vreg {
+	regulator-min-microvolt = <5700000>;
+	regulator-max-microvolt = <5700000>;
+};
+
+&lcdb_ncp_vreg {
+	regulator-min-microvolt = <5700000>;
+	regulator-max-microvolt = <5700000>;
+};
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 9033c23..a0652b7 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -3484,11 +3484,8 @@
 static int fastrpc_device_open(struct inode *inode, struct file *filp)
 {
 	int err = 0;
-	struct dentry *debugfs_file;
 	struct fastrpc_file *fl = NULL;
 	struct fastrpc_apps *me = &gfa;
-	char strpid[PID_SIZE];
-	int buf_size = 0;
 
 	/*
 	 * Indicates the device node opened
@@ -3506,13 +3503,6 @@
 	VERIFY(err, NULL != (fl = kzalloc(sizeof(*fl), GFP_KERNEL)));
 	if (err)
 		return err;
-	snprintf(strpid, PID_SIZE, "%d", current->pid);
-	buf_size = strlen(current->comm) + strlen("_") + strlen(strpid) + 1;
-	fl->debug_buf = kzalloc(buf_size, GFP_KERNEL);
-	snprintf(fl->debug_buf, UL_SIZE, "%.10s%s%d",
-	current->comm, "_", current->pid);
-	debugfs_file = debugfs_create_file(fl->debug_buf, 0644,
-	debugfs_root, fl, &debugfs_fops);
 
 	context_list_ctor(&fl->clst);
 	spin_lock_init(&fl->hlock);
@@ -3522,14 +3512,11 @@
 	INIT_HLIST_HEAD(&fl->remote_bufs);
 	INIT_HLIST_NODE(&fl->hn);
 	fl->sessionid = 0;
-	fl->tgid = current->tgid;
 	fl->apps = me;
 	fl->mode = FASTRPC_MODE_SERIAL;
 	fl->cid = -1;
 	fl->dev_minor = dev_minor;
 	fl->init_mem = NULL;
-	if (debugfs_file != NULL)
-		fl->debugfs_file = debugfs_file;
 	fl->qos_request = 0;
 	fl->refcount = 0;
 	filp->private_data = fl;
@@ -3542,6 +3529,29 @@
 	return 0;
 }
 
+static int fastrpc_set_process_info(struct fastrpc_file *fl)
+{
+	int err = 0, buf_size = 0;
+	char strpid[PID_SIZE];
+
+	fl->tgid = current->tgid;
+	snprintf(strpid, PID_SIZE, "%d", current->pid);
+	buf_size = strlen(current->comm) + strlen("_") + strlen(strpid) + 1;
+	fl->debug_buf = kzalloc(buf_size, GFP_KERNEL);
+	if (!fl->debug_buf) {
+		err = -ENOMEM;
+		return err;
+	}
+	snprintf(fl->debug_buf, UL_SIZE, "%.10s%s%d",
+			current->comm, "_", current->pid);
+	fl->debugfs_file = debugfs_create_file(fl->debug_buf, 0644,
+					debugfs_root, fl, &debugfs_fops);
+	if (!fl->debugfs_file)
+		pr_warn("Error: %s: %s: failed to create debugfs file %s\n",
+				current->comm, __func__, fl->debug_buf);
+	return err;
+}
+
 static int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info)
 {
 	int err = 0;
@@ -3550,6 +3560,9 @@
 	VERIFY(err, fl != NULL);
 	if (err)
 		goto bail;
+	err = fastrpc_set_process_info(fl);
+	if (err)
+		goto bail;
 	if (fl->cid == -1) {
 		cid = *info;
 		VERIFY(err, cid < NUM_CHANNELS);
diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c
index 514c0ad..8d07b3c 100644
--- a/drivers/clk/qcom/clk-alpha-pll.c
+++ b/drivers/clk/qcom/clk-alpha-pll.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017, 2020, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -554,7 +554,7 @@
 	pll->inited = true;
 }
 
-static int clk_fabia_pll_enable(struct clk_hw *hw)
+static int pll_is_enabled(struct clk_hw *hw, u32 mask)
 {
 	int ret;
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
@@ -564,6 +564,24 @@
 	if (ret)
 		return ret;
 
+	return !!(val & mask);
+}
+
+static int clk_alpha_pll_is_enabled(struct clk_hw *hw)
+{
+	return pll_is_enabled(hw, PLL_LOCK_DET);
+}
+
+static int clk_fabia_pll_enable(struct clk_hw *hw)
+{
+	int ret;
+	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+	u32 val, opmode_val, off = pll->offset;
+
+	ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
+	if (ret)
+		return ret;
+
 	/* If in FSM mode, just vote for it */
 	if (val & PLL_VOTE_FSM_ENA) {
 		ret = clk_enable_regmap(hw);
@@ -572,6 +590,14 @@
 		return wait_for_pll_enable(pll, PLL_ACTIVE_FLAG);
 	}
 
+	ret = regmap_read(pll->clkr.regmap, off + FABIA_OPMODE, &opmode_val);
+	if (ret)
+		return ret;
+
+	/* Skip If PLL is already running */
+	if ((opmode_val & PLL_RUN) && (val & PLL_OUTCTRL))
+		return 0;
+
 	if (unlikely(!pll->inited))
 		clk_fabia_pll_configure(pll, pll->clkr.regmap, pll->config);
 
@@ -751,6 +777,7 @@
 const struct clk_ops clk_fabia_pll_ops = {
 	.enable = clk_fabia_pll_enable,
 	.disable = clk_fabia_pll_disable,
+	.is_enabled = clk_alpha_pll_is_enabled,
 	.recalc_rate = clk_fabia_pll_recalc_rate,
 	.round_rate = clk_alpha_pll_round_rate,
 	.set_rate = clk_fabia_pll_set_rate,
@@ -761,6 +788,7 @@
 const struct clk_ops clk_fabia_fixed_pll_ops = {
 	.enable = clk_fabia_pll_enable,
 	.disable = clk_fabia_pll_disable,
+	.is_enabled = clk_alpha_pll_is_enabled,
 	.recalc_rate = clk_fabia_pll_recalc_rate,
 	.round_rate = clk_alpha_pll_round_rate,
 	.list_registers = clk_fabia_pll_list_registers,
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 1d2361b..f603a3f 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -1,5 +1,7 @@
 /*
- * Copyright (c) 2013, 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016-2018, 2020,
+ *
+ * The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -248,6 +250,7 @@
 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 	const struct freq_tbl *f_curr;
 	u32 cfg, hid_div, m = 0, n = 0, mode = 0, mask;
+	unsigned long recalc_rate;
 
 	if (rcg->flags & DFS_ENABLE_RCG)
 		return rcg->current_freq;
@@ -285,7 +288,16 @@
 		hid_div &= mask;
 	}
 
-	return clk_rcg2_calc_rate(parent_rate, m, n, mode, hid_div);
+	recalc_rate = clk_rcg2_calc_rate(parent_rate, m, n, mode, hid_div);
+
+	/*
+	 * Check the case when the RCG has been initialized to a non-CXO
+	 * frequency.
+	 */
+	if (rcg->enable_safe_config && !rcg->current_freq)
+		rcg->current_freq = recalc_rate;
+
+	return recalc_rate;
 }
 
 static int _freq_tbl_determine_rate(struct clk_hw *hw,
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index 1ef5382..e80523b 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -1,7 +1,7 @@
 /*
  * QTI Crypto Engine driver.
  *
- * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2020, 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
@@ -4680,7 +4680,7 @@
 			pce_dev->intr_cadence = 0;
 			atomic_set(&pce_dev->bunch_cmd_seq, 0);
 			atomic_set(&pce_dev->last_intr_seq, 0);
-			pce_dev->cadence_flag = ~pce_dev->cadence_flag;
+			pce_dev->cadence_flag = !pce_dev->cadence_flag;
 		}
 	}
 
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index a9ec5954..d410562 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -1808,10 +1808,11 @@
 				handle->sha_ctxt.diglen);
 		mutex_unlock(&hash_access_lock);
 		if (copy_to_user((void __user *)arg, &qcedev_areq->sha_op_req,
-					sizeof(struct qcedev_sha_op_req)))
+					sizeof(struct qcedev_sha_op_req))) {
 			err = -EFAULT;
 			goto exit_free_qcedev_areq;
 		}
+		}
 		break;
 
 	case QCEDEV_IOCTL_SHA_FINAL_REQ:
@@ -1900,10 +1901,11 @@
 				handle->sha_ctxt.diglen);
 		mutex_unlock(&hash_access_lock);
 		if (copy_to_user((void __user *)arg, &qcedev_areq->sha_op_req,
-					sizeof(struct qcedev_sha_op_req)))
+					sizeof(struct qcedev_sha_op_req))) {
 			err = -EFAULT;
 			goto exit_free_qcedev_areq;
 		}
+		}
 		break;
 
 	case QCEDEV_IOCTL_MAP_BUF_REQ:
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index 76e0e25..a499b2c 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2020, 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
@@ -1296,6 +1296,11 @@
 	if (size == 0)
 		goto done;
 
+	if (size > device->snapshot_memory.size) {
+		SNAPSHOT_ERR_NOMEM(device, "OBJS");
+		goto done;
+	}
+
 	snapshot->mempool = vmalloc(size);
 
 	ptr = snapshot->mempool;
diff --git a/drivers/iio/imu/st_asm330lhh/st_asm330lhh_buffer.c b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_buffer.c
index b8b3eff..623d434 100644
--- a/drivers/iio/imu/st_asm330lhh/st_asm330lhh_buffer.c
+++ b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_buffer.c
@@ -332,10 +332,10 @@
 				}
 				memcpy(iio_buf, ptr, ST_ASM330LHH_SAMPLE_SIZE);
 
-				hw->tsample = min_t(s64,
-						    hw->ts,
-						    hw->tsample);
-
+				if ((i + (3*ST_ASM330LHH_FIFO_SAMPLE_SIZE)) >
+						word_len) {
+					hw->tsample = hw->ts;
+				}
 				iio_push_to_buffers_with_timestamp(iio_dev,
 								   iio_buf,
 								   hw->tsample);
@@ -538,6 +538,8 @@
 	bool irq_active_low;
 	int i, err;
 
+	if (!irq_get_irq_data(hw->irq))
+		return -EINVAL;
 	irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
 	if (irq_type == IRQF_TRIGGER_NONE)
 		irq_type = IRQF_TRIGGER_HIGH;
diff --git a/drivers/input/misc/qti-haptics.c b/drivers/input/misc/qti-haptics.c
index 27ce7cf..a2c8e76 100644
--- a/drivers/input/misc/qti-haptics.c
+++ b/drivers/input/misc/qti-haptics.c
@@ -254,6 +254,11 @@
 static int wf_repeat[8] = {1, 2, 4, 8, 16, 32, 64, 128};
 static int wf_s_repeat[4] = {1, 2, 4, 8};
 
+static int twm_sys_enable;
+module_param_named(
+	haptics_twm, twm_sys_enable, int, 0600
+);
+
 static inline bool is_secure(u8 addr)
 {
 	return ((addr & 0xFF) > 0xD0);
@@ -2028,6 +2033,7 @@
 {
 	struct qti_hap_chip *chip = dev_get_drvdata(&pdev->dev);
 	int rc;
+	bool enable_haptics_twm;
 
 	dev_dbg(chip->dev, "Shutdown!\n");
 
@@ -2043,7 +2049,9 @@
 		chip->vdd_enabled = false;
 	}
 
-	if (chip->twm_state == PMIC_TWM_ENABLE && chip->haptics_ext_pin_twm) {
+	enable_haptics_twm = chip->haptics_ext_pin_twm && twm_sys_enable;
+
+	if (chip->twm_state == PMIC_TWM_ENABLE && enable_haptics_twm) {
 		rc = qti_haptics_twm_config(chip);
 		if (rc < 0)
 			pr_err("Haptics TWM config failed rc=%d\n", rc);
diff --git a/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c b/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c
index f501b5c..cd78249 100644
--- a/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c
+++ b/drivers/input/touchscreen/cyttsp5/cyttsp5_device_access.c
@@ -1835,15 +1835,15 @@
 	 */
 	if (test_item > 0 && test_item < 5)
 		range_check = 0;
-		dad->cmcp_test_items = test_item;
-		dad->cmcp_range_check = range_check;
-		dad->cmcp_force_calibrate = force_calibrate;
-		parade_debug(dev, DEBUG_LEVEL_2,
-			"%s: Item: %s, Range check: %s, Force calibrate: %s.\n",
-			__func__,
-			cmcp_test_case_array[test_item],
-			cmcp_test_range_check_array[range_check],
-			cmcp_test_force_cal_array[force_calibrate]);
+	dad->cmcp_test_items = test_item;
+	dad->cmcp_range_check = range_check;
+	dad->cmcp_force_calibrate = force_calibrate;
+	parade_debug(dev, DEBUG_LEVEL_2,
+		"%s: Item: %s, Range check: %s, Force calibrate: %s.\n",
+		__func__,
+		cmcp_test_case_array[test_item],
+		cmcp_test_range_check_array[range_check],
+		cmcp_test_force_cal_array[force_calibrate]);
 
 error:
 	mutex_unlock(&dad->sysfs_lock);
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c
index 78dd64c..3c4d6df 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020, 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
@@ -196,11 +196,12 @@
 	if (rc)
 		CAM_ERR(CAM_ISP, "CPAS0 unregistration failed rc=%d", rc);
 
-	if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120)
+	if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120) {
 		rc = cam_cpas_unregister_client(soc_private->cpas_handle[1]);
 		if (rc)
 			CAM_ERR(CAM_ISP, "CPAS1 unregistration failed rc=%d",
 				rc);
+	}
 
 	rc = cam_vfe_release_platform_resource(soc_info);
 	if (rc < 0)
@@ -245,7 +246,7 @@
 		goto end;
 	}
 
-	if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120)
+	if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120) {
 		rc = cam_cpas_start(soc_private->cpas_handle[1], &ahb_vote,
 			&axi_vote);
 		if (rc) {
@@ -253,6 +254,7 @@
 			rc = -EFAULT;
 			goto end;
 		}
+	}
 
 	rc = cam_soc_util_enable_platform_resource(soc_info, true,
 		CAM_TURBO_VOTE, true);
@@ -344,12 +346,13 @@
 		return rc;
 	}
 
-	if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120)
+	if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120) {
 		rc = cam_cpas_stop(soc_private->cpas_handle[1]);
 		if (rc) {
 			CAM_ERR(CAM_ISP, "Error! CPAS stop failed rc=%d", rc);
 			return rc;
 		}
+	}
 
 	return rc;
 }
diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c
index 185e060..e9998a7 100644
--- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c
+++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2020, 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
@@ -450,13 +450,13 @@
 		break;
 	case CAM_FORMAT_NV21:
 	case CAM_FORMAT_NV12:
-	if (plane_index < CAM_PACKET_MAX_PLANES)
-		kmd_plane_size = plane_stride * slice_height;
+		if (plane_index < CAM_PACKET_MAX_PLANES)
+			kmd_plane_size = plane_stride * slice_height;
 		break;
 	case CAM_FORMAT_PD10:
-	if (plane_index < CAM_PACKET_MAX_PLANES)
-		kmd_plane_size = plane_stride * slice_height;
-	break;
+		if (plane_index < CAM_PACKET_MAX_PLANES)
+			kmd_plane_size = plane_stride * slice_height;
+		break;
 	case CAM_FORMAT_UBWC_NV12:
 	case CAM_FORMAT_UBWC_NV12_4R:
 	case CAM_FORMAT_UBWC_TP10:
diff --git a/drivers/misc/qcom-xr-smrtvwr-misc.c b/drivers/misc/qcom-xr-smrtvwr-misc.c
index fc8796f..fe3cdc8 100644
--- a/drivers/misc/qcom-xr-smrtvwr-misc.c
+++ b/drivers/misc/qcom-xr-smrtvwr-misc.c
@@ -32,7 +32,6 @@
 	struct regulator *reg1, *reg2, *reg3;
 	int dp3p3_en_gpio = 142;
 	int wcd_en_gpio = 93;
-	int switch_gpio = 112;
 	int rgb_tck_oe_en_gpio = 108;
 
 	reg1 = devm_regulator_get(&pdev->dev, "pm660l_l6");
@@ -91,19 +90,6 @@
 	gpio_set_value(wcd_en_gpio, 1);
 	msleep(20);
 
-	rc = gpio_request(switch_gpio, "1p8_en_gpio");
-	if (rc) {
-		pr_err("%s 1p8_switch_gpio request failed\n", __func__);
-		goto gpio_switch_fail;
-	}
-	rc = gpio_direction_output(switch_gpio, 0);
-	if (rc) {
-		pr_err("%s 1p8_switch_gpio direction failed\n", __func__);
-		goto gpio_switch_fail;
-	}
-	gpio_set_value(switch_gpio, 1);
-	msleep(20);
-
 	rc = gpio_request(rgb_tck_oe_en_gpio, "rgb_tck_oe_en_gpio");
 	if (rc) {
 		pr_err("%s rgb_tck_oe_en_gpio request failed\n", __func__);
@@ -122,8 +108,6 @@
 
 gpio_oe_en_fail:
 	gpio_free(rgb_tck_oe_en_gpio);
-gpio_switch_fail:
-	gpio_free(switch_gpio);
 gpiowcd_fail:
 	gpio_free(wcd_en_gpio);
 gpio3p3_fail:
diff --git a/drivers/misc/tusb1064.c b/drivers/misc/tusb1064.c
index 234e21a..b9f40e9 100644
--- a/drivers/misc/tusb1064.c
+++ b/drivers/misc/tusb1064.c
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/gpio.h>
 #include <linux/delay.h>
+#include "tusb1064.h"
 
 struct tusb1064 {
 	struct device *dev;
@@ -80,21 +81,23 @@
 	return 0;
 }
 
-void tusb1064_flip(bool flip)
+void tusb1064_usb_event(bool flip)
 {
 	if (pdata) {
 		if (flip) {
-			pr_debug("%s flipping the switch\n", __func__);
-			/*AUXn->SBU2, AUXp->SBU1*/
-			tusb1064_write(pdata->i2c_client, 0x13, 0x2F);
+			if (standalone_mode)
+				tusb1064_write(pdata->i2c_client, 0x0A, 0x05);
+			else
+				tusb1064_write(pdata->i2c_client, 0x0A, 0x06);
 		} else {
-			pr_debug("%s not flipping the switch\n", __func__);
-			/*AUXn->SBU2, AUXp->SBU1*/
-			tusb1064_write(pdata->i2c_client, 0x13, 0x1F);
+			if (standalone_mode)
+				tusb1064_write(pdata->i2c_client, 0x0A, 0x01);
+			else
+				tusb1064_write(pdata->i2c_client, 0x0A, 0x02);
 		}
 	}
 }
-EXPORT_SYMBOL(tusb1064_flip);
+EXPORT_SYMBOL(tusb1064_usb_event);
 
 static int tusb1064_probe(struct i2c_client *client,
 	const struct i2c_device_id *id)
@@ -140,19 +143,6 @@
 			goto fail;
 
 		pr_debug("%s setting SBU1 to AUXN, SBU2 to AUXP\n", __func__);
-		/*AUXn->SBU2, AUXp->SBU1 */
-		if (tusb1064_write(pdata->i2c_client, 0x13, 0x1F) < 0)
-			goto fail;
-		//tusb1064_write(pdata, 0x13, 0x01);//AUXn->SBU1, AUXp->SBU2
-
-		/*Enable 4-lane DP */
-		if (tusb1064_write(pdata->i2c_client, 0x10, 0x55) < 0)
-			goto fail;
-		/*Enable 4-lane DP */
-		if (tusb1064_write(pdata->i2c_client, 0x11, 0x55) < 0)
-			goto fail;
-		//pr_err("setting SBU1 to AUXp and SBU2 to AUXN\n");
-		//tusb1064_write(pdata, 0x13, 0x8F);//Enable 4-lane DP
 	}
 	tusb1064_read(pdata->i2c_client, 0x0A, buf, 2);
 	tusb1064_read(pdata->i2c_client, 0x13, buf, 2);
diff --git a/drivers/misc/tusb1064.h b/drivers/misc/tusb1064.h
new file mode 100644
index 0000000..effecdc
--- /dev/null
+++ b/drivers/misc/tusb1064.h
@@ -0,0 +1,18 @@
+/* Copyright (c) 2020 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.
+ */
+
+#ifndef __TUSB1064_H_
+#define __TUSB1064_H_
+
+void tusb1064_usb_event(bool flip);
+
+#endif /* __TUSB1064_H_ */
diff --git a/drivers/misc/vxr7200.c b/drivers/misc/vxr7200.c
index ad1c82c..7388ade 100644
--- a/drivers/misc/vxr7200.c
+++ b/drivers/misc/vxr7200.c
@@ -41,10 +41,8 @@
 	u32 led_drive_en1;
 	u32 led_drive_en2;
 	u32 display_1v8_en;
-	u32 mipi_sw_1v8_en;
+	u32 mipi_switch_1v8_en;
 	u32 display_res1;
-	u32 selab_gpio;
-	u32 oenab_gpio;
 	bool gpioInit;
 
 	struct i2c_client *i2c_client;
@@ -104,6 +102,7 @@
 			goto error;
 		}
 		gpio_set_value(gpio, 1);
+		msleep(20);
 		pr_debug("%s vxr7200 gpio:%d set to high\n", __func__, gpio);
 	} else {
 		ret = gpio_direction_output(gpio, 1);
@@ -112,6 +111,7 @@
 			goto error;
 		}
 		gpio_set_value(gpio, 0);
+		msleep(20);
 		pr_debug("%s vxr7200 gpio:%d set to low\n", __func__, gpio);
 	}
 	return 0;
@@ -128,62 +128,54 @@
 		rc = turnGpio(pdata, pdata->vxr_3v3_en, "vxr_3v3_en", turnOn);
 		if (rc)
 			goto gpio1Fail;
-		rc = turnGpio(pdata, pdata->led_5v_en, "led_5v_en", turnOn);
-		if (rc)
-			goto gpio2Fail;
-		rc = turnGpio(pdata, pdata->led_drive_en1,
-					"led_drive_en1", turnOn);
-		if (rc)
-			goto gpio3Fail;
-		rc = turnGpio(pdata, pdata->led_drive_en2,
-					 "led_drive_en2", turnOn);
-		if (rc)
-			goto gpio4Fail;
-		rc = turnGpio(pdata, pdata->display_1v8_en,
-					 "disp_1v8_en", turnOn);
-		if (rc)
-			goto gpio5Fail;
-		pdata->mipi_sw_1v8_en += 1100;
-		rc = turnGpio(pdata, pdata->mipi_sw_1v8_en,
-						 "mipi_sw1v8_en", turnOn);
-		if (rc)
-			goto gpio6Fail;
+
 		rc = turnGpio(pdata, pdata->display_res1,
 						 "display_res1", turnOn);
 		if (rc)
+			goto gpio2Fail;
+
+		rc = turnGpio(pdata, pdata->display_1v8_en,
+					 "disp_1v8_en", turnOn);
+		if (rc)
+			goto gpio3Fail;
+
+		rc = turnGpio(pdata, pdata->mipi_switch_1v8_en,
+						 "mipi_switch_1v8_en", turnOn);
+		if (rc)
+			goto gpio4Fail;
+
+		rc = turnGpio(pdata, pdata->led_5v_en, "led_5v_en", turnOn);
+		if (rc)
+			goto gpio5Fail;
+
+		rc = turnGpio(pdata, pdata->led_drive_en1,
+					"led_drive_en1", turnOn);
+		if (rc)
+			goto gpio6Fail;
+
+		rc = turnGpio(pdata, pdata->led_drive_en2,
+					 "led_drive_en2", turnOn);
+		if (rc)
 			goto gpio7Fail;
 	}
+	return;
 
 gpio7Fail:
-	gpio_free(pdata->display_res1);
-gpio6Fail:
-	gpio_free(pdata->mipi_sw_1v8_en);
-gpio5Fail:
-	gpio_free(pdata->display_1v8_en);
-gpio4Fail:
 	gpio_free(pdata->led_drive_en2);
-gpio3Fail:
+gpio6Fail:
 	gpio_free(pdata->led_drive_en1);
-gpio2Fail:
+gpio5Fail:
 	gpio_free(pdata->led_5v_en);
+gpio4Fail:
+	gpio_free(pdata->mipi_switch_1v8_en);
+gpio3Fail:
+	gpio_free(pdata->display_1v8_en);
+gpio2Fail:
+	gpio_free(pdata->display_res1);
 gpio1Fail:
 	gpio_free(pdata->vxr_3v3_en);
 }
 
-static void vxr7200_free_gpios(struct vxr7200 *pdata)
-{
-	if (pdata) {
-		gpio_free(pdata->vxr_3v3_en);
-		gpio_free(pdata->led_5v_en);
-		gpio_free(pdata->led_drive_en1);
-		gpio_free(pdata->led_drive_en2);
-		gpio_free(pdata->display_1v8_en);
-		gpio_free(pdata->mipi_sw_1v8_en);
-		gpio_free(pdata->display_res1);
-	}
-}
-
-
 static int vxr7200_parse_dt(struct device *dev,
 				struct vxr7200 *pdata)
 {
@@ -225,10 +217,10 @@
 		rc = -EINVAL;
 	}
 
-	pdata->mipi_sw_1v8_en =
+	pdata->mipi_switch_1v8_en =
 		of_get_named_gpio(np, "qcom,switch-power-gpio", 0);
-	if (!gpio_is_valid(pdata->mipi_sw_1v8_en)) {
-		pr_err("mipi_sw_1v8_en gpio not specified\n");
+	if (!gpio_is_valid(pdata->mipi_switch_1v8_en)) {
+		pr_err("mipi_switch_1v8_en gpio not specified\n");
 		rc = -EINVAL;
 	}
 
@@ -242,39 +234,15 @@
 	if (!rc)
 		vxr7200_set_gpios(pdata, true);
 
-	pdata->selab_gpio = of_get_named_gpio(np, "qcom,selab-gpio", 0);
-	if (!gpio_is_valid(pdata->selab_gpio)) {
-		pr_err("selab_gpio gpio not specified\n");
-		rc = -EINVAL;
-		goto gpio_selab_fail;
-	} else
-		turnGpio(pdata, pdata->selab_gpio, "selab_gpio", 0);
-
-	pdata->oenab_gpio = of_get_named_gpio(np, "qcom,oenab-gpio", 0);
-	if (!gpio_is_valid(pdata->oenab_gpio)) {
-		pr_err("oenab_gpio gpio not specified\n");
-		rc = -EINVAL;
-		goto gpio_oenab_fail;
-	} else
-		turnGpio(pdata, pdata->oenab_gpio, "oenab_gpio", 0);
-
 	if (!pdata->gpioInit)
 		pdata->gpioInit = true;
 
 	return rc;
-
-gpio_oenab_fail:
-	gpio_free(pdata->oenab_gpio);
-gpio_selab_fail:
-	gpio_free(pdata->selab_gpio);
-	vxr7200_free_gpios(pdata);
-	return rc;
 }
 
 static void vxr7200_display_pwr_enable_vregs(struct vxr7200 *pdata)
 {
 	int rc = 0;
-
 	pdata->vddio = devm_regulator_get(pdata->dev, "pm660_l11");
 	rc = PTR_RET(pdata->vddio);
 	if (rc) {
@@ -286,12 +254,8 @@
 		pr_err("Load setting failed for vddio %s\n", __func__);
 		goto vddio_fail;
 	}
-	rc = regulator_set_voltage(pdata->vddio, 1800000, 1800000);
-	if (rc) {
-		pr_err("Set voltage(vddio) fail, rc=%d %s\n", rc, __func__);
-		goto vddio_fail;
-	}
 	rc = regulator_enable(pdata->vddio);
+	msleep(20);
 	if (rc) {
 		pr_err("enable failed for vddio, rc=%d %s\n", rc, __func__);
 		goto vddio_fail;
@@ -308,16 +272,12 @@
 		pr_err("Load Setting failed for lab %s\n", __func__);
 		goto lab_fail;
 	}
-	rc = regulator_set_voltage(pdata->lab, 4600000, 6000000);
-	if (rc) {
-		pr_err("Set voltage(lab) fail, rc=%d %s\n", rc, __func__);
-		goto lab_fail;
-	}
 	rc = regulator_enable(pdata->lab);
 	if (rc) {
 		pr_err("enable failed for lab, rc=%d %s\n", rc, __func__);
 		goto lab_fail;
 	}
+	msleep(20);
 
 	pdata->ibb = devm_regulator_get(pdata->dev, "lcdb_ncp");
 	rc = PTR_RET(pdata->ibb);
@@ -330,16 +290,12 @@
 		pr_err("Load Setting failed for ibb %s\n", __func__);
 		goto ibb_fail;
 	}
-	rc = regulator_set_voltage(pdata->ibb, 4600000, 6000000);
-	if (rc) {
-		pr_err("Set voltage(ibb) fail, rc=%d %s\n", rc, __func__);
-		goto ibb_fail;
-	}
 	rc = regulator_enable(pdata->ibb);
 	if (rc) {
 		pr_err("enable failed for ibb, rc=%d %s\n", rc, __func__);
 		goto ibb_fail;
 	}
+	msleep(20);
 
 	return;
 
diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c b/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c
index b16cc0c..8c9be67 100644
--- a/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c
+++ b/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c
@@ -673,7 +673,8 @@
 	}
 	if (ntn_ctx->conn.dl.smmu_enabled)
 		ipa_uc_ntn_free_conn_smmu_info(&ntn_ctx->conn.dl);
-		ipa_uc_ntn_free_conn_smmu_info(&ntn_ctx->conn.ul);
+
+	ipa_uc_ntn_free_conn_smmu_info(&ntn_ctx->conn.ul);
 
 	return ret;
 }
diff --git a/drivers/platform/msm/ipa/ipa_common_i.h b/drivers/platform/msm/ipa/ipa_common_i.h
index 3b40b41..858804d 100644
--- a/drivers/platform/msm/ipa/ipa_common_i.h
+++ b/drivers/platform/msm/ipa/ipa_common_i.h
@@ -21,6 +21,8 @@
 #include <linux/ipa_uc_offload.h>
 #include <linux/ipa_wdi3.h>
 #include <linux/ratelimit.h>
+#include <linux/swab.h>
+#include <linux/compiler.h>
 
 #define WARNON_RATELIMIT_BURST 1
 #define IPA_RATELIMIT_BURST 1
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
index bc107d8..17f22f1 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2020, 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
@@ -1590,7 +1590,7 @@
 				(RMNET_IOCTL_FEAT_NOTIFY_MUX_CHANNEL |
 				RMNET_IOCTL_FEAT_SET_EGRESS_DATA_FORMAT |
 				RMNET_IOCTL_FEAT_SET_INGRESS_DATA_FORMAT);
-			if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
+			if (copy_to_user(ifr->ifr_ifru.ifru_data,
 				&extend_ioctl_data,
 				sizeof(struct rmnet_ioctl_extended_s)))
 				rc = -EFAULT;
@@ -1604,7 +1604,7 @@
 		/*  Get MRU  */
 		case RMNET_IOCTL_GET_MRU:
 			extend_ioctl_data.u.data = mru;
-			if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
+			if (copy_to_user(ifr->ifr_ifru.ifru_data,
 				&extend_ioctl_data,
 				sizeof(struct rmnet_ioctl_extended_s)))
 				rc = -EFAULT;
@@ -1613,7 +1613,7 @@
 		case RMNET_IOCTL_GET_SG_SUPPORT:
 			extend_ioctl_data.u.data =
 				ipa3_rmnet_res.ipa_advertise_sg_support;
-			if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
+			if (copy_to_user(ifr->ifr_ifru.ifru_data,
 				&extend_ioctl_data,
 				sizeof(struct rmnet_ioctl_extended_s)))
 				rc = -EFAULT;
@@ -1622,7 +1622,7 @@
 		case RMNET_IOCTL_GET_EPID:
 			IPAWANDBG("get ioctl: RMNET_IOCTL_GET_EPID\n");
 			extend_ioctl_data.u.data = epid;
-			if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
+			if (copy_to_user(ifr->ifr_ifru.ifru_data,
 				&extend_ioctl_data,
 				sizeof(struct rmnet_ioctl_extended_s)))
 				rc = -EFAULT;
@@ -1643,7 +1643,7 @@
 			ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_PROD);
 			extend_ioctl_data.u.ipa_ep_pair.producer_pipe_num =
 			ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_CONS);
-			if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
+			if (copy_to_user(ifr->ifr_ifru.ifru_data,
 				&extend_ioctl_data,
 				sizeof(struct rmnet_ioctl_extended_s)))
 				rc = -EFAULT;
@@ -1660,13 +1660,19 @@
 			break;
 		/*  Get driver name  */
 		case RMNET_IOCTL_GET_DRIVER_NAME:
-			memcpy(&extend_ioctl_data.u.if_name,
-				IPA_NETDEV()->name, IFNAMSIZ);
-			extend_ioctl_data.u.if_name[IFNAMSIZ - 1] = '\0';
-			if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
+			if (IPA_NETDEV() != NULL) {
+				memcpy(&extend_ioctl_data.u.if_name,
+					IPA_NETDEV()->name, IFNAMSIZ);
+				extend_ioctl_data.u.if_name[IFNAMSIZ - 1] =
+				'\0';
+				if (copy_to_user(ifr->ifr_ifru.ifru_data,
 					&extend_ioctl_data,
 					sizeof(struct rmnet_ioctl_extended_s)))
+					rc = -EFAULT;
+			} else {
+				IPAWANERR("IPA_NETDEV is NULL\n");
 				rc = -EFAULT;
+			}
 			break;
 		/*  Add MUX ID  */
 		case RMNET_IOCTL_ADD_MUX_CHANNEL:
diff --git a/drivers/platform/msm/mhi_dev/mhi.c b/drivers/platform/msm/mhi_dev/mhi.c
index 42e3997..125a1969 100644
--- a/drivers/platform/msm/mhi_dev/mhi.c
+++ b/drivers/platform/msm/mhi_dev/mhi.c
@@ -82,6 +82,8 @@
 static void mhi_dev_resume_init_with_link_up(struct ep_pcie_notify *notify);
 static int mhi_dev_pcie_notify_event;
 static void mhi_dev_transfer_completion_cb(void *mreq);
+static int mhi_dev_alloc_evt_buf_evt_req(struct mhi_dev *mhi,
+		struct mhi_dev_channel *ch, struct mhi_dev_ring *evt_ring);
 static struct mhi_dev_uevent_info channel_state_info[MHI_MAX_CHANNELS];
 
 /*
@@ -90,17 +92,14 @@
  *
  * @req : ring cache request
  */
-static void  mhi_dev_ring_cache_completion_cb(void *req)
+static void mhi_dev_ring_cache_completion_cb(void *req)
 {
-	struct ring_cache_req *ring_req = NULL;
+	struct ring_cache_req *ring_req = req;
 
-	if (req)
-		ring_req = (struct ring_cache_req *)req;
-	else {
-		pr_err("%s():ring cache req data is NULL\n", __func__);
-		return;
-	}
-	complete(ring_req->done);
+	if (ring_req)
+		complete(ring_req->done);
+	else
+		mhi_log(MHI_MSG_ERROR, "ring cache req is NULL\n");
 }
 
 void mhi_dev_read_from_host(struct mhi_dev *mhi, struct mhi_addr *transfer)
@@ -193,13 +192,310 @@
 }
 EXPORT_SYMBOL(mhi_dev_write_to_host);
 
+/*
+ * mhi_dev_event_buf_completion_cb() - CB function called by IPA driver
+ * when transfer completion event buffer copy to host is done.
+ *
+ * @req -  event_req structure
+ */
+static void mhi_dev_event_buf_completion_cb(void *req)
+{
+	struct event_req *ereq = req;
+
+	if (ereq)
+		dma_unmap_single(&mhi_ctx->pdev->dev, ereq->dma,
+			ereq->dma_len, DMA_TO_DEVICE);
+	else
+		mhi_log(MHI_MSG_ERROR, "event req is null\n");
+}
+
+/*
+ * mhi_dev_event_rd_offset_completion_cb() - CB function called by IPA driver
+ * when event ring rd_offset transfer is done.
+ *
+ * @req -  event_req structure
+ */
+static void mhi_dev_event_rd_offset_completion_cb(void *req)
+{
+	union mhi_dev_ring_ctx *ctx;
+	int rc;
+	struct event_req *ereq = req;
+	struct mhi_dev_channel *ch = ereq->context;
+	struct mhi_dev *mhi = ch->ring->mhi_dev;
+	unsigned long flags;
+
+	if (ereq->event_rd_dma)
+		dma_unmap_single(&mhi_ctx->pdev->dev, ereq->event_rd_dma,
+			sizeof(uint64_t), DMA_TO_DEVICE);
+	/* rp update in host memory should be flushed before sending an MSI */
+	wmb();
+	ctx = (union mhi_dev_ring_ctx *)&mhi->ev_ctx_cache[ereq->event_ring];
+	rc = ep_pcie_trigger_msi(mhi_ctx->phandle, ctx->ev.msivec);
+	if (rc)
+		pr_err("%s: error sending in msi\n", __func__);
+
+	/* Add back the flushed events space to the event buffer */
+	ch->evt_buf_wp = ereq->start + ereq->num_events;
+	if (ch->evt_buf_wp == ch->evt_buf_size)
+		ch->evt_buf_wp = 0;
+	/* Return the event req to the list */
+	spin_lock_irqsave(&mhi->lock, flags);
+	if (ch->curr_ereq == NULL)
+		ch->curr_ereq = ereq;
+	else
+		list_add_tail(&ereq->list, &ch->event_req_buffers);
+	spin_unlock_irqrestore(&mhi->lock, flags);
+}
+
+static int mhi_dev_send_multiple_tr_events(struct mhi_dev *mhi, int evnt_ring,
+		struct event_req *ereq, uint32_t evt_len)
+{
+	int rc = 0;
+	uint64_t evnt_ring_idx = mhi->ev_ring_start + evnt_ring;
+	struct mhi_dev_ring *ring = &mhi->ring[evnt_ring_idx];
+	union mhi_dev_ring_ctx *ctx;
+	struct mhi_addr transfer_addr;
+	struct mhi_dev_channel *ch;
+
+	if (!ereq) {
+		pr_err("%s(): invalid event req\n", __func__);
+		return -EINVAL;
+	}
+
+	if (evnt_ring_idx > mhi->cfg.event_rings) {
+		pr_err("Invalid event ring idx: %lld\n", evnt_ring_idx);
+		return -EINVAL;
+	}
+
+	if (mhi_ring_get_state(ring) == RING_STATE_UINT) {
+		ctx = (union mhi_dev_ring_ctx *)&mhi->ev_ctx_cache[evnt_ring];
+		rc = mhi_ring_start(ring, ctx, mhi);
+		if (rc) {
+			mhi_log(MHI_MSG_ERROR,
+				"error starting event ring %d\n", evnt_ring);
+			return rc;
+		}
+	}
+	ch = ereq->context;
+	/* Check the limits of the buffer to be flushed */
+	if (ereq->tr_events < ch->tr_events ||
+		(ereq->tr_events + ereq->num_events) >
+		(ch->tr_events + ch->evt_buf_size)) {
+		pr_err("%s: Invalid completion event buffer!\n", __func__);
+		mhi_log(MHI_MSG_ERROR,
+			"Invalid cmpl evt buf - start %pK, end %pK\n",
+			ereq->tr_events, ereq->tr_events + ereq->num_events);
+		return -EINVAL;
+	}
+
+	mhi_log(MHI_MSG_VERBOSE, "Flushing %d cmpl events of ch %d\n",
+			ereq->num_events, ch->ch_id);
+	/* add the events */
+	ereq->client_cb = mhi_dev_event_buf_completion_cb;
+	ereq->event_type = SEND_EVENT_BUFFER;
+	rc = mhi_dev_add_element(ring, ereq->tr_events, ereq, evt_len);
+	if (rc) {
+		pr_err("%s(): error in adding element rc %d\n", __func__, rc);
+		return rc;
+	}
+	ring->ring_ctx_shadow->ev.rp = (ring->rd_offset *
+		sizeof(union mhi_dev_ring_element_type)) +
+		ring->ring_ctx->generic.rbase;
+
+	mhi_log(MHI_MSG_VERBOSE, "ev.rp = %llx for %lld\n",
+		ring->ring_ctx_shadow->ev.rp, evnt_ring_idx);
+
+	if (mhi->use_ipa) {
+		transfer_addr.host_pa = (mhi->ev_ctx_shadow.host_pa +
+		sizeof(struct mhi_dev_ev_ctx) *
+		evnt_ring) + (size_t)&ring->ring_ctx->ev.rp -
+		(size_t)ring->ring_ctx;
+		/*
+		 * As ev_ctx_cache memory is dma_alloc_coherent, dma_map_single
+		 * should not be called. Pass physical address to write to host.
+		 */
+		transfer_addr.phy_addr = (mhi->ev_ctx_cache_dma_handle +
+			sizeof(struct mhi_dev_ev_ctx) * evnt_ring) +
+			(size_t)&ring->ring_ctx->ev.rp -
+			(size_t)ring->ring_ctx;
+	} else {
+		transfer_addr.device_va = (mhi->ev_ctx_shadow.device_va +
+		sizeof(struct mhi_dev_ev_ctx) *
+		evnt_ring) + (size_t)&ring->ring_ctx->ev.rp -
+		(size_t)ring->ring_ctx;
+	}
+
+	transfer_addr.virt_addr = &ring->ring_ctx_shadow->ev.rp;
+	transfer_addr.size = sizeof(uint64_t);
+	ereq->event_type = SEND_EVENT_RD_OFFSET;
+	ereq->client_cb = mhi_dev_event_rd_offset_completion_cb;
+	ereq->event_ring = evnt_ring;
+	mhi_dev_write_to_host(mhi, &transfer_addr, ereq, MHI_DEV_DMA_ASYNC);
+	return rc;
+}
+
+static int mhi_dev_flush_transfer_completion_events(struct mhi_dev *mhi,
+		struct mhi_dev_channel *ch)
+{
+	int rc = 0;
+	unsigned long flags;
+	struct event_req *flush_ereq;
+
+	/*
+	 * Channel got closed with transfers pending
+	 * Do not send completion events to host
+	 */
+	if (ch->state == MHI_DEV_CH_CLOSED) {
+		mhi_log(MHI_MSG_DBG, "Ch %d closed with %d writes pending\n",
+			ch->ch_id, ch->pend_wr_count + 1);
+		return -ENODEV;
+	}
+
+	do {
+		spin_lock_irqsave(&mhi->lock, flags);
+		if (list_empty(&ch->flush_event_req_buffers)) {
+			spin_unlock_irqrestore(&mhi->lock, flags);
+			break;
+		}
+		flush_ereq = container_of(ch->flush_event_req_buffers.next,
+					struct event_req, list);
+		list_del_init(&flush_ereq->list);
+		spin_unlock_irqrestore(&mhi->lock, flags);
+
+		mhi_log(MHI_MSG_DBG, "Flush called for ch %d\n", ch->ch_id);
+		rc = mhi_dev_send_multiple_tr_events(mhi,
+				mhi->ch_ctx_cache[ch->ch_id].err_indx,
+				flush_ereq,
+				(flush_ereq->num_events *
+				sizeof(union mhi_dev_ring_element_type)));
+		if (rc) {
+			mhi_log(MHI_MSG_ERROR, "failed to send compl evts\n");
+			break;
+		}
+	} while (true);
+
+	return rc;
+}
+
+static bool mhi_dev_is_full_compl_evt_buf(struct mhi_dev_channel *ch)
+{
+	if (((ch->evt_buf_rp + 1) % ch->evt_buf_size) == ch->evt_buf_wp)
+		return true;
+
+	return false;
+}
+
+static void mhi_dev_rollback_compl_evt(struct mhi_dev_channel *ch)
+{
+	if (ch->evt_buf_rp)
+		ch->evt_buf_rp--;
+	else
+		ch->evt_buf_rp = ch->evt_buf_size - 1;
+}
+
+/*
+ * mhi_dev_queue_transfer_completion() - Queues a transfer completion
+ * event to the event buffer (where events are stored until they get
+ * flushed to host). Also determines when the completion events are
+ * to be flushed (sent) to host.
+ *
+ * @req -  event_req structure
+ * @flush - Set to true when completion events are to be flushed.
+ */
+
+static int mhi_dev_queue_transfer_completion(struct mhi_req *mreq, bool *flush)
+{
+	union mhi_dev_ring_element_type *compl_ev;
+	struct mhi_dev_channel *ch = mreq->client->channel;
+	unsigned long flags;
+
+	if (mhi_dev_is_full_compl_evt_buf(ch) || ch->curr_ereq == NULL) {
+		mhi_log(MHI_MSG_VERBOSE, "Ran out of %s\n",
+			(ch->curr_ereq ? "compl evts" : "ereqs"));
+		return -EBUSY;
+	}
+
+	if (mreq->el->tre.ieot) {
+		compl_ev = ch->tr_events + ch->evt_buf_rp;
+		compl_ev->evt_tr_comp.chid = ch->ch_id;
+		compl_ev->evt_tr_comp.type =
+			MHI_DEV_RING_EL_TRANSFER_COMPLETION_EVENT;
+		compl_ev->evt_tr_comp.len = mreq->transfer_len;
+		compl_ev->evt_tr_comp.code = MHI_CMD_COMPL_CODE_EOT;
+		compl_ev->evt_tr_comp.ptr = ch->ring->ring_ctx->generic.rbase +
+			mreq->rd_offset * TR_RING_ELEMENT_SZ;
+		ch->evt_buf_rp++;
+		if (ch->evt_buf_rp == ch->evt_buf_size)
+			ch->evt_buf_rp = 0;
+		ch->curr_ereq->num_events++;
+		/*
+		 * It is not necessary to flush when we need to wrap-around, if
+		 * we do have free space in the buffer upon wrap-around.
+		 * But when we really need to flush, we need a separate dma op
+		 * anyway for the current chunk (from flush_start to the
+		 * physical buffer end) since the buffer is circular. So we
+		 * might as well flush on wrap-around.
+		 * Also, we flush when we hit the threshold as well. The flush
+		 * threshold is based on the channel's event ring size.
+		 *
+		 * In summary, completion event buffer flush is done if
+		 *    * Client requests it (snd_cmpl was set to 1) OR
+		 *    * Physical end of the event buffer is reached OR
+		 *    * Flush threshold is reached for the current ereq
+		 *
+		 * When events are to be flushed, the current ereq is moved to
+		 * the flush list, and the flush param is set to true for the
+		 * second and third cases above. The actual flush of the events
+		 * is done in the write_to_host API (for the write path) or
+		 * in the transfer completion callback (for the read path).
+		 */
+		if (ch->evt_buf_rp == 0 ||
+			ch->curr_ereq->num_events >=
+			MHI_CMPL_EVT_FLUSH_THRSHLD(ch->evt_buf_size)
+			|| mreq->snd_cmpl) {
+			if (flush)
+				*flush = true;
+
+			if (!mreq->snd_cmpl)
+				mreq->snd_cmpl = 1;
+
+			ch->curr_ereq->tr_events = ch->tr_events +
+				ch->curr_ereq->start;
+			ch->curr_ereq->context = ch;
+
+			/* Move current event req to flush list*/
+			spin_lock_irqsave(&mhi_ctx->lock, flags);
+			list_add_tail(&ch->curr_ereq->list,
+				&ch->flush_event_req_buffers);
+
+			if (!list_empty(&ch->event_req_buffers)) {
+				ch->curr_ereq =
+					container_of(ch->event_req_buffers.next,
+						struct event_req, list);
+				list_del_init(&ch->curr_ereq->list);
+				ch->curr_ereq->num_events = 0;
+				ch->curr_ereq->start = ch->evt_buf_rp;
+			} else {
+				pr_err("%s evt req buffers empty\n", __func__);
+				mhi_log(MHI_MSG_ERROR,
+						"evt req buffers empty\n");
+				ch->curr_ereq = NULL;
+			}
+			spin_unlock_irqrestore(&mhi_ctx->lock, flags);
+		}
+		return 0;
+	}
+
+	mhi_log(MHI_MSG_ERROR, "ieot is not valid\n");
+	return -EINVAL;
+}
 int mhi_transfer_host_to_device(void *dev, uint64_t host_pa, uint32_t len,
 		struct mhi_dev *mhi, struct mhi_req *mreq)
 {
 	int rc = 0;
 	uint64_t bit_40 = ((u64) 1) << 40, host_addr_pa = 0, offset = 0;
 	struct mhi_dev_ring *ring = NULL;
-
+	struct mhi_dev_channel *ch;
 
 	if (!mhi || !dev || !host_pa || !mreq) {
 		pr_err("%s():Invalid parameters\n", __func__);
@@ -226,20 +522,37 @@
 		}
 		memcpy(dev, mhi->read_handle, len);
 	} else if (mreq->mode == IPA_DMA_ASYNC) {
-		ring = mreq->client->channel->ring;
+		ch = mreq->client->channel;
+		ring = ch->ring;
 		mreq->dma = dma_map_single(&mhi->pdev->dev, dev, len,
 				DMA_FROM_DEVICE);
 		mhi_dev_ring_inc_index(ring, ring->rd_offset);
 
-		if (ring->rd_offset == ring->wr_offset)
+		if (ring->rd_offset == ring->wr_offset) {
+			mhi_log(MHI_MSG_VERBOSE,
+				"Setting snd_cmpl to 1 for ch %d\n", ch->ch_id);
 			mreq->snd_cmpl = 1;
-		else
-			mreq->snd_cmpl = 0;
+		}
+
+		/* Queue the completion event for the current transfer */
+		rc = mhi_dev_queue_transfer_completion(mreq, NULL);
+		if (rc) {
+			mhi_log(MHI_MSG_ERROR,
+				"Failed to queue completion for ch %d, rc %d\n",
+				ch->ch_id, rc);
+			return rc;
+		}
 		rc = ipa_dma_async_memcpy(mreq->dma, host_addr_pa,
 				(int) len, mhi_dev_transfer_completion_cb,
 				mreq);
 		if (rc) {
-			pr_err("error while reading chan using async:%d\n", rc);
+			mhi_log(MHI_MSG_ERROR,
+				"DMA read error %d for ch %d\n", rc, ch->ch_id);
+			/* Roll back the completion event that we wrote above */
+			mhi_dev_rollback_compl_evt(ch);
+			/* Unmap the buffer */
+			dma_unmap_single(&mhi_ctx->pdev->dev, mreq->dma,
+							len, DMA_FROM_DEVICE);
 			return rc;
 		}
 	}
@@ -253,6 +566,9 @@
 	int rc = 0;
 	uint64_t bit_40 = ((u64) 1) << 40, host_addr_pa = 0, offset = 0;
 	struct mhi_dev_ring *ring = NULL;
+	bool flush = false;
+	struct mhi_dev_channel *ch;
+	u32 snd_cmpl;
 
 	if (!mhi || !dev || !req  || !host_addr) {
 		pr_err("%sInvalid parameters\n", __func__);
@@ -275,17 +591,45 @@
 		rc = ipa_dma_sync_memcpy(host_addr_pa,
 				(u64) mhi->write_dma_handle, (int) len);
 	} else if (req->mode == IPA_DMA_ASYNC) {
+		ch = req->client->channel;
 		req->dma = dma_map_single(&mhi->pdev->dev, req->buf,
 				req->len, DMA_TO_DEVICE);
-		ring = req->client->channel->ring;
+
+		ring = ch->ring;
 		mhi_dev_ring_inc_index(ring, ring->rd_offset);
 		if (ring->rd_offset == ring->wr_offset)
 			req->snd_cmpl = 1;
+		snd_cmpl = req->snd_cmpl;
+
+		/* Queue the completion event for the current transfer */
+		rc = mhi_dev_queue_transfer_completion(req, &flush);
+		if (rc) {
+			pr_err("Failed to queue completion: %d\n", rc);
+			return rc;
+		}
+
 		rc = ipa_dma_async_memcpy(host_addr_pa,
 				(uint64_t) req->dma, (int) len,
 				mhi_dev_transfer_completion_cb, req);
+		if (rc) {
+			mhi_log(MHI_MSG_ERROR, "Error sending data to host\n");
+			/* Roll back the completion event that we wrote above */
+			mhi_dev_rollback_compl_evt(ch);
+			/* Unmap the buffer */
+			dma_unmap_single(&mhi_ctx->pdev->dev, req->dma,
+				req->len, DMA_TO_DEVICE);
+			return rc;
+		}
+		if (snd_cmpl || flush) {
+			rc = mhi_dev_flush_transfer_completion_events(mhi, ch);
+			if (rc) {
+				mhi_log(MHI_MSG_ERROR,
+					"Failed to flush write completions to host\n");
+				return rc;
+			}
+		}
 	}
-	return rc;
+	return 0;
 }
 EXPORT_SYMBOL(mhi_transfer_device_to_host);
 
@@ -666,130 +1010,6 @@
 	return rc;
 }
 
-/*
- * mhi_dev_event_buf_completion_cb() -Cb function called by IPA driver
- * when transfer completion event buffer copy is done.
- *
- * @req -  event_req structure
- */
-
-static void mhi_dev_event_buf_completion_cb(void *req)
-{
-	struct event_req *ereq = NULL;
-
-	if (req) {
-		ereq = (struct event_req *)req;
-	} else {
-		pr_err("%s():event req data is invalid\n", __func__);
-		return;
-	}
-	dma_unmap_single(&mhi_ctx->pdev->dev, ereq->dma,
-			ereq->dma_len, DMA_TO_DEVICE);
-}
-
-/**
- * mhi_dev_event_rd_offset_completion_cb() -CB function called by IPA driver
- * when event rd_offset transfer is done.
- *
- * @req -  event_req structure
- */
-
-static void mhi_dev_event_rd_offset_completion_cb(void *req)
-{
-	union mhi_dev_ring_ctx *ctx;
-	int rc = 0;
-	struct event_req *ereq = (struct event_req *)req;
-	struct mhi_dev_channel *ch = ereq->context;
-	struct mhi_dev *mhi = ch->ring->mhi_dev;
-	unsigned long flags;
-
-	dma_unmap_single(&mhi_ctx->pdev->dev, ereq->event_rd_dma,
-			sizeof(uint64_t), DMA_TO_DEVICE);
-	ctx = (union mhi_dev_ring_ctx *)&mhi->ev_ctx_cache[ereq->event_ring];
-	rc = ep_pcie_trigger_msi(mhi_ctx->phandle, ctx->ev.msivec);
-	if (rc)
-		pr_err("%s: error sending in msi\n", __func__);
-
-	/* return the event req to pre allocated pooled list */
-	spin_lock_irqsave(&mhi->lock, flags);
-	list_add_tail(&ereq->list, &ch->event_req_buffers);
-	spin_unlock_irqrestore(&mhi->lock, flags);
-}
-
-static int mhi_dev_send_multiple_tr_events(struct mhi_dev *mhi, int evnt_ring,
-		struct event_req *ereq, uint32_t evt_len)
-{
-	int rc = 0;
-	uint64_t evnt_ring_idx = mhi->ev_ring_start + evnt_ring;
-	struct mhi_dev_ring *ring = &mhi->ring[evnt_ring_idx];
-	union mhi_dev_ring_ctx *ctx;
-	struct mhi_addr transfer_addr;
-	static int count;
-
-	if (!ereq) {
-		pr_err("%s(): invalid event req\n", __func__);
-		return -EINVAL;
-	}
-
-	if (count == 0) {
-		rc = ep_pcie_get_msi_config(mhi->phandle, &mhi->msi_cfg);
-		if (rc) {
-			pr_err("Error retrieving pcie msi logic\n");
-			return rc;
-		}
-		count++;
-	}
-
-	if (evnt_ring_idx > mhi->cfg.event_rings) {
-		pr_err("Invalid event ring idx: %lld\n", evnt_ring_idx);
-		return -EINVAL;
-	}
-
-	ctx = (union mhi_dev_ring_ctx *)&mhi->ev_ctx_cache[evnt_ring];
-	if (mhi_ring_get_state(ring) == RING_STATE_UINT) {
-		rc = mhi_ring_start(ring, ctx, mhi);
-		if (rc) {
-			mhi_log(MHI_MSG_ERROR,
-				"error starting event ring %d\n", evnt_ring);
-			return rc;
-		}
-	}
-
-	/* add the ring element */
-	ereq->client_cb = mhi_dev_event_buf_completion_cb;
-	ereq->event_type = SEND_EVENT_BUFFER;
-	rc = mhi_dev_add_element(ring, ereq->tr_events, ereq, evt_len);
-	if (rc) {
-		pr_err("%s(): error in adding element rc %d\n", __func__, rc);
-		return rc;
-	}
-	ring->ring_ctx_shadow->ev.rp = (ring->rd_offset *
-		sizeof(union mhi_dev_ring_element_type)) +
-		ring->ring_ctx->generic.rbase;
-
-	mhi_log(MHI_MSG_VERBOSE, "ev.rp = %llx for %lld\n",
-		ring->ring_ctx_shadow->ev.rp, evnt_ring_idx);
-
-	if (mhi->use_ipa)
-		transfer_addr.host_pa = (mhi->ev_ctx_shadow.host_pa +
-		sizeof(struct mhi_dev_ev_ctx) *
-		evnt_ring) + (uint32_t)&ring->ring_ctx->ev.rp -
-		(uint32_t)ring->ring_ctx;
-	else
-		transfer_addr.device_va = (mhi->ev_ctx_shadow.device_va +
-		sizeof(struct mhi_dev_ev_ctx) *
-		evnt_ring) + (uint32_t)&ring->ring_ctx->ev.rp -
-		(uint32_t)ring->ring_ctx;
-
-	transfer_addr.virt_addr = &ring->ring_ctx_shadow->ev.rp;
-	transfer_addr.size = sizeof(uint64_t);
-	ereq->event_type = SEND_EVENT_RD_OFFSET;
-	ereq->client_cb = mhi_dev_event_rd_offset_completion_cb;
-	ereq->event_ring = evnt_ring;
-	mhi_dev_write_to_host(mhi, &transfer_addr, ereq, MHI_DEV_DMA_ASYNC);
-	return rc;
-}
-
 static int mhi_dev_send_completion_event(struct mhi_dev_channel *ch,
 			uint32_t rd_ofst, uint32_t len,
 			enum mhi_dev_cmd_completion_code code)
@@ -854,6 +1074,10 @@
 	struct mhi_dev_ready_cb_info *info;
 	enum mhi_ctrl_info state_data;
 
+	/* Currently no clients register for HW channel notify */
+	if (ch_id >= MHI_MAX_SOFTWARE_CHANNELS)
+		return;
+
 	list_for_each_entry(info, &mhi_ctx->client_cb_list, list)
 		if (info->cb && info->cb_data.channel == ch_id) {
 			mhi_ctrl_state_info(info->cb_data.channel, &state_data);
@@ -962,6 +1186,7 @@
 	struct mhi_addr host_addr;
 	struct mhi_dev_channel *ch;
 	struct mhi_dev_ring *ring;
+	union mhi_dev_ring_ctx *evt_ctx;
 
 	ch_id = el->generic.chid;
 	mhi_log(MHI_MSG_VERBOSE, "for channel:%d and cmd:%d\n",
@@ -1026,6 +1251,26 @@
 			return;
 		}
 
+		if (mhi->use_ipa) {
+			uint32_t evnt_ring_idx = mhi->ev_ring_start +
+					mhi->ch_ctx_cache[ch_id].err_indx;
+			struct mhi_dev_ring *evt_ring =
+				&mhi->ring[evnt_ring_idx];
+			evt_ctx = (union mhi_dev_ring_ctx *)&mhi->ev_ctx_cache
+				[mhi->ch_ctx_cache[ch_id].err_indx];
+			if (mhi_ring_get_state(evt_ring) == RING_STATE_UINT) {
+				rc = mhi_ring_start(evt_ring, evt_ctx, mhi);
+				if (rc) {
+					mhi_log(MHI_MSG_ERROR,
+					"error starting event ring %d\n",
+					mhi->ch_ctx_cache[ch_id].err_indx);
+					return;
+				}
+			}
+			mhi_dev_alloc_evt_buf_evt_req(mhi, &mhi->ch[ch_id],
+					evt_ring);
+		}
+
 		if (mhi->use_ipa)
 			host_addr.host_pa = mhi->ch_ctx_shadow.host_pa +
 					sizeof(struct mhi_dev_ch_ctx) * ch_id;
@@ -1349,7 +1594,7 @@
 	struct mhi_dev_client_cb_reason reason;
 
 	mhi_ctx->ctrl_info = info;
-	for (i = 0; i < MHI_MAX_CHANNELS; ++i) {
+	for (i = 0; i < MHI_MAX_SOFTWARE_CHANNELS; ++i) {
 		channel_state_info[i].ctrl_info = info;
 		/* Notify kernel clients */
 		mhi_dev_trigger_cb(i);
@@ -1439,28 +1684,12 @@
 
 static void mhi_dev_transfer_completion_cb(void *mreq)
 {
-	struct mhi_dev_channel *ch;
-	struct mhi_dev_client *client;
-	union mhi_dev_ring_element_type *el;
 	int rc = 0;
-	struct mhi_req *req = (struct mhi_req *)mreq;
-	union mhi_dev_ring_element_type *compl_ev = NULL;
-	struct mhi_dev *mhi = NULL;
-	unsigned long flags;
-	size_t transfer_len;
-	u32 snd_cmpl;
-	uint32_t rd_offset;
+	struct mhi_req *req = mreq;
+	struct mhi_dev_channel *ch = req->client->channel;
+	u32 snd_cmpl = req->snd_cmpl;
 
-	client = req->client;
-	ch = client->channel;
-	mhi = ch->ring->mhi_dev;
-	el = req->el;
-	transfer_len = req->transfer_len;
-	snd_cmpl = req->snd_cmpl;
-	rd_offset = req->rd_offset;
-	ch->curr_ereq->context = ch;
-
-	if (mhi->ch_ctx_cache[ch->ch_id].ch_type ==
+	if (mhi_ctx->ch_ctx_cache[ch->ch_id].ch_type ==
 			MHI_DEV_CH_TYPE_INBOUND_CHANNEL)
 		ch->pend_wr_count--;
 
@@ -1480,41 +1709,16 @@
 	/* Trigger client call back */
 	req->client_cb(req);
 
-	if (el->tre.ieot) {
-		compl_ev = ch->curr_ereq->tr_events + ch->curr_ereq->num_events;
-		compl_ev->evt_tr_comp.chid = ch->ch_id;
-		compl_ev->evt_tr_comp.type =
-				MHI_DEV_RING_EL_TRANSFER_COMPLETION_EVENT;
-		compl_ev->evt_tr_comp.len = transfer_len;
-		compl_ev->evt_tr_comp.code = MHI_CMD_COMPL_CODE_EOT;
-		compl_ev->evt_tr_comp.ptr = ch->ring->ring_ctx->generic.rbase +
-						rd_offset * TR_RING_ELEMENT_SZ;
-		ch->curr_ereq->num_events++;
-
-		if (ch->curr_ereq->num_events >= MAX_TR_EVENTS || snd_cmpl) {
-			mhi_log(MHI_MSG_VERBOSE,
-					"num of tr events %d for ch %d\n",
-					ch->curr_ereq->num_events, ch->ch_id);
-			rc = mhi_dev_send_multiple_tr_events(mhi,
-				mhi->ch_ctx_cache[ch->ch_id].err_indx,
-				ch->curr_ereq, (ch->curr_ereq->num_events*
-				sizeof(union mhi_dev_ring_element_type)));
-			if (rc)
-				mhi_log(MHI_MSG_ERROR,
-						"failed to send compl evts\n");
-			if (!list_empty(&ch->event_req_buffers)) {
-				ch->curr_ereq =
-					container_of(ch->event_req_buffers.next,
-							struct event_req, list);
-				spin_lock_irqsave(&mhi->lock, flags);
-				list_del_init(&ch->curr_ereq->list);
-				spin_unlock_irqrestore(&mhi->lock, flags);
-				ch->curr_ereq->num_events = 0;
-			} else
-				pr_err("%s evt req buffers empty\n", __func__);
+	/* Flush read completions to host */
+	if (snd_cmpl && mhi_ctx->ch_ctx_cache[ch->ch_id].ch_type ==
+				MHI_DEV_CH_TYPE_OUTBOUND_CHANNEL) {
+		mhi_log(MHI_MSG_DBG, "Calling flush for ch %d\n", ch->ch_id);
+		rc = mhi_dev_flush_transfer_completion_events(mhi_ctx, ch);
+		if (rc) {
+			mhi_log(MHI_MSG_ERROR,
+				"Failed to flush read completions to host\n");
 		}
-	} else
-		mhi_log(MHI_MSG_ERROR, "ieot is not valid\n");
+	}
 
 	if (ch->state == MHI_DEV_CH_PENDING_STOP) {
 		ch->state = MHI_DEV_CH_STOPPED;
@@ -1924,8 +2128,104 @@
 		mhi_ring_set_cb(&dev->ring[i], mhi_dev_process_tre_ring);
 	}
 
+	return 0;
+}
+
+static uint32_t mhi_dev_get_evt_ring_size(struct mhi_dev *mhi, uint32_t ch_id)
+{
+	uint32_t info;
+	int rc;
+
+	/* If channel was started by host, get event ring size */
+	rc = mhi_ctrl_state_info(ch_id, &info);
+	if (rc || (info != MHI_STATE_CONNECTED))
+		return NUM_TR_EVENTS_DEFAULT;
+
+	return mhi->ring[mhi->ev_ring_start +
+		mhi->ch_ctx_cache[ch_id].err_indx].ring_size;
+}
+
+static int mhi_dev_alloc_evt_buf_evt_req(struct mhi_dev *mhi,
+		struct mhi_dev_channel *ch, struct mhi_dev_ring *evt_ring)
+{
+	int rc;
+	uint32_t size, i;
+
+	if (evt_ring)
+		size = evt_ring->ring_size;
+	else
+		size = mhi_dev_get_evt_ring_size(mhi, ch->ch_id);
+
+	if (!size) {
+		mhi_log(MHI_MSG_ERROR,
+			"Evt buf size is 0 for channel %d", ch->ch_id);
+		return -EINVAL;
+	}
+
+	/* Previous allocated evt buf size matches requested size */
+	if (size == ch->evt_buf_size)
+		return 0;
+
+	/*
+	 * Either evt buf and evt reqs were not allocated yet or
+	 * they were allocated with a different size
+	 */
+	if (ch->evt_buf_size) {
+		kfree(ch->ereqs);
+		kfree(ch->tr_events);
+	}
+	/*
+	 * Set number of event flush req buffers equal to size of
+	 * event buf since in the worst case we may need to flush
+	 * every event ring element individually
+	 */
+	ch->evt_buf_size = size;
+	ch->evt_req_size = size;
+
+	mhi_log(MHI_MSG_INFO,
+		"Channel %d evt buf size is %d\n", ch->ch_id, ch->evt_buf_size);
+
+	/* Allocate event requests */
+	ch->ereqs = kcalloc(ch->evt_req_size, sizeof(*ch->ereqs), GFP_KERNEL);
+	if (!ch->ereqs)
+		return -ENOMEM;
+
+	/* Allocate buffers to queue transfer completion events */
+	ch->tr_events = kcalloc(ch->evt_buf_size, sizeof(*ch->tr_events),
+			GFP_KERNEL);
+	if (!ch->tr_events) {
+		rc = -ENOMEM;
+		goto free_ereqs;
+	}
+
+	/* Organize event flush requests into a linked list */
+	INIT_LIST_HEAD(&ch->event_req_buffers);
+	INIT_LIST_HEAD(&ch->flush_event_req_buffers);
+	for (i = 0; i < ch->evt_req_size; ++i)
+		list_add_tail(&ch->ereqs[i].list, &ch->event_req_buffers);
+
+	ch->curr_ereq =
+		container_of(ch->event_req_buffers.next,
+					struct event_req, list);
+	list_del_init(&ch->curr_ereq->list);
+	ch->curr_ereq->start = 0;
+
+	/*
+	 * Initialize cmpl event buffer indexes - evt_buf_rp and
+	 * evt_buf_wp point to the first and last free index available.
+	 */
+	ch->evt_buf_rp = 0;
+	ch->evt_buf_wp = ch->evt_buf_size - 1;
 
 	return 0;
+
+free_ereqs:
+	kfree(ch->ereqs);
+	ch->ereqs = NULL;
+	ch->evt_buf_size = 0;
+	ch->evt_req_size = 0;
+
+	return rc;
 }
 
 int mhi_dev_open_channel(uint32_t chan_id,
@@ -1934,7 +2234,6 @@
 			(struct mhi_dev_client_cb_reason *cb))
 {
 	int rc = 0;
-	int i = 0;
 	struct mhi_dev_channel *ch;
 	struct platform_device *pdev;
 
@@ -1958,37 +2257,9 @@
 		goto exit;
 	}
 
-	/* Pre allocate event requests */
-	ch->ereqs = kcalloc(MHI_MAX_EVT_REQ, sizeof(*ch->ereqs), GFP_KERNEL);
-	if (!ch->ereqs) {
-		rc = -ENOMEM;
+	rc = mhi_dev_alloc_evt_buf_evt_req(mhi_ctx, ch, NULL);
+	if (rc)
 		goto free_client;
-	}
-	/* pre allocate buffers to queue transfer completion events */
-	ch->tr_events = kcalloc(MHI_MAX_EVT_REQ,
-				MAX_TR_EVENTS * sizeof(*ch->tr_events),
-				GFP_KERNEL);
-	if (!ch->tr_events) {
-		rc = -ENOMEM;
-		goto free_ereqs;
-	}
-
-	/*
-	 * Organize the above allocated event request block and
-	 * completion event block into linked lists. Each event
-	 * request includes a pointer to a block of MAX_TR_EVENTS
-	 * completion events.
-	 */
-	INIT_LIST_HEAD(&mhi_ctx->ch[chan_id].event_req_buffers);
-	for (i = 0; i < MHI_MAX_EVT_REQ; ++i) {
-		ch->ereqs[i].tr_events = ch->tr_events + i * MAX_TR_EVENTS;
-		list_add_tail(&ch->ereqs[i].list,
-				&mhi_ctx->ch[chan_id].event_req_buffers);
-	}
-	mhi_ctx->ch[chan_id].curr_ereq =
-		container_of(mhi_ctx->ch[chan_id].event_req_buffers.next,
-				struct event_req, list);
-	list_del_init(&mhi_ctx->ch[chan_id].curr_ereq->list);
 
 	ch->active_client = (*handle_client);
 	(*handle_client)->channel = ch;
@@ -2004,11 +2275,10 @@
 
 	goto exit;
 
-free_ereqs:
-	kfree(ch->ereqs);
-	ch->ereqs = NULL;
 free_client:
 	kfree(*handle_client);
+	*handle_client = NULL;
+
 exit:
 	mutex_unlock(&ch->ch_lock);
 	return rc;
@@ -2020,6 +2290,11 @@
 	struct mhi_dev_channel *ch;
 	int rc;
 
+	if (!handle) {
+		mhi_log(MHI_MSG_ERROR, "Invalid channel access\n");
+		return -EINVAL;
+	}
+
 	ch = handle->channel;
 	if (!ch)
 		return -EINVAL;
@@ -2053,6 +2328,10 @@
 	int count = 0;
 	int rc = 0;
 
+	if (!handle) {
+		mhi_log(MHI_MSG_ERROR, "Invalid channel access:%d\n", -ENODEV);
+		return -EINVAL;
+	}
 	ch = handle->channel;
 
 	do {
@@ -2090,6 +2369,8 @@
 	ch->active_client = NULL;
 	kfree(ch->ereqs);
 	kfree(ch->tr_events);
+	ch->evt_buf_size = 0;
+	ch->evt_req_size = 0;
 	ch->ereqs = NULL;
 	ch->tr_events = NULL;
 	kfree(handle);
@@ -2548,11 +2829,6 @@
 		return;
 	}
 
-	/*Enable MHI dev network stack Interface*/
-	rc = mhi_dev_net_interface_init();
-	if (rc)
-		pr_err("%s Failed to initialize mhi_dev_net iface\n", __func__);
-
 	rc = mhi_dev_mmio_read(mhi, BHI_INTVEC, &bhi_intvec);
 	if (rc)
 		return;
@@ -2619,6 +2895,11 @@
 	}
 
 	mhi_update_state_info(MHI_DEV_UEVENT_CTRL, MHI_STATE_CONFIGURED);
+
+	/*Enable MHI dev network stack Interface*/
+	rc = mhi_dev_net_interface_init();
+	if (rc)
+		pr_err("%s Failed to initialize mhi_dev_net iface\n", __func__);
 }
 
 static void mhi_ring_init_cb(void *data)
@@ -2644,7 +2925,7 @@
 		return -ENXIO;
 	}
 
-	if (channel > MHI_MAX_CHANNELS) {
+	if (channel >= MHI_MAX_SOFTWARE_CHANNELS) {
 		pr_err("Invalid channel :%d\n", channel);
 		return -EINVAL;
 	}
@@ -2684,6 +2965,10 @@
 {
 	struct mhi_dev_client_cb_reason reason;
 
+	/* Currently no clients register for HW channel notify */
+	if (uevent_idx >= MHI_MAX_SOFTWARE_CHANNELS)
+		return;
+
 	if (uevent_idx == MHI_DEV_UEVENT_CTRL)
 		mhi_ctx->ctrl_info = info;
 
@@ -2703,7 +2988,10 @@
 	if (idx == MHI_DEV_UEVENT_CTRL)
 		*info = mhi_ctx->ctrl_info;
 	else
-		*info = channel_state_info[idx].ctrl_info;
+		if (idx < MHI_MAX_SOFTWARE_CHANNELS)
+			*info = channel_state_info[idx].ctrl_info;
+		else
+			return -EINVAL;
 
 	mhi_log(MHI_MSG_VERBOSE, "idx:%d, ctrl:%d", idx, *info);
 
@@ -2883,8 +3171,10 @@
 		if (!mhi->ch)
 			return -ENOMEM;
 
-		for (i = 0; i < mhi->cfg.channels; i++)
+		for (i = 0; i < mhi->cfg.channels; i++) {
+			mhi->ch[i].ch_id = i;
 			mutex_init(&mhi->ch[i].ch_lock);
+			}
 	}
 
 	spin_lock_init(&mhi->lock);
diff --git a/drivers/platform/msm/mhi_dev/mhi.h b/drivers/platform/msm/mhi_dev/mhi.h
index 8f7a8e3..f97efd5 100644
--- a/drivers/platform/msm/mhi_dev/mhi.h
+++ b/drivers/platform/msm/mhi_dev/mhi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2020, 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
@@ -277,10 +277,11 @@
 #define TRB_MAX_DATA_SIZE		8192
 #define MHI_CTRL_STATE			100
 
-/*maximum trasnfer completion events buffer*/
-#define MAX_TR_EVENTS			50
-/*maximum event requests */
-#define MHI_MAX_EVT_REQ			50
+/* maximum transfer completion events buffer */
+#define NUM_TR_EVENTS_DEFAULT			128
+
+/* Set flush threshold to 80% of event buf size */
+#define MHI_CMPL_EVT_FLUSH_THRSHLD(n) ((n * 8) / 10)
 
 /* Possible ring element types */
 union mhi_dev_ring_element_type {
@@ -418,6 +419,11 @@
 
 struct event_req {
 	union mhi_dev_ring_element_type *tr_events;
+	/*
+	 * Start index of the completion event buffer segment
+	 * to be flushed to host
+	 */
+	u32			start;
 	u32			num_events;
 	dma_addr_t		dma;
 	u32			dma_len;
@@ -443,14 +449,23 @@
 	struct mutex			ch_lock;
 	/* client which the current inbound/outbound message is for */
 	struct mhi_dev_client		*active_client;
+	/* Pointer to completion event buffer */
+	union mhi_dev_ring_element_type *tr_events;
+	/* Indices for completion event buffer */
+	uint32_t			evt_buf_rp;
+	uint32_t			evt_buf_wp;
+	uint32_t			evt_buf_size;
 	/*
-	 * Pointer to event request structs used to temporarily store
+	 * Pointer to a block of event request structs used to temporarily store
 	 * completion events and meta data before sending them to host
 	 */
 	struct event_req		*ereqs;
-	/* Pointer to completion event buffers */
-	union mhi_dev_ring_element_type *tr_events;
+	/* Linked list head for event request structs */
 	struct list_head		event_req_buffers;
+	uint32_t				evt_req_size;
+	/* Linked list head for event request structs to be flushed */
+	struct list_head		flush_event_req_buffers;
+	/* Pointer to the currently used event request struct */
 	struct event_req		*curr_ereq;
 
 	/* current TRE being processed */
@@ -533,7 +548,6 @@
 	u32                             ifc_id;
 	struct ep_pcie_hw               *phandle;
 	struct work_struct		pcie_event;
-	struct ep_pcie_msi_config	msi_cfg;
 
 	atomic_t			write_active;
 	atomic_t			is_suspended;
diff --git a/drivers/soc/qcom/dcc_v2.c b/drivers/soc/qcom/dcc_v2.c
index 1e977ca..89dcd97 100644
--- a/drivers/soc/qcom/dcc_v2.c
+++ b/drivers/soc/qcom/dcc_v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2020, 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
@@ -299,19 +299,19 @@
 			ret = dcc_sram_writel(drvdata, addr, sram_offset);
 			if (ret)
 				goto overstep;
-				sram_offset += 4;
+			sram_offset += 4;
 
 			ret = dcc_sram_writel(drvdata,
 					entry->mask, sram_offset);
 			if (ret)
 				goto overstep;
-				sram_offset += 4;
+			sram_offset += 4;
 
 			ret = dcc_sram_writel(drvdata,
 					entry->write_val, sram_offset);
 			if (ret)
 				goto overstep;
-				sram_offset += 4;
+			sram_offset += 4;
 			addr = 0;
 			break;
 		}
@@ -394,18 +394,18 @@
 			ret = dcc_sram_writel(drvdata, addr, sram_offset);
 			if (ret)
 				goto overstep;
-				sram_offset += 4;
+			sram_offset += 4;
 
 			ret = dcc_sram_writel(drvdata, link, sram_offset);
 			if (ret)
 				goto overstep;
-				sram_offset += 4;
+			sram_offset += 4;
 
 			ret = dcc_sram_writel(drvdata,
 				entry->write_val, sram_offset);
 			if (ret)
 				goto overstep;
-				sram_offset += 4;
+			sram_offset += 4;
 			addr = 0x00;
 			link = 0;
 			break;
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 3d98684..e6700b8 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -54,6 +54,10 @@
 #include "dbm.h"
 #include "debug.h"
 #include "xhci.h"
+#ifdef CONFIG_TUSB1064_XR_MISC
+#include "../../misc/tusb1064.h"
+#endif
+
 
 #define SDP_CONNETION_CHECK_TIME 10000 /* in ms */
 
@@ -2956,9 +2960,13 @@
 				EXTCON_PROP_USB_TYPEC_POLARITY, &val);
 		if (ret)
 			mdwc->typec_orientation = ORIENTATION_NONE;
-		else
+		else {
 			mdwc->typec_orientation = val.intval ?
 					ORIENTATION_CC2 : ORIENTATION_CC1;
+#ifdef CONFIG_TUSB1064_XR_MISC
+			tusb1064_usb_event(val.intval ? true : false);
+#endif
+		}
 
 		dbg_event(0xFF, "cc_state", mdwc->typec_orientation);
 
diff --git a/drivers/usb/phy/phy-msm-qusb.c b/drivers/usb/phy/phy-msm-qusb.c
index 9d66366..88a0dee 100644
--- a/drivers/usb/phy/phy-msm-qusb.c
+++ b/drivers/usb/phy/phy-msm-qusb.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018, 2020, 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
@@ -1029,7 +1029,7 @@
 			qphy->iface_clk = NULL;
 		if (ret == -EPROBE_DEFER)
 			return ret;
-			dev_err(dev, "couldn't get iface_clk(%d)\n", ret);
+		dev_err(dev, "couldn't get iface_clk(%d)\n", ret);
 		}
 	}
 
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index c1b0289..e165e56 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -479,23 +479,24 @@
 		if (io->io_bio)
 			gfp_flags = GFP_NOWAIT | __GFP_NOWARN;
 	retry_encrypt:
-	if (!fscrypt_using_hardware_encryption(inode))
-		data_page = fscrypt_encrypt_page(inode, page, PAGE_SIZE, 0,
-						page->index, gfp_flags);
-		if (IS_ERR(data_page)) {
-			ret = PTR_ERR(data_page);
-			if (ret == -ENOMEM &&
-			    (io->io_bio || wbc->sync_mode == WB_SYNC_ALL)) {
-				gfp_flags = GFP_NOFS;
-				if (io->io_bio)
-					ext4_io_submit(io);
-				else
-					gfp_flags |= __GFP_NOFAIL;
-				congestion_wait(BLK_RW_ASYNC, HZ/50);
-				goto retry_encrypt;
+		if (!fscrypt_using_hardware_encryption(inode)) {
+			data_page = fscrypt_encrypt_page(inode, page,
+				 PAGE_SIZE, 0, page->index, gfp_flags);
+			if (IS_ERR(data_page)) {
+				ret = PTR_ERR(data_page);
+				if (ret == -ENOMEM && (io->io_bio ||
+					wbc->sync_mode == WB_SYNC_ALL)) {
+					gfp_flags = GFP_NOFS;
+					if (io->io_bio)
+						ext4_io_submit(io);
+					else
+						gfp_flags |= __GFP_NOFAIL;
+					congestion_wait(BLK_RW_ASYNC, HZ/50);
+					goto retry_encrypt;
+				}
+				data_page = NULL;
+				goto out;
 			}
-			data_page = NULL;
-			goto out;
 		}
 	}
 
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index 9e9408d..2ccbda2 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -148,10 +148,10 @@
  * a new RANGE of SSIDs to the msg_mask_tbl.
  */
 #define MSG_MASK_TBL_CNT		26
-#define APPS_EVENT_LAST_ID		0xCC1
+#define APPS_EVENT_LAST_ID		0xCC2
 
 #define MSG_SSID_0			0
-#define MSG_SSID_0_LAST			132
+#define MSG_SSID_0_LAST			134
 #define MSG_SSID_1			500
 #define MSG_SSID_1_LAST			506
 #define MSG_SSID_2			1000
@@ -363,7 +363,9 @@
 	MSG_LVL_HIGH,
 	MSG_LVL_HIGH,
 	MSG_LVL_LOW | MSG_LVL_MED | MSG_LVL_HIGH | MSG_LVL_ERROR,
-	MSG_LVL_HIGH
+	MSG_LVL_HIGH,
+	MSG_LVL_LOW,
+	MSG_LVL_LOW
 };
 
 static const uint32_t msg_bld_masks_1[] = {
@@ -925,7 +927,7 @@
 /* LOG CODES */
 static const uint32_t log_code_last_tbl[] = {
 	0x0,	/* EQUIP ID 0 */
-	0x1CD6,	/* EQUIP ID 1 */
+	0x1CDD,	/* EQUIP ID 1 */
 	0x0,	/* EQUIP ID 2 */
 	0x0,	/* EQUIP ID 3 */
 	0x4910,	/* EQUIP ID 4 */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index fbbe3e8..db31d9f 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -48,6 +48,9 @@
 /* Indicate support for including KEK length in rekey data */
 #define CFG80211_REKEY_DATA_KEK_LEN 1
 
+/* Indicate backport support for key configuration for Beacon protection*/
+#define CFG80211_BIGTK_CONFIGURATION_SUPPORT 1
+
 /**
  * Indicate backport support for the new cfg80211_roamed event which unifies the
  * old APIs cfg80211_roamed and cfg80211_roamed_bss and takes a structure to
@@ -2688,6 +2691,8 @@
  * @set_default_key: set the default key on an interface
  *
  * @set_default_mgmt_key: set the default management frame key on an interface
+
+ * @set_default_beacon_key: set the default Beacon frame key on an interface
  *
  * @set_rekey_data: give the data necessary for GTK rekeying to the driver
  *
@@ -2991,6 +2996,9 @@
 	int	(*set_default_mgmt_key)(struct wiphy *wiphy,
 					struct net_device *netdev,
 					u8 key_index);
+	int	(*set_default_beacon_key)(struct wiphy *wiphy,
+					  struct net_device *netdev,
+					  u8 key_index);
 
 	int	(*start_ap)(struct wiphy *wiphy, struct net_device *dev,
 			    struct cfg80211_ap_settings *settings);
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index 8878609..6dca52c 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -4,9 +4,6 @@
 no-export-headers += a.out.h
 endif
 
-header-y += hbtp_input.h
-header-y += qbt1000.h
-
 ifeq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/uapi/asm/kvm.h),)
 no-export-headers += kvm.h
 endif
@@ -37,13 +34,6 @@
 no-export-headers += userio.h
 no-export-headers += wil6210_uapi.h
 
-header-y += mhi.h
-header-y += sockev.h
-header-y += nfc/
-header-y += seemp_api.h
-header-y += seemp_param_id.h
-
 ifneq ($(VSERVICES_SUPPORT), "")
 include include/linux/Kbuild.vservices
 endif
-header-y += okl4-link-shbuf.h
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 17f1635..1cef158 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4164,6 +4164,10 @@
  * @NL80211_KEY_DEFAULT_TYPES: A nested attribute containing flags
  *	attributes, specifying what a key should be set as default as.
  *	See &enum nl80211_key_default_types.
+ * @NL80211_KEY_MODE: the mode from enum nl80211_key_mode.
+ *	Defaults to @NL80211_KEY_RX_TX.
+ * @NL80211_KEY_DEFAULT_BEACON: flag indicating default Beacon frame key
+ *
  * @__NL80211_KEY_AFTER_LAST: internal
  * @NL80211_KEY_MAX: highest key attribute
  */
@@ -4177,6 +4181,8 @@
 	NL80211_KEY_DEFAULT_MGMT,
 	NL80211_KEY_TYPE,
 	NL80211_KEY_DEFAULT_TYPES,
+	NL80211_KEY_MODE,
+	NL80211_KEY_DEFAULT_BEACON,
 
 	/* keep last */
 	__NL80211_KEY_AFTER_LAST,
@@ -5125,6 +5131,26 @@
  * @NL80211_EXT_FEATURE_AP_PMKSA_CACHING: Driver/device supports PMKSA caching
  *	(set/del PMKSA operations) in AP mode.
  *
+ * @NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD: Driver supports
+ *	filtering of sched scan results using band specific RSSI thresholds.
+ *
+ * @NL80211_EXT_FEATURE_STA_TX_PWR: This driver supports controlling tx power
+ *	to a station.
+ *
+ * @NL80211_EXT_FEATURE_SAE_OFFLOAD: Device wants to do SAE authentication in
+ *	station mode (SAE password is passed as part of the connect command).
+ *
+ * @NL80211_EXT_FEATURE_VLAN_OFFLOAD: The driver supports a single netdev
+ *	with VLAN tagged frames and separate VLAN-specific netdevs added using
+ *	vconfig similarly to the Ethernet case.
+ *
+ * @NL80211_EXT_FEATURE_AQL: The driver supports the Airtime Queue Limit (AQL)
+ *	feature, which prevents bufferbloat by using the expected transmission
+ *	time to limit the amount of data buffered in the hardware.
+ *
+ * @NL80211_EXT_FEATURE_BEACON_PROTECTION: The driver supports Beacon protection
+ *	and can receive key configuration for BIGTK using key indexes 6 and 7.
+ *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
  */
@@ -5164,6 +5190,13 @@
 	NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER,
 	NL80211_EXT_FEATURE_AIRTIME_FAIRNESS,
 	NL80211_EXT_FEATURE_AP_PMKSA_CACHING,
+	NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD,
+	NL80211_EXT_FEATURE_EXT_KEY_ID,
+	NL80211_EXT_FEATURE_STA_TX_PWR,
+	NL80211_EXT_FEATURE_SAE_OFFLOAD,
+	NL80211_EXT_FEATURE_VLAN_OFFLOAD,
+	NL80211_EXT_FEATURE_AQL,
+	NL80211_EXT_FEATURE_BEACON_PROTECTION,
 
 	/* add new features before the definition below */
 	NUM_NL80211_EXT_FEATURES,
diff --git a/kernel/audit.c b/kernel/audit.c
index f98476d..7d9b52a 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -908,9 +908,9 @@
 			}
 			if (audit_enabled != AUDIT_OFF)
 				audit_log_config_change("audit_pid", new_pid, audit_pid, 1);
+			mutex_lock(&audit_sock_mutex);
 			audit_pid = new_pid;
 			audit_nlk_portid = NETLINK_CB(skb).portid;
-			mutex_lock(&audit_sock_mutex);
 			audit_sock = skb->sk;
 			mutex_unlock(&audit_sock_mutex);
 		}
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index e2f1d27..0ed63b8 100755
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -2338,7 +2338,7 @@
 #else /* CONFIG_SCHED_WALT */
 static inline u64 sched_ktime_clock(void)
 {
-	return 0;
+	return sched_clock();
 }
 static inline void note_task_waking(struct task_struct *p, u64 wallclock) { }
 #endif /* CONFIG_SCHED_WALT */
@@ -2371,16 +2371,20 @@
 static inline void cpufreq_update_util(struct rq *rq, unsigned int flags)
 {
 	struct update_util_data *data;
+	u64 clock;
 
 #ifdef CONFIG_SCHED_WALT
 	if (!(flags & SCHED_CPUFREQ_WALT))
 		return;
+	clock = sched_ktime_clock();
+#else
+	clock = rq_clock(rq);
 #endif
 
 	data = rcu_dereference_sched(*per_cpu_ptr(&cpufreq_update_util_data,
 					cpu_of(rq)));
 	if (data)
-		data->func(data, sched_ktime_clock(), flags);
+		data->func(data, clock, flags);
 }
 
 static inline void cpufreq_update_this_cpu(struct rq *rq, unsigned int flags)
diff --git a/net/ipc_router/ipc_router_core.c b/net/ipc_router/ipc_router_core.c
index 8b432ae..90f1024 100644
--- a/net/ipc_router/ipc_router_core.c
+++ b/net/ipc_router/ipc_router_core.c
@@ -3572,16 +3572,6 @@
 			ipc_router_destroy_rport(rport_ptr);
 		}
 
-		if (port_ptr->type == SERVER_PORT) {
-			memset(&msg, 0, sizeof(msg));
-			msg.cmd = IPC_ROUTER_CTRL_CMD_REMOVE_SERVER;
-			msg.srv.service = port_ptr->port_name.service;
-			msg.srv.instance = port_ptr->port_name.instance;
-			msg.srv.node_id = port_ptr->this_port.node_id;
-			msg.srv.port_id = port_ptr->this_port.port_id;
-			broadcast_ctl_msg(&msg);
-		}
-
 		/* Server port could have been a client port earlier.
 		 * Send REMOVE_CLIENT message in either case.
 		 */
@@ -3611,6 +3601,19 @@
 						  port_ptr->this_port.node_id,
 						  port_ptr->this_port.port_id);
 		}
+		/**
+		 * released server information from hash table, now
+		 * it is safe to broadcast remove server message so that
+		 * next call to lookup server will not succeed until
+		 * server open the port again
+		 */
+		memset(&msg, 0, sizeof(msg));
+		msg.cmd = IPC_ROUTER_CTRL_CMD_REMOVE_SERVER;
+		msg.srv.service = port_ptr->port_name.service;
+		msg.srv.instance = port_ptr->port_name.instance;
+		msg.srv.node_id = port_ptr->this_port.node_id;
+		msg.srv.port_id = port_ptr->this_port.port_id;
+		broadcast_ctl_msg(&msg);
 	}
 
 	mutex_lock(&port_ptr->port_lock_lhc3);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 94b537f..475d1f5 100755
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -779,7 +779,7 @@
 	struct key_params p;
 	int idx;
 	int type;
-	bool def, defmgmt;
+	bool def, defmgmt, defbeacon;
 	bool def_uni, def_multi;
 };
 
@@ -793,12 +793,13 @@
 
 	k->def = !!tb[NL80211_KEY_DEFAULT];
 	k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
+	k->defbeacon = !!tb[NL80211_KEY_DEFAULT_BEACON];
 
 	if (k->def) {
 		k->def_uni = true;
 		k->def_multi = true;
 	}
-	if (k->defmgmt)
+	if (k->defmgmt || k->defbeacon)
 		k->def_multi = true;
 
 	if (tb[NL80211_KEY_IDX])
@@ -905,10 +906,11 @@
 	if (err)
 		return err;
 
-	if (k->def && k->defmgmt)
+	if ((k->def ? 1 : 0) + (k->defmgmt ? 1 : 0) +
+	    (k->defbeacon ? 1 : 0) > 1)
 		return -EINVAL;
 
-	if (k->defmgmt) {
+	if (k->defmgmt || k->defbeacon) {
 		if (k->def_uni || !k->def_multi)
 			return -EINVAL;
 	}
@@ -917,11 +919,14 @@
 		if (k->defmgmt) {
 			if (k->idx < 4 || k->idx > 5)
 				return -EINVAL;
+		} else if (k->defbeacon) {
+			if (k->idx < 6 || k->idx > 7)
+				return -EINVAL;
 		} else if (k->def) {
 			if (k->idx < 0 || k->idx > 3)
 				return -EINVAL;
 		} else {
-			if (k->idx < 0 || k->idx > 5)
+			if (k->idx < 0 || k->idx > 7)
 				return -EINVAL;
 		}
 	}
@@ -3162,10 +3167,15 @@
 	void *hdr;
 	struct sk_buff *msg;
 
-	if (info->attrs[NL80211_ATTR_KEY_IDX])
+	if (info->attrs[NL80211_ATTR_KEY_IDX]) {
 		key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
+		if (key_idx > 5 &&
+		    !wiphy_ext_feature_isset(&rdev->wiphy,
+			    NL80211_EXT_FEATURE_BEACON_PROTECTION))
+			return -EINVAL;
+	}
 
-	if (key_idx > 5)
+	if (key_idx > 7)
 		return -EINVAL;
 
 	if (info->attrs[NL80211_ATTR_MAC])
@@ -3242,7 +3252,7 @@
 		return -EINVAL;
 
 	/* only support setting default key */
-	if (!key.def && !key.defmgmt)
+	if (!key.def && !key.defmgmt && !key.defbeacon)
 		return -EINVAL;
 
 	wdev_lock(dev->ieee80211_ptr);
@@ -3266,6 +3276,24 @@
 #ifdef CONFIG_CFG80211_WEXT
 		dev->ieee80211_ptr->wext.default_key = key.idx;
 #endif
+	} else if (key.defbeacon) {
+		if (key.def_uni || !key.def_multi) {
+			err = -EINVAL;
+			goto out;
+		}
+
+		if (!rdev->ops->set_default_beacon_key) {
+			err = -EOPNOTSUPP;
+			goto out;
+		}
+
+		err = nl80211_key_allowed(dev->ieee80211_ptr);
+		if (err)
+			goto out;
+
+		err = rdev_set_default_beacon_key(rdev, dev, key.idx);
+		if (err)
+			goto out;
 	} else {
 		if (key.def_uni || !key.def_multi) {
 			err = -EINVAL;
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 8be0578..349c80d 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -135,6 +135,19 @@
 	return ret;
 }
 
+static inline int
+rdev_set_default_beacon_key(struct cfg80211_registered_device *rdev,
+			    struct net_device *netdev, u8 key_index)
+{
+	int ret;
+
+	trace_rdev_set_default_beacon_key(&rdev->wiphy, netdev, key_index);
+	ret = rdev->ops->set_default_beacon_key(&rdev->wiphy, netdev,
+						key_index);
+	trace_rdev_return_int(&rdev->wiphy, ret);
+	return ret;
+}
+
 static inline int rdev_start_ap(struct cfg80211_registered_device *rdev,
 				struct net_device *dev,
 				struct cfg80211_ap_settings *settings)
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 0dc41fd..5d1c8ec 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -1027,9 +1027,16 @@
 	 * Delete all the keys ... pairwise keys can't really
 	 * exist any more anyway, but default keys might.
 	 */
-	if (rdev->ops->del_key)
-		for (i = 0; i < 6; i++)
+	if (rdev->ops->del_key) {
+		int max_key_idx = 5;
+
+		if (wiphy_ext_feature_isset(
+			    wdev->wiphy,
+			    NL80211_EXT_FEATURE_BEACON_PROTECTION))
+			max_key_idx = 7;
+		for (i = 0; i <= max_key_idx; i++)
 			rdev_del_key(rdev, dev, i, false, NULL);
+	}
 
 	rdev_set_qos_map(rdev, dev, NULL);
 
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index ef56df5..42cfc51 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -470,6 +470,23 @@
 		  WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index)
 );
 
+TRACE_EVENT(rdev_set_default_beacon_key,
+	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u8 key_index),
+	TP_ARGS(wiphy, netdev, key_index),
+	TP_STRUCT__entry(
+		WIPHY_ENTRY
+		NETDEV_ENTRY
+		__field(u8, key_index)
+	),
+	TP_fast_assign(
+		WIPHY_ASSIGN;
+		NETDEV_ASSIGN;
+		__entry->key_index = key_index;
+	),
+	TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", key index: %u",
+		  WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->key_index)
+);
+
 TRACE_EVENT(rdev_start_ap,
 	TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
 		 struct cfg80211_ap_settings *settings),
diff --git a/net/wireless/util.c b/net/wireless/util.c
index bdd0b62..e7ea152 100755
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -221,7 +221,12 @@
 				   struct key_params *params, int key_idx,
 				   bool pairwise, const u8 *mac_addr)
 {
-	if (key_idx < 0 || key_idx > 5)
+	int max_key_idx = 5;
+
+	if (wiphy_ext_feature_isset(&rdev->wiphy,
+				    NL80211_EXT_FEATURE_BEACON_PROTECTION))
+		max_key_idx = 7;
+	if (key_idx < 0 || key_idx > max_key_idx)
 		return -EINVAL;
 
 	if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))