Merge "input: gpio-matrix-keypad: Accept device name from device node"
diff --git a/AndroidKernel.mk b/AndroidKernel.mk
index 1c2f92c..d48eecd 100644
--- a/AndroidKernel.mk
+++ b/AndroidKernel.mk
@@ -69,7 +69,11 @@
 
 real_cc :=
 ifeq ($(KERNEL_LLVM_SUPPORT),true)
-real_cc := REAL_CC=$(KERNEL_LLVM_BIN) CLANG_TRIPLE=aarch64-linux-gnu-
+  ifeq ($(KERNEL_ARCH), arm64)
+    real_cc := REAL_CC=$(KERNEL_LLVM_BIN) CLANG_TRIPLE=aarch64-linux-gnu-
+  else
+    real_cc := REAL_CC=$(KERNEL_LLVM_BIN) CLANG_TRIPLE=arm-linux-gnueabihf
+  endif
 else
 ifeq ($(strip $(KERNEL_GCC_NOANDROID_CHK)),0)
 KERNEL_CFLAGS := KCFLAGS=-mno-android
diff --git a/Documentation/devicetree/bindings/usb/qcom,usb-gadget.txt b/Documentation/devicetree/bindings/usb/qcom,usb-gadget.txt
new file mode 100644
index 0000000..909df52
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/qcom,usb-gadget.txt
@@ -0,0 +1,22 @@
+Qualcomm Technologies, Inc's USB Gadget
+
+Required properties:
+- compatible: Should be "qcom,usb-gadget".
+- qcom,composition: List of configurations where each is separated by '|'.
+	And each configuration has comma separated list of functions
+	specified as: <f1_name>.<f1_instance_name>,<f2_name>....
+- qcom,vid: VendorId to be used by composite device.
+- qcom,pid: ProductId to be used by composite device.
+
+Optional properties:
+- qcom,class: Class of composite device.
+- qcom,subclass: SubClass of composite device.
+- qcom,protocol: Protocol of composite device.
+
+Examples:
+	usb_gadget {
+		compatible = "qcom,usb-gadget";
+		qcom,composition = "rndis.rndis|ecm.ecm";
+		qcom,vid = <0x05c6>;
+		qcom,pid = <0x9057>;
+	};
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 70e2849..546b158 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts
+++ b/arch/arm/boot/dts/qcom/sa415m-ccard-usb-ep.dts
@@ -1,4 +1,4 @@
-/* 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
@@ -25,3 +25,6 @@
 	qcom,ipa-config-is-auto;
 };
 
+&usb {
+	qcom,gadget-imod-val = <250>;
+};
diff --git a/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi b/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi
index 00564c7..91ebc96 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi
+++ b/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi
@@ -1,4 +1,4 @@
-/* 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
@@ -51,8 +51,7 @@
 &i2c_4 {
 	asm330@6a {
 		reg = <0x6b>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&sensor_enable_default>;
+		asm330-enable-gpio = <&tlmm 90 0x1>;
 	};
 };
 
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 ffbc8de..1e4c7231 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts
+++ b/arch/arm/boot/dts/qcom/sa415m-ttp-usb-ep.dts
@@ -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
@@ -34,3 +34,6 @@
 	qcom,ipa-config-is-auto;
 };
 
+&usb {
+	qcom,gadget-imod-val = <250>;
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi
index 033f8a3..484d29e 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi
@@ -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
@@ -1762,7 +1762,7 @@
 				pins = "gpio90";
 				bias-pull-up;
 				drive-strength = <16>;
-				output-high;
+				output-low;
 			};
 		};
 	};
diff --git a/arch/arm/configs/sa415m-perf_defconfig b/arch/arm/configs/sa415m-perf_defconfig
index 718e4c0..af520d9 100644
--- a/arch/arm/configs/sa415m-perf_defconfig
+++ b/arch/arm/configs/sa415m-perf_defconfig
@@ -321,6 +321,7 @@
 CONFIG_USB_CONFIGFS_F_GSI=y
 CONFIG_USB_CONFIGFS_F_QDSS=y
 CONFIG_USB_CONFIGFS_F_IPC=y
+CONFIG_USB_G_QTI=y
 CONFIG_MMC=y
 CONFIG_MMC_PERF_PROFILING=y
 CONFIG_MMC_PARANOID_SD_INIT=y
@@ -337,6 +338,7 @@
 CONFIG_QCOM_SPS_DMA=y
 CONFIG_UIO=y
 CONFIG_STAGING=y
+CONFIG_ASHMEM=y
 CONFIG_ION=y
 CONFIG_ION_MSM=y
 CONFIG_GSI=y
diff --git a/arch/arm/configs/sa415m_defconfig b/arch/arm/configs/sa415m_defconfig
index 72f4ea3..accaa86 100644
--- a/arch/arm/configs/sa415m_defconfig
+++ b/arch/arm/configs/sa415m_defconfig
@@ -334,6 +334,7 @@
 CONFIG_USB_CONFIGFS_F_GSI=y
 CONFIG_USB_CONFIGFS_F_QDSS=y
 CONFIG_USB_CONFIGFS_F_IPC=y
+CONFIG_USB_G_QTI=y
 CONFIG_MMC=y
 CONFIG_MMC_PERF_PROFILING=y
 CONFIG_MMC_RING_BUFFER=y
@@ -354,6 +355,7 @@
 CONFIG_QCOM_SPS_DMA=y
 CONFIG_UIO=y
 CONFIG_STAGING=y
+CONFIG_ASHMEM=y
 CONFIG_ION=y
 CONFIG_ION_MSM=y
 CONFIG_GSI=y
diff --git a/arch/arm/configs/sdm429-bg-perf_defconfig b/arch/arm/configs/sdm429-bg-perf_defconfig
index 0d6a8ec..c18dadf 100644
--- a/arch/arm/configs/sdm429-bg-perf_defconfig
+++ b/arch/arm/configs/sdm429-bg-perf_defconfig
@@ -13,6 +13,8 @@
 CONFIG_RCU_FAST_NO_HZ=y
 CONFIG_RCU_NOCB_CPU=y
 CONFIG_RCU_NOCB_CPU_ALL=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_CPU_MAX_BUF_SHIFT=13
 CONFIG_CGROUP_FREEZER=y
 CONFIG_CPUSETS=y
@@ -439,6 +441,7 @@
 CONFIG_MSM_L2_SPM=y
 CONFIG_MSM_BOOT_STATS=y
 CONFIG_QCOM_WATCHDOG_V2=y
+CONFIG_QPNP_PBS=y
 CONFIG_QCOM_MEMORY_DUMP_V2=y
 CONFIG_MSM_RPM_SMD=y
 CONFIG_QCOM_BUS_SCALING=y
diff --git a/arch/arm64/boot/dts/qcom/pm660-rpm-regulator.dtsi b/arch/arm64/boot/dts/qcom/pm660-rpm-regulator.dtsi
index 5896615..ca12f71 100644
--- a/arch/arm64/boot/dts/qcom/pm660-rpm-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm660-rpm-regulator.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-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
@@ -16,7 +16,7 @@
 		qcom,resource-name = "smpa";
 		qcom,resource-id = <1>;
 		qcom,regulator-type = <1>;
-		qcom,hpm-min-load = <100000>;
+		qcom,hpm-min-load = <400000>;
 		status = "disabled";
 
 		regulator-s1 {
@@ -32,7 +32,7 @@
 		qcom,resource-name = "smpa";
 		qcom,resource-id = <2>;
 		qcom,regulator-type = <1>;
-		qcom,hpm-min-load = <100000>;
+		qcom,hpm-min-load = <400000>;
 		status = "disabled";
 
 		regulator-s2 {
@@ -96,7 +96,7 @@
 		qcom,resource-name = "smpa";
 		qcom,resource-id = <6>;
 		qcom,regulator-type = <1>;
-		qcom,hpm-min-load = <100000>;
+		qcom,hpm-min-load = <400000>;
 		status = "disabled";
 
 		regulator-s6 {
diff --git a/arch/arm64/boot/dts/qcom/sdm450-camera-sensor-qrd.dtsi b/arch/arm64/boot/dts/qcom/sdm450-camera-sensor-qrd.dtsi
new file mode 100644
index 0000000..0d62d8c
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm450-camera-sensor-qrd.dtsi
@@ -0,0 +1,232 @@
+/*
+ * 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.
+ */
+
+&cci {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	actuator0: qcom,actuator@0 {
+		cell-index = <0>;
+		reg = <0x0>;
+		compatible = "qcom,actuator";
+		qcom,cci-master = <0>;
+		cam_vaf-supply = <&pm8953_l17>;
+		qcom,cam-vreg-name = "cam_vaf";
+		qcom,cam-vreg-min-voltage = <2850000>;
+		qcom,cam-vreg-max-voltage = <2850000>;
+		qcom,cam-vreg-op-mode = <80000>;
+	};
+
+	eeprom0: qcom,eeprom@0 {
+		cell-index = <0>;
+		compatible = "qcom,eeprom";
+		qcom,cci-master = <0>;
+		reg = <0x0>;
+		cam_vio-supply = <&pm8953_l6>;
+		cam_vdig-supply = <&pm8953_l23>;
+		cam_vaf-supply = <&pm8953_l17>;
+		qcom,cam-vreg-name = "cam_vio", "cam_vdig", "cam_vaf";
+		qcom,cam-vreg-min-voltage = <0 1200000 2850000>;
+		qcom,cam-vreg-max-voltage = <0 1200000 2850000>;
+		qcom,cam-vreg-op-mode = <0 105000 100000>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_default
+				&cam_sensor_rear_default
+				&cam_sensor_rear_vana>;
+		pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep
+				&cam_sensor_rear_vana_sleep>;
+		gpios = <&tlmm 26 0>,
+			<&tlmm 40 0>,
+			<&tlmm 39 0>,
+			<&tlmm 134 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-vana = <3>;
+		qcom,gpio-req-tbl-num = <0 1 2 3>;
+		qcom,gpio-req-tbl-flags = <1 0 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+					"CAM_RESET0",
+					"CAM_STANDBY0",
+					"CAM_VANA";
+		status = "ok";
+		clocks = <&clock_gcc clk_mclk0_clk_src>,
+				<&clock_gcc clk_gcc_camss_mclk0_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <19200000 0>;
+	};
+
+	eeprom2: qcom,eeprom@2 {
+		cell-index = <2>;
+		reg = <0x2>;
+		compatible = "qcom,eeprom";
+		qcom,cci-master = <1>;
+		cam_vdig-supply = <&pm8953_l23>;
+		cam_vana-supply = <&pm8953_l22>;
+		cam_vio-supply = <&pm8953_l6>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+		qcom,cam-vreg-min-voltage = <1200000 0 2800000>;
+		qcom,cam-vreg-max-voltage = <1200000 0 2800000>;
+		qcom,cam-vreg-op-mode = <105000 0 80000>;
+		qcom,gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_default
+						&cam_sensor_front1_default>;
+		pinctrl-1 = <&cam_sensor_mclk1_sleep &cam_sensor_front1_sleep>;
+		gpios = <&tlmm 27 0>,
+			<&tlmm 129 0>,
+			<&tlmm 130 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+					  "CAM_RESET2",
+					  "CAM_STANDBY2";
+		qcom,sensor-mode = <0>;
+		status = "ok";
+		clocks = <&clock_gcc clk_mclk1_clk_src>,
+			<&clock_gcc clk_gcc_camss_mclk1_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <19200000 0>;
+	};
+
+	qcom,camera@0 {
+		cell-index = <0>;
+		compatible = "qcom,camera";
+		reg = <0x0>;
+		qcom,csiphy-sd-index = <0>;
+		qcom,csid-sd-index = <0>;
+		qcom,mount-angle = <90>;
+		qcom,led-flash-src = <&led_flash0>;
+		qcom,eeprom-src = <&eeprom0>;
+		qcom,actuator-src = <&actuator0>;
+		cam_vio-supply = <&pm8953_l6>;
+		cam_vdig-supply = <&pm8953_l23>;
+		cam_vaf-supply = <&pm8953_l17>;
+		cam_vana-supply = <&pm8953_l22>;
+		qcom,cam-vreg-name = "cam_vio", "cam_vdig", "cam_vaf",
+						"cam_vana";
+		qcom,cam-vreg-min-voltage = <0 1200000 2850000 2800000>;
+		qcom,cam-vreg-max-voltage = <0 1200000 2850000 2800000>;
+		qcom,cam-vreg-op-mode = <0 105000 100000 80000>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_default
+				&cam_sensor_rear_default
+				&cam_sensor_rear_vana>;
+		pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep
+				&cam_sensor_rear_vana_sleep>;
+		gpios = <&tlmm 26 0>,
+			<&tlmm 40 0>,
+			<&tlmm 39 0>,
+			<&tlmm 134 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-vana = <3>;
+		qcom,gpio-req-tbl-num = <0 1 2 3>;
+		qcom,gpio-req-tbl-flags = <1 0 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+			"CAM_RESET0",
+			"CAM_STANDBY0",
+			"CAM_VANA";
+		qcom,sensor-position = <0>;
+		qcom,sensor-mode = <0>;
+		qcom,cci-master = <0>;
+		status = "ok";
+		clocks = <&clock_gcc clk_mclk0_clk_src>,
+				<&clock_gcc clk_gcc_camss_mclk0_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <24000000 0>;
+	};
+
+	qcom,camera@1 {
+		cell-index = <1>;
+		compatible = "qcom,camera";
+		reg = <0x1>;
+		qcom,csiphy-sd-index = <1>;
+		qcom,csid-sd-index = <1>;
+		qcom,mount-angle = <90>;
+		cam_vdig-supply = <&pm8953_l23>;
+		cam_vana-supply = <&pm8953_l22>;
+		cam_vio-supply = <&pm8953_l6>;
+		cam_vaf-supply = <&pm8953_l17>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+							"cam_vaf";
+		qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_default
+				&cam_sensor_front_default>;
+		pinctrl-1 = <&cam_sensor_mclk2_sleep
+				&cam_sensor_front_sleep>;
+		gpios = <&tlmm 28 0>,
+			<&tlmm 131 0>,
+			<&tlmm 132 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK1",
+			"CAM_RESET1",
+			"CAM_STANDBY1";
+		qcom,sensor-position = <1>;
+		qcom,sensor-mode = <0>;
+		qcom,cci-master = <0>;
+		status = "disabled";
+		clocks = <&clock_gcc clk_mclk2_clk_src>,
+				<&clock_gcc clk_gcc_camss_mclk2_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <24000000 0>;
+	};
+
+	qcom,camera@2 {
+		cell-index = <2>;
+		compatible = "qcom,camera";
+		reg = <0x02>;
+		qcom,csiphy-sd-index = <2>;
+		qcom,csid-sd-index = <2>;
+		qcom,mount-angle = <270>;
+		qcom,eeprom-src = <&eeprom2>;
+		cam_vdig-supply = <&pm8953_l23>;
+		cam_vana-supply = <&pm8953_l22>;
+		cam_vio-supply = <&pm8953_l6>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+		qcom,cam-vreg-min-voltage = <1200000 0 2800000>;
+		qcom,cam-vreg-max-voltage = <1200000 0 2800000>;
+		qcom,cam-vreg-op-mode = <105000 0 80000>;
+		qcom,gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_default
+				&cam_sensor_front1_default>;
+		pinctrl-1 = <&cam_sensor_mclk1_sleep
+				&cam_sensor_front1_sleep>;
+		gpios = <&tlmm 27 0>,
+			<&tlmm 129 0>,
+			<&tlmm 130 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+					  "CAM_RESET2",
+					  "CAM_STANDBY2";
+		qcom,sensor-position = <1>;
+		qcom,sensor-mode = <0>;
+		qcom,cci-master = <1>;
+		status = "ok";
+		clocks = <&clock_gcc clk_mclk1_clk_src>,
+			<&clock_gcc clk_gcc_camss_mclk1_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <24000000 0>;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm450-qrd-sku4.dtsi b/arch/arm64/boot/dts/qcom/sdm450-qrd-sku4.dtsi
index 004411f..e5097e6 100644
--- a/arch/arm64/boot/dts/qcom/sdm450-qrd-sku4.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm450-qrd-sku4.dtsi
@@ -1,5 +1,5 @@
 /*
- * 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
@@ -13,7 +13,7 @@
 
 #include "msm8953-qrd.dtsi"
 #include "msm8953-mdss-panels.dtsi"
-#include "msm8953-camera-sensor-qrd.dtsi"
+#include "sdm450-camera-sensor-qrd.dtsi"
 
 &qusb_phy {
 	qcom,qusb-phy-init-seq = <0x78 0x80
diff --git a/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-svr.dtsi b/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-svr.dtsi
index bdc13b4..a6535ac 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-svr.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-svr.dtsi
@@ -39,7 +39,16 @@
 		flash-source = <&pm660l_flash2>;
 		torch-source = <&pm660l_torch2>;
 		switch-source = <&pm660l_switch1>;
-		status = "disabled";
+		gpios = <&tlmm 0 0>,
+			<&tlmm 1 0>,
+			<&tlmm 23 0>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags = <0 0 0>;
+		gpio-req-tbl-label = "TCKING_LED_3V3_EN",
+					"TCKING_LED_1V2_EN",
+					"TCKing_LED_EN";
+		gpio-req-tbl-delay = <20 20 20>;
+		status = "ok";
 	};
 
 	actuator_regulator: gpio-regulator@0 {
@@ -350,6 +359,7 @@
 		sensor-position-roll = <270>;
 		sensor-position-pitch = <0>;
 		sensor-position-yaw = <180>;
+		led-flash-src = <&led_flash_front>;
 		cam_vio-supply = <&pm660_l14>;
 		cam_vana-supply = <&pm660l_l3>;
 		cam_vdig-supply = <&pm660_l12>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-670-usb-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-670-usb-common.dtsi
index c53367a..aff49d7 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-670-usb-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-670-usb-common.dtsi
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-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
@@ -143,6 +143,8 @@
 			 0x22c /* QUSB2PHY_SQ_CTRL2 */
 			 0x27c /* QUSB2PHY_DEBUG_CTRL1 */
 			 0x280 /* QUSB2PHY_DEBUG_CTRL2 */
+			 0x284 /* QUSB2PHY_DEBUG_CTRL3 */
+			 0x288 /* QUSB2PHY_DEBUG_CTRL4 */
 			 0x2a0>; /* QUSB2PHY_STAT5 */
 
 		qcom,qusb-phy-init-seq =
diff --git a/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-svr.dtsi b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-svr.dtsi
index 763e91a..ceae92c 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-svr.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-camera-sensor-svr.dtsi
@@ -39,6 +39,12 @@
 		flash-source = <&pmi8998_flash2>;
 		torch-source = <&pmi8998_torch2>;
 		switch-source = <&pmi8998_switch1>;
+		gpios = <&tlmm 90 0>,
+			<&tlmm 40 0>;
+		gpio-req-tbl-num = <0 1>;
+		gpio-req-tbl-flags = <0 0>;
+		gpio-req-tbl-label = "FLASH_EN",
+			"FLASH_NOW";
 		status = "ok";
 	};
 
@@ -408,22 +414,16 @@
 		gpios = <&tlmm 13 0>,
 			<&tlmm 26 0>,
 			<&tlmm 132 0>,
-			<&tlmm 133 0>,
-			<&tlmm 90 0>,
-			<&tlmm 40 0>;
+			<&tlmm 133 0>;
 		gpio-reset = <1>;
 		gpio-vana = <2>;
 		gpio-vdig = <3>;
-		gpio-vio = <4>;
-		gpio-standby = <5>;
-		gpio-req-tbl-num = <0 1 2 3 4 5>;
-		gpio-req-tbl-flags = <1 0 0 0 0 0>;
+		gpio-req-tbl-num = <0 1 2 3>;
+		gpio-req-tbl-flags = <1 0 0 0>;
 		gpio-req-tbl-label = "CAMIF_MCLK0",
 					"CAM_RESET2",
 					"CAM_VANA2",
-					"CAM_VDIG2",
-					"CAM_VIO2",
-					"CAM_STANDBY2";
+					"CAM_VDIG2";
 		sensor-mode = <0>;
 		cci-master = <0>;
 		status = "ok";
diff --git a/drivers/bus/mhi/core/mhi_internal.h b/drivers/bus/mhi/core/mhi_internal.h
index d0bc74b..a2a4359 100644
--- a/drivers/bus/mhi/core/mhi_internal.h
+++ b/drivers/bus/mhi/core/mhi_internal.h
@@ -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
@@ -879,22 +879,9 @@
 irqreturn_t mhi_intvec_handlr(int irq_number, void *dev);
 void mhi_ev_task(unsigned long data);
 
-#ifdef CONFIG_MHI_DEBUG
-
-#define MHI_ASSERT(cond, msg) do { \
+#define MHI_ASSERT(cond, fmt, ...) do { \
 	if (cond) \
-		panic(msg); \
+		panic(fmt); \
 } while (0)
 
