summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/msm/msm.txt1
-rw-r--r--Documentation/devicetree/bindings/arm/msm/spss_utils.txt18
-rw-r--r--Documentation/devicetree/bindings/sound/qcom-audio-dev.txt5
-rw-r--r--arch/arm/boot/dts/qcom/Makefile1
-rw-r--r--arch/arm/boot/dts/qcom/msm-audio.dtsi18
-rw-r--r--arch/arm/boot/dts/qcom/msm-pm660l-rpm-regulator.dtsi8
-rw-r--r--arch/arm/boot/dts/qcom/msm-pm660l.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk-evt3.dtsi454
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-camera.dtsi6
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dts3
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts3
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts3
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk.dts3
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-v2.dtsi17
-rw-r--r--arch/arm/boot/dts/qcom/msm8998.dtsi16
-rw-r--r--arch/arm/boot/dts/qcom/sda658.dtsi12
-rw-r--r--arch/arm/boot/dts/qcom/sda660.dtsi12
-rw-r--r--arch/arm/boot/dts/qcom/sdm630-cdp.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/sdm630-mtp.dtsi9
-rw-r--r--arch/arm/boot/dts/qcom/sdm630-pm660a-qrd.dts25
-rw-r--r--arch/arm/boot/dts/qcom/sdm630-qrd.dtsi24
-rw-r--r--arch/arm/boot/dts/qcom/sdm630.dtsi108
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-camera.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-cdp.dts12
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-cdp.dtsi12
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-coresight.dtsi16
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-gpu.dtsi9
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-internal-codec-cdp.dts26
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-internal-codec-mtp.dts26
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-cdp.dts74
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-mtp.dts74
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-rcm.dts74
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-internal-codec-rcm.dts26
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-mtp.dtsi17
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi6
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-rcm.dts12
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-rumi.dts8
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-sim.dts8
-rw-r--r--arch/arm/boot/dts/qcom/sdm660.dtsi67
-rw-r--r--arch/arm64/Kconfig2
-rw-r--r--arch/arm64/kernel/insn.c165
-rw-r--r--drivers/char/adsprpc.c110
-rw-r--r--drivers/char/adsprpc_compat.c49
-rw-r--r--drivers/char/adsprpc_shared.h11
-rw-r--r--drivers/clk/qcom/clk-rcg2.c62
-rw-r--r--drivers/gpu/msm/adreno-gpulist.h4
-rw-r--r--drivers/gpu/msm/adreno_a5xx.c75
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c24
-rw-r--r--drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c6
-rw-r--r--drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c6
-rw-r--r--drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c2
-rw-r--r--drivers/mmc/core/mmc.c52
-rw-r--r--drivers/mmc/core/mmc_ops.c2
-rw-r--r--drivers/mmc/core/mmc_ops.h3
-rw-r--r--drivers/platform/msm/seemp_core/seemp_event_encoder.c21
-rw-r--r--drivers/power/qcom-charger/msm_bcl.c10
-rw-r--r--drivers/power/qcom-charger/qpnp-fg.c18
-rw-r--r--drivers/power/qcom-charger/smb-lib.c2
-rw-r--r--drivers/power/reset/msm-poweroff.c15
-rw-r--r--drivers/scsi/ufs/ufshcd.c43
-rw-r--r--drivers/soc/qcom/glink.c8
-rw-r--r--drivers/soc/qcom/icnss.c4
-rw-r--r--drivers/soc/qcom/secure_buffer.c23
-rw-r--r--drivers/soc/qcom/service-notifier.c6
-rw-r--r--drivers/soc/qcom/spss_utils.c132
-rw-r--r--drivers/soc/qcom/subsys-pil-tz.c4
-rw-r--r--drivers/soc/qcom/subsystem_restart.c7
-rw-r--r--drivers/staging/android/ion/ion.c23
-rw-r--r--drivers/thermal/msm_lmh_dcvs.c38
-rw-r--r--drivers/usb/dwc3/dwc3-msm.c4
-rw-r--r--drivers/usb/phy/phy-msm-qusb.c19
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pipe.c7
-rw-r--r--include/net/mac80211.h26
-rw-r--r--kernel/events/core.c7
-rw-r--r--kernel/sched/core.c4
-rw-r--r--kernel/sched/fair.c23
-rw-r--r--kernel/sched/hmp.c4
-rw-r--r--kernel/sched/sched.h22
-rw-r--r--kernel/workqueue.c7
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/iface.c1
-rw-r--r--net/mac80211/rx.c29
-rw-r--r--net/mac80211/sta_info.c1
-rw-r--r--net/mac80211/tx.c8
-rw-r--r--net/mac80211/util.c14
-rw-r--r--security/keys/proc.c2
-rw-r--r--sound/soc/codecs/wcd-mbhc-v2.c66
-rw-r--r--sound/soc/codecs/wcd-mbhc-v2.h5
-rw-r--r--sound/soc/codecs/wcd9335.c8
-rw-r--r--sound/soc/codecs/wcd934x/wcd934x-mbhc.c6
-rw-r--r--sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c14
-rw-r--r--sound/usb/usb_audio_qmi_svc.c94
93 files changed, 2115 insertions, 410 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt
index 4fadd0ccbcf7..02bf809740c3 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm.txt
@@ -289,6 +289,7 @@ compatible = "qcom,sdm630-mtp"
compatible = "qcom,sdm630-cdp"
compatible = "qcom,sda630-mtp"
compatible = "qcom,sda630-cdp"
+compatible = "qcom,sdm630-qrd"
compatible = "qcom,msm8952-rumi"
compatible = "qcom,msm8952-sim"
compatible = "qcom,msm8952-qrd"
diff --git a/Documentation/devicetree/bindings/arm/msm/spss_utils.txt b/Documentation/devicetree/bindings/arm/msm/spss_utils.txt
index 61d3865b73d5..0e8e75ba87f8 100644
--- a/Documentation/devicetree/bindings/arm/msm/spss_utils.txt
+++ b/Documentation/devicetree/bindings/arm/msm/spss_utils.txt
@@ -11,19 +11,25 @@ according to a dedicated fuse and the platform HW version.
Required properties:
-compatible : should be "qcom,spss_utils"
--qcom,spss-fuse-addr: fuse register physical address
--qcom,spss-fuse-bit: fuse relevant bit
+-qcom,spss-fuse1-addr: fuse1 register physical address
+-qcom,spss-fuse1-bit: fuse1 relevant bit
+-qcom,spss-fuse2-addr: fuse2 register physical address
+-qcom,spss-fuse2-bit: fuse2 relevant bit
-qcom,spss-test-firmware-name: test firmware file name
-qcom,spss-prod-firmware-name: production firmware file name
+-qcom,spss-hybr-firmware-name: hybrid firmware file name
-qcom,spss-debug-reg-addr: debug register physical address
Example:
qcom,spss_utils {
compatible = "qcom,spss-utils";
- qcom,spss-fuse-addr = <0x007841c4>; /* spss test fuse physical address */
- qcom,spss-fuse-bit = <27>;
- qcom,spss-test-firmware-name = "spss1t"; /* 8 chars max */
- qcom,spss-prod-firmware-name = "spss1p"; /* 8 chars max */
+ qcom,spss-fuse1-addr = <0x007841c4>;
+ qcom,spss-fuse1-bit = <27>;
+ qcom,spss-fuse2-addr = <0x0078413c>;
+ qcom,spss-fuse2-bit = <31>;
+ qcom,spss-test-firmware-name = "spss2t"; /* 8 chars max */
+ qcom,spss-prod-firmware-name = "spss2p"; /* 8 chars max */
+ qcom,spss-hybr-firmware-name = "spss2h"; /* 8 chars max */
qcom,spss-debug-reg-addr = <0x01d06020>;
};
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index e8177c3a0952..f79f49608743 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -1663,6 +1663,10 @@ mclk frequency needs to be configured for internal and external PA.
- qcom,cdc-comp-gpios : phandle for compander gpios.
- qcom,cdc-dmic-gpios : phandle for Digital mic clk and data gpios.
- qcom,cdc-sdw-gpios : phandle for soundwire clk and data gpios.
+- qcom,msm-mbhc-moist-cfg: This property is used to set moisture detection
+ threshold values for different codecs. First parameter is V(voltage)
+ second one is i(current), third one is r (resistance). Depending on the
+ codec set corresponding element in array and set others to 0.
Example:
sound {
@@ -1671,6 +1675,7 @@ Example:
qcom,msm-mclk-freq = <9600000>;
qcom,msm-mbhc-hphl-swh = <0>;
qcom,msm-mbhc-gnd-swh = <0>;
+ qcom,msm-mbhc-moist-cfg = <1>, <3>, <0>;
qcom,msm-hs-micbias-type = "internal";
qcom,msm-micbias1-ext-cap;
qcom,audio-routing =
diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile
index 65c42b8de30c..83fee34e5265 100644
--- a/arch/arm/boot/dts/qcom/Makefile
+++ b/arch/arm/boot/dts/qcom/Makefile
@@ -192,6 +192,7 @@ dtb-$(CONFIG_ARCH_SDM630) += sdm630-rumi.dtb \
sdm630-pm660a-cdp.dtb \
sdm630-pm660a-mtp.dtb \
sdm630-pm660a-rcm.dtb \
+ sdm630-pm660a-qrd.dtb \
sdm630-internal-codec-pm660a-cdp.dtb \
sdm630-internal-codec-pm660a-mtp.dtb \
sdm630-internal-codec-pm660a-rcm.dtb \
diff --git a/arch/arm/boot/dts/qcom/msm-audio.dtsi b/arch/arm/boot/dts/qcom/msm-audio.dtsi
index d86e77e2c7ee..46f66d667fb8 100644
--- a/arch/arm/boot/dts/qcom/msm-audio.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-audio.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -11,6 +11,10 @@
* GNU General Public License for more details.
*/
+&spi_7 {
+ status = "okay";
+};
+
&soc {
pcm0: qcom,msm-pcm {
compatible = "qcom,msm-pcm-dsp";
@@ -61,6 +65,18 @@
qcom,msm-cpe-lsm-id = <3>;
};
+ wdsp_mgr: qcom,wcd-dsp-mgr {
+ compatible = "qcom,wcd-dsp-mgr";
+ qcom,wdsp-components = <&wcd934x_cdc 0>,
+ <&wcd_spi_0 1>,
+ <&glink_spi_xprt_wdsp 2>;
+ qcom,img-filename = "cpe_9340";
+ };
+
+ wdsp_glink: qcom,wcd-dsp-glink {
+ compatible = "qcom,wcd-dsp-glink";
+ };
+
compress: qcom,msm-compress-dsp {
compatible = "qcom,msm-compress-dsp";
};
diff --git a/arch/arm/boot/dts/qcom/msm-pm660l-rpm-regulator.dtsi b/arch/arm/boot/dts/qcom/msm-pm660l-rpm-regulator.dtsi
index 83235317fa02..57b62489e502 100644
--- a/arch/arm/boot/dts/qcom/msm-pm660l-rpm-regulator.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pm660l-rpm-regulator.dtsi
@@ -43,8 +43,8 @@
rpm-regulator-smpb3 {
compatible = "qcom,rpm-smd-regulator-resource";
- qcom,resource-name = "smpb";
- qcom,resource-id = <3>;
+ qcom,resource-name = "rwcx";
+ qcom,resource-id = <0>;
qcom,regulator-type = <1>;
status = "disabled";
@@ -58,8 +58,8 @@
rpm-regulator-smpb5 {
compatible = "qcom,rpm-smd-regulator-resource";
- qcom,resource-name = "smpb";
- qcom,resource-id = <5>;
+ qcom,resource-name = "rwmx";
+ qcom,resource-id = <0>;
qcom,regulator-type = <1>;
status = "disabled";
diff --git a/arch/arm/boot/dts/qcom/msm-pm660l.dtsi b/arch/arm/boot/dts/qcom/msm-pm660l.dtsi
index d0033d5bf3bc..3ac4c851f5ba 100644
--- a/arch/arm/boot/dts/qcom/msm-pm660l.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pm660l.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -37,7 +37,7 @@
qcom,temp-alarm@2400 {
compatible = "qcom,qpnp-temp-alarm";
reg = <0x2400 0x100>;
- interrupts = <0x0 0x24 0x0 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <0x2 0x24 0x0 IRQ_TYPE_EDGE_RISING>;
label = "pm660l_tz";
};
diff --git a/arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk-evt3.dtsi b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk-evt3.dtsi
new file mode 100644
index 000000000000..7e52b0258f1f
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk-evt3.dtsi
@@ -0,0 +1,454 @@
+/*
+ * 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.
+ */
+
+&soc {
+ led_flash0: qcom,camera-flash@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera-flash";
+ qcom,flash-source = <&pmi8998_flash0 &pmi8998_flash1>;
+ qcom,torch-source = <&pmi8998_torch0 &pmi8998_torch1>;
+ qcom,switch-source = <&pmi8998_switch0>;
+ status = "ok";
+ };
+
+ led_flash1: qcom,camera-flash@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera-flash";
+ qcom,flash-source = <&pmi8998_flash2>;
+ qcom,torch-source = <&pmi8998_torch2>;
+ qcom,switch-source = <&pmi8998_switch1>;
+ status = "ok";
+ };
+
+ rear_vana_regulator:fixed_regulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "rear_vana_regulator";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ enable-active-high;
+ gpio = <&tlmm 27 0>;
+ vin-supply = <&pmi8998_bob>;
+ };
+
+ vaf1_gpio_supply:fixed_regulator@1 {
+ compatible = "regulator-fixed";
+ regulator-name = "vaf1_gpio_supply";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ enable-active-high;
+ gpio = <&tlmm 29 0>;
+ vin-supply = <&pmi8998_bob>;
+ };
+
+ vaf2_gpio_supply:fixed_regulator@2 {
+ compatible = "regulator-fixed";
+ regulator-name = "vaf2_gpio_supply";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ enable-active-high;
+ gpio = <&tlmm 27 0>;
+ vin-supply = <&pmi8998_bob>;
+ };
+};
+
+&tlmm{
+ cam_sensor_front_active: cam_sensor_front_active {
+ /* RESET */
+ mux {
+ pins = "gpio9";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio9";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_front_suspend: cam_sensor_front_suspend {
+ /* RESET */
+ mux {
+ pins = "gpio9";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio9";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_rear2_active: cam_sensor_rear2_active {
+ /* RESET, STANDBY */
+ mux {
+ pins = "gpio28";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio28";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_rear2_suspend: cam_sensor_rear2_suspend {
+ /* RESET, STANDBY */
+ mux {
+ pins = "gpio28";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio28";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_rear_active: cam_sensor_rear_active {
+ /* RESET, STANDBY */
+ mux {
+ pins = "gpio30";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio30";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+
+ cam_sensor_rear_suspend: cam_sensor_rear_suspend {
+ /* RESET, STANDBY */
+ mux {
+ pins = "gpio30";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio30";
+ bias-disable; /* No PULL */
+ drive-strength = <2>; /* 2 MA */
+ };
+ };
+};
+
+&cci {
+ actuator0: qcom,actuator@0 {
+ cell-index = <0>;
+ reg = <0x0>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&vaf1_gpio_supply>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2800000>;
+ qcom,cam-vreg-max-voltage = <2800000>;
+ qcom,cam-vreg-op-mode = <0>;
+ };
+
+ actuator1: qcom,actuator@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <1>;
+ cam_vaf-supply = <&vaf2_gpio_supply>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2800000>;
+ qcom,cam-vreg-max-voltage = <2800000>;
+ qcom,cam-vreg-op-mode = <0>;
+ };
+
+ ois0: qcom,ois@0 {
+ cell-index = <0>;
+ reg = <0x0>;
+ compatible = "qcom,ois";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&vaf2_gpio_supply>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2800000>;
+ qcom,cam-vreg-max-voltage = <2800000>;
+ qcom,cam-vreg-op-mode = <0>;
+ status = "disabled";
+ };
+
+ eeprom0: qcom,eeprom@0 {
+ cell-index = <0>;
+ reg = <0>;
+ compatible = "qcom,eeprom";
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&rear_vana_regulator>;
+ cam_vdig-supply = <&pm8998_s3>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage = <0 2800000 1352000>;
+ qcom,cam-vreg-max-voltage = <0 2800000 1352000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_active
+ &cam_sensor_rear_active>;
+ pinctrl-1 = <&cam_sensor_mclk0_suspend
+ &cam_sensor_rear_suspend>;
+ gpios = <&tlmm 13 0>,
+ <&tlmm 30 0>,
+ <&pm8998_gpios 20 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vdig = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+ "CAM_RESET0",
+ "CAM_VDIG";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_mmss clk_mclk0_clk_src>,
+ <&clock_mmss clk_mmss_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ eeprom1: qcom,eeprom@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ compatible = "qcom,eeprom";
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&rear_vana_regulator>;
+ cam_vdig-supply = <&pm8998_s3>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage = <0 2800000 1352000>;
+ qcom,cam-vreg-max-voltage = <0 2800000 1352000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_active
+ &cam_sensor_rear2_active>;
+ pinctrl-1 = <&cam_sensor_mclk1_suspend
+ &cam_sensor_rear2_suspend>;
+ gpios = <&tlmm 14 0>,
+ <&tlmm 28 0>,
+ <&pm8998_gpios 20 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vdig = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK1",
+ "CAM_RESET1",
+ "CAM_VDIG";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_mmss clk_mclk1_clk_src>,
+ <&clock_mmss clk_mmss_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ eeprom2: qcom,eeprom@2 {
+ cell-index = <2>;
+ reg = <0x2>;
+ compatible = "qcom,eeprom";
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&pm8998_l22>;
+ cam_vdig-supply = <&pm8998_s3>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage =
+ <0 2864000 1352000>;
+ qcom,cam-vreg-max-voltage =
+ <0 2864000 1352000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_active
+ &cam_sensor_front_active>;
+ pinctrl-1 = <&cam_sensor_mclk2_suspend
+ &cam_sensor_front_suspend>;
+ gpios = <&tlmm 15 0>,
+ <&tlmm 9 0>,
+ <&pm8998_gpios 9 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vdig = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_RESET2",
+ "CAM_VDIG";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_mmss clk_mclk2_clk_src>,
+ <&clock_mmss clk_mmss_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ qcom,camera@0 {
+ cell-index = <0>;
+ compatible = "qcom,camera";
+ reg = <0x0>;
+ qcom,special-support-sensors = "imx362_gt24c64a",
+ "s5k3m3sm", "s5k2l7sx";
+ qcom,csiphy-sd-index = <0>;
+ qcom,csid-sd-index = <0>;
+ qcom,mount-angle = <270>;
+ qcom,led-flash-src = <&led_flash0>;
+ qcom,actuator-src = <&actuator0>;
+ qcom,eeprom-src = <&eeprom0>;
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&rear_vana_regulator>;
+ cam_vdig-supply = <&pm8998_s3>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage = <0 2800000 1352000>;
+ qcom,cam-vreg-max-voltage = <0 2800000 1352000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_active
+ &cam_sensor_rear_active>;
+ pinctrl-1 = <&cam_sensor_mclk0_suspend
+ &cam_sensor_rear_suspend>;
+ gpios = <&tlmm 13 0>,
+ <&tlmm 30 0>,
+ <&pm8998_gpios 20 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vdig = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+ "CAM_RESET0",
+ "CAM_VDIG";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_mmss clk_mclk0_clk_src>,
+ <&clock_mmss clk_mmss_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ qcom,camera@1 {
+ cell-index = <1>;
+ compatible = "qcom,camera";
+ reg = <0x1>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <90>;
+ qcom,led-flash-src = <&led_flash0>;
+ qcom,actuator-src = <&actuator1>;
+ qcom,eeprom-src = <&eeprom1>;
+ qcom,ois-src = <&ois0>;
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&rear_vana_regulator>;
+ cam_vdig-supply = <&pm8998_s3>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage = <0 2800000 1352000>;
+ qcom,cam-vreg-max-voltage = <0 2800000 1352000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_active
+ &cam_sensor_rear2_active>;
+ pinctrl-1 = <&cam_sensor_mclk1_suspend
+ &cam_sensor_rear2_suspend>;
+ gpios = <&tlmm 14 0>,
+ <&tlmm 28 0>,
+ <&pm8998_gpios 20 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vdig = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK1",
+ "CAM_RESET1",
+ "CAM_VDIG";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_mmss clk_mclk1_clk_src>,
+ <&clock_mmss clk_mmss_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ qcom,camera@2 {
+ cell-index = <2>;
+ compatible = "qcom,camera";
+ reg = <0x02>;
+ qcom,csiphy-sd-index = <2>;
+ qcom,csid-sd-index = <2>;
+ qcom,mount-angle = <90>;
+ qcom,eeprom-src = <&eeprom2>;
+ cam_vio-supply = <&pm8998_lvs1>;
+ cam_vana-supply = <&pm8998_l22>;
+ cam_vdig-supply = <&pm8998_s3>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vdig";
+ qcom,cam-vreg-min-voltage =
+ <0 2864000 1352000>;
+ qcom,cam-vreg-max-voltage =
+ <0 2864000 1352000>;
+ qcom,cam-vreg-op-mode = <0 80000 105000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_active
+ &cam_sensor_front_active>;
+ pinctrl-1 = <&cam_sensor_mclk2_suspend
+ &cam_sensor_front_suspend>;
+ gpios = <&tlmm 15 0>,
+ <&tlmm 9 0>,
+ <&pm8998_gpios 9 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-vdig = <2>;
+ qcom,gpio-req-tbl-num = <0 1 2>;
+ qcom,gpio-req-tbl-flags = <1 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+ "CAM_RESET2",
+ "CAM_VDIG";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_mmss clk_mclk2_clk_src>,
+ <&clock_mmss clk_mmss_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+};
+
+&pm8998_gpios {
+ gpio@c800 { /* GPIO 9 - CAMERA SENSOR 2 VDIG */
+ qcom,mode = <1>; /* Output */
+ qcom,pull = <5>; /* No Pull */
+ qcom,vin-sel = <0>; /* VIN1 GPIO_LV */
+ qcom,src-sel = <0>; /* GPIO */
+ qcom,invert = <0>; /* Invert */
+ qcom,master-en = <1>; /* Enable GPIO */
+ status = "ok";
+ };
+
+ gpio@d300 { /* GPIO 20 - CAMERA SENSOR 0/1 VDIG */
+ qcom,mode = <1>; /* Output */
+ qcom,pull = <5>; /* No Pull */
+ qcom,vin-sel = <1>; /* VIN1 GPIO_MV */
+ qcom,src-sel = <0>; /* GPIO */
+ qcom,invert = <0>; /* Invert */
+ qcom,master-en = <1>; /* Enable GPIO */
+ status = "ok";
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/msm8998-camera.dtsi b/arch/arm/boot/dts/qcom/msm8998-camera.dtsi
index 799455a0de2e..f8dae210bc4e 100644
--- a/arch/arm/boot/dts/qcom/msm8998-camera.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-camera.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -559,7 +559,7 @@
"camss_vfe_ahb_clk", "camss_vfe_vbif_ahb_clk",
"camss_vfe_vbif_axi_clk", "vfe_clk_src",
"camss_csi_vfe_clk";
- qcom,clock-rates = <0 0 0 0 0 0 0 0 0 0 0 384000000 0
+ qcom,clock-rates = <0 0 0 0 0 0 0 0 0 0 0 480000000 0
0 0 0 0 0 0 0 0 0 0 0 576000000 0
0 0 0 0 0 0 0 0 0 0 0 600000000 0>;
status = "ok";
@@ -639,7 +639,7 @@
"camss_vfe_ahb_clk", "camss_vfe_vbif_ahb_clk",
"camss_vfe_vbif_axi_clk", "vfe_clk_src",
"camss_csi_vfe_clk";
- qcom,clock-rates = <0 0 0 0 0 0 0 0 0 0 0 384000000 0
+ qcom,clock-rates = <0 0 0 0 0 0 0 0 0 0 0 480000000 0
0 0 0 0 0 0 0 0 0 0 0 576000000 0
0 0 0 0 0 0 0 0 0 0 0 600000000 0>;
status = "ok";
diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dts b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dts
index d9afddd0ab46..753f01ea2ea7 100644
--- a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dts
+++ b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -15,6 +15,7 @@
#include "msm8998.dtsi"
#include "msm8998-qrd-skuk.dtsi"
+#include "msm8998-camera-sensor-skuk.dtsi"
/ {
model = "Qualcomm Technologies, Inc. MSM 8998 SKUK";
diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi
index d912a18d06f8..c57fa50d0f29 100644
--- a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi
@@ -13,7 +13,6 @@
#include <dt-bindings/interrupt-controller/irq.h>
#include "msm8998-pinctrl.dtsi"
#include "msm8998-audio.dtsi"
-#include "msm8998-camera-sensor-skuk.dtsi"
/ {
bluetooth: bt_wcn3990 {
diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts
index 51ff3888bc3d..a64f620f3999 100644
--- a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts
+++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -15,6 +15,7 @@
#include "msm8998-v2.dtsi"
#include "msm8998-qrd-skuk.dtsi"
+#include "msm8998-camera-sensor-skuk-evt3.dtsi"
/ {
model = "Qualcomm Technologies, Inc. MSM 8998 V2 SKUK EVT3";
diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts
index c2b70224ed2c..ca0609f34642 100644
--- a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts
+++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -15,6 +15,7 @@
#include "msm8998-v2.dtsi"
#include "msm8998-qrd-skuk.dtsi"
+#include "msm8998-camera-sensor-skuk.dtsi"
/ {
model = "Qualcomm Technologies, Inc. MSM 8998 SKUK HDK";
diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk.dts
index 471602ac80b9..7e7eb96c01d6 100644
--- a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk.dts
+++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -15,6 +15,7 @@
#include "msm8998-v2.dtsi"
#include "msm8998-qrd-skuk.dtsi"
+#include "msm8998-camera-sensor-skuk.dtsi"
/ {
model = "Qualcomm Technologies, Inc. MSM 8998 V2 SKUK";
diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2.dtsi
index 2408ad515b61..1d8fe225c9af 100644
--- a/arch/arm/boot/dts/qcom/msm8998-v2.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-v2.dtsi
@@ -1001,7 +1001,7 @@
&gfx_cpr {
compatible = "qcom,cpr4-msm8998-v2-mmss-regulator";
- qcom,cpr-aging-ref-voltage = <1024000>;
+ qcom,cpr-aging-ref-voltage = <1088000>;
};
&gfx_vreg {
@@ -1016,13 +1016,13 @@
qcom,cpr-voltage-ceiling =
<716000 716000 772000 880000 908000 948000 1016000 1088000>,
- <724000 724000 772000 832000 916000 968000 1024000 1024000>,
- <724000 724000 772000 832000 916000 968000 1024000 1024000>,
- <724000 724000 772000 832000 916000 968000 1024000 1024000>,
- <724000 724000 772000 832000 916000 968000 1024000 1024000>,
- <724000 724000 772000 832000 916000 968000 1024000 1024000>,
- <724000 724000 772000 832000 916000 968000 1024000 1024000>,
- <724000 724000 772000 832000 916000 968000 1024000 1024000>;
+ <724000 724000 772000 832000 916000 968000 1024000 1088000>,
+ <724000 724000 772000 832000 916000 968000 1024000 1088000>,
+ <724000 724000 772000 832000 916000 968000 1024000 1088000>,
+ <724000 724000 772000 832000 916000 968000 1024000 1088000>,
+ <724000 724000 772000 832000 916000 968000 1024000 1088000>,
+ <724000 724000 772000 832000 916000 968000 1024000 1088000>,
+ <724000 724000 772000 832000 916000 968000 1024000 1088000>;
qcom,cpr-voltage-floor =
<516000 516000 532000 584000 632000 672000 712000 756000>;
@@ -1272,6 +1272,7 @@
&spss_utils {
qcom,spss-test-firmware-name = "spss2t"; /* 8 chars max */
qcom,spss-prod-firmware-name = "spss2p"; /* 8 chars max */
+ qcom,spss-hybr-firmware-name = "spss2h"; /* 8 chars max */
};
&ufs1 {
diff --git a/arch/arm/boot/dts/qcom/msm8998.dtsi b/arch/arm/boot/dts/qcom/msm8998.dtsi
index 150a3c42c6b7..cb3d1fee1f48 100644
--- a/arch/arm/boot/dts/qcom/msm8998.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998.dtsi
@@ -1510,11 +1510,14 @@
spss_utils: qcom,spss_utils {
compatible = "qcom,spss-utils";
- /* spss test fuse physical address */
- qcom,spss-fuse-addr = <0x007841c4>;
- qcom,spss-fuse-bit = <27>;
+ /* spss fuses physical address */
+ qcom,spss-fuse1-addr = <0x007841c4>;
+ qcom,spss-fuse1-bit = <27>;
+ qcom,spss-fuse2-addr = <0x0078413c>;
+ qcom,spss-fuse2-bit = <31>;
qcom,spss-test-firmware-name = "spss"; /* default name */
qcom,spss-prod-firmware-name = "spss1p"; /* 8 chars max */
+ qcom,spss-hybr-firmware-name = "spss1h"; /* 8 chars max */
qcom,spss-debug-reg-addr = <0x01d06020>;
status = "ok";
};
@@ -2195,37 +2198,42 @@
qcom,sensor-type = "tsens";
qcom,sensor-name = "tsens_tz_sensor15";
qcom,scaling-factor = <10>;
+ qcom,alias-name = "modem_dsp";
};
sensor_information16: qcom,sensor-information-16 {
qcom,sensor-type = "tsens";
qcom,sensor-name = "tsens_tz_sensor16";
- qcom,alias-name = "pop_mem";
qcom,scaling-factor = <10>;
};
sensor_information17: qcom,sensor-information-17 {
qcom,sensor-type = "tsens";
qcom,sensor-name = "tsens_tz_sensor17";
qcom,scaling-factor = <10>;
+ qcom,alias-name = "hvx";
};
sensor_information18: qcom,sensor-information-18 {
qcom,sensor-type = "tsens";
qcom,sensor-name = "tsens_tz_sensor18";
qcom,scaling-factor = <10>;
+ qcom,alias-name = "camera";
};
sensor_information19: qcom,sensor-information-19 {
qcom,sensor-type = "tsens";
qcom,sensor-name = "tsens_tz_sensor19";
qcom,scaling-factor = <10>;
+ qcom,alias-name = "multi_media_ss";
};
sensor_information20: qcom,sensor-information-20 {
qcom,sensor-type = "tsens";
qcom,sensor-name = "tsens_tz_sensor20";
qcom,scaling-factor = <10>;
+ qcom,alias-name = "modem";
};
sensor_information21: qcom,sensor-information-21 {
qcom,sensor-type = "tsens";
qcom,sensor-name = "tsens_tz_sensor21";
qcom,scaling-factor = <10>;
+ qcom,alias-name = "pop_mem";
};
sensor_information22: qcom,sensor-information-22 {
qcom,sensor-type = "alarm";
diff --git a/arch/arm/boot/dts/qcom/sda658.dtsi b/arch/arm/boot/dts/qcom/sda658.dtsi
index 33018a177b41..035b93eacf5d 100644
--- a/arch/arm/boot/dts/qcom/sda658.dtsi
+++ b/arch/arm/boot/dts/qcom/sda658.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -17,3 +17,13 @@
compatible = "qcom,sda658";
qcom,msm-id = <326 0x0>;
};
+
+&soc {
+ qcom,rmnet-ipa {
+ status = "disabled";
+ };
+};
+
+&ipa_hw {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/qcom/sda660.dtsi b/arch/arm/boot/dts/qcom/sda660.dtsi
index d2919a9467dd..d394c277ecdd 100644
--- a/arch/arm/boot/dts/qcom/sda660.dtsi
+++ b/arch/arm/boot/dts/qcom/sda660.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -17,3 +17,13 @@
compatible = "qcom,sda660";
qcom,msm-id = <324 0x0>;
};
+
+&soc {
+ qcom,rmnet-ipa {
+ status = "disabled";
+ };
+};
+
+&ipa_hw {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/qcom/sdm630-cdp.dtsi b/arch/arm/boot/dts/qcom/sdm630-cdp.dtsi
index 6779d80d76cf..c22926510f94 100644
--- a/arch/arm/boot/dts/qcom/sdm630-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm630-cdp.dtsi
@@ -22,3 +22,7 @@
&soc {
};
+
+&pm660_charger {
+ qcom,batteryless-platform;
+};
diff --git a/arch/arm/boot/dts/qcom/sdm630-mtp.dtsi b/arch/arm/boot/dts/qcom/sdm630-mtp.dtsi
index 16d6c1bf9500..b4b22d31402e 100644
--- a/arch/arm/boot/dts/qcom/sdm630-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm630-mtp.dtsi
@@ -12,6 +12,11 @@
#include "sdm660-pinctrl.dtsi"
/ {
+ mtp_batterydata: qcom,battery-data {
+ qcom,batt-id-range-pct = <15>;
+ #include "fg-gen3-batterydata-itech-3000mah.dtsi"
+ #include "fg-gen3-batterydata-ascent-3450mah.dtsi"
+ };
};
&uartblsp1dm1 {
@@ -26,3 +31,7 @@
&soc {
};
+
+&pm660_fg {
+ qcom,battery-data = <&mtp_batterydata>;
+};
diff --git a/arch/arm/boot/dts/qcom/sdm630-pm660a-qrd.dts b/arch/arm/boot/dts/qcom/sdm630-pm660a-qrd.dts
new file mode 100644
index 000000000000..d535d62e521c
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdm630-pm660a-qrd.dts
@@ -0,0 +1,25 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm630.dtsi"
+#include "sdm630-qrd.dtsi"
+#include "msm-pm660a.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM 630 PM660 + PM660A QRD";
+ compatible = "qcom,sdm630-qrd", "qcom,sdm630", "qcom,qrd";
+ qcom,board-id = <0x0002000b 0x00>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>;
+};
diff --git a/arch/arm/boot/dts/qcom/sdm630-qrd.dtsi b/arch/arm/boot/dts/qcom/sdm630-qrd.dtsi
new file mode 100644
index 000000000000..6779d80d76cf
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdm630-qrd.dtsi
@@ -0,0 +1,24 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "sdm660-pinctrl.dtsi"
+/ {
+};
+
+&uartblsp1dm1 {
+ status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart_console_active>;
+};
+
+&soc {
+};
diff --git a/arch/arm/boot/dts/qcom/sdm630.dtsi b/arch/arm/boot/dts/qcom/sdm630.dtsi
index 2ebabab84f11..9186ce0118a3 100644
--- a/arch/arm/boot/dts/qcom/sdm630.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm630.dtsi
@@ -312,6 +312,7 @@
};
};
+#include "sdm660-blsp.dtsi"
#include "sdm630-smp2p.dtsi"
#include "sdm630-coresight.dtsi"
&soc {
@@ -343,6 +344,22 @@
clock-frequency = <19200000>;
};
+ dma_blsp1: qcom,sps-dma@0xc144000{ /* BLSP1 */
+ #dma-cells = <4>;
+ compatible = "qcom,sps-dma";
+ reg = <0xc144000 0x1F000>;
+ interrupts = <0 238 0>;
+ qcom,summing-threshold = <0x10>;
+ };
+
+ dma_blsp2: qcom,sps-dma@0xc184000{ /* BLSP2 */
+ #dma-cells = <4>;
+ compatible = "qcom,sps-dma";
+ reg = <0xc184000 0x1F000>;
+ interrupts = <0 239 0>;
+ qcom,summing-threshold = <0x10>;
+ };
+
restart@10ac000 {
compatible = "qcom,pshold";
reg = <0x10ac000 0x4>,
@@ -659,6 +676,31 @@
clock-names = "core", "iface";
};
+ slim_aud: slim@151c0000 {
+ cell-index = <1>;
+ compatible = "qcom,slim-ngd";
+ reg = <0x151c0000 0x2c000>,
+ <0x15180000 0x2e000>;
+ reg-names = "slimbus_physical", "slimbus_bam_physical";
+ interrupts = <0 163 0>, <0 164 0>;
+ interrupt-names = "slimbus_irq", "slimbus_bam_irq";
+ qcom,apps-ch-pipes = <0x7e0000>;
+ qcom,ea-pc = <0x260>;
+ status = "disabled";
+ };
+
+ slim_qca: slim@15240000 {
+ cell-index = <3>;
+ compatible = "qcom,slim-ngd";
+ reg = <0x15240000 0x2c000>,
+ <0x15200000 0x24000>;
+ reg-names = "slimbus_physical", "slimbus_bam_physical";
+ interrupts = <0 291 0>, <0 292 0>;
+ interrupt-names = "slimbus_irq", "slimbus_bam_irq";
+ qcom,apps-ch-pipes = <0x1800>;
+ status = "disabled";
+ };
+
timer@17920000 {
#address-cells = <1>;
#size-cells = <1>;
@@ -806,6 +848,72 @@
#clock-cells = <1>;
};
+ ipa_hw: qcom,ipa@14780000 {
+ compatible = "qcom,ipa";
+ reg = <0x14780000 0x4effc>, <0x14784000 0x26934>;
+ reg-names = "ipa-base", "bam-base";
+ interrupts = <0 333 0>,
+ <0 432 0>;
+ interrupt-names = "ipa-irq", "bam-irq";
+ qcom,ipa-hw-ver = <6>; /* IPA core version = IPAv2.6L */
+ qcom,ipa-hw-mode = <0>; /* IPA hw type = Normal */
+ qcom,wan-rx-ring-size = <192>; /* IPA WAN-rx-ring-size*/
+ qcom,lan-rx-ring-size = <192>; /* IPA LAN-rx-ring-size*/
+ clocks = <&clock_rpmcc RPM_IPA_CLK>,
+ <&clock_rpmcc RPM_AGGR2_NOC_CLK>;
+ clock-names = "core_clk", "smmu_clk";
+ qcom,arm-smmu;
+ qcom,smmu-disable-htw;
+ qcom,smmu-s1-bypass;
+ qcom,ee = <0>;
+ qcom,use-ipa-tethering-bridge;
+ qcom,modem-cfg-emb-pipe-flt;
+ qcom,msm-bus,name = "ipa";
+ qcom,msm-bus,num-cases = <4>;
+ qcom,msm-bus,num-paths = <2>;
+ qcom,msm-bus,vectors-KBps =
+ /* No vote */
+ <90 512 0 0>,
+ <1 676 0 0>,
+ /* SVS */
+ <90 512 80000 640000>,
+ <1 676 80000 80000>,
+ /* NOMINAL */
+ <90 512 206000 960000>,
+ <1 676 206000 160000>,
+ /* TURBO */
+ <90 512 206000 960000>,
+ <1 676 206000 160000>;
+ qcom,bus-vector-names = "MIN", "SVS", "PERF", "TURBO";
+ qcom,rx-polling-sleep-ms = <2>; /* Polling sleep interval */
+ qcom,ipa-polling-iteration = <5>; /* Polling Iteration */
+
+ ipa_smmu_ap: ipa_smmu_ap {
+ compatible = "qcom,ipa-smmu-ap-cb";
+ iommus = <&anoc2_smmu 0x19C0>;
+ qcom,iova-mapping = <0x10000000 0x40000000>;
+ };
+
+ ipa_smmu_wlan: ipa_smmu_wlan {
+ status = "disabled";
+ compatible = "qcom,ipa-smmu-wlan-cb";
+ iommus = <&anoc2_smmu 0x19C1>;
+ };
+
+ ipa_smmu_uc: ipa_smmu_uc {
+ compatible = "qcom,ipa-smmu-uc-cb";
+ iommus = <&anoc2_smmu 0x19C2>;
+ qcom,iova-mapping = <0x40000000 0x20000000>;
+ };
+ };
+
+ qcom,rmnet-ipa {
+ compatible = "qcom,rmnet-ipa";
+ qcom,rmnet-ipa-ssr;
+ qcom,ipa-loaduC;
+ qcom,ipa-advertise-sg-support;
+ };
+
qcom,ipc-spinlock@1f40000 {
compatible = "qcom,ipc-spinlock-sfpb";
reg = <0x1f40000 0x8000>;
diff --git a/arch/arm/boot/dts/qcom/sdm660-camera.dtsi b/arch/arm/boot/dts/qcom/sdm660-camera.dtsi
index 747729d158a8..150c759496bf 100644
--- a/arch/arm/boot/dts/qcom/sdm660-camera.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-camera.dtsi
@@ -1,5 +1,5 @@
/*
- * 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
@@ -111,7 +111,7 @@
<&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>,
<&clock_mmss MMSS_CAMSS_AHB_CLK>,
<&clock_mmss MMSS_CAMSS_TOP_AHB_CLK>,
- <&clock_mmss CSI0_CLK_SRC>,
+ <&clock_mmss CSI2_CLK_SRC>,
<&clock_mmss MMSS_CAMSS_CSI2_CLK>,
<&clock_mmss MMSS_CAMSS_CPHY_CSID2_CLK>,
<&clock_mmss CSI2PHYTIMER_CLK_SRC>,
diff --git a/arch/arm/boot/dts/qcom/sdm660-cdp.dts b/arch/arm/boot/dts/qcom/sdm660-cdp.dts
index 8d338660a14a..0a226fad698e 100644
--- a/arch/arm/boot/dts/qcom/sdm660-cdp.dts
+++ b/arch/arm/boot/dts/qcom/sdm660-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -23,3 +23,13 @@
qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
<0x0001001b 0x0201011a 0x0 0x0>;
};
+
+&tavil_snd {
+ qcom,msm-mbhc-hphl-swh = <0>;
+ qcom,msm-mbhc-gnd-swh = <0>;
+};
+
+&tasha_snd {
+ qcom,msm-mbhc-hphl-swh = <0>;
+ qcom,msm-mbhc-gnd-swh = <0>;
+};
diff --git a/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi b/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi
index a3654c21f2db..84292383b1b0 100644
--- a/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-cdp.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -118,7 +118,7 @@
/* device core power supply */
vdd-supply = <&pm660l_l5>;
qcom,vdd-voltage-level = <2950000 2950000>;
- qcom,vdd-current-level = <15000 900000>;
+ qcom,vdd-current-level = <15000 800000>;
/* device communication power supply */
vdd-io-supply = <&pm660l_l2>;
@@ -134,8 +134,8 @@
interrupts = <0 1 2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0xffffffff>;
- interrupt-map = <0 &intc 0 125 0
- 1 &intc 0 221 0
+ interrupt-map = <0 &intc 0 0 125 0
+ 1 &intc 0 0 221 0
2 &tlmm 54 0>;
interrupt-names = "hc_irq", "pwr_irq", "status_irq";
cd-gpios = <&tlmm 54 0x1>;
@@ -152,3 +152,7 @@
compatible = "qcom,msm-ssc-sensors";
};
};
+
+&pm660_charger {
+ qcom,batteryless-platform;
+};
diff --git a/arch/arm/boot/dts/qcom/sdm660-coresight.dtsi b/arch/arm/boot/dts/qcom/sdm660-coresight.dtsi
index d712c04b3e70..b0002dddf419 100644
--- a/arch/arm/boot/dts/qcom/sdm660-coresight.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-coresight.dtsi
@@ -1061,6 +1061,22 @@
clock-names = "core_clk", "core_a_clk";
};
+ qpdi: qpdi@1fc1000 {
+ compatible = "qcom,coresight-qpdi";
+ reg = <0x01fc1000 0x4>;
+ reg-names = "qpdi-base";
+
+ coresight-name = "coresight-qpdi";
+
+ vdd-supply = <&pm660l_l5>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <15000 900000>;
+
+ vdd-io-supply = <&pm660l_l2>;
+ qcom,vdd-io-voltage-level = <1800000 2950000>;
+ qcom,vdd-io-current-level = <200 22000>;
+ };
+
funnel_qatb: funnel@6005000 {
compatible = "arm,primecell";
arm,primecell-periphid = <0x0003b908>;
diff --git a/arch/arm/boot/dts/qcom/sdm660-gpu.dtsi b/arch/arm/boot/dts/qcom/sdm660-gpu.dtsi
index e3a3835ae809..d347f033b12d 100644
--- a/arch/arm/boot/dts/qcom/sdm660-gpu.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-gpu.dtsi
@@ -65,6 +65,7 @@
/* <HZ/12> */
qcom,idle-timeout = <80>;
+ qcom,no-nap;
qcom,highest-bank-bit = <14>;
@@ -75,11 +76,11 @@
<&clock_gcc GCC_GPU_CFG_AHB_CLK>,
<&clock_gfx GPUCC_RBBMTIMER_CLK>,
<&clock_gcc GCC_GPU_BIMC_GFX_CLK>,
- <&clock_gcc GCC_GPU_BIMC_GFX_SRC_CLK>,
+ <&clock_gcc GCC_BIMC_GFX_CLK>,
<&clock_gpu GPUCC_RBCPR_CLK>;
clock-names = "core_clk", "iface_clk", "rbbmtimer_clk",
- "mem_clk", "mem_iface_clk", "rbcpr_clk";
+ "mem_clk", "alt_mem_iface_clk", "rbcpr_clk";
/* Bus Scale Settings */
qcom,gpubw-dev = <&gpubw>;
@@ -248,9 +249,9 @@
clocks =<&clock_gcc GCC_GPU_CFG_AHB_CLK>,
<&clock_gcc GCC_GPU_BIMC_GFX_CLK>,
- <&clock_gcc GCC_GPU_BIMC_GFX_SRC_CLK>;
+ <&clock_gcc GCC_BIMC_GFX_CLK>;
- clock-names = "iface_clk", "mem_clk", "mem_iface_clk";
+ clock-names = "iface_clk", "mem_clk", "alt_mem_iface_clk";
qcom,secure_align_mask = <0xfff>;
qcom,retention;
diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-cdp.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-cdp.dts
index 2a338d2ed07b..6272e7eefe2f 100644
--- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-cdp.dts
+++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -60,6 +60,30 @@
status = "disabled";
};
+&spi_7 {
+ status = "disabled";
+};
+
+&wdsp_mgr {
+ status = "disabled";
+};
+
+&wdsp_glink {
+ status = "disabled";
+};
+
+&glink_spi_xprt_wdsp {
+ status = "disabled";
+};
+
+&glink_fifo_wdsp {
+ status = "disabled";
+};
+
+&glink_qos_wdsp {
+ status = "disabled";
+};
+
&int_codec {
status = "okay";
};
diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-mtp.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-mtp.dts
index 3518402bd0dc..beedbe5676b1 100644
--- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-mtp.dts
+++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-mtp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -60,6 +60,30 @@
status = "disabled";
};
+&spi_7 {
+ status = "disabled";
+};
+
+&wdsp_mgr {
+ status = "disabled";
+};
+
+&wdsp_glink {
+ status = "disabled";
+};
+
+&glink_spi_xprt_wdsp {
+ status = "disabled";
+};
+
+&glink_fifo_wdsp {
+ status = "disabled";
+};
+
+&glink_qos_wdsp {
+ status = "disabled";
+};
+
&int_codec {
qcom,model = "sdm660-snd-card-mtp";
status = "okay";
diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-cdp.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-cdp.dts
index af0467cb3278..ec318a59561c 100644
--- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-cdp.dts
+++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -23,3 +23,75 @@
qcom,board-id = <1 1>;
qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>;
};
+
+&slim_aud {
+ status = "disabled";
+};
+
+&dai_slim {
+ status = "disabled";
+};
+
+&wcd9335 {
+ status = "disabled";
+};
+
+&wcd934x_cdc {
+ status = "disabled";
+};
+
+&clock_audio {
+ status = "disabled";
+};
+
+&wcd_rst_gpio {
+ status = "disabled";
+};
+
+&wcd9xxx_intc {
+ status = "disabled";
+};
+
+&tasha_snd {
+ status = "disabled";
+};
+
+&tavil_snd {
+ status = "disabled";
+};
+
+&spi_7 {
+ status = "disabled";
+};
+
+&wdsp_mgr {
+ status = "disabled";
+};
+
+&wdsp_glink {
+ status = "disabled";
+};
+
+&glink_spi_xprt_wdsp {
+ status = "disabled";
+};
+
+&glink_fifo_wdsp {
+ status = "disabled";
+};
+
+&glink_qos_wdsp {
+ status = "disabled";
+};
+
+&int_codec {
+ status = "okay";
+};
+
+&pmic_analog_codec {
+ status = "okay";
+};
+
+&msm_sdw_codec {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-mtp.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-mtp.dts
index c9e37963146c..4f4003220baf 100644
--- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-mtp.dts
+++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-mtp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -23,3 +23,75 @@
qcom,board-id = <8 1>;
qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>;
};
+
+&slim_aud {
+ status = "disabled";
+};
+
+&dai_slim {
+ status = "disabled";
+};
+
+&wcd9335 {
+ status = "disabled";
+};
+
+&wcd934x_cdc {
+ status = "disabled";
+};
+
+&clock_audio {
+ status = "disabled";
+};
+
+&wcd_rst_gpio {
+ status = "disabled";
+};
+
+&wcd9xxx_intc {
+ status = "disabled";
+};
+
+&tasha_snd {
+ status = "disabled";
+};
+
+&tavil_snd {
+ status = "disabled";
+};
+
+&spi_7 {
+ status = "disabled";
+};
+
+&wdsp_mgr {
+ status = "disabled";
+};
+
+&wdsp_glink {
+ status = "disabled";
+};
+
+&glink_spi_xprt_wdsp {
+ status = "disabled";
+};
+
+&glink_fifo_wdsp {
+ status = "disabled";
+};
+
+&glink_qos_wdsp {
+ status = "disabled";
+};
+
+&int_codec {
+ status = "okay";
+};
+
+&pmic_analog_codec {
+ status = "okay";
+};
+
+&msm_sdw_codec {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-rcm.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-rcm.dts
index d38f16d4f628..eda22eaa40ca 100644
--- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-rcm.dts
+++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-pm660a-rcm.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -23,3 +23,75 @@
qcom,board-id = <21 1>;
qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>;
};
+
+&slim_aud {
+ status = "disabled";
+};
+
+&dai_slim {
+ status = "disabled";
+};
+
+&wcd9335 {
+ status = "disabled";
+};
+
+&wcd934x_cdc {
+ status = "disabled";
+};
+
+&clock_audio {
+ status = "disabled";
+};
+
+&wcd_rst_gpio {
+ status = "disabled";
+};
+
+&wcd9xxx_intc {
+ status = "disabled";
+};
+
+&tasha_snd {
+ status = "disabled";
+};
+
+&tavil_snd {
+ status = "disabled";
+};
+
+&spi_7 {
+ status = "disabled";
+};
+
+&wdsp_mgr {
+ status = "disabled";
+};
+
+&wdsp_glink {
+ status = "disabled";
+};
+
+&glink_spi_xprt_wdsp {
+ status = "disabled";
+};
+
+&glink_fifo_wdsp {
+ status = "disabled";
+};
+
+&glink_qos_wdsp {
+ status = "disabled";
+};
+
+&int_codec {
+ status = "okay";
+};
+
+&pmic_analog_codec {
+ status = "okay";
+};
+
+&msm_sdw_codec {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdm660-internal-codec-rcm.dts b/arch/arm/boot/dts/qcom/sdm660-internal-codec-rcm.dts
index eb171c66849b..55958f3e31f6 100644
--- a/arch/arm/boot/dts/qcom/sdm660-internal-codec-rcm.dts
+++ b/arch/arm/boot/dts/qcom/sdm660-internal-codec-rcm.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -60,6 +60,30 @@
status = "disabled";
};
+&spi_7 {
+ status = "disabled";
+};
+
+&wdsp_mgr {
+ status = "disabled";
+};
+
+&wdsp_glink {
+ status = "disabled";
+};
+
+&glink_spi_xprt_wdsp {
+ status = "disabled";
+};
+
+&glink_fifo_wdsp {
+ status = "disabled";
+};
+
+&glink_qos_wdsp {
+ status = "disabled";
+};
+
&int_codec {
status = "okay";
};
diff --git a/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi b/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi
index fbf44f8350bd..da44cb131b65 100644
--- a/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-mtp.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -13,6 +13,11 @@
#include "sdm660-pinctrl.dtsi"
#include "sdm660-camera-sensor-mtp.dtsi"
/ {
+ mtp_batterydata: qcom,battery-data {
+ qcom,batt-id-range-pct = <15>;
+ #include "fg-gen3-batterydata-itech-3000mah.dtsi"
+ #include "fg-gen3-batterydata-ascent-3450mah.dtsi"
+ };
};
&uartblsp1dm1 {
@@ -118,7 +123,7 @@
/* device core power supply */
vdd-supply = <&pm660l_l5>;
qcom,vdd-voltage-level = <2950000 2950000>;
- qcom,vdd-current-level = <15000 900000>;
+ qcom,vdd-current-level = <15000 800000>;
/* device communication power supply */
vdd-io-supply = <&pm660l_l2>;
@@ -134,8 +139,8 @@
interrupts = <0 1 2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0xffffffff>;
- interrupt-map = <0 &intc 0 125 0
- 1 &intc 0 221 0
+ interrupt-map = <0 &intc 0 0 125 0
+ 1 &intc 0 0 221 0
2 &tlmm 54 0>;
interrupt-names = "hc_irq", "pwr_irq", "status_irq";
cd-gpios = <&tlmm 54 0x1>;
@@ -156,3 +161,7 @@
&mem_client_3_size {
qcom,peripheral-size = <0x500000>;
};
+
+&pm660_fg {
+ qcom,battery-data = <&mtp_batterydata>;
+};
diff --git a/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi b/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi
index 172668f7ec0b..0c933807cdd8 100644
--- a/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1301,7 +1301,7 @@
mdss_te_active: mdss_te_active {
mux {
pins = "gpio59";
- function = "mdp_vsync_p";
+ function = "mdp_vsync";
};
config {
pins = "gpio59";
@@ -1313,7 +1313,7 @@
mdss_te_suspend: mdss_te_suspend {
mux {
pins = "gpio59";
- function = "mdp_vsync_p";
+ function = "mdp_vsync";
};
config {
pins = "gpio59";
diff --git a/arch/arm/boot/dts/qcom/sdm660-rcm.dts b/arch/arm/boot/dts/qcom/sdm660-rcm.dts
index a3f9445d4164..63fa6c2d3c02 100644
--- a/arch/arm/boot/dts/qcom/sdm660-rcm.dts
+++ b/arch/arm/boot/dts/qcom/sdm660-rcm.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -23,3 +23,13 @@
qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
<0x0001001b 0x0201011a 0x0 0x0>;
};
+
+&tavil_snd {
+ qcom,msm-mbhc-hphl-swh = <0>;
+ qcom,msm-mbhc-gnd-swh = <0>;
+};
+
+&tasha_snd {
+ qcom,msm-mbhc-hphl-swh = <0>;
+ qcom,msm-mbhc-gnd-swh = <0>;
+};
diff --git a/arch/arm/boot/dts/qcom/sdm660-rumi.dts b/arch/arm/boot/dts/qcom/sdm660-rumi.dts
index 80202cc87322..09213e5b9c21 100644
--- a/arch/arm/boot/dts/qcom/sdm660-rumi.dts
+++ b/arch/arm/boot/dts/qcom/sdm660-rumi.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -97,7 +97,7 @@
/* device core power supply */
vdd-supply = <&pm660l_l5>;
qcom,vdd-voltage-level = <2950000 2950000>;
- qcom,vdd-current-level = <15000 900000>;
+ qcom,vdd-current-level = <15000 800000>;
/* device communication power supply */
vdd-io-supply = <&pm660l_l2>;
@@ -113,8 +113,8 @@
interrupts = <0 1 2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0xffffffff>;
- interrupt-map = <0 &intc 0 125 0
- 1 &intc 0 221 0
+ interrupt-map = <0 &intc 0 0 125 0
+ 1 &intc 0 0 221 0
2 &tlmm 54 0>;
interrupt-names = "hc_irq", "pwr_irq", "status_irq";
cd-gpios = <&tlmm 54 0x1>;
diff --git a/arch/arm/boot/dts/qcom/sdm660-sim.dts b/arch/arm/boot/dts/qcom/sdm660-sim.dts
index a3ee70d0bed0..33e0f9bd5507 100644
--- a/arch/arm/boot/dts/qcom/sdm660-sim.dts
+++ b/arch/arm/boot/dts/qcom/sdm660-sim.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -81,7 +81,7 @@
/* device core power supply */
vdd-supply = <&pm660l_l5>;
qcom,vdd-voltage-level = <2950000 2950000>;
- qcom,vdd-current-level = <15000 900000>;
+ qcom,vdd-current-level = <15000 800000>;
/* device communication power supply */
vdd-io-supply = <&pm660l_l2>;
@@ -97,8 +97,8 @@
interrupts = <0 1 2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0xffffffff>;
- interrupt-map = <0 &intc 0 125 0
- 1 &intc 0 221 0
+ interrupt-map = <0 &intc 0 0 125 0
+ 1 &intc 0 0 221 0
2 &tlmm 54 0>;
interrupt-names = "hc_irq", "pwr_irq", "status_irq";
cd-gpios = <&tlmm 54 0x1>;
diff --git a/arch/arm/boot/dts/qcom/sdm660.dtsi b/arch/arm/boot/dts/qcom/sdm660.dtsi
index 6e3cd999ac05..2657ef2eef51 100644
--- a/arch/arm/boot/dts/qcom/sdm660.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660.dtsi
@@ -52,6 +52,7 @@
reg = <0x0 0x0>;
enable-method = "psci";
qcom,limits-info = <&mitigation_profile0>;
+ qcom,lmh-dcvs = <&lmh_dcvs0>;
qcom,ea = <&ea0>;
efficiency = <1024>;
next-level-cache = <&L2_0>;
@@ -77,6 +78,7 @@
reg = <0x0 0x1>;
enable-method = "psci";
qcom,limits-info = <&mitigation_profile0>;
+ qcom,lmh-dcvs = <&lmh_dcvs0>;
qcom,ea = <&ea1>;
efficiency = <1024>;
next-level-cache = <&L2_0>;
@@ -96,6 +98,7 @@
reg = <0x0 0x2>;
enable-method = "psci";
qcom,limits-info = <&mitigation_profile0>;
+ qcom,lmh-dcvs = <&lmh_dcvs0>;
qcom,ea = <&ea2>;
efficiency = <1024>;
next-level-cache = <&L2_0>;
@@ -115,6 +118,7 @@
reg = <0x0 0x3>;
enable-method = "psci";
qcom,limits-info = <&mitigation_profile0>;
+ qcom,lmh-dcvs = <&lmh_dcvs0>;
qcom,ea = <&ea3>;
efficiency = <1024>;
next-level-cache = <&L2_0>;
@@ -134,6 +138,7 @@
reg = <0x0 0x100>;
enable-method = "psci";
qcom,limits-info = <&mitigation_profile1>;
+ qcom,lmh-dcvs = <&lmh_dcvs1>;
qcom,ea = <&ea4>;
efficiency = <1536>;
next-level-cache = <&L2_1>;
@@ -157,6 +162,7 @@
reg = <0x0 0x101>;
enable-method = "psci";
qcom,limits-info = <&mitigation_profile2>;
+ qcom,lmh-dcvs = <&lmh_dcvs1>;
qcom,ea = <&ea5>;
efficiency = <1536>;
next-level-cache = <&L2_1>;
@@ -176,6 +182,7 @@
reg = <0x0 0x102>;
enable-method = "psci";
qcom,limits-info = <&mitigation_profile3>;
+ qcom,lmh-dcvs = <&lmh_dcvs1>;
qcom,ea = <&ea6>;
efficiency = <1536>;
next-level-cache = <&L2_1>;
@@ -195,6 +202,7 @@
reg = <0x0 0x103>;
enable-method = "psci";
qcom,limits-info = <&mitigation_profile4>;
+ qcom,lmh-dcvs = <&lmh_dcvs1>;
qcom,ea = <&ea7>;
efficiency = <1536>;
next-level-cache = <&L2_1>;
@@ -325,6 +333,16 @@
alignment = <0x0 0x400000>;
size = <0x0 0x5c00000>;
};
+
+ /* global autoconfigured region for contiguous allocations */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ alloc-ranges = <0 0x00000000 0 0xffffffff>;
+ reusable;
+ alignment = <0 0x400000>;
+ size = <0 0x2000000>;
+ linux,cma-default;
+ };
};
bluetooth: bt_wcn3990 {
@@ -702,6 +720,9 @@
qcom,synchronous-cluster-map = <0 4 &CPU0 &CPU1 &CPU2 &CPU3>,
<1 4 &CPU4 &CPU5 &CPU6 &CPU7>;
+ clock-names = "osm";
+ clocks = <&clock_cpu PWRCL_CLK>;
+
qcom,vdd-restriction-temp = <5>;
qcom,vdd-restriction-temp-hysteresis = <10>;
@@ -729,6 +750,21 @@
};
};
+ qcom,bcl {
+ compatible = "qcom,bcl";
+ qcom,bcl-enable;
+ qcom,bcl-framework-interface;
+ qcom,bcl-hotplug-list = <&CPU6 &CPU7>;
+ qcom,bcl-soc-hotplug-list = <&CPU4 &CPU5 &CPU6 &CPU7>;
+ qcom,ibat-monitor {
+ qcom,low-threshold-uamp = <3400000>;
+ qcom,high-threshold-uamp = <4200000>;
+ qcom,vph-high-threshold-uv = <3500000>;
+ qcom,vph-low-threshold-uv = <3300000>;
+ qcom,soc-low-threshold = <10>;
+ };
+ };
+
qcom,lmh {
compatible = "qcom,lmh_v1";
interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
@@ -787,7 +823,7 @@
cell-index = <1>;
compatible = "qcom,slim-ngd";
reg = <0x151c0000 0x2c000>,
- <0x15180000 0x2e000>;
+ <0x15184000 0x2a000>;
reg-names = "slimbus_physical", "slimbus_bam_physical";
interrupts = <0 163 0>, <0 164 0>;
interrupt-names = "slimbus_irq", "slimbus_bam_irq";
@@ -800,7 +836,7 @@
cell-index = <3>;
compatible = "qcom,slim-ngd";
reg = <0x15240000 0x2c000>,
- <0x15200000 0x24000>;
+ <0x15204000 0x20000>;
reg-names = "slimbus_physical", "slimbus_bam_physical";
interrupts = <0 291 0>, <0 292 0>;
interrupt-names = "slimbus_irq", "slimbus_bam_irq";
@@ -1095,7 +1131,6 @@
clock_cpu: qcom,clk-cpu-660@179c0000 {
compatible = "qcom,clk-cpu-osm";
- status = "disabled";
reg = <0x179c0000 0x4000>, <0x17916000 0x1000>,
<0x17816000 0x1000>, <0x179d1000 0x1000>,
<0x00784130 0x8>;
@@ -1161,7 +1196,7 @@
qcom,apm-mode-ctl = <0x179d0004 0x179d0010>;
qcom,apm-ctrl-status = <0x179d000c 0x179d0018>;
- qcom,apm-threshold-voltage = <832000>;
+ qcom,apm-threshold-voltage = <872000>;
qcom,boost-fsm-en;
qcom,safe-fsm-en;
qcom,ps-fsm-en;
@@ -1715,11 +1750,13 @@
};
qcom,icnss@18800000 {
- status = "disabled";
compatible = "qcom,icnss";
reg = <0x18800000 0x800000>,
- <0x10ac000 0x20>;
- reg-names = "membase", "mpm_config";
+ <0xa0000000 0x10000000>,
+ <0xb0000000 0x10000>;
+ reg-names = "membase", "smmu_iova_base", "smmu_iova_ipa";
+ iommus = <&anoc2_smmu 0x1a00>,
+ <&anoc2_smmu 0x1a01>;
interrupts = <0 413 0>, /* CE0 */
<0 414 0>, /* CE1 */
<0 415 0>, /* CE2 */
@@ -2246,8 +2283,6 @@
#include "msm-gdsc-660.dtsi"
#include "sdm660-gpu.dtsi"
#include "sdm660-pm.dtsi"
-#include "msm-audio.dtsi"
-#include "sdm660-audio.dtsi"
&gdsc_usb30 {
status = "ok";
@@ -2324,12 +2359,26 @@
status = "ok";
};
+&clock_cpu {
+ lmh_dcvs0: qcom,limits-dcvs@0 {
+ compatible = "qcom,msm-hw-limits";
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ lmh_dcvs1: qcom,limits-dcvs@1 {
+ compatible = "qcom,msm-hw-limits";
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ };
+};
+
#include "msm-arm-smmu-660.dtsi"
#include "msm-arm-smmu-impl-defs-660.dtsi"
#include "sdm660-common.dtsi"
#include "sdm660-blsp.dtsi"
#include "sdm660-camera.dtsi"
#include "sdm660-vidc.dtsi"
+#include "msm-audio.dtsi"
+#include "sdm660-audio.dtsi"
&pm660l_gpios {
/* GPIO 7 for VOL_UP */
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 8eeb297d7b6f..0efb7c66e818 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -910,7 +910,7 @@ config RANDOMIZE_BASE
config RANDOMIZE_MODULE_REGION_FULL
bool "Randomize the module region independently from the core kernel"
- depends on RANDOMIZE_BASE
+ depends on RANDOMIZE_BASE && !DYNAMIC_FTRACE
default y
help
Randomizes the location of the module region without considering the
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c
index 217c639f9ef5..62152a48e65f 100644
--- a/arch/arm64/kernel/insn.c
+++ b/arch/arm64/kernel/insn.c
@@ -2,7 +2,7 @@
* Copyright (C) 2013 Huawei Ltd.
* Author: Jiang Liu <liuj97@gmail.com>
*
- * Copyright (C) 2014 Zi Shen Lim <zlim.lnx@gmail.com>
+ * Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -364,6 +364,9 @@ u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
u32 immlo, immhi, mask;
int shift;
+ if (insn == AARCH64_BREAK_FAULT)
+ return AARCH64_BREAK_FAULT;
+
switch (type) {
case AARCH64_INSN_IMM_ADR:
shift = 0;
@@ -378,7 +381,7 @@ u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) {
pr_err("aarch64_insn_encode_immediate: unknown immediate encoding %d\n",
type);
- return 0;
+ return AARCH64_BREAK_FAULT;
}
}
@@ -395,9 +398,12 @@ static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type,
{
int shift;
+ if (insn == AARCH64_BREAK_FAULT)
+ return AARCH64_BREAK_FAULT;
+
if (reg < AARCH64_INSN_REG_0 || reg > AARCH64_INSN_REG_SP) {
pr_err("%s: unknown register encoding %d\n", __func__, reg);
- return 0;
+ return AARCH64_BREAK_FAULT;
}
switch (type) {
@@ -418,7 +424,7 @@ static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type,
default:
pr_err("%s: unknown register type encoding %d\n", __func__,
type);
- return 0;
+ return AARCH64_BREAK_FAULT;
}
insn &= ~(GENMASK(4, 0) << shift);
@@ -447,7 +453,7 @@ static u32 aarch64_insn_encode_ldst_size(enum aarch64_insn_size_type type,
break;
default:
pr_err("%s: unknown size encoding %d\n", __func__, type);
- return 0;
+ return AARCH64_BREAK_FAULT;
}
insn &= ~GENMASK(31, 30);
@@ -461,14 +467,17 @@ static inline long branch_imm_common(unsigned long pc, unsigned long addr,
{
long offset;
- /*
- * PC: A 64-bit Program Counter holding the address of the current
- * instruction. A64 instructions must be word-aligned.
- */
- BUG_ON((pc & 0x3) || (addr & 0x3));
+ if ((pc & 0x3) || (addr & 0x3)) {
+ pr_err("%s: A64 instructions must be word aligned\n", __func__);
+ return range;
+ }
offset = ((long)addr - (long)pc);
- BUG_ON(offset < -range || offset >= range);
+
+ if (offset < -range || offset >= range) {
+ pr_err("%s: offset out of range\n", __func__);
+ return range;
+ }
return offset;
}
@@ -485,6 +494,8 @@ u32 __kprobes aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr,
* texts are within +/-128M.
*/
offset = branch_imm_common(pc, addr, SZ_128M);
+ if (offset >= SZ_128M)
+ return AARCH64_BREAK_FAULT;
switch (type) {
case AARCH64_INSN_BRANCH_LINK:
@@ -494,7 +505,7 @@ u32 __kprobes aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr,
insn = aarch64_insn_get_b_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown branch encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -511,6 +522,8 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr,
long offset;
offset = branch_imm_common(pc, addr, SZ_1M);
+ if (offset >= SZ_1M)
+ return AARCH64_BREAK_FAULT;
switch (type) {
case AARCH64_INSN_BRANCH_COMP_ZERO:
@@ -520,7 +533,7 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr,
insn = aarch64_insn_get_cbnz_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown branch encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -531,7 +544,7 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr,
insn |= AARCH64_INSN_SF_BIT;
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
@@ -551,7 +564,10 @@ u32 aarch64_insn_gen_cond_branch_imm(unsigned long pc, unsigned long addr,
insn = aarch64_insn_get_bcond_value();
- BUG_ON(cond < AARCH64_INSN_COND_EQ || cond > AARCH64_INSN_COND_AL);
+ if (cond < AARCH64_INSN_COND_EQ || cond > AARCH64_INSN_COND_AL) {
+ pr_err("%s: unknown condition encoding %d\n", __func__, cond);
+ return AARCH64_BREAK_FAULT;
+ }
insn |= cond;
return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn,
@@ -584,7 +600,7 @@ u32 aarch64_insn_gen_branch_reg(enum aarch64_insn_register reg,
insn = aarch64_insn_get_ret_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown branch encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -607,7 +623,7 @@ u32 aarch64_insn_gen_load_store_reg(enum aarch64_insn_register reg,
insn = aarch64_insn_get_str_reg_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown load/store encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -646,26 +662,30 @@ u32 aarch64_insn_gen_load_store_pair(enum aarch64_insn_register reg1,
insn = aarch64_insn_get_stp_post_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown load/store encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
switch (variant) {
case AARCH64_INSN_VARIANT_32BIT:
- /* offset must be multiples of 4 in the range [-256, 252] */
- BUG_ON(offset & 0x3);
- BUG_ON(offset < -256 || offset > 252);
+ if ((offset & 0x3) || (offset < -256) || (offset > 252)) {
+ pr_err("%s: offset must be multiples of 4 in the range of [-256, 252] %d\n",
+ __func__, offset);
+ return AARCH64_BREAK_FAULT;
+ }
shift = 2;
break;
case AARCH64_INSN_VARIANT_64BIT:
- /* offset must be multiples of 8 in the range [-512, 504] */
- BUG_ON(offset & 0x7);
- BUG_ON(offset < -512 || offset > 504);
+ if ((offset & 0x7) || (offset < -512) || (offset > 504)) {
+ pr_err("%s: offset must be multiples of 8 in the range of [-512, 504] %d\n",
+ __func__, offset);
+ return AARCH64_BREAK_FAULT;
+ }
shift = 3;
insn |= AARCH64_INSN_SF_BIT;
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
@@ -703,7 +723,7 @@ u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
insn = aarch64_insn_get_subs_imm_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown add/sub encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -714,11 +734,14 @@ u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
insn |= AARCH64_INSN_SF_BIT;
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
- BUG_ON(imm & ~(SZ_4K - 1));
+ if (imm & ~(SZ_4K - 1)) {
+ pr_err("%s: invalid immediate encoding %d\n", __func__, imm);
+ return AARCH64_BREAK_FAULT;
+ }
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
@@ -747,7 +770,7 @@ u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst,
insn = aarch64_insn_get_sbfm_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown bitfield encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -760,12 +783,18 @@ u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst,
mask = GENMASK(5, 0);
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
- BUG_ON(immr & ~mask);
- BUG_ON(imms & ~mask);
+ if (immr & ~mask) {
+ pr_err("%s: invalid immr encoding %d\n", __func__, immr);
+ return AARCH64_BREAK_FAULT;
+ }
+ if (imms & ~mask) {
+ pr_err("%s: invalid imms encoding %d\n", __func__, imms);
+ return AARCH64_BREAK_FAULT;
+ }
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
@@ -794,23 +823,33 @@ u32 aarch64_insn_gen_movewide(enum aarch64_insn_register dst,
insn = aarch64_insn_get_movn_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown movewide encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
- BUG_ON(imm & ~(SZ_64K - 1));
+ if (imm & ~(SZ_64K - 1)) {
+ pr_err("%s: invalid immediate encoding %d\n", __func__, imm);
+ return AARCH64_BREAK_FAULT;
+ }
switch (variant) {
case AARCH64_INSN_VARIANT_32BIT:
- BUG_ON(shift != 0 && shift != 16);
+ if (shift != 0 && shift != 16) {
+ pr_err("%s: invalid shift encoding %d\n", __func__,
+ shift);
+ return AARCH64_BREAK_FAULT;
+ }
break;
case AARCH64_INSN_VARIANT_64BIT:
insn |= AARCH64_INSN_SF_BIT;
- BUG_ON(shift != 0 && shift != 16 && shift != 32 &&
- shift != 48);
+ if (shift != 0 && shift != 16 && shift != 32 && shift != 48) {
+ pr_err("%s: invalid shift encoding %d\n", __func__,
+ shift);
+ return AARCH64_BREAK_FAULT;
+ }
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
@@ -844,20 +883,28 @@ u32 aarch64_insn_gen_add_sub_shifted_reg(enum aarch64_insn_register dst,
insn = aarch64_insn_get_subs_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown add/sub encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
switch (variant) {
case AARCH64_INSN_VARIANT_32BIT:
- BUG_ON(shift & ~(SZ_32 - 1));
+ if (shift & ~(SZ_32 - 1)) {
+ pr_err("%s: invalid shift encoding %d\n", __func__,
+ shift);
+ return AARCH64_BREAK_FAULT;
+ }
break;
case AARCH64_INSN_VARIANT_64BIT:
insn |= AARCH64_INSN_SF_BIT;
- BUG_ON(shift & ~(SZ_64 - 1));
+ if (shift & ~(SZ_64 - 1)) {
+ pr_err("%s: invalid shift encoding %d\n", __func__,
+ shift);
+ return AARCH64_BREAK_FAULT;
+ }
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
@@ -886,11 +933,15 @@ u32 aarch64_insn_gen_data1(enum aarch64_insn_register dst,
insn = aarch64_insn_get_rev32_value();
break;
case AARCH64_INSN_DATA1_REVERSE_64:
- BUG_ON(variant != AARCH64_INSN_VARIANT_64BIT);
+ if (variant != AARCH64_INSN_VARIANT_64BIT) {
+ pr_err("%s: invalid variant for reverse64 %d\n",
+ __func__, variant);
+ return AARCH64_BREAK_FAULT;
+ }
insn = aarch64_insn_get_rev64_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown data1 encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -901,7 +952,7 @@ u32 aarch64_insn_gen_data1(enum aarch64_insn_register dst,
insn |= AARCH64_INSN_SF_BIT;
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
@@ -938,7 +989,7 @@ u32 aarch64_insn_gen_data2(enum aarch64_insn_register dst,
insn = aarch64_insn_get_rorv_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown data2 encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -949,7 +1000,7 @@ u32 aarch64_insn_gen_data2(enum aarch64_insn_register dst,
insn |= AARCH64_INSN_SF_BIT;
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
@@ -977,7 +1028,7 @@ u32 aarch64_insn_gen_data3(enum aarch64_insn_register dst,
insn = aarch64_insn_get_msub_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown data3 encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
@@ -988,7 +1039,7 @@ u32 aarch64_insn_gen_data3(enum aarch64_insn_register dst,
insn |= AARCH64_INSN_SF_BIT;
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
@@ -1038,20 +1089,28 @@ u32 aarch64_insn_gen_logical_shifted_reg(enum aarch64_insn_register dst,
insn = aarch64_insn_get_bics_value();
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown logical encoding %d\n", __func__, type);
return AARCH64_BREAK_FAULT;
}
switch (variant) {
case AARCH64_INSN_VARIANT_32BIT:
- BUG_ON(shift & ~(SZ_32 - 1));
+ if (shift & ~(SZ_32 - 1)) {
+ pr_err("%s: invalid shift encoding %d\n", __func__,
+ shift);
+ return AARCH64_BREAK_FAULT;
+ }
break;
case AARCH64_INSN_VARIANT_64BIT:
insn |= AARCH64_INSN_SF_BIT;
- BUG_ON(shift & ~(SZ_64 - 1));
+ if (shift & ~(SZ_64 - 1)) {
+ pr_err("%s: invalid shift encoding %d\n", __func__,
+ shift);
+ return AARCH64_BREAK_FAULT;
+ }
break;
default:
- BUG_ON(1);
+ pr_err("%s: unknown variant encoding %d\n", __func__, variant);
return AARCH64_BREAK_FAULT;
}
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 896bd6ec90f6..82caf98491fa 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -70,6 +70,24 @@
#define FASTRPC_LINK_CONNECTED (0x3)
#define FASTRPC_LINK_DISCONNECTING (0x7)
+#define PERF_KEYS "count:flush:map:copy:glink:getargs:putargs:invalidate:invoke"
+#define FASTRPC_STATIC_HANDLE_LISTENER (3)
+#define FASTRPC_STATIC_HANDLE_MAX (20)
+
+#define PERF_END (void)0
+
+#define PERF(enb, cnt, ff) \
+ {\
+ struct timespec startT = {0};\
+ if (enb) {\
+ getnstimeofday(&startT);\
+ } \
+ ff ;\
+ if (enb) {\
+ cnt += getnstimediff(&startT);\
+ } \
+ }
+
static int fastrpc_glink_open(int cid);
static void fastrpc_glink_close(void *chan, int cid);
@@ -237,6 +255,18 @@ struct fastrpc_mmap {
uintptr_t attr;
};
+struct fastrpc_perf {
+ int64_t count;
+ int64_t flush;
+ int64_t map;
+ int64_t copy;
+ int64_t link;
+ int64_t getargs;
+ int64_t putargs;
+ int64_t invargs;
+ int64_t invoke;
+};
+
struct fastrpc_file {
struct hlist_node hn;
spinlock_t hlock;
@@ -246,11 +276,13 @@ struct fastrpc_file {
struct fastrpc_session_ctx *sctx;
struct fastrpc_session_ctx *secsctx;
uint32_t mode;
+ uint32_t profile;
int tgid;
int cid;
int ssrcount;
int pd;
struct fastrpc_apps *apps;
+ struct fastrpc_perf perf;
};
static struct fastrpc_apps gfa;
@@ -286,6 +318,17 @@ static struct fastrpc_channel_ctx gcinfo[NUM_CHANNELS] = {
},
};
+static inline int64_t getnstimediff(struct timespec *start)
+{
+ int64_t ns;
+ struct timespec ts, b;
+
+ getnstimeofday(&ts);
+ b = timespec_sub(ts, *start);
+ ns = timespec_to_ns(&b);
+ return ns;
+}
+
static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache)
{
struct fastrpc_file *fl = buf == 0 ? 0 : buf->fl;
@@ -1075,6 +1118,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
ipage++;
}
/* map ion buffers */
+ PERF(ctx->fl->profile, ctx->fl->perf.map,
for (i = 0; i < inbufs + outbufs; ++i) {
struct fastrpc_mmap *map = ctx->maps[i];
uint64_t buf = ptr_to_uint64(lpra[i].buf.pv);
@@ -1110,7 +1154,10 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
}
rpra[i].buf.pv = buf;
}
+ PERF_END);
+
/* copy non ion buffers */
+ PERF(ctx->fl->profile, ctx->fl->perf.copy,
rlen = copylen - metalen;
for (oix = 0; oix < inbufs + outbufs; ++oix) {
int i = ctx->overps[oix]->raix;
@@ -1146,7 +1193,9 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
args = args + mlen;
rlen -= mlen;
}
+ PERF_END);
+ PERF(ctx->fl->profile, ctx->fl->perf.flush,
for (oix = 0; oix < inbufs + outbufs; ++oix) {
int i = ctx->overps[oix]->raix;
struct fastrpc_mmap *map = ctx->maps[i];
@@ -1163,14 +1212,20 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
dmac_flush_range(uint64_to_ptr(rpra[i].buf.pv),
uint64_to_ptr(rpra[i].buf.pv + rpra[i].buf.len));
}
+ PERF_END);
+
inh = inbufs + outbufs;
for (i = 0; i < REMOTE_SCALARS_INHANDLES(sc); i++) {
rpra[inh + i].buf.pv = ptr_to_uint64(ctx->lpra[inh + i].buf.pv);
rpra[inh + i].buf.len = ctx->lpra[inh + i].buf.len;
rpra[inh + i].h = ctx->lpra[inh + i].h;
}
- if (!ctx->fl->sctx->smmu.coherent)
+
+ if (!ctx->fl->sctx->smmu.coherent) {
+ PERF(ctx->fl->profile, ctx->fl->perf.flush,
dmac_flush_range((char *)rpra, (char *)rpra + ctx->used);
+ PERF_END);
+ }
bail:
return err;
}
@@ -1390,7 +1445,10 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
int cid = fl->cid;
int interrupted = 0;
int err = 0;
+ struct timespec invoket;
+ if (fl->profile)
+ getnstimeofday(&invoket);
if (!kernel) {
VERIFY(err, 0 == context_restore_interrupted(fl, inv,
&ctx));
@@ -1409,19 +1467,30 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
goto bail;
if (REMOTE_SCALARS_LENGTH(ctx->sc)) {
+ PERF(fl->profile, fl->perf.getargs,
VERIFY(err, 0 == get_args(kernel, ctx));
+ PERF_END);
if (err)
goto bail;
}
+ PERF(fl->profile, fl->perf.invargs,
inv_args_pre(ctx);
if (mode == FASTRPC_MODE_SERIAL)
inv_args(ctx);
+ PERF_END);
+
+ PERF(fl->profile, fl->perf.link,
VERIFY(err, 0 == fastrpc_invoke_send(ctx, kernel, invoke->handle));
+ PERF_END);
+
if (err)
goto bail;
+
+ PERF(fl->profile, fl->perf.invargs,
if (mode == FASTRPC_MODE_PARALLEL)
inv_args(ctx);
+ PERF_END);
wait:
if (kernel)
wait_for_completion(&ctx->work);
@@ -1434,7 +1503,10 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
VERIFY(err, 0 == (err = ctx->retval));
if (err)
goto bail;
+
+ PERF(fl->profile, fl->perf.putargs,
VERIFY(err, 0 == put_args(kernel, ctx, invoke->pra));
+ PERF_END);
if (err)
goto bail;
bail:
@@ -1444,6 +1516,14 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
context_free(ctx);
if (fl->ssrcount != fl->apps->channel[cid].ssrcount)
err = ECONNRESET;
+
+ if (fl->profile && !interrupted) {
+ if (invoke->handle != FASTRPC_STATIC_HANDLE_LISTENER)
+ fl->perf.invoke += getnstimediff(&invoket);
+ if (!(invoke->handle >= 0 &&
+ invoke->handle <= FASTRPC_STATIC_HANDLE_MAX))
+ fl->perf.count++;
+ }
return err;
}
@@ -2086,6 +2166,8 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
fl->tgid = current->tgid;
fl->apps = me;
fl->cid = cid;
+ memset(&fl->perf, 0, sizeof(fl->perf));
+
VERIFY(err, !fastrpc_session_alloc_locked(&me->channel[cid], 0,
&fl->sctx));
if (err)
@@ -2156,6 +2238,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
struct fastrpc_ioctl_mmap mmap;
struct fastrpc_ioctl_munmap munmap;
struct fastrpc_ioctl_init init;
+ struct fastrpc_ioctl_perf perf;
} p;
void *param = (char *)ioctl_param;
struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data;
@@ -2211,11 +2294,36 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
case FASTRPC_MODE_SERIAL:
fl->mode = (uint32_t)ioctl_param;
break;
+ case FASTRPC_MODE_PROFILE:
+ fl->profile = (uint32_t)ioctl_param;
+ break;
default:
err = -ENOTTY;
break;
}
break;
+ case FASTRPC_IOCTL_GETPERF:
+ VERIFY(err, 0 == copy_from_user(&p.perf,
+ param, sizeof(p.perf)));
+ if (err)
+ goto bail;
+ p.perf.numkeys = sizeof(struct fastrpc_perf)/sizeof(int64_t);
+ if (p.perf.keys) {
+ char *keys = PERF_KEYS;
+
+ VERIFY(err, 0 == copy_to_user((char *)p.perf.keys,
+ keys, strlen(keys)+1));
+ if (err)
+ goto bail;
+ }
+ if (p.perf.data) {
+ VERIFY(err, 0 == copy_to_user((int64_t *)p.perf.data,
+ &fl->perf, sizeof(fl->perf)));
+ }
+ VERIFY(err, 0 == copy_to_user(param, &p.perf, sizeof(p.perf)));
+ if (err)
+ goto bail;
+ break;
case FASTRPC_IOCTL_GETINFO:
VERIFY(err, 0 == (err = fastrpc_get_info(fl, &info)));
if (err)
diff --git a/drivers/char/adsprpc_compat.c b/drivers/char/adsprpc_compat.c
index 1e5649a8d4c4..a224ba7ed3e4 100644
--- a/drivers/char/adsprpc_compat.c
+++ b/drivers/char/adsprpc_compat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -32,6 +32,8 @@
_IOWR('R', 6, struct compat_fastrpc_ioctl_init)
#define COMPAT_FASTRPC_IOCTL_INVOKE_ATTRS \
_IOWR('R', 7, struct compat_fastrpc_ioctl_invoke_attrs)
+#define COMPAT_FASTRPC_IOCTL_GETPERF \
+ _IOWR('R', 9, struct compat_fastrpc_ioctl_perf)
struct compat_remote_buf {
compat_uptr_t pv; /* buffer pointer */
@@ -83,6 +85,12 @@ struct compat_fastrpc_ioctl_init {
compat_int_t memfd; /* ION fd for the mem */
};
+struct compat_fastrpc_ioctl_perf { /* kernel performance data */
+ compat_uptr_t data;
+ compat_int_t numkeys;
+ compat_uptr_t keys;
+};
+
static int compat_get_fastrpc_ioctl_invoke(
struct compat_fastrpc_ioctl_invoke_attrs __user *inv32,
struct fastrpc_ioctl_invoke_attrs __user **inva,
@@ -222,6 +230,21 @@ static int compat_get_fastrpc_ioctl_munmap(
return err;
}
+static int compat_get_fastrpc_ioctl_perf(
+ struct compat_fastrpc_ioctl_perf __user *perf32,
+ struct fastrpc_ioctl_perf __user *perf)
+{
+ compat_uptr_t p;
+ int err;
+
+ err = get_user(p, &perf32->data);
+ err |= put_user(p, &perf->data);
+ err |= get_user(p, &perf32->keys);
+ err |= put_user(p, &perf->keys);
+
+ return err;
+}
+
static int compat_get_fastrpc_ioctl_init(
struct compat_fastrpc_ioctl_init __user *init32,
struct fastrpc_ioctl_init __user *init)
@@ -356,6 +379,30 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
case FASTRPC_IOCTL_SETMODE:
return filp->f_op->unlocked_ioctl(filp, cmd,
(unsigned long)compat_ptr(arg));
+ case COMPAT_FASTRPC_IOCTL_GETPERF:
+ {
+ struct compat_fastrpc_ioctl_perf __user *perf32;
+ struct fastrpc_ioctl_perf *perf;
+ compat_uint_t u;
+ long ret;
+
+ perf32 = compat_ptr(arg);
+ VERIFY(err, NULL != (perf = compat_alloc_user_space(
+ sizeof(*perf))));
+ if (err)
+ return -EFAULT;
+ VERIFY(err, 0 == compat_get_fastrpc_ioctl_perf(perf32,
+ perf));
+ if (err)
+ return err;
+ ret = filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_GETPERF,
+ (unsigned long)perf);
+ if (ret)
+ return ret;
+ err = get_user(u, &perf->numkeys);
+ err |= put_user(u, &perf32->numkeys);
+ return err;
+ }
default:
return -ENOIOCTLCMD;
}
diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h
index 4fc9396bfd3a..9b24e2da489f 100644
--- a/drivers/char/adsprpc_shared.h
+++ b/drivers/char/adsprpc_shared.h
@@ -25,6 +25,7 @@
#define FASTRPC_IOCTL_INVOKE_ATTRS \
_IOWR('R', 7, struct fastrpc_ioctl_invoke_attrs)
#define FASTRPC_IOCTL_GETINFO _IOWR('R', 8, uint32_t)
+#define FASTRPC_IOCTL_GETPERF _IOWR('R', 9, struct fastrpc_ioctl_perf)
#define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp"
#define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp"
@@ -45,6 +46,9 @@
/* Driver should operate in serial mode with the co-processor */
#define FASTRPC_MODE_SERIAL 1
+/* Driver should operate in profile mode with the co-processor */
+#define FASTRPC_MODE_PROFILE 2
+
/* INIT a new process or attach to guestos */
#define FASTRPC_INIT_ATTACH 0
#define FASTRPC_INIT_CREATE 1
@@ -159,7 +163,6 @@ struct fastrpc_ioctl_munmap {
ssize_t size; /* size */
};
-
struct fastrpc_ioctl_mmap {
int fd; /* ion fd */
uint32_t flags; /* flags for dsp to map with */
@@ -168,6 +171,12 @@ struct fastrpc_ioctl_mmap {
uintptr_t vaddrout; /* dsps virtual address */
};
+struct fastrpc_ioctl_perf { /* kernel performance data */
+ uintptr_t __user data;
+ uint32_t numkeys;
+ uintptr_t __user keys;
+};
+
struct smq_null_invoke {
uint64_t ctx; /* invoke caller context */
uint32_t handle; /* handle to invoke */
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index c37716e8273d..40c592457ea1 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016-2017, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -474,29 +474,7 @@ static int clk_rcg2_enable(struct clk_hw *hw)
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
if (rcg->flags & FORCE_ENABLE_RCGR) {
- if (!rcg->current_freq)
- rcg->current_freq = cxo_f.freq;
-
- if (rcg->current_freq == cxo_f.freq)
- rcg->curr_index = 0;
- else {
- f = qcom_find_freq(rcg->freq_tbl, rcg->current_freq);
- rcg->curr_index = qcom_find_src_index(hw,
- rcg->parent_map, f->src);
- }
-
- ret = clk_enable_disable_prepare_unprepare(hw, rcg->curr_index,
- rcg->new_index, true);
- if (ret) {
- pr_err("Failed to prepare_enable new and current sources\n");
- return ret;
- }
-
clk_rcg_set_force_enable(hw);
-
- clk_enable_disable_prepare_unprepare(hw, rcg->curr_index,
- rcg->new_index, false);
-
return ret;
}
@@ -563,8 +541,17 @@ static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate)
int ret = 0;
/* Current frequency */
- if (rcg->flags & FORCE_ENABLE_RCGR)
+ if (rcg->flags & FORCE_ENABLE_RCGR) {
rcg->current_freq = clk_get_rate(hw->clk);
+ if (rcg->current_freq == cxo_f.freq)
+ rcg->curr_index = 0;
+ else {
+ f = qcom_find_freq(rcg->freq_tbl, rcg->current_freq);
+ rcg->curr_index = qcom_find_src_index(hw,
+ rcg->parent_map, f->src);
+
+ }
+ }
/*
* Return if the RCG is currently disabled. This configuration update
@@ -583,6 +570,13 @@ static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate)
if (rcg->flags & FORCE_ENABLE_RCGR) {
rcg->new_index = qcom_find_src_index(hw,
rcg->parent_map, f->src);
+ ret = clk_enable_disable_prepare_unprepare(hw, rcg->curr_index,
+ rcg->new_index, true);
+ if (ret) {
+ pr_err("Failed to prepare_enable new & current src\n");
+ return ret;
+ }
+
ret = clk_rcg2_enable(hw);
if (ret) {
pr_err("Failed to enable rcg\n");
@@ -594,8 +588,11 @@ static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate)
if (ret)
return ret;
- if (rcg->flags & FORCE_ENABLE_RCGR)
+ if (rcg->flags & FORCE_ENABLE_RCGR) {
clk_rcg2_disable(hw);
+ clk_enable_disable_prepare_unprepare(hw, rcg->curr_index,
+ rcg->new_index, false);
+ }
return ret;
}
@@ -1063,7 +1060,8 @@ static int clk_dp_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long src_rate;
unsigned long num, den;
u32 mask = BIT(rcg->hid_width) - 1;
- u32 hid_div;
+ u32 hid_div, cfg;
+ int i, num_parents = clk_hw_get_num_parents(hw);
src_rate = clk_get_rate(clk_hw_get_parent(hw)->clk);
if (src_rate <= 0) {
@@ -1081,7 +1079,17 @@ static int clk_dp_set_rate(struct clk_hw *hw, unsigned long rate,
return -EINVAL;
}
- regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &hid_div);
+ regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
+ hid_div = cfg;
+ cfg &= CFG_SRC_SEL_MASK;
+ cfg >>= CFG_SRC_SEL_SHIFT;
+
+ for (i = 0; i < num_parents; i++)
+ if (cfg == rcg->parent_map[i].cfg) {
+ f.src = rcg->parent_map[i].src;
+ break;
+ }
+
f.pre_div = hid_div;
f.pre_div >>= CFG_SRC_DIV_SHIFT;
f.pre_div &= mask;
diff --git a/drivers/gpu/msm/adreno-gpulist.h b/drivers/gpu/msm/adreno-gpulist.h
index 2418ee003c22..f1439381d781 100644
--- a/drivers/gpu/msm/adreno-gpulist.h
+++ b/drivers/gpu/msm/adreno-gpulist.h
@@ -289,8 +289,8 @@ static const struct adreno_gpu_core adreno_gpulist[] = {
.major = 1,
.minor = 2,
.patchid = ANY_ID,
- .features = ADRENO_64BIT | ADRENO_CONTENT_PROTECTION |
- ADRENO_CPZ_RETENTION,
+ .features = ADRENO_PREEMPTION | ADRENO_64BIT |
+ ADRENO_CONTENT_PROTECTION | ADRENO_CPZ_RETENTION,
.pm4fw_name = "a530_pm4.fw",
.pfpfw_name = "a530_pfp.fw",
.zap_name = "a512_zap",
diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c
index 90b833888d9d..0aab38ccc703 100644
--- a/drivers/gpu/msm/adreno_a5xx.c
+++ b/drivers/gpu/msm/adreno_a5xx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -197,7 +197,8 @@ static void a5xx_platform_setup(struct adreno_device *adreno_dev)
/* A510 has 3 XIN ports in VBIF */
gpudev->vbif_xin_halt_ctrl0_mask =
A510_VBIF_XIN_HALT_CTRL0_MASK;
- } else if (adreno_is_a540(adreno_dev)) {
+ } else if (adreno_is_a540(adreno_dev) ||
+ adreno_is_a512(adreno_dev)) {
gpudev->snapshot_data->sect_sizes->cp_merciu = 1024;
}
@@ -485,7 +486,7 @@ static int a5xx_regulator_enable(struct adreno_device *adreno_dev)
kgsl_regwrite(device, A5XX_RBBM_CLOCK_CNTL, 0x00000055);
a5xx_hwcg_set(adreno_dev, true);
/* Turn on sp_input_clk at HM level */
- kgsl_regrmw(device, A5XX_RBBM_CLOCK_CNTL, 3, 0);
+ kgsl_regrmw(device, A5XX_RBBM_CLOCK_CNTL, 0xFF, 0);
return 0;
}
@@ -535,6 +536,9 @@ static void a5xx_regulator_disable(struct adreno_device *adreno_dev)
unsigned int reg;
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
+ if (adreno_is_a512(adreno_dev))
+ return;
+
/* If feature is not supported or not enabled */
if (!ADRENO_FEATURE(adreno_dev, ADRENO_SPTP_PC) ||
!test_bit(ADRENO_SPTP_PC_CTRL, &adreno_dev->pwrctrl_flag)) {
@@ -1120,6 +1124,65 @@ static const struct kgsl_hwcg_reg a540_hwcg_regs[] = {
{A5XX_RBBM_CLOCK_HYST_GPMU, 0x00000004}
};
+static const struct kgsl_hwcg_reg a512_hwcg_regs[] = {
+ {A5XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
+ {A5XX_RBBM_CLOCK_CNTL_SP1, 0x02222222},
+ {A5XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
+ {A5XX_RBBM_CLOCK_CNTL2_SP1, 0x02222220},
+ {A5XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
+ {A5XX_RBBM_CLOCK_HYST_SP1, 0x0000F3CF},
+ {A5XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
+ {A5XX_RBBM_CLOCK_DELAY_SP1, 0x00000080},
+ {A5XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
+ {A5XX_RBBM_CLOCK_CNTL_TP1, 0x22222222},
+ {A5XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+ {A5XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222},
+ {A5XX_RBBM_CLOCK_CNTL3_TP0, 0x00002222},
+ {A5XX_RBBM_CLOCK_CNTL3_TP1, 0x00002222},
+ {A5XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
+ {A5XX_RBBM_CLOCK_HYST_TP1, 0x77777777},
+ {A5XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+ {A5XX_RBBM_CLOCK_HYST2_TP1, 0x77777777},
+ {A5XX_RBBM_CLOCK_HYST3_TP0, 0x00007777},
+ {A5XX_RBBM_CLOCK_HYST3_TP1, 0x00007777},
+ {A5XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+ {A5XX_RBBM_CLOCK_DELAY_TP1, 0x11111111},
+ {A5XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+ {A5XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111},
+ {A5XX_RBBM_CLOCK_DELAY3_TP0, 0x00001111},
+ {A5XX_RBBM_CLOCK_DELAY3_TP1, 0x00001111},
+ {A5XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
+ {A5XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222},
+ {A5XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222},
+ {A5XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222},
+ {A5XX_RBBM_CLOCK_HYST_UCHE, 0x00444444},
+ {A5XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+ {A5XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+ {A5XX_RBBM_CLOCK_CNTL_RB1, 0x22222222},
+ {A5XX_RBBM_CLOCK_CNTL2_RB0, 0x00222222},
+ {A5XX_RBBM_CLOCK_CNTL2_RB1, 0x00222222},
+ {A5XX_RBBM_CLOCK_CNTL_CCU0, 0x00022220},
+ {A5XX_RBBM_CLOCK_CNTL_CCU1, 0x00022220},
+ {A5XX_RBBM_CLOCK_CNTL_RAC, 0x05522222},
+ {A5XX_RBBM_CLOCK_CNTL2_RAC, 0x00555555},
+ {A5XX_RBBM_CLOCK_HYST_RB_CCU0, 0x04040404},
+ {A5XX_RBBM_CLOCK_HYST_RB_CCU1, 0x04040404},
+ {A5XX_RBBM_CLOCK_HYST_RAC, 0x07444044},
+ {A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_0, 0x00000002},
+ {A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_1, 0x00000002},
+ {A5XX_RBBM_CLOCK_DELAY_RAC, 0x00010011},
+ {A5XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+ {A5XX_RBBM_CLOCK_MODE_GPC, 0x02222222},
+ {A5XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+ {A5XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+ {A5XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+ {A5XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+ {A5XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+ {A5XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+ {A5XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+ {A5XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
+};
+
static const struct {
int (*devfunc)(struct adreno_device *adreno_dev);
const struct kgsl_hwcg_reg *regs;
@@ -1127,6 +1190,7 @@ static const struct {
} a5xx_hwcg_registers[] = {
{ adreno_is_a540, a540_hwcg_regs, ARRAY_SIZE(a540_hwcg_regs) },
{ adreno_is_a530, a530_hwcg_regs, ARRAY_SIZE(a530_hwcg_regs) },
+ { adreno_is_a512, a512_hwcg_regs, ARRAY_SIZE(a512_hwcg_regs) },
{ adreno_is_a510, a510_hwcg_regs, ARRAY_SIZE(a510_hwcg_regs) },
{ adreno_is_a505, a50x_hwcg_regs, ARRAY_SIZE(a50x_hwcg_regs) },
{ adreno_is_a506, a50x_hwcg_regs, ARRAY_SIZE(a50x_hwcg_regs) },
@@ -1871,6 +1935,11 @@ static void a5xx_start(struct adreno_device *adreno_dev)
kgsl_regwrite(device, A5XX_CP_MERCIU_SIZE, 0x20);
kgsl_regwrite(device, A5XX_CP_ROQ_THRESHOLDS_2, 0x40000030);
kgsl_regwrite(device, A5XX_CP_ROQ_THRESHOLDS_1, 0x20100D0A);
+ } else if (adreno_is_a540(adreno_dev) || adreno_is_a512(adreno_dev)) {
+ kgsl_regwrite(device, A5XX_CP_MEQ_THRESHOLDS, 0x40);
+ kgsl_regwrite(device, A5XX_CP_MERCIU_SIZE, 0x400);
+ kgsl_regwrite(device, A5XX_CP_ROQ_THRESHOLDS_2, 0x80000060);
+ kgsl_regwrite(device, A5XX_CP_ROQ_THRESHOLDS_1, 0x40201B16);
} else {
kgsl_regwrite(device, A5XX_CP_MEQ_THRESHOLDS, 0x40);
kgsl_regwrite(device, A5XX_CP_MERCIU_SIZE, 0x40);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index e238f54a9100..09de276e8418 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -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
@@ -1794,6 +1794,7 @@ int msm_isp_process_overflow_irq(
{
uint32_t overflow_mask;
uint32_t bus_err = 0;
+ unsigned long flags;
/* if there are no active streams - do not start recovery */
if (!vfe_dev->axi_data.num_active_stream)
@@ -1825,23 +1826,33 @@ int msm_isp_process_overflow_irq(
int i;
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+ spin_lock_irqsave(
+ &vfe_dev->common_data->common_dev_data_lock, flags);
+
if (atomic_cmpxchg(&vfe_dev->error_info.overflow_state,
- NO_OVERFLOW, OVERFLOW_DETECTED != NO_OVERFLOW))
+ NO_OVERFLOW, OVERFLOW_DETECTED)) {
+ spin_unlock_irqrestore(
+ &vfe_dev->common_data->common_dev_data_lock,
+ flags);
return 0;
+ }
if (vfe_dev->reset_pending == 1) {
- pr_err("%s:%d failed: overflow %x during reset\n",
+ pr_err_ratelimited("%s:%d overflow %x during reset\n",
__func__, __LINE__, overflow_mask);
/* Clear overflow bits since reset is pending */
*irq_status1 &= ~overflow_mask;
+ spin_unlock_irqrestore(
+ &vfe_dev->common_data->common_dev_data_lock,
+ flags);
return 0;
}
- pr_err("%s: vfe %d overflow mask %x, bus_error %x\n",
+ pr_err_ratelimited("%s: vfe %d overflowmask %x,bus_error %x\n",
__func__, vfe_dev->pdev->id, overflow_mask, bus_err);
for (i = 0; i < axi_data->hw_info->num_wm; i++) {
if (!axi_data->free_wm[i])
continue;
- pr_err("%s: wm %d assigned to stream handle %x\n",
+ ISP_DBG("%s:wm %d assigned to stream handle %x\n",
__func__, i, axi_data->free_wm[i]);
}
vfe_dev->recovery_irq0_mask = vfe_dev->irq0_mask;
@@ -1880,6 +1891,9 @@ int msm_isp_process_overflow_irq(
msm_isp_send_event(vfe_dev,
ISP_EVENT_ERROR, &error_event);
}
+ spin_unlock_irqrestore(
+ &vfe_dev->common_data->common_dev_data_lock,
+ flags);
return 1;
}
return 0;
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
index dc2061fc4537..5264bba57c8d 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -1447,6 +1447,12 @@ static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out,
pr_err_ratelimited("%s: fatal error, stop ispif immediately\n",
__func__);
for (i = 0; i < ispif->vfe_info.num_vfe; i++) {
+ msm_camera_io_w(0x0,
+ ispif->base + ISPIF_VFE_m_IRQ_MASK_0(i));
+ msm_camera_io_w(0x0,
+ ispif->base + ISPIF_VFE_m_IRQ_MASK_1(i));
+ msm_camera_io_w(0x0,
+ ispif->base + ISPIF_VFE_m_IRQ_MASK_2(i));
msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY,
ispif->base + ISPIF_VFE_m_INTF_CMD_0(i));
msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY,
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
index 4b4846907d0f..7f6e78710117 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -496,7 +496,7 @@ static int msm_jpegdma_queue_init(void *priv, struct vb2_queue *src_vq,
src_vq->drv_priv = ctx;
src_vq->mem_ops = &msm_jpegdma_vb2_mem_ops;
src_vq->ops = &msm_jpegdma_vb2_q_ops;
- src_vq->buf_struct_size = sizeof(struct vb2_v4l2_buffer);
+ src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
ret = vb2_queue_init(src_vq);
@@ -510,7 +510,7 @@ static int msm_jpegdma_queue_init(void *priv, struct vb2_queue *src_vq,
dst_vq->drv_priv = ctx;
dst_vq->mem_ops = &msm_jpegdma_vb2_mem_ops;
dst_vq->ops = &msm_jpegdma_vb2_q_ops;
- dst_vq->buf_struct_size = sizeof(struct vb2_v4l2_buffer);
+ dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
ret = vb2_queue_init(dst_vq);
diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
index ac9a4b2048d1..bc6fb191b3b5 100644
--- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
@@ -302,7 +302,7 @@ static void msm_buf_mngr_sd_shutdown(struct msm_buf_mngr_device *dev,
pr_info("%s: Delete invalid bufs =%lx, session_id=%u, bufs->ses_id=%d, str_id=%d, idx=%d\n",
__func__, (unsigned long)bufs, session->session,
bufs->session_id, bufs->stream_id,
- bufs->vb2_v4l2_buf->vb2_buf.index);
+ bufs->index);
if (session->session == bufs->session_id) {
list_del_init(&bufs->entry);
kfree(bufs);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 7aa01372412d..449514bae4f3 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -61,6 +61,7 @@ static const unsigned int tacc_mant[] = {
__res & __mask; \
})
+static int mmc_switch_status(struct mmc_card *card, bool ignore_crc);
/*
* Given the decoded CSD structure, decode the raw CID to our CID structure.
*/
@@ -1064,9 +1065,11 @@ static int mmc_select_hs(struct mmc_card *card)
err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS,
card->ext_csd.generic_cmd6_time,
- true, true, true);
- if (!err)
+ true, false, true);
+ if (!err) {
mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
+ err = mmc_switch_status(card, false);
+ }
return err;
}
@@ -1090,10 +1093,11 @@ static int mmc_select_hs_ddr(struct mmc_card *card)
ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
EXT_CSD_DDR_BUS_WIDTH_8 : EXT_CSD_DDR_BUS_WIDTH_4;
- err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_BUS_WIDTH,
ext_csd_bits,
- card->ext_csd.generic_cmd6_time);
+ card->ext_csd.generic_cmd6_time,
+ true, false, false);
if (err) {
pr_err("%s: switch to bus width %d ddr failed\n",
mmc_hostname(host), 1 << bus_width);
@@ -1136,19 +1140,21 @@ static int mmc_select_hs_ddr(struct mmc_card *card)
if (err)
err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330);
- if (!err)
+ if (!err) {
mmc_set_timing(host, MMC_TIMING_MMC_DDR52);
+ err = mmc_switch_status(card, false);
+ }
return err;
}
/* Caller must hold re-tuning */
-static int mmc_switch_status(struct mmc_card *card)
+static int mmc_switch_status(struct mmc_card *card, bool ignore_crc)
{
u32 status;
int err;
- err = mmc_send_status(card, &status);
+ err = __mmc_send_status(card, &status, ignore_crc);
if (err)
return err;
@@ -1212,7 +1218,7 @@ static int mmc_select_hs400(struct mmc_card *card)
mmc_set_clock(host, max_dtr);
if (!send_status) {
- err = mmc_switch_status(card);
+ err = mmc_switch_status(card, false);
if (err)
goto out_err;
}
@@ -1253,12 +1259,6 @@ static int mmc_select_hs400(struct mmc_card *card)
mmc_set_timing(host, MMC_TIMING_MMC_HS400);
mmc_set_bus_speed(card);
- if (!send_status) {
- err = mmc_switch_status(card);
- if (err)
- goto out_err;
- }
-
if (card->ext_csd.strobe_support && host->ops->enhanced_strobe) {
mmc_host_clk_hold(host);
err = host->ops->enhanced_strobe(host);
@@ -1275,6 +1275,17 @@ static int mmc_select_hs400(struct mmc_card *card)
mmc_hostname(host));
}
+ /*
+ * Sending of CMD13 should be done after the host calibration
+ * for enhanced_strobe or HS400 mode is completed.
+ * Otherwise may see CMD13 timeouts or CRC errors.
+ */
+ if (!send_status) {
+ err = mmc_switch_status(card, false);
+ if (err)
+ goto out_err;
+ }
+
return 0;
out_err:
@@ -1314,7 +1325,7 @@ int mmc_hs400_to_hs200(struct mmc_card *card)
mmc_set_timing(host, MMC_TIMING_MMC_DDR52);
if (!send_status) {
- err = mmc_switch_status(card);
+ err = mmc_switch_status(card, false);
if (err)
goto out_err;
}
@@ -1329,7 +1340,7 @@ int mmc_hs400_to_hs200(struct mmc_card *card)
mmc_set_timing(host, MMC_TIMING_MMC_HS);
if (!send_status) {
- err = mmc_switch_status(card);
+ err = mmc_switch_status(card, false);
if (err)
goto out_err;
}
@@ -1346,7 +1357,7 @@ int mmc_hs400_to_hs200(struct mmc_card *card)
mmc_set_timing(host, MMC_TIMING_MMC_HS200);
if (!send_status) {
- err = mmc_switch_status(card);
+ err = mmc_switch_status(card, false);
if (err)
goto out_err;
}
@@ -1425,7 +1436,12 @@ static int mmc_select_hs200(struct mmc_card *card)
old_timing = host->ios.timing;
mmc_set_timing(host, MMC_TIMING_MMC_HS200);
if (!send_status) {
- err = mmc_switch_status(card);
+ /*
+ * Since after switching to hs200, crc errors might
+ * occur for commands send before tuning.
+ * So ignore crc error for cmd13.
+ */
+ err = mmc_switch_status(card, true);
/*
* mmc_select_timing() assumes timing has not changed if
* it is a switch error.
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 4a978898af84..de406431e5a4 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -54,7 +54,7 @@ static const u8 tuning_blk_pattern_8bit[] = {
0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
};
-static inline int __mmc_send_status(struct mmc_card *card, u32 *status,
+int __mmc_send_status(struct mmc_card *card, u32 *status,
bool ignore_crc)
{
int err;
diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h
index 1eea7bd51367..ad1058c1adfd 100644
--- a/drivers/mmc/core/mmc_ops.h
+++ b/drivers/mmc/core/mmc_ops.h
@@ -32,6 +32,7 @@ int mmc_switch_status_error(struct mmc_host *host, u32 status);
int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
unsigned int timeout_ms, bool use_busy_signal, bool send_status,
bool ignore_crc);
-
+int __mmc_send_status(struct mmc_card *card, u32 *status,
+ bool ignore_crc);
#endif
diff --git a/drivers/platform/msm/seemp_core/seemp_event_encoder.c b/drivers/platform/msm/seemp_core/seemp_event_encoder.c
index df56a84bc667..36901f5fbee7 100644
--- a/drivers/platform/msm/seemp_core/seemp_event_encoder.c
+++ b/drivers/platform/msm/seemp_core/seemp_event_encoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015, 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -48,9 +48,15 @@ static void check_param_range(char *section_eq, bool param,
void encode_seemp_params(struct seemp_logk_blk *blk)
{
- char *s = blk->payload.msg + 1;
+ struct seemp_logk_blk tmp;
+ char *s = 0;
+ char *msg_section_start = 0;
+ char *msg_section_eq = 0;
+ char *msg_s = 0;
- blk->payload.msg[BLK_MAX_MSG_SZ - 1] = 0; /* zero-terminate */
+ memcpy(tmp.payload.msg, blk->payload.msg, BLK_MAX_MSG_SZ);
+ s = tmp.payload.msg + 1;
+ tmp.payload.msg[BLK_MAX_MSG_SZ - 1] = 0; /* zero-terminate */
while (true) {
char *section_start = s;
@@ -105,8 +111,13 @@ void encode_seemp_params(struct seemp_logk_blk *blk)
}
}
- encode_seemp_section(section_start, section_eq, s, param,
- numeric, id, numeric_value);
+ msg_section_start = blk->payload.msg + (section_start -
+ tmp.payload.msg);
+ msg_section_eq = blk->payload.msg + (section_eq -
+ tmp.payload.msg);
+ msg_s = blk->payload.msg + (s - tmp.payload.msg);
+ encode_seemp_section(msg_section_start, msg_section_eq,
+ msg_s, param, numeric, id, numeric_value);
if (*s == 0)
break;
diff --git a/drivers/power/qcom-charger/msm_bcl.c b/drivers/power/qcom-charger/msm_bcl.c
index 6b7cefdc0250..aea3f4645897 100644
--- a/drivers/power/qcom-charger/msm_bcl.c
+++ b/drivers/power/qcom-charger/msm_bcl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, 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
@@ -99,14 +99,14 @@ int msm_bcl_set_threshold(enum bcl_param param_type,
{
int ret = 0;
- if (!bcl[param_type] || !bcl[param_type]->registered) {
+ if (param_type >= BCL_PARAM_MAX || !bcl[param_type]
+ || !bcl[param_type]->registered) {
pr_err("BCL not initialized\n");
return -EINVAL;
}
if ((!inp_thresh)
|| (inp_thresh->trip_value < 0)
|| (!inp_thresh->trip_notify)
- || (param_type >= BCL_PARAM_MAX)
|| (trip_type >= BCL_TRIP_MAX)) {
pr_err("Invalid Input\n");
return -EINVAL;
@@ -152,8 +152,8 @@ struct bcl_param_data *msm_bcl_register_param(enum bcl_param param_type,
{
int ret = 0;
- if (!bcl[param_type]
- || param_type >= BCL_PARAM_MAX || !param_ops || !name
+ if (param_type >= BCL_PARAM_MAX
+ || !bcl[param_type] || !param_ops || !name
|| !param_ops->read || !param_ops->set_high_trip
|| !param_ops->get_high_trip || !param_ops->set_low_trip
|| !param_ops->get_low_trip || !param_ops->enable
diff --git a/drivers/power/qcom-charger/qpnp-fg.c b/drivers/power/qcom-charger/qpnp-fg.c
index 0658f0d3b1eb..e4a8ade80d4f 100644
--- a/drivers/power/qcom-charger/qpnp-fg.c
+++ b/drivers/power/qcom-charger/qpnp-fg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -2081,7 +2081,7 @@ static void update_sram_data_work(struct work_struct *work)
struct fg_chip *chip = container_of(work,
struct fg_chip,
update_sram_data.work);
- int resched_ms, ret;
+ int resched_ms = SRAM_PERIOD_NO_ID_UPDATE_MS, ret;
bool tried_again = false;
wait:
@@ -5961,7 +5961,19 @@ static ssize_t fg_memif_dfs_reg_write(struct file *file, const char __user *buf,
values = kbuf;
/* Parse the data in the buffer. It should be a string of numbers */
- while (sscanf(kbuf + pos, "%i%n", &data, &bytes_read) == 1) {
+ while ((pos < count) &&
+ sscanf(kbuf + pos, "%i%n", &data, &bytes_read) == 1) {
+ /*
+ * We shouldn't be receiving a string of characters that
+ * exceeds a size of 5 to keep this functionally correct.
+ * Also, we should make sure that pos never gets overflowed
+ * beyond the limit.
+ */
+ if (bytes_read > 5 || bytes_read > INT_MAX - pos) {
+ cnt = 0;
+ ret = -EINVAL;
+ break;
+ }
pos += bytes_read;
values[cnt++] = data & 0xff;
}
diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c
index eec96d30d4f9..9728490736ff 100644
--- a/drivers/power/qcom-charger/smb-lib.c
+++ b/drivers/power/qcom-charger/smb-lib.c
@@ -2010,7 +2010,7 @@ int smblib_set_prop_pd_current_max(struct smb_charger *chg,
int smblib_set_prop_usb_current_max(struct smb_charger *chg,
const union power_supply_propval *val)
{
- int rc;
+ int rc = 0;
if (!chg->pd_active) {
rc = vote(chg->usb_icl_votable, USB_PSY_VOTER,
diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c
index cd02ed5bd46a..38e822de34a7 100644
--- a/drivers/power/reset/msm-poweroff.c
+++ b/drivers/power/reset/msm-poweroff.c
@@ -48,7 +48,7 @@
static int restart_mode;
-static void *restart_reason, *dload_type_addr;
+static void *restart_reason;
static bool scm_pmic_arbiter_disable_supported;
static bool scm_deassert_ps_hold_supported;
/* Download mode master kill-switch */
@@ -60,8 +60,6 @@ static void scm_disable_sdi(void);
* There is no API from TZ to re-enable the registers.
* So the SDI cannot be re-enabled when it already by-passed.
*/
-static int download_mode = 1;
-static struct kobject dload_kobj;
#ifdef CONFIG_QCOM_DLOAD_MODE
#define EDL_MODE_PROP "qcom,msm-imem-emergency_download_mode"
@@ -71,7 +69,9 @@ static struct kobject dload_kobj;
#endif
static int in_panic;
-static void *dload_mode_addr;
+static int download_mode = 1;
+static struct kobject dload_kobj;
+static void *dload_mode_addr, *dload_type_addr;
static bool dload_mode_enabled;
static void *emergency_dload_mode_addr;
#ifdef CONFIG_RANDOMIZE_BASE
@@ -268,9 +268,9 @@ static void halt_spmi_pmic_arbiter(void)
static void msm_restart_prepare(const char *cmd)
{
-#ifdef CONFIG_QCOM_DLOAD_MODE
bool need_warm_reset = false;
+#ifdef CONFIG_QCOM_DLOAD_MODE
/* Write download mode flags if we're panic'ing
* Write download mode flags if restart_mode says so
@@ -409,6 +409,7 @@ static void do_msm_poweroff(void)
return;
}
+#ifdef CONFIG_QCOM_DLOAD_MODE
static ssize_t attr_show(struct kobject *kobj, struct attribute *attr,
char *buf)
{
@@ -486,6 +487,7 @@ static struct attribute *reset_attrs[] = {
static struct attribute_group reset_attr_group = {
.attrs = reset_attrs,
};
+#endif
static int msm_restart_probe(struct platform_device *pdev)
{
@@ -599,11 +601,12 @@ skip_sysfs_create:
if (scm_is_call_available(SCM_SVC_PWR, SCM_IO_DEASSERT_PS_HOLD) > 0)
scm_deassert_ps_hold_supported = true;
+#ifdef CONFIG_QCOM_DLOAD_MODE
download_mode = scm_is_secure_device();
set_dload_mode(download_mode);
if (!download_mode)
scm_disable_sdi();
-
+#endif
return 0;
err_restart_reason:
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 2138e81bb9e9..d46682bb1d84 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -8904,6 +8904,35 @@ static inline void ufshcd_add_sysfs_nodes(struct ufs_hba *hba)
ufshcd_add_spm_lvl_sysfs_nodes(hba);
}
+static void ufshcd_shutdown_clkscaling(struct ufs_hba *hba)
+{
+ bool suspend = false;
+ unsigned long flags;
+
+ spin_lock_irqsave(hba->host->host_lock, flags);
+ if (hba->clk_scaling.is_allowed) {
+ hba->clk_scaling.is_allowed = false;
+ suspend = true;
+ }
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+ /**
+ * Scaling may be scheduled before, hence make sure it
+ * doesn't race with shutdown
+ */
+ if (ufshcd_is_clkscaling_supported(hba)) {
+ device_remove_file(hba->dev, &hba->clk_scaling.enable_attr);
+ cancel_work_sync(&hba->clk_scaling.suspend_work);
+ cancel_work_sync(&hba->clk_scaling.resume_work);
+ if (suspend)
+ ufshcd_suspend_clkscaling(hba);
+ }
+
+ /* Unregister so that devfreq_monitor can't race with shutdown */
+ if (hba->devfreq)
+ devfreq_remove_device(hba->devfreq);
+}
+
/**
* ufshcd_shutdown - shutdown routine
* @hba: per adapter instance
@@ -8921,16 +8950,14 @@ int ufshcd_shutdown(struct ufs_hba *hba)
pm_runtime_get_sync(hba->dev);
ufshcd_hold_all(hba);
+ ufshcd_mark_shutdown_ongoing(hba);
+ ufshcd_shutdown_clkscaling(hba);
/**
- * (1) Set state to shutting down
- * (2) Acquire the lock to stop any more requests
- * (3) Suspend clock scaling
- * (4) Wait for all issued requests to complete
+ * (1) Acquire the lock to stop any more requests
+ * (2) Wait for all issued requests to complete
*/
- ufshcd_mark_shutdown_ongoing(hba);
ufshcd_get_write_lock(hba);
ufshcd_scsi_block_requests(hba);
- ufshcd_suspend_clkscaling(hba);
ret = ufshcd_wait_for_doorbell_clr(hba, U64_MAX);
if (ret)
dev_err(hba->dev, "%s: waiting for DB clear: failed: %d\n",
@@ -9373,10 +9400,6 @@ static void ufshcd_clk_scaling_resume_work(struct work_struct *work)
clk_scaling.resume_work);
unsigned long irq_flags;
- /* Let's not resume scaling if shutdown is ongoing */
- if (ufshcd_is_shutdown_ongoing(hba))
- return;
-
spin_lock_irqsave(hba->host->host_lock, irq_flags);
if (!hba->clk_scaling.is_suspended) {
spin_unlock_irqrestore(hba->host->host_lock, irq_flags);
diff --git a/drivers/soc/qcom/glink.c b/drivers/soc/qcom/glink.c
index 65ce7d791a47..33cf48454414 100644
--- a/drivers/soc/qcom/glink.c
+++ b/drivers/soc/qcom/glink.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -582,6 +582,9 @@ static bool glink_core_remote_close_common(struct channel_ctx *ctx, bool safe)
}
ctx->rcid = 0;
+ ctx->int_req_ack = false;
+ complete_all(&ctx->int_req_ack_complete);
+ complete_all(&ctx->int_req_complete);
if (ctx->local_open_state != GLINK_CHANNEL_CLOSED &&
ctx->local_open_state != GLINK_CHANNEL_CLOSING) {
if (ctx->notify_state)
@@ -598,9 +601,6 @@ static bool glink_core_remote_close_common(struct channel_ctx *ctx, bool safe)
"Did not send GLINK_REMOTE_DISCONNECTED",
"local state is already CLOSED");
- ctx->int_req_ack = false;
- complete_all(&ctx->int_req_ack_complete);
- complete_all(&ctx->int_req_complete);
ch_purge_intent_lists(ctx);
return is_fully_closed;
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index 2b097d8ab090..44d086656a12 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -51,12 +51,12 @@
#include "wlan_firmware_service_v01.h"
#ifdef CONFIG_ICNSS_DEBUG
-unsigned long qmi_timeout = 3000;
+unsigned long qmi_timeout = 10000;
module_param(qmi_timeout, ulong, 0600);
#define WLFW_TIMEOUT_MS qmi_timeout
#else
-#define WLFW_TIMEOUT_MS 3000
+#define WLFW_TIMEOUT_MS 10000
#endif
#define WLFW_SERVICE_INS_ID_V01 0
#define WLFW_CLIENT_ID 0x4b4e454c
diff --git a/drivers/soc/qcom/secure_buffer.c b/drivers/soc/qcom/secure_buffer.c
index 95d50fe01ee1..90c7585d480c 100644
--- a/drivers/soc/qcom/secure_buffer.c
+++ b/drivers/soc/qcom/secure_buffer.c
@@ -364,28 +364,19 @@ int hyp_assign_phys(phys_addr_t addr, u64 size, u32 *source_vm_list,
int source_nelems, int *dest_vmids,
int *dest_perms, int dest_nelems)
{
- struct sg_table *table;
+ struct sg_table table;
int ret;
- table = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
- if (!table)
- return -ENOMEM;
- ret = sg_alloc_table(table, 1, GFP_KERNEL);
+ ret = sg_alloc_table(&table, 1, GFP_KERNEL);
if (ret)
- goto err1;
+ return ret;
- sg_set_page(table->sgl, phys_to_page(addr), size, 0);
+ sg_set_page(table.sgl, phys_to_page(addr), size, 0);
- ret = hyp_assign_table(table, source_vm_list, source_nelems, dest_vmids,
- dest_perms, dest_nelems);
- if (ret)
- goto err2;
+ ret = hyp_assign_table(&table, source_vm_list, source_nelems,
+ dest_vmids, dest_perms, dest_nelems);
- return ret;
-err2:
- sg_free_table(table);
-err1:
- kfree(table);
+ sg_free_table(&table);
return ret;
}
diff --git a/drivers/soc/qcom/service-notifier.c b/drivers/soc/qcom/service-notifier.c
index 84a2aeee8cf7..e7307c46a895 100644
--- a/drivers/soc/qcom/service-notifier.c
+++ b/drivers/soc/qcom/service-notifier.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -336,11 +336,13 @@ static void root_service_service_arrive(struct work_struct *work)
int rc;
int curr_state;
+ mutex_lock(&qmi_client_release_lock);
/* Create a Local client port for QMI communication */
data->clnt_handle = qmi_handle_create(root_service_clnt_notify, work);
if (!data->clnt_handle) {
pr_err("QMI client handle alloc failed (instance-id: %d)\n",
data->instance_id);
+ mutex_unlock(&qmi_client_release_lock);
return;
}
@@ -353,9 +355,11 @@ static void root_service_service_arrive(struct work_struct *work)
data->instance_id, rc);
qmi_handle_destroy(data->clnt_handle);
data->clnt_handle = NULL;
+ mutex_unlock(&qmi_client_release_lock);
return;
}
data->service_connected = true;
+ mutex_unlock(&qmi_client_release_lock);
pr_info("Connection established between QMI handle and %d service\n",
data->instance_id);
/* Register for indication messages about service */
diff --git a/drivers/soc/qcom/spss_utils.c b/drivers/soc/qcom/spss_utils.c
index c93a9a5c8a1c..e17a1370d1f0 100644
--- a/drivers/soc/qcom/spss_utils.c
+++ b/drivers/soc/qcom/spss_utils.c
@@ -1,5 +1,5 @@
/*
- * 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
@@ -18,7 +18,7 @@
*
* The SP daemon needs to load different SPSS images based on:
*
- * 1. Test/Production key used to sign the SPSS image (read fuse).
+ * 1. Test/Production key used to sign the SPSS image (read fuses).
* 2. SPSS HW version (selected via Device Tree).
*
*/
@@ -43,10 +43,17 @@
/* driver name */
#define DEVICE_NAME "spss-utils"
-static bool is_test_fuse_set;
+enum spss_firmware_type {
+ SPSS_FW_TYPE_TEST = 't',
+ SPSS_FW_TYPE_PROD = 'p',
+ SPSS_FW_TYPE_HYBRID = 'h',
+};
+
+static enum spss_firmware_type firmware_type = SPSS_FW_TYPE_TEST;
static const char *test_firmware_name;
static const char *prod_firmware_name;
-static const char *firmware_name;
+static const char *hybr_firmware_name;
+static const char *firmware_name = "NA";
static struct device *spss_dev;
static u32 spss_debug_reg_addr; /* SP_SCSR_MBn_SP2CL_GPm(n,m) */
@@ -97,10 +104,19 @@ static ssize_t test_fuse_state_show(struct device *dev,
return -EINVAL;
}
- if (is_test_fuse_set)
+ switch (firmware_type) {
+ case SPSS_FW_TYPE_TEST:
ret = snprintf(buf, PAGE_SIZE, "%s", "test");
- else
+ break;
+ case SPSS_FW_TYPE_PROD:
ret = snprintf(buf, PAGE_SIZE, "%s", "prod");
+ break;
+ case SPSS_FW_TYPE_HYBRID:
+ ret = snprintf(buf, PAGE_SIZE, "%s", "hybrid");
+ break;
+ default:
+ return -EINVAL;
+ }
return ret;
}
@@ -198,11 +214,16 @@ static int spss_create_sysfs(struct device *dev)
static int spss_parse_dt(struct device_node *node)
{
int ret;
- u32 spss_fuse_addr = 0;
- u32 spss_fuse_bit = 0;
- u32 spss_fuse_mask = 0;
- void __iomem *spss_fuse_reg = NULL;
- u32 val = 0;
+ u32 spss_fuse1_addr = 0;
+ u32 spss_fuse1_bit = 0;
+ u32 spss_fuse1_mask = 0;
+ void __iomem *spss_fuse1_reg = NULL;
+ u32 spss_fuse2_addr = 0;
+ u32 spss_fuse2_bit = 0;
+ u32 spss_fuse2_mask = 0;
+ void __iomem *spss_fuse2_reg = NULL;
+ u32 val1 = 0;
+ u32 val2 = 0;
ret = of_property_read_string(node, "qcom,spss-test-firmware-name",
&test_firmware_name);
@@ -218,40 +239,80 @@ static int spss_parse_dt(struct device_node *node)
return -EFAULT;
}
- ret = of_property_read_u32(node, "qcom,spss-fuse-addr",
- &spss_fuse_addr);
+ ret = of_property_read_string(node, "qcom,spss-hybr-firmware-name",
+ &hybr_firmware_name);
+ if (ret < 0) {
+ pr_err("can't get prod fw name.\n");
+ return -EFAULT;
+ }
+
+ ret = of_property_read_u32(node, "qcom,spss-fuse1-addr",
+ &spss_fuse1_addr);
+ if (ret < 0) {
+ pr_err("can't get fuse1 addr.\n");
+ return -EFAULT;
+ }
+
+ ret = of_property_read_u32(node, "qcom,spss-fuse2-addr",
+ &spss_fuse2_addr);
if (ret < 0) {
- pr_err("can't get fuse addr.\n");
+ pr_err("can't get fuse2 addr.\n");
return -EFAULT;
}
- ret = of_property_read_u32(node, "qcom,spss-fuse-bit",
- &spss_fuse_bit);
+ ret = of_property_read_u32(node, "qcom,spss-fuse1-bit",
+ &spss_fuse1_bit);
if (ret < 0) {
- pr_err("can't get fuse bit.\n");
+ pr_err("can't get fuse1 bit.\n");
return -EFAULT;
}
- spss_fuse_mask = BIT(spss_fuse_bit);
+ ret = of_property_read_u32(node, "qcom,spss-fuse2-bit",
+ &spss_fuse2_bit);
+ if (ret < 0) {
+ pr_err("can't get fuse2 bit.\n");
+ return -EFAULT;
+ }
- pr_debug("spss_fuse_addr [0x%x] , spss_fuse_bit [%d] .\n",
- (int) spss_fuse_addr, (int) spss_fuse_bit);
- spss_fuse_reg = ioremap_nocache(spss_fuse_addr, sizeof(u32));
+ spss_fuse1_mask = BIT(spss_fuse1_bit);
+ spss_fuse2_mask = BIT(spss_fuse2_bit);
- if (!spss_fuse_reg) {
- pr_err("can't map fuse addr.\n");
+ pr_debug("spss fuse1 addr [0x%x] bit [%d] .\n",
+ (int) spss_fuse1_addr, (int) spss_fuse1_bit);
+ pr_debug("spss fuse2 addr [0x%x] bit [%d] .\n",
+ (int) spss_fuse2_addr, (int) spss_fuse2_bit);
+
+ spss_fuse1_reg = ioremap_nocache(spss_fuse1_addr, sizeof(u32));
+ spss_fuse2_reg = ioremap_nocache(spss_fuse2_addr, sizeof(u32));
+
+ if (!spss_fuse1_reg) {
+ pr_err("can't map fuse1 addr.\n");
return -EFAULT;
}
+ if (!spss_fuse2_reg) {
+ pr_err("can't map fuse2 addr.\n");
+ return -EFAULT;
+ }
+
+ val1 = readl_relaxed(spss_fuse1_reg);
+ val2 = readl_relaxed(spss_fuse2_reg);
- val = readl_relaxed(spss_fuse_reg);
+ pr_debug("spss fuse1 value [0x%08x].\n", (int) val1);
+ pr_debug("spss fuse2 value [0x%08x].\n", (int) val2);
- pr_debug("spss fuse register value [0x%x].\n", (int) val);
+ pr_debug("spss fuse1 mask [0x%08x].\n", (int) spss_fuse1_mask);
+ pr_debug("spss fuse2 mask [0x%08x].\n", (int) spss_fuse2_mask);
- if (val & spss_fuse_mask)
- is_test_fuse_set = true;
+ if (val1 & spss_fuse1_mask)
+ firmware_type = SPSS_FW_TYPE_TEST;
+ else if (val2 & spss_fuse2_mask)
+ firmware_type = SPSS_FW_TYPE_PROD;
+ else
+ firmware_type = SPSS_FW_TYPE_HYBRID;
- iounmap(spss_fuse_reg);
+ iounmap(spss_fuse1_reg);
+ iounmap(spss_fuse2_reg);
ret = of_property_read_u32(node, "qcom,spss-debug-reg-addr",
&spss_debug_reg_addr);
@@ -299,10 +360,19 @@ static int spss_probe(struct platform_device *pdev)
return -EFAULT;
}
- if (is_test_fuse_set)
+ switch (firmware_type) {
+ case SPSS_FW_TYPE_TEST:
firmware_name = test_firmware_name;
- else
+ break;
+ case SPSS_FW_TYPE_PROD:
firmware_name = prod_firmware_name;
+ break;
+ case SPSS_FW_TYPE_HYBRID:
+ firmware_name = hybr_firmware_name;
+ break;
+ default:
+ return -EINVAL;
+ }
ret = subsystem_set_fwname("spss", firmware_name);
if (ret < 0) {
@@ -339,7 +409,7 @@ static int __init spss_init(void)
{
int ret = 0;
- pr_info("spss-utils driver Ver 1.1 18-Sep-2016.\n");
+ pr_info("spss-utils driver Ver 1.2 13-Jan-2017.\n");
ret = platform_driver_register(&spss_driver);
if (ret)
diff --git a/drivers/soc/qcom/subsys-pil-tz.c b/drivers/soc/qcom/subsys-pil-tz.c
index 769a683e3d8d..c6531de48f65 100644
--- a/drivers/soc/qcom/subsys-pil-tz.c
+++ b/drivers/soc/qcom/subsys-pil-tz.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1043,7 +1043,7 @@ static int pil_tz_driver_probe(struct platform_device *pdev)
if (!d->subsys_desc.no_auth) {
rc = piltz_resc_init(pdev, d);
if (rc)
- return -ENOENT;
+ return rc;
rc = of_property_read_u32(pdev->dev.of_node, "qcom,pas-id",
&d->pas_id);
diff --git a/drivers/soc/qcom/subsystem_restart.c b/drivers/soc/qcom/subsystem_restart.c
index 77362912321d..c35ec26fefa2 100644
--- a/drivers/soc/qcom/subsystem_restart.c
+++ b/drivers/soc/qcom/subsystem_restart.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
@@ -1063,8 +1063,9 @@ int subsystem_restart_dev(struct subsys_device *dev)
pr_info("Restart sequence requested for %s, restart_level = %s.\n",
name, restart_levels[dev->restart_level]);
- if (WARN(disable_restart_work == DISABLE_SSR,
- "subsys-restart: Ignoring restart request for %s.\n", name)) {
+ if (disable_restart_work == DISABLE_SSR) {
+ pr_warn("subsys-restart: Ignoring restart request for %s.\n",
+ name);
return 0;
}
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index e0af922a0329..81bda878a7ec 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -503,9 +503,9 @@ static int ion_handle_add(struct ion_client *client, struct ion_handle *handle)
return 0;
}
-struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
+static struct ion_handle *__ion_alloc(struct ion_client *client, size_t len,
size_t align, unsigned int heap_id_mask,
- unsigned int flags)
+ unsigned int flags, bool grab_handle)
{
struct ion_handle *handle;
struct ion_device *dev = client->dev;
@@ -600,6 +600,8 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
return handle;
mutex_lock(&client->lock);
+ if (grab_handle)
+ ion_handle_get(handle);
ret = ion_handle_add(client, handle);
mutex_unlock(&client->lock);
if (ret) {
@@ -609,6 +611,13 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
return handle;
}
+
+struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
+ size_t align, unsigned int heap_id_mask,
+ unsigned int flags)
+{
+ return __ion_alloc(client, len, align, heap_id_mask, flags, false);
+}
EXPORT_SYMBOL(ion_alloc);
static void ion_free_nolock(struct ion_client *client, struct ion_handle *handle)
@@ -1493,10 +1502,10 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct ion_handle *handle;
- handle = ion_alloc(client, data.allocation.len,
+ handle = __ion_alloc(client, data.allocation.len,
data.allocation.align,
data.allocation.heap_id_mask,
- data.allocation.flags);
+ data.allocation.flags, true);
if (IS_ERR(handle))
return PTR_ERR(handle);
@@ -1573,11 +1582,15 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
if (dir & _IOC_READ) {
if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) {
- if (cleanup_handle)
+ if (cleanup_handle) {
ion_free(client, cleanup_handle);
+ ion_handle_put(cleanup_handle);
+ }
return -EFAULT;
}
}
+ if (cleanup_handle)
+ ion_handle_put(cleanup_handle);
return ret;
}
diff --git a/drivers/thermal/msm_lmh_dcvs.c b/drivers/thermal/msm_lmh_dcvs.c
index ac1da854ab32..7758750516f8 100644
--- a/drivers/thermal/msm_lmh_dcvs.c
+++ b/drivers/thermal/msm_lmh_dcvs.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
@@ -48,6 +48,7 @@
#define MSM_LIMITS_ALGO_MODE_ENABLE 0x454E424C
#define MSM_LIMITS_HI_THRESHOLD 0x48494748
+#define MSM_LIMITS_LOW_THRESHOLD 0x4C4F5700
#define MSM_LIMITS_ARM_THRESHOLD 0x41524D00
#define MSM_LIMITS_CLUSTER_0 0x6370302D
@@ -57,6 +58,7 @@
#define MSM_LIMITS_HIGH_THRESHOLD_VAL 95000
#define MSM_LIMITS_ARM_THRESHOLD_VAL 65000
+#define MSM_LIMITS_LOW_THRESHOLD_OFFSET 500
#define MSM_LIMITS_POLLING_DELAY_MS 10
#define MSM_LIMITS_CLUSTER_0_REQ 0x179C1B04
#define MSM_LIMITS_CLUSTER_1_REQ 0x179C3B04
@@ -227,7 +229,8 @@ static int lmh_activate_trip(struct thermal_zone_device *dev,
int trip, enum thermal_trip_activation_mode mode)
{
struct msm_lmh_dcvs_hw *hw = dev->devdata;
- uint32_t enable, temp, thresh;
+ uint32_t enable, temp;
+ int ret = 0;
enable = (mode == THERMAL_TRIP_ACTIVATION_ENABLED) ? 1 : 0;
if (!enable) {
@@ -240,12 +243,35 @@ static int lmh_activate_trip(struct thermal_zone_device *dev,
hw->temp_limits[LIMITS_TRIP_HI])
return -EINVAL;
- thresh = (trip == LIMITS_TRIP_LO) ? MSM_LIMITS_ARM_THRESHOLD :
- MSM_LIMITS_HI_THRESHOLD;
temp = hw->temp_limits[trip];
+ switch (trip) {
+ case LIMITS_TRIP_LO:
+ ret = msm_lmh_dcvs_write(hw->affinity,
+ MSM_LIMITS_SUB_FN_THERMAL,
+ MSM_LIMITS_ARM_THRESHOLD, temp);
+ break;
+ case LIMITS_TRIP_HI:
+ /*
+ * The high threshold should be atleast greater than the
+ * low threshold offset
+ */
+ if (temp < MSM_LIMITS_LOW_THRESHOLD_OFFSET)
+ return -EINVAL;
+ ret = msm_lmh_dcvs_write(hw->affinity,
+ MSM_LIMITS_SUB_FN_THERMAL,
+ MSM_LIMITS_HI_THRESHOLD, temp);
+ if (ret)
+ break;
+ ret = msm_lmh_dcvs_write(hw->affinity,
+ MSM_LIMITS_SUB_FN_THERMAL,
+ MSM_LIMITS_LOW_THRESHOLD, temp -
+ MSM_LIMITS_LOW_THRESHOLD_OFFSET);
+ break;
+ default:
+ return -EINVAL;
+ }
- return msm_lmh_dcvs_write(hw->affinity, MSM_LIMITS_SUB_FN_THERMAL,
- thresh, temp);
+ return ret;
}
static int lmh_get_trip_temp(struct thermal_zone_device *dev,
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 5c451f8a6827..bc0e0184a917 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -2574,7 +2574,7 @@ static int dwc3_msm_id_notifier(struct notifier_block *nb,
dbg_event(0xFF, "cc_state", mdwc->typec_orientation);
speed = extcon_get_cable_state_(edev, EXTCON_USB_SPEED);
- dwc->maximum_speed = (speed == 0) ? USB_SPEED_HIGH : USB_SPEED_SUPER;
+ dwc->maximum_speed = (speed <= 0) ? USB_SPEED_HIGH : USB_SPEED_SUPER;
if (mdwc->id_state != id) {
mdwc->id_state = id;
@@ -2615,7 +2615,7 @@ static int dwc3_msm_vbus_notifier(struct notifier_block *nb,
dbg_event(0xFF, "cc_state", mdwc->typec_orientation);
speed = extcon_get_cable_state_(edev, EXTCON_USB_SPEED);
- dwc->maximum_speed = (speed == 0) ? USB_SPEED_HIGH : USB_SPEED_SUPER;
+ dwc->maximum_speed = (speed <= 0) ? USB_SPEED_HIGH : USB_SPEED_SUPER;
mdwc->vbus_active = event;
if (dwc->is_drd && !mdwc->in_restart) {
diff --git a/drivers/usb/phy/phy-msm-qusb.c b/drivers/usb/phy/phy-msm-qusb.c
index 09a61acceb81..170cbf0a853f 100644
--- a/drivers/usb/phy/phy-msm-qusb.c
+++ b/drivers/usb/phy/phy-msm-qusb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -47,6 +47,8 @@
#define FREEZIO_N BIT(1)
#define POWER_DOWN BIT(0)
+#define QUSB2PHY_PORT_TEST_CTRL 0xB8
+
#define QUSB2PHY_PWR_CTRL1 0x210
#define PWR_CTRL1_CLAMP_N_EN BIT(1)
#define PWR_CTRL1_POWR_DOWN BIT(0)
@@ -688,6 +690,21 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend)
writel_relaxed(intr_mask,
qphy->base + QUSB2PHY_PORT_INTR_CTRL);
+ /* enable phy auto-resume */
+ writel_relaxed(0x0C,
+ qphy->base + QUSB2PHY_PORT_TEST_CTRL);
+ /* flush the previous write before next write */
+ wmb();
+ writel_relaxed(0x04,
+ qphy->base + QUSB2PHY_PORT_TEST_CTRL);
+
+
+ dev_dbg(phy->dev, "%s: intr_mask = %x\n",
+ __func__, intr_mask);
+
+ /* Makes sure that above write goes through */
+ wmb();
+
qusb_phy_enable_clocks(qphy, false);
} else { /* Disconnect case */
/* Disable all interrupts */
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
index 6311352cb0cf..6870193166f2 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -2461,7 +2461,8 @@ static u32 __get_ts_count(struct mdss_mdp_pipe *pipe,
if (pipe &&
pipe->multirect.mode == MDSS_MDP_PIPE_MULTIRECT_SERIAL) {
__get_ordered_rects(pipe, &low_pipe, &high_pipe);
- ts_ypos = high_pipe->dst.y - low_pipe->dst.y - 1;
+ ts_ypos = high_pipe->dst.y -
+ (low_pipe->dst.y + low_pipe->dst.h) - 1;
rate_factor = TS_CLK / fps;
ts_count = mult_frac(ts_ypos, rate_factor, v_total);
MDSS_XLOG(ts_ypos, rate_factor, ts_count);
@@ -2535,7 +2536,7 @@ static u32 __get_ts_bytes(struct mdss_mdp_pipe *pipe,
/* calculate ts bytes as the sum of both rects */
ts_bytes_low = __calc_ts_bytes(&low_pipe->src, fps,
low_pipe->src_fmt->bpp);
- ts_bytes_high = __calc_ts_bytes(&low_pipe->src, fps,
+ ts_bytes_high = __calc_ts_bytes(&high_pipe->src, fps,
high_pipe->src_fmt->bpp);
ts_bytes = ts_bytes_low + ts_bytes_high;
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 760bc4d5a2cf..2dc3abfd61be 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1014,6 +1014,14 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
* @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC
* is stored in the @ampdu_delimiter_crc field)
* @RX_FLAG_LDPC: LDPC was used
+ * @RX_FLAG_ONLY_MONITOR: Report frame only to monitor interfaces without
+ * processing it in any regular way.
+ * This is useful if drivers offload some frames but still want to report
+ * them for sniffing purposes.
+ * @RX_FLAG_SKIP_MONITOR: Process and report frame to all interfaces except
+ * monitor interfaces.
+ * This is useful if drivers offload some frames but still want to report
+ * them for sniffing purposes.
* @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3
* @RX_FLAG_10MHZ: 10 MHz (half channel) was used
* @RX_FLAG_5MHZ: 5 MHz (quarter channel) was used
@@ -1054,6 +1062,8 @@ enum mac80211_rx_flags {
RX_FLAG_MACTIME_END = BIT(21),
RX_FLAG_VHT = BIT(22),
RX_FLAG_LDPC = BIT(23),
+ RX_FLAG_ONLY_MONITOR = BIT(24),
+ RX_FLAG_SKIP_MONITOR = BIT(25),
RX_FLAG_STBC_MASK = BIT(26) | BIT(27),
RX_FLAG_10MHZ = BIT(28),
RX_FLAG_5MHZ = BIT(29),
@@ -1072,6 +1082,7 @@ enum mac80211_rx_flags {
* @RX_VHT_FLAG_160MHZ: 160 MHz was used
* @RX_VHT_FLAG_BF: packet was beamformed
*/
+
enum mac80211_rx_vht_flags {
RX_VHT_FLAG_80MHZ = BIT(0),
RX_VHT_FLAG_160MHZ = BIT(1),
@@ -5467,4 +5478,19 @@ void ieee80211_unreserve_tid(struct ieee80211_sta *sta, u8 tid);
*/
struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
struct ieee80211_txq *txq);
+
+/**
+ * ieee80211_txq_get_depth - get pending frame/byte count of given txq
+ *
+ * The values are not guaranteed to be coherent with regard to each other, i.e.
+ * txq state can change half-way of this function and the caller may end up
+ * with "new" frame_cnt and "old" byte_cnt or vice-versa.
+ *
+ * @txq: pointer obtained from station or virtual interface
+ * @frame_cnt: pointer to store frame count
+ * @byte_cnt: pointer to store byte count
+ */
+void ieee80211_txq_get_depth(struct ieee80211_txq *txq,
+ unsigned long *frame_cnt,
+ unsigned long *byte_cnt);
#endif /* MAC80211_H */
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 00beacd233fd..424961e5bd80 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -1489,10 +1489,17 @@ static void perf_group_detach(struct perf_event *event)
* If this was a group event with sibling events then
* upgrade the siblings to singleton events by adding them
* to whatever list we are on.
+ * If this isn't on a list, make sure we still remove the sibling's
+ * group_entry from this sibling_list; otherwise, when that sibling
+ * is later deallocated, it will try to remove itself from this
+ * sibling_list, which may well have been deallocated already,
+ * resulting in a use-after-free.
*/
list_for_each_entry_safe(sibling, tmp, &event->sibling_list, group_entry) {
if (list)
list_move_tail(&sibling->group_entry, list);
+ else
+ list_del_init(&sibling->group_entry);
sibling->group_leader = sibling;
/* Inherit group flags from the previous leader */
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index b70a76058b00..76cbd55e99ac 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5859,7 +5859,7 @@ int sched_isolate_cpu(int cpu)
struct rq *rq = cpu_rq(cpu);
cpumask_t avail_cpus;
int ret_code = 0;
- u64 start_time;
+ u64 start_time = 0;
if (trace_sched_isolate_enabled())
start_time = sched_clock();
@@ -5929,7 +5929,7 @@ int sched_unisolate_cpu_unlocked(int cpu)
{
int ret_code = 0;
struct rq *rq = cpu_rq(cpu);
- u64 start_time;
+ u64 start_time = 0;
if (trace_sched_isolate_enabled())
start_time = sched_clock();
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index e1c8ec0458b3..c52655581c4c 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -3634,15 +3634,8 @@ static inline void inc_cfs_rq_hmp_stats(struct cfs_rq *cfs_rq,
static inline void dec_cfs_rq_hmp_stats(struct cfs_rq *cfs_rq,
struct task_struct *p, int change_cra) { }
-static inline void inc_throttled_cfs_rq_hmp_stats(struct hmp_sched_stats *stats,
- struct cfs_rq *cfs_rq)
-{
-}
-
-static inline void dec_throttled_cfs_rq_hmp_stats(struct hmp_sched_stats *stats,
- struct cfs_rq *cfs_rq)
-{
-}
+#define dec_throttled_cfs_rq_hmp_stats(...)
+#define inc_throttled_cfs_rq_hmp_stats(...)
#endif /* CONFIG_SCHED_HMP */
@@ -4670,6 +4663,7 @@ static inline int cfs_rq_throttled(struct cfs_rq *cfs_rq)
return cfs_bandwidth_used() && cfs_rq->throttled;
}
+#ifdef CONFIG_SCHED_HMP
/*
* Check if task is part of a hierarchy where some cfs_rq does not have any
* runtime left.
@@ -4696,6 +4690,7 @@ static int task_will_be_throttled(struct task_struct *p)
return 0;
}
+#endif
/* check whether cfs_rq, or any parent, is throttled */
static inline int throttled_hierarchy(struct cfs_rq *cfs_rq)
@@ -4776,9 +4771,7 @@ static void throttle_cfs_rq(struct cfs_rq *cfs_rq)
if (dequeue)
dequeue_entity(qcfs_rq, se, DEQUEUE_SLEEP);
qcfs_rq->h_nr_running -= task_delta;
-#ifdef CONFIG_SCHED_HMP
dec_throttled_cfs_rq_hmp_stats(&qcfs_rq->hmp_stats, cfs_rq);
-#endif
if (qcfs_rq->load.weight)
dequeue = 0;
@@ -4786,9 +4779,7 @@ static void throttle_cfs_rq(struct cfs_rq *cfs_rq)
if (!se) {
sub_nr_running(rq, task_delta);
-#ifdef CONFIG_SCHED_HMP
dec_throttled_cfs_rq_hmp_stats(&rq->hmp_stats, cfs_rq);
-#endif
}
cfs_rq->throttled = 1;
@@ -4825,7 +4816,7 @@ void unthrottle_cfs_rq(struct cfs_rq *cfs_rq)
struct sched_entity *se;
int enqueue = 1;
long task_delta;
- struct cfs_rq *tcfs_rq = cfs_rq;
+ struct cfs_rq *tcfs_rq __maybe_unused = cfs_rq;
se = cfs_rq->tg->se[cpu_of(rq)];
@@ -4853,9 +4844,7 @@ void unthrottle_cfs_rq(struct cfs_rq *cfs_rq)
if (enqueue)
enqueue_entity(cfs_rq, se, ENQUEUE_WAKEUP);
cfs_rq->h_nr_running += task_delta;
-#ifdef CONFIG_SCHED_HMP
inc_throttled_cfs_rq_hmp_stats(&cfs_rq->hmp_stats, tcfs_rq);
-#endif
if (cfs_rq_throttled(cfs_rq))
break;
@@ -4863,9 +4852,7 @@ void unthrottle_cfs_rq(struct cfs_rq *cfs_rq)
if (!se) {
add_nr_running(rq, task_delta);
-#ifdef CONFIG_SCHED_HMP
inc_throttled_cfs_rq_hmp_stats(&rq->hmp_stats, tcfs_rq);
-#endif
}
/* determine whether we need to wake up potentially idle cpu */
diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c
index 15b8f2c80e06..443f16732414 100644
--- a/kernel/sched/hmp.c
+++ b/kernel/sched/hmp.c
@@ -2309,7 +2309,7 @@ static void update_cpu_busy_time(struct task_struct *p, struct rq *rq,
bool new_task;
struct related_thread_group *grp;
int cpu = rq->cpu;
- u32 old_curr_window;
+ u32 old_curr_window = p->ravg.curr_window;
new_window = mark_start < window_start;
if (new_window) {
@@ -2370,8 +2370,6 @@ static void update_cpu_busy_time(struct task_struct *p, struct rq *rq,
* task or exiting tasks.
*/
if (!is_idle_task(p) && !exiting_task(p)) {
- old_curr_window = p->ravg.curr_window;
-
if (new_window)
rollover_task_window(p, full_window);
}
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index c110c4aaf2be..a9d98b7dd10e 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1055,6 +1055,12 @@ static inline void sched_ttwu_pending(void) { }
#include "stats.h"
#include "auto_group.h"
+enum sched_boost_policy {
+ SCHED_BOOST_NONE,
+ SCHED_BOOST_ON_BIG,
+ SCHED_BOOST_ON_ALL,
+};
+
#ifdef CONFIG_SCHED_HMP
#define WINDOW_STATS_RECENT 0
@@ -1139,12 +1145,6 @@ extern unsigned int update_freq_aggregate_threshold(unsigned int threshold);
extern void update_avg_burst(struct task_struct *p);
extern void update_avg(u64 *avg, u64 sample);
-enum sched_boost_policy {
- SCHED_BOOST_NONE,
- SCHED_BOOST_ON_BIG,
- SCHED_BOOST_ON_ALL,
-};
-
#define NO_BOOST 0
#define FULL_THROTTLE_BOOST 1
#define CONSERVATIVE_BOOST 2
@@ -1496,6 +1496,16 @@ struct hmp_sched_stats;
struct related_thread_group;
struct sched_cluster;
+static inline enum sched_boost_policy sched_boost_policy(void)
+{
+ return SCHED_BOOST_NONE;
+}
+
+static inline bool task_sched_boost(struct task_struct *p)
+{
+ return true;
+}
+
static inline int got_boost_kick(void)
{
return 0;
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 316b316c7528..c0ab232e3abd 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -49,6 +49,7 @@
#include <linux/moduleparam.h>
#include <linux/uaccess.h>
#include <linux/bug.h>
+#include <linux/delay.h>
#include "workqueue_internal.h"
@@ -1285,6 +1286,12 @@ fail:
if (work_is_canceling(work))
return -ENOENT;
cpu_relax();
+ /*
+ * The queueing is in progress in another context. If we keep
+ * taking the pool->lock in a busy loop, the other context may
+ * never get the lock. Give 1 usec delay to avoid this contention.
+ */
+ udelay(1);
return -EAGAIN;
}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 6837a46ca4a2..67fede656ea5 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -808,6 +808,7 @@ enum txq_info_flags {
struct txq_info {
struct sk_buff_head queue;
unsigned long flags;
+ unsigned long byte_cnt;
/* keep last! */
struct ieee80211_txq txq;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index bcb0a1b64556..7fc1250c8d37 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -979,6 +979,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
spin_lock_bh(&txqi->queue.lock);
ieee80211_purge_tx_queue(&local->hw, &txqi->queue);
+ txqi->byte_cnt = 0;
spin_unlock_bh(&txqi->queue.lock);
atomic_set(&sdata->txqs_len[txqi->txq.ac], 0);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index a3bb8f7f5fc5..5e2adf622b1e 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -122,7 +122,8 @@ static inline bool should_drop_frame(struct sk_buff *skb, int present_fcs_len,
hdr = (void *)(skb->data + rtap_vendor_space);
if (status->flag & (RX_FLAG_FAILED_FCS_CRC |
- RX_FLAG_FAILED_PLCP_CRC))
+ RX_FLAG_FAILED_PLCP_CRC |
+ RX_FLAG_ONLY_MONITOR))
return true;
if (unlikely(skb->len < 16 + present_fcs_len + rtap_vendor_space))
@@ -507,7 +508,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
return NULL;
}
- if (!local->monitors) {
+ if (!local->monitors || (status->flag & RX_FLAG_SKIP_MONITOR)) {
if (should_drop_frame(origskb, present_fcs_len,
rtap_vendor_space)) {
dev_kfree_skb(origskb);
@@ -2203,16 +2204,22 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
if (!(status->rx_flags & IEEE80211_RX_AMSDU))
return RX_CONTINUE;
- if (ieee80211_has_a4(hdr->frame_control) &&
- rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
- !rx->sdata->u.vlan.sta)
- return RX_DROP_UNUSABLE;
+ if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
+ switch (rx->sdata->vif.type) {
+ case NL80211_IFTYPE_AP_VLAN:
+ if (!rx->sdata->u.vlan.sta)
+ return RX_DROP_UNUSABLE;
+ break;
+ case NL80211_IFTYPE_STATION:
+ if (!rx->sdata->u.mgd.use_4addr)
+ return RX_DROP_UNUSABLE;
+ break;
+ default:
+ return RX_DROP_UNUSABLE;
+ }
+ }
- if (is_multicast_ether_addr(hdr->addr1) &&
- ((rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
- rx->sdata->u.vlan.sta) ||
- (rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
- rx->sdata->u.mgd.use_4addr)))
+ if (is_multicast_ether_addr(hdr->addr1))
return RX_DROP_UNUSABLE;
skb->dev = dev;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 67066d048e6f..fe88071d4abb 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -115,6 +115,7 @@ static void __cleanup_single_sta(struct sta_info *sta)
ieee80211_purge_tx_queue(&local->hw, &txqi->queue);
atomic_sub(n, &sdata->txqs_len[txqi->txq.ac]);
+ txqi->byte_cnt = 0;
}
}
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e1225b395415..2022f1cf38e1 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1266,7 +1266,11 @@ static void ieee80211_drv_tx(struct ieee80211_local *local,
if (atomic_read(&sdata->txqs_len[ac]) >= local->hw.txq_ac_max_pending)
netif_stop_subqueue(sdata->dev, ac);
- skb_queue_tail(&txqi->queue, skb);
+ spin_lock_bh(&txqi->queue.lock);
+ txqi->byte_cnt += skb->len;
+ __skb_queue_tail(&txqi->queue, skb);
+ spin_unlock_bh(&txqi->queue.lock);
+
drv_wake_tx_queue(local, txqi);
return;
@@ -1294,6 +1298,8 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
if (!skb)
goto out;
+ txqi->byte_cnt -= skb->len;
+
atomic_dec(&sdata->txqs_len[ac]);
if (__netif_subqueue_stopped(sdata->dev, ac))
ieee80211_propagate_queue_wake(local, sdata->vif.hw_queue[ac]);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 9ea2cc098ad1..bc799a4b7cd1 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -3340,3 +3340,17 @@ void ieee80211_init_tx_queue(struct ieee80211_sub_if_data *sdata,
txqi->txq.ac = IEEE80211_AC_BE;
}
}
+
+void ieee80211_txq_get_depth(struct ieee80211_txq *txq,
+ unsigned long *frame_cnt,
+ unsigned long *byte_cnt)
+{
+ struct txq_info *txqi = to_txq_info(txq);
+
+ if (frame_cnt)
+ *frame_cnt = txqi->queue.qlen;
+
+ if (byte_cnt)
+ *byte_cnt = txqi->byte_cnt;
+}
+EXPORT_SYMBOL(ieee80211_txq_get_depth);
diff --git a/security/keys/proc.c b/security/keys/proc.c
index f0611a6368cd..b9f531c9e4fa 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -181,7 +181,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
struct timespec now;
unsigned long timo;
key_ref_t key_ref, skey_ref;
- char xbuf[12];
+ char xbuf[16];
int rc;
struct keyring_search_context ctx = {
diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c
index 0549b235fade..51bb3387de16 100644
--- a/sound/soc/codecs/wcd-mbhc-v2.c
+++ b/sound/soc/codecs/wcd-mbhc-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1166,6 +1166,8 @@ static void wcd_correct_swch_plug(struct work_struct *work)
bool micbias1 = false;
int ret = 0;
int rc, spl_hs_count = 0;
+ int cross_conn;
+ int try = 0;
pr_debug("%s: enter\n", __func__);
@@ -1183,11 +1185,6 @@ static void wcd_correct_swch_plug(struct work_struct *work)
wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB);
- if (mbhc->current_plug == MBHC_PLUG_TYPE_GND_MIC_SWAP) {
- mbhc->current_plug = MBHC_PLUG_TYPE_NONE;
- goto correct_plug_type;
- }
-
/* Enable HW FSM */
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 1);
/*
@@ -1215,8 +1212,23 @@ static void wcd_correct_swch_plug(struct work_struct *work)
plug_type = MBHC_PLUG_TYPE_INVALID;
}
- pr_debug("%s: Valid plug found, plug type is %d\n",
+ do {
+ cross_conn = wcd_check_cross_conn(mbhc);
+ try++;
+ } while (try < GND_MIC_SWAP_THRESHOLD);
+ /*
+ * check for cross coneection 4 times.
+ * conisder the result of the fourth iteration.
+ */
+ if (cross_conn > 0) {
+ pr_debug("%s: cross con found, start polling\n",
+ __func__);
+ plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP;
+ pr_debug("%s: Plug found, plug type is %d\n",
__func__, plug_type);
+ goto correct_plug_type;
+ }
+
if ((plug_type == MBHC_PLUG_TYPE_HEADSET ||
plug_type == MBHC_PLUG_TYPE_HEADPHONE) &&
(!wcd_swch_level_remove(mbhc))) {
@@ -1234,7 +1246,8 @@ correct_plug_type:
mbhc->hs_detect_work_stop);
wcd_enable_curr_micbias(mbhc,
WCD_MBHC_EN_NONE);
- if (mbhc->micbias_enable) {
+ if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic &&
+ mbhc->micbias_enable) {
mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(
mbhc->codec, MIC_BIAS_2, false);
if (mbhc->mbhc_cb->set_micbias_value)
@@ -1259,7 +1272,8 @@ correct_plug_type:
mbhc->hs_detect_work_stop);
wcd_enable_curr_micbias(mbhc,
WCD_MBHC_EN_NONE);
- if (mbhc->micbias_enable) {
+ if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic &&
+ mbhc->micbias_enable) {
mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(
mbhc->codec, MIC_BIAS_2, false);
if (mbhc->mbhc_cb->set_micbias_value)
@@ -1456,10 +1470,7 @@ exit:
static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc)
{
struct snd_soc_codec *codec = mbhc->codec;
- enum wcd_mbhc_plug_type plug_type;
bool micbias1 = false;
- int cross_conn;
- int try = 0;
pr_debug("%s: enter\n", __func__);
WCD_MBHC_RSC_ASSERT_LOCKED(mbhc);
@@ -1480,21 +1491,6 @@ static void wcd_mbhc_detect_plug_type(struct wcd_mbhc *mbhc)
else
wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_MB);
- do {
- cross_conn = wcd_check_cross_conn(mbhc);
- try++;
- } while (try < GND_MIC_SWAP_THRESHOLD);
-
- if (cross_conn > 0) {
- pr_debug("%s: cross con found, start polling\n",
- __func__);
- plug_type = MBHC_PLUG_TYPE_GND_MIC_SWAP;
- if (!mbhc->current_plug)
- mbhc->current_plug = plug_type;
- pr_debug("%s: Plug found, plug type is %d\n",
- __func__, plug_type);
- }
-
/* Re-initialize button press completion object */
reinit_completion(&mbhc->btn_press_compl);
wcd_schedule_hs_detect_plug(mbhc, &mbhc->correct_plug_swch);
@@ -2380,6 +2376,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec,
int ret = 0;
int hph_swh = 0;
int gnd_swh = 0;
+ u32 hph_moist_config[3];
struct snd_soc_card *card = codec->component.card;
const char *hph_switch = "qcom,msm-mbhc-hphl-swh";
const char *gnd_switch = "qcom,msm-mbhc-gnd-swh";
@@ -2400,6 +2397,21 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec,
goto err;
}
+ ret = of_property_read_u32_array(card->dev->of_node,
+ "qcom,msm-mbhc-moist-cfg",
+ hph_moist_config, 3);
+ if (ret) {
+ dev_dbg(card->dev, "%s: no qcom,msm-mbhc-moist-cfg in DT\n",
+ __func__);
+ mbhc->moist_vref = V_45_MV;
+ mbhc->moist_iref = I_3P0_UA;
+ mbhc->moist_rref = R_24_KOHM;
+ } else {
+ mbhc->moist_vref = hph_moist_config[0];
+ mbhc->moist_iref = hph_moist_config[1];
+ mbhc->moist_rref = hph_moist_config[2];
+ }
+
mbhc->in_swch_irq_handler = false;
mbhc->current_plug = MBHC_PLUG_TYPE_NONE;
mbhc->is_btn_press = false;
diff --git a/sound/soc/codecs/wcd-mbhc-v2.h b/sound/soc/codecs/wcd-mbhc-v2.h
index 676ec342a30a..60473ce8dab0 100644
--- a/sound/soc/codecs/wcd-mbhc-v2.h
+++ b/sound/soc/codecs/wcd-mbhc-v2.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
@@ -393,6 +393,9 @@ struct wcd_mbhc {
bool in_swch_irq_handler;
bool hphl_swh; /*track HPHL switch NC / NO */
bool gnd_swh; /*track GND switch NC / NO */
+ u32 moist_vref;
+ u32 moist_iref;
+ u32 moist_rref;
u8 micbias1_cap_mode; /* track ext cap setting */
u8 micbias2_cap_mode; /* track ext cap setting */
bool hs_detect_work_stop;
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
index 89357f32d288..d533984558f0 100644
--- a/sound/soc/codecs/wcd9335.c
+++ b/sound/soc/codecs/wcd9335.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -2202,7 +2202,7 @@ static void tasha_mbhc_moisture_config(struct wcd_mbhc *mbhc)
{
struct snd_soc_codec *codec = mbhc->codec;
- if (TASHA_MBHC_MOISTURE_VREF == V_OFF)
+ if (mbhc->moist_vref == V_OFF)
return;
/* Donot enable moisture detection if jack type is NC */
@@ -2213,8 +2213,8 @@ static void tasha_mbhc_moisture_config(struct wcd_mbhc *mbhc)
}
snd_soc_update_bits(codec, WCD9335_MBHC_CTL_2,
- 0x0C, TASHA_MBHC_MOISTURE_VREF << 2);
- tasha_mbhc_hph_l_pull_up_control(codec, TASHA_MBHC_MOISTURE_IREF);
+ 0x0C, mbhc->moist_vref << 2);
+ tasha_mbhc_hph_l_pull_up_control(codec, mbhc->moist_iref);
}
static const struct wcd_mbhc_cb mbhc_cb = {
diff --git a/sound/soc/codecs/wcd934x/wcd934x-mbhc.c b/sound/soc/codecs/wcd934x/wcd934x-mbhc.c
index 0e0c26dc72cd..f9b588e87e87 100644
--- a/sound/soc/codecs/wcd934x/wcd934x-mbhc.c
+++ b/sound/soc/codecs/wcd934x/wcd934x-mbhc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -772,7 +772,7 @@ static void tavil_mbhc_moisture_config(struct wcd_mbhc *mbhc)
{
struct snd_soc_codec *codec = mbhc->codec;
- if (TAVIL_MBHC_MOISTURE_RREF == R_OFF)
+ if (mbhc->moist_rref == R_OFF)
return;
/* Donot enable moisture detection if jack type is NC */
@@ -783,7 +783,7 @@ static void tavil_mbhc_moisture_config(struct wcd_mbhc *mbhc)
}
snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_2,
- 0x0C, TAVIL_MBHC_MOISTURE_RREF << 2);
+ 0x0C, mbhc->moist_rref << 2);
}
static bool tavil_hph_register_recovery(struct wcd_mbhc *mbhc)
diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c
index 2441cabc07a7..39e7e087b3e3 100644
--- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c
+++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c
@@ -998,6 +998,20 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data)
copp_idx, rc);
}
}
+ /* Turn on qti modules */
+ for (j = 1; j < mod_list[0]; j++) {
+ if (!msm_ds2_dap_can_enable_module(
+ mod_list[j]) ||
+ mod_list[j] ==
+ DS2_MODULE_ID)
+ continue;
+ pr_debug("%s: param enable %d\n",
+ __func__, mod_list[j]);
+ adm_param_enable(port_id, copp_idx,
+ mod_list[j],
+ MODULE_ENABLE);
+ }
+
/* Add adm api to resend calibration on port */
rc = msm_ds2_dap_send_cal_data(i);
if (rc < 0) {
diff --git a/sound/usb/usb_audio_qmi_svc.c b/sound/usb/usb_audio_qmi_svc.c
index 039519c1d822..a495a7f6cb22 100644
--- a/sound/usb/usb_audio_qmi_svc.c
+++ b/sound/usb/usb_audio_qmi_svc.c
@@ -69,6 +69,7 @@ struct intf_info {
size_t xfer_buf_size;
phys_addr_t xfer_buf_pa;
u8 *xfer_buf;
+ u8 intf_num;
u8 pcm_card_num;
u8 pcm_dev_num;
u8 direction;
@@ -391,10 +392,9 @@ static void uaudio_iommu_unmap(enum mem_type mtype, unsigned long va,
}
static int prepare_qmi_response(struct snd_usb_substream *subs,
- struct qmi_uaudio_stream_resp_msg_v01 *resp, u32 xfer_buf_len,
- int card_num, int pcm_dev_num)
+ struct qmi_uaudio_stream_req_msg_v01 *req_msg,
+ struct qmi_uaudio_stream_resp_msg_v01 *resp, int info_idx)
{
- int ret = -ENODEV;
struct usb_interface *iface;
struct usb_host_interface *alts;
struct usb_interface_descriptor *altsd;
@@ -403,10 +403,11 @@ static int prepare_qmi_response(struct snd_usb_substream *subs,
struct uac_format_type_i_discrete_descriptor *fmt_v1;
struct uac_format_type_i_ext_descriptor *fmt_v2;
struct uac1_as_header_descriptor *as;
- int protocol;
+ int ret = -ENODEV;
+ int protocol, card_num, pcm_dev_num;
void *hdr_ptr;
u8 *xfer_buf;
- u32 len, mult, remainder;
+ u32 len, mult, remainder, xfer_buf_len;
unsigned long va, tr_data_va = 0, tr_sync_va = 0, dcba_va = 0,
xfer_buf_va = 0;
phys_addr_t xhci_pa, xfer_buf_pa;
@@ -418,13 +419,9 @@ static int prepare_qmi_response(struct snd_usb_substream *subs,
goto err;
}
- if (uadev[card_num].info &&
- uadev[card_num].info[subs->interface].in_use) {
- pr_err("%s interface# %d already in use card# %d\n", __func__,
- subs->interface, card_num);
- ret = -EBUSY;
- goto err;
- }
+ pcm_dev_num = (req_msg->usb_token & SND_PCM_DEV_NUM_MASK) >> 8;
+ card_num = (req_msg->usb_token & SND_PCM_CARD_NUM_MASK) >> 16;
+ xfer_buf_len = req_msg->xfer_buff_size;
alts = &iface->altsetting[subs->altset_idx];
altsd = get_iface_desc(alts);
@@ -655,18 +652,19 @@ skip_sync:
uadev[card_num].card_num = card_num;
/* cache intf specific info to use it for unmap and free xfer buf */
- uadev[card_num].info[subs->interface].data_xfer_ring_va = tr_data_va;
- uadev[card_num].info[subs->interface].data_xfer_ring_size = PAGE_SIZE;
- uadev[card_num].info[subs->interface].sync_xfer_ring_va = tr_sync_va;
- uadev[card_num].info[subs->interface].sync_xfer_ring_size = PAGE_SIZE;
- uadev[card_num].info[subs->interface].xfer_buf_va = xfer_buf_va;
- uadev[card_num].info[subs->interface].xfer_buf_pa = xfer_buf_pa;
- uadev[card_num].info[subs->interface].xfer_buf_size = len;
- uadev[card_num].info[subs->interface].xfer_buf = xfer_buf;
- uadev[card_num].info[subs->interface].pcm_card_num = card_num;
- uadev[card_num].info[subs->interface].pcm_dev_num = pcm_dev_num;
- uadev[card_num].info[subs->interface].direction = subs->direction;
- uadev[card_num].info[subs->interface].in_use = true;
+ uadev[card_num].info[info_idx].data_xfer_ring_va = tr_data_va;
+ uadev[card_num].info[info_idx].data_xfer_ring_size = PAGE_SIZE;
+ uadev[card_num].info[info_idx].sync_xfer_ring_va = tr_sync_va;
+ uadev[card_num].info[info_idx].sync_xfer_ring_size = PAGE_SIZE;
+ uadev[card_num].info[info_idx].xfer_buf_va = xfer_buf_va;
+ uadev[card_num].info[info_idx].xfer_buf_pa = xfer_buf_pa;
+ uadev[card_num].info[info_idx].xfer_buf_size = len;
+ uadev[card_num].info[info_idx].xfer_buf = xfer_buf;
+ uadev[card_num].info[info_idx].pcm_card_num = card_num;
+ uadev[card_num].info[info_idx].pcm_dev_num = pcm_dev_num;
+ uadev[card_num].info[info_idx].direction = subs->direction;
+ uadev[card_num].info[info_idx].intf_num = subs->interface;
+ uadev[card_num].info[info_idx].in_use = true;
set_bit(card_num, &uaudio_qdev->card_slot);
@@ -723,7 +721,7 @@ static void uaudio_dev_cleanup(struct uaudio_dev *dev)
continue;
uaudio_dev_intf_cleanup(dev->udev, &dev->info[if_idx]);
pr_debug("%s: release resources: intf# %d card# %d\n", __func__,
- if_idx, dev->card_num);
+ dev->info[if_idx].intf_num, dev->card_num);
}
/* iommu_unmap dcba iova for a usb device */
@@ -867,6 +865,28 @@ static int map_pcm_format(unsigned int fmt_received)
}
}
+static int info_idx_from_ifnum(int card_num, int intf_num, bool enable)
+{
+ int i;
+
+ /*
+ * default index 0 is used when info is allocated upon
+ * first enable audio stream req for a pcm device
+ */
+ if (enable && !uadev[card_num].info)
+ return 0;
+
+ for (i = 0; i < uadev[card_num].num_intf; i++) {
+ if (enable && !uadev[card_num].info[i].in_use)
+ return i;
+ else if (!enable &&
+ uadev[card_num].info[i].intf_num == intf_num)
+ return i;
+ }
+
+ return -EINVAL;
+}
+
static int handle_uaudio_stream_req(void *req_h, void *req)
{
struct qmi_uaudio_stream_req_msg_v01 *req_msg;
@@ -877,7 +897,7 @@ static int handle_uaudio_stream_req(void *req_h, void *req)
struct intf_info *info;
int pcm_format;
u8 pcm_card_num, pcm_dev_num, direction;
- int intf_num = -1, ret = 0;
+ int info_idx = -EINVAL, ret = 0;
req_msg = (struct qmi_uaudio_stream_req_msg_v01 *)req;
@@ -921,7 +941,8 @@ static int handle_uaudio_stream_req(void *req_h, void *req)
}
mutex_lock(&chip->dev_lock);
- intf_num = subs->interface;
+ info_idx = info_idx_from_ifnum(pcm_card_num, subs->interface,
+ req_msg->enable);
if (atomic_read(&chip->shutdown) || !subs->stream || !subs->stream->pcm
|| !subs->stream->chip) {
ret = -ENODEV;
@@ -929,6 +950,16 @@ static int handle_uaudio_stream_req(void *req_h, void *req)
goto response;
}
+ if (req_msg->enable) {
+ if (info_idx < 0) {
+ pr_err("%s interface# %d already in use card# %d\n",
+ __func__, subs->interface, pcm_card_num);
+ ret = -EBUSY;
+ mutex_unlock(&chip->dev_lock);
+ goto response;
+ }
+ }
+
subs->pcm_format = pcm_format;
subs->channels = req_msg->number_of_ch;
subs->cur_rate = req_msg->bit_rate;
@@ -937,19 +968,18 @@ static int handle_uaudio_stream_req(void *req_h, void *req)
ret = snd_usb_enable_audio_stream(subs, req_msg->enable);
if (!ret && req_msg->enable)
- ret = prepare_qmi_response(subs, &resp, req_msg->xfer_buff_size,
- pcm_card_num, pcm_dev_num);
+ ret = prepare_qmi_response(subs, req_msg, &resp, info_idx);
mutex_unlock(&chip->dev_lock);
response:
if (!req_msg->enable && ret != -EINVAL) {
- if (intf_num >= 0) {
+ if (info_idx >= 0) {
mutex_lock(&chip->dev_lock);
- info = &uadev[pcm_card_num].info[intf_num];
+ info = &uadev[pcm_card_num].info[info_idx];
uaudio_dev_intf_cleanup(uadev[pcm_card_num].udev, info);
pr_debug("%s:release resources: intf# %d card# %d\n",
- __func__, intf_num, pcm_card_num);
+ __func__, subs->interface, pcm_card_num);
mutex_unlock(&chip->dev_lock);
}
if (atomic_read(&uadev[pcm_card_num].in_use))