Merge "wcnss: Fix buffer overflow in wcnss_prealloc_get"
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8917-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,msm8917-pinctrl.txt
index d2327a257..751448c 100644
--- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8917-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8917-pinctrl.txt
@@ -11,7 +11,13 @@
- reg:
Usage: required
Value type: <prop-encoded-array>
- Definition: the base address and size of the TLMM register space.
+ Definition: the base address and size of the TLMM register space
+ provided as "pinctrl_regs".
+
+- reg-names:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: Provides labels for the reg property.
- interrupts:
Usage: required
@@ -167,6 +173,7 @@
tlmm: pinctrl@1000000 {
compatible = "qcom,msm8917-pinctrl";
reg = <0x1000000 0x300000>;
+ reg-names = "pinctrl_regs";
interrupts = <0 208 0>;
gpio-controller;
#gpio-cells = <2>;
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8937-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,msm8937-pinctrl.txt
index f697704..39872c5 100644
--- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8937-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8937-pinctrl.txt
@@ -11,7 +11,13 @@
- reg:
Usage: required
Value type: <prop-encoded-array>
- Definition: the base address and size of the TLMM register space.
+ Definition: the base address and size of the TLMM register space
+ provided as "pinctrl_regs".
+
+- reg-names:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: Provides labels for the reg property.
- interrupts:
Usage: required
@@ -167,6 +173,7 @@
tlmm: pinctrl@1000000 {
compatible = "qcom,msm8937-pinctrl";
reg = <0x1000000 0x300000>;
+ reg-names = "pinctrl_regs";
interrupts = <0 208 0>;
gpio-controller;
#gpio-cells = <2>;
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8953-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,msm8953-pinctrl.txt
index 4b483e5..8da0a75 100644
--- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8953-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8953-pinctrl.txt
@@ -11,7 +11,13 @@
- reg:
Usage: required
Value type: <prop-encoded-array>
- Definition: the base address and size of the TLMM register space.
+ Definition: the base address and size of the TLMM register space
+ provided as "pinctrl_regs".
+
+- reg-names:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: Provides labels for the reg property.
- interrupts:
Usage: required
@@ -173,6 +179,7 @@
tlmm: pinctrl@1000000 {
compatible = "qcom,msm8953-pinctrl";
reg = <0x1000000 0x300000>;
+ reg-names = "pinctrl_regs";
interrupts = <0 208 0>;
gpio-controller;
#gpio-cells = <2>;
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sdm670-pinctrl b/Documentation/devicetree/bindings/pinctrl/qcom,sdm670-pinctrl
index 0eb1043f..2b3dc01 100644
--- a/Documentation/devicetree/bindings/pinctrl/qcom,sdm670-pinctrl
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,sdm670-pinctrl
@@ -11,7 +11,16 @@
- reg:
Usage: required
Value type: <prop-encoded-array>
- Definition: the base address and size of the TLMM register space.
+ Definition: the base address and size of the TLMM register space
+ provided as "pinctrl_regs", optional base address of
+ PDC mux selection registers provided as "pdc_regs"
+ and optional base address of shared SPI config
+ registers provided as "spi_cfg_regs".
+
+- reg-names:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: Provides labels for the reg property.
- interrupts:
Usage: required
@@ -137,7 +146,8 @@
tlmm: pinctrl@03400000 {
compatible = "qcom,sdm670-pinctrl";
- reg = <0x03400000 0xc00000>;
+ reg = <0x03400000 0xc00000>, <0x179900f0 0x60>;
+ reg-names = "pinctrl_regs", "spi_cfg_regs";
interrupts = <0 208 0>;
gpio-controller;
#gpio-cells = <2>;
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sdm845-pinctrl b/Documentation/devicetree/bindings/pinctrl/qcom,sdm845-pinctrl
index 7e75d2c..f8fc5d0 100644
--- a/Documentation/devicetree/bindings/pinctrl/qcom,sdm845-pinctrl
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,sdm845-pinctrl
@@ -11,7 +11,17 @@
- reg:
Usage: required
Value type: <prop-encoded-array>
- Definition: the base address and size of the TLMM register space.
+ Definition: the base address and size of the TLMM register space
+ provided as "pinctrl_regs", optional base address of
+ PDC mux selection registers provided as "pdc_regs"
+ and optional base address of shared SPI config
+ registers provided as "spi_cfg_regs".
+
+- reg-names:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: Provides labels for the reg property.
+
- interrupts:
Usage: required
@@ -177,7 +187,8 @@
tlmm: pinctrl@03400000 {
compatible = "qcom,sdm845-pinctrl";
- reg = <0x03800000 0xc00000>;
+ reg = <0x03800000 0xc00000>, <0x179900f0 0x60>;
+ reg-names = "pinctrl_regs", "spi_cfg_regs";
interrupts = <0 208 0>;
gpio-controller;
#gpio-cells = <2>;
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sdxpoorwill-pinctrl b/Documentation/devicetree/bindings/pinctrl/qcom,sdxpoorwill-pinctrl
index 9a69084..552cec8 100644
--- a/Documentation/devicetree/bindings/pinctrl/qcom,sdxpoorwill-pinctrl
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,sdxpoorwill-pinctrl
@@ -11,7 +11,17 @@
- reg:
Usage: required
Value type: <prop-encoded-array>
- Definition: the base address and size of the TLMM register space.
+ Definition: the base address and size of the TLMM register space
+ provided as "pinctrl_regs", optional base address of
+ PDC mux selection registers provided as "pdc_regs"
+ and optional base address of shared SPI config
+ registers provided as "spi_cfg_regs".
+
+- reg-names:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: Provides labels for the reg property.
+
- interrupts:
Usage: required
@@ -178,6 +188,7 @@
tlmm: pinctrl@03900000 {
compatible = "qcom,sdxpoorwills-pinctrl";
reg = <0x03900000 0x300000>;
+ reg-names = "pinctrl_regs", "pdc_regs";
interrupts = <0 212 0>;
gpio-controller;
#gpio-cells = <2>;
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi
index d31916b..c167bdd 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi
@@ -15,6 +15,7 @@
compatible = "qcom,sdxpoorwills-pinctrl";
reg = <0x3900000 0x300000>,
<0xB204900 0x280>;
+ reg-names = "pinctrl_regs", "pdc_regs";
interrupts = <0 212 0>;
gpio-controller;
#gpio-cells = <2>;
@@ -1683,6 +1684,21 @@
};
};
};
+
+ emac {
+ emac_pin_pps_0: emac_pin_pps_0 {
+ mux {
+ pins = "gpio89";
+ function = "emac_pps";
+ };
+
+ config {
+ pins = "gpio89";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable; /* NO PULL*/
+ };
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-v2.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-v2.dtsi
index be346e1..a3431cf 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-v2.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-v2.dtsi
@@ -19,6 +19,8 @@
&emac_hw {
emac-core-version = <5>;
+ pinctrl-names = "dev-emac_pin_pps_0";
+ pinctrl-0 = <&emac_pin_pps_0>;
};
&apps_smmu {
diff --git a/arch/arm/configs/msm8909_defconfig b/arch/arm/configs/msm8909_defconfig
index 004c025..17640c9 100644
--- a/arch/arm/configs/msm8909_defconfig
+++ b/arch/arm/configs/msm8909_defconfig
@@ -474,7 +474,6 @@
CONFIG_WCNSS_CORE_PRONTO=y
CONFIG_WCNSS_REGISTER_DUMP_ON_BITE=y
CONFIG_CNSS_CRYPTO=y
-CONFIG_QCOM_DEVFREQ_DEVBW=y
CONFIG_IIO=y
CONFIG_INV_ICM20602_IIO=y
CONFIG_PWM=y
diff --git a/arch/arm/configs/msm8909w-perf_defconfig b/arch/arm/configs/msm8909w-perf_defconfig
index 080ccff..6ef7915 100644
--- a/arch/arm/configs/msm8909w-perf_defconfig
+++ b/arch/arm/configs/msm8909w-perf_defconfig
@@ -443,7 +443,6 @@
CONFIG_WCNSS_CORE=y
CONFIG_WCNSS_CORE_PRONTO=y
CONFIG_WCNSS_REGISTER_DUMP_ON_BITE=y
-CONFIG_QCOM_DEVFREQ_DEVBW=y
CONFIG_IIO=y
CONFIG_QCOM_SPMI_IADC=y
CONFIG_QCOM_SPMI_VADC=y
diff --git a/arch/arm/configs/msm8909w_defconfig b/arch/arm/configs/msm8909w_defconfig
index 0fc7cd2..986a65c 100644
--- a/arch/arm/configs/msm8909w_defconfig
+++ b/arch/arm/configs/msm8909w_defconfig
@@ -437,7 +437,6 @@
CONFIG_WCNSS_CORE=y
CONFIG_WCNSS_CORE_PRONTO=y
CONFIG_WCNSS_REGISTER_DUMP_ON_BITE=y
-CONFIG_QCOM_DEVFREQ_DEVBW=y
CONFIG_IIO=y
CONFIG_QCOM_SPMI_IADC=y
CONFIG_QCOM_SPMI_VADC=y
diff --git a/arch/arm/configs/msm8953-perf_defconfig b/arch/arm/configs/msm8953-perf_defconfig
index 5590635..4587317 100644
--- a/arch/arm/configs/msm8953-perf_defconfig
+++ b/arch/arm/configs/msm8953-perf_defconfig
@@ -616,6 +616,7 @@
CONFIG_EXT4_FS_ICE_ENCRYPTION=y
CONFIG_F2FS_FS=y
CONFIG_F2FS_FS_SECURITY=y
+CONFIG_F2FS_FS_ENCRYPTION=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QFMT_V2=y
diff --git a/arch/arm/configs/msm8953_defconfig b/arch/arm/configs/msm8953_defconfig
index 153cdd9..528cb27 100644
--- a/arch/arm/configs/msm8953_defconfig
+++ b/arch/arm/configs/msm8953_defconfig
@@ -633,6 +633,7 @@
CONFIG_EXT4_FS_ICE_ENCRYPTION=y
CONFIG_F2FS_FS=y
CONFIG_F2FS_FS_SECURITY=y
+CONFIG_F2FS_FS_ENCRYPTION=y
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QFMT_V2=y
diff --git a/arch/arm/configs/sdm670-perf_defconfig b/arch/arm/configs/sdm670-perf_defconfig
index 3b23165..d5bbdcc 100644
--- a/arch/arm/configs/sdm670-perf_defconfig
+++ b/arch/arm/configs/sdm670-perf_defconfig
@@ -498,6 +498,7 @@
CONFIG_QCOM_SMCINVOKE=y
CONFIG_MSM_EVENT_TIMER=y
CONFIG_MSM_QBT1000=y
+CONFIG_QCOM_DCC_V2=y
CONFIG_QTI_RPM_STATS_LOG=y
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
CONFIG_QMP_DEBUGFS_CLIENT=y
diff --git a/arch/arm/configs/sdm670_defconfig b/arch/arm/configs/sdm670_defconfig
index 702f622..baac195 100644
--- a/arch/arm/configs/sdm670_defconfig
+++ b/arch/arm/configs/sdm670_defconfig
@@ -520,6 +520,7 @@
CONFIG_QCOM_SMCINVOKE=y
CONFIG_MSM_EVENT_TIMER=y
CONFIG_MSM_QBT1000=y
+CONFIG_QCOM_DCC_V2=y
CONFIG_QTI_RPM_STATS_LOG=y
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
CONFIG_QMP_DEBUGFS_CLIENT=y
diff --git a/arch/arm/configs/sdxpoorwills-perf_defconfig b/arch/arm/configs/sdxpoorwills-perf_defconfig
index 931c015..1c0764e 100644
--- a/arch/arm/configs/sdxpoorwills-perf_defconfig
+++ b/arch/arm/configs/sdxpoorwills-perf_defconfig
@@ -19,6 +19,7 @@
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
# CONFIG_SLUB_DEBUG is not set
+CONFIG_SLAB_FREELIST_RANDOM=y
CONFIG_PROFILING=y
CONFIG_CC_STACKPROTECTOR_REGULAR=y
CONFIG_MODULES=y
diff --git a/arch/arm/configs/sdxpoorwills_defconfig b/arch/arm/configs/sdxpoorwills_defconfig
index 54760af..6bce860 100644
--- a/arch/arm/configs/sdxpoorwills_defconfig
+++ b/arch/arm/configs/sdxpoorwills_defconfig
@@ -20,6 +20,7 @@
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
+CONFIG_SLAB_FREELIST_RANDOM=y
CONFIG_PROFILING=y
CONFIG_CC_STACKPROTECTOR_REGULAR=y
CONFIG_MODULES=y
@@ -432,6 +433,7 @@
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_CREDENTIALS=y
CONFIG_FAULT_INJECTION=y
CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAULT_INJECTION_DEBUG_FS=y
@@ -441,6 +443,7 @@
CONFIG_IRQSOFF_TRACER=y
CONFIG_PREEMPT_TRACER=y
CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_PANIC_ON_DATA_CORRUPTION=y
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_SET_MODULE_RONX=y
CONFIG_CORESIGHT=y
@@ -460,6 +463,7 @@
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_HARDENED_USERCOPY=y
+CONFIG_HARDENED_USERCOPY_PAGESPAN=y
CONFIG_SECURITY_SELINUX=y
# CONFIG_SECURITY_SELINUX_AVC_STATS is not set
CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
index 6b43733..4e95a7b 100644
--- a/arch/arm/mach-qcom/Kconfig
+++ b/arch/arm/mach-qcom/Kconfig
@@ -105,7 +105,7 @@
select CPU_FREQ_MSM
select PM_DEVFREQ
select PM_OPP
- select MSM_DEVFREQ_DEVBW
+ select QCOM_DEVFREQ_DEVBW
select DEVFREQ_SIMPLE_DEV
select DEVFREQ_GOV_QCOM_BW_HWMON
select QCOM_BIMC_BWMON
diff --git a/arch/arm64/boot/dts/qcom/apq8009-robot-pronto-refboard.dts b/arch/arm64/boot/dts/qcom/apq8009-robot-pronto-refboard.dts
index 6f3bffc..3a421bf 100644
--- a/arch/arm64/boot/dts/qcom/apq8009-robot-pronto-refboard.dts
+++ b/arch/arm64/boot/dts/qcom/apq8009-robot-pronto-refboard.dts
@@ -172,7 +172,7 @@
cdc-vdda-cp-supply = <&pm8916_s4>;
qcom,cdc-vdda-cp-voltage = <1800000 2100000>;
- qcom,cdc-vdda-cp-current = <1800000>;
+ qcom,cdc-vdda-cp-current = <770000>;
cdc-vdd-io-supply = <&pm8916_l5>;
qcom,cdc-vdd-io-voltage = <1800000 1800000>;
@@ -180,7 +180,7 @@
cdc-vdd-pa-supply = <&pm8916_s4>;
qcom,cdc-vdd-pa-voltage = <1800000 2100000>;
- qcom,cdc-vdd-pa-current = <1800000>;
+ qcom,cdc-vdd-pa-current = <5000>;
cdc-vdd-mic-bias-supply = <&pm8916_l13>;
qcom,cdc-vdd-mic-bias-voltage = <3075000 3075000>;
diff --git a/arch/arm64/boot/dts/qcom/msm8909-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8909-pinctrl.dtsi
index 3bf23de..c22259b 100644
--- a/arch/arm64/boot/dts/qcom/msm8909-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8909-pinctrl.dtsi
@@ -14,6 +14,7 @@
msm_gpio: pinctrl@1000000 {
compatible = "qcom,msm8909-pinctrl";
reg = <0x1000000 0x300000>;
+ reg-names = "pinctrl_regs";
interrupts = <0 208 0>;
interrupts-extended = <&wakegic GIC_SPI 208 IRQ_TYPE_NONE>;
gpio-controller;
diff --git a/arch/arm64/boot/dts/qcom/msm8917-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8917-pinctrl.dtsi
index 0e613b6..8238b98 100644
--- a/arch/arm64/boot/dts/qcom/msm8917-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8917-pinctrl.dtsi
@@ -15,6 +15,7 @@
tlmm: pinctrl@1000000 {
compatible = "qcom,msm8917-pinctrl";
reg = <0x1000000 0x300000>;
+ reg-names = "pinctrl_regs";
interrupts-extended = <&wakegic GIC_SPI 208 IRQ_TYPE_NONE>;
gpio-controller;
#gpio-cells = <2>;
diff --git a/arch/arm64/boot/dts/qcom/msm8937-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8937-pinctrl.dtsi
index a730287..f07069c 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-pinctrl.dtsi
@@ -15,6 +15,7 @@
tlmm: pinctrl@1000000 {
compatible = "qcom,msm8937-pinctrl";
reg = <0x1000000 0x300000>;
+ reg-names = "pinctrl_regs";
interrupts-extended = <&wakegic GIC_SPI 208 IRQ_TYPE_NONE>;
gpio-controller;
#gpio-cells = <2>;
diff --git a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi
index 72513e1..9da42f9 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi
@@ -15,6 +15,7 @@
tlmm: pinctrl@1000000 {
compatible = "qcom,msm8953-pinctrl";
reg = <0x1000000 0x300000>;
+ reg-names = "pinctrl_regs";
interrupts = <0 208 0>;
interrupts-extended = <&wakegic GIC_SPI 208 IRQ_TYPE_NONE>;
gpio-controller;
diff --git a/arch/arm64/boot/dts/qcom/sdm429.dtsi b/arch/arm64/boot/dts/qcom/sdm429.dtsi
index 65f7b5e..0a8aab3 100644
--- a/arch/arm64/boot/dts/qcom/sdm429.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm429.dtsi
@@ -205,6 +205,17 @@
#clock-cells = <1>;
};
+
+ /* Disable secure_mem node */
+ qcom,ion {
+ /delete-node/ qcom,ion-heap@8;
+ };
+ /* delete hypervisor node for GPU*/
+ /delete-node/ qcom,kgsl-hyp;
+};
+
+&secure_mem {
+ status = "disabled";
};
&clock_gcc_mdss {
@@ -226,3 +237,8 @@
/* disable mem pools */
/delete-node/qcom,gpu-mempools;
};
+
+/* Disable secure context for Graphics*/
+&kgsl_msm_iommu {
+ /delete-node/ gfx3d_secure;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
index 0453cee..cfd96cb3 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
@@ -13,7 +13,8 @@
&soc {
tlmm: pinctrl@03400000 {
compatible = "qcom,sdm670-pinctrl";
- reg = <0x03400000 0xc00000>;
+ reg = <0x03400000 0xc00000>, <0x179900F0 0x60>;
+ reg-names = "pinctrl_regs", "spi_cfg_regs";
interrupts = <0 208 0>;
gpio-controller;
#gpio-cells = <2>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi
index 019607c..53f8084 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-pinctrl.dtsi
@@ -13,7 +13,8 @@
&soc {
tlmm: pinctrl@03400000 {
compatible = "qcom,sdm845-pinctrl";
- reg = <0x03400000 0xc00000>;
+ reg = <0x03400000 0xc00000>, <0x179900F0 0x60>;
+ reg-names = "pinctrl_regs", "spi_cfg_regs";
interrupts = <0 208 0>;
gpio-controller;
#gpio-cells = <2>;
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
index 1c76daa..abb56a9 100644
--- a/drivers/android/binder_alloc.c
+++ b/drivers/android/binder_alloc.c
@@ -669,7 +669,7 @@
goto err_already_mapped;
}
- area = get_vm_area(vma->vm_end - vma->vm_start, VM_IOREMAP);
+ area = get_vm_area(vma->vm_end - vma->vm_start, VM_ALLOC);
if (area == NULL) {
ret = -ENOMEM;
failure_string = "get_vm_area";
diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c
index 8dfdf85..94e672b 100644
--- a/drivers/clk/qcom/gpucc-sdm845.c
+++ b/drivers/clk/qcom/gpucc-sdm845.c
@@ -292,6 +292,7 @@
F(430000000, P_CRC_DIV, 1, 0, 0),
F(504000000, P_CRC_DIV, 1, 0, 0),
F(565000000, P_CRC_DIV, 1, 0, 0),
+ F(610000000, P_CRC_DIV, 1, 0, 0),
F(650000000, P_CRC_DIV, 1, 0, 0),
F(700000000, P_CRC_DIV, 1, 0, 0),
F(750000000, P_CRC_DIV, 1, 0, 0),
diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c
index 5135571..99c0b9f 100644
--- a/drivers/extcon/extcon.c
+++ b/drivers/extcon/extcon.c
@@ -482,7 +482,7 @@
}
EXPORT_SYMBOL_GPL(extcon_sync);
-int extcon_blocking_sync(struct extcon_dev *edev, unsigned int id, bool val)
+int extcon_blocking_sync(struct extcon_dev *edev, unsigned int id, u8 val)
{
int index;
diff --git a/drivers/gpu/msm/adreno-gpulist.h b/drivers/gpu/msm/adreno-gpulist.h
index 614b1c7..0a59334 100644
--- a/drivers/gpu/msm/adreno-gpulist.h
+++ b/drivers/gpu/msm/adreno-gpulist.h
@@ -207,11 +207,9 @@
.major = 0,
.minor = 4,
.patchid = ANY_ID,
- .features = ADRENO_PREEMPTION | ADRENO_64BIT |
- ADRENO_CONTENT_PROTECTION | ADRENO_CPZ_RETENTION,
+ .features = ADRENO_PREEMPTION | ADRENO_64BIT,
.pm4fw_name = "a530_pm4.fw",
.pfpfw_name = "a530_pfp.fw",
- .zap_name = "a506_zap",
.gpudev = &adreno_a5xx_gpudev,
.gmem_size = (SZ_128K + SZ_8K),
.num_protected_regs = 0x20,
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 2585a27..7c219fa 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1993,6 +1993,17 @@
}
}
+ if (kgsl_gmu_isenabled(device) && adreno_dev->perfctr_ifpc_lo == 0) {
+ ret = adreno_perfcounter_get(adreno_dev,
+ KGSL_PERFCOUNTER_GROUP_GPMU_PWR, 4,
+ &adreno_dev->perfctr_ifpc_lo, NULL,
+ PERFCOUNTER_FLAG_KERNEL);
+ if (ret) {
+ WARN_ONCE(1, "Unable to get perf counter for IFPC\n");
+ adreno_dev->perfctr_ifpc_lo = 0;
+ }
+ }
+
/* Clear the busy_data stats - we're starting over from scratch */
adreno_dev->busy_data.gpu_busy = 0;
adreno_dev->busy_data.bif_ram_cycles = 0;
@@ -2001,6 +2012,7 @@
adreno_dev->busy_data.bif_ram_cycles_write_ch1 = 0;
adreno_dev->busy_data.bif_starved_ram = 0;
adreno_dev->busy_data.bif_starved_ram_ch1 = 0;
+ adreno_dev->busy_data.num_ifpc = 0;
/* Restore performance counter registers with saved values */
adreno_perfcounter_restore(adreno_dev);
@@ -3552,6 +3564,17 @@
stats->ram_time = ram_cycles;
stats->ram_wait = starved_ram;
}
+
+ if (adreno_dev->perfctr_ifpc_lo != 0) {
+ uint32_t num_ifpc;
+
+ num_ifpc = counter_delta(device, adreno_dev->perfctr_ifpc_lo,
+ &busy->num_ifpc);
+ adreno_dev->ifpc_count += num_ifpc;
+ if (num_ifpc > 0)
+ trace_adreno_ifpc_count(adreno_dev->ifpc_count);
+ }
+
if (adreno_dev->lm_threshold_count &&
gpudev->count_throttles)
gpudev->count_throttles(adreno_dev, adj);
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index fc32fb9..555856a 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -309,6 +309,7 @@
unsigned int bif_ram_cycles_write_ch1;
unsigned int bif_starved_ram;
unsigned int bif_starved_ram_ch1;
+ unsigned int num_ifpc;
unsigned int throttle_cycles[ADRENO_GPMU_THROTTLE_COUNTERS];
};
@@ -467,6 +468,7 @@
* stall cycles in case of GBIF)
* @starved_ram_lo_ch1: Number of cycles GBIF is stalled by DDR channel 1
* @perfctr_pwr_lo: GPU busy cycles
+ * @perfctr_ifpc_lo: IFPC count
* @halt: Atomic variable to check whether the GPU is currently halted
* @pending_irq_refcnt: Atomic variable to keep track of running IRQ handlers
* @ctx_d_debugfs: Context debugfs node
@@ -484,6 +486,7 @@
* @lm_limit: limiting value for LM
* @lm_threshold_count: register value for counter for lm threshold breakin
* @lm_threshold_cross: number of current peaks exceeding threshold
+ * @ifpc_count: Number of times the GPU went into IFPC
* @speed_bin: Indicate which power level set to use
* @csdev: Pointer to a coresight device (if applicable)
* @gpmu_throttle_counters - counteers for number of throttled clocks
@@ -533,6 +536,7 @@
unsigned int starved_ram_lo;
unsigned int starved_ram_lo_ch1;
unsigned int perfctr_pwr_lo;
+ unsigned int perfctr_ifpc_lo;
atomic_t halt;
atomic_t pending_irq_refcnt;
struct dentry *ctx_d_debugfs;
@@ -552,6 +556,7 @@
uint32_t lm_limit;
uint32_t lm_threshold_count;
uint32_t lm_threshold_cross;
+ uint32_t ifpc_count;
unsigned int speed_bin;
unsigned int quirks;
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index f7f01f5..b095b027 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -115,8 +115,11 @@
rb->wptr = rb->_wptr;
spin_unlock_irqrestore(&rb->preempt_lock, flags);
- if (ret)
- kgsl_device_snapshot(KGSL_DEVICE(adreno_dev), NULL, false);
+ if (ret) {
+ /* If WPTR update fails, set the fault and trigger recovery */
+ adreno_set_gpu_fault(adreno_dev, ADRENO_GMU_FAULT);
+ adreno_dispatcher_schedule(KGSL_DEVICE(adreno_dev));
+ }
}
diff --git a/drivers/gpu/msm/adreno_sysfs.c b/drivers/gpu/msm/adreno_sysfs.c
index 022aa9f..a7aa939 100644
--- a/drivers/gpu/msm/adreno_sysfs.c
+++ b/drivers/gpu/msm/adreno_sysfs.c
@@ -341,6 +341,11 @@
return kgsl_gmu_isenabled(device) && gmu->idle_level >= GPU_HW_IFPC;
}
+static unsigned int _ifpc_count_show(struct adreno_device *adreno_dev)
+{
+ return adreno_dev->ifpc_count;
+}
+
static unsigned int _preempt_count_show(struct adreno_device *adreno_dev)
{
struct adreno_preemption *preempt = &adreno_dev->preempt;
@@ -451,6 +456,7 @@
static ADRENO_SYSFS_BOOL(hwcg);
static ADRENO_SYSFS_BOOL(throttling);
static ADRENO_SYSFS_BOOL(ifpc);
+static ADRENO_SYSFS_RO_U32(ifpc_count);
@@ -472,6 +478,7 @@
&adreno_attr_usesgmem.attr,
&adreno_attr_skipsaverestore.attr,
&adreno_attr_ifpc.attr,
+ &adreno_attr_ifpc_count.attr,
&adreno_attr_preempt_count.attr,
NULL,
};
diff --git a/drivers/gpu/msm/adreno_trace.h b/drivers/gpu/msm/adreno_trace.h
index de028fa..bf5e798 100644
--- a/drivers/gpu/msm/adreno_trace.h
+++ b/drivers/gpu/msm/adreno_trace.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, 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
@@ -609,6 +609,19 @@
__entry->next->id, __entry->cur->id, __entry->level
)
);
+
+TRACE_EVENT(adreno_ifpc_count,
+ TP_PROTO(unsigned int ifpc_count),
+ TP_ARGS(ifpc_count),
+ TP_STRUCT__entry(
+ __field(unsigned int, ifpc_count)
+ ),
+ TP_fast_assign(
+ __entry->ifpc_count = ifpc_count;
+ ),
+ TP_printk("total times GMU entered IFPC = %d", __entry->ifpc_count)
+);
+
#endif /* _ADRENO_TRACE_H */
/* This part must be outside protection */
diff --git a/drivers/leds/leds-qpnp-wled.c b/drivers/leds/leds-qpnp-wled.c
index d272ca6..18a1163 100644
--- a/drivers/leds/leds-qpnp-wled.c
+++ b/drivers/leds/leds-qpnp-wled.c
@@ -2090,22 +2090,26 @@
return rc;
/* Configure the HYBRID THRESHOLD register */
- if (wled->hyb_thres < QPNP_WLED_HYB_THRES_MIN)
- wled->hyb_thres = QPNP_WLED_HYB_THRES_MIN;
- else if (wled->hyb_thres > QPNP_WLED_HYB_THRES_MAX)
- wled->hyb_thres = QPNP_WLED_HYB_THRES_MAX;
+ if (wled->dim_mode == QPNP_WLED_DIM_HYBRID) {
+ if (wled->hyb_thres < QPNP_WLED_HYB_THRES_MIN)
+ wled->hyb_thres = QPNP_WLED_HYB_THRES_MIN;
+ else if (wled->hyb_thres > QPNP_WLED_HYB_THRES_MAX)
+ wled->hyb_thres = QPNP_WLED_HYB_THRES_MAX;
- rc = qpnp_wled_read_reg(wled, QPNP_WLED_HYB_THRES_REG(wled->sink_base),
- ®);
- if (rc < 0)
- return rc;
- reg &= QPNP_WLED_HYB_THRES_MASK;
- temp = fls(wled->hyb_thres / QPNP_WLED_HYB_THRES_MIN) - 1;
- reg |= temp;
- rc = qpnp_wled_write_reg(wled, QPNP_WLED_HYB_THRES_REG(wled->sink_base),
- reg);
- if (rc)
- return rc;
+ rc = qpnp_wled_read_reg(wled,
+ QPNP_WLED_HYB_THRES_REG(wled->sink_base),
+ ®);
+ if (rc < 0)
+ return rc;
+ reg &= QPNP_WLED_HYB_THRES_MASK;
+ temp = fls(wled->hyb_thres / QPNP_WLED_HYB_THRES_MIN) - 1;
+ reg |= temp;
+ rc = qpnp_wled_write_reg(wled,
+ QPNP_WLED_HYB_THRES_REG(wled->sink_base),
+ reg);
+ if (rc)
+ return rc;
+ }
/* Configure TEST5 register */
if (wled->dim_mode == QPNP_WLED_DIM_DIGITAL) {
@@ -2642,9 +2646,10 @@
else
wled->max_strings = QPNP_WLED_MAX_STRINGS;
+ temp_val = 0;
prop = of_find_property(pdev->dev.of_node,
"qcom,led-strings-list", &temp_val);
- if (!prop || !temp_val || temp_val > QPNP_WLED_MAX_STRINGS) {
+ if (!prop || temp_val > QPNP_WLED_MAX_STRINGS) {
dev_err(&pdev->dev, "Invalid strings info, use default");
wled->num_strings = wled->max_strings;
for (i = 0; i < wled->num_strings; i++)
diff --git a/drivers/media/platform/msm/camera_v2/camera/camera.c b/drivers/media/platform/msm/camera_v2/camera/camera.c
index 01ee5d4..1da62e2 100644
--- a/drivers/media/platform/msm/camera_v2/camera/camera.c
+++ b/drivers/media/platform/msm/camera_v2/camera/camera.c
@@ -688,8 +688,6 @@
if (rc < 0)
goto post_fail;
}
- /* Enable power collapse latency */
- msm_pm_qos_update_request(CAMERA_ENABLE_PC_LATENCY);
} else {
rc = msm_create_command_ack_q(pvdev->vdev->num,
find_first_zero_bit((const unsigned long *)&opn_idx,
@@ -713,6 +711,7 @@
command_ack_q_fail:
msm_destroy_session(pvdev->vdev->num);
session_fail:
+ msm_pm_qos_update_request(CAMERA_ENABLE_PC_LATENCY);
pm_relax(&pvdev->vdev->dev);
stream_fail:
camera_v4l2_vb2_q_release(filep);
@@ -786,6 +785,8 @@
camera_v4l2_vb2_q_release(filep);
msm_destroy_session(pvdev->vdev->num);
+ /* Enable power collapse latency */
+ msm_pm_qos_update_request(CAMERA_ENABLE_PC_LATENCY);
pm_relax(&pvdev->vdev->dev);
} else {
msm_delete_command_ack_q(pvdev->vdev->num,
@@ -933,6 +934,7 @@
pvdev->vdev->ioctl_ops = &camera_v4l2_ioctl_ops;
pvdev->vdev->minor = -1;
pvdev->vdev->vfl_type = VFL_TYPE_GRABBER;
+ pvdev->vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
rc = video_register_device(pvdev->vdev,
VFL_TYPE_GRABBER, -1);
if (WARN_ON(rc < 0))
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
index cfe8054..7c55ad8 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
@@ -691,7 +691,8 @@
spin_lock_init(&vfe_dev->shared_data_lock);
spin_lock_init(&vfe_dev->reg_update_lock);
spin_lock_init(&req_history_lock);
- spin_lock_init(&vfe_dev->completion_lock);
+ spin_lock_init(&vfe_dev->reset_completion_lock);
+ spin_lock_init(&vfe_dev->halt_completion_lock);
media_entity_pads_init(&vfe_dev->subdev.sd.entity, 0, NULL);
vfe_dev->subdev.sd.entity.function = MSM_CAMERA_SUBDEV_VFE;
//vfe_dev->subdev.sd.entity.group_id = MSM_CAMERA_SUBDEV_VFE;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index f560e83..7697392 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -802,7 +802,8 @@
struct mutex core_mutex;
spinlock_t shared_data_lock;
spinlock_t reg_update_lock;
- spinlock_t completion_lock;
+ spinlock_t reset_completion_lock;
+ spinlock_t halt_completion_lock;
/* Tasklet info */
atomic_t irq_cnt;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index 72ab3ba..d4068be 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -363,15 +363,24 @@
static void msm_vfe40_process_reset_irq(struct vfe_device *vfe_dev,
uint32_t irq_status0, uint32_t irq_status1)
{
- if (irq_status0 & (1 << 31))
+ unsigned long flags;
+
+ if (irq_status0 & (1 << 31)) {
+ spin_lock_irqsave(&vfe_dev->reset_completion_lock, flags);
complete(&vfe_dev->reset_complete);
+ spin_unlock_irqrestore(&vfe_dev->reset_completion_lock, flags);
+ }
}
static void msm_vfe40_process_halt_irq(struct vfe_device *vfe_dev,
uint32_t irq_status0, uint32_t irq_status1)
{
+ unsigned long flags;
+
if (irq_status1 & (1 << 8)) {
+ spin_lock_irqsave(&vfe_dev->halt_completion_lock, flags);
complete(&vfe_dev->halt_complete);
+ spin_unlock_irqrestore(&vfe_dev->halt_completion_lock, flags);
msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x2C0);
}
}
@@ -761,8 +770,11 @@
uint32_t first_start, uint32_t blocking_call)
{
long rc = 0;
+ unsigned long flags;
+ spin_lock_irqsave(&vfe_dev->reset_completion_lock, flags);
init_completion(&vfe_dev->reset_complete);
+ spin_unlock_irqrestore(&vfe_dev->reset_completion_lock, flags);
if (first_start) {
msm_camera_io_w_mb(0x1FF, vfe_dev->vfe_base + 0xC);
@@ -1777,6 +1789,7 @@
int rc = 0;
enum msm_vfe_input_src i;
struct msm_isp_timestamp ts;
+ unsigned long flags;
/* Keep only halt and restart mask */
msm_vfe40_config_irq(vfe_dev, (1 << 31), (1 << 8),
@@ -1793,7 +1806,9 @@
msm_isp_stats_stream_update(vfe_dev);
if (blocking) {
+ spin_lock_irqsave(&vfe_dev->halt_completion_lock, flags);
init_completion(&vfe_dev->halt_complete);
+ spin_unlock_irqrestore(&vfe_dev->halt_completion_lock, flags);
/* Halt AXI Bus Bridge */
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x2C0);
rc = wait_for_completion_interruptible_timeout(
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
index b867eb3..1ded01a 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
@@ -440,10 +440,10 @@
unsigned long flags;
if (irq_status0 & (1 << 31)) {
- spin_lock_irqsave(&vfe_dev->completion_lock, flags);
+ spin_lock_irqsave(&vfe_dev->reset_completion_lock, flags);
complete(&vfe_dev->reset_complete);
vfe_dev->reset_pending = 0;
- spin_unlock_irqrestore(&vfe_dev->completion_lock, flags);
+ spin_unlock_irqrestore(&vfe_dev->reset_completion_lock, flags);
}
}
@@ -451,9 +451,12 @@
uint32_t irq_status0, uint32_t irq_status1)
{
uint32_t val = 0;
+ unsigned long flags;
if (irq_status1 & (1 << 8)) {
+ spin_lock_irqsave(&vfe_dev->halt_completion_lock, flags);
complete(&vfe_dev->halt_complete);
+ spin_unlock_irqrestore(&vfe_dev->halt_completion_lock, flags);
msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x400);
}
@@ -770,9 +773,9 @@
uint32_t reset;
unsigned long flags;
- spin_lock_irqsave(&vfe_dev->completion_lock, flags);
+ spin_lock_irqsave(&vfe_dev->reset_completion_lock, flags);
init_completion(&vfe_dev->reset_complete);
- spin_unlock_irqrestore(&vfe_dev->completion_lock, flags);
+ spin_unlock_irqrestore(&vfe_dev->reset_completion_lock, flags);
if (blocking_call)
vfe_dev->reset_pending = 1;
@@ -2002,6 +2005,7 @@
enum msm_vfe_input_src i;
uint32_t val = 0;
struct msm_isp_timestamp ts;
+ unsigned long flags;
val = msm_camera_io_r(vfe_dev->vfe_vbif_base + VFE47_VBIF_CLK_OFFSET);
val |= 0x1;
@@ -2018,7 +2022,9 @@
__func__, vfe_dev->pdev->id, blocking);
if (blocking) {
+ spin_lock_irqsave(&vfe_dev->halt_completion_lock, flags);
init_completion(&vfe_dev->halt_complete);
+ spin_unlock_irqrestore(&vfe_dev->halt_completion_lock, flags);
/* Halt AXI Bus Bridge */
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x400);
rc = wait_for_completion_interruptible_timeout(
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index 3832d63..1b04e1d 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -1739,12 +1739,40 @@
struct msm_vfe_axi_halt_cmd halt_cmd;
struct vfe_device *temp_dev = NULL;
uint32_t irq_status0 = 0, irq_status1 = 0;
+ struct vfe_device *vfe_dev_other = NULL;
+ uint32_t vfe_id_other = 0;
+ unsigned long flags;
if (atomic_read(&vfe_dev->error_info.overflow_state) !=
NO_OVERFLOW)
/* Recovery is already in Progress */
return;
+ /* if there are no active streams - do not start recovery */
+ if (vfe_dev->is_split) {
+ if (vfe_dev->pdev->id == ISP_VFE0)
+ vfe_id_other = ISP_VFE1;
+ else
+ vfe_id_other = ISP_VFE0;
+
+ spin_lock_irqsave(
+ &vfe_dev->common_data->common_dev_data_lock, flags);
+ vfe_dev_other = vfe_dev->common_data->dual_vfe_res->
+ vfe_dev[vfe_id_other];
+ if (!vfe_dev->axi_data.num_active_stream ||
+ !vfe_dev_other->axi_data.num_active_stream) {
+ spin_unlock_irqrestore(
+ &vfe_dev->common_data->common_dev_data_lock,
+ flags);
+ pr_err("%s:skip the recovery as no active streams\n",
+ __func__);
+ return;
+ }
+ spin_unlock_irqrestore(
+ &vfe_dev->common_data->common_dev_data_lock, flags);
+ } else if (!vfe_dev->axi_data.num_active_stream)
+ return;
+
if (event == ISP_EVENT_PING_PONG_MISMATCH &&
vfe_dev->axi_data.recovery_count < MAX_RECOVERY_THRESHOLD) {
pr_err("%s: ping pong mismatch on vfe%d recovery count %d\n",
diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c
index d52d8bc..559ad4d 100644
--- a/drivers/media/platform/msm/camera_v2/msm.c
+++ b/drivers/media/platform/msm/camera_v2/msm.c
@@ -238,8 +238,13 @@
void msm_pm_qos_update_request(int val)
{
- pr_info("%s: update request %d", __func__, val);
- pm_qos_update_request(&msm_v4l2_pm_qos_request, val);
+ /* update just before creating the first session,
+ * or after destroying the last session.
+ */
+ if (msm_session_q && msm_session_q->len == 0) {
+ pr_info("%s: update request %d", __func__, val);
+ pm_qos_update_request(&msm_v4l2_pm_qos_request, val);
+ }
}
struct msm_session *msm_session_find(unsigned int session_id)
diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c
index c1fc8ba..0c07bef 100644
--- a/drivers/net/wireless/cnss2/pci.c
+++ b/drivers/net/wireless/cnss2/pci.c
@@ -229,6 +229,27 @@
}
EXPORT_SYMBOL(cnss_pci_link_down);
+int cnss_pci_is_device_down(struct device *dev)
+{
+ struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
+ struct cnss_pci_data *pci_priv;
+
+ if (!plat_priv) {
+ cnss_pr_err("plat_priv is NULL\n");
+ return -ENODEV;
+ }
+
+ pci_priv = plat_priv->bus_priv;
+ if (!pci_priv) {
+ cnss_pr_err("pci_priv is NULL\n");
+ return -ENODEV;
+ }
+
+ return test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state) |
+ pci_priv->pci_link_down_ind;
+}
+EXPORT_SYMBOL(cnss_pci_is_device_down);
+
int cnss_pci_call_driver_probe(struct cnss_pci_data *pci_priv)
{
int ret = 0;
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index 15f3df9..dcfe105 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -35,6 +35,7 @@
#include <linux/pm.h>
#include <linux/log2.h>
#include <linux/irq.h>
+#include <soc/qcom/scm.h>
#include "../core.h"
#include "../pinconf.h"
#include "pinctrl-msm.h"
@@ -73,6 +74,8 @@
const struct msm_pinctrl_soc_data *soc;
void __iomem *regs;
void __iomem *pdc_regs;
+ phys_addr_t spi_cfg_regs;
+ phys_addr_t spi_cfg_end;
};
static struct msm_pinctrl *msm_pinctrl_data;
@@ -1279,8 +1282,12 @@
struct irq_desc *desc = irq_data_to_desc(d);
struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq);
struct irq_data *dir_conn_data = NULL;
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
int offset = 0;
- unsigned int virt = 0;
+ unsigned int virt = 0, val = 0;
+ struct msm_pinctrl *pctrl;
+ phys_addr_t spi_cfg_reg = 0;
+ unsigned long flags;
offset = select_dir_conn_mux(d, &irq);
if (offset < 0 || !parent_data)
@@ -1296,6 +1303,28 @@
dir_conn_data = &(desc->irq_data);
if (dir_conn_data) {
+
+ pctrl = gpiochip_get_data(gc);
+ if (pctrl->spi_cfg_regs) {
+ spi_cfg_reg = pctrl->spi_cfg_regs +
+ (dir_conn_data->hwirq / 32) * 4;
+ if (spi_cfg_reg < pctrl->spi_cfg_end) {
+ spin_lock_irqsave(&pctrl->lock, flags);
+ val = scm_io_read(spi_cfg_reg);
+ /*
+ * Clear the respective bit for edge type
+ * interrupt
+ */
+ val &= ~(1 << (dir_conn_data->hwirq % 32));
+ WARN_ON(scm_io_write(spi_cfg_reg, val));
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+ } else
+ pr_err("%s: type config failed for SPI: %lu\n",
+ __func__, irq);
+ } else
+ pr_debug("%s: type config for SPI is not supported\n",
+ __func__);
+
if (dir_conn_data->chip && dir_conn_data->chip->irq_set_type)
dir_conn_data->chip->irq_set_type(dir_conn_data,
IRQ_TYPE_EDGE_RISING);
@@ -1331,11 +1360,19 @@
{
struct irq_desc *desc = irq_data_to_desc(d);
struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq);
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
irq_hw_number_t irq = 0;
+ struct msm_pinctrl *pctrl;
+ phys_addr_t spi_cfg_reg = 0;
+ unsigned int config_val = 0;
+ unsigned int val = 0;
+ unsigned long flags;
if (!parent_data)
return 0;
+ pctrl = gpiochip_get_data(gc);
+
if (type == IRQ_TYPE_EDGE_BOTH)
add_dirconn_tlmm(d, irq);
else if (is_gpio_dual_edge(d, &irq))
@@ -1343,11 +1380,33 @@
else if (is_gpio_tlmm_dc(d, type))
type = IRQ_TYPE_EDGE_RISING;
- if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
+ /*
+ * Shared SPI config for Edge is 0 and
+ * for Level interrupt is 1
+ */
+ if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) {
irq_set_handler_locked(d, handle_level_irq);
- else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+ config_val = 1;
+ } else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
irq_set_handler_locked(d, handle_edge_irq);
+ if (pctrl->spi_cfg_regs && type != IRQ_TYPE_NONE) {
+ spi_cfg_reg = pctrl->spi_cfg_regs +
+ (parent_data->hwirq / 32) * 4;
+ if (spi_cfg_reg < pctrl->spi_cfg_end) {
+ spin_lock_irqsave(&pctrl->lock, flags);
+ val = scm_io_read(spi_cfg_reg);
+ val &= ~(1 << (parent_data->hwirq % 32));
+ if (config_val)
+ val |= (1 << (parent_data->hwirq % 32));
+ WARN_ON(scm_io_write(spi_cfg_reg, val));
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+ } else
+ pr_err("%s: type config failed for SPI: %lu\n",
+ __func__, irq);
+ } else
+ pr_debug("%s: SPI type config is not supported\n", __func__);
+
if (parent_data->chip->irq_set_type)
return parent_data->chip->irq_set_type(parent_data, type);
@@ -1653,6 +1712,7 @@
struct msm_pinctrl *pctrl;
struct resource *res;
int ret;
+ char *key;
msm_pinctrl_data = pctrl = devm_kzalloc(&pdev->dev,
sizeof(*pctrl), GFP_KERNEL);
@@ -1666,14 +1726,23 @@
spin_lock_init(&pctrl->lock);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ key = "pinctrl_regs";
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, key);
pctrl->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pctrl->regs))
return PTR_ERR(pctrl->regs);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ key = "pdc_regs";
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, key);
pctrl->pdc_regs = devm_ioremap_resource(&pdev->dev, res);
+ key = "spi_cfg_regs";
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, key);
+ if (res) {
+ pctrl->spi_cfg_regs = res->start;
+ pctrl->spi_cfg_end = res->end;
+ }
+
msm_pinctrl_setup_pm_reset(pctrl);
pctrl->irq = platform_get_irq(pdev, 0);
diff --git a/drivers/platform/msm/mhi_dev/mhi.c b/drivers/platform/msm/mhi_dev/mhi.c
index 3e245cc..c938e8e 100644
--- a/drivers/platform/msm/mhi_dev/mhi.c
+++ b/drivers/platform/msm/mhi_dev/mhi.c
@@ -458,8 +458,9 @@
mhi_update_state_info(MHI_DEV_UEVENT_CTRL, MHI_STATE_CONNECTED);
- ep_pcie_mask_irq_event(mhi_ctx->phandle,
- EP_PCIE_INT_EVT_MHI_A7, true);
+ if (!mhi_ctx->mhi_int)
+ ep_pcie_mask_irq_event(mhi_ctx->phandle,
+ EP_PCIE_INT_EVT_MHI_A7, true);
break;
case IPA_MHI_EVENT_DATA_AVAILABLE:
rc = mhi_dev_notify_sm_event(MHI_DEV_EVENT_HW_ACC_WAKEUP);
@@ -2758,8 +2759,9 @@
EP_PCIE_EVENT_PM_D3_COLD |
EP_PCIE_EVENT_PM_D0 |
EP_PCIE_EVENT_PM_RST_DEAST |
- EP_PCIE_EVENT_MHI_A7 |
EP_PCIE_EVENT_LINKDOWN;
+ if (!mhi_ctx->mhi_int)
+ mhi_ctx->event_reg.events |= EP_PCIE_EVENT_MHI_A7;
mhi_ctx->event_reg.user = mhi_ctx;
mhi_ctx->event_reg.mode = EP_PCIE_TRIGGER_CALLBACK;
mhi_ctx->event_reg.callback = mhi_dev_sm_pcie_handler;
@@ -2902,8 +2904,9 @@
EP_PCIE_EVENT_PM_D3_COLD |
EP_PCIE_EVENT_PM_D0 |
EP_PCIE_EVENT_PM_RST_DEAST |
- EP_PCIE_EVENT_MHI_A7 |
EP_PCIE_EVENT_LINKDOWN;
+ if (!mhi_ctx->mhi_int)
+ mhi_ctx->event_reg.events |= EP_PCIE_EVENT_MHI_A7;
mhi_ctx->event_reg.user = mhi_ctx;
mhi_ctx->event_reg.mode = EP_PCIE_TRIGGER_CALLBACK;
mhi_ctx->event_reg.callback = mhi_dev_sm_pcie_handler;
diff --git a/drivers/power/supply/qcom/smb138x-charger.c b/drivers/power/supply/qcom/smb138x-charger.c
index e03e0a8..7dbd189 100644
--- a/drivers/power/supply/qcom/smb138x-charger.c
+++ b/drivers/power/supply/qcom/smb138x-charger.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018 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
@@ -1265,7 +1265,9 @@
struct smb_irq_data *irq_data = data;
struct smb138x *chip = irq_data->parent_data;
- power_supply_changed(chip->parallel_psy);
+ if (chip->parallel_psy)
+ power_supply_changed(chip->parallel_psy);
+
return IRQ_HANDLED;
}
diff --git a/drivers/power/supply/qcom/step-chg-jeita.c b/drivers/power/supply/qcom/step-chg-jeita.c
index 3b4b275..3e8b46b 100644
--- a/drivers/power/supply/qcom/step-chg-jeita.c
+++ b/drivers/power/supply/qcom/step-chg-jeita.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018 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
@@ -79,10 +79,12 @@
struct votable *fcc_votable;
struct votable *fv_votable;
+ struct votable *usb_icl_votable;
struct wakeup_source *step_chg_ws;
struct power_supply *batt_psy;
struct power_supply *bms_psy;
struct power_supply *main_psy;
+ struct power_supply *usb_psy;
struct delayed_work status_change_work;
struct delayed_work get_config_work;
struct notifier_block nb;
@@ -119,6 +121,17 @@
return true;
}
+static bool is_usb_available(struct step_chg_info *chip)
+{
+ if (!chip->usb_psy)
+ chip->usb_psy = power_supply_get_by_name("usb");
+
+ if (!chip->usb_psy)
+ return false;
+
+ return true;
+}
+
static int read_range_data_from_node(struct device_node *node,
const char *prop_str, struct range_data *ranges,
u32 max_threshold, u32 max_value)
@@ -486,6 +499,7 @@
return (STEP_CHG_HYSTERISIS_DELAY_US - elapsed_us + 1000);
}
+#define JEITA_SUSPEND_HYST_UV 50000
static int handle_jeita(struct step_chg_info *chip)
{
union power_supply_propval pval = {0, };
@@ -504,6 +518,8 @@
vote(chip->fcc_votable, JEITA_VOTER, false, 0);
if (chip->fv_votable)
vote(chip->fv_votable, JEITA_VOTER, false, 0);
+ if (chip->usb_icl_votable)
+ vote(chip->usb_icl_votable, JEITA_VOTER, false, 0);
return 0;
}
@@ -525,12 +541,8 @@
pval.intval,
&chip->jeita_fcc_index,
&fcc_ua);
- if (rc < 0) {
- /* remove the vote if no step-based fcc is found */
- if (chip->fcc_votable)
- vote(chip->fcc_votable, JEITA_VOTER, false, 0);
- goto update_time;
- }
+ if (rc < 0)
+ fcc_ua = 0;
if (!chip->fcc_votable)
chip->fcc_votable = find_votable("FCC");
@@ -538,7 +550,7 @@
/* changing FCC is a must */
return -EINVAL;
- vote(chip->fcc_votable, JEITA_VOTER, true, fcc_ua);
+ vote(chip->fcc_votable, JEITA_VOTER, fcc_ua ? true : false, fcc_ua);
rc = get_val(chip->jeita_fv_config->fv_cfg,
chip->jeita_fv_config->hysteresis,
@@ -546,21 +558,45 @@
pval.intval,
&chip->jeita_fv_index,
&fv_uv);
- if (rc < 0) {
- /* remove the vote if no step-based fcc is found */
- if (chip->fv_votable)
- vote(chip->fv_votable, JEITA_VOTER, false, 0);
- goto update_time;
- }
+ if (rc < 0)
+ fv_uv = 0;
chip->fv_votable = find_votable("FV");
if (!chip->fv_votable)
goto update_time;
- vote(chip->fv_votable, JEITA_VOTER, true, fv_uv);
+ if (!chip->usb_icl_votable)
+ chip->usb_icl_votable = find_votable("USB_ICL");
- pr_debug("%s = %d FCC = %duA FV = %duV\n",
- chip->jeita_fcc_config->prop_name, pval.intval, fcc_ua, fv_uv);
+ if (!chip->usb_icl_votable)
+ goto set_jeita_fv;
+
+ /*
+ * If JEITA float voltage is same as max-vfloat of battery then
+ * skip any further VBAT specific checks.
+ */
+ rc = power_supply_get_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_VOLTAGE_MAX, &pval);
+ if (rc || (pval.intval == fv_uv)) {
+ vote(chip->usb_icl_votable, JEITA_VOTER, false, 0);
+ goto set_jeita_fv;
+ }
+
+ /*
+ * Suspend USB input path if battery voltage is above
+ * JEITA VFLOAT threshold.
+ */
+ if (fv_uv > 0) {
+ rc = power_supply_get_property(chip->batt_psy,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW, &pval);
+ if (!rc && (pval.intval > fv_uv))
+ vote(chip->usb_icl_votable, JEITA_VOTER, true, 0);
+ else if (pval.intval < (fv_uv - JEITA_SUSPEND_HYST_UV))
+ vote(chip->usb_icl_votable, JEITA_VOTER, false, 0);
+ }
+
+set_jeita_fv:
+ vote(chip->fv_votable, JEITA_VOTER, fv_uv ? true : false, fv_uv);
update_time:
chip->jeita_last_update_time = ktime_get();
@@ -618,11 +654,13 @@
int reschedule_us;
int reschedule_jeita_work_us = 0;
int reschedule_step_work_us = 0;
+ union power_supply_propval prop = {0, };
if (!is_batt_available(chip))
- return;
+ goto exit_work;
handle_battery_insertion(chip);
+
/* skip elapsed_us debounce for handling battery temperature */
rc = handle_jeita(chip);
if (rc > 0)
@@ -636,12 +674,28 @@
if (rc < 0)
pr_err("Couldn't handle step rc = %d\n", rc);
+ /* Remove stale votes on USB removal */
+ if (is_usb_available(chip)) {
+ prop.intval = 0;
+ power_supply_get_property(chip->usb_psy,
+ POWER_SUPPLY_PROP_PRESENT, &prop);
+ if (!prop.intval) {
+ if (chip->usb_icl_votable)
+ vote(chip->usb_icl_votable, JEITA_VOTER,
+ false, 0);
+ }
+ }
+
reschedule_us = min(reschedule_jeita_work_us, reschedule_step_work_us);
if (reschedule_us == 0)
- __pm_relax(chip->step_chg_ws);
+ goto exit_work;
else
schedule_delayed_work(&chip->status_change_work,
usecs_to_jiffies(reschedule_us));
+ return;
+
+exit_work:
+ __pm_relax(chip->step_chg_ws);
}
static int step_chg_notifier_call(struct notifier_block *nb,
@@ -653,7 +707,8 @@
if (ev != PSY_EVENT_PROP_CHANGED)
return NOTIFY_OK;
- if ((strcmp(psy->desc->name, "battery") == 0)) {
+ if ((strcmp(psy->desc->name, "battery") == 0)
+ || (strcmp(psy->desc->name, "usb") == 0)) {
__pm_stay_awake(chip->step_chg_ws);
schedule_delayed_work(&chip->status_change_work, 0);
}
diff --git a/drivers/pwm/pwm-qti-lpg.c b/drivers/pwm/pwm-qti-lpg.c
index d24bef1..ab32295 100644
--- a/drivers/pwm/pwm-qti-lpg.c
+++ b/drivers/pwm/pwm-qti-lpg.c
@@ -816,11 +816,11 @@
struct lpg_pwm_config *pwm_config)
{
u16 pwm_value, max_pwm_value;
+ u64 tmp;
- if ((1 << pwm_config->pwm_size) > (INT_MAX / duty_ns))
- pwm_value = duty_ns / (period_ns >> pwm_config->pwm_size);
- else
- pwm_value = (duty_ns << pwm_config->pwm_size) / period_ns;
+ tmp = (u64)duty_ns << pwm_config->pwm_size;
+ do_div(tmp, period_ns);
+ pwm_value = (u16)tmp;
max_pwm_value = (1 << pwm_config->pwm_size) - 1;
if (pwm_value > max_pwm_value)
@@ -1067,6 +1067,7 @@
struct qpnp_lpg_channel *lpg;
int rc = 0, i, period_ns, duty_ns;
u32 *percentages;
+ u64 tmp;
lpg = pwm_dev_to_qpnp_lpg(pwm_chip, pwm);
if (lpg == NULL) {
@@ -1095,10 +1096,9 @@
goto err;
}
/* Translate the pattern in duty_ns to percentage */
- if ((INT_MAX / duty_ns) < 100)
- percentages[i] = duty_ns / (period_ns / 100);
- else
- percentages[i] = (duty_ns * 100) / period_ns;
+ tmp = (u64)duty_ns * 100;
+ do_div(tmp, period_ns);
+ percentages[i] = (u32)tmp;
}
rc = qpnp_lpg_set_lut_pattern(lpg, percentages,
@@ -1114,12 +1114,10 @@
output_pattern->num_entries);
lpg->ramp_config.hi_idx = lpg->ramp_config.lo_idx +
output_pattern->num_entries - 1;
- if ((INT_MAX / period_ns) > output_pattern->cycles_per_duty)
- lpg->ramp_config.step_ms = output_pattern->cycles_per_duty *
- period_ns / NSEC_PER_MSEC;
- else
- lpg->ramp_config.step_ms = (period_ns / NSEC_PER_MSEC) *
- output_pattern->cycles_per_duty;
+
+ tmp = (u64)output_pattern->cycles_per_duty * period_ns;
+ do_div(tmp, NSEC_PER_MSEC);
+ lpg->ramp_config.step_ms = (u16)tmp;
rc = qpnp_lpg_set_ramp_config(lpg);
if (rc < 0)
diff --git a/drivers/soc/qcom/dcc_v2.c b/drivers/soc/qcom/dcc_v2.c
index 279461d..afe304d 100644
--- a/drivers/soc/qcom/dcc_v2.c
+++ b/drivers/soc/qcom/dcc_v2.c
@@ -162,6 +162,28 @@
return 0;
}
+static void dcc_sram_memset(const struct device *dev, void __iomem *dst,
+ int c, size_t count)
+{
+ u64 qc = (u8)c;
+
+ qc |= qc << 8;
+ qc |= qc << 16;
+
+ if (!count || !IS_ALIGNED((unsigned long)dst, 4)
+ || !IS_ALIGNED((unsigned long)count, 4)) {
+ dev_err(dev,
+ "Target address or size not aligned with 4 bytes");
+ return;
+ }
+
+ while (count >= 4) {
+ __raw_writel_no_log(qc, dst);
+ dst += 4;
+ count -= 4;
+ }
+}
+
static bool dcc_ready(struct dcc_drvdata *drvdata)
{
uint32_t val;
@@ -529,7 +551,7 @@
return 0;
overstep:
ret = -EINVAL;
- memset_io(drvdata->ram_base, 0, drvdata->ram_size);
+ dcc_sram_memset(drvdata->dev, drvdata->ram_base, 0, drvdata->ram_size);
dev_err(drvdata->dev, "DCC SRAM oversteps, 0x%x (0x%x)\n",
sram_offset, drvdata->ram_size);
err:
@@ -587,7 +609,8 @@
mutex_lock(&drvdata->mutex);
- memset_io(drvdata->ram_base, 0xDE, drvdata->ram_size);
+ dcc_sram_memset(drvdata->dev, drvdata->ram_base, 0xDE,
+ drvdata->ram_size);
for (list = 0; list < DCC_MAX_LINK_LIST; list++) {
@@ -1647,7 +1670,7 @@
drvdata->nr_config[i] = 0;
}
- memset_io(drvdata->ram_base, 0, drvdata->ram_size);
+ dcc_sram_memset(drvdata->dev, drvdata->ram_base, 0, drvdata->ram_size);
drvdata->data_sink = DCC_DATA_SINK_SRAM;
ret = of_property_read_string(pdev->dev.of_node, "qcom,data-sink",
diff --git a/drivers/soc/qcom/secure_buffer.c b/drivers/soc/qcom/secure_buffer.c
index 1c8bc51..5b82c0b 100644
--- a/drivers/soc/qcom/secure_buffer.c
+++ b/drivers/soc/qcom/secure_buffer.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 Google, Inc
- * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018, 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
@@ -142,7 +142,8 @@
* secure environment to ensure the data is actually present
* in RAM
*/
- dmac_flush_range(chunk_list, chunk_list + chunk_list_len);
+ dmac_flush_range(chunk_list,
+ (void *)chunk_list + chunk_list_len);
ret = secure_buffer_change_chunk(chunk_list_phys,
nchunks, V2_CHUNK_SIZE, lock);
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c
index 5222f79..0065c06 100644
--- a/drivers/usb/gadget/function/f_gsi.c
+++ b/drivers/usb/gadget/function/f_gsi.c
@@ -2418,8 +2418,13 @@
if (alt == 0 && ((gsi->d_port.in_ep &&
!gsi->d_port.in_ep->driver_data) ||
(gsi->d_port.out_ep &&
- !gsi->d_port.out_ep->driver_data)))
+ !gsi->d_port.out_ep->driver_data))) {
ipa_disconnect_handler(&gsi->d_port);
+ post_event(&gsi->d_port, EVT_DISCONNECTED);
+ queue_work(gsi->d_port.ipa_usb_wq,
+ &gsi->d_port.usb_ipa_w);
+ log_event_dbg("%s: Disconnecting\n", __func__);
+ }
gsi->data_interface_up = alt;
log_event_dbg("DATA_INTERFACE id = %d, status = %d",
@@ -2506,11 +2511,11 @@
return;
}
- /*
- * GPS doesn't use any data interface, hence bail out as there is no
- * GSI specific handling needed.
+ /* For functions such as MBIM that support alternate data
+ * interface, suspend/resume handling becomes a no-op if the
+ * data interface is not selected.
*/
- if (gsi->prot_id == USB_PROT_GPS_CTRL) {
+ if (!gsi->data_interface_up) {
log_event_dbg("%s: suspend done\n", __func__);
usb_gsi_check_pending_wakeup(f);
return;
@@ -2550,7 +2555,7 @@
/* Check any pending cpkt, and queue immediately on resume */
gsi_ctrl_send_notification(gsi);
- if (gsi->prot_id == USB_PROT_GPS_CTRL) {
+ if (!gsi->data_interface_up) {
log_event_dbg("%s: resume done\n", __func__);
return;
}
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index ff2484d..10d11ac 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -472,6 +472,7 @@
struct list_head instance;
+ bool has_dp;
u16 ss_lane_svid;
/* ext msg support */
@@ -494,6 +495,7 @@
static const unsigned int usbpd_extcon_cable[] = {
EXTCON_USB,
EXTCON_USB_HOST,
+ EXTCON_DISP_DP,
EXTCON_NONE,
};
@@ -611,6 +613,13 @@
pd->ss_lane_svid = hdlr->svid;
+ /* DP 4 Lane mode */
+ ret = extcon_blocking_sync(pd->extcon, EXTCON_DISP_DP, 4);
+ if (ret) {
+ usbpd_err(&pd->dev, "err(%d) for notify DP 4 Lane", ret);
+ goto err_exit;
+ }
+
err_exit:
return ret;
}
@@ -1645,11 +1654,19 @@
u8 i, num_vdos = PD_MSG_HDR_COUNT(rx_msg->hdr) - 1;
u8 cmd = SVDM_HDR_CMD(vdm_hdr);
u8 cmd_type = SVDM_HDR_CMD_TYPE(vdm_hdr);
- bool has_dp = false;
struct usbpd_svid_handler *handler;
- usbpd_dbg(&pd->dev, "VDM rx: svid:%x cmd:%x cmd_type:%x vdm_hdr:%x\n",
- svid, cmd, cmd_type, vdm_hdr);
+ usbpd_dbg(&pd->dev,
+ "VDM rx: svid:%x cmd:%x cmd_type:%x vdm_hdr:%x has_dp: %s\n",
+ svid, cmd, cmd_type, vdm_hdr,
+ pd->has_dp ? "true" : "false");
+
+ if ((svid == 0xFF01) && (pd->has_dp == false)) {
+ pd->has_dp = true;
+
+ /* Set to USB and DP cocurrency mode */
+ extcon_blocking_sync(pd->extcon, EXTCON_DISP_DP, 2);
+ }
/* if it's a supported SVID, pass the message to the handler */
handler = find_svid_handler(pd, svid);
@@ -1807,9 +1824,6 @@
handler->discovered = true;
}
}
-
- if (svid == 0xFF01)
- has_dp = true;
}
break;
@@ -2164,6 +2178,13 @@
kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
dual_role_instance_changed(pd->dual_role);
+ if (pd->has_dp) {
+ pd->has_dp = false;
+
+ /* Set to USB only mode when cable disconnected */
+ extcon_blocking_sync(pd->extcon, EXTCON_DISP_DP, 0);
+ }
+
goto sm_done;
}
diff --git a/include/linux/extcon.h b/include/linux/extcon.h
index 94c7be2..59a8473 100644
--- a/include/linux/extcon.h
+++ b/include/linux/extcon.h
@@ -317,7 +317,7 @@
extern const char *extcon_get_edev_name(struct extcon_dev *edev);
extern int extcon_blocking_sync(struct extcon_dev *edev, unsigned int id,
- bool val);
+ u8 val);
#else /* CONFIG_EXTCON */
static inline int extcon_dev_register(struct extcon_dev *edev)
{
diff --git a/include/microvisor/resource_manager.h b/include/microvisor/resource_manager.h
new file mode 100644
index 0000000..5d553bb
--- /dev/null
+++ b/include/microvisor/resource_manager.h
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2018 Cog Systems Pty Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Header file for communication with resource manager.
+ *
+ */
+
+/*
+ * Core API
+ */
+#define ERROR_REPLY 0x8000ffff
+
+/*
+ * Boot manager API
+ */
+#define BOOT_MGR_PROTOCOL_ID 'B'
+
+/* start_client: Unmap the client (ML VM) memory and start Linux */
+#define BOOT_MGR_START_CLIENT 0x00420001
+/* msg_payload: struct boot_mgr_start_params */
+
+struct boot_mgr_start_params {
+ uint64_t entry_addr; /* Physical load address / entry point of Linux */
+ uint64_t dtb_addr; /* Physical address of DTB */
+ bool is_64bit; /* True to reset VM to AArch64 mode, false for AArch32 */
+};
+
+/* start_client_reply: Response to BOOT_MGR_START_CLIENT */
+#define BOOT_MGR_START_CLIENT_REPLY 0x80420001
+/* msg_payload: bool success */
+
+/* start_self: Reset the caller and start the loaded HLOS image */
+#define BOOT_MGR_START_SELF 0x00420002
+/* msg_payload: struct boot_mgr_start_params */
+
+/*
+ * start_self_reply: Response to BOOT_MGR_START_CLIENT; sent only on
+ * failure as the caller will be reset if this call succeeds
+ */
+#define BOOT_MGR_START_SELF_REPLY 0x80420002
+/* msg_payload: bool success */
+
+
+/*
+ * Secure Camera Server API (for HLOS)
+ */
+#define RES_MGR_SECURECAM_SERVER_PROTOCOL_ID 'q'
+
+/*
+ * get_handle: Given a buffer sg list, return an SC handle.
+ *
+ * This is sent by the HLOS to the resource manager to obtain the SC handle
+ * to be used to refer to a specific camera buffer.
+ *
+ * The message payload is a list of IPA ranges in the HLOS VM's stage 2
+ * address space. These ranges must have previously been passed to a TZ secure
+ * camera map call that has been intercepted by the hypervisor and forwarded
+ * to both TZ and the resource manager.
+ *
+ * Payload: struct res_mgr_sglist securecam.sglist
+ * Note: The payload ends with a variable-length array.
+ */
+#define RES_MGR_SECURECAM_GET_HANDLE 0x00710001
+
+struct res_mgr_region {
+ uint64_t address_ipa;
+ uint64_t size;
+};
+
+struct res_mgr_sglist {
+ uint32_t region_count;
+ struct res_mgr_region regions[];
+};
+
+/*
+ * get_handle_reply: Response to a get_handle request.
+ *
+ * This is sent by the resource manager to the HLOS to return the SC handle to
+ * be used to refer to the specified buffer.
+ *
+ * If the specified sglist did not match a secure camera buffer known to the
+ * resource manager, the value 0xffffffff is returned. This value is never
+ * a valid SC handle.
+ *
+ * Payload: uint32_t securecam.handle
+ */
+#define RES_MGR_SECURECAM_GET_HANDLE_REPLY 0x80710001
+
+/*
+ * destroy_handles: Destroy all SC handles and unmap their buffers.
+ *
+ * This is sent by the HLOS to the resource manager to ask it to unmap all
+ * secure camera buffers from the ML VM and return the memory to the HLOS.
+ *
+ * Under normal operation, this message will be received by the resource
+ * manager after the ML VM has indicated that its application is complete by
+ * sending a DONE message. If this is not the case, the resource manager will
+ * wait until both this message and the DONE message have been received before
+ * destroying the buffers.
+ *
+ * Payload: void
+ */
+#define RES_MGR_SECURECAM_DESTROY_HANDLES 0x00710002
+
+/*
+ * destroy_handles_reply: Indicate that all SC handles have been destroyed.
+ *
+ * This is sent by the resource manager to the HLOS to inform it that all
+ * secure camera buffers have been unmapped from the ML VM and returned to the
+ * HLOS.
+ *
+ * Payload: void
+ */
+#define RES_MGR_SECURECAM_DESTROY_HANDLES_REPLY 0x80710002
+
+
+/*
+ * Secure Camera Client API (for ML VM)
+ */
+#define RES_MGR_SECURECAM_CLIENT_PROTOCOL_ID 'Q'
+
+/*
+ * notify_start: Tell the client that the first camera buffer has been mapped.
+ *
+ * This is sent by the resource manager to the ML VM after the first instance
+ * of a TZ map call for a secure camera buffer being intercepted.
+ *
+ * Payload: void
+ */
+#define RES_MGR_SECURECAM_NOTIFY_START 0x80510001
+
+/*
+ * ack_start: Acknowledge a notify_start message
+ *
+ * This is sent by the ML VM to the resource manager to acknowledge receipt
+ * of a notify_start message.
+ *
+ * Payload: void
+ */
+#define RES_MGR_SECURECAM_ACK_START 0x00510001
+
+/*
+ * done: Indicate that the secure camera application has terminated.
+ *
+ * This is sent by the ML VM when access to the secure camera buffers is no
+ * longer required. The resource manager will delay unmapping the buffers
+ * until this message is received.
+ *
+ * Payload: void
+ */
+#define RES_MGR_SECURECAM_DONE 0x00510002
+
+/*
+ * lookup_handle: Request physical addresses for a secure camera handle.
+ *
+ * This is sent by the ML VM when userspace code attempts to register a secure
+ * camera buffer handle.
+ *
+ * Payload: uint32_t securecam.handle
+ */
+#define RES_MGR_LOOKUP_HANDLE 0x00510003
+
+/*
+ * lookup_handle_reply: Response to lookup_handle.
+ *
+ * When the resource manager receives a lookup_handle message containing a
+ * handle that is valid and has already been mapped into the ML VM stage 2,
+ * this message is returned containing the list of IPA ranges that have been
+ * assigned to the buffer in the ML VM's address space.
+ *
+ * If the handle is unknown, or corresponds to a buffer that is not currently
+ * mapped into the ML VM stage 2, the region_count field of the result will be
+ * set to 0.
+ *
+ * Payload: struct res_mgr_sglist securecam.sglist
+ * Note: The payload ends with a variable-length array.
+ */
+#define RES_MGR_LOOKUP_HANDLE_REPLY 0x80510003
+
+/*
+ * notify_start: Tell the client that the camera buffers will be unmapped.
+ *
+ * This is sent by the resource manager to the ML VM after the first instance
+ * of a TZ unprotect call for a secure camera buffer being intercepted.
+ *
+ * Payload: void
+ */
+#define RES_MGR_SECURECAM_NOTIFY_STOP 0x80510004
+
+/*
+ * ack_start: Acknowledge a notify_stop message
+ *
+ * This is sent by the ML VM to the resource manager to acknowledge receipt
+ * of a notify_stop message.
+ *
+ * Payload: void
+ */
+#define RES_MGR_SECURECAM_ACK_STOP 0x00510004
+
+/*
+ * Top-level message structure
+ */
+struct res_mgr_msg {
+ uint32_t msg_id;
+ union {
+ bool success;
+ struct {
+ struct boot_mgr_start_params start_params;
+ } boot_mgr;
+ struct {
+ uint32_t handle;
+ struct res_mgr_sglist sglist;
+ } securecam;
+ };
+};
diff --git a/include/net/cnss2.h b/include/net/cnss2.h
index c5ccee4..e95ef8b 100644
--- a/include/net/cnss2.h
+++ b/include/net/cnss2.h
@@ -148,6 +148,7 @@
extern void cnss_wlan_unregister_driver(struct cnss_wlan_driver *driver);
extern void cnss_device_crashed(struct device *dev);
extern int cnss_pci_link_down(struct device *dev);
+extern int cnss_pci_is_device_down(struct device *dev);
extern void cnss_schedule_recovery(struct device *dev,
enum cnss_recovery_reason reason);
extern int cnss_self_recovery(struct device *dev,
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 335b40e..b9bcac6 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -6875,37 +6875,30 @@
return (estimated_capacity <= capacity_curr_of(target_cpu));
}
-static inline bool skip_sg(struct task_struct *p, struct sched_group *sg,
- struct cpumask *rtg_target)
-{
- int fcpu = group_first_cpu(sg);
-
- /* Are all CPUs isolated in this group? */
- if (!sg->group_weight)
- return true;
-
- /*
- * Don't skip a group if a task affinity allows it
- * to run only on that group.
- */
- if (cpumask_subset(tsk_cpus_allowed(p), sched_group_cpus(sg)))
- return false;
-
- if (!task_fits_max(p, fcpu))
- return true;
-
- if (rtg_target && !cpumask_test_cpu(fcpu, rtg_target))
- return true;
-
- return false;
-}
-
-static int start_cpu(bool boosted)
+static int start_cpu(struct task_struct *p, bool boosted,
+ struct cpumask *rtg_target)
{
struct root_domain *rd = cpu_rq(smp_processor_id())->rd;
- int start_cpu;
+ int start_cpu = -1;
- start_cpu = boosted ? rd->max_cap_orig_cpu : rd->min_cap_orig_cpu;
+ if (boosted)
+ return rd->max_cap_orig_cpu;
+
+ /* A task always fits on its rtg_target */
+ if (rtg_target) {
+ int rtg_target_cpu = cpumask_first_and(rtg_target,
+ cpu_online_mask);
+
+ if (rtg_target_cpu < nr_cpu_ids)
+ return rtg_target_cpu;
+ }
+
+ /* Where the task should land based on its demand */
+ if (rd->min_cap_orig_cpu != -1
+ && task_fits_max(p, rd->min_cap_orig_cpu))
+ start_cpu = rd->min_cap_orig_cpu;
+ else
+ start_cpu = rd->max_cap_orig_cpu;
return walt_start_cpu(start_cpu);
}
@@ -6929,6 +6922,8 @@
int best_idle_cpu = -1;
int target_cpu = -1;
int cpu, i;
+ long spare_cap, most_spare_cap = 0;
+ int most_spare_cap_cpu = -1;
unsigned int active_cpus_count = 0;
int isolated_candidate = -1;
int prev_cpu = task_cpu(p);
@@ -6939,7 +6934,7 @@
schedstat_inc(this_rq()->eas_stats.fbt_attempts);
/* Find start CPU based on boost value */
- cpu = start_cpu(boosted);
+ cpu = start_cpu(p, boosted, fbt_env->rtg_target);
if (cpu < 0) {
schedstat_inc(p->se.statistics.nr_wakeups_fbt_no_cpu);
schedstat_inc(this_rq()->eas_stats.fbt_no_cpu);
@@ -6960,9 +6955,6 @@
cpumask_t search_cpus;
bool do_rotate = false, avoid_prev_cpu = false;
- if (skip_sg(p, sg, fbt_env->rtg_target))
- continue;
-
cpumask_copy(&search_cpus, tsk_cpus_allowed(p));
cpumask_and(&search_cpus, &search_cpus, sched_group_cpus(sg));
i = find_first_cpu_bit(p, &search_cpus, sg, &avoid_prev_cpu,
@@ -6997,6 +6989,12 @@
*/
wake_util = cpu_util_wake(i, p);
new_util = wake_util + task_util(p);
+ spare_cap = capacity_orig_of(i) - wake_util;
+
+ if (spare_cap > most_spare_cap) {
+ most_spare_cap = spare_cap;
+ most_spare_cap_cpu = i;
+ }
/*
* Ensure minimum capacity to grant the required boost.
@@ -7232,6 +7230,13 @@
target_capacity = ULONG_MAX;
}
+ /*
+ * if we have found a target cpu within a group, don't bother
+ * checking other groups.
+ */
+ if (target_capacity != ULONG_MAX)
+ break;
+
} while (sg = sg->next, sg != sd->groups);
if (best_idle_cpu != -1 && !is_packing_eligible(p, target_cpu, fbt_env,
@@ -7272,10 +7277,15 @@
? best_active_cpu
: best_idle_cpu;
- if (target_cpu == -1 && cpu_isolated(prev_cpu) &&
- isolated_candidate != -1) {
- target_cpu = isolated_candidate;
+ if (target_cpu == -1 && most_spare_cap_cpu != -1 &&
+ /* ensure we use active cpu for active migration */
+ !(p->state == TASK_RUNNING && !idle_cpu(most_spare_cap_cpu)))
+ target_cpu = most_spare_cap_cpu;
+
+ if (cpu_isolated(prev_cpu)) {
fbt_env->avoid_prev_cpu = true;
+ if (target_cpu == -1 && isolated_candidate != -1)
+ target_cpu = isolated_candidate;
}
/*
@@ -8367,6 +8377,9 @@
return 0;
}
+ /* Record that we found atleast one task that could run on dst_cpu */
+ env->flags &= ~LBF_ALL_PINNED;
+
if (energy_aware() && !env->dst_rq->rd->overutilized &&
env->idle == CPU_NEWLY_IDLE) {
long util_cum_dst, util_cum_src;
@@ -8380,9 +8393,6 @@
return 0;
}
- /* Record that we found atleast one task that could run on dst_cpu */
- env->flags &= ~LBF_ALL_PINNED;
-
#ifdef CONFIG_SCHED_WALT
if (env->flags & LBF_IGNORE_PREFERRED_CLUSTER_TASKS &&
!preferred_cluster(cpu_rq(env->dst_cpu)->cluster, p))
@@ -9643,8 +9653,23 @@
* a think about bumping its value to force at least one task to be
* moved
*/
- if (env->imbalance < busiest->load_per_task)
+ if (env->imbalance < busiest->load_per_task) {
+ /*
+ * The busiest group is overloaded so it could use help
+ * from the other groups. If the local group has idle CPUs
+ * and it is not overloaded and has no imbalance with in
+ * the group, allow the load balance by bumping the
+ * imbalance.
+ */
+ if (busiest->group_type == group_overloaded &&
+ local->group_type <= group_misfit_task &&
+ env->idle != CPU_NOT_IDLE) {
+ env->imbalance = busiest->load_per_task;
+ return;
+ }
+
return fix_small_imbalance(env, sds);
+ }
}
/******* find_busiest_group() helpers end here *********************/
diff --git a/kernel/sched/walt.c b/kernel/sched/walt.c
index 4afefd6..269f687 100644
--- a/kernel/sched/walt.c
+++ b/kernel/sched/walt.c
@@ -370,11 +370,12 @@
struct task_struct *p;
int loop_max = 10;
+ rq->ed_task = NULL;
+
if ((!walt_rotation_enabled && sched_boost_policy() ==
SCHED_BOOST_NONE) || !rq->cfs.h_nr_running)
return 0;
- rq->ed_task = NULL;
list_for_each_entry(p, &rq->cfs_tasks, se.group_node) {
if (!loop_max)
break;