-#else
-
-#define MHI_ASSERT(cond, msg) do { \
-	if (cond) { \
-		MHI_ERR(msg); \
-		WARN_ON(cond); \
-	} \
-} while (0)
-
-#endif
-
 #endif /* _MHI_INT_H */
diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c
index eb3a4a9..82a5081 100644
--- a/drivers/bus/mhi/core/mhi_main.c
+++ b/drivers/bus/mhi/core/mhi_main.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
@@ -1111,6 +1111,10 @@
 		complete(&mhi_tsync->completion);
 	} else {
 		chan = MHI_TRE_GET_CMD_CHID(cmd_pkt);
+		if (chan >= mhi_cntrl->max_chan) {
+			MHI_ERR("invalid channel id %u\n", chan);
+			break;
+		}
 		mhi_chan = &mhi_cntrl->mhi_chan[chan];
 		write_lock_bh(&mhi_chan->lock);
 		mhi_chan->ccs = MHI_TRE_GET_EV_CODE(tre);
diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c
index 99c0b9f..e223a8c 100644
--- a/drivers/extcon/extcon.c
+++ b/drivers/extcon/extcon.c
@@ -440,10 +440,11 @@
 		return index;
 
 	spin_lock_irqsave(&edev->lock, flags);
-
 	state = !!(edev->state & BIT(index));
+	spin_unlock_irqrestore(&edev->lock, flags);
 	raw_notifier_call_chain(&edev->nh[index], state, edev);
 
+	spin_lock_irqsave(&edev->lock, flags);
 	/* This could be in interrupt handler */
 	prop_buf = (char *)get_zeroed_page(GFP_ATOMIC);
 	if (!prop_buf) {
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index 1b43282..1783691 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_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
@@ -910,17 +910,34 @@
 	 * The problem is that IB size from the register is the unprocessed size
 	 * of the buffer not the original size, so if we didn't catch this
 	 * buffer being directly used in the RB, then we might not be able to
-	 * dump the whole thing. Print a warning message so we can try to
+	 * dump the whole thing. Try to dump the maximum possible size from the
+	 * IB1 base address till the end of memdesc size so that we dont miss
+	 * what we are interested in. Print a warning message so we can try to
 	 * figure how often this really happens.
 	 */
 
 	if (-ENOENT == find_object(snapshot->ib1base, snapshot->process) &&
 			snapshot->ib1size) {
-		kgsl_snapshot_push_object(snapshot->process, snapshot->ib1base,
-				snapshot->ib1size);
-		KGSL_CORE_ERR(
-		"CP_IB1_BASE not found in the ringbuffer.Dumping %x dwords of the buffer.\n",
-		snapshot->ib1size);
+		struct kgsl_mem_entry *entry;
+		u64 ibsize;
+
+		entry = kgsl_sharedmem_find(snapshot->process,
+				snapshot->ib1base);
+		if (entry == NULL) {
+			KGSL_CORE_ERR(
+				"Can't find a memory entry containing IB1BASE %16llx\n",
+				snapshot->ib1base);
+		} else {
+			ibsize = entry->memdesc.size -
+				(snapshot->ib1base - entry->memdesc.gpuaddr);
+			kgsl_mem_entry_put(entry);
+
+			kgsl_snapshot_push_object(snapshot->process,
+				snapshot->ib1base, ibsize >> 2);
+			KGSL_CORE_ERR(
+				"CP_IB1_BASE is not found in the ringbuffer. Dumping %llx dwords of the buffer\n",
+				ibsize >> 2);
+		}
 	}
 
 	/*
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index 9971fcd..8f3b264 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -398,7 +398,7 @@
 
 	/* bit[12], Low-power state behavior override bit */
 	if ((config->mode & ETM_MODE_LPOVERRIDE) &&
-	    (drvdata->lpoverride == true))
+	    (drvdata->lpoverride == true) && !drvdata->tupwr_disable)
 		config->eventctrl1 |= BIT(12);
 	else
 		config->eventctrl1 &= ~BIT(12);
diff --git a/drivers/iio/imu/st_asm330lhh/st_asm330lhh.h b/drivers/iio/imu/st_asm330lhh/st_asm330lhh.h
index 7b4963d..c582e4f 100644
--- a/drivers/iio/imu/st_asm330lhh/st_asm330lhh.h
+++ b/drivers/iio/imu/st_asm330lhh/st_asm330lhh.h
@@ -237,6 +237,7 @@
 
 	const struct st_asm330lhh_transfer_function *tf;
 	struct st_asm330lhh_transfer_buffer tb;
+	int enable_gpio;
 };
 
 extern const struct dev_pm_ops st_asm330lhh_pm_ops;
