summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/gpu/adreno.txt1
-rw-r--r--Documentation/devicetree/bindings/platform/msm/qpnp-revid.txt2
-rw-r--r--Documentation/devicetree/bindings/regulator/qpnp-lcdb-regulator.txt7
-rw-r--r--Documentation/devicetree/bindings/soc/qcom/msm-early-cam.txt110
-rw-r--r--arch/arm/boot/dts/qcom/apq8098-v2.1-mediabox.dts4
-rw-r--r--arch/arm/boot/dts/qcom/msm-pm660.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi98
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi98
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-v2.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msm8998.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-camera-sensor-cdp.dtsi79
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-camera-sensor-mtp.dtsi79
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-mtp.dtsi10
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi28
-rw-r--r--arch/arm/boot/dts/qcom/sdm660.dtsi10
-rw-r--r--arch/arm/boot/dts/qcom/vplatform-lfv-msm8996.dts76
-rw-r--r--arch/arm64/configs/msmcortex-perf_defconfig1
-rw-r--r--arch/arm64/configs/msmcortex_defconfig1
-rw-r--r--arch/arm64/configs/sdm660-perf_defconfig2
-rw-r--r--arch/arm64/configs/sdm660_defconfig2
-rw-r--r--arch/arm64/include/asm/io.h4
-rw-r--r--drivers/bluetooth/btfm_slim.c14
-rw-r--r--drivers/bluetooth/btfm_slim_codec.c60
-rw-r--r--drivers/bluetooth/btfm_slim_wcn3990.c24
-rw-r--r--drivers/bluetooth/btfm_slim_wcn3990.h3
-rw-r--r--drivers/char/adsprpc.c12
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_gpu.c18
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_device.c3
-rw-r--r--drivers/gpu/drm/msm/msm_gem.h1
-rw-r--r--drivers/gpu/drm/msm/msm_gem_submit.c91
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.c27
-rw-r--r--drivers/gpu/drm/msm/sde/sde_color_processing.c4
-rw-r--r--drivers/gpu/drm/msm/sde/sde_crtc.c9
-rw-r--r--drivers/gpu/drm/msm/sde/sde_splash.c98
-rw-r--r--drivers/gpu/drm/msm/sde/sde_splash.h10
-rw-r--r--drivers/gpu/msm/adreno.c26
-rw-r--r--drivers/gpu/msm/kgsl_pwrctrl.h2
-rw-r--r--drivers/iio/adc/qcom-rradc.c78
-rw-r--r--drivers/media/platform/msm/ais/fd/msm_fd_dev.c21
-rw-r--r--drivers/media/platform/msm/ais/fd/msm_fd_dev.h1
-rw-r--r--drivers/media/platform/msm/ais/sensor/cci/Makefile1
-rw-r--r--drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.c279
-rw-r--r--drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.h53
-rw-r--r--drivers/media/platform/msm/ais/sensor/msm_sensor_init.c33
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c2
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc.c17
-rw-r--r--drivers/net/can/spi/rh850.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c52
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.h9
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.h13
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h10
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c12
-rw-r--r--drivers/net/wireless/cnss2/debug.c25
-rw-r--r--drivers/net/wireless/cnss2/main.c7
-rw-r--r--drivers/net/wireless/cnss2/main.h1
-rw-r--r--drivers/pci/host/pci-msm.c10
-rw-r--r--drivers/platform/msm/gsi/gsi.c14
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa.c39
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c17
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h2
-rw-r--r--drivers/platform/msm/qpnp-revid.c11
-rw-r--r--drivers/platform/msm/usb_bam.c134
-rw-r--r--drivers/power/power_supply_sysfs.c3
-rw-r--r--drivers/power/supply/qcom/pmic-voter.c17
-rw-r--r--drivers/power/supply/qcom/qpnp-smb2.c65
-rw-r--r--drivers/power/supply/qcom/smb-lib.c117
-rw-r--r--drivers/power/supply/qcom/smb-lib.h21
-rw-r--r--drivers/power/supply/qcom/smb138x-charger.c26
-rw-r--r--drivers/regulator/qpnp-lcdb-regulator.c84
-rw-r--r--drivers/soc/qcom/glink_smem_native_xprt.c1
-rw-r--r--drivers/soc/qcom/qbt1000.c101
-rw-r--r--drivers/soc/qcom/scm_qcpe.c8
-rw-r--r--drivers/usb/dwc3/dwc3-msm.c16
-rw-r--r--drivers/usb/pd/policy_engine.c34
-rw-r--r--drivers/usb/pd/qpnp-pdphy.c20
-rw-r--r--drivers/usb/pd/usbpd.h12
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_tx.c21
-rw-r--r--include/linux/power_supply.h3
-rw-r--r--include/linux/qpnp/qpnp-revid.h1
-rw-r--r--include/linux/usb_bam.h6
-rw-r--r--include/sound/apr_audio-v2.h2
-rw-r--r--include/sound/q6asm-v2.h2
-rw-r--r--include/uapi/drm/msm_drm.h6
-rw-r--r--include/uapi/sound/compress_offload.h7
-rw-r--r--sound/soc/codecs/wcd-dsp-mgr.c23
-rw-r--r--sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c9
-rw-r--r--sound/soc/msm/msm8998.c21
-rw-r--r--sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c3
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c12
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c13
-rw-r--r--sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c301
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c15
93 files changed, 2183 insertions, 650 deletions
diff --git a/Documentation/devicetree/bindings/gpu/adreno.txt b/Documentation/devicetree/bindings/gpu/adreno.txt
index 32de5ce3da7e..80813dd1b3e5 100644
--- a/Documentation/devicetree/bindings/gpu/adreno.txt
+++ b/Documentation/devicetree/bindings/gpu/adreno.txt
@@ -93,6 +93,7 @@ Optional Properties:
- qcom,chipid: If it exists this property is used to replace
the chip identification read from the GPU hardware.
This is used to override faulty hardware readings.
+- qcom,disable-wake-on-touch: Boolean. Disables the GPU power up on a touch input event.
- qcom,disable-busy-time-burst:
Boolean. Disables the busy time burst to avoid switching
of power level for large frames based on the busy time limit.
diff --git a/Documentation/devicetree/bindings/platform/msm/qpnp-revid.txt b/Documentation/devicetree/bindings/platform/msm/qpnp-revid.txt
index babc4523a29a..dd14890123e6 100644
--- a/Documentation/devicetree/bindings/platform/msm/qpnp-revid.txt
+++ b/Documentation/devicetree/bindings/platform/msm/qpnp-revid.txt
@@ -9,6 +9,8 @@ Required properties:
Optional property:
- qcom,fab-id-valid: Use this property when support to read Fab
identification from REV ID peripheral is available.
+- qcom,tp-rev-valid: Use this property when support to read TP
+ revision identification from REV ID peripheral.
Example:
qcom,revid@100 {
diff --git a/Documentation/devicetree/bindings/regulator/qpnp-lcdb-regulator.txt b/Documentation/devicetree/bindings/regulator/qpnp-lcdb-regulator.txt
index ed383ce9ea8f..9798ac60b493 100644
--- a/Documentation/devicetree/bindings/regulator/qpnp-lcdb-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/qpnp-lcdb-regulator.txt
@@ -209,6 +209,12 @@ Properties below are specific to BOOST subnode only.
Definition: Current limit (in mA) of the BOOST rail.
Possible values are 200 to 1600mA in 200mA steps.
+- qcom,bst-headroom-mv
+ Usage: optional
+ Value type: <u16>
+ Definition: Headroom of the boost (in mV). The minimum headroom is
+ 200mV and if not specified defaults to 200mV.
+
=======
Example
=======
@@ -250,5 +256,6 @@ pm660l_lcdb: qpnp-lcdb@ec00 {
qcom,bst-pd-strength = <1>;
qcom,bst-ps = <1>;
qcom,bst-ps-threshold-ma = <50>;
+ qcom,bst-headroom-mv = <200>;
};
};
diff --git a/Documentation/devicetree/bindings/soc/qcom/msm-early-cam.txt b/Documentation/devicetree/bindings/soc/qcom/msm-early-cam.txt
new file mode 100644
index 000000000000..388426f44524
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/qcom/msm-early-cam.txt
@@ -0,0 +1,110 @@
+* Qualcomm Technologies Inc MSM BA
+
+[Root level node]
+==================
+Required properties:
+- compatible: Must be "qcom,early-cam".
+
+[Subnode]
+==========
+- qcom,early-cam-input-profile-#: Defines child nodes for the profiles supported
+ by early camera driver. Each profile should have properties
+ "mmagic-supply", "gdscr-supply", "vfe0-vdd-supply",
+ "qcom,cam-vreg-name", "clocks", "clock-names",
+ "qcom,clock-rates".
+Required properties:
+- mmagic-supply : should contain mmagic regulator used for mmagic clocks.
+- gdscr-supply : should contain gdsr regulator used for cci clocks.
+- vfe0-vdd-supply: phandle to vfe0 regulator.
+- qcom,cam-vreg-name : name of the voltage regulators required for the device.
+- clocks: List of clock handles. The parent clocks of the input clocks to the
+ devices in this power domain are set to oscclk before power gating
+ and restored back after powering on a domain. This is required for
+ all domains which are powered on and off and not required for unused
+ domains.
+- clock-names: name of the clock used by the driver.
+- qcom,clock-rates: clock rate in Hz.
+Example:
+
+ qcom,early-cam {
+ cell-index = <0>;
+ compatible = "qcom,early-cam";
+ status = "ok";
+ mmagic-supply = <&gdsc_mmagic_camss>;
+ gdscr-supply = <&gdsc_camss_top>;
+ vfe0-vdd-supply = <&gdsc_vfe0>;
+ qcom,cam-vreg-name = "mmagic", "gdscr", "vfe0-vdd";
+ clocks = <&clock_mmss clk_mmss_mmagic_ahb_clk>,
+ <&clock_mmss clk_camss_top_ahb_clk>,
+ <&clock_mmss clk_cci_clk_src>,
+ <&clock_mmss clk_camss_cci_ahb_clk>,
+ <&clock_mmss clk_camss_cci_clk>,
+ <&clock_mmss clk_camss_ahb_clk>,
+ <&clock_mmss clk_mmagic_camss_axi_clk>,
+ <&clock_mmss clk_camss_vfe_ahb_clk>,
+ <&clock_mmss clk_camss_vfe0_ahb_clk>,
+ <&clock_mmss clk_camss_vfe_axi_clk>,
+ <&clock_mmss clk_camss_vfe0_stream_clk>,
+ <&clock_mmss clk_smmu_vfe_axi_clk>,
+ <&clock_mmss clk_smmu_vfe_ahb_clk>,
+ <&clock_mmss clk_camss_csi_vfe0_clk>,
+ <&clock_mmss clk_vfe0_clk_src>,
+ <&clock_mmss clk_camss_csi_vfe0_clk>,
+ <&clock_mmss clk_camss_csi2_ahb_clk>,
+ <&clock_mmss clk_camss_csi2_clk>,
+ <&clock_mmss clk_camss_csi2phy_clk>,
+ <&clock_mmss clk_csi2phytimer_clk_src>,
+ <&clock_mmss clk_camss_csi2phytimer_clk>,
+ <&clock_mmss clk_camss_csi2rdi_clk>,
+ <&clock_mmss clk_camss_ispif_ahb_clk>,
+ <&clock_mmss clk_camss_vfe0_clk>;
+ clock-names =
+ "mmss_mmagic_ahb_clk",
+ "camss_top_ahb_clk",
+ "cci_clk_src",
+ "camss_cci_ahb_clk",
+ "camss_cci_clk",
+ "camss_ahb_clk",
+ "mmagic_camss_axi_clk",
+ "camss_vfe_ahb_clk",
+ "camss_vfe0_ahb_clk",
+ "camss_vfe_axi_clk",
+ "camss_vfe0_stream_clk",
+ "smmu_vfe_axi_clk",
+ "smmu_vfe_ahb_clk",
+ "camss_csi_vfe0_clk",
+ "vfe0_clk_src",
+ "camss_csi_vfe0_clk",
+ "camss_csi2_ahb_clk",
+ "camss_csi2_clk",
+ "camss_csi2phy_clk",
+ "csi2phytimer_clk_src",
+ "camss_csi2phytimer_clk",
+ "camss_csi2rdi_clk",
+ "camss_ispif_ahb_clk",
+ "clk_camss_vfe0_clk";
+
+ qcom,clock-rates = <19200000
+ 19200000
+ 19200000
+ 19200000
+ 19200000
+ 19200000
+ 0
+ 0
+ 0
+ 320000000
+ 0
+ 0
+ 0
+ 0
+ 19200000
+ 0
+ 0
+ 200000000
+ 200000000
+ 200000000
+ 200000000
+ 200000000
+ 0
+ };
diff --git a/arch/arm/boot/dts/qcom/apq8098-v2.1-mediabox.dts b/arch/arm/boot/dts/qcom/apq8098-v2.1-mediabox.dts
index bd29c0307576..1fa49d8a060d 100644
--- a/arch/arm/boot/dts/qcom/apq8098-v2.1-mediabox.dts
+++ b/arch/arm/boot/dts/qcom/apq8098-v2.1-mediabox.dts
@@ -101,6 +101,10 @@
status = "disabled";
};
+&pcie0 {
+ qcom,boot-option = <0x0>;
+};
+
&soc {
qcom,msm-dai-mi2s {
dai_mi2s3: qcom,msm-dai-q6-mi2s-quat {
diff --git a/arch/arm/boot/dts/qcom/msm-pm660.dtsi b/arch/arm/boot/dts/qcom/msm-pm660.dtsi
index 93aeef07cfe0..460e7e76ac4d 100644
--- a/arch/arm/boot/dts/qcom/msm-pm660.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pm660.dtsi
@@ -24,6 +24,7 @@
compatible = "qcom,qpnp-revid";
reg = <0x100 0x100>;
qcom,fab-id-valid;
+ qcom,tp-rev-valid;
};
pm660_misc: qcom,misc@900 {
diff --git a/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi b/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi
index 2dc5c919190c..1283cdddc2db 100644
--- a/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi
@@ -858,6 +858,90 @@
};
&soc {
+ qcom,early-cam {
+ cell-index = <0>;
+ compatible = "qcom,early-cam";
+ status = "ok";
+ mmagic-supply = <&gdsc_mmagic_camss>;
+ gdscr-supply = <&gdsc_camss_top>;
+ vfe0-vdd-supply = <&gdsc_vfe0>;
+ qcom,cam-vreg-name = "mmagic", "gdscr", "vfe0-vdd";
+ clocks = <&clock_mmss clk_mmss_mmagic_ahb_clk>,
+ <&clock_mmss clk_camss_top_ahb_clk>,
+ <&clock_mmss clk_cci_clk_src>,
+ <&clock_mmss clk_camss_cci_ahb_clk>,
+ <&clock_mmss clk_camss_cci_clk>,
+ <&clock_mmss clk_camss_ahb_clk>,
+ <&clock_mmss clk_mmagic_camss_axi_clk>,
+ <&clock_mmss clk_camss_vfe_ahb_clk>,
+ <&clock_mmss clk_camss_vfe0_ahb_clk>,
+ <&clock_mmss clk_camss_vfe_axi_clk>,
+ <&clock_mmss clk_camss_vfe0_stream_clk>,
+ <&clock_mmss clk_smmu_vfe_axi_clk>,
+ <&clock_mmss clk_smmu_vfe_ahb_clk>,
+ <&clock_mmss clk_camss_csi_vfe0_clk>,
+ <&clock_mmss clk_vfe0_clk_src>,
+ <&clock_mmss clk_camss_csi_vfe0_clk>,
+ <&clock_mmss clk_camss_csi2_ahb_clk>,
+ <&clock_mmss clk_camss_csi2_clk>,
+ <&clock_mmss clk_camss_csi2phy_clk>,
+ <&clock_mmss clk_csi2phytimer_clk_src>,
+ <&clock_mmss clk_camss_csi2phytimer_clk>,
+ <&clock_mmss clk_camss_csi2rdi_clk>,
+ <&clock_mmss clk_camss_ispif_ahb_clk>,
+ <&clock_mmss clk_camss_vfe0_clk>;
+ clock-names =
+ "mmss_mmagic_ahb_clk",
+ "camss_top_ahb_clk",
+ "cci_clk_src",
+ "camss_cci_ahb_clk",
+ "camss_cci_clk",
+ "camss_ahb_clk",
+ "mmagic_camss_axi_clk",
+ "camss_vfe_ahb_clk",
+ "camss_vfe0_ahb_clk",
+ "camss_vfe_axi_clk",
+ "camss_vfe0_stream_clk",
+ "smmu_vfe_axi_clk",
+ "smmu_vfe_ahb_clk",
+ "camss_csi_vfe0_clk",
+ "vfe0_clk_src",
+ "camss_csi_vfe0_clk",
+ "camss_csi2_ahb_clk",
+ "camss_csi2_clk",
+ "camss_csi2phy_clk",
+ "csi2phytimer_clk_src",
+ "camss_csi2phytimer_clk",
+ "camss_csi2rdi_clk",
+ "camss_ispif_ahb_clk",
+ "clk_camss_vfe0_clk";
+
+ qcom,clock-rates = <19200000
+ 19200000
+ 19200000
+ 19200000
+ 19200000
+ 19200000
+ 0
+ 0
+ 0
+ 320000000
+ 0
+ 0
+ 0
+ 0
+ 19200000
+ 0
+ 0
+ 200000000
+ 200000000
+ 200000000
+ 200000000
+ 200000000
+ 0
+ 100000000>;
+ };
+
qcom,ntn_avb {
compatible = "qcom,ntn_avb";
@@ -1457,11 +1541,21 @@
};
};
+&vfe_smmu {
+ qcom,no-smr-check;
+};
+
/ {
reserved-memory {
- lk_mem: lk_pool@91600000 {
- reg = <0x0 0x91600000 0x0 0x600000>;
+ lk_mem: lk_pool@0x91600000 {
+ no-map;
+ reg = <0 0x91600000 0 0x00600000>;
label = "lk_pool";
};
+
+ early_camera_mem: early_camera_mem@b3fff000 {
+ reg = <0 0xb3fff000 0 0x800000>;
+ label = "early_camera_mem";
+ };
};
};
diff --git a/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi
index 1d5e3035afd0..c3b986786034 100644
--- a/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi
@@ -623,6 +623,90 @@
};
&soc {
+ qcom,early-cam {
+ cell-index = <0>;
+ compatible = "qcom,early-cam";
+ status = "ok";
+ mmagic-supply = <&gdsc_mmagic_camss>;
+ gdscr-supply = <&gdsc_camss_top>;
+ vfe0-vdd-supply = <&gdsc_vfe0>;
+ qcom,cam-vreg-name = "mmagic", "gdscr", "vfe0-vdd";
+ clocks = <&clock_mmss clk_mmss_mmagic_ahb_clk>,
+ <&clock_mmss clk_camss_top_ahb_clk>,
+ <&clock_mmss clk_cci_clk_src>,
+ <&clock_mmss clk_camss_cci_ahb_clk>,
+ <&clock_mmss clk_camss_cci_clk>,
+ <&clock_mmss clk_camss_ahb_clk>,
+ <&clock_mmss clk_mmagic_camss_axi_clk>,
+ <&clock_mmss clk_camss_vfe_ahb_clk>,
+ <&clock_mmss clk_camss_vfe0_ahb_clk>,
+ <&clock_mmss clk_camss_vfe_axi_clk>,
+ <&clock_mmss clk_camss_vfe0_stream_clk>,
+ <&clock_mmss clk_smmu_vfe_axi_clk>,
+ <&clock_mmss clk_smmu_vfe_ahb_clk>,
+ <&clock_mmss clk_camss_csi_vfe0_clk>,
+ <&clock_mmss clk_vfe0_clk_src>,
+ <&clock_mmss clk_camss_csi_vfe0_clk>,
+ <&clock_mmss clk_camss_csi2_ahb_clk>,
+ <&clock_mmss clk_camss_csi2_clk>,
+ <&clock_mmss clk_camss_csi2phy_clk>,
+ <&clock_mmss clk_csi2phytimer_clk_src>,
+ <&clock_mmss clk_camss_csi2phytimer_clk>,
+ <&clock_mmss clk_camss_csi2rdi_clk>,
+ <&clock_mmss clk_camss_ispif_ahb_clk>,
+ <&clock_mmss clk_camss_vfe0_clk>;
+ clock-names =
+ "mmss_mmagic_ahb_clk",
+ "camss_top_ahb_clk",
+ "cci_clk_src",
+ "camss_cci_ahb_clk",
+ "camss_cci_clk",
+ "camss_ahb_clk",
+ "mmagic_camss_axi_clk",
+ "camss_vfe_ahb_clk",
+ "camss_vfe0_ahb_clk",
+ "camss_vfe_axi_clk",
+ "camss_vfe0_stream_clk",
+ "smmu_vfe_axi_clk",
+ "smmu_vfe_ahb_clk",
+ "camss_csi_vfe0_clk",
+ "vfe0_clk_src",
+ "camss_csi_vfe0_clk",
+ "camss_csi2_ahb_clk",
+ "camss_csi2_clk",
+ "camss_csi2phy_clk",
+ "csi2phytimer_clk_src",
+ "camss_csi2phytimer_clk",
+ "camss_csi2rdi_clk",
+ "camss_ispif_ahb_clk",
+ "clk_camss_vfe0_clk";
+
+ qcom,clock-rates = <19200000
+ 19200000
+ 19200000
+ 19200000
+ 19200000
+ 19200000
+ 0
+ 0
+ 0
+ 320000000
+ 0
+ 0
+ 0
+ 0
+ 19200000
+ 0
+ 0
+ 200000000
+ 200000000
+ 200000000
+ 200000000
+ 200000000
+ 0
+ 100000000>;
+ };
+
ntn1: ntn_avb@1 { /* Neutrno device on RC1*/
compatible = "qcom,ntn_avb";
@@ -1231,12 +1315,22 @@
/delete-property/ qcom,spkr-sd-n-gpio;
};
+&vfe_smmu {
+ qcom,no-smr-check;
+};
+
/ {
reserved-memory {
- lk_mem: lk_pool@91600000 {
- reg = <0x0 0x91600000 0x0 0x600000>;
+ lk_mem: lk_pool@0x91600000 {
+ no-map;
+ reg = <0 0x91600000 0 0x00600000>;
label = "lk_pool";
};
+
+ early_camera_mem: early_camera_mem@b3fff000 {
+ reg = <0 0xb3fff000 0 0x800000>;
+ label = "early_camera_mem";
+ };
};
};
diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2.dtsi
index b2f30de94bbc..acdd4bdcd95b 100644
--- a/arch/arm/boot/dts/qcom/msm8998-v2.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-v2.dtsi
@@ -436,7 +436,7 @@
0x9ac 0x00 0x00
0x8a0 0x01 0x00
0x9e0 0x00 0x00
- 0x9dc 0x01 0x00
+ 0x9dc 0x20 0x00
0x9a8 0x00 0x00
0x8a4 0x01 0x00
0x8a8 0x73 0x00
diff --git a/arch/arm/boot/dts/qcom/msm8998.dtsi b/arch/arm/boot/dts/qcom/msm8998.dtsi
index 3f8962de22be..eafa6b841c17 100644
--- a/arch/arm/boot/dts/qcom/msm8998.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998.dtsi
@@ -2675,7 +2675,7 @@
0x9ac 0x00 0x00
0x8a0 0x01 0x00
0x9e0 0x00 0x00
- 0x9dc 0x01 0x00
+ 0x9dc 0x20 0x00
0x9a8 0x00 0x00
0x8a4 0x01 0x00
0x8a8 0x73 0x00
diff --git a/arch/arm/boot/dts/qcom/sdm660-camera-sensor-cdp.dtsi b/arch/arm/boot/dts/qcom/sdm660-camera-sensor-cdp.dtsi
index 46f77e9a3253..476fedec35a4 100644
--- a/arch/arm/boot/dts/qcom/sdm660-camera-sensor-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-camera-sensor-cdp.dtsi
@@ -29,6 +29,16 @@
qcom,switch-source = <&pm660l_switch1>;
status = "ok";
};
+
+ cam_actuator_regulator: cam_actuator_fixed_regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "cam_actuator_regulator";
+ regulator-min-microvolt = <3600000>;
+ regulator-max-microvolt = <3600000>;
+ enable-active-high;
+ gpio = <&tlmm 50 0>;
+ vin-supply = <&pm660l_bob>;
+ };
};
&cci {
@@ -37,14 +47,11 @@
reg = <0x0>;
compatible = "qcom,actuator";
qcom,cci-master = <0>;
- gpios = <&tlmm 50 0>;
- qcom,gpio-vaf = <0>;
- qcom,gpio-req-tbl-num = <0>;
- qcom,gpio-req-tbl-flags = <0>;
- qcom,gpio-req-tbl-label = "CAM_VAF";
- pinctrl-names = "cam_default", "cam_suspend";
- pinctrl-0 = <&cam_actuator_vaf_active>;
- pinctrl-1 = <&cam_actuator_vaf_suspend>;
+ cam_vaf-supply = <&cam_actuator_regulator>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <3600000>;
+ qcom,cam-vreg-max-voltage = <3600000>;
+ qcom,cam-vreg-op-mode = <0>;
};
actuator1: qcom,actuator@1 {
@@ -52,14 +59,11 @@
reg = <0x1>;
compatible = "qcom,actuator";
qcom,cci-master = <1>;
- gpios = <&tlmm 50 0>;
- qcom,gpio-vaf = <0>;
- qcom,gpio-req-tbl-num = <0>;
- qcom,gpio-req-tbl-flags = <0>;
- qcom,gpio-req-tbl-label = "CAM_VAF";
- pinctrl-names = "cam_default", "cam_suspend";
- pinctrl-0 = <&cam_actuator_vaf_active>;
- pinctrl-1 = <&cam_actuator_vaf_suspend>;
+ cam_vaf-supply = <&cam_actuator_regulator>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <3600000>;
+ qcom,cam-vreg-max-voltage = <3600000>;
+ qcom,cam-vreg-op-mode = <0>;
};
actuator2: qcom,actuator@2 {
@@ -67,14 +71,11 @@
reg = <0x2>;
compatible = "qcom,actuator";
qcom,cci-master = <1>;
- gpios = <&tlmm 50 0>;
- qcom,gpio-vaf = <0>;
- qcom,gpio-req-tbl-num = <0>;
- qcom,gpio-req-tbl-flags = <0>;
- qcom,gpio-req-tbl-label = "CAM_VAF";
- pinctrl-names = "cam_default", "cam_suspend";
- pinctrl-0 = <&cam_actuator_vaf_active>;
- pinctrl-1 = <&cam_actuator_vaf_suspend>;
+ cam_vaf-supply = <&cam_actuator_regulator>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <3600000>;
+ qcom,cam-vreg-max-voltage = <3600000>;
+ qcom,cam-vreg-op-mode = <0>;
};
ois0: qcom,ois@0 {
@@ -82,15 +83,31 @@
reg = <0x0>;
compatible = "qcom,ois";
qcom,cci-master = <0>;
- gpios = <&tlmm 50 0>;
- qcom,gpio-vaf = <0>;
+ cam_vaf-supply = <&cam_actuator_regulator>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <3600000>;
+ qcom,cam-vreg-max-voltage = <3600000>;
+ qcom,cam-vreg-op-mode = <0>;
+ status = "disabled";
+ };
+
+ tof0: qcom,tof@29{
+ cell-index = <0>;
+ reg = <0x29>;
+ compatible = "st,stmvl53l0";
+ qcom,cci-master = <0>;
+ cam_laser-supply = <&cam_actuator_regulator>;
+ qcom,cam-vreg-name = "cam_laser";
+ qcom,cam-vreg-min-voltage = <3600000>;
+ qcom,cam-vreg-max-voltage = <3600000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_tof_active>;
+ pinctrl-1 = <&cam_tof_suspend>;
+ stm,irq-gpio = <&tlmm 45 0x2008>;
+ gpios = <&tlmm 42 0>;
qcom,gpio-req-tbl-num = <0>;
qcom,gpio-req-tbl-flags = <0>;
- qcom,gpio-req-tbl-label = "CAM_VAF";
- pinctrl-names = "cam_default", "cam_suspend";
- pinctrl-0 = <&cam_actuator_vaf_active>;
- pinctrl-1 = <&cam_actuator_vaf_suspend>;
- status = "disabled";
+ qcom,gpio-req-tbl-label = "RNG_EN";
};
eeprom0: qcom,eeprom@0 {
diff --git a/arch/arm/boot/dts/qcom/sdm660-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/qcom/sdm660-camera-sensor-mtp.dtsi
index 94166bf8dd3e..11eb288804ff 100644
--- a/arch/arm/boot/dts/qcom/sdm660-camera-sensor-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-camera-sensor-mtp.dtsi
@@ -40,6 +40,16 @@
vin-supply = <&pm660l_bob>;
};
+ cam_actuator_regulator: cam_actuator_fixed_regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "cam_actuator_regulator";
+ regulator-min-microvolt = <3600000>;
+ regulator-max-microvolt = <3600000>;
+ enable-active-high;
+ gpio = <&tlmm 50 0>;
+ vin-supply = <&pm660l_bob>;
+ };
+
cam_dvdd_gpio_regulator: cam_dvdd_fixed_regulator {
compatible = "regulator-fixed";
regulator-name = "cam_dvdd_gpio_regulator";
@@ -67,14 +77,11 @@
reg = <0x0>;
compatible = "qcom,actuator";
qcom,cci-master = <0>;
- gpios = <&tlmm 50 0>;
- qcom,gpio-vaf = <0>;
- qcom,gpio-req-tbl-num = <0>;
- qcom,gpio-req-tbl-flags = <0>;
- qcom,gpio-req-tbl-label = "CAM_VAF";
- pinctrl-names = "cam_default", "cam_suspend";
- pinctrl-0 = <&cam_actuator_vaf_active>;
- pinctrl-1 = <&cam_actuator_vaf_suspend>;
+ cam_vaf-supply = <&cam_actuator_regulator>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <3600000>;
+ qcom,cam-vreg-max-voltage = <3600000>;
+ qcom,cam-vreg-op-mode = <0>;
};
actuator1: qcom,actuator@1 {
@@ -82,14 +89,11 @@
reg = <0x1>;
compatible = "qcom,actuator";
qcom,cci-master = <1>;
- gpios = <&tlmm 50 0>;
- qcom,gpio-vaf = <0>;
- qcom,gpio-req-tbl-num = <0>;
- qcom,gpio-req-tbl-flags = <0>;
- qcom,gpio-req-tbl-label = "CAM_VAF";
- pinctrl-names = "cam_default", "cam_suspend";
- pinctrl-0 = <&cam_actuator_vaf_active>;
- pinctrl-1 = <&cam_actuator_vaf_suspend>;
+ cam_vaf-supply = <&cam_actuator_regulator>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <3600000>;
+ qcom,cam-vreg-max-voltage = <3600000>;
+ qcom,cam-vreg-op-mode = <0>;
};
actuator2: qcom,actuator@2 {
@@ -97,14 +101,11 @@
reg = <0x2>;
compatible = "qcom,actuator";
qcom,cci-master = <1>;
- gpios = <&tlmm 50 0>;
- qcom,gpio-vaf = <0>;
- qcom,gpio-req-tbl-num = <0>;
- qcom,gpio-req-tbl-flags = <0>;
- qcom,gpio-req-tbl-label = "CAM_VAF";
- pinctrl-names = "cam_default", "cam_suspend";
- pinctrl-0 = <&cam_actuator_vaf_active>;
- pinctrl-1 = <&cam_actuator_vaf_suspend>;
+ cam_vaf-supply = <&cam_actuator_regulator>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <3600000>;
+ qcom,cam-vreg-max-voltage = <3600000>;
+ qcom,cam-vreg-op-mode = <0>;
};
ois0: qcom,ois@0 {
@@ -112,15 +113,31 @@
reg = <0x0>;
compatible = "qcom,ois";
qcom,cci-master = <0>;
- gpios = <&tlmm 50 0>;
- qcom,gpio-vaf = <0>;
+ cam_vaf-supply = <&cam_actuator_regulator>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <3600000>;
+ qcom,cam-vreg-max-voltage = <3600000>;
+ qcom,cam-vreg-op-mode = <0>;
+ status = "disabled";
+ };
+
+ tof0: qcom,tof@29{
+ cell-index = <0>;
+ reg = <0x29>;
+ compatible = "st,stmvl53l0";
+ qcom,cci-master = <0>;
+ cam_laser-supply = <&cam_actuator_regulator>;
+ qcom,cam-vreg-name = "cam_laser";
+ qcom,cam-vreg-min-voltage = <3600000>;
+ qcom,cam-vreg-max-voltage = <3600000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_tof_active>;
+ pinctrl-1 = <&cam_tof_suspend>;
+ stm,irq-gpio = <&tlmm 45 0x2008>;
+ gpios = <&tlmm 42 0>;
qcom,gpio-req-tbl-num = <0>;
qcom,gpio-req-tbl-flags = <0>;
- qcom,gpio-req-tbl-label = "CAM_VAF";
- pinctrl-names = "cam_default", "cam_suspend";
- pinctrl-0 = <&cam_actuator_vaf_active>;
- pinctrl-1 = <&cam_actuator_vaf_suspend>;
- status = "disabled";
+ qcom,gpio-req-tbl-label = "RNG_EN";
};
eeprom0: qcom,eeprom@0 {
diff --git a/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi b/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi
index 45b7201fbf71..50f5d83346c6 100644
--- a/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi
@@ -56,6 +56,16 @@
qcom,master-en = <1>;
status = "okay";
};
+
+ /* GPIO 11 for Home Key */
+ gpio@ca00 {
+ status = "okay";
+ qcom,mode = <0>;
+ qcom,pull = <0>;
+ qcom,vin-sel = <0>;
+ qcom,src-sel = <0>;
+ qcom,out-strength = <1>;
+ };
};
&i2c_6 { /* BLSP1 QUP6 (NFC) */
diff --git a/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi b/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi
index d902078b1048..e55a67e68b36 100644
--- a/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi
@@ -1101,6 +1101,34 @@
};
};
+ cam_tof_active: cam_tof_active {
+ /* LASER */
+ mux {
+ pins = "gpio50", "gpio42", "gpio45";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio50", "gpio42", "gpio45";
+ bias-pull-up;
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_tof_suspend: cam_tof_suspend {
+ /* LASER */
+ mux {
+ pins = "gpio50", "gpio42", "gpio45";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio50", "gpio42", "gpio45";
+ bias-pull-down; /* PULL DOWN */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
cam_sensor_mclk0_active: cam_sensor_mclk0_active {
/* MCLK0 */
mux {
diff --git a/arch/arm/boot/dts/qcom/sdm660.dtsi b/arch/arm/boot/dts/qcom/sdm660.dtsi
index 105cfe3fbdc4..e00753f8b3e7 100644
--- a/arch/arm/boot/dts/qcom/sdm660.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660.dtsi
@@ -672,6 +672,16 @@
clock-names = "core", "iface";
};
+ qcom,qbt1000 {
+ compatible = "qcom,qbt1000";
+ clock-names = "core", "iface";
+ clocks = <&clock_gcc GCC_BLSP1_QUP3_SPI_APPS_CLK>,
+ <&clock_gcc GCC_BLSP1_AHB_CLK>;
+ clock-frequency = <15000000>;
+ qcom,ipc-gpio = <&tlmm 72 0>;
+ qcom,finger-detect-gpio = <&pm660_gpios 11 0>;
+ };
+
qcom,sensor-information {
compatible = "qcom,sensor-information";
sensor_information0: qcom,sensor-information-0 {
diff --git a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996.dts b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996.dts
index 30b36c0ac541..5c0bbbccafea 100644
--- a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996.dts
+++ b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996.dts
@@ -300,6 +300,82 @@
};
};
+ qcom,msm-dai-tdm-pri-rx {
+ compatible = "qcom,msm-dai-tdm";
+ qcom,msm-cpudai-tdm-group-id = <37120>;
+ qcom,msm-cpudai-tdm-group-num-ports = <4>;
+ qcom,msm-cpudai-tdm-group-port-id = <36864 36866 36868 36870>;
+ qcom,msm-cpudai-tdm-clk-rate = <12288000>;
+ qcom,msm-cpudai-tdm-clk-internal = <1>;
+ qcom,msm-cpudai-tdm-sync-mode = <0>;
+ qcom,msm-cpudai-tdm-sync-src = <1>;
+ qcom,msm-cpudai-tdm-data-out = <0>;
+ qcom,msm-cpudai-tdm-invert-sync = <0>;
+ qcom,msm-cpudai-tdm-data-delay = <1>;
+ qcom,msm-cpudai-tdm-clk-attribute = /bits/ 16 <1>;
+ dai_pri_tdm_rx_0: qcom,msm-dai-q6-tdm-pri-rx-0 {
+ compatible = "qcom,msm-dai-q6-tdm";
+ qcom,msm-cpudai-tdm-dev-id = <36864>;
+ qcom,msm-cpudai-tdm-data-align = <0>;
+ };
+
+ dai_pri_tdm_rx_1: qcom,msm-dai-q6-tdm-pri-rx-1 {
+ compatible = "qcom,msm-dai-q6-tdm";
+ qcom,msm-cpudai-tdm-dev-id = <36866>;
+ qcom,msm-cpudai-tdm-data-align = <0>;
+ };
+
+ dai_pri_tdm_rx_2: qcom,msm-dai-q6-tdm-pri-rx-2 {
+ compatible = "qcom,msm-dai-q6-tdm";
+ qcom,msm-cpudai-tdm-dev-id = <36868>;
+ qcom,msm-cpudai-tdm-data-align = <0>;
+ };
+
+ dai_pri_tdm_rx_3: qcom,msm-dai-q6-tdm-pri-rx-3 {
+ compatible = "qcom,msm-dai-q6-tdm";
+ qcom,msm-cpudai-tdm-dev-id = <36870>;
+ qcom,msm-cpudai-tdm-data-align = <0>;
+ };
+ };
+
+ qcom,msm-dai-tdm-pri-tx {
+ compatible = "qcom,msm-dai-tdm";
+ qcom,msm-cpudai-tdm-group-id = <37121>;
+ qcom,msm-cpudai-tdm-group-num-ports = <4>;
+ qcom,msm-cpudai-tdm-group-port-id = <36865 36867 36869 36871>;
+ qcom,msm-cpudai-tdm-clk-rate = <12288000>;
+ qcom,msm-cpudai-tdm-clk-internal = <1>;
+ qcom,msm-cpudai-tdm-sync-mode = <0>;
+ qcom,msm-cpudai-tdm-sync-src = <1>;
+ qcom,msm-cpudai-tdm-data-out = <0>;
+ qcom,msm-cpudai-tdm-invert-sync = <0>;
+ qcom,msm-cpudai-tdm-data-delay = <1>;
+ qcom,msm-cpudai-tdm-clk-attribute = /bits/ 16 <1>;
+ dai_pri_tdm_tx_0: qcom,msm-dai-q6-tdm-pri-tx-0 {
+ compatible = "qcom,msm-dai-q6-tdm";
+ qcom,msm-cpudai-tdm-dev-id = <36865>;
+ qcom,msm-cpudai-tdm-data-align = <0>;
+ };
+
+ dai_pri_tdm_tx_1: qcom,msm-dai-q6-tdm-pri-tx-1 {
+ compatible = "qcom,msm-dai-q6-tdm";
+ qcom,msm-cpudai-tdm-dev-id = <36867>;
+ qcom,msm-cpudai-tdm-data-align = <0>;
+ };
+
+ dai_pri_tdm_tx_2: qcom,msm-dai-q6-tdm-pri-tx-2 {
+ compatible = "qcom,msm-dai-q6-tdm";
+ qcom,msm-cpudai-tdm-dev-id = <36869>;
+ qcom,msm-cpudai-tdm-data-align = <0>;
+ };
+
+ dai_pri_tdm_tx_3: qcom,msm-dai-q6-tdm-pri-tx-3 {
+ compatible = "qcom,msm-dai-q6-tdm";
+ qcom,msm-cpudai-tdm-dev-id = <36871>;
+ qcom,msm-cpudai-tdm-data-align = <0>;
+ };
+ };
+
qcom,msm-dai-tdm-sec-tx {
compatible = "qcom,msm-dai-tdm";
qcom,msm-cpudai-tdm-group-id = <37137>;
diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig
index ac919d751145..e16fc58ce913 100644
--- a/arch/arm64/configs/msmcortex-perf_defconfig
+++ b/arch/arm64/configs/msmcortex-perf_defconfig
@@ -295,6 +295,7 @@ CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_ATH_CARDS=y
CONFIG_WIL6210=m
CONFIG_CLD_LL_CORE=y
+CONFIG_CNSS_GENL=y
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_KEYRESET=y
CONFIG_KEYBOARD_GPIO=y
diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig
index fe6cf23caeab..77157bb85ee1 100644
--- a/arch/arm64/configs/msmcortex_defconfig
+++ b/arch/arm64/configs/msmcortex_defconfig
@@ -296,6 +296,7 @@ CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_ATH_CARDS=y
CONFIG_WIL6210=m
CONFIG_CLD_LL_CORE=y
+CONFIG_CNSS_GENL=y
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_KEYRESET=y
CONFIG_KEYBOARD_GPIO=y
diff --git a/arch/arm64/configs/sdm660-perf_defconfig b/arch/arm64/configs/sdm660-perf_defconfig
index 493ed7e14437..c92551c69bf8 100644
--- a/arch/arm64/configs/sdm660-perf_defconfig
+++ b/arch/arm64/configs/sdm660-perf_defconfig
@@ -300,6 +300,7 @@ CONFIG_INPUT_MISC=y
CONFIG_INPUT_HBTP_INPUT=y
CONFIG_INPUT_QPNP_POWER_ON=y
CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_STMVL53L0=y
# CONFIG_SERIO_SERPORT is not set
# CONFIG_VT is not set
# CONFIG_LEGACY_PTYS is not set
@@ -575,6 +576,7 @@ CONFIG_MSM_EVENT_TIMER=y
CONFIG_MSM_AVTIMER=y
CONFIG_QCOM_REMOTEQDSS=y
CONFIG_MSM_SERVICE_NOTIFIER=y
+CONFIG_MSM_QBT1000=y
CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y
CONFIG_MSM_RPM_LOG=y
CONFIG_MSM_RPM_STATS_LOG=y
diff --git a/arch/arm64/configs/sdm660_defconfig b/arch/arm64/configs/sdm660_defconfig
index 50762356cb6f..6b45087e2603 100644
--- a/arch/arm64/configs/sdm660_defconfig
+++ b/arch/arm64/configs/sdm660_defconfig
@@ -309,6 +309,7 @@ CONFIG_INPUT_QPNP_POWER_ON=y
CONFIG_INPUT_KEYCHORD=y
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_GPIO=y
+CONFIG_INPUT_STMVL53L0=y
# CONFIG_SERIO_SERPORT is not set
# CONFIG_VT is not set
# CONFIG_LEGACY_PTYS is not set
@@ -600,6 +601,7 @@ CONFIG_MSM_EVENT_TIMER=y
CONFIG_MSM_AVTIMER=y
CONFIG_QCOM_REMOTEQDSS=y
CONFIG_MSM_SERVICE_NOTIFIER=y
+CONFIG_MSM_QBT1000=y
CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y
CONFIG_MSM_RPM_LOG=y
CONFIG_MSM_RPM_STATS_LOG=y
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index eea245bf546a..3112c2a9d96f 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -167,9 +167,9 @@ static inline u64 __raw_readq_no_log(const volatile void __iomem *addr)
#define readq_relaxed_no_log(c) ({ u64 __v = le64_to_cpu((__force __le64)__raw_readq_no_log(c)); __v; })
#define writeb_relaxed_no_log(v, c) ((void)__raw_writeb_no_log((v), (c)))
-#define writew_relaxed_no_log(v, c) ((void)__raw_writew_no_log((__force u16)cpu_to_le32(v), (c)))
+#define writew_relaxed_no_log(v, c) ((void)__raw_writew_no_log((__force u16)cpu_to_le16(v), (c)))
#define writel_relaxed_no_log(v, c) ((void)__raw_writel_no_log((__force u32)cpu_to_le32(v), (c)))
-#define writeq_relaxed_no_log(v, c) ((void)__raw_writeq_no_log((__force u64)cpu_to_le32(v), (c)))
+#define writeq_relaxed_no_log(v, c) ((void)__raw_writeq_no_log((__force u64)cpu_to_le64(v), (c)))
/*
* I/O memory access primitives. Reads are ordered relative to any
diff --git a/drivers/bluetooth/btfm_slim.c b/drivers/bluetooth/btfm_slim.c
index 969f755f5dc4..0a61186167ba 100644
--- a/drivers/bluetooth/btfm_slim.c
+++ b/drivers/bluetooth/btfm_slim.c
@@ -155,23 +155,22 @@ int btfm_slim_enable_ch(struct btfmslim *btfmslim, struct btfmslim_ch *ch,
rxport, 1);
if (ret < 0) {
BTFMSLIM_ERR("vendor_port_en failed ret[%d]",
- ret);
+ ret);
goto error;
}
}
if (rxport) {
BTFMSLIM_INFO("slim_connect_sink(port: %d, ch: %d)",
- ch->port, ch->ch);
+ ch->port, ch->ch);
/* Connect Port with channel given by Machine driver*/
ret = slim_connect_sink(btfmslim->slim_pgd,
&ch->port_hdl, 1, ch->ch_hdl);
if (ret < 0) {
BTFMSLIM_ERR("slim_connect_sink failed ret[%d]",
- ret);
+ ret);
goto remove_channel;
}
-
} else {
BTFMSLIM_INFO("slim_connect_src(port: %d, ch: %d)",
ch->port, ch->ch);
@@ -180,7 +179,7 @@ int btfm_slim_enable_ch(struct btfmslim *btfmslim, struct btfmslim_ch *ch,
ch->ch_hdl);
if (ret < 0) {
BTFMSLIM_ERR("slim_connect_src failed ret[%d]",
- ret);
+ ret);
goto remove_channel;
}
}
@@ -190,6 +189,7 @@ int btfm_slim_enable_ch(struct btfmslim *btfmslim, struct btfmslim_ch *ch,
BTFMSLIM_INFO(
"port: %d, ch: %d, grp: %d, ch->grph: 0x%x, ch_hdl: 0x%x",
chan->port, chan->ch, grp, chan->grph, chan->ch_hdl);
+
ret = slim_control_ch(btfmslim->slim_pgd, (grp ? chan->grph :
chan->ch_hdl), SLIM_CH_ACTIVATE, true);
if (ret < 0) {
@@ -220,6 +220,7 @@ int btfm_slim_disable_ch(struct btfmslim *btfmslim, struct btfmslim_ch *ch,
BTFMSLIM_INFO("port:%d, grp: %d, ch->grph:0x%x, ch->ch_hdl:0x%x ",
ch->port, grp, ch->grph, ch->ch_hdl);
+
/* Remove the channel immediately*/
ret = slim_control_ch(btfmslim->slim_pgd, (grp ? ch->grph : ch->ch_hdl),
SLIM_CH_REMOVE, true);
@@ -233,7 +234,6 @@ int btfm_slim_disable_ch(struct btfmslim *btfmslim, struct btfmslim_ch *ch,
goto error;
}
}
-
/* Disable port through registration setting */
for (i = 0; i < nchan; i++, ch++) {
if (btfmslim->vendor_port_en) {
@@ -246,9 +246,11 @@ int btfm_slim_disable_ch(struct btfmslim *btfmslim, struct btfmslim_ch *ch,
}
}
}
+
error:
return ret;
}
+
static int btfm_slim_get_logical_addr(struct slim_device *slim)
{
int ret = 0;
diff --git a/drivers/bluetooth/btfm_slim_codec.c b/drivers/bluetooth/btfm_slim_codec.c
index 96be0e2f9183..035e8d9fb5fd 100644
--- a/drivers/bluetooth/btfm_slim_codec.c
+++ b/drivers/bluetooth/btfm_slim_codec.c
@@ -118,9 +118,6 @@ static void btfm_slim_dai_shutdown(struct snd_pcm_substream *substream,
return;
}
- if (dai->id == BTFM_FM_SLIM_TX)
- goto out;
-
/* Search for dai->id matched port handler */
for (i = 0; (i < BTFM_SLIM_NUM_CODEC_DAIS) &&
(ch->id != BTFM_SLIM_NUM_CODEC_DAIS) &&
@@ -134,7 +131,6 @@ static void btfm_slim_dai_shutdown(struct snd_pcm_substream *substream,
}
btfm_slim_disable_ch(btfmslim, ch, rxport, grp, nchan);
-out:
btfm_slim_hw_deinit(btfmslim);
}
@@ -205,61 +201,6 @@ int btfm_slim_dai_prepare(struct snd_pcm_substream *substream,
return ret;
}
-static int btfm_slim_dai_hw_free(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- int ret = -EINVAL, i;
- struct btfmslim *btfmslim = dai->dev->platform_data;
- struct btfmslim_ch *ch;
- uint8_t rxport, grp = false, nchan = 1;
-
- BTFMSLIM_DBG("dai->name: %s, dai->id: %d, dai->rate: %d", dai->name,
- dai->id, dai->rate);
-
- switch (dai->id) {
- case BTFM_FM_SLIM_TX:
- grp = true; nchan = 2;
- ch = btfmslim->tx_chs;
- rxport = 0;
- break;
- case BTFM_BT_SCO_SLIM_TX:
- ch = btfmslim->tx_chs;
- rxport = 0;
- break;
- case BTFM_BT_SCO_A2DP_SLIM_RX:
- case BTFM_BT_SPLIT_A2DP_SLIM_RX:
- ch = btfmslim->rx_chs;
- rxport = 1;
- break;
- case BTFM_SLIM_NUM_CODEC_DAIS:
- default:
- BTFMSLIM_ERR("dai->id is invalid:%d", dai->id);
- goto out;
- }
-
- if (dai->id != BTFM_FM_SLIM_TX) {
- ret = 0;
- goto out;
- }
-
- /* Search for dai->id matched port handler */
- for (i = 0; (i < BTFM_SLIM_NUM_CODEC_DAIS) &&
- (ch->id != BTFM_SLIM_NUM_CODEC_DAIS) &&
- (ch->id != dai->id); ch++, i++)
- ;
-
- if ((ch->port == BTFM_SLIM_PGD_PORT_LAST) ||
- (ch->id == BTFM_SLIM_NUM_CODEC_DAIS)) {
- BTFMSLIM_ERR("ch is invalid!!");
- goto out;
- }
-
- btfm_slim_disable_ch(btfmslim, ch, rxport, grp, nchan);
-
-out:
- return ret;
-}
-
/* This function will be called once during boot up */
static int btfm_slim_dai_set_channel_map(struct snd_soc_dai *dai,
unsigned int tx_num, unsigned int *tx_slot,
@@ -402,7 +343,6 @@ static struct snd_soc_dai_ops btfmslim_dai_ops = {
.shutdown = btfm_slim_dai_shutdown,
.hw_params = btfm_slim_dai_hw_params,
.prepare = btfm_slim_dai_prepare,
- .hw_free = btfm_slim_dai_hw_free,
.set_channel_map = btfm_slim_dai_set_channel_map,
.get_channel_map = btfm_slim_dai_get_channel_map,
};
diff --git a/drivers/bluetooth/btfm_slim_wcn3990.c b/drivers/bluetooth/btfm_slim_wcn3990.c
index 0c4e0b3d5c2e..363b4692d228 100644
--- a/drivers/bluetooth/btfm_slim_wcn3990.c
+++ b/drivers/bluetooth/btfm_slim_wcn3990.c
@@ -82,11 +82,12 @@ int btfm_slim_chrk_enable_port(struct btfmslim *btfmslim, uint8_t port_num,
uint8_t rxport, uint8_t enable)
{
int ret = 0;
- uint8_t reg_val = 0;
+ uint8_t reg_val = 0, en;
uint8_t port_bit = 0;
uint16_t reg;
BTFMSLIM_DBG("port(%d) enable(%d)", port_num, enable);
+
if (rxport) {
if (enable) {
/* For SCO Rx, A2DP Rx */
@@ -117,7 +118,8 @@ int btfm_slim_chrk_enable_port(struct btfmslim *btfmslim, uint8_t port_num,
reg = CHRK_SB_PGD_TX_PORTn_MULTI_CHNL_0(port_num);
ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
if (ret) {
- BTFMSLIM_ERR("failed to write (%d) reg 0x%x", ret, reg);
+ BTFMSLIM_ERR("failed to write (%d) reg 0x%x",
+ ret, reg);
goto error;
}
}
@@ -137,15 +139,15 @@ enable_disable_txport:
reg = CHRK_SB_PGD_PORT_TX_CFGN(port_num);
enable_disable_rxport:
- if (enable) {
- if (is_fm_port(port_num))
- reg_val = CHRK_SB_PGD_PORT_ENABLE |
- CHRK_SB_PGD_PORT_WM_L3;
- else
- reg_val = CHRK_SB_PGD_PORT_ENABLE |
- CHRK_SB_PGD_PORT_WM_LB;
- } else
- reg_val = CHRK_SB_PGD_PORT_DISABLE;
+ if (enable)
+ en = CHRK_SB_PGD_PORT_ENABLE;
+ else
+ en = CHRK_SB_PGD_PORT_DISABLE;
+
+ if (is_fm_port(port_num))
+ reg_val = en | CHRK_SB_PGD_PORT_WM_L8;
+ else
+ reg_val = enable ? en | CHRK_SB_PGD_PORT_WM_LB : en;
ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
if (ret)
diff --git a/drivers/bluetooth/btfm_slim_wcn3990.h b/drivers/bluetooth/btfm_slim_wcn3990.h
index f6a260096c91..b637ac581201 100644
--- a/drivers/bluetooth/btfm_slim_wcn3990.h
+++ b/drivers/bluetooth/btfm_slim_wcn3990.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -68,6 +68,7 @@
#define CHRK_SB_PGD_PORT_WM_L1 (0x1 << 1)
#define CHRK_SB_PGD_PORT_WM_L2 (0x2 << 1)
#define CHRK_SB_PGD_PORT_WM_L3 (0x3 << 1)
+#define CHRK_SB_PGD_PORT_WM_L8 (0x8 << 1)
#define CHRK_SB_PGD_PORT_WM_LB (0xB << 1)
#define CHRK_SB_PGD_PORT_RX_NUM 16
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 774ac3538075..a8e23598ea58 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -2402,16 +2402,16 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
spin_lock(&fl->hlock);
hlist_for_each_entry_safe(buf, n, &fl->bufs, hn) {
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "%s %p %s %p %s %llx\n", "buf:",
- buf, "buf->virt:", buf->virt,
- "buf->phys:", buf->phys);
+ "%s %pK %s %pK %s %llx\n", "buf:",
+ buf, "buf->virt:", buf->virt,
+ "buf->phys:", buf->phys);
}
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"\n%s\n",
"LIST OF MAPS:");
hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "%s %p %s %lx %s %llx\n",
+ "%s %pK %s %lx %s %llx\n",
"map:", map,
"map->va:", map->va,
"map->phys:", map->phys);
@@ -2421,7 +2421,7 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
"LIST OF PENDING SMQCONTEXTS:");
hlist_for_each_entry_safe(ictx, n, &fl->clst.pending, hn) {
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "%s %p %s %u %s %u %s %u\n",
+ "%s %pK %s %u %s %u %s %u\n",
"smqcontext:", ictx,
"sc:", ictx->sc,
"tid:", ictx->pid,
@@ -2432,7 +2432,7 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
"LIST OF INTERRUPTED SMQCONTEXTS:");
hlist_for_each_entry_safe(ictx, n, &fl->clst.interrupted, hn) {
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "%s %p %s %u %s %u %s %u\n",
+ "%s %pK %s %u %s %u %s %u\n",
"smqcontext:", ictx,
"sc:", ictx->sc,
"tid:", ictx->pid,
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 45a38b247727..765c1c087c76 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -15,6 +15,7 @@
#include "msm_iommu.h"
#include "msm_trace.h"
#include "a5xx_gpu.h"
+#include <linux/clk/msm-clk.h>
#define SECURE_VA_START 0xc0000000
#define SECURE_VA_SIZE SZ_256M
@@ -1169,6 +1170,17 @@ static int a5xx_pm_resume(struct msm_gpu *gpu)
{
int ret;
+ /*
+ * Between suspend/resumes the GPU clocks need to be turned off
+ * but not a complete power down, typically between frames. Set the
+ * memory retention flags on the GPU core clock to retain memory
+ * across clock toggles.
+ */
+ if (gpu->core_clk) {
+ clk_set_flags(gpu->core_clk, CLKFLAG_RETAIN_PERIPH);
+ clk_set_flags(gpu->core_clk, CLKFLAG_RETAIN_MEM);
+ }
+
/* Turn on the core power */
ret = msm_gpu_pm_resume(gpu);
if (ret)
@@ -1208,6 +1220,12 @@ static int a5xx_pm_suspend(struct msm_gpu *gpu)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+ /* Turn off the memory retention flag when not necessary */
+ if (gpu->core_clk) {
+ clk_set_flags(gpu->core_clk, CLKFLAG_NORETAIN_PERIPH);
+ clk_set_flags(gpu->core_clk, CLKFLAG_NORETAIN_MEM);
+ }
+
/* Only do this next bit if we are about to go down */
if (gpu->active_cnt == 1) {
/* Clear the VBIF pipe before shutting down */
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
index a498a60cd52d..4e4709d6172f 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -173,6 +173,9 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
ret = gpu->funcs->hw_init(gpu);
if (ret) {
dev_err(dev->dev, "gpu hw init failed: %d\n", ret);
+ mutex_lock(&dev->struct_mutex);
+ gpu->funcs->pm_suspend(gpu);
+ mutex_unlock(&dev->struct_mutex);
gpu->funcs->destroy(gpu);
gpu = NULL;
} else {
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index df9ddadc5c5c..0cd458fd184b 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -149,7 +149,6 @@ struct msm_gem_submit {
uint32_t fence;
int ring;
u32 flags;
- bool valid;
uint64_t profile_buf_iova;
struct drm_msm_gem_submit_profile_buffer *profile_buf;
bool secure;
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index b73379aa9ed7..f2b6aa29b410 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -212,15 +212,8 @@ static int submit_validate_objects(struct msm_gpu *gpu,
int contended, slow_locked = -1, i, ret = 0;
retry:
- submit->valid = true;
-
for (i = 0; i < submit->nr_bos; i++) {
struct msm_gem_object *msm_obj = submit->bos[i].obj;
- struct msm_gem_address_space *aspace;
- uint64_t iova;
-
- aspace = (msm_obj->flags & MSM_BO_SECURE) ?
- gpu->secure_aspace : submit->aspace;
if (slow_locked == i)
slow_locked = -1;
@@ -247,28 +240,6 @@ retry:
goto fail;
}
}
-
- /* if locking succeeded, pin bo: */
- ret = msm_gem_get_iova(&msm_obj->base, aspace, &iova);
-
- /* this would break the logic in the fail path.. there is no
- * reason for this to happen, but just to be on the safe side
- * let's notice if this starts happening in the future:
- */
- WARN_ON(ret == -EDEADLK);
-
- if (ret)
- goto fail;
-
- submit->bos[i].flags |= BO_PINNED;
-
- if (iova == submit->bos[i].iova) {
- submit->bos[i].flags |= BO_VALID;
- } else {
- submit->bos[i].iova = iova;
- submit->bos[i].flags &= ~BO_VALID;
- submit->valid = false;
- }
}
ww_acquire_done(&submit->ticket);
@@ -297,9 +268,14 @@ fail:
return ret;
}
-static int submit_bo(struct msm_gem_submit *submit, uint32_t idx,
+static int submit_bo(struct msm_gpu *gpu,
+ struct msm_gem_submit *submit, uint32_t idx,
struct msm_gem_object **obj, uint64_t *iova, bool *valid)
{
+ struct msm_gem_object *msm_obj;
+ struct msm_gem_address_space *aspace;
+ int ret;
+
if (idx >= submit->nr_bos) {
DRM_ERROR("invalid buffer index: %u (out of %u)\n",
idx, submit->nr_bos);
@@ -308,6 +284,39 @@ static int submit_bo(struct msm_gem_submit *submit, uint32_t idx,
if (obj)
*obj = submit->bos[idx].obj;
+
+ /* Only map and pin if the caller needs either the iova or valid */
+ if (!iova && !valid)
+ return 0;
+
+ if (!(submit->bos[idx].flags & BO_PINNED)) {
+ uint64_t buf_iova;
+
+ msm_obj = submit->bos[idx].obj;
+ aspace = (msm_obj->flags & MSM_BO_SECURE) ?
+ gpu->secure_aspace : submit->aspace;
+
+ ret = msm_gem_get_iova(&msm_obj->base, aspace, &buf_iova);
+
+ /* this would break the logic in the fail path.. there is no
+ * reason for this to happen, but just to be on the safe side
+ * let's notice if this starts happening in the future:
+ */
+ WARN_ON(ret == -EDEADLK);
+
+ if (ret)
+ return ret;
+
+ submit->bos[idx].flags |= BO_PINNED;
+
+ if (buf_iova == submit->bos[idx].iova) {
+ submit->bos[idx].flags |= BO_VALID;
+ } else {
+ submit->bos[idx].iova = buf_iova;
+ submit->bos[idx].flags &= ~BO_VALID;
+ }
+ }
+
if (iova)
*iova = submit->bos[idx].iova;
if (valid)
@@ -317,8 +326,10 @@ static int submit_bo(struct msm_gem_submit *submit, uint32_t idx,
}
/* process the reloc's and patch up the cmdstream as needed: */
-static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *obj,
- uint32_t offset, uint32_t nr_relocs, uint64_t relocs)
+static int submit_reloc(struct msm_gpu *gpu,
+ struct msm_gem_submit *submit,
+ struct msm_gem_object *obj, uint32_t offset,
+ uint32_t nr_relocs, uint64_t relocs)
{
uint32_t i, last_offset = 0;
uint32_t *ptr;
@@ -334,6 +345,9 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
return -EINVAL;
}
+ if (nr_relocs == 0)
+ return 0;
+
/* For now, just map the entire thing. Eventually we probably
* to do it page-by-page, w/ kmap() if not vmap()d..
*/
@@ -372,7 +386,8 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
return -EINVAL;
}
- ret = submit_bo(submit, submit_reloc.reloc_idx, NULL, &iova, &valid);
+ ret = submit_bo(gpu, submit, submit_reloc.reloc_idx,
+ NULL, &iova, &valid);
if (ret)
return ret;
@@ -482,7 +497,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
goto out;
}
- ret = submit_bo(submit, submit_cmd.submit_idx,
+ ret = submit_bo(gpu, submit, submit_cmd.submit_idx,
&msm_obj, &iova, NULL);
if (ret)
goto out;
@@ -515,11 +530,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+ submit_cmd.submit_offset;
}
- if (submit->valid)
- continue;
-
- ret = submit_reloc(submit, msm_obj, submit_cmd.submit_offset,
- submit_cmd.nr_relocs, submit_cmd.relocs);
+ ret = submit_reloc(gpu, submit, msm_obj,
+ submit_cmd.submit_offset, submit_cmd.nr_relocs,
+ submit_cmd.relocs);
if (ret)
goto out;
}
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 9320437e923d..7c109fdab545 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -863,7 +863,14 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
gpu->dev = drm;
gpu->funcs = funcs;
gpu->name = name;
- gpu->inactive = true;
+ /*
+ * Set the inactive flag to false, so that when the retire worker
+ * kicks in from the init path, it knows that it has to turn off the
+ * clocks. This should be fine to do since this is the init sequence
+ * and we have an init_lock in msm_open() to protect against bad things
+ * from happening.
+ */
+ gpu->inactive = false;
INIT_LIST_HEAD(&gpu->active_list);
INIT_WORK(&gpu->retire_work, retire_worker);
@@ -1028,4 +1035,22 @@ void msm_gpu_cleanup(struct msm_gpu *gpu)
msm_gpu_destroy_address_space(gpu->aspace);
msm_gpu_destroy_address_space(gpu->secure_aspace);
+
+ if (gpu->gpu_reg)
+ devm_regulator_put(gpu->gpu_reg);
+
+ if (gpu->gpu_cx)
+ devm_regulator_put(gpu->gpu_cx);
+
+ if (gpu->ebi1_clk)
+ devm_clk_put(&pdev->dev, gpu->ebi1_clk);
+
+ for (i = gpu->nr_clocks - 1; i >= 0; i--)
+ if (gpu->grp_clks[i])
+ devm_clk_put(&pdev->dev, gpu->grp_clks[i]);
+
+ devm_kfree(&pdev->dev, gpu->grp_clks);
+
+ if (gpu->mmio)
+ devm_iounmap(&pdev->dev, gpu->mmio);
}
diff --git a/drivers/gpu/drm/msm/sde/sde_color_processing.c b/drivers/gpu/drm/msm/sde/sde_color_processing.c
index ef7492817983..a0f6b5c6a732 100644
--- a/drivers/gpu/drm/msm/sde/sde_color_processing.c
+++ b/drivers/gpu/drm/msm/sde/sde_color_processing.c
@@ -344,8 +344,8 @@ static void sde_cp_crtc_install_immutable_property(struct drm_crtc *crtc,
prop = priv->cp_property[feature];
if (!prop) {
- prop = drm_property_create(crtc->dev, DRM_MODE_PROP_IMMUTABLE,
- name, 0);
+ prop = drm_property_create_range(crtc->dev,
+ DRM_MODE_PROP_IMMUTABLE, name, 0, 1);
if (!prop) {
DRM_ERROR("property create failed: %s\n", name);
kfree(prop_node);
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index 9ab216213d8e..2e9e2192670d 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -601,6 +601,7 @@ void sde_crtc_complete_commit(struct drm_crtc *crtc,
struct sde_crtc *sde_crtc;
struct sde_crtc_state *cstate;
struct drm_connector *conn;
+ struct sde_connector *c_conn;
struct drm_device *dev;
struct msm_drm_private *priv;
struct sde_kms *sde_kms;
@@ -625,16 +626,18 @@ void sde_crtc_complete_commit(struct drm_crtc *crtc,
for (i = 0; i < cstate->num_connectors; ++i)
sde_connector_complete_commit(cstate->connectors[i]);
- if (!sde_kms->splash_info.handoff &&
- sde_kms->splash_info.lk_is_exited) {
+ if (sde_splash_get_lk_complete_status(&sde_kms->splash_info)) {
mutex_lock(&dev->mode_config.mutex);
drm_for_each_connector(conn, crtc->dev) {
if (conn->state->crtc != crtc)
continue;
+ c_conn = to_sde_connector(conn);
+
sde_splash_clean_up_free_resource(priv->kms,
&priv->phandle,
- conn->connector_type);
+ c_conn->connector_type,
+ c_conn->display);
}
mutex_unlock(&dev->mode_config.mutex);
}
diff --git a/drivers/gpu/drm/msm/sde/sde_splash.c b/drivers/gpu/drm/msm/sde/sde_splash.c
index 79989f3ac1e9..19e6406600cd 100644
--- a/drivers/gpu/drm/msm/sde/sde_splash.c
+++ b/drivers/gpu/drm/msm/sde/sde_splash.c
@@ -22,6 +22,7 @@
#include "sde_hw_util.h"
#include "sde_hw_intf.h"
#include "sde_hw_catalog.h"
+#include "dsi_display.h"
#define MDP_SSPP_TOP0_OFF 0x1000
#define DISP_INTF_SEL 0x004
@@ -37,6 +38,9 @@
#define SDE_LK_EXIT_VALUE 0xDEADBEEF
#define SDE_LK_EXIT_MAX_LOOP 20
+
+static DEFINE_MUTEX(sde_splash_lock);
+
/*
* In order to free reseved memory from bootup, and we are not
* able to call the __init free functions, so we need to free
@@ -279,6 +283,15 @@ static void _sde_splash_destroy_splash_node(struct sde_splash_info *sinfo)
sinfo->splash_mem_size = NULL;
}
+static void _sde_splash_get_connector_ref_cnt(struct sde_splash_info *sinfo,
+ u32 *hdmi_cnt, u32 *dsi_cnt)
+{
+ mutex_lock(&sde_splash_lock);
+ *hdmi_cnt = sinfo->hdmi_connector_cnt;
+ *dsi_cnt = sinfo->dsi_connector_cnt;
+ mutex_unlock(&sde_splash_lock);
+}
+
static int _sde_splash_free_resource(struct msm_mmu *mmu,
struct sde_splash_info *sinfo, enum splash_connector_type conn)
{
@@ -442,13 +455,13 @@ int sde_splash_get_handoff_status(struct msm_kms *kms)
if (num_of_display_on) {
sinfo->handoff = true;
sinfo->program_scratch_regs = true;
+ sinfo->lk_is_exited = false;
} else {
sinfo->handoff = false;
sinfo->program_scratch_regs = false;
+ sinfo->lk_is_exited = true;
}
- sinfo->lk_is_exited = false;
-
return 0;
}
@@ -505,15 +518,29 @@ void sde_splash_setup_connector_count(struct sde_splash_info *sinfo,
}
}
+bool sde_splash_get_lk_complete_status(struct sde_splash_info *sinfo)
+{
+ bool ret = 0;
+
+ mutex_lock(&sde_splash_lock);
+ ret = !sinfo->handoff && !sinfo->lk_is_exited;
+ mutex_unlock(&sde_splash_lock);
+
+ return ret;
+}
+
int sde_splash_clean_up_free_resource(struct msm_kms *kms,
- struct sde_power_handle *phandle, int connector_type)
+ struct sde_power_handle *phandle,
+ int connector_type, void *display)
{
struct sde_kms *sde_kms;
struct sde_splash_info *sinfo;
struct msm_mmu *mmu;
+ struct dsi_display *dsi_display = display;
int ret = 0;
- static bool hdmi_is_released;
- static bool dsi_is_released;
+ int hdmi_conn_count = 0;
+ int dsi_conn_count = 0;
+ static const char *last_commit_display_type = "unknown";
if (!phandle || !kms) {
SDE_ERROR("invalid phandle/kms.\n");
@@ -527,16 +554,20 @@ int sde_splash_clean_up_free_resource(struct msm_kms *kms,
return -EINVAL;
}
- /* When both hdmi's and dsi's resource are freed,
- * 1. Destroy splash node objects.
- * 2. Release the memory which LK's stack is running on.
- * 3. Withdraw AHB data bus bandwidth voting.
- */
- if (sinfo->hdmi_connector_cnt == 0 &&
- sinfo->dsi_connector_cnt == 0) {
+ _sde_splash_get_connector_ref_cnt(sinfo, &hdmi_conn_count,
+ &dsi_conn_count);
+
+ mutex_lock(&sde_splash_lock);
+ if (hdmi_conn_count == 0 && dsi_conn_count == 0 &&
+ !sinfo->lk_is_exited) {
+ /* When both hdmi's and dsi's handoff are finished,
+ * 1. Destroy splash node objects.
+ * 2. Release the memory which LK's stack is running on.
+ * 3. Withdraw AHB data bus bandwidth voting.
+ */
DRM_INFO("HDMI and DSI resource handoff is completed\n");
- sinfo->lk_is_exited = false;
+ sinfo->lk_is_exited = true;
_sde_splash_destroy_splash_node(sinfo);
@@ -546,6 +577,7 @@ int sde_splash_clean_up_free_resource(struct msm_kms *kms,
sde_power_data_bus_bandwidth_ctrl(phandle,
sde_kms->core_client, false);
+ mutex_unlock(&sde_splash_lock);
return 0;
}
@@ -553,25 +585,36 @@ int sde_splash_clean_up_free_resource(struct msm_kms *kms,
switch (connector_type) {
case DRM_MODE_CONNECTOR_HDMIA:
- if (!hdmi_is_released)
+ if (sinfo->hdmi_connector_cnt == 1) {
sinfo->hdmi_connector_cnt--;
- if ((sinfo->hdmi_connector_cnt == 0) && (!hdmi_is_released)) {
- hdmi_is_released = true;
-
ret = _sde_splash_free_resource(mmu,
- sinfo, SPLASH_HDMI);
+ sinfo, SPLASH_HDMI);
}
break;
case DRM_MODE_CONNECTOR_DSI:
- if (!dsi_is_released)
- sinfo->dsi_connector_cnt--;
-
- if ((sinfo->dsi_connector_cnt == 0) && (!dsi_is_released)) {
- dsi_is_released = true;
+ /*
+ * Basically, we have commits coming on two DSI connectors.
+ * So when releasing DSI resource, it's ensured that the
+ * coming commits should happen on different DSIs, to promise
+ * the handoff has finished on the two DSIs, then it's safe
+ * to release DSI resource, otherwise, problem happens when
+ * freeing memory, while DSI0 or DSI1 is still visiting
+ * the memory.
+ */
+ if (strcmp(dsi_display->display_type, "unknown") &&
+ strcmp(last_commit_display_type,
+ dsi_display->display_type)) {
+ if (sinfo->dsi_connector_cnt > 1)
+ sinfo->dsi_connector_cnt--;
+ else if (sinfo->dsi_connector_cnt == 1) {
+ ret = _sde_splash_free_resource(mmu,
+ sinfo, SPLASH_DSI);
+
+ sinfo->dsi_connector_cnt--;
+ }
- ret = _sde_splash_free_resource(mmu,
- sinfo, SPLASH_DSI);
+ last_commit_display_type = dsi_display->display_type;
}
break;
default:
@@ -580,6 +623,8 @@ int sde_splash_clean_up_free_resource(struct msm_kms *kms,
__func__, connector_type);
}
+ mutex_unlock(&sde_splash_lock);
+
return ret;
}
@@ -603,6 +648,7 @@ int sde_splash_clean_up_exit_lk(struct msm_kms *kms)
}
/* Monitor LK's status and tell it to exit. */
+ mutex_lock(&sde_splash_lock);
if (sinfo->program_scratch_regs) {
if (_sde_splash_lk_check(sde_kms->hw_intr))
_sde_splash_notify_lk_exit(sde_kms->hw_intr);
@@ -610,6 +656,7 @@ int sde_splash_clean_up_exit_lk(struct msm_kms *kms)
sinfo->handoff = false;
sinfo->program_scratch_regs = false;
}
+ mutex_unlock(&sde_splash_lock);
if (!sde_kms->aspace[0] || !sde_kms->aspace[0]->mmu) {
/* We do not return fault value here, to ensure
@@ -631,6 +678,5 @@ int sde_splash_clean_up_exit_lk(struct msm_kms *kms)
}
}
- sinfo->lk_is_exited = true;
return 0;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_splash.h b/drivers/gpu/drm/msm/sde/sde_splash.h
index 47965693f0b8..babf88335e49 100644
--- a/drivers/gpu/drm/msm/sde/sde_splash.h
+++ b/drivers/gpu/drm/msm/sde/sde_splash.h
@@ -95,7 +95,8 @@ int sde_splash_clean_up_exit_lk(struct msm_kms *kms);
* HDMI's and DSI's resource respectively.
*/
int sde_splash_clean_up_free_resource(struct msm_kms *kms,
- struct sde_power_handle *phandle, int connector_type);
+ struct sde_power_handle *phandle,
+ int connector_type, void *display);
/**
* sde_splash_parse_dt.
@@ -121,4 +122,11 @@ void sde_splash_destroy(struct sde_splash_info *sinfo,
struct sde_power_handle *phandle,
struct sde_power_client *pclient);
+/**
+ * sde_splash_get_lk_complete_status
+ *
+ * Get LK's status to check if it has been stopped.
+ */
+bool sde_splash_get_lk_complete_status(struct sde_splash_info *sinfo);
+
#endif
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index afa71116c691..7cab049771de 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -902,6 +902,9 @@ static int adreno_of_get_power(struct adreno_device *adreno_dev,
device->pwrctrl.bus_control = of_property_read_bool(node,
"qcom,bus-control");
+ device->pwrctrl.input_disable = of_property_read_bool(node,
+ "qcom,disable-wake-on-touch");
+
return 0;
}
@@ -1016,15 +1019,19 @@ static int adreno_probe(struct platform_device *pdev)
/* Initialize coresight for the target */
adreno_coresight_init(adreno_dev);
- adreno_input_handler.private = device;
-
#ifdef CONFIG_INPUT
- /*
- * It isn't fatal if we cannot register the input handler. Sad,
- * perhaps, but not fatal
- */
- if (input_register_handler(&adreno_input_handler))
- KGSL_DRV_ERR(device, "Unable to register the input handler\n");
+ if (!device->pwrctrl.input_disable) {
+ adreno_input_handler.private = device;
+ /*
+ * It isn't fatal if we cannot register the input handler. Sad,
+ * perhaps, but not fatal
+ */
+ if (input_register_handler(&adreno_input_handler)) {
+ adreno_input_handler.private = NULL;
+ KGSL_DRV_ERR(device,
+ "Unable to register the input handler\n");
+ }
+ }
#endif
out:
if (status) {
@@ -1076,7 +1083,8 @@ static int adreno_remove(struct platform_device *pdev)
_adreno_free_memories(adreno_dev);
#ifdef CONFIG_INPUT
- input_unregister_handler(&adreno_input_handler);
+ if (adreno_input_handler.private)
+ input_unregister_handler(&adreno_input_handler);
#endif
adreno_sysfs_close(adreno_dev);
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index 5c0071544f60..02707c901839 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -146,6 +146,7 @@ struct kgsl_regulator {
* @pm_qos_req_dma - the power management quality of service structure
* @pm_qos_active_latency - allowed CPU latency in microseconds when active
* @pm_qos_cpu_mask_latency - allowed CPU mask latency in microseconds
+ * @input_disable - To disable GPU wakeup on touch input event
* @pm_qos_wakeup_latency - allowed CPU latency in microseconds during wakeup
* @bus_control - true if the bus calculation is independent
* @bus_mod - modifier from the current power level for the bus vote
@@ -203,6 +204,7 @@ struct kgsl_pwrctrl {
unsigned int pm_qos_active_latency;
unsigned int pm_qos_cpu_mask_latency;
unsigned int pm_qos_wakeup_latency;
+ bool input_disable;
bool bus_control;
int bus_mod;
unsigned int bus_percent_ab;
diff --git a/drivers/iio/adc/qcom-rradc.c b/drivers/iio/adc/qcom-rradc.c
index 5c20970ccbbb..28ab4e52dab5 100644
--- a/drivers/iio/adc/qcom-rradc.c
+++ b/drivers/iio/adc/qcom-rradc.c
@@ -180,6 +180,9 @@
#define FG_ADC_RR_VOLT_INPUT_FACTOR 8
#define FG_ADC_RR_CURR_INPUT_FACTOR 2000
#define FG_ADC_RR_CURR_USBIN_INPUT_FACTOR_MIL 1886
+#define FG_ADC_RR_CURR_USBIN_660_FACTOR_MIL 9
+#define FG_ADC_RR_CURR_USBIN_660_UV_VAL 579500
+
#define FG_ADC_SCALE_MILLI_FACTOR 1000
#define FG_ADC_KELVINMIL_CELSIUSMIL 273150
@@ -192,6 +195,9 @@
#define FG_RR_CONV_CONTINUOUS_TIME_MIN_US 50000
#define FG_RR_CONV_CONTINUOUS_TIME_MAX_US 51000
#define FG_RR_CONV_MAX_RETRY_CNT 50
+#define FG_RR_TP_REV_VERSION1 21
+#define FG_RR_TP_REV_VERSION2 29
+#define FG_RR_TP_REV_VERSION3 32
/*
* The channel number is not a physical index in hardware,
@@ -228,6 +234,7 @@ struct rradc_chip {
struct rradc_chan_prop *chan_props;
struct device_node *revid_dev_node;
struct pmic_revid_data *pmic_fab_id;
+ int volt;
};
struct rradc_channels {
@@ -353,7 +360,7 @@ static int rradc_post_process_volt(struct rradc_chip *chip,
return 0;
}
-static int rradc_post_process_curr(struct rradc_chip *chip,
+static int rradc_post_process_usbin_curr(struct rradc_chip *chip,
struct rradc_chan_prop *prop, u16 adc_code,
int *result_ua)
{
@@ -361,11 +368,33 @@ static int rradc_post_process_curr(struct rradc_chip *chip,
if (!prop)
return -EINVAL;
-
- if (prop->channel == RR_ADC_USBIN_I)
- scale = FG_ADC_RR_CURR_USBIN_INPUT_FACTOR_MIL;
- else
- scale = FG_ADC_RR_CURR_INPUT_FACTOR;
+ if (chip->revid_dev_node) {
+ switch (chip->pmic_fab_id->pmic_subtype) {
+ case PM660_SUBTYPE:
+ if (((chip->pmic_fab_id->tp_rev
+ >= FG_RR_TP_REV_VERSION1)
+ && (chip->pmic_fab_id->tp_rev
+ <= FG_RR_TP_REV_VERSION2))
+ || (chip->pmic_fab_id->tp_rev
+ >= FG_RR_TP_REV_VERSION3)) {
+ chip->volt = div64_s64(chip->volt, 1000);
+ chip->volt = chip->volt *
+ FG_ADC_RR_CURR_USBIN_660_FACTOR_MIL;
+ chip->volt = FG_ADC_RR_CURR_USBIN_660_UV_VAL -
+ (chip->volt);
+ chip->volt = div64_s64(1000000000, chip->volt);
+ scale = chip->volt;
+ } else
+ scale = FG_ADC_RR_CURR_USBIN_INPUT_FACTOR_MIL;
+ break;
+ case PMI8998_SUBTYPE:
+ scale = FG_ADC_RR_CURR_USBIN_INPUT_FACTOR_MIL;
+ break;
+ default:
+ pr_err("No PMIC subtype found\n");
+ return -EINVAL;
+ }
+ }
/* scale * V/A; 2.5V ADC full scale */
ua = ((int64_t)adc_code * scale);
@@ -376,6 +405,24 @@ static int rradc_post_process_curr(struct rradc_chip *chip,
return 0;
}
+static int rradc_post_process_dcin_curr(struct rradc_chip *chip,
+ struct rradc_chan_prop *prop, u16 adc_code,
+ int *result_ua)
+{
+ int64_t ua = 0;
+
+ if (!prop)
+ return -EINVAL;
+
+ /* 0.5 V/A; 2.5V ADC full scale */
+ ua = ((int64_t)adc_code * FG_ADC_RR_CURR_INPUT_FACTOR);
+ ua *= (FG_ADC_RR_FS_VOLTAGE_MV * FG_ADC_SCALE_MILLI_FACTOR);
+ ua = div64_s64(ua, (FG_MAX_ADC_READINGS * 1000));
+ *result_ua = ua;
+
+ return 0;
+}
+
static int rradc_post_process_die_temp(struct rradc_chip *chip,
struct rradc_chan_prop *prop, u16 adc_code,
int *result_millidegc)
@@ -591,13 +638,13 @@ static const struct rradc_channels rradc_chans[] = {
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_PROCESSED),
FG_ADC_RR_SKIN_TEMP_LSB, FG_ADC_RR_SKIN_TEMP_MSB,
FG_ADC_RR_AUX_THERM_STS)
- RR_ADC_CHAN_CURRENT("usbin_i", &rradc_post_process_curr,
+ RR_ADC_CHAN_CURRENT("usbin_i", &rradc_post_process_usbin_curr,
FG_ADC_RR_USB_IN_I_LSB, FG_ADC_RR_USB_IN_I_MSB,
FG_ADC_RR_USB_IN_I_STS)
RR_ADC_CHAN_VOLT("usbin_v", &rradc_post_process_volt,
FG_ADC_RR_USB_IN_V_LSB, FG_ADC_RR_USB_IN_V_MSB,
FG_ADC_RR_USB_IN_V_STS)
- RR_ADC_CHAN_CURRENT("dcin_i", &rradc_post_process_curr,
+ RR_ADC_CHAN_CURRENT("dcin_i", &rradc_post_process_dcin_curr,
FG_ADC_RR_DC_IN_I_LSB, FG_ADC_RR_DC_IN_I_MSB,
FG_ADC_RR_DC_IN_I_STS)
RR_ADC_CHAN_VOLT("dcin_v", &rradc_post_process_volt,
@@ -955,6 +1002,21 @@ static int rradc_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_PROCESSED:
+ if (((chip->pmic_fab_id->tp_rev
+ >= FG_RR_TP_REV_VERSION1)
+ && (chip->pmic_fab_id->tp_rev
+ <= FG_RR_TP_REV_VERSION2))
+ || (chip->pmic_fab_id->tp_rev
+ >= FG_RR_TP_REV_VERSION3)) {
+ if (chan->address == RR_ADC_USBIN_I) {
+ prop = &chip->chan_props[RR_ADC_USBIN_V];
+ rc = rradc_do_conversion(chip, prop, &adc_code);
+ if (rc)
+ break;
+ prop->scale(chip, prop, adc_code, &chip->volt);
+ }
+ }
+
prop = &chip->chan_props[chan->address];
rc = rradc_do_conversion(chip, prop, &adc_code);
if (rc)
diff --git a/drivers/media/platform/msm/ais/fd/msm_fd_dev.c b/drivers/media/platform/msm/ais/fd/msm_fd_dev.c
index 4024748e6afa..d9e109938e7e 100644
--- a/drivers/media/platform/msm/ais/fd/msm_fd_dev.c
+++ b/drivers/media/platform/msm/ais/fd/msm_fd_dev.c
@@ -430,6 +430,7 @@ static int msm_fd_open(struct file *file)
ctx->vb2_q.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
ctx->vb2_q.io_modes = VB2_USERPTR;
ctx->vb2_q.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+ mutex_init(&ctx->lock);
ret = vb2_queue_init(&ctx->vb2_q);
if (ret < 0) {
dev_err(device->dev, "Error queue init\n");
@@ -480,7 +481,9 @@ static int msm_fd_release(struct file *file)
msm_cpp_vbif_register_error_handler((void *)ctx,
VBIF_CLIENT_FD, NULL);
+ mutex_lock(&ctx->lock);
vb2_queue_release(&ctx->vb2_q);
+ mutex_unlock(&ctx->lock);
vfree(ctx->stats);
@@ -510,7 +513,9 @@ static unsigned int msm_fd_poll(struct file *file,
struct fd_ctx *ctx = msm_fd_ctx_from_fh(file->private_data);
unsigned int ret;
+ mutex_lock(&ctx->lock);
ret = vb2_poll(&ctx->vb2_q, file, wait);
+ mutex_unlock(&ctx->lock);
if (atomic_read(&ctx->subscribed_for_event)) {
poll_wait(file, &ctx->fh.wait, wait);
@@ -748,9 +753,9 @@ static int msm_fd_reqbufs(struct file *file,
int ret;
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
- mutex_lock(&ctx->fd_device->recovery_lock);
+ mutex_lock(&ctx->lock);
ret = vb2_reqbufs(&ctx->vb2_q, req);
- mutex_unlock(&ctx->fd_device->recovery_lock);
+ mutex_unlock(&ctx->lock);
return ret;
}
@@ -766,9 +771,9 @@ static int msm_fd_qbuf(struct file *file, void *fh,
int ret;
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
- mutex_lock(&ctx->fd_device->recovery_lock);
+ mutex_lock(&ctx->lock);
ret = vb2_qbuf(&ctx->vb2_q, pb);
- mutex_unlock(&ctx->fd_device->recovery_lock);
+ mutex_unlock(&ctx->lock);
return ret;
}
@@ -785,9 +790,9 @@ static int msm_fd_dqbuf(struct file *file,
int ret;
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
- mutex_lock(&ctx->fd_device->recovery_lock);
+ mutex_lock(&ctx->lock);
ret = vb2_dqbuf(&ctx->vb2_q, pb, file->f_flags & O_NONBLOCK);
- mutex_unlock(&ctx->fd_device->recovery_lock);
+ mutex_unlock(&ctx->lock);
return ret;
}
@@ -803,7 +808,9 @@ static int msm_fd_streamon(struct file *file,
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
int ret;
+ mutex_lock(&ctx->lock);
ret = vb2_streamon(&ctx->vb2_q, buf_type);
+ mutex_unlock(&ctx->lock);
if (ret < 0)
dev_err(ctx->fd_device->dev, "Stream on fails\n");
@@ -822,7 +829,9 @@ static int msm_fd_streamoff(struct file *file,
struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh);
int ret;
+ mutex_lock(&ctx->lock);
ret = vb2_streamoff(&ctx->vb2_q, buf_type);
+ mutex_unlock(&ctx->lock);
if (ret < 0)
dev_err(ctx->fd_device->dev, "Stream off fails\n");
diff --git a/drivers/media/platform/msm/ais/fd/msm_fd_dev.h b/drivers/media/platform/msm/ais/fd/msm_fd_dev.h
index c15032256f4d..a7615a65d2fc 100644
--- a/drivers/media/platform/msm/ais/fd/msm_fd_dev.h
+++ b/drivers/media/platform/msm/ais/fd/msm_fd_dev.h
@@ -161,6 +161,7 @@ struct fd_ctx {
struct msm_fd_mem_pool mem_pool;
struct msm_fd_stats *stats;
struct msm_fd_buf_handle work_buf;
+ struct mutex lock;
};
/*
diff --git a/drivers/media/platform/msm/ais/sensor/cci/Makefile b/drivers/media/platform/msm/ais/sensor/cci/Makefile
index 3942508c0d66..b8b8c83bc6de 100644
--- a/drivers/media/platform/msm/ais/sensor/cci/Makefile
+++ b/drivers/media/platform/msm/ais/sensor/cci/Makefile
@@ -2,3 +2,4 @@ ccflags-y += -Idrivers/media/platform/msm/ais
ccflags-y += -Idrivers/media/platform/msm/ais/common
ccflags-y += -Idrivers/media/platform/msm/ais/sensor/io
obj-$(CONFIG_MSM_AIS) += msm_cci.o
+obj-$(CONFIG_MSM_AIS) += msm_early_cam.o
diff --git a/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.c b/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.c
new file mode 100644
index 000000000000..00ec613e7303
--- /dev/null
+++ b/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.c
@@ -0,0 +1,279 @@
+/* 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/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+#include "msm_sd.h"
+#include "msm_early_cam.h"
+#include "msm_cam_cci_hwreg.h"
+#include "msm_camera_io_util.h"
+#include "msm_camera_dt_util.h"
+#include "cam_hw_ops.h"
+
+#undef CDBG
+#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+
+#undef EARLY_CAM_DBG
+#ifdef MSM_EARLY_CAM_DEBUG
+#define EARLY_CAM_DBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define EARLY_CAM_DBG(fmt, args...) pr_debug(fmt, ##args)
+#endif
+
+#define MSM_EARLY_CAM_DRV_NAME "msm_early_cam"
+static struct platform_driver msm_early_camera_driver;
+static struct early_cam_device *new_early_cam_dev;
+
+int msm_early_cam_disable_clocks(void)
+{
+ int rc = 0;
+
+ CDBG("%s:\n", __func__);
+ /* Vote OFF for clocks */
+ if (new_early_cam_dev == NULL) {
+ rc = -EINVAL;
+ pr_err("%s: clock structure uninitialised %d\n", __func__,
+ rc);
+ return rc;
+ }
+
+ if ((new_early_cam_dev->pdev == NULL) ||
+ (new_early_cam_dev->early_cam_clk_info == NULL) ||
+ (new_early_cam_dev->early_cam_clk == NULL) ||
+ (new_early_cam_dev->num_clk == 0)) {
+ rc = -EINVAL;
+ pr_err("%s: Clock details uninitialised %d\n", __func__,
+ rc);
+ return rc;
+ }
+
+ rc = msm_camera_clk_enable(&new_early_cam_dev->pdev->dev,
+ new_early_cam_dev->early_cam_clk_info,
+ new_early_cam_dev->early_cam_clk,
+ new_early_cam_dev->num_clk, false);
+ if (rc < 0) {
+ pr_err("%s: clk disable failed %d\n", __func__, rc);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
+ CAM_AHB_SUSPEND_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote OFF AHB_CLIENT_CSIPHY %d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSID,
+ CAM_AHB_SUSPEND_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote OFF AHB_CLIENT_CSID %d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CCI,
+ CAM_AHB_SUSPEND_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote OFF AHB_CLIENT_CCI %d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_ISPIF,
+ CAM_AHB_SUSPEND_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote OFF AHB_CLIENT_ISPIF %d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_VFE0,
+ CAM_AHB_SUSPEND_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote OFF AHB_CLIENT_VFE0 %d\n",
+ __func__, rc);
+ return rc;
+ }
+ pr_debug("Turned OFF camera clocks\n");
+ return 0;
+
+}
+static int msm_early_cam_probe(struct platform_device *pdev)
+{
+ int rc = 0;
+
+ CDBG("%s: pdev %pK device id = %d\n", __func__, pdev, pdev->id);
+
+ /* Vote for Early camera if enabled */
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
+ CAM_AHB_SVS_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote for AHB\n", __func__);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSID,
+ CAM_AHB_SVS_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote for AHB\n", __func__);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CCI,
+ CAM_AHB_SVS_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote for AHB\n", __func__);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_ISPIF,
+ CAM_AHB_SVS_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote for AHB\n", __func__);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_VFE0,
+ CAM_AHB_SVS_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote for AHB\n", __func__);
+ return rc;
+ }
+
+ new_early_cam_dev = kzalloc(sizeof(struct early_cam_device),
+ GFP_KERNEL);
+ if (!new_early_cam_dev)
+ return -ENOMEM;
+
+ if (pdev->dev.of_node)
+ of_property_read_u32((&pdev->dev)->of_node,
+ "cell-index", &pdev->id);
+
+ rc = msm_camera_get_clk_info_and_rates(pdev,
+ &new_early_cam_dev->early_cam_clk_info,
+ &new_early_cam_dev->early_cam_clk,
+ &new_early_cam_dev->early_cam_clk_rates,
+ &new_early_cam_dev->num_clk_cases,
+ &new_early_cam_dev->num_clk);
+ if (rc < 0) {
+ pr_err("%s: msm_early_cam_get_clk_info() failed", __func__);
+ kfree(new_early_cam_dev);
+ return -EFAULT;
+ }
+
+ new_early_cam_dev->ref_count = 0;
+ new_early_cam_dev->pdev = pdev;
+
+ rc = msm_camera_get_dt_vreg_data(
+ new_early_cam_dev->pdev->dev.of_node,
+ &(new_early_cam_dev->early_cam_vreg),
+ &(new_early_cam_dev->regulator_count));
+ if (rc < 0) {
+ pr_err("%s: msm_camera_get_dt_vreg_data fail\n", __func__);
+ rc = -EFAULT;
+ goto early_cam_release_mem;
+ }
+
+ if ((new_early_cam_dev->regulator_count < 0) ||
+ (new_early_cam_dev->regulator_count > MAX_REGULATOR)) {
+ pr_err("%s: invalid reg count = %d, max is %d\n", __func__,
+ new_early_cam_dev->regulator_count, MAX_REGULATOR);
+ rc = -EFAULT;
+ goto early_cam_invalid_vreg_data;
+ }
+
+ rc = msm_camera_config_vreg(&new_early_cam_dev->pdev->dev,
+ new_early_cam_dev->early_cam_vreg,
+ new_early_cam_dev->regulator_count,
+ NULL,
+ 0,
+ &new_early_cam_dev->early_cam_reg_ptr[0], 1);
+ if (rc < 0)
+ pr_err("%s:%d early_cam config_vreg failed\n", __func__,
+ __LINE__);
+
+ rc = msm_camera_enable_vreg(&new_early_cam_dev->pdev->dev,
+ new_early_cam_dev->early_cam_vreg,
+ new_early_cam_dev->regulator_count,
+ NULL,
+ 0,
+ &new_early_cam_dev->early_cam_reg_ptr[0], 1);
+ if (rc < 0)
+ pr_err("%s:%d early_cam enable_vreg failed\n", __func__,
+ __LINE__);
+
+ rc = msm_camera_clk_enable(&new_early_cam_dev->pdev->dev,
+ new_early_cam_dev->early_cam_clk_info,
+ new_early_cam_dev->early_cam_clk,
+ new_early_cam_dev->num_clk, true);
+
+ if (rc < 0) {
+ pr_err("%s: clk enable failed %d\n", __func__, rc);
+ rc = 0;
+ goto early_cam_release_mem;
+ }
+
+ platform_set_drvdata(pdev, new_early_cam_dev);
+
+ return 0;
+
+early_cam_invalid_vreg_data:
+ kfree(new_early_cam_dev->early_cam_vreg);
+early_cam_release_mem:
+ kfree(new_early_cam_dev);
+ new_early_cam_dev = NULL;
+ return rc;
+}
+
+static int msm_early_cam_exit(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static int __init msm_early_cam_init_module(void)
+{
+ return platform_driver_register(&msm_early_camera_driver);
+}
+
+static void __exit msm_early_cam_exit_module(void)
+{
+ kfree(new_early_cam_dev);
+ platform_driver_unregister(&msm_early_camera_driver);
+}
+
+static const struct of_device_id msm_early_camera_match_table[] = {
+ { .compatible = "qcom,early-cam" },
+ {},
+};
+
+static struct platform_driver msm_early_camera_driver = {
+ .probe = msm_early_cam_probe,
+ .remove = msm_early_cam_exit,
+ .driver = {
+ .name = MSM_EARLY_CAM_DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = msm_early_camera_match_table,
+ },
+};
+
+MODULE_DEVICE_TABLE(of, msm_early_camera_match_table);
+
+module_init(msm_early_cam_init_module);
+module_exit(msm_early_cam_exit_module);
+MODULE_DESCRIPTION("MSM early camera driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.h b/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.h
new file mode 100644
index 000000000000..a40ab2d1ebc3
--- /dev/null
+++ b/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.h
@@ -0,0 +1,53 @@
+/* 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
+ * 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 MSM_EARLY_CAM_H
+#define MSM_EARLY_CAM_H
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-subdev.h>
+#include <linux/workqueue.h>
+#include <media/ais/msm_ais_sensor.h>
+#include <soc/qcom/ais.h>
+#include "msm_sd.h"
+#include "cam_soc_api.h"
+
+#define NUM_MASTERS 2
+#define NUM_QUEUES 2
+
+#define TRUE 1
+#define FALSE 0
+
+
+enum msm_early_cam_state_t {
+ STATE_DISABLED,
+ STATE_ENABLED,
+};
+
+struct early_cam_device {
+ struct platform_device *pdev;
+ uint8_t ref_count;
+ enum msm_early_cam_state_t early_cam_state;
+ size_t num_clk;
+ size_t num_clk_cases;
+ struct clk **early_cam_clk;
+ uint32_t **early_cam_clk_rates;
+ struct msm_cam_clk_info *early_cam_clk_info;
+ struct camera_vreg_t *early_cam_vreg;
+ struct regulator *early_cam_reg_ptr[MAX_REGULATOR];
+ int32_t regulator_count;
+};
+
+int msm_early_cam_disable_clocks(void);
+#endif
diff --git a/drivers/media/platform/msm/ais/sensor/msm_sensor_init.c b/drivers/media/platform/msm/ais/sensor/msm_sensor_init.c
index c3943be78226..ffbf963e819e 100644
--- a/drivers/media/platform/msm/ais/sensor/msm_sensor_init.c
+++ b/drivers/media/platform/msm/ais/sensor/msm_sensor_init.c
@@ -16,11 +16,17 @@
#include "msm_sensor_driver.h"
#include "msm_sensor.h"
#include "msm_sd.h"
+#include "msm_camera_io_util.h"
+#include "msm_early_cam.h"
/* Logging macro */
#undef CDBG
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+#define EARLY_CAMERA_SIGNAL_DONE 0xa5a5a5a5
+#define EARLY_CAMERA_SIGNAL_DISABLED 0
+
+static bool early_camera_clock_off;
static struct msm_sensor_init_t *s_init;
static int msm_sensor_wait_for_probe_done(struct msm_sensor_init_t *s_init)
@@ -42,10 +48,14 @@ static int msm_sensor_wait_for_probe_done(struct msm_sensor_init_t *s_init)
return rc;
}
+#define MMSS_A_VFE_0_SPARE 0xC84
+
/* Static function definition */
int32_t msm_sensor_driver_cmd(struct msm_sensor_init_t *s_init, void *arg)
{
int32_t rc = 0;
+ u32 val = 0;
+ void __iomem *base;
struct sensor_init_cfg_data *cfg = (struct sensor_init_cfg_data *)arg;
/* Validate input parameters */
@@ -68,6 +78,28 @@ int32_t msm_sensor_driver_cmd(struct msm_sensor_init_t *s_init, void *arg)
break;
case CFG_SINIT_PROBE_DONE:
+ if (early_camera_clock_off == false) {
+ base = ioremap(0x00A10000, 0x1000);
+ val = msm_camera_io_r_mb(base + MMSS_A_VFE_0_SPARE);
+ while (val != EARLY_CAMERA_SIGNAL_DONE) {
+ if (val == EARLY_CAMERA_SIGNAL_DISABLED)
+ break;
+ msleep(1000);
+ val = msm_camera_io_r_mb(
+ base + MMSS_A_VFE_0_SPARE);
+ pr_err("Waiting for signal from LK val = %u\n",
+ val);
+ }
+ rc = msm_early_cam_disable_clocks();
+ if (rc < 0) {
+ pr_err("Failed to disable early camera :%d\n",
+ rc);
+ } else {
+ early_camera_clock_off = true;
+ pr_debug("Voted OFF early camera clocks\n");
+ }
+ }
+
s_init->module_init_status = 1;
wake_up(&s_init->state_wait);
break;
@@ -99,6 +131,7 @@ static int __init msm_sensor_init_module(void)
mutex_init(&s_init->imutex);
init_waitqueue_head(&s_init->state_wait);
+ early_camera_clock_off = false;
return ret;
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
index 84266691f9b8..302a7b16bc26 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
@@ -615,11 +615,13 @@ static long msm_ois_subdev_ioctl(struct v4l2_subdev *sd,
pr_err("o_ctrl->i2c_client.i2c_func_tbl NULL\n");
return -EINVAL;
}
+ mutex_lock(o_ctrl->ois_mutex);
rc = msm_ois_power_down(o_ctrl);
if (rc < 0) {
pr_err("%s:%d OIS Power down failed\n",
__func__, __LINE__);
}
+ mutex_unlock(o_ctrl->ois_mutex);
return msm_ois_close(sd, NULL);
default:
return -ENOIOCTLCMD;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index de4705c3d2eb..3677bb6e32e6 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -533,11 +533,18 @@ static inline void save_v4l2_buffer(struct v4l2_buffer *b,
static int __map_and_update_binfo(struct msm_vidc_inst *inst,
struct buffer_info *binfo,
- struct v4l2_buffer *b, int i)
+ struct v4l2_buffer *b, u32 i)
{
int rc = 0;
struct msm_smem *same_fd_handle = NULL;
+ if (i >= VIDEO_MAX_PLANES) {
+ dprintk(VIDC_ERR, "Num planes exceeds max: %d, %d\n",
+ i, VIDEO_MAX_PLANES);
+ rc = -EINVAL;
+ goto exit;
+ }
+
same_fd_handle = get_same_fd_buffer(
inst, b->m.planes[i].reserved[0]);
@@ -558,6 +565,7 @@ static int __map_and_update_binfo(struct msm_vidc_inst *inst,
b->m.planes[i].m.userptr = binfo->device_addr[i];
}
+exit:
return rc;
}
@@ -565,7 +573,8 @@ static int __handle_fw_referenced_buffers(struct msm_vidc_inst *inst,
struct buffer_info *binfo,
struct v4l2_buffer *b)
{
- int i = 0, rc = 0;
+ int rc = 0;
+ u32 i = 0;
if (EXTRADATA_IDX(b->length)) {
i = EXTRADATA_IDX(b->length);
@@ -583,8 +592,8 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
{
struct buffer_info *binfo = NULL;
struct buffer_info *temp = NULL, *iterator = NULL;
- int plane = 0;
- int i = 0, rc = 0;
+ int plane = 0, rc = 0;
+ u32 i = 0;
if (!b || !inst) {
dprintk(VIDC_ERR, "%s: invalid input\n", __func__);
diff --git a/drivers/net/can/spi/rh850.c b/drivers/net/can/spi/rh850.c
index a93f979da9ed..d2b6e8caa112 100644
--- a/drivers/net/can/spi/rh850.c
+++ b/drivers/net/can/spi/rh850.c
@@ -1020,6 +1020,8 @@ static int rh850_create_netdev(struct spi_device *spi,
return -ENOMEM;
}
+ netdev->mtu = CANFD_MTU;
+
netdev_priv_data = netdev_priv(netdev);
netdev_priv_data->rh850_can = priv_data;
netdev_priv_data->netdev_index = index;
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index cb152bb4a222..42aab9b86af3 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -2644,14 +2644,14 @@ static void ath10k_process_ieee_hdr(void *data)
dir = (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK);
if (dir == IEEE80211_FC1_DIR_TODS)
- ath10k_extract_frame_header(&wh->i_addr1, &wh->i_addr2,
- &wh->i_addr3);
+ ath10k_extract_frame_header(wh->i_addr1, wh->i_addr2,
+ wh->i_addr3);
else if (dir == IEEE80211_FC1_DIR_FROMDS)
- ath10k_extract_frame_header(&wh->i_addr2, &wh->i_addr3,
- &wh->i_addr1);
+ ath10k_extract_frame_header(wh->i_addr2, wh->i_addr3,
+ wh->i_addr1);
else
- ath10k_extract_frame_header(&wh->i_addr3, &wh->i_addr2,
- &wh->i_addr1);
+ ath10k_extract_frame_header(wh->i_addr3, wh->i_addr2,
+ wh->i_addr1);
}
static void ath10k_pktlog_process_rx(struct ath10k *ar, struct sk_buff *skb)
@@ -2717,6 +2717,46 @@ static void ath10k_pktlog_process_rx(struct ath10k *ar, struct sk_buff *skb)
}
}
+int ath10k_rx_record_pktlog(struct ath10k *ar, struct sk_buff *skb)
+{
+ struct sk_buff *pktlog_skb;
+ struct ath_pktlog_hdr *pl_hdr;
+ struct ath_pktlog_rx_info *pktlog_rx_info;
+ struct htt_rx_desc *rx_desc = (void *)skb->data - sizeof(*rx_desc);
+
+ if (!ar->debug.pktlog_filter)
+ return 0;
+
+ pktlog_skb = dev_alloc_skb(sizeof(struct ath_pktlog_hdr) +
+ sizeof(struct htt_rx_desc) -
+ sizeof(struct htt_host_fw_desc_base));
+ if (!pktlog_skb)
+ return -ENOMEM;
+
+ pktlog_rx_info = (struct ath_pktlog_rx_info *)pktlog_skb->data;
+ pl_hdr = &pktlog_rx_info->pl_hdr;
+
+ pl_hdr->flags = (1 << ATH10K_PKTLOG_FLG_FRM_TYPE_REMOTE_S);
+ pl_hdr->missed_cnt = 0;
+ pl_hdr->mac_id = 0;
+ pl_hdr->log_type = ATH10K_PKTLOG_TYPE_RX_STAT;
+ pl_hdr->flags |= ATH10K_PKTLOG_HDR_SIZE_16;
+ pl_hdr->size = sizeof(*rx_desc) -
+ sizeof(struct htt_host_fw_desc_base);
+
+ pl_hdr->timestamp =
+ cpu_to_le32(rx_desc->ppdu_end.wcn3990.rx_pkt_end.phy_timestamp_1);
+
+ pl_hdr->type_specific_data = 0xDEADAA;
+ memcpy((void *)pktlog_rx_info + sizeof(struct ath_pktlog_hdr),
+ (void *)rx_desc + sizeof(struct htt_host_fw_desc_base),
+ pl_hdr->size);
+
+ ath10k_pktlog_process_rx(ar, pktlog_skb);
+ dev_kfree_skb_any(pktlog_skb);
+ return 0;
+}
+
static void ath10k_pktlog_htc_tx_complete(struct ath10k *ar,
struct sk_buff *skb)
{
diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h
index f9e90e1227de..eb47720bbf91 100644
--- a/drivers/net/wireless/ath/ath10k/debug.h
+++ b/drivers/net/wireless/ath/ath10k/debug.h
@@ -84,7 +84,7 @@ struct ath_pktlog_hdr {
__le16 flags;
__le16 missed_cnt;
u8 log_type;
- u8 macId;
+ u8 mac_id;
__le16 size;
__le32 timestamp;
__le32 type_specific_data;
@@ -164,6 +164,7 @@ struct ath10k_fw_crash_data *
ath10k_debug_get_new_fw_crash_data(struct ath10k *ar);
void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, int len);
+int ath10k_rx_record_pktlog(struct ath10k *ar, struct sk_buff *skb);
#define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++)
void ath10k_debug_get_et_strings(struct ieee80211_hw *hw,
@@ -221,6 +222,12 @@ static inline void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer,
{
}
+static inline int ath10k_rx_record_pktlog(struct ath10k *ar,
+ struct sk_buff *skb)
+{
+ return 0;
+}
+
static inline struct ath10k_fw_crash_data *
ath10k_debug_get_new_fw_crash_data(struct ath10k *ar)
{
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 2df7fcb4a5ea..6377c4ef427c 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -1745,16 +1745,21 @@ struct ath10k_htt {
#define RX_HTT_HDR_STATUS_LEN 64
-/* This structure layout is programmed via rx ring setup
- * so that FW knows how to transfer the rx descriptor to the host.
- * Buffers like this are placed on the rx ring. */
-struct htt_rx_desc {
+struct htt_host_fw_desc_base {
union {
/* This field is filled on the host using the msdu buffer
* from htt_rx_indication */
struct fw_rx_desc_base fw_desc;
u32 pad;
} __packed;
+};
+
+/* This structure layout is programmed via rx ring setup
+ * so that FW knows how to transfer the rx descriptor to the host.
+ * Buffers like this are placed on the rx ring.
+ */
+struct htt_rx_desc {
+ struct htt_host_fw_desc_base fw_desc_base;
struct {
struct rx_attention attention;
struct rx_frag_info frag_info;
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 437ea2c192b3..635b8281b055 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -969,6 +969,7 @@ static void ath10k_process_rx(struct ath10k *ar,
trace_ath10k_rx_hdr(ar, skb->data, skb->len);
trace_ath10k_rx_payload(ar, skb->data, skb->len);
+ ath10k_rx_record_pktlog(ar, skb);
ieee80211_rx_napi(ar->hw, NULL, skb, &ar->napi);
}
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 3e1917a6a8e8..37479589b8e1 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -984,6 +984,16 @@ struct ath10k_shadow_reg_address {
extern struct ath10k_shadow_reg_value wcn3990_shadow_reg_value;
extern struct ath10k_shadow_reg_address wcn3990_shadow_reg_address;
+#define ATH10K_PKTLOG_HDR_SIZE_16 0x8000
+
+enum {
+ ATH10k_PKTLOG_FLG_FRM_TYPE_LOCAL_S = 0,
+ ATH10K_PKTLOG_FLG_FRM_TYPE_REMOTE_S,
+ ATH10K_PKTLOG_FLG_FRM_TYPE_CLONE_S,
+ ATH10K_PKTLOG_FLG_FRM_TYPE_CBF_S,
+ ATH10K_PKTLOG_FLG_FRM_TYPE_UNKNOWN_S
+};
+
enum ath10k_pktlog_type {
ATH10K_PKTLOG_TYPE_TX_CTRL = 1,
ATH10K_PKTLOG_TYPE_TX_STAT,
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index cce931e51d7e..ec86c837e60a 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -7822,10 +7822,6 @@ static const struct ieee80211_iface_limit ath10k_wcn3990_if_limit[] = {
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO),
},
- {
- .max = 1,
- .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
- },
};
static const struct ieee80211_iface_limit ath10k_wcn3990_qcs_if_limit[] = {
@@ -7845,10 +7841,6 @@ static const struct ieee80211_iface_limit ath10k_wcn3990_qcs_if_limit[] = {
#endif
BIT(NL80211_IFTYPE_P2P_GO),
},
- {
- .max = 1,
- .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
- },
};
static const struct ieee80211_iface_limit ath10k_wcn3990_if_limit_ibss[] = {
@@ -8022,6 +8014,10 @@ int ath10k_mac_register(struct ath10k *ar)
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO);
+ if (QCA_REV_WCN3990(ar))
+ ar->hw->wiphy->interface_modes &=
+ ~BIT(NL80211_IFTYPE_P2P_DEVICE);
+
ieee80211_hw_set(ar->hw, SIGNAL_DBM);
ieee80211_hw_set(ar->hw, SUPPORTS_PS);
ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
diff --git a/drivers/net/wireless/cnss2/debug.c b/drivers/net/wireless/cnss2/debug.c
index c3bcb38f428f..c69f0a488c52 100644
--- a/drivers/net/wireless/cnss2/debug.c
+++ b/drivers/net/wireless/cnss2/debug.c
@@ -98,6 +98,10 @@ static int cnss_stats_show_state(struct seq_file *s,
continue;
case CNSS_DEV_ERR_NOTIFY:
seq_puts(s, "DEV_ERR");
+ continue;
+ case CNSS_DRIVER_DEBUG:
+ seq_puts(s, "DRIVER_DEBUG");
+ continue;
}
seq_printf(s, "UNKNOWN-%d", i);
@@ -149,10 +153,26 @@ static ssize_t cnss_dev_boot_debug_write(struct file *fp,
if (sysfs_streq(cmd, "on")) {
ret = cnss_power_on_device(plat_priv);
+ } else if (sysfs_streq(cmd, "off")) {
+ cnss_power_off_device(plat_priv);
} else if (sysfs_streq(cmd, "enumerate")) {
ret = cnss_pci_init(plat_priv);
} else if (sysfs_streq(cmd, "download")) {
ret = cnss_pci_start_mhi(plat_priv->bus_priv);
+ } else if (sysfs_streq(cmd, "linkup")) {
+ ret = cnss_resume_pci_link(plat_priv->bus_priv);
+ } else if (sysfs_streq(cmd, "linkdown")) {
+ ret = cnss_suspend_pci_link(plat_priv->bus_priv);
+ } else if (sysfs_streq(cmd, "powerup")) {
+ set_bit(CNSS_DRIVER_DEBUG, &plat_priv->driver_state);
+ ret = cnss_driver_event_post(plat_priv,
+ CNSS_DRIVER_EVENT_POWER_UP,
+ true, NULL);
+ } else if (sysfs_streq(cmd, "shutdown")) {
+ ret = cnss_driver_event_post(plat_priv,
+ CNSS_DRIVER_EVENT_POWER_DOWN,
+ true, NULL);
+ clear_bit(CNSS_DRIVER_DEBUG, &plat_priv->driver_state);
} else {
cnss_pr_err("Device boot debugfs command is invalid\n");
ret = -EINVAL;
@@ -169,8 +189,13 @@ static int cnss_dev_boot_debug_show(struct seq_file *s, void *data)
seq_puts(s, "\nUsage: echo <action> > <debugfs_path>/cnss/dev_boot\n");
seq_puts(s, "<action> can be one of below:\n");
seq_puts(s, "on: turn on device power, assert WLAN_EN\n");
+ seq_puts(s, "off: de-assert WLAN_EN, turn off device power\n");
seq_puts(s, "enumerate: de-assert PERST, enumerate PCIe\n");
seq_puts(s, "download: download FW and do QMI handshake with FW\n");
+ seq_puts(s, "linkup: bring up PCIe link\n");
+ seq_puts(s, "linkdown: bring down PCIe link\n");
+ seq_puts(s, "powerup: full power on sequence to boot device, download FW and do QMI handshake with FW\n");
+ seq_puts(s, "shutdown: full power off sequence to shutdown device\n");
return 0;
}
diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c
index 8838a1319629..8277de861d63 100644
--- a/drivers/net/wireless/cnss2/main.c
+++ b/drivers/net/wireless/cnss2/main.c
@@ -1060,11 +1060,15 @@ static int cnss_qca6174_shutdown(struct cnss_plat_data *plat_priv)
if (!pci_priv)
return -ENODEV;
+ if (test_bit(CNSS_DRIVER_DEBUG, &plat_priv->driver_state))
+ goto skip_driver_remove;
+
if (!plat_priv->driver_ops)
return -EINVAL;
cnss_driver_call_remove(plat_priv);
+skip_driver_remove:
cnss_request_bus_bandwidth(CNSS_BUS_WIDTH_NONE);
cnss_pci_set_monitor_wake_intr(pci_priv, false);
cnss_pci_set_auto_suspended(pci_priv, 0);
@@ -1162,7 +1166,8 @@ static int cnss_qca6290_shutdown(struct cnss_plat_data *plat_priv)
return -ENODEV;
if (test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state) ||
- test_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state))
+ test_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state) ||
+ test_bit(CNSS_DRIVER_DEBUG, &plat_priv->driver_state))
goto skip_driver_remove;
if (!plat_priv->driver_ops)
diff --git a/drivers/net/wireless/cnss2/main.h b/drivers/net/wireless/cnss2/main.h
index a2d9a02bde20..89ada0b2e1f0 100644
--- a/drivers/net/wireless/cnss2/main.h
+++ b/drivers/net/wireless/cnss2/main.h
@@ -142,6 +142,7 @@ enum cnss_driver_state {
CNSS_DRIVER_RECOVERY,
CNSS_FW_BOOT_RECOVERY,
CNSS_DEV_ERR_NOTIFY,
+ CNSS_DRIVER_DEBUG,
};
struct cnss_recovery_data {
diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c
index 8e66cd5770b5..a741c9c7d115 100644
--- a/drivers/pci/host/pci-msm.c
+++ b/drivers/pci/host/pci-msm.c
@@ -596,7 +596,6 @@ struct msm_pcie_dev_t {
bool cfg_access;
spinlock_t cfg_lock;
unsigned long irqsave_flags;
- struct mutex enumerate_lock;
struct mutex setup_lock;
struct irq_domain *irq_domain;
@@ -704,6 +703,9 @@ static u32 num_rc_on;
/* global lock for PCIe common PHY */
static struct mutex com_phy_lock;
+/* global lock for PCIe enumeration */
+static struct mutex enumerate_lock;
+
/* Table to track info of PCIe devices */
static struct msm_pcie_device_info
msm_pcie_dev_tbl[MAX_RC_NUM * MAX_DEVICE_NUM];
@@ -5050,7 +5052,7 @@ int msm_pcie_enumerate(u32 rc_idx)
int ret = 0, bus_ret = 0, scan_ret = 0;
struct msm_pcie_dev_t *dev = &msm_pcie_dev[rc_idx];
- mutex_lock(&dev->enumerate_lock);
+ mutex_lock(&enumerate_lock);
PCIE_DBG(dev, "Enumerate RC%d\n", rc_idx);
@@ -5169,7 +5171,7 @@ int msm_pcie_enumerate(u32 rc_idx)
}
out:
- mutex_unlock(&dev->enumerate_lock);
+ mutex_unlock(&enumerate_lock);
return ret;
}
@@ -6631,6 +6633,7 @@ int __init pcie_init(void)
pcie_drv.rc_num = 0;
mutex_init(&pcie_drv.drv_lock);
mutex_init(&com_phy_lock);
+ mutex_init(&enumerate_lock);
for (i = 0; i < MAX_RC_NUM; i++) {
snprintf(rc_name, MAX_RC_NAME_LEN, "pcie%d-short", i);
@@ -6665,7 +6668,6 @@ int __init pcie_init(void)
rc_name, i);
spin_lock_init(&msm_pcie_dev[i].cfg_lock);
msm_pcie_dev[i].cfg_access = true;
- mutex_init(&msm_pcie_dev[i].enumerate_lock);
mutex_init(&msm_pcie_dev[i].setup_lock);
mutex_init(&msm_pcie_dev[i].recovery_lock);
spin_lock_init(&msm_pcie_dev[i].linkdown_lock);
diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c
index b111a5904952..2ae2438032b7 100644
--- a/drivers/platform/msm/gsi/gsi.c
+++ b/drivers/platform/msm/gsi/gsi.c
@@ -1901,6 +1901,20 @@ int gsi_stop_channel(unsigned long chan_hdl)
res = wait_for_completion_timeout(&ctx->compl,
msecs_to_jiffies(GSI_STOP_CMD_TIMEOUT_MS));
if (res == 0) {
+ /*
+ * check channel state here in case the channel is stopped but
+ * the interrupt was not handled yet.
+ */
+ val = gsi_readl(gsi_ctx->base +
+ GSI_EE_n_GSI_CH_k_CNTXT_0_OFFS(chan_hdl,
+ gsi_ctx->per.ee));
+ ctx->state = (val &
+ GSI_EE_n_GSI_CH_k_CNTXT_0_CHSTATE_BMSK) >>
+ GSI_EE_n_GSI_CH_k_CNTXT_0_CHSTATE_SHFT;
+ if (ctx->state == GSI_CHAN_STATE_STOPPED) {
+ res = GSI_STATUS_SUCCESS;
+ goto free_lock;
+ }
GSIDBG("chan_hdl=%lu timed out\n", chan_hdl);
res = -GSI_STATUS_TIMED_OUT;
goto free_lock;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 41c497a83555..52f99c830b47 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -2248,7 +2248,6 @@ static int ipa3_q6_set_ex_path_to_apps(void)
struct ipahal_imm_cmd_register_write reg_write;
struct ipahal_imm_cmd_pyld *cmd_pyld;
int retval;
- struct ipahal_reg_valmask valmask;
desc = kcalloc(ipa3_ctx->ipa_num_pipes, sizeof(struct ipa3_desc),
GFP_KERNEL);
@@ -2263,40 +2262,10 @@ static int ipa3_q6_set_ex_path_to_apps(void)
if (ep_idx == -1)
continue;
- if (ipa3_ctx->ep[ep_idx].valid &&
- ipa3_ctx->ep[ep_idx].skip_ep_cfg) {
- BUG_ON(num_descs >= ipa3_ctx->ipa_num_pipes);
-
- reg_write.skip_pipeline_clear = false;
- reg_write.pipeline_clear_options =
- IPAHAL_HPS_CLEAR;
- reg_write.offset =
- ipahal_get_reg_n_ofst(IPA_ENDP_STATUS_n,
- ep_idx);
- ipahal_get_status_ep_valmask(
- ipa3_get_ep_mapping(IPA_CLIENT_APPS_LAN_CONS),
- &valmask);
- reg_write.value = valmask.val;
- reg_write.value_mask = valmask.mask;
- cmd_pyld = ipahal_construct_imm_cmd(
- IPA_IMM_CMD_REGISTER_WRITE, &reg_write, false);
- if (!cmd_pyld) {
- IPAERR("fail construct register_write cmd\n");
- BUG();
- }
-
- desc[num_descs].opcode = ipahal_imm_cmd_get_opcode(
- IPA_IMM_CMD_REGISTER_WRITE);
- desc[num_descs].type = IPA_IMM_CMD_DESC;
- desc[num_descs].callback = ipa3_destroy_imm;
- desc[num_descs].user1 = cmd_pyld;
- desc[num_descs].pyld = cmd_pyld->data;
- desc[num_descs].len = cmd_pyld->len;
- num_descs++;
- }
-
- /* disable statuses for modem producers */
- if (IPA_CLIENT_IS_Q6_PROD(client_idx)) {
+ /* disable statuses for all modem controlled prod pipes */
+ if (IPA_CLIENT_IS_Q6_PROD(client_idx) ||
+ (ipa3_ctx->ep[ep_idx].valid &&
+ ipa3_ctx->ep[ep_idx].skip_ep_cfg)) {
ipa_assert_on(num_descs >= ipa3_ctx->ipa_num_pipes);
reg_write.skip_pipeline_clear = false;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
index 594fd9bcfc02..d0aa42c81750 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
@@ -1612,20 +1612,3 @@ void ipahal_get_fltrt_hash_flush_valmask(
valmask->mask = valmask->val;
}
-
-void ipahal_get_status_ep_valmask(int pipe_num,
- struct ipahal_reg_valmask *valmask)
-{
- if (!valmask) {
- IPAHAL_ERR("Input error\n");
- return;
- }
-
- valmask->val =
- (pipe_num & IPA_ENDP_STATUS_n_STATUS_ENDP_BMSK) <<
- IPA_ENDP_STATUS_n_STATUS_ENDP_SHFT;
-
- valmask->mask =
- IPA_ENDP_STATUS_n_STATUS_ENDP_BMSK <<
- IPA_ENDP_STATUS_n_STATUS_ENDP_SHFT;
-}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h
index 4db09475d5e2..9f32c071cb68 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h
@@ -467,8 +467,6 @@ void ipahal_get_aggr_force_close_valmask(int ep_idx,
void ipahal_get_fltrt_hash_flush_valmask(
struct ipahal_reg_fltrt_hash_flush *flush,
struct ipahal_reg_valmask *valmask);
-void ipahal_get_status_ep_valmask(int pipe_num,
- struct ipahal_reg_valmask *valmask);
#endif /* _IPAHAL_REG_H_ */
diff --git a/drivers/platform/msm/qpnp-revid.c b/drivers/platform/msm/qpnp-revid.c
index 9ea0b40304eb..0fec8acde96c 100644
--- a/drivers/platform/msm/qpnp-revid.c
+++ b/drivers/platform/msm/qpnp-revid.c
@@ -27,6 +27,7 @@
#define REVID_SUBTYPE 0x5
#define REVID_STATUS1 0x8
#define REVID_SPARE_0 0x60
+#define REVID_TP_REV 0xf1
#define REVID_FAB_ID 0xf2
#define QPNP_REVID_DEV_NAME "qcom,qpnp-revid"
@@ -157,9 +158,9 @@ static size_t build_pmic_string(char *buf, size_t n, int sid,
static int qpnp_revid_probe(struct platform_device *pdev)
{
u8 rev1, rev2, rev3, rev4, pmic_type, pmic_subtype, pmic_status;
- u8 option1, option2, option3, option4, spare0, fab_id;
+ u8 option1, option2, option3, option4, spare0;
unsigned int base;
- int rc;
+ int rc, fab_id, tp_rev;
char pmic_string[PMIC_STRING_MAXLENGTH] = {'\0'};
struct revid_chip *revid_chip;
struct regmap *regmap;
@@ -207,6 +208,11 @@ static int qpnp_revid_probe(struct platform_device *pdev)
else
fab_id = -EINVAL;
+ if (of_property_read_bool(pdev->dev.of_node, "qcom,tp-rev-valid"))
+ tp_rev = qpnp_read_byte(regmap, base + REVID_TP_REV);
+ else
+ tp_rev = -EINVAL;
+
revid_chip = devm_kzalloc(&pdev->dev, sizeof(struct revid_chip),
GFP_KERNEL);
if (!revid_chip)
@@ -220,6 +226,7 @@ static int qpnp_revid_probe(struct platform_device *pdev)
revid_chip->data.pmic_subtype = pmic_subtype;
revid_chip->data.pmic_type = pmic_type;
revid_chip->data.fab_id = fab_id;
+ revid_chip->data.tp_rev = tp_rev;
if (pmic_subtype < ARRAY_SIZE(pmic_names))
revid_chip->data.pmic_name = pmic_names[pmic_subtype];
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index 48d31140834a..49e0666d0c23 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -103,7 +103,6 @@ struct usb_bam_sps_type {
struct usb_bam_ctx_type {
struct usb_bam_sps_type usb_bam_sps;
struct resource *io_res;
- void __iomem *regs;
int irq;
struct platform_device *usb_bam_pdev;
struct workqueue_struct *usb_bam_wq;
@@ -113,6 +112,7 @@ struct usb_bam_ctx_type {
u32 inactivity_timer_ms;
bool is_bam_inactivity;
struct usb_bam_pipe_connect *usb_bam_connections;
+ struct msm_usb_bam_data *usb_bam_data;
spinlock_t usb_bam_lock;
};
@@ -320,8 +320,6 @@ static int usb_bam_alloc_buffer(struct usb_bam_pipe_connect *pipe_connect)
{
int ret = 0;
struct usb_bam_ctx_type *ctx = &msm_usb_bam[pipe_connect->bam_type];
- struct msm_usb_bam_platform_data *pdata =
- ctx->usb_bam_pdev->dev.platform_data;
struct sps_mem_buffer *data_buf = &(pipe_connect->data_mem_buf);
struct sps_mem_buffer *desc_buf = &(pipe_connect->desc_mem_buf);
@@ -360,7 +358,7 @@ static int usb_bam_alloc_buffer(struct usb_bam_pipe_connect *pipe_connect)
}
data_buf->phys_base = pipe_connect->data_fifo_base_offset +
- pdata->usb_bam_fifo_baseaddr;
+ ctx->usb_bam_data->usb_bam_fifo_baseaddr;
data_buf->size = pipe_connect->data_fifo_size;
data_buf->base = ioremap(data_buf->phys_base, data_buf->size);
if (!data_buf->base) {
@@ -372,7 +370,7 @@ static int usb_bam_alloc_buffer(struct usb_bam_pipe_connect *pipe_connect)
memset_io(data_buf->base, 0, data_buf->size);
desc_buf->phys_base = pipe_connect->desc_fifo_base_offset +
- pdata->usb_bam_fifo_baseaddr;
+ ctx->usb_bam_data->usb_bam_fifo_baseaddr;
desc_buf->size = pipe_connect->desc_fifo_size;
desc_buf->base = ioremap(desc_buf->phys_base, desc_buf->size);
if (!desc_buf->base) {
@@ -1070,7 +1068,6 @@ int usb_bam_connect(enum usb_ctrl cur_bam, int idx, u32 *bam_pipe_idx)
struct usb_bam_pipe_connect *pipe_connect =
&ctx->usb_bam_connections[idx];
struct device *bam_dev = &ctx->usb_bam_pdev->dev;
- struct msm_usb_bam_platform_data *pdata = bam_dev->platform_data;
enum usb_bam_mode cur_mode;
if (pipe_connect->enabled) {
@@ -1096,7 +1093,7 @@ int usb_bam_connect(enum usb_ctrl cur_bam, int idx, u32 *bam_pipe_idx)
spin_lock(&ctx->usb_bam_lock);
/* Check if BAM requires RESET before connect and reset of first pipe */
- if ((pdata->reset_on_connect == true) &&
+ if ((ctx->usb_bam_data->reset_on_connect == true) &&
(ctx->pipes_enabled_per_bam == 0)) {
spin_unlock(&ctx->usb_bam_lock);
@@ -1596,8 +1593,6 @@ static int ss_usb_cons_release_resource(void)
static void usb_bam_ipa_create_resources(enum usb_ctrl cur_bam)
{
struct usb_bam_ctx_type *ctx = &msm_usb_bam[cur_bam];
- struct msm_usb_bam_platform_data *pdata =
- ctx->usb_bam_pdev->dev.platform_data;
struct ipa_rm_create_params usb_prod_create_params;
struct ipa_rm_create_params usb_cons_create_params;
int ret;
@@ -1606,7 +1601,8 @@ static void usb_bam_ipa_create_resources(enum usb_ctrl cur_bam)
memset(&usb_prod_create_params, 0, sizeof(usb_prod_create_params));
usb_prod_create_params.name = ipa_rm_resource_prod[cur_bam];
usb_prod_create_params.reg_params.notify_cb = usb_prod_notify_cb;
- usb_prod_create_params.reg_params.user_data = &pdata->bam_type;
+ usb_prod_create_params.reg_params.user_data
+ = &ctx->usb_bam_data->bam_type;
usb_prod_create_params.floor_voltage = IPA_VOLTAGE_SVS;
ret = ipa_rm_create_resource(&usb_prod_create_params);
if (ret) {
@@ -2136,16 +2132,14 @@ static int usb_bam_set_ipa_perf(enum usb_ctrl cur_bam,
int ret;
struct usb_bam_ctx_type *ctx = &msm_usb_bam[cur_bam];
struct ipa_rm_perf_profile ipa_rm_perf_prof;
- struct msm_usb_bam_platform_data *pdata =
- ctx->usb_bam_pdev->dev.platform_data;
if (usb_connection_speed == USB_SPEED_SUPER)
ipa_rm_perf_prof.max_supported_bandwidth_mbps =
- pdata->max_mbps_superspeed;
+ ctx->usb_bam_data->max_mbps_superspeed;
else
/* Bam2Bam is supported only for SS and HS (HW limitation) */
ipa_rm_perf_prof.max_supported_bandwidth_mbps =
- pdata->max_mbps_highspeed;
+ ctx->usb_bam_data->max_mbps_highspeed;
/*
* Having a max mbps property in dtsi file is a must
@@ -2182,7 +2176,6 @@ int usb_bam_connect_ipa(enum usb_ctrl cur_bam,
struct usb_bam_ctx_type *ctx = &msm_usb_bam[cur_bam];
struct usb_bam_pipe_connect *pipe_connect;
struct device *bam_dev = &ctx->usb_bam_pdev->dev;
- struct msm_usb_bam_platform_data *pdata = bam_dev->platform_data;
int ret;
bool bam2bam, is_dpl;
@@ -2260,7 +2253,8 @@ int usb_bam_connect_ipa(enum usb_ctrl cur_bam,
/* Check if BAM requires RESET before connect and reset first pipe */
spin_lock(&ctx->usb_bam_lock);
- if (pdata->reset_on_connect && !ctx->pipes_enabled_per_bam) {
+ if (ctx->usb_bam_data->reset_on_connect &&
+ !ctx->pipes_enabled_per_bam) {
spin_unlock(&ctx->usb_bam_lock);
if (cur_bam == CI_CTRL)
@@ -2610,8 +2604,6 @@ int usb_bam_disconnect_pipe(enum usb_ctrl bam_type, u8 idx)
struct usb_bam_pipe_connect *pipe_connect;
struct device *bam_dev = &ctx->usb_bam_pdev->dev;
int ret;
- struct msm_usb_bam_platform_data *pdata =
- ctx->usb_bam_pdev->dev.platform_data;
pipe_connect = &ctx->usb_bam_connections[idx];
@@ -2639,7 +2631,8 @@ int usb_bam_disconnect_pipe(enum usb_ctrl bam_type, u8 idx)
log_event_dbg("%s: success disconnecting pipe %d\n", __func__, idx);
- if (pdata->reset_on_disconnect && !ctx->pipes_enabled_per_bam) {
+ if (ctx->usb_bam_data->reset_on_disconnect
+ && !ctx->pipes_enabled_per_bam) {
if (bam_type == CI_CTRL)
msm_hw_bam_disable(1);
@@ -2807,10 +2800,10 @@ static void usb_bam_sps_events(enum sps_callback_case sps_cb_case, void *user)
}
}
-static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata(
+static struct msm_usb_bam_data *usb_bam_dt_to_data(
struct platform_device *pdev, u32 usb_addr)
{
- struct msm_usb_bam_platform_data *pdata;
+ struct msm_usb_bam_data *usb_bam_data;
struct device_node *node = pdev->dev.of_node;
int rc = 0;
u8 i = 0;
@@ -2819,10 +2812,10 @@ static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata(
u32 threshold, max_connections = 0;
static struct usb_bam_pipe_connect *usb_bam_connections;
- pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata) {
+ usb_bam_data = devm_kzalloc(&pdev->dev, sizeof(*usb_bam_data),
+ GFP_KERNEL);
+ if (!usb_bam_data)
return NULL;
- }
rc = of_property_read_u32(node, "qcom,bam-type", &bam);
if (rc) {
@@ -2835,7 +2828,7 @@ static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata(
__func__, bam);
return NULL;
}
- pdata->bam_type = bam;
+ usb_bam_data->bam_type = bam;
rc = of_property_read_u32(node, "qcom,bam-mode", &bam_mode);
if (rc) {
@@ -2845,49 +2838,49 @@ static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata(
bam_mode = USB_BAM_DEVICE;
}
- pdata->reset_on_connect = of_property_read_bool(node,
+ usb_bam_data->reset_on_connect = of_property_read_bool(node,
"qcom,reset-bam-on-connect");
- pdata->reset_on_disconnect = of_property_read_bool(node,
+ usb_bam_data->reset_on_disconnect = of_property_read_bool(node,
"qcom,reset-bam-on-disconnect");
rc = of_property_read_u32(node, "qcom,usb-bam-num-pipes",
- &pdata->usb_bam_num_pipes);
+ &usb_bam_data->usb_bam_num_pipes);
if (rc) {
log_event_err("Invalid usb bam num pipes property\n");
return NULL;
}
rc = of_property_read_u32(node, "qcom,usb-bam-max-mbps-highspeed",
- &pdata->max_mbps_highspeed);
+ &usb_bam_data->max_mbps_highspeed);
if (rc)
- pdata->max_mbps_highspeed = 0;
+ usb_bam_data->max_mbps_highspeed = 0;
rc = of_property_read_u32(node, "qcom,usb-bam-max-mbps-superspeed",
- &pdata->max_mbps_superspeed);
+ &usb_bam_data->max_mbps_superspeed);
if (rc)
- pdata->max_mbps_superspeed = 0;
+ usb_bam_data->max_mbps_superspeed = 0;
rc = of_property_read_u32(node, "qcom,usb-bam-fifo-baseaddr", &addr);
if (rc)
pr_debug("%s: Invalid usb base address property\n", __func__);
else
- pdata->usb_bam_fifo_baseaddr = addr;
+ usb_bam_data->usb_bam_fifo_baseaddr = addr;
- pdata->ignore_core_reset_ack = of_property_read_bool(node,
+ usb_bam_data->ignore_core_reset_ack = of_property_read_bool(node,
"qcom,ignore-core-reset-ack");
- pdata->disable_clk_gating = of_property_read_bool(node,
+ usb_bam_data->disable_clk_gating = of_property_read_bool(node,
"qcom,disable-clk-gating");
rc = of_property_read_u32(node, "qcom,usb-bam-override-threshold",
&threshold);
if (rc)
- pdata->override_threshold = USB_THRESHOLD;
+ usb_bam_data->override_threshold = USB_THRESHOLD;
else
- pdata->override_threshold = threshold;
+ usb_bam_data->override_threshold = threshold;
- pdata->enable_hsusb_bam_on_boot = of_property_read_bool(node,
+ usb_bam_data->enable_hsusb_bam_on_boot = of_property_read_bool(node,
"qcom,enable-hsusb-bam-on-boot");
for_each_child_of_node(pdev->dev.of_node, node)
@@ -2923,7 +2916,7 @@ static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata(
goto err;
if (usb_bam_connections[i].mem_type == OCI_MEM) {
- if (!pdata->usb_bam_fifo_baseaddr) {
+ if (!usb_bam_data->usb_bam_fifo_baseaddr) {
log_event_err("%s: base address is missing\n",
__func__);
goto err;
@@ -3007,7 +3000,7 @@ static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata(
msm_usb_bam[bam].usb_bam_connections = usb_bam_connections;
msm_usb_bam[bam].max_connections = max_connections;
- return pdata;
+ return usb_bam_data;
err:
log_event_err("%s: failed\n", __func__);
return NULL;
@@ -3016,9 +3009,8 @@ err:
static int usb_bam_init(struct platform_device *pdev)
{
int ret;
- struct msm_usb_bam_platform_data *pdata = pdev->dev.platform_data;
- enum usb_ctrl bam_type = pdata->bam_type;
- struct usb_bam_ctx_type *ctx = &msm_usb_bam[bam_type];
+ struct usb_bam_ctx_type *ctx = dev_get_drvdata(&pdev->dev);
+ enum usb_ctrl bam_type = ctx->usb_bam_data->bam_type;
struct sps_bam_props props;
memset(&props, 0, sizeof(props));
@@ -3027,12 +3019,11 @@ static int usb_bam_init(struct platform_device *pdev)
bam_enable_strings[bam_type]);
props.phys_addr = ctx->io_res->start;
- props.virt_addr = ctx->regs;
props.virt_size = resource_size(ctx->io_res);
props.irq = ctx->irq;
- props.summing_threshold = pdata->override_threshold;
- props.event_threshold = pdata->override_threshold;
- props.num_pipes = pdata->usb_bam_num_pipes;
+ props.summing_threshold = ctx->usb_bam_data->override_threshold;
+ props.event_threshold = ctx->usb_bam_data->override_threshold;
+ props.num_pipes = ctx->usb_bam_data->usb_bam_num_pipes;
props.callback = usb_bam_sps_events;
props.user = bam_enable_strings[bam_type];
@@ -3040,10 +3031,10 @@ static int usb_bam_init(struct platform_device *pdev)
* HSUSB and HSIC Cores don't support RESET ACK signal to BAMs
* Hence, let BAM to ignore acknowledge from USB while resetting PIPE
*/
- if (pdata->ignore_core_reset_ack && bam_type != DWC3_CTRL)
+ if (ctx->usb_bam_data->ignore_core_reset_ack && bam_type != DWC3_CTRL)
props.options = SPS_BAM_NO_EXT_P_RST;
- if (pdata->disable_clk_gating)
+ if (ctx->usb_bam_data->disable_clk_gating)
props.options |= SPS_BAM_NO_LOCAL_CLK_GATING;
/*
@@ -3051,7 +3042,8 @@ static int usb_bam_init(struct platform_device *pdev)
* starting peripheral controller to avoid switching USB core mode
* from legacy to BAM with ongoing data transfers.
*/
- if (pdata->enable_hsusb_bam_on_boot && bam_type == CI_CTRL) {
+ if (ctx->usb_bam_data->enable_hsusb_bam_on_boot
+ && bam_type == CI_CTRL) {
pr_debug("Register and enable HSUSB BAM\n");
props.options |= SPS_BAM_OPT_ENABLE_AT_BOOT;
}
@@ -3068,9 +3060,8 @@ static int usb_bam_init(struct platform_device *pdev)
static int enable_usb_bam(struct platform_device *pdev)
{
int ret;
- struct msm_usb_bam_platform_data *pdata = pdev->dev.platform_data;
- enum usb_ctrl bam_type = pdata->bam_type;
- struct usb_bam_ctx_type *ctx = &msm_usb_bam[bam_type];
+ struct usb_bam_ctx_type *ctx = dev_get_drvdata(&pdev->dev);
+ enum usb_ctrl bam_type = ctx->usb_bam_data->bam_type;
ret = usb_bam_init(pdev);
if (ret) {
@@ -3137,14 +3128,19 @@ void usb_bam_register_panic_hdlr(void)
&usb_bam_panic_blk);
}
+static void usb_bam_unregister_panic_hdlr(void)
+{
+ atomic_notifier_chain_unregister(&panic_notifier_list,
+ &usb_bam_panic_blk);
+}
+
static int usb_bam_probe(struct platform_device *pdev)
{
int ret, i, irq;
struct resource *io_res;
- void __iomem *regs;
enum usb_ctrl bam_type;
struct usb_bam_ctx_type *ctx;
- struct msm_usb_bam_platform_data *pdata;
+ struct msm_usb_bam_data *usb_bam_data;
dev_dbg(&pdev->dev, "usb_bam_probe\n");
@@ -3160,25 +3156,19 @@ static int usb_bam_probe(struct platform_device *pdev)
return irq;
}
- regs = devm_ioremap(&pdev->dev, io_res->start, resource_size(io_res));
- if (!regs) {
- log_event_err("%s: ioremap failed\n", __func__);
- return -ENOMEM;
- }
-
/* specify BAM physical address to be filled in BAM connections */
- pdata = usb_bam_dt_to_pdata(pdev, io_res->start);
- if (!pdata)
+ usb_bam_data = usb_bam_dt_to_data(pdev, io_res->start);
+ if (!usb_bam_data)
return -EINVAL;
- pdev->dev.platform_data = pdata;
- bam_type = pdata->bam_type;
+ bam_type = usb_bam_data->bam_type;
ctx = &msm_usb_bam[bam_type];
+ dev_set_drvdata(&pdev->dev, ctx);
ctx->usb_bam_pdev = pdev;
ctx->irq = irq;
- ctx->regs = regs;
ctx->io_res = io_res;
+ ctx->usb_bam_data = usb_bam_data;
for (i = 0; i < ctx->max_connections; i++) {
ctx->usb_bam_connections[i].enabled = 0;
@@ -3319,15 +3309,15 @@ EXPORT_SYMBOL(usb_bam_get_bam_type);
bool msm_usb_bam_enable(enum usb_ctrl bam, bool bam_enable)
{
- struct msm_usb_bam_platform_data *pdata;
+ struct msm_usb_bam_data *usb_bam_data;
struct usb_bam_ctx_type *ctx = &msm_usb_bam[bam];
if (!ctx->usb_bam_pdev)
return 0;
- pdata = ctx->usb_bam_pdev->dev.platform_data;
+ usb_bam_data = ctx->usb_bam_data;
if ((bam != CI_CTRL) || !(bam_enable ||
- pdata->enable_hsusb_bam_on_boot))
+ usb_bam_data->enable_hsusb_bam_on_boot))
return 0;
msm_hw_bam_disable(1);
@@ -3409,10 +3399,10 @@ EXPORT_SYMBOL(msm_bam_hsic_lpm_ok);
static int usb_bam_remove(struct platform_device *pdev)
{
- struct msm_usb_bam_platform_data *pdata = pdev->dev.platform_data;
- enum usb_ctrl bam_type = pdata->bam_type;
- struct usb_bam_ctx_type *ctx = &msm_usb_bam[bam_type];
+ struct usb_bam_ctx_type *ctx = dev_get_drvdata(&pdev->dev);
+ usb_bam_unregister_panic_hdlr();
+ sps_deregister_bam_device(ctx->h_bam);
destroy_workqueue(ctx->usb_bam_wq);
return 0;
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index 743972bb4b3c..a45a51490817 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -300,6 +300,9 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(cc_step),
POWER_SUPPLY_ATTR(cc_step_sel),
POWER_SUPPLY_ATTR(sw_jeita_enabled),
+ POWER_SUPPLY_ATTR(pd_voltage_max),
+ POWER_SUPPLY_ATTR(pd_voltage_min),
+ POWER_SUPPLY_ATTR(sdp_current_max),
/* Local extensions of type int64_t */
POWER_SUPPLY_ATTR(charge_counter_ext),
/* Properties of type `const char *' */
diff --git a/drivers/power/supply/qcom/pmic-voter.c b/drivers/power/supply/qcom/pmic-voter.c
index b99558ed2100..3d0a71844608 100644
--- a/drivers/power/supply/qcom/pmic-voter.c
+++ b/drivers/power/supply/qcom/pmic-voter.c
@@ -438,12 +438,14 @@ out:
int rerun_election(struct votable *votable)
{
int rc = 0;
+ int effective_result;
lock_votable(votable);
+ effective_result = get_effective_result_locked(votable);
if (votable->callback)
rc = votable->callback(votable,
- votable->data,
- votable->effective_result,
+ votable->data,
+ effective_result,
get_client_str(votable, votable->effective_client_id));
unlock_votable(votable);
return rc;
@@ -519,11 +521,10 @@ static int show_votable_clients(struct seq_file *m, void *data)
lock_votable(votable);
- seq_printf(m, "Votable %s:\n", votable->name);
- seq_puts(m, "clients:\n");
for (i = 0; i < votable->num_clients; i++) {
if (votable->client_strs[i]) {
- seq_printf(m, "%-15s:\t\ten=%d\t\tv=%d\n",
+ seq_printf(m, "%s: %s:\t\t\ten=%d v=%d\n",
+ votable->name,
votable->client_strs[i],
votable->votes[i].enabled,
votable->votes[i].value);
@@ -542,11 +543,11 @@ static int show_votable_clients(struct seq_file *m, void *data)
break;
}
- seq_printf(m, "type: %s\n", type_str);
- seq_puts(m, "Effective:\n");
effective_client_str = get_effective_client_locked(votable);
- seq_printf(m, "%-15s:\t\tv=%d\n",
+ seq_printf(m, "%s: effective=%s type=%s v=%d\n",
+ votable->name,
effective_client_str ? effective_client_str : "none",
+ type_str,
get_effective_result_locked(votable));
unlock_votable(votable);
diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c
index b0a78758abd6..c085256a794a 100644
--- a/drivers/power/supply/qcom/qpnp-smb2.c
+++ b/drivers/power/supply/qcom/qpnp-smb2.c
@@ -330,7 +330,6 @@ static int smb2_parse_dt(struct smb2 *chip)
static enum power_supply_property smb2_usb_props[] = {
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_ONLINE,
- POWER_SUPPLY_PROP_VOLTAGE_MIN,
POWER_SUPPLY_PROP_VOLTAGE_MAX,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_PD_CURRENT_MAX,
@@ -349,6 +348,9 @@ static enum power_supply_property smb2_usb_props[] = {
POWER_SUPPLY_PROP_HW_CURRENT_MAX,
POWER_SUPPLY_PROP_REAL_TYPE,
POWER_SUPPLY_PROP_PR_SWAP,
+ POWER_SUPPLY_PROP_PD_VOLTAGE_MAX,
+ POWER_SUPPLY_PROP_PD_VOLTAGE_MIN,
+ POWER_SUPPLY_PROP_SDP_CURRENT_MAX,
};
static int smb2_usb_get_prop(struct power_supply *psy,
@@ -380,20 +382,17 @@ static int smb2_usb_get_prop(struct power_supply *psy,
if (chg->real_charger_type == POWER_SUPPLY_TYPE_UNKNOWN)
val->intval = 0;
break;
- case POWER_SUPPLY_PROP_VOLTAGE_MIN:
- val->intval = chg->voltage_min_uv;
- break;
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
- val->intval = chg->voltage_max_uv;
+ rc = smblib_get_prop_usb_voltage_max(chg, val);
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
rc = smblib_get_prop_usb_voltage_now(chg, val);
break;
case POWER_SUPPLY_PROP_PD_CURRENT_MAX:
- rc = smblib_get_prop_pd_current_max(chg, val);
+ val->intval = get_client_vote(chg->usb_icl_votable, PD_VOTER);
break;
case POWER_SUPPLY_PROP_CURRENT_MAX:
- rc = smblib_get_prop_usb_current_max(chg, val);
+ rc = smblib_get_prop_input_current_settled(chg, val);
break;
case POWER_SUPPLY_PROP_TYPE:
val->intval = POWER_SUPPLY_TYPE_USB_PD;
@@ -457,6 +456,16 @@ static int smb2_usb_get_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_PR_SWAP:
rc = smblib_get_prop_pr_swap_in_progress(chg, val);
break;
+ case POWER_SUPPLY_PROP_PD_VOLTAGE_MAX:
+ val->intval = chg->voltage_max_uv;
+ break;
+ case POWER_SUPPLY_PROP_PD_VOLTAGE_MIN:
+ val->intval = chg->voltage_min_uv;
+ break;
+ case POWER_SUPPLY_PROP_SDP_CURRENT_MAX:
+ val->intval = get_client_vote(chg->usb_icl_votable,
+ USB_PSY_VOTER);
+ break;
default:
pr_err("get prop %d is not supported in usb\n", psp);
rc = -EINVAL;
@@ -484,18 +493,9 @@ static int smb2_usb_set_prop(struct power_supply *psy,
}
switch (psp) {
- case POWER_SUPPLY_PROP_VOLTAGE_MIN:
- rc = smblib_set_prop_usb_voltage_min(chg, val);
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_MAX:
- rc = smblib_set_prop_usb_voltage_max(chg, val);
- break;
case POWER_SUPPLY_PROP_PD_CURRENT_MAX:
rc = smblib_set_prop_pd_current_max(chg, val);
break;
- case POWER_SUPPLY_PROP_CURRENT_MAX:
- rc = smblib_set_prop_usb_current_max(chg, val);
- break;
case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
rc = smblib_set_prop_typec_power_role(chg, val);
break;
@@ -518,6 +518,15 @@ static int smb2_usb_set_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_PR_SWAP:
rc = smblib_set_prop_pr_swap_in_progress(chg, val);
break;
+ case POWER_SUPPLY_PROP_PD_VOLTAGE_MAX:
+ rc = smblib_set_prop_pd_voltage_max(chg, val);
+ break;
+ case POWER_SUPPLY_PROP_PD_VOLTAGE_MIN:
+ rc = smblib_set_prop_pd_voltage_min(chg, val);
+ break;
+ case POWER_SUPPLY_PROP_SDP_CURRENT_MAX:
+ rc = smblib_set_prop_sdp_current_max(chg, val);
+ break;
default:
pr_err("set prop %d is not supported\n", psp);
rc = -EINVAL;
@@ -533,8 +542,6 @@ static int smb2_usb_prop_is_writeable(struct power_supply *psy,
enum power_supply_property psp)
{
switch (psp) {
- case POWER_SUPPLY_PROP_CURRENT_MAX:
- case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
case POWER_SUPPLY_PROP_CTM_CURRENT_MAX:
return 1;
default:
@@ -576,6 +583,8 @@ static int smb2_init_usb_psy(struct smb2 *chip)
static enum power_supply_property smb2_usb_port_props[] = {
POWER_SUPPLY_PROP_TYPE,
POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_VOLTAGE_MAX,
+ POWER_SUPPLY_PROP_CURRENT_MAX,
};
static int smb2_usb_port_get_prop(struct power_supply *psy,
@@ -602,6 +611,12 @@ static int smb2_usb_port_get_prop(struct power_supply *psy,
else
val->intval = 0;
break;
+ case POWER_SUPPLY_PROP_VOLTAGE_MAX:
+ val->intval = 5000000;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_MAX:
+ rc = smblib_get_prop_input_current_settled(chg, val);
+ break;
default:
pr_err_ratelimited("Get prop %d is not supported in pc_port\n",
psp);
@@ -783,6 +798,7 @@ static enum power_supply_property smb2_dc_props[] = {
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_ONLINE,
POWER_SUPPLY_PROP_CURRENT_MAX,
+ POWER_SUPPLY_PROP_REAL_TYPE,
};
static int smb2_dc_get_prop(struct power_supply *psy,
@@ -803,6 +819,9 @@ static int smb2_dc_get_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_CURRENT_MAX:
rc = smblib_get_prop_dc_current_max(chg, val);
break;
+ case POWER_SUPPLY_PROP_REAL_TYPE:
+ val->intval = POWER_SUPPLY_TYPE_WIPOWER;
+ break;
default:
return -EINVAL;
}
@@ -851,7 +870,7 @@ static int smb2_dc_prop_is_writeable(struct power_supply *psy,
static const struct power_supply_desc dc_psy_desc = {
.name = "dc",
- .type = POWER_SUPPLY_TYPE_WIPOWER,
+ .type = POWER_SUPPLY_TYPE_WIRELESS,
.properties = smb2_dc_props,
.num_properties = ARRAY_SIZE(smb2_dc_props),
.get_property = smb2_dc_get_prop,
@@ -908,6 +927,7 @@ static enum power_supply_property smb2_batt_props[] = {
POWER_SUPPLY_PROP_DIE_HEALTH,
POWER_SUPPLY_PROP_RERUN_AICL,
POWER_SUPPLY_PROP_DP_DM,
+ POWER_SUPPLY_PROP_CHARGE_COUNTER,
};
static int smb2_batt_get_prop(struct power_supply *psy,
@@ -1013,6 +1033,9 @@ static int smb2_batt_get_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_RERUN_AICL:
val->intval = 0;
break;
+ case POWER_SUPPLY_PROP_CHARGE_COUNTER:
+ rc = smblib_get_prop_batt_charge_counter(chg, val);
+ break;
default:
pr_err("batt power supply prop %d not supported\n", psp);
return -EINVAL;
@@ -1799,8 +1822,8 @@ static int smb2_chg_config_init(struct smb2 *chip)
chip->chg.wa_flags |= BOOST_BACK_WA | OTG_WA;
chg->param.freq_buck = pm660_params.freq_buck;
chg->param.freq_boost = pm660_params.freq_boost;
- chg->chg_freq.freq_5V = 600;
- chg->chg_freq.freq_6V_8V = 800;
+ chg->chg_freq.freq_5V = 650;
+ chg->chg_freq.freq_6V_8V = 850;
chg->chg_freq.freq_9V = 1050;
chg->chg_freq.freq_12V = 1200;
chg->chg_freq.freq_removal = 1050;
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index 825d49b2fe4f..f9d35ea7775b 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -420,19 +420,21 @@ static int smblib_set_adapter_allowance(struct smb_charger *chg,
{
int rc = 0;
- switch (allowed_voltage) {
- case USBIN_ADAPTER_ALLOW_12V:
- case USBIN_ADAPTER_ALLOW_5V_OR_12V:
- case USBIN_ADAPTER_ALLOW_9V_TO_12V:
- case USBIN_ADAPTER_ALLOW_5V_OR_9V_TO_12V:
- case USBIN_ADAPTER_ALLOW_5V_TO_12V:
- /* PM660 only support max. 9V */
- if (chg->smb_version == PM660_SUBTYPE) {
- smblib_dbg(chg, PR_MISC, "voltage not supported=%d\n",
- allowed_voltage);
+ /* PM660 only support max. 9V */
+ if (chg->smb_version == PM660_SUBTYPE) {
+ switch (allowed_voltage) {
+ case USBIN_ADAPTER_ALLOW_12V:
+ case USBIN_ADAPTER_ALLOW_9V_TO_12V:
+ allowed_voltage = USBIN_ADAPTER_ALLOW_9V;
+ break;
+ case USBIN_ADAPTER_ALLOW_5V_OR_12V:
+ case USBIN_ADAPTER_ALLOW_5V_OR_9V_TO_12V:
allowed_voltage = USBIN_ADAPTER_ALLOW_5V_OR_9V;
+ break;
+ case USBIN_ADAPTER_ALLOW_5V_TO_12V:
+ allowed_voltage = USBIN_ADAPTER_ALLOW_5V_TO_9V;
+ break;
}
- break;
}
rc = smblib_write(chg, USBIN_ADAPTER_ALLOW_CFG_REG, allowed_voltage);
@@ -1843,6 +1845,19 @@ int smblib_get_prop_charge_qnovo_enable(struct smb_charger *chg,
return 0;
}
+int smblib_get_prop_batt_charge_counter(struct smb_charger *chg,
+ union power_supply_propval *val)
+{
+ int rc;
+
+ if (!chg->bms_psy)
+ return -EINVAL;
+
+ rc = power_supply_get_property(chg->bms_psy,
+ POWER_SUPPLY_PROP_CHARGE_COUNTER, val);
+ return rc;
+}
+
/***********************
* BATTERY PSY SETTERS *
***********************/
@@ -2187,6 +2202,25 @@ int smblib_get_prop_usb_online(struct smb_charger *chg,
return rc;
}
+int smblib_get_prop_usb_voltage_max(struct smb_charger *chg,
+ union power_supply_propval *val)
+{
+ switch (chg->real_charger_type) {
+ case POWER_SUPPLY_TYPE_USB_HVDCP:
+ case POWER_SUPPLY_TYPE_USB_PD:
+ if (chg->smb_version == PM660_SUBTYPE)
+ val->intval = MICRO_9V;
+ else
+ val->intval = MICRO_12V;
+ break;
+ default:
+ val->intval = MICRO_5V;
+ break;
+ }
+
+ return 0;
+}
+
int smblib_get_prop_usb_voltage_now(struct smb_charger *chg,
union power_supply_propval *val)
{
@@ -2206,21 +2240,6 @@ int smblib_get_prop_usb_voltage_now(struct smb_charger *chg,
return iio_read_channel_processed(chg->iio.usbin_v_chan, &val->intval);
}
-int smblib_get_prop_pd_current_max(struct smb_charger *chg,
- union power_supply_propval *val)
-{
- val->intval = get_client_vote_locked(chg->usb_icl_votable, PD_VOTER);
- return 0;
-}
-
-int smblib_get_prop_usb_current_max(struct smb_charger *chg,
- union power_supply_propval *val)
-{
- val->intval = get_client_vote_locked(chg->usb_icl_votable,
- USB_PSY_VOTER);
- return 0;
-}
-
int smblib_get_prop_usb_current_now(struct smb_charger *chg,
union power_supply_propval *val)
{
@@ -2558,7 +2577,7 @@ static int smblib_handle_usb_current(struct smb_charger *chg,
return rc;
}
-int smblib_set_prop_usb_current_max(struct smb_charger *chg,
+int smblib_set_prop_sdp_current_max(struct smb_charger *chg,
const union power_supply_propval *val)
{
int rc = 0;
@@ -2645,7 +2664,7 @@ int smblib_set_prop_typec_power_role(struct smb_charger *chg,
return rc;
}
-int smblib_set_prop_usb_voltage_min(struct smb_charger *chg,
+int smblib_set_prop_pd_voltage_min(struct smb_charger *chg,
const union power_supply_propval *val)
{
int rc, min_uv;
@@ -2664,7 +2683,7 @@ int smblib_set_prop_usb_voltage_min(struct smb_charger *chg,
return rc;
}
-int smblib_set_prop_usb_voltage_max(struct smb_charger *chg,
+int smblib_set_prop_pd_voltage_max(struct smb_charger *chg,
const union power_supply_propval *val)
{
int rc, max_uv;
@@ -3597,6 +3616,32 @@ static void smblib_force_legacy_icl(struct smb_charger *chg, int pst)
}
}
+static void smblib_notify_extcon_props(struct smb_charger *chg)
+{
+ union power_supply_propval val;
+
+ smblib_get_prop_typec_cc_orientation(chg, &val);
+ extcon_set_cable_state_(chg->extcon, EXTCON_USB_CC,
+ (val.intval == 2) ? 1 : 0);
+ extcon_set_cable_state_(chg->extcon, EXTCON_USB_SPEED, true);
+}
+
+static void smblib_notify_device_mode(struct smb_charger *chg, bool enable)
+{
+ if (enable)
+ smblib_notify_extcon_props(chg);
+
+ extcon_set_cable_state_(chg->extcon, EXTCON_USB, enable);
+}
+
+static void smblib_notify_usb_host(struct smb_charger *chg, bool enable)
+{
+ if (enable)
+ smblib_notify_extcon_props(chg);
+
+ extcon_set_cable_state_(chg->extcon, EXTCON_USB_HOST, enable);
+}
+
#define HVDCP_DET_MS 2500
static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising)
{
@@ -3616,6 +3661,8 @@ static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising)
if (chg->micro_usb_mode)
extcon_set_cable_state_(chg->extcon, EXTCON_USB,
true);
+ if (chg->use_extcon)
+ smblib_notify_device_mode(chg, true);
case OCP_CHARGER_BIT:
case FLOAT_CHARGER_BIT:
/* if not DCP then no hvdcp timeout happens, Enable pd here. */
@@ -3700,6 +3747,10 @@ static void typec_sink_insertion(struct smb_charger *chg)
*/
vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER,
false, 0);
+ if (chg->use_extcon) {
+ smblib_notify_usb_host(chg, true);
+ chg->otg_present = true;
+ }
}
static void typec_sink_removal(struct smb_charger *chg)
@@ -3848,6 +3899,14 @@ unlock:
typec_sink_removal(chg);
smblib_update_usb_type(chg);
+
+ if (chg->use_extcon) {
+ if (chg->otg_present)
+ smblib_notify_usb_host(chg, false);
+ else
+ smblib_notify_device_mode(chg, false);
+ }
+ chg->otg_present = false;
}
static void smblib_handle_typec_insertion(struct smb_charger *chg)
diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h
index 0bb1ae03d101..a89d09711ec8 100644
--- a/drivers/power/supply/qcom/smb-lib.h
+++ b/drivers/power/supply/qcom/smb-lib.h
@@ -139,9 +139,14 @@ struct smb_irq_info {
static const unsigned int smblib_extcon_cable[] = {
EXTCON_USB,
EXTCON_USB_HOST,
+ EXTCON_USB_CC,
+ EXTCON_USB_SPEED,
EXTCON_NONE,
};
+/* EXTCON_USB and EXTCON_USB_HOST are mutually exclusive */
+static const u32 smblib_extcon_exclusive[] = {0x3, 0};
+
struct smb_regulator {
struct regulator_dev *rdev;
struct regulator_desc rdesc;
@@ -328,6 +333,8 @@ struct smb_charger {
int usb_icl_change_irq_enabled;
u32 jeita_status;
u8 float_cfg;
+ bool use_extcon;
+ bool otg_present;
/* workaround flag */
u32 wa_flags;
@@ -419,6 +426,8 @@ int smblib_get_prop_batt_current_now(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_batt_temp(struct smb_charger *chg,
union power_supply_propval *val);
+int smblib_get_prop_batt_charge_counter(struct smb_charger *chg,
+ union power_supply_propval *val);
int smblib_set_prop_input_suspend(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_batt_capacity(struct smb_charger *chg,
@@ -443,11 +452,9 @@ int smblib_get_prop_usb_online(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_usb_suspend(struct smb_charger *chg,
union power_supply_propval *val);
-int smblib_get_prop_usb_voltage_now(struct smb_charger *chg,
+int smblib_get_prop_usb_voltage_max(struct smb_charger *chg,
union power_supply_propval *val);
-int smblib_get_prop_pd_current_max(struct smb_charger *chg,
- union power_supply_propval *val);
-int smblib_get_prop_usb_current_max(struct smb_charger *chg,
+int smblib_get_prop_usb_voltage_now(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_usb_current_now(struct smb_charger *chg,
union power_supply_propval *val);
@@ -475,11 +482,11 @@ int smblib_get_prop_charge_qnovo_enable(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_set_prop_pd_current_max(struct smb_charger *chg,
const union power_supply_propval *val);
-int smblib_set_prop_usb_current_max(struct smb_charger *chg,
+int smblib_set_prop_sdp_current_max(struct smb_charger *chg,
const union power_supply_propval *val);
-int smblib_set_prop_usb_voltage_min(struct smb_charger *chg,
+int smblib_set_prop_pd_voltage_max(struct smb_charger *chg,
const union power_supply_propval *val);
-int smblib_set_prop_usb_voltage_max(struct smb_charger *chg,
+int smblib_set_prop_pd_voltage_min(struct smb_charger *chg,
const union power_supply_propval *val);
int smblib_set_prop_boost_current(struct smb_charger *chg,
const union power_supply_propval *val);
diff --git a/drivers/power/supply/qcom/smb138x-charger.c b/drivers/power/supply/qcom/smb138x-charger.c
index ec74e3825dd5..17e5891ace4f 100644
--- a/drivers/power/supply/qcom/smb138x-charger.c
+++ b/drivers/power/supply/qcom/smb138x-charger.c
@@ -215,6 +215,7 @@ static enum power_supply_property smb138x_usb_props[] = {
POWER_SUPPLY_PROP_TYPEC_MODE,
POWER_SUPPLY_PROP_TYPEC_POWER_ROLE,
POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION,
+ POWER_SUPPLY_PROP_SDP_CURRENT_MAX,
};
static int smb138x_usb_get_prop(struct power_supply *psy,
@@ -242,7 +243,7 @@ static int smb138x_usb_get_prop(struct power_supply *psy,
rc = smblib_get_prop_usb_voltage_now(chg, val);
break;
case POWER_SUPPLY_PROP_CURRENT_MAX:
- rc = smblib_get_prop_usb_current_max(chg, val);
+ val->intval = get_effective_result(chg->usb_icl_votable);
break;
case POWER_SUPPLY_PROP_TYPE:
val->intval = chg->usb_psy_desc.type;
@@ -256,6 +257,10 @@ static int smb138x_usb_get_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION:
rc = smblib_get_prop_typec_cc_orientation(chg, val);
break;
+ case POWER_SUPPLY_PROP_SDP_CURRENT_MAX:
+ val->intval = get_client_vote(chg->usb_icl_votable,
+ USB_PSY_VOTER);
+ break;
default:
pr_err("get prop %d is not supported\n", prop);
return -EINVAL;
@@ -278,18 +283,12 @@ static int smb138x_usb_set_prop(struct power_supply *psy,
int rc = 0;
switch (prop) {
- case POWER_SUPPLY_PROP_VOLTAGE_MIN:
- rc = smblib_set_prop_usb_voltage_min(chg, val);
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_MAX:
- rc = smblib_set_prop_usb_voltage_max(chg, val);
- break;
- case POWER_SUPPLY_PROP_CURRENT_MAX:
- rc = smblib_set_prop_usb_current_max(chg, val);
- break;
case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
rc = smblib_set_prop_typec_power_role(chg, val);
break;
+ case POWER_SUPPLY_PROP_SDP_CURRENT_MAX:
+ rc = smblib_set_prop_sdp_current_max(chg, val);
+ break;
default:
pr_err("set prop %d is not supported\n", prop);
return -EINVAL;
@@ -301,13 +300,6 @@ static int smb138x_usb_set_prop(struct power_supply *psy,
static int smb138x_usb_prop_is_writeable(struct power_supply *psy,
enum power_supply_property prop)
{
- switch (prop) {
- case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
- return 1;
- default:
- break;
- }
-
return 0;
}
diff --git a/drivers/regulator/qpnp-lcdb-regulator.c b/drivers/regulator/qpnp-lcdb-regulator.c
index 724e8a4c00da..27f2d9851c2a 100644
--- a/drivers/regulator/qpnp-lcdb-regulator.c
+++ b/drivers/regulator/qpnp-lcdb-regulator.c
@@ -147,6 +147,8 @@
#define MIN_SOFT_START_US 0
#define MAX_SOFT_START_US 2000
+#define BST_HEADROOM_DEFAULT_MV 200
+
struct ldo_regulator {
struct regulator_desc rdesc;
struct regulator_dev *rdev;
@@ -187,6 +189,7 @@ struct bst_params {
int soft_start_us;
int vreg_ok_dbc_us;
int voltage_mv;
+ u16 headroom_mv;
};
struct qpnp_lcdb {
@@ -853,28 +856,40 @@ irq_handled:
#define VOLTAGE_STEP_50_MV 50
#define VOLTAGE_STEP_50MV_OFFSET 0xA
static int qpnp_lcdb_set_bst_voltage(struct qpnp_lcdb *lcdb,
- int voltage_mv)
+ int voltage_mv, u8 type)
{
int rc = 0;
u8 val = 0;
+ int bst_voltage_mv;
+ struct ldo_regulator *ldo = &lcdb->ldo;
+ struct ncp_regulator *ncp = &lcdb->ncp;
+ struct bst_params *bst = &lcdb->bst;
+
+ /* Vout_Boost = headroom_mv + max( Vout_LDO, abs (Vout_NCP)) */
+ bst_voltage_mv = max(voltage_mv, max(ldo->voltage_mv, ncp->voltage_mv));
+ bst_voltage_mv += bst->headroom_mv;
+
+ if (bst_voltage_mv < MIN_BST_VOLTAGE_MV)
+ bst_voltage_mv = MIN_BST_VOLTAGE_MV;
+ else if (bst_voltage_mv > MAX_BST_VOLTAGE_MV)
+ bst_voltage_mv = MAX_BST_VOLTAGE_MV;
+
+ if (bst_voltage_mv != bst->voltage_mv) {
+ val = DIV_ROUND_UP(bst_voltage_mv - MIN_BST_VOLTAGE_MV,
+ VOLTAGE_STEP_50_MV);
- if (voltage_mv < MIN_BST_VOLTAGE_MV)
- voltage_mv = MIN_BST_VOLTAGE_MV;
- else if (voltage_mv > MAX_BST_VOLTAGE_MV)
- voltage_mv = MAX_BST_VOLTAGE_MV;
-
- val = DIV_ROUND_UP(voltage_mv - MIN_BST_VOLTAGE_MV,
- VOLTAGE_STEP_50_MV);
-
- rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
- LCDB_BST_OUTPUT_VOLTAGE_REG,
- SET_OUTPUT_VOLTAGE_MASK, val);
- if (rc < 0)
- pr_err("Failed to set boost voltage %d mv rc=%d\n",
- voltage_mv, rc);
- else
- pr_debug("Boost voltage set = %d mv (0x%02x = 0x%02x)\n",
- voltage_mv, LCDB_BST_OUTPUT_VOLTAGE_REG, val);
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
+ LCDB_BST_OUTPUT_VOLTAGE_REG,
+ SET_OUTPUT_VOLTAGE_MASK, val);
+ if (rc < 0) {
+ pr_err("Failed to set boost voltage %d mv rc=%d\n",
+ bst_voltage_mv, rc);
+ } else {
+ pr_debug("Boost voltage set = %d mv (0x%02x = 0x%02x)\n",
+ bst_voltage_mv, LCDB_BST_OUTPUT_VOLTAGE_REG, val);
+ bst->voltage_mv = bst_voltage_mv;
+ }
+ }
return rc;
}
@@ -905,25 +920,16 @@ static int qpnp_lcdb_set_voltage(struct qpnp_lcdb *lcdb,
u16 offset = LCDB_LDO_OUTPUT_VOLTAGE_REG;
u8 val = 0;
- if (type == BST)
- return qpnp_lcdb_set_bst_voltage(lcdb, voltage_mv);
-
- if (type == NCP)
- offset = LCDB_NCP_OUTPUT_VOLTAGE_REG;
-
if (!is_between(voltage_mv, MIN_VOLTAGE_MV, MAX_VOLTAGE_MV)) {
pr_err("Invalid voltage %dmv (min=%d max=%d)\n",
voltage_mv, MIN_VOLTAGE_MV, MAX_VOLTAGE_MV);
return -EINVAL;
}
- /* Change the BST voltage to LDO + 100mV */
- if (type == LDO) {
- rc = qpnp_lcdb_set_bst_voltage(lcdb, voltage_mv + 100);
- if (rc < 0) {
- pr_err("Failed to set boost voltage rc=%d\n", rc);
- return rc;
- }
+ rc = qpnp_lcdb_set_bst_voltage(lcdb, voltage_mv, type);
+ if (rc < 0) {
+ pr_err("Failed to set boost voltage rc=%d\n", rc);
+ return rc;
}
/* Below logic is only valid for LDO and NCP type */
@@ -936,6 +942,9 @@ static int qpnp_lcdb_set_voltage(struct qpnp_lcdb *lcdb,
val += VOLTAGE_STEP_50MV_OFFSET;
}
+ if (type == NCP)
+ offset = LCDB_NCP_OUTPUT_VOLTAGE_REG;
+
rc = qpnp_lcdb_masked_write(lcdb, lcdb->base + offset,
SET_OUTPUT_VOLTAGE_MASK, val);
if (rc < 0)
@@ -1058,6 +1067,8 @@ static int qpnp_lcdb_ldo_regulator_set_voltage(struct regulator_dev *rdev,
rc = qpnp_lcdb_set_voltage(lcdb, min_uV / 1000, LDO);
if (rc < 0)
pr_err("Failed to set LDO voltage rc=%c\n", rc);
+ else
+ lcdb->ldo.voltage_mv = min_uV / 1000;
return rc;
}
@@ -1129,6 +1140,8 @@ static int qpnp_lcdb_ncp_regulator_set_voltage(struct regulator_dev *rdev,
rc = qpnp_lcdb_set_voltage(lcdb, min_uV / 1000, NCP);
if (rc < 0)
pr_err("Failed to set LDO voltage rc=%c\n", rc);
+ else
+ lcdb->ncp.voltage_mv = min_uV / 1000;
return rc;
}
@@ -1389,6 +1402,12 @@ static int qpnp_lcdb_bst_dt_init(struct qpnp_lcdb *lcdb)
return -EINVAL;
}
+ /* Boost head room configuration */
+ of_property_read_u16(node, "qcom,bst-headroom-mv",
+ &lcdb->bst.headroom_mv);
+ if (lcdb->bst.headroom_mv < BST_HEADROOM_DEFAULT_MV)
+ lcdb->bst.headroom_mv = BST_HEADROOM_DEFAULT_MV;
+
return 0;
}
@@ -1695,6 +1714,9 @@ static int qpnp_lcdb_init_bst(struct qpnp_lcdb *lcdb)
}
lcdb->bst.soft_start_us = (val & SOFT_START_MASK) * 200 + 200;
+ if (!lcdb->bst.headroom_mv)
+ lcdb->bst.headroom_mv = BST_HEADROOM_DEFAULT_MV;
+
return 0;
}
diff --git a/drivers/soc/qcom/glink_smem_native_xprt.c b/drivers/soc/qcom/glink_smem_native_xprt.c
index 37193bbb23b7..042108d4035b 100644
--- a/drivers/soc/qcom/glink_smem_native_xprt.c
+++ b/drivers/soc/qcom/glink_smem_native_xprt.c
@@ -2242,6 +2242,7 @@ static int parse_qos_dt_params(struct device_node *node,
einfo->ramp_time_us[i] = arr32[i];
rc = 0;
+ kfree(arr32);
return rc;
invalid_key:
diff --git a/drivers/soc/qcom/qbt1000.c b/drivers/soc/qcom/qbt1000.c
index d14e82415c5a..7a62c2e36da8 100644
--- a/drivers/soc/qcom/qbt1000.c
+++ b/drivers/soc/qcom/qbt1000.c
@@ -12,6 +12,7 @@
#define pr_fmt(fmt) "qbt1000:%s: " fmt, __func__
+#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
@@ -105,10 +106,14 @@ struct qbt1000_drvdata {
*/
struct fw_ipc_cmd {
uint32_t status;
+ uint32_t numMsgs;
+ uint8_t msg_data[FW_MAX_IPC_MSG_DATA_SIZE];
+};
+
+struct fw_ipc_header {
uint32_t msg_type;
uint32_t msg_len;
uint32_t resp_needed;
- uint8_t msg_data[FW_MAX_IPC_MSG_DATA_SIZE];
};
/*
@@ -352,7 +357,14 @@ static int qbt1000_open(struct inode *inode, struct file *file)
*/
static int qbt1000_release(struct inode *inode, struct file *file)
{
- struct qbt1000_drvdata *drvdata = file->private_data;
+ struct qbt1000_drvdata *drvdata;
+
+ if (!file->private_data) {
+ pr_err("Null pointer passed in file->private_data");
+ return -EINVAL;
+ }
+
+ drvdata = file->private_data;
atomic_inc(&drvdata->available);
return 0;
@@ -374,6 +386,11 @@ static long qbt1000_ioctl(struct file *file, unsigned cmd, unsigned long arg)
void __user *priv_arg = (void __user *)arg;
struct qbt1000_drvdata *drvdata;
+ if (!file->private_data) {
+ pr_err("Null pointer passed in file->private_data");
+ return -EINVAL;
+ }
+
drvdata = file->private_data;
if (IS_ERR(priv_arg)) {
@@ -789,6 +806,8 @@ static int qbt1000_create_input_device(struct qbt1000_drvdata *drvdata)
BIT_MASK(KEY_HOMEPAGE);
drvdata->in_dev->keybit[BIT_WORD(KEY_CAMERA)] |=
BIT_MASK(KEY_CAMERA);
+ drvdata->in_dev->keybit[BIT_WORD(KEY_VOLUMEDOWN)] |=
+ BIT_MASK(KEY_VOLUMEDOWN);
drvdata->in_dev->keybit[BIT_WORD(KEY_POWER)] |=
BIT_MASK(KEY_POWER);
@@ -917,11 +936,14 @@ static irqreturn_t qbt1000_gpio_isr(int irq, void *dev_id)
*/
static irqreturn_t qbt1000_ipc_irq_handler(int irq, void *dev_id)
{
+ uint8_t *msg_buffer;
struct fw_ipc_cmd *rx_cmd;
- int i;
+ struct fw_ipc_header *header;
+ int i, j;
uint32_t rxipc = FP_APP_CMD_RX_IPC;
struct qbt1000_drvdata *drvdata = (struct qbt1000_drvdata *)dev_id;
int rc = 0;
+ uint32_t retry_count = 10;
pm_stay_awake(drvdata->dev);
@@ -933,18 +955,25 @@ static irqreturn_t qbt1000_ipc_irq_handler(int irq, void *dev_id)
goto end;
}
- pr_debug("firmware interrupt received (irq %d)\n", irq);
-
if (!drvdata->fp_app_handle)
goto end;
- /*
- * send the TZ command to fetch the message from firmware
- * TZ will process the message if it can
- */
- rc = send_tz_cmd(drvdata, drvdata->fp_app_handle, 0,
- &rxipc, sizeof(rxipc),
- (void *)&rx_cmd, sizeof(*rx_cmd));
+ while (retry_count > 0) {
+ /*
+ * send the TZ command to fetch the message from firmware
+ * TZ will process the message if it can
+ */
+ rc = send_tz_cmd(drvdata, drvdata->fp_app_handle, 0,
+ &rxipc, sizeof(rxipc),
+ (void *)&rx_cmd, sizeof(*rx_cmd));
+ if (rc < 0) {
+ msleep(50); /* sleep for 50ms before retry */
+ retry_count -= 1;
+ continue;
+ } else {
+ break;
+ }
+ }
if (rc < 0) {
pr_err("failure sending tz cmd %d\n", rxipc);
@@ -956,29 +985,35 @@ static irqreturn_t qbt1000_ipc_irq_handler(int irq, void *dev_id)
goto end;
}
- /*
- * given the IPC message type, search for a corresponding event for the
- * driver client. If found, add to the events FIFO
- */
- for (i = 0; i < ARRAY_SIZE(g_msg_to_event); i++) {
- if (g_msg_to_event[i].msg_type == rx_cmd->msg_type) {
- enum qbt1000_fw_event ev = g_msg_to_event[i].fw_event;
- struct fw_event_desc fw_ev_desc;
-
- mutex_lock(&drvdata->fw_events_mutex);
- pr_debug("fw events: add %d\n", (int) ev);
- fw_ev_desc.ev = ev;
-
- if (!kfifo_put(&drvdata->fw_events, fw_ev_desc))
- pr_err("fw events: fifo full, drop event %d\n",
- (int) ev);
-
- mutex_unlock(&drvdata->fw_events_mutex);
- wake_up_interruptible(&drvdata->read_wait_queue);
- break;
+ msg_buffer = rx_cmd->msg_data;
+
+ for (j = 0; j < rx_cmd->numMsgs; j++) {
+ header = (struct fw_ipc_header *) msg_buffer;
+ /*
+ * given the IPC message type, search for a corresponding event
+ * for the driver client. If found, add to the events FIFO
+ */
+ for (i = 0; i < ARRAY_SIZE(g_msg_to_event); i++) {
+ if (g_msg_to_event[i].msg_type == header->msg_type) {
+ enum qbt1000_fw_event ev =
+ g_msg_to_event[i].fw_event;
+ struct fw_event_desc fw_ev_desc;
+
+ mutex_lock(&drvdata->fw_events_mutex);
+ pr_debug("fw events: add %d\n", (int) ev);
+ fw_ev_desc.ev = ev;
+
+ if (!kfifo_put(&drvdata->fw_events, fw_ev_desc))
+ pr_err("fw events: fifo full, drop event %d\n",
+ (int) ev);
+
+ mutex_unlock(&drvdata->fw_events_mutex);
+ break;
+ }
}
+ msg_buffer += sizeof(*header) + header->msg_len;
}
-
+ wake_up_interruptible(&drvdata->read_wait_queue);
end:
mutex_unlock(&drvdata->mutex);
pm_relax(drvdata->dev);
diff --git a/drivers/soc/qcom/scm_qcpe.c b/drivers/soc/qcom/scm_qcpe.c
index 0263350ae931..1e369c73e34b 100644
--- a/drivers/soc/qcom/scm_qcpe.c
+++ b/drivers/soc/qcom/scm_qcpe.c
@@ -27,7 +27,7 @@
#define CREATE_TRACE_POINTS
#include <trace/events/scm.h>
-#include <uapi/linux/habmm.h>
+#include <linux/habmm.h>
#define SCM_ENOMEM (-5)
#define SCM_EOPNOTSUPP (-4)
@@ -218,7 +218,7 @@ static int scm_call_qcpe(u32 fn_id, struct scm_desc *desc)
if (!opened) {
ret = habmm_socket_open(&handle, MM_QCPE_VM1, 0, 0);
- if (ret != HAB_OK) {
+ if (ret) {
pr_err("scm_call_qcpe: habmm_socket_open failed with ret = %d",
ret);
return ret;
@@ -235,14 +235,14 @@ static int scm_call_qcpe(u32 fn_id, struct scm_desc *desc)
smc_params.sid = 0;
ret = habmm_socket_send(handle, &smc_params, sizeof(smc_params), 0);
- if (ret != HAB_OK)
+ if (ret)
return ret;
size_bytes = sizeof(smc_params);
memset(&smc_params, 0x0, sizeof(smc_params));
ret = habmm_socket_recv(handle, &smc_params, &size_bytes, 0, 0);
- if (ret != HAB_OK)
+ if (ret)
return ret;
if (size_bytes != sizeof(smc_params)) {
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 70db070b05d8..224602e95299 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -2898,7 +2898,7 @@ static int dwc3_msm_probe(struct platform_device *pdev)
ret = dwc3_msm_get_clk_gdsc(mdwc);
if (ret) {
dev_err(&pdev->dev, "error getting clock or gdsc.\n");
- return ret;
+ goto err;
}
mdwc->id_state = DWC3_ID_FLOAT;
@@ -3206,19 +3206,14 @@ static int dwc3_msm_probe(struct platform_device *pdev)
return 0;
put_dwc3:
- platform_device_put(mdwc->dwc3);
if (mdwc->bus_perf_client)
msm_bus_scale_unregister_client(mdwc->bus_perf_client);
+ of_platform_depopulate(&pdev->dev);
err:
+ destroy_workqueue(mdwc->dwc3_wq);
return ret;
}
-static int dwc3_msm_remove_children(struct device *dev, void *data)
-{
- device_unregister(dev);
- return 0;
-}
-
static int dwc3_msm_remove(struct platform_device *pdev)
{
struct dwc3_msm *mdwc = platform_get_drvdata(pdev);
@@ -3255,8 +3250,7 @@ static int dwc3_msm_remove(struct platform_device *pdev)
if (mdwc->hs_phy)
mdwc->hs_phy->flags &= ~PHY_HOST_MODE;
- platform_device_put(mdwc->dwc3);
- device_for_each_child(&pdev->dev, NULL, dwc3_msm_remove_children);
+ of_platform_depopulate(&pdev->dev);
dbg_event(0xFF, "Remov put", 0);
pm_runtime_disable(mdwc->dev);
@@ -3702,7 +3696,7 @@ static int dwc3_msm_gadget_vbus_draw(struct dwc3_msm *mdwc, unsigned mA)
}
ret = power_supply_set_property(mdwc->usb_psy,
- POWER_SUPPLY_PROP_CURRENT_MAX, &pval);
+ POWER_SUPPLY_PROP_SDP_CURRENT_MAX, &pval);
if (ret) {
dev_dbg(mdwc->dev, "power supply error when setting property\n");
return ret;
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index 0cbe95304417..202d417e1dde 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -481,15 +481,15 @@ static inline void pd_reset_protocol(struct usbpd *pd)
pd->send_dr_swap = false;
}
-static int pd_send_msg(struct usbpd *pd, u8 hdr_type, const u32 *data,
- size_t num_data, enum pd_msg_type type)
+static int pd_send_msg(struct usbpd *pd, u8 msg_type, const u32 *data,
+ size_t num_data, enum pd_sop_type sop)
{
int ret;
u16 hdr;
- hdr = PD_MSG_HDR(hdr_type, pd->current_dr, pd->current_pr,
+ hdr = PD_MSG_HDR(msg_type, pd->current_dr, pd->current_pr,
pd->tx_msgid, num_data, pd->spec_rev);
- ret = pd_phy_write(hdr, (u8 *)data, num_data * sizeof(u32), type, 15);
+ ret = pd_phy_write(hdr, (u8 *)data, num_data * sizeof(u32), sop, 15);
/* TODO figure out timeout. based on tReceive=1.1ms x nRetryCount? */
if (ret < 0)
@@ -612,12 +612,12 @@ static void kick_sm(struct usbpd *pd, int ms)
queue_work(pd->wq, &pd->sm_work);
}
-static void phy_sig_received(struct usbpd *pd, enum pd_sig_type type)
+static void phy_sig_received(struct usbpd *pd, enum pd_sig_type sig)
{
union power_supply_propval val = {1};
- if (type != HARD_RESET_SIG) {
- usbpd_err(&pd->dev, "invalid signal (%d) received\n", type);
+ if (sig != HARD_RESET_SIG) {
+ usbpd_err(&pd->dev, "invalid signal (%d) received\n", sig);
return;
}
@@ -632,16 +632,16 @@ static void phy_sig_received(struct usbpd *pd, enum pd_sig_type type)
kick_sm(pd, 0);
}
-static void phy_msg_received(struct usbpd *pd, enum pd_msg_type type,
+static void phy_msg_received(struct usbpd *pd, enum pd_sop_type sop,
u8 *buf, size_t len)
{
struct rx_msg *rx_msg;
unsigned long flags;
u16 header;
- if (type != SOP_MSG) {
+ if (sop != SOP_MSG) {
usbpd_err(&pd->dev, "invalid msg type (%d) received; only SOP supported\n",
- type);
+ sop);
return;
}
@@ -964,7 +964,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
pd->current_voltage = pd->requested_voltage = 5000000;
val.intval = pd->requested_voltage; /* set max range to 5V */
power_supply_set_property(pd->usb_psy,
- POWER_SUPPLY_PROP_VOLTAGE_MAX, &val);
+ POWER_SUPPLY_PROP_PD_VOLTAGE_MAX, &val);
if (!pd->vbus_present) {
pd->current_state = PE_SNK_DISCOVERY;
@@ -1663,7 +1663,7 @@ static void usbpd_sm(struct work_struct *w)
pd->requested_voltage = 5000000;
val.intval = pd->requested_voltage;
power_supply_set_property(pd->usb_psy,
- POWER_SUPPLY_PROP_VOLTAGE_MIN, &val);
+ POWER_SUPPLY_PROP_PD_VOLTAGE_MIN, &val);
pd->in_pr_swap = false;
val.intval = 0;
@@ -1982,8 +1982,8 @@ static void usbpd_sm(struct work_struct *w)
val.intval = pd->requested_voltage;
power_supply_set_property(pd->usb_psy,
pd->requested_voltage >= pd->current_voltage ?
- POWER_SUPPLY_PROP_VOLTAGE_MAX :
- POWER_SUPPLY_PROP_VOLTAGE_MIN,
+ POWER_SUPPLY_PROP_PD_VOLTAGE_MAX :
+ POWER_SUPPLY_PROP_PD_VOLTAGE_MIN,
&val);
/*
@@ -2034,8 +2034,8 @@ static void usbpd_sm(struct work_struct *w)
val.intval = pd->requested_voltage;
power_supply_set_property(pd->usb_psy,
pd->requested_voltage >= pd->current_voltage ?
- POWER_SUPPLY_PROP_VOLTAGE_MIN :
- POWER_SUPPLY_PROP_VOLTAGE_MAX, &val);
+ POWER_SUPPLY_PROP_PD_VOLTAGE_MIN :
+ POWER_SUPPLY_PROP_PD_VOLTAGE_MAX, &val);
pd->current_voltage = pd->requested_voltage;
/* resume charging */
@@ -2217,7 +2217,7 @@ static void usbpd_sm(struct work_struct *w)
val.intval = pd->requested_voltage;
power_supply_set_property(pd->usb_psy,
- POWER_SUPPLY_PROP_VOLTAGE_MIN, &val);
+ POWER_SUPPLY_PROP_PD_VOLTAGE_MIN, &val);
pd_send_hard_reset(pd);
pd->in_explicit_contract = false;
diff --git a/drivers/usb/pd/qpnp-pdphy.c b/drivers/usb/pd/qpnp-pdphy.c
index e200c25bc23a..f30261e543ba 100644
--- a/drivers/usb/pd/qpnp-pdphy.c
+++ b/drivers/usb/pd/qpnp-pdphy.c
@@ -96,8 +96,8 @@ struct usb_pdphy {
int msg_tx_discarded_irq;
int msg_rx_discarded_irq;
- void (*signal_cb)(struct usbpd *pd, enum pd_sig_type type);
- void (*msg_rx_cb)(struct usbpd *pd, enum pd_msg_type type,
+ void (*signal_cb)(struct usbpd *pd, enum pd_sig_type sig);
+ void (*msg_rx_cb)(struct usbpd *pd, enum pd_sop_type sop,
u8 *buf, size_t len);
void (*shutdown_cb)(struct usbpd *pd);
@@ -401,13 +401,13 @@ int pd_phy_open(struct pd_phy_params *params)
}
EXPORT_SYMBOL(pd_phy_open);
-int pd_phy_signal(enum pd_sig_type type, unsigned int timeout_ms)
+int pd_phy_signal(enum pd_sig_type sig, unsigned int timeout_ms)
{
u8 val;
int ret;
struct usb_pdphy *pdphy = __pdphy;
- dev_dbg(pdphy->dev, "%s: type %d timeout %u\n", __func__, type,
+ dev_dbg(pdphy->dev, "%s: type %d timeout %u\n", __func__, sig,
timeout_ms);
if (!pdphy) {
@@ -428,7 +428,7 @@ int pd_phy_signal(enum pd_sig_type type, unsigned int timeout_ms)
usleep_range(2, 3);
- val = (type == CABLE_RESET_SIG ? TX_CONTROL_FRAME_TYPE_CABLE_RESET : 0)
+ val = (sig == CABLE_RESET_SIG ? TX_CONTROL_FRAME_TYPE_CABLE_RESET : 0)
| TX_CONTROL_SEND_SIGNAL;
ret = pdphy_reg_write(pdphy, USB_PDPHY_TX_CONTROL, val);
@@ -447,7 +447,7 @@ int pd_phy_signal(enum pd_sig_type type, unsigned int timeout_ms)
if (pdphy->tx_status)
return pdphy->tx_status;
- if (type == HARD_RESET_SIG)
+ if (sig == HARD_RESET_SIG)
/* Frame filter is reconfigured in pd_phy_open() */
return pdphy_reg_write(pdphy, USB_PDPHY_FRAME_FILTER, 0);
@@ -456,15 +456,15 @@ int pd_phy_signal(enum pd_sig_type type, unsigned int timeout_ms)
EXPORT_SYMBOL(pd_phy_signal);
int pd_phy_write(u16 hdr, const u8 *data, size_t data_len,
- enum pd_msg_type type, unsigned int timeout_ms)
+ enum pd_sop_type sop, unsigned int timeout_ms)
{
u8 val;
int ret;
size_t total_len = data_len + USB_PDPHY_MSG_HDR_LEN;
struct usb_pdphy *pdphy = __pdphy;
- dev_dbg(pdphy->dev, "%s: hdr %x frame type %d timeout %u\n",
- __func__, hdr, type, timeout_ms);
+ dev_dbg(pdphy->dev, "%s: hdr %x frame sop_type %d timeout %u\n",
+ __func__, hdr, sop, timeout_ms);
if (data && data_len)
print_hex_dump_debug("tx data obj:", DUMP_PREFIX_NONE, 32, 4,
@@ -518,7 +518,7 @@ int pd_phy_write(u16 hdr, const u8 *data, size_t data_len,
usleep_range(2, 3);
- val = TX_CONTROL_RETRY_COUNT | (type << 2) | TX_CONTROL_SEND_MSG;
+ val = TX_CONTROL_RETRY_COUNT | (sop << 2) | TX_CONTROL_SEND_MSG;
ret = pdphy_reg_write(pdphy, USB_PDPHY_TX_CONTROL, val);
if (ret)
diff --git a/drivers/usb/pd/usbpd.h b/drivers/usb/pd/usbpd.h
index 108701739f89..6b323e238aad 100644
--- a/drivers/usb/pd/usbpd.h
+++ b/drivers/usb/pd/usbpd.h
@@ -45,7 +45,7 @@ enum pd_sig_type {
CABLE_RESET_SIG,
};
-enum pd_msg_type {
+enum pd_sop_type {
SOP_MSG = 0,
SOPI_MSG,
SOPII_MSG,
@@ -61,8 +61,8 @@ enum pd_spec_rev {
#define FRAME_FILTER_EN_HARD_RESET BIT(5)
struct pd_phy_params {
- void (*signal_cb)(struct usbpd *pd, enum pd_sig_type type);
- void (*msg_rx_cb)(struct usbpd *pd, enum pd_msg_type type,
+ void (*signal_cb)(struct usbpd *pd, enum pd_sig_type sig);
+ void (*msg_rx_cb)(struct usbpd *pd, enum pd_sop_type sop,
u8 *buf, size_t len);
void (*shutdown_cb)(struct usbpd *pd);
enum data_role data_role;
@@ -72,9 +72,9 @@ struct pd_phy_params {
#if IS_ENABLED(CONFIG_QPNP_USB_PDPHY)
int pd_phy_open(struct pd_phy_params *params);
-int pd_phy_signal(enum pd_sig_type type, unsigned int timeout_ms);
+int pd_phy_signal(enum pd_sig_type sig, unsigned int timeout_ms);
int pd_phy_write(u16 hdr, const u8 *data, size_t data_len,
- enum pd_msg_type type, unsigned int timeout_ms);
+ enum pd_sop_type sop, unsigned int timeout_ms);
int pd_phy_update_roles(enum data_role dr, enum power_role pr);
void pd_phy_close(void);
#else
@@ -89,7 +89,7 @@ static inline int pd_phy_signal(enum pd_sig_type type, unsigned int timeout_ms)
}
static inline int pd_phy_write(u16 hdr, const u8 *data, size_t data_len,
- enum pd_msg_type type, unsigned int timeout_ms)
+ enum pd_sop_type sop, unsigned int timeout_ms)
{
return -ENODEV;
}
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
index bda93bf0558a..837147dc5036 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
@@ -2179,6 +2179,7 @@ static int hdmi_tx_read_sink_info(struct hdmi_tx_ctrl *hdmi_ctrl)
int status = 0;
void *data;
struct dss_io_data *io;
+ u32 sink_max_pclk;
if (!hdmi_ctrl) {
DEV_ERR("%s: invalid input\n", __func__);
@@ -2218,16 +2219,22 @@ static int hdmi_tx_read_sink_info(struct hdmi_tx_ctrl *hdmi_ctrl)
/* parse edid if a valid edid buffer is present */
if (hdmi_ctrl->custom_edid || !hdmi_ctrl->sim_mode) {
status = hdmi_edid_parser(data);
- if (status)
+ if (status) {
DEV_ERR("%s: edid parse failed\n", __func__);
- else
+ } else {
/*
- * Updata HDMI max supported TMDS clock, consider
- * both sink and source capicity.
+ * Update HDMI max supported TMDS clock, consider
+ * both sink and source capacity. For DVI sink,
+ * could not get max TMDS clock from EDID, so just
+ * use source capacity.
*/
- hdmi_edid_set_max_pclk_rate(data,
- min(hdmi_edid_get_sink_caps_max_tmds_clk(data) / 1000,
- hdmi_ctrl->max_pclk_khz));
+ sink_max_pclk =
+ hdmi_edid_get_sink_caps_max_tmds_clk(data);
+ if (sink_max_pclk != 0)
+ hdmi_edid_set_max_pclk_rate(data,
+ min(sink_max_pclk / 1000,
+ hdmi_ctrl->max_pclk_khz));
+ }
}
bail:
if (hdmi_tx_enable_power(hdmi_ctrl, HDMI_TX_DDC_PM, false))
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 93efe2b916ea..982b93ccfbe4 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -252,6 +252,9 @@ enum power_supply_property {
POWER_SUPPLY_PROP_CC_STEP,
POWER_SUPPLY_PROP_CC_STEP_SEL,
POWER_SUPPLY_PROP_SW_JEITA_ENABLED,
+ POWER_SUPPLY_PROP_PD_VOLTAGE_MAX,
+ POWER_SUPPLY_PROP_PD_VOLTAGE_MIN,
+ POWER_SUPPLY_PROP_SDP_CURRENT_MAX,
/* Local extensions of type int64_t */
POWER_SUPPLY_PROP_CHARGE_COUNTER_EXT,
/* Properties of type `const char *' */
diff --git a/include/linux/qpnp/qpnp-revid.h b/include/linux/qpnp/qpnp-revid.h
index b025df568259..bbc4625a2d39 100644
--- a/include/linux/qpnp/qpnp-revid.h
+++ b/include/linux/qpnp/qpnp-revid.h
@@ -252,6 +252,7 @@ struct pmic_revid_data {
u8 pmic_subtype;
const char *pmic_name;
int fab_id;
+ int tp_rev;
};
#ifdef CONFIG_QPNP_REVID
diff --git a/include/linux/usb_bam.h b/include/linux/usb_bam.h
index e65fb12c1410..b5b9edaab783 100644
--- a/include/linux/usb_bam.h
+++ b/include/linux/usb_bam.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-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
@@ -191,7 +191,7 @@ struct usb_bam_pipe_connect {
};
/**
- * struct msm_usb_bam_platform_data: pipe connection information
+ * struct msm_usb_bam_data: pipe connection information
* between USB/HSIC BAM and another BAM. USB/HSIC BAM can be
* either src BAM or dst BAM
* @usb_bam_num_pipes: max number of pipes to use.
@@ -211,7 +211,7 @@ struct usb_bam_pipe_connect {
* can work at in bam2bam mode when connected to SS host.
* @enable_hsusb_bam_on_boot: Enable HSUSB BAM (non-NDP) on bootup itself
*/
-struct msm_usb_bam_platform_data {
+struct msm_usb_bam_data {
u8 max_connections;
int usb_bam_num_pipes;
phys_addr_t usb_bam_fifo_baseaddr;
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 2680a13721c2..21b30bf7c74c 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -4012,7 +4012,7 @@ struct asm_stream_pan_ctrl_params {
uint16_t num_input_channels;
uint16_t output_channel_map[8];
uint16_t input_channel_map[8];
- uint16_t gain[64];
+ uint32_t gain[64];
} __packed;
#define ASM_END_POINT_DEVICE_MATRIX 0
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index dcf7dcb4f6e4..2ff0a2b02d4a 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -99,7 +99,7 @@
#define SOFT_PAUSE_ENABLE 1
#define SOFT_PAUSE_DISABLE 0
-#define ASM_ACTIVE_STREAMS_ALLOWED 0x8
+#define ASM_ACTIVE_STREAMS_ALLOWED 0x9
/* Control session is used for mapping calibration memory */
#define ASM_CONTROL_SESSION (ASM_ACTIVE_STREAMS_ALLOWED + 1)
diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h
index 8b51873e7b08..a852f2a3701f 100644
--- a/include/uapi/drm/msm_drm.h
+++ b/include/uapi/drm/msm_drm.h
@@ -234,7 +234,7 @@ struct drm_msm_gem_submit_cmd {
__u32 size; /* in, cmdstream size */
__u32 pad;
__u32 nr_relocs; /* in, number of submit_reloc's */
- __u64 __user relocs; /* in, ptr to array of submit_reloc's */
+ __u64 relocs; /* in, ptr to array of submit_reloc's */
};
/* Each buffer referenced elsewhere in the cmdstream submit (ie. the
@@ -274,8 +274,8 @@ struct drm_msm_gem_submit {
__u32 fence; /* out */
__u32 nr_bos; /* in, number of submit_bo's */
__u32 nr_cmds; /* in, number of submit_cmd's */
- __u64 __user bos; /* in, ptr to array of submit_bo's */
- __u64 __user cmds; /* in, ptr to array of submit_cmd's */
+ __u64 bos; /* in, ptr to array of submit_bo's */
+ __u64 cmds; /* in, ptr to array of submit_cmd's */
__s32 fence_fd; /* gap for the fence_fd which is upstream */
__u32 queueid; /* in, submitqueue id */
};
diff --git a/include/uapi/sound/compress_offload.h b/include/uapi/sound/compress_offload.h
index 866ec3d2af69..7845fdd556fa 100644
--- a/include/uapi/sound/compress_offload.h
+++ b/include/uapi/sound/compress_offload.h
@@ -138,6 +138,11 @@ struct snd_compr_audio_info {
#define SNDRV_COMPRESS_CLK_REC_MODE_NONE 0
#define SNDRV_COMPRESS_CLK_REC_MODE_AUTO 1
+enum sndrv_compress_latency_mode {
+ SNDRV_COMPRESS_LEGACY_LATENCY_MODE = 0,
+ SNDRV_COMPRESS_LOW_LATENCY_MODE = 1,
+};
+
/**
* enum sndrv_compress_encoder
* @SNDRV_COMPRESS_ENCODER_PADDING: no of samples appended by the encoder at the
@@ -164,6 +169,7 @@ enum sndrv_compress_encoder {
SNDRV_COMPRESS_START_DELAY = 9,
SNDRV_COMPRESS_ENABLE_ADJUST_SESSION_CLOCK = 10,
SNDRV_COMPRESS_ADJUST_SESSION_CLOCK = 11,
+ SNDRV_COMPRESS_LATENCY_MODE = 12,
};
#define SNDRV_COMPRESS_PATH_DELAY SNDRV_COMPRESS_PATH_DELAY
@@ -174,6 +180,7 @@ enum sndrv_compress_encoder {
#define SNDRV_COMPRESS_ENABLE_ADJUST_SESSION_CLOCK \
SNDRV_COMPRESS_ENABLE_ADJUST_SESSION_CLOCK
#define SNDRV_COMPRESS_ADJUST_SESSION_CLOCK SNDRV_COMPRESS_ADJUST_SESSION_CLOCK
+#define SNDRV_COMPRESS_LATENCY_MODE SNDRV_COMPRESS_LATENCY_MODE
/**
* struct snd_compr_metadata - compressed stream metadata
diff --git a/sound/soc/codecs/wcd-dsp-mgr.c b/sound/soc/codecs/wcd-dsp-mgr.c
index 9b1c8c98946c..1613c5baa9c7 100644
--- a/sound/soc/codecs/wcd-dsp-mgr.c
+++ b/sound/soc/codecs/wcd-dsp-mgr.c
@@ -415,22 +415,24 @@ static int wdsp_download_segments(struct wdsp_mgr_priv *wdsp,
/* Go through the list of segments and download one by one */
list_for_each_entry(seg, wdsp->seg_list, list) {
ret = wdsp_load_each_segment(wdsp, seg);
- if (IS_ERR_VALUE(ret)) {
- wdsp_broadcast_event_downseq(wdsp,
- WDSP_EVENT_DLOAD_FAILED,
- NULL);
+ if (ret)
goto dload_error;
- }
}
+ /* Flush the list before setting status and notifying components */
+ wdsp_flush_segment_list(wdsp->seg_list);
+
WDSP_SET_STATUS(wdsp, status);
/* Notify all components that image is downloaded */
wdsp_broadcast_event_downseq(wdsp, post, NULL);
+done:
+ return ret;
dload_error:
wdsp_flush_segment_list(wdsp->seg_list);
-done:
+ wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_DLOAD_FAILED, NULL);
+
return ret;
}
@@ -484,10 +486,14 @@ static int wdsp_enable_dsp(struct wdsp_mgr_priv *wdsp)
/* Make sure wdsp is in good state */
if (!WDSP_STATUS_IS_SET(wdsp, WDSP_STATUS_CODE_DLOADED)) {
WDSP_ERR(wdsp, "WDSP in invalid state 0x%x", wdsp->status);
- ret = -EINVAL;
- goto done;
+ return -EINVAL;
}
+ /*
+ * Acquire SSR mutex lock to make sure enablement of DSP
+ * does not race with SSR handling.
+ */
+ WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex);
/* Download the read-write sections of image */
ret = wdsp_download_segments(wdsp, WDSP_ELF_FLAG_WRITE);
if (IS_ERR_VALUE(ret)) {
@@ -508,6 +514,7 @@ static int wdsp_enable_dsp(struct wdsp_mgr_priv *wdsp)
wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_POST_BOOTUP, NULL);
WDSP_SET_STATUS(wdsp, WDSP_STATUS_BOOTED);
done:
+ WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex);
return ret;
}
diff --git a/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c b/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c
index e791bf07ec67..29c218013a07 100644
--- a/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c
+++ b/sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c
@@ -763,10 +763,6 @@ static int wcd_control_handler(struct device *dev, void *priv_data,
case WDSP_EVENT_DLOAD_FAILED:
case WDSP_EVENT_POST_SHUTDOWN:
- if (event == WDSP_EVENT_POST_DLOAD_CODE)
- /* Mark DSP online since code download is complete */
- wcd_cntl_change_online_state(cntl, 1);
-
/* Disable CPAR */
wcd_cntl_cpar_ctrl(cntl, false);
/* Disable all the clocks */
@@ -775,6 +771,11 @@ static int wcd_control_handler(struct device *dev, void *priv_data,
dev_err(codec->dev,
"%s: Failed to disable clocks, err = %d\n",
__func__, ret);
+
+ if (event == WDSP_EVENT_POST_DLOAD_CODE)
+ /* Mark DSP online since code download is complete */
+ wcd_cntl_change_online_state(cntl, 1);
+
break;
case WDSP_EVENT_PRE_DLOAD_DATA:
diff --git a/sound/soc/msm/msm8998.c b/sound/soc/msm/msm8998.c
index b8bd32e046a3..9159ea642816 100644
--- a/sound/soc/msm/msm8998.c
+++ b/sound/soc/msm/msm8998.c
@@ -434,7 +434,8 @@ static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32",
static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"};
static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16",
"KHZ_32", "KHZ_44P1", "KHZ_48",
- "KHZ_96", "KHZ_192"};
+ "KHZ_88P2", "KHZ_96", "KHZ_176P4",
+ "KHZ_192"};
static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four",
"Five", "Six", "Seven",
"Eight"};
@@ -2228,12 +2229,18 @@ static int mi2s_get_sample_rate_val(int sample_rate)
case SAMPLING_RATE_48KHZ:
sample_rate_val = 4;
break;
- case SAMPLING_RATE_96KHZ:
+ case SAMPLING_RATE_88P2KHZ:
sample_rate_val = 5;
break;
- case SAMPLING_RATE_192KHZ:
+ case SAMPLING_RATE_96KHZ:
sample_rate_val = 6;
break;
+ case SAMPLING_RATE_176P4KHZ:
+ sample_rate_val = 7;
+ break;
+ case SAMPLING_RATE_192KHZ:
+ sample_rate_val = 8;
+ break;
default:
sample_rate_val = 4;
break;
@@ -2262,9 +2269,15 @@ static int mi2s_get_sample_rate(int value)
sample_rate = SAMPLING_RATE_48KHZ;
break;
case 5:
- sample_rate = SAMPLING_RATE_96KHZ;
+ sample_rate = SAMPLING_RATE_88P2KHZ;
break;
case 6:
+ sample_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 7:
+ sample_rate = SAMPLING_RATE_176P4KHZ;
+ break;
+ case 8:
sample_rate = SAMPLING_RATE_192KHZ;
break;
default:
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index 3610901addea..292b3d04f7d5 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -4152,7 +4152,8 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = {
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
+ SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
SNDRV_PCM_RATE_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rate_min = 8000,
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index de769e8b806c..b94eb6fbfeea 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -1668,7 +1668,7 @@ static int msm_pcm_playback_pan_scale_ctl_put(struct snd_kcontrol *kcontrol,
for (i = 0; i < pan_param.num_output_channels *
pan_param.num_input_channels; i++) {
pan_param.gain[i] =
- !(ucontrol->value.integer.value[len++] > 0) ?
+ !(ucontrol->value.integer.value[len++] > 0) ?
0 : 2 << 13;
}
}
@@ -1679,8 +1679,12 @@ static int msm_pcm_playback_pan_scale_ctl_put(struct snd_kcontrol *kcontrol,
pan_param.num_input_channels;
for (i = 0; i < pan_param.num_output_channels *
pan_param.num_input_channels; i++) {
+ /*
+ * The data userspace passes is already in Q14 format.
+ * For volume gain is in Q28.
+ */
pan_param.gain[i] =
- ucontrol->value.integer.value[len++];
+ ucontrol->value.integer.value[len++] << 14;
}
ret = q6asm_set_vol_ctrl_gain_pair(prtd->audio_client,
&pan_param);
@@ -1753,7 +1757,7 @@ static int msm_pcm_playback_dnmix_ctl_put(struct snd_kcontrol *kcontrol,
struct msm_audio *prtd;
struct asm_stream_pan_ctrl_params dnmix_param;
- int be_id = ucontrol->value.integer.value[len];
+ int be_id = ucontrol->value.integer.value[len++];
int stream_id = 0;
if (!usr_info) {
@@ -1809,7 +1813,7 @@ static int msm_pcm_playback_dnmix_ctl_put(struct snd_kcontrol *kcontrol,
for (i = 0; i < dnmix_param.num_output_channels *
dnmix_param.num_input_channels; i++) {
dnmix_param.gain[i] =
- ucontrol->value.integer.value[len++];
+ ucontrol->value.integer.value[len++];
}
}
msm_routing_set_downmix_control_data(be_id,
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 38937612dcce..9e2e8b37ec10 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -16201,6 +16201,8 @@ int msm_routing_set_downmix_control_data(int be_id, int session_id,
char *adm_params = NULL;
int port_id, copp_idx = 0;
uint32_t params_length = 0;
+ uint16_t ii;
+ uint16_t *dst_gain_ptr = NULL;
if (be_id >= MSM_BACKEND_DAI_MAX) {
rc = -EINVAL;
@@ -16213,7 +16215,7 @@ int msm_routing_set_downmix_control_data(int be_id, int session_id,
variable_payload = dnmix_param->num_output_channels * sizeof(uint16_t)+
dnmix_param->num_input_channels * sizeof(uint16_t) +
- dnmix_param->num_output_channels * sizeof(uint16_t) *
+ dnmix_param->num_output_channels *
dnmix_param->num_input_channels * sizeof(uint16_t);
i = (variable_payload % sizeof(uint32_t));
variable_payload += (i == 0) ? 0 : sizeof(uint32_t) - i;
@@ -16252,14 +16254,15 @@ int msm_routing_set_downmix_control_data(int be_id, int session_id,
dnmix_param->num_output_channels * sizeof(uint16_t)),
dnmix_param->input_channel_map,
dnmix_param->num_input_channels * sizeof(uint16_t));
- memcpy(((u8 *)adm_params +
+
+ dst_gain_ptr = (uint16_t *) ((u8 *)adm_params +
sizeof(struct adm_pspd_param_data_t) +
sizeof(struct audproc_chmixer_param_coeff) +
(dnmix_param->num_output_channels * sizeof(uint16_t)) +
- (dnmix_param->num_input_channels * sizeof(uint16_t))),
- dnmix_param->gain,
- (dnmix_param->num_output_channels * sizeof(uint16_t)) *
(dnmix_param->num_input_channels * sizeof(uint16_t)));
+ for (ii = 0; ii < dnmix_param->num_output_channels *
+ dnmix_param->num_input_channels; ii++)
+ dst_gain_ptr[ii] = (uint16_t) dnmix_param->gain[ii];
if (params_length) {
rc = adm_set_pspd_matrix_params(port_id,
diff --git a/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c
index a75de6d1d7c0..fdeb8a15ffee 100644
--- a/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c
@@ -28,6 +28,7 @@
#include <sound/control.h>
#include <sound/q6asm-v2.h>
#include <sound/q6core.h>
+#include <sound/q6audio-v2.h>
#include <sound/pcm_params.h>
#include <sound/timer.h>
#include <sound/tlv.h>
@@ -41,12 +42,21 @@
#include "msm-qti-pp-config.h"
#define LOOPBACK_SESSION_MAX_NUM_STREAMS 2
+/* Max volume corresponding to 24dB */
+#define TRANSCODE_LR_VOL_MAX_STEPS 0xFFFF
+
+#define APP_TYPE_CONFIG_IDX_APP_TYPE 0
+#define APP_TYPE_CONFIG_IDX_ACDB_ID 1
+#define APP_TYPE_CONFIG_IDX_SAMPLE_RATE 2
+#define APP_TYPE_CONFIG_IDX_BE_ID 3
static DEFINE_MUTEX(transcode_loopback_session_lock);
struct trans_loopback_pdata {
struct snd_compr_stream *cstream[MSM_FRONTEND_DAI_MAX];
int32_t ion_fd[MSM_FRONTEND_DAI_MAX];
+ uint32_t master_gain;
+ int perf_mode;
};
struct loopback_stream {
@@ -398,6 +408,8 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream,
struct msm_transcode_loopback *trans = runtime->private_data;
struct snd_soc_pcm_runtime *soc_pcm_rx;
struct snd_soc_pcm_runtime *soc_pcm_tx;
+ struct snd_soc_pcm_runtime *rtd;
+ struct trans_loopback_pdata *pdata;
uint32_t bit_width = 16;
int ret = 0;
@@ -408,6 +420,9 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream,
mutex_lock(&trans->lock);
+ rtd = snd_pcm_substream_chip(cstream);
+ pdata = snd_soc_platform_get_drvdata(rtd->platform);
+
if (cstream->direction == SND_COMPRESS_PLAYBACK) {
if (codec_param->codec.id == SND_AUDIOCODEC_PCM) {
trans->sink.codec_format =
@@ -489,7 +504,7 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream,
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;
+ trans->audio_client->perf_mode = pdata->perf_mode;
ret = q6asm_open_transcode_loopback(trans->audio_client,
bit_width,
trans->source.codec_format,
@@ -508,7 +523,7 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream,
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,
+ false,
trans->session_id,
SNDRV_PCM_STREAM_CAPTURE,
COMPRESSED_PASSTHROUGH_GEN);
@@ -521,7 +536,7 @@ static int msm_transcode_loopback_set_params(struct snd_compr_stream *cstream,
/* Opening Rx ADM in LOW_LATENCY mode by default */
msm_pcm_routing_reg_phy_stream(
soc_pcm_rx->dai_link->be_id,
- true,
+ trans->audio_client->perf_mode,
trans->session_id,
SNDRV_PCM_STREAM_PLAYBACK);
pr_debug("%s: Successfully opened ADM sessions\n", __func__);
@@ -554,6 +569,46 @@ static int msm_transcode_loopback_get_caps(struct snd_compr_stream *cstream,
return 0;
}
+static int msm_transcode_loopback_set_metadata(struct snd_compr_stream *cstream,
+ struct snd_compr_metadata *metadata)
+{
+ struct snd_soc_pcm_runtime *rtd;
+ struct trans_loopback_pdata *pdata;
+
+ if (!metadata || !cstream) {
+ pr_err("%s: Invalid arguments\n", __func__);
+ return -EINVAL;
+ }
+
+ rtd = snd_pcm_substream_chip(cstream);
+ pdata = snd_soc_platform_get_drvdata(rtd->platform);
+
+ switch (metadata->key) {
+ case SNDRV_COMPRESS_LATENCY_MODE:
+ {
+ switch (metadata->value[0]) {
+ case SNDRV_COMPRESS_LEGACY_LATENCY_MODE:
+ pdata->perf_mode = LEGACY_PCM_MODE;
+ break;
+ case SNDRV_COMPRESS_LOW_LATENCY_MODE:
+ pdata->perf_mode = LOW_LATENCY_PCM_MODE;
+ break;
+ default:
+ pr_debug("%s: Unsupported latency mode %d, default to Legacy\n",
+ __func__, metadata->value[0]);
+ pdata->perf_mode = LEGACY_PCM_MODE;
+ break;
+ }
+ }
+ break;
+ default:
+ pr_debug("%s: Unsupported metadata %d\n",
+ __func__, metadata->key);
+ break;
+ }
+ return 0;
+}
+
static int msm_transcode_stream_cmd_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -747,6 +802,141 @@ done:
return ret;
}
+static int msm_transcode_playback_app_type_cfg_put(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u64 fe_id = kcontrol->private_value;
+ int session_type = SESSION_TYPE_RX;
+ int be_id = ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_BE_ID];
+ struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000};
+ int ret = 0;
+
+ cfg_data.app_type = ucontrol->value.integer.value[
+ APP_TYPE_CONFIG_IDX_APP_TYPE];
+ cfg_data.acdb_dev_id = ucontrol->value.integer.value[
+ APP_TYPE_CONFIG_IDX_ACDB_ID];
+ if (ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_SAMPLE_RATE] != 0)
+ cfg_data.sample_rate = ucontrol->value.integer.value[
+ APP_TYPE_CONFIG_IDX_SAMPLE_RATE];
+ pr_debug("%s: fe_id %llu session_type %d be_id %d app_type %d acdb_dev_id %d sample_rate- %d\n",
+ __func__, fe_id, session_type, be_id,
+ cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate);
+ ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type,
+ be_id, &cfg_data);
+ if (ret < 0)
+ pr_err("%s: msm_transcode_playback_stream_app_type_cfg set failed returned %d\n",
+ __func__, ret);
+
+ return ret;
+}
+
+static int msm_transcode_playback_app_type_cfg_get(
+ struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u64 fe_id = kcontrol->private_value;
+ int session_type = SESSION_TYPE_RX;
+ int be_id = 0;
+ struct msm_pcm_stream_app_type_cfg cfg_data = {0};
+ int ret = 0;
+
+ ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type,
+ &be_id, &cfg_data);
+ if (ret < 0) {
+ pr_err("%s: msm_transcode_playback_stream_app_type_cfg get failed returned %d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_APP_TYPE] =
+ cfg_data.app_type;
+ ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_ACDB_ID] =
+ cfg_data.acdb_dev_id;
+ ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_SAMPLE_RATE] =
+ cfg_data.sample_rate;
+ ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_BE_ID] = be_id;
+ pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n",
+ __func__, fe_id, session_type, be_id,
+ cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate);
+done:
+ return ret;
+}
+
+static int msm_transcode_set_volume(struct snd_compr_stream *cstream,
+ uint32_t master_gain)
+{
+ int rc = 0;
+ struct msm_transcode_loopback *prtd;
+ struct snd_soc_pcm_runtime *rtd;
+
+ pr_debug("%s: master_gain %d\n", __func__, master_gain);
+ if (!cstream || !cstream->runtime) {
+ pr_err("%s: session not active\n", __func__);
+ return -EPERM;
+ }
+ rtd = cstream->private_data;
+ prtd = cstream->runtime->private_data;
+
+ if (!rtd || !rtd->platform || !prtd || !prtd->audio_client) {
+ pr_err("%s: invalid rtd, prtd or audio client", __func__);
+ return -EINVAL;
+ }
+
+ rc = q6asm_set_volume(prtd->audio_client, master_gain);
+ if (rc < 0)
+ pr_err("%s: Send vol gain command failed rc=%d\n",
+ __func__, rc);
+
+ return rc;
+}
+
+static int msm_transcode_volume_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;
+ uint32_t ret = 0;
+
+ if (fe_id >= MSM_FRONTEND_DAI_MAX) {
+ pr_err("%s Received out of bounds fe_id %lu\n",
+ __func__, fe_id);
+ return -EINVAL;
+ }
+
+ cstream = pdata->cstream[fe_id];
+ pdata->master_gain = ucontrol->value.integer.value[0];
+
+ pr_debug("%s: fe_id %lu master_gain %d\n",
+ __func__, fe_id, pdata->master_gain);
+ if (cstream)
+ ret = msm_transcode_set_volume(cstream, pdata->master_gain);
+ return ret;
+}
+
+static int msm_transcode_volume_get(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);
+
+ if (fe_id >= MSM_FRONTEND_DAI_MAX) {
+ pr_err("%s Received out of bound fe_id %lu\n", __func__, fe_id);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: fe_id %lu\n", __func__, fe_id);
+ ucontrol->value.integer.value[0] = pdata->master_gain;
+
+ return 0;
+}
+
static int msm_transcode_stream_cmd_control(
struct snd_soc_pcm_runtime *rtd)
{
@@ -995,6 +1185,99 @@ done:
return ret;
}
+static int msm_transcode_app_type_cfg_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 5;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 0xFFFFFFFF;
+ return 0;
+}
+
+static int msm_transcode_add_app_type_cfg_control(
+ struct snd_soc_pcm_runtime *rtd)
+{
+ char mixer_str[32];
+ int rc = 0;
+ struct snd_kcontrol_new fe_app_type_cfg_control[1] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = msm_transcode_app_type_cfg_info,
+ .put = msm_transcode_playback_app_type_cfg_put,
+ .get = msm_transcode_playback_app_type_cfg_get,
+ .private_value = 0,
+ }
+ };
+
+ if (!rtd) {
+ pr_err("%s NULL rtd\n", __func__);
+
+ return -EINVAL;
+ }
+
+ if (rtd->compr->direction == SND_COMPRESS_PLAYBACK) {
+
+ snprintf(mixer_str, sizeof(mixer_str),
+ "Audio Stream %d App Type Cfg",
+ rtd->pcm->device);
+
+ fe_app_type_cfg_control[0].name = mixer_str;
+ fe_app_type_cfg_control[0].private_value = rtd->dai_link->be_id;
+
+ fe_app_type_cfg_control[0].put =
+ msm_transcode_playback_app_type_cfg_put;
+ fe_app_type_cfg_control[0].get =
+ msm_transcode_playback_app_type_cfg_get;
+
+ pr_debug("Registering new mixer ctl %s", mixer_str);
+ snd_soc_add_platform_controls(rtd->platform,
+ fe_app_type_cfg_control,
+ ARRAY_SIZE(fe_app_type_cfg_control));
+ }
+
+ return rc;
+}
+static int msm_transcode_volume_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = TRANSCODE_LR_VOL_MAX_STEPS;
+ return 0;
+}
+
+static int msm_transcode_add_volume_control(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_kcontrol_new fe_volume_control[1] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Transcode Loopback Rx Volume",
+ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |
+ SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = msm_transcode_volume_info,
+ .get = msm_transcode_volume_get,
+ .put = msm_transcode_volume_put,
+ .private_value = 0,
+ }
+ };
+
+ if (!rtd) {
+ pr_err("%s NULL rtd\n", __func__);
+ return -EINVAL;
+ }
+ if (rtd->compr->direction == SND_COMPRESS_PLAYBACK) {
+ fe_volume_control[0].private_value = rtd->dai_link->be_id;
+ pr_debug("Registering new mixer ctl %s",
+ fe_volume_control[0].name);
+ snd_soc_add_platform_controls(rtd->platform, fe_volume_control,
+ ARRAY_SIZE(fe_volume_control));
+ }
+ return 0;
+}
+
static int msm_transcode_loopback_new(struct snd_soc_pcm_runtime *rtd)
{
int rc;
@@ -1023,6 +1306,16 @@ static int msm_transcode_loopback_new(struct snd_soc_pcm_runtime *rtd)
pr_err("%s: Could not add transcode event ack Control\n",
__func__);
+ rc = msm_transcode_add_app_type_cfg_control(rtd);
+ if (rc)
+ pr_err("%s: Could not add Compr App Type Cfg Control\n",
+ __func__);
+
+ rc = msm_transcode_add_volume_control(rtd);
+ if (rc)
+ pr_err("%s: Could not add transcode volume Control\n",
+ __func__);
+
return 0;
}
@@ -1032,6 +1325,7 @@ static struct snd_compr_ops msm_transcode_loopback_ops = {
.trigger = msm_transcode_loopback_trigger,
.set_params = msm_transcode_loopback_set_params,
.get_caps = msm_transcode_loopback_get_caps,
+ .set_metadata = msm_transcode_loopback_set_metadata,
};
@@ -1046,6 +1340,7 @@ static int msm_transcode_loopback_probe(struct snd_soc_platform *platform)
if (!pdata)
return -ENOMEM;
+ pdata->perf_mode = LOW_LATENCY_PCM_MODE;
snd_soc_platform_set_drvdata(platform, pdata);
return 0;
}
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index d297acd62665..609ae8cd82ac 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -7543,7 +7543,9 @@ int q6asm_set_mfc_panning_params(struct audio_client *ac,
struct asm_stream_param_data_v2 data;
struct audproc_chmixer_param_coeff pan_cfg;
uint16_t variable_payload = 0;
- uint16_t *asm_params = NULL;
+ char *asm_params = NULL;
+ uint16_t ii;
+ uint16_t *dst_gain_ptr = NULL;
sz = rc = i = 0;
if (ac == NULL) {
@@ -7604,7 +7606,7 @@ int q6asm_set_mfc_panning_params(struct audio_client *ac,
variable_payload = pan_param->num_output_channels * sizeof(uint16_t)+
pan_param->num_input_channels * sizeof(uint16_t) +
- pan_param->num_output_channels * sizeof(uint16_t) *
+ pan_param->num_output_channels *
pan_param->num_input_channels * sizeof(uint16_t);
i = (variable_payload % sizeof(uint32_t));
variable_payload += (i == 0) ? 0 : sizeof(uint32_t) - i;
@@ -7664,15 +7666,16 @@ int q6asm_set_mfc_panning_params(struct audio_client *ac,
pan_param->num_output_channels * sizeof(uint16_t)),
pan_param->input_channel_map,
pan_param->num_input_channels * sizeof(uint16_t));
- memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
+
+ dst_gain_ptr = (uint16_t *) ((u8 *)asm_params + sizeof(struct apr_hdr) +
sizeof(struct asm_stream_cmd_set_pp_params_v2) +
sizeof(struct asm_stream_param_data_v2) +
sizeof(struct audproc_chmixer_param_coeff) +
(pan_param->num_output_channels * sizeof(uint16_t)) +
- (pan_param->num_input_channels * sizeof(uint16_t))),
- pan_param->gain,
- (pan_param->num_output_channels * sizeof(uint16_t)) *
(pan_param->num_input_channels * sizeof(uint16_t)));
+ for (ii = 0; ii < pan_param->num_output_channels *
+ pan_param->num_input_channels; ii++)
+ dst_gain_ptr[ii] = (uint16_t) pan_param->gain[ii];
rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params);
if (rc < 0) {