summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/qcom-audio-dev.txt5
-rw-r--r--arch/arm/boot/dts/qcom/Makefile3
-rw-r--r--arch/arm/boot/dts/qcom/msm8996.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-coresight.dtsi10
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-interposer-sdm660.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi6
-rw-r--r--arch/arm/boot/dts/qcom/msm8998.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom/sdm630-pm660a-rumi.dts88
-rw-r--r--arch/arm/boot/dts/qcom/sdm630-rumi.dts6
-rw-r--r--arch/arm/boot/dts/qcom/sdm630.dtsi9
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-camera.dtsi60
-rw-r--r--arch/arm/boot/dts/qcom/sdm660.dtsi39
-rw-r--r--arch/arm/configs/sdm660-perf_defconfig4
-rw-r--r--drivers/clk/qcom/clk-smd-rpm.c28
-rw-r--r--drivers/clk/qcom/clk-voter.c10
-rw-r--r--drivers/clk/qcom/clk-voter.h3
-rw-r--r--drivers/gpu/msm/adreno-gpulist.h5
-rw-r--r--drivers/mmc/card/block.c19
-rw-r--r--drivers/mmc/core/core.c7
-rw-r--r--drivers/mmc/core/mmc.c9
-rw-r--r--drivers/mmc/core/sdio.c1
-rw-r--r--drivers/mmc/host/sdhci.c3
-rw-r--r--drivers/net/ethernet/msm/rndis_ipa.c432
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa.c43
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c49
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_dma.c51
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_dp.c94
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_flt.c28
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c22
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_i.h35
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_interrupts.c20
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_intf.c4
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_mhi.c36
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c24
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.h34
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_rt.c20
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_utils.c9
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c41
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/rmnet_ipa_fd_ioctl.c17
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa.c4
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_client.c4
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_i.h5
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c17
-rw-r--r--drivers/soc/qcom/icnss.c11
-rw-r--r--drivers/soc/qcom/msm_glink_pkt.c39
-rw-r--r--include/soc/qcom/icnss.h3
-rw-r--r--net/rmnet_data/rmnet_map_command.c10
-rw-r--r--sound/soc/msm/sdm660-common.c125
-rw-r--r--sound/soc/msm/sdm660-common.h4
-rw-r--r--sound/soc/msm/sdm660-external.c18
-rw-r--r--sound/soc/msm/sdm660-external.h6
-rw-r--r--sound/soc/msm/sdm660-internal.c16
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 =