diff --git a/drivers/iio/imu/st_asm330lhh/st_asm330lhh_core.c b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_core.c
index 21f1b8d3..623de5d 100644
--- a/drivers/iio/imu/st_asm330lhh/st_asm330lhh_core.c
+++ b/drivers/iio/imu/st_asm330lhh/st_asm330lhh_core.c
@@ -16,6 +16,7 @@
 #include <linux/pm.h>
 #include <linux/version.h>
 #include <linux/of.h>
+#include <linux/of_gpio.h>
 
 #include <linux/platform_data/st_sensors_pdata.h>
 
@@ -68,6 +69,9 @@
 #define ST_ASM330LHH_TEMP_FS_GAIN		(1000000 / ST_ASM330LHH_TEMP_GAIN)
 #define ST_ASM330LHH_OFFSET			(6400)
 
+/**Turn on of sensor in ms*/
+#define ST_ASM330LHH_TURN_ON_TIME		35
+
 struct st_asm330lhh_std_entry {
 	u16 odr;
 	u8 val;
@@ -1028,6 +1032,7 @@
 		       const struct st_asm330lhh_transfer_function *tf_ops)
 {
 	struct st_asm330lhh_hw *hw;
+	struct device_node *np;
 	int i, err;
 
 	hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
@@ -1042,6 +1047,20 @@
 	hw->dev = dev;
 	hw->irq = irq;
 	hw->tf = tf_ops;
+	np = hw->dev->of_node;
+
+	hw->enable_gpio = of_get_named_gpio(np, "asm330-enable-gpio", 0);
+	if (gpio_is_valid(hw->enable_gpio)) {
+		err = gpio_request(hw->enable_gpio, "asm330_enable");
+		if (err < 0) {
+			dev_err(hw->dev,
+					"failed to request gpio %d: %d\n",
+					hw->enable_gpio, err);
+			return err;
+		}
+		gpio_direction_output(hw->enable_gpio, 1);
+		msleep(ST_ASM330LHH_TURN_ON_TIME);
+	}
 
 	dev_info(hw->dev, "Ver: %s\n", ST_ASM330LHH_VERSION);
 	err = st_asm330lhh_check_whoami(hw);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
index 182eec3..8e35686 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
@@ -11,6 +11,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/gpio.h>
 
 #include "cam_sensor_cmn_header.h"
 #include "cam_flash_core.h"
@@ -21,6 +22,10 @@
 static int cam_flash_prepare(struct cam_flash_ctrl *flash_ctrl,
 	bool regulator_enable)
 {
+	struct cam_flash_private_soc *soc_private =
+		(struct cam_flash_private_soc *) flash_ctrl->soc_info
+		.soc_private;
+	struct cam_soc_gpio_data *gpio_conf = soc_private->gpio_data;
 	int rc = 0;
 
 	if (!(flash_ctrl->switch_trigger)) {
@@ -48,6 +53,11 @@
 			return rc;
 		}
 		flash_ctrl->is_regulator_enabled = false;
+	} else if ((gpio_conf != NULL) &&
+		(gpio_conf->cam_gpio_common_tbl_size > 0)) {
+		CAM_INFO(CAM_FLASH,
+			"gpio based flash not need regulator");
+		return rc;
 	} else {
 		CAM_ERR(CAM_FLASH, "Wrong Flash State : %d",
 			flash_ctrl->flash_state);
@@ -380,6 +390,45 @@
 	return rc;
 }
 
+static void cam_flash_set_gpios(struct cam_flash_ctrl *flash_ctrl, bool enable)
+{
+
+	struct cam_flash_private_soc *soc_private =
+		(struct cam_flash_private_soc *) flash_ctrl->soc_info
+		.soc_private;
+	struct cam_soc_gpio_data *gpio_conf = soc_private->gpio_data;
+	int i;
+
+	if (gpio_conf != NULL && gpio_conf->cam_gpio_common_tbl_size > 0) {
+		struct gpio *gpio_tbl = gpio_conf->cam_gpio_req_tbl;
+		int size = (int) gpio_conf->cam_gpio_req_tbl_size;
+
+		if (enable) {
+			for (i = 0; i < size; i++) {
+				CAM_DBG(CAM_FLASH, "enabling gpio %d",
+					gpio_tbl[i].gpio);
+				gpio_set_value_cansleep(gpio_tbl[i].gpio, 1);
+				if (soc_private->gpio_delay_tbl_size > 0) {
+					CAM_DBG(CAM_FLASH, "sleeping for %d ms",
+						soc_private->gpio_delay_tbl[i]);
+					msleep(soc_private->gpio_delay_tbl[i]);
+				}
+			}
+		} else {
+			for (i = size-1; i >= 0; i--) {
+				CAM_DBG(CAM_FLASH, "disabling gpio %d",
+					gpio_tbl[i].gpio);
+				gpio_set_value_cansleep(gpio_tbl[i].gpio, 0);
+				if (soc_private->gpio_delay_tbl_size > 0) {
+					CAM_DBG(CAM_FLASH, "sleeping for %d ms",
+						soc_private->gpio_delay_tbl[i]);
+					msleep(soc_private->gpio_delay_tbl[i]);
+				}
+			}
+		}
+	}
+}
+
 static int cam_flash_ops(struct cam_flash_ctrl *flash_ctrl,
 	struct cam_flash_frame_setting *flash_data, enum camera_flash_opcode op)
 {
@@ -396,6 +445,7 @@
 		flash_ctrl->soc_info.soc_private;
 
 	if (op == CAMERA_SENSOR_FLASH_OP_FIRELOW) {
+		cam_flash_set_gpios(flash_ctrl, true);
 		for (i = 0; i < flash_ctrl->torch_num_sources; i++) {
 			if (flash_ctrl->torch_trigger[i]) {
 				max_current = soc_private->torch_max_current[i];
@@ -455,6 +505,7 @@
 		cam_res_mgr_led_trigger_event(flash_ctrl->switch_trigger,
 			(enum led_brightness)LED_SWITCH_OFF);
 
+	cam_flash_set_gpios(flash_ctrl, false);
 	flash_ctrl->flash_state = CAM_FLASH_STATE_START;
 	return 0;
 }
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.h
index 6a1ce99..52934ba 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_dev.h
@@ -136,6 +136,9 @@
  * @torch_trigger_name  : Torch trigger name array
  * @torch_op_current    : Torch operational current
  * @torch_max_current   : Max supported current for LED in torch mode
+ * @gpio_data           : GPIO info
+ * @gpio_delay_tbl      : Sleep times after enabling/disabling GPIOs
+ * @gpio_delay_tbl_size : Number of elements in cam_gpio_delay_tbl
  */
 
 struct cam_flash_private_soc {
@@ -147,6 +150,9 @@
 	const char   *torch_trigger_name[CAM_FLASH_MAX_LED_TRIGGERS];
 	uint32_t     torch_op_current[CAM_FLASH_MAX_LED_TRIGGERS];
 	uint32_t     torch_max_current[CAM_FLASH_MAX_LED_TRIGGERS];
+	struct cam_soc_gpio_data *gpio_data;
+	uint32_t     *gpio_delay_tbl;
+	uint8_t      gpio_delay_tbl_size;
 };
 
 struct cam_flash_func_tbl {
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_soc.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_soc.c
index 22a124d..72fc63a 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_soc.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_soc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -15,6 +15,262 @@
 #include "cam_flash_soc.h"
 #include "cam_res_mgr_api.h"
 
+static int cam_flash_get_dt_gpio_req_tbl(struct device_node *of_node,
+	struct cam_soc_gpio_data *gconf,
+	uint16_t *gpio_array,
+	uint16_t gpio_array_size)
+{
+	int32_t rc = 0, i = 0;
+	uint32_t count = 0;
+	uint32_t *val_array = NULL;
+
+	if (!of_get_property(of_node, "gpio-req-tbl-num", &count))
+		return 0;
+
+	count /= sizeof(uint32_t);
+	if (!count) {
+		CAM_DBG(CAM_FLASH, "gpio-req-tbl-num 0");
+		return 0;
+	}
+
+	val_array = kcalloc(count, sizeof(uint32_t), GFP_KERNEL);
+	if (!val_array)
+		return -ENOMEM;
+
+	gconf->cam_gpio_req_tbl = kcalloc(count, sizeof(struct gpio),
+		GFP_KERNEL);
+	if (!gconf->cam_gpio_req_tbl) {
+		rc = -ENOMEM;
+		goto free_val_array;
+	}
+	gconf->cam_gpio_req_tbl_size = count;
+
+	rc = of_property_read_u32_array(of_node, "gpio-req-tbl-num",
+		val_array, count);
+	if (rc) {
+		CAM_ERR(CAM_FLASH,
+			"failed in reading gpio-req-tbl-num, rc = %d",
+			rc);
+		goto free_gpio_req_tbl;
+	}
+
+	for (i = 0; i < count; i++) {
+		if (val_array[i] >= gpio_array_size) {
+			CAM_ERR(CAM_FLASH, "gpio req tbl index %d invalid",
+				val_array[i]);
+			goto free_gpio_req_tbl;
+		}
+		gconf->cam_gpio_req_tbl[i].gpio = gpio_array[val_array[i]];
+		CAM_DBG(CAM_FLASH, "cam_gpio_req_tbl[%d].gpio = %d", i,
+			gconf->cam_gpio_req_tbl[i].gpio);
+	}
+
+	rc = of_property_read_u32_array(of_node, "gpio-req-tbl-flags",
+		val_array, count);
+	if (rc) {
+		CAM_ERR(CAM_FLASH, "Failed in gpio-req-tbl-flags, rc %d", rc);
+		goto free_gpio_req_tbl;
+	}
+
+	for (i = 0; i < count; i++) {
+		gconf->cam_gpio_req_tbl[i].flags = val_array[i];
+		CAM_DBG(CAM_FLASH, "cam_gpio_req_tbl[%d].flags = %ld", i,
+			gconf->cam_gpio_req_tbl[i].flags);
+	}
+
+	for (i = 0; i < count; i++) {
+		rc = of_property_read_string_index(of_node,
+			"gpio-req-tbl-label", i,
+			&gconf->cam_gpio_req_tbl[i].label);
+		if (rc) {
+			CAM_ERR(CAM_FLASH, "Failed rc %d", rc);
+			goto free_gpio_req_tbl;
+		}
+		CAM_DBG(CAM_FLASH, "cam_gpio_req_tbl[%d].label = %s", i,
+			gconf->cam_gpio_req_tbl[i].label);
+	}
+
+	kfree(val_array);
+
+	return rc;
+
+free_gpio_req_tbl:
+	kfree(gconf->cam_gpio_req_tbl);
+free_val_array:
+	kfree(val_array);
+	gconf->cam_gpio_req_tbl_size = 0;
+
+	return rc;
+}
+
+static int cam_flash_get_dt_gpio_delay_tbl(
+	struct device_node *of_node, struct cam_flash_private_soc *soc_private)
+{
+	int32_t rc = 0, i = 0;
+	uint32_t *val_array = NULL;
+	uint32_t count = 0;
+
+	soc_private->gpio_delay_tbl_size = 0;
+
+	if (!of_get_property(of_node, "gpio-req-tbl-delay", &count))
+		return 0;
+
+	count /= sizeof(uint32_t);
+	if (!count) {
+		CAM_ERR(CAM_FLASH, "gpio-req-tbl-delay 0");
+		return 0;
+	}
+
+	if (count != soc_private->gpio_data->cam_gpio_req_tbl_size) {
+		CAM_ERR(CAM_FLASH,
+			"Invalid number of gpio-req-tbl-delay entries: %d",
+			count);
+		return 0;
+	}
+
+	val_array = kcalloc(count, sizeof(uint32_t), GFP_KERNEL);
+	if (!val_array)
+		return -ENOMEM;
+
+	soc_private->gpio_delay_tbl_size = count;
+
+	rc = of_property_read_u32_array(of_node, "gpio-req-tbl-delay",
+		val_array, count);
+	if (rc) {
+		CAM_ERR(CAM_FLASH, "Failed in gpio-req-tbl-delay, rc %d", rc);
+		goto free_val_array;
+	}
+
+	soc_private->gpio_delay_tbl = val_array;
+
+	for (i = 0; i < count; i++) {
+		CAM_DBG(CAM_FLASH, "gpio_delay_tbl[%d] = %ld", i,
+			soc_private->gpio_delay_tbl[i]);
+	}
+
+	return 0;
+
+free_val_array:
+	kfree(val_array);
+	soc_private->gpio_delay_tbl_size = 0;
+	return rc;
+}
+
+static int cam_flash_get_gpio_info(
+	struct device_node *of_node,
+	struct cam_flash_private_soc *soc_private)
+{
+	int32_t rc = 0, i = 0;
+	uint16_t *gpio_array = NULL;
+	int16_t gpio_array_size = 0;
+	struct cam_soc_gpio_data *gconf = NULL;
+
+	gpio_array_size = of_gpio_count(of_node);
+
+	CAM_DBG(CAM_FLASH, "gpio count %d", gpio_array_size);
+	if (gpio_array_size <= 0)
+		return 0;
+
+	gpio_array = kcalloc(gpio_array_size, sizeof(uint16_t), GFP_KERNEL);
+	if (!gpio_array)
+		goto free_gpio_conf;
+
+	for (i = 0; i < gpio_array_size; i++) {
+		gpio_array[i] = of_get_gpio(of_node, i);
+		CAM_DBG(CAM_FLASH, "gpio_array[%d] = %d", i, gpio_array[i]);
+	}
+
+	gconf = kzalloc(sizeof(*gconf), GFP_KERNEL);
+	if (!gconf)
+		return -ENOMEM;
+
+	rc = cam_flash_get_dt_gpio_req_tbl(of_node, gconf, gpio_array,
+		gpio_array_size);
+	if (rc) {
+		CAM_ERR(CAM_FLASH, "failed in msm_camera_get_dt_gpio_req_tbl");
+		goto free_gpio_array;
+	}
+
+	gconf->cam_gpio_common_tbl = kcalloc(gpio_array_size,
+		sizeof(struct gpio), GFP_KERNEL);
+	if (!gconf->cam_gpio_common_tbl) {
+		rc = -ENOMEM;
+		goto free_gpio_array;
+	}
+
+	for (i = 0; i < gpio_array_size; i++)
+		gconf->cam_gpio_common_tbl[i].gpio = gpio_array[i];
+
+	gconf->cam_gpio_common_tbl_size = gpio_array_size;
+	soc_private->gpio_data = gconf;
+	kfree(gpio_array);
+
+	cam_flash_get_dt_gpio_delay_tbl(of_node, soc_private);
+
+	return rc;
+
+free_gpio_array:
+	kfree(gpio_array);
+free_gpio_conf:
+	kfree(gconf);
+	soc_private->gpio_data = NULL;
+
+	return rc;
+}
+
+static int cam_flash_request_gpio_table(
+	struct cam_flash_private_soc *soc_private, bool gpio_en)
+{
+	int rc = 0, i = 0;
+	uint8_t size = 0;
+	struct cam_soc_gpio_data *gpio_conf =
+		soc_private->gpio_data;
+	struct gpio *gpio_tbl = NULL;
+
+	if (!gpio_conf) {
+		CAM_DBG(CAM_FLASH, "No GPIO entry");
+		return 0;
+	}
+	if (gpio_conf->cam_gpio_common_tbl_size <= 0) {
+		CAM_ERR(CAM_FLASH, "GPIO table size is invalid");
+		return -EINVAL;
+	}
+	size = gpio_conf->cam_gpio_req_tbl_size;
+	gpio_tbl = gpio_conf->cam_gpio_req_tbl;
+
+	if (!gpio_tbl || !size) {
+		CAM_ERR(CAM_FLASH, "Invalid gpio_tbl %pK / size %d",
+			gpio_tbl, size);
+		return -EINVAL;
+	}
+	for (i = 0; i < size; i++) {
+		CAM_DBG(CAM_FLASH,
+			"cam_flash_request_gpio_table: i=%d, gpio=%d dir=%ld",
+			i,
+			gpio_tbl[i].gpio,
+			gpio_tbl[i].flags);
+	}
+	if (gpio_en) {
+		for (i = 0; i < size; i++) {
+			rc = gpio_request_one(gpio_tbl[i].gpio,
+				gpio_tbl[i].flags, gpio_tbl[i].label);
+			if (rc) {
+				/*
+				 * After GPIO request fails, contine to
+				 * apply new gpios, outout a error message
+				 * for driver bringup debug
+				 */
+				CAM_ERR(CAM_FLASH, "gpio %d:%s request fails",
+					gpio_tbl[i].gpio, gpio_tbl[i].label);
+			}
+		}
+	} else {
+		gpio_free_array(gpio_tbl, size);
+	}
+
+	return rc;
+}
+
 static int32_t cam_get_source_node_info(
 	struct device_node *of_node,
 	struct cam_flash_ctrl *fctrl,
@@ -179,6 +435,15 @@
 		}
 	}
 
+	(void) cam_flash_get_gpio_info(of_node, soc_private);
+	if (soc_private->gpio_data != NULL) {
+		rc = cam_flash_request_gpio_table(soc_private, true);
+		if (rc < 0)
+			CAM_ERR(CAM_FLASH,
+			"Failed in request gpio table, rc=%d",
+			rc);
+	}
+
 	return rc;
 }
 
@@ -216,6 +481,7 @@
 	return rc;
 
 free_soc_private:
+	cam_flash_request_gpio_table(soc_info->soc_private, false);
 	kfree(soc_info->soc_private);
 	soc_info->soc_private = NULL;
 release_soc_res:
diff --git a/drivers/net/can/spi/qti-can.c b/drivers/net/can/spi/qti-can.c
index 0131148..6c688ed 100644
--- a/drivers/net/can/spi/qti-can.c
+++ b/drivers/net/can/spi/qti-can.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
@@ -143,7 +143,8 @@
 #define IFR_DATA_OFFSET		0x100
 struct can_fw_resp {
 	u8 maj;
-	u8 min;
+	u8 min : 4;
+	u8 sub_min : 4;
 	u8 ver[48];
 } __packed;
 
@@ -255,7 +256,8 @@
 
 struct can_fw_br_resp {
 	u8 maj;
-	u8 min;
+	u8 min : 4;
+	u8 sub_min : 4;
 	u8 ver[32];
 	u8 br_maj;
 	u8 br_min;
@@ -406,16 +408,16 @@
 	} else if (resp->cmd  == CMD_GET_FW_VERSION) {
 		struct can_fw_resp *fw_resp = (struct can_fw_resp *)resp->data;
 
-		dev_info(&priv_data->spidev->dev, "fw %d.%d",
-			 fw_resp->maj, fw_resp->min);
+		dev_info(&priv_data->spidev->dev, "fw %d.%d.%d",
+			 fw_resp->maj, fw_resp->min, fw_resp->sub_min);
 		dev_info(&priv_data->spidev->dev, "fw string %s",
 			 fw_resp->ver);
 	} else if (resp->cmd  == CMD_GET_FW_BR_VERSION) {
 		struct can_fw_br_resp *fw_resp =
 				(struct can_fw_br_resp *)resp->data;
 
-		dev_info(&priv_data->spidev->dev, "fw_can %d.%d",
-			 fw_resp->maj, fw_resp->min);
+		dev_info(&priv_data->spidev->dev, "fw_can %d.%d.%d",
+			 fw_resp->maj, fw_resp->min, fw_resp->sub_min);
 		dev_info(&priv_data->spidev->dev, "fw string %s",
 			 fw_resp->ver);
 		dev_info(&priv_data->spidev->dev, "fw_br %d.%d exec_mode %d",
@@ -425,7 +427,8 @@
 		ret |= (fw_resp->br_maj & 0xF) << 24;
 		ret |= (fw_resp->br_min & 0xFF) << 16;
 		ret |= (fw_resp->maj & 0xF) << 8;
-		ret |= (fw_resp->min & 0xFF);
+		ret |= (fw_resp->min & 0xF) << 4;
+		ret |= (fw_resp->sub_min & 0xF);
 	} else if (resp->cmd == CMD_UPDATE_TIME_INFO) {
 		struct can_time_info *time_data =
 			(struct can_time_info *)resp->data;
diff --git a/drivers/soc/qcom/bg_rsb.c b/drivers/soc/qcom/bg_rsb.c
index c0ed484..6c00677 100644
--- a/drivers/soc/qcom/bg_rsb.c
+++ b/drivers/soc/qcom/bg_rsb.c
@@ -962,13 +962,13 @@
 		return count;
 	}
 
+	rc = split_bg_work(dev, arr);
 	if (!dev->is_cnfgrd) {
 		bgrsb_handle_cmd_in_ssr(dev, arr);
 		kfree(arr);
 		return -ENOMEDIUM;
 	}
 
-	rc = split_bg_work(dev, arr);
 	if (rc != 0)
 		pr_err("Not able to process request\n");
 	kfree(arr);
diff --git a/drivers/soc/qcom/rpm_master_stat.c b/drivers/soc/qcom/rpm_master_stat.c
index efbe033..bf4f5ec 100644
--- a/drivers/soc/qcom/rpm_master_stat.c
+++ b/drivers/soc/qcom/rpm_master_stat.c
@@ -416,7 +416,7 @@
 		if (!pdata->masters[i])
 			goto err;
 		strlcpy(pdata->masters[i], master_name,
-					strlen(pdata->masters[i]) + 1);
+					strlen(master_name) + 1);
 	}
 	return pdata;
 err:
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index d3bab43..3d98684 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.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
@@ -3104,6 +3104,7 @@
 }
 
 static void dwc3_otg_sm_work(struct work_struct *w);
+static int get_psy_type(struct dwc3_msm *mdwc);
 
 static int dwc3_msm_get_clk_gdsc(struct dwc3_msm *mdwc)
 {
@@ -3258,6 +3259,8 @@
 	}
 }
 
