summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/cpus.txt1
-rw-r--r--Documentation/devicetree/bindings/sound/qcom-audio-dev.txt11
-rw-r--r--arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-coresight-v3.dtsi829
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-audio.dtsi9
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/vplatform-lfv-msm8996.dts14
-rw-r--r--arch/arm64/configs/msm-auto-perf_defconfig31
-rw-r--r--arch/arm64/configs/msm-auto_defconfig31
-rw-r--r--drivers/char/diag/diag_dci.c19
-rw-r--r--drivers/char/diag/diag_debugfs.c13
-rw-r--r--drivers/char/diag/diagchar.h6
-rw-r--r--drivers/char/diag/diagchar_core.c44
-rw-r--r--drivers/char/diag/diagfwd.c5
-rw-r--r--drivers/char/diag/diagfwd_cntl.c341
-rw-r--r--drivers/char/diag/diagfwd_cntl.h54
-rw-r--r--drivers/cpuidle/lpm-levels.c26
-rw-r--r--drivers/crypto/msm/qcedev.c12
-rw-r--r--drivers/firmware/psci.c13
-rw-r--r--drivers/gpu/drm/msm/msm_gem_submit.c10
-rw-r--r--drivers/hwtracing/coresight/coresight-stm.c3
-rw-r--r--drivers/iommu/iommu-debug.c394
-rw-r--r--drivers/iommu/iommu-debug.h23
-rw-r--r--drivers/iommu/iommu.c3
-rw-r--r--drivers/media/platform/msm/ais/pproc/cpp/msm_cpp.c7
-rw-r--r--drivers/media/platform/msm/ais/sensor/csiphy/msm_csiphy.c90
-rw-r--r--drivers/media/platform/msm/ais/sensor/csiphy/msm_csiphy.h4
-rw-r--r--drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c89
-rw-r--r--drivers/media/platform/msm/camera_v2/common/cam_smmu_api.h26
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c6
-rw-r--r--drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c153
-rw-r--r--drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h7
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/csiphy/include/msm_csiphy_5_0_1_hwreg.h2
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/csiphy/include/msm_csiphy_5_0_hwreg.h2
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c18
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h2
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c7
-rw-r--r--drivers/mfd/wcd9xxx-irq.c30
-rw-r--r--drivers/misc/qcom/qdsp6v2/audio_utils_aio.c3
-rw-r--r--drivers/pinctrl/qcom/pinctrl-lpi.c5
-rw-r--r--drivers/platform/msm/mhi/mhi_bhi.c2
-rw-r--r--drivers/platform/msm/mhi/mhi_main.c11
-rw-r--r--drivers/power/supply/qcom/qpnp-smb2.c8
-rw-r--r--drivers/power/supply/qcom/smb-lib.c122
-rw-r--r--drivers/power/supply/qcom/smb-lib.h3
-rw-r--r--drivers/power/supply/qcom/smb-reg.h2
-rw-r--r--drivers/power/supply/qcom/smb138x-charger.c2
-rw-r--r--drivers/soc/qcom/qdsp6v2/apr.c15
-rw-r--r--drivers/usb/pd/policy_engine.c18
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.c2
-rw-r--r--include/linux/msm_mhi.h137
-rw-r--r--include/linux/sde_io_util.h2
-rw-r--r--include/sound/apr_audio-v2.h5
-rw-r--r--include/sound/q6adm-v2.h1
-rw-r--r--sound/soc/codecs/msm_sdw/msm-sdw-tables.c97
-rw-r--r--sound/soc/codecs/msm_sdw/msm_sdw.h1
-rw-r--r--sound/soc/codecs/msm_sdw/msm_sdw_cdc.c4
-rw-r--r--sound/soc/codecs/msm_sdw/msm_sdw_regmap.c8
-rw-r--r--sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c4
-rw-r--r--sound/soc/codecs/sdm660_cdc/msm-cdc-common.h3
-rw-r--r--sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c29
-rw-r--r--sound/soc/codecs/sdm660_cdc/sdm660-regmap.c137
-rw-r--r--sound/soc/codecs/wcd934x/wcd934x.c46
-rw-r--r--sound/soc/msm/apq8096-auto.c6
-rw-r--r--sound/soc/msm/msm-dai-fe.c2
-rw-r--r--sound/soc/msm/msm8998.c31
-rw-r--r--sound/soc/msm/qdsp6v2/Makefile2
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c14
-rw-r--r--sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c971
-rw-r--r--sound/soc/msm/qdsp6v2/q6adm.c10
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c56
75 files changed, 3073 insertions, 1043 deletions
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index 9a9c045dbf6a..0d7034e20d8d 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -190,6 +190,7 @@ nodes to be present and contain the properties described below.
"allwinner,sun6i-a31"
"allwinner,sun8i-a23"
"arm,psci"
+ "psci"
"brcm,brahma-b15"
"marvell,armada-375-smp"
"marvell,armada-380-smp"
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index dec5442b33d6..38e056cdc0ee 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -182,6 +182,12 @@ Optional properties:
- qcom,msm-pcm-loopback-low-latency : Flag indicating whether
the device node is of type low latency.
+* msm-transcode-loopback
+
+Required properties:
+
+ - compatible : "qcom,msm-transcode-loopback"
+
* msm-dai-q6
[First Level Nodes]
@@ -2401,14 +2407,15 @@ Example:
qcom,tasha-mclk-clk-freq = <9600000>;
asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
<&loopback>, <&compress>, <&hostless>,
- <&afe>, <&lsm>, <&routing>, <&cpe>, <&compr>;
+ <&afe>, <&lsm>, <&routing>, <&cpe>, <&compr>,
+ <&trans_loopback>;
asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
"msm-pcm-dsp.2", "msm-voip-dsp",
"msm-pcm-voice", "msm-pcm-loopback",
"msm-compress-dsp", "msm-pcm-hostless",
"msm-pcm-afe", "msm-lsm-client",
"msm-pcm-routing", "msm-cpe-lsm",
- "msm-compr-dsp";
+ "msm-compr-dsp","msm-transcode-loopback";
asoc-cpu = <&dai_hdmi>,
<&sb_0_rx>, <&sb_0_tx>, <&sb_1_rx>, <&sb_1_tx>,
<&sb_2_rx>, <&sb_2_tx>, <&sb_3_rx>, <&sb_3_tx>,
diff --git a/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi b/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi
index ea8fc87c9b67..b7dff4041de0 100644
--- a/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi
+++ b/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi
@@ -627,14 +627,14 @@
asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
<&loopback>, <&compress>, <&hostless>,
- <&afe>, <&lsm>, <&routing>, <&compr>,
+ <&afe>, <&lsm>, <&routing>, <&pcmnoirq>,
<&loopback1>;
asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
"msm-pcm-dsp.2", "msm-voip-dsp",
"msm-pcm-voice", "msm-pcm-loopback",
"msm-compress-dsp", "msm-pcm-hostless",
"msm-pcm-afe", "msm-lsm-client",
- "msm-pcm-routing", "msm-compr-dsp",
+ "msm-pcm-routing", "msm-pcm-dsp-noirq",
"msm-pcm-loopback.1";
asoc-cpu = <&dai_pri_auxpcm>, <&dai_sec_auxpcm>, <&dai_hdmi>,
<&dai_mi2s_sec>, <&dai_mi2s>, <&dai_mi2s_quat>,
diff --git a/arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi b/arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi
index d4962df321ed..7fce7606720c 100644
--- a/arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi
@@ -85,6 +85,10 @@
compatible = "qcom,msm-pcm-loopback";
};
+ trans_loopback: qcom,msm-transcode-loopback {
+ compatible = "qcom,msm-transcode-loopback";
+ };
+
qcom,msm-dai-mi2s {
compatible = "qcom,msm-dai-mi2s";
dai_mi2s0: qcom,msm-dai-q6-mi2s-prim {
diff --git a/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi b/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi
index 31cfa0ddce43..382f4182b32d 100644
--- a/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi
@@ -926,14 +926,14 @@
asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
<&loopback>, <&compress>, <&hostless>,
- <&afe>, <&lsm>, <&routing>, <&compr>,
+ <&afe>, <&lsm>, <&routing>, <&pcmnoirq>,
<&loopback1>;
asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
"msm-pcm-dsp.2", "msm-voip-dsp",
"msm-pcm-voice", "msm-pcm-loopback",
"msm-compress-dsp", "msm-pcm-hostless",
"msm-pcm-afe", "msm-lsm-client",
- "msm-pcm-routing", "msm-compr-dsp",
+ "msm-pcm-routing", "msm-pcm-dsp-noirq",
"msm-pcm-loopback.1";
asoc-cpu = <&dai_pri_auxpcm>, <&dai_sec_auxpcm>, <&dai_hdmi>,
<&dai_mi2s_sec>, <&dai_mi2s>, <&dai_mi2s_quat>,
diff --git a/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi
index b03323eb5323..59ca2ade4a76 100644
--- a/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi
@@ -653,14 +653,14 @@
asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
<&loopback>, <&compress>, <&hostless>,
- <&afe>, <&lsm>, <&routing>, <&compr>,
+ <&afe>, <&lsm>, <&routing>, <&pcmnoirq>,
<&loopback1>;
asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
"msm-pcm-dsp.2", "msm-voip-dsp",
"msm-pcm-voice", "msm-pcm-loopback",
"msm-compress-dsp", "msm-pcm-hostless",
"msm-pcm-afe", "msm-lsm-client",
- "msm-pcm-routing", "msm-compr-dsp",
+ "msm-pcm-routing", "msm-pcm-dsp-noirq",
"msm-pcm-loopback.1";
asoc-cpu = <&dai_pri_auxpcm>, <&dai_sec_auxpcm>, <&dai_hdmi>,
<&dai_mi2s_sec>, <&dai_mi2s>, <&dai_mi2s_quat>,
diff --git a/arch/arm/boot/dts/qcom/msm8996-coresight-v3.dtsi b/arch/arm/boot/dts/qcom/msm8996-coresight-v3.dtsi
index f9c9d07c3078..90ad4a0319c4 100644
--- a/arch/arm/boot/dts/qcom/msm8996-coresight-v3.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-coresight-v3.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015,2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -12,36 +12,44 @@
&soc {
tmc_etr: tmc@3028000 {
- compatible = "arm,coresight-tmc";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b961>;
+
reg = <0x3028000 0x1000>,
<0x3084000 0x15000>;
reg-names = "tmc-base", "bam-base";
+
interrupts = <0 270 0>;
interrupt-names = "byte-cntr-irq";
- qcom,memory-size = <0x400000>;
- qcom,tmc-flush-powerdown;
- qcom,sg-enable;
- qcom,force-reg-dump;
+ arm,buffer-size = <0x400000>;
+ arm,sg-enable;
+
+ coresight-ctis = <&cti0 &cti8>;
- coresight-id = <0>;
coresight-name = "coresight-tmc-etr";
coresight-nr-inports = <1>;
- coresight-ctis = <&cti0 &cti8>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
- clock-names = "core_clk", "core_a_clk";
+ clock-names = "apb_pclk", "core_a_clk";
+
+ port{
+ tmc_etr_in_replicator: endpoint {
+ slave-mode;
+ remote-endpoint = <&replicator_out_tmc_etr>;
+ };
+ };
};
tpiu: tpiu@3020000 {
- compatible = "arm,coresight-tpiu";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b912>;
+
reg = <0x3020000 0x1000>;
reg-names = "tpiu-base";
- coresight-id = <1>;
coresight-name = "coresight-tpiu";
- coresight-nr-inports = <1>;
vdd-supply = <&pm8994_l21>;
qcom,vdd-voltage-level = <2950000 2950000>;
@@ -57,182 +65,443 @@
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
- clock-names = "core_clk", "core_a_clk";
+ clock-names = "apb_pclk", "core_a_clk";
+
+ port{
+ tpiu_in_replicator: endpoint {
+ slave-mode;
+ remote-endpoint = <&replicator_out_tpiu>;
+ };
+ };
};
replicator: replicator@3026000 {
- compatible = "qcom,coresight-replicator";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b909>;
+
reg = <0x3026000 0x1000>;
reg-names = "replicator-base";
- coresight-id = <2>;
coresight-name = "coresight-replicator";
- coresight-nr-inports = <1>;
- coresight-outports = <0 1>;
- coresight-child-list = <&tmc_etr &tpiu>;
- coresight-child-ports = <0 0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
- clock-names = "core_clk", "core_a_clk";
+ clock-names = "apb_clk", "core_a_clk";
+
+ ports{
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ replicator_out_tmc_etr:endpoint {
+ remote-endpoint =
+ <&tmc_etr_in_replicator>;
+ };
+ };
+ port@1 {
+ reg = <1>;
+ replicator_out_tpiu:endpoint {
+ remote-endpoint =
+ <&tpiu_in_replicator>;
+ };
+ };
+ port@2 {
+ reg = <0>;
+ replicator_in_tmc_etf:endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&tmc_etf_out_replicator>;
+ };
+ };
+ };
};
tmc_etf: tmc@3027000 {
- compatible = "arm,coresight-tmc";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b961>;
+
reg = <0x3027000 0x1000>;
reg-names = "tmc-base";
- coresight-id = <3>;
- coresight-name = "coresight-tmc-etf";
- coresight-nr-inports = <1>;
- coresight-outports = <0>;
- coresight-child-list = <&replicator>;
- coresight-child-ports = <0>;
- coresight-default-sink;
coresight-ctis = <&cti0 &cti8>;
+ coresight-name = "coresight-tmc-etf";
+
+ arm,default-sink;
+
qcom,tmc-flush-powerdown;
qcom,force-reg-dump;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
- clock-names = "core_clk", "core_a_clk";
+ clock-names = "apb_pclk", "core_a_clk";
+
+ ports{
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ tmc_etf_out_replicator:endpoint {
+ remote-endpoint =
+ <&replicator_in_tmc_etf>;
+ };
+ };
+ port@1 {
+ reg = <0>;
+ tmc_etf_in_funnel_merg:endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&funnel_merg_out_tmc_etf>;
+ };
+ };
+ };
};
funnel_merg: funnel@3025000 {
- compatible = "arm,coresight-funnel";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b908>;
+
reg = <0x3025000 0x1000>;
reg-names = "funnel-base";
- coresight-id = <4>;
coresight-name = "coresight-funnel-merg";
- coresight-nr-inports = <2>;
- coresight-outports = <0>;
- coresight-child-list = <&tmc_etf>;
- coresight-child-ports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
- clock-names = "core_clk", "core_a_clk";
+ clock-names = "apb_pclk", "core_a_clk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ funnel_merg_out_tmc_etf:endpoint {
+ remote-endpoint =
+ <&tmc_etf_in_funnel_merg>;
+ };
+ };
+ port@1 {
+ reg = <0>;
+ funnel_merg_in_funnel_in0:endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&funnel_in0_out_funnel_merg>;
+ };
+ };
+ port@2 {
+ reg = <1>;
+ funnel_merg_in_funnel_in1:endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&funnel_in1_out_funnel_merg>;
+ };
+ };
+ port@3 {
+ reg = <2>;
+ funnel_merg_in_funnel_in2:endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&funnel_in2_out_funnel_merg>;
+ };
+ };
+ };
};
funnel_in0: funnel@3021000 {
- compatible = "arm,coresight-funnel";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b908>;
+
reg = <0x3021000 0x1000>;
reg-names = "funnel-base";
- coresight-id = <5>;
coresight-name = "coresight-funnel-in0";
- coresight-nr-inports = <8>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_merg>;
- coresight-child-ports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
- clock-names = "core_clk", "core_a_clk";
+ clock-names = "apb_pclk", "core_a_clk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ funnel_in0_out_funnel_merg: endpoint {
+ remote-endpoint =
+ <&funnel_merg_in_funnel_in0>;
+ };
+ };
+ port@1 {
+ reg = <0>;
+ funnel_in0_in_rpm_etm0: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&rpm_etm0_out_funnel_in0>;
+ };
+ };
+ port@2 {
+ reg = <1>;
+ funnel_in0_in_funnel_mmss: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&funnel_mmss_out_funnel_in0>;
+ };
+ };
+ port@3 {
+ reg = <2>;
+ funnel_in0_in_audio_etm0: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&audio_etm0_out_funnel_in0>;
+ };
+ };
+ port@4 {
+ reg = <3>;
+ funnel_in0_in_tpda: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&tpda_out_funnel_in0>;
+ };
+ };
+ port@5 {
+ reg = <7>;
+ funnel_in0_in_stm: endpoint {
+ slave-mode;
+ remote-endpoint = <&stm_out_funnel_in0>;
+ };
+ };
+ };
};
funnel_in1: funnel@3022000 {
- compatible = "arm,coresight-funnel";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b908>;
+
reg = <0x3022000 0x1000>;
reg-names = "funnel-base";
- coresight-id = <6>;
coresight-name = "coresight-funnel-in1";
- coresight-nr-inports = <8>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_merg>;
- coresight-child-ports = <1>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
- clock-names = "core_clk", "core_a_clk";
+ clock-names = "apb_pclk", "core_a_clk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ funnel_in1_out_funnel_merg: endpoint {
+ remote-endpoint =
+ <&funnel_merg_in_funnel_in1>;
+ };
+ };
+ port@1 {
+ reg = <6>;
+ funnel_in1_in_funnel_apss_merg: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&funnel_apss_merg_out_funnel_in1>;
+ };
+ };
+ };
};
funnel_in2: funnel@3023000 {
- compatible = "arm,coresight-funnel";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b908>;
+
reg = <0x3023000 0x1000>;
reg-names = "funnel-base";
- coresight-id = <7>;
coresight-name = "coresight-funnel-in2";
- coresight-nr-inports = <8>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_merg>;
- coresight-child-ports = <2>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
- clock-names = "core_clk", "core_a_clk";
+ clock-names = "apb_pclk", "core_a_clk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ funnel_in2_out_funnel_merg: endpoint {
+ remote-endpoint =
+ <&funnel_merg_in_funnel_in2>;
+ };
+ };
+ port@1 {
+ reg = <0>;
+ funnel_in2_in_modem_etm0: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&modem_etm0_out_funnel_in2>;
+ };
+ };
+ };
+
};
funnel_apss_merge: funnel@3bc0000 {
- compatible = "arm,coresight-funnel";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b908>;
+
reg = <0x3bc0000 0x1000>;
reg-names = "funnel-base";
- coresight-id = <8>;
coresight-name = "coresight-funnel-apss-merge";
- coresight-nr-inports = <4>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_in1>;
- coresight-child-ports = <6>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
- clock-names = "core_clk", "core_a_clk";
+ clock-names = "apb_pclk", "core_a_clk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ funnel_apss_merg_out_funnel_in1: endpoint {
+ remote-endpoint =
+ <&funnel_in1_in_funnel_apss_merg>;
+ };
+ };
+ port@1 {
+ reg = <0>;
+ funnel_apss_merg_in_funnel_apss0: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&funnel_apss0_out_funnel_apss_merg>;
+ };
+ };
+ port@2 {
+ reg = <1>;
+ funnel_apss_merg_in_funnel_apss1: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&funnel_apss1_out_funnel_apss_merg>;
+ };
+ };
+ port@3 {
+ reg = <2>;
+ funnel_apss_merg_in_tpda_apss: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&tpda_apss_out_funnel_apss_merg>;
+ };
+ };
+ };
};
funnel_apss0: funnel@39b0000 {
- compatible = "arm,coresight-funnel";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b908>;
+
reg = <0x39b0000 0x1000>;
reg-names = "funnel-base";
- coresight-id = <9>;
coresight-name = "coresight-funnel-apss0";
- coresight-nr-inports = <2>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_apss_merge>;
- coresight-child-ports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
- clock-names = "core_clk", "core_a_clk";
+ clock-names = "apb_pclk", "core_a_clk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ funnel_apss0_out_funnel_apss_merg: endpoint {
+ remote-endpoint =
+ <&funnel_apss_merg_in_funnel_apss0>;
+ };
+ };
+ port@1 {
+ reg = <0>;
+ funnel_apss0_in_etm0: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&etm0_out_funnel_apss0>;
+ };
+ };
+ port@2 {
+ reg = <1>;
+ funnel_apss0_in_etm1: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&etm1_out_funnel_apss0>;
+ };
+ };
+ };
};
funnel_apss1: funnel@3bb0000 {
- compatible = "arm,coresight-funnel";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b908>;
+
reg = <0x3bb0000 0x1000>;
reg-names = "funnel-base";
- coresight-id = <10>;
coresight-name = "coresight-funnel-apss1";
- coresight-nr-inports = <2>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_apss_merge>;
- coresight-child-ports = <1>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
- clock-names = "core_clk", "core_a_clk";
+ clock-names = "apb_pclk", "core_a_clk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ funnel_apss1_out_funnel_apss_merg: endpoint {
+ remote-endpoint =
+ <&funnel_apss_merg_in_funnel_apss1>;
+ };
+ };
+ port@1 {
+ reg = <0>;
+ funnel_apss1_in_etm2: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&etm2_out_funnel_apss1>;
+ };
+ };
+ port@2 {
+ reg = <1>;
+ funnel_apss1_in_etm3: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&etm3_out_funnel_apss1>;
+ };
+ };
+ };
};
funnel_mmss: funnel@3184000 {
- compatible = "arm,coresight-funnel";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b908>;
+
reg = <0x3184000 0x1000>;
reg-names = "funnel-base";
- coresight-id = <11>;
coresight-name = "coresight-funnel-mmss";
- coresight-nr-inports = <8>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_in0>;
- coresight-child-ports = <1>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
- clock-names = "core_clk", "core_a_clk";
+ clock-names = "apb_pclk", "core_a_clk";
+
+ port{
+ funnel_mmss_out_funnel_in0: endpoint {
+ remote-endpoint = <&funnel_in0_in_funnel_mmss>;
+ };
+ };
};
tpda: tpda@3003000 {
@@ -240,12 +509,7 @@
reg = <0x3003000 0x1000>;
reg-names = "tpda-base";
- coresight-id = <13>;
coresight-name = "coresight-tpda";
- coresight-nr-inports = <32>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_in0>;
- coresight-child-ports = <3>;
qcom,tpda-atid = <65>;
qcom,bc-elem-size = <3 32>,
@@ -263,6 +527,66 @@
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
clock-names = "core_clk", "core_a_clk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ tpda_out_funnel_in0: endpoint {
+ remote-endpoint =
+ <&funnel_in0_in_tpda>;
+ };
+ };
+ port@1 {
+ reg = <0>;
+ tpda_in_tpdm_vsense: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&tpdm_vsense_out_tpda>;
+ };
+ };
+ port@2 {
+ reg = <1>;
+ tpda_in_tpdm_dcc: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&tpdm_dcc_out_tpda>;
+ };
+ };
+ port@3 {
+ reg = <2>;
+ tpda_in_tpdm_prng: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&tpdm_prng_out_tpda>;
+ };
+ };
+ port@4 {
+ reg = <3>;
+ tpda_in_tpdm_dsat: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&tpdm_dsat_out_tpda>;
+ };
+ };
+ port@5 {
+ reg = <6>;
+ tpda_in_tpdm_pimem: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&tpdm_pimem_out_tpda>;
+ };
+ };
+ port@6 {
+ reg = <7>;
+ tpda_in_tpdm_hwevents: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&tpdm_hwevents_out_tpda>;
+ };
+ };
+ };
};
tpda_apss: tpda@39e0000 {
@@ -270,12 +594,7 @@
reg = <0x39e0000 0x1000>;
reg-names = "tpda-base";
- coresight-id = <14>;
coresight-name = "coresight-tpda-apss";
- coresight-nr-inports = <32>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_apss_merge>;
- coresight-child-ports = <2>;
qcom,tpda-atid = <66>;
qcom,bc-elem-size = <0 32>,
@@ -285,6 +604,26 @@
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
clock-names = "core_clk", "core_a_clk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ tpda_apss_out_funnel_apss_merg: endpoint {
+ remote-endpoint =
+ <&funnel_apss_merg_in_tpda_apss>;
+ };
+ };
+ port@1 {
+ reg = <0>;
+ tpda_apss_in_tpdm_m4m: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&tpdm_m4m_out_tpda_apss>;
+ };
+ };
+ };
};
tpdm_vsense: tpdm@3038000 {
@@ -292,16 +631,17 @@
reg = <0x3038000 0x1000>;
reg-names = "tpdm-base";
- coresight-id = <15>;
coresight-name = "coresight-tpdm-vsense";
- coresight-nr-inports = <0>;
- coresight-outports = <0>;
- coresight-child-list = <&tpda>;
- coresight-child-ports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
clock-names = "core_clk", "core_a_clk";
+
+ port{
+ tpdm_vsense_out_tpda: endpoint {
+ remote-endpoint = <&tpda_in_tpdm_vsense>;
+ };
+ };
};
tpdm_dcc: tpdm@3054000 {
@@ -309,16 +649,17 @@
reg = <0x3054000 0x1000>;
reg-names = "tpdm-base";
- coresight-id = <16>;
coresight-name = "coresight-tpdm-dcc";
- coresight-nr-inports = <0>;
- coresight-outports = <0>;
- coresight-child-list = <&tpda>;
- coresight-child-ports = <1>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
clock-names = "core_clk", "core_a_clk";
+
+ port{
+ tpdm_dcc_out_tpda: endpoint {
+ remote-endpoint = <&tpda_in_tpdm_dcc>;
+ };
+ };
};
tpdm_prng: tpdm@304c000 {
@@ -326,16 +667,17 @@
reg = <0x304c000 0x1000>;
reg-names = "tpdm-base";
- coresight-id = <17>;
coresight-name = "coresight-tpdm-prng";
- coresight-nr-inports = <0>;
- coresight-outports = <0>;
- coresight-child-list = <&tpda>;
- coresight-child-ports = <2>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
clock-names = "core_clk", "core_a_clk";
+
+ port{
+ tpdm_prng_out_tpda: endpoint {
+ remote-endpoint = <&tpda_in_tpdm_prng>;
+ };
+ };
};
tpdm_dsat: tpdm@3185000 {
@@ -343,16 +685,17 @@
reg = <0x3185000 0x1000>;
reg-names = "tpdm-base";
- coresight-id = <18>;
coresight-name = "coresight-tpdm-dsat";
- coresight-nr-inports = <0>;
- coresight-outports = <0>;
- coresight-child-list = <&tpda>;
- coresight-child-ports = <3>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
clock-names = "core_clk", "core_a_clk";
+
+ port{
+ tpdm_dsat_out_tpda: endpoint {
+ remote-endpoint = <&tpda_in_tpdm_dsat>;
+ };
+ };
};
tpdm_pimem: tpdm@3050000 {
@@ -360,16 +703,17 @@
reg = <0x3050000 0x1000>;
reg-names = "tpdm-base";
- coresight-id = <19>;
coresight-name = "coresight-tpdm-pimem";
- coresight-nr-inports = <0>;
- coresight-outports = <0>;
- coresight-child-list = <&tpda>;
- coresight-child-ports = <6>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
clock-names = "core_clk", "core_a_clk";
+
+ port{
+ tpdm_pimem_out_tpda: endpoint {
+ remote-endpoint = <&tpda_in_tpdm_pimem>;
+ };
+ };
};
tpdm_hwevents: tpdm@3004000 {
@@ -377,16 +721,17 @@
reg = <0x3004000 0x1000>;
reg-names = "tpdm-base";
- coresight-id = <20>;
coresight-name = "coresight-tpdm-hwevents";
- coresight-nr-inports = <0>;
- coresight-outports = <0>;
- coresight-child-list = <&tpda>;
- coresight-child-ports = <7>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
clock-names = "core_clk", "core_a_clk";
+
+ port{
+ tpdm_hwevents_out_tpda: endpoint {
+ remote-endpoint = <&tpda_in_tpdm_hwevents>;
+ };
+ };
};
tpdm_m4m: tpdm@38e0000 {
@@ -394,147 +739,163 @@
reg = <0x38e0000 0x1000>;
reg-names = "tpdm-base";
- coresight-id = <21>;
coresight-name = "coresight-tpdm-m4m";
- coresight-nr-inports = <0>;
- coresight-outports = <0>;
- coresight-child-list = <&tpda_apss>;
- coresight-child-ports = <0>;
qcom,clk-enable;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
clock-names = "core_clk", "core_a_clk";
+
+ port{
+ tpdm_m4m_out_tpda_apss: endpoint {
+ remote-endpoint = <&tpda_apss_in_tpdm_m4m>;
+ };
+ };
};
stm: stm@3002000 {
- compatible = "arm,coresight-stm";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b962>;
+
reg = <0x3002000 0x1000>,
<0x8280000 0x180000>;
reg-names = "stm-base", "stm-data-base";
- coresight-id = <23>;
coresight-name = "coresight-stm";
- coresight-nr-inports = <0>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_in0>;
- coresight-child-ports = <7>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
- clock-names = "core_clk", "core_a_clk";
+ clock-names = "apb_pclk", "core_a_clk";
+
+ port{
+ stm_out_funnel_in0: endpoint {
+ remote-endpoint = <&funnel_in0_in_stm>;
+ };
+ };
};
etm0: etm@3840000 {
- compatible = "arm,coresight-etmv4";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b95d>;
+
reg = <0x3840000 0x1000>;
- reg-names = "etm-base";
+ cpu = <&CPU0>;
- coresight-id = <24>;
coresight-name = "coresight-etm0";
- coresight-nr-inports = <0>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_apss0>;
- coresight-child-ports = <0>;
- coresight-etm-cpu = <&CPU0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
- clock-names = "core_clk", "core_a_clk";
+ clock-names = "apb_pclk", "core_a_clk";
+
+ port{
+ etm0_out_funnel_apss0: endpoint {
+ remote-endpoint = <&funnel_apss0_in_etm0>;
+ };
+ };
};
etm1: etm@3940000 {
- compatible = "arm,coresight-etmv4";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b95d>;
+
reg = <0x3940000 0x1000>;
- reg-names = "etm-base";
+ cpu = <&CPU1>;
- coresight-id = <25>;
coresight-name = "coresight-etm1";
- coresight-nr-inports = <0>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_apss0>;
- coresight-child-ports = <1>;
- coresight-etm-cpu = <&CPU1>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
- clock-names = "core_clk", "core_a_clk";
+ clock-names = "apb_pclk", "core_a_clk";
+
+ port{
+ etm1_out_funnel_apss0: endpoint {
+ remote-endpoint = <&funnel_apss0_in_etm1>;
+ };
+ };
};
etm2: etm@3a40000 {
- compatible = "arm,coresight-etmv4";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b95d>;
+
reg = <0x3a40000 0x1000>;
- reg-names = "etm-base";
+ cpu = <&CPU2>;
- coresight-id = <26>;
coresight-name = "coresight-etm2";
- coresight-nr-inports = <0>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_apss1>;
- coresight-child-ports = <0>;
- coresight-etm-cpu = <&CPU2>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
- clock-names = "core_clk", "core_a_clk";
+ clock-names = "apb_pclk", "core_a_clk";
+
+ port{
+ etm2_out_funnel_apss1: endpoint {
+ remote-endpoint = <&funnel_apss1_in_etm2>;
+ };
+ };
};
etm3: etm@3b40000 {
- compatible = "arm,coresight-etmv4";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b95d>;
+
reg = <0x3b40000 0x1000>;
- reg-names = "etm-base";
+ cpu = <&CPU3>;
- coresight-id = <27>;
coresight-name = "coresight-etm3";
- coresight-nr-inports = <0>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_apss1>;
- coresight-child-ports = <1>;
- coresight-etm-cpu = <&CPU3>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
- clock-names = "core_clk", "core_a_clk";
+ clock-names = "apb_pclk", "core_a_clk";
+
+ port{
+ etm3_out_funnel_apss1: endpoint {
+ remote-endpoint = <&funnel_apss1_in_etm3>;
+ };
+ };
};
audio_etm0 {
compatible = "qcom,coresight-remote-etm";
- coresight-id = <28>;
coresight-name = "coresight-audio-etm0";
- coresight-nr-inports = <0>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_in0>;
- coresight-child-ports = <2>;
qcom,inst-id = <5>;
+
+ port{
+ audio_etm0_out_funnel_in0: endpoint {
+ remote-endpoint = <&funnel_in0_in_audio_etm0>;
+ };
+ };
+
};
rpm_etm0 {
compatible = "qcom,coresight-remote-etm";
- coresight-id = <29>;
coresight-name = "coresight-rpm-etm0";
- coresight-nr-inports = <0>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_in0>;
- coresight-child-ports = <0>;
qcom,inst-id = <4>;
+
+ port{
+ rpm_etm0_out_funnel_in0: endpoint {
+ remote-endpoint = <&funnel_in0_in_rpm_etm0>;
+ };
+ };
};
modem_etm0 {
compatible = "qcom,coresight-remote-etm";
- coresight-id = <30>;
coresight-name = "coresight-modem-etm0";
- coresight-nr-inports = <0>;
- coresight-outports = <0>;
- coresight-child-list = <&funnel_in2>;
- coresight-child-ports = <0>;
qcom,inst-id = <2>;
+
+ port{
+ modem_etm0_out_funnel_in2: endpoint {
+ remote-endpoint = <&funnel_in2_in_modem_etm0>;
+ };
+ };
};
csr: csr@3001000 {
@@ -542,9 +903,7 @@
reg = <0x3001000 0x1000>;
reg-names = "csr-base";
- coresight-id = <31>;
coresight-name = "coresight-csr";
- coresight-nr-inports = <0>;
qcom,blk-size = <1>;
};
@@ -554,9 +913,7 @@
reg = <0x3010000 0x1000>;
reg-names = "cti-base";
- coresight-id = <32>;
coresight-name = "coresight-cti0";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -568,9 +925,7 @@
reg = <0x3011000 0x1000>;
reg-names = "cti-base";
- coresight-id = <33>;
coresight-name = "coresight-cti1";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -582,9 +937,7 @@
reg = <0x3012000 0x1000>;
reg-names = "cti-base";
- coresight-id = <34>;
coresight-name = "coresight-cti2";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -596,9 +949,7 @@
reg = <0x3013000 0x1000>;
reg-names = "cti-base";
- coresight-id = <35>;
coresight-name = "coresight-cti3";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -610,9 +961,7 @@
reg = <0x3014000 0x1000>;
reg-names = "cti-base";
- coresight-id = <36>;
coresight-name = "coresight-cti4";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -624,9 +973,7 @@
reg = <0x3015000 0x1000>;
reg-names = "cti-base";
- coresight-id = <37>;
coresight-name = "coresight-cti5";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -638,9 +985,7 @@
reg = <0x3016000 0x1000>;
reg-names = "cti-base";
- coresight-id = <38>;
coresight-name = "coresight-cti6";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -656,9 +1001,7 @@
reg = <0x3017000 0x1000>;
reg-names = "cti-base";
- coresight-id = <39>;
coresight-name = "coresight-cti7";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -670,9 +1013,7 @@
reg = <0x3018000 0x1000>;
reg-names = "cti-base";
- coresight-id = <40>;
coresight-name = "coresight-cti8";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -684,9 +1025,7 @@
reg = <0x3019000 0x1000>;
reg-names = "cti-base";
- coresight-id = <41>;
coresight-name = "coresight-cti9";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -698,9 +1037,7 @@
reg = <0x301a000 0x1000>;
reg-names = "cti-base";
- coresight-id = <42>;
coresight-name = "coresight-cti10";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -712,9 +1049,7 @@
reg = <0x301b000 0x1000>;
reg-names = "cti-base";
- coresight-id = <43>;
coresight-name = "coresight-cti11";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -726,9 +1061,7 @@
reg = <0x301c000 0x1000>;
reg-names = "cti-base";
- coresight-id = <44>;
coresight-name = "coresight-cti12";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -740,9 +1073,7 @@
reg = <0x301d000 0x1000>;
reg-names = "cti-base";
- coresight-id = <45>;
coresight-name = "coresight-cti13";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -754,9 +1085,7 @@
reg = <0x301e000 0x1000>;
reg-names = "cti-base";
- coresight-id = <46>;
coresight-name = "coresight-cti14";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -768,10 +1097,8 @@
reg = <0x3820000 0x1000>;
reg-names = "cti-base";
- coresight-id = <47>;
coresight-name = "coresight-cti-cpu0";
- coresight-nr-inports = <0>;
- coresight-cti-cpu = <&CPU0>;
+ cpu = <&CPU0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -783,10 +1110,8 @@
reg = <0x3920000 0x1000>;
reg-names = "cti-base";
- coresight-id = <48>;
coresight-name = "coresight-cti-cpu1";
- coresight-nr-inports = <0>;
- coresight-cti-cpu = <&CPU1>;
+ cpu = <&CPU1>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -798,10 +1123,8 @@
reg = <0x3a20000 0x1000>;
reg-names = "cti-base";
- coresight-id = <49>;
coresight-name = "coresight-cti-cpu2";
- coresight-nr-inports = <0>;
- coresight-cti-cpu = <&CPU2>;
+ cpu = <&CPU2>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -813,10 +1136,8 @@
reg = <0x3b20000 0x1000>;
reg-names = "cti-base";
- coresight-id = <50>;
coresight-name = "coresight-cti-cpu3";
- coresight-nr-inports = <0>;
- coresight-cti-cpu = <&CPU3>;
+ cpu = <&CPU3>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -828,10 +1149,8 @@
reg = <0x38a0000 0x1000>;
reg-names = "cti-base";
- coresight-id = <51>;
coresight-name = "coresight-cti-pmu-cpu0";
- coresight-nr-inports = <0>;
- coresight-cti-cpu = <&CPU0>;
+ cpu = <&CPU0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -843,10 +1162,8 @@
reg = <0x39a0000 0x1000>;
reg-names = "cti-base";
- coresight-id = <52>;
coresight-name = "coresight-cti-pmu-cpu1";
- coresight-nr-inports = <0>;
- coresight-cti-cpu = <&CPU1>;
+ cpu = <&CPU1>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -858,10 +1175,8 @@
reg = <0x3aa0000 0x1000>;
reg-names = "cti-base";
- coresight-id = <53>;
coresight-name = "coresight-cti-pmu-cpu2";
- coresight-nr-inports = <0>;
- coresight-cti-cpu = <&CPU2>;
+ cpu = <&CPU2>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -873,10 +1188,8 @@
reg = <0x3ba0000 0x1000>;
reg-names = "cti-base";
- coresight-id = <54>;
coresight-name = "coresight-cti-pmu-cpu3";
- coresight-nr-inports = <0>;
- coresight-cti-cpu = <&CPU3>;
+ cpu = <&CPU3>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -888,9 +1201,7 @@
reg = <0x38b0000 0x1000>;
reg-names = "cti-base";
- coresight-id = <55>;
coresight-name = "coresight-cti-l2pmu-cluster0";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -902,9 +1213,7 @@
reg = <0x3ab0000 0x1000>;
reg-names = "cti-base";
- coresight-id = <56>;
coresight-name = "coresight-cti-l2pmu-cluster1";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -916,9 +1225,7 @@
reg = <0x3ad0000 0x1000>;
reg-names = "cti-base";
- coresight-id = <57>;
coresight-name = "coresight-cti-l3";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -930,9 +1237,7 @@
reg = <0x39c0000 0x1000>;
reg-names = "cti-base";
- coresight-id = <58>;
coresight-name = "coresight-cti-lm-cluster0";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -944,9 +1249,7 @@
reg = <0x39d0000 0x1000>;
reg-names = "cti-base";
- coresight-id = <59>;
coresight-name = "coresight-cti-lm-cluster1";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -958,9 +1261,7 @@
reg = <0x38d0000 0x1000>;
reg-names = "cti-base";
- coresight-id = <60>;
coresight-name = "coresight-cti-m4m";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -972,9 +1273,7 @@
reg = <0x39f0000 0x1000>;
reg-names = "cti-base";
- coresight-id = <61>;
coresight-name = "coresight-cti-tpda-apss";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -986,9 +1285,7 @@
reg = <0x3180000 0x1000>;
reg-names = "cti-base";
- coresight-id = <64>;
coresight-name = "coresight-cti-venus-cpu0";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -1000,9 +1297,7 @@
reg = <0x3044000 0x1000>;
reg-names = "cti-base";
- coresight-id = <65>;
coresight-name = "coresight-cti-audio-cpu0";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -1014,9 +1309,7 @@
reg = <0x3048000 0x1000>;
reg-names = "cti-base";
- coresight-id = <66>;
coresight-name = "coresight-cti-rpm-cpu0";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -1028,9 +1321,7 @@
reg = <0x3040000 0x1000>;
reg-names = "cti-base";
- coresight-id = <67>;
coresight-name = "coresight-cti-modem-cpu0";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>;
@@ -1057,9 +1348,7 @@
"pcie1-hwev", "pcie2-hwev", "tcsr-mux", "mss-mux0",
"mss-mux1";
- coresight-id = <70>;
coresight-name = "coresight-hwevent";
- coresight-nr-inports = <0>;
clocks = <&clock_gcc clk_qdss_clk>,
<&clock_gcc clk_qdss_a_clk>,
@@ -1075,9 +1364,7 @@
<0x76014 0x4>;
reg-names = "fuse-base", "qpdi-fuse-base";
- coresight-id = <71>;
coresight-name = "coresight-fuse";
- coresight-nr-inports = <0>;
};
qpdi: qpdi@7a1000 {
@@ -1085,9 +1372,7 @@
reg = <0x7a1000 0x4>;
reg-names = "qpdi-base";
- coresight-id = <72>;
coresight-name = "coresight-qpdi";
- coresight-nr-inports = <0>;
vdd-supply = <&pm8994_l21>;
qcom,vdd-voltage-level = <2950000 2950000>;
diff --git a/arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi b/arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi
index 53c3c7e727bc..d3ea51268590 100644
--- a/arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi
@@ -523,14 +523,14 @@
asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
<&loopback>, <&compress>, <&hostless>,
- <&afe>, <&lsm>, <&routing>, <&compr>,
+ <&afe>, <&lsm>, <&routing>, <&pcmnoirq>,
<&loopback1>;
asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
"msm-pcm-dsp.2", "msm-voip-dsp",
"msm-pcm-voice", "msm-pcm-loopback",
"msm-compress-dsp", "msm-pcm-hostless",
"msm-pcm-afe", "msm-lsm-client",
- "msm-pcm-routing", "msm-compr-dsp",
+ "msm-pcm-routing", "msm-pcm-dsp-noirq",
"msm-pcm-loopback.1";
asoc-cpu = <&dai_pri_auxpcm>, <&dai_sec_auxpcm>, <&dai_hdmi>,
<&dai_mi2s_sec>, <&dai_mi2s>, <&dai_mi2s_quat>,
diff --git a/arch/arm/boot/dts/qcom/msm8998-audio.dtsi b/arch/arm/boot/dts/qcom/msm8998-audio.dtsi
index c4e6393997ec..9a263510b27d 100644
--- a/arch/arm/boot/dts/qcom/msm8998-audio.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-audio.dtsi
@@ -89,7 +89,7 @@
asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
<&loopback>, <&compress>, <&hostless>,
<&afe>, <&lsm>, <&routing>, <&cpe>, <&compr>,
- <&pcm_noirq>, <&cpe3>;
+ <&pcm_noirq>, <&cpe3>, <&trans_loopback>;
asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
"msm-pcm-dsp.2", "msm-voip-dsp",
"msm-pcm-voice", "msm-pcm-loopback",
@@ -97,7 +97,7 @@
"msm-pcm-afe", "msm-lsm-client",
"msm-pcm-routing", "msm-cpe-lsm",
"msm-compr-dsp", "msm-pcm-dsp-noirq",
- "msm-cpe-lsm.3";
+ "msm-cpe-lsm.3", "msm-transcode-loopback";
asoc-cpu = <&dai_hdmi>, <&dai_dp>,
<&dai_mi2s0>, <&dai_mi2s1>,
<&dai_mi2s2>, <&dai_mi2s3>,
@@ -222,14 +222,15 @@
asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
<&loopback>, <&compress>, <&hostless>,
<&afe>, <&lsm>, <&routing>, <&cpe>, <&compr>,
- <&pcm_noirq>;
+ <&pcm_noirq>, <&trans_loopback>;
asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
"msm-pcm-dsp.2", "msm-voip-dsp",
"msm-pcm-voice", "msm-pcm-loopback",
"msm-compress-dsp", "msm-pcm-hostless",
"msm-pcm-afe", "msm-lsm-client",
"msm-pcm-routing", "msm-cpe-lsm",
- "msm-compr-dsp", "msm-pcm-dsp-noirq";
+ "msm-compr-dsp", "msm-pcm-dsp-noirq",
+ "msm-transcode-loopback";
asoc-cpu = <&dai_hdmi>, <&dai_dp>,
<&dai_mi2s0>, <&dai_mi2s1>,
<&dai_mi2s2>, <&dai_mi2s3>,
diff --git a/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi
index 318dc5d7c791..71593012148d 100644
--- a/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi
@@ -975,7 +975,7 @@
config {
pins = "gpio26", "gpio126";
- bias-disable;
+ bias-pull-up;
drive-strength = <2>; /* 2 MA */
};
};
diff --git a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996.dts b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996.dts
index 99f17844e508..310cd9134c79 100644
--- a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996.dts
+++ b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996.dts
@@ -63,14 +63,14 @@
asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
<&loopback>, <&compress>, <&hostless>,
- <&afe>, <&lsm>, <&routing>, <&compr>,
+ <&afe>, <&lsm>, <&routing>, <&pcmnoirq>,
<&loopback1>;
asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
"msm-pcm-dsp.2", "msm-voip-dsp",
"msm-pcm-voice", "msm-pcm-loopback",
"msm-compress-dsp", "msm-pcm-hostless",
"msm-pcm-afe", "msm-lsm-client",
- "msm-pcm-routing", "msm-compr-dsp",
+ "msm-pcm-routing", "msm-pcm-dsp-noirq",
"msm-pcm-loopback.1";
asoc-cpu = <&dai_pri_auxpcm>, <&dai_sec_auxpcm>, <&dai_hdmi>,
<&dai_mi2s_sec>, <&dai_mi2s>, <&dai_mi2s_quat>,
@@ -134,14 +134,16 @@
compatible = "qcom,msm-pcm-routing";
};
- compr: qcom,msm-compr-dsp {
- compatible = "qcom,msm-compr-dsp";
- };
-
compress: qcom,msm-compress-dsp {
compatible = "qcom,msm-compress-dsp";
};
+ pcmnoirq: qcom,msm-pcm-dsp-noirq {
+ compatible = "qcom,msm-pcm-dsp-noirq";
+ qcom,msm-pcm-low-latency;
+ qcom,latency-level = "ultra";
+ };
+
voip: qcom,msm-voip-dsp {
compatible = "qcom,msm-voip-dsp";
};
diff --git a/arch/arm64/configs/msm-auto-perf_defconfig b/arch/arm64/configs/msm-auto-perf_defconfig
index 81fa3afa8cca..2af1500ab065 100644
--- a/arch/arm64/configs/msm-auto-perf_defconfig
+++ b/arch/arm64/configs/msm-auto-perf_defconfig
@@ -358,37 +358,13 @@ CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_SOC_CAMERA=y
CONFIG_SOC_CAMERA_PLATFORM=y
-CONFIG_MSM_CAMERA=y
-CONFIG_MSM_CAMERA_DEBUG=y
-CONFIG_MSMB_CAMERA=y
-CONFIG_MSMB_CAMERA_DEBUG=y
-CONFIG_MSM_CAMERA_SENSOR=y
-CONFIG_MSM_CPP=y
-CONFIG_MSM_CCI=y
-CONFIG_MSM_CSI20_HEADER=y
-CONFIG_MSM_CSI22_HEADER=y
-CONFIG_MSM_CSI30_HEADER=y
-CONFIG_MSM_CSI31_HEADER=y
-CONFIG_MSM_CSIPHY=y
-CONFIG_MSM_CSID=y
-CONFIG_MSM_EEPROM=y
-CONFIG_MSM_ISPIF=y
-CONFIG_IMX134=y
-CONFIG_IMX132=y
-CONFIG_OV9724=y
-CONFIG_OV5648=y
-CONFIG_GC0339=y
-CONFIG_OV8825=y
-CONFIG_OV8865=y
-CONFIG_s5k4e1=y
-CONFIG_OV12830=y
-CONFIG_MSMB_JPEG=y
-CONFIG_MSM_FD=y
-CONFIG_MSM_JPEGDMA=y
CONFIG_MSM_VIDC_V4L2=y
CONFIG_MSM_VIDC_VMEM=y
CONFIG_MSM_VIDC_GOVERNORS=y
CONFIG_MSM_SDE_ROTATOR=y
+CONFIG_MSM_AIS=y
+CONFIG_MSM_AIS_DEBUG=y
+CONFIG_MSM_AIS_CAMERA_SENSOR=y
CONFIG_QCOM_KGSL=y
CONFIG_FB=y
CONFIG_FB_MSM=y
@@ -600,6 +576,7 @@ CONFIG_DEBUG_ALIGN_RODATA=y
CONFIG_CORESIGHT=y
CONFIG_CORESIGHT_EVENT=y
CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
+CONFIG_CORESIGHT_SINK_TPIU=y
CONFIG_CORESIGHT_QCOM_REPLICATOR=y
CONFIG_CORESIGHT_STM=y
CONFIG_CORESIGHT_HWEVENT=y
diff --git a/arch/arm64/configs/msm-auto_defconfig b/arch/arm64/configs/msm-auto_defconfig
index 70674f6043cf..16ada380e76e 100644
--- a/arch/arm64/configs/msm-auto_defconfig
+++ b/arch/arm64/configs/msm-auto_defconfig
@@ -362,37 +362,13 @@ CONFIG_VIDEO_ADV_DEBUG=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_SOC_CAMERA=y
CONFIG_SOC_CAMERA_PLATFORM=y
-CONFIG_MSM_CAMERA=y
-CONFIG_MSM_CAMERA_DEBUG=y
-CONFIG_MSMB_CAMERA=y
-CONFIG_MSMB_CAMERA_DEBUG=y
-CONFIG_MSM_CAMERA_SENSOR=y
-CONFIG_MSM_CPP=y
-CONFIG_MSM_CCI=y
-CONFIG_MSM_CSI20_HEADER=y
-CONFIG_MSM_CSI22_HEADER=y
-CONFIG_MSM_CSI30_HEADER=y
-CONFIG_MSM_CSI31_HEADER=y
-CONFIG_MSM_CSIPHY=y
-CONFIG_MSM_CSID=y
-CONFIG_MSM_EEPROM=y
-CONFIG_MSM_ISPIF=y
-CONFIG_IMX134=y
-CONFIG_IMX132=y
-CONFIG_OV9724=y
-CONFIG_OV5648=y
-CONFIG_GC0339=y
-CONFIG_OV8825=y
-CONFIG_OV8865=y
-CONFIG_s5k4e1=y
-CONFIG_OV12830=y
-CONFIG_MSMB_JPEG=y
-CONFIG_MSM_FD=y
-CONFIG_MSM_JPEGDMA=y
CONFIG_MSM_VIDC_V4L2=y
CONFIG_MSM_VIDC_VMEM=y
CONFIG_MSM_VIDC_GOVERNORS=y
CONFIG_MSM_SDE_ROTATOR=y
+CONFIG_MSM_AIS=y
+CONFIG_MSM_AIS_DEBUG=y
+CONFIG_MSM_AIS_CAMERA_SENSOR=y
CONFIG_QCOM_KGSL=y
CONFIG_FB=y
CONFIG_FB_MSM=y
@@ -640,6 +616,7 @@ CONFIG_FREE_PAGES_RDONLY=y
CONFIG_CORESIGHT=y
CONFIG_CORESIGHT_EVENT=y
CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
+CONFIG_CORESIGHT_SINK_TPIU=y
CONFIG_CORESIGHT_SOURCE_ETM4X=y
CONFIG_CORESIGHT_REMOTE_ETM=y
CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index 4a83fc5cc68a..fb45af9c49d3 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -2244,9 +2244,26 @@ struct diag_dci_client_tbl *dci_lookup_client_entry_pid(int tgid)
{
struct list_head *start, *temp;
struct diag_dci_client_tbl *entry = NULL;
+ struct pid *pid_struct = NULL;
+ struct task_struct *task_s = NULL;
+
list_for_each_safe(start, temp, &driver->dci_client_list) {
entry = list_entry(start, struct diag_dci_client_tbl, track);
- if (entry->client && entry->tgid == entry->client->tgid)
+ pid_struct = find_get_pid(entry->tgid);
+ if (!pid_struct) {
+ DIAG_LOG(DIAG_DEBUG_DCI,
+ "diag: valid pid doesn't exist for pid = %d\n",
+ entry->tgid);
+ continue;
+ }
+ task_s = get_pid_task(pid_struct, PIDTYPE_PID);
+ if (!task_s) {
+ DIAG_LOG(DIAG_DEBUG_DCI,
+ "diag: valid task doesn't exist for pid = %d\n",
+ entry->tgid);
+ continue;
+ }
+ if (task_s == entry->client)
if (entry->client->tgid == tgid)
return entry;
}
diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c
index ca7dd88048ac..c963e4658c07 100644
--- a/drivers/char/diag/diag_debugfs.c
+++ b/drivers/char/diag/diag_debugfs.c
@@ -80,7 +80,8 @@ static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
"Time Sync Enabled: %d\n"
"MD session mode: %d\n"
"MD session mask: %d\n"
- "Uses Time API: %d\n",
+ "Uses Time API: %d\n"
+ "Supports PD buffering: %d\n",
chk_config_get_id(),
chk_polling_response(),
driver->polling_reg_flag,
@@ -95,11 +96,12 @@ static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
driver->time_sync_enabled,
driver->md_session_mode,
driver->md_session_mask,
- driver->uses_time_api);
+ driver->uses_time_api,
+ driver->supports_pd_buffering);
for (i = 0; i < NUM_PERIPHERALS; i++) {
ret += scnprintf(buf+ret, buf_size-ret,
- "p: %s Feature: %02x %02x |%c%c%c%c%c%c%c%c%c|\n",
+ "p: %s Feature: %02x %02x |%c%c%c%c%c%c%c%c%c%c|\n",
PERIPHERAL_STRING(i),
driver->feature[i].feature_mask[0],
driver->feature[i].feature_mask[1],
@@ -108,6 +110,7 @@ static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
driver->feature[i].separate_cmd_rsp ? 'C':'c',
driver->feature[i].encode_hdlc ? 'H':'h',
driver->feature[i].mask_centralization ? 'M':'m',
+ driver->feature[i].pd_buffering ? 'P':'p',
driver->feature[i].stm_support ? 'Q':'q',
driver->feature[i].sockets_enabled ? 'S':'s',
driver->feature[i].sent_feature_mask ? 'T':'t',
@@ -273,8 +276,10 @@ static ssize_t diag_dbgfs_read_table(struct file *file, char __user *ubuf,
struct list_head *temp;
struct diag_cmd_reg_t *item = NULL;
+ mutex_lock(&driver->cmd_reg_mutex);
if (diag_dbgfs_table_index == driver->cmd_reg_count) {
diag_dbgfs_table_index = 0;
+ mutex_unlock(&driver->cmd_reg_mutex);
return 0;
}
@@ -283,6 +288,7 @@ static ssize_t diag_dbgfs_read_table(struct file *file, char __user *ubuf,
buf = kzalloc(sizeof(char) * buf_size, GFP_KERNEL);
if (ZERO_OR_NULL_PTR(buf)) {
pr_err("diag: %s, Error allocating memory\n", __func__);
+ mutex_unlock(&driver->cmd_reg_mutex);
return -ENOMEM;
}
buf_size = ksize(buf);
@@ -327,6 +333,7 @@ static ssize_t diag_dbgfs_read_table(struct file *file, char __user *ubuf,
break;
}
diag_dbgfs_table_index = i;
+ mutex_unlock(&driver->cmd_reg_mutex);
*ppos = 0;
ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 4047a2c42bb7..73296b573436 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -478,6 +478,7 @@ struct diag_feature_t {
uint8_t encode_hdlc;
uint8_t untag_header;
uint8_t peripheral_buffering;
+ uint8_t pd_buffering;
uint8_t mask_centralization;
uint8_t stm_support;
uint8_t sockets_enabled;
@@ -509,6 +510,7 @@ struct diagchar_dev {
int supports_separate_cmdrsp;
int supports_apps_hdlc_encoding;
int supports_apps_header_untagging;
+ int supports_pd_buffering;
int peripheral_untag[NUM_PERIPHERALS];
int supports_sockets;
/* The state requested in the STM command */
@@ -561,8 +563,8 @@ struct diagchar_dev {
struct diagfwd_info *diagfwd_cmd[NUM_PERIPHERALS];
struct diagfwd_info *diagfwd_dci_cmd[NUM_PERIPHERALS];
struct diag_feature_t feature[NUM_PERIPHERALS];
- struct diag_buffering_mode_t buffering_mode[NUM_PERIPHERALS];
- uint8_t buffering_flag[NUM_PERIPHERALS];
+ struct diag_buffering_mode_t buffering_mode[NUM_MD_SESSIONS];
+ uint8_t buffering_flag[NUM_MD_SESSIONS];
struct mutex mode_lock;
unsigned char *user_space_data_buf;
uint8_t user_space_data_busy;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 60bfb2af49d0..5c1094b48e92 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -1908,12 +1908,33 @@ static int diag_ioctl_get_real_time(unsigned long ioarg)
static int diag_ioctl_set_buffering_mode(unsigned long ioarg)
{
struct diag_buffering_mode_t params;
+ int peripheral = 0;
+ uint8_t diag_id = 0;
if (copy_from_user(&params, (void __user *)ioarg, sizeof(params)))
return -EFAULT;
- if (params.peripheral >= NUM_PERIPHERALS)
- return -EINVAL;
+ diag_map_pd_to_diagid(params.peripheral, &diag_id, &peripheral);
+
+ if ((peripheral < 0) ||
+ peripheral >= NUM_PERIPHERALS) {
+ pr_err("diag: In %s, invalid peripheral %d\n", __func__,
+ peripheral);
+ return -EIO;
+ }
+
+ if (params.peripheral > NUM_PERIPHERALS &&
+ !driver->feature[peripheral].pd_buffering) {
+ pr_err("diag: In %s, pd buffering not supported for peripheral:%d\n",
+ __func__, peripheral);
+ return -EIO;
+ }
+
+ if (!driver->feature[peripheral].peripheral_buffering) {
+ pr_err("diag: In %s, peripheral %d doesn't support buffering\n",
+ __func__, peripheral);
+ return -EIO;
+ }
mutex_lock(&driver->mode_lock);
driver->buffering_flag[params.peripheral] = 1;
@@ -1924,24 +1945,29 @@ static int diag_ioctl_set_buffering_mode(unsigned long ioarg)
static int diag_ioctl_peripheral_drain_immediate(unsigned long ioarg)
{
- uint8_t peripheral;
+ uint8_t pd, diag_id = 0;
+ int peripheral = 0;
- if (copy_from_user(&peripheral, (void __user *)ioarg, sizeof(uint8_t)))
+ if (copy_from_user(&pd, (void __user *)ioarg, sizeof(uint8_t)))
return -EFAULT;
- if (peripheral >= NUM_PERIPHERALS) {
+ diag_map_pd_to_diagid(pd, &diag_id, &peripheral);
+
+ if ((peripheral < 0) ||
+ peripheral >= NUM_PERIPHERALS) {
pr_err("diag: In %s, invalid peripheral %d\n", __func__,
peripheral);
return -EINVAL;
}
- if (!driver->feature[peripheral].peripheral_buffering) {
- pr_err("diag: In %s, peripheral %d doesn't support buffering\n",
- __func__, peripheral);
+ if (pd > NUM_PERIPHERALS &&
+ !driver->feature[peripheral].pd_buffering) {
+ pr_err("diag: In %s, pd buffering not supported for peripheral:%d\n",
+ __func__, peripheral);
return -EIO;
}
- return diag_send_peripheral_drain_immediate(peripheral);
+ return diag_send_peripheral_drain_immediate(pd, diag_id, peripheral);
}
static int diag_ioctl_dci_support(unsigned long ioarg)
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 8fb724305c03..019bf1946ac3 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -1601,6 +1601,7 @@ int diagfwd_init(void)
driver->supports_separate_cmdrsp = 1;
driver->supports_apps_hdlc_encoding = 1;
driver->supports_apps_header_untagging = 1;
+ driver->supports_pd_buffering = 1;
for (i = 0; i < NUM_PERIPHERALS; i++)
driver->peripheral_untag[i] = 0;
mutex_init(&driver->diag_hdlc_mutex);
@@ -1631,12 +1632,16 @@ int diagfwd_init(void)
driver->feature[i].stm_support = DISABLE_STM;
driver->feature[i].rcvd_feature_mask = 0;
driver->feature[i].peripheral_buffering = 0;
+ driver->feature[i].pd_buffering = 0;
driver->feature[i].encode_hdlc = 0;
driver->feature[i].untag_header =
DISABLE_PKT_HEADER_UNTAGGING;
driver->feature[i].mask_centralization = 0;
driver->feature[i].log_on_demand = 0;
driver->feature[i].sent_feature_mask = 0;
+ }
+
+ for (i = 0; i < NUM_MD_SESSIONS; i++) {
driver->buffering_mode[i].peripheral = i;
driver->buffering_mode[i].mode = DIAG_BUFFERING_MODE_STREAMING;
driver->buffering_mode[i].high_wm_val = DEFAULT_HIGH_WM_VAL;
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 729fbf4fc145..4ae2158b5a6b 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -418,6 +418,8 @@ static void process_incoming_feature_mask(uint8_t *buf, uint32_t len,
driver->feature[peripheral].mask_centralization = 1;
if (FEATURE_SUPPORTED(F_DIAG_PERIPHERAL_BUFFERING))
driver->feature[peripheral].peripheral_buffering = 1;
+ if (FEATURE_SUPPORTED(F_DIAG_PD_BUFFERING))
+ driver->feature[peripheral].pd_buffering = 1;
if (FEATURE_SUPPORTED(F_DIAG_SOCKETS_ENABLED))
enable_socket_feature(peripheral);
}
@@ -792,32 +794,54 @@ static int diag_compute_real_time(int idx)
}
static void diag_create_diag_mode_ctrl_pkt(unsigned char *dest_buf,
- int real_time)
+ uint8_t diag_id, int real_time)
{
struct diag_ctrl_msg_diagmode diagmode;
+ struct diag_ctrl_msg_diagmode_v2 diagmode_v2;
int msg_size = sizeof(struct diag_ctrl_msg_diagmode);
+ int msg_size_2 = sizeof(struct diag_ctrl_msg_diagmode_v2);
if (!dest_buf)
return;
- diagmode.ctrl_pkt_id = DIAG_CTRL_MSG_DIAGMODE;
- diagmode.ctrl_pkt_data_len = DIAG_MODE_PKT_LEN;
- diagmode.version = 1;
- diagmode.sleep_vote = real_time ? 1 : 0;
- /*
- * 0 - Disables real-time logging (to prevent
- * frequent APPS wake-ups, etc.).
- * 1 - Enable real-time logging
- */
- diagmode.real_time = real_time;
- diagmode.use_nrt_values = 0;
- diagmode.commit_threshold = 0;
- diagmode.sleep_threshold = 0;
- diagmode.sleep_time = 0;
- diagmode.drain_timer_val = 0;
- diagmode.event_stale_timer_val = 0;
-
- memcpy(dest_buf, &diagmode, msg_size);
+ if (diag_id) {
+ diagmode_v2.ctrl_pkt_id = DIAG_CTRL_MSG_DIAGMODE;
+ diagmode_v2.ctrl_pkt_data_len = DIAG_MODE_PKT_LEN_V2;
+ diagmode_v2.version = 2;
+ diagmode_v2.sleep_vote = real_time ? 1 : 0;
+ /*
+ * 0 - Disables real-time logging (to prevent
+ * frequent APPS wake-ups, etc.).
+ * 1 - Enable real-time logging
+ */
+ diagmode_v2.real_time = real_time;
+ diagmode_v2.use_nrt_values = 0;
+ diagmode_v2.commit_threshold = 0;
+ diagmode_v2.sleep_threshold = 0;
+ diagmode_v2.sleep_time = 0;
+ diagmode_v2.drain_timer_val = 0;
+ diagmode_v2.event_stale_timer_val = 0;
+ diagmode_v2.diag_id = diag_id;
+ memcpy(dest_buf, &diagmode_v2, msg_size_2);
+ } else {
+ diagmode.ctrl_pkt_id = DIAG_CTRL_MSG_DIAGMODE;
+ diagmode.ctrl_pkt_data_len = DIAG_MODE_PKT_LEN;
+ diagmode.version = 1;
+ diagmode.sleep_vote = real_time ? 1 : 0;
+ /*
+ * 0 - Disables real-time logging (to prevent
+ * frequent APPS wake-ups, etc.).
+ * 1 - Enable real-time logging
+ */
+ diagmode.real_time = real_time;
+ diagmode.use_nrt_values = 0;
+ diagmode.commit_threshold = 0;
+ diagmode.sleep_threshold = 0;
+ diagmode.sleep_time = 0;
+ diagmode.drain_timer_val = 0;
+ diagmode.event_stale_timer_val = 0;
+ memcpy(dest_buf, &diagmode, msg_size);
+ }
}
void diag_update_proc_vote(uint16_t proc, uint8_t vote, int index)
@@ -902,7 +926,7 @@ static void diag_send_diag_mode_update_remote(int token, int real_time)
memcpy(buf + write_len, &dci_header, dci_header_size);
write_len += dci_header_size;
- diag_create_diag_mode_ctrl_pkt(buf + write_len, real_time);
+ diag_create_diag_mode_ctrl_pkt(buf + write_len, 0, real_time);
write_len += msg_size;
*(buf + write_len) = CONTROL_CHAR; /* End Terminator */
write_len += sizeof(uint8_t);
@@ -1008,14 +1032,18 @@ void diag_real_time_work_fn(struct work_struct *work)
}
#endif
-static int __diag_send_real_time_update(uint8_t peripheral, int real_time)
+static int __diag_send_real_time_update(uint8_t peripheral, int real_time,
+ uint8_t diag_id)
{
- char buf[sizeof(struct diag_ctrl_msg_diagmode)];
- int msg_size = sizeof(struct diag_ctrl_msg_diagmode);
+ char buf[sizeof(struct diag_ctrl_msg_diagmode_v2)];
+ int msg_size = 0;
int err = 0;
- if (peripheral >= NUM_PERIPHERALS)
+ if (peripheral >= NUM_PERIPHERALS) {
+ pr_err("diag: In %s, invalid peripheral %d\n", __func__,
+ peripheral);
return -EINVAL;
+ }
if (!driver->diagfwd_cntl[peripheral] ||
!driver->diagfwd_cntl[peripheral]->ch_open) {
@@ -1030,12 +1058,17 @@ static int __diag_send_real_time_update(uint8_t peripheral, int real_time)
return -EINVAL;
}
- diag_create_diag_mode_ctrl_pkt(buf, real_time);
+ msg_size = (diag_id ? sizeof(struct diag_ctrl_msg_diagmode_v2) :
+ sizeof(struct diag_ctrl_msg_diagmode));
+
+ diag_create_diag_mode_ctrl_pkt(buf, diag_id, real_time);
mutex_lock(&driver->diag_cntl_mutex);
+
err = diagfwd_write(peripheral, TYPE_CNTL, buf, msg_size);
+
if (err && err != -ENODEV) {
- pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n",
+ pr_err("diag: In %s, unable to write, peripheral: %d, type: %d, len: %d, err: %d\n",
__func__, peripheral, TYPE_CNTL,
msg_size, err);
} else {
@@ -1061,27 +1094,79 @@ int diag_send_real_time_update(uint8_t peripheral, int real_time)
return -EINVAL;
}
- return __diag_send_real_time_update(peripheral, real_time);
+ return __diag_send_real_time_update(peripheral, real_time, 0);
+}
+
+void diag_map_pd_to_diagid(uint8_t pd, uint8_t *diag_id, int *peripheral)
+{
+ switch (pd) {
+ case UPD_WLAN:
+ *diag_id = DIAG_ID_WLAN;
+ *peripheral = PERIPHERAL_MODEM;
+ break;
+ case UPD_AUDIO:
+ *diag_id = DIAG_ID_AUDIO;
+ *peripheral = PERIPHERAL_LPASS;
+ break;
+ case UPD_SENSORS:
+ *diag_id = DIAG_ID_SENSORS;
+ *peripheral = PERIPHERAL_LPASS;
+ break;
+ case PERIPHERAL_MODEM:
+ *diag_id = DIAG_ID_MPSS;
+ *peripheral = PERIPHERAL_MODEM;
+ break;
+ case PERIPHERAL_LPASS:
+ *diag_id = DIAG_ID_LPASS;
+ *peripheral = PERIPHERAL_LPASS;
+ break;
+ case PERIPHERAL_CDSP:
+ *diag_id = DIAG_ID_CDSP;
+ *peripheral = PERIPHERAL_CDSP;
+ break;
+ default:
+ pr_err("diag: In %s, invalid peripheral %d\n", __func__,
+ pd);
+ *peripheral = -EINVAL;
+ break;
+ }
+
+ if (*peripheral > 0)
+ if (!driver->feature[*peripheral].pd_buffering)
+ *diag_id = 0;
}
int diag_send_peripheral_buffering_mode(struct diag_buffering_mode_t *params)
{
int err = 0;
int mode = MODE_REALTIME;
- uint8_t peripheral = 0;
+ int peripheral = 0;
+ uint8_t diag_id = 0;
if (!params)
return -EIO;
- peripheral = params->peripheral;
- if (peripheral >= NUM_PERIPHERALS) {
+ diag_map_pd_to_diagid(params->peripheral,
+ &diag_id, &peripheral);
+
+ if ((peripheral < 0) ||
+ peripheral >= NUM_PERIPHERALS) {
pr_err("diag: In %s, invalid peripheral %d\n", __func__,
peripheral);
return -EINVAL;
}
- if (!driver->buffering_flag[peripheral])
+ if (!driver->buffering_flag[params->peripheral]) {
+ pr_err("diag: In %s, buffering flag not set for %d\n", __func__,
+ params->peripheral);
return -EINVAL;
+ }
+
+ if (!driver->feature[peripheral].peripheral_buffering) {
+ pr_err("diag: In %s, peripheral %d doesn't support buffering\n",
+ __func__, peripheral);
+ return -EIO;
+ }
switch (params->mode) {
case DIAG_BUFFERING_MODE_STREAMING:
@@ -1100,7 +1185,7 @@ int diag_send_peripheral_buffering_mode(struct diag_buffering_mode_t *params)
if (!driver->feature[peripheral].peripheral_buffering) {
pr_debug("diag: In %s, peripheral %d doesn't support buffering\n",
__func__, peripheral);
- driver->buffering_flag[peripheral] = 0;
+ driver->buffering_flag[params->peripheral] = 0;
return -EIO;
}
@@ -1115,35 +1200,39 @@ int diag_send_peripheral_buffering_mode(struct diag_buffering_mode_t *params)
(params->low_wm_val != DIAG_MIN_WM_VAL))) {
pr_err("diag: In %s, invalid watermark values, high: %d, low: %d, peripheral: %d\n",
__func__, params->high_wm_val, params->low_wm_val,
- peripheral);
+ params->peripheral);
return -EINVAL;
}
mutex_lock(&driver->mode_lock);
- err = diag_send_buffering_tx_mode_pkt(peripheral, params);
+ err = diag_send_buffering_tx_mode_pkt(peripheral, diag_id, params);
if (err) {
pr_err("diag: In %s, unable to send buffering mode packet to peripheral %d, err: %d\n",
__func__, peripheral, err);
goto fail;
}
- err = diag_send_buffering_wm_values(peripheral, params);
+ err = diag_send_buffering_wm_values(peripheral, diag_id, params);
if (err) {
pr_err("diag: In %s, unable to send buffering wm value packet to peripheral %d, err: %d\n",
__func__, peripheral, err);
goto fail;
}
- err = __diag_send_real_time_update(peripheral, mode);
+ err = __diag_send_real_time_update(peripheral, mode, diag_id);
if (err) {
pr_err("diag: In %s, unable to send mode update to peripheral %d, mode: %d, err: %d\n",
__func__, peripheral, mode, err);
goto fail;
}
- driver->buffering_mode[peripheral].peripheral = peripheral;
- driver->buffering_mode[peripheral].mode = params->mode;
- driver->buffering_mode[peripheral].low_wm_val = params->low_wm_val;
- driver->buffering_mode[peripheral].high_wm_val = params->high_wm_val;
+ driver->buffering_mode[params->peripheral].peripheral =
+ params->peripheral;
+ driver->buffering_mode[params->peripheral].mode =
+ params->mode;
+ driver->buffering_mode[params->peripheral].low_wm_val =
+ params->low_wm_val;
+ driver->buffering_mode[params->peripheral].high_wm_val =
+ params->high_wm_val;
if (params->mode == DIAG_BUFFERING_MODE_STREAMING)
- driver->buffering_flag[peripheral] = 0;
+ driver->buffering_flag[params->peripheral] = 0;
fail:
mutex_unlock(&driver->mode_lock);
return err;
@@ -1182,10 +1271,12 @@ int diag_send_stm_state(uint8_t peripheral, uint8_t stm_control_data)
return err;
}
-int diag_send_peripheral_drain_immediate(uint8_t peripheral)
+int diag_send_peripheral_drain_immediate(uint8_t pd,
+ uint8_t diag_id, int peripheral)
{
int err = 0;
struct diag_ctrl_drain_immediate ctrl_pkt;
+ struct diag_ctrl_drain_immediate_v2 ctrl_pkt_v2;
if (!driver->feature[peripheral].peripheral_buffering) {
pr_debug("diag: In %s, peripheral %d doesn't support buffering\n",
@@ -1200,32 +1291,57 @@ int diag_send_peripheral_drain_immediate(uint8_t peripheral)
return -ENODEV;
}
- ctrl_pkt.pkt_id = DIAG_CTRL_MSG_PERIPHERAL_BUF_DRAIN_IMM;
- /* The length of the ctrl pkt is size of version and stream id */
- ctrl_pkt.len = sizeof(uint32_t) + sizeof(uint8_t);
- ctrl_pkt.version = 1;
- ctrl_pkt.stream_id = 1;
-
- err = diagfwd_write(peripheral, TYPE_CNTL, &ctrl_pkt, sizeof(ctrl_pkt));
- if (err && err != -ENODEV) {
- pr_err("diag: Unable to send drain immediate ctrl packet to peripheral %d, err: %d\n",
- peripheral, err);
+ if (diag_id && driver->feature[peripheral].pd_buffering) {
+ ctrl_pkt_v2.pkt_id = DIAG_CTRL_MSG_PERIPHERAL_BUF_DRAIN_IMM;
+ /*
+ * The length of the ctrl pkt is size of version,
+ * diag_id and stream id
+ */
+ ctrl_pkt_v2.len = sizeof(uint32_t) + (2 * sizeof(uint8_t));
+ ctrl_pkt_v2.version = 2;
+ ctrl_pkt_v2.diag_id = diag_id;
+ ctrl_pkt_v2.stream_id = 1;
+ err = diagfwd_write(peripheral, TYPE_CNTL, &ctrl_pkt_v2,
+ sizeof(ctrl_pkt_v2));
+ if (err && err != -ENODEV) {
+ pr_err("diag: Unable to send drain immediate ctrl packet to peripheral %d, err: %d\n",
+ peripheral, err);
+ }
+ } else {
+ ctrl_pkt.pkt_id = DIAG_CTRL_MSG_PERIPHERAL_BUF_DRAIN_IMM;
+ /*
+ * The length of the ctrl pkt is
+ * size of version and stream id
+ */
+ ctrl_pkt.len = sizeof(uint32_t) + sizeof(uint8_t);
+ ctrl_pkt.version = 1;
+ ctrl_pkt.stream_id = 1;
+ err = diagfwd_write(peripheral, TYPE_CNTL, &ctrl_pkt,
+ sizeof(ctrl_pkt));
+ if (err && err != -ENODEV) {
+ pr_err("diag: Unable to send drain immediate ctrl packet to peripheral %d, err: %d\n",
+ peripheral, err);
+ }
}
return err;
}
int diag_send_buffering_tx_mode_pkt(uint8_t peripheral,
- struct diag_buffering_mode_t *params)
+ uint8_t diag_id, struct diag_buffering_mode_t *params)
{
int err = 0;
struct diag_ctrl_peripheral_tx_mode ctrl_pkt;
+ struct diag_ctrl_peripheral_tx_mode_v2 ctrl_pkt_v2;
if (!params)
return -EIO;
- if (peripheral >= NUM_PERIPHERALS)
+ if (peripheral >= NUM_PERIPHERALS) {
+ pr_err("diag: In %s, invalid peripheral %d\n", __func__,
+ peripheral);
return -EINVAL;
+ }
if (!driver->feature[peripheral].peripheral_buffering) {
pr_debug("diag: In %s, peripheral %d doesn't support buffering\n",
@@ -1233,9 +1349,6 @@ int diag_send_buffering_tx_mode_pkt(uint8_t peripheral,
return -EINVAL;
}
- if (params->peripheral != peripheral)
- return -EINVAL;
-
switch (params->mode) {
case DIAG_BUFFERING_MODE_STREAMING:
case DIAG_BUFFERING_MODE_THRESHOLD:
@@ -1247,36 +1360,67 @@ int diag_send_buffering_tx_mode_pkt(uint8_t peripheral,
return -EINVAL;
}
- ctrl_pkt.pkt_id = DIAG_CTRL_MSG_CONFIG_PERIPHERAL_TX_MODE;
- /* Control packet length is size of version, stream_id and tx_mode */
- ctrl_pkt.len = sizeof(uint32_t) + (2 * sizeof(uint8_t));
- ctrl_pkt.version = 1;
- ctrl_pkt.stream_id = 1;
- ctrl_pkt.tx_mode = params->mode;
+ if (diag_id &&
+ driver->feature[peripheral].pd_buffering) {
- err = diagfwd_write(peripheral, TYPE_CNTL, &ctrl_pkt, sizeof(ctrl_pkt));
- if (err && err != -ENODEV) {
- pr_err("diag: Unable to send tx_mode ctrl packet to peripheral %d, err: %d\n",
- peripheral, err);
- goto fail;
+ ctrl_pkt_v2.pkt_id = DIAG_CTRL_MSG_CONFIG_PERIPHERAL_TX_MODE;
+ /*
+ * Control packet length is size of version, diag_id,
+ * stream_id and tx_mode
+ */
+ ctrl_pkt_v2.len = sizeof(uint32_t) + (3 * sizeof(uint8_t));
+ ctrl_pkt_v2.version = 2;
+ ctrl_pkt_v2.diag_id = diag_id;
+ ctrl_pkt_v2.stream_id = 1;
+ ctrl_pkt_v2.tx_mode = params->mode;
+
+ err = diagfwd_write(peripheral, TYPE_CNTL, &ctrl_pkt_v2,
+ sizeof(ctrl_pkt_v2));
+ if (err && err != -ENODEV) {
+ pr_err("diag: Unable to send tx_mode ctrl packet to peripheral %d, err: %d\n",
+ peripheral, err);
+ goto fail;
+ }
+ } else {
+ ctrl_pkt.pkt_id = DIAG_CTRL_MSG_CONFIG_PERIPHERAL_TX_MODE;
+ /*
+ * Control packet length is size of version,
+ * stream_id and tx_mode
+ */
+ ctrl_pkt.len = sizeof(uint32_t) + (2 * sizeof(uint8_t));
+ ctrl_pkt.version = 1;
+ ctrl_pkt.stream_id = 1;
+ ctrl_pkt.tx_mode = params->mode;
+
+ err = diagfwd_write(peripheral, TYPE_CNTL, &ctrl_pkt,
+ sizeof(ctrl_pkt));
+ if (err && err != -ENODEV) {
+ pr_err("diag: Unable to send tx_mode ctrl packet to peripheral %d, err: %d\n",
+ peripheral, err);
+ goto fail;
+ }
}
- driver->buffering_mode[peripheral].mode = params->mode;
+ driver->buffering_mode[params->peripheral].mode = params->mode;
fail:
return err;
}
int diag_send_buffering_wm_values(uint8_t peripheral,
- struct diag_buffering_mode_t *params)
+ uint8_t diag_id, struct diag_buffering_mode_t *params)
{
int err = 0;
struct diag_ctrl_set_wq_val ctrl_pkt;
+ struct diag_ctrl_set_wq_val_v2 ctrl_pkt_v2;
if (!params)
return -EIO;
- if (peripheral >= NUM_PERIPHERALS)
+ if (peripheral >= NUM_PERIPHERALS) {
+ pr_err("diag: In %s, invalid peripheral %d\n", __func__,
+ peripheral);
return -EINVAL;
+ }
if (!driver->feature[peripheral].peripheral_buffering) {
pr_debug("diag: In %s, peripheral %d doesn't support buffering\n",
@@ -1291,9 +1435,6 @@ int diag_send_buffering_wm_values(uint8_t peripheral,
return -ENODEV;
}
- if (params->peripheral != peripheral)
- return -EINVAL;
-
switch (params->mode) {
case DIAG_BUFFERING_MODE_STREAMING:
case DIAG_BUFFERING_MODE_THRESHOLD:
@@ -1305,21 +1446,45 @@ int diag_send_buffering_wm_values(uint8_t peripheral,
return -EINVAL;
}
- ctrl_pkt.pkt_id = DIAG_CTRL_MSG_CONFIG_PERIPHERAL_WMQ_VAL;
- /* Control packet length is size of version, stream_id and wmq values */
- ctrl_pkt.len = sizeof(uint32_t) + (3 * sizeof(uint8_t));
- ctrl_pkt.version = 1;
- ctrl_pkt.stream_id = 1;
- ctrl_pkt.high_wm_val = params->high_wm_val;
- ctrl_pkt.low_wm_val = params->low_wm_val;
-
- err = diagfwd_write(peripheral, TYPE_CNTL, &ctrl_pkt,
- sizeof(ctrl_pkt));
- if (err && err != -ENODEV) {
- pr_err("diag: Unable to send watermark values to peripheral %d, err: %d\n",
- peripheral, err);
+ if (diag_id &&
+ driver->feature[peripheral].pd_buffering) {
+ ctrl_pkt_v2.pkt_id = DIAG_CTRL_MSG_CONFIG_PERIPHERAL_WMQ_VAL;
+ /*
+ * Control packet length is size of version, diag_id,
+ * stream_id and wmq values
+ */
+ ctrl_pkt_v2.len = sizeof(uint32_t) + (4 * sizeof(uint8_t));
+ ctrl_pkt_v2.version = 2;
+ ctrl_pkt_v2.diag_id = diag_id;
+ ctrl_pkt_v2.stream_id = 1;
+ ctrl_pkt_v2.high_wm_val = params->high_wm_val;
+ ctrl_pkt_v2.low_wm_val = params->low_wm_val;
+
+ err = diagfwd_write(peripheral, TYPE_CNTL, &ctrl_pkt_v2,
+ sizeof(ctrl_pkt_v2));
+ if (err && err != -ENODEV) {
+ pr_err("diag: Unable to send watermark values to peripheral %d, err: %d\n",
+ peripheral, err);
+ }
+ } else {
+ ctrl_pkt.pkt_id = DIAG_CTRL_MSG_CONFIG_PERIPHERAL_WMQ_VAL;
+ /*
+ * Control packet length is size of version,
+ * stream_id and wmq values
+ */
+ ctrl_pkt.len = sizeof(uint32_t) + (3 * sizeof(uint8_t));
+ ctrl_pkt.version = 1;
+ ctrl_pkt.stream_id = 1;
+ ctrl_pkt.high_wm_val = params->high_wm_val;
+ ctrl_pkt.low_wm_val = params->low_wm_val;
+
+ err = diagfwd_write(peripheral, TYPE_CNTL, &ctrl_pkt,
+ sizeof(ctrl_pkt));
+ if (err && err != -ENODEV) {
+ pr_err("diag: Unable to send watermark values to peripheral %d, err: %d\n",
+ peripheral, err);
+ }
}
-
return err;
}
diff --git a/drivers/char/diag/diagfwd_cntl.h b/drivers/char/diag/diagfwd_cntl.h
index e8608f47ff14..86442d838471 100644
--- a/drivers/char/diag/diagfwd_cntl.h
+++ b/drivers/char/diag/diagfwd_cntl.h
@@ -68,6 +68,7 @@
#define F_DIAG_SOCKETS_ENABLED 13
#define F_DIAG_DCI_EXTENDED_HEADER_SUPPORT 14
#define F_DIAG_PKT_HEADER_UNTAG 16
+#define F_DIAG_PD_BUFFERING 17
#define ENABLE_SEPARATE_CMDRSP 1
#define DISABLE_SEPARATE_CMDRSP 0
@@ -85,7 +86,8 @@
#define ENABLE_PKT_HEADER_UNTAGGING 1
#define DISABLE_PKT_HEADER_UNTAGGING 0
-#define DIAG_MODE_PKT_LEN 36
+#define DIAG_MODE_PKT_LEN 36
+#define DIAG_MODE_PKT_LEN_V2 37
struct diag_ctrl_pkt_header_t {
uint32_t pkt_id;
@@ -171,6 +173,21 @@ struct diag_ctrl_msg_diagmode {
uint32_t event_stale_timer_val;
} __packed;
+struct diag_ctrl_msg_diagmode_v2 {
+ uint32_t ctrl_pkt_id;
+ uint32_t ctrl_pkt_data_len;
+ uint32_t version;
+ uint32_t sleep_vote;
+ uint32_t real_time;
+ uint32_t use_nrt_values;
+ uint32_t commit_threshold;
+ uint32_t sleep_threshold;
+ uint32_t sleep_time;
+ uint32_t drain_timer_val;
+ uint32_t event_stale_timer_val;
+ uint8_t diag_id;
+} __packed;
+
struct diag_ctrl_msg_stm {
uint32_t ctrl_pkt_id;
uint32_t ctrl_pkt_data_len;
@@ -249,6 +266,15 @@ struct diag_ctrl_peripheral_tx_mode {
uint8_t tx_mode;
} __packed;
+struct diag_ctrl_peripheral_tx_mode_v2 {
+ uint32_t pkt_id;
+ uint32_t len;
+ uint32_t version;
+ uint8_t diag_id;
+ uint8_t stream_id;
+ uint8_t tx_mode;
+} __packed;
+
struct diag_ctrl_drain_immediate {
uint32_t pkt_id;
uint32_t len;
@@ -256,6 +282,14 @@ struct diag_ctrl_drain_immediate {
uint8_t stream_id;
} __packed;
+struct diag_ctrl_drain_immediate_v2 {
+ uint32_t pkt_id;
+ uint32_t len;
+ uint32_t version;
+ uint8_t diag_id;
+ uint8_t stream_id;
+} __packed;
+
struct diag_ctrl_set_wq_val {
uint32_t pkt_id;
uint32_t len;
@@ -265,6 +299,16 @@ struct diag_ctrl_set_wq_val {
uint8_t low_wm_val;
} __packed;
+struct diag_ctrl_set_wq_val_v2 {
+ uint32_t pkt_id;
+ uint32_t len;
+ uint32_t version;
+ uint8_t diag_id;
+ uint8_t stream_id;
+ uint8_t high_wm_val;
+ uint8_t low_wm_val;
+} __packed;
+
int diagfwd_cntl_init(void);
void diagfwd_cntl_channel_init(void);
void diagfwd_cntl_exit(void);
@@ -273,14 +317,16 @@ void diag_cntl_channel_close(struct diagfwd_info *p_info);
void diag_cntl_process_read_data(struct diagfwd_info *p_info, void *buf,
int len);
int diag_send_real_time_update(uint8_t peripheral, int real_time);
+void diag_map_pd_to_diagid(uint8_t pd, uint8_t *diag_id, int *peripheral);
int diag_send_peripheral_buffering_mode(struct diag_buffering_mode_t *params);
void diag_update_proc_vote(uint16_t proc, uint8_t vote, int index);
void diag_update_real_time_vote(uint16_t proc, uint8_t real_time, int index);
void diag_real_time_work_fn(struct work_struct *work);
int diag_send_stm_state(uint8_t peripheral, uint8_t stm_control_data);
-int diag_send_peripheral_drain_immediate(uint8_t peripheral);
+int diag_send_peripheral_drain_immediate(uint8_t pd,
+ uint8_t diag_id, int peripheral);
int diag_send_buffering_tx_mode_pkt(uint8_t peripheral,
- struct diag_buffering_mode_t *params);
+ uint8_t diag_id, struct diag_buffering_mode_t *params);
int diag_send_buffering_wm_values(uint8_t peripheral,
- struct diag_buffering_mode_t *params);
+ uint8_t diag_id, struct diag_buffering_mode_t *params);
#endif
diff --git a/drivers/cpuidle/lpm-levels.c b/drivers/cpuidle/lpm-levels.c
index 4224b594f1b8..b69e59eeeae1 100644
--- a/drivers/cpuidle/lpm-levels.c
+++ b/drivers/cpuidle/lpm-levels.c
@@ -363,6 +363,24 @@ static int lpm_cpu_callback(struct notifier_block *cpu_nb,
return NOTIFY_OK;
}
+#ifdef CONFIG_ARM_PSCI
+
+static int __init set_cpuidle_ops(void)
+{
+ int ret = 0, cpu;
+
+ for_each_possible_cpu(cpu) {
+ ret = arm_cpuidle_init(cpu);
+ if (ret)
+ goto exit;
+ }
+
+exit:
+ return ret;
+}
+
+#endif
+
static enum hrtimer_restart lpm_hrtimer_cb(struct hrtimer *h)
{
return HRTIMER_NORESTART;
@@ -1954,6 +1972,14 @@ static int __init lpm_levels_module_init(void)
goto fail;
}
+#ifdef CONFIG_ARM_PSCI
+ rc = set_cpuidle_ops();
+ if (rc) {
+ pr_err("%s(): Failed to set cpuidle ops\n", __func__);
+ goto fail;
+ }
+#endif
+
fail:
return rc;
}
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index d04ca6f28f90..beeb99e479c7 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -1741,6 +1741,12 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
mutex_unlock(&hash_access_lock);
return err;
}
+ if (handle->sha_ctxt.diglen > QCEDEV_MAX_SHA_DIGEST) {
+ pr_err("Invalid sha_ctxt.diglen %d\n",
+ handle->sha_ctxt.diglen);
+ mutex_unlock(&hash_access_lock);
+ return -EINVAL;
+ }
qcedev_areq.sha_op_req.diglen = handle->sha_ctxt.diglen;
memcpy(&qcedev_areq.sha_op_req.digest[0],
&handle->sha_ctxt.digest[0],
@@ -1777,6 +1783,12 @@ long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
mutex_unlock(&hash_access_lock);
return err;
}
+ if (handle->sha_ctxt.diglen > QCEDEV_MAX_SHA_DIGEST) {
+ pr_err("Invalid sha_ctxt.diglen %d\n",
+ handle->sha_ctxt.diglen);
+ mutex_unlock(&hash_access_lock);
+ return -EINVAL;
+ }
qcedev_areq.sha_op_req.diglen = handle->sha_ctxt.diglen;
memcpy(&qcedev_areq.sha_op_req.digest[0],
&handle->sha_ctxt.digest[0],
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index af0060d6a22a..d652f3b53635 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -230,6 +230,13 @@ static int __init psci_features(u32 psci_func_id)
#ifdef CONFIG_CPU_IDLE
static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
+#ifdef CONFIG_ARM_PSCI
+static int psci_cpu_init(struct device_node *cpu_node, int cpu)
+{
+ return 0;
+}
+#endif
+
static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
{
int i, ret, count = 0;
@@ -333,10 +340,14 @@ int psci_cpu_suspend_enter(unsigned long state_id)
#ifdef CONFIG_ARM
static struct cpuidle_ops psci_cpuidle_ops __initdata = {
.suspend = psci_cpu_suspend_enter,
+#ifdef CONFIG_ARM_PSCI
+ .init = psci_cpu_init,
+#else
.init = psci_dt_cpu_init_idle,
+#endif
};
-CPUIDLE_METHOD_OF_DECLARE(psci, "arm,psci", &psci_cpuidle_ops);
+CPUIDLE_METHOD_OF_DECLARE(psci, "psci", &psci_cpuidle_ops);
#endif
#endif
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index 12cc28acec18..6d88eb374f69 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -34,11 +34,15 @@ static inline void __user *to_user_ptr(u64 address)
}
static struct msm_gem_submit *submit_create(struct drm_device *dev,
- struct msm_gem_address_space *aspace, int nr_bos, int nr_cmds)
+ struct msm_gem_address_space *aspace,
+ uint32_t nr_bos, uint32_t nr_cmds)
{
struct msm_gem_submit *submit;
- int sz = sizeof(*submit) + (nr_bos * sizeof(submit->bos[0])) +
- (nr_cmds * sizeof(*submit->cmd));
+ uint64_t sz = sizeof(*submit) + (nr_bos * sizeof(submit->bos[0])) +
+ (nr_cmds * sizeof(submit->cmd[0]));
+
+ if (sz > SIZE_MAX)
+ return NULL;
submit = kmalloc(sz, GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
if (submit) {
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index 11500fccc770..d85bcd8e121a 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -866,7 +866,6 @@ err:
coresight_unregister(drvdata->csdev);
return ret;
err1:
- pm_runtime_put(&adev->dev);
return -EPERM;
}
diff --git a/drivers/iommu/iommu-debug.c b/drivers/iommu/iommu-debug.c
index 776e06facc11..b8155c9227d3 100644
--- a/drivers/iommu/iommu-debug.c
+++ b/drivers/iommu/iommu-debug.c
@@ -28,6 +28,7 @@
#include <linux/dma-mapping.h>
#include <asm/cacheflush.h>
#include <asm/dma-iommu.h>
+#include "iommu-debug.h"
#if defined(CONFIG_IOMMU_DEBUG_TRACKING) || defined(CONFIG_IOMMU_TESTS)
@@ -84,371 +85,58 @@ static const char *iommu_debug_attr_to_string(enum iommu_attr attr)
static DEFINE_MUTEX(iommu_debug_attachments_lock);
static LIST_HEAD(iommu_debug_attachments);
-static struct dentry *debugfs_attachments_dir;
+/*
+ * Each group may have more than one domain; but each domain may
+ * only have one group.
+ * Used by debug tools to display the name of the device(s) associated
+ * with a particular domain.
+ */
struct iommu_debug_attachment {
struct iommu_domain *domain;
- struct device *dev;
- struct dentry *dentry;
+ struct iommu_group *group;
struct list_head list;
- unsigned long reg_offset;
-};
-
-static int iommu_debug_attachment_info_show(struct seq_file *s, void *ignored)
-{
- struct iommu_debug_attachment *attach = s->private;
- phys_addr_t pt_phys;
- int secure_vmid;
-
- seq_printf(s, "Domain: 0x%p\n", attach->domain);
- if (iommu_domain_get_attr(attach->domain, DOMAIN_ATTR_PT_BASE_ADDR,
- &pt_phys)) {
- seq_puts(s, "PT_BASE_ADDR: (Unknown)\n");
- } else {
- void *pt_virt = phys_to_virt(pt_phys);
-
- seq_printf(s, "PT_BASE_ADDR: virt=0x%p phys=%pa\n",
- pt_virt, &pt_phys);
- }
-
- seq_puts(s, "SECURE_VMID: ");
- if (iommu_domain_get_attr(attach->domain,
- DOMAIN_ATTR_SECURE_VMID,
- &secure_vmid))
- seq_puts(s, "(Unknown)\n");
- else
- seq_printf(s, "%s (0x%x)\n",
- msm_secure_vmid_to_string(secure_vmid), secure_vmid);
-
- return 0;
-}
-
-static int iommu_debug_attachment_info_open(struct inode *inode,
- struct file *file)
-{
- return single_open(file, iommu_debug_attachment_info_show,
- inode->i_private);
-}
-
-static const struct file_operations iommu_debug_attachment_info_fops = {
- .open = iommu_debug_attachment_info_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static ssize_t iommu_debug_attachment_trigger_fault_write(
- struct file *file, const char __user *ubuf, size_t count,
- loff_t *offset)
-{
- struct iommu_debug_attachment *attach = file->private_data;
- unsigned long flags;
-
- if (kstrtoul_from_user(ubuf, count, 0, &flags)) {
- pr_err("Invalid flags format\n");
- return -EFAULT;
- }
-
- iommu_trigger_fault(attach->domain, flags);
-
- return count;
-}
-
-static const struct file_operations
-iommu_debug_attachment_trigger_fault_fops = {
- .open = simple_open,
- .write = iommu_debug_attachment_trigger_fault_write,
-};
-
-static ssize_t iommu_debug_attachment_reg_offset_write(
- struct file *file, const char __user *ubuf, size_t count,
- loff_t *offset)
-{
- struct iommu_debug_attachment *attach = file->private_data;
- unsigned long reg_offset;
-
- if (kstrtoul_from_user(ubuf, count, 0, &reg_offset)) {
- pr_err("Invalid reg_offset format\n");
- return -EFAULT;
- }
-
- attach->reg_offset = reg_offset;
-
- return count;
-}
-
-static const struct file_operations iommu_debug_attachment_reg_offset_fops = {
- .open = simple_open,
- .write = iommu_debug_attachment_reg_offset_write,
-};
-
-static ssize_t iommu_debug_attachment_reg_read_read(
- struct file *file, char __user *ubuf, size_t count, loff_t *offset)
-{
- struct iommu_debug_attachment *attach = file->private_data;
- unsigned long val;
- char *val_str;
- ssize_t val_str_len;
-
- if (*offset)
- return 0;
-
- val = iommu_reg_read(attach->domain, attach->reg_offset);
- val_str = kasprintf(GFP_KERNEL, "0x%lx\n", val);
- if (!val_str)
- return -ENOMEM;
- val_str_len = strlen(val_str);
-
- if (copy_to_user(ubuf, val_str, val_str_len)) {
- pr_err("copy_to_user failed\n");
- val_str_len = -EFAULT;
- goto out;
- }
- *offset = 1; /* non-zero means we're done */
-
-out:
- kfree(val_str);
- return val_str_len;
-}
-
-static const struct file_operations iommu_debug_attachment_reg_read_fops = {
- .open = simple_open,
- .read = iommu_debug_attachment_reg_read_read,
-};
-
-static ssize_t iommu_debug_attachment_reg_write_write(
- struct file *file, const char __user *ubuf, size_t count,
- loff_t *offset)
-{
- struct iommu_debug_attachment *attach = file->private_data;
- unsigned long val;
-
- if (kstrtoul_from_user(ubuf, count, 0, &val)) {
- pr_err("Invalid val format\n");
- return -EFAULT;
- }
-
- iommu_reg_write(attach->domain, attach->reg_offset, val);
-
- return count;
-}
-
-static const struct file_operations iommu_debug_attachment_reg_write_fops = {
- .open = simple_open,
- .write = iommu_debug_attachment_reg_write_write,
};
-/* should be called with iommu_debug_attachments_lock locked */
-static int iommu_debug_attach_add_debugfs(
- struct iommu_debug_attachment *attach)
-{
- const char *attach_name;
- struct device *dev = attach->dev;
- struct iommu_domain *domain = attach->domain;
- int is_dynamic;
-
- if (iommu_domain_get_attr(domain, DOMAIN_ATTR_DYNAMIC, &is_dynamic))
- is_dynamic = 0;
-
- if (is_dynamic) {
- uuid_le uuid;
-
- uuid_le_gen(&uuid);
- attach_name = kasprintf(GFP_KERNEL, "%s-%pUl", dev_name(dev),
- uuid.b);
- if (!attach_name)
- return -ENOMEM;
- } else {
- attach_name = dev_name(dev);
- }
-
- attach->dentry = debugfs_create_dir(attach_name,
- debugfs_attachments_dir);
- if (!attach->dentry) {
- pr_err("Couldn't create iommu/attachments/%s debugfs directory for domain 0x%p\n",
- attach_name, domain);
- if (is_dynamic)
- kfree(attach_name);
- return -EIO;
- }
-
- if (is_dynamic)
- kfree(attach_name);
-
- if (!debugfs_create_file(
- "info", S_IRUSR, attach->dentry, attach,
- &iommu_debug_attachment_info_fops)) {
- pr_err("Couldn't create iommu/attachments/%s/info debugfs file for domain 0x%p\n",
- dev_name(dev), domain);
- goto err_rmdir;
- }
-
- if (!debugfs_create_file(
- "trigger_fault", S_IRUSR, attach->dentry, attach,
- &iommu_debug_attachment_trigger_fault_fops)) {
- pr_err("Couldn't create iommu/attachments/%s/trigger_fault debugfs file for domain 0x%p\n",
- dev_name(dev), domain);
- goto err_rmdir;
- }
-
- if (!debugfs_create_file(
- "reg_offset", S_IRUSR, attach->dentry, attach,
- &iommu_debug_attachment_reg_offset_fops)) {
- pr_err("Couldn't create iommu/attachments/%s/reg_offset debugfs file for domain 0x%p\n",
- dev_name(dev), domain);
- goto err_rmdir;
- }
-
- if (!debugfs_create_file(
- "reg_read", S_IRUSR, attach->dentry, attach,
- &iommu_debug_attachment_reg_read_fops)) {
- pr_err("Couldn't create iommu/attachments/%s/reg_read debugfs file for domain 0x%p\n",
- dev_name(dev), domain);
- goto err_rmdir;
- }
-
- if (!debugfs_create_file(
- "reg_write", S_IRUSR, attach->dentry, attach,
- &iommu_debug_attachment_reg_write_fops)) {
- pr_err("Couldn't create iommu/attachments/%s/reg_write debugfs file for domain 0x%p\n",
- dev_name(dev), domain);
- goto err_rmdir;
- }
-
- return 0;
-
-err_rmdir:
- debugfs_remove_recursive(attach->dentry);
- return -EIO;
-}
-
-void iommu_debug_domain_add(struct iommu_domain *domain)
+void iommu_debug_attach_device(struct iommu_domain *domain,
+ struct device *dev)
{
struct iommu_debug_attachment *attach;
+ struct iommu_group *group;
- mutex_lock(&iommu_debug_attachments_lock);
+ group = iommu_group_get(dev);
+ if (!group)
+ return;
- attach = kmalloc(sizeof(*attach), GFP_KERNEL);
+ attach = kzalloc(sizeof(*attach), GFP_KERNEL);
if (!attach)
- goto out_unlock;
+ return;
attach->domain = domain;
- attach->dev = NULL;
- list_add(&attach->list, &iommu_debug_attachments);
+ attach->group = group;
+ INIT_LIST_HEAD(&attach->list);
-out_unlock:
+ mutex_lock(&iommu_debug_attachments_lock);
+ list_add(&attach->list, &iommu_debug_attachments);
mutex_unlock(&iommu_debug_attachments_lock);
}
void iommu_debug_domain_remove(struct iommu_domain *domain)
{
- struct iommu_debug_attachment *it;
+ struct iommu_debug_attachment *it, *tmp;
mutex_lock(&iommu_debug_attachments_lock);
- list_for_each_entry(it, &iommu_debug_attachments, list)
- if (it->domain == domain && it->dev == NULL)
- break;
-
- if (&it->list == &iommu_debug_attachments) {
- WARN(1, "Couldn't find debug attachment for domain=0x%p",
- domain);
- } else {
+ list_for_each_entry_safe(it, tmp, &iommu_debug_attachments, list) {
+ if (it->domain != domain)
+ continue;
list_del(&it->list);
+ iommu_group_put(it->group);
kfree(it);
}
- mutex_unlock(&iommu_debug_attachments_lock);
-}
-
-void iommu_debug_attach_device(struct iommu_domain *domain,
- struct device *dev)
-{
- struct iommu_debug_attachment *attach;
-
- mutex_lock(&iommu_debug_attachments_lock);
-
- list_for_each_entry(attach, &iommu_debug_attachments, list)
- if (attach->domain == domain && attach->dev == NULL)
- break;
-
- if (&attach->list == &iommu_debug_attachments) {
- WARN(1, "Couldn't find debug attachment for domain=0x%p dev=%s",
- domain, dev_name(dev));
- } else {
- attach->dev = dev;
- /*
- * we might not init until after other drivers start calling
- * iommu_attach_device. Only set up the debugfs nodes if we've
- * already init'd to avoid polluting the top-level debugfs
- * directory (by calling debugfs_create_dir with a NULL
- * parent). These will be flushed out later once we init.
- */
-
- if (debugfs_attachments_dir)
- iommu_debug_attach_add_debugfs(attach);
- }
-
- mutex_unlock(&iommu_debug_attachments_lock);
-}
-
-void iommu_debug_detach_device(struct iommu_domain *domain,
- struct device *dev)
-{
- struct iommu_debug_attachment *it;
-
- mutex_lock(&iommu_debug_attachments_lock);
- list_for_each_entry(it, &iommu_debug_attachments, list)
- if (it->domain == domain && it->dev == dev)
- break;
-
- if (&it->list == &iommu_debug_attachments) {
- WARN(1, "Couldn't find debug attachment for domain=0x%p dev=%s",
- domain, dev_name(dev));
- } else {
- /*
- * Just remove debugfs entry and mark dev as NULL on
- * iommu_detach call. We would remove the actual
- * attachment entry from the list only on domain_free call.
- * This is to ensure we keep track of unattached domains too.
- */
-
- debugfs_remove_recursive(it->dentry);
- it->dev = NULL;
- }
mutex_unlock(&iommu_debug_attachments_lock);
}
-static int iommu_debug_init_tracking(void)
-{
- int ret = 0;
- struct iommu_debug_attachment *attach;
-
- mutex_lock(&iommu_debug_attachments_lock);
- debugfs_attachments_dir = debugfs_create_dir("attachments",
- iommu_debugfs_top);
- if (!debugfs_attachments_dir) {
- pr_err("Couldn't create iommu/attachments debugfs directory\n");
- ret = -ENODEV;
- goto out_unlock;
- }
-
- /* set up debugfs entries for attachments made during early boot */
- list_for_each_entry(attach, &iommu_debug_attachments, list)
- if (attach->dev)
- iommu_debug_attach_add_debugfs(attach);
-
-out_unlock:
- mutex_unlock(&iommu_debug_attachments_lock);
- return ret;
-}
-
-static void iommu_debug_destroy_tracking(void)
-{
- debugfs_remove_recursive(debugfs_attachments_dir);
-}
-#else
-static inline int iommu_debug_init_tracking(void) { return 0; }
-static inline void iommu_debug_destroy_tracking(void) { }
#endif
#ifdef CONFIG_IOMMU_TESTS
@@ -479,6 +167,8 @@ struct iommu_debug_device {
u64 phys;
size_t len;
struct list_head list;
+ struct mutex clk_lock;
+ unsigned int clk_count;
};
static int iommu_debug_build_phoney_sg_table(struct device *dev,
@@ -1518,6 +1208,7 @@ static int iommu_debug_attach_do_attach(struct iommu_debug_device *ddev,
return -ENOMEM;
}
+ val = VMID_CP_CAMERA;
if (is_secure && iommu_domain_set_attr(ddev->domain,
DOMAIN_ATTR_SECURE_VMID,
&val)) {
@@ -1867,6 +1558,10 @@ static ssize_t iommu_debug_atos_read(struct file *file, char __user *ubuf,
ssize_t retval;
size_t buflen;
+ if (kptr_restrict != 0) {
+ pr_err("kptr_restrict needs to be disabled.\n");
+ return -EPERM;
+ }
if (!ddev->domain) {
pr_err("No domain. Did you already attach?\n");
return -EINVAL;
@@ -2355,20 +2050,34 @@ static ssize_t iommu_debug_config_clocks_write(struct file *file,
return -EFAULT;
}
+ mutex_lock(&ddev->clk_lock);
switch (buf) {
case '0':
+ if (ddev->clk_count == 0) {
+ dev_err(dev, "Config clocks already disabled\n");
+ break;
+ }
+
+ if (--ddev->clk_count > 0)
+ break;
+
dev_err(dev, "Disabling config clocks\n");
iommu_disable_config_clocks(ddev->domain);
break;
case '1':
+ if (ddev->clk_count++ > 0)
+ break;
+
dev_err(dev, "Enabling config clocks\n");
if (iommu_enable_config_clocks(ddev->domain))
dev_err(dev, "Failed!\n");
break;
default:
dev_err(dev, "Invalid value. Should be 0 or 1.\n");
+ mutex_unlock(&ddev->clk_lock);
return -EINVAL;
}
+ mutex_unlock(&ddev->clk_lock);
return count;
}
@@ -2394,6 +2103,7 @@ static int snarf_iommu_devices(struct device *dev, const char *name)
ddev = kzalloc(sizeof(*ddev), GFP_KERNEL);
if (!ddev)
return -ENODEV;
+ mutex_init(&ddev->clk_lock);
ddev->dev = dev;
dir = debugfs_create_dir(name, debugfs_tests_dir);
if (!dir) {
@@ -2547,6 +2257,9 @@ err:
static int pass_iommu_devices(struct device *dev, void *ignored)
{
+ if (!of_device_is_compatible(dev->of_node, "iommu-debug-test"))
+ return 0;
+
if (!of_find_property(dev->of_node, "iommus", NULL))
return 0;
@@ -2560,6 +2273,9 @@ static int iommu_debug_populate_devices(void)
const char *cb_name;
for_each_compatible_node(np, NULL, "qcom,msm-smmu-v2-ctx") {
+ if (!of_device_is_compatible(np, "iommu-debug-test"))
+ continue;
+
ret = of_property_read_string(np, "label", &cb_name);
if (ret)
return ret;
@@ -2625,9 +2341,6 @@ static struct platform_driver iommu_debug_driver = {
static int iommu_debug_init(void)
{
- if (iommu_debug_init_tracking())
- return -ENODEV;
-
if (iommu_debug_init_tests())
return -ENODEV;
@@ -2637,7 +2350,6 @@ static int iommu_debug_init(void)
static void iommu_debug_exit(void)
{
platform_driver_unregister(&iommu_debug_driver);
- iommu_debug_destroy_tracking();
iommu_debug_destroy_tests();
}
diff --git a/drivers/iommu/iommu-debug.h b/drivers/iommu/iommu-debug.h
index 3dc87032f2a0..91c418d9e37f 100644
--- a/drivers/iommu/iommu-debug.h
+++ b/drivers/iommu/iommu-debug.h
@@ -1,11 +1,21 @@
+/* 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
#ifndef IOMMU_DEBUG_H
#define IOMMU_DEBUG_H
#ifdef CONFIG_IOMMU_DEBUG_TRACKING
void iommu_debug_attach_device(struct iommu_domain *domain, struct device *dev);
-void iommu_debug_detach_device(struct iommu_domain *domain, struct device *dev);
-void iommu_debug_domain_add(struct iommu_domain *domain);
void iommu_debug_domain_remove(struct iommu_domain *domain);
#else /* !CONFIG_IOMMU_DEBUG_TRACKING */
@@ -15,15 +25,6 @@ static inline void iommu_debug_attach_device(struct iommu_domain *domain,
{
}
-static inline void iommu_debug_detach_device(struct iommu_domain *domain,
- struct device *dev)
-{
-}
-
-static inline void iommu_debug_domain_add(struct iommu_domain *domain)
-{
-}
-
static inline void iommu_debug_domain_remove(struct iommu_domain *domain)
{
}
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index b831796b5b7d..33176a4aa6ef 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1118,8 +1118,6 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
domain->ops = bus->iommu_ops;
domain->type = type;
- iommu_debug_domain_add(domain);
-
return domain;
}
@@ -1186,7 +1184,6 @@ static void __iommu_detach_device(struct iommu_domain *domain,
if (unlikely(domain->ops->detach_dev == NULL))
return;
- iommu_debug_detach_device(domain, dev);
domain->ops->detach_dev(domain, dev);
trace_detach_device_from_domain(dev);
}
diff --git a/drivers/media/platform/msm/ais/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/ais/pproc/cpp/msm_cpp.c
index c9cb0080436a..811ac98beead 100644
--- a/drivers/media/platform/msm/ais/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/ais/pproc/cpp/msm_cpp.c
@@ -2889,6 +2889,8 @@ static int msm_cpp_validate_input(unsigned int cmd, void *arg,
case MSM_SD_SHUTDOWN:
case MSM_SD_NOTIFY_FREEZE:
case MSM_SD_UNNOTIFY_FREEZE:
+ case VIDIOC_MSM_CPP_IOMMU_ATTACH:
+ case VIDIOC_MSM_CPP_IOMMU_DETACH:
break;
default: {
if (ioctl_ptr == NULL) {
@@ -2897,8 +2899,9 @@ static int msm_cpp_validate_input(unsigned int cmd, void *arg,
}
*ioctl_ptr = arg;
- if ((*ioctl_ptr == NULL) ||
- (*ioctl_ptr)->ioctl_ptr == NULL) {
+ if (((*ioctl_ptr) == NULL) ||
+ ((*ioctl_ptr)->ioctl_ptr == NULL) ||
+ ((*ioctl_ptr)->len == 0)) {
pr_err("Error invalid ioctl argument cmd %u", cmd);
return -EINVAL;
}
diff --git a/drivers/media/platform/msm/ais/sensor/csiphy/msm_csiphy.c b/drivers/media/platform/msm/ais/sensor/csiphy/msm_csiphy.c
index 345fac905074..d146cc3d28a5 100644
--- a/drivers/media/platform/msm/ais/sensor/csiphy/msm_csiphy.c
+++ b/drivers/media/platform/msm/ais/sensor/csiphy/msm_csiphy.c
@@ -787,6 +787,25 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
CDBG("%s:%d called\n", __func__, __LINE__);
+ rc = msm_camera_config_vreg(&csiphy_dev->pdev->dev,
+ csiphy_dev->csiphy_vreg,
+ csiphy_dev->regulator_count, NULL, 0,
+ &csiphy_dev->csiphy_reg_ptr[0], 1);
+ if (rc < 0) {
+ pr_err("%s:%d csiphy config_vreg failed\n",
+ __func__, __LINE__);
+ goto csiphy_vreg_config_fail;
+ }
+ rc = msm_camera_enable_vreg(&csiphy_dev->pdev->dev,
+ csiphy_dev->csiphy_vreg,
+ csiphy_dev->regulator_count, NULL, 0,
+ &csiphy_dev->csiphy_reg_ptr[0], 1);
+ if (rc < 0) {
+ pr_err("%s:%d csiphy enable_vreg failed\n",
+ __func__, __LINE__);
+ goto top_vreg_enable_failed;
+ }
+
rc = msm_camera_clk_enable(&csiphy_dev->pdev->dev,
csiphy_dev->csiphy_clk_info, csiphy_dev->csiphy_clk,
csiphy_dev->num_clk, true);
@@ -795,7 +814,7 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
if (rc < 0) {
pr_err("%s: csiphy clk enable failed\n", __func__);
csiphy_dev->ref_count--;
- goto csiphy_resource_fail;
+ goto csiphy_enable_clk_fail;
}
CDBG("%s:%d called\n", __func__, __LINE__);
@@ -823,7 +842,17 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
csiphy_dev->csiphy_state = CSIPHY_POWER_UP;
return 0;
-csiphy_resource_fail:
+csiphy_enable_clk_fail:
+ msm_camera_enable_vreg(&csiphy_dev->pdev->dev,
+ csiphy_dev->csiphy_vreg,
+ csiphy_dev->regulator_count, NULL, 0,
+ &csiphy_dev->csiphy_reg_ptr[0], 0);
+top_vreg_enable_failed:
+ msm_camera_config_vreg(&csiphy_dev->pdev->dev,
+ csiphy_dev->csiphy_vreg,
+ csiphy_dev->regulator_count, NULL, 0,
+ &csiphy_dev->csiphy_reg_ptr[0], 0);
+csiphy_vreg_config_fail:
if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to vote for AHB\n", __func__);
@@ -862,14 +891,34 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
return rc;
}
+ rc = msm_camera_config_vreg(&csiphy_dev->pdev->dev,
+ csiphy_dev->csiphy_vreg,
+ csiphy_dev->regulator_count, NULL, 0,
+ &csiphy_dev->csiphy_reg_ptr[0], 1);
+ if (rc < 0) {
+ pr_err("%s:%d csiphy config_vreg failed\n",
+ __func__, __LINE__);
+ goto csiphy_vreg_config_fail;
+ }
+ rc = msm_camera_enable_vreg(&csiphy_dev->pdev->dev,
+ csiphy_dev->csiphy_vreg,
+ csiphy_dev->regulator_count, NULL, 0,
+ &csiphy_dev->csiphy_reg_ptr[0], 1);
+ if (rc < 0) {
+ pr_err("%s:%d csiphy enable_vreg failed\n",
+ __func__, __LINE__);
+ goto top_vreg_enable_failed;
+ }
+
rc = msm_camera_clk_enable(&csiphy_dev->pdev->dev,
csiphy_dev->csiphy_clk_info, csiphy_dev->csiphy_clk,
csiphy_dev->num_clk, true);
if (rc < 0) {
pr_err("%s: csiphy clk enable failed\n", __func__);
csiphy_dev->ref_count--;
- goto csiphy_resource_fail;
+ goto csiphy_enable_clk_fail;
}
+ CDBG("%s:%d clk enable success\n", __func__, __LINE__);
if (csiphy_dev->csiphy_3phase == CSI_3PHASE_HW)
msm_csiphy_3ph_reset(csiphy_dev);
@@ -890,7 +939,17 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
csiphy_dev->csiphy_state = CSIPHY_POWER_UP;
return 0;
-csiphy_resource_fail:
+csiphy_enable_clk_fail:
+ msm_camera_enable_vreg(&csiphy_dev->pdev->dev,
+ csiphy_dev->csiphy_vreg,
+ csiphy_dev->regulator_count, NULL, 0,
+ &csiphy_dev->csiphy_reg_ptr[0], 0);
+top_vreg_enable_failed:
+ msm_camera_config_vreg(&csiphy_dev->pdev->dev,
+ csiphy_dev->csiphy_vreg,
+ csiphy_dev->regulator_count, NULL, 0,
+ &csiphy_dev->csiphy_reg_ptr[0], 0);
+csiphy_vreg_config_fail:
if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to vote for AHB\n", __func__);
@@ -999,6 +1058,14 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
csiphy_dev->csiphy_3p_clk, 2, false);
}
+ msm_camera_enable_vreg(&csiphy_dev->pdev->dev,
+ csiphy_dev->csiphy_vreg,
+ csiphy_dev->regulator_count, NULL, 0,
+ &csiphy_dev->csiphy_reg_ptr[0], 0);
+ msm_camera_config_vreg(&csiphy_dev->pdev->dev,
+ csiphy_dev->csiphy_vreg, csiphy_dev->regulator_count,
+ NULL, 0, &csiphy_dev->csiphy_reg_ptr[0], 0);
+
csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN;
if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
@@ -1105,6 +1172,13 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
csiphy_dev->csiphy_3p_clk, 2, false);
}
+ msm_camera_enable_vreg(&csiphy_dev->pdev->dev,
+ csiphy_dev->csiphy_vreg, csiphy_dev->regulator_count,
+ NULL, 0, &csiphy_dev->csiphy_reg_ptr[0], 0);
+ msm_camera_config_vreg(&csiphy_dev->pdev->dev,
+ csiphy_dev->csiphy_vreg, csiphy_dev->regulator_count,
+ NULL, 0, &csiphy_dev->csiphy_reg_ptr[0], 0);
+
csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN;
if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
@@ -1463,6 +1537,14 @@ static int csiphy_probe(struct platform_device *pdev)
goto csiphy_no_resource;
}
+ rc = msm_camera_get_dt_vreg_data(pdev->dev.of_node,
+ &(new_csiphy_dev->csiphy_vreg),
+ &(new_csiphy_dev->regulator_count));
+ if (rc < 0) {
+ pr_err("%s: get vreg data from dtsi fail\n", __func__);
+ rc = -EFAULT;
+ goto csiphy_no_resource;
+ }
/* ToDo: Enable 3phase clock for dynamic clock enable/disable */
rc = msm_csiphy_get_clk_info(new_csiphy_dev, pdev);
if (rc < 0) {
diff --git a/drivers/media/platform/msm/ais/sensor/csiphy/msm_csiphy.h b/drivers/media/platform/msm/ais/sensor/csiphy/msm_csiphy.h
index 9b38fa50ce98..025ce0d3e05a 100644
--- a/drivers/media/platform/msm/ais/sensor/csiphy/msm_csiphy.h
+++ b/drivers/media/platform/msm/ais/sensor/csiphy/msm_csiphy.h
@@ -20,6 +20,7 @@
#include <media/ais/msm_ais_sensor.h>
#include "msm_sd.h"
#include "msm_camera_io_util.h"
+#include "msm_camera_dt_util.h"
#include "cam_soc_api.h"
#define MAX_CSIPHY 3
@@ -169,6 +170,9 @@ struct csiphy_device {
uint32_t csiphy_sof_debug;
uint32_t csiphy_sof_debug_count;
uint32_t is_combo_mode;
+ struct camera_vreg_t *csiphy_vreg;
+ struct regulator *csiphy_reg_ptr[MAX_REGULATOR];
+ int32_t regulator_count;
struct msm_camera_csiphy_params csiphy_params;
};
diff --git a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c
index 9cdcabb762c0..2030755d59d0 100644
--- a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c
+++ b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c
@@ -24,6 +24,7 @@
#include <linux/dma-mapping.h>
#include <linux/msm_dma_iommu_mapping.h>
#include <linux/workqueue.h>
+#include <linux/sizes.h>
#include <soc/qcom/scm.h>
#include <soc/qcom/secure_buffer.h>
#include <msm_camera_tz_util.h>
@@ -98,6 +99,7 @@ struct scratch_mapping {
struct cam_context_bank_info {
struct device *dev;
struct dma_iommu_mapping *mapping;
+ enum iommu_attr attr;
dma_addr_t va_start;
size_t va_len;
const char *name;
@@ -108,9 +110,8 @@ struct cam_context_bank_info {
struct mutex lock;
int handle;
enum cam_smmu_ops_param state;
- void (*handler[CAM_SMMU_CB_MAX])(struct iommu_domain *,
- struct device *, unsigned long,
- int, void*);
+ client_handler handler[CAM_SMMU_CB_MAX];
+ client_reset_handler hw_reset_handler[CAM_SMMU_CB_MAX];
void *token[CAM_SMMU_CB_MAX];
int cb_count;
int ref_cnt;
@@ -354,9 +355,9 @@ static void cam_smmu_check_vaddr_in_range(int idx, void *vaddr)
}
void cam_smmu_reg_client_page_fault_handler(int handle,
- void (*client_page_fault_handler)(struct iommu_domain *,
- struct device *, unsigned long,
- int, void*), void *token)
+ client_handler page_fault_handler,
+ client_reset_handler hw_reset_handler,
+ void *token)
{
int idx, i = 0;
@@ -380,7 +381,7 @@ void cam_smmu_reg_client_page_fault_handler(int handle,
return;
}
- if (client_page_fault_handler) {
+ if (page_fault_handler) {
if (iommu_cb_set.cb_info[idx].cb_count == CAM_SMMU_CB_MAX) {
pr_err("%s Should not regiester more handlers\n",
iommu_cb_set.cb_info[idx].name);
@@ -392,7 +393,9 @@ void cam_smmu_reg_client_page_fault_handler(int handle,
if (iommu_cb_set.cb_info[idx].token[i] == NULL) {
iommu_cb_set.cb_info[idx].token[i] = token;
iommu_cb_set.cb_info[idx].handler[i] =
- client_page_fault_handler;
+ page_fault_handler;
+ iommu_cb_set.cb_info[idx].hw_reset_handler[i] =
+ hw_reset_handler;
break;
}
}
@@ -420,6 +423,7 @@ static int cam_smmu_iommu_fault_handler(struct iommu_domain *domain,
{
char *cb_name;
int idx;
+ int j;
struct cam_smmu_work_payload *payload;
if (!token) {
@@ -453,6 +457,18 @@ static int cam_smmu_iommu_fault_handler(struct iommu_domain *domain,
payload->token = token;
payload->idx = idx;
+ /* trigger hw reset handler */
+ mutex_lock(&iommu_cb_set.cb_info[idx].lock);
+ for (j = 0; j < CAM_SMMU_CB_MAX; j++) {
+ if ((iommu_cb_set.cb_info[idx].hw_reset_handler[j])) {
+ iommu_cb_set.cb_info[idx].hw_reset_handler[j](
+ payload->domain,
+ payload->dev,
+ iommu_cb_set.cb_info[idx].token[j]);
+ }
+ }
+ mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
+
mutex_lock(&iommu_cb_set.payload_list_lock);
list_add_tail(&payload->list, &iommu_cb_set.payload_list);
mutex_unlock(&iommu_cb_set.payload_list_lock);
@@ -876,6 +892,13 @@ static int cam_smmu_detach_device(int idx)
{
struct cam_context_bank_info *cb = &iommu_cb_set.cb_info[idx];
+ if (!list_empty_careful(&iommu_cb_set.cb_info[idx].smmu_buf_list)) {
+ pr_err("Client %s buffer list is not clean!\n",
+ iommu_cb_set.cb_info[idx].name);
+ cam_smmu_print_list(idx);
+ cam_smmu_clean_buffer_list(idx);
+ }
+
/* detach the mapping to device */
arm_iommu_detach_device(cb->dev);
iommu_cb_set.cb_info[idx].state = CAM_SMMU_DETACH;
@@ -1031,7 +1054,8 @@ static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd,
buf = dma_buf_get(ion_fd);
if (IS_ERR_OR_NULL(buf)) {
rc = PTR_ERR(buf);
- pr_err("Error: dma get buf failed. fd = %d\n", ion_fd);
+ pr_err("Error: dma get buf failed. fd = %d rc = %d\n",
+ ion_fd, rc);
goto err_out;
}
@@ -1096,7 +1120,9 @@ static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd,
rc = -ENOSPC;
goto err_mapping_info;
}
- CDBG("ion_fd = %d, dev = %pK, paddr= %pK, len = %u\n", ion_fd,
+ CDBG("name %s ion_fd = %d, dev = %pK, paddr= %pK, len = %u\n",
+ iommu_cb_set.cb_info[idx].name,
+ ion_fd,
(void *)iommu_cb_set.cb_info[idx].dev,
(void *)*paddr_ptr, (unsigned int)*len_ptr);
@@ -1305,6 +1331,47 @@ int cam_smmu_get_handle(char *identifier, int *handle_ptr)
}
EXPORT_SYMBOL(cam_smmu_get_handle);
+
+int cam_smmu_set_attr(int handle, uint32_t flags, int32_t *data)
+{
+ int ret = 0, idx;
+ struct cam_context_bank_info *cb = NULL;
+ struct iommu_domain *domain = NULL;
+
+ CDBG("E: set_attr\n");
+ idx = GET_SMMU_TABLE_IDX(handle);
+ if (handle == HANDLE_INIT || idx < 0 || idx >= iommu_cb_set.cb_num) {
+ pr_err("Error: handle or index invalid. idx = %d hdl = %x\n",
+ idx, handle);
+ return -EINVAL;
+ }
+ mutex_lock(&iommu_cb_set.cb_info[idx].lock);
+ if (iommu_cb_set.cb_info[idx].handle != handle) {
+ pr_err("Error: hdl is not valid, table_hdl = %x, hdl = %x\n",
+ iommu_cb_set.cb_info[idx].handle, handle);
+ mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
+ return -EINVAL;
+ }
+
+ if (iommu_cb_set.cb_info[idx].state == CAM_SMMU_DETACH) {
+ domain = iommu_cb_set.cb_info[idx].mapping->domain;
+ cb = &iommu_cb_set.cb_info[idx];
+ cb->attr |= flags;
+ /* set attributes */
+ ret = iommu_domain_set_attr(domain, cb->attr, (void *)data);
+ if (ret < 0) {
+ pr_err("Error: set attr\n");
+ return -ENODEV;
+ }
+ } else {
+ return -EINVAL;
+ }
+ mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
+ return ret;
+}
+EXPORT_SYMBOL(cam_smmu_set_attr);
+
+
int cam_smmu_ops(int handle, enum cam_smmu_ops_param ops)
{
int ret = 0, idx;
@@ -2226,7 +2293,7 @@ static int cam_smmu_setup_cb(struct cam_context_bank_info *cb,
}
} else {
cb->va_start = SZ_128K;
- cb->va_len = VA_SPACE_END - SZ_128K;
+ cb->va_len = VA_SPACE_END - SZ_128M;
}
/* create a virtual mapping */
diff --git a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.h b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.h
index 3b8481f8bf7e..189ab2488e65 100644
--- a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.h
+++ b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.h
@@ -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
@@ -49,6 +49,13 @@ enum cam_smmu_map_dir {
CAM_SMMU_MAP_INVALID
};
+typedef void (*client_handler)(struct iommu_domain *,
+ struct device *, unsigned long,
+ int, void*);
+
+typedef void (*client_reset_handler)(struct iommu_domain *,
+ struct device *, void*);
+
/**
* @param identifier: Unique identifier to be used by clients which they
* should get from device tree. CAM SMMU driver will
@@ -61,6 +68,16 @@ enum cam_smmu_map_dir {
*/
int cam_smmu_get_handle(char *identifier, int *handle_ptr);
+
+/**
+ * @param handle: Handle to identify the CAM SMMU client (VFE, CPP, FD etc.)
+ * @param flags : SMMU attribute type
+ * @data : Value of attribute
+ * @return Status of operation. Negative in case of error. Zero otherwise.
+ */
+int cam_smmu_set_attr(int handle, uint32_t flags, int32_t *data);
+
+
/**
* @param handle: Handle to identify the CAM SMMU client (VFE, CPP, FD etc.)
* @param op : Operation to be performed. Can be either CAM_SMMU_ATTACH
@@ -215,11 +232,12 @@ int cam_smmu_find_index_by_handle(int hdl);
/**
* @param handle: Handle to identify the CAM SMMU client (VFE, CPP, FD etc.)
* @param client_page_fault_handler: It is triggered in IOMMU page fault
+ * @param client_hw_reset_handler: It is triggered in IOMMU page fault
* @param token: It is input param when trigger page fault handler
*/
void cam_smmu_reg_client_page_fault_handler(int handle,
- void (*client_page_fault_handler)(struct iommu_domain *,
- struct device *, unsigned long,
- int, void*), void *token);
+ client_handler page_fault_handler,
+ client_reset_handler hw_reset_handler,
+ void *token);
#endif /* _CAM_SMMU_API_H_ */
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index 2f8134bc3efb..f19e6dd1cb01 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -2318,7 +2318,9 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
cam_smmu_reg_client_page_fault_handler(
vfe_dev->buf_mgr->iommu_hdl,
- msm_vfe_iommu_fault_handler, vfe_dev);
+ msm_vfe_iommu_fault_handler,
+ NULL,
+ vfe_dev);
mutex_unlock(&vfe_dev->core_mutex);
mutex_unlock(&vfe_dev->realtime_mutex);
return 0;
@@ -2367,7 +2369,7 @@ int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
/* Unregister page fault handler */
cam_smmu_reg_client_page_fault_handler(
vfe_dev->buf_mgr->iommu_hdl,
- NULL, vfe_dev);
+ NULL, NULL, vfe_dev);
rc = vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, 1);
if (rc <= 0)
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index b7feb126f707..25fc34b26bc1 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -424,7 +424,17 @@ static unsigned long msm_cpp_queue_buffer_info(struct cpp_device *cpp_dev,
list_for_each_entry_safe(buff, save, buff_head, entry) {
if (buff->map_info.buff_info.index == buffer_info->index) {
- pr_err("error buffer index already queued\n");
+ pr_err("error buf index already queued\n");
+ pr_err("error buf, fd %d idx %d native %d ssid %d %d\n",
+ buffer_info->fd, buffer_info->index,
+ buffer_info->native_buff,
+ buff_queue->session_id,
+ buff_queue->stream_id);
+ pr_err("existing buf,fd %d idx %d native %d id %x\n",
+ buff->map_info.buff_info.fd,
+ buff->map_info.buff_info.index,
+ buff->map_info.buff_info.native_buff,
+ buff->map_info.buff_info.identity);
goto error;
}
}
@@ -439,6 +449,11 @@ static unsigned long msm_cpp_queue_buffer_info(struct cpp_device *cpp_dev,
buff->map_info.buff_info = *buffer_info;
buff->map_info.buf_fd = buffer_info->fd;
+ trace_printk("fd %d index %d native_buff %d ssid %d %d\n",
+ buffer_info->fd, buffer_info->index,
+ buffer_info->native_buff, buff_queue->session_id,
+ buff_queue->stream_id);
+
if (buff_queue->security_mode == SECURE_MODE)
rc = cam_smmu_get_stage2_phy_addr(cpp_dev->iommu_hdl,
buffer_info->fd, CAM_SMMU_MAP_RW,
@@ -469,6 +484,11 @@ static void msm_cpp_dequeue_buffer_info(struct cpp_device *cpp_dev,
{
int ret = -1;
+ trace_printk("fd %d index %d native_buf %d ssid %d %d\n",
+ buff->map_info.buf_fd, buff->map_info.buff_info.index,
+ buff->map_info.buff_info.native_buff, buff_queue->session_id,
+ buff_queue->stream_id);
+
if (buff_queue->security_mode == SECURE_MODE)
ret = cam_smmu_put_stage2_phy_addr(cpp_dev->iommu_hdl,
buff->map_info.buf_fd);
@@ -770,6 +790,36 @@ static int msm_cpp_dump_addr(struct cpp_device *cpp_dev,
return 0;
}
+static void msm_cpp_iommu_fault_reset_handler(
+ struct iommu_domain *domain, struct device *dev,
+ void *token)
+{
+ struct cpp_device *cpp_dev = NULL;
+
+ if (!token) {
+ pr_err("Invalid token\n");
+ return;
+ }
+
+ cpp_dev = token;
+
+ if (cpp_dev->fault_status != CPP_IOMMU_FAULT_NONE) {
+ pr_err("fault already detected %d\n", cpp_dev->fault_status);
+ return;
+ }
+
+ cpp_dev->fault_status = CPP_IOMMU_FAULT_DETECTED;
+
+ /* mask IRQ status */
+ msm_camera_io_w(0xB, cpp_dev->cpp_hw_base + 0xC);
+
+ pr_err("Issue CPP HALT %d\n", cpp_dev->fault_status);
+
+ /* MMSS_A_CPP_AXI_CMD = 0x16C, reset 0x1*/
+ msm_camera_io_w(0x1, cpp_dev->cpp_hw_base + 0x16C);
+
+}
+
static void msm_cpp_iommu_fault_handler(struct iommu_domain *domain,
struct device *dev, unsigned long iova, int flags, void *token)
{
@@ -777,50 +827,94 @@ static void msm_cpp_iommu_fault_handler(struct iommu_domain *domain,
struct msm_cpp_frame_info_t *processed_frame[MAX_CPP_PROCESSING_FRAME];
int32_t i = 0, queue_len = 0;
struct msm_device_queue *queue = NULL;
- int32_t rc = 0;
+ int32_t ifd, ofd, dfd, t0fd, t1fd;
+ int counter = 0;
+ u32 result;
if (token) {
cpp_dev = token;
+
+ if (cpp_dev->fault_status != CPP_IOMMU_FAULT_DETECTED) {
+ pr_err("fault recovery already done %d\n",
+ cpp_dev->fault_status);
+ return;
+ }
+
disable_irq(cpp_dev->irq->start);
if (atomic_read(&cpp_timer.used)) {
atomic_set(&cpp_timer.used, 0);
del_timer_sync(&cpp_timer.cpp_timer);
}
- mutex_lock(&cpp_dev->mutex);
tasklet_kill(&cpp_dev->cpp_tasklet);
- rc = cpp_load_fw(cpp_dev, cpp_dev->fw_name_bin);
- if (rc < 0) {
- pr_err("load fw failure %d-retry\n", rc);
- rc = msm_cpp_reset_vbif_and_load_fw(cpp_dev);
- if (rc < 0) {
- msm_cpp_set_micro_irq_mask(cpp_dev, 1, 0x8);
- mutex_unlock(&cpp_dev->mutex);
- return;
- }
+
+ pr_err("in recovery, HALT status = 0x%x\n",
+ msm_camera_io_r(cpp_dev->cpp_hw_base + 0x10));
+
+ while (counter < MSM_CPP_POLL_RETRIES) {
+ result = msm_camera_io_r(cpp_dev->cpp_hw_base + 0x10);
+ if (result & 0x2)
+ break;
+ usleep_range(100, 200);
+ counter++;
}
+ /* MMSS_A_CPP_IRQ_STATUS_0 = 0x10 */
+ pr_err("counter %d HALT status later = 0x%x\n",
+ counter,
+ msm_camera_io_r(cpp_dev->cpp_hw_base + 0x10));
+
+ /* MMSS_A_CPP_RST_CMD_0 = 0x8 firmware reset = 0x3FFFF */
+ msm_camera_io_w(0x3FFFF, cpp_dev->cpp_hw_base + 0x8);
+
+ counter = 0;
+ while (counter < MSM_CPP_POLL_RETRIES) {
+ result = msm_camera_io_r(cpp_dev->cpp_hw_base + 0x10);
+ if (result & 0x1)
+ break;
+ usleep_range(100, 200);
+ counter++;
+ }
+
+ /* MMSS_A_CPP_IRQ_STATUS_0 = 0x10 */
+ pr_err("counter %d after reset IRQ_STATUS_0 = 0x%x\n",
+ counter,
+ msm_camera_io_r(cpp_dev->cpp_hw_base + 0x10));
+
+ /* MMSS_A_CPP_AXI_CMD = 0x16C, reset 0x1*/
+ msm_camera_io_w(0x0, cpp_dev->cpp_hw_base + 0x16C);
+
queue = &cpp_timer.data.cpp_dev->processing_q;
queue_len = queue->len;
if (!queue_len) {
pr_err("%s:%d: Invalid queuelen\n", __func__, __LINE__);
- msm_cpp_set_micro_irq_mask(cpp_dev, 1, 0x8);
- mutex_unlock(&cpp_dev->mutex);
- return;
}
+
for (i = 0; i < queue_len; i++) {
if (cpp_timer.data.processed_frame[i]) {
processed_frame[i] =
cpp_timer.data.processed_frame[i];
- pr_err("Fault on identity=0x%x, frame_id=%03d\n",
+ ifd = processed_frame[i]->input_buffer_info.fd;
+ ofd = processed_frame[i]->
+ output_buffer_info[0].fd;
+ dfd = processed_frame[i]->
+ duplicate_buffer_info.fd;
+ t0fd = processed_frame[i]->
+ tnr_scratch_buffer_info[0].fd;
+ t1fd = processed_frame[i]->
+ tnr_scratch_buffer_info[1].fd;
+ pr_err("Fault on identity=0x%x, frame_id=%03d\n",
processed_frame[i]->identity,
processed_frame[i]->frame_id);
+ pr_err("ifd %d ofd %d dfd %d t0fd %d t1fd %d\n",
+ ifd, ofd, dfd, t0fd, t1fd);
msm_cpp_dump_addr(cpp_dev, processed_frame[i]);
msm_cpp_dump_frame_cmd(processed_frame[i]);
}
}
msm_cpp_flush_queue_and_release_buffer(cpp_dev, queue_len);
- msm_cpp_set_micro_irq_mask(cpp_dev, 1, 0x8);
- mutex_unlock(&cpp_dev->mutex);
+ cpp_dev->fault_status = CPP_IOMMU_FAULT_RECOVERED;
+ pr_err("fault recovery successful\n");
}
+ return;
}
static int cpp_init_mem(struct cpp_device *cpp_dev)
@@ -842,7 +936,9 @@ static int cpp_init_mem(struct cpp_device *cpp_dev)
cpp_dev->iommu_hdl = iommu_hdl;
cam_smmu_reg_client_page_fault_handler(
cpp_dev->iommu_hdl,
- msm_cpp_iommu_fault_handler, cpp_dev);
+ msm_cpp_iommu_fault_handler,
+ msm_cpp_iommu_fault_reset_handler,
+ cpp_dev);
return 0;
}
@@ -981,6 +1077,7 @@ static int cpp_init_hardware(struct cpp_device *cpp_dev)
int rc = 0;
uint32_t vbif_version;
cpp_dev->turbo_vote = 0;
+ cpp_dev->fault_status = CPP_IOMMU_FAULT_NONE;
rc = msm_camera_regulator_enable(cpp_dev->cpp_vdd,
cpp_dev->num_reg, true);
@@ -1115,7 +1212,7 @@ static void cpp_release_hardware(struct cpp_device *cpp_dev)
rc = msm_cpp_update_bandwidth_setting(cpp_dev, 0, 0);
}
cpp_dev->stream_cnt = 0;
-
+ pr_info("cpp hw release done\n");
}
static int32_t cpp_load_fw(struct cpp_device *cpp_dev, char *fw_name_bin)
@@ -2536,6 +2633,16 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev,
return -EINVAL;
}
+ if (cpp_dev->fault_status == CPP_IOMMU_FAULT_RECOVERED) {
+ pr_err("Error, page fault occurred %d\n",
+ cpp_dev->fault_status);
+ return -EINVAL;
+ } else if (cpp_dev->fault_status == CPP_IOMMU_FAULT_DETECTED) {
+ pr_err("drop frame, page fault occurred %d\n",
+ cpp_dev->fault_status);
+ return -EFAULT;
+ }
+
if (cpp_frame_msg[new_frame->msg_len - 1] !=
MSM_CPP_MSG_ID_TRAILER) {
pr_err("Invalid frame message\n");
@@ -3523,6 +3630,7 @@ STREAM_BUFF_END:
break;
case VIDIOC_MSM_CPP_IOMMU_ATTACH: {
if (cpp_dev->iommu_state == CPP_IOMMU_STATE_DETACHED) {
+ int32_t stall_disable;
struct msm_camera_smmu_attach_type cpp_attach_info;
if (ioctl_ptr->len !=
@@ -3540,7 +3648,10 @@ STREAM_BUFF_END:
}
cpp_dev->security_mode = cpp_attach_info.attach;
-
+ stall_disable = 1;
+ /* disable smmu stall on fault */
+ cam_smmu_set_attr(cpp_dev->iommu_hdl,
+ DOMAIN_ATTR_CB_STALL_DISABLE, &stall_disable);
if (cpp_dev->security_mode == SECURE_MODE) {
rc = cam_smmu_ops(cpp_dev->iommu_hdl,
CAM_SMMU_ATTACH_SEC_CPP);
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h
index a05448091e42..f2c544785f46 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h
@@ -130,6 +130,12 @@ enum cpp_iommu_state {
CPP_IOMMU_STATE_ATTACHED,
};
+enum cpp_iommu_fault_state {
+ CPP_IOMMU_FAULT_NONE,
+ CPP_IOMMU_FAULT_DETECTED,
+ CPP_IOMMU_FAULT_RECOVERED,
+};
+
enum msm_queue {
MSM_CAM_Q_CTRL, /* control command or control command status */
MSM_CAM_Q_VFE_EVT, /* adsp event */
@@ -287,6 +293,7 @@ struct cpp_device {
struct msm_cpp_vbif_data *vbif_data;
bool turbo_vote;
struct cx_ipeak_client *cpp_cx_ipeak;
+ enum cpp_iommu_fault_state fault_status;
};
int msm_cpp_set_micro_clk(struct cpp_device *cpp_dev);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/include/msm_csiphy_5_0_1_hwreg.h b/drivers/media/platform/msm/camera_v2/sensor/csiphy/include/msm_csiphy_5_0_1_hwreg.h
index 9120a4cc85ca..5dbcbd219732 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/include/msm_csiphy_5_0_1_hwreg.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/include/msm_csiphy_5_0_1_hwreg.h
@@ -100,6 +100,8 @@ struct csiphy_reg_3ph_parms_t csiphy_v5_0_1_3ph = {
{0x38, 0xFE},
{0x81c, 0x2},
{0x700, 0x80},
+ {0x724, 0x04},
+ {0x024, 0x04},
};
struct csiphy_settings_t csiphy_combo_mode_v5_0_1 = {
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/include/msm_csiphy_5_0_hwreg.h b/drivers/media/platform/msm/camera_v2/sensor/csiphy/include/msm_csiphy_5_0_hwreg.h
index 8591f0646080..98d0b933bba2 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/include/msm_csiphy_5_0_hwreg.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/include/msm_csiphy_5_0_hwreg.h
@@ -101,6 +101,8 @@ struct csiphy_reg_3ph_parms_t csiphy_v5_0_3ph = {
{0x38, 0xFE},
{0x81c, 0x6},
{0x700, 0x80},
+ {0x724, 0x04},
+ {0x024, 0x04},
};
struct csiphy_settings_t csiphy_combo_mode_v5_0 = {
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
index 214dd6f3406d..8d091320cbca 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
@@ -684,14 +684,20 @@ static int msm_csiphy_2phase_lane_config_v50(
csiphybase + csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl15.addr + offset);
- if (mask == CLOCK_LANE)
+ if (mask == CLOCK_LANE) {
msm_camera_io_w(csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnck_ctrl0.data,
csiphybase + csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnck_ctrl0.addr);
- else
+ msm_camera_io_w(csiphy_dev->ctrl_reg->
+ csiphy_3ph_reg.
+ mipi_csiphy_2ph_lnck_ctrl9.data,
+ csiphybase + csiphy_dev->ctrl_reg->
+ csiphy_3ph_reg.
+ mipi_csiphy_2ph_lnck_ctrl9.addr);
+ } else {
msm_camera_io_w(csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl0.data,
@@ -699,6 +705,14 @@ static int msm_csiphy_2phase_lane_config_v50(
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_ctrl0.addr +
offset);
+ msm_camera_io_w(csiphy_dev->ctrl_reg->
+ csiphy_3ph_reg.
+ mipi_csiphy_2ph_lnn_ctrl9.data,
+ csiphybase + csiphy_dev->ctrl_reg->
+ csiphy_3ph_reg.
+ mipi_csiphy_2ph_lnn_ctrl9.addr +
+ offset);
+ }
msm_camera_io_w(csiphy_dev->ctrl_reg->
csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg1.data,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h
index c1a9748e8af5..c33f183963cc 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h
@@ -142,6 +142,8 @@ struct csiphy_reg_3ph_parms_t {
struct csiphy_reg_t mipi_csiphy_2ph_lnn_ctrl14;
struct csiphy_reg_t mipi_csiphy_3ph_cmn_ctrl7_cphy;
struct csiphy_reg_t mipi_csiphy_2ph_lnck_ctrl0;
+ struct csiphy_reg_t mipi_csiphy_2ph_lnck_ctrl9;
+ struct csiphy_reg_t mipi_csiphy_2ph_lnn_ctrl9;
};
struct csiphy_ctrl_t {
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c
index 58cb160f118e..9273c0e95230 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_smmu.c
@@ -486,11 +486,8 @@ int sde_smmu_secure_ctrl(int enable)
mdata->iommu_attached = true;
} else {
rc = sde_smmu_detach(mdata);
- /*
- * keep iommu_attached equal to true,
- * so that driver does not attemp to attach
- * while in secure state
- */
+ if (!rc)
+ mdata->iommu_attached = false;
}
mutex_unlock(&sde_smmu_ref_cnt_lock);
diff --git a/drivers/mfd/wcd9xxx-irq.c b/drivers/mfd/wcd9xxx-irq.c
index 856179b96f37..43c6b0651064 100644
--- a/drivers/mfd/wcd9xxx-irq.c
+++ b/drivers/mfd/wcd9xxx-irq.c
@@ -290,7 +290,7 @@ static irqreturn_t wcd9xxx_irq_thread(int irq, void *data)
static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 1);
struct wcd9xxx_core_resource *wcd9xxx_res = data;
int num_irq_regs = wcd9xxx_res->num_irq_regs;
- u8 status[num_irq_regs], status1[num_irq_regs];
+ u8 status[4], status1[4] = {0}, unmask_status[4] = {0};
if (unlikely(wcd9xxx_lock_sleep(wcd9xxx_res) == false)) {
dev_err(wcd9xxx_res->dev, "Failed to hold suspend\n");
@@ -314,6 +314,23 @@ static irqreturn_t wcd9xxx_irq_thread(int irq, void *data)
"Failed to read interrupt status: %d\n", ret);
goto err_disable_irq;
}
+ /*
+ * If status is 0 return without clearing.
+ * status contains: HW status - masked interrupts
+ * status1 contains: unhandled interrupts - masked interrupts
+ * unmasked_status contains: unhandled interrupts
+ */
+ if (unlikely(!memcmp(status, status1, sizeof(status)))) {
+ pr_debug("%s: status is 0\n", __func__);
+ wcd9xxx_unlock_sleep(wcd9xxx_res);
+ return IRQ_HANDLED;
+ }
+
+ /*
+ * Copy status to unmask_status before masking, otherwise SW may miss
+ * to clear masked interrupt in corner case.
+ */
+ memcpy(unmask_status, status, sizeof(unmask_status));
/* Apply masking */
for (i = 0; i < num_irq_regs; i++)
@@ -337,6 +354,8 @@ static irqreturn_t wcd9xxx_irq_thread(int irq, void *data)
wcd9xxx_irq_dispatch(wcd9xxx_res, &irqdata);
status1[BIT_BYTE(irqdata.intr_num)] &=
~BYTE_BIT_MASK(irqdata.intr_num);
+ unmask_status[BIT_BYTE(irqdata.intr_num)] &=
+ ~BYTE_BIT_MASK(irqdata.intr_num);
}
}
@@ -358,12 +377,13 @@ static irqreturn_t wcd9xxx_irq_thread(int irq, void *data)
linebuf, sizeof(linebuf), false);
pr_warn("%s: status1 : %s\n", __func__, linebuf);
}
-
- memset(status, 0xff, num_irq_regs);
-
+ /*
+ * unmask_status contains unhandled interrupts, hence clear all
+ * unhandled interrupts.
+ */
ret = regmap_bulk_write(wcd9xxx_res->wcd_core_regmap,
wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLEAR_BASE],
- status, num_irq_regs);
+ unmask_status, num_irq_regs);
if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
regmap_write(wcd9xxx_res->wcd_core_regmap,
wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLR_COMMIT],
diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c
index e3f23caac5b8..5419bd1655c1 100644
--- a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c
+++ b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c
@@ -140,7 +140,8 @@ static int audio_aio_ion_lookup_vaddr(struct q6audio_aio *audio, void *addr,
list) {
if (addr >= region_elt->vaddr &&
addr < region_elt->vaddr + region_elt->len &&
- addr + len <= region_elt->vaddr + region_elt->len)
+ addr + len <= region_elt->vaddr + region_elt->len &&
+ addr + len > addr)
pr_err("\t%s[%pK]:%pK, %ld --> %pK\n",
__func__, audio,
region_elt->vaddr,
diff --git a/drivers/pinctrl/qcom/pinctrl-lpi.c b/drivers/pinctrl/qcom/pinctrl-lpi.c
index 3fe41ee4c3c1..e383f4b42599 100644
--- a/drivers/pinctrl/qcom/pinctrl-lpi.c
+++ b/drivers/pinctrl/qcom/pinctrl-lpi.c
@@ -414,8 +414,10 @@ static int lpi_notifier_service_cb(struct notifier_block *this,
switch (opcode) {
case AUDIO_NOTIFIER_SERVICE_DOWN:
- if (initial_boot)
+ if (initial_boot) {
+ initial_boot = false;
break;
+ }
lpi_dev_up = false;
break;
case AUDIO_NOTIFIER_SERVICE_UP:
@@ -463,6 +465,7 @@ static void lpi_gpio_dbg_show_one(struct seq_file *s,
"pull up"
};
+ pctldev = pctldev ? : to_gpio_state(chip)->ctrl;
pindesc = pctldev->desc->pins[offset];
pad = pctldev->desc->pins[offset].drv_data;
ctl_reg = lpi_gpio_read(pad, LPI_GPIO_REG_DIR_CTL);
diff --git a/drivers/platform/msm/mhi/mhi_bhi.c b/drivers/platform/msm/mhi/mhi_bhi.c
index 5b05270b1e66..e1c50e1273ac 100644
--- a/drivers/platform/msm/mhi/mhi_bhi.c
+++ b/drivers/platform/msm/mhi/mhi_bhi.c
@@ -598,6 +598,7 @@ void bhi_exit(struct mhi_device_ctxt *mhi_dev_ctxt)
dma_free_coherent(dev, bhie_mem_info->alloc_size,
bhie_mem_info->pre_aligned,
bhie_mem_info->dma_handle);
+ kfree(fw_table->bhie_mem_info);
fw_table->bhie_mem_info = NULL;
/* vector table is the last entry in bhie_mem_info */
fw_table->bhi_vec_entry = NULL;
@@ -613,6 +614,7 @@ void bhi_exit(struct mhi_device_ctxt *mhi_dev_ctxt)
dma_free_coherent(dev, bhie_mem_info->alloc_size,
bhie_mem_info->pre_aligned,
bhie_mem_info->dma_handle);
+ kfree(rddm_table->bhie_mem_info);
rddm_table->bhie_mem_info = NULL;
rddm_table->bhi_vec_entry = NULL;
}
diff --git a/drivers/platform/msm/mhi/mhi_main.c b/drivers/platform/msm/mhi/mhi_main.c
index 78aa1beb870d..702f9ad5ddfb 100644
--- a/drivers/platform/msm/mhi/mhi_main.c
+++ b/drivers/platform/msm/mhi/mhi_main.c
@@ -508,6 +508,7 @@ int mhi_register_channel(struct mhi_client_handle **client_handle,
struct mhi_client_config *client_config;
const char *node_name;
enum MHI_CLIENT_CHANNEL chan;
+ struct mhi_chan_info chan_info = {0};
int ret;
if (!client_info || client_info->dev->of_node == NULL)
@@ -537,6 +538,14 @@ int mhi_register_channel(struct mhi_client_handle **client_handle,
mhi_log(mhi_dev_ctxt, MHI_MSG_INFO,
"Registering channel 0x%x for client\n", chan);
+ /* check if it's a supported channel by endpoint */
+ ret = get_chan_props(mhi_dev_ctxt, chan, &chan_info);
+ if (ret) {
+ mhi_log(mhi_dev_ctxt, MHI_MSG_ERROR,
+ "Client try to register unsupported chan:%d\n", chan);
+ return -EINVAL;
+ }
+
*client_handle = kzalloc(sizeof(struct mhi_client_handle), GFP_KERNEL);
if (NULL == *client_handle)
return -ENOMEM;
@@ -567,7 +576,7 @@ int mhi_register_channel(struct mhi_client_handle **client_handle,
if (MHI_CLIENT_IP_HW_0_IN == chan)
client_config->intmod_t = 10;
- get_chan_props(mhi_dev_ctxt, chan, &client_config->chan_info);
+ client_config->chan_info = chan_info;
ret = enable_bb_ctxt(mhi_dev_ctxt, &mhi_dev_ctxt->chan_bb_list[chan],
client_config->chan_info.max_desc, chan,
client_config->client_info.max_payload);
diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c
index fa4232d4436c..803851d2b3ef 100644
--- a/drivers/power/supply/qcom/qpnp-smb2.c
+++ b/drivers/power/supply/qcom/qpnp-smb2.c
@@ -455,8 +455,7 @@ static int smb2_usb_get_prop(struct power_supply *psy,
if (!val->intval)
break;
- rc = smblib_get_prop_typec_mode(chg, val);
- if ((val->intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT ||
+ if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT ||
chg->micro_usb_mode) &&
chg->real_charger_type == POWER_SUPPLY_TYPE_USB)
val->intval = 0;
@@ -493,7 +492,7 @@ static int smb2_usb_get_prop(struct power_supply *psy,
else if (chip->bad_part)
val->intval = POWER_SUPPLY_TYPEC_SOURCE_DEFAULT;
else
- rc = smblib_get_prop_typec_mode(chg, val);
+ val->intval = chg->typec_mode;
break;
case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
if (chg->micro_usb_mode)
@@ -678,8 +677,7 @@ static int smb2_usb_port_get_prop(struct power_supply *psy,
if (!val->intval)
break;
- rc = smblib_get_prop_typec_mode(chg, val);
- if ((val->intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT ||
+ if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT ||
chg->micro_usb_mode) &&
chg->real_charger_type == POWER_SUPPLY_TYPE_USB)
val->intval = 1;
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index dee387bc87e7..7848ca4396d9 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -841,7 +841,6 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua)
{
int rc = 0;
bool override;
- union power_supply_propval pval;
/* suspend and return if 25mA or less is requested */
if (icl_ua < USBIN_25MA)
@@ -851,14 +850,8 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua)
if (icl_ua == INT_MAX)
goto override_suspend_config;
- rc = smblib_get_prop_typec_mode(chg, &pval);
- if (rc < 0) {
- smblib_err(chg, "Couldn't get typeC mode rc = %d\n", rc);
- goto enable_icl_changed_interrupt;
- }
-
/* configure current */
- if (pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT
+ if (chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT
&& (chg->real_charger_type == POWER_SUPPLY_TYPE_USB)) {
rc = set_sdp_current(chg, icl_ua);
if (rc < 0) {
@@ -880,7 +873,7 @@ override_suspend_config:
if (icl_ua == INT_MAX) {
/* remove override if no voters - hw defaults is desired */
override = false;
- } else if (pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) {
+ } else if (chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) {
if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB)
/* For std cable with type = SDP never override */
override = false;
@@ -920,15 +913,8 @@ int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua)
int rc = 0;
u8 load_cfg;
bool override;
- union power_supply_propval pval;
- rc = smblib_get_prop_typec_mode(chg, &pval);
- if (rc < 0) {
- smblib_err(chg, "Couldn't get typeC mode rc = %d\n", rc);
- return rc;
- }
-
- if ((pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT
+ if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT
|| chg->micro_usb_mode)
&& (chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB)) {
rc = get_sdp_current(chg, icl_ua);
@@ -2219,8 +2205,6 @@ static const char * const smblib_typec_mode_name[] = {
static int smblib_get_prop_ufp_mode(struct smb_charger *chg)
{
switch (chg->typec_status[0]) {
- case 0:
- return POWER_SUPPLY_TYPEC_NONE;
case UFP_TYPEC_RDSTD_BIT:
return POWER_SUPPLY_TYPEC_SOURCE_DEFAULT;
case UFP_TYPEC_RD1P5_BIT:
@@ -2231,7 +2215,7 @@ static int smblib_get_prop_ufp_mode(struct smb_charger *chg)
break;
}
- return POWER_SUPPLY_TYPEC_NON_COMPLIANT;
+ return POWER_SUPPLY_TYPEC_NONE;
}
static int smblib_get_prop_dfp_mode(struct smb_charger *chg)
@@ -2245,8 +2229,6 @@ static int smblib_get_prop_dfp_mode(struct smb_charger *chg)
return POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE;
case DFP_RD_OPEN_BIT:
return POWER_SUPPLY_TYPEC_SINK;
- case DFP_RA_OPEN_BIT:
- return POWER_SUPPLY_TYPEC_POWERED_CABLE_ONLY;
default:
break;
}
@@ -2254,20 +2236,12 @@ static int smblib_get_prop_dfp_mode(struct smb_charger *chg)
return POWER_SUPPLY_TYPEC_NONE;
}
-int smblib_get_prop_typec_mode(struct smb_charger *chg,
- union power_supply_propval *val)
+static int smblib_get_prop_typec_mode(struct smb_charger *chg)
{
- if (!(chg->typec_status[3] & TYPEC_DEBOUNCE_DONE_STATUS_BIT)) {
- val->intval = POWER_SUPPLY_TYPEC_NONE;
- return 0;
- }
-
if (chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT)
- val->intval = smblib_get_prop_dfp_mode(chg);
+ return smblib_get_prop_dfp_mode(chg);
else
- val->intval = smblib_get_prop_ufp_mode(chg);
-
- return 0;
+ return smblib_get_prop_ufp_mode(chg);
}
int smblib_get_prop_typec_power_role(struct smb_charger *chg,
@@ -2555,24 +2529,12 @@ int smblib_set_prop_pd_active(struct smb_charger *chg,
const union power_supply_propval *val)
{
int rc;
- bool orientation, cc_debounced, sink_attached, hvdcp;
+ bool orientation, sink_attached, hvdcp;
u8 stat;
if (!get_effective_result(chg->pd_allowed_votable))
return -EINVAL;
- rc = smblib_read(chg, APSD_STATUS_REG, &stat);
- if (rc < 0) {
- smblib_err(chg, "Couldn't read APSD status rc=%d\n", rc);
- return rc;
- }
-
- cc_debounced = (bool)
- (chg->typec_status[3] & TYPEC_DEBOUNCE_DONE_STATUS_BIT);
- sink_attached = (bool)
- (chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT);
- hvdcp = stat & QC_CHARGER_BIT;
-
chg->pd_active = val->intval;
if (chg->pd_active) {
vote(chg->apsd_disable_votable, PD_VOTER, true, 0);
@@ -2624,6 +2586,14 @@ int smblib_set_prop_pd_active(struct smb_charger *chg,
if (rc < 0)
smblib_err(chg, "Couldn't unvote USB_PSY rc=%d\n", rc);
} else {
+ rc = smblib_read(chg, APSD_STATUS_REG, &stat);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't read APSD status rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ hvdcp = stat & QC_CHARGER_BIT;
vote(chg->apsd_disable_votable, PD_VOTER, false, 0);
vote(chg->pd_allowed_votable, PD_VOTER, true, 0);
vote(chg->usb_irq_enable_votable, PD_VOTER, true, 0);
@@ -2643,8 +2613,8 @@ int smblib_set_prop_pd_active(struct smb_charger *chg,
* and data could be interrupted. Non-legacy DCP could also draw
* more, but it may impact compliance.
*/
- if (!chg->typec_legacy_valid && cc_debounced &&
- !sink_attached && hvdcp)
+ sink_attached = chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT;
+ if (!chg->typec_legacy_valid && !sink_attached && hvdcp)
schedule_work(&chg->legacy_detection_work);
}
@@ -2766,6 +2736,7 @@ static int smblib_cc2_sink_removal_enter(struct smb_charger *chg)
smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc);
return rc;
}
+
ccout = (stat & CC_ATTACHED_BIT) ?
(!!(stat & CC_ORIENTATION_BIT) + 1) : 0;
ufp_mode = (stat & TYPEC_DEBOUNCE_DONE_STATUS_BIT) ?
@@ -3684,8 +3655,7 @@ unlock:
smblib_update_usb_type(chg);
}
-static void smblib_handle_typec_insertion(struct smb_charger *chg,
- bool sink_attached)
+static void smblib_handle_typec_insertion(struct smb_charger *chg)
{
int rc;
@@ -3697,45 +3667,37 @@ static void smblib_handle_typec_insertion(struct smb_charger *chg,
smblib_err(chg, "Couldn't disable APSD_START_ON_CC rc=%d\n",
rc);
- if (sink_attached)
+ if (chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT)
typec_sink_insertion(chg);
else
typec_sink_removal(chg);
}
-static void smblib_handle_typec_debounce_done(struct smb_charger *chg,
- bool rising, bool sink_attached)
+static void smblib_handle_typec_cc_state_change(struct smb_charger *chg)
{
- int rc;
- union power_supply_propval pval = {0, };
+ if (chg->pr_swap_in_progress)
+ return;
- if (rising) {
- if (!chg->typec_present && !chg->pr_swap_in_progress) {
- chg->typec_present = true;
- smblib_dbg(chg, PR_MISC, "TypeC insertion\n");
- smblib_handle_typec_insertion(chg, sink_attached);
- }
- } else {
- if (chg->typec_present && !chg->pr_swap_in_progress) {
- chg->typec_present = false;
- smblib_dbg(chg, PR_MISC, "TypeC removal\n");
- smblib_handle_typec_removal(chg);
- }
+ chg->typec_mode = smblib_get_prop_typec_mode(chg);
+ if (!chg->typec_present && chg->typec_mode != POWER_SUPPLY_TYPEC_NONE) {
+ chg->typec_present = true;
+ smblib_dbg(chg, PR_MISC, "TypeC %s insertion\n",
+ smblib_typec_mode_name[chg->typec_mode]);
+ smblib_handle_typec_insertion(chg);
+ } else if (chg->typec_present &&
+ chg->typec_mode == POWER_SUPPLY_TYPEC_NONE) {
+ chg->typec_present = false;
+ smblib_dbg(chg, PR_MISC, "TypeC removal\n");
+ smblib_handle_typec_removal(chg);
}
- rc = smblib_get_prop_typec_mode(chg, &pval);
- if (rc < 0)
- smblib_err(chg, "Couldn't get prop typec mode rc=%d\n", rc);
-
- smblib_dbg(chg, PR_INTERRUPT, "IRQ: debounce-done %s; Type-C %s detected\n",
- rising ? "rising" : "falling",
- smblib_typec_mode_name[pval.intval]);
+ smblib_dbg(chg, PR_INTERRUPT, "IRQ: cc-state-change; Type-C %s detected\n",
+ smblib_typec_mode_name[chg->typec_mode]);
}
static void smblib_usb_typec_change(struct smb_charger *chg)
{
int rc;
- bool debounce_done, sink_attached;
rc = smblib_multibyte_read(chg, TYPE_C_STATUS_1_REG,
chg->typec_status, 5);
@@ -3744,12 +3706,7 @@ static void smblib_usb_typec_change(struct smb_charger *chg)
return;
}
- debounce_done =
- (bool)(chg->typec_status[3] & TYPEC_DEBOUNCE_DONE_STATUS_BIT);
- sink_attached =
- (bool)(chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT);
-
- smblib_handle_typec_debounce_done(chg, debounce_done, sink_attached);
+ smblib_handle_typec_cc_state_change(chg);
if (chg->typec_status[3] & TYPEC_VBUS_ERROR_STATUS_BIT)
smblib_dbg(chg, PR_INTERRUPT, "IRQ: vbus-error\n");
@@ -4264,8 +4221,7 @@ static void smblib_legacy_detection_work(struct work_struct *work)
chg->typec_legacy_valid = true;
vote(chg->usb_icl_votable, LEGACY_UNKNOWN_VOTER, false, 0);
legacy = stat & TYPEC_LEGACY_CABLE_STATUS_BIT;
- rp_high = smblib_get_prop_ufp_mode(chg) ==
- POWER_SUPPLY_TYPEC_SOURCE_HIGH;
+ rp_high = chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_HIGH;
if (!legacy || !rp_high)
vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER,
false, 0);
diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h
index 70219e259e05..8ba0a1dfe19f 100644
--- a/drivers/power/supply/qcom/smb-lib.h
+++ b/drivers/power/supply/qcom/smb-lib.h
@@ -322,6 +322,7 @@ struct smb_charger {
bool typec_legacy_valid;
int fake_input_current_limited;
bool pr_swap_in_progress;
+ int typec_mode;
/* workaround flag */
u32 wa_flags;
@@ -453,8 +454,6 @@ int smblib_get_prop_usb_current_now(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_typec_cc_orientation(struct smb_charger *chg,
union power_supply_propval *val);
-int smblib_get_prop_typec_mode(struct smb_charger *chg,
- union power_supply_propval *val);
int smblib_get_prop_typec_power_role(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_pd_allowed(struct smb_charger *chg,
diff --git a/drivers/power/supply/qcom/smb-reg.h b/drivers/power/supply/qcom/smb-reg.h
index 167666a8c548..d8671ab1fd06 100644
--- a/drivers/power/supply/qcom/smb-reg.h
+++ b/drivers/power/supply/qcom/smb-reg.h
@@ -486,11 +486,11 @@ enum {
#define UFP_TYPEC_OPEN_OPEN_BIT BIT(0)
#define TYPE_C_STATUS_2_REG (USBIN_BASE + 0x0C)
-#define DFP_TYPEC_MASK 0x8F
#define DFP_RA_OPEN_BIT BIT(7)
#define TIMER_STAGE_BIT BIT(6)
#define EXIT_UFP_MODE_BIT BIT(5)
#define EXIT_DFP_MODE_BIT BIT(4)
+#define DFP_TYPEC_MASK GENMASK(3, 0)
#define DFP_RD_OPEN_BIT BIT(3)
#define DFP_RD_RA_VCONN_BIT BIT(2)
#define DFP_RD_RD_BIT BIT(1)
diff --git a/drivers/power/supply/qcom/smb138x-charger.c b/drivers/power/supply/qcom/smb138x-charger.c
index 694591c3ec56..0ee53b100ae2 100644
--- a/drivers/power/supply/qcom/smb138x-charger.c
+++ b/drivers/power/supply/qcom/smb138x-charger.c
@@ -248,7 +248,7 @@ static int smb138x_usb_get_prop(struct power_supply *psy,
val->intval = chg->usb_psy_desc.type;
break;
case POWER_SUPPLY_PROP_TYPEC_MODE:
- rc = smblib_get_prop_typec_mode(chg, val);
+ val->intval = chg->typec_mode;
break;
case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
rc = smblib_get_prop_typec_power_role(chg, val);
diff --git a/drivers/soc/qcom/qdsp6v2/apr.c b/drivers/soc/qcom/qdsp6v2/apr.c
index 2da8731c5753..eca992ec17e4 100644
--- a/drivers/soc/qcom/qdsp6v2/apr.c
+++ b/drivers/soc/qcom/qdsp6v2/apr.c
@@ -886,8 +886,10 @@ static int apr_notifier_service_cb(struct notifier_block *this,
* recovery notifications during initial boot
* up since everything is expected to be down.
*/
- if (is_initial_boot)
+ if (is_initial_boot) {
+ is_initial_boot = false;
break;
+ }
if (cb_data->domain == AUDIO_NOTIFIER_MODEM_DOMAIN)
apr_modem_down(opcode);
else
@@ -907,7 +909,12 @@ done:
return NOTIFY_OK;
}
-static struct notifier_block service_nb = {
+static struct notifier_block adsp_service_nb = {
+ .notifier_call = apr_notifier_service_cb,
+ .priority = 0,
+};
+
+static struct notifier_block modem_service_nb = {
.notifier_call = apr_notifier_service_cb,
.priority = 0,
};
@@ -937,9 +944,9 @@ static int __init apr_init(void)
is_initial_boot = true;
subsys_notif_register("apr_adsp", AUDIO_NOTIFIER_ADSP_DOMAIN,
- &service_nb);
+ &adsp_service_nb);
subsys_notif_register("apr_modem", AUDIO_NOTIFIER_MODEM_DOMAIN,
- &service_nb);
+ &modem_service_nb);
return 0;
}
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index 757ab00812f2..7bfadccf0e47 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -1738,14 +1738,8 @@ static void usbpd_sm(struct work_struct *w)
case PE_SRC_READY:
if (IS_CTRL(rx_msg, MSG_GET_SOURCE_CAP)) {
- ret = pd_send_msg(pd, MSG_SOURCE_CAPABILITIES,
- default_src_caps,
- ARRAY_SIZE(default_src_caps), SOP_MSG);
- if (ret) {
- usbpd_err(&pd->dev, "Error sending SRC CAPs\n");
- usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
- break;
- }
+ pd->current_state = PE_SRC_SEND_CAPABILITIES;
+ kick_sm(pd, 0);
} else if (IS_CTRL(rx_msg, MSG_GET_SINK_CAP)) {
ret = pd_send_msg(pd, MSG_SINK_CAPABILITIES,
pd->sink_caps, pd->num_sink_caps,
@@ -2321,6 +2315,14 @@ static void usbpd_sm(struct work_struct *w)
sm_done:
kfree(rx_msg);
+ spin_lock_irqsave(&pd->rx_lock, flags);
+ ret = list_empty(&pd->rx_q);
+ spin_unlock_irqrestore(&pd->rx_lock, flags);
+
+ /* requeue if there are any new/pending RX messages */
+ if (!ret)
+ kick_sm(pd, 0);
+
if (!pd->sm_queued)
pm_relax(&pd->dev);
}
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index 797c8b4a2eb1..d5caf0e6bb1c 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -1815,7 +1815,7 @@ static int mdss_dsi_post_panel_on(struct mdss_panel_data *pdata)
return 0;
}
-irqreturn_t test_hw_vsync_handler(int irq, void *data)
+static irqreturn_t test_hw_vsync_handler(int irq, void *data)
{
struct mdss_panel_data *pdata = (struct mdss_panel_data *)data;
diff --git a/include/linux/msm_mhi.h b/include/linux/msm_mhi.h
index c01cb1af4231..e655f7397527 100644
--- a/include/linux/msm_mhi.h
+++ b/include/linux/msm_mhi.h
@@ -168,6 +168,7 @@ enum mhi_rddm_segment {
MHI_RDDM_RD_SEGMENT,
};
+#if defined(CONFIG_MSM_MHI)
/**
* mhi_is_device_ready - Check if MHI is ready to register clients
*
@@ -187,11 +188,23 @@ bool mhi_is_device_ready(const struct device * const dev,
* @userdata: cb data for client
* @Return 0 on success
*/
-int mhi_register_device(struct mhi_device *mhi_device,
- const char *node_name,
+int mhi_register_device(struct mhi_device *mhi_device, const char *node_name,
void *user_data);
/**
+ * mhi_register_channel - Client must call this function to obtain a handle for
+ * any MHI operations
+ *
+ * @client_handle: Handle populated by MHI, opaque to client
+ * @client_info: Channel\device information provided by client to
+ * which the handle maps to.
+ *
+ * @Return errno
+ */
+int mhi_register_channel(struct mhi_client_handle **client_handle,
+ struct mhi_client_info_t *client_info);
+
+/**
* mhi_pm_control_device - power management control api
* @mhi_device: registered device structure
* @ctrl: specific command
@@ -219,19 +232,6 @@ int mhi_xfer_rddm(struct mhi_device *mhi_device, enum mhi_rddm_segment seg,
int mhi_deregister_channel(struct mhi_client_handle *client_handle);
/**
- * mhi_register_channel - Client must call this function to obtain a handle for
- * any MHI operations
- *
- * @client_handle: Handle populated by MHI, opaque to client
- * @client_info: Channel\device information provided by client to
- * which the handle maps to.
- *
- * @Return errno
- */
-int mhi_register_channel(struct mhi_client_handle **client_handle,
- struct mhi_client_info_t *client_info);
-
-/**
* mhi_open_channel - Client must call this function to open a channel
*
* @client_handle: Handle populated by MHI, opaque to client
@@ -258,8 +258,8 @@ int mhi_open_channel(struct mhi_client_handle *client_handle);
*
* @Return errno
*/
-int mhi_queue_xfer(struct mhi_client_handle *client_handle,
- void *buf, size_t buf_len, enum MHI_FLAGS mhi_flags);
+int mhi_queue_xfer(struct mhi_client_handle *client_handle, void *buf,
+ size_t buf_len, enum MHI_FLAGS mhi_flags);
/**
* mhi_close_channel - Client can request channel to be closed and handle freed
@@ -300,7 +300,7 @@ int mhi_get_free_desc(struct mhi_client_handle *client_handle);
* @Return non negative on success
*/
int mhi_poll_inbound(struct mhi_client_handle *client_handle,
- struct mhi_result *result);
+ struct mhi_result *result);
/**
* mhi_get_max_desc - Get the maximum number of descriptors
@@ -311,12 +311,107 @@ int mhi_poll_inbound(struct mhi_client_handle *client_handle,
*/
int mhi_get_max_desc(struct mhi_client_handle *client_handle);
-/* RmNET Reserved APIs, This APIs are reserved for use by the linux network
-* stack only. Use by other clients will introduce system wide issues
-*/
+/* following APIs meant to be used by rmnet interface only */
int mhi_set_lpm(struct mhi_client_handle *client_handle, bool enable_lpm);
int mhi_get_epid(struct mhi_client_handle *mhi_handle);
struct mhi_result *mhi_poll(struct mhi_client_handle *client_handle);
void mhi_mask_irq(struct mhi_client_handle *client_handle);
void mhi_unmask_irq(struct mhi_client_handle *client_handle);
+
+#else
+static inline bool mhi_is_device_ready(const struct device * const dev,
+ const char *node_name)
+{
+ return false;
+};
+
+static inline int mhi_register_device(struct mhi_device *mhi_device,
+ const char *node_name, void *user_data)
+{
+ return -EINVAL;
+};
+
+static inline int mhi_register_channel(struct mhi_client_handle **client_handle,
+ struct mhi_client_info_t *client_info)
+{
+ return -EINVAL;
+};
+
+static inline int mhi_pm_control_device(struct mhi_device *mhi_device,
+ enum mhi_dev_ctrl ctrl)
+{
+ return -EINVAL;
+};
+
+static inline int mhi_xfer_rddm(struct mhi_device *mhi_device,
+ enum mhi_rddm_segment seg,
+ struct scatterlist **sg_list)
+{
+ return -EINVAL;
+};
+
+static inline int mhi_deregister_channel(struct mhi_client_handle
+ *client_handle)
+{
+ return -EINVAL;
+};
+
+static inline int mhi_open_channel(struct mhi_client_handle *client_handle)
+{
+ return -EINVAL;
+};
+
+static inline int mhi_queue_xfer(struct mhi_client_handle *client_handle,
+ void *buf, size_t buf_len,
+ enum MHI_FLAGS mhi_flags)
+{
+ return -EINVAL;
+};
+
+static inline void mhi_close_channel(struct mhi_client_handle *client_handle)
+{
+};
+
+static inline int mhi_get_free_desc(struct mhi_client_handle *client_handle)
+{
+ return -EINVAL;
+};
+
+static inline int mhi_poll_inbound(struct mhi_client_handle *client_handle,
+ struct mhi_result *result)
+{
+ return -EINVAL;
+};
+
+static inline int mhi_get_max_desc(struct mhi_client_handle *client_handle)
+{
+ return -EINVAL;
+};
+
+static inline int mhi_set_lpm(struct mhi_client_handle *client_handle,
+ bool enable_lpm)
+{
+ return -EINVAL;
+};
+
+static inline int mhi_get_epid(struct mhi_client_handle *mhi_handle)
+{
+ return -EINVAL;
+};
+
+static inline struct mhi_result *mhi_poll(struct mhi_client_handle
+ *client_handle)
+{
+ return NULL;
+};
+
+static inline void mhi_mask_irq(struct mhi_client_handle *client_handle)
+{
+};
+
+static inline void mhi_unmask_irq(struct mhi_client_handle *client_handle)
+{
+};
+
+#endif
#endif
diff --git a/include/linux/sde_io_util.h b/include/linux/sde_io_util.h
index 6bd5c168ecd8..da4a50722984 100644
--- a/include/linux/sde_io_util.h
+++ b/include/linux/sde_io_util.h
@@ -58,6 +58,8 @@ struct dss_vreg {
int post_on_sleep;
int pre_off_sleep;
int post_off_sleep;
+ bool lp_disable_allowed;
+ bool disabled;
};
struct dss_gpio {
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 1f19ff2210f8..74995a0cdbad 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -44,6 +44,8 @@ struct param_outband {
#define ADM_MATRIX_ID_COMPRESSED_AUDIO_RX 2
+#define ADM_MATRIX_ID_COMPRESSED_AUDIO_TX 3
+
#define ADM_MATRIX_ID_LISTEN_TX 4
/* Enumeration for an audio Tx matrix ID.*/
#define ADM_MATRIX_ID_AUDIOX 1
@@ -446,6 +448,9 @@ struct adm_param_data_v5 {
#define ASM_STREAM_CMD_REGISTER_PP_EVENTS 0x00013213
#define ASM_STREAM_PP_EVENT 0x00013214
+#define ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE 0x13333
+#define ASM_IEC_61937_MEDIA_FMT_EVENT 0x13334
+
#define DSP_STREAM_CMD "ADSP Stream Cmd"
#define DSP_STREAM_CALLBACK "ADSP Stream Callback Event"
#define DSP_STREAM_CALLBACK_QUEUE_SIZE 1024
diff --git a/include/sound/q6adm-v2.h b/include/sound/q6adm-v2.h
index caabb66bd0b4..900d2455993a 100644
--- a/include/sound/q6adm-v2.h
+++ b/include/sound/q6adm-v2.h
@@ -17,6 +17,7 @@
#define ADM_PATH_LIVE_REC 0x2
#define ADM_PATH_NONLIVE_REC 0x3
#define ADM_PATH_COMPRESSED_RX 0x5
+#define ADM_PATH_COMPRESSED_TX 0x6
#include <linux/qdsp6v2/rtac.h>
#include <sound/q6afe-v2.h>
#include <sound/q6audio-v2.h>
diff --git a/sound/soc/codecs/msm_sdw/msm-sdw-tables.c b/sound/soc/codecs/msm_sdw/msm-sdw-tables.c
index 4cbdb728ef41..1b51805bb92e 100644
--- a/sound/soc/codecs/msm_sdw/msm-sdw-tables.c
+++ b/sound/soc/codecs/msm_sdw/msm-sdw-tables.c
@@ -220,3 +220,100 @@ const u8 msm_sdw_reg_readable[MSM_SDW_MAX_REGISTER] = {
[MSM_SDW_TOP_I2S_RESET] = 1,
[MSM_SDW_TOP_BLOCKS_RESET] = 1,
};
+
+const u8 msm_sdw_reg_writeable[MSM_SDW_MAX_REGISTER] = {
+ [MSM_SDW_PAGE_REGISTER] = 1,
+ [MSM_SDW_TX9_SPKR_PROT_PATH_CTL] = 1,
+ [MSM_SDW_TX9_SPKR_PROT_PATH_CFG0] = 1,
+ [MSM_SDW_TX10_SPKR_PROT_PATH_CTL] = 1,
+ [MSM_SDW_TX10_SPKR_PROT_PATH_CFG0] = 1,
+ [MSM_SDW_TX11_SPKR_PROT_PATH_CTL] = 1,
+ [MSM_SDW_TX11_SPKR_PROT_PATH_CFG0] = 1,
+ [MSM_SDW_TX12_SPKR_PROT_PATH_CTL] = 1,
+ [MSM_SDW_TX12_SPKR_PROT_PATH_CFG0] = 1,
+ [MSM_SDW_COMPANDER7_CTL0] = 1,
+ [MSM_SDW_COMPANDER7_CTL1] = 1,
+ [MSM_SDW_COMPANDER7_CTL2] = 1,
+ [MSM_SDW_COMPANDER7_CTL3] = 1,
+ [MSM_SDW_COMPANDER7_CTL4] = 1,
+ [MSM_SDW_COMPANDER7_CTL5] = 1,
+ [MSM_SDW_COMPANDER7_CTL7] = 1,
+ [MSM_SDW_COMPANDER8_CTL0] = 1,
+ [MSM_SDW_COMPANDER8_CTL1] = 1,
+ [MSM_SDW_COMPANDER8_CTL2] = 1,
+ [MSM_SDW_COMPANDER8_CTL3] = 1,
+ [MSM_SDW_COMPANDER8_CTL4] = 1,
+ [MSM_SDW_COMPANDER8_CTL5] = 1,
+ [MSM_SDW_COMPANDER8_CTL7] = 1,
+ [MSM_SDW_RX7_RX_PATH_CTL] = 1,
+ [MSM_SDW_RX7_RX_PATH_CFG0] = 1,
+ [MSM_SDW_RX7_RX_PATH_CFG1] = 1,
+ [MSM_SDW_RX7_RX_PATH_CFG2] = 1,
+ [MSM_SDW_RX7_RX_VOL_CTL] = 1,
+ [MSM_SDW_RX7_RX_PATH_MIX_CTL] = 1,
+ [MSM_SDW_RX7_RX_PATH_MIX_CFG] = 1,
+ [MSM_SDW_RX7_RX_VOL_MIX_CTL] = 1,
+ [MSM_SDW_RX7_RX_PATH_SEC0] = 1,
+ [MSM_SDW_RX7_RX_PATH_SEC1] = 1,
+ [MSM_SDW_RX7_RX_PATH_SEC2] = 1,
+ [MSM_SDW_RX7_RX_PATH_SEC3] = 1,
+ [MSM_SDW_RX7_RX_PATH_SEC5] = 1,
+ [MSM_SDW_RX7_RX_PATH_SEC6] = 1,
+ [MSM_SDW_RX7_RX_PATH_SEC7] = 1,
+ [MSM_SDW_RX7_RX_PATH_MIX_SEC0] = 1,
+ [MSM_SDW_RX7_RX_PATH_MIX_SEC1] = 1,
+ [MSM_SDW_RX8_RX_PATH_CTL] = 1,
+ [MSM_SDW_RX8_RX_PATH_CFG0] = 1,
+ [MSM_SDW_RX8_RX_PATH_CFG1] = 1,
+ [MSM_SDW_RX8_RX_PATH_CFG2] = 1,
+ [MSM_SDW_RX8_RX_VOL_CTL] = 1,
+ [MSM_SDW_RX8_RX_PATH_MIX_CTL] = 1,
+ [MSM_SDW_RX8_RX_PATH_MIX_CFG] = 1,
+ [MSM_SDW_RX8_RX_VOL_MIX_CTL] = 1,
+ [MSM_SDW_RX8_RX_PATH_SEC0] = 1,
+ [MSM_SDW_RX8_RX_PATH_SEC1] = 1,
+ [MSM_SDW_RX8_RX_PATH_SEC2] = 1,
+ [MSM_SDW_RX8_RX_PATH_SEC3] = 1,
+ [MSM_SDW_RX8_RX_PATH_SEC5] = 1,
+ [MSM_SDW_RX8_RX_PATH_SEC6] = 1,
+ [MSM_SDW_RX8_RX_PATH_SEC7] = 1,
+ [MSM_SDW_RX8_RX_PATH_MIX_SEC0] = 1,
+ [MSM_SDW_RX8_RX_PATH_MIX_SEC1] = 1,
+ [MSM_SDW_BOOST0_BOOST_PATH_CTL] = 1,
+ [MSM_SDW_BOOST0_BOOST_CTL] = 1,
+ [MSM_SDW_BOOST0_BOOST_CFG1] = 1,
+ [MSM_SDW_BOOST0_BOOST_CFG2] = 1,
+ [MSM_SDW_BOOST1_BOOST_PATH_CTL] = 1,
+ [MSM_SDW_BOOST1_BOOST_CTL] = 1,
+ [MSM_SDW_BOOST1_BOOST_CFG1] = 1,
+ [MSM_SDW_BOOST1_BOOST_CFG2] = 1,
+ [MSM_SDW_AHB_BRIDGE_WR_DATA_0] = 1,
+ [MSM_SDW_AHB_BRIDGE_WR_DATA_1] = 1,
+ [MSM_SDW_AHB_BRIDGE_WR_DATA_2] = 1,
+ [MSM_SDW_AHB_BRIDGE_WR_DATA_3] = 1,
+ [MSM_SDW_AHB_BRIDGE_WR_ADDR_0] = 1,
+ [MSM_SDW_AHB_BRIDGE_WR_ADDR_1] = 1,
+ [MSM_SDW_AHB_BRIDGE_WR_ADDR_2] = 1,
+ [MSM_SDW_AHB_BRIDGE_WR_ADDR_3] = 1,
+ [MSM_SDW_AHB_BRIDGE_RD_ADDR_0] = 1,
+ [MSM_SDW_AHB_BRIDGE_RD_ADDR_1] = 1,
+ [MSM_SDW_AHB_BRIDGE_RD_ADDR_2] = 1,
+ [MSM_SDW_AHB_BRIDGE_RD_ADDR_3] = 1,
+ [MSM_SDW_AHB_BRIDGE_ACCESS_CFG] = 1,
+ [MSM_SDW_CLK_RST_CTRL_MCLK_CONTROL] = 1,
+ [MSM_SDW_CLK_RST_CTRL_FS_CNT_CONTROL] = 1,
+ [MSM_SDW_CLK_RST_CTRL_SWR_CONTROL] = 1,
+ [MSM_SDW_TOP_TOP_CFG0] = 1,
+ [MSM_SDW_TOP_TOP_CFG1] = 1,
+ [MSM_SDW_TOP_RX_I2S_CTL] = 1,
+ [MSM_SDW_TOP_TX_I2S_CTL] = 1,
+ [MSM_SDW_TOP_RX7_PATH_INPUT0_MUX] = 1,
+ [MSM_SDW_TOP_RX7_PATH_INPUT1_MUX] = 1,
+ [MSM_SDW_TOP_RX8_PATH_INPUT0_MUX] = 1,
+ [MSM_SDW_TOP_RX8_PATH_INPUT1_MUX] = 1,
+ [MSM_SDW_TOP_FREQ_MCLK] = 1,
+ [MSM_SDW_TOP_DEBUG_BUS_SEL] = 1,
+ [MSM_SDW_TOP_DEBUG_EN] = 1,
+ [MSM_SDW_TOP_I2S_RESET] = 1,
+ [MSM_SDW_TOP_BLOCKS_RESET] = 1,
+};
diff --git a/sound/soc/codecs/msm_sdw/msm_sdw.h b/sound/soc/codecs/msm_sdw/msm_sdw.h
index 8e7612c85455..db991481e07d 100644
--- a/sound/soc/codecs/msm_sdw/msm_sdw.h
+++ b/sound/soc/codecs/msm_sdw/msm_sdw.h
@@ -21,6 +21,7 @@
extern const struct regmap_config msm_sdw_regmap_config;
extern const u8 msm_sdw_page_map[MSM_SDW_MAX_REGISTER];
extern const u8 msm_sdw_reg_readable[MSM_SDW_MAX_REGISTER];
+extern const u8 msm_sdw_reg_writeable[MSM_SDW_MAX_REGISTER];
enum {
MSM_SDW_RX4 = 0,
diff --git a/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c b/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c
index db723e5ec1f4..b91d13c8e010 100644
--- a/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c
+++ b/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c
@@ -1668,8 +1668,10 @@ static int msm_sdw_notifier_service_cb(struct notifier_block *nb,
mutex_lock(&msm_sdw->codec_mutex);
switch (opcode) {
case AUDIO_NOTIFIER_SERVICE_DOWN:
- if (initial_boot)
+ if (initial_boot) {
+ initial_boot = false;
break;
+ }
msm_sdw->int_mclk1_enabled = false;
msm_sdw->dev_up = false;
for (i = 0; i < msm_sdw->nr; i++)
diff --git a/sound/soc/codecs/msm_sdw/msm_sdw_regmap.c b/sound/soc/codecs/msm_sdw/msm_sdw_regmap.c
index e79db0ab17be..22663384ec35 100644
--- a/sound/soc/codecs/msm_sdw/msm_sdw_regmap.c
+++ b/sound/soc/codecs/msm_sdw/msm_sdw_regmap.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -115,6 +115,11 @@ static bool msm_sdw_is_readable_register(struct device *dev, unsigned int reg)
return msm_sdw_reg_readable[reg];
}
+static bool msm_sdw_is_writeable_register(struct device *dev, unsigned int reg)
+{
+ return msm_sdw_reg_writeable[reg];
+}
+
static bool msm_sdw_is_volatile_register(struct device *dev, unsigned int reg)
{
switch (reg) {
@@ -150,6 +155,7 @@ const struct regmap_config msm_sdw_regmap_config = {
.reg_defaults = msm_sdw_defaults,
.num_reg_defaults = ARRAY_SIZE(msm_sdw_defaults),
.max_register = MSM_SDW_MAX_REGISTER,
+ .writeable_reg = msm_sdw_is_writeable_register,
.volatile_reg = msm_sdw_is_volatile_register,
.readable_reg = msm_sdw_is_readable_register,
};
diff --git a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c
index 9eaf6cc7b89b..00f2aa766363 100644
--- a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c
+++ b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c
@@ -3813,8 +3813,10 @@ static int sdm660_cdc_notifier_service_cb(struct notifier_block *nb,
switch (opcode) {
case AUDIO_NOTIFIER_SERVICE_DOWN:
- if (initial_boot)
+ if (initial_boot) {
+ initial_boot = false;
break;
+ }
dev_dbg(codec->dev,
"ADSP is about to power down. teardown/reset codec\n");
msm_anlg_cdc_device_down(codec);
diff --git a/sound/soc/codecs/sdm660_cdc/msm-cdc-common.h b/sound/soc/codecs/sdm660_cdc/msm-cdc-common.h
index 7a63a71ceeb1..5d5cee124bca 100644
--- a/sound/soc/codecs/sdm660_cdc/msm-cdc-common.h
+++ b/sound/soc/codecs/sdm660_cdc/msm-cdc-common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -19,6 +19,7 @@ extern struct reg_default
msm89xx_pmic_cdc_defaults[MSM89XX_PMIC_CDC_CACHE_SIZE];
bool msm89xx_cdc_core_readable_reg(struct device *dev, unsigned int reg);
+bool msm89xx_cdc_core_writeable_reg(struct device *dev, unsigned int reg);
bool msm89xx_cdc_core_volatile_reg(struct device *dev, unsigned int reg);
enum {
diff --git a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c
index 6c702c8fc35f..4249ada17c87 100644
--- a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c
+++ b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c
@@ -77,8 +77,8 @@ static int msm_digcdc_clock_control(bool flag)
pdata = snd_soc_card_get_drvdata(registered_digcodec->component.card);
- mutex_lock(&pdata->cdc_int_mclk0_mutex);
if (flag) {
+ mutex_lock(&pdata->cdc_int_mclk0_mutex);
if (atomic_read(&pdata->int_mclk0_enabled) == false) {
pdata->digital_cdc_core_clk.enable = 1;
ret = afe_set_lpass_clock_v2(
@@ -93,7 +93,6 @@ static int msm_digcdc_clock_control(bool flag)
*/
if (ret == -ENODEV)
msm_dig_cdc->regmap->cache_only = true;
- mutex_unlock(&pdata->cdc_int_mclk0_mutex);
return ret;
}
pr_debug("enabled digital codec core clk\n");
@@ -102,10 +101,10 @@ static int msm_digcdc_clock_control(bool flag)
50);
}
} else {
+ mutex_unlock(&pdata->cdc_int_mclk0_mutex);
dev_dbg(registered_digcodec->dev,
"disable MCLK, workq to disable set already\n");
}
- mutex_unlock(&pdata->cdc_int_mclk0_mutex);
return 0;
}
@@ -116,6 +115,7 @@ static void enable_digital_callback(void *flag)
static void disable_digital_callback(void *flag)
{
+ msm_digcdc_clock_control(false);
pr_debug("disable mclk happens in workq\n");
}
@@ -982,6 +982,7 @@ static int msm_dig_cdc_event_notify(struct notifier_block *block,
struct snd_soc_codec *codec = registered_digcodec;
struct msm_dig_priv *msm_dig_cdc = snd_soc_codec_get_drvdata(codec);
struct msm_asoc_mach_data *pdata = NULL;
+ int ret = -EINVAL;
pdata = snd_soc_card_get_drvdata(codec->component.card);
@@ -1073,7 +1074,28 @@ static int msm_dig_cdc_event_notify(struct notifier_block *block,
case DIG_CDC_EVENT_SSR_UP:
regcache_cache_only(msm_dig_cdc->regmap, false);
regcache_mark_dirty(msm_dig_cdc->regmap);
+
+ mutex_lock(&pdata->cdc_int_mclk0_mutex);
+ pdata->digital_cdc_core_clk.enable = 1;
+ ret = afe_set_lpass_clock_v2(
+ AFE_PORT_ID_INT0_MI2S_RX,
+ &pdata->digital_cdc_core_clk);
+ if (ret < 0) {
+ pr_err("%s:failed to enable the MCLK\n",
+ __func__);
+ mutex_unlock(&pdata->cdc_int_mclk0_mutex);
+ break;
+ }
+ mutex_unlock(&pdata->cdc_int_mclk0_mutex);
+
regcache_sync(msm_dig_cdc->regmap);
+
+ mutex_lock(&pdata->cdc_int_mclk0_mutex);
+ pdata->digital_cdc_core_clk.enable = 0;
+ afe_set_lpass_clock_v2(
+ AFE_PORT_ID_INT0_MI2S_RX,
+ &pdata->digital_cdc_core_clk);
+ mutex_unlock(&pdata->cdc_int_mclk0_mutex);
break;
case DIG_CDC_EVENT_INVALID:
default:
@@ -2033,6 +2055,7 @@ const struct regmap_config msm_digital_regmap_config = {
.cache_type = REGCACHE_FLAT,
.reg_defaults = msm89xx_cdc_core_defaults,
.num_reg_defaults = MSM89XX_CDC_CORE_MAX_REGISTER,
+ .writeable_reg = msm89xx_cdc_core_writeable_reg,
.readable_reg = msm89xx_cdc_core_readable_reg,
.volatile_reg = msm89xx_cdc_core_volatile_reg,
.reg_format_endian = REGMAP_ENDIAN_NATIVE,
diff --git a/sound/soc/codecs/sdm660_cdc/sdm660-regmap.c b/sound/soc/codecs/sdm660_cdc/sdm660-regmap.c
index c9babac8ffaf..7d8ac6df14bb 100644
--- a/sound/soc/codecs/sdm660_cdc/sdm660-regmap.c
+++ b/sound/soc/codecs/sdm660_cdc/sdm660-regmap.c
@@ -12,6 +12,7 @@
*/
#include <linux/regmap.h>
+#include "msm-cdc-common.h"
#include "sdm660-cdc-registers.h"
/*
@@ -444,11 +445,147 @@ static const u8 msm89xx_cdc_core_reg_readable[MSM89XX_CDC_CORE_CACHE_SIZE] = {
[MSM89XX_CDC_CORE_TX4_DMIC_CTL] = 1,
};
+static const u8 msm89xx_cdc_core_reg_writeable[MSM89XX_CDC_CORE_CACHE_SIZE] = {
+ [MSM89XX_CDC_CORE_CLK_RX_RESET_CTL] = 1,
+ [MSM89XX_CDC_CORE_CLK_TX_RESET_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_CLK_DMIC_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_CLK_RX_I2S_CTL] = 1,
+ [MSM89XX_CDC_CORE_CLK_TX_I2S_CTL] = 1,
+ [MSM89XX_CDC_CORE_CLK_OTHR_RESET_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_CLK_TX_CLK_EN_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_CLK_OTHR_CTL] = 1,
+ [MSM89XX_CDC_CORE_CLK_RX_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_CLK_MCLK_CTL] = 1,
+ [MSM89XX_CDC_CORE_CLK_PDM_CTL] = 1,
+ [MSM89XX_CDC_CORE_CLK_SD_CTL] = 1,
+ [MSM89XX_CDC_CORE_CLK_DMIC_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_CLK_RX_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_CLK_TX2_I2S_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX1_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX2_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX3_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX1_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX2_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX3_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX1_B3_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX2_B3_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX3_B3_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX1_B4_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX2_B4_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX3_B4_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX1_B5_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX2_B5_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX3_B5_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX1_B6_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX2_B6_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX3_B6_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX1_VOL_CTL_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX2_VOL_CTL_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX3_VOL_CTL_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX1_VOL_CTL_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX2_VOL_CTL_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_RX3_VOL_CTL_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_TOP_GAIN_UPDATE] = 1,
+ [MSM89XX_CDC_CORE_TOP_CTL] = 1,
+ [MSM89XX_CDC_CORE_COMP0_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_COMP0_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_COMP0_B3_CTL] = 1,
+ [MSM89XX_CDC_CORE_COMP0_B4_CTL] = 1,
+ [MSM89XX_CDC_CORE_COMP0_B5_CTL] = 1,
+ [MSM89XX_CDC_CORE_COMP0_B6_CTL] = 1,
+ [MSM89XX_CDC_CORE_COMP0_FS_CFG] = 1,
+ [MSM89XX_CDC_CORE_COMP0_DELAY_BUF_CTL] = 1,
+ [MSM89XX_CDC_CORE_DEBUG_DESER1_CTL] = 1,
+ [MSM89XX_CDC_CORE_DEBUG_DESER2_CTL] = 1,
+ [MSM89XX_CDC_CORE_DEBUG_B1_CTL_CFG] = 1,
+ [MSM89XX_CDC_CORE_DEBUG_B2_CTL_CFG] = 1,
+ [MSM89XX_CDC_CORE_DEBUG_B3_CTL_CFG] = 1,
+ [MSM89XX_CDC_CORE_IIR1_GAIN_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR2_GAIN_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR1_GAIN_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR2_GAIN_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR1_GAIN_B3_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR2_GAIN_B3_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR1_GAIN_B4_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR2_GAIN_B4_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR1_GAIN_B5_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR2_GAIN_B5_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR1_GAIN_B6_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR2_GAIN_B6_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR1_GAIN_B7_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR2_GAIN_B7_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR1_GAIN_B8_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR2_GAIN_B8_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR1_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR2_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR1_GAIN_TIMER_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR2_GAIN_TIMER_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR1_COEF_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR2_COEF_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR1_COEF_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_IIR2_COEF_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_RX1_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_RX1_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_RX1_B3_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_RX2_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_RX2_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_RX2_B3_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_RX3_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_RX3_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_TX_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_TX_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_EQ1_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_EQ1_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_EQ1_B3_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_EQ1_B4_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_EQ2_B1_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_EQ2_B2_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_EQ2_B3_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_EQ2_B4_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_TX_I2S_SD1_CTL] = 1,
+ [MSM89XX_CDC_CORE_CONN_TX_B3_CTL] = 1,
+ [MSM89XX_CDC_CORE_TX1_VOL_CTL_TIMER] = 1,
+ [MSM89XX_CDC_CORE_TX2_VOL_CTL_TIMER] = 1,
+ [MSM89XX_CDC_CORE_TX3_VOL_CTL_TIMER] = 1,
+ [MSM89XX_CDC_CORE_TX4_VOL_CTL_TIMER] = 1,
+ [MSM89XX_CDC_CORE_TX1_VOL_CTL_GAIN] = 1,
+ [MSM89XX_CDC_CORE_TX2_VOL_CTL_GAIN] = 1,
+ [MSM89XX_CDC_CORE_TX3_VOL_CTL_GAIN] = 1,
+ [MSM89XX_CDC_CORE_TX4_VOL_CTL_GAIN] = 1,
+ [MSM89XX_CDC_CORE_TX1_VOL_CTL_CFG] = 1,
+ [MSM89XX_CDC_CORE_TX2_VOL_CTL_CFG] = 1,
+ [MSM89XX_CDC_CORE_TX3_VOL_CTL_CFG] = 1,
+ [MSM89XX_CDC_CORE_TX4_VOL_CTL_CFG] = 1,
+ [MSM89XX_CDC_CORE_TX1_MUX_CTL] = 1,
+ [MSM89XX_CDC_CORE_TX2_MUX_CTL] = 1,
+ [MSM89XX_CDC_CORE_TX3_MUX_CTL] = 1,
+ [MSM89XX_CDC_CORE_TX4_MUX_CTL] = 1,
+ [MSM89XX_CDC_CORE_TX1_CLK_FS_CTL] = 1,
+ [MSM89XX_CDC_CORE_TX2_CLK_FS_CTL] = 1,
+ [MSM89XX_CDC_CORE_TX3_CLK_FS_CTL] = 1,
+ [MSM89XX_CDC_CORE_TX4_CLK_FS_CTL] = 1,
+ [MSM89XX_CDC_CORE_TX5_VOL_CTL_TIMER] = 1,
+ [MSM89XX_CDC_CORE_TX5_VOL_CTL_GAIN] = 1,
+ [MSM89XX_CDC_CORE_TX5_VOL_CTL_CFG] = 1,
+ [MSM89XX_CDC_CORE_TX5_MUX_CTL] = 1,
+ [MSM89XX_CDC_CORE_TX5_CLK_FS_CTL] = 1,
+ [MSM89XX_CDC_CORE_TX5_DMIC_CTL] = 1,
+ [MSM89XX_CDC_CORE_TX1_DMIC_CTL] = 1,
+ [MSM89XX_CDC_CORE_TX2_DMIC_CTL] = 1,
+ [MSM89XX_CDC_CORE_TX3_DMIC_CTL] = 1,
+ [MSM89XX_CDC_CORE_TX4_DMIC_CTL] = 1,
+};
+
bool msm89xx_cdc_core_readable_reg(struct device *dev, unsigned int reg)
{
return msm89xx_cdc_core_reg_readable[reg];
}
+bool msm89xx_cdc_core_writeable_reg(struct device *dev, unsigned int reg)
+{
+ return msm89xx_cdc_core_reg_writeable[reg];
+}
+
bool msm89xx_cdc_core_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/sound/soc/codecs/wcd934x/wcd934x.c
index 12a4d348d9a9..26320fd01a5a 100644
--- a/sound/soc/codecs/wcd934x/wcd934x.c
+++ b/sound/soc/codecs/wcd934x/wcd934x.c
@@ -123,6 +123,7 @@ static const struct snd_kcontrol_new name##_mux = \
#define WCD934X_DEC_PWR_LVL_DF 0x00
#define WCD934X_STRING_LEN 100
+#define WCD934X_CDC_SIDETONE_IIR_COEFF_MAX 5
#define WCD934X_DIG_CORE_REG_MIN WCD934X_CDC_ANC0_CLK_RESET_CTL
#define WCD934X_DIG_CORE_REG_MAX 0xFFF
@@ -654,6 +655,8 @@ struct tavil_priv {
struct tavil_idle_detect_config idle_det_cfg;
int power_active_ref;
+ int sidetone_coeff_array[IIR_MAX][BAND_MAX]
+ [WCD934X_CDC_SIDETONE_IIR_COEFF_MAX];
};
static const struct tavil_reg_mask_val tavil_spkr_default[] = {
@@ -5162,10 +5165,12 @@ static int tavil_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
int iir_idx = ((struct soc_multi_mixer_control *)
kcontrol->private_value)->reg;
int band_idx = ((struct soc_multi_mixer_control *)
kcontrol->private_value)->shift;
+ int coeff_idx;
/*
* Mask top bit it is reserved
@@ -5175,16 +5180,15 @@ static int tavil_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol,
(WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
(band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
- set_iir_band_coeff(codec, iir_idx, band_idx,
- ucontrol->value.integer.value[0]);
- set_iir_band_coeff(codec, iir_idx, band_idx,
- ucontrol->value.integer.value[1]);
- set_iir_band_coeff(codec, iir_idx, band_idx,
- ucontrol->value.integer.value[2]);
- set_iir_band_coeff(codec, iir_idx, band_idx,
- ucontrol->value.integer.value[3]);
- set_iir_band_coeff(codec, iir_idx, band_idx,
- ucontrol->value.integer.value[4]);
+ /* Store the coefficients in sidetone coeff array */
+ for (coeff_idx = 0; coeff_idx < WCD934X_CDC_SIDETONE_IIR_COEFF_MAX;
+ coeff_idx++) {
+ tavil->sidetone_coeff_array[iir_idx][band_idx][coeff_idx] =
+ ucontrol->value.integer.value[coeff_idx];
+ set_iir_band_coeff(codec, iir_idx, band_idx,
+ tavil->sidetone_coeff_array[iir_idx][band_idx]
+ [coeff_idx]);
+ }
pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
"%s: IIR #%d band #%d b1 = 0x%x\n"
@@ -5204,6 +5208,26 @@ static int tavil_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol,
return 0;
}
+static void tavil_restore_iir_coeff(struct tavil_priv *tavil, int iir_idx)
+{
+ int band_idx = 0, coeff_idx = 0;
+ struct snd_soc_codec *codec = tavil->codec;
+
+ for (band_idx = 0; band_idx < BAND_MAX; band_idx++) {
+ snd_soc_write(codec,
+ (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
+ (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
+
+ for (coeff_idx = 0;
+ coeff_idx < WCD934X_CDC_SIDETONE_IIR_COEFF_MAX;
+ coeff_idx++) {
+ set_iir_band_coeff(codec, iir_idx, band_idx,
+ tavil->sidetone_coeff_array[iir_idx][band_idx]
+ [coeff_idx]);
+ }
+ }
+}
+
static int tavil_compander_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -8156,6 +8180,8 @@ static int tavil_dig_core_remove_power_collapse(struct tavil_priv *tavil)
WCD934X_DIG_CORE_REG_MIN,
WCD934X_DIG_CORE_REG_MAX);
+ tavil_restore_iir_coeff(tavil, IIR0);
+ tavil_restore_iir_coeff(tavil, IIR1);
return 0;
}
diff --git a/sound/soc/msm/apq8096-auto.c b/sound/soc/msm/apq8096-auto.c
index be6a6a710dc1..b6121d75c148 100644
--- a/sound/soc/msm/apq8096-auto.c
+++ b/sound/soc/msm/apq8096-auto.c
@@ -3149,10 +3149,10 @@ static struct snd_soc_dai_link apq8096_common_dai_links[] = {
.be_id = MSM_FRONTEND_DAI_MULTIMEDIA10,
},
{
- .name = "MSM8996 Compr8",
- .stream_name = "COMPR8",
+ .name = "MSM8996 ULL NOIRQ",
+ .stream_name = "MM_NOIRQ",
.cpu_dai_name = "MultiMedia8",
- .platform_name = "msm-compr-dsp",
+ .platform_name = "msm-pcm-dsp-noirq",
.dynamic = 1,
.dpcm_playback = 1,
.dpcm_capture = 1,
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 509574faebf8..24dbbedf0be7 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -2582,7 +2582,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 192000,
},
.ops = &msm_fe_Multimedia_dai_ops,
.compress_new = snd_soc_new_compress,
diff --git a/sound/soc/msm/msm8998.c b/sound/soc/msm/msm8998.c
index f6a5d1344568..15c596f54926 100644
--- a/sound/soc/msm/msm8998.c
+++ b/sound/soc/msm/msm8998.c
@@ -5498,6 +5498,37 @@ static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = {
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
},
+ {
+ .name = MSM_DAILINK_NAME(Transcode Loopback Playback),
+ .stream_name = "Transcode Loopback Playback",
+ .cpu_dai_name = "MultiMedia14",
+ .platform_name = "msm-transcode-loopback",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA14,
+ },
+ {
+ .name = MSM_DAILINK_NAME(Transcode Loopback Capture),
+ .stream_name = "Transcode Loopback Capture",
+ .cpu_dai_name = "MultiMedia18",
+ .platform_name = "msm-transcode-loopback",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA18,
+ },
};
static struct snd_soc_dai_link msm_common_be_dai_links[] = {
diff --git a/sound/soc/msm/qdsp6v2/Makefile b/sound/soc/msm/qdsp6v2/Makefile
index 219892a85da2..98c52a4db51f 100644
--- a/sound/soc/msm/qdsp6v2/Makefile
+++ b/sound/soc/msm/qdsp6v2/Makefile
@@ -4,7 +4,7 @@ snd-soc-qdsp6v2-objs += msm-dai-q6-v2.o msm-pcm-q6-v2.o msm-pcm-routing-v2.o \
msm-pcm-voice-v2.o msm-dai-q6-hdmi-v2.o \
msm-lsm-client.o msm-pcm-host-voice-v2.o \
msm-audio-effects-q6-v2.o msm-pcm-loopback-v2.o \
- msm-dai-slim.o \
+ msm-dai-slim.o msm-transcode-loopback-q6-v2.o \
adsp_err.o
obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o msm-pcm-dtmf-v2.o \
msm-dai-stub-v2.o
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 32f68fedcd3b..8744eb166261 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -1077,7 +1077,10 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
port_type = MSM_AFE_PORT_TYPE_RX;
} else if (stream_type == SNDRV_PCM_STREAM_CAPTURE) {
session_type = SESSION_TYPE_TX;
- path_type = ADM_PATH_LIVE_REC;
+ if (passthr_mode != LEGACY_PCM)
+ path_type = ADM_PATH_COMPRESSED_TX;
+ else
+ path_type = ADM_PATH_LIVE_REC;
port_type = MSM_AFE_PORT_TYPE_TX;
} else {
pr_err("%s: invalid stream type %d\n", __func__, stream_type);
@@ -1514,7 +1517,10 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
path_type = ADM_PATH_PLAYBACK;
} else {
session_type = SESSION_TYPE_TX;
- path_type = ADM_PATH_LIVE_REC;
+ if (passthr_mode != LEGACY_PCM)
+ path_type = ADM_PATH_COMPRESSED_TX;
+ else
+ path_type = ADM_PATH_LIVE_REC;
}
is_lsm = (val >= MSM_FRONTEND_DAI_LSM1) &&
(val <= MSM_FRONTEND_DAI_LSM8);
@@ -6449,6 +6455,9 @@ static const struct snd_kcontrol_new mmul18_mixer_controls[] = {
SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -11913,6 +11922,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MultiMedia18 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia19 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia8 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+ {"MultiMedia18 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
{"MultiMedia8 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"MultiMedia3 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"MultiMedia5 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
diff --git a/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c
new file mode 100644
index 000000000000..dbda90c3616d
--- /dev/null
+++ b/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c
@@ -0,0 +1,971 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/time.h>
+#include <linux/math64.h>
+#include <linux/wait.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/msm_audio_ion.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+#include <sound/control.h>
+#include <sound/q6asm-v2.h>
+#include <sound/pcm_params.h>
+#include <sound/timer.h>
+#include <sound/tlv.h>
+#include <sound/apr_audio-v2.h>
+#include <sound/compress_params.h>
+#include <sound/compress_offload.h>
+#include <sound/compress_driver.h>
+#include <linux/msm_audio.h>
+
+#include "msm-pcm-routing-v2.h"
+#include "msm-qti-pp-config.h"
+
+#define LOOPBACK_SESSION_MAX_NUM_STREAMS 2
+
+static DEFINE_MUTEX(transcode_loopback_session_lock);
+
+struct trans_loopback_pdata {
+ struct snd_compr_stream *cstream[MSM_FRONTEND_DAI_MAX];
+};
+
+struct loopback_stream {
+ struct snd_compr_stream *cstream;
+ uint32_t codec_format;
+ bool start;
+};
+
+enum loopback_session_state {
+ /* One or both streams not opened */
+ LOOPBACK_SESSION_CLOSE = 0,
+ /* Loopback streams opened */
+ LOOPBACK_SESSION_READY,
+ /* Loopback streams opened and formats configured */
+ LOOPBACK_SESSION_START,
+ /* Trigger issued on either of streams when in START state */
+ LOOPBACK_SESSION_RUN
+};
+
+struct msm_transcode_loopback {
+ struct loopback_stream source;
+ struct loopback_stream sink;
+
+ struct snd_compr_caps source_compr_cap;
+ struct snd_compr_caps sink_compr_cap;
+
+ uint32_t instance;
+ uint32_t num_streams;
+ int session_state;
+
+ struct mutex lock;
+
+ int session_id;
+ struct audio_client *audio_client;
+};
+
+/* Transcode loopback global info struct */
+static struct msm_transcode_loopback transcode_info;
+
+static void loopback_event_handler(uint32_t opcode,
+ uint32_t token, uint32_t *payload, void *priv)
+{
+ struct msm_transcode_loopback *trans =
+ (struct msm_transcode_loopback *)priv;
+ struct snd_soc_pcm_runtime *rtd;
+ struct snd_compr_stream *cstream;
+ struct audio_client *ac;
+ int stream_id;
+ int ret;
+
+ if (!trans || !payload) {
+ pr_err("%s: rtd or payload is NULL\n", __func__);
+ return;
+ }
+
+ cstream = trans->source.cstream;
+ ac = trans->audio_client;
+
+ /*
+ * Token for rest of the compressed commands use to set
+ * session id, stream id, dir etc.
+ */
+ stream_id = q6asm_get_stream_id_from_token(token);
+
+ switch (opcode) {
+ case ASM_STREAM_CMD_ENCDEC_EVENTS:
+ case ASM_IEC_61937_MEDIA_FMT_EVENT:
+ pr_debug("%s: ASM_IEC_61937_MEDIA_FMT_EVENT\n", __func__);
+ rtd = cstream->private_data;
+ if (!rtd) {
+ pr_err("%s: rtd is NULL\n", __func__);
+ return;
+ }
+
+ ret = msm_adsp_inform_mixer_ctl(rtd, payload);
+ if (ret) {
+ pr_err("%s: failed to inform mixer ctrl. err = %d\n",
+ __func__, ret);
+ return;
+ }
+ break;
+ case APR_BASIC_RSP_RESULT: {
+ switch (payload[0]) {
+ case ASM_SESSION_CMD_RUN_V2:
+ pr_debug("%s: ASM_SESSION_CMD_RUN_V2:", __func__);
+ pr_debug("token 0x%x, stream id %d\n", token,
+ stream_id);
+ break;
+ case ASM_STREAM_CMD_CLOSE:
+ pr_debug("%s: ASM_DATA_CMD_CLOSE:", __func__);
+ pr_debug("token 0x%x, stream id %d\n", token,
+ stream_id);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ pr_debug("%s: Not Supported Event opcode[0x%x]\n",
+ __func__, opcode);
+ break;
+ }
+}
+
+static void populate_codec_list(struct msm_transcode_loopback *trans,
+ struct snd_compr_stream *cstream)
+{
+ struct snd_compr_caps compr_cap;
+
+ pr_debug("%s\n", __func__);
+
+ memset(&compr_cap, 0, sizeof(struct snd_compr_caps));
+
+ if (cstream->direction == SND_COMPRESS_CAPTURE) {
+ compr_cap.direction = SND_COMPRESS_CAPTURE;
+ compr_cap.num_codecs = 3;
+ compr_cap.codecs[0] = SND_AUDIOCODEC_PCM;
+ compr_cap.codecs[1] = SND_AUDIOCODEC_AC3;
+ compr_cap.codecs[2] = SND_AUDIOCODEC_EAC3;
+ memcpy(&trans->source_compr_cap, &compr_cap,
+ sizeof(struct snd_compr_caps));
+ }
+
+ if (cstream->direction == SND_COMPRESS_PLAYBACK) {
+ compr_cap.direction = SND_COMPRESS_PLAYBACK;
+ compr_cap.num_codecs = 1;
+ compr_cap.codecs[0] = SND_AUDIOCODEC_PCM;
+ memcpy(&trans->sink_compr_cap, &compr_cap,
+ sizeof(struct snd_compr_caps));
+ }
+}
+
+static int msm_transcode_loopback_open(struct snd_compr_stream *cstream)
+{
+ int ret = 0;
+ struct snd_compr_runtime *runtime;
+ struct snd_soc_pcm_runtime *rtd;
+ struct msm_transcode_loopback *trans = &transcode_info;
+ struct trans_loopback_pdata *pdata;
+
+ if (cstream == NULL) {
+ pr_err("%s: Invalid substream\n", __func__);
+ return -EINVAL;
+ }
+ runtime = cstream->runtime;
+ rtd = snd_pcm_substream_chip(cstream);
+ pdata = snd_soc_platform_get_drvdata(rtd->platform);
+ pdata->cstream[rtd->dai_link->be_id] = cstream;
+
+ mutex_lock(&trans->lock);
+ if (trans->num_streams > LOOPBACK_SESSION_MAX_NUM_STREAMS) {
+ pr_err("msm_transcode_open failed..invalid stream\n");
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if (cstream->direction == SND_COMPRESS_CAPTURE) {
+ if (trans->source.cstream == NULL) {
+ trans->source.cstream = cstream;
+ trans->num_streams++;
+ } else {
+ pr_err("%s: capture stream already opened\n",
+ __func__);
+ ret = -EINVAL;
+ goto exit;
+ }
+ } else if (cstream->direction == SND_COMPRESS_PLAYBACK) {
+ if (trans->sink.cstream == NULL) {
+ trans->sink.cstream = cstream;
+ trans->num_streams++;
+ } else {
+ pr_debug("%s: playback stream already opened\n",
+ __func__);
+ ret = -EINVAL;
+ goto exit;
+ }
+ }
+
+ pr_debug("%s: num stream%d, stream name %s\n", __func__,
+ trans->num_streams, cstream->name);
+
+ populate_codec_list(trans, cstream);
+
+ if (trans->num_streams == LOOPBACK_SESSION_MAX_NUM_STREAMS) {
+ pr_debug("%s: Moving loopback session to READY state %d\n",
+ __func__, trans->session_state);
+ trans->session_state = LOOPBACK_SESSION_READY;
+ }
+
+ runtime->private_data = trans;
+ if (trans->num_streams == 1)
+ msm_adsp_init_mixer_ctl_pp_event_queue(rtd);
+exit:
+ mutex_unlock(&trans->lock);
+ return ret;
+}
+
+static void stop_transcoding(struct msm_transcode_loopback *trans)
+{
+ struct snd_soc_pcm_runtime *soc_pcm_rx;
+ struct snd_soc_pcm_runtime *soc_pcm_tx;
+
+ if (trans->audio_client != NULL) {
+ q6asm_cmd(trans->audio_client, CMD_CLOSE);
+
+ if (trans->sink.cstream != NULL) {
+ soc_pcm_rx = trans->sink.cstream->private_data;
+ msm_pcm_routing_dereg_phy_stream(
+ soc_pcm_rx->dai_link->be_id,
+ SND_COMPRESS_PLAYBACK);
+ }
+ if (trans->source.cstream != NULL) {
+ soc_pcm_tx = trans->source.cstream->private_data;
+ msm_pcm_routing_dereg_phy_stream(
+ soc_pcm_tx->dai_link->be_id,
+ SND_COMPRESS_CAPTURE);
+ }
+ q6asm_audio_client_free(trans->audio_client);
+ trans->audio_client = NULL;
+ }
+}
+
+static int msm_transcode_loopback_free(struct snd_compr_stream *cstream)
+{
+ struct snd_compr_runtime *runtime = cstream->runtime;
+ struct msm_transcode_loopback *trans = runtime->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(cstream);
+ int ret = 0;
+
+ mutex_lock(&trans->lock);
+
+ pr_debug("%s: Transcode loopback end:%d, streams %d\n", __func__,
+ cstream->direction, trans->num_streams);
+ trans->num_streams--;
+ stop_transcoding(trans);
+
+ if (cstream->direction == SND_COMPRESS_PLAYBACK)
+ memset(&trans->sink, 0, sizeof(struct loopback_stream));
+ else if (cstream->direction == SND_COMPRESS_CAPTURE)
+ memset(&trans->source, 0, sizeof(struct loopback_stream));
+
+ trans->session_state = LOOPBACK_SESSION_CLOSE;
+ if (trans->num_streams == 1)
+ msm_adsp_clean_mixer_ctl_pp_event_queue(rtd);
+ mutex_unlock(&trans->lock);
+ return ret;
+}
+
+static int msm_transcode_loopback_trigger(struct snd_compr_stream *cstream,
+ int cmd)
+{
+ struct snd_compr_runtime *runtime = cstream->runtime;
+ struct msm_transcode_loopback *trans = runtime->private_data;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+
+ if (trans->session_state == LOOPBACK_SESSION_START) {
+ pr_debug("%s: Issue Loopback session %d RUN\n",
+ __func__, trans->instance);
+ q6asm_run_nowait(trans->audio_client, 0, 0, 0);
+ trans->session_state = LOOPBACK_SESSION_RUN;
+ }
+ break;
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ case SNDRV_PCM_TRIGGER_STOP:
+ pr_debug("%s: Issue Loopback session %d STOP\n", __func__,
+ trans->instance);
+ if (trans->session_state == LOOPBACK_SESSION_RUN)
+ q6asm_cmd_nowait(trans->audio_client, CMD_PAUSE);
+ trans->session_state = LOOPBACK_SESSION_START;
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream,
+ struct snd_compr_params *codec_param)
+{
+
+ struct snd_compr_runtime *runtime = cstream->runtime;
+ struct msm_transcode_loopback *trans = runtime->private_data;
+ struct snd_soc_pcm_runtime *soc_pcm_rx;
+ struct snd_soc_pcm_runtime *soc_pcm_tx;
+ uint32_t bit_width = 16;
+ int ret = 0;
+
+ if (trans == NULL) {
+ pr_err("%s: Invalid param\n", __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&trans->lock);
+
+ if (cstream->direction == SND_COMPRESS_PLAYBACK) {
+ if (codec_param->codec.id == SND_AUDIOCODEC_PCM) {
+ trans->sink.codec_format =
+ FORMAT_LINEAR_PCM;
+ switch (codec_param->codec.format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ bit_width = 32;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ bit_width = 24;
+ break;
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ bit_width = 24;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ bit_width = 16;
+ break;
+ }
+ } else {
+ pr_debug("%s: unknown sink codec\n", __func__);
+ ret = -EINVAL;
+ goto exit;
+ }
+ trans->sink.start = true;
+ }
+
+ if (cstream->direction == SND_COMPRESS_CAPTURE) {
+ switch (codec_param->codec.id) {
+ case SND_AUDIOCODEC_PCM:
+ pr_debug("Source SND_AUDIOCODEC_PCM\n");
+ trans->source.codec_format =
+ FORMAT_LINEAR_PCM;
+ break;
+ case SND_AUDIOCODEC_AC3:
+ pr_debug("Source SND_AUDIOCODEC_AC3\n");
+ trans->source.codec_format =
+ FORMAT_AC3;
+ break;
+ case SND_AUDIOCODEC_EAC3:
+ pr_debug("Source SND_AUDIOCODEC_EAC3\n");
+ trans->source.codec_format =
+ FORMAT_EAC3;
+ break;
+ default:
+ pr_debug("%s: unknown source codec\n", __func__);
+ ret = -EINVAL;
+ goto exit;
+ }
+ trans->source.start = true;
+ }
+
+ pr_debug("%s: trans->source.start %d trans->sink.start %d trans->source.cstream %pK trans->sink.cstream %pK trans->session_state %d\n",
+ __func__, trans->source.start, trans->sink.start,
+ trans->source.cstream, trans->sink.cstream,
+ trans->session_state);
+
+ if ((trans->session_state == LOOPBACK_SESSION_READY) &&
+ trans->source.start && trans->sink.start) {
+ pr_debug("%s: Moving loopback session to start state\n",
+ __func__);
+ trans->session_state = LOOPBACK_SESSION_START;
+ }
+
+ if (trans->session_state == LOOPBACK_SESSION_START) {
+ if (trans->audio_client != NULL) {
+ pr_debug("%s: ASM client already opened, closing\n",
+ __func__);
+ stop_transcoding(trans);
+ }
+
+ trans->audio_client = q6asm_audio_client_alloc(
+ (app_cb)loopback_event_handler, trans);
+ if (!trans->audio_client) {
+ pr_err("%s: Could not allocate memory\n", __func__);
+ ret = -EINVAL;
+ goto exit;
+ }
+ pr_debug("%s: ASM client allocated, callback %pK\n", __func__,
+ loopback_event_handler);
+ trans->session_id = trans->audio_client->session;
+ trans->audio_client->perf_mode = false;
+ ret = q6asm_open_transcode_loopback(trans->audio_client,
+ bit_width,
+ trans->source.codec_format,
+ trans->sink.codec_format);
+ if (ret < 0) {
+ pr_err("%s: Session transcode loopback open failed\n",
+ __func__);
+ q6asm_audio_client_free(trans->audio_client);
+ trans->audio_client = NULL;
+ goto exit;
+ }
+
+ pr_debug("%s: Starting ADM open for loopback\n", __func__);
+ soc_pcm_rx = trans->sink.cstream->private_data;
+ soc_pcm_tx = trans->source.cstream->private_data;
+ if (trans->source.codec_format != FORMAT_LINEAR_PCM)
+ msm_pcm_routing_reg_phy_compr_stream(
+ soc_pcm_tx->dai_link->be_id,
+ trans->audio_client->perf_mode,
+ trans->session_id,
+ SNDRV_PCM_STREAM_CAPTURE,
+ true);
+ else
+ msm_pcm_routing_reg_phy_stream(
+ soc_pcm_tx->dai_link->be_id,
+ trans->audio_client->perf_mode,
+ trans->session_id,
+ SNDRV_PCM_STREAM_CAPTURE);
+
+ msm_pcm_routing_reg_phy_stream(
+ soc_pcm_rx->dai_link->be_id,
+ trans->audio_client->perf_mode,
+ trans->session_id,
+ SNDRV_PCM_STREAM_PLAYBACK);
+ pr_debug("%s: Successfully opened ADM sessions\n", __func__);
+ }
+exit:
+ mutex_unlock(&trans->lock);
+ return ret;
+}
+
+static int msm_transcode_loopback_get_caps(struct snd_compr_stream *cstream,
+ struct snd_compr_caps *arg)
+{
+ struct snd_compr_runtime *runtime;
+ struct msm_transcode_loopback *trans;
+
+ if (!arg || !cstream) {
+ pr_err("%s: Invalid arguments\n", __func__);
+ return -EINVAL;
+ }
+
+ runtime = cstream->runtime;
+ trans = runtime->private_data;
+ pr_debug("%s\n", __func__);
+ if (cstream->direction == SND_COMPRESS_CAPTURE)
+ memcpy(arg, &trans->source_compr_cap,
+ sizeof(struct snd_compr_caps));
+ else
+ memcpy(arg, &trans->sink_compr_cap,
+ sizeof(struct snd_compr_caps));
+ return 0;
+}
+
+static int msm_transcode_stream_cmd_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ unsigned long fe_id = kcontrol->private_value;
+ struct trans_loopback_pdata *pdata = (struct trans_loopback_pdata *)
+ snd_soc_component_get_drvdata(comp);
+ struct snd_compr_stream *cstream = NULL;
+ struct msm_transcode_loopback *prtd;
+ int ret = 0;
+ struct msm_adsp_event_data *event_data = NULL;
+
+ if (fe_id >= MSM_FRONTEND_DAI_MAX) {
+ pr_err("%s Received invalid fe_id %lu\n",
+ __func__, fe_id);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ cstream = pdata->cstream[fe_id];
+ if (cstream == NULL) {
+ pr_err("%s cstream is null.\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ prtd = cstream->runtime->private_data;
+ if (!prtd) {
+ pr_err("%s: prtd is null.\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (prtd->audio_client == NULL) {
+ pr_err("%s: audio_client is null.\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ event_data = (struct msm_adsp_event_data *)ucontrol->value.bytes.data;
+ if ((event_data->event_type < ADSP_STREAM_PP_EVENT) ||
+ (event_data->event_type >= ADSP_STREAM_EVENT_MAX)) {
+ pr_err("%s: invalid event_type=%d",
+ __func__, event_data->event_type);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >=
+ sizeof(ucontrol->value.bytes.data)) {
+ pr_err("%s param length=%d exceeds limit",
+ __func__, event_data->payload_len);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = q6asm_send_stream_cmd(prtd->audio_client, event_data);
+ if (ret < 0)
+ pr_err("%s: failed to send stream event cmd, err = %d\n",
+ __func__, ret);
+done:
+ return ret;
+}
+
+static int msm_transcode_ion_fd_map_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ unsigned long fe_id = kcontrol->private_value;
+ struct trans_loopback_pdata *pdata = (struct trans_loopback_pdata *)
+ snd_soc_component_get_drvdata(comp);
+ struct snd_compr_stream *cstream = NULL;
+ struct msm_transcode_loopback *prtd;
+ int fd;
+ int ret = 0;
+
+ if (fe_id >= MSM_FRONTEND_DAI_MAX) {
+ pr_err("%s Received out of bounds invalid fe_id %lu\n",
+ __func__, fe_id);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ cstream = pdata->cstream[fe_id];
+ if (cstream == NULL) {
+ pr_err("%s cstream is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ prtd = cstream->runtime->private_data;
+ if (!prtd) {
+ pr_err("%s: prtd is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (prtd->audio_client == NULL) {
+ pr_err("%s: audio_client is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ memcpy(&fd, ucontrol->value.bytes.data, sizeof(fd));
+ ret = q6asm_send_ion_fd(prtd->audio_client, fd);
+ if (ret < 0)
+ pr_err("%s: failed to register ion fd\n", __func__);
+done:
+ return ret;
+}
+
+static int msm_transcode_rtic_event_ack_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ unsigned long fe_id = kcontrol->private_value;
+ struct trans_loopback_pdata *pdata = (struct trans_loopback_pdata *)
+ snd_soc_component_get_drvdata(comp);
+ struct snd_compr_stream *cstream = NULL;
+ struct msm_transcode_loopback *prtd;
+ int ret = 0;
+ int param_length = 0;
+
+ if (fe_id >= MSM_FRONTEND_DAI_MAX) {
+ pr_err("%s Received invalid fe_id %lu\n",
+ __func__, fe_id);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ cstream = pdata->cstream[fe_id];
+ if (cstream == NULL) {
+ pr_err("%s cstream is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ prtd = cstream->runtime->private_data;
+ if (!prtd) {
+ pr_err("%s: prtd is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (prtd->audio_client == NULL) {
+ pr_err("%s: audio_client is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ memcpy(&param_length, ucontrol->value.bytes.data,
+ sizeof(param_length));
+ if ((param_length + sizeof(param_length))
+ >= sizeof(ucontrol->value.bytes.data)) {
+ pr_err("%s param length=%d exceeds limit",
+ __func__, param_length);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = q6asm_send_rtic_event_ack(prtd->audio_client,
+ ucontrol->value.bytes.data + sizeof(param_length),
+ param_length);
+ if (ret < 0)
+ pr_err("%s: failed to send rtic event ack, err = %d\n",
+ __func__, ret);
+done:
+ return ret;
+}
+
+static int msm_transcode_stream_cmd_control(
+ struct snd_soc_pcm_runtime *rtd)
+{
+ const char *mixer_ctl_name = DSP_STREAM_CMD;
+ const char *deviceNo = "NN";
+ char *mixer_str = NULL;
+ int ctl_len = 0, ret = 0;
+ struct snd_kcontrol_new fe_loopback_stream_cmd_config_control[1] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "?",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = msm_adsp_stream_cmd_info,
+ .put = msm_transcode_stream_cmd_put,
+ .private_value = 0,
+ }
+ };
+
+ if (!rtd) {
+ pr_err("%s NULL rtd\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
+ mixer_str = kzalloc(ctl_len, GFP_KERNEL);
+ if (!mixer_str) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
+ fe_loopback_stream_cmd_config_control[0].name = mixer_str;
+ fe_loopback_stream_cmd_config_control[0].private_value =
+ rtd->dai_link->be_id;
+ pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
+ ret = snd_soc_add_platform_controls(rtd->platform,
+ fe_loopback_stream_cmd_config_control,
+ ARRAY_SIZE(fe_loopback_stream_cmd_config_control));
+ if (ret < 0)
+ pr_err("%s: failed to add ctl %s. err = %d\n",
+ __func__, mixer_str, ret);
+
+ kfree(mixer_str);
+done:
+ return ret;
+}
+
+static int msm_transcode_stream_callback_control(
+ struct snd_soc_pcm_runtime *rtd)
+{
+ const char *mixer_ctl_name = DSP_STREAM_CALLBACK;
+ const char *deviceNo = "NN";
+ char *mixer_str = NULL;
+ int ctl_len = 0, ret = 0;
+ struct snd_kcontrol *kctl;
+
+ struct snd_kcontrol_new fe_loopback_callback_config_control[1] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "?",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = msm_adsp_stream_callback_info,
+ .get = msm_adsp_stream_callback_get,
+ .private_value = 0,
+ }
+ };
+
+ if (!rtd) {
+ pr_err("%s: rtd is NULL\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
+ mixer_str = kzalloc(ctl_len, GFP_KERNEL);
+ if (!mixer_str) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
+ fe_loopback_callback_config_control[0].name = mixer_str;
+ fe_loopback_callback_config_control[0].private_value =
+ rtd->dai_link->be_id;
+ pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
+ ret = snd_soc_add_platform_controls(rtd->platform,
+ fe_loopback_callback_config_control,
+ ARRAY_SIZE(fe_loopback_callback_config_control));
+ if (ret < 0) {
+ pr_err("%s: failed to add ctl %s. err = %d\n",
+ __func__, mixer_str, ret);
+ ret = -EINVAL;
+ goto free_mixer_str;
+ }
+
+ kctl = snd_soc_card_get_kcontrol(rtd->card, mixer_str);
+ if (!kctl) {
+ pr_err("%s: failed to get kctl %s.\n", __func__, mixer_str);
+ ret = -EINVAL;
+ goto free_mixer_str;
+ }
+
+ kctl->private_data = NULL;
+free_mixer_str:
+ kfree(mixer_str);
+done:
+ return ret;
+}
+
+static int msm_transcode_add_ion_fd_cmd_control(struct snd_soc_pcm_runtime *rtd)
+{
+ const char *mixer_ctl_name = "Playback ION FD";
+ const char *deviceNo = "NN";
+ char *mixer_str = NULL;
+ int ctl_len = 0, ret = 0;
+ struct snd_kcontrol_new fe_ion_fd_config_control[1] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "?",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = msm_adsp_stream_cmd_info,
+ .put = msm_transcode_ion_fd_map_put,
+ .private_value = 0,
+ }
+ };
+
+ if (!rtd) {
+ pr_err("%s NULL rtd\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
+ mixer_str = kzalloc(ctl_len, GFP_KERNEL);
+ if (!mixer_str) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
+ fe_ion_fd_config_control[0].name = mixer_str;
+ fe_ion_fd_config_control[0].private_value = rtd->dai_link->be_id;
+ pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
+ ret = snd_soc_add_platform_controls(rtd->platform,
+ fe_ion_fd_config_control,
+ ARRAY_SIZE(fe_ion_fd_config_control));
+ if (ret < 0)
+ pr_err("%s: failed to add ctl %s\n", __func__, mixer_str);
+
+ kfree(mixer_str);
+done:
+ return ret;
+}
+
+static int msm_transcode_add_event_ack_cmd_control(
+ struct snd_soc_pcm_runtime *rtd)
+{
+ const char *mixer_ctl_name = "Playback Event Ack";
+ const char *deviceNo = "NN";
+ char *mixer_str = NULL;
+ int ctl_len = 0, ret = 0;
+ struct snd_kcontrol_new fe_event_ack_config_control[1] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "?",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = msm_adsp_stream_cmd_info,
+ .put = msm_transcode_rtic_event_ack_put,
+ .private_value = 0,
+ }
+ };
+
+ if (!rtd) {
+ pr_err("%s NULL rtd\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
+ mixer_str = kzalloc(ctl_len, GFP_KERNEL);
+ if (!mixer_str) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
+ fe_event_ack_config_control[0].name = mixer_str;
+ fe_event_ack_config_control[0].private_value = rtd->dai_link->be_id;
+ pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
+ ret = snd_soc_add_platform_controls(rtd->platform,
+ fe_event_ack_config_control,
+ ARRAY_SIZE(fe_event_ack_config_control));
+ if (ret < 0)
+ pr_err("%s: failed to add ctl %s\n", __func__, mixer_str);
+
+ kfree(mixer_str);
+done:
+ return ret;
+}
+
+static int msm_transcode_loopback_new(struct snd_soc_pcm_runtime *rtd)
+{
+ int rc;
+
+ rc = msm_transcode_stream_cmd_control(rtd);
+ if (rc)
+ pr_err("%s: ADSP Stream Cmd Control open failed\n", __func__);
+
+ rc = msm_transcode_stream_callback_control(rtd);
+ if (rc)
+ pr_err("%s: ADSP Stream callback Control open failed\n",
+ __func__);
+
+ rc = msm_transcode_add_ion_fd_cmd_control(rtd);
+ if (rc)
+ pr_err("%s: Could not add transcode ion fd Control\n",
+ __func__);
+
+ rc = msm_transcode_add_event_ack_cmd_control(rtd);
+ if (rc)
+ pr_err("%s: Could not add transcode event ack Control\n",
+ __func__);
+
+ return 0;
+}
+
+static struct snd_compr_ops msm_transcode_loopback_ops = {
+ .open = msm_transcode_loopback_open,
+ .free = msm_transcode_loopback_free,
+ .trigger = msm_transcode_loopback_trigger,
+ .set_params = msm_transcode_loopback_set_params,
+ .get_caps = msm_transcode_loopback_get_caps,
+};
+
+
+static int msm_transcode_loopback_probe(struct snd_soc_platform *platform)
+{
+ struct trans_loopback_pdata *pdata = NULL;
+
+ pr_debug("%s\n", __func__);
+ pdata = (struct trans_loopback_pdata *)
+ kzalloc(sizeof(struct trans_loopback_pdata),
+ GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ snd_soc_platform_set_drvdata(platform, pdata);
+ return 0;
+}
+
+static struct snd_soc_platform_driver msm_soc_platform = {
+ .probe = msm_transcode_loopback_probe,
+ .compr_ops = &msm_transcode_loopback_ops,
+ .pcm_new = msm_transcode_loopback_new,
+};
+
+static int msm_transcode_dev_probe(struct platform_device *pdev)
+{
+
+ pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev));
+ if (pdev->dev.of_node)
+ dev_set_name(&pdev->dev, "%s", "msm-transcode-loopback");
+
+ return snd_soc_register_platform(&pdev->dev,
+ &msm_soc_platform);
+}
+
+static int msm_transcode_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_platform(&pdev->dev);
+ return 0;
+}
+
+static const struct of_device_id msm_transcode_loopback_dt_match[] = {
+ {.compatible = "qcom,msm-transcode-loopback"},
+ {}
+};
+MODULE_DEVICE_TABLE(of, msm_transcode_loopback_dt_match);
+
+static struct platform_driver msm_transcode_loopback_driver = {
+ .driver = {
+ .name = "msm-transcode-loopback",
+ .owner = THIS_MODULE,
+ .of_match_table = msm_transcode_loopback_dt_match,
+ },
+ .probe = msm_transcode_dev_probe,
+ .remove = msm_transcode_remove,
+};
+
+static int __init msm_soc_platform_init(void)
+{
+ memset(&transcode_info, 0, sizeof(struct msm_transcode_loopback));
+ mutex_init(&transcode_info.lock);
+ return platform_driver_register(&msm_transcode_loopback_driver);
+}
+module_init(msm_soc_platform_init);
+
+static void __exit msm_soc_platform_exit(void)
+{
+ mutex_destroy(&transcode_info.lock);
+ platform_driver_unregister(&msm_transcode_loopback_driver);
+}
+module_exit(msm_soc_platform_exit);
+
+MODULE_DESCRIPTION("Transcode loopback platform driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index 9f00e1bc4a3d..7cf19a9ed335 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -2156,7 +2156,8 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
(topology == SRS_TRUMEDIA_TOPOLOGY_ID))
topology = DEFAULT_COPP_TOPOLOGY;
} else {
- if (path == ADM_PATH_COMPRESSED_RX)
+ if ((path == ADM_PATH_COMPRESSED_RX) ||
+ (path == ADM_PATH_COMPRESSED_TX))
flags = 0;
else
flags = ADM_LEGACY_DEVICE_SESSION;
@@ -2193,7 +2194,8 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
acdb_id);
set_bit(ADM_STATUS_CALIBRATION_REQUIRED,
(void *)&this_adm.copp.adm_status[port_idx][copp_idx]);
- if (path != ADM_PATH_COMPRESSED_RX)
+ if ((path != ADM_PATH_COMPRESSED_RX) &&
+ (path != ADM_PATH_COMPRESSED_TX))
send_adm_custom_topology();
}
}
@@ -2465,6 +2467,10 @@ static void route_set_opcode_matrix_id(
route->hdr.opcode = ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5;
route->matrix_id = ADM_MATRIX_ID_COMPRESSED_AUDIO_RX;
break;
+ case ADM_PATH_COMPRESSED_TX:
+ route->hdr.opcode = ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5;
+ route->matrix_id = ADM_MATRIX_ID_COMPRESSED_AUDIO_TX;
+ break;
default:
pr_err("%s: Wrong path set[%d]\n", __func__, path);
break;
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 0d142f77db50..da156bf61610 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -155,12 +155,37 @@ static int out_cold_index;
static char *out_buffer;
static char *in_buffer;
-static uint32_t adsp_reg_event_opcode[] = {ASM_STREAM_CMD_REGISTER_PP_EVENTS,
- ASM_STREAM_CMD_REGISTER_ENCDEC_EVENTS};
+static uint32_t adsp_reg_event_opcode[] = {
+ ASM_STREAM_CMD_REGISTER_PP_EVENTS,
+ ASM_STREAM_CMD_REGISTER_ENCDEC_EVENTS,
+ ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE };
-static uint32_t adsp_raise_event_opcode[] = {ASM_STREAM_PP_EVENT,
- ASM_STREAM_CMD_ENCDEC_EVENTS};
+static uint32_t adsp_raise_event_opcode[] = {
+ ASM_STREAM_PP_EVENT,
+ ASM_STREAM_CMD_ENCDEC_EVENTS,
+ ASM_IEC_61937_MEDIA_FMT_EVENT };
+static int is_adsp_reg_event(uint32_t cmd)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(adsp_reg_event_opcode); i++) {
+ if (cmd == adsp_reg_event_opcode[i])
+ return i;
+ }
+ return -EINVAL;
+}
+
+static int is_adsp_raise_event(uint32_t cmd)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(adsp_raise_event_opcode); i++) {
+ if (cmd == adsp_raise_event_opcode[i])
+ return i;
+ }
+ return -EINVAL;
+}
static inline void q6asm_set_flag_in_token(union asm_token_struct *asm_token,
int flag, int flag_offset)
@@ -1794,6 +1819,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
case ASM_STREAM_CMD_SET_ENCDEC_PARAM_V2:
case ASM_STREAM_CMD_REGISTER_ENCDEC_EVENTS:
+ case ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE:
case ASM_DATA_CMD_REMOVE_INITIAL_SILENCE:
case ASM_DATA_CMD_REMOVE_TRAILING_SILENCE:
case ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS:
@@ -1807,10 +1833,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
__func__, payload[0], payload[1]);
if (wakeup_flag) {
- if (payload[0] ==
- ASM_STREAM_CMD_SET_PP_PARAMS_V2
- || payload[0] ==
- ASM_STREAM_CMD_REGISTER_ENCDEC_EVENTS)
+ if ((is_adsp_reg_event(payload[0]) >= 0)
+ || (payload[0] ==
+ ASM_STREAM_CMD_SET_PP_PARAMS_V2))
atomic_set(&ac->cmd_state_pp,
payload[1]);
else
@@ -1820,9 +1845,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
}
return 0;
}
- if (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2 ||
- payload[0] ==
- ASM_STREAM_CMD_REGISTER_ENCDEC_EVENTS) {
+ if ((is_adsp_reg_event(payload[0]) >= 0) ||
+ (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2)) {
if (atomic_read(&ac->cmd_state_pp) &&
wakeup_flag) {
atomic_set(&ac->cmd_state_pp, 0);
@@ -2063,13 +2087,11 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
break;
case ASM_STREAM_PP_EVENT:
case ASM_STREAM_CMD_ENCDEC_EVENTS:
- pr_debug("%s: ASM_STREAM_PP_EVENT payload[0][0x%x] payload[1][0x%x]",
+ case ASM_STREAM_CMD_REGISTER_IEC_61937_FMT_UPDATE:
+ pr_debug("%s: ASM_STREAM_EVENT payload[0][0x%x] payload[1][0x%x]",
__func__, payload[0], payload[1]);
- for (i = 0; i < ARRAY_SIZE(adsp_raise_event_opcode); i++)
- if (adsp_raise_event_opcode[i] == data->opcode)
- break;
-
- if (i >= ARRAY_SIZE(adsp_raise_event_opcode))
+ i = is_adsp_raise_event(data->opcode);
+ if (i < 0)
return 0;
/* repack payload for asm_stream_pp_event