summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/drm/msm/hdmi-display.txt2
-rw-r--r--Documentation/devicetree/bindings/media/video/msm-csid.txt2
-rw-r--r--Documentation/devicetree/bindings/spi/spi_qsd.txt4
-rw-r--r--arch/arm/boot/dts/qcom/Makefile3
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-auto-mizar.dts328
-rw-r--r--arch/arm/boot/dts/qcom/msm8996.dtsi11
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-mtp.dts9
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-qrd.dts9
-rw-r--r--arch/arm64/Kconfig10
-rw-r--r--arch/arm64/mm/init.c42
-rw-r--r--drivers/android/binder.c63
-rw-r--r--drivers/bluetooth/ath3k.c18
-rw-r--r--drivers/bluetooth/btqca.c58
-rw-r--r--drivers/clk/msm/mdss/mdss-dp-pll-8998-util.c6
-rw-r--r--drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c5
-rw-r--r--drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_bridge.c12
-rw-r--r--drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c10
-rw-r--r--drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.c72
-rw-r--r--drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.h3
-rw-r--r--drivers/gpu/drm/msm/sde/sde_plane.c4
-rw-r--r--drivers/gpu/drm/msm/sde_dbg.c64
-rw-r--r--drivers/gpu/msm/adreno_dispatch.c2
-rw-r--r--drivers/gpu/msm/kgsl_debugfs.c2
-rw-r--r--drivers/media/i2c/adv7481_reg.h2
-rw-r--r--drivers/media/platform/msm/ais/sensor/actuator/msm_actuator.c11
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h4
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp.c70
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp.h6
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp40.c20
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp47.c24
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c138
-rw-r--r--drivers/media/platform/msm/camera_v2/msm.c18
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/csid/include/msm_csid_3_5_1_hwreg.h64
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c8
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c21
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c2
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c16
-rw-r--r--drivers/media/platform/msm/vidc/msm_v4l2_vidc.c14
-rw-r--r--drivers/media/platform/msm/vidc/msm_vdec.c28
-rw-r--r--drivers/media/platform/msm/vidc/msm_venc.c28
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc.c95
-rw-r--r--drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c5
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c3
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h3
-rw-r--r--drivers/net/wireless/ath/ath10k/htc.c3
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c5
-rw-r--r--drivers/net/wireless/ath/ath10k/snoc.c52
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-ops.h19
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c79
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.h7
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h49
-rw-r--r--drivers/net/wireless/ath/ath10k/wow.c135
-rw-r--r--drivers/net/wireless/ath/ath10k/wow.h1
-rw-r--r--drivers/net/wireless/cnss2/pci.c7
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_flt.c8
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c54
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c7
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa.c5
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_i.h1
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c93
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_utils.c8
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c8
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c2
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c7
-rw-r--r--drivers/platform/msm/ipa/test/ipa_ut_framework.c10
-rw-r--r--drivers/platform/msm/mhi/mhi_bhi.c2
-rw-r--r--drivers/platform/msm/mhi/mhi_iface.c1
-rw-r--r--drivers/platform/msm/mhi/mhi_main.c1
-rw-r--r--drivers/platform/msm/sps/bam.c110
-rw-r--r--drivers/platform/msm/sps/sps.c7
-rw-r--r--drivers/platform/msm/sps/sps_bam.c8
-rw-r--r--drivers/platform/msm/sps/sps_mem.c5
-rw-r--r--drivers/platform/msm/sps/sps_rm.c7
-rw-r--r--drivers/power/supply/qcom/qpnp-fg-gen3.c55
-rw-r--r--drivers/power/supply/qcom/smb-lib.c34
-rw-r--r--drivers/scsi/sg.c28
-rw-r--r--drivers/scsi/ufs/ufs-qcom-debugfs.c3
-rw-r--r--drivers/scsi/ufs/ufshcd.c3
-rw-r--r--drivers/soc/qcom/icnss.c29
-rw-r--r--drivers/soc/qcom/msm_bus/msm_bus_dbg_voter.c15
-rw-r--r--drivers/soc/qcom/qdsp6v2/msm_audio_ion_vm.c3
-rw-r--r--drivers/spi/spi_qsd.c104
-rw-r--r--drivers/spi/spi_qsd.h29
-rw-r--r--drivers/usb/core/hub.c6
-rw-r--r--drivers/usb/dwc3/ep0.c2
-rw-r--r--drivers/usb/dwc3/gadget.c9
-rw-r--r--drivers/usb/dwc3/gadget.h1
-rw-r--r--drivers/usb/gadget/function/f_gsi.c3
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.c16
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_panel.c15
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_util.c3
-rw-r--r--drivers/video/msm/ba/msm_ba.c5
-rw-r--r--include/linux/spi/qcom-spi.h2
-rw-r--r--include/uapi/linux/nl80211.h5
-rw-r--r--include/uapi/media/ais/msm_ais_isp.h3
-rw-r--r--net/wireless/ap.c5
-rw-r--r--net/wireless/chan.c99
-rw-r--r--net/wireless/core.h10
-rw-r--r--net/wireless/db.txt6
-rw-r--r--net/wireless/ibss.c1
-rw-r--r--net/wireless/mesh.c1
-rw-r--r--net/wireless/mlme.c40
-rw-r--r--net/wireless/reg.c28
-rw-r--r--net/wireless/reg.h14
-rw-r--r--net/wireless/sysfs.c2
-rw-r--r--security/pfe/pfk_ice.c65
108 files changed, 2264 insertions, 402 deletions
diff --git a/Documentation/devicetree/bindings/drm/msm/hdmi-display.txt b/Documentation/devicetree/bindings/drm/msm/hdmi-display.txt
index aaa3722659ab..9329fb74dea0 100644
--- a/Documentation/devicetree/bindings/drm/msm/hdmi-display.txt
+++ b/Documentation/devicetree/bindings/drm/msm/hdmi-display.txt
@@ -50,7 +50,7 @@ Example:
qcom,mode-v-pulse-width = <10>;
qcom,mode-v-back-porch = <72>;
qcom,mode-v-active-high;
- qcom,mode-refersh-rate = <30>;
+ qcom,mode-refresh-rate = <30>;
qcom,mode-clock-in-khz = <297000>;
};
};
diff --git a/Documentation/devicetree/bindings/media/video/msm-csid.txt b/Documentation/devicetree/bindings/media/video/msm-csid.txt
index 340d98688b76..e580c056b3eb 100644
--- a/Documentation/devicetree/bindings/media/video/msm-csid.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-csid.txt
@@ -12,8 +12,8 @@ Required properties:
- "qcom,csid-v3.5"
- "qcom,csid-v4.0"
- "qcom,csid-v3.4.2"
- - "qcom,csid-v3.5.1"
- "qcom,csid-v3.4.3"
+ - "qcom,csid-v3.5.1"
- "qcom,csid-v5.0"
- reg : offset and length of the register set for the device
for the csid operating in compatible mode.
diff --git a/Documentation/devicetree/bindings/spi/spi_qsd.txt b/Documentation/devicetree/bindings/spi/spi_qsd.txt
index 1edf0820398a..b3007eb9ceea 100644
--- a/Documentation/devicetree/bindings/spi/spi_qsd.txt
+++ b/Documentation/devicetree/bindings/spi/spi_qsd.txt
@@ -1,7 +1,8 @@
Qualcomm Serial Peripheral Interface (SPI)
Required properties:
-- compatible : Should be "qcom,spi-qup-v2".
+- compatible : Should be "qcom,spi-qup-v2". Should "qcom,qup-v26" for
+ controllers that support spi slave mode.
- reg : Offset and length of the register regions for the device
- reg-names : Register region names referenced in reg above.
Required register resource entries are:
@@ -72,6 +73,7 @@ the following properties.
clock phase (CPHA) mode
- spi-cs-high : (optional) Empty property indicating device requires
chip select active high
+- qcom,slv-ctrl : Set this flag to configure QUP as SPI slave controller.
Example:
aliases {
diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile
index 8829ef5fd221..f7ba268b233e 100644
--- a/arch/arm/boot/dts/qcom/Makefile
+++ b/arch/arm/boot/dts/qcom/Makefile
@@ -113,7 +113,8 @@ dtb-$(CONFIG_ARCH_MSM8996) += msm8996-v2-pmi8994-cdp.dtb \
apq8096-v3-pmi8994-mdm9x55-slimbus-mtp.dtb \
apq8096-v3-pmi8996-mdm9x55-i2s-mtp.dtb \
apq8096-v3-pmi8996-mdm9x55-slimbus-mtp.dtb \
- apq8096-v3-pmi8996-dragonboard.dtb
+ apq8096-v3-pmi8996-dragonboard.dtb \
+ msm8996-auto-mizar.dtb
dtb-$(CONFIG_MSM_GVM_QUIN) += vplatform-lfv-msm8996-telematics.dtb \
vplatform-lfv-msm8996-ivi.dtb
diff --git a/arch/arm/boot/dts/qcom/msm8996-auto-mizar.dts b/arch/arm/boot/dts/qcom/msm8996-auto-mizar.dts
new file mode 100644
index 000000000000..3a7d009c12a4
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msm8996-auto-mizar.dts
@@ -0,0 +1,328 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "msm8996pro.dtsi"
+#include "msm8996-pm8994.dtsi"
+#include "msm8996-agave-adp.dtsi"
+#include "msm8996pro-auto.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. MSM 8996pro AUTO ADP";
+ compatible = "qcom,msm8996-adp", "qcom,msm8996", "qcom,adp";
+ qcom,msm-id = <315 0x10001>;
+ qcom,board-id = <0x06010019 0>, <0x00010001 0>;
+};
+
+&spi_9 {
+ status = "ok";
+ can-controller@0 {
+ compatible = "renesas,rh850";
+ reg = <0>;
+ interrupt-parent = <&tlmm>;
+ interrupts = <122 0>;
+ spi-max-frequency = <5000000>;
+ };
+};
+
+&soc {
+ qcom,msm-ssc-sensors {
+ status = "disabled";
+ };
+
+ qcom,msm-thermal {
+ qcom,hotplug-temp = <115>;
+ qcom,hotplug-temp-hysteresis = <25>;
+ qcom,therm-reset-temp = <119>;
+ };
+
+ qcom,adv7481@70 {
+ status = "disabled";
+ };
+
+ qcom,ntn_avb {
+ qcom,ntn-rc-num = <2>;
+ };
+
+ i2c@75b6000 { /* BLSP8 */
+ /* ADV7533 HDMI Bridge Chip removed on ADP Lite */
+ adv7533@39 {
+ status = "disabled";
+ };
+
+ adv7533@3d {
+ status = "disabled";
+ };
+ };
+
+};
+
+&cci {
+ qcom,camera@0 {
+ pinctrl-names = "cam_default", "cam_suspend","default";
+ pinctrl-2 = <&mx9296_pwr>;
+ qcom,cci-master = <0>;
+ };
+};
+
+&tlmm {
+ pcie2 {
+ pcie2_perst_default: pcie2_perst_default {
+ mux {
+ pins = "gpio90";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio90";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+
+ pcie2_wake_default: pcie2_wake_default {
+ mux {
+ pins = "gpio54";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio54";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+ };
+
+ mx9296_pwr: mx9296_pwr {
+ mux {
+ pins = "gpio21";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio21";
+ drive-strength = <2>;
+ bias-pull-up;
+ output-high;
+ };
+ };
+};
+
+&pil_modem {
+ pinctrl-names = "default";
+ pinctrl-0 = <&modem_mux>;
+};
+
+&slim_msm {
+ status = "disabled";
+};
+
+&pm8994_mpps {
+ mpp@a500 { /* MPP 6 */
+ qcom,mode = <1>; /* Digital output */
+ qcom,output-type = <0>; /* CMOS logic */
+ qcom,vin-sel = <2>; /* S4 1.8V */
+ qcom,src-sel = <0>; /* Constant */
+ qcom,master-en = <1>; /* Enable GPIO */
+ status = "okay";
+ };
+};
+
+&sdhc_2 {
+ cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on_sbc>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off
+ &sdc2_cd_on_sbc>;
+};
+
+&i2c_7 {
+ silabs4705@11 { /* SiLabs FM chip, slave id 0x11*/
+ status = "disabled";
+ };
+};
+
+&pcie0 {
+ qcom,phy-sequence = <0x404 0x01 0x00
+ 0x034 0x1c 0x00
+ 0x038 0x10 0x00
+ 0x174 0x33 0x00
+ 0x194 0x06 0x00
+ 0x0c8 0x42 0x00
+ 0x128 0x00 0x00
+ 0x144 0xff 0x00
+ 0x148 0x1f 0x00
+ 0x178 0x01 0x00
+ 0x19c 0x01 0x00
+ 0x18c 0x00 0x00
+ 0x184 0x0a 0x00
+ 0x00c 0x09 0x00
+ 0x0d0 0x82 0x00
+ 0x0e4 0x03 0x00
+ 0x0e0 0x55 0x00
+ 0x0dc 0x55 0x00
+ 0x054 0x00 0x00
+ 0x050 0x1a 0x00
+ 0x04c 0x0a 0x00
+ 0x174 0x33 0x00
+ 0x03c 0x02 0x00
+ 0x040 0x1f 0x00
+ 0x0ac 0x04 0x00
+ 0x078 0x0b 0x00
+ 0x084 0x16 0x00
+ 0x090 0x28 0x00
+ 0x10c 0x00 0x00
+ 0x108 0x80 0x00
+ 0x010 0x00 0x00
+ 0x01c 0x31 0x00
+ 0x020 0x01 0x00
+ 0x014 0x02 0x00
+ 0x018 0x00 0x00
+ 0x024 0x2f 0x00
+ 0x028 0x19 0x00
+ 0x0c4 0x15 0x00
+ 0x070 0x0f 0x00
+ 0x048 0x0f 0x00
+ 0x074 0x19 0x00
+ 0x038 0x10 0x00
+ 0x178 0x00 0x00
+ 0x0c4 0x40 0x00
+ 0x400 0x00 0x00
+ 0x408 0x03 0x00>;
+
+ qcom,port-phy-sequence = <0x1068 0x45 0x00
+ 0x1094 0x06 0x00
+ 0x1310 0x1c 0x00
+ 0x1318 0x17 0x00
+ 0x12d8 0x01 0x00
+ 0x12dc 0x00 0x00
+ 0x12e0 0xdb 0x00
+ 0x1320 0x18 0x00
+ 0x121c 0x04 0x00
+ 0x1210 0x04 0x00
+ 0x1458 0x4c 0x00
+ 0x14a0 0x00 0x00
+ 0x14a4 0x01 0x00
+ 0x14a8 0x05 0x00
+ 0x1248 0x4b 0x00
+ 0x131c 0x14 0x00
+ 0x1454 0x05 0x00
+ 0x1404 0x02 0x00
+ 0x146c 0x00 0x00
+ 0x1460 0xa3 0x00
+ 0x1318 0x19 0x00
+ 0x1428 0x0e 0x00
+ 0x1054 0x08 0x00
+ 0x14f8 0x04 0x00
+ 0x14ec 0x06 0x00
+ 0x104c 0x2e 0x00
+ 0x1404 0x03 0x0a
+ 0x1400 0x00 0x00
+ 0x1408 0x0a 0x00>;
+
+ /delete-property/qcom,l1-supported;
+ /delete-property/qcom,l1ss-supported;
+ qcom,aux-clk-sync;
+ qcom,boot-option = <0x0>;
+};
+
+&pcie1 {
+ qcom,phy-sequence = <0x404 0x01 0x00
+ 0x034 0x1c 0x00
+ 0x038 0x10 0x00
+ 0x174 0x33 0x00
+ 0x194 0x06 0x00
+ 0x0c8 0x42 0x00
+ 0x128 0x00 0x00
+ 0x144 0xff 0x00
+ 0x148 0x1f 0x00
+ 0x178 0x01 0x00
+ 0x19c 0x01 0x00
+ 0x18c 0x00 0x00
+ 0x184 0x0a 0x00
+ 0x00c 0x09 0x00
+ 0x0d0 0x82 0x00
+ 0x0e4 0x03 0x00
+ 0x0e0 0x55 0x00
+ 0x0dc 0x55 0x00
+ 0x054 0x00 0x00
+ 0x050 0x1a 0x00
+ 0x04c 0x0a 0x00
+ 0x174 0x33 0x00
+ 0x03c 0x02 0x00
+ 0x040 0x1f 0x00
+ 0x0ac 0x04 0x00
+ 0x078 0x0b 0x00
+ 0x084 0x16 0x00
+ 0x090 0x28 0x00
+ 0x10c 0x00 0x00
+ 0x108 0x80 0x00
+ 0x010 0x00 0x00
+ 0x01c 0x31 0x00
+ 0x020 0x01 0x00
+ 0x014 0x02 0x00
+ 0x018 0x00 0x00
+ 0x024 0x2f 0x00
+ 0x028 0x19 0x00
+ 0x0c4 0x15 0x00
+ 0x070 0x0f 0x00
+ 0x048 0x0f 0x00
+ 0x074 0x19 0x00
+ 0x038 0x10 0x00
+ 0x178 0x00 0x00
+ 0x0c4 0x40 0x00
+ 0x400 0x00 0x00
+ 0x408 0x03 0x00>;
+
+ qcom,port-phy-sequence = <0x2068 0x45 0x00
+ 0x2094 0x06 0x00
+ 0x2310 0x1c 0x00
+ 0x2318 0x17 0x00
+ 0x22d8 0x01 0x00
+ 0x22dc 0x00 0x00
+ 0x22e0 0xdb 0x00
+ 0x2320 0x18 0x00
+ 0x221c 0x04 0x00
+ 0x2210 0x04 0x00
+ 0x2458 0x4c 0x00
+ 0x24a0 0x00 0x00
+ 0x24a4 0x01 0x00
+ 0x24a8 0x05 0x00
+ 0x2248 0x4b 0x00
+ 0x231c 0x14 0x00
+ 0x2454 0x05 0x00
+ 0x2404 0x02 0x00
+ 0x246c 0x00 0x00
+ 0x2460 0xa3 0x00
+ 0x2318 0x19 0x00
+ 0x2428 0x0e 0x00
+ 0x2054 0x08 0x00
+ 0x24f8 0x04 0x00
+ 0x24ec 0x06 0x00
+ 0x204c 0x2e 0x00
+ 0x2404 0x03 0x0a
+ 0x2400 0x00 0x00
+ 0x2408 0x0a 0x00>;
+
+ /delete-property/qcom,l1-supported;
+ /delete-property/qcom,l1ss-supported;
+ /delete-property/qcom,aux-clk-sync;
+ qcom,boot-option = <0x0>;
+};
+
+&pcie2 {
+ qcom,boot-option = <0x0>;
+ perst-gpio = <&tlmm 90 0>;
+ wake-gpio = <&tlmm 54 0>;
+};
diff --git a/arch/arm/boot/dts/qcom/msm8996.dtsi b/arch/arm/boot/dts/qcom/msm8996.dtsi
index 0803207a96d1..9694490a39a2 100644
--- a/arch/arm/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996.dtsi
@@ -250,8 +250,8 @@
label = "cont_splash_mem";
};
- cont_splash_mem_hdmi: cont_splash_mem_hdmi@b1c00000 {
- reg = <0 0xb1c00000 0 0x23ff000>;
+ cont_splash_mem_hdmi: cont_splash_mem_hdmi@bdd00000 {
+ reg = <0 0xbdd00000 0 0x23ff000>;
label = "cont_splash_mem_hdmi";
};
};
@@ -2289,6 +2289,13 @@
qcom,reset-ep-after-lpm-resume;
};
+ usb_audio_qmi_dev {
+ compatible = "qcom,usb-audio-qmi-dev";
+ iommus = <&lpass_q6_smmu 12>;
+ qcom,usb-audio-stream-id = <12>;
+ qcom,usb-audio-intr-num = <1>;
+ };
+
qcom,lpass@9300000 {
compatible = "qcom,pil-tz-generic";
reg = <0x9300000 0x00100>;
diff --git a/arch/arm/boot/dts/qcom/sdm660-mtp.dts b/arch/arm/boot/dts/qcom/sdm660-mtp.dts
index 32b294ee6883..68e4491193d5 100644
--- a/arch/arm/boot/dts/qcom/sdm660-mtp.dts
+++ b/arch/arm/boot/dts/qcom/sdm660-mtp.dts
@@ -29,3 +29,12 @@
&tavil_snd {
qcom,msm-mbhc-moist-cfg = <0>, <0>, <3>;
};
+
+&slim_aud {
+ /delete-node/tasha_codec;
+};
+
+&soc {
+ /delete-node/sound-9335;
+};
+
diff --git a/arch/arm/boot/dts/qcom/sdm660-qrd.dts b/arch/arm/boot/dts/qcom/sdm660-qrd.dts
index 3284e805a093..4e7cc547e6cd 100644
--- a/arch/arm/boot/dts/qcom/sdm660-qrd.dts
+++ b/arch/arm/boot/dts/qcom/sdm660-qrd.dts
@@ -86,3 +86,12 @@
qcom,afe-power-off-delay-us = <6>;
};
};
+
+&slim_aud {
+ /delete-node/wcd934x_cdc;
+};
+
+&soc {
+ /delete-node/sound-tavil;
+};
+
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index d61f3ae80e15..07090b418129 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -652,6 +652,12 @@ config HOTPLUG_CPU
Say Y here to experiment with turning CPUs off and on. CPUs
can be controlled through /sys/devices/system/cpu.
+config ARCH_ENABLE_MEMORY_HOTPLUG
+ def_bool y
+
+config ARCH_ENABLE_MEMORY_HOTREMOVE
+ def_bool y
+
# The GPIO number here must be sorted by descending number. In case of
# a multiplatform kernel, we just want the highest value required by the
# selected platforms.
@@ -738,6 +744,10 @@ config ARCH_HAS_CACHE_LINE_SIZE
source "mm/Kconfig"
+config ARCH_MEMORY_PROBE
+ def_bool y
+ depends on MEMORY_HOTPLUG
+
config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode"
---help---
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index b4ef9ea679a1..1d4dcd57ac85 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -495,3 +495,45 @@ static int __init register_mem_limit_dumper(void)
return 0;
}
__initcall(register_mem_limit_dumper);
+
+#ifdef CONFIG_MEMORY_HOTPLUG
+int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
+{
+ pg_data_t *pgdat;
+ struct zone *zone;
+ unsigned long start_pfn = start >> PAGE_SHIFT;
+ unsigned long nr_pages = size >> PAGE_SHIFT;
+ int ret;
+
+ pgdat = NODE_DATA(nid);
+
+ zone = pgdat->node_zones +
+ zone_for_memory(nid, start, size, ZONE_NORMAL, for_device);
+ ret = __add_pages(nid, zone, start_pfn, nr_pages);
+
+ if (ret)
+ pr_warn("%s: Problem encountered in __add_pages() ret=%d\n",
+ __func__, ret);
+
+ return ret;
+}
+
+#ifdef CONFIG_MEMORY_HOTREMOVE
+int arch_remove_memory(u64 start, u64 size)
+{
+ unsigned long start_pfn = start >> PAGE_SHIFT;
+ unsigned long nr_pages = size >> PAGE_SHIFT;
+ struct zone *zone;
+ int ret;
+
+ zone = page_zone(pfn_to_page(start_pfn));
+ ret = __remove_pages(zone, start_pfn, nr_pages);
+ if (ret)
+ pr_warn("%s: Problem encountered in __remove_pages() ret=%d\n",
+ __func__, ret);
+
+ return ret;
+}
+#endif
+#endif
+
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 9e31197f4b6d..2c33b1251afb 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -466,9 +466,8 @@ struct binder_ref {
};
enum binder_deferred_state {
- BINDER_DEFERRED_PUT_FILES = 0x01,
- BINDER_DEFERRED_FLUSH = 0x02,
- BINDER_DEFERRED_RELEASE = 0x04,
+ BINDER_DEFERRED_FLUSH = 0x01,
+ BINDER_DEFERRED_RELEASE = 0x02,
};
/**
@@ -505,8 +504,6 @@ struct binder_priority {
* (invariant after initialized)
* @tsk task_struct for group_leader of process
* (invariant after initialized)
- * @files files_struct for process
- * (invariant after initialized)
* @deferred_work_node: element for binder_deferred_list
* (protected by binder_deferred_lock)
* @deferred_work: bitmap of deferred work to perform
@@ -553,7 +550,6 @@ struct binder_proc {
struct list_head waiting_threads;
int pid;
struct task_struct *tsk;
- struct files_struct *files;
struct hlist_node deferred_work_node;
int deferred_work;
bool is_dead;
@@ -949,22 +945,34 @@ static void binder_free_thread(struct binder_thread *thread);
static void binder_free_proc(struct binder_proc *proc);
static void binder_inc_node_tmpref_ilocked(struct binder_node *node);
+struct files_struct *binder_get_files_struct(struct binder_proc *proc)
+{
+ return get_files_struct(proc->tsk);
+}
+
static int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
{
- struct files_struct *files = proc->files;
+ struct files_struct *files;
unsigned long rlim_cur;
unsigned long irqs;
+ int ret;
+ files = binder_get_files_struct(proc);
if (files == NULL)
return -ESRCH;
- if (!lock_task_sighand(proc->tsk, &irqs))
- return -EMFILE;
+ if (!lock_task_sighand(proc->tsk, &irqs)) {
+ ret = -EMFILE;
+ goto err;
+ }
rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE);
unlock_task_sighand(proc->tsk, &irqs);
- return __alloc_fd(files, 0, rlim_cur, flags);
+ ret = __alloc_fd(files, 0, rlim_cur, flags);
+err:
+ put_files_struct(files);
+ return ret;
}
/*
@@ -973,8 +981,12 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
static void task_fd_install(
struct binder_proc *proc, unsigned int fd, struct file *file)
{
- if (proc->files)
- __fd_install(proc->files, fd, file);
+ struct files_struct *files = binder_get_files_struct(proc);
+
+ if (files) {
+ __fd_install(files, fd, file);
+ put_files_struct(files);
+ }
}
/*
@@ -982,18 +994,20 @@ static void task_fd_install(
*/
static long task_close_fd(struct binder_proc *proc, unsigned int fd)
{
+ struct files_struct *files = binder_get_files_struct(proc);
int retval;
- if (proc->files == NULL)
+ if (files == NULL)
return -ESRCH;
- retval = __close_fd(proc->files, fd);
+ retval = __close_fd(files, fd);
/* can't restart close syscall because file table entry was cleared */
if (unlikely(retval == -ERESTARTSYS ||
retval == -ERESTARTNOINTR ||
retval == -ERESTARTNOHAND ||
retval == -ERESTART_RESTARTBLOCK))
retval = -EINTR;
+ put_files_struct(files);
return retval;
}
@@ -4811,7 +4825,6 @@ static void binder_vma_close(struct vm_area_struct *vma)
(vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
(unsigned long)pgprot_val(vma->vm_page_prot));
binder_alloc_vma_close(&proc->alloc);
- binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES);
}
static int binder_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -4853,10 +4866,8 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_private_data = proc;
ret = binder_alloc_mmap_handler(&proc->alloc, vma);
- if (ret)
- return ret;
- proc->files = get_files_struct(current);
- return 0;
+
+ return ret;
err_bad_arg:
pr_err("binder_mmap: %d %lx-%lx %s failed %d\n",
@@ -5035,8 +5046,6 @@ static void binder_deferred_release(struct binder_proc *proc)
struct rb_node *n;
int threads, nodes, incoming_refs, outgoing_refs, active_transactions;
- BUG_ON(proc->files);
-
mutex_lock(&binder_procs_lock);
hlist_del(&proc->proc_node);
mutex_unlock(&binder_procs_lock);
@@ -5118,8 +5127,6 @@ static void binder_deferred_release(struct binder_proc *proc)
static void binder_deferred_func(struct work_struct *work)
{
struct binder_proc *proc;
- struct files_struct *files;
-
int defer;
do {
@@ -5136,21 +5143,11 @@ static void binder_deferred_func(struct work_struct *work)
}
mutex_unlock(&binder_deferred_lock);
- files = NULL;
- if (defer & BINDER_DEFERRED_PUT_FILES) {
- files = proc->files;
- if (files)
- proc->files = NULL;
- }
-
if (defer & BINDER_DEFERRED_FLUSH)
binder_deferred_flush(proc);
if (defer & BINDER_DEFERRED_RELEASE)
binder_deferred_release(proc); /* frees proc */
-
- if (files)
- put_files_struct(files);
} while (proc);
}
static DECLARE_WORK(binder_deferred_work, binder_deferred_func);
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 5df8e1234505..071c94457d34 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -209,13 +209,27 @@ static int ath3k_load_firmware(struct usb_device *udev,
{
u8 *send_buf;
int err, pipe, len, size, sent = 0;
- int count = firmware->size;
+ int count;
BT_DBG("udev %p", udev);
+ if (!firmware || !firmware->data || firmware->size <= 0) {
+ err = -EINVAL;
+ BT_ERR("Not a valid FW file");
+ return err;
+ }
+
+ count = firmware->size;
+
+ if (count < FW_HDR_SIZE) {
+ err = -EINVAL;
+ BT_ERR("ath3k loading invalid size of file");
+ return err;
+ }
+
pipe = usb_sndctrlpipe(udev, 0);
- send_buf = kmalloc(BULK_SIZE, GFP_KERNEL);
+ send_buf = kzalloc(BULK_SIZE, GFP_KERNEL);
if (!send_buf) {
BT_ERR("Can't allocate memory chunk for firmware");
return -ENOMEM;
diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index 4a6208168850..0db4a00e7641 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -27,6 +27,9 @@
#define VERSION "0.1"
+#define MAX_PATCH_FILE_SIZE (100*1024)
+#define MAX_NVM_FILE_SIZE (10*1024)
+
static int rome_patch_ver_req(struct hci_dev *hdev, u32 *rome_version)
{
struct sk_buff *skb;
@@ -285,27 +288,59 @@ static int rome_download_firmware(struct hci_dev *hdev,
struct rome_config *config)
{
const struct firmware *fw;
+ u32 type_len, length;
+ struct tlv_type_hdr *tlv;
int ret;
- BT_INFO("%s: ROME Downloading %s", hdev->name, config->fwname);
-
+ BT_INFO("%s: ROME Downloading file: %s", hdev->name, config->fwname);
ret = request_firmware(&fw, config->fwname, &hdev->dev);
- if (ret) {
- BT_ERR("%s: Failed to request file: %s (%d)", hdev->name,
- config->fwname, ret);
+
+ if (ret || !fw || !fw->data || fw->size <= 0) {
+ BT_ERR("Failed to request file: err = (%d)", ret);
+ ret = ret ? ret : -EINVAL;
return ret;
}
+ if (config->type == TLV_TYPE_PATCH &&
+ (fw->size > MAX_PATCH_FILE_SIZE)) {
+ ret = -EINVAL;
+ BT_ERR("TLV_PATCH dload: wrong patch file sizes");
+ goto exit;
+ } else if (config->type == TLV_TYPE_NVM &&
+ (fw->size > MAX_NVM_FILE_SIZE)) {
+ ret = -EINVAL;
+ BT_ERR("TLV_NVM dload: wrong NVM file sizes");
+ goto exit;
+ } else {
+ ret = -EINVAL;
+ BT_ERR("TLV_NVM dload: wrong config type selected");
+ goto exit;
+ }
- rome_tlv_check_data(config, fw);
+ if (fw->size < sizeof(struct tlv_type_hdr)) {
+ ret = -EINVAL;
+ BT_ERR("Firware size smaller to fit minimum value");
+ goto exit;
+ }
+ tlv = (struct tlv_type_hdr *)fw->data;
+ type_len = le32_to_cpu(tlv->type_len);
+ length = (type_len >> 8) & 0x00ffffff;
+
+ if (fw->size - 4 != length) {
+ ret = -EINVAL;
+ BT_ERR("Requested size not matching size in header");
+ goto exit;
+ }
+
+ rome_tlv_check_data(config, fw);
ret = rome_tlv_download_request(hdev, fw);
+
if (ret) {
- BT_ERR("%s: Failed to download file: %s (%d)", hdev->name,
- config->fwname, ret);
+ BT_ERR("Failed to download FW: error = (%d)", ret);
}
+exit:
release_firmware(fw);
-
return ret;
}
@@ -316,8 +351,9 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
int err;
cmd[0] = EDL_NVM_ACCESS_SET_REQ_CMD;
- cmd[1] = 0x02; /* TAG ID */
- cmd[2] = sizeof(bdaddr_t); /* size */
+ /* Set the TAG ID of 0x02 for NVM set and size of tag */
+ cmd[1] = 0x02;
+ cmd[2] = sizeof(bdaddr_t);
memcpy(cmd + 3, bdaddr, sizeof(bdaddr_t));
skb = __hci_cmd_sync_ev(hdev, EDL_NVM_ACCESS_OPCODE, sizeof(cmd), cmd,
HCI_VENDOR_PKT, HCI_INIT_TIMEOUT);
diff --git a/drivers/clk/msm/mdss/mdss-dp-pll-8998-util.c b/drivers/clk/msm/mdss/mdss-dp-pll-8998-util.c
index 0bd7e6413a6b..2d40fdeabcae 100644
--- a/drivers/clk/msm/mdss/mdss-dp-pll-8998-util.c
+++ b/drivers/clk/msm/mdss/mdss-dp-pll-8998-util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -128,10 +128,10 @@ int vco_divided_clk_set_div(struct div_clk *clk, int div)
auxclk_div = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_VCO_DIV);
auxclk_div &= ~0x03; /* bits 0 to 1 */
- auxclk_div |= 1; /* Default divider */
-
if (div == 4)
auxclk_div |= 2;
+ else
+ auxclk_div |= 1; /* Default divider */
MDSS_PLL_REG_W(dp_res->phy_base,
DP_PHY_VCO_DIV, auxclk_div);
diff --git a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c
index 0f77e35ef287..35ba396e1cd1 100644
--- a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c
@@ -2799,7 +2799,6 @@ static int _sde_hdmi_parse_dt_modes(struct device_node *np,
u32 v_front_porch, v_pulse_width, v_back_porch;
bool h_active_high, v_active_high;
u32 flags = 0;
-
root_node = of_get_child_by_name(np, "qcom,customize-modes");
if (!root_node) {
root_node = of_parse_phandle(np, "qcom,customize-modes", 0);
@@ -2887,10 +2886,10 @@ static int _sde_hdmi_parse_dt_modes(struct device_node *np,
v_active_high = of_property_read_bool(node,
"qcom,mode-v-active-high");
- rc = of_property_read_u32(node, "qcom,mode-refersh-rate",
+ rc = of_property_read_u32(node, "qcom,mode-refresh-rate",
&mode->vrefresh);
if (rc) {
- SDE_ERROR("failed to read refersh-rate, rc=%d\n", rc);
+ SDE_ERROR("failed to read refresh-rate, rc=%d\n", rc);
goto fail;
}
diff --git a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_bridge.c
index 0c143059b749..5fbe4767ad3a 100644
--- a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_bridge.c
@@ -578,6 +578,9 @@ static void _sde_hdmi_bridge_disable(struct drm_bridge *bridge)
display->sink_hdcp_ver = SDE_HDMI_HDCP_NONE;
display->sink_hdcp22_support = false;
+ if (sde_hdmi_tx_is_hdcp_enabled(display))
+ sde_hdmi_hdcp_off(display);
+
sde_hdmi_clear_hdr_info(bridge);
mutex_unlock(&display->display_lock);
}
@@ -592,9 +595,6 @@ static void _sde_hdmi_bridge_post_disable(struct drm_bridge *bridge)
sde_hdmi_notify_clients(display, display->connected);
- if (sde_hdmi_tx_is_hdcp_enabled(display))
- sde_hdmi_hdcp_off(display);
-
sde_hdmi_audio_off(hdmi);
DRM_DEBUG("power down");
@@ -603,10 +603,16 @@ static void _sde_hdmi_bridge_post_disable(struct drm_bridge *bridge)
if (phy)
phy->funcs->powerdown(phy);
+ /* HDMI teardown sequence */
+ sde_hdmi_ctrl_reset(hdmi);
+
if (hdmi->power_on) {
_sde_hdmi_bridge_power_off(bridge);
hdmi->power_on = false;
}
+
+ /* Powering-on the controller for HPD */
+ sde_hdmi_ctrl_cfg(hdmi, 1);
}
static void _sde_hdmi_bridge_set_avi_infoframe(struct hdmi *hdmi,
diff --git a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c
index 51f5c8d8dde6..a4f47756ad9b 100644
--- a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c
+++ b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c
@@ -234,10 +234,16 @@ static void sde_hdmi_hdcp2p2_off(void *input)
flush_kthread_worker(&ctrl->worker);
- sde_hdmi_hdcp2p2_ddc_disable((void *)ctrl->init_data.cb_data);
-
cdata.context = input;
sde_hdmi_hdcp2p2_wakeup(&cdata);
+
+ /* There could be upto one frame delay
+ * between the time encryption disable is
+ * requested till the time we get encryption
+ * disabled interrupt
+ */
+ msleep(20);
+ sde_hdmi_hdcp2p2_ddc_disable((void *)ctrl->init_data.cb_data);
}
static int sde_hdmi_hdcp2p2_authenticate(void *input)
diff --git a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.c b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.c
index a291a1112aeb..8ce90b9bc162 100644
--- a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.c
+++ b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.c
@@ -681,6 +681,78 @@ static void _sde_hdmi_scrambler_ddc_reset(struct hdmi *hdmi)
hdmi_write(hdmi, REG_HDMI_SCRAMBLER_STATUS_DDC_CTRL, reg_val);
}
+void sde_hdmi_ctrl_cfg(struct hdmi *hdmi, bool power_on)
+{
+ uint32_t ctrl = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&hdmi->reg_lock, flags);
+ ctrl = hdmi_read(hdmi, REG_HDMI_CTRL);
+
+ if (power_on)
+ ctrl |= HDMI_CTRL_ENABLE;
+ else
+ ctrl &= ~HDMI_CTRL_ENABLE;
+
+ hdmi_write(hdmi, REG_HDMI_CTRL, ctrl);
+ spin_unlock_irqrestore(&hdmi->reg_lock, flags);
+
+ HDMI_UTIL_DEBUG("HDMI Core: %s, HDMI_CTRL=0x%08x\n",
+ power_on ? "Enable" : "Disable", ctrl);
+}
+
+static void sde_hdmi_clear_pkt_send(struct hdmi *hdmi)
+{
+ uint32_t reg_val;
+
+ /* Clear audio sample send */
+ reg_val = hdmi_read(hdmi, HDMI_AUDIO_PKT_CTRL);
+ reg_val &= ~BIT(0);
+ hdmi_write(hdmi, HDMI_AUDIO_PKT_CTRL, reg_val);
+
+ /* Clear sending VBI ctrl packets */
+ reg_val = hdmi_read(hdmi, HDMI_VBI_PKT_CTRL);
+ reg_val &= ~(BIT(4) | BIT(8) | BIT(12));
+ hdmi_write(hdmi, HDMI_VBI_PKT_CTRL, reg_val);
+
+ /* Clear sending infoframe packets */
+ reg_val = hdmi_read(hdmi, HDMI_INFOFRAME_CTRL0);
+ reg_val &= ~(BIT(0) | BIT(4) | BIT(8) | BIT(12)
+ | BIT(15) | BIT(19));
+ hdmi_write(hdmi, HDMI_INFOFRAME_CTRL0, reg_val);
+
+ /* Clear sending general ctrl packets */
+ reg_val = hdmi_read(hdmi, HDMI_GEN_PKT_CTRL);
+ reg_val &= ~(BIT(0) | BIT(4));
+ hdmi_write(hdmi, HDMI_GEN_PKT_CTRL, reg_val);
+}
+
+void sde_hdmi_ctrl_reset(struct hdmi *hdmi)
+{
+ uint32_t reg_val;
+
+ /* Assert HDMI CTRL SW reset */
+ reg_val = hdmi_read(hdmi, HDMI_CTRL_SW_RESET);
+ reg_val |= BIT(0);
+ hdmi_write(hdmi, HDMI_CTRL_SW_RESET, reg_val);
+
+ /* disable the controller and put to known state */
+ sde_hdmi_ctrl_cfg(hdmi, 0);
+
+ /* disable the audio engine */
+ reg_val = hdmi_read(hdmi, HDMI_AUDIO_CFG);
+ reg_val &= ~BIT(0);
+ hdmi_write(hdmi, HDMI_AUDIO_CFG, reg_val);
+
+ /* clear sending packets to sink */
+ sde_hdmi_clear_pkt_send(hdmi);
+
+ /* De-assert HDMI CTRL SW reset */
+ reg_val = hdmi_read(hdmi, HDMI_CTRL_SW_RESET);
+ reg_val &= ~BIT(0);
+ hdmi_write(hdmi, HDMI_CTRL_SW_RESET, reg_val);
+}
+
void _sde_hdmi_scrambler_ddc_disable(void *hdmi_display)
{
struct sde_hdmi *display = (struct sde_hdmi *)hdmi_display;
diff --git a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.h b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.h
index 3cef7e6aca39..340e665f2c28 100644
--- a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.h
+++ b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.h
@@ -198,4 +198,7 @@ int sde_hdmi_sink_dc_support(struct drm_connector *connector,
struct drm_display_mode *mode);
u8 sde_hdmi_hdr_get_ops(u8 curr_state,
u8 new_state);
+void sde_hdmi_ctrl_reset(struct hdmi *hdmi);
+void sde_hdmi_ctrl_cfg(struct hdmi *hdmi, bool power_on);
+
#endif /* _SDE_HDMI_UTIL_H_ */
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c
index 9cbee5243e6d..f5f125c3f71c 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.c
+++ b/drivers/gpu/drm/msm/sde/sde_plane.c
@@ -1808,8 +1808,8 @@ static void _sde_plane_install_properties(struct drm_plane *plane,
char feature_name[256];
struct sde_phy_plane *pp;
uint32_t features = 0xFFFFFFFF, nformats = 64;
- u32 maxlinewidth = -1, maxupscale = -1, maxdwnscale = -1;
- u32 maxhdeciexp = -1, maxvdeciexp = -1;
+ u32 maxlinewidth = 0, maxupscale = 0, maxdwnscale = 0;
+ u32 maxhdeciexp = 0, maxvdeciexp = 0;
if (!plane || !psde) {
SDE_ERROR("invalid plane\n");
diff --git a/drivers/gpu/drm/msm/sde_dbg.c b/drivers/gpu/drm/msm/sde_dbg.c
index 5a0c5e677ed8..ea133619cf62 100644
--- a/drivers/gpu/drm/msm/sde_dbg.c
+++ b/drivers/gpu/drm/msm/sde_dbg.c
@@ -153,6 +153,7 @@ struct sde_dbg_vbif_debug_bus {
* @reg_base_list: list of register dumping regions
* @root: base debugfs root
* @dev: device pointer
+ * @mutex: mutex to serialize access to serialze dumps, debugfs access
* @power_ctrl: callback structure for enabling power for reading hw registers
* @req_dump_blks: list of blocks requested for dumping
* @panic_on_err: whether to kernel panic after triggering dump via debugfs
@@ -167,6 +168,7 @@ static struct sde_dbg_base {
struct list_head reg_base_list;
struct dentry *root;
struct device *dev;
+ struct mutex mutex;
struct sde_dbg_power_ctrl power_ctrl;
struct sde_dbg_reg_base *req_dump_blks[SDE_DBG_BASE_MAX];
@@ -1450,6 +1452,8 @@ static void _sde_dump_array(struct sde_dbg_reg_base *blk_arr[],
{
int i;
+ mutex_lock(&sde_dbg_base.mutex);
+
for (i = 0; i < len; i++) {
if (blk_arr[i] != NULL)
_sde_dump_reg_by_ranges(blk_arr[i],
@@ -1466,6 +1470,8 @@ static void _sde_dump_array(struct sde_dbg_reg_base *blk_arr[],
if (do_panic && sde_dbg_base.panic_on_err)
panic(name);
+
+ mutex_unlock(&sde_dbg_base.mutex);
}
/**
@@ -1663,6 +1669,7 @@ int sde_dbg_init(struct dentry *debugfs_root, struct device *dev,
{
int i;
+ mutex_init(&sde_dbg_base.mutex);
INIT_LIST_HEAD(&sde_dbg_base.reg_base_list);
sde_dbg_base.dev = dev;
sde_dbg_base.power_ctrl = *power_ctrl;
@@ -1718,6 +1725,7 @@ void sde_dbg_destroy(void)
sde_dbg_base_evtlog = NULL;
sde_evtlog_destroy(sde_dbg_base.evtlog);
sde_dbg_base.evtlog = NULL;
+ mutex_destroy(&sde_dbg_base.mutex);
}
/**
@@ -1730,11 +1738,14 @@ static int sde_dbg_reg_base_release(struct inode *inode, struct file *file)
{
struct sde_dbg_reg_base *dbg = file->private_data;
+ mutex_lock(&sde_dbg_base.mutex);
if (dbg && dbg->buf) {
kfree(dbg->buf);
dbg->buf_len = 0;
dbg->buf = NULL;
}
+ mutex_unlock(&sde_dbg_base.mutex);
+
return 0;
}
@@ -1753,6 +1764,7 @@ static ssize_t sde_dbg_reg_base_offset_write(struct file *file,
u32 off = 0;
u32 cnt = DEFAULT_BASE_REG_CNT;
char buf[24];
+ ssize_t rc = count;
if (!dbg)
return -ENODEV;
@@ -1768,24 +1780,33 @@ static ssize_t sde_dbg_reg_base_offset_write(struct file *file,
if (sscanf(buf, "%x %x", &off, &cnt) != 2)
return -EFAULT;
- if (off > dbg->max_offset)
- return -EINVAL;
+ mutex_lock(&sde_dbg_base.mutex);
+ if (off > dbg->max_offset) {
+ rc = -EINVAL;
+ goto exit;
+ }
- if (off % sizeof(u32))
- return -EINVAL;
+ if (off % sizeof(u32)) {
+ rc = -EINVAL;
+ goto exit;
+ }
if (cnt > (dbg->max_offset - off))
cnt = dbg->max_offset - off;
- if (cnt % sizeof(u32))
- return -EINVAL;
+ if (cnt % sizeof(u32)) {
+ rc = -EINVAL;
+ goto exit;
+ }
dbg->off = off;
dbg->cnt = cnt;
+exit:
+ mutex_unlock(&sde_dbg_base.mutex);
pr_debug("offset=%x cnt=%x\n", off, cnt);
- return count;
+ return rc;
}
/**
@@ -1808,14 +1829,20 @@ static ssize_t sde_dbg_reg_base_offset_read(struct file *file,
if (*ppos)
return 0; /* the end */
+ mutex_lock(&sde_dbg_base.mutex);
len = snprintf(buf, sizeof(buf), "0x%08zx %zx\n", dbg->off, dbg->cnt);
- if (len < 0 || len >= sizeof(buf))
+ if (len < 0 || len >= sizeof(buf)) {
+ mutex_unlock(&sde_dbg_base.mutex);
return 0;
+ }
- if ((count < sizeof(buf)) || copy_to_user(buff, buf, len))
+ if ((count < sizeof(buf)) || copy_to_user(buff, buf, len)) {
+ mutex_unlock(&sde_dbg_base.mutex);
return -EFAULT;
+ }
*ppos += len; /* increase offset */
+ mutex_unlock(&sde_dbg_base.mutex);
return len;
}
@@ -1851,8 +1878,11 @@ static ssize_t sde_dbg_reg_base_reg_write(struct file *file,
if (cnt < 2)
return -EFAULT;
- if (off >= dbg->max_offset)
+ mutex_lock(&sde_dbg_base.mutex);
+ if (off >= dbg->max_offset) {
+ mutex_unlock(&sde_dbg_base.mutex);
return -EFAULT;
+ }
_sde_dbg_enable_power(true);
@@ -1860,6 +1890,8 @@ static ssize_t sde_dbg_reg_base_reg_write(struct file *file,
_sde_dbg_enable_power(false);
+ mutex_unlock(&sde_dbg_base.mutex);
+
pr_debug("addr=%zx data=%x\n", off, data);
return count;
@@ -1883,6 +1915,7 @@ static ssize_t sde_dbg_reg_base_reg_read(struct file *file,
return -ENODEV;
}
+ mutex_lock(&sde_dbg_base.mutex);
if (!dbg->buf) {
char *hwbuf;
char dump_buf[64];
@@ -1897,12 +1930,15 @@ static ssize_t sde_dbg_reg_base_reg_read(struct file *file,
dbg->buf = kzalloc(dbg->buf_len, GFP_KERNEL);
- if (!dbg->buf)
+ if (!dbg->buf) {
+ mutex_unlock(&sde_dbg_base.mutex);
return -ENOMEM;
+ }
hwbuf = kzalloc(ROW_BYTES, GFP_KERNEL);
if (!hwbuf) {
kfree(dbg->buf);
+ mutex_unlock(&sde_dbg_base.mutex);
return -ENOMEM;
}
@@ -1934,16 +1970,20 @@ static ssize_t sde_dbg_reg_base_reg_read(struct file *file,
kfree(hwbuf);
}
- if (*ppos >= dbg->buf_len)
+ if (*ppos >= dbg->buf_len) {
+ mutex_unlock(&sde_dbg_base.mutex);
return 0; /* done reading */
+ }
len = min(count, dbg->buf_len - (size_t) *ppos);
if (copy_to_user(user_buf, dbg->buf + *ppos, len)) {
+ mutex_unlock(&sde_dbg_base.mutex);
pr_err("failed to copy to user\n");
return -EFAULT;
}
*ppos += len; /* increase offset */
+ mutex_unlock(&sde_dbg_base.mutex);
return len;
}
diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c
index 862d832823f7..fc7799722026 100644
--- a/drivers/gpu/msm/adreno_dispatch.c
+++ b/drivers/gpu/msm/adreno_dispatch.c
@@ -677,7 +677,7 @@ static int sendcmd(struct adreno_device *adreno_dev,
* then set up the timer. If this misses, then preemption is indeed a
* thing and the timer will be set up in due time
*/
- if (!adreno_in_preempt_state(adreno_dev, ADRENO_PREEMPT_NONE)) {
+ if (adreno_in_preempt_state(adreno_dev, ADRENO_PREEMPT_NONE)) {
if (drawqueue_is_current(dispatch_q))
mod_timer(&dispatcher->timer, dispatch_q->expires);
}
diff --git a/drivers/gpu/msm/kgsl_debugfs.c b/drivers/gpu/msm/kgsl_debugfs.c
index 37d92428f02c..592257a332d1 100644
--- a/drivers/gpu/msm/kgsl_debugfs.c
+++ b/drivers/gpu/msm/kgsl_debugfs.c
@@ -299,6 +299,7 @@ static int print_sparse_mem_entry(int id, void *ptr, void *data)
if (!(m->flags & KGSL_MEMFLAGS_SPARSE_VIRT))
return 0;
+ spin_lock(&entry->bind_lock);
node = rb_first(&entry->bind_tree);
while (node != NULL) {
@@ -309,6 +310,7 @@ static int print_sparse_mem_entry(int id, void *ptr, void *data)
obj->v_off, obj->size, obj->p_off);
node = rb_next(node);
}
+ spin_unlock(&entry->bind_lock);
seq_putc(s, '\n');
diff --git a/drivers/media/i2c/adv7481_reg.h b/drivers/media/i2c/adv7481_reg.h
index 60b1301abbe6..b0bb5784d2ef 100644
--- a/drivers/media/i2c/adv7481_reg.h
+++ b/drivers/media/i2c/adv7481_reg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
diff --git a/drivers/media/platform/msm/ais/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/ais/sensor/actuator/msm_actuator.c
index 40806d5a164f..f11c2652728a 100644
--- a/drivers/media/platform/msm/ais/sensor/actuator/msm_actuator.c
+++ b/drivers/media/platform/msm/ais/sensor/actuator/msm_actuator.c
@@ -98,6 +98,11 @@ static void msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl,
return;
}
+ if (a_ctrl->i2c_reg_tbl == NULL) {
+ pr_err("failed. i2c reg tabl is NULL");
+ return;
+ }
+
size = a_ctrl->reg_tbl_size;
write_arr = a_ctrl->reg_tbl;
i2c_tbl = a_ctrl->i2c_reg_tbl;
@@ -1290,9 +1295,11 @@ static int32_t msm_actuator_set_param(struct msm_actuator_ctrl_t *a_ctrl,
if (copy_from_user(&a_ctrl->region_params,
(void __user *)set_info->af_tuning_params.region_params,
- a_ctrl->region_size * sizeof(struct region_params_t)))
+ a_ctrl->region_size * sizeof(struct region_params_t))) {
+ a_ctrl->total_steps = 0;
+ pr_err("Error copying region_params\n");
return -EFAULT;
-
+ }
if (a_ctrl->act_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
cci_client = a_ctrl->i2c_client.cci_client;
cci_client->sid =
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
index 21fab0590b55..34cac9daea89 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -98,6 +98,8 @@ struct msm_isp_buffer {
struct timeval *tv;
/* Indicates whether buffer is used as ping ot pong buffer */
uint32_t pingpong_bit;
+ /* Indicates buffer is reconfig due to drop frame */
+ uint32_t is_drop_reconfig;
/*Native buffer*/
struct list_head list;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
index 22eb86f4f875..23e27e1179d1 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
@@ -453,11 +453,69 @@ static long msm_isp_v4l2_fops_ioctl(struct file *file, unsigned int cmd,
return video_usercopy(file, cmd, arg, msm_isp_subdev_do_ioctl);
}
+static void isp_vma_open(struct vm_area_struct *vma)
+{
+ pr_debug("%s: open called\n", __func__);
+}
+
+static void isp_vma_close(struct vm_area_struct *vma)
+{
+ pr_debug("%s: close called\n", __func__);
+}
+
+static int isp_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ struct page *page;
+ struct vfe_device *vfe_dev = vma->vm_private_data;
+ struct isp_proc *isp_page = NULL;
+
+ isp_page = vfe_dev->isp_page;
+
+ pr_debug("%s: vfeid:%d u_virt_addr:0x%lx k_virt_addr:%pK\n",
+ __func__, vfe_dev->pdev->id, vma->vm_start,
+ (void *)isp_page);
+ if (isp_page != NULL) {
+ page = virt_to_page(isp_page);
+ get_page(page);
+ vmf->page = page;
+ isp_page->kernel_sofid =
+ vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
+ isp_page->vfeid = vfe_dev->pdev->id;
+ }
+ return 0;
+}
+
+static const struct vm_operations_struct isp_vm_ops = {
+ .open = isp_vma_open,
+ .close = isp_vma_close,
+ .fault = isp_vma_fault,
+};
+
+static int msm_isp_v4l2_fops_mmap(struct file *filep,
+ struct vm_area_struct *vma)
+{
+ int ret = -EINVAL;
+ struct video_device *vdev = video_devdata(filep);
+ struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
+ struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
+
+ vma->vm_ops = &isp_vm_ops;
+ vma->vm_flags |=
+ (unsigned long)(VM_DONTEXPAND | VM_DONTDUMP);
+ vma->vm_private_data = vfe_dev;
+ isp_vma_open(vma);
+ ret = 0;
+ pr_debug("%s: isp mmap is called vm_start: 0x%lx\n",
+ __func__, vma->vm_start);
+ return ret;
+}
+
static struct v4l2_file_operations msm_isp_v4l2_fops = {
#ifdef CONFIG_COMPAT
.compat_ioctl32 = msm_isp_v4l2_fops_ioctl,
#endif
- .unlocked_ioctl = msm_isp_v4l2_fops_ioctl
+ .unlocked_ioctl = msm_isp_v4l2_fops_ioctl,
+ .mmap = msm_isp_v4l2_fops_mmap
};
static int vfe_set_common_data(struct platform_device *pdev)
@@ -671,6 +729,8 @@ int vfe_hw_probe(struct platform_device *pdev)
msm_isp_v4l2_fops.compat_ioctl32 =
msm_isp_v4l2_fops_ioctl;
#endif
+ msm_isp_v4l2_fops.mmap = msm_isp_v4l2_fops_mmap;
+
vfe_dev->subdev.sd.devnode->fops = &msm_isp_v4l2_fops;
vfe_dev->buf_mgr = &vfe_buf_mgr;
@@ -687,6 +747,14 @@ int vfe_hw_probe(struct platform_device *pdev)
msm_isp_enable_debugfs(vfe_dev, msm_isp_bw_request_history);
vfe_dev->buf_mgr->init_done = 1;
vfe_dev->vfe_open_cnt = 0;
+ /*Allocate a page in kernel and map it to camera user process*/
+ vfe_dev->isp_page = (struct isp_proc *)get_zeroed_page(GFP_KERNEL);
+ if (vfe_dev->isp_page == NULL) {
+ pr_err("%s: no enough memory\n", __func__);
+ rc = -ENOMEM;
+ goto probe_fail3;
+ }
+ vfe_dev->isp_page->vfeid = vfe_dev->pdev->id;
return rc;
probe_fail3:
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index b2d152bf4ef0..d336e1ef1bd7 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -759,6 +759,11 @@ struct msm_vfe_common_subdev {
struct msm_vfe_common_dev_data *common_data;
};
+struct isp_proc {
+ uint32_t kernel_sofid;
+ uint32_t vfeid;
+};
+
struct vfe_device {
/* Driver private data */
struct platform_device *pdev;
@@ -842,6 +847,7 @@ struct vfe_device {
uint32_t recovery_irq1_mask;
/* total bandwidth per vfe */
uint64_t total_bandwidth;
+ struct isp_proc *isp_page;
};
struct vfe_parent_device {
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index e04229fed666..d3c418511ece 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -1342,6 +1342,7 @@ static void msm_vfe40_cfg_camif(struct vfe_device *vfe_dev,
struct msm_vfe_pix_cfg *pix_cfg)
{
uint16_t first_pixel, last_pixel, first_line, last_line;
+ uint16_t epoch_line1;
struct msm_vfe_camif_cfg *camif_cfg = &pix_cfg->camif_cfg;
uint32_t val, subsample_period, subsample_pattern;
struct msm_vfe_camif_subsample_cfg *subsample_cfg =
@@ -1357,6 +1358,14 @@ static void msm_vfe40_cfg_camif(struct vfe_device *vfe_dev,
last_pixel = camif_cfg->last_pixel;
first_line = camif_cfg->first_line;
last_line = camif_cfg->last_line;
+ epoch_line1 = camif_cfg->epoch_line1;
+
+ if ((epoch_line1 <= 0) || (epoch_line1 > last_line))
+ epoch_line1 = last_line - 50;
+
+ if ((last_line - epoch_line1) > 100)
+ epoch_line1 = last_line - 100;
+
subsample_period = camif_cfg->subsample_cfg.irq_subsample_period;
subsample_pattern = camif_cfg->subsample_cfg.irq_subsample_pattern;
@@ -1368,6 +1377,14 @@ static void msm_vfe40_cfg_camif(struct vfe_device *vfe_dev,
msm_camera_io_w(first_line << 16 | last_line,
vfe_dev->vfe_base + 0x308);
+
+ /*configure EPOCH0: 20 lines, and
+ * configure EPOCH1: epoch_line1 before EOF
+ */
+ msm_camera_io_w_mb(0x140000 | epoch_line1,
+ vfe_dev->vfe_base + 0x318);
+ pr_debug("%s:%d: epoch_line1: %d\n",
+ __func__, __LINE__, epoch_line1);
if (subsample_period && subsample_pattern) {
val = msm_camera_io_r(vfe_dev->vfe_base + 0x2F8);
val &= 0xFFE0FFFF;
@@ -1489,9 +1506,8 @@ static void msm_vfe40_update_camif_state(struct vfe_device *vfe_dev,
msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x30);
msm_camera_io_w_mb(0x81, vfe_dev->vfe_base + 0x34);
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x24);
- msm_vfe40_config_irq(vfe_dev, 0xF7, 0x81,
+ msm_vfe40_config_irq(vfe_dev, 0xFF, 0x81,
MSM_ISP_IRQ_ENABLE);
- msm_camera_io_w_mb(0x140000, vfe_dev->vfe_base + 0x318);
bus_en =
((vfe_dev->axi_data.
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
index 70950a88fc66..146ed1f14467 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
@@ -699,7 +699,7 @@ void msm_vfe47_process_epoch_irq(struct vfe_device *vfe_dev,
void msm_isp47_preprocess_camif_irq(struct vfe_device *vfe_dev,
uint32_t irq_status0)
{
- if (irq_status0 & BIT(1))
+ if (irq_status0 & BIT(3))
vfe_dev->axi_data.src_info[VFE_PIX_0].accept_frame = false;
if (irq_status0 & BIT(0))
vfe_dev->axi_data.src_info[VFE_PIX_0].accept_frame = true;
@@ -788,7 +788,7 @@ long msm_vfe47_reset_hardware(struct vfe_device *vfe_dev,
msm_camera_io_w(0xFFFFFEFF, vfe_dev->vfe_base + 0x68);
msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x58);
vfe_dev->hw_info->vfe_ops.axi_ops.
- reload_wm(vfe_dev, vfe_dev->vfe_base, 0x0031FFFF);
+ reload_wm(vfe_dev, vfe_dev->vfe_base, 0x0011FFFF);
}
if (blocking_call) {
@@ -1368,6 +1368,7 @@ void msm_vfe47_cfg_camif(struct vfe_device *vfe_dev,
struct msm_vfe_pix_cfg *pix_cfg)
{
uint16_t first_pixel, last_pixel, first_line, last_line;
+ uint16_t epoch_line1;
struct msm_vfe_camif_cfg *camif_cfg = &pix_cfg->camif_cfg;
struct msm_vfe_testgen_cfg *testgen_cfg = &pix_cfg->testgen_cfg;
uint32_t val, subsample_period, subsample_pattern;
@@ -1390,6 +1391,14 @@ void msm_vfe47_cfg_camif(struct vfe_device *vfe_dev,
last_pixel = camif_cfg->last_pixel;
first_line = camif_cfg->first_line;
last_line = camif_cfg->last_line;
+ epoch_line1 = camif_cfg->epoch_line1;
+
+ if ((epoch_line1 <= 0) || (epoch_line1 > last_line))
+ epoch_line1 = last_line - 50;
+
+ if ((last_line - epoch_line1) > 100)
+ epoch_line1 = last_line - 100;
+
subsample_period = camif_cfg->subsample_cfg.irq_subsample_period;
subsample_pattern = camif_cfg->subsample_cfg.irq_subsample_pattern;
@@ -1420,6 +1429,13 @@ void msm_vfe47_cfg_camif(struct vfe_device *vfe_dev,
msm_camera_io_w(first_line << 16 | last_line,
vfe_dev->vfe_base + 0x48C);
+ /*configure EPOCH0: 20 lines, and
+ * configure EPOCH1: epoch_line1 before EOF
+ */
+ msm_camera_io_w_mb(0x140000 | epoch_line1,
+ vfe_dev->vfe_base + 0x4A0);
+ pr_debug("%s:%d: epoch_line1: %d\n",
+ __func__, __LINE__, epoch_line1);
msm_camera_io_w(((irq_sub_period - 1) << 8) | 0 << 5 |
(frame_sub_period - 1), vfe_dev->vfe_base + 0x494);
msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x498);
@@ -1597,7 +1613,7 @@ void msm_vfe47_update_camif_state(struct vfe_device *vfe_dev,
val = msm_camera_io_r(vfe_dev->vfe_base + 0x47C);
if (update_state == ENABLE_CAMIF) {
vfe_dev->hw_info->vfe_ops.irq_ops.config_irq(vfe_dev,
- 0x15, 0x91,
+ 0x1F, 0x91,
MSM_ISP_IRQ_ENABLE);
if ((vfe_dev->hvx_cmd > HVX_DISABLE) &&
@@ -1618,8 +1634,6 @@ void msm_vfe47_update_camif_state(struct vfe_device *vfe_dev,
msm_camera_io_w(val, vfe_dev->vfe_base + 0x47C);
msm_camera_io_w_mb(0x4, vfe_dev->vfe_base + 0x478);
msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x478);
- /* configure EPOCH0 for 20 lines */
- msm_camera_io_w_mb(0x140000, vfe_dev->vfe_base + 0x4A0);
/* testgen GO*/
if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN)
msm_camera_io_w(1, vfe_dev->vfe_base + 0xC58);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index 5bcb3034b82a..15f8061b9919 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -719,13 +719,7 @@ void msm_isp_check_for_output_error(struct vfe_device *vfe_dev,
sof_info->stream_get_buf_fail_mask = 0;
axi_data = &vfe_dev->axi_data;
- /* report that registers are not updated and return empty buffer for
- * controllable outputs
- */
- if (!vfe_dev->reg_updated) {
- sof_info->regs_not_updated =
- vfe_dev->reg_update_requested;
- }
+
for (i = 0; i < RDI_INTF_0; i++) {
stream_info = msm_isp_get_stream_common_data(vfe_dev,
i);
@@ -747,6 +741,12 @@ void msm_isp_check_for_output_error(struct vfe_device *vfe_dev,
if (stream_info->controllable_output &&
!vfe_dev->reg_updated) {
if (stream_info->undelivered_request_cnt) {
+ /*report that registers are not updated
+ * and return empty buffer for controllable
+ * outputs
+ */
+ sof_info->regs_not_updated =
+ !vfe_dev->reg_updated;
pr_err("Drop frame no reg update\n");
if (msm_isp_drop_frame(vfe_dev, stream_info, ts,
sof_info)) {
@@ -933,6 +933,8 @@ void msm_isp_increment_frame_id(struct vfe_device *vfe_dev,
}
if (frame_src == VFE_PIX_0) {
+ vfe_dev->isp_page->kernel_sofid =
+ vfe_dev->axi_data.src_info[frame_src].frame_id;
if (!src_info->frame_id &&
!src_info->reg_update_frame_id &&
((src_info->frame_id -
@@ -1646,23 +1648,30 @@ static void msm_isp_reload_ping_pong_offset(
}
static int msm_isp_update_deliver_count(struct vfe_device *vfe_dev,
- struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_bit)
+ struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_bit,
+ struct msm_isp_buffer *done_buf)
{
int rc = 0;
if (!stream_info->controllable_output)
goto done;
- if (!stream_info->undelivered_request_cnt) {
+ if (!stream_info->undelivered_request_cnt ||
+ (done_buf == NULL)) {
pr_err_ratelimited("%s:%d error undelivered_request_cnt 0\n",
__func__, __LINE__);
rc = -EINVAL;
goto done;
} else {
+ if ((done_buf->is_drop_reconfig == 1) &&
+ (stream_info->sw_ping_pong_bit == -1)) {
+ goto done;
+ }
/*After wm reload, we get bufdone for ping buffer*/
if (stream_info->sw_ping_pong_bit == -1)
stream_info->sw_ping_pong_bit = 0;
- stream_info->undelivered_request_cnt--;
+ if (done_buf->is_drop_reconfig != 1)
+ stream_info->undelivered_request_cnt--;
if (pingpong_bit != stream_info->sw_ping_pong_bit) {
pr_err("%s:%d ping pong bit actual %d sw %d\n",
__func__, __LINE__, pingpong_bit,
@@ -1908,7 +1917,8 @@ int msm_isp_cfg_offline_ping_pong_address(struct vfe_device *vfe_dev,
}
static int msm_isp_cfg_ping_pong_address(
- struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status)
+ struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status,
+ struct msm_isp_buffer *buf)
{
int i;
int j;
@@ -1917,7 +1927,6 @@ static int msm_isp_cfg_ping_pong_address(
uint32_t buffer_size_byte = 0;
int32_t word_per_line = 0;
dma_addr_t paddr;
- struct msm_isp_buffer *buf = NULL;
/* Isolate pingpong_bit from pingpong_status */
@@ -1928,10 +1937,11 @@ static int msm_isp_cfg_ping_pong_address(
if (stream_info->buf[!pingpong_bit]) {
pr_err("stream %x buffer already set for pingpong %d\n",
stream_info->stream_src, !pingpong_bit);
- return 0;
+ return 1;
}
- buf = msm_isp_get_stream_buffer(vfe_dev, stream_info);
+ if (buf == NULL)
+ buf = msm_isp_get_stream_buffer(vfe_dev, stream_info);
if (!buf) {
msm_isp_cfg_stream_scratch(stream_info, pingpong_status);
@@ -2165,6 +2175,7 @@ int msm_isp_drop_frame(struct vfe_device *vfe_dev,
struct msm_isp_bufq *bufq = NULL;
uint32_t pingpong_bit;
int vfe_idx;
+ int rc = -1;
if (!vfe_dev || !stream_info || !ts || !sof_info) {
pr_err("%s %d vfe_dev %pK stream_info %pK ts %pK op_info %pK\n",
@@ -2181,17 +2192,42 @@ int msm_isp_drop_frame(struct vfe_device *vfe_dev,
pingpong_bit =
(~(pingpong_status >> stream_info->wm[vfe_idx][0]) & 0x1);
done_buf = stream_info->buf[pingpong_bit];
- if (done_buf) {
- bufq = vfe_dev->buf_mgr->ops->get_bufq(vfe_dev->buf_mgr,
- done_buf->bufq_handle);
- if (!bufq) {
- spin_unlock_irqrestore(&stream_info->lock, flags);
- pr_err("%s: Invalid bufq buf_handle %x\n",
- __func__, done_buf->bufq_handle);
- return -EINVAL;
+ if (done_buf &&
+ (stream_info->composite_irq[MSM_ISP_COMP_IRQ_EPOCH] == 0)) {
+ if ((stream_info->sw_ping_pong_bit != -1) &&
+ !vfe_dev->reg_updated) {
+ rc = msm_isp_cfg_ping_pong_address(
+ stream_info, ~pingpong_status, done_buf);
+ if (rc < 0) {
+ ISP_DBG("%s: Error configuring ping_pong\n",
+ __func__);
+ bufq = vfe_dev->buf_mgr->ops->get_bufq(
+ vfe_dev->buf_mgr,
+ done_buf->bufq_handle);
+ if (!bufq) {
+ spin_unlock_irqrestore(
+ &stream_info->lock,
+ flags);
+ pr_err("%s: Invalid bufq buf_handle %x\n",
+ __func__,
+ done_buf->bufq_handle);
+ return -EINVAL;
+ }
+ sof_info->reg_update_fail_mask_ext |=
+ (bufq->bufq_handle & 0xFF);
+ }
+ }
+ /*Avoid Drop Frame and re-issue pingpong cfg*/
+ /*this notify is per ping and pong buffer*/
+ done_buf->is_drop_reconfig = 1;
+ stream_info->current_framedrop_period = 1;
+ /*Avoid Multiple request frames for single SOF*/
+ vfe_dev->axi_data.src_info[VFE_PIX_0].accept_frame = false;
+
+ if (stream_info->current_framedrop_period !=
+ stream_info->requested_framedrop_period) {
+ msm_isp_cfg_framedrop_reg(stream_info);
}
- sof_info->reg_update_fail_mask_ext |=
- (bufq->bufq_handle & 0xFF);
}
spin_unlock_irqrestore(&stream_info->lock, flags);
@@ -2201,6 +2237,8 @@ int msm_isp_drop_frame(struct vfe_device *vfe_dev,
/* no buf done come */
msm_isp_process_axi_irq_stream(vfe_dev, stream_info,
pingpong_status, ts);
+ if (done_buf)
+ done_buf->is_drop_reconfig = 0;
}
return 0;
}
@@ -2505,7 +2543,7 @@ static int msm_isp_init_stream_ping_pong_reg(
/* Set address for both PING & PO NG register */
rc = msm_isp_cfg_ping_pong_address(
- stream_info, VFE_PING_FLAG);
+ stream_info, VFE_PING_FLAG, NULL);
/* No buffer available on start is not error */
if (rc == -ENOMEM && stream_info->stream_type != BURST_STREAM)
return 0;
@@ -2517,7 +2555,7 @@ static int msm_isp_init_stream_ping_pong_reg(
if (stream_info->stream_type != BURST_STREAM ||
stream_info->runtime_num_burst_capture > 1) {
rc = msm_isp_cfg_ping_pong_address(
- stream_info, VFE_PONG_FLAG);
+ stream_info, VFE_PONG_FLAG, NULL);
/* No buffer available on start is not error */
if (rc == -ENOMEM)
return 0;
@@ -3516,7 +3554,7 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
if (stream_info->undelivered_request_cnt == 1) {
rc = msm_isp_cfg_ping_pong_address(stream_info,
- VFE_PING_FLAG);
+ VFE_PING_FLAG, NULL);
if (rc) {
spin_unlock_irqrestore(&stream_info->lock, flags);
stream_info->undelivered_request_cnt--;
@@ -3549,10 +3587,10 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
* now.
*/
rc = msm_isp_cfg_ping_pong_address(stream_info,
- VFE_PONG_FLAG);
+ VFE_PONG_FLAG, NULL);
} else {
rc = msm_isp_cfg_ping_pong_address(
- stream_info, pingpong_status);
+ stream_info, pingpong_status, NULL);
}
if (rc) {
stream_info->undelivered_request_cnt--;
@@ -3574,6 +3612,9 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
if (0 == rc)
msm_isp_reset_framedrop(vfe_dev, stream_info);
+ /*Avoid Multiple request frames for single SOF*/
+ vfe_dev->axi_data.src_info[frame_src].accept_frame = false;
+
spin_unlock_irqrestore(&stream_info->lock, flags);
return rc;
@@ -4057,6 +4098,10 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev,
done_buf = stream_info->buf[pingpong_bit];
if (vfe_dev->buf_mgr->frameId_mismatch_recovery == 1) {
+ if (done_buf) {
+ if (done_buf->is_drop_reconfig == 1)
+ done_buf->is_drop_reconfig = 0;
+ }
pr_err_ratelimited("%s: Mismatch Recovery in progress, drop frame!\n",
__func__);
spin_unlock_irqrestore(&stream_info->lock, flags);
@@ -4076,14 +4121,26 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev,
stream_info->frame_id++;
stream_info->buf[pingpong_bit] = NULL;
+ if (stream_info->controllable_output &&
+ (done_buf != NULL) &&
+ (stream_info->sw_ping_pong_bit == -1) &&
+ (done_buf->is_drop_reconfig == 1)) {
+ /*When wm reloaded and corresponding reg_update fail
+ * then buffer is reconfig as PING buffer. so, avoid
+ * NULL assignment to PING buffer and eventually
+ * next AXI_DONE or buf_done can be successful
+ */
+ stream_info->buf[pingpong_bit] = done_buf;
+ }
+
if (stream_info->stream_type == CONTINUOUS_STREAM ||
stream_info->runtime_num_burst_capture > 1) {
rc = msm_isp_cfg_ping_pong_address(
- stream_info, pingpong_status);
+ stream_info, pingpong_status, NULL);
if (rc < 0)
ISP_DBG("%s: Error configuring ping_pong\n",
__func__);
- } else if (done_buf) {
+ } else if (done_buf && (done_buf->is_drop_reconfig != 1)) {
msm_isp_cfg_stream_scratch(stream_info, pingpong_status);
}
@@ -4107,8 +4164,10 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev,
}
rc = msm_isp_update_deliver_count(vfe_dev, stream_info,
- pingpong_bit);
+ pingpong_bit, done_buf);
if (rc) {
+ if (done_buf->is_drop_reconfig == 1)
+ done_buf->is_drop_reconfig = 0;
spin_unlock_irqrestore(&stream_info->lock, flags);
pr_err_ratelimited("%s:VFE%d get done buf fail\n",
__func__, vfe_dev->pdev->id);
@@ -4117,17 +4176,28 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev,
return;
}
- spin_unlock_irqrestore(&stream_info->lock, flags);
if ((done_buf->frame_id != frame_id) &&
vfe_dev->axi_data.enable_frameid_recovery) {
+ if (done_buf->is_drop_reconfig == 1)
+ done_buf->is_drop_reconfig = 0;
+ spin_unlock_irqrestore(&stream_info->lock, flags);
msm_isp_handle_done_buf_frame_id_mismatch(vfe_dev,
stream_info, done_buf, time_stamp, frame_id);
return;
}
- msm_isp_process_done_buf(vfe_dev, stream_info,
+ if (done_buf->is_drop_reconfig == 1) {
+ /*When ping/pong buf is already reconfigured
+ * then dont issue buf-done for current buffer
+ */
+ done_buf->is_drop_reconfig = 0;
+ spin_unlock_irqrestore(&stream_info->lock, flags);
+ } else {
+ spin_unlock_irqrestore(&stream_info->lock, flags);
+ msm_isp_process_done_buf(vfe_dev, stream_info,
done_buf, time_stamp, frame_id);
+ }
}
void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c
index 194a6583103e..6a969401e950 100644
--- a/drivers/media/platform/msm/camera_v2/msm.c
+++ b/drivers/media/platform/msm/camera_v2/msm.c
@@ -35,6 +35,7 @@
static struct v4l2_device *msm_v4l2_dev;
static struct list_head ordered_sd_list;
static struct mutex ordered_sd_mtx;
+static struct mutex v4l2_event_mtx;
static struct pm_qos_request msm_v4l2_pm_qos_request;
@@ -852,13 +853,25 @@ static long msm_private_ioctl(struct file *file, void *fh,
static int msm_unsubscribe_event(struct v4l2_fh *fh,
const struct v4l2_event_subscription *sub)
{
- return v4l2_event_unsubscribe(fh, sub);
+ int rc;
+
+ mutex_lock(&v4l2_event_mtx);
+ rc = v4l2_event_unsubscribe(fh, sub);
+ mutex_unlock(&v4l2_event_mtx);
+
+ return rc;
}
static int msm_subscribe_event(struct v4l2_fh *fh,
const struct v4l2_event_subscription *sub)
{
- return v4l2_event_subscribe(fh, sub, 5, NULL);
+ int rc;
+
+ mutex_lock(&v4l2_event_mtx);
+ rc = v4l2_event_subscribe(fh, sub, 5, NULL);
+ mutex_unlock(&v4l2_event_mtx);
+
+ return rc;
}
static const struct v4l2_ioctl_ops g_msm_ioctl_ops = {
@@ -1376,6 +1389,7 @@ static int msm_probe(struct platform_device *pdev)
spin_lock_init(&msm_eventq_lock);
spin_lock_init(&msm_pid_lock);
mutex_init(&ordered_sd_mtx);
+ mutex_init(&v4l2_event_mtx);
INIT_LIST_HEAD(&ordered_sd_list);
cam_debugfs_root = debugfs_create_dir(MSM_CAM_LOGSYNC_FILE_BASEDIR,
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/include/msm_csid_3_5_1_hwreg.h b/drivers/media/platform/msm/camera_v2/sensor/csid/include/msm_csid_3_5_1_hwreg.h
new file mode 100644
index 000000000000..13e560dc207d
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/csid/include/msm_csid_3_5_1_hwreg.h
@@ -0,0 +1,64 @@
+/* Copyright (c) 2015, 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_CSID_3_5_1_HWREG_H
+#define MSM_CSID_3_5_1_HWREG_H
+
+#include <sensor/csid/msm_csid.h>
+
+static uint8_t csid_lane_assign_v3_5_1[PHY_LANE_MAX] = {0, 4, 1, 2, 3};
+
+static struct csid_reg_parms_t csid_v3_5_1 = {
+ /* MIPI CSID registers */
+ 0x0,
+ 0x4,
+ 0x8,
+ 0x10,
+ 0x14,
+ 0x18,
+ 0x1C,
+ 0x20,
+ 0x24,
+ 0x64,
+ 0x68,
+ 0x6C,
+ 0x70,
+ 0x74,
+ 0x78,
+ 0x7C,
+ 0x80,
+ 0x88,
+ 0x8C,
+ 0x90,
+ 0x94,
+ 0x98,
+ 0x9C,
+ 0xA0,
+ 0xA8,
+ 0xAC,
+ 0xB4,
+ 0xB8,
+ 0xBC,
+ 11,
+ 0x7FFF,
+ 0x4,
+ 17,
+ 0x30050001,
+ 0xC,
+ 0x84,
+ 0xA4,
+ 0x7f010800,
+ 20,
+ 17,
+ 16,
+};
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
index 7ae071176ef4..9473fb0dc44e 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
@@ -27,6 +27,7 @@
#include "include/msm_csid_3_4_1_hwreg.h"
#include "include/msm_csid_3_4_2_hwreg.h"
#include "include/msm_csid_3_6_0_hwreg.h"
+#include "include/msm_csid_3_5_1_hwreg.h"
#include "cam_hw_ops.h"
#define V4L2_IDENT_CSID 50002
@@ -44,6 +45,7 @@
#define CSID_VERSION_V36 0x30060000
#define CSID_VERSION_V37 0x30070000
#define CSID_VERSION_V35 0x30050000
+#define CSID_VERSION_V35_1 0x30050001
#define CSID_VERSION_V40 0x40000000
#define CSID_VERSION_V50 0x50000000
#define MSM_CSID_DRV_NAME "msm_csid"
@@ -1186,6 +1188,12 @@ static int csid_probe(struct platform_device *pdev)
csid_lane_assign_v3_5;
new_csid_dev->hw_dts_version = CSID_VERSION_V35;
} else if (of_device_is_compatible(new_csid_dev->pdev->dev.of_node,
+ "qcom,csid-v3.5.1")) {
+ new_csid_dev->ctrl_reg->csid_reg = csid_v3_5_1;
+ new_csid_dev->ctrl_reg->csid_lane_assign =
+ csid_lane_assign_v3_5_1;
+ new_csid_dev->hw_dts_version = CSID_VERSION_V35_1;
+ } else if (of_device_is_compatible(new_csid_dev->pdev->dev.of_node,
"qcom,csid-v5.0")) {
new_csid_dev->ctrl_reg->csid_reg = csid_v3_5;
new_csid_dev->ctrl_reg->csid_lane_assign =
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
index 8d091320cbca..a8d7c1f8b489 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
@@ -437,6 +437,11 @@ static int msm_csiphy_2phase_lane_config(
csiphybase = csiphy_dev->base;
lane_mask = csiphy_params->lane_mask & 0x1f;
+
+ lane_enable = msm_camera_io_r(csiphybase +
+ csiphy_dev->ctrl_reg->csiphy_3ph_reg.
+ mipi_csiphy_3ph_cmn_ctrl5.addr);
+
for (i = 0; i < MAX_DPHY_DATA_LN; i++) {
if (mask == 0x2) {
if (lane_mask & mask)
@@ -474,7 +479,11 @@ static int msm_csiphy_2phase_lane_config(
clk_lane = 0;
}
- if (csiphy_params->combo_mode == 1) {
+ /* In combo mode setting the 4th lane
+ * as clk_lane for 1 lane sensor, checking
+ * the lane_mask == 0x18 for one lane sensor
+ */
+ if ((csiphy_params->combo_mode == 1) && (lane_mask == 0x18)) {
val |= 0xA;
if (mask == csiphy_dev->ctrl_reg->
csiphy_reg.combo_clk_mask) {
@@ -520,6 +529,12 @@ static int msm_csiphy_2phase_lane_config(
mipi_csiphy_2ph_lnn_cfg4.data, csiphybase +
csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg4.addr + offset);
+ if (lane_mask == 0x18)
+ msm_camera_io_w(0x80,
+ csiphybase +
+ csiphy_dev->ctrl_reg->csiphy_3ph_reg.
+ mipi_csiphy_2ph_lnn_cfg1.addr + offset);
+
} else {
msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg1.data,
@@ -540,8 +555,8 @@ static int msm_csiphy_2phase_lane_config(
csiphy_dev->ctrl_reg->csiphy_3ph_reg.
mipi_csiphy_2ph_lnn_cfg5.addr + offset);
}
- if (clk_lane == 1 &&
- csiphy_dev->hw_version == CSIPHY_VERSION_V342) {
+ if (clk_lane == 1 && lane_mask != 0x18 &&
+ (csiphy_dev->hw_version == CSIPHY_VERSION_V342)) {
msm_camera_io_w(0x1f,
csiphybase +
csiphy_dev->ctrl_reg->csiphy_3ph_reg.
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
index 167ed5492088..3f180735dd95 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
@@ -1428,8 +1428,8 @@ static int32_t msm_sensor_driver_i2c_probe(struct i2c_client *client,
rc);
goto FREE_S_CTRL;
}
- return rc;
}
+ return rc;
FREE_S_CTRL:
kfree(s_ctrl);
return rc;
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
index 08bbed147c86..76e1b60512d0 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
@@ -2009,6 +2009,18 @@ ioctl32_error:
}
#endif
+static int sde_rotator_ctrl_subscribe_event(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub)
+{
+ return -EINVAL;
+}
+
+static int sde_rotator_event_unsubscribe(struct v4l2_fh *fh,
+ const struct v4l2_event_subscription *sub)
+{
+ return -EINVAL;
+}
+
/* V4l2 ioctl handlers */
static const struct v4l2_ioctl_ops sde_rotator_ioctl_ops = {
.vidioc_querycap = sde_rotator_querycap,
@@ -2033,8 +2045,8 @@ static const struct v4l2_ioctl_ops sde_rotator_ioctl_ops = {
.vidioc_s_parm = sde_rotator_s_parm,
.vidioc_default = sde_rotator_private_ioctl,
.vidioc_log_status = v4l2_ctrl_log_status,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ .vidioc_subscribe_event = sde_rotator_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = sde_rotator_event_unsubscribe,
};
/*
diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
index de5a2dececdf..e81162f3c4ad 100644
--- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
@@ -456,14 +456,15 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev)
struct device *dev;
int nr = BASE_DEVICE_NUMBER;
- core = kzalloc(sizeof(*core), GFP_KERNEL);
- if (!core || !vidc_driver) {
- dprintk(VIDC_ERR,
- "Failed to allocate memory for device core\n");
- rc = -ENOMEM;
- goto err_no_mem;
+ if (!vidc_driver) {
+ dprintk(VIDC_ERR, "Invalid vidc driver\n");
+ return -EINVAL;
}
+ core = kzalloc(sizeof(*core), GFP_KERNEL);
+ if (!core)
+ return -ENOMEM;
+
dev_set_drvdata(&pdev->dev, core);
rc = msm_vidc_initialize_core(pdev, core);
if (rc) {
@@ -628,7 +629,6 @@ err_v4l2_register:
err_core_init:
dev_set_drvdata(&pdev->dev, NULL);
kfree(core);
-err_no_mem:
return rc;
}
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index c80f535d95e1..5959f61c677c 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -1957,6 +1957,8 @@ const struct vb2_ops *msm_vdec_get_vb2q_ops(void)
int msm_vdec_inst_init(struct msm_vidc_inst *inst)
{
int rc = 0;
+ struct msm_vidc_format *fmt = NULL;
+
if (!inst) {
dprintk(VIDC_ERR, "Invalid input = %pK\n", inst);
return -EINVAL;
@@ -1964,12 +1966,34 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
inst->prop.height[CAPTURE_PORT] = DEFAULT_HEIGHT;
inst->prop.width[CAPTURE_PORT] = DEFAULT_WIDTH;
inst->prop.num_planes[CAPTURE_PORT] = 2;
- inst->fmts[CAPTURE_PORT] = vdec_formats[0];
+
+ /* By default, initialize CAPTURE port to NV12 format */
+ fmt = msm_comm_get_pixel_fmt_fourcc(vdec_formats,
+ ARRAY_SIZE(vdec_formats), V4L2_PIX_FMT_NV12,
+ CAPTURE_PORT);
+ if (!fmt || fmt->type != CAPTURE_PORT) {
+ dprintk(VIDC_ERR,
+ "vdec_formats corrupted\n");
+ return -EINVAL;
+ }
+ memcpy(&inst->fmts[fmt->type], fmt,
+ sizeof(struct msm_vidc_format));
inst->prop.height[OUTPUT_PORT] = DEFAULT_HEIGHT;
inst->prop.width[OUTPUT_PORT] = DEFAULT_WIDTH;
inst->prop.num_planes[OUTPUT_PORT] = 1;
- inst->fmts[OUTPUT_PORT] = vdec_formats[2];
+
+ /* By default, initialize OUTPUT port to H264 decoder */
+ fmt = msm_comm_get_pixel_fmt_fourcc(vdec_formats,
+ ARRAY_SIZE(vdec_formats), V4L2_PIX_FMT_H264,
+ OUTPUT_PORT);
+ if (!fmt || fmt->type != OUTPUT_PORT) {
+ dprintk(VIDC_ERR,
+ "vdec_formats corrupted\n");
+ return -EINVAL;
+ }
+ memcpy(&inst->fmts[fmt->type], fmt,
+ sizeof(struct msm_vidc_format));
inst->capability.height.min = MIN_SUPPORTED_HEIGHT;
inst->capability.height.max = DEFAULT_HEIGHT;
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index ec6695a670b0..ebdafd66e590 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -4096,6 +4096,8 @@ const struct v4l2_ctrl_ops *msm_venc_get_ctrl_ops(void)
int msm_venc_inst_init(struct msm_vidc_inst *inst)
{
int rc = 0;
+ struct msm_vidc_format *fmt = NULL;
+
if (!inst) {
dprintk(VIDC_ERR, "Invalid input = %pK\n", inst);
return -EINVAL;
@@ -4103,12 +4105,34 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
inst->prop.height[CAPTURE_PORT] = DEFAULT_HEIGHT;
inst->prop.width[CAPTURE_PORT] = DEFAULT_WIDTH;
inst->prop.num_planes[CAPTURE_PORT] = 1;
- inst->fmts[CAPTURE_PORT] = venc_formats[4];
+
+ /* By default, initialize CAPTURE port to H264 encoder */
+ fmt = msm_comm_get_pixel_fmt_fourcc(venc_formats,
+ ARRAY_SIZE(venc_formats), V4L2_PIX_FMT_H264,
+ CAPTURE_PORT);
+ if (!fmt || fmt->type != CAPTURE_PORT) {
+ dprintk(VIDC_ERR,
+ "venc_formats corrupted\n");
+ return -EINVAL;
+ }
+ memcpy(&inst->fmts[fmt->type], fmt,
+ sizeof(struct msm_vidc_format));
inst->prop.height[OUTPUT_PORT] = DEFAULT_HEIGHT;
inst->prop.width[OUTPUT_PORT] = DEFAULT_WIDTH;
inst->prop.num_planes[OUTPUT_PORT] = 1;
- inst->fmts[OUTPUT_PORT] = venc_formats[0];
+
+ /* By default, initialize OUTPUT port to NV12 format */
+ fmt = msm_comm_get_pixel_fmt_fourcc(venc_formats,
+ ARRAY_SIZE(venc_formats), V4L2_PIX_FMT_NV12,
+ OUTPUT_PORT);
+ if (!fmt || fmt->type != OUTPUT_PORT) {
+ dprintk(VIDC_ERR,
+ "venc_formats corrupted\n");
+ return -EINVAL;
+ }
+ memcpy(&inst->fmts[fmt->type], fmt,
+ sizeof(struct msm_vidc_format));
inst->capability.height.min = MIN_SUPPORTED_HEIGHT;
inst->capability.height.max = DEFAULT_HEIGHT;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index a343bc2d59e4..02bfc459614f 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -516,7 +516,6 @@ static inline bool is_dynamic_output_buffer_mode(struct v4l2_buffer *b,
inst->buffer_mode_set[CAPTURE_PORT] == HAL_BUFFER_MODE_DYNAMIC;
}
-
static inline void save_v4l2_buffer(struct v4l2_buffer *b,
struct buffer_info *binfo)
{
@@ -529,71 +528,22 @@ static inline void save_v4l2_buffer(struct v4l2_buffer *b,
}
populate_buf_info(binfo, b, i);
}
-}
-
-static int __map_and_update_binfo(struct msm_vidc_inst *inst,
- struct buffer_info *binfo,
- 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]);
-
- if (same_fd_handle) {
- binfo->device_addr[i] =
- same_fd_handle->device_addr + binfo->buff_off[i];
- b->m.planes[i].m.userptr = binfo->device_addr[i];
- binfo->handle[i] = same_fd_handle;
- } else {
- binfo->handle[i] = map_buffer(inst, &b->m.planes[i],
- get_hal_buffer_type(inst, b));
- if (!binfo->handle[i])
- return -EINVAL;
-
- binfo->mapped[i] = true;
- binfo->device_addr[i] = binfo->handle[i]->device_addr +
- binfo->buff_off[i];
- b->m.planes[i].m.userptr = binfo->device_addr[i];
- }
-
-exit:
- return rc;
-}
-
-static int __handle_fw_referenced_buffers(struct msm_vidc_inst *inst,
- struct buffer_info *binfo,
- struct v4l2_buffer *b)
-{
- int rc = 0;
- u32 i = 0;
if (EXTRADATA_IDX(b->length)) {
i = EXTRADATA_IDX(b->length);
if (b->m.planes[i].length)
- rc = __map_and_update_binfo(inst, binfo, b, i);
+ binfo->device_addr[i] = binfo->handle[i]->device_addr +
+ binfo->buff_off[i];
}
-
- if (rc)
- dprintk(VIDC_ERR, "%s: Failed to map extradata\n", __func__);
-
- return rc;
}
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, rc = 0;
- u32 i = 0;
+ int plane = 0;
+ int i = 0, rc = 0;
+ struct msm_smem *same_fd_handle = NULL;
if (!b || !inst) {
dprintk(VIDC_ERR, "%s: invalid input\n", __func__);
@@ -669,23 +619,39 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
rc = 0;
goto exit;
} else if (rc == 2) {
- rc = __handle_fw_referenced_buffers(inst, temp, b);
- if (!rc)
- rc = -EEXIST;
+ rc = -EEXIST;
goto exit;
}
+ same_fd_handle = get_same_fd_buffer(
+ inst, b->m.planes[i].reserved[0]);
+
populate_buf_info(binfo, b, i);
+ if (same_fd_handle) {
+ binfo->device_addr[i] =
+ same_fd_handle->device_addr + binfo->buff_off[i];
+ b->m.planes[i].m.userptr = binfo->device_addr[i];
+ binfo->mapped[i] = false;
+ binfo->handle[i] = same_fd_handle;
+ } else {
+ binfo->handle[i] = map_buffer(inst, &b->m.planes[i],
+ get_hal_buffer_type(inst, b));
+ if (!binfo->handle[i]) {
+ rc = -EINVAL;
+ goto exit;
+ }
- rc = __map_and_update_binfo(inst, binfo, b, i);
- if (rc)
- goto map_err;
+ binfo->mapped[i] = true;
+ binfo->device_addr[i] = binfo->handle[i]->device_addr +
+ binfo->buff_off[i];
+ b->m.planes[i].m.userptr = binfo->device_addr[i];
+ }
/* We maintain one ref count for all planes*/
if (!i && is_dynamic_output_buffer_mode(b, inst)) {
rc = buf_ref_get(inst, binfo);
if (rc < 0)
- goto map_err;
+ goto exit;
}
dprintk(VIDC_DBG,
"%s: [MAP] binfo = %pK, handle[%d] = %pK, device_addr = %pa, fd = %d, offset = %d, mapped = %d\n",
@@ -699,9 +665,6 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
mutex_unlock(&inst->registeredbufs.lock);
return 0;
-map_err:
- if (binfo->handle[0] && binfo->mapped[0])
- msm_comm_smem_free(inst, binfo->handle[0]);
exit:
kfree(binfo);
return rc;
@@ -771,7 +734,6 @@ int unmap_and_deregister_buf(struct msm_vidc_inst *inst,
temp->handle[i] = 0;
temp->device_addr[i] = 0;
temp->uvaddr[i] = 0;
- temp->mapped[i] = false;
}
}
if (!keep_node) {
@@ -786,7 +748,6 @@ exit:
return 0;
}
-
int qbuf_dynamic_buf(struct msm_vidc_inst *inst,
struct buffer_info *binfo)
{
diff --git a/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c b/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c
index e602650c4cb5..ebe9ab763a68 100644
--- a/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c
+++ b/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c
@@ -161,7 +161,6 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd,
pr_err("%s: Read buffer Allocation failed rc = %d\n",
__func__, rc);
rc = -ENOMEM;
- mutex_unlock(&effects->lock);
goto readbuf_fail;
}
atomic_set(&effects->out_count, effects->config.output.num_buf);
@@ -176,7 +175,6 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd,
if (rc < 0) {
pr_err("%s: pcm read block config failed\n", __func__);
rc = -EINVAL;
- mutex_unlock(&effects->lock);
goto cfg_fail;
}
pr_debug("%s: dec: sample_rate: %d, num_channels: %d, bit_width: %d\n",
@@ -191,7 +189,6 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd,
pr_err("%s: pcm write format block config failed\n",
__func__);
rc = -EINVAL;
- mutex_unlock(&effects->lock);
goto cfg_fail;
}
@@ -325,6 +322,7 @@ ioctl_fail:
readbuf_fail:
q6asm_audio_client_buf_free_contiguous(IN,
effects->ac);
+ mutex_unlock(&effects->lock);
return rc;
cfg_fail:
q6asm_audio_client_buf_free_contiguous(IN,
@@ -332,6 +330,7 @@ cfg_fail:
q6asm_audio_client_buf_free_contiguous(OUT,
effects->ac);
effects->buf_alloc = 0;
+ mutex_unlock(&effects->lock);
return rc;
}
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 8b8bea5d546a..55033aed6d6b 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -1304,6 +1304,9 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
fw_file = &ar->normal_mode_fw.fw_file;
fw_file->wmi_op_version = ATH10K_FW_WMI_OP_VERSION_TLV;
fw_file->htt_op_version = ATH10K_FW_HTT_OP_VERSION_TLV;
+ __set_bit(ATH10K_FW_FEATURE_WOWLAN_SUPPORT,
+ fw_file->fw_features);
+ __set_bit(WMI_SERVICE_WOW, ar->wmi.svc_map);
return 0;
}
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index ffcf30756b9e..f194d434b97c 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -24,6 +24,7 @@
#include <linux/pci.h>
#include <linux/uuid.h>
#include <linux/time.h>
+#include <linux/inetdevice.h>
#include <soc/qcom/socinfo.h>
#include "htt.h"
@@ -430,6 +431,8 @@ struct ath10k_vif {
struct work_struct ap_csa_work;
struct delayed_work connection_loss_work;
struct cfg80211_bitrate_mask bitrate_mask;
+ struct wmi_ns_arp_offload_req arp_offload;
+ struct wmi_ns_arp_offload_req ns_offload;
};
struct ath10k_vif_iter {
diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
index c01f59955797..aa20ebbefe94 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -86,7 +86,8 @@ static void ath10k_htc_prepare_tx_skb(struct ath10k_htc_ep *ep,
hdr->eid = ep->eid;
hdr->len = __cpu_to_le16(skb->len - sizeof(*hdr));
hdr->flags = 0;
- hdr->flags |= ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE;
+ if (ep->tx_credit_flow_enabled)
+ hdr->flags |= ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE;
spin_lock_bh(&ep->htc->tx_lock);
hdr->seq_no = ep->seq_no++;
diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c
index 1d37b2c8426b..caf63b8bbba4 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -509,6 +509,7 @@ const struct ath10k_hw_values wcn3990_values = {
.num_target_ce_config_wlan = 12,
.ce_desc_meta_data_mask = 0xFFF0,
.ce_desc_meta_data_lsb = 4,
+ .default_listen_interval = 1,
};
struct fw_flag wcn3990_fw_flags = {
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index e0af0f766b02..8aa696ed2e72 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -369,6 +369,7 @@ struct ath10k_hw_values {
u8 num_target_ce_config_wlan;
u16 ce_desc_meta_data_mask;
u8 ce_desc_meta_data_lsb;
+ u8 default_listen_interval;
};
extern const struct ath10k_hw_values qca988x_values;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 5a84626dff14..9fcc2866d830 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1387,6 +1387,10 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
lockdep_assert_held(&ar->conf_mutex);
+ /* Clear arp and ns offload cache */
+ memset(&arvif->arp_offload, 0, sizeof(arvif->arp_offload));
+ memset(&arvif->ns_offload, 0, sizeof(arvif->ns_offload));
+
reinit_completion(&ar->vdev_setup_done);
reinit_completion(&ar->vdev_delete_done);
@@ -7578,6 +7582,7 @@ static const struct ieee80211_ops ath10k_ops = {
#ifdef CONFIG_PM
.suspend = ath10k_wow_op_suspend,
.resume = ath10k_wow_op_resume,
+ .set_wakeup = ath10k_wow_op_set_wakeup,
#endif
#ifdef CONFIG_MAC80211_DEBUGFS
.sta_add_debugfs = ath10k_sta_add_debugfs,
diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c
index c42d7eebf465..a1a4812feeed 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -30,7 +30,8 @@
#include <linux/regulator/consumer.h>
#include <linux/clk.h>
-#define WCN3990_MAX_IRQ 12
+#define WCN3990_MAX_IRQ 12
+#define WCN3990_WAKE_IRQ_CE 2
const char *ce_name[WCN3990_MAX_IRQ] = {
"WLAN_CE_0",
@@ -1161,7 +1162,8 @@ static int ath10k_snoc_hif_power_up(struct ath10k *ar)
atomic_set(&ar_snoc->pm_ops_inprogress, 0);
}
- if (ar->state == ATH10K_STATE_ON ||
+ if ((ar->state == ATH10K_STATE_ON) ||
+ (ar->state == ATH10K_STATE_RESTARTING) ||
test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) {
ret = ath10k_snoc_bus_configure(ar);
if (ret) {
@@ -1571,6 +1573,50 @@ static int ath10k_hw_power_off(struct ath10k *ar)
return ret;
}
+static int ath10k_snoc_hif_suspend(struct ath10k *ar)
+{
+ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+ int ret = 0;
+
+ if (!ar_snoc)
+ return -EINVAL;
+
+ if (!device_may_wakeup(ar->dev))
+ return -EINVAL;
+
+ ret = enable_irq_wake(ar_snoc->ce_irqs[WCN3990_WAKE_IRQ_CE].irq_line);
+ if (ret) {
+ ath10k_dbg(ar, ATH10K_DBG_SNOC,
+ "HIF Suspend: Failed to enable wakeup IRQ\n");
+ return ret;
+ }
+
+ ath10k_dbg(ar, ATH10K_DBG_SNOC, "HIF Suspended\n");
+ return ret;
+}
+
+static int ath10k_snoc_hif_resume(struct ath10k *ar)
+{
+ struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
+ int ret = 0;
+
+ if (!ar_snoc)
+ return -EINVAL;
+
+ if (!device_may_wakeup(ar->dev))
+ return -EINVAL;
+
+ ret = disable_irq_wake(ar_snoc->ce_irqs[WCN3990_WAKE_IRQ_CE].irq_line);
+ if (ret) {
+ ath10k_dbg(ar, ATH10K_DBG_SNOC,
+ "HIF Resume: Failed to disable wakeup IRQ\n");
+ return ret;
+ }
+
+ ath10k_dbg(ar, ATH10K_DBG_SNOC, "HIF Resumed\n");
+ return ret;
+}
+
static const struct ath10k_hif_ops ath10k_snoc_hif_ops = {
.tx_sg = ath10k_snoc_hif_tx_sg,
.start = ath10k_snoc_hif_start,
@@ -1583,6 +1629,8 @@ static const struct ath10k_hif_ops ath10k_snoc_hif_ops = {
.power_down = ath10k_snoc_hif_power_down,
.read32 = ath10k_snoc_read32,
.write32 = ath10k_snoc_write32,
+ .suspend = ath10k_snoc_hif_suspend,
+ .resume = ath10k_snoc_hif_resume,
};
static const struct ath10k_bus_ops ath10k_snoc_bus_ops = {
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index 8bb01c1a35f7..dcb0da51530a 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -160,6 +160,8 @@ struct wmi_ops {
u32 num_ac);
struct sk_buff *(*gen_sta_keepalive)(struct ath10k *ar,
const struct wmi_sta_keepalive_arg *arg);
+ struct sk_buff *(*gen_set_arp_ns_offload)(struct ath10k *ar,
+ struct ath10k_vif *arvif);
struct sk_buff *(*gen_wow_enable)(struct ath10k *ar);
struct sk_buff *(*gen_wow_add_wakeup_event)(struct ath10k *ar, u32 vdev_id,
enum wmi_wow_wakeup_event event,
@@ -1187,6 +1189,23 @@ ath10k_wmi_sta_keepalive(struct ath10k *ar,
}
static inline int
+ath10k_wmi_set_arp_ns_offload(struct ath10k *ar, struct ath10k_vif *arvif)
+{
+ struct sk_buff *skb;
+ u32 cmd_id;
+
+ if (!ar->wmi.ops->gen_set_arp_ns_offload)
+ return -EOPNOTSUPP;
+
+ skb = ar->wmi.ops->gen_set_arp_ns_offload(ar, arvif);
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ cmd_id = ar->wmi.cmd->set_arp_ns_offload_cmdid;
+ return ath10k_wmi_cmd_send(ar, skb, cmd_id);
+}
+
+static inline int
ath10k_wmi_wow_enable(struct ath10k *ar)
{
struct sk_buff *skb;
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index f5360444a083..b904a0d9d391 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -3010,6 +3010,82 @@ ath10k_wmi_tlv_op_gen_tdls_peer_update(struct ath10k *ar,
}
static struct sk_buff *
+ath10k_wmi_tlv_op_gen_set_arp_ns_offload(struct ath10k *ar,
+ struct ath10k_vif *arvif)
+{
+ struct wmi_tlv_arp_ns_offload_cmd *cmd;
+ struct wmi_tlv *tlv;
+ struct sk_buff *skb;
+ size_t len;
+ void *ptr;
+ int i;
+ struct wmi_ns_arp_offload_req *arp = &arvif->arp_offload;
+ struct wmi_ns_offload *ns_tuple[WMI_MAX_NS_OFFLOADS];
+ struct wmi_arp_offload *arp_tuple[WMI_MAX_ARP_OFFLOADS];
+
+ len = sizeof(*cmd) + sizeof(*tlv) +
+ sizeof(*tlv) + WMI_MAX_NS_OFFLOADS *
+ (sizeof(struct wmi_ns_offload) + sizeof(*tlv)) +
+ sizeof(*tlv) + WMI_MAX_ARP_OFFLOADS *
+ (sizeof(struct wmi_arp_offload) + sizeof(*tlv));
+
+ skb = ath10k_wmi_alloc_skb(ar, len);
+ if (!skb)
+ return ERR_PTR(-ENOMEM);
+
+ ptr = (void *)skb->data;
+ tlv = ptr;
+ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_SET_ARP_NS_OFFLOAD_CMD);
+ tlv->len = __cpu_to_le16(sizeof(*cmd));
+ cmd = (struct wmi_tlv_arp_ns_offload_cmd *)tlv->value;
+ cmd->flags = __cpu_to_le32(0);
+ cmd->vdev_id = __cpu_to_le32(arvif->vdev_id);
+
+ ptr += (sizeof(*tlv) + sizeof(*cmd));
+ tlv = ptr;
+ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
+ tlv->len = __cpu_to_le16(WMI_MAX_NS_OFFLOADS *
+ (sizeof(struct wmi_ns_offload) + sizeof(*tlv)));
+ ptr += sizeof(*tlv);
+ tlv = ptr;
+
+ for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) {
+ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_NS_OFFLOAD_TUPLE);
+ tlv->len = __cpu_to_le16(sizeof(struct wmi_ns_offload));
+ ns_tuple[i] = (struct wmi_ns_offload *)tlv->value;
+ ns_tuple[i]->flags |= __cpu_to_le32(WMI_ARP_NS_OFFLOAD_DISABLE);
+ ptr += (sizeof(*tlv) + sizeof(struct wmi_ns_offload));
+ tlv = ptr;
+ }
+
+ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
+ tlv->len = __cpu_to_le16(WMI_MAX_ARP_OFFLOADS *
+ (sizeof(struct wmi_arp_offload) + sizeof(*tlv)));
+ ptr += sizeof(*tlv);
+ tlv = ptr;
+
+ for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) {
+ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_ARP_OFFLOAD_TUPLE);
+ tlv->len = __cpu_to_le16(sizeof(struct wmi_arp_offload));
+ arp_tuple[i] = (struct wmi_arp_offload *)tlv->value;
+ if (arp->enable_offload && (i == 0)) {
+ arp_tuple[i]->flags |=
+ __cpu_to_le32(WMI_ARPOFF_FLAGS_VALID);
+ memcpy(&arp_tuple[i]->target_ipaddr,
+ &arp->params.ipv4_addr, 4);
+ } else {
+ arp_tuple[i]->flags |=
+ __cpu_to_le32(WMI_ARP_NS_OFFLOAD_DISABLE);
+ }
+ ptr += (sizeof(*tlv) + sizeof(struct wmi_arp_offload));
+ tlv = ptr;
+ }
+
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set arp ns offload\n");
+ return skb;
+}
+
+static struct sk_buff *
ath10k_wmi_tlv_op_gen_wow_enable(struct ath10k *ar)
{
struct wmi_tlv_wow_enable_cmd *cmd;
@@ -3028,6 +3104,8 @@ ath10k_wmi_tlv_op_gen_wow_enable(struct ath10k *ar)
cmd = (void *)tlv->value;
cmd->enable = __cpu_to_le32(1);
+ if (QCA_REV_WCN3990(ar))
+ cmd->pause_iface_config = __cpu_to_le32(1);
ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv wow enable\n");
return skb;
@@ -3693,6 +3771,7 @@ static const struct wmi_ops wmi_tlv_ops = {
.gen_p2p_go_bcn_ie = ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie,
.gen_vdev_sta_uapsd = ath10k_wmi_tlv_op_gen_vdev_sta_uapsd,
.gen_sta_keepalive = ath10k_wmi_tlv_op_gen_sta_keepalive,
+ .gen_set_arp_ns_offload = ath10k_wmi_tlv_op_gen_set_arp_ns_offload,
.gen_wow_enable = ath10k_wmi_tlv_op_gen_wow_enable,
.gen_wow_add_wakeup_event = ath10k_wmi_tlv_op_gen_wow_add_wakeup_event,
.gen_wow_host_wakeup_ind = ath10k_wmi_tlv_gen_wow_host_wakeup_ind,
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
index 500d1d8f441f..1d4aed14fbb4 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
@@ -1554,6 +1554,13 @@ struct wmi_tlv_wow_add_del_event_cmd {
struct wmi_tlv_wow_enable_cmd {
__le32 enable;
+ __le32 pause_iface_config;
+} __packed;
+
+struct wmi_tlv_arp_ns_offload_cmd {
+ __le32 flags;
+ __le32 vdev_id;
+ __le32 num_ns_ext_tuples;
} __packed;
struct wmi_tlv_wow_host_wakeup_ind {
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index f59e5f86708b..9b17ef150303 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -20,6 +20,8 @@
#include <linux/types.h>
#include <net/mac80211.h>
+#include <linux/ipv6.h>
+#include <linux/in.h>
/*
* This file specifies the WMI interface for the Unified Software
@@ -2884,6 +2886,53 @@ struct wmi_start_scan_common {
__le32 scan_ctrl_flags;
} __packed;
+/* ARP-NS offload data structure */
+#define WMI_NSOFF_MAX_TARGET_IPS 2
+#define WMI_MAX_NS_OFFLOADS 2
+#define WMI_MAX_ARP_OFFLOADS 2
+#define WMI_ARPOFF_FLAGS_VALID BIT(0)
+#define WMI_IPV4_ARP_REPLY_OFFLOAD 0
+#define WMI_ARP_NS_OFFLOAD_DISABLE 0
+#define WMI_ARP_NS_OFFLOAD_ENABLE 1
+
+struct wmi_ns_offload_info {
+ struct in6_addr src_addr;
+ struct in6_addr self_addr[TARGET_NUM_STATIONS];
+ struct in6_addr target_addr[TARGET_NUM_STATIONS];
+ struct wmi_mac_addr self_macaddr;
+ u8 src_ipv6_addr_valid;
+ struct in6_addr target_addr_valid;
+ struct in6_addr target_addr_ac_type;
+ u8 slot_idx;
+} __packed;
+
+struct wmi_ns_arp_offload_req {
+ u8 offload_type;
+ u8 enable_offload;
+ __le32 num_ns_offload_count;
+ union {
+ struct in_addr ipv4_addr;
+ struct in6_addr ipv6_addr;
+ } params;
+ struct wmi_ns_offload_info offload_info;
+ struct wmi_mac_addr bssid;
+} __packed;
+
+struct wmi_ns_offload {
+ __le32 flags;
+ struct in6_addr target_ipaddr[WMI_NSOFF_MAX_TARGET_IPS];
+ struct in6_addr solicitation_ipaddr;
+ struct in6_addr remote_ipaddr;
+ struct wmi_mac_addr target_mac;
+} __packed;
+
+struct wmi_arp_offload {
+ __le32 flags;
+ struct in_addr target_ipaddr;
+ struct in_addr remote_ipaddr;
+ struct wmi_mac_addr target_mac;
+} __packed;
+
struct wmi_start_scan_tlvs {
/* TLV parameters. These includes channel list, ssid list, bssid list,
* extra ies.
diff --git a/drivers/net/wireless/ath/ath10k/wow.c b/drivers/net/wireless/ath/ath10k/wow.c
index 77100d42f401..1a43375c3264 100644
--- a/drivers/net/wireless/ath/ath10k/wow.c
+++ b/drivers/net/wireless/ath/ath10k/wow.c
@@ -224,6 +224,101 @@ static int ath10k_wow_wakeup(struct ath10k *ar)
return 0;
}
+static int
+ath10k_wow_fill_vdev_arp_offload_struct(struct ath10k_vif *arvif,
+ bool enable_offload)
+{
+ struct in_device *in_dev;
+ struct in_ifaddr *ifa;
+ bool offload_params_found = false;
+ struct wireless_dev *wdev = ieee80211_vif_to_wdev(arvif->vif);
+ struct wmi_ns_arp_offload_req *arp = &arvif->arp_offload;
+
+ if (!enable_offload) {
+ arp->offload_type = __cpu_to_le16(WMI_IPV4_ARP_REPLY_OFFLOAD);
+ arp->enable_offload = __cpu_to_le16(WMI_ARP_NS_OFFLOAD_DISABLE);
+ return 0;
+ }
+
+ if (!wdev)
+ return -ENODEV;
+ if (!wdev->netdev)
+ return -ENODEV;
+ in_dev = __in_dev_get_rtnl(wdev->netdev);
+ if (!in_dev)
+ return -ENODEV;
+
+ arp->offload_type = __cpu_to_le16(WMI_IPV4_ARP_REPLY_OFFLOAD);
+ arp->enable_offload = __cpu_to_le16(WMI_ARP_NS_OFFLOAD_ENABLE);
+ for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
+ if (!strcmp(ifa->ifa_label, wdev->netdev->name)) {
+ offload_params_found = true;
+ break;
+ }
+ }
+
+ if (!offload_params_found)
+ return -ENODEV;
+
+ memcpy(&arp->params.ipv4_addr, &ifa->ifa_local, 4);
+ return 0;
+}
+
+static int ath10k_wow_enable_ns_arp_offload(struct ath10k *ar, bool offload)
+{
+ struct ath10k_vif *arvif;
+ int ret;
+
+ list_for_each_entry(arvif, &ar->arvifs, list) {
+ if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
+ continue;
+
+ if (!arvif->is_up)
+ continue;
+
+ ret = ath10k_wow_fill_vdev_arp_offload_struct(arvif, offload);
+ if (ret) {
+ ath10k_err(ar, "ARP-offload config failed, vdev: %d\n",
+ arvif->vdev_id);
+ return ret;
+ }
+
+ ret = ath10k_wmi_set_arp_ns_offload(ar, arvif);
+ if (ret) {
+ ath10k_err(ar, "failed to send offload cmd, vdev: %d\n",
+ arvif->vdev_id);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int ath10k_config_wow_listen_interval(struct ath10k *ar)
+{
+ int ret;
+ u32 param = ar->wmi.vdev_param->listen_interval;
+ u8 listen_interval = ar->hw_values->default_listen_interval;
+ struct ath10k_vif *arvif;
+
+ if (!listen_interval)
+ return 0;
+
+ list_for_each_entry(arvif, &ar->arvifs, list) {
+ if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
+ continue;
+ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
+ param, listen_interval);
+ if (ret) {
+ ath10k_err(ar, "failed to config LI for vdev_id: %d\n",
+ arvif->vdev_id);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
int ath10k_wow_op_suspend(struct ieee80211_hw *hw,
struct cfg80211_wowlan *wowlan)
{
@@ -238,11 +333,17 @@ int ath10k_wow_op_suspend(struct ieee80211_hw *hw,
goto exit;
}
+ ret = ath10k_wow_enable_ns_arp_offload(ar, true);
+ if (ret) {
+ ath10k_warn(ar, "failed to enable ARP-NS offload: %d\n", ret);
+ goto exit;
+ }
+
ret = ath10k_wow_cleanup(ar);
if (ret) {
ath10k_warn(ar, "failed to clear wow wakeup events: %d\n",
ret);
- goto exit;
+ goto disable_ns_arp_offload;
}
ret = ath10k_wow_set_wakeups(ar, wowlan);
@@ -252,6 +353,13 @@ int ath10k_wow_op_suspend(struct ieee80211_hw *hw,
goto cleanup;
}
+ ret = ath10k_config_wow_listen_interval(ar);
+ if (ret) {
+ ath10k_warn(ar, "failed to config wow listen interval: %d\n",
+ ret);
+ goto cleanup;
+ }
+
ret = ath10k_wow_enable(ar);
if (ret) {
ath10k_warn(ar, "failed to start wow: %d\n", ret);
@@ -272,11 +380,26 @@ wakeup:
cleanup:
ath10k_wow_cleanup(ar);
+disable_ns_arp_offload:
+ ath10k_wow_enable_ns_arp_offload(ar, false);
+
exit:
mutex_unlock(&ar->conf_mutex);
return ret ? 1 : 0;
}
+void ath10k_wow_op_set_wakeup(struct ieee80211_hw *hw, bool enabled)
+{
+ struct ath10k *ar = hw->priv;
+
+ mutex_lock(&ar->conf_mutex);
+ if (test_bit(ATH10K_FW_FEATURE_WOWLAN_SUPPORT,
+ ar->running_fw->fw_file.fw_features)) {
+ device_set_wakeup_enable(ar->dev, enabled);
+ }
+ mutex_unlock(&ar->conf_mutex);
+}
+
int ath10k_wow_op_resume(struct ieee80211_hw *hw)
{
struct ath10k *ar = hw->priv;
@@ -297,8 +420,14 @@ int ath10k_wow_op_resume(struct ieee80211_hw *hw)
}
ret = ath10k_wow_wakeup(ar);
- if (ret)
+ if (ret) {
ath10k_warn(ar, "failed to wakeup from wow: %d\n", ret);
+ goto exit;
+ }
+
+ ret = ath10k_wow_enable_ns_arp_offload(ar, false);
+ if (ret)
+ ath10k_warn(ar, "failed to disable ARP-NS offload: %d\n", ret);
exit:
if (ret) {
@@ -336,5 +465,7 @@ int ath10k_wow_init(struct ath10k *ar)
ar->wow.wowlan_support.n_patterns = ar->wow.max_num_patterns;
ar->hw->wiphy->wowlan = &ar->wow.wowlan_support;
+ device_set_wakeup_capable(ar->dev, true);
+
return 0;
}
diff --git a/drivers/net/wireless/ath/ath10k/wow.h b/drivers/net/wireless/ath/ath10k/wow.h
index abbb04b6d1bd..9745b9ddc7f5 100644
--- a/drivers/net/wireless/ath/ath10k/wow.h
+++ b/drivers/net/wireless/ath/ath10k/wow.h
@@ -28,6 +28,7 @@ int ath10k_wow_init(struct ath10k *ar);
int ath10k_wow_op_suspend(struct ieee80211_hw *hw,
struct cfg80211_wowlan *wowlan);
int ath10k_wow_op_resume(struct ieee80211_hw *hw);
+void ath10k_wow_op_set_wakeup(struct ieee80211_hw *hw, bool enabled);
#else
diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c
index 8d34d74477eb..9bf4c7e11c66 100644
--- a/drivers/net/wireless/cnss2/pci.c
+++ b/drivers/net/wireless/cnss2/pci.c
@@ -129,9 +129,10 @@ int cnss_suspend_pci_link(struct cnss_pci_data *pci_priv)
pci_disable_device(pci_priv->pci_dev);
- ret = pci_set_power_state(pci_priv->pci_dev, PCI_D3hot);
- if (ret)
- cnss_pr_err("Failed to set D3Hot, err = %d\n", ret);
+ if (pci_priv->pci_dev->device != QCA6174_DEVICE_ID) {
+ if (pci_set_power_state(pci_priv->pci_dev, PCI_D3hot))
+ cnss_pr_err("Failed to set D3Hot, err = %d\n", ret);
+ }
ret = cnss_set_pci_link(pci_priv, PCI_LINK_DOWN);
if (ret)
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
index 72542bf6dd5d..c0af295c7362 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
@@ -23,10 +23,10 @@
static int ipa_generate_hw_rule_from_eq(
const struct ipa_ipfltri_rule_eq *attrib, u8 **buf)
{
- int num_offset_meq_32 = attrib->num_offset_meq_32;
- int num_ihl_offset_range_16 = attrib->num_ihl_offset_range_16;
- int num_ihl_offset_meq_32 = attrib->num_ihl_offset_meq_32;
- int num_offset_meq_128 = attrib->num_offset_meq_128;
+ uint8_t num_offset_meq_32 = attrib->num_offset_meq_32;
+ uint8_t num_ihl_offset_range_16 = attrib->num_ihl_offset_range_16;
+ uint8_t num_ihl_offset_meq_32 = attrib->num_ihl_offset_meq_32;
+ uint8_t num_offset_meq_128 = attrib->num_offset_meq_128;
int i;
if (attrib->tos_eq_present) {
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c
index 119d17cae9f5..e33d0d86ac95 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c
@@ -512,6 +512,7 @@ int qmi_filter_request_send(struct ipa_install_fltr_rule_req_msg_v01 *req)
struct ipa_install_fltr_rule_resp_msg_v01 resp;
struct msg_desc req_desc, resp_desc;
int rc;
+ int i;
/* check if the filter rules from IPACM is valid */
if (req->filter_spec_list_len == 0) {
@@ -521,6 +522,38 @@ int qmi_filter_request_send(struct ipa_install_fltr_rule_req_msg_v01 *req)
req->filter_spec_list_len);
}
+ if (req->filter_spec_list_len >= QMI_IPA_MAX_FILTERS_V01) {
+ IPAWANDBG(
+ "IPACM passes the number of filtering rules exceed limit\n");
+ return -EINVAL;
+ } else if (req->source_pipe_index_valid != 0) {
+ IPAWANDBG(
+ "IPACM passes source_pipe_index_valid not zero 0 != %d\n",
+ req->source_pipe_index_valid);
+ return -EINVAL;
+ } else if (req->source_pipe_index >= ipa_ctx->ipa_num_pipes) {
+ IPAWANDBG(
+ "IPACM passes source pipe index not valid ID = %d\n",
+ req->source_pipe_index);
+ return -EINVAL;
+ }
+ for (i = 0; i < req->filter_spec_list_len; i++) {
+ if ((req->filter_spec_list[i].ip_type !=
+ QMI_IPA_IP_TYPE_V4_V01) &&
+ (req->filter_spec_list[i].ip_type !=
+ QMI_IPA_IP_TYPE_V6_V01))
+ return -EINVAL;
+ if (req->filter_spec_list[i].is_mux_id_valid == false)
+ return -EINVAL;
+ if (req->filter_spec_list[i].is_routing_table_index_valid
+ == false)
+ return -EINVAL;
+ if ((req->filter_spec_list[i].filter_action <=
+ QMI_IPA_FILTER_ACTION_INVALID_V01) &&
+ (req->filter_spec_list[i].filter_action >
+ QMI_IPA_FILTER_ACTION_EXCEPTION_V01))
+ return -EINVAL;
+ }
mutex_lock(&ipa_qmi_lock);
if (ipa_qmi_ctx != NULL) {
/* cache the qmi_filter_request */
@@ -675,6 +708,27 @@ int qmi_filter_notify_send(struct ipa_fltr_installed_notif_req_msg_v01 *req)
return -EINVAL;
}
+ if (req->install_status != IPA_QMI_RESULT_SUCCESS_V01) {
+ IPAWANERR(" UL filter rule for pipe %d install_status = %d\n",
+ req->source_pipe_index, req->install_status);
+ return -EINVAL;
+ } else if (req->source_pipe_index >= ipa_ctx->ipa_num_pipes) {
+ IPAWANERR("IPACM passes source pipe index not valid ID = %d\n",
+ req->source_pipe_index);
+ return -EINVAL;
+ } else if (((req->embedded_pipe_index_valid != true) ||
+ (req->embedded_call_mux_id_valid != true)) &&
+ ((req->embedded_pipe_index_valid != false) ||
+ (req->embedded_call_mux_id_valid != false))) {
+ IPAWANERR(
+ "IPACM passes embedded pipe and mux valid not valid\n");
+ return -EINVAL;
+ } else if (req->embedded_pipe_index >= ipa_ctx->ipa_num_pipes) {
+ IPAWANERR("IPACM passes source pipe index not valid ID = %d\n",
+ req->source_pipe_index);
+ return -EINVAL;
+ }
+
mutex_lock(&ipa_qmi_lock);
if (ipa_qmi_ctx != NULL) {
/* cache the qmi_filter_request */
diff --git a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
index 23e4d2b0d6e8..b158b2b1c326 100644
--- a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
@@ -649,6 +649,8 @@ static int wwan_add_ul_flt_rule_to_ipa(void)
return -ENOMEM;
}
+ memset(req, 0, sizeof(struct ipa_fltr_installed_notif_req_msg_v01));
+
param->commit = 1;
param->ep = IPA_CLIENT_APPS_LAN_WAN_PROD;
param->global = false;
@@ -1517,8 +1519,8 @@ static int ipa_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
/* Get driver name */
case RMNET_IOCTL_GET_DRIVER_NAME:
memcpy(&extend_ioctl_data.u.if_name,
- ipa_netdevs[0]->name,
- sizeof(IFNAMSIZ));
+ ipa_netdevs[0]->name, IFNAMSIZ);
+ extend_ioctl_data.u.if_name[IFNAMSIZ - 1] = '\0';
if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
&extend_ioctl_data,
sizeof(struct rmnet_ioctl_extended_s)))
@@ -1664,6 +1666,7 @@ static int ipa_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
sizeof(wan_msg->upstream_ifname);
strlcpy(wan_msg->upstream_ifname,
extend_ioctl_data.u.if_name, len);
+ wan_msg->upstream_ifname[len - 1] = '\0';
memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
msg_meta.msg_type = WAN_XLAT_CONNECT;
msg_meta.msg_len = sizeof(struct ipa_wan_msg);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index e9fd1560b1e8..a869b6419e5e 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -4306,6 +4306,7 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p,
ipa3_register_panic_hdlr();
ipa3_ctx->q6_proxy_clk_vote_valid = true;
+ ipa3_ctx->q6_proxy_clk_vote_cnt++;
mutex_lock(&ipa3_ctx->lock);
ipa3_ctx->ipa_initialization_complete = true;
@@ -4413,6 +4414,9 @@ static ssize_t ipa3_write(struct file *file, const char __user *buf,
return -EFAULT;
}
+ if (count > 0)
+ dbg_buff[count - 1] = '\0';
+
/* Prevent consequent calls from trying to load the FW again. */
if (ipa3_is_ready())
return count;
@@ -4887,6 +4891,7 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
mutex_init(&ipa3_ctx->nat_mem.lock);
mutex_init(&ipa3_ctx->q6_proxy_clk_vote_mutex);
mutex_init(&ipa3_ctx->ipa_cne_evt_lock);
+ ipa3_ctx->q6_proxy_clk_vote_cnt = 0;
idr_init(&ipa3_ctx->ipa_idr);
spin_lock_init(&ipa3_ctx->idr_lock);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index 8e6db8f63fc1..a4c5e425dc83 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -1240,6 +1240,7 @@ struct ipa3_context {
u32 curr_ipa_clk_rate;
bool q6_proxy_clk_vote_valid;
struct mutex q6_proxy_clk_vote_mutex;
+ u32 q6_proxy_clk_vote_cnt;
u32 ipa_num_pipes;
struct ipa3_wlan_comm_memb wc_memb;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
index 4897c4dccf59..afe8db7a7284 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
@@ -603,13 +603,46 @@ int ipa3_qmi_filter_request_send(struct ipa_install_fltr_rule_req_msg_v01 *req)
struct ipa_install_fltr_rule_resp_msg_v01 resp;
struct msg_desc req_desc, resp_desc;
int rc;
+ int i;
/* check if the filter rules from IPACM is valid */
- if (req->filter_spec_ex_list_len == 0) {
+ if (req->filter_spec_list_len == 0)
IPAWANDBG("IPACM pass zero rules to Q6\n");
- } else {
+ else
IPAWANDBG("IPACM pass %u rules to Q6\n",
- req->filter_spec_ex_list_len);
+ req->filter_spec_list_len);
+
+ if (req->filter_spec_list_len >= QMI_IPA_MAX_FILTERS_V01) {
+ IPAWANDBG(
+ "IPACM passes the number of filtering rules exceed limit\n");
+ return -EINVAL;
+ } else if (req->source_pipe_index_valid != 0) {
+ IPAWANDBG(
+ "IPACM passes source_pipe_index_valid not zero 0 != %d\n",
+ req->source_pipe_index_valid);
+ return -EINVAL;
+ } else if (req->source_pipe_index >= ipa3_ctx->ipa_num_pipes) {
+ IPAWANDBG(
+ "IPACM passes source pipe index not valid ID = %d\n",
+ req->source_pipe_index);
+ return -EINVAL;
+ }
+ for (i = 0; i < req->filter_spec_list_len; i++) {
+ if ((req->filter_spec_list[i].ip_type !=
+ QMI_IPA_IP_TYPE_V4_V01) &&
+ (req->filter_spec_list[i].ip_type !=
+ QMI_IPA_IP_TYPE_V6_V01))
+ return -EINVAL;
+ if (req->filter_spec_list[i].is_mux_id_valid == false)
+ return -EINVAL;
+ if (req->filter_spec_list[i].is_routing_table_index_valid
+ == false)
+ return -EINVAL;
+ if ((req->filter_spec_list[i].filter_action <=
+ QMI_IPA_FILTER_ACTION_INVALID_V01) &&
+ (req->filter_spec_list[i].filter_action >
+ QMI_IPA_FILTER_ACTION_EXCEPTION_V01))
+ return -EINVAL;
}
mutex_lock(&ipa3_qmi_lock);
@@ -653,6 +686,7 @@ int ipa3_qmi_filter_request_ex_send(
struct ipa_install_fltr_rule_resp_ex_msg_v01 resp;
struct msg_desc req_desc, resp_desc;
int rc;
+ int i;
/* check if the filter rules from IPACM is valid */
if (req->filter_spec_ex_list_len == 0) {
@@ -662,6 +696,34 @@ int ipa3_qmi_filter_request_ex_send(
req->filter_spec_ex_list_len);
}
+ if (req->filter_spec_ex_list_len >= QMI_IPA_MAX_FILTERS_EX_V01) {
+ IPAWANDBG(
+ "IPACM pass the number of filtering rules exceed limit\n");
+ return -EINVAL;
+ } else if (req->source_pipe_index_valid != 0) {
+ IPAWANDBG(
+ "IPACM passes source_pipe_index_valid not zero 0 != %d\n",
+ req->source_pipe_index_valid);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < req->filter_spec_ex_list_len-1; i++) {
+ if ((req->filter_spec_ex_list[i].ip_type !=
+ QMI_IPA_IP_TYPE_V4_V01) &&
+ (req->filter_spec_ex_list[i].ip_type !=
+ QMI_IPA_IP_TYPE_V6_V01))
+ return -EINVAL;
+ if (req->filter_spec_ex_list[i].is_mux_id_valid == false)
+ return -EINVAL;
+ if (req->filter_spec_ex_list[i].is_routing_table_index_valid
+ == false)
+ return -EINVAL;
+ if ((req->filter_spec_ex_list[i].filter_action <=
+ QMI_IPA_FILTER_ACTION_INVALID_V01) &&
+ (req->filter_spec_ex_list[i].filter_action >
+ QMI_IPA_FILTER_ACTION_EXCEPTION_V01))
+ return -EINVAL;
+ }
mutex_lock(&ipa3_qmi_lock);
if (ipa3_qmi_ctx != NULL) {
/* cache the qmi_filter_request */
@@ -862,6 +924,31 @@ int ipa3_qmi_filter_notify_send(
IPAWANERR("Source pipe index invalid\n");
return -EINVAL;
}
+ if (req->install_status != IPA_QMI_RESULT_SUCCESS_V01) {
+ IPAWANERR(" UL filter rule for pipe %d install_status = %d\n",
+ req->source_pipe_index, req->install_status);
+ return -EINVAL;
+ } else if (req->rule_id_valid != 1) {
+ IPAWANERR(" UL filter rule for pipe %d rule_id_valid = %d\n",
+ req->source_pipe_index, req->rule_id_valid);
+ return -EINVAL;
+ } else if (req->source_pipe_index >= ipa3_ctx->ipa_num_pipes) {
+ IPAWANDBG(
+ "IPACM passes source pipe index not valid ID = %d\n",
+ req->source_pipe_index);
+ return -EINVAL;
+ } else if (((req->embedded_pipe_index_valid != true) ||
+ (req->embedded_call_mux_id_valid != true)) &&
+ ((req->embedded_pipe_index_valid != false) ||
+ (req->embedded_call_mux_id_valid != false))) {
+ IPAWANERR(
+ "IPACM passes embedded pipe and mux valid not valid\n");
+ return -EINVAL;
+ } else if (req->embedded_pipe_index >= ipa3_ctx->ipa_num_pipes) {
+ IPAWANERR("IPACM passes source pipe index not valid ID = %d\n",
+ req->source_pipe_index);
+ return -EINVAL;
+ }
mutex_lock(&ipa3_qmi_lock);
if (ipa3_qmi_ctx != NULL) {
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index 29f2046610c8..74176d1aa47a 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -2989,7 +2989,9 @@ void ipa3_proxy_clk_unvote(void)
mutex_lock(&ipa3_ctx->q6_proxy_clk_vote_mutex);
if (ipa3_ctx->q6_proxy_clk_vote_valid) {
IPA_ACTIVE_CLIENTS_DEC_SPECIAL("PROXY_CLK_VOTE");
- ipa3_ctx->q6_proxy_clk_vote_valid = false;
+ ipa3_ctx->q6_proxy_clk_vote_cnt--;
+ if (ipa3_ctx->q6_proxy_clk_vote_cnt == 0)
+ ipa3_ctx->q6_proxy_clk_vote_valid = false;
}
mutex_unlock(&ipa3_ctx->q6_proxy_clk_vote_mutex);
}
@@ -3005,8 +3007,10 @@ void ipa3_proxy_clk_vote(void)
return;
mutex_lock(&ipa3_ctx->q6_proxy_clk_vote_mutex);
- if (!ipa3_ctx->q6_proxy_clk_vote_valid) {
+ if (!ipa3_ctx->q6_proxy_clk_vote_valid ||
+ (ipa3_ctx->q6_proxy_clk_vote_cnt > 0)) {
IPA_ACTIVE_CLIENTS_INC_SPECIAL("PROXY_CLK_VOTE");
+ ipa3_ctx->q6_proxy_clk_vote_cnt++;
ipa3_ctx->q6_proxy_clk_vote_valid = true;
}
mutex_unlock(&ipa3_ctx->q6_proxy_clk_vote_mutex);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c
index 053a581b1d26..b7ed529e9160 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c
@@ -1216,10 +1216,10 @@ static int ipa_fltrt_calc_extra_wrd_bytes(
static int ipa_fltrt_generate_hw_rule_bdy_from_eq(
const struct ipa_ipfltri_rule_eq *attrib, u8 **buf)
{
- int num_offset_meq_32 = attrib->num_offset_meq_32;
- int num_ihl_offset_range_16 = attrib->num_ihl_offset_range_16;
- int num_ihl_offset_meq_32 = attrib->num_ihl_offset_meq_32;
- int num_offset_meq_128 = attrib->num_offset_meq_128;
+ uint8_t num_offset_meq_32 = attrib->num_offset_meq_32;
+ uint8_t num_ihl_offset_range_16 = attrib->num_ihl_offset_range_16;
+ uint8_t num_ihl_offset_meq_32 = attrib->num_ihl_offset_meq_32;
+ uint8_t num_offset_meq_128 = attrib->num_offset_meq_128;
int i;
int extra_bytes;
u8 *extra;
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 d0aa42c81750..9fe7b6c59302 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
@@ -1566,6 +1566,8 @@ void ipahal_get_aggr_force_close_valmask(int ep_idx,
return;
}
+ memset(valmask, 0, sizeof(struct ipahal_reg_valmask));
+
if (ipahal_ctx->hw_type <= IPA_HW_v3_1) {
shft = IPA_AGGR_FORCE_CLOSE_AGGR_FORCE_CLOSE_PIPE_BITMAP_SHFT;
bmsk = IPA_AGGR_FORCE_CLOSE_AGGR_FORCE_CLOSE_PIPE_BITMAP_BMSK;
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
index 01ef670dba51..e49402afb6a2 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
@@ -678,6 +678,8 @@ static int ipa3_wwan_add_ul_flt_rule_to_ipa(void)
param->global = false;
param->num_rules = (uint8_t)1;
+ memset(req, 0, sizeof(struct ipa_fltr_installed_notif_req_msg_v01));
+
for (i = 0; i < rmnet_ipa3_ctx->num_q6_rules; i++) {
param->ip = ipa3_qmi_ctx->q6_ul_filter_rule[i].ip;
memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
@@ -1651,8 +1653,8 @@ static int ipa3_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
/* Get driver name */
case RMNET_IOCTL_GET_DRIVER_NAME:
memcpy(&extend_ioctl_data.u.if_name,
- IPA_NETDEV()->name,
- sizeof(IFNAMSIZ));
+ IPA_NETDEV()->name, IFNAMSIZ);
+ extend_ioctl_data.u.if_name[IFNAMSIZ - 1] = '\0';
if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
&extend_ioctl_data,
sizeof(struct rmnet_ioctl_extended_s)))
@@ -1745,6 +1747,7 @@ static int ipa3_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
sizeof(wan_msg->upstream_ifname);
strlcpy(wan_msg->upstream_ifname,
extend_ioctl_data.u.if_name, len);
+ wan_msg->upstream_ifname[len-1] = '\0';
memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
msg_meta.msg_type = WAN_XLAT_CONNECT;
msg_meta.msg_len = sizeof(struct ipa_wan_msg);
diff --git a/drivers/platform/msm/ipa/test/ipa_ut_framework.c b/drivers/platform/msm/ipa/test/ipa_ut_framework.c
index 3bf9ac11f2d1..dfc8442e0862 100644
--- a/drivers/platform/msm/ipa/test/ipa_ut_framework.c
+++ b/drivers/platform/msm/ipa/test/ipa_ut_framework.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -215,6 +215,10 @@ static ssize_t ipa_ut_dbgfs_meta_test_write(struct file *file,
IPA_UT_DBG("Entry\n");
mutex_lock(&ipa_ut_ctx->lock);
+ if (file == NULL) {
+ rc = -EFAULT;
+ goto unlock_mutex;
+ }
suite = file->f_inode->i_private;
ipa_assert_on(!suite);
meta_type = (long)(file->private_data);
@@ -470,6 +474,10 @@ static ssize_t ipa_ut_dbgfs_test_write(struct file *file,
IPA_UT_DBG("Entry\n");
mutex_lock(&ipa_ut_ctx->lock);
+ if (file == NULL) {
+ rc = -EFAULT;
+ goto unlock_mutex;
+ }
test = file->f_inode->i_private;
ipa_assert_on(!test);
diff --git a/drivers/platform/msm/mhi/mhi_bhi.c b/drivers/platform/msm/mhi/mhi_bhi.c
index 68ef2595f3c3..a931b1c139bc 100644
--- a/drivers/platform/msm/mhi/mhi_bhi.c
+++ b/drivers/platform/msm/mhi/mhi_bhi.c
@@ -641,7 +641,6 @@ int bhi_probe(struct mhi_device_ctxt *mhi_dev_ctxt)
image += to_copy;
}
- fw_table->sequence++;
release_firmware(firmware);
/* allocate memory and setup rddm table */
@@ -662,7 +661,6 @@ int bhi_probe(struct mhi_device_ctxt *mhi_dev_ctxt)
rddm_table->bhie_mem_info[i].phys_addr;
sg_dma_len(itr) = size;
}
- rddm_table->sequence++;
} else {
/* out of memory for rddm, not fatal error */
mhi_log(mhi_dev_ctxt, MHI_MSG_INFO,
diff --git a/drivers/platform/msm/mhi/mhi_iface.c b/drivers/platform/msm/mhi/mhi_iface.c
index ce6d1257cfbb..7423c13842fa 100644
--- a/drivers/platform/msm/mhi/mhi_iface.c
+++ b/drivers/platform/msm/mhi/mhi_iface.c
@@ -459,6 +459,7 @@ static int mhi_plat_probe(struct platform_device *pdev)
return r;
}
INIT_WORK(&bhi_ctxt->fw_load_work, bhi_firmware_download);
+ bhi_ctxt->fw_table.sequence = 1;
}
mhi_dev_ctxt->flags.bb_required =
diff --git a/drivers/platform/msm/mhi/mhi_main.c b/drivers/platform/msm/mhi/mhi_main.c
index 739915c4af6f..9ee459806ab5 100644
--- a/drivers/platform/msm/mhi/mhi_main.c
+++ b/drivers/platform/msm/mhi/mhi_main.c
@@ -1898,6 +1898,7 @@ int mhi_register_device(struct mhi_device *mhi_device,
if (mhi_device->support_rddm) {
mhi_dev_ctxt->bhi_ctxt.support_rddm = true;
mhi_dev_ctxt->bhi_ctxt.rddm_size = mhi_device->rddm_size;
+ mhi_dev_ctxt->bhi_ctxt.rddm_table.sequence = 1;
mhi_log(mhi_dev_ctxt, MHI_MSG_INFO,
"Device support rddm of size:0x%lx bytes\n",
diff --git a/drivers/platform/msm/sps/bam.c b/drivers/platform/msm/sps/bam.c
index c94536398dac..8eb29a3fc66d 100644
--- a/drivers/platform/msm/sps/bam.c
+++ b/drivers/platform/msm/sps/bam.c
@@ -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
@@ -707,7 +707,7 @@ static inline u32 bam_get_register_offset(void *base, enum bam_regs reg,
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return SPS_ERROR;
}
@@ -756,7 +756,7 @@ static inline u32 bam_read_reg(void *base, enum bam_regs reg, u32 param)
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return SPS_ERROR;
}
@@ -767,7 +767,7 @@ static inline u32 bam_read_reg(void *base, enum bam_regs reg, u32 param)
return offset;
}
val = ioread32(dev->base + offset);
- SPS_DBG(dev, "sps:bam 0x%p(va) offset 0x%x reg 0x%x r_val 0x%x.\n",
+ SPS_DBG(dev, "sps:bam 0x%pK(va) offset 0x%x reg 0x%x r_val 0x%x.\n",
dev->base, offset, reg, val);
return val;
}
@@ -788,7 +788,7 @@ static inline u32 bam_read_reg_field(void *base, enum bam_regs reg, u32 param,
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return SPS_ERROR;
}
@@ -802,7 +802,7 @@ static inline u32 bam_read_reg_field(void *base, enum bam_regs reg, u32 param,
val = ioread32(dev->base + offset);
val &= mask; /* clear other bits */
val >>= shift;
- SPS_DBG(dev, "sps:bam 0x%p(va) read reg 0x%x mask 0x%x r_val 0x%x.\n",
+ SPS_DBG(dev, "sps:bam 0x%pK(va) read reg 0x%x mask 0x%x r_val 0x%x.\n",
dev->base, offset, mask, val);
return val;
}
@@ -823,7 +823,7 @@ static inline void bam_write_reg(void *base, enum bam_regs reg,
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return;
}
@@ -834,7 +834,7 @@ static inline void bam_write_reg(void *base, enum bam_regs reg,
return;
}
iowrite32(val, dev->base + offset);
- SPS_DBG(dev, "sps:bam 0x%p(va) write reg 0x%x w_val 0x%x.\n",
+ SPS_DBG(dev, "sps:bam 0x%pK(va) write reg 0x%x w_val 0x%x.\n",
dev->base, offset, val);
}
@@ -854,7 +854,7 @@ static inline void bam_write_reg_field(void *base, enum bam_regs reg,
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return;
}
@@ -870,7 +870,7 @@ static inline void bam_write_reg_field(void *base, enum bam_regs reg,
tmp &= ~mask; /* clear written bits */
val = tmp | (val << shift);
iowrite32(val, dev->base + offset);
- SPS_DBG(dev, "sps:bam 0x%p(va) write reg 0x%x w_val 0x%x.\n",
+ SPS_DBG(dev, "sps:bam 0x%pK(va) write reg 0x%x w_val 0x%x.\n",
dev->base, offset, val);
}
@@ -888,28 +888,28 @@ int bam_init(void *base, u32 ee,
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return SPS_ERROR;
}
- SPS_DBG3(dev, "sps:%s:bam=%pa 0x%p(va).ee=%d.", __func__,
+ SPS_DBG3(dev, "sps:%s:bam=%pa 0x%pK(va).ee=%d.", __func__,
BAM_ID(dev), dev->base, ee);
ver = bam_read_reg_field(base, REVISION, 0, BAM_REVISION);
if ((ver < BAM_MIN_VERSION) || (ver > BAM_MAX_VERSION)) {
- SPS_ERR(dev, "sps:bam 0x%p(va) Invalid BAM REVISION 0x%x.\n",
+ SPS_ERR(dev, "sps:bam 0x%pK(va) Invalid BAM REVISION 0x%x.\n",
dev->base, ver);
return -ENODEV;
} else
- SPS_DBG(dev, "sps:REVISION of BAM 0x%p is 0x%x.\n",
+ SPS_DBG(dev, "sps:REVISION of BAM 0x%pK is 0x%x.\n",
dev->base, ver);
if (summing_threshold == 0) {
summing_threshold = 4;
SPS_ERR(dev,
- "sps:bam 0x%p(va) summing_threshold is zero,use default 4.\n",
+ "sps:bam 0x%pK(va) summing_threshold is zero,use default 4.\n",
dev->base);
}
@@ -1009,12 +1009,12 @@ int bam_security_init(void *base, u32 ee, u32 vmid, u32 pipe_mask)
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return SPS_ERROR;
}
- SPS_DBG3(dev, "sps:%s:bam=%pa 0x%p(va).", __func__,
+ SPS_DBG3(dev, "sps:%s:bam=%pa 0x%pK(va).", __func__,
BAM_ID(dev), dev->base);
/*
@@ -1025,14 +1025,14 @@ int bam_security_init(void *base, u32 ee, u32 vmid, u32 pipe_mask)
num_pipes = bam_read_reg_field(base, NUM_PIPES, 0, BAM_NUM_PIPES);
if (version < 3 || version > 0x1F) {
SPS_ERR(dev,
- "sps:bam 0x%p(va) security is not supported for this BAM version 0x%x.\n",
+ "sps:bam 0x%pK(va) security is not supported for this BAM version 0x%x.\n",
dev->base, version);
return -ENODEV;
}
if (num_pipes > BAM_MAX_PIPES) {
SPS_ERR(dev,
- "sps:bam 0x%p(va) the number of pipes is more than the maximum number allowed.\n",
+ "sps:bam 0x%pK(va) the number of pipes is more than the maximum number allowed.\n",
dev->base);
return -ENODEV;
}
@@ -1080,12 +1080,12 @@ int bam_check(void *base, u32 *version, u32 ee, u32 *num_pipes)
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return SPS_ERROR;
}
- SPS_DBG3(dev, "sps:%s:bam=%pa 0x%p(va).",
+ SPS_DBG3(dev, "sps:%s:bam=%pa 0x%pK(va).",
__func__, BAM_ID(dev), dev->base);
if (!enhd_pipe)
@@ -1094,7 +1094,7 @@ int bam_check(void *base, u32 *version, u32 ee, u32 *num_pipes)
enabled = bam_get_pipe_attr(base, ee, true);
if (!enabled) {
- SPS_ERR(dev, "sps:%s:bam 0x%p(va) is not enabled.\n",
+ SPS_ERR(dev, "sps:%s:bam 0x%pK(va) is not enabled.\n",
__func__, dev->base);
return -ENODEV;
}
@@ -1110,7 +1110,7 @@ int bam_check(void *base, u32 *version, u32 ee, u32 *num_pipes)
/* Check BAM version */
if ((ver < BAM_MIN_VERSION) || (ver > BAM_MAX_VERSION)) {
- SPS_ERR(dev, "sps:%s:bam 0x%p(va) Invalid BAM version 0x%x.\n",
+ SPS_ERR(dev, "sps:%s:bam 0x%pK(va) Invalid BAM version 0x%x.\n",
__func__, dev->base, ver);
return -ENODEV;
}
@@ -1127,11 +1127,11 @@ void bam_exit(void *base, u32 ee)
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return;
}
- SPS_DBG3(dev, "sps:%s:bam=%pa 0x%p(va).ee=%d.",
+ SPS_DBG3(dev, "sps:%s:bam=%pa 0x%pK(va).ee=%d.",
__func__, BAM_ID(dev), dev->base, ee);
bam_write_reg_field(base, IRQ_SRCS_MSK_EE, ee, BAM_IRQ, 0);
@@ -1155,7 +1155,7 @@ void bam_output_register_content(void *base, u32 ee)
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return;
}
@@ -1166,7 +1166,7 @@ void bam_output_register_content(void *base, u32 ee)
num_pipes = bam_read_reg_field(base, NUM_PIPES, 0,
BAM_NUM_PIPES);
- SPS_INFO(dev, "sps:bam %pa 0x%p(va) has %d pipes.",
+ SPS_INFO(dev, "sps:bam %pa 0x%pK(va) has %d pipes.",
BAM_ID(dev), dev->base, num_pipes);
pipe_attr = enhd_pipe ?
@@ -1193,7 +1193,7 @@ u32 bam_check_irq_source(void *base, u32 ee, u32 mask,
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return SPS_ERROR;
}
@@ -1205,13 +1205,13 @@ u32 bam_check_irq_source(void *base, u32 ee, u32 mask,
status = bam_read_reg(base, IRQ_STTS, 0);
if (status & IRQ_STTS_BAM_ERROR_IRQ) {
- SPS_ERR(dev, "sps:bam %pa 0x%p(va);bam irq status="
+ SPS_ERR(dev, "sps:bam %pa 0x%pK(va);bam irq status="
"0x%x.\nsps: BAM_ERROR_IRQ\n",
BAM_ID(dev), dev->base, status);
bam_output_register_content(base, ee);
*cb_case = SPS_CALLBACK_BAM_ERROR_IRQ;
} else if (status & IRQ_STTS_BAM_HRESP_ERR_IRQ) {
- SPS_ERR(dev, "sps:bam %pa 0x%p(va);bam irq status="
+ SPS_ERR(dev, "sps:bam %pa 0x%pK(va);bam irq status="
"0x%x.\nsps: BAM_HRESP_ERR_IRQ\n",
BAM_ID(dev), dev->base, status);
bam_output_register_content(base, ee);
@@ -1219,13 +1219,13 @@ u32 bam_check_irq_source(void *base, u32 ee, u32 mask,
#ifdef CONFIG_SPS_SUPPORT_NDP_BAM
} else if (status & IRQ_STTS_BAM_TIMER_IRQ) {
SPS_DBG1(dev,
- "sps:bam 0x%p(va);receive BAM_TIMER_IRQ\n",
+ "sps:bam 0x%pK(va);receive BAM_TIMER_IRQ\n",
dev->base);
*cb_case = SPS_CALLBACK_BAM_TIMER_IRQ;
#endif
} else
SPS_INFO(dev,
- "sps:bam %pa 0x%p(va);bam irq status=0x%x.\n",
+ "sps:bam %pa 0x%pK(va);bam irq status=0x%x.\n",
BAM_ID(dev), dev->base, status);
bam_write_reg(base, IRQ_CLR, 0, status);
@@ -1243,11 +1243,11 @@ void bam_pipe_reset(void *base, u32 pipe)
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return;
}
- SPS_DBG2(dev, "sps:%s:bam=%pa 0x%p(va).pipe=%d.",
+ SPS_DBG2(dev, "sps:%s:bam=%pa 0x%pK(va).pipe=%d.",
__func__, BAM_ID(dev), dev->base, pipe);
bam_write_reg(base, P_RST, pipe, 1);
@@ -1264,11 +1264,11 @@ void bam_disable_pipe(void *base, u32 pipe)
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return;
}
- SPS_DBG2(dev, "sps:%s:bam=0x%p(va).pipe=%d.", __func__, base, pipe);
+ SPS_DBG2(dev, "sps:%s:bam=0x%pK(va).pipe=%d.", __func__, base, pipe);
bam_write_reg_field(base, P_CTRL, pipe, P_EN, 0);
wmb(); /* ensure pipe is disabled */
}
@@ -1281,20 +1281,20 @@ bool bam_pipe_check_zlt(void *base, u32 pipe)
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return false;
}
if (bam_read_reg_field(base, P_HALT, pipe, P_HALT_P_LAST_DESC_ZLT)) {
SPS_DBG(dev,
- "sps:%s:bam=0x%p(va).pipe=%d: the last desc is ZLT.",
+ "sps:%s:bam=0x%pK(va).pipe=%d: the last desc is ZLT.",
__func__, base, pipe);
return true;
}
SPS_DBG(dev,
- "sps:%s:bam=0x%p(va).pipe=%d: the last desc is not ZLT.",
+ "sps:%s:bam=0x%pK(va).pipe=%d: the last desc is not ZLT.",
__func__, base, pipe);
return false;
}
@@ -1307,20 +1307,20 @@ bool bam_pipe_check_pipe_empty(void *base, u32 pipe)
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return false;
}
if (bam_read_reg_field(base, P_HALT, pipe, P_HALT_P_PIPE_EMPTY)) {
SPS_DBG(dev,
- "sps:%s:bam=0x%p(va).pipe=%d: desc FIFO is empty.",
+ "sps:%s:bam=0x%pK(va).pipe=%d: desc FIFO is empty.",
__func__, base, pipe);
return true;
}
SPS_DBG(dev,
- "sps:%s:bam=0x%p(va).pipe=%d: desc FIFO is not empty.",
+ "sps:%s:bam=0x%pK(va).pipe=%d: desc FIFO is not empty.",
__func__, base, pipe);
return false;
}
@@ -1334,11 +1334,11 @@ int bam_pipe_init(void *base, u32 pipe, struct bam_pipe_parameters *param,
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return SPS_ERROR;
}
- SPS_DBG2(dev, "sps:%s:bam=%pa 0x%p(va).pipe=%d.",
+ SPS_DBG2(dev, "sps:%s:bam=%pa 0x%pK(va).pipe=%d.",
__func__, BAM_ID(dev), dev->base, pipe);
/* Reset the BAM pipe */
@@ -1372,7 +1372,7 @@ int bam_pipe_init(void *base, u32 pipe, struct bam_pipe_parameters *param,
bam_write_reg_field(base, P_CTRL, pipe, P_LOCK_GROUP,
param->lock_group);
- SPS_DBG(dev, "sps:bam=0x%p(va).pipe=%d.lock_group=%d.\n",
+ SPS_DBG(dev, "sps:bam=0x%pK(va).pipe=%d.lock_group=%d.\n",
dev->base, pipe, param->lock_group);
#endif
@@ -1388,7 +1388,7 @@ int bam_pipe_init(void *base, u32 pipe, struct bam_pipe_parameters *param,
bam_write_reg(base, P_EVNT_DEST_ADDR, pipe, peer_dest_addr);
- SPS_DBG2(dev, "sps:bam=0x%p(va).pipe=%d.peer_bam=0x%x."
+ SPS_DBG2(dev, "sps:bam=0x%pK(va).pipe=%d.peer_bam=0x%x."
"peer_pipe=%d.\n",
dev->base, pipe,
(u32) param->peer_phys_addr,
@@ -1424,11 +1424,11 @@ void bam_pipe_exit(void *base, u32 pipe, u32 ee)
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return;
}
- SPS_DBG2(dev, "sps:%s:bam=%pa 0x%p(va).pipe=%d.",
+ SPS_DBG2(dev, "sps:%s:bam=%pa 0x%pK(va).pipe=%d.",
__func__, BAM_ID(dev), dev->base, pipe);
bam_write_reg(base, P_IRQ_EN, pipe, 0);
@@ -1449,15 +1449,15 @@ void bam_pipe_enable(void *base, u32 pipe)
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return;
}
- SPS_DBG2(dev, "sps:%s:bam=%pa 0x%p(va).pipe=%d.",
+ SPS_DBG2(dev, "sps:%s:bam=%pa 0x%pK(va).pipe=%d.",
__func__, BAM_ID(dev), dev->base, pipe);
if (bam_read_reg_field(base, P_CTRL, pipe, P_EN))
- SPS_DBG2(dev, "sps:bam=0x%p(va).pipe=%d is already enabled.\n",
+ SPS_DBG2(dev, "sps:bam=0x%pK(va).pipe=%d is already enabled.\n",
dev->base, pipe);
else
bam_write_reg_field(base, P_CTRL, pipe, P_EN, 1);
@@ -1472,11 +1472,11 @@ void bam_pipe_disable(void *base, u32 pipe)
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return;
}
- SPS_DBG2(dev, "sps:%s:bam=%pa 0x%p(va).pipe=%d.",
+ SPS_DBG2(dev, "sps:%s:bam=%pa 0x%pK(va).pipe=%d.",
__func__, BAM_ID(dev), dev->base, pipe);
bam_write_reg_field(base, P_CTRL, pipe, P_EN, 0);
@@ -1501,12 +1501,12 @@ void bam_pipe_set_irq(void *base, u32 pipe, enum bam_enable irq_en,
struct sps_bam *dev = to_sps_bam_dev(base);
if ((dev == NULL) || (&dev->base != base)) {
- SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n",
+ SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n",
__func__, base);
return;
}
SPS_DBG2(dev,
- "sps:%s:bam=%pa 0x%p(va).pipe=%d; irq_en:%d; src_mask:0x%x; ee:%d.\n",
+ "sps:%s:bam=%pa 0x%pK(va).pipe=%d; irq_en:%d; src_mask:0x%x; ee:%d.\n",
__func__, BAM_ID(dev), dev->base, pipe,
irq_en, src_mask, ee);
if (src_mask & BAM_PIPE_IRQ_RST_ERROR) {
diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c
index e7710f929e71..367e0e39dc23 100644
--- a/drivers/platform/msm/sps/sps.c
+++ b/drivers/platform/msm/sps/sps.c
@@ -931,7 +931,7 @@ static int sps_device_init(void)
goto exit_err;
}
- SPS_DBG3(sps, "sps:bamdma_bam.phys=%pa.virt=0x%p.",
+ SPS_DBG3(sps, "sps:bamdma_bam.phys=%pa.virt=0x%pK.",
&bamdma_props.phys_addr,
bamdma_props.virt_addr);
@@ -946,7 +946,7 @@ static int sps_device_init(void)
goto exit_err;
}
- SPS_DBG3(sps, "sps:bamdma_dma.phys=%pa.virt=0x%p.",
+ SPS_DBG3(sps, "sps:bamdma_dma.phys=%pa.virt=0x%pK.",
&bamdma_props.periph_phys_addr,
bamdma_props.periph_virt_addr);
@@ -2322,11 +2322,8 @@ int sps_deregister_bam_device(unsigned long dev_handle)
mutex_lock(&bam->lock);
sps_bam_device_de_init(bam);
mutex_unlock(&bam->lock);
- ipc_log_context_destroy(bam->ipc_log0);
ipc_log_context_destroy(bam->ipc_log1);
ipc_log_context_destroy(bam->ipc_log2);
- ipc_log_context_destroy(bam->ipc_log3);
- ipc_log_context_destroy(bam->ipc_log4);
if (bam->props.virt_size)
(void)iounmap(bam->props.virt_addr);
diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c
index 38a6474dd06f..74b6894f889f 100644
--- a/drivers/platform/msm/sps/sps_bam.c
+++ b/drivers/platform/msm/sps/sps_bam.c
@@ -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
@@ -508,12 +508,12 @@ int sps_bam_enable(struct sps_bam *dev)
if (dev->props.logging_number > 0)
dev->props.logging_number--;
SPS_INFO(dev,
- "sps:BAM %pa (va:0x%p) enabled: ver:0x%x, number of pipes:%d\n",
+ "sps:BAM %pa (va:0x%pK) enabled: ver:0x%x, number of pipes:%d\n",
BAM_ID(dev), dev->base, dev->version,
dev->props.num_pipes);
} else
SPS_DBG3(dev,
- "sps:BAM %pa (va:0x%p) enabled: ver:0x%x, number of pipes:%d\n",
+ "sps:BAM %pa (va:0x%pK) enabled: ver:0x%x, number of pipes:%d\n",
BAM_ID(dev), dev->base, dev->version,
dev->props.num_pipes);
@@ -2127,7 +2127,7 @@ int sps_bam_pipe_get_event(struct sps_bam *dev,
if (pipe->sys.no_queue) {
SPS_ERR(dev,
- "sps:Invalid connection for event: BAM %pa pipe %d context 0x%p\n",
+ "sps:Invalid connection for event: BAM %pa pipe %d context 0x%pK\n",
BAM_ID(dev), pipe_index, pipe);
notify->event_id = SPS_EVENT_INVALID;
return SPS_ERROR;
diff --git a/drivers/platform/msm/sps/sps_mem.c b/drivers/platform/msm/sps/sps_mem.c
index becb9a15882a..db36e64f96d8 100644
--- a/drivers/platform/msm/sps/sps_mem.c
+++ b/drivers/platform/msm/sps/sps_mem.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2011-2013, 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, 2015, 2017, The Linux Foundation.
+ * All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -129,7 +130,7 @@ int sps_mem_init(phys_addr_t pipemem_phys_base, u32 pipemem_size)
iomem_offset = 0;
SPS_DBG(sps,
- "sps:sps_mem_init.iomem_phys=%pa,iomem_virt=0x%p.",
+ "sps:sps_mem_init.iomem_phys=%pa,iomem_virt=0x%pK.",
&iomem_phys, iomem_virt);
}
diff --git a/drivers/platform/msm/sps/sps_rm.c b/drivers/platform/msm/sps/sps_rm.c
index ec64e6c25465..db5db28d5f9e 100644
--- a/drivers/platform/msm/sps/sps_rm.c
+++ b/drivers/platform/msm/sps/sps_rm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2015, 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -723,8 +723,7 @@ int sps_rm_state_change(struct sps_pipe *pipe, u32 state)
state == SPS_STATE_ALLOCATE) {
if (sps_rm_alloc(pipe)) {
SPS_ERR(pipe->bam,
- "sps:Fail to allocate resource for"
- " BAM 0x%p pipe %d.\n",
+ "sps:Fail to allocate resource for BAM 0x%pK pipe %d.\n",
pipe->bam, pipe->pipe_index);
return SPS_ERROR;
}
@@ -745,7 +744,7 @@ int sps_rm_state_change(struct sps_pipe *pipe, u32 state)
result = sps_bam_pipe_connect(pipe, &params);
if (result) {
SPS_ERR(pipe->bam,
- "sps:Failed to connect BAM 0x%p pipe %d",
+ "sps:Failed to connect BAM 0x%pK pipe %d",
pipe->bam, pipe->pipe_index);
return SPS_ERROR;
}
diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c
index 491dda6ff7e8..b1a57d8853e8 100644
--- a/drivers/power/supply/qcom/qpnp-fg-gen3.c
+++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c
@@ -2733,6 +2733,49 @@ static bool is_profile_load_required(struct fg_chip *chip)
return true;
}
+static void fg_update_batt_profile(struct fg_chip *chip)
+{
+ int rc, offset;
+ u8 val;
+
+ rc = fg_sram_read(chip, PROFILE_INTEGRITY_WORD,
+ SW_CONFIG_OFFSET, &val, 1, FG_IMA_DEFAULT);
+ if (rc < 0) {
+ pr_err("Error in reading SW_CONFIG_OFFSET, rc=%d\n", rc);
+ return;
+ }
+
+ /*
+ * If the RCONN had not been updated, no need to update battery
+ * profile. Else, update the battery profile so that the profile
+ * modified by bootloader or HLOS matches with the profile read
+ * from device tree.
+ */
+
+ if (!(val & RCONN_CONFIG_BIT))
+ return;
+
+ rc = fg_sram_read(chip, ESR_RSLOW_CHG_WORD,
+ ESR_RSLOW_CHG_OFFSET, &val, 1, FG_IMA_DEFAULT);
+ if (rc < 0) {
+ pr_err("Error in reading ESR_RSLOW_CHG_OFFSET, rc=%d\n", rc);
+ return;
+ }
+ offset = (ESR_RSLOW_CHG_WORD - PROFILE_LOAD_WORD) * 4
+ + ESR_RSLOW_CHG_OFFSET;
+ chip->batt_profile[offset] = val;
+
+ rc = fg_sram_read(chip, ESR_RSLOW_DISCHG_WORD,
+ ESR_RSLOW_DISCHG_OFFSET, &val, 1, FG_IMA_DEFAULT);
+ if (rc < 0) {
+ pr_err("Error in reading ESR_RSLOW_DISCHG_OFFSET, rc=%d\n", rc);
+ return;
+ }
+ offset = (ESR_RSLOW_DISCHG_WORD - PROFILE_LOAD_WORD) * 4
+ + ESR_RSLOW_DISCHG_OFFSET;
+ chip->batt_profile[offset] = val;
+}
+
static void clear_battery_profile(struct fg_chip *chip)
{
u8 val = 0;
@@ -2816,6 +2859,8 @@ static void profile_load_work(struct work_struct *work)
if (!chip->profile_available)
goto out;
+ fg_update_batt_profile(chip);
+
if (!is_profile_load_required(chip))
goto done;
@@ -2877,6 +2922,10 @@ done:
rc);
}
+ rc = fg_rconn_config(chip);
+ if (rc < 0)
+ pr_err("Error in configuring Rconn, rc=%d\n", rc);
+
batt_psy_initialized(chip);
fg_notify_charger(chip);
chip->profile_loaded = true;
@@ -4076,12 +4125,6 @@ static int fg_hw_init(struct fg_chip *chip)
return rc;
}
- rc = fg_rconn_config(chip);
- if (rc < 0) {
- pr_err("Error in configuring Rconn, rc=%d\n", rc);
- return rc;
- }
-
fg_encode(chip->sp, FG_SRAM_ESR_TIGHT_FILTER,
chip->dt.esr_tight_flt_upct, buf);
rc = fg_sram_write(chip, chip->sp[FG_SRAM_ESR_TIGHT_FILTER].addr_word,
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index 93512f155c52..7acf5fab573b 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -2695,17 +2695,13 @@ int smblib_set_prop_pd_voltage_max(struct smb_charger *chg,
return rc;
}
-int smblib_set_prop_pd_active(struct smb_charger *chg,
- const union power_supply_propval *val)
+static int __smblib_set_prop_pd_active(struct smb_charger *chg, bool pd_active)
{
int rc;
bool orientation, sink_attached, hvdcp;
u8 stat;
- if (!get_effective_result(chg->pd_allowed_votable))
- return -EINVAL;
-
- chg->pd_active = val->intval;
+ chg->pd_active = pd_active;
if (chg->pd_active) {
vote(chg->apsd_disable_votable, PD_VOTER, true, 0);
vote(chg->pd_allowed_votable, PD_VOTER, true, 0);
@@ -2793,6 +2789,15 @@ int smblib_set_prop_pd_active(struct smb_charger *chg,
return rc;
}
+int smblib_set_prop_pd_active(struct smb_charger *chg,
+ const union power_supply_propval *val)
+{
+ if (!get_effective_result(chg->pd_allowed_votable))
+ return -EINVAL;
+
+ return __smblib_set_prop_pd_active(chg, val->intval);
+}
+
int smblib_set_prop_ship_mode(struct smb_charger *chg,
const union power_supply_propval *val)
{
@@ -3544,6 +3549,13 @@ static void smblib_handle_hvdcp_check_timeout(struct smb_charger *chg,
/* enforce DCP ICL if specified */
vote(chg->usb_icl_votable, DCP_VOTER,
chg->dcp_icl_ua != -EINVAL, chg->dcp_icl_ua);
+
+ /*
+ * if pd is not allowed, then set pd_active = false right here,
+ * so that it starts the hvdcp engine
+ */
+ if (!get_effective_result(chg->pd_allowed_votable))
+ __smblib_set_prop_pd_active(chg, 0);
}
smblib_dbg(chg, PR_INTERRUPT, "IRQ: smblib_handle_hvdcp_check_timeout %s\n",
@@ -4188,7 +4200,7 @@ irqreturn_t smblib_handle_usb_typec_change(int irq, void *data)
if (chg->cc2_detach_wa_active || chg->typec_en_dis_active ||
chg->try_sink_active) {
- smblib_dbg(chg, PR_INTERRUPT, "Ignoring since %s active\n",
+ smblib_dbg(chg, PR_MISC | PR_INTERRUPT, "Ignoring since %s active\n",
chg->cc2_detach_wa_active ?
"cc2_detach_wa" : "typec_en_dis");
return IRQ_HANDLED;
@@ -4699,7 +4711,9 @@ static void smblib_legacy_detection_work(struct work_struct *work)
smblib_err(chg, "Couldn't disable type-c rc=%d\n", rc);
/* wait for the adapter to turn off VBUS */
- msleep(500);
+ msleep(1000);
+
+ smblib_dbg(chg, PR_MISC, "legacy workaround enabling typec\n");
rc = smblib_masked_write(chg,
TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
@@ -4708,7 +4722,7 @@ static void smblib_legacy_detection_work(struct work_struct *work)
smblib_err(chg, "Couldn't enable type-c rc=%d\n", rc);
/* wait for type-c detection to complete */
- msleep(100);
+ msleep(400);
rc = smblib_read(chg, TYPE_C_STATUS_5_REG, &stat);
if (rc < 0) {
@@ -4720,6 +4734,8 @@ static void smblib_legacy_detection_work(struct work_struct *work)
vote(chg->usb_icl_votable, LEGACY_UNKNOWN_VOTER, false, 0);
legacy = stat & TYPEC_LEGACY_CABLE_STATUS_BIT;
rp_high = chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_HIGH;
+ smblib_dbg(chg, PR_MISC, "legacy workaround done legacy = %d rp_high = %d\n",
+ legacy, rp_high);
if (!legacy || !rp_high)
vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER,
false, 0);
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index b0e2e292e3cb..bb6518159d12 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -510,7 +510,7 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
old_hdr->result = EIO;
break;
case DID_ERROR:
- old_hdr->result = (srp->sense_b[0] == 0 &&
+ old_hdr->result = (srp->sense_b[0] == 0 &&
hp->masked_status == GOOD) ? 0 : EIO;
break;
default:
@@ -898,8 +898,10 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
return -ENXIO;
if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR))
return -EFAULT;
+ mutex_lock(&sfp->parentdp->open_rel_lock);
result = sg_new_write(sfp, filp, p, SZ_SG_IO_HDR,
1, read_only, 1, &srp);
+ mutex_unlock(&sfp->parentdp->open_rel_lock);
if (result < 0)
return result;
result = wait_event_interruptible(sfp->read_wait,
@@ -939,8 +941,10 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
sfp->low_dma = 1;
if ((0 == sfp->low_dma) && !sfp->res_in_use) {
val = (int) sfp->reserve.bufflen;
+ mutex_lock(&sfp->parentdp->open_rel_lock);
sg_remove_scat(sfp, &sfp->reserve);
sg_build_reserve(sfp, val);
+ mutex_unlock(&sfp->parentdp->open_rel_lock);
}
} else {
if (atomic_read(&sdp->detaching))
@@ -1009,8 +1013,8 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
result = get_user(val, ip);
if (result)
return result;
- if (val < 0)
- return -EINVAL;
+ if (val < 0)
+ return -EINVAL;
val = min_t(int, val,
max_sectors_bytes(sdp->device->request_queue));
mutex_lock(&sfp->f_mutex);
@@ -1020,9 +1024,10 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
mutex_unlock(&sfp->f_mutex);
return -EBUSY;
}
-
+ mutex_lock(&sfp->parentdp->open_rel_lock);
sg_remove_scat(sfp, &sfp->reserve);
sg_build_reserve(sfp, val);
+ mutex_unlock(&sfp->parentdp->open_rel_lock);
}
mutex_unlock(&sfp->f_mutex);
return 0;
@@ -1149,14 +1154,14 @@ static long sg_compat_ioctl(struct file *filp, unsigned int cmd_in, unsigned lon
return -ENXIO;
sdev = sdp->device;
- if (sdev->host->hostt->compat_ioctl) {
+ if (sdev->host->hostt->compat_ioctl) {
int ret;
ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);
return ret;
}
-
+
return -ENOIOCTLCMD;
}
#endif
@@ -1646,7 +1651,7 @@ init_sg(void)
else
def_reserved_size = sg_big_buff;
- rc = register_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0),
+ rc = register_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0),
SG_MAX_DEVS, "sg");
if (rc)
return rc;
@@ -2304,7 +2309,7 @@ static const struct file_operations adio_fops = {
};
static int sg_proc_single_open_dressz(struct inode *inode, struct file *file);
-static ssize_t sg_proc_write_dressz(struct file *filp,
+static ssize_t sg_proc_write_dressz(struct file *filp,
const char __user *buffer, size_t count, loff_t *off);
static const struct file_operations dressz_fops = {
.owner = THIS_MODULE,
@@ -2444,7 +2449,7 @@ static int sg_proc_single_open_adio(struct inode *inode, struct file *file)
return single_open(file, sg_proc_seq_show_int, &sg_allow_dio);
}
-static ssize_t
+static ssize_t
sg_proc_write_adio(struct file *filp, const char __user *buffer,
size_t count, loff_t *off)
{
@@ -2465,7 +2470,7 @@ static int sg_proc_single_open_dressz(struct inode *inode, struct file *file)
return single_open(file, sg_proc_seq_show_int, &sg_big_buff);
}
-static ssize_t
+static ssize_t
sg_proc_write_dressz(struct file *filp, const char __user *buffer,
size_t count, loff_t *off)
{
@@ -2640,6 +2645,9 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp)
seq_puts(s, srp->done ?
((1 == srp->done) ? "rcv:" : "fin:")
: "act:");
+ seq_printf(s, srp->done ?
+ ((1 == srp->done) ? "rcv:" : "fin:")
+ : "act:");
seq_printf(s, " id=%d blen=%d",
srp->header.pack_id, blen);
if (srp->done)
diff --git a/drivers/scsi/ufs/ufs-qcom-debugfs.c b/drivers/scsi/ufs/ufs-qcom-debugfs.c
index 494ecd1c5f79..db4ecec6cf2f 100644
--- a/drivers/scsi/ufs/ufs-qcom-debugfs.c
+++ b/drivers/scsi/ufs/ufs-qcom-debugfs.c
@@ -121,7 +121,8 @@ static ssize_t ufs_qcom_dbg_testbus_cfg_write(struct file *file,
struct ufs_hba *hba = host->hba;
- ret = simple_write_to_buffer(configuration, TESTBUS_CFG_BUFF_LINE_SIZE,
+ ret = simple_write_to_buffer(configuration,
+ TESTBUS_CFG_BUFF_LINE_SIZE - 1,
&buff_pos, ubuf, cnt);
if (ret < 0) {
dev_err(host->hba->dev, "%s: failed to read user data\n",
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 35575c071760..34109bbe69ac 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -884,7 +884,6 @@ static void ufshcd_print_host_state(struct ufs_hba *hba)
hba->capabilities, hba->caps);
dev_err(hba->dev, "quirks=0x%x, dev. quirks=0x%x\n", hba->quirks,
hba->dev_quirks);
- ufshcd_print_fsm_state(hba);
}
/**
@@ -6834,6 +6833,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
*/
scsi_print_command(cmd);
if (!hba->req_abort_count) {
+ ufshcd_print_fsm_state(hba);
ufshcd_print_host_regs(hba);
ufshcd_print_host_state(hba);
ufshcd_print_pwr_info(hba);
@@ -8760,7 +8760,6 @@ static int ufshcd_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
goto enable_gating;
}
- flush_work(&hba->eeh_work);
ret = ufshcd_link_state_transition(hba, req_link_state, 1);
if (ret)
goto set_dev_active;
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index 83efbbe25e6b..d9d49e861f03 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -2511,8 +2511,17 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
if (code != SUBSYS_BEFORE_SHUTDOWN)
return NOTIFY_OK;
- if (test_bit(ICNSS_PDR_REGISTERED, &priv->state))
+ if (test_bit(ICNSS_PDR_REGISTERED, &priv->state)) {
+ set_bit(ICNSS_FW_DOWN, &priv->state);
+ icnss_ignore_qmi_timeout(true);
+
+ fw_down_data.crashed = !!notif->crashed;
+ if (test_bit(ICNSS_FW_READY, &priv->state))
+ icnss_call_driver_uevent(priv,
+ ICNSS_UEVENT_FW_DOWN,
+ &fw_down_data);
return NOTIFY_OK;
+ }
icnss_pr_info("Modem went down, state: 0x%lx, crashed: %d\n",
priv->state, notif->crashed);
@@ -2646,14 +2655,18 @@ static int icnss_service_notifier_notify(struct notifier_block *nb,
icnss_pr_info("PD service down, pd_state: %d, state: 0x%lx: cause: %s\n",
*state, priv->state, icnss_pdr_cause[cause]);
event_post:
- set_bit(ICNSS_FW_DOWN, &priv->state);
- icnss_ignore_qmi_timeout(true);
- clear_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state);
+ if (!test_bit(ICNSS_FW_DOWN, &priv->state)) {
+ set_bit(ICNSS_FW_DOWN, &priv->state);
+ icnss_ignore_qmi_timeout(true);
- fw_down_data.crashed = event_data->crashed;
- if (test_bit(ICNSS_FW_READY, &priv->state))
- icnss_call_driver_uevent(priv, ICNSS_UEVENT_FW_DOWN,
- &fw_down_data);
+ fw_down_data.crashed = event_data->crashed;
+ if (test_bit(ICNSS_FW_READY, &priv->state))
+ icnss_call_driver_uevent(priv,
+ ICNSS_UEVENT_FW_DOWN,
+ &fw_down_data);
+ }
+
+ clear_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state);
icnss_driver_event_post(ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
ICNSS_EVENT_SYNC, event_data);
done:
diff --git a/drivers/soc/qcom/msm_bus/msm_bus_dbg_voter.c b/drivers/soc/qcom/msm_bus/msm_bus_dbg_voter.c
index a876484859eb..ba1adb8acea7 100644
--- a/drivers/soc/qcom/msm_bus/msm_bus_dbg_voter.c
+++ b/drivers/soc/qcom/msm_bus/msm_bus_dbg_voter.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is Mree software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -27,6 +27,7 @@ struct msm_bus_floor_client_type {
};
static struct class *bus_floor_class;
+static DEFINE_RT_MUTEX(msm_bus_floor_vote_lock);
#define MAX_VOTER_NAME (50)
#define DEFAULT_NODE_WIDTH (8)
#define DBG_NAME(s) (strnstr(s, "-", 7) + 1)
@@ -64,18 +65,22 @@ static ssize_t bus_floor_active_only_store(struct device *dev,
{
struct msm_bus_floor_client_type *cl;
+ rt_mutex_lock(&msm_bus_floor_vote_lock);
cl = dev_get_drvdata(dev);
if (!cl) {
pr_err("%s: Can't find cl", __func__);
+ rt_mutex_unlock(&msm_bus_floor_vote_lock);
return 0;
}
if (sscanf(buf, "%d", &cl->active_only) != 1) {
pr_err("%s:return error", __func__);
+ rt_mutex_unlock(&msm_bus_floor_vote_lock);
return -EINVAL;
}
+ rt_mutex_unlock(&msm_bus_floor_vote_lock);
return n;
}
@@ -100,20 +105,24 @@ static ssize_t bus_floor_vote_store(struct device *dev,
struct msm_bus_floor_client_type *cl;
int ret = 0;
+ rt_mutex_lock(&msm_bus_floor_vote_lock);
cl = dev_get_drvdata(dev);
if (!cl) {
pr_err("%s: Can't find cl", __func__);
+ rt_mutex_unlock(&msm_bus_floor_vote_lock);
return 0;
}
if (sscanf(buf, "%llu", &cl->cur_vote_hz) != 1) {
pr_err("%s:return error", __func__);
+ rt_mutex_unlock(&msm_bus_floor_vote_lock);
return -EINVAL;
}
ret = msm_bus_floor_vote_context(dev_name(dev), cl->cur_vote_hz,
cl->active_only);
+ rt_mutex_unlock(&msm_bus_floor_vote_lock);
return n;
}
@@ -126,15 +135,18 @@ static ssize_t bus_floor_vote_store_api(struct device *dev,
char name[10];
u64 vote_khz = 0;
+ rt_mutex_lock(&msm_bus_floor_vote_lock);
cl = dev_get_drvdata(dev);
if (!cl) {
pr_err("%s: Can't find cl", __func__);
+ rt_mutex_unlock(&msm_bus_floor_vote_lock);
return 0;
}
if (sscanf(buf, "%9s %llu", name, &vote_khz) != 2) {
pr_err("%s:return error", __func__);
+ rt_mutex_unlock(&msm_bus_floor_vote_lock);
return -EINVAL;
}
@@ -142,6 +154,7 @@ static ssize_t bus_floor_vote_store_api(struct device *dev,
__func__, name, vote_khz);
ret = msm_bus_floor_vote(name, vote_khz);
+ rt_mutex_unlock(&msm_bus_floor_vote_lock);
return n;
}
diff --git a/drivers/soc/qcom/qdsp6v2/msm_audio_ion_vm.c b/drivers/soc/qcom/qdsp6v2/msm_audio_ion_vm.c
index a3aa8823d8ce..afc40461e8e8 100644
--- a/drivers/soc/qcom/qdsp6v2/msm_audio_ion_vm.c
+++ b/drivers/soc/qcom/qdsp6v2/msm_audio_ion_vm.c
@@ -22,7 +22,6 @@
#include <linux/msm_audio_ion.h>
#include <linux/habmm.h>
#include "../../../staging/android/ion/ion_priv.h"
-#include "../../../staging/android/ion/ion_hvenv_driver.h"
#define MSM_AUDIO_ION_PROBED (1 << 0)
@@ -628,7 +627,7 @@ struct ion_client *msm_audio_ion_client_create(const char *name)
{
struct ion_client *pclient = NULL;
- pclient = hvenv_ion_client_create(name);
+ pclient = msm_ion_client_create(name);
return pclient;
}
diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c
index da58f19dd6e6..73396072a052 100644
--- a/drivers/spi/spi_qsd.c
+++ b/drivers/spi/spi_qsd.c
@@ -33,6 +33,7 @@
#include <linux/debugfs.h>
#include <linux/gpio.h>
#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/dma-mapping.h>
#include <linux/sched.h>
@@ -52,6 +53,7 @@ static int msm_spi_pm_suspend_runtime(struct device *device);
static inline void msm_spi_dma_unmap_buffers(struct msm_spi *dd);
static int get_local_resources(struct msm_spi *dd);
static void put_local_resources(struct msm_spi *dd);
+static void msm_spi_slv_setup(struct msm_spi *dd);
static inline int msm_spi_configure_gsbi(struct msm_spi *dd,
struct platform_device *pdev)
@@ -84,7 +86,10 @@ static inline int msm_spi_configure_gsbi(struct msm_spi *dd,
static inline void msm_spi_register_init(struct msm_spi *dd)
{
- writel_relaxed(0x00000001, dd->base + SPI_SW_RESET);
+ if (dd->pdata->is_slv_ctrl)
+ writel_relaxed(0x00000002, dd->base + SPI_SW_RESET);
+ else
+ writel_relaxed(0x00000001, dd->base + SPI_SW_RESET);
msm_spi_set_state(dd, SPI_OP_STATE_RESET);
writel_relaxed(0x00000000, dd->base + SPI_OPERATIONAL);
writel_relaxed(0x00000000, dd->base + SPI_CONFIG);
@@ -932,6 +937,7 @@ static inline void msm_spi_ack_transfer(struct msm_spi *dd)
static inline irqreturn_t msm_spi_qup_irq(int irq, void *dev_id)
{
u32 op, ret = IRQ_NONE;
+ u32 slv;
struct msm_spi *dd = dev_id;
if (pm_runtime_suspended(dd->dev)) {
@@ -945,7 +951,9 @@ static inline irqreturn_t msm_spi_qup_irq(int irq, void *dev_id)
}
op = readl_relaxed(dd->base + SPI_OPERATIONAL);
+ slv = readl_relaxed(dd->base + SPI_SLAVE_IRQ_STATUS);
writel_relaxed(op, dd->base + SPI_OPERATIONAL);
+ writel_relaxed(slv, dd->base + SPI_SLAVE_IRQ_STATUS);
/*
* Ensure service flag was cleared before further
* processing of interrupt.
@@ -1234,7 +1242,10 @@ msm_spi_use_dma(struct msm_spi *dd, struct spi_transfer *tr, u8 bpw)
static void
msm_spi_set_transfer_mode(struct msm_spi *dd, u8 bpw, u32 read_count)
{
- if (msm_spi_use_dma(dd, dd->cur_transfer, bpw)) {
+ if (dd->pdata->is_slv_ctrl) {
+ dd->tx_mode = SPI_BAM_MODE;
+ dd->rx_mode = SPI_BAM_MODE;
+ } else if (msm_spi_use_dma(dd, dd->cur_transfer, bpw)) {
dd->tx_mode = SPI_BAM_MODE;
dd->rx_mode = SPI_BAM_MODE;
} else {
@@ -1353,7 +1364,7 @@ static void get_transfer_length(struct msm_spi *dd)
static int msm_spi_process_transfer(struct msm_spi *dd)
{
u8 bpw;
- u32 max_speed;
+ u32 max_speed = 0;
u32 read_count;
u32 timeout;
u32 spi_ioc;
@@ -1392,7 +1403,7 @@ static int msm_spi_process_transfer(struct msm_spi *dd)
DIV_ROUND_UP(max_speed, MSEC_PER_SEC)));
read_count = DIV_ROUND_UP(dd->cur_msg_len, dd->bytes_per_word);
- if (dd->spi->mode & SPI_LOOP)
+ if (dd->spi->mode & SPI_LOOP && !dd->pdata->is_slv_ctrl)
int_loopback = 1;
if (msm_spi_set_state(dd, SPI_OP_STATE_RESET))
@@ -1414,8 +1425,11 @@ static int msm_spi_process_transfer(struct msm_spi *dd)
msm_spi_set_qup_io_modes(dd);
msm_spi_set_spi_config(dd, bpw);
msm_spi_set_qup_config(dd, bpw);
- spi_ioc = msm_spi_set_spi_io_control(dd);
+ if (!dd->pdata->is_slv_ctrl)
+ spi_ioc = msm_spi_set_spi_io_control(dd);
msm_spi_set_qup_op_mask(dd);
+ if (dd->pdata->is_slv_ctrl)
+ msm_spi_slv_setup(dd);
/* The output fifo interrupt handler will handle all writes after
the first. Restricting this to one write avoids contention
@@ -1482,12 +1496,20 @@ transfer_end:
dd->rx_mode = SPI_MODE_NONE;
msm_spi_set_state(dd, SPI_OP_STATE_RESET);
- if (!dd->cur_transfer->cs_change)
+ if (!dd->cur_transfer->cs_change && !dd->pdata->is_slv_ctrl)
writel_relaxed(spi_ioc & ~SPI_IO_C_MX_CS_MODE,
dd->base + SPI_IO_CONTROL);
return status;
}
+static int msm_spi_slv_abort(struct spi_master *spi)
+{
+ struct msm_spi *dd = spi_master_get_devdata(spi);
+
+ complete_all(&dd->tx_transfer_complete);
+ complete_all(&dd->rx_transfer_complete);
+ return 0;
+}
static inline void msm_spi_set_cs(struct spi_device *spi, bool set_flag)
{
@@ -1753,6 +1775,32 @@ static int msm_spi_unprepare_transfer_hardware(struct spi_master *master)
return 0;
}
+static void msm_spi_slv_setup(struct msm_spi *dd)
+{
+ u32 spi_config = readl_relaxed(dd->base + SPI_CONFIG);
+ u32 qup_config = readl_relaxed(dd->base + QUP_CONFIG);
+ u32 irq_en = GENMASK(6, 0);
+
+ qup_config &= ~QUP_CFG_MODE;
+ qup_config |= QUP_CONFIG_SPI_SLAVE;
+ qup_config |= (SPI_EN_EXT_OUT_FLAG | APP_CLK_ON_EN | CORE_CLK_ON_EN
+ | FIFO_CLK_ON_EN | CORE_EX_CLK_ON_EN);
+ spi_config |= SPI_CFG_SLAVE_OP;
+ writel_relaxed(qup_config, dd->base + QUP_CONFIG);
+ writel_relaxed(spi_config, dd->base + SPI_CONFIG);
+ writel_relaxed(irq_en, (dd->base + SPI_SLAVE_IRQ_EN));
+ if (dd->read_buf && !dd->write_buf) {
+ u32 slv_cfg =
+ readl_relaxed(dd->base + SPI_SLAVE_CONFIG);
+ slv_cfg |= (RX_UNBALANCED_MASK | SPI_S_CGC_EN);
+ writel_relaxed(slv_cfg, (dd->base + SPI_SLAVE_CONFIG));
+ }
+ /*
+ * Ensure Slave setup completes before returning.
+ */
+ mb();
+}
+
static int msm_spi_setup(struct spi_device *spi)
{
struct msm_spi *dd;
@@ -2248,6 +2296,8 @@ struct msm_spi_platform_data *msm_spi_dt_to_pdata(
&pdata->rt_priority, DT_OPT, DT_BOOL, 0},
{"qcom,shared",
&pdata->is_shared, DT_OPT, DT_BOOL, 0},
+ {"qcom,slv-ctrl",
+ &pdata->is_slv_ctrl, DT_OPT, DT_BOOL, 0},
{NULL, NULL, 0, 0, 0},
};
@@ -2451,6 +2501,12 @@ err_clk_get:
return rc;
}
+static const struct of_device_id msm_spi_dt_match[] = {
+ { .compatible = "qcom,spi-qup-v2", },
+ { .compatible = "qcom,qup-v26", },
+ {}
+};
+
static int msm_spi_probe(struct platform_device *pdev)
{
struct spi_master *master;
@@ -2481,6 +2537,9 @@ static int msm_spi_probe(struct platform_device *pdev)
dd = spi_master_get_devdata(master);
if (pdev->dev.of_node) {
+ const struct of_device_id *dev_id;
+ enum msm_spi_qup_version ver;
+
dd->qup_ver = SPI_QUP_VERSION_BFAM;
master->dev.of_node = pdev->dev.of_node;
pdata = msm_spi_dt_to_pdata(pdev, dd);
@@ -2495,6 +2554,17 @@ static int msm_spi_probe(struct platform_device *pdev)
"using default bus_num %d\n", pdev->id);
else
master->bus_num = pdev->id = rc;
+
+ dev_id = of_match_device(msm_spi_dt_match, &pdev->dev);
+ if (dev_id)
+ ver = SPI_QUP_VERSION_SPI_SLV;
+ else
+ ver = SPI_QUP_VERSION_BFAM;
+
+ if (ver >= SPI_QUP_VERSION_SPI_SLV)
+ dd->slv_support = true;
+ else
+ dd->slv_support = false;
} else {
pdata = pdev->dev.platform_data;
dd->qup_ver = SPI_QUP_VERSION_NONE;
@@ -2553,6 +2623,21 @@ static int msm_spi_probe(struct platform_device *pdev)
}
spi_dma_mask(&pdev->dev);
+
+ if (pdata && pdata->is_slv_ctrl) {
+ if (!dd->slv_support) {
+ rc = -ENXIO;
+ dev_err(&pdev->dev, "QUP ver %d, no slv support\n",
+ dd->qup_ver);
+ goto err_probe_res;
+ }
+
+ master->slave = true;
+ master->set_cs = NULL;
+ master->setup = NULL;
+ master->slave_abort = msm_spi_slv_abort;
+ }
+
skip_dma_resources:
spin_lock_init(&dd->queue_lock);
@@ -2753,13 +2838,6 @@ static int msm_spi_remove(struct platform_device *pdev)
return 0;
}
-static struct of_device_id msm_spi_dt_match[] = {
- {
- .compatible = "qcom,spi-qup-v2",
- },
- {}
-};
-
static const struct dev_pm_ops msm_spi_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(msm_spi_suspend, msm_spi_resume)
SET_RUNTIME_PM_OPS(msm_spi_pm_suspend_runtime,
diff --git a/drivers/spi/spi_qsd.h b/drivers/spi/spi_qsd.h
index 47d69965f18a..6632fe806e41 100644
--- a/drivers/spi/spi_qsd.h
+++ b/drivers/spi/spi_qsd.h
@@ -38,6 +38,7 @@
#define QUP_MX_WRITE_CNT_CURRENT 0x0154
#define QUP_CONFIG_SPI_MODE 0x0100
+#define QUP_CONFIG_SPI_SLAVE 0x0400
#endif
#define GSBI_CTRL_REG 0x0
@@ -72,17 +73,26 @@
#define SPI_OUTPUT_FIFO QSD_REG(0x0100) QUP_REG(0x0110)
#define SPI_INPUT_FIFO QSD_REG(0x0200) QUP_REG(0x0218)
#define SPI_STATE QSD_REG(SPI_OPERATIONAL) QUP_REG(0x0004)
+#define SPI_SLAVE_IRQ_STATUS (0x0330)
+#define SPI_SLAVE_IRQ_EN (0x0334)
+#define SPI_SLAVE_CONFIG (0x0338)
/* QUP_CONFIG fields */
#define SPI_CFG_N 0x0000001F
#define SPI_NO_INPUT 0x00000080
#define SPI_NO_OUTPUT 0x00000040
#define SPI_EN_EXT_OUT_FLAG 0x00010000
+#define QUP_CFG_MODE 0x00000F00
+#define APP_CLK_ON_EN BIT(12)
+#define CORE_CLK_ON_EN BIT(13)
+#define FIFO_CLK_ON_EN BIT(14)
+#define CORE_EX_CLK_ON_EN BIT(15)
/* SPI_CONFIG fields */
#define SPI_CFG_LOOPBACK 0x00000100
#define SPI_CFG_INPUT_FIRST 0x00000200
#define SPI_CFG_HS_MODE 0x00000400
+#define SPI_CFG_SLAVE_OP 0x00000020
/* SPI_IO_CONTROL fields */
#define SPI_IO_C_FORCE_CS 0x00000800
@@ -128,6 +138,23 @@
#define SPI_OP_STATE_CLEAR_BITS 0x2
+/* SPI SLAVE IRQ_STATUS/EN fields */
+#define CS_N_ASSERT BIT(0)
+#define CS_N_DEASSERT BIT(1)
+#define CS_N_ETXT BIT(2)
+#define TX_UNDERFLOW BIT(3)
+#define RX_OVERFLOW_WAIT_EOT BIT(4)
+#define RX_OVERFLOW_NO_EOT BIT(5)
+#define CS_N_ERXT BIT(6)
+
+/* SPI_SLAVE_CONFIG Fields */
+#define RX_N_SHIFT BIT(0)
+#define PAUSE_ON_ERR_DIS BIT(1)
+#define SPI_S_CGC_EN BIT(2)
+#define RX_UNBALANCED_MASK BIT(3)
+#define SLAVE_DIS_RESET_ST BIT(4)
+#define SLAVE_AUTO_PAUSE_EOT BIT(7)
+
#define SPI_PINCTRL_STATE_DEFAULT "spi_default"
#define SPI_PINCTRL_STATE_SLEEP "spi_sleep"
@@ -177,6 +204,7 @@ enum msm_spi_state {
enum msm_spi_qup_version {
SPI_QUP_VERSION_NONE = 0x0,
SPI_QUP_VERSION_BFAM = 0x2,
+ SPI_QUP_VERSION_SPI_SLV = 0x26,
};
enum msm_spi_pipe_direction {
@@ -376,6 +404,7 @@ struct msm_spi {
struct pinctrl_state *pins_sleep;
bool is_init_complete;
bool pack_words;
+ bool slv_support;
};
/* Forward declaration */
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index c08a524f3dab..5644051b4010 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -4294,6 +4294,8 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
enum usb_device_speed oldspeed = udev->speed;
const char *speed;
int devnum = udev->devnum;
+ char *error_event[] = {
+ "USB_DEVICE_ERROR=Device_No_Response", NULL };
/* root hub ports have a slightly longer reset period
* (from USB 2.0 spec, section 7.1.7.5)
@@ -4467,6 +4469,8 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
if (r != -ENODEV)
dev_err(&udev->dev, "device descriptor read/64, error %d\n",
r);
+ kobject_uevent_env(&udev->parent->dev.kobj,
+ KOBJ_CHANGE, error_event);
retval = -EMSGSIZE;
continue;
}
@@ -4519,6 +4523,8 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
dev_err(&udev->dev,
"device descriptor read/8, error %d\n",
retval);
+ kobject_uevent_env(&udev->parent->dev.kobj,
+ KOBJ_CHANGE, error_event);
if (retval >= 0)
retval = -EMSGSIZE;
} else {
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index c244d908fa4f..24ecbc469eb6 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -282,7 +282,7 @@ out:
return ret;
}
-static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
+void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
{
struct dwc3_ep *dep;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 94709587f238..f108aecbfe52 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2882,6 +2882,15 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
dwc->test_mode = false;
+ /*
+ * From SNPS databook section 8.1.2
+ * the EP0 should be in setup phase. So ensure
+ * that EP0 is in setup phase by issuing a stall
+ * and restart if EP0 is not in setup phase.
+ */
+ if (dwc->ep0state != EP0_SETUP_PHASE)
+ dwc3_ep0_stall_and_restart(dwc);
+
dwc3_stop_active_transfers(dwc);
dwc3_clear_stall_all_ep(dwc);
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
index baa83cf9638b..5b3ffbe3056d 100644
--- a/drivers/usb/dwc3/gadget.h
+++ b/drivers/usb/dwc3/gadget.h
@@ -98,6 +98,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
void dwc3_ep0_interrupt(struct dwc3 *dwc,
const struct dwc3_event_depevt *event);
void dwc3_ep0_out_start(struct dwc3 *dwc);
+void dwc3_ep0_stall_and_restart(struct dwc3 *dwc);
int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value);
int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value);
int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c
index 18e3c5cdcc24..67f7e75a9219 100644
--- a/drivers/usb/gadget/function/f_gsi.c
+++ b/drivers/usb/gadget/function/f_gsi.c
@@ -554,6 +554,9 @@ static int ipa_suspend_work_handler(struct gsi_data_port *d_port)
if (!usb_gsi_ep_op(gsi->d_port.in_ep, (void *) &f_suspend,
GSI_EP_OP_CHECK_FOR_SUSPEND)) {
ret = -EFAULT;
+ block_db = false;
+ usb_gsi_ep_op(d_port->in_ep, (void *)&block_db,
+ GSI_EP_OP_SET_CLR_BLOCK_DBL);
goto done;
}
diff --git a/drivers/video/fbdev/msm/mdss_dp_util.c b/drivers/video/fbdev/msm/mdss_dp_util.c
index 037741df4382..5cb141b1d5e7 100644
--- a/drivers/video/fbdev/msm/mdss_dp_util.c
+++ b/drivers/video/fbdev/msm/mdss_dp_util.c
@@ -1233,6 +1233,7 @@ static void mdss_dp_audio_setup_audio_stream_sdp(struct dss_io_data *ctrl_io,
/* Config header and parity byte 1 */
value = readl_relaxed(ctrl_io->base + MMSS_DP_AUDIO_STREAM_0);
+ value &= 0x0000ffff;
new_value = 0x02;
parity_byte = mdss_dp_calculate_parity_byte(new_value);
value |= ((new_value << HEADER_BYTE_1_BIT)
@@ -1243,7 +1244,8 @@ static void mdss_dp_audio_setup_audio_stream_sdp(struct dss_io_data *ctrl_io,
/* Config header and parity byte 2 */
value = readl_relaxed(ctrl_io->base + MMSS_DP_AUDIO_STREAM_1);
- new_value = value;
+ value &= 0xffff0000;
+ new_value = 0x00;
parity_byte = mdss_dp_calculate_parity_byte(new_value);
value |= ((new_value << HEADER_BYTE_2_BIT)
| (parity_byte << PARITY_BYTE_2_BIT));
@@ -1253,6 +1255,7 @@ static void mdss_dp_audio_setup_audio_stream_sdp(struct dss_io_data *ctrl_io,
/* Config header and parity byte 3 */
value = readl_relaxed(ctrl_io->base + MMSS_DP_AUDIO_STREAM_1);
+ value &= 0x0000ffff;
new_value = num_of_channels - 1;
parity_byte = mdss_dp_calculate_parity_byte(new_value);
value |= ((new_value << HEADER_BYTE_3_BIT)
@@ -1271,6 +1274,7 @@ static void mdss_dp_audio_setup_audio_timestamp_sdp(struct dss_io_data *ctrl_io)
/* Config header and parity byte 1 */
value = readl_relaxed(ctrl_io->base + MMSS_DP_AUDIO_TIMESTAMP_0);
+ value &= 0x0000ffff;
new_value = 0x1;
parity_byte = mdss_dp_calculate_parity_byte(new_value);
value |= ((new_value << HEADER_BYTE_1_BIT)
@@ -1281,6 +1285,7 @@ static void mdss_dp_audio_setup_audio_timestamp_sdp(struct dss_io_data *ctrl_io)
/* Config header and parity byte 2 */
value = readl_relaxed(ctrl_io->base + MMSS_DP_AUDIO_TIMESTAMP_1);
+ value &= 0xffff0000;
new_value = 0x17;
parity_byte = mdss_dp_calculate_parity_byte(new_value);
value |= ((new_value << HEADER_BYTE_2_BIT)
@@ -1291,6 +1296,7 @@ static void mdss_dp_audio_setup_audio_timestamp_sdp(struct dss_io_data *ctrl_io)
/* Config header and parity byte 3 */
value = readl_relaxed(ctrl_io->base + MMSS_DP_AUDIO_TIMESTAMP_1);
+ value &= 0x0000ffff;
new_value = (0x0 | (0x11 << 2));
parity_byte = mdss_dp_calculate_parity_byte(new_value);
value |= ((new_value << HEADER_BYTE_3_BIT)
@@ -1308,6 +1314,7 @@ static void mdss_dp_audio_setup_audio_infoframe_sdp(struct dss_io_data *ctrl_io)
/* Config header and parity byte 1 */
value = readl_relaxed(ctrl_io->base + MMSS_DP_AUDIO_INFOFRAME_0);
+ value &= 0x0000ffff;
new_value = 0x84;
parity_byte = mdss_dp_calculate_parity_byte(new_value);
value |= ((new_value << HEADER_BYTE_1_BIT)
@@ -1318,6 +1325,7 @@ static void mdss_dp_audio_setup_audio_infoframe_sdp(struct dss_io_data *ctrl_io)
/* Config header and parity byte 2 */
value = readl_relaxed(ctrl_io->base + MMSS_DP_AUDIO_INFOFRAME_1);
+ value &= 0xffff0000;
new_value = 0x1b;
parity_byte = mdss_dp_calculate_parity_byte(new_value);
value |= ((new_value << HEADER_BYTE_2_BIT)
@@ -1328,6 +1336,7 @@ static void mdss_dp_audio_setup_audio_infoframe_sdp(struct dss_io_data *ctrl_io)
/* Config header and parity byte 3 */
value = readl_relaxed(ctrl_io->base + MMSS_DP_AUDIO_INFOFRAME_1);
+ value &= 0x0000ffff;
new_value = (0x0 | (0x11 << 2));
parity_byte = mdss_dp_calculate_parity_byte(new_value);
value |= ((new_value << HEADER_BYTE_3_BIT)
@@ -1349,6 +1358,7 @@ static void mdss_dp_audio_setup_copy_management_sdp(struct dss_io_data *ctrl_io)
/* Config header and parity byte 1 */
value = readl_relaxed(ctrl_io->base +
MMSS_DP_AUDIO_COPYMANAGEMENT_0);
+ value &= 0x0000ffff;
new_value = 0x05;
parity_byte = mdss_dp_calculate_parity_byte(new_value);
value |= ((new_value << HEADER_BYTE_1_BIT)
@@ -1361,6 +1371,7 @@ static void mdss_dp_audio_setup_copy_management_sdp(struct dss_io_data *ctrl_io)
/* Config header and parity byte 2 */
value = readl_relaxed(ctrl_io->base +
MMSS_DP_AUDIO_COPYMANAGEMENT_1);
+ value &= 0xffff0000;
new_value = 0x0F;
parity_byte = mdss_dp_calculate_parity_byte(new_value);
value |= ((new_value << HEADER_BYTE_2_BIT)
@@ -1373,6 +1384,7 @@ static void mdss_dp_audio_setup_copy_management_sdp(struct dss_io_data *ctrl_io)
/* Config header and parity byte 3 */
value = readl_relaxed(ctrl_io->base +
MMSS_DP_AUDIO_COPYMANAGEMENT_1);
+ value &= 0x0000ffff;
new_value = 0x0;
parity_byte = mdss_dp_calculate_parity_byte(new_value);
value |= ((new_value << HEADER_BYTE_3_BIT)
@@ -1398,6 +1410,7 @@ static void mdss_dp_audio_setup_isrc_sdp(struct dss_io_data *ctrl_io)
/* Config header and parity byte 1 */
value = readl_relaxed(ctrl_io->base + MMSS_DP_AUDIO_ISRC_0);
+ value &= 0x0000ffff;
new_value = 0x06;
parity_byte = mdss_dp_calculate_parity_byte(new_value);
value |= ((new_value << HEADER_BYTE_1_BIT)
@@ -1408,6 +1421,7 @@ static void mdss_dp_audio_setup_isrc_sdp(struct dss_io_data *ctrl_io)
/* Config header and parity byte 2 */
value = readl_relaxed(ctrl_io->base + MMSS_DP_AUDIO_ISRC_1);
+ value &= 0xffff0000;
new_value = 0x0F;
parity_byte = mdss_dp_calculate_parity_byte(new_value);
value |= ((new_value << HEADER_BYTE_2_BIT)
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_panel.c b/drivers/video/fbdev/msm/mdss_hdmi_panel.c
index a8a56e3a8745..af72973a3988 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_panel.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_panel.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-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
@@ -632,6 +632,19 @@ static int hdmi_panel_setup_dc(struct hdmi_panel *panel)
vbi_pkt_reg = DSS_REG_R(panel->io, HDMI_VBI_PKT_CTRL);
vbi_pkt_reg |= BIT(5) | BIT(4);
DSS_REG_W(panel->io, HDMI_VBI_PKT_CTRL, vbi_pkt_reg);
+ } else {
+ hdmi_ctrl_reg = DSS_REG_R(panel->io, HDMI_CTRL);
+
+ /* disable GC CD override */
+ hdmi_ctrl_reg &= ~BIT(27);
+ /* disable deep color for RGB888/YUV444/YUV420 30 bits */
+ hdmi_ctrl_reg &= ~BIT(24);
+ DSS_REG_W(panel->io, HDMI_CTRL, hdmi_ctrl_reg);
+
+ /* disable the GC packet sending */
+ vbi_pkt_reg = DSS_REG_R(panel->io, HDMI_VBI_PKT_CTRL);
+ vbi_pkt_reg &= ~(BIT(5) | BIT(4));
+ DSS_REG_W(panel->io, HDMI_VBI_PKT_CTRL, vbi_pkt_reg);
}
return rc;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_util.c b/drivers/video/fbdev/msm/mdss_mdp_util.c
index 1ae3d0ba4ec6..6015ed20fe56 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_util.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_util.c
@@ -524,11 +524,12 @@ int mdss_mdp_get_plane_sizes(struct mdss_mdp_format_params *fmt, u32 w, u32 h,
if (ps == NULL)
return -EINVAL;
+ memset(ps, 0, sizeof(struct mdss_mdp_plane_sizes));
+
if ((w > MAX_IMG_WIDTH) || (h > MAX_IMG_HEIGHT))
return -ERANGE;
bpp = fmt->bpp;
- memset(ps, 0, sizeof(struct mdss_mdp_plane_sizes));
if (mdss_mdp_is_ubwc_format(fmt)) {
rc = mdss_mdp_get_ubwc_plane_size(fmt, w, h, ps);
diff --git a/drivers/video/msm/ba/msm_ba.c b/drivers/video/msm/ba/msm_ba.c
index 8d1459088b80..4200b8f20073 100644
--- a/drivers/video/msm/ba/msm_ba.c
+++ b/drivers/video/msm/ba/msm_ba.c
@@ -812,6 +812,11 @@ void *msm_ba_open(const struct msm_ba_ext_ops *ext_ops)
dev_ctxt = get_ba_dev();
+ if (!dev_ctxt) {
+ dprintk(BA_ERR, "Failed to get ba dev");
+ return NULL;
+ }
+
inst = kzalloc(sizeof(*inst), GFP_KERNEL);
if (!inst) {
diff --git a/include/linux/spi/qcom-spi.h b/include/linux/spi/qcom-spi.h
index 598481079383..67ef31c69641 100644
--- a/include/linux/spi/qcom-spi.h
+++ b/include/linux/spi/qcom-spi.h
@@ -48,9 +48,11 @@ struct msm_spi_platform_data {
u32 infinite_mode;
bool ver_reg_exists;
bool use_bam;
+ bool slv_test;
u32 bam_consumer_pipe_index;
u32 bam_producer_pipe_index;
bool rt_priority;
bool use_pinctrl;
bool is_shared;
+ bool is_slv_ctrl;
};
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 3dd0091f4af3..75050fac06fb 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4904,12 +4904,17 @@ enum nl80211_smps_mode {
* change to the channel status.
* @NL80211_RADAR_NOP_FINISHED: The Non-Occupancy Period for this channel is
* over, channel becomes usable.
+ * @NL80211_RADAR_PRE_CAC_EXPIRED: Channel Availability Check done on this
+ * non-operating channel is expired and no longer valid. New CAC must
+ * be done on this channel before starting the operation. This is not
+ * applicable for ETSI dfs domain where pre-CAC is valid for ever.
*/
enum nl80211_radar_event {
NL80211_RADAR_DETECTED,
NL80211_RADAR_CAC_FINISHED,
NL80211_RADAR_CAC_ABORTED,
NL80211_RADAR_NOP_FINISHED,
+ NL80211_RADAR_PRE_CAC_EXPIRED,
};
/**
diff --git a/include/uapi/media/ais/msm_ais_isp.h b/include/uapi/media/ais/msm_ais_isp.h
index 7c9daafc404d..f323d3bf7baf 100644
--- a/include/uapi/media/ais/msm_ais_isp.h
+++ b/include/uapi/media/ais/msm_ais_isp.h
@@ -23,6 +23,8 @@
#define ISP_STATS_STREAM_BIT 0x80000000
+#define INTERLACE_SUPPORT_OLD_REMOVED
+
struct msm_vfe_cfg_cmd_list;
enum ISP_START_PIXEL_PATTERN {
@@ -733,6 +735,7 @@ struct msm_isp_buf_event {
uint32_t handle;
uint32_t output_format;
int8_t buf_idx;
+ uint8_t field_type;
};
struct msm_isp_fetch_eng_event {
uint32_t session_id;
diff --git a/net/wireless/ap.c b/net/wireless/ap.c
index 91d02ac0f42f..547d38356583 100644
--- a/net/wireless/ap.c
+++ b/net/wireless/ap.c
@@ -32,6 +32,11 @@ int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
rdev_set_qos_map(rdev, dev, NULL);
if (notify)
nl80211_send_ap_stopped(wdev);
+
+ /* Should we apply the grace period during beaconing interface
+ * shutdown also?
+ */
+ cfg80211_sched_dfs_chan_update(rdev);
}
return err;
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index d5ccaeaa76e0..6b5467ea99db 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -456,6 +456,105 @@ bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
return (r1 + r2 > 0);
}
+/*
+ * Checks if center frequency of chan falls with in the bandwidth
+ * range of chandef.
+ */
+bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef,
+ struct ieee80211_channel *chan)
+{
+ int width;
+ u32 cf_offset, freq;
+
+ if (chandef->chan->center_freq == chan->center_freq)
+ return true;
+
+ width = cfg80211_chandef_get_width(chandef);
+ if (width <= 20)
+ return false;
+
+ cf_offset = width / 2 - 10;
+
+ for (freq = chandef->center_freq1 - width / 2 + 10;
+ freq <= chandef->center_freq1 + width / 2 - 10; freq += 20) {
+ if (chan->center_freq == freq)
+ return true;
+ }
+
+ if (!chandef->center_freq2)
+ return false;
+
+ for (freq = chandef->center_freq2 - width / 2 + 10;
+ freq <= chandef->center_freq2 + width / 2 - 10; freq += 20) {
+ if (chan->center_freq == freq)
+ return true;
+ }
+
+ return false;
+}
+
+bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev)
+{
+ bool active = false;
+
+ ASSERT_WDEV_LOCK(wdev);
+
+ if (!wdev->chandef.chan)
+ return false;
+
+ switch (wdev->iftype) {
+ case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_P2P_GO:
+ active = wdev->beacon_interval != 0;
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ active = wdev->ssid_len != 0;
+ break;
+ case NL80211_IFTYPE_MESH_POINT:
+ active = wdev->mesh_id_len != 0;
+ break;
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_OCB:
+ case NL80211_IFTYPE_P2P_CLIENT:
+ case NL80211_IFTYPE_MONITOR:
+ case NL80211_IFTYPE_AP_VLAN:
+ case NL80211_IFTYPE_WDS:
+ case NL80211_IFTYPE_P2P_DEVICE:
+ break;
+ case NL80211_IFTYPE_UNSPECIFIED:
+ case NUM_NL80211_IFTYPES:
+ WARN_ON(1);
+ }
+
+ return active;
+}
+
+bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
+ struct ieee80211_channel *chan)
+{
+ struct wireless_dev *wdev;
+
+ ASSERT_RTNL();
+
+ if (!(chan->flags & IEEE80211_CHAN_RADAR))
+ return false;
+
+ list_for_each_entry(wdev, &wiphy->wdev_list, list) {
+ wdev_lock(wdev);
+ if (!cfg80211_beaconing_iface_active(wdev)) {
+ wdev_unlock(wdev);
+ continue;
+ }
+
+ if (cfg80211_is_sub_chan(&wdev->chandef, chan)) {
+ wdev_unlock(wdev);
+ return true;
+ }
+ wdev_unlock(wdev);
+ }
+
+ return false;
+}
static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
u32 center_freq,
diff --git a/net/wireless/core.h b/net/wireless/core.h
index be5ab8c13a39..55c64d08db31 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -438,6 +438,16 @@ unsigned int
cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
const struct cfg80211_chan_def *chandef);
+void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev);
+
+bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
+ struct ieee80211_channel *chan);
+
+bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev);
+
+bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef,
+ struct ieee80211_channel *chan);
+
static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
{
unsigned long end = jiffies;
diff --git a/net/wireless/db.txt b/net/wireless/db.txt
index 86005410a22f..499d98745d44 100644
--- a/net/wireless/db.txt
+++ b/net/wireless/db.txt
@@ -1478,9 +1478,9 @@ country VI: DFS-FCC
country VN: DFS-FCC
(2402 - 2482 @ 40), (20)
- (5170 - 5250 @ 80), (24), AUTO-BW
- (5250 - 5330 @ 80), (24), DFS, AUTO-BW
- (5490 - 5730 @ 160), (24), DFS
+ (5170 - 5250 @ 80), (24)
+ (5250 - 5330 @ 80), (24), DFS
+ (5490 - 5730 @ 80), (24), DFS
(5735 - 5835 @ 80), (30)
# 60 gHz band channels 1-4
(57240 - 65880 @ 2160), (40)
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 4c55fab9b4e4..7da0cd9c5e73 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -186,6 +186,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
if (!nowext)
wdev->wext.ibss.ssid_len = 0;
#endif
+ cfg80211_sched_dfs_chan_update(rdev);
}
void cfg80211_clear_ibss(struct net_device *dev, bool nowext)
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 092300b30c37..dda90a39be40 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -260,6 +260,7 @@ int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
wdev->mesh_id_len = 0;
memset(&wdev->chandef, 0, sizeof(wdev->chandef));
rdev_set_qos_map(rdev, dev, NULL);
+ cfg80211_sched_dfs_chan_update(rdev);
}
return err;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 2bc6eaa766c7..465e0d31229d 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -743,6 +743,12 @@ bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
}
EXPORT_SYMBOL(cfg80211_rx_mgmt);
+void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev)
+{
+ cancel_delayed_work(&rdev->dfs_update_channels_wk);
+ queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk, 0);
+}
+
void cfg80211_dfs_channels_update_work(struct work_struct *work)
{
struct delayed_work *delayed_work;
@@ -753,6 +759,8 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
struct wiphy *wiphy;
bool check_again = false;
unsigned long timeout, next_time = 0;
+ unsigned long time_dfs_update;
+ enum nl80211_radar_event radar_event;
int bandid, i;
delayed_work = container_of(work, struct delayed_work, work);
@@ -769,11 +777,27 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
for (i = 0; i < sband->n_channels; i++) {
c = &sband->channels[i];
- if (c->dfs_state != NL80211_DFS_UNAVAILABLE)
+ if (!(c->flags & IEEE80211_CHAN_RADAR))
+ continue;
+
+ if (c->dfs_state != NL80211_DFS_UNAVAILABLE &&
+ c->dfs_state != NL80211_DFS_AVAILABLE)
continue;
- timeout = c->dfs_state_entered + msecs_to_jiffies(
- IEEE80211_DFS_MIN_NOP_TIME_MS);
+ if (c->dfs_state == NL80211_DFS_UNAVAILABLE) {
+ time_dfs_update = IEEE80211_DFS_MIN_NOP_TIME_MS;
+ radar_event = NL80211_RADAR_NOP_FINISHED;
+ } else {
+ if (regulatory_pre_cac_allowed(wiphy) ||
+ cfg80211_any_wiphy_oper_chan(wiphy, c))
+ continue;
+
+ time_dfs_update = REG_PRE_CAC_EXPIRY_GRACE_MS;
+ radar_event = NL80211_RADAR_PRE_CAC_EXPIRED;
+ }
+
+ timeout = c->dfs_state_entered +
+ msecs_to_jiffies(time_dfs_update);
if (time_after_eq(jiffies, timeout)) {
c->dfs_state = NL80211_DFS_USABLE;
@@ -783,8 +807,8 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
NL80211_CHAN_NO_HT);
nl80211_radar_notify(rdev, &chandef,
- NL80211_RADAR_NOP_FINISHED,
- NULL, GFP_ATOMIC);
+ radar_event, NULL,
+ GFP_ATOMIC);
continue;
}
@@ -809,7 +833,6 @@ void cfg80211_radar_event(struct wiphy *wiphy,
gfp_t gfp)
{
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
- unsigned long timeout;
trace_cfg80211_radar_event(wiphy, chandef);
@@ -819,9 +842,7 @@ void cfg80211_radar_event(struct wiphy *wiphy,
*/
cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE);
- timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_NOP_TIME_MS);
- queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk,
- timeout);
+ cfg80211_sched_dfs_chan_update(rdev);
nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp);
}
@@ -850,6 +871,7 @@ void cfg80211_cac_event(struct net_device *netdev,
msecs_to_jiffies(wdev->cac_time_ms);
WARN_ON(!time_after_eq(jiffies, timeout));
cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
+ cfg80211_sched_dfs_chan_update(rdev);
break;
case NL80211_RADAR_CAC_ABORTED:
break;
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 050d7948dd68..26ac0a4808a0 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -3247,6 +3247,34 @@ bool regulatory_indoor_allowed(void)
return reg_is_indoor;
}
+bool regulatory_pre_cac_allowed(struct wiphy *wiphy)
+{
+ const struct ieee80211_regdomain *regd = NULL;
+ const struct ieee80211_regdomain *wiphy_regd = NULL;
+ bool pre_cac_allowed = false;
+
+ rcu_read_lock();
+
+ regd = rcu_dereference(cfg80211_regdomain);
+ wiphy_regd = rcu_dereference(wiphy->regd);
+ if (!wiphy_regd) {
+ if (regd->dfs_region == NL80211_DFS_ETSI)
+ pre_cac_allowed = true;
+
+ rcu_read_unlock();
+
+ return pre_cac_allowed;
+ }
+
+ if (regd->dfs_region == wiphy_regd->dfs_region &&
+ wiphy_regd->dfs_region == NL80211_DFS_ETSI)
+ pre_cac_allowed = true;
+
+ rcu_read_unlock();
+
+ return pre_cac_allowed;
+}
+
int __init regulatory_init(void)
{
int err = 0;
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index 9f495d76eca0..7bbe2d138d2a 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -143,4 +143,18 @@ int cfg80211_get_unii(int freq);
*/
bool regulatory_indoor_allowed(void);
+/*
+ * Grace period to timeout pre-CAC results on the dfs channels. This timeout
+ * value is used for Non-ETSI domain.
+ * TODO: May be make this timeout available through regdb?
+ */
+#define REG_PRE_CAC_EXPIRY_GRACE_MS 2000
+
+/**
+ * regulatory_pre_cac_allowed - if pre-CAC allowed in the current dfs domain
+ * @wiphy: wiphy for which pre-CAC capability is checked.
+
+ * Pre-CAC is allowed only in ETSI domain.
+ */
+bool regulatory_pre_cac_allowed(struct wiphy *wiphy);
#endif /* __NET_WIRELESS_REG_H */
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 460c4b0e343c..e0eb2a4cfd8e 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -97,7 +97,7 @@ static int wiphy_suspend(struct device *dev)
rtnl_lock();
if (rdev->wiphy.registered)
if (rdev->ops->suspend)
- ret = rdev_suspend(rdev, NULL);
+ ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config);
rtnl_unlock();
return ret;
diff --git a/security/pfe/pfk_ice.c b/security/pfe/pfk_ice.c
index facecedc3827..2bf18b74bfd5 100644
--- a/security/pfe/pfk_ice.c
+++ b/security/pfe/pfk_ice.c
@@ -68,25 +68,34 @@ int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt,
char *storage_type)
{
struct scm_desc desc = {0};
- int ret;
+ int ret, ret1;
char *tzbuf_key = (char *)ice_key;
char *tzbuf_salt = (char *)ice_salt;
+ char *s_type = storage_type;
uint32_t smc_id = 0;
u32 tzbuflen_key = sizeof(ice_key);
u32 tzbuflen_salt = sizeof(ice_salt);
- if (index < MIN_ICE_KEY_INDEX || index > MAX_ICE_KEY_INDEX)
+ if (index < MIN_ICE_KEY_INDEX || index > MAX_ICE_KEY_INDEX) {
+ pr_err("%s Invalid index %d\n", __func__, index);
return -EINVAL;
+ }
- if (!key || !salt)
+ if (!key || !salt) {
+ pr_err("%s Invalid key/salt\n", __func__);
return -EINVAL;
+ }
- if (!tzbuf_key || !tzbuf_salt)
+ if (!tzbuf_key || !tzbuf_salt) {
+ pr_err("%s No Memory\n", __func__);
return -ENOMEM;
+ }
- if (storage_type == NULL)
+ if (s_type == NULL) {
+ pr_err("%s Invalid storage\n", __func__);
return -EINVAL;
+ }
memset(tzbuf_key, 0, tzbuflen_key);
memset(tzbuf_salt, 0, tzbuflen_salt);
@@ -98,7 +107,6 @@ int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt,
dmac_flush_range(tzbuf_salt, tzbuf_salt + tzbuflen_salt);
smc_id = TZ_ES_SET_ICE_KEY_ID;
- pr_debug(" %s , smc_id = 0x%x\n", __func__, smc_id);
desc.arginfo = TZ_ES_SET_ICE_KEY_PARAM_ID;
desc.args[0] = index;
@@ -107,27 +115,36 @@ int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt,
desc.args[3] = virt_to_phys(tzbuf_salt);
desc.args[4] = tzbuflen_salt;
- ret = qcom_ice_setup_ice_hw((const char *)storage_type, true);
+ ret = qcom_ice_setup_ice_hw((const char *)s_type, true);
if (ret) {
- pr_err("%s: could not enable clocks: 0x%x\n", __func__, ret);
- return ret;
+ pr_err("%s: could not enable clocks: %d\n", __func__, ret);
+ goto out;
}
ret = scm_call2(smc_id, &desc);
- ret = qcom_ice_setup_ice_hw((const char *)storage_type, false);
-
pr_debug(" %s , ret = %d\n", __func__, ret);
- if (ret) {
- pr_err("%s: Error: 0x%x\n", __func__, ret);
+ if (ret) {
+ pr_err("%s: Set key Error: %d\n", __func__, ret);
+ if (ret == -EBUSY) {
+ if (qcom_ice_setup_ice_hw((const char *)s_type, false))
+ pr_err("%s: disable clock failed\n", __func__);
+ goto out;
+ }
+ /*Try to invalidate the key to keep ICE in proper state*/
smc_id = TZ_ES_INVALIDATE_ICE_KEY_ID;
desc.arginfo = TZ_ES_INVALIDATE_ICE_KEY_PARAM_ID;
desc.args[0] = index;
- scm_call2(smc_id, &desc);
+ ret1 = scm_call2(smc_id, &desc);
+ if (ret1)
+ pr_err("%s:Invalidate key Error: %d\n", __func__,
+ ret1);
}
+ ret = qcom_ice_setup_ice_hw((const char *)s_type, false);
+out:
return ret;
}
@@ -139,14 +156,17 @@ int qti_pfk_ice_invalidate_key(uint32_t index, char *storage_type)
uint32_t smc_id = 0;
- if (index < MIN_ICE_KEY_INDEX || index > MAX_ICE_KEY_INDEX)
+ if (index < MIN_ICE_KEY_INDEX || index > MAX_ICE_KEY_INDEX) {
+ pr_err("%s Invalid index %d\n", __func__, index);
return -EINVAL;
+ }
- if (storage_type == NULL)
+ if (storage_type == NULL) {
+ pr_err("%s Invalid storage\n", __func__);
return -EINVAL;
+ }
smc_id = TZ_ES_INVALIDATE_ICE_KEY_ID;
- pr_debug(" %s , smc_id = 0x%x\n", __func__, smc_id);
desc.arginfo = TZ_ES_INVALIDATE_ICE_KEY_PARAM_ID;
desc.args[0] = index;
@@ -160,12 +180,13 @@ int qti_pfk_ice_invalidate_key(uint32_t index, char *storage_type)
ret = scm_call2(smc_id, &desc);
- ret = qcom_ice_setup_ice_hw((const char *)storage_type, false);
-
- pr_debug(" %s , ret = %d\n", __func__, ret);
- if (ret)
+ if (ret) {
pr_err("%s: Error: 0x%x\n", __func__, ret);
+ if (qcom_ice_setup_ice_hw((const char *)storage_type, false))
+ pr_err("%s: could not disable clocks\n", __func__);
+ } else {
+ ret = qcom_ice_setup_ice_hw((const char *)storage_type, false);
+ }
return ret;
-
}