+#define DP_PULSE_WIDTH_MSEC 200
+
 static int dwc3_msm_vbus_notifier(struct notifier_block *nb,
 	unsigned long event, void *ptr)
 {
@@ -3270,6 +3273,14 @@
 		return NOTIFY_DONE;
 
 	mdwc->vbus_active = event;
+
+	if (get_psy_type(mdwc) == POWER_SUPPLY_TYPE_USB_CDP &&
+			mdwc->vbus_active) {
+		dev_dbg(mdwc->dev, "Connected to CDP, pull DP up\n");
+		usb_phy_drive_dp_pulse(mdwc->hs_phy, DP_PULSE_WIDTH_MSEC);
+	}
+
+
 	if (dwc->is_drd && !mdwc->in_restart)
 		queue_work(mdwc->dwc3_wq, &mdwc->resume_work);
 
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index ac5b101..2daa8ef 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2735,17 +2735,15 @@
 	struct dwc3_trb *trb;
 	dma_addr_t offset;
 
+	/*
+	 * Doorbell needs to be rung with the next TRB that is going to be
+	 * processed by hardware.
+	 * So, if 'n'th TRB got completed then ring doorbell with (n+1) TRB.
+	 */
+	dwc3_ep_inc_trb(dep, &dep->trb_dequeue);
 	trb = &dep->trb_pool[dep->trb_dequeue];
-	while (trb->ctrl & DWC3_TRBCTL_LINK_TRB) {
-		dwc3_ep_inc_trb(dep, &dep->trb_dequeue);
-		trb = &dep->trb_pool[dep->trb_dequeue];
-	}
-
-	if (!(trb->ctrl & DWC3_TRB_CTRL_HWO)) {
-		offset = dwc3_trb_dma_offset(dep, trb);
-		usb_gsi_ep_op(ep, (void *)&offset, GSI_EP_OP_UPDATE_DB);
-		dwc3_ep_inc_trb(dep, &dep->trb_dequeue);
-	}
+	offset = dwc3_trb_dma_offset(dep, trb);
+	usb_gsi_ep_op(ep, (void *)&offset, GSI_EP_OP_UPDATE_DB);
 }
 
 static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc,
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c
index 51413dc..f252d32 100644
--- a/drivers/usb/gadget/function/f_gsi.c
+++ b/drivers/usb/gadget/function/f_gsi.c
@@ -2429,9 +2429,12 @@
 {
 	struct f_gsi	 *gsi = func_to_gsi(f);
 	struct f_gsi	 *gsi_rmnet_v2x = __gsi[USB_PROT_RMNET_V2X_IPA];
+	struct f_gsi	 *gsi_ecm = __gsi[USB_PROT_ECM_IPA];
 	struct usb_composite_dev *cdev = f->config->cdev;
 	struct net_device	*net;
 	int ret;
+	int in_intr_num = 0;
+	int out_intr_num = 0;
 
 	log_event_dbg("intf=%u, alt=%u", intf, alt);
 
@@ -2504,21 +2507,49 @@
 			}
 
 			/*
-			 * Configure EPs for GSI. Note that when both RmNet LTE
-			 * (or ECM) and RmNet V2X instances are enabled in a
-			 * composition, configure HW accelerated EPs for V2X
-			 * instance and normal EPs for LTE (or ECM).
+			 * Configure EPs for GSI. Note that:
+			 * 1. In general, configure HW accelerated EPs for all
+			 *    instances.
+			 * 2. If both RmNet LTE and RmNet V2X instances are
+			 *    enabled in a composition, configure HW accelerated
+			 *    EPs for V2X and normal EPs for LTE.
+			 * 3. If RmNet V2X, ECM and ADPL instances are enabled
+			 *    in a composition, configure HW accelerated EPs in
+			 *    both directions for V2X and IN direction for ECM.
+			 *    Configure normal EPs for ECM OUT and ADPL.
 			 */
