diff options
52 files changed, 858 insertions, 681 deletions
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt index f71d1a909d07..e8177c3a0952 100644 --- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt +++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt @@ -1772,6 +1772,10 @@ Optional Properties: - qcom,msm-mi2s-master: This property is used to inform machine driver if MSM is the clock master of mi2s. 1 means master and 0 means slave. The first entry is primary mi2s; the second entry is secondary mi2s, and so on. +- qcom,msm-mi2s-ext-mclk: This property is used to inform machine driver + if MCLK from MSM is used for any external audio connections. 1 means used + as external mclk source and 0 indicate not used. The first entry is + primary mclk; the second entry is secondary mclk, and so on. - reg: This property provides the AUX PCM/MI2S mux select register addresses and size. - reg_names: This property provides the name of the AUX PCM/MI2S mux select @@ -1812,6 +1816,7 @@ Example: qcom,mi2s-audio-intf; qcom,auxpcm-audio-intf; qcom,msm-mi2s-master = <1>, <0>, <1>, <1>; + qcom,msm-mi2s-ext-mclk = <1>, <1>, <0>, <1>; reg = <0x1711a000 0x4>, <0x1711b000 0x4>, <0x1711c000 0x4>, diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile index af4c3d1d6de4..97508071c18b 100644 --- a/arch/arm/boot/dts/qcom/Makefile +++ b/arch/arm/boot/dts/qcom/Makefile @@ -161,7 +161,8 @@ dtb-$(CONFIG_ARCH_SDM660) += sdm660-sim.dtb \ sda660-pm660a-mtp.dtb \ sda660-pm660a-rcm.dtb -dtb-$(CONFIG_ARCH_SDM630) += sdm630-rumi.dtb +dtb-$(CONFIG_ARCH_SDM630) += sdm630-rumi.dtb \ + sdm630-pm660a-rumi.dtb ifeq ($(CONFIG_ARM64),y) always := $(dtb-y) diff --git a/arch/arm/boot/dts/qcom/msm8996.dtsi b/arch/arm/boot/dts/qcom/msm8996.dtsi index 2735cfb93be0..f69c388fbbef 100644 --- a/arch/arm/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996.dtsi @@ -3901,6 +3901,7 @@ clock-names = "core_clk"; clocks = <&clock_mmss clk_camss_cpp_clk>; parent-supply = <&gdsc_camss_top>; + qcom,support-hw-trigger; status = "ok"; }; diff --git a/arch/arm/boot/dts/qcom/msm8998-coresight.dtsi b/arch/arm/boot/dts/qcom/msm8998-coresight.dtsi index 75a90b0499e1..4b81d2754255 100644 --- a/arch/arm/boot/dts/qcom/msm8998-coresight.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-coresight.dtsi @@ -1132,6 +1132,8 @@ <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; + qcom,msr-fix-req; + port{ tpdm_qm_out_tpda: endpoint { remote-endpoint = <&tpda_in_tpdm_qm>; @@ -1151,6 +1153,8 @@ <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; + qcom,msr-fix-req; + port{ tpdm_pimem_out_tpda: endpoint { remote-endpoint = <&tpda_in_tpdm_pimem>; @@ -1205,6 +1209,8 @@ <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; + qcom,msr-fix-req; + port{ tpdm_apss_out_tpda_apss: endpoint { remote-endpoint = <&tpda_apss_in_tpdm_apss>; @@ -1259,6 +1265,8 @@ <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; + qcom,msr-fix-req; + port{ tpdm_mss_out_tpda_mss: endpoint { remote-endpoint = <&tpda_mss_in_tpdm_mss>; @@ -1453,6 +1461,8 @@ <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; + qcom,msr-fix-req; + port{ tpdm_spss_out_tpda_spss: endpoint { remote-endpoint = <&tpda_spss_in_tpdm_spss>; diff --git a/arch/arm/boot/dts/qcom/msm8998-interposer-sdm660.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-sdm660.dtsi index d6b278e2a789..cfb71e3b1cb3 100644 --- a/arch/arm/boot/dts/qcom/msm8998-interposer-sdm660.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-sdm660.dtsi @@ -3067,6 +3067,7 @@ &gdsc_cpp { parent-supply = <&gdsc_camss_top>; + qcom,support-hw-trigger; status = "ok"; }; diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi index 07a0e6e6d5ad..420f78b442b9 100644 --- a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.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 @@ -457,3 +457,7 @@ &blue_led { /delete-property/ linux,default-trigger; }; + +&wil6210 { + status = "ok"; +}; diff --git a/arch/arm/boot/dts/qcom/msm8998.dtsi b/arch/arm/boot/dts/qcom/msm8998.dtsi index 91bd35a8ce07..6a11e7c51ca5 100644 --- a/arch/arm/boot/dts/qcom/msm8998.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998.dtsi @@ -3153,6 +3153,7 @@ &gdsc_cpp { parent-supply = <&gdsc_camss_top>; + qcom,support-hw-trigger; status = "ok"; }; diff --git a/arch/arm/boot/dts/qcom/sdm630-pm660a-rumi.dts b/arch/arm/boot/dts/qcom/sdm630-pm660a-rumi.dts new file mode 100644 index 000000000000..398496a943ac --- /dev/null +++ b/arch/arm/boot/dts/qcom/sdm630-pm660a-rumi.dts @@ -0,0 +1,88 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "sdm630.dtsi" +#include "sdm660-pinctrl.dtsi" +#include "msm-pm660a.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SDM 630 PM660 + PM660A RUMI"; + compatible = "qcom,sdm630-rumi", "qcom,sdm630", "qcom,rumi"; + qcom,board-id = <15 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; + + chosen { + bootargs = "lpm_levels.sleep_disabled=1"; + }; +}; + +&usb3 { + /delete-property/ USB3_GDSC-supply; + /delete-property/ extcon; + dwc3@a800000 { + maximum-speed = "high-speed"; + }; +}; + +&ssphy { + compatible = "usb-nop-xceiv"; +}; + +&qusb_phy0 { + reg = <0x0a928000 0x8000>, + <0x0a8f8800 0x400>, + <0x0a920000 0x100>; + reg-names = "qusb_phy_base", + "qscratch_base", + "emu_phy_base"; + qcom,emulation; + qcom,qusb-phy-init-seq = <0x19 0x1404 + 0x20 0x1414 + 0x79 0x1410 + 0x00 0x1418 + 0x99 0x1404 + 0x04 0x1408 + 0xd9 0x1404>; + qcom,emu-dcm-reset-seq = <0x100000 0x20 + 0x0 0x20 + 0x1a0 0x20 + 0x5 0x14>; +}; + +&uartblsp1dm1 { + status = "ok"; + pinctrl-names = "default"; + pinctrl-0 = <&uart_console_active>; +}; + +&clock_gcc { + compatible = "qcom,dummycc"; + clock-output-names = "gcc_clocks"; +}; + +&clock_gfx { + compatible = "qcom,dummycc"; + clock-output-names = "gfx_clocks"; +}; + +&clock_mmss { + compatible = "qcom,dummycc"; + clock-output-names = "mmss_clocks"; +}; + +&clock_debug { + compatible = "qcom,dummycc"; + clock-output-names = "debug_clocks"; +}; diff --git a/arch/arm/boot/dts/qcom/sdm630-rumi.dts b/arch/arm/boot/dts/qcom/sdm630-rumi.dts index 92e6c4ccc790..ddf954f9f6ff 100644 --- a/arch/arm/boot/dts/qcom/sdm630-rumi.dts +++ b/arch/arm/boot/dts/qcom/sdm630-rumi.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -17,9 +17,11 @@ #include "sdm660-pinctrl.dtsi" / { - model = "Qualcomm Technologies, Inc. SDM 630 RUMI"; + model = "Qualcomm Technologies, Inc. SDM 630 PM660 + PM660L RUMI"; compatible = "qcom,sdm630-rumi", "qcom,sdm630", "qcom,rumi"; qcom,board-id = <15 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; chosen { bootargs = "lpm_levels.sleep_disabled=1"; diff --git a/arch/arm/boot/dts/qcom/sdm630.dtsi b/arch/arm/boot/dts/qcom/sdm630.dtsi index a82979d63244..e42f78fb7708 100644 --- a/arch/arm/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm/boot/dts/qcom/sdm630.dtsi @@ -48,7 +48,7 @@ reg = <0x0 0x100>; enable-method = "psci"; qcom,limits-info = <&mitigation_profile0>; - efficiency = <1024>; + efficiency = <1126>; next-level-cache = <&L2_1>; L2_1: l2-cache { compatible = "arm,arch-cache"; @@ -72,7 +72,7 @@ reg = <0x0 0x101>; enable-method = "psci"; qcom,limits-info = <&mitigation_profile1>; - efficiency = <1024>; + efficiency = <1126>; next-level-cache = <&L2_1>; L1_I_101: l1-icache { compatible = "arm,arch-cache"; @@ -90,7 +90,7 @@ reg = <0x0 0x102>; enable-method = "psci"; qcom,limits-info = <&mitigation_profile2>; - efficiency = <1024>; + efficiency = <1126>; next-level-cache = <&L2_1>; L1_I_102: l1-icache { compatible = "arm,arch-cache"; @@ -108,7 +108,7 @@ reg = <0x0 0x103>; enable-method = "psci"; qcom,limits-info = <&mitigation_profile3>; - efficiency = <1024>; + efficiency = <1126>; next-level-cache = <&L2_1>; L1_I_103: l1-icache { compatible = "arm,arch-cache"; @@ -1294,6 +1294,7 @@ &gdsc_cpp { parent-supply = <&gdsc_camss_top>; + qcom,support-hw-trigger; status = "ok"; }; diff --git a/arch/arm/boot/dts/qcom/sdm660-camera.dtsi b/arch/arm/boot/dts/qcom/sdm660-camera.dtsi index 09f5bec8ca62..747729d158a8 100644 --- a/arch/arm/boot/dts/qcom/sdm660-camera.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660-camera.dtsi @@ -12,13 +12,13 @@ */ &soc { - qcom,msm-cam@8c0000 { + qcom,msm-cam@ca00000 { compatible = "qcom,msm-cam"; - reg = <0x8c0000 0x40000>; + reg = <0xca00000 0x4000>; reg-names = "msm-cam"; status = "ok"; bus-vectors = "suspend", "svs", "nominal", "turbo"; - qcom,bus-votes = <0 300000000 640000000 640000000>; + qcom,bus-votes = <0 150000000 320000000 320000000>; }; qcom,csiphy@c824000 { @@ -44,15 +44,17 @@ <&clock_mmss MMSS_CAMSS_CSI0PHYTIMER_CLK>, <&clock_mmss MMSS_CAMSS_ISPIF_AHB_CLK>, <&clock_mmss CSIPHY_CLK_SRC>, - <&clock_mmss MMSS_CAMSS_CSIPHY0_CLK>; + <&clock_mmss MMSS_CAMSS_CSIPHY0_CLK>, + <&clock_mmss MMSS_CSIPHY_AHB2CRIF_CLK>; clock-names = "mmssnoc_axi", "mnoc_ahb", "bmic_smmu_ahb", "bmic_smmu_axi", "camss_ahb_clk", "camss_top_ahb_clk", "csi_src_clk", "csi_clk", "cphy_csid_clk", "csiphy_timer_src_clk", "csiphy_timer_clk", - "camss_ispif_ahb_clk", "csiphy_clk_src", "csiphy_clk"; + "camss_ispif_ahb_clk", "csiphy_clk_src", "csiphy_clk", + "csiphy_ahb2crif"; qcom,clock-rates = <0 0 0 0 0 0 384000000 0 0 269333333 0 - 0 384000000 0>; + 0 384000000 0 0>; status = "ok"; }; @@ -79,15 +81,17 @@ <&clock_mmss MMSS_CAMSS_CSI1PHYTIMER_CLK>, <&clock_mmss MMSS_CAMSS_ISPIF_AHB_CLK>, <&clock_mmss CSIPHY_CLK_SRC>, - <&clock_mmss MMSS_CAMSS_CSIPHY1_CLK>; + <&clock_mmss MMSS_CAMSS_CSIPHY1_CLK>, + <&clock_mmss MMSS_CSIPHY_AHB2CRIF_CLK>; clock-names = "mmssnoc_axi", "mnoc_ahb", "bmic_smmu_ahb", "bmic_smmu_axi", "camss_ahb_clk", "camss_top_ahb_clk", "csi_src_clk", "csi_clk", "cphy_csid_clk", "csiphy_timer_src_clk", "csiphy_timer_clk", - "camss_ispif_ahb_clk", "csiphy_clk_src", "csiphy_clk"; + "camss_ispif_ahb_clk", "csiphy_clk_src", "csiphy_clk", + "csiphy_ahb2crif"; qcom,clock-rates = <0 0 0 0 0 0 384000000 0 0 269333333 0 - 0 384000000 0>; + 0 384000000 0 0>; status = "ok"; }; @@ -114,15 +118,17 @@ <&clock_mmss MMSS_CAMSS_CSI2PHYTIMER_CLK>, <&clock_mmss MMSS_CAMSS_ISPIF_AHB_CLK>, <&clock_mmss CSIPHY_CLK_SRC>, - <&clock_mmss MMSS_CAMSS_CSIPHY2_CLK>; + <&clock_mmss MMSS_CAMSS_CSIPHY2_CLK>, + <&clock_mmss MMSS_CSIPHY_AHB2CRIF_CLK>; clock-names = "mmssnoc_axi", "mnoc_ahb", "bmic_smmu_ahb", "bmic_smmu_axi", "camss_ahb_clk", "camss_top_ahb_clk", "csi_src_clk", "csi_clk", "cphy_csid_clk", "csiphy_timer_src_clk", "csiphy_timer_clk", - "camss_ispif_ahb_clk", "csiphy_clk_src", "csiphy_clk"; + "camss_ispif_ahb_clk", "csiphy_clk_src", "csiphy_clk", + "csiphy_ahb2crif"; qcom,clock-rates = <0 0 0 0 0 0 384000000 0 0 269333333 0 - 0 384000000 0>; + 0 384000000 0 0>; status = "ok"; }; @@ -310,12 +316,6 @@ label = "cpp"; }; - msm_cam_smmu_cb3 { - compatible = "qcom,msm-cam-smmu-cb"; - iommus = <&mmss_bimc_smmu 0xa01>; - label = "camera_fd"; - }; - msm_cam_smmu_cb4 { compatible = "qcom,msm-cam-smmu-cb"; iommus = <&mmss_bimc_smmu 0x800>; @@ -364,10 +364,6 @@ qcom,clock-rates = <0 0 0 0 200000000 200000000 0 0 0 0 0>; qcom,min-clock-rate = <200000000>; qcom,bus-master = <1>; - qcom,vbif-qos-setting = <0x20 0x10000000>, - <0x24 0x10000000>, - <0x28 0x10000000>, - <0x2C 0x10000000>; status = "ok"; qcom,msm-bus,name = "msm_camera_cpp"; qcom,msm-bus,num-cases = <2>; @@ -378,8 +374,8 @@ qcom,msm-bus-vector-dyn-vote; resets = <&clock_mmss CAMSS_MICRO_BCR>; reset-names = "micro_iface_reset"; - qcom,src-clock-rates = <100000000 200000000 576000000 - 600000000>; + qcom,src-clock-rates = <120000000 256000000 384000000 + 480000000 540000000 576000000>; qcom,cpp-fw-payload-info { qcom,stripe-base = <790>; qcom,plane-base = <715>; @@ -514,9 +510,9 @@ "camss_vfe_ahb_clk", "camss_vfe_vbif_ahb_clk", "camss_vfe_vbif_axi_clk", "vfe_clk_src", "camss_csi_vfe_clk"; - qcom,clock-rates = <0 0 0 0 0 0 0 0 0 0 0 384000000 0 - 0 0 0 0 0 0 0 0 0 0 0 576000000 0 - 0 0 0 0 0 0 0 0 0 0 0 600000000 0>; + qcom,clock-rates = <0 0 0 0 0 0 0 0 0 0 0 256000000 0 + 0 0 0 0 0 0 0 0 0 0 0 480000000 0 + 0 0 0 0 0 0 0 0 0 0 0 576000000 0>; status = "ok"; qos-entries = <8>; qos-regs = <0x404 0x408 0x40c 0x410 0x414 0x418 @@ -594,9 +590,9 @@ "camss_vfe_ahb_clk", "camss_vfe_vbif_ahb_clk", "camss_vfe_vbif_axi_clk", "vfe_clk_src", "camss_csi_vfe_clk"; - qcom,clock-rates = <0 0 0 0 0 0 0 0 0 0 0 384000000 0 - 0 0 0 0 0 0 0 0 0 0 0 576000000 0 - 0 0 0 0 0 0 0 0 0 0 0 600000000 0>; + qcom,clock-rates = <0 0 0 0 0 0 0 0 0 0 0 256000000 0 + 0 0 0 0 0 0 0 0 0 0 0 480000000 0 + 0 0 0 0 0 0 0 0 0 0 0 576000000 0>; status = "ok"; qos-entries = <8>; qos-regs = <0x404 0x408 0x40c 0x410 0x414 0x418 @@ -727,7 +723,7 @@ <&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>, <&clock_mmss MMSS_CAMSS_AHB_CLK>, <&clock_mmss MMSS_CAMSS_TOP_AHB_CLK>, - <&clock_mmss MMSS_CAMSS_JPEG0_CLK>, + <&clock_mmss MMSS_CAMSS_JPEG0_VOTE_CLK>, <&clock_mmss MMSS_CAMSS_JPEG_AHB_CLK>, <&clock_mmss MMSS_CAMSS_JPEG_AXI_CLK >; qcom,clock-rates = <0 0 0 0 0 0 480000000 0 0>; @@ -771,7 +767,7 @@ <&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>, <&clock_mmss MMSS_CAMSS_AHB_CLK>, <&clock_mmss MMSS_CAMSS_TOP_AHB_CLK>, - <&clock_mmss MMSS_CAMSS_JPEG0_CLK>, + <&clock_mmss MMSS_CAMSS_JPEG0_DMA_VOTE_CLK>, <&clock_mmss MMSS_CAMSS_JPEG_AHB_CLK>, <&clock_mmss MMSS_CAMSS_JPEG_AXI_CLK>; qcom,clock-rates = <0 0 0 0 0 0 480000000 0 0>; diff --git a/arch/arm/boot/dts/qcom/sdm660.dtsi b/arch/arm/boot/dts/qcom/sdm660.dtsi index b32742ab00f6..2d31d2859f94 100644 --- a/arch/arm/boot/dts/qcom/sdm660.dtsi +++ b/arch/arm/boot/dts/qcom/sdm660.dtsi @@ -18,6 +18,7 @@ #include <dt-bindings/clock/audio-ext-clk.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/regulator/qcom,rpm-smd-regulator.h> +#include <dt-bindings/clock/qcom,cpu-osm.h> / { model = "Qualcomm Technologies, Inc. SDM 660"; @@ -1179,6 +1180,43 @@ #clock-cells = <1>; }; + msm_cpufreq: qcom,msm-cpufreq { + compatible = "qcom,msm-cpufreq"; + clock-names = "cpu0_clk", "cpu1_clk", "cpu2_clk", + "cpu3_clk", "cpu4_clk", "cpu5_clk", + "cpu6_clk", "cpu7_clk"; + clocks = <&clock_cpu PWRCL_CLK>, + <&clock_cpu PWRCL_CLK>, + <&clock_cpu PWRCL_CLK>, + <&clock_cpu PWRCL_CLK>, + <&clock_cpu PERFCL_CLK>, + <&clock_cpu PERFCL_CLK>, + <&clock_cpu PERFCL_CLK>, + <&clock_cpu PERFCL_CLK>; + + qcom,governor-per-policy; + + qcom,cpufreq-table-0 = + < 300000 >, + < 633600 >, + < 902400 >, + < 1113600 >, + < 1401600 >, + < 1536000 >, + < 1747200 >, + < 1843200 >; + + qcom,cpufreq-table-4 = + < 300000 >, + < 1113600 >, + < 1401600 >, + < 1747200 >, + < 1958400 >, + < 2150400 >, + < 2208000 >, + < 2457600 >; + }; + sdhc_1: sdhci@c0c4000 { compatible = "qcom,sdhci-msm-v5"; reg = <0xc0c4000 0x1000>, <0xc0c5000 0x1000>; @@ -2247,6 +2285,7 @@ &gdsc_cpp { parent-supply = <&gdsc_camss_top>; + qcom,support-hw-trigger; status = "ok"; }; diff --git a/arch/arm/configs/sdm660-perf_defconfig b/arch/arm/configs/sdm660-perf_defconfig index ac968edff299..879b6ff88423 100644 --- a/arch/arm/configs/sdm660-perf_defconfig +++ b/arch/arm/configs/sdm660-perf_defconfig @@ -483,7 +483,9 @@ CONFIG_GPIO_USB_DETECT=y CONFIG_SEEMP_CORE=y CONFIG_USB_BAM=y CONFIG_QCOM_CLK_SMD_RPM=y -CONFIG_MSM_GCC_660=y +CONFIG_MSM_GPUCC_660=y +CONFIG_MSM_MMCC_660=y +CONFIG_CLOCK_CPU_OSM=y CONFIG_QCOM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y CONFIG_ARM_SMMU=y diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index 349af277291d..9015d505f4dc 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -55,6 +55,7 @@ .hw.init = &(struct clk_init_data){ \ .ops = &clk_smd_rpm_ops, \ .name = #_name, \ + .flags = CLK_ENABLE_HAND_OFF, \ .parent_names = (const char *[]){ "xo_board" }, \ .num_parents = 1, \ }, \ @@ -72,6 +73,7 @@ .hw.init = &(struct clk_init_data){ \ .ops = &clk_smd_rpm_ops, \ .name = #_active, \ + .flags = CLK_ENABLE_HAND_OFF, \ .parent_names = (const char *[]){ "xo_board" }, \ .num_parents = 1, \ }, \ @@ -95,6 +97,7 @@ .hw.init = &(struct clk_init_data){ \ .ops = &clk_smd_rpm_branch_ops, \ .name = #_name, \ + .flags = CLK_ENABLE_HAND_OFF, \ .parent_names = (const char *[]){ "xo_board" }, \ .num_parents = 1, \ }, \ @@ -113,6 +116,7 @@ .hw.init = &(struct clk_init_data){ \ .ops = &clk_smd_rpm_branch_ops, \ .name = #_active, \ + .flags = CLK_ENABLE_HAND_OFF, \ .parent_names = (const char *[]){ "xo_board" }, \ .num_parents = 1, \ }, \ @@ -177,6 +181,8 @@ struct rpm_smd_clk_desc { static DEFINE_MUTEX(rpm_smd_clk_lock); +static int clk_smd_rpm_prepare(struct clk_hw *hw); + static int clk_smd_rpm_handoff(struct clk_hw *hw) { int ret = 0; @@ -198,6 +204,8 @@ static int clk_smd_rpm_handoff(struct clk_hw *hw) if (ret) return ret; + ret = clk_smd_rpm_prepare(hw); + return ret; } @@ -462,12 +470,20 @@ static int clk_vote_bimc(struct clk_hw *hw, uint32_t rate) return ret; } +static int clk_smd_rpm_is_enabled(struct clk_hw *hw) +{ + struct clk_smd_rpm *r = to_clk_smd_rpm(hw); + + return r->enabled; +} + static const struct clk_ops clk_smd_rpm_ops = { .prepare = clk_smd_rpm_prepare, .unprepare = clk_smd_rpm_unprepare, .set_rate = clk_smd_rpm_set_rate, .round_rate = clk_smd_rpm_round_rate, .recalc_rate = clk_smd_rpm_recalc_rate, + .is_enabled = clk_smd_rpm_is_enabled, }; static const struct clk_ops clk_smd_rpm_branch_ops = { @@ -475,6 +491,7 @@ static const struct clk_ops clk_smd_rpm_branch_ops = { .unprepare = clk_smd_rpm_unprepare, .round_rate = clk_smd_rpm_round_rate, .recalc_rate = clk_smd_rpm_recalc_rate, + .is_enabled = clk_smd_rpm_is_enabled, }; /* msm8916 */ @@ -817,6 +834,17 @@ static int rpm_smd_clk_probe(struct platform_device *pdev) goto err; } + for (i = (desc->num_rpm_clks + 1); i < num_clks; i++) { + if (!hw_clks[i]) { + clks[i] = ERR_PTR(-ENOENT); + continue; + } + + ret = voter_clk_handoff(hw_clks[i]); + if (ret) + goto err; + } + ret = clk_smd_rpm_enable_scaling(); if (ret) goto err; diff --git a/drivers/clk/qcom/clk-voter.c b/drivers/clk/qcom/clk-voter.c index d3409b9e6b64..60e319620e1b 100644 --- a/drivers/clk/qcom/clk-voter.c +++ b/drivers/clk/qcom/clk-voter.c @@ -123,6 +123,16 @@ static unsigned long voter_clk_recalc_rate(struct clk_hw *hw, return v->rate; } +int voter_clk_handoff(struct clk_hw *hw) +{ + struct clk_voter *v = to_clk_voter(hw); + + v->enabled = true; + + return 0; +} +EXPORT_SYMBOL(voter_clk_handoff); + struct clk_ops clk_ops_voter = { .prepare = voter_clk_prepare, .unprepare = voter_clk_unprepare, diff --git a/drivers/clk/qcom/clk-voter.h b/drivers/clk/qcom/clk-voter.h index 27092ae7d131..abc26cd94cd5 100644 --- a/drivers/clk/qcom/clk-voter.h +++ b/drivers/clk/qcom/clk-voter.h @@ -36,6 +36,7 @@ extern struct clk_ops clk_ops_voter; .hw.init = &(struct clk_init_data){ \ .ops = &clk_ops_voter, \ .name = #clk_name, \ + .flags = CLK_ENABLE_HAND_OFF, \ .parent_names = (const char *[]){ #_parent_name }, \ .num_parents = 1, \ }, \ @@ -47,4 +48,6 @@ extern struct clk_ops clk_ops_voter; #define DEFINE_CLK_BRANCH_VOTER(clk_name, _parent_name) \ __DEFINE_CLK_VOTER(clk_name, _parent_name, 1000, 1) +int voter_clk_handoff(struct clk_hw *hw); + #endif diff --git a/drivers/gpu/msm/adreno-gpulist.h b/drivers/gpu/msm/adreno-gpulist.h index e6163384f9c1..6a00919f144b 100644 --- a/drivers/gpu/msm/adreno-gpulist.h +++ b/drivers/gpu/msm/adreno-gpulist.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-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 @@ -289,7 +289,8 @@ static const struct adreno_gpu_core adreno_gpulist[] = { .major = 1, .minor = 2, .patchid = ANY_ID, - .features = ADRENO_64BIT, + .features = ADRENO_64BIT | ADRENO_CONTENT_PROTECTION | + ADRENO_CPZ_RETENTION, .pm4fw_name = "a530_pm4.fw", .pfpfw_name = "a530_pfp.fw", .gpudev = &adreno_a5xx_gpudev, diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 9ec0928658cd..5743588aa52b 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -136,6 +136,7 @@ struct mmc_blk_data { #define MMC_BLK_DISCARD BIT(2) #define MMC_BLK_SECDISCARD BIT(3) #define MMC_BLK_FLUSH BIT(4) +#define MMC_BLK_PARTSWITCH BIT(5) /* * Only set in main mmc_blk_data associated @@ -1416,8 +1417,13 @@ static inline int mmc_blk_part_switch(struct mmc_card *card, ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG, part_config, card->ext_csd.part_time); - if (ret) + + if (ret) { + pr_err("%s: mmc_blk_part_switch failure, %d -> %d\n", + mmc_hostname(card->host), main_md->part_curr, + md->part_type); return ret; + } card->ext_csd.part_config = part_config; card->part_curr = md->part_type; @@ -3933,6 +3939,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) struct mmc_host *host = card->host; unsigned long flags; unsigned int cmd_flags = req ? req->cmd_flags : 0; + int err; if (req && !mq->mqrq_prev->req) { /* claim host only for the first request */ @@ -3946,7 +3953,17 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) } ret = mmc_blk_part_switch(card, md); + if (ret) { + err = mmc_blk_reset(md, card->host, MMC_BLK_PARTSWITCH); + if (!err) { + pr_err("%s: mmc_blk_reset(MMC_BLK_PARTSWITCH) succeeded.\n", + mmc_hostname(host)); + mmc_blk_reset_success(md, MMC_BLK_PARTSWITCH); + } else + pr_err("%s: mmc_blk_reset(MMC_BLK_PARTSWITCH) failed.\n", + mmc_hostname(host)); + if (req) { blk_end_request_all(req, -EIO); } diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index a444a3a80f52..152a3e3b4f47 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1748,6 +1748,10 @@ EXPORT_SYMBOL(mmc_start_req); */ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) { +#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME + if (mmc_bus_needs_resume(host)) + mmc_resume_bus(host); +#endif __mmc_start_req(host, mrq); mmc_wait_for_req_done(host, mrq); } @@ -3105,9 +3109,6 @@ int mmc_resume_bus(struct mmc_host *host) } } - if (host->bus_ops->detect && !host->bus_dead) - host->bus_ops->detect(host); - mmc_bus_put(host); pr_debug("%s: Deferred resume completed\n", mmc_hostname(host)); return 0; diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 89288bd1eaa4..a3f650f5ee9f 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -2514,12 +2514,6 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend) goto out; } - if (mmc_card_doing_auto_bkops(host->card)) { - err = mmc_set_auto_bkops(host->card, false); - if (err) - goto out; - } - err = mmc_flush_cache(host->card); if (err) goto out; @@ -2599,9 +2593,6 @@ static int mmc_partial_init(struct mmc_host *host) pr_debug("%s: %s: reading and comparing ext_csd successful\n", mmc_hostname(host), __func__); - if (mmc_card_support_auto_bkops(host->card)) - (void)mmc_set_auto_bkops(host->card, true); - if (card->ext_csd.cmdq_support && (card->host->caps2 & MMC_CAP2_CMD_QUEUE)) { err = mmc_select_cmdq(card); diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index e7ebc3cb8eda..5fedab49cf34 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -1078,6 +1078,7 @@ static int mmc_sdio_resume(struct mmc_host *host) mmc_release_host(host); host->pm_flags &= ~MMC_PM_KEEP_POWER; + host->pm_flags &= ~MMC_PM_WAKE_SDIO_IRQ; return err; } diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index d51195e8a352..08822464d82f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2997,7 +2997,8 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) host->ops->adma_workaround(host, intmask); } if (host->data->error) { - if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT)) { + if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT + | SDHCI_INT_DATA_END_BIT)) { command = SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)); if ((command != MMC_SEND_TUNING_BLOCK_HS200) && diff --git a/drivers/net/ethernet/msm/rndis_ipa.c b/drivers/net/ethernet/msm/rndis_ipa.c index 15cfb1d1dbeb..62e72ca01929 100644 --- a/drivers/net/ethernet/msm/rndis_ipa.c +++ b/drivers/net/ethernet/msm/rndis_ipa.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -135,29 +135,6 @@ enum rndis_ipa_operation { RNDIS_IPA_DEBUG("Driver state: %s\n",\ rndis_ipa_state_string(ctx->state)); -/** - * struct rndis_loopback_pipe - hold all information needed for - * pipe loopback logic - */ -struct rndis_loopback_pipe { - struct sps_pipe *ipa_sps; - struct ipa_sps_params ipa_sps_connect; - struct ipa_connect_params ipa_connect_params; - - struct sps_pipe *dma_sps; - struct sps_connect dma_connect; - - struct sps_alloc_dma_chan dst_alloc; - struct sps_dma_chan ipa_sps_channel; - enum sps_mode mode; - u32 ipa_peer_bam_hdl; - u32 peer_pipe_index; - u32 ipa_drv_ep_hdl; - u32 ipa_pipe_index; - enum ipa_client_type ipa_client; - ipa_notify_cb ipa_callback; - struct ipa_ep_cfg *ipa_ep_cfg; -}; /** * struct rndis_ipa_dev - main driver context parameters @@ -172,13 +149,9 @@ struct rndis_loopback_pipe { * @rx_dump_enable: dump all Rx packets * @icmp_filter: allow all ICMP packet to pass through the filters * @rm_enable: flag that enable/disable Resource manager request prior to Tx - * @loopback_enable: flag that enable/disable USB stub loopback * @deaggregation_enable: enable/disable IPA HW deaggregation logic * @during_xmit_error: flags that indicate that the driver is in a middle * of error handling in Tx path - * @usb_to_ipa_loopback_pipe: usb to ipa (Rx) pipe representation for loopback - * @ipa_to_usb_loopback_pipe: ipa to usb (Tx) pipe representation for loopback - * @bam_dma_hdl: handle representing bam-dma, used for loopback logic * @directory: holds all debug flags used by the driver to allow cleanup * for driver unload * @eth_ipv4_hdr_hdl: saved handle for ipv4 header-insertion table @@ -208,12 +181,8 @@ struct rndis_ipa_dev { bool rx_dump_enable; bool icmp_filter; bool rm_enable; - bool loopback_enable; bool deaggregation_enable; bool during_xmit_error; - struct rndis_loopback_pipe usb_to_ipa_loopback_pipe; - struct rndis_loopback_pipe ipa_to_usb_loopback_pipe; - u32 bam_dma_hdl; struct dentry *directory; uint32_t eth_ipv4_hdr_hdl; uint32_t eth_ipv6_hdr_hdl; @@ -277,31 +246,12 @@ static int resource_request(struct rndis_ipa_dev *rndis_ipa_ctx); static void resource_release(struct rndis_ipa_dev *rndis_ipa_ctx); static netdev_tx_t rndis_ipa_start_xmit(struct sk_buff *skb, struct net_device *net); -static int rndis_ipa_loopback_pipe_create( - struct rndis_ipa_dev *rndis_ipa_ctx, - struct rndis_loopback_pipe *loopback_pipe); -static void rndis_ipa_destroy_loopback_pipe( - struct rndis_loopback_pipe *loopback_pipe); -static int rndis_ipa_create_loopback(struct rndis_ipa_dev *rndis_ipa_ctx); -static void rndis_ipa_destroy_loopback(struct rndis_ipa_dev *rndis_ipa_ctx); -static int rndis_ipa_setup_loopback(bool enable, - struct rndis_ipa_dev *rndis_ipa_ctx); -static int rndis_ipa_debugfs_loopback_open(struct inode *inode, - struct file *file); static int rndis_ipa_debugfs_atomic_open(struct inode *inode, struct file *file); static int rndis_ipa_debugfs_aggr_open(struct inode *inode, struct file *file); static ssize_t rndis_ipa_debugfs_aggr_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos); -static ssize_t rndis_ipa_debugfs_loopback_write(struct file *file, - const char __user *buf, size_t count, loff_t *ppos); -static ssize_t rndis_ipa_debugfs_enable_write(struct file *file, - const char __user *buf, size_t count, loff_t *ppos); -static ssize_t rndis_ipa_debugfs_enable_read(struct file *file, - char __user *ubuf, size_t count, loff_t *ppos); -static ssize_t rndis_ipa_debugfs_loopback_read(struct file *file, - char __user *ubuf, size_t count, loff_t *ppos); static ssize_t rndis_ipa_debugfs_atomic_read(struct file *file, char __user *ubuf, size_t count, loff_t *ppos); static void rndis_ipa_dump_skb(struct sk_buff *skb); @@ -336,12 +286,6 @@ const struct file_operations rndis_ipa_debugfs_atomic_ops = { .read = rndis_ipa_debugfs_atomic_read, }; -const struct file_operations rndis_ipa_loopback_ops = { - .open = rndis_ipa_debugfs_loopback_open, - .read = rndis_ipa_debugfs_loopback_read, - .write = rndis_ipa_debugfs_loopback_write, -}; - const struct file_operations rndis_ipa_aggr_ops = { .open = rndis_ipa_debugfs_aggr_open, .write = rndis_ipa_debugfs_aggr_write, @@ -2195,14 +2139,6 @@ static int rndis_ipa_debugfs_init(struct rndis_ipa_dev *rndis_ipa_ctx) goto fail_file; } - file = debugfs_create_file("loopback_enable", flags_read_write, - rndis_ipa_ctx->directory, - rndis_ipa_ctx, &rndis_ipa_loopback_ops); - if (!file) { - RNDIS_IPA_ERROR("could not create outstanding file\n"); - goto fail_file; - } - file = debugfs_create_u8("state", flags_read_only, rndis_ipa_ctx->directory, (u8 *)&rndis_ipa_ctx->state); if (!file) { @@ -2358,59 +2294,6 @@ static ssize_t rndis_ipa_debugfs_aggr_write(struct file *file, return count; } -static int rndis_ipa_debugfs_loopback_open(struct inode *inode, - struct file *file) -{ - struct rndis_ipa_dev *rndis_ipa_ctx = inode->i_private; - file->private_data = rndis_ipa_ctx; - - return 0; -} - -static ssize_t rndis_ipa_debugfs_loopback_read(struct file *file, - char __user *ubuf, size_t count, loff_t *ppos) -{ - int cnt; - struct rndis_ipa_dev *rndis_ipa_ctx = file->private_data; - - file->private_data = &rndis_ipa_ctx->loopback_enable; - - cnt = rndis_ipa_debugfs_enable_read(file, - ubuf, count, ppos); - - return cnt; -} - -static ssize_t rndis_ipa_debugfs_loopback_write(struct file *file, - const char __user *buf, size_t count, loff_t *ppos) -{ - int retval; - int cnt; - struct rndis_ipa_dev *rndis_ipa_ctx = file->private_data; - bool old_state = rndis_ipa_ctx->loopback_enable; - - file->private_data = &rndis_ipa_ctx->loopback_enable; - - cnt = rndis_ipa_debugfs_enable_write(file, - buf, count, ppos); - - RNDIS_IPA_DEBUG("loopback_enable was set to:%d->%d\n", - old_state, rndis_ipa_ctx->loopback_enable); - - if (old_state == rndis_ipa_ctx->loopback_enable) { - RNDIS_IPA_ERROR("NOP - same state\n"); - return cnt; - } - - retval = rndis_ipa_setup_loopback( - rndis_ipa_ctx->loopback_enable, - rndis_ipa_ctx); - if (retval) - rndis_ipa_ctx->loopback_enable = old_state; - - return cnt; -} - static int rndis_ipa_debugfs_atomic_open(struct inode *inode, struct file *file) { struct rndis_ipa_dev *rndis_ipa_ctx = inode->i_private; @@ -2441,319 +2324,6 @@ static ssize_t rndis_ipa_debugfs_atomic_read(struct file *file, return simple_read_from_buffer(ubuf, count, ppos, atomic_str, nbytes); } -static ssize_t rndis_ipa_debugfs_enable_read(struct file *file, - char __user *ubuf, size_t count, loff_t *ppos) -{ - int nbytes; - int size = 0; - int ret; - loff_t pos; - u8 enable_str[sizeof(char)*3] = {0}; - bool *enable = file->private_data; - pos = *ppos; - nbytes = scnprintf(enable_str, sizeof(enable_str), "%d\n", *enable); - ret = simple_read_from_buffer(ubuf, count, ppos, enable_str, nbytes); - if (ret < 0) { - RNDIS_IPA_ERROR("simple_read_from_buffer problem\n"); - return ret; - } - size += ret; - count -= nbytes; - *ppos = pos + size; - return size; -} - -static ssize_t rndis_ipa_debugfs_enable_write(struct file *file, - const char __user *buf, size_t count, loff_t *ppos) -{ - unsigned long missing; - char input; - bool *enable = file->private_data; - if (count != sizeof(input) + 1) { - RNDIS_IPA_ERROR("wrong input length(%zd)\n", count); - return -EINVAL; - } - if (!buf) { - RNDIS_IPA_ERROR("Bad argument\n"); - return -EINVAL; - } - missing = copy_from_user(&input, buf, 1); - if (missing) - return -EFAULT; - RNDIS_IPA_DEBUG("input received %c\n", input); - *enable = input - '0'; - RNDIS_IPA_DEBUG("value was set to %d\n", *enable); - return count; -} - -/** - * Connects IPA->BAMDMA - * This shall simulate the path from IPA to USB - * Allowing the driver TX path - */ -static int rndis_ipa_loopback_pipe_create( - struct rndis_ipa_dev *rndis_ipa_ctx, - struct rndis_loopback_pipe *loopback_pipe) -{ - int retval; - - RNDIS_IPA_LOG_ENTRY(); - - /* SPS pipe has two side handshake - * This is the first handshake of IPA->BAMDMA, - * This is the IPA side - */ - loopback_pipe->ipa_connect_params.client = loopback_pipe->ipa_client; - loopback_pipe->ipa_connect_params.client_bam_hdl = - rndis_ipa_ctx->bam_dma_hdl; - loopback_pipe->ipa_connect_params.client_ep_idx = - loopback_pipe->peer_pipe_index; - loopback_pipe->ipa_connect_params.desc_fifo_sz = BAM_DMA_DESC_FIFO_SIZE; - loopback_pipe->ipa_connect_params.data_fifo_sz = BAM_DMA_DATA_FIFO_SIZE; - loopback_pipe->ipa_connect_params.notify = loopback_pipe->ipa_callback; - loopback_pipe->ipa_connect_params.priv = rndis_ipa_ctx; - loopback_pipe->ipa_connect_params.ipa_ep_cfg = - *(loopback_pipe->ipa_ep_cfg); - - /* loopback_pipe->ipa_sps_connect is out param */ - retval = ipa_connect(&loopback_pipe->ipa_connect_params, - &loopback_pipe->ipa_sps_connect, - &loopback_pipe->ipa_drv_ep_hdl); - if (retval) { - RNDIS_IPA_ERROR("ipa_connect() fail (%d)", retval); - return retval; - } - RNDIS_IPA_DEBUG("ipa_connect() succeeded, ipa_drv_ep_hdl=%d", - loopback_pipe->ipa_drv_ep_hdl); - - /* SPS pipe has two side handshake - * This is the second handshake of IPA->BAMDMA, - * This is the BAMDMA side - */ - loopback_pipe->dma_sps = sps_alloc_endpoint(); - if (!loopback_pipe->dma_sps) { - RNDIS_IPA_ERROR("sps_alloc_endpoint() failed "); - retval = -ENOMEM; - goto fail_sps_alloc; - } - - retval = sps_get_config(loopback_pipe->dma_sps, - &loopback_pipe->dma_connect); - if (retval) { - RNDIS_IPA_ERROR("sps_get_config() failed (%d)", retval); - goto fail_get_cfg; - } - - /* Start setting the non IPA ep for SPS driver*/ - loopback_pipe->dma_connect.mode = loopback_pipe->mode; - - /* SPS_MODE_DEST: DMA end point is the dest (consumer) IPA->DMA */ - if (loopback_pipe->mode == SPS_MODE_DEST) { - - loopback_pipe->dma_connect.source = - loopback_pipe->ipa_sps_connect.ipa_bam_hdl; - loopback_pipe->dma_connect.src_pipe_index = - loopback_pipe->ipa_sps_connect.ipa_ep_idx; - loopback_pipe->dma_connect.destination = - rndis_ipa_ctx->bam_dma_hdl; - loopback_pipe->dma_connect.dest_pipe_index = - loopback_pipe->peer_pipe_index; - - /* SPS_MODE_SRC: DMA end point is the source (producer) DMA->IPA */ - } else { - - loopback_pipe->dma_connect.source = - rndis_ipa_ctx->bam_dma_hdl; - loopback_pipe->dma_connect.src_pipe_index = - loopback_pipe->peer_pipe_index; - loopback_pipe->dma_connect.destination = - loopback_pipe->ipa_sps_connect.ipa_bam_hdl; - loopback_pipe->dma_connect.dest_pipe_index = - loopback_pipe->ipa_sps_connect.ipa_ep_idx; - - } - - loopback_pipe->dma_connect.desc = loopback_pipe->ipa_sps_connect.desc; - loopback_pipe->dma_connect.data = loopback_pipe->ipa_sps_connect.data; - loopback_pipe->dma_connect.event_thresh = 0x10; - /* BAM-to-BAM */ - loopback_pipe->dma_connect.options = SPS_O_AUTO_ENABLE; - - RNDIS_IPA_DEBUG("doing sps_connect() with - "); - RNDIS_IPA_DEBUG("src bam_hdl:0x%lx, src_pipe#:%d", - loopback_pipe->dma_connect.source, - loopback_pipe->dma_connect.src_pipe_index); - RNDIS_IPA_DEBUG("dst bam_hdl:0x%lx, dst_pipe#:%d", - loopback_pipe->dma_connect.destination, - loopback_pipe->dma_connect.dest_pipe_index); - - retval = sps_connect(loopback_pipe->dma_sps, - &loopback_pipe->dma_connect); - if (retval) { - RNDIS_IPA_ERROR("sps_connect() fail for BAMDMA side (%d)", - retval); - goto fail_sps_connect; - } - - RNDIS_IPA_LOG_EXIT(); - - return 0; - -fail_sps_connect: -fail_get_cfg: - sps_free_endpoint(loopback_pipe->dma_sps); -fail_sps_alloc: - ipa_disconnect(loopback_pipe->ipa_drv_ep_hdl); - return retval; -} - -static void rndis_ipa_destroy_loopback_pipe( - struct rndis_loopback_pipe *loopback_pipe) -{ - sps_disconnect(loopback_pipe->dma_sps); - sps_free_endpoint(loopback_pipe->dma_sps); -} - -/** - * rndis_ipa_create_loopback() - create a BAM-DMA loopback - * in order to replace the USB core - */ -static int rndis_ipa_create_loopback(struct rndis_ipa_dev *rndis_ipa_ctx) -{ - /* The BAM handle should be use as - * source/destination in the sps_connect() - */ - int retval; - - RNDIS_IPA_LOG_ENTRY(); - - - retval = sps_ctrl_bam_dma_clk(true); - if (retval) { - RNDIS_IPA_ERROR("fail on enabling BAM-DMA clocks"); - return -ENODEV; - } - - /* Get BAM handle instead of USB handle */ - rndis_ipa_ctx->bam_dma_hdl = sps_dma_get_bam_handle(); - if (!rndis_ipa_ctx->bam_dma_hdl) { - RNDIS_IPA_ERROR("sps_dma_get_bam_handle() failed"); - return -ENODEV; - } - RNDIS_IPA_DEBUG("sps_dma_get_bam_handle() succeeded (0x%x)", - rndis_ipa_ctx->bam_dma_hdl); - - /* IPA<-BAMDMA, NetDev Rx path (BAMDMA is the USB stub) */ - rndis_ipa_ctx->usb_to_ipa_loopback_pipe.ipa_client = - IPA_CLIENT_USB_PROD; - rndis_ipa_ctx->usb_to_ipa_loopback_pipe.peer_pipe_index = - FROM_USB_TO_IPA_BAMDMA; - /*DMA EP mode*/ - rndis_ipa_ctx->usb_to_ipa_loopback_pipe.mode = SPS_MODE_SRC; - rndis_ipa_ctx->usb_to_ipa_loopback_pipe.ipa_ep_cfg = - &usb_to_ipa_ep_cfg_deaggr_en; - rndis_ipa_ctx->usb_to_ipa_loopback_pipe.ipa_callback = - rndis_ipa_packet_receive_notify; - RNDIS_IPA_DEBUG("setting up IPA<-BAMDAM pipe (RNDIS_IPA RX path)"); - retval = rndis_ipa_loopback_pipe_create(rndis_ipa_ctx, - &rndis_ipa_ctx->usb_to_ipa_loopback_pipe); - if (retval) { - RNDIS_IPA_ERROR("fail to close IPA->BAMDAM pipe"); - goto fail_to_usb; - } - RNDIS_IPA_DEBUG("IPA->BAMDAM pipe successfully connected (TX path)"); - - /* IPA->BAMDMA, NetDev Tx path (BAMDMA is the USB stub)*/ - rndis_ipa_ctx->ipa_to_usb_loopback_pipe.ipa_client = - IPA_CLIENT_USB_CONS; - /*DMA EP mode*/ - rndis_ipa_ctx->ipa_to_usb_loopback_pipe.mode = SPS_MODE_DEST; - rndis_ipa_ctx->ipa_to_usb_loopback_pipe.ipa_ep_cfg = &ipa_to_usb_ep_cfg; - rndis_ipa_ctx->ipa_to_usb_loopback_pipe.peer_pipe_index = - FROM_IPA_TO_USB_BAMDMA; - rndis_ipa_ctx->ipa_to_usb_loopback_pipe.ipa_callback = - rndis_ipa_tx_complete_notify; - RNDIS_IPA_DEBUG("setting up IPA->BAMDAM pipe (RNDIS_IPA TX path)"); - retval = rndis_ipa_loopback_pipe_create(rndis_ipa_ctx, - &rndis_ipa_ctx->ipa_to_usb_loopback_pipe); - if (retval) { - RNDIS_IPA_ERROR("fail to close IPA<-BAMDAM pipe"); - goto fail_from_usb; - } - RNDIS_IPA_DEBUG("IPA<-BAMDAM pipe successfully connected(RX path)"); - - RNDIS_IPA_LOG_EXIT(); - - return 0; - -fail_from_usb: - rndis_ipa_destroy_loopback_pipe( - &rndis_ipa_ctx->usb_to_ipa_loopback_pipe); -fail_to_usb: - - return retval; -} - -static void rndis_ipa_destroy_loopback(struct rndis_ipa_dev *rndis_ipa_ctx) -{ - rndis_ipa_destroy_loopback_pipe( - &rndis_ipa_ctx->ipa_to_usb_loopback_pipe); - rndis_ipa_destroy_loopback_pipe( - &rndis_ipa_ctx->usb_to_ipa_loopback_pipe); - sps_dma_free_bam_handle(rndis_ipa_ctx->bam_dma_hdl); - if (sps_ctrl_bam_dma_clk(false)) - RNDIS_IPA_ERROR("fail to disable BAM-DMA clocks"); -} - -/** - * rndis_ipa_setup_loopback() - create/destroy a loopback on IPA HW - * (as USB pipes loopback) and notify RNDIS_IPA netdev for pipe connected - * @enable: flag that determines if the loopback should be created or destroyed - * @rndis_ipa_ctx: driver main context - * - * This function is the main loopback logic. - * It shall create/destory the loopback by using BAM-DMA and notify - * the netdev accordingly. - */ -static int rndis_ipa_setup_loopback(bool enable, - struct rndis_ipa_dev *rndis_ipa_ctx) -{ - int retval; - - if (!enable) { - rndis_ipa_destroy_loopback(rndis_ipa_ctx); - RNDIS_IPA_DEBUG("loopback destroy done"); - retval = rndis_ipa_pipe_disconnect_notify(rndis_ipa_ctx); - if (retval) { - RNDIS_IPA_ERROR("connect notify fail"); - return -ENODEV; - } - return 0; - } - - RNDIS_IPA_DEBUG("creating loopback (instead of USB core)"); - retval = rndis_ipa_create_loopback(rndis_ipa_ctx); - RNDIS_IPA_DEBUG("creating loopback- %s", (retval ? "FAIL" : "OK")); - if (retval) { - RNDIS_IPA_ERROR("Fail to connect loopback"); - return -ENODEV; - } - retval = rndis_ipa_pipe_connect_notify( - rndis_ipa_ctx->usb_to_ipa_loopback_pipe.ipa_drv_ep_hdl, - rndis_ipa_ctx->ipa_to_usb_loopback_pipe.ipa_drv_ep_hdl, - BAM_DMA_DATA_FIFO_SIZE, - 15, - BAM_DMA_DATA_FIFO_SIZE - rndis_ipa_ctx->net->mtu, - rndis_ipa_ctx); - if (retval) { - RNDIS_IPA_ERROR("connect notify fail"); - return -ENODEV; - } - - return 0; - -} - static int rndis_ipa_init_module(void) { pr_info("RNDIS_IPA module is loaded."); diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa.c b/drivers/platform/msm/ipa/ipa_v2/ipa.c index 73add50cf224..d82651f7b492 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa.c @@ -450,7 +450,7 @@ static int ipa_open(struct inode *inode, struct file *filp) { struct ipa_context *ctx = NULL; - IPADBG("ENTER\n"); + IPADBG_LOW("ENTER\n"); ctx = container_of(inode->i_cdev, struct ipa_context, cdev); filp->private_data = ctx; @@ -2936,11 +2936,11 @@ static int ipa_get_clks(struct device *dev) void _ipa_enable_clks_v2_0(void) { - IPADBG("enabling gcc_ipa_clk\n"); + IPADBG_LOW("enabling gcc_ipa_clk\n"); if (ipa_clk) { clk_prepare(ipa_clk); clk_enable(ipa_clk); - IPADBG("curr_ipa_clk_rate=%d", ipa_ctx->curr_ipa_clk_rate); + IPADBG_LOW("curr_ipa_clk_rate=%d", ipa_ctx->curr_ipa_clk_rate); clk_set_rate(ipa_clk, ipa_ctx->curr_ipa_clk_rate); ipa_uc_notify_clk_state(true); } else { @@ -3072,7 +3072,7 @@ void _ipa_disable_clks_v1_1(void) void _ipa_disable_clks_v2_0(void) { - IPADBG("disabling gcc_ipa_clk\n"); + IPADBG_LOW("disabling gcc_ipa_clk\n"); ipa_suspend_apps_pipes(true); ipa_sps_irq_control_all(false); ipa_uc_notify_clk_state(false); @@ -3093,7 +3093,7 @@ void _ipa_disable_clks_v2_0(void) */ void ipa_disable_clks(void) { - IPADBG("disabling IPA clocks and bus voting\n"); + IPADBG_LOW("disabling IPA clocks and bus voting\n"); ipa_ctx->ctrl->ipa_disable_clks(); @@ -3237,7 +3237,7 @@ void ipa2_inc_client_enable_clks(struct ipa_active_client_logging_info *id) ipa_ctx->ipa_active_clients.cnt++; if (ipa_ctx->ipa_active_clients.cnt == 1) ipa_enable_clks(); - IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients.cnt); + IPADBG_LOW("active clients = %d\n", ipa_ctx->ipa_active_clients.cnt); ipa_active_clients_unlock(); } @@ -3269,7 +3269,7 @@ int ipa2_inc_client_enable_clks_no_block(struct ipa_active_client_logging_info ipa2_active_clients_log_inc(id, true); ipa_ctx->ipa_active_clients.cnt++; - IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients.cnt); + IPADBG_LOW("active clients = %d\n", ipa_ctx->ipa_active_clients.cnt); bail: ipa_active_clients_trylock_unlock(&flags); @@ -3297,7 +3297,7 @@ void ipa2_dec_client_disable_clks(struct ipa_active_client_logging_info *id) ipa_active_clients_lock(); ipa2_active_clients_log_dec(id, false); ipa_ctx->ipa_active_clients.cnt--; - IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients.cnt); + IPADBG_LOW("active clients = %d\n", ipa_ctx->ipa_active_clients.cnt); if (ipa_ctx->ipa_active_clients.cnt == 0) { if (ipa_ctx->tag_process_before_gating) { IPA_ACTIVE_CLIENTS_PREP_SPECIAL(log_info, @@ -3337,7 +3337,7 @@ void ipa_inc_acquire_wakelock(enum ipa_wakelock_ref_client ref_client) ipa_ctx->wakelock_ref_cnt.cnt |= (1 << ref_client); if (ipa_ctx->wakelock_ref_cnt.cnt) __pm_stay_awake(&ipa_ctx->w_lock); - IPADBG("active wakelock ref cnt = %d client enum %d\n", + IPADBG_LOW("active wakelock ref cnt = %d client enum %d\n", ipa_ctx->wakelock_ref_cnt.cnt, ref_client); spin_unlock_irqrestore(&ipa_ctx->wakelock_ref_cnt.spinlock, flags); } @@ -3358,7 +3358,7 @@ void ipa_dec_release_wakelock(enum ipa_wakelock_ref_client ref_client) return; spin_lock_irqsave(&ipa_ctx->wakelock_ref_cnt.spinlock, flags); ipa_ctx->wakelock_ref_cnt.cnt &= ~(1 << ref_client); - IPADBG("active wakelock ref cnt = %d client enum %d\n", + IPADBG_LOW("active wakelock ref cnt = %d client enum %d\n", ipa_ctx->wakelock_ref_cnt.cnt, ref_client); if (ipa_ctx->wakelock_ref_cnt.cnt == 0) __pm_relax(&ipa_ctx->w_lock); @@ -3402,7 +3402,7 @@ int ipa2_set_required_perf_profile(enum ipa_voltage_level floor_voltage, enum ipa_voltage_level needed_voltage; u32 clk_rate; - IPADBG("floor_voltage=%d, bandwidth_mbps=%u", + IPADBG_LOW("floor_voltage=%d, bandwidth_mbps=%u", floor_voltage, bandwidth_mbps); if (floor_voltage < IPA_VOLTAGE_UNSPECIFIED || @@ -3412,7 +3412,7 @@ int ipa2_set_required_perf_profile(enum ipa_voltage_level floor_voltage, } if (ipa_ctx->enable_clock_scaling) { - IPADBG("Clock scaling is enabled\n"); + IPADBG_LOW("Clock scaling is enabled\n"); if (bandwidth_mbps >= ipa_ctx->ctrl->clock_scaling_bw_threshold_turbo) needed_voltage = IPA_VOLTAGE_TURBO; @@ -3422,7 +3422,7 @@ int ipa2_set_required_perf_profile(enum ipa_voltage_level floor_voltage, else needed_voltage = IPA_VOLTAGE_SVS; } else { - IPADBG("Clock scaling is disabled\n"); + IPADBG_LOW("Clock scaling is disabled\n"); needed_voltage = IPA_VOLTAGE_NOMINAL; } @@ -3444,13 +3444,13 @@ int ipa2_set_required_perf_profile(enum ipa_voltage_level floor_voltage, } if (clk_rate == ipa_ctx->curr_ipa_clk_rate) { - IPADBG("Same voltage\n"); + IPADBG_LOW("Same voltage\n"); return 0; } ipa_active_clients_lock(); ipa_ctx->curr_ipa_clk_rate = clk_rate; - IPADBG("setting clock rate to %u\n", ipa_ctx->curr_ipa_clk_rate); + IPADBG_LOW("setting clock rate to %u\n", ipa_ctx->curr_ipa_clk_rate); if (ipa_ctx->ipa_active_clients.cnt > 0) { clk_set_rate(ipa_clk, ipa_ctx->curr_ipa_clk_rate); if (ipa_ctx->ipa_hw_mode != IPA_HW_MODE_VIRTUAL) @@ -3458,10 +3458,10 @@ int ipa2_set_required_perf_profile(enum ipa_voltage_level floor_voltage, ipa_ctx->ipa_bus_hdl, ipa_get_bus_vote())) WARN_ON(1); } else { - IPADBG("clocks are gated, not setting rate\n"); + IPADBG_LOW("clocks are gated, not setting rate\n"); } ipa_active_clients_unlock(); - IPADBG("Done\n"); + IPADBG_LOW("Done\n"); return 0; } @@ -3755,6 +3755,13 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p, goto fail_mem_ctx; } + ipa_ctx->logbuf = ipc_log_context_create(IPA_IPC_LOG_PAGES, "ipa", 0); + if (ipa_ctx->logbuf == NULL) { + IPAERR("failed to get logbuf\n"); + result = -ENOMEM; + goto fail_logbuf; + } + ipa_ctx->pdev = ipa_dev; ipa_ctx->uc_pdev = ipa_dev; ipa_ctx->smmu_present = smmu_info.present; @@ -4289,6 +4296,8 @@ fail_bus_reg: fail_bind: kfree(ipa_ctx->ctrl); fail_mem_ctrl: + ipc_log_context_destroy(ipa_ctx->logbuf); +fail_logbuf: kfree(ipa_ctx); ipa_ctx = NULL; fail_mem_ctx: diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c index 50c387ec785d..7ce51fccb822 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c @@ -1804,6 +1804,44 @@ static ssize_t ipa_write_polling_iteration(struct file *file, return count; } +static ssize_t ipa_enable_ipc_low(struct file *file, + const char __user *ubuf, size_t count, loff_t *ppos) +{ + unsigned long missing; + s8 option = 0; + + if (sizeof(dbg_buff) < count + 1) + return -EFAULT; + + missing = copy_from_user(dbg_buff, ubuf, count); + if (missing) + return -EFAULT; + + dbg_buff[count] = '\0'; + if (kstrtos8(dbg_buff, 0, &option)) + return -EFAULT; + + if (option) { + if (!ipa_ctx->logbuf_low) { + ipa_ctx->logbuf_low = + ipc_log_context_create(IPA_IPC_LOG_PAGES, + "ipa_low", 0); + } + + if (ipa_ctx->logbuf_low == NULL) { + IPAERR("failed to get logbuf_low\n"); + return -EFAULT; + } + + } else { + if (ipa_ctx->logbuf_low) + ipc_log_context_destroy(ipa_ctx->logbuf_low); + ipa_ctx->logbuf_low = NULL; + } + + return count; +} + const struct file_operations ipa_gen_reg_ops = { .read = ipa_read_gen_reg, }; @@ -1882,6 +1920,10 @@ const struct file_operations ipa2_active_clients = { .write = ipa2_clear_active_clients_log, }; +const struct file_operations ipa_ipc_low_ops = { + .write = ipa_enable_ipc_low, +}; + const struct file_operations ipa_rx_poll_time_ops = { .read = ipa_read_rx_polling_timeout, .write = ipa_write_rx_polling_timeout, @@ -2097,6 +2139,13 @@ void ipa_debugfs_init(void) goto fail; } + file = debugfs_create_file("enable_low_prio_print", write_only_mode, + dent, 0, &ipa_ipc_low_ops); + if (!file) { + IPAERR("could not create enable_low_prio_print file\n"); + goto fail; + } + return; fail: diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_dma.c b/drivers/platform/msm/ipa/ipa_v2/ipa_dma.c index e08f281b1864..21be67aa2494 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_dma.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_dma.c @@ -32,16 +32,39 @@ #define IPADMA_DRV_NAME "ipa_dma" #define IPADMA_DBG(fmt, args...) \ - pr_debug(IPADMA_DRV_NAME " %s:%d " fmt, \ - __func__, __LINE__, ## args) + do { \ + pr_debug(IPADMA_DRV_NAME " %s:%d " fmt, \ + __func__, __LINE__, ## args); \ + IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \ + IPADMA_DRV_NAME " %s:%d " fmt, ## args); \ + IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \ + IPADMA_DRV_NAME " %s:%d " fmt, ## args); \ + } while (0) + +#define IPADMA_DBG_LOW(fmt, args...) \ + do { \ + pr_debug(IPADMA_DRV_NAME " %s:%d " fmt, \ + __func__, __LINE__, ## args); \ + IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \ + IPADMA_DRV_NAME " %s:%d " fmt, ## args); \ + } while (0) + #define IPADMA_ERR(fmt, args...) \ - pr_err(IPADMA_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args) + do { \ + pr_err(IPADMA_DRV_NAME " %s:%d " fmt, \ + __func__, __LINE__, ## args); \ + IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \ + IPADMA_DRV_NAME " %s:%d " fmt, ## args); \ + IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \ + IPADMA_DRV_NAME " %s:%d " fmt, ## args); \ + } while (0) #define IPADMA_FUNC_ENTRY() \ - IPADMA_DBG("ENTRY\n") + IPADMA_DBG_LOW("ENTRY\n") #define IPADMA_FUNC_EXIT() \ - IPADMA_DBG("EXIT\n") + IPADMA_DBG_LOW("EXIT\n") + #ifdef CONFIG_DEBUG_FS #define IPADMA_MAX_MSG_LEN 1024 @@ -270,7 +293,7 @@ int ipa2_dma_enable(void) } mutex_lock(&ipa_dma_ctx->enable_lock); if (ipa_dma_ctx->is_enabled) { - IPADMA_DBG("Already enabled.\n"); + IPADMA_ERR("Already enabled.\n"); mutex_unlock(&ipa_dma_ctx->enable_lock); return -EPERM; } @@ -296,7 +319,7 @@ static bool ipa_dma_work_pending(void) IPADMA_DBG("pending uc\n"); return true; } - IPADMA_DBG("no pending work\n"); + IPADMA_DBG_LOW("no pending work\n"); return false; } @@ -324,7 +347,7 @@ int ipa2_dma_disable(void) mutex_lock(&ipa_dma_ctx->enable_lock); spin_lock_irqsave(&ipa_dma_ctx->pending_lock, flags); if (!ipa_dma_ctx->is_enabled) { - IPADMA_DBG("Already disabled.\n"); + IPADMA_ERR("Already disabled.\n"); spin_unlock_irqrestore(&ipa_dma_ctx->pending_lock, flags); mutex_unlock(&ipa_dma_ctx->enable_lock); return -EPERM; @@ -371,6 +394,8 @@ int ipa2_dma_sync_memcpy(u64 dest, u64 src, int len) IPADMA_FUNC_ENTRY(); + IPADMA_DBG_LOW("dest = 0x%llx, src = 0x%llx, len = %d\n", + dest, src, len); if (ipa_dma_ctx == NULL) { IPADMA_ERR("IPADMA isn't initialized, can't memcpy\n"); return -EPERM; @@ -398,7 +423,7 @@ int ipa2_dma_sync_memcpy(u64 dest, u64 src, int len) if (atomic_read(&ipa_dma_ctx->sync_memcpy_pending_cnt) >= IPA_DMA_MAX_PENDING_SYNC) { atomic_dec(&ipa_dma_ctx->sync_memcpy_pending_cnt); - IPADMA_DBG("Reached pending requests limit\n"); + IPADMA_ERR("Reached pending requests limit\n"); return -EFAULT; } @@ -531,6 +556,8 @@ int ipa2_dma_async_memcpy(u64 dest, u64 src, int len, unsigned long flags; IPADMA_FUNC_ENTRY(); + IPADMA_DBG_LOW("dest = 0x%llx, src = 0x%llx, len = %d\n", + dest, src, len); if (ipa_dma_ctx == NULL) { IPADMA_ERR("IPADMA isn't initialized, can't memcpy\n"); return -EPERM; @@ -562,7 +589,7 @@ int ipa2_dma_async_memcpy(u64 dest, u64 src, int len, if (atomic_read(&ipa_dma_ctx->async_memcpy_pending_cnt) >= IPA_DMA_MAX_PENDING_ASYNC) { atomic_dec(&ipa_dma_ctx->async_memcpy_pending_cnt); - IPADMA_DBG("Reached pending requests limit\n"); + IPADMA_ERR("Reached pending requests limit\n"); return -EFAULT; } @@ -692,7 +719,7 @@ void ipa2_dma_destroy(void) IPADMA_FUNC_ENTRY(); if (!ipa_dma_ctx) { - IPADMA_DBG("IPADMA isn't initialized\n"); + IPADMA_ERR("IPADMA isn't initialized\n"); return; } @@ -836,7 +863,7 @@ static ssize_t ipa_dma_debugfs_reset_statistics(struct file *file, switch (in_num) { case 0: if (ipa_dma_work_pending()) - IPADMA_DBG("Note, there are pending memcpy\n"); + IPADMA_ERR("Note, there are pending memcpy\n"); atomic_set(&ipa_dma_ctx->total_async_memcpy, 0); atomic_set(&ipa_dma_ctx->total_sync_memcpy, 0); diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c index a7f1f9a040f9..7b48991cba65 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c @@ -346,7 +346,7 @@ int ipa_send_one(struct ipa_sys_context *sys, struct ipa_desc *desc, if (desc->type == IPA_IMM_CMD_DESC) { sps_flags |= SPS_IOVEC_FLAG_IMME; len = desc->opcode; - IPADBG("sending cmd=%d pyld_len=%d sps_flags=%x\n", + IPADBG_LOW("sending cmd=%d pyld_len=%d sps_flags=%x\n", desc->opcode, desc->len, sps_flags); IPA_DUMP_BUFF(desc->pyld, dma_address, desc->len); } else { @@ -624,7 +624,7 @@ static void ipa_sps_irq_cmd_ack(void *user1, int user2) WARN_ON(1); return; } - IPADBG("got ack for cmd=%d\n", desc->opcode); + IPADBG_LOW("got ack for cmd=%d\n", desc->opcode); complete(&desc->xfer_done); } @@ -641,11 +641,12 @@ static void ipa_sps_irq_cmd_ack(void *user1, int user2) int ipa_send_cmd(u16 num_desc, struct ipa_desc *descr) { struct ipa_desc *desc; - int result = 0; + int i, result = 0; struct ipa_sys_context *sys; int ep_idx; - IPADBG("sending command\n"); + for (i = 0; i < num_desc; i++) + IPADBG_LOW("sending imm cmd %d\n", descr[i].opcode); ep_idx = ipa2_get_ep_mapping(IPA_CLIENT_APPS_CMD_PROD); if (-1 == ep_idx) { @@ -706,7 +707,7 @@ static void ipa_sps_irq_tx_notify(struct sps_event_notify *notify) struct ipa_sys_context *sys = (struct ipa_sys_context *)notify->user; int ret; - IPADBG("event %d notified\n", notify->event_id); + IPADBG_LOW("event %d notified\n", notify->event_id); switch (notify->event_id) { case SPS_EVENT_EOT: @@ -749,7 +750,7 @@ static void ipa_sps_irq_tx_no_aggr_notify(struct sps_event_notify *notify) { struct ipa_tx_pkt_wrapper *tx_pkt; - IPADBG("event %d notified\n", notify->event_id); + IPADBG_LOW("event %d notified\n", notify->event_id); switch (notify->event_id) { case SPS_EVENT_EOT: @@ -1596,7 +1597,7 @@ static void ipa_tx_comp_usr_notify_release(void *user1, int user2) struct sk_buff *skb = (struct sk_buff *)user1; int ep_idx = user2; - IPADBG("skb=%p ep=%d\n", skb, ep_idx); + IPADBG_LOW("skb=%p ep=%d\n", skb, ep_idx); IPA_STATS_INC_CNT(ipa_ctx->stats.tx_pkts_compl); @@ -1916,7 +1917,7 @@ static void ipa_replenish_wlan_rx_cache(struct ipa_sys_context *sys) int ret; u32 rx_len_cached = 0; - IPADBG("\n"); + IPADBG_LOW("\n"); spin_lock_bh(&ipa_ctx->wc_memb.wlan_spinlock); rx_len_cached = sys->len; @@ -2339,7 +2340,7 @@ static int ipa_lan_rx_pyld_hdlr(struct sk_buff *skb, } if (sys->len_partial) { - IPADBG("len_partial %d\n", sys->len_partial); + IPADBG_LOW("len_partial %d\n", sys->len_partial); buf = skb_push(skb, sys->len_partial); memcpy(buf, sys->prev_skb->data, sys->len_partial); sys->len_partial = 0; @@ -2351,7 +2352,7 @@ static int ipa_lan_rx_pyld_hdlr(struct sk_buff *skb, /* this pipe has TX comp (status only) + mux-ed LAN RX data * (status+data) */ if (sys->len_rem) { - IPADBG("rem %d skb %d pad %d\n", sys->len_rem, skb->len, + IPADBG_LOW("rem %d skb %d pad %d\n", sys->len_rem, skb->len, sys->len_pad); if (sys->len_rem <= skb->len) { if (sys->prev_skb) { @@ -2402,7 +2403,7 @@ static int ipa_lan_rx_pyld_hdlr(struct sk_buff *skb, begin: while (skb->len) { sys->drop_packet = false; - IPADBG("LEN_REM %d\n", skb->len); + IPADBG_LOW("LEN_REM %d\n", skb->len); if (skb->len < IPA_PKT_STATUS_SIZE) { WARN_ON(sys->prev_skb != NULL); @@ -2413,7 +2414,7 @@ begin: } status = (struct ipa_hw_pkt_status *)skb->data; - IPADBG("STATUS opcode=%d src=%d dst=%d len=%d\n", + IPADBG_LOW("STATUS opcode=%d src=%d dst=%d len=%d\n", status->status_opcode, status->endp_src_idx, status->endp_dest_idx, status->pkt_len); if (sys->status_stat) { @@ -2451,7 +2452,7 @@ begin: if (status->status_mask & IPA_HW_PKT_STATUS_MASK_TAG_VALID) { struct ipa_tag_completion *comp; - IPADBG("TAG packet arrived\n"); + IPADBG_LOW("TAG packet arrived\n"); if (status->tag_f_2 == IPA_COOKIE) { skb_pull(skb, IPA_PKT_STATUS_SIZE); if (skb->len < sizeof(comp)) { @@ -2491,7 +2492,7 @@ begin: if (skb->len == IPA_PKT_STATUS_SIZE && !status->exception) { WARN_ON(sys->prev_skb != NULL); - IPADBG("Ins header in next buffer\n"); + IPADBG_LOW("Ins header in next buffer\n"); sys->prev_skb = skb_copy(skb, GFP_KERNEL); sys->len_partial = skb->len; return rc; @@ -2502,12 +2503,13 @@ begin: len = status->pkt_len + pad_len_byte + IPA_SIZE_DL_CSUM_META_TRAILER; - IPADBG("pad %d pkt_len %d len %d\n", pad_len_byte, + IPADBG_LOW("pad %d pkt_len %d len %d\n", pad_len_byte, status->pkt_len, len); if (status->exception == IPA_HW_PKT_STATUS_EXCEPTION_DEAGGR) { - IPADBG("Dropping packet on DeAggr Exception\n"); + IPADBG_LOW("Dropping packet"); + IPADBG_LOW(" on DeAggr Exception\n"); sys->drop_packet = true; } @@ -2516,7 +2518,7 @@ begin: skb2 = ipa_skb_copy_for_client(skb, skb2_len); if (likely(skb2)) { if (skb->len < len + IPA_PKT_STATUS_SIZE) { - IPADBG("SPL skb len %d len %d\n", + IPADBG_LOW("SPL skb len %d len %d\n", skb->len, len); sys->prev_skb = skb2; sys->len_rem = len - skb->len + @@ -2526,7 +2528,7 @@ begin: } else { skb_trim(skb2, status->pkt_len + IPA_PKT_STATUS_SIZE); - IPADBG("rx avail for %d\n", + IPADBG_LOW("rx avail for %d\n", status->endp_dest_idx); if (sys->drop_packet) { dev_kfree_skb_any(skb2); @@ -2570,11 +2572,12 @@ begin: } /* TX comp */ ipa_wq_write_done_status(src_pipe); - IPADBG("tx comp imp for %d\n", src_pipe); + IPADBG_LOW("tx comp imp for %d\n", src_pipe); } else { /* TX comp */ ipa_wq_write_done_status(status->endp_src_idx); - IPADBG("tx comp exp for %d\n", status->endp_src_idx); + IPADBG_LOW + ("tx comp exp for %d\n", status->endp_src_idx); skb_pull(skb, IPA_PKT_STATUS_SIZE); IPA_STATS_INC_CNT(ipa_ctx->stats.stat_compl); IPA_STATS_DEC_CNT( @@ -2610,13 +2613,13 @@ static void wan_rx_handle_splt_pyld(struct sk_buff *skb, { struct sk_buff *skb2; - IPADBG("rem %d skb %d\n", sys->len_rem, skb->len); + IPADBG_LOW("rem %d skb %d\n", sys->len_rem, skb->len); if (sys->len_rem <= skb->len) { if (sys->prev_skb) { skb2 = join_prev_skb(sys->prev_skb, skb, sys->len_rem); if (likely(skb2)) { - IPADBG( + IPADBG_LOW( "removing Status element from skb and sending to WAN client"); skb_pull(skb2, IPA_PKT_STATUS_SIZE); skb2->truesize = skb2->len + @@ -2679,14 +2682,14 @@ static int ipa_wan_rx_pyld_hdlr(struct sk_buff *skb, while (skb->len) { - IPADBG("LEN_REM %d\n", skb->len); + IPADBG_LOW("LEN_REM %d\n", skb->len); if (skb->len < IPA_PKT_STATUS_SIZE) { IPAERR("status straddles buffer\n"); WARN_ON(1); goto bail; } status = (struct ipa_hw_pkt_status *)skb->data; - IPADBG("STATUS opcode=%d src=%d dst=%d len=%d\n", + IPADBG_LOW("STATUS opcode=%d src=%d dst=%d len=%d\n", status->status_opcode, status->endp_src_idx, status->endp_dest_idx, status->pkt_len); @@ -2717,7 +2720,7 @@ static int ipa_wan_rx_pyld_hdlr(struct sk_buff *skb, goto bail; } if (status->pkt_len == 0) { - IPADBG("Skip aggr close status\n"); + IPADBG_LOW("Skip aggr close status\n"); skb_pull(skb, IPA_PKT_STATUS_SIZE); IPA_STATS_DEC_CNT(ipa_ctx->stats.rx_pkts); IPA_STATS_INC_CNT(ipa_ctx->stats.wan_aggr_close); @@ -2744,11 +2747,11 @@ static int ipa_wan_rx_pyld_hdlr(struct sk_buff *skb, /*QMAP is BE: convert the pkt_len field from BE to LE*/ pkt_len_with_pad = ntohs((qmap_hdr>>16) & 0xffff); - IPADBG("pkt_len with pad %d\n", pkt_len_with_pad); + IPADBG_LOW("pkt_len with pad %d\n", pkt_len_with_pad); /*get the CHECKSUM_PROCESS bit*/ checksum_trailer_exists = status->status_mask & IPA_HW_PKT_STATUS_MASK_CKSUM_PROCESS; - IPADBG("checksum_trailer_exists %d\n", + IPADBG_LOW("checksum_trailer_exists %d\n", checksum_trailer_exists); frame_len = IPA_PKT_STATUS_SIZE + @@ -2756,7 +2759,7 @@ static int ipa_wan_rx_pyld_hdlr(struct sk_buff *skb, pkt_len_with_pad; if (checksum_trailer_exists) frame_len += IPA_DL_CHECKSUM_LENGTH; - IPADBG("frame_len %d\n", frame_len); + IPADBG_LOW("frame_len %d\n", frame_len); skb2 = skb_clone(skb, GFP_KERNEL); if (likely(skb2)) { @@ -2765,16 +2768,16 @@ static int ipa_wan_rx_pyld_hdlr(struct sk_buff *skb, * payload split across 2 buff */ if (skb->len < frame_len) { - IPADBG("SPL skb len %d len %d\n", + IPADBG_LOW("SPL skb len %d len %d\n", skb->len, frame_len); sys->prev_skb = skb2; sys->len_rem = frame_len - skb->len; skb_pull(skb, skb->len); } else { skb_trim(skb2, frame_len); - IPADBG("rx avail for %d\n", + IPADBG_LOW("rx avail for %d\n", status->endp_dest_idx); - IPADBG( + IPADBG_LOW( "removing Status element from skb and sending to WAN client"); skb_pull(skb2, IPA_PKT_STATUS_SIZE); skb2->truesize = skb2->len + @@ -2914,7 +2917,7 @@ void ipa_lan_rx_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data) ------------------------------------------ */ *(u16 *)rx_skb->cb = ((metadata >> 16) & 0xFFFF); - IPADBG("meta_data: 0x%x cb: 0x%x\n", + IPADBG_LOW("meta_data: 0x%x cb: 0x%x\n", metadata, *(u32 *)rx_skb->cb); ep->client_notify(ep->priv, IPA_RECEIVE, (unsigned long)(rx_skb)); @@ -3017,7 +3020,7 @@ static void ipa_wlan_wq_rx_common(struct ipa_sys_context *sys, u32 size) static void ipa_dma_memcpy_notify(struct ipa_sys_context *sys, struct sps_iovec *iovec) { - IPADBG("ENTER.\n"); + IPADBG_LOW("ENTER.\n"); if (unlikely(list_empty(&sys->head_desc_list))) { IPAERR("descriptor list is empty!\n"); WARN_ON(1); @@ -3064,7 +3067,8 @@ void ipa_sps_irq_rx_no_aggr_notify(struct sps_event_notify *notify) if (IPA_CLIENT_IS_APPS_CONS(rx_pkt->sys->ep->client)) atomic_set(&ipa_ctx->sps_pm.eot_activity, 1); rx_pkt->len = notify->data.transfer.iovec.size; - IPADBG("event %d notified sys=%p len=%u\n", notify->event_id, + IPADBG_LOW + ("event %d notified sys=%p len=%u\n", notify->event_id, notify->user, rx_pkt->len); queue_work(rx_pkt->sys->wq, &rx_pkt->work); break; @@ -3370,15 +3374,15 @@ static void ipa_tx_client_rx_notify_release(void *user1, int user2) struct ipa_tx_data_desc *dd = (struct ipa_tx_data_desc *)user1; int ep_idx = user2; - IPADBG("Received data desc anchor:%p\n", dd); + IPADBG_LOW("Received data desc anchor:%p\n", dd); atomic_inc(&ipa_ctx->ep[ep_idx].avail_fifo_desc); ipa_ctx->ep[ep_idx].wstats.rx_pkts_status_rcvd++; /* wlan host driver waits till tx complete before unload */ - IPADBG("ep=%d fifo_desc_free_count=%d\n", + IPADBG_LOW("ep=%d fifo_desc_free_count=%d\n", ep_idx, atomic_read(&ipa_ctx->ep[ep_idx].avail_fifo_desc)); - IPADBG("calling client notify callback with priv:%p\n", + IPADBG_LOW("calling client notify callback with priv:%p\n", ipa_ctx->ep[ep_idx].priv); if (ipa_ctx->ep[ep_idx].client_notify) { @@ -3442,7 +3446,7 @@ int ipa2_tx_dp_mul(enum ipa_client_type src, return -EINVAL; } - IPADBG("Received data desc anchor:%p\n", data_desc); + IPADBG_LOW("Received data desc anchor:%p\n", data_desc); spin_lock_bh(&ipa_ctx->wc_memb.ipa_tx_mul_spinlock); @@ -3451,7 +3455,7 @@ int ipa2_tx_dp_mul(enum ipa_client_type src, IPAERR("dest EP does not exist.\n"); goto fail_send; } - IPADBG("ep idx:%d\n", ep_idx); + IPADBG_LOW("ep idx:%d\n", ep_idx); sys = ipa_ctx->ep[ep_idx].sys; if (unlikely(ipa_ctx->ep[ep_idx].valid == 0)) { @@ -3465,7 +3469,7 @@ int ipa2_tx_dp_mul(enum ipa_client_type src, list_for_each_entry(entry, &data_desc->link, link) { num_desc++; } - IPADBG("Number of Data Descriptors:%d", num_desc); + IPADBG_LOW("Number of Data Descriptors:%d", num_desc); if (atomic_read(&sys->ep->avail_fifo_desc) < num_desc) { IPAERR("Insufficient data descriptors available\n"); @@ -3475,7 +3479,7 @@ int ipa2_tx_dp_mul(enum ipa_client_type src, /* Assign callback only for last data descriptor */ cnt = 0; list_for_each_entry(entry, &data_desc->link, link) { - IPADBG("Parsing data desc :%d\n", cnt); + IPADBG_LOW("Parsing data desc :%d\n", cnt); cnt++; ((u8 *)entry->pyld_buffer)[IPA_WLAN_HDR_QMAP_ID_OFFSET] = (u8)sys->ep->cfg.meta.qmap_id; @@ -3484,18 +3488,18 @@ int ipa2_tx_dp_mul(enum ipa_client_type src, desc.type = IPA_DATA_DESC_SKB; desc.user1 = data_desc; desc.user2 = ep_idx; - IPADBG("priv:%p pyld_buf:0x%p pyld_len:%d\n", + IPADBG_LOW("priv:%p pyld_buf:0x%p pyld_len:%d\n", entry->priv, desc.pyld, desc.len); /* In case of last descriptor populate callback */ if (cnt == num_desc) { - IPADBG("data desc:%p\n", data_desc); + IPADBG_LOW("data desc:%p\n", data_desc); desc.callback = ipa_tx_client_rx_notify_release; } else { desc.callback = ipa_tx_client_rx_pkt_status; } - IPADBG("calling ipa_send_one()\n"); + IPADBG_LOW("calling ipa_send_one()\n"); if (ipa_send_one(sys, &desc, true)) { IPAERR("fail to send skb\n"); sys->ep->wstats.rx_pkt_leak += (cnt-1); @@ -3507,7 +3511,7 @@ int ipa2_tx_dp_mul(enum ipa_client_type src, atomic_dec(&sys->ep->avail_fifo_desc); sys->ep->wstats.rx_pkts_rcvd++; - IPADBG("ep=%d fifo desc=%d\n", + IPADBG_LOW("ep=%d fifo desc=%d\n", ep_idx, atomic_read(&sys->ep->avail_fifo_desc)); } diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c index d6e563b935b6..7ca2314d5839 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c @@ -209,7 +209,7 @@ static int ipa_generate_flt_hw_rule(enum ipa_ip_type ip, } } - IPADBG("en_rule 0x%x, action=%d, rt_idx=%d, uc=%d, retain_hdr=%d\n", + IPADBG_LOW("en_rule 0x%x, action=%d, rt_idx=%d, uc=%d, retain_hdr=%d\n", en_rule, hdr->u.hdr.action, hdr->u.hdr.rt_tbl_idx, @@ -601,7 +601,7 @@ static void __ipa_reap_sys_flt_tbls(enum ipa_ip_type ip) tbl = &ipa_ctx->glob_flt_tbl[ip]; if (tbl->prev_mem.phys_base) { - IPADBG("reaping glob flt tbl (prev) ip=%d\n", ip); + IPADBG_LOW("reaping glob flt tbl (prev) ip=%d\n", ip); dma_free_coherent(ipa_ctx->pdev, tbl->prev_mem.size, tbl->prev_mem.base, tbl->prev_mem.phys_base); memset(&tbl->prev_mem, 0, sizeof(tbl->prev_mem)); @@ -609,7 +609,7 @@ static void __ipa_reap_sys_flt_tbls(enum ipa_ip_type ip) if (list_empty(&tbl->head_flt_rule_list)) { if (tbl->curr_mem.phys_base) { - IPADBG("reaping glob flt tbl (curr) ip=%d\n", ip); + IPADBG_LOW("reaping glob flt tbl (curr) ip=%d\n", ip); dma_free_coherent(ipa_ctx->pdev, tbl->curr_mem.size, tbl->curr_mem.base, tbl->curr_mem.phys_base); @@ -620,7 +620,8 @@ static void __ipa_reap_sys_flt_tbls(enum ipa_ip_type ip) for (i = 0; i < ipa_ctx->ipa_num_pipes; i++) { tbl = &ipa_ctx->flt_tbl[i][ip]; if (tbl->prev_mem.phys_base) { - IPADBG("reaping flt tbl (prev) pipe=%d ip=%d\n", i, ip); + IPADBG_LOW("reaping flt tbl"); + IPADBG_LOW("(prev) pipe=%d ip=%d\n", i, ip); dma_free_coherent(ipa_ctx->pdev, tbl->prev_mem.size, tbl->prev_mem.base, tbl->prev_mem.phys_base); @@ -629,7 +630,8 @@ static void __ipa_reap_sys_flt_tbls(enum ipa_ip_type ip) if (list_empty(&tbl->head_flt_rule_list)) { if (tbl->curr_mem.phys_base) { - IPADBG("reaping flt tbl (curr) pipe=%d ip=%d\n", + IPADBG_LOW("reaping flt tbl"); + IPADBG_LOW("(curr) pipe=%d ip=%d\n", i, ip); dma_free_coherent(ipa_ctx->pdev, tbl->curr_mem.size, @@ -897,7 +899,7 @@ int __ipa_commit_flt_v2(enum ipa_ip_type ip) for (i = 0; i < 6; i++) { if (ipa_ctx->skip_ep_cfg_shadow[i]) { - IPADBG("skip %d\n", i); + IPADBG_LOW("skip %d\n", i); continue; } @@ -906,7 +908,7 @@ int __ipa_commit_flt_v2(enum ipa_ip_type ip) ipa2_get_ep_mapping(IPA_CLIENT_APPS_CMD_PROD) == i || (ipa2_get_ep_mapping(IPA_CLIENT_APPS_LAN_WAN_PROD) == i && ipa_ctx->modem_cfg_emb_pipe_flt)) { - IPADBG("skip %d\n", i); + IPADBG_LOW("skip %d\n", i); continue; } @@ -932,12 +934,12 @@ int __ipa_commit_flt_v2(enum ipa_ip_type ip) for (i = 11; i < ipa_ctx->ipa_num_pipes; i++) { if (ipa_ctx->skip_ep_cfg_shadow[i]) { - IPADBG("skip %d\n", i); + IPADBG_LOW("skip %d\n", i); continue; } if (ipa2_get_ep_mapping(IPA_CLIENT_APPS_LAN_WAN_PROD) == i && ipa_ctx->modem_cfg_emb_pipe_flt) { - IPADBG("skip %d\n", i); + IPADBG_LOW("skip %d\n", i); continue; } if (ip == IPA_IP_v4) { @@ -1066,7 +1068,7 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip, } *rule_hdl = id; entry->id = id; - IPADBG("add flt rule rule_cnt=%d\n", tbl->rule_cnt); + IPADBG_LOW("add flt rule rule_cnt=%d\n", tbl->rule_cnt); return 0; @@ -1095,7 +1097,7 @@ static int __ipa_del_flt_rule(u32 rule_hdl) entry->tbl->rule_cnt--; if (entry->rt_tbl) entry->rt_tbl->ref_cnt--; - IPADBG("del flt rule rule_cnt=%d\n", entry->tbl->rule_cnt); + IPADBG_LOW("del flt rule rule_cnt=%d\n", entry->tbl->rule_cnt); entry->cookie = 0; kmem_cache_free(ipa_ctx->flt_rule_cache, entry); @@ -1176,7 +1178,7 @@ static int __ipa_add_global_flt_rule(enum ipa_ip_type ip, } tbl = &ipa_ctx->glob_flt_tbl[ip]; - IPADBG("add global flt rule ip=%d\n", ip); + IPADBG_LOW("add global flt rule ip=%d\n", ip); return __ipa_add_flt_rule(tbl, ip, rule, add_rear, rule_hdl); } @@ -1203,7 +1205,7 @@ static int __ipa_add_ep_flt_rule(enum ipa_ip_type ip, enum ipa_client_type ep, IPADBG("ep not connected ep_idx=%d\n", ipa_ep_idx); tbl = &ipa_ctx->flt_tbl[ipa_ep_idx][ip]; - IPADBG("add ep flt rule ip=%d ep=%d\n", ip, ep); + IPADBG_LOW("add ep flt rule ip=%d ep=%d\n", ip, ep); return __ipa_add_flt_rule(tbl, ip, rule, add_rear, rule_hdl); } diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c index 62e026262663..40d42e1775a9 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c @@ -43,7 +43,7 @@ static int ipa_generate_hdr_hw_tbl(struct ipa_mem_buffer *mem) IPAERR("hdr tbl empty\n"); return -EPERM; } - IPADBG("tbl_sz=%d\n", ipa_ctx->hdr_tbl.end); + IPADBG_LOW("tbl_sz=%d\n", ipa_ctx->hdr_tbl.end); mem->base = dma_alloc_coherent(ipa_ctx->pdev, mem->size, &mem->phys_base, GFP_KERNEL); @@ -57,7 +57,7 @@ static int ipa_generate_hdr_hw_tbl(struct ipa_mem_buffer *mem) link) { if (entry->is_hdr_proc_ctx) continue; - IPADBG("hdr of len %d ofst=%d\n", entry->hdr_len, + IPADBG_LOW("hdr of len %d ofst=%d\n", entry->hdr_len, entry->offset_entry->offset); memcpy(mem->base + entry->offset_entry->offset, entry->hdr, entry->hdr_len); @@ -74,7 +74,7 @@ static void ipa_hdr_proc_ctx_to_hw_format(struct ipa_mem_buffer *mem, list_for_each_entry(entry, &ipa_ctx->hdr_proc_ctx_tbl.head_proc_ctx_entry_list, link) { - IPADBG("processing type %d ofst=%d\n", + IPADBG_LOW("processing type %d ofst=%d\n", entry->type, entry->offset_entry->offset); if (entry->type == IPA_HDR_PROC_NONE) { struct ipa_hdr_proc_ctx_add_hdr_seq *ctx; @@ -88,7 +88,7 @@ static void ipa_hdr_proc_ctx_to_hw_format(struct ipa_mem_buffer *mem, entry->hdr->phys_base : hdr_base_addr + entry->hdr->offset_entry->offset; - IPADBG("header address 0x%x\n", + IPADBG_LOW("header address 0x%x\n", ctx->hdr_add.hdr_addr); ctx->end.type = IPA_PROC_CTX_TLV_TYPE_END; ctx->end.length = 0; @@ -105,7 +105,7 @@ static void ipa_hdr_proc_ctx_to_hw_format(struct ipa_mem_buffer *mem, entry->hdr->phys_base : hdr_base_addr + entry->hdr->offset_entry->offset; - IPADBG("header address 0x%x\n", + IPADBG_LOW("header address 0x%x\n", ctx->hdr_add.hdr_addr); ctx->cmd.type = IPA_PROC_CTX_TLV_TYPE_PROC_CMD; ctx->cmd.length = 0; @@ -117,7 +117,7 @@ static void ipa_hdr_proc_ctx_to_hw_format(struct ipa_mem_buffer *mem, ctx->cmd.value = IPA_HDR_UCP_802_3_TO_ETHII; else if (entry->type == IPA_HDR_PROC_802_3_TO_802_3) ctx->cmd.value = IPA_HDR_UCP_802_3_TO_802_3; - IPADBG("command id %d\n", ctx->cmd.value); + IPADBG_LOW("command id %d\n", ctx->cmd.value); ctx->end.type = IPA_PROC_CTX_TLV_TYPE_END; ctx->end.length = 0; ctx->end.value = 0; @@ -144,7 +144,7 @@ static int ipa_generate_hdr_proc_ctx_hw_tbl(u32 hdr_sys_addr, /* make sure table is aligned */ mem->size += IPA_HDR_PROC_CTX_TABLE_ALIGNMENT_BYTE; - IPADBG("tbl_sz=%d\n", ipa_ctx->hdr_proc_ctx_tbl.end); + IPADBG_LOW("tbl_sz=%d\n", ipa_ctx->hdr_proc_ctx_tbl.end); mem->base = dma_alloc_coherent(ipa_ctx->pdev, mem->size, &mem->phys_base, GFP_KERNEL); @@ -487,7 +487,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx, int needed_len; int mem_size; - IPADBG("processing type %d hdr_hdl %d\n", + IPADBG_LOW("processing type %d hdr_hdl %d\n", proc_ctx->type, proc_ctx->hdr_hdl); if (!HDR_PROC_TYPE_IS_VALID(proc_ctx->type)) { @@ -566,7 +566,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx, entry->offset_entry = offset; list_add(&entry->link, &htbl->head_proc_ctx_entry_list); htbl->proc_ctx_cnt++; - IPADBG("add proc ctx of sz=%d cnt=%d ofst=%d\n", needed_len, + IPADBG_LOW("add proc ctx of sz=%d cnt=%d ofst=%d\n", needed_len, htbl->proc_ctx_cnt, offset->offset); id = ipa_id_alloc(entry); @@ -692,12 +692,12 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr) list_add(&entry->link, &htbl->head_hdr_entry_list); htbl->hdr_cnt++; if (entry->is_hdr_proc_ctx) - IPADBG("add hdr of sz=%d hdr_cnt=%d phys_base=%pa\n", + IPADBG_LOW("add hdr of sz=%d hdr_cnt=%d phys_base=%pa\n", hdr->hdr_len, htbl->hdr_cnt, &entry->phys_base); else - IPADBG("add hdr of sz=%d hdr_cnt=%d ofst=%d\n", + IPADBG_LOW("add hdr of sz=%d hdr_cnt=%d ofst=%d\n", hdr->hdr_len, htbl->hdr_cnt, entry->offset_entry->offset); diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h index fd61435db5e2..6515d29e497a 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h @@ -54,10 +54,37 @@ #define IPA_MAX_STATUS_STAT_NUM 30 +#define IPA_IPC_LOG_PAGES 50 + #define IPADBG(fmt, args...) \ - pr_debug(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args) + do { \ + pr_debug(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args);\ + if (ipa_ctx) { \ + IPA_IPC_LOGGING(ipa_ctx->logbuf, \ + DRV_NAME " %s:%d " fmt, ## args); \ + IPA_IPC_LOGGING(ipa_ctx->logbuf_low, \ + DRV_NAME " %s:%d " fmt, ## args); \ + } \ + } while (0) + +#define IPADBG_LOW(fmt, args...) \ + do { \ + pr_debug(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args);\ + if (ipa_ctx) \ + IPA_IPC_LOGGING(ipa_ctx->logbuf_low, \ + DRV_NAME " %s:%d " fmt, ## args); \ + } while (0) + #define IPAERR(fmt, args...) \ - pr_err(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args) + do { \ + pr_err(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args);\ + if (ipa_ctx) { \ + IPA_IPC_LOGGING(ipa_ctx->logbuf, \ + DRV_NAME " %s:%d " fmt, ## args); \ + IPA_IPC_LOGGING(ipa_ctx->logbuf_low, \ + DRV_NAME " %s:%d " fmt, ## args); \ + } \ + } while (0) #define WLAN_AMPDU_TX_EP 15 #define WLAN_PROD_TX_EP 19 @@ -1003,6 +1030,8 @@ struct ipacm_client_info { * @use_ipa_teth_bridge: use tethering bridge driver * @ipa_bam_remote_mode: ipa bam is in remote mode * @modem_cfg_emb_pipe_flt: modem configure embedded pipe filtering rules + * @logbuf: ipc log buffer for high priority messages + * @logbuf_low: ipc log buffer for low priority messages * @ipa_wdi2: using wdi-2.0 * @ipa_bus_hdl: msm driver handle for the data path bus * @ctrl: holds the core specific operations based on @@ -1095,6 +1124,8 @@ struct ipa_context { /* featurize if memory footprint becomes a concern */ struct ipa_stats stats; void *smem_pipe_mem; + void *logbuf; + void *logbuf_low; u32 ipa_bus_hdl; struct ipa_controller *ctrl; struct idr ipa_idr; diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_interrupts.c b/drivers/platform/msm/ipa/ipa_v2/ipa_interrupts.c index 17f577ab6c4c..c17dee939f1c 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_interrupts.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_interrupts.c @@ -103,11 +103,12 @@ static int handle_interrupt(int irq_num, bool isr_context) switch (interrupt_info.interrupt) { case IPA_TX_SUSPEND_IRQ: + IPADBG_LOW("processing TX_SUSPEND interrupt work-around\n"); suspend_data = ipa_read_reg(ipa_ctx->mmio, IPA_IRQ_SUSPEND_INFO_EE_n_ADDR(ipa_ee)); if (!is_valid_ep(suspend_data)) return 0; - + IPADBG_LOW("get interrupt %d\n", suspend_data); suspend_interrupt_data = kzalloc(sizeof(*suspend_interrupt_data), GFP_ATOMIC); if (!suspend_interrupt_data) { @@ -167,9 +168,11 @@ static void ipa_process_interrupts(bool isr_context) u32 i = 0; u32 en; bool uc_irq; - en = ipa_read_reg(ipa_ctx->mmio, IPA_IRQ_EN_EE_n_ADDR(ipa_ee)); reg = ipa_read_reg(ipa_ctx->mmio, IPA_IRQ_STTS_EE_n_ADDR(ipa_ee)); + IPADBG_LOW( + "ISR enter\n isr_ctx = %d EN reg = 0x%x STTS reg = 0x%x\n", + isr_context, en, reg); while (en & reg) { bmsk = 1; for (i = 0; i < IPA_IRQ_NUM_MAX; i++) { @@ -206,21 +209,22 @@ static void ipa_process_interrupts(bool isr_context) reg = ipa_read_reg(ipa_ctx->mmio, IPA_IRQ_STTS_EE_n_ADDR(ipa_ee)); } + IPADBG_LOW("Exit\n"); } static void ipa_interrupt_defer(struct work_struct *work) { - IPADBG("processing interrupts in wq\n"); + IPADBG_LOW("processing interrupts in wq\n"); IPA_ACTIVE_CLIENTS_INC_SIMPLE(); ipa_process_interrupts(false); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); - IPADBG("Done\n"); + IPADBG_LOW("Done\n"); } static irqreturn_t ipa_isr(int irq, void *ctxt) { unsigned long flags; - + IPADBG_LOW("Enter\n"); /* defer interrupt handling in case IPA is not clocked on */ if (ipa_active_clients_trylock(&flags) == 0) { IPADBG("defer interrupt processing\n"); @@ -235,7 +239,7 @@ static irqreturn_t ipa_isr(int irq, void *ctxt) } ipa_process_interrupts(true); - + IPADBG_LOW("Exit\n"); bail: ipa_active_clients_trylock_unlock(&flags); return IRQ_HANDLED; @@ -260,7 +264,7 @@ int ipa2_add_interrupt_handler(enum ipa_irq_type interrupt, u32 bmsk; int irq_num; - IPADBG("in ipa2_add_interrupt_handler\n"); + IPADBG_LOW("in ipa2_add_interrupt_handler\n"); if (interrupt < IPA_BAD_SNOC_ACCESS_IRQ || interrupt >= IPA_IRQ_MAX) { IPAERR("invalid interrupt number %d\n", interrupt); @@ -284,7 +288,7 @@ int ipa2_add_interrupt_handler(enum ipa_irq_type interrupt, bmsk = 1 << irq_num; val |= bmsk; ipa_write_reg(ipa_ctx->mmio, IPA_IRQ_EN_EE_n_ADDR(ipa_ee), val); - IPADBG("wrote IPA_IRQ_EN_EE_n_ADDR register. reg = %d\n", val); + IPADBG_LOW("wrote IPA_IRQ_EN_EE_n_ADDR register. reg = %d\n", val); return 0; } diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_intf.c b/drivers/platform/msm/ipa/ipa_v2/ipa_intf.c index f5afb4b0141c..dfc3e06f452b 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_intf.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_intf.c @@ -532,9 +532,8 @@ ssize_t ipa_read(struct file *filp, char __user *buf, size_t count, list_del(&msg->link); } - IPADBG("msg=%p\n", msg); - if (msg) { + IPADBG("msg=%pK\n", msg); locked = 0; mutex_unlock(&ipa_ctx->msg_lock); if (copy_to_user(buf, &msg->meta, @@ -558,6 +557,7 @@ ssize_t ipa_read(struct file *filp, char __user *buf, size_t count, IPA_STATS_INC_CNT( ipa_ctx->stats.msg_r[msg->meta.msg_type]); kfree(msg); + msg = NULL; } ret = -EAGAIN; diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_mhi.c b/drivers/platform/msm/ipa/ipa_v2/ipa_mhi.c index e8f25c9c23d3..0ab4a6882a63 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_mhi.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_mhi.c @@ -20,16 +20,40 @@ #include "ipa_i.h" #include "ipa_qmi_service.h" -#define IPA_MHI_DRV_NAME +#define IPA_MHI_DRV_NAME "ipa_mhi" #define IPA_MHI_DBG(fmt, args...) \ - pr_debug(IPA_MHI_DRV_NAME " %s:%d " fmt, \ - __func__, __LINE__, ## args) + do { \ + pr_debug(IPA_MHI_DRV_NAME " %s:%d " fmt, \ + __func__, __LINE__, ## args); \ + IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \ + IPA_MHI_DRV_NAME " %s:%d " fmt, ## args); \ + IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \ + IPA_MHI_DRV_NAME " %s:%d " fmt, ## args); \ + } while (0) + +#define IPA_MHI_DBG_LOW(fmt, args...) \ + do { \ + pr_debug(IPA_MHI_DRV_NAME " %s:%d " fmt, \ + __func__, __LINE__, ## args); \ + IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \ + IPA_MHI_DRV_NAME " %s:%d " fmt, ## args); \ + } while (0) + #define IPA_MHI_ERR(fmt, args...) \ - pr_err(IPA_MHI_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args) + do { \ + pr_err(IPA_MHI_DRV_NAME " %s:%d " fmt, \ + __func__, __LINE__, ## args); \ + IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \ + IPA_MHI_DRV_NAME " %s:%d " fmt, ## args); \ + IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \ + IPA_MHI_DRV_NAME " %s:%d " fmt, ## args); \ + } while (0) + #define IPA_MHI_FUNC_ENTRY() \ - IPA_MHI_DBG("ENTRY\n") + IPA_MHI_DBG_LOW("ENTRY\n") #define IPA_MHI_FUNC_EXIT() \ - IPA_MHI_DBG("EXIT\n") + IPA_MHI_DBG_LOW("EXIT\n") + bool ipa2_mhi_sps_channel_empty(enum ipa_client_type client) { diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c index 3f20941155a5..0f5d7b7719b5 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c @@ -310,7 +310,7 @@ static void ipa_a5_svc_recv_msg(struct work_struct *work) int rc; do { - IPAWANDBG("Notified about a Receive Event"); + IPAWANDBG_LOW("Notified about a Receive Event"); rc = qmi_recv_msg(ipa_svc_handle); } while (rc == 0); if (rc != -ENOMSG) @@ -384,7 +384,7 @@ static int ipa_check_qmi_response(int rc, req_id, result, error); return result; } - IPAWANDBG("Received %s successfully\n", resp_type); + IPAWANDBG_LOW("Received %s successfully\n", resp_type); return 0; } @@ -711,7 +711,7 @@ static void ipa_q6_clnt_recv_msg(struct work_struct *work) int rc; do { - IPAWANDBG("Notified about a Receive Event"); + IPAWANDBG_LOW("Notified about a Receive Event"); rc = qmi_recv_msg(ipa_q6_clnt); } while (rc == 0); if (rc != -ENOMSG) @@ -723,7 +723,7 @@ static void ipa_q6_clnt_notify(struct qmi_handle *handle, { switch (event) { case QMI_RECV_MSG: - IPAWANDBG("client qmi recv message called"); + IPAWANDBG_LOW("client qmi recv message called"); if (!atomic_read(&workqueues_stopped)) queue_delayed_work(ipa_clnt_resp_workqueue, &work_recv_msg_client, 0); @@ -1094,7 +1094,7 @@ int ipa_qmi_get_data_stats(struct ipa_get_data_stats_req_msg_v01 *req, resp_desc.msg_id = QMI_IPA_GET_DATA_STATS_RESP_V01; resp_desc.ei_array = ipa_get_data_stats_resp_msg_data_v01_ei; - IPAWANDBG("Sending QMI_IPA_GET_DATA_STATS_REQ_V01\n"); + IPAWANDBG_LOW("Sending QMI_IPA_GET_DATA_STATS_REQ_V01\n"); if (unlikely(!ipa_q6_clnt)) return -ETIMEDOUT; rc = qmi_send_req_wait(ipa_q6_clnt, &req_desc, req, @@ -1103,7 +1103,7 @@ int ipa_qmi_get_data_stats(struct ipa_get_data_stats_req_msg_v01 *req, sizeof(struct ipa_get_data_stats_resp_msg_v01), QMI_SEND_STATS_REQ_TIMEOUT_MS); - IPAWANDBG("QMI_IPA_GET_DATA_STATS_RESP_V01 received\n"); + IPAWANDBG_LOW("QMI_IPA_GET_DATA_STATS_RESP_V01 received\n"); return ipa_check_qmi_response(rc, QMI_IPA_GET_DATA_STATS_REQ_V01, resp->resp.result, @@ -1124,7 +1124,7 @@ int ipa_qmi_get_network_stats(struct ipa_get_apn_data_stats_req_msg_v01 *req, resp_desc.msg_id = QMI_IPA_GET_APN_DATA_STATS_RESP_V01; resp_desc.ei_array = ipa_get_apn_data_stats_resp_msg_data_v01_ei; - IPAWANDBG("Sending QMI_IPA_GET_APN_DATA_STATS_REQ_V01\n"); + IPAWANDBG_LOW("Sending QMI_IPA_GET_APN_DATA_STATS_REQ_V01\n"); if (unlikely(!ipa_q6_clnt)) return -ETIMEDOUT; rc = qmi_send_req_wait(ipa_q6_clnt, &req_desc, req, @@ -1133,7 +1133,7 @@ int ipa_qmi_get_network_stats(struct ipa_get_apn_data_stats_req_msg_v01 *req, sizeof(struct ipa_get_apn_data_stats_resp_msg_v01), QMI_SEND_STATS_REQ_TIMEOUT_MS); - IPAWANDBG("QMI_IPA_GET_APN_DATA_STATS_RESP_V01 received\n"); + IPAWANDBG_LOW("QMI_IPA_GET_APN_DATA_STATS_RESP_V01 received\n"); return ipa_check_qmi_response(rc, QMI_IPA_GET_APN_DATA_STATS_REQ_V01, resp->resp.result, @@ -1157,7 +1157,7 @@ int ipa_qmi_set_data_quota(struct ipa_set_data_usage_quota_req_msg_v01 *req) resp_desc.msg_id = QMI_IPA_SET_DATA_USAGE_QUOTA_RESP_V01; resp_desc.ei_array = ipa_set_data_usage_quota_resp_msg_data_v01_ei; - IPAWANDBG("Sending QMI_IPA_SET_DATA_USAGE_QUOTA_REQ_V01\n"); + IPAWANDBG_LOW("Sending QMI_IPA_SET_DATA_USAGE_QUOTA_REQ_V01\n"); if (unlikely(!ipa_q6_clnt)) return -ETIMEDOUT; rc = qmi_send_req_wait(ipa_q6_clnt, &req_desc, req, @@ -1165,7 +1165,7 @@ int ipa_qmi_set_data_quota(struct ipa_set_data_usage_quota_req_msg_v01 *req) &resp_desc, &resp, sizeof(resp), QMI_SEND_STATS_REQ_TIMEOUT_MS); - IPAWANDBG("QMI_IPA_SET_DATA_USAGE_QUOTA_RESP_V01 received\n"); + IPAWANDBG_LOW("QMI_IPA_SET_DATA_USAGE_QUOTA_RESP_V01 received\n"); return ipa_check_qmi_response(rc, QMI_IPA_SET_DATA_USAGE_QUOTA_REQ_V01, resp.resp.result, @@ -1192,14 +1192,14 @@ int ipa_qmi_stop_data_qouta(void) resp_desc.msg_id = QMI_IPA_STOP_DATA_USAGE_QUOTA_RESP_V01; resp_desc.ei_array = ipa_stop_data_usage_quota_resp_msg_data_v01_ei; - IPAWANDBG("Sending QMI_IPA_STOP_DATA_USAGE_QUOTA_REQ_V01\n"); + IPAWANDBG_LOW("Sending QMI_IPA_STOP_DATA_USAGE_QUOTA_REQ_V01\n"); if (unlikely(!ipa_q6_clnt)) return -ETIMEDOUT; rc = qmi_send_req_wait(ipa_q6_clnt, &req_desc, &req, sizeof(req), &resp_desc, &resp, sizeof(resp), QMI_SEND_STATS_REQ_TIMEOUT_MS); - IPAWANDBG("QMI_IPA_STOP_DATA_USAGE_QUOTA_RESP_V01 received\n"); + IPAWANDBG_LOW("QMI_IPA_STOP_DATA_USAGE_QUOTA_RESP_V01 received\n"); return ipa_check_qmi_response(rc, QMI_IPA_STOP_DATA_USAGE_QUOTA_REQ_V01, resp.resp.result, diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.h b/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.h index 7793fc05a339..c7c6234aae0e 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.h +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.h @@ -31,9 +31,39 @@ #define SUBSYS_MODEM "modem" #define IPAWANDBG(fmt, args...) \ - pr_debug(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args) + do { \ + pr_debug(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args); \ + IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \ + DEV_NAME " %s:%d " fmt, ## args); \ + IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \ + DEV_NAME " %s:%d " fmt, ## args); \ + } while (0) + +#define IPAWANDBG_LOW(fmt, args...) \ + do { \ + pr_debug(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args); \ + IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \ + DEV_NAME " %s:%d " fmt, ## args); \ + } while (0) + #define IPAWANERR(fmt, args...) \ - pr_err(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args) + do { \ + pr_err(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args); \ + IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \ + DEV_NAME " %s:%d " fmt, ## args); \ + IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \ + DEV_NAME " %s:%d " fmt, ## args); \ + } while (0) + +#define IPAWANINFO(fmt, args...) \ + do { \ + pr_info(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args); \ + IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \ + DEV_NAME " %s:%d " fmt, ## args); \ + IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \ + DEV_NAME " %s:%d " fmt, ## args); \ + } while (0) + extern struct ipa_qmi_context *ipa_qmi_ctx; extern struct mutex ipa_qmi_lock; diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c index 5e7a5383334c..069c5cbcf4f3 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c @@ -87,7 +87,7 @@ int __ipa_generate_rt_hw_rule_v2(enum ipa_ip_type ip, return -EPERM; } - IPADBG("en_rule 0x%x\n", en_rule); + IPADBG_LOW("en_rule 0x%x\n", en_rule); rule_hdr->u.hdr.en_rule = en_rule; ipa_write_32(rule_hdr->u.word, (u8 *)rule_hdr); @@ -490,7 +490,9 @@ static void __ipa_reap_sys_rt_tbls(enum ipa_ip_type ip) set = &ipa_ctx->rt_tbl_set[ip]; list_for_each_entry(tbl, &set->head_rt_tbl_list, link) { if (tbl->prev_mem.phys_base) { - IPADBG("reaping rt tbl name=%s ip=%d\n", tbl->name, ip); + IPADBG_LOW("reaping rt"); + IPADBG_LOW("tbl name=%s ip=%d\n", + tbl->name, ip); dma_free_coherent(ipa_ctx->pdev, tbl->prev_mem.size, tbl->prev_mem.base, tbl->prev_mem.phys_base); @@ -503,8 +505,9 @@ static void __ipa_reap_sys_rt_tbls(enum ipa_ip_type ip) list_del(&tbl->link); WARN_ON(tbl->prev_mem.phys_base != 0); if (tbl->curr_mem.phys_base) { - IPADBG("reaping sys rt tbl name=%s ip=%d\n", tbl->name, - ip); + IPADBG_LOW("reaping sys"); + IPADBG_LOW("rt tbl name=%s ip=%d\n", + tbl->name, ip); dma_free_coherent(ipa_ctx->pdev, tbl->curr_mem.size, tbl->curr_mem.base, tbl->curr_mem.phys_base); @@ -931,7 +934,7 @@ static int __ipa_del_rt_tbl(struct ipa_rt_tbl *entry) list_del(&entry->link); clear_bit(entry->idx, &ipa_ctx->rt_idx_bitmap[ip]); entry->set->tbl_cnt--; - IPADBG("del rt tbl_idx=%d tbl_cnt=%d\n", entry->idx, + IPADBG_LOW("del rt tbl_idx=%d tbl_cnt=%d\n", entry->idx, entry->set->tbl_cnt); kmem_cache_free(ipa_ctx->rt_tbl_cache, entry); } else { @@ -939,7 +942,7 @@ static int __ipa_del_rt_tbl(struct ipa_rt_tbl *entry) &ipa_ctx->reap_rt_tbl_set[ip].head_rt_tbl_list); clear_bit(entry->idx, &ipa_ctx->rt_idx_bitmap[ip]); entry->set->tbl_cnt--; - IPADBG("del sys rt tbl_idx=%d tbl_cnt=%d\n", entry->idx, + IPADBG_LOW("del sys rt tbl_idx=%d tbl_cnt=%d\n", entry->idx, entry->set->tbl_cnt); } @@ -1019,7 +1022,8 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name, WARN_ON(1); goto ipa_insert_failed; } - IPADBG("add rt rule tbl_idx=%d rule_cnt=%d\n", tbl->idx, tbl->rule_cnt); + IPADBG_LOW("add rt rule tbl_idx=%d", tbl->idx); + IPADBG_LOW("rule_cnt=%d\n", tbl->rule_cnt); *rule_hdl = id; entry->id = id; @@ -1103,7 +1107,7 @@ int __ipa_del_rt_rule(u32 rule_hdl) __ipa_release_hdr_proc_ctx(entry->proc_ctx->id); list_del(&entry->link); entry->tbl->rule_cnt--; - IPADBG("del rt rule tbl_idx=%d rule_cnt=%d\n", entry->tbl->idx, + IPADBG_LOW("del rt rule tbl_idx=%d rule_cnt=%d\n", entry->tbl->idx, entry->tbl->rule_cnt); if (entry->tbl->rule_cnt == 0 && entry->tbl->ref_cnt == 0) { if (__ipa_del_rt_tbl(entry->tbl)) diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c index 8968d5d4509f..87d84b43c829 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c @@ -1675,6 +1675,7 @@ int ipa_generate_hw_rule(enum ipa_ip_type ip, * OFFSET_MEQ32_0 with mask of 0 and val of 0 and offset 0 */ if (attrib->attrib_mask == 0) { + IPADBG_LOW("building default rule\n"); if (ipa_ofst_meq32[ofst_meq32] == -1) { IPAERR("ran out of meq32 eq\n"); return -EPERM; @@ -4913,13 +4914,17 @@ static int ipa2_stop_gsi_channel(u32 clnt_hdl) static void *ipa2_get_ipc_logbuf(void) { - /* no support for IPC logging in IPAv2 */ + if (ipa_ctx) + return ipa_ctx->logbuf; + return NULL; } static void *ipa2_get_ipc_logbuf_low(void) { - /* no support for IPC logging in IPAv2 */ + if (ipa_ctx) + return ipa_ctx->logbuf_low; + return NULL; } diff --git a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c index b1f27ceb492b..b7583b990a84 100644 --- a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c @@ -1052,7 +1052,7 @@ static int ipa_wwan_xmit(struct sk_buff *skb, struct net_device *dev) struct ipa_tx_meta meta; if (skb->protocol != htons(ETH_P_MAP)) { - IPAWANDBG + IPAWANDBG_LOW ("SW filtering out none QMAP packet received from %s", current->comm); dev_kfree_skb_any(skb); @@ -1077,7 +1077,8 @@ static int ipa_wwan_xmit(struct sk_buff *skb, struct net_device *dev) if (atomic_read(&wwan_ptr->outstanding_pkts) >= wwan_ptr->outstanding_high) { if (!qmap_check) { - IPAWANDBG("pending(%d)/(%d)- stop(%d), qmap_chk(%d)\n", + IPAWANDBG_LOW + ("pending(%d)/(%d)- stop(%d), qmap_chk(%d)\n", atomic_read(&wwan_ptr->outstanding_pkts), wwan_ptr->outstanding_high, netif_queue_stopped(dev), @@ -1171,7 +1172,8 @@ static void apps_ipa_tx_complete_notify(void *priv, netif_queue_stopped(wwan_ptr->net) && atomic_read(&wwan_ptr->outstanding_pkts) < (wwan_ptr->outstanding_low)) { - IPAWANDBG("Outstanding low (%d) - wake up queue\n", + IPAWANDBG_LOW + ("Outstanding low (%d) - wake up queue\n", wwan_ptr->outstanding_low); netif_wake_queue(wwan_ptr->net); } @@ -1201,7 +1203,7 @@ static void apps_ipa_packet_receive_notify(void *priv, int result; unsigned int packet_len = skb->len; - IPAWANDBG("Rx packet was received"); + IPAWANDBG_LOW("Rx packet was received"); skb->dev = ipa_netdevs[0]; skb->protocol = htons(ETH_P_MAP); @@ -1763,10 +1765,10 @@ static void q6_rm_notify_cb(void *user_data, { switch (event) { case IPA_RM_RESOURCE_GRANTED: - IPAWANDBG("%s: Q6_PROD GRANTED CB\n", __func__); + IPAWANDBG_LOW("%s: Q6_PROD GRANTED CB\n", __func__); break; case IPA_RM_RESOURCE_RELEASED: - IPAWANDBG("%s: Q6_PROD RELEASED CB\n", __func__); + IPAWANDBG_LOW("%s: Q6_PROD RELEASED CB\n", __func__); break; default: return; @@ -1873,7 +1875,7 @@ static void wake_tx_queue(struct work_struct *work) */ static void ipa_rm_resource_granted(void *dev) { - IPAWANDBG("Resource Granted - starting queue\n"); + IPAWANDBG_LOW("Resource Granted - starting queue\n"); schedule_work(&ipa_tx_wakequeue_work); } @@ -2246,7 +2248,7 @@ static int rmnet_ipa_ap_suspend(struct device *dev) struct net_device *netdev = ipa_netdevs[0]; struct wwan_private *wwan_ptr = netdev_priv(netdev); - IPAWANDBG("Enter...\n"); + IPAWANDBG_LOW("Enter...\n"); /* Do not allow A7 to suspend in case there are oustanding packets */ if (atomic_read(&wwan_ptr->outstanding_pkts) != 0) { IPAWANDBG("Outstanding packets, postponing AP suspend.\n"); @@ -2257,7 +2259,7 @@ static int rmnet_ipa_ap_suspend(struct device *dev) netif_tx_lock_bh(netdev); ipa_rm_release_resource(IPA_RM_RESOURCE_WWAN_0_PROD); netif_tx_unlock_bh(netdev); - IPAWANDBG("Exit\n"); + IPAWANDBG_LOW("Exit\n"); return 0; } @@ -2276,9 +2278,9 @@ static int rmnet_ipa_ap_resume(struct device *dev) { struct net_device *netdev = ipa_netdevs[0]; - IPAWANDBG("Enter...\n"); + IPAWANDBG_LOW("Enter...\n"); netif_wake_queue(netdev); - IPAWANDBG("Exit\n"); + IPAWANDBG_LOW("Exit\n"); return 0; } @@ -2355,6 +2357,7 @@ static int ssr_notifier_cb(struct notifier_block *this, return NOTIFY_DONE; } } + IPAWANDBG_LOW("Exit\n"); return NOTIFY_DONE; } @@ -2658,7 +2661,7 @@ int rmnet_ipa_query_tethering_stats(struct wan_ioctl_query_tether_stats *data, IPAWANERR("reset the pipe stats\n"); } else { /* print tethered-client enum */ - IPAWANDBG("Tethered-client enum(%d)\n", data->ipa_client); + IPAWANDBG_LOW("Tethered-client enum(%d)\n", data->ipa_client); } rc = ipa_qmi_get_data_stats(req, resp); @@ -2676,10 +2679,11 @@ int rmnet_ipa_query_tethering_stats(struct wan_ioctl_query_tether_stats *data, if (resp->dl_dst_pipe_stats_list_valid) { for (pipe_len = 0; pipe_len < resp->dl_dst_pipe_stats_list_len; pipe_len++) { - IPAWANDBG("Check entry(%d) dl_dst_pipe(%d)\n", + IPAWANDBG_LOW("Check entry(%d) dl_dst_pipe(%d)\n", pipe_len, resp->dl_dst_pipe_stats_list [pipe_len].pipe_index); - IPAWANDBG("dl_p_v4(%lu)v6(%lu) dl_b_v4(%lu)v6(%lu)\n", + IPAWANDBG_LOW + ("dl_p_v4(%lu)v6(%lu) dl_b_v4(%lu)v6(%lu)\n", (unsigned long int) resp-> dl_dst_pipe_stats_list[pipe_len]. num_ipv4_packets, @@ -2715,7 +2719,7 @@ int rmnet_ipa_query_tethering_stats(struct wan_ioctl_query_tether_stats *data, } } } - IPAWANDBG("v4_rx_p(%lu) v6_rx_p(%lu) v4_rx_b(%lu) v6_rx_b(%lu)\n", + IPAWANDBG_LOW("v4_rx_p(%lu) v6_rx_p(%lu) v4_rx_b(%lu) v6_rx_b(%lu)\n", (unsigned long int) data->ipv4_rx_packets, (unsigned long int) data->ipv6_rx_packets, (unsigned long int) data->ipv4_rx_bytes, @@ -2724,11 +2728,12 @@ int rmnet_ipa_query_tethering_stats(struct wan_ioctl_query_tether_stats *data, if (resp->ul_src_pipe_stats_list_valid) { for (pipe_len = 0; pipe_len < resp->ul_src_pipe_stats_list_len; pipe_len++) { - IPAWANDBG("Check entry(%d) ul_dst_pipe(%d)\n", + IPAWANDBG_LOW("Check entry(%d) ul_dst_pipe(%d)\n", pipe_len, resp->ul_src_pipe_stats_list[pipe_len]. pipe_index); - IPAWANDBG("ul_p_v4(%lu)v6(%lu)ul_b_v4(%lu)v6(%lu)\n", + IPAWANDBG_LOW + ("ul_p_v4(%lu)v6(%lu)ul_b_v4(%lu)v6(%lu)\n", (unsigned long int) resp-> ul_src_pipe_stats_list[pipe_len]. num_ipv4_packets, @@ -2764,7 +2769,7 @@ int rmnet_ipa_query_tethering_stats(struct wan_ioctl_query_tether_stats *data, } } } - IPAWANDBG("tx_p_v4(%lu)v6(%lu)tx_b_v4(%lu) v6(%lu)\n", + IPAWANDBG_LOW("tx_p_v4(%lu)v6(%lu)tx_b_v4(%lu) v6(%lu)\n", (unsigned long int) data->ipv4_tx_packets, (unsigned long int) data->ipv6_tx_packets, (unsigned long int) data->ipv4_tx_bytes, 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 811dba4ab756..6a92c5fb7d52 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 @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, 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 @@ -145,8 +145,7 @@ static long wan_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; case WAN_IOC_POLL_TETHERING_STATS: - IPAWANDBG("device %s got WAN_IOCTL_POLL_TETHERING_STATS :>>>\n", - DRIVER_NAME); + IPAWANDBG_LOW("got WAN_IOCTL_POLL_TETHERING_STATS :>>>\n"); pyld_sz = sizeof(struct wan_ioctl_poll_tethering_stats); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { @@ -170,8 +169,7 @@ static long wan_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; case WAN_IOC_SET_DATA_QUOTA: - IPAWANDBG("device %s got WAN_IOCTL_SET_DATA_QUOTA :>>>\n", - DRIVER_NAME); + IPAWANDBG_LOW("got WAN_IOCTL_SET_DATA_QUOTA :>>>\n"); pyld_sz = sizeof(struct wan_ioctl_set_data_quota); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { @@ -195,8 +193,7 @@ static long wan_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; case WAN_IOC_SET_TETHER_CLIENT_PIPE: - IPAWANDBG("device %s got WAN_IOC_SET_TETHER_CLIENT_PIPE :>>>\n", - DRIVER_NAME); + IPAWANDBG_LOW("got WAN_IOC_SET_TETHER_CLIENT_PIPE :>>>\n"); pyld_sz = sizeof(struct wan_ioctl_set_tether_client_pipe); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { @@ -216,8 +213,7 @@ static long wan_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; case WAN_IOC_QUERY_TETHER_STATS: - IPAWANDBG("device %s got WAN_IOC_QUERY_TETHER_STATS :>>>\n", - DRIVER_NAME); + IPAWANDBG_LOW("got WAN_IOC_QUERY_TETHER_STATS :>>>\n"); pyld_sz = sizeof(struct wan_ioctl_query_tether_stats); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { @@ -243,8 +239,7 @@ static long wan_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; case WAN_IOC_RESET_TETHER_STATS: - IPAWANDBG("device %s got WAN_IOC_RESET_TETHER_STATS :>>>\n", - DRIVER_NAME); + IPAWANDBG_LOW("got WAN_IOC_RESET_TETHER_STATS :>>>\n"); pyld_sz = sizeof(struct wan_ioctl_reset_tether_stats); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 214ae08234a9..3d276b0f535d 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -3616,6 +3616,7 @@ static int ipa3_apps_cons_request_resource(void) static void ipa3_sps_release_resource(struct work_struct *work) { + mutex_lock(&ipa3_ctx->transport_pm.transport_pm_mutex); /* check whether still need to decrease client usage */ if (atomic_read(&ipa3_ctx->transport_pm.dec_clients)) { if (atomic_read(&ipa3_ctx->transport_pm.eot_activity)) { @@ -3627,6 +3628,7 @@ static void ipa3_sps_release_resource(struct work_struct *work) } } atomic_set(&ipa3_ctx->transport_pm.eot_activity, 0); + mutex_unlock(&ipa3_ctx->transport_pm.transport_pm_mutex); } int ipa3_create_apps_resource(void) @@ -4406,6 +4408,8 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, goto fail_create_transport_wq; } + /* Initialize the SPS PM lock. */ + mutex_init(&ipa3_ctx->transport_pm.transport_pm_mutex); spin_lock_init(&ipa3_ctx->transport_pm.lock); ipa3_ctx->transport_pm.res_granted = false; ipa3_ctx->transport_pm.res_rel_in_prog = false; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c index 26bd180624f1..00bfbf84c75a 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c @@ -1474,7 +1474,7 @@ static int ipa3_is_xdci_channel_empty(struct ipa3_ep_context *ep, return 0; } -static int ipa3_enable_force_clear(u32 request_id, bool throttle_source, +int ipa3_enable_force_clear(u32 request_id, bool throttle_source, u32 source_pipe_bitmask) { struct ipa_enable_force_clear_datapath_req_msg_v01 req; @@ -1497,7 +1497,7 @@ static int ipa3_enable_force_clear(u32 request_id, bool throttle_source, return 0; } -static int ipa3_disable_force_clear(u32 request_id) +int ipa3_disable_force_clear(u32 request_id) { struct ipa_disable_force_clear_datapath_req_msg_v01 req; int result; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index b4f447f56d1c..fe7c88a25374 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -974,6 +974,7 @@ struct ipa3_uc_wdi_ctx { * @lock: lock for ensuring atomic operations * @res_granted: true if SPS requested IPA resource and IPA granted it * @res_rel_in_prog: true if releasing IPA resource is in progress + * @transport_pm_mutex: Mutex to protect the transport_pm functionality. */ struct ipa3_transport_pm { spinlock_t lock; @@ -981,6 +982,7 @@ struct ipa3_transport_pm { bool res_rel_in_prog; atomic_t dec_clients; atomic_t eot_activity; + struct mutex transport_pm_mutex; }; /** @@ -1917,6 +1919,9 @@ int ipa3_alloc_rule_id(struct idr *rule_ids); int ipa3_id_alloc(void *ptr); void *ipa3_id_find(u32 id); void ipa3_id_remove(u32 id); +int ipa3_enable_force_clear(u32 request_id, bool throttle_source, + u32 source_pipe_bitmask); +int ipa3_disable_force_clear(u32 request_id); int ipa3_set_required_perf_profile(enum ipa_voltage_level floor_voltage, u32 bandwidth_mbps); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c index 8cb6935cd720..41bb8651f69c 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c @@ -1370,6 +1370,7 @@ int ipa3_disable_wdi_pipe(u32 clnt_hdl) u32 prod_hdl; int i; u32 rx_door_bell_value; + u32 source_pipe_bitmask = 0; if (clnt_hdl >= ipa3_ctx->ipa_num_pipes || ipa3_ctx->ep[clnt_hdl].valid == 0) { @@ -1405,6 +1406,17 @@ int ipa3_disable_wdi_pipe(u32 clnt_hdl) * holb on IPA Producer pipe */ if (IPA_CLIENT_IS_PROD(ep->client)) { + /* enable force clear */ + IPADBG("Stopping PROD channel - hdl=%d clnt=%d\n", + clnt_hdl, ep->client); + source_pipe_bitmask = 1 << + ipa3_get_ep_mapping(ep->client); + result = ipa3_enable_force_clear(clnt_hdl, false, + source_pipe_bitmask); + if (result) + goto uc_timeout; + + /* remove delay on wlan-prod pipe*/ memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl)); ipa3_cfg_ep_ctrl(clnt_hdl, &ep_cfg_ctrl); @@ -1437,7 +1449,7 @@ int ipa3_disable_wdi_pipe(u32 clnt_hdl) rx_door_bell_value, *ipa3_ctx->uc_ctx.rdy_ring_rp_va, *ipa3_ctx->uc_ctx.rdy_comp_ring_wp_va); - if (rx_door_bell_value != + if (*ipa3_ctx->uc_ctx.rdy_ring_rp_va != *ipa3_ctx->uc_ctx.rdy_comp_ring_wp_va) { usleep_range(IPA_UC_WAIT_MIN_SLEEP, IPA_UC_WAII_MAX_SLEEP); @@ -1470,11 +1482,14 @@ int ipa3_disable_wdi_pipe(u32 clnt_hdl) memset(&ep_cfg_ctrl, 0, sizeof(struct ipa_ep_cfg_ctrl)); ep_cfg_ctrl.ipa_ep_delay = true; ipa3_cfg_ep_ctrl(clnt_hdl, &ep_cfg_ctrl); + /* disable force clear */ + ipa3_disable_force_clear(clnt_hdl); } IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(clnt_hdl)); ep->uc_offload_state &= ~IPA_WDI_ENABLED; IPADBG("client (ep: %d) disabled\n", clnt_hdl); + uc_timeout: return result; } diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index c3792d5a72ac..561a0d38e502 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.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 @@ -720,6 +720,15 @@ int icnss_power_on(struct device *dev) } EXPORT_SYMBOL(icnss_power_on); +bool icnss_is_fw_ready(void) +{ + if (!penv) + return false; + else + return test_bit(ICNSS_FW_READY, &penv->state); +} +EXPORT_SYMBOL(icnss_is_fw_ready); + int icnss_power_off(struct device *dev) { struct icnss_priv *priv = dev_get_drvdata(dev); diff --git a/drivers/soc/qcom/msm_glink_pkt.c b/drivers/soc/qcom/msm_glink_pkt.c index 9ebc6a3c23c9..78f6a2aa8f66 100644 --- a/drivers/soc/qcom/msm_glink_pkt.c +++ b/drivers/soc/qcom/msm_glink_pkt.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -502,13 +502,21 @@ static void glink_pkt_queue_rx_intent_worker(struct work_struct *work) struct queue_rx_intent_work, work); struct glink_pkt_dev *devp = work_item->devp; - if (!devp || !devp->handle) { + if (!devp) { + GLINK_PKT_ERR("%s: Invalid device\n", __func__); + kfree(work_item); + return; + } + mutex_lock(&devp->ch_lock); + if (!devp->handle) { GLINK_PKT_ERR("%s: Invalid device Handle\n", __func__); + mutex_unlock(&devp->ch_lock); kfree(work_item); return; } ret = glink_queue_rx_intent(devp->handle, devp, work_item->intent_size); + mutex_unlock(&devp->ch_lock); GLINK_PKT_INFO("%s: Triggered with size[%zu] ret[%d]\n", __func__, work_item->intent_size, ret); if (ret) @@ -1051,6 +1059,27 @@ error: } /** + * pop_rx_pkt() - return first pkt from rx pkt_list + * devp: pointer to G-Link packet device. + * + * This function return first item from rx pkt_list and NULL if list is empty. + */ +struct glink_rx_pkt *pop_rx_pkt(struct glink_pkt_dev *devp) +{ + unsigned long flags; + struct glink_rx_pkt *pkt = NULL; + + spin_lock_irqsave(&devp->pkt_list_lock, flags); + if (!list_empty(&devp->pkt_list)) { + pkt = list_first_entry(&devp->pkt_list, + struct glink_rx_pkt, list); + list_del(&pkt->list); + } + spin_unlock_irqrestore(&devp->pkt_list_lock, flags); + return pkt; +} + +/** * glink_pkt_release() - release operation on glink_pkt device * inode: Pointer to the inode structure. * file: Pointer to the file structure. @@ -1064,6 +1093,7 @@ int glink_pkt_release(struct inode *inode, struct file *file) int ret = 0; struct glink_pkt_dev *devp = file->private_data; unsigned long flags; + struct glink_rx_pkt *pkt; GLINK_PKT_INFO("%s() on dev id:%d by [%s] ref_cnt[%d]\n", __func__, devp->i, current->comm, devp->ref_cnt); @@ -1072,9 +1102,14 @@ int glink_pkt_release(struct inode *inode, struct file *file) devp->ref_cnt--; if (devp->handle && devp->ref_cnt == 0) { + while ((pkt = pop_rx_pkt(devp))) { + glink_rx_done(devp->handle, pkt->data, false); + kfree(pkt); + } wake_up(&devp->ch_read_wait_queue); wake_up_interruptible(&devp->ch_opened_wait_queue); ret = glink_close(devp->handle); + devp->handle = NULL; if (ret) { GLINK_PKT_ERR("%s: close failed ret[%d]\n", __func__, ret); diff --git a/include/soc/qcom/icnss.h b/include/soc/qcom/icnss.h index 9c38b9aa5627..14892a05bd19 100644 --- a/include/soc/qcom/icnss.h +++ b/include/soc/qcom/icnss.h @@ -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 @@ -124,6 +124,7 @@ extern int icnss_get_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 *ch_count, extern int icnss_wlan_set_dfs_nol(const void *info, u16 info_len); extern int icnss_wlan_get_dfs_nol(void *info, u16 info_len); extern bool icnss_is_qmi_disable(void); +extern bool icnss_is_fw_ready(void); extern int icnss_set_wlan_mac_address(const u8 *in, const uint32_t len); extern u8 *icnss_get_wlan_mac_address(struct device *dev, uint32_t *num); diff --git a/net/rmnet_data/rmnet_map_command.c b/net/rmnet_data/rmnet_map_command.c index 055d5f402957..9dac2b27d4c3 100644 --- a/net/rmnet_data/rmnet_map_command.c +++ b/net/rmnet_data/rmnet_map_command.c @@ -121,6 +121,7 @@ static void rmnet_map_send_ack(struct sk_buff *skb, { struct rmnet_map_control_command_s *cmd; int xmit_status; + int rc; if (unlikely(!skb)) BUG(); @@ -149,6 +150,15 @@ static void rmnet_map_send_ack(struct sk_buff *skb, netif_tx_unlock(skb->dev); LOGD("MAP command ACK=%hhu sent with rc: %d", type & 0x03, xmit_status); + + if (xmit_status != NETDEV_TX_OK) { + rc = dev_queue_xmit(skb); + if (rc != 0) { + LOGD("Failed to queue packet for transmission on [%s]", + skb->dev->name); + } + } + } /** diff --git a/sound/soc/msm/sdm660-common.c b/sound/soc/msm/sdm660-common.c index 623b8c5c866a..1497ddcca61f 100644 --- a/sound/soc/msm/sdm660-common.c +++ b/sound/soc/msm/sdm660-common.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 @@ -169,6 +169,7 @@ struct mi2s_conf { struct mutex lock; u32 ref_cnt; u32 msm_is_mi2s_master; + u32 msm_is_ext_mclk; }; struct auxpcm_conf { @@ -176,6 +177,13 @@ struct auxpcm_conf { u32 ref_cnt; }; +static u32 mi2s_ebit_clk[MI2S_MAX] = { + Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT, + Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT +}; + struct msm_wsa881x_dev_info { struct device_node *of_node; u32 index; @@ -340,6 +348,43 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = { } }; +static struct afe_clk_set mi2s_mclk[MI2S_MAX] = { + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_MCLK_1, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_MCLK_2, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_MCLK_3, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + }, + { + AFE_API_VERSION_I2S_CONFIG, + Q6AFE_LPASS_CLK_ID_MCLK_4, + Q6AFE_LPASS_OSR_CLK_9_P600_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, + } +}; + + + static struct mi2s_aux_pcm_common_conf mi2s_auxpcm_conf[PCM_I2S_SEL_MAX]; static struct mi2s_conf mi2s_intf_conf[MI2S_MAX]; static struct auxpcm_conf auxpcm_intf_conf[AUX_PCM_MAX]; @@ -1638,6 +1683,17 @@ const struct snd_kcontrol_new msm_common_snd_controls[] = { tdm_tx_ch_put), }; +/** + * msm_common_snd_controls_size - to return controls size + * + * Return: returns size of common controls array + */ +int msm_common_snd_controls_size(void) +{ + return ARRAY_SIZE(msm_common_snd_controls); +} +EXPORT_SYMBOL(msm_common_snd_controls_size); + static inline int param_is_mask(int p) { return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && @@ -2095,6 +2151,7 @@ int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int port_id = msm_get_port_id(rtd->dai_link->be_id); int index = cpu_dai->id; unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; @@ -2117,6 +2174,11 @@ int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) */ mutex_lock(&mi2s_intf_conf[index].lock); if (++mi2s_intf_conf[index].ref_cnt == 1) { + /* Check if msm needs to provide the clock to the interface */ + if (!mi2s_intf_conf[index].msm_is_mi2s_master) { + mi2s_clk[index].clk_id = mi2s_ebit_clk[index]; + fmt = SND_SOC_DAIFMT_CBM_CFM; + } ret = msm_mi2s_set_sclk(substream, true); if (IS_ERR_VALUE(ret)) { dev_err(rtd->card->dev, @@ -2136,9 +2198,6 @@ int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) ret = -EINVAL; goto clk_off; } - /* Check if msm needs to provide the clock to the interface */ - if (!mi2s_intf_conf[index].msm_is_mi2s_master) - fmt = SND_SOC_DAIFMT_CBM_CFM; ret = snd_soc_dai_set_fmt(cpu_dai, fmt); if (IS_ERR_VALUE(ret)) { dev_err(rtd->card->dev, @@ -2146,7 +2205,21 @@ int msm_mi2s_snd_startup(struct snd_pcm_substream *substream) __func__, index, ret); goto clk_off; } + if (mi2s_intf_conf[index].msm_is_ext_mclk) { + mi2s_mclk[index].enable = 1; + pr_debug("%s: Enabling mclk, clk_freq_in_hz = %u\n", + __func__, mi2s_mclk[index].clk_freq_in_hz); + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_mclk[index]); + if (ret < 0) { + pr_err("%s: afe lpass mclk failed, err:%d\n", + __func__, ret); + goto clk_off; + } + } } + mutex_unlock(&mi2s_intf_conf[index].lock); + return 0; clk_off: if (IS_ERR_VALUE(ret)) msm_mi2s_set_sclk(substream, false); @@ -2168,6 +2241,7 @@ void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) { int ret; struct snd_soc_pcm_runtime *rtd = substream->private_data; + int port_id = msm_get_port_id(rtd->dai_link->be_id); int index = rtd->cpu_dai->id; pr_debug("%s(): substream = %s stream = %d\n", __func__, @@ -2185,6 +2259,17 @@ void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream) __func__, index, ret); mi2s_intf_conf[index].ref_cnt++; } + if (mi2s_intf_conf[index].msm_is_ext_mclk) { + mi2s_mclk[index].enable = 0; + pr_debug("%s: Disabling mclk, clk_freq_in_hz = %u\n", + __func__, mi2s_mclk[index].clk_freq_in_hz); + ret = afe_set_lpass_clock_v2(port_id, + &mi2s_mclk[index]); + if (ret < 0) { + pr_err("%s: mclk disable failed for MCLK (%d); ret=%d\n", + __func__, index, ret); + } + } } mutex_unlock(&mi2s_intf_conf[index].lock); } @@ -2601,6 +2686,7 @@ static void i2s_auxpcm_init(struct platform_device *pdev) struct resource *muxsel; int count; u32 mi2s_master_slave[MI2S_MAX]; + u32 mi2s_ext_mclk[MI2S_MAX]; int ret; char *str[PCM_I2S_SEL_MAX] = { "lpaif_pri_mode_muxsel", @@ -2634,8 +2720,8 @@ static void i2s_auxpcm_init(struct platform_device *pdev) } ret = of_property_read_u32_array(pdev->dev.of_node, - "qcom,msm-mi2s-master", - mi2s_master_slave, MI2S_MAX); + "qcom,msm-mi2s-master", + mi2s_master_slave, MI2S_MAX); if (ret) { dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n", __func__); @@ -2645,6 +2731,18 @@ static void i2s_auxpcm_init(struct platform_device *pdev) mi2s_master_slave[count]; } } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "qcom,msm-mi2s-ext-mclk", + mi2s_ext_mclk, MI2S_MAX); + if (ret) { + dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-ext-mclk in DT node\n", + __func__); + } else { + for (count = 0; count < MI2S_MAX; count++) + mi2s_intf_conf[count].msm_is_ext_mclk = + mi2s_ext_mclk[count]; + } } static void i2s_auxpcm_deinit(void) @@ -2772,11 +2870,24 @@ static int msm_asoc_machine_probe(struct platform_device *pdev) ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret) { + if (ret == -EPROBE_DEFER) { + if (codec_reg_done) { + /* + * return failure as EINVAL since other codec + * registered sound card successfully. + * This avoids any further probe calls. + */ + ret = -EINVAL; + } + goto err; + } else if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); goto err; } + if (pdata->snd_card_val != INT_SND_CARD) + msm_ext_register_audio_notifier(pdev); + return 0; err: if (pdata->us_euro_gpio > 0) { diff --git a/sound/soc/msm/sdm660-common.h b/sound/soc/msm/sdm660-common.h index 71b6a0786549..36c2d9b7ca4e 100644 --- a/sound/soc/msm/sdm660-common.h +++ b/sound/soc/msm/sdm660-common.h @@ -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 @@ -66,6 +66,7 @@ enum { }; extern const struct snd_kcontrol_new msm_common_snd_controls[]; +extern bool codec_reg_done; struct sdm660_codec { void* (*get_afe_config_fn)(struct snd_soc_codec *codec, enum afe_config_type config_type); @@ -112,4 +113,5 @@ int msm_aux_pcm_snd_startup(struct snd_pcm_substream *substream); void msm_aux_pcm_snd_shutdown(struct snd_pcm_substream *substream); int msm_mi2s_snd_startup(struct snd_pcm_substream *substream); void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream); +int msm_common_snd_controls_size(void); #endif diff --git a/sound/soc/msm/sdm660-external.c b/sound/soc/msm/sdm660-external.c index f610eb53d5df..c900ce1a0fe9 100644 --- a/sound/soc/msm/sdm660-external.c +++ b/sound/soc/msm/sdm660-external.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 @@ -56,6 +56,7 @@ static int msm_ext_spk_control = 1; static struct wcd_mbhc_config *wcd_mbhc_cfg_ptr; +bool codec_reg_done; struct msm_asoc_wcd93xx_codec { void* (*get_afe_config_fn)(struct snd_soc_codec *codec, @@ -1529,6 +1530,14 @@ int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) return ret; } + ret = snd_soc_add_codec_controls(codec, msm_common_snd_controls, + msm_common_snd_controls_size()); + if (ret < 0) { + pr_err("%s: add_common_snd_controls failed: %d\n", + __func__, ret); + return ret; + } + snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, ARRAY_SIZE(msm_dapm_widgets)); @@ -1722,6 +1731,7 @@ int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) } } + codec_reg_done = true; done: return 0; @@ -1735,10 +1745,12 @@ EXPORT_SYMBOL(msm_audrx_init); /** * msm_ext_register_audio_notifier - register SSR notifier. */ -void msm_ext_register_audio_notifier(void) +void msm_ext_register_audio_notifier(struct platform_device *pdev) { int ret; + is_initial_boot = true; + spdev = pdev; ret = audio_notifier_register("sdm660", AUDIO_NOTIFIER_ADSP_DOMAIN, &service_nb); if (ret < 0) @@ -1777,10 +1789,8 @@ int msm_ext_cdc_init(struct platform_device *pdev, ret = -EPROBE_DEFER; goto err; } - spdev = pdev; platform_set_drvdata(pdev, *card); snd_soc_card_set_drvdata(*card, pdata); - is_initial_boot = true; pdata->hph_en1_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,hph-en1-gpio", 0); if (!gpio_is_valid(pdata->hph_en1_gpio)) diff --git a/sound/soc/msm/sdm660-external.h b/sound/soc/msm/sdm660-external.h index 0ede06f0c082..7625a24e8fae 100644 --- a/sound/soc/msm/sdm660-external.h +++ b/sound/soc/msm/sdm660-external.h @@ -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 @@ -33,7 +33,7 @@ int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, #ifdef CONFIG_SND_SOC_EXT_CODEC int msm_ext_cdc_init(struct platform_device *, struct msm_asoc_mach_data *, struct snd_soc_card **, struct wcd_mbhc_config *); -void msm_ext_register_audio_notifier(void); +void msm_ext_register_audio_notifier(struct platform_device *pdev); void msm_ext_cdc_deinit(void); #else inline int msm_ext_cdc_init(struct platform_device *pdev, @@ -44,7 +44,7 @@ inline int msm_ext_cdc_init(struct platform_device *pdev, return 0; } -inline void msm_ext_register_audio_notifier(void) +inline void msm_ext_register_audio_notifier(struct platform_device *pdev) { } inline void msm_ext_cdc_deinit(void) diff --git a/sound/soc/msm/sdm660-internal.c b/sound/soc/msm/sdm660-internal.c index aa094fe853ee..5d3ec356343e 100644 --- a/sound/soc/msm/sdm660-internal.c +++ b/sound/soc/msm/sdm660-internal.c @@ -1300,8 +1300,20 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) pr_debug("%s(),dev_name%s\n", __func__, dev_name(cpu_dai->dev)); - snd_soc_add_codec_controls(ana_cdc, msm_snd_controls, + ret = snd_soc_add_codec_controls(ana_cdc, msm_snd_controls, ARRAY_SIZE(msm_snd_controls)); + if (ret < 0) { + pr_err("%s: add_codec_controls failed: %d\n", + __func__, ret); + return ret; + } + ret = snd_soc_add_codec_controls(ana_cdc, msm_common_snd_controls, + msm_common_snd_controls_size()); + if (ret < 0) { + pr_err("%s: add common snd controls failed: %d\n", + __func__, ret); + return ret; + } snd_soc_dapm_new_controls(dapm, msm_int_dapm_widgets, ARRAY_SIZE(msm_int_dapm_widgets)); @@ -3033,7 +3045,7 @@ static int msm_internal_init(struct platform_device *pdev, AFE_API_VERSION_I2S_CONFIG; pdata->digital_cdc_core_clk.clk_id = Q6AFE_LPASS_CLK_ID_INT_MCLK_0; - pdata->digital_cdc_core_clk.clk_freq_in_hz = 0; + pdata->digital_cdc_core_clk.clk_freq_in_hz = pdata->mclk_freq; pdata->digital_cdc_core_clk.clk_attri = Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO; pdata->digital_cdc_core_clk.clk_root = |
