summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/qcom-audio-dev.txt7
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-mtp.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-sde-display.dtsi40
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-sde.dtsi39
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-v2.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/msm8996.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom/msm8996v3-auto.dtsi39
-rw-r--r--arch/arm/boot/dts/qcom/sdm630.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom/sdm660.dtsi1
-rw-r--r--drivers/char/adsprpc.c12
-rw-r--r--drivers/char/diag/diag_masks.c14
-rw-r--r--drivers/char/diag/diag_memorydevice.c31
-rw-r--r--drivers/char/diag/diag_mux.c7
-rw-r--r--drivers/char/diag/diagchar_core.c24
-rw-r--r--drivers/char/diag/diagfwd_peripheral.c55
-rw-r--r--drivers/char/diag/diagfwd_peripheral.h3
-rw-r--r--drivers/hwtracing/coresight/coresight-tmc.c36
-rw-r--r--drivers/media/platform/msm/ais/sensor/flash/msm_flash.c10
-rw-r--r--drivers/media/platform/msm/ais/sensor/ois/msm_ois.c3
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c3
-rw-r--r--drivers/platform/msm/Kconfig2
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_flt.c18
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c39
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_i.h18
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_rt.c37
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_flt.c35
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c37
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_i.h16
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_rt.c41
-rw-r--r--drivers/power/qcom/msm-core.c4
-rw-r--r--drivers/power/supply/qcom/qpnp-smb2.c8
-rw-r--r--drivers/power/supply/qcom/smb-lib.c17
-rw-r--r--drivers/power/supply/qcom/smb-lib.h1
-rw-r--r--drivers/tty/serial/msm_serial_hs.c2
-rw-r--r--drivers/usb/pd/policy_engine.c20
-rw-r--r--drivers/video/fbdev/msm/mdss.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c9
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_ctl.c24
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_layer.c8
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c34
-rw-r--r--drivers/video/fbdev/msm/msm_mdss_io_8974.c3
-rw-r--r--include/sound/apr_audio-v2.h73
-rw-r--r--include/sound/q6adm-v2.h10
-rw-r--r--include/sound/q6asm-v2.h8
-rw-r--r--net/ipv6/datagram.c5
-rw-r--r--net/ipv6/udp.c24
-rw-r--r--sound/soc/msm/msm-dai-fe.c95
-rw-r--r--sound/soc/msm/msm8998.c85
-rw-r--r--sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c57
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c264
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c254
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h11
-rw-r--r--sound/soc/msm/qdsp6v2/msm-qti-pp-config.c10
-rw-r--r--sound/soc/msm/qdsp6v2/q6adm.c6
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c292
57 files changed, 1662 insertions, 246 deletions
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index 38e056cdc0ee..db21a2b58c2b 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -1311,6 +1311,13 @@ Optional properties:
- pinctrl-x: Defines pinctrl state for each pin group.
+ - qcom,msm-cpudai-tdm-clk-attribute: Clock attribute for tdm.
+ 0 - Clk invalid attribute
+ 1 - Clk attribute couple no
+ 2 - Clk attribute couple dividend
+ 3 - Clk attribute couple divisor
+ 4 - Clk attribute invert couple no
+
Example:
qcom,msm-dai-tdm-quat-rx {
diff --git a/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi b/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi
index a4c08f19dfa0..9dbec1e87fda 100644
--- a/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi
@@ -547,7 +547,7 @@
#include "msm8996-sde-display.dtsi"
-&mdss_mdp {
+&sde_kms {
qcom,mdss-pref-prim-intf = "dsi";
qcom,sde-plane-id-map {
qcom,sde-plane-id@0 {
@@ -1241,7 +1241,7 @@
qcom,vin-sel = <2>; /* 1.8 */
qcom,out-strength = <1>;
qcom,src-sel = <0>; /* GPIO */
- qcom,master-en = <0>; /* Disable GPIO */
+ qcom,master-en = <1>; /* Enable GPIO */
status = "okay";
};
diff --git a/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi
index 91cfa5826519..ad14bfd00cd1 100644
--- a/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi
@@ -333,7 +333,7 @@
};
};
-&mdss_mdp {
+&sde_kms {
qcom,mdss-pref-prim-intf = "dsi";
qcom,sde-plane-id-map {
qcom,sde-plane-id@0 {
diff --git a/arch/arm/boot/dts/qcom/msm8996-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8996-mtp.dtsi
index ab10a71d1fd7..0bd9b02f3d2e 100644
--- a/arch/arm/boot/dts/qcom/msm8996-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-mtp.dtsi
@@ -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
@@ -343,7 +343,7 @@
qcom,mdss-pref-prim-intf = "dsi";
};
-&mdss_hdmi {
+&sde_hdmi {
status = "ok";
};
diff --git a/arch/arm/boot/dts/qcom/msm8996-sde-display.dtsi b/arch/arm/boot/dts/qcom/msm8996-sde-display.dtsi
index 061301f1c479..1c81bc433374 100644
--- a/arch/arm/boot/dts/qcom/msm8996-sde-display.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-sde-display.dtsi
@@ -94,8 +94,8 @@
label = "dsi_dual_sharp_video";
qcom,display-type = "primary";
- qcom,dsi-ctrl = <&mdss_dsi0 &mdss_dsi1>;
- qcom,dsi-phy = <&mdss_dsi_phy0 &mdss_dsi_phy1>;
+ qcom,dsi-ctrl = <&sde_dsi0 &sde_dsi1>;
+ qcom,dsi-phy = <&sde_dsi_phy0 &sde_dsi_phy1>;
clocks = <&clock_mmss clk_ext_byte0_clk_src>,
<&clock_mmss clk_ext_pclk0_clk_src>;
clock-names = "src_byte_clk", "src_pixel_clk";
@@ -118,8 +118,8 @@
label = "single_dsi_sim";
qcom,display-type = "primary";
- qcom,dsi-ctrl = <&mdss_dsi0>;
- qcom,dsi-phy = <&mdss_dsi_phy0>;
+ qcom,dsi-ctrl = <&sde_dsi0>;
+ qcom,dsi-phy = <&sde_dsi_phy0>;
clocks = <&clock_mmss clk_ext_byte0_clk_src>,
<&clock_mmss clk_ext_pclk0_clk_src>;
clock-names = "src_byte_clk", "src_pixel_clk";
@@ -140,8 +140,8 @@
label = "single_dsi_toshiba_720p";
qcom,display-type = "primary";
- qcom,dsi-ctrl = <&mdss_dsi0>;
- qcom,dsi-phy = <&mdss_dsi_phy0>;
+ qcom,dsi-ctrl = <&sde_dsi0>;
+ qcom,dsi-phy = <&sde_dsi_phy0>;
clocks = <&clock_mmss clk_ext_byte0_clk_src>,
<&clock_mmss clk_ext_pclk0_clk_src>;
clock-names = "src_byte_clk", "src_pixel_clk";
@@ -161,8 +161,8 @@
label = "single_dsi_jdi_1080p";
qcom,display-type = "primary";
- qcom,dsi-ctrl = <&mdss_dsi0>;
- qcom,dsi-phy = <&mdss_dsi_phy0>;
+ qcom,dsi-ctrl = <&sde_dsi0>;
+ qcom,dsi-phy = <&sde_dsi_phy0>;
clocks = <&clock_mmss clk_ext_byte0_clk_src>,
<&clock_mmss clk_ext_pclk0_clk_src>;
clock-names = "src_byte_clk", "src_pixel_clk";
@@ -180,8 +180,8 @@
label = "single_dsi_sharp_1080p";
qcom,display-type = "primary";
- qcom,dsi-ctrl = <&mdss_dsi0>;
- qcom,dsi-phy = <&mdss_dsi_phy0>;
+ qcom,dsi-ctrl = <&sde_dsi0>;
+ qcom,dsi-phy = <&sde_dsi_phy0>;
clocks = <&clock_mmss clk_ext_byte0_clk_src>,
<&clock_mmss clk_ext_pclk0_clk_src>;
clock-names = "src_byte_clk", "src_pixel_clk";
@@ -209,8 +209,8 @@
qcom,display-type = "primary";
/* dsi1/dsi0 swapped due to IMGSWAP */
- qcom,dsi-ctrl = <&mdss_dsi1 &mdss_dsi0>;
- qcom,dsi-phy = <&mdss_dsi_phy0 &mdss_dsi_phy1>;
+ qcom,dsi-ctrl = <&sde_dsi1 &sde_dsi0>;
+ qcom,dsi-phy = <&sde_dsi_phy0 &sde_dsi_phy1>;
clocks = <&clock_mmss clk_ext_byte0_clk_src>,
<&clock_mmss clk_ext_pclk0_clk_src>;
clock-names = "src_byte_clk", "src_pixel_clk";
@@ -231,8 +231,8 @@
label = "dsi_dual_nt35597_video";
qcom,display-type = "primary";
- qcom,dsi-ctrl = <&mdss_dsi0 &mdss_dsi1>;
- qcom,dsi-phy = <&mdss_dsi_phy0 &mdss_dsi_phy1>;
+ qcom,dsi-ctrl = <&sde_dsi0 &sde_dsi1>;
+ qcom,dsi-phy = <&sde_dsi_phy0 &sde_dsi_phy1>;
clocks = <&clock_mmss clk_ext_byte0_clk_src>,
<&clock_mmss clk_ext_pclk0_clk_src>;
clock-names = "src_byte_clk", "src_pixel_clk";
@@ -253,8 +253,8 @@
label = "dsi_adv_7533_1";
qcom,display-type = "secondary";
- qcom,dsi-ctrl = <&mdss_dsi0>;
- qcom,dsi-phy = <&mdss_dsi_phy0>;
+ qcom,dsi-ctrl = <&sde_dsi0>;
+ qcom,dsi-phy = <&sde_dsi_phy0>;
clocks = <&clock_mmss clk_ext_byte0_clk_src>,
<&clock_mmss clk_ext_pclk0_clk_src>;
clock-names = "src_byte_clk", "src_pixel_clk";
@@ -269,8 +269,8 @@
label = "dsi_adv_7533_2";
qcom,display-type = "tertiary";
- qcom,dsi-ctrl = <&mdss_dsi1>;
- qcom,dsi-phy = <&mdss_dsi_phy1>;
+ qcom,dsi-ctrl = <&sde_dsi1>;
+ qcom,dsi-phy = <&sde_dsi_phy1>;
clocks = <&clock_mmss clk_ext_byte1_clk_src>,
<&clock_mmss clk_ext_pclk1_clk_src>;
clock-names = "src_byte_clk", "src_pixel_clk";
@@ -297,8 +297,8 @@
};
};
-&mdss_mdp {
- connectors = <&mdss_hdmi &sde_hdmi &dsi_adv_7533_1 &dsi_adv_7533_2>;
+&sde_kms {
+ connectors = <&sde_hdmi_tx &sde_hdmi &dsi_adv_7533_1 &dsi_adv_7533_2>;
};
&dsi_dual_sharp_video {
diff --git a/arch/arm/boot/dts/qcom/msm8996-sde.dtsi b/arch/arm/boot/dts/qcom/msm8996-sde.dtsi
index f0fa5dcb2224..6d0e5c4cb920 100644
--- a/arch/arm/boot/dts/qcom/msm8996-sde.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-sde.dtsi
@@ -11,7 +11,7 @@
*/
&soc {
- mdss_mdp: qcom,mdss_mdp@900000 {
+ sde_kms: qcom,sde_kms@900000 {
compatible = "qcom,sde-kms";
reg = <0x00900000 0x90000>,
<0x009b0000 0x1040>,
@@ -180,8 +180,8 @@
};
};
- smmu_mdp_unsec: qcom,smmu_mdp_unsec_cb {
- compatible = "qcom,smmu_mdp_unsec";
+ smmu_kms_unsec: qcom,smmu_kms_unsec_cb {
+ compatible = "qcom,smmu_kms_unsec";
iommus = <&mdp_smmu 0>;
};
@@ -211,7 +211,7 @@
};
};
- mdss_dsi0: qcom,mdss_dsi_ctrl0@994000 {
+ sde_dsi0: qcom,sde_dsi_ctrl0@994000 {
compatible = "qcom,dsi-ctrl-hw-v1.4";
label = "dsi-ctrl-0";
cell-index = <0>;
@@ -246,7 +246,7 @@
<22 512 0 0>,
<22 512 0 1000>;
- interrupt-parent = <&mdss_mdp>;
+ interrupt-parent = <&sde_kms>;
interrupts = <4 0>;
qcom,core-supply-entries {
#address-cells = <1>;
@@ -287,7 +287,7 @@
};
};
- mdss_dsi1: qcom,mdss_dsi_ctrl1@996000 {
+ sde_dsi1: qcom,sde_dsi_ctrl1@996000 {
compatible = "qcom,dsi-ctrl-hw-v1.4";
label = "dsi-ctrl-1";
cell-index = <1>;
@@ -321,7 +321,7 @@
<22 512 0 0>,
<22 512 0 1000>;
- interrupt-parent = <&mdss_mdp>;
+ interrupt-parent = <&sde_kms>;
interrupts = <5 0>;
qcom,core-supply-entries {
#address-cells = <1>;
@@ -361,7 +361,7 @@
};
};
- mdss_dsi_phy0: qcom,mdss_dsi_phy0@994400 {
+ sde_dsi_phy0: qcom,sde_dsi_phy0@994400 {
compatible = "qcom,dsi-phy-v4.0";
label = "dsi-phy-0";
cell-index = <0>;
@@ -420,7 +420,7 @@
};
};
- mdss_dsi_phy1: qcom,mdss_dsi_phy1@996400 {
+ sde_dsi_phy1: qcom,sde_dsi_phy1@996400 {
compatible = "qcom,dsi-phy-v4.0";
label = "dsi-phy-1";
cell-index = <1>;
@@ -479,7 +479,7 @@
};
};
- mdss_hdmi: qcom,hdmi_tx@9a0000 {
+ sde_hdmi_tx: qcom,hdmi_tx_8996@9a0000 {
compatible = "qcom,hdmi-tx-8996";
reg = <0x009a0000 0x50c>,
@@ -499,7 +499,7 @@
"core_clk",
"alt_iface_clk",
"extp_clk";
- interrupt-parent = <&mdss_mdp>;
+ interrupt-parent = <&sde_kms>;
interrupts = <8 0>;
hpd-gdsc-supply = <&gdsc_mdss>;
qcom,hdmi-tx-hpd-gpio = <&pm8994_mpps 4 0>;
@@ -511,23 +511,8 @@
&mdss_hdmi_ddc_suspend
&mdss_hdmi_cec_suspend>;
- hdmi_audio: qcom,msm-hdmi-audio-rx {
+ sde_hdmi_audio: qcom,sde-hdmi-audio-rx {
compatible = "qcom,msm-hdmi-audio-codec-rx";
};
};
};
-
-/* dummy nodes for compatibility with 8996 mdss dtsi */
-&soc {
- mdss_dsi: qcom,mdss_dsi_dummy {
- /* dummy node for backward compatibility */
- };
-
- mdss_hdmi_tx: qcom,mdss_hdmi_tx_dummy {
- /* dummy node for backward compatibility */
- };
-
- mdss_fb2: qcom,mdss_fb2_dummy {
- /* dummy node for backward compatibility */
- };
-};
diff --git a/arch/arm/boot/dts/qcom/msm8996-v2.dtsi b/arch/arm/boot/dts/qcom/msm8996-v2.dtsi
index 9725bc3ee530..698c0193a164 100644
--- a/arch/arm/boot/dts/qcom/msm8996-v2.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-v2.dtsi
@@ -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
@@ -480,7 +480,7 @@
gdsc-venus-supply = <&gdsc_venus>;
};
-&mdss_hdmi {
+&sde_hdmi_tx {
hpd-gdsc-venus-supply = <&gdsc_venus>;
};
diff --git a/arch/arm/boot/dts/qcom/msm8996.dtsi b/arch/arm/boot/dts/qcom/msm8996.dtsi
index 80b3437beac6..dcd884b4a745 100644
--- a/arch/arm/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996.dtsi
@@ -242,6 +242,7 @@
#include "msm8996-ion.dtsi"
#include "msm8996-sde.dtsi"
+#include "msm8996-mdss.dtsi"
#include "msm8996-mdss-pll.dtsi"
#include "msm8996-smp2p.dtsi"
#include "msm8996-ipcrouter.dtsi"
diff --git a/arch/arm/boot/dts/qcom/msm8996v3-auto.dtsi b/arch/arm/boot/dts/qcom/msm8996v3-auto.dtsi
index 32adb9a36dd4..355062adf7ef 100644
--- a/arch/arm/boot/dts/qcom/msm8996v3-auto.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996v3-auto.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
@@ -167,3 +167,40 @@
< 560000000 7 >,
< 624000000 7 >;
};
+
+&soc {
+ ipa_hw: qcom,ipa@680000 {
+ compatible = "qcom,ipa";
+ reg = <0x680000 0x4effc>,
+ <0x684000 0x26934>;
+ reg-names = "ipa-base", "bam-base";
+ interrupts = <0 333 0>,
+ <0 432 0>;
+ interrupt-names = "ipa-irq", "bam-irq";
+ qcom,ipa-hw-ver = <5>; /* IPA core version = IPAv2.5 */
+ qcom,ipa-hw-mode = <0>;
+ qcom,ee = <0>;
+ qcom,use-ipa-tethering-bridge;
+ qcom,ipa-bam-remote-mode;
+ qcom,modem-cfg-emb-pipe-flt;
+ clocks = <&clock_gcc clk_ipa_clk>;
+ clock-names = "core_clk";
+ qcom,use-dma-zone;
+ qcom,msm-bus,name = "ipa";
+ qcom,msm-bus,num-cases = <3>;
+ qcom,msm-bus,num-paths = <2>;
+ qcom,msm-bus,vectors-KBps =
+ <90 512 0 0>, <90 585 0 0>, /* No vote */
+ <90 512 80000 640000>, <90 585 80000 640000>, /* SVS */
+ <90 512 206000 960000>, <90 585 206000 960000>; /* PERF */
+ qcom,bus-vector-names = "MIN", "SVS", "PERF";
+ };
+
+ qcom,rmnet-ipa {
+ compatible = "qcom,rmnet-ipa";
+ qcom,rmnet-ipa-ssr;
+ qcom,ipa-loaduC;
+ qcom,ipa-advertise-sg-support;
+ };
+};
+
diff --git a/arch/arm/boot/dts/qcom/sdm630.dtsi b/arch/arm/boot/dts/qcom/sdm630.dtsi
index 8ca0b94403cb..cff3aa809488 100644
--- a/arch/arm/boot/dts/qcom/sdm630.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm630.dtsi
@@ -1689,6 +1689,7 @@
qcom,vdd-1.3-rfa-config = <1200000 1370000>;
qcom,vdd-3.3-ch0-config = <3200000 3400000>;
qcom,wlan-msa-memory = <0x100000>;
+ qcom,wlan-msa-fixed-region = <&wlan_msa_mem>;
qcom,smmu-s1-bypass;
};
diff --git a/arch/arm/boot/dts/qcom/sdm660.dtsi b/arch/arm/boot/dts/qcom/sdm660.dtsi
index 8158825264c2..f14c9a32c2f9 100644
--- a/arch/arm/boot/dts/qcom/sdm660.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660.dtsi
@@ -1940,6 +1940,7 @@
qcom,vdd-1.3-rfa-config = <1200000 1370000>;
qcom,vdd-3.3-ch0-config = <3200000 3400000>;
qcom,wlan-msa-memory = <0x100000>;
+ qcom,wlan-msa-fixed-region = <&wlan_msa_mem>;
qcom,smmu-s1-bypass;
};
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 13016f32b344..a84172106e0f 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -212,6 +212,7 @@ struct fastrpc_channel_ctx {
struct device *dev;
struct fastrpc_session_ctx session[NUM_SESSIONS];
struct completion work;
+ struct completion workport;
struct notifier_block nb;
struct kref kref;
int channel;
@@ -1474,6 +1475,7 @@ static void fastrpc_init(struct fastrpc_apps *me)
me->channel = &gcinfo[0];
for (i = 0; i < NUM_CHANNELS; i++) {
init_completion(&me->channel[i].work);
+ init_completion(&me->channel[i].workport);
me->channel[i].sesscount = 0;
}
}
@@ -2135,7 +2137,7 @@ void fastrpc_glink_notify_state(void *handle, const void *priv, unsigned event)
switch (event) {
case GLINK_CONNECTED:
link->port_state = FASTRPC_LINK_CONNECTED;
- complete(&me->channel[cid].work);
+ complete(&me->channel[cid].workport);
break;
case GLINK_LOCAL_DISCONNECTED:
link->port_state = FASTRPC_LINK_DISCONNECTED;
@@ -2285,8 +2287,7 @@ static void fastrpc_glink_close(void *chan, int cid)
return;
link = &gfa.channel[cid].link;
- if (link->port_state == FASTRPC_LINK_CONNECTED ||
- link->port_state == FASTRPC_LINK_CONNECTING) {
+ if (link->port_state == FASTRPC_LINK_CONNECTED) {
link->port_state = FASTRPC_LINK_DISCONNECTING;
glink_close(chan);
}
@@ -2484,8 +2485,9 @@ static int fastrpc_channel_open(struct fastrpc_file *fl)
if (err)
goto bail;
- VERIFY(err, wait_for_completion_timeout(&me->channel[cid].work,
- RPC_TIMEOUT));
+ VERIFY(err,
+ wait_for_completion_timeout(&me->channel[cid].workport,
+ RPC_TIMEOUT));
if (err) {
me->channel[cid].chan = 0;
goto bail;
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index 20e617ed0770..e37609abf7bf 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -796,7 +796,9 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
for (i = 0; i < NUM_PERIPHERALS; i++) {
if (!diag_check_update(i))
continue;
+ mutex_lock(&driver->md_session_lock);
diag_send_msg_mask_update(i, req->ssid_first, req->ssid_last);
+ mutex_unlock(&driver->md_session_lock);
}
end:
return write_len;
@@ -856,7 +858,9 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
for (i = 0; i < NUM_PERIPHERALS; i++) {
if (!diag_check_update(i))
continue;
+ mutex_lock(&driver->md_session_lock);
diag_send_msg_mask_update(i, ALL_SSID, ALL_SSID);
+ mutex_unlock(&driver->md_session_lock);
}
return write_len;
@@ -950,7 +954,9 @@ static int diag_cmd_update_event_mask(unsigned char *src_buf, int src_len,
for (i = 0; i < NUM_PERIPHERALS; i++) {
if (!diag_check_update(i))
continue;
+ mutex_lock(&driver->md_session_lock);
diag_send_event_mask_update(i);
+ mutex_unlock(&driver->md_session_lock);
}
return write_len;
@@ -997,7 +1003,9 @@ static int diag_cmd_toggle_events(unsigned char *src_buf, int src_len,
for (i = 0; i < NUM_PERIPHERALS; i++) {
if (!diag_check_update(i))
continue;
+ mutex_lock(&driver->md_session_lock);
diag_send_event_mask_update(i);
+ mutex_unlock(&driver->md_session_lock);
}
memcpy(dest_buf, &header, sizeof(header));
write_len += sizeof(header);
@@ -1251,7 +1259,9 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
for (i = 0; i < NUM_PERIPHERALS; i++) {
if (!diag_check_update(i))
continue;
+ mutex_lock(&driver->md_session_lock);
diag_send_log_mask_update(i, req->equip_id);
+ mutex_unlock(&driver->md_session_lock);
}
end:
return write_len;
@@ -1302,7 +1312,9 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len,
for (i = 0; i < NUM_PERIPHERALS; i++) {
if (!diag_check_update(i))
continue;
+ mutex_lock(&driver->md_session_lock);
diag_send_log_mask_update(i, ALL_EQUIP_ID);
+ mutex_unlock(&driver->md_session_lock);
}
return write_len;
@@ -1966,9 +1978,11 @@ void diag_send_updates_peripheral(uint8_t peripheral)
diag_send_feature_mask_update(peripheral);
if (driver->time_sync_enabled)
diag_send_time_sync_update(peripheral);
+ mutex_lock(&driver->md_session_lock);
diag_send_msg_mask_update(peripheral, ALL_SSID, ALL_SSID);
diag_send_log_mask_update(peripheral, ALL_EQUIP_ID);
diag_send_event_mask_update(peripheral);
+ mutex_unlock(&driver->md_session_lock);
diag_send_real_time_update(peripheral,
driver->real_time_mode[DIAG_LOCAL_PROC]);
diag_send_peripheral_buffering_mode(
diff --git a/drivers/char/diag/diag_memorydevice.c b/drivers/char/diag/diag_memorydevice.c
index 06b83f5230bf..a27f12883c8d 100644
--- a/drivers/char/diag/diag_memorydevice.c
+++ b/drivers/char/diag/diag_memorydevice.c
@@ -129,37 +129,6 @@ void diag_md_close_all()
diag_ws_reset(DIAG_WS_MUX);
}
-static int diag_md_get_peripheral(int ctxt)
-{
- int peripheral;
-
- if (driver->num_pd_session) {
- peripheral = GET_PD_CTXT(ctxt);
- switch (peripheral) {
- case UPD_WLAN:
- case UPD_AUDIO:
- case UPD_SENSORS:
- break;
- case DIAG_ID_MPSS:
- case DIAG_ID_LPASS:
- case DIAG_ID_CDSP:
- default:
- peripheral =
- GET_BUF_PERIPHERAL(ctxt);
- if (peripheral > NUM_PERIPHERALS)
- peripheral = -EINVAL;
- break;
- }
- } else {
- /* Account for Apps data as well */
- peripheral = GET_BUF_PERIPHERAL(ctxt);
- if (peripheral > NUM_PERIPHERALS)
- peripheral = -EINVAL;
- }
-
- return peripheral;
-}
-
int diag_md_write(int id, unsigned char *buf, int len, int ctx)
{
int i;
diff --git a/drivers/char/diag/diag_mux.c b/drivers/char/diag/diag_mux.c
index d6f6ea7af8ea..8cc803eef552 100644
--- a/drivers/char/diag/diag_mux.c
+++ b/drivers/char/diag/diag_mux.c
@@ -153,12 +153,15 @@ int diag_mux_write(int proc, unsigned char *buf, int len, int ctx)
upd = PERIPHERAL_CDSP;
break;
case UPD_WLAN:
- if (!driver->num_pd_session)
+ if (!driver->pd_logging_mode[0])
upd = PERIPHERAL_MODEM;
break;
case UPD_AUDIO:
+ if (!driver->pd_logging_mode[1])
+ upd = PERIPHERAL_LPASS;
+ break;
case UPD_SENSORS:
- if (!driver->num_pd_session)
+ if (!driver->pd_logging_mode[2])
upd = PERIPHERAL_LPASS;
break;
default:
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 5ae3e4defd0d..afaedc99a4e7 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -456,6 +456,7 @@ static void diag_close_logging_process(const int pid)
{
int i, j;
int session_mask;
+ uint32_t p_mask;
struct diag_md_session_t *session_info = NULL;
struct diag_logging_mode_param_t params;
@@ -475,6 +476,9 @@ static void diag_close_logging_process(const int pid)
session_mask = session_info->peripheral_mask;
diag_md_session_close(session_info);
+ p_mask =
+ diag_translate_kernel_to_user_mask(session_mask);
+
for (i = 0; i < NUM_MD_SESSIONS; i++)
if (MD_PERIPHERAL_MASK(i) & session_mask)
diag_mux_close_peripheral(DIAG_LOCAL_PROC, i);
@@ -482,19 +486,17 @@ static void diag_close_logging_process(const int pid)
params.req_mode = USB_MODE;
params.mode_param = 0;
params.pd_mask = 0;
- params.peripheral_mask =
- diag_translate_kernel_to_user_mask(session_mask);
+ params.peripheral_mask = p_mask;
if (driver->num_pd_session > 0) {
- for (i = UPD_WLAN; ((i < NUM_MD_SESSIONS) &&
- (session_mask & MD_PERIPHERAL_MASK(i)));
- i++) {
- j = i - UPD_WLAN;
- driver->pd_session_clear[j] = 1;
- driver->pd_logging_mode[j] = 0;
- driver->num_pd_session -= 1;
- params.pd_mask =
- diag_translate_kernel_to_user_mask(session_mask);
+ for (i = UPD_WLAN; (i < NUM_MD_SESSIONS); i++) {
+ if (session_mask & MD_PERIPHERAL_MASK(i)) {
+ j = i - UPD_WLAN;
+ driver->pd_session_clear[j] = 1;
+ driver->pd_logging_mode[j] = 0;
+ driver->num_pd_session -= 1;
+ params.pd_mask = p_mask;
+ }
}
}
diff --git a/drivers/char/diag/diagfwd_peripheral.c b/drivers/char/diag/diagfwd_peripheral.c
index e209039bed5a..9ac1ad62ffe0 100644
--- a/drivers/char/diag/diagfwd_peripheral.c
+++ b/drivers/char/diag/diagfwd_peripheral.c
@@ -216,6 +216,45 @@ static int check_bufsize_for_encoding(struct diagfwd_buf_t *buf, uint32_t len)
return buf->len;
}
+int diag_md_get_peripheral(int ctxt)
+{
+ int peripheral;
+
+ if (driver->num_pd_session) {
+ peripheral = GET_PD_CTXT(ctxt);
+ switch (peripheral) {
+ case UPD_WLAN:
+ if (!driver->pd_logging_mode[0])
+ peripheral = PERIPHERAL_MODEM;
+ break;
+ case UPD_AUDIO:
+ if (!driver->pd_logging_mode[1])
+ peripheral = PERIPHERAL_LPASS;
+ break;
+ case UPD_SENSORS:
+ if (!driver->pd_logging_mode[2])
+ peripheral = PERIPHERAL_LPASS;
+ break;
+ case DIAG_ID_MPSS:
+ case DIAG_ID_LPASS:
+ case DIAG_ID_CDSP:
+ default:
+ peripheral =
+ GET_BUF_PERIPHERAL(ctxt);
+ if (peripheral > NUM_PERIPHERALS)
+ peripheral = -EINVAL;
+ break;
+ }
+ } else {
+ /* Account for Apps data as well */
+ peripheral = GET_BUF_PERIPHERAL(ctxt);
+ if (peripheral > NUM_PERIPHERALS)
+ peripheral = -EINVAL;
+ }
+
+ return peripheral;
+}
+
static void diagfwd_data_process_done(struct diagfwd_info *fwd_info,
struct diagfwd_buf_t *buf, int len)
{
@@ -245,13 +284,15 @@ static void diagfwd_data_process_done(struct diagfwd_info *fwd_info,
mutex_lock(&driver->hdlc_disable_mutex);
mutex_lock(&fwd_info->data_mutex);
- peripheral = GET_PD_CTXT(buf->ctxt);
- if (peripheral == DIAG_ID_MPSS)
- peripheral = PERIPHERAL_MODEM;
- if (peripheral == DIAG_ID_LPASS)
- peripheral = PERIPHERAL_LPASS;
- if (peripheral == DIAG_ID_CDSP)
- peripheral = PERIPHERAL_CDSP;
+ peripheral = diag_md_get_peripheral(buf->ctxt);
+ if (peripheral < 0) {
+ pr_err("diag:%s:%d invalid peripheral = %d\n",
+ __func__, __LINE__, peripheral);
+ mutex_unlock(&fwd_info->data_mutex);
+ mutex_unlock(&driver->hdlc_disable_mutex);
+ diag_ws_release();
+ return;
+ }
session_info =
diag_md_session_get_peripheral(peripheral);
diff --git a/drivers/char/diag/diagfwd_peripheral.h b/drivers/char/diag/diagfwd_peripheral.h
index 037eeebdeb35..eda70dcfdcd9 100644
--- a/drivers/char/diag/diagfwd_peripheral.h
+++ b/drivers/char/diag/diagfwd_peripheral.h
@@ -105,6 +105,9 @@ void diagfwd_early_open(uint8_t peripheral);
void diagfwd_late_open(struct diagfwd_info *fwd_info);
void diagfwd_close(uint8_t peripheral, uint8_t type);
+
+int diag_md_get_peripheral(int ctxt);
+
int diagfwd_register(uint8_t transport, uint8_t peripheral, uint8_t type,
void *ctxt, struct diag_peripheral_ops *ops,
struct diagfwd_info **fwd_ctxt);
diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c
index 316d8b783d94..691c7bb3afac 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.c
+++ b/drivers/hwtracing/coresight/coresight-tmc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, 2016-2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012, 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
@@ -764,6 +764,16 @@ static int tmc_enable(struct tmc_drvdata *drvdata, enum tmc_mode mode)
pm_runtime_get_sync(drvdata->dev);
mutex_lock(&drvdata->mem_lock);
+
+ spin_lock_irqsave(&drvdata->spinlock, flags);
+ if (drvdata->reading) {
+ spin_unlock_irqrestore(&drvdata->spinlock, flags);
+ mutex_unlock(&drvdata->mem_lock);
+ pm_runtime_put(drvdata->dev);
+ return -EBUSY;
+ }
+ spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
if (drvdata->config_type == TMC_CONFIG_TYPE_ETR &&
drvdata->out_mode == TMC_ETR_OUT_MODE_MEM) {
/*
@@ -807,19 +817,8 @@ static int tmc_enable(struct tmc_drvdata *drvdata, enum tmc_mode mode)
coresight_cti_map_trigout(drvdata->cti_flush, 1, 0);
coresight_cti_map_trigin(drvdata->cti_reset, 2, 0);
}
- mutex_unlock(&drvdata->mem_lock);
spin_lock_irqsave(&drvdata->spinlock, flags);
- if (drvdata->reading) {
- spin_unlock_irqrestore(&drvdata->spinlock, flags);
-
- if (drvdata->config_type == TMC_CONFIG_TYPE_ETR
- && drvdata->out_mode == TMC_ETR_OUT_MODE_USB)
- usb_qdss_close(drvdata->usbch);
- pm_runtime_put(drvdata->dev);
-
- return -EBUSY;
- }
if (drvdata->config_type == TMC_CONFIG_TYPE_ETB) {
tmc_etb_enable_hw(drvdata);
@@ -845,6 +844,7 @@ static int tmc_enable(struct tmc_drvdata *drvdata, enum tmc_mode mode)
*/
drvdata->sticky_enable = true;
spin_unlock_irqrestore(&drvdata->spinlock, flags);
+ mutex_unlock(&drvdata->mem_lock);
dev_info(drvdata->dev, "TMC enabled\n");
return 0;
@@ -1140,6 +1140,7 @@ static int tmc_read_prepare(struct tmc_drvdata *drvdata)
unsigned long flags;
enum tmc_mode mode;
+ mutex_lock(&drvdata->mem_lock);
spin_lock_irqsave(&drvdata->spinlock, flags);
if (!drvdata->sticky_enable) {
dev_err(drvdata->dev, "enable tmc once before reading\n");
@@ -1172,11 +1173,13 @@ static int tmc_read_prepare(struct tmc_drvdata *drvdata)
out:
drvdata->reading = true;
spin_unlock_irqrestore(&drvdata->spinlock, flags);
+ mutex_unlock(&drvdata->mem_lock);
dev_info(drvdata->dev, "TMC read start\n");
return 0;
err:
spin_unlock_irqrestore(&drvdata->spinlock, flags);
+ mutex_unlock(&drvdata->mem_lock);
return ret;
}
@@ -1353,7 +1356,11 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
{
struct tmc_drvdata *drvdata = container_of(file->private_data,
struct tmc_drvdata, miscdev);
- char *bufp = drvdata->buf + *ppos;
+ char *bufp;
+
+ mutex_lock(&drvdata->mem_lock);
+
+ bufp = drvdata->buf + *ppos;
if (*ppos + len > drvdata->size)
len = drvdata->size - *ppos;
@@ -1375,6 +1382,7 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
if (copy_to_user(data, bufp, len)) {
dev_dbg(drvdata->dev, "%s: copy_to_user failed\n", __func__);
+ mutex_unlock(&drvdata->mem_lock);
return -EFAULT;
}
@@ -1382,6 +1390,8 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
dev_dbg(drvdata->dev, "%s: %zu bytes copied, %d bytes left\n",
__func__, len, (int)(drvdata->size - *ppos));
+
+ mutex_unlock(&drvdata->mem_lock);
return len;
}
diff --git a/drivers/media/platform/msm/ais/sensor/flash/msm_flash.c b/drivers/media/platform/msm/ais/sensor/flash/msm_flash.c
index 6af589e5c230..a2a89b92c9f1 100644
--- a/drivers/media/platform/msm/ais/sensor/flash/msm_flash.c
+++ b/drivers/media/platform/msm/ais/sensor/flash/msm_flash.c
@@ -1022,13 +1022,13 @@ static long msm_flash_subdev_do_ioctl(
sd = vdev_to_v4l2_subdev(vdev);
u32 = (struct msm_flash_cfg_data_t32 *)arg;
- flash_data.cfg_type = u32->cfg_type;
- for (i = 0; i < MAX_LED_TRIGGERS; i++) {
- flash_data.flash_current[i] = u32->flash_current[i];
- flash_data.flash_duration[i] = u32->flash_duration[i];
- }
switch (cmd) {
case VIDIOC_MSM_FLASH_CFG32:
+ flash_data.cfg_type = u32->cfg_type;
+ for (i = 0; i < MAX_LED_TRIGGERS; i++) {
+ flash_data.flash_current[i] = u32->flash_current[i];
+ flash_data.flash_duration[i] = u32->flash_duration[i];
+ }
cmd = VIDIOC_MSM_FLASH_CFG;
switch (flash_data.cfg_type) {
case CFG_FLASH_OFF:
diff --git a/drivers/media/platform/msm/ais/sensor/ois/msm_ois.c b/drivers/media/platform/msm/ais/sensor/ois/msm_ois.c
index 28a5402a4359..236660dca3fb 100644
--- a/drivers/media/platform/msm/ais/sensor/ois/msm_ois.c
+++ b/drivers/media/platform/msm/ais/sensor/ois/msm_ois.c
@@ -781,11 +781,10 @@ static long msm_ois_subdev_do_ioctl(
u32 = (struct msm_ois_cfg_data32 *)arg;
parg = arg;
- ois_data.cfgtype = u32->cfgtype;
-
switch (cmd) {
case VIDIOC_MSM_OIS_CFG32:
cmd = VIDIOC_MSM_OIS_CFG;
+ ois_data.cfgtype = u32->cfgtype;
switch (u32->cfgtype) {
case CFG_OIS_CONTROL:
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
index acb697946e18..10f72a2155db 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
@@ -814,6 +814,9 @@ static void sde_hw_rotator_setup_wbengine(struct sde_hw_rotator_context *ctx,
bw /= TRAFFIC_SHAPE_CLKTICK_12MS;
if (bw > 0xFF)
bw = 0xFF;
+ else if (bw == 0)
+ bw = 1;
+
SDE_REGDMA_WRITE(wrptr, ROT_WB_TRAFFIC_SHAPER_WR_CLIENT,
BIT(31) | bw);
SDEROT_DBG("Enable ROT_WB Traffic Shaper:%d\n", bw);
diff --git a/drivers/platform/msm/Kconfig b/drivers/platform/msm/Kconfig
index 66bdc593f811..333d28e64087 100644
--- a/drivers/platform/msm/Kconfig
+++ b/drivers/platform/msm/Kconfig
@@ -194,7 +194,7 @@ config MSM_11AD
tristate "Platform driver for 11ad chip"
depends on PCI
depends on PCI_MSM
- default y
+ default m
---help---
This module adds required platform support for wireless adapter based on
Qualcomm Technologies, Inc. 11ad chip, integrated into MSM platform
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
index 80514f6c738e..b7f451b7c6fd 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
@@ -1027,7 +1027,7 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
goto error;
}
- if (rt_tbl->cookie != IPA_COOKIE) {
+ if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
IPAERR("RT table cookie is invalid\n");
goto error;
}
@@ -1048,7 +1048,7 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
}
INIT_LIST_HEAD(&entry->link);
entry->rule = *rule;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_FLT_COOKIE;
entry->rt_tbl = rt_tbl;
entry->tbl = tbl;
if (add_rear) {
@@ -1067,13 +1067,19 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
if (id < 0) {
IPAERR("failed to add to tree\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
*rule_hdl = id;
entry->id = id;
IPADBG_LOW("add flt rule rule_cnt=%d\n", tbl->rule_cnt);
return 0;
-
+ipa_insert_failed:
+ tbl->rule_cnt--;
+ if (entry->rt_tbl)
+ entry->rt_tbl->ref_cnt--;
+ list_del(&entry->link);
+ kmem_cache_free(ipa_ctx->flt_rule_cache, entry);
error:
return -EPERM;
}
@@ -1089,7 +1095,7 @@ static int __ipa_del_flt_rule(u32 rule_hdl)
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_FLT_COOKIE) {
IPAERR("bad params\n");
return -EINVAL;
}
@@ -1121,7 +1127,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
goto error;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_FLT_COOKIE) {
IPAERR("bad params\n");
goto error;
}
@@ -1142,7 +1148,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
goto error;
}
- if (rt_tbl->cookie != IPA_COOKIE) {
+ if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
IPAERR("RT table cookie is invalid\n");
goto error;
}
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c
index 10a49b1e75d8..75e4ff5c3c57 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_hdr.c
@@ -547,7 +547,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
{
struct ipa_hdr_entry *hdr_entry;
struct ipa_hdr_proc_ctx_entry *entry;
- struct ipa_hdr_proc_ctx_offset_entry *offset;
+ struct ipa_hdr_proc_ctx_offset_entry *offset = NULL;
u32 bin;
struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl;
int id;
@@ -563,7 +563,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
}
hdr_entry = ipa_id_find(proc_ctx->hdr_hdl);
- if (!hdr_entry || (hdr_entry->cookie != IPA_COOKIE)) {
+ if (!hdr_entry || (hdr_entry->cookie != IPA_HDR_COOKIE)) {
IPAERR("hdr_hdl is invalid\n");
return -EINVAL;
}
@@ -580,7 +580,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
entry->hdr = hdr_entry;
if (add_ref_hdr)
hdr_entry->ref_cnt++;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_PROC_HDR_COOKIE;
needed_len = (proc_ctx->type == IPA_HDR_PROC_NONE) ?
sizeof(struct ipa_hdr_proc_ctx_add_hdr_seq) :
@@ -640,6 +640,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
if (id < 0) {
IPAERR("failed to alloc id\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
proc_ctx->proc_ctx_hdl = id;
@@ -647,6 +648,14 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
return 0;
+ipa_insert_failed:
+ if (offset)
+ list_move(&offset->link,
+ &htbl->head_free_offset_list[offset->bin]);
+ entry->offset_entry = NULL;
+ list_del(&entry->link);
+ htbl->proc_ctx_cnt--;
+
bad_len:
if (add_ref_hdr)
hdr_entry->ref_cnt--;
@@ -659,7 +668,7 @@ bad_len:
static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
{
struct ipa_hdr_entry *entry;
- struct ipa_hdr_offset_entry *offset;
+ struct ipa_hdr_offset_entry *offset = NULL;
u32 bin;
struct ipa_hdr_tbl *htbl = &ipa_ctx->hdr_tbl;
int id;
@@ -691,7 +700,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
entry->type = hdr->type;
entry->is_eth2_ofst_valid = hdr->is_eth2_ofst_valid;
entry->eth2_ofst = hdr->eth2_ofst;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_HDR_COOKIE;
if (hdr->hdr_len <= ipa_hdr_bin_sz[IPA_HDR_BIN0])
bin = IPA_HDR_BIN0;
@@ -780,6 +789,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
if (id < 0) {
IPAERR("failed to alloc id\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
hdr->hdr_hdl = id;
@@ -804,10 +814,19 @@ fail_add_proc_ctx:
entry->ref_cnt--;
hdr->hdr_hdl = 0;
ipa_id_remove(id);
+ipa_insert_failed:
+ if (entry->is_hdr_proc_ctx) {
+ dma_unmap_single(ipa_ctx->pdev, entry->phys_base,
+ entry->hdr_len, DMA_TO_DEVICE);
+ } else {
+ if (offset)
+ list_move(&offset->link,
+ &htbl->head_free_offset_list[offset->bin]);
+ entry->offset_entry = NULL;
+ }
htbl->hdr_cnt--;
list_del(&entry->link);
- dma_unmap_single(ipa_ctx->pdev, entry->phys_base,
- entry->hdr_len, DMA_TO_DEVICE);
+
fail_dma_mapping:
entry->is_hdr_proc_ctx = false;
bad_hdr_len:
@@ -824,7 +843,7 @@ static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl,
struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl;
entry = ipa_id_find(proc_ctx_hdl);
- if (!entry || (entry->cookie != IPA_COOKIE)) {
+ if (!entry || (entry->cookie != IPA_PROC_HDR_COOKIE)) {
IPAERR("bad parm\n");
return -EINVAL;
}
@@ -875,7 +894,7 @@ int __ipa_del_hdr(u32 hdr_hdl, bool by_user)
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_HDR_COOKIE) {
IPAERR("bad parm\n");
return -EINVAL;
}
@@ -1444,7 +1463,7 @@ int ipa2_put_hdr(u32 hdr_hdl)
goto bail;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_HDR_COOKIE) {
IPAERR("invalid header entry\n");
result = -EINVAL;
goto bail;
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h
index bb11230c960a..70b2a2eeb53f 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h
@@ -37,7 +37,15 @@
#define DRV_NAME "ipa"
#define NAT_DEV_NAME "ipaNatTable"
+
#define IPA_COOKIE 0x57831603
+#define IPA_RT_RULE_COOKIE 0x57831604
+#define IPA_RT_TBL_COOKIE 0x57831605
+#define IPA_FLT_COOKIE 0x57831606
+#define IPA_HDR_COOKIE 0x57831607
+#define IPA_PROC_HDR_COOKIE 0x57831608
+
+
#define MTU_BYTE 1500
#define IPA_MAX_NUM_PIPES 0x14
@@ -223,8 +231,8 @@ struct ipa_smmu_cb_ctx {
*/
struct ipa_flt_entry {
struct list_head link;
- struct ipa_flt_rule rule;
u32 cookie;
+ struct ipa_flt_rule rule;
struct ipa_flt_tbl *tbl;
struct ipa_rt_tbl *rt_tbl;
u32 hw_len;
@@ -249,13 +257,13 @@ struct ipa_flt_entry {
*/
struct ipa_rt_tbl {
struct list_head link;
+ u32 cookie;
struct list_head head_rt_rule_list;
char name[IPA_RESOURCE_NAME_MAX];
u32 idx;
u32 rule_cnt;
u32 ref_cnt;
struct ipa_rt_tbl_set *set;
- u32 cookie;
bool in_sys;
u32 sz;
struct ipa_mem_buffer curr_mem;
@@ -286,6 +294,7 @@ struct ipa_rt_tbl {
*/
struct ipa_hdr_entry {
struct list_head link;
+ u32 cookie;
u8 hdr[IPA_HDR_MAX_SIZE];
u32 hdr_len;
char name[IPA_RESOURCE_NAME_MAX];
@@ -295,7 +304,6 @@ struct ipa_hdr_entry {
dma_addr_t phys_base;
struct ipa_hdr_proc_ctx_entry *proc_ctx;
struct ipa_hdr_offset_entry *offset_entry;
- u32 cookie;
u32 ref_cnt;
int id;
u8 is_eth2_ofst_valid;
@@ -368,10 +376,10 @@ struct ipa_hdr_proc_ctx_add_hdr_cmd_seq {
*/
struct ipa_hdr_proc_ctx_entry {
struct list_head link;
+ u32 cookie;
enum ipa_hdr_proc_type type;
struct ipa_hdr_proc_ctx_offset_entry *offset_entry;
struct ipa_hdr_entry *hdr;
- u32 cookie;
u32 ref_cnt;
int id;
bool user_deleted;
@@ -427,8 +435,8 @@ struct ipa_flt_tbl {
*/
struct ipa_rt_entry {
struct list_head link;
- struct ipa_rt_rule rule;
u32 cookie;
+ struct ipa_rt_rule rule;
struct ipa_rt_tbl *tbl;
struct ipa_hdr_entry *hdr;
struct ipa_hdr_proc_ctx_entry *proc_ctx;
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
index f2909110d09f..9ac7b3809895 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
@@ -909,7 +909,7 @@ static struct ipa_rt_tbl *__ipa_add_rt_tbl(enum ipa_ip_type ip,
INIT_LIST_HEAD(&entry->link);
strlcpy(entry->name, name, IPA_RESOURCE_NAME_MAX);
entry->set = set;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_RT_TBL_COOKIE;
entry->in_sys = (ip == IPA_IP_v4) ?
!ipa_ctx->ip4_rt_tbl_lcl : !ipa_ctx->ip6_rt_tbl_lcl;
set->tbl_cnt++;
@@ -922,12 +922,16 @@ static struct ipa_rt_tbl *__ipa_add_rt_tbl(enum ipa_ip_type ip,
if (id < 0) {
IPAERR("failed to add to tree\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
}
return entry;
+ipa_insert_failed:
+ set->tbl_cnt--;
+ list_del(&entry->link);
fail_rt_idx_alloc:
entry->cookie = 0;
kmem_cache_free(ipa_ctx->rt_tbl_cache, entry);
@@ -940,7 +944,7 @@ static int __ipa_del_rt_tbl(struct ipa_rt_tbl *entry)
enum ipa_ip_type ip = IPA_IP_MAX;
u32 id;
- if (entry == NULL || (entry->cookie != IPA_COOKIE)) {
+ if (entry == NULL || (entry->cookie != IPA_RT_TBL_COOKIE)) {
IPAERR("bad parms\n");
return -EINVAL;
}
@@ -954,8 +958,11 @@ static int __ipa_del_rt_tbl(struct ipa_rt_tbl *entry)
ip = IPA_IP_v4;
else if (entry->set == &ipa_ctx->rt_tbl_set[IPA_IP_v6])
ip = IPA_IP_v6;
- else
+ else {
WARN_ON(1);
+ return -EPERM;
+ }
+
if (!entry->in_sys) {
list_del(&entry->link);
@@ -994,13 +1001,14 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
if (rule->hdr_hdl) {
hdr = ipa_id_find(rule->hdr_hdl);
- if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
+ if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid hdr\n");
goto error;
}
} else if (rule->hdr_proc_ctx_hdl) {
proc_ctx = ipa_id_find(rule->hdr_proc_ctx_hdl);
- if ((proc_ctx == NULL) || (proc_ctx->cookie != IPA_COOKIE)) {
+ if ((proc_ctx == NULL) ||
+ (proc_ctx->cookie != IPA_PROC_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid proc ctx\n");
goto error;
}
@@ -1008,7 +1016,7 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
tbl = __ipa_add_rt_tbl(ip, name);
- if (tbl == NULL || (tbl->cookie != IPA_COOKIE)) {
+ if (tbl == NULL || (tbl->cookie != IPA_RT_TBL_COOKIE)) {
IPAERR("bad params\n");
goto error;
}
@@ -1029,7 +1037,7 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
goto error;
}
INIT_LIST_HEAD(&entry->link);
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_RT_RULE_COOKIE;
entry->rule = *rule;
entry->tbl = tbl;
entry->hdr = hdr;
@@ -1123,7 +1131,7 @@ int __ipa_del_rt_rule(u32 rule_hdl)
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_RT_RULE_COOKIE) {
IPAERR("bad params\n");
return -EINVAL;
}
@@ -1358,7 +1366,7 @@ int ipa2_get_rt_tbl(struct ipa_ioc_get_rt_tbl *lookup)
}
mutex_lock(&ipa_ctx->lock);
entry = __ipa_find_rt_tbl(lookup->ip, lookup->name);
- if (entry && entry->cookie == IPA_COOKIE) {
+ if (entry && entry->cookie == IPA_RT_TBL_COOKIE) {
if (entry->ref_cnt == U32_MAX) {
IPAERR("fail: ref count crossed limit\n");
goto ret;
@@ -1401,7 +1409,7 @@ int ipa2_put_rt_tbl(u32 rt_tbl_hdl)
goto ret;
}
- if ((entry->cookie != IPA_COOKIE) || entry->ref_cnt == 0) {
+ if ((entry->cookie != IPA_RT_TBL_COOKIE) || entry->ref_cnt == 0) {
IPAERR("bad parms\n");
result = -EINVAL;
goto ret;
@@ -1411,8 +1419,11 @@ int ipa2_put_rt_tbl(u32 rt_tbl_hdl)
ip = IPA_IP_v4;
else if (entry->set == &ipa_ctx->rt_tbl_set[IPA_IP_v6])
ip = IPA_IP_v6;
- else
+ else {
WARN_ON(1);
+ result = -EINVAL;
+ goto ret;
+ }
entry->ref_cnt--;
if (entry->ref_cnt == 0 && entry->rule_cnt == 0) {
@@ -1439,7 +1450,7 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
if (rtrule->rule.hdr_hdl) {
hdr = ipa_id_find(rtrule->rule.hdr_hdl);
- if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
+ if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid hdr\n");
goto error;
}
@@ -1451,7 +1462,7 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
goto error;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_RT_RULE_COOKIE) {
IPAERR("bad params\n");
goto error;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
index 41b29335d23b..42632c527bdd 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
@@ -745,7 +745,7 @@ static int __ipa_validate_flt_rule(const struct ipa_flt_rule *rule,
goto error;
}
- if ((*rt_tbl)->cookie != IPA_COOKIE) {
+ if ((*rt_tbl)->cookie != IPA_RT_TBL_COOKIE) {
IPAERR("RT table cookie is invalid\n");
goto error;
}
@@ -787,7 +787,7 @@ static int __ipa_create_flt_entry(struct ipa3_flt_entry **entry,
}
INIT_LIST_HEAD(&((*entry)->link));
(*entry)->rule = *rule;
- (*entry)->cookie = IPA_COOKIE;
+ (*entry)->cookie = IPA_FLT_COOKIE;
(*entry)->rt_tbl = rt_tbl;
(*entry)->tbl = tbl;
if (rule->rule_id) {
@@ -822,12 +822,18 @@ static int __ipa_finish_flt_rule_add(struct ipa3_flt_tbl *tbl,
if (id < 0) {
IPAERR("failed to add to tree\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
*rule_hdl = id;
entry->id = id;
IPADBG_LOW("add flt rule rule_cnt=%d\n", tbl->rule_cnt);
return 0;
+ipa_insert_failed:
+ if (entry->rt_tbl)
+ entry->rt_tbl->ref_cnt--;
+ tbl->rule_cnt--;
+ return -EPERM;
}
static int __ipa_add_flt_rule(struct ipa3_flt_tbl *tbl, enum ipa_ip_type ip,
@@ -853,9 +859,16 @@ static int __ipa_add_flt_rule(struct ipa3_flt_tbl *tbl, enum ipa_ip_type ip,
list_add(&entry->link, &tbl->head_flt_rule_list);
}
- __ipa_finish_flt_rule_add(tbl, entry, rule_hdl);
+ if (__ipa_finish_flt_rule_add(tbl, entry, rule_hdl))
+ goto ipa_insert_failed;
return 0;
+ipa_insert_failed:
+ list_del(&entry->link);
+ /* if rule id was allocated from idr, remove it */
+ if (!(entry->rule_id & ipahal_get_rule_id_hi_bit()))
+ idr_remove(&entry->tbl->rule_ids, entry->rule_id);
+ kmem_cache_free(ipa3_ctx->flt_rule_cache, entry);
error:
return -EPERM;
@@ -887,7 +900,8 @@ static int __ipa_add_flt_rule_after(struct ipa3_flt_tbl *tbl,
list_add(&entry->link, &((*add_after_entry)->link));
- __ipa_finish_flt_rule_add(tbl, entry, rule_hdl);
+ if (__ipa_finish_flt_rule_add(tbl, entry, rule_hdl))
+ goto ipa_insert_failed;
/*
* prepare for next insertion
@@ -896,6 +910,13 @@ static int __ipa_add_flt_rule_after(struct ipa3_flt_tbl *tbl,
return 0;
+ipa_insert_failed:
+ list_del(&entry->link);
+ /* if rule id was allocated from idr, remove it */
+ if (!(entry->rule_id & ipahal_get_rule_id_hi_bit()))
+ idr_remove(&entry->tbl->rule_ids, entry->rule_id);
+ kmem_cache_free(ipa3_ctx->flt_rule_cache, entry);
+
error:
*add_after_entry = NULL;
return -EPERM;
@@ -912,7 +933,7 @@ static int __ipa_del_flt_rule(u32 rule_hdl)
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_FLT_COOKIE) {
IPAERR("bad params\n");
return -EINVAL;
}
@@ -949,7 +970,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
goto error;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_FLT_COOKIE) {
IPAERR("bad params\n");
goto error;
}
@@ -970,7 +991,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
goto error;
}
- if (rt_tbl->cookie != IPA_COOKIE) {
+ if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
IPAERR("RT table cookie is invalid\n");
goto error;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
index a5186f1aff35..34bc7dcd63cf 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
@@ -339,7 +339,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
IPAERR("hdr_hdl is invalid\n");
return -EINVAL;
}
- if (hdr_entry->cookie != IPA_COOKIE) {
+ if (hdr_entry->cookie != IPA_HDR_COOKIE) {
IPAERR("Invalid header cookie %u\n", hdr_entry->cookie);
WARN_ON(1);
return -EINVAL;
@@ -359,7 +359,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
entry->hdr = hdr_entry;
if (add_ref_hdr)
hdr_entry->ref_cnt++;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_HDR_COOKIE;
needed_len = ipahal_get_proc_ctx_needed_len(proc_ctx->type);
@@ -417,6 +417,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
if (id < 0) {
IPAERR("failed to alloc id\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
proc_ctx->proc_ctx_hdl = id;
@@ -424,6 +425,14 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
return 0;
+ipa_insert_failed:
+ if (offset)
+ list_move(&offset->link,
+ &htbl->head_free_offset_list[offset->bin]);
+ entry->offset_entry = NULL;
+ list_del(&entry->link);
+ htbl->proc_ctx_cnt--;
+
bad_len:
if (add_ref_hdr)
hdr_entry->ref_cnt--;
@@ -436,7 +445,7 @@ bad_len:
static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
{
struct ipa3_hdr_entry *entry;
- struct ipa_hdr_offset_entry *offset;
+ struct ipa_hdr_offset_entry *offset = NULL;
u32 bin;
struct ipa3_hdr_tbl *htbl = &ipa3_ctx->hdr_tbl;
int id;
@@ -467,7 +476,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
entry->type = hdr->type;
entry->is_eth2_ofst_valid = hdr->is_eth2_ofst_valid;
entry->eth2_ofst = hdr->eth2_ofst;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_HDR_COOKIE;
if (hdr->hdr_len <= ipa_hdr_bin_sz[IPA_HDR_BIN0])
bin = IPA_HDR_BIN0;
@@ -546,6 +555,7 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
if (id < 0) {
IPAERR("failed to alloc id\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
hdr->hdr_hdl = id;
@@ -570,10 +580,19 @@ fail_add_proc_ctx:
entry->ref_cnt--;
hdr->hdr_hdl = 0;
ipa3_id_remove(id);
+ipa_insert_failed:
+ if (entry->is_hdr_proc_ctx) {
+ dma_unmap_single(ipa3_ctx->pdev, entry->phys_base,
+ entry->hdr_len, DMA_TO_DEVICE);
+ } else {
+ if (offset)
+ list_move(&offset->link,
+ &htbl->head_free_offset_list[offset->bin]);
+ entry->offset_entry = NULL;
+ }
htbl->hdr_cnt--;
list_del(&entry->link);
- dma_unmap_single(ipa3_ctx->pdev, entry->phys_base,
- entry->hdr_len, DMA_TO_DEVICE);
+
fail_dma_mapping:
entry->is_hdr_proc_ctx = false;
@@ -591,7 +610,7 @@ static int __ipa3_del_hdr_proc_ctx(u32 proc_ctx_hdl,
struct ipa3_hdr_proc_ctx_tbl *htbl = &ipa3_ctx->hdr_proc_ctx_tbl;
entry = ipa3_id_find(proc_ctx_hdl);
- if (!entry || (entry->cookie != IPA_COOKIE)) {
+ if (!entry || (entry->cookie != IPA_HDR_COOKIE)) {
IPAERR("bad parm\n");
return -EINVAL;
}
@@ -642,7 +661,7 @@ int __ipa3_del_hdr(u32 hdr_hdl, bool by_user)
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_HDR_COOKIE) {
IPAERR("bad parm\n");
return -EINVAL;
}
@@ -1188,7 +1207,7 @@ int ipa3_put_hdr(u32 hdr_hdl)
goto bail;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_HDR_COOKIE) {
IPAERR("invalid header entry\n");
result = -EINVAL;
goto bail;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index ac7ef6a21952..cbc53fb6815d 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -40,6 +40,12 @@
#define DRV_NAME "ipa"
#define NAT_DEV_NAME "ipaNatTable"
#define IPA_COOKIE 0x57831603
+#define IPA_RT_RULE_COOKIE 0x57831604
+#define IPA_RT_TBL_COOKIE 0x57831605
+#define IPA_FLT_COOKIE 0x57831606
+#define IPA_HDR_COOKIE 0x57831607
+#define IPA_PROC_HDR_COOKIE 0x57831608
+
#define MTU_BYTE 1500
#define IPA_EP_NOT_ALLOCATED (-1)
@@ -217,8 +223,8 @@ struct ipa_smmu_cb_ctx {
*/
struct ipa3_flt_entry {
struct list_head link;
- struct ipa_flt_rule rule;
u32 cookie;
+ struct ipa_flt_rule rule;
struct ipa3_flt_tbl *tbl;
struct ipa3_rt_tbl *rt_tbl;
u32 hw_len;
@@ -246,13 +252,13 @@ struct ipa3_flt_entry {
*/
struct ipa3_rt_tbl {
struct list_head link;
+ u32 cookie;
struct list_head head_rt_rule_list;
char name[IPA_RESOURCE_NAME_MAX];
u32 idx;
u32 rule_cnt;
u32 ref_cnt;
struct ipa3_rt_tbl_set *set;
- u32 cookie;
bool in_sys[IPA_RULE_TYPE_MAX];
u32 sz[IPA_RULE_TYPE_MAX];
struct ipa_mem_buffer curr_mem[IPA_RULE_TYPE_MAX];
@@ -284,6 +290,7 @@ struct ipa3_rt_tbl {
*/
struct ipa3_hdr_entry {
struct list_head link;
+ u32 cookie;
u8 hdr[IPA_HDR_MAX_SIZE];
u32 hdr_len;
char name[IPA_RESOURCE_NAME_MAX];
@@ -293,7 +300,6 @@ struct ipa3_hdr_entry {
dma_addr_t phys_base;
struct ipa3_hdr_proc_ctx_entry *proc_ctx;
struct ipa_hdr_offset_entry *offset_entry;
- u32 cookie;
u32 ref_cnt;
int id;
u8 is_eth2_ofst_valid;
@@ -342,10 +348,10 @@ struct ipa3_hdr_proc_ctx_offset_entry {
*/
struct ipa3_hdr_proc_ctx_entry {
struct list_head link;
+ u32 cookie;
enum ipa_hdr_proc_type type;
struct ipa3_hdr_proc_ctx_offset_entry *offset_entry;
struct ipa3_hdr_entry *hdr;
- u32 cookie;
u32 ref_cnt;
int id;
bool user_deleted;
@@ -407,8 +413,8 @@ struct ipa3_flt_tbl {
*/
struct ipa3_rt_entry {
struct list_head link;
- struct ipa_rt_rule rule;
u32 cookie;
+ struct ipa_rt_rule rule;
struct ipa3_rt_tbl *tbl;
struct ipa3_hdr_entry *hdr;
struct ipa3_hdr_proc_ctx_entry *proc_ctx;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
index 6197c9f64ca5..2ade584890fb 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
@@ -796,7 +796,7 @@ static struct ipa3_rt_tbl *__ipa_add_rt_tbl(enum ipa_ip_type ip,
INIT_LIST_HEAD(&entry->link);
strlcpy(entry->name, name, IPA_RESOURCE_NAME_MAX);
entry->set = set;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_RT_TBL_COOKIE;
entry->in_sys[IPA_RULE_HASHABLE] = (ip == IPA_IP_v4) ?
!ipa3_ctx->ip4_rt_tbl_hash_lcl :
!ipa3_ctx->ip6_rt_tbl_hash_lcl;
@@ -814,12 +814,16 @@ static struct ipa3_rt_tbl *__ipa_add_rt_tbl(enum ipa_ip_type ip,
if (id < 0) {
IPAERR("failed to add to tree\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
}
return entry;
-
+ipa_insert_failed:
+ set->tbl_cnt--;
+ list_del(&entry->link);
+ idr_destroy(&entry->rule_ids);
fail_rt_idx_alloc:
entry->cookie = 0;
kmem_cache_free(ipa3_ctx->rt_tbl_cache, entry);
@@ -833,7 +837,7 @@ static int __ipa_del_rt_tbl(struct ipa3_rt_tbl *entry)
u32 id;
struct ipa3_rt_tbl_set *rset;
- if (entry == NULL || (entry->cookie != IPA_COOKIE)) {
+ if (entry == NULL || (entry->cookie != IPA_RT_TBL_COOKIE)) {
IPAERR("bad parms\n");
return -EINVAL;
}
@@ -847,8 +851,10 @@ static int __ipa_del_rt_tbl(struct ipa3_rt_tbl *entry)
ip = IPA_IP_v4;
else if (entry->set == &ipa3_ctx->rt_tbl_set[IPA_IP_v6])
ip = IPA_IP_v6;
- else
+ else {
WARN_ON(1);
+ return -EPERM;
+ }
rset = &ipa3_ctx->reap_rt_tbl_set[ip];
@@ -885,14 +891,14 @@ static int __ipa_rt_validate_hndls(const struct ipa_rt_rule *rule,
if (rule->hdr_hdl) {
*hdr = ipa3_id_find(rule->hdr_hdl);
- if ((*hdr == NULL) || ((*hdr)->cookie != IPA_COOKIE)) {
+ if ((*hdr == NULL) || ((*hdr)->cookie != IPA_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid hdr\n");
return -EPERM;
}
} else if (rule->hdr_proc_ctx_hdl) {
*proc_ctx = ipa3_id_find(rule->hdr_proc_ctx_hdl);
if ((*proc_ctx == NULL) ||
- ((*proc_ctx)->cookie != IPA_COOKIE)) {
+ ((*proc_ctx)->cookie != IPA_PROC_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid proc ctx\n");
return -EPERM;
@@ -915,7 +921,7 @@ static int __ipa_create_rt_entry(struct ipa3_rt_entry **entry,
goto error;
}
INIT_LIST_HEAD(&(*entry)->link);
- (*(entry))->cookie = IPA_COOKIE;
+ (*(entry))->cookie = IPA_RT_RULE_COOKIE;
(*(entry))->rule = *rule;
(*(entry))->tbl = tbl;
(*(entry))->hdr = hdr;
@@ -983,7 +989,7 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
tbl = __ipa_add_rt_tbl(ip, name);
- if (tbl == NULL || (tbl->cookie != IPA_COOKIE)) {
+ if (tbl == NULL || (tbl->cookie != IPA_RT_TBL_COOKIE)) {
IPAERR("failed adding rt tbl name = %s\n",
name ? name : "");
goto error;
@@ -1118,7 +1124,7 @@ int ipa3_add_rt_rule_after(struct ipa_ioc_add_rt_rule_after *rules)
mutex_lock(&ipa3_ctx->lock);
tbl = __ipa3_find_rt_tbl(rules->ip, rules->rt_tbl_name);
- if (tbl == NULL || (tbl->cookie != IPA_COOKIE)) {
+ if (tbl == NULL || (tbl->cookie != IPA_RT_TBL_COOKIE)) {
IPAERR("failed finding rt tbl name = %s\n",
rules->rt_tbl_name ? rules->rt_tbl_name : "");
ret = -EINVAL;
@@ -1202,7 +1208,7 @@ int __ipa3_del_rt_rule(u32 rule_hdl)
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_RT_RULE_COOKIE) {
IPAERR("bad params\n");
return -EINVAL;
}
@@ -1440,7 +1446,7 @@ int ipa3_get_rt_tbl(struct ipa_ioc_get_rt_tbl *lookup)
}
mutex_lock(&ipa3_ctx->lock);
entry = __ipa3_find_rt_tbl(lookup->ip, lookup->name);
- if (entry && entry->cookie == IPA_COOKIE) {
+ if (entry && entry->cookie == IPA_RT_TBL_COOKIE) {
if (entry->ref_cnt == U32_MAX) {
IPAERR("fail: ref count crossed limit\n");
goto ret;
@@ -1483,7 +1489,7 @@ int ipa3_put_rt_tbl(u32 rt_tbl_hdl)
goto ret;
}
- if ((entry->cookie != IPA_COOKIE) || entry->ref_cnt == 0) {
+ if ((entry->cookie != IPA_RT_TBL_COOKIE) || entry->ref_cnt == 0) {
IPAERR("bad parms\n");
result = -EINVAL;
goto ret;
@@ -1493,8 +1499,10 @@ int ipa3_put_rt_tbl(u32 rt_tbl_hdl)
ip = IPA_IP_v4;
else if (entry->set == &ipa3_ctx->rt_tbl_set[IPA_IP_v6])
ip = IPA_IP_v6;
- else
+ else {
WARN_ON(1);
+ goto ret;
+ }
entry->ref_cnt--;
if (entry->ref_cnt == 0 && entry->rule_cnt == 0) {
@@ -1524,13 +1532,14 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
if (rtrule->rule.hdr_hdl) {
hdr = ipa3_id_find(rtrule->rule.hdr_hdl);
- if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
+ if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid hdr\n");
goto error;
}
} else if (rtrule->rule.hdr_proc_ctx_hdl) {
proc_ctx = ipa3_id_find(rtrule->rule.hdr_proc_ctx_hdl);
- if ((proc_ctx == NULL) || (proc_ctx->cookie != IPA_COOKIE)) {
+ if ((proc_ctx == NULL) ||
+ (proc_ctx->cookie != IPA_PROC_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid proc ctx\n");
goto error;
}
@@ -1542,7 +1551,7 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
goto error;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_RT_RULE_COOKIE) {
IPAERR("bad params\n");
goto error;
}
diff --git a/drivers/power/qcom/msm-core.c b/drivers/power/qcom/msm-core.c
index 43ad33ea234b..825c27e7a4c1 100644
--- a/drivers/power/qcom/msm-core.c
+++ b/drivers/power/qcom/msm-core.c
@@ -190,10 +190,12 @@ static void core_temp_notify(enum thermal_trip_type type,
struct cpu_activity_info *cpu_node =
(struct cpu_activity_info *) data;
+ temp /= scaling_factor;
+
trace_temp_notification(cpu_node->sensor_id,
type, temp, cpu_node->temp);
- cpu_node->temp = temp / scaling_factor;
+ cpu_node->temp = temp;
complete(&sampling_completion);
}
diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c
index 0908eea3b186..7b7f991ecba9 100644
--- a/drivers/power/supply/qcom/qpnp-smb2.c
+++ b/drivers/power/supply/qcom/qpnp-smb2.c
@@ -1847,6 +1847,12 @@ static int smb2_post_init(struct smb2 *chip)
struct smb_charger *chg = &chip->chg;
int rc;
+ /* In case the usb path is suspended, we would have missed disabling
+ * the icl change interrupt because the interrupt could have been
+ * not requested
+ */
+ rerun_election(chg->usb_icl_votable);
+
/* configure power role for dual-role */
rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
TYPEC_POWER_ROLE_CMD_MASK, 0);
@@ -2196,6 +2202,8 @@ static int smb2_request_interrupts(struct smb2 *chip)
return rc;
}
}
+ if (chg->irq_info[USBIN_ICL_CHANGE_IRQ].irq)
+ chg->usb_icl_change_irq_enabled = true;
return rc;
}
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index 16db425514c3..64ed53185e88 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -427,6 +427,14 @@ static int step_charge_soc_update(struct smb_charger *chg, int capacity)
int smblib_set_usb_suspend(struct smb_charger *chg, bool suspend)
{
int rc = 0;
+ int irq = chg->irq_info[USBIN_ICL_CHANGE_IRQ].irq;
+
+ if (suspend && irq) {
+ if (chg->usb_icl_change_irq_enabled) {
+ disable_irq_nosync(irq);
+ chg->usb_icl_change_irq_enabled = false;
+ }
+ }
rc = smblib_masked_write(chg, USBIN_CMD_IL_REG, USBIN_SUSPEND_BIT,
suspend ? USBIN_SUSPEND_BIT : 0);
@@ -434,6 +442,13 @@ int smblib_set_usb_suspend(struct smb_charger *chg, bool suspend)
smblib_err(chg, "Couldn't write %s to USBIN_SUSPEND_BIT rc=%d\n",
suspend ? "suspend" : "resume", rc);
+ if (!suspend && irq) {
+ if (!chg->usb_icl_change_irq_enabled) {
+ enable_irq(irq);
+ chg->usb_icl_change_irq_enabled = true;
+ }
+ }
+
return rc;
}
@@ -885,7 +900,6 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua)
if (icl_ua < USBIN_25MA)
return smblib_set_usb_suspend(chg, true);
- disable_irq_nosync(chg->irq_info[USBIN_ICL_CHANGE_IRQ].irq);
if (icl_ua == INT_MAX)
goto override_suspend_config;
@@ -943,7 +957,6 @@ override_suspend_config:
}
enable_icl_changed_interrupt:
- enable_irq(chg->irq_info[USBIN_ICL_CHANGE_IRQ].irq);
return rc;
}
diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h
index c97b84c34084..18714827b8d2 100644
--- a/drivers/power/supply/qcom/smb-lib.h
+++ b/drivers/power/supply/qcom/smb-lib.h
@@ -328,6 +328,7 @@ struct smb_charger {
int fake_input_current_limited;
bool pr_swap_in_progress;
int typec_mode;
+ int usb_icl_change_irq_enabled;
/* workaround flag */
u32 wa_flags;
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 830ef92ffe80..fc9faaee3170 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -272,7 +272,7 @@ static struct of_device_id msm_hs_match_table[] = {
#define UARTDM_TX_BUF_SIZE UART_XMIT_SIZE
#define UARTDM_RX_BUF_SIZE 512
#define RETRY_TIMEOUT 5
-#define UARTDM_NR 256
+#define UARTDM_NR 4
#define BAM_PIPE_MIN 0
#define BAM_PIPE_MAX 11
#define BUS_SCALING 1
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index 03aeec2e878c..7cdc95d2b085 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -182,7 +182,7 @@ static void *usbpd_ipc_log;
#define PS_HARD_RESET_TIME 25
#define PS_SOURCE_ON 400
#define PS_SOURCE_OFF 750
-#define SWAP_SOURCE_START_TIME 20
+#define FIRST_SOURCE_CAP_TIME 200
#define VDM_BUSY_TIME 50
#define VCONN_ON_TIME 100
@@ -790,17 +790,27 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
pd->pd_phy_opened = true;
}
- pd->current_state = PE_SRC_SEND_CAPABILITIES;
if (pd->in_pr_swap) {
- kick_sm(pd, SWAP_SOURCE_START_TIME);
pd->in_pr_swap = false;
val.intval = 0;
power_supply_set_property(pd->usb_psy,
POWER_SUPPLY_PROP_PR_SWAP, &val);
- break;
}
- /* fall-through */
+ /*
+ * A sink might remove its terminations (during some Type-C
+ * compliance tests or a sink attempting to do Try.SRC)
+ * at this point just after we enabled VBUS. Sending PD
+ * messages now would delay detecting the detach beyond the
+ * required timing. Instead, delay sending out the first
+ * source capabilities to allow for the other side to
+ * completely settle CC debounce and allow HW to detect detach
+ * sooner in the meantime. PD spec allows up to
+ * tFirstSourceCap (250ms).
+ */
+ pd->current_state = PE_SRC_SEND_CAPABILITIES;
+ kick_sm(pd, FIRST_SOURCE_CAP_TIME);
+ break;
case PE_SRC_SEND_CAPABILITIES:
kick_sm(pd, 0);
diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h
index d6e8a213c215..5548f0f09f8a 100644
--- a/drivers/video/fbdev/msm/mdss.h
+++ b/drivers/video/fbdev/msm/mdss.h
@@ -547,6 +547,7 @@ struct mdss_data_type {
u32 sec_session_cnt;
wait_queue_head_t secure_waitq;
struct cx_ipeak_client *mdss_cx_ipeak;
+ struct mult_factor bus_throughput_factor;
};
extern struct mdss_data_type *mdss_res;
diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c
index 6936c4c1f3cc..6fb32761a767 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp.c
@@ -4527,6 +4527,15 @@ static int mdss_mdp_parse_dt_misc(struct platform_device *pdev)
mdss_mdp_parse_dt_fudge_factors(pdev, "qcom,mdss-clk-factor",
&mdata->clk_factor);
+ /*
+ * Bus throughput factor will be used during high downscale cases.
+ * The recommended default factor is 1.1.
+ */
+ mdata->bus_throughput_factor.numer = 11;
+ mdata->bus_throughput_factor.denom = 10;
+ mdss_mdp_parse_dt_fudge_factors(pdev, "qcom,mdss-bus-througput-factor",
+ &mdata->bus_throughput_factor);
+
rc = of_property_read_u32(pdev->dev.of_node,
"qcom,max-bandwidth-low-kbps", &mdata->max_bw_low);
if (rc)
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index efd681a5d954..0165c48a0467 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -31,6 +31,7 @@
#define MDSS_MDP_QSEED3_VER_DOWNSCALE_LIM 2
#define NUM_MIXERCFG_REGS 3
#define MDSS_MDP_WB_OUTPUT_BPP 3
+#define MIN_BUS_THROUGHPUT_SCALE_FACTOR 35
struct mdss_mdp_mixer_cfg {
u32 config_masks[NUM_MIXERCFG_REGS];
bool border_enabled;
@@ -622,11 +623,21 @@ static u32 __calc_qseed3_mdp_clk_rate(struct mdss_mdp_pipe *pipe,
}
static inline bool __is_vert_downscaling(u32 src_h,
- struct mdss_rect dst){
-
+ struct mdss_rect dst)
+{
return (src_h > dst.h);
}
+static inline bool __is_bus_throughput_factor_required(u32 src_h,
+ struct mdss_rect dst)
+{
+ u32 scale_factor = src_h * 10;
+
+ do_div(scale_factor, dst.h);
+ return (__is_vert_downscaling(src_h, dst) &&
+ (scale_factor >= MIN_BUS_THROUGHPUT_SCALE_FACTOR));
+}
+
static u32 get_pipe_mdp_clk_rate(struct mdss_mdp_pipe *pipe,
struct mdss_rect src, struct mdss_rect dst,
u32 fps, u32 v_total, u32 flags)
@@ -673,6 +684,15 @@ static u32 get_pipe_mdp_clk_rate(struct mdss_mdp_pipe *pipe,
}
}
+ /*
+ * If the downscale factor is >= 3.5 for a 32 BPP surface,
+ * it is recommended to add a 10% bus throughput factor to
+ * the clock rate.
+ */
+ if ((pipe->src_fmt->bpp == 4) &&
+ __is_bus_throughput_factor_required(src_h, dst))
+ rate = apply_fudge_factor(rate, &mdata->bus_throughput_factor);
+
if (flags & PERF_CALC_PIPE_APPLY_CLK_FUDGE)
rate = mdss_mdp_clk_fudge_factor(mixer, rate);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_layer.c b/drivers/video/fbdev/msm/mdss_mdp_layer.c
index e44edb8fbea7..3ccc09d58480 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_layer.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_layer.c
@@ -3131,6 +3131,14 @@ int mdss_mdp_layer_pre_commit_wfd(struct msm_fb_data_type *mfd,
sync_pt_data = &mfd->mdp_sync_pt_data;
mutex_lock(&sync_pt_data->sync_mutex);
count = sync_pt_data->acq_fen_cnt;
+
+ if (count >= MDP_MAX_FENCE_FD) {
+ pr_err("Reached maximum possible value for fence count\n");
+ mutex_unlock(&sync_pt_data->sync_mutex);
+ rc = -EINVAL;
+ goto input_layer_err;
+ }
+
sync_pt_data->acq_fen[count] = fence;
sync_pt_data->acq_fen_cnt++;
mutex_unlock(&sync_pt_data->sync_mutex);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c b/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c
index 017a2f10dfbc..a5ec7097e0f6 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -194,8 +194,12 @@ static int pp_hist_lut_cache_params_pipe_v1_7(struct mdp_hist_lut_data *config,
return -EINVAL;
}
- memcpy(&hist_lut_usr_config, config->cfg_payload,
- sizeof(struct mdp_hist_lut_data_v1_7));
+ if (copy_from_user(&hist_lut_usr_config,
+ (void __user *) config->cfg_payload,
+ sizeof(hist_lut_usr_config))) {
+ pr_err("failed to copy hist lut config\n");
+ return -EFAULT;
+ }
hist_lut_cache_data = pipe->pp_res.hist_lut_cfg_payload;
if (!hist_lut_cache_data) {
@@ -606,8 +610,12 @@ static int pp_pcc_cache_params_pipe_v1_7(struct mdp_pcc_cfg_data *config,
return -EINVAL;
}
- memcpy(&v17_usr_config, config->cfg_payload,
- sizeof(v17_usr_config));
+ if (copy_from_user(&v17_usr_config,
+ (void __user *) config->cfg_payload,
+ sizeof(v17_usr_config))) {
+ pr_err("failed to copy pcc config\n");
+ return -EFAULT;
+ }
if (!(config->ops & MDP_PP_OPS_WRITE)) {
pr_debug("write ops not set value of flag is %d\n",
@@ -861,8 +869,12 @@ static int pp_igc_lut_cache_params_pipe_v1_7(struct mdp_igc_lut_data *config,
goto igc_config_exit;
}
- memcpy(&v17_usr_config, config->cfg_payload,
- sizeof(v17_usr_config));
+ if (copy_from_user(&v17_usr_config,
+ (void __user *) config->cfg_payload,
+ sizeof(v17_usr_config))) {
+ pr_err("failed to copy igc usr config\n");
+ return -EFAULT;
+ }
if (!(config->ops & MDP_PP_OPS_WRITE)) {
pr_debug("op for gamut %d\n", config->ops);
@@ -1272,8 +1284,12 @@ static int pp_pa_cache_params_pipe_v1_7(struct mdp_pa_v2_cfg_data *config,
return -EINVAL;
}
- memcpy(&pa_usr_config, config->cfg_payload,
- sizeof(struct mdp_pa_data_v1_7));
+ if (copy_from_user(&pa_usr_config,
+ (void __user *) config->cfg_payload,
+ sizeof(pa_usr_config))) {
+ pr_err("failed to copy pa usr config\n");
+ return -EFAULT;
+ }
pa_cache_data = pipe->pp_res.pa_cfg_payload;
if (!pa_cache_data) {
diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
index 80dbe83972d7..bb3b4b3fa929 100644
--- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c
+++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
@@ -2587,7 +2587,8 @@ int mdss_dsi_post_clkon_cb(void *priv,
}
if (clk & MDSS_DSI_LINK_CLK) {
/* toggle the resync FIFO everytime clock changes */
- if (ctrl->shared_data->phy_rev == DSI_PHY_REV_30)
+ if ((ctrl->shared_data->phy_rev == DSI_PHY_REV_30) &&
+ !pdata->panel_info.cont_splash_enabled)
mdss_dsi_phy_v3_toggle_resync_fifo(ctrl);
if (ctrl->ulps) {
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 74995a0cdbad..a1d8b04d08ac 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -625,6 +625,29 @@ struct audproc_softvolume_params {
*/
#define AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT 0x00010913
+/* ID of the Channel Mixer module, which is used to configure
+ * channel-mixer related parameters.
+ * This module supports the AUDPROC_CHMIXER_PARAM_ID_COEFF parameter ID.
+ */
+#define AUDPROC_MODULE_ID_CHMIXER 0x00010341
+
+/* ID of the Coefficient parameter used by AUDPROC_MODULE_ID_CHMIXER to
+ *configure the channel mixer weighting coefficients.
+ */
+#define AUDPROC_CHMIXER_PARAM_ID_COEFF 0x00010342
+
+/* Payload of the per-session, per-device parameter data of the
+ * #ADM_CMD_SET_PSPD_MTMX_STRTR_PARAMS_V5 command or
+ * #ADM_CMD_SET_PSPD_MTMX_STRTR_PARAMS_V6 command.
+ * Immediately following this structure are param_size bytes of parameter
+ * data. The structure and size depend on the module_id/param_id pair.
+ */
+struct adm_pspd_param_data_t {
+ uint32_t module_id;
+ uint32_t param_id;
+ uint16_t param_size;
+ uint16_t reserved;
+} __packed;
struct audproc_mfc_output_media_fmt {
struct adm_cmd_set_pp_params_v5 params;
@@ -3902,6 +3925,14 @@ struct asm_softvolume_params {
u32 rampingcurve;
} __packed;
+struct asm_stream_pan_ctrl_params {
+ uint16_t num_output_channels;
+ uint16_t num_input_channels;
+ uint16_t output_channel_map[8];
+ uint16_t input_channel_map[8];
+ uint16_t gain[64];
+} __packed;
+
#define ASM_END_POINT_DEVICE_MATRIX 0
#define PCM_CHANNEL_NULL 0
@@ -7802,6 +7833,48 @@ struct asm_volume_ctrl_lr_chan_gain {
/*< Linear gain in Q13 format for the right channel.*/
} __packed;
+struct audproc_chmixer_param_coeff {
+ uint32_t index;
+ uint16_t num_output_channels;
+ uint16_t num_input_channels;
+} __packed;
+
+
+/* ID of the Multichannel Volume Control parameters used by
+ * AUDPROC_MODULE_ID_VOL_CTRL.
+ */
+#define AUDPROC_PARAM_ID_MULTICHANNEL_GAIN 0x00010713
+
+/* Payload of the AUDPROC_PARAM_ID_MULTICHANNEL_GAIN channel type/gain
+ * pairs used by the Volume Control module.
+ * This structure immediately follows the
+ * audproc_volume_ctrl_multichannel_gain_t structure.
+ */
+struct audproc_volume_ctrl_channel_type_gain_pair {
+ uint8_t channel_type;
+ /* Channel type for which the gain setting is to be applied. */
+
+ uint8_t reserved1;
+ uint8_t reserved2;
+ uint8_t reserved3;
+
+ uint32_t gain;
+ /* Gain value for this channel in Q28 format. */
+} __packed;
+
+/* Payload of the AUDPROC_PARAM_ID_MULTICHANNEL_MUTE parameters used by
+ * the Volume Control module.
+ */
+struct audproc_volume_ctrl_multichannel_gain {
+ uint32_t num_channels;
+ /* Number of channels for which mute configuration is provided. Any
+ * channels present in the data for which mute configuration is not
+ * provided are set to unmute.
+ */
+
+ struct audproc_volume_ctrl_channel_type_gain_pair *gain_data;
+ /* Array of channel type/mute setting pairs. */
+} __packed;
/* Structure for the mute configuration parameter for a
volume control module. */
diff --git a/include/sound/q6adm-v2.h b/include/sound/q6adm-v2.h
index e689e9357012..8c53bb9762ce 100644
--- a/include/sound/q6adm-v2.h
+++ b/include/sound/q6adm-v2.h
@@ -138,9 +138,13 @@ int adm_get_topology_for_port_copp_idx(int port_id, int copp_idx);
int adm_get_indexes_from_copp_id(int copp_id, int *port_idx, int *copp_idx);
-int adm_set_stereo_to_custom_stereo(int port_id, int copp_idx,
- unsigned int session_id,
- char *params, uint32_t params_length);
+int adm_set_pspd_matrix_params(int port_id, int copp_idx,
+ unsigned int session_id,
+ char *params, uint32_t params_length);
+
+int adm_set_downmix_params(int port_id, int copp_idx,
+ unsigned int session_id, char *params,
+ uint32_t params_length);
int adm_get_pp_topo_module_list(int port_id, int copp_idx, int32_t param_length,
char *params);
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index d0dffbd15923..177c2f4da32e 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -611,6 +611,14 @@ int q6asm_set_softvolume(struct audio_client *ac,
int q6asm_set_softvolume_v2(struct audio_client *ac,
struct asm_softvolume_params *param, int instance);
+/* Set panning and MFC params */
+int q6asm_set_mfc_panning_params(struct audio_client *ac,
+ struct asm_stream_pan_ctrl_params *pan_param);
+
+/* Set vol gain pair */
+int q6asm_set_vol_ctrl_gain_pair(struct audio_client *ac,
+ struct asm_stream_pan_ctrl_params *pan_param);
+
/* Send left-right channel gain */
int q6asm_set_lrgain(struct audio_client *ac, int left_gain, int right_gain);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 27796c33ca05..d7c1ee7cf0e2 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -184,6 +184,11 @@ ipv4_connected:
err = 0;
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
+ /* Reset daddr and dport so that udp_v6_early_demux()
+ * fails to find this socket
+ */
+ memset(&sk->sk_v6_daddr, 0, sizeof(sk->sk_v6_daddr));
+ inet->inet_dport = 0;
goto out;
}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 8a07c63ddccd..a8cabc876348 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -45,6 +45,7 @@
#include <net/tcp_states.h>
#include <net/ip6_checksum.h>
#include <net/xfrm.h>
+#include <net/inet_hashtables.h>
#include <net/inet6_hashtables.h>
#include <net/busy_poll.h>
@@ -964,15 +965,22 @@ static struct sock *__udp6_lib_demux_lookup(struct net *net,
int dif)
{
struct sock *sk;
+ struct hlist_nulls_node *hnode;
+ unsigned short hnum = ntohs(loc_port);
+ unsigned int hash2 = udp6_portaddr_hash(net, loc_addr, hnum);
+ unsigned int slot2 = hash2 & udp_table.mask;
+ struct udp_hslot *hslot2 = &udp_table.hash2[slot2];
- rcu_read_lock();
- sk = __udp6_lib_lookup(net, rmt_addr, rmt_port, loc_addr, loc_port,
- dif, &udp_table);
- if (sk && !atomic_inc_not_zero(&sk->sk_refcnt))
- sk = NULL;
- rcu_read_unlock();
+ const __portpair ports = INET_COMBINED_PORTS(rmt_port, hnum);
- return sk;
+ udp_portaddr_for_each_entry_rcu(sk, hnode, &hslot2->head) {
+ if (sk->sk_state == TCP_ESTABLISHED &&
+ INET6_MATCH(sk, net, rmt_addr, loc_addr, ports, dif))
+ return sk;
+ /* Only check first socket in chain */
+ break;
+ }
+ return NULL;
}
static void udp_v6_early_demux(struct sk_buff *skb)
@@ -997,7 +1005,7 @@ static void udp_v6_early_demux(struct sk_buff *skb)
else
return;
- if (!sk)
+ if (!sk || !atomic_inc_not_zero_hint(&sk->sk_refcnt, 2))
return;
skb->sk = sk;
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 24dbbedf0be7..cc89408fcb39 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -2641,6 +2641,101 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.name = "MultiMedia20",
.probe = fe_dai_probe,
},
+ {
+ .playback = {
+ .stream_name = "MultiMedia21 Playback",
+ .aif_name = "MM_DL21",
+ .rates = (SNDRV_PCM_RATE_8000_384000 |
+ SNDRV_PCM_RATE_KNOT),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
+ .channels_min = 1,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ },
+ .ops = &msm_fe_Multimedia_dai_ops,
+ .name = "MultiMedia21",
+ .probe = fe_dai_probe,
+ },
+ {
+ .playback = {
+ .stream_name = "MultiMedia22 Playback",
+ .aif_name = "MM_DL22",
+ .rates = (SNDRV_PCM_RATE_8000_384000 |
+ SNDRV_PCM_RATE_KNOT),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
+ .channels_min = 1,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ },
+ .ops = &msm_fe_Multimedia_dai_ops,
+ .name = "MultiMedia22",
+ .probe = fe_dai_probe,
+ },
+ {
+ .playback = {
+ .stream_name = "MultiMedia23 Playback",
+ .aif_name = "MM_DL23",
+ .rates = (SNDRV_PCM_RATE_8000_384000 |
+ SNDRV_PCM_RATE_KNOT),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
+ .channels_min = 1,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ },
+ .ops = &msm_fe_Multimedia_dai_ops,
+ .name = "MultiMedia23",
+ .probe = fe_dai_probe,
+ },
+ {
+ .playback = {
+ .stream_name = "MultiMedia24 Playback",
+ .aif_name = "MM_DL24",
+ .rates = (SNDRV_PCM_RATE_8000_384000 |
+ SNDRV_PCM_RATE_KNOT),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
+ .channels_min = 1,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ },
+ .ops = &msm_fe_Multimedia_dai_ops,
+ .name = "MultiMedia24",
+ .probe = fe_dai_probe,
+ },
+ {
+ .playback = {
+ .stream_name = "MultiMedia25 Playback",
+ .aif_name = "MM_DL25",
+ .rates = (SNDRV_PCM_RATE_8000_384000 |
+ SNDRV_PCM_RATE_KNOT),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
+ .channels_min = 1,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ },
+ .ops = &msm_fe_Multimedia_dai_ops,
+ .name = "MultiMedia25",
+ .probe = fe_dai_probe,
+ },
};
static int msm_fe_dai_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/msm/msm8998.c b/sound/soc/msm/msm8998.c
index 0b37e7e073aa..82bdb4af68d8 100644
--- a/sound/soc/msm/msm8998.c
+++ b/sound/soc/msm/msm8998.c
@@ -5526,6 +5526,91 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = {
.ignore_pmdown_time = 1,
.be_id = MSM_FRONTEND_DAI_MULTIMEDIA18,
},
+ {
+ .name = "MultiMedia21",
+ .stream_name = "MultiMedia21",
+ .cpu_dai_name = "MultiMedia21",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
+ .dpcm_playback = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA21,
+ },
+ {
+ .name = "MultiMedia22",
+ .stream_name = "MultiMedia22",
+ .cpu_dai_name = "MultiMedia22",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
+ .dpcm_playback = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA22,
+ },
+ {
+ .name = "MultiMedia23",
+ .stream_name = "MultiMedia23",
+ .cpu_dai_name = "MultiMedia23",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
+ .dpcm_playback = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA23,
+ },
+ {
+ .name = "MultiMedia24",
+ .stream_name = "MultiMedia24",
+ .cpu_dai_name = "MultiMedia24",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
+ .dpcm_playback = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA24,
+ },
+ {
+ .name = "MultiMedia25",
+ .stream_name = "MultiMedia25",
+ .cpu_dai_name = "MultiMedia25",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
+ .dpcm_playback = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA25,
+ },
};
static struct snd_soc_dai_link msm_common_be_dai_links[] = {
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index fa8bdddacef2..3610901addea 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -5147,6 +5147,27 @@ static int msm_dai_tdm_q6_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "%s: Clk Rate from DT file %d\n",
__func__, tdm_clk_set.clk_freq_in_hz);
+ /* initialize static tdm clk attribute to default value */
+ tdm_clk_set.clk_attri = Q6AFE_LPASS_CLK_ATTRIBUTE_INVERT_COUPLE_NO;
+
+ /* extract tdm clk attribute into static */
+ if (of_find_property(pdev->dev.of_node,
+ "qcom,msm-cpudai-tdm-clk-attribute", NULL)) {
+ rc = of_property_read_u16(pdev->dev.of_node,
+ "qcom,msm-cpudai-tdm-clk-attribute",
+ &tdm_clk_set.clk_attri);
+ if (rc) {
+ dev_err(&pdev->dev, "%s: clk attribute from DT file %s\n",
+ __func__, "qcom,msm-cpudai-tdm-clk-attribute");
+ goto rtn;
+ }
+ dev_dbg(&pdev->dev, "%s: clk attribute from DT file %d\n",
+ __func__, tdm_clk_set.clk_attri);
+ } else {
+ dev_dbg(&pdev->dev, "%s: No optional clk attribute found\n",
+ __func__);
+ }
+
/* extract tdm clk src master/slave info into static */
rc = of_property_read_u32(pdev->dev.of_node,
"qcom,msm-cpudai-tdm-clk-internal",
@@ -6226,6 +6247,41 @@ static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai,
return rc;
}
+static int msm_dai_q6_tdm_set_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct msm_dai_q6_tdm_dai_data *dai_data =
+ dev_get_drvdata(dai->dev);
+
+ switch (dai->id) {
+ case AFE_PORT_ID_PRIMARY_TDM_RX:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_1:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_2:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_3:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_4:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_5:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_6:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_7:
+ case AFE_PORT_ID_PRIMARY_TDM_TX:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_1:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_2:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_3:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_4:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_5:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_6:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_7:
+ dai_data->clk_set.clk_freq_in_hz = freq;
+ break;
+ default:
+ return 0;
+ }
+
+ dev_dbg(dai->dev, "%s: dai id = 0x%x group clk_freq %d\n",
+ __func__, dai->id, freq);
+ return 0;
+}
+
+
static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai,
unsigned int tx_num, unsigned int *tx_slot,
unsigned int rx_num, unsigned int *rx_slot)
@@ -6653,6 +6709,7 @@ static struct snd_soc_dai_ops msm_dai_q6_tdm_ops = {
.hw_params = msm_dai_q6_tdm_hw_params,
.set_tdm_slot = msm_dai_q6_tdm_set_tdm_slot,
.set_channel_map = msm_dai_q6_tdm_set_channel_map,
+ .set_sysclk = msm_dai_q6_tdm_set_sysclk,
.shutdown = msm_dai_q6_tdm_shutdown,
};
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index 46a3324d2d6b..de769e8b806c 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -1603,6 +1603,262 @@ done:
return ret;
}
+static int msm_pcm_playback_pan_scale_ctl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret = 0;
+ int len = 0;
+ int i = 0;
+ struct snd_pcm_usr *usr_info = snd_kcontrol_chip(kcontrol);
+ struct snd_pcm_substream *substream;
+ struct msm_audio *prtd;
+ struct asm_stream_pan_ctrl_params pan_param;
+
+ if (!usr_info) {
+ pr_err("%s: usr_info is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ substream = usr_info->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
+ if (!substream) {
+ pr_err("%s substream not found\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (!substream->runtime) {
+ pr_err("%s substream runtime not found\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ prtd = substream->runtime->private_data;
+ if (!prtd) {
+ ret = -EINVAL;
+ goto done;
+ }
+ pan_param.num_output_channels =
+ ucontrol->value.integer.value[len++];
+ if (pan_param.num_output_channels >
+ PCM_FORMAT_MAX_NUM_CHANNEL) {
+ ret = -EINVAL;
+ goto done;
+ }
+ pan_param.num_input_channels =
+ ucontrol->value.integer.value[len++];
+ if (pan_param.num_input_channels >
+ PCM_FORMAT_MAX_NUM_CHANNEL) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (ucontrol->value.integer.value[len++]) {
+ for (i = 0; i < pan_param.num_output_channels; i++) {
+ pan_param.output_channel_map[i] =
+ ucontrol->value.integer.value[len++];
+ }
+ }
+ if (ucontrol->value.integer.value[len++]) {
+ for (i = 0; i < pan_param.num_input_channels; i++) {
+ pan_param.input_channel_map[i] =
+ ucontrol->value.integer.value[len++];
+ }
+ }
+ if (ucontrol->value.integer.value[len++]) {
+ for (i = 0; i < pan_param.num_output_channels *
+ pan_param.num_input_channels; i++) {
+ pan_param.gain[i] =
+ !(ucontrol->value.integer.value[len++] > 0) ?
+ 0 : 2 << 13;
+ }
+ }
+
+ ret = q6asm_set_mfc_panning_params(prtd->audio_client,
+ &pan_param);
+ len -= pan_param.num_output_channels *
+ pan_param.num_input_channels;
+ for (i = 0; i < pan_param.num_output_channels *
+ pan_param.num_input_channels; i++) {
+ pan_param.gain[i] =
+ ucontrol->value.integer.value[len++];
+ }
+ ret = q6asm_set_vol_ctrl_gain_pair(prtd->audio_client,
+ &pan_param);
+
+done:
+ return ret;
+}
+
+static int msm_pcm_playback_pan_scale_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return 0;
+}
+
+static int msm_add_stream_pan_scale_controls(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_pcm *pcm;
+ struct snd_pcm_usr *pan_ctl_info;
+ struct snd_kcontrol *kctl;
+ const char *playback_mixer_ctl_name = "Audio Stream";
+ const char *deviceNo = "NN";
+ const char *suffix = "Pan Scale Control";
+ int ctl_len, ret = 0;
+
+ if (!rtd) {
+ pr_err("%s: rtd is NULL\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ pcm = rtd->pcm;
+ ctl_len = strlen(playback_mixer_ctl_name) + 1 + strlen(deviceNo) + 1 +
+ strlen(suffix) + 1;
+
+ ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ NULL, 1, ctl_len, rtd->dai_link->be_id,
+ &pan_ctl_info);
+
+ if (ret < 0) {
+ pr_err("%s: failed add ctl %s. err = %d\n",
+ __func__, suffix, ret);
+ goto done;
+ }
+ kctl = pan_ctl_info->kctl;
+ snprintf(kctl->id.name, ctl_len, "%s %d %s", playback_mixer_ctl_name,
+ rtd->pcm->device, suffix);
+ kctl->put = msm_pcm_playback_pan_scale_ctl_put;
+ kctl->get = msm_pcm_playback_pan_scale_ctl_get;
+ pr_debug("%s: Registering new mixer ctl = %s\n", __func__,
+ kctl->id.name);
+done:
+ return ret;
+
+}
+
+static int msm_pcm_playback_dnmix_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return 0;
+}
+
+static int msm_pcm_playback_dnmix_ctl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret = 0;
+ int len = 0;
+ int i = 0;
+ struct snd_pcm_usr *usr_info = snd_kcontrol_chip(kcontrol);
+ struct snd_pcm_substream *substream;
+ struct msm_audio *prtd;
+ struct asm_stream_pan_ctrl_params dnmix_param;
+
+ int be_id = ucontrol->value.integer.value[len];
+ int stream_id = 0;
+
+ if (!usr_info) {
+ pr_err("%s usr_info is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ substream = usr_info->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
+ if (!substream) {
+ pr_err("%s substream not found\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ if (!substream->runtime) {
+ pr_err("%s substream runtime not found\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ prtd = substream->runtime->private_data;
+ if (!prtd) {
+ ret = -EINVAL;
+ goto done;
+ }
+ stream_id = prtd->audio_client->session;
+ dnmix_param.num_output_channels =
+ ucontrol->value.integer.value[len++];
+ if (dnmix_param.num_output_channels >
+ PCM_FORMAT_MAX_NUM_CHANNEL) {
+ ret = -EINVAL;
+ goto done;
+ }
+ dnmix_param.num_input_channels =
+ ucontrol->value.integer.value[len++];
+ if (dnmix_param.num_input_channels >
+ PCM_FORMAT_MAX_NUM_CHANNEL) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (ucontrol->value.integer.value[len++]) {
+ for (i = 0; i < dnmix_param.num_output_channels; i++) {
+ dnmix_param.output_channel_map[i] =
+ ucontrol->value.integer.value[len++];
+ }
+ }
+ if (ucontrol->value.integer.value[len++]) {
+ for (i = 0; i < dnmix_param.num_input_channels; i++) {
+ dnmix_param.input_channel_map[i] =
+ ucontrol->value.integer.value[len++];
+ }
+ }
+ if (ucontrol->value.integer.value[len++]) {
+ for (i = 0; i < dnmix_param.num_output_channels *
+ dnmix_param.num_input_channels; i++) {
+ dnmix_param.gain[i] =
+ ucontrol->value.integer.value[len++];
+ }
+ }
+ msm_routing_set_downmix_control_data(be_id,
+ stream_id,
+ &dnmix_param);
+
+done:
+ return ret;
+}
+
+static int msm_add_device_down_mix_controls(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_pcm *pcm;
+ struct snd_pcm_usr *usr_info;
+ struct snd_kcontrol *kctl;
+ const char *playback_mixer_ctl_name = "Audio Device";
+ const char *deviceNo = "NN";
+ const char *suffix = "Downmix Control";
+ int ctl_len, ret = 0;
+
+ if (!rtd) {
+ pr_err("%s: rtd is NULL\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ pcm = rtd->pcm;
+ ctl_len = strlen(playback_mixer_ctl_name) + 1 +
+ strlen(deviceNo) + 1 + strlen(suffix) + 1;
+ ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ NULL, 1, ctl_len, rtd->dai_link->be_id,
+ &usr_info);
+ if (ret < 0) {
+ pr_err("%s: downmix control add failed: %d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ kctl = usr_info->kctl;
+ snprintf(kctl->id.name, ctl_len, "%s %d %s",
+ playback_mixer_ctl_name, rtd->pcm->device, suffix);
+ kctl->put = msm_pcm_playback_dnmix_ctl_put;
+ kctl->get = msm_pcm_playback_dnmix_ctl_get;
+ pr_debug("%s: downmix control name = %s\n",
+ __func__, playback_mixer_ctl_name);
+done:
+ return ret;
+}
+
static int msm_pcm_capture_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -1719,6 +1975,14 @@ static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd)
if (ret)
pr_err("%s: pcm add app type controls failed:%d\n",
__func__, ret);
+ ret = msm_add_stream_pan_scale_controls(rtd);
+ if (ret)
+ pr_err("%s: pcm add pan scale controls failed:%d\n",
+ __func__, ret);
+ ret = msm_add_device_down_mix_controls(rtd);
+ if (ret)
+ pr_err("%s: pcm add dnmix controls failed:%d\n",
+ __func__, ret);
return ret;
}
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 974d4a582540..b64bd7ed8fc7 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -35,6 +35,8 @@
#include <sound/audio_cal_utils.h>
#include <sound/audio_effects.h>
#include <sound/hwdep.h>
+#include <sound/q6adm-v2.h>
+#include <sound/apr_audio-v2.h>
#include "msm-pcm-routing-v2.h"
#include "msm-pcm-routing-devdep.h"
@@ -4090,6 +4092,21 @@ static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SLIMBUS_0_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia22", MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia23", MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia24", MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia25", MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = {
@@ -4612,6 +4629,21 @@ static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_HDMI_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia22", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia23", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia24", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia25", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new display_port_mixer_controls[] = {
@@ -4760,6 +4792,21 @@ static const struct snd_kcontrol_new slimbus_6_rx_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SLIMBUS_6_RX,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_SLIMBUS_6_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia22", MSM_BACKEND_DAI_SLIMBUS_6_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia23", MSM_BACKEND_DAI_SLIMBUS_6_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia24", MSM_BACKEND_DAI_SLIMBUS_6_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia25", MSM_BACKEND_DAI_SLIMBUS_6_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new slimbus_7_rx_mixer_controls[] = {
@@ -4811,6 +4858,21 @@ static const struct snd_kcontrol_new slimbus_7_rx_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SLIMBUS_7_RX,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_SLIMBUS_7_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia22", MSM_BACKEND_DAI_SLIMBUS_7_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA22, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia23", MSM_BACKEND_DAI_SLIMBUS_7_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA23, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia24", MSM_BACKEND_DAI_SLIMBUS_7_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA24, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia25", MSM_BACKEND_DAI_SLIMBUS_7_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA25, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new usb_audio_rx_mixer_controls[] = {
@@ -9797,6 +9859,22 @@ static const struct snd_kcontrol_new quat_tdm_rx_0_port_mixer_controls[] = {
MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0,
msm_routing_get_port_mixer,
msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_0,
+ MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_0,
+ MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_0,
+ MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_0,
+ MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_0,
MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0,
msm_routing_get_port_mixer,
@@ -9864,6 +9942,22 @@ static const struct snd_kcontrol_new quat_tdm_rx_1_port_mixer_controls[] = {
MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0,
msm_routing_get_port_mixer,
msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_1,
+ MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_1,
+ MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_1,
+ MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_1,
+ MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_1,
MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0,
msm_routing_get_port_mixer,
@@ -9931,6 +10025,22 @@ static const struct snd_kcontrol_new quat_tdm_rx_2_port_mixer_controls[] = {
MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0,
msm_routing_get_port_mixer,
msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_2,
+ MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_2,
+ MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_2,
+ MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_2,
+ MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_2,
MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0,
msm_routing_get_port_mixer,
@@ -9998,6 +10108,22 @@ static const struct snd_kcontrol_new quat_tdm_rx_3_port_mixer_controls[] = {
MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0,
msm_routing_get_port_mixer,
msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_3,
+ MSM_BACKEND_DAI_PRI_TDM_TX_0, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_RX_3,
+ MSM_BACKEND_DAI_PRI_TDM_TX_1, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_RX_3,
+ MSM_BACKEND_DAI_PRI_TDM_TX_2, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_RX_3,
+ MSM_BACKEND_DAI_PRI_TDM_TX_3, 1, 0,
+ msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_RX_3,
MSM_BACKEND_DAI_TERT_TDM_TX_0, 1, 0,
msm_routing_get_port_mixer,
@@ -11314,6 +11440,11 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
SND_SOC_DAPM_AIF_IN("MM_DL15", "MultiMedia15 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("MM_DL16", "MultiMedia16 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("MM_DL20", "MultiMedia20 Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("MM_DL21", "MultiMedia21 Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("MM_DL22", "MultiMedia22 Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("MM_DL23", "MultiMedia23 Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("MM_DL24", "MultiMedia24 Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("MM_DL25", "MultiMedia25 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
@@ -12450,6 +12581,11 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia14", "MM_DL14"},
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia15", "MM_DL15"},
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"SLIMBUS_0_RX Audio Mixer", "MultiMedia21", "MM_DL21"},
+ {"SLIMBUS_0_RX Audio Mixer", "MultiMedia22", "MM_DL22"},
+ {"SLIMBUS_0_RX Audio Mixer", "MultiMedia23", "MM_DL23"},
+ {"SLIMBUS_0_RX Audio Mixer", "MultiMedia24", "MM_DL24"},
+ {"SLIMBUS_0_RX Audio Mixer", "MultiMedia25", "MM_DL25"},
{"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"},
{"SLIMBUS_2_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -12504,6 +12640,11 @@ static const struct snd_soc_dapm_route intercon[] = {
{"HDMI Mixer", "MultiMedia14", "MM_DL14"},
{"HDMI Mixer", "MultiMedia15", "MM_DL15"},
{"HDMI Mixer", "MultiMedia16", "MM_DL16"},
+ {"HDMI Mixer", "MultiMedia21", "MM_DL21"},
+ {"HDMI Mixer", "MultiMedia22", "MM_DL22"},
+ {"HDMI Mixer", "MultiMedia23", "MM_DL23"},
+ {"HDMI Mixer", "MultiMedia24", "MM_DL24"},
+ {"HDMI Mixer", "MultiMedia25", "MM_DL25"},
{"HDMI", NULL, "HDMI Mixer"},
{"DISPLAY_PORT Mixer", "MultiMedia1", "MM_DL1"},
@@ -12575,6 +12716,11 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SLIMBUS_6_RX Audio Mixer", "MultiMedia14", "MM_DL14"},
{"SLIMBUS_6_RX Audio Mixer", "MultiMedia15", "MM_DL15"},
{"SLIMBUS_6_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"SLIMBUS_6_RX Audio Mixer", "MultiMedia21", "MM_DL21"},
+ {"SLIMBUS_6_RX Audio Mixer", "MultiMedia22", "MM_DL22"},
+ {"SLIMBUS_6_RX Audio Mixer", "MultiMedia23", "MM_DL23"},
+ {"SLIMBUS_6_RX Audio Mixer", "MultiMedia24", "MM_DL24"},
+ {"SLIMBUS_6_RX Audio Mixer", "MultiMedia25", "MM_DL25"},
{"SLIMBUS_6_RX", NULL, "SLIMBUS_6_RX Audio Mixer"},
{"SLIMBUS_7_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -12593,6 +12739,11 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SLIMBUS_7_RX Audio Mixer", "MultiMedia14", "MM_DL14"},
{"SLIMBUS_7_RX Audio Mixer", "MultiMedia15", "MM_DL15"},
{"SLIMBUS_7_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"SLIMBUS_7_RX Audio Mixer", "MultiMedia21", "MM_DL21"},
+ {"SLIMBUS_7_RX Audio Mixer", "MultiMedia22", "MM_DL22"},
+ {"SLIMBUS_7_RX Audio Mixer", "MultiMedia23", "MM_DL23"},
+ {"SLIMBUS_7_RX Audio Mixer", "MultiMedia24", "MM_DL24"},
+ {"SLIMBUS_7_RX Audio Mixer", "MultiMedia25", "MM_DL25"},
{"SLIMBUS_7_RX", NULL, "SLIMBUS_7_RX Audio Mixer"},
{"USB_AUDIO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -14460,6 +14611,10 @@ static const struct snd_soc_dapm_route intercon[] = {
{"QUAT_TDM_RX_0 Port Mixer", "AFE_PCM_TX", "PCM_TX"},
{"QUAT_TDM_RX_0 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
{"QUAT_TDM_RX_0 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
+ {"QUAT_TDM_RX_0 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"QUAT_TDM_RX_0 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"QUAT_TDM_RX_0 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"QUAT_TDM_RX_0 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
{"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"},
{"QUAT_TDM_RX_0 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"},
@@ -14478,6 +14633,10 @@ static const struct snd_soc_dapm_route intercon[] = {
{"QUAT_TDM_RX_1 Port Mixer", "AFE_PCM_TX", "PCM_TX"},
{"QUAT_TDM_RX_1 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
{"QUAT_TDM_RX_1 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
+ {"QUAT_TDM_RX_1 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"QUAT_TDM_RX_1 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"QUAT_TDM_RX_1 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"QUAT_TDM_RX_1 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
{"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"},
{"QUAT_TDM_RX_1 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"},
@@ -14496,6 +14655,10 @@ static const struct snd_soc_dapm_route intercon[] = {
{"QUAT_TDM_RX_2 Port Mixer", "AFE_PCM_TX", "PCM_TX"},
{"QUAT_TDM_RX_2 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
{"QUAT_TDM_RX_2 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
+ {"QUAT_TDM_RX_2 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"QUAT_TDM_RX_2 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"QUAT_TDM_RX_2 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"QUAT_TDM_RX_2 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
{"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"},
{"QUAT_TDM_RX_2 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"},
@@ -14514,6 +14677,10 @@ static const struct snd_soc_dapm_route intercon[] = {
{"QUAT_TDM_RX_3 Port Mixer", "AFE_PCM_TX", "PCM_TX"},
{"QUAT_TDM_RX_3 Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
{"QUAT_TDM_RX_3 Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
+ {"QUAT_TDM_RX_3 Port Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"QUAT_TDM_RX_3 Port Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"QUAT_TDM_RX_3 Port Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"QUAT_TDM_RX_3 Port Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
{"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"},
{"QUAT_TDM_RX_3 Port Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"},
@@ -15486,6 +15653,93 @@ static struct snd_pcm_ops msm_routing_pcm_ops = {
.prepare = msm_pcm_routing_prepare,
};
+int msm_routing_set_downmix_control_data(int be_id, int session_id,
+ struct asm_stream_pan_ctrl_params *dnmix_param)
+{
+ int i, rc = 0;
+ struct adm_pspd_param_data_t data;
+ struct audproc_chmixer_param_coeff dnmix_cfg;
+ uint16_t variable_payload = 0;
+ char *adm_params = NULL;
+ int port_id, copp_idx = 0;
+ uint32_t params_length = 0;
+
+ if (be_id >= MSM_BACKEND_DAI_MAX) {
+ rc = -EINVAL;
+ return rc;
+ }
+ port_id = msm_bedais[be_id].port_id;
+ copp_idx = adm_get_default_copp_idx(port_id);
+ pr_debug("%s: port_id - %d, copp_idx %d session id - %d\n",
+ __func__, port_id, copp_idx, session_id);
+
+ variable_payload = dnmix_param->num_output_channels * sizeof(uint16_t)+
+ dnmix_param->num_input_channels * sizeof(uint16_t) +
+ dnmix_param->num_output_channels * sizeof(uint16_t) *
+ dnmix_param->num_input_channels * sizeof(uint16_t);
+ i = (variable_payload % sizeof(uint32_t));
+ variable_payload += (i == 0) ? 0 : sizeof(uint32_t) - i;
+
+ params_length = variable_payload +
+ sizeof(struct adm_pspd_param_data_t) +
+ sizeof(struct audproc_chmixer_param_coeff);
+ adm_params = kzalloc(params_length, GFP_KERNEL);
+ if (!adm_params) {
+ rc = -ENOMEM;
+ goto end;
+ }
+
+ data.module_id = AUDPROC_MODULE_ID_CHMIXER;
+ data.param_id = AUDPROC_CHMIXER_PARAM_ID_COEFF;
+ data.param_size = sizeof(struct audproc_chmixer_param_coeff) +
+ variable_payload;
+ data.reserved = 0;
+ memcpy((u8 *)adm_params, &data, sizeof(struct adm_pspd_param_data_t));
+
+ dnmix_cfg.index = 0;
+ dnmix_cfg.num_output_channels = dnmix_param->num_output_channels;
+ dnmix_cfg.num_input_channels = dnmix_param->num_input_channels;
+ memcpy(((u8 *)adm_params +
+ sizeof(struct adm_pspd_param_data_t)),
+ &dnmix_cfg, sizeof(struct audproc_chmixer_param_coeff));
+
+ memcpy(((u8 *)adm_params +
+ sizeof(struct adm_pspd_param_data_t) +
+ sizeof(struct audproc_chmixer_param_coeff)),
+ dnmix_param->output_channel_map,
+ dnmix_param->num_output_channels * sizeof(uint16_t));
+ memcpy(((u8 *)adm_params +
+ sizeof(struct adm_pspd_param_data_t) +
+ sizeof(struct audproc_chmixer_param_coeff) +
+ dnmix_param->num_output_channels * sizeof(uint16_t)),
+ dnmix_param->input_channel_map,
+ dnmix_param->num_input_channels * sizeof(uint16_t));
+ memcpy(((u8 *)adm_params +
+ sizeof(struct adm_pspd_param_data_t) +
+ sizeof(struct audproc_chmixer_param_coeff) +
+ (dnmix_param->num_output_channels * sizeof(uint16_t)) +
+ (dnmix_param->num_input_channels * sizeof(uint16_t))),
+ dnmix_param->gain,
+ (dnmix_param->num_output_channels * sizeof(uint16_t)) *
+ (dnmix_param->num_input_channels * sizeof(uint16_t)));
+
+ if (params_length) {
+ rc = adm_set_pspd_matrix_params(port_id,
+ copp_idx,
+ session_id,
+ adm_params,
+ params_length);
+ if (rc) {
+ pr_err("%s: send params failed rc=%d\n", __func__, rc);
+ rc = -EINVAL;
+ }
+ }
+end:
+ kfree(adm_params);
+ return rc;
+}
+
+
/* Not used but frame seems to require it */
static int msm_routing_probe(struct snd_soc_platform *platform)
{
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
index 19e726001d25..fa948abd1b4c 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -193,6 +193,11 @@ enum {
MSM_FRONTEND_DAI_MULTIMEDIA18,
MSM_FRONTEND_DAI_MULTIMEDIA19,
MSM_FRONTEND_DAI_MULTIMEDIA20,
+ MSM_FRONTEND_DAI_MULTIMEDIA21,
+ MSM_FRONTEND_DAI_MULTIMEDIA22,
+ MSM_FRONTEND_DAI_MULTIMEDIA23,
+ MSM_FRONTEND_DAI_MULTIMEDIA24,
+ MSM_FRONTEND_DAI_MULTIMEDIA25,
MSM_FRONTEND_DAI_CS_VOICE,
MSM_FRONTEND_DAI_VOIP,
MSM_FRONTEND_DAI_AFE_RX,
@@ -218,8 +223,8 @@ enum {
MSM_FRONTEND_DAI_MAX,
};
-#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA20 + 1)
-#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA20
+#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA25 + 1)
+#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA25
enum {
MSM_BACKEND_DAI_PRI_I2S_RX = 0,
@@ -483,4 +488,6 @@ int msm_pcm_routing_reg_stream_app_type_cfg(
int msm_pcm_routing_get_stream_app_type_cfg(
int fedai_id, int session_type, int *be_id,
struct msm_pcm_stream_app_type_cfg *cfg_data);
+int msm_routing_set_downmix_control_data(int be_id, int session_id,
+ struct asm_stream_pan_ctrl_params *pan_param);
#endif /*_MSM_PCM_H*/
diff --git a/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c b/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c
index cac28f43e5ae..65f5167d9dee 100644
--- a/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c
+++ b/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c
@@ -298,11 +298,11 @@ int msm_qti_pp_send_stereo_to_custom_stereo_cmd(int port_id, int copp_idx,
*update_params_value16++ = op_FR_ip_FR_weight;
avail_length = avail_length - (4 * sizeof(uint16_t));
if (params_length) {
- rc = adm_set_stereo_to_custom_stereo(port_id,
- copp_idx,
- session_id,
- params_value,
- params_length);
+ rc = adm_set_pspd_matrix_params(port_id,
+ copp_idx,
+ session_id,
+ params_value,
+ params_length);
if (rc) {
pr_err("%s: send params failed rc=%d\n", __func__, rc);
kfree(params_value);
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index 28aaf2172221..4aad16db3e0f 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -781,9 +781,9 @@ fail_cmd:
return ret;
}
-int adm_set_stereo_to_custom_stereo(int port_id, int copp_idx,
- unsigned int session_id, char *params,
- uint32_t params_length)
+int adm_set_pspd_matrix_params(int port_id, int copp_idx,
+ unsigned int session_id, char *params,
+ uint32_t params_length)
{
struct adm_cmd_set_pspd_mtmx_strtr_params_v5 *adm_params = NULL;
int sz, rc = 0, port_idx;
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 44e5b01b1ccb..d3cff9fccf59 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -44,7 +44,7 @@
#define TRUE 0x01
#define FALSE 0x00
#define SESSION_MAX 8
-
+#define ASM_MAX_CHANNELS 8
enum {
ASM_TOPOLOGY_CAL = 0,
ASM_CUSTOM_TOP_CAL,
@@ -7419,6 +7419,296 @@ int q6asm_set_softvolume_v2(struct audio_client *ac,
return __q6asm_set_softvolume(ac, softvol_param, instance);
}
+int q6asm_set_vol_ctrl_gain_pair(struct audio_client *ac,
+ struct asm_stream_pan_ctrl_params *pan_param)
+{
+ int sz = 0;
+ int rc = 0;
+ int i = 0;
+ int32_t ch = 0;
+ struct apr_hdr hdr;
+ struct audproc_volume_ctrl_channel_type_gain_pair
+ gain_data[ASM_MAX_CHANNELS];
+ struct asm_stream_cmd_set_pp_params_v2 payload_params;
+ struct asm_stream_param_data_v2 data;
+ uint16_t *asm_params = NULL;
+
+ if (ac == NULL) {
+ pr_err("%s: ac is NULL\n", __func__);
+ rc = -EINVAL;
+ goto fail;
+ }
+ if (ac->apr == NULL) {
+ dev_err(ac->dev, "%s: ac apr handle NULL\n", __func__);
+ rc = -EINVAL;
+ goto fail;
+ }
+
+ sz = sizeof(struct apr_hdr) +
+ sizeof(struct asm_stream_cmd_set_pp_params_v2) +
+ sizeof(struct asm_stream_param_data_v2) +
+ sizeof(uint32_t) +
+ (sizeof(struct audproc_volume_ctrl_channel_type_gain_pair) *
+ ASM_MAX_CHANNELS);
+ asm_params = kzalloc(sz, GFP_KERNEL);
+ if (!asm_params) {
+ rc = -ENOMEM;
+ goto fail;
+ }
+
+ q6asm_add_hdr_async(ac, &hdr, sz, TRUE);
+ atomic_set(&ac->cmd_state_pp, -1);
+
+ hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
+ memcpy(((u8 *)asm_params), &hdr, sizeof(struct apr_hdr));
+
+ payload_params.data_payload_addr_lsw = 0;
+ payload_params.data_payload_addr_msw = 0;
+ payload_params.mem_map_handle = 0;
+ payload_params.data_payload_size =
+ sizeof(struct asm_stream_param_data_v2) +
+ sizeof(uint32_t) +
+ (sizeof(struct audproc_volume_ctrl_channel_type_gain_pair) *
+ ASM_MAX_CHANNELS);
+ memcpy(((u8 *)asm_params + sizeof(struct apr_hdr)),
+ &payload_params,
+ sizeof(struct asm_stream_cmd_set_pp_params_v2));
+
+ data.module_id = AUDPROC_MODULE_ID_VOL_CTRL;
+ data.param_id = AUDPROC_PARAM_ID_MULTICHANNEL_GAIN;
+ data.param_size = sizeof(uint32_t) +
+ (sizeof(struct audproc_volume_ctrl_channel_type_gain_pair) *
+ ASM_MAX_CHANNELS);
+ data.reserved = 0;
+ memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
+ sizeof(struct asm_stream_cmd_set_pp_params_v2)),
+ &data, sizeof(struct asm_stream_param_data_v2));
+
+ ch = pan_param->num_output_channels;
+ memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
+ sizeof(struct asm_stream_cmd_set_pp_params_v2) +
+ sizeof(struct asm_stream_param_data_v2)),
+ &ch,
+ sizeof(uint32_t));
+
+ memset(gain_data, 0,
+ ASM_MAX_CHANNELS *
+ sizeof(struct audproc_volume_ctrl_channel_type_gain_pair));
+ for (i = 0; i < pan_param->num_output_channels; i++) {
+ gain_data[i].channel_type =
+ pan_param->output_channel_map[i];
+ gain_data[i].gain = pan_param->gain[i];
+ }
+ memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
+ sizeof(struct asm_stream_cmd_set_pp_params_v2) +
+ sizeof(struct asm_stream_param_data_v2) +
+ sizeof(uint32_t)),
+ gain_data,
+ ASM_MAX_CHANNELS *
+ sizeof(struct audproc_volume_ctrl_channel_type_gain_pair));
+
+ rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params);
+ if (rc < 0) {
+ pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
+ __func__, data.param_id, rc);
+ goto done;
+ }
+
+ rc = wait_event_timeout(ac->cmd_wait,
+ (atomic_read(&ac->cmd_state_pp) >= 0), 5 * HZ);
+ if (!rc) {
+ pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__,
+ data.param_id);
+ rc = -EINVAL;
+ goto done;
+ }
+ if (atomic_read(&ac->cmd_state_pp) > 0) {
+ pr_err("%s: DSP returned error[%d], set-params paramid[0x%x]\n",
+ __func__, atomic_read(&ac->cmd_state_pp),
+ data.param_id);
+ rc = -EINVAL;
+ goto done;
+ }
+ rc = 0;
+done:
+ kfree(asm_params);
+fail:
+ return rc;
+}
+
+int q6asm_set_mfc_panning_params(struct audio_client *ac,
+ struct asm_stream_pan_ctrl_params *pan_param)
+{
+ int sz, rc, i;
+ struct audproc_mfc_output_media_fmt mfc_cfg;
+ struct apr_hdr hdr;
+ struct asm_stream_cmd_set_pp_params_v2 payload_params;
+ struct asm_stream_param_data_v2 data;
+ struct audproc_chmixer_param_coeff pan_cfg;
+ uint16_t variable_payload = 0;
+ uint16_t *asm_params = NULL;
+
+ sz = rc = i = 0;
+ if (ac == NULL) {
+ pr_err("%s: ac handle NULL\n", __func__);
+ rc = -EINVAL;
+ goto fail_cmd1;
+ }
+ if (ac->apr == NULL) {
+ pr_err("%s: ac apr handle NULL\n", __func__);
+ rc = -EINVAL;
+ goto fail_cmd1;
+ }
+
+ sz = sizeof(struct audproc_mfc_output_media_fmt);
+ q6asm_add_hdr_async(ac, &mfc_cfg.params.hdr, sz, TRUE);
+ atomic_set(&ac->cmd_state_pp, -1);
+ mfc_cfg.params.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
+ mfc_cfg.params.payload_addr_lsw = 0;
+ mfc_cfg.params.payload_addr_msw = 0;
+ mfc_cfg.params.mem_map_handle = 0;
+ mfc_cfg.params.payload_size = sizeof(mfc_cfg) - sizeof(mfc_cfg.params);
+ mfc_cfg.data.module_id = AUDPROC_MODULE_ID_MFC;
+ mfc_cfg.data.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT;
+ mfc_cfg.data.param_size = mfc_cfg.params.payload_size -
+ sizeof(mfc_cfg.data);
+ mfc_cfg.data.reserved = 0;
+ mfc_cfg.sampling_rate = 0;
+ mfc_cfg.bits_per_sample = 0;
+ mfc_cfg.num_channels = pan_param->num_output_channels;
+ for (i = 0; i < mfc_cfg.num_channels; i++)
+ mfc_cfg.channel_type[i] = pan_param->output_channel_map[i];
+
+ rc = apr_send_pkt(ac->apr, (uint32_t *) &mfc_cfg);
+ if (rc < 0) {
+ pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
+ __func__, mfc_cfg.data.param_id, rc);
+ rc = -EINVAL;
+ goto fail_cmd1;
+ }
+
+ rc = wait_event_timeout(ac->cmd_wait,
+ (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ);
+ if (!rc) {
+ pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__,
+ mfc_cfg.data.param_id);
+ rc = -ETIMEDOUT;
+ goto fail_cmd1;
+ }
+ if (atomic_read(&ac->cmd_state_pp) > 0) {
+ pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n",
+ __func__, adsp_err_get_err_str(
+ atomic_read(&ac->cmd_state_pp)),
+ mfc_cfg.data.param_id);
+ rc = adsp_err_get_lnx_err_code(
+ atomic_read(&ac->cmd_state_pp));
+ goto fail_cmd1;
+ }
+
+ variable_payload = pan_param->num_output_channels * sizeof(uint16_t)+
+ pan_param->num_input_channels * sizeof(uint16_t) +
+ pan_param->num_output_channels * sizeof(uint16_t) *
+ pan_param->num_input_channels * sizeof(uint16_t);
+ i = (variable_payload % sizeof(uint32_t));
+ variable_payload += (i == 0) ? 0 : sizeof(uint32_t) - i;
+ sz = sizeof(struct apr_hdr) +
+ sizeof(struct asm_stream_cmd_set_pp_params_v2) +
+ sizeof(struct asm_stream_param_data_v2) +
+ sizeof(struct audproc_chmixer_param_coeff) +
+ variable_payload;
+
+ asm_params = kzalloc(sz, GFP_KERNEL);
+ if (!asm_params) {
+ rc = -ENOMEM;
+ goto fail_cmd1;
+ }
+
+ q6asm_add_hdr_async(ac, &hdr, sz, TRUE);
+ atomic_set(&ac->cmd_state_pp, -1);
+ hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
+ memcpy(((u8 *)asm_params), &hdr, sizeof(struct apr_hdr));
+
+ payload_params.data_payload_addr_lsw = 0;
+ payload_params.data_payload_addr_msw = 0;
+ payload_params.mem_map_handle = 0;
+ payload_params.data_payload_size =
+ sizeof(struct audproc_chmixer_param_coeff) +
+ variable_payload + sizeof(struct asm_stream_param_data_v2);
+ memcpy(((u8 *)asm_params + sizeof(struct apr_hdr)),
+ &payload_params,
+ sizeof(struct asm_stream_cmd_set_pp_params_v2));
+
+ data.module_id = AUDPROC_MODULE_ID_MFC;
+ data.param_id = AUDPROC_CHMIXER_PARAM_ID_COEFF;
+ data.param_size = sizeof(struct audproc_chmixer_param_coeff) +
+ variable_payload;
+ data.reserved = 0;
+ memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
+ sizeof(struct asm_stream_cmd_set_pp_params_v2)),
+ &data, sizeof(struct asm_stream_param_data_v2));
+
+ pan_cfg.index = 0;
+ pan_cfg.num_output_channels = pan_param->num_output_channels;
+ pan_cfg.num_input_channels = pan_param->num_input_channels;
+ memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
+ sizeof(struct asm_stream_cmd_set_pp_params_v2) +
+ sizeof(struct asm_stream_param_data_v2)),
+ &pan_cfg, sizeof(struct audproc_chmixer_param_coeff));
+ memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
+ sizeof(struct asm_stream_cmd_set_pp_params_v2) +
+ sizeof(struct asm_stream_param_data_v2) +
+ sizeof(struct audproc_chmixer_param_coeff)),
+ pan_param->output_channel_map,
+ pan_param->num_output_channels * sizeof(uint16_t));
+ memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
+ sizeof(struct asm_stream_cmd_set_pp_params_v2) +
+ sizeof(struct asm_stream_param_data_v2) +
+ sizeof(struct audproc_chmixer_param_coeff) +
+ pan_param->num_output_channels * sizeof(uint16_t)),
+ pan_param->input_channel_map,
+ pan_param->num_input_channels * sizeof(uint16_t));
+ memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
+ sizeof(struct asm_stream_cmd_set_pp_params_v2) +
+ sizeof(struct asm_stream_param_data_v2) +
+ sizeof(struct audproc_chmixer_param_coeff) +
+ (pan_param->num_output_channels * sizeof(uint16_t)) +
+ (pan_param->num_input_channels * sizeof(uint16_t))),
+ pan_param->gain,
+ (pan_param->num_output_channels * sizeof(uint16_t)) *
+ (pan_param->num_input_channels * sizeof(uint16_t)));
+
+ rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params);
+ if (rc < 0) {
+ pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
+ __func__, data.param_id, rc);
+ rc = -EINVAL;
+ goto fail_cmd2;
+ }
+
+ rc = wait_event_timeout(ac->cmd_wait,
+ (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ);
+ if (!rc) {
+ pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__,
+ data.param_id);
+ rc = -ETIMEDOUT;
+ goto fail_cmd2;
+ }
+ if (atomic_read(&ac->cmd_state_pp) > 0) {
+ pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n",
+ __func__, adsp_err_get_err_str(
+ atomic_read(&ac->cmd_state_pp)),
+ data.param_id);
+ rc = adsp_err_get_lnx_err_code(
+ atomic_read(&ac->cmd_state_pp));
+ goto fail_cmd2;
+ }
+ rc = 0;
+fail_cmd2:
+ kfree(asm_params);
+fail_cmd1:
+ return rc;
+}
+
int q6asm_equalizer(struct audio_client *ac, void *eq_p)
{
struct asm_eq_params eq;