+			switch (gsi->prot_id) {
+			case USB_PROT_RMNET_IPA:
+				if (!gsi_rmnet_v2x->function.fs_descriptors) {
+					in_intr_num = 2;
+					out_intr_num = 1;
+				}
+				break;
+			case USB_PROT_ECM_IPA:
+				/* If v2x is used then only IN/DL uses GSI EP */
+				if (gsi_rmnet_v2x->function.fs_descriptors) {
+					in_intr_num = 3;
+					out_intr_num = 0;
+				} else {
+					in_intr_num = 2;
+					out_intr_num = 1;
+				}
+				break;
+			case USB_PROT_DIAG_IPA:
+				/* DPL to use normal EP if used with ECM+cv2x */
+				if (!(gsi_ecm->function.fs_descriptors &&
+					gsi_rmnet_v2x->function.fs_descriptors))
+					in_intr_num = 3;
+				break;
+			default:
+				in_intr_num = 2;
+				out_intr_num = 1;
+			}
+
+			/* gsi_configure_ep required only for GSI-IPA EPs */
 			if (gsi->d_port.in_ep &&
 				gsi->prot_id <= USB_PROT_RMNET_V2X_IPA) {
-				if (gsi->prot_id == USB_PROT_DIAG_IPA)
-					gsi->d_port.in_ep->ep_intr_num = 3;
-				else if ((gsi->prot_id == USB_PROT_RMNET_IPA ||
-					 gsi->prot_id == USB_PROT_ECM_IPA) &&
-					 gsi_rmnet_v2x->function.fs_descriptors)
-					gsi->d_port.in_ep->ep_intr_num = 0;
-				else
-					gsi->d_port.in_ep->ep_intr_num = 2;
+				gsi->d_port.in_ep->ep_intr_num = in_intr_num;
 				usb_gsi_ep_op(gsi->d_port.in_ep,
 					&gsi->d_port.in_request,
 						GSI_EP_OP_CONFIG);
@@ -2526,12 +2557,7 @@
 
 			if (gsi->d_port.out_ep &&
 				gsi->prot_id <= USB_PROT_RMNET_V2X_IPA) {
-				if ((gsi->prot_id == USB_PROT_RMNET_IPA ||
-				     gsi->prot_id == USB_PROT_ECM_IPA) &&
-				     gsi_rmnet_v2x->function.fs_descriptors)
-					gsi->d_port.out_ep->ep_intr_num = 0;
-				else
-					gsi->d_port.out_ep->ep_intr_num = 1;
+				gsi->d_port.out_ep->ep_intr_num = out_intr_num;
 				usb_gsi_ep_op(gsi->d_port.out_ep,
 					&gsi->d_port.out_request,
 						GSI_EP_OP_CONFIG);
diff --git a/drivers/usb/gadget/legacy/Kconfig b/drivers/usb/gadget/legacy/Kconfig
index 0b36878..57af7b5 100644
--- a/drivers/usb/gadget/legacy/Kconfig
+++ b/drivers/usb/gadget/legacy/Kconfig
@@ -315,6 +315,16 @@
 	  For more information, see Documentation/usb/gadget_printer.txt
 	  which includes sample code for accessing the device file.
 
+config USB_G_QTI
+	tristate "QTI composite gadget"
+	select USB_LIBCOMPOSITE
+	help
+	  This gadget provides support for multi-configuration
+	  composite device.
+	  Functions can be specified via devicetree properties,
+	  along with PID and PID details which can also also be
+	  updated using kernel commandline using module parameters.
+
 if TTY
 
 config USB_CDC_COMPOSITE
diff --git a/drivers/usb/gadget/legacy/Makefile b/drivers/usb/gadget/legacy/Makefile
index 7f485f2..e186a6f 100644
--- a/drivers/usb/gadget/legacy/Makefile
+++ b/drivers/usb/gadget/legacy/Makefile
@@ -23,6 +23,7 @@
 g_ncm-y				:= ncm.o
 g_acm_ms-y			:= acm_ms.o
 g_tcm_usb_gadget-y		:= tcm_usb_gadget.o
+g_qti_gadget-y			:= qti_gadget.o
 
 obj-$(CONFIG_USB_ZERO)		+= g_zero.o
 obj-$(CONFIG_USB_AUDIO)		+= g_audio.o
@@ -42,3 +43,4 @@
 obj-$(CONFIG_USB_G_NCM)		+= g_ncm.o
 obj-$(CONFIG_USB_G_ACM_MS)	+= g_acm_ms.o
 obj-$(CONFIG_USB_GADGET_TARGET)	+= tcm_usb_gadget.o
+obj-$(CONFIG_USB_G_QTI)		+= g_qti_gadget.o
diff --git a/drivers/usb/gadget/legacy/qti_gadget.c b/drivers/usb/gadget/legacy/qti_gadget.c
new file mode 100644
index 0000000..1093e8c
--- /dev/null
+++ b/drivers/usb/gadget/legacy/qti_gadget.c
@@ -0,0 +1,617 @@
+/*
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/usb/composite.h>
+#include <linux/platform_device.h>
+
+struct qti_usb_function {
+	struct usb_function_instance *fi;
+	struct usb_function *f;
+
+	struct list_head list;
+};
+
+#define MAX_FUNC_NAME_LEN	48
+#define MAX_CFG_NAME_LEN       128
+
+struct qti_usb_config {
+	struct usb_configuration c;
+
+	/* List of functions bound to this config */
+	struct list_head func_list;
+	/* List of qti_usb_functions bound to this config */
+	struct list_head qti_funcs;
+};
+
+struct qti_usb_gadget {
+	struct usb_composite_dev cdev;
+	struct usb_composite_driver composite;
+
+	const char *composition_funcs;
+	bool enabled;
+	struct device *dev;
+};
+
+static char manufacturer_string[256] = "Qualcomm Technologies, Inc";
+module_param_string(manufacturer, manufacturer_string,
+		    sizeof(manufacturer_string), 0644);
+MODULE_PARM_DESC(quirks, "String representing name of manufacturer");
+
+static char product_string[256] = "USB_device_SN:12345";
+module_param_string(product, product_string,
+		    sizeof(product_string), 0644);
+MODULE_PARM_DESC(quirks, "String representing product name");
+
+static char serialno_string[256] = "12345";
+module_param_string(serialno, serialno_string,
+		    sizeof(serialno_string), 0644);
+MODULE_PARM_DESC(quirks, "String representing name of manufacturer");
+
+/* String Table */
+static struct usb_string strings_dev[] = {
+	[USB_GADGET_MANUFACTURER_IDX].s = manufacturer_string,
+	[USB_GADGET_PRODUCT_IDX].s = product_string,
+	[USB_GADGET_SERIAL_IDX].s = serialno_string,
+	{  }			/* end of list */
+};
+
+static struct usb_gadget_strings stringtab_dev = {
+	.language	= 0x0409,	/* en-us */
+	.strings	= strings_dev,
+};
+
+static struct usb_gadget_strings *dev_strings[] = {
+	&stringtab_dev,
+	NULL,
+};
+
+static void qti_configs_remove_funcs(struct qti_usb_gadget *qg)
+{
+	struct usb_configuration	*c;
+
+	list_for_each_entry(c, &qg->cdev.configs, list) {
+		struct qti_usb_config *cfg;
+		struct usb_function *f, *tmp;
+
+		cfg = container_of(c, struct qti_usb_config, c);
+
+		list_for_each_entry_safe_reverse(f, tmp, &c->functions, list) {
+
+			list_move(&f->list, &cfg->func_list);
+			if (f->unbind) {
+				dev_dbg(&qg->cdev.gadget->dev,
+					"unbind function '%s'/%pK\n",
+					     f->name, f);
+				f->unbind(c, f);
+			}
+		}
+		c->fullspeed = 0;
+		c->highspeed = 0;
+		c->superspeed = 0;
+		c->superspeed_plus = 0;
+		c->next_interface_id = 0;
+		memset(c->interface, 0, sizeof(c->interface));
+	}
+}
+
+static int qti_composite_bind(struct usb_gadget *gadget,
+		struct usb_gadget_driver *gdriver)
+{
+	struct usb_composite_driver *composite = to_cdriver(gdriver);
+	struct qti_usb_gadget *qg = container_of(composite,
+				     struct qti_usb_gadget, composite);
+	struct usb_composite_dev *cdev = &qg->cdev;
+	struct usb_configuration *c;
+	struct usb_string *s;
+	int ret = -EINVAL;
+
+	cdev->gadget = gadget;
+	set_gadget_data(gadget, cdev);
+	spin_lock_init(&qg->cdev.lock);
+
+	ret = composite_dev_prepare(composite, cdev);
+	if (ret)
+		return ret;
+
+	if (list_empty(&cdev->configs)) {
+		pr_err("No configurations found in %s.\n", composite->name);
+		ret = -EINVAL;
+		goto composite_cleanup;
+	}
+
+	list_for_each_entry(c, &cdev->configs, list) {
+		struct qti_usb_config *qcfg;
+
+		qcfg = container_of(c, struct qti_usb_config, c);
+		if (list_empty(&qcfg->func_list)) {
+			pr_err("Config %s/%d of %s doesn't have a function.\n",
+			      c->label, c->bConfigurationValue,
+			      qg->composite.name);
+			goto composite_cleanup;
+		}
+	}
+
+	s = usb_gstrings_attach(cdev, dev_strings, USB_GADGET_FIRST_AVAIL_IDX);
+	if (IS_ERR(s)) {
+		ret = PTR_ERR(s);
+		goto composite_cleanup;
+	}
+
+	cdev->desc.iManufacturer = s[USB_GADGET_MANUFACTURER_IDX].id;
+	cdev->desc.iProduct = s[USB_GADGET_PRODUCT_IDX].id;
+	cdev->desc.iSerialNumber = s[USB_GADGET_SERIAL_IDX].id;
+
+	/* Go through all configs, attach all functions */
+	list_for_each_entry(c, &qg->cdev.configs, list) {
+		struct qti_usb_config *qcfg;
+		struct usb_function *f, *tmp;
+
+		qcfg = container_of(c, struct qti_usb_config, c);
+
+		list_for_each_entry_safe(f, tmp, &qcfg->func_list, list) {
+			list_del(&f->list);
+			ret = usb_add_function(c, f);
+			if (ret) {
+				list_add(&f->list, &qcfg->func_list);
+				goto remove_funcs;
+			}
+		}
+		usb_ep_autoconfig_reset(cdev->gadget);
+	}
+
+	usb_ep_autoconfig_reset(cdev->gadget);
+
+	return 0;
+
+remove_funcs:
+	qti_configs_remove_funcs(qg);
+composite_cleanup:
+	composite_dev_cleanup(cdev);
+	return ret;
+}
+
+static void qti_composite_unbind(struct usb_gadget *gadget)
+{
+	struct usb_composite_dev *cdev;
+	struct qti_usb_gadget *qg;
+
+	cdev = get_gadget_data(gadget);
+	qg = container_of(cdev, struct qti_usb_gadget, cdev);
+
+	qti_configs_remove_funcs(qg);
+	composite_dev_cleanup(cdev);
+	usb_ep_autoconfig_reset(cdev->gadget);
+	cdev->gadget = NULL;
+	set_gadget_data(gadget, NULL);
+}
+
+static const struct usb_gadget_driver qti_gadget_driver = {
+	.bind           = qti_composite_bind,
+	.unbind         = qti_composite_unbind,
+	.setup          = composite_setup,
+	.reset          = composite_disconnect,
+	.disconnect     = composite_disconnect,
+	.suspend	= composite_suspend,
+	.resume		= composite_resume,
+
+	.max_speed	= USB_SPEED_SUPER_PLUS,
+	.driver = {
+		.owner          = THIS_MODULE,
+		.name		= "qti-gadget",
+	},
+};
+
+static void qti_usb_funcs_free(struct qti_usb_config *qcfg)
+{
+	struct usb_function *f, *tmp;
+	struct qti_usb_function *qf, *qf_tmp;
+
+	list_for_each_entry_safe(f, tmp, &qcfg->func_list, list) {
+		list_del(&f->list);
+		usb_put_function(f);
+
+		/* find corresponding function_instance and free it */
+		list_for_each_entry_safe(qf, qf_tmp, &qcfg->qti_funcs, list) {
+			if (qf->f == f) {
+				list_del(&qf->list);
+				usb_put_function_instance(qf->fi);
+				kfree(qf);
+				break;
+			}
+		}
+	}
+}
+
+static void qti_cleanup_configs_funcs(struct qti_usb_gadget *qg)
+{
+	struct usb_configuration *c, *c_tmp;
+
+	list_for_each_entry_safe(c, c_tmp, &qg->cdev.configs, list) {
+		struct qti_usb_config *qcfg;
+
+		qcfg = container_of(c, struct qti_usb_config, c);
+		WARN_ON(!list_empty(&qcfg->c.functions));
+
+		qti_usb_funcs_free(qcfg);
+
+		list_del(&qcfg->c.list);
+		kfree(qcfg->c.label);
+		kfree(qcfg);
+	}
+}
+
+static int qti_usb_func_alloc(struct qti_usb_config *qcfg,
+				   const char *name)
+{
+	struct qti_usb_function *qf;
+	struct usb_function_instance *fi;
+	struct usb_function *f;
+	char buf[MAX_FUNC_NAME_LEN];
+	char *func_name;
+	char *instance_name;
+	int ret;
+
+	ret = snprintf(buf, MAX_FUNC_NAME_LEN, "%s", name);
+	if (ret >= MAX_FUNC_NAME_LEN)
+		return -ENAMETOOLONG;
+
+	func_name = buf;
+	instance_name = strnchr(func_name, MAX_FUNC_NAME_LEN, '.');
+	if (!instance_name) {
+		pr_err("Can't find . in <func>.<instance>:%s\n", buf);
+		return -EINVAL;
+	}
+	*instance_name = '\0';
+	instance_name++;
+
+	qf = kzalloc(sizeof(*qf), GFP_KERNEL);
+	if (!qf)
+		return -ENOMEM;
+
+	fi = usb_get_function_instance(func_name);
+	if (IS_ERR(fi)) {
+		kfree(qf);
+		return PTR_ERR(fi);
+	}
+	qf->fi = fi;
+
+	if (fi->set_inst_name) {
+		ret = fi->set_inst_name(fi, instance_name);
+		if (ret) {
+			kfree(qf);
+			usb_put_function_instance(fi);
+			return ret;
+		}
+	}
+
+	f = usb_get_function(fi);
+	if (IS_ERR(f)) {
+		kfree(qf);
+		usb_put_function_instance(fi);
+		return PTR_ERR(f);
+	}
+	qf->f = f;
+	list_add_tail(&qf->list, &qcfg->qti_funcs);
+
+	/* stash the function until we bind it to the gadget */
+	list_add_tail(&f->list, &qcfg->func_list);
+
+	return 0;
+}
+
+static int qti_usb_funcs_alloc(struct qti_usb_config *qcfg,
+				const char *funcs)
+{
+	char buf[MAX_CFG_NAME_LEN];
+	char *fn_name, *next_fn;
+	int ret = 0;
+
+	ret = snprintf(buf, MAX_CFG_NAME_LEN, "%s", funcs);
+	if (ret >= MAX_CFG_NAME_LEN)
+		return -ENAMETOOLONG;
+
+	fn_name = buf;
+	while (fn_name) {
+		next_fn = strnchr(fn_name, MAX_CFG_NAME_LEN, ',');
+		if (next_fn)
+			*next_fn++ = '\0';
+
+		ret = qti_usb_func_alloc(qcfg, fn_name);
+		if (ret) {
+			qti_usb_funcs_free(qcfg);
+			break;
+		}
+
+		fn_name = next_fn;
+	};
+
+	return ret;
+}
+
+static int qti_usb_config_add(struct qti_usb_gadget *gadget,
+				  const char *name, u8 num)
+{
+	struct qti_usb_config *qcfg;
+	int ret = 0;
+
+	qcfg = kzalloc(sizeof(*qcfg), GFP_KERNEL);
+	if (!qcfg)
+		return -ENOMEM;
+
+	qcfg->c.label = kstrdup(name, GFP_KERNEL);
+	if (!qcfg->c.label) {
+		ret = -ENOMEM;
+		goto free_cfg;
+	}
+	qcfg->c.bConfigurationValue = num;
+	qcfg->c.bmAttributes = USB_CONFIG_ATT_ONE;
+	qcfg->c.MaxPower = CONFIG_USB_GADGET_VBUS_DRAW;
+	INIT_LIST_HEAD(&qcfg->func_list);
+	INIT_LIST_HEAD(&qcfg->qti_funcs);
+
+	ret = usb_add_config_only(&gadget->cdev, &qcfg->c);
+	if (ret)
+		goto free_label;
+
+	ret = qti_usb_funcs_alloc(qcfg, name);
+	if (ret)
+		goto cfg_del;
+
+	return ret;
+
+cfg_del:
+	list_del(&qcfg->c.list);
+free_label:
+	kfree(qcfg->c.label);
+free_cfg:
+	kfree(qcfg);
+	return ret;
+
+}
+
+static int qti_usb_configs_make(struct qti_usb_gadget *gadget,
+				  const char *cfgs)
+{
+	char buf[MAX_CFG_NAME_LEN];
+	char *cfg_name, *next_cfg;
+	int ret = 0;
+	u8 num = 1;
+
+	ret = snprintf(buf, MAX_CFG_NAME_LEN, "%s", cfgs);
+	if (ret >= MAX_CFG_NAME_LEN)
+		return -ENAMETOOLONG;
+
+	cfg_name = buf;
+	while (cfg_name) {
+		next_cfg = strnchr(cfg_name, MAX_CFG_NAME_LEN, '|');
+		if (next_cfg)
+			*next_cfg++ = '\0';
+
+		ret = qti_usb_config_add(gadget, cfg_name, num);
+		if (ret)
+			break;
+
+		cfg_name = next_cfg;
+		num++;
+	};
+
+	return ret;
+}
+
+static int qti_gadget_register(struct qti_usb_gadget *qg)
+{
+	int ret;
+
+	if (qg->enabled)
+		return -EINVAL;
+
+	ret = qti_usb_configs_make(qg, qg->composition_funcs);
+	if (ret)
+		return ret;
+
+	qg->cdev.desc.bLength = USB_DT_DEVICE_SIZE;
+	qg->cdev.desc.bDescriptorType = USB_DT_DEVICE;
+	qg->cdev.desc.bcdDevice = cpu_to_le16(get_default_bcdDevice());
+
+	qg->composite.gadget_driver = qti_gadget_driver;
+	qg->composite.max_speed = qti_gadget_driver.max_speed;
+
+	qg->composite.gadget_driver.function = kstrdup("qti-gadget",
+							GFP_KERNEL);
+	qg->composite.name = qg->composite.gadget_driver.function;
+
+	if (!qg->composite.gadget_driver.function) {
+		ret = -ENOMEM;
+		goto free_configs;
+	}
+
+	ret = usb_gadget_probe_driver(&qg->composite.gadget_driver);
+	if (ret)
+		goto free_name;
+
+	qg->enabled = true;
+
+	return 0;
+
+free_name:
+	kfree(qg->composite.gadget_driver.function);
+free_configs:
+	qti_cleanup_configs_funcs(qg);
+
+	return ret;
+}
+
+static void qti_gadget_unregister(struct qti_usb_gadget *qg)
+{
+	if (!qg->enabled)
+		return;
+
+	usb_gadget_unregister_driver(&qg->composite.gadget_driver);
+	kfree(qg->composite.gadget_driver.function);
+	qti_cleanup_configs_funcs(qg);
+
+	qg->enabled = false;
+}
+
+static int qti_gadget_get_properties(struct qti_usb_gadget *gadget)
+{
+	struct device *dev = gadget->dev;
+	int ret, val;
+
+	ret = device_property_read_string(dev, "qcom,composition",
+				    &gadget->composition_funcs);
+	if (ret) {
+		dev_err(dev, "USB gadget composition not specified\n");
+		return ret;
+	}
+
+	/* bail out if ffs is specified and let userspace handle it */
+	if (strstr(gadget->composition_funcs, "ffs.")) {
+		dev_err(dev, "user should enable ffs\n");
+		return -EINVAL;
+	}
+
+	ret = device_property_read_u32(dev, "qcom,vid", &val);
+	if (ret) {
+		dev_err(dev, "USB gadget idVendor not specified\n");
+		return ret;
+	}
+	gadget->cdev.desc.idVendor = (u16)val;
+
+	ret = device_property_read_u32(dev, "qcom,pid", &val);
+	if (ret) {
+		dev_err(dev, "USB gadget idProduct not specified\n");
+		return ret;
+	}
+	gadget->cdev.desc.idProduct = (u16)val;
+
+	ret = device_property_read_u32(dev, "qcom,class", &val);
+	if (!ret)
+		gadget->cdev.desc.bDeviceClass = (u8)val;
+
+	ret = device_property_read_u32(dev, "qcom,subclass", &val);
+	if (!ret)
+		gadget->cdev.desc.bDeviceSubClass = (u8)val;
+
+	ret = device_property_read_u32(dev, "qcom,protocol", &val);
+	if (!ret)
+		gadget->cdev.desc.bDeviceProtocol = (u8)val;
+
+	return 0;
+}
+
+static ssize_t enabled_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct qti_usb_gadget *qg = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%c\n",
+			qg->enabled ? 'Y' : 'N');
+}
+
+static ssize_t enabled_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct qti_usb_gadget *qg = dev_get_drvdata(dev);
+	bool enable;
+	int ret;
+
+	ret = strtobool(buf, &enable);
+	if (ret)
+		return ret;
+
+	if (enable)
+		qti_gadget_register(qg);
+	else
+		qti_gadget_unregister(qg);
+
+	return count;
+}
+static DEVICE_ATTR_RW(enabled);
+
+static int qti_gadget_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct device *dev = &pdev->dev;
+	struct qti_usb_gadget *gadget;
+
+	gadget = devm_kzalloc(dev, sizeof(*gadget), GFP_KERNEL);
+	if (!gadget)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, gadget);
+	gadget->dev = dev;
+	INIT_LIST_HEAD(&gadget->cdev.configs);
+	INIT_LIST_HEAD(&gadget->cdev.gstrings);
+
+	ret = qti_gadget_get_properties(gadget);
+	if (ret)
+		return ret;
+
+	ret = qti_gadget_register(gadget);
+	if (ret)
+		return ret;
+
+	device_create_file(&pdev->dev, &dev_attr_enabled);
+
+	return 0;
+}
+
+static int qti_gadget_remove(struct platform_device *pdev)
+{
+	struct qti_usb_gadget *qg = platform_get_drvdata(pdev);
+
+	device_remove_file(&pdev->dev, &dev_attr_enabled);
+	qti_gadget_unregister(qg);
+
+	return 0;
+}
+
+static const struct of_device_id qti_gadget_dt_match[] = {
+	{
+		.compatible = "qcom,usb-gadget",
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, qti_gadget_dt_match);
+
+static struct platform_driver qti_gadget_platform_driver = {
+	.driver = {
+		.name = "qti_usb_gadget",
+		.of_match_table = qti_gadget_dt_match,
+	},
+	.probe = qti_gadget_probe,
+	.remove = qti_gadget_remove,
+};
+
+static int __init gadget_qti_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&qti_gadget_platform_driver);
+	if (ret) {
+		pr_err("%s: Failed to register qti gadget platform driver\n",
+			__func__);
+	}
+
+	return ret;
+}
+module_init(gadget_qti_init);
+
+static void __exit gadget_qti_exit(void)
+{
+	platform_driver_unregister(&qti_gadget_platform_driver);
+}
+module_exit(gadget_qti_exit);
diff --git a/drivers/usb/phy/phy-msm-qusb-v2.c b/drivers/usb/phy/phy-msm-qusb-v2.c
index 41e5e32..cd7a768 100644
--- a/drivers/usb/phy/phy-msm-qusb-v2.c
+++ b/drivers/usb/phy/phy-msm-qusb-v2.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
@@ -32,6 +32,7 @@
 
 /* QUSB2PHY_PWR_CTRL1 register related bits */
 #define PWR_CTRL1_POWR_DOWN		BIT(0)
