diff options
70 files changed, 1123 insertions, 773 deletions
diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-cmd.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-cmd.dtsi index 7a3660a3b480..89bf222231fb 100644 --- a/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-cmd.dtsi +++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35597-truly-dsc-wqxga-cmd.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 @@ -11,7 +11,7 @@ */ &mdss_mdp { - dsi_nt35597_truly_dsc_video: qcom,mdss_dsi_nt35597_dsc_cmd_truly { + dsi_nt35597_truly_dsc_cmd: qcom,mdss_dsi_nt35597_dsc_cmd_truly { qcom,mdss-dsi-panel-name = "nt35597 cmd mode dsi truly panel with DSC"; qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; diff --git a/arch/arm/boot/dts/qcom/msm-audio.dtsi b/arch/arm/boot/dts/qcom/msm-audio.dtsi index 46f66d667fb8..e4903a821bc1 100644 --- a/arch/arm/boot/dts/qcom/msm-audio.dtsi +++ b/arch/arm/boot/dts/qcom/msm-audio.dtsi @@ -928,10 +928,11 @@ }; clock_audio: audio_ext_clk { + status = "disabled"; compatible = "qcom,audio-ref-clk"; qcom,audio-ref-clk-gpio = <&pm660_gpios 3 0>; clock-names = "osr_clk"; - clocks = <&clock_rpmcc AUDIO_PMI_CLK>; + clocks = <&clock_rpmcc RPM_DIV_CLK1>; qcom,node_has_rpm_clock; #clock-cells = <1>; pinctrl-names = "sleep", "active"; @@ -942,18 +943,16 @@ clock_audio_lnbb: audio_ext_clk_lnbb { compatible = "qcom,audio-ref-clk"; clock-names = "osr_clk"; - clocks = <&clock_rpmcc AUDIO_PMIC_LNBB_CLK>; + clocks = <&clock_rpmcc RPM_LN_BB_CLK2>; qcom,node_has_rpm_clock; #clock-cells = <1>; }; wcd_rst_gpio: msm_cdc_pinctrl@64 { compatible = "qcom,msm-cdc-pinctrl"; - qcom,cdc-rst-n-gpio = <&lpi_tlmm 24 0>; pinctrl-names = "aud_active", "aud_sleep"; pinctrl-0 = <&lpi_cdc_reset_active>; pinctrl-1 = <&lpi_cdc_reset_sleep>; + qcom,lpi-gpios; }; - }; - diff --git a/arch/arm/boot/dts/qcom/msm8998-interposer-sdm660-audio.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-sdm660-audio.dtsi index c117bdbf5578..f5ab8078ec13 100644 --- a/arch/arm/boot/dts/qcom/msm8998-interposer-sdm660-audio.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-sdm660-audio.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 @@ -20,6 +20,7 @@ &soc { /delete-node/msm-sdw-codec@152c1000; /delete-node/sound; + /delete-node/sdw_clk_data_pinctrl; }; &slim_aud { diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi index c57fa50d0f29..bc87b375ff50 100644 --- a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi @@ -211,11 +211,11 @@ vcc_ana-supply = <&pm8998_l28>; vcc_dig-supply = <&pm8998_l6>; qcom,afe-load = <20000>; - qcom,afe-vtg-min = <2850000>; - qcom,afe-vtg-max = <3000000>; + qcom,afe-vtg-min = <3008000>; + qcom,afe-vtg-max = <3008000>; qcom,dig-load = <40000>; - qcom,dig-vtg-min = <1800000>; - qcom,dig-vtg-max = <1800000>; + qcom,dig-vtg-min = <1808000>; + qcom,dig-vtg-max = <1808000>; qcom,fb-resume-delay-us = <10000>; qcom,afe-power-on-delay-us = <1000>; qcom,afe-power-off-delay-us = <6>; diff --git a/arch/arm/boot/dts/qcom/sdm630.dtsi b/arch/arm/boot/dts/qcom/sdm630.dtsi index 9186ce0118a3..fa826cbc6b18 100644 --- a/arch/arm/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm/boot/dts/qcom/sdm630.dtsi @@ -868,6 +868,7 @@ qcom,ee = <0>; qcom,use-ipa-tethering-bridge; qcom,modem-cfg-emb-pipe-flt; + qcom,ipa-wdi2; qcom,msm-bus,name = "ipa"; qcom,msm-bus,num-cases = <4>; qcom,msm-bus,num-paths = <2>; diff --git a/arch/arm/boot/dts/qcom/sdm660-audio.dtsi b/arch/arm/boot/dts/qcom/sdm660-audio.dtsi index 13ee40c71228..766642dced6a 100644 --- a/arch/arm/boot/dts/qcom/sdm660-audio.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-audio.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -103,14 +103,20 @@ compatible = "qcom,pmic-analog-codec"; reg = <0xf000 0x200>; interrupt-parent = <&spmi_bus>; - interrupts = <0x1 0xf0 0x0>, - <0x1 0xf0 0x1>, - <0x1 0xf0 0x2>, - <0x1 0xf0 0x3>, - <0x1 0xf0 0x4>, - <0x1 0xf0 0x5>, - <0x1 0xf0 0x6>, - <0x1 0xf0 0x7>; + interrupts = <0x3 0xf0 0x0 IRQ_TYPE_NONE>, + <0x3 0xf0 0x1 IRQ_TYPE_NONE>, + <0x3 0xf0 0x2 IRQ_TYPE_NONE>, + <0x3 0xf0 0x3 IRQ_TYPE_NONE>, + <0x3 0xf0 0x4 IRQ_TYPE_NONE>, + <0x3 0xf0 0x5 IRQ_TYPE_NONE>, + <0x3 0xf0 0x6 IRQ_TYPE_NONE>, + <0x3 0xf0 0x7 IRQ_TYPE_NONE>, + <0x3 0xf1 0x0 IRQ_TYPE_NONE>, + <0x3 0xf1 0x1 IRQ_TYPE_NONE>, + <0x3 0xf1 0x2 IRQ_TYPE_NONE>, + <0x3 0xf1 0x3 IRQ_TYPE_NONE>, + <0x3 0xf1 0x4 IRQ_TYPE_NONE>, + <0x3 0xf1 0x5 IRQ_TYPE_NONE>; interrupt-names = "spk_cnp_int", "spk_clip_int", "spk_ocp_int", @@ -118,7 +124,14 @@ "but_rel_det", "but_press_det", "ins_rem_det", - "mbhc_int"; + "mbhc_int", + "ear_ocp_int", + "hphr_ocp_int", + "hphl_ocp_det", + "ear_cnp_int", + "hphr_cnp_int", + "hphl_cnp_int"; + cdc-vdda-cp-supply = <&pm660_s4>; qcom,cdc-vdda-cp-voltage = <1900000 2050000>; @@ -129,7 +142,7 @@ qcom,cdc-vdd-pa-current = <260000>; cdc-vdd-mic-bias-supply = <&pm660l_l7>; - qcom,cdc-vdd-mic-bias-voltage = <3125000 3125000>; + qcom,cdc-vdd-mic-bias-voltage = <3088000 3088000>; qcom,cdc-vdd-mic-bias-current = <5000>; qcom,cdc-mclk-clk-rate = <9600000>; @@ -139,21 +152,6 @@ qcom,cdc-on-demand-supplies = "cdc-vdd-mic-bias"; - cdc_pdm_gpios: cdc_pdm_pinctrl { - compatible = "qcom,msm-cdc-pinctrl"; - pinctrl-names = "aud_active", "aud_sleep"; - pinctrl-0 = <&cdc_pdm_gpios_active>; - pinctrl-1 = <&cdc_pdm_gpios_sleep>; - qcom,lpi-gpios; - }; - - cdc_comp_gpios: cdc_comp_pinctrl { - compatible = "qcom,msm-cdc-pinctrl"; - pinctrl-names = "aud_active", "aud_sleep"; - pinctrl-0 = <&cdc_comp_gpios_active>; - pinctrl-1 = <&cdc_comp_gpios_sleep>; - qcom,lpi-gpios; - }; /* * Not marking address @ as driver searches this child * with name msm-dig-codec @@ -161,20 +159,58 @@ msm_digital_codec: msm-dig-codec { compatible = "qcom,msm-digital-codec"; reg = <0x152c0000 0x0>; - cdc_dmic_gpios: cdc_dmic_pinctrl { - compatible = "qcom,msm-cdc-pinctrl"; - pinctrl-names = "aud_active", "aud_sleep"; - pinctrl-0 = <&cdc_dmic12_gpios_active - &cdc_dmic34_gpios_active>; - pinctrl-1 = <&cdc_dmic12_gpios_sleep - &cdc_dmic34_gpios_sleep>; - qcom,lpi-gpios; - }; }; }; }; &soc { + cdc_pdm_gpios: cdc_pdm_pinctrl { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&cdc_pdm_gpios_active>; + pinctrl-1 = <&cdc_pdm_gpios_sleep>; + qcom,lpi-gpios; + }; + + cdc_comp_gpios: cdc_comp_pinctrl { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&cdc_comp_gpios_active>; + pinctrl-1 = <&cdc_comp_gpios_sleep>; + qcom,lpi-gpios; + }; + + cdc_dmic_gpios: cdc_dmic_pinctrl { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&cdc_dmic12_gpios_active + &cdc_dmic34_gpios_active>; + pinctrl-1 = <&cdc_dmic12_gpios_sleep + &cdc_dmic34_gpios_sleep>; + qcom,lpi-gpios; + }; + + cdc_sdw_gpios: sdw_clk_data_pinctrl { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&sdw_clk_active &sdw_data_active>; + pinctrl-1 = <&sdw_clk_sleep &sdw_data_sleep>; + }; + + wsa_spkr_en1: wsa_spkr_en1_pinctrl { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&spkr_1_sd_n_active>; + pinctrl-1 = <&spkr_1_sd_n_sleep>; + }; + + wsa_spkr_en2: wsa_spkr_en2_pinctrl { + compatible = "qcom,msm-cdc-pinctrl"; + pinctrl-names = "aud_active", "aud_sleep"; + pinctrl-0 = <&spkr_2_sd_n_active>; + pinctrl-1 = <&spkr_2_sd_n_sleep>; + }; + msm_sdw_codec: msm-sdw-codec@152c1000 { status = "disabled"; compatible = "qcom,msm-sdw-codec"; @@ -182,27 +218,6 @@ interrupts = <0 161 0>; interrupt-names = "swr_master_irq"; - cdc_sdw_gpios: sdw_clk_data_pinctrl { - compatible = "qcom,msm-cdc-pinctrl"; - pinctrl-names = "aud_active", "aud_sleep"; - pinctrl-0 = <&sdw_clk_active &sdw_data_active>; - pinctrl-1 = <&sdw_clk_sleep &sdw_data_sleep>; - }; - - wsa_spkr_en1: wsa_spkr_en1_pinctrl { - compatible = "qcom,msm-cdc-pinctrl"; - pinctrl-names = "aud_active", "aud_sleep"; - pinctrl-0 = <&spkr_1_sd_n_active>; - pinctrl-1 = <&spkr_1_sd_n_sleep>; - }; - - wsa_spkr_en2: wsa_spkr_en2_pinctrl { - compatible = "qcom,msm-cdc-pinctrl"; - pinctrl-names = "aud_active", "aud_sleep"; - pinctrl-0 = <&spkr_2_sd_n_active>; - pinctrl-1 = <&spkr_2_sd_n_sleep>; - }; - swr_master { compatible = "qcom,swr-wcd"; #address-cells = <2>; diff --git a/arch/arm/boot/dts/qcom/sdm660-cdp.dts b/arch/arm/boot/dts/qcom/sdm660-cdp.dts index 0a226fad698e..7b4b68af6188 100644 --- a/arch/arm/boot/dts/qcom/sdm660-cdp.dts +++ b/arch/arm/boot/dts/qcom/sdm660-cdp.dts @@ -15,6 +15,7 @@ #include "sdm660.dtsi" #include "sdm660-cdp.dtsi" +#include "sdm660-external-codec.dtsi" / { model = "Qualcomm Technologies, Inc. SDM 660 PM660 + PM660L CDP"; diff --git a/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi b/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi index 84292383b1b0..729e55ec9d6c 100644 --- a/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi @@ -88,6 +88,27 @@ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; }; +&dsi_dual_sharp_video { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + +&dsi_nt35597_truly_dsc_video { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + +&dsi_nt35597_truly_dsc_cmd { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + &sdhc_1 { /* device core power supply */ vdd-supply = <&pm660l_l4>; diff --git a/arch/arm/boot/dts/qcom/sdm660-external-codec.dtsi b/arch/arm/boot/dts/qcom/sdm660-external-codec.dtsi new file mode 100644 index 000000000000..1cea52f2b0dd --- /dev/null +++ b/arch/arm/boot/dts/qcom/sdm660-external-codec.dtsi @@ -0,0 +1,35 @@ +/* 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. + */ + +&cdc_pdm_gpios { + status = "disabled"; +}; + +&cdc_comp_gpios { + status = "disabled"; +}; + +&cdc_dmic_gpios { + status = "disabled"; +}; + +&cdc_sdw_gpios { + status = "disabled"; +}; + +&wsa_spkr_en1 { + status = "disabled"; +}; + +&wsa_spkr_en2 { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-cdp.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-cdp.dts index 6272e7eefe2f..c5d4504fd97e 100644 --- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-cdp.dts +++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-cdp.dts @@ -15,6 +15,7 @@ #include "sdm660.dtsi" #include "sdm660-cdp.dtsi" +#include "sdm660-internal-codec.dtsi" / { model = "Qualcomm Technologies, Inc. SDM 660 PM660 + PM660L Int. Audio Codec CDP"; @@ -24,74 +25,8 @@ <0x0001001b 0x0201011a 0x0 0x0>; }; -&slim_aud { - status = "disabled"; -}; - -&dai_slim { - status = "disabled"; -}; - -&wcd9335 { - status = "disabled"; -}; - -&wcd934x_cdc { - status = "disabled"; -}; - -&clock_audio { - status = "disabled"; -}; - -&wcd_rst_gpio { - status = "disabled"; -}; - -&wcd9xxx_intc { - status = "disabled"; -}; - -&tasha_snd { - status = "disabled"; -}; - -&tavil_snd { - status = "disabled"; -}; - -&spi_7 { - status = "disabled"; -}; - -&wdsp_mgr { - status = "disabled"; -}; - -&wdsp_glink { - status = "disabled"; -}; - -&glink_spi_xprt_wdsp { - status = "disabled"; -}; - -&glink_fifo_wdsp { - status = "disabled"; -}; - -&glink_qos_wdsp { - status = "disabled"; -}; - &int_codec { status = "okay"; -}; - -&pmic_analog_codec { - status = "okay"; -}; - -&msm_sdw_codec { - status = "okay"; + qcom,msm-hs-micbias-type = "internal"; + qcom,msm-micbias2-ext-cap; }; diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-mtp.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-mtp.dts index beedbe5676b1..9d5453240ef9 100644 --- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-mtp.dts +++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-mtp.dts @@ -15,6 +15,7 @@ #include "sdm660.dtsi" #include "sdm660-mtp.dtsi" +#include "sdm660-internal-codec.dtsi" / { model = "Qualcomm Technologies, Inc. SDM 660 PM660 + PM660L Int. Audio Codec MTP"; @@ -24,75 +25,7 @@ <0x0001001b 0x0201011a 0x0 0x0>; }; -&slim_aud { - status = "disabled"; -}; - -&dai_slim { - status = "disabled"; -}; - -&wcd9335 { - status = "disabled"; -}; - -&wcd934x_cdc { - status = "disabled"; -}; - -&clock_audio { - status = "disabled"; -}; - -&wcd_rst_gpio { - status = "disabled"; -}; - -&wcd9xxx_intc { - status = "disabled"; -}; - -&tasha_snd { - status = "disabled"; -}; - -&tavil_snd { - status = "disabled"; -}; - -&spi_7 { - status = "disabled"; -}; - -&wdsp_mgr { - status = "disabled"; -}; - -&wdsp_glink { - status = "disabled"; -}; - -&glink_spi_xprt_wdsp { - status = "disabled"; -}; - -&glink_fifo_wdsp { - status = "disabled"; -}; - -&glink_qos_wdsp { - status = "disabled"; -}; - &int_codec { qcom,model = "sdm660-snd-card-mtp"; status = "okay"; }; - -&pmic_analog_codec { - status = "okay"; -}; - -&msm_sdw_codec { - status = "okay"; -}; diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-cdp.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-cdp.dts index ec318a59561c..6990c299d4e2 100644 --- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-cdp.dts +++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-cdp.dts @@ -16,6 +16,7 @@ #include "sdm660.dtsi" #include "sdm660-cdp.dtsi" #include "msm-pm660a.dtsi" +#include "sdm660-internal-codec.dtsi" / { model = "Qualcomm Technologies, Inc. SDM 660 PM660 + PM660A Int. Audio Codec CDP"; @@ -24,74 +25,8 @@ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; }; -&slim_aud { - status = "disabled"; -}; - -&dai_slim { - status = "disabled"; -}; - -&wcd9335 { - status = "disabled"; -}; - -&wcd934x_cdc { - status = "disabled"; -}; - -&clock_audio { - status = "disabled"; -}; - -&wcd_rst_gpio { - status = "disabled"; -}; - -&wcd9xxx_intc { - status = "disabled"; -}; - -&tasha_snd { - status = "disabled"; -}; - -&tavil_snd { - status = "disabled"; -}; - -&spi_7 { - status = "disabled"; -}; - -&wdsp_mgr { - status = "disabled"; -}; - -&wdsp_glink { - status = "disabled"; -}; - -&glink_spi_xprt_wdsp { - status = "disabled"; -}; - -&glink_fifo_wdsp { - status = "disabled"; -}; - -&glink_qos_wdsp { - status = "disabled"; -}; - &int_codec { status = "okay"; -}; - -&pmic_analog_codec { - status = "okay"; -}; - -&msm_sdw_codec { - status = "okay"; + qcom,msm-hs-micbias-type = "internal"; + qcom,msm-micbias2-ext-cap; }; diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-mtp.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-mtp.dts index 4f4003220baf..d2ae22879ef4 100644 --- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-mtp.dts +++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-mtp.dts @@ -16,6 +16,7 @@ #include "sdm660.dtsi" #include "sdm660-mtp.dtsi" #include "msm-pm660a.dtsi" +#include "sdm660-internal-codec.dtsi" / { model = "Qualcomm Technologies, Inc. SDM 660 PM660 + PM660A Int. Audio Codec MTP"; @@ -24,74 +25,7 @@ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; }; -&slim_aud { - status = "disabled"; -}; - -&dai_slim { - status = "disabled"; -}; - -&wcd9335 { - status = "disabled"; -}; - -&wcd934x_cdc { - status = "disabled"; -}; - -&clock_audio { - status = "disabled"; -}; - -&wcd_rst_gpio { - status = "disabled"; -}; - -&wcd9xxx_intc { - status = "disabled"; -}; - -&tasha_snd { - status = "disabled"; -}; - -&tavil_snd { - status = "disabled"; -}; - -&spi_7 { - status = "disabled"; -}; - -&wdsp_mgr { - status = "disabled"; -}; - -&wdsp_glink { - status = "disabled"; -}; - -&glink_spi_xprt_wdsp { - status = "disabled"; -}; - -&glink_fifo_wdsp { - status = "disabled"; -}; - -&glink_qos_wdsp { - status = "disabled"; -}; - &int_codec { - status = "okay"; -}; - -&pmic_analog_codec { - status = "okay"; -}; - -&msm_sdw_codec { + qcom,model = "sdm660-snd-card-mtp"; status = "okay"; }; diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-rcm.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-rcm.dts index eda22eaa40ca..03b0e029a569 100644 --- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-rcm.dts +++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-rcm.dts @@ -16,6 +16,7 @@ #include "sdm660.dtsi" #include "sdm660-cdp.dtsi" #include "msm-pm660a.dtsi" +#include "sdm660-internal-codec.dtsi" / { model = "Qualcomm Technologies, Inc. SDM 660 PM660 + PM660A Int. Audio Codec RCM"; @@ -24,74 +25,8 @@ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; }; -&slim_aud { - status = "disabled"; -}; - -&dai_slim { - status = "disabled"; -}; - -&wcd9335 { - status = "disabled"; -}; - -&wcd934x_cdc { - status = "disabled"; -}; - -&clock_audio { - status = "disabled"; -}; - -&wcd_rst_gpio { - status = "disabled"; -}; - -&wcd9xxx_intc { - status = "disabled"; -}; - -&tasha_snd { - status = "disabled"; -}; - -&tavil_snd { - status = "disabled"; -}; - -&spi_7 { - status = "disabled"; -}; - -&wdsp_mgr { - status = "disabled"; -}; - -&wdsp_glink { - status = "disabled"; -}; - -&glink_spi_xprt_wdsp { - status = "disabled"; -}; - -&glink_fifo_wdsp { - status = "disabled"; -}; - -&glink_qos_wdsp { - status = "disabled"; -}; - &int_codec { status = "okay"; -}; - -&pmic_analog_codec { - status = "okay"; -}; - -&msm_sdw_codec { - status = "okay"; + qcom,msm-hs-micbias-type = "internal"; + qcom,msm-micbias2-ext-cap; }; diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-rcm.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-rcm.dts index 55958f3e31f6..fc79dc9a36ee 100644 --- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-rcm.dts +++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-rcm.dts @@ -15,6 +15,7 @@ #include "sdm660.dtsi" #include "sdm660-cdp.dtsi" +#include "sdm660-internal-codec.dtsi" / { model = "Qualcomm Technologies, Inc. SDM 660 PM660 + PM660L Int. Audio Codec RCM"; @@ -24,74 +25,8 @@ <0x0001001b 0x0201011a 0x0 0x0>; }; -&slim_aud { - status = "disabled"; -}; - -&dai_slim { - status = "disabled"; -}; - -&wcd9335 { - status = "disabled"; -}; - -&wcd934x_cdc { - status = "disabled"; -}; - -&clock_audio { - status = "disabled"; -}; - -&wcd_rst_gpio { - status = "disabled"; -}; - -&wcd9xxx_intc { - status = "disabled"; -}; - -&tasha_snd { - status = "disabled"; -}; - -&tavil_snd { - status = "disabled"; -}; - -&spi_7 { - status = "disabled"; -}; - -&wdsp_mgr { - status = "disabled"; -}; - -&wdsp_glink { - status = "disabled"; -}; - -&glink_spi_xprt_wdsp { - status = "disabled"; -}; - -&glink_fifo_wdsp { - status = "disabled"; -}; - -&glink_qos_wdsp { - status = "disabled"; -}; - &int_codec { status = "okay"; -}; - -&pmic_analog_codec { - status = "okay"; -}; - -&msm_sdw_codec { - status = "okay"; + qcom,msm-hs-micbias-type = "internal"; + qcom,msm-micbias2-ext-cap; }; diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec.dtsi b/arch/arm/boot/dts/qcom/sdm660-internal-codec.dtsi new file mode 100644 index 000000000000..512918966f6d --- /dev/null +++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec.dtsi @@ -0,0 +1,79 @@ +/* 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. + */ + +&slim_aud { + status = "disabled"; +}; + +&dai_slim { + status = "disabled"; +}; + +&wcd9335 { + status = "disabled"; +}; + +&wcd934x_cdc { + status = "disabled"; +}; + +&clock_audio { + status = "disabled"; +}; + +&wcd_rst_gpio { + status = "disabled"; +}; + +&wcd9xxx_intc { + status = "disabled"; +}; + +&tasha_snd { + status = "disabled"; +}; + +&tavil_snd { + status = "disabled"; +}; + +&spi_7 { + status = "disabled"; +}; + +&wdsp_mgr { + status = "disabled"; +}; + +&wdsp_glink { + status = "disabled"; +}; + +&glink_spi_xprt_wdsp { + status = "disabled"; +}; + +&glink_fifo_wdsp { + status = "disabled"; +}; + +&glink_qos_wdsp { + status = "disabled"; +}; + +&pmic_analog_codec { + status = "okay"; +}; + +&msm_sdw_codec { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/qcom/sdm660-lpi.dtsi b/arch/arm/boot/dts/qcom/sdm660-lpi.dtsi index 34946c07074b..195128f3ad43 100644 --- a/arch/arm/boot/dts/qcom/sdm660-lpi.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-lpi.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 @@ -47,31 +47,58 @@ cdc_pdm_gpios_active: cdc_pdm_gpios_active { mux { pins = "gpio18", "gpio19", - "gpio20", "gpio21", - "gpio23", "gpio25"; + "gpio21", "gpio23", + "gpio25"; function = "func1"; }; config { pins = "gpio18", "gpio19", - "gpio20", "gpio21", - "gpio23", "gpio25"; + "gpio21", "gpio23", + "gpio25"; drive-strength = <8>; + output-high; }; }; cdc_pdm_gpios_sleep: cdc_pdm_gpios_sleep { mux { pins = "gpio18", "gpio19", - "gpio20", "gpio21", - "gpio23", "gpio25"; + "gpio21", "gpio23", + "gpio25"; function = "func1"; }; config { pins = "gpio18", "gpio19", - "gpio20", "gpio21", - "gpio23", "gpio25"; + "gpio21", "gpio23", + "gpio25"; + drive-strength = <2>; + bias-disable; + output-low; + }; + }; + + cdc_pdm_2_gpios_active: cdc_pdm_2_gpios_active { + mux { + pins = "gpio20"; + function = "func1"; + }; + + config { + pins = "gpio20"; + drive-strength = <8>; + }; + }; + + cdc_pdm_2_gpios_sleep: cdc_pdm_2_gpios_sleep { + mux { + pins = "gpio20"; + function = "func1"; + }; + + config { + pins = "gpio20"; drive-strength = <2>; bias-disable; }; @@ -105,12 +132,11 @@ lpi_cdc_reset_active: lpi_cdc_reset_active { mux { pins = "gpio24"; - function = "func2"; + function = "gpio"; }; config { pins = "gpio24"; drive-strength = <16>; - bias-pull-down; output-high; }; }; @@ -118,7 +144,7 @@ lpi_cdc_reset_sleep: lpi_cdc_reset_sleep { mux { pins = "gpio24"; - function = "func2"; + function = "gpio"; }; config { diff --git a/arch/arm/boot/dts/qcom/sdm660-mdss-panels.dtsi b/arch/arm/boot/dts/qcom/sdm660-mdss-panels.dtsi index 25337fefcdb1..6407b32082f4 100644 --- a/arch/arm/boot/dts/qcom/sdm660-mdss-panels.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-mdss-panels.dtsi @@ -15,6 +15,9 @@ #include "dsi-panel-nt35597-truly-dualmipi-wqxga-video.dtsi" #include "dsi-panel-nt35597-truly-dualmipi-wqxga-cmd.dtsi" #include "dsi-panel-nt36850-truly-dualmipi-wqhd-cmd.dtsi" +#include "dsi-panel-sharp-dualmipi-wqxga-video.dtsi" +#include "dsi-panel-nt35597-truly-dsc-wqxga-video.dtsi" +#include "dsi-panel-nt35597-truly-dsc-wqxga-cmd.dtsi" &soc { dsi_panel_pwr_supply: dsi_panel_pwr_supply { @@ -90,3 +93,29 @@ 24 1f 08 09 05 03 04 a0 24 1c 08 09 05 03 04 a0]; }; + +&dsi_dual_sharp_video { + qcom,mdss-dsi-panel-timings-phy-v2 = [23 20 06 09 05 03 04 a0 + 23 20 06 09 05 03 04 a0 + 23 20 06 09 05 03 04 a0 + 23 20 06 09 05 03 04 a0 + 23 2e 06 08 05 03 04 a0]; +}; + +&dsi_nt35597_truly_dsc_video { + qcom,mdss-dsi-panel-timings-phy-v2 = [20 1d 05 07 03 03 04 a0 + 20 1d 05 07 03 03 04 a0 + 20 1d 05 07 03 03 04 a0 + 20 1d 05 07 03 03 04 a0 + 20 12 05 06 03 13 04 a0]; + qcom,config-select = <&dsi_nt35597_truly_dsc_video_config2>; +}; + +&dsi_nt35597_truly_dsc_cmd { + qcom,mdss-dsi-panel-timings-phy-v2 = [20 1d 05 07 03 03 04 a0 + 20 1d 05 07 03 03 04 a0 + 20 1d 05 07 03 03 04 a0 + 20 1d 05 07 03 03 04 a0 + 20 12 05 06 03 13 04 a0]; + qcom,config-select = <&dsi_nt35597_truly_dsc_cmd_config2>; +}; diff --git a/arch/arm/boot/dts/qcom/sdm660-mtp.dts b/arch/arm/boot/dts/qcom/sdm660-mtp.dts index 3e5a6e1a38b9..97058d470446 100644 --- a/arch/arm/boot/dts/qcom/sdm660-mtp.dts +++ b/arch/arm/boot/dts/qcom/sdm660-mtp.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -15,6 +15,7 @@ #include "sdm660.dtsi" #include "sdm660-mtp.dtsi" +#include "sdm660-external-codec.dtsi" / { model = "Qualcomm Technologies, Inc. SDM 660 PM660 + PM660L MTP"; diff --git a/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi b/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi index da44cb131b65..b35f66abfde5 100644 --- a/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi @@ -93,6 +93,27 @@ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; }; +&dsi_dual_sharp_video { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + +&dsi_nt35597_truly_dsc_video { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + +&dsi_nt35597_truly_dsc_cmd { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + &sdhc_1 { /* device core power supply */ vdd-supply = <&pm660l_l4>; diff --git a/arch/arm/boot/dts/qcom/sdm660-pm660a-cdp.dts b/arch/arm/boot/dts/qcom/sdm660-pm660a-cdp.dts index 7621c8aef432..0ce1ab440e92 100644 --- a/arch/arm/boot/dts/qcom/sdm660-pm660a-cdp.dts +++ b/arch/arm/boot/dts/qcom/sdm660-pm660a-cdp.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -16,6 +16,7 @@ #include "sdm660.dtsi" #include "sdm660-cdp.dtsi" #include "msm-pm660a.dtsi" +#include "sdm660-external-codec.dtsi" / { model = "Qualcomm Technologies, Inc. SDM 660 PM660 + PM660A CDP"; diff --git a/arch/arm/boot/dts/qcom/sdm660-pm660a-mtp.dts b/arch/arm/boot/dts/qcom/sdm660-pm660a-mtp.dts index 1ea6dbde11ce..25f7c1ba969c 100644 --- a/arch/arm/boot/dts/qcom/sdm660-pm660a-mtp.dts +++ b/arch/arm/boot/dts/qcom/sdm660-pm660a-mtp.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -16,6 +16,7 @@ #include "sdm660.dtsi" #include "sdm660-mtp.dtsi" #include "msm-pm660a.dtsi" +#include "sdm660-external-codec.dtsi" / { model = "Qualcomm Technologies, Inc. SDM 660 PM660 + PM660A MTP"; diff --git a/arch/arm/boot/dts/qcom/sdm660-pm660a-rcm.dts b/arch/arm/boot/dts/qcom/sdm660-pm660a-rcm.dts index 0b65b4a3631c..6c3afd4e1a4a 100644 --- a/arch/arm/boot/dts/qcom/sdm660-pm660a-rcm.dts +++ b/arch/arm/boot/dts/qcom/sdm660-pm660a-rcm.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -16,6 +16,7 @@ #include "sdm660.dtsi" #include "sdm660-cdp.dtsi" #include "msm-pm660a.dtsi" +#include "sdm660-external-codec.dtsi" / { model = "Qualcomm Technologies, Inc. SDM 660 PM660 + PM660A RCM"; diff --git a/arch/arm/boot/dts/qcom/sdm660-qrd.dtsi b/arch/arm/boot/dts/qcom/sdm660-qrd.dtsi index 6037bfd97fef..ab35515405de 100644 --- a/arch/arm/boot/dts/qcom/sdm660-qrd.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-qrd.dtsi @@ -120,6 +120,38 @@ }; }; +&tlmm { + pmx_ts_rst_active { + ts_rst_active: ts_rst_active { + mux { + pins = "gpio66"; + function = "gpio"; + }; + + config { + pins = "gpio66"; + drive-strength = <16>; + bias-pull-up; + }; + }; + }; + + pmx_ts_rst_suspend { + ts_rst_suspend: ts_rst_suspend { + mux { + pins = "gpio66"; + function = "gpio"; + }; + + config { + pins = "gpio66"; + drive-strength = <2>; + bias-pull-down; + }; + }; + }; +}; + &soc { gpio_keys { compatible = "gpio-keys"; @@ -135,6 +167,24 @@ debounce-interval = <15>; }; }; + + hbtp { + compatible = "qcom,hbtp-input"; + pinctrl-names = "pmx_ts_active", "pmx_ts_suspend"; + pinctrl-0 = <&ts_rst_active>; + pinctrl-1 = <&ts_rst_suspend>; + vcc_ana-supply = <&pm660l_l3>; + vcc_dig-supply = <&pm660_l13>; + qcom,afe-load = <20000>; + qcom,afe-vtg-min = <3008000>; + qcom,afe-vtg-max = <3008000>; + qcom,dig-load = <40000>; + qcom,dig-vtg-min = <1808000>; + qcom,dig-vtg-max = <1808000>; + qcom,fb-resume-delay-us = <10000>; + qcom,afe-power-on-delay-us = <1000>; + qcom,afe-power-off-delay-us = <6>; + }; }; / { diff --git a/arch/arm/boot/dts/qcom/sdm660-rcm.dts b/arch/arm/boot/dts/qcom/sdm660-rcm.dts index 63fa6c2d3c02..0fa148e82d43 100644 --- a/arch/arm/boot/dts/qcom/sdm660-rcm.dts +++ b/arch/arm/boot/dts/qcom/sdm660-rcm.dts @@ -15,6 +15,7 @@ #include "sdm660.dtsi" #include "sdm660-cdp.dtsi" +#include "sdm660-external-codec.dtsi" / { model = "Qualcomm Technologies, Inc. SDM 660 PM660 + PM660L RCM"; diff --git a/arch/arm/boot/dts/qcom/sdm660.dtsi b/arch/arm/boot/dts/qcom/sdm660.dtsi index 63e506875ebc..42db8c60f681 100644 --- a/arch/arm/boot/dts/qcom/sdm660.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660.dtsi @@ -1335,6 +1335,7 @@ qcom,ee = <0>; qcom,use-ipa-tethering-bridge; qcom,modem-cfg-emb-pipe-flt; + qcom,ipa-wdi2; qcom,msm-bus,name = "ipa"; qcom,msm-bus,num-cases = <4>; qcom,msm-bus,num-paths = <2>; @@ -1500,7 +1501,7 @@ dcc: dcc@10b3000 { compatible = "qcom,dcc"; reg = <0x10b3000 0x1000>, - <0x10b4000 0x800>; + <0x10b4000 0x2000>; reg-names = "dcc-base", "dcc-ram-base"; clocks = <&clock_gcc GCC_DCC_AHB_CLK>; diff --git a/arch/arm/configs/sdm660-perf_defconfig b/arch/arm/configs/sdm660-perf_defconfig index cd09f085e6af..a2584f6831e2 100644 --- a/arch/arm/configs/sdm660-perf_defconfig +++ b/arch/arm/configs/sdm660-perf_defconfig @@ -440,6 +440,7 @@ CONFIG_MMC_PERF_PROFILING=y CONFIG_MMC_PARANOID_SD_INIT=y CONFIG_MMC_CLKGATE=y CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BLOCK_DEFERRED_RESUME=y CONFIG_MMC_TEST=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y @@ -497,6 +498,7 @@ CONFIG_MSM_GLINK=y CONFIG_MSM_GLINK_LOOPBACK_SERVER=y CONFIG_MSM_GLINK_SMD_XPRT=y CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y +CONFIG_MSM_GLINK_SPI_XPRT=y CONFIG_MSM_SPCOM=y CONFIG_MSM_SMEM_LOGGING=y CONFIG_MSM_SMP2P=y diff --git a/arch/arm/configs/sdm660_defconfig b/arch/arm/configs/sdm660_defconfig index 8055774d9cdb..7ba3f7b4362f 100644 --- a/arch/arm/configs/sdm660_defconfig +++ b/arch/arm/configs/sdm660_defconfig @@ -441,6 +441,7 @@ CONFIG_MMC_PERF_PROFILING=y CONFIG_MMC_PARANOID_SD_INIT=y CONFIG_MMC_CLKGATE=y CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BLOCK_DEFERRED_RESUME=y CONFIG_MMC_TEST=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y @@ -501,6 +502,7 @@ CONFIG_MSM_GLINK=y CONFIG_MSM_GLINK_LOOPBACK_SERVER=y CONFIG_MSM_GLINK_SMD_XPRT=y CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y +CONFIG_MSM_GLINK_SPI_XPRT=y CONFIG_MSM_SPCOM=y CONFIG_MSM_SPSS_UTILS=y CONFIG_MSM_SMEM_LOGGING=y diff --git a/arch/arm64/configs/sdm660-perf_defconfig b/arch/arm64/configs/sdm660-perf_defconfig index 6a8b4aca2119..df5ce357294c 100644 --- a/arch/arm64/configs/sdm660-perf_defconfig +++ b/arch/arm64/configs/sdm660-perf_defconfig @@ -468,6 +468,7 @@ CONFIG_MMC=y CONFIG_MMC_PERF_PROFILING=y CONFIG_MMC_CLKGATE=y CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BLOCK_DEFERRED_RESUME=y CONFIG_MMC_TEST=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y @@ -509,6 +510,7 @@ CONFIG_MSM_MMCC_660=y CONFIG_CLOCK_CPU_OSM=y CONFIG_QCOM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_MSM_TIMER_LEAP=y CONFIG_IOMMU_IO_PGTABLE_FAST=y CONFIG_ARM_SMMU=y CONFIG_IOMMU_DEBUG=y diff --git a/arch/arm64/configs/sdm660_defconfig b/arch/arm64/configs/sdm660_defconfig index 1b3c96a28475..c959f1864256 100644 --- a/arch/arm64/configs/sdm660_defconfig +++ b/arch/arm64/configs/sdm660_defconfig @@ -470,6 +470,7 @@ CONFIG_MMC_PERF_PROFILING=y CONFIG_MMC_PARANOID_SD_INIT=y CONFIG_MMC_CLKGATE=y CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BLOCK_DEFERRED_RESUME=y CONFIG_MMC_TEST=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y @@ -518,6 +519,7 @@ CONFIG_MSM_MMCC_660=y CONFIG_CLOCK_CPU_OSM=y CONFIG_QCOM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y +CONFIG_MSM_TIMER_LEAP=y CONFIG_IOMMU_IO_PGTABLE_FAST=y CONFIG_IOMMU_IO_PGTABLE_FAST_SELFTEST=y CONFIG_ARM_SMMU=y diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index c9df86d68b44..eccd8c49ad69 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -590,6 +590,9 @@ static void armv8pmu_idle_update(struct arm_pmu *cpu_pmu) hw_events = this_cpu_ptr(cpu_pmu->hw_events); + if (!hw_events) + return; + for (idx = 0; idx < cpu_pmu->num_events; ++idx) { if (!test_bit(idx, hw_events->used_mask)) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 82caf98491fa..03429b18825b 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -304,7 +304,7 @@ static struct fastrpc_channel_ctx gcinfo[NUM_CHANNELS] = { }, { .name = "sdsprpc-smd", - .subsys = "dsps", + .subsys = "slpi", .channel = SMD_APPS_DSPS, .link.link_info.edge = "dsps", .link.link_info.transport = "smem", @@ -1528,10 +1528,11 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, } static int fastrpc_init_process(struct fastrpc_file *fl, - struct fastrpc_ioctl_init *init) + struct fastrpc_ioctl_init_attrs *uproc) { int err = 0; struct fastrpc_ioctl_invoke_attrs ioctl; + struct fastrpc_ioctl_init *init = &uproc->init; struct smq_phy_page pages[1]; struct fastrpc_mmap *file = 0, *mem = 0; if (init->flags == FASTRPC_INIT_ATTACH) { @@ -1550,14 +1551,16 @@ static int fastrpc_init_process(struct fastrpc_file *fl, if (err) goto bail; } else if (init->flags == FASTRPC_INIT_CREATE) { - remote_arg_t ra[4]; - int fds[4]; + remote_arg_t ra[6]; + int fds[6]; int mflags = 0; struct { int pgid; int namelen; int filelen; int pageslen; + int attrs; + int siglen; } inbuf; inbuf.pgid = current->tgid; inbuf.namelen = strlen(current->comm) + 1; @@ -1593,8 +1596,20 @@ static int fastrpc_init_process(struct fastrpc_file *fl, ra[3].buf.len = 1 * sizeof(*pages); fds[3] = 0; + inbuf.attrs = uproc->attrs; + ra[4].buf.pv = (void *)&(inbuf.attrs); + ra[4].buf.len = sizeof(inbuf.attrs); + fds[4] = 0; + + inbuf.siglen = uproc->siglen; + ra[5].buf.pv = (void *)&(inbuf.siglen); + ra[5].buf.len = sizeof(inbuf.siglen); + fds[5] = 0; + ioctl.inv.handle = 1; ioctl.inv.sc = REMOTE_SCALARS_MAKE(6, 4, 0); + if (uproc->attrs) + ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 6, 0); ioctl.inv.pra = ra; ioctl.fds = fds; ioctl.attrs = 0; @@ -2237,7 +2252,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, struct fastrpc_ioctl_invoke_attrs inv; struct fastrpc_ioctl_mmap mmap; struct fastrpc_ioctl_munmap munmap; - struct fastrpc_ioctl_init init; + struct fastrpc_ioctl_init_attrs init; struct fastrpc_ioctl_perf perf; } p; void *param = (char *)ioctl_param; @@ -2333,8 +2348,14 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, goto bail; break; case FASTRPC_IOCTL_INIT: - VERIFY(err, 0 == copy_from_user(&p.init, param, - sizeof(p.init))); + p.init.attrs = 0; + p.init.siglen = 0; + size = sizeof(struct fastrpc_ioctl_init); + /* fall through */ + case FASTRPC_IOCTL_INIT_ATTRS: + if (!size) + size = sizeof(struct fastrpc_ioctl_init_attrs); + VERIFY(err, 0 == copy_from_user(&p.init, param, size)); if (err) goto bail; VERIFY(err, 0 == fastrpc_init_process(fl, &p.init)); diff --git a/drivers/char/adsprpc_compat.c b/drivers/char/adsprpc_compat.c index a224ba7ed3e4..f7e84dd55606 100644 --- a/drivers/char/adsprpc_compat.c +++ b/drivers/char/adsprpc_compat.c @@ -34,6 +34,8 @@ _IOWR('R', 7, struct compat_fastrpc_ioctl_invoke_attrs) #define COMPAT_FASTRPC_IOCTL_GETPERF \ _IOWR('R', 9, struct compat_fastrpc_ioctl_perf) +#define COMPAT_FASTRPC_IOCTL_INIT_ATTRS \ + _IOWR('R', 10, struct compat_fastrpc_ioctl_init_attrs) struct compat_remote_buf { compat_uptr_t pv; /* buffer pointer */ @@ -85,6 +87,12 @@ struct compat_fastrpc_ioctl_init { compat_int_t memfd; /* ION fd for the mem */ }; +struct compat_fastrpc_ioctl_init_attrs { + struct compat_fastrpc_ioctl_init init; + compat_int_t attrs; /* attributes to init process */ + compat_int_t siglen; /* test signature file length */ +}; + struct compat_fastrpc_ioctl_perf { /* kernel performance data */ compat_uptr_t data; compat_int_t numkeys; @@ -246,28 +254,41 @@ static int compat_get_fastrpc_ioctl_perf( } static int compat_get_fastrpc_ioctl_init( - struct compat_fastrpc_ioctl_init __user *init32, - struct fastrpc_ioctl_init __user *init) + struct compat_fastrpc_ioctl_init_attrs __user *init32, + struct fastrpc_ioctl_init_attrs __user *init, + unsigned int cmd) { compat_uint_t u; compat_uptr_t p; compat_int_t i; int err; - err = get_user(u, &init32->flags); - err |= put_user(u, &init->flags); - err |= get_user(p, &init32->file); - err |= put_user(p, &init->file); - err |= get_user(i, &init32->filelen); - err |= put_user(i, &init->filelen); - err |= get_user(i, &init32->filefd); - err |= put_user(i, &init->filefd); - err |= get_user(p, &init32->mem); - err |= put_user(p, &init->mem); - err |= get_user(i, &init32->memlen); - err |= put_user(i, &init->memlen); - err |= get_user(i, &init32->memfd); - err |= put_user(i, &init->memfd); + err = get_user(u, &init32->init.flags); + err |= put_user(u, &init->init.flags); + err |= get_user(p, &init32->init.file); + err |= put_user(p, &init->init.file); + err |= get_user(i, &init32->init.filelen); + err |= put_user(i, &init->init.filelen); + err |= get_user(i, &init32->init.filefd); + err |= put_user(i, &init->init.filefd); + err |= get_user(p, &init32->init.mem); + err |= put_user(p, &init->init.mem); + err |= get_user(i, &init32->init.memlen); + err |= put_user(i, &init->init.memlen); + err |= get_user(i, &init32->init.memfd); + err |= put_user(i, &init->init.memfd); + + err |= put_user(0, &init->attrs); + if (cmd == COMPAT_FASTRPC_IOCTL_INIT_ATTRS) { + err |= get_user(i, &init32->attrs); + err |= put_user(i, (compat_uptr_t *)&init->attrs); + } + + err |= put_user(0, &init->siglen); + if (cmd == COMPAT_FASTRPC_IOCTL_INIT_ATTRS) { + err |= get_user(i, &init32->siglen); + err |= put_user(i, (compat_uptr_t *)&init->siglen); + } return err; } @@ -340,9 +361,11 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd, (unsigned long)unmap); } case COMPAT_FASTRPC_IOCTL_INIT: + /* fall through */ + case COMPAT_FASTRPC_IOCTL_INIT_ATTRS: { - struct compat_fastrpc_ioctl_init __user *init32; - struct fastrpc_ioctl_init __user *init; + struct compat_fastrpc_ioctl_init_attrs __user *init32; + struct fastrpc_ioctl_init_attrs __user *init; init32 = compat_ptr(arg); VERIFY(err, NULL != (init = compat_alloc_user_space( @@ -350,11 +373,11 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd, if (err) return -EFAULT; VERIFY(err, 0 == compat_get_fastrpc_ioctl_init(init32, - init)); + init, cmd)); if (err) return err; - return filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_INIT, - (unsigned long)init); + return filp->f_op->unlocked_ioctl(filp, + FASTRPC_IOCTL_INIT_ATTRS, (unsigned long)init); } case FASTRPC_IOCTL_GETINFO: { diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h index 9b24e2da489f..f686b0a1d6fa 100644 --- a/drivers/char/adsprpc_shared.h +++ b/drivers/char/adsprpc_shared.h @@ -26,6 +26,7 @@ _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_IOCTL_INIT_ATTRS _IOWR('R', 10, struct fastrpc_ioctl_init_attrs) #define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp" #define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp" @@ -158,6 +159,12 @@ struct fastrpc_ioctl_init { int32_t memfd; /* ION fd for the mem */ }; +struct fastrpc_ioctl_init_attrs { + struct fastrpc_ioctl_init init; + int attrs; + int siglen; +}; + struct fastrpc_ioctl_munmap { uintptr_t vaddrout; /* address to unmap */ ssize_t size; /* size */ diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index 7e63b7277d80..f8b08527d633 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-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 @@ -441,8 +441,10 @@ static void diag_close_logging_process(const int pid) driver->mask_clear = 1; mutex_unlock(&driver->diag_maskclear_mutex); + mutex_lock(&driver->diagchar_mutex); session_peripheral_mask = session_info->peripheral_mask; diag_md_session_close(session_info); + mutex_unlock(&driver->diagchar_mutex); for (i = 0; i < NUM_MD_SESSIONS; i++) if (MD_PERIPHERAL_MASK(i) & session_peripheral_mask) diag_mux_close_peripheral(DIAG_LOCAL_PROC, i); @@ -716,7 +718,7 @@ struct diag_cmd_reg_entry_t *diag_cmd_search( list_for_each_safe(start, temp, &driver->cmd_reg_list) { item = list_entry(start, struct diag_cmd_reg_t, link); - if (item == NULL || &item->entry == NULL) { + if (&item->entry == NULL) { pr_err("diag: In %s, unable to search command\n", __func__); return NULL; diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index c762a387068b..cba778b827ec 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014, 2016-2017, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -339,10 +339,11 @@ static unsigned long clk_debug_mux_measure_rate(struct clk_hw *hw) struct clk_debug_mux *meas = to_clk_measure(hw); struct measure_clk_data *data = meas->priv; - spin_lock_irqsave(&clk_reg_lock, flags); clk_prepare_enable(data->cxo); + spin_lock_irqsave(&clk_reg_lock, flags); + /* Enable CXO/4 and RINGOSC branch. */ regmap_read(meas->regmap[GCC], data->xo_div4_cbcr, &gcc_xo4_reg); gcc_xo4_reg |= BIT(0); @@ -376,10 +377,10 @@ static unsigned long clk_debug_mux_measure_rate(struct clk_hw *hw) ret = (raw_count_full * multiplier); } - clk_disable_unprepare(data->cxo); - spin_unlock_irqrestore(&clk_reg_lock, flags); + clk_disable_unprepare(data->cxo); + return ret; } diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c index ced75851d52f..076ff3565ef4 100644 --- a/drivers/clk/qcom/gcc-sdm660.c +++ b/drivers/clk/qcom/gcc-sdm660.c @@ -1132,6 +1132,7 @@ static struct clk_rcg2 usb30_master_clk_src = { }; static const struct freq_tbl ftbl_usb30_mock_utmi_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), F(40000000, P_PLL0_EARLY_DIV_CLK_SRC, 7.5, 0, 0), F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0), { } @@ -1763,19 +1764,6 @@ static struct clk_branch gcc_gpu_bimc_gfx_clk = { }, }; -static struct clk_branch gcc_gpu_bimc_gfx_src_clk = { - .halt_reg = 0x7100c, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0x7100c, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_gpu_bimc_gfx_src_clk", - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gpu_cfg_ahb_clk = { .halt_reg = 0x71004, .halt_check = BRANCH_VOTED, @@ -1835,19 +1823,6 @@ static struct clk_branch gcc_gpu_gpll0_div_clk = { }, }; -static struct clk_branch gcc_gpu_snoc_dvm_gfx_clk = { - .halt_reg = 0x71018, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0x71018, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_gpu_snoc_dvm_gfx_clk", - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_hmss_ahb_clk = { .halt_reg = 0x48000, .halt_check = BRANCH_HALT_VOTED, @@ -2675,11 +2650,9 @@ static struct clk_regmap *gcc_660_clocks[] = { [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, [GCC_GPU_BIMC_GFX_CLK] = &gcc_gpu_bimc_gfx_clk.clkr, - [GCC_GPU_BIMC_GFX_SRC_CLK] = &gcc_gpu_bimc_gfx_src_clk.clkr, [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr, [GCC_GPU_GPLL0_CLK] = &gcc_gpu_gpll0_clk.clkr, [GCC_GPU_GPLL0_DIV_CLK] = &gcc_gpu_gpll0_div_clk.clkr, - [GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr, [GCC_HMSS_AHB_CLK] = &gcc_hmss_ahb_clk.clkr, [GCC_HMSS_DVM_BUS_CLK] = &gcc_hmss_dvm_bus_clk.clkr, [GCC_HMSS_RBCPR_CLK] = &gcc_hmss_rbcpr_clk.clkr, @@ -2919,9 +2892,7 @@ static const char *const debug_mux_parent_names[] = { "gcc_gp2_clk", "gcc_gp3_clk", "gcc_gpu_bimc_gfx_clk", - "gcc_gpu_bimc_gfx_src_clk", "gcc_gpu_cfg_ahb_clk", - "gcc_gpu_snoc_dvm_gfx_clk", "gcc_hmss_ahb_clk", "gcc_hmss_dvm_bus_clk", "gcc_hmss_rbcpr_clk", @@ -3100,9 +3071,7 @@ static struct clk_debug_mux gcc_debug_mux = { { "gcc_gp2_clk", 0x0E0 }, { "gcc_gp3_clk", 0x0E1 }, { "gcc_gpu_bimc_gfx_clk", 0x13F }, - { "gcc_gpu_bimc_gfx_src_clk", 0x13E }, { "gcc_gpu_cfg_ahb_clk", 0x13B }, - { "gcc_gpu_snoc_dvm_gfx_clk", 0x141 }, { "gcc_hmss_ahb_clk", 0x0BA }, { "gcc_hmss_dvm_bus_clk", 0x0BF }, { "gcc_hmss_rbcpr_clk", 0x0BC }, diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index d3f65fa67ebd..ba20b8e42fbd 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -53,7 +53,7 @@ static ssize_t brightness_store(struct device *dev, if (ret) goto unlock; - if (state == LED_OFF) + if (state == LED_OFF && !(led_cdev->flags & LED_KEEP_TRIGGER)) led_trigger_remove(led_cdev); led_set_brightness(led_cdev, state); led_cdev->usr_brightness_req = state; diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c index aa59677c4b6a..b6aa4a87f31d 100644 --- a/drivers/leds/leds-qpnp-flash-v2.c +++ b/drivers/leds/leds-qpnp-flash-v2.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 @@ -1102,16 +1102,22 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on) int qpnp_flash_led_prepare(struct led_trigger *trig, int options, int *max_current) { - struct led_classdev *led_cdev = trigger_to_lcdev(trig); + struct led_classdev *led_cdev; struct flash_switch_data *snode; struct qpnp_flash_led *led; int rc; - if (!led_cdev) { + if (!trig) { pr_err("Invalid led_trigger provided\n"); return -EINVAL; } + led_cdev = trigger_to_lcdev(trig); + if (!led_cdev) { + pr_err("Invalid led_cdev in trigger %s\n", trig->name); + return -EINVAL; + } + snode = container_of(led_cdev, struct flash_switch_data, cdev); led = dev_get_drvdata(&snode->pdev->dev); @@ -1569,6 +1575,7 @@ static int qpnp_flash_led_parse_and_register_switch(struct qpnp_flash_led *led, snode->pdev = led->pdev; snode->cdev.brightness_set = qpnp_flash_led_brightness_set; snode->cdev.brightness_get = qpnp_flash_led_brightness_get; + snode->cdev.flags |= LED_KEEP_TRIGGER; rc = led_classdev_register(&led->pdev->dev, &snode->cdev); if (rc < 0) { pr_err("Unable to register led switch node\n"); diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c index bc6fb191b3b5..730f8b32ff1a 100644 --- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c +++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c @@ -299,8 +299,8 @@ static void msm_buf_mngr_sd_shutdown(struct msm_buf_mngr_device *dev, if (!list_empty(&dev->buf_qhead)) { list_for_each_entry_safe(bufs, save, &dev->buf_qhead, entry) { - pr_info("%s: Delete invalid bufs =%lx, session_id=%u, bufs->ses_id=%d, str_id=%d, idx=%d\n", - __func__, (unsigned long)bufs, session->session, + pr_info("%s: Delete invalid bufs =%pK, session_id=%u, bufs->ses_id=%d, str_id=%d, idx=%d\n", + __func__, (void *)bufs, session->session, bufs->session_id, bufs->stream_id, bufs->index); if (session->session == bufs->session_id) { diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig index 6142ec1b9dfb..91f2445b6ac8 100644 --- a/drivers/mmc/card/Kconfig +++ b/drivers/mmc/card/Kconfig @@ -50,6 +50,17 @@ config MMC_BLOCK_BOUNCE If unsure, say Y here. +config MMC_BLOCK_DEFERRED_RESUME + bool "Defer MMC layer resume until I/O is requested" + depends on MMC_BLOCK + default n + help + Say Y here to enable deferred MMC resume until I/O + is requested. + + This will reduce overall resume latency and + save power when there is an SD card inserted but not being used. + config SDIO_UART tristate "SDIO UART/GPS class support" depends on TTY diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 71154ec99d3c..13b79438af1c 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -1051,6 +1051,10 @@ int arm_pmu_device_probe(struct platform_device *pdev, pmu->plat_device = pdev; + ret = cpu_pmu_init(pmu); + if (ret) + goto out_free; + if (node && (of_id = of_match_node(of_table, pdev->dev.of_node))) { init_fn = of_id->data; @@ -1073,13 +1077,9 @@ int arm_pmu_device_probe(struct platform_device *pdev, if (ret) { pr_info("%s: failed to probe PMU!\n", of_node_full_name(node)); - goto out_free; + goto out_destroy; } - ret = cpu_pmu_init(pmu); - if (ret) - goto out_free; - ret = perf_pmu_register(&pmu->pmu, pmu->name, -1); if (ret) goto out_destroy; diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa.c b/drivers/platform/msm/ipa/ipa_v2/ipa.c index d82651f7b492..09ec8458fcad 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -733,7 +733,8 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - if (ipa2_del_hdr((struct ipa_ioc_del_hdr *)param)) { + if (ipa2_del_hdr_by_user((struct ipa_ioc_del_hdr *)param, + true)) { retval = -EFAULT; break; } @@ -1417,8 +1418,8 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - if (ipa2_del_hdr_proc_ctx( - (struct ipa_ioc_del_hdr_proc_ctx *)param)) { + if (ipa2_del_hdr_proc_ctx_by_user( + (struct ipa_ioc_del_hdr_proc_ctx *)param, true)) { retval = -EFAULT; break; } @@ -2715,7 +2716,7 @@ fail_schedule_delayed_work: if (ipa_ctx->dflt_v4_rt_rule_hdl) __ipa_del_rt_rule(ipa_ctx->dflt_v4_rt_rule_hdl); if (ipa_ctx->excp_hdr_hdl) - __ipa_del_hdr(ipa_ctx->excp_hdr_hdl); + __ipa_del_hdr(ipa_ctx->excp_hdr_hdl, false); ipa2_teardown_sys_pipe(ipa_ctx->clnt_hdl_cmd); fail_cmd: return result; @@ -2727,7 +2728,7 @@ static void ipa_teardown_apps_pipes(void) ipa2_teardown_sys_pipe(ipa_ctx->clnt_hdl_data_in); __ipa_del_rt_rule(ipa_ctx->dflt_v6_rt_rule_hdl); __ipa_del_rt_rule(ipa_ctx->dflt_v4_rt_rule_hdl); - __ipa_del_hdr(ipa_ctx->excp_hdr_hdl); + __ipa_del_hdr(ipa_ctx->excp_hdr_hdl, false); ipa2_teardown_sys_pipe(ipa_ctx->clnt_hdl_cmd); } diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c index 40d42e1775a9..51f34f0d5101 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -741,7 +741,8 @@ error: return -EPERM; } -static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr) +static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl, + bool release_hdr, bool by_user) { struct ipa_hdr_proc_ctx_entry *entry; struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl; @@ -755,6 +756,14 @@ static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr) IPADBG("del ctx proc cnt=%d ofst=%d\n", htbl->proc_ctx_cnt, entry->offset_entry->offset); + if (by_user && entry->user_deleted) { + IPAERR("proc_ctx already deleted by user\n"); + return -EINVAL; + } + + if (by_user) + entry->user_deleted = true; + if (--entry->ref_cnt) { IPADBG("proc_ctx_hdl %x ref_cnt %d\n", proc_ctx_hdl, entry->ref_cnt); @@ -762,7 +771,7 @@ static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr) } if (release_hdr) - __ipa_del_hdr(entry->hdr->id); + __ipa_del_hdr(entry->hdr->id, false); /* move the offset entry to appropriate free list */ list_move(&entry->offset_entry->link, @@ -779,7 +788,7 @@ static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr) } -int __ipa_del_hdr(u32 hdr_hdl) +int __ipa_del_hdr(u32 hdr_hdl, bool by_user) { struct ipa_hdr_entry *entry; struct ipa_hdr_tbl *htbl = &ipa_ctx->hdr_tbl; @@ -790,7 +799,7 @@ int __ipa_del_hdr(u32 hdr_hdl) return -EINVAL; } - if (!entry || (entry->cookie != IPA_COOKIE)) { + if (entry->cookie != IPA_COOKIE) { IPAERR("bad parm\n"); return -EINVAL; } @@ -802,6 +811,14 @@ int __ipa_del_hdr(u32 hdr_hdl) IPADBG("del hdr of sz=%d hdr_cnt=%d ofst=%d\n", entry->hdr_len, htbl->hdr_cnt, entry->offset_entry->offset); + if (by_user && entry->user_deleted) { + IPAERR("hdr already deleted by user\n"); + return -EINVAL; + } + + if (by_user) + entry->user_deleted = true; + if (--entry->ref_cnt) { IPADBG("hdr_hdl %x ref_cnt %d\n", hdr_hdl, entry->ref_cnt); return 0; @@ -812,7 +829,7 @@ int __ipa_del_hdr(u32 hdr_hdl) entry->phys_base, entry->hdr_len, DMA_TO_DEVICE); - __ipa_del_hdr_proc_ctx(entry->proc_ctx->id, false); + __ipa_del_hdr_proc_ctx(entry->proc_ctx->id, false, false); } else { /* move the offset entry to appropriate free list */ list_move(&entry->offset_entry->link, @@ -879,15 +896,16 @@ bail: } /** - * ipa2_del_hdr() - Remove the specified headers from SW and optionally commit them - * to IPA HW + * ipa2_del_hdr_by_user() - Remove the specified headers + * from SW and optionally commit them to IPA HW * @hdls: [inout] set of headers to delete + * @by_user: Operation requested by user? * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ -int ipa2_del_hdr(struct ipa_ioc_del_hdr *hdls) +int ipa2_del_hdr_by_user(struct ipa_ioc_del_hdr *hdls, bool by_user) { int i; int result = -EFAULT; @@ -904,7 +922,7 @@ int ipa2_del_hdr(struct ipa_ioc_del_hdr *hdls) mutex_lock(&ipa_ctx->lock); for (i = 0; i < hdls->num_hdls; i++) { - if (__ipa_del_hdr(hdls->hdl[i].hdl)) { + if (__ipa_del_hdr(hdls->hdl[i].hdl, by_user)) { IPAERR("failed to del hdr %i\n", i); hdls->hdl[i].status = -1; } else { @@ -925,6 +943,20 @@ bail: } /** + * ipa2_del_hdr() - Remove the specified headers from SW + * and optionally commit them to IPA HW + * @hdls: [inout] set of headers to delete + * + * Returns: 0 on success, negative on failure + * + * Note: Should not be called from atomic context + */ +int ipa2_del_hdr(struct ipa_ioc_del_hdr *hdls) +{ + return ipa2_del_hdr_by_user(hdls, false); +} + +/** * ipa2_add_hdr_proc_ctx() - add the specified headers to SW * and optionally commit them to IPA HW * @proc_ctxs: [inout] set of processing context headers to add @@ -976,16 +1008,18 @@ bail: } /** - * ipa2_del_hdr_proc_ctx() - + * ipa2_del_hdr_proc_ctx_by_user() - * Remove the specified processing context headers from SW and * optionally commit them to IPA HW. * @hdls: [inout] set of processing context headers to delete + * @by_user: Operation requested by user? * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ -int ipa2_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls) +int ipa2_del_hdr_proc_ctx_by_user(struct ipa_ioc_del_hdr_proc_ctx *hdls, + bool by_user) { int i; int result; @@ -1004,7 +1038,7 @@ int ipa2_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls) mutex_lock(&ipa_ctx->lock); for (i = 0; i < hdls->num_hdls; i++) { - if (__ipa_del_hdr_proc_ctx(hdls->hdl[i].hdl, true)) { + if (__ipa_del_hdr_proc_ctx(hdls->hdl[i].hdl, true, by_user)) { IPAERR("failed to del hdr %i\n", i); hdls->hdl[i].status = -1; } else { @@ -1025,6 +1059,21 @@ bail: } /** + * ipa2_del_hdr_proc_ctx() - + * Remove the specified processing context headers from SW and + * optionally commit them to IPA HW. + * @hdls: [inout] set of processing context headers to delete + * + * Returns: 0 on success, negative on failure + * + * Note: Should not be called from atomic context + */ +int ipa2_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls) +{ + return ipa2_del_hdr_proc_ctx_by_user(hdls, false); +} + +/** * ipa2_commit_hdr() - commit to IPA HW the current header table in SW * * Returns: 0 on success, negative on failure @@ -1252,7 +1301,7 @@ int __ipa_release_hdr(u32 hdr_hdl) { int result = 0; - if (__ipa_del_hdr(hdr_hdl)) { + if (__ipa_del_hdr(hdr_hdl, false)) { IPADBG("fail to del hdr %x\n", hdr_hdl); result = -EFAULT; goto bail; @@ -1280,7 +1329,7 @@ int __ipa_release_hdr_proc_ctx(u32 proc_ctx_hdl) { int result = 0; - if (__ipa_del_hdr_proc_ctx(proc_ctx_hdl, true)) { + if (__ipa_del_hdr_proc_ctx(proc_ctx_hdl, true, false)) { IPADBG("fail to del hdr %x\n", proc_ctx_hdl); result = -EFAULT; goto bail; diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h index 967036a25746..2c2a9c617b16 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h @@ -281,6 +281,7 @@ struct ipa_rt_tbl { * @id: header entry id * @is_eth2_ofst_valid: is eth2_ofst field valid? * @eth2_ofst: offset to start of Ethernet-II/802.3 header + * @user_deleted: is the header deleted by the user? */ struct ipa_hdr_entry { struct list_head link; @@ -298,6 +299,7 @@ struct ipa_hdr_entry { int id; u8 is_eth2_ofst_valid; u16 eth2_ofst; + bool user_deleted; }; /** @@ -361,6 +363,7 @@ struct ipa_hdr_proc_ctx_add_hdr_cmd_seq { * @cookie: cookie used for validity check * @ref_cnt: reference counter of routing table * @id: processing context header entry id + * @user_deleted: is the hdr processing context deleted by the user? */ struct ipa_hdr_proc_ctx_entry { struct list_head link; @@ -370,6 +373,7 @@ struct ipa_hdr_proc_ctx_entry { u32 cookie; u32 ref_cnt; int id; + bool user_deleted; }; /** @@ -1400,6 +1404,8 @@ int ipa2_add_hdr(struct ipa_ioc_add_hdr *hdrs); int ipa2_del_hdr(struct ipa_ioc_del_hdr *hdls); +int ipa2_del_hdr_by_user(struct ipa_ioc_del_hdr *hdls, bool by_user); + int ipa2_commit_hdr(void); int ipa2_reset_hdr(void); @@ -1417,6 +1423,9 @@ int ipa2_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs); int ipa2_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls); +int ipa2_del_hdr_proc_ctx_by_user(struct ipa_ioc_del_hdr_proc_ctx *hdls, + bool by_user); + /* * Routing */ @@ -1709,7 +1718,7 @@ int ipa2_active_clients_log_print_table(char *buf, int size); void ipa2_active_clients_log_clear(void); int ipa_interrupts_init(u32 ipa_irq, u32 ee, struct device *ipa_dev); int __ipa_del_rt_rule(u32 rule_hdl); -int __ipa_del_hdr(u32 hdr_hdl); +int __ipa_del_hdr(u32 hdr_hdl, bool by_user); int __ipa_release_hdr(u32 hdr_hdl); int __ipa_release_hdr_proc_ctx(u32 proc_ctx_hdl); int _ipa_read_gen_reg_v1_1(char *buff, int max_len); diff --git a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa_fd_ioctl.c b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa_fd_ioctl.c index 64d5c488310b..46bfe021eb4b 100644 --- a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa_fd_ioctl.c +++ b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa_fd_ioctl.c @@ -251,8 +251,9 @@ static long wan_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; } - if (rmnet_ipa_reset_tethering_stats(NULL)) { - IPAWANERR("WAN_IOC_QUERY_TETHER_STATS failed\n"); + if (rmnet_ipa_reset_tethering_stats( + (struct wan_ioctl_reset_tether_stats *)param)) { + IPAWANERR("WAN_IOC_RESET_TETHER_STATS failed\n"); retval = -EFAULT; break; } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 3d276b0f535d..2da3b0ddca8f 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -784,7 +784,8 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - if (ipa3_del_hdr((struct ipa_ioc_del_hdr *)param)) { + if (ipa3_del_hdr_by_user((struct ipa_ioc_del_hdr *)param, + true)) { retval = -EFAULT; break; } @@ -1553,8 +1554,8 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - if (ipa3_del_hdr_proc_ctx( - (struct ipa_ioc_del_hdr_proc_ctx *)param)) { + if (ipa3_del_hdr_proc_ctx_by_user( + (struct ipa_ioc_del_hdr_proc_ctx *)param, true)) { retval = -EFAULT; break; } @@ -2921,7 +2922,7 @@ fail_schedule_delayed_work: if (ipa3_ctx->dflt_v4_rt_rule_hdl) __ipa3_del_rt_rule(ipa3_ctx->dflt_v4_rt_rule_hdl); if (ipa3_ctx->excp_hdr_hdl) - __ipa3_del_hdr(ipa3_ctx->excp_hdr_hdl); + __ipa3_del_hdr(ipa3_ctx->excp_hdr_hdl, false); ipa3_teardown_sys_pipe(ipa3_ctx->clnt_hdl_cmd); fail_cmd: return result; @@ -2933,7 +2934,7 @@ static void ipa3_teardown_apps_pipes(void) ipa3_teardown_sys_pipe(ipa3_ctx->clnt_hdl_data_in); __ipa3_del_rt_rule(ipa3_ctx->dflt_v6_rt_rule_hdl); __ipa3_del_rt_rule(ipa3_ctx->dflt_v4_rt_rule_hdl); - __ipa3_del_hdr(ipa3_ctx->excp_hdr_hdl); + __ipa3_del_hdr(ipa3_ctx->excp_hdr_hdl, false); ipa3_teardown_sys_pipe(ipa3_ctx->clnt_hdl_cmd); } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c index 93fa1492cfd5..69dca7666346 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -576,7 +576,8 @@ error: return -EPERM; } -static int __ipa3_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr) +static int __ipa3_del_hdr_proc_ctx(u32 proc_ctx_hdl, + bool release_hdr, bool by_user) { struct ipa3_hdr_proc_ctx_entry *entry; struct ipa3_hdr_proc_ctx_tbl *htbl = &ipa3_ctx->hdr_proc_ctx_tbl; @@ -590,6 +591,14 @@ static int __ipa3_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr) IPADBG("del proc ctx cnt=%d ofst=%d\n", htbl->proc_ctx_cnt, entry->offset_entry->offset); + if (by_user && entry->user_deleted) { + IPAERR("proc_ctx already deleted by user\n"); + return -EINVAL; + } + + if (by_user) + entry->user_deleted = true; + if (--entry->ref_cnt) { IPADBG("proc_ctx_hdl %x ref_cnt %d\n", proc_ctx_hdl, entry->ref_cnt); @@ -597,7 +606,7 @@ static int __ipa3_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr) } if (release_hdr) - __ipa3_del_hdr(entry->hdr->id); + __ipa3_del_hdr(entry->hdr->id, false); /* move the offset entry to appropriate free list */ list_move(&entry->offset_entry->link, @@ -614,7 +623,7 @@ static int __ipa3_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr) } -int __ipa3_del_hdr(u32 hdr_hdl) +int __ipa3_del_hdr(u32 hdr_hdl, bool by_user) { struct ipa3_hdr_entry *entry; struct ipa3_hdr_tbl *htbl = &ipa3_ctx->hdr_tbl; @@ -625,7 +634,7 @@ int __ipa3_del_hdr(u32 hdr_hdl) return -EINVAL; } - if (!entry || (entry->cookie != IPA_COOKIE)) { + if (entry->cookie != IPA_COOKIE) { IPAERR("bad parm\n"); return -EINVAL; } @@ -638,6 +647,14 @@ int __ipa3_del_hdr(u32 hdr_hdl) entry->hdr_len, htbl->hdr_cnt, entry->offset_entry->offset); + if (by_user && entry->user_deleted) { + IPAERR("proc_ctx already deleted by user\n"); + return -EINVAL; + } + + if (by_user) + entry->user_deleted = true; + if (--entry->ref_cnt) { IPADBG("hdr_hdl %x ref_cnt %d\n", hdr_hdl, entry->ref_cnt); return 0; @@ -648,7 +665,7 @@ int __ipa3_del_hdr(u32 hdr_hdl) entry->phys_base, entry->hdr_len, DMA_TO_DEVICE); - __ipa3_del_hdr_proc_ctx(entry->proc_ctx->id, false); + __ipa3_del_hdr_proc_ctx(entry->proc_ctx->id, false, false); } else { /* move the offset entry to appropriate free list */ list_move(&entry->offset_entry->link, @@ -710,15 +727,16 @@ bail: } /** - * ipa3_del_hdr() - Remove the specified headers from SW and optionally commit them - * to IPA HW + * ipa3_del_hdr_by_user() - Remove the specified headers + * from SW and optionally commit them to IPA HW * @hdls: [inout] set of headers to delete + * @by_user: Operation requested by user? * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ -int ipa3_del_hdr(struct ipa_ioc_del_hdr *hdls) +int ipa3_del_hdr_by_user(struct ipa_ioc_del_hdr *hdls, bool by_user) { int i; int result = -EFAULT; @@ -730,7 +748,7 @@ int ipa3_del_hdr(struct ipa_ioc_del_hdr *hdls) mutex_lock(&ipa3_ctx->lock); for (i = 0; i < hdls->num_hdls; i++) { - if (__ipa3_del_hdr(hdls->hdl[i].hdl)) { + if (__ipa3_del_hdr(hdls->hdl[i].hdl, by_user)) { IPAERR("failed to del hdr %i\n", i); hdls->hdl[i].status = -1; } else { @@ -751,6 +769,20 @@ bail: } /** + * ipa3_del_hdr() - Remove the specified headers from SW + * and optionally commit them to IPA HW + * @hdls: [inout] set of headers to delete + * + * Returns: 0 on success, negative on failure + * + * Note: Should not be called from atomic context + */ +int ipa3_del_hdr(struct ipa_ioc_del_hdr *hdls) +{ + return ipa3_del_hdr_by_user(hdls, false); +} + +/** * ipa3_add_hdr_proc_ctx() - add the specified headers to SW * and optionally commit them to IPA HW * @proc_ctxs: [inout] set of processing context headers to add @@ -795,16 +827,18 @@ bail: } /** - * ipa3_del_hdr_proc_ctx() - + * ipa3_del_hdr_proc_ctx_by_user() - * Remove the specified processing context headers from SW and * optionally commit them to IPA HW. * @hdls: [inout] set of processing context headers to delete + * @by_user: Operation requested by user? * * Returns: 0 on success, negative on failure * * Note: Should not be called from atomic context */ -int ipa3_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls) +int ipa3_del_hdr_proc_ctx_by_user(struct ipa_ioc_del_hdr_proc_ctx *hdls, + bool by_user) { int i; int result; @@ -816,7 +850,7 @@ int ipa3_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls) mutex_lock(&ipa3_ctx->lock); for (i = 0; i < hdls->num_hdls; i++) { - if (__ipa3_del_hdr_proc_ctx(hdls->hdl[i].hdl, true)) { + if (__ipa3_del_hdr_proc_ctx(hdls->hdl[i].hdl, true, by_user)) { IPAERR("failed to del hdr %i\n", i); hdls->hdl[i].status = -1; } else { @@ -837,6 +871,21 @@ bail: } /** + * ipa3_del_hdr_proc_ctx() - + * Remove the specified processing context headers from SW and + * optionally commit them to IPA HW. + * @hdls: [inout] set of processing context headers to delete + * + * Returns: 0 on success, negative on failure + * + * Note: Should not be called from atomic context + */ +int ipa3_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls) +{ + return ipa3_del_hdr_proc_ctx_by_user(hdls, false); +} + +/** * ipa3_commit_hdr() - commit to IPA HW the current header table in SW * * Returns: 0 on success, negative on failure @@ -1064,7 +1113,7 @@ int __ipa3_release_hdr(u32 hdr_hdl) { int result = 0; - if (__ipa3_del_hdr(hdr_hdl)) { + if (__ipa3_del_hdr(hdr_hdl, false)) { IPADBG("fail to del hdr %x\n", hdr_hdl); result = -EFAULT; goto bail; @@ -1092,7 +1141,7 @@ int __ipa3_release_hdr_proc_ctx(u32 proc_ctx_hdl) { int result = 0; - if (__ipa3_del_hdr_proc_ctx(proc_ctx_hdl, true)) { + if (__ipa3_del_hdr_proc_ctx(proc_ctx_hdl, true, false)) { IPADBG("fail to del hdr %x\n", proc_ctx_hdl); result = -EFAULT; goto bail; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index fe7c88a25374..b3ce52424fec 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -279,6 +279,7 @@ struct ipa3_rt_tbl { * @id: header entry id * @is_eth2_ofst_valid: is eth2_ofst field valid? * @eth2_ofst: offset to start of Ethernet-II/802.3 header + * @user_deleted: is the header deleted by the user? */ struct ipa3_hdr_entry { struct list_head link; @@ -296,6 +297,7 @@ struct ipa3_hdr_entry { int id; u8 is_eth2_ofst_valid; u16 eth2_ofst; + bool user_deleted; }; /** @@ -335,6 +337,7 @@ struct ipa3_hdr_proc_ctx_offset_entry { * @cookie: cookie used for validity check * @ref_cnt: reference counter of routing table * @id: processing context header entry id + * @user_deleted: is the hdr processing context deleted by the user? */ struct ipa3_hdr_proc_ctx_entry { struct list_head link; @@ -344,6 +347,7 @@ struct ipa3_hdr_proc_ctx_entry { u32 cookie; u32 ref_cnt; int id; + bool user_deleted; }; /** @@ -1548,6 +1552,8 @@ int ipa3_add_hdr(struct ipa_ioc_add_hdr *hdrs); int ipa3_del_hdr(struct ipa_ioc_del_hdr *hdls); +int ipa3_del_hdr_by_user(struct ipa_ioc_del_hdr *hdls, bool by_user); + int ipa3_commit_hdr(void); int ipa3_reset_hdr(void); @@ -1565,6 +1571,9 @@ int ipa3_add_hdr_proc_ctx(struct ipa_ioc_add_hdr_proc_ctx *proc_ctxs); int ipa3_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls); +int ipa3_del_hdr_proc_ctx_by_user(struct ipa_ioc_del_hdr_proc_ctx *hdls, + bool by_user); + /* * Routing */ @@ -1869,7 +1878,7 @@ int ipa3_active_clients_log_print_table(char *buf, int size); void ipa3_active_clients_log_clear(void); int ipa3_interrupts_init(u32 ipa_irq, u32 ee, struct device *ipa_dev); int __ipa3_del_rt_rule(u32 rule_hdl); -int __ipa3_del_hdr(u32 hdr_hdl); +int __ipa3_del_hdr(u32 hdr_hdl, bool by_user); int __ipa3_release_hdr(u32 hdr_hdl); int __ipa3_release_hdr_proc_ctx(u32 proc_ctx_hdl); int _ipa_read_ep_reg_v3_0(char *buf, int max_len, int pipe); diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c index 8523efa1a4ab..a441ff310e9f 100644 --- a/drivers/power/supply/qcom/qpnp-fg-gen3.c +++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c @@ -2543,6 +2543,9 @@ static int fg_psy_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_SOC_REPORTING_READY: pval->intval = chip->soc_reporting_ready; break; + case POWER_SUPPLY_PROP_DEBUG_BATTERY: + pval->intval = is_debug_batt_id(chip); + break; default: pr_err("unsupported property %d\n", psp); rc = -EINVAL; @@ -2641,6 +2644,7 @@ static enum power_supply_property fg_psy_props[] = { POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, POWER_SUPPLY_PROP_SOC_REPORTING_READY, + POWER_SUPPLY_PROP_DEBUG_BATTERY, }; static const struct power_supply_desc fg_psy_desc = { @@ -2977,6 +2981,9 @@ enable_bmd: if (rc < 0) pr_err("Error in enabling BMD, rc=%d\n", rc); + if (chip->fg_psy) + power_supply_changed(chip->fg_psy); + return IRQ_HANDLED; } diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index 98a917273328..4a12af466c36 100644 --- a/drivers/power/supply/qcom/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -1468,7 +1468,10 @@ static int smb2_setup_wa_flags(struct smb2 *chip) static int smb2_determine_initial_status(struct smb2 *chip) { struct smb_irq_data irq_data = {chip, "determine-initial-status"}; + struct smb_charger *chg = &chip->chg; + if (chg->bms_psy) + smblib_suspend_on_debug_battery(chg); smblib_handle_usb_plugin(0, &irq_data); smblib_handle_usb_typec_change(0, &irq_data); smblib_handle_usb_source_change(0, &irq_data); diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index 9728490736ff..d3f7e43ea10e 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -532,7 +532,7 @@ static int smblib_notifier_call(struct notifier_block *nb, if (!strcmp(psy->desc->name, "bms")) { if (!chg->bms_psy) chg->bms_psy = psy; - if (ev == PSY_EVENT_PROP_CHANGED && chg->batt_psy) + if (ev == PSY_EVENT_PROP_CHANGED) schedule_work(&chg->bms_update_work); } @@ -642,6 +642,24 @@ static bool smblib_sysok_reason_usbin(struct smb_charger *chg) return stat & SYSOK_REASON_USBIN_BIT; } +void smblib_suspend_on_debug_battery(struct smb_charger *chg) +{ + int rc; + union power_supply_propval val; + + rc = power_supply_get_property(chg->bms_psy, + POWER_SUPPLY_PROP_DEBUG_BATTERY, &val); + if (rc < 0) { + smblib_err(chg, "Couldn't get debug battery prop rc=%d\n", rc); + return; + } + + vote(chg->usb_suspend_votable, DEBUG_BOARD_VOTER, val.intval, 0); + vote(chg->dc_suspend_votable, DEBUG_BOARD_VOTER, val.intval, 0); + if (val.intval) + pr_info("Input suspended: Fake battery\n"); +} + /********************* * VOTABLE CALLBACKS * *********************/ @@ -3299,7 +3317,11 @@ static void bms_update_work(struct work_struct *work) { struct smb_charger *chg = container_of(work, struct smb_charger, bms_update_work); - power_supply_changed(chg->batt_psy); + + smblib_suspend_on_debug_battery(chg); + + if (chg->batt_psy) + power_supply_changed(chg->batt_psy); } static void step_soc_req_work(struct work_struct *work) diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index efce7eb987ab..c5d014193fd6 100644 --- a/drivers/power/supply/qcom/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h @@ -51,6 +51,7 @@ enum print_reason { #define BOOST_BACK_VOTER "BOOST_BACK_VOTER" #define HVDCP_INDIRECT_VOTER "HVDCP_INDIRECT_VOTER" #define MICRO_USB_VOTER "MICRO_USB_VOTER" +#define DEBUG_BOARD_VOTER "DEBUG_BOARD_VOTER" #define VCONN_MAX_ATTEMPTS 3 #define OTG_MAX_ATTEMPTS 3 @@ -383,6 +384,7 @@ int smblib_get_prop_slave_current_now(struct smb_charger *chg, union power_supply_propval *val); int smblib_set_prop_ship_mode(struct smb_charger *chg, const union power_supply_propval *val); +void smblib_suspend_on_debug_battery(struct smb_charger *chg); int smblib_init(struct smb_charger *chg); int smblib_deinit(struct smb_charger *chg); diff --git a/drivers/regulator/cpr3-util.c b/drivers/regulator/cpr3-util.c index 120ca69e100f..7f712d4f6ee4 100644 --- a/drivers/regulator/cpr3-util.c +++ b/drivers/regulator/cpr3-util.c @@ -1851,7 +1851,7 @@ static int cpr4_load_core_and_temp_adj(struct cpr3_regulator *vreg, for (i = 0; i < sdelta->max_core_count; i++) { for (j = 0, pos = 0; j < sdelta->temp_band_count; j++) pos += scnprintf(buf + pos, buflen - pos, " %u", - sdelta->table[i * sdelta->max_core_count + j]); + sdelta->table[i * sdelta->temp_band_count + j]); cpr3_debug(vreg, "sdelta[%d]:%s\n", i, buf); } diff --git a/drivers/soc/qcom/glink_spi_xprt.c b/drivers/soc/qcom/glink_spi_xprt.c index 47c66c892736..5de6e7eac7ea 100644 --- a/drivers/soc/qcom/glink_spi_xprt.c +++ b/drivers/soc/qcom/glink_spi_xprt.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 @@ -789,9 +789,9 @@ static void process_rx_cmd(struct edge_info *einfo, offset += sizeof(*intents); einfo->xprt_if.glink_core_if_ptr-> rx_cmd_remote_rx_intent_put_cookie( - &einfo->xprt_if, cmd->param1, - intents->id, intents->size, - (void *)(intents->addr)); + &einfo->xprt_if, cmd->param1, + intents->id, intents->size, + (void *)(uintptr_t)(intents->addr)); } break; @@ -821,9 +821,10 @@ static void process_rx_cmd(struct edge_info *einfo, case TRACER_PKT_CONT_CMD: rx_descp = (struct rx_desc *)(rx_data + offset); offset += sizeof(*rx_descp); - process_rx_data(einfo, cmd->id, cmd->param1, - cmd->param2, (void *)rx_descp->addr, - rx_descp->size, rx_descp->size_left); + process_rx_data(einfo, cmd->id, cmd->param1, + cmd->param2, + (void *)(uintptr_t)(rx_descp->addr), + rx_descp->size, rx_descp->size_left); break; case TX_SHORT_DATA_CMD: diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 0ae654a921f8..6c8154d126b2 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -1,5 +1,5 @@ /* - * 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 @@ -30,6 +30,7 @@ #define PMIC_ARB_VERSION 0x0000 #define PMIC_ARB_VERSION_V2_MIN 0x20010000 #define PMIC_ARB_VERSION_V3_MIN 0x30000000 +#define PMIC_ARB_VERSION_V5_MIN 0x50000000 #define PMIC_ARB_INT_EN 0x0004 /* PMIC Arbiter channel registers offsets */ @@ -40,7 +41,6 @@ #define PMIC_ARB_WDATA1 0x14 #define PMIC_ARB_RDATA0 0x18 #define PMIC_ARB_RDATA1 0x1C -#define PMIC_ARB_REG_CHNL(N) (0x800 + 0x4 * (N)) /* Mapping Table */ #define SPMI_MAPPING_TABLE_REG(N) (0x0B00 + (4 * (N))) @@ -53,6 +53,8 @@ #define SPMI_MAPPING_TABLE_TREE_DEPTH 16 /* Maximum of 16-bits */ #define PMIC_ARB_MAX_PPID BIT(12) /* PPID is 12bit */ #define PMIC_ARB_CHAN_VALID BIT(15) +#define PMIC_ARB_CHAN_IS_IRQ_OWNER(reg) ((reg) & BIT(24)) +#define INVALID_EE (-1) /* Ownership Table */ #define SPMI_OWNERSHIP_TABLE_REG(N) (0x0700 + (4 * (N))) @@ -87,6 +89,15 @@ enum pmic_arb_cmd_op_code { PMIC_ARB_OP_ZERO_WRITE = 16, }; +/* + * PMIC arbiter version 5 uses different register offsets for read/write vs + * observer channels. + */ +enum pmic_arb_channel { + PMIC_ARB_CHANNEL_RW, + PMIC_ARB_CHANNEL_OBS, +}; + /* Maximum number of support PMIC peripherals */ #define PMIC_ARB_MAX_PERIPHS 512 #define PMIC_ARB_TIMEOUT_US 100 @@ -113,7 +124,8 @@ struct pmic_arb_ver_ops; struct apid_data { u16 ppid; - u8 owner; + u8 write_owner; + u8 irq_owner; }; /** @@ -122,6 +134,7 @@ struct apid_data { * @rd_base: on v1 "core", on v2 "observer" register base off DT. * @wr_base: on v1 "core", on v2 "chnls" register base off DT. * @intr: address of the SPMI interrupt control registers. + * @acc_status: address of SPMI ACC interrupt status registers. * @cnfg: address of the PMIC Arbiter configuration registers. * @lock: lock to synchronize accesses. * @channel: execution environment channel to use for accesses. @@ -141,6 +154,7 @@ struct spmi_pmic_arb { void __iomem *rd_base; void __iomem *wr_base; void __iomem *intr; + void __iomem *acc_status; void __iomem *cnfg; void __iomem *core; resource_size_t core_size; @@ -181,6 +195,7 @@ static struct spmi_pmic_arb *the_pa; * on v2 offset of SPMI_PIC_IRQ_STATUSn. * @irq_clear: on v1 offset of PMIC_ARB_SPMI_PIC_IRQ_CLEARn * on v2 offset of SPMI_PIC_IRQ_CLEARn. + * @channel_map_offset: offset of PMIC_ARB_REG_CHNLn */ struct pmic_arb_ver_ops { const char *ver_str; @@ -190,7 +205,7 @@ struct pmic_arb_ver_ops { mode_t *mode); /* spmi commands (read_cmd, write_cmd, cmd) functionality */ int (*offset)(struct spmi_pmic_arb *dev, u8 sid, u16 addr, - u32 *offset); + enum pmic_arb_channel ch_type, u32 *offset); u32 (*fmt_cmd)(u8 opc, u8 sid, u16 addr, u8 bc); int (*non_data_cmd)(struct spmi_controller *ctrl, u8 opc, u8 sid); /* Interrupts controller functionality (offset of PIC registers) */ @@ -198,6 +213,7 @@ struct pmic_arb_ver_ops { u32 (*acc_enable)(u16 n); u32 (*irq_status)(u16 n); u32 (*irq_clear)(u16 n); + u32 (*channel_map_offset)(u16 n); }; static inline void pmic_arb_base_write(struct spmi_pmic_arb *pa, @@ -241,7 +257,8 @@ pa_write_data(struct spmi_pmic_arb *pa, const u8 *buf, u32 reg, u8 bc) } static int pmic_arb_wait_for_done(struct spmi_controller *ctrl, - void __iomem *base, u8 sid, u16 addr) + void __iomem *base, u8 sid, u16 addr, + enum pmic_arb_channel ch_type) { struct spmi_pmic_arb *pa = spmi_controller_get_drvdata(ctrl); u32 status = 0; @@ -249,7 +266,7 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl, u32 offset; int rc; - rc = pa->ver_ops->offset(pa, sid, addr, &offset); + rc = pa->ver_ops->offset(pa, sid, addr, ch_type, &offset); if (rc) return rc; @@ -300,7 +317,7 @@ pmic_arb_non_data_cmd_v1(struct spmi_controller *ctrl, u8 opc, u8 sid) int rc; u32 offset; - rc = pa->ver_ops->offset(pa, sid, 0, &offset); + rc = pa->ver_ops->offset(pa, sid, 0, PMIC_ARB_CHANNEL_RW, &offset); if (rc) return rc; @@ -308,7 +325,8 @@ pmic_arb_non_data_cmd_v1(struct spmi_controller *ctrl, u8 opc, u8 sid) raw_spin_lock_irqsave(&pa->lock, flags); pmic_arb_base_write(pa, offset + PMIC_ARB_CMD, cmd); - rc = pmic_arb_wait_for_done(ctrl, pa->wr_base, sid, 0); + rc = pmic_arb_wait_for_done(ctrl, pa->wr_base, sid, 0, + PMIC_ARB_CHANNEL_RW); raw_spin_unlock_irqrestore(&pa->lock, flags); return rc; @@ -345,7 +363,7 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, u32 offset; mode_t mode; - rc = pa->ver_ops->offset(pa, sid, addr, &offset); + rc = pa->ver_ops->offset(pa, sid, addr, PMIC_ARB_CHANNEL_OBS, &offset); if (rc) return rc; @@ -353,7 +371,7 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, if (rc) return rc; - if (!(mode & S_IRUSR)) { + if (!(mode & 0400)) { dev_err(&pa->spmic->dev, "error: impermissible read from peripheral sid:%d addr:0x%x\n", sid, addr); @@ -381,7 +399,8 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, raw_spin_lock_irqsave(&pa->lock, flags); pmic_arb_set_rd_cmd(pa, offset + PMIC_ARB_CMD, cmd); - rc = pmic_arb_wait_for_done(ctrl, pa->rd_base, sid, addr); + rc = pmic_arb_wait_for_done(ctrl, pa->rd_base, sid, addr, + PMIC_ARB_CHANNEL_OBS); if (rc) goto done; @@ -407,7 +426,7 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, u32 offset; mode_t mode; - rc = pa->ver_ops->offset(pa, sid, addr, &offset); + rc = pa->ver_ops->offset(pa, sid, addr, PMIC_ARB_CHANNEL_RW, &offset); if (rc) return rc; @@ -415,7 +434,7 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, if (rc) return rc; - if (!(mode & S_IWUSR)) { + if (!(mode & 0200)) { dev_err(&pa->spmic->dev, "error: impermissible write to peripheral sid:%d addr:0x%x\n", sid, addr); @@ -451,7 +470,8 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, /* Start the transaction */ pmic_arb_base_write(pa, offset + PMIC_ARB_CMD, cmd); - rc = pmic_arb_wait_for_done(ctrl, pa->wr_base, sid, addr); + rc = pmic_arb_wait_for_done(ctrl, pa->wr_base, sid, addr, + PMIC_ARB_CHANNEL_RW); raw_spin_unlock_irqrestore(&pa->lock, flags); return rc; @@ -564,20 +584,19 @@ static void periph_interrupt(struct spmi_pmic_arb *pa, u16 apid, bool show) static void __pmic_arb_chained_irq(struct spmi_pmic_arb *pa, bool show) { - void __iomem *intr = pa->intr; int first = pa->min_apid >> 5; int last = pa->max_apid >> 5; u32 status, enable; int i, id, apid; for (i = first; i <= last; ++i) { - status = readl_relaxed(intr + + status = readl_relaxed(pa->acc_status + pa->ver_ops->owner_acc_status(pa->ee, i)); while (status) { id = ffs(status) - 1; status &= ~BIT(id); apid = id + i * 32; - enable = readl_relaxed(intr + + enable = readl_relaxed(pa->intr + pa->ver_ops->acc_enable(apid)); if (enable & SPMI_PIC_ACC_ENABLE_BIT) periph_interrupt(pa, apid, show); @@ -728,11 +747,18 @@ static int qpnpint_irq_domain_dt_translate(struct irq_domain *d, (intspec[1] << 8), &apid); if (rc < 0) { dev_err(&pa->spmic->dev, - "failed to xlate sid = 0x%x, periph = 0x%x, irq = %x rc = %d\n", + "failed to xlate sid = 0x%x, periph = 0x%x, irq = %u rc = %d\n", intspec[0], intspec[1], intspec[2], rc); return rc; } + if (pa->apid_data[apid].irq_owner != pa->ee) { + dev_err(&pa->spmic->dev, "failed to xlate sid = 0x%x, periph = 0x%x, irq = %u: ee=%u but owner=%u\n", + intspec[0], intspec[1], intspec[2], pa->ee, + pa->apid_data[apid].irq_owner); + return -ENODEV; + } + /* Keep track of {max,min}_apid for bounding search during interrupt */ if (apid > pa->max_apid) pa->max_apid = apid; @@ -812,13 +838,14 @@ pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pa, u8 sid, u16 addr, u16 *apid) static int pmic_arb_mode_v1_v3(struct spmi_pmic_arb *pa, u8 sid, u16 addr, mode_t *mode) { - *mode = S_IRUSR | S_IWUSR; + *mode = 0600; return 0; } /* v1 offset per ee */ static int -pmic_arb_offset_v1(struct spmi_pmic_arb *pa, u8 sid, u16 addr, u32 *offset) +pmic_arb_offset_v1(struct spmi_pmic_arb *pa, u8 sid, u16 addr, + enum pmic_arb_channel ch_type, u32 *offset) { *offset = 0x800 + 0x80 * pa->channel; return 0; @@ -837,9 +864,11 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pa, u16 ppid) for (apid = pa->last_apid; apid < pa->max_periph; apid++) { regval = readl_relaxed(pa->cnfg + SPMI_OWNERSHIP_TABLE_REG(apid)); - pa->apid_data[apid].owner = SPMI_OWNERSHIP_PERIPH2OWNER(regval); + pa->apid_data[apid].irq_owner + = SPMI_OWNERSHIP_PERIPH2OWNER(regval); + pa->apid_data[apid].write_owner = pa->apid_data[apid].irq_owner; - offset = PMIC_ARB_REG_CHNL(apid); + offset = pa->ver_ops->channel_map_offset(apid); if (offset >= pa->core_size) break; @@ -876,27 +905,110 @@ pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pa, u8 sid, u16 addr, u16 *apid) return 0; } +static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pa) +{ + u32 regval, offset; + u16 apid, prev_apid, ppid; + bool valid, is_irq_owner; + + /* + * PMIC_ARB_REG_CHNL is a table in HW mapping APID (channel) to PPID. + * ppid_to_apid is an in-memory invert of that table. In order to allow + * multiple EE's to write to a single PPID in arbiter version 5, there + * is more than one APID mapped to each PPID. The owner field for each + * of these mappings specifies the EE which is allowed to write to the + * APID. The owner of the last (highest) APID for a given PPID will + * receive interrupts from the PPID. + */ + for (apid = 0; apid < pa->max_periph; apid++) { + offset = pa->ver_ops->channel_map_offset(apid); + if (offset >= pa->core_size) + break; + + regval = readl_relaxed(pa->core + offset); + if (!regval) + continue; + ppid = (regval >> 8) & PMIC_ARB_PPID_MASK; + is_irq_owner = PMIC_ARB_CHAN_IS_IRQ_OWNER(regval); + + regval = readl_relaxed(pa->cnfg + + SPMI_OWNERSHIP_TABLE_REG(apid)); + pa->apid_data[apid].write_owner + = SPMI_OWNERSHIP_PERIPH2OWNER(regval); + + pa->apid_data[apid].irq_owner = is_irq_owner ? + pa->apid_data[apid].write_owner : INVALID_EE; + + valid = pa->ppid_to_apid[ppid] & PMIC_ARB_CHAN_VALID; + prev_apid = pa->ppid_to_apid[ppid] & ~PMIC_ARB_CHAN_VALID; + + if (valid && is_irq_owner && + pa->apid_data[prev_apid].write_owner == pa->ee) { + /* + * Duplicate PPID mapping after the one for this EE; + * override the irq owner + */ + pa->apid_data[prev_apid].irq_owner + = pa->apid_data[apid].irq_owner; + } else if (!valid || is_irq_owner) { + /* First PPID mapping or duplicate for another EE */ + pa->ppid_to_apid[ppid] = apid | PMIC_ARB_CHAN_VALID; + } + + pa->apid_data[apid].ppid = ppid; + pa->last_apid = apid; + } + + /* Dump the mapping table for debug purposes. */ + dev_dbg(&pa->spmic->dev, "PPID APID Write-EE IRQ-EE\n"); + for (ppid = 0; ppid < PMIC_ARB_MAX_PPID; ppid++) { + valid = pa->ppid_to_apid[ppid] & PMIC_ARB_CHAN_VALID; + apid = pa->ppid_to_apid[ppid] & ~PMIC_ARB_CHAN_VALID; + + if (valid) + dev_dbg(&pa->spmic->dev, "0x%03X %3u %2u %2u\n", + ppid, apid, pa->apid_data[apid].write_owner, + pa->apid_data[apid].irq_owner); + } + + return 0; +} + +static int +pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb *pa, u8 sid, u16 addr, u16 *apid) +{ + u16 ppid = (sid << 8) | (addr >> 8); + + if (!(pa->ppid_to_apid[ppid] & PMIC_ARB_CHAN_VALID)) + return -ENODEV; + + *apid = pa->ppid_to_apid[ppid] & ~PMIC_ARB_CHAN_VALID; + + return 0; +} + static int pmic_arb_mode_v2(struct spmi_pmic_arb *pa, u8 sid, u16 addr, mode_t *mode) { u16 apid; int rc; - rc = pmic_arb_ppid_to_apid_v2(pa, sid, addr, &apid); + rc = pa->ver_ops->ppid_to_apid(pa, sid, addr, &apid); if (rc < 0) return rc; *mode = 0; - *mode |= S_IRUSR; + *mode |= 0400; - if (pa->ee == pa->apid_data[apid].owner) - *mode |= S_IWUSR; + if (pa->ee == pa->apid_data[apid].write_owner) + *mode |= 0200; return 0; } /* v2 offset per ppid and per ee */ static int -pmic_arb_offset_v2(struct spmi_pmic_arb *pa, u8 sid, u16 addr, u32 *offset) +pmic_arb_offset_v2(struct spmi_pmic_arb *pa, u8 sid, u16 addr, + enum pmic_arb_channel ch_type, u32 *offset) { u16 apid; int rc; @@ -909,6 +1021,27 @@ pmic_arb_offset_v2(struct spmi_pmic_arb *pa, u8 sid, u16 addr, u32 *offset) return 0; } +/* + * v5 offset per ee and per apid for observer channels and per apid for + * read/write channels. + */ +static int +pmic_arb_offset_v5(struct spmi_pmic_arb *pa, u8 sid, u16 addr, + enum pmic_arb_channel ch_type, u32 *offset) +{ + u16 apid; + int rc; + + rc = pmic_arb_ppid_to_apid_v5(pa, sid, addr, &apid); + if (rc < 0) + return rc; + + *offset = (ch_type == PMIC_ARB_CHANNEL_OBS) + ? 0x10000 * pa->ee + 0x80 * apid + : 0x10000 * apid; + return 0; +} + static u32 pmic_arb_fmt_cmd_v1(u8 opc, u8 sid, u16 addr, u8 bc) { return (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7); @@ -934,6 +1067,11 @@ static u32 pmic_arb_owner_acc_status_v3(u8 m, u16 n) return 0x200000 + 0x1000 * m + 0x4 * n; } +static u32 pmic_arb_owner_acc_status_v5(u8 m, u16 n) +{ + return 0x10000 * m + 0x4 * n; +} + static u32 pmic_arb_acc_enable_v1(u16 n) { return 0x200 + 0x4 * n; @@ -944,6 +1082,11 @@ static u32 pmic_arb_acc_enable_v2(u16 n) return 0x1000 * n; } +static u32 pmic_arb_acc_enable_v5(u16 n) +{ + return 0x100 + 0x10000 * n; +} + static u32 pmic_arb_irq_status_v1(u16 n) { return 0x600 + 0x4 * n; @@ -954,6 +1097,11 @@ static u32 pmic_arb_irq_status_v2(u16 n) return 0x4 + 0x1000 * n; } +static u32 pmic_arb_irq_status_v5(u16 n) +{ + return 0x104 + 0x10000 * n; +} + static u32 pmic_arb_irq_clear_v1(u16 n) { return 0xA00 + 0x4 * n; @@ -964,6 +1112,21 @@ static u32 pmic_arb_irq_clear_v2(u16 n) return 0x8 + 0x1000 * n; } +static u32 pmic_arb_irq_clear_v5(u16 n) +{ + return 0x108 + 0x10000 * n; +} + +static u32 pmic_arb_channel_map_offset_v2(u16 n) +{ + return 0x800 + 0x4 * n; +} + +static u32 pmic_arb_channel_map_offset_v5(u16 n) +{ + return 0x900 + 0x4 * n; +} + static const struct pmic_arb_ver_ops pmic_arb_v1 = { .ver_str = "v1", .ppid_to_apid = pmic_arb_ppid_to_apid_v1, @@ -975,6 +1138,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = { .acc_enable = pmic_arb_acc_enable_v1, .irq_status = pmic_arb_irq_status_v1, .irq_clear = pmic_arb_irq_clear_v1, + .channel_map_offset = pmic_arb_channel_map_offset_v2, }; static const struct pmic_arb_ver_ops pmic_arb_v2 = { @@ -988,6 +1152,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = { .acc_enable = pmic_arb_acc_enable_v2, .irq_status = pmic_arb_irq_status_v2, .irq_clear = pmic_arb_irq_clear_v2, + .channel_map_offset = pmic_arb_channel_map_offset_v2, }; static const struct pmic_arb_ver_ops pmic_arb_v3 = { @@ -1001,6 +1166,21 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = { .acc_enable = pmic_arb_acc_enable_v2, .irq_status = pmic_arb_irq_status_v2, .irq_clear = pmic_arb_irq_clear_v2, + .channel_map_offset = pmic_arb_channel_map_offset_v2, +}; + +static const struct pmic_arb_ver_ops pmic_arb_v5 = { + .ver_str = "v5", + .ppid_to_apid = pmic_arb_ppid_to_apid_v5, + .mode = pmic_arb_mode_v2, + .non_data_cmd = pmic_arb_non_data_cmd_v2, + .offset = pmic_arb_offset_v5, + .fmt_cmd = pmic_arb_fmt_cmd_v2, + .owner_acc_status = pmic_arb_owner_acc_status_v5, + .acc_enable = pmic_arb_acc_enable_v5, + .irq_status = pmic_arb_irq_status_v5, + .irq_clear = pmic_arb_irq_clear_v5, + .channel_map_offset = pmic_arb_channel_map_offset_v5, }; static const struct irq_domain_ops pmic_arb_irq_domain_ops = { @@ -1065,11 +1245,14 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) if (hw_ver < PMIC_ARB_VERSION_V3_MIN) pa->ver_ops = &pmic_arb_v2; - else + else if (hw_ver < PMIC_ARB_VERSION_V5_MIN) pa->ver_ops = &pmic_arb_v3; + else + pa->ver_ops = &pmic_arb_v5; - /* the apid to ppid table starts at PMIC_ARB_REG_CHNL(0) */ - pa->max_periph = (pa->core_size - PMIC_ARB_REG_CHNL(0)) / 4; + /* the apid to ppid table starts at PMIC_ARB_REG_CHNL0 */ + pa->max_periph + = (pa->core_size - pa->ver_ops->channel_map_offset(0)) / 4; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "obsrvr"); @@ -1106,6 +1289,14 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) err = PTR_ERR(pa->intr); goto err_put_ctrl; } + pa->acc_status = pa->intr; + + /* + * PMIC arbiter v5 groups the IRQ control registers in the same hardware + * module as the read/write channels. + */ + if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) + pa->intr = pa->wr_base; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cnfg"); pa->cnfg = devm_ioremap_resource(&ctrl->dev, res); @@ -1129,6 +1320,7 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) if (channel > 5) { dev_err(&pdev->dev, "invalid channel (%u) specified.\n", channel); + err = -EINVAL; goto err_put_ctrl; } @@ -1167,6 +1359,15 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) ctrl->read_cmd = pmic_arb_read_cmd; ctrl->write_cmd = pmic_arb_write_cmd; + if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) { + err = pmic_arb_read_apid_map_v5(pa); + if (err) { + dev_err(&pdev->dev, "could not read APID->PPID mapping table, rc= %d\n", + err); + goto err_put_ctrl; + } + } + dev_dbg(&pdev->dev, "adding irq domain\n"); pa->domain = irq_domain_add_tree(pdev->dev.of_node, &pmic_arb_irq_domain_ops, pa); diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index dfc63b47ae81..d0ee0c9d6430 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -256,12 +256,6 @@ static void *usbpd_ipc_log; static int min_sink_current = 900; module_param(min_sink_current, int, S_IRUSR | S_IWUSR); -static bool ss_host; -module_param(ss_host, bool, S_IRUSR | S_IWUSR); - -static bool ss_dev = true; -module_param(ss_dev, bool, S_IRUSR | S_IWUSR); - static const u32 default_src_caps[] = { 0x36019096 }; /* VSafe5V @ 1.5A */ static const u32 default_snk_caps[] = { 0x2601905A }; /* 5V @ 900mA */ @@ -375,20 +369,34 @@ enum plug_orientation usbpd_get_plug_orientation(struct usbpd *pd) } EXPORT_SYMBOL(usbpd_get_plug_orientation); -static bool is_cable_flipped(struct usbpd *pd) +static inline void stop_usb_host(struct usbpd *pd) +{ + extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 0); +} + +static inline void start_usb_host(struct usbpd *pd, bool ss) { - enum plug_orientation cc; + enum plug_orientation cc = usbpd_get_plug_orientation(pd); - cc = usbpd_get_plug_orientation(pd); - if (cc == ORIENTATION_CC2) - return true; + extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC, + cc == ORIENTATION_CC2); + extcon_set_cable_state_(pd->extcon, EXTCON_USB_SPEED, ss); + extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 1); +} - /* - * ORIENTATION_CC1 or ORIENTATION_NONE. - * Return value for ORIENTATION_NONE is - * "dont care" as disconnect handles it. - */ - return false; +static inline void stop_usb_peripheral(struct usbpd *pd) +{ + extcon_set_cable_state_(pd->extcon, EXTCON_USB, 0); +} + +static inline void start_usb_peripheral(struct usbpd *pd) +{ + enum plug_orientation cc = usbpd_get_plug_orientation(pd); + + extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC, + cc == ORIENTATION_CC2); + extcon_set_cable_state_(pd->extcon, EXTCON_USB_SPEED, 1); + extcon_set_cable_state_(pd->extcon, EXTCON_USB, 1); } static int set_power_role(struct usbpd *pd, enum power_role pr) @@ -774,17 +782,12 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) case PE_SRC_READY: pd->in_explicit_contract = true; if (pd->current_dr == DR_DFP) { + /* don't start USB host until after SVDM discovery */ if (pd->vdm_state == VDM_NONE) usbpd_send_svdm(pd, USBPD_SID, USBPD_SVDM_DISCOVER_IDENTITY, SVDM_CMD_TYPE_INITIATOR, 0, NULL, 0); - - extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC, - is_cable_flipped(pd)); - extcon_set_cable_state_(pd->extcon, EXTCON_USB_SPEED, - ss_host); - extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 1); } kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE); @@ -820,15 +823,8 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) pd->current_dr = DR_UFP; if (pd->psy_type == POWER_SUPPLY_TYPE_USB || - pd->psy_type == POWER_SUPPLY_TYPE_USB_CDP) { - extcon_set_cable_state_(pd->extcon, - EXTCON_USB_CC, - is_cable_flipped(pd)); - extcon_set_cable_state_(pd->extcon, - EXTCON_USB_SPEED, ss_dev); - extcon_set_cable_state_(pd->extcon, - EXTCON_USB, 1); - } + pd->psy_type == POWER_SUPPLY_TYPE_USB_CDP) + start_usb_peripheral(pd); } dual_role_instance_changed(pd->dual_role); @@ -928,14 +924,9 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) case PE_SNK_TRANSITION_TO_DEFAULT: if (pd->current_dr != DR_UFP) { - extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 0); - + stop_usb_host(pd); + start_usb_peripheral(pd); pd->current_dr = DR_UFP; - extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC, - is_cable_flipped(pd)); - extcon_set_cable_state_(pd->extcon, EXTCON_USB_SPEED, - ss_dev); - extcon_set_cable_state_(pd->extcon, EXTCON_USB, 1); pd_phy_update_roles(pd->current_dr, pd->current_pr); } if (pd->vconn_enabled) { @@ -1061,6 +1052,7 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) u8 i, num_vdos = rx_msg->len - 1; /* num objects minus header */ u8 cmd = SVDM_HDR_CMD(vdm_hdr); u8 cmd_type = SVDM_HDR_CMD_TYPE(vdm_hdr); + bool has_dp = false; struct usbpd_svid_handler *handler; usbpd_dbg(&pd->dev, "VDM rx: svid:%x cmd:%x cmd_type:%x vdm_hdr:%x\n", @@ -1210,8 +1202,18 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) handler->discovered = true; } } + + if (svid == 0xFF01) + has_dp = true; } + /* + * Finally start USB host now that we have determined + * if DisplayPort mode is present or not and limit USB + * to HS-only mode if so. + */ + start_usb_host(pd, !has_dp); + break; default: @@ -1224,6 +1226,16 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) case SVDM_CMD_TYPE_RESP_NAK: usbpd_info(&pd->dev, "VDM NAK received for SVID:0x%04x command:0x%x\n", svid, cmd); + + switch (cmd) { + case USBPD_SVDM_DISCOVER_IDENTITY: + case USBPD_SVDM_DISCOVER_SVIDS: + start_usb_host(pd, true); + break; + default: + break; + } + break; case SVDM_CMD_TYPE_RESP_BUSY: @@ -1325,26 +1337,19 @@ static void reset_vdm_state(struct usbpd *pd) static void dr_swap(struct usbpd *pd) { + reset_vdm_state(pd); + if (pd->current_dr == DR_DFP) { - extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 0); - extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC, - is_cable_flipped(pd)); - extcon_set_cable_state_(pd->extcon, EXTCON_USB_SPEED, ss_dev); - extcon_set_cable_state_(pd->extcon, EXTCON_USB, 1); + stop_usb_host(pd); + start_usb_peripheral(pd); pd->current_dr = DR_UFP; } else if (pd->current_dr == DR_UFP) { - extcon_set_cable_state_(pd->extcon, EXTCON_USB, 0); - extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC, - is_cable_flipped(pd)); - extcon_set_cable_state_(pd->extcon, EXTCON_USB_SPEED, ss_host); - extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 1); + stop_usb_peripheral(pd); pd->current_dr = DR_DFP; - if (pd->vdm_state == VDM_NONE) - usbpd_send_svdm(pd, USBPD_SID, - USBPD_SVDM_DISCOVER_IDENTITY, - SVDM_CMD_TYPE_INITIATOR, 0, - NULL, 0); + /* don't start USB host until after SVDM discovery */ + usbpd_send_svdm(pd, USBPD_SID, USBPD_SVDM_DISCOVER_IDENTITY, + SVDM_CMD_TYPE_INITIATOR, 0, NULL, 0); } pd_phy_update_roles(pd->current_dr, pd->current_pr); @@ -1466,9 +1471,9 @@ static void usbpd_sm(struct work_struct *w) } if (pd->current_dr == DR_UFP) - extcon_set_cable_state_(pd->extcon, EXTCON_USB, 0); + stop_usb_peripheral(pd); else if (pd->current_dr == DR_DFP) - extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 0); + stop_usb_host(pd); pd->current_pr = PR_NONE; pd->current_dr = DR_NONE; @@ -1566,14 +1571,9 @@ static void usbpd_sm(struct work_struct *w) if (ret) { pd->caps_count++; - if (pd->caps_count == 5 && pd->current_dr == DR_DFP) { + if (pd->caps_count == 10 && pd->current_dr == DR_DFP) { /* Likely not PD-capable, start host now */ - extcon_set_cable_state_(pd->extcon, - EXTCON_USB_CC, is_cable_flipped(pd)); - extcon_set_cable_state_(pd->extcon, - EXTCON_USB_SPEED, ss_host); - extcon_set_cable_state_(pd->extcon, - EXTCON_USB_HOST, 1); + start_usb_host(pd, true); } else if (pd->caps_count >= PD_CAPS_COUNT) { usbpd_dbg(&pd->dev, "Src CapsCounter exceeded, disabling PD\n"); usbpd_set_state(pd, PE_SRC_DISABLED); diff --git a/drivers/usb/pd/qpnp-pdphy.c b/drivers/usb/pd/qpnp-pdphy.c index 1a03b0d71a18..4ecc24c6be11 100644 --- a/drivers/usb/pd/qpnp-pdphy.c +++ b/drivers/usb/pd/qpnp-pdphy.c @@ -244,9 +244,12 @@ void pdphy_enable_irq(struct usb_pdphy *pdphy, bool enable) if (enable) { enable_irq(pdphy->sig_tx_irq); enable_irq(pdphy->sig_rx_irq); + enable_irq_wake(pdphy->sig_rx_irq); enable_irq(pdphy->msg_tx_irq); - if (!pdphy->in_test_data_mode) + if (!pdphy->in_test_data_mode) { enable_irq(pdphy->msg_rx_irq); + enable_irq_wake(pdphy->msg_rx_irq); + } enable_irq(pdphy->msg_tx_failed_irq); enable_irq(pdphy->msg_tx_discarded_irq); enable_irq(pdphy->msg_rx_discarded_irq); @@ -255,9 +258,12 @@ void pdphy_enable_irq(struct usb_pdphy *pdphy, bool enable) disable_irq(pdphy->sig_tx_irq); disable_irq(pdphy->sig_rx_irq); + disable_irq_wake(pdphy->sig_rx_irq); disable_irq(pdphy->msg_tx_irq); - if (!pdphy->in_test_data_mode) + if (!pdphy->in_test_data_mode) { disable_irq(pdphy->msg_rx_irq); + disable_irq_wake(pdphy->msg_rx_irq); + } disable_irq(pdphy->msg_tx_failed_irq); disable_irq(pdphy->msg_tx_discarded_irq); disable_irq(pdphy->msg_rx_discarded_irq); diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 338ae65a160f..5071d1039c26 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -900,6 +900,41 @@ static int fuse_readpages_fill(void *_data, struct page *page) return -EIO; } +#ifdef CONFIG_CMA + if (is_cma_pageblock(page)) { + struct page *oldpage = page, *newpage; + int err; + + /* make sure that old page is not free in-between the calls */ + page_cache_get(oldpage); + + newpage = alloc_page(GFP_HIGHUSER); + if (!newpage) { + page_cache_release(oldpage); + return -ENOMEM; + } + + err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL); + if (err) { + __free_page(newpage); + page_cache_release(oldpage); + return err; + } + + /* + * Decrement the count on new page to make page cache the only + * owner of it + */ + lock_page(newpage); + put_page(newpage); + + /* finally release the old page and swap pointers */ + unlock_page(oldpage); + page_cache_release(oldpage); + page = newpage; + } +#endif + page_cache_get(page); req->pages[req->num_pages] = page; req->page_descs[req->num_pages].length = PAGE_SIZE; diff --git a/include/dt-bindings/clock/audio-ext-clk.h b/include/dt-bindings/clock/audio-ext-clk.h index a384ddf68ea0..6fe8a466cf0e 100644 --- a/include/dt-bindings/clock/audio-ext-clk.h +++ b/include/dt-bindings/clock/audio-ext-clk.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 @@ -15,11 +15,11 @@ /* Audio External Clocks */ #define AUDIO_PMI_CLK 0 -#define AUDIO_PMIC_LNBB_CLK 1 -#define AUDIO_AP_CLK 2 -#define AUDIO_AP_CLK2 3 -#define AUDIO_LPASS_MCLK 4 -#define AUDIO_LPASS_MCLK2 5 +#define AUDIO_PMIC_LNBB_CLK 0 +#define AUDIO_AP_CLK 1 +#define AUDIO_AP_CLK2 2 +#define AUDIO_LPASS_MCLK 3 +#define AUDIO_LPASS_MCLK2 4 #define clk_audio_ap_clk 0x9b5727cb #define clk_audio_pmi_clk 0xcbfe416d diff --git a/include/dt-bindings/clock/qcom,gcc-sdm660.h b/include/dt-bindings/clock/qcom,gcc-sdm660.h index c67d6473fdc2..e66633c74c0c 100644 --- a/include/dt-bindings/clock/qcom,gcc-sdm660.h +++ b/include/dt-bindings/clock/qcom,gcc-sdm660.h @@ -77,11 +77,9 @@ #define GCC_GP2_CLK 62 #define GCC_GP3_CLK 63 #define GCC_GPU_BIMC_GFX_CLK 64 -#define GCC_GPU_BIMC_GFX_SRC_CLK 65 #define GCC_GPU_CFG_AHB_CLK 66 #define GCC_GPU_GPLL0_CLK 67 #define GCC_GPU_GPLL0_DIV_CLK 68 -#define GCC_GPU_SNOC_DVM_GFX_CLK 69 #define GCC_HMSS_AHB_CLK 70 #define GCC_HMSS_DVM_BUS_CLK 71 #define GCC_HMSS_RBCPR_CLK 72 diff --git a/include/linux/leds.h b/include/linux/leds.h index bba189a62dfd..197b61500ab7 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -49,6 +49,7 @@ struct led_classdev { #define SET_BRIGHTNESS_ASYNC (1 << 21) #define SET_BRIGHTNESS_SYNC (1 << 22) #define LED_DEV_CAP_FLASH (1 << 23) +#define LED_KEEP_TRIGGER (1 << 24) /* Set LED brightness level */ /* Must not sleep, use a workqueue if needed */ diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index f7aeb14f4d63..418eb97110a3 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h @@ -63,7 +63,6 @@ extern unsigned int sysctl_sched_boost; extern unsigned int sysctl_sched_small_wakee_task_load_pct; extern unsigned int sysctl_sched_big_waker_task_load_pct; extern unsigned int sysctl_sched_select_prev_cpu_us; -extern unsigned int sysctl_sched_enable_colocation; extern unsigned int sysctl_sched_restrict_cluster_spill; extern unsigned int sysctl_sched_new_task_windows; extern unsigned int sysctl_sched_pred_alert_freq; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 2dc3abfd61be..ee5270f984ba 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3762,11 +3762,12 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw); * This function must be called with BHs disabled. * * @hw: the hardware this frame came in on + * @sta: the station the frame was received from, or %NULL * @skb: the buffer to receive, owned by mac80211 after this call * @napi: the NAPI context */ -void ieee80211_rx_napi(struct ieee80211_hw *hw, struct sk_buff *skb, - struct napi_struct *napi); +void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *sta, + struct sk_buff *skb, struct napi_struct *napi); /** * ieee80211_rx - receive frame @@ -3790,7 +3791,7 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct sk_buff *skb, */ static inline void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) { - ieee80211_rx_napi(hw, skb, NULL); + ieee80211_rx_napi(hw, NULL, skb, NULL); } /** diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c index 443f16732414..e28f2b424643 100644 --- a/kernel/sched/hmp.c +++ b/kernel/sched/hmp.c @@ -718,8 +718,6 @@ __read_mostly unsigned int sysctl_sched_window_stats_policy = __read_mostly unsigned int sysctl_sched_cpu_high_irqload = (10 * NSEC_PER_MSEC); -unsigned int __read_mostly sysctl_sched_enable_colocation = 1; - /* * Enable colocation and frequency aggregation for all threads in a process. * The children inherits the group id from the parent. @@ -1292,14 +1290,12 @@ void reset_hmp_stats(struct hmp_sched_stats *stats, int reset_cra) int preferred_cluster(struct sched_cluster *cluster, struct task_struct *p) { struct related_thread_group *grp; - int rc = 0; + int rc = 1; rcu_read_lock(); grp = task_related_thread_group(p); - if (!grp || !sysctl_sched_enable_colocation) - rc = 1; - else + if (grp) rc = (grp->preferred_cluster == cluster); rcu_read_unlock(); @@ -3751,7 +3747,7 @@ static struct sched_cluster *best_cluster(struct related_thread_group *grp, return cluster; } - return NULL; + return sched_cluster[0]; } static void _set_preferred_cluster(struct related_thread_group *grp) @@ -3762,12 +3758,6 @@ static void _set_preferred_cluster(struct related_thread_group *grp) bool group_boost = false; u64 wallclock; - if (!sysctl_sched_enable_colocation) { - grp->last_update = sched_ktime_clock(); - grp->preferred_cluster = NULL; - return; - } - if (list_empty(&grp->tasks)) return; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index eced92aa492a..d3873333c766 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -404,15 +404,6 @@ static struct ctl_table kern_table[] = { .extra1 = &zero, }, { - .procname = "sched_enable_colocation", - .data = &sysctl_sched_enable_colocation, - .maxlen = sizeof(unsigned int), - .mode = 0644, - .proc_handler = proc_dointvec, - .extra1 = &zero, - .extra2 = &one, - }, - { .procname = "sched_restrict_cluster_spill", .data = &sysctl_sched_restrict_cluster_spill, .maxlen = sizeof(unsigned int), diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index ae68222c5a74..1d0f1a1ac44c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1685,7 +1685,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags, TRACE_FLAG_IRQS_NOSUPPORT | #endif ((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) | - ((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) | + ((pc & SOFTIRQ_OFFSET) ? TRACE_FLAG_SOFTIRQ : 0) | (tif_need_resched() ? TRACE_FLAG_NEED_RESCHED : 0) | (test_preempt_need_resched() ? TRACE_FLAG_PREEMPT_RESCHED : 0); } diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 5e2adf622b1e..4f4c45ba7b70 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -3454,6 +3454,7 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, * be called with rcu_read_lock protection. */ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, + struct ieee80211_sta *pubsta, struct sk_buff *skb, struct napi_struct *napi) { @@ -3463,7 +3464,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, __le16 fc; struct ieee80211_rx_data rx; struct ieee80211_sub_if_data *prev; - struct sta_info *sta, *prev_sta; struct rhash_head *tmp; int err = 0; @@ -3499,7 +3499,14 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, ieee80211_is_beacon(hdr->frame_control))) ieee80211_scan_rx(local, skb); - if (ieee80211_is_data(fc)) { + if (pubsta) { + rx.sta = container_of(pubsta, struct sta_info, sta); + rx.sdata = rx.sta->sdata; + if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) + return; + goto out; + } else if (ieee80211_is_data(fc)) { + struct sta_info *sta, *prev_sta; const struct bucket_table *tbl; prev_sta = NULL; @@ -3573,8 +3580,8 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, * This is the receive path handler. It is called by a low level driver when an * 802.11 MPDU is received from the hardware. */ -void ieee80211_rx_napi(struct ieee80211_hw *hw, struct sk_buff *skb, - struct napi_struct *napi) +void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta, + struct sk_buff *skb, struct napi_struct *napi) { struct ieee80211_local *local = hw_to_local(hw); struct ieee80211_rate *rate = NULL; @@ -3673,7 +3680,8 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct sk_buff *skb, ieee80211_tpt_led_trig_rx(local, ((struct ieee80211_hdr *)skb->data)->frame_control, skb->len); - __ieee80211_rx_handle_packet(hw, skb, napi); + + __ieee80211_rx_handle_packet(hw, pubsta, skb, napi); rcu_read_unlock(); diff --git a/sound/soc/codecs/audio-ext-clk-up.c b/sound/soc/codecs/audio-ext-clk-up.c index f989498e9c32..6de88aff0dd4 100644 --- a/sound/soc/codecs/audio-ext-clk-up.c +++ b/sound/soc/codecs/audio-ext-clk-up.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 @@ -296,6 +296,8 @@ static struct audio_ext_pmi_clk audio_pmi_clk = { .div = 1, .hw.init = &(struct clk_init_data){ .name = "audio_ext_pmi_clk", + .parent_names = (const char *[]){ "div_clk1" }, + .num_parents = 1, .ops = &clk_dummy_ops, }, }, @@ -308,6 +310,8 @@ static struct audio_ext_pmi_clk audio_pmi_lnbb_clk = { .div = 1, .hw.init = &(struct clk_init_data){ .name = "audio_ext_pmi_lnbb_clk", + .parent_names = (const char *[]){ "ln_bb_clk2" }, + .num_parents = 1, .ops = &clk_dummy_ops, }, }, @@ -364,13 +368,16 @@ static struct audio_ext_lpass_mclk audio_lpass_mclk2 = { static struct clk_hw *audio_msm_hws[] = { &audio_pmi_clk.fact.hw, - &audio_pmi_lnbb_clk.fact.hw, &audio_ap_clk.fact.hw, &audio_ap_clk2.fact.hw, &audio_lpass_mclk.fact.hw, &audio_lpass_mclk2.fact.hw, }; +static struct clk_hw *audio_msm_hws1[] = { + &audio_pmi_lnbb_clk.fact.hw, +}; + static int audio_get_pinctrl(struct platform_device *pdev, enum audio_clk_mux mux) { @@ -496,15 +503,31 @@ static int audio_ref_clk_probe(struct platform_device *pdev) if (!clk_data->clks) goto err_clk; - for (i = 0; i < ARRAY_SIZE(audio_msm_hws); i++) { - audio_clk = devm_clk_register(dev, audio_msm_hws[i]); - if (IS_ERR(audio_clk)) { - dev_err(&pdev->dev, - "%s: audio ref clock i = %d register failed\n", - __func__, i); - return PTR_ERR(audio_clk); + + clk_gpio = of_get_named_gpio(pdev->dev.of_node, + "qcom,audio-ref-clk-gpio", 0); + if (clk_gpio > 0) { + for (i = 0; i < ARRAY_SIZE(audio_msm_hws); i++) { + audio_clk = devm_clk_register(dev, audio_msm_hws[i]); + if (IS_ERR(audio_clk)) { + dev_err(&pdev->dev, + "%s: ref clock: %d register failed\n", + __func__, i); + return PTR_ERR(audio_clk); + } + clk_data->clks[i] = audio_clk; + } + } else { + for (i = 0; i < ARRAY_SIZE(audio_msm_hws1); i++) { + audio_clk = devm_clk_register(dev, audio_msm_hws1[i]); + if (IS_ERR(audio_clk)) { + dev_err(&pdev->dev, + "%s: ref clock: %d register failed\n", + __func__, i); + return PTR_ERR(audio_clk); + } + clk_data->clks[i] = audio_clk; } - clk_data->clks[i] = audio_clk; } ret = of_clk_add_provider(pdev->dev.of_node, diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c index 51bb3387de16..e34fc06dc75e 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.c +++ b/sound/soc/codecs/wcd-mbhc-v2.c @@ -52,7 +52,7 @@ #define WCD_MBHC_BTN_PRESS_COMPL_TIMEOUT_MS 50 #define ANC_DETECT_RETRY_CNT 7 -#define WCD_MBHC_SPL_HS_CNT 1 +#define WCD_MBHC_SPL_HS_CNT 2 static int det_extn_cable_en; module_param(det_extn_cable_en, int, |
