Merge "soc: qcom: dcc_v2: Avoid dcc_sram_writel overstep"
diff --git a/Documentation/devicetree/bindings/input/qti-haptics.txt b/Documentation/devicetree/bindings/input/qti-haptics.txt
new file mode 100644
index 0000000..2c4f4f0
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/qti-haptics.txt
@@ -0,0 +1,202 @@
+Qualcomm Technologies, Inc. Haptics driver
+
+Haptics peripheral in QTI PMICs can support different type of actuators or
+vibrators:
+  1) Eccentric Rotation Mass (ERM);
+  2) Linear Resonant Actuator (LRA).
+This binding document describes the properties for this module.
+
+Properties:
+
+- compatible
+  Usage:      required
+  Value type: <string>
+  Definition: It can be one of the following:
+		"qcom,haptics",
+		"qcom,pm660-haptics",
+		"qcom,pm8150b-haptics".
+
+- reg
+  Usage:      required
+  Value type: <u32>
+  Definition: Base address of haptics peripheral.
+
+- interrupts
+  Usage:      required
+  Value type: <prop-encoded-array>
+  Definition: Peripheral interrupt specifier.
+
+- interrupt-names
+  Usage:      required
+  Value type: <stringlist>
+  Definition: Interrupt names.  This list must match up 1-to-1 with the
+		interrupts specified in the 'interrupts' property. Following
+		interrupts are required: "hap_play_irq", "hap_sc_irq".
+
+- qcom,actuator-type
+  Usage:      optional
+  Value type: <string>
+  Definition: Specifies the type of the actuator connected on the output of
+		haptics module. Allowed values: "erm", "lra". If this is
+		not specified, then LRA type will be used by default.
+
+- qcom,vmax-mv
+  Usage:      optional
+  Value type: <u32>
+  Definition: Specifies the maximum allowed output voltage in millivolts
+		for the actuator. Value specified here will be rounded
+		off to the closest multiple of 116 mV. Allowed values:
+		0 to 3596. If this is not specified, then 1800 mV will be
+		used by default.
+
+- qcom,ilim-ma
+  Usage:      optional
+  Value type: <u32>
+  Definition: Specifies the maximum allowed output current in mA for the
+		actuator. Allowed values: 400 or 800. If this is not
+		specified, 400 mA will be used by default.
+
+- qcom,play-rate-us
+  Usage:      optional
+  Value type: <u32>
+  Definition: Specifies the period at which each sample of the 8-byte waveform
+		registers is played. For ERM, this period is flexible and it
+		can be chosen based on the desired shape of the pattern.
+		For LRA, it should be set equal to the resonance period
+		specified in the LRA actuator datasheet. Allowed values are:
+		0 to 20475. If this is not specified, 5715us play rate is used.
+
+- qcom,external-waveform-source
+  Usage:      optional
+  Value type: <string>
+  Definition: The haptics module supports to play with internal constant
+		Vmax strength or play with patterns specified in its internal
+		8-bytes waveform buffer. It can also play with the audio
+		LINE-IN signal or PWM waveform coming from LINE-IN/PWM pin.
+		This property specify the kind of the waveform resources
+		on the LINE-IN/PWM pins. Allowed values are: "audio", "pwm".
+		If this is not specified, internal signals (Vmax or buffer)
+		will be selected according to the requriement of the playing
+		waveforms.
+
+- vdd-supply
+  Usage:      optional
+  Value type: <phandle>
+  Definition: Specifies the phandle of the regulator device which supplies
+		haptics module through VDD_HAP pin. This is only needed if VDD_HAP
+		is supplied from an external boost regulator instead of VPH_PWR.
+
+Following properties are specific only when LRA actuator is used:
+
+- qcom,lra-resonance-sig-shape
+  Usage:      optional
+  Value type: <string>
+  Definition: Specifies the shape of the LRA resonance drive signal. Allowed
+		values: "sine", "square". If this is not specified, sinusoid
+		resonance driver signal is used.
+
+- qcom,lra-allow-variable-play-rate
+  Usage:      optional
+  Value type: <empty>
+  Definition: If specified, "qcom,wf-play-rate-us" for LRA defined in each
+		effect could be different with the resonance period of the
+		LRA actuator.
+
+- qcom,lra-auto-resonance-mode
+  Usage:      optional
+  Value type: <string>
+  Definition: Specifies the auto resonance technique for LRA. Allowed values are:
+		"zxd": zero crossing based discontinuous method;
+		"qwd": quarter wave drive method;
+
+Following properties could be specified in child nodes for defining vibrating
+waveforms/effects:
+
+- qcom,effect-id
+  Usage:      required
+  Value type: <u32>
+  Definition: Specifies the effect ID that the client can request to play the
+		corresponding waveform defined in this child node. The ID is
+		normaly defined and sent from userspace for certain user
+		notification event.
+
+- qcom,wf-pattern
+  Usage:      required
+  Value type: <prop-encoded-array>
+  Definition: Specifies the waveform pattern in a byte array that will be
+		played for the effect-id. The bit fields of each byte are:
+		 [7]: drive direction, 0 - forward; 1 - reverse
+		 [6]: overdrive, 0 -- 1x drive; 1 -- 2x drive
+		 [5:1]: waveform amplitude
+		 [0]: reserved.
+
+- qcom,wf-play-rate-us
+  Usage:      optional
+  Value type: <u32>
+  Definition: Specifies the play period in microseconds for each byte pattern.
+		Allowed values are: 0 to 20475. For LRA actuator, if
+		"qcom,lra-allow-variable-play-rate" is defined, it could be
+		set to other values not equal to the resonance period of the
+		LRA actuator.
+
+- qcom,wf-repeat-count
+  Usage:      optional
+  Value type: <u32>
+  Definition: Specifies the repeat times for the waveform pattern. Allowed
+		values are: 1, 2, 4, 8, 16, 32, 64, 128.
+
+- qcom,wf-s-repeat-count
+  Usage:      optional
+  Value type: <u32>
+  Definition: Specifies the repeat times for each sample defined in
+		qcom,wf-pattern. Allowed values are: 1, 2, 4, 8.
+
+- qcom,wf-brake-pattern
+  Usage:      optional
+  Value type: <prop-encoded-array>
+  Definition: Specifies the brake pattern with 4 elements used to enable the
+		internal reverse braking. Allowed values for each element are:
+			0: no brake
+			1: brake with (Vmax / 2) strength
+			2: brake with Vmax strength
+			3: brake with (2 * Vmax) strength
+		If this property is specified with an array of non-zero values,
+		then the brake pattern is applied at the end of the playing
+		waveform.
+
+- qcom,lra-auto-resonance-disable
+  Usage:      optional
+  Value type: <empty>
+  Definition: If specified, the hardware feature of LRA auto resonance detection
+		is disabled.
+
+Example:
+  qcom,haptics@c000 {
+	compatible = "qcom,haptics";
+	reg = <0xc000 0x100>;
+	interrupts = <0x3 0xc0 0x0 IRQ_TYPE_EDGE_BOTH>,
+		     <0x3 0xc0 0x1 IRQ_TYPE_EDGE_BOTH>;
+	interrupt-names = "hap-sc-irq", "hap-play-irq";
+	qcom,actuator-type = "lra";
+	qcom,vmax-mv = <1800>;
+	qcom,ilim-ma = <400>;
+	qcom,play-rate-us = <8000>;
+	qcom,lra-resonance-sig-shape = "sine";
+	qcom,lra-auto-resonance-mode = "qwd";
+	qcom,lra-allow-variable-play-rate;
+
+	wf_0 {
+		/* CLICK effect */
+		qcom,effect-id = <0>;
+		qcom,wf-play-rate-us = <6250>;
+		qcom,wf-pattern = [3e 3e 3e];
+		qcom,lra-auto-resonance-disable;
+	};
+
+	wf_5 {
+		/* HEAVY_CLICK effect */
+		qcom,effect-id = <5>;
+		qcom,wf-play-rate-us = <6250>;
+		qcom,wf-pattern = [7e 7e 7e];
+	};
+  };
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-usb.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-usb.dtsi
index 642a541..0d36f2a 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-usb.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-usb.dtsi
@@ -33,6 +33,7 @@
 		qcom,dwc-usb3-msm-tx-fifo-size = <21288>;
 		qcom,num-gsi-evt-buffs = <0x3>;
 		qcom,use-pdc-interrupts;
+		qcom,pm-qos-latency = <2 241 271>;
 
 		clocks = <&clock_gcc GCC_USB30_MASTER_CLK>,
 			 <&clock_gcc GCC_SYS_NOC_USB3_CLK>,
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-v2.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-v2.dtsi
index a49003e..eef2ffb 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-v2.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-v2.dtsi
@@ -16,3 +16,7 @@
 	compatible = "qcom,sdxpoorwills";
 	qcom,msm-id = <334 0x20000>, <335 0x20000>;
 };
+
+&emac_hw {
+	emac-core-version = <5>;
+};
diff --git a/arch/arm/configs/msm8909-perf_defconfig b/arch/arm/configs/msm8909-perf_defconfig
index b4ae846..b5474db 100644
--- a/arch/arm/configs/msm8909-perf_defconfig
+++ b/arch/arm/configs/msm8909-perf_defconfig
@@ -437,6 +437,7 @@
 CONFIG_QTI_MPM=y
 CONFIG_ANDROID=y
 CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_BINDER_IPC_32BIT=y
 CONFIG_STM=y
 CONFIG_SENSORS_SSC=y
 CONFIG_MSM_TZ_LOG=y
diff --git a/arch/arm/configs/msm8909_defconfig b/arch/arm/configs/msm8909_defconfig
index 4d1bda0..787b38e 100644
--- a/arch/arm/configs/msm8909_defconfig
+++ b/arch/arm/configs/msm8909_defconfig
@@ -479,6 +479,7 @@
 CONFIG_QTI_MPM=y
 CONFIG_ANDROID=y
 CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_BINDER_IPC_32BIT=y
 CONFIG_SENSORS_SSC=y
 CONFIG_MSM_TZ_LOG=y
 CONFIG_EXT2_FS=y
diff --git a/arch/arm/configs/sdm670-perf_defconfig b/arch/arm/configs/sdm670-perf_defconfig
index eddab29..33d53db 100644
--- a/arch/arm/configs/sdm670-perf_defconfig
+++ b/arch/arm/configs/sdm670-perf_defconfig
@@ -342,9 +342,12 @@
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_VIDEO_ADV_DEBUG=y
 CONFIG_VIDEO_FIXED_MINOR_RANGES=y
 CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_MSM_VIDC_V4L2=y
+CONFIG_MSM_VIDC_GOVERNORS=y
 CONFIG_MSM_SDE_ROTATOR=y
 CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG=y
 CONFIG_QCOM_KGSL=y
@@ -528,6 +531,7 @@
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_INFO=y
+CONFIG_FRAME_WARN=2048
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_PAGE_EXTENSION=y
 CONFIG_DETECT_HUNG_TASK=y
diff --git a/arch/arm/configs/sdm670_defconfig b/arch/arm/configs/sdm670_defconfig
index 949b279..51ca98d 100644
--- a/arch/arm/configs/sdm670_defconfig
+++ b/arch/arm/configs/sdm670_defconfig
@@ -352,9 +352,12 @@
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_VIDEO_ADV_DEBUG=y
 CONFIG_VIDEO_FIXED_MINOR_RANGES=y
 CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_MSM_VIDC_V4L2=y
+CONFIG_MSM_VIDC_GOVERNORS=y
 CONFIG_MSM_SDE_ROTATOR=y
 CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG=y
 CONFIG_QCOM_KGSL=y
@@ -552,6 +555,7 @@
 CONFIG_PRINTK_TIME=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_INFO=y
+CONFIG_FRAME_WARN=2048
 CONFIG_PAGE_OWNER=y
 CONFIG_PAGE_OWNER_ENABLE_DEFAULT=y
 CONFIG_MAGIC_SYSRQ=y
diff --git a/arch/arm/configs/sdxpoorwills-perf_defconfig b/arch/arm/configs/sdxpoorwills-perf_defconfig
index e1fed15..cdbfebd 100644
--- a/arch/arm/configs/sdxpoorwills-perf_defconfig
+++ b/arch/arm/configs/sdxpoorwills-perf_defconfig
@@ -366,6 +366,8 @@
 CONFIG_IOMMU_DEBUG=y
 CONFIG_IOMMU_DEBUG_TRACKING=y
 CONFIG_IOMMU_TESTS=y
+CONFIG_MSM_SERVICE_LOCATOR=y
+CONFIG_MSM_SERVICE_NOTIFIER=y
 CONFIG_QCOM_SCM=y
 CONFIG_MSM_BOOT_STATS=y
 CONFIG_QCOM_WATCHDOG_V2=y
diff --git a/arch/arm/configs/sdxpoorwills_defconfig b/arch/arm/configs/sdxpoorwills_defconfig
index 54072cc..b3fef2f 100644
--- a/arch/arm/configs/sdxpoorwills_defconfig
+++ b/arch/arm/configs/sdxpoorwills_defconfig
@@ -371,6 +371,8 @@
 CONFIG_IOMMU_DEBUG=y
 CONFIG_IOMMU_DEBUG_TRACKING=y
 CONFIG_IOMMU_TESTS=y
+CONFIG_MSM_SERVICE_LOCATOR=y
+CONFIG_MSM_SERVICE_NOTIFIER=y
 CONFIG_QCOM_SCM=y
 CONFIG_MSM_BOOT_STATS=y
 CONFIG_QCOM_WATCHDOG_V2=y
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 15f53ee..ef0ac4d 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -223,7 +223,7 @@
 qcs605-mtp-overlay.dtbo-base := qcs605.dtb
 qcs605-external-codec-mtp-overlay.dtbo-base := qcs605.dtb
 qcs605-lc-mtp-overlay.dtbo-base := qcs605-lc.dtb
-qcs605-lc-ipcamera-overlay.dtbo-base := qcs605-lc.dtb
+qcs605-lc-ipcamera-overlay.dtbo-base := qcs605-lc-ipcamera-base.dtb
 qcs605-360camera-overlay.dtbo-base := qcs605.dtb
 qcs605-lc-cdp-overlay.dtbo-base := qcs605-lc-cdp-base.dtb
 sdm710-cdp-overlay.dtbo-base := sdm710.dtb
@@ -499,8 +499,11 @@
 	apq8053-lite-dragon-v2.0.dtb \
 	apq8053-lite-dragon-v2.1.dtb \
 	apq8053-lite-dragon-v2.2.dtb \
+	apq8053-lite-dragon-v2.2.1.dtb \
 	apq8053-lite-dragon-v2.3.dtb \
 	apq8053-lite-dragon-v2.4.dtb \
+	apq8053-lat-concam-dev.dtb \
+	apq8053-lat-concam-proto.dtb \
 	msm8953-pmi8940-cdp.dtb \
 	msm8953-pmi8940-mtp.dtb \
 	msm8953-pmi8937-cdp.dtb \