+#define CLAMP_N_EN			BIT(1)
 
 /* QUSB2PHY_PLL_COMMON_STATUS_ONE register related bits */
 #define CORE_READY_STATUS		BIT(0)
@@ -82,6 +83,10 @@
 /* STAT5 register bits */
 #define VSTATUS_PLL_LOCK_STATUS_MASK	BIT(0)
 
+/* DEBUG_CTRL4 register bits  */
+#define FORCED_UTMI_DPPULLDOWN	BIT(2)
+#define FORCED_UTMI_DMPULLDOWN	BIT(3)
+
 enum qusb_phy_reg {
 	PORT_TUNE1,
 	PLL_COMMON_STATUS_ONE,
@@ -94,6 +99,8 @@
 	SQ_CTRL2,
 	DEBUG_CTRL1,
 	DEBUG_CTRL2,
+	DEBUG_CTRL3,
+	DEBUG_CTRL4,
 	STAT5,
 	USB2_PHY_REG_MAX,
 };
@@ -127,7 +134,6 @@
 	int			efuse_num_of_bits;
 
 	int			power_enabled_ref;
-	bool			clocks_enabled;
 	bool			cable_connected;
 	bool			suspended;
 	bool			dpdm_enable;
@@ -229,10 +235,9 @@
 
 static void qusb_phy_enable_clocks(struct qusb_phy *qphy, bool on)
 {
-	dev_dbg(qphy->phy.dev, "%s(): clocks_enabled:%d on:%d\n",
-			__func__, qphy->clocks_enabled, on);
+	dev_dbg(qphy->phy.dev, "%s(): on:%d\n", __func__, on);
 
-	if (!qphy->clocks_enabled && on) {
+	if (on) {
 		clk_prepare_enable(qphy->ref_clk_src);
 		if (qphy->ref_clk)
 			clk_prepare_enable(qphy->ref_clk);
@@ -240,10 +245,7 @@
 		if (qphy->cfg_ahb_clk)
 			clk_prepare_enable(qphy->cfg_ahb_clk);
 
-		qphy->clocks_enabled = true;
-	}
-
-	if (qphy->clocks_enabled && !on) {
+	} else {
 		if (qphy->cfg_ahb_clk)
 			clk_disable_unprepare(qphy->cfg_ahb_clk);
 
@@ -251,11 +253,7 @@
 			clk_disable_unprepare(qphy->ref_clk);
 
 		clk_disable_unprepare(qphy->ref_clk_src);
-		qphy->clocks_enabled = false;
 	}
-
-	dev_dbg(qphy->phy.dev, "%s(): clocks_enabled:%d\n", __func__,
-						qphy->clocks_enabled);
 }
 
 static int qusb_phy_config_vdd(struct qusb_phy *qphy, int high)
@@ -461,6 +459,24 @@
 			usleep_range(delay, (delay + 2000));
 	}
 }
