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);