diff --git a/arch/arm64/boot/dts/qcom/apq8053-lat-concam-audio.dtsi b/arch/arm64/boot/dts/qcom/apq8053-lat-concam-audio.dtsi
new file mode 100644
index 0000000..b0fee57
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8053-lat-concam-audio.dtsi
@@ -0,0 +1,645 @@
+/*
+ * Copyright (c) 2018, 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.
+ */
+
+/* picked up from base file msm8953-audio.dtsi, enables internal codec config */
+
+&soc {
+	&i2c_2 {
+		status = "okay";
+		wsa881x_i2c_f: wsa881x-i2c-codec@f {
+			status = "okay";
+
+			compatible = "qcom,wsa881x-i2c-codec";
+			reg = <0x0f>;
+			qcom,msm-gpios = "wsa_clk",
+					"wsa_reset",
+					"wsa_vi";
+			qcom,pinctrl-names = "all_off",
+					"wsa_clk",
+					"wsa_active",
+					"wsa_clk_active",
+					"wsa_vi",
+					"wsa_clk_vi",
+					"wsa_active_vi",
+					"wsa_all";
+			pinctrl-names = "all_off",
+					"wsa_clk",
+					"wsa_active",
+					"wsa_clk_active",
+					"wsa_vi",
+					"wsa_clk_vi",
+					"wsa_active_vi",
+					"wsa_all";
+			pinctrl-0 = <&wsa_clk_off &wsa_reset_off &wsa_vi_off>;
+			pinctrl-1 = <&wsa_clk_on &wsa_reset_off &wsa_vi_off>;
+			pinctrl-2 = <&wsa_clk_off &wsa_reset_on &wsa_vi_off>;
+			pinctrl-3 = <&wsa_clk_on &wsa_reset_on &wsa_vi_off>;
+			pinctrl-4 = <&wsa_clk_off &wsa_reset_off &wsa_vi_on>;
+			pinctrl-5 = <&wsa_clk_on &wsa_reset_off &wsa_vi_on>;
+			pinctrl-6 = <&wsa_clk_off &wsa_reset_on &wsa_vi_on>;
+			pinctrl-7 = <&wsa_clk_on &wsa_reset_on &wsa_vi_on>;
+		};
+
+		wsa881x_i2c_45: wsa881x-i2c-codec@45 {
+			status = "okay";
+
+			compatible = "qcom,wsa881x-i2c-codec";
+			reg = <0x45>;
+			qcom,msm-gpios = "wsa_clk",
+					"wsa_reset",
+					"wsa_vi";
+			qcom,pinctrl-names = "all_off",
+					"wsa_clk",
+					"wsa_active",
+					"wsa_clk_active",
+					"wsa_vi",
+					"wsa_clk_vi",
+					"wsa_active_vi",
+					"wsa_all";
+			pinctrl-names = "all_off",
+					"wsa_clk",
+					"wsa_active",
+					"wsa_clk_active",
+					"wsa_vi",
+					"wsa_clk_vi",
+					"wsa_active_vi",
+					"wsa_all";
+			pinctrl-0 = <&wsa_clk_off &wsa_reset_off &wsa_vi_off>;
+			pinctrl-1 = <&wsa_clk_on &wsa_reset_off &wsa_vi_off>;
+			pinctrl-2 = <&wsa_clk_off &wsa_reset_on &wsa_vi_off>;
+			pinctrl-3 = <&wsa_clk_on &wsa_reset_on &wsa_vi_off>;
+			pinctrl-4 = <&wsa_clk_off &wsa_reset_off &wsa_vi_on>;
+			pinctrl-5 = <&wsa_clk_on &wsa_reset_off &wsa_vi_on>;
+			pinctrl-6 = <&wsa_clk_off &wsa_reset_on &wsa_vi_on>;
+			pinctrl-7 = <&wsa_clk_on &wsa_reset_on &wsa_vi_on>;
+		};
+	};
+
+	pcm0: qcom,msm-pcm {
+		compatible = "qcom,msm-pcm-dsp";
+		qcom,msm-pcm-dsp-id = <0>;
+	};
+
+	routing: qcom,msm-pcm-routing {
+		compatible = "qcom,msm-pcm-routing";
+	};
+
+	pcm2: qcom,msm-ultra-low-latency {
+		compatible = "qcom,msm-pcm-dsp";
+		qcom,msm-pcm-dsp-id = <2>;
+		qcom,msm-pcm-low-latency;
+		qcom,latency-level = "ultra";
+	};
+
+	pcm1: qcom,msm-pcm-low-latency {
+		compatible = "qcom,msm-pcm-dsp";
+		qcom,msm-pcm-dsp-id = <1>;
+		qcom,msm-pcm-low-latency;
+		qcom,latency-level = "regular";
+	};
+
+	pcm2: qcom,msm-ultra-low-latency {
+		compatible = "qcom,msm-pcm-dsp";
+		qcom,msm-pcm-dsp-id = <2>;
+		qcom,msm-pcm-low-latency;
+		qcom,latency-level = "ultra";
+	};
+
+	cpe: qcom,msm-cpe-lsm {
+		compatible = "qcom,msm-cpe-lsm";
+	};
+
+	lpa: qcom,msm-pcm-lpa {
+		compatible = "qcom,msm-pcm-lpa";
+	};
+
+	compress: qcom,msm-compress-dsp {
+		compatible = "qcom,msm-compress-dsp";
+	};
+
+	voip: qcom,msm-voip-dsp {
+		compatible = "qcom,msm-voip-dsp";
+	};
+
+	voice: qcom,msm-pcm-voice {
+		compatible = "qcom,msm-pcm-voice";
+		qcom,destroy-cvd;
+	};
+
+	stub_codec: qcom,msm-stub-codec {
+		compatible = "qcom,msm-stub-codec";
+	};
+
+	qcom,msm-dai-fe {
+		compatible = "qcom,msm-dai-fe";
+	};
+
+	afe: qcom,msm-pcm-afe {
+		compatible = "qcom,msm-pcm-afe";
+	};
+
+	loopback: qcom,msm-pcm-loopback {
+		compatible = "qcom,msm-pcm-loopback";
+	};
+
+	qcom,msm-dai-mi2s {
+		compatible = "qcom,msm-dai-mi2s";
+		dai_mi2s0: qcom,msm-dai-q6-mi2s-prim {
+			compatible = "qcom,msm-dai-q6-mi2s";
+			qcom,msm-dai-q6-mi2s-dev-id = <0>;
+			qcom,msm-mi2s-rx-lines = <3>;
+			qcom,msm-mi2s-tx-lines = <0>;
+		};
+
+		dai_mi2s1: qcom,msm-dai-q6-mi2s-sec {
+			compatible = "qcom,msm-dai-q6-mi2s";
+			qcom,msm-dai-q6-mi2s-dev-id = <1>;
+			qcom,msm-mi2s-rx-lines = <1>;
+			qcom,msm-mi2s-tx-lines = <0>;
+		};
+
+		dai_mi2s3: qcom,msm-dai-q6-mi2s-quat {
+			compatible = "qcom,msm-dai-q6-mi2s";
+			qcom,msm-dai-q6-mi2s-dev-id = <3>;
+			qcom,msm-mi2s-rx-lines = <1>;
+			qcom,msm-mi2s-tx-lines = <2>;
+		};
+
+		dai_mi2s2: qcom,msm-dai-q6-mi2s-tert {
+			compatible = "qcom,msm-dai-q6-mi2s";
+			qcom,msm-dai-q6-mi2s-dev-id = <2>;
+			qcom,msm-mi2s-rx-lines = <0>;
+			qcom,msm-mi2s-tx-lines = <3>;
+		};
+
+		dai_mi2s5: qcom,msm-dai-q6-mi2s-quin {
+			compatible = "qcom,msm-dai-q6-mi2s";
+			qcom,msm-dai-q6-mi2s-dev-id = <5>;
+			qcom,msm-mi2s-rx-lines = <1>;
+			qcom,msm-mi2s-tx-lines = <2>;
+		};
+
+		dai_mi2s6: qcom,msm-dai-q6-mi2s-senary {
+			compatible = "qcom,msm-dai-q6-mi2s";
+			qcom,msm-dai-q6-mi2s-dev-id = <6>;
+			qcom,msm-mi2s-rx-lines = <0>;
+			qcom,msm-mi2s-tx-lines = <3>;
+		};
+	};
+
+	lsm: qcom,msm-lsm-client {
+		compatible = "qcom,msm-lsm-client";
+	};
+
+	qcom,msm-dai-q6 {
+		compatible = "qcom,msm-dai-q6";
+		sb_0_rx: qcom,msm-dai-q6-sb-0-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16384>;
+		};
+
+		sb_0_tx: qcom,msm-dai-q6-sb-0-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16385>;
+		};
+
+		sb_1_rx: qcom,msm-dai-q6-sb-1-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16386>;
+		};
+
+		sb_1_tx: qcom,msm-dai-q6-sb-1-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16387>;
+		};
+
+		sb_2_rx: qcom,msm-dai-q6-sb-2-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16388>;
+		};
+
+		sb_2_tx: qcom,msm-dai-q6-sb-2-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16389>;
+		};
+
+
+		sb_3_rx: qcom,msm-dai-q6-sb-3-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16390>;
+		};
+
+		sb_3_tx: qcom,msm-dai-q6-sb-3-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16391>;
+		};
+
+		sb_4_rx: qcom,msm-dai-q6-sb-4-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16392>;
+		};
+
+		sb_4_tx: qcom,msm-dai-q6-sb-4-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16393>;
+		};
+
+		sb_5_tx: qcom,msm-dai-q6-sb-5-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16395>;
+		};
+
+		sb_5_rx: qcom,msm-dai-q6-sb-5-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16394>;
+		};
+
+		bt_sco_rx: qcom,msm-dai-q6-bt-sco-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <12288>;
+		};
+
+		bt_sco_tx: qcom,msm-dai-q6-bt-sco-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <12289>;
+		};
+
+		int_fm_rx: qcom,msm-dai-q6-int-fm-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <12292>;
+		};
+
+		int_fm_tx: qcom,msm-dai-q6-int-fm-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <12293>;
+		};
+
+		afe_pcm_rx: qcom,msm-dai-q6-be-afe-pcm-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <224>;
+		};
+
+		afe_pcm_tx: qcom,msm-dai-q6-be-afe-pcm-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <225>;
+		};
+
+		afe_proxy_rx: qcom,msm-dai-q6-afe-proxy-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <241>;
+		};
+
+		afe_proxy_tx: qcom,msm-dai-q6-afe-proxy-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <240>;
+		};
+
+		incall_record_rx: qcom,msm-dai-q6-incall-record-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <32771>;
+		};
+
+		incall_record_tx: qcom,msm-dai-q6-incall-record-tx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <32772>;
+		};
+
+		incall_music_rx: qcom,msm-dai-q6-incall-music-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <32773>;
+		};
+
+		incall_music_2_rx: qcom,msm-dai-q6-incall-music-2-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <32770>;
+		};
+
+		sb_6_rx: qcom,msm-dai-q6-sb-6-rx {
+			compatible = "qcom,msm-dai-q6-dev";
+			qcom,msm-dai-q6-dev-id = <16396>;
+		};
+	};
+
+	hostless: qcom,msm-pcm-hostless {
+		compatible = "qcom,msm-pcm-hostless";
+	};
+
+	dai_pri_auxpcm: qcom,msm-pri-auxpcm {
+		compatible = "qcom,msm-auxpcm-dev";
+		qcom,msm-cpudai-auxpcm-mode = <0>, <0>;
+		qcom,msm-cpudai-auxpcm-sync = <1>, <1>;
+		qcom,msm-cpudai-auxpcm-frame = <5>, <4>;
+		qcom,msm-cpudai-auxpcm-quant = <2>, <2>;
+		qcom,msm-cpudai-auxpcm-num-slots = <1>, <1>;
+		qcom,msm-cpudai-auxpcm-slot-mapping = <1>, <1>;
+		qcom,msm-cpudai-auxpcm-data = <0>, <0>;
+		qcom,msm-cpudai-auxpcm-pcm-clk-rate = <2048000>, <2048000>;
+		qcom,msm-auxpcm-interface = "primary";
+	};
+
+	hdmi_dba: qcom,msm-hdmi-dba-codec-rx {
+		compatible = "qcom,msm-hdmi-dba-codec-rx";
+		qcom,dba-bridge-chip = "adv7533";
+	};
+
+	qcom,msm-audio-ion {
+		compatible = "qcom,msm-audio-ion";
+		qcom,smmu-version = <1>;
+		qcom,smmu-enabled;
+		iommus = <&adsp_io 1>;
+	};
+
+	qcom,msm-adsp-loader {
+		compatible = "qcom,adsp-loader";
+		qcom,adsp-state = <0>;
+	};
+
+	qcom,avtimer@c0a300c {
+		compatible = "qcom,avtimer";
+		reg = <0x0c0a300c 0x4>,
+			<0x0c0a3010 0x4>;
+		reg-names = "avtimer_lsb_addr", "avtimer_msb_addr";
+		qcom,clk-div = <27>;
+	};
+
+	int_codec: sound {
+		status = "okay";
+		compatible = "qcom,msm8952-audio-codec";
+		qcom,model = "msm8953-snd-card";
+		reg = <0xc051000 0x4>,
+		      <0xc051004 0x4>,
+		      <0xc055000 0x4>,
+		      <0xc052000 0x4>;
+		reg-names = "csr_gp_io_mux_mic_ctl",
+			    "csr_gp_io_mux_spkr_ctl",
+			    "csr_gp_io_lpaif_pri_pcm_pri_mode_muxsel",
+			    "csr_gp_io_mux_quin_ctl";
+
+		qcom,msm-ext-pa = "primary";
+		qcom,msm-mclk-freq = <9600000>;
+		qcom,msm-mbhc-hphl-swh = <0>;
+		qcom,msm-mbhc-gnd-swh = <0>;
+		qcom,msm-hs-micbias-type = "external";
+		qcom,msm-micbias1-ext-cap;
+		qcom,audio-routing =
+			"RX_BIAS", "MCLK",
+			"SPK_RX_BIAS", "MCLK",
+			"INT_LDO_H", "MCLK",
+			"MIC BIAS External", "Handset Mic",
+			"MIC BIAS External2", "Headset Mic",
+			"MIC BIAS External", "Secondary Mic",
+			"AMIC1", "MIC BIAS External",
+			"AMIC2", "MIC BIAS External2",
+			"AMIC3", "MIC BIAS External",
+			"DMIC1", "MIC BIAS Internal1",
+			"MIC BIAS Internal1", "Digital Mic1",
+			"DMIC2", "MIC BIAS Internal1",
+			"MIC BIAS Internal1", "Digital Mic2",
+			"WSA_SPK OUT", "VDD_WSA_SWITCH",
+			"SpkrMono WSA_IN", "WSA_SPK OUT";
+
+		qcom,hdmi-dba-codec-rx;
+
+		qcom,msm-gpios =
+			"pri_i2s",
+			"dmic_gpio",
+			"quin_i2s",
+			"comp_gpio";
+		qcom,pinctrl-names =
+			"all_off",
+			"pri_i2s_act",
+			"dmic_gpio_act",
+			"pri_i2s_dmic_gpio_act",
+			"quin_act",
+			"quin_pri_i2s_act",
+			"quin_dmic_gpio_act",
+			"quin_dmic_gpio_pri_i2s_act",
+			"comp_gpio_act",
+			"comp_gpio_pri_i2s_act",
+			"comp_gpio_dmic_gpio_act",
+			"comp_gpio_pri_i2s_dmic_gpio_act",
+			"comp_gpio_quin_act",
+			"comp_gpio_quin_pri_i2s_act",
+			"comp_gpio_quin_dmic_gpio_act",
+			"comp_gpio_quin_dmic_gpio_pri_i2s_act";
+
+		pinctrl-names =
+			"all_off",
+			"pri_i2s_act",
+			"dmic_gpio_act",
+			"pri_i2s_dmic_gpio_act",
+			"quin_act",
+			"quin_pri_i2s_act",
+			"quin_dmic_gpio_act",
+			"quin_dmic_gpio_pri_i2s_act",
+			"comp_gpio_act",
+			"comp_gpio_pri_i2s_act",
+			"comp_gpio_dmic_gpio_act",
+			"comp_gpio_pri_i2s_dmic_gpio_act",
+			"comp_gpio_quin_act",
+			"comp_gpio_quin_pri_i2s_act",
+			"comp_gpio_quin_dmic_gpio_act",
+			"comp_gpio_quin_dmic_gpio_pri_i2s_act";
+
+		pinctrl-0 = <&cdc_pdm_lines_sus &cdc_pdm_comp_lines_sus
+			&cdc_pdm_lines_2_sus &cdc_dmic_lines_sus
+			&cdc_dmic_clk_sus &pri_tlmm_lines_sus &pri_tlmm_ws_sus>;
+		pinctrl-1 = <&cdc_pdm_lines_act &cdc_pdm_comp_lines_sus
+			&cdc_pdm_lines_2_act &cdc_dmic_lines_sus
+			&cdc_dmic_clk_sus &pri_tlmm_lines_sus &pri_tlmm_ws_sus>;
+		pinctrl-2 = <&cdc_pdm_lines_sus &cdc_pdm_comp_lines_sus
+			&cdc_pdm_lines_2_sus &cdc_dmic_lines_act
+			&cdc_dmic_clk_act &pri_tlmm_lines_sus &pri_tlmm_ws_sus>;
+		pinctrl-3 = <&cdc_pdm_lines_act &cdc_pdm_comp_lines_sus
+			&cdc_pdm_lines_2_act &cdc_dmic_lines_act
+			&cdc_dmic_clk_act &pri_tlmm_lines_sus &pri_tlmm_ws_sus>;
+		pinctrl-4 = <&cdc_pdm_lines_sus &cdc_pdm_comp_lines_sus
+			&cdc_pdm_lines_2_sus &cdc_dmic_lines_sus
+			&cdc_dmic_clk_sus &pri_tlmm_lines_act &pri_tlmm_ws_act>;
+		pinctrl-5 = <&cdc_pdm_lines_act &cdc_pdm_comp_lines_sus
+			&cdc_pdm_lines_2_act &cdc_dmic_lines_sus
+			&cdc_dmic_clk_sus &pri_tlmm_lines_act &pri_tlmm_ws_act>;
+		pinctrl-6 = <&cdc_pdm_lines_sus &cdc_pdm_comp_lines_sus
+			&cdc_pdm_lines_2_sus &cdc_dmic_lines_act
+			&cdc_dmic_clk_act &pri_tlmm_lines_act &pri_tlmm_ws_act>;
+		pinctrl-7 = <&cdc_pdm_lines_act &cdc_pdm_comp_lines_sus
+			&cdc_pdm_lines_2_act &cdc_dmic_lines_act
+			&cdc_dmic_clk_act &pri_tlmm_lines_act &pri_tlmm_ws_act>;
+		pinctrl-8 = <&cdc_pdm_lines_sus &cdc_pdm_comp_lines_act
+			&cdc_pdm_lines_2_sus &cdc_dmic_lines_sus
+			&cdc_dmic_clk_sus &pri_tlmm_lines_sus &pri_tlmm_ws_sus>;
+		pinctrl-9 = <&cdc_pdm_lines_act &cdc_pdm_comp_lines_act
+			&cdc_pdm_lines_2_act &cdc_dmic_lines_sus
+			&cdc_dmic_clk_sus &pri_tlmm_lines_sus &pri_tlmm_ws_sus>;
+		pinctrl-10 = <&cdc_pdm_lines_sus &cdc_pdm_comp_lines_act
+			&cdc_pdm_lines_2_sus &cdc_dmic_lines_act
+			&cdc_dmic_clk_act &pri_tlmm_lines_sus &pri_tlmm_ws_sus>;
+		pinctrl-11 = <&cdc_pdm_lines_act &cdc_pdm_comp_lines_act
+			&cdc_pdm_lines_2_act &cdc_dmic_lines_act
+			&cdc_dmic_clk_act &pri_tlmm_lines_sus &pri_tlmm_ws_sus>;
+		pinctrl-12 = <&cdc_pdm_lines_sus &cdc_pdm_comp_lines_act
+			&cdc_pdm_lines_2_sus &cdc_dmic_lines_sus
+			&cdc_dmic_clk_sus &pri_tlmm_lines_act &pri_tlmm_ws_act>;
+		pinctrl-13 = <&cdc_pdm_lines_act &cdc_pdm_comp_lines_act
+			&cdc_pdm_lines_2_act &cdc_dmic_lines_sus
+			&cdc_dmic_clk_sus &pri_tlmm_lines_act &pri_tlmm_ws_act>;
+		pinctrl-14 = <&cdc_pdm_lines_sus &cdc_pdm_comp_lines_act
+			&cdc_pdm_lines_2_sus &cdc_dmic_lines_act
+			&cdc_dmic_clk_act &pri_tlmm_lines_act &pri_tlmm_ws_act>;
+		pinctrl-15 = <&cdc_pdm_lines_act &cdc_pdm_comp_lines_act
+			&cdc_pdm_lines_2_act &cdc_dmic_lines_act
+			&cdc_dmic_lines_act &pri_tlmm_lines_act
+			&pri_tlmm_ws_act>;
+
+		asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
+				<&loopback>, <&compress>, <&hostless>,
+				<&afe>, <&lsm>, <&routing>, <&lpa>;
+		asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
+				"msm-pcm-dsp.2", "msm-voip-dsp",
+				"msm-pcm-voice", "msm-pcm-loopback",
+				"msm-compress-dsp", "msm-pcm-hostless",
+				"msm-pcm-afe", "msm-lsm-client",
+				"msm-pcm-routing", "msm-pcm-lpa";
+		asoc-cpu = <&dai_pri_auxpcm>,
+				<&dai_mi2s0>, <&dai_mi2s1>,
+				<&dai_mi2s2>, <&dai_mi2s3>,
+				<&dai_mi2s5>, <&dai_mi2s6>,
+				<&sb_0_rx>, <&sb_0_tx>, <&sb_1_rx>, <&sb_1_tx>,
+				<&sb_3_rx>, <&sb_3_tx>, <&sb_4_rx>, <&sb_4_tx>,
+				<&bt_sco_rx>, <&bt_sco_tx>,
+				<&int_fm_rx>, <&int_fm_tx>,
+				<&afe_pcm_rx>, <&afe_pcm_tx>,
+				<&afe_proxy_rx>, <&afe_proxy_tx>,
+				<&incall_record_rx>, <&incall_record_tx>,
+				<&incall_music_rx>, <&incall_music_2_rx>;
+		asoc-cpu-names = "msm-dai-q6-auxpcm.1",
+				"msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1",
+				"msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3",
+				"msm-dai-q6-mi2s.5", "msm-dai-q6-mi2s.6",
+				"msm-dai-q6-dev.16384", "msm-dai-q6-dev.16385",
+				"msm-dai-q6-dev.16386", "msm-dai-q6-dev.16387",
+				"msm-dai-q6-dev.16390", "msm-dai-q6-dev.16391",
+				"msm-dai-q6-dev.16392", "msm-dai-q6-dev.16393",
+				"msm-dai-q6-dev.12288", "msm-dai-q6-dev.12289",
+				"msm-dai-q6-dev.12292", "msm-dai-q6-dev.12293",
+				"msm-dai-q6-dev.224", "msm-dai-q6-dev.225",
+				"msm-dai-q6-dev.241", "msm-dai-q6-dev.240",
+				"msm-dai-q6-dev.32771", "msm-dai-q6-dev.32772",
+				"msm-dai-q6-dev.32773", "msm-dai-q6-dev.32770";
+
+		asoc-codec = <&stub_codec>, <&pm8953_diangu_dig>, <&hdmi_dba>;
+		asoc-codec-names = "msm-stub-codec.1", "cajon_codec",
+							"msm-hdmi-dba-codec-rx";
+		asoc-wsa-codec-names = "wsa881x-i2c-codec.2-000f";
+		asoc-wsa-codec-prefixes = "SpkrMono";
+
+		msm-vdd-wsa-switch-supply = <&pm8953_l5>;
+		qcom,msm-vdd-wsa-switch-voltage = <1800000>;
+		qcom,msm-vdd-wsa-switch-current = <10000>;
+	};
+
+	clock_audio: audio_ext_clk {
+		status = "disabled";
+		compatible = "qcom,audio-ref-clk";
+		clock-names = "osr_clk";
+		qcom,node_has_rpm_clock;
+		#clock-cells = <1>;
+	};
+
+};
+
+&adsp_io {
+	qcom,virtual-addr-pool = <0x10000000 0x0fffffff>;
+	#iommu-cells = <1>;
+};
+
+&clock_audio {
+	status = "okay";
+	qcom,audio-ref-clk-gpio = <&pm8953_gpios 1 0>;
+	qcom,lpass-mclk-id = "pri_mclk";
+	clocks = <&clock_gcc clk_div_clk2>;
+	pinctrl-names = "sleep", "active";
+	pinctrl-0 = <&cdc_mclk2_sleep>;
+	pinctrl-1 = <&cdc_mclk2_active>;
+};
+
+&pm8953_1 {
+	status = "okay";
+	pm8953_diangu_dig: 8953_wcd_codec@f000 {
+		status = "okay";
+		compatible = "qcom,msm8x16_wcd_codec";
+		reg = <0xf000 0x100>;
+		interrupt-parent = <&spmi_bus>;
+		interrupts = <0x1 0xf0 0x0>,
+			     <0x1 0xf0 0x1>,
+			     <0x1 0xf0 0x2>,
+			     <0x1 0xf0 0x3>,
+			     <0x1 0xf0 0x4>,
+			     <0x1 0xf0 0x5>,
+			     <0x1 0xf0 0x6>,
+			     <0x1 0xf0 0x7>;
+		interrupt-names = "spk_cnp_int",
+				  "spk_clip_int",
+				  "spk_ocp_int",
+				  "ins_rem_det1",
+				  "but_rel_det",
+				  "but_press_det",
+				  "ins_rem_det",
+				  "mbhc_int";
+
+		cdc-vdda-cp-supply = <&pm8953_s4>;
+		qcom,cdc-vdda-cp-voltage = <1900000 2050000>;
+		qcom,cdc-vdda-cp-current = <500000>;
+
+		cdc-vdd-io-supply = <&pm8953_l5>;
+		qcom,cdc-vdd-io-voltage = <1800000 1800000>;
+		qcom,cdc-vdd-io-current = <5000>;
+
+		cdc-vdd-pa-supply = <&pm8953_s4>;
+		qcom,cdc-vdd-pa-voltage = <1900000 2050000>;
+		qcom,cdc-vdd-pa-current = <260000>;
+
+		cdc-vdd-mic-bias-supply = <&pm8953_l13>;
+		qcom,cdc-vdd-mic-bias-voltage = <3125000 3125000>;
+		qcom,cdc-vdd-mic-bias-current = <5000>;
+
+		qcom,cdc-mclk-clk-rate = <9600000>;
+
+		qcom,cdc-static-supplies =  "cdc-vdd-io",
+					   "cdc-vdd-pa",
+					   "cdc-vdda-cp";
+
+		qcom,cdc-on-demand-supplies = "cdc-vdd-mic-bias";
+		qcom,dig-cdc-base-addr = <0xc0f0000>;
+	};
+
+	pm8953_diangu_analog: 8953_wcd_codec@f100 {
+		status = "okay";
+		compatible = "qcom,msm8x16_wcd_codec";
+		reg = <0xf100 0x100>;
+		interrupt-parent = <&spmi_bus>;
+		interrupts = <0x1 0xf1 0x0>,
+			     <0x1 0xf1 0x1>,
+			     <0x1 0xf1 0x2>,
+			     <0x1 0xf1 0x3>,
+			     <0x1 0xf1 0x4>,
+			     <0x1 0xf1 0x5>;
+		interrupt-names = "ear_ocp_int",
+				  "hphr_ocp_int",
+				  "hphl_ocp_det",
+				  "ear_cnp_int",
+				  "hphr_cnp_int",
+				  "hphl_cnp_int";
+		qcom,dig-cdc-base-addr = <0xc0f0000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8053-lat-concam-dev.dts b/arch/arm64/boot/dts/qcom/apq8053-lat-concam-dev.dts
new file mode 100644
index 0000000..7947008
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8053-lat-concam-dev.dts
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2018, 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 "apq8053-lat-concam.dtsi"
+#include "apq8053-camera-sensor-mtp.dtsi"
+#include "apq8053-lat-concam-regulator.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. APQ8053 LAT Concam Dev board";
+	compatible = "qcom,apq8053-mtp", "qcom,apq8053", "qcom,mtp";
+	qcom,board-id= <0x56 0x30>;
+};
+
+&pm8953_mpps {
+	mpp@a100 {
+		reg = <0xa100 0x100>;
+		qcom,pin-num = <2>;
+		qcom,mode = <4>; // A-input
+		qcom,invert = <1>; /* Enable MPP */
+		qcom,ain-route = <1>; // QPNP_PIN_AIN_AMUX_CH6 = 1 for MPP2
+		qcom,master-en = <1>; //Enable MPP
+		qcom,src-sel = <0>; /* Function constant */
+		status = "okay";
+	};
+
+	mpp@a200 {
+		/* MPP3 - PA_THERM config */
+		reg = <0xa200 0x100>;
+		com,pin-num = <3>;
+		qcom,mode = <4>; /* AIN input */
+		qcom,invert = <1>; /* Enable MPP */
+		qcom,ain-route = <2>; /* AMUX 7 */
+		qcom,master-en = <1>;
+		qcom,src-sel = <0>; /* Function constant */
+		status = "okay";
+	};
+
+	mpp@a300 {
+		/* MPP4 - CASE_THERM config */
+		reg = <0xa300 0x100>;
+		com,pin-num = <4>;
+		qcom,mode = <4>; /* AIN input */
+		qcom,invert = <1>; /* Enable MPP */
+		qcom,ain-route = <3>; /* AMUX 8 */
+		qcom,master-en = <1>;
+		qcom,src-sel = <0>; /* Function constant */
+		status = "okay";
+	};
+};
+
+&tlmm {
+	button_active: button_active {
+		mux {
+			pins = "gpio57";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio57";
+			drive-strength = <8>;
+			bias-pull-up;
+		};
+	};
+
+	icr_int {
+		qcom,pins = <&tlmm 53>;
+		qcom,num-grp-pins = <1>;
+		qcom,pin-func = <0>;
+		label = "icr-int";
+		icr_int_default: icr_int_default {
+			drive-strength = <2>;	/* 2 MA */
+			bias-pull-up;		/* PULL UP*/
+		};
+	};
+
+	gcc_gp1_clk_pin {
+		qcom,pins = <&tlmm 33>;
+		qcom,num-grp-pins = <1>;
+		qcom,pin-func = <2>;
+		label = "gp1-clk-pin";
+		gcc_gp1_clk_pin: gcc_gp1_clk_pin {
+			drive-strength = <2>;	/* 2 MA */
+			bias-disable;
+		};
+	};
+
+	bt_host_wake_default: bt_host_wake_default {
+		mux {
+			pins = "gpio52";
+			function = "gpio";
+		};
+		config {
+			pins = "gpio52";
+			bias-disable; /* No PULL */
+			drive-strength = <2>;
+		};
+	};
+};
+
+&soc {
+	usb_detect: usb_detect {
+		compatible = "linux,extcon-usb-gpio";
+		vbus-gpio = <&tlmm 57 GPIO_ACTIVE_HIGH>;
+		qcom,enable-button-mode;
+
+		pinctrl-names = "button_active";
+		pinctrl-0 = <&button_active>;
+	};
+
+	hbtp {
+		status = "disabled";
+	};
+};
+
+&usb3 {
+	extcon = <&usb_detect>;
+};
+
+&firmware {
+	android {
+		vbmeta {
+			compatible = "android,vbmeta";
+			parts = "vbmeta,boot,system,vendor,bluetooth,modem,oem";
+		};
+		fstab {
+			/delete-node/ system;
+			vendor {
+				fsmgr_flags = "wait,slotselect,avb";
+			};
+		};
+	};
+};
+
+&modem_mem {
+	reg = <0x0 0x86c00000 0x0 0x1e00000>;
+};
+
+&wcnss_fw_mem {
+	reg = <0x0 0x89b00000 0x0 0x700000>;
+};
+
+&gpio_key_suspend {
+	config {
+		/delete-property/ bias-pull-up;
+		bias-pull-down;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8053-lat-concam-proto.dts b/arch/arm64/boot/dts/qcom/apq8053-lat-concam-proto.dts
new file mode 100644
index 0000000..f3124bc
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8053-lat-concam-proto.dts
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2018, 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 "apq8053-lat-concam.dtsi"
+#include "apq8053-camera-sensor-mtp.dtsi"
+#include "apq8053-lat-concam-regulator.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. APQ8053 LAT Concam Dev board";
+	compatible = "qcom,apq8053-mtp", "qcom,apq8053", "qcom,mtp";
+	qcom,board-id= <0x56 0x31>;
+};
+
+
+
+&pm8953_mpps {
+	mpp@a100 {
+		reg = <0xa100 0x100>;
+		qcom,pin-num = <2>;
+		qcom,mode = <4>; // A-input
+		qcom,invert = <1>; /* Enable MPP */
+		qcom,ain-route = <1>; // QPNP_PIN_AIN_AMUX_CH6 = 1 for MPP2
+		qcom,master-en = <1>; //Enable MPP
+		qcom,src-sel = <0>; /* Function constant */
+		status = "okay";
+	};
+
+	mpp@a200 {
+		/* MPP3 - PA_THERM config */
+		reg = <0xa200 0x100>;
+		com,pin-num = <3>;
+		qcom,mode = <4>; /* AIN input */
+		qcom,invert = <1>; /* Enable MPP */
+		qcom,ain-route = <2>; /* AMUX 7 */
+		qcom,master-en = <1>;
+		qcom,src-sel = <0>; /* Function constant */
+		status = "okay";
+	};
+
+	mpp@a300 {
+		/* MPP4 - CASE_THERM config */
+		reg = <0xa300 0x100>;
+		com,pin-num = <4>;
+		qcom,mode = <4>; /* AIN input */
+		qcom,invert = <1>; /* Enable MPP */
+		qcom,ain-route = <3>; /* AMUX 8 */
+		qcom,master-en = <1>;
+		qcom,src-sel = <0>; /* Function constant */
+		status = "okay";
+	};
+};
+
+&tlmm {
+	button_active: button_active {
+		mux {
+			pins = "gpio57";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio57";
+			drive-strength = <8>;
+			bias-pull-up;
+		};
+	};
+
+	icr_int {
+		qcom,pins = <&tlmm 53>;
+		qcom,num-grp-pins = <1>;
+		qcom,pin-func = <0>;
+		label = "icr-int";
+		icr_int_default: icr_int_default {
+			drive-strength = <2>;	/* 2 MA */
+			bias-pull-up;		/* PULL UP*/
+		};
+	};
+
+	gcc_gp1_clk_pin {
+		qcom,pins = <&tlmm 33>;
+		qcom,num-grp-pins = <1>;
+		qcom,pin-func = <2>;
+		label = "gp1-clk-pin";
+		gcc_gp1_clk_pin: gcc_gp1_clk_pin {
+			drive-strength = <2>;	/* 2 MA */
+			bias-disable;
+		};
+	};
+
+	bt_host_wake_default: bt_host_wake_default {
+		mux {
+			pins = "gpio52";
+			function = "gpio";
+		};
+		config {
+			pins = "gpio52";
+			bias-disable; /* No PULL */
+			drive-strength = <2>;
+		};
+	};
+};
+
+&soc {
+	usb_detect: usb_detect {
+		compatible = "linux,extcon-usb-gpio";
+		vbus-gpio = <&tlmm 57 GPIO_ACTIVE_HIGH>;
+		qcom,enable-button-mode;
+
+		pinctrl-names = "button_active";
+		pinctrl-0 = <&button_active>;
+	};
+
+	hbtp {
+		status = "disabled";
+	};
+};
+
+&usb3 {
+	extcon = <&usb_detect>;
+};
+
+&firmware {
+	android {
+		vbmeta {
+			compatible = "android,vbmeta";
+			parts = "vbmeta,boot,system,vendor,bluetooth,modem,oem";
+		};
+		fstab {
+			/delete-node/ system;
+			vendor {
+				fsmgr_flags = "wait,slotselect,avb";
+			};
+		};
+	};
+};
+
+&modem_mem {
+	reg = <0x0 0x86c00000 0x0 0x1e00000>;
+};
+
+&wcnss_fw_mem {
+	reg = <0x0 0x89b00000 0x0 0x700000>;
+};
+
+&gpio_key_suspend {
+	config {
+		/delete-property/ bias-pull-up;
+		bias-pull-down;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8053-lat-concam-regulator.dtsi b/arch/arm64/boot/dts/qcom/apq8053-lat-concam-regulator.dtsi
new file mode 100644
index 0000000..8fae286
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8053-lat-concam-regulator.dtsi
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2018, 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.
+ */
+
+&rpm_bus {
+	rpm-regulator-ldoa18 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <18>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		pm8953_l18: regulator-l18 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l18";
+			qcom,set = <3>;
+			regulator-min-microvolt = <2700000>;
+			regulator-max-microvolt = <3300000>;
+			qcom,init-voltage = <2700000>;
+		};
+
+	};
+
+	rpm-regulator-ldoa9 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <9>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "okay";
+		regulator-boot-on;
+		regulator-always-on;
+		regulator-l9 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l9";
+			qcom,set = <3>;
+			regulator-boot-on;
+			regulator-always-on;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa10 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <10>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		regulator-boot-on;
+		regulator-always-on;
+		pm8953_l10: regulator-l10 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l10";
+			qcom,set = <3>;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,init-voltage = <1800000>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+	};
+
+	/* L4 for ALS, TMP, Moisture, Image Sensor, PD Control, Thermistor */
+	rpm-regulator-ldoa4 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <4>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		regulator-boot-on;
+		regulator-l4 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l4";
+			qcom,set = <3>;
+			regulator-always-on;
+			regulator-boot-on;
+			status = "okay";
+		};
+	};
+
+	/* l2, l7 and l17 for cci */
+	rpm-regulator-ldoa2 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <2>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "okay";
+		regulator-l2 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l2";
+			qcom,set = <3>;
+			regulator-always-on;
+			regulator-boot-on;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa7 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <7>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "okay";
+		regulator-l7 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l7";
+			qcom,set = <3>;
+			regulator-always-on;
+			regulator-boot-on;
+			status = "okay";
+		};
+	};
+
+	rpm-regulator-ldoa17 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <17>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "okay";
+
+		regulator-l17 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l17";
+			qcom,set = <3>;
+			regulator-always-on;
+			regulator-boot-on;
+			status = "okay";
+		};
+	};
+
+	/* l6 for eeprom/ Image sensor */
+
+	rpm-regulator-ldoa6 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <6>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "okay";
+		regulator-l6 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l6";
+			qcom,set = <3>;
+			regulator-always-on;
+			regulator-boot-on;
+			status = "okay";
+		};
+	};
+
+	/* l5 for WSA8815 Speaker amp */
+	rpm-regulator-ldoa5 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <5>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "okay";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-l5 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l5";
+			qcom,set = <3>;
+			regulator-always-on;
+			regulator-boot-on;
+			status = "okay";
+		};
+	};
+
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8053-lat-concam.dtsi b/arch/arm64/boot/dts/qcom/apq8053-lat-concam.dtsi
new file mode 100644
index 0000000..b359db3
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8053-lat-concam.dtsi
@@ -0,0 +1,580 @@
+/*
+ * Copyright (c) 2018, 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 "msm8953.dtsi"
+#include "msm8953-pinctrl.dtsi"
+/ {
+	model = "Qualcomm Technologies, Inc. APQ 8953";
+	compatible = "qcom,apq8053";
+	qcom,msm-id = <304 0x0>;
+};
+
+/ {
+	/delete-property/ aliases;
+
+	aliases {
+		/* smdtty devices */
+		smd1 = &smdtty_apps_fm;
+		smd2 = &smdtty_apps_riva_bt_acl;
+		smd3 = &smdtty_apps_riva_bt_cmd;
+		smd4 = &smdtty_mbalbridge;
+		smd5 = &smdtty_apps_riva_ant_cmd;
+		smd6 = &smdtty_apps_riva_ant_data;
+		smd7 = &smdtty_data1;
+		smd8 = &smdtty_data4;
+		smd11 = &smdtty_data11;
+		smd21 = &smdtty_data21;
+		smd36 = &smdtty_loopback;
+		sdhc1 = &sdhc_1; /* SDC1 eMMC slot */
+		sdhc2 = &sdhc_2; /* SDC2 for SD card */
+		i2c1 = &i2c_1;
+		i2c2 = &i2c_2;
+		i2c3 = &i2c_3;
+		i2c4 = &i2c_4;
+		i2c5 = &i2c_5;
+		i2c7 = &i2c_7;
+		i2c8 = &i2c_8;
+		spi3 = &spi_3;
+	};
+
+};
+
+&sdhc_2 {
+	nest,workaround-ocr-add-vio = "VIO_3_3";
+};
+
+&soc {
+	i2c_4: i2c@78b8000 { /* BLSP1 QUP3 */
+		compatible = "qcom,i2c-msm-v2";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg-names = "qup_phys_addr";
+		reg = <0x78b8000 0x600>;
+		interrupt-names = "qup_irq";
+		interrupts = <0 98 0>;
+		qcom,clk-freq-out = <400000>;
+		qcom,clk-freq-in  = <19200000>;
+		clock-names = "iface_clk", "core_clk";
+		clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
+			<&clock_gcc clk_gcc_blsp1_qup4_i2c_apps_clk>;
+
+		pinctrl-names = "i2c_active", "i2c_sleep";
+		pinctrl-0 = <&i2c_4_active>;
+		pinctrl-1 = <&i2c_4_sleep>;
+		qcom,noise-rjct-scl = <0>;
+		qcom,noise-rjct-sda = <0>;
+		qcom,master-id = <86>;
+		dmas = <&dma_blsp1 10 64 0x20000020 0x20>,
+			<&dma_blsp1 11 32 0x20000020 0x20>;
+		dma-names = "tx", "rx";
+		status = "disabled";
+	};
+
+	i2c_7: i2c@7AF7000 { /* BLSP2 QUP2 */
+		compatible = "qcom,i2c-msm-v2";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg-names = "qup_phys_addr";
+		reg = <0x7AF7000 0x600>;
+		interrupt-names = "qup_irq";
+		interrupts = <0 301 0>;
+		qcom,clk-freq-out = <400000>;
+		qcom,clk-freq-in  = <19200000>;
+		clock-names = "iface_clk", "core_clk";
+		clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>,
+			<&clock_gcc clk_gcc_blsp2_qup3_i2c_apps_clk>;
+
+		pinctrl-names = "i2c_active", "i2c_sleep";
+		pinctrl-0 = <&i2c_7_active>;
+		pinctrl-1 = <&i2c_7_sleep>;
+		qcom,noise-rjct-scl = <0>;
+		qcom,noise-rjct-sda = <0>;
+		qcom,master-id = <84>;
+		dmas = <&dma_blsp1 8 64 0x20000020 0x20>,
+			<&dma_blsp1 9 32 0x20000020 0x20>;
+		dma-names = "tx", "rx";
+		status = "disabled";
+	};
+
+	i2c_8: i2c@7AF8000 { /* BLSP2 QUP3 */
+		compatible = "qcom,i2c-msm-v2";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg-names = "qup_phys_addr";
+		reg = <0x7AF8000 0x600>;
+		interrupt-names = "qup_irq";
+		interrupts = <0 302 0>;
+		qcom,clk-freq-out = <400000>;
+		qcom,clk-freq-in  = <19200000>;
+		clock-names = "iface_clk", "core_clk";
+		clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>,
+			<&clock_gcc clk_gcc_blsp2_qup4_i2c_apps_clk>;
+
+		pinctrl-names = "i2c_active", "i2c_sleep";
+		pinctrl-0 = <&i2c_8_active>;
+		pinctrl-1 = <&i2c_8_sleep>;
+		qcom,noise-rjct-scl = <0>;
+		qcom,noise-rjct-sda = <0>;
+		qcom,master-id = <84>;
+		dmas = <&dma_blsp1 10 64 0x20000020 0x20>,
+			<&dma_blsp1 11 32 0x20000020 0x20>;
+		dma-names = "tx", "rx";
+		status = "disabled";
+	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+		input-name = "gpio-keys";
+		pinctrl-names = "tlmm_gpio_key_active","tlmm_gpio_key_suspend";
+		pinctrl-0 = <&gpio_key_active>;
+		pinctrl-1 = <&gpio_key_suspend>;
+
+		camera_focus {
+			label = "camera_focus";
+			gpios = <&tlmm 87 0x1>;
+			linux,input-type = <1>;
+			linux,code = <0x210>;
+			debounce-interval = <15>;
+		};
+
+		camera_snapshot {
+			label = "camera_snapshot";
+			gpios = <&tlmm 86 0x1>;
+			linux,input-type = <1>;
+			linux,code = <0x2fe>;
+			debounce-interval = <15>;
+		};
+
+		vol_up {
+			label = "volume_up";
+			gpios = <&tlmm 85 0x1>;
+			linux,input-type = <1>;
+			linux,code = <115>;
+			debounce-interval = <15>;
+		};
+	};
+
+	hbtp {
+		compatible = "qcom,hbtp-input";
+		vcc_ana-supply = <&pm8953_l10>;
+		vcc_dig-supply = <&pm8953_l5>;
+		qcom,afe-load = <50000>;
+		qcom,afe-vtg-min = <2850000>;
+		qcom,afe-vtg-max = <2850000>;
+		qcom,dig-load = <15000>;
+		qcom,dig-vtg-min = <1800000>;
+		qcom,dig-vtg-max = <1800000>;
+	};
+};
+
+&soc {
+	qcom,rmnet-ipa {
+		status = "disabled";
+	};
+};
+
+&ipa_hw {
+	status = "disabled";
+};
+
+&secure_mem {
+	status = "disabled";
+};
+
+&tlmm {
+	i2c_4 {
+		i2c_4_active: i2c_4_active {
+			/* active state */
+			mux {
+				pins = "gpio14", "gpio15";
+				function = "blsp_i2c4";
+			};
+
+			config {
+				pins = "gpio14", "gpio15";
+				drive-strength = <2>;
+				bias-disable;
+			};
+		};
+
+		i2c_4_sleep: i2c_4_sleep {
+			/* suspended state */
+			mux {
+				pins = "gpio14", "gpio15";
+				function = "gpio";
+			};
+
+			config {
+				pins = "gpio14", "gpio15";
+				drive-strength = <2>;
+				bias-disable;
+			};
+		};
+	};
+
+	i2c_7 {
+		i2c_7_active: i2c_7_active {
+			/* active state */
+			mux {
+				pins = "gpio135", "gpio136";
+				function = "blsp_i2c7";
+			};
+
+			config {
+				pins = "gpio135", "gpio136";
+				drive-strength = <2>;
+				bias-disable;
+			};
+		};
+
+		i2c_7_sleep: i2c_7_sleep {
+			/* suspended state */
+			mux {
+				pins = "gpio135", "gpio136";
+				function = "gpio";
+			};
+
+			config {
+				pins = "gpio135", "gpio136";
+				drive-strength = <2>;
+				bias-disable;
+			};
+		};
+	};
+
+	i2c_8 {
+		i2c_8_active: i2c_8_active {
+			/* active state */
+			mux {
+				pins = "gpio98", "gpio99";
+				function = "blsp_i2c8";
+			};
+
+			config {
+				pins = "gpio98", "gpio99";
+				drive-strength = <2>;
+				bias-disable;
+			};
+		};
+
+		i2c_8_sleep: i2c_8_sleep {
+			/* suspended state */
+			mux {
+				pins = "gpio98", "gpio99";
+				function = "gpio";
+			};
+
+			config {
+				pins = "gpio98", "gpio99";
+				drive-strength = <2>;
+				bias-disable;
+			};
+		};
+	};
+};
+
+&blsp1_uart0 {
+	status = "ok";
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart_console_active>;
+};
+
+&i2c_4 {
+	status = "ok";
+
+	opt3001@44 {
+		compatible = "ti,opt3001";
+		reg = <0x44>; /* ALS_ADDR connected to ground */
+		status = "okay";
+	};
+
+	ina231@40 {
+		compatible = "ti,ina231";
+		reg = <0x40>;
+		shunt-resistor = <10000>;
+	};
+};
+
+&sdhc_1 {
+	/* device core power supply */
+	vdd-supply = <&pm8953_l8>;
+	qcom,vdd-voltage-level = <2900000 2900000>;
+	qcom,vdd-current-level = <200 570000>;
+
+	/* device communication power supply */
+	vdd-io-supply = <&pm8953_l5>;
+	qcom,vdd-io-always-on;
+	qcom,vdd-io-lpm-sup;
+	qcom,vdd-io-voltage-level = <1800000 1800000>;
+	qcom,vdd-io-current-level = <200 325000>;
+
+	pinctrl-names = "active", "sleep";
+	pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on  &sdc1_rclk_on>;
+	pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>;
+
+	qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000
+								384000000>;
+	qcom,nonremovable;
+	qcom,bus-speed-mode = "HS200_1p8v";
+
+	status = "ok";
+};
+
+&i2c_8 {
+	status = "ok";
+
+	tlc59108@42 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		#gpio-cells = <2>;
+		enable-gpio = <&tlmm 61 GPIO_ACTIVE_HIGH>;
+		compatible = "ti,tlc59108";
+		label = "tlc59108";
+		reg = <0x42>;
+
+		chan0@0 {
+			label = "tlc59108:chan0";
+			reg = <0x0>;
+		};
+
+		chan1@1 {
+			label = "tlc59108:chan1";
+			reg = <0x1>;
+		};
+
+		chan2@2 {
+			label = "tlc59108:chan2";
+			reg = <0x2>;
+		};
+
+		chan3@3 {
+			label = "tlc59108:chan3";
+			reg = <0x3>;
+		};
+
+		chan4@4 {
+			label = "tlc59108:chan4";
+			reg = <0x4>;
+		};
+
+		chan5@5 {
+			label = "tlc59108:chan5";
+			reg = <0x5>;
+		};
+
+		chan6@6 {
+			label = "tlc59108:chan6";
+			reg = <0x6>;
+		};
+
+		chan7@7 {
+			label = "tlc59108:chan7";
+			reg = <0x7>;
+		};
+	};
+
+	tlc59116@68 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		#gpio-cells = <2>;
+		enable-gpio = <&tlmm 61 GPIO_ACTIVE_HIGH>;
+		compatible = "ti,tlc59116";
+		label = "tlc59116";
+		reg = <0x68>;
+
+		chan0@0 {
+			label = "tlc59116:chan0";
+			reg = <0x0>;
+		};
+
+		chan1@1 {
+			label = "tlc59116:chan1";
+			reg = <0x1>;
+		};
+
+		chan2@2 {
+			label = "tlc59116:chan2";
+			reg = <0x2>;
+		};
+
+		chan3@3 {
+			label = "tlc59116:chan3";
+			reg = <0x3>;
+		};
+
+		chan4@4 {
+			label = "tlc59116:chan4";
+			reg = <0x4>;
+		};
+
+		chan5@5 {
+			label = "tlc59116:chan5";
+			reg = <0x5>;
+		};
+
+		chan6@6 {
+			label = "tlc59116:chan6";
+			reg = <0x6>;
+		};
+
+		chan7@7 {
+			label = "tlc59116:chan7";
+			reg = <0x7>;
+		};
+
+		chan8@8 {
+			label = "tlc59116:chan8";
+			reg = <0x8>;
+		};
+
+		chan9@9 {
+			label = "tlc59116:chan9";
+			reg = <0x9>;
+		};
+
+		chan10@10 {
+			label = "tlc59116:chan10";
+			reg = <0xa>;
+		};
+
+		chan11@11 {
+			label = "tlc59116:chan11";
+			reg = <0xb>;
+		};
+
+		chan12@12 {
+			label = "tlc59116:chan12";
+			reg = <0xc>;
+		};
+
+		chan13@13 {
+			label = "tlc59116:chan13";
+			reg = <0xd>;
+		};
+
+		chan14@14 {
+			label = "tlc59116:chan14";
+			reg = <0xe>;
+		};
+
+		chan15@15 {
+			label = "tlc59116:chan15";
+			reg = <0xf>;
+		};
+	};
+
+};
+
+&i2c_3 {
+	status = "ok";
+	eeprom0: qcom,eeprom@0 {
+		cell-index = <0>;
+		reg = <0x56>;
+		qcom,eeprom-name = "cat24c512";
+		compatible = "qcom,eeprom";
+		qcom,slave-addr = <0x56>;
+		qcom,cci-master = <0>;
+		/* For 512 Kb eeprom chip
+		 * add 8 logic eeprom blcoks each is 8KB
+		 */
+		qcom,num-blocks = <8>;
+
+		qcom,page0 = <0 0 0 0 0 0>;
+		qcom,poll0 = <0 0 0 0 0 0>;
+		qcom,saddr0 = <0x56>;
+		qcom,mem0 = <8192 0x0000 2 0 1 0>;
+
+		qcom,page1 = <0 0 0 0 0 0>;
+		qcom,poll1 = <0 0 0 0 0 0>;
+		qcom,saddr1 = <0x56>;
+		qcom,mem1 = <8192 0x2000 2 0 1 0>;
+
+		qcom,page2 = <0 0 0 0 0 0>;
+		qcom,poll2 = <0 0 0 0 0 0>;
+		qcom,saddr2 = <0x56>;
+		qcom,mem2 = <8192 0x4000 2 0 1 0>;
+
+		qcom,page3 = <0 0 0 0 0 0>;
+		qcom,poll3 = <0 0 0 0 0 0>;
+		qcom,saddr3 = <0x56>;
+		qcom,mem3 = <8192 0x6000 2 0 1 0>;
+
+		qcom,page4 = <0 0 0 0 0 0>;
+		qcom,poll4 = <0 0 0 0 0 0>;
+		qcom,saddr4 = <0x56>;
+		qcom,mem4 = <8192 0x8000 2 0 1 0>;
+
+		qcom,page5 = <0 0 0 0 0 0>;
+		qcom,poll5 = <0 0 0 0 0 0>;
+		qcom,saddr5 = <0x56>;
+		qcom,mem5 = <8192 0xA000 2 0 1 0>;
+
+		qcom,page6 = <0 0 0 0 0 0>;
+		qcom,poll6 = <0 0 0 0 0 0>;
+		qcom,saddr6 = <0x56>;
+		qcom,mem6 = <8192 0xC000 2 0 1 0>;
+
+		qcom,page7 = <0 0 0 0 0 0>;
+		qcom,poll7 = <0 0 0 0 0 0>;
+		qcom,saddr7 = <0x56>;
+		qcom,mem7 = <8192 0xE000 2 0 1 0>;
+
+		cam_vio-supply = <&pm8953_l6>;
+		qcom,cam-vreg-name = "cam_vio";
+		qcom,cam-vreg-min-voltage = <0>;
+		qcom,cam-vreg-max-voltage = <0>;
+		qcom,cam-vreg-op-mode = <0>;
+		qcom,cam-power-seq-type = "sensor_vreg";
+		qcom,cam-power-seq-val = "cam_vio";
+		qcom,cam-power-seq-cfg-val = <1>;
+		qcom,cam-power-seq-delay = <1>;
+		status = "ok";
+	};
+};
+
+&sdhc_2 {
+	/* device core power supply */
+	vdd-supply = <&pm8953_l10>;
+	qcom,vdd-voltage-level = <18000000 1800000>;
+	qcom,vdd-current-level = <200 22000>;
+
+	/* device communication power supply */
+	vdd-io-supply = <&pm8953_l12>;
+	qcom,vdd-io-voltage-level = <1800000 1800000>;
+	qcom,vdd-io-current-level = <200 22000>;
+
+	pinctrl-names = "active", "sleep";
+	pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>;
+	pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>;
+
+	#address-cells = <0>;
+	interrupt-parent = <&sdhc_2>;
+	interrupts = <0 1 2>;
+	#interrupt-cells = <1>;
+	interrupt-map-mask = <0xffffffff>;
+	interrupt-map = <0 &intc 0 125 0
+		1 &intc 0 221 0
+		2 &tlmm 45 0>;
+	interrupt-names = "hc_irq", "pwr_irq", "sdiowakeup_irq";
+	/*cd-gpios = <&tlmm 45 0x1>;*/
+
+	qcom,clk-rates = <400000 20000000 25000000 50000000 100000000
+								200000000>;
+	qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
+
+	status = "ok";
+};
+
+&pm8953_typec {
+	status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8053-lite-dragon-v2.2.1.dts b/arch/arm64/boot/dts/qcom/apq8053-lite-dragon-v2.2.1.dts
new file mode 100644
index 0000000..ef4c7a1
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8053-lite-dragon-v2.2.1.dts
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018, 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 "apq8053-lite.dtsi"
+#include "apq8053-lite-dragon-v2.2.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. APQ8053 Lite DragonBoard V2.2.1";
+	compatible = "qcom,apq8053-lite-dragonboard", "qcom,apq8053",
+			"qcom,dragonboard";
+	qcom,board-id = <0x01010320 0>;
+};
+
+&blsp2_uart0 {
+	status = "okay";
+};
+
+&mdss_dsi0 {
+	qcom,dsi-pref-prim-pan = <&dsi_inxnt51021_1200p_video>;
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi b/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi
index 84c08533..6638aac 100644
--- a/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi
@@ -159,7 +159,7 @@
 	android {
 		vbmeta {
 			compatible = "android,vbmeta";
-			parts = "vbmeta,boot,system,vendor,bluetooth,modem,oem";
+			parts = "vbmeta,boot,system,vendor,bluetooth,modem,dsp,oem";
 		};
 		fstab {
 			/delete-node/ system;
diff --git a/arch/arm64/boot/dts/qcom/apq8053-lite-som.dts b/arch/arm64/boot/dts/qcom/apq8053-lite-som.dts
new file mode 100644
index 0000000..eae1118
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8053-lite-som.dts
@@ -0,0 +1,443 @@
+/*
+ * Copyright (c) 2018, 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 "apq8053-lite.dtsi"
+#include "msm8953-pinctrl.dtsi"
+#include "pmi8950.dtsi"
+#include "msm8953-pmi8950.dtsi"
+#include "msm8953-mdss-panels.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. APQ8053 Lite SoM";
+};
+
+&soc {
+	vreg_5p0: vreg_5p0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vreg_5p0";
+		status = "ok";
+		enable-active-high;
+	};
+
+	eldo_cam0_vreg: eldo_cam0_vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "eldo_cam0_vreg";
+		regulator-min-microvolt = <1100000>;
+		regulator-max-microvolt = <1100000>;
+		status = "ok";
+		enable-active-high;
+		vin-supply = <&pm8953_l5>;
+	};
+
+	eldo_cam1_vreg: eldo_cam1_vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "eldo_cam1_vreg";
+		regulator-min-microvolt = <1100000>;
+		regulator-max-microvolt = <1100000>;
+		status = "ok";
+		enable-active-high;
+		vin-supply = <&pm8953_l5>;
+	};
+
+	eldo_cam2_vreg: eldo_cam2_vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "eldo_cam2_vreg";
+		regulator-min-microvolt = <1100000>;
+		regulator-max-microvolt = <1100000>;
+		status = "ok";
+		enable-active-high;
+		vin-supply = <&pm8953_l5>;
+	};
+
+	eldo_cam1_vcm_vreg: eldo_cam1_vcm_vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "eldo_cam1_vcm_vreg";
+		regulator-min-microvolt = <2800000>;
+		regulator-max-microvolt = <2800000>;
+		status = "ok";
+		enable-active-high;
+	};
+
+	cnss_sdio: qcom,cnss_sdio {
+		compatible = "qcom,cnss_sdio";
+		subsys-name = "AR6320";
+
+		/**
+		 * There is no vdd-wlan on board and this is not for DSRC.
+		 * IO and XTAL share the same vreg.
+		 */
+		vdd-wlan-io-supply = <&pm8953_l6>;
+		qcom,wlan-ramdump-dynamic = <0x200000>;
+		qcom,msm-bus,name = "msm-cnss";
+		qcom,msm-bus,num-cases = <4>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+			<79 512 0 0>,             /* No vote */
+			<79 512 6250 200000>,     /* 50 Mbps */
+			<79 512 25000 200000>,    /* 200 Mbps */
+			<79 512 2048000 4096000>; /* MAX */
+	};
+
+	bluetooth: bt_qca9379 {
+		compatible = "qca,qca6174";
+		qca,bt-reset-gpio = <&tlmm 76 0>; /* BT_EN */
+	};
+
+	cdc_dmic_gpios: cdc_dmic_pinctrl {
+		compatible = "qcom,msm-cdc-pinctrl";
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&cdc_dmic0_clk_act &cdc_dmic0_data_act>;
+		pinctrl-1 = <&cdc_dmic0_clk_sus &cdc_dmic0_data_sus>;
+	};
+
+	cdc_quat_mi2s_gpios: msm_cdc_pinctrl_quat {
+		compatible = "qcom,msm-cdc-pinctrl";
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&sec_tlmm_lines_act &ext_amp_ctrl_active>;
+		pinctrl-1 = <&sec_tlmm_lines_sus &ext_amp_ctrl_sleep>;
+	};
+};
+
+&cdc_pdm_comp_lines_act {
+	mux {
+		pins = "gpio67";
+		function = "cdc_pdm0";
+	};
+
+	config {
+		pins = "gpio67";
+		drive-strength = <8>;
+	};
+};
+
+&cdc_pdm_comp_lines_sus {
+	mux {
+		pins = "gpio67";
+		function = "cdc_pdm0";
+	};
+
+	config {
+		pins = "gpio67";
+		drive-strength = <2>;
+		bias-disable;
+	};
+};
+
+&firmware {
+	android {
+		vbmeta {
+			compatible = "android,vbmeta";
+
+			parts = "vbmeta,boot,system,vendor,bluetooth,modem,oem";
+		};
+		fstab {
+			/delete-node/ system;
+			vendor {
+				fsmgr_flags = "wait,slotselect,avb";
+			};
+		};
+	};
+};
+
+&rpm_bus {
+	rpm-regulator-ldoa4 {
+		compatible = "qcom,rpm-smd-regulator-resource";
+		qcom,resource-name = "ldoa";
+		qcom,resource-id = <4>;
+		qcom,regulator-type = <0>;
+		qcom,hpm-min-load = <10000>;
+		status = "okay";
+
+		pm8953_l4: regulator-l4 {
+			compatible = "qcom,rpm-smd-regulator";
+			regulator-name = "pm8953_l4";
+			qcom,set = <3>;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			qcom,init-voltage = <1800000>;
+			status = "okay";
+		};
+	};
+};
+
+&int_codec {
+	status = "ok";
+	qcom,model = "msm8953-openq624-snd-card";
+
+	/delete-property/ qcom,cdc-us-euro-gpios;
+	qcom,msm-hs-micbias-type = "internal";
+
+	qcom,audio-routing =
+		"RX_BIAS", "MCLK",
+		"SPK_RX_BIAS", "MCLK",
+		"INT_LDO_H", "MCLK",
+		"MIC BIAS Internal1", "Handset Mic",
+		"MIC BIAS Internal2", "Headset Mic",
+		"MIC BIAS Internal1", "Secondary Mic",
+		"AMIC1", "MIC BIAS Internal1",
+		"AMIC2", "MIC BIAS Internal2",
+		"AMIC3", "MIC BIAS Internal1",
+		"DMIC1", "MIC BIAS Internal1",
+		"MIC BIAS Internal1", "Digital Mic1",
+		"DMIC2", "MIC BIAS Internal1",
+		"MIC BIAS Internal1", "Digital Mic2";
+
+	qcom,quat-mi2s-gpios = <&cdc_quat_mi2s_gpios>;
+	qcom,cdc-dmic-gpios = <&cdc_dmic_gpios>;
+
+	/delete-property/ asoc-wsa-codec-names;
+	/delete-property/ asoc-wsa-codec-prefixes;
+	/delete-property/ msm-vdd-wsa-switch-supply;
+	/delete-property/ qcom,msm-vdd-wsa-switch-voltage;
+	/delete-property/ qcom,msm-vdd-wsa-switch-current;
+};
+
+&soc {
+	/delete-node/ hbtp;
+};
+
+&mdss_mdp {
+	qcom,mdss-pref-prim-intf = "dsi";
+};
+
+&mdss_dsi0 {
+	qcom,dsi-pref-prim-pan = <&dsi_boyi_hx83100a_800p_video>;
+};
+
+&blsp1_uart0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart_console_active>;
+};
+
+
+&blsp2_uart0 {
+	status = "okay";
+};
+
+&sdhc_1 {
+	/* device core power supply */
+	vdd-supply = <&pm8953_l8>;
+	qcom,vdd-voltage-level = <2900000 2900000>;
+	qcom,vdd-current-level = <200 570000>;
+
+	/* device communication power supply */
+	vdd-io-supply = <&pm8953_l5>;
+	qcom,vdd-io-always-on;
+	qcom,vdd-io-lpm-sup;
+	qcom,vdd-io-voltage-level = <1800000 1800000>;
+	qcom,vdd-io-current-level = <200 325000>;
+
+	pinctrl-names = "active", "sleep";
+	pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>;
+	pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>;
+
+	qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000
+								384000000>;
+	qcom,nonremovable;
+	qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v";
+
+	status = "ok";
+};
+
+&tlmm {
+	sdc2_wlan_gpio_on: sdc2_wlan_gpio_on {
+		mux {
+			pins = "gpio75";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio75";
+			drive-strength = <10>;
+			bias-pull-up;
+			output-high;
+		};
+	};
+	sdc2_wlan_gpio_off: sdc2_wlan_gpio_off {
+		mux {
+			pins = "gpio75";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio75";
+			drive-strength = <2>;
+			bias-disable;
+			output-low;
+		};
+	};
+};
+
+&sdhc_2 {
+	/* device communication power supply */
+	vdd-io-supply = <&pm8953_l12>;
+	qcom,vdd-io-always-on;
+	qcom,vdd-io-voltage-level = <1800000 1800000>;
+	qcom,vdd-io-current-level = <200 22000>;
+
+	qcom,core_3_0v_support;
+	qcom,nonremovable;
+
+	pinctrl-names = "active", "sleep";
+	pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on
+			&sdc2_wlan_gpio_on>;
+	pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off
+			&sdc2_wlan_gpio_off>;
+
+	qcom,clk-rates = <400000 20000000 25000000 50000000 100000000>;
+	qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
+
+	status = "ok";
+};
+
+&spmi_bus {
+	qcom,pm8953@0 {
+		qcom,power-on@800 {
+			qcom,resin-gpiobase = <1019>;
+			qcom,pon_2 {
+				/delete-property/ linux,code;
+			};
+		};
+	};
+	qcom,pmi8950@2 {
+		qcom,leds@a100 {
+			compatible = "qcom,leds-qpnp";
+			reg = <0xa100 0x100>;
+			label = "mpp";
+
+			qcom,led_mpp_2 {
+				label = "mpp";
+				linux,name = "green";
+				linux,default-trigger = "none";
+				qcom,default-state = "off";
+				qcom,max-current = <40>;
+				qcom,current-setting = <5>;
+				qcom,id = <6>;
+				qcom,mode = "manual";
+				qcom,source-sel = <1>;
+				qcom,mode-ctrl = <0x60>;
+			};
+		};
+
+		qcom,leds@a300 {
+			compatible = "qcom,leds-qpnp";
+			reg = <0xa300 0x100>;
+			label = "mpp";
+
+			qcom,led_mpp_4 {
+				label = "mpp";
+				linux,name = "blue";
+				linux,default-trigger = "none";
+				qcom,default-state = "off";
+				qcom,max-current = <40>;
+				qcom,current-setting = <5>;
+				qcom,id = <6>;
+				qcom,mode = "manual";
+				qcom,source-sel = <1>;
+				qcom,mode-ctrl = <0x60>;
+			};
+		};
+	};
+};
+
+&pm8953_typec {
+	ss-mux-supply = <&pm8953_l13>;
+	qcom,ssmux-gpio = <&tlmm 139 GPIO_ACTIVE_HIGH>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&typec_ssmux_config>;
+};
+
+/{
+	mtp_batterydata: qcom,battery-data {
+		qcom,batt-id-range-pct = <15>;
+		#include "batterydata-itech-3000mah.dtsi"
+		#include "batterydata-ascent-3450mAh.dtsi"
+	};
+};
+
+&pmi_haptic{
+	status = "disabled";
+	qcom,actuator-type = "lra";
+	qcom,lra-auto-res-mode="qwd";
+	qcom,lra-high-z="opt1";
+	qcom,lra-res-cal-period = <0>;
+	qcom,wave-play-rate-us = <4165>;
+};
+
+&flash_led {
+	status = "disabled";
+};
+
+&pm8953_pwm {
+	status = "ok";
+};
+
+&pm8953_vadc {
+	/delete-node/ chan@13;
+};
+
+&pmi8950_gpios {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pmi_gpio1_default>;
+	pmi_gpio1_default: pmi8950_gpio1 {
+		pins = "gpio1";
+		function = "normal";
+		input-enable;
+		power-source = <0>;
+		status = "okay";
+	};
+};
+
+&pmi8950_mpps {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ext_fet_wled_pwr_en_default>;
+	ext_fet_wled_pwr_en_default: pmi8950_mpp3 {
+		pins = "mpp3";  /* MPP_3 */
+		function = "digital"; /* Digital */
+		output-high; /* Output */
+		drive-strength = <2>; /* 1.8 mA */
+		power-source = <1>;
+		bias-disable = <0>; /* no pull */
+		status = "okay";
+	};
+};
+
+&pm8953_gpios {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pm_gpio1_div_clk2_default>;
+	pm_gpio1_div_clk2_default: pm8953_gpio1 {
+		pins = "gpio1";
+		function = "normal";
+		output-high;
+		power-source = <1>;
+		status = "okay";
+	};
+};
+
+&pm8953_mpps {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pm_mpp4_wled_pwm_ctrl_default>;
+	pm_mpp4_wled_pwm_ctrl_default: pm8953_mpp4 {
+		pins = "mpp4"; /* WLED_PWM_CTRL */
+		function = "digital"; /* Digital */
+		output-high;	/* Output */
+		drive-strength = <2>; /* 1.8 mA */
+		power-source = <0>; /* VPH_PWR */
+		qcom,dtest = <1>; /* DTEST1 */
+		bias-disable = <0>; /* no pull */
+		status = "okay";
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-inxnt51021-1200p-video.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-inxnt51021-1200p-video.dtsi
new file mode 100644
index 0000000..2131aec
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-inxnt51021-1200p-video.dtsi
@@ -0,0 +1,106 @@
+/* Novatek Android Driver Sample Code for Novatek chipset
+*
+* Copyright (C) 2015 Novatek Microelectronics Corp.
+*
+* This software is licensed under the terms of the GNU General Public
+* License version 2, as published by the Free Software Foundation, and
+* may be copied, distributed, and modified under those terms.
+*
+* 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.
+*
+*/
+
+&mdss_mdp {
+        dsi_inxnt51021_1200p_video: qcom,mdss_dsi_inxnt51021_1200p_video {
+		qcom,mdss-dsi-panel-name = "inxnt51021 1200p video mode dsi panel";
+		qcom,mdss-dsi-panel-controller = <&mdss_dsi0>;
+		qcom,mdss-dsi-panel-type = "dsi_video_mode";
+		qcom,mdss-dsi-panel-framerate = <60>;
+		qcom,mdss-dsi-virtual-channel-id = <0>;
+		qcom,mdss-dsi-stream = <0>;
+		qcom,mdss-dsi-panel-width = <1200>;
+		qcom,mdss-dsi-panel-height = <1920>;
+		qcom,mdss-dsi-h-front-porch = <100>;
+		qcom,mdss-dsi-h-back-porch = <32>;
+		qcom,mdss-dsi-h-pulse-width = <1>;
+		qcom,mdss-dsi-h-sync-skew = <0>;
+		qcom,mdss-dsi-v-back-porch = <14>;
+		qcom,mdss-dsi-v-front-porch = <25>;
+		qcom,mdss-dsi-v-pulse-width = <1>;
+		qcom,mdss-dsi-h-left-border = <0>;
+		qcom,mdss-dsi-h-right-border = <0>;
+		qcom,mdss-dsi-v-top-border = <0>;
+		qcom,mdss-dsi-v-bottom-border = <0>;
+		qcom,mdss-dsi-bpp = <24>;
+		qcom,mdss-dsi-underflow-color = <0xff>;
+		qcom,mdss-dsi-border-color = <0>;
+		qcom,mdss-dsi-on-command = [
+			23 01 00 00 01 00 02 8F A5
+			23 01 00 00 00 00 02 83 00
+			23 01 00 00 00 00 02 84 00
+			23 01 00 00 00 00 02 8C 84
+			23 01 00 00 00 00 02 C5 50
+			23 01 00 00 00 00 02 C7 50
+			23 01 00 00 00 00 02 85 04
+			23 01 00 00 00 00 02 86 08
+			23 01 00 00 00 00 02 83 AA
+			23 01 00 00 00 00 02 84 11
+			23 01 00 00 00 00 02 9C 10
+			23 01 00 00 00 00 02 A9 4B
+			23 01 00 00 00 00 02 A0 36
+			23 01 00 00 00 00 02 A1 36
+			23 01 00 00 00 00 02 C0 00
+			23 01 00 00 00 00 02 E0 3D
+			23 01 00 00 00 00 02 83 BB
+			23 01 00 00 00 00 02 84 22
+			23 01 00 00 00 00 02 C0 00
+			23 01 00 00 00 00 02 E0 3D
+			23 01 00 00 00 00 02 83 CC
+			23 01 00 00 00 00 02 84 33
+			23 01 00 00 00 00 02 C0 00
+			23 01 00 00 00 00 02 E0 3D
+			23 01 00 00 00 00 02 8F 00
+		];
+		qcom,mdss-dsi-off-command = [
+			23 01 00 00 01 00 02 8F A5
+			23 01 00 00 00 00 02 83 00
+			23 01 00 00 78 00 02 84 00
+			05 01 00 00 78 00 02 10 00
+		];
+		qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+		qcom,mdss-dsi-off-command-state = "dsi_lp_mode";
+		//qcom,cont-splash-enabled;
+		qcom,mdss-dsi-h-sync-pulse = <1>;
+		qcom,mdss-dsi-traffic-mode = "burst_mode";
+		qcom,mdss-dsi-lane-map = "lane_map_0123";
+		qcom,mdss-dsi-bllp-eof-power-mode;
+		qcom,mdss-dsi-bllp-power-mode;
+		qcom,mdss-dsi-lane-0-state;
+		qcom,mdss-dsi-lane-1-state;
+		qcom,mdss-dsi-lane-2-state;
+		qcom,mdss-dsi-lane-3-state;
+		qcom,mdss-dsi-panel-timings = [f2 3a 28 00 6c 70 2c 3e 2e 03 04 00];
+		qcom,mdss-dsi-t-clk-post = <0x0e>;
+		qcom,mdss-dsi-t-clk-pre = <0x33>;
+		qcom,mdss-dsi-bl-min-level = <1>;
+		qcom,mdss-dsi-bl-max-level = <4095>;
+		qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+		qcom,mdss-dsi-dma-trigger = "trigger_sw";
+		qcom,mdss-dsi-mdp-trigger = "none";
+		qcom,mdss-dsi-force-clock-lane-hs;
+		//qcom,platform-bklight-en-gpio = <&tlmm 46 0>;
+		//qcom,mdss-dsi-lcden-ctrl = <&tlmm 61 0>;
+		qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+		//qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>;
+		//qcom,mdss-dsi-bl-pmic-bank-select = <0>;
+		//qcom,mdss-dsi-pwm-gpio = <&pm8953_mpps 4 0>;
+		qcom,mdss-pan-physical-width-dimension = <135>;
+		qcom,mdss-pan-physical-height-dimension = <216>;
+		//qcom,mdss-dsi-reset-sequence = <1 10>, <0 5>, <1 50>;
+		qcom,mdss-dsi-lp11-init;
+		qcom,mdss-dsi-post-init-delay = <1>;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8909-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8909-mtp.dtsi
index e2fbc9e..ee2d0ac 100644
--- a/arch/arm64/boot/dts/qcom/msm8909-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8909-mtp.dtsi
@@ -113,17 +113,17 @@
 	gpio_keys {
 		compatible = "gpio-keys";
 		input-name = "gpio-keys";
-		pinctrl-names = "tlmm_gpio_key_active","tlmm_gpio_key_suspend";
+		pinctrl-names = "default";
 		pinctrl-0 = <&gpio_key_active>;
-		pinctrl-1 = <&gpio_key_suspend>;
 
 		camera_focus {
 			label = "camera_focus";
 			gpios = <&msm_gpio 91 0x1>;
 			linux,input-type = <1>;
 			linux,code = <0x210>;
-			gpio-key,wakeup;
 			debounce-interval = <15>;
+			linux,can-disable;
+			gpio-key,wakeup;
 		};
 
 		camera_snapshot {
@@ -131,8 +131,9 @@
 			gpios = <&msm_gpio 92 0x1>;
 			linux,input-type = <1>;
 			linux,code = <0x2fe>;
-			gpio-key,wakeup;
 			debounce-interval = <15>;
+			linux,can-disable;
+			gpio-key,wakeup;
 		};
 
 		vol_up {
@@ -140,8 +141,9 @@
 			gpios = <&msm_gpio 90 0x1>;
 			linux,input-type = <1>;
 			linux,code = <115>;
-			gpio-key,wakeup;
 			debounce-interval = <15>;
+			linux,can-disable;
+			gpio-key,wakeup;
 		};
 	};
 
diff --git a/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi b/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi
index be6ab79..fa218ca 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi
@@ -27,6 +27,7 @@
 #include "dsi-panel-hx83100a-800p-video.dtsi"
 #include "dsi-panel-boent51021-1200p-video.dtsi"
 #include "dsi-panel-hx8394d-wxga-video.dtsi"
+#include "dsi-panel-inxnt51021-1200p-video.dtsi"
 
 &soc {
 	dsi_panel_pwr_supply: dsi_panel_pwr_supply {
@@ -187,9 +188,17 @@
 };
 
 &dsi_hx8394d_kingdisplay_vid {
-    qcom,mdss-dsi-panel-timings-phy-v2 = [1c 19 02 03 01 03 04 a0
-        1c 19 02 03 01 03 04 a0
-        1c 19 02 03 01 03 04 a0
-        1c 19 02 03 01 03 04 a0
-        1c 07 02 03 01 03 04 a0];
+	qcom,mdss-dsi-panel-timings-phy-v2 = [1c 19 02 03 01 03 04 a0
+		1c 19 02 03 01 03 04 a0
+		1c 19 02 03 01 03 04 a0
+		1c 19 02 03 01 03 04 a0
+		1c 07 02 03 01 03 04 a0];
+};
+
+&dsi_inxnt51021_1200p_video {
+	qcom,mdss-dsi-panel-timings-phy-v2 = [25 20 08 0A 06 03 04 a0
+		25 20 08 0A 06 03 04 a0
+		25 20 08 0A 06 03 04 a0
+		25 20 08 0A 06 03 04 a0
+		25 1D 08 0A 06 03 04 a0];
 };
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera-base.dts b/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera-base.dts
new file mode 100644
index 0000000..622230c
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera-base.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2018, 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 "qcs605-lc.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. QCS605 LC SoC Ipcam base";
+	compatible = "qcom,qcs605";
+	qcom,board-id = <0 4>;
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera-overlay.dts b/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera-overlay.dts
index c7912d6..0cb7c33 100644
--- a/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera-overlay.dts
@@ -26,5 +26,5 @@
 	model = "Qualcomm Technologies, Inc. QC605 LC Groot + PM8005 IPC";
 	compatible = "qcom,qcs605-mtp", "qcom,qcs605", "qcom,mtp";
 	qcom,msm-id = <347 0x0>;
-	qcom,board-id = <8 6>;
+	qcom,board-id = <0x020208 4>;
 };
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera.dts b/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera.dts
index 90dcd7b..37dc8e0 100644
--- a/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera.dts
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera.dts
@@ -20,5 +20,5 @@
 / {
 	model = "Qualcomm Technologies, Inc. QC605 LC Groot + PM8005 IPC";
 	compatible = "qcom,qcs605-mtp", "qcom,qcs605", "qcom,mtp";
-	qcom,board-id = <8 6>;
+	qcom,board-id = <0x020208 4>;
 };
diff --git a/arch/arm64/boot/dts/qcom/sda845-v2-hdk.dtsi b/arch/arm64/boot/dts/qcom/sda845-v2-hdk.dtsi
index 378c4a1..d89a60e 100644
--- a/arch/arm64/boot/dts/qcom/sda845-v2-hdk.dtsi
+++ b/arch/arm64/boot/dts/qcom/sda845-v2-hdk.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2018, 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
@@ -91,3 +91,8 @@
 		qcom,afe-power-off-delay-us = <6>;
 	};
 };
+
+&qupv3_se5_i2c {
+	status = "disabled";
+};
+
diff --git a/arch/arm64/configs/msm8937-perf_defconfig b/arch/arm64/configs/msm8937-perf_defconfig
index 6420837..02d853a 100644
--- a/arch/arm64/configs/msm8937-perf_defconfig
+++ b/arch/arm64/configs/msm8937-perf_defconfig
@@ -72,6 +72,7 @@
 CONFIG_SWP_EMULATION=y
 CONFIG_CP15_BARRIER_EMULATION=y
 CONFIG_SETEND_EMULATION=y
+CONFIG_ARM64_SW_TTBR0_PAN=y
 # CONFIG_ARM64_VHE is not set
 CONFIG_RANDOMIZE_BASE=y
 CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y
diff --git a/arch/arm64/configs/msm8937_defconfig b/arch/arm64/configs/msm8937_defconfig
index 4040863..a2b4abb 100644
--- a/arch/arm64/configs/msm8937_defconfig
+++ b/arch/arm64/configs/msm8937_defconfig
@@ -75,6 +75,7 @@
 CONFIG_SWP_EMULATION=y
 CONFIG_CP15_BARRIER_EMULATION=y
 CONFIG_SETEND_EMULATION=y
+CONFIG_ARM64_SW_TTBR0_PAN=y
 # CONFIG_ARM64_VHE is not set
 CONFIG_RANDOMIZE_BASE=y
 CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y
diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig
index f3c1e7b..698857a 100644
--- a/arch/arm64/configs/msm8953-perf_defconfig
+++ b/arch/arm64/configs/msm8953-perf_defconfig
@@ -73,6 +73,7 @@
 CONFIG_SWP_EMULATION=y
 CONFIG_CP15_BARRIER_EMULATION=y
 CONFIG_SETEND_EMULATION=y
+CONFIG_ARM64_SW_TTBR0_PAN=y
 # CONFIG_ARM64_VHE is not set
 CONFIG_RANDOMIZE_BASE=y
 CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y
diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig
index 8401173c..6434a8e 100644
--- a/arch/arm64/configs/msm8953_defconfig
+++ b/arch/arm64/configs/msm8953_defconfig
@@ -76,6 +76,7 @@
 CONFIG_SWP_EMULATION=y
 CONFIG_CP15_BARRIER_EMULATION=y
 CONFIG_SETEND_EMULATION=y
+CONFIG_ARM64_SW_TTBR0_PAN=y
 # CONFIG_ARM64_VHE is not set
 CONFIG_RANDOMIZE_BASE=y
 CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index b7e61c8..c582701 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -313,6 +313,7 @@
 	unsigned int latency;
 	bool glink;
 	bool legacy;
+	bool secure_flag;
 	spinlock_t ctxlock;
 	struct smq_invoke_ctx *ctxtable[FASTRPC_CTX_MAX];
 };
@@ -3215,7 +3216,8 @@
 		if (err)
 			goto bail;
 		/* Check to see if the device node is non-secure */
-		if (fl->dev_minor == MINOR_NUM_DEV) {
+		if (fl->dev_minor == MINOR_NUM_DEV &&
+			fl->apps->secure_flag == true) {
 			/*
 			 * For non secure device node check and make sure that
 			 * the channel allows non-secure access
@@ -3863,10 +3865,13 @@
 			VERIFY(err, !of_property_read_u32(dev->of_node,
 					  "qcom,secure-domains",
 			      &secure_domains));
-			if (!err)
+			if (!err) {
+				me->secure_flag = true;
 				configure_secure_channels(secure_domains);
-			else
+			} else {
+				me->secure_flag = false;
 				pr_info("adsprpc: unable to read the domain configuration from dts\n");
+			}
 		}
 	}
 	if (of_device_is_compatible(dev->of_node,
@@ -4021,6 +4026,7 @@
 	fastrpc_init(me);
 	me->dev = NULL;
 	me->glink = true;
+	me->secure_flag = false;
 	VERIFY(err, 0 == platform_driver_register(&fastrpc_driver));
 	if (err)
 		goto register_bail;
diff --git a/drivers/cpuidle/lpm-levels.c b/drivers/cpuidle/lpm-levels.c
index e692f660..3c75997 100644
--- a/drivers/cpuidle/lpm-levels.c
+++ b/drivers/cpuidle/lpm-levels.c
@@ -83,7 +83,7 @@
 };
 
 static struct system_pm_ops *sys_pm_ops;
-
+static DEFINE_SPINLOCK(bc_timer_lock);
 
 struct lpm_cluster *lpm_root_node;
 
@@ -1029,6 +1029,7 @@
 	struct lpm_cluster_level *level = &cluster->levels[idx];
 	struct cpumask online_cpus, cpumask;
 	unsigned int cpu;
+	int ret = 0;
 
 	cpumask_and(&online_cpus, &cluster->num_children_in_sync,
 					cpu_online_mask);
@@ -1067,9 +1068,13 @@
 
 		clear_predict_history();
 		clear_cl_predict_history();
-		if (sys_pm_ops && sys_pm_ops->enter)
-			if ((sys_pm_ops->enter(&cpumask)))
+		if (sys_pm_ops && sys_pm_ops->enter) {
+			spin_lock(&bc_timer_lock);
+			ret = sys_pm_ops->enter(&cpumask);
+			spin_unlock(&bc_timer_lock);
+			if (ret)
 				return -EBUSY;
+		}
 	}
 	/* Notify cluster enter event after successfully config completion */
 	cluster_notify(cluster, level, true);
@@ -1202,8 +1207,11 @@
 	level = &cluster->levels[cluster->last_level];
 
 	if (level->notify_rpm)
-		if (sys_pm_ops && sys_pm_ops->exit)
+		if (sys_pm_ops && sys_pm_ops->exit) {
+			spin_lock(&bc_timer_lock);
 			sys_pm_ops->exit();
+			spin_unlock(&bc_timer_lock);
+		}
 
 	update_debug_pc_event(CLUSTER_EXIT, cluster->last_level,
 			cluster->num_children_in_sync.bits[0],
@@ -1298,6 +1306,7 @@
 {
 	int affinity_level = 0, state_id = 0, power_state = 0;
 	bool success = false;
+	int ret = 0;
 	/*
 	 * idx = 0 is the default LPM state
 	 */
@@ -1310,7 +1319,17 @@
 	}
 
 	if (from_idle && cpu->levels[idx].use_bc_timer) {
-		if (tick_broadcast_enter())
+		/*
+		 * tick_broadcast_enter can change the affinity of the
+		 * broadcast timer interrupt, during which interrupt will
+		 * be disabled and enabled back. To avoid system pm ops
+		 * doing any interrupt state save or restore in between
+		 * this window hold the lock.
+		 */
+		spin_lock(&bc_timer_lock);
+		ret = tick_broadcast_enter();
+		spin_unlock(&bc_timer_lock);
+		if (ret)
 			return success;
 	}
 
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index f8a987a..ee32e1a 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -184,6 +184,15 @@
 	  reporting the change in status of the KPDPWR_N line (connected to the
 	  power-key) as well as reset features.
 
+config INPUT_QTI_HAPTICS
+	tristate "Haptics support for QTI PMIC"
+	depends on MFD_SPMI_PMIC
+	help
+	  This option enables device driver support for the haptics peripheral
+	  found on Qualcomm Technologies, Inc. PMICs.  The haptics peripheral
+	  is capable of driving both LRA and ERM vibrators.  This module provides
+	  haptic feedback for user actions such as a long press on the touch screen.
+
 config INPUT_SPARCSPKR
 	tristate "SPARC Speaker support"
 	depends on PCI && SPARC64
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 149273c..c08ee8f 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -61,6 +61,7 @@
 obj-$(CONFIG_INPUT_PM8XXX_VIBRATOR)	+= pm8xxx-vibrator.o
 obj-$(CONFIG_INPUT_PMIC8XXX_PWRKEY)	+= pmic8xxx-pwrkey.o
 obj-$(CONFIG_INPUT_QPNP_POWER_ON)	+= qpnp-power-on.o
+obj-$(CONFIG_INPUT_QTI_HAPTICS)		+= qti-haptics.o
 obj-$(CONFIG_INPUT_POWERMATE)		+= powermate.o
 obj-$(CONFIG_INPUT_PWM_BEEPER)		+= pwm-beeper.o
 obj-$(CONFIG_INPUT_RB532_BUTTON)	+= rb532_button.o
diff --git a/drivers/input/misc/qti-haptics.c b/drivers/input/misc/qti-haptics.c
new file mode 100644
index 0000000..d63ced7
--- /dev/null
+++ b/drivers/input/misc/qti-haptics.c
@@ -0,0 +1,1471 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/hrtimer.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/uaccess.h>
+#include <linux/types.h>
+
+enum actutor_type {
+	ACT_LRA,
+	ACT_ERM,
+};
+
+enum lra_res_sig_shape {
+	RES_SIG_SINE,
+	RES_SIG_SQUARE,
+};
+
+enum lra_auto_res_mode {
+	AUTO_RES_MODE_ZXD,
+	AUTO_RES_MODE_QWD,
+};
+
+enum wf_src {
+	INT_WF_VMAX,
+	INT_WF_BUFFER,
+	EXT_WF_AUDIO,
+	EXT_WF_PWM,
+};
+
+enum haptics_custom_effect_param {
+	CUSTOM_DATA_EFFECT_IDX,
+	CUSTOM_DATA_TIMEOUT_SEC_IDX,
+	CUSTOM_DATA_TIMEOUT_MSEC_IDX,
+	CUSTOM_DATA_LEN,
+};
+
+/* common definitions */
+#define HAP_BRAKE_PATTERN_MAX		4
+#define HAP_WAVEFORM_BUFFER_MAX		8
+#define HAP_VMAX_MV_DEFAULT		1800
+#define HAP_VMAX_MV_MAX			3596
+#define HAP_ILIM_MA_DEFAULT		400
+#define HAP_ILIM_MA_MAX			800
+#define HAP_PLAY_RATE_US_DEFAULT	5715
+#define HAP_PLAY_RATE_US_MAX		20475
+#define HAP_PLAY_RATE_US_LSB		5
+#define VMAX_MIN_PLAY_TIME_US		20000
+#define HAP_SC_DET_MAX_COUNT		5
+#define HAP_SC_DET_TIME_US		1000000
+#define FF_EFFECT_COUNT_MAX		32
+
+/* haptics module register definitions */
+#define REG_HAP_STATUS1			0x0A
+#define HAP_SC_DET_BIT			BIT(3)
+#define HAP_BUSY_BIT			BIT(1)
+
+#define REG_HAP_EN_CTL1			0x46
+#define HAP_EN_BIT			BIT(7)
+
+#define REG_HAP_EN_CTL2			0x48
+#define HAP_AUTO_STANDBY_EN_BIT		BIT(1)
+#define HAP_BRAKE_EN_BIT		BIT(0)
+
+#define REG_HAP_EN_CTL3			0x4A
+#define HAP_HBRIDGE_EN_BIT		BIT(7)
+#define HAP_PWM_SIGNAL_EN_BIT		BIT(6)
+#define HAP_ILIM_EN_BIT			BIT(5)
+#define HAP_ILIM_CC_EN_BIT		BIT(4)
+#define HAP_AUTO_RES_RBIAS_EN_BIT	BIT(3)
+#define HAP_DAC_EN_BIT			BIT(2)
+#define HAP_ZX_HYST_EN_BIT		BIT(1)
+#define HAP_PWM_CTL_EN_BIT		BIT(0)
+
+#define REG_HAP_AUTO_RES_CTRL		0x4B
+#define HAP_AUTO_RES_EN_BIT		BIT(7)
+#define HAP_SEL_AUTO_RES_PERIOD		BIT(6)
+#define HAP_AUTO_RES_CNT_ERR_DELTA_MASK	GENMASK(5, 4)
+#define HAP_AUTO_RES_CNT_ERR_DELTA_SHIFT	4
+#define HAP_AUTO_RES_ERR_RECOVERY_BIT	BIT(3)
+#define HAP_AUTO_RES_EN_DLY_MASK	GENMASK(2, 0)
+#define AUTO_RES_CNT_ERR_DELTA(x)	(x << HAP_AUTO_RES_CNT_ERR_DELTA_SHIFT)
+#define AUTO_RES_EN_DLY(x)		x
+
+#define REG_HAP_CFG1			0x4C
+#define REG_HAP_CFG2			0x4D
+#define HAP_LRA_RES_TYPE_BIT		BIT(0)
+
+#define REG_HAP_SEL			0x4E
+#define HAP_WF_SOURCE_MASK		GENMASK(5, 4)
+#define HAP_WF_SOURCE_SHIFT		4
+#define HAP_WF_TRIGGER_BIT		BIT(0)
+#define HAP_WF_SOURCE_VMAX		(0 << HAP_WF_SOURCE_SHIFT)
+#define HAP_WF_SOURCE_BUFFER		(1 << HAP_WF_SOURCE_SHIFT)
+#define HAP_WF_SOURCE_AUDIO		(2 << HAP_WF_SOURCE_SHIFT)
+#define HAP_WF_SOURCE_PWM		(3 << HAP_WF_SOURCE_SHIFT)
+
+#define REG_HAP_AUTO_RES_CFG		0x4F
+#define HAP_AUTO_RES_MODE_BIT		BIT(7)
+#define HAP_AUTO_RES_MODE_SHIFT		7
+#define HAP_AUTO_RES_CAL_DURATON_MASK	GENMASK(6, 5)
+#define HAP_CAL_EOP_EN_BIT		BIT(3)
+#define HAP_CAL_PERIOD_MASK		GENMASK(2, 0)
+#define HAP_CAL_OPT3_EVERY_8_PERIOD	2
+
+#define REG_HAP_SLEW_CFG		0x50
+#define REG_HAP_VMAX_CFG		0x51
+#define HAP_VMAX_SIGN_BIT		BIT(7)
+#define HAP_VMAX_OVD_BIT		BIT(6)
+#define HAP_VMAX_MV_MASK		GENMASK(5, 1)
+#define HAP_VMAX_MV_SHIFT		1
+#define HAP_VMAX_MV_LSB			116
+
+#define REG_HAP_ILIM_CFG		0x52
+#define REG_HAP_SC_DEB_CFG		0x53
+#define REG_HAP_RATE_CFG1		0x54
+#define REG_HAP_RATE_CFG2		0x55
+#define REG_HAP_INTERNAL_PWM		0x56
+#define REG_HAP_EXTERNAL_PWM		0x57
+#define REG_HAP_PWM			0x58
+
+#define REG_HAP_SC_CLR			0x59
+#define HAP_SC_CLR_BIT			BIT(0)
+
+#define REG_HAP_ZX_CFG			0x5A
+#define HAP_ZX_DET_DEB_MASK		GENMASK(2, 0)
+#define ZX_DET_DEB_10US			0
+#define ZX_DET_DEB_20US			1
+#define ZX_DET_DEB_40US			2
+#define ZX_DET_DEB_80US			3
+
+#define REG_HAP_BRAKE			0x5C
+#define HAP_BRAKE_PATTERN_MASK		0x3
+#define HAP_BRAKE_PATTERN_SHIFT		2
+
+#define REG_HAP_WF_REPEAT		0x5E
+#define HAP_WF_REPEAT_MASK		GENMASK(6, 4)
+#define HAP_WF_REPEAT_SHIFT		4
+#define HAP_WF_S_REPEAT_MASK		GENMASK(1, 0)
+
+#define REG_HAP_WF_S1			0x60
+#define HAP_WF_SIGN_BIT			BIT(7)
+#define HAP_WF_OVD_BIT			BIT(6)
+#define HAP_WF_AMP_BIT			GENMASK(5, 1)
+#define HAP_WF_AMP_SHIFT		1
+
+#define REG_HAP_PLAY			0x70
+#define HAP_PLAY_BIT			BIT(7)
+
+#define REG_HAP_SEC_ACCESS		0xD0
+
+struct qti_hap_effect {
+	int			id;
+	u8			*pattern;
+	int			pattern_length;
+	u16			play_rate_us;
+	u8			wf_repeat_n;
+	u8			wf_s_repeat_n;
+	u8			brake[HAP_BRAKE_PATTERN_MAX];
+	int			brake_pattern_length;
+	bool			brake_en;
+	bool			lra_auto_res_disable;
+};
+
+struct qti_hap_play_info {
+	struct qti_hap_effect	*effect;
+	u16			vmax_mv;
+	int			length_us;
+	int			playing_pos;
+	bool			playing_pattern;
+};
+
+struct qti_hap_config {
+	enum actutor_type	act_type;
+	enum lra_res_sig_shape	lra_shape;
+	enum lra_auto_res_mode	lra_auto_res_mode;
+	enum wf_src		ext_src;
+	u16			vmax_mv;
+	u16			ilim_ma;
+	u16			play_rate_us;
+	bool			lra_allow_variable_play_rate;
+	bool			use_ext_wf_src;
+};
+
+struct qti_hap_chip {
+	struct platform_device		*pdev;
+	struct device			*dev;
+	struct regmap			*regmap;
+	struct input_dev		*input_dev;
+	struct pwm_device		*pwm_dev;
+	struct qti_hap_config		config;
+	struct qti_hap_play_info	play;
+	struct qti_hap_effect		*predefined;
+	struct qti_hap_effect		constant;
+	struct regulator		*vdd_supply;
+	struct hrtimer			stop_timer;
+	spinlock_t			bus_lock;
+	ktime_t				last_sc_time;
+	int				play_irq;
+	int				sc_irq;
+	int				effects_count;
+	int				sc_det_count;
+	u16				reg_base;
+	bool				perm_disable;
+	bool				play_irq_en;
+	bool				vdd_enabled;
+};
+
+static int wf_repeat[8] = {1, 2, 4, 8, 16, 32, 64, 128};
+static int wf_s_repeat[4] = {1, 2, 4, 8};
+
+static inline bool is_secure(u8 addr)
+{
+	return ((addr & 0xFF) > 0xD0);
+}
+
+static int qti_haptics_read(struct qti_hap_chip *chip,
+			u8 addr, u8 *val, int len)
+{
+	int rc = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chip->bus_lock, flags);
+
+	rc = regmap_bulk_read(chip->regmap, chip->reg_base + addr, val, len);
+	if (rc < 0)
+		dev_err(chip->dev, "Reading addr 0x%x failed, rc=%d\n",
+				addr, rc);
+	spin_unlock_irqrestore(&chip->bus_lock, flags);
+
+	return rc;
+}
+
+static int qti_haptics_write(struct qti_hap_chip *chip,
+		u8 addr, u8 *val, int len)
+{
+	int rc = 0, i;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chip->bus_lock, flags);
+	if (is_secure(addr)) {
+		for (i = 0; i < len; i++) {
+			rc = regmap_write(chip->regmap,
+					chip->reg_base + REG_HAP_SEC_ACCESS,
+					0xA5);
+			if (rc < 0) {
+				dev_err(chip->dev, "write SEC_ACCESS failed, rc=%d\n",
+						rc);
+				goto unlock;
+			}
+
+			rc = regmap_write(chip->regmap,
+					chip->reg_base + addr + i, val[i]);
+			if (rc < 0) {
+				dev_err(chip->dev, "write val 0x%x to addr 0x%x failed, rc=%d\n",
+						val[i], addr + i, rc);
+				goto unlock;
+			}
+		}
+	} else {
+		if (len > 1)
+			rc = regmap_bulk_write(chip->regmap,
+					chip->reg_base + addr, val, len);
+		else
+			rc = regmap_write(chip->regmap,
+					chip->reg_base + addr, *val);
+
+			if (rc < 0)
+				dev_err(chip->dev, "write addr 0x%x failed, rc=%d\n",
+						addr, rc);
+	}
+
+	for (i = 0; i < len; i++)
+		dev_dbg(chip->dev, "Update addr 0x%x to val 0x%x\n",
+				addr + i, val[i]);
+
+unlock:
+	spin_unlock_irqrestore(&chip->bus_lock, flags);
+	return rc;
+}
+
+static int qti_haptics_masked_write(struct qti_hap_chip *chip, u8 addr,
+		u8 mask, u8 val)
+{
+	int rc;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chip->bus_lock, flags);
+	if (is_secure(addr)) {
+		rc = regmap_write(chip->regmap,
+				chip->reg_base + REG_HAP_SEC_ACCESS,
+				0xA5);
+		if (rc < 0) {
+			dev_err(chip->dev, "write SEC_ACCESS failed, rc=%d\n",
+					rc);
+			goto unlock;
+		}
+	}
+
+	rc = regmap_update_bits(chip->regmap, chip->reg_base + addr, mask, val);
+	if (rc < 0)
+		dev_err(chip->dev, "Update addr 0x%x to val 0x%x with mask 0x%x failed, rc=%d\n",
+				addr, val, mask, rc);
+
+	dev_dbg(chip->dev, "Update addr 0x%x to val 0x%x with mask 0x%x\n",
+			addr, val, mask);
+unlock:
+	spin_unlock_irqrestore(&chip->bus_lock, flags);
+
+	return rc;
+}
+
+static void construct_constant_waveform_in_pattern(
+		struct qti_hap_play_info *play)
+{
+	struct qti_hap_chip *chip = container_of(play,
+			struct qti_hap_chip, play);
+	struct qti_hap_config *config = &chip->config;
+	struct qti_hap_effect *effect = play->effect;
+	int total_samples, samples, left, magnitude, i, j, k;
+	int delta = INT_MAX, delta_min = INT_MAX;
+
+	/* Using play_rate_us in config for constant waveform */
+	effect->play_rate_us = config->play_rate_us;
+	total_samples = play->length_us / effect->play_rate_us;
+	left = play->length_us % effect->play_rate_us;
+
+	if (total_samples <= HAP_WAVEFORM_BUFFER_MAX) {
+		effect->pattern_length = total_samples;
+		effect->wf_s_repeat_n = 0;
+		effect->wf_repeat_n = 0;
+	} else {
+		/*
+		 * Find a closest setting to achieve the constant waveform
+		 * with the required length by using buffer waveform source:
+		 * play_length_us = pattern_length * wf_s_repeat_n
+		 *		* wf_repeat_n * play_rate_us
+		 */
+		for (i = 0; i < ARRAY_SIZE(wf_repeat); i++) {
+			for (j = 0; j < ARRAY_SIZE(wf_s_repeat); j++) {
+				for (k = 1; k <= HAP_WAVEFORM_BUFFER_MAX; k++) {
+					samples = k * wf_s_repeat[j] *
+						wf_repeat[i];
+					delta = abs(total_samples - samples);
+					if (delta < delta_min) {
+						delta_min = delta;
+						effect->pattern_length = k;
+						effect->wf_s_repeat_n = j;
+						effect->wf_repeat_n = i;
+					}
+					if (samples > total_samples)
+						break;
+				}
+			}
+		}
+	}
+
+	if (left > 0 && effect->pattern_length < HAP_WAVEFORM_BUFFER_MAX)
+		effect->pattern_length++;
+
+	play->length_us = effect->pattern_length * effect->play_rate_us;
+	dev_dbg(chip->dev, "total_samples = %d, pattern_length = %d, wf_s_repeat = %d, wf_repeat = %d\n",
+			total_samples, effect->pattern_length,
+			wf_s_repeat[effect->wf_s_repeat_n],
+			wf_repeat[effect->wf_repeat_n]);
+
+	for (i = 0; i < effect->pattern_length; i++) {
+		magnitude = play->vmax_mv / HAP_VMAX_MV_LSB;
+		effect->pattern[i] = (u8)magnitude << HAP_WF_AMP_SHIFT;
+	}
+}
+
+static int qti_haptics_config_wf_buffer(struct qti_hap_chip *chip)
+{
+	struct qti_hap_play_info *play = &chip->play;
+	struct qti_hap_effect *effect = play->effect;
+	u8 addr, pattern[HAP_WAVEFORM_BUFFER_MAX] = {0};
+	int rc = 0;
+	size_t len;
+
+	if (play->playing_pos == effect->pattern_length) {
+		dev_dbg(chip->dev, "pattern playing done\n");
+		return 0;
+	}
+
+	if (effect->pattern_length - play->playing_pos
+			>= HAP_WAVEFORM_BUFFER_MAX)
+		len = HAP_WAVEFORM_BUFFER_MAX;
+	else
+		len = effect->pattern_length - play->playing_pos;
+
+	dev_dbg(chip->dev, "copy %d bytes start from %d\n",
+			(int)len, play->playing_pos);
+	memcpy(pattern, &effect->pattern[play->playing_pos], len);
+
+	play->playing_pos += len;
+
+	addr = REG_HAP_WF_S1;
+	rc = qti_haptics_write(chip, REG_HAP_WF_S1, pattern,
+			HAP_WAVEFORM_BUFFER_MAX);
+	if (rc < 0)
+		dev_err(chip->dev, "Program WF_SAMPLE failed, rc=%d\n", rc);
+
+	return rc;
+}
+
+static int qti_haptics_config_wf_repeat(struct qti_hap_chip *chip)
+{
+	struct qti_hap_effect *effect = chip->play.effect;
+	u8 addr, mask, val;
+	int rc = 0;
+
+	addr = REG_HAP_WF_REPEAT;
+	mask = HAP_WF_REPEAT_MASK | HAP_WF_S_REPEAT_MASK;
+	val = effect->wf_repeat_n << HAP_WF_REPEAT_SHIFT;
+	val |= effect->wf_s_repeat_n;
+	rc = qti_haptics_masked_write(chip, addr, mask, val);
+	if (rc < 0)
+		dev_err(chip->dev, "Program WF_REPEAT failed, rc=%d\n", rc);
+
+	return rc;
+}
+
+static int qti_haptics_play(struct qti_hap_chip *chip, bool play)
+{
+	int rc = 0;
+	u8 val = play ? HAP_PLAY_BIT : 0;
+
+	rc = qti_haptics_write(chip,
+			REG_HAP_PLAY, &val, 1);
+	if (rc < 0)
+		dev_err(chip->dev, "%s playing haptics failed, rc=%d\n",
+				play ? "start" : "stop", rc);
+
+	return rc;
+}
+
+static int qti_haptics_module_en(struct qti_hap_chip *chip, bool en)
+{
+	int rc = 0;
+	u8 val = en ? HAP_EN_BIT : 0;
+
+	rc = qti_haptics_write(chip,
+			REG_HAP_EN_CTL1, &val, 1);
+	if (rc < 0)
+		dev_err(chip->dev, "%s haptics failed, rc=%d\n",
+				en ? "enable" : "disable", rc);
+
+
+	return rc;
+}
+
+static int qti_haptics_config_vmax(struct qti_hap_chip *chip, int vmax_mv)
+{
+	u8 addr, mask, val;
+	int rc;
+
+	addr = REG_HAP_VMAX_CFG;
+	mask = HAP_VMAX_MV_MASK;
+	val = (vmax_mv / HAP_VMAX_MV_LSB) << HAP_VMAX_MV_SHIFT;
+	rc = qti_haptics_masked_write(chip, addr, mask, val);
+	if (rc < 0)
+		dev_err(chip->dev, "write VMAX_CFG failed, rc=%d\n",
+				rc);
+
+	return rc;
+}
+
+static int qti_haptics_config_wf_src(struct qti_hap_chip *chip,
+						enum wf_src src)
+{
+	u8 addr, mask, val = 0;
+	int rc;
+
+	addr = REG_HAP_SEL;
+	mask = HAP_WF_SOURCE_MASK | HAP_WF_TRIGGER_BIT;
+	val = src << HAP_WF_SOURCE_SHIFT;
+	if (src == EXT_WF_AUDIO || src == EXT_WF_PWM)
+		val |= HAP_WF_TRIGGER_BIT;
+
+	rc = qti_haptics_masked_write(chip, addr, mask, val);
+	if (rc < 0)
+		dev_err(chip->dev, "set HAP_SEL failed, rc=%d\n", rc);
+
+	return rc;
+}
+
+static int qti_haptics_config_play_rate_us(struct qti_hap_chip *chip,
+						int play_rate_us)
+{
+	u8 addr, val[2];
+	int tmp, rc;
+
+	addr = REG_HAP_RATE_CFG1;
+	tmp = play_rate_us / HAP_PLAY_RATE_US_LSB;
+	val[0] = tmp & 0xff;
+	val[1] = (tmp >> 8) & 0xf;
+	rc = qti_haptics_write(chip, addr, val, 2);
+	if (rc < 0)
+		dev_err(chip->dev, "write play_rate failed, rc=%d\n", rc);
+
+	return rc;
+}
+
+static int qti_haptics_config_brake(struct qti_hap_chip *chip, u8 *brake)
+{
+	u8 addr, mask, val;
+	int i, rc;
+	bool en = true;
+
+	addr = REG_HAP_BRAKE;
+	for (val = 0, i = 0; i < HAP_BRAKE_PATTERN_MAX; i++)
+		val |= (brake[i] & HAP_BRAKE_PATTERN_MASK) <<
+			i * HAP_BRAKE_PATTERN_SHIFT;
+
+	rc = qti_haptics_write(chip, addr, &val, 1);
+	if (rc < 0) {
+		dev_err(chip->dev, "write brake pattern failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	if (val == 0)
+		en = false;
+
+	/* Set BRAKE_EN only if brake pattern is non-zero */
+	addr = REG_HAP_EN_CTL2;
+	mask = HAP_BRAKE_EN_BIT;
+	val = en;
+	rc = qti_haptics_masked_write(chip, addr, mask, val);
+	if (rc < 0)
+		dev_err(chip->dev, "set EN_CTL2 failed, rc=%d\n", rc);
+
+	return rc;
+}
+
+static int qti_haptics_lra_auto_res_enable(struct qti_hap_chip *chip, bool en)
+{
+	int rc;
+	u8 addr, val, mask;
+
+	addr = REG_HAP_AUTO_RES_CTRL;
+	mask = HAP_AUTO_RES_EN_BIT;
+	val = en ? HAP_AUTO_RES_EN_BIT : 0;
+	rc = qti_haptics_masked_write(chip, addr, mask, val);
+	if (rc < 0)
+		dev_err(chip->dev, "set AUTO_RES_CTRL failed, rc=%d\n", rc);
+
+	return rc;
+}
+
+static int qti_haptics_load_constant_waveform(struct qti_hap_chip *chip)
+{
+	struct qti_hap_play_info *play = &chip->play;
+	struct qti_hap_config *config = &chip->config;
+	int rc = 0;
+
+	rc = qti_haptics_module_en(chip, true);
+	if (rc < 0)
+		return rc;
+
+	/*
+	 * Using VMAX waveform source if playing length is >= 20ms,
+	 * otherwise using buffer waveform source and calculate the
+	 * pattern length and repeating times to achieve accurate
+	 * playing time accuracy.
+	 */
+	if (play->length_us >= VMAX_MIN_PLAY_TIME_US) {
+		rc = qti_haptics_config_vmax(chip, play->vmax_mv);
+		if (rc < 0)
+			return rc;
+
+		/* Enable Auto-Resonance when VMAX wf-src is selected */
+		if (config->act_type == ACT_LRA) {
+			rc = qti_haptics_lra_auto_res_enable(chip, true);
+			if (rc < 0)
+				return rc;
+		}
+
+		/* Set WF_SOURCE to VMAX */
+		rc = qti_haptics_config_wf_src(chip, INT_WF_VMAX);
+		if (rc < 0)
+			return rc;
+
+		play->playing_pattern = false;
+	} else {
+		rc = qti_haptics_config_vmax(chip, config->vmax_mv);
+		if (rc < 0)
+			return rc;
+
+		play->effect = &chip->constant;
+		play->playing_pos = 0;
+		/* Format and config waveform in patterns */
+		construct_constant_waveform_in_pattern(play);
+		rc = qti_haptics_config_wf_buffer(chip);
+		if (rc < 0)
+			return rc;
+
+		rc = qti_haptics_config_wf_repeat(chip);
+		if (rc < 0)
+			return rc;
+
+		/* Set WF_SOURCE to buffer */
+		rc = qti_haptics_config_wf_src(chip, INT_WF_BUFFER);
+		if (rc < 0)
+			return rc;
+
+		play->playing_pattern = true;
+	}
+
+	return 0;
+}
+
+static int qti_haptics_load_predefined_effect(struct qti_hap_chip *chip,
+		int effect_idx)
+{
+	struct qti_hap_play_info *play = &chip->play;
+	struct qti_hap_config *config = &chip->config;
+	int rc = 0;
+
+	if (effect_idx >= chip->effects_count)
+		return -EINVAL;
+
+	play->effect = &chip->predefined[effect_idx];
+	play->playing_pos = 0;
+
+	rc = qti_haptics_module_en(chip, true);
+	if (rc < 0)
+		return rc;
+
+	rc = qti_haptics_config_vmax(chip, play->vmax_mv);
+	if (rc < 0)
+		return rc;
+
+	rc = qti_haptics_config_play_rate_us(chip, play->effect->play_rate_us);
+	if (rc < 0)
+		return rc;
+
+	if (config->act_type == ACT_LRA) {
+		rc = qti_haptics_lra_auto_res_enable(chip,
+				!play->effect->lra_auto_res_disable);
+		if (rc < 0)
+			return rc;
+	}
+
+	/* Set brake pattern in the effect */
+	rc = qti_haptics_config_brake(chip, play->effect->brake);
+	if (rc < 0)
+		return rc;
+
+	rc = qti_haptics_config_wf_buffer(chip);
+	if (rc < 0)
+		return rc;
+
+	rc = qti_haptics_config_wf_repeat(chip);
+	if (rc < 0)
+		return rc;
+
+	/* Set WF_SOURCE to buffer */
+	rc = qti_haptics_config_wf_src(chip, INT_WF_BUFFER);
+	if (rc < 0)
+		return rc;
+
+	play->playing_pattern = true;
+
+	return 0;
+}
+
+static irqreturn_t qti_haptics_play_irq_handler(int irq, void *data)
+{
+	struct qti_hap_chip *chip = (struct qti_hap_chip *)data;
+	struct qti_hap_play_info *play = &chip->play;
+	struct qti_hap_effect *effect = play->effect;
+	int rc;
+
+	dev_dbg(chip->dev, "play_irq triggered\n");
+	if (play->playing_pos == effect->pattern_length) {
+		dev_dbg(chip->dev, "waveform playing done\n");
+		qti_haptics_play(chip, false);
+		if (chip->play_irq_en) {
+			disable_irq_nosync(chip->play_irq);
+			chip->play_irq_en = false;
+		}
+
+		goto handled;
+	}
+
+	/* Config to play remaining patterns */
+	rc = qti_haptics_config_wf_repeat(chip);
+	if (rc < 0)
+		goto handled;
+
+	rc = qti_haptics_config_wf_buffer(chip);
+	if (rc < 0)
+		goto handled;
+
+handled:
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t qti_haptics_sc_irq_handler(int irq, void *data)
+{
+	struct qti_hap_chip *chip = (struct qti_hap_chip *)data;
+	u8 addr, val;
+	ktime_t temp;
+	s64 sc_delta_time_us;
+	int rc;
+
+	dev_dbg(chip->dev, "sc_irq triggered\n");
+	addr = REG_HAP_STATUS1;
+	rc = qti_haptics_read(chip, addr, &val, 1);
+	if (rc < 0) {
+		dev_err(chip->dev, "read HAP_STATUS1 failed, rc=%d\n", rc);
+		goto handled;
+	}
+
+	if (!(val & HAP_SC_DET_BIT))
+		goto handled;
+
+	temp = ktime_get();
+	sc_delta_time_us = ktime_us_delta(temp, chip->last_sc_time);
+	chip->last_sc_time = temp;
+
+	if (sc_delta_time_us > HAP_SC_DET_TIME_US)
+		chip->sc_det_count = 0;
+	else
+		chip->sc_det_count++;
+
+	addr = REG_HAP_SC_CLR;
+	val = HAP_SC_CLR_BIT;
+	rc = qti_haptics_write(chip, addr, &val, 1);
+	if (rc < 0) {
+		dev_err(chip->dev, "write SC_CLR failed, rc=%d\n", rc);
+		goto handled;
+	}
+
+	if (chip->sc_det_count > HAP_SC_DET_MAX_COUNT) {
+		rc = qti_haptics_module_en(chip, false);
+		if (rc < 0)
+			goto handled;
+
+		dev_crit(chip->dev, "Short circuit persists, disable haptics\n");
+		chip->perm_disable = true;
+	}
+
+handled:
+	return IRQ_HANDLED;
+}
+
+static inline void get_play_length(struct qti_hap_play_info *play,
+		int *length_us)
+{
+	struct qti_hap_effect *effect = play->effect;
+	int tmp;
+
+	tmp = effect->pattern_length * effect->play_rate_us;
+	tmp *= wf_s_repeat[effect->wf_s_repeat_n];
+	tmp *= wf_repeat[effect->wf_repeat_n];
+	if (effect->brake_en)
+		tmp += effect->play_rate_us * effect->brake_pattern_length;
+
+	*length_us = tmp;
+}
+
+static int qti_haptics_upload_effect(struct input_dev *dev,
+		struct ff_effect *effect, struct ff_effect *old)
+{
+	struct qti_hap_chip *chip = input_get_drvdata(dev);
+	struct qti_hap_config *config = &chip->config;
+	struct qti_hap_play_info *play = &chip->play;
+	int rc = 0, tmp, i;
+	s16 level, data[CUSTOM_DATA_LEN];
+
+	if (chip->vdd_supply && !chip->vdd_enabled) {
+		rc = regulator_enable(chip->vdd_supply);
+		if (rc < 0) {
+			dev_err(chip->dev, "Enable VDD supply failed, rc=%d\n",
+					rc);
+			return rc;
+		}
+		chip->vdd_enabled = true;
+	}
+
+	switch (effect->type) {
+	case FF_CONSTANT:
+		play->length_us = effect->replay.length * USEC_PER_MSEC;
+		level = effect->u.constant.level;
+		tmp = level * config->vmax_mv;
+		play->vmax_mv = tmp / 0x7fff;
+		dev_dbg(chip->dev, "upload constant effect, length = %dus, vmax_mv=%d\n",
+				play->length_us, play->vmax_mv);
+
+		rc = qti_haptics_load_constant_waveform(chip);
+		if (rc < 0) {
+			dev_err(chip->dev, "Play constant waveform failed, rc=%d\n",
+					rc);
+			goto disable_vdd;
+		}
+		break;
+
+	case FF_PERIODIC:
+		if (chip->effects_count == 0) {
+			rc = -EINVAL;
+			goto disable_vdd;
+		}
+
+		if (effect->u.periodic.waveform != FF_CUSTOM) {
+			dev_err(chip->dev, "Only accept custom waveforms\n");
+			rc = -EINVAL;
+			goto disable_vdd;
+		}
+
+		level = effect->u.periodic.magnitude;
+		tmp = level * config->vmax_mv;
+		play->vmax_mv = tmp / 0x7fff;
+
+		if (copy_from_user(data, effect->u.periodic.custom_data,
+					sizeof(s16) * CUSTOM_DATA_LEN)) {
+			rc = -EFAULT;
+			goto disable_vdd;
+		}
+
+		for (i = 0; i < chip->effects_count; i++)
+			if (chip->predefined[i].id ==
+					data[CUSTOM_DATA_EFFECT_IDX])
+				break;
+
+		if (i == chip->effects_count) {
+			dev_err(chip->dev, "predefined effect %d is NOT supported\n",
+					data[0]);
+			rc = -EINVAL;
+			goto disable_vdd;
+		}
+
+		dev_dbg(chip->dev, "upload effect %d, vmax_mv=%d\n",
+				chip->predefined[i].id, play->vmax_mv);
+		rc = qti_haptics_load_predefined_effect(chip, i);
+		if (rc < 0) {
+			dev_err(chip->dev, "Play predefined effect %d failed, rc=%d\n",
+					chip->predefined[i].id, rc);
+			goto disable_vdd;
+		}
+
+		get_play_length(play, &play->length_us);
+		data[CUSTOM_DATA_TIMEOUT_SEC_IDX] =
+			play->length_us / USEC_PER_SEC;
+		data[CUSTOM_DATA_TIMEOUT_MSEC_IDX] =
+			(play->length_us % USEC_PER_SEC) / USEC_PER_MSEC;
+
+		/*
+		 * Copy the custom data contains the play length back to
+		 * userspace so that the userspace client can wait and
+		 * send stop playing command after it's done.
+		 */
+		if (copy_to_user(effect->u.periodic.custom_data, data,
+					sizeof(s16) * CUSTOM_DATA_LEN)) {
+			rc = -EFAULT;
+			goto disable_vdd;
+		}
+		break;
+
+	default:
+		dev_err(chip->dev, "Unsupported effect type: %d\n",
+				effect->type);
+		break;
+	}
+
+	return 0;
+disable_vdd:
+	if (chip->vdd_supply && chip->vdd_enabled) {
+		rc = regulator_disable(chip->vdd_supply);
+		if (rc < 0) {
+			dev_err(chip->dev, "Disable VDD supply failed, rc=%d\n",
+					rc);
+			return rc;
+		}
+		chip->vdd_enabled = false;
+	}
+	return rc;
+}
+
+static int qti_haptics_playback(struct input_dev *dev, int effect_id, int val)
+{
+	struct qti_hap_chip *chip = input_get_drvdata(dev);
+	struct qti_hap_play_info *play = &chip->play;
+	s64 secs;
+	unsigned long nsecs;
+	int rc = 0;
+
+	dev_dbg(chip->dev, "playback, val = %d\n", val);
+	if (!!val) {
+		rc = qti_haptics_play(chip, true);
+		if (rc < 0)
+			return rc;
+
+		if (play->playing_pattern) {
+			if (!chip->play_irq_en) {
+				enable_irq(chip->play_irq);
+				chip->play_irq_en = true;
+			}
+		} else {
+			if (chip->play_irq_en) {
+				disable_irq_nosync(chip->play_irq);
+				chip->play_irq_en = false;
+			}
+			secs = play->length_us / USEC_PER_SEC;
+			nsecs = (play->length_us % USEC_PER_SEC) *
+				NSEC_PER_USEC;
+			hrtimer_start(&chip->stop_timer, ktime_set(secs, nsecs),
+					HRTIMER_MODE_REL);
+		}
+	} else {
+		play->length_us = 0;
+		rc = qti_haptics_play(chip, false);
+		if (rc < 0)
+			return rc;
+
+		rc = qti_haptics_module_en(chip, false);
+		if (rc < 0)
+			return rc;
+
+		if (chip->play_irq_en) {
+			disable_irq_nosync(chip->play_irq);
+			chip->play_irq_en = false;
+		}
+	}
+
+	return rc;
+}
+
+static int qti_haptics_erase(struct input_dev *dev, int effect_id)
+{
+	struct qti_hap_chip *chip = input_get_drvdata(dev);
+	int rc = 0;
+
+	if (chip->vdd_supply && chip->vdd_enabled) {
+		rc = regulator_disable(chip->vdd_supply);
+		if (rc < 0) {
+			dev_err(chip->dev, "Disable VDD supply failed, rc=%d\n",
+					rc);
+			return rc;
+		}
+		chip->vdd_enabled = false;
+	}
+
+	return rc;
+}
+
+static int qti_haptics_hw_init(struct qti_hap_chip *chip)
+{
+	struct qti_hap_config *config = &chip->config;
+	u8 addr, val, mask;
+	int rc = 0;
+
+	/* Config actuator type */
+	addr = REG_HAP_CFG1;
+	val = config->act_type;
+	rc = qti_haptics_write(chip, addr, &val, 1);
+	if (rc < 0) {
+		dev_err(chip->dev, "write actuator type failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	/* Config ilim_ma */
+	addr = REG_HAP_ILIM_CFG;
+	val = config->ilim_ma == 400 ? 0 : 1;
+	rc = qti_haptics_write(chip, addr, &val, 1);
+	if (rc < 0) {
+		dev_err(chip->dev, "write ilim_ma failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	/* Set HAP_EN_CTL3 */
+	addr = REG_HAP_EN_CTL3;
+	val = HAP_HBRIDGE_EN_BIT | HAP_PWM_SIGNAL_EN_BIT | HAP_ILIM_EN_BIT |
+		HAP_ILIM_CC_EN_BIT | HAP_AUTO_RES_RBIAS_EN_BIT |
+		HAP_DAC_EN_BIT | HAP_PWM_CTL_EN_BIT;
+	rc = qti_haptics_write(chip, addr, &val, 1);
+	if (rc < 0) {
+		dev_err(chip->dev, "set EN_CTL3 failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	/* Set ZX_CFG */
+	addr = REG_HAP_ZX_CFG;
+	mask = HAP_ZX_DET_DEB_MASK;
+	val = ZX_DET_DEB_80US;
+	rc = qti_haptics_masked_write(chip, addr, mask, val);
+	if (rc < 0) {
+		dev_err(chip->dev, "write ZX_CFG failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	/*
+	 * Config play rate: this is the resonance period for LRA,
+	 * or the play duration of each waveform sample for ERM.
+	 */
+	rc = qti_haptics_config_play_rate_us(chip, config->play_rate_us);
+	if (rc < 0)
+		return rc;
+
+	/* Set external waveform source if it's used */
+	if (config->use_ext_wf_src) {
+		rc = qti_haptics_config_wf_src(chip, config->ext_src);
+		if (rc < 0)
+			return rc;
+	}
+
+	/*
+	 * Skip configurations below for ERM actuator
+	 * as they're only for LRA actuators
+	 */
+	if (config->act_type == ACT_ERM)
+		return 0;
+
+	addr = REG_HAP_CFG2;
+	val = config->lra_shape;
+	rc = qti_haptics_write(chip, addr, &val, 1);
+	if (rc < 0) {
+		dev_err(chip->dev, "write lra_sig_shape failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	addr = REG_HAP_AUTO_RES_CFG;
+	mask = HAP_AUTO_RES_MODE_BIT | HAP_CAL_EOP_EN_BIT | HAP_CAL_PERIOD_MASK;
+	val = config->lra_auto_res_mode << HAP_AUTO_RES_MODE_SHIFT;
+	val |= HAP_CAL_EOP_EN_BIT | HAP_CAL_OPT3_EVERY_8_PERIOD;
+	rc = qti_haptics_masked_write(chip, addr, mask, val);
+	if (rc < 0) {
+		dev_err(chip->dev, "set AUTO_RES_CFG failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	addr = REG_HAP_AUTO_RES_CTRL;
+	val = HAP_AUTO_RES_EN_BIT | HAP_SEL_AUTO_RES_PERIOD |
+		AUTO_RES_CNT_ERR_DELTA(2) | HAP_AUTO_RES_ERR_RECOVERY_BIT |
+		AUTO_RES_EN_DLY(4);
+	rc = qti_haptics_write(chip, addr, &val, 1);
+	if (rc < 0) {
+		dev_err(chip->dev, "set AUTO_RES_CTRL failed, rc=%d\n",
+				rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+static enum hrtimer_restart qti_hap_stop_timer(struct hrtimer *timer)
+{
+	struct qti_hap_chip *chip = container_of(timer, struct qti_hap_chip,
+			stop_timer);
+	int rc;
+
+	chip->play.length_us = 0;
+	rc = qti_haptics_play(chip, false);
+	if (rc < 0) {
+		dev_err(chip->dev, "Stop playing failed, rc=%d\n", rc);
+		goto err_out;
+	}
+
+	rc = qti_haptics_module_en(chip, false);
+	if (rc < 0)
+		dev_err(chip->dev, "Disable module failed, rc=%d\n", rc);
+err_out:
+	return HRTIMER_NORESTART;
+}
+
+static int qti_haptics_parse_dt(struct qti_hap_chip *chip)
+{
+	struct qti_hap_config *config = &chip->config;
+	const struct device_node *node = chip->dev->of_node;
+	struct device_node *child_node;
+	struct qti_hap_effect *effect;
+	const char *str;
+	int rc = 0, tmp, i = 0, j;
+	u8 val;
+
+	rc = of_property_read_u32(node, "reg", &tmp);
+	if (rc < 0) {
+		dev_err(chip->dev, "Failed to reg base, rc=%d\n", rc);
+		return rc;
+	}
+	chip->reg_base = (u16)tmp;
+
+	chip->sc_irq = platform_get_irq_byname(chip->pdev, "hap-sc-irq");
+	if (chip->sc_irq < 0) {
+		dev_err(chip->dev, "Failed to get hap-sc-irq\n");
+		return chip->sc_irq;
+	}
+
+	chip->play_irq = platform_get_irq_byname(chip->pdev, "hap-play-irq");
+	if (chip->play_irq < 0) {
+		dev_err(chip->dev, "Failed to get hap-play-irq\n");
+		return chip->play_irq;
+	}
+
+	config->act_type = ACT_LRA;
+	rc = of_property_read_string(node, "qcom,actuator-type", &str);
+	if (!rc) {
+		if (strcmp(str, "erm") == 0) {
+			config->act_type = ACT_ERM;
+		} else if (strcmp(str, "lra") == 0) {
+			config->act_type = ACT_LRA;
+		} else {
+			dev_err(chip->dev, "Invalid actuator type: %s\n",
+					str);
+			return -EINVAL;
+		}
+	}
+
+	config->vmax_mv = HAP_VMAX_MV_DEFAULT;
+	rc = of_property_read_u32(node, "qcom,vmax-mv", &tmp);
+	if (!rc)
+		config->vmax_mv = (tmp > HAP_VMAX_MV_MAX) ?
+			HAP_VMAX_MV_MAX : tmp;
+
+	config->ilim_ma = HAP_ILIM_MA_DEFAULT;
+	rc = of_property_read_u32(node, "qcom,ilim-ma", &tmp);
+	if (!rc)
+		config->ilim_ma = (tmp >= HAP_ILIM_MA_MAX) ?
+			HAP_ILIM_MA_MAX : HAP_ILIM_MA_DEFAULT;
+
+	config->play_rate_us = HAP_PLAY_RATE_US_DEFAULT;
+	rc = of_property_read_u32(node, "qcom,play-rate-us", &tmp);
+	if (!rc)
+		config->play_rate_us = (tmp >= HAP_PLAY_RATE_US_MAX) ?
+			HAP_PLAY_RATE_US_MAX : tmp;
+
+	if (of_find_property(node, "qcom,external-waveform-source", NULL)) {
+		if (!of_property_read_string(node,
+				"qcom,external-waveform-source", &str)) {
+			if (strcmp(str, "audio") == 0) {
+				config->ext_src = EXT_WF_AUDIO;
+			} else if (strcmp(str, "pwm") == 0) {
+				config->ext_src = EXT_WF_PWM;
+			} else {
+				dev_err(chip->dev, "Invalid external waveform source: %s\n",
+						str);
+				return -EINVAL;
+			}
+		}
+		config->use_ext_wf_src = true;
+	}
+
+	if (of_find_property(node, "vdd-supply", NULL)) {
+		chip->vdd_supply = devm_regulator_get(chip->dev, "vdd");
+		if (IS_ERR(chip->vdd_supply)) {
+			rc = PTR_ERR(chip->vdd_supply);
+			if (rc != -EPROBE_DEFER)
+				dev_err(chip->dev, "Failed to get vdd regulator");
+			return rc;
+		}
+	}
+
+	if (config->act_type == ACT_LRA) {
+		config->lra_shape = RES_SIG_SINE;
+		rc = of_property_read_string(node,
+				"qcom,lra-resonance-sig-shape", &str);
+		if (!rc) {
+			if (strcmp(str, "sine") == 0) {
+				config->lra_shape = RES_SIG_SINE;
+			} else if (strcmp(str, "square") == 0) {
+				config->lra_shape = RES_SIG_SQUARE;
+			} else {
+				dev_err(chip->dev, "Invalid resonance signal shape: %s\n",
+						str);
+				return -EINVAL;
+			}
+		}
+
+		config->lra_allow_variable_play_rate = of_property_read_bool(
+				node, "qcom,lra-allow-variable-play-rate");
+
+		config->lra_auto_res_mode = AUTO_RES_MODE_ZXD;
+		rc = of_property_read_string(node,
+				"qcom,lra-auto-resonance-mode", &str);
+		if (!rc) {
+			if (strcmp(str, "zxd") == 0) {
+				config->lra_auto_res_mode = AUTO_RES_MODE_ZXD;
+			} else if (strcmp(str, "qwd") == 0) {
+				config->lra_auto_res_mode = AUTO_RES_MODE_QWD;
+			} else {
+				dev_err(chip->dev, "Invalid auto resonance mode: %s\n",
+						str);
+				return -EINVAL;
+			}
+		}
+	}
+
+	chip->constant.pattern = devm_kcalloc(chip->dev,
+			HAP_WAVEFORM_BUFFER_MAX,
+			sizeof(u8), GFP_KERNEL);
+	if (!chip->constant.pattern)
+		return -ENOMEM;
+
+	tmp = of_get_available_child_count(node);
+	if (tmp == 0)
+		return 0;
+
+	chip->predefined = devm_kcalloc(chip->dev, tmp,
+			sizeof(*chip->predefined), GFP_KERNEL);
+	if (!chip->predefined)
+		return -ENOMEM;
+
+	chip->effects_count = tmp;
+
+	for_each_available_child_of_node(node, child_node) {
+		effect = &chip->predefined[i++];
+		rc = of_property_read_u32(child_node, "qcom,effect-id",
+				&effect->id);
+		if (rc < 0) {
+			dev_err(chip->dev, "Read qcom,effect-id failed, rc=%d\n",
+					rc);
+			return rc;
+		}
+
+		rc = of_property_count_elems_of_size(child_node,
+				"qcom,wf-pattern", sizeof(u8));
+		if (rc < 0) {
+			dev_err(chip->dev, "Count qcom,wf-pattern property failed, rc=%d\n",
+					rc);
+			return rc;
+		} else if (rc == 0) {
+			dev_dbg(chip->dev, "qcom,wf-pattern has no data\n");
+			return -EINVAL;
+		}
+
+		effect->pattern_length = rc;
+		effect->pattern = devm_kcalloc(chip->dev,
+				effect->pattern_length, sizeof(u8), GFP_KERNEL);
+		if (!effect->pattern)
+			return -ENOMEM;
+
+		rc = of_property_read_u8_array(child_node, "qcom,wf-pattern",
+				effect->pattern, effect->pattern_length);
+		if (rc < 0) {
+			dev_err(chip->dev, "Read qcom,wf-pattern property failed, rc=%d\n",
+					rc);
+			return rc;
+		}
+
+		effect->play_rate_us = config->play_rate_us;
+		rc = of_property_read_u32(child_node, "qcom,wf-play-rate-us",
+				&tmp);
+		if (rc < 0)
+			dev_dbg(chip->dev, "Read qcom,wf-play-rate-us failed, rc=%d\n",
+					rc);
+		else
+			effect->play_rate_us = tmp;
+
+		if (config->act_type == ACT_LRA &&
+				!config->lra_allow_variable_play_rate &&
+				config->play_rate_us != effect->play_rate_us) {
+			dev_warn(chip->dev, "play rate should match with LRA resonance frequency\n");
+			effect->play_rate_us = config->play_rate_us;
+		}
+
+		rc = of_property_read_u32(child_node, "qcom,wf-repeat-count",
+				&tmp);
+		if (rc < 0) {
+			dev_dbg(chip->dev, "Read qcom,wf-repeat-count failed, rc=%d\n",
+					rc);
+		} else {
+			for (j = 0; j < ARRAY_SIZE(wf_repeat); j++)
+				if (tmp <= wf_repeat[j])
+					break;
+
+			effect->wf_repeat_n = j;
+		}
+
+		rc = of_property_read_u32(child_node, "qcom,wf-s-repeat-count",
+				&tmp);
+		if (rc < 0) {
+			dev_dbg(chip->dev, "Read qcom,wf-s-repeat-count failed, rc=%d\n",
+					rc);
+		} else {
+			for (j = 0; j < ARRAY_SIZE(wf_s_repeat); j++)
+				if (tmp <= wf_s_repeat[j])
+					break;
+
+			effect->wf_s_repeat_n = j;
+		}
+
+		effect->lra_auto_res_disable = of_property_read_bool(node,
+				"qcom,lra-auto-resonance-disable");
+
+		tmp = of_property_count_elems_of_size(child_node,
+				"qcom,wf-brake-pattern", sizeof(u8));
+		if (tmp <= 0)
+			continue;
+
+		if (tmp > HAP_BRAKE_PATTERN_MAX) {
+			dev_err(chip->dev, "wf-brake-pattern shouldn't be more than %d bytes\n",
+					HAP_BRAKE_PATTERN_MAX);
+			return -EINVAL;
+		}
+
+		rc = of_property_read_u8_array(child_node,
+				"qcom,wf-brake-pattern", effect->brake, tmp);
+		if (rc < 0) {
+			dev_err(chip->dev, "Failed to get wf-brake-pattern, rc=%d\n",
+					rc);
+			return rc;
+		}
+
+		effect->brake_pattern_length = tmp;
+		for (j = tmp - 1; j >= 0; j--) {
+			if (effect->brake[j] != 0)
+				break;
+			effect->brake_pattern_length--;
+		}
+
+		for (val = 0, j = 0; j < effect->brake_pattern_length; j++)
+			val |= (effect->brake[j] & HAP_BRAKE_PATTERN_MASK)
+				<< j * HAP_BRAKE_PATTERN_SHIFT;
+
+		effect->brake_en = (val != 0);
+	}
+
+	return 0;
+}
+
+static int qti_haptics_probe(struct platform_device *pdev)
+{
+	struct qti_hap_chip *chip;
+	struct input_dev *input_dev;
+	struct ff_device *ff;
+	int rc = 0, effect_count_max;
+
+	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	input_dev = devm_input_allocate_device(&pdev->dev);
+	if (!input_dev)
+		return -ENOMEM;
+
+	chip->pdev = pdev;
+	chip->dev = &pdev->dev;
+	chip->regmap = dev_get_regmap(chip->dev->parent, NULL);
+	if (!chip->regmap) {
+		dev_err(chip->dev, "Failed to get regmap handle\n");
+		return -ENXIO;
+	}
+
+	rc = qti_haptics_parse_dt(chip);
+	if (rc < 0) {
+		dev_err(chip->dev, "parse device-tree failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	spin_lock_init(&chip->bus_lock);
+
+	rc = qti_haptics_hw_init(chip);
+	if (rc < 0) {
+		dev_err(chip->dev, "parse device-tree failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	rc = devm_request_threaded_irq(chip->dev, chip->play_irq, NULL,
+			qti_haptics_play_irq_handler,
+			IRQF_ONESHOT, "hap_play_irq", chip);
+	if (rc < 0) {
+		dev_err(chip->dev, "request play-irq failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	disable_irq(chip->play_irq);
+	chip->play_irq_en = false;
+
+	rc = devm_request_threaded_irq(chip->dev, chip->sc_irq, NULL,
+			qti_haptics_sc_irq_handler,
+			IRQF_ONESHOT, "hap_sc_irq", chip);
+	if (rc < 0) {
+		dev_err(chip->dev, "request sc-irq failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	hrtimer_init(&chip->stop_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	chip->stop_timer.function = qti_hap_stop_timer;
+
+	input_dev->name = "vibrator";
+	input_set_drvdata(input_dev, chip);
+	chip->input_dev = input_dev;
+
+	input_set_capability(input_dev, EV_FF, FF_CONSTANT);
+	if (chip->effects_count != 0) {
+		input_set_capability(input_dev, EV_FF, FF_PERIODIC);
+		input_set_capability(input_dev, EV_FF, FF_CUSTOM);
+	}
+
+	if (chip->effects_count + 1 > FF_EFFECT_COUNT_MAX)
+		effect_count_max = chip->effects_count + 1;
+	else
+		effect_count_max = FF_EFFECT_COUNT_MAX;
+	rc = input_ff_create(input_dev, effect_count_max);
+	if (rc < 0) {
+		dev_err(chip->dev, "create FF input device failed, rc=%d\n",
+				rc);
+		return rc;
+	}
+
+	ff = input_dev->ff;
+	ff->upload = qti_haptics_upload_effect;
+	ff->playback = qti_haptics_playback;
+	ff->erase = qti_haptics_erase;
+
+	rc = input_register_device(input_dev);
+	if (rc < 0) {
+		dev_err(chip->dev, "register input device failed, rc=%d\n",
+				rc);
+		goto destroy_ff;
+	}
+
+	dev_set_drvdata(chip->dev, chip);
+	return 0;
+
+destroy_ff:
+	input_ff_destroy(chip->input_dev);
+	return rc;
+}
+
+static int qti_haptics_remove(struct platform_device *pdev)
+{
+	struct qti_hap_chip *chip = dev_get_drvdata(&pdev->dev);
+
+	input_ff_destroy(chip->input_dev);
+	dev_set_drvdata(chip->dev, NULL);
+
+	return 0;
+}
+
+static const struct of_device_id haptics_match_table[] = {
+	{ .compatible = "qcom,haptics" },
+	{ .compatible = "qcom,pm660-haptics" },
+	{ .compatible = "qcom,pm8150b-haptics" },
+	{},
+};
+
+static struct platform_driver qti_haptics_driver = {
+	.driver		= {
+		.name = "qcom,haptics",
+		.of_match_table = haptics_match_table,
+	},
+	.probe		= qti_haptics_probe,
+	.remove		= qti_haptics_remove,
+};
+module_platform_driver(qti_haptics_driver);
+
+MODULE_DESCRIPTION("QTI haptics driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_platform.c b/drivers/media/platform/msm/vidc/msm_vidc_platform.c
index 6fc1afb..f975409 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_platform.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_platform.c
@@ -120,7 +120,7 @@
 	},
 	{
 		.key = "qcom,max-secure-instances",
-		.value = 5,
+		.value = 2,
 	},
 	{
 		.key = "qcom,max-hw-load",
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index 2f64594..6909bd1 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -1455,7 +1455,7 @@
 	 * Statically choose the GPIOs for mapping to PDC. Dynamic mux mapping
 	 * is very difficult.
 	 */
-	for (i = 0; i < pctrl->soc->n_pdc_mux_out; i++) {
+	for (i = 0; i < pctrl->soc->n_gpio_mux_in; i++) {
 		unsigned int irq;
 		struct irq_data *d;
 		struct msm_gpio_mux_input *gpio_in =
diff --git a/drivers/pinctrl/qcom/pinctrl-sdxpoorwills.c b/drivers/pinctrl/qcom/pinctrl-sdxpoorwills.c
index c5f1307..c3081cb 100644
--- a/drivers/pinctrl/qcom/pinctrl-sdxpoorwills.c
+++ b/drivers/pinctrl/qcom/pinctrl-sdxpoorwills.c
@@ -50,6 +50,7 @@
 		.intr_cfg_reg = REG_BASE + 0x8 + REG_SIZE * id,		\
 		.intr_status_reg = REG_BASE + 0xc + REG_SIZE * id,	\
 		.intr_target_reg = REG_BASE + 0x8 + REG_SIZE * id,	\
+		.dir_conn_reg = REG_BASE + 0xab000,\
 		.mux_bit = 2,			\
 		.pull_bit = 0,			\
 		.drv_bit = 6,			\
@@ -64,6 +65,7 @@
 		.intr_polarity_bit = 1,		\
 		.intr_detection_bit = 2,	\
 		.intr_detection_width = 2,	\
+		.dir_conn_en_bit = 8,		\
 	}
 
 #define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv)	\
@@ -1151,7 +1153,7 @@
 	{42, 80},
 	{43, 82},
 	{44, 83},
-	{45, 84},
+	{45, 84, 1},
 	{46, 86},
 	{47, 87},
 	{48, 88},
@@ -1196,6 +1198,17 @@
 	{0, 195},
 };
 
+static struct msm_dir_conn sdxpoorwills_dir_conn[] = {
+	{0, 220},
+	{0, 219},
+	{0, 218},
+	{0, 217},
+	{0, 216},
+	{0, 215},
+	{0, 214},
+	{0, 213},
+};
+
 static const struct msm_pinctrl_soc_data sdxpoorwills_pinctrl = {
 	.pins = sdxpoorwills_pins,
 	.npins = ARRAY_SIZE(sdxpoorwills_pins),
@@ -1209,6 +1222,9 @@
 	.n_pdc_mux_out = ARRAY_SIZE(sdxpoorwills_mux_out),
 	.n_pdc_mux_offset = 20,
 	.ngpios = 100,
+	.dir_conn_irq_base = 220,
+	.dir_conn = sdxpoorwills_dir_conn,
+	.n_dir_conns = ARRAY_SIZE(sdxpoorwills_dir_conn),
 };
 
 static int sdxpoorwills_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
index 736c0fb..2212b00 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
@@ -908,6 +908,20 @@
 	return 0;
 }
 
+static int __ipa_rt_validate_rule_id(u16 rule_id)
+{
+	if (!rule_id)
+		return 0;
+
+	if ((rule_id < ipahal_get_rule_id_hi_bit()) ||
+		(rule_id >= ((ipahal_get_rule_id_hi_bit()<<1)-1))) {
+		IPAERR_RL("Invalid rule_id provided 0x%x\n",
+			rule_id);
+		return -EPERM;
+	}
+
+	return 0;
+}
 static int __ipa_rt_validate_hndls(const struct ipa_rt_rule *rule,
 				struct ipa3_hdr_entry **hdr,
 				struct ipa3_hdr_proc_ctx_entry **proc_ctx)
@@ -1023,6 +1037,8 @@
 	if (__ipa_rt_validate_hndls(rule, &hdr, &proc_ctx))
 		goto error;
 
+	if (__ipa_rt_validate_rule_id(rule_id))
+		goto error;
 
 	tbl = __ipa_add_rt_tbl(ip, name);
 	if (tbl == NULL || (tbl->cookie != IPA_RT_TBL_COOKIE)) {
diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c
index 56a09c6..e3e4f2b 100644
--- a/drivers/power/supply/qcom/qpnp-smb2.c
+++ b/drivers/power/supply/qcom/qpnp-smb2.c
@@ -985,6 +985,7 @@
 	POWER_SUPPLY_PROP_CURRENT_NOW,
 	POWER_SUPPLY_PROP_CURRENT_QNOVO,
 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
+	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
 	POWER_SUPPLY_PROP_TEMP,
 	POWER_SUPPLY_PROP_TECHNOLOGY,
 	POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED,
@@ -1076,6 +1077,10 @@
 		val->intval = get_client_vote(chg->fcc_votable,
 					      BATT_PROFILE_VOTER);
 		break;
+	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
+		val->intval = get_client_vote(chg->fcc_votable,
+					      FG_ESR_VOTER);
+		break;
 	case POWER_SUPPLY_PROP_TECHNOLOGY:
 		val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
 		break;
@@ -1183,6 +1188,12 @@
 		chg->batt_profile_fcc_ua = val->intval;
 		vote(chg->fcc_votable, BATT_PROFILE_VOTER, true, val->intval);
 		break;
+	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
+		if (val->intval)
+			vote(chg->fcc_votable, FG_ESR_VOTER, true, val->intval);
+		else
+			vote(chg->fcc_votable, FG_ESR_VOTER, false, 0);
+		break;
 	case POWER_SUPPLY_PROP_SET_SHIP_MODE:
 		/* Not in ship mode as long as the device is active */
 		if (!val->intval)
diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h
index 3b8bc1f..729118d 100644
--- a/drivers/power/supply/qcom/smb-lib.h
+++ b/drivers/power/supply/qcom/smb-lib.h
@@ -71,6 +71,7 @@
 #define MOISTURE_VOTER			"MOISTURE_VOTER"
 #define HVDCP2_ICL_VOTER		"HVDCP2_ICL_VOTER"
 #define OV_VOTER			"OV_VOTER"
+#define FG_ESR_VOTER			"FG_ESR_VOTER"
 
 #define VCONN_MAX_ATTEMPTS	3
 #define OTG_MAX_ATTEMPTS	3
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 0ae6979..4dfd8d3 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -897,17 +897,16 @@
 		req = lrbp->cmd->request;
 	else
 		return 0;
-	/*
-	 * Right now ICE do not support variable dun but can be
-	 * taken as future enhancement
-	 * if (bio_dun(req->bio)) {
-	 *      dun @bio can be split, so we have to adjust offset
-	 *      *dun = bio_dun(req->bio);
-	 * } else
-	 */
+
+	/* Use request LBA or given dun as the DUN value */
 	if (req->bio) {
-		*dun = req->bio->bi_iter.bi_sector;
-		*dun >>= UFS_QCOM_ICE_TR_DATA_UNIT_4_KB;
+		if (bio_dun(req->bio)) {
+			/* dun @bio can be split, so we have to adjust offset */
+			*dun = bio_dun(req->bio);
+		} else {
+			*dun = req->bio->bi_iter.bi_sector;
+			*dun >>= UFS_QCOM_ICE_TR_DATA_UNIT_4_KB;
+		}
 	}
 
 	ret = ufs_qcom_ice_req_setup(host, lrbp->cmd, cc_index, enable);
diff --git a/drivers/soc/qcom/dcc.c b/drivers/soc/qcom/dcc.c
index bef0757..3f4ad5d 100644
--- a/drivers/soc/qcom/dcc.c
+++ b/drivers/soc/qcom/dcc.c
@@ -39,8 +39,6 @@
 #define dcc_readl(drvdata, off)						\
 	__raw_readl(drvdata->base + off)
 
-#define dcc_sram_writel(drvdata, val, off)				\
-	__raw_writel((val), drvdata->ram_base + off)
 #define dcc_sram_readl(drvdata, off)					\
 	__raw_readl(drvdata->ram_base + off)
 
@@ -129,6 +127,16 @@
 	uint64_t		xpu_addr;
 	uint32_t		xpu_unlock_count;
 };
+static int dcc_sram_writel(struct dcc_drvdata *drvdata,
+					uint32_t val, uint32_t off)
+{
+	if (unlikely(off > (drvdata->ram_size - 4)))
+		return -EINVAL;
+
+	__raw_writel((val), drvdata->ram_base + off);
+
+	return 0;
+}
 
 static int dcc_cfg_xpu(struct dcc_drvdata *drvdata, bool enable)
 {
@@ -277,12 +285,17 @@
 		if (!prev_addr || prev_addr != addr || prev_off > off) {
 			/* Check if we need to write link of prev entry */
 			if (link) {
-				dcc_sram_writel(drvdata, link, sram_offset);
+				ret = dcc_sram_writel(drvdata,
+							link, sram_offset);
+				if (ret)
+					goto overstep;
 				sram_offset += 4;
 			}
 
 			/* Write address */
-			dcc_sram_writel(drvdata, addr, sram_offset);
+			ret = dcc_sram_writel(drvdata, addr, sram_offset);
+			if (ret)
+				goto overstep;
 			sram_offset += 4;
 
 			/* Reset link and prev_off */
@@ -322,7 +335,9 @@
 			 ((entry->len << 8) & BM(8, 14))) << pos;
 
 		if (pos) {
-			dcc_sram_writel(drvdata, link, sram_offset);
+			ret = dcc_sram_writel(drvdata, link, sram_offset);
+			if (ret)
+				goto overstep;
 			sram_offset += 4;
 			link = 0;
 		}
@@ -332,12 +347,16 @@
 	}
 
 	if (link) {
-		dcc_sram_writel(drvdata, link, sram_offset);
+		ret = dcc_sram_writel(drvdata, link, sram_offset);
+		if (ret)
+			goto overstep;
 		sram_offset += 4;
 	}
 
 	/* Setting zero to indicate end of the list */
-	dcc_sram_writel(drvdata, 0, sram_offset);
+	ret = dcc_sram_writel(drvdata, 0, sram_offset);
+	if (ret)
+		goto overstep;
 	sram_offset += 4;
 
 	/* check if the data will overstep */
diff --git a/fs/crypto/fscrypt_ice.h b/fs/crypto/fscrypt_ice.h
index c540506..d448eae 100644
--- a/fs/crypto/fscrypt_ice.h
+++ b/fs/crypto/fscrypt_ice.h
@@ -21,7 +21,7 @@
 {
 	if (!inode->i_sb->s_cop)
 		return 0;
-	if (!inode->i_sb->s_cop->is_encrypted((struct inode *)inode))
+	if (!IS_ENCRYPTED((struct inode *)inode))
 	return 0;
 
 	return fscrypt_using_hardware_encryption(inode);
diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
index 03ff3aa..6563f88 100644
--- a/fs/crypto/fscrypt_private.h
+++ b/fs/crypto/fscrypt_private.h
@@ -105,7 +105,8 @@
 	    filenames_mode == FS_ENCRYPTION_MODE_SPECK128_256_CTS)
 		return true;
 
-	if (contents_mode == FS_ENCRYPTION_MODE_PRIVATE)
+	if (contents_mode == FS_ENCRYPTION_MODE_PRIVATE &&
+	    filenames_mode == FS_ENCRYPTION_MODE_AES_256_CTS)
 		return true;
 
 	return false;
diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
index 737b6fc..1866733 100644
--- a/fs/crypto/keyinfo.c
+++ b/fs/crypto/keyinfo.c
@@ -267,7 +267,7 @@
 
 static int fscrypt_data_encryption_mode(struct inode *inode)
 {
-	return fscrypt_should_be_processed_by_ice(inode) ?
+	return fscrypt_is_ice_capable(inode->i_sb) ?
 	FS_ENCRYPTION_MODE_PRIVATE : FS_ENCRYPTION_MODE_AES_256_XTS;
 }
 
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 30fa14a..ab72207 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1180,11 +1180,6 @@
 		EXT4_NAME_LEN;
 }
 
-static inline bool ext4_is_encrypted(struct inode *inode)
-{
-	return ext4_encrypted_inode(inode);
-}
-
 static const struct fscrypt_operations ext4_cryptops = {
 	.key_prefix		= "ext4:",
 	.get_context		= ext4_get_context,
@@ -1192,7 +1187,6 @@
 	.dummy_context		= ext4_dummy_context,
 	.empty_dir		= ext4_empty_dir,
 	.max_namelen		= ext4_max_namelen,
-	.is_encrypted       = ext4_is_encrypted,
 };
 #endif
 
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 9efe77e..062529c 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1548,9 +1548,9 @@
 				bio = NULL;
 				goto set_error_page;
 			}
+			if (bio_encrypted)
+				fscrypt_set_ice_dun(inode, bio, dun);
 		}
-		if (bio_encrypted)
-			fscrypt_set_ice_dun(inode, bio, dun);
 		if (bio_add_page(bio, page, blocksize, 0) < blocksize)
 			goto submit_and_realloc;
 
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index a7711d7..c850618 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1344,6 +1344,8 @@
 		seq_printf(seq, ",fsync_mode=%s", "posix");
 	else if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT)
 		seq_printf(seq, ",fsync_mode=%s", "strict");
+	else if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_NOBARRIER)
+		seq_printf(seq, ",fsync_mode=%s", "nobarrier");
 	return 0;
 }
 
@@ -1940,11 +1942,6 @@
 			inode->i_sb->s_blocksize : F2FS_NAME_LEN;
 }
 
-static inline bool f2fs_is_encrypted(struct inode *inode)
-{
-	return f2fs_encrypted_file(inode);
-}
-
 static const struct fscrypt_operations f2fs_cryptops = {
 	.key_prefix	= "f2fs:",
 	.get_context	= f2fs_get_context,
@@ -1952,7 +1949,6 @@
 	.dummy_context	= f2fs_dummy_context,
 	.empty_dir	= f2fs_empty_dir,
 	.max_namelen	= f2fs_max_namelen,
-	.is_encrypted = f2fs_is_encrypted,
 };
 #endif
 
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index 8f4e90c..7a7fce9 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -19,12 +19,9 @@
 
 struct fscrypt_ctx;
 
-/* iv sector for security/pfe/pfk_fscrypt.c and f2fs. sizeof is required
- * to accommodate 32 bit targets.
- */
+/* iv sector for security/pfe/pfk_fscrypt.c and f2fs */
 #define PG_DUN(i, p)                                            \
-	((((i)->i_ino & 0xffffffff) << (sizeof((i)->i_ino)/2)) | \
-				((p)->index & 0xffffffff))
+	(((((u64)(i)->i_ino) & 0xffffffff) << 32) | ((p)->index & 0xffffffff))
 
 struct fscrypt_info;
 
diff --git a/include/linux/fscrypt_supp.h b/include/linux/fscrypt_supp.h
index 32e2b6c..2f62d5b 100644
--- a/include/linux/fscrypt_supp.h
+++ b/include/linux/fscrypt_supp.h
@@ -29,7 +29,6 @@
 	bool (*dummy_context)(struct inode *);
 	bool (*empty_dir)(struct inode *);
 	unsigned (*max_namelen)(struct inode *);
-	bool (*is_encrypted)(struct inode *);
 };
 
 struct fscrypt_ctx {
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 3fbfe96..6b20f91 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2986,6 +2986,8 @@
 	return __skb_grow(skb, len);
 }
 
+#define rb_to_skb(rb) rb_entry_safe(rb, struct sk_buff, rbnode)
+
 #define skb_queue_walk(queue, skb) \
 		for (skb = (queue)->next;					\
 		     skb != (struct sk_buff *)(queue);				\
diff --git a/include/uapi/media/msmb_qca.h b/include/uapi/media/msmb_qca.h
index 02a6b1f..22b1006 100644
--- a/include/uapi/media/msmb_qca.h
+++ b/include/uapi/media/msmb_qca.h
@@ -1,16 +1,3 @@
-/* Copyright (c) 2018, The Linux Foundation.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
 #ifndef __UAPI_LINUX_MSMB_QCA402X_H
 #define __UAPI_LINUX_MSMB_QCA402X_H
 
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 91a909f..335b40e 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -10540,8 +10540,12 @@
 	rcu_read_lock();
 	sd = rcu_dereference_check_sched_domain(rq->sd);
 	if (sd) {
-		cpumask_and(&cpumask, nohz.idle_cpus_mask,
-			    sched_domain_span(sd));
+		if (energy_aware() && rq->misfit_task)
+			cpumask_andnot(&cpumask, nohz.idle_cpus_mask,
+				sched_domain_span(sd));
+		else
+			cpumask_and(&cpumask, nohz.idle_cpus_mask,
+				    sched_domain_span(sd));
 		cpumask_andnot(&cpumask, &cpumask,
 			    cpu_isolated_mask);
 		ilb = cpumask_first(&cpumask);
@@ -10552,7 +10556,7 @@
 		if (!energy_aware() ||
 		    (capacity_orig_of(cpu) ==
 		     cpu_rq(cpu)->rd->max_cpu_capacity.val ||
-		     cpu_overutilized(cpu))) {
+		     (cpu_overutilized(cpu) && rq->nr_running > 1))) {
 			cpumask_andnot(&cpumask, nohz.idle_cpus_mask,
 			    cpu_isolated_mask);
 			ilb = cpumask_first(&cpumask);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 59c1581..340a3db 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -889,12 +889,9 @@
 	now = jiffies;
 	next = now + HZ;
 
-	if (!(state & NUD_IN_TIMER)) {
-		if (neigh_probe_enable && (state & NUD_STALE))
-			neigh_dbg(2, "neigh %pK is still alive\n", neigh);
-		else
-			goto out;
-	}
+	if (!(state & NUD_IN_TIMER))
+		goto out;
+
 	if (state & NUD_REACHABLE) {
 		if (time_before_eq(now,
 				   neigh->confirmed + neigh->parms->reachable_time)) {
@@ -1185,10 +1182,7 @@
 		neigh_del_timer(neigh);
 		if (new & NUD_PROBE)
 			atomic_set(&neigh->probes, 0);
-		if (new & NUD_IN_TIMER || (
-			neigh_probe_enable &&
-			(neigh->tbl->family == AF_INET6) &&
-			(new & NUD_STALE)))
+		if (new & NUD_IN_TIMER)
 			neigh_add_timer(neigh, (jiffies +
 						((new & NUD_REACHABLE) ?
 						 neigh->parms->reachable_time :
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index f0fc835..c244b72 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4909,6 +4909,7 @@
 static void tcp_collapse_ofo_queue(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
+	u32 range_truesize, sum_tiny = 0;
 	struct sk_buff *skb, *head;
 	struct rb_node *p;
 	u32 start, end;
@@ -4927,6 +4928,7 @@
 	}
 	start = TCP_SKB_CB(skb)->seq;
 	end = TCP_SKB_CB(skb)->end_seq;
+	range_truesize = skb->truesize;
 
 	for (head = skb;;) {
 		skb = tcp_skb_next(skb, NULL);
@@ -4937,11 +4939,20 @@
 		if (!skb ||
 		    after(TCP_SKB_CB(skb)->seq, end) ||
 		    before(TCP_SKB_CB(skb)->end_seq, start)) {
-			tcp_collapse(sk, NULL, &tp->out_of_order_queue,
-				     head, skb, start, end);
+			/* Do not attempt collapsing tiny skbs */
+			if (range_truesize != head->truesize ||
+			    end - start >= SKB_WITH_OVERHEAD(SK_MEM_QUANTUM)) {
+				tcp_collapse(sk, NULL, &tp->out_of_order_queue,
+					     head, skb, start, end);
+			} else {
+				sum_tiny += range_truesize;
+				if (sum_tiny > sk->sk_rcvbuf >> 3)
+					return;
+			}
 			goto new_range;
 		}
 
+		range_truesize += skb->truesize;
 		if (unlikely(before(TCP_SKB_CB(skb)->seq, start)))
 			start = TCP_SKB_CB(skb)->seq;
 		if (after(TCP_SKB_CB(skb)->end_seq, end))
@@ -4956,6 +4967,7 @@
  * 2) not add too big latencies if thousands of packets sit there.
  *    (But if application shrinks SO_RCVBUF, we could still end up
  *     freeing whole queue here)
+ * 3) Drop at least 12.5 % of sk_rcvbuf to avoid malicious attacks.
  *
  * Return true if queue has shrunk.
  */
@@ -4963,20 +4975,26 @@
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct rb_node *node, *prev;
+	int goal;
 
 	if (RB_EMPTY_ROOT(&tp->out_of_order_queue))
 		return false;
 
 	NET_INC_STATS(sock_net(sk), LINUX_MIB_OFOPRUNED);
+	goal = sk->sk_rcvbuf >> 3;
 	node = &tp->ooo_last_skb->rbnode;
 	do {
 		prev = rb_prev(node);
 		rb_erase(node, &tp->out_of_order_queue);
+		goal -= rb_to_skb(node)->truesize;
 		tcp_drop(sk, rb_entry(node, struct sk_buff, rbnode));
-		sk_mem_reclaim(sk);
-		if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf &&
-		    !tcp_under_memory_pressure(sk))
-			break;
+		if (!prev || goal <= 0) {
+			sk_mem_reclaim(sk);
+			if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf &&
+			    !tcp_under_memory_pressure(sk))
+				break;
+			goal = sk->sk_rcvbuf >> 3;
+		}
 		node = prev;
 	} while (node);
 	tp->ooo_last_skb = rb_entry(prev, struct sk_buff, rbnode);
@@ -5011,6 +5029,9 @@
 	else if (tcp_under_memory_pressure(sk))
 		tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss);
 
+	if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf)
+		return 0;
+
 	tcp_collapse_ofo_queue(sk);
 	if (!skb_queue_empty(&sk->sk_receive_queue))
 		tcp_collapse(sk, &sk->sk_receive_queue, NULL,