diff options
109 files changed, 857 insertions, 400 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt index 4fadd0ccbcf7..02bf809740c3 100644 --- a/Documentation/devicetree/bindings/arm/msm/msm.txt +++ b/Documentation/devicetree/bindings/arm/msm/msm.txt @@ -289,6 +289,7 @@ compatible = "qcom,sdm630-mtp" compatible = "qcom,sdm630-cdp" compatible = "qcom,sda630-mtp" compatible = "qcom,sda630-cdp" +compatible = "qcom,sdm630-qrd" compatible = "qcom,msm8952-rumi" compatible = "qcom,msm8952-sim" compatible = "qcom,msm8952-qrd" diff --git a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-fg-gen3.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt index 35d8d0d7d50b..221657780178 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-fg-gen3.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt @@ -118,7 +118,6 @@ First Level Node - FG Gen3 device Definition: Specifies the source of sense resistor. Allowed values are: 0 - Rsense is from Battery FET - 1 - Rsense is external 2 - Rsense is Battery FET and SMB Option 2 can be used only when a parallel charger is present. If this property is not specified, then the diff --git a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-fg.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg.txt index f6a7a1ba3005..f6a7a1ba3005 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-fg.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg.txt diff --git a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-qnovo.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qnovo.txt index 96b7dd517231..96b7dd517231 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-qnovo.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qnovo.txt diff --git a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smb2.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt index eabdc6a75fbe..eabdc6a75fbe 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smb2.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt diff --git a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smbcharger.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smbcharger.txt index efd64cd90878..efd64cd90878 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smbcharger.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smbcharger.txt diff --git a/Documentation/devicetree/bindings/power/qcom-charger/smb1351-charger.txt b/Documentation/devicetree/bindings/power/supply/qcom/smb1351-charger.txt index ab0ac32e444e..ab0ac32e444e 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/smb1351-charger.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/smb1351-charger.txt diff --git a/Documentation/devicetree/bindings/power/qcom-charger/smb135x-charger.txt b/Documentation/devicetree/bindings/power/supply/qcom/smb135x-charger.txt index 3eff91a1d112..3eff91a1d112 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/smb135x-charger.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/smb135x-charger.txt diff --git a/Documentation/devicetree/bindings/power/qcom-charger/smb138x-charger.txt b/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt index 0244f910017a..0244f910017a 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/smb138x-charger.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile index 65c42b8de30c..83fee34e5265 100644 --- a/arch/arm/boot/dts/qcom/Makefile +++ b/arch/arm/boot/dts/qcom/Makefile @@ -192,6 +192,7 @@ dtb-$(CONFIG_ARCH_SDM630) += sdm630-rumi.dtb \ sdm630-pm660a-cdp.dtb \ sdm630-pm660a-mtp.dtb \ sdm630-pm660a-rcm.dtb \ + sdm630-pm660a-qrd.dtb \ sdm630-internal-codec-pm660a-cdp.dtb \ sdm630-internal-codec-pm660a-mtp.dtb \ sdm630-internal-codec-pm660a-rcm.dtb \ diff --git a/arch/arm/boot/dts/qcom/msm-pm660l-rpm-regulator.dtsi b/arch/arm/boot/dts/qcom/msm-pm660l-rpm-regulator.dtsi index 83235317fa02..57b62489e502 100644 --- a/arch/arm/boot/dts/qcom/msm-pm660l-rpm-regulator.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pm660l-rpm-regulator.dtsi @@ -43,8 +43,8 @@ rpm-regulator-smpb3 { compatible = "qcom,rpm-smd-regulator-resource"; - qcom,resource-name = "smpb"; - qcom,resource-id = <3>; + qcom,resource-name = "rwcx"; + qcom,resource-id = <0>; qcom,regulator-type = <1>; status = "disabled"; @@ -58,8 +58,8 @@ rpm-regulator-smpb5 { compatible = "qcom,rpm-smd-regulator-resource"; - qcom,resource-name = "smpb"; - qcom,resource-id = <5>; + qcom,resource-name = "rwmx"; + qcom,resource-id = <0>; qcom,regulator-type = <1>; status = "disabled"; diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi index c57fa50d0f29..bc87b375ff50 100644 --- a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi @@ -211,11 +211,11 @@ vcc_ana-supply = <&pm8998_l28>; vcc_dig-supply = <&pm8998_l6>; qcom,afe-load = <20000>; - qcom,afe-vtg-min = <2850000>; - qcom,afe-vtg-max = <3000000>; + qcom,afe-vtg-min = <3008000>; + qcom,afe-vtg-max = <3008000>; qcom,dig-load = <40000>; - qcom,dig-vtg-min = <1800000>; - qcom,dig-vtg-max = <1800000>; + qcom,dig-vtg-min = <1808000>; + qcom,dig-vtg-max = <1808000>; qcom,fb-resume-delay-us = <10000>; qcom,afe-power-on-delay-us = <1000>; qcom,afe-power-off-delay-us = <6>; diff --git a/arch/arm/boot/dts/qcom/msm8998.dtsi b/arch/arm/boot/dts/qcom/msm8998.dtsi index cb3d1fee1f48..cfdbf98af76e 100644 --- a/arch/arm/boot/dts/qcom/msm8998.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998.dtsi @@ -286,34 +286,40 @@ reg = <0 0x85800000 0 0x3700000>; }; - pil_slpi_mem: pil_slpi_region@93800000 { + pil_ipa_gpu_mem: pil_ipa_gpu_region@95000000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x93800000 0 0xf00000>; + reg = <0 0x95000000 0 0x100000>; }; - pil_video_mem: pil_video_region@93300000 { + pil_slpi_mem: pil_slpi_region@94100000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x93300000 0 0x500000>; + reg = <0 0x94100000 0 0xf00000>; }; - pil_adsp_mem: pil_adsp_region@91900000 { + pil_video_mem: pil_video_region@93c00000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x91900000 0 0x1a00000>; + reg = <0 0x93c00000 0 0x500000>; }; - modem_mem: modem_region@8ac00000 { + modem_mem: modem_region@8cc00000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x8ac00000 0 0x6d00000>; + reg = <0 0x8cc00000 0 0x7000000>; + }; + + pil_adsp_mem: pil_adsp_region@0x8b200000 { + compatible = "removed-dma-pool"; + no-map; + reg = <0 0x8b200000 0 0x1a00000>; }; spss_mem: spss_region@8ab00000 { /* for SPSS-PIL */ compatible = "removed-dma-pool"; no-map; - reg = <0 0x8ab00000 0 0x100000>; + reg = <0 0x8ab00000 0 0x700000>; }; adsp_mem: adsp_region { diff --git a/arch/arm/boot/dts/qcom/sda630.dtsi b/arch/arm/boot/dts/qcom/sda630.dtsi index 87af4de959af..c0ac1a4e814e 100644 --- a/arch/arm/boot/dts/qcom/sda630.dtsi +++ b/arch/arm/boot/dts/qcom/sda630.dtsi @@ -17,3 +17,13 @@ compatible = "qcom,sda630"; qcom,msm-id = <327 0x0>; }; + +&soc { + qcom,rmnet-ipa { + status = "disabled"; + }; +}; + +&ipa_hw { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/qcom/sdm630-pm660a-qrd.dts b/arch/arm/boot/dts/qcom/sdm630-pm660a-qrd.dts new file mode 100644 index 000000000000..d535d62e521c --- /dev/null +++ b/arch/arm/boot/dts/qcom/sdm630-pm660a-qrd.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "sdm630.dtsi" +#include "sdm630-qrd.dtsi" +#include "msm-pm660a.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SDM 630 PM660 + PM660A QRD"; + compatible = "qcom,sdm630-qrd", "qcom,sdm630", "qcom,qrd"; + qcom,board-id = <0x0002000b 0x00>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/sdm630-qrd.dtsi b/arch/arm/boot/dts/qcom/sdm630-qrd.dtsi new file mode 100644 index 000000000000..6779d80d76cf --- /dev/null +++ b/arch/arm/boot/dts/qcom/sdm630-qrd.dtsi @@ -0,0 +1,24 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "sdm660-pinctrl.dtsi" +/ { +}; + +&uartblsp1dm1 { + status = "ok"; + pinctrl-names = "default"; + pinctrl-0 = <&uart_console_active>; +}; + +&soc { +}; diff --git a/arch/arm/boot/dts/qcom/sdm660-coresight.dtsi b/arch/arm/boot/dts/qcom/sdm660-coresight.dtsi index d712c04b3e70..b0002dddf419 100644 --- a/arch/arm/boot/dts/qcom/sdm660-coresight.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-coresight.dtsi @@ -1061,6 +1061,22 @@ clock-names = "core_clk", "core_a_clk"; }; + qpdi: qpdi@1fc1000 { + compatible = "qcom,coresight-qpdi"; + reg = <0x01fc1000 0x4>; + reg-names = "qpdi-base"; + + coresight-name = "coresight-qpdi"; + + vdd-supply = <&pm660l_l5>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <15000 900000>; + + vdd-io-supply = <&pm660l_l2>; + qcom,vdd-io-voltage-level = <1800000 2950000>; + qcom,vdd-io-current-level = <200 22000>; + }; + funnel_qatb: funnel@6005000 { compatible = "arm,primecell"; arm,primecell-periphid = <0x0003b908>; diff --git a/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi b/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi index 172668f7ec0b..0c933807cdd8 100644 --- a/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1301,7 +1301,7 @@ mdss_te_active: mdss_te_active { mux { pins = "gpio59"; - function = "mdp_vsync_p"; + function = "mdp_vsync"; }; config { pins = "gpio59"; @@ -1313,7 +1313,7 @@ mdss_te_suspend: mdss_te_suspend { mux { pins = "gpio59"; - function = "mdp_vsync_p"; + function = "mdp_vsync"; }; config { pins = "gpio59"; diff --git a/arch/arm/boot/dts/qcom/sdm660.dtsi b/arch/arm/boot/dts/qcom/sdm660.dtsi index c0219bd273a9..7335aab92478 100644 --- a/arch/arm/boot/dts/qcom/sdm660.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660.dtsi @@ -1494,7 +1494,7 @@ dcc: dcc@10b3000 { compatible = "qcom,dcc"; reg = <0x10b3000 0x1000>, - <0x10b4000 0x800>; + <0x10b4000 0x2000>; reg-names = "dcc-base", "dcc-ram-base"; clocks = <&clock_gcc GCC_DCC_AHB_CLK>; diff --git a/arch/arm/configs/msmcortex_defconfig b/arch/arm/configs/msmcortex_defconfig index 1831f2c63ca5..fec429d7bd0c 100644 --- a/arch/arm/configs/msmcortex_defconfig +++ b/arch/arm/configs/msmcortex_defconfig @@ -292,15 +292,15 @@ CONFIG_PINCTRL_MSM8998=y CONFIG_PINCTRL_SDM660=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_QPNP_PIN=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y -CONFIG_QPNP_SMBCHARGER=y -CONFIG_SMB135X_CHARGER=y -CONFIG_SMB1351_USB_CHARGER=y +CONFIG_POWER_SUPPLY=y +CONFIG_QPNP_FG_GEN3=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y CONFIG_QPNP_SMB2=y CONFIG_SMB138X_CHARGER=y +CONFIG_QPNP_QNOVO=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_THERMAL=y CONFIG_MFD_SPMI_PMIC=y @@ -477,6 +477,7 @@ CONFIG_QCOM_DEVFREQ_DEVBW=y CONFIG_EXTCON=y CONFIG_IIO=y CONFIG_QCOM_RRADC=y +CONFIG_QCOM_TADC=y CONFIG_PWM=y CONFIG_PWM_QPNP=y CONFIG_ARM_GIC_V3_ACL=y diff --git a/arch/arm/configs/sdm660-perf_defconfig b/arch/arm/configs/sdm660-perf_defconfig index d555a1b179d8..cd09f085e6af 100644 --- a/arch/arm/configs/sdm660-perf_defconfig +++ b/arch/arm/configs/sdm660-perf_defconfig @@ -318,20 +318,19 @@ CONFIG_SPMI=y CONFIG_PINCTRL_SDM660=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_QPNP_PIN=y +CONFIG_POWER_SUPPLY=y CONFIG_POWER_RESET=y CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y CONFIG_POWER_RESET_SYSCON=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y -CONFIG_QPNP_SMBCHARGER=y -CONFIG_SMB135X_CHARGER=y CONFIG_SMB1351_USB_CHARGER=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y CONFIG_BATTERY_BCL=y CONFIG_QPNP_SMB2=y CONFIG_SMB138X_CHARGER=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_THERMAL=y CONFIG_CPU_THERMAL=y diff --git a/arch/arm/configs/sdm660_defconfig b/arch/arm/configs/sdm660_defconfig index 2c94274b0637..8055774d9cdb 100644 --- a/arch/arm/configs/sdm660_defconfig +++ b/arch/arm/configs/sdm660_defconfig @@ -316,20 +316,19 @@ CONFIG_SPMI=y CONFIG_PINCTRL_SDM660=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_QPNP_PIN=y +CONFIG_POWER_SUPPLY=y CONFIG_POWER_RESET=y CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y CONFIG_POWER_RESET_SYSCON=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y -CONFIG_QPNP_SMBCHARGER=y -CONFIG_SMB135X_CHARGER=y CONFIG_SMB1351_USB_CHARGER=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y CONFIG_BATTERY_BCL=y CONFIG_QPNP_SMB2=y CONFIG_SMB138X_CHARGER=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_THERMAL=y CONFIG_CPU_THERMAL=y diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 0efb7c66e818..8ac5ba251136 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -806,7 +806,6 @@ menu "ARMv8.1 architectural features" config ARM64_HW_AFDBM bool "Support for hardware updates of the Access and Dirty page flags" - default y help The ARMv8.1 architecture extensions introduce support for hardware updates of the access and dirty information in page @@ -823,7 +822,6 @@ config ARM64_HW_AFDBM config ARM64_PAN bool "Enable support for Privileged Access Never (PAN)" - default y help Privileged Access Never (PAN; part of the ARMv8.1 Extensions) prevents the kernel or hypervisor from accessing user-space (EL0) @@ -851,7 +849,6 @@ endmenu config ARM64_UAO bool "Enable support for User Access Override (UAO)" - default y help User Access Override (UAO; part of the ARMv8.2 Extensions) causes the 'unprivileged' variant of the load/store instructions to diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig index 07e413e31234..56bbe8054264 100644 --- a/arch/arm64/configs/msm-perf_defconfig +++ b/arch/arm64/configs/msm-perf_defconfig @@ -326,15 +326,15 @@ CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y -CONFIG_MSM_PM=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y CONFIG_QPNP_SMBCHARGER=y CONFIG_QPNP_FG=y CONFIG_SMB135X_CHARGER=y CONFIG_SMB1351_USB_CHARGER=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_EPM_ADC=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_LIMITS_MONITOR=y diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index 76d949319dfa..c39a9311e056 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -313,15 +313,15 @@ CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y -CONFIG_MSM_PM=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y CONFIG_QPNP_SMBCHARGER=y CONFIG_QPNP_FG=y CONFIG_SMB135X_CHARGER=y CONFIG_SMB1351_USB_CHARGER=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_EPM_ADC=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_LIMITS_MONITOR=y diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig index 9700145bfdf6..d71cfed7614d 100644 --- a/arch/arm64/configs/msmcortex-perf_defconfig +++ b/arch/arm64/configs/msmcortex-perf_defconfig @@ -316,9 +316,6 @@ CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y -CONFIG_MSM_PM=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y CONFIG_QPNP_FG_GEN3=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y @@ -326,6 +323,9 @@ CONFIG_BATTERY_BCL=y CONFIG_QPNP_SMB2=y CONFIG_SMB138X_CHARGER=y CONFIG_QPNP_QNOVO=y +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_CPU_THERMAL=y CONFIG_LIMITS_MONITOR=y diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig index 7761c2360675..cbff6b3a5b74 100644 --- a/arch/arm64/configs/msmcortex_defconfig +++ b/arch/arm64/configs/msmcortex_defconfig @@ -318,9 +318,6 @@ CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y -CONFIG_MSM_PM=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y CONFIG_QPNP_FG_GEN3=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y @@ -328,6 +325,9 @@ CONFIG_BATTERY_BCL=y CONFIG_QPNP_SMB2=y CONFIG_SMB138X_CHARGER=y CONFIG_QPNP_QNOVO=y +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_CPU_THERMAL=y CONFIG_LIMITS_MONITOR=y diff --git a/arch/arm64/configs/sdm660-perf_defconfig b/arch/arm64/configs/sdm660-perf_defconfig index 7d203e49d595..9172e73ce075 100644 --- a/arch/arm64/configs/sdm660-perf_defconfig +++ b/arch/arm64/configs/sdm660-perf_defconfig @@ -318,12 +318,7 @@ CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y -CONFIG_MSM_PM=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y -CONFIG_QPNP_SMBCHARGER=y CONFIG_QPNP_FG_GEN3=y -CONFIG_SMB135X_CHARGER=y CONFIG_SMB1351_USB_CHARGER=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y @@ -331,6 +326,9 @@ CONFIG_BATTERY_BCL=y CONFIG_QPNP_SMB2=y CONFIG_SMB138X_CHARGER=y CONFIG_QPNP_QNOVO=y +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_CPU_THERMAL=y CONFIG_LIMITS_MONITOR=y @@ -511,6 +509,7 @@ CONFIG_MSM_MMCC_660=y CONFIG_CLOCK_CPU_OSM=y CONFIG_QCOM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_MSM_TIMER_LEAP=y CONFIG_IOMMU_IO_PGTABLE_FAST=y CONFIG_ARM_SMMU=y CONFIG_IOMMU_DEBUG=y diff --git a/arch/arm64/configs/sdm660_defconfig b/arch/arm64/configs/sdm660_defconfig index c295ba7e0d70..17de7c1a247a 100644 --- a/arch/arm64/configs/sdm660_defconfig +++ b/arch/arm64/configs/sdm660_defconfig @@ -320,12 +320,7 @@ CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y -CONFIG_MSM_PM=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y -CONFIG_QPNP_SMBCHARGER=y CONFIG_QPNP_FG_GEN3=y -CONFIG_SMB135X_CHARGER=y CONFIG_SMB1351_USB_CHARGER=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y @@ -333,6 +328,9 @@ CONFIG_BATTERY_BCL=y CONFIG_QPNP_SMB2=y CONFIG_SMB138X_CHARGER=y CONFIG_QPNP_QNOVO=y +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_CPU_THERMAL=y CONFIG_LIMITS_MONITOR=y @@ -520,6 +518,7 @@ CONFIG_MSM_MMCC_660=y CONFIG_CLOCK_CPU_OSM=y CONFIG_QCOM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_MSM_TIMER_LEAP=y CONFIG_IOMMU_IO_PGTABLE_FAST=y CONFIG_IOMMU_IO_PGTABLE_FAST_SELFTEST=y CONFIG_ARM_SMMU=y diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index c9df86d68b44..eccd8c49ad69 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -590,6 +590,9 @@ static void armv8pmu_idle_update(struct arm_pmu *cpu_pmu) hw_events = this_cpu_ptr(cpu_pmu->hw_events); + if (!hw_events) + return; + for (idx = 0; idx < cpu_pmu->num_events; ++idx) { if (!test_bit(idx, hw_events->used_mask)) diff --git a/drivers/char/diag/diagfwd_socket.c b/drivers/char/diag/diagfwd_socket.c index 1b19e014af63..888949816dfe 100644 --- a/drivers/char/diag/diagfwd_socket.c +++ b/drivers/char/diag/diagfwd_socket.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -43,8 +43,8 @@ #define LPASS_INST_BASE 64 #define WCNSS_INST_BASE 128 #define SENSORS_INST_BASE 192 -#define WDSP_INST_BASE 256 -#define CDSP_INST_BASE 320 +#define CDSP_INST_BASE 256 +#define WDSP_INST_BASE 320 #define INST_ID_CNTL 0 #define INST_ID_CMD 1 diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index f685e7fe3a4d..375f1420f3bb 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -301,7 +301,12 @@ static int clk_alpha_pll_enable(struct clk_hw *hw) ret = clk_enable_regmap(hw); if (ret) return ret; - return wait_for_pll_enable(pll, PLL_ACTIVE_FLAG); + ret = wait_for_pll_enable(pll, PLL_ACTIVE_FLAG); + if (ret == 0) { + if (pll->flags & SUPPORTS_FSM_VOTE) + *pll->soft_vote |= (pll->soft_vote_mask); + return ret; + } } /* Skip if already enabled */ @@ -351,7 +356,13 @@ static void clk_alpha_pll_disable(struct clk_hw *hw) /* If in FSM mode, just unvote it */ if (val & PLL_VOTE_FSM_ENA) { - clk_disable_regmap(hw); + if (pll->flags & SUPPORTS_FSM_VOTE) { + *pll->soft_vote &= ~(pll->soft_vote_mask); + if (!*pll->soft_vote) + clk_disable_regmap(hw); + } else + clk_disable_regmap(hw); + return; } diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index dd92bc340f8a..9644ee46f097 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -32,6 +32,8 @@ struct pll_vco { /** * struct clk_alpha_pll - phase locked loop (PLL) * @offset: base address of registers + * @soft_vote: soft voting variable for multiple PLL software instances + * @soft_vote_mask: soft voting mask for multiple PLL software instances * @vco_table: array of VCO settings * @vco_data: array of VCO data settings like post div * @clkr: regmap clock handle @@ -40,6 +42,13 @@ struct clk_alpha_pll { u32 offset; struct pll_config *config; + u32 *soft_vote; + u32 soft_vote_mask; +/* Soft voting values */ +#define PLL_SOFT_VOTE_PRIMARY BIT(0) +#define PLL_SOFT_VOTE_CPU BIT(1) +#define PLL_SOFT_VOTE_AUX BIT(2) + const struct pll_vco *vco_table; size_t num_vco; @@ -54,6 +63,8 @@ struct clk_alpha_pll { */ #define SUPPORTS_DYNAMIC_UPDATE BIT(1) #define SUPPORTS_SLEW BIT(2) + /* associated with soft_vote for multiple PLL software instances */ +#define SUPPORTS_FSM_VOTE BIT(3) struct clk_regmap clkr; #define PLLOUT_MAIN BIT(0) diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index c762a387068b..cba778b827ec 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014, 2016-2017, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -339,10 +339,11 @@ static unsigned long clk_debug_mux_measure_rate(struct clk_hw *hw) struct clk_debug_mux *meas = to_clk_measure(hw); struct measure_clk_data *data = meas->priv; - spin_lock_irqsave(&clk_reg_lock, flags); clk_prepare_enable(data->cxo); + spin_lock_irqsave(&clk_reg_lock, flags); + /* Enable CXO/4 and RINGOSC branch. */ regmap_read(meas->regmap[GCC], data->xo_div4_cbcr, &gcc_xo4_reg); gcc_xo4_reg |= BIT(0); @@ -376,10 +377,10 @@ static unsigned long clk_debug_mux_measure_rate(struct clk_hw *hw) ret = (raw_count_full * multiplier); } - clk_disable_unprepare(data->cxo); - spin_unlock_irqrestore(&clk_reg_lock, flags); + clk_disable_unprepare(data->cxo); + return ret; } diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c index 5b118f297238..076ff3565ef4 100644 --- a/drivers/clk/qcom/gcc-sdm660.c +++ b/drivers/clk/qcom/gcc-sdm660.c @@ -76,6 +76,12 @@ static const char * const gcc_parent_names_1[] = { "core_bi_pll_test_se", }; +static const char * const gcc_parent_names_ao_1[] = { + "cxo_a", + "gpll0_ao_out_main", + "core_bi_pll_test_se", +}; + static const struct parent_map gcc_parent_map_2[] = { { P_XO, 0 }, { P_GPLL0_OUT_MAIN, 1 }, @@ -189,8 +195,13 @@ static struct clk_fixed_factor xo = { }, }; +static unsigned int soft_vote_gpll0; + static struct clk_alpha_pll gpll0_out_main = { .offset = 0x0, + .soft_vote = &soft_vote_gpll0, + .soft_vote_mask = PLL_SOFT_VOTE_PRIMARY, + .flags = SUPPORTS_FSM_VOTE, .clkr = { .enable_reg = 0x52000, .enable_mask = BIT(0), @@ -203,6 +214,23 @@ static struct clk_alpha_pll gpll0_out_main = { }, }; +static struct clk_alpha_pll gpll0_ao_out_main = { + .offset = 0x0, + .soft_vote = &soft_vote_gpll0, + .soft_vote_mask = PLL_SOFT_VOTE_CPU, + .flags = SUPPORTS_FSM_VOTE, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0_ao_out_main", + .parent_names = (const char *[]){ "cxo_a" }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + static struct clk_fixed_factor gpll0_out_early_div = { .mult = 1, .div = 2, @@ -718,7 +746,7 @@ static struct clk_rcg2 hmss_ahb_clk_src = { .freq_tbl = ftbl_hmss_ahb_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "hmss_ahb_clk_src", - .parent_names = gcc_parent_names_1, + .parent_names = gcc_parent_names_ao_1, .num_parents = 3, .ops = &clk_rcg2_ops, VDD_DIG_FMAX_MAP3_AO( @@ -741,7 +769,7 @@ static struct clk_rcg2 hmss_gpll0_clk_src = { .freq_tbl = ftbl_hmss_gpll0_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "hmss_gpll0_clk_src", - .parent_names = gcc_parent_names_1, + .parent_names = gcc_parent_names_ao_1, .num_parents = 3, .ops = &clk_rcg2_ops, VDD_DIG_FMAX_MAP1_AO( @@ -787,7 +815,7 @@ static struct clk_rcg2 hmss_rbcpr_clk_src = { .freq_tbl = ftbl_hmss_rbcpr_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "hmss_rbcpr_clk_src", - .parent_names = gcc_parent_names_1, + .parent_names = gcc_parent_names_ao_1, .num_parents = 3, .ops = &clk_rcg2_ops, VDD_DIG_FMAX_MAP2( @@ -1104,6 +1132,7 @@ static struct clk_rcg2 usb30_master_clk_src = { }; static const struct freq_tbl ftbl_usb30_mock_utmi_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), F(40000000, P_PLL0_EARLY_DIV_CLK_SRC, 7.5, 0, 0), F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0), { } @@ -1735,19 +1764,6 @@ static struct clk_branch gcc_gpu_bimc_gfx_clk = { }, }; -static struct clk_branch gcc_gpu_bimc_gfx_src_clk = { - .halt_reg = 0x7100c, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0x7100c, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_gpu_bimc_gfx_src_clk", - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gpu_cfg_ahb_clk = { .halt_reg = 0x71004, .halt_check = BRANCH_VOTED, @@ -1807,19 +1823,6 @@ static struct clk_branch gcc_gpu_gpll0_div_clk = { }, }; -static struct clk_branch gcc_gpu_snoc_dvm_gfx_clk = { - .halt_reg = 0x71018, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0x71018, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_gpu_snoc_dvm_gfx_clk", - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_hmss_ahb_clk = { .halt_reg = 0x48000, .halt_check = BRANCH_HALT_VOTED, @@ -2647,11 +2650,9 @@ static struct clk_regmap *gcc_660_clocks[] = { [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, [GCC_GPU_BIMC_GFX_CLK] = &gcc_gpu_bimc_gfx_clk.clkr, - [GCC_GPU_BIMC_GFX_SRC_CLK] = &gcc_gpu_bimc_gfx_src_clk.clkr, [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr, [GCC_GPU_GPLL0_CLK] = &gcc_gpu_gpll0_clk.clkr, [GCC_GPU_GPLL0_DIV_CLK] = &gcc_gpu_gpll0_div_clk.clkr, - [GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr, [GCC_HMSS_AHB_CLK] = &gcc_hmss_ahb_clk.clkr, [GCC_HMSS_DVM_BUS_CLK] = &gcc_hmss_dvm_bus_clk.clkr, [GCC_HMSS_RBCPR_CLK] = &gcc_hmss_rbcpr_clk.clkr, @@ -2699,6 +2700,7 @@ static struct clk_regmap *gcc_660_clocks[] = { [GP2_CLK_SRC] = &gp2_clk_src.clkr, [GP3_CLK_SRC] = &gp3_clk_src.clkr, [GPLL0] = &gpll0_out_main.clkr, + [GPLL0_AO] = &gpll0_ao_out_main.clkr, [GPLL1] = &gpll1_out_main.clkr, [GPLL4] = &gpll4_out_main.clkr, [HLOS1_VOTE_LPASS_ADSP_SMMU_CLK] = &hlos1_vote_lpass_adsp_smmu_clk.clkr, @@ -2890,9 +2892,7 @@ static const char *const debug_mux_parent_names[] = { "gcc_gp2_clk", "gcc_gp3_clk", "gcc_gpu_bimc_gfx_clk", - "gcc_gpu_bimc_gfx_src_clk", "gcc_gpu_cfg_ahb_clk", - "gcc_gpu_snoc_dvm_gfx_clk", "gcc_hmss_ahb_clk", "gcc_hmss_dvm_bus_clk", "gcc_hmss_rbcpr_clk", @@ -3071,9 +3071,7 @@ static struct clk_debug_mux gcc_debug_mux = { { "gcc_gp2_clk", 0x0E0 }, { "gcc_gp3_clk", 0x0E1 }, { "gcc_gpu_bimc_gfx_clk", 0x13F }, - { "gcc_gpu_bimc_gfx_src_clk", 0x13E }, { "gcc_gpu_cfg_ahb_clk", 0x13B }, - { "gcc_gpu_snoc_dvm_gfx_clk", 0x141 }, { "gcc_hmss_ahb_clk", 0x0BA }, { "gcc_hmss_dvm_bus_clk", 0x0BF }, { "gcc_hmss_rbcpr_clk", 0x0BC }, diff --git a/drivers/gpu/msm/adreno-gpulist.h b/drivers/gpu/msm/adreno-gpulist.h index 2418ee003c22..f1439381d781 100644 --- a/drivers/gpu/msm/adreno-gpulist.h +++ b/drivers/gpu/msm/adreno-gpulist.h @@ -289,8 +289,8 @@ static const struct adreno_gpu_core adreno_gpulist[] = { .major = 1, .minor = 2, .patchid = ANY_ID, - .features = ADRENO_64BIT | ADRENO_CONTENT_PROTECTION | - ADRENO_CPZ_RETENTION, + .features = ADRENO_PREEMPTION | ADRENO_64BIT | + ADRENO_CONTENT_PROTECTION | ADRENO_CPZ_RETENTION, .pm4fw_name = "a530_pm4.fw", .pfpfw_name = "a530_pfp.fw", .zap_name = "a512_zap", diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c index 90b833888d9d..0aab38ccc703 100644 --- a/drivers/gpu/msm/adreno_a5xx.c +++ b/drivers/gpu/msm/adreno_a5xx.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -197,7 +197,8 @@ static void a5xx_platform_setup(struct adreno_device *adreno_dev) /* A510 has 3 XIN ports in VBIF */ gpudev->vbif_xin_halt_ctrl0_mask = A510_VBIF_XIN_HALT_CTRL0_MASK; - } else if (adreno_is_a540(adreno_dev)) { + } else if (adreno_is_a540(adreno_dev) || + adreno_is_a512(adreno_dev)) { gpudev->snapshot_data->sect_sizes->cp_merciu = 1024; } @@ -485,7 +486,7 @@ static int a5xx_regulator_enable(struct adreno_device *adreno_dev) kgsl_regwrite(device, A5XX_RBBM_CLOCK_CNTL, 0x00000055); a5xx_hwcg_set(adreno_dev, true); /* Turn on sp_input_clk at HM level */ - kgsl_regrmw(device, A5XX_RBBM_CLOCK_CNTL, 3, 0); + kgsl_regrmw(device, A5XX_RBBM_CLOCK_CNTL, 0xFF, 0); return 0; } @@ -535,6 +536,9 @@ static void a5xx_regulator_disable(struct adreno_device *adreno_dev) unsigned int reg; struct kgsl_device *device = KGSL_DEVICE(adreno_dev); + if (adreno_is_a512(adreno_dev)) + return; + /* If feature is not supported or not enabled */ if (!ADRENO_FEATURE(adreno_dev, ADRENO_SPTP_PC) || !test_bit(ADRENO_SPTP_PC_CTRL, &adreno_dev->pwrctrl_flag)) { @@ -1120,6 +1124,65 @@ static const struct kgsl_hwcg_reg a540_hwcg_regs[] = { {A5XX_RBBM_CLOCK_HYST_GPMU, 0x00000004} }; +static const struct kgsl_hwcg_reg a512_hwcg_regs[] = { + {A5XX_RBBM_CLOCK_CNTL_SP0, 0x02222222}, + {A5XX_RBBM_CLOCK_CNTL_SP1, 0x02222222}, + {A5XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220}, + {A5XX_RBBM_CLOCK_CNTL2_SP1, 0x02222220}, + {A5XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF}, + {A5XX_RBBM_CLOCK_HYST_SP1, 0x0000F3CF}, + {A5XX_RBBM_CLOCK_DELAY_SP0, 0x00000080}, + {A5XX_RBBM_CLOCK_DELAY_SP1, 0x00000080}, + {A5XX_RBBM_CLOCK_CNTL_TP0, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL_TP1, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL3_TP0, 0x00002222}, + {A5XX_RBBM_CLOCK_CNTL3_TP1, 0x00002222}, + {A5XX_RBBM_CLOCK_HYST_TP0, 0x77777777}, + {A5XX_RBBM_CLOCK_HYST_TP1, 0x77777777}, + {A5XX_RBBM_CLOCK_HYST2_TP0, 0x77777777}, + {A5XX_RBBM_CLOCK_HYST2_TP1, 0x77777777}, + {A5XX_RBBM_CLOCK_HYST3_TP0, 0x00007777}, + {A5XX_RBBM_CLOCK_HYST3_TP1, 0x00007777}, + {A5XX_RBBM_CLOCK_DELAY_TP0, 0x11111111}, + {A5XX_RBBM_CLOCK_DELAY_TP1, 0x11111111}, + {A5XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111}, + {A5XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111}, + {A5XX_RBBM_CLOCK_DELAY3_TP0, 0x00001111}, + {A5XX_RBBM_CLOCK_DELAY3_TP1, 0x00001111}, + {A5XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222}, + {A5XX_RBBM_CLOCK_HYST_UCHE, 0x00444444}, + {A5XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002}, + {A5XX_RBBM_CLOCK_CNTL_RB0, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL_RB1, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL2_RB0, 0x00222222}, + {A5XX_RBBM_CLOCK_CNTL2_RB1, 0x00222222}, + {A5XX_RBBM_CLOCK_CNTL_CCU0, 0x00022220}, + {A5XX_RBBM_CLOCK_CNTL_CCU1, 0x00022220}, + {A5XX_RBBM_CLOCK_CNTL_RAC, 0x05522222}, + {A5XX_RBBM_CLOCK_CNTL2_RAC, 0x00555555}, + {A5XX_RBBM_CLOCK_HYST_RB_CCU0, 0x04040404}, + {A5XX_RBBM_CLOCK_HYST_RB_CCU1, 0x04040404}, + {A5XX_RBBM_CLOCK_HYST_RAC, 0x07444044}, + {A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_0, 0x00000002}, + {A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_1, 0x00000002}, + {A5XX_RBBM_CLOCK_DELAY_RAC, 0x00010011}, + {A5XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222}, + {A5XX_RBBM_CLOCK_MODE_GPC, 0x02222222}, + {A5XX_RBBM_CLOCK_MODE_VFD, 0x00002222}, + {A5XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000}, + {A5XX_RBBM_CLOCK_HYST_GPC, 0x04104004}, + {A5XX_RBBM_CLOCK_HYST_VFD, 0x00000000}, + {A5XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000}, + {A5XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000}, + {A5XX_RBBM_CLOCK_DELAY_GPC, 0x00000200}, + {A5XX_RBBM_CLOCK_DELAY_VFD, 0x00002222}, +}; + static const struct { int (*devfunc)(struct adreno_device *adreno_dev); const struct kgsl_hwcg_reg *regs; @@ -1127,6 +1190,7 @@ static const struct { } a5xx_hwcg_registers[] = { { adreno_is_a540, a540_hwcg_regs, ARRAY_SIZE(a540_hwcg_regs) }, { adreno_is_a530, a530_hwcg_regs, ARRAY_SIZE(a530_hwcg_regs) }, + { adreno_is_a512, a512_hwcg_regs, ARRAY_SIZE(a512_hwcg_regs) }, { adreno_is_a510, a510_hwcg_regs, ARRAY_SIZE(a510_hwcg_regs) }, { adreno_is_a505, a50x_hwcg_regs, ARRAY_SIZE(a50x_hwcg_regs) }, { adreno_is_a506, a50x_hwcg_regs, ARRAY_SIZE(a50x_hwcg_regs) }, @@ -1871,6 +1935,11 @@ static void a5xx_start(struct adreno_device *adreno_dev) kgsl_regwrite(device, A5XX_CP_MERCIU_SIZE, 0x20); kgsl_regwrite(device, A5XX_CP_ROQ_THRESHOLDS_2, 0x40000030); kgsl_regwrite(device, A5XX_CP_ROQ_THRESHOLDS_1, 0x20100D0A); + } else if (adreno_is_a540(adreno_dev) || adreno_is_a512(adreno_dev)) { + kgsl_regwrite(device, A5XX_CP_MEQ_THRESHOLDS, 0x40); + kgsl_regwrite(device, A5XX_CP_MERCIU_SIZE, 0x400); + kgsl_regwrite(device, A5XX_CP_ROQ_THRESHOLDS_2, 0x80000060); + kgsl_regwrite(device, A5XX_CP_ROQ_THRESHOLDS_1, 0x40201B16); } else { kgsl_regwrite(device, A5XX_CP_MEQ_THRESHOLDS, 0x40); kgsl_regwrite(device, A5XX_CP_MERCIU_SIZE, 0x40); diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 54dc4ce09f35..1a2032c2c1fb 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -175,27 +175,9 @@ static int __uhid_report_queue_and_wait(struct uhid_device *uhid, uhid_queue(uhid, ev); spin_unlock_irqrestore(&uhid->qlock, flags); - /* - * Assumption: report_lock and devlock are both locked. So unlock - * before sleeping. - */ - mutex_unlock(&uhid->report_lock); - mutex_unlock(&uhid->devlock); ret = wait_event_interruptible_timeout(uhid->report_wait, !uhid->report_running || !uhid->running, 5 * HZ); - ret = mutex_lock_interruptible(&uhid->devlock); - if (ret) - return ret; - ret = mutex_lock_interruptible(&uhid->report_lock); - if (ret) { - /* - * Failed to lock, unlock previous mutex before exiting - * this function. - */ - mutex_unlock(&uhid->devlock); - return ret; - } if (!ret || !uhid->running || uhid->report_running) ret = -EIO; else if (ret < 0) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c index e238f54a9100..09de276e8418 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1794,6 +1794,7 @@ int msm_isp_process_overflow_irq( { uint32_t overflow_mask; uint32_t bus_err = 0; + unsigned long flags; /* if there are no active streams - do not start recovery */ if (!vfe_dev->axi_data.num_active_stream) @@ -1825,23 +1826,33 @@ int msm_isp_process_overflow_irq( int i; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; + spin_lock_irqsave( + &vfe_dev->common_data->common_dev_data_lock, flags); + if (atomic_cmpxchg(&vfe_dev->error_info.overflow_state, - NO_OVERFLOW, OVERFLOW_DETECTED != NO_OVERFLOW)) + NO_OVERFLOW, OVERFLOW_DETECTED)) { + spin_unlock_irqrestore( + &vfe_dev->common_data->common_dev_data_lock, + flags); return 0; + } if (vfe_dev->reset_pending == 1) { - pr_err("%s:%d failed: overflow %x during reset\n", + pr_err_ratelimited("%s:%d overflow %x during reset\n", __func__, __LINE__, overflow_mask); /* Clear overflow bits since reset is pending */ *irq_status1 &= ~overflow_mask; + spin_unlock_irqrestore( + &vfe_dev->common_data->common_dev_data_lock, + flags); return 0; } - pr_err("%s: vfe %d overflow mask %x, bus_error %x\n", + pr_err_ratelimited("%s: vfe %d overflowmask %x,bus_error %x\n", __func__, vfe_dev->pdev->id, overflow_mask, bus_err); for (i = 0; i < axi_data->hw_info->num_wm; i++) { if (!axi_data->free_wm[i]) continue; - pr_err("%s: wm %d assigned to stream handle %x\n", + ISP_DBG("%s:wm %d assigned to stream handle %x\n", __func__, i, axi_data->free_wm[i]); } vfe_dev->recovery_irq0_mask = vfe_dev->irq0_mask; @@ -1880,6 +1891,9 @@ int msm_isp_process_overflow_irq( msm_isp_send_event(vfe_dev, ISP_EVENT_ERROR, &error_event); } + spin_unlock_irqrestore( + &vfe_dev->common_data->common_dev_data_lock, + flags); return 1; } return 0; diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c index dc2061fc4537..5264bba57c8d 100644 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c +++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c @@ -1447,6 +1447,12 @@ static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out, pr_err_ratelimited("%s: fatal error, stop ispif immediately\n", __func__); for (i = 0; i < ispif->vfe_info.num_vfe; i++) { + msm_camera_io_w(0x0, + ispif->base + ISPIF_VFE_m_IRQ_MASK_0(i)); + msm_camera_io_w(0x0, + ispif->base + ISPIF_VFE_m_IRQ_MASK_1(i)); + msm_camera_io_w(0x0, + ispif->base + ISPIF_VFE_m_IRQ_MASK_2(i)); msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY, ispif->base + ISPIF_VFE_m_INTF_CMD_0(i)); msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY, diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c index 4b4846907d0f..7f6e78710117 100644 --- a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c +++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -496,7 +496,7 @@ static int msm_jpegdma_queue_init(void *priv, struct vb2_queue *src_vq, src_vq->drv_priv = ctx; src_vq->mem_ops = &msm_jpegdma_vb2_mem_ops; src_vq->ops = &msm_jpegdma_vb2_q_ops; - src_vq->buf_struct_size = sizeof(struct vb2_v4l2_buffer); + src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; ret = vb2_queue_init(src_vq); @@ -510,7 +510,7 @@ static int msm_jpegdma_queue_init(void *priv, struct vb2_queue *src_vq, dst_vq->drv_priv = ctx; dst_vq->mem_ops = &msm_jpegdma_vb2_mem_ops; dst_vq->ops = &msm_jpegdma_vb2_q_ops; - dst_vq->buf_struct_size = sizeof(struct vb2_v4l2_buffer); + dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; ret = vb2_queue_init(dst_vq); diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c index bc6fb191b3b5..730f8b32ff1a 100644 --- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c +++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c @@ -299,8 +299,8 @@ static void msm_buf_mngr_sd_shutdown(struct msm_buf_mngr_device *dev, if (!list_empty(&dev->buf_qhead)) { list_for_each_entry_safe(bufs, save, &dev->buf_qhead, entry) { - pr_info("%s: Delete invalid bufs =%lx, session_id=%u, bufs->ses_id=%d, str_id=%d, idx=%d\n", - __func__, (unsigned long)bufs, session->session, + pr_info("%s: Delete invalid bufs =%pK, session_id=%u, bufs->ses_id=%d, str_id=%d, idx=%d\n", + __func__, (void *)bufs, session->session, bufs->session_id, bufs->stream_id, bufs->index); if (session->session == bufs->session_id) { diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c index 44746ca0d2e6..fdbc51ae1e1a 100644 --- a/drivers/net/wireless/ath/wil6210/pcie_bus.c +++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c @@ -187,6 +187,22 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) dev_err(dev, "wil_if_alloc failed: %d\n", rc); return rc; } + + /* device supports 48 bit addresses */ + rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48)); + if (rc) { + dev_err(dev, "dma_set_mask_and_coherent(48) failed: %d\n", rc); + rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + if (rc) { + dev_err(dev, + "dma_set_mask_and_coherent(32) failed: %d\n", + rc); + goto if_free; + } + } else { + wil->use_extended_dma_addr = 1; + } + wil->pdev = pdev; pci_set_drvdata(pdev, wil); /* rollback to if_free */ diff --git a/drivers/net/wireless/ath/wil6210/pmc.c b/drivers/net/wireless/ath/wil6210/pmc.c index b9faae0278c9..b6765d4a4602 100644 --- a/drivers/net/wireless/ath/wil6210/pmc.c +++ b/drivers/net/wireless/ath/wil6210/pmc.c @@ -108,13 +108,28 @@ void wil_pmc_alloc(struct wil6210_priv *wil, /* Allocate pring buffer and descriptors. * vring->va should be aligned on its size rounded up to power of 2 - * This is granted by the dma_alloc_coherent + * This is granted by the dma_alloc_coherent. + * + * HW has limitation that all vrings addresses must share the same + * upper 16 msb bits part of 48 bits address. To workaround that, + * if we are using 48 bit addresses switch to 32 bit allocation + * before allocating vring memory. + * + * There's no check for the return value of dma_set_mask_and_coherent, + * since we assume if we were able to set the mask during + * initialization in this system it will not fail if we set it again */ + if (wil->use_extended_dma_addr) + dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + pmc->pring_va = dma_alloc_coherent(dev, sizeof(struct vring_tx_desc) * num_descriptors, &pmc->pring_pa, GFP_KERNEL); + if (wil->use_extended_dma_addr) + dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48)); + wil_dbg_misc(wil, "%s: allocated pring %p => %pad. %zd x %d = total %zd bytes\n", __func__, diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 4ac9ba04afed..b0166d224508 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -123,15 +123,32 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring) vring->va = NULL; return -ENOMEM; } + /* vring->va should be aligned on its size rounded up to power of 2 - * This is granted by the dma_alloc_coherent + * This is granted by the dma_alloc_coherent. + * + * HW has limitation that all vrings addresses must share the same + * upper 16 msb bits part of 48 bits address. To workaround that, + * if we are using 48 bit addresses switch to 32 bit allocation + * before allocating vring memory. + * + * There's no check for the return value of dma_set_mask_and_coherent, + * since we assume if we were able to set the mask during + * initialization in this system it will not fail if we set it again */ + if (wil->use_extended_dma_addr) + dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + vring->va = dma_alloc_coherent(dev, sz, &vring->pa, GFP_KERNEL); if (!vring->va) { kfree(vring->ctx); vring->ctx = NULL; return -ENOMEM; } + + if (wil->use_extended_dma_addr) + dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48)); + /* initially, all descriptors are SW owned * For Tx and Rx, ownership bit is at the same location, thus * we can use any diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index bab0ed20c8c4..cc20517a4726 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -647,6 +647,7 @@ struct wil6210_priv { u8 vring2cid_tid[WIL6210_MAX_TX_RINGS][2]; /* [0] - CID, [1] - TID */ struct wil_sta_info sta[WIL6210_MAX_CID]; int bcast_vring; + bool use_extended_dma_addr; /* indicates whether we are using 48 bits */ /* scan */ struct cfg80211_scan_request *scan_request; diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 71154ec99d3c..13b79438af1c 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -1051,6 +1051,10 @@ int arm_pmu_device_probe(struct platform_device *pdev, pmu->plat_device = pdev; + ret = cpu_pmu_init(pmu); + if (ret) + goto out_free; + if (node && (of_id = of_match_node(of_table, pdev->dev.of_node))) { init_fn = of_id->data; @@ -1073,13 +1077,9 @@ int arm_pmu_device_probe(struct platform_device *pdev, if (ret) { pr_info("%s: failed to probe PMU!\n", of_node_full_name(node)); - goto out_free; + goto out_destroy; } - ret = cpu_pmu_init(pmu); - if (ret) - goto out_free; - ret = perf_pmu_register(&pmu->pmu, pmu->name, -1); if (ret) goto out_destroy; diff --git a/drivers/pinctrl/qcom/pinctrl-lpi.c b/drivers/pinctrl/qcom/pinctrl-lpi.c index 4829ba7f4bf0..67cac25689ef 100644 --- a/drivers/pinctrl/qcom/pinctrl-lpi.c +++ b/drivers/pinctrl/qcom/pinctrl-lpi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -108,6 +108,7 @@ static const u32 lpi_offset[] = { 0x00000000, 0x00001000, 0x00002000, + 0x00002010, 0x00003000, 0x00003010, 0x00004000, @@ -592,7 +593,7 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) goto err_range; } - lpi_dev_up = false; + lpi_dev_up = true; ret = audio_notifier_register("lpi_tlmm", AUDIO_NOTIFIER_ADSP_DOMAIN, &service_nb); if (ret < 0) { diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa.c b/drivers/platform/msm/ipa/ipa_v2/ipa.c index d82651f7b492..09ec8458fcad 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -733,7 +733,8 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - if (ipa2_del_hdr((struct ipa_ioc_del_hdr *)param)) { + if (ipa2_del_hdr_by_user((struct ipa_ioc_del_hdr *)param, + true)) { retval = -EFAULT; break; } @@ -1417,8 +1418,8 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - if (ipa2_del_hdr_proc_ctx( - (struct ipa_ioc_del_hdr_proc_ctx *)param)) { + if (ipa2_del_hdr_proc_ctx_by_user( + (struct ipa_ioc_del_hdr_proc_ctx *)param, true)) { retval = -EFAULT; break; } @@ -2715,7 +2716,7 @@ fail_schedule_delayed_work: if (ipa_ctx->dflt_v4_rt_rule_hdl) __ipa_del_rt_rule(ipa_ctx->dflt_v4_rt_rule_hdl); if (ipa_ctx->excp_hdr_hdl) - __ipa_del_hdr(ipa_ctx->excp_hdr_hdl); + __ipa_del_hdr(ipa_ctx->excp_hdr_hdl, false); ipa2_teardown_sys_pipe(ipa_ctx->clnt_hdl_cmd); fail_cmd: return result; @@ -2727,7 +2728,7 @@ static void ipa_teardown_apps_pipes(void) ipa2_teardown_sys_pipe(ipa_ctx->clnt_hdl_data_in); __ipa_del_rt_rule(ipa_ctx->dflt_v6_rt_rule_hdl); __ipa_del_rt_rule(ipa_ctx->dflt_v4_rt_rule_hdl); - __ipa_del_hdr(ipa_ctx->excp_hdr_hdl); + __ipa_del_hdr(ipa_ctx->excp_hdr_hdl, false); ipa2_teardown_sys_pipe(ipa_ctx->clnt_hdl_cmd); } diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c index 40d42e1775a9..51f34f0d5101 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -741,7 +741,8 @@ error: return -EPERM; } -static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr) +static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl, + bool release_hdr, bool by_user) { struct ipa_hdr_proc_ctx_entry *entry; struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl; @@ -755,6 +756,14 @@ static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr) IPADBG("del ctx proc cnt=%d ofst=%d\n", htbl->proc_ctx_cnt, entry->offset_entry->offset); + if (by_user && entry->user_deleted) { + IPAERR("proc_ctx already deleted by user\n"); + return -EINVAL; + } + + if (by_user) + entry->user_deleted = true; + if (--entry->ref_cnt) { IPADBG("proc_ctx_hdl %x ref_cnt %d\n", proc_ctx_hdl, entry->ref_cnt); @@ -762,7 +771,7 @@ static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr) } if (release_hdr) - __ipa_del_hdr(entry->hdr->id); + __ipa_del_hdr(entry->hdr->id, false); /* move the offset entry to appropriate free list */ list_move(&entry->offset_entry->link, @@ -779,7 +788,7 @@ static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr) } -int __ipa_del_hdr(u32 hdr_hdl) +int __ipa_del_hdr(u32 hdr_hdl, bool by_user) { struct ipa_hdr_entry *entry; struct ipa_hdr_tbl *htbl = &ipa_ctx->hdr_tbl; @@ -790,7 +799,7 @@ int __ipa_del_hdr(u32 hdr_hdl) return -EINVAL; } - if (!entry || (entry->cookie != IPA_COOKIE)) { + if (entry->cookie != IPA_COOKIE) { IPAERR("bad parm\n"); return -EINVAL; } @@ -802,6 +811,14 @@ int __ipa_del_hdr(u32 hdr_hdl) IPADBG("del hdr of sz=%d hdr_cnt=%d ofst=%d\n", entry->hdr_len, htbl->hdr_cnt, entry->offset_entry->offset); + if (by_user && entry->user_deleted) { + IPAERR("hdr already deleted by user\n"); + return -EINVAL; + } + + if (by_user) + entry->user_deleted = true; + if (--entry->ref_cnt) { IPADBG("hdr_hdl %x ref_cnt %d\n", hdr_hdl, entry->ref_cnt); return 0; @@ -812,7 +829,7 @@ int __ipa_del_hdr(u32 hdr_hdl) entry->phys_base, entry->hdr_len, DMA_TO_DEVICE); - __ipa_del_hdr_proc_ctx(entry->proc_ctx->id, false); + __ipa_del_hdr_proc_ctx(entry->proc_ctx->id, false, false); } else { /* move the offset entry to appropriate free list */ list_move(&entry->offset_entry->link, @@ -879,15 +896,16 @@ bail: } /** - * ipa2_del_hdr() - Remove the specified headers from SW and optionally commit them - * to IPA HW + * ipa2_del_hdr_by_user() - Remove the specified headers + * from SW and optionally commit them to IPA HW * @hdls: [inout] set of headers to delete + * @by_user: Operation requested by user? * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ -int ipa2_del_hdr(struct ipa_ioc_del_hdr *hdls) +int ipa2_del_hdr_by_user(struct ipa_ioc_del_hdr *hdls, bool by_user) { int i; int result = -EFAULT; @@ -904,7 +922,7 @@ int ipa2_del_hdr(struct ipa_ioc_del_hdr *hdls) mutex_lock(&ipa_ctx->lock); for (i = 0; i < hdls->num_hdls; i++) { - if (__ipa_del_hdr(hdls->hdl[i].hdl)) { + if (__ipa_del_hdr(hdls->hdl[i].hdl, by_user)) { IPAERR("failed to del hdr %i\n", i); hdls->hdl[i].status = -1; } else { @@ -925,6 +943,20 @@ bail: } /** + * ipa2_del_hdr() - Remove the specified headers from SW + * and optionally commit them to IPA HW + * @hdls: [inout] set of headers to delete + * + * Returns: 0 on success, negative on failure + * + * Note: Should not be called from atomic context + */ +int ipa2_del_hdr(struct ipa_ioc_del_hdr *hdls) +{ + return ipa2_del_hdr_by_user(hdls, false); +} + +/** * ipa2_add_hdr_proc_ctx() - add the specified headers to SW * and optionally commit them to IPA HW * @proc_ctxs: [inout] set of processing context headers to add @@ -976,16 +1008,18 @@ bail: } /** - * ipa2_del_hdr_proc_ctx() - + * ipa2_del_hdr_proc_ctx_by_user() - * Remove the specified processing context headers from SW and * optionally commit them to IPA HW. * @hdls: [inout] set of processing context headers to delete + * @by_user: Operation requested by user? * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ -int ipa2_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls) +int ipa2_del_hdr_proc_ctx_by_user(struct ipa_ioc_del_hdr_proc_ctx *hdls, + bool by_user) { int i; int result; @@ -1004,7 +1038,7 @@ int ipa2_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls) mutex_lock(&ipa_ctx->lock); for (i = 0; i < hdls->num_hdls; i++) { - if (__ipa_del_hdr_proc_ctx(hdls->hdl[i].hdl, true)) { + if (__ipa_del_hdr_proc_ctx(hdls->hdl[i].hdl, true, by_user)) { IPAERR("failed to del hdr %i\n", i); hdls->hdl[i].status = -1; } else { @@ -1025,6 +1059,21 @@ bail: } /** + * ipa2_del_hdr_proc_ctx() - + * Remove the specified processing context headers from SW and + * optionally commit them to IPA HW. + * @hdls: [inout] set of processing context headers to delete + * + * Returns: 0 on success, negative on failure + * + * Note: Should not be called from atomic context + */ +int ipa2_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls) +{ + return ipa2_del_hdr_proc_ctx_by_user(hdls, false); +} + +/** * ipa2_commit_hdr() - commit to IPA HW the current header table in SW * * Returns: 0 on success, negative on failure @@ -1252,7 +1301,7 @@ int __ipa_release_hdr(u32 hdr_hdl) { int result = 0; - if (__ipa_del_hdr(hdr_hdl)) { + if (__ipa_del_hdr(hdr_hdl, false)) { IPADBG("fail to del hdr %x\n", hdr_hdl); result = -EFAULT; goto bail; @@ -1280,7 +1329,7 @@ int __ipa_release_hdr_proc_ctx(u32 proc_ctx_hdl) { int result = 0; - if (__ipa_del_hdr_proc_ctx(proc_ctx_hdl, true)) { + if (__ipa_del_hdr_proc_ctx(proc_ctx_hdl, true, false)) { IPADBG("fail to del hdr %x\n", proc_ctx_hdl); result = -EFAULT; goto bail; diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h index 967036a25746..2c2a9c617b16 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h @@ -281,6 +281,7 @@ struct ipa_rt_tbl { * @id: header entry id * @is_eth2_ofst_valid: is eth2_ofst field valid? * @eth2_ofst: offset to start of Ethernet-II/802.3 header + * @user_deleted: is the header deleted by the user? */ struct ipa_hdr_entry { struct list_head link; @@ -298,6 +299,7 @@ struct ipa_hdr_entry { int id; u8 is_eth2_ofst_valid; u16 eth2_ofst; + bool user_deleted; }; /** @@ -361,6 +363,7 @@ struct ipa_hdr_proc_ctx_add_hdr_cmd_seq { * @cookie: cookie used for validity check * @ref_cnt: reference counter of routing table * @id: processing context header entry id + * @user_deleted: is the hdr processing context deleted by the user? */ struct ipa_hdr_proc_ctx_entry { struct list_head link; @@ -370,6 +373,7 @@ struct ipa_hdr_proc_ctx_entry { u32 cookie; u32 ref_cnt; int id; + bool user_deleted; }; /** @@ -1400,6 +1404,8 @@ int ipa2_add_hdr(struct ipa_ioc_add_hdr *hdrs); int ipa2_del_hdr(struct ipa_ioc_del_hdr *hdls); +int ipa2_del_hdr_by_user(struct ipa_ioc_del_hdr *hdls, bool by_user); + int ipa2_commit_hdr(void); int ipa2_reset_hdr(void); @@ -1417,6 +1423,9 @@ int ipa2_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs); int ipa2_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls); +int ipa2_del_hdr_proc_ctx_by_user(struct ipa_ioc_del_hdr_proc_ctx *hdls, + bool by_user); + /* * Routing */ @@ -1709,7 +1718,7 @@ int ipa2_active_clients_log_print_table(char *buf, int size); void ipa2_active_clients_log_clear(void); int ipa_interrupts_init(u32 ipa_irq, u32 ee, struct device *ipa_dev); int __ipa_del_rt_rule(u32 rule_hdl); -int __ipa_del_hdr(u32 hdr_hdl); +int __ipa_del_hdr(u32 hdr_hdl, bool by_user); int __ipa_release_hdr(u32 hdr_hdl); int __ipa_release_hdr_proc_ctx(u32 proc_ctx_hdl); int _ipa_read_gen_reg_v1_1(char *buff, int max_len); diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c index c063e4392c16..e3d20422d591 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c @@ -884,8 +884,8 @@ int ipa_init_hw(void) ipa_write_reg(ipa_ctx->mmio, IPA_COMP_SW_RESET_OFST, 1); ipa_write_reg(ipa_ctx->mmio, IPA_COMP_SW_RESET_OFST, 0); - /* enable IPA */ - ipa_write_reg(ipa_ctx->mmio, IPA_COMP_CFG_OFST, 1); + /* enable IPA Bit:0, enable 2x fast clock Bit:4 */ + ipa_write_reg(ipa_ctx->mmio, IPA_COMP_CFG_OFST, 0x11); /* Read IPA version and make sure we have access to the registers */ ipa_version = ipa_read_reg(ipa_ctx->mmio, IPA_VERSION_OFST); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 3d276b0f535d..2da3b0ddca8f 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -784,7 +784,8 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - if (ipa3_del_hdr((struct ipa_ioc_del_hdr *)param)) { + if (ipa3_del_hdr_by_user((struct ipa_ioc_del_hdr *)param, + true)) { retval = -EFAULT; break; } @@ -1553,8 +1554,8 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - if (ipa3_del_hdr_proc_ctx( - (struct ipa_ioc_del_hdr_proc_ctx *)param)) { + if (ipa3_del_hdr_proc_ctx_by_user( + (struct ipa_ioc_del_hdr_proc_ctx *)param, true)) { retval = -EFAULT; break; } @@ -2921,7 +2922,7 @@ fail_schedule_delayed_work: if (ipa3_ctx->dflt_v4_rt_rule_hdl) __ipa3_del_rt_rule(ipa3_ctx->dflt_v4_rt_rule_hdl); if (ipa3_ctx->excp_hdr_hdl) - __ipa3_del_hdr(ipa3_ctx->excp_hdr_hdl); + __ipa3_del_hdr(ipa3_ctx->excp_hdr_hdl, false); ipa3_teardown_sys_pipe(ipa3_ctx->clnt_hdl_cmd); fail_cmd: return result; @@ -2933,7 +2934,7 @@ static void ipa3_teardown_apps_pipes(void) ipa3_teardown_sys_pipe(ipa3_ctx->clnt_hdl_data_in); __ipa3_del_rt_rule(ipa3_ctx->dflt_v6_rt_rule_hdl); __ipa3_del_rt_rule(ipa3_ctx->dflt_v4_rt_rule_hdl); - __ipa3_del_hdr(ipa3_ctx->excp_hdr_hdl); + __ipa3_del_hdr(ipa3_ctx->excp_hdr_hdl, false); ipa3_teardown_sys_pipe(ipa3_ctx->clnt_hdl_cmd); } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c index 93fa1492cfd5..69dca7666346 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -576,7 +576,8 @@ error: return -EPERM; } -static int __ipa3_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr) +static int __ipa3_del_hdr_proc_ctx(u32 proc_ctx_hdl, + bool release_hdr, bool by_user) { struct ipa3_hdr_proc_ctx_entry *entry; struct ipa3_hdr_proc_ctx_tbl *htbl = &ipa3_ctx->hdr_proc_ctx_tbl; @@ -590,6 +591,14 @@ static int __ipa3_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr) IPADBG("del proc ctx cnt=%d ofst=%d\n", htbl->proc_ctx_cnt, entry->offset_entry->offset); + if (by_user && entry->user_deleted) { + IPAERR("proc_ctx already deleted by user\n"); + return -EINVAL; + } + + if (by_user) + entry->user_deleted = true; + if (--entry->ref_cnt) { IPADBG("proc_ctx_hdl %x ref_cnt %d\n", proc_ctx_hdl, entry->ref_cnt); @@ -597,7 +606,7 @@ static int __ipa3_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr) } if (release_hdr) - __ipa3_del_hdr(entry->hdr->id); + __ipa3_del_hdr(entry->hdr->id, false); /* move the offset entry to appropriate free list */ list_move(&entry->offset_entry->link, @@ -614,7 +623,7 @@ static int __ipa3_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr) } -int __ipa3_del_hdr(u32 hdr_hdl) +int __ipa3_del_hdr(u32 hdr_hdl, bool by_user) { struct ipa3_hdr_entry *entry; struct ipa3_hdr_tbl *htbl = &ipa3_ctx->hdr_tbl; @@ -625,7 +634,7 @@ int __ipa3_del_hdr(u32 hdr_hdl) return -EINVAL; } - if (!entry || (entry->cookie != IPA_COOKIE)) { + if (entry->cookie != IPA_COOKIE) { IPAERR("bad parm\n"); return -EINVAL; } @@ -638,6 +647,14 @@ int __ipa3_del_hdr(u32 hdr_hdl) entry->hdr_len, htbl->hdr_cnt, entry->offset_entry->offset); + if (by_user && entry->user_deleted) { + IPAERR("proc_ctx already deleted by user\n"); + return -EINVAL; + } + + if (by_user) + entry->user_deleted = true; + if (--entry->ref_cnt) { IPADBG("hdr_hdl %x ref_cnt %d\n", hdr_hdl, entry->ref_cnt); return 0; @@ -648,7 +665,7 @@ int __ipa3_del_hdr(u32 hdr_hdl) entry->phys_base, entry->hdr_len, DMA_TO_DEVICE); - __ipa3_del_hdr_proc_ctx(entry->proc_ctx->id, false); + __ipa3_del_hdr_proc_ctx(entry->proc_ctx->id, false, false); } else { /* move the offset entry to appropriate free list */ list_move(&entry->offset_entry->link, @@ -710,15 +727,16 @@ bail: } /** - * ipa3_del_hdr() - Remove the specified headers from SW and optionally commit them - * to IPA HW + * ipa3_del_hdr_by_user() - Remove the specified headers + * from SW and optionally commit them to IPA HW * @hdls: [inout] set of headers to delete + * @by_user: Operation requested by user? * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ -int ipa3_del_hdr(struct ipa_ioc_del_hdr *hdls) +int ipa3_del_hdr_by_user(struct ipa_ioc_del_hdr *hdls, bool by_user) { int i; int result = -EFAULT; @@ -730,7 +748,7 @@ int ipa3_del_hdr(struct ipa_ioc_del_hdr *hdls) mutex_lock(&ipa3_ctx->lock); for (i = 0; i < hdls->num_hdls; i++) { - if (__ipa3_del_hdr(hdls->hdl[i].hdl)) { + if (__ipa3_del_hdr(hdls->hdl[i].hdl, by_user)) { IPAERR("failed to del hdr %i\n", i); hdls->hdl[i].status = -1; } else { @@ -751,6 +769,20 @@ bail: } /** + * ipa3_del_hdr() - Remove the specified headers from SW + * and optionally commit them to IPA HW + * @hdls: [inout] set of headers to delete + * + * Returns: 0 on success, negative on failure + * + * Note: Should not be called from atomic context + */ +int ipa3_del_hdr(struct ipa_ioc_del_hdr *hdls) +{ + return ipa3_del_hdr_by_user(hdls, false); +} + +/** * ipa3_add_hdr_proc_ctx() - add the specified headers to SW * and optionally commit them to IPA HW * @proc_ctxs: [inout] set of processing context headers to add @@ -795,16 +827,18 @@ bail: } /** - * ipa3_del_hdr_proc_ctx() - + * ipa3_del_hdr_proc_ctx_by_user() - * Remove the specified processing context headers from SW and * optionally commit them to IPA HW. * @hdls: [inout] set of processing context headers to delete + * @by_user: Operation requested by user? * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ -int ipa3_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls) +int ipa3_del_hdr_proc_ctx_by_user(struct ipa_ioc_del_hdr_proc_ctx *hdls, + bool by_user) { int i; int result; @@ -816,7 +850,7 @@ int ipa3_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls) mutex_lock(&ipa3_ctx->lock); for (i = 0; i < hdls->num_hdls; i++) { - if (__ipa3_del_hdr_proc_ctx(hdls->hdl[i].hdl, true)) { + if (__ipa3_del_hdr_proc_ctx(hdls->hdl[i].hdl, true, by_user)) { IPAERR("failed to del hdr %i\n", i); hdls->hdl[i].status = -1; } else { @@ -837,6 +871,21 @@ bail: } /** + * ipa3_del_hdr_proc_ctx() - + * Remove the specified processing context headers from SW and + * optionally commit them to IPA HW. + * @hdls: [inout] set of processing context headers to delete + * + * Returns: 0 on success, negative on failure + * + * Note: Should not be called from atomic context + */ +int ipa3_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls) +{ + return ipa3_del_hdr_proc_ctx_by_user(hdls, false); +} + +/** * ipa3_commit_hdr() - commit to IPA HW the current header table in SW * * Returns: 0 on success, negative on failure @@ -1064,7 +1113,7 @@ int __ipa3_release_hdr(u32 hdr_hdl) { int result = 0; - if (__ipa3_del_hdr(hdr_hdl)) { + if (__ipa3_del_hdr(hdr_hdl, false)) { IPADBG("fail to del hdr %x\n", hdr_hdl); result = -EFAULT; goto bail; @@ -1092,7 +1141,7 @@ int __ipa3_release_hdr_proc_ctx(u32 proc_ctx_hdl) { int result = 0; - if (__ipa3_del_hdr_proc_ctx(proc_ctx_hdl, true)) { + if (__ipa3_del_hdr_proc_ctx(proc_ctx_hdl, true, false)) { IPADBG("fail to del hdr %x\n", proc_ctx_hdl); result = -EFAULT; goto bail; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index fe7c88a25374..b3ce52424fec 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -279,6 +279,7 @@ struct ipa3_rt_tbl { * @id: header entry id * @is_eth2_ofst_valid: is eth2_ofst field valid? * @eth2_ofst: offset to start of Ethernet-II/802.3 header + * @user_deleted: is the header deleted by the user? */ struct ipa3_hdr_entry { struct list_head link; @@ -296,6 +297,7 @@ struct ipa3_hdr_entry { int id; u8 is_eth2_ofst_valid; u16 eth2_ofst; + bool user_deleted; }; /** @@ -335,6 +337,7 @@ struct ipa3_hdr_proc_ctx_offset_entry { * @cookie: cookie used for validity check * @ref_cnt: reference counter of routing table * @id: processing context header entry id + * @user_deleted: is the hdr processing context deleted by the user? */ struct ipa3_hdr_proc_ctx_entry { struct list_head link; @@ -344,6 +347,7 @@ struct ipa3_hdr_proc_ctx_entry { u32 cookie; u32 ref_cnt; int id; + bool user_deleted; }; /** @@ -1548,6 +1552,8 @@ int ipa3_add_hdr(struct ipa_ioc_add_hdr *hdrs); int ipa3_del_hdr(struct ipa_ioc_del_hdr *hdls); +int ipa3_del_hdr_by_user(struct ipa_ioc_del_hdr *hdls, bool by_user); + int ipa3_commit_hdr(void); int ipa3_reset_hdr(void); @@ -1565,6 +1571,9 @@ int ipa3_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs); int ipa3_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls); +int ipa3_del_hdr_proc_ctx_by_user(struct ipa_ioc_del_hdr_proc_ctx *hdls, + bool by_user); + /* * Routing */ @@ -1869,7 +1878,7 @@ int ipa3_active_clients_log_print_table(char *buf, int size); void ipa3_active_clients_log_clear(void); int ipa3_interrupts_init(u32 ipa_irq, u32 ee, struct device *ipa_dev); int __ipa3_del_rt_rule(u32 rule_hdl); -int __ipa3_del_hdr(u32 hdr_hdl); +int __ipa3_del_hdr(u32 hdr_hdl, bool by_user); int __ipa3_release_hdr(u32 hdr_hdl); int __ipa3_release_hdr_proc_ctx(u32 proc_ctx_hdl); int _ipa_read_ep_reg_v3_0(char *buf, int max_len, int pipe); diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 931230d55f90..91fdeaf67037 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -521,9 +521,9 @@ config AXP20X_POWER AXP20x PMIC. source "drivers/power/reset/Kconfig" +source "drivers/power/supply/Kconfig" endif # POWER_SUPPLY source "drivers/power/avs/Kconfig" source "drivers/power/qcom/Kconfig" -source "drivers/power/qcom-charger/Kconfig" diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 21aceda44c9e..f7adecea0a70 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -73,4 +73,4 @@ obj-$(CONFIG_POWER_RESET) += reset/ obj-$(CONFIG_AXP288_FUEL_GAUGE) += axp288_fuel_gauge.o obj-$(CONFIG_AXP288_CHARGER) += axp288_charger.o obj-$(CONFIG_ARCH_QCOM) += qcom/ -obj-y += qcom-charger/ +obj-$(CONFIG_POWER_SUPPLY) += supply/ diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index 83b75fcd257e..e99bf1ee5ad2 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c @@ -279,6 +279,7 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(pe_start), POWER_SUPPLY_ATTR(set_ship_mode), POWER_SUPPLY_ATTR(soc_reporting_ready), + POWER_SUPPLY_ATTR(debug_battery), /* Local extensions of type int64_t */ POWER_SUPPLY_ATTR(charge_counter_ext), /* Properties of type `const char *' */ diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig new file mode 100644 index 000000000000..ec128bf6a93a --- /dev/null +++ b/drivers/power/supply/Kconfig @@ -0,0 +1 @@ +source "drivers/power/supply/qcom/Kconfig" diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile new file mode 100644 index 000000000000..c8f025f309e7 --- /dev/null +++ b/drivers/power/supply/Makefile @@ -0,0 +1 @@ +obj-y += qcom/ diff --git a/drivers/power/qcom-charger/Kconfig b/drivers/power/supply/qcom/Kconfig index 7a0b1464ad86..b919c688e627 100644 --- a/drivers/power/qcom-charger/Kconfig +++ b/drivers/power/supply/qcom/Kconfig @@ -1,9 +1,8 @@ -menu "Qualcomm Technologies Inc Charger and FG Drivers" +menu "Qualcomm Technologies Inc Charger and Fuel Gauge support" config QPNP_SMBCHARGER tristate "QPNP SMB Charger driver" - depends on SPMI - select POWER_SUPPLY + depends on MFD_SPMI_PMIC help Say Y here to enable the dual path switch mode battery charger which supports USB detection and battery charging up to 3A. @@ -12,8 +11,7 @@ config QPNP_SMBCHARGER config QPNP_FG tristate "QPNP fuel gauge driver" - depends on SPMI - select POWER_SUPPLY + depends on MFD_SPMI_PMIC help Say Y here to enable the Fuel Gauge driver. This adds support for battery fuel gauging and state of charge of battery connected to the @@ -22,8 +20,7 @@ config QPNP_FG config QPNP_FG_GEN3 tristate "QPNP GEN3 fuel gauge driver" - depends on SPMI - select REGMAP_SPMI + depends on MFD_SPMI_PMIC help Say Y here to enable the GEN3 Fuel Gauge driver. This adds support for battery fuel gauging and state of charge of battery connected to @@ -33,7 +30,6 @@ config QPNP_FG_GEN3 config SMB135X_CHARGER tristate "SMB135X Battery Charger" depends on I2C - select POWER_SUPPLY help Say Y to include support for SMB135X Battery Charger. SMB135X is a dual path switching mode charger capable of charging @@ -45,7 +41,6 @@ config SMB135X_CHARGER config SMB1351_USB_CHARGER tristate "smb1351 usb charger (with VBUS detection)" depends on I2C - select POWER_SUPPLY help Say Y to enable support for the SMB1351 switching mode based charger. The driver supports charging control (enable/disable) and @@ -65,7 +60,6 @@ config MSM_BCL_PERIPHERAL_CTL bool "BCL driver to control the PMIC BCL peripheral" depends on SPMI depends on MSM_BCL_CTL - select POWER_SUPPLY help Say Y here to enable this BCL PMIC peripheral driver. This driver provides routines to configure and monitor the BCL @@ -83,14 +77,12 @@ config BATTERY_BCL config QPNP_SMB2 tristate "SMB2 Battery Charger" depends on MFD_SPMI_PMIC - select POWER_SUPPLY help Enables support for the SMB2 charging peripheral config SMB138X_CHARGER tristate "SMB138X Battery Charger" depends on MFD_I2C_PMIC - select POWER_SUPPLY help Say Y to include support for SMB138X Battery Charger. SMB1380 is a dual phase 6A battery charger, and SMB1381 is a single @@ -101,8 +93,7 @@ config SMB138X_CHARGER config QPNP_QNOVO bool "QPNP QNOVO driver" - depends on SPMI - select POWER_SUPPLY + depends on MFD_SPMI_PMIC help Say Y here to enable the Qnovo pulse charging engine. Qnovo driver accepts pulse parameters via sysfs entries and programs the hardware diff --git a/drivers/power/qcom-charger/Makefile b/drivers/power/supply/qcom/Makefile index 0126d2d0a18e..0126d2d0a18e 100644 --- a/drivers/power/qcom-charger/Makefile +++ b/drivers/power/supply/qcom/Makefile diff --git a/drivers/power/qcom-charger/battery_current_limit.c b/drivers/power/supply/qcom/battery_current_limit.c index d2c25bfbf66c..d2c25bfbf66c 100644 --- a/drivers/power/qcom-charger/battery_current_limit.c +++ b/drivers/power/supply/qcom/battery_current_limit.c diff --git a/drivers/power/qcom-charger/batterydata-lib.c b/drivers/power/supply/qcom/batterydata-lib.c index 226581468fda..226581468fda 100644 --- a/drivers/power/qcom-charger/batterydata-lib.c +++ b/drivers/power/supply/qcom/batterydata-lib.c diff --git a/drivers/power/qcom-charger/bcl_peripheral.c b/drivers/power/supply/qcom/bcl_peripheral.c index cae4967f1ef4..cae4967f1ef4 100644 --- a/drivers/power/qcom-charger/bcl_peripheral.c +++ b/drivers/power/supply/qcom/bcl_peripheral.c diff --git a/drivers/power/qcom-charger/fg-core.h b/drivers/power/supply/qcom/fg-core.h index 07bde30524ac..07bde30524ac 100644 --- a/drivers/power/qcom-charger/fg-core.h +++ b/drivers/power/supply/qcom/fg-core.h diff --git a/drivers/power/qcom-charger/fg-memif.c b/drivers/power/supply/qcom/fg-memif.c index a98ff7d765e3..a98ff7d765e3 100644 --- a/drivers/power/qcom-charger/fg-memif.c +++ b/drivers/power/supply/qcom/fg-memif.c diff --git a/drivers/power/qcom-charger/fg-reg.h b/drivers/power/supply/qcom/fg-reg.h index 7ad26215e469..bf2827fb550d 100644 --- a/drivers/power/qcom-charger/fg-reg.h +++ b/drivers/power/supply/qcom/fg-reg.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -211,7 +211,6 @@ #define ADC_BITSTREAM_INV_BIT BIT(4) #define SOURCE_SELECT_MASK GENMASK(1, 0) #define SRC_SEL_BATFET 0x0 -#define SRC_SEL_RSENSE 0x1 #define SRC_SEL_BATFET_SMB 0x2 #define SRC_SEL_RESERVED 0x3 diff --git a/drivers/power/qcom-charger/fg-util.c b/drivers/power/supply/qcom/fg-util.c index 41d2af0fbdc6..41d2af0fbdc6 100644 --- a/drivers/power/qcom-charger/fg-util.c +++ b/drivers/power/supply/qcom/fg-util.c diff --git a/drivers/power/qcom-charger/msm_bcl.c b/drivers/power/supply/qcom/msm_bcl.c index 6b7cefdc0250..aea3f4645897 100644 --- a/drivers/power/qcom-charger/msm_bcl.c +++ b/drivers/power/supply/qcom/msm_bcl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -99,14 +99,14 @@ int msm_bcl_set_threshold(enum bcl_param param_type, { int ret = 0; - if (!bcl[param_type] || !bcl[param_type]->registered) { + if (param_type >= BCL_PARAM_MAX || !bcl[param_type] + || !bcl[param_type]->registered) { pr_err("BCL not initialized\n"); return -EINVAL; } if ((!inp_thresh) || (inp_thresh->trip_value < 0) || (!inp_thresh->trip_notify) - || (param_type >= BCL_PARAM_MAX) || (trip_type >= BCL_TRIP_MAX)) { pr_err("Invalid Input\n"); return -EINVAL; @@ -152,8 +152,8 @@ struct bcl_param_data *msm_bcl_register_param(enum bcl_param param_type, { int ret = 0; - if (!bcl[param_type] - || param_type >= BCL_PARAM_MAX || !param_ops || !name + if (param_type >= BCL_PARAM_MAX + || !bcl[param_type] || !param_ops || !name || !param_ops->read || !param_ops->set_high_trip || !param_ops->get_high_trip || !param_ops->set_low_trip || !param_ops->get_low_trip || !param_ops->enable diff --git a/drivers/power/qcom-charger/pmic-voter.c b/drivers/power/supply/qcom/pmic-voter.c index e1a92fb23912..e1a92fb23912 100644 --- a/drivers/power/qcom-charger/pmic-voter.c +++ b/drivers/power/supply/qcom/pmic-voter.c diff --git a/drivers/power/qcom-charger/pmic-voter.h b/drivers/power/supply/qcom/pmic-voter.h index 031b9a010a42..031b9a010a42 100644 --- a/drivers/power/qcom-charger/pmic-voter.h +++ b/drivers/power/supply/qcom/pmic-voter.h diff --git a/drivers/power/qcom-charger/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c index 8523efa1a4ab..a441ff310e9f 100644 --- a/drivers/power/qcom-charger/qpnp-fg-gen3.c +++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c @@ -2543,6 +2543,9 @@ static int fg_psy_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_SOC_REPORTING_READY: pval->intval = chip->soc_reporting_ready; break; + case POWER_SUPPLY_PROP_DEBUG_BATTERY: + pval->intval = is_debug_batt_id(chip); + break; default: pr_err("unsupported property %d\n", psp); rc = -EINVAL; @@ -2641,6 +2644,7 @@ static enum power_supply_property fg_psy_props[] = { POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, POWER_SUPPLY_PROP_SOC_REPORTING_READY, + POWER_SUPPLY_PROP_DEBUG_BATTERY, }; static const struct power_supply_desc fg_psy_desc = { @@ -2977,6 +2981,9 @@ enable_bmd: if (rc < 0) pr_err("Error in enabling BMD, rc=%d\n", rc); + if (chip->fg_psy) + power_supply_changed(chip->fg_psy); + return IRQ_HANDLED; } diff --git a/drivers/power/qcom-charger/qpnp-fg.c b/drivers/power/supply/qcom/qpnp-fg.c index 0658f0d3b1eb..e4a8ade80d4f 100644 --- a/drivers/power/qcom-charger/qpnp-fg.c +++ b/drivers/power/supply/qcom/qpnp-fg.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2081,7 +2081,7 @@ static void update_sram_data_work(struct work_struct *work) struct fg_chip *chip = container_of(work, struct fg_chip, update_sram_data.work); - int resched_ms, ret; + int resched_ms = SRAM_PERIOD_NO_ID_UPDATE_MS, ret; bool tried_again = false; wait: @@ -5961,7 +5961,19 @@ static ssize_t fg_memif_dfs_reg_write(struct file *file, const char __user *buf, values = kbuf; /* Parse the data in the buffer. It should be a string of numbers */ - while (sscanf(kbuf + pos, "%i%n", &data, &bytes_read) == 1) { + while ((pos < count) && + sscanf(kbuf + pos, "%i%n", &data, &bytes_read) == 1) { + /* + * We shouldn't be receiving a string of characters that + * exceeds a size of 5 to keep this functionally correct. + * Also, we should make sure that pos never gets overflowed + * beyond the limit. + */ + if (bytes_read > 5 || bytes_read > INT_MAX - pos) { + cnt = 0; + ret = -EINVAL; + break; + } pos += bytes_read; values[cnt++] = data & 0xff; } diff --git a/drivers/power/qcom-charger/qpnp-qnovo.c b/drivers/power/supply/qcom/qpnp-qnovo.c index 7bc90fbf2929..7bc90fbf2929 100644 --- a/drivers/power/qcom-charger/qpnp-qnovo.c +++ b/drivers/power/supply/qcom/qpnp-qnovo.c diff --git a/drivers/power/qcom-charger/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index 98a917273328..4a12af466c36 100644 --- a/drivers/power/qcom-charger/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -1468,7 +1468,10 @@ static int smb2_setup_wa_flags(struct smb2 *chip) static int smb2_determine_initial_status(struct smb2 *chip) { struct smb_irq_data irq_data = {chip, "determine-initial-status"}; + struct smb_charger *chg = &chip->chg; + if (chg->bms_psy) + smblib_suspend_on_debug_battery(chg); smblib_handle_usb_plugin(0, &irq_data); smblib_handle_usb_typec_change(0, &irq_data); smblib_handle_usb_source_change(0, &irq_data); diff --git a/drivers/power/qcom-charger/qpnp-smbcharger.c b/drivers/power/supply/qcom/qpnp-smbcharger.c index 6c1e58d046e8..6c1e58d046e8 100644 --- a/drivers/power/qcom-charger/qpnp-smbcharger.c +++ b/drivers/power/supply/qcom/qpnp-smbcharger.c diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index eec96d30d4f9..d3f7e43ea10e 100644 --- a/drivers/power/qcom-charger/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -532,7 +532,7 @@ static int smblib_notifier_call(struct notifier_block *nb, if (!strcmp(psy->desc->name, "bms")) { if (!chg->bms_psy) chg->bms_psy = psy; - if (ev == PSY_EVENT_PROP_CHANGED && chg->batt_psy) + if (ev == PSY_EVENT_PROP_CHANGED) schedule_work(&chg->bms_update_work); } @@ -642,6 +642,24 @@ static bool smblib_sysok_reason_usbin(struct smb_charger *chg) return stat & SYSOK_REASON_USBIN_BIT; } +void smblib_suspend_on_debug_battery(struct smb_charger *chg) +{ + int rc; + union power_supply_propval val; + + rc = power_supply_get_property(chg->bms_psy, + POWER_SUPPLY_PROP_DEBUG_BATTERY, &val); + if (rc < 0) { + smblib_err(chg, "Couldn't get debug battery prop rc=%d\n", rc); + return; + } + + vote(chg->usb_suspend_votable, DEBUG_BOARD_VOTER, val.intval, 0); + vote(chg->dc_suspend_votable, DEBUG_BOARD_VOTER, val.intval, 0); + if (val.intval) + pr_info("Input suspended: Fake battery\n"); +} + /********************* * VOTABLE CALLBACKS * *********************/ @@ -2010,7 +2028,7 @@ int smblib_set_prop_pd_current_max(struct smb_charger *chg, int smblib_set_prop_usb_current_max(struct smb_charger *chg, const union power_supply_propval *val) { - int rc; + int rc = 0; if (!chg->pd_active) { rc = vote(chg->usb_icl_votable, USB_PSY_VOTER, @@ -3299,7 +3317,11 @@ static void bms_update_work(struct work_struct *work) { struct smb_charger *chg = container_of(work, struct smb_charger, bms_update_work); - power_supply_changed(chg->batt_psy); + + smblib_suspend_on_debug_battery(chg); + + if (chg->batt_psy) + power_supply_changed(chg->batt_psy); } static void step_soc_req_work(struct work_struct *work) diff --git a/drivers/power/qcom-charger/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index efce7eb987ab..c5d014193fd6 100644 --- a/drivers/power/qcom-charger/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h @@ -51,6 +51,7 @@ enum print_reason { #define BOOST_BACK_VOTER "BOOST_BACK_VOTER" #define HVDCP_INDIRECT_VOTER "HVDCP_INDIRECT_VOTER" #define MICRO_USB_VOTER "MICRO_USB_VOTER" +#define DEBUG_BOARD_VOTER "DEBUG_BOARD_VOTER" #define VCONN_MAX_ATTEMPTS 3 #define OTG_MAX_ATTEMPTS 3 @@ -383,6 +384,7 @@ int smblib_get_prop_slave_current_now(struct smb_charger *chg, union power_supply_propval *val); int smblib_set_prop_ship_mode(struct smb_charger *chg, const union power_supply_propval *val); +void smblib_suspend_on_debug_battery(struct smb_charger *chg); int smblib_init(struct smb_charger *chg); int smblib_deinit(struct smb_charger *chg); diff --git a/drivers/power/qcom-charger/smb-reg.h b/drivers/power/supply/qcom/smb-reg.h index 5f74e27c7978..5f74e27c7978 100644 --- a/drivers/power/qcom-charger/smb-reg.h +++ b/drivers/power/supply/qcom/smb-reg.h diff --git a/drivers/power/qcom-charger/smb1351-charger.c b/drivers/power/supply/qcom/smb1351-charger.c index e9d8c0e08447..e9d8c0e08447 100644 --- a/drivers/power/qcom-charger/smb1351-charger.c +++ b/drivers/power/supply/qcom/smb1351-charger.c diff --git a/drivers/power/qcom-charger/smb135x-charger.c b/drivers/power/supply/qcom/smb135x-charger.c index 65d4ae56ff83..65d4ae56ff83 100644 --- a/drivers/power/qcom-charger/smb135x-charger.c +++ b/drivers/power/supply/qcom/smb135x-charger.c diff --git a/drivers/power/qcom-charger/smb138x-charger.c b/drivers/power/supply/qcom/smb138x-charger.c index 70d935e9d1df..70d935e9d1df 100644 --- a/drivers/power/qcom-charger/smb138x-charger.c +++ b/drivers/power/supply/qcom/smb138x-charger.c diff --git a/drivers/power/qcom-charger/storm-watch.c b/drivers/power/supply/qcom/storm-watch.c index 90fec12bd742..90fec12bd742 100644 --- a/drivers/power/qcom-charger/storm-watch.c +++ b/drivers/power/supply/qcom/storm-watch.c diff --git a/drivers/power/qcom-charger/storm-watch.h b/drivers/power/supply/qcom/storm-watch.h index 44b9d64d8a87..44b9d64d8a87 100644 --- a/drivers/power/qcom-charger/storm-watch.h +++ b/drivers/power/supply/qcom/storm-watch.h diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index d46682bb1d84..1e6db2a76fa5 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -3,7 +3,7 @@ * * This code is based on drivers/scsi/ufs/ufshcd.c * Copyright (C) 2011-2013 Samsung India Software Operations - * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. * * Authors: * Santosh Yaraganavi <santosh.sy@samsung.com> @@ -5264,9 +5264,28 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status) retval = IRQ_HANDLED; } - if ((intr_status & UFSHCD_UIC_PWR_MASK) && hba->uic_async_done) { - complete(hba->uic_async_done); - retval = IRQ_HANDLED; + if (intr_status & UFSHCD_UIC_PWR_MASK) { + if (hba->uic_async_done) { + complete(hba->uic_async_done); + retval = IRQ_HANDLED; + } else if (ufshcd_is_auto_hibern8_supported(hba)) { + /* + * If uic_async_done flag is not set then this + * is an Auto hibern8 err interrupt. + * Perform a host reset followed by a full + * link recovery. + */ + hba->ufshcd_state = UFSHCD_STATE_ERROR; + hba->force_host_reset = true; + dev_err(hba->dev, "%s: Auto Hibern8 %s failed - status: 0x%08x, upmcrs: 0x%08x\n", + __func__, (intr_status & UIC_HIBERNATE_ENTER) ? + "Enter" : "Exit", + intr_status, ufshcd_get_upmcrs(hba)); + __ufshcd_print_host_regs(hba, true); + ufshcd_print_host_state(hba); + schedule_work(&hba->eh_work); + retval = IRQ_HANDLED; + } } return retval; } @@ -5858,6 +5877,7 @@ static void ufshcd_err_handler(struct work_struct *work) int err = 0; int tag; bool needs_reset = false; + bool clks_enabled = false; hba = container_of(work, struct ufs_hba, eh_work); @@ -5867,6 +5887,22 @@ static void ufshcd_err_handler(struct work_struct *work) if (hba->ufshcd_state == UFSHCD_STATE_RESET) goto out; + /* + * Make sure the clocks are ON before we proceed with err + * handling. For the majority of cases err handler would be + * run with clocks ON. There is a possibility that the err + * handler was scheduled due to auto hibern8 error interrupt, + * in which case the clocks could be gated or be in the + * process of gating when the err handler runs. + */ + if (unlikely((hba->clk_gating.state != CLKS_ON) && + ufshcd_is_auto_hibern8_supported(hba))) { + spin_unlock_irqrestore(hba->host->host_lock, flags); + ufshcd_hold(hba, false); + spin_lock_irqsave(hba->host->host_lock, flags); + clks_enabled = true; + } + hba->ufshcd_state = UFSHCD_STATE_RESET; ufshcd_set_eh_in_progress(hba); @@ -6003,6 +6039,9 @@ skip_err_handling: } hba->silence_err_logs = false; + + if (clks_enabled) + __ufshcd_release(hba, false); out: ufshcd_clear_eh_in_progress(hba); spin_unlock_irqrestore(hba->host->host_lock, flags); diff --git a/drivers/soc/qcom/secure_buffer.c b/drivers/soc/qcom/secure_buffer.c index 95d50fe01ee1..90c7585d480c 100644 --- a/drivers/soc/qcom/secure_buffer.c +++ b/drivers/soc/qcom/secure_buffer.c @@ -364,28 +364,19 @@ int hyp_assign_phys(phys_addr_t addr, u64 size, u32 *source_vm_list, int source_nelems, int *dest_vmids, int *dest_perms, int dest_nelems) { - struct sg_table *table; + struct sg_table table; int ret; - table = kzalloc(sizeof(struct sg_table), GFP_KERNEL); - if (!table) - return -ENOMEM; - ret = sg_alloc_table(table, 1, GFP_KERNEL); + ret = sg_alloc_table(&table, 1, GFP_KERNEL); if (ret) - goto err1; + return ret; - sg_set_page(table->sgl, phys_to_page(addr), size, 0); + sg_set_page(table.sgl, phys_to_page(addr), size, 0); - ret = hyp_assign_table(table, source_vm_list, source_nelems, dest_vmids, - dest_perms, dest_nelems); - if (ret) - goto err2; + ret = hyp_assign_table(&table, source_vm_list, source_nelems, + dest_vmids, dest_perms, dest_nelems); - return ret; -err2: - sg_free_table(table); -err1: - kfree(table); + sg_free_table(&table); return ret; } diff --git a/drivers/soc/qcom/subsystem_restart.c b/drivers/soc/qcom/subsystem_restart.c index 77362912321d..c35ec26fefa2 100644 --- a/drivers/soc/qcom/subsystem_restart.c +++ b/drivers/soc/qcom/subsystem_restart.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1063,8 +1063,9 @@ int subsystem_restart_dev(struct subsys_device *dev) pr_info("Restart sequence requested for %s, restart_level = %s.\n", name, restart_levels[dev->restart_level]); - if (WARN(disable_restart_work == DISABLE_SSR, - "subsys-restart: Ignoring restart request for %s.\n", name)) { + if (disable_restart_work == DISABLE_SSR) { + pr_warn("subsys-restart: Ignoring restart request for %s.\n", + name); return 0; } diff --git a/drivers/usb/gadget/function/f_mbim.c b/drivers/usb/gadget/function/f_mbim.c index cdbac89d8734..e7c3278f66d4 100644 --- a/drivers/usb/gadget/function/f_mbim.c +++ b/drivers/usb/gadget/function/f_mbim.c @@ -2027,7 +2027,7 @@ static long mbim_ioctl(struct file *fp, unsigned cmd, unsigned long arg) default: ret = -ENODEV; pr_err("unknown transport\n"); - break; + goto fail; } ret = copy_to_user((void __user *)arg, &info, @@ -2043,6 +2043,7 @@ static long mbim_ioctl(struct file *fp, unsigned cmd, unsigned long arg) ret = -EINVAL; } +fail: mbim_unlock(&mbim->ioctl_excl); return ret; diff --git a/include/dt-bindings/clock/qcom,gcc-sdm660.h b/include/dt-bindings/clock/qcom,gcc-sdm660.h index 4bf87f6c08bf..e66633c74c0c 100644 --- a/include/dt-bindings/clock/qcom,gcc-sdm660.h +++ b/include/dt-bindings/clock/qcom,gcc-sdm660.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -77,11 +77,9 @@ #define GCC_GP2_CLK 62 #define GCC_GP3_CLK 63 #define GCC_GPU_BIMC_GFX_CLK 64 -#define GCC_GPU_BIMC_GFX_SRC_CLK 65 #define GCC_GPU_CFG_AHB_CLK 66 #define GCC_GPU_GPLL0_CLK 67 #define GCC_GPU_GPLL0_DIV_CLK 68 -#define GCC_GPU_SNOC_DVM_GFX_CLK 69 #define GCC_HMSS_AHB_CLK 70 #define GCC_HMSS_DVM_BUS_CLK 71 #define GCC_HMSS_RBCPR_CLK 72 @@ -134,7 +132,7 @@ #define GPLL0_OUT_AUX2 119 #define GPLL0_OUT_EARLY 120 #define GPLL0_OUT_MAIN 121 -#define GPLL0_OUT_TEST 122 +#define GPLL0_AO 122 #define GPLL1 123 #define GPLL1_OUT_AUX 124 #define GPLL1_OUT_AUX2 125 diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index 20280ff20e52..de35fe9441fe 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -228,6 +228,7 @@ enum power_supply_property { POWER_SUPPLY_PROP_PE_START, POWER_SUPPLY_PROP_SET_SHIP_MODE, POWER_SUPPLY_PROP_SOC_REPORTING_READY, + POWER_SUPPLY_PROP_DEBUG_BATTERY, /* Local extensions of type int64_t */ POWER_SUPPLY_PROP_CHARGE_COUNTER_EXT, /* Properties of type `const char *' */ diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 760bc4d5a2cf..ee5270f984ba 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1014,6 +1014,14 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC * is stored in the @ampdu_delimiter_crc field) * @RX_FLAG_LDPC: LDPC was used + * @RX_FLAG_ONLY_MONITOR: Report frame only to monitor interfaces without + * processing it in any regular way. + * This is useful if drivers offload some frames but still want to report + * them for sniffing purposes. + * @RX_FLAG_SKIP_MONITOR: Process and report frame to all interfaces except + * monitor interfaces. + * This is useful if drivers offload some frames but still want to report + * them for sniffing purposes. * @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3 * @RX_FLAG_10MHZ: 10 MHz (half channel) was used * @RX_FLAG_5MHZ: 5 MHz (quarter channel) was used @@ -1054,6 +1062,8 @@ enum mac80211_rx_flags { RX_FLAG_MACTIME_END = BIT(21), RX_FLAG_VHT = BIT(22), RX_FLAG_LDPC = BIT(23), + RX_FLAG_ONLY_MONITOR = BIT(24), + RX_FLAG_SKIP_MONITOR = BIT(25), RX_FLAG_STBC_MASK = BIT(26) | BIT(27), RX_FLAG_10MHZ = BIT(28), RX_FLAG_5MHZ = BIT(29), @@ -1072,6 +1082,7 @@ enum mac80211_rx_flags { * @RX_VHT_FLAG_160MHZ: 160 MHz was used * @RX_VHT_FLAG_BF: packet was beamformed */ + enum mac80211_rx_vht_flags { RX_VHT_FLAG_80MHZ = BIT(0), RX_VHT_FLAG_160MHZ = BIT(1), @@ -3751,11 +3762,12 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw); * This function must be called with BHs disabled. * * @hw: the hardware this frame came in on + * @sta: the station the frame was received from, or %NULL * @skb: the buffer to receive, owned by mac80211 after this call * @napi: the NAPI context */ -void ieee80211_rx_napi(struct ieee80211_hw *hw, struct sk_buff *skb, - struct napi_struct *napi); +void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *sta, + struct sk_buff *skb, struct napi_struct *napi); /** * ieee80211_rx - receive frame @@ -3779,7 +3791,7 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct sk_buff *skb, */ static inline void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) { - ieee80211_rx_napi(hw, skb, NULL); + ieee80211_rx_napi(hw, NULL, skb, NULL); } /** @@ -5467,4 +5479,19 @@ void ieee80211_unreserve_tid(struct ieee80211_sta *sta, u8 tid); */ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, struct ieee80211_txq *txq); + +/** + * ieee80211_txq_get_depth - get pending frame/byte count of given txq + * + * The values are not guaranteed to be coherent with regard to each other, i.e. + * txq state can change half-way of this function and the caller may end up + * with "new" frame_cnt and "old" byte_cnt or vice-versa. + * + * @txq: pointer obtained from station or virtual interface + * @frame_cnt: pointer to store frame count + * @byte_cnt: pointer to store byte count + */ +void ieee80211_txq_get_depth(struct ieee80211_txq *txq, + unsigned long *frame_cnt, + unsigned long *byte_cnt); #endif /* MAC80211_H */ diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index ae68222c5a74..1d0f1a1ac44c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1685,7 +1685,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags, TRACE_FLAG_IRQS_NOSUPPORT | #endif ((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) | - ((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) | + ((pc & SOFTIRQ_OFFSET) ? TRACE_FLAG_SOFTIRQ : 0) | (tif_need_resched() ? TRACE_FLAG_NEED_RESCHED : 0) | (test_preempt_need_resched() ? TRACE_FLAG_PREEMPT_RESCHED : 0); } diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 316b316c7528..c0ab232e3abd 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -49,6 +49,7 @@ #include <linux/moduleparam.h> #include <linux/uaccess.h> #include <linux/bug.h> +#include <linux/delay.h> #include "workqueue_internal.h" @@ -1285,6 +1286,12 @@ fail: if (work_is_canceling(work)) return -ENOENT; cpu_relax(); + /* + * The queueing is in progress in another context. If we keep + * taking the pool->lock in a busy loop, the other context may + * never get the lock. Give 1 usec delay to avoid this contention. + */ + udelay(1); return -EAGAIN; } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 6837a46ca4a2..67fede656ea5 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -808,6 +808,7 @@ enum txq_info_flags { struct txq_info { struct sk_buff_head queue; unsigned long flags; + unsigned long byte_cnt; /* keep last! */ struct ieee80211_txq txq; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index bcb0a1b64556..7fc1250c8d37 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -979,6 +979,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, spin_lock_bh(&txqi->queue.lock); ieee80211_purge_tx_queue(&local->hw, &txqi->queue); + txqi->byte_cnt = 0; spin_unlock_bh(&txqi->queue.lock); atomic_set(&sdata->txqs_len[txqi->txq.ac], 0); diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index a3bb8f7f5fc5..4f4c45ba7b70 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -122,7 +122,8 @@ static inline bool should_drop_frame(struct sk_buff *skb, int present_fcs_len, hdr = (void *)(skb->data + rtap_vendor_space); if (status->flag & (RX_FLAG_FAILED_FCS_CRC | - RX_FLAG_FAILED_PLCP_CRC)) + RX_FLAG_FAILED_PLCP_CRC | + RX_FLAG_ONLY_MONITOR)) return true; if (unlikely(skb->len < 16 + present_fcs_len + rtap_vendor_space)) @@ -507,7 +508,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, return NULL; } - if (!local->monitors) { + if (!local->monitors || (status->flag & RX_FLAG_SKIP_MONITOR)) { if (should_drop_frame(origskb, present_fcs_len, rtap_vendor_space)) { dev_kfree_skb(origskb); @@ -2203,16 +2204,22 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) if (!(status->rx_flags & IEEE80211_RX_AMSDU)) return RX_CONTINUE; - if (ieee80211_has_a4(hdr->frame_control) && - rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN && - !rx->sdata->u.vlan.sta) - return RX_DROP_UNUSABLE; + if (unlikely(ieee80211_has_a4(hdr->frame_control))) { + switch (rx->sdata->vif.type) { + case NL80211_IFTYPE_AP_VLAN: + if (!rx->sdata->u.vlan.sta) + return RX_DROP_UNUSABLE; + break; + case NL80211_IFTYPE_STATION: + if (!rx->sdata->u.mgd.use_4addr) + return RX_DROP_UNUSABLE; + break; + default: + return RX_DROP_UNUSABLE; + } + } - if (is_multicast_ether_addr(hdr->addr1) && - ((rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN && - rx->sdata->u.vlan.sta) || - (rx->sdata->vif.type == NL80211_IFTYPE_STATION && - rx->sdata->u.mgd.use_4addr))) + if (is_multicast_ether_addr(hdr->addr1)) return RX_DROP_UNUSABLE; skb->dev = dev; @@ -3447,6 +3454,7 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, * be called with rcu_read_lock protection. */ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, + struct ieee80211_sta *pubsta, struct sk_buff *skb, struct napi_struct *napi) { @@ -3456,7 +3464,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, __le16 fc; struct ieee80211_rx_data rx; struct ieee80211_sub_if_data *prev; - struct sta_info *sta, *prev_sta; struct rhash_head *tmp; int err = 0; @@ -3492,7 +3499,14 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, ieee80211_is_beacon(hdr->frame_control))) ieee80211_scan_rx(local, skb); - if (ieee80211_is_data(fc)) { + if (pubsta) { + rx.sta = container_of(pubsta, struct sta_info, sta); + rx.sdata = rx.sta->sdata; + if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) + return; + goto out; + } else if (ieee80211_is_data(fc)) { + struct sta_info *sta, *prev_sta; const struct bucket_table *tbl; prev_sta = NULL; @@ -3566,8 +3580,8 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, * This is the receive path handler. It is called by a low level driver when an * 802.11 MPDU is received from the hardware. */ -void ieee80211_rx_napi(struct ieee80211_hw *hw, struct sk_buff *skb, - struct napi_struct *napi) +void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta, + struct sk_buff *skb, struct napi_struct *napi) { struct ieee80211_local *local = hw_to_local(hw); struct ieee80211_rate *rate = NULL; @@ -3666,7 +3680,8 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct sk_buff *skb, ieee80211_tpt_led_trig_rx(local, ((struct ieee80211_hdr *)skb->data)->frame_control, skb->len); - __ieee80211_rx_handle_packet(hw, skb, napi); + + __ieee80211_rx_handle_packet(hw, pubsta, skb, napi); rcu_read_unlock(); diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 67066d048e6f..fe88071d4abb 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -115,6 +115,7 @@ static void __cleanup_single_sta(struct sta_info *sta) ieee80211_purge_tx_queue(&local->hw, &txqi->queue); atomic_sub(n, &sdata->txqs_len[txqi->txq.ac]); + txqi->byte_cnt = 0; } } diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index e1225b395415..2022f1cf38e1 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1266,7 +1266,11 @@ static void ieee80211_drv_tx(struct ieee80211_local *local, if (atomic_read(&sdata->txqs_len[ac]) >= local->hw.txq_ac_max_pending) netif_stop_subqueue(sdata->dev, ac); - skb_queue_tail(&txqi->queue, skb); + spin_lock_bh(&txqi->queue.lock); + txqi->byte_cnt += skb->len; + __skb_queue_tail(&txqi->queue, skb); + spin_unlock_bh(&txqi->queue.lock); + drv_wake_tx_queue(local, txqi); return; @@ -1294,6 +1298,8 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, if (!skb) goto out; + txqi->byte_cnt -= skb->len; + atomic_dec(&sdata->txqs_len[ac]); if (__netif_subqueue_stopped(sdata->dev, ac)) ieee80211_propagate_queue_wake(local, sdata->vif.hw_queue[ac]); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 9ea2cc098ad1..bc799a4b7cd1 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -3340,3 +3340,17 @@ void ieee80211_init_tx_queue(struct ieee80211_sub_if_data *sdata, txqi->txq.ac = IEEE80211_AC_BE; } } + +void ieee80211_txq_get_depth(struct ieee80211_txq *txq, + unsigned long *frame_cnt, + unsigned long *byte_cnt) +{ + struct txq_info *txqi = to_txq_info(txq); + + if (frame_cnt) + *frame_cnt = txqi->queue.qlen; + + if (byte_cnt) + *byte_cnt = txqi->byte_cnt; +} +EXPORT_SYMBOL(ieee80211_txq_get_depth); diff --git a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c index cee4720bbe31..b94001d8a6eb 100644 --- a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c +++ b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2383,6 +2383,7 @@ static int msm_anlg_cdc_codec_enable_dig_clk(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMU: msm_anlg_cdc_codec_enable_clock_block(codec, 1); snd_soc_update_bits(codec, w->reg, 0x80, 0x80); + msm_anlg_cdc_boost_mode_sequence(codec, SPK_PMU); break; case SND_SOC_DAPM_POST_PMD: if (sdm660_cdc->rx_bias_count == 0) @@ -4016,6 +4017,7 @@ int msm_anlg_codec_info_create_codec_entry(struct snd_info_entry *codec_root, struct snd_info_entry *version_entry; struct sdm660_cdc_priv *sdm660_cdc_priv; struct snd_soc_card *card; + int ret; if (!codec_root || !codec) return -EINVAL; @@ -4023,7 +4025,7 @@ int msm_anlg_codec_info_create_codec_entry(struct snd_info_entry *codec_root, sdm660_cdc_priv = snd_soc_codec_get_drvdata(codec); card = codec->component.card; sdm660_cdc_priv->entry = snd_register_module_info(codec_root->module, - "pmic_analog", + "spmi0-03", codec_root); if (!sdm660_cdc_priv->entry) { dev_dbg(codec->dev, "%s: failed to create pmic_analog entry\n", @@ -4050,6 +4052,16 @@ int msm_anlg_codec_info_create_codec_entry(struct snd_info_entry *codec_root, return -ENOMEM; } sdm660_cdc_priv->version_entry = version_entry; + sdm660_cdc_priv->audio_ssr_nb.notifier_call = + sdm660_cdc_notifier_service_cb; + ret = audio_notifier_register("pmic_analog_cdc", + AUDIO_NOTIFIER_ADSP_DOMAIN, + &sdm660_cdc_priv->audio_ssr_nb); + if (ret < 0) { + pr_err("%s: Audio notifier register failed ret = %d\n", + __func__, ret); + return ret; + } return 0; } EXPORT_SYMBOL(msm_anlg_codec_info_create_codec_entry); @@ -4176,17 +4188,6 @@ static int msm_anlg_cdc_soc_probe(struct snd_soc_codec *codec) /* Set initial cap mode */ msm_anlg_cdc_configure_cap(codec, false, false); - sdm660_cdc_priv->audio_ssr_nb.notifier_call = - sdm660_cdc_notifier_service_cb; - ret = audio_notifier_register("pmic_analog_cdc", - AUDIO_NOTIFIER_ADSP_DOMAIN, - &sdm660_cdc_priv->audio_ssr_nb); - if (ret < 0) { - pr_err("%s: Audio notifier register failed ret = %d\n", - __func__, ret); - wcd_mbhc_deinit(&sdm660_cdc_priv->mbhc); - return ret; - } return 0; } @@ -4586,6 +4587,8 @@ static int msm_anlg_cdc_probe(struct platform_device *pdev) usleep_range(5, 6); dev_set_drvdata(&pdev->dev, sdm660_cdc); + wcd9xxx_spmi_set_dev(pdev, 0); + wcd9xxx_spmi_set_dev(pdev, 1); if (wcd9xxx_spmi_irq_init()) { dev_err(&pdev->dev, "%s: irq initialization failed\n", __func__); diff --git a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c index ac71e3c6d6a1..c39b6d57f908 100644 --- a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c +++ b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -815,7 +815,7 @@ static int msm_dig_cdc_codec_enable_dmic(struct snd_soc_dapm_widget *w, } snd_soc_update_bits(codec, MSM89XX_CDC_CORE_TX1_DMIC_CTL + (dmic - 1) * 0x20, - 0x07, 0x01); + 0x07, 0x02); break; case SND_SOC_DAPM_POST_PMD: (*dmic_clk_cnt)--; @@ -1132,7 +1132,7 @@ int msm_dig_codec_info_create_codec_entry(struct snd_info_entry *codec_root, msm_dig = snd_soc_codec_get_drvdata(codec); card = codec->component.card; msm_dig->entry = snd_register_module_info(codec_root->module, - "msm_digital", + "msm_digital_codec", codec_root); if (!msm_dig->entry) { dev_dbg(codec->dev, "%s: failed to create msm_digital entry\n", @@ -1202,9 +1202,8 @@ static int msm_dig_cdc_soc_probe(struct snd_soc_codec *codec) return ret; } } - if (msm_dig_cdc->get_cdc_version) - dig_cdc->version = msm_dig_cdc->get_cdc_version( - msm_dig_cdc->handle); + /* Assign to DRAX_CDC for initial version */ + dig_cdc->version = DRAX_CDC; registered_digcodec = codec; return 0; } @@ -1557,16 +1556,18 @@ static const struct snd_soc_dapm_widget msm_dig_dapm_widgets[] = { SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER_E("RX1 CHAIN", MSM89XX_CDC_CORE_RX1_B6_CTL, - MSM89XX_RX1, 0, NULL, 0, + SND_SOC_DAPM_MIXER_E("RX1 CHAIN", SND_SOC_NOPM, + 0, 0, NULL, 0, + msm_dig_cdc_codec_enable_rx_chain, + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX2 CHAIN", SND_SOC_NOPM, + 0, 0, NULL, 0, + msm_dig_cdc_codec_enable_rx_chain, + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX3 CHAIN", SND_SOC_NOPM, + 0, 0, NULL, 0, msm_dig_cdc_codec_enable_rx_chain, SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER_E("RX2 CHAIN", MSM89XX_CDC_CORE_RX2_B6_CTL, - MSM89XX_RX2, 0, NULL, 0, - msm_dig_cdc_codec_enable_rx_chain, SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER_E("RX3 CHAIN", MSM89XX_CDC_CORE_RX3_B6_CTL, - MSM89XX_RX3, 0, NULL, 0, - msm_dig_cdc_codec_enable_rx_chain, SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0, &rx_mix1_inp1_mux), diff --git a/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.c b/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.c index 63a715c5248c..78a9a10a258f 100644 --- a/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.c +++ b/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -13,6 +13,7 @@ #include <linux/bitops.h> #include <linux/module.h> #include <linux/init.h> +#include <linux/of_irq.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/slab.h> @@ -83,7 +84,7 @@ struct wcd9xxx_spmi_map { uint8_t mask[NUM_IRQ_REGS]; int linuxirq[MAX_NUM_IRQS]; irq_handler_t handler[MAX_NUM_IRQS]; - struct spmi_device *spmi[NUM_IRQ_REGS]; + struct platform_device *spmi[NUM_IRQ_REGS]; struct snd_soc_codec *codec; enum wcd9xxx_spmi_pm_state pm_state; @@ -99,22 +100,6 @@ struct wcd9xxx_spmi_map map; void wcd9xxx_spmi_enable_irq(int irq) { pr_debug("%s: irqno =%d\n", __func__, irq); - if ((irq >= 0) && (irq <= 7)) { - snd_soc_update_bits(map.codec, - MSM89XX_PMIC_DIGITAL_INT_EN_CLR, - (0x01 << irq), 0x00); - snd_soc_update_bits(map.codec, - MSM89XX_PMIC_DIGITAL_INT_EN_SET, - (0x01 << irq), (0x01 << irq)); - } - if ((irq > 7) && (irq <= 15)) { - snd_soc_update_bits(map.codec, - MSM89XX_PMIC_ANALOG_INT_EN_CLR, - (0x01 << (irq - 8)), 0x00); - snd_soc_update_bits(map.codec, - MSM89XX_PMIC_ANALOG_INT_EN_SET, - (0x01 << (irq - 8)), (0x01 << (irq - 8))); - } if (!(map.mask[BIT_BYTE(irq)] & (BYTE_BIT_MASK(irq)))) return; @@ -128,23 +113,6 @@ void wcd9xxx_spmi_enable_irq(int irq) void wcd9xxx_spmi_disable_irq(int irq) { pr_debug("%s: irqno =%d\n", __func__, irq); - if ((irq >= 0) && (irq <= 7)) { - snd_soc_update_bits(map.codec, - MSM89XX_PMIC_DIGITAL_INT_EN_SET, - (0x01 << (irq)), 0x00); - snd_soc_update_bits(map.codec, - MSM89XX_PMIC_DIGITAL_INT_EN_CLR, - (0x01 << irq), (0x01 << irq)); - } - - if ((irq > 7) && (irq <= 15)) { - snd_soc_update_bits(map.codec, - MSM89XX_PMIC_ANALOG_INT_EN_SET, - (0x01 << (irq - 8)), 0x00); - snd_soc_update_bits(map.codec, - MSM89XX_PMIC_ANALOG_INT_EN_CLR, - (0x01 << (irq - 8)), (0x01 << (irq - 8))); - } if (map.mask[BIT_BYTE(irq)] & (BYTE_BIT_MASK(irq))) return; @@ -161,6 +129,10 @@ int wcd9xxx_spmi_request_irq(int irq, irq_handler_t handler, int rc; unsigned long irq_flags; + map.linuxirq[irq] = + platform_get_irq_byname(map.spmi[BIT_BYTE(irq)], + irq_names[irq]); + if (strcmp(name, "mbhc sw intr")) irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT; @@ -414,7 +386,7 @@ void wcd9xxx_spmi_set_codec(struct snd_soc_codec *codec) map.codec = codec; } -void wcd9xxx_spmi_set_dev(struct spmi_device *spmi, int i) +void wcd9xxx_spmi_set_dev(struct platform_device *spmi, int i) { if (i < NUM_IRQ_REGS) map.spmi[i] = spmi; diff --git a/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.h b/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.h index 659e52cc2a5e..42596df0f65b 100644 --- a/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.h +++ b/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -24,7 +24,7 @@ extern int wcd9xxx_spmi_request_irq(int irq, irq_handler_t handler, const char *name, void *priv); extern int wcd9xxx_spmi_free_irq(int irq, void *priv); extern void wcd9xxx_spmi_set_codec(struct snd_soc_codec *codec); -extern void wcd9xxx_spmi_set_dev(struct spmi_device *spmi, int i); +extern void wcd9xxx_spmi_set_dev(struct platform_device *spmi, int i); extern int wcd9xxx_spmi_irq_init(void); extern int wcd9xxx_spmi_suspend(pm_message_t); extern int wcd9xxx_spmi_resume(void); diff --git a/sound/soc/codecs/sdm660_cdc/sdm660-regmap.c b/sound/soc/codecs/sdm660_cdc/sdm660-regmap.c index 1c3a8d2c2fd9..fff1fdc5b421 100644 --- a/sound/soc/codecs/sdm660_cdc/sdm660-regmap.c +++ b/sound/soc/codecs/sdm660_cdc/sdm660-regmap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -452,20 +452,8 @@ bool msm89xx_cdc_core_readable_reg(struct device *dev, unsigned int reg) bool msm89xx_cdc_core_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { - case MSM89XX_CDC_CORE_RX1_B1_CTL: - case MSM89XX_CDC_CORE_RX2_B1_CTL: - case MSM89XX_CDC_CORE_RX3_B1_CTL: - case MSM89XX_CDC_CORE_RX1_B6_CTL: - case MSM89XX_CDC_CORE_RX2_B6_CTL: - case MSM89XX_CDC_CORE_RX3_B6_CTL: - case MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG: - case MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG: - case MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL: - case MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL: - case MSM89XX_CDC_CORE_CLK_MCLK_CTL: - case MSM89XX_CDC_CORE_CLK_PDM_CTL: - return true; + /* cache bypass for initial version */ default: - return false; + return true; } } diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c index dbe61b252cb9..41f68e05e075 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c @@ -9383,12 +9383,6 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { slimbus_8_rx_voice_mixer_controls, ARRAY_SIZE(slimbus_8_rx_voice_mixer_controls)), /* port mixer */ - SND_SOC_DAPM_MIXER("INT0_MI2S_RX Port Mixer", - SND_SOC_NOPM, 0, 0, int0_mi2s_rx_port_mixer_controls, - ARRAY_SIZE(int0_mi2s_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("INT4_MI2S_RX Port Mixer", - SND_SOC_NOPM, 0, 0, int4_mi2s_rx_port_mixer_controls, - ARRAY_SIZE(int4_mi2s_rx_port_mixer_controls)), SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Port Mixer", SND_SOC_NOPM, 0, 0, sbus_0_rx_port_mixer_controls, ARRAY_SIZE(sbus_0_rx_port_mixer_controls)), diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c index b87dcd36958f..4ceaa452f14b 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2937,6 +2937,20 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, case AFE_PORT_ID_QUINARY_MI2S_RX: case AFE_PORT_ID_QUINARY_MI2S_TX: case AFE_PORT_ID_SENARY_MI2S_TX: + case AFE_PORT_ID_INT0_MI2S_RX: + case AFE_PORT_ID_INT0_MI2S_TX: + case AFE_PORT_ID_INT1_MI2S_RX: + case AFE_PORT_ID_INT1_MI2S_TX: + case AFE_PORT_ID_INT2_MI2S_RX: + case AFE_PORT_ID_INT2_MI2S_TX: + case AFE_PORT_ID_INT3_MI2S_RX: + case AFE_PORT_ID_INT3_MI2S_TX: + case AFE_PORT_ID_INT4_MI2S_RX: + case AFE_PORT_ID_INT4_MI2S_TX: + case AFE_PORT_ID_INT5_MI2S_RX: + case AFE_PORT_ID_INT5_MI2S_TX: + case AFE_PORT_ID_INT6_MI2S_RX: + case AFE_PORT_ID_INT6_MI2S_TX: cfg_type = AFE_PARAM_ID_I2S_CONFIG; break; case HDMI_RX: @@ -3316,6 +3330,34 @@ int afe_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_7; case AFE_PORT_ID_QUATERNARY_TDM_TX_7: return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_7; + case AFE_PORT_ID_INT0_MI2S_RX: + return IDX_AFE_PORT_ID_INT0_MI2S_RX; + case AFE_PORT_ID_INT0_MI2S_TX: + return IDX_AFE_PORT_ID_INT0_MI2S_TX; + case AFE_PORT_ID_INT1_MI2S_RX: + return IDX_AFE_PORT_ID_INT1_MI2S_RX; + case AFE_PORT_ID_INT1_MI2S_TX: + return IDX_AFE_PORT_ID_INT1_MI2S_TX; + case AFE_PORT_ID_INT2_MI2S_RX: + return IDX_AFE_PORT_ID_INT2_MI2S_RX; + case AFE_PORT_ID_INT2_MI2S_TX: + return IDX_AFE_PORT_ID_INT2_MI2S_TX; + case AFE_PORT_ID_INT3_MI2S_RX: + return IDX_AFE_PORT_ID_INT3_MI2S_RX; + case AFE_PORT_ID_INT3_MI2S_TX: + return IDX_AFE_PORT_ID_INT3_MI2S_TX; + case AFE_PORT_ID_INT4_MI2S_RX: + return IDX_AFE_PORT_ID_INT4_MI2S_RX; + case AFE_PORT_ID_INT4_MI2S_TX: + return IDX_AFE_PORT_ID_INT4_MI2S_TX; + case AFE_PORT_ID_INT5_MI2S_RX: + return IDX_AFE_PORT_ID_INT5_MI2S_RX; + case AFE_PORT_ID_INT5_MI2S_TX: + return IDX_AFE_PORT_ID_INT5_MI2S_TX; + case AFE_PORT_ID_INT6_MI2S_RX: + return IDX_AFE_PORT_ID_INT6_MI2S_RX; + case AFE_PORT_ID_INT6_MI2S_TX: + return IDX_AFE_PORT_ID_INT6_MI2S_TX; default: pr_err("%s: port 0x%x\n", __func__, port_id); return -EINVAL; diff --git a/sound/soc/msm/sdm660-common.c b/sound/soc/msm/sdm660-common.c index 1497ddcca61f..63d8598d0b92 100644 --- a/sound/soc/msm/sdm660-common.c +++ b/sound/soc/msm/sdm660-common.c @@ -351,7 +351,7 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = { static struct afe_clk_set mi2s_mclk[MI2S_MAX] = { { AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_MCLK_1, + Q6AFE_LPASS_CLK_ID_MCLK_3, Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, @@ -359,7 +359,7 @@ static struct afe_clk_set mi2s_mclk[MI2S_MAX] = { }, { AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_MCLK_2, + Q6AFE_LPASS_CLK_ID_MCLK_4, Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, @@ -367,7 +367,7 @@ static struct afe_clk_set mi2s_mclk[MI2S_MAX] = { }, { AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_MCLK_3, + Q6AFE_LPASS_CLK_ID_MCLK_1, Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, @@ -375,7 +375,7 @@ static struct afe_clk_set mi2s_mclk[MI2S_MAX] = { }, { AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_MCLK_4, + Q6AFE_LPASS_CLK_ID_MCLK_2, Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, diff --git a/sound/soc/msm/sdm660-internal.c b/sound/soc/msm/sdm660-internal.c index c5661dd7ec1e..4ca579694a05 100644 --- a/sound/soc/msm/sdm660-internal.c +++ b/sound/soc/msm/sdm660-internal.c @@ -181,9 +181,7 @@ static int msm_int_mi2s_snd_startup(struct snd_pcm_substream *substream); static void msm_int_mi2s_snd_shutdown(struct snd_pcm_substream *substream); static struct wcd_mbhc_config *mbhc_cfg_ptr; -static struct snd_info_entry *msm_sdw_codec_root; -static struct snd_info_entry *msm_dig_codec_root; -static struct snd_info_entry *pmic_analog_codec_root; +static struct snd_info_entry *codec_root; static int int_mi2s_get_bit_format_val(int bit_format) { @@ -916,15 +914,6 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("INT3_MI2S_TX SampleRate", int3_mi2s_tx_sample_rate, int_mi2s_sample_rate_get, int_mi2s_sample_rate_put), - SOC_ENUM_EXT("INT0_MI2S_RX SampleRate", int0_mi2s_rx_sample_rate, - int_mi2s_sample_rate_get, - int_mi2s_sample_rate_put), - SOC_ENUM_EXT("INT2_MI2S_TX SampleRate", int2_mi2s_tx_sample_rate, - int_mi2s_sample_rate_get, - int_mi2s_sample_rate_put), - SOC_ENUM_EXT("INT3_MI2S_TX SampleRate", int3_mi2s_tx_sample_rate, - int_mi2s_sample_rate_get, - int_mi2s_sample_rate_put), SOC_ENUM_EXT("INT0_MI2S_RX Channels", int0_mi2s_rx_chs, int_mi2s_ch_get, int_mi2s_ch_put), SOC_ENUM_EXT("INT2_MI2S_TX Channels", int2_mi2s_tx_chs, @@ -1295,7 +1284,6 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_pcm_runtime *rtd_aux = rtd->card->rtd_aux; struct snd_card *card; - struct snd_info_entry *entry; int ret = -ENOMEM; pr_debug("%s(),dev_name%s\n", __func__, dev_name(cpu_dai->dev)); @@ -1361,26 +1349,16 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) } } card = rtd->card->snd_card; - entry = snd_register_module_info(card->module, "codecs", - card->proc_root); - if (!entry) { - pr_debug("%s: Cannot create codecs module entry\n", - __func__); - msm_dig_codec_root = NULL; - goto done; - } - msm_dig_codec_root = entry; - msm_dig_codec_info_create_codec_entry(msm_dig_codec_root, dig_cdc); - entry = snd_register_module_info(card->module, "codecs", - card->proc_root); - if (!entry) { + if (!codec_root) + codec_root = snd_register_module_info(card->module, "codecs", + card->proc_root); + if (!codec_root) { pr_debug("%s: Cannot create codecs module entry\n", __func__); - pmic_analog_codec_root = NULL; goto done; } - pmic_analog_codec_root = entry; - msm_anlg_codec_info_create_codec_entry(pmic_analog_codec_root, ana_cdc); + msm_dig_codec_info_create_codec_entry(codec_root, dig_cdc); + msm_anlg_codec_info_create_codec_entry(codec_root, ana_cdc); done: return 0; } @@ -1391,7 +1369,6 @@ static int msm_sdw_audrx_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct snd_card *card; - struct snd_info_entry *entry; snd_soc_add_codec_controls(codec, msm_sdw_controls, ARRAY_SIZE(msm_sdw_controls)); @@ -1406,16 +1383,15 @@ static int msm_sdw_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_sync(dapm); msm_sdw_gpio_cb(msm_config_sdw_gpio, codec); card = rtd->card->snd_card; - entry = snd_register_module_info(card->module, "codecs", - card->proc_root); - if (!entry) { + if (!codec_root) + codec_root = snd_register_module_info(card->module, "codecs", + card->proc_root); + if (!codec_root) { pr_debug("%s: Cannot create codecs module entry\n", __func__); - msm_sdw_codec_root = NULL; goto done; } - msm_sdw_codec_root = entry; - msm_sdw_codec_info_create_codec_entry(msm_sdw_codec_root, codec); + msm_sdw_codec_info_create_codec_entry(codec_root, codec); done: return 0; } |