+static void msm_usb_write_readback(void __iomem *base, u32 offset,
+					const u32 mask, u32 val)
+{
+	u32 write_val, tmp = readl_relaxed(base + offset);
+
+	tmp &= ~mask;		/* retain other bits */
+	write_val = tmp | val;
+
+	writel_relaxed(write_val, base + offset);
+
+	/* Read back to see if val was written */
+	tmp = readl_relaxed(base + offset);
+	tmp &= mask;		/* clear other bits */
+
+	if (tmp != val)
+		pr_err("%s: write: %x to QSCRATCH: %x FAILED\n",
+			__func__, val, offset);
+}
 
 static void qusb_phy_reset(struct qusb_phy *qphy)
 {
@@ -572,8 +588,6 @@
 	if (ret)
 		return ret;
 
-	qusb_phy_enable_clocks(qphy, true);
-
 	qusb_phy_reset(qphy);
 
 	if (qphy->qusb_phy_host_init_seq && qphy->phy.flags & PHY_HOST_MODE) {
@@ -735,7 +749,7 @@
 	struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
 	u32 linestate = 0, intr_mask = 0;
 
-	if (qphy->suspended && suspend) {
+	if (qphy->suspended == suspend) {
 		dev_dbg(phy->dev, "%s: USB PHY is already suspended\n",
 			__func__);
 		return 0;
@@ -900,6 +914,48 @@
 	mutex_unlock(&qphy->lock);
 	return ret;
 }
+static int msm_qusb_phy_drive_dp_pulse(struct usb_phy *phy,
+					unsigned int interval_ms)
+{
+	struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
+
+	qusb_phy_enable_clocks(qphy, true);
+
+	msm_usb_write_readback(qphy->base, qphy->phy_reg[PWR_CTRL1],
+				PWR_CTRL1_POWR_DOWN, 0x00);
+	msm_usb_write_readback(qphy->base, qphy->phy_reg[DEBUG_CTRL4],
+				FORCED_UTMI_DPPULLDOWN, 0x00);
+	msm_usb_write_readback(qphy->base, qphy->phy_reg[DEBUG_CTRL4],
+				FORCED_UTMI_DMPULLDOWN,
+				FORCED_UTMI_DMPULLDOWN);
+	msm_usb_write_readback(qphy->base, qphy->phy_reg[DEBUG_CTRL3],
+				0xd1, 0xd1);
+	msm_usb_write_readback(qphy->base, qphy->phy_reg[PWR_CTRL1],
+				CLAMP_N_EN, CLAMP_N_EN);
+	msm_usb_write_readback(qphy->base, qphy->phy_reg[INTR_CTRL],
+				DPSE_INTR_HIGH_SEL, 0x00);
+	msm_usb_write_readback(qphy->base, qphy->phy_reg[INTR_CTRL],
+				DPSE_INTR_EN, DPSE_INTR_EN);
+
+	msleep(interval_ms);
+
+	msm_usb_write_readback(qphy->base, qphy->phy_reg[INTR_CTRL],
+				DPSE_INTR_HIGH_SEL |
+				DPSE_INTR_EN, 0x00);
+	msm_usb_write_readback(qphy->base, qphy->phy_reg[DEBUG_CTRL3],
+				0xd1, 0x00);
+	msm_usb_write_readback(qphy->base, qphy->phy_reg[DEBUG_CTRL4],
+				FORCED_UTMI_DPPULLDOWN |
+				FORCED_UTMI_DMPULLDOWN, 0x00);
+	msm_usb_write_readback(qphy->base, qphy->phy_reg[PWR_CTRL1],
+				PWR_CTRL1_POWR_DOWN |
+				CLAMP_N_EN, 0x00);
+
+	msleep(20);
+
+	qusb_phy_enable_clocks(qphy, false);
+	return 0;
+}
 
 static int qusb_phy_dpdm_regulator_enable(struct regulator_dev *rdev)
 {
@@ -1343,6 +1399,7 @@
 	qphy->phy.type			= USB_PHY_TYPE_USB2;
 	qphy->phy.notify_connect        = qusb_phy_notify_connect;
 	qphy->phy.notify_disconnect     = qusb_phy_notify_disconnect;
+	qphy->phy.drive_dp_pulse	= msm_qusb_phy_drive_dp_pulse;
 
 	/*
 	 * qusb_phy_disable_chirp is not required if soc version is
@@ -1361,6 +1418,7 @@
 	if (ret)
 		usb_remove_phy(&qphy->phy);
 
+	qphy->suspended = true;
 	qusb_phy_create_debugfs(qphy);
 
 	return ret;
@@ -1371,8 +1429,8 @@
 	struct qusb_phy *qphy = platform_get_drvdata(pdev);
 
 	usb_remove_phy(&qphy->phy);
-	qusb_phy_enable_clocks(qphy, false);
-	qusb_phy_enable_power(qphy, false);
+	qphy->cable_connected = false;
+	qusb_phy_set_suspend(&qphy->phy, true);
 	debugfs_remove_recursive(qphy->root);
 
 	return 0;
diff --git a/drivers/usb/phy/phy-msm-qusb.c b/drivers/usb/phy/phy-msm-qusb.c
index 47db12b..9d66366 100644
--- a/drivers/usb/phy/phy-msm-qusb.c
+++ b/drivers/usb/phy/phy-msm-qusb.c
@@ -147,7 +147,6 @@
 	int			tune2_efuse_correction;
 
 	bool			power_enabled;
-	bool			clocks_enabled;
 	bool			cable_connected;
 	bool			suspended;
 	bool			ulpi_mode;
@@ -172,19 +171,15 @@
 
 static void qusb_phy_enable_clocks(struct qusb_phy *qphy, bool on)
 {
-	dev_dbg(qphy->phy.dev, "%s(): clocks_enabled:%d on:%d\n",
-			__func__, qphy->clocks_enabled, on);
+	dev_dbg(qphy->phy.dev, "%s(): on:%d\n", __func__, on);
 
-	if (!qphy->clocks_enabled && on) {
+	if (on) {
 		clk_prepare_enable(qphy->ref_clk_src);
 		clk_prepare_enable(qphy->ref_clk);
 		clk_prepare_enable(qphy->iface_clk);
 		clk_prepare_enable(qphy->core_clk);
 		clk_prepare_enable(qphy->cfg_ahb_clk);
-		qphy->clocks_enabled = true;
-	}
-
-	if (qphy->clocks_enabled && !on) {
+	} else {
 		clk_disable_unprepare(qphy->cfg_ahb_clk);
 		/*
 		 * FSM depedency beween iface_clk and core_clk.
@@ -194,11 +189,8 @@
 		clk_disable_unprepare(qphy->iface_clk);
 		clk_disable_unprepare(qphy->ref_clk);
 		clk_disable_unprepare(qphy->ref_clk_src);
-		qphy->clocks_enabled = false;
 	}
 
-	dev_dbg(qphy->phy.dev, "%s(): clocks_enabled:%d\n", __func__,
-						qphy->clocks_enabled);
 }
 
 static int qusb_phy_gdsc(struct qusb_phy *qphy, bool on)
@@ -441,8 +433,6 @@
 	if (ret)
 		return ret;
 
-	qusb_phy_enable_clocks(qphy, true);
-
 	/*
 	 * ref clock is enabled by default after power on reset. Linux clock
 	 * driver will disable this clock as part of late init if peripheral
@@ -646,7 +636,7 @@
 	struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy);
 	u32 linestate = 0, intr_mask = 0;
 
-	if (qphy->suspended && suspend) {
+	if (qphy->suspended == suspend) {
 		dev_dbg(phy->dev, "%s: USB PHY is already suspended\n",
 			__func__);
 		return 0;
@@ -1227,6 +1217,8 @@
 	if (qphy->tcsr_clamp_dig_n)
 		writel_relaxed(0x0, qphy->tcsr_clamp_dig_n);
 
+	qphy->suspended = true;
+
 	return ret;
 }
 
@@ -1235,15 +1227,8 @@
 	struct qusb_phy *qphy = platform_get_drvdata(pdev);
 
 	usb_remove_phy(&qphy->phy);
-
-	if (qphy->clocks_enabled) {
-		clk_disable_unprepare(qphy->cfg_ahb_clk);
-		clk_disable_unprepare(qphy->ref_clk);
-		clk_disable_unprepare(qphy->ref_clk_src);
-		qphy->clocks_enabled = false;
-	}
-
-	qusb_phy_enable_power(qphy, false);
+	qphy->cable_connected = false;
+	qusb_phy_set_suspend(&qphy->phy, true);
 
 	return 0;
 }
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index a5db4a6..356fa56 100755
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -873,7 +873,21 @@
 
 static int f2fs_drop_inode(struct inode *inode)
 {
+	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
 	int ret;
+
+	/*
+	 * during filesystem shutdown, if checkpoint is disabled,
+	 * drop useless meta/node dirty pages.
+	 */
+	if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) {
+		if (inode->i_ino == F2FS_NODE_INO(sbi) ||
+			inode->i_ino == F2FS_META_INO(sbi)) {
+			trace_f2fs_drop_inode(inode, 1);
+			return 1;
+		}
+	}
+
 	/*
 	 * This is to avoid a deadlock condition like below.
 	 * writeback_single_inode(inode)
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index 90e8394..ae72202 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-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
@@ -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		0xCB7
+#define APPS_EVENT_LAST_ID		0xCB9
 
 #define MSG_SSID_0			0
-#define MSG_SSID_0_LAST			131
+#define MSG_SSID_0_LAST			132
 #define MSG_SSID_1			500
 #define MSG_SSID_1_LAST			506
 #define MSG_SSID_2			1000
@@ -362,7 +362,8 @@
 	MSG_LVL_MED,
 	MSG_LVL_HIGH,
 	MSG_LVL_HIGH,
-	MSG_LVL_LOW | MSG_LVL_MED | MSG_LVL_HIGH | MSG_LVL_ERROR
+	MSG_LVL_LOW | MSG_LVL_MED | MSG_LVL_HIGH | MSG_LVL_ERROR,
+	MSG_LVL_HIGH
 };
 
 static const uint32_t msg_bld_masks_1[] = {
@@ -924,7 +925,7 @@
 /* LOG CODES */
 static const uint32_t log_code_last_tbl[] = {
 	0x0,	/* EQUIP ID 0 */
-	0x1CC0,	/* EQUIP ID 1 */
+	0x1CCA,	/* EQUIP ID 1 */
 	0x0,	/* EQUIP ID 2 */
 	0x0,	/* EQUIP ID 3 */
 	0x4910,	/* EQUIP ID 4 */
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 87e97bb..bd25e81 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -589,6 +589,9 @@
 void usb_composite_overwrite_options(struct usb_composite_dev *cdev,
 		struct usb_composite_overwrite *covr);
 
+int composite_dev_prepare(struct usb_composite_driver *composite,
+		struct usb_composite_dev *dev);
+
 static inline u16 get_default_bcdDevice(void)
 {
 	u16 bcdDevice;
diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h
index c724747..e4f3f21 100644
--- a/include/linux/usb/phy.h
+++ b/include/linux/usb/phy.h
@@ -144,6 +144,7 @@
 
 	/* reset the PHY clocks */
 	int     (*reset)(struct usb_phy *x);
+	int	(*drive_dp_pulse)(struct usb_phy *x, unsigned int pulse_width);
 
 	/* for notification of usb_phy_dbg_events */
 	void    (*dbg_event)(struct usb_phy *x,
@@ -241,6 +242,15 @@
 	return 0;
 }
 
+static inline int
+usb_phy_drive_dp_pulse(struct usb_phy *x, unsigned int pulse_width)
+{
+	if (x && x->drive_dp_pulse)
+		return x->drive_dp_pulse(x, pulse_width);
+
+	return 0;
+}
+
 /* for usb host and peripheral controller drivers */
 #if IS_ENABLED(CONFIG_USB_PHY)
 extern struct usb_phy *usb_get_phy(enum usb_phy_type type);