diff options
93 files changed, 2115 insertions, 410 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/arm/msm/spss_utils.txt b/Documentation/devicetree/bindings/arm/msm/spss_utils.txt index 61d3865b73d5..0e8e75ba87f8 100644 --- a/Documentation/devicetree/bindings/arm/msm/spss_utils.txt +++ b/Documentation/devicetree/bindings/arm/msm/spss_utils.txt @@ -11,19 +11,25 @@ according to a dedicated fuse and the platform HW version. Required properties: -compatible : should be "qcom,spss_utils" --qcom,spss-fuse-addr: fuse register physical address --qcom,spss-fuse-bit: fuse relevant bit +-qcom,spss-fuse1-addr: fuse1 register physical address +-qcom,spss-fuse1-bit: fuse1 relevant bit +-qcom,spss-fuse2-addr: fuse2 register physical address +-qcom,spss-fuse2-bit: fuse2 relevant bit -qcom,spss-test-firmware-name: test firmware file name -qcom,spss-prod-firmware-name: production firmware file name +-qcom,spss-hybr-firmware-name: hybrid firmware file name -qcom,spss-debug-reg-addr: debug register physical address Example: qcom,spss_utils { compatible = "qcom,spss-utils"; - qcom,spss-fuse-addr = <0x007841c4>; /* spss test fuse physical address */ - qcom,spss-fuse-bit = <27>; - qcom,spss-test-firmware-name = "spss1t"; /* 8 chars max */ - qcom,spss-prod-firmware-name = "spss1p"; /* 8 chars max */ + qcom,spss-fuse1-addr = <0x007841c4>; + qcom,spss-fuse1-bit = <27>; + qcom,spss-fuse2-addr = <0x0078413c>; + qcom,spss-fuse2-bit = <31>; + qcom,spss-test-firmware-name = "spss2t"; /* 8 chars max */ + qcom,spss-prod-firmware-name = "spss2p"; /* 8 chars max */ + qcom,spss-hybr-firmware-name = "spss2h"; /* 8 chars max */ qcom,spss-debug-reg-addr = <0x01d06020>; }; diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt index e8177c3a0952..f79f49608743 100644 --- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt +++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt @@ -1663,6 +1663,10 @@ mclk frequency needs to be configured for internal and external PA. - qcom,cdc-comp-gpios : phandle for compander gpios. - qcom,cdc-dmic-gpios : phandle for Digital mic clk and data gpios. - qcom,cdc-sdw-gpios : phandle for soundwire clk and data gpios. +- qcom,msm-mbhc-moist-cfg: This property is used to set moisture detection + threshold values for different codecs. First parameter is V(voltage) + second one is i(current), third one is r (resistance). Depending on the + codec set corresponding element in array and set others to 0. Example: sound { @@ -1671,6 +1675,7 @@ Example: qcom,msm-mclk-freq = <9600000>; qcom,msm-mbhc-hphl-swh = <0>; qcom,msm-mbhc-gnd-swh = <0>; + qcom,msm-mbhc-moist-cfg = <1>, <3>, <0>; qcom,msm-hs-micbias-type = "internal"; qcom,msm-micbias1-ext-cap; qcom,audio-routing = 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-audio.dtsi b/arch/arm/boot/dts/qcom/msm-audio.dtsi index d86e77e2c7ee..46f66d667fb8 100644 --- a/arch/arm/boot/dts/qcom/msm-audio.dtsi +++ b/arch/arm/boot/dts/qcom/msm-audio.dtsi @@ -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 @@ -11,6 +11,10 @@ * GNU General Public License for more details. */ +&spi_7 { + status = "okay"; +}; + &soc { pcm0: qcom,msm-pcm { compatible = "qcom,msm-pcm-dsp"; @@ -61,6 +65,18 @@ qcom,msm-cpe-lsm-id = <3>; }; + wdsp_mgr: qcom,wcd-dsp-mgr { + compatible = "qcom,wcd-dsp-mgr"; + qcom,wdsp-components = <&wcd934x_cdc 0>, + <&wcd_spi_0 1>, + <&glink_spi_xprt_wdsp 2>; + qcom,img-filename = "cpe_9340"; + }; + + wdsp_glink: qcom,wcd-dsp-glink { + compatible = "qcom,wcd-dsp-glink"; + }; + compress: qcom,msm-compress-dsp { compatible = "qcom,msm-compress-dsp"; }; 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/msm-pm660l.dtsi b/arch/arm/boot/dts/qcom/msm-pm660l.dtsi index d0033d5bf3bc..3ac4c851f5ba 100644 --- a/arch/arm/boot/dts/qcom/msm-pm660l.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pm660l.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 @@ -37,7 +37,7 @@ qcom,temp-alarm@2400 { compatible = "qcom,qpnp-temp-alarm"; reg = <0x2400 0x100>; - interrupts = <0x0 0x24 0x0 IRQ_TYPE_EDGE_RISING>; + interrupts = <0x2 0x24 0x0 IRQ_TYPE_EDGE_RISING>; label = "pm660l_tz"; }; diff --git a/arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk-evt3.dtsi b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk-evt3.dtsi new file mode 100644 index 000000000000..7e52b0258f1f --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk-evt3.dtsi @@ -0,0 +1,454 @@ +/* + * 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. + */ + +&soc { + led_flash0: qcom,camera-flash@0 { + cell-index = <0>; + compatible = "qcom,camera-flash"; + qcom,flash-source = <&pmi8998_flash0 &pmi8998_flash1>; + qcom,torch-source = <&pmi8998_torch0 &pmi8998_torch1>; + qcom,switch-source = <&pmi8998_switch0>; + status = "ok"; + }; + + led_flash1: qcom,camera-flash@1 { + cell-index = <1>; + compatible = "qcom,camera-flash"; + qcom,flash-source = <&pmi8998_flash2>; + qcom,torch-source = <&pmi8998_torch2>; + qcom,switch-source = <&pmi8998_switch1>; + status = "ok"; + }; + + rear_vana_regulator:fixed_regulator@0 { + compatible = "regulator-fixed"; + regulator-name = "rear_vana_regulator"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + enable-active-high; + gpio = <&tlmm 27 0>; + vin-supply = <&pmi8998_bob>; + }; + + vaf1_gpio_supply:fixed_regulator@1 { + compatible = "regulator-fixed"; + regulator-name = "vaf1_gpio_supply"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + enable-active-high; + gpio = <&tlmm 29 0>; + vin-supply = <&pmi8998_bob>; + }; + + vaf2_gpio_supply:fixed_regulator@2 { + compatible = "regulator-fixed"; + regulator-name = "vaf2_gpio_supply"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + enable-active-high; + gpio = <&tlmm 27 0>; + vin-supply = <&pmi8998_bob>; + }; +}; + +&tlmm{ + cam_sensor_front_active: cam_sensor_front_active { + /* RESET */ + mux { + pins = "gpio9"; + function = "gpio"; + }; + + config { + pins = "gpio9"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_front_suspend: cam_sensor_front_suspend { + /* RESET */ + mux { + pins = "gpio9"; + function = "gpio"; + }; + + config { + pins = "gpio9"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_rear2_active: cam_sensor_rear2_active { + /* RESET, STANDBY */ + mux { + pins = "gpio28"; + function = "gpio"; + }; + + config { + pins = "gpio28"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_rear2_suspend: cam_sensor_rear2_suspend { + /* RESET, STANDBY */ + mux { + pins = "gpio28"; + function = "gpio"; + }; + + config { + pins = "gpio28"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_rear_active: cam_sensor_rear_active { + /* RESET, STANDBY */ + mux { + pins = "gpio30"; + function = "gpio"; + }; + + config { + pins = "gpio30"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_rear_suspend: cam_sensor_rear_suspend { + /* RESET, STANDBY */ + mux { + pins = "gpio30"; + function = "gpio"; + }; + + config { + pins = "gpio30"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; +}; + +&cci { + actuator0: qcom,actuator@0 { + cell-index = <0>; + reg = <0x0>; + compatible = "qcom,actuator"; + qcom,cci-master = <0>; + cam_vaf-supply = <&vaf1_gpio_supply>; + qcom,cam-vreg-name = "cam_vaf"; + qcom,cam-vreg-min-voltage = <2800000>; + qcom,cam-vreg-max-voltage = <2800000>; + qcom,cam-vreg-op-mode = <0>; + }; + + actuator1: qcom,actuator@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,actuator"; + qcom,cci-master = <1>; + cam_vaf-supply = <&vaf2_gpio_supply>; + qcom,cam-vreg-name = "cam_vaf"; + qcom,cam-vreg-min-voltage = <2800000>; + qcom,cam-vreg-max-voltage = <2800000>; + qcom,cam-vreg-op-mode = <0>; + }; + + ois0: qcom,ois@0 { + cell-index = <0>; + reg = <0x0>; + compatible = "qcom,ois"; + qcom,cci-master = <0>; + cam_vaf-supply = <&vaf2_gpio_supply>; + qcom,cam-vreg-name = "cam_vaf"; + qcom,cam-vreg-min-voltage = <2800000>; + qcom,cam-vreg-max-voltage = <2800000>; + qcom,cam-vreg-op-mode = <0>; + status = "disabled"; + }; + + eeprom0: qcom,eeprom@0 { + cell-index = <0>; + reg = <0>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&rear_vana_regulator>; + cam_vdig-supply = <&pm8998_s3>; + qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; + qcom,cam-vreg-min-voltage = <0 2800000 1352000>; + qcom,cam-vreg-max-voltage = <0 2800000 1352000>; + qcom,cam-vreg-op-mode = <0 80000 105000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_rear_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_rear_suspend>; + gpios = <&tlmm 13 0>, + <&tlmm 30 0>, + <&pm8998_gpios 20 0>; + qcom,gpio-reset = <1>; + qcom,gpio-vdig = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_VDIG"; + qcom,sensor-position = <0>; + qcom,sensor-mode = <0>; + qcom,cci-master = <0>; + status = "ok"; + clocks = <&clock_mmss clk_mclk0_clk_src>, + <&clock_mmss clk_mmss_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; + + eeprom1: qcom,eeprom@1 { + cell-index = <1>; + reg = <0x1>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&rear_vana_regulator>; + cam_vdig-supply = <&pm8998_s3>; + qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; + qcom,cam-vreg-min-voltage = <0 2800000 1352000>; + qcom,cam-vreg-max-voltage = <0 2800000 1352000>; + qcom,cam-vreg-op-mode = <0 80000 105000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_rear2_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_rear2_suspend>; + gpios = <&tlmm 14 0>, + <&tlmm 28 0>, + <&pm8998_gpios 20 0>; + qcom,gpio-reset = <1>; + qcom,gpio-vdig = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET1", + "CAM_VDIG"; + qcom,sensor-position = <0>; + qcom,sensor-mode = <0>; + qcom,cci-master = <1>; + status = "ok"; + clocks = <&clock_mmss clk_mclk1_clk_src>, + <&clock_mmss clk_mmss_camss_mclk1_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; + + eeprom2: qcom,eeprom@2 { + cell-index = <2>; + reg = <0x2>; + compatible = "qcom,eeprom"; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pm8998_l22>; + cam_vdig-supply = <&pm8998_s3>; + qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; + qcom,cam-vreg-min-voltage = + <0 2864000 1352000>; + qcom,cam-vreg-max-voltage = + <0 2864000 1352000>; + qcom,cam-vreg-op-mode = <0 80000 105000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_front_suspend>; + gpios = <&tlmm 15 0>, + <&tlmm 9 0>, + <&pm8998_gpios 9 0>; + qcom,gpio-reset = <1>; + qcom,gpio-vdig = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_VDIG"; + qcom,sensor-position = <1>; + qcom,sensor-mode = <0>; + qcom,cci-master = <1>; + status = "ok"; + clocks = <&clock_mmss clk_mclk2_clk_src>, + <&clock_mmss clk_mmss_camss_mclk2_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; + + qcom,camera@0 { + cell-index = <0>; + compatible = "qcom,camera"; + reg = <0x0>; + qcom,special-support-sensors = "imx362_gt24c64a", + "s5k3m3sm", "s5k2l7sx"; + qcom,csiphy-sd-index = <0>; + qcom,csid-sd-index = <0>; + qcom,mount-angle = <270>; + qcom,led-flash-src = <&led_flash0>; + qcom,actuator-src = <&actuator0>; + qcom,eeprom-src = <&eeprom0>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&rear_vana_regulator>; + cam_vdig-supply = <&pm8998_s3>; + qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; + qcom,cam-vreg-min-voltage = <0 2800000 1352000>; + qcom,cam-vreg-max-voltage = <0 2800000 1352000>; + qcom,cam-vreg-op-mode = <0 80000 105000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_active + &cam_sensor_rear_active>; + pinctrl-1 = <&cam_sensor_mclk0_suspend + &cam_sensor_rear_suspend>; + gpios = <&tlmm 13 0>, + <&tlmm 30 0>, + <&pm8998_gpios 20 0>; + qcom,gpio-reset = <1>; + qcom,gpio-vdig = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_VDIG"; + qcom,sensor-position = <0>; + qcom,sensor-mode = <0>; + qcom,cci-master = <0>; + status = "ok"; + clocks = <&clock_mmss clk_mclk0_clk_src>, + <&clock_mmss clk_mmss_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; + + qcom,camera@1 { + cell-index = <1>; + compatible = "qcom,camera"; + reg = <0x1>; + qcom,csiphy-sd-index = <1>; + qcom,csid-sd-index = <1>; + qcom,mount-angle = <90>; + qcom,led-flash-src = <&led_flash0>; + qcom,actuator-src = <&actuator1>; + qcom,eeprom-src = <&eeprom1>; + qcom,ois-src = <&ois0>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&rear_vana_regulator>; + cam_vdig-supply = <&pm8998_s3>; + qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; + qcom,cam-vreg-min-voltage = <0 2800000 1352000>; + qcom,cam-vreg-max-voltage = <0 2800000 1352000>; + qcom,cam-vreg-op-mode = <0 80000 105000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_active + &cam_sensor_rear2_active>; + pinctrl-1 = <&cam_sensor_mclk1_suspend + &cam_sensor_rear2_suspend>; + gpios = <&tlmm 14 0>, + <&tlmm 28 0>, + <&pm8998_gpios 20 0>; + qcom,gpio-reset = <1>; + qcom,gpio-vdig = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK1", + "CAM_RESET1", + "CAM_VDIG"; + qcom,sensor-position = <0>; + qcom,sensor-mode = <0>; + qcom,cci-master = <1>; + status = "ok"; + clocks = <&clock_mmss clk_mclk1_clk_src>, + <&clock_mmss clk_mmss_camss_mclk1_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; + + qcom,camera@2 { + cell-index = <2>; + compatible = "qcom,camera"; + reg = <0x02>; + qcom,csiphy-sd-index = <2>; + qcom,csid-sd-index = <2>; + qcom,mount-angle = <90>; + qcom,eeprom-src = <&eeprom2>; + cam_vio-supply = <&pm8998_lvs1>; + cam_vana-supply = <&pm8998_l22>; + cam_vdig-supply = <&pm8998_s3>; + qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig"; + qcom,cam-vreg-min-voltage = + <0 2864000 1352000>; + qcom,cam-vreg-max-voltage = + <0 2864000 1352000>; + qcom,cam-vreg-op-mode = <0 80000 105000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk2_active + &cam_sensor_front_active>; + pinctrl-1 = <&cam_sensor_mclk2_suspend + &cam_sensor_front_suspend>; + gpios = <&tlmm 15 0>, + <&tlmm 9 0>, + <&pm8998_gpios 9 0>; + qcom,gpio-reset = <1>; + qcom,gpio-vdig = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_VDIG"; + qcom,sensor-position = <1>; + qcom,sensor-mode = <0>; + qcom,cci-master = <1>; + status = "ok"; + clocks = <&clock_mmss clk_mclk2_clk_src>, + <&clock_mmss clk_mmss_camss_mclk2_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <24000000 0>; + }; +}; + +&pm8998_gpios { + gpio@c800 { /* GPIO 9 - CAMERA SENSOR 2 VDIG */ + qcom,mode = <1>; /* Output */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <0>; /* VIN1 GPIO_LV */ + qcom,src-sel = <0>; /* GPIO */ + qcom,invert = <0>; /* Invert */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "ok"; + }; + + gpio@d300 { /* GPIO 20 - CAMERA SENSOR 0/1 VDIG */ + qcom,mode = <1>; /* Output */ + qcom,pull = <5>; /* No Pull */ + qcom,vin-sel = <1>; /* VIN1 GPIO_MV */ + qcom,src-sel = <0>; /* GPIO */ + qcom,invert = <0>; /* Invert */ + qcom,master-en = <1>; /* Enable GPIO */ + status = "ok"; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msm8998-camera.dtsi b/arch/arm/boot/dts/qcom/msm8998-camera.dtsi index 799455a0de2e..f8dae210bc4e 100644 --- a/arch/arm/boot/dts/qcom/msm8998-camera.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-camera.dtsi @@ -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 @@ -559,7 +559,7 @@ "camss_vfe_ahb_clk", "camss_vfe_vbif_ahb_clk", "camss_vfe_vbif_axi_clk", "vfe_clk_src", "camss_csi_vfe_clk"; - qcom,clock-rates = <0 0 0 0 0 0 0 0 0 0 0 384000000 0 + qcom,clock-rates = <0 0 0 0 0 0 0 0 0 0 0 480000000 0 0 0 0 0 0 0 0 0 0 0 0 576000000 0 0 0 0 0 0 0 0 0 0 0 0 600000000 0>; status = "ok"; @@ -639,7 +639,7 @@ "camss_vfe_ahb_clk", "camss_vfe_vbif_ahb_clk", "camss_vfe_vbif_axi_clk", "vfe_clk_src", "camss_csi_vfe_clk"; - qcom,clock-rates = <0 0 0 0 0 0 0 0 0 0 0 384000000 0 + qcom,clock-rates = <0 0 0 0 0 0 0 0 0 0 0 480000000 0 0 0 0 0 0 0 0 0 0 0 0 576000000 0 0 0 0 0 0 0 0 0 0 0 0 600000000 0>; status = "ok"; diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dts b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dts index d9afddd0ab46..753f01ea2ea7 100644 --- a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dts +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dts @@ -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 @@ -15,6 +15,7 @@ #include "msm8998.dtsi" #include "msm8998-qrd-skuk.dtsi" +#include "msm8998-camera-sensor-skuk.dtsi" / { model = "Qualcomm Technologies, Inc. MSM 8998 SKUK"; diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi index d912a18d06f8..c57fa50d0f29 100644 --- a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi @@ -13,7 +13,6 @@ #include <dt-bindings/interrupt-controller/irq.h> #include "msm8998-pinctrl.dtsi" #include "msm8998-audio.dtsi" -#include "msm8998-camera-sensor-skuk.dtsi" / { bluetooth: bt_wcn3990 { diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts index 51ff3888bc3d..a64f620f3999 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts @@ -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 @@ -15,6 +15,7 @@ #include "msm8998-v2.dtsi" #include "msm8998-qrd-skuk.dtsi" +#include "msm8998-camera-sensor-skuk-evt3.dtsi" / { model = "Qualcomm Technologies, Inc. MSM 8998 V2 SKUK EVT3"; diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts index c2b70224ed2c..ca0609f34642 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts @@ -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 @@ -15,6 +15,7 @@ #include "msm8998-v2.dtsi" #include "msm8998-qrd-skuk.dtsi" +#include "msm8998-camera-sensor-skuk.dtsi" / { model = "Qualcomm Technologies, Inc. MSM 8998 SKUK HDK"; diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk.dts index 471602ac80b9..7e7eb96c01d6 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk.dts @@ -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 @@ -15,6 +15,7 @@ #include "msm8998-v2.dtsi" #include "msm8998-qrd-skuk.dtsi" +#include "msm8998-camera-sensor-skuk.dtsi" / { model = "Qualcomm Technologies, Inc. MSM 8998 V2 SKUK"; diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2.dtsi index 2408ad515b61..1d8fe225c9af 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-v2.dtsi @@ -1001,7 +1001,7 @@ &gfx_cpr { compatible = "qcom,cpr4-msm8998-v2-mmss-regulator"; - qcom,cpr-aging-ref-voltage = <1024000>; + qcom,cpr-aging-ref-voltage = <1088000>; }; &gfx_vreg { @@ -1016,13 +1016,13 @@ qcom,cpr-voltage-ceiling = <716000 716000 772000 880000 908000 948000 1016000 1088000>, - <724000 724000 772000 832000 916000 968000 1024000 1024000>, - <724000 724000 772000 832000 916000 968000 1024000 1024000>, - <724000 724000 772000 832000 916000 968000 1024000 1024000>, - <724000 724000 772000 832000 916000 968000 1024000 1024000>, - <724000 724000 772000 832000 916000 968000 1024000 1024000>, - <724000 724000 772000 832000 916000 968000 1024000 1024000>, - <724000 724000 772000 832000 916000 968000 1024000 1024000>; + <724000 724000 772000 832000 916000 968000 1024000 1088000>, + <724000 724000 772000 832000 916000 968000 1024000 1088000>, + <724000 724000 772000 832000 916000 968000 1024000 1088000>, + <724000 724000 772000 832000 916000 968000 1024000 1088000>, + <724000 724000 772000 832000 916000 968000 1024000 1088000>, + <724000 724000 772000 832000 916000 968000 1024000 1088000>, + <724000 724000 772000 832000 916000 968000 1024000 1088000>; qcom,cpr-voltage-floor = <516000 516000 532000 584000 632000 672000 712000 756000>; @@ -1272,6 +1272,7 @@ &spss_utils { qcom,spss-test-firmware-name = "spss2t"; /* 8 chars max */ qcom,spss-prod-firmware-name = "spss2p"; /* 8 chars max */ + qcom,spss-hybr-firmware-name = "spss2h"; /* 8 chars max */ }; &ufs1 { diff --git a/arch/arm/boot/dts/qcom/msm8998.dtsi b/arch/arm/boot/dts/qcom/msm8998.dtsi index 150a3c42c6b7..cb3d1fee1f48 100644 --- a/arch/arm/boot/dts/qcom/msm8998.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998.dtsi @@ -1510,11 +1510,14 @@ spss_utils: qcom,spss_utils { compatible = "qcom,spss-utils"; - /* spss test fuse physical address */ - qcom,spss-fuse-addr = <0x007841c4>; - qcom,spss-fuse-bit = <27>; + /* spss fuses physical address */ + qcom,spss-fuse1-addr = <0x007841c4>; + qcom,spss-fuse1-bit = <27>; + qcom,spss-fuse2-addr = <0x0078413c>; + qcom,spss-fuse2-bit = <31>; qcom,spss-test-firmware-name = "spss"; /* default name */ qcom,spss-prod-firmware-name = "spss1p"; /* 8 chars max */ + qcom,spss-hybr-firmware-name = "spss1h"; /* 8 chars max */ qcom,spss-debug-reg-addr = <0x01d06020>; status = "ok"; }; @@ -2195,37 +2198,42 @@ qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor15"; qcom,scaling-factor = <10>; + qcom,alias-name = "modem_dsp"; }; sensor_information16: qcom,sensor-information-16 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor16"; - qcom,alias-name = "pop_mem"; qcom,scaling-factor = <10>; }; sensor_information17: qcom,sensor-information-17 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor17"; qcom,scaling-factor = <10>; + qcom,alias-name = "hvx"; }; sensor_information18: qcom,sensor-information-18 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor18"; qcom,scaling-factor = <10>; + qcom,alias-name = "camera"; }; sensor_information19: qcom,sensor-information-19 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor19"; qcom,scaling-factor = <10>; + qcom,alias-name = "multi_media_ss"; }; sensor_information20: qcom,sensor-information-20 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor20"; qcom,scaling-factor = <10>; + qcom,alias-name = "modem"; }; sensor_information21: qcom,sensor-information-21 { qcom,sensor-type = "tsens"; qcom,sensor-name = "tsens_tz_sensor21"; qcom,scaling-factor = <10>; + qcom,alias-name = "pop_mem"; }; sensor_information22: qcom,sensor-information-22 { qcom,sensor-type = "alarm"; diff --git a/arch/arm/boot/dts/qcom/sda658.dtsi b/arch/arm/boot/dts/qcom/sda658.dtsi index 33018a177b41..035b93eacf5d 100644 --- a/arch/arm/boot/dts/qcom/sda658.dtsi +++ b/arch/arm/boot/dts/qcom/sda658.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 @@ -17,3 +17,13 @@ compatible = "qcom,sda658"; qcom,msm-id = <326 0x0>; }; + +&soc { + qcom,rmnet-ipa { + status = "disabled"; + }; +}; + +&ipa_hw { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/qcom/sda660.dtsi b/arch/arm/boot/dts/qcom/sda660.dtsi index d2919a9467dd..d394c277ecdd 100644 --- a/arch/arm/boot/dts/qcom/sda660.dtsi +++ b/arch/arm/boot/dts/qcom/sda660.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 @@ -17,3 +17,13 @@ compatible = "qcom,sda660"; qcom,msm-id = <324 0x0>; }; + +&soc { + qcom,rmnet-ipa { + status = "disabled"; + }; +}; + +&ipa_hw { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/qcom/sdm630-cdp.dtsi b/arch/arm/boot/dts/qcom/sdm630-cdp.dtsi index 6779d80d76cf..c22926510f94 100644 --- a/arch/arm/boot/dts/qcom/sdm630-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/sdm630-cdp.dtsi @@ -22,3 +22,7 @@ &soc { }; + +&pm660_charger { + qcom,batteryless-platform; +}; diff --git a/arch/arm/boot/dts/qcom/sdm630-mtp.dtsi b/arch/arm/boot/dts/qcom/sdm630-mtp.dtsi index 16d6c1bf9500..b4b22d31402e 100644 --- a/arch/arm/boot/dts/qcom/sdm630-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/sdm630-mtp.dtsi @@ -12,6 +12,11 @@ #include "sdm660-pinctrl.dtsi" / { + mtp_batterydata: qcom,battery-data { + qcom,batt-id-range-pct = <15>; + #include "fg-gen3-batterydata-itech-3000mah.dtsi" + #include "fg-gen3-batterydata-ascent-3450mah.dtsi" + }; }; &uartblsp1dm1 { @@ -26,3 +31,7 @@ &soc { }; + +&pm660_fg { + qcom,battery-data = <&mtp_batterydata>; +}; 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/sdm630.dtsi b/arch/arm/boot/dts/qcom/sdm630.dtsi index 2ebabab84f11..9186ce0118a3 100644 --- a/arch/arm/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm/boot/dts/qcom/sdm630.dtsi @@ -312,6 +312,7 @@ }; }; +#include "sdm660-blsp.dtsi" #include "sdm630-smp2p.dtsi" #include "sdm630-coresight.dtsi" &soc { @@ -343,6 +344,22 @@ clock-frequency = <19200000>; }; + dma_blsp1: qcom,sps-dma@0xc144000{ /* BLSP1 */ + #dma-cells = <4>; + compatible = "qcom,sps-dma"; + reg = <0xc144000 0x1F000>; + interrupts = <0 238 0>; + qcom,summing-threshold = <0x10>; + }; + + dma_blsp2: qcom,sps-dma@0xc184000{ /* BLSP2 */ + #dma-cells = <4>; + compatible = "qcom,sps-dma"; + reg = <0xc184000 0x1F000>; + interrupts = <0 239 0>; + qcom,summing-threshold = <0x10>; + }; + restart@10ac000 { compatible = "qcom,pshold"; reg = <0x10ac000 0x4>, @@ -659,6 +676,31 @@ clock-names = "core", "iface"; }; + slim_aud: slim@151c0000 { + cell-index = <1>; + compatible = "qcom,slim-ngd"; + reg = <0x151c0000 0x2c000>, + <0x15180000 0x2e000>; + reg-names = "slimbus_physical", "slimbus_bam_physical"; + interrupts = <0 163 0>, <0 164 0>; + interrupt-names = "slimbus_irq", "slimbus_bam_irq"; + qcom,apps-ch-pipes = <0x7e0000>; + qcom,ea-pc = <0x260>; + status = "disabled"; + }; + + slim_qca: slim@15240000 { + cell-index = <3>; + compatible = "qcom,slim-ngd"; + reg = <0x15240000 0x2c000>, + <0x15200000 0x24000>; + reg-names = "slimbus_physical", "slimbus_bam_physical"; + interrupts = <0 291 0>, <0 292 0>; + interrupt-names = "slimbus_irq", "slimbus_bam_irq"; + qcom,apps-ch-pipes = <0x1800>; + status = "disabled"; + }; + timer@17920000 { #address-cells = <1>; #size-cells = <1>; @@ -806,6 +848,72 @@ #clock-cells = <1>; }; + ipa_hw: qcom,ipa@14780000 { + compatible = "qcom,ipa"; + reg = <0x14780000 0x4effc>, <0x14784000 0x26934>; + reg-names = "ipa-base", "bam-base"; + interrupts = <0 333 0>, + <0 432 0>; + interrupt-names = "ipa-irq", "bam-irq"; + qcom,ipa-hw-ver = <6>; /* IPA core version = IPAv2.6L */ + qcom,ipa-hw-mode = <0>; /* IPA hw type = Normal */ + qcom,wan-rx-ring-size = <192>; /* IPA WAN-rx-ring-size*/ + qcom,lan-rx-ring-size = <192>; /* IPA LAN-rx-ring-size*/ + clocks = <&clock_rpmcc RPM_IPA_CLK>, + <&clock_rpmcc RPM_AGGR2_NOC_CLK>; + clock-names = "core_clk", "smmu_clk"; + qcom,arm-smmu; + qcom,smmu-disable-htw; + qcom,smmu-s1-bypass; + qcom,ee = <0>; + qcom,use-ipa-tethering-bridge; + qcom,modem-cfg-emb-pipe-flt; + qcom,msm-bus,name = "ipa"; + qcom,msm-bus,num-cases = <4>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + /* No vote */ + <90 512 0 0>, + <1 676 0 0>, + /* SVS */ + <90 512 80000 640000>, + <1 676 80000 80000>, + /* NOMINAL */ + <90 512 206000 960000>, + <1 676 206000 160000>, + /* TURBO */ + <90 512 206000 960000>, + <1 676 206000 160000>; + qcom,bus-vector-names = "MIN", "SVS", "PERF", "TURBO"; + qcom,rx-polling-sleep-ms = <2>; /* Polling sleep interval */ + qcom,ipa-polling-iteration = <5>; /* Polling Iteration */ + + ipa_smmu_ap: ipa_smmu_ap { + compatible = "qcom,ipa-smmu-ap-cb"; + iommus = <&anoc2_smmu 0x19C0>; + qcom,iova-mapping = <0x10000000 0x40000000>; + }; + + ipa_smmu_wlan: ipa_smmu_wlan { + status = "disabled"; + compatible = "qcom,ipa-smmu-wlan-cb"; + iommus = <&anoc2_smmu 0x19C1>; + }; + + ipa_smmu_uc: ipa_smmu_uc { + compatible = "qcom,ipa-smmu-uc-cb"; + iommus = <&anoc2_smmu 0x19C2>; + qcom,iova-mapping = <0x40000000 0x20000000>; + }; + }; + + qcom,rmnet-ipa { + compatible = "qcom,rmnet-ipa"; + qcom,rmnet-ipa-ssr; + qcom,ipa-loaduC; + qcom,ipa-advertise-sg-support; + }; + qcom,ipc-spinlock@1f40000 { compatible = "qcom,ipc-spinlock-sfpb"; reg = <0x1f40000 0x8000>; diff --git a/arch/arm/boot/dts/qcom/sdm660-camera.dtsi b/arch/arm/boot/dts/qcom/sdm660-camera.dtsi index 747729d158a8..150c759496bf 100644 --- a/arch/arm/boot/dts/qcom/sdm660-camera.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-camera.dtsi @@ -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 @@ -111,7 +111,7 @@ <&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>, <&clock_mmss MMSS_CAMSS_AHB_CLK>, <&clock_mmss MMSS_CAMSS_TOP_AHB_CLK>, - <&clock_mmss CSI0_CLK_SRC>, + <&clock_mmss CSI2_CLK_SRC>, <&clock_mmss MMSS_CAMSS_CSI2_CLK>, <&clock_mmss MMSS_CAMSS_CPHY_CSID2_CLK>, <&clock_mmss CSI2PHYTIMER_CLK_SRC>, diff --git a/arch/arm/boot/dts/qcom/sdm660-cdp.dts b/arch/arm/boot/dts/qcom/sdm660-cdp.dts index 8d338660a14a..0a226fad698e 100644 --- a/arch/arm/boot/dts/qcom/sdm660-cdp.dts +++ b/arch/arm/boot/dts/qcom/sdm660-cdp.dts @@ -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 @@ -23,3 +23,13 @@ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, <0x0001001b 0x0201011a 0x0 0x0>; }; + +&tavil_snd { + qcom,msm-mbhc-hphl-swh = <0>; + qcom,msm-mbhc-gnd-swh = <0>; +}; + +&tasha_snd { + qcom,msm-mbhc-hphl-swh = <0>; + qcom,msm-mbhc-gnd-swh = <0>; +}; diff --git a/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi b/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi index a3654c21f2db..84292383b1b0 100644 --- a/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-cdp.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 @@ -118,7 +118,7 @@ /* device core power supply */ vdd-supply = <&pm660l_l5>; qcom,vdd-voltage-level = <2950000 2950000>; - qcom,vdd-current-level = <15000 900000>; + qcom,vdd-current-level = <15000 800000>; /* device communication power supply */ vdd-io-supply = <&pm660l_l2>; @@ -134,8 +134,8 @@ interrupts = <0 1 2>; #interrupt-cells = <1>; interrupt-map-mask = <0xffffffff>; - interrupt-map = <0 &intc 0 125 0 - 1 &intc 0 221 0 + interrupt-map = <0 &intc 0 0 125 0 + 1 &intc 0 0 221 0 2 &tlmm 54 0>; interrupt-names = "hc_irq", "pwr_irq", "status_irq"; cd-gpios = <&tlmm 54 0x1>; @@ -152,3 +152,7 @@ compatible = "qcom,msm-ssc-sensors"; }; }; + +&pm660_charger { + qcom,batteryless-platform; +}; 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-gpu.dtsi b/arch/arm/boot/dts/qcom/sdm660-gpu.dtsi index e3a3835ae809..d347f033b12d 100644 --- a/arch/arm/boot/dts/qcom/sdm660-gpu.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-gpu.dtsi @@ -65,6 +65,7 @@ /* <HZ/12> */ qcom,idle-timeout = <80>; + qcom,no-nap; qcom,highest-bank-bit = <14>; @@ -75,11 +76,11 @@ <&clock_gcc GCC_GPU_CFG_AHB_CLK>, <&clock_gfx GPUCC_RBBMTIMER_CLK>, <&clock_gcc GCC_GPU_BIMC_GFX_CLK>, - <&clock_gcc GCC_GPU_BIMC_GFX_SRC_CLK>, + <&clock_gcc GCC_BIMC_GFX_CLK>, <&clock_gpu GPUCC_RBCPR_CLK>; clock-names = "core_clk", "iface_clk", "rbbmtimer_clk", - "mem_clk", "mem_iface_clk", "rbcpr_clk"; + "mem_clk", "alt_mem_iface_clk", "rbcpr_clk"; /* Bus Scale Settings */ qcom,gpubw-dev = <&gpubw>; @@ -248,9 +249,9 @@ clocks =<&clock_gcc GCC_GPU_CFG_AHB_CLK>, <&clock_gcc GCC_GPU_BIMC_GFX_CLK>, - <&clock_gcc GCC_GPU_BIMC_GFX_SRC_CLK>; + <&clock_gcc GCC_BIMC_GFX_CLK>; - clock-names = "iface_clk", "mem_clk", "mem_iface_clk"; + clock-names = "iface_clk", "mem_clk", "alt_mem_iface_clk"; qcom,secure_align_mask = <0xfff>; qcom,retention; diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-cdp.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-cdp.dts index 2a338d2ed07b..6272e7eefe2f 100644 --- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-cdp.dts +++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-cdp.dts @@ -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 @@ -60,6 +60,30 @@ status = "disabled"; }; +&spi_7 { + status = "disabled"; +}; + +&wdsp_mgr { + status = "disabled"; +}; + +&wdsp_glink { + status = "disabled"; +}; + +&glink_spi_xprt_wdsp { + status = "disabled"; +}; + +&glink_fifo_wdsp { + status = "disabled"; +}; + +&glink_qos_wdsp { + status = "disabled"; +}; + &int_codec { status = "okay"; }; diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-mtp.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-mtp.dts index 3518402bd0dc..beedbe5676b1 100644 --- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-mtp.dts +++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-mtp.dts @@ -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 @@ -60,6 +60,30 @@ status = "disabled"; }; +&spi_7 { + status = "disabled"; +}; + +&wdsp_mgr { + status = "disabled"; +}; + +&wdsp_glink { + status = "disabled"; +}; + +&glink_spi_xprt_wdsp { + status = "disabled"; +}; + +&glink_fifo_wdsp { + status = "disabled"; +}; + +&glink_qos_wdsp { + status = "disabled"; +}; + &int_codec { qcom,model = "sdm660-snd-card-mtp"; status = "okay"; diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-cdp.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-cdp.dts index af0467cb3278..ec318a59561c 100644 --- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-cdp.dts +++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-cdp.dts @@ -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 @@ -23,3 +23,75 @@ qcom,board-id = <1 1>; qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; }; + +&slim_aud { + status = "disabled"; +}; + +&dai_slim { + status = "disabled"; +}; + +&wcd9335 { + status = "disabled"; +}; + +&wcd934x_cdc { + status = "disabled"; +}; + +&clock_audio { + status = "disabled"; +}; + +&wcd_rst_gpio { + status = "disabled"; +}; + +&wcd9xxx_intc { + status = "disabled"; +}; + +&tasha_snd { + status = "disabled"; +}; + +&tavil_snd { + status = "disabled"; +}; + +&spi_7 { + status = "disabled"; +}; + +&wdsp_mgr { + status = "disabled"; +}; + +&wdsp_glink { + status = "disabled"; +}; + +&glink_spi_xprt_wdsp { + status = "disabled"; +}; + +&glink_fifo_wdsp { + status = "disabled"; +}; + +&glink_qos_wdsp { + status = "disabled"; +}; + +&int_codec { + status = "okay"; +}; + +&pmic_analog_codec { + status = "okay"; +}; + +&msm_sdw_codec { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-mtp.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-mtp.dts index c9e37963146c..4f4003220baf 100644 --- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-mtp.dts +++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-mtp.dts @@ -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 @@ -23,3 +23,75 @@ qcom,board-id = <8 1>; qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; }; + +&slim_aud { + status = "disabled"; +}; + +&dai_slim { + status = "disabled"; +}; + +&wcd9335 { + status = "disabled"; +}; + +&wcd934x_cdc { + status = "disabled"; +}; + +&clock_audio { + status = "disabled"; +}; + +&wcd_rst_gpio { + status = "disabled"; +}; + +&wcd9xxx_intc { + status = "disabled"; +}; + +&tasha_snd { + status = "disabled"; +}; + +&tavil_snd { + status = "disabled"; +}; + +&spi_7 { + status = "disabled"; +}; + +&wdsp_mgr { + status = "disabled"; +}; + +&wdsp_glink { + status = "disabled"; +}; + +&glink_spi_xprt_wdsp { + status = "disabled"; +}; + +&glink_fifo_wdsp { + status = "disabled"; +}; + +&glink_qos_wdsp { + status = "disabled"; +}; + +&int_codec { + status = "okay"; +}; + +&pmic_analog_codec { + status = "okay"; +}; + +&msm_sdw_codec { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-rcm.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-rcm.dts index d38f16d4f628..eda22eaa40ca 100644 --- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-rcm.dts +++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-rcm.dts @@ -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 @@ -23,3 +23,75 @@ qcom,board-id = <21 1>; qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; }; + +&slim_aud { + status = "disabled"; +}; + +&dai_slim { + status = "disabled"; +}; + +&wcd9335 { + status = "disabled"; +}; + +&wcd934x_cdc { + status = "disabled"; +}; + +&clock_audio { + status = "disabled"; +}; + +&wcd_rst_gpio { + status = "disabled"; +}; + +&wcd9xxx_intc { + status = "disabled"; +}; + +&tasha_snd { + status = "disabled"; +}; + +&tavil_snd { + status = "disabled"; +}; + +&spi_7 { + status = "disabled"; +}; + +&wdsp_mgr { + status = "disabled"; +}; + +&wdsp_glink { + status = "disabled"; +}; + +&glink_spi_xprt_wdsp { + status = "disabled"; +}; + +&glink_fifo_wdsp { + status = "disabled"; +}; + +&glink_qos_wdsp { + status = "disabled"; +}; + +&int_codec { + status = "okay"; +}; + +&pmic_analog_codec { + status = "okay"; +}; + +&msm_sdw_codec { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-rcm.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-rcm.dts index eb171c66849b..55958f3e31f6 100644 --- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-rcm.dts +++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-rcm.dts @@ -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 @@ -60,6 +60,30 @@ status = "disabled"; }; +&spi_7 { + status = "disabled"; +}; + +&wdsp_mgr { + status = "disabled"; +}; + +&wdsp_glink { + status = "disabled"; +}; + +&glink_spi_xprt_wdsp { + status = "disabled"; +}; + +&glink_fifo_wdsp { + status = "disabled"; +}; + +&glink_qos_wdsp { + status = "disabled"; +}; + &int_codec { status = "okay"; }; diff --git a/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi b/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi index fbf44f8350bd..da44cb131b65 100644 --- a/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-mtp.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 @@ -13,6 +13,11 @@ #include "sdm660-pinctrl.dtsi" #include "sdm660-camera-sensor-mtp.dtsi" / { + mtp_batterydata: qcom,battery-data { + qcom,batt-id-range-pct = <15>; + #include "fg-gen3-batterydata-itech-3000mah.dtsi" + #include "fg-gen3-batterydata-ascent-3450mah.dtsi" + }; }; &uartblsp1dm1 { @@ -118,7 +123,7 @@ /* device core power supply */ vdd-supply = <&pm660l_l5>; qcom,vdd-voltage-level = <2950000 2950000>; - qcom,vdd-current-level = <15000 900000>; + qcom,vdd-current-level = <15000 800000>; /* device communication power supply */ vdd-io-supply = <&pm660l_l2>; @@ -134,8 +139,8 @@ interrupts = <0 1 2>; #interrupt-cells = <1>; interrupt-map-mask = <0xffffffff>; - interrupt-map = <0 &intc 0 125 0 - 1 &intc 0 221 0 + interrupt-map = <0 &intc 0 0 125 0 + 1 &intc 0 0 221 0 2 &tlmm 54 0>; interrupt-names = "hc_irq", "pwr_irq", "status_irq"; cd-gpios = <&tlmm 54 0x1>; @@ -156,3 +161,7 @@ &mem_client_3_size { qcom,peripheral-size = <0x500000>; }; + +&pm660_fg { + qcom,battery-data = <&mtp_batterydata>; +}; 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-rcm.dts b/arch/arm/boot/dts/qcom/sdm660-rcm.dts index a3f9445d4164..63fa6c2d3c02 100644 --- a/arch/arm/boot/dts/qcom/sdm660-rcm.dts +++ b/arch/arm/boot/dts/qcom/sdm660-rcm.dts @@ -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 @@ -23,3 +23,13 @@ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, <0x0001001b 0x0201011a 0x0 0x0>; }; + +&tavil_snd { + qcom,msm-mbhc-hphl-swh = <0>; + qcom,msm-mbhc-gnd-swh = <0>; +}; + +&tasha_snd { + qcom,msm-mbhc-hphl-swh = <0>; + qcom,msm-mbhc-gnd-swh = <0>; +}; diff --git a/arch/arm/boot/dts/qcom/sdm660-rumi.dts b/arch/arm/boot/dts/qcom/sdm660-rumi.dts index 80202cc87322..09213e5b9c21 100644 --- a/arch/arm/boot/dts/qcom/sdm660-rumi.dts +++ b/arch/arm/boot/dts/qcom/sdm660-rumi.dts @@ -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 @@ -97,7 +97,7 @@ /* device core power supply */ vdd-supply = <&pm660l_l5>; qcom,vdd-voltage-level = <2950000 2950000>; - qcom,vdd-current-level = <15000 900000>; + qcom,vdd-current-level = <15000 800000>; /* device communication power supply */ vdd-io-supply = <&pm660l_l2>; @@ -113,8 +113,8 @@ interrupts = <0 1 2>; #interrupt-cells = <1>; interrupt-map-mask = <0xffffffff>; - interrupt-map = <0 &intc 0 125 0 - 1 &intc 0 221 0 + interrupt-map = <0 &intc 0 0 125 0 + 1 &intc 0 0 221 0 2 &tlmm 54 0>; interrupt-names = "hc_irq", "pwr_irq", "status_irq"; cd-gpios = <&tlmm 54 0x1>; diff --git a/arch/arm/boot/dts/qcom/sdm660-sim.dts b/arch/arm/boot/dts/qcom/sdm660-sim.dts index a3ee70d0bed0..33e0f9bd5507 100644 --- a/arch/arm/boot/dts/qcom/sdm660-sim.dts +++ b/arch/arm/boot/dts/qcom/sdm660-sim.dts @@ -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 @@ -81,7 +81,7 @@ /* device core power supply */ vdd-supply = <&pm660l_l5>; qcom,vdd-voltage-level = <2950000 2950000>; - qcom,vdd-current-level = <15000 900000>; + qcom,vdd-current-level = <15000 800000>; /* device communication power supply */ vdd-io-supply = <&pm660l_l2>; @@ -97,8 +97,8 @@ interrupts = <0 1 2>; #interrupt-cells = <1>; interrupt-map-mask = <0xffffffff>; - interrupt-map = <0 &intc 0 125 0 - 1 &intc 0 221 0 + interrupt-map = <0 &intc 0 0 125 0 + 1 &intc 0 0 221 0 2 &tlmm 54 0>; interrupt-names = "hc_irq", "pwr_irq", "status_irq"; cd-gpios = <&tlmm 54 0x1>; diff --git a/arch/arm/boot/dts/qcom/sdm660.dtsi b/arch/arm/boot/dts/qcom/sdm660.dtsi index 6e3cd999ac05..2657ef2eef51 100644 --- a/arch/arm/boot/dts/qcom/sdm660.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660.dtsi @@ -52,6 +52,7 @@ reg = <0x0 0x0>; enable-method = "psci"; qcom,limits-info = <&mitigation_profile0>; + qcom,lmh-dcvs = <&lmh_dcvs0>; qcom,ea = <&ea0>; efficiency = <1024>; next-level-cache = <&L2_0>; @@ -77,6 +78,7 @@ reg = <0x0 0x1>; enable-method = "psci"; qcom,limits-info = <&mitigation_profile0>; + qcom,lmh-dcvs = <&lmh_dcvs0>; qcom,ea = <&ea1>; efficiency = <1024>; next-level-cache = <&L2_0>; @@ -96,6 +98,7 @@ reg = <0x0 0x2>; enable-method = "psci"; qcom,limits-info = <&mitigation_profile0>; + qcom,lmh-dcvs = <&lmh_dcvs0>; qcom,ea = <&ea2>; efficiency = <1024>; next-level-cache = <&L2_0>; @@ -115,6 +118,7 @@ reg = <0x0 0x3>; enable-method = "psci"; qcom,limits-info = <&mitigation_profile0>; + qcom,lmh-dcvs = <&lmh_dcvs0>; qcom,ea = <&ea3>; efficiency = <1024>; next-level-cache = <&L2_0>; @@ -134,6 +138,7 @@ reg = <0x0 0x100>; enable-method = "psci"; qcom,limits-info = <&mitigation_profile1>; + qcom,lmh-dcvs = <&lmh_dcvs1>; qcom,ea = <&ea4>; efficiency = <1536>; next-level-cache = <&L2_1>; @@ -157,6 +162,7 @@ reg = <0x0 0x101>; enable-method = "psci"; qcom,limits-info = <&mitigation_profile2>; + qcom,lmh-dcvs = <&lmh_dcvs1>; qcom,ea = <&ea5>; efficiency = <1536>; next-level-cache = <&L2_1>; @@ -176,6 +182,7 @@ reg = <0x0 0x102>; enable-method = "psci"; qcom,limits-info = <&mitigation_profile3>; + qcom,lmh-dcvs = <&lmh_dcvs1>; qcom,ea = <&ea6>; efficiency = <1536>; next-level-cache = <&L2_1>; @@ -195,6 +202,7 @@ reg = <0x0 0x103>; enable-method = "psci"; qcom,limits-info = <&mitigation_profile4>; + qcom,lmh-dcvs = <&lmh_dcvs1>; qcom,ea = <&ea7>; efficiency = <1536>; next-level-cache = <&L2_1>; @@ -325,6 +333,16 @@ alignment = <0x0 0x400000>; size = <0x0 0x5c00000>; }; + + /* global autoconfigured region for contiguous allocations */ + linux,cma { + compatible = "shared-dma-pool"; + alloc-ranges = <0 0x00000000 0 0xffffffff>; + reusable; + alignment = <0 0x400000>; + size = <0 0x2000000>; + linux,cma-default; + }; }; bluetooth: bt_wcn3990 { @@ -702,6 +720,9 @@ qcom,synchronous-cluster-map = <0 4 &CPU0 &CPU1 &CPU2 &CPU3>, <1 4 &CPU4 &CPU5 &CPU6 &CPU7>; + clock-names = "osm"; + clocks = <&clock_cpu PWRCL_CLK>; + qcom,vdd-restriction-temp = <5>; qcom,vdd-restriction-temp-hysteresis = <10>; @@ -729,6 +750,21 @@ }; }; + qcom,bcl { + compatible = "qcom,bcl"; + qcom,bcl-enable; + qcom,bcl-framework-interface; + qcom,bcl-hotplug-list = <&CPU6 &CPU7>; + qcom,bcl-soc-hotplug-list = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,ibat-monitor { + qcom,low-threshold-uamp = <3400000>; + qcom,high-threshold-uamp = <4200000>; + qcom,vph-high-threshold-uv = <3500000>; + qcom,vph-low-threshold-uv = <3300000>; + qcom,soc-low-threshold = <10>; + }; + }; + qcom,lmh { compatible = "qcom,lmh_v1"; interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; @@ -787,7 +823,7 @@ cell-index = <1>; compatible = "qcom,slim-ngd"; reg = <0x151c0000 0x2c000>, - <0x15180000 0x2e000>; + <0x15184000 0x2a000>; reg-names = "slimbus_physical", "slimbus_bam_physical"; interrupts = <0 163 0>, <0 164 0>; interrupt-names = "slimbus_irq", "slimbus_bam_irq"; @@ -800,7 +836,7 @@ cell-index = <3>; compatible = "qcom,slim-ngd"; reg = <0x15240000 0x2c000>, - <0x15200000 0x24000>; + <0x15204000 0x20000>; reg-names = "slimbus_physical", "slimbus_bam_physical"; interrupts = <0 291 0>, <0 292 0>; interrupt-names = "slimbus_irq", "slimbus_bam_irq"; @@ -1095,7 +1131,6 @@ clock_cpu: qcom,clk-cpu-660@179c0000 { compatible = "qcom,clk-cpu-osm"; - status = "disabled"; reg = <0x179c0000 0x4000>, <0x17916000 0x1000>, <0x17816000 0x1000>, <0x179d1000 0x1000>, <0x00784130 0x8>; @@ -1161,7 +1196,7 @@ qcom,apm-mode-ctl = <0x179d0004 0x179d0010>; qcom,apm-ctrl-status = <0x179d000c 0x179d0018>; - qcom,apm-threshold-voltage = <832000>; + qcom,apm-threshold-voltage = <872000>; qcom,boost-fsm-en; qcom,safe-fsm-en; qcom,ps-fsm-en; @@ -1715,11 +1750,13 @@ }; qcom,icnss@18800000 { - status = "disabled"; compatible = "qcom,icnss"; reg = <0x18800000 0x800000>, - <0x10ac000 0x20>; - reg-names = "membase", "mpm_config"; + <0xa0000000 0x10000000>, + <0xb0000000 0x10000>; + reg-names = "membase", "smmu_iova_base", "smmu_iova_ipa"; + iommus = <&anoc2_smmu 0x1a00>, + <&anoc2_smmu 0x1a01>; interrupts = <0 413 0>, /* CE0 */ <0 414 0>, /* CE1 */ <0 415 0>, /* CE2 */ @@ -2246,8 +2283,6 @@ #include "msm-gdsc-660.dtsi" #include "sdm660-gpu.dtsi" #include "sdm660-pm.dtsi" -#include "msm-audio.dtsi" -#include "sdm660-audio.dtsi" &gdsc_usb30 { status = "ok"; @@ -2324,12 +2359,26 @@ status = "ok"; }; +&clock_cpu { + lmh_dcvs0: qcom,limits-dcvs@0 { + compatible = "qcom,msm-hw-limits"; + interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; + }; + + lmh_dcvs1: qcom,limits-dcvs@1 { + compatible = "qcom,msm-hw-limits"; + interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>; + }; +}; + #include "msm-arm-smmu-660.dtsi" #include "msm-arm-smmu-impl-defs-660.dtsi" #include "sdm660-common.dtsi" #include "sdm660-blsp.dtsi" #include "sdm660-camera.dtsi" #include "sdm660-vidc.dtsi" +#include "msm-audio.dtsi" +#include "sdm660-audio.dtsi" &pm660l_gpios { /* GPIO 7 for VOL_UP */ diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 8eeb297d7b6f..0efb7c66e818 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -910,7 +910,7 @@ config RANDOMIZE_BASE config RANDOMIZE_MODULE_REGION_FULL bool "Randomize the module region independently from the core kernel" - depends on RANDOMIZE_BASE + depends on RANDOMIZE_BASE && !DYNAMIC_FTRACE default y help Randomizes the location of the module region without considering the diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c index 217c639f9ef5..62152a48e65f 100644 --- a/arch/arm64/kernel/insn.c +++ b/arch/arm64/kernel/insn.c @@ -2,7 +2,7 @@ * Copyright (C) 2013 Huawei Ltd. * Author: Jiang Liu <liuj97@gmail.com> * - * Copyright (C) 2014 Zi Shen Lim <zlim.lnx@gmail.com> + * Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -364,6 +364,9 @@ u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, u32 immlo, immhi, mask; int shift; + if (insn == AARCH64_BREAK_FAULT) + return AARCH64_BREAK_FAULT; + switch (type) { case AARCH64_INSN_IMM_ADR: shift = 0; @@ -378,7 +381,7 @@ u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) { pr_err("aarch64_insn_encode_immediate: unknown immediate encoding %d\n", type); - return 0; + return AARCH64_BREAK_FAULT; } } @@ -395,9 +398,12 @@ static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type, { int shift; + if (insn == AARCH64_BREAK_FAULT) + return AARCH64_BREAK_FAULT; + if (reg < AARCH64_INSN_REG_0 || reg > AARCH64_INSN_REG_SP) { pr_err("%s: unknown register encoding %d\n", __func__, reg); - return 0; + return AARCH64_BREAK_FAULT; } switch (type) { @@ -418,7 +424,7 @@ static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type, default: pr_err("%s: unknown register type encoding %d\n", __func__, type); - return 0; + return AARCH64_BREAK_FAULT; } insn &= ~(GENMASK(4, 0) << shift); @@ -447,7 +453,7 @@ static u32 aarch64_insn_encode_ldst_size(enum aarch64_insn_size_type type, break; default: pr_err("%s: unknown size encoding %d\n", __func__, type); - return 0; + return AARCH64_BREAK_FAULT; } insn &= ~GENMASK(31, 30); @@ -461,14 +467,17 @@ static inline long branch_imm_common(unsigned long pc, unsigned long addr, { long offset; - /* - * PC: A 64-bit Program Counter holding the address of the current - * instruction. A64 instructions must be word-aligned. - */ - BUG_ON((pc & 0x3) || (addr & 0x3)); + if ((pc & 0x3) || (addr & 0x3)) { + pr_err("%s: A64 instructions must be word aligned\n", __func__); + return range; + } offset = ((long)addr - (long)pc); - BUG_ON(offset < -range || offset >= range); + + if (offset < -range || offset >= range) { + pr_err("%s: offset out of range\n", __func__); + return range; + } return offset; } @@ -485,6 +494,8 @@ u32 __kprobes aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr, * texts are within +/-128M. */ offset = branch_imm_common(pc, addr, SZ_128M); + if (offset >= SZ_128M) + return AARCH64_BREAK_FAULT; switch (type) { case AARCH64_INSN_BRANCH_LINK: @@ -494,7 +505,7 @@ u32 __kprobes aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr, insn = aarch64_insn_get_b_value(); break; default: - BUG_ON(1); + pr_err("%s: unknown branch encoding %d\n", __func__, type); return AARCH64_BREAK_FAULT; } @@ -511,6 +522,8 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr, long offset; offset = branch_imm_common(pc, addr, SZ_1M); + if (offset >= SZ_1M) + return AARCH64_BREAK_FAULT; switch (type) { case AARCH64_INSN_BRANCH_COMP_ZERO: @@ -520,7 +533,7 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr, insn = aarch64_insn_get_cbnz_value(); break; default: - BUG_ON(1); + pr_err("%s: unknown branch encoding %d\n", __func__, type); return AARCH64_BREAK_FAULT; } @@ -531,7 +544,7 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr, insn |= AARCH64_INSN_SF_BIT; break; default: - BUG_ON(1); + pr_err("%s: unknown variant encoding %d\n", __func__, variant); return AARCH64_BREAK_FAULT; } @@ -551,7 +564,10 @@ u32 aarch64_insn_gen_cond_branch_imm(unsigned long pc, unsigned long addr, insn = aarch64_insn_get_bcond_value(); - BUG_ON(cond < AARCH64_INSN_COND_EQ || cond > AARCH64_INSN_COND_AL); + if (cond < AARCH64_INSN_COND_EQ || cond > AARCH64_INSN_COND_AL) { + pr_err("%s: unknown condition encoding %d\n", __func__, cond); + return AARCH64_BREAK_FAULT; + } insn |= cond; return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn, @@ -584,7 +600,7 @@ u32 aarch64_insn_gen_branch_reg(enum aarch64_insn_register reg, insn = aarch64_insn_get_ret_value(); break; default: - BUG_ON(1); + pr_err("%s: unknown branch encoding %d\n", __func__, type); return AARCH64_BREAK_FAULT; } @@ -607,7 +623,7 @@ u32 aarch64_insn_gen_load_store_reg(enum aarch64_insn_register reg, insn = aarch64_insn_get_str_reg_value(); break; default: - BUG_ON(1); + pr_err("%s: unknown load/store encoding %d\n", __func__, type); return AARCH64_BREAK_FAULT; } @@ -646,26 +662,30 @@ u32 aarch64_insn_gen_load_store_pair(enum aarch64_insn_register reg1, insn = aarch64_insn_get_stp_post_value(); break; default: - BUG_ON(1); + pr_err("%s: unknown load/store encoding %d\n", __func__, type); return AARCH64_BREAK_FAULT; } switch (variant) { case AARCH64_INSN_VARIANT_32BIT: - /* offset must be multiples of 4 in the range [-256, 252] */ - BUG_ON(offset & 0x3); - BUG_ON(offset < -256 || offset > 252); + if ((offset & 0x3) || (offset < -256) || (offset > 252)) { + pr_err("%s: offset must be multiples of 4 in the range of [-256, 252] %d\n", + __func__, offset); + return AARCH64_BREAK_FAULT; + } shift = 2; break; case AARCH64_INSN_VARIANT_64BIT: - /* offset must be multiples of 8 in the range [-512, 504] */ - BUG_ON(offset & 0x7); - BUG_ON(offset < -512 || offset > 504); + if ((offset & 0x7) || (offset < -512) || (offset > 504)) { + pr_err("%s: offset must be multiples of 8 in the range of [-512, 504] %d\n", + __func__, offset); + return AARCH64_BREAK_FAULT; + } shift = 3; insn |= AARCH64_INSN_SF_BIT; break; default: - BUG_ON(1); + pr_err("%s: unknown variant encoding %d\n", __func__, variant); return AARCH64_BREAK_FAULT; } @@ -703,7 +723,7 @@ u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst, insn = aarch64_insn_get_subs_imm_value(); break; default: - BUG_ON(1); + pr_err("%s: unknown add/sub encoding %d\n", __func__, type); return AARCH64_BREAK_FAULT; } @@ -714,11 +734,14 @@ u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst, insn |= AARCH64_INSN_SF_BIT; break; default: - BUG_ON(1); + pr_err("%s: unknown variant encoding %d\n", __func__, variant); return AARCH64_BREAK_FAULT; } - BUG_ON(imm & ~(SZ_4K - 1)); + if (imm & ~(SZ_4K - 1)) { + pr_err("%s: invalid immediate encoding %d\n", __func__, imm); + return AARCH64_BREAK_FAULT; + } insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst); @@ -747,7 +770,7 @@ u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst, insn = aarch64_insn_get_sbfm_value(); break; default: - BUG_ON(1); + pr_err("%s: unknown bitfield encoding %d\n", __func__, type); return AARCH64_BREAK_FAULT; } @@ -760,12 +783,18 @@ u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst, mask = GENMASK(5, 0); break; default: - BUG_ON(1); + pr_err("%s: unknown variant encoding %d\n", __func__, variant); return AARCH64_BREAK_FAULT; } - BUG_ON(immr & ~mask); - BUG_ON(imms & ~mask); + if (immr & ~mask) { + pr_err("%s: invalid immr encoding %d\n", __func__, immr); + return AARCH64_BREAK_FAULT; + } + if (imms & ~mask) { + pr_err("%s: invalid imms encoding %d\n", __func__, imms); + return AARCH64_BREAK_FAULT; + } insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst); @@ -794,23 +823,33 @@ u32 aarch64_insn_gen_movewide(enum aarch64_insn_register dst, insn = aarch64_insn_get_movn_value(); break; default: - BUG_ON(1); + pr_err("%s: unknown movewide encoding %d\n", __func__, type); return AARCH64_BREAK_FAULT; } - BUG_ON(imm & ~(SZ_64K - 1)); + if (imm & ~(SZ_64K - 1)) { + pr_err("%s: invalid immediate encoding %d\n", __func__, imm); + return AARCH64_BREAK_FAULT; + } switch (variant) { case AARCH64_INSN_VARIANT_32BIT: - BUG_ON(shift != 0 && shift != 16); + if (shift != 0 && shift != 16) { + pr_err("%s: invalid shift encoding %d\n", __func__, + shift); + return AARCH64_BREAK_FAULT; + } break; case AARCH64_INSN_VARIANT_64BIT: insn |= AARCH64_INSN_SF_BIT; - BUG_ON(shift != 0 && shift != 16 && shift != 32 && - shift != 48); + if (shift != 0 && shift != 16 && shift != 32 && shift != 48) { + pr_err("%s: invalid shift encoding %d\n", __func__, + shift); + return AARCH64_BREAK_FAULT; + } break; default: - BUG_ON(1); + pr_err("%s: unknown variant encoding %d\n", __func__, variant); return AARCH64_BREAK_FAULT; } @@ -844,20 +883,28 @@ u32 aarch64_insn_gen_add_sub_shifted_reg(enum aarch64_insn_register dst, insn = aarch64_insn_get_subs_value(); break; default: - BUG_ON(1); + pr_err("%s: unknown add/sub encoding %d\n", __func__, type); return AARCH64_BREAK_FAULT; } switch (variant) { case AARCH64_INSN_VARIANT_32BIT: - BUG_ON(shift & ~(SZ_32 - 1)); + if (shift & ~(SZ_32 - 1)) { + pr_err("%s: invalid shift encoding %d\n", __func__, + shift); + return AARCH64_BREAK_FAULT; + } break; case AARCH64_INSN_VARIANT_64BIT: insn |= AARCH64_INSN_SF_BIT; - BUG_ON(shift & ~(SZ_64 - 1)); + if (shift & ~(SZ_64 - 1)) { + pr_err("%s: invalid shift encoding %d\n", __func__, + shift); + return AARCH64_BREAK_FAULT; + } break; default: - BUG_ON(1); + pr_err("%s: unknown variant encoding %d\n", __func__, variant); return AARCH64_BREAK_FAULT; } @@ -886,11 +933,15 @@ u32 aarch64_insn_gen_data1(enum aarch64_insn_register dst, insn = aarch64_insn_get_rev32_value(); break; case AARCH64_INSN_DATA1_REVERSE_64: - BUG_ON(variant != AARCH64_INSN_VARIANT_64BIT); + if (variant != AARCH64_INSN_VARIANT_64BIT) { + pr_err("%s: invalid variant for reverse64 %d\n", + __func__, variant); + return AARCH64_BREAK_FAULT; + } insn = aarch64_insn_get_rev64_value(); break; default: - BUG_ON(1); + pr_err("%s: unknown data1 encoding %d\n", __func__, type); return AARCH64_BREAK_FAULT; } @@ -901,7 +952,7 @@ u32 aarch64_insn_gen_data1(enum aarch64_insn_register dst, insn |= AARCH64_INSN_SF_BIT; break; default: - BUG_ON(1); + pr_err("%s: unknown variant encoding %d\n", __func__, variant); return AARCH64_BREAK_FAULT; } @@ -938,7 +989,7 @@ u32 aarch64_insn_gen_data2(enum aarch64_insn_register dst, insn = aarch64_insn_get_rorv_value(); break; default: - BUG_ON(1); + pr_err("%s: unknown data2 encoding %d\n", __func__, type); return AARCH64_BREAK_FAULT; } @@ -949,7 +1000,7 @@ u32 aarch64_insn_gen_data2(enum aarch64_insn_register dst, insn |= AARCH64_INSN_SF_BIT; break; default: - BUG_ON(1); + pr_err("%s: unknown variant encoding %d\n", __func__, variant); return AARCH64_BREAK_FAULT; } @@ -977,7 +1028,7 @@ u32 aarch64_insn_gen_data3(enum aarch64_insn_register dst, insn = aarch64_insn_get_msub_value(); break; default: - BUG_ON(1); + pr_err("%s: unknown data3 encoding %d\n", __func__, type); return AARCH64_BREAK_FAULT; } @@ -988,7 +1039,7 @@ u32 aarch64_insn_gen_data3(enum aarch64_insn_register dst, insn |= AARCH64_INSN_SF_BIT; break; default: - BUG_ON(1); + pr_err("%s: unknown variant encoding %d\n", __func__, variant); return AARCH64_BREAK_FAULT; } @@ -1038,20 +1089,28 @@ u32 aarch64_insn_gen_logical_shifted_reg(enum aarch64_insn_register dst, insn = aarch64_insn_get_bics_value(); break; default: - BUG_ON(1); + pr_err("%s: unknown logical encoding %d\n", __func__, type); return AARCH64_BREAK_FAULT; } switch (variant) { case AARCH64_INSN_VARIANT_32BIT: - BUG_ON(shift & ~(SZ_32 - 1)); + if (shift & ~(SZ_32 - 1)) { + pr_err("%s: invalid shift encoding %d\n", __func__, + shift); + return AARCH64_BREAK_FAULT; + } break; case AARCH64_INSN_VARIANT_64BIT: insn |= AARCH64_INSN_SF_BIT; - BUG_ON(shift & ~(SZ_64 - 1)); + if (shift & ~(SZ_64 - 1)) { + pr_err("%s: invalid shift encoding %d\n", __func__, + shift); + return AARCH64_BREAK_FAULT; + } break; default: - BUG_ON(1); + pr_err("%s: unknown variant encoding %d\n", __func__, variant); return AARCH64_BREAK_FAULT; } diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 896bd6ec90f6..82caf98491fa 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -70,6 +70,24 @@ #define FASTRPC_LINK_CONNECTED (0x3) #define FASTRPC_LINK_DISCONNECTING (0x7) +#define PERF_KEYS "count:flush:map:copy:glink:getargs:putargs:invalidate:invoke" +#define FASTRPC_STATIC_HANDLE_LISTENER (3) +#define FASTRPC_STATIC_HANDLE_MAX (20) + +#define PERF_END (void)0 + +#define PERF(enb, cnt, ff) \ + {\ + struct timespec startT = {0};\ + if (enb) {\ + getnstimeofday(&startT);\ + } \ + ff ;\ + if (enb) {\ + cnt += getnstimediff(&startT);\ + } \ + } + static int fastrpc_glink_open(int cid); static void fastrpc_glink_close(void *chan, int cid); @@ -237,6 +255,18 @@ struct fastrpc_mmap { uintptr_t attr; }; +struct fastrpc_perf { + int64_t count; + int64_t flush; + int64_t map; + int64_t copy; + int64_t link; + int64_t getargs; + int64_t putargs; + int64_t invargs; + int64_t invoke; +}; + struct fastrpc_file { struct hlist_node hn; spinlock_t hlock; @@ -246,11 +276,13 @@ struct fastrpc_file { struct fastrpc_session_ctx *sctx; struct fastrpc_session_ctx *secsctx; uint32_t mode; + uint32_t profile; int tgid; int cid; int ssrcount; int pd; struct fastrpc_apps *apps; + struct fastrpc_perf perf; }; static struct fastrpc_apps gfa; @@ -286,6 +318,17 @@ static struct fastrpc_channel_ctx gcinfo[NUM_CHANNELS] = { }, }; +static inline int64_t getnstimediff(struct timespec *start) +{ + int64_t ns; + struct timespec ts, b; + + getnstimeofday(&ts); + b = timespec_sub(ts, *start); + ns = timespec_to_ns(&b); + return ns; +} + static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache) { struct fastrpc_file *fl = buf == 0 ? 0 : buf->fl; @@ -1075,6 +1118,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) ipage++; } /* map ion buffers */ + PERF(ctx->fl->profile, ctx->fl->perf.map, for (i = 0; i < inbufs + outbufs; ++i) { struct fastrpc_mmap *map = ctx->maps[i]; uint64_t buf = ptr_to_uint64(lpra[i].buf.pv); @@ -1110,7 +1154,10 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) } rpra[i].buf.pv = buf; } + PERF_END); + /* copy non ion buffers */ + PERF(ctx->fl->profile, ctx->fl->perf.copy, rlen = copylen - metalen; for (oix = 0; oix < inbufs + outbufs; ++oix) { int i = ctx->overps[oix]->raix; @@ -1146,7 +1193,9 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) args = args + mlen; rlen -= mlen; } + PERF_END); + PERF(ctx->fl->profile, ctx->fl->perf.flush, for (oix = 0; oix < inbufs + outbufs; ++oix) { int i = ctx->overps[oix]->raix; struct fastrpc_mmap *map = ctx->maps[i]; @@ -1163,14 +1212,20 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) dmac_flush_range(uint64_to_ptr(rpra[i].buf.pv), uint64_to_ptr(rpra[i].buf.pv + rpra[i].buf.len)); } + PERF_END); + inh = inbufs + outbufs; for (i = 0; i < REMOTE_SCALARS_INHANDLES(sc); i++) { rpra[inh + i].buf.pv = ptr_to_uint64(ctx->lpra[inh + i].buf.pv); rpra[inh + i].buf.len = ctx->lpra[inh + i].buf.len; rpra[inh + i].h = ctx->lpra[inh + i].h; } - if (!ctx->fl->sctx->smmu.coherent) + + if (!ctx->fl->sctx->smmu.coherent) { + PERF(ctx->fl->profile, ctx->fl->perf.flush, dmac_flush_range((char *)rpra, (char *)rpra + ctx->used); + PERF_END); + } bail: return err; } @@ -1390,7 +1445,10 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, int cid = fl->cid; int interrupted = 0; int err = 0; + struct timespec invoket; + if (fl->profile) + getnstimeofday(&invoket); if (!kernel) { VERIFY(err, 0 == context_restore_interrupted(fl, inv, &ctx)); @@ -1409,19 +1467,30 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, goto bail; if (REMOTE_SCALARS_LENGTH(ctx->sc)) { + PERF(fl->profile, fl->perf.getargs, VERIFY(err, 0 == get_args(kernel, ctx)); + PERF_END); if (err) goto bail; } + PERF(fl->profile, fl->perf.invargs, inv_args_pre(ctx); if (mode == FASTRPC_MODE_SERIAL) inv_args(ctx); + PERF_END); + + PERF(fl->profile, fl->perf.link, VERIFY(err, 0 == fastrpc_invoke_send(ctx, kernel, invoke->handle)); + PERF_END); + if (err) goto bail; + + PERF(fl->profile, fl->perf.invargs, if (mode == FASTRPC_MODE_PARALLEL) inv_args(ctx); + PERF_END); wait: if (kernel) wait_for_completion(&ctx->work); @@ -1434,7 +1503,10 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, VERIFY(err, 0 == (err = ctx->retval)); if (err) goto bail; + + PERF(fl->profile, fl->perf.putargs, VERIFY(err, 0 == put_args(kernel, ctx, invoke->pra)); + PERF_END); if (err) goto bail; bail: @@ -1444,6 +1516,14 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, context_free(ctx); if (fl->ssrcount != fl->apps->channel[cid].ssrcount) err = ECONNRESET; + + if (fl->profile && !interrupted) { + if (invoke->handle != FASTRPC_STATIC_HANDLE_LISTENER) + fl->perf.invoke += getnstimediff(&invoket); + if (!(invoke->handle >= 0 && + invoke->handle <= FASTRPC_STATIC_HANDLE_MAX)) + fl->perf.count++; + } return err; } @@ -2086,6 +2166,8 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) fl->tgid = current->tgid; fl->apps = me; fl->cid = cid; + memset(&fl->perf, 0, sizeof(fl->perf)); + VERIFY(err, !fastrpc_session_alloc_locked(&me->channel[cid], 0, &fl->sctx)); if (err) @@ -2156,6 +2238,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, struct fastrpc_ioctl_mmap mmap; struct fastrpc_ioctl_munmap munmap; struct fastrpc_ioctl_init init; + struct fastrpc_ioctl_perf perf; } p; void *param = (char *)ioctl_param; struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data; @@ -2211,11 +2294,36 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, case FASTRPC_MODE_SERIAL: fl->mode = (uint32_t)ioctl_param; break; + case FASTRPC_MODE_PROFILE: + fl->profile = (uint32_t)ioctl_param; + break; default: err = -ENOTTY; break; } break; + case FASTRPC_IOCTL_GETPERF: + VERIFY(err, 0 == copy_from_user(&p.perf, + param, sizeof(p.perf))); + if (err) + goto bail; + p.perf.numkeys = sizeof(struct fastrpc_perf)/sizeof(int64_t); + if (p.perf.keys) { + char *keys = PERF_KEYS; + + VERIFY(err, 0 == copy_to_user((char *)p.perf.keys, + keys, strlen(keys)+1)); + if (err) + goto bail; + } + if (p.perf.data) { + VERIFY(err, 0 == copy_to_user((int64_t *)p.perf.data, + &fl->perf, sizeof(fl->perf))); + } + VERIFY(err, 0 == copy_to_user(param, &p.perf, sizeof(p.perf))); + if (err) + goto bail; + break; case FASTRPC_IOCTL_GETINFO: VERIFY(err, 0 == (err = fastrpc_get_info(fl, &info))); if (err) diff --git a/drivers/char/adsprpc_compat.c b/drivers/char/adsprpc_compat.c index 1e5649a8d4c4..a224ba7ed3e4 100644 --- a/drivers/char/adsprpc_compat.c +++ b/drivers/char/adsprpc_compat.c @@ -1,5 +1,5 @@ /* - * 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 @@ -32,6 +32,8 @@ _IOWR('R', 6, struct compat_fastrpc_ioctl_init) #define COMPAT_FASTRPC_IOCTL_INVOKE_ATTRS \ _IOWR('R', 7, struct compat_fastrpc_ioctl_invoke_attrs) +#define COMPAT_FASTRPC_IOCTL_GETPERF \ + _IOWR('R', 9, struct compat_fastrpc_ioctl_perf) struct compat_remote_buf { compat_uptr_t pv; /* buffer pointer */ @@ -83,6 +85,12 @@ struct compat_fastrpc_ioctl_init { compat_int_t memfd; /* ION fd for the mem */ }; +struct compat_fastrpc_ioctl_perf { /* kernel performance data */ + compat_uptr_t data; + compat_int_t numkeys; + compat_uptr_t keys; +}; + static int compat_get_fastrpc_ioctl_invoke( struct compat_fastrpc_ioctl_invoke_attrs __user *inv32, struct fastrpc_ioctl_invoke_attrs __user **inva, @@ -222,6 +230,21 @@ static int compat_get_fastrpc_ioctl_munmap( return err; } +static int compat_get_fastrpc_ioctl_perf( + struct compat_fastrpc_ioctl_perf __user *perf32, + struct fastrpc_ioctl_perf __user *perf) +{ + compat_uptr_t p; + int err; + + err = get_user(p, &perf32->data); + err |= put_user(p, &perf->data); + err |= get_user(p, &perf32->keys); + err |= put_user(p, &perf->keys); + + return err; +} + static int compat_get_fastrpc_ioctl_init( struct compat_fastrpc_ioctl_init __user *init32, struct fastrpc_ioctl_init __user *init) @@ -356,6 +379,30 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd, case FASTRPC_IOCTL_SETMODE: return filp->f_op->unlocked_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); + case COMPAT_FASTRPC_IOCTL_GETPERF: + { + struct compat_fastrpc_ioctl_perf __user *perf32; + struct fastrpc_ioctl_perf *perf; + compat_uint_t u; + long ret; + + perf32 = compat_ptr(arg); + VERIFY(err, NULL != (perf = compat_alloc_user_space( + sizeof(*perf)))); + if (err) + return -EFAULT; + VERIFY(err, 0 == compat_get_fastrpc_ioctl_perf(perf32, + perf)); + if (err) + return err; + ret = filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_GETPERF, + (unsigned long)perf); + if (ret) + return ret; + err = get_user(u, &perf->numkeys); + err |= put_user(u, &perf32->numkeys); + return err; + } default: return -ENOIOCTLCMD; } diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h index 4fc9396bfd3a..9b24e2da489f 100644 --- a/drivers/char/adsprpc_shared.h +++ b/drivers/char/adsprpc_shared.h @@ -25,6 +25,7 @@ #define FASTRPC_IOCTL_INVOKE_ATTRS \ _IOWR('R', 7, struct fastrpc_ioctl_invoke_attrs) #define FASTRPC_IOCTL_GETINFO _IOWR('R', 8, uint32_t) +#define FASTRPC_IOCTL_GETPERF _IOWR('R', 9, struct fastrpc_ioctl_perf) #define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp" #define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp" @@ -45,6 +46,9 @@ /* Driver should operate in serial mode with the co-processor */ #define FASTRPC_MODE_SERIAL 1 +/* Driver should operate in profile mode with the co-processor */ +#define FASTRPC_MODE_PROFILE 2 + /* INIT a new process or attach to guestos */ #define FASTRPC_INIT_ATTACH 0 #define FASTRPC_INIT_CREATE 1 @@ -159,7 +163,6 @@ struct fastrpc_ioctl_munmap { ssize_t size; /* size */ }; - struct fastrpc_ioctl_mmap { int fd; /* ion fd */ uint32_t flags; /* flags for dsp to map with */ @@ -168,6 +171,12 @@ struct fastrpc_ioctl_mmap { uintptr_t vaddrout; /* dsps virtual address */ }; +struct fastrpc_ioctl_perf { /* kernel performance data */ + uintptr_t __user data; + uint32_t numkeys; + uintptr_t __user keys; +}; + struct smq_null_invoke { uint64_t ctx; /* invoke caller context */ uint32_t handle; /* handle to invoke */ diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index c37716e8273d..40c592457ea1 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2013, 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 @@ -474,29 +474,7 @@ static int clk_rcg2_enable(struct clk_hw *hw) struct clk_rcg2 *rcg = to_clk_rcg2(hw); if (rcg->flags & FORCE_ENABLE_RCGR) { - if (!rcg->current_freq) - rcg->current_freq = cxo_f.freq; - - if (rcg->current_freq == cxo_f.freq) - rcg->curr_index = 0; - else { - f = qcom_find_freq(rcg->freq_tbl, rcg->current_freq); - rcg->curr_index = qcom_find_src_index(hw, - rcg->parent_map, f->src); - } - - ret = clk_enable_disable_prepare_unprepare(hw, rcg->curr_index, - rcg->new_index, true); - if (ret) { - pr_err("Failed to prepare_enable new and current sources\n"); - return ret; - } - clk_rcg_set_force_enable(hw); - - clk_enable_disable_prepare_unprepare(hw, rcg->curr_index, - rcg->new_index, false); - return ret; } @@ -563,8 +541,17 @@ static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate) int ret = 0; /* Current frequency */ - if (rcg->flags & FORCE_ENABLE_RCGR) + if (rcg->flags & FORCE_ENABLE_RCGR) { rcg->current_freq = clk_get_rate(hw->clk); + if (rcg->current_freq == cxo_f.freq) + rcg->curr_index = 0; + else { + f = qcom_find_freq(rcg->freq_tbl, rcg->current_freq); + rcg->curr_index = qcom_find_src_index(hw, + rcg->parent_map, f->src); + + } + } /* * Return if the RCG is currently disabled. This configuration update @@ -583,6 +570,13 @@ static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate) if (rcg->flags & FORCE_ENABLE_RCGR) { rcg->new_index = qcom_find_src_index(hw, rcg->parent_map, f->src); + ret = clk_enable_disable_prepare_unprepare(hw, rcg->curr_index, + rcg->new_index, true); + if (ret) { + pr_err("Failed to prepare_enable new & current src\n"); + return ret; + } + ret = clk_rcg2_enable(hw); if (ret) { pr_err("Failed to enable rcg\n"); @@ -594,8 +588,11 @@ static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate) if (ret) return ret; - if (rcg->flags & FORCE_ENABLE_RCGR) + if (rcg->flags & FORCE_ENABLE_RCGR) { clk_rcg2_disable(hw); + clk_enable_disable_prepare_unprepare(hw, rcg->curr_index, + rcg->new_index, false); + } return ret; } @@ -1063,7 +1060,8 @@ static int clk_dp_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long src_rate; unsigned long num, den; u32 mask = BIT(rcg->hid_width) - 1; - u32 hid_div; + u32 hid_div, cfg; + int i, num_parents = clk_hw_get_num_parents(hw); src_rate = clk_get_rate(clk_hw_get_parent(hw)->clk); if (src_rate <= 0) { @@ -1081,7 +1079,17 @@ static int clk_dp_set_rate(struct clk_hw *hw, unsigned long rate, return -EINVAL; } - regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &hid_div); + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg); + hid_div = cfg; + cfg &= CFG_SRC_SEL_MASK; + cfg >>= CFG_SRC_SEL_SHIFT; + + for (i = 0; i < num_parents; i++) + if (cfg == rcg->parent_map[i].cfg) { + f.src = rcg->parent_map[i].src; + break; + } + f.pre_div = hid_div; f.pre_div >>= CFG_SRC_DIV_SHIFT; f.pre_div &= mask; 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/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 ac9a4b2048d1..bc6fb191b3b5 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 @@ -302,7 +302,7 @@ static void msm_buf_mngr_sd_shutdown(struct msm_buf_mngr_device *dev, 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, bufs->session_id, bufs->stream_id, - bufs->vb2_v4l2_buf->vb2_buf.index); + bufs->index); if (session->session == bufs->session_id) { list_del_init(&bufs->entry); kfree(bufs); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 7aa01372412d..449514bae4f3 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -61,6 +61,7 @@ static const unsigned int tacc_mant[] = { __res & __mask; \ }) +static int mmc_switch_status(struct mmc_card *card, bool ignore_crc); /* * Given the decoded CSD structure, decode the raw CID to our CID structure. */ @@ -1064,9 +1065,11 @@ static int mmc_select_hs(struct mmc_card *card) err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, card->ext_csd.generic_cmd6_time, - true, true, true); - if (!err) + true, false, true); + if (!err) { mmc_set_timing(card->host, MMC_TIMING_MMC_HS); + err = mmc_switch_status(card, false); + } return err; } @@ -1090,10 +1093,11 @@ static int mmc_select_hs_ddr(struct mmc_card *card) ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4; - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits, - card->ext_csd.generic_cmd6_time); + card->ext_csd.generic_cmd6_time, + true, false, false); if (err) { pr_err("%s: switch to bus width %d ddr failed\n", mmc_hostname(host), 1 << bus_width); @@ -1136,19 +1140,21 @@ static int mmc_select_hs_ddr(struct mmc_card *card) if (err) err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330); - if (!err) + if (!err) { mmc_set_timing(host, MMC_TIMING_MMC_DDR52); + err = mmc_switch_status(card, false); + } return err; } /* Caller must hold re-tuning */ -static int mmc_switch_status(struct mmc_card *card) +static int mmc_switch_status(struct mmc_card *card, bool ignore_crc) { u32 status; int err; - err = mmc_send_status(card, &status); + err = __mmc_send_status(card, &status, ignore_crc); if (err) return err; @@ -1212,7 +1218,7 @@ static int mmc_select_hs400(struct mmc_card *card) mmc_set_clock(host, max_dtr); if (!send_status) { - err = mmc_switch_status(card); + err = mmc_switch_status(card, false); if (err) goto out_err; } @@ -1253,12 +1259,6 @@ static int mmc_select_hs400(struct mmc_card *card) mmc_set_timing(host, MMC_TIMING_MMC_HS400); mmc_set_bus_speed(card); - if (!send_status) { - err = mmc_switch_status(card); - if (err) - goto out_err; - } - if (card->ext_csd.strobe_support && host->ops->enhanced_strobe) { mmc_host_clk_hold(host); err = host->ops->enhanced_strobe(host); @@ -1275,6 +1275,17 @@ static int mmc_select_hs400(struct mmc_card *card) mmc_hostname(host)); } + /* + * Sending of CMD13 should be done after the host calibration + * for enhanced_strobe or HS400 mode is completed. + * Otherwise may see CMD13 timeouts or CRC errors. + */ + if (!send_status) { + err = mmc_switch_status(card, false); + if (err) + goto out_err; + } + return 0; out_err: @@ -1314,7 +1325,7 @@ int mmc_hs400_to_hs200(struct mmc_card *card) mmc_set_timing(host, MMC_TIMING_MMC_DDR52); if (!send_status) { - err = mmc_switch_status(card); + err = mmc_switch_status(card, false); if (err) goto out_err; } @@ -1329,7 +1340,7 @@ int mmc_hs400_to_hs200(struct mmc_card *card) mmc_set_timing(host, MMC_TIMING_MMC_HS); if (!send_status) { - err = mmc_switch_status(card); + err = mmc_switch_status(card, false); if (err) goto out_err; } @@ -1346,7 +1357,7 @@ int mmc_hs400_to_hs200(struct mmc_card *card) mmc_set_timing(host, MMC_TIMING_MMC_HS200); if (!send_status) { - err = mmc_switch_status(card); + err = mmc_switch_status(card, false); if (err) goto out_err; } @@ -1425,7 +1436,12 @@ static int mmc_select_hs200(struct mmc_card *card) old_timing = host->ios.timing; mmc_set_timing(host, MMC_TIMING_MMC_HS200); if (!send_status) { - err = mmc_switch_status(card); + /* + * Since after switching to hs200, crc errors might + * occur for commands send before tuning. + * So ignore crc error for cmd13. + */ + err = mmc_switch_status(card, true); /* * mmc_select_timing() assumes timing has not changed if * it is a switch error. diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 4a978898af84..de406431e5a4 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -54,7 +54,7 @@ static const u8 tuning_blk_pattern_8bit[] = { 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, }; -static inline int __mmc_send_status(struct mmc_card *card, u32 *status, +int __mmc_send_status(struct mmc_card *card, u32 *status, bool ignore_crc) { int err; diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h index 1eea7bd51367..ad1058c1adfd 100644 --- a/drivers/mmc/core/mmc_ops.h +++ b/drivers/mmc/core/mmc_ops.h @@ -32,6 +32,7 @@ int mmc_switch_status_error(struct mmc_host *host, u32 status); int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, unsigned int timeout_ms, bool use_busy_signal, bool send_status, bool ignore_crc); - +int __mmc_send_status(struct mmc_card *card, u32 *status, + bool ignore_crc); #endif diff --git a/drivers/platform/msm/seemp_core/seemp_event_encoder.c b/drivers/platform/msm/seemp_core/seemp_event_encoder.c index df56a84bc667..36901f5fbee7 100644 --- a/drivers/platform/msm/seemp_core/seemp_event_encoder.c +++ b/drivers/platform/msm/seemp_core/seemp_event_encoder.c @@ -1,5 +1,5 @@ /* - * 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 @@ -48,9 +48,15 @@ static void check_param_range(char *section_eq, bool param, void encode_seemp_params(struct seemp_logk_blk *blk) { - char *s = blk->payload.msg + 1; + struct seemp_logk_blk tmp; + char *s = 0; + char *msg_section_start = 0; + char *msg_section_eq = 0; + char *msg_s = 0; - blk->payload.msg[BLK_MAX_MSG_SZ - 1] = 0; /* zero-terminate */ + memcpy(tmp.payload.msg, blk->payload.msg, BLK_MAX_MSG_SZ); + s = tmp.payload.msg + 1; + tmp.payload.msg[BLK_MAX_MSG_SZ - 1] = 0; /* zero-terminate */ while (true) { char *section_start = s; @@ -105,8 +111,13 @@ void encode_seemp_params(struct seemp_logk_blk *blk) } } - encode_seemp_section(section_start, section_eq, s, param, - numeric, id, numeric_value); + msg_section_start = blk->payload.msg + (section_start - + tmp.payload.msg); + msg_section_eq = blk->payload.msg + (section_eq - + tmp.payload.msg); + msg_s = blk->payload.msg + (s - tmp.payload.msg); + encode_seemp_section(msg_section_start, msg_section_eq, + msg_s, param, numeric, id, numeric_value); if (*s == 0) break; diff --git a/drivers/power/qcom-charger/msm_bcl.c b/drivers/power/qcom-charger/msm_bcl.c index 6b7cefdc0250..aea3f4645897 100644 --- a/drivers/power/qcom-charger/msm_bcl.c +++ b/drivers/power/qcom-charger/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/qpnp-fg.c b/drivers/power/qcom-charger/qpnp-fg.c index 0658f0d3b1eb..e4a8ade80d4f 100644 --- a/drivers/power/qcom-charger/qpnp-fg.c +++ b/drivers/power/qcom-charger/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/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c index eec96d30d4f9..9728490736ff 100644 --- a/drivers/power/qcom-charger/smb-lib.c +++ b/drivers/power/qcom-charger/smb-lib.c @@ -2010,7 +2010,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, diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c index cd02ed5bd46a..38e822de34a7 100644 --- a/drivers/power/reset/msm-poweroff.c +++ b/drivers/power/reset/msm-poweroff.c @@ -48,7 +48,7 @@ static int restart_mode; -static void *restart_reason, *dload_type_addr; +static void *restart_reason; static bool scm_pmic_arbiter_disable_supported; static bool scm_deassert_ps_hold_supported; /* Download mode master kill-switch */ @@ -60,8 +60,6 @@ static void scm_disable_sdi(void); * There is no API from TZ to re-enable the registers. * So the SDI cannot be re-enabled when it already by-passed. */ -static int download_mode = 1; -static struct kobject dload_kobj; #ifdef CONFIG_QCOM_DLOAD_MODE #define EDL_MODE_PROP "qcom,msm-imem-emergency_download_mode" @@ -71,7 +69,9 @@ static struct kobject dload_kobj; #endif static int in_panic; -static void *dload_mode_addr; +static int download_mode = 1; +static struct kobject dload_kobj; +static void *dload_mode_addr, *dload_type_addr; static bool dload_mode_enabled; static void *emergency_dload_mode_addr; #ifdef CONFIG_RANDOMIZE_BASE @@ -268,9 +268,9 @@ static void halt_spmi_pmic_arbiter(void) static void msm_restart_prepare(const char *cmd) { -#ifdef CONFIG_QCOM_DLOAD_MODE bool need_warm_reset = false; +#ifdef CONFIG_QCOM_DLOAD_MODE /* Write download mode flags if we're panic'ing * Write download mode flags if restart_mode says so @@ -409,6 +409,7 @@ static void do_msm_poweroff(void) return; } +#ifdef CONFIG_QCOM_DLOAD_MODE static ssize_t attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { @@ -486,6 +487,7 @@ static struct attribute *reset_attrs[] = { static struct attribute_group reset_attr_group = { .attrs = reset_attrs, }; +#endif static int msm_restart_probe(struct platform_device *pdev) { @@ -599,11 +601,12 @@ skip_sysfs_create: if (scm_is_call_available(SCM_SVC_PWR, SCM_IO_DEASSERT_PS_HOLD) > 0) scm_deassert_ps_hold_supported = true; +#ifdef CONFIG_QCOM_DLOAD_MODE download_mode = scm_is_secure_device(); set_dload_mode(download_mode); if (!download_mode) scm_disable_sdi(); - +#endif return 0; err_restart_reason: diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 2138e81bb9e9..d46682bb1d84 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -8904,6 +8904,35 @@ static inline void ufshcd_add_sysfs_nodes(struct ufs_hba *hba) ufshcd_add_spm_lvl_sysfs_nodes(hba); } +static void ufshcd_shutdown_clkscaling(struct ufs_hba *hba) +{ + bool suspend = false; + unsigned long flags; + + spin_lock_irqsave(hba->host->host_lock, flags); + if (hba->clk_scaling.is_allowed) { + hba->clk_scaling.is_allowed = false; + suspend = true; + } + spin_unlock_irqrestore(hba->host->host_lock, flags); + + /** + * Scaling may be scheduled before, hence make sure it + * doesn't race with shutdown + */ + if (ufshcd_is_clkscaling_supported(hba)) { + device_remove_file(hba->dev, &hba->clk_scaling.enable_attr); + cancel_work_sync(&hba->clk_scaling.suspend_work); + cancel_work_sync(&hba->clk_scaling.resume_work); + if (suspend) + ufshcd_suspend_clkscaling(hba); + } + + /* Unregister so that devfreq_monitor can't race with shutdown */ + if (hba->devfreq) + devfreq_remove_device(hba->devfreq); +} + /** * ufshcd_shutdown - shutdown routine * @hba: per adapter instance @@ -8921,16 +8950,14 @@ int ufshcd_shutdown(struct ufs_hba *hba) pm_runtime_get_sync(hba->dev); ufshcd_hold_all(hba); + ufshcd_mark_shutdown_ongoing(hba); + ufshcd_shutdown_clkscaling(hba); /** - * (1) Set state to shutting down - * (2) Acquire the lock to stop any more requests - * (3) Suspend clock scaling - * (4) Wait for all issued requests to complete + * (1) Acquire the lock to stop any more requests + * (2) Wait for all issued requests to complete */ - ufshcd_mark_shutdown_ongoing(hba); ufshcd_get_write_lock(hba); ufshcd_scsi_block_requests(hba); - ufshcd_suspend_clkscaling(hba); ret = ufshcd_wait_for_doorbell_clr(hba, U64_MAX); if (ret) dev_err(hba->dev, "%s: waiting for DB clear: failed: %d\n", @@ -9373,10 +9400,6 @@ static void ufshcd_clk_scaling_resume_work(struct work_struct *work) clk_scaling.resume_work); unsigned long irq_flags; - /* Let's not resume scaling if shutdown is ongoing */ - if (ufshcd_is_shutdown_ongoing(hba)) - return; - spin_lock_irqsave(hba->host->host_lock, irq_flags); if (!hba->clk_scaling.is_suspended) { spin_unlock_irqrestore(hba->host->host_lock, irq_flags); diff --git a/drivers/soc/qcom/glink.c b/drivers/soc/qcom/glink.c index 65ce7d791a47..33cf48454414 100644 --- a/drivers/soc/qcom/glink.c +++ b/drivers/soc/qcom/glink.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 @@ -582,6 +582,9 @@ static bool glink_core_remote_close_common(struct channel_ctx *ctx, bool safe) } ctx->rcid = 0; + ctx->int_req_ack = false; + complete_all(&ctx->int_req_ack_complete); + complete_all(&ctx->int_req_complete); if (ctx->local_open_state != GLINK_CHANNEL_CLOSED && ctx->local_open_state != GLINK_CHANNEL_CLOSING) { if (ctx->notify_state) @@ -598,9 +601,6 @@ static bool glink_core_remote_close_common(struct channel_ctx *ctx, bool safe) "Did not send GLINK_REMOTE_DISCONNECTED", "local state is already CLOSED"); - ctx->int_req_ack = false; - complete_all(&ctx->int_req_ack_complete); - complete_all(&ctx->int_req_complete); ch_purge_intent_lists(ctx); return is_fully_closed; diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 2b097d8ab090..44d086656a12 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -51,12 +51,12 @@ #include "wlan_firmware_service_v01.h" #ifdef CONFIG_ICNSS_DEBUG -unsigned long qmi_timeout = 3000; +unsigned long qmi_timeout = 10000; module_param(qmi_timeout, ulong, 0600); #define WLFW_TIMEOUT_MS qmi_timeout #else -#define WLFW_TIMEOUT_MS 3000 +#define WLFW_TIMEOUT_MS 10000 #endif #define WLFW_SERVICE_INS_ID_V01 0 #define WLFW_CLIENT_ID 0x4b4e454c 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/service-notifier.c b/drivers/soc/qcom/service-notifier.c index 84a2aeee8cf7..e7307c46a895 100644 --- a/drivers/soc/qcom/service-notifier.c +++ b/drivers/soc/qcom/service-notifier.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 @@ -336,11 +336,13 @@ static void root_service_service_arrive(struct work_struct *work) int rc; int curr_state; + mutex_lock(&qmi_client_release_lock); /* Create a Local client port for QMI communication */ data->clnt_handle = qmi_handle_create(root_service_clnt_notify, work); if (!data->clnt_handle) { pr_err("QMI client handle alloc failed (instance-id: %d)\n", data->instance_id); + mutex_unlock(&qmi_client_release_lock); return; } @@ -353,9 +355,11 @@ static void root_service_service_arrive(struct work_struct *work) data->instance_id, rc); qmi_handle_destroy(data->clnt_handle); data->clnt_handle = NULL; + mutex_unlock(&qmi_client_release_lock); return; } data->service_connected = true; + mutex_unlock(&qmi_client_release_lock); pr_info("Connection established between QMI handle and %d service\n", data->instance_id); /* Register for indication messages about service */ diff --git a/drivers/soc/qcom/spss_utils.c b/drivers/soc/qcom/spss_utils.c index c93a9a5c8a1c..e17a1370d1f0 100644 --- a/drivers/soc/qcom/spss_utils.c +++ b/drivers/soc/qcom/spss_utils.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 @@ -18,7 +18,7 @@ * * The SP daemon needs to load different SPSS images based on: * - * 1. Test/Production key used to sign the SPSS image (read fuse). + * 1. Test/Production key used to sign the SPSS image (read fuses). * 2. SPSS HW version (selected via Device Tree). * */ @@ -43,10 +43,17 @@ /* driver name */ #define DEVICE_NAME "spss-utils" -static bool is_test_fuse_set; +enum spss_firmware_type { + SPSS_FW_TYPE_TEST = 't', + SPSS_FW_TYPE_PROD = 'p', + SPSS_FW_TYPE_HYBRID = 'h', +}; + +static enum spss_firmware_type firmware_type = SPSS_FW_TYPE_TEST; static const char *test_firmware_name; static const char *prod_firmware_name; -static const char *firmware_name; +static const char *hybr_firmware_name; +static const char *firmware_name = "NA"; static struct device *spss_dev; static u32 spss_debug_reg_addr; /* SP_SCSR_MBn_SP2CL_GPm(n,m) */ @@ -97,10 +104,19 @@ static ssize_t test_fuse_state_show(struct device *dev, return -EINVAL; } - if (is_test_fuse_set) + switch (firmware_type) { + case SPSS_FW_TYPE_TEST: ret = snprintf(buf, PAGE_SIZE, "%s", "test"); - else + break; + case SPSS_FW_TYPE_PROD: ret = snprintf(buf, PAGE_SIZE, "%s", "prod"); + break; + case SPSS_FW_TYPE_HYBRID: + ret = snprintf(buf, PAGE_SIZE, "%s", "hybrid"); + break; + default: + return -EINVAL; + } return ret; } @@ -198,11 +214,16 @@ static int spss_create_sysfs(struct device *dev) static int spss_parse_dt(struct device_node *node) { int ret; - u32 spss_fuse_addr = 0; - u32 spss_fuse_bit = 0; - u32 spss_fuse_mask = 0; - void __iomem *spss_fuse_reg = NULL; - u32 val = 0; + u32 spss_fuse1_addr = 0; + u32 spss_fuse1_bit = 0; + u32 spss_fuse1_mask = 0; + void __iomem *spss_fuse1_reg = NULL; + u32 spss_fuse2_addr = 0; + u32 spss_fuse2_bit = 0; + u32 spss_fuse2_mask = 0; + void __iomem *spss_fuse2_reg = NULL; + u32 val1 = 0; + u32 val2 = 0; ret = of_property_read_string(node, "qcom,spss-test-firmware-name", &test_firmware_name); @@ -218,40 +239,80 @@ static int spss_parse_dt(struct device_node *node) return -EFAULT; } - ret = of_property_read_u32(node, "qcom,spss-fuse-addr", - &spss_fuse_addr); + ret = of_property_read_string(node, "qcom,spss-hybr-firmware-name", + &hybr_firmware_name); + if (ret < 0) { + pr_err("can't get prod fw name.\n"); + return -EFAULT; + } + + ret = of_property_read_u32(node, "qcom,spss-fuse1-addr", + &spss_fuse1_addr); + if (ret < 0) { + pr_err("can't get fuse1 addr.\n"); + return -EFAULT; + } + + ret = of_property_read_u32(node, "qcom,spss-fuse2-addr", + &spss_fuse2_addr); if (ret < 0) { - pr_err("can't get fuse addr.\n"); + pr_err("can't get fuse2 addr.\n"); return -EFAULT; } - ret = of_property_read_u32(node, "qcom,spss-fuse-bit", - &spss_fuse_bit); + ret = of_property_read_u32(node, "qcom,spss-fuse1-bit", + &spss_fuse1_bit); if (ret < 0) { - pr_err("can't get fuse bit.\n"); + pr_err("can't get fuse1 bit.\n"); return -EFAULT; } - spss_fuse_mask = BIT(spss_fuse_bit); + ret = of_property_read_u32(node, "qcom,spss-fuse2-bit", + &spss_fuse2_bit); + if (ret < 0) { + pr_err("can't get fuse2 bit.\n"); + return -EFAULT; + } - pr_debug("spss_fuse_addr [0x%x] , spss_fuse_bit [%d] .\n", - (int) spss_fuse_addr, (int) spss_fuse_bit); - spss_fuse_reg = ioremap_nocache(spss_fuse_addr, sizeof(u32)); + spss_fuse1_mask = BIT(spss_fuse1_bit); + spss_fuse2_mask = BIT(spss_fuse2_bit); - if (!spss_fuse_reg) { - pr_err("can't map fuse addr.\n"); + pr_debug("spss fuse1 addr [0x%x] bit [%d] .\n", + (int) spss_fuse1_addr, (int) spss_fuse1_bit); + pr_debug("spss fuse2 addr [0x%x] bit [%d] .\n", + (int) spss_fuse2_addr, (int) spss_fuse2_bit); + + spss_fuse1_reg = ioremap_nocache(spss_fuse1_addr, sizeof(u32)); + spss_fuse2_reg = ioremap_nocache(spss_fuse2_addr, sizeof(u32)); + + if (!spss_fuse1_reg) { + pr_err("can't map fuse1 addr.\n"); return -EFAULT; } + if (!spss_fuse2_reg) { + pr_err("can't map fuse2 addr.\n"); + return -EFAULT; + } + + val1 = readl_relaxed(spss_fuse1_reg); + val2 = readl_relaxed(spss_fuse2_reg); - val = readl_relaxed(spss_fuse_reg); + pr_debug("spss fuse1 value [0x%08x].\n", (int) val1); + pr_debug("spss fuse2 value [0x%08x].\n", (int) val2); - pr_debug("spss fuse register value [0x%x].\n", (int) val); + pr_debug("spss fuse1 mask [0x%08x].\n", (int) spss_fuse1_mask); + pr_debug("spss fuse2 mask [0x%08x].\n", (int) spss_fuse2_mask); - if (val & spss_fuse_mask) - is_test_fuse_set = true; + if (val1 & spss_fuse1_mask) + firmware_type = SPSS_FW_TYPE_TEST; + else if (val2 & spss_fuse2_mask) + firmware_type = SPSS_FW_TYPE_PROD; + else + firmware_type = SPSS_FW_TYPE_HYBRID; - iounmap(spss_fuse_reg); + iounmap(spss_fuse1_reg); + iounmap(spss_fuse2_reg); ret = of_property_read_u32(node, "qcom,spss-debug-reg-addr", &spss_debug_reg_addr); @@ -299,10 +360,19 @@ static int spss_probe(struct platform_device *pdev) return -EFAULT; } - if (is_test_fuse_set) + switch (firmware_type) { + case SPSS_FW_TYPE_TEST: firmware_name = test_firmware_name; - else + break; + case SPSS_FW_TYPE_PROD: firmware_name = prod_firmware_name; + break; + case SPSS_FW_TYPE_HYBRID: + firmware_name = hybr_firmware_name; + break; + default: + return -EINVAL; + } ret = subsystem_set_fwname("spss", firmware_name); if (ret < 0) { @@ -339,7 +409,7 @@ static int __init spss_init(void) { int ret = 0; - pr_info("spss-utils driver Ver 1.1 18-Sep-2016.\n"); + pr_info("spss-utils driver Ver 1.2 13-Jan-2017.\n"); ret = platform_driver_register(&spss_driver); if (ret) diff --git a/drivers/soc/qcom/subsys-pil-tz.c b/drivers/soc/qcom/subsys-pil-tz.c index 769a683e3d8d..c6531de48f65 100644 --- a/drivers/soc/qcom/subsys-pil-tz.c +++ b/drivers/soc/qcom/subsys-pil-tz.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 @@ -1043,7 +1043,7 @@ static int pil_tz_driver_probe(struct platform_device *pdev) if (!d->subsys_desc.no_auth) { rc = piltz_resc_init(pdev, d); if (rc) - return -ENOENT; + return rc; rc = of_property_read_u32(pdev->dev.of_node, "qcom,pas-id", &d->pas_id); 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/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index e0af922a0329..81bda878a7ec 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -503,9 +503,9 @@ static int ion_handle_add(struct ion_client *client, struct ion_handle *handle) return 0; } -struct ion_handle *ion_alloc(struct ion_client *client, size_t len, +static struct ion_handle *__ion_alloc(struct ion_client *client, size_t len, size_t align, unsigned int heap_id_mask, - unsigned int flags) + unsigned int flags, bool grab_handle) { struct ion_handle *handle; struct ion_device *dev = client->dev; @@ -600,6 +600,8 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len, return handle; mutex_lock(&client->lock); + if (grab_handle) + ion_handle_get(handle); ret = ion_handle_add(client, handle); mutex_unlock(&client->lock); if (ret) { @@ -609,6 +611,13 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len, return handle; } + +struct ion_handle *ion_alloc(struct ion_client *client, size_t len, + size_t align, unsigned int heap_id_mask, + unsigned int flags) +{ + return __ion_alloc(client, len, align, heap_id_mask, flags, false); +} EXPORT_SYMBOL(ion_alloc); static void ion_free_nolock(struct ion_client *client, struct ion_handle *handle) @@ -1493,10 +1502,10 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct ion_handle *handle; - handle = ion_alloc(client, data.allocation.len, + handle = __ion_alloc(client, data.allocation.len, data.allocation.align, data.allocation.heap_id_mask, - data.allocation.flags); + data.allocation.flags, true); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -1573,11 +1582,15 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (dir & _IOC_READ) { if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) { - if (cleanup_handle) + if (cleanup_handle) { ion_free(client, cleanup_handle); + ion_handle_put(cleanup_handle); + } return -EFAULT; } } + if (cleanup_handle) + ion_handle_put(cleanup_handle); return ret; } diff --git a/drivers/thermal/msm_lmh_dcvs.c b/drivers/thermal/msm_lmh_dcvs.c index ac1da854ab32..7758750516f8 100644 --- a/drivers/thermal/msm_lmh_dcvs.c +++ b/drivers/thermal/msm_lmh_dcvs.c @@ -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 @@ -48,6 +48,7 @@ #define MSM_LIMITS_ALGO_MODE_ENABLE 0x454E424C #define MSM_LIMITS_HI_THRESHOLD 0x48494748 +#define MSM_LIMITS_LOW_THRESHOLD 0x4C4F5700 #define MSM_LIMITS_ARM_THRESHOLD 0x41524D00 #define MSM_LIMITS_CLUSTER_0 0x6370302D @@ -57,6 +58,7 @@ #define MSM_LIMITS_HIGH_THRESHOLD_VAL 95000 #define MSM_LIMITS_ARM_THRESHOLD_VAL 65000 +#define MSM_LIMITS_LOW_THRESHOLD_OFFSET 500 #define MSM_LIMITS_POLLING_DELAY_MS 10 #define MSM_LIMITS_CLUSTER_0_REQ 0x179C1B04 #define MSM_LIMITS_CLUSTER_1_REQ 0x179C3B04 @@ -227,7 +229,8 @@ static int lmh_activate_trip(struct thermal_zone_device *dev, int trip, enum thermal_trip_activation_mode mode) { struct msm_lmh_dcvs_hw *hw = dev->devdata; - uint32_t enable, temp, thresh; + uint32_t enable, temp; + int ret = 0; enable = (mode == THERMAL_TRIP_ACTIVATION_ENABLED) ? 1 : 0; if (!enable) { @@ -240,12 +243,35 @@ static int lmh_activate_trip(struct thermal_zone_device *dev, hw->temp_limits[LIMITS_TRIP_HI]) return -EINVAL; - thresh = (trip == LIMITS_TRIP_LO) ? MSM_LIMITS_ARM_THRESHOLD : - MSM_LIMITS_HI_THRESHOLD; temp = hw->temp_limits[trip]; + switch (trip) { + case LIMITS_TRIP_LO: + ret = msm_lmh_dcvs_write(hw->affinity, + MSM_LIMITS_SUB_FN_THERMAL, + MSM_LIMITS_ARM_THRESHOLD, temp); + break; + case LIMITS_TRIP_HI: + /* + * The high threshold should be atleast greater than the + * low threshold offset + */ + if (temp < MSM_LIMITS_LOW_THRESHOLD_OFFSET) + return -EINVAL; + ret = msm_lmh_dcvs_write(hw->affinity, + MSM_LIMITS_SUB_FN_THERMAL, + MSM_LIMITS_HI_THRESHOLD, temp); + if (ret) + break; + ret = msm_lmh_dcvs_write(hw->affinity, + MSM_LIMITS_SUB_FN_THERMAL, + MSM_LIMITS_LOW_THRESHOLD, temp - + MSM_LIMITS_LOW_THRESHOLD_OFFSET); + break; + default: + return -EINVAL; + } - return msm_lmh_dcvs_write(hw->affinity, MSM_LIMITS_SUB_FN_THERMAL, - thresh, temp); + return ret; } static int lmh_get_trip_temp(struct thermal_zone_device *dev, diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 5c451f8a6827..bc0e0184a917 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -2574,7 +2574,7 @@ static int dwc3_msm_id_notifier(struct notifier_block *nb, dbg_event(0xFF, "cc_state", mdwc->typec_orientation); speed = extcon_get_cable_state_(edev, EXTCON_USB_SPEED); - dwc->maximum_speed = (speed == 0) ? USB_SPEED_HIGH : USB_SPEED_SUPER; + dwc->maximum_speed = (speed <= 0) ? USB_SPEED_HIGH : USB_SPEED_SUPER; if (mdwc->id_state != id) { mdwc->id_state = id; @@ -2615,7 +2615,7 @@ static int dwc3_msm_vbus_notifier(struct notifier_block *nb, dbg_event(0xFF, "cc_state", mdwc->typec_orientation); speed = extcon_get_cable_state_(edev, EXTCON_USB_SPEED); - dwc->maximum_speed = (speed == 0) ? USB_SPEED_HIGH : USB_SPEED_SUPER; + dwc->maximum_speed = (speed <= 0) ? USB_SPEED_HIGH : USB_SPEED_SUPER; mdwc->vbus_active = event; if (dwc->is_drd && !mdwc->in_restart) { diff --git a/drivers/usb/phy/phy-msm-qusb.c b/drivers/usb/phy/phy-msm-qusb.c index 09a61acceb81..170cbf0a853f 100644 --- a/drivers/usb/phy/phy-msm-qusb.c +++ b/drivers/usb/phy/phy-msm-qusb.c @@ -1,5 +1,5 @@ /* - * 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 @@ -47,6 +47,8 @@ #define FREEZIO_N BIT(1) #define POWER_DOWN BIT(0) +#define QUSB2PHY_PORT_TEST_CTRL 0xB8 + #define QUSB2PHY_PWR_CTRL1 0x210 #define PWR_CTRL1_CLAMP_N_EN BIT(1) #define PWR_CTRL1_POWR_DOWN BIT(0) @@ -688,6 +690,21 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend) writel_relaxed(intr_mask, qphy->base + QUSB2PHY_PORT_INTR_CTRL); + /* enable phy auto-resume */ + writel_relaxed(0x0C, + qphy->base + QUSB2PHY_PORT_TEST_CTRL); + /* flush the previous write before next write */ + wmb(); + writel_relaxed(0x04, + qphy->base + QUSB2PHY_PORT_TEST_CTRL); + + + dev_dbg(phy->dev, "%s: intr_mask = %x\n", + __func__, intr_mask); + + /* Makes sure that above write goes through */ + wmb(); + qusb_phy_enable_clocks(qphy, false); } else { /* Disconnect case */ /* Disable all interrupts */ diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c index 6311352cb0cf..6870193166f2 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.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 @@ -2461,7 +2461,8 @@ static u32 __get_ts_count(struct mdss_mdp_pipe *pipe, if (pipe && pipe->multirect.mode == MDSS_MDP_PIPE_MULTIRECT_SERIAL) { __get_ordered_rects(pipe, &low_pipe, &high_pipe); - ts_ypos = high_pipe->dst.y - low_pipe->dst.y - 1; + ts_ypos = high_pipe->dst.y - + (low_pipe->dst.y + low_pipe->dst.h) - 1; rate_factor = TS_CLK / fps; ts_count = mult_frac(ts_ypos, rate_factor, v_total); MDSS_XLOG(ts_ypos, rate_factor, ts_count); @@ -2535,7 +2536,7 @@ static u32 __get_ts_bytes(struct mdss_mdp_pipe *pipe, /* calculate ts bytes as the sum of both rects */ ts_bytes_low = __calc_ts_bytes(&low_pipe->src, fps, low_pipe->src_fmt->bpp); - ts_bytes_high = __calc_ts_bytes(&low_pipe->src, fps, + ts_bytes_high = __calc_ts_bytes(&high_pipe->src, fps, high_pipe->src_fmt->bpp); ts_bytes = ts_bytes_low + ts_bytes_high; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 760bc4d5a2cf..2dc3abfd61be 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), @@ -5467,4 +5478,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/events/core.c b/kernel/events/core.c index 00beacd233fd..424961e5bd80 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -1489,10 +1489,17 @@ static void perf_group_detach(struct perf_event *event) * If this was a group event with sibling events then * upgrade the siblings to singleton events by adding them * to whatever list we are on. + * If this isn't on a list, make sure we still remove the sibling's + * group_entry from this sibling_list; otherwise, when that sibling + * is later deallocated, it will try to remove itself from this + * sibling_list, which may well have been deallocated already, + * resulting in a use-after-free. */ list_for_each_entry_safe(sibling, tmp, &event->sibling_list, group_entry) { if (list) list_move_tail(&sibling->group_entry, list); + else + list_del_init(&sibling->group_entry); sibling->group_leader = sibling; /* Inherit group flags from the previous leader */ diff --git a/kernel/sched/core.c b/kernel/sched/core.c index b70a76058b00..76cbd55e99ac 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -5859,7 +5859,7 @@ int sched_isolate_cpu(int cpu) struct rq *rq = cpu_rq(cpu); cpumask_t avail_cpus; int ret_code = 0; - u64 start_time; + u64 start_time = 0; if (trace_sched_isolate_enabled()) start_time = sched_clock(); @@ -5929,7 +5929,7 @@ int sched_unisolate_cpu_unlocked(int cpu) { int ret_code = 0; struct rq *rq = cpu_rq(cpu); - u64 start_time; + u64 start_time = 0; if (trace_sched_isolate_enabled()) start_time = sched_clock(); diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index e1c8ec0458b3..c52655581c4c 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -3634,15 +3634,8 @@ static inline void inc_cfs_rq_hmp_stats(struct cfs_rq *cfs_rq, static inline void dec_cfs_rq_hmp_stats(struct cfs_rq *cfs_rq, struct task_struct *p, int change_cra) { } -static inline void inc_throttled_cfs_rq_hmp_stats(struct hmp_sched_stats *stats, - struct cfs_rq *cfs_rq) -{ -} - -static inline void dec_throttled_cfs_rq_hmp_stats(struct hmp_sched_stats *stats, - struct cfs_rq *cfs_rq) -{ -} +#define dec_throttled_cfs_rq_hmp_stats(...) +#define inc_throttled_cfs_rq_hmp_stats(...) #endif /* CONFIG_SCHED_HMP */ @@ -4670,6 +4663,7 @@ static inline int cfs_rq_throttled(struct cfs_rq *cfs_rq) return cfs_bandwidth_used() && cfs_rq->throttled; } +#ifdef CONFIG_SCHED_HMP /* * Check if task is part of a hierarchy where some cfs_rq does not have any * runtime left. @@ -4696,6 +4690,7 @@ static int task_will_be_throttled(struct task_struct *p) return 0; } +#endif /* check whether cfs_rq, or any parent, is throttled */ static inline int throttled_hierarchy(struct cfs_rq *cfs_rq) @@ -4776,9 +4771,7 @@ static void throttle_cfs_rq(struct cfs_rq *cfs_rq) if (dequeue) dequeue_entity(qcfs_rq, se, DEQUEUE_SLEEP); qcfs_rq->h_nr_running -= task_delta; -#ifdef CONFIG_SCHED_HMP dec_throttled_cfs_rq_hmp_stats(&qcfs_rq->hmp_stats, cfs_rq); -#endif if (qcfs_rq->load.weight) dequeue = 0; @@ -4786,9 +4779,7 @@ static void throttle_cfs_rq(struct cfs_rq *cfs_rq) if (!se) { sub_nr_running(rq, task_delta); -#ifdef CONFIG_SCHED_HMP dec_throttled_cfs_rq_hmp_stats(&rq->hmp_stats, cfs_rq); -#endif } cfs_rq->throttled = 1; @@ -4825,7 +4816,7 @@ void unthrottle_cfs_rq(struct cfs_rq *cfs_rq) struct sched_entity *se; int enqueue = 1; long task_delta; - struct cfs_rq *tcfs_rq = cfs_rq; + struct cfs_rq *tcfs_rq __maybe_unused = cfs_rq; se = cfs_rq->tg->se[cpu_of(rq)]; @@ -4853,9 +4844,7 @@ void unthrottle_cfs_rq(struct cfs_rq *cfs_rq) if (enqueue) enqueue_entity(cfs_rq, se, ENQUEUE_WAKEUP); cfs_rq->h_nr_running += task_delta; -#ifdef CONFIG_SCHED_HMP inc_throttled_cfs_rq_hmp_stats(&cfs_rq->hmp_stats, tcfs_rq); -#endif if (cfs_rq_throttled(cfs_rq)) break; @@ -4863,9 +4852,7 @@ void unthrottle_cfs_rq(struct cfs_rq *cfs_rq) if (!se) { add_nr_running(rq, task_delta); -#ifdef CONFIG_SCHED_HMP inc_throttled_cfs_rq_hmp_stats(&rq->hmp_stats, tcfs_rq); -#endif } /* determine whether we need to wake up potentially idle cpu */ diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c index 15b8f2c80e06..443f16732414 100644 --- a/kernel/sched/hmp.c +++ b/kernel/sched/hmp.c @@ -2309,7 +2309,7 @@ static void update_cpu_busy_time(struct task_struct *p, struct rq *rq, bool new_task; struct related_thread_group *grp; int cpu = rq->cpu; - u32 old_curr_window; + u32 old_curr_window = p->ravg.curr_window; new_window = mark_start < window_start; if (new_window) { @@ -2370,8 +2370,6 @@ static void update_cpu_busy_time(struct task_struct *p, struct rq *rq, * task or exiting tasks. */ if (!is_idle_task(p) && !exiting_task(p)) { - old_curr_window = p->ravg.curr_window; - if (new_window) rollover_task_window(p, full_window); } diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index c110c4aaf2be..a9d98b7dd10e 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1055,6 +1055,12 @@ static inline void sched_ttwu_pending(void) { } #include "stats.h" #include "auto_group.h" +enum sched_boost_policy { + SCHED_BOOST_NONE, + SCHED_BOOST_ON_BIG, + SCHED_BOOST_ON_ALL, +}; + #ifdef CONFIG_SCHED_HMP #define WINDOW_STATS_RECENT 0 @@ -1139,12 +1145,6 @@ extern unsigned int update_freq_aggregate_threshold(unsigned int threshold); extern void update_avg_burst(struct task_struct *p); extern void update_avg(u64 *avg, u64 sample); -enum sched_boost_policy { - SCHED_BOOST_NONE, - SCHED_BOOST_ON_BIG, - SCHED_BOOST_ON_ALL, -}; - #define NO_BOOST 0 #define FULL_THROTTLE_BOOST 1 #define CONSERVATIVE_BOOST 2 @@ -1496,6 +1496,16 @@ struct hmp_sched_stats; struct related_thread_group; struct sched_cluster; +static inline enum sched_boost_policy sched_boost_policy(void) +{ + return SCHED_BOOST_NONE; +} + +static inline bool task_sched_boost(struct task_struct *p) +{ + return true; +} + static inline int got_boost_kick(void) { return 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..5e2adf622b1e 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; 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/security/keys/proc.c b/security/keys/proc.c index f0611a6368cd..b9f531c9e4fa 100644 --- a/security/keys/proc.c +++ b/security/keys/proc.c @@ -181,7 +181,7 @@ static int proc_keys_show(struct seq_file *m, void *v) struct timespec now; unsigned long timo; key_ref_t key_ref, skey_ref; - char xbuf[12]; + char xbuf[16]; int rc; struct keyring_search_context ctx = { diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c index 0549b235fade..51bb3387de16 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.c +++ b/sound/soc/codecs/wcd-mbhc-v2.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 @@ -1166,6 +1166,8 @@ static void wcd_correct_swch_plug(struct work_struct *work) bool micbias1 = false; int ret = 0; int rc, spl_hs_count = 0; + int cross_conn; + int try = 0; pr_debug("%s: enter\n", __func__); @@ -1183,11 +1185,6 @@ static void wcd_correct_swch_plug(struct work_struct *work) wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); - if (mbhc->current_plug == MBHC_PLUG_TYPE_GND_MIC_SWAP) { - mbhc->current_plug = MBHC_PLUG_TYPE_NONE; - goto correct_plug_type; - } - /* Enable HW FSM */ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1); /* @@ -1215,8 +1212,23 @@ static void wcd_correct_swch_plug(struct work_struct *work) plug_type = MBHC_PLUG_TYPE_INVALID; } - pr_debug("%s: Valid plug found, plug type is %d\n", + do { + cross_conn = wcd_check_cross_conn(mbhc); + try++; + } while (try < GND_MIC_SWAP_THRESHOLD); + /* + * check for cross coneection 4 times. + * conisder the result of the fourth iteration. + */ + if (cross_conn > 0) { + pr_debug("%s: cross con found, start polling\n", + __func__); + plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP; + pr_debug("%s: Plug found, plug type is %d\n", __func__, plug_type); + goto correct_plug_type; + } + if ((plug_type == MBHC_PLUG_TYPE_HEADSET || plug_type == MBHC_PLUG_TYPE_HEADPHONE) && (!wcd_swch_level_remove(mbhc))) { @@ -1234,7 +1246,8 @@ correct_plug_type: mbhc->hs_detect_work_stop); wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_NONE); - if (mbhc->micbias_enable) { + if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic && + mbhc->micbias_enable) { mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( mbhc->codec, MIC_BIAS_2, false); if (mbhc->mbhc_cb->set_micbias_value) @@ -1259,7 +1272,8 @@ correct_plug_type: mbhc->hs_detect_work_stop); wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_NONE); - if (mbhc->micbias_enable) { + if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic && + mbhc->micbias_enable) { mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic( mbhc->codec, MIC_BIAS_2, false); if (mbhc->mbhc_cb->set_micbias_value) @@ -1456,10 +1470,7 @@ exit: static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc) { struct snd_soc_codec *codec = mbhc->codec; - enum wcd_mbhc_plug_type plug_type; bool micbias1 = false; - int cross_conn; - int try = 0; pr_debug("%s: enter\n", __func__); WCD_MBHC_RSC_ASSERT_LOCKED(mbhc); @@ -1480,21 +1491,6 @@ static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc) else wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB); - do { - cross_conn = wcd_check_cross_conn(mbhc); - try++; - } while (try < GND_MIC_SWAP_THRESHOLD); - - if (cross_conn > 0) { - pr_debug("%s: cross con found, start polling\n", - __func__); - plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP; - if (!mbhc->current_plug) - mbhc->current_plug = plug_type; - pr_debug("%s: Plug found, plug type is %d\n", - __func__, plug_type); - } - /* Re-initialize button press completion object */ reinit_completion(&mbhc->btn_press_compl); wcd_schedule_hs_detect_plug(mbhc, &mbhc->correct_plug_swch); @@ -2380,6 +2376,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, int ret = 0; int hph_swh = 0; int gnd_swh = 0; + u32 hph_moist_config[3]; struct snd_soc_card *card = codec->component.card; const char *hph_switch = "qcom,msm-mbhc-hphl-swh"; const char *gnd_switch = "qcom,msm-mbhc-gnd-swh"; @@ -2400,6 +2397,21 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, goto err; } + ret = of_property_read_u32_array(card->dev->of_node, + "qcom,msm-mbhc-moist-cfg", + hph_moist_config, 3); + if (ret) { + dev_dbg(card->dev, "%s: no qcom,msm-mbhc-moist-cfg in DT\n", + __func__); + mbhc->moist_vref = V_45_MV; + mbhc->moist_iref = I_3P0_UA; + mbhc->moist_rref = R_24_KOHM; + } else { + mbhc->moist_vref = hph_moist_config[0]; + mbhc->moist_iref = hph_moist_config[1]; + mbhc->moist_rref = hph_moist_config[2]; + } + mbhc->in_swch_irq_handler = false; mbhc->current_plug = MBHC_PLUG_TYPE_NONE; mbhc->is_btn_press = false; diff --git a/sound/soc/codecs/wcd-mbhc-v2.h b/sound/soc/codecs/wcd-mbhc-v2.h index 676ec342a30a..60473ce8dab0 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.h +++ b/sound/soc/codecs/wcd-mbhc-v2.h @@ -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 @@ -393,6 +393,9 @@ struct wcd_mbhc { bool in_swch_irq_handler; bool hphl_swh; /*track HPHL switch NC / NO */ bool gnd_swh; /*track GND switch NC / NO */ + u32 moist_vref; + u32 moist_iref; + u32 moist_rref; u8 micbias1_cap_mode; /* track ext cap setting */ u8 micbias2_cap_mode; /* track ext cap setting */ bool hs_detect_work_stop; diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 89357f32d288..d533984558f0 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.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 @@ -2202,7 +2202,7 @@ static void tasha_mbhc_moisture_config(struct wcd_mbhc *mbhc) { struct snd_soc_codec *codec = mbhc->codec; - if (TASHA_MBHC_MOISTURE_VREF == V_OFF) + if (mbhc->moist_vref == V_OFF) return; /* Donot enable moisture detection if jack type is NC */ @@ -2213,8 +2213,8 @@ static void tasha_mbhc_moisture_config(struct wcd_mbhc *mbhc) } snd_soc_update_bits(codec, WCD9335_MBHC_CTL_2, - 0x0C, TASHA_MBHC_MOISTURE_VREF << 2); - tasha_mbhc_hph_l_pull_up_control(codec, TASHA_MBHC_MOISTURE_IREF); + 0x0C, mbhc->moist_vref << 2); + tasha_mbhc_hph_l_pull_up_control(codec, mbhc->moist_iref); } static const struct wcd_mbhc_cb mbhc_cb = { diff --git a/sound/soc/codecs/wcd934x/wcd934x-mbhc.c b/sound/soc/codecs/wcd934x/wcd934x-mbhc.c index 0e0c26dc72cd..f9b588e87e87 100644 --- a/sound/soc/codecs/wcd934x/wcd934x-mbhc.c +++ b/sound/soc/codecs/wcd934x/wcd934x-mbhc.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 @@ -772,7 +772,7 @@ static void tavil_mbhc_moisture_config(struct wcd_mbhc *mbhc) { struct snd_soc_codec *codec = mbhc->codec; - if (TAVIL_MBHC_MOISTURE_RREF == R_OFF) + if (mbhc->moist_rref == R_OFF) return; /* Donot enable moisture detection if jack type is NC */ @@ -783,7 +783,7 @@ static void tavil_mbhc_moisture_config(struct wcd_mbhc *mbhc) } snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_2, - 0x0C, TAVIL_MBHC_MOISTURE_RREF << 2); + 0x0C, mbhc->moist_rref << 2); } static bool tavil_hph_register_recovery(struct wcd_mbhc *mbhc) diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c index 2441cabc07a7..39e7e087b3e3 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -998,6 +998,20 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) copp_idx, rc); } } + /* Turn on qti modules */ + for (j = 1; j < mod_list[0]; j++) { + if (!msm_ds2_dap_can_enable_module( + mod_list[j]) || + mod_list[j] == + DS2_MODULE_ID) + continue; + pr_debug("%s: param enable %d\n", + __func__, mod_list[j]); + adm_param_enable(port_id, copp_idx, + mod_list[j], + MODULE_ENABLE); + } + /* Add adm api to resend calibration on port */ rc = msm_ds2_dap_send_cal_data(i); if (rc < 0) { diff --git a/sound/usb/usb_audio_qmi_svc.c b/sound/usb/usb_audio_qmi_svc.c index 039519c1d822..a495a7f6cb22 100644 --- a/sound/usb/usb_audio_qmi_svc.c +++ b/sound/usb/usb_audio_qmi_svc.c @@ -69,6 +69,7 @@ struct intf_info { size_t xfer_buf_size; phys_addr_t xfer_buf_pa; u8 *xfer_buf; + u8 intf_num; u8 pcm_card_num; u8 pcm_dev_num; u8 direction; @@ -391,10 +392,9 @@ static void uaudio_iommu_unmap(enum mem_type mtype, unsigned long va, } static int prepare_qmi_response(struct snd_usb_substream *subs, - struct qmi_uaudio_stream_resp_msg_v01 *resp, u32 xfer_buf_len, - int card_num, int pcm_dev_num) + struct qmi_uaudio_stream_req_msg_v01 *req_msg, + struct qmi_uaudio_stream_resp_msg_v01 *resp, int info_idx) { - int ret = -ENODEV; struct usb_interface *iface; struct usb_host_interface *alts; struct usb_interface_descriptor *altsd; @@ -403,10 +403,11 @@ static int prepare_qmi_response(struct snd_usb_substream *subs, struct uac_format_type_i_discrete_descriptor *fmt_v1; struct uac_format_type_i_ext_descriptor *fmt_v2; struct uac1_as_header_descriptor *as; - int protocol; + int ret = -ENODEV; + int protocol, card_num, pcm_dev_num; void *hdr_ptr; u8 *xfer_buf; - u32 len, mult, remainder; + u32 len, mult, remainder, xfer_buf_len; unsigned long va, tr_data_va = 0, tr_sync_va = 0, dcba_va = 0, xfer_buf_va = 0; phys_addr_t xhci_pa, xfer_buf_pa; @@ -418,13 +419,9 @@ static int prepare_qmi_response(struct snd_usb_substream *subs, goto err; } - if (uadev[card_num].info && - uadev[card_num].info[subs->interface].in_use) { - pr_err("%s interface# %d already in use card# %d\n", __func__, - subs->interface, card_num); - ret = -EBUSY; - goto err; - } + pcm_dev_num = (req_msg->usb_token & SND_PCM_DEV_NUM_MASK) >> 8; + card_num = (req_msg->usb_token & SND_PCM_CARD_NUM_MASK) >> 16; + xfer_buf_len = req_msg->xfer_buff_size; alts = &iface->altsetting[subs->altset_idx]; altsd = get_iface_desc(alts); @@ -655,18 +652,19 @@ skip_sync: uadev[card_num].card_num = card_num; /* cache intf specific info to use it for unmap and free xfer buf */ - uadev[card_num].info[subs->interface].data_xfer_ring_va = tr_data_va; - uadev[card_num].info[subs->interface].data_xfer_ring_size = PAGE_SIZE; - uadev[card_num].info[subs->interface].sync_xfer_ring_va = tr_sync_va; - uadev[card_num].info[subs->interface].sync_xfer_ring_size = PAGE_SIZE; - uadev[card_num].info[subs->interface].xfer_buf_va = xfer_buf_va; - uadev[card_num].info[subs->interface].xfer_buf_pa = xfer_buf_pa; - uadev[card_num].info[subs->interface].xfer_buf_size = len; - uadev[card_num].info[subs->interface].xfer_buf = xfer_buf; - uadev[card_num].info[subs->interface].pcm_card_num = card_num; - uadev[card_num].info[subs->interface].pcm_dev_num = pcm_dev_num; - uadev[card_num].info[subs->interface].direction = subs->direction; - uadev[card_num].info[subs->interface].in_use = true; + uadev[card_num].info[info_idx].data_xfer_ring_va = tr_data_va; + uadev[card_num].info[info_idx].data_xfer_ring_size = PAGE_SIZE; + uadev[card_num].info[info_idx].sync_xfer_ring_va = tr_sync_va; + uadev[card_num].info[info_idx].sync_xfer_ring_size = PAGE_SIZE; + uadev[card_num].info[info_idx].xfer_buf_va = xfer_buf_va; + uadev[card_num].info[info_idx].xfer_buf_pa = xfer_buf_pa; + uadev[card_num].info[info_idx].xfer_buf_size = len; + uadev[card_num].info[info_idx].xfer_buf = xfer_buf; + uadev[card_num].info[info_idx].pcm_card_num = card_num; + uadev[card_num].info[info_idx].pcm_dev_num = pcm_dev_num; + uadev[card_num].info[info_idx].direction = subs->direction; + uadev[card_num].info[info_idx].intf_num = subs->interface; + uadev[card_num].info[info_idx].in_use = true; set_bit(card_num, &uaudio_qdev->card_slot); @@ -723,7 +721,7 @@ static void uaudio_dev_cleanup(struct uaudio_dev *dev) continue; uaudio_dev_intf_cleanup(dev->udev, &dev->info[if_idx]); pr_debug("%s: release resources: intf# %d card# %d\n", __func__, - if_idx, dev->card_num); + dev->info[if_idx].intf_num, dev->card_num); } /* iommu_unmap dcba iova for a usb device */ @@ -867,6 +865,28 @@ static int map_pcm_format(unsigned int fmt_received) } } +static int info_idx_from_ifnum(int card_num, int intf_num, bool enable) +{ + int i; + + /* + * default index 0 is used when info is allocated upon + * first enable audio stream req for a pcm device + */ + if (enable && !uadev[card_num].info) + return 0; + + for (i = 0; i < uadev[card_num].num_intf; i++) { + if (enable && !uadev[card_num].info[i].in_use) + return i; + else if (!enable && + uadev[card_num].info[i].intf_num == intf_num) + return i; + } + + return -EINVAL; +} + static int handle_uaudio_stream_req(void *req_h, void *req) { struct qmi_uaudio_stream_req_msg_v01 *req_msg; @@ -877,7 +897,7 @@ static int handle_uaudio_stream_req(void *req_h, void *req) struct intf_info *info; int pcm_format; u8 pcm_card_num, pcm_dev_num, direction; - int intf_num = -1, ret = 0; + int info_idx = -EINVAL, ret = 0; req_msg = (struct qmi_uaudio_stream_req_msg_v01 *)req; @@ -921,7 +941,8 @@ static int handle_uaudio_stream_req(void *req_h, void *req) } mutex_lock(&chip->dev_lock); - intf_num = subs->interface; + info_idx = info_idx_from_ifnum(pcm_card_num, subs->interface, + req_msg->enable); if (atomic_read(&chip->shutdown) || !subs->stream || !subs->stream->pcm || !subs->stream->chip) { ret = -ENODEV; @@ -929,6 +950,16 @@ static int handle_uaudio_stream_req(void *req_h, void *req) goto response; } + if (req_msg->enable) { + if (info_idx < 0) { + pr_err("%s interface# %d already in use card# %d\n", + __func__, subs->interface, pcm_card_num); + ret = -EBUSY; + mutex_unlock(&chip->dev_lock); + goto response; + } + } + subs->pcm_format = pcm_format; subs->channels = req_msg->number_of_ch; subs->cur_rate = req_msg->bit_rate; @@ -937,19 +968,18 @@ static int handle_uaudio_stream_req(void *req_h, void *req) ret = snd_usb_enable_audio_stream(subs, req_msg->enable); if (!ret && req_msg->enable) - ret = prepare_qmi_response(subs, &resp, req_msg->xfer_buff_size, - pcm_card_num, pcm_dev_num); + ret = prepare_qmi_response(subs, req_msg, &resp, info_idx); mutex_unlock(&chip->dev_lock); response: if (!req_msg->enable && ret != -EINVAL) { - if (intf_num >= 0) { + if (info_idx >= 0) { mutex_lock(&chip->dev_lock); - info = &uadev[pcm_card_num].info[intf_num]; + info = &uadev[pcm_card_num].info[info_idx]; uaudio_dev_intf_cleanup(uadev[pcm_card_num].udev, info); pr_debug("%s:release resources: intf# %d card# %d\n", - __func__, intf_num, pcm_card_num); + __func__, subs->interface, pcm_card_num); mutex_unlock(&chip->dev_lock); } if (atomic_read(&uadev[pcm_card_num].in_use)) |
