diff options
124 files changed, 1661 insertions, 432 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt index 4fadd0ccbcf7..02bf809740c3 100644 --- a/Documentation/devicetree/bindings/arm/msm/msm.txt +++ b/Documentation/devicetree/bindings/arm/msm/msm.txt @@ -289,6 +289,7 @@ compatible = "qcom,sdm630-mtp" compatible = "qcom,sdm630-cdp" compatible = "qcom,sda630-mtp" compatible = "qcom,sda630-cdp" +compatible = "qcom,sdm630-qrd" compatible = "qcom,msm8952-rumi" compatible = "qcom,msm8952-sim" compatible = "qcom,msm8952-qrd" diff --git a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-fg-gen3.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt index 35d8d0d7d50b..221657780178 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-fg-gen3.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt @@ -118,7 +118,6 @@ First Level Node - FG Gen3 device Definition: Specifies the source of sense resistor. Allowed values are: 0 - Rsense is from Battery FET - 1 - Rsense is external 2 - Rsense is Battery FET and SMB Option 2 can be used only when a parallel charger is present. If this property is not specified, then the diff --git a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-fg.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg.txt index f6a7a1ba3005..f6a7a1ba3005 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-fg.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg.txt diff --git a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-qnovo.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qnovo.txt index 96b7dd517231..96b7dd517231 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-qnovo.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-qnovo.txt diff --git a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smb2.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt index eabdc6a75fbe..eabdc6a75fbe 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smb2.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb2.txt diff --git a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smbcharger.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smbcharger.txt index efd64cd90878..efd64cd90878 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-smbcharger.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smbcharger.txt diff --git a/Documentation/devicetree/bindings/power/qcom-charger/smb1351-charger.txt b/Documentation/devicetree/bindings/power/supply/qcom/smb1351-charger.txt index ab0ac32e444e..ab0ac32e444e 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/smb1351-charger.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/smb1351-charger.txt diff --git a/Documentation/devicetree/bindings/power/qcom-charger/smb135x-charger.txt b/Documentation/devicetree/bindings/power/supply/qcom/smb135x-charger.txt index 3eff91a1d112..3eff91a1d112 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/smb135x-charger.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/smb135x-charger.txt diff --git a/Documentation/devicetree/bindings/power/qcom-charger/smb138x-charger.txt b/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt index 0244f910017a..0244f910017a 100644 --- a/Documentation/devicetree/bindings/power/qcom-charger/smb138x-charger.txt +++ b/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile index 65c42b8de30c..83fee34e5265 100644 --- a/arch/arm/boot/dts/qcom/Makefile +++ b/arch/arm/boot/dts/qcom/Makefile @@ -192,6 +192,7 @@ dtb-$(CONFIG_ARCH_SDM630) += sdm630-rumi.dtb \ sdm630-pm660a-cdp.dtb \ sdm630-pm660a-mtp.dtb \ sdm630-pm660a-rcm.dtb \ + sdm630-pm660a-qrd.dtb \ sdm630-internal-codec-pm660a-cdp.dtb \ sdm630-internal-codec-pm660a-mtp.dtb \ sdm630-internal-codec-pm660a-rcm.dtb \ diff --git a/arch/arm/boot/dts/qcom/msm-pm660l-rpm-regulator.dtsi b/arch/arm/boot/dts/qcom/msm-pm660l-rpm-regulator.dtsi index 83235317fa02..57b62489e502 100644 --- a/arch/arm/boot/dts/qcom/msm-pm660l-rpm-regulator.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pm660l-rpm-regulator.dtsi @@ -43,8 +43,8 @@ rpm-regulator-smpb3 { compatible = "qcom,rpm-smd-regulator-resource"; - qcom,resource-name = "smpb"; - qcom,resource-id = <3>; + qcom,resource-name = "rwcx"; + qcom,resource-id = <0>; qcom,regulator-type = <1>; status = "disabled"; @@ -58,8 +58,8 @@ rpm-regulator-smpb5 { compatible = "qcom,rpm-smd-regulator-resource"; - qcom,resource-name = "smpb"; - qcom,resource-id = <5>; + qcom,resource-name = "rwmx"; + qcom,resource-id = <0>; qcom,regulator-type = <1>; status = "disabled"; diff --git a/arch/arm/boot/dts/qcom/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-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.dtsi b/arch/arm/boot/dts/qcom/msm8998.dtsi index cb3d1fee1f48..cfdbf98af76e 100644 --- a/arch/arm/boot/dts/qcom/msm8998.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998.dtsi @@ -286,34 +286,40 @@ reg = <0 0x85800000 0 0x3700000>; }; - pil_slpi_mem: pil_slpi_region@93800000 { + pil_ipa_gpu_mem: pil_ipa_gpu_region@95000000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x93800000 0 0xf00000>; + reg = <0 0x95000000 0 0x100000>; }; - pil_video_mem: pil_video_region@93300000 { + pil_slpi_mem: pil_slpi_region@94100000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x93300000 0 0x500000>; + reg = <0 0x94100000 0 0xf00000>; }; - pil_adsp_mem: pil_adsp_region@91900000 { + pil_video_mem: pil_video_region@93c00000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x91900000 0 0x1a00000>; + reg = <0 0x93c00000 0 0x500000>; }; - modem_mem: modem_region@8ac00000 { + modem_mem: modem_region@8cc00000 { compatible = "removed-dma-pool"; no-map; - reg = <0 0x8ac00000 0 0x6d00000>; + reg = <0 0x8cc00000 0 0x7000000>; + }; + + pil_adsp_mem: pil_adsp_region@0x8b200000 { + compatible = "removed-dma-pool"; + no-map; + reg = <0 0x8b200000 0 0x1a00000>; }; spss_mem: spss_region@8ab00000 { /* for SPSS-PIL */ compatible = "removed-dma-pool"; no-map; - reg = <0 0x8ab00000 0 0x100000>; + reg = <0 0x8ab00000 0 0x700000>; }; adsp_mem: adsp_region { diff --git a/arch/arm/boot/dts/qcom/sda630.dtsi b/arch/arm/boot/dts/qcom/sda630.dtsi index 87af4de959af..c0ac1a4e814e 100644 --- a/arch/arm/boot/dts/qcom/sda630.dtsi +++ b/arch/arm/boot/dts/qcom/sda630.dtsi @@ -17,3 +17,13 @@ compatible = "qcom,sda630"; qcom,msm-id = <327 0x0>; }; + +&soc { + qcom,rmnet-ipa { + status = "disabled"; + }; +}; + +&ipa_hw { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/qcom/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 f3870680dcb0..9186ce0118a3 100644 --- a/arch/arm/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm/boot/dts/qcom/sdm630.dtsi @@ -848,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.dtsi b/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi index 9a7a80f24145..84292383b1b0 100644 --- a/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi @@ -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-mtp.dtsi b/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi index 42c12612e66d..da44cb131b65 100644 --- a/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi @@ -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 { @@ -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.dtsi b/arch/arm/boot/dts/qcom/sdm660.dtsi index 3c643f030999..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>; @@ -1714,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 */ @@ -2321,6 +2359,18 @@ 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" diff --git a/arch/arm/configs/msmcortex_defconfig b/arch/arm/configs/msmcortex_defconfig index 1831f2c63ca5..fec429d7bd0c 100644 --- a/arch/arm/configs/msmcortex_defconfig +++ b/arch/arm/configs/msmcortex_defconfig @@ -292,15 +292,15 @@ CONFIG_PINCTRL_MSM8998=y CONFIG_PINCTRL_SDM660=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_QPNP_PIN=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y -CONFIG_QPNP_SMBCHARGER=y -CONFIG_SMB135X_CHARGER=y -CONFIG_SMB1351_USB_CHARGER=y +CONFIG_POWER_SUPPLY=y +CONFIG_QPNP_FG_GEN3=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y CONFIG_QPNP_SMB2=y CONFIG_SMB138X_CHARGER=y +CONFIG_QPNP_QNOVO=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_THERMAL=y CONFIG_MFD_SPMI_PMIC=y @@ -477,6 +477,7 @@ CONFIG_QCOM_DEVFREQ_DEVBW=y CONFIG_EXTCON=y CONFIG_IIO=y CONFIG_QCOM_RRADC=y +CONFIG_QCOM_TADC=y CONFIG_PWM=y CONFIG_PWM_QPNP=y CONFIG_ARM_GIC_V3_ACL=y diff --git a/arch/arm/configs/sdm660-perf_defconfig b/arch/arm/configs/sdm660-perf_defconfig index d555a1b179d8..cd09f085e6af 100644 --- a/arch/arm/configs/sdm660-perf_defconfig +++ b/arch/arm/configs/sdm660-perf_defconfig @@ -318,20 +318,19 @@ CONFIG_SPMI=y CONFIG_PINCTRL_SDM660=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_QPNP_PIN=y +CONFIG_POWER_SUPPLY=y CONFIG_POWER_RESET=y CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y CONFIG_POWER_RESET_SYSCON=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y -CONFIG_QPNP_SMBCHARGER=y -CONFIG_SMB135X_CHARGER=y CONFIG_SMB1351_USB_CHARGER=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y CONFIG_BATTERY_BCL=y CONFIG_QPNP_SMB2=y CONFIG_SMB138X_CHARGER=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_THERMAL=y CONFIG_CPU_THERMAL=y diff --git a/arch/arm/configs/sdm660_defconfig b/arch/arm/configs/sdm660_defconfig index 2c94274b0637..8055774d9cdb 100644 --- a/arch/arm/configs/sdm660_defconfig +++ b/arch/arm/configs/sdm660_defconfig @@ -316,20 +316,19 @@ CONFIG_SPMI=y CONFIG_PINCTRL_SDM660=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_QPNP_PIN=y +CONFIG_POWER_SUPPLY=y CONFIG_POWER_RESET=y CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y CONFIG_POWER_RESET_SYSCON=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y -CONFIG_QPNP_SMBCHARGER=y -CONFIG_SMB135X_CHARGER=y CONFIG_SMB1351_USB_CHARGER=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y CONFIG_BATTERY_BCL=y CONFIG_QPNP_SMB2=y CONFIG_SMB138X_CHARGER=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_THERMAL=y CONFIG_CPU_THERMAL=y diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 8eeb297d7b6f..8ac5ba251136 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -806,7 +806,6 @@ menu "ARMv8.1 architectural features" config ARM64_HW_AFDBM bool "Support for hardware updates of the Access and Dirty page flags" - default y help The ARMv8.1 architecture extensions introduce support for hardware updates of the access and dirty information in page @@ -823,7 +822,6 @@ config ARM64_HW_AFDBM config ARM64_PAN bool "Enable support for Privileged Access Never (PAN)" - default y help Privileged Access Never (PAN; part of the ARMv8.1 Extensions) prevents the kernel or hypervisor from accessing user-space (EL0) @@ -851,7 +849,6 @@ endmenu config ARM64_UAO bool "Enable support for User Access Override (UAO)" - default y help User Access Override (UAO; part of the ARMv8.2 Extensions) causes the 'unprivileged' variant of the load/store instructions to @@ -910,7 +907,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/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig index 07e413e31234..56bbe8054264 100644 --- a/arch/arm64/configs/msm-perf_defconfig +++ b/arch/arm64/configs/msm-perf_defconfig @@ -326,15 +326,15 @@ CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y -CONFIG_MSM_PM=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y CONFIG_QPNP_SMBCHARGER=y CONFIG_QPNP_FG=y CONFIG_SMB135X_CHARGER=y CONFIG_SMB1351_USB_CHARGER=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_EPM_ADC=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_LIMITS_MONITOR=y diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index 76d949319dfa..c39a9311e056 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -313,15 +313,15 @@ CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y -CONFIG_MSM_PM=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y CONFIG_QPNP_SMBCHARGER=y CONFIG_QPNP_FG=y CONFIG_SMB135X_CHARGER=y CONFIG_SMB1351_USB_CHARGER=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_EPM_ADC=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_LIMITS_MONITOR=y diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig index 9700145bfdf6..d71cfed7614d 100644 --- a/arch/arm64/configs/msmcortex-perf_defconfig +++ b/arch/arm64/configs/msmcortex-perf_defconfig @@ -316,9 +316,6 @@ CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y -CONFIG_MSM_PM=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y CONFIG_QPNP_FG_GEN3=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y @@ -326,6 +323,9 @@ CONFIG_BATTERY_BCL=y CONFIG_QPNP_SMB2=y CONFIG_SMB138X_CHARGER=y CONFIG_QPNP_QNOVO=y +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_CPU_THERMAL=y CONFIG_LIMITS_MONITOR=y diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig index 7761c2360675..cbff6b3a5b74 100644 --- a/arch/arm64/configs/msmcortex_defconfig +++ b/arch/arm64/configs/msmcortex_defconfig @@ -318,9 +318,6 @@ CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y -CONFIG_MSM_PM=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y CONFIG_QPNP_FG_GEN3=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y @@ -328,6 +325,9 @@ CONFIG_BATTERY_BCL=y CONFIG_QPNP_SMB2=y CONFIG_SMB138X_CHARGER=y CONFIG_QPNP_QNOVO=y +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_CPU_THERMAL=y CONFIG_LIMITS_MONITOR=y diff --git a/arch/arm64/configs/sdm660-perf_defconfig b/arch/arm64/configs/sdm660-perf_defconfig index 7d203e49d595..6a8b4aca2119 100644 --- a/arch/arm64/configs/sdm660-perf_defconfig +++ b/arch/arm64/configs/sdm660-perf_defconfig @@ -318,12 +318,7 @@ CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y -CONFIG_MSM_PM=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y -CONFIG_QPNP_SMBCHARGER=y CONFIG_QPNP_FG_GEN3=y -CONFIG_SMB135X_CHARGER=y CONFIG_SMB1351_USB_CHARGER=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y @@ -331,6 +326,9 @@ CONFIG_BATTERY_BCL=y CONFIG_QPNP_SMB2=y CONFIG_SMB138X_CHARGER=y CONFIG_QPNP_QNOVO=y +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_CPU_THERMAL=y CONFIG_LIMITS_MONITOR=y diff --git a/arch/arm64/configs/sdm660_defconfig b/arch/arm64/configs/sdm660_defconfig index c295ba7e0d70..1b3c96a28475 100644 --- a/arch/arm64/configs/sdm660_defconfig +++ b/arch/arm64/configs/sdm660_defconfig @@ -320,12 +320,7 @@ CONFIG_POWER_RESET_QCOM=y CONFIG_QCOM_DLOAD_MODE=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y -CONFIG_MSM_PM=y -CONFIG_APSS_CORE_EA=y -CONFIG_MSM_APM=y -CONFIG_QPNP_SMBCHARGER=y CONFIG_QPNP_FG_GEN3=y -CONFIG_SMB135X_CHARGER=y CONFIG_SMB1351_USB_CHARGER=y CONFIG_MSM_BCL_CTL=y CONFIG_MSM_BCL_PERIPHERAL_CTL=y @@ -333,6 +328,9 @@ CONFIG_BATTERY_BCL=y CONFIG_QPNP_SMB2=y CONFIG_SMB138X_CHARGER=y CONFIG_QPNP_QNOVO=y +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y CONFIG_CPU_THERMAL=y CONFIG_LIMITS_MONITOR=y 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/char/diag/diagfwd_socket.c b/drivers/char/diag/diagfwd_socket.c index 1b19e014af63..888949816dfe 100644 --- a/drivers/char/diag/diagfwd_socket.c +++ b/drivers/char/diag/diagfwd_socket.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -43,8 +43,8 @@ #define LPASS_INST_BASE 64 #define WCNSS_INST_BASE 128 #define SENSORS_INST_BASE 192 -#define WDSP_INST_BASE 256 -#define CDSP_INST_BASE 320 +#define CDSP_INST_BASE 256 +#define WDSP_INST_BASE 320 #define INST_ID_CNTL 0 #define INST_ID_CMD 1 diff --git a/drivers/gpu/msm/adreno-gpulist.h b/drivers/gpu/msm/adreno-gpulist.h index 2418ee003c22..f1439381d781 100644 --- a/drivers/gpu/msm/adreno-gpulist.h +++ b/drivers/gpu/msm/adreno-gpulist.h @@ -289,8 +289,8 @@ static const struct adreno_gpu_core adreno_gpulist[] = { .major = 1, .minor = 2, .patchid = ANY_ID, - .features = ADRENO_64BIT | ADRENO_CONTENT_PROTECTION | - ADRENO_CPZ_RETENTION, + .features = ADRENO_PREEMPTION | ADRENO_64BIT | + ADRENO_CONTENT_PROTECTION | ADRENO_CPZ_RETENTION, .pm4fw_name = "a530_pm4.fw", .pfpfw_name = "a530_pfp.fw", .zap_name = "a512_zap", diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c index 90b833888d9d..0aab38ccc703 100644 --- a/drivers/gpu/msm/adreno_a5xx.c +++ b/drivers/gpu/msm/adreno_a5xx.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -197,7 +197,8 @@ static void a5xx_platform_setup(struct adreno_device *adreno_dev) /* A510 has 3 XIN ports in VBIF */ gpudev->vbif_xin_halt_ctrl0_mask = A510_VBIF_XIN_HALT_CTRL0_MASK; - } else if (adreno_is_a540(adreno_dev)) { + } else if (adreno_is_a540(adreno_dev) || + adreno_is_a512(adreno_dev)) { gpudev->snapshot_data->sect_sizes->cp_merciu = 1024; } @@ -485,7 +486,7 @@ static int a5xx_regulator_enable(struct adreno_device *adreno_dev) kgsl_regwrite(device, A5XX_RBBM_CLOCK_CNTL, 0x00000055); a5xx_hwcg_set(adreno_dev, true); /* Turn on sp_input_clk at HM level */ - kgsl_regrmw(device, A5XX_RBBM_CLOCK_CNTL, 3, 0); + kgsl_regrmw(device, A5XX_RBBM_CLOCK_CNTL, 0xFF, 0); return 0; } @@ -535,6 +536,9 @@ static void a5xx_regulator_disable(struct adreno_device *adreno_dev) unsigned int reg; struct kgsl_device *device = KGSL_DEVICE(adreno_dev); + if (adreno_is_a512(adreno_dev)) + return; + /* If feature is not supported or not enabled */ if (!ADRENO_FEATURE(adreno_dev, ADRENO_SPTP_PC) || !test_bit(ADRENO_SPTP_PC_CTRL, &adreno_dev->pwrctrl_flag)) { @@ -1120,6 +1124,65 @@ static const struct kgsl_hwcg_reg a540_hwcg_regs[] = { {A5XX_RBBM_CLOCK_HYST_GPMU, 0x00000004} }; +static const struct kgsl_hwcg_reg a512_hwcg_regs[] = { + {A5XX_RBBM_CLOCK_CNTL_SP0, 0x02222222}, + {A5XX_RBBM_CLOCK_CNTL_SP1, 0x02222222}, + {A5XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220}, + {A5XX_RBBM_CLOCK_CNTL2_SP1, 0x02222220}, + {A5XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF}, + {A5XX_RBBM_CLOCK_HYST_SP1, 0x0000F3CF}, + {A5XX_RBBM_CLOCK_DELAY_SP0, 0x00000080}, + {A5XX_RBBM_CLOCK_DELAY_SP1, 0x00000080}, + {A5XX_RBBM_CLOCK_CNTL_TP0, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL_TP1, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL3_TP0, 0x00002222}, + {A5XX_RBBM_CLOCK_CNTL3_TP1, 0x00002222}, + {A5XX_RBBM_CLOCK_HYST_TP0, 0x77777777}, + {A5XX_RBBM_CLOCK_HYST_TP1, 0x77777777}, + {A5XX_RBBM_CLOCK_HYST2_TP0, 0x77777777}, + {A5XX_RBBM_CLOCK_HYST2_TP1, 0x77777777}, + {A5XX_RBBM_CLOCK_HYST3_TP0, 0x00007777}, + {A5XX_RBBM_CLOCK_HYST3_TP1, 0x00007777}, + {A5XX_RBBM_CLOCK_DELAY_TP0, 0x11111111}, + {A5XX_RBBM_CLOCK_DELAY_TP1, 0x11111111}, + {A5XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111}, + {A5XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111}, + {A5XX_RBBM_CLOCK_DELAY3_TP0, 0x00001111}, + {A5XX_RBBM_CLOCK_DELAY3_TP1, 0x00001111}, + {A5XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222}, + {A5XX_RBBM_CLOCK_HYST_UCHE, 0x00444444}, + {A5XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002}, + {A5XX_RBBM_CLOCK_CNTL_RB0, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL_RB1, 0x22222222}, + {A5XX_RBBM_CLOCK_CNTL2_RB0, 0x00222222}, + {A5XX_RBBM_CLOCK_CNTL2_RB1, 0x00222222}, + {A5XX_RBBM_CLOCK_CNTL_CCU0, 0x00022220}, + {A5XX_RBBM_CLOCK_CNTL_CCU1, 0x00022220}, + {A5XX_RBBM_CLOCK_CNTL_RAC, 0x05522222}, + {A5XX_RBBM_CLOCK_CNTL2_RAC, 0x00555555}, + {A5XX_RBBM_CLOCK_HYST_RB_CCU0, 0x04040404}, + {A5XX_RBBM_CLOCK_HYST_RB_CCU1, 0x04040404}, + {A5XX_RBBM_CLOCK_HYST_RAC, 0x07444044}, + {A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_0, 0x00000002}, + {A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_1, 0x00000002}, + {A5XX_RBBM_CLOCK_DELAY_RAC, 0x00010011}, + {A5XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222}, + {A5XX_RBBM_CLOCK_MODE_GPC, 0x02222222}, + {A5XX_RBBM_CLOCK_MODE_VFD, 0x00002222}, + {A5XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000}, + {A5XX_RBBM_CLOCK_HYST_GPC, 0x04104004}, + {A5XX_RBBM_CLOCK_HYST_VFD, 0x00000000}, + {A5XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000}, + {A5XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000}, + {A5XX_RBBM_CLOCK_DELAY_GPC, 0x00000200}, + {A5XX_RBBM_CLOCK_DELAY_VFD, 0x00002222}, +}; + static const struct { int (*devfunc)(struct adreno_device *adreno_dev); const struct kgsl_hwcg_reg *regs; @@ -1127,6 +1190,7 @@ static const struct { } a5xx_hwcg_registers[] = { { adreno_is_a540, a540_hwcg_regs, ARRAY_SIZE(a540_hwcg_regs) }, { adreno_is_a530, a530_hwcg_regs, ARRAY_SIZE(a530_hwcg_regs) }, + { adreno_is_a512, a512_hwcg_regs, ARRAY_SIZE(a512_hwcg_regs) }, { adreno_is_a510, a510_hwcg_regs, ARRAY_SIZE(a510_hwcg_regs) }, { adreno_is_a505, a50x_hwcg_regs, ARRAY_SIZE(a50x_hwcg_regs) }, { adreno_is_a506, a50x_hwcg_regs, ARRAY_SIZE(a50x_hwcg_regs) }, @@ -1871,6 +1935,11 @@ static void a5xx_start(struct adreno_device *adreno_dev) kgsl_regwrite(device, A5XX_CP_MERCIU_SIZE, 0x20); kgsl_regwrite(device, A5XX_CP_ROQ_THRESHOLDS_2, 0x40000030); kgsl_regwrite(device, A5XX_CP_ROQ_THRESHOLDS_1, 0x20100D0A); + } else if (adreno_is_a540(adreno_dev) || adreno_is_a512(adreno_dev)) { + kgsl_regwrite(device, A5XX_CP_MEQ_THRESHOLDS, 0x40); + kgsl_regwrite(device, A5XX_CP_MERCIU_SIZE, 0x400); + kgsl_regwrite(device, A5XX_CP_ROQ_THRESHOLDS_2, 0x80000060); + kgsl_regwrite(device, A5XX_CP_ROQ_THRESHOLDS_1, 0x40201B16); } else { kgsl_regwrite(device, A5XX_CP_MEQ_THRESHOLDS, 0x40); kgsl_regwrite(device, A5XX_CP_MERCIU_SIZE, 0x40); diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 54dc4ce09f35..1a2032c2c1fb 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -175,27 +175,9 @@ static int __uhid_report_queue_and_wait(struct uhid_device *uhid, uhid_queue(uhid, ev); spin_unlock_irqrestore(&uhid->qlock, flags); - /* - * Assumption: report_lock and devlock are both locked. So unlock - * before sleeping. - */ - mutex_unlock(&uhid->report_lock); - mutex_unlock(&uhid->devlock); ret = wait_event_interruptible_timeout(uhid->report_wait, !uhid->report_running || !uhid->running, 5 * HZ); - ret = mutex_lock_interruptible(&uhid->devlock); - if (ret) - return ret; - ret = mutex_lock_interruptible(&uhid->report_lock); - if (ret) { - /* - * Failed to lock, unlock previous mutex before exiting - * this function. - */ - mutex_unlock(&uhid->devlock); - return ret; - } if (!ret || !uhid->running || uhid->report_running) ret = -EIO; else if (ret < 0) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c index e238f54a9100..09de276e8418 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1794,6 +1794,7 @@ int msm_isp_process_overflow_irq( { uint32_t overflow_mask; uint32_t bus_err = 0; + unsigned long flags; /* if there are no active streams - do not start recovery */ if (!vfe_dev->axi_data.num_active_stream) @@ -1825,23 +1826,33 @@ int msm_isp_process_overflow_irq( int i; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; + spin_lock_irqsave( + &vfe_dev->common_data->common_dev_data_lock, flags); + if (atomic_cmpxchg(&vfe_dev->error_info.overflow_state, - NO_OVERFLOW, OVERFLOW_DETECTED != NO_OVERFLOW)) + NO_OVERFLOW, OVERFLOW_DETECTED)) { + spin_unlock_irqrestore( + &vfe_dev->common_data->common_dev_data_lock, + flags); return 0; + } if (vfe_dev->reset_pending == 1) { - pr_err("%s:%d failed: overflow %x during reset\n", + pr_err_ratelimited("%s:%d overflow %x during reset\n", __func__, __LINE__, overflow_mask); /* Clear overflow bits since reset is pending */ *irq_status1 &= ~overflow_mask; + spin_unlock_irqrestore( + &vfe_dev->common_data->common_dev_data_lock, + flags); return 0; } - pr_err("%s: vfe %d overflow mask %x, bus_error %x\n", + pr_err_ratelimited("%s: vfe %d overflowmask %x,bus_error %x\n", __func__, vfe_dev->pdev->id, overflow_mask, bus_err); for (i = 0; i < axi_data->hw_info->num_wm; i++) { if (!axi_data->free_wm[i]) continue; - pr_err("%s: wm %d assigned to stream handle %x\n", + ISP_DBG("%s:wm %d assigned to stream handle %x\n", __func__, i, axi_data->free_wm[i]); } vfe_dev->recovery_irq0_mask = vfe_dev->irq0_mask; @@ -1880,6 +1891,9 @@ int msm_isp_process_overflow_irq( msm_isp_send_event(vfe_dev, ISP_EVENT_ERROR, &error_event); } + spin_unlock_irqrestore( + &vfe_dev->common_data->common_dev_data_lock, + flags); return 1; } return 0; diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c index dc2061fc4537..5264bba57c8d 100644 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c +++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c @@ -1447,6 +1447,12 @@ static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out, pr_err_ratelimited("%s: fatal error, stop ispif immediately\n", __func__); for (i = 0; i < ispif->vfe_info.num_vfe; i++) { + msm_camera_io_w(0x0, + ispif->base + ISPIF_VFE_m_IRQ_MASK_0(i)); + msm_camera_io_w(0x0, + ispif->base + ISPIF_VFE_m_IRQ_MASK_1(i)); + msm_camera_io_w(0x0, + ispif->base + ISPIF_VFE_m_IRQ_MASK_2(i)); msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY, ispif->base + ISPIF_VFE_m_INTF_CMD_0(i)); msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY, diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c index 4b4846907d0f..7f6e78710117 100644 --- a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c +++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -496,7 +496,7 @@ static int msm_jpegdma_queue_init(void *priv, struct vb2_queue *src_vq, src_vq->drv_priv = ctx; src_vq->mem_ops = &msm_jpegdma_vb2_mem_ops; src_vq->ops = &msm_jpegdma_vb2_q_ops; - src_vq->buf_struct_size = sizeof(struct vb2_v4l2_buffer); + src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; ret = vb2_queue_init(src_vq); @@ -510,7 +510,7 @@ static int msm_jpegdma_queue_init(void *priv, struct vb2_queue *src_vq, dst_vq->drv_priv = ctx; dst_vq->mem_ops = &msm_jpegdma_vb2_mem_ops; dst_vq->ops = &msm_jpegdma_vb2_q_ops; - dst_vq->buf_struct_size = sizeof(struct vb2_v4l2_buffer); + dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; ret = vb2_queue_init(dst_vq); diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c index 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/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c index 44746ca0d2e6..fdbc51ae1e1a 100644 --- a/drivers/net/wireless/ath/wil6210/pcie_bus.c +++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c @@ -187,6 +187,22 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) dev_err(dev, "wil_if_alloc failed: %d\n", rc); return rc; } + + /* device supports 48 bit addresses */ + rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48)); + if (rc) { + dev_err(dev, "dma_set_mask_and_coherent(48) failed: %d\n", rc); + rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + if (rc) { + dev_err(dev, + "dma_set_mask_and_coherent(32) failed: %d\n", + rc); + goto if_free; + } + } else { + wil->use_extended_dma_addr = 1; + } + wil->pdev = pdev; pci_set_drvdata(pdev, wil); /* rollback to if_free */ diff --git a/drivers/net/wireless/ath/wil6210/pmc.c b/drivers/net/wireless/ath/wil6210/pmc.c index b9faae0278c9..b6765d4a4602 100644 --- a/drivers/net/wireless/ath/wil6210/pmc.c +++ b/drivers/net/wireless/ath/wil6210/pmc.c @@ -108,13 +108,28 @@ void wil_pmc_alloc(struct wil6210_priv *wil, /* Allocate pring buffer and descriptors. * vring->va should be aligned on its size rounded up to power of 2 - * This is granted by the dma_alloc_coherent + * This is granted by the dma_alloc_coherent. + * + * HW has limitation that all vrings addresses must share the same + * upper 16 msb bits part of 48 bits address. To workaround that, + * if we are using 48 bit addresses switch to 32 bit allocation + * before allocating vring memory. + * + * There's no check for the return value of dma_set_mask_and_coherent, + * since we assume if we were able to set the mask during + * initialization in this system it will not fail if we set it again */ + if (wil->use_extended_dma_addr) + dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + pmc->pring_va = dma_alloc_coherent(dev, sizeof(struct vring_tx_desc) * num_descriptors, &pmc->pring_pa, GFP_KERNEL); + if (wil->use_extended_dma_addr) + dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48)); + wil_dbg_misc(wil, "%s: allocated pring %p => %pad. %zd x %d = total %zd bytes\n", __func__, diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 4ac9ba04afed..b0166d224508 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -123,15 +123,32 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring) vring->va = NULL; return -ENOMEM; } + /* vring->va should be aligned on its size rounded up to power of 2 - * This is granted by the dma_alloc_coherent + * This is granted by the dma_alloc_coherent. + * + * HW has limitation that all vrings addresses must share the same + * upper 16 msb bits part of 48 bits address. To workaround that, + * if we are using 48 bit addresses switch to 32 bit allocation + * before allocating vring memory. + * + * There's no check for the return value of dma_set_mask_and_coherent, + * since we assume if we were able to set the mask during + * initialization in this system it will not fail if we set it again */ + if (wil->use_extended_dma_addr) + dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + vring->va = dma_alloc_coherent(dev, sz, &vring->pa, GFP_KERNEL); if (!vring->va) { kfree(vring->ctx); vring->ctx = NULL; return -ENOMEM; } + + if (wil->use_extended_dma_addr) + dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48)); + /* initially, all descriptors are SW owned * For Tx and Rx, ownership bit is at the same location, thus * we can use any diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index bab0ed20c8c4..cc20517a4726 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -647,6 +647,7 @@ struct wil6210_priv { u8 vring2cid_tid[WIL6210_MAX_TX_RINGS][2]; /* [0] - CID, [1] - TID */ struct wil_sta_info sta[WIL6210_MAX_CID]; int bcast_vring; + bool use_extended_dma_addr; /* indicates whether we are using 48 bits */ /* scan */ struct cfg80211_scan_request *scan_request; diff --git a/drivers/pinctrl/qcom/pinctrl-lpi.c b/drivers/pinctrl/qcom/pinctrl-lpi.c index 4829ba7f4bf0..67cac25689ef 100644 --- a/drivers/pinctrl/qcom/pinctrl-lpi.c +++ b/drivers/pinctrl/qcom/pinctrl-lpi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -108,6 +108,7 @@ static const u32 lpi_offset[] = { 0x00000000, 0x00001000, 0x00002000, + 0x00002010, 0x00003000, 0x00003010, 0x00004000, @@ -592,7 +593,7 @@ static int lpi_pinctrl_probe(struct platform_device *pdev) goto err_range; } - lpi_dev_up = false; + lpi_dev_up = true; ret = audio_notifier_register("lpi_tlmm", AUDIO_NOTIFIER_ADSP_DOMAIN, &service_nb); if (ret < 0) { diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c index c063e4392c16..e3d20422d591 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c @@ -884,8 +884,8 @@ int ipa_init_hw(void) ipa_write_reg(ipa_ctx->mmio, IPA_COMP_SW_RESET_OFST, 1); ipa_write_reg(ipa_ctx->mmio, IPA_COMP_SW_RESET_OFST, 0); - /* enable IPA */ - ipa_write_reg(ipa_ctx->mmio, IPA_COMP_CFG_OFST, 1); + /* enable IPA Bit:0, enable 2x fast clock Bit:4 */ + ipa_write_reg(ipa_ctx->mmio, IPA_COMP_CFG_OFST, 0x11); /* Read IPA version and make sure we have access to the registers */ ipa_version = ipa_read_reg(ipa_ctx->mmio, IPA_VERSION_OFST); diff --git a/drivers/platform/msm/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/Kconfig b/drivers/power/Kconfig index 931230d55f90..91fdeaf67037 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -521,9 +521,9 @@ config AXP20X_POWER AXP20x PMIC. source "drivers/power/reset/Kconfig" +source "drivers/power/supply/Kconfig" endif # POWER_SUPPLY source "drivers/power/avs/Kconfig" source "drivers/power/qcom/Kconfig" -source "drivers/power/qcom-charger/Kconfig" diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 21aceda44c9e..f7adecea0a70 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -73,4 +73,4 @@ obj-$(CONFIG_POWER_RESET) += reset/ obj-$(CONFIG_AXP288_FUEL_GAUGE) += axp288_fuel_gauge.o obj-$(CONFIG_AXP288_CHARGER) += axp288_charger.o obj-$(CONFIG_ARCH_QCOM) += qcom/ -obj-y += qcom-charger/ +obj-$(CONFIG_POWER_SUPPLY) += supply/ diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index 83b75fcd257e..e99bf1ee5ad2 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c @@ -279,6 +279,7 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(pe_start), POWER_SUPPLY_ATTR(set_ship_mode), POWER_SUPPLY_ATTR(soc_reporting_ready), + POWER_SUPPLY_ATTR(debug_battery), /* Local extensions of type int64_t */ POWER_SUPPLY_ATTR(charge_counter_ext), /* Properties of type `const char *' */ diff --git a/drivers/power/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/power/supply/Kconfig b/drivers/power/supply/Kconfig new file mode 100644 index 000000000000..ec128bf6a93a --- /dev/null +++ b/drivers/power/supply/Kconfig @@ -0,0 +1 @@ +source "drivers/power/supply/qcom/Kconfig" diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile new file mode 100644 index 000000000000..c8f025f309e7 --- /dev/null +++ b/drivers/power/supply/Makefile @@ -0,0 +1 @@ +obj-y += qcom/ diff --git a/drivers/power/qcom-charger/Kconfig b/drivers/power/supply/qcom/Kconfig index 7a0b1464ad86..b919c688e627 100644 --- a/drivers/power/qcom-charger/Kconfig +++ b/drivers/power/supply/qcom/Kconfig @@ -1,9 +1,8 @@ -menu "Qualcomm Technologies Inc Charger and FG Drivers" +menu "Qualcomm Technologies Inc Charger and Fuel Gauge support" config QPNP_SMBCHARGER tristate "QPNP SMB Charger driver" - depends on SPMI - select POWER_SUPPLY + depends on MFD_SPMI_PMIC help Say Y here to enable the dual path switch mode battery charger which supports USB detection and battery charging up to 3A. @@ -12,8 +11,7 @@ config QPNP_SMBCHARGER config QPNP_FG tristate "QPNP fuel gauge driver" - depends on SPMI - select POWER_SUPPLY + depends on MFD_SPMI_PMIC help Say Y here to enable the Fuel Gauge driver. This adds support for battery fuel gauging and state of charge of battery connected to the @@ -22,8 +20,7 @@ config QPNP_FG config QPNP_FG_GEN3 tristate "QPNP GEN3 fuel gauge driver" - depends on SPMI - select REGMAP_SPMI + depends on MFD_SPMI_PMIC help Say Y here to enable the GEN3 Fuel Gauge driver. This adds support for battery fuel gauging and state of charge of battery connected to @@ -33,7 +30,6 @@ config QPNP_FG_GEN3 config SMB135X_CHARGER tristate "SMB135X Battery Charger" depends on I2C - select POWER_SUPPLY help Say Y to include support for SMB135X Battery Charger. SMB135X is a dual path switching mode charger capable of charging @@ -45,7 +41,6 @@ config SMB135X_CHARGER config SMB1351_USB_CHARGER tristate "smb1351 usb charger (with VBUS detection)" depends on I2C - select POWER_SUPPLY help Say Y to enable support for the SMB1351 switching mode based charger. The driver supports charging control (enable/disable) and @@ -65,7 +60,6 @@ config MSM_BCL_PERIPHERAL_CTL bool "BCL driver to control the PMIC BCL peripheral" depends on SPMI depends on MSM_BCL_CTL - select POWER_SUPPLY help Say Y here to enable this BCL PMIC peripheral driver. This driver provides routines to configure and monitor the BCL @@ -83,14 +77,12 @@ config BATTERY_BCL config QPNP_SMB2 tristate "SMB2 Battery Charger" depends on MFD_SPMI_PMIC - select POWER_SUPPLY help Enables support for the SMB2 charging peripheral config SMB138X_CHARGER tristate "SMB138X Battery Charger" depends on MFD_I2C_PMIC - select POWER_SUPPLY help Say Y to include support for SMB138X Battery Charger. SMB1380 is a dual phase 6A battery charger, and SMB1381 is a single @@ -101,8 +93,7 @@ config SMB138X_CHARGER config QPNP_QNOVO bool "QPNP QNOVO driver" - depends on SPMI - select POWER_SUPPLY + depends on MFD_SPMI_PMIC help Say Y here to enable the Qnovo pulse charging engine. Qnovo driver accepts pulse parameters via sysfs entries and programs the hardware diff --git a/drivers/power/qcom-charger/Makefile b/drivers/power/supply/qcom/Makefile index 0126d2d0a18e..0126d2d0a18e 100644 --- a/drivers/power/qcom-charger/Makefile +++ b/drivers/power/supply/qcom/Makefile diff --git a/drivers/power/qcom-charger/battery_current_limit.c b/drivers/power/supply/qcom/battery_current_limit.c index d2c25bfbf66c..d2c25bfbf66c 100644 --- a/drivers/power/qcom-charger/battery_current_limit.c +++ b/drivers/power/supply/qcom/battery_current_limit.c diff --git a/drivers/power/qcom-charger/batterydata-lib.c b/drivers/power/supply/qcom/batterydata-lib.c index 226581468fda..226581468fda 100644 --- a/drivers/power/qcom-charger/batterydata-lib.c +++ b/drivers/power/supply/qcom/batterydata-lib.c diff --git a/drivers/power/qcom-charger/bcl_peripheral.c b/drivers/power/supply/qcom/bcl_peripheral.c index cae4967f1ef4..cae4967f1ef4 100644 --- a/drivers/power/qcom-charger/bcl_peripheral.c +++ b/drivers/power/supply/qcom/bcl_peripheral.c diff --git a/drivers/power/qcom-charger/fg-core.h b/drivers/power/supply/qcom/fg-core.h index 07bde30524ac..07bde30524ac 100644 --- a/drivers/power/qcom-charger/fg-core.h +++ b/drivers/power/supply/qcom/fg-core.h diff --git a/drivers/power/qcom-charger/fg-memif.c b/drivers/power/supply/qcom/fg-memif.c index a98ff7d765e3..a98ff7d765e3 100644 --- a/drivers/power/qcom-charger/fg-memif.c +++ b/drivers/power/supply/qcom/fg-memif.c diff --git a/drivers/power/qcom-charger/fg-reg.h b/drivers/power/supply/qcom/fg-reg.h index 7ad26215e469..bf2827fb550d 100644 --- a/drivers/power/qcom-charger/fg-reg.h +++ b/drivers/power/supply/qcom/fg-reg.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -211,7 +211,6 @@ #define ADC_BITSTREAM_INV_BIT BIT(4) #define SOURCE_SELECT_MASK GENMASK(1, 0) #define SRC_SEL_BATFET 0x0 -#define SRC_SEL_RSENSE 0x1 #define SRC_SEL_BATFET_SMB 0x2 #define SRC_SEL_RESERVED 0x3 diff --git a/drivers/power/qcom-charger/fg-util.c b/drivers/power/supply/qcom/fg-util.c index 41d2af0fbdc6..41d2af0fbdc6 100644 --- a/drivers/power/qcom-charger/fg-util.c +++ b/drivers/power/supply/qcom/fg-util.c diff --git a/drivers/power/qcom-charger/msm_bcl.c b/drivers/power/supply/qcom/msm_bcl.c index 6b7cefdc0250..aea3f4645897 100644 --- a/drivers/power/qcom-charger/msm_bcl.c +++ b/drivers/power/supply/qcom/msm_bcl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -99,14 +99,14 @@ int msm_bcl_set_threshold(enum bcl_param param_type, { int ret = 0; - if (!bcl[param_type] || !bcl[param_type]->registered) { + if (param_type >= BCL_PARAM_MAX || !bcl[param_type] + || !bcl[param_type]->registered) { pr_err("BCL not initialized\n"); return -EINVAL; } if ((!inp_thresh) || (inp_thresh->trip_value < 0) || (!inp_thresh->trip_notify) - || (param_type >= BCL_PARAM_MAX) || (trip_type >= BCL_TRIP_MAX)) { pr_err("Invalid Input\n"); return -EINVAL; @@ -152,8 +152,8 @@ struct bcl_param_data *msm_bcl_register_param(enum bcl_param param_type, { int ret = 0; - if (!bcl[param_type] - || param_type >= BCL_PARAM_MAX || !param_ops || !name + if (param_type >= BCL_PARAM_MAX + || !bcl[param_type] || !param_ops || !name || !param_ops->read || !param_ops->set_high_trip || !param_ops->get_high_trip || !param_ops->set_low_trip || !param_ops->get_low_trip || !param_ops->enable diff --git a/drivers/power/qcom-charger/pmic-voter.c b/drivers/power/supply/qcom/pmic-voter.c index e1a92fb23912..e1a92fb23912 100644 --- a/drivers/power/qcom-charger/pmic-voter.c +++ b/drivers/power/supply/qcom/pmic-voter.c diff --git a/drivers/power/qcom-charger/pmic-voter.h b/drivers/power/supply/qcom/pmic-voter.h index 031b9a010a42..031b9a010a42 100644 --- a/drivers/power/qcom-charger/pmic-voter.h +++ b/drivers/power/supply/qcom/pmic-voter.h diff --git a/drivers/power/qcom-charger/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c index 8523efa1a4ab..8523efa1a4ab 100644 --- a/drivers/power/qcom-charger/qpnp-fg-gen3.c +++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c diff --git a/drivers/power/qcom-charger/qpnp-fg.c b/drivers/power/supply/qcom/qpnp-fg.c index 0658f0d3b1eb..e4a8ade80d4f 100644 --- a/drivers/power/qcom-charger/qpnp-fg.c +++ b/drivers/power/supply/qcom/qpnp-fg.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2081,7 +2081,7 @@ static void update_sram_data_work(struct work_struct *work) struct fg_chip *chip = container_of(work, struct fg_chip, update_sram_data.work); - int resched_ms, ret; + int resched_ms = SRAM_PERIOD_NO_ID_UPDATE_MS, ret; bool tried_again = false; wait: @@ -5961,7 +5961,19 @@ static ssize_t fg_memif_dfs_reg_write(struct file *file, const char __user *buf, values = kbuf; /* Parse the data in the buffer. It should be a string of numbers */ - while (sscanf(kbuf + pos, "%i%n", &data, &bytes_read) == 1) { + while ((pos < count) && + sscanf(kbuf + pos, "%i%n", &data, &bytes_read) == 1) { + /* + * We shouldn't be receiving a string of characters that + * exceeds a size of 5 to keep this functionally correct. + * Also, we should make sure that pos never gets overflowed + * beyond the limit. + */ + if (bytes_read > 5 || bytes_read > INT_MAX - pos) { + cnt = 0; + ret = -EINVAL; + break; + } pos += bytes_read; values[cnt++] = data & 0xff; } diff --git a/drivers/power/qcom-charger/qpnp-qnovo.c b/drivers/power/supply/qcom/qpnp-qnovo.c index 7bc90fbf2929..7bc90fbf2929 100644 --- a/drivers/power/qcom-charger/qpnp-qnovo.c +++ b/drivers/power/supply/qcom/qpnp-qnovo.c diff --git a/drivers/power/qcom-charger/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index 98a917273328..98a917273328 100644 --- a/drivers/power/qcom-charger/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c diff --git a/drivers/power/qcom-charger/qpnp-smbcharger.c b/drivers/power/supply/qcom/qpnp-smbcharger.c index 6c1e58d046e8..6c1e58d046e8 100644 --- a/drivers/power/qcom-charger/qpnp-smbcharger.c +++ b/drivers/power/supply/qcom/qpnp-smbcharger.c diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index eec96d30d4f9..9728490736ff 100644 --- a/drivers/power/qcom-charger/smb-lib.c +++ b/drivers/power/supply/qcom/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/qcom-charger/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index efce7eb987ab..efce7eb987ab 100644 --- a/drivers/power/qcom-charger/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h diff --git a/drivers/power/qcom-charger/smb-reg.h b/drivers/power/supply/qcom/smb-reg.h index 5f74e27c7978..5f74e27c7978 100644 --- a/drivers/power/qcom-charger/smb-reg.h +++ b/drivers/power/supply/qcom/smb-reg.h diff --git a/drivers/power/qcom-charger/smb1351-charger.c b/drivers/power/supply/qcom/smb1351-charger.c index e9d8c0e08447..e9d8c0e08447 100644 --- a/drivers/power/qcom-charger/smb1351-charger.c +++ b/drivers/power/supply/qcom/smb1351-charger.c diff --git a/drivers/power/qcom-charger/smb135x-charger.c b/drivers/power/supply/qcom/smb135x-charger.c index 65d4ae56ff83..65d4ae56ff83 100644 --- a/drivers/power/qcom-charger/smb135x-charger.c +++ b/drivers/power/supply/qcom/smb135x-charger.c diff --git a/drivers/power/qcom-charger/smb138x-charger.c b/drivers/power/supply/qcom/smb138x-charger.c index 70d935e9d1df..70d935e9d1df 100644 --- a/drivers/power/qcom-charger/smb138x-charger.c +++ b/drivers/power/supply/qcom/smb138x-charger.c diff --git a/drivers/power/qcom-charger/storm-watch.c b/drivers/power/supply/qcom/storm-watch.c index 90fec12bd742..90fec12bd742 100644 --- a/drivers/power/qcom-charger/storm-watch.c +++ b/drivers/power/supply/qcom/storm-watch.c diff --git a/drivers/power/qcom-charger/storm-watch.h b/drivers/power/supply/qcom/storm-watch.h index 44b9d64d8a87..44b9d64d8a87 100644 --- a/drivers/power/qcom-charger/storm-watch.h +++ b/drivers/power/supply/qcom/storm-watch.h diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 2138e81bb9e9..1e6db2a76fa5 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -3,7 +3,7 @@ * * This code is based on drivers/scsi/ufs/ufshcd.c * Copyright (C) 2011-2013 Samsung India Software Operations - * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. * * Authors: * Santosh Yaraganavi <santosh.sy@samsung.com> @@ -5264,9 +5264,28 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status) retval = IRQ_HANDLED; } - if ((intr_status & UFSHCD_UIC_PWR_MASK) && hba->uic_async_done) { - complete(hba->uic_async_done); - retval = IRQ_HANDLED; + if (intr_status & UFSHCD_UIC_PWR_MASK) { + if (hba->uic_async_done) { + complete(hba->uic_async_done); + retval = IRQ_HANDLED; + } else if (ufshcd_is_auto_hibern8_supported(hba)) { + /* + * If uic_async_done flag is not set then this + * is an Auto hibern8 err interrupt. + * Perform a host reset followed by a full + * link recovery. + */ + hba->ufshcd_state = UFSHCD_STATE_ERROR; + hba->force_host_reset = true; + dev_err(hba->dev, "%s: Auto Hibern8 %s failed - status: 0x%08x, upmcrs: 0x%08x\n", + __func__, (intr_status & UIC_HIBERNATE_ENTER) ? + "Enter" : "Exit", + intr_status, ufshcd_get_upmcrs(hba)); + __ufshcd_print_host_regs(hba, true); + ufshcd_print_host_state(hba); + schedule_work(&hba->eh_work); + retval = IRQ_HANDLED; + } } return retval; } @@ -5858,6 +5877,7 @@ static void ufshcd_err_handler(struct work_struct *work) int err = 0; int tag; bool needs_reset = false; + bool clks_enabled = false; hba = container_of(work, struct ufs_hba, eh_work); @@ -5867,6 +5887,22 @@ static void ufshcd_err_handler(struct work_struct *work) if (hba->ufshcd_state == UFSHCD_STATE_RESET) goto out; + /* + * Make sure the clocks are ON before we proceed with err + * handling. For the majority of cases err handler would be + * run with clocks ON. There is a possibility that the err + * handler was scheduled due to auto hibern8 error interrupt, + * in which case the clocks could be gated or be in the + * process of gating when the err handler runs. + */ + if (unlikely((hba->clk_gating.state != CLKS_ON) && + ufshcd_is_auto_hibern8_supported(hba))) { + spin_unlock_irqrestore(hba->host->host_lock, flags); + ufshcd_hold(hba, false); + spin_lock_irqsave(hba->host->host_lock, flags); + clks_enabled = true; + } + hba->ufshcd_state = UFSHCD_STATE_RESET; ufshcd_set_eh_in_progress(hba); @@ -6003,6 +6039,9 @@ skip_err_handling: } hba->silence_err_logs = false; + + if (clks_enabled) + __ufshcd_release(hba, false); out: ufshcd_clear_eh_in_progress(hba); spin_unlock_irqrestore(hba->host->host_lock, flags); @@ -8904,6 +8943,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 +8989,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 +9439,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/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/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/gadget/function/f_mbim.c b/drivers/usb/gadget/function/f_mbim.c index cdbac89d8734..e7c3278f66d4 100644 --- a/drivers/usb/gadget/function/f_mbim.c +++ b/drivers/usb/gadget/function/f_mbim.c @@ -2027,7 +2027,7 @@ static long mbim_ioctl(struct file *fp, unsigned cmd, unsigned long arg) default: ret = -ENODEV; pr_err("unknown transport\n"); - break; + goto fail; } ret = copy_to_user((void __user *)arg, &info, @@ -2043,6 +2043,7 @@ static long mbim_ioctl(struct file *fp, unsigned cmd, unsigned long arg) ret = -EINVAL; } +fail: mbim_unlock(&mbim->ioctl_excl); return ret; diff --git a/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/include/linux/power_supply.h b/include/linux/power_supply.h index 20280ff20e52..de35fe9441fe 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -228,6 +228,7 @@ enum power_supply_property { POWER_SUPPLY_PROP_PE_START, POWER_SUPPLY_PROP_SET_SHIP_MODE, POWER_SUPPLY_PROP_SOC_REPORTING_READY, + POWER_SUPPLY_PROP_DEBUG_BATTERY, /* Local extensions of type int64_t */ POWER_SUPPLY_PROP_CHARGE_COUNTER_EXT, /* Properties of type `const char *' */ diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 760bc4d5a2cf..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/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/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c index cee4720bbe31..b94001d8a6eb 100644 --- a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c +++ b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2383,6 +2383,7 @@ static int msm_anlg_cdc_codec_enable_dig_clk(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMU: msm_anlg_cdc_codec_enable_clock_block(codec, 1); snd_soc_update_bits(codec, w->reg, 0x80, 0x80); + msm_anlg_cdc_boost_mode_sequence(codec, SPK_PMU); break; case SND_SOC_DAPM_POST_PMD: if (sdm660_cdc->rx_bias_count == 0) @@ -4016,6 +4017,7 @@ int msm_anlg_codec_info_create_codec_entry(struct snd_info_entry *codec_root, struct snd_info_entry *version_entry; struct sdm660_cdc_priv *sdm660_cdc_priv; struct snd_soc_card *card; + int ret; if (!codec_root || !codec) return -EINVAL; @@ -4023,7 +4025,7 @@ int msm_anlg_codec_info_create_codec_entry(struct snd_info_entry *codec_root, sdm660_cdc_priv = snd_soc_codec_get_drvdata(codec); card = codec->component.card; sdm660_cdc_priv->entry = snd_register_module_info(codec_root->module, - "pmic_analog", + "spmi0-03", codec_root); if (!sdm660_cdc_priv->entry) { dev_dbg(codec->dev, "%s: failed to create pmic_analog entry\n", @@ -4050,6 +4052,16 @@ int msm_anlg_codec_info_create_codec_entry(struct snd_info_entry *codec_root, return -ENOMEM; } sdm660_cdc_priv->version_entry = version_entry; + sdm660_cdc_priv->audio_ssr_nb.notifier_call = + sdm660_cdc_notifier_service_cb; + ret = audio_notifier_register("pmic_analog_cdc", + AUDIO_NOTIFIER_ADSP_DOMAIN, + &sdm660_cdc_priv->audio_ssr_nb); + if (ret < 0) { + pr_err("%s: Audio notifier register failed ret = %d\n", + __func__, ret); + return ret; + } return 0; } EXPORT_SYMBOL(msm_anlg_codec_info_create_codec_entry); @@ -4176,17 +4188,6 @@ static int msm_anlg_cdc_soc_probe(struct snd_soc_codec *codec) /* Set initial cap mode */ msm_anlg_cdc_configure_cap(codec, false, false); - sdm660_cdc_priv->audio_ssr_nb.notifier_call = - sdm660_cdc_notifier_service_cb; - ret = audio_notifier_register("pmic_analog_cdc", - AUDIO_NOTIFIER_ADSP_DOMAIN, - &sdm660_cdc_priv->audio_ssr_nb); - if (ret < 0) { - pr_err("%s: Audio notifier register failed ret = %d\n", - __func__, ret); - wcd_mbhc_deinit(&sdm660_cdc_priv->mbhc); - return ret; - } return 0; } @@ -4586,6 +4587,8 @@ static int msm_anlg_cdc_probe(struct platform_device *pdev) usleep_range(5, 6); dev_set_drvdata(&pdev->dev, sdm660_cdc); + wcd9xxx_spmi_set_dev(pdev, 0); + wcd9xxx_spmi_set_dev(pdev, 1); if (wcd9xxx_spmi_irq_init()) { dev_err(&pdev->dev, "%s: irq initialization failed\n", __func__); diff --git a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c index ac71e3c6d6a1..c39b6d57f908 100644 --- a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c +++ b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -815,7 +815,7 @@ static int msm_dig_cdc_codec_enable_dmic(struct snd_soc_dapm_widget *w, } snd_soc_update_bits(codec, MSM89XX_CDC_CORE_TX1_DMIC_CTL + (dmic - 1) * 0x20, - 0x07, 0x01); + 0x07, 0x02); break; case SND_SOC_DAPM_POST_PMD: (*dmic_clk_cnt)--; @@ -1132,7 +1132,7 @@ int msm_dig_codec_info_create_codec_entry(struct snd_info_entry *codec_root, msm_dig = snd_soc_codec_get_drvdata(codec); card = codec->component.card; msm_dig->entry = snd_register_module_info(codec_root->module, - "msm_digital", + "msm_digital_codec", codec_root); if (!msm_dig->entry) { dev_dbg(codec->dev, "%s: failed to create msm_digital entry\n", @@ -1202,9 +1202,8 @@ static int msm_dig_cdc_soc_probe(struct snd_soc_codec *codec) return ret; } } - if (msm_dig_cdc->get_cdc_version) - dig_cdc->version = msm_dig_cdc->get_cdc_version( - msm_dig_cdc->handle); + /* Assign to DRAX_CDC for initial version */ + dig_cdc->version = DRAX_CDC; registered_digcodec = codec; return 0; } @@ -1557,16 +1556,18 @@ static const struct snd_soc_dapm_widget msm_dig_dapm_widgets[] = { SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER_E("RX1 CHAIN", MSM89XX_CDC_CORE_RX1_B6_CTL, - MSM89XX_RX1, 0, NULL, 0, + SND_SOC_DAPM_MIXER_E("RX1 CHAIN", SND_SOC_NOPM, + 0, 0, NULL, 0, + msm_dig_cdc_codec_enable_rx_chain, + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX2 CHAIN", SND_SOC_NOPM, + 0, 0, NULL, 0, + msm_dig_cdc_codec_enable_rx_chain, + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER_E("RX3 CHAIN", SND_SOC_NOPM, + 0, 0, NULL, 0, msm_dig_cdc_codec_enable_rx_chain, SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER_E("RX2 CHAIN", MSM89XX_CDC_CORE_RX2_B6_CTL, - MSM89XX_RX2, 0, NULL, 0, - msm_dig_cdc_codec_enable_rx_chain, SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER_E("RX3 CHAIN", MSM89XX_CDC_CORE_RX3_B6_CTL, - MSM89XX_RX3, 0, NULL, 0, - msm_dig_cdc_codec_enable_rx_chain, SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0, &rx_mix1_inp1_mux), diff --git a/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.c b/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.c index 63a715c5248c..78a9a10a258f 100644 --- a/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.c +++ b/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -13,6 +13,7 @@ #include <linux/bitops.h> #include <linux/module.h> #include <linux/init.h> +#include <linux/of_irq.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/slab.h> @@ -83,7 +84,7 @@ struct wcd9xxx_spmi_map { uint8_t mask[NUM_IRQ_REGS]; int linuxirq[MAX_NUM_IRQS]; irq_handler_t handler[MAX_NUM_IRQS]; - struct spmi_device *spmi[NUM_IRQ_REGS]; + struct platform_device *spmi[NUM_IRQ_REGS]; struct snd_soc_codec *codec; enum wcd9xxx_spmi_pm_state pm_state; @@ -99,22 +100,6 @@ struct wcd9xxx_spmi_map map; void wcd9xxx_spmi_enable_irq(int irq) { pr_debug("%s: irqno =%d\n", __func__, irq); - if ((irq >= 0) && (irq <= 7)) { - snd_soc_update_bits(map.codec, - MSM89XX_PMIC_DIGITAL_INT_EN_CLR, - (0x01 << irq), 0x00); - snd_soc_update_bits(map.codec, - MSM89XX_PMIC_DIGITAL_INT_EN_SET, - (0x01 << irq), (0x01 << irq)); - } - if ((irq > 7) && (irq <= 15)) { - snd_soc_update_bits(map.codec, - MSM89XX_PMIC_ANALOG_INT_EN_CLR, - (0x01 << (irq - 8)), 0x00); - snd_soc_update_bits(map.codec, - MSM89XX_PMIC_ANALOG_INT_EN_SET, - (0x01 << (irq - 8)), (0x01 << (irq - 8))); - } if (!(map.mask[BIT_BYTE(irq)] & (BYTE_BIT_MASK(irq)))) return; @@ -128,23 +113,6 @@ void wcd9xxx_spmi_enable_irq(int irq) void wcd9xxx_spmi_disable_irq(int irq) { pr_debug("%s: irqno =%d\n", __func__, irq); - if ((irq >= 0) && (irq <= 7)) { - snd_soc_update_bits(map.codec, - MSM89XX_PMIC_DIGITAL_INT_EN_SET, - (0x01 << (irq)), 0x00); - snd_soc_update_bits(map.codec, - MSM89XX_PMIC_DIGITAL_INT_EN_CLR, - (0x01 << irq), (0x01 << irq)); - } - - if ((irq > 7) && (irq <= 15)) { - snd_soc_update_bits(map.codec, - MSM89XX_PMIC_ANALOG_INT_EN_SET, - (0x01 << (irq - 8)), 0x00); - snd_soc_update_bits(map.codec, - MSM89XX_PMIC_ANALOG_INT_EN_CLR, - (0x01 << (irq - 8)), (0x01 << (irq - 8))); - } if (map.mask[BIT_BYTE(irq)] & (BYTE_BIT_MASK(irq))) return; @@ -161,6 +129,10 @@ int wcd9xxx_spmi_request_irq(int irq, irq_handler_t handler, int rc; unsigned long irq_flags; + map.linuxirq[irq] = + platform_get_irq_byname(map.spmi[BIT_BYTE(irq)], + irq_names[irq]); + if (strcmp(name, "mbhc sw intr")) irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT; @@ -414,7 +386,7 @@ void wcd9xxx_spmi_set_codec(struct snd_soc_codec *codec) map.codec = codec; } -void wcd9xxx_spmi_set_dev(struct spmi_device *spmi, int i) +void wcd9xxx_spmi_set_dev(struct platform_device *spmi, int i) { if (i < NUM_IRQ_REGS) map.spmi[i] = spmi; diff --git a/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.h b/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.h index 659e52cc2a5e..42596df0f65b 100644 --- a/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.h +++ b/sound/soc/codecs/sdm660_cdc/sdm660-cdc-irq.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -24,7 +24,7 @@ extern int wcd9xxx_spmi_request_irq(int irq, irq_handler_t handler, const char *name, void *priv); extern int wcd9xxx_spmi_free_irq(int irq, void *priv); extern void wcd9xxx_spmi_set_codec(struct snd_soc_codec *codec); -extern void wcd9xxx_spmi_set_dev(struct spmi_device *spmi, int i); +extern void wcd9xxx_spmi_set_dev(struct platform_device *spmi, int i); extern int wcd9xxx_spmi_irq_init(void); extern int wcd9xxx_spmi_suspend(pm_message_t); extern int wcd9xxx_spmi_resume(void); diff --git a/sound/soc/codecs/sdm660_cdc/sdm660-regmap.c b/sound/soc/codecs/sdm660_cdc/sdm660-regmap.c index 1c3a8d2c2fd9..fff1fdc5b421 100644 --- a/sound/soc/codecs/sdm660_cdc/sdm660-regmap.c +++ b/sound/soc/codecs/sdm660_cdc/sdm660-regmap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -452,20 +452,8 @@ bool msm89xx_cdc_core_readable_reg(struct device *dev, unsigned int reg) bool msm89xx_cdc_core_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { - case MSM89XX_CDC_CORE_RX1_B1_CTL: - case MSM89XX_CDC_CORE_RX2_B1_CTL: - case MSM89XX_CDC_CORE_RX3_B1_CTL: - case MSM89XX_CDC_CORE_RX1_B6_CTL: - case MSM89XX_CDC_CORE_RX2_B6_CTL: - case MSM89XX_CDC_CORE_RX3_B6_CTL: - case MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG: - case MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG: - case MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL: - case MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL: - case MSM89XX_CDC_CORE_CLK_MCLK_CTL: - case MSM89XX_CDC_CORE_CLK_PDM_CTL: - return true; + /* cache bypass for initial version */ default: - return false; + return true; } } diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c index dbe61b252cb9..41f68e05e075 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c @@ -9383,12 +9383,6 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { slimbus_8_rx_voice_mixer_controls, ARRAY_SIZE(slimbus_8_rx_voice_mixer_controls)), /* port mixer */ - SND_SOC_DAPM_MIXER("INT0_MI2S_RX Port Mixer", - SND_SOC_NOPM, 0, 0, int0_mi2s_rx_port_mixer_controls, - ARRAY_SIZE(int0_mi2s_rx_port_mixer_controls)), - SND_SOC_DAPM_MIXER("INT4_MI2S_RX Port Mixer", - SND_SOC_NOPM, 0, 0, int4_mi2s_rx_port_mixer_controls, - ARRAY_SIZE(int4_mi2s_rx_port_mixer_controls)), SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Port Mixer", SND_SOC_NOPM, 0, 0, sbus_0_rx_port_mixer_controls, ARRAY_SIZE(sbus_0_rx_port_mixer_controls)), diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c index b87dcd36958f..4ceaa452f14b 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2937,6 +2937,20 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, case AFE_PORT_ID_QUINARY_MI2S_RX: case AFE_PORT_ID_QUINARY_MI2S_TX: case AFE_PORT_ID_SENARY_MI2S_TX: + case AFE_PORT_ID_INT0_MI2S_RX: + case AFE_PORT_ID_INT0_MI2S_TX: + case AFE_PORT_ID_INT1_MI2S_RX: + case AFE_PORT_ID_INT1_MI2S_TX: + case AFE_PORT_ID_INT2_MI2S_RX: + case AFE_PORT_ID_INT2_MI2S_TX: + case AFE_PORT_ID_INT3_MI2S_RX: + case AFE_PORT_ID_INT3_MI2S_TX: + case AFE_PORT_ID_INT4_MI2S_RX: + case AFE_PORT_ID_INT4_MI2S_TX: + case AFE_PORT_ID_INT5_MI2S_RX: + case AFE_PORT_ID_INT5_MI2S_TX: + case AFE_PORT_ID_INT6_MI2S_RX: + case AFE_PORT_ID_INT6_MI2S_TX: cfg_type = AFE_PARAM_ID_I2S_CONFIG; break; case HDMI_RX: @@ -3316,6 +3330,34 @@ int afe_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_QUATERNARY_TDM_RX_7; case AFE_PORT_ID_QUATERNARY_TDM_TX_7: return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_7; + case AFE_PORT_ID_INT0_MI2S_RX: + return IDX_AFE_PORT_ID_INT0_MI2S_RX; + case AFE_PORT_ID_INT0_MI2S_TX: + return IDX_AFE_PORT_ID_INT0_MI2S_TX; + case AFE_PORT_ID_INT1_MI2S_RX: + return IDX_AFE_PORT_ID_INT1_MI2S_RX; + case AFE_PORT_ID_INT1_MI2S_TX: + return IDX_AFE_PORT_ID_INT1_MI2S_TX; + case AFE_PORT_ID_INT2_MI2S_RX: + return IDX_AFE_PORT_ID_INT2_MI2S_RX; + case AFE_PORT_ID_INT2_MI2S_TX: + return IDX_AFE_PORT_ID_INT2_MI2S_TX; + case AFE_PORT_ID_INT3_MI2S_RX: + return IDX_AFE_PORT_ID_INT3_MI2S_RX; + case AFE_PORT_ID_INT3_MI2S_TX: + return IDX_AFE_PORT_ID_INT3_MI2S_TX; + case AFE_PORT_ID_INT4_MI2S_RX: + return IDX_AFE_PORT_ID_INT4_MI2S_RX; + case AFE_PORT_ID_INT4_MI2S_TX: + return IDX_AFE_PORT_ID_INT4_MI2S_TX; + case AFE_PORT_ID_INT5_MI2S_RX: + return IDX_AFE_PORT_ID_INT5_MI2S_RX; + case AFE_PORT_ID_INT5_MI2S_TX: + return IDX_AFE_PORT_ID_INT5_MI2S_TX; + case AFE_PORT_ID_INT6_MI2S_RX: + return IDX_AFE_PORT_ID_INT6_MI2S_RX; + case AFE_PORT_ID_INT6_MI2S_TX: + return IDX_AFE_PORT_ID_INT6_MI2S_TX; default: pr_err("%s: port 0x%x\n", __func__, port_id); return -EINVAL; diff --git a/sound/soc/msm/sdm660-common.c b/sound/soc/msm/sdm660-common.c index 1497ddcca61f..63d8598d0b92 100644 --- a/sound/soc/msm/sdm660-common.c +++ b/sound/soc/msm/sdm660-common.c @@ -351,7 +351,7 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = { static struct afe_clk_set mi2s_mclk[MI2S_MAX] = { { AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_MCLK_1, + Q6AFE_LPASS_CLK_ID_MCLK_3, Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, @@ -359,7 +359,7 @@ static struct afe_clk_set mi2s_mclk[MI2S_MAX] = { }, { AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_MCLK_2, + Q6AFE_LPASS_CLK_ID_MCLK_4, Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, @@ -367,7 +367,7 @@ static struct afe_clk_set mi2s_mclk[MI2S_MAX] = { }, { AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_MCLK_3, + Q6AFE_LPASS_CLK_ID_MCLK_1, Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, @@ -375,7 +375,7 @@ static struct afe_clk_set mi2s_mclk[MI2S_MAX] = { }, { AFE_API_VERSION_I2S_CONFIG, - Q6AFE_LPASS_CLK_ID_MCLK_4, + Q6AFE_LPASS_CLK_ID_MCLK_2, Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, Q6AFE_LPASS_CLK_ROOT_DEFAULT, diff --git a/sound/soc/msm/sdm660-internal.c b/sound/soc/msm/sdm660-internal.c index c5661dd7ec1e..4ca579694a05 100644 --- a/sound/soc/msm/sdm660-internal.c +++ b/sound/soc/msm/sdm660-internal.c @@ -181,9 +181,7 @@ static int msm_int_mi2s_snd_startup(struct snd_pcm_substream *substream); static void msm_int_mi2s_snd_shutdown(struct snd_pcm_substream *substream); static struct wcd_mbhc_config *mbhc_cfg_ptr; -static struct snd_info_entry *msm_sdw_codec_root; -static struct snd_info_entry *msm_dig_codec_root; -static struct snd_info_entry *pmic_analog_codec_root; +static struct snd_info_entry *codec_root; static int int_mi2s_get_bit_format_val(int bit_format) { @@ -916,15 +914,6 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { SOC_ENUM_EXT("INT3_MI2S_TX SampleRate", int3_mi2s_tx_sample_rate, int_mi2s_sample_rate_get, int_mi2s_sample_rate_put), - SOC_ENUM_EXT("INT0_MI2S_RX SampleRate", int0_mi2s_rx_sample_rate, - int_mi2s_sample_rate_get, - int_mi2s_sample_rate_put), - SOC_ENUM_EXT("INT2_MI2S_TX SampleRate", int2_mi2s_tx_sample_rate, - int_mi2s_sample_rate_get, - int_mi2s_sample_rate_put), - SOC_ENUM_EXT("INT3_MI2S_TX SampleRate", int3_mi2s_tx_sample_rate, - int_mi2s_sample_rate_get, - int_mi2s_sample_rate_put), SOC_ENUM_EXT("INT0_MI2S_RX Channels", int0_mi2s_rx_chs, int_mi2s_ch_get, int_mi2s_ch_put), SOC_ENUM_EXT("INT2_MI2S_TX Channels", int2_mi2s_tx_chs, @@ -1295,7 +1284,6 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_pcm_runtime *rtd_aux = rtd->card->rtd_aux; struct snd_card *card; - struct snd_info_entry *entry; int ret = -ENOMEM; pr_debug("%s(),dev_name%s\n", __func__, dev_name(cpu_dai->dev)); @@ -1361,26 +1349,16 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) } } card = rtd->card->snd_card; - entry = snd_register_module_info(card->module, "codecs", - card->proc_root); - if (!entry) { - pr_debug("%s: Cannot create codecs module entry\n", - __func__); - msm_dig_codec_root = NULL; - goto done; - } - msm_dig_codec_root = entry; - msm_dig_codec_info_create_codec_entry(msm_dig_codec_root, dig_cdc); - entry = snd_register_module_info(card->module, "codecs", - card->proc_root); - if (!entry) { + if (!codec_root) + codec_root = snd_register_module_info(card->module, "codecs", + card->proc_root); + if (!codec_root) { pr_debug("%s: Cannot create codecs module entry\n", __func__); - pmic_analog_codec_root = NULL; goto done; } - pmic_analog_codec_root = entry; - msm_anlg_codec_info_create_codec_entry(pmic_analog_codec_root, ana_cdc); + msm_dig_codec_info_create_codec_entry(codec_root, dig_cdc); + msm_anlg_codec_info_create_codec_entry(codec_root, ana_cdc); done: return 0; } @@ -1391,7 +1369,6 @@ static int msm_sdw_audrx_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct snd_card *card; - struct snd_info_entry *entry; snd_soc_add_codec_controls(codec, msm_sdw_controls, ARRAY_SIZE(msm_sdw_controls)); @@ -1406,16 +1383,15 @@ static int msm_sdw_audrx_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_sync(dapm); msm_sdw_gpio_cb(msm_config_sdw_gpio, codec); card = rtd->card->snd_card; - entry = snd_register_module_info(card->module, "codecs", - card->proc_root); - if (!entry) { + if (!codec_root) + codec_root = snd_register_module_info(card->module, "codecs", + card->proc_root); + if (!codec_root) { pr_debug("%s: Cannot create codecs module entry\n", __func__); - msm_sdw_codec_root = NULL; goto done; } - msm_sdw_codec_root = entry; - msm_sdw_codec_info_create_codec_entry(msm_sdw_codec_root, codec); + msm_sdw_codec_info_create_codec_entry(codec_root, codec); done: return 0; } 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)) |
