Merge "ARM: dts: msm: Split system low power mode state id for sdxpoorwills"
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_watchdog.txt b/Documentation/devicetree/bindings/arm/msm/msm_watchdog.txt
index 53ad68e..cf13d34 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm_watchdog.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm_watchdog.txt
@@ -33,6 +33,7 @@
 - qcom,ipi-ping : (boolean) send keep alive ping to other cpus if present
 - qcom,wakeup-enable : (boolean) enable non secure watchdog to freeze / unfreeze
                         automatically across suspend / resume path.
+- qcom,scandump-size : size of scan dump memory region.
 
 Example:
 
diff --git a/Documentation/devicetree/bindings/bt-fm/fm.txt b/Documentation/devicetree/bindings/bt-fm/fm.txt
new file mode 100644
index 0000000..ed73e5d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/bt-fm/fm.txt
@@ -0,0 +1,29 @@
+Qti radio iris device
+
+-FM RX playback with no RDS
+
+   FM samples is filtered by external RF chips at baseband, then send to Riva-FM core through serial link.
+   FM signal is demodulated then audio L/R samples are stored inside memory.
+   FM Rx received samples data is connected to external audio codec.
+
+-Audio playback to FM TX
+
+  Used to play audio source  to FM TX.
+  FM TX module will read the audio samples from memory then modulated samples will be send through serial interface to external RF chip.
+
+-RX playback with RDS
+
+  FM Rx receive audio data along with RDS.
+
+-FM TX with RDS
+
+  Used to send RDS messages to external FM receiver.
+
+Required Properties:
+- compatible: "qcom,iris_fm"
+
+Example:
+        qcom,iris-fm {
+                compatible = "qcom,iris_fm";
+        };
+
diff --git a/Documentation/devicetree/bindings/display/bridge/lt9611.txt b/Documentation/devicetree/bindings/display/bridge/lt9611.txt
index 61688b5..419be2d 100644
--- a/Documentation/devicetree/bindings/display/bridge/lt9611.txt
+++ b/Documentation/devicetree/bindings/display/bridge/lt9611.txt
@@ -8,7 +8,7 @@
 	- lt,reset-gpio				Main reset gpio mapping
 
 
-	Optional properties:
+Optional properties:
 	- lt,hdmi-ps-gpio:			gpio mapping for HDMI PS
 	- lt,hdmi-en-gpio:			gpio mapping for HDMI EN
 
@@ -29,6 +29,7 @@
 	-- lt,supply-post-off-sleep: time to sleep (ms) after turning off
 
 	- lt,non-pluggable: Boolean to indicate if display is non pluggable.
+	- lt,preferred-mode: Preferred display mode.
 	- lt,customize-modes: Customized modes when it's non-pluggable display.
 	e.g. lt,customize-mode-id@0
 	-- lt,mode-h-active: Horizontal active pixels for this mode.
@@ -66,6 +67,8 @@
 		lt,reset-gpio = <&tlmm 134 0x0>;
 		lt,hdmi-ps-gpio = <&tlmm 136 0x0>;
 		lt,hdmi-en-gpio = <&tlmm 137 0x0>;
+		lt,non-pluggable;
+		lt,preferred-mode = "1920x1080";
 
 		vcc-supply = <&pm660l_l6>;
 		vdd-supply = <&pm660_l11>;
diff --git a/Documentation/devicetree/bindings/display/msm/sde.txt b/Documentation/devicetree/bindings/display/msm/sde.txt
index 4b4c274..0589165 100644
--- a/Documentation/devicetree/bindings/display/msm/sde.txt
+++ b/Documentation/devicetree/bindings/display/msm/sde.txt
@@ -78,6 +78,8 @@
 Optional properties:
 - clock-rate:		List of clock rates in Hz.
 - clock-max-rate:	List of maximum clock rate in Hz that this device supports.
+- connectors:		Specifies the connector components.
+- bridges:		Specifies the bridge components.
 - qcom,platform-supply-entries:	A node that lists the elements of the supply. There
 				can be more than one instance of this binding,
 				in which case the entry would be appended with
diff --git a/Documentation/devicetree/bindings/input/qpnp-power-on.txt b/Documentation/devicetree/bindings/input/qpnp-power-on.txt
index 33d0236..0f1d9e1 100644
--- a/Documentation/devicetree/bindings/input/qpnp-power-on.txt
+++ b/Documentation/devicetree/bindings/input/qpnp-power-on.txt
@@ -112,6 +112,9 @@
 				trigger during system shutdown case.
 - qcom,ps-hold-hard-reset-disable	Boolean property to disable PS_HOLD
 				POFF trigger during system hard reset case.
+- qcom,use-legacy-hard-reset-offset	Boolean property to support legacy
+				hard-reset offset of the PON_RB_SPARE register for
+				some (PON gen2) platforms.
 
 All the below properties are in the sub-node section (properties of the child
 node).
diff --git a/Documentation/devicetree/bindings/input/touchscreen/focaltech_ts.txt b/Documentation/devicetree/bindings/input/touchscreen/focaltech_ts.txt
index 4a1b751..0174e3d 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/focaltech_ts.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/focaltech_ts.txt
@@ -30,6 +30,7 @@
  - focaltech,keys 			: array of key code.
  - focaltech,key-y-coord 	: y coordinate for the keys.
  - focaltech,key-x-coords	: array of x coordinates for the keys.
+ - focaltech,wakeup-gestures-en	: enable wakeup gestures.
 
 Example:
 	i2c@f9923000{
diff --git a/Documentation/devicetree/bindings/pil/pil-blackghost.txt b/Documentation/devicetree/bindings/pil/pil-blackghost.txt
new file mode 100644
index 0000000..66cde5c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pil/pil-blackghost.txt
@@ -0,0 +1,33 @@
+Qualcomm Technologies Inc Blackghost(BG) PIL driver:
+
+Blackghost(BG) PIL driver provide interface to load and boot Blackghost(BG)
+SOC. Blackghost(BG) SOC is an external SOC which communicate to MSM via
+SPI. The PIL driver loads firmware into memory and invoke secure app via
+qseecom to transfer and handshake the boot process. Once Blackghost(BG) SOC
+is booted it raises ready interrupt which is handled by BG PIL driver, and
+this event is informed to other MSM drivers, other remote subsystem via
+notifier framework. The PIL driver also handles interrupt for the BG SOC
+crash upon arrival of which it reset and initiates ramdump collection for BG
+SOC.
+
+Required properties:
+- compatible:			Must be "qcom,PIL-blackghost"
+- qcom,firmware-name:		Base name of the firmware image.
+- qcom,bg2ap-status-gpio:	GPIO used by the blackghost to indicate status to the apps.
+- qcom,bg2ap-errfatal-gpio:	GPIO used by the blackghost to indicate software error to the apps.
+- qcom,ap2bg-status-gpio:	GPIO used by the apps to indicate its status to blackghost.
+- qcom,ap2bg-errfatal-gpio:	GPIO used by the apps to indicate blackghost about apps reset.
+
+Example:
+
+	qcom,blackghost {
+		compatible = "qcom,pil-blackghost";
+		qcom,firmware-name = "bgelf";
+
+		/* GPIO inputs from blackghost */
+		qcom,bg2ap-status-gpio = <&msm_gpio 97 0>;
+		qcom,bg2ap-errfatal-gpio = <&msm_gpio 95 0>;
+		/* GPIO output to blackghost */
+		qcom,ap2bg-status-gpio = <&msm_gpio 17 0>;
+		qcom,ap2bg-errfatal-gpio = <&msm_gpio 23 0>;
+	};
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
index 5034e9f..392ee7b 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
@@ -380,7 +380,7 @@
 	Value type: <u32>
 	Definition: Value in micro percentage for low temperature ESR tight
 		    filter. If this is not specified, then a default value of
-		    48829 (4.88 %) will be used. Lowest possible value is 1954
+		    30000 (3 %) will be used. Lowest possible value is 1954
 		    (0.19 %).
 
 - qcom,fg-esr-broad-lt-filter-micro-pct
@@ -388,9 +388,35 @@
 	Value type: <u32>
 	Definition: Value in micro percentage for low temperature ESR broad
 		    filter. If this is not specified, then a default value of
-		    148438 (14.84 %) will be used. Lowest possible value is
+		    30000 (3 %) will be used. Lowest possible value is
 		    1954 (0.19 %).
 
+- qcom,fg-esr-rt-filter-switch-temp
+	Usage:      optional
+	Value type: <u32>
+	Definition: Battery temperature threshold below which ESR relax
+		    filter coefficients will be applied after a certain
+		    number of delta battery temperature interrupts firing in
+		    an interval of time. This will be applied only when Qnovo
+		    is enabled. If this is not specified, then the default
+		    value used will be -100. Unit is in decidegC.
+
+- qcom,fg-esr-tight-rt-filter-micro-pct
+	Usage:      optional
+	Value type: <u32>
+	Definition: Value in micro percentage for relax temperature ESR tight
+		    filter. If this is not specified, then a default value of
+		    5860 will be used. Lowest possible value is 1954 (0.19 %).
+		    This will be applied only if Qnovo is enabled.
+
+- qcom,fg-esr-broad-rt-filter-micro-pct
+	Usage:      optional
+	Value type: <u32>
+	Definition: Value in micro percentage for relax temperature ESR broad
+		    filter. If this is not specified, then a default value of
+		    156250 will be used. Lowest possible value is 1954 (0.19 %).
+		    This will be applied only if Qnovo is enabled.
+
 - qcom,fg-auto-recharge-soc
 	Usage:      optional
 	Value type: <empty>
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index f56516c..f42fcd4 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -131,7 +131,7 @@
 KBUILD_CFLAGS	+=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
 KBUILD_AFLAGS	+=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float
 
-CHECKFLAGS	+= -D__arm__
+CHECKFLAGS	+= -D__arm__ -m32
 
 #Default value
 head-y		:= arch/arm/kernel/head$(MMUEXT).o
diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile
index 29151fc..b4bc69f 100644
--- a/arch/arm/boot/dts/qcom/Makefile
+++ b/arch/arm/boot/dts/qcom/Makefile
@@ -4,6 +4,10 @@
 	sdxpoorwills-mtp.dtb \
 	sdxpoorwills-cdp-256.dtb \
 	sdxpoorwills-mtp-256.dtb \
+	sdxpoorwills-dualwifi-cdp.dtb \
+	sdxpoorwills-dualwifi-mtp.dtb \
+	sdxpoorwills-pcie-ep-cdp-256.dtb \
+	sdxpoorwills-pcie-ep-mtp-256.dtb \
 	sdxpoorwills-pcie-ep-cdp.dtb \
 	sdxpoorwills-pcie-ep-mtp.dtb
 
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi
index ad1e6ca..b4e91ab 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-bus.dtsi
@@ -35,6 +35,14 @@
 		};
 
 		/*BCMs*/
+		bcm_acv: bcm-acv {
+			cell-id = <MSM_BUS_BCM_ACV>;
+			label = "ACV";
+			qcom,bcm-name = "ACV";
+			qcom,rscs = <&rsc_apps>;
+			qcom,bcm-dev;
+		};
+
 		bcm_alc: bcm-alc {
 			cell-id = <MSM_BUS_BCM_ALC>;
 			label = "ALC";
@@ -564,6 +572,15 @@
 			qcom,prio = <0>;
 		};
 
+		mas_alc: mas-alc {
+			cell-id = <MSM_BUS_MASTER_ALC>;
+			label = "mas-alc";
+			qcom,buswidth = <1>;
+			qcom,agg-ports = <1>;
+			qcom,bus-dev = <&fab_mc_virt>;
+			qcom,bcms = <&bcm_alc>;
+		};
+
 		/*Internal nodes*/
 
 		/*Slaves*/
@@ -583,7 +600,7 @@
 			qcom,buswidth = <4>;
 			qcom,agg-ports = <1>;
 			qcom,bus-dev = <&fab_mc_virt>;
-			qcom,bcms = <&bcm_mc0>;
+			qcom,bcms = <&bcm_mc0>, <&bcm_acv>;
 		};
 
 		slv_qns_llcc:slv-qns-llcc {
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-cdp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-cdp.dts
new file mode 100644
index 0000000..6909ef5
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-cdp.dts
@@ -0,0 +1,30 @@
+/* Copyright (c) 2017-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 "sdxpoorwills-dualwifi-cdp.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDXPOORWILLS DUAL-WIFI CDP";
+	compatible = "qcom,sdxpoorwills-cdp",
+		"qcom,sdxpoorwills", "qcom,cdp";
+	qcom,board-id = <1 0x105>;
+};
+
+&cnss_pcie {
+	qcom,is-dual-wifi-enabled;
+};
+
+&cnss_sdio {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-cdp.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-cdp.dtsi
new file mode 100644
index 0000000..8a7b771
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-cdp.dtsi
@@ -0,0 +1,13 @@
+/* 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 "sdxpoorwills-cdp.dtsi"
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-mtp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-mtp.dts
new file mode 100644
index 0000000..5fd7042
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-mtp.dts
@@ -0,0 +1,30 @@
+/* Copyright (c) 2017-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 "sdxpoorwills-dualwifi-mtp.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDXPOORWILLS DUAL-WIFI MTP";
+	compatible = "qcom,sdxpoorwills-mtp",
+		"qcom,sdxpoorwills", "qcom,mtp";
+	qcom,board-id = <8 0x104>;
+};
+
+&cnss_pcie {
+	qcom,is-dual-wifi-enabled;
+};
+
+&cnss_sdio {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-mtp.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-mtp.dtsi
new file mode 100644
index 0000000..4a2ece8c
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-mtp.dtsi
@@ -0,0 +1,13 @@
+/* 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 "sdxpoorwills-mtp.dtsi"
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dts
new file mode 100644
index 0000000..cbbf585
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.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 "sdxpoorwills-pcie-ep-cdp-256.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDXPOORWILLS(M) PCIE-EP CDP";
+	compatible = "qcom,sdxpoorwills-cdp",
+		"qcom,sdxpoorwills", "qcom,cdp";
+	qcom,board-id = <1 0x1>;
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dtsi
new file mode 100644
index 0000000..518d8a1
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dtsi
@@ -0,0 +1,34 @@
+/* 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 "sdxpoorwills-cdp.dtsi"
+
+&vbus_detect {
+	status = "okay";
+};
+
+&usb {
+	status = "okay";
+	extcon = <&vbus_detect>;
+};
+
+&pcie_ep {
+	status = "okay";
+};
+
+&pcie0 {
+	status = "disabled";
+};
+
+&mhi_device {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dts
index 52eaba3..2a2e496 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dts
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dts
@@ -12,32 +12,12 @@
 
 /dts-v1/;
 
-#include "sdxpoorwills-cdp.dtsi"
+#include "sdxpoorwills-pcie-ep-cdp.dtsi"
 
 / {
 	model = "Qualcomm Technologies, Inc. SDXPOORWILLS PCIE-EP CDP";
 	compatible = "qcom,sdxpoorwills-cdp",
 		"qcom,sdxpoorwills", "qcom,cdp";
-	qcom,board-id = <1 0x1>, <1 0x101>;
+	qcom,board-id = <1 0x106>;
 };
 
-&vbus_detect {
-	status = "okay";
-};
-
-&usb {
-	status = "okay";
-	extcon = <&vbus_detect>;
-};
-
-&pcie_ep {
-	status = "okay";
-};
-
-&pcie0 {
-	status = "disabled";
-};
-
-&mhi_device {
-	status = "okay";
-};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dtsi
new file mode 100644
index 0000000..518d8a1
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dtsi
@@ -0,0 +1,34 @@
+/* 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 "sdxpoorwills-cdp.dtsi"
+
+&vbus_detect {
+	status = "okay";
+};
+
+&usb {
+	status = "okay";
+	extcon = <&vbus_detect>;
+};
+
+&pcie_ep {
+	status = "okay";
+};
+
+&pcie0 {
+	status = "disabled";
+};
+
+&mhi_device {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dts
new file mode 100644
index 0000000..6b6aab5
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.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 "sdxpoorwills-pcie-ep-mtp-256.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDXPOORWILLS(M) PCIE-EP MTP";
+	compatible = "qcom,sdxpoorwills-mtp",
+		"qcom,sdxpoorwills", "qcom,mtp";
+	qcom,board-id = <8 0x1>;
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dtsi
new file mode 100644
index 0000000..eb544e6
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dtsi
@@ -0,0 +1,34 @@
+/* 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 "sdxpoorwills-mtp.dtsi"
+
+&vbus_detect {
+	status = "okay";
+};
+
+&usb {
+	status = "okay";
+	extcon = <&vbus_detect>;
+};
+
+&pcie_ep {
+	status = "okay";
+};
+
+&pcie0 {
+	status = "disabled";
+};
+
+&mhi_device {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp.dts
index b68e401..8c22348 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp.dts
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp.dts
@@ -12,32 +12,11 @@
 
 /dts-v1/;
 
-#include "sdxpoorwills-mtp.dtsi"
+#include "sdxpoorwills-pcie-ep-mtp.dtsi"
 
 / {
 	model = "Qualcomm Technologies, Inc. SDXPOORWILLS PCIE-EP MTP";
 	compatible = "qcom,sdxpoorwills-mtp",
 		"qcom,sdxpoorwills", "qcom,mtp";
-	qcom,board-id = <8 0x1>, <8 0x101>;
-};
-
-&vbus_detect {
-	status = "okay";
-};
-
-&usb {
-	status = "okay";
-	extcon = <&vbus_detect>;
-};
-
-&pcie_ep {
-	status = "okay";
-};
-
-&pcie0 {
-	status = "disabled";
-};
-
-&mhi_device {
-	status = "okay";
+	qcom,board-id = <8 0x105>;
 };
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp.dtsi
new file mode 100644
index 0000000..eb544e6
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp.dtsi
@@ -0,0 +1,34 @@
+/* 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 "sdxpoorwills-mtp.dtsi"
+
+&vbus_detect {
+	status = "okay";
+};
+
+&usb {
+	status = "okay";
+	extcon = <&vbus_detect>;
+};
+
+&pcie_ep {
+	status = "okay";
+};
+
+&pcie0 {
+	status = "disabled";
+};
+
+&mhi_device {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index b125e08..6e9bdd5 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -43,6 +43,16 @@
 			label = "sbl_mem";
 		};
 
+		flex_sec_apps_mem: flex_sec_apps_regions@8fcfd000 {
+			no-map;
+			reg = <0x8fcfd000 0x3000>;
+		};
+
+		access_control_mem: access_control_mem@8fc80000 {
+			no-map;
+			reg = <0x8fc80000 0x40000>;
+		};
+
 		hyp_region: hyp_region@8fc00000 {
 			no-map;
 			reg = <0x8fc00000 0x80000>;
@@ -823,6 +833,8 @@
 		qcom,mhi-event-ring-id-limits = <9 10>; /* start and end */
 		qcom,modem-cfg-emb-pipe-flt;
 		qcom,use-ipa-pm;
+		qcom,arm-smmu;
+		qcom,smmu-fast-map;
 		qcom,bandwidth-vote-for-ipa;
 		qcom,msm-bus,name = "ipa";
 		qcom,msm-bus,num-cases = <5>;
@@ -964,6 +976,32 @@
 			compatible = "qcom,smp2pgpio-map-ipa-1-in";
 			gpios = <&smp2pgpio_ipa_1_in 0 0>;
 		};
+
+		ipa_smmu_ap: ipa_smmu_ap {
+			compatible = "qcom,ipa-smmu-ap-cb";
+			qcom,smmu-s1-bypass;
+			iommus = <&apps_smmu 0x5E0 0x0>;
+			qcom,iova-mapping = <0x20000000 0x40000000>;
+			qcom,additional-mapping =
+				/* modem tables in IMEM */
+				<0x14686000 0x14686000 0x3000>;
+		};
+
+		ipa_smmu_wlan: ipa_smmu_wlan {
+			compatible = "qcom,ipa-smmu-wlan-cb";
+			qcom,smmu-s1-bypass;
+			iommus = <&apps_smmu 0x5E1 0x0>;
+			qcom,additional-mapping =
+				/* ipa-uc ram */
+				<0x1E60000 0x1E60000 0xA000>;
+		};
+
+		ipa_smmu_uc: ipa_smmu_uc {
+			compatible = "qcom,ipa-smmu-uc-cb";
+			qcom,smmu-s1-bypass;
+			iommus = <&apps_smmu 0x5E2 0x0>;
+			qcom,iova-mapping = <0x40000000 0x20000000>;
+		};
 	};
 
 	qmp_aop: qcom,qmp-aop@c300000 {
@@ -1142,12 +1180,12 @@
 			<0x36000 0x100>,
 			<0x3900000 0x300000>;
 		reg-names = "emac-base", "rgmii-base", "tlmm-central-base";
-		interrupts = <0 62 4>, <0 60 4>,
-			<0 45 4>, <0 49 4>,
-			<0 50 4>, <0 51 4>,
-			<0 52 4>, <0 53 4>,
-			<0 54 4>, <0 55 4>,
-			<0 56 4>, <0 57 4>;
+		interrupts-extended = <&pdc 0 62 4>, <&pdc 0 60 4>,
+			<&tlmm 84 2>, <&pdc 0 49 4>,
+			<&pdc 0 50 4>, <&pdc 0 51 4>,
+			<&pdc 0 52 4>, <&pdc 0 53 4>,
+			<&pdc 0 54 4>, <&pdc 0 55 4>,
+			<&pdc 0 56 4>, <&pdc 0 57 4>;
 		interrupt-names = "sbd-intr", "lpi-intr",
 			"wol-intr", "tx-ch0-intr",
 			"tx-ch1-intr", "tx-ch2-intr",
diff --git a/arch/arm/configs/msm8909w-perf_defconfig b/arch/arm/configs/msm8909w-perf_defconfig
index 7c10cdd..0c04f9c 100644
--- a/arch/arm/configs/msm8909w-perf_defconfig
+++ b/arch/arm/configs/msm8909w-perf_defconfig
@@ -259,6 +259,10 @@
 CONFIG_KEYBOARD_GPIO=y
 CONFIG_INPUT_JOYSTICK=y
 CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v26=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v26=y
+CONFIG_TOUCHSCREEN_FTS=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_QPNP_POWER_ON=y
 CONFIG_INPUT_UINPUT=y
@@ -421,10 +425,13 @@
 CONFIG_MSM_GLINK_PKT=y
 CONFIG_MSM_SUBSYSTEM_RESTART=y
 CONFIG_MSM_PIL=y
+CONFIG_MSM_PIL_SSR_GENERIC=y
+CONFIG_MSM_PIL_MSS_QDSP6V5=y
 CONFIG_MSM_EVENT_TIMER=y
 CONFIG_QTI_RPM_STATS_LOG=y
 CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
 CONFIG_MSM_BAM_DMUX=y
+CONFIG_QCOM_DEVFREQ_DEVBW=y
 CONFIG_IIO=y
 CONFIG_QCOM_SPMI_IADC=y
 CONFIG_QCOM_SPMI_VADC=y
diff --git a/arch/arm/configs/msm8909w_defconfig b/arch/arm/configs/msm8909w_defconfig
index 7c10cdd..0c04f9c 100644
--- a/arch/arm/configs/msm8909w_defconfig
+++ b/arch/arm/configs/msm8909w_defconfig
@@ -259,6 +259,10 @@
 CONFIG_KEYBOARD_GPIO=y
 CONFIG_INPUT_JOYSTICK=y
 CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v26=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v26=y
+CONFIG_TOUCHSCREEN_FTS=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_QPNP_POWER_ON=y
 CONFIG_INPUT_UINPUT=y
@@ -421,10 +425,13 @@
 CONFIG_MSM_GLINK_PKT=y
 CONFIG_MSM_SUBSYSTEM_RESTART=y
 CONFIG_MSM_PIL=y
+CONFIG_MSM_PIL_SSR_GENERIC=y
+CONFIG_MSM_PIL_MSS_QDSP6V5=y
 CONFIG_MSM_EVENT_TIMER=y
 CONFIG_QTI_RPM_STATS_LOG=y
 CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
 CONFIG_MSM_BAM_DMUX=y
+CONFIG_QCOM_DEVFREQ_DEVBW=y
 CONFIG_IIO=y
 CONFIG_QCOM_SPMI_IADC=y
 CONFIG_QCOM_SPMI_VADC=y
diff --git a/arch/arm/configs/msm8953-perf_defconfig b/arch/arm/configs/msm8953-perf_defconfig
index 722845e..9a88cb6 100644
--- a/arch/arm/configs/msm8953-perf_defconfig
+++ b/arch/arm/configs/msm8953-perf_defconfig
@@ -51,6 +51,7 @@
 CONFIG_ARCH_QCOM=y
 CONFIG_ARCH_MSM8953=y
 CONFIG_ARCH_MSM8937=y
+CONFIG_ARCH_MSM8917=y
 CONFIG_ARCH_SDM450=y
 # CONFIG_VDSO is not set
 CONFIG_SMP=y
@@ -291,6 +292,9 @@
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_VT is not set
 # CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_MSM_HS=y
 CONFIG_SERIAL_MSM_SMD=y
 CONFIG_DIAG_CHAR=y
 CONFIG_DIAG_USES_SMD=y
@@ -300,6 +304,7 @@
 CONFIG_MSM_ADSPRPC=y
 CONFIG_MSM_RDBG=m
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MSM_V2=y
 CONFIG_SPI=y
 CONFIG_SPI_QUP=y
 CONFIG_SPI_SPIDEV=y
@@ -385,6 +390,8 @@
 CONFIG_MSM_JPEGDMA=y
 CONFIG_MSM_VIDC_3X_V4L2=y
 CONFIG_MSM_VIDC_3X_GOVERNORS=y
+CONFIG_RADIO_IRIS=y
+CONFIG_RADIO_IRIS_TRANSPORT=y
 CONFIG_QCOM_KGSL=y
 CONFIG_FB=y
 CONFIG_FB_MSM=y
@@ -505,6 +512,7 @@
 CONFIG_QPNP_COINCELL=y
 CONFIG_QPNP_REVID=y
 CONFIG_USB_BAM=y
+CONFIG_MSM_RMNET_BAM=y
 CONFIG_MSM_MDSS_PLL=y
 CONFIG_REMOTE_SPINLOCK_MSM=y
 CONFIG_MAILBOX=y
@@ -545,6 +553,7 @@
 CONFIG_WCNSS_REGISTER_DUMP_ON_BITE=y
 CONFIG_QCOM_BIMC_BWMON=y
 CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
+CONFIG_DEVFREQ_SIMPLE_DEV=y
 CONFIG_QCOM_DEVFREQ_DEVBW=y
 CONFIG_SPDM_SCM=y
 CONFIG_DEVFREQ_SPDM=y
diff --git a/arch/arm/configs/msm8953_defconfig b/arch/arm/configs/msm8953_defconfig
index 26d9717..102b148 100644
--- a/arch/arm/configs/msm8953_defconfig
+++ b/arch/arm/configs/msm8953_defconfig
@@ -57,6 +57,7 @@
 CONFIG_ARCH_QCOM=y
 CONFIG_ARCH_MSM8953=y
 CONFIG_ARCH_MSM8937=y
+CONFIG_ARCH_MSM8917=y
 CONFIG_ARCH_SDM450=y
 # CONFIG_VDSO is not set
 CONFIG_SMP=y
@@ -300,8 +301,11 @@
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_VT is not set
 # CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_MSM=y
 CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_SERIAL_MSM_HS=y
 CONFIG_SERIAL_MSM_SMD=y
 CONFIG_DIAG_CHAR=y
 CONFIG_DIAG_USES_SMD=y
@@ -311,6 +315,7 @@
 CONFIG_MSM_ADSPRPC=y
 CONFIG_MSM_RDBG=m
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MSM_V2=y
 CONFIG_SPI=y
 CONFIG_SPI_QUP=y
 CONFIG_SPI_SPIDEV=y
@@ -396,6 +401,8 @@
 CONFIG_MSM_JPEGDMA=y
 CONFIG_MSM_VIDC_3X_V4L2=y
 CONFIG_MSM_VIDC_3X_GOVERNORS=y
+CONFIG_RADIO_IRIS=y
+CONFIG_RADIO_IRIS_TRANSPORT=y
 CONFIG_QCOM_KGSL=y
 CONFIG_FB=y
 CONFIG_FB_VIRTUAL=y
@@ -519,6 +526,7 @@
 CONFIG_QPNP_REVID=y
 CONFIG_USB_BAM=y
 CONFIG_MSM_EXT_DISPLAY=y
+CONFIG_MSM_RMNET_BAM=y
 CONFIG_MSM_MDSS_PLL=y
 CONFIG_REMOTE_SPINLOCK_MSM=y
 CONFIG_MAILBOX=y
@@ -565,6 +573,7 @@
 CONFIG_WCNSS_REGISTER_DUMP_ON_BITE=y
 CONFIG_QCOM_BIMC_BWMON=y
 CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
+CONFIG_DEVFREQ_SIMPLE_DEV=y
 CONFIG_QCOM_DEVFREQ_DEVBW=y
 CONFIG_SPDM_SCM=y
 CONFIG_DEVFREQ_SPDM=y
diff --git a/arch/arm/configs/sdxpoorwills-perf_defconfig b/arch/arm/configs/sdxpoorwills-perf_defconfig
index 32ff446..8d8e6d1 100644
--- a/arch/arm/configs/sdxpoorwills-perf_defconfig
+++ b/arch/arm/configs/sdxpoorwills-perf_defconfig
@@ -194,6 +194,7 @@
 # CONFIG_NET_VENDOR_SEEQ is not set
 # CONFIG_NET_VENDOR_SMSC is not set
 # CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_AT803X_PHY=y
 CONFIG_PPP=y
 CONFIG_PPP_ASYNC=y
 CONFIG_USB_USBNET=y
@@ -321,6 +322,7 @@
 CONFIG_ION_MSM=y
 CONFIG_GSI=y
 CONFIG_IPA3=y
+CONFIG_IPA_WDI_UNIFIED_API=y
 CONFIG_RMNET_IPA3=y
 CONFIG_ECM_IPA=y
 CONFIG_RNDIS_IPA=y
@@ -366,6 +368,7 @@
 CONFIG_MSM_PIL_SSR_GENERIC=y
 CONFIG_QCOM_COMMAND_DB=y
 CONFIG_MSM_PM=y
+CONFIG_QCOM_DCC_V2=y
 CONFIG_QTI_RPM_STATS_LOG=y
 CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
 CONFIG_EXTCON_QCOM_SPMI_MISC=y
diff --git a/arch/arm/configs/sdxpoorwills_defconfig b/arch/arm/configs/sdxpoorwills_defconfig
index a6063c8..f786337 100644
--- a/arch/arm/configs/sdxpoorwills_defconfig
+++ b/arch/arm/configs/sdxpoorwills_defconfig
@@ -186,6 +186,7 @@
 # CONFIG_NET_VENDOR_SEEQ is not set
 # CONFIG_NET_VENDOR_SMSC is not set
 # CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_AT803X_PHY=y
 CONFIG_PPP=y
 CONFIG_PPP_ASYNC=y
 CONFIG_USB_USBNET=y
@@ -326,6 +327,7 @@
 CONFIG_ION_MSM=y
 CONFIG_GSI=y
 CONFIG_IPA3=y
+CONFIG_IPA_WDI_UNIFIED_API=y
 CONFIG_RMNET_IPA3=y
 CONFIG_ECM_IPA=y
 CONFIG_RNDIS_IPA=y
@@ -371,6 +373,7 @@
 CONFIG_MSM_PIL_SSR_GENERIC=y
 CONFIG_QCOM_COMMAND_DB=y
 CONFIG_MSM_PM=y
+CONFIG_QCOM_DCC_V2=y
 CONFIG_QTI_RPM_STATS_LOG=y
 CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
 CONFIG_QCOM_DEVFREQ_DEVBW=y
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index cc75e7f..a92f511 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -165,6 +165,15 @@
 	  This enables support for the MSM8937 chipset. If you do not
 	  wish to build a kernel that runs on this chipset, say 'N' here.
 
+config ARCH_MSM8917
+	bool "Enable Support for Qualcomm Technologies Inc. MSM8917"
+	depends on ARCH_QCOM
+	select CPU_FREQ_QCOM
+	select COMMON_CLK_MSM
+	help
+	  This enables support for the MSM8917 chipset. If you do not
+	  wish to build a kernel that runs on this chipset, say 'N' here.
+
 config ARCH_SDM450
 	bool "Enable Support for Qualcomm Technologies Inc. SDM450"
 	depends on ARCH_QCOM
diff --git a/arch/arm64/boot/dts/qcom/8909w-pm660.dtsi b/arch/arm64/boot/dts/qcom/8909w-pm660.dtsi
index 211e28c..c9996f8 100644
--- a/arch/arm64/boot/dts/qcom/8909w-pm660.dtsi
+++ b/arch/arm64/boot/dts/qcom/8909w-pm660.dtsi
@@ -326,6 +326,10 @@
 		};
 	};
 
+	qcom,power-on@800 {
+		qcom,use-legacy-hard-reset-offset;
+	};
+
 	pm660_rradc: rradc@4500 {
 		compatible = "qcom,rradc";
 		reg = <0x4500 0x100>;
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 8675d09..fb167a6 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -143,7 +143,27 @@
 		qcs605-mtp-overlay.dtbo \
 		qcs605-360camera-overlay.dtbo \
 		qcs605-external-codec-mtp-overlay.dtbo \
-		qcs605-lc-mtp-overlay.dtbo
+		qcs605-lc-mtp-overlay.dtbo \
+		sdm710-cdp-overlay.dtbo \
+		sdm710-mtp-overlay.dtbo \
+		sdm710-qrd-overlay.dtbo \
+		sdm710-qrd-sku2-overlay.dtbo \
+		sdm710-pm660a-cdp-overlay.dtbo \
+		sdm710-pm660a-mtp-overlay.dtbo \
+		sdm710-external-codec-cdp-overlay.dtbo \
+		sdm710-external-codec-mtp-overlay.dtbo \
+		sdm710-external-codec-pm660a-cdp-overlay.dtbo \
+		sdm710-external-codec-pm660a-mtp-overlay.dtbo \
+		sdm710-usbc-cdp-overlay.dtbo \
+		sdm710-usbc-mtp-overlay.dtbo \
+		sdm710-usbc-pm660a-cdp-overlay.dtbo \
+		sdm710-usbc-pm660a-mtp-overlay.dtbo \
+		sdm710-usbc-external-codec-cdp-overlay.dtbo \
+		sdm710-usbc-external-codec-mtp-overlay.dtbo \
+		sdm710-usbc-external-codec-pm660a-cdp-overlay.dtbo \
+		sdm710-usbc-external-codec-pm660a-mtp-overlay.dtbo \
+		sdm710-tasha-codec-cdp-overlay.dtbo \
+		sdm710-pm660a-tasha-codec-cdp-overlay.dtbo
 
 sdm670-cdp-overlay.dtbo-base := sdm670.dtb
 sdm670-mtp-overlay.dtbo-base := sdm670.dtb
@@ -175,6 +195,26 @@
 qcs605-external-codec-mtp-overlay.dtbo-base := qcs605.dtb
 qcs605-lc-mtp-overlay.dtbo-base := qcs605-lc.dtb
 qcs605-360camera-overlay.dtbo-base := qcs605.dtb
+sdm710-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-mtp-overlay.dtbo-base := sdm710.dtb
+sdm710-qrd-overlay.dtbo-base := sdm710.dtb
+sdm710-qrd-sku2-overlay.dtbo-base := sdm710.dtb
+sdm710-pm660a-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-pm660a-mtp-overlay.dtbo-base := sdm710.dtb
+sdm710-external-codec-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-external-codec-mtp-overlay.dtbo-base := sdm710.dtb
+sdm710-external-codec-pm660a-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-external-codec-pm660a-mtp-overlay.dtbo-base := sdm710.dtb
+sdm710-usbc-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-usbc-mtp-overlay.dtbo-base := sdm710.dtb
+sdm710-usbc-pm660a-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-usbc-pm660a-mtp-overlay.dtbo-base := sdm710.dtb
+sdm710-usbc-external-codec-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-usbc-external-codec-mtp-overlay.dtbo-base := sdm710.dtb
+sdm710-usbc-external-codec-pm660a-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-usbc-external-codec-pm660a-mtp-overlay.dtbo-base := sdm710.dtb
+sdm710-tasha-codec-cdp-overlay.dtbo-base := sdm710.dtb
+sdm710-pm660a-tasha-codec-cdp-overlay.dtbo-base := sdm710.dtb
 
 else
 dtb-$(CONFIG_ARCH_SDM670) += sdm670-rumi.dtb \
@@ -206,7 +246,27 @@
 	qcs605-mtp.dtb \
 	qcs605-cdp.dtb \
 	qcs605-external-codec-mtp.dtb \
-	qcs605-lc-mtp.dtb
+	qcs605-lc-mtp.dtb \
+	sdm710-mtp.dtb \
+	sdm710-cdp.dtb \
+	sdm710-qrd.dtb \
+	sdm710-qrd-sku2.dtb \
+	sdm710-pm660a-mtp.dtb \
+	sdm710-pm660a-cdp.dtb \
+	sdm710-external-codec-cdp.dtb \
+	sdm710-external-codec-mtp.dtb \
+	sdm710-external-codec-pm660a-cdp.dtb \
+	sdm710-external-codec-pm660a-mtp.dtb \
+	sdm710-usbc-cdp.dtb \
+	sdm710-usbc-external-codec-cdp.dtb \
+	sdm710-usbc-external-codec-mtp.dtb \
+	sdm710-usbc-external-codec-pm660a-cdp.dtb \
+	sdm710-usbc-external-codec-pm660a-mtp.dtb \
+	sdm710-usbc-mtp.dtb \
+	sdm710-usbc-pm660a-cdp.dtb \
+	sdm710-usbc-pm660a-mtp.dtb \
+	sdm710-tasha-codec-cdp.dtb \
+	sdm710-pm660a-tasha-codec-cdp.dtb
 endif
 
 ifeq ($(CONFIG_BUILD_ARM64_DT_OVERLAY),y)
@@ -306,7 +366,9 @@
 
 dtb-$(CONFIG_ARCH_MSM8917) += msm8917-pmi8950-mtp.dtb
 
-dtb-$(CONFIG_ARCH_MSM8909) += msm8909w-bg-wtp-v2.dtb
+dtb-$(CONFIG_ARCH_MSM8909) += msm8909w-bg-wtp-v2.dtb \
+	apq8009w-bg-wtp-v2.dtb \
+	apq8009w-bg-alpha.dtb
 
 dtb-$(CONFIG_ARCH_SDM450) += sdm450-rcm.dtb \
 	sdm450-cdp.dtb \
diff --git a/arch/arm64/boot/dts/qcom/apq8009w-bg-alpha.dts b/arch/arm64/boot/dts/qcom/apq8009w-bg-alpha.dts
new file mode 100644
index 0000000..57a28d0
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8009w-bg-alpha.dts
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2017-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 "msm8909-mtp.dtsi"
+#include "msm8909w.dtsi"
+#include "8909w-pm660.dtsi"
+#include "apq8009w-bg-memory.dtsi"
+#include "msm8909-audio-bg_codec.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. APQ8009W-PM660 BG Alpha";
+	compatible = "qcom,apq8009-mtp", "qcom,apq8009", "qcom,mtp";
+	qcom,msm-id =   <265 0>,
+			<301 0>;
+	qcom,board-id = <8 0x113>;
+	qcom,pmic-id =  <0x0001001b 0x0 0x0 0x0>,
+			<0x0001011b 0x0 0x0 0x0>;
+};
+
+&soc {
+	i2c@78b9000 { /* BLSP1 QUP5 */
+		focaltech@38 {
+			compatible = "focaltech,fts";
+			reg = <0x38>;
+			interrupt-parent = <&msm_gpio>;
+			interrupts = <98 0x2008>;
+			vdd-supply = <&pm660_l18>;
+			vcc-i2c-supply = <&pm660_l13>;
+			focaltech,irq-gpio = <&msm_gpio 98 0x2008>;
+			focaltech,reset-gpio = <&msm_gpio 16 0x00>;/**/
+			focaltech,max-touch-number = <5>;
+			focaltech,display-coords = <0 0 390 390>;/**/
+			focaltech,wakeup-gestures-en;
+		};
+
+		/delete-node/ it7260@46;
+		/delete-node/ synaptics@20;
+	};
+
+	qcom,blackghost {
+		compatible = "qcom,pil-blackghost";
+
+		qcom,firmware-name = "bg-wear";
+		/* GPIO inputs from blackghost */
+		qcom,bg2ap-status-gpio = <&msm_gpio 97 0>;
+		qcom,bg2ap-errfatal-gpio = <&msm_gpio 95 0>;
+		/* GPIO output to blackghost */
+		qcom,ap2bg-status-gpio = <&msm_gpio 17 0>;
+		qcom,ap2bg-errfatal-gpio = <&msm_gpio 23 0>;
+	};
+
+	qcom,msm-ssc-sensors {
+		compatible = "qcom,msm-ssc-sensors";
+	};
+
+	qcom,glink-bgcom-xprt-bg {
+		compatible = "qcom,glink-bgcom-xprt";
+		label = "bg";
+		qcom,qos-config = <&glink_qos_bg>;
+		qcom,ramp-time = <0x10>,
+				     <0x20>,
+				     <0x30>,
+				     <0x40>;
+	};
+
+	glink_qos_bg: qcom,glink-qos-config-bg {
+		compatible = "qcom,glink-qos-config";
+		qcom,flow-info = <0x80 0x0>,
+				 <0x70 0x1>,
+				 <0x60 0x2>,
+				 <0x50 0x3>;
+		qcom,mtu-size = <0x800>;
+		qcom,tput-stats-cycle = <0xa>;
+	};
+
+	qcom,glink_pkt {
+		compatible = "qcom,glinkpkt";
+
+		qcom,glinkpkt-bg-daemon {
+			qcom,glinkpkt-transport = "bgcom";
+			qcom,glinkpkt-edge = "bg";
+			qcom,glinkpkt-ch-name = "bg-daemon";
+			qcom,glinkpkt-dev-name = "glink_pkt_bg_daemon";
+		};
+
+		qcom,glinkpkt-bg-display-ctrl {
+			qcom,glinkpkt-transport = "bgcom";
+			qcom,glinkpkt-edge = "bg";
+			qcom,glinkpkt-ch-name = "display-ctrl";
+			qcom,glinkpkt-dev-name = "glink_pkt_bg_display_ctrl";
+		};
+
+		qcom,glinkpkt-bg-display-data {
+			qcom,glinkpkt-transport = "bgcom";
+			qcom,glinkpkt-edge = "bg";
+			qcom,glinkpkt-ch-name = "display-data";
+			qcom,glinkpkt-dev-name = "glink_pkt_bg_display_data";
+		};
+
+		qcom,glinkpkt-bg-rsb-ctrl {
+			qcom,glinkpkt-transport = "bgcom";
+			qcom,glinkpkt-edge = "bg";
+			qcom,glinkpkt-ch-name = "RSB_CTRL";
+			qcom,glinkpkt-dev-name = "glink_pkt_bg_rsb_ctrl";
+		};
+	};
+
+	spi@78B8000 {  /* BLSP1 QUP4 */
+		status = "ok";
+		qcom,bg-spi {
+			compatible = "qcom,bg-spi";
+			reg = <0>;
+			spi-max-frequency = <16000000>;
+			interrupt-parent = <&msm_gpio>;
+			qcom,irq-gpio = <&msm_gpio 110 1>;
+		};
+	};
+
+	qcom,bg-rsb {
+		compatible = "qcom,bg-rsb";
+		vdd-ldo1-supply = <&pm660_l11>;
+		vdd-ldo2-supply = <&pm660_l15>;
+	};
+
+	qcom,bg-daemon {
+		compatible = "qcom,bg-daemon";
+		qcom,bg-reset-gpio = <&pm660_gpios 5 0>;
+		ssr-reg1-supply = <&pm660_l3>;
+		ssr-reg2-supply = <&pm660_l9>;
+	};
+};
+
+&i2c_1 {
+	status = "okay";
+	nq@28 {
+		compatible = "qcom,nq-nci";
+		reg = <0x28>;
+		qcom,nq-irq = <&msm_gpio 50 0x00>;
+		qcom,nq-ven = <&msm_gpio 36 0x00>;
+		qcom,nq-firm = <&msm_gpio 38 0x00>;
+		qcom,nq-esepwr = <&msm_gpio 49 0x00>;
+		qcom,nq-clkreq = <&pm660_gpios 4 0x00>;
+		qcom,clk-src = "BBCLK3";
+		interrupt-parent = <&msm_gpio>;
+		interrupts = <50 0>;
+		interrupt-names = "nfc_irq";
+		pinctrl-names = "nfc_active","nfc_suspend";
+		pinctrl-0 = <&nfcw_int_active &nfcw_disable_active>;
+		pinctrl-1 = <&nfcw_int_suspend &nfcw_disable_suspend>;
+		clock-names = "ref_clk";
+	};
+};
+
+&spi_0 {
+	status = "disabled";
+};
+
+&i2c_3 {
+	status = "disabled";
+};
+
+&i2c_4 {
+	status = "disabled";
+};
+
+&i2c_2 {
+	status = "disabled";
+};
+
+&sdc1_clk_off {
+	config {
+		pins = "sdc1_clk";
+		bias-disable; /* NO pull */
+		drive-strength = <2>; /* 2 MA */
+		output-low;
+	};
+};
+
+&sdc1_cmd_off {
+	config {
+		pins = "sdc1_cmd";
+		bias-disable; /* NO pull */
+		drive-strength = <2>; /* 2 MA */
+		output-low;
+	};
+};
+
+&sdc1_data_off {
+	config {
+		pins = "sdc1_data";
+		bias-disable; /* NO pull */
+		drive-strength = <2>; /* 2 MA */
+		output-low;
+	};
+};
+
+&sdhc_2 {
+	status = "disabled";
+};
+
+&audio_codec_mtp {
+	status = "disabled";
+};
+
+&audio_codec_bg {
+	status = "ok";
+};
+
+&bg_cdc {
+	status = "ok";
+	vdd-spkr-supply = <&pm660_l11>;
+};
+
+&blsp1_uart1 {
+	status = "ok";
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart_console_sleep>;
+};
+
+/* Pinctrl dt nodes for interrupt and reset gpio for Synaptics controller */
+&ts_int_active {
+	mux {
+		pins = "gpio98";
+	};
+
+	config {
+		pins = "gpio98";
+	};
+};
+
+&ts_int_suspend {
+	mux {
+		pins = "gpio98";
+	};
+
+	config {
+		pins = "gpio98";
+	};
+};
+
+&ts_reset_active {
+	mux {
+		pins = "gpio16";
+	};
+
+	config {
+		pins = "gpio16";
+	};
+};
+
+&ts_reset_suspend {
+	mux {
+		pins = "gpio16";
+	};
+
+	config {
+		pins = "gpio16";
+	};
+};
+
+&ts_release {
+	mux {
+		pins = "gpio98", "gpio16";
+	};
+
+	config {
+		pins = "gpio98", "gpio16";
+	};
+};
+
+&pm660_charger {
+	qcom,micro-usb;
+};
+
+&spi4_cs0_active {
+	mux {
+		pins = "gpio14";
+		function = "blsp_spi4";
+	};
+	config {
+		pins = "gpio14";
+		drive-strength = <2>;
+		bias-disable; /* No PULL */
+		output-high;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8009w-bg-memory.dtsi b/arch/arm64/boot/dts/qcom/apq8009w-bg-memory.dtsi
new file mode 100644
index 0000000..d41a792
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8009w-bg-memory.dtsi
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017-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.
+ */
+
+&external_image_mem {
+	reg = <0x0 0x87b00000 0x0 0x0500000>;
+};
+
+&modem_adsp_mem {
+	reg = <0x0 0x88000000 0x0 0x02300000>;
+};
+
+&peripheral_mem {
+	reg = <0x0 0x8a300000 0x0 0x0600000>;
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8009w-bg-wtp-v2.dts b/arch/arm64/boot/dts/qcom/apq8009w-bg-wtp-v2.dts
new file mode 100644
index 0000000..454ba81
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8009w-bg-wtp-v2.dts
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2017-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 "msm8909-mtp.dtsi"
+#include "msm8909w.dtsi"
+#include "8909w-pm660.dtsi"
+#include "apq8009w-bg-memory.dtsi"
+#include "msm8909-audio-bg_codec.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. APQ8009W-PM660 BLACKGHOST WTP";
+	compatible = "qcom,apq8009-mtp", "qcom,apq8009", "qcom,mtp";
+	qcom,msm-id =   <265 0>,
+			<301 0>;
+	qcom,board-id = <8 0x10f>;
+	qcom,pmic-id =  <0x0001001b 0x0 0x0 0x0>,
+			<0x0001011b 0x0 0x0 0x0>;
+};
+
+&soc {
+	i2c@78b9000 { /* BLSP1 QUP5 */
+		synaptics@20 {
+			compatible = "synaptics,dsx-i2c";
+			reg = <0x20>;
+			interrupt-parent = <&msm_gpio>;
+			interrupts = <98 0x2008>;
+			vdd_ana-supply = <&pm660_l18>;
+			vcc_i2c-supply = <&pm660_l13>;
+			synaptics,pwr-reg-name = "vdd_ana";
+			synaptics,bus-reg-name = "vcc_i2c";
+			pinctrl-names = "pmx_ts_active", "pmx_ts_suspend",
+							"pmx_ts_release";
+			pinctrl-0 = <&ts_int_active &ts_reset_active>;
+			pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
+			pinctrl-2 = <&ts_release>;
+			synaptics,irq-gpio = <&msm_gpio 98 0x2008>;
+			synaptics,irq-on-state = <0>;
+			synaptics,irq-flags = <0x2008>;
+			synaptics,power-delay-ms = <200>;
+			synaptics,reset-delay-ms = <200>;
+			synaptics,max-y-for-2d = <389>;
+			synaptics,bus-lpm-cur-uA = <450>;
+			synaptics,do-not-disable-regulators;
+			synaptics,wakeup-gestures-en;
+			synaptics,resume-in-workqueue;
+			synaptics,x-flip;
+			synaptics,y-flip;
+			/delete-property/ synaptics,reset-gpio;
+			/delete-property/ synaptics,display-coords;
+			/delete-property/ synaptics,panel-coords;
+			/delete-property/ synaptics,power-down;
+			/delete-property/ synaptics,disable-gpios;
+			/delete-property/ synaptics,is_wake;
+		};
+
+		/delete-node/ it7260@46;
+	};
+
+	qcom,blackghost {
+		compatible = "qcom,pil-blackghost";
+
+		qcom,firmware-name = "bg-wear";
+		/* GPIO inputs from blackghost */
+		qcom,bg2ap-status-gpio = <&msm_gpio 97 0>;
+		qcom,bg2ap-errfatal-gpio = <&msm_gpio 95 0>;
+		/* GPIO output to blackghost */
+		qcom,ap2bg-status-gpio = <&msm_gpio 17 0>;
+		qcom,ap2bg-errfatal-gpio = <&msm_gpio 23 0>;
+	};
+
+	qcom,msm-ssc-sensors {
+		compatible = "qcom,msm-ssc-sensors";
+	};
+
+	qcom,glink-bgcom-xprt-bg {
+		compatible = "qcom,glink-bgcom-xprt";
+		label = "bg";
+		qcom,qos-config = <&glink_qos_bg>;
+		qcom,ramp-time = <0x10>,
+				     <0x20>,
+				     <0x30>,
+				     <0x40>;
+	};
+
+	glink_qos_bg: qcom,glink-qos-config-bg {
+		compatible = "qcom,glink-qos-config";
+		qcom,flow-info = <0x80 0x0>,
+				 <0x70 0x1>,
+				 <0x60 0x2>,
+				 <0x50 0x3>;
+		qcom,mtu-size = <0x800>;
+		qcom,tput-stats-cycle = <0xa>;
+	};
+
+	qcom,glink_pkt {
+		compatible = "qcom,glinkpkt";
+
+		qcom,glinkpkt-bg-daemon {
+			qcom,glinkpkt-transport = "bgcom";
+			qcom,glinkpkt-edge = "bg";
+			qcom,glinkpkt-ch-name = "bg-daemon";
+			qcom,glinkpkt-dev-name = "glink_pkt_bg_daemon";
+		};
+
+		qcom,glinkpkt-bg-display-ctrl {
+			qcom,glinkpkt-transport = "bgcom";
+			qcom,glinkpkt-edge = "bg";
+			qcom,glinkpkt-ch-name = "display-ctrl";
+			qcom,glinkpkt-dev-name = "glink_pkt_bg_display_ctrl";
+		};
+
+		qcom,glinkpkt-bg-display-data {
+			qcom,glinkpkt-transport = "bgcom";
+			qcom,glinkpkt-edge = "bg";
+			qcom,glinkpkt-ch-name = "display-data";
+			qcom,glinkpkt-dev-name = "glink_pkt_bg_display_data";
+		};
+
+		qcom,glinkpkt-bg-rsb-ctrl {
+			qcom,glinkpkt-transport = "bgcom";
+			qcom,glinkpkt-edge = "bg";
+			qcom,glinkpkt-ch-name = "RSB_CTRL";
+			qcom,glinkpkt-dev-name = "glink_pkt_bg_rsb_ctrl";
+		};
+	};
+
+	spi@78B8000 {  /* BLSP1 QUP4 */
+		status = "ok";
+		qcom,bg-spi {
+			compatible = "qcom,bg-spi";
+			reg = <0>;
+			spi-max-frequency = <16000000>;
+			interrupt-parent = <&msm_gpio>;
+			qcom,irq-gpio = <&msm_gpio 110 1>;
+		};
+	};
+
+	qcom,bg-rsb {
+		compatible = "qcom,bg-rsb";
+		vdd-ldo1-supply = <&pm660_l11>;
+		vdd-ldo2-supply = <&pm660_l15>;
+	};
+
+	qcom,bg-daemon {
+		compatible = "qcom,bg-daemon";
+		qcom,bg-reset-gpio = <&pm660_gpios 5 0>;
+		ssr-reg1-supply = <&pm660_l3>;
+		ssr-reg2-supply = <&pm660_l9>;
+	};
+};
+
+&i2c_1 {
+	status = "okay";
+	nq@28 {
+		compatible = "qcom,nq-nci";
+		reg = <0x28>;
+		qcom,nq-irq = <&msm_gpio 50 0x00>;
+		qcom,nq-ven = <&msm_gpio 36 0x00>;
+		qcom,nq-firm = <&msm_gpio 38 0x00>;
+		qcom,nq-esepwr = <&msm_gpio 49 0x00>;
+		qcom,nq-clkreq = <&pm660_gpios 4 0x00>;
+		qcom,clk-src = "BBCLK3";
+		interrupt-parent = <&msm_gpio>;
+		interrupts = <50 0>;
+		interrupt-names = "nfc_irq";
+		pinctrl-names = "nfc_active","nfc_suspend";
+		pinctrl-0 = <&nfcw_int_active &nfcw_disable_active>;
+		pinctrl-1 = <&nfcw_int_suspend &nfcw_disable_suspend>;
+		clock-names = "ref_clk";
+	};
+};
+
+&spi_0 {
+	status = "disabled";
+};
+
+&i2c_3 {
+	status = "disabled";
+};
+
+&i2c_4 {
+	status = "disabled";
+};
+
+&i2c_2 {
+	status = "disabled";
+};
+
+&sdc1_clk_off {
+	config {
+		pins = "sdc1_clk";
+		bias-disable; /* NO pull */
+		drive-strength = <2>; /* 2 MA */
+		output-low;
+	};
+};
+
+&sdc1_cmd_off {
+	config {
+		pins = "sdc1_cmd";
+		bias-disable; /* NO pull */
+		drive-strength = <2>; /* 2 MA */
+		output-low;
+	};
+};
+
+&sdc1_data_off {
+	config {
+		pins = "sdc1_data";
+		bias-disable; /* NO pull */
+		drive-strength = <2>; /* 2 MA */
+		output-low;
+	};
+};
+
+&sdhc_2 {
+	status = "disabled";
+};
+
+&audio_codec_mtp {
+	status = "disabled";
+};
+
+&audio_codec_bg {
+	status = "ok";
+};
+
+&bg_cdc {
+	status = "ok";
+	vdd-spkr-supply = <&pm660_l11>;
+};
+
+&blsp1_uart1 {
+	status = "ok";
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart_console_sleep>;
+};
+
+/* Pinctrl dt nodes for interrupt and reset gpio for Synaptics controller */
+&ts_int_active {
+	mux {
+		pins = "gpio98";
+	};
+
+	config {
+		pins = "gpio98";
+	};
+};
+
+&ts_int_suspend {
+	mux {
+		pins = "gpio98";
+	};
+
+	config {
+		pins = "gpio98";
+		/delete-property/ bias-pull-down;
+		bias-disable; /* No PULL */
+	};
+};
+
+&ts_reset_active {
+	mux {
+		pins = "gpio16";
+	};
+
+	config {
+		pins = "gpio16";
+	};
+};
+
+&ts_reset_suspend {
+	mux {
+		pins = "gpio16";
+	};
+
+	config {
+		pins = "gpio16";
+	};
+};
+
+&ts_release {
+	mux {
+		pins = "gpio98", "gpio16";
+	};
+
+	config {
+		pins = "gpio98", "gpio16";
+	};
+};
+
+&spi4_cs0_active {
+	mux {
+		pins = "gpio14";
+		function = "blsp_spi4";
+	};
+	config {
+		pins = "gpio14";
+		drive-strength = <2>;
+		bias-disable; /* No PULL */
+		output-high;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi b/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi
index 76b1fa2..f2d4ef3 100644
--- a/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi
@@ -344,47 +344,54 @@
 };
 
 &pmi8950_gpios {
-	gpio@c000 {	/* GPIO_1 */
-		status = "ok";
+	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 {
-	mpp@a200 {	/* MPP_3 */
-		qcom,mode = <1>;		/* Digital output */
-		qcom,output-type = <0>;	/* CMOS logic */
-		qcom,vin-sel = <2>;		/* 1.8V */
-		qcom,src-sel = <0>;		/* Constant */
-		qcom,master-en = <1>;	/* Enable GPIO */
-		qcom,invert = <0>;
-		status = "ok";
+	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 {
-	gpio@c000 {	/* GPIO_1 */
-		status = "ok";
+	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 {
-	mpp@a000 {	/* MPP_1 */		/* VDD_PX */
-		status = "disabled";
-	};
-	mpp@a100 {	/* MPP_2 */
-		status = "disabled";
-	};
-	mpp@a200 {	/* MPP_3 */
-		status = "disabled";
-	};
-
-	mpp@a300 {	/* MPP_4 */		/* WLED_PWM_CTRL */
-		qcom,mode = <1>;		/* Digital output */
-		qcom,output-type = <0>;	/* CMOS logic */
-		qcom,vin-sel = <0>;		/* VPH_PWR */
-		qcom,src-sel = <4>;		/* DTEST1 */
-		qcom,master-en = <1>;	/* Enable GPIO */
-		qcom,invert = <0>;
-		status = "ok";
+	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/msm-arm-smmu-8909.dtsi b/arch/arm64/boot/dts/qcom/msm-arm-smmu-8909.dtsi
new file mode 100644
index 0000000..a601b5f
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm-arm-smmu-8909.dtsi
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2015-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 <dt-bindings/clock/msm-clocks-8909.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+&soc {
+
+	apps_iommu: qcom,iommu@1e00000 {
+		compatible = "qcom,qsmmu-v500";
+		reg = <0x1e00000 0x40000>,
+			<0x1ef2000 0x20>;
+		reg-names = "base", "tcu-base";
+		#iommu-cells = <2>;
+		qcom,tz-device-id = "APPS";
+		qcom,skip-init;
+		qcom,enable-static-cb;
+		qcom,use-3-lvl-tables;
+		qcom,disable-atos;
+		#global-interrupts = <0>;
+		#size-cells = <1>;
+		#address-cells = <1>;
+		ranges;
+		interrupts =
+				<GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 230 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 231 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			clocks =
+				<&clock_gcc clk_gcc_smmu_cfg_clk>,
+				<&clock_gcc clk_gcc_apss_tcu_clk>;
+			clock-names = "iface_clk", "core_clk";
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8909.dtsi b/arch/arm64/boot/dts/qcom/msm8909.dtsi
index 7b38370..5e56c49 100644
--- a/arch/arm64/boot/dts/qcom/msm8909.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8909.dtsi
@@ -334,7 +334,7 @@
 		compatible = "qcom,gcc-mdss-8909";
 		clocks = <&mdss_dsi0_pll clk_dsi_pll0_pixel_clk_src>,
 			 <&mdss_dsi0_pll clk_dsi_pll0_byte_clk_src>;
-		clock-names = "pixel_src", "byte_src";
+		clock-names = "pclk0_src", "byte0_src";
 		#clock-cells = <1>;
 	};
 
@@ -1363,6 +1363,7 @@
 		qcom,scm_core_clk_src-freq = <80000000>;
 
 		qcom,pas-id = <9>;
+		qcom,mas-crypto = <&mas_crypto>;
 		qcom,proxy-timeout-ms = <100>;
 		qcom,firmware-name = "venus";
 		memory-region = <&venus_qseecom_mem>;
@@ -1792,6 +1793,7 @@
 		qcom,sysmon-id = <6>;
 		qcom,ssctl-instance-id = <0x13>;
 		qcom,firmware-name = "wcnss";
+		qcom,mas-crypto = <&mas_crypto>;
 
 		/* GPIO inputs from wcnss */
 		qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_4_in 0 0>;
@@ -1835,6 +1837,7 @@
 		qcom,pil-self-auth;
 		qcom,sysmon-id = <0>;
 		qcom,ssctl-instance-id = <0x12>;
+		qcom,reset-clk;
 
 		/* GPIO inputs from mss */
 		qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>;
diff --git a/arch/arm64/boot/dts/qcom/msm8909w-bg-wtp-v2.dts b/arch/arm64/boot/dts/qcom/msm8909w-bg-wtp-v2.dts
index 8bcbe68..24266e8 100644
--- a/arch/arm64/boot/dts/qcom/msm8909w-bg-wtp-v2.dts
+++ b/arch/arm64/boot/dts/qcom/msm8909w-bg-wtp-v2.dts
@@ -18,6 +18,7 @@
 #include "msm8909w-bg-memory.dtsi"
 #include "8909w-pm660.dtsi"
 #include "msm8909-audio-bg_codec.dtsi"
+#include "msm-arm-smmu-8909.dtsi"
 
 / {
 	model = "Qualcomm Technologies, Inc. MSM8909W-PM660 BLACKGHOST WTP";
diff --git a/arch/arm64/boot/dts/qcom/msm8917-gpu.dtsi b/arch/arm64/boot/dts/qcom/msm8917-gpu.dtsi
new file mode 100644
index 0000000..3b12ba4
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8917-gpu.dtsi
@@ -0,0 +1,184 @@
+/* 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.
+ */
+
+&soc {
+	msm_bus: qcom,kgsl-busmon {
+		label = "kgsl-busmon";
+		compatible = "qcom,kgsl-busmon";
+	};
+
+	/* Bus governor */
+	gpubw: qcom,gpubw {
+		compatible = "qcom,devbw";
+		governor = "bw_vbif";
+		qcom,src-dst-ports = <26 512>;
+		/*
+		 * Need to configure 2x Clock as BIMC
+		 * Internally Divides by 2 for Gen1 DDR PHY.
+		 */
+		qcom,active-only;
+		qcom,bw-tbl =
+			< 0 >,    /* Off */
+			< 769 >,  /* 1. DDR:100.80 MHz BIMC: 201.60 MHz */
+			< 1611 >, /* 2. DDR:211.20 MHz BIMC: 422.40 MHz */
+			< 2270 >, /* 3. DDR:297.60 MHz BIMC: 595.20 MHz */
+			< 2929 >, /* 4. DDR:384.00 MHz BIMC: 768.00 MHz */
+			< 4248 >, /* 5. DDR:556.80 MHz BIMC: 1113.60 MHz */
+			< 4541 >, /* 6. DDR:595.20 MHz BIMC: 1190.40 MHz */
+			< 5126 >, /* 7. DDR:672.00 MHz BIMC: 1344.00 MHz */
+			< 5639 >; /* 8. DDR:739.20 MHz BIMC: 1478.40 MHz */
+	};
+
+	msm_gpu: qcom,kgsl-3d0@1c00000 {
+		label = "kgsl-3d0";
+		compatible = "qcom,kgsl-3d0", "qcom,kgsl-3d";
+		reg = <0x1c00000 0x10000
+		       0x1c10000 0x10000
+		       0x00a0000 0x06fff>;
+		reg-names = "kgsl_3d0_reg_memory" , "kgsl_3d0_shader_memory",
+				"qfprom_memory";
+		interrupts = <0 33 0>;
+		interrupt-names = "kgsl_3d0_irq";
+		qcom,id = <0>;
+
+		qcom,chipid = <0x03000620>;
+
+		qcom,initial-pwrlevel = <3>;
+
+		qcom,idle-timeout = <80>; //msecs
+		qcom,strtstp-sleepwake;
+		qcom,gpu-bimc-interface-clk-freq = <400000000>; //In Hz
+
+		clocks = <&clock_gcc clk_gcc_oxili_gfx3d_clk>,
+			<&clock_gcc clk_gcc_oxili_ahb_clk>,
+			<&clock_gcc clk_gcc_bimc_gfx_clk>,
+			<&clock_gcc clk_gcc_bimc_gpu_clk>,
+			<&clock_gcc clk_gcc_gtcu_ahb_clk>,
+			<&clock_gcc clk_gcc_gfx_tcu_clk>,
+			<&clock_gcc clk_gcc_gfx_tbu_clk>,
+			<&clock_gcc clk_bimc_gpu_clk>;
+
+		clock-names = "core_clk", "iface_clk", "mem_iface_clk",
+				"alt_mem_iface_clk", "gtcu_iface_clk",
+				"gtcu_clk", "gtbu_clk", "bimc_gpu_clk";
+
+		/* Bus Scale Settings */
+		qcom,gpubw-dev = <&gpubw>;
+		qcom,bus-control;
+		qcom,bus-width = <16>;
+		qcom,msm-bus,name = "grp3d";
+		qcom,msm-bus,num-cases = <9>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<26 512 0 0>,       /*    off        */
+				<26 512 0 806400>,  /* 1. 100.80 MHz */
+				<26 512 0 1689600>, /* 2. 211.20 MHz */
+				<26 512 0 2380800>, /* 3. 297.60 MHz */
+				<26 512 0 3072000>, /* 4. 384.00 MHz */
+				<26 512 0 4454400>, /* 5. 556.80 MHz */
+				<26 512 0 4761600>, /* 6. 595.20 MHz */
+				<26 512 0 5376000>, /* 7. 672.00 MHz */
+				<26 512 0 5913600>; /* 8. 739.20 MHz */
+
+		/* GDSC regulator names */
+		regulator-names = "vdd";
+		/* GDSC oxili regulators */
+		vdd-supply = <&gdsc_oxili_gx>;
+
+		/* CPU latency parameter */
+		qcom,pm-qos-active-latency = <651>;
+
+		/* Power levels */
+		qcom,gpu-pwrlevels {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			compatible = "qcom,gpu-pwrlevels";
+
+			/* TURBO */
+			qcom,gpu-pwrlevel@0 {
+				reg = <0>;
+				qcom,gpu-freq = <598000000>;
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <7>;
+				qcom,bus-max = <7>;
+			};
+
+			/* NOM+ */
+			qcom,gpu-pwrlevel@1 {
+				reg = <1>;
+				qcom,gpu-freq = <523200000>;
+				qcom,bus-freq = <6>;
+				qcom,bus-min = <5>;
+				qcom,bus-max = <7>;
+			};
+
+			/* NOM */
+			qcom,gpu-pwrlevel@2 {
+				reg = <2>;
+				qcom,gpu-freq = <484800000>;
+				qcom,bus-freq = <5>;
+				qcom,bus-min = <4>;
+				qcom,bus-max = <6>;
+			};
+
+			/* SVS+ */
+			qcom,gpu-pwrlevel@3 {
+				reg = <3>;
+				qcom,gpu-freq = <400000000>;
+				qcom,bus-freq = <4>;
+				qcom,bus-min = <3>;
+				qcom,bus-max = <5>;
+			};
+
+			/* SVS */
+			qcom,gpu-pwrlevel@4 {
+				reg = <4>;
+				qcom,gpu-freq = <270000000>;
+				qcom,bus-freq = <3>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <3>;
+			};
+
+			/* XO */
+			qcom,gpu-pwrlevel@5 {
+				reg = <5>;
+				qcom,gpu-freq = <19200000>;
+				qcom,bus-freq = <0>;
+				qcom,bus-min = <0>;
+				qcom,bus-max = <0>;
+		};
+	};
+};
+
+	kgsl_msm_iommu: qcom,kgsl-iommu@1f00000 {
+		compatible = "qcom,kgsl-smmu-v2";
+		reg = <0x1f00000 0x10000>;
+		/*
+		 * The gpu can only program a single context bank
+		 * at this fixed offset.
+		 */
+		qcom,protect = <0xa000 0x1000>;
+		clocks = <&clock_gcc clk_gcc_smmu_cfg_clk>,
+			<&clock_gcc clk_gcc_gfx_tcu_clk>,
+			<&clock_gcc clk_gcc_gtcu_ahb_clk>,
+			<&clock_gcc clk_gcc_gfx_tbu_clk>;
+		clock-names = "scfg_clk", "gtcu_clk", "gtcu_iface_clk",
+				"gtbu_clk";
+		qcom,retention;
+		gfx3d_user: gfx3d_user {
+			compatible = "qcom,smmu-kgsl-cb";
+			iommus = <&gfx_iommu 0>;
+			qcom,gpu-offset = <0xa000>;
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8917.dtsi b/arch/arm64/boot/dts/qcom/msm8917.dtsi
index a85d6d2..a315ade 100644
--- a/arch/arm64/boot/dts/qcom/msm8917.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8917.dtsi
@@ -165,6 +165,7 @@
 #include "msm8917-mdss.dtsi"
 #include "msm8917-mdss-pll.dtsi"
 #include "msm-arm-smmu-8917.dtsi"
+#include "msm8917-gpu.dtsi"
 
 &soc {
 	#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/qcom/msm8937-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8937-camera-sensor-mtp.dtsi
new file mode 100644
index 0000000..d134dd1
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8937-camera-sensor-mtp.dtsi
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2015-2016, 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.
+ */
+
+&cci {
+	actuator0: qcom,actuator@0 {
+		cell-index = <0>;
+		reg = <0x0>;
+		compatible = "qcom,actuator";
+		qcom,cci-master = <0>;
+		cam_vaf-supply = <&pm8937_l17>;
+		qcom,cam-vreg-name = "cam_vaf";
+		qcom,cam-vreg-min-voltage = <2850000>;
+		qcom,cam-vreg-max-voltage = <2850000>;
+		qcom,cam-vreg-op-mode = <80000>;
+	};
+
+	actuator1: qcom,actuator@1 {
+		cell-index = <1>;
+		reg = <0x1>;
+		compatible = "qcom,actuator";
+		qcom,cci-master = <0>;
+		cam_vaf-supply = <&pm8937_l17>;
+		qcom,cam-vreg-name = "cam_vaf";
+		qcom,cam-vreg-min-voltage = <2850000>;
+		qcom,cam-vreg-max-voltage = <2850000>;
+		qcom,cam-vreg-op-mode = <80000>;
+	};
+
+	eeprom0: qcom,eeprom@0 {
+		cell-index = <0>;
+		compatible = "qcom,eeprom";
+		qcom,cci-master = <0>;
+		reg = <0x0>;
+		cam_vana-supply = <&pm8937_l22>;
+		cam_vio-supply = <&pm8937_l6>;
+		cam_vaf-supply = <&pm8937_l17>;
+		qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vaf";
+		qcom,cam-vreg-min-voltage = <0 2800000 2850000>;
+		qcom,cam-vreg-max-voltage = <0 2800000 2850000>;
+		qcom,cam-vreg-op-mode = <0 80000 100000>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_default
+				&cam_sensor_rear_reset
+				&cam_sensor_rear_standby
+				&cam_sensor_rear_vdig>;
+		pinctrl-1 = <&cam_sensor_mclk0_sleep
+				&cam_sensor_rear_reset_sleep
+				&cam_sensor_rear_standby_sleep
+				&cam_sensor_rear_vdig_sleep>;
+		gpios = <&tlmm 26 0>,
+			<&tlmm 36 0>,
+			<&tlmm 35 0>,
+			<&tlmm 62 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-vdig = <3>;
+		qcom,gpio-req-tbl-num = <0 1 2 3>;
+		qcom,gpio-req-tbl-flags = <1 0 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+			"CAM_RESET0",
+			"CAM_STANDBY0",
+			"CAM_VDIG";
+		status = "ok";
+		clocks = <&clock_gcc clk_mclk0_clk_src>,
+				<&clock_gcc clk_gcc_camss_mclk0_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <19200000 0>;
+	};
+
+	eeprom1: qcom,eeprom@1 {
+		cell-index = <1>;
+		reg = <0x1>;
+		qcom,eeprom-name = "sunny_8865";
+		compatible = "qcom,eeprom";
+		qcom,slave-addr = <0x6c>;
+		qcom,cci-master = <0>;
+		qcom,num-blocks = <8>;
+
+		qcom,page0 = <1 0x0100 2 0x01 1 1>;
+		qcom,poll0 = <0 0x0 2 0x0 1 0>;
+		qcom,mem0 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page1 = <1 0x5002 2 0x00 1 0>;
+		qcom,poll1 = <0 0x0 2 0x0 1 0>;
+		qcom,mem1 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page2 = <1 0x3d84 2 0xc0 1 0>;
+		qcom,poll2 = <0 0x0 2 0x0 1 0>;
+		qcom,mem2 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page3 = <1 0x3d88 2 0x70 1 0>;
+		qcom,poll3 = <0 0x0 2 0x0 1 0>;
+		qcom,mem3 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page4 = <1 0x3d89 2 0x10 1 0>;
+		qcom,poll4 = <0 0x0 2 0x0 1 0>;
+		qcom,mem4 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page5 = <1 0x3d8a 2 0x70 1 0>;
+		qcom,poll5 = <0 0x0 2 0x0 1 0>;
+		qcom,mem5 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page6 = <1 0x3d8b 2 0xf4 1 0>;
+		qcom,poll6 = <0 0x0 2 0x0 1 0>;
+		qcom,mem6 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page7 = <1 0x3d81 2 0x01 1 10>;
+		qcom,poll7 = <0 0x0 2 0x0 1 1>;
+		qcom,mem7 = <1536 0x7010 2 0 1 0>;
+
+		cam_vdig-supply = <&pm8937_l23>;
+		cam_vana-supply = <&pm8937_l22>;
+		cam_vio-supply = <&pm8937_l6>;
+		cam_vaf-supply = <&pm8937_l17>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+			"cam_vaf";
+		qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+		qcom,gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_default
+			&cam_sensor_front1_default>;
+		pinctrl-1 = <&cam_sensor_mclk2_sleep &cam_sensor_front1_sleep>;
+		gpios = <&tlmm 28 0>,
+			<&tlmm 40 0>,
+			<&tlmm 39 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+					  "CAM_RESET2",
+					  "CAM_STANDBY2";
+		qcom,cam-power-seq-type = "sensor_vreg", "sensor_vreg",
+			"sensor_vreg",
+			"sensor_gpio", "sensor_gpio" , "sensor_clk";
+		qcom,cam-power-seq-val = "cam_vdig", "cam_vana", "cam_vio",
+			"sensor_gpio_reset", "sensor_gpio_standby",
+			"sensor_cam_mclk";
+		qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>;
+		qcom,cam-power-seq-delay = <1 1 1 30 30 5>;
+		status = "ok";
+		clocks = <&clock_gcc clk_mclk2_clk_src>,
+			<&clock_gcc clk_gcc_camss_mclk2_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <19200000 0>;
+	};
+
+	qcom,camera@0 {
+		cell-index = <0>;
+		compatible = "qcom,camera";
+		reg = <0x0>;
+		qcom,csiphy-sd-index = <0>;
+		qcom,csid-sd-index = <0>;
+		qcom,mount-angle = <270>;
+		qcom,led-flash-src = <&led_flash0>;
+		qcom,eeprom-src = <&eeprom0>;
+		qcom,actuator-src = <&actuator0>;
+		cam_vana-supply = <&pm8937_l22>;
+		cam_vio-supply = <&pm8937_l6>;
+		cam_vaf-supply = <&pm8937_l17>;
+		qcom,cam-vreg-name = "cam_vio", "cam_vana", "cam_vaf";
+		qcom,cam-vreg-min-voltage = <0 2800000 2850000>;
+		qcom,cam-vreg-max-voltage = <0 2800000 2850000>;
+		qcom,cam-vreg-op-mode = <0 80000 100000>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_default
+				&cam_sensor_rear_reset
+				&cam_sensor_rear_standby
+				&cam_sensor_rear_vdig>;
+		pinctrl-1 = <&cam_sensor_mclk0_sleep
+				&cam_sensor_rear_reset_sleep
+				&cam_sensor_rear_standby_sleep
+				&cam_sensor_rear_vdig_sleep>;
+		gpios = <&tlmm 26 0>,
+			<&tlmm 36 0>,
+			<&tlmm 35 0>,
+			<&tlmm 62 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-vdig = <3>;
+		qcom,gpio-req-tbl-num = <0 1 2 3>;
+		qcom,gpio-req-tbl-flags = <1 0 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+			"CAM_RESET0",
+			"CAM_STANDBY0",
+			"CAM_VDIG";
+		qcom,sensor-position = <0>;
+		qcom,sensor-mode = <0>;
+		qcom,cci-master = <0>;
+		status = "ok";
+		clocks = <&clock_gcc clk_mclk0_clk_src>,
+				<&clock_gcc clk_gcc_camss_mclk0_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <24000000 0>;
+	};
+
+	qcom,camera@1 {
+		cell-index = <1>;
+		compatible = "qcom,camera";
+		reg = <0x1>;
+		qcom,csiphy-sd-index = <1>;
+		qcom,csid-sd-index = <1>;
+		qcom,mount-angle = <90>;
+		cam_vdig-supply = <&pm8937_l23>;
+		cam_vana-supply = <&pm8937_l22>;
+		cam_vio-supply = <&pm8937_l6>;
+		cam_vaf-supply = <&pm8937_l17>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+							"cam_vaf";
+		qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_default
+				&cam_sensor_front_default>;
+		pinctrl-1 = <&cam_sensor_mclk1_sleep
+				&cam_sensor_front_sleep>;
+		gpios = <&tlmm 27 0>,
+			<&tlmm 38 0>,
+			<&tlmm 50 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK1",
+			"CAM_RESET1",
+			"CAM_STANDBY1";
+		qcom,sensor-position = <0x100>;
+		qcom,sensor-mode = <1>;
+		qcom,cci-master = <1>;
+		clocks = <&clock_gcc clk_mclk1_clk_src>,
+				<&clock_gcc clk_gcc_camss_mclk1_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <24000000 0>;
+	};
+
+	qcom,camera@2 {
+		cell-index = <2>;
+		compatible = "qcom,camera";
+		reg = <0x02>;
+		qcom,csiphy-sd-index = <1>;
+		qcom,csid-sd-index = <1>;
+		qcom,mount-angle = <90>;
+		qcom,eeprom-src = <&eeprom1>;
+		qcom,actuator-src = <&actuator1>;
+		cam_vdig-supply = <&pm8937_l23>;
+		cam_vana-supply = <&pm8937_l22>;
+		cam_vio-supply = <&pm8937_l6>;
+		cam_vaf-supply = <&pm8937_l17>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+					"cam_vaf";
+		qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+		qcom,gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_default
+				&cam_sensor_front1_default>;
+		pinctrl-1 = <&cam_sensor_mclk2_sleep
+				&cam_sensor_front1_sleep>;
+		gpios = <&tlmm 28 0>,
+			<&tlmm 40 0>,
+			<&tlmm 39 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+					  "CAM_RESET2",
+					  "CAM_STANDBY2";
+		qcom,sensor-position = <1>;
+		qcom,sensor-mode = <0>;
+		qcom,cci-master = <0>;
+		status = "ok";
+		clocks = <&clock_gcc clk_mclk2_clk_src>,
+			<&clock_gcc clk_gcc_camss_mclk2_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <24000000 0>;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8937-camera.dtsi b/arch/arm64/boot/dts/qcom/msm8937-camera.dtsi
new file mode 100644
index 0000000..b5f467e
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8937-camera.dtsi
@@ -0,0 +1,536 @@
+/*
+ * Copyright (c) 2015-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.
+ */
+
+&soc {
+	qcom,msm-cam@1b00000 {
+		compatible = "qcom,msm-cam";
+		reg = <0x1b00000 0x40000>;
+		reg-names = "msm-cam";
+		status = "ok";
+		bus-vectors = "suspend", "svs", "nominal", "turbo";
+		qcom,bus-votes = <0 160000000 320000000 320000000>;
+	};
+
+	qcom,csiphy@1b34000 {
+		status = "ok";
+		cell-index = <0>;
+		compatible = "qcom,csiphy-v3.4.2", "qcom,csiphy";
+		reg = <0x1b34000 0x1000>,
+			<0x1b00030 0x4>;
+		reg-names = "csiphy", "csiphy_clk_mux";
+		interrupts = <0 78 0>;
+		interrupt-names = "csiphy";
+		clocks = <&clock_gcc clk_gcc_camss_top_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_ispif_ahb_clk>,
+			<&clock_gcc clk_csi0phytimer_clk_src>,
+			<&clock_gcc clk_gcc_camss_csi0phytimer_clk>,
+			<&clock_gcc clk_camss_top_ahb_clk_src>,
+			<&clock_gcc clk_gcc_camss_ahb_clk>;
+		clock-names = "camss_top_ahb_clk", "ispif_ahb_clk",
+			"csiphy_timer_src_clk", "csiphy_timer_clk",
+			"camss_ahb_src", "camss_ahb_clk";
+		qcom,clock-rates = <0 61540000 200000000 0 0 0>;
+	};
+
+	qcom,csiphy@1b35000 {
+		status = "ok";
+		cell-index = <1>;
+		compatible = "qcom,csiphy-v3.4.2", "qcom,csiphy";
+		reg = <0x1b35000 0x1000>,
+			<0x1b00038 0x4>;
+		reg-names = "csiphy", "csiphy_clk_mux";
+		interrupts = <0 79 0>;
+		interrupt-names = "csiphy";
+		clocks = <&clock_gcc clk_gcc_camss_top_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_ispif_ahb_clk>,
+			<&clock_gcc clk_csi1phytimer_clk_src>,
+			<&clock_gcc clk_gcc_camss_csi1phytimer_clk>,
+			<&clock_gcc clk_camss_top_ahb_clk_src>,
+			<&clock_gcc clk_gcc_camss_ahb_clk>;
+		clock-names = "camss_top_ahb_clk", "ispif_ahb_clk",
+			"csiphy_timer_src_clk", "csiphy_timer_clk",
+			"camss_ahb_src", "camss_ahb_clk";
+		qcom,clock-rates = <0 61540000 200000000 0 0 0>;
+	};
+
+	qcom,csid@1b30000  {
+		status = "ok";
+		cell-index = <0>;
+		compatible = "qcom,csid-v3.4.2", "qcom,csid";
+		reg = <0x1b30000 0x400>;
+		reg-names = "csid";
+		interrupts = <0 51 0>;
+		interrupt-names = "csid";
+		qcom,csi-vdd-voltage = <1200000>;
+		qcom,mipi-csi-vdd-supply = <&pm8937_l2>;
+		clocks = <&clock_gcc clk_gcc_camss_top_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_ispif_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_csi0_ahb_clk>,
+			<&clock_gcc clk_csi0_clk_src>,
+			<&clock_gcc clk_gcc_camss_csi0phy_clk>,
+			<&clock_gcc clk_gcc_camss_csi0_clk>,
+			<&clock_gcc clk_gcc_camss_csi0pix_clk>,
+			<&clock_gcc clk_gcc_camss_csi0rdi_clk>,
+			<&clock_gcc clk_gcc_camss_ahb_clk>;
+		clock-names = "camss_top_ahb_clk",
+			"ispif_ahb_clk", "csi_ahb_clk", "csi_src_clk",
+			"csi0_phy_clk",
+			"csi_clk",  "csi_pix_clk",
+			"csi_rdi_clk", "camss_ahb_clk";
+		qcom,clock-rates = <0 61540000 0 200000000 0 0 0 0 0>;
+	};
+
+	qcom,csid@1b30400 {
+		status = "ok";
+		cell-index = <1>;
+		compatible = "qcom,csid-v3.4.2", "qcom,csid";
+		reg = <0x1b30400 0x400>;
+		reg-names = "csid";
+		interrupts = <0 52 0>;
+		interrupt-names = "csid";
+		qcom,csi-vdd-voltage = <1200000>;
+		qcom,mipi-csi-vdd-supply = <&pm8937_l2>;
+		clocks = <&clock_gcc clk_gcc_camss_top_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_ispif_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_csi1_ahb_clk>,
+			<&clock_gcc clk_csi1_clk_src>,
+			<&clock_gcc clk_gcc_camss_csi1phy_clk>,
+			<&clock_gcc clk_gcc_camss_csi1_clk>,
+			<&clock_gcc clk_gcc_camss_csi1pix_clk>,
+			<&clock_gcc clk_gcc_camss_csi1rdi_clk>,
+			<&clock_gcc clk_gcc_camss_ahb_clk>;
+		clock-names = "camss_top_ahb_clk",
+			"ispif_ahb_clk", "csi_ahb_clk", "csi_src_clk",
+			"csi1_phy_clk",
+			"csi_clk", "csi_pix_clk",
+			"csi_rdi_clk", "camss_ahb_clk";
+		qcom,clock-rates = <0 61540000 0 200000000 0 0 0 0 0>;
+	};
+
+	qcom,csid@1b30800 {
+		status = "ok";
+		cell-index = <2>;
+		compatible = "qcom,csid-v3.4.2", "qcom,csid";
+		reg = <0x1b30800 0x400>;
+		reg-names = "csid";
+		interrupts = <0 153 0>;
+		interrupt-names = "csid";
+		qcom,csi-vdd-voltage = <1200000>;
+		qcom,mipi-csi-vdd-supply = <&pm8937_l2>;
+		clocks = <&clock_gcc clk_gcc_camss_top_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_ispif_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_csi2_ahb_clk>,
+			<&clock_gcc clk_csi2_clk_src>,
+			<&clock_gcc clk_gcc_camss_csi2phy_clk>,
+			<&clock_gcc clk_gcc_camss_csi2_clk>,
+			<&clock_gcc clk_gcc_camss_csi2pix_clk>,
+			<&clock_gcc clk_gcc_camss_csi2rdi_clk>,
+			<&clock_gcc clk_gcc_camss_ahb_clk>;
+		clock-names = "camss_top_ahb_clk",
+			"ispif_ahb_clk", "csi_ahb_clk", "csi_src_clk",
+			"csi2_phy_clk",
+			"csi_clk", "csi_pix_clk",
+			"csi_rdi_clk", "camss_ahb_clk";
+		qcom,clock-rates = <0 61540000 0 200000000 0 0 0 0 0>;
+	};
+
+	qcom,ispif@1b31000 {
+		cell-index = <0>;
+		compatible = "qcom,ispif-v3.0", "qcom,ispif";
+		reg = <0x1b31000 0x500>,
+			<0x1b00020 0x10>;
+		reg-names = "ispif", "csi_clk_mux";
+		interrupts = <0 55 0>;
+		interrupt-names = "ispif";
+		qcom,num-isps = <0x2>;
+		vfe0-vdd-supply = <&gdsc_vfe>;
+		vfe1-vdd-supply = <&gdsc_vfe1>;
+		qcom,vdd-names = "vfe0-vdd", "vfe1-vdd";
+		clocks = <&clock_gcc clk_gcc_camss_ispif_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_top_ahb_clk>,
+			<&clock_gcc clk_camss_top_ahb_clk_src>,
+			<&clock_gcc clk_csi0_clk_src>,
+			<&clock_gcc clk_gcc_camss_csi0_clk>,
+			<&clock_gcc clk_gcc_camss_csi0rdi_clk>,
+			<&clock_gcc clk_gcc_camss_csi0pix_clk>,
+			<&clock_gcc clk_csi1_clk_src>,
+			<&clock_gcc clk_gcc_camss_csi1_clk>,
+			<&clock_gcc clk_gcc_camss_csi1rdi_clk>,
+			<&clock_gcc clk_gcc_camss_csi1pix_clk>,
+			<&clock_gcc clk_csi2_clk_src>,
+			<&clock_gcc clk_gcc_camss_csi2_clk>,
+			<&clock_gcc clk_gcc_camss_csi2rdi_clk>,
+			<&clock_gcc clk_gcc_camss_csi2pix_clk>,
+			<&clock_gcc clk_vfe0_clk_src>,
+			<&clock_gcc clk_gcc_camss_vfe0_clk>,
+			<&clock_gcc clk_gcc_camss_csi_vfe0_clk>,
+			<&clock_gcc clk_vfe1_clk_src>,
+			<&clock_gcc clk_gcc_camss_vfe1_clk>,
+			<&clock_gcc clk_gcc_camss_csi_vfe1_clk>;
+		clock-names = "ispif_ahb_clk",
+			"camss_ahb_clk", "camss_top_ahb_clk",
+			"camss_ahb_src",
+			"csi0_src_clk", "csi0_clk",
+			"csi0_rdi_clk", "csi0_pix_clk",
+			"csi1_src_clk", "csi1_clk",
+			"csi1_rdi_clk", "csi1_pix_clk",
+			"csi2_src_clk", "csi2_clk",
+			"csi2_rdi_clk", "csi2_pix_clk",
+			"vfe0_clk_src", "camss_vfe_vfe0_clk",
+			"camss_csi_vfe0_clk", "vfe1_clk_src",
+			"camss_vfe_vfe1_clk", "camss_csi_vfe1_clk";
+		qcom,clock-rates = <61540000 0 0 0
+			200000000 0 0 0
+			200000000 0 0 0
+			200000000 0 0 0
+			0 0 0
+			0 0 0>;
+		qcom,clock-cntl-support;
+		qcom,clock-control = "SET_RATE","NO_SET_RATE", "NO_SET_RATE",
+			"NO_SET_RATE", "SET_RATE", "NO_SET_RATE",
+			"NO_SET_RATE", "NO_SET_RATE", "SET_RATE",
+			"NO_SET_RATE", "NO_SET_RATE", "NO_SET_RATE",
+			"SET_RATE", "NO_SET_RATE", "NO_SET_RATE",
+			"NO_SET_RATE", "INIT_RATE", "NO_SET_RATE",
+			"NO_SET_RATE", "INIT_RATE", "NO_SET_RATE",
+			"NO_SET_RATE";
+	};
+
+	vfe0: qcom,vfe0@1b10000 {
+		cell-index = <0>;
+		compatible = "qcom,vfe40";
+		reg = <0x1b10000 0x1000>,
+			<0x1b40000 0x200>;
+		reg-names = "vfe", "vfe_vbif";
+		interrupts = <0 57 0>;
+		interrupt-names = "vfe";
+		vdd-supply = <&gdsc_vfe>;
+		clocks = <&clock_gcc clk_gcc_camss_top_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_ahb_clk>,
+			<&clock_gcc clk_vfe0_clk_src>,
+			<&clock_gcc clk_gcc_camss_vfe0_clk>,
+			<&clock_gcc clk_gcc_camss_csi_vfe0_clk>,
+			<&clock_gcc clk_gcc_camss_vfe_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_vfe_axi_clk>,
+			<&clock_gcc clk_gcc_camss_ispif_ahb_clk>;
+		clock-names = "camss_top_ahb_clk", "camss_ahb_clk",
+			"vfe_clk_src", "camss_vfe_vfe_clk",
+			"camss_csi_vfe_clk", "iface_clk",
+			"bus_clk", "iface_ahb_clk";
+		qcom,clock-rates = <0 0 266670000 0 0 0 0 0>;
+		qos-entries = <8>;
+		qos-regs = <0x2c4 0x2c8 0x2cc 0x2d0 0x2d4 0x2d8
+			0x2dc 0x2e0>;
+		qos-settings = <0xaa55aa55
+			0xaa55aa55 0xaa55aa55
+			0xaa55aa55 0xaa55aa55
+			0xaa55aa55 0xaa55aa55
+			0xaa55aa55>;
+		vbif-entries = <1>;
+		vbif-regs = <0x124>;
+		vbif-settings = <0x3>;
+		ds-entries = <17>;
+		ds-regs = <0x988 0x98c 0x990 0x994 0x998
+			0x99c 0x9a0 0x9a4 0x9a8 0x9ac 0x9b0
+			0x9b4 0x9b8 0x9bc 0x9c0 0x9c4 0x9c8>;
+		ds-settings = <0xcccc1111
+			0xcccc1111 0xcccc1111
+			0xcccc1111 0xcccc1111
+			0xcccc1111 0xcccc1111
+			0xcccc1111 0xcccc1111
+			0xcccc1111 0xcccc1111
+			0xcccc1111 0xcccc1111
+			0xcccc1111 0xcccc1111
+			0xcccc1111 0x00000110>;
+		max-clk-nominal = <400000000>;
+		max-clk-turbo = <432000000>;
+	};
+
+	vfe1: qcom,vfe1@1b14000 {
+		cell-index = <1>;
+		compatible = "qcom,vfe40";
+		reg = <0x1b14000 0x1000>,
+			<0x1ba0000 0x200>;
+		reg-names = "vfe", "vfe_vbif";
+		interrupts = <0 29 0>;
+		interrupt-names = "vfe";
+		vdd-supply = <&gdsc_vfe1>;
+		clocks = <&clock_gcc clk_gcc_camss_top_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_ahb_clk>,
+			<&clock_gcc clk_vfe1_clk_src>,
+			<&clock_gcc clk_gcc_camss_vfe1_clk>,
+			<&clock_gcc clk_gcc_camss_csi_vfe1_clk>,
+			<&clock_gcc clk_gcc_camss_vfe1_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_vfe1_axi_clk>,
+			<&clock_gcc clk_gcc_camss_ispif_ahb_clk>;
+		clock-names = "camss_top_ahb_clk" , "camss_ahb_clk",
+			"vfe_clk_src", "camss_vfe_vfe_clk",
+			"camss_csi_vfe_clk", "iface_clk",
+			"bus_clk", "iface_ahb_clk";
+		qcom,clock-rates = <0 0 266670000 0 0 0 0 0>;
+		qos-entries = <8>;
+		qos-regs = <0x2c4 0x2c8 0x2cc 0x2d0 0x2d4 0x2d8
+			0x2dc 0x2e0>;
+		qos-settings = <0xaa55aa55
+			0xaa55aa55 0xaa55aa55
+			0xaa55aa55 0xaa55aa55
+			0xaa55aa55 0xaa55aa55
+			0xaa55aa55>;
+		vbif-entries = <1>;
+		vbif-regs = <0x124>;
+		vbif-settings = <0x3>;
+		ds-entries = <17>;
+		ds-regs = <0x988 0x98c 0x990 0x994 0x998
+			0x99c 0x9a0 0x9a4 0x9a8 0x9ac 0x9b0
+			0x9b4 0x9b8 0x9bc 0x9c0 0x9c4 0x9c8>;
+		ds-settings = <0xcccc1111
+			0xcccc1111 0xcccc1111
+			0xcccc1111 0xcccc1111
+			0xcccc1111 0xcccc1111
+			0xcccc1111 0xcccc1111
+			0xcccc1111 0xcccc1111
+			0xcccc1111 0xcccc1111
+			0xcccc1111 0xcccc1111
+			0xcccc1111 0x00000110>;
+		max-clk-nominal = <400000000>;
+		max-clk-turbo = <432000000>;
+	};
+
+	qcom,vfe {
+		compatible = "qcom,vfe";
+		num_child = <2>;
+	};
+
+	qcom,cam_smmu {
+		status = "ok";
+		compatible = "qcom,msm-cam-smmu";
+		msm_cam_smmu_cb1: msm_cam_smmu_cb1 {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_iommu 0x400 0x00>,
+				<&apps_iommu 0x2400 0x00>;
+			label = "vfe";
+			qcom,scratch-buf-support;
+		};
+
+		msm_cam_smmu_cb2: msm_cam_smmu_cb2 {
+			compatible = "qcom,msm-cam-smmu-cb";
+			label = "vfe_secure";
+			qcom,secure-context;
+		};
+
+		msm_cam_smmu_cb3: msm_cam_smmu_cb3 {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_iommu 0x1c00 0x00>;
+			label = "cpp";
+		};
+
+		msm_cam_smmu_cb4: msm_cam_smmu_cb4 {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_iommu 0x1800 0x00>;
+			label = "jpeg_enc0";
+		};
+	};
+
+	qcom,jpeg@1b1c000 {
+		status = "ok";
+		cell-index = <0>;
+		compatible = "qcom,jpeg";
+		reg = <0x1b1c000 0x400>,
+			<0x1b60000 0xc30>;
+		reg-names = "jpeg_hw", "jpeg_vbif";
+		interrupts = <0 59 0>;
+		interrupt-names = "jpeg";
+		vdd-supply = <&gdsc_jpeg>;
+		qcom,vdd-names = "vdd";
+		clock-names =  "core_clk", "iface_clk", "bus_clk0",
+			"camss_top_ahb_clk", "camss_ahb_clk";
+		clocks = <&clock_gcc clk_gcc_camss_jpeg0_clk>,
+			<&clock_gcc clk_gcc_camss_jpeg_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_jpeg_axi_clk>,
+			<&clock_gcc clk_gcc_camss_top_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_ahb_clk>;
+		qcom,clock-rates = <266670000 0 0 0 0>;
+		qcom,qos-reg-settings = <0x28 0x0000555e>,
+			<0xc8 0x00005555>;
+		qcom,vbif-reg-settings = <0xc0 0x10101000>,
+			<0xb0 0x10100010>;
+		qcom,msm-bus,name = "msm_camera_jpeg0";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps = <62 512 0 0>,
+			<62 512 800000 800000>;
+	};
+
+	qcom,irqrouter@1b00000 {
+		status = "ok";
+		cell-index = <0>;
+		compatible = "qcom,irqrouter";
+		reg = <0x1b00000 0x100>;
+		reg-names = "irqrouter";
+	};
+
+	qcom,cpp@1b04000 {
+		status = "ok";
+		cell-index = <0>;
+		compatible = "qcom,cpp";
+		reg = <0x1b04000 0x100>,
+			<0x1b80000 0x200>,
+			<0x1b18000 0x018>,
+			<0x1858078 0x4>;
+		reg-names = "cpp", "cpp_vbif", "cpp_hw", "camss_cpp";
+		interrupts = <0 49 0>;
+		interrupt-names = "cpp";
+		vdd-supply = <&gdsc_cpp>;
+		qcom,vdd-names = "vdd";
+		clocks = <&clock_gcc clk_gcc_camss_ispif_ahb_clk>,
+			<&clock_gcc clk_cpp_clk_src>,
+			<&clock_gcc clk_gcc_camss_top_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_cpp_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_cpp_axi_clk>,
+			<&clock_gcc clk_gcc_camss_cpp_clk>,
+			<&clock_gcc clk_gcc_camss_micro_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_ahb_clk>;
+		clock-names = "ispif_ahb_clk", "cpp_core_clk",
+			"camss_top_ahb_clk", "camss_vfe_cpp_ahb_clk",
+			"camss_vfe_cpp_axi_clk", "camss_vfe_cpp_clk",
+			"micro_iface_clk", "camss_ahb_clk";
+		qcom,clock-rates = <61540000 180000000 0 0 0 180000000 0 0>;
+		qcom,min-clock-rate = <133000000>;
+		resets = <&clock_gcc GCC_CAMSS_MICRO_BCR>;
+		reset-names = "micro_iface_reset";
+		qcom,bus-master = <1>;
+		qcom,msm-bus,name = "msm_camera_cpp";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+			<106 512 0 0>,
+			<106 512 0 0>;
+		qcom,msm-bus-vector-dyn-vote;
+		qcom,micro-reset;
+		qcom,cpp-fw-payload-info {
+			qcom,stripe-base = <156>;
+			qcom,plane-base = <141>;
+			qcom,stripe-size = <27>;
+			qcom,plane-size = <5>;
+			qcom,fe-ptr-off = <5>;
+			qcom,we-ptr-off = <11>;
+		};
+	};
+
+	cci: qcom,cci@1b0c000 {
+		status = "ok";
+		cell-index = <0>;
+		compatible = "qcom,cci";
+		reg = <0x1b0c000 0x4000>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg-names = "cci";
+		interrupts = <0 50 0>;
+		interrupt-names = "cci";
+		clocks = <&clock_gcc clk_gcc_camss_ispif_ahb_clk>,
+			<&clock_gcc clk_cci_clk_src>,
+			<&clock_gcc clk_gcc_camss_cci_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_cci_clk>,
+			<&clock_gcc clk_gcc_camss_ahb_clk>,
+			<&clock_gcc clk_gcc_camss_top_ahb_clk>;
+		clock-names = "ispif_ahb_clk", "cci_src_clk",
+			"cci_ahb_clk", "camss_cci_clk",
+			"camss_ahb_clk", "camss_top_ahb_clk";
+		qcom,clock-rates = <61540000 19200000 0 0 0 0>,
+				<61540000 37500000 0 0 0 0>;
+		pinctrl-names = "cci_default", "cci_suspend";
+			pinctrl-0 = <&cci0_active &cci1_active>;
+			pinctrl-1 = <&cci0_suspend &cci1_suspend>;
+		gpios = <&tlmm 29 0>,
+			<&tlmm 30 0>,
+			<&tlmm 31 0>,
+			<&tlmm 32 0>;
+		qcom,gpio-tbl-num = <0 1 2 3>;
+		qcom,gpio-tbl-flags = <1 1 1 1>;
+		qcom,gpio-tbl-label = "CCI_I2C_DATA0",
+						"CCI_I2C_CLK0",
+						"CCI_I2C_DATA1",
+						"CCI_I2C_CLK1";
+		i2c_freq_100Khz: qcom,i2c_standard_mode {
+			status = "disabled";
+		};
+		i2c_freq_400Khz: qcom,i2c_fast_mode {
+			status = "disabled";
+		};
+		i2c_freq_custom: qcom,i2c_custom_mode {
+			status = "disabled";
+		};
+
+		i2c_freq_1Mhz: qcom,i2c_fast_plus_mode {
+			status = "disabled";
+		};
+
+	};
+};
+
+&i2c_freq_100Khz {
+	qcom,hw-thigh = <78>;
+	qcom,hw-tlow = <114>;
+	qcom,hw-tsu-sto = <28>;
+	qcom,hw-tsu-sta = <28>;
+	qcom,hw-thd-dat = <10>;
+	qcom,hw-thd-sta = <77>;
+	qcom,hw-tbuf = <118>;
+	qcom,hw-scl-stretch-en = <0>;
+	qcom,hw-trdhld = <6>;
+	qcom,hw-tsp = <1>;
+};
+
+&i2c_freq_400Khz {
+	qcom,hw-thigh = <20>;
+	qcom,hw-tlow = <28>;
+	qcom,hw-tsu-sto = <21>;
+	qcom,hw-tsu-sta = <21>;
+	qcom,hw-thd-dat = <13>;
+	qcom,hw-thd-sta = <18>;
+	qcom,hw-tbuf = <32>;
+	qcom,hw-scl-stretch-en = <0>;
+	qcom,hw-trdhld = <6>;
+	qcom,hw-tsp = <3>;
+	status = "ok";
+};
+
+&i2c_freq_custom {
+	qcom,hw-thigh = <15>;
+	qcom,hw-tlow = <28>;
+	qcom,hw-tsu-sto = <21>;
+	qcom,hw-tsu-sta = <21>;
+	qcom,hw-thd-dat = <13>;
+	qcom,hw-thd-sta = <18>;
+	qcom,hw-tbuf = <25>;
+	qcom,hw-scl-stretch-en = <1>;
+	qcom,hw-trdhld = <6>;
+	qcom,hw-tsp = <3>;
+	status = "ok";
+};
+
+&i2c_freq_1Mhz {
+	qcom,hw-thigh = <16>;
+	qcom,hw-tlow = <22>;
+	qcom,hw-tsu-sto = <17>;
+	qcom,hw-tsu-sta = <18>;
+	qcom,hw-thd-dat = <16>;
+	qcom,hw-thd-sta = <15>;
+	qcom,hw-tbuf = <19>;
+	qcom,hw-scl-stretch-en = <1>;
+	qcom,hw-trdhld = <3>;
+	qcom,hw-tsp = <3>;
+	qcom,cci-clk-src = <37500000>;
+	status = "ok";
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8937-cpu.dtsi b/arch/arm64/boot/dts/qcom/msm8937-cpu.dtsi
index f72fda9..ec92805 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-cpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-cpu.dtsi
@@ -58,7 +58,7 @@
 			reg = <0x100>;
 			enable-method = "psci";
 			efficiency = <1126>;
-			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
+			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
 			next-level-cache = <&L2_1>;
 			#cooling-cells = <2>;
 			L2_1: l2-cache {
@@ -83,7 +83,7 @@
 			reg = <0x101>;
 			enable-method = "psci";
 			efficiency = <1126>;
-			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
+			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
 			next-level-cache = <&L2_1>;
 			#cooling-cells = <2>;
 			L1_I_101: l1-icache {
@@ -102,7 +102,7 @@
 			reg = <0x102>;
 			enable-method = "psci";
 			efficiency = <1126>;
-			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
+			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
 			next-level-cache = <&L2_1>;
 			#cooling-cells = <2>;
 			L1_I_102: l1-icache {
@@ -121,7 +121,7 @@
 			reg = <0x103>;
 			enable-method = "psci";
 			efficiency = <1126>;
-			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_1>;
+			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
 			next-level-cache = <&L2_1>;
 			#cooling-cells = <2>;
 			L1_I_103: l1-icache {
@@ -140,7 +140,7 @@
 			reg = <0x0>;
 			enable-method = "psci";
 			efficiency = <1024>;
-			sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_0>;
+			sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>;
 			next-level-cache = <&L2_0>;
 			#cooling-cells = <2>;
 			L2_0: l2-cache {
@@ -164,7 +164,7 @@
 			reg = <0x1>;
 			enable-method = "psci";
 			efficiency = <1024>;
-			sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_0>;
+			sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>;
 			next-level-cache = <&L2_0>;
 			#cooling-cells = <2>;
 			L1_I_1: l1-icache {
@@ -183,7 +183,7 @@
 			reg = <0x2>;
 			enable-method = "psci";
 			efficiency = <1024>;
-			sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_0>;
+			sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>;
 			next-level-cache = <&L2_0>;
 			#cooling-cells = <2>;
 			L1_I_2: l1-icache {
@@ -202,7 +202,7 @@
 			reg = <0x3>;
 			enable-method = "psci";
 			efficiency = <1024>;
-			sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_0>;
+			sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>;
 			next-level-cache = <&L2_0>;
 			#cooling-cells = <2>;
 			L1_I_3: l1-icache {
@@ -245,11 +245,11 @@
 		};
 		CLUSTER_COST_0: cluster-cost0 {
 			busy-cost-data = <
-				 500000  19
-				 800000  29
-				 900000  36
-				1000000  46
-				1100000  55
+				 700000  85
+				1000000  126
+				1100000  152
+				1250000  197
+				1400000  239
 			>;
 			idle-cost-data = <
 				4 3 2 1
@@ -257,11 +257,11 @@
 		};
 		CLUSTER_COST_1: cluster-cost1 {
 			busy-cost-data = <
-				 700000  85
-				1000000  126
-				1100000  152
-				1250000  197
-				1400000  239
+				 500000  19
+				 800000  29
+				 900000  36
+				1000000  46
+				1100000  55
 			>;
 			idle-cost-data = <
 				4 3 2 1
diff --git a/arch/arm64/boot/dts/qcom/msm8937-interposer-sdm439.dtsi b/arch/arm64/boot/dts/qcom/msm8937-interposer-sdm439.dtsi
index a6918b9..fbe5ce7 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-interposer-sdm439.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-interposer-sdm439.dtsi
@@ -28,13 +28,13 @@
 
 &soc {
 	qcom,csid@1b30000 {
-		/delete-property/ qcom,mipi-csi-vdd-supply;
+		qcom,mipi-csi-vdd-supply = <&pm8953_l2>;
 	};
 	qcom,csid@1b30400 {
-		/delete-property/ qcom,mipi-csi-vdd-supply;
+		qcom,mipi-csi-vdd-supply = <&pm8953_l2>;
 	};
 	qcom,csid@1b30800 {
-		/delete-property/ qcom,mipi-csi-vdd-supply;
+		qcom,mipi-csi-vdd-supply = <&pm8953_l2>;
 	};
 
 	mem_acc_vreg_corner: regulator@01946004 {
diff --git a/arch/arm64/boot/dts/qcom/msm8937-mdss-panels.dtsi b/arch/arm64/boot/dts/qcom/msm8937-mdss-panels.dtsi
index 8d18bdd..bca8912 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-mdss-panels.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-mdss-panels.dtsi
@@ -20,7 +20,8 @@
 #include "dsi-panel-r69006-1080p-video.dtsi"
 #include "dsi-adv7533-1080p.dtsi"
 #include "dsi-adv7533-720p.dtsi"
-
+#include "dsi-panel-hx8399c-fhd-plus-video.dtsi"
+#include "dsi-panel-hx8399c-hd-plus-video.dtsi"
 &soc {
 	dsi_panel_pwr_supply: dsi_panel_pwr_supply {
 		#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/qcom/msm8937-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8937-mtp.dtsi
index 01192af..42f1b5c 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-mtp.dtsi
@@ -11,6 +11,8 @@
  * GNU General Public License for more details.
  */
 
+#include "msm8937-camera-sensor-mtp.dtsi"
+
 #include "msm8937-pinctrl.dtsi"
 &blsp1_uart2 {
 	status = "ok";
diff --git a/arch/arm64/boot/dts/qcom/msm8937-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8937-pinctrl.dtsi
index 1b273ef..87dd30e 100644
--- a/arch/arm64/boot/dts/qcom/msm8937-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937-pinctrl.dtsi
@@ -15,7 +15,7 @@
 	tlmm: pinctrl@1000000 {
 		compatible = "qcom,msm8937-pinctrl";
 		reg = <0x1000000 0x300000>;
-		interrupts = <0 208 0>;
+		interrupts-extended = <&wakegic GIC_SPI 208 IRQ_TYPE_NONE>;
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
@@ -1376,29 +1376,57 @@
 			};
 		};
 
-		cam_sensor_rear_default: cam_sensor_rear_default {
-			/* RESET, STANDBY */
+		cam_sensor_rear_reset: cam_sensor_rear_reset {
+			/* RESET */
 			mux {
-				pins = "gpio36", "gpio35";
+				pins = "gpio36";
 				function = "gpio";
 			};
 
 			config {
-				pins = "gpio36","gpio35";
+				pins = "gpio36";
 				bias-disable; /* No PULL */
 				drive-strength = <2>; /* 2 MA */
 			};
 		};
 
-		cam_sensor_rear_sleep: cam_sensor_rear_sleep {
-			/* RESET, STANDBY */
+		cam_sensor_rear_reset_sleep: cam_sensor_rear_reset_sleep {
+			/* RESET */
 			mux {
-				pins = "gpio36","gpio35";
+				pins = "gpio36";
 				function = "gpio";
 			};
 
 			config {
-				pins = "gpio36","gpio35";
+				pins = "gpio36";
+				bias-disable; /* No PULL */
+				drive-strength = <2>; /* 2 MA */
+			};
+		};
+
+		cam_sensor_rear_standby: cam_sensor_rear_standby {
+			/* STANDBY */
+			mux {
+				pins = "gpio35";
+				function = "gpio";
+			};
+
+			config {
+				pins = "gpio35";
+				bias-disable; /* No PULL */
+				drive-strength = <2>; /* 2 MA */
+			};
+		};
+
+		cam_sensor_rear_standby_sleep: cam_sensor_rear_standby_sleep {
+			/* STANDBY */
+			mux {
+				pins = "gpio35";
+				function = "gpio";
+			};
+
+			config {
+				pins = "gpio35";
 				bias-disable; /* No PULL */
 				drive-strength = <2>; /* 2 MA */
 			};
@@ -1432,6 +1460,34 @@
 			};
 		};
 
+		cam_sensor_rear_vana: cam_sensor_rear_vana {
+			/* VANA */
+			mux {
+				pins = "gpio35";
+				function = "gpio";
+			};
+
+			config {
+				pins = "gpio35";
+				bias-disable; /* No PULL */
+				drive-strength = <2>; /* 2 MA */
+			};
+		};
+
+		cam_sensor_rear_vana_sleep: cam_sensor_rear_vana_sleep {
+			/* VANA */
+			mux {
+				pins = "gpio35";
+				function = "gpio";
+			};
+
+			config {
+				pins = "gpio35";
+				bias-disable; /* No PULL */
+				drive-strength = <2>; /* 2 MA */
+			};
+		};
+
 		cam_sensor_mclk1_default: cam_sensor_mclk1_default {
 			/* MCLK1 */
 			mux {
diff --git a/arch/arm64/boot/dts/qcom/msm8937.dtsi b/arch/arm64/boot/dts/qcom/msm8937.dtsi
index 3518473..8f769fe 100644
--- a/arch/arm64/boot/dts/qcom/msm8937.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8937.dtsi
@@ -889,6 +889,10 @@
 		};
 	};
 
+	qcom,iris-fm {
+		compatible = "qcom,iris_fm";
+	};
+
 	rpm_bus: qcom,rpm-smd {
 		compatible = "qcom,rpm-smd";
 		rpm-channel-name = "rpm_requests";
@@ -991,6 +995,7 @@
 		qcom,ipi-ping;
 		qcom,wakeup-enable;
 		status = "okay";
+		qcom,scandump-size = <0x40000>;
 	};
 
 	spmi_bus: qcom,spmi@200f000 {
@@ -1052,10 +1057,20 @@
 			reg = <0x6b0 32>;
 		};
 
+		kaslr_offset@6d0 {
+			compatible = "qcom,msm-imem-kaslr_offset";
+			reg = <0x6d0 12>;
+		};
+
 		pil@94c {
 			compatible = "qcom,msm-imem-pil";
 			reg = <0x94c 200>;
 		};
+
+		diag_dload@c8 {
+			compatible = "qcom,msm-imem-diag-dload";
+			reg = <0xc8 200>;
+		};
 	};
 
 	qcom,memshare {
@@ -1722,6 +1737,7 @@
 #include "msm8937-regulator.dtsi"
 #include "pm8937.dtsi"
 #include "msm8937-audio.dtsi"
+#include "msm8937-camera.dtsi"
 #include "msm-gdsc-8916.dtsi"
 #include "msm8937-coresight.dtsi"
 #include "msm8937-thermal.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/msm8953-coresight.dtsi b/arch/arm64/boot/dts/qcom/msm8953-coresight.dtsi
index 2845e36..196a526 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-coresight.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-coresight.dtsi
@@ -25,6 +25,7 @@
 
 		arm,buffer-size = <0x100000>;
 		arm,sg-enable;
+		qcom,force-reg-dump;
 
 		coresight-name = "coresight-tmc-etr";
 		coresight-csr = <&csr>;
@@ -53,6 +54,7 @@
 		coresight-csr = <&csr>;
 
 		arm,default-sink;
+		qcom,force-reg-dump;
 		coresight-ctis = <&cti0 &cti8>;
 
 		clocks = <&clock_gcc clk_qdss_clk>,
diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi
index 005444c..50ee0e8 100644
--- a/arch/arm64/boot/dts/qcom/msm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
@@ -26,7 +26,7 @@
 	interrupt-parent = <&wakegic>;
 
 	chosen {
-		bootargs = "kpti=0";
+		bootargs = "core_ctl_disable_cpumask=0-7 kpti=0";
 	};
 
 	firmware: firmware {
@@ -1187,6 +1187,10 @@
 		};
 	};
 
+	qcom,iris-fm {
+		compatible = "qcom,iris_fm";
+	};
+
 	rpm_bus: qcom,rpm-smd {
 		compatible = "qcom,rpm-smd";
 		rpm-channel-name = "rpm_requests";
diff --git a/arch/arm64/boot/dts/qcom/pm8937.dtsi b/arch/arm64/boot/dts/qcom/pm8937.dtsi
index cd1bddb..18a3270c 100644
--- a/arch/arm64/boot/dts/qcom/pm8937.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8937.dtsi
@@ -35,6 +35,7 @@
 				"resin-bark", "kpdpwr-resin-bark";
 			qcom,pon-dbc-delay = <15625>;
 			qcom,system-reset;
+			qcom,store-hard-reset-reason;
 
 			qcom,pon_1 {
 				qcom,pon-type = <0>;
diff --git a/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi b/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi
index 5d7d0b8..aa316ba 100644
--- a/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs605-360camera.dtsi
@@ -47,9 +47,14 @@
 	status = "disabled";
 };
 
+&mdss_mdp {
+	bridges = <&lt9611>;
+};
+
 &qupv3_se9_i2c {
 	status = "okay";
-	lt9611@3b {
+
+	lt9611: lt,lt9611@3b {
 		compatible = "lt,lt9611";
 		reg = <0x3b>;
 		interrupt-parent = <&tlmm>;
@@ -60,6 +65,7 @@
 		lt,hdmi-ps-gpio = <&tlmm 136 0x0>;
 		lt,hdmi-en-gpio = <&tlmm 137 0x0>;
 		lt,non-pluggable;
+		lt,preferred-mode = "1920x1080";
 
 		vcc-supply = <&pm660l_l6>;
 		vdd-supply = <&pm660_l11>;
@@ -101,6 +107,21 @@
 				lt,mode-refresh-rate = <60>;
 				lt,mode-clock-in-khz = <148500>;
 			};
+
+			lt,customize-mode-id@1 {
+				lt,mode-h-active = <3840>;
+				lt,mode-h-front-porch = <176>;
+				lt,mode-h-pulse-width = <88>;
+				lt,mode-h-back-porch = <296>;
+				lt,mode-h-active-high;
+				lt,mode-v-active = <2160>;
+				lt,mode-v-front-porch = <8>;
+				lt,mode-v-pulse-width = <10>;
+				lt,mode-v-back-porch = <72>;
+				lt,mode-v-active-high;
+				lt,mode-refresh-rate = <30>;
+				lt,mode-clock-in-khz = <297000>;
+			};
 		};
 
 		ports {
diff --git a/arch/arm64/boot/dts/qcom/qcs605-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/qcs605-cdp-overlay.dts
index 1429880..a479175 100644
--- a/arch/arm64/boot/dts/qcom/qcs605-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/qcs605-cdp-overlay.dts
@@ -46,7 +46,7 @@
 		eeprom-src = <&eeprom_rear_aux>;
 		cam_vio-supply = <&camera_vio_ldo>;
 		cam_vana-supply = <&camera_vana_ldo>;
-		cam_vdig-supply = <&camera_ldo>;
+		cam_vdig-supply = <&camera_rear_ldo>;
 		cam_clk-supply = <&titan_top_gdsc>;
 		regulator-names = "cam_vdig", "cam_vio", "cam_vana",
 			"cam_clk";
diff --git a/arch/arm64/boot/dts/qcom/qcs605-cdp.dts b/arch/arm64/boot/dts/qcom/qcs605-cdp.dts
index 6c6012e..92453d4 100644
--- a/arch/arm64/boot/dts/qcom/qcs605-cdp.dts
+++ b/arch/arm64/boot/dts/qcom/qcs605-cdp.dts
@@ -40,7 +40,7 @@
 		eeprom-src = <&eeprom_rear_aux>;
 		cam_vio-supply = <&camera_vio_ldo>;
 		cam_vana-supply = <&camera_vana_ldo>;
-		cam_vdig-supply = <&camera_ldo>;
+		cam_vdig-supply = <&camera_rear_ldo>;
 		cam_clk-supply = <&titan_top_gdsc>;
 		regulator-names = "cam_vdig", "cam_vio", "cam_vana",
 			"cam_clk";
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/qcs605-lc-camera-sensor-mtp.dtsi
new file mode 100644
index 0000000..a2841bf
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-camera-sensor-mtp.dtsi
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+&cam_cci {
+	qcom,cam-res-mgr {
+		compatible = "qcom,cam-res-mgr";
+		status = "ok";
+	};
+
+	qcom,cam-sensor@0 {
+		cell-index = <0>;
+		compatible = "qcom,cam-sensor";
+		reg = <0x0>;
+		csiphy-sd-index = <0>;
+		sensor-position-roll = <270>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&pm660_l11>;
+		cam_vana-supply = <&pm660_l15>;
+		cam_vdig-supply = <&pm660_l5>;
+		cam_clk-supply = <&titan_top_gdsc>;
+		regulator-names = "cam_vio", "cam_vana", "cam_vdig",
+			"cam_clk";
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1800000 2900000 1200000 0>;
+		rgltr-max-voltage = <1800000 2900000 1200000 0>;
+		rgltr-load-current = <0 80000 105000 0>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_active
+				&cam_sensor_rear_active>;
+		pinctrl-1 = <&cam_sensor_mclk0_suspend
+				&cam_sensor_rear_suspend>;
+		gpios = <&tlmm 13 0>,
+			<&tlmm 30 0>;
+		gpio-reset = <1>;
+		gpio-req-tbl-num = <0 1>;
+		gpio-req-tbl-flags = <1 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK0",
+					"CAM_RESET0";
+		sensor-mode = <0>;
+		cci-master = <0>;
+		status = "ok";
+		clocks = <&clock_camcc CAM_CC_MCLK0_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "turbo";
+		clock-rates = <24000000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.dtsi b/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.dtsi
index f592c0e..1ae339e 100644
--- a/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.dtsi
@@ -11,6 +11,7 @@
  */
 
 #include "qcs605-lc-pmic-overlay.dtsi"
+#include "qcs605-lc-camera-sensor-mtp.dtsi"
 
 &qupv3_se9_2uart {
 	status = "disabled";
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-sde-display.dtsi b/arch/arm64/boot/dts/qcom/qcs605-lc-sde-display.dtsi
new file mode 100644
index 0000000..654f3a1
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-sde-display.dtsi
@@ -0,0 +1,73 @@
+/* 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 <dt-bindings/clock/mdss-10nm-pll-clk.h>
+
+&soc {
+	ext_dsi_bridge_display: qcom,dsi-display@0 {
+		compatible = "qcom,dsi-display";
+		label = "ext_dsi_bridge_display";
+		qcom,display-type = "primary";
+
+		qcom,dsi-ctrl = <&mdss_dsi0>;
+		qcom,dsi-phy = <&mdss_dsi_phy0>;
+		clocks = <&mdss_dsi0_pll BYTECLK_MUX_0_CLK>,
+			<&mdss_dsi0_pll PCLK_MUX_0_CLK>;
+		clock-names = "src_byte_clk", "src_pixel_clk";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				ext_dsi_out: endpoint {
+				};
+			};
+		};
+	};
+
+	sde_wb: qcom,wb-display@0 {
+		compatible = "qcom,wb-display";
+		cell-index = <0>;
+		label = "wb_display";
+	};
+
+	ext_disp: qcom,msm-ext-disp {
+		compatible = "qcom,msm-ext-disp";
+
+		ext_disp_audio_codec: qcom,msm-ext-disp-audio-codec-rx {
+			compatible = "qcom,msm-ext-disp-audio-codec-rx";
+		};
+	};
+};
+
+&mdss_dsi0 {
+	vdda-1p2-supply = <&pm660_l2>;
+};
+
+&mdss_dsi1 {
+	vdda-1p2-supply = <&pm660_l2>;
+};
+
+&mdss_dsi_phy0 {
+	vdda-0p9-supply = <&pm660_l6>;
+};
+
+&mdss_dsi_phy1 {
+	vdda-0p9-supply = <&pm660_l6>;
+};
+
+&sde_dp {
+	vdda-0p9-supply = <&pm660_l6>;
+};
+
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc.dtsi b/arch/arm64/boot/dts/qcom/qcs605-lc.dtsi
index 2af6610..94ee398 100644
--- a/arch/arm64/boot/dts/qcom/qcs605-lc.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc.dtsi
@@ -14,6 +14,7 @@
 #include "qcs605.dtsi"
 #include "pm8005.dtsi"
 #include "qcs605-pm660-pm8005-regulator.dtsi"
+#include "qcs605-lc-sde-display.dtsi"
 
 / {
 	model = "Qualcomm Technologies, Inc. QCS605 SoC";
@@ -134,6 +135,13 @@
 	/delete-node/ qcom,pm660l@3;
 };
 
+&icnss {
+	/delete-property/ vdd-3.3-ch0-supply;
+	vdd-0.8-cx-mx-supply = <&pm660_l1>;
+	vdd-1.8-xo-supply = <&pm660_l9>;
+	vdd-1.3-rfa-supply = <&pm660_l3>;
+};
+
 &thermal_zones {
 	pm660l_tz {
 		/delete-property/ thermal-sensors;
@@ -201,24 +209,147 @@
 
 &clock_gfx {
 	/delete-property/ vdd_gfx-supply;
-	vdd_gfx-supply = <&pm8005_s2>;
+	vdd_gfx-supply = <&pm8005_s3_level>;
 };
 
 &gpu_gx_gdsc {
 	/delete-property/ parent-supply;
-	parent-supply = <&pm8005_s2>;
+	parent-supply = <&pm8005_s3_level>;
 };
 
-&mdss_dsi_phy0 {
-	/delete-property/ vdda-0p9-supply;
-};
-
-&mdss_dsi_phy1 {
-	/delete-property/ vdda-0p9-supply;
+&mdss_mdp {
+	connectors = <&sde_rscc &sde_wb>;
+	bridges = <&lt9611>;
 };
 
 &sde_dp {
-	/delete-property/ vdda-0p9-supply;
+	status = "disabled";
+};
+
+&tlmm {
+	lt9611_vcc_eldo_default: lt9611_vcc_eldo_default {
+		mux {
+			pins = "gpio53";
+			function = "gpio";
+		};
+		config {
+			pins = "gpio53";
+			drive-strength = <8>;
+			bias-disable = <0>;
+			output-low;
+		};
+	};
+};
+
+&soc {
+	lt9611_vcc_eldo: lt9611-gpio-regulator@0 {
+		compatible = "regulator-fixed";
+		regulator-name = "lt9611_vcc_eldo";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-enable-ramp-delay = <233>;
+		gpio = <&tlmm 53 0>;
+		enable-active-high;
+		pinctrl-names = "default";
+		pintctrl-0 = <&lt9611_vcc_eldo_default>;
+	};
+};
+
+&qupv3_se9_i2c {
+	status = "okay";
+
+	lt9611: lt,lt9611@3b {
+		compatible = "lt,lt9611";
+		reg = <0x3b>;
+		interrupt-parent = <&tlmm>;
+		interrupts = <96 0>;
+		interrupt-names = "lt_irq";
+		lt,irq-gpio = <&tlmm 96 0x0>;
+		lt,reset-gpio = <&tlmm 95 0x0>;
+		lt,non-pluggable;
+		lt,preferred-mode = "1920x1080";
+
+		vdd-supply = <&pm660_l12>;
+		vcc-supply = <&lt9611_vcc_eldo>;
+		lt,supply-entries {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			lt,supply-entry@0 {
+				reg = <0>;
+				lt,supply-name = "vdd";
+				lt,supply-min-voltage = <1800000>;
+				lt,supply-max-voltage = <1800000>;
+				lt,supply-enable-load = <200000>;
+				lt,supply-post-on-sleep = <50>;
+			};
+
+			lt,supply-entry@1 {
+				reg = <1>;
+				lt,supply-name = "vcc";
+				lt,supply-min-voltage = <3300000>;
+				lt,supply-max-voltage = <3300000>;
+				lt,supply-post-on-sleep = <50>;
+			};
+		};
+
+		lt,customize-modes {
+			lt,customize-mode-id@0 {
+				lt,mode-h-active = <1920>;
+				lt,mode-h-front-porch = <88>;
+				lt,mode-h-pulse-width = <44>;
+				lt,mode-h-back-porch = <148>;
+				lt,mode-h-active-high;
+				lt,mode-v-active = <1080>;
+				lt,mode-v-front-porch = <4>;
+				lt,mode-v-pulse-width = <5>;
+				lt,mode-v-back-porch = <36>;
+				lt,mode-v-active-high;
+				lt,mode-refresh-rate = <60>;
+				lt,mode-clock-in-khz = <148500>;
+			};
+
+			lt,customize-mode-id@1 {
+				lt,mode-h-active = <3840>;
+				lt,mode-h-front-porch = <176>;
+				lt,mode-h-pulse-width = <88>;
+				lt,mode-h-back-porch = <296>;
+				lt,mode-h-active-high;
+				lt,mode-v-active = <2160>;
+				lt,mode-v-front-porch = <8>;
+				lt,mode-v-pulse-width = <10>;
+				lt,mode-v-back-porch = <72>;
+				lt,mode-v-active-high;
+				lt,mode-refresh-rate = <30>;
+				lt,mode-clock-in-khz = <297000>;
+			};
+		};
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				lt9611_in: endpoint {
+					remote-endpoint = <&ext_dsi_out>;
+				};
+			};
+		};
+	};
+};
+
+&soc {
+	qcom,dsi-display@0 {
+		qcom,dsi-display-active;
+
+		ports {
+			port@0 {
+				endpoint {
+					remote-endpoint = <&lt9611_in>;
+				};
+			};
+		};
+	};
 };
 
 &qusb_phy0 {
diff --git a/arch/arm64/boot/dts/qcom/sda845-svr.dtsi b/arch/arm64/boot/dts/qcom/sda845-svr.dtsi
index 51dbe74..ce62781 100644
--- a/arch/arm64/boot/dts/qcom/sda845-svr.dtsi
+++ b/arch/arm64/boot/dts/qcom/sda845-svr.dtsi
@@ -325,7 +325,7 @@
 };
 
 &adsp_mem {
-	size = <0 0xc800000>;
+	size = <0 0x12c00000>;
 };
 
 &qupv3_se9_2uart {
diff --git a/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi b/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi
index d2a8f3e..80f7007 100644
--- a/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm429-cpu.dtsi
@@ -13,16 +13,13 @@
 
 / {
 	/delete-node/ cpus;
+	/delete-node/ energy-costs;
 
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		cpu-map {
-
 			cluster0 {
-			};
-
-			cluster1 {
 				core0 {
 					cpu = <&CPU0>;
 				};
@@ -44,6 +41,8 @@
 			reg = <0x100>;
 			enable-method = "psci";
 			cpu-release-addr = <0x0 0x90000000>;
+			efficiency = <1024>;
+			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
 			next-level-cache = <&L2_1>;
 			#cooling-cells = <2>;
 			L2_1: l2-cache {
@@ -68,6 +67,8 @@
 			reg = <0x101>;
 			enable-method = "psci";
 			cpu-release-addr = <0x0 0x90000000>;
+			efficiency = <1024>;
+			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
 			next-level-cache = <&L2_1>;
 			#cooling-cells = <2>;
 			L1_I_101: l1-icache {
@@ -86,6 +87,8 @@
 			reg = <0x102>;
 			enable-method = "psci";
 			cpu-release-addr = <0x0 0x90000000>;
+			efficiency = <1024>;
+			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
 			next-level-cache = <&L2_1>;
 			#cooling-cells = <2>;
 			L1_I_102: l1-icache {
@@ -104,6 +107,8 @@
 			reg = <0x103>;
 			enable-method = "psci";
 			cpu-release-addr = <0x0 0x90000000>;
+			efficiency = <1024>;
+			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
 			next-level-cache = <&L2_1>;
 			#cooling-cells = <2>;
 			L1_I_103: l1-icache {
@@ -118,4 +123,34 @@
 
 	};
 
+	energy_costs: energy-costs {
+		compatible = "sched-energy";
+
+		CPU_COST_0: core-cost0 {
+			busy-cost-data = <
+				 800000	137
+				1001600	165
+				1305600	207
+				1497600	256
+				1708800	327
+				1958400	445
+			>;
+			idle-cost-data = <
+				100 80 60 40
+			>;
+		};
+		CLUSTER_COST_0: cluster-cost0 {
+			busy-cost-data = <
+				 800000	49
+				1001600	53
+				1305600	61
+				1497600	71
+				1708800	85
+				1958400	110
+			>;
+			idle-cost-data = <
+				4 3 2 1
+			>;
+		};
+	};
 };
diff --git a/arch/arm64/boot/dts/qcom/sdm429.dtsi b/arch/arm64/boot/dts/qcom/sdm429.dtsi
index f31eb6e..a4d2a80 100644
--- a/arch/arm64/boot/dts/qcom/sdm429.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm429.dtsi
@@ -20,8 +20,6 @@
 };
 
 &soc {
-	/delete-node/ qcom,spm@b1d2000;
-	/delete-node/ qcom,lpm-levels;
 	/delete-node/ etm@619c000;
 	/delete-node/ etm@619d000;
 	/delete-node/ etm@619e000;
@@ -30,6 +28,16 @@
 	/delete-node/ cti@61b9000;
 	/delete-node/ cti@61ba000;
 	/delete-node/ cti@61bb000;
+
+	qcom,spm@b1d2000 {
+		qcom,cpu-vctl-list = <&CPU0 &CPU1 &CPU2 &CPU3>;
+	};
+
+	qcom,lpm-levels {
+		qcom,pm-cluster@0 {
+			/delete-node/qcom,pm-cluster@1;
+		};
+	};
 };
 
 &funnel_apss {
diff --git a/arch/arm64/boot/dts/qcom/sdm439-audio.dtsi b/arch/arm64/boot/dts/qcom/sdm439-audio.dtsi
index fae43ba..f6751d2 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-audio.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-audio.dtsi
@@ -13,6 +13,7 @@
 
 &soc {
 	int_codec: sound {
+		qcom,model = "sdm439-snd-card-mtp";
 		qcom,msm-hs-micbias-type = "internal";
 
 		asoc-codec = <&stub_codec>, <&msm_digital_codec>,
diff --git a/arch/arm64/boot/dts/qcom/sdm439-camera-sensor-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm439-camera-sensor-cdp.dtsi
new file mode 100644
index 0000000..5e2c740
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm439-camera-sensor-cdp.dtsi
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2015-2016, 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.
+ */
+
+&cci {
+	actuator0: qcom,actuator@0 {
+		cell-index = <0>;
+		reg = <0x0>;
+		compatible = "qcom,actuator";
+		qcom,cci-master = <0>;
+		cam_vaf-supply = <&pm8953_l17>;
+		qcom,cam-vreg-name = "cam_vaf";
+		qcom,cam-vreg-min-voltage = <2850000>;
+		qcom,cam-vreg-max-voltage = <2850000>;
+		qcom,cam-vreg-op-mode = <80000>;
+	};
+
+	actuator1: qcom,actuator@1 {
+		cell-index = <1>;
+		reg = <0x1>;
+		compatible = "qcom,actuator";
+		qcom,cci-master = <0>;
+		cam_vaf-supply = <&pm8953_l17>;
+		qcom,cam-vreg-name = "cam_vaf";
+		qcom,cam-vreg-min-voltage = <2850000>;
+		qcom,cam-vreg-max-voltage = <2850000>;
+		qcom,cam-vreg-op-mode = <80000>;
+	};
+
+	eeprom0: qcom,eeprom@0 {
+		cell-index = <0>;
+		compatible = "qcom,eeprom";
+		qcom,cci-master = <0>;
+		reg = <0x0>;
+		cam_vana-supply = <&pm8953_l22>;
+		cam_vio-supply = <&pm8953_l6>;
+		cam_vaf-supply = <&pm8953_l17>;
+		cam_vdig-supply = <&pm8953_l3>;
+		qcom,cam-vreg-name = "cam_vana",
+			"cam_vio", "cam_vdig", "cam_vaf";
+		qcom,cam-vreg-min-voltage = <2800000 0 1200000 2850000>;
+		qcom,cam-vreg-max-voltage = <2800000 0 1200000 2850000>;
+		qcom,cam-vreg-op-mode = <80000 0 200000 100000>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_default
+				&cam_sensor_rear_reset
+			&cam_sensor_rear_vana>;
+		pinctrl-1 = <&cam_sensor_mclk0_sleep
+			&cam_sensor_rear_reset_sleep
+			&cam_sensor_rear_vana_sleep>;
+		gpios = <&tlmm 26 0>,
+			<&tlmm 36 0>,
+			<&tlmm 35 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-vana = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+			"CAM_RESET0",
+			"CAM_VANA";
+		status = "ok";
+		clocks = <&clock_gcc clk_mclk0_clk_src>,
+			<&clock_gcc clk_gcc_camss_mclk0_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <19200000 0>;
+	};
+
+	eeprom1: qcom,eeprom@1 {
+		cell-index = <1>;
+		reg = <0x1>;
+		qcom,eeprom-name = "sunny_8865";
+		compatible = "qcom,eeprom";
+		qcom,slave-addr = <0x6c>;
+		qcom,cci-master = <0>;
+		qcom,num-blocks = <8>;
+
+		qcom,page0 = <1 0x0100 2 0x01 1 1>;
+		qcom,poll0 = <0 0x0 2 0x0 1 0>;
+		qcom,mem0 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page1 = <1 0x5002 2 0x00 1 0>;
+		qcom,poll1 = <0 0x0 2 0x0 1 0>;
+		qcom,mem1 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page2 = <1 0x3d84 2 0xc0 1 0>;
+		qcom,poll2 = <0 0x0 2 0x0 1 0>;
+		qcom,mem2 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page3 = <1 0x3d88 2 0x70 1 0>;
+		qcom,poll3 = <0 0x0 2 0x0 1 0>;
+		qcom,mem3 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page4 = <1 0x3d89 2 0x10 1 0>;
+		qcom,poll4 = <0 0x0 2 0x0 1 0>;
+		qcom,mem4 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page5 = <1 0x3d8a 2 0x70 1 0>;
+		qcom,poll5 = <0 0x0 2 0x0 1 0>;
+		qcom,mem5 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page6 = <1 0x3d8b 2 0xf4 1 0>;
+		qcom,poll6 = <0 0x0 2 0x0 1 0>;
+		qcom,mem6 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page7 = <1 0x3d81 2 0x01 1 10>;
+		qcom,poll7 = <0 0x0 2 0x0 1 1>;
+		qcom,mem7 = <1536 0x7010 2 0 1 0>;
+
+		cam_vdig-supply = <&pm8953_l23>;
+		cam_vana-supply = <&pm8953_l22>;
+		cam_vio-supply = <&pm8953_l6>;
+		cam_vaf-supply = <&pm8953_l17>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+			"cam_vaf";
+		qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+		qcom,gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_default
+			&cam_sensor_front1_default>;
+		pinctrl-1 = <&cam_sensor_mclk2_sleep &cam_sensor_front1_sleep>;
+		gpios = <&tlmm 28 0>,
+			<&tlmm 40 0>,
+			<&tlmm 39 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+					  "CAM_RESET2",
+					  "CAM_STANDBY2";
+		qcom,cam-power-seq-type = "sensor_vreg", "sensor_vreg",
+			"sensor_vreg",
+			"sensor_gpio", "sensor_gpio" , "sensor_clk";
+		qcom,cam-power-seq-val = "cam_vdig", "cam_vana", "cam_vio",
+			"sensor_gpio_reset", "sensor_gpio_standby",
+			"sensor_cam_mclk";
+		qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>;
+		qcom,cam-power-seq-delay = <1 1 1 30 30 5>;
+		status = "ok";
+		clocks = <&clock_gcc clk_mclk2_clk_src>,
+			<&clock_gcc clk_gcc_camss_mclk2_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <19200000 0>;
+	};
+
+	qcom,camera@0 {
+		cell-index = <0>;
+		compatible = "qcom,camera";
+		reg = <0x0>;
+		qcom,csiphy-sd-index = <0>;
+		qcom,csid-sd-index = <0>;
+		qcom,mount-angle = <270>;
+		qcom,led-flash-src = <&led_flash0>;
+		qcom,eeprom-src = <&eeprom0>;
+		qcom,actuator-src = <&actuator0>;
+		cam_vana-supply = <&pm8953_l22>;
+		cam_vio-supply = <&pm8953_l6>;
+		cam_vaf-supply = <&pm8953_l17>;
+		cam_vdig-supply = <&pm8953_l3>;
+		qcom,cam-vreg-name = "cam_vana",
+			"cam_vio", "cam_vdig", "cam_vaf";
+		qcom,cam-vreg-min-voltage = <2800000 0 1200000 2850000>;
+		qcom,cam-vreg-max-voltage = <2800000 0 1200000 2850000>;
+		qcom,cam-vreg-op-mode = <80000 0 200000 100000>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_default
+				&cam_sensor_rear_reset
+				&cam_sensor_rear_vana>;
+		pinctrl-1 = <&cam_sensor_mclk0_sleep
+				&cam_sensor_rear_reset_sleep
+				&cam_sensor_rear_vana_sleep>;
+		gpios = <&tlmm 26 0>,
+			<&tlmm 36 0>,
+			<&tlmm 35 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-vana = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+			"CAM_RESET0",
+			"CAM_VANA";
+		qcom,sensor-position = <0>;
+		qcom,sensor-mode = <0>;
+		qcom,cci-master = <0>;
+		status = "ok";
+		clocks = <&clock_gcc clk_mclk0_clk_src>,
+				<&clock_gcc clk_gcc_camss_mclk0_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <24000000 0>;
+	};
+
+	qcom,camera@1 {
+		cell-index = <1>;
+		compatible = "qcom,camera";
+		reg = <0x1>;
+		qcom,csiphy-sd-index = <1>;
+		qcom,csid-sd-index = <1>;
+		qcom,mount-angle = <90>;
+		cam_vdig-supply = <&pm8953_l3>;
+		cam_vana-supply = <&pm8953_l22>;
+		cam_vio-supply = <&pm8953_l6>;
+		cam_vaf-supply = <&pm8953_l17>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+							"cam_vaf";
+		qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_default
+				&cam_sensor_front_default>;
+		pinctrl-1 = <&cam_sensor_mclk1_sleep
+				&cam_sensor_front_sleep>;
+		gpios = <&tlmm 27 0>,
+			<&tlmm 38 0>,
+			<&tlmm 50 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK1",
+			"CAM_RESET1",
+			"CAM_STANDBY1";
+		qcom,sensor-position = <0x100>;
+		qcom,sensor-mode = <1>;
+		qcom,cci-master = <1>;
+		clocks = <&clock_gcc clk_mclk1_clk_src>,
+				<&clock_gcc clk_gcc_camss_mclk1_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <24000000 0>;
+	};
+
+	qcom,camera@2 {
+		cell-index = <2>;
+		compatible = "qcom,camera";
+		reg = <0x02>;
+		qcom,csiphy-sd-index = <1>;
+		qcom,csid-sd-index = <1>;
+		qcom,mount-angle = <90>;
+		qcom,eeprom-src = <&eeprom1>;
+		qcom,actuator-src = <&actuator1>;
+		cam_vdig-supply = <&pm8953_l23>;
+		cam_vana-supply = <&pm8953_l22>;
+		cam_vio-supply = <&pm8953_l6>;
+		cam_vaf-supply = <&pm8953_l17>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+					"cam_vaf";
+		qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+		qcom,gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_default
+				&cam_sensor_front1_default>;
+		pinctrl-1 = <&cam_sensor_mclk2_sleep
+				&cam_sensor_front1_sleep>;
+		gpios = <&tlmm 28 0>,
+			<&tlmm 40 0>,
+			<&tlmm 39 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+					  "CAM_RESET2",
+					  "CAM_STANDBY2";
+		qcom,sensor-position = <1>;
+		qcom,sensor-mode = <0>;
+		qcom,cci-master = <0>;
+		status = "ok";
+		clocks = <&clock_gcc clk_mclk2_clk_src>,
+			<&clock_gcc clk_gcc_camss_mclk2_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <24000000 0>;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm439-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm439-camera-sensor-mtp.dtsi
new file mode 100644
index 0000000..5e2c740
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm439-camera-sensor-mtp.dtsi
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2015-2016, 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.
+ */
+
+&cci {
+	actuator0: qcom,actuator@0 {
+		cell-index = <0>;
+		reg = <0x0>;
+		compatible = "qcom,actuator";
+		qcom,cci-master = <0>;
+		cam_vaf-supply = <&pm8953_l17>;
+		qcom,cam-vreg-name = "cam_vaf";
+		qcom,cam-vreg-min-voltage = <2850000>;
+		qcom,cam-vreg-max-voltage = <2850000>;
+		qcom,cam-vreg-op-mode = <80000>;
+	};
+
+	actuator1: qcom,actuator@1 {
+		cell-index = <1>;
+		reg = <0x1>;
+		compatible = "qcom,actuator";
+		qcom,cci-master = <0>;
+		cam_vaf-supply = <&pm8953_l17>;
+		qcom,cam-vreg-name = "cam_vaf";
+		qcom,cam-vreg-min-voltage = <2850000>;
+		qcom,cam-vreg-max-voltage = <2850000>;
+		qcom,cam-vreg-op-mode = <80000>;
+	};
+
+	eeprom0: qcom,eeprom@0 {
+		cell-index = <0>;
+		compatible = "qcom,eeprom";
+		qcom,cci-master = <0>;
+		reg = <0x0>;
+		cam_vana-supply = <&pm8953_l22>;
+		cam_vio-supply = <&pm8953_l6>;
+		cam_vaf-supply = <&pm8953_l17>;
+		cam_vdig-supply = <&pm8953_l3>;
+		qcom,cam-vreg-name = "cam_vana",
+			"cam_vio", "cam_vdig", "cam_vaf";
+		qcom,cam-vreg-min-voltage = <2800000 0 1200000 2850000>;
+		qcom,cam-vreg-max-voltage = <2800000 0 1200000 2850000>;
+		qcom,cam-vreg-op-mode = <80000 0 200000 100000>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_default
+				&cam_sensor_rear_reset
+			&cam_sensor_rear_vana>;
+		pinctrl-1 = <&cam_sensor_mclk0_sleep
+			&cam_sensor_rear_reset_sleep
+			&cam_sensor_rear_vana_sleep>;
+		gpios = <&tlmm 26 0>,
+			<&tlmm 36 0>,
+			<&tlmm 35 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-vana = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+			"CAM_RESET0",
+			"CAM_VANA";
+		status = "ok";
+		clocks = <&clock_gcc clk_mclk0_clk_src>,
+			<&clock_gcc clk_gcc_camss_mclk0_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <19200000 0>;
+	};
+
+	eeprom1: qcom,eeprom@1 {
+		cell-index = <1>;
+		reg = <0x1>;
+		qcom,eeprom-name = "sunny_8865";
+		compatible = "qcom,eeprom";
+		qcom,slave-addr = <0x6c>;
+		qcom,cci-master = <0>;
+		qcom,num-blocks = <8>;
+
+		qcom,page0 = <1 0x0100 2 0x01 1 1>;
+		qcom,poll0 = <0 0x0 2 0x0 1 0>;
+		qcom,mem0 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page1 = <1 0x5002 2 0x00 1 0>;
+		qcom,poll1 = <0 0x0 2 0x0 1 0>;
+		qcom,mem1 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page2 = <1 0x3d84 2 0xc0 1 0>;
+		qcom,poll2 = <0 0x0 2 0x0 1 0>;
+		qcom,mem2 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page3 = <1 0x3d88 2 0x70 1 0>;
+		qcom,poll3 = <0 0x0 2 0x0 1 0>;
+		qcom,mem3 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page4 = <1 0x3d89 2 0x10 1 0>;
+		qcom,poll4 = <0 0x0 2 0x0 1 0>;
+		qcom,mem4 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page5 = <1 0x3d8a 2 0x70 1 0>;
+		qcom,poll5 = <0 0x0 2 0x0 1 0>;
+		qcom,mem5 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page6 = <1 0x3d8b 2 0xf4 1 0>;
+		qcom,poll6 = <0 0x0 2 0x0 1 0>;
+		qcom,mem6 = <0 0x0 2 0x0 1 0>;
+
+		qcom,page7 = <1 0x3d81 2 0x01 1 10>;
+		qcom,poll7 = <0 0x0 2 0x0 1 1>;
+		qcom,mem7 = <1536 0x7010 2 0 1 0>;
+
+		cam_vdig-supply = <&pm8953_l23>;
+		cam_vana-supply = <&pm8953_l22>;
+		cam_vio-supply = <&pm8953_l6>;
+		cam_vaf-supply = <&pm8953_l17>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+			"cam_vaf";
+		qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+		qcom,gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_default
+			&cam_sensor_front1_default>;
+		pinctrl-1 = <&cam_sensor_mclk2_sleep &cam_sensor_front1_sleep>;
+		gpios = <&tlmm 28 0>,
+			<&tlmm 40 0>,
+			<&tlmm 39 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+					  "CAM_RESET2",
+					  "CAM_STANDBY2";
+		qcom,cam-power-seq-type = "sensor_vreg", "sensor_vreg",
+			"sensor_vreg",
+			"sensor_gpio", "sensor_gpio" , "sensor_clk";
+		qcom,cam-power-seq-val = "cam_vdig", "cam_vana", "cam_vio",
+			"sensor_gpio_reset", "sensor_gpio_standby",
+			"sensor_cam_mclk";
+		qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>;
+		qcom,cam-power-seq-delay = <1 1 1 30 30 5>;
+		status = "ok";
+		clocks = <&clock_gcc clk_mclk2_clk_src>,
+			<&clock_gcc clk_gcc_camss_mclk2_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <19200000 0>;
+	};
+
+	qcom,camera@0 {
+		cell-index = <0>;
+		compatible = "qcom,camera";
+		reg = <0x0>;
+		qcom,csiphy-sd-index = <0>;
+		qcom,csid-sd-index = <0>;
+		qcom,mount-angle = <270>;
+		qcom,led-flash-src = <&led_flash0>;
+		qcom,eeprom-src = <&eeprom0>;
+		qcom,actuator-src = <&actuator0>;
+		cam_vana-supply = <&pm8953_l22>;
+		cam_vio-supply = <&pm8953_l6>;
+		cam_vaf-supply = <&pm8953_l17>;
+		cam_vdig-supply = <&pm8953_l3>;
+		qcom,cam-vreg-name = "cam_vana",
+			"cam_vio", "cam_vdig", "cam_vaf";
+		qcom,cam-vreg-min-voltage = <2800000 0 1200000 2850000>;
+		qcom,cam-vreg-max-voltage = <2800000 0 1200000 2850000>;
+		qcom,cam-vreg-op-mode = <80000 0 200000 100000>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_default
+				&cam_sensor_rear_reset
+				&cam_sensor_rear_vana>;
+		pinctrl-1 = <&cam_sensor_mclk0_sleep
+				&cam_sensor_rear_reset_sleep
+				&cam_sensor_rear_vana_sleep>;
+		gpios = <&tlmm 26 0>,
+			<&tlmm 36 0>,
+			<&tlmm 35 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-vana = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK0",
+			"CAM_RESET0",
+			"CAM_VANA";
+		qcom,sensor-position = <0>;
+		qcom,sensor-mode = <0>;
+		qcom,cci-master = <0>;
+		status = "ok";
+		clocks = <&clock_gcc clk_mclk0_clk_src>,
+				<&clock_gcc clk_gcc_camss_mclk0_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <24000000 0>;
+	};
+
+	qcom,camera@1 {
+		cell-index = <1>;
+		compatible = "qcom,camera";
+		reg = <0x1>;
+		qcom,csiphy-sd-index = <1>;
+		qcom,csid-sd-index = <1>;
+		qcom,mount-angle = <90>;
+		cam_vdig-supply = <&pm8953_l3>;
+		cam_vana-supply = <&pm8953_l22>;
+		cam_vio-supply = <&pm8953_l6>;
+		cam_vaf-supply = <&pm8953_l17>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+							"cam_vaf";
+		qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_default
+				&cam_sensor_front_default>;
+		pinctrl-1 = <&cam_sensor_mclk1_sleep
+				&cam_sensor_front_sleep>;
+		gpios = <&tlmm 27 0>,
+			<&tlmm 38 0>,
+			<&tlmm 50 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK1",
+			"CAM_RESET1",
+			"CAM_STANDBY1";
+		qcom,sensor-position = <0x100>;
+		qcom,sensor-mode = <1>;
+		qcom,cci-master = <1>;
+		clocks = <&clock_gcc clk_mclk1_clk_src>,
+				<&clock_gcc clk_gcc_camss_mclk1_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <24000000 0>;
+	};
+
+	qcom,camera@2 {
+		cell-index = <2>;
+		compatible = "qcom,camera";
+		reg = <0x02>;
+		qcom,csiphy-sd-index = <1>;
+		qcom,csid-sd-index = <1>;
+		qcom,mount-angle = <90>;
+		qcom,eeprom-src = <&eeprom1>;
+		qcom,actuator-src = <&actuator1>;
+		cam_vdig-supply = <&pm8953_l23>;
+		cam_vana-supply = <&pm8953_l22>;
+		cam_vio-supply = <&pm8953_l6>;
+		cam_vaf-supply = <&pm8953_l17>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+					"cam_vaf";
+		qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+		qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+		qcom,gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_default
+				&cam_sensor_front1_default>;
+		pinctrl-1 = <&cam_sensor_mclk2_sleep
+				&cam_sensor_front1_sleep>;
+		gpios = <&tlmm 28 0>,
+			<&tlmm 40 0>,
+			<&tlmm 39 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK2",
+					  "CAM_RESET2",
+					  "CAM_STANDBY2";
+		qcom,sensor-position = <1>;
+		qcom,sensor-mode = <0>;
+		qcom,cci-master = <0>;
+		status = "ok";
+		clocks = <&clock_gcc clk_mclk2_clk_src>,
+			<&clock_gcc clk_gcc_camss_mclk2_clk>;
+		clock-names = "cam_src_clk", "cam_clk";
+		qcom,clock-rates = <24000000 0>;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm439-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm439-cdp.dtsi
index 5512297..83a4651 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-cdp.dtsi
@@ -11,6 +11,8 @@
  * GNU General Public License for more details.
  */
 
+#include "sdm439-camera-sensor-cdp.dtsi"
+
 &blsp1_uart2 {
 	status = "ok";
 };
@@ -63,3 +65,106 @@
 
 	status = "ok";
 };
+
+&soc {
+	gpio_keys {
+		compatible = "gpio-keys";
+		input-name = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&gpio_key_active>;
+
+		camera_focus {
+			label = "camera_focus";
+			gpios = <&tlmm 128 0x1>;
+			linux,input-type = <1>;
+			linux,code = <0x210>;
+			debounce-interval = <15>;
+			linux,can-disable;
+			gpio-key,wakeup;
+		};
+
+		camera_snapshot {
+			label = "camera_snapshot";
+			gpios = <&tlmm 127 0x1>;
+			linux,input-type = <1>;
+			linux,code = <0x2fe>;
+			debounce-interval = <15>;
+			linux,can-disable;
+			gpio-key,wakeup;
+		};
+
+		vol_up {
+			label = "volume_up";
+			gpios = <&tlmm 91 0x1>;
+			linux,input-type = <1>;
+			linux,code = <115>;
+			debounce-interval = <15>;
+			linux,can-disable;
+			gpio-key,wakeup;
+		};
+	};
+};
+
+&pm8953_gpios {
+	bklt_en {
+		bklt_en_default: bklt_en_default {
+		pins = "gpio4";
+		function = "normal";
+		power-source = <0>;
+		output-high;
+		};
+	};
+};
+
+&pm8953_pwm {
+	status = "ok";
+};
+
+#include "msm8937-mdss-panels.dtsi"
+
+&mdss_mdp {
+	qcom,mdss-pref-prim-intf = "dsi";
+};
+
+&mdss_dsi {
+	hw-config = "single_dsi";
+};
+
+&mdss_dsi0 {
+	qcom,dsi-pref-prim-pan = <&dsi_hx8399c_truly_vid>;
+	pinctrl-names = "mdss_default", "mdss_sleep";
+	pinctrl-0 = <&mdss_dsi_active &mdss_te_active &bklt_en_default>;
+	pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>;
+
+	qcom,platform-bklight-en-gpio = <&pm8953_gpios 4 0>;
+	qcom,platform-te-gpio = <&tlmm 24 0>;
+	qcom,platform-reset-gpio = <&tlmm 61 0>;
+	lab-supply = <&lcdb_ldo_vreg>;
+	ibb-supply = <&lcdb_ncp_vreg>;
+
+};
+
+&dsi_hx8399c_truly_vid {
+	qcom,mdss-dsi-panel-timings =
+		[f3 3a 26 00 6c 6e 2c 3e 2f 03 04 00];
+	qcom,mdss-dsi-t-clk-post = <0x02>;
+	qcom,mdss-dsi-t-clk-pre = <0x2d>;
+	qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+	qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm";
+	qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>;
+	qcom,mdss-dsi-bl-pmic-bank-select = <0>;
+	qcom,mdss-dsi-pwm-gpio = <&pm8953_gpios 8 0>;
+	qcom,mdss-dsi-pan-enable-dynamic-fps;
+	qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp";
+};
+
+
+&dsi_hx8399c_hd_vid {
+	qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+	qcom,mdss-dsi-pan-enable-dynamic-fps;
+	qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp";
+	qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm";
+	qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>;
+	qcom,mdss-dsi-bl-pmic-bank-select = <0>;
+	qcom,mdss-dsi-pwm-gpio = <&pm8953_gpios 8 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm439-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm439-mtp.dtsi
index 5512297..17218a8 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-mtp.dtsi
@@ -11,6 +11,8 @@
  * GNU General Public License for more details.
  */
 
+#include "sdm439-camera-sensor-mtp.dtsi"
+
 &blsp1_uart2 {
 	status = "ok";
 };
@@ -63,3 +65,105 @@
 
 	status = "ok";
 };
+
+&soc {
+	gpio_keys {
+		compatible = "gpio-keys";
+		input-name = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&gpio_key_active>;
+
+		camera_focus {
+			label = "camera_focus";
+			gpios = <&tlmm 128 0x1>;
+			linux,input-type = <1>;
+			linux,code = <0x210>;
+			debounce-interval = <15>;
+			linux,can-disable;
+			gpio-key,wakeup;
+		};
+
+		camera_snapshot {
+			label = "camera_snapshot";
+			gpios = <&tlmm 127 0x1>;
+			linux,input-type = <1>;
+			linux,code = <0x2fe>;
+			debounce-interval = <15>;
+			linux,can-disable;
+			gpio-key,wakeup;
+		};
+
+		vol_up {
+			label = "volume_up";
+			gpios = <&tlmm 91 0x1>;
+			linux,input-type = <1>;
+			linux,code = <115>;
+			debounce-interval = <15>;
+			linux,can-disable;
+			gpio-key,wakeup;
+		};
+	};
+};
+
+#include "msm8937-mdss-panels.dtsi"
+
+&pm8953_gpios {
+	bklt_en {
+		bklt_en_default: bklt_en_default {
+		pins = "gpio4";
+		function = "normal";
+		power-source = <0>;
+		output-high;
+		};
+	};
+};
+
+&pm8953_pwm {
+	status = "ok";
+};
+
+&mdss_mdp {
+	qcom,mdss-pref-prim-intf = "dsi";
+};
+
+&mdss_dsi {
+	hw-config = "single_dsi";
+};
+
+&mdss_dsi0 {
+	qcom,dsi-pref-prim-pan = <&dsi_hx8399c_truly_vid>;
+	pinctrl-names = "mdss_default", "mdss_sleep";
+	pinctrl-0 = <&mdss_dsi_active &mdss_te_active &bklt_en_default>;
+	pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>;
+
+	qcom,platform-bklight-en-gpio = <&pm8953_gpios 4 0>;
+	qcom,platform-te-gpio = <&tlmm 24 0>;
+	qcom,platform-reset-gpio = <&tlmm 61 0>;
+	lab-supply = <&lcdb_ldo_vreg>;
+	ibb-supply = <&lcdb_ncp_vreg>;
+
+};
+
+&dsi_hx8399c_truly_vid {
+	qcom,mdss-dsi-panel-timings =
+		[f3 3a 26 00 6c 6e 2c 3e 2f 03 04 00];
+	qcom,mdss-dsi-t-clk-post = <0x02>;
+	qcom,mdss-dsi-t-clk-pre = <0x2d>;
+	qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm";
+	qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>;
+	qcom,mdss-dsi-bl-pmic-bank-select = <0>;
+	qcom,mdss-dsi-pwm-gpio = <&pm8953_gpios 8 0>;
+	qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+	qcom,mdss-dsi-pan-enable-dynamic-fps;
+	qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp";
+};
+
+&dsi_hx8399c_hd_vid {
+	qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+	qcom,mdss-dsi-pan-enable-dynamic-fps;
+	qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp";
+	qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm";
+	qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>;
+	qcom,mdss-dsi-bl-pmic-bank-select = <0>;
+	qcom,mdss-dsi-pwm-gpio = <&pm8953_gpios 8 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm439-pm8953.dtsi b/arch/arm64/boot/dts/qcom/sdm439-pm8953.dtsi
index 1c0a1fc..3c8a298 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-pm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-pm8953.dtsi
@@ -125,8 +125,8 @@
 };
 
 &mdss_dsi {
-	/delete-property/ vdda-supply;
-	/delete-property/ vddio-supply;
+	vdda-supply = <&pm8953_l2>; /*1.2V*/
+	vddio-supply = <&pm8953_l6>; /*1.8V*/
 };
 
 &usb_otg {
@@ -137,21 +137,22 @@
 };
 
 &mdss_dsi0_pll {
-	/delete-property/ vddio-supply;
+	vddio-supply = <&pm8953_l6>;
 };
 
 &mdss_dsi1_pll {
-	/delete-property/ vddio-supply;
+	vddio-supply = <&pm8953_l6>;
 };
 
 &mdss_dsi0 {
-	/delete-property/ vdd-supply;
-	/delete-property/ vddio-supply;
+	vdd-supply = <&pm8953_l17>;
+	vddio-supply = <&pm8953_l6>;
 };
 
 &mdss_dsi1 {
-	/delete-property/ vdd-supply;
-	/delete-property/ vddio-supply;
+	status = "disabled";
+	vdd-supply = <&pm8953_l17>;
+	vddio-supply = <&pm8953_l6>;
 };
 
 &int_codec {
@@ -266,3 +267,33 @@
 	/delete-node/ case_therm;
 };
 
+&pil_mss {
+	vdd_mss-supply = <&pm8953_s1>;
+	vdd_cx-supply = <&pm8953_s2_level>;
+	vdd_cx-voltage = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+	vdd_mx-supply = <&pm8953_s7_level_ao>;
+	vdd_mx-uV = <RPM_SMD_REGULATOR_LEVEL_TURBO>;
+	vdd_pll-supply = <&pm8953_l7>;
+};
+
+&soc {
+	qcom,lpass@c200000 {
+		vdd_cx-supply = <&pm8953_s2_level>;
+	};
+
+	qcom,pronto@a21b000 {
+		vdd_pronto_pll-supply = <&pm8953_l7>;
+	};
+
+	qcom,wcnss-wlan@0a000000 {
+		qcom,pronto-vddmx-supply = <&pm8953_s7_level_ao>;
+		qcom,pronto-vddcx-supply = <&pm8953_s2_level>;
+		qcom,pronto-vddpx-supply = <&pm8953_l5>;
+		qcom,iris-vddxo-supply   = <&pm8953_l7>;
+		qcom,iris-vddrfa-supply  = <&pm8953_l19>;
+		qcom,iris-vddpa-supply   = <&pm8953_l9>;
+		qcom,iris-vdddig-supply  = <&pm8953_l5>;
+		qcom,wcnss-adc_tm = <&pm8953_adc_tm>;
+	};
+};
+
diff --git a/arch/arm64/boot/dts/qcom/sdm439-qrd.dtsi b/arch/arm64/boot/dts/qcom/sdm439-qrd.dtsi
index 5512297..24748dd 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-qrd.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-qrd.dtsi
@@ -40,6 +40,24 @@
 	status = "ok";
 };
 
+&int_codec {
+	status = "okay";
+	qcom,model = "sdm439-sku1-snd-card";
+	qcom,msm-micbias1-ext-cap;
+	qcom,msm-micbias2-ext-cap;
+	qcom,msm-mbhc-hphl-swh = <1>;
+	qcom,msm-mbhc-gnd-swh = <0>;
+	qcom,msm-hs-micbias-type = "external";
+};
+
+&wsa881x_i2c_f {
+	status = "okay";
+};
+
+&wsa881x_i2c_45 {
+	status = "okay";
+};
+
 &sdhc_2 {
 	/* device core power supply */
 	vdd-supply = <&pm8953_l11>;
@@ -63,3 +81,22 @@
 
 	status = "ok";
 };
+
+&soc {
+	gpio_keys {
+		compatible = "gpio-keys";
+		input-name = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&gpio_key_active>;
+
+		vol_up {
+			label = "volume_up";
+			gpios = <&tlmm 91 0x1>;
+			linux,input-type = <1>;
+			linux,code = <115>;
+			debounce-interval = <15>;
+			linux,can-disable;
+			gpio-key,wakeup;
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi
index f9bef43..08c9e4f 100644
--- a/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439-regulator.dtsi
@@ -174,7 +174,7 @@
 		qcom,hpm-min-load = <10000>;
 		status = "okay";
 		pm8953_l4: regulator-l4 {
-			compatible = "qcom,rpm-smd-regulator-resource";
+			compatible = "qcom,rpm-smd-regulator";
 			regulator-name = "pm8953_l4";
 			qcom,set = <3>;
 			regulator-min-microvolt = <1800000>;
@@ -291,7 +291,7 @@
 		qcom,hpm-min-load = <5000>;
 		status = "okay";
 		pm8953_l14: regulator-l14 {
-			compatible = "qcom,rpm-smd-regulator-resource";
+			compatible = "qcom,rpm-smd-regulator";
 			regulator-name = "pm8953_l14";
 			qcom,set = <3>;
 			regulator-min-microvolt = <1800000>;
@@ -309,7 +309,7 @@
 		qcom,hpm-min-load = <5000>;
 		status = "okay";
 		pm8953_l15: regulator-l15 {
-			compatible = "qcom,rpm-smd-regulator-resource";
+			compatible = "qcom,rpm-smd-regulator";
 			regulator-name = "pm8953_l15";
 			qcom,set = <3>;
 			regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/qcom/sdm439.dtsi b/arch/arm64/boot/dts/qcom/sdm439.dtsi
index 13bcf1b..422a95f 100644
--- a/arch/arm64/boot/dts/qcom/sdm439.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439.dtsi
@@ -32,3 +32,58 @@
 		/delete-property/ qcom,mipi-csi-vdd-supply;
 	};
 };
+
+&energy_costs {
+	compatible = "sched-energy";
+
+	CPU_COST_0: core-cost0 {
+		busy-cost-data = <
+			8000000	137
+			1001600	165
+			1305600	207
+			1497600	256
+			1708800	327
+			1958400	445
+		>;
+		idle-cost-data = <
+			100 80 60 40
+		>;
+	};
+	CPU_COST_1: core-cost1 {
+		busy-cost-data = <
+			8000000	45
+			1001600	56
+			1171200	71
+			1305600	89
+			1459200	120
+		>;
+		idle-cost-data = <
+			40 20 10 8
+		>;
+	};
+	CLUSTER_COST_0: cluster-cost0 {
+			busy-cost-data = <
+			8000000	49
+			1001600	53
+			1305600	61
+			1497600	71
+			1708800	85
+			1958400	110
+		>;
+		idle-cost-data = <
+			4 3 2 1
+		>;
+	};
+	CLUSTER_COST_1: cluster-cost1 {
+			busy-cost-data = <
+			8000000	9
+			1001600	10
+			1171200	13
+			1305600	15
+			1459200	20
+		>;
+		idle-cost-data = <
+			4 3 2 1
+		>;
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm632-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm632-regulator.dtsi
index ed7ec2a..060b8996 100644
--- a/arch/arm64/boot/dts/qcom/sdm632-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm632-regulator.dtsi
@@ -13,6 +13,42 @@
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 
+&pm8953_s3 {
+	regulator-min-microvolt = <984000>;
+	regulator-max-microvolt = <1240000>;
+	qcom,init-voltage = <984000>;
+};
+
+&pm8953_s4 {
+	regulator-min-microvolt = <1036000>;
+	regulator-max-microvolt = <2040000>;
+	qcom,init-voltage = <1036000>;
+};
+
+&pm8953_l1 {
+	regulator-min-microvolt = <975000>;
+	regulator-max-microvolt = <1050000>;
+	qcom,init-voltage = <975000>;
+};
+
+&pm8953_l2 {
+	regulator-min-microvolt = <975000>;
+	regulator-max-microvolt = <1175000>;
+	qcom,init-voltage = <975000>;
+};
+
+&pm8953_l10 {
+	regulator-min-microvolt = <2800000>;
+	regulator-max-microvolt = <3000000>;
+	qcom,init-voltage = <2800000>;
+};
+
+&pm8953_l22 {
+	regulator-min-microvolt = <2800000>;
+	regulator-max-microvolt = <2800000>;
+	qcom,init-voltage = <2800000>;
+};
+
 &rpm_bus {
 	rpm-regulator-ldoc1 {
 		status = "okay";
@@ -150,7 +186,7 @@
 				qcom,cpr-corner-fmax-map = <1 2 3 4 7>;
 
 				qcom,cpr-voltage-ceiling =
-					<720000  720000 790000 865000 920000
+					<720000  790000 865000 865000 920000
 					 990000 1065000>;
 
 				qcom,cpr-voltage-floor =
@@ -162,7 +198,7 @@
 				qcom,corner-frequencies =
 					<614400000  883200000 1036800000
 					1363200000 1536000000 1670400000
-					1785600000>;
+					1804800000>;
 
 				qcom,cpr-ro-scaling-factor =
 				      <3600 3600 3830 2430 2520 2700 1790 1760
@@ -200,7 +236,7 @@
 				qcom,cpr-corner-fmax-map = <1 2 5>;
 
 				qcom,cpr-voltage-ceiling =
-					<790000 865000 920000 990000 1065000>;
+					<865000 865000 920000 990000 1065000>;
 
 				qcom,cpr-voltage-floor =
 					<500000  500000 500000 500000 500000>;
@@ -209,7 +245,7 @@
 
 				qcom,corner-frequencies =
 					<1094400000 1401600000 1555200000
-					 1785600000 1996200000>;
+					 1804800000 2016000000>;
 
 				qcom,cpr-ro-scaling-factor =
 				      <3600 3600 3830 2430 2520 2700 1790 1760
diff --git a/arch/arm64/boot/dts/qcom/sdm632.dtsi b/arch/arm64/boot/dts/qcom/sdm632.dtsi
index f1fe11d..813b89d 100644
--- a/arch/arm64/boot/dts/qcom/sdm632.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm632.dtsi
@@ -22,6 +22,10 @@
 	compatible = "qcom,sdm632";
 	qcom,msm-id = <349 0x0>;
 	qcom,msm-name = "SDM632";
+
+	chosen {
+		/delete-property/ bootargs;
+	};
 };
 
 &clock_gcc_mdss {
@@ -788,42 +792,40 @@
 
 &clock_cpu {
 	/delete-property/ vdd-cl-supply;
-	status = "disabled";
 	compatible = "qcom,cpu-clock-sdm632";
 	reg =   <0xb114000  0x68>,
 		<0xb014000  0x68>,
-		<0xb016000  0x8>,
-		<0xb116000  0x8>,
-		<0xb1d0000  0x8>,
 		<0xb011050  0x8>,
 		<0xb111050  0x8>,
 		<0xb1d1050  0x8>,
-		<0x00a412c  0x8>;
+		<0xb011050  0x8>,
+		<0xb111050  0x8>,
+		<0x00a4124  0x8>;
 	reg-names = "rcgwr-c0-base", "rcgwr-c1-base",
-		    "apcs-c1-pll-base", "apcs-c0-pll-base",
-		    "apcs-cci-pll-base", "apcs-c1-rcg-base",
-		    "apcs-c0-rcg-base", "apcs-cci-rcg-base",
-		    "efuse";
+		    "apcs-c1-rcg-base", "apcs-c0-rcg-base",
+		    "apcs-cci-rcg-base", "c1-mux",
+		    "c0-mux", "efuse";
 	qcom,num-clusters = <2>;
+	vdd-c0-supply = <&apc0_pwrcl_vreg>;
+	vdd-c1-supply = <&apc1_perfcl_vreg>;
+	vdd-cci-supply = <&apc0_pwrcl_vreg>;
 	clocks = <&clock_gcc clk_xo_a_clk_src>;
 	clock-names = "xo_a";
 	qcom,speed0-bin-v0-c0 =
 		<          0 0>,
 		<   614400000 1>,
 		<   883200000 2>,
-		<  1036200000 3>,
+		<  1036800000 3>,
 		<  1363200000 4>,
-		<  1563000000 5>,
+		<  1536000000 5>,
 		<  1670400000 6>,
 		<  1785600000 7>;
 	qcom,speed0-bin-v0-c1 =
 		<          0 0>,
-		<   633600000 1>,
-		<   902400000 2>,
-		<  1094400000 3>,
-		<  1401600000 4>,
-		<  1555200000 5>,
-		<  1785600000 6>;
+		<  1094400000 1>,
+		<  1401600000 2>,
+		<  1555200000 3>,
+		<  1785600000 4>;
 	qcom,speed0-bin-v0-cci =
 		<          0 0>,
 		<  307200000 1>,
@@ -844,9 +846,9 @@
 			"cpu0_clk",
 			"cpu4_clk";
 		clocks =
-			<&clock_cpu clk_a53_cci_clk >,
-			<&clock_cpu clk_a53_pwr_clk >,
-			<&clock_cpu clk_a53_perf_clk >;
+			<&clock_cpu clk_cci_clk >,
+			<&clock_cpu clk_pwr_clk >,
+			<&clock_cpu clk_perf_clk >;
 
 		qcom,governor-per-policy;
 
@@ -871,7 +873,7 @@
 	cci_cache: qcom,cci {
 		compatible = "devfreq-simple-dev";
 		clock-names = "devfreq_clk";
-		clocks = <&clock_cpu clk_a53_cci_clk >;
+		clocks = <&clock_cpu clk_cci_clk >;
 		governor = "cpufreq";
 		freq-tbl-khz =
 			<  307200 >,
diff --git a/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi b/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi
index f6ce559..e86117d 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi
@@ -63,6 +63,7 @@
 
 		qcom,gpu-quirk-hfi-use-reg;
 		qcom,gpu-quirk-limit-uche-gbif-rw;
+		qcom,gpu-quirk-secvid-set-once;
 
 		/* <HZ/12> */
 		qcom,idle-timeout = <80>;
@@ -147,12 +148,14 @@
 				qcom,gpu-quirk-hfi-use-reg;
 				qcom,gpu-quirk-limit-uche-gbif-rw;
 				qcom,gpu-quirk-mmu-secure-cb-alt;
+				qcom,gpu-quirk-secvid-set-once;
 			};
 
 			qcom,soc-hw-revision-1 {
 				qcom,soc-hw-revision = <1>;
 				qcom,chipid = <0x06010501>;
 				qcom,gpu-quirk-hfi-use-reg;
+				qcom,gpu-quirk-secvid-set-once;
 			};
 		};
 
@@ -357,7 +360,7 @@
 					reg = <0>;
 					qcom,gpu-freq = <700000000>;
 					qcom,bus-freq = <11>;
-					qcom,bus-min = <8>;
+					qcom,bus-min = <9>;
 					qcom,bus-max = <11>;
 				};
 
@@ -365,7 +368,7 @@
 				qcom,gpu-pwrlevel@1 {
 					reg = <1>;
 					qcom,gpu-freq = <650000000>;
-					qcom,bus-freq = <11>;
+					qcom,bus-freq = <10>;
 					qcom,bus-min = <8>;
 					qcom,bus-max = <11>;
 				};
@@ -374,27 +377,27 @@
 				qcom,gpu-pwrlevel@2 {
 					reg = <2>;
 					qcom,gpu-freq = <565000000>;
-					qcom,bus-freq = <11>;
+					qcom,bus-freq = <9>;
 					qcom,bus-min = <8>;
-					qcom,bus-max = <11>;
+					qcom,bus-max = <10>;
 				};
 
 				/* SVS_L1 */
 				qcom,gpu-pwrlevel@3 {
 					reg = <3>;
 					qcom,gpu-freq = <430000000>;
-					qcom,bus-freq = <11>;
-					qcom,bus-min = <8>;
-					qcom,bus-max = <11>;
+					qcom,bus-freq = <8>;
+					qcom,bus-min = <7>;
+					qcom,bus-max = <10>;
 				};
 
 				/* SVS */
 				qcom,gpu-pwrlevel@4 {
 					reg = <4>;
 					qcom,gpu-freq = <355000000>;
-					qcom,bus-freq = <8>;
+					qcom,bus-freq = <7>;
 					qcom,bus-min = <5>;
-					qcom,bus-max = <9>;
+					qcom,bus-max = <8>;
 				};
 
 				/* LOW SVS */
@@ -403,7 +406,7 @@
 					qcom,gpu-freq = <267000000>;
 					qcom,bus-freq = <6>;
 					qcom,bus-min = <4>;
-					qcom,bus-max = <8>;
+					qcom,bus-max = <7>;
 				};
 
 				/* MIN SVS */
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 152b760..4d4e918 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -2469,6 +2469,7 @@
 		compatible = "qcom,msm-fastrpc-compute";
 		qcom,adsp-remoteheap-vmid = <22 37>;
 		qcom,fastrpc-adsp-audio-pdr;
+		qcom,fastrpc-adsp-sensors-pdr;
 
 		qcom,msm_fastrpc_compute_cb1 {
 			compatible = "qcom,msm-fastrpc-compute-cb";
@@ -2543,6 +2544,7 @@
 			label = "adsprpc-smd";
 			iommus = <&apps_smmu 0x1806 0x0>;
 			dma-coherent;
+			shared-cb;
 		};
 	};
 
@@ -2561,7 +2563,7 @@
 		qca,bt-vdd-ldo-current-level = <1>; /* LPM/PFM */
 	};
 
-	qcom,icnss@18800000 {
+	icnss: qcom,icnss@18800000 {
 		compatible = "qcom,icnss";
 		reg = <0x18800000 0x800000>,
 		      <0xa0000000 0x10000000>,
diff --git a/arch/arm64/boot/dts/qcom/sdm710-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-cdp-overlay.dts
new file mode 100644
index 0000000..a61d714
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-cdp-overlay.dts
@@ -0,0 +1,34 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "sdm670-audio-overlay.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <1 0>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
+
diff --git a/arch/arm64/boot/dts/qcom/sdm710-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-cdp.dts
new file mode 100644
index 0000000..a39ee9e
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-cdp.dts
@@ -0,0 +1,27 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "sdm670-audio-overlay.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,board-id = <1 0>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-cdp-overlay.dts
new file mode 100644
index 0000000..c64e623
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-cdp-overlay.dts
@@ -0,0 +1,37 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "sdm670-external-codec.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L Ext. Audio Codec CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <1 1>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
+
+&tavil_snd {
+	qcom,us-euro-gpios = <&tavil_us_euro_sw>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-cdp.dts
new file mode 100644
index 0000000..0b4c3af
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-cdp.dts
@@ -0,0 +1,31 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "sdm670-external-codec.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM 710 PM660 + PM660L Ext. Audio Codec CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,board-id = <1 1>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
+
+&tavil_snd {
+	qcom,us-euro-gpios = <&tavil_us_euro_sw>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-mtp-overlay.dts
new file mode 100644
index 0000000..058a3f1
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-mtp-overlay.dts
@@ -0,0 +1,33 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "sdm670-external-codec.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L Ext. Audio Codec MTP";
+	compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <8 1>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-mtp.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-mtp.dts
new file mode 100644
index 0000000..3920d78
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-mtp.dts
@@ -0,0 +1,27 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "sdm670-external-codec.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM 710 PM660 + PM660L Ext. Audio Codec MTP";
+	compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+	qcom,board-id = <8 1>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-cdp-overlay.dts
new file mode 100644
index 0000000..408a376
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-cdp-overlay.dts
@@ -0,0 +1,38 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-external-codec.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A Ext. Audio Codec CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <1 1>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
+
+&tavil_snd {
+	qcom,us-euro-gpios = <&tavil_us_euro_sw>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-cdp.dts
new file mode 100644
index 0000000..1257c64
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-cdp.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 "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-external-codec.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM 710 PM660 + PM660A Ext. Audio Codec CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,board-id = <1 1>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
+
+&tavil_snd {
+	qcom,us-euro-gpios = <&tavil_us_euro_sw>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-mtp-overlay.dts
new file mode 100644
index 0000000..9a41edd
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-mtp-overlay.dts
@@ -0,0 +1,34 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-external-codec.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A Ext. Audio Codec MTP";
+	compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <8 1>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-mtp.dts b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-mtp.dts
new file mode 100644
index 0000000..e519095
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-external-codec-pm660a-mtp.dts
@@ -0,0 +1,28 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-external-codec.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM 710 PM660 + PM660A Ext. Audio Codec MTP";
+	compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+	qcom,board-id = <8 1>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-mtp-overlay.dts
new file mode 100644
index 0000000..aa8ba6a
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-mtp-overlay.dts
@@ -0,0 +1,33 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "sdm670-audio-overlay.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L MTP";
+	compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <8 0>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-mtp.dts b/arch/arm64/boot/dts/qcom/sdm710-mtp.dts
new file mode 100644
index 0000000..c081d00
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-mtp.dts
@@ -0,0 +1,27 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "sdm670-audio-overlay.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L MTP";
+	compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+	qcom,board-id = <8 0>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-pm660a-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-pm660a-cdp-overlay.dts
new file mode 100644
index 0000000..66afaad
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-pm660a-cdp-overlay.dts
@@ -0,0 +1,74 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-audio-overlay.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <1 0>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
+
+&dsi_dual_nt35597_truly_video_display {
+	/delete-property/ qcom,dsi-display-active;
+};
+
+&dsi_panel_pwr_supply_labibb_amoled {
+	qcom,panel-supply-entry@2 {
+		reg = <2>;
+		qcom,supply-name = "lab";
+		qcom,supply-min-voltage = <4600000>;
+		qcom,supply-max-voltage = <6100000>;
+		qcom,supply-enable-load = <100000>;
+		qcom,supply-disable-load = <100>;
+	};
+
+	qcom,panel-supply-entry@3 {
+		reg = <3>;
+		qcom,supply-name = "ibb";
+		qcom,supply-min-voltage = <4000000>;
+		qcom,supply-max-voltage = <6300000>;
+		qcom,supply-enable-load = <100000>;
+		qcom,supply-disable-load = <100>;
+	};
+
+	qcom,panel-supply-entry@4 {
+		reg = <4>;
+		qcom,supply-name = "oledb";
+		qcom,supply-min-voltage = <5000000>;
+		qcom,supply-max-voltage = <8100000>;
+		qcom,supply-enable-load = <100000>;
+		qcom,supply-disable-load = <100>;
+	};
+};
+
+&dsi_rm67195_amoled_fhd_cmd_display {
+	qcom,dsi-display-active;
+	lab-supply = <&lab_regulator>;
+	ibb-supply = <&ibb_regulator>;
+	oledb-supply = <&pm660a_oledb>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-pm660a-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-pm660a-cdp.dts
new file mode 100644
index 0000000..2786717
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-pm660a-cdp.dts
@@ -0,0 +1,68 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-audio-overlay.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,board-id = <1 0>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
+
+&dsi_dual_nt35597_truly_video_display {
+	/delete-property/ qcom,dsi-display-active;
+};
+
+&dsi_panel_pwr_supply_labibb_amoled {
+	qcom,panel-supply-entry@2 {
+		reg = <2>;
+		qcom,supply-name = "lab";
+		qcom,supply-min-voltage = <4600000>;
+		qcom,supply-max-voltage = <6100000>;
+		qcom,supply-enable-load = <100000>;
+		qcom,supply-disable-load = <100>;
+	};
+
+	qcom,panel-supply-entry@3 {
+		reg = <3>;
+		qcom,supply-name = "ibb";
+		qcom,supply-min-voltage = <4000000>;
+		qcom,supply-max-voltage = <6300000>;
+		qcom,supply-enable-load = <100000>;
+		qcom,supply-disable-load = <100>;
+	};
+
+	qcom,panel-supply-entry@4 {
+		reg = <4>;
+		qcom,supply-name = "oledb";
+		qcom,supply-min-voltage = <5000000>;
+		qcom,supply-max-voltage = <8100000>;
+		qcom,supply-enable-load = <100000>;
+		qcom,supply-disable-load = <100>;
+	};
+};
+
+&dsi_rm67195_amoled_fhd_cmd_display {
+	qcom,dsi-display-active;
+	lab-supply = <&lab_regulator>;
+	ibb-supply = <&ibb_regulator>;
+	oledb-supply = <&pm660a_oledb>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-pm660a-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-pm660a-mtp-overlay.dts
new file mode 100644
index 0000000..d9b055d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-pm660a-mtp-overlay.dts
@@ -0,0 +1,34 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-audio-overlay.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A MTP";
+	compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <8 0>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-pm660a-mtp.dts b/arch/arm64/boot/dts/qcom/sdm710-pm660a-mtp.dts
new file mode 100644
index 0000000..97bbf2b
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-pm660a-mtp.dts
@@ -0,0 +1,28 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-audio-overlay.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A MTP";
+	compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+	qcom,board-id = <8 0>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-pm660a-tasha-codec-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-pm660a-tasha-codec-cdp-overlay.dts
new file mode 100644
index 0000000..7e9eaa7
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-pm660a-tasha-codec-cdp-overlay.dts
@@ -0,0 +1,74 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-tasha-codec.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A + Tasha Codec CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <1 5>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
+
+&dsi_dual_nt35597_truly_video_display {
+	/delete-property/ qcom,dsi-display-active;
+};
+
+&dsi_panel_pwr_supply_labibb_amoled {
+	qcom,panel-supply-entry@2 {
+		reg = <2>;
+		qcom,supply-name = "lab";
+		qcom,supply-min-voltage = <4600000>;
+		qcom,supply-max-voltage = <6100000>;
+		qcom,supply-enable-load = <100000>;
+		qcom,supply-disable-load = <100>;
+	};
+
+	qcom,panel-supply-entry@3 {
+		reg = <3>;
+		qcom,supply-name = "ibb";
+		qcom,supply-min-voltage = <4000000>;
+		qcom,supply-max-voltage = <6300000>;
+		qcom,supply-enable-load = <100000>;
+		qcom,supply-disable-load = <100>;
+	};
+
+	qcom,panel-supply-entry@4 {
+		reg = <4>;
+		qcom,supply-name = "oledb";
+		qcom,supply-min-voltage = <5000000>;
+		qcom,supply-max-voltage = <8100000>;
+		qcom,supply-enable-load = <100000>;
+		qcom,supply-disable-load = <100>;
+	};
+};
+
+&dsi_rm67195_amoled_fhd_cmd_display {
+	qcom,dsi-display-active;
+	lab-supply = <&lab_regulator>;
+	ibb-supply = <&ibb_regulator>;
+	oledb-supply = <&pm660a_oledb>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-pm660a-tasha-codec-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-pm660a-tasha-codec-cdp.dts
new file mode 100644
index 0000000..f7c654d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-pm660a-tasha-codec-cdp.dts
@@ -0,0 +1,68 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-tasha-codec.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A Tasha Codec CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,board-id = <1 5>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
+
+&dsi_dual_nt35597_truly_video_display {
+	/delete-property/ qcom,dsi-display-active;
+};
+
+&dsi_panel_pwr_supply_labibb_amoled {
+	qcom,panel-supply-entry@2 {
+		reg = <2>;
+		qcom,supply-name = "lab";
+		qcom,supply-min-voltage = <4600000>;
+		qcom,supply-max-voltage = <6100000>;
+		qcom,supply-enable-load = <100000>;
+		qcom,supply-disable-load = <100>;
+	};
+
+	qcom,panel-supply-entry@3 {
+		reg = <3>;
+		qcom,supply-name = "ibb";
+		qcom,supply-min-voltage = <4000000>;
+		qcom,supply-max-voltage = <6300000>;
+		qcom,supply-enable-load = <100000>;
+		qcom,supply-disable-load = <100>;
+	};
+
+	qcom,panel-supply-entry@4 {
+		reg = <4>;
+		qcom,supply-name = "oledb";
+		qcom,supply-min-voltage = <5000000>;
+		qcom,supply-max-voltage = <8100000>;
+		qcom,supply-enable-load = <100000>;
+		qcom,supply-disable-load = <100>;
+	};
+};
+
+&dsi_rm67195_amoled_fhd_cmd_display {
+	qcom,dsi-display-active;
+	lab-supply = <&lab_regulator>;
+	ibb-supply = <&ibb_regulator>;
+	oledb-supply = <&pm660a_oledb>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-qrd-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-qrd-overlay.dts
new file mode 100644
index 0000000..803616d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-qrd-overlay.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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-qrd.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L QRD";
+	compatible = "qcom,sdm670-qrd", "qcom,sdm670", "qcom,qrd";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <0x0002000b 0>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-qrd-sku2-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-qrd-sku2-overlay.dts
new file mode 100644
index 0000000..ab3ce4d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-qrd-sku2-overlay.dts
@@ -0,0 +1,51 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-qrd.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L QRD SKU2";
+	compatible = "qcom,sdm670-qrd", "qcom,sdm670", "qcom,qrd";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <0x0012000b 0>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
+
+&dsi_dual_nt36850_truly_cmd_display {
+	/delete-property/ qcom,dsi-display-active;
+};
+
+&dsi_hx8399_truly_cmd {
+	qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+	qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+	qcom,mdss-dsi-bl-min-level = <1>;
+	qcom,mdss-dsi-bl-max-level = <4095>;
+	qcom,panel-mode-gpio = <&tlmm 76 0>;
+	qcom,mdss-dsi-mode-sel-gpio-state = "single_port";
+	qcom,platform-reset-gpio = <&tlmm 75 0>;
+	qcom,platform-te-gpio = <&tlmm 10 0>;
+};
+
+&dsi_hx8399_truly_cmd_display {
+	qcom,dsi-display-active;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-qrd-sku2.dts b/arch/arm64/boot/dts/qcom/sdm710-qrd-sku2.dts
new file mode 100644
index 0000000..76b2862
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-qrd-sku2.dts
@@ -0,0 +1,45 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-qrd.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L QRD SKU2";
+	compatible = "qcom,sdm670-qrd", "qcom,sdm670", "qcom,qrd";
+	qcom,board-id = <0x0012000b 0>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
+
+&dsi_dual_nt36850_truly_cmd_display {
+	/delete-property/ qcom,dsi-display-active;
+};
+
+&dsi_hx8399_truly_cmd {
+	qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+	qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+	qcom,mdss-dsi-bl-min-level = <1>;
+	qcom,mdss-dsi-bl-max-level = <4095>;
+	qcom,panel-mode-gpio = <&tlmm 76 0>;
+	qcom,mdss-dsi-mode-sel-gpio-state = "single_port";
+	qcom,platform-reset-gpio = <&tlmm 75 0>;
+	qcom,platform-te-gpio = <&tlmm 10 0>;
+};
+
+&dsi_hx8399_truly_cmd_display {
+	qcom,dsi-display-active;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-qrd.dts b/arch/arm64/boot/dts/qcom/sdm710-qrd.dts
new file mode 100644
index 0000000..e3cb7cc
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-qrd.dts
@@ -0,0 +1,26 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-qrd.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L QRD";
+	compatible = "qcom,sdm670-qrd", "qcom,sdm670", "qcom,qrd";
+	qcom,board-id = <0x0002000b 0>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-tasha-codec-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-tasha-codec-cdp-overlay.dts
new file mode 100644
index 0000000..1632ebf
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-tasha-codec-cdp-overlay.dts
@@ -0,0 +1,33 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "sdm670-tasha-codec.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L Tasha Codec CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <1 5>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-tasha-codec-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-tasha-codec-cdp.dts
new file mode 100644
index 0000000..456e3d2
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-tasha-codec-cdp.dts
@@ -0,0 +1,27 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "sdm670-tasha-codec.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L Tasha Codec CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,board-id = <1 5>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-cdp-overlay.dts
new file mode 100644
index 0000000..fe05472
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-cdp-overlay.dts
@@ -0,0 +1,34 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "sdm670-int-cdc-usbc-audio-overlay.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L, USB-C Audio, CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <1 2>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
+
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-cdp.dts
new file mode 100644
index 0000000..ac7f59a
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-cdp.dts
@@ -0,0 +1,26 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "sdm670-int-cdc-usbc-audio-overlay.dtsi"
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L, USB-C Audio, CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,board-id = <1 2>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-cdp-overlay.dts
new file mode 100644
index 0000000..846bee4
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-cdp-overlay.dts
@@ -0,0 +1,34 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "sdm670-external-codec.dtsi"
+#include "sdm670-ext-cdc-usbc-audio.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660+PM660L, USB-C Audio, Ext. Audio Codec CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <1 3>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-cdp.dts
new file mode 100644
index 0000000..b3b8254
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-cdp.dts
@@ -0,0 +1,28 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "sdm670-external-codec.dtsi"
+#include "sdm670-ext-cdc-usbc-audio.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM 710 PM660+PM660L, USB-C Audio, Ext. Audio Codec CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,board-id = <1 3>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-mtp-overlay.dts
new file mode 100644
index 0000000..bfc9a7f
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-mtp-overlay.dts
@@ -0,0 +1,33 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "sdm670-external-codec.dtsi"
+#include "sdm670-ext-cdc-usbc-audio.dtsi"
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660+PM660L, USB-C Audio, Ext. Audio Codec MTP";
+	compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <8 3>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-mtp.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-mtp.dts
new file mode 100644
index 0000000..011e6ae
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-mtp.dts
@@ -0,0 +1,28 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "sdm670-external-codec.dtsi"
+#include "sdm670-ext-cdc-usbc-audio.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM 710 PM660+PM660L, USB-C Audio, Ext. Audio Codec MTP";
+	compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+	qcom,board-id = <8 3>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-cdp-overlay.dts
new file mode 100644
index 0000000..f8642bb
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-cdp-overlay.dts
@@ -0,0 +1,36 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-external-codec.dtsi"
+#include "sdm670-ext-cdc-usbc-audio.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660+PM660A, USB-C Audio, Ext. Audio Codec CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <1 3>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
+
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-cdp.dts
new file mode 100644
index 0000000..6e9d9d9
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-cdp.dts
@@ -0,0 +1,29 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-external-codec.dtsi"
+#include "sdm670-ext-cdc-usbc-audio.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM 710 PM660+PM660A, USB-C Audio, Ext. Audio Codec CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,board-id = <1 3>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-mtp-overlay.dts
new file mode 100644
index 0000000..c820950
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-mtp-overlay.dts
@@ -0,0 +1,35 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-external-codec.dtsi"
+#include "sdm670-ext-cdc-usbc-audio.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660+PM660A, USB-C Audio, Ext. Audio Codec MTP";
+	compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <8 3>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-mtp.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-mtp.dts
new file mode 100644
index 0000000..11e7243
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-external-codec-pm660a-mtp.dts
@@ -0,0 +1,29 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-external-codec.dtsi"
+#include "sdm670-ext-cdc-usbc-audio.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM 710 PM660+PM660A, USB-C Audio, Ext. Audio Codec MTP";
+	compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+	qcom,board-id = <8 3>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-mtp-overlay.dts
new file mode 100644
index 0000000..a40ab83
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-mtp-overlay.dts
@@ -0,0 +1,33 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "sdm670-int-cdc-usbc-audio-overlay.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L, USB-C Audio, MTP";
+	compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <8 2>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-mtp.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-mtp.dts
new file mode 100644
index 0000000..1c8ab48
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-mtp.dts
@@ -0,0 +1,27 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "sdm670-int-cdc-usbc-audio-overlay.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660L, USB-C Audio, MTP";
+	compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+	qcom,board-id = <8 2>;
+	qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+		       <0x0001001b 0x0102001a 0x0 0x0>,
+		       <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-cdp-overlay.dts
new file mode 100644
index 0000000..df4c2b9
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-cdp-overlay.dts
@@ -0,0 +1,35 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-int-cdc-usbc-audio-overlay.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A, USB-C Audio, CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <1 2>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
+
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-cdp.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-cdp.dts
new file mode 100644
index 0000000..2f484b5
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-cdp.dts
@@ -0,0 +1,28 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-int-cdc-usbc-audio-overlay.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A, USB-C Audio, CDP";
+	compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+	qcom,board-id = <1 2>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-mtp-overlay.dts
new file mode 100644
index 0000000..35f9570
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-mtp-overlay.dts
@@ -0,0 +1,34 @@
+/* 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/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-int-cdc-usbc-audio-overlay.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A, USB-C Audio, MTP";
+	compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+	qcom,msm-id = <360 0x0>;
+	qcom,board-id = <8 2>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-mtp.dts b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-mtp.dts
new file mode 100644
index 0000000..f71b77a
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710-usbc-pm660a-mtp.dts
@@ -0,0 +1,28 @@
+/* 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 "sdm710.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+#include "sdm670-int-cdc-usbc-audio-overlay.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 PM660 + PM660A, USB-C Audio, MTP";
+	compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+	qcom,board-id = <8 2>;
+	qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+		       <0x0001001b 0x0002001a 0x0 0x0>,
+		       <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710.dts b/arch/arm64/boot/dts/qcom/sdm710.dts
new file mode 100644
index 0000000..da971a3
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710.dts
@@ -0,0 +1,21 @@
+/* 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 "sdm710.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710 SoC";
+	compatible = "qcom,sdm670";
+	qcom,board-id = <0 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm710.dtsi b/arch/arm64/boot/dts/qcom/sdm710.dtsi
new file mode 100644
index 0000000..4a051b0
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm710.dtsi
@@ -0,0 +1,26 @@
+/* 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 "sdm670.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SDM710";
+	compatible = "qcom,sdm670";
+	qcom,msm-id = <360 0x0>;
+};
+
+&msm_gpu {
+	qcom,chipid = <0x06010500>;
+	/delete-property/qcom,gpu-quirk-limit-uche-gbif-rw;
+	/delete-property/qcom,soc-hw-rev-efuse;
+	/delete-node/qcom,soc-hw-revisions;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
index 8d4d7df..6e0bb861 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
@@ -562,6 +562,7 @@
 &dsi_dual_nt35597_truly_cmd {
 	qcom,mdss-dsi-t-clk-post = <0x0D>;
 	qcom,mdss-dsi-t-clk-pre = <0x2D>;
+	qcom,ulps-enabled;
 	qcom,esd-check-enabled;
 	qcom,mdss-dsi-panel-status-check-mode = "reg_read";
 	qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 0a];
@@ -576,6 +577,8 @@
 			qcom,display-topology = <2 0 2>,
 						<1 0 2>;
 			qcom,default-topology-index = <0>;
+			qcom,partial-update-enabled = "single_roi";
+			qcom,panel-roi-alignment = <720 128 720 128 1440 128>;
 		};
 	};
 };
@@ -829,6 +832,7 @@
 &dsi_dual_nt35597_cmd {
 	qcom,mdss-dsi-t-clk-post = <0x0d>;
 	qcom,mdss-dsi-t-clk-pre = <0x2d>;
+	qcom,ulps-enabled;
 	qcom,mdss-dsi-display-timings {
 		 timing@0 {
 			qcom,mdss-dsi-panel-timings = [00 1c 08 07 23 22 07 07
@@ -836,6 +840,8 @@
 			qcom,display-topology = <2 0 2>,
 						<1 0 2>;
 			qcom,default-topology-index = <0>;
+			qcom,partial-update-enabled = "single_roi";
+			qcom,panel-roi-alignment = <720 128 720 128 1440 128>;
 		};
 	};
 };
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index aa16a77..82e55c4 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -2641,7 +2641,7 @@
 			<0 432 0>;
 		interrupt-names = "ipa-irq", "gsi-irq";
 		qcom,ipa-hw-ver = <13>; /* IPA core version = IPAv3.5.1 */
-		qcom,ipa-hw-mode = <1>;
+		qcom,ipa-hw-mode = <0>;
 		qcom,ee = <0>;
 		qcom,use-ipa-tethering-bridge;
 		qcom,modem-cfg-emb-pipe-flt;
diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig
index f5410c1..64c1e0b 100644
--- a/arch/arm64/configs/msm8953-perf_defconfig
+++ b/arch/arm64/configs/msm8953-perf_defconfig
@@ -53,6 +53,7 @@
 CONFIG_ARCH_QCOM=y
 CONFIG_ARCH_MSM8953=y
 CONFIG_ARCH_MSM8937=y
+CONFIG_ARCH_MSM8917=y
 CONFIG_ARCH_SDM450=y
 CONFIG_ARCH_SDM632=y
 CONFIG_ARCH_SDM429=y
@@ -293,6 +294,8 @@
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_VT is not set
 # CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_MSM_HS=y
 CONFIG_SERIAL_MSM_SMD=y
 CONFIG_DIAG_CHAR=y
@@ -395,6 +398,8 @@
 CONFIG_MSM_VIDC_3X_GOVERNORS=y
 CONFIG_MSM_SDE_ROTATOR=y
 CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG=y
+CONFIG_RADIO_IRIS=y
+CONFIG_RADIO_IRIS_TRANSPORT=y
 CONFIG_QCOM_KGSL=y
 CONFIG_DRM=y
 CONFIG_DRM_SDE_EVTLOG_DEBUG=y
@@ -517,6 +522,7 @@
 CONFIG_QPNP_COINCELL=y
 CONFIG_QPNP_REVID=y
 CONFIG_USB_BAM=y
+CONFIG_MSM_RMNET_BAM=y
 CONFIG_MSM_MDSS_PLL=y
 CONFIG_REMOTE_SPINLOCK_MSM=y
 CONFIG_MAILBOX=y
@@ -558,6 +564,7 @@
 CONFIG_WCNSS_REGISTER_DUMP_ON_BITE=y
 CONFIG_QCOM_BIMC_BWMON=y
 CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
+CONFIG_DEVFREQ_SIMPLE_DEV=y
 CONFIG_QCOM_DEVFREQ_DEVBW=y
 CONFIG_SPDM_SCM=y
 CONFIG_DEVFREQ_SPDM=y
diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig
index b9f4d9d..a287b1c 100644
--- a/arch/arm64/configs/msm8953_defconfig
+++ b/arch/arm64/configs/msm8953_defconfig
@@ -57,6 +57,7 @@
 CONFIG_ARCH_QCOM=y
 CONFIG_ARCH_MSM8953=y
 CONFIG_ARCH_MSM8937=y
+CONFIG_ARCH_MSM8917=y
 CONFIG_ARCH_SDM450=y
 CONFIG_ARCH_SDM632=y
 CONFIG_ARCH_SDM429=y
@@ -303,6 +304,8 @@
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_VT is not set
 # CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_MSM=y
 CONFIG_SERIAL_MSM_CONSOLE=y
 CONFIG_SERIAL_MSM_HS=y
@@ -407,6 +410,8 @@
 CONFIG_MSM_VIDC_3X_GOVERNORS=y
 CONFIG_MSM_SDE_ROTATOR=y
 CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG=y
+CONFIG_RADIO_IRIS=y
+CONFIG_RADIO_IRIS_TRANSPORT=y
 CONFIG_QCOM_KGSL=y
 CONFIG_DRM=y
 CONFIG_DRM_SDE_EVTLOG_DEBUG=y
@@ -531,6 +536,7 @@
 CONFIG_QPNP_COINCELL=y
 CONFIG_QPNP_REVID=y
 CONFIG_USB_BAM=y
+CONFIG_MSM_RMNET_BAM=y
 CONFIG_MSM_MDSS_PLL=y
 CONFIG_REMOTE_SPINLOCK_MSM=y
 CONFIG_MAILBOX=y
diff --git a/drivers/clk/msm/mdss/mdss-dsi-pll-8996-util.c b/drivers/clk/msm/mdss/mdss-dsi-pll-8996-util.c
index 20b8e34..7121261 100644
--- a/drivers/clk/msm/mdss/mdss-dsi-pll-8996-util.c
+++ b/drivers/clk/msm/mdss/mdss-dsi-pll-8996-util.c
@@ -424,8 +424,8 @@
 	pdb->in.pll_ip_trim = 4;	/* 4, reg: 0x0404 */
 	pdb->in.pll_cpcset_cur = 1;	/* 1, reg: 0x04f0, bit 0 - 2 */
 	pdb->in.pll_cpmset_cur = 1;	/* 1, reg: 0x04f0, bit 3 - 5 */
-	pdb->in.pll_icpmset = 4;	/* 4, reg: 0x04fc, bit 3 - 5 */
-	pdb->in.pll_icpcset = 4;	/* 4, reg: 0x04fc, bit 0 - 2 */
+	pdb->in.pll_icpmset = 7;	/* 7, reg: 0x04fc, bit 3 - 5 */
+	pdb->in.pll_icpcset = 7;	/* 7, reg: 0x04fc, bit 0 - 2 */
 	pdb->in.pll_icpmset_p = 0;	/* 0, reg: 0x04f4, bit 0 - 2 */
 	pdb->in.pll_icpmset_m = 0;	/* 0, reg: 0x04f4, bit 3 - 5 */
 	pdb->in.pll_icpcset_p = 0;	/* 0, reg: 0x04f8, bit 0 - 2 */
diff --git a/drivers/gpu/drm/bridge/lt9611.c b/drivers/gpu/drm/bridge/lt9611.c
index 887dd6f..dd2d54f 100644
--- a/drivers/gpu/drm/bridge/lt9611.c
+++ b/drivers/gpu/drm/bridge/lt9611.c
@@ -24,6 +24,7 @@
 #include <linux/i2c.h>
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
+#include <linux/component.h>
 #include <linux/of_gpio.h>
 #include <linux/of_graph.h>
 #include <linux/of_irq.h>
@@ -1687,6 +1688,22 @@
 	return 0;
 }
 
+static void lt9611_set_preferred_mode(struct drm_connector *connector)
+{
+	struct lt9611 *pdata = connector_to_lt9611(connector);
+	struct drm_display_mode *mode;
+	const char *string;
+
+	/* use specified mode as preferred */
+	if (!of_property_read_string(pdata->dev->of_node,
+			"lt,preferred-mode", &string)) {
+		list_for_each_entry(mode, &connector->probed_modes, head) {
+			if (!strcmp(mode->name, string))
+				mode->type |= DRM_MODE_TYPE_PREFERRED;
+		}
+	}
+}
+
 static int lt9611_connector_get_modes(struct drm_connector *connector)
 {
 	struct lt9611 *pdata = connector_to_lt9611(connector);
@@ -1719,12 +1736,11 @@
 		pdata->hdmi_mode = drm_detect_hdmi_monitor(edid);
 		pr_debug("hdmi_mode = %d\n", pdata->hdmi_mode);
 
-		/* TODO: this should not be hard coded */
-		drm_set_preferred_mode(connector, 1920, 1080);
-
 		kfree(edid);
 	}
 
+	lt9611_set_preferred_mode(connector);
+
 	return count;
 }
 
@@ -1997,6 +2013,20 @@
 	sysfs_remove_group(&dev->kobj, &lt9611_sysfs_attr_grp);
 }
 
+static int lt9611_bind(struct device *dev, struct device *master, void *data)
+{
+	return 0;
+}
+
+static void lt9611_unbind(struct device *dev, struct device *master, void *data)
+{
+}
+
+static const struct component_ops lt9611_comp_ops = {
+	.bind = lt9611_bind,
+	.unbind = lt9611_unbind,
+};
+
 static int lt9611_probe(struct i2c_client *client,
 	 const struct i2c_device_id *id)
 {
@@ -2078,6 +2108,10 @@
 
 	drm_bridge_add(&pdata->bridge);
 
+	ret = component_add(&client->dev, &lt9611_comp_ops);
+	if (ret)
+		pr_err("component add failed, rc=%d\n", ret);
+
 	return ret;
 
 err_sysfs_init:
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c b/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c
index 189a5c3..434d383 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_clk_manager.c
@@ -1078,12 +1078,7 @@
 	struct dsi_clk_mngr *mngr;
 	struct dsi_link_clks *l_clks;
 
-	if (!client) {
-		pr_err("%s: Invalid arg\n", __func__);
-		return -EINVAL;
-	}
 	mngr = c->mngr;
-
 	mutex_lock(&mngr->clk_mutex);
 
 	l_clks = mngr->link_clks;
@@ -1133,8 +1128,6 @@
 	mutex_lock(&dsi_mngr_clk_mutex);
 
 	rc = dsi_display_link_clk_force_update(handle);
-	if (rc && (rc != -EAGAIN))
-		pr_err("%s: failed set clk state, rc = %d\n", __func__, rc);
 
 	mutex_unlock(&dsi_mngr_clk_mutex);
 
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index c9e8a01..1ab1de6 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -1333,6 +1333,9 @@
 	u32 dlen, diff, rlen = msg->rx_len;
 	unsigned char *buff;
 	char cmd;
+	struct dsi_cmd_desc *of_cmd;
+
+	of_cmd = container_of(msg, struct dsi_cmd_desc, msg);
 
 	if (msg->rx_len <= 2) {
 		short_resp = true;
@@ -1366,6 +1369,13 @@
 			pr_err("Message transmission failed, rc=%d\n", rc);
 			goto error;
 		}
+		/*
+		 * wait before reading rdbk_data register, if any delay is
+		 * required after sending the read command.
+		 */
+		if (of_cmd && of_cmd->post_wait_ms)
+			usleep_range(of_cmd->post_wait_ms * 1000,
+				     ((of_cmd->post_wait_ms * 1000) + 10));
 
 		dlen = dsi_ctrl->hw.ops.get_cmd_read_data(&dsi_ctrl->hw,
 					buff, total_bytes_read,
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
index f0e7ba6..c1af52f 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
@@ -1487,7 +1487,7 @@
 	rc = readl_poll_timeout(ctrl->base + DSI_STATUS, val,
 			!(val & cmd_mode_mdp_busy_mask), sleep_us, timeout_us);
 	if (rc)
-		pr_err("%s: waiting failed, ret=%d\n", __func__, rc);
+		pr_err("%s: timed out waiting for idle\n", __func__);
 
 	return rc;
 }
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index 12ca46e..5e5a3ee 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -349,7 +349,7 @@
 
 static void dsi_display_register_te_irq(struct dsi_display *display)
 {
-	int rc;
+	int rc = 0;
 	struct platform_device *pdev;
 	struct device *dev;
 
@@ -365,18 +365,31 @@
 		return;
 	}
 
+	if (!gpio_is_valid(display->disp_te_gpio)) {
+		rc = -EINVAL;
+		goto error;
+	}
+
+	init_completion(&display->esd_te_gate);
+
 	rc = devm_request_irq(dev, gpio_to_irq(display->disp_te_gpio),
 			dsi_display_panel_te_irq_handler, IRQF_TRIGGER_FALLING,
 			"TE_GPIO", display);
 	if (rc) {
 		pr_err("TE request_irq failed for ESD rc:%d\n", rc);
-		return;
+		goto error;
 	}
 
-	init_completion(&display->esd_te_gate);
-
 	disable_irq(gpio_to_irq(display->disp_te_gpio));
 	display->is_te_irq_enabled = false;
+
+	return;
+
+error:
+	/* disable the TE based ESD check */
+	pr_warn("Unable to register for TE IRQ\n");
+	if (display->panel->esd_config.status_mode == ESD_MODE_PANEL_TE)
+		display->panel->esd_config.esd_enabled = false;
 }
 
 static bool dsi_display_is_te_based_esd(struct dsi_display *display)
@@ -555,14 +568,14 @@
 	lenp = config->status_valid_params ?: config->status_cmds_rlen;
 	count = config->status_cmd.count;
 	cmds = config->status_cmd.cmds;
-	if (cmds->last_command) {
-		cmds->msg.flags |= MIPI_DSI_MSG_LASTCOMMAND;
-		flags |= DSI_CTRL_CMD_LAST_COMMAND;
-	}
 	flags |= (DSI_CTRL_CMD_FETCH_MEMORY | DSI_CTRL_CMD_READ);
 
 	for (i = 0; i < count; ++i) {
 		memset(config->status_buf, 0x0, SZ_4K);
+		if (cmds[i].last_command) {
+			cmds[i].msg.flags |= MIPI_DSI_MSG_LASTCOMMAND;
+			flags |= DSI_CTRL_CMD_LAST_COMMAND;
+		}
 		cmds[i].msg.rx_buf = config->status_buf;
 		cmds[i].msg.rx_len = config->status_cmds_rlen[i];
 		rc = dsi_ctrl_cmd_transfer(ctrl->ctrl, &cmds[i].msg, flags);
@@ -646,7 +659,7 @@
 
 		rc = dsi_display_validate_status(ctrl, display->panel);
 		if (rc <= 0) {
-			pr_err("[%s] read status failed on master,rc=%d\n",
+			pr_err("[%s] read status failed on slave,rc=%d\n",
 			       display->name, rc);
 			goto exit;
 		}
@@ -4079,11 +4092,6 @@
 {
 	int rc = 0;
 
-	if (!display || !display->panel) {
-		pr_err("Invalid params\n");
-		return -EINVAL;
-	}
-
 	rc = dsi_display_link_clk_force_update_ctrl(display->dsi_clk_handle);
 
 	if (!rc) {
@@ -4091,8 +4099,6 @@
 			display->cached_clk_rate);
 
 		atomic_set(&display->clkrate_change_pending, 0);
-	} else if (rc == -EAGAIN) {
-		pr_info("Clock is disabled, update it next time\n");
 	} else {
 		pr_err("Failed to configure dsi bit clock '%d'. rc = %d\n",
 			display->cached_clk_rate, rc);
@@ -4108,7 +4114,7 @@
 	int i;
 
 	pr_debug("%s:bit rate:%d\n", __func__, bit_clk_rate);
-	if (!display || !display->panel) {
+	if (!display->panel) {
 		pr_err("Invalid params\n");
 		return -EINVAL;
 	}
@@ -4187,11 +4193,6 @@
 	struct dsi_display_ctrl *m_ctrl;
 	struct dsi_ctrl *ctrl;
 
-	if (!dev) {
-		pr_err("Invalid device\n");
-		return -EINVAL;
-	}
-
 	display = dev_get_drvdata(dev);
 	if (!display) {
 		pr_err("Invalid display\n");
@@ -4207,7 +4208,7 @@
 					byte_clk_rate * 8;
 
 	rc = snprintf(buf, PAGE_SIZE, "%d\n", display->cached_clk_rate);
-	pr_info("%s: read dsi clk rate %d\n", __func__,
+	pr_debug("%s: read dsi clk rate %d\n", __func__,
 		display->cached_clk_rate);
 
 	mutex_unlock(&display->display_lock);
@@ -4222,11 +4223,6 @@
 	int clk_rate;
 	struct dsi_display *display;
 
-	if (!dev) {
-		pr_err("Invalid device\n");
-		return -EINVAL;
-	}
-
 	display = dev_get_drvdata(dev);
 	if (!display) {
 		pr_err("Invalid display\n");
@@ -6030,11 +6026,8 @@
 			int ret = 0;
 
 			ret = dsi_ctrl_wait_for_cmd_mode_mdp_idle(ctrl);
-			if (ret) {
-				pr_info("Failed to wait for cmd engine not to be busy sending data from MDP, rc: %d\n",
-					ret);
+			if (ret)
 				goto wait_failure;
-			}
 		}
 
 		/*
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index d5437d0..15fff53 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1806,6 +1806,27 @@
 	return ret;
 }
 
+static int add_bridge_components(struct device *dev,
+				  struct component_match **matchptr)
+{
+	struct device_node *node;
+
+	if (of_device_is_compatible(dev->of_node, "qcom,sde-kms")) {
+		struct device_node *np = dev->of_node;
+		unsigned int i;
+
+		for (i = 0; ; i++) {
+			node = of_parse_phandle(np, "bridges", i);
+			if (!node)
+				break;
+
+			component_match_add(dev, matchptr, compare_of, node);
+		}
+	}
+
+	return 0;
+}
+
 struct msm_gem_address_space *
 msm_gem_smmu_address_space_get(struct drm_device *dev,
 		unsigned int domain)
@@ -1897,6 +1918,10 @@
 	if (ret)
 		return ret;
 
+	ret = add_bridge_components(&pdev->dev, &match);
+	if (ret)
+		return ret;
+
 	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 	return component_master_add_with_match(&pdev->dev, &msm_drm_ops, match);
 }
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c
index f908e7f..db0c1d4 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.c
+++ b/drivers/gpu/drm/msm/sde/sde_connector.c
@@ -414,6 +414,10 @@
 	if (!c_conn)
 		return;
 
+	/* Return if there is no change in ESD status check condition */
+	if (en == c_conn->esd_status_check)
+		return;
+
 	sde_connector_get_info(connector, &info);
 	if (c_conn->ops.check_status &&
 		(info.capabilities & MSM_DISPLAY_ESD_ENABLED)) {
@@ -430,9 +434,11 @@
 			/* Schedule ESD status check */
 			schedule_delayed_work(&c_conn->status_work,
 				msecs_to_jiffies(interval));
+			c_conn->esd_status_check = true;
 		} else {
 			/* Cancel any pending ESD status check */
 			cancel_delayed_work_sync(&c_conn->status_work);
+			c_conn->esd_status_check = false;
 		}
 	}
 }
@@ -482,11 +488,12 @@
 	}
 	c_conn->last_panel_power_mode = mode;
 
-	if (mode != SDE_MODE_DPMS_ON) {
-		mutex_unlock(&c_conn->lock);
+	mutex_unlock(&c_conn->lock);
+	if (mode != SDE_MODE_DPMS_ON)
 		sde_connector_schedule_status_work(connector, false);
-		mutex_lock(&c_conn->lock);
-	}
+	else
+		sde_connector_schedule_status_work(connector, true);
+	mutex_lock(&c_conn->lock);
 
 	return rc;
 }
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.h b/drivers/gpu/drm/msm/sde/sde_connector.h
index 1495622..101fc01 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.h
+++ b/drivers/gpu/drm/msm/sde/sde_connector.h
@@ -356,6 +356,8 @@
 	u32 force_panel_dead;
 	u32 esd_status_interval;
 
+	bool esd_status_check;
+
 	bool bl_scale_dirty;
 	u32 bl_scale;
 	u32 bl_scale_ad;
diff --git a/drivers/gpu/drm/msm/sde/sde_formats.c b/drivers/gpu/drm/msm/sde/sde_formats.c
index d09054e..719b8c1 100644
--- a/drivers/gpu/drm/msm/sde/sde_formats.c
+++ b/drivers/gpu/drm/msm/sde/sde_formats.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-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
@@ -275,97 +275,97 @@
 
 	INTERLEAVED_RGB_FMT(ARGB1555,
 		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
-		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
 		true, 2, 0,
 		SDE_FETCH_LINEAR, 1),
 
 	INTERLEAVED_RGB_FMT(ABGR1555,
 		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
-		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
+		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
 		true, 2, 0,
 		SDE_FETCH_LINEAR, 1),
 
 	INTERLEAVED_RGB_FMT(RGBA5551,
 		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
-		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
 		true, 2, 0,
 		SDE_FETCH_LINEAR, 1),
 
 	INTERLEAVED_RGB_FMT(BGRA5551,
 		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
-		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
+		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
 		true, 2, 0,
 		SDE_FETCH_LINEAR, 1),
 
 	INTERLEAVED_RGB_FMT(XRGB1555,
 		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
-		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
 		false, 2, 0,
 		SDE_FETCH_LINEAR, 1),
 
 	INTERLEAVED_RGB_FMT(XBGR1555,
 		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
-		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
+		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
 		false, 2, 0,
 		SDE_FETCH_LINEAR, 1),
 
 	INTERLEAVED_RGB_FMT(RGBX5551,
 		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
-		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
 		false, 2, 0,
 		SDE_FETCH_LINEAR, 1),
 
 	INTERLEAVED_RGB_FMT(BGRX5551,
 		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
-		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
+		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
 		false, 2, 0,
 		SDE_FETCH_LINEAR, 1),
 
 	INTERLEAVED_RGB_FMT(ARGB4444,
 		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
-		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
 		true, 2, 0,
 		SDE_FETCH_LINEAR, 1),
 
 	INTERLEAVED_RGB_FMT(ABGR4444,
 		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
-		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
+		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
 		true, 2, 0,
 		SDE_FETCH_LINEAR, 1),
 
 	INTERLEAVED_RGB_FMT(RGBA4444,
 		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
-		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
 		true, 2, 0,
 		SDE_FETCH_LINEAR, 1),
 
 	INTERLEAVED_RGB_FMT(BGRA4444,
 		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
-		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
+		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
 		true, 2, 0,
 		SDE_FETCH_LINEAR, 1),
 
 	INTERLEAVED_RGB_FMT(XRGB4444,
 		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
-		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
 		false, 2, 0,
 		SDE_FETCH_LINEAR, 1),
 
 	INTERLEAVED_RGB_FMT(XBGR4444,
 		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
-		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
+		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
 		false, 2, 0,
 		SDE_FETCH_LINEAR, 1),
 
 	INTERLEAVED_RGB_FMT(RGBX4444,
 		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
-		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
 		false, 2, 0,
 		SDE_FETCH_LINEAR, 1),
 
 	INTERLEAVED_RGB_FMT(BGRX4444,
 		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
-		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
+		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
 		false, 2, 0,
 		SDE_FETCH_LINEAR, 1),
 
diff --git a/drivers/gpu/drm/msm/sde_rsc.c b/drivers/gpu/drm/msm/sde_rsc.c
index ca4f0da..8179b10 100644
--- a/drivers/gpu/drm/msm/sde_rsc.c
+++ b/drivers/gpu/drm/msm/sde_rsc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-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
@@ -882,23 +882,22 @@
 int sde_rsc_client_vote(struct sde_rsc_client *caller_client,
 		u32 bus_id, u64 ab_vote, u64 ib_vote)
 {
-	int rc = 0;
+	int rc = 0, rsc_index;
 	struct sde_rsc_priv *rsc;
 
-	if (!caller_client) {
-		pr_err("invalid client for ab/ib vote\n");
-		return -EINVAL;
-	} else if (caller_client->rsc_index >= MAX_RSC_COUNT) {
+	if (caller_client && caller_client->rsc_index >= MAX_RSC_COUNT) {
 		pr_err("invalid rsc index\n");
 		return -EINVAL;
 	}
 
-	rsc = rsc_prv_list[caller_client->rsc_index];
+	rsc_index = caller_client ? caller_client->rsc_index : SDE_RSC_INDEX;
+	rsc = rsc_prv_list[rsc_index];
 	if (!rsc)
 		return -EINVAL;
 
 	pr_debug("client:%s ab:%llu ib:%llu\n",
-			caller_client->name, ab_vote, ib_vote);
+			caller_client ? caller_client->name : "unknown",
+			ab_vote, ib_vote);
 
 	mutex_lock(&rsc->client_lock);
 	rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
diff --git a/drivers/gpu/drm/msm/sde_rsc_hw.c b/drivers/gpu/drm/msm/sde_rsc_hw.c
index d40b0ad..5049758 100644
--- a/drivers/gpu/drm/msm/sde_rsc_hw.c
+++ b/drivers/gpu/drm/msm/sde_rsc_hw.c
@@ -405,6 +405,9 @@
 	if (rc)
 		pr_err("vdd reg is not enabled yet\n");
 
+	dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_SOLVER_MODES_ENABLED_DRV0,
+						0x3, rsc->debug_mode);
+
 	rsc_event_trigger(rsc, SDE_RSC_EVENT_POST_CORE_RESTORE);
 
 	return rc;
@@ -477,19 +480,33 @@
 
 	if (seq_busy && (current_mode == SDE_RSC_MODE_0_VAL ||
 			current_mode == SDE_RSC_MODE_1_VAL)) {
-		dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_LO,
-						0xffffffff, rsc->debug_mode);
 		dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_HI,
+						0xffffff, rsc->debug_mode);
+		dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_LO,
 						0xffffffff, rsc->debug_mode);
 		/* unstick f1 qtimer */
 		wmb();
 
-		dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_LO,
-						0x0, rsc->debug_mode);
 		dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_HI,
 						0x0, rsc->debug_mode);
+		dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F1_QTMR_V1_CNTP_CVAL_LO,
+						0x0, rsc->debug_mode);
 		/* manually trigger f1 qtimer interrupt */
 		wmb();
+
+		dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_HI,
+						0xffffff, rsc->debug_mode);
+		dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_LO,
+						0xffffffff, rsc->debug_mode);
+		/* unstick f0 qtimer */
+		wmb();
+
+		dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_HI,
+						0x0, rsc->debug_mode);
+		dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_LO,
+						0x0, rsc->debug_mode);
+		/* manually trigger f0 qtimer interrupt */
+		wmb();
 	}
 }
 
@@ -506,6 +523,8 @@
 		return rc;
 	}
 
+	dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_SOLVER_MODES_ENABLED_DRV0,
+						0x7, rsc->debug_mode);
 	rsc_event_trigger(rsc, SDE_RSC_EVENT_PRE_CORE_PC);
 
 	for (i = 0; i <= MAX_MODE2_ENTRY_TRY; i++) {
diff --git a/drivers/gpu/msm/adreno-gpulist.h b/drivers/gpu/msm/adreno-gpulist.h
index 2aff383..1fb76dd 100644
--- a/drivers/gpu/msm/adreno-gpulist.h
+++ b/drivers/gpu/msm/adreno-gpulist.h
@@ -379,4 +379,22 @@
 		.gpmu_major = 0x1,
 		.gpmu_minor = 0x003,
 	},
+	{
+		.gpurev = ADRENO_REV_A616,
+		.core = 6,
+		.major = 1,
+		.minor = 6,
+		.patchid = ANY_ID,
+		.features = ADRENO_64BIT | ADRENO_RPMH | ADRENO_PREEMPTION |
+			ADRENO_GPMU | ADRENO_CONTENT_PROTECTION | ADRENO_IFPC,
+		.sqefw_name = "a630_sqe.fw",
+		.zap_name = "a615_zap",
+		.gpudev = &adreno_a6xx_gpudev,
+		.gmem_size = SZ_512K,
+		.num_protected_regs = 0x20,
+		.busy_mask = 0xFFFFFFFE,
+		.gpmufw_name = "a630_gmu.bin",
+		.gpmu_major = 0x1,
+		.gpmu_minor = 0x003,
+	},
 };
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 8785d62..9ca22fd 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -211,6 +211,7 @@
 	ADRENO_REV_A530 = 530,
 	ADRENO_REV_A540 = 540,
 	ADRENO_REV_A615 = 615,
+	ADRENO_REV_A616 = 616,
 	ADRENO_REV_A630 = 630,
 };
 
@@ -1251,6 +1252,7 @@
 }
 
 ADRENO_TARGET(a615, ADRENO_REV_A615)
+ADRENO_TARGET(a616, ADRENO_REV_A616)
 ADRENO_TARGET(a630, ADRENO_REV_A630)
 
 static inline int adreno_is_a630v1(struct adreno_device *adreno_dev)
@@ -1878,7 +1880,7 @@
 
 static inline bool adreno_has_gbif(struct adreno_device *adreno_dev)
 {
-	if (adreno_is_a615(adreno_dev))
+	if (adreno_is_a615(adreno_dev) || adreno_is_a616(adreno_dev))
 		return true;
 	else
 		return false;
diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c
index daf314d..7096d7c 100644
--- a/drivers/gpu/msm/adreno_a6xx.c
+++ b/drivers/gpu/msm/adreno_a6xx.c
@@ -61,6 +61,7 @@
 static const struct adreno_vbif_platform a6xx_vbif_platforms[] = {
 	{ adreno_is_a630, a630_vbif },
 	{ adreno_is_a615, a615_gbif },
+	{ adreno_is_a616, a615_gbif },
 };
 
 
@@ -251,6 +252,7 @@
 } a6xx_hwcg_registers[] = {
 	{adreno_is_a630, a630_hwcg_regs, ARRAY_SIZE(a630_hwcg_regs)},
 	{adreno_is_a615, a615_hwcg_regs, ARRAY_SIZE(a615_hwcg_regs)},
+	{adreno_is_a616, a615_hwcg_regs, ARRAY_SIZE(a615_hwcg_regs)},
 };
 
 static struct a6xx_protected_regs {
@@ -499,7 +501,7 @@
 static inline unsigned int
 __get_rbbm_clock_cntl_on(struct adreno_device *adreno_dev)
 {
-	if (adreno_is_a615(adreno_dev))
+	if (adreno_is_a615(adreno_dev) || adreno_is_a616(adreno_dev))
 		return 0x8AA8AA82;
 	else
 		return 0x8AA8AA02;
@@ -508,7 +510,7 @@
 static inline unsigned int
 __get_gmu_ao_cgc_mode_cntl(struct adreno_device *adreno_dev)
 {
-	if (adreno_is_a615(adreno_dev))
+	if (adreno_is_a615(adreno_dev) || adreno_is_a616(adreno_dev))
 		return 0x00000222;
 	else
 		return 0x00020202;
@@ -517,7 +519,7 @@
 static inline unsigned int
 __get_gmu_ao_cgc_delay_cntl(struct adreno_device *adreno_dev)
 {
-	if (adreno_is_a615(adreno_dev))
+	if (adreno_is_a615(adreno_dev) || adreno_is_a616(adreno_dev))
 		return 0x00000111;
 	else
 		return 0x00010111;
@@ -526,7 +528,7 @@
 static inline unsigned int
 __get_gmu_ao_cgc_hyst_cntl(struct adreno_device *adreno_dev)
 {
-	if (adreno_is_a615(adreno_dev))
+	if (adreno_is_a615(adreno_dev) || adreno_is_a616(adreno_dev))
 		return 0x00000555;
 	else
 		return 0x00005555;
@@ -643,7 +645,7 @@
 		+ sizeof(a6xx_ifpc_pwrup_reglist), a6xx_pwrup_reglist,
 		sizeof(a6xx_pwrup_reglist));
 
-	if (adreno_is_a615(adreno_dev)) {
+	if (adreno_is_a615(adreno_dev) || adreno_is_a616(adreno_dev)) {
 		for (i = 0; i < ARRAY_SIZE(a615_pwrup_reglist); i++) {
 			r = &a615_pwrup_reglist[i];
 			kgsl_regread(KGSL_DEVICE(adreno_dev),
@@ -3587,6 +3589,7 @@
 	void (*func)(struct adreno_device *adreno_dev);
 } a6xx_efuse_funcs[] = {
 	{ adreno_is_a615, a6xx_efuse_speed_bin },
+	{ adreno_is_a616, a6xx_efuse_speed_bin },
 };
 
 static void a6xx_check_features(struct adreno_device *adreno_dev)
diff --git a/drivers/gpu/msm/adreno_a6xx_snapshot.c b/drivers/gpu/msm/adreno_a6xx_snapshot.c
index afd1be5..7376a38 100644
--- a/drivers/gpu/msm/adreno_a6xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a6xx_snapshot.c
@@ -1169,7 +1169,8 @@
 
 	block_id = block->block_id;
 	/* GMU_GX data is read using the GMU_CX block id on A630 */
-	if ((adreno_is_a630(adreno_dev) || adreno_is_a615(adreno_dev)) &&
+	if ((adreno_is_a630(adreno_dev) || adreno_is_a615(adreno_dev) ||
+		adreno_is_a616(adreno_dev)) &&
 		(block_id == A6XX_DBGBUS_GMU_GX))
 		block_id = A6XX_DBGBUS_GMU_CX;
 
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index a9c2252..3702893 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-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
@@ -716,6 +716,18 @@
 
 	align = (memdesc->flags & KGSL_MEMALIGN_MASK) >> KGSL_MEMALIGN_SHIFT;
 
+	/*
+	 * As 1MB is the max supported page size, use the alignment
+	 * corresponding to 1MB page to make sure higher order pages
+	 * are used if possible for a given memory size. Also, we
+	 * don't need to update alignment in memdesc flags in case
+	 * higher order page is used, as memdesc flags represent the
+	 * virtual alignment specified by the user which is anyways
+	 * getting satisfied.
+	 */
+	if (align < ilog2(SZ_1M))
+		align = ilog2(SZ_1M);
+
 	page_size = kgsl_get_page_size(size, align);
 
 	/*
diff --git a/drivers/hwmon/qpnp-adc-voltage.c b/drivers/hwmon/qpnp-adc-voltage.c
index 59ca208..1f38574 100644
--- a/drivers/hwmon/qpnp-adc-voltage.c
+++ b/drivers/hwmon/qpnp-adc-voltage.c
@@ -109,7 +109,7 @@
 #define QPNP_VADC_CONV_TIME_MIN					1000
 #define QPNP_VADC_CONV_TIME_MAX					1100
 #define QPNP_ADC_COMPLETION_TIMEOUT				HZ
-#define QPNP_VADC_ERR_COUNT					50
+#define QPNP_VADC_ERR_COUNT					20
 #define QPNP_OP_MODE_SHIFT					3
 
 #define QPNP_VADC_THR_LSB_MASK(val)				(val & 0xff)
@@ -277,42 +277,6 @@
 	return -EINVAL;
 }
 
-static int32_t qpnp_vadc_warm_rst_configure(struct qpnp_vadc_chip *vadc)
-{
-	int rc = 0;
-	u8 data = 0, buf = 0;
-
-	buf = QPNP_VADC_ACCESS_DATA;
-	rc = qpnp_vadc_write_reg(vadc, QPNP_VADC_ACCESS, &buf, 1);
-	if (rc < 0) {
-		pr_err("VADC write access failed\n");
-		return rc;
-	}
-
-	rc = qpnp_vadc_read_reg(vadc, QPNP_VADC_PERH_RESET_CTL3, &data, 1);
-	if (rc < 0) {
-		pr_err("VADC perh reset ctl3 read failed\n");
-		return rc;
-	}
-
-	buf = QPNP_VADC_ACCESS_DATA;
-	rc = qpnp_vadc_write_reg(vadc, QPNP_VADC_ACCESS, &buf, 1);
-	if (rc < 0) {
-		pr_err("VADC write access failed\n");
-		return rc;
-	}
-
-	data |= QPNP_FOLLOW_WARM_RB;
-
-	rc = qpnp_vadc_write_reg(vadc, QPNP_VADC_PERH_RESET_CTL3, &data, 1);
-	if (rc < 0) {
-		pr_err("VADC perh reset ctl3 write failed\n");
-		return rc;
-	}
-
-	return 0;
-}
-
 static int32_t qpnp_vadc_mode_select(struct qpnp_vadc_chip *vadc, u8 mode_ctl)
 {
 	int rc;
@@ -422,20 +386,7 @@
 static int qpnp_vadc_hc_read_data(struct qpnp_vadc_chip *vadc, int *data)
 {
 	int rc = 0;
-	u8 buf = 0, rslt_lsb = 0, rslt_msb = 0;
-
-	/* Set hold bit */
-	rc = qpnp_vadc_read_reg(vadc, QPNP_VADC_HC1_DATA_HOLD_CTL, &buf, 1);
-	if (rc) {
-		pr_err("debug register dump failed\n");
-		return rc;
-	}
-	buf |= QPNP_VADC_HC1_DATA_HOLD_CTL_FIELD;
-	rc = qpnp_vadc_write_reg(vadc, QPNP_VADC_HC1_DATA_HOLD_CTL, &buf, 1);
-	if (rc) {
-		pr_err("debug register dump failed\n");
-		return rc;
-	}
+	u8 rslt_lsb = 0, rslt_msb = 0;
 
 	rc = qpnp_vadc_read_reg(vadc, QPNP_VADC_HC1_DATA0, &rslt_lsb, 1);
 	if (rc < 0) {
@@ -462,11 +413,6 @@
 		return rc;
 	}
 
-	/* De-assert hold bit */
-	buf &= ~QPNP_VADC_HC1_DATA_HOLD_CTL_FIELD;
-	rc = qpnp_vadc_write_reg(vadc, QPNP_VADC_HC1_DATA_HOLD_CTL, &buf, 1);
-	if (rc)
-		pr_err("de-asserting hold bit failed\n");
 
 	return rc;
 }
@@ -2757,12 +2703,6 @@
 		goto err_setup;
 	}
 
-	rc = qpnp_vadc_warm_rst_configure(vadc);
-	if (rc < 0) {
-		pr_err("Setting perp reset on warm reset failed %d\n", rc);
-		goto err_setup;
-	}
-
 	INIT_WORK(&vadc->trigger_completion_work, qpnp_vadc_work);
 
 	vadc->vadc_recalib_check = of_property_read_bool(node,
diff --git a/drivers/hwtracing/coresight/coresight-byte-cntr.c b/drivers/hwtracing/coresight/coresight-byte-cntr.c
index 5173770..9fa3e0f 100644
--- a/drivers/hwtracing/coresight/coresight-byte-cntr.c
+++ b/drivers/hwtracing/coresight/coresight-byte-cntr.c
@@ -162,7 +162,7 @@
 				goto err0;
 		}
 
-		if (tmcdrvdata->mem_type == TMC_ETR_MEM_TYPE_CONTIG)
+		if (tmcdrvdata->memtype == TMC_ETR_MEM_TYPE_CONTIG)
 			tmc_etr_read_bytes(byte_cntr_data, ppos,
 					   byte_cntr_data->block_size, &len,
 					   &bufp);
@@ -172,7 +172,7 @@
 
 	} else {
 		if (!atomic_read(&byte_cntr_data->irq_cnt)) {
-			if (tmcdrvdata->mem_type == TMC_ETR_MEM_TYPE_CONTIG)
+			if (tmcdrvdata->memtype == TMC_ETR_MEM_TYPE_CONTIG)
 				tmc_etr_flush_bytes(ppos,
 						    byte_cntr_data->block_size,
 						    &len);
@@ -184,7 +184,7 @@
 			if (!len)
 				goto err0;
 		} else {
-			if (tmcdrvdata->mem_type == TMC_ETR_MEM_TYPE_CONTIG)
+			if (tmcdrvdata->memtype == TMC_ETR_MEM_TYPE_CONTIG)
 				tmc_etr_read_bytes(byte_cntr_data, ppos,
 						   byte_cntr_data->block_size,
 						   &len, &bufp);
diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c
index 6597fd6..c9c22d0 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.c
+++ b/drivers/hwtracing/coresight/coresight-tmc.c
@@ -28,10 +28,13 @@
 #include <linux/of.h>
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
+#include <soc/qcom/memory_dump.h>
 
 #include "coresight-priv.h"
 #include "coresight-tmc.h"
 
+#define TMC_REG_DUMP_MAGIC 0x42445953
+
 void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
 {
 	/* Ensure formatter, unformatter and hardware fifo are empty */
@@ -61,11 +64,85 @@
 	tmc_wait_for_tmcready(drvdata);
 }
 
+static void __tmc_reg_dump(struct tmc_drvdata *drvdata)
+{
+	struct dump_vaddr_entry *dump_entry;
+	struct msm_dump_data *dump_data;
+	uint32_t *reg_buf;
+
+	if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
+		dump_entry = get_msm_dump_ptr(MSM_DUMP_DATA_TMC_ETR_REG);
+		dev_dbg(drvdata->dev, "%s: TMC ETR dump entry ptr is %pK\n",
+			__func__, dump_entry);
+	} else if (drvdata->config_type == TMC_CONFIG_TYPE_ETB ||
+			drvdata->config_type == TMC_CONFIG_TYPE_ETF) {
+		dump_entry = get_msm_dump_ptr(MSM_DUMP_DATA_TMC_ETF_REG);
+		dev_dbg(drvdata->dev, "%s: TMC ETF dump entry ptr is %pK\n",
+			__func__, dump_entry);
+	} else
+		return;
+
+	if (dump_entry == NULL)
+		return;
+
+	reg_buf = (uint32_t *)(dump_entry->dump_vaddr);
+	dump_data = dump_entry->dump_data_vaddr;
+
+	if (reg_buf == NULL || dump_data == NULL)
+		return;
+
+	dev_dbg(drvdata->dev, "%s: TMC dump reg ptr is %pK, dump_data is %pK\n",
+		__func__, reg_buf, dump_data);
+
+	reg_buf[1] = readl_relaxed(drvdata->base + TMC_RSZ);
+	reg_buf[3] = readl_relaxed(drvdata->base + TMC_STS);
+	reg_buf[5] = readl_relaxed(drvdata->base + TMC_RRP);
+	reg_buf[6] = readl_relaxed(drvdata->base + TMC_RWP);
+	reg_buf[7] = readl_relaxed(drvdata->base + TMC_TRG);
+	reg_buf[8] = readl_relaxed(drvdata->base + TMC_CTL);
+	reg_buf[10] = readl_relaxed(drvdata->base + TMC_MODE);
+	reg_buf[11] = readl_relaxed(drvdata->base + TMC_LBUFLEVEL);
+	reg_buf[12] = readl_relaxed(drvdata->base + TMC_CBUFLEVEL);
+	reg_buf[13] = readl_relaxed(drvdata->base + TMC_BUFWM);
+	if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
+		reg_buf[14] = readl_relaxed(drvdata->base + TMC_RRPHI);
+		reg_buf[15] = readl_relaxed(drvdata->base + TMC_RWPHI);
+		reg_buf[68] = readl_relaxed(drvdata->base + TMC_AXICTL);
+		reg_buf[70] = readl_relaxed(drvdata->base + TMC_DBALO);
+		reg_buf[71] = readl_relaxed(drvdata->base + TMC_DBAHI);
+	}
+	reg_buf[192] = readl_relaxed(drvdata->base + TMC_FFSR);
+	reg_buf[193] = readl_relaxed(drvdata->base + TMC_FFCR);
+	reg_buf[194] = readl_relaxed(drvdata->base + TMC_PSCR);
+	reg_buf[1000] = readl_relaxed(drvdata->base + CORESIGHT_CLAIMSET);
+	reg_buf[1001] = readl_relaxed(drvdata->base + CORESIGHT_CLAIMCLR);
+	reg_buf[1005] = readl_relaxed(drvdata->base + CORESIGHT_LSR);
+	reg_buf[1006] = readl_relaxed(drvdata->base + CORESIGHT_AUTHSTATUS);
+	reg_buf[1010] = readl_relaxed(drvdata->base + CORESIGHT_DEVID);
+	reg_buf[1011] = readl_relaxed(drvdata->base + CORESIGHT_DEVTYPE);
+	reg_buf[1012] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR4);
+	reg_buf[1013] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR5);
+	reg_buf[1014] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR6);
+	reg_buf[1015] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR7);
+	reg_buf[1016] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR0);
+	reg_buf[1017] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR1);
+	reg_buf[1018] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR2);
+	reg_buf[1019] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR3);
+	reg_buf[1020] = readl_relaxed(drvdata->base + CORESIGHT_COMPIDR0);
+	reg_buf[1021] = readl_relaxed(drvdata->base + CORESIGHT_COMPIDR1);
+	reg_buf[1022] = readl_relaxed(drvdata->base + CORESIGHT_COMPIDR2);
+	reg_buf[1023] = readl_relaxed(drvdata->base + CORESIGHT_COMPIDR3);
+
+	dump_data->magic = TMC_REG_DUMP_MAGIC;
+}
+
 void tmc_enable_hw(struct tmc_drvdata *drvdata)
 {
 	drvdata->enable = true;
 	drvdata->sticky_enable = true;
 	writel_relaxed(TMC_CTL_CAPT_EN, drvdata->base + TMC_CTL);
+	if (drvdata->force_reg_dump)
+		__tmc_reg_dump(drvdata);
 }
 
 void tmc_disable_hw(struct tmc_drvdata *drvdata)
@@ -626,6 +703,8 @@
 			return -EPROBE_DEFER;
 		}
 	}
+	if (of_property_read_bool(drvdata->dev->of_node, "qcom,force-reg-dump"))
+		drvdata->force_reg_dump = true;
 
 	desc.pdata = pdata;
 	desc.dev = dev;
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 0a271e5..2372be6 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -192,6 +192,7 @@
 	struct coresight_csr	*csr;
 	const char		*csr_name;
 	struct byte_cntr	*byte_cntr;
+	bool			force_reg_dump;
 };
 
 /* Generic functions */
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index 0bc9439..7cdb459 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -3898,6 +3898,8 @@
 
 static int tpdm_datasets_alloc(struct tpdm_drvdata *drvdata)
 {
+	struct dump_vaddr_entry *dump_entry;
+
 	if (test_bit(TPDM_DS_GPR, drvdata->datasets)) {
 		drvdata->gpr = devm_kzalloc(drvdata->dev, sizeof(*drvdata->gpr),
 					    GFP_KERNEL);
@@ -3939,10 +3941,13 @@
 			return -ENOMEM;
 
 		if (of_property_read_bool(drvdata->dev->of_node,
-						    "qcom,dump-enable"))
-			drvdata->cmb->mcmb->mcmb_msr_dump_ptr =
-				(uint32_t *)get_msm_dump_ptr(
-						MSM_DUMP_DATA_TPDM_SWAO_MCMB);
+						    "qcom,dump-enable")) {
+			dump_entry = get_msm_dump_ptr(
+				MSM_DUMP_DATA_TPDM_SWAO_MCMB);
+			if (dump_entry)
+				drvdata->cmb->mcmb->mcmb_msr_dump_ptr =
+					(uint32_t *)(dump_entry->dump_vaddr);
+		}
 	}
 	return 0;
 }
diff --git a/drivers/input/misc/qpnp-power-on.c b/drivers/input/misc/qpnp-power-on.c
index 5fa0d4b..36d07c5 100644
--- a/drivers/input/misc/qpnp-power-on.c
+++ b/drivers/input/misc/qpnp-power-on.c
@@ -229,6 +229,7 @@
 	bool			kpdpwr_dbc_enable;
 	bool			resin_pon_reset;
 	ktime_t			kpdpwr_last_release_time;
+	bool			legacy_hard_reset_offset;
 };
 
 static int pon_ship_mode_en;
@@ -353,7 +354,7 @@
 	if (!pon->store_hard_reset_reason)
 		return 0;
 
-	if (is_pon_gen2(pon))
+	if (is_pon_gen2(pon) && !pon->legacy_hard_reset_offset)
 		rc = qpnp_pon_masked_write(pon, QPNP_PON_SOFT_RB_SPARE(pon),
 					   GENMASK(7, 1), (reason << 1));
 	else
@@ -2524,6 +2525,9 @@
 	pon->store_hard_reset_reason = of_property_read_bool(pdev->dev.of_node,
 					"qcom,store-hard-reset-reason");
 
+	pon->legacy_hard_reset_offset = of_property_read_bool(pdev->dev.of_node,
+					"qcom,use-legacy-hard-reset-offset");
+
 	qpnp_pon_debugfs_init(pdev);
 	return 0;
 
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_config.h b/drivers/input/touchscreen/focaltech_touch/focaltech_config.h
index 157f0df..5ab6bda 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_config.h
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_config.h
@@ -121,7 +121,7 @@
  * Gesture function enable
  * default: disable
  */
-#define FTS_GESTURE_EN                          0
+#define FTS_GESTURE_EN                          1
 
 /*
  * ESD check & protection
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_core.c b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c
index 27bb390..b3d7322 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_core.c
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c
@@ -648,7 +648,7 @@
 #if FTS_GESTURE_EN
 	u8 state;
 
-	if (data->suspended) {
+	if (data->suspended && data->pdata->wakeup_gestures_en) {
 		fts_i2c_read_reg(data->client, FTS_REG_GESTURE_EN, &state);
 		if (state == 1) {
 			fts_gesture_readdata(data->client);
@@ -989,6 +989,8 @@
 		pdata->max_touch_number = FTS_MAX_POINTS;
 	}
 
+	pdata->wakeup_gestures_en = of_property_read_bool(np,
+			"focaltech,wakeup-gestures-en");
 
 	FTS_FUNC_EXIT();
 	return 0;
@@ -1310,15 +1312,17 @@
 #endif
 
 #if FTS_GESTURE_EN
-	retval = fts_gesture_suspend(data->client);
-	if (retval == 0) {
-		/* Enter into gesture mode(suspend) */
-		retval = enable_irq_wake(fts_wq_data->client->irq);
-		if (retval)
-			FTS_ERROR("%s: set_irq_wake failed", __func__);
-		data->suspended = true;
-		FTS_FUNC_EXIT();
-		return 0;
+	if (data->pdata->wakeup_gestures_en) {
+		retval = fts_gesture_suspend(data->client);
+		if (retval == 0) {
+			/* Enter into gesture mode(suspend) */
+			retval = enable_irq_wake(fts_wq_data->client->irq);
+			if (retval)
+				FTS_ERROR("%s: set_irq_wake failed", __func__);
+			data->suspended = true;
+			FTS_FUNC_EXIT();
+			return 0;
+		}
 	}
 #endif
 
@@ -1376,15 +1380,18 @@
 #endif
 
 #if FTS_GESTURE_EN
-	if (fts_gesture_resume(data->client) == 0) {
-		int err;
+	if (data->pdata->wakeup_gestures_en) {
+		if (fts_gesture_resume(data->client) == 0) {
+			int err;
 
-		err = disable_irq_wake(data->client->irq);
-		if (err)
-			FTS_ERROR("%s: disable_irq_wake failed", __func__);
-		data->suspended = false;
-		FTS_FUNC_EXIT();
-		return 0;
+			err = disable_irq_wake(data->client->irq);
+			if (err)
+				FTS_ERROR("%s: disable_irq_wake failed",
+						__func__);
+			data->suspended = false;
+			FTS_FUNC_EXIT();
+			return 0;
+		}
 	}
 #endif
 
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_core.h b/drivers/input/touchscreen/focaltech_touch/focaltech_core.h
index 52b4ffe..a3c64f9 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_core.h
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_core.h
@@ -97,10 +97,10 @@
 #define FTS_TOUCH_UP        1
 #define FTS_TOUCH_CONTACT   2
 
-#define FTS_SYSFS_ECHO_ON(buf)      ((strnicmp(buf, "1", 1)  == 0) || \
-					(strnicmp(buf, "on", 2) == 0))
-#define FTS_SYSFS_ECHO_OFF(buf)     ((strnicmp(buf, "0", 1)  == 0) || \
-					(strnicmp(buf, "off", 3) == 0))
+#define FTS_SYSFS_ECHO_ON(buf)      ((strncasecmp(buf, "1", 1)  == 0) || \
+					(strncasecmp(buf, "on", 2) == 0))
+#define FTS_SYSFS_ECHO_OFF(buf)     ((strncasecmp(buf, "0", 1)  == 0) || \
+					(strncasecmp(buf, "off", 3) == 0))
 
 /*****************************************************************************
  * Private enumerations, structures and unions using typedef
@@ -122,6 +122,7 @@
 	u32 x_min;
 	u32 y_min;
 	u32 max_touch_number;
+	bool wakeup_gestures_en;
 };
 
 struct ts_event {
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_test.c b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_test.c
index 2041369..aa4c9cf 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_test.c
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_flash/focaltech_upgrade_test.c
@@ -34,7 +34,6 @@
  *****************************************************************************/
 #include "../focaltech_core.h"
 #include "../focaltech_flash.h"
-#include <linux/wakelock.h>
 #include <linux/timer.h>
 
 /*****************************************************************************
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c b/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c
index b3bb39e..d24cd8a 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_gesture.c
@@ -69,6 +69,9 @@
 #define FTS_GESTRUE_POINTS                      255
 #define FTS_GESTRUE_POINTS_HEADER               8
 
+#define GESTURE_SMALL_AREA      0x25    /* TP Coverage < 50% */
+#define GESTURE_LARGE_AREA      0x26    /* TP Coverage > 50% */
+
 /*****************************************************************************
  * Private enumerations, structures and unions using typedef
  *****************************************************************************/
@@ -423,11 +426,21 @@
 		return ret;
 	}
 
-	/* FW recognize gesture */
-	if (fts_gesture_fw()) {
-		memcpy(fts_gesture_data.header, buf, FTS_GESTRUE_POINTS_HEADER);
-		gestrue_id = buf[0];
-		pointnum = buf[1];
+	memcpy(fts_gesture_data.header, buf, FTS_GESTRUE_POINTS_HEADER);
+	gestrue_id = buf[0];
+	pointnum = buf[1];
+
+	if (gestrue_id == GESTURE_SMALL_AREA) {
+		FTS_INFO("[GESTURE] Wakeup gesture.");
+		input_report_key(fts_input_dev, KEY_POWER, 1);
+		input_sync(fts_input_dev);
+		input_report_key(fts_input_dev, KEY_POWER, 0);
+		input_sync(fts_input_dev);
+
+	} else if (gestrue_id == GESTURE_LARGE_AREA) {
+		FTS_INFO("[GESTURE] Large object detected.");
+	} else if (fts_gesture_fw()) {
+		/* FW recognize gesture */
 		read_bytes = ((int)pointnum) * 4 + 2;
 		buf[0] = FTS_REG_GESTURE_OUTPUT_ADDRESS;
 		FTS_DEBUG("[GESTURE]PointNum=%d", pointnum);
@@ -448,12 +461,13 @@
 				| (((s16) buf[3 + (4 * i + 2)]) & 0xFF);
 		}
 
-		FTS_FUNC_EXIT();
-		return 0;
+
+	} else {
+		FTS_ERROR("[GESTURE]IC 0x%x need lib to support gestures.",
+							chip_types.chip_idh);
 	}
 
-	FTS_ERROR("[GESTURE]IC 0x%x need gesture lib to support gestures.",
-				chip_types.chip_idh);
+	FTS_FUNC_EXIT();
 
 	return 0;
 }
diff --git a/drivers/irqchip/qcom/mpm.c b/drivers/irqchip/qcom/mpm.c
index 72bd7fd..a8b8b9b 100644
--- a/drivers/irqchip/qcom/mpm.c
+++ b/drivers/irqchip/qcom/mpm.c
@@ -162,13 +162,26 @@
 	}
 }
 
-static inline void msm_mpm_set_type(struct irq_data *d,
+static void msm_mpm_program_set_type(bool set, unsigned int reg,
+					unsigned int index, unsigned int mask)
+{
+	u32 type;
+
+	type = msm_mpm_read(reg, index);
+	if (set)
+		type = ENABLE_TYPE(type, mask);
+	else
+		type = CLEAR_TYPE(type, mask);
+
+	msm_mpm_write(reg, index, type);
+}
+
+static void msm_mpm_set_type(struct irq_data *d,
 					unsigned int flowtype)
 {
 	int mpm_pin[MAX_MPM_PIN_PER_IRQ] = {-1, -1};
 	unsigned long flags;
 	int i = 0;
-	u32 type;
 	unsigned int index, mask;
 	unsigned int reg = 0;
 
@@ -180,24 +193,24 @@
 		index = mpm_pin[i]/32;
 		mask = mpm_pin[i]%32;
 
-		if (flowtype & IRQ_TYPE_LEVEL_HIGH)
-			reg = MPM_REG_FALLING_EDGE;
-
-		if (flowtype & IRQ_TYPE_EDGE_RISING)
-			reg = MPM_REG_RISING_EDGE;
-
-		if (flowtype & IRQ_TYPE_EDGE_FALLING)
-			reg = MPM_REG_POLARITY;
-
 		spin_lock_irqsave(&mpm_lock, flags);
-		type = msm_mpm_read(reg, index);
-
-		if (flowtype)
-			type = ENABLE_TYPE(type, mask);
+		reg = MPM_REG_RISING_EDGE;
+		if (flowtype & IRQ_TYPE_EDGE_RISING)
+			msm_mpm_program_set_type(1, reg, index, mask);
 		else
-			type = CLEAR_TYPE(type, mask);
+			msm_mpm_program_set_type(0, reg, index, mask);
 
-		msm_mpm_write(reg, index, type);
+		reg = MPM_REG_FALLING_EDGE;
+		if (flowtype & IRQ_TYPE_EDGE_FALLING)
+			msm_mpm_program_set_type(1, reg, index, mask);
+		else
+			msm_mpm_program_set_type(0, reg, index, mask);
+
+		reg = MPM_REG_POLARITY;
+		if (flowtype & IRQ_TYPE_LEVEL_HIGH)
+			msm_mpm_program_set_type(1, reg, index, mask);
+		else
+			msm_mpm_program_set_type(0, reg, index, mask);
 		spin_unlock_irqrestore(&mpm_lock, flags);
 	}
 }
@@ -512,6 +525,8 @@
 						IRQCHIP_STATE_PENDING, true);
 
 		}
+
+		msm_mpm_write(MPM_REG_STATUS, i, 0);
 	}
 	return IRQ_HANDLED;
 }
diff --git a/drivers/mailbox/msm_qmp.c b/drivers/mailbox/msm_qmp.c
index d6e41ae..9e898b8 100644
--- a/drivers/mailbox/msm_qmp.c
+++ b/drivers/mailbox/msm_qmp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-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
@@ -893,7 +893,7 @@
 								mdev->name);
 
 	ret = devm_request_irq(&pdev->dev, mdev->rx_irq_line, qmp_irq_handler,
-		IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND | IRQF_SHARED,
+		IRQF_TRIGGER_RISING | IRQF_SHARED,
 		edge_node->name, mdev);
 	if (ret < 0) {
 		qmp_mbox_remove(pdev);
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
index 85e9058..b4f83f7 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
+++ b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
@@ -535,10 +535,9 @@
 					CAM_SYNC_STATE_SIGNALED_ERROR);
 				if (rc == -EALREADY) {
 					CAM_ERR(CAM_CTXT,
-						"Req: %llu already signalled, sync_id:%d",
-						req->request_id,
-						req->out_map_entries[i].
-						sync_id);
+					"Req: %llu already signalled, sync_id:%d",
+					req->request_id,
+					req->out_map_entries[i].sync_id);
 					break;
 				}
 			}
@@ -629,6 +628,7 @@
 	struct cam_ctx_request *req = NULL;
 	struct cam_hw_flush_args flush_args;
 	uint32_t i;
+	int32_t sync_id = 0;
 	int rc = 0;
 
 	CAM_DBG(CAM_CTXT, "[%s] E: NRT flush req", ctx->dev_name);
@@ -683,20 +683,20 @@
 
 	if (req) {
 		if (flush_args.num_req_pending || flush_args.num_req_active) {
-			for (i = 0; i < req->num_out_map_entries; i++)
-				if (req->out_map_entries[i].sync_id != -1) {
-					rc = cam_sync_signal(
-						req->out_map_entries[i].sync_id,
+			for (i = 0; i < req->num_out_map_entries; i++) {
+				sync_id =
+					req->out_map_entries[i].sync_id;
+				if (sync_id != -1) {
+					rc = cam_sync_signal(sync_id,
 						CAM_SYNC_STATE_SIGNALED_ERROR);
 					if (rc == -EALREADY) {
 						CAM_ERR(CAM_CTXT,
-							"Req: %llu already signalled, sync_id:%d",
-							req->request_id,
-							req->out_map_entries[i].
-							sync_id);
+						"Req: %llu already signalled, sync_id:%d",
+						req->request_id, sync_id);
 						break;
 					}
 				}
+			}
 			if (flush_args.num_req_active) {
 				spin_lock(&ctx->lock);
 				list_add_tail(&req->list, &ctx->free_req_list);
diff --git a/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c b/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c
index e7de207..5e4ff0d 100644
--- a/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c
+++ b/drivers/media/platform/msm/camera/cam_cpas/cam_cpas_hw.c
@@ -873,6 +873,7 @@
 	if (!CAM_CPAS_CLIENT_VALID(client_indx))
 		return -EINVAL;
 
+	mutex_lock(&cpas_hw->hw_mutex);
 	mutex_lock(&cpas_core->client_mutex[client_indx]);
 
 	if (!CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) {
@@ -892,6 +893,7 @@
 
 unlock_client:
 	mutex_unlock(&cpas_core->client_mutex[client_indx]);
+	mutex_unlock(&cpas_hw->hw_mutex);
 	return rc;
 }
 
@@ -907,6 +909,7 @@
 	struct cam_axi_vote *axi_vote;
 	enum cam_vote_level applied_level = CAM_SVS_VOTE;
 	int rc;
+	struct cam_cpas_private_soc *soc_private = NULL;
 
 	if (!hw_priv || !start_args) {
 		CAM_ERR(CAM_CPAS, "Invalid arguments %pK %pK",
@@ -922,6 +925,8 @@
 
 	cpas_hw = (struct cam_hw_info *)hw_priv;
 	cpas_core = (struct cam_cpas *) cpas_hw->core_info;
+	soc_private = (struct cam_cpas_private_soc *)
+		cpas_hw->soc_info.soc_private;
 	cmd_hw_start = (struct cam_cpas_hw_cmd_start *)start_args;
 	client_indx = CAM_CPAS_GET_CLIENT_IDX(cmd_hw_start->client_handle);
 	ahb_vote = cmd_hw_start->ahb_vote;
@@ -1005,8 +1010,9 @@
 	cpas_client->started = true;
 	cpas_core->streamon_clients++;
 
-	CAM_DBG(CAM_CPAS, "client_indx=%d, streamon_clients=%d",
-		client_indx, cpas_core->streamon_clients);
+	CAM_DBG(CAM_CPAS, "client=%s, streamon_clients=%d",
+		soc_private->client_name[client_indx],
+		cpas_core->streamon_clients);
 done:
 	mutex_unlock(&cpas_core->client_mutex[client_indx]);
 	mutex_unlock(&cpas_hw->hw_mutex);
@@ -1028,6 +1034,7 @@
 	struct cam_cpas_client *cpas_client;
 	struct cam_ahb_vote ahb_vote;
 	struct cam_axi_vote axi_vote;
+	struct cam_cpas_private_soc *soc_private = NULL;
 	int rc = 0;
 	long result;
 
@@ -1045,6 +1052,8 @@
 
 	cpas_hw = (struct cam_hw_info *)hw_priv;
 	cpas_core = (struct cam_cpas *) cpas_hw->core_info;
+	soc_private = (struct cam_cpas_private_soc *)
+		cpas_hw->soc_info.soc_private;
 	cmd_hw_stop = (struct cam_cpas_hw_cmd_stop *)stop_args;
 	client_indx = CAM_CPAS_GET_CLIENT_IDX(cmd_hw_stop->client_handle);
 
@@ -1054,8 +1063,9 @@
 	mutex_lock(&cpas_hw->hw_mutex);
 	mutex_lock(&cpas_core->client_mutex[client_indx]);
 
-	CAM_DBG(CAM_CPAS, "client_indx=%d, streamon_clients=%d",
-		client_indx, cpas_core->streamon_clients);
+	CAM_DBG(CAM_CPAS, "client=%s, streamon_clients=%d",
+		soc_private->client_name[client_indx],
+		cpas_core->streamon_clients);
 
 	if (!CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) {
 		CAM_ERR(CAM_CPAS, "Client %d is not started", client_indx);
diff --git a/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_session_defs.h b/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_session_defs.h
index 7b2cb8b..69e6ccf 100644
--- a/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_session_defs.h
+++ b/drivers/media/platform/msm/camera/cam_icp/fw_inc/hfi_session_defs.h
@@ -261,8 +261,8 @@
 };
 
 struct frame_buffer {
-	uint32_t buffer_ptr[MAX_NUM_OF_IMAGE_PLANES];
-	uint32_t meta_buffer_ptr[MAX_NUM_OF_IMAGE_PLANES];
+	uint32_t buf_ptr[MAX_NUM_OF_IMAGE_PLANES];
+	uint32_t meta_buf_ptr[MAX_NUM_OF_IMAGE_PLANES];
 } __packed;
 
 struct bps_frame_process_data {
diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_dev.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_dev.c
index 0e36ec0..feb0bd8 100644
--- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_dev.c
+++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/bps_hw/bps_dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-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
@@ -33,6 +33,40 @@
 };
 EXPORT_SYMBOL(cam_bps_hw_info);
 
+static bool cam_bps_cpas_cb(uint32_t client_handle, void *userdata,
+	struct cam_cpas_irq_data *irq_data)
+{
+	bool error_handled = false;
+
+	if (!irq_data)
+		return error_handled;
+
+	switch (irq_data->irq_type) {
+	case CAM_CAMNOC_IRQ_IPE_BPS_UBWC_DECODE_ERROR:
+		CAM_ERR_RATE_LIMIT(CAM_ICP,
+			"IPE/BPS UBWC Decode error type=%d status=%x thr_err=%d, fcl_err=%d, len_md_err=%d, format_err=%d",
+			irq_data->irq_type,
+			irq_data->u.dec_err.decerr_status.value,
+			irq_data->u.dec_err.decerr_status.thr_err,
+			irq_data->u.dec_err.decerr_status.fcl_err,
+			irq_data->u.dec_err.decerr_status.len_md_err,
+			irq_data->u.dec_err.decerr_status.format_err);
+		error_handled = true;
+		break;
+	case CAM_CAMNOC_IRQ_IPE_BPS_UBWC_ENCODE_ERROR:
+		CAM_ERR_RATE_LIMIT(CAM_ICP,
+			"IPE/BPS UBWC Encode error type=%d status=%x",
+			irq_data->irq_type,
+			irq_data->u.enc_err.encerr_status.value);
+		error_handled = true;
+		break;
+	default:
+		break;
+	}
+
+	return error_handled;
+}
+
 int cam_bps_register_cpas(struct cam_hw_soc_info *soc_info,
 			struct cam_bps_device_core_info *core_info,
 			uint32_t hw_idx)
@@ -42,7 +76,7 @@
 
 	cpas_register_params.dev = &soc_info->pdev->dev;
 	memcpy(cpas_register_params.identifier, "bps", sizeof("bps"));
-	cpas_register_params.cam_cpas_client_cb = NULL;
+	cpas_register_params.cam_cpas_client_cb = cam_bps_cpas_cb;
 	cpas_register_params.cell_index = hw_idx;
 	cpas_register_params.userdata = NULL;
 
diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
index c6c9b85..9ed71d2 100644
--- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
@@ -308,8 +308,9 @@
 		ctx_data = &hw_mgr->ctx_data[i];
 		mutex_lock(&ctx_data->ctx_mutex);
 		if ((ctx_data->state == CAM_ICP_CTX_STATE_ACQUIRED) &&
-			(ICP_DEV_TYPE_TO_CLK_TYPE(ctx_data->
-			icp_dev_acquire_info->dev_type) == clk_info->hw_type)) {
+			(ICP_DEV_TYPE_TO_CLK_TYPE(
+			ctx_data->icp_dev_acquire_info->dev_type)
+			== clk_info->hw_type)) {
 			busy = cam_icp_frame_pending(ctx_data);
 			if (busy) {
 				mutex_unlock(&ctx_data->ctx_mutex);
@@ -2994,6 +2995,8 @@
 	uint64_t cpu_addr = 0;
 	struct ipe_frame_process_data *frame_process_data = NULL;
 	struct bps_frame_process_data *bps_frame_process_data = NULL;
+	struct frame_set *ipe_set = NULL;
+	struct frame_buffer *bps_bufs = NULL;
 
 	cmd_desc = (struct cam_cmd_buf_desc *)
 		((uint32_t *) &packet->payload + packet->cmd_buf_offset/4);
@@ -3042,14 +3045,11 @@
 		frame_process_data->cdm_buffer_addr = 0;
 		frame_process_data->cdm_prog_base = 0;
 		for (i = 0; i < frame_process_data->frames_in_batch; i++) {
+			ipe_set = &frame_process_data->framesets[i];
 			for (j = 0; j < IPE_IO_IMAGES_MAX; j++) {
 				for (k = 0; k < MAX_NUM_OF_IMAGE_PLANES; k++) {
-					frame_process_data->
-					framesets[i].buffers[j].
-					buffer_ptr[k] = 0;
-					frame_process_data->
-					framesets[i].buffers[j].
-					meta_buffer_ptr[k] = 0;
+					ipe_set->buffers[j].buf_ptr[k] = 0;
+					ipe_set->buffers[j].meta_buf_ptr[k] = 0;
 				}
 			}
 		}
@@ -3066,11 +3066,10 @@
 		bps_frame_process_data->strip_lib_out_addr = 0;
 		bps_frame_process_data->cdm_prog_addr = 0;
 		for (i = 0; i < BPS_IO_IMAGES_MAX; i++) {
+			bps_bufs = &bps_frame_process_data->buffers[i];
 			for (j = 0; j < MAX_NUM_OF_IMAGE_PLANES; j++) {
-				bps_frame_process_data->
-				buffers[i].buffer_ptr[j] = 0;
-				bps_frame_process_data->
-				buffers[i].meta_buffer_ptr[j] = 0;
+				bps_bufs->buf_ptr[j] = 0;
+				bps_bufs->meta_buf_ptr[j] = 0;
 			}
 		}
 	}
@@ -4028,8 +4027,8 @@
 		CAM_ERR(CAM_ICP, "read num bps devices failed");
 		goto num_bps_failed;
 	}
-	icp_hw_mgr.devices[CAM_ICP_DEV_BPS] = kzalloc(
-		sizeof(struct cam_hw_intf *) * num_dev, GFP_KERNEL);
+	icp_hw_mgr.devices[CAM_ICP_DEV_BPS] = kcalloc(num_dev,
+		sizeof(struct cam_hw_intf *), GFP_KERNEL);
 	if (!icp_hw_mgr.devices[CAM_ICP_DEV_BPS]) {
 		rc = -ENOMEM;
 		goto num_bps_failed;
diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
index 8753bbb..1106453 100644
--- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
+++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
@@ -26,6 +26,97 @@
 
 static const char isp_dev_name[] = "isp";
 
+#define INC_STATE_MONITOR_HEAD(head) \
+	(atomic64_add_return(1, head) % \
+	CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES)
+
+static void __cam_isp_ctx_update_state_monitor_array(
+	struct cam_isp_context *ctx_isp,
+	enum cam_isp_state_change_trigger trigger_type,
+	uint32_t req_id)
+{
+	int iterator = 0;
+
+	iterator = INC_STATE_MONITOR_HEAD(&ctx_isp->state_monitor_head);
+	ctx_isp->cam_isp_ctx_state_monitor[iterator].curr_state =
+		ctx_isp->substate_activated;
+	ctx_isp->cam_isp_ctx_state_monitor[iterator].trigger =
+		trigger_type;
+	ctx_isp->cam_isp_ctx_state_monitor[iterator].req_id =
+		req_id;
+	ctx_isp->cam_isp_ctx_state_monitor[iterator].evt_time_stamp =
+		jiffies_to_msecs(jiffies);
+}
+
+static const char *__cam_isp_ctx_substate_val_to_type(
+	uint32_t type)
+{
+	switch (type) {
+	case CAM_ISP_CTX_ACTIVATED_SOF:
+		return "SOF";
+	case CAM_ISP_CTX_ACTIVATED_APPLIED:
+		return "APPLIED";
+	case CAM_ISP_CTX_ACTIVATED_EPOCH:
+		return "EPOCH";
+	case CAM_ISP_CTX_ACTIVATED_BUBBLE:
+		return "BUBBLE";
+	case CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED:
+		return "BUBBLE_APPLIED";
+	case CAM_ISP_CTX_ACTIVATED_HALT:
+		return "HALT";
+	default:
+		return "CAM_ISP_CTX_INVALID_STATE";
+	}
+}
+
+static const char *__cam_isp_hw_evt_val_to_type(
+	uint32_t evt_id)
+{
+	switch (evt_id) {
+	case CAM_ISP_STATE_CHANGE_TRIGGER_ERROR:
+		return "ERROR";
+	case CAM_ISP_STATE_CHANGE_TRIGGER_SOF:
+		return "SOF";
+	case CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE:
+		return "REG_UPDATE";
+	case CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH:
+		return "EPOCH";
+	case CAM_ISP_STATE_CHANGE_TRIGGER_EOF:
+		return "EOF";
+	case CAM_ISP_STATE_CHANGE_TRIGGER_DONE:
+		return "DONE";
+	default:
+		return "CAM_ISP_EVENT_INVALID";
+	}
+}
+
+static void __cam_isp_ctx_dump_state_monitor_array(
+	struct cam_isp_context *ctx_isp)
+{
+	int i = 0;
+	uint64_t state_head = 0;
+	uint64_t index;
+
+	state_head = atomic64_read(&ctx_isp->state_monitor_head);
+	CAM_ERR_RATE_LIMIT(CAM_ISP,
+		"Dumping state information for preceding requests");
+
+	for (i = CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES - 1; i >= 0;
+		i--) {
+		index = (((state_head - i) +
+			CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES) %
+			CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES);
+		CAM_ERR_RATE_LIMIT(CAM_ISP,
+		"time[0x%llx] req_id[%u] state[%s] evt_type[%s]",
+		ctx_isp->cam_isp_ctx_state_monitor[index].evt_time_stamp,
+		ctx_isp->cam_isp_ctx_state_monitor[index].req_id,
+		__cam_isp_ctx_substate_val_to_type(
+		ctx_isp->cam_isp_ctx_state_monitor[index].curr_state),
+		__cam_isp_hw_evt_val_to_type(
+		ctx_isp->cam_isp_ctx_state_monitor[index].trigger));
+	}
+}
+
 static int __cam_isp_ctx_enqueue_request_in_order(
 	struct cam_context *ctx, struct cam_ctx_request *req)
 {
@@ -134,46 +225,46 @@
 	return rc;
 }
 
-static const char *__cam_isp_resource_handle_id_to_type
-	(uint32_t resource_handle)
+static const char *__cam_isp_resource_handle_id_to_type(
+	uint32_t resource_handle)
 {
 	switch (resource_handle) {
 	case CAM_ISP_IFE_OUT_RES_FULL:
-		return "CAM_ISP_IFE_OUT_RES_FULL";
+		return "FULL";
 	case CAM_ISP_IFE_OUT_RES_DS4:
-		return "CAM_ISP_IFE_OUT_RES_DS4";
+		return "DS4";
 	case CAM_ISP_IFE_OUT_RES_DS16:
-		return "CAM_ISP_IFE_OUT_RES_DS16";
+		return "DS16";
 	case CAM_ISP_IFE_OUT_RES_RAW_DUMP:
-		return "CAM_ISP_IFE_OUT_RES_RAW_DUMP";
+		return "RAW_DUMP";
 	case CAM_ISP_IFE_OUT_RES_FD:
-		return "CAM_ISP_IFE_OUT_RES_FD";
+		return "FD";
 	case CAM_ISP_IFE_OUT_RES_PDAF:
-		return "CAM_ISP_IFE_OUT_RES_PDAF";
+		return "PDAF";
 	case CAM_ISP_IFE_OUT_RES_RDI_0:
-		return "CAM_ISP_IFE_OUT_RES_RDI_0";
+		return "RDI_0";
 	case CAM_ISP_IFE_OUT_RES_RDI_1:
-		return "CAM_ISP_IFE_OUT_RES_RDI_1";
+		return "RDI_1";
 	case CAM_ISP_IFE_OUT_RES_RDI_2:
-		return "CAM_ISP_IFE_OUT_RES_RDI_2";
+		return "RDI_2";
 	case CAM_ISP_IFE_OUT_RES_RDI_3:
-		return "CAM_ISP_IFE_OUT_RES_RDI_3";
+		return "RDI_3";
 	case CAM_ISP_IFE_OUT_RES_STATS_HDR_BE:
-		return "CAM_ISP_IFE_OUT_RES_STATS_HDR_BE";
+		return "STATS_HDR_BE";
 	case CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST:
-		return "CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST";
+		return "STATS_HDR_BHIST";
 	case CAM_ISP_IFE_OUT_RES_STATS_TL_BG:
-		return "CAM_ISP_IFE_OUT_RES_STATS_TL_BG";
+		return "STATS_TL_BG";
 	case CAM_ISP_IFE_OUT_RES_STATS_BF:
-		return "CAM_ISP_IFE_OUT_RES_STATS_BF";
+		return "STATS_BF";
 	case CAM_ISP_IFE_OUT_RES_STATS_AWB_BG:
-		return "CAM_ISP_IFE_OUT_RES_STATS_AWB_BG";
+		return "STATS_AWB_BG";
 	case CAM_ISP_IFE_OUT_RES_STATS_BHIST:
-		return "CAM_ISP_IFE_OUT_RES_STATS_BHIST";
+		return "STATS_BHIST";
 	case CAM_ISP_IFE_OUT_RES_STATS_RS:
-		return "CAM_ISP_IFE_OUT_RES_STATS_RS";
+		return "STATS_RS";
 	case CAM_ISP_IFE_OUT_RES_STATS_CS:
-		return "CAM_ISP_IFE_OUT_RES_STATS_CS";
+		return "STATS_CS";
 	default:
 		return "CAM_ISP_Invalid_Resource_Type";
 	}
@@ -350,6 +441,9 @@
 	}
 
 end:
+	__cam_isp_ctx_update_state_monitor_array(ctx_isp,
+		CAM_ISP_STATE_CHANGE_TRIGGER_DONE,
+		ctx_isp->base->req_list->request_id);
 	return rc;
 }
 
@@ -510,6 +604,11 @@
 {
 	int rc = 0;
 	struct cam_isp_hw_sof_event_data      *sof_event_data = evt_data;
+	struct cam_ctx_request *req;
+	struct cam_context *ctx = ctx_isp->base;
+
+	req = list_last_entry(&ctx->pending_req_list,
+		struct cam_ctx_request, list);
 
 	if (!evt_data) {
 		CAM_ERR(CAM_ISP, "in valid sof event data");
@@ -518,6 +617,8 @@
 
 	ctx_isp->frame_id++;
 	ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
+	__cam_isp_ctx_update_state_monitor_array(ctx_isp,
+		CAM_ISP_STATE_CHANGE_TRIGGER_SOF, req->request_id);
 	CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
 		ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
 
@@ -528,11 +629,11 @@
 	void *evt_data)
 {
 	int rc = 0;
-	struct cam_ctx_request *req;
+	struct cam_ctx_request *req = NULL;
 	struct cam_isp_ctx_req *req_isp;
 	struct cam_context *ctx = ctx_isp->base;
 
-	if (ctx->state != CAM_CTX_ACTIVATED) {
+	if (ctx->state != CAM_CTX_ACTIVATED && ctx_isp->frame_id > 1) {
 		CAM_DBG(CAM_ISP, "invalid RUP");
 		goto end;
 	}
@@ -560,6 +661,11 @@
 				CAM_ISP_CTX_ACTIVATED_EPOCH;
 		}
 	}
+	if (req != NULL) {
+		__cam_isp_ctx_update_state_monitor_array(ctx_isp,
+			CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE,
+			req->request_id);
+	}
 end:
 	return rc;
 }
@@ -627,6 +733,15 @@
 	CAM_DBG(CAM_ISP, "next substate %d",
 		ctx_isp->substate_activated);
 end:
+	if (request_id == 0) {
+		req = list_last_entry(&ctx->active_req_list,
+			struct cam_ctx_request, list);
+		__cam_isp_ctx_update_state_monitor_array(ctx_isp,
+			CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id);
+	} else {
+		__cam_isp_ctx_update_state_monitor_array(ctx_isp,
+			CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, request_id);
+	}
 	return 0;
 }
 
@@ -649,6 +764,7 @@
 	int rc = 0;
 	struct cam_context                    *ctx = ctx_isp->base;
 	struct cam_isp_hw_sof_event_data      *sof_event_data = evt_data;
+	struct cam_ctx_request *req;
 
 	if (!evt_data) {
 		CAM_ERR(CAM_ISP, "in valid sof event data");
@@ -663,6 +779,10 @@
 	else
 		CAM_DBG(CAM_ISP, "Still need to wait for the buf done");
 
+	req = list_last_entry(&ctx->active_req_list,
+		struct cam_ctx_request, list);
+	__cam_isp_ctx_update_state_monitor_array(ctx_isp,
+		CAM_ISP_STATE_CHANGE_TRIGGER_SOF, ctx->req_list->request_id);
 	CAM_DBG(CAM_ISP, "next substate %d",
 		ctx_isp->substate_activated);
 
@@ -761,6 +881,10 @@
 	ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
 	CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
 end:
+	req = list_last_entry(&ctx->active_req_list, struct cam_ctx_request,
+		list);
+	__cam_isp_ctx_update_state_monitor_array(ctx_isp,
+		CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id);
 	return 0;
 }
 
@@ -772,6 +896,9 @@
 		(struct cam_isp_hw_done_event_data *) evt_data;
 
 	rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 1);
+	__cam_isp_ctx_update_state_monitor_array(ctx_isp,
+		CAM_ISP_STATE_CHANGE_TRIGGER_DONE,
+		ctx_isp->base->req_list->request_id);
 	return rc;
 }
 
@@ -786,6 +913,7 @@
 	struct cam_isp_ctx_req          *req_isp = NULL;
 	struct cam_req_mgr_error_notify  notify;
 	uint64_t                         error_request_id;
+	struct cam_hw_fence_map_entry   *fence_map_out = NULL;
 
 	struct cam_context *ctx = ctx_isp->base;
 	struct cam_isp_hw_error_event_data  *error_event_data =
@@ -814,18 +942,18 @@
 			if (!req_isp->bubble_report) {
 				for (i = 0; i < req_isp->num_fence_map_out;
 					i++) {
+					fence_map_out =
+						&req_isp->fence_map_out[i];
 					CAM_ERR(CAM_ISP, "req %llu, Sync fd %x",
-						req->request_id,
-						req_isp->fence_map_out[i].
-						sync_id);
+					req->request_id,
+					req_isp->fence_map_out[i].sync_id);
 					if (req_isp->fence_map_out[i].sync_id
 						!= -1) {
 						rc = cam_sync_signal(
-						req_isp->fence_map_out[i].
-						sync_id,
+						fence_map_out->sync_id,
 						CAM_SYNC_STATE_SIGNALED_ERROR);
-						req_isp->fence_map_out[i].
-						sync_id = -1;
+						fence_map_out->sync_id =
+						-1;
 					}
 				}
 				list_del_init(&req->list);
@@ -893,6 +1021,14 @@
 		rc = -EFAULT;
 	}
 
+
+	list_del_init(&req->list);
+	list_add(&req->list, &ctx->pending_req_list);
+	/* might need to check if active list is empty */
+	if (req != NULL) {
+		__cam_isp_ctx_update_state_monitor_array(ctx_isp,
+			CAM_ISP_STATE_CHANGE_TRIGGER_ERROR, req->request_id);
+	}
 	CAM_DBG(CAM_ISP, "Exit");
 	return rc;
 }
@@ -1013,7 +1149,7 @@
 	struct cam_ctx_request          *active_req;
 	struct cam_isp_ctx_req          *req_isp;
 	struct cam_isp_ctx_req          *active_req_isp;
-	struct cam_isp_context          *ctx_isp;
+	struct cam_isp_context          *ctx_isp = NULL;
 	struct cam_hw_config_args        cfg;
 
 	if (list_empty(&ctx->pending_req_list)) {
@@ -1087,6 +1223,11 @@
 		spin_unlock_bh(&ctx->lock);
 	}
 end:
+	if (ctx_isp != NULL) {
+		__cam_isp_ctx_update_state_monitor_array(ctx_isp,
+			CAM_ISP_STATE_CHANGE_TRIGGER_SOF,
+			ctx->req_list->request_id);
+	}
 	return rc;
 }
 
@@ -2390,16 +2531,16 @@
 	struct cam_req_mgr_apply_request *apply)
 {
 	int rc = 0;
+	struct cam_ctx_ops *ctx_ops = NULL;
 	struct cam_isp_context *ctx_isp =
 		(struct cam_isp_context *) ctx->ctx_priv;
 
 	trace_cam_apply_req("ISP", apply->request_id);
 	CAM_DBG(CAM_ISP, "Enter: apply req in Substate %d request _id:%lld",
 		 ctx_isp->substate_activated, apply->request_id);
-	if (ctx_isp->substate_machine[ctx_isp->substate_activated].
-		crm_ops.apply_req) {
-		rc = ctx_isp->substate_machine[ctx_isp->substate_activated].
-			crm_ops.apply_req(ctx, apply);
+	ctx_ops = &ctx_isp->substate_machine[ctx_isp->substate_activated];
+	if (ctx_ops->crm_ops.apply_req) {
+		rc = ctx_ops->crm_ops.apply_req(ctx, apply);
 	} else {
 		CAM_ERR_RATE_LIMIT(CAM_ISP,
 			"No handle function in activated substate %d",
@@ -2420,6 +2561,7 @@
 	uint32_t evt_id, void *evt_data)
 {
 	int rc = 0;
+	struct cam_isp_ctx_irq_ops *irq_ops = NULL;
 	struct cam_context *ctx = (struct cam_context *)context;
 	struct cam_isp_context *ctx_isp =
 		(struct cam_isp_context *)ctx->ctx_priv;
@@ -2431,13 +2573,13 @@
 
 	CAM_DBG(CAM_ISP, "Enter: State %d, Substate %d, evt id %d",
 		 ctx->state, ctx_isp->substate_activated, evt_id);
-	if (ctx_isp->substate_machine_irq[ctx_isp->substate_activated].
-		irq_ops[evt_id]) {
-		rc = ctx_isp->substate_machine_irq[ctx_isp->substate_activated].
-			irq_ops[evt_id](ctx_isp, evt_data);
+	irq_ops = &ctx_isp->substate_machine_irq[ctx_isp->substate_activated];
+	if (irq_ops->irq_ops[evt_id]) {
+		rc = irq_ops->irq_ops[evt_id](ctx_isp, evt_data);
 	} else {
 		CAM_DBG(CAM_ISP, "No handle function for substate %d",
 			ctx_isp->substate_activated);
+		__cam_isp_ctx_dump_state_monitor_array(ctx_isp);
 	}
 	CAM_DBG(CAM_ISP, "Exit: State %d Substate %d",
 		 ctx->state, ctx_isp->substate_activated);
@@ -2551,6 +2693,12 @@
 	ctx_base->state_machine = cam_isp_ctx_top_state_machine;
 	ctx_base->ctx_priv = ctx;
 
+	/* initializing current state for error logging */
+	for (i = 0; i < CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES; i++) {
+		ctx->cam_isp_ctx_state_monitor[i].curr_state =
+		CAM_ISP_CTX_ACTIVATED_MAX;
+	}
+	atomic64_set(&ctx->state_monitor_head, -1);
 err:
 	return rc;
 }
diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h
index 38ea58d..1eae89f 100644
--- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h
+++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h
@@ -28,11 +28,16 @@
 #define CAM_ISP_CTX_RES_MAX                     20
 
 /*
- * Maxiimum configuration entry size  - This is based on the
+ * Maximum configuration entry size  - This is based on the
  * worst case DUAL IFE use case plus some margin.
  */
 #define CAM_ISP_CTX_CFG_MAX                     22
 
+/*
+ * Maximum entries in state monitoring array for error logging
+ */
+#define CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES   20
+
 /* forward declaration */
 struct cam_isp_context;
 
@@ -56,6 +61,19 @@
 	CAM_ISP_CTX_ACTIVATED_MAX,
 };
 
+/**
+ * enum cam_isp_state_change_trigger - Different types of ISP events
+ *
+ */
+enum cam_isp_state_change_trigger {
+	CAM_ISP_STATE_CHANGE_TRIGGER_ERROR,
+	CAM_ISP_STATE_CHANGE_TRIGGER_SOF,
+	CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE,
+	CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH,
+	CAM_ISP_STATE_CHANGE_TRIGGER_EOF,
+	CAM_ISP_STATE_CHANGE_TRIGGER_DONE,
+	CAM_ISP_STATE_CHANGE_TRIGGER_MAX
+};
 
 /**
  * struct cam_isp_ctx_irq_ops - Function table for handling IRQ callbacks
@@ -101,23 +119,44 @@
 };
 
 /**
- * struct cam_isp_context  - ISP context object
+ * struct cam_isp_context_state_monitor - ISP context state
+ *                                        monitoring for
+ *                                        debug purposes
  *
- * @base:                  Common context object pointer
- * @frame_id:              Frame id tracking for the isp context
- * @substate_actiavted:    Current substate for the activated state.
- * @substate_machine:      ISP substate machine for external interface
- * @substate_machine_irq:  ISP substate machine for irq handling
- * @req_base:              Common request object storage
- * @req_isp:               ISP private request object storage
- * @hw_ctx:                HW object returned by the acquire device command
- * @sof_timestamp_val:     Captured time stamp value at sof hw event
- * @active_req_cnt:        Counter for the active request
- * @reported_req_id:       Last reported request id
- * @subscribe_event:       The irq event mask that CRM subscribes to, IFE will
- *                         invoke CRM cb at those event.
- * @last_applied_req_id:   Last applied request id
- * @frame_skip_count:      Number of frame to skip before change state
+ *@curr_state:          Current sub state that received req
+ *@req_type:            Event type of incoming req
+ *@req_id:              Request id
+ *@evt_time_stamp       Current time stamp
+ *
+ */
+struct cam_isp_context_state_monitor {
+	enum cam_isp_ctx_activated_substate  curr_state;
+	enum cam_isp_state_change_trigger    trigger;
+	uint32_t                             req_id;
+	int64_t                              frame_id;
+	uint64_t                             evt_time_stamp;
+};
+
+/**
+ * struct cam_isp_context   -  ISP context object
+ *
+ * @base:                      Common context object pointer
+ * @frame_id:                  Frame id tracking for the isp context
+ * @substate_actiavted:        Current substate for the activated state.
+ * @substate_machine:          ISP substate machine for external interface
+ * @substate_machine_irq:      ISP substate machine for irq handling
+ * @req_base:                  Common request object storage
+ * @req_isp:                   ISP private request object storage
+ * @hw_ctx:                    HW object returned by the acquire device command
+ * @sof_timestamp_val:         Captured time stamp value at sof hw event
+ * @active_req_cnt:            Counter for the active request
+ * @reported_req_id:           Last reported request id
+ * @subscribe_event:           The irq event mask that CRM subscribes to, IFE
+ *                             will invoke CRM cb at those event.
+ * @last_applied_req_id:       Last applied request id
+ * @frame_skip_count:          Number of frame to skip before change state
+ * @state_monitor_head:        Write index to the state monitoring array
+ * @cam_isp_ctx_state_monitor: State monitoring array
  *
  */
 struct cam_isp_context {
@@ -138,6 +177,9 @@
 	uint32_t                         subscribe_event;
 	int64_t                          last_applied_req_id;
 	uint32_t                         frame_skip_count;
+	atomic64_t                       state_monitor_head;
+	struct cam_isp_context_state_monitor cam_isp_ctx_state_monitor[
+		CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES];
 };
 
 /**
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
index 4628172..6e140e2 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
@@ -1809,7 +1809,6 @@
 	if (cam_cdm_stream_off(ctx->cdm_handle))
 		CAM_ERR(CAM_ISP, "CDM stream off failed %d",
 			ctx->cdm_handle);
-	cam_tasklet_stop(ctx->common.tasklet_info);
 
 	CAM_DBG(CAM_ISP, "Going to stop IFE Mux");
 
@@ -1831,6 +1830,8 @@
 		}
 	}
 
+	cam_tasklet_stop(ctx->common.tasklet_info);
+
 	/*
 	 * If Context does not have PIX resources and has only RDI resource
 	 * then take the first base index.
@@ -4031,6 +4032,8 @@
 	int rc = -EFAULT;
 	int i, j;
 	struct cam_iommu_handle cdm_handles;
+	struct cam_ife_hw_mgr_ctx *ctx_pool;
+	struct cam_ife_hw_mgr_res *res_list_ife_out;
 
 	CAM_DBG(CAM_ISP, "Enter");
 
@@ -4135,9 +4138,10 @@
 		INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_ife_cid);
 		INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_ife_csid);
 		INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_ife_src);
+		ctx_pool = &g_ife_hw_mgr.ctx_pool[i];
 		for (j = 0; j < CAM_IFE_HW_OUT_RES_MAX; j++) {
-			INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].
-				res_list_ife_out[j].list);
+			res_list_ife_out = &ctx_pool->res_list_ife_out[j];
+			INIT_LIST_HEAD(&res_list_ife_out->list);
 		}
 
 		/* init context pool */
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c
index 3606af9..1d38f3b 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-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
@@ -414,6 +414,8 @@
 	struct cam_ife_hw_mgr_res          *hw_mgr_res;
 	struct cam_isp_hw_get_cmd_update    update_buf;
 	struct cam_isp_hw_get_wm_update     wm_update;
+	struct cam_hw_fence_map_entry      *out_map_entries;
+	struct cam_hw_fence_map_entry      *in_map_entries;
 	uint32_t                            kmd_buf_remain_size;
 	uint32_t                            i, j, num_out_buf, num_in_buf;
 	uint32_t                            res_id_out, res_id_in, plane_id;
@@ -458,14 +460,15 @@
 			CAM_DBG(CAM_ISP,
 				"configure output io with fill fence %d",
 				fill_fence);
+			out_map_entries =
+				&prepare->out_map_entries[num_out_buf];
 			if (fill_fence) {
 				if (num_out_buf <
 					prepare->max_out_map_entries) {
-					prepare->out_map_entries[num_out_buf].
-						resource_handle =
-							io_cfg[i].resource_type;
-					prepare->out_map_entries[num_out_buf].
-						sync_id = io_cfg[i].fence;
+					out_map_entries->resource_handle =
+						io_cfg[i].resource_type;
+					out_map_entries->sync_id =
+						io_cfg[i].fence;
 					num_out_buf++;
 				} else {
 					CAM_ERR(CAM_ISP, "ln_out:%d max_ln:%d",
@@ -486,14 +489,14 @@
 			CAM_DBG(CAM_ISP,
 				"configure input io with fill fence %d",
 				fill_fence);
+			in_map_entries =
+				&prepare->in_map_entries[num_in_buf];
 			if (fill_fence) {
 				if (num_in_buf < prepare->max_in_map_entries) {
-					prepare->in_map_entries[num_in_buf].
-						resource_handle =
-							io_cfg[i].resource_type;
-					prepare->in_map_entries[num_in_buf].
-						sync_id =
-							io_cfg[i].fence;
+					in_map_entries->resource_handle =
+						io_cfg[i].resource_type;
+					in_map_entries->sync_id =
+						io_cfg[i].fence;
 					num_in_buf++;
 				} else {
 					CAM_ERR(CAM_ISP, "ln_in:%d imax_ln:%d",
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
index 24df4ce..feb79cc 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/hw_utils/irq_controller/cam_irq_controller.c
@@ -336,9 +336,11 @@
 
 int cam_irq_controller_enable_irq(void *irq_controller, uint32_t handle)
 {
-	struct cam_irq_controller  *controller  = irq_controller;
-	struct cam_irq_evt_handler *evt_handler = NULL;
-	struct cam_irq_evt_handler *evt_handler_temp;
+	struct cam_irq_controller   *controller  = irq_controller;
+	struct cam_irq_evt_handler  *evt_handler = NULL;
+	struct cam_irq_evt_handler  *evt_handler_temp;
+	struct cam_irq_register_obj *irq_register = NULL;
+	enum cam_irq_priority_level priority;
 	unsigned long               flags = 0;
 	unsigned int                i;
 	uint32_t                    irq_mask;
@@ -369,14 +371,14 @@
 		return rc;
 	}
 
+	priority = evt_handler->priority;
 	for (i = 0; i < controller->num_registers; i++) {
-		controller->irq_register_arr[i].
-		top_half_enable_mask[evt_handler->priority] |=
+		irq_register = &controller->irq_register_arr[i];
+		irq_register->top_half_enable_mask[priority] |=
 			evt_handler->evt_bit_mask_arr[i];
 
 		irq_mask = cam_io_r_mb(controller->mem_base +
-			controller->irq_register_arr[i].
-			mask_reg_offset);
+			irq_register->mask_reg_offset);
 		irq_mask |= evt_handler->evt_bit_mask_arr[i];
 
 		cam_io_w_mb(irq_mask, controller->mem_base +
@@ -390,9 +392,11 @@
 
 int cam_irq_controller_disable_irq(void *irq_controller, uint32_t handle)
 {
-	struct cam_irq_controller  *controller  = irq_controller;
-	struct cam_irq_evt_handler *evt_handler = NULL;
-	struct cam_irq_evt_handler *evt_handler_temp;
+	struct cam_irq_controller   *controller  = irq_controller;
+	struct cam_irq_evt_handler  *evt_handler = NULL;
+	struct cam_irq_evt_handler  *evt_handler_temp;
+	struct cam_irq_register_obj *irq_register;
+	enum cam_irq_priority_level priority;
 	unsigned long               flags = 0;
 	unsigned int                i;
 	uint32_t                    irq_mask;
@@ -423,31 +427,27 @@
 		return rc;
 	}
 
+	priority = evt_handler->priority;
 	for (i = 0; i < controller->num_registers; i++) {
-		controller->irq_register_arr[i].
-		top_half_enable_mask[evt_handler->priority] &=
+		irq_register = &controller->irq_register_arr[i];
+		irq_register->top_half_enable_mask[priority] &=
 			~(evt_handler->evt_bit_mask_arr[i]);
 
 		irq_mask = cam_io_r_mb(controller->mem_base +
-			controller->irq_register_arr[i].
-			mask_reg_offset);
+			irq_register->mask_reg_offset);
 		CAM_DBG(CAM_ISP, "irq_mask 0x%x before disable 0x%x",
-			controller->irq_register_arr[i].mask_reg_offset,
-			irq_mask);
+			irq_register->mask_reg_offset, irq_mask);
 		irq_mask &= ~(evt_handler->evt_bit_mask_arr[i]);
 
 		cam_io_w_mb(irq_mask, controller->mem_base +
-			controller->irq_register_arr[i].
-			mask_reg_offset);
+			irq_register->mask_reg_offset);
 		CAM_DBG(CAM_ISP, "irq_mask 0x%x after disable 0x%x",
-			controller->irq_register_arr[i].mask_reg_offset,
-			irq_mask);
+			irq_register->mask_reg_offset, irq_mask);
 
 		/* Clear the IRQ bits of this handler */
 		cam_io_w_mb(evt_handler->evt_bit_mask_arr[i],
 			controller->mem_base +
-			controller->irq_register_arr[i].
-			clear_reg_offset);
+			irq_register->clear_reg_offset);
 
 		if (controller->global_clear_offset)
 			cam_io_w_mb(
@@ -464,9 +464,11 @@
 int cam_irq_controller_unsubscribe_irq(void *irq_controller,
 	uint32_t handle)
 {
-	struct cam_irq_controller  *controller  = irq_controller;
-	struct cam_irq_evt_handler *evt_handler = NULL;
-	struct cam_irq_evt_handler *evt_handler_temp;
+	struct cam_irq_controller   *controller  = irq_controller;
+	struct cam_irq_evt_handler  *evt_handler = NULL;
+	struct cam_irq_evt_handler  *evt_handler_temp;
+	struct cam_irq_register_obj *irq_register;
+	enum cam_irq_priority_level priority;
 	uint32_t                    i;
 	uint32_t                    found = 0;
 	uint32_t                    irq_mask;
@@ -490,26 +492,24 @@
 		}
 	}
 
+	priority = evt_handler->priority;
 	if (found) {
 		for (i = 0; i < controller->num_registers; i++) {
-			controller->irq_register_arr[i].
-				top_half_enable_mask[evt_handler->priority] &=
+			irq_register = &controller->irq_register_arr[i];
+			irq_register->top_half_enable_mask[priority] &=
 				~(evt_handler->evt_bit_mask_arr[i]);
 
 			irq_mask = cam_io_r_mb(controller->mem_base +
-				controller->irq_register_arr[i].
-				mask_reg_offset);
+				irq_register->mask_reg_offset);
 			irq_mask &= ~(evt_handler->evt_bit_mask_arr[i]);
 
 			cam_io_w_mb(irq_mask, controller->mem_base +
-				controller->irq_register_arr[i].
-				mask_reg_offset);
+				irq_register->mask_reg_offset);
 
 			/* Clear the IRQ bits of this handler */
 			cam_io_w_mb(evt_handler->evt_bit_mask_arr[i],
 				controller->mem_base +
-				controller->irq_register_arr[i].
-				clear_reg_offset);
+				irq_register->clear_reg_offset);
 			if (controller->global_clear_offset)
 				cam_io_w_mb(
 					controller->global_clear_bitmask,
@@ -642,7 +642,8 @@
 
 irqreturn_t cam_irq_controller_handle_irq(int irq_num, void *priv)
 {
-	struct cam_irq_controller  *controller  = priv;
+	struct cam_irq_controller   *controller  = priv;
+	struct cam_irq_register_obj *irq_register;
 	bool         need_th_processing[CAM_IRQ_PRIORITY_MAX] = {false};
 	int          i;
 	int          j;
@@ -654,6 +655,7 @@
 		controller, controller->name, &controller->lock);
 	spin_lock(&controller->lock);
 	for (i = 0; i < controller->num_registers; i++) {
+		irq_register = &controller->irq_register_arr[i];
 		controller->irq_status_arr[i] = cam_io_r_mb(
 			controller->mem_base +
 			controller->irq_register_arr[i].status_reg_offset);
@@ -664,8 +666,7 @@
 			controller->irq_register_arr[i].status_reg_offset,
 			controller->irq_status_arr[i]);
 		for (j = 0; j < CAM_IRQ_PRIORITY_MAX; j++) {
-			if (controller->irq_register_arr[i].
-				top_half_enable_mask[j] &
+			if (irq_register->top_half_enable_mask[j] &
 				controller->irq_status_arr[i])
 				need_th_processing[j] = true;
 				CAM_DBG(CAM_ISP,
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
index 328aaaf..34f8c41 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
@@ -356,6 +356,8 @@
 	struct cam_ife_csid_reg_offset  *csid_reg;
 	int rc = 0;
 	uint32_t val = 0, i;
+	uint32_t status;
+
 
 	soc_info = &csid_hw->hw_info->soc_info;
 	csid_reg = csid_hw->csid_info->csid_reg;
@@ -370,8 +372,6 @@
 	CAM_DBG(CAM_ISP, "CSID:%d Csid reset",
 		csid_hw->hw_intf->hw_idx);
 
-	init_completion(&csid_hw->csid_top_complete);
-
 	/* Mask all interrupts */
 	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
 		csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
@@ -417,21 +417,19 @@
 		cam_io_w_mb(0x2, soc_info->reg_map[0].mem_base +
 			csid_reg->rdi_reg[i]->csid_rdi_cfg0_addr);
 
-	/* perform the top CSID HW reset */
-	cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb,
+	/* perform the top CSID HW and SW registers reset */
+	cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb_sw_all,
 		soc_info->reg_map[0].mem_base +
 		csid_reg->cmn_reg->csid_rst_strobes_addr);
 
-	CAM_DBG(CAM_ISP, " Waiting for reset complete from irq handler");
-	rc = wait_for_completion_timeout(&csid_hw->csid_top_complete,
-		msecs_to_jiffies(IFE_CSID_TIMEOUT));
-	if (rc <= 0) {
-		CAM_ERR(CAM_ISP, "CSID:%d reset completion in fail rc = %d",
-			 csid_hw->hw_intf->hw_idx, rc);
-		if (rc == 0)
-			rc = -ETIMEDOUT;
-	} else {
-		rc = 0;
+	rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
+		csid_reg->cmn_reg->csid_top_irq_status_addr,
+			status, (status & 0x1) == 0x1,
+		CAM_IFE_CSID_TIMEOUT_SLEEP_US, CAM_IFE_CSID_TIMEOUT_ALL_US);
+	if (rc < 0) {
+		CAM_ERR(CAM_ISP, "CSID:%d csid_reset fail rc = %d",
+			  csid_hw->hw_intf->hw_idx, rc);
+		rc = -ETIMEDOUT;
 	}
 
 	val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
@@ -858,6 +856,11 @@
 	path_data->height  = reserve->in_port->height;
 	path_data->start_line = reserve->in_port->line_start;
 	path_data->end_line = reserve->in_port->line_stop;
+	path_data->crop_enable = true;
+	CAM_DBG(CAM_ISP, "Res id: %d height:%d line_start %d line_stop %d",
+		reserve->res_id, reserve->in_port->height,
+		reserve->in_port->line_start, reserve->in_port->line_stop);
+
 	if (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) {
 		path_data->dt = CAM_IFE_CSID_TPG_DT_VAL;
 		path_data->vc = CAM_IFE_CSID_TPG_VC_VAL;
@@ -867,7 +870,6 @@
 	}
 
 	if (reserve->sync_mode == CAM_ISP_HW_SYNC_MASTER) {
-		path_data->crop_enable = 1;
 		path_data->start_pixel = reserve->in_port->left_start;
 		path_data->end_pixel = reserve->in_port->left_stop;
 		path_data->width  = reserve->in_port->left_width;
@@ -878,7 +880,6 @@
 			csid_hw->hw_intf->hw_idx, path_data->start_line,
 			path_data->end_line);
 	} else if (reserve->sync_mode == CAM_ISP_HW_SYNC_SLAVE) {
-		path_data->crop_enable = 1;
 		path_data->start_pixel = reserve->in_port->right_start;
 		path_data->end_pixel = reserve->in_port->right_stop;
 		path_data->width  = reserve->in_port->right_width;
@@ -889,9 +890,13 @@
 			csid_hw->hw_intf->hw_idx, path_data->start_line,
 			path_data->end_line);
 	} else {
-		path_data->crop_enable = 0;
 		path_data->width  = reserve->in_port->left_width;
 		path_data->start_pixel = reserve->in_port->left_start;
+		path_data->end_pixel = reserve->in_port->left_stop;
+		CAM_DBG(CAM_ISP, "Res id: %d left width %d start: %d stop:%d",
+			reserve->res_id, reserve->in_port->left_width,
+			reserve->in_port->left_start,
+			reserve->in_port->left_stop);
 	}
 
 	CAM_DBG(CAM_ISP, "Res %d width %d height %d", reserve->res_id,
@@ -907,7 +912,7 @@
 	int rc = 0;
 	struct cam_ife_csid_reg_offset      *csid_reg;
 	struct cam_hw_soc_info              *soc_info;
-	uint32_t i, status, val;
+	uint32_t i, val;
 
 	csid_reg = csid_hw->csid_info->csid_reg;
 	soc_info = &csid_hw->hw_info->soc_info;
@@ -936,42 +941,10 @@
 		goto err;
 	}
 
-
-	CAM_DBG(CAM_ISP, "CSID:%d enable top irq interrupt",
-		csid_hw->hw_intf->hw_idx);
-
 	csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_UP;
-	/* Enable the top IRQ interrupt */
-	cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
-		csid_reg->cmn_reg->csid_top_irq_mask_addr);
-
+	/* Reset CSID top */
 	rc = cam_ife_csid_global_reset(csid_hw);
 	if (rc) {
-		CAM_ERR(CAM_ISP, "CSID:%d csid_reset fail rc = %d",
-			  csid_hw->hw_intf->hw_idx, rc);
-		rc = -ETIMEDOUT;
-		goto disable_soc;
-	}
-
-	/*
-	 * Reset the SW registers
-	 * SW register reset also reset the mask irq, so poll the irq status
-	 * to check the reset complete.
-	 */
-	CAM_DBG(CAM_ISP, "CSID:%d Reset Software registers",
-			csid_hw->hw_intf->hw_idx);
-
-	cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb_sw_all,
-		soc_info->reg_map[0].mem_base +
-		csid_reg->cmn_reg->csid_rst_strobes_addr);
-
-	rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
-		csid_reg->cmn_reg->csid_top_irq_status_addr,
-			status, (status & 0x1) == 0x1,
-		CAM_IFE_CSID_TIMEOUT_SLEEP_US, CAM_IFE_CSID_TIMEOUT_ALL_US);
-	if (rc < 0) {
-		CAM_ERR(CAM_ISP, "software register reset timeout.....");
-		rc = -ETIMEDOUT;
 		goto disable_soc;
 	}
 
@@ -1065,6 +1038,7 @@
 	int rc = 0;
 	uint32_t  val = 0;
 	struct cam_hw_soc_info    *soc_info;
+	struct cam_ife_csid_reg_offset *csid_reg = NULL;
 
 	csid_hw->tpg_start_cnt++;
 	if (csid_hw->tpg_start_cnt == 1) {
@@ -1109,10 +1083,10 @@
 		}
 
 		/* Enable the IFE force clock on for dual isp case */
+		csid_reg = csid_hw->csid_info->csid_reg;
 		if (csid_hw->tpg_cfg.usage_type) {
 			rc = cam_ife_csid_enable_ife_force_clock_on(soc_info,
-				csid_hw->csid_info->csid_reg->tpg_reg->
-				tpg_cpas_ife_reg_offset);
+				csid_reg->tpg_reg->tpg_cpas_ife_reg_offset);
 			if (rc)
 				return rc;
 		}
@@ -1122,10 +1096,9 @@
 		val |= (0x80 << 8);
 		val |= (((csid_hw->csi2_rx_cfg.lane_num - 1) & 0x3) << 4);
 		val |= 7;
-		cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
-			csid_hw->csid_info->csid_reg->tpg_reg->
-			csid_tpg_ctrl_addr);
 
+		cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			csid_reg->tpg_reg->csid_tpg_ctrl_addr);
 		val = cam_io_r_mb(soc_info->reg_map[0].mem_base + 0x600);
 		CAM_DBG(CAM_ISP, "reg 0x%x = 0x%x", 0x600, val);
 	}
@@ -1138,6 +1111,7 @@
 {
 	int rc = 0;
 	struct cam_hw_soc_info    *soc_info;
+	struct cam_ife_csid_reg_offset *csid_reg = NULL;
 
 	if (csid_hw->tpg_start_cnt)
 		csid_hw->tpg_start_cnt--;
@@ -1146,6 +1120,7 @@
 		return 0;
 
 	soc_info = &csid_hw->hw_info->soc_info;
+	csid_reg = csid_hw->csid_info->csid_reg;
 
 	/* disable the TPG */
 	if (!csid_hw->tpg_start_cnt) {
@@ -1155,8 +1130,7 @@
 		/* Disable the IFE force clock on for dual isp case */
 		if (csid_hw->tpg_cfg.usage_type)
 			rc = cam_ife_csid_disable_ife_force_clock_on(soc_info,
-				csid_hw->csid_info->csid_reg->tpg_reg->
-				tpg_cpas_ife_reg_offset);
+				csid_reg->tpg_reg->tpg_cpas_ife_reg_offset);
 
 		/*stop the TPG */
 		cam_io_w_mb(0,  soc_info->reg_map[0].mem_base +
@@ -1669,6 +1643,10 @@
 	if (rc)
 		return rc;
 
+	/* if path decode format is payload only then RDI crop is not applied */
+	if (path_format == 0xF)
+		path_data->crop_enable = 0;
+
 	/*
 	 * RDI path config and enable the time stamp capture
 	 * Enable the measurement blocks
@@ -1905,6 +1883,7 @@
 	struct cam_isp_resource_node         *res;
 	struct cam_ife_csid_reg_offset       *csid_reg;
 	struct cam_hw_soc_info               *soc_info;
+	struct cam_ife_csid_rdi_reg_offset   *rdi_reg;
 	uint32_t  time_32, id;
 
 	time_stamp = (struct cam_csid_get_time_stamp_args  *)cmd_args;
@@ -1937,15 +1916,14 @@
 		time_stamp->time_stamp_val |= time_32;
 	} else {
 		id = res->res_id;
+		rdi_reg = csid_reg->rdi_reg[id];
 		time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
-			csid_reg->rdi_reg[id]->
-			csid_rdi_timestamp_curr1_sof_addr);
+			rdi_reg->csid_rdi_timestamp_curr1_sof_addr);
 		time_stamp->time_stamp_val = time_32;
 		time_stamp->time_stamp_val = time_stamp->time_stamp_val << 32;
 
 		time_32 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
-			csid_reg->rdi_reg[id]->
-			csid_rdi_timestamp_curr0_sof_addr);
+			rdi_reg->csid_rdi_timestamp_curr0_sof_addr);
 		time_stamp->time_stamp_val |= time_32;
 	}
 
@@ -2171,6 +2149,7 @@
 	struct cam_ife_csid_reg_offset *csid_reg =
 		csid_hw->csid_info->csid_reg;
 
+	init_completion(&csid_hw->csid_top_complete);
 	cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb,
 		csid_hw->hw_info->soc_info.reg_map[0].mem_base +
 		csid_reg->cmn_reg->csid_rst_strobes_addr);
@@ -2490,6 +2469,7 @@
 	struct cam_ife_csid_hw          *csid_hw;
 	struct cam_hw_soc_info          *soc_info;
 	struct cam_ife_csid_reg_offset  *csid_reg;
+	struct cam_ife_csid_csi2_rx_reg_offset *csi2_reg;
 	uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0;
 	uint32_t irq_status_rdi[4] = {0, 0, 0, 0};
 	uint32_t val;
@@ -2505,6 +2485,7 @@
 
 	csid_reg = csid_hw->csid_info->csid_reg;
 	soc_info = &csid_hw->hw_info->soc_info;
+	csi2_reg = csid_reg->csi2_reg;
 
 	/* read */
 	irq_status_top = cam_io_r_mb(soc_info->reg_map[0].mem_base +
@@ -2653,19 +2634,16 @@
 		CAM_ERR(CAM_ISP, "CSID:%d LONG_PKT_CAPTURED",
 			csid_hw->hw_intf->hw_idx);
 		val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
-			csid_reg->csi2_reg->
-			csid_csi2_rx_captured_long_pkt_0_addr);
+			csi2_reg->csid_csi2_rx_captured_long_pkt_0_addr);
 		CAM_ERR(CAM_ISP, "CSID:%d long packet VC :%d DT:%d WC:%d",
 			csid_hw->hw_intf->hw_idx,
 			(val >> 22), ((val >> 16) & 0x3F), (val & 0xFFFF));
 		val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
-			csid_reg->csi2_reg->
-			csid_csi2_rx_captured_long_pkt_1_addr);
+			csi2_reg->csid_csi2_rx_captured_long_pkt_1_addr);
 		CAM_ERR(CAM_ISP, "CSID:%d long packet ECC :%d",
 			csid_hw->hw_intf->hw_idx, val);
 		val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
-			csid_reg->csi2_reg->
-			csid_csi2_rx_captured_long_pkt_ftr_addr);
+			csi2_reg->csid_csi2_rx_captured_long_pkt_ftr_addr);
 		CAM_ERR(CAM_ISP, "CSID:%d long pkt cal CRC:%d expected CRC:%d",
 			csid_hw->hw_intf->hw_idx, (val >> 16), (val & 0xFFFF));
 	}
@@ -2674,14 +2652,12 @@
 		CAM_ERR(CAM_ISP, "CSID:%d SHORT_PKT_CAPTURED",
 			csid_hw->hw_intf->hw_idx);
 		val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
-			csid_reg->csi2_reg->
-			csid_csi2_rx_captured_short_pkt_0_addr);
+			csi2_reg->csid_csi2_rx_captured_short_pkt_0_addr);
 		CAM_ERR(CAM_ISP, "CSID:%d short pkt VC :%d DT:%d LC:%d",
 			csid_hw->hw_intf->hw_idx,
 			(val >> 22), ((val >> 16) & 0x1F), (val & 0xFFFF));
 		val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
-			csid_reg->csi2_reg->
-			csid_csi2_rx_captured_short_pkt_1_addr);
+			csi2_reg->csid_csi2_rx_captured_short_pkt_1_addr);
 		CAM_ERR(CAM_ISP, "CSID:%d short packet ECC :%d",
 			csid_hw->hw_intf->hw_idx, val);
 	}
@@ -2691,8 +2667,7 @@
 		CAM_ERR(CAM_ISP, "CSID:%d CPHY_PKT_HDR_CAPTURED",
 			csid_hw->hw_intf->hw_idx);
 		val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
-			csid_reg->csi2_reg->
-			csid_csi2_rx_captured_cphy_pkt_hdr_addr);
+			csi2_reg->csid_csi2_rx_captured_cphy_pkt_hdr_addr);
 		CAM_ERR(CAM_ISP, "CSID:%d cphy packet VC :%d DT:%d WC:%d",
 			csid_hw->hw_intf->hw_idx,
 			(val >> 22), ((val >> 16) & 0x1F), (val & 0xFFFF));
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
index 2c4fe9d..fd38a96 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
@@ -32,17 +32,17 @@
 };
 
 static uint32_t camif_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
-	0x0003FD1F,
+	0x00000017,
 	0x00000000,
 };
 
 static uint32_t camif_irq_err_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
-	0x00000000,
+	0x0003FC00,
 	0x0FFF7EBC,
 };
 
 static uint32_t rdi_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
-	0x780000e0,
+	0x780001e0,
 	0x00000000,
 };
 
@@ -89,9 +89,10 @@
 	spin_lock_irqsave(&vfe_core_info->spin_lock, flags);
 	(*evt_payload)->error_type = 0;
 	list_add_tail(&(*evt_payload)->list, &vfe_core_info->free_payload_list);
+	*evt_payload = NULL;
 	spin_unlock_irqrestore(&vfe_core_info->spin_lock, flags);
 
-	*evt_payload = NULL;
+
 	return 0;
 }
 
@@ -156,6 +157,7 @@
 	struct cam_vfe_irq_handler_priv     *handler_priv;
 	struct cam_vfe_top_irq_evt_payload  *evt_payload;
 	struct cam_vfe_hw_core_info         *core_info;
+	bool                                 error_flag = false;
 
 	CAM_DBG(CAM_ISP, "IRQ status_0 = %x, IRQ status_1 = %x",
 		th_payload->evt_status_arr[0], th_payload->evt_status_arr[1]);
@@ -166,14 +168,20 @@
 	 *  need to handle overflow condition here, otherwise irq storm
 	 *  will block everything
 	 */
-
-	if (th_payload->evt_status_arr[1]) {
-		CAM_ERR(CAM_ISP, "IRQ status_1: %x, Masking all interrupts",
+	if (th_payload->evt_status_arr[1] ||
+		(th_payload->evt_status_arr[0] & camif_irq_err_reg_mask[0])) {
+		CAM_ERR(CAM_ISP,
+			"Encountered Error: vfe:%d:  Irq_status0=0x%x Status1=0x%x",
+			handler_priv->core_index, th_payload->evt_status_arr[0],
 			th_payload->evt_status_arr[1]);
+		CAM_ERR(CAM_ISP,
+			"Stopping further IRQ processing from this HW index=%d",
+			handler_priv->core_index);
 		cam_irq_controller_disable_irq(core_info->vfe_irq_controller,
 			core_info->irq_err_handle);
 		cam_irq_controller_clear_and_mask(evt_id,
 			core_info->vfe_irq_controller);
+		error_flag = true;
 	}
 
 	rc  = cam_vfe_get_evt_payload(handler_priv->core_info, &evt_payload);
@@ -200,7 +208,9 @@
 			irq_reg_offset[i]);
 	}
 
-	CAM_DBG(CAM_ISP, "Violation status = %x", evt_payload->irq_reg_val[2]);
+	if (error_flag)
+		CAM_INFO(CAM_ISP, "Violation status = %x",
+			evt_payload->irq_reg_val[2]);
 
 	th_payload->evt_payload_priv = evt_payload;
 
@@ -291,6 +301,8 @@
 	struct cam_vfe_hw_core_info       *core_info = NULL;
 	struct cam_isp_resource_node      *isp_res = NULL;
 	int rc = 0;
+	uint32_t                           reset_core_args =
+					CAM_VFE_HW_RESET_HW_AND_REG;
 
 	CAM_DBG(CAM_ISP, "Enter");
 	if (!hw_priv) {
@@ -327,6 +339,8 @@
 			CAM_ERR(CAM_ISP, "deinit failed");
 	}
 
+	rc = cam_vfe_reset(hw_priv, &reset_core_args, sizeof(uint32_t));
+
 	/* Turn OFF Regulators, Clocks and other SOC resources */
 	CAM_DBG(CAM_ISP, "Disable SOC resource");
 	rc = cam_vfe_disable_soc_resources(soc_info);
@@ -373,7 +387,7 @@
 
 	reinit_completion(&vfe_hw->hw_complete);
 
-	CAM_DBG(CAM_ISP, "calling RESET");
+	CAM_DBG(CAM_ISP, "calling RESET on vfe %d", soc_info->index);
 	core_info->vfe_top->hw_ops.reset(core_info->vfe_top->top_priv,
 		reset_core_args, arg_size);
 	CAM_DBG(CAM_ISP, "waiting for vfe reset complete");
@@ -416,23 +430,6 @@
 	CAM_DBG(CAM_ISP, "IRQ status_0 = %x", th_payload->evt_status_arr[0]);
 	CAM_DBG(CAM_ISP, "IRQ status_1 = %x", th_payload->evt_status_arr[1]);
 
-	/*
-	 *  need to handle non-recoverable condition here, otherwise irq storm
-	 *  will block everything.
-	 */
-	if (th_payload->evt_status_arr[0] & 0x3FC00) {
-		CAM_ERR(CAM_ISP,
-			"Encountered Error Irq_status0=0x%x Status1=0x%x",
-			th_payload->evt_status_arr[0],
-			th_payload->evt_status_arr[1]);
-		CAM_ERR(CAM_ISP,
-			"Stopping further IRQ processing from this HW index=%d",
-			handler_priv->core_index);
-		cam_io_w(0, handler_priv->mem_base + 0x60);
-		cam_io_w(0, handler_priv->mem_base + 0x5C);
-		return 0;
-	}
-
 	rc  = cam_vfe_get_evt_payload(handler_priv->core_info, &evt_payload);
 	if (rc) {
 		CAM_ERR_RATE_LIMIT(CAM_ISP,
@@ -705,6 +702,7 @@
 	case CAM_ISP_HW_CMD_GET_BUF_UPDATE:
 	case CAM_ISP_HW_CMD_GET_HFR_UPDATE:
 	case CAM_ISP_HW_CMD_STRIPE_UPDATE:
+	case CAM_ISP_HW_CMD_STOP_BUS_ERR_IRQ:
 		rc = core_info->vfe_bus->hw_ops.process_cmd(
 			core_info->vfe_bus->bus_priv, cmd_type, cmd_args,
 			arg_size);
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
index ed728f5..969b75a 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
@@ -2291,6 +2291,7 @@
 	struct cam_buf_io_cfg                    *io_cfg;
 	struct cam_vfe_bus_ver2_vfe_out_data     *vfe_out_data = NULL;
 	struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL;
+	struct cam_vfe_bus_ver2_reg_offset_ubwc_client *ubwc_client = NULL;
 	uint32_t *reg_val_pair;
 	uint32_t  i, j, size = 0;
 	uint32_t  frame_inc = 0, ubwc_bw_limit = 0, camera_hw_version, val;
@@ -2326,7 +2327,7 @@
 		}
 
 		wm_data = vfe_out_data->wm_res[i]->res_priv;
-
+		ubwc_client = wm_data->hw_regs->ubwc_regs;
 		/* update width register */
 		CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
 			wm_data->hw_regs->buffer_width_cfg,
@@ -2398,9 +2399,8 @@
 					 * update offset value.
 					 */
 					CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair,
-						j,
-						wm_data->hw_regs->ubwc_regs->
-						h_init, wm_data->offset);
+						j, ubwc_client->h_init,
+						wm_data->offset);
 					wm_data->h_init = wm_data->offset;
 				}
 			} else if (wm_data->h_init !=
@@ -2428,8 +2428,7 @@
 				io_cfg->planes[i].meta_stride ||
 				!wm_data->init_cfg_done) {
 				CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
-					wm_data->hw_regs->ubwc_regs->
-					meta_stride,
+					ubwc_client->meta_stride,
 					io_cfg->planes[i].meta_stride);
 				wm_data->ubwc_meta_stride =
 					io_cfg->planes[i].meta_stride;
@@ -2453,8 +2452,7 @@
 				io_cfg->planes[i].meta_offset ||
 				!wm_data->init_cfg_done) {
 				CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
-					wm_data->hw_regs->ubwc_regs->
-					meta_offset,
+					ubwc_client->meta_offset,
 					io_cfg->planes[i].meta_offset);
 				wm_data->ubwc_meta_offset =
 					io_cfg->planes[i].meta_offset;
@@ -2849,7 +2847,7 @@
 	case CAM_ISP_HW_CMD_STOP_BUS_ERR_IRQ:
 		bus_priv = (struct cam_vfe_bus_ver2_priv  *) priv;
 		if (bus_priv->error_irq_handle) {
-			CAM_INFO(CAM_ISP, "Mask off bus error irq handler");
+			CAM_DBG(CAM_ISP, "Mask off bus error irq handler");
 			rc = cam_irq_controller_unsubscribe_irq(
 				bus_priv->common_data.bus_irq_controller,
 				bus_priv->error_irq_handle);
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
index 976e6d2..5d6045b 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
@@ -275,7 +275,7 @@
 	}
 
 	if (hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
-		CAM_ERR_RATE_LIMIT(CAM_ISP,
+		CAM_DBG(CAM_ISP,
 			"VFE:%d Not ready to set clocks yet :%d",
 			res->hw_intf->hw_idx,
 			hw_info->hw_state);
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
index 32f11a7..f172a79 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
@@ -145,8 +145,7 @@
 	}
 
 	rc = cam_mem_get_cpu_buf(
-		p_cfg_req->hw_cfg_args.
-		hw_update_entries[CAM_JPEG_PARAM].handle,
+		p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].handle,
 		(uint64_t *)&kaddr, &cmd_buf_len);
 	if (rc) {
 		CAM_ERR(CAM_JPEG, "unable to get info for cmd buf: %x %d",
@@ -157,20 +156,20 @@
 	cmd_buf_kaddr = (uint32_t *)kaddr;
 
 	cmd_buf_kaddr =
-		(cmd_buf_kaddr + (p_cfg_req->hw_cfg_args.
-		hw_update_entries[CAM_JPEG_PARAM].offset / sizeof(uint32_t)));
+		(cmd_buf_kaddr +
+		(p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].offset
+			/ sizeof(uint32_t)));
 
 	p_params = (struct cam_jpeg_config_inout_param_info *)cmd_buf_kaddr;
 
 	p_params->output_size = task_data->result_size;
 	CAM_DBG(CAM_JPEG, "Encoded Size %d", task_data->result_size);
 
-	buf_data.num_handles = p_cfg_req->
-		hw_cfg_args.num_out_map_entries;
+	buf_data.num_handles =
+		p_cfg_req->hw_cfg_args.num_out_map_entries;
 	for (i = 0; i < buf_data.num_handles; i++) {
 		buf_data.resource_handle[i] =
-			p_cfg_req->hw_cfg_args.
-			out_map_entries[i].resource_handle;
+		p_cfg_req->hw_cfg_args.out_map_entries[i].resource_handle;
 	}
 	buf_data.request_id =
 		(uint64_t)p_cfg_req->hw_cfg_args.priv;
@@ -267,8 +266,8 @@
 	uint32_t *ch_base_iova_addr;
 	size_t ch_base_len;
 
-	rc = cam_mem_get_cpu_buf(config_args->
-		hw_update_entries[CAM_JPEG_CHBASE].handle,
+	rc = cam_mem_get_cpu_buf(
+		config_args->hw_update_entries[CAM_JPEG_CHBASE].handle,
 		&iova_addr, &ch_base_len);
 	if (rc) {
 		CAM_ERR(CAM_JPEG,
@@ -285,10 +284,10 @@
 
 	dev_type = ctx_data->jpeg_dev_acquire_info.dev_type;
 	mem_cam_base = hw_mgr->cdm_reg_map[dev_type][0]->mem_cam_base;
-	size = hw_mgr->cdm_info[dev_type][0].cdm_ops->
-		cdm_required_size_changebase();
-	hw_mgr->cdm_info[dev_type][0].cdm_ops->
-		cdm_write_changebase(ch_base_iova_addr, mem_cam_base);
+	size =
+	hw_mgr->cdm_info[dev_type][0].cdm_ops->cdm_required_size_changebase();
+	hw_mgr->cdm_info[dev_type][0].cdm_ops->cdm_write_changebase(
+		ch_base_iova_addr, mem_cam_base);
 
 	cdm_cmd = ctx_data->cdm_cmd;
 	cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].bl_addr.mem_handle =
@@ -322,6 +321,7 @@
 	struct cam_jpeg_set_irq_cb irq_cb;
 	struct cam_jpeg_hw_cfg_req *p_cfg_req = NULL;
 	struct cam_hw_done_event_data buf_data;
+	struct cam_hw_config_args *hw_cfg_args = NULL;
 
 	if (!hw_mgr || !task_data) {
 		CAM_ERR(CAM_JPEG, "Invalid arguments %pK %pK",
@@ -444,8 +444,8 @@
 	for (i = CAM_JPEG_CFG; i < (config_args->num_hw_update_entries - 1);
 		i++) {
 		cmd = (config_args->hw_update_entries + i);
-		cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].
-			bl_addr.mem_handle = cmd->handle;
+		cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].bl_addr.mem_handle
+			= cmd->handle;
 		cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].offset =
 			cmd->offset;
 		cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].len =
@@ -456,8 +456,7 @@
 	}
 
 	rc = cam_cdm_submit_bls(
-		hw_mgr->cdm_info[dev_type][0].cdm_handle,
-		cdm_cmd);
+		hw_mgr->cdm_info[dev_type][0].cdm_handle, cdm_cmd);
 	if (rc) {
 		CAM_ERR(CAM_JPEG, "Failed to apply the configs %d", rc);
 		goto end_callcb;
@@ -483,15 +482,14 @@
 end_callcb:
 	mutex_unlock(&hw_mgr->hw_mgr_mutex);
 	if (p_cfg_req) {
-		buf_data.num_handles = p_cfg_req->
-			hw_cfg_args.num_out_map_entries;
+		hw_cfg_args = &p_cfg_req->hw_cfg_args;
+		buf_data.num_handles =
+			hw_cfg_args->num_out_map_entries;
 		for (i = 0; i < buf_data.num_handles; i++) {
 			buf_data.resource_handle[i] =
-				p_cfg_req->hw_cfg_args.
-				out_map_entries[i].resource_handle;
+			hw_cfg_args->out_map_entries[i].resource_handle;
 		}
-		buf_data.request_id =
-			(uint64_t)p_cfg_req->hw_cfg_args.priv;
+		buf_data.request_id = (uint64_t)p_cfg_req->hw_cfg_args.priv;
 		ctx_data->ctxt_event_cb(ctx_data->context_priv, 0, &buf_data);
 	}
 
@@ -753,8 +751,8 @@
 	p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0];
 	if (hw_mgr->device_in_use[dev_type][0] == true &&
 		p_cfg_req != NULL) {
-		if ((struct cam_jpeg_hw_ctx_data *)p_cfg_req->
-		hw_cfg_args.ctxt_to_hw_map == ctx_data) {
+		if ((struct cam_jpeg_hw_ctx_data *)
+			p_cfg_req->hw_cfg_args.ctxt_to_hw_map == ctx_data) {
 			/* stop reset Unregister CB and deinit */
 			irq_cb.jpeg_hw_mgr_cb = cam_jpeg_hw_mgr_cb;
 			irq_cb.data = NULL;
@@ -811,8 +809,8 @@
 
 	list_for_each_entry_safe(cfg_req, req_temp,
 		&hw_mgr->hw_config_req_list, list) {
-		if ((cfg_req) && ((struct cam_jpeg_hw_ctx_data *)cfg_req->
-			hw_cfg_args.ctxt_to_hw_map != ctx_data))
+		if ((cfg_req) && ((struct cam_jpeg_hw_ctx_data *)
+			cfg_req->hw_cfg_args.ctxt_to_hw_map != ctx_data))
 			continue;
 
 		list_del_init(&cfg_req->list);
@@ -1091,8 +1089,8 @@
 		hw_mgr->cdm_info[dev_type][0].ref_cnt++;
 	}
 
-	size = hw_mgr->cdm_info[dev_type][0].
-		cdm_ops->cdm_required_size_changebase();
+	size =
+	hw_mgr->cdm_info[dev_type][0].cdm_ops->cdm_required_size_changebase();
 
 	if (hw_mgr->cdm_info[dev_type][0].ref_cnt == 1)
 		if (cam_cdm_stream_on(
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c
index 2d343dd..bc6dce9 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-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
@@ -47,9 +47,8 @@
 	}
 
 	soc_info = &jpeg_dma_dev->soc_info;
-	core_info =
-		(struct cam_jpeg_dma_device_core_info *)jpeg_dma_dev->
-		core_info;
+	core_info = (struct cam_jpeg_dma_device_core_info *)
+		jpeg_dma_dev->core_info;
 
 	if (!soc_info || !core_info) {
 		CAM_ERR(CAM_JPEG, "soc_info = %pK core_info = %pK",
@@ -159,9 +158,8 @@
 		return -EINVAL;
 	}
 
-	core_info =
-		(struct cam_jpeg_dma_device_core_info *)jpeg_dma_dev->
-		core_info;
+	core_info = (struct cam_jpeg_dma_device_core_info *)
+		jpeg_dma_dev->core_info;
 
 	switch (cmd_type) {
 	case CAM_JPEG_CMD_SET_IRQ_CB:
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c
index 05ae7cc..ef10406 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-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
@@ -153,8 +153,8 @@
 		rc = -ENOMEM;
 		goto error_alloc_core;
 	}
-	core_info = (struct cam_jpeg_dma_device_core_info *)jpeg_dma_dev->
-		core_info;
+	core_info = (struct cam_jpeg_dma_device_core_info *)
+		jpeg_dma_dev->core_info;
 
 	match_dev = of_match_device(pdev->dev.driver->of_match_table,
 		&pdev->dev);
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c
index 934b911..9fa691b 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-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
@@ -58,9 +58,8 @@
 	}
 
 	soc_info = &jpeg_enc_dev->soc_info;
-	core_info =
-		(struct cam_jpeg_enc_device_core_info *)jpeg_enc_dev->
-		core_info;
+	core_info = (struct cam_jpeg_enc_device_core_info *)
+		jpeg_enc_dev->core_info;
 
 	if (!soc_info || !core_info) {
 		CAM_ERR(CAM_JPEG, "soc_info = %pK core_info = %pK",
@@ -168,9 +167,8 @@
 		return IRQ_HANDLED;
 	}
 	soc_info = &jpeg_enc_dev->soc_info;
-	core_info =
-		(struct cam_jpeg_enc_device_core_info *)jpeg_enc_dev->
-		core_info;
+	core_info = (struct cam_jpeg_enc_device_core_info *)
+		jpeg_enc_dev->core_info;
 	hw_info = core_info->jpeg_enc_hw_info;
 	mem_base = soc_info->reg_map[0].mem_base;
 
@@ -188,8 +186,7 @@
 		spin_lock(&jpeg_enc_dev->hw_lock);
 		if (core_info->core_state == CAM_JPEG_ENC_CORE_READY) {
 			encoded_size = cam_io_r_mb(mem_base +
-				core_info->jpeg_enc_hw_info->reg_offset.
-				encode_size);
+			core_info->jpeg_enc_hw_info->reg_offset.encode_size);
 			if (core_info->irq_cb.jpeg_hw_mgr_cb) {
 				core_info->irq_cb.jpeg_hw_mgr_cb(irq_status,
 					encoded_size,
@@ -263,9 +260,8 @@
 	}
 	/* maskdisable.clrirq.maskenable.resetcmd */
 	soc_info = &jpeg_enc_dev->soc_info;
-	core_info =
-		(struct cam_jpeg_enc_device_core_info *)jpeg_enc_dev->
-		core_info;
+	core_info = (struct cam_jpeg_enc_device_core_info *)
+		jpeg_enc_dev->core_info;
 	hw_info = core_info->jpeg_enc_hw_info;
 	mem_base = soc_info->reg_map[0].mem_base;
 
@@ -348,9 +344,8 @@
 		return -EINVAL;
 	}
 	soc_info = &jpeg_enc_dev->soc_info;
-	core_info =
-		(struct cam_jpeg_enc_device_core_info *)jpeg_enc_dev->
-		core_info;
+	core_info = (struct cam_jpeg_enc_device_core_info *)
+		jpeg_enc_dev->core_info;
 	hw_info = core_info->jpeg_enc_hw_info;
 	mem_base = soc_info->reg_map[0].mem_base;
 
@@ -398,9 +393,8 @@
 		return -EINVAL;
 	}
 
-	core_info =
-		(struct cam_jpeg_enc_device_core_info *)jpeg_enc_dev->
-		core_info;
+	core_info = (struct cam_jpeg_enc_device_core_info *)
+		jpeg_enc_dev->core_info;
 
 	switch (cmd_type) {
 	case CAM_JPEG_CMD_SET_IRQ_CB:
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c
index 2180448..d1eb526 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-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
@@ -152,8 +152,8 @@
 		rc = -ENOMEM;
 		goto error_alloc_core;
 	}
-	core_info = (struct cam_jpeg_enc_device_core_info *)jpeg_enc_dev->
-		core_info;
+	core_info = (struct cam_jpeg_enc_device_core_info *)
+		jpeg_enc_dev->core_info;
 
 	match_dev = of_match_device(pdev->dev.driver->of_match_table,
 		&pdev->dev);
diff --git a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c
index 20b8586..898997a 100644
--- a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-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
@@ -391,13 +391,14 @@
 	work_data = (struct cam_lrme_mgr_work_data *)data;
 	hw_device = work_data->hw_device;
 
-	rc = cam_lrme_mgr_util_get_frame_req(&hw_device->
-		frame_pending_list_high, &frame_req, &hw_device->high_req_lock);
+	rc = cam_lrme_mgr_util_get_frame_req(
+		&hw_device->frame_pending_list_high, &frame_req,
+		&hw_device->high_req_lock);
 
 	if (!frame_req) {
-		rc = cam_lrme_mgr_util_get_frame_req(&hw_device->
-				frame_pending_list_normal, &frame_req,
-				&hw_device->normal_req_lock);
+		rc = cam_lrme_mgr_util_get_frame_req(
+			&hw_device->frame_pending_list_normal, &frame_req,
+			&hw_device->normal_req_lock);
 		if (frame_req)
 			req_prio = 1;
 	}
diff --git a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c
index 21e66a2..6f98354 100644
--- a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c
+++ b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c
@@ -449,8 +449,8 @@
 		cb_args.cb_type = CAM_LRME_CB_PUT_FRAME;
 		cb_args.frame_req = req_submit;
 		if (lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb)
-			lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(lrme_core->
-				hw_mgr_cb.data, &cb_args);
+			lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(
+				lrme_core->hw_mgr_cb.data, &cb_args);
 	} else if (req_submit) {
 		submit_args.frame_req = req_submit;
 		submit_args.hw_update_entries = req_submit->hw_update_entries;
@@ -468,8 +468,8 @@
 		cb_args.cb_type = CAM_LRME_CB_PUT_FRAME;
 		cb_args.frame_req = req_proc;
 		if (lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb)
-			lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(lrme_core->
-				hw_mgr_cb.data, &cb_args);
+			lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(
+				lrme_core->hw_mgr_cb.data, &cb_args);
 	} else if (req_proc) {
 		submit_args.frame_req = req_proc;
 		submit_args.hw_update_entries = req_proc->hw_update_entries;
@@ -511,8 +511,8 @@
 		cb_args.cb_type = CAM_LRME_CB_PUT_FRAME;
 		cb_args.frame_req = req_submit;
 		if (lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb)
-			lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(lrme_core->
-				hw_mgr_cb.data, &cb_args);
+			lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(
+				lrme_core->hw_mgr_cb.data, &cb_args);
 	} else if (req_submit) {
 		submit_args.frame_req = req_submit;
 		submit_args.hw_update_entries = req_submit->hw_update_entries;
@@ -530,8 +530,8 @@
 		cb_args.cb_type = CAM_LRME_CB_PUT_FRAME;
 		cb_args.frame_req = req_proc;
 		if (lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb)
-			lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(lrme_core->
-				hw_mgr_cb.data, &cb_args);
+			lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(
+				lrme_core->hw_mgr_cb.data, &cb_args);
 	} else if (req_proc) {
 		submit_args.frame_req = req_proc;
 		submit_args.hw_update_entries = req_proc->hw_update_entries;
@@ -745,8 +745,8 @@
 	}
 
 	if (lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb) {
-		lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(lrme_core->
-			hw_mgr_cb.data, &cb_args);
+		lrme_core->hw_mgr_cb.cam_lrme_hw_mgr_cb(
+			lrme_core->hw_mgr_cb.data, &cb_args);
 	} else {
 		CAM_ERR(CAM_LRME, "No hw mgr cb");
 		rc = -EINVAL;
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
index e66d21d..aaba481 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
@@ -1684,8 +1684,8 @@
 					evt_data.u.error = err_info->error;
 					if (device->ops &&
 						device->ops->process_evt)
-						rc = device->ops->
-							process_evt(&evt_data);
+						rc = device->ops->process_evt(
+							&evt_data);
 				}
 			}
 			/* Bring processing pointer to bubbled req id */
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c
index 079f5bb..9f26635 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_actuator/cam_actuator_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-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
@@ -193,16 +193,12 @@
 		for (i = 0; i < size; i++) {
 			rc = camera_io_dev_poll(
 			io_master_info,
-			i2c_list->i2c_settings.
-				reg_setting[i].reg_addr,
-			i2c_list->i2c_settings.
-				reg_setting[i].reg_data,
-			i2c_list->i2c_settings.
-				reg_setting[i].data_mask,
+			i2c_list->i2c_settings.reg_setting[i].reg_addr,
+			i2c_list->i2c_settings.reg_setting[i].reg_data,
+			i2c_list->i2c_settings.reg_setting[i].data_mask,
 			i2c_list->i2c_settings.addr_type,
-				i2c_list->i2c_settings.data_type,
-			i2c_list->i2c_settings.
-				reg_setting[i].delay);
+			i2c_list->i2c_settings.data_type,
+			i2c_list->i2c_settings.reg_setting[i].delay);
 			if (rc < 0) {
 				CAM_ERR(CAM_ACTUATOR,
 					"i2c poll apply setting Fail: %d", rc);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c
index b975418..fe69fcb 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c
@@ -94,8 +94,8 @@
 	CAM_DBG(CAM_CCI, "CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR %d len %d max %d",
 		read_val, len,
 		cci_dev->cci_i2c_queue_info[master][queue].max_queue_size);
-	if ((read_val + len + 1) > cci_dev->
-		cci_i2c_queue_info[master][queue].max_queue_size) {
+	if ((read_val + len + 1) >
+		cci_dev->cci_i2c_queue_info[master][queue].max_queue_size) {
 		uint32_t reg_val = 0;
 		uint32_t report_val = CCI_I2C_REPORT_CMD | (1 << 8);
 
@@ -113,16 +113,18 @@
 		CAM_DBG(CAM_CCI, "CCI_QUEUE_START_ADDR");
 		spin_lock_irqsave(
 			&cci_dev->cci_master_info[master].lock_q[queue], flags);
-		atomic_set(&cci_dev->cci_master_info[master].
-						done_pending[queue], 1);
+		atomic_set(
+			&cci_dev->cci_master_info[master].done_pending[queue],
+			1);
 		cam_io_w_mb(reg_val, base +
 			CCI_QUEUE_START_ADDR);
 		CAM_DBG(CAM_CCI, "wait_for_completion_timeout");
 		atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1);
 		spin_unlock_irqrestore(
 			&cci_dev->cci_master_info[master].lock_q[queue], flags);
-		rc = wait_for_completion_timeout(&cci_dev->
-			cci_master_info[master].report_q[queue], CCI_TIMEOUT);
+		rc = wait_for_completion_timeout(
+			&cci_dev->cci_master_info[master].report_q[queue],
+			CCI_TIMEOUT);
 		if (rc <= 0) {
 			CAM_ERR(CAM_CCI, "Wait_for_completion_timeout: rc: %d",
 				rc);
@@ -244,8 +246,8 @@
 		return -EINVAL;
 	}
 
-	rc = wait_for_completion_timeout(&cci_dev->
-		cci_master_info[master].report_q[queue], CCI_TIMEOUT);
+	rc = wait_for_completion_timeout(
+		&cci_dev->cci_master_info[master].report_q[queue], CCI_TIMEOUT);
 	CAM_DBG(CAM_CCI, "wait DONE_for_completion_timeout");
 
 	if (rc <= 0) {
@@ -338,8 +340,9 @@
 			return rc;
 		}
 	} else {
-		atomic_set(&cci_dev->cci_master_info[master].
-						done_pending[queue], 1);
+		atomic_set(
+			&cci_dev->cci_master_info[master].done_pending[queue],
+			1);
 		spin_unlock_irqrestore(
 			&cci_dev->cci_master_info[master].lock_q[queue], flags);
 		rc = cam_cci_wait(cci_dev, master, queue);
@@ -376,9 +379,8 @@
 		CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset);
 	CAM_DBG(CAM_CCI, "CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR %d max %d", read_val,
 		cci_dev->cci_i2c_queue_info[master][queue].max_queue_size);
-	return (cci_dev->
-		cci_i2c_queue_info[master][queue].max_queue_size) -
-		read_val;
+	return ((cci_dev->cci_i2c_queue_info[master][queue].max_queue_size) -
+			read_val);
 }
 
 static void cam_cci_process_half_q(struct cci_device *cci_dev,
@@ -414,8 +416,9 @@
 	spin_lock_irqsave(&cci_dev->cci_master_info[master].lock_q[queue],
 		flags);
 	if (atomic_read(&cci_dev->cci_master_info[master].q_free[queue]) == 1) {
-		atomic_set(&cci_dev->cci_master_info[master].
-						done_pending[queue], 1);
+		atomic_set(
+			&cci_dev->cci_master_info[master].done_pending[queue],
+			1);
 		spin_unlock_irqrestore(
 			&cci_dev->cci_master_info[master].lock_q[queue], flags);
 		rc = cam_cci_wait(cci_dev, master, queue);
@@ -682,8 +685,8 @@
 	spin_unlock_irqrestore(&cci_dev->cci_master_info[master].lock_q[queue],
 		flags);
 
-	max_queue_size = cci_dev->cci_i2c_queue_info[master][queue].
-			max_queue_size;
+	max_queue_size =
+		cci_dev->cci_i2c_queue_info[master][queue].max_queue_size;
 
 	if (c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ)
 		queue_size = max_queue_size;
@@ -993,8 +996,8 @@
 	cam_io_w_mb(val, base + CCI_QUEUE_START_ADDR);
 	CAM_DBG(CAM_CCI, "wait_for_completion_timeout");
 
-	rc = wait_for_completion_timeout(&cci_dev->
-		cci_master_info[master].reset_complete, CCI_TIMEOUT);
+	rc = wait_for_completion_timeout(
+		&cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT);
 	if (rc <= 0) {
 #ifdef DUMP_CCI_REGISTERS
 		cam_cci_dump_registers(cci_dev, master, queue);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c
index 8fb2468..fb37526 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c
@@ -74,14 +74,14 @@
 		if (cci_dev->cci_master_info[MASTER_0].reset_pending == TRUE) {
 			cci_dev->cci_master_info[MASTER_0].reset_pending =
 				FALSE;
-			complete(&cci_dev->cci_master_info[MASTER_0].
-				reset_complete);
+			complete(
+			&cci_dev->cci_master_info[MASTER_0].reset_complete);
 		}
 		if (cci_dev->cci_master_info[MASTER_1].reset_pending == TRUE) {
 			cci_dev->cci_master_info[MASTER_1].reset_pending =
 				FALSE;
-			complete(&cci_dev->cci_master_info[MASTER_1].
-				reset_complete);
+			complete(
+			&cci_dev->cci_master_info[MASTER_1].reset_complete);
 		}
 	}
 	if (irq & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) {
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c
index 14737f9..295259d 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c
@@ -53,11 +53,11 @@
 			mutex_lock(&cci_dev->cci_master_info[master].mutex);
 			flush_workqueue(cci_dev->write_wq[master]);
 			/* Re-initialize the completion */
-			reinit_completion(&cci_dev->
-				cci_master_info[master].reset_complete);
+			reinit_completion(
+			&cci_dev->cci_master_info[master].reset_complete);
 			for (i = 0; i < NUM_QUEUES; i++)
-				reinit_completion(&cci_dev->
-					cci_master_info[master].report_q[i]);
+				reinit_completion(
+				&cci_dev->cci_master_info[master].report_q[i]);
 			/* Set reset pending flag to TRUE */
 			cci_dev->cci_master_info[master].reset_pending = TRUE;
 			/* Set proper mask to RESET CMD address */
@@ -69,8 +69,7 @@
 					base + CCI_RESET_CMD_ADDR);
 			/* wait for reset done irq */
 			rc = wait_for_completion_timeout(
-				&cci_dev->cci_master_info[master].
-				reset_complete,
+			&cci_dev->cci_master_info[master].reset_complete,
 				CCI_TIMEOUT);
 			if (rc <= 0)
 				CAM_ERR(CAM_CCI, "wait failed %d", rc);
@@ -94,8 +93,8 @@
 	/* Re-initialize the completion */
 	reinit_completion(&cci_dev->cci_master_info[master].reset_complete);
 	for (i = 0; i < NUM_QUEUES; i++)
-		reinit_completion(&cci_dev->cci_master_info[master].
-			report_q[i]);
+		reinit_completion(
+			&cci_dev->cci_master_info[master].report_q[i]);
 
 	/* Enable Regulators and IRQ*/
 	rc = cam_soc_util_enable_platform_resource(soc_info, true,
@@ -116,19 +115,15 @@
 	for (i = 0; i < NUM_MASTERS; i++) {
 		for (j = 0; j < NUM_QUEUES; j++) {
 			if (j == QUEUE_0)
-				cci_dev->cci_i2c_queue_info[i][j].
-					max_queue_size =
-						CCI_I2C_QUEUE_0_SIZE;
+				cci_dev->cci_i2c_queue_info[i][j].max_queue_size
+					= CCI_I2C_QUEUE_0_SIZE;
 			else
-				cci_dev->cci_i2c_queue_info[i][j].
-					max_queue_size =
-						CCI_I2C_QUEUE_1_SIZE;
+				cci_dev->cci_i2c_queue_info[i][j].max_queue_size
+					= CCI_I2C_QUEUE_1_SIZE;
 
-			CAM_DBG(CAM_CCI, "CCI Master[%d] :: Q0 : %d Q1 : %d", i
-				, cci_dev->cci_i2c_queue_info[i][j].
-					max_queue_size,
-				cci_dev->cci_i2c_queue_info[i][j].
-					max_queue_size);
+			CAM_DBG(CAM_CCI, "CCI Master[%d] :: Q0 : %d Q1 : %d", i,
+			cci_dev->cci_i2c_queue_info[i][j].max_queue_size,
+			cci_dev->cci_i2c_queue_info[i][j].max_queue_size);
 		}
 	}
 
@@ -191,13 +186,13 @@
 	for (i = 0; i < NUM_MASTERS; i++) {
 		new_cci_dev->cci_master_info[i].status = 0;
 		mutex_init(&new_cci_dev->cci_master_info[i].mutex);
-		init_completion(&new_cci_dev->
-			cci_master_info[i].reset_complete);
+		init_completion(
+			&new_cci_dev->cci_master_info[i].reset_complete);
 
 		for (j = 0; j < NUM_QUEUES; j++) {
 			mutex_init(&new_cci_dev->cci_master_info[i].mutex_q[j]);
-			init_completion(&new_cci_dev->
-				cci_master_info[i].report_q[j]);
+			init_completion(
+				&new_cci_dev->cci_master_info[i].report_q[j]);
 			spin_lock_init(
 				&new_cci_dev->cci_master_info[i].lock_q[j]);
 		}
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
index 4f30f56..e978a40 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
@@ -64,16 +64,14 @@
 
 	for (i = 0; i < size; i++) {
 		cam_io_w_mb(
-			csiphy_dev->ctrl_reg->
-			csiphy_reset_reg[i].reg_data,
+			csiphy_dev->ctrl_reg->csiphy_reset_reg[i].reg_data,
 			base +
-			csiphy_dev->ctrl_reg->
-			csiphy_reset_reg[i].reg_addr);
+			csiphy_dev->ctrl_reg->csiphy_reset_reg[i].reg_addr);
 
 		usleep_range(csiphy_dev->ctrl_reg->
 			csiphy_reset_reg[i].delay * 1000,
-			csiphy_dev->ctrl_reg->
-			csiphy_reset_reg[i].delay * 1000 + 10);
+			csiphy_dev->ctrl_reg->csiphy_reset_reg[i].delay * 1000
+			+ 10);
 	}
 }
 
@@ -150,11 +148,10 @@
 		csiphy_dev->soc_info.reg_map[0].mem_base;
 
 	for (i = 0; i < csiphy_dev->num_irq_registers; i++)
-		cam_io_w_mb(csiphy_dev->ctrl_reg->
-			csiphy_irq_reg[i].reg_data,
+		cam_io_w_mb(
+			csiphy_dev->ctrl_reg->csiphy_irq_reg[i].reg_data,
 			csiphybase +
-			csiphy_dev->ctrl_reg->
-			csiphy_irq_reg[i].reg_addr);
+			csiphy_dev->ctrl_reg->csiphy_irq_reg[i].reg_addr);
 }
 
 void cam_csiphy_cphy_irq_disable(struct csiphy_device *csiphy_dev)
@@ -164,10 +161,8 @@
 		csiphy_dev->soc_info.reg_map[0].mem_base;
 
 	for (i = 0; i < csiphy_dev->num_irq_registers; i++)
-		cam_io_w_mb(0x0,
-			csiphybase +
-			csiphy_dev->ctrl_reg->
-			csiphy_irq_reg[i].reg_addr);
+		cam_io_w_mb(0x0, csiphybase +
+			csiphy_dev->ctrl_reg->csiphy_irq_reg[i].reg_addr);
 }
 
 irqreturn_t cam_csiphy_irq(int irq_num, void *data)
@@ -177,6 +172,7 @@
 	struct csiphy_device *csiphy_dev =
 		(struct csiphy_device *)data;
 	struct cam_hw_soc_info *soc_info = NULL;
+	struct csiphy_reg_parms_t *csiphy_reg = NULL;
 	void __iomem *base = NULL;
 
 	if (!csiphy_dev) {
@@ -186,30 +182,24 @@
 
 	soc_info = &csiphy_dev->soc_info;
 	base =  csiphy_dev->soc_info.reg_map[0].mem_base;
+	csiphy_reg = &csiphy_dev->ctrl_reg->csiphy_reg;
 
 	for (i = 0; i < csiphy_dev->num_irq_registers; i++) {
-		irq = cam_io_r(
-			base +
-			csiphy_dev->ctrl_reg->csiphy_reg.
-			mipi_csiphy_interrupt_status0_addr + 0x4*i);
-		cam_io_w_mb(irq,
-			base +
-			csiphy_dev->ctrl_reg->csiphy_reg.
-			mipi_csiphy_interrupt_clear0_addr + 0x4*i);
+		irq = cam_io_r(base +
+			csiphy_reg->mipi_csiphy_interrupt_status0_addr +
+			(0x4 * i));
+		cam_io_w_mb(irq, base +
+			csiphy_reg->mipi_csiphy_interrupt_clear0_addr +
+			(0x4 * i));
 		CAM_ERR_RATE_LIMIT(CAM_CSIPHY,
 			"CSIPHY%d_IRQ_STATUS_ADDR%d = 0x%x",
 			soc_info->index, i, irq);
-		cam_io_w_mb(0x0,
-			base +
-			csiphy_dev->ctrl_reg->csiphy_reg.
-			mipi_csiphy_interrupt_clear0_addr + 0x4*i);
+		cam_io_w_mb(0x0, base +
+			csiphy_reg->mipi_csiphy_interrupt_clear0_addr +
+			(0x4 * i));
 	}
-	cam_io_w_mb(0x1, base +
-		csiphy_dev->ctrl_reg->
-		csiphy_reg.mipi_csiphy_glbl_irq_cmd_addr);
-	cam_io_w_mb(0x0, base +
-		csiphy_dev->ctrl_reg->
-		csiphy_reg.mipi_csiphy_glbl_irq_cmd_addr);
+	cam_io_w_mb(0x1, base + csiphy_reg->mipi_csiphy_glbl_irq_cmd_addr);
+	cam_io_w_mb(0x0, base + csiphy_reg->mipi_csiphy_glbl_irq_cmd_addr);
 
 	return IRQ_HANDLED;
 }
@@ -222,6 +212,7 @@
 	uint8_t      lane_cnt, lane_pos = 0;
 	uint16_t     settle_cnt = 0;
 	void __iomem *csiphybase;
+	struct csiphy_reg_t *csiphy_common_reg = NULL;
 	struct csiphy_reg_t (*reg_array)[MAX_SETTINGS_PER_LANE];
 
 	lane_cnt = csiphy_dev->csiphy_info.lane_cnt;
@@ -240,8 +231,8 @@
 			reg_array =
 				csiphy_dev->ctrl_reg->csiphy_2ph_reg;
 		csiphy_dev->num_irq_registers = 11;
-		cfg_size = csiphy_dev->ctrl_reg->csiphy_reg.
-			csiphy_2ph_config_array_size;
+		cfg_size =
+		csiphy_dev->ctrl_reg->csiphy_reg.csiphy_2ph_config_array_size;
 
 		lane_mask = csiphy_dev->csiphy_info.lane_mask & 0x1f;
 		for (i = 0; i < MAX_DPHY_DATA_LN; i++) {
@@ -262,8 +253,8 @@
 			reg_array =
 				csiphy_dev->ctrl_reg->csiphy_3ph_reg;
 		csiphy_dev->num_irq_registers = 11;
-		cfg_size = csiphy_dev->ctrl_reg->csiphy_reg.
-			csiphy_3ph_config_array_size;
+		cfg_size =
+		csiphy_dev->ctrl_reg->csiphy_reg.csiphy_3ph_config_array_size;
 
 		lane_mask = csiphy_dev->csiphy_info.lane_mask & 0x7;
 		mask = lane_mask;
@@ -276,32 +267,24 @@
 	}
 
 	size = csiphy_dev->ctrl_reg->csiphy_reg.csiphy_common_array_size;
-
 	for (i = 0; i < size; i++) {
-		switch (csiphy_dev->ctrl_reg->
-			csiphy_common_reg[i].csiphy_param_type) {
-			case CSIPHY_LANE_ENABLE:
+		csiphy_common_reg = &csiphy_dev->ctrl_reg->csiphy_common_reg[i];
+		switch (csiphy_common_reg->csiphy_param_type) {
+		case CSIPHY_LANE_ENABLE:
 				cam_io_w_mb(lane_enable,
 					csiphybase +
-					csiphy_dev->ctrl_reg->
-					csiphy_common_reg[i].reg_addr);
-				usleep_range(csiphy_dev->ctrl_reg->
-					csiphy_common_reg[i].delay*1000,
-					csiphy_dev->ctrl_reg->
-					csiphy_common_reg[i].delay*1000 + 10);
+					csiphy_common_reg->reg_addr);
+				usleep_range(csiphy_common_reg->delay * 1000,
+					csiphy_common_reg->delay * 1000 + 10);
 			break;
-			case CSIPHY_DEFAULT_PARAMS:
-				cam_io_w_mb(csiphy_dev->ctrl_reg->
-					csiphy_common_reg[i].reg_data,
+		case CSIPHY_DEFAULT_PARAMS:
+				cam_io_w_mb(csiphy_common_reg->reg_data,
 					csiphybase +
-					csiphy_dev->ctrl_reg->
-					csiphy_common_reg[i].reg_addr);
-				usleep_range(csiphy_dev->ctrl_reg->
-					csiphy_common_reg[i].delay*1000,
-					csiphy_dev->ctrl_reg->
-					csiphy_common_reg[i].delay*1000 + 10);
+					csiphy_common_reg->reg_addr);
+				usleep_range(csiphy_common_reg->delay * 1000,
+					csiphy_common_reg->delay * 1000 + 10);
 			break;
-			default:
+		default:
 			break;
 		}
 	}
@@ -317,8 +300,8 @@
 		if (csiphy_dev->csiphy_info.combo_mode == 1 &&
 			(lane_pos >= 3))
 			settle_cnt =
-				(csiphy_dev->csiphy_info.
-				settle_time_combo_sensor / 200000000);
+			(csiphy_dev->csiphy_info.settle_time_combo_sensor /
+				200000000);
 		for (i = 0; i < cfg_size; i++) {
 			switch (reg_array[lane_pos][i].csiphy_param_type) {
 			case CSIPHY_LANE_ENABLE:
@@ -400,6 +383,7 @@
 	csiphy_dev->ref_count = 0;
 	csiphy_dev->is_acquired_dev_combo_mode = 0;
 	csiphy_dev->acquire_count = 0;
+	csiphy_dev->start_dev_count = 0;
 	csiphy_dev->csiphy_state = CAM_CSIPHY_INIT;
 }
 
@@ -445,6 +429,7 @@
 {
 	struct csiphy_device *csiphy_dev =
 		(struct csiphy_device *)phy_dev;
+	struct intf_params   *bridge_intf = NULL;
 	struct cam_control   *cmd = (struct cam_control *)arg;
 	int32_t              rc = 0;
 
@@ -523,11 +508,10 @@
 
 		csiphy_acq_dev.device_handle =
 			cam_create_device_hdl(&bridge_params);
-		csiphy_dev->bridge_intf.
-			device_hdl[csiphy_acq_params.combo_mode] =
-				csiphy_acq_dev.device_handle;
-		csiphy_dev->bridge_intf.
-			session_hdl[csiphy_acq_params.combo_mode] =
+		bridge_intf = &csiphy_dev->bridge_intf;
+		bridge_intf->device_hdl[csiphy_acq_params.combo_mode]
+			= csiphy_acq_dev.device_handle;
+		bridge_intf->session_hdl[csiphy_acq_params.combo_mode] =
 			csiphy_acq_dev.session_handle;
 
 		if (copy_to_user((void __user *)cmd->handle,
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
index e7110b8..9b74826 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_flash/cam_flash_core.c
@@ -284,8 +284,8 @@
 			for (i = 0; i < flash_data->cmn_attr.count; i++)
 				flash_data->led_current_ma[i] = 0;
 		} else {
-			fctrl->flash_init_setting.cmn_attr.
-				is_settings_valid = false;
+			fctrl->flash_init_setting.cmn_attr.is_settings_valid
+				= false;
 		}
 	} else {
 		for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
@@ -513,7 +513,7 @@
 	uint64_t generic_ptr;
 	uint32_t *cmd_buf =  NULL;
 	uint32_t *offset = NULL;
-	uint32_t frame_offset = 0;
+	uint32_t frm_offset = 0;
 	size_t len_of_buffer;
 	struct cam_control *ioctl_ctrl = NULL;
 	struct cam_packet *csl_packet = NULL;
@@ -525,6 +525,7 @@
 	struct cam_flash_set_rer *flash_rer_info = NULL;
 	struct cam_flash_set_on_off *flash_operation_info = NULL;
 	struct cam_flash_query_curr *flash_query_info = NULL;
+	struct cam_flash_frame_setting *flash_data = NULL;
 
 	if (!fctrl || !arg) {
 		CAM_ERR(CAM_FLASH, "fctrl/arg is NULL");
@@ -616,25 +617,19 @@
 	case CAM_FLASH_PACKET_OPCODE_SET_OPS: {
 		offset = (uint32_t *)((uint8_t *)&csl_packet->payload +
 			csl_packet->cmd_buf_offset);
-		frame_offset = csl_packet->header.request_id %
+		frm_offset = csl_packet->header.request_id %
 			MAX_PER_FRAME_ARRAY;
-		if (fctrl->per_frame[frame_offset].cmn_attr.is_settings_valid
-			== true) {
-			fctrl->per_frame[frame_offset].cmn_attr.request_id = 0;
-			fctrl->per_frame[frame_offset].
-				cmn_attr.is_settings_valid = false;
-			for (i = 0;
-			i < fctrl->per_frame[frame_offset].cmn_attr.count;
-			i++) {
-				fctrl->per_frame[frame_offset].
-					led_current_ma[i] = 0;
-			}
+		flash_data = &fctrl->per_frame[frm_offset];
+
+		if (flash_data->cmn_attr.is_settings_valid == true) {
+			flash_data->cmn_attr.request_id = 0;
+			flash_data->cmn_attr.is_settings_valid = false;
+			for (i = 0; i < flash_data->cmn_attr.count; i++)
+				flash_data->led_current_ma[i] = 0;
 		}
 
-		fctrl->per_frame[frame_offset].cmn_attr.request_id =
-			csl_packet->header.request_id;
-		fctrl->per_frame[frame_offset].cmn_attr.is_settings_valid =
-			true;
+		flash_data->cmn_attr.request_id = csl_packet->header.request_id;
+		flash_data->cmn_attr.is_settings_valid = true;
 		cmd_desc = (struct cam_cmd_buf_desc *)(offset);
 		rc = cam_mem_get_cpu_buf(cmd_desc->mem_handle,
 			(uint64_t *)&generic_ptr, &len_of_buffer);
@@ -655,8 +650,7 @@
 					CAM_FLASH_STATE_ACQUIRE)) {
 				CAM_WARN(CAM_FLASH,
 					"Rxed Flash fire ops without linking");
-				fctrl->per_frame[frame_offset].
-					cmn_attr.is_settings_valid = false;
+				flash_data->cmn_attr.is_settings_valid = false;
 				return 0;
 			}
 
@@ -668,16 +662,12 @@
 				return -EINVAL;
 			}
 
-			fctrl->per_frame[frame_offset].opcode =
-				flash_operation_info->opcode;
-			fctrl->per_frame[frame_offset].cmn_attr.count =
+			flash_data->opcode = flash_operation_info->opcode;
+			flash_data->cmn_attr.count =
 				flash_operation_info->count;
-			for (i = 0;
-				i < flash_operation_info->count; i++)
-				fctrl->per_frame[frame_offset].
-					led_current_ma[i]
-					= flash_operation_info->
-					led_current_ma[i];
+			for (i = 0; i < flash_operation_info->count; i++)
+				flash_data->led_current_ma[i]
+				= flash_operation_info->led_current_ma[i];
 			}
 			break;
 		default:
@@ -782,8 +772,10 @@
 			(fctrl->flash_state == CAM_FLASH_STATE_ACQUIRE)) {
 			CAM_WARN(CAM_FLASH,
 				"Rxed NOP packets without linking");
-			fctrl->per_frame[frame_offset].
-				cmn_attr.is_settings_valid = false;
+			frm_offset = csl_packet->header.request_id %
+				MAX_PER_FRAME_ARRAY;
+			fctrl->per_frame[frm_offset].cmn_attr.is_settings_valid
+				= false;
 			return 0;
 		}
 
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c
index 3a0a6d6..fbdaee7 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_core.c
@@ -233,17 +233,13 @@
 			size = i2c_list->i2c_settings.size;
 			for (i = 0; i < size; i++) {
 				rc = camera_io_dev_poll(
-					&(o_ctrl->io_master_info),
-					i2c_list->i2c_settings.
-						reg_setting[i].reg_addr,
-					i2c_list->i2c_settings.
-						reg_setting[i].reg_data,
-					i2c_list->i2c_settings.
-						reg_setting[i].data_mask,
-					i2c_list->i2c_settings.addr_type,
-					i2c_list->i2c_settings.data_type,
-					i2c_list->i2c_settings.
-						reg_setting[i].delay);
+				&(o_ctrl->io_master_info),
+				i2c_list->i2c_settings.reg_setting[i].reg_addr,
+				i2c_list->i2c_settings.reg_setting[i].reg_data,
+				i2c_list->i2c_settings.reg_setting[i].data_mask,
+				i2c_list->i2c_settings.addr_type,
+				i2c_list->i2c_settings.data_type,
+				i2c_list->i2c_settings.reg_setting[i].delay);
 				if (rc < 0) {
 					CAM_ERR(CAM_OIS,
 						"i2c poll apply setting Fail");
@@ -529,8 +525,8 @@
 					return rc;
 				}
 			} else if ((o_ctrl->is_ois_calib != 0) &&
-				(o_ctrl->i2c_calib_data.
-					is_settings_valid == 0)) {
+				(o_ctrl->i2c_calib_data.is_settings_valid ==
+				0)) {
 				CAM_DBG(CAM_OIS,
 					"Received calib settings");
 				i2c_reg_settings = &(o_ctrl->i2c_calib_data);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
index 5a1b67c..b3f3a35 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor/cam_sensor_core.c
@@ -190,9 +190,8 @@
 		}
 
 		i2c_reg_settings =
-			&i2c_data->
-			per_frame[csl_packet->header.request_id %
-			MAX_PER_FRAME_ARRAY];
+			&i2c_data->per_frame[csl_packet->header.request_id %
+				MAX_PER_FRAME_ARRAY];
 		CAM_DBG(CAM_SENSOR, "Received Packet: %lld req: %lld",
 			csl_packet->header.request_id % MAX_PER_FRAME_ARRAY,
 			csl_packet->header.request_id);
@@ -290,16 +289,12 @@
 		for (i = 0; i < size; i++) {
 			rc = camera_io_dev_poll(
 			io_master_info,
-			i2c_list->i2c_settings.
-				reg_setting[i].reg_addr,
-			i2c_list->i2c_settings.
-				reg_setting[i].reg_data,
-			i2c_list->i2c_settings.
-				reg_setting[i].data_mask,
+			i2c_list->i2c_settings.reg_setting[i].reg_addr,
+			i2c_list->i2c_settings.reg_setting[i].reg_data,
+			i2c_list->i2c_settings.reg_setting[i].data_mask,
 			i2c_list->i2c_settings.addr_type,
-				i2c_list->i2c_settings.data_type,
-			i2c_list->i2c_settings.
-				reg_setting[i].delay);
+			i2c_list->i2c_settings.data_type,
+			i2c_list->i2c_settings.reg_setting[i].delay);
 			if (rc < 0) {
 				CAM_ERR(CAM_SENSOR,
 					"i2c poll apply setting Fail: %d", rc);
@@ -1104,9 +1099,9 @@
 
 		for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
 			if ((del_req_id >
-				 s_ctrl->i2c_data.per_frame[i].request_id) &&
-				(s_ctrl->i2c_data.per_frame[i].
-					is_settings_valid == 1)) {
+				 s_ctrl->i2c_data.per_frame[i].request_id) && (
+				 s_ctrl->i2c_data.per_frame[i].is_settings_valid
+					== 1)) {
 				s_ctrl->i2c_data.per_frame[i].request_id = 0;
 				rc = delete_request(
 					&(s_ctrl->i2c_data.per_frame[i]));
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
index f9b846b..ac60dc8 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
@@ -93,12 +93,10 @@
 			list_entry(list_ptr, struct i2c_settings_list, list);
 		if (generic_op_code ==
 			CAMERA_SENSOR_WAIT_OP_HW_UCND)
-			i2c_list->i2c_settings.
-				reg_setting[offset - 1].delay =
+			i2c_list->i2c_settings.reg_setting[offset - 1].delay =
 				cmd_uncond_wait->delay;
 		else
-			i2c_list->i2c_settings.delay =
-				cmd_uncond_wait->delay;
+			i2c_list->i2c_settings.delay = cmd_uncond_wait->delay;
 		(*cmd_buf) +=
 			sizeof(
 			struct cam_cmd_unconditional_wait) / sizeof(uint32_t);
@@ -182,14 +180,10 @@
 	for (cnt = 0; cnt < (cam_cmd_i2c_random_wr->header.count);
 		cnt++) {
 		i2c_list->i2c_settings.reg_setting[cnt].reg_addr =
-			cam_cmd_i2c_random_wr->
-			random_wr_payload[cnt].reg_addr;
-		i2c_list->i2c_settings.
-			reg_setting[cnt].reg_data =
-			cam_cmd_i2c_random_wr->
-			random_wr_payload[cnt].reg_data;
-		i2c_list->i2c_settings.
-			reg_setting[cnt].data_mask = 0;
+			cam_cmd_i2c_random_wr->random_wr_payload[cnt].reg_addr;
+		i2c_list->i2c_settings.reg_setting[cnt].reg_data =
+			cam_cmd_i2c_random_wr->random_wr_payload[cnt].reg_data;
+		i2c_list->i2c_settings.reg_setting[cnt].data_mask = 0;
 	}
 	*offset = cnt;
 	*list = &(i2c_list->list);
@@ -237,14 +231,10 @@
 	for (cnt = 0; cnt < (cam_cmd_i2c_continuous_wr->header.count);
 		cnt++) {
 		i2c_list->i2c_settings.reg_setting[cnt].reg_addr =
-			cam_cmd_i2c_continuous_wr->
-			reg_addr;
-		i2c_list->i2c_settings.
-			reg_setting[cnt].reg_data =
-			cam_cmd_i2c_continuous_wr->
-			data_read[cnt].reg_data;
-		i2c_list->i2c_settings.
-			reg_setting[cnt].data_mask = 0;
+			cam_cmd_i2c_continuous_wr->reg_addr;
+		i2c_list->i2c_settings.reg_setting[cnt].reg_data =
+			cam_cmd_i2c_continuous_wr->data_read[cnt].reg_data;
+		i2c_list->i2c_settings.reg_setting[cnt].data_mask = 0;
 	}
 	*offset = cnt;
 	*list = &(i2c_list->list);
@@ -642,6 +632,7 @@
 {
 	int32_t rc = 0, tot_size = 0, last_cmd_type = 0;
 	int32_t i = 0, pwr_up = 0, pwr_down = 0;
+	struct cam_sensor_power_setting *pwr_settings;
 	void *ptr = cmd_buf, *scr;
 	struct cam_cmd_power *pwr_cmd = (struct cam_cmd_power *)cmd_buf;
 	struct common_header *cmm_hdr = (struct common_header *)cmd_buf;
@@ -684,14 +675,10 @@
 				CAM_WARN(CAM_SENSOR, "Un expected Command");
 
 			for (i = 0; i < pwr_cmd->count; i++, pwr_up++) {
-				power_info->
-					power_setting[pwr_up].seq_type =
-					pwr_cmd->power_settings[i].
-						power_seq_type;
-				power_info->
-					power_setting[pwr_up].config_val =
-					pwr_cmd->power_settings[i].
-						config_val_low;
+				power_info->power_setting[pwr_up].seq_type =
+				pwr_cmd->power_settings[i].power_seq_type;
+				power_info->power_setting[pwr_up].config_val =
+				pwr_cmd->power_settings[i].config_val_low;
 				power_info->power_setting[pwr_up].delay = 0;
 				if (i) {
 					scr = scr +
@@ -708,13 +695,9 @@
 					goto free_power_down_settings;
 				}
 				CAM_DBG(CAM_SENSOR,
-					"Seq Type[%d]: %d Config_val: %ld",
-					pwr_up,
-					power_info->
-						power_setting[pwr_up].seq_type,
-					power_info->
-						power_setting[pwr_up].
-						config_val);
+				"Seq Type[%d]: %d Config_val: %ld", pwr_up,
+				power_info->power_setting[pwr_up].seq_type,
+				power_info->power_setting[pwr_up].config_val);
 			}
 			last_cmd_type = CAMERA_SENSOR_CMD_TYPE_PWR_UP;
 			ptr = (void *) scr;
@@ -722,32 +705,38 @@
 		} else if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_WAIT) {
 			struct cam_cmd_unconditional_wait *wait_cmd =
 				(struct cam_cmd_unconditional_wait *)ptr;
-			if (wait_cmd->op_code ==
-				CAMERA_SENSOR_WAIT_OP_SW_UCND) {
-				if (last_cmd_type ==
-					CAMERA_SENSOR_CMD_TYPE_PWR_UP) {
-					if (pwr_up > 0)
-						power_info->
-							power_setting
-							[pwr_up - 1].delay +=
-							wait_cmd->delay;
-					else
-						CAM_ERR(CAM_SENSOR,
-							"Delay is expected only after valid power up setting");
-				} else if (last_cmd_type ==
-					CAMERA_SENSOR_CMD_TYPE_PWR_DOWN) {
-					if (pwr_down > 0)
-						power_info->
-							power_down_setting
-							[pwr_down - 1].delay +=
-							wait_cmd->delay;
-					else
-						CAM_ERR(CAM_SENSOR,
-							"Delay is expected only after valid power up setting");
+			if ((wait_cmd->op_code ==
+				CAMERA_SENSOR_WAIT_OP_SW_UCND) &&
+				(last_cmd_type ==
+				CAMERA_SENSOR_CMD_TYPE_PWR_UP)) {
+				if (pwr_up > 0) {
+					pwr_settings =
+					&power_info->power_setting[pwr_up - 1];
+					pwr_settings->delay +=
+						wait_cmd->delay;
+				} else {
+					CAM_ERR(CAM_SENSOR,
+					"Delay is expected only after valid power up setting");
 				}
-			} else
+			} else if ((wait_cmd->op_code ==
+				CAMERA_SENSOR_WAIT_OP_SW_UCND) &&
+				(last_cmd_type ==
+				CAMERA_SENSOR_CMD_TYPE_PWR_DOWN)) {
+				if (pwr_down > 0) {
+					pwr_settings =
+					&power_info->power_down_setting[
+						pwr_down - 1];
+					pwr_settings->delay +=
+						wait_cmd->delay;
+				} else {
+					CAM_ERR(CAM_SENSOR,
+					"Delay is expected only after valid power up setting");
+				}
+			} else {
 				CAM_DBG(CAM_SENSOR, "Invalid op code: %d",
 					wait_cmd->op_code);
+			}
+
 			tot_size = tot_size +
 				sizeof(struct cam_cmd_unconditional_wait);
 			if (tot_size > cmd_length) {
@@ -776,18 +765,14 @@
 				CAM_ERR(CAM_SENSOR, "Invalid Command");
 
 			for (i = 0; i < pwr_cmd->count; i++, pwr_down++) {
-				power_info->
-					power_down_setting[pwr_down].
-					seq_type =
-					pwr_cmd->power_settings[i].
-					power_seq_type;
-				power_info->
-					power_down_setting[pwr_down].
-					config_val =
-					pwr_cmd->power_settings[i].
-					config_val_low;
-				power_info->
-					power_down_setting[pwr_down].delay = 0;
+				pwr_settings =
+				&power_info->power_down_setting[pwr_down];
+				pwr_settings->seq_type =
+				pwr_cmd->power_settings[i].power_seq_type;
+				pwr_settings->config_val =
+				pwr_cmd->power_settings[i].config_val_low;
+				power_info->power_down_setting[pwr_down].delay
+					= 0;
 				if (i) {
 					scr = scr +
 						sizeof(
@@ -805,13 +790,8 @@
 				}
 				CAM_DBG(CAM_SENSOR,
 					"Seq Type[%d]: %d Config_val: %ld",
-					pwr_down,
-					power_info->
-						power_down_setting[pwr_down].
-						seq_type,
-					power_info->
-						power_down_setting[pwr_down].
-						config_val);
+					pwr_down, pwr_settings->seq_type,
+					pwr_settings->config_val);
 			}
 			last_cmd_type = CAMERA_SENSOR_CMD_TYPE_PWR_DOWN;
 			ptr = (void *) scr;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
index fda45cb..691b492 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -26,6 +26,7 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-device.h>
 #include <media/videobuf2-core.h>
+#include <media/msmb_generic_buf_mgr.h>
 
 #include "msm.h"
 #include "msm_buf_mgr.h"
diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
index e350096..e458b4df 100644
--- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
@@ -167,6 +167,33 @@
 	return ret;
 }
 
+static int32_t msm_buf_mngr_buf_error(struct msm_buf_mngr_device *buf_mngr_dev,
+	struct msm_buf_mngr_info *buf_info)
+{
+	unsigned long flags;
+	struct msm_get_bufs *bufs, *save;
+	int32_t ret = -EINVAL;
+
+	spin_lock_irqsave(&buf_mngr_dev->buf_q_spinlock, flags);
+	list_for_each_entry_safe(bufs, save, &buf_mngr_dev->buf_qhead, entry) {
+		if ((bufs->session_id == buf_info->session_id) &&
+			(bufs->stream_id == buf_info->stream_id) &&
+			(bufs->index == buf_info->index)) {
+			ret = buf_mngr_dev->vb2_ops.buf_error
+					(bufs->vb2_v4l2_buf,
+						buf_info->session_id,
+						buf_info->stream_id,
+						buf_info->frame_id,
+						&buf_info->timestamp,
+						buf_info->reserved);
+			list_del_init(&bufs->entry);
+			kfree(bufs);
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&buf_mngr_dev->buf_q_spinlock, flags);
+	return ret;
+}
 
 static int32_t msm_buf_mngr_put_buf(struct msm_buf_mngr_device *buf_mngr_dev,
 	struct msm_buf_mngr_info *buf_info)
@@ -478,6 +505,9 @@
 	case VIDIOC_MSM_BUF_MNGR_BUF_DONE:
 		rc = msm_buf_mngr_buf_done(msm_buf_mngr_dev, argp);
 		break;
+	case VIDIOC_MSM_BUF_MNGR_BUF_ERROR:
+		rc = msm_buf_mngr_buf_error(msm_buf_mngr_dev, argp);
+		break;
 	case VIDIOC_MSM_BUF_MNGR_PUT_BUF:
 		rc = msm_buf_mngr_put_buf(msm_buf_mngr_dev, argp);
 		break;
@@ -576,6 +606,7 @@
 	case VIDIOC_MSM_BUF_MNGR_GET_BUF:
 	case VIDIOC_MSM_BUF_MNGR_BUF_DONE:
 	case VIDIOC_MSM_BUF_MNGR_PUT_BUF:
+	case VIDIOC_MSM_BUF_MNGR_BUF_ERROR:
 		rc = msm_cam_buf_mgr_ops(cmd, argp);
 		break;
 	case VIDIOC_MSM_BUF_MNGR_INIT:
@@ -724,6 +755,9 @@
 	case VIDIOC_MSM_BUF_MNGR_BUF_DONE32:
 		cmd = VIDIOC_MSM_BUF_MNGR_BUF_DONE;
 		break;
+	case VIDIOC_MSM_BUF_MNGR_BUF_ERROR32:
+		cmd = VIDIOC_MSM_BUF_MNGR_BUF_ERROR;
+		break;
 	case VIDIOC_MSM_BUF_MNGR_PUT_BUF32:
 		cmd = VIDIOC_MSM_BUF_MNGR_PUT_BUF;
 		break;
@@ -742,6 +776,7 @@
 	switch (cmd) {
 	case VIDIOC_MSM_BUF_MNGR_GET_BUF:
 	case VIDIOC_MSM_BUF_MNGR_BUF_DONE:
+	case VIDIOC_MSM_BUF_MNGR_BUF_ERROR:
 	case VIDIOC_MSM_BUF_MNGR_FLUSH:
 	case VIDIOC_MSM_BUF_MNGR_PUT_BUF: {
 		struct msm_buf_mngr_info32_t buf_info32;
diff --git a/drivers/media/platform/msm/camera_v2/msm_sd.h b/drivers/media/platform/msm/camera_v2/msm_sd.h
index f45c0d7..64cb785 100644
--- a/drivers/media/platform/msm/camera_v2/msm_sd.h
+++ b/drivers/media/platform/msm/camera_v2/msm_sd.h
@@ -81,6 +81,9 @@
 		unsigned int stream_id, uint32_t sequence, struct timeval *ts,
 		uint32_t reserved);
 	int (*flush_buf)(int session_id, unsigned int stream_id);
+	int (*buf_error)(struct vb2_v4l2_buffer *vb2_v4l2_buf, int session_id,
+		unsigned int stream_id, uint32_t sequence, struct timeval *ts,
+		uint32_t reserved);
 };
 
 #define MSM_SD_NOTIFY_GET_SD 0x00000001
diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
index 87e0172..6e528a6 100644
--- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
@@ -461,6 +461,69 @@
 	return rc;
 }
 
+static int msm_vb2_buf_error(struct vb2_v4l2_buffer *vb, int session_id,
+				unsigned int stream_id, uint32_t sequence,
+				struct timeval *ts, uint32_t buf_type)
+{
+	unsigned long flags, rl_flags;
+	struct msm_vb2_buffer *msm_vb2;
+	struct msm_stream *stream;
+	struct msm_session *session;
+	struct vb2_v4l2_buffer *vb2_v4l2_buf = NULL;
+	int rc = 0;
+
+	session = msm_get_session(session_id);
+	if (IS_ERR_OR_NULL(session))
+		return -EINVAL;
+
+	read_lock_irqsave(&session->stream_rwlock, rl_flags);
+
+	stream = msm_get_stream(session, stream_id);
+	if (IS_ERR_OR_NULL(stream)) {
+		read_unlock_irqrestore(&session->stream_rwlock, rl_flags);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&stream->stream_lock, flags);
+	if (vb) {
+		list_for_each_entry(msm_vb2, &(stream->queued_list), list) {
+			vb2_v4l2_buf = &(msm_vb2->vb2_v4l2_buf);
+			if (vb2_v4l2_buf == vb)
+				break;
+		}
+		if (vb2_v4l2_buf != vb) {
+			pr_err("VB buffer is INVALID ses_id=%d, str_id=%d, vb=%pK\n",
+				    session_id, stream_id, vb);
+			spin_unlock_irqrestore(&stream->stream_lock, flags);
+			read_unlock_irqrestore(&session->stream_rwlock,
+				rl_flags);
+			return -EINVAL;
+		}
+		msm_vb2 =
+			container_of(vb2_v4l2_buf, struct msm_vb2_buffer,
+				vb2_v4l2_buf);
+		/* put buf before buf done */
+		if (msm_vb2->in_freeq) {
+			vb2_v4l2_buf->sequence = sequence;
+			vb2_v4l2_buf->timecode.type = buf_type;
+			vb2_v4l2_buf->vb2_buf.timestamp =
+				(ts->tv_sec * 1000000 + ts->tv_usec) * 1000;
+			vb2_buffer_done(&vb2_v4l2_buf->vb2_buf,
+				VB2_BUF_STATE_ERROR);
+			msm_vb2->in_freeq = 0;
+			rc = 0;
+		} else
+			rc = -EINVAL;
+	} else {
+		pr_err(" VB buffer is NULL for ses_id=%d, str_id=%d\n",
+			    session_id, stream_id);
+		rc = -EINVAL;
+	}
+	spin_unlock_irqrestore(&stream->stream_lock, flags);
+	read_unlock_irqrestore(&session->stream_rwlock, rl_flags);
+	return rc;
+}
+
 long msm_vb2_return_buf_by_idx(int session_id, unsigned int stream_id,
 				uint32_t index)
 {
@@ -559,6 +622,7 @@
 	req->put_buf = msm_vb2_put_buf;
 	req->buf_done = msm_vb2_buf_done;
 	req->flush_buf = msm_vb2_flush_buf;
+	req->buf_error = msm_vb2_buf_error;
 	return 0;
 }
 
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index 70bb3f2..1ad2f257 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -1617,6 +1617,7 @@
 	case VIDIOC_MSM_BUF_MNGR_PUT_BUF:
 	case VIDIOC_MSM_BUF_MNGR_BUF_DONE:
 	case VIDIOC_MSM_BUF_MNGR_GET_BUF:
+	case VIDIOC_MSM_BUF_MNGR_BUF_ERROR:
 	default: {
 		struct msm_buf_mngr_info *buff_mgr_info =
 			(struct msm_buf_mngr_info *)arg;
@@ -3604,7 +3605,7 @@
 			break;
 		}
 		buff_mgr_info.frame_id = frame_info.frame_id;
-		rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_BUF_DONE,
+		rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_BUF_ERROR,
 			0x0, &buff_mgr_info);
 		if (rc < 0) {
 			pr_err("error in buf done\n");
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index cef5396..97f5ca2 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -1501,6 +1501,8 @@
 		data_done.output_done.timestamp_hi = pkt->time_stamp_hi;
 		data_done.output_done.timestamp_lo = pkt->time_stamp_lo;
 		data_done.output_done.flags1 = pkt->flags;
+		data_done.output_done.input_tag = pkt->input_tag;
+		data_done.output_done.output_tag = pkt->output_tag;
 		data_done.output_done.mark_target = pkt->mark_target;
 		data_done.output_done.mark_data = pkt->mark_data;
 		data_done.output_done.stats = pkt->stats;
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 192f36f2..3d29ed4 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -499,3 +499,25 @@
 endif # V4L_RADIO_ISA_DRIVERS
 
 endif # RADIO_ADAPTERS
+
+config RADIO_IRIS
+        tristate "QTI IRIS FM support"
+        depends on VIDEO_V4L2
+        ---help---
+          Say Y here if you want to use the QTI FM chip (IRIS).
+          This FM chip uses SMD interface
+
+          To compile this driver as a module, choose M here: the
+          module will be called radio-iris.
+
+
+config RADIO_IRIS_TRANSPORT
+        tristate "QTI IRIS Transport"
+        depends on RADIO_IRIS
+        ---help---
+          Say Y here if you want to use the QTI FM chip (IRIS).
+          with SMD as transport.
+
+          To compile this driver as a module, choose M here: the
+          module will be called radio-iris-transport.
+
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 120e791..efda39b 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -33,6 +33,8 @@
 obj-$(CONFIG_RADIO_WL128X) += wl128x/
 obj-$(CONFIG_RADIO_TEA575X) += tea575x.o
 obj-$(CONFIG_USB_RAREMONO) += radio-raremono.o
+obj-$(CONFIG_RADIO_IRIS) += radio-iris.o
+obj-$(CONFIG_RADIO_IRIS_TRANSPORT) += radio-iris-transport.o
 
 shark2-objs := radio-shark2.o radio-tea5777.o
 
diff --git a/drivers/media/radio/radio-iris-transport.c b/drivers/media/radio/radio-iris-transport.c
new file mode 100644
index 0000000..98afd19
--- /dev/null
+++ b/drivers/media/radio/radio-iris-transport.c
@@ -0,0 +1,274 @@
+/*
+ *  QTI's FM Shared Memory Transport Driver
+ *
+ *  FM HCI_SMD ( FM HCI Shared Memory Driver) is QTI's Shared memory driver
+ *  for the HCI protocol. This file is based on drivers/bluetooth/hci_vhci.c
+ *
+ *  Copyright (c) 2000-2001, 2011-2012, 2014-2015 The Linux Foundation.
+ *  All rights reserved.
+ *
+ *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
+ *  Copyright (C) 2004-2006  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as 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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/skbuff.h>
+#include <linux/workqueue.h>
+#include <soc/qcom/smd.h>
+#include <media/radio-iris.h>
+#include <linux/uaccess.h>
+
+struct radio_data {
+	struct radio_hci_dev *hdev;
+	struct tasklet_struct   rx_task;
+	struct smd_channel  *fm_channel;
+};
+struct radio_data hs;
+DEFINE_MUTEX(fm_smd_enable);
+static int fmsmd_set;
+static bool chan_opened;
+static int hcismd_fm_set_enable(const char *val, struct kernel_param *kp);
+module_param_call(fmsmd_set, hcismd_fm_set_enable, NULL, &fmsmd_set, 0644);
+static struct work_struct *reset_worker;
+static void radio_hci_smd_deregister(void);
+static void radio_hci_smd_exit(void);
+
+static void radio_hci_smd_destruct(struct radio_hci_dev *hdev)
+{
+	radio_hci_unregister_dev();
+}
+
+
+static void radio_hci_smd_recv_event(unsigned long temp)
+{
+	int len;
+	int rc;
+	struct sk_buff *skb;
+	unsigned  char *buf;
+	struct radio_data *hsmd = &hs;
+
+	len = smd_read_avail(hsmd->fm_channel);
+
+	while (len) {
+		skb = alloc_skb(len, GFP_ATOMIC);
+		if (!skb) {
+			FMDERR("Memory not allocated for the socket\n");
+			return;
+		}
+
+		buf = kmalloc(len, GFP_ATOMIC);
+		if (!buf) {
+			kfree_skb(skb);
+			return;
+		}
+
+		rc = smd_read(hsmd->fm_channel, (void *)buf, len);
+
+		memcpy(skb_put(skb, len), buf, len);
+
+		skb_orphan(skb);
+		skb->dev = (struct net_device   *)hs.hdev;
+
+		rc = radio_hci_recv_frame(skb);
+
+		kfree(buf);
+		len = smd_read_avail(hsmd->fm_channel);
+	}
+}
+
+static int radio_hci_smd_send_frame(struct sk_buff *skb)
+{
+	int len = 0;
+
+	FMDBG("skb %pK\n", skb);
+
+	len = smd_write(hs.fm_channel, skb->data, skb->len);
+	if (len < skb->len) {
+		FMDERR("Failed to write Data %d\n", len);
+		kfree_skb(skb);
+		return -ENODEV;
+	}
+	kfree_skb(skb);
+	return 0;
+}
+
+
+static void send_disable_event(struct work_struct *worker)
+{
+	struct sk_buff *skb;
+	unsigned char buf[6] = { 0x0f, 0x04, 0x01, 0x02, 0x4c, 0x00 };
+	int len = sizeof(buf);
+
+	skb = alloc_skb(len, GFP_ATOMIC);
+	if (!skb) {
+		FMDERR("Memory not allocated for the socket\n");
+		kfree(worker);
+		return;
+	}
+
+	FMDBG("FM INSERT DISABLE Rx Event\n");
+
+	memcpy(skb_put(skb, len), buf, len);
+
+	skb_orphan(skb);
+	skb->dev = (struct net_device   *)hs.hdev;
+
+	radio_hci_recv_frame(skb);
+	kfree(worker);
+}
+
+static void radio_hci_smd_notify_cmd(void *data, unsigned int event)
+{
+	struct radio_hci_dev *hdev = (struct radio_hci_dev *)data;
+
+	FMDBG("data %p event %u\n", data, event);
+
+	if (!hdev) {
+		FMDERR("Frame for unknown HCI device (hdev=NULL)\n");
+		return;
+	}
+
+	switch (event) {
+	case SMD_EVENT_DATA:
+		tasklet_schedule(&hs.rx_task);
+		break;
+	case SMD_EVENT_OPEN:
+		break;
+	case SMD_EVENT_CLOSE:
+		reset_worker = kzalloc(sizeof(*reset_worker), GFP_ATOMIC);
+		if (reset_worker) {
+			INIT_WORK(reset_worker, send_disable_event);
+			schedule_work(reset_worker);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+static int radio_hci_smd_register_dev(struct radio_data *hsmd)
+{
+	struct radio_hci_dev *hdev;
+	int rc;
+
+	FMDBG("hsmd: %pK\n", hsmd);
+
+	if (hsmd == NULL)
+		return -ENODEV;
+
+	hdev = kmalloc(sizeof(struct radio_hci_dev), GFP_KERNEL);
+	if (hdev == NULL)
+		return -ENODEV;
+
+	tasklet_init(&hsmd->rx_task, radio_hci_smd_recv_event,
+		(unsigned long) hsmd);
+	hdev->send  = radio_hci_smd_send_frame;
+	hdev->destruct = radio_hci_smd_destruct;
+	hdev->close_smd = radio_hci_smd_exit;
+
+	/* Open the SMD Channel and device and register the callback function */
+	rc = smd_named_open_on_edge("APPS_FM", SMD_APPS_WCNSS,
+		&hsmd->fm_channel, hdev, radio_hci_smd_notify_cmd);
+
+	if (rc < 0) {
+		FMDERR("Cannot open the command channel\n");
+		hsmd->hdev = NULL;
+		kfree(hdev);
+		return -ENODEV;
+	}
+
+	smd_disable_read_intr(hsmd->fm_channel);
+
+	if (radio_hci_register_dev(hdev) < 0) {
+		FMDERR("Can't register HCI device\n");
+		smd_close(hsmd->fm_channel);
+		hsmd->hdev = NULL;
+		kfree(hdev);
+		return -ENODEV;
+	}
+
+	hsmd->hdev = hdev;
+	return 0;
+}
+
+static void radio_hci_smd_deregister(void)
+{
+	radio_hci_unregister_dev();
+	kfree(hs.hdev);
+	hs.hdev = NULL;
+
+	smd_close(hs.fm_channel);
+	hs.fm_channel = 0;
+	fmsmd_set = 0;
+}
+
+static int radio_hci_smd_init(void)
+{
+	int ret;
+
+	if (chan_opened) {
+		FMDBG("Channel is already opened\n");
+		return 0;
+	}
+
+	/* this should be called with fm_smd_enable lock held */
+	ret = radio_hci_smd_register_dev(&hs);
+	if (ret < 0) {
+		FMDERR("Failed to register smd device\n");
+		chan_opened = false;
+		return ret;
+	}
+	chan_opened = true;
+	return ret;
+}
+
+static void radio_hci_smd_exit(void)
+{
+	if (!chan_opened) {
+		FMDBG("Channel already closed\n");
+		return;
+	}
+
+	/* this should be called with fm_smd_enable lock held */
+	radio_hci_smd_deregister();
+	chan_opened = false;
+}
+
+static int hcismd_fm_set_enable(const char *val, struct kernel_param *kp)
+{
+	int ret = 0;
+
+	mutex_lock(&fm_smd_enable);
+	ret = param_set_int(val, kp);
+	if (ret)
+		goto done;
+	switch (fmsmd_set) {
+
+	case 1:
+		radio_hci_smd_init();
+		break;
+	case 0:
+		radio_hci_smd_exit();
+		break;
+	default:
+		ret = -EFAULT;
+	}
+done:
+	mutex_unlock(&fm_smd_enable);
+	return ret;
+}
+MODULE_DESCRIPTION("FM SMD driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
new file mode 100644
index 0000000..7671049
--- /dev/null
+++ b/drivers/media/radio/radio-iris.c
@@ -0,0 +1,5646 @@
+/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved
+ *
+ * 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.
+ */
+
+#define DRIVER_NAME "radio-iris"
+#define DRIVER_CARD "QTI FM Radio Transceiver"
+#define DRIVER_DESC "Driver for QTI FM Radio Transceiver "
+
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <linux/kfifo.h>
+#include <linux/param.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/version.h>
+#include <linux/videodev2.h>
+#include <linux/mutex.h>
+#include <linux/unistd.h>
+#include <linux/atomic.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/slab.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/radio-iris.h>
+#include <asm/unaligned.h>
+
+static unsigned int rds_buf = 100;
+static int oda_agt;
+static int grp_mask;
+static int rt_plus_carrier = -1;
+static int ert_carrier = -1;
+static unsigned char ert_buf[256];
+static unsigned char ert_len;
+static unsigned char c_byt_pair_index;
+static char utf_8_flag;
+static char rt_ert_flag;
+static char formatting_dir;
+static unsigned char sig_blend = CTRL_ON;
+static DEFINE_MUTEX(iris_fm);
+
+module_param(rds_buf, uint, 0000);
+MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
+
+module_param(sig_blend, byte, 0200 | 0400 | 0040 | 0004);
+MODULE_PARM_DESC(sig_blend, "signal blending switch: 0:OFF 1:ON");
+
+static void radio_hci_cmd_task(unsigned long arg);
+static void radio_hci_rx_task(unsigned long arg);
+static struct video_device *video_get_dev(void);
+static DEFINE_RWLOCK(hci_task_lock);
+
+typedef int (*radio_hci_request_func)(struct radio_hci_dev *hdev,
+		int (*req)(struct radio_hci_dev *hdev, unsigned long param),
+		unsigned long param, unsigned long timeout_msecs);
+
+struct iris_device {
+	struct device *dev;
+	struct kfifo data_buf[IRIS_BUF_MAX];
+
+	int pending_xfrs[IRIS_XFR_MAX];
+	int xfr_bytes_left;
+	int xfr_in_progress;
+	struct completion sync_xfr_start;
+	int tune_req;
+	unsigned int mode;
+	bool is_fm_closing;
+
+	__u16 pi;
+	__u8 pty;
+	__u8 ps_repeatcount;
+	__u8 prev_trans_rds;
+	__u8 af_jump_bit;
+	struct video_device *videodev;
+	struct v4l2_device v4l2_dev;
+
+	struct mutex lock;
+	spinlock_t buf_lock[IRIS_BUF_MAX];
+	wait_queue_head_t event_queue;
+	wait_queue_head_t read_queue;
+
+	struct radio_hci_dev *fm_hdev;
+
+	struct v4l2_capability g_cap;
+	struct v4l2_control *g_ctl;
+
+	struct hci_fm_mute_mode_req mute_mode;
+	struct hci_fm_stereo_mode_req stereo_mode;
+	struct hci_fm_station_rsp fm_st_rsp;
+	struct hci_fm_search_station_req srch_st;
+	struct hci_fm_search_rds_station_req srch_rds;
+	struct hci_fm_search_station_list_req srch_st_list;
+	struct hci_fm_recv_conf_req recv_conf;
+	struct hci_fm_trans_conf_req_struct trans_conf;
+	struct hci_fm_rds_grp_req rds_grp;
+	unsigned char g_search_mode;
+	unsigned char power_mode;
+	int search_on;
+	unsigned int tone_freq;
+	unsigned char spur_table_size;
+	unsigned char g_scan_time;
+	unsigned int g_antenna;
+	unsigned int g_rds_grp_proc_ps;
+	unsigned char event_mask;
+	enum iris_region_t region;
+	struct hci_fm_dbg_param_rsp st_dbg_param;
+	struct hci_ev_srch_list_compl srch_st_result;
+	struct hci_fm_riva_poke   riva_data_req;
+	struct hci_fm_ssbi_req    ssbi_data_accs;
+	struct hci_fm_ssbi_peek   ssbi_peek_reg;
+	struct hci_fm_sig_threshold_rsp sig_th;
+	struct hci_fm_ch_det_threshold ch_det_threshold;
+	struct hci_fm_data_rd_rsp default_data;
+	struct hci_fm_spur_data spur_data;
+	unsigned char is_station_valid;
+	struct hci_fm_blend_table blend_tbl;
+};
+
+static struct video_device *priv_videodev;
+static int iris_do_calibration(struct iris_device *radio);
+static void hci_buff_ert(struct iris_device *radio,
+		struct rds_grp_data *rds_buf);
+static void hci_ev_rt_plus(struct iris_device *radio,
+		struct rds_grp_data rds_buf);
+static void hci_ev_ert(struct iris_device *radio);
+static int update_spur_table(struct iris_device *radio);
+static int initialise_recv(struct iris_device *radio);
+static int initialise_trans(struct iris_device *radio);
+static int is_enable_rx_possible(struct iris_device *radio);
+static int is_enable_tx_possible(struct iris_device *radio);
+
+static struct v4l2_queryctrl iris_v4l2_queryctrl[] = {
+	{
+	.id	= V4L2_CID_AUDIO_VOLUME,
+	.type	= V4L2_CTRL_TYPE_INTEGER,
+	.name	= "Volume",
+	.minimum	= 0,
+	.maximum	= 15,
+	.step	=	1,
+	.default_value	=	15,
+	},
+	{
+	.id	=	V4L2_CID_AUDIO_BALANCE,
+	.flags	= V4L2_CTRL_FLAG_DISABLED,
+	},
+	{
+	.id	=	V4L2_CID_AUDIO_BASS,
+	.flags	=	V4L2_CTRL_FLAG_DISABLED,
+	},
+	{
+	.id	=	V4L2_CID_AUDIO_TREBLE,
+	.flags	=	V4L2_CTRL_FLAG_DISABLED,
+	},
+	{
+	.id	=	V4L2_CID_AUDIO_MUTE,
+	.type	=	V4L2_CTRL_TYPE_BOOLEAN,
+	.name	=	"Mute",
+	.minimum	=	0,
+	.maximum	=	1,
+	.step	=	1,
+	.default_value	= 1,
+	},
+	{
+	.id	=	V4L2_CID_AUDIO_LOUDNESS,
+	.flags	=	V4L2_CTRL_FLAG_DISABLED,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_SRCHMODE,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"Search mode",
+	.minimum	=	0,
+	.maximum	= 7,
+	.step	= 1,
+	.default_value	= 0,
+	},
+	{
+	.id	= V4L2_CID_PRIVATE_IRIS_SCANDWELL,
+	.type	= V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"Search dwell time",
+	.minimum	= 0,
+	.maximum	= 7,
+	.step	= 1,
+	.default_value	= 0,
+	},
+	{
+	.id	= V4L2_CID_PRIVATE_IRIS_SRCHON,
+	.type	= V4L2_CTRL_TYPE_BOOLEAN,
+	.name	= "Search on/off",
+	.minimum	= 0,
+	.maximum	= 1,
+	.step	= 1,
+	.default_value	= 1,
+
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_STATE,
+	.type	= V4L2_CTRL_TYPE_INTEGER,
+	.name	= "radio 0ff/rx/tx/reset",
+	.minimum	= 0,
+	.maximum	= 3,
+	.step	= 1,
+	.default_value	=	1,
+
+	},
+	{
+	.id	= V4L2_CID_PRIVATE_IRIS_REGION,
+	.type	= V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"radio standard",
+	.minimum	=	0,
+	.maximum	=	2,
+	.step	=	1,
+	.default_value	=	0,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_SIGNAL_TH,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"Signal Threshold",
+	.minimum	=	0x80,
+	.maximum	=	0x7F,
+	.step	=	1,
+	.default_value	=	0,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_SRCH_PTY,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"Search PTY",
+	.minimum	=	0,
+	.maximum	=	31,
+	.default_value	=	0,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_SRCH_PI,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"Search PI",
+	.minimum	=	0,
+	.maximum	=	0xFF,
+	.default_value	=	0,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_SRCH_CNT,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"Preset num",
+	.minimum	=	0,
+	.maximum	=	12,
+	.default_value	=	0,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_EMPHASIS,
+	.type	=	V4L2_CTRL_TYPE_BOOLEAN,
+	.name	=	"Emphasis",
+	.minimum	=	0,
+	.maximum	=	1,
+	.default_value	=	0,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_RDS_STD,
+	.type	=	V4L2_CTRL_TYPE_BOOLEAN,
+	.name	=	"RDS standard",
+	.minimum	=	0,
+	.maximum	=	1,
+	.default_value	=	0,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_SPACING,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"Channel spacing",
+	.minimum	=	0,
+	.maximum	=	2,
+	.default_value	=	0,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_RDSON,
+	.type	=	V4L2_CTRL_TYPE_BOOLEAN,
+	.name	=	"RDS on/off",
+	.minimum	=	0,
+	.maximum	=	1,
+	.default_value	=	0,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"RDS group mask",
+	.minimum	=	0,
+	.maximum	=	0xFFFFFFFF,
+	.default_value	=	0,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_RDSGROUP_PROC,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"RDS processing",
+	.minimum	=	0,
+	.maximum	=	0xFF,
+	.default_value	=	0,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_RDSD_BUF,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"RDS data groups to buffer",
+	.minimum	=	1,
+	.maximum	=	21,
+	.default_value	=	0,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_PSALL,
+	.type	=	V4L2_CTRL_TYPE_BOOLEAN,
+	.name	=	"pass all ps strings",
+	.minimum	=	0,
+	.maximum	=	1,
+	.default_value	=	0,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_LP_MODE,
+	.type	=	V4L2_CTRL_TYPE_BOOLEAN,
+	.name	=	"Low power mode",
+	.minimum	=	0,
+	.maximum	=	1,
+	.default_value	=	0,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_ANTENNA,
+	.type	=	V4L2_CTRL_TYPE_BOOLEAN,
+	.name	=	"headset/internal",
+	.minimum	=	0,
+	.maximum	=	1,
+	.default_value	=	0,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_TX_SETPSREPEATCOUNT,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"Set PS REPEATCOUNT",
+	.minimum	=	0,
+	.maximum	=	15,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_PS_NAME,
+	.type	=	V4L2_CTRL_TYPE_BOOLEAN,
+	.name	=	"Stop PS NAME",
+	.minimum	=	0,
+	.maximum	=	1,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_RT,
+	.type	=	V4L2_CTRL_TYPE_BOOLEAN,
+	.name	=	"Stop RT",
+	.minimum	=	0,
+	.maximum	=	1,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_SOFT_MUTE,
+	.type	=	V4L2_CTRL_TYPE_BOOLEAN,
+	.name	=	"Soft Mute",
+	.minimum	=	0,
+	.maximum	=	1,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_RIVA_ACCS_ADDR,
+	.type	=	V4L2_CTRL_TYPE_BOOLEAN,
+	.name	=	"Riva addr",
+	.minimum	=	0x3180000,
+	.maximum	=	0x31E0004,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_RIVA_ACCS_LEN,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"Data len",
+	.minimum	=	0,
+	.maximum	=	0xFF,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_RIVA_PEEK,
+	.type	=	V4L2_CTRL_TYPE_BOOLEAN,
+	.name	=	"Riva peek",
+	.minimum	=	0,
+	.maximum	=	1,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_RIVA_POKE,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"Riva poke",
+	.minimum	=	0x3180000,
+	.maximum	=	0x31E0004,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_SSBI_ACCS_ADDR,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"Ssbi addr",
+	.minimum	=	0x280,
+	.maximum	=	0x37F,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_SSBI_PEEK,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"Ssbi peek",
+	.minimum	=	0,
+	.maximum	=	0x37F,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_SSBI_POKE,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"ssbi poke",
+	.minimum	=	0x01,
+	.maximum	=	0xFF,
+	},
+	{
+	.id =	 V4L2_CID_PRIVATE_IRIS_HLSI,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"set hlsi",
+	.minimum	=	0,
+	.maximum	=	2,
+	},
+	{
+	.id =	 V4L2_CID_PRIVATE_IRIS_RDS_GRP_COUNTERS,
+	.type	=	V4L2_CTRL_TYPE_BOOLEAN,
+	.name	=	"RDS grp",
+	.minimum	=	0,
+	.maximum	=	1,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_SET_NOTCH_FILTER,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"Notch filter",
+	.minimum	=	0,
+	.maximum	=	2,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_READ_DEFAULT,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"Read default",
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_WRITE_DEFAULT,
+	.type	=	V4L2_CTRL_TYPE_INTEGER,
+	.name	=	"Write default",
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_SET_CALIBRATION,
+	.type	=	V4L2_CTRL_TYPE_BOOLEAN,
+	.name	=	"SET Calibration",
+	.minimum	=	0,
+	.maximum	=	1,
+	},
+	{
+	.id	=	V4L2_CID_PRIVATE_IRIS_DO_CALIBRATION,
+	.type	=	V4L2_CTRL_TYPE_BOOLEAN,
+	.name	=	"SET Calibration",
+	.minimum	=	0,
+	.maximum	=	1,
+	},
+	{
+	.id     =       V4L2_CID_PRIVATE_IRIS_GET_SINR,
+	.type   =       V4L2_CTRL_TYPE_INTEGER,
+	.name   =       "GET SINR",
+	.minimum        =       -128,
+	.maximum        =       127,
+	},
+	{
+	.id     =       V4L2_CID_PRIVATE_INTF_HIGH_THRESHOLD,
+	.type   =       V4L2_CTRL_TYPE_INTEGER,
+	.name   =       "Intf High Threshold",
+	.minimum        =       0,
+	.maximum        =       0xFF,
+	.default_value  =       0,
+	},
+	{
+	.id     =       V4L2_CID_PRIVATE_INTF_LOW_THRESHOLD,
+	.type   =       V4L2_CTRL_TYPE_INTEGER,
+	.name   =       "Intf low Threshold",
+	.minimum        =       0,
+	.maximum        =       0xFF,
+	.default_value  =       0,
+	},
+	{
+	.id     =       V4L2_CID_PRIVATE_SINR_THRESHOLD,
+	.type   =       V4L2_CTRL_TYPE_INTEGER,
+	.name   =       "SINR Threshold",
+	.minimum        =       -128,
+	.maximum        =       127,
+	.default_value  =       0,
+	},
+	{
+	.id     =       V4L2_CID_PRIVATE_SINR_SAMPLES,
+	.type   =       V4L2_CTRL_TYPE_INTEGER,
+	.name   =       "SINR samples",
+	.minimum        =       1,
+	.maximum        =       0xFF,
+	.default_value  =       0,
+	},
+};
+
+static void iris_q_event(struct iris_device *radio,
+				enum iris_evt_t event)
+{
+	struct kfifo *data_b;
+	unsigned char evt = event;
+
+	FMDBG("radio %pK event %d", radio, event);
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return;
+	}
+
+	data_b = &radio->data_buf[IRIS_BUF_EVENTS];
+	if (kfifo_in_locked(data_b, &evt, 1, &radio->buf_lock[IRIS_BUF_EVENTS]))
+		wake_up_interruptible(&radio->event_queue);
+}
+
+static int hci_send_frame(struct sk_buff *skb)
+{
+	struct radio_hci_dev *hdev;
+
+	FMDBG("skb %pK", skb);
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return -EINVAL;
+	}
+	hdev = (struct radio_hci_dev *) skb->dev;
+	if (unlikely(!hdev)) {
+		kfree_skb(skb);
+		return -ENODEV;
+	}
+
+	__net_timestamp(skb);
+
+	skb_orphan(skb);
+	return hdev->send(skb);
+}
+
+static void radio_hci_cmd_task(unsigned long arg)
+{
+	struct radio_hci_dev *hdev = (struct radio_hci_dev *) arg;
+	struct sk_buff *skb;
+
+	FMDBG("hdev %pK", hdev);
+
+	if (unlikely(hdev == NULL)) {
+		FMDERR("%s, HCI Device is null\n", __func__);
+		return;
+	}
+	if (!(atomic_read(&hdev->cmd_cnt))
+		&& time_after(jiffies, hdev->cmd_last_tx + HZ)) {
+		FMDERR("%s command tx timeout\n", hdev->name);
+		atomic_set(&hdev->cmd_cnt, 1);
+	}
+
+	skb = skb_dequeue(&hdev->cmd_q);
+	if (atomic_read(&hdev->cmd_cnt) && skb) {
+		kfree_skb(hdev->sent_cmd);
+		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
+		if (hdev->sent_cmd) {
+			atomic_dec(&hdev->cmd_cnt);
+			hci_send_frame(skb);
+			hdev->cmd_last_tx = jiffies;
+		} else {
+			skb_queue_head(&hdev->cmd_q, skb);
+			tasklet_schedule(&hdev->cmd_task);
+		}
+	}
+
+}
+
+static void radio_hci_rx_task(unsigned long arg)
+{
+	struct radio_hci_dev *hdev = (struct radio_hci_dev *) arg;
+	struct sk_buff *skb;
+
+	FMDBG("hdev %pK", hdev);
+
+	if (unlikely(hdev == NULL)) {
+		FMDERR("%s, HCI Device is null\n", __func__);
+		return;
+	}
+	read_lock(&hci_task_lock);
+
+	skb = skb_dequeue(&hdev->rx_q);
+	radio_hci_event_packet(hdev, skb);
+
+	read_unlock(&hci_task_lock);
+}
+
+int radio_hci_register_dev(struct radio_hci_dev *hdev)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+	FMDBG("radio %pK", radio);
+
+	if (!radio) {
+		FMDERR(":radio is null\n");
+		return -EINVAL;
+	}
+
+	if (!hdev) {
+		FMDERR("hdev is null\n");
+		return -EINVAL;
+	}
+
+	hdev->flags = 0;
+
+	tasklet_init(&hdev->cmd_task, radio_hci_cmd_task, (unsigned long)
+		hdev);
+	tasklet_init(&hdev->rx_task, radio_hci_rx_task, (unsigned long)
+		hdev);
+
+	init_waitqueue_head(&hdev->req_wait_q);
+
+	skb_queue_head_init(&hdev->rx_q);
+	skb_queue_head_init(&hdev->cmd_q);
+	skb_queue_head_init(&hdev->raw_q);
+
+
+	radio->fm_hdev = hdev;
+
+	return 0;
+}
+EXPORT_SYMBOL(radio_hci_register_dev);
+
+int radio_hci_unregister_dev(void)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	struct radio_hci_dev *hdev = NULL;
+
+	if (!radio) {
+		FMDERR("radio is null\n");
+		return -EINVAL;
+	}
+	hdev = radio->fm_hdev;
+	if (!hdev) {
+		FMDERR("hdev is null\n");
+		return -EINVAL;
+	}
+
+	tasklet_kill(&hdev->rx_task);
+	tasklet_kill(&hdev->cmd_task);
+	skb_queue_purge(&hdev->rx_q);
+	skb_queue_purge(&hdev->cmd_q);
+	skb_queue_purge(&hdev->raw_q);
+
+	radio->fm_hdev = NULL;
+	return 0;
+}
+EXPORT_SYMBOL(radio_hci_unregister_dev);
+
+int radio_hci_recv_frame(struct sk_buff *skb)
+{
+	struct radio_hci_dev *hdev;
+
+	FMDBG("hdev %pK", skb);
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return -EINVAL;
+	}
+	hdev = (struct radio_hci_dev *) skb->dev;
+	if (unlikely(!hdev)) {
+		FMDERR("%s hdev is null while receiving frame\n", hdev->name);
+		kfree_skb(skb);
+		return -ENXIO;
+	}
+
+	__net_timestamp(skb);
+
+	radio_hci_event_packet(hdev, skb);
+	kfree_skb(skb);
+	return 0;
+}
+EXPORT_SYMBOL(radio_hci_recv_frame);
+
+int radio_hci_send_cmd(struct radio_hci_dev *hdev, __u16 opcode, __u32 plen,
+		void *param)
+{
+	int len = RADIO_HCI_COMMAND_HDR_SIZE + plen;
+	struct radio_hci_command_hdr *hdr;
+	struct sk_buff *skb;
+	int ret = 0;
+
+	FMDBG("hdev %pK opcode %u len %u", hdev, opcode, plen);
+
+	if (unlikely(hdev == NULL)) {
+		FMDERR("%s, hci device is null\n", __func__);
+		return -EINVAL;
+	}
+	skb = alloc_skb(len, GFP_ATOMIC);
+	if (!skb)
+		return -ENOMEM;
+
+	hdr = (struct radio_hci_command_hdr *) skb_put(skb,
+		RADIO_HCI_COMMAND_HDR_SIZE);
+	hdr->opcode = cpu_to_le16(opcode);
+	hdr->plen   = plen;
+
+	if (plen)
+		memcpy(skb_put(skb, plen), param, plen);
+
+	skb->dev = (void *) hdev;
+
+	ret = hci_send_frame(skb);
+
+	return ret;
+}
+EXPORT_SYMBOL(radio_hci_send_cmd);
+
+static int hci_fm_enable_recv_req(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	__u16 opcode = 0;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_ENABLE_RECV_REQ);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_tone_generator(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	__u16 opcode = 0;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+		HCI_FM_SET_INTERNAL_TONE_GENRATOR);
+	return radio_hci_send_cmd(hdev, opcode,
+			sizeof(radio->tone_freq), &radio->tone_freq);
+}
+
+static int hci_fm_enable_trans_req(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	__u16 opcode = 0;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+		HCI_OCF_FM_ENABLE_TRANS_REQ);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_disable_recv_req(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	__u16 opcode = 0;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_DISABLE_RECV_REQ);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_disable_trans_req(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	__u16 opcode = 0;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+		HCI_OCF_FM_DISABLE_TRANS_REQ);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_get_fm_recv_conf_req(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	__u16 opcode = 0;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_GET_RECV_CONF_REQ);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_get_fm_trans_conf_req(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	u16 opcode = 0;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+		HCI_OCF_FM_GET_TRANS_CONF_REQ);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+static int hci_set_fm_recv_conf_req(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	__u16 opcode = 0;
+
+	struct hci_fm_recv_conf_req *recv_conf_req =
+		(struct hci_fm_recv_conf_req *) param;
+
+	if (recv_conf_req == NULL) {
+		FMDERR("%s, recv conf is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_SET_RECV_CONF_REQ);
+	return radio_hci_send_cmd(hdev, opcode, sizeof((*recv_conf_req)),
+		recv_conf_req);
+}
+
+static int hci_set_fm_trans_conf_req(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	__u16 opcode = 0;
+
+	struct hci_fm_trans_conf_req_struct *trans_conf_req =
+		(struct hci_fm_trans_conf_req_struct *) param;
+
+	if (trans_conf_req == NULL) {
+		FMDERR("%s, tx conf is null\n", __func__);
+		return -EINVAL;
+	}
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+		HCI_OCF_FM_SET_TRANS_CONF_REQ);
+	return radio_hci_send_cmd(hdev, opcode, sizeof((*trans_conf_req)),
+		trans_conf_req);
+}
+
+static int hci_fm_get_station_param_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_GET_STATION_PARAM_REQ);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_set_fm_mute_mode_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+	struct hci_fm_mute_mode_req *mute_mode_req =
+		(struct hci_fm_mute_mode_req *) param;
+
+	if (mute_mode_req == NULL) {
+		FMDERR("%s, mute mode is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_SET_MUTE_MODE_REQ);
+	return radio_hci_send_cmd(hdev, opcode, sizeof((*mute_mode_req)),
+		mute_mode_req);
+}
+
+
+static int hci_trans_ps_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+	struct hci_fm_tx_ps *tx_ps_req =
+		(struct hci_fm_tx_ps *) param;
+
+	if (tx_ps_req == NULL) {
+		FMDERR("%s, tx ps req is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+		HCI_OCF_FM_RDS_PS_REQ);
+
+	return radio_hci_send_cmd(hdev, opcode, sizeof((*tx_ps_req)),
+		tx_ps_req);
+}
+
+static int hci_trans_rt_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+	struct hci_fm_tx_rt *tx_rt_req =
+		(struct hci_fm_tx_rt *) param;
+
+	if (tx_rt_req == NULL) {
+		FMDERR("%s, tx rt req is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_TRANS_CTRL_CMD_REQ,
+		HCI_OCF_FM_RDS_RT_REQ);
+
+	return radio_hci_send_cmd(hdev, opcode, sizeof((*tx_rt_req)),
+		tx_rt_req);
+}
+
+static int hci_set_fm_stereo_mode_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+	struct hci_fm_stereo_mode_req *stereo_mode_req =
+		(struct hci_fm_stereo_mode_req *) param;
+
+	if (stereo_mode_req == NULL) {
+		FMDERR("%s, stere mode req is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_SET_STEREO_MODE_REQ);
+	return radio_hci_send_cmd(hdev, opcode, sizeof((*stereo_mode_req)),
+		stereo_mode_req);
+}
+
+static int hci_fm_set_antenna_req(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	__u16 opcode = 0;
+
+	__u8 antenna = param;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_SET_ANTENNA);
+	return radio_hci_send_cmd(hdev, opcode, sizeof(antenna), &antenna);
+}
+
+static int hci_fm_set_sig_threshold_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+
+	__u8 sig_threshold = param;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_SET_SIGNAL_THRESHOLD);
+	return radio_hci_send_cmd(hdev, opcode, sizeof(sig_threshold),
+		&sig_threshold);
+}
+
+static int hci_fm_set_event_mask(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	u16 opcode = 0;
+	u8 event_mask = param;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_SET_EVENT_MASK);
+	return radio_hci_send_cmd(hdev, opcode, sizeof(event_mask),
+		&event_mask);
+}
+static int hci_fm_get_sig_threshold_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_GET_SIGNAL_THRESHOLD);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_get_program_service_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_GET_PROGRAM_SERVICE_REQ);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_get_radio_text_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_GET_RADIO_TEXT_REQ);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_get_af_list_req(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	__u16 opcode = 0;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_GET_AF_LIST_REQ);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_search_stations_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+	struct hci_fm_search_station_req *srch_stations =
+		(struct hci_fm_search_station_req *) param;
+
+	if (srch_stations == NULL) {
+		FMDERR("%s, search station param is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_SEARCH_STATIONS);
+	return radio_hci_send_cmd(hdev, opcode, sizeof((*srch_stations)),
+		srch_stations);
+}
+
+static int hci_fm_srch_rds_stations_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+	struct hci_fm_search_rds_station_req *srch_stations =
+		(struct hci_fm_search_rds_station_req *) param;
+
+	if (srch_stations == NULL) {
+		FMDERR("%s, rds stations param is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_SEARCH_RDS_STATIONS);
+	return radio_hci_send_cmd(hdev, opcode, sizeof((*srch_stations)),
+		srch_stations);
+}
+
+static int hci_fm_srch_station_list_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+	struct hci_fm_search_station_list_req *srch_list =
+		(struct hci_fm_search_station_list_req *) param;
+
+	if (srch_list == NULL) {
+		FMDERR("%s, search list param is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_SEARCH_STATIONS_LIST);
+	return radio_hci_send_cmd(hdev, opcode, sizeof((*srch_list)),
+		srch_list);
+}
+
+static int hci_fm_cancel_search_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_CANCEL_SEARCH);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_rds_grp_mask_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	 __u16 opcode = 0;
+
+	struct hci_fm_rds_grp_req *fm_grp_mask =
+		(struct hci_fm_rds_grp_req *)param;
+
+	if (fm_grp_mask == NULL) {
+		FMDERR("%s, grp mask param is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_RDS_GRP);
+	return radio_hci_send_cmd(hdev, opcode, sizeof(*fm_grp_mask),
+		fm_grp_mask);
+}
+
+static int hci_fm_rds_grp_process_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+
+	__u32 fm_grps_process = param;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_RDS_GRP_PROCESS);
+	return radio_hci_send_cmd(hdev, opcode, sizeof(fm_grps_process),
+		&fm_grps_process);
+}
+
+static int hci_fm_tune_station_req(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	__u16 opcode = 0;
+
+	__u32 tune_freq = param;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+		HCI_OCF_FM_TUNE_STATION_REQ);
+	return radio_hci_send_cmd(hdev, opcode, sizeof(tune_freq), &tune_freq);
+}
+
+static int hci_def_data_read_req(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	__u16 opcode = 0;
+	struct hci_fm_def_data_rd_req *def_data_rd =
+		(struct hci_fm_def_data_rd_req *) param;
+
+	if (def_data_rd == NULL) {
+		FMDERR("%s, def data read param is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+		HCI_OCF_FM_DEFAULT_DATA_READ);
+	return radio_hci_send_cmd(hdev, opcode, sizeof((*def_data_rd)),
+	def_data_rd);
+}
+
+static int hci_def_data_write_req(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	__u16 opcode = 0;
+	struct hci_fm_def_data_wr_req *def_data_wr =
+		(struct hci_fm_def_data_wr_req *) param;
+
+	if (def_data_wr == NULL) {
+		FMDERR("%s, def data write param is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+		HCI_OCF_FM_DEFAULT_DATA_WRITE);
+
+	return radio_hci_send_cmd(hdev, opcode, (def_data_wr->length+2),
+	def_data_wr);
+}
+
+static int hci_set_notch_filter_req(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	__u16 opcode = 0;
+	__u8 notch_filter_val = param;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_EN_NOTCH_CTRL);
+	return radio_hci_send_cmd(hdev, opcode, sizeof(notch_filter_val),
+	&notch_filter_val);
+}
+
+static int hci_fm_reset_req(struct radio_hci_dev *hdev, unsigned long param)
+{
+	__u16 opcode = 0;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+		HCI_OCF_FM_RESET);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_get_feature_lists_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+		HCI_OCF_FM_GET_FEATURE_LIST);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_do_calibration_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+
+	__u8 mode = param;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+		HCI_OCF_FM_DO_CALIBRATION);
+	return radio_hci_send_cmd(hdev, opcode, sizeof(mode), &mode);
+}
+
+static int hci_read_grp_counters_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+	__u8 reset_counters = param;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_STATUS_PARAMETERS_CMD_REQ,
+		HCI_OCF_FM_READ_GRP_COUNTERS);
+	return radio_hci_send_cmd(hdev, opcode, sizeof(reset_counters),
+		&reset_counters);
+}
+
+static int hci_peek_data_req(struct radio_hci_dev *hdev, unsigned long param)
+{
+	__u16 opcode = 0;
+	struct hci_fm_riva_data *peek_data = (struct hci_fm_riva_data *)param;
+
+	if (peek_data == NULL) {
+		FMDERR("%s, peek data param is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+		HCI_OCF_FM_PEEK_DATA);
+	return radio_hci_send_cmd(hdev, opcode, sizeof((*peek_data)),
+	peek_data);
+}
+
+static int hci_poke_data_req(struct radio_hci_dev *hdev, unsigned long param)
+{
+	__u16 opcode = 0;
+	struct hci_fm_riva_poke *poke_data = (struct hci_fm_riva_poke *) param;
+
+	if (poke_data == NULL) {
+		FMDERR("%s, poke data param is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+		HCI_OCF_FM_POKE_DATA);
+	return radio_hci_send_cmd(hdev, opcode, sizeof((*poke_data)),
+	poke_data);
+}
+
+static int hci_ssbi_peek_reg_req(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	__u16 opcode = 0;
+	struct hci_fm_ssbi_peek *ssbi_peek = (struct hci_fm_ssbi_peek *) param;
+
+	if (ssbi_peek == NULL) {
+		FMDERR("%s, ssbi peek param is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+		HCI_OCF_FM_SSBI_PEEK_REG);
+	return radio_hci_send_cmd(hdev, opcode, sizeof((*ssbi_peek)),
+	ssbi_peek);
+}
+
+static int hci_ssbi_poke_reg_req(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	__u16 opcode = 0;
+	struct hci_fm_ssbi_req *ssbi_poke = (struct hci_fm_ssbi_req *) param;
+
+	if (ssbi_poke == NULL) {
+		FMDERR("%s, ssbi poke param is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+		HCI_OCF_FM_SSBI_POKE_REG);
+	return radio_hci_send_cmd(hdev, opcode, sizeof((*ssbi_poke)),
+	ssbi_poke);
+}
+
+static int hci_fm_get_station_dbg_param_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	__u16 opcode = 0;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+		HCI_OCF_FM_STATION_DBG_PARAM);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_set_ch_det_th(struct radio_hci_dev *hdev,
+	unsigned long param)
+{
+	struct hci_fm_ch_det_threshold *ch_det_th =
+			 (struct hci_fm_ch_det_threshold *) param;
+	u16 opcode;
+
+	if (ch_det_th == NULL) {
+		FMDERR("%s, channel det thrshld is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+		HCI_OCF_FM_SET_CH_DET_THRESHOLD);
+	return radio_hci_send_cmd(hdev, opcode, sizeof((*ch_det_th)),
+		ch_det_th);
+}
+
+static int hci_fm_get_ch_det_th(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	u16 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+			HCI_OCF_FM_GET_CH_DET_THRESHOLD);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_get_blend_tbl(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	u16 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+				HCI_OCF_FM_GET_BLND_TBL);
+	return radio_hci_send_cmd(hdev, opcode, 0, NULL);
+}
+
+static int hci_fm_set_blend_tbl(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	struct hci_fm_blend_table *blnd_tbl =
+			 (struct hci_fm_blend_table *) param;
+	u16 opcode;
+
+	if (blnd_tbl == NULL) {
+		FMDERR("%s, blend tbl is null\n", __func__);
+		return -EINVAL;
+	}
+	opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
+			HCI_OCF_FM_SET_BLND_TBL);
+	return radio_hci_send_cmd(hdev, opcode,
+			sizeof(struct hci_fm_blend_table), blnd_tbl);
+}
+
+static int radio_hci_err(__u32 code)
+{
+	switch (code) {
+	case 0:
+		return 0;
+	case 0x01:
+		return -EBADRQC;
+	case 0x02:
+		return -ENOTCONN;
+	case 0x03:
+		return -EIO;
+	case 0x07:
+		return -ENOMEM;
+	case 0x0c:
+		return -EBUSY;
+	case 0x11:
+		return -EOPNOTSUPP;
+	case 0x12:
+		return -EINVAL;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int __radio_hci_request(struct radio_hci_dev *hdev,
+		int (*req)(struct radio_hci_dev *hdev,
+			unsigned long param),
+			unsigned long param, unsigned long timeout_msecs,
+			bool interruptible)
+{
+	int err = 0;
+	DECLARE_WAITQUEUE(wait, current);
+
+	if (unlikely(hdev == NULL)) {
+		FMDERR("%s, hci dev is null\n", __func__);
+		return -EINVAL;
+	}
+
+	mutex_lock(&iris_fm);
+	hdev->req_status = HCI_REQ_PEND;
+
+	add_wait_queue(&hdev->req_wait_q, &wait);
+	if (interruptible)
+		set_current_state(TASK_INTERRUPTIBLE);
+	else
+		set_current_state(TASK_UNINTERRUPTIBLE);
+
+	err = req(hdev, param);
+
+	schedule_timeout(msecs_to_jiffies(timeout_msecs));
+
+	remove_wait_queue(&hdev->req_wait_q, &wait);
+
+	if (interruptible && signal_pending(current)) {
+		mutex_unlock(&iris_fm);
+		return -EINTR;
+	}
+
+	switch (hdev->req_status) {
+	case HCI_REQ_DONE:
+	case HCI_REQ_STATUS:
+		err = radio_hci_err(hdev->req_result);
+		break;
+	default:
+		err = -ETIMEDOUT;
+		break;
+	}
+
+	hdev->req_status = hdev->req_result = 0;
+	mutex_unlock(&iris_fm);
+
+	return err;
+}
+
+static inline int radio_hci_request_interruptible(struct radio_hci_dev *hdev,
+		int (*req)(struct
+		radio_hci_dev * hdev, unsigned long param),
+		unsigned long param, unsigned long timeout_msecs)
+{
+	int ret = 0;
+
+	ret = __radio_hci_request(hdev, req, param, timeout_msecs, true);
+
+	return ret;
+}
+
+static inline int radio_hci_request_uninterruptible(struct radio_hci_dev *hdev,
+		int (*req)(struct
+		radio_hci_dev * hdev, unsigned long param),
+		unsigned long param, unsigned long timeout_msecs)
+{
+	int ret = 0;
+
+	ret = __radio_hci_request(hdev, req, param, timeout_msecs, false);
+
+	return ret;
+}
+
+static inline int radio_hci_request(struct radio_hci_dev *hdev,
+		int (*req)(struct
+		radio_hci_dev * hdev, unsigned long param),
+		unsigned long param, unsigned long timeout_msecs)
+{
+	return radio_hci_request_interruptible(hdev, req, param, timeout_msecs);
+}
+
+static inline int hci_conf_event_mask(__u8 *arg,
+		struct radio_hci_dev *hdev)
+{
+	u8 event_mask;
+
+	if (arg == NULL) {
+		FMDERR("%s, arg is null\n", __func__);
+		return -EINVAL;
+	}
+	event_mask = *arg;
+	return  radio_hci_request(hdev, hci_fm_set_event_mask,
+				event_mask, RADIO_HCI_TIMEOUT);
+}
+static int hci_set_fm_recv_conf(struct hci_fm_recv_conf_req *arg,
+		struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	struct hci_fm_recv_conf_req *set_recv_conf = arg;
+
+	ret = radio_hci_request(hdev, hci_set_fm_recv_conf_req, (unsigned
+		long)set_recv_conf, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_set_fm_trans_conf(struct hci_fm_trans_conf_req_struct *arg,
+		struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	struct hci_fm_trans_conf_req_struct *set_trans_conf = arg;
+
+	ret = radio_hci_request(hdev, hci_set_fm_trans_conf_req, (unsigned
+		long)set_trans_conf, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_fm_tune_station(__u32 *arg, struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	__u32 tune_freq;
+
+	if (arg == NULL) {
+		FMDERR("%s, arg is null\n", __func__);
+		return -EINVAL;
+	}
+	tune_freq = *arg;
+	ret = radio_hci_request(hdev, hci_fm_tune_station_req, tune_freq,
+		RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_set_fm_mute_mode(struct hci_fm_mute_mode_req *arg,
+	struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	struct hci_fm_mute_mode_req *set_mute_conf = arg;
+
+	ret = radio_hci_request(hdev, hci_set_fm_mute_mode_req, (unsigned
+		long)set_mute_conf, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_set_fm_stereo_mode(struct hci_fm_stereo_mode_req *arg,
+	struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	struct hci_fm_stereo_mode_req *set_stereo_conf = arg;
+
+	ret = radio_hci_request(hdev, hci_set_fm_stereo_mode_req, (unsigned
+		long)set_stereo_conf, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_fm_set_antenna(__u8 *arg, struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	__u8 antenna;
+
+	if (arg == NULL) {
+		FMDERR("%s, arg is null\n", __func__);
+		return -EINVAL;
+	}
+	antenna = *arg;
+	ret = radio_hci_request(hdev, hci_fm_set_antenna_req, antenna,
+		RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_fm_set_signal_threshold(__u8 *arg,
+	struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	__u8 sig_threshold;
+
+	if (arg == NULL) {
+		FMDERR("%s, arg is null\n", __func__);
+		return -EINVAL;
+	}
+	sig_threshold = *arg;
+	ret = radio_hci_request(hdev, hci_fm_set_sig_threshold_req,
+		sig_threshold, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_fm_search_stations(struct hci_fm_search_station_req *arg,
+	struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	struct hci_fm_search_station_req *srch_stations = arg;
+
+	ret = radio_hci_request(hdev, hci_fm_search_stations_req, (unsigned
+		long)srch_stations, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_fm_search_rds_stations(struct hci_fm_search_rds_station_req *arg,
+	struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	struct hci_fm_search_rds_station_req *srch_stations = arg;
+
+	ret = radio_hci_request(hdev, hci_fm_srch_rds_stations_req, (unsigned
+		long)srch_stations, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_fm_search_station_list
+	(struct hci_fm_search_station_list_req *arg,
+	struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	struct hci_fm_search_station_list_req *srch_list = arg;
+
+	ret = radio_hci_request(hdev, hci_fm_srch_station_list_req, (unsigned
+		long)srch_list, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_fm_rds_grp(struct hci_fm_rds_grp_req *arg,
+	struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	struct hci_fm_rds_grp_req *fm_grp_mask = arg;
+
+	ret = radio_hci_request(hdev, hci_fm_rds_grp_mask_req, (unsigned
+		long)fm_grp_mask, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_fm_rds_grps_process(__u32 *arg, struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	__u32 fm_grps_process;
+
+	if (arg == NULL) {
+		FMDERR("%s, arg is null\n", __func__);
+		return -EINVAL;
+	}
+	fm_grps_process = *arg;
+	ret = radio_hci_request(hdev, hci_fm_rds_grp_process_req,
+		fm_grps_process, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+int hci_def_data_read(struct hci_fm_def_data_rd_req *arg,
+	struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	struct hci_fm_def_data_rd_req *def_data_rd = arg;
+
+	ret = radio_hci_request(hdev, hci_def_data_read_req, (unsigned
+		long)def_data_rd, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+int hci_def_data_write(struct hci_fm_def_data_wr_req *arg,
+	struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	struct hci_fm_def_data_wr_req *def_data_wr = arg;
+
+	ret = radio_hci_request(hdev, hci_def_data_write_req, (unsigned
+		long)def_data_wr, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+int hci_fm_do_calibration(__u8 *arg, struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	__u8 mode;
+
+	if (arg == NULL) {
+		FMDERR("%s, arg is null\n", __func__);
+		return -EINVAL;
+	}
+	mode = *arg;
+	ret = radio_hci_request(hdev, hci_fm_do_calibration_req, mode,
+		RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_read_grp_counters(__u8 *arg, struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	__u8 reset_counters;
+
+	if (arg == NULL) {
+		FMDERR("%s, arg is null\n", __func__);
+		return -EINVAL;
+	}
+	reset_counters = *arg;
+	ret = radio_hci_request(hdev, hci_read_grp_counters_req,
+		reset_counters, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_set_notch_filter(__u8 *arg, struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	__u8 notch_filter;
+
+	if (arg == NULL) {
+		FMDERR("%s, arg is null\n", __func__);
+		return -EINVAL;
+	}
+
+	notch_filter = *arg;
+	ret = radio_hci_request(hdev, hci_set_notch_filter_req,
+		notch_filter, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_peek_data(struct hci_fm_riva_data *arg,
+				struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	struct hci_fm_riva_data *peek_data = arg;
+
+	ret = radio_hci_request(hdev, hci_peek_data_req, (unsigned
+		long)peek_data, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_poke_data(struct hci_fm_riva_poke *arg,
+			struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	struct hci_fm_riva_poke *poke_data = arg;
+
+	ret = radio_hci_request(hdev, hci_poke_data_req, (unsigned
+		long)poke_data, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_ssbi_peek_reg(struct hci_fm_ssbi_peek *arg,
+	struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	struct hci_fm_ssbi_peek *ssbi_peek_reg = arg;
+
+	ret = radio_hci_request(hdev, hci_ssbi_peek_reg_req, (unsigned
+		long)ssbi_peek_reg, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_ssbi_poke_reg(struct hci_fm_ssbi_req *arg,
+			struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	struct hci_fm_ssbi_req *ssbi_poke_reg = arg;
+
+	ret = radio_hci_request(hdev, hci_ssbi_poke_reg_req, (unsigned
+		long)ssbi_poke_reg, RADIO_HCI_TIMEOUT);
+
+	return ret;
+}
+
+static int hci_set_ch_det_thresholds_req(struct hci_fm_ch_det_threshold *arg,
+		struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	struct hci_fm_ch_det_threshold *ch_det_threshold = arg;
+
+	ret = radio_hci_request(hdev, hci_fm_set_ch_det_th,
+		 (unsigned long)ch_det_threshold, RADIO_HCI_TIMEOUT);
+	return ret;
+}
+
+static int hci_fm_set_cal_req_proc(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	u16 opcode = 0;
+	struct hci_fm_set_cal_req_proc *cal_req =
+		(struct hci_fm_set_cal_req_proc *)param;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+		HCI_OCF_FM_SET_CALIBRATION);
+	return radio_hci_send_cmd(hdev, opcode,
+		sizeof(struct hci_fm_set_cal_req_proc), cal_req);
+}
+
+static int hci_fm_do_cal_req(struct radio_hci_dev *hdev,
+		unsigned long param)
+{
+	u16 opcode = 0;
+	u8 cal_mode = param;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+		HCI_OCF_FM_DO_CALIBRATION);
+	return radio_hci_send_cmd(hdev, opcode, sizeof(cal_mode),
+		&cal_mode);
+
+}
+
+static int hci_fm_set_spur_tbl_req(struct radio_hci_dev *hdev,
+					unsigned long param)
+{
+	u16 opcode = 0, len = 0;
+	struct hci_fm_set_spur_table_req *spur_req =
+		(struct hci_fm_set_spur_table_req *)param;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+			HCI_OCF_FM_SET_SPUR_TABLE);
+	if (spur_req->no_of_freqs_entries > ENTRIES_EACH_CMD)
+		len = (ENTRIES_EACH_CMD * SPUR_DATA_LEN)
+			+ SPUR_DATA_INDEX;
+	else
+		len = (spur_req->no_of_freqs_entries * SPUR_DATA_LEN)
+			+ SPUR_DATA_INDEX;
+
+	return radio_hci_send_cmd(hdev, opcode, len, spur_req);
+}
+
+static int hci_fm_get_spur_tbl_data(struct radio_hci_dev *hdev,
+					unsigned long param)
+{
+	u16 opcode = 0;
+	unsigned int spur_freq = (unsigned int)param;
+
+	opcode = hci_opcode_pack(HCI_OGF_FM_COMMON_CTRL_CMD_REQ,
+			HCI_OCF_FM_GET_SPUR_TABLE);
+	return radio_hci_send_cmd(hdev, opcode, sizeof(int), &spur_freq);
+}
+
+static int hci_set_blend_tbl_req(struct hci_fm_blend_table *arg,
+		struct radio_hci_dev *hdev)
+{
+	int ret = 0;
+	struct hci_fm_blend_table *blend_tbl = arg;
+
+	ret = radio_hci_request(hdev, hci_fm_set_blend_tbl,
+		 (unsigned long)blend_tbl, RADIO_HCI_TIMEOUT);
+	return ret;
+}
+
+static int hci_cmd_internal(unsigned int cmd, struct radio_hci_dev *hdev,
+						bool interruptible)
+{
+	int ret = 0;
+	unsigned long arg = 0;
+	radio_hci_request_func radio_hci_request;
+
+	FMDBG("hdev %pK cmd 0x%x", hdev, cmd);
+
+	if (!hdev)
+		return -ENODEV;
+
+	radio_hci_request = interruptible ? radio_hci_request_interruptible :
+			radio_hci_request_uninterruptible;
+
+	switch (cmd) {
+	case HCI_FM_ENABLE_RECV_CMD:
+		ret = radio_hci_request(hdev, hci_fm_enable_recv_req, arg,
+			RADIO_HCI_TIMEOUT);
+		break;
+
+	case HCI_FM_DISABLE_RECV_CMD:
+		ret = radio_hci_request(hdev, hci_fm_disable_recv_req, arg,
+			RADIO_HCI_TIMEOUT);
+		break;
+
+	case HCI_FM_GET_RECV_CONF_CMD:
+		ret = radio_hci_request(hdev, hci_get_fm_recv_conf_req, arg,
+			RADIO_HCI_TIMEOUT);
+		break;
+
+	case HCI_FM_GET_STATION_PARAM_CMD:
+		ret = radio_hci_request(hdev,
+			hci_fm_get_station_param_req, arg,
+			RADIO_HCI_TIMEOUT);
+		break;
+
+	case HCI_FM_GET_SIGNAL_TH_CMD:
+		ret = radio_hci_request(hdev,
+			hci_fm_get_sig_threshold_req, arg,
+			RADIO_HCI_TIMEOUT);
+		break;
+
+	case HCI_FM_GET_PROGRAM_SERVICE_CMD:
+		ret = radio_hci_request(hdev,
+			hci_fm_get_program_service_req, arg,
+			RADIO_HCI_TIMEOUT);
+		break;
+
+	case HCI_FM_GET_RADIO_TEXT_CMD:
+		ret = radio_hci_request(hdev, hci_fm_get_radio_text_req, arg,
+			RADIO_HCI_TIMEOUT);
+		break;
+
+	case HCI_FM_GET_AF_LIST_CMD:
+		ret = radio_hci_request(hdev, hci_fm_get_af_list_req, arg,
+			RADIO_HCI_TIMEOUT);
+		break;
+
+	case HCI_FM_CANCEL_SEARCH_CMD:
+		ret = radio_hci_request(hdev, hci_fm_cancel_search_req, arg,
+			RADIO_HCI_TIMEOUT);
+		break;
+
+	case HCI_FM_RESET_CMD:
+		ret = radio_hci_request(hdev, hci_fm_reset_req, arg,
+			RADIO_HCI_TIMEOUT);
+		break;
+
+	case HCI_FM_GET_FEATURES_CMD:
+		ret = radio_hci_request(hdev,
+		hci_fm_get_feature_lists_req, arg,
+			RADIO_HCI_TIMEOUT);
+		break;
+
+	case HCI_FM_STATION_DBG_PARAM_CMD:
+		ret = radio_hci_request(hdev,
+		hci_fm_get_station_dbg_param_req, arg,
+			RADIO_HCI_TIMEOUT);
+		break;
+
+	case HCI_FM_ENABLE_TRANS_CMD:
+		ret = radio_hci_request(hdev, hci_fm_enable_trans_req, arg,
+			RADIO_HCI_TIMEOUT);
+		break;
+
+	case HCI_FM_DISABLE_TRANS_CMD:
+		ret = radio_hci_request(hdev, hci_fm_disable_trans_req, arg,
+			RADIO_HCI_TIMEOUT);
+		break;
+
+	case HCI_FM_GET_TX_CONFIG:
+		ret = radio_hci_request(hdev, hci_get_fm_trans_conf_req, arg,
+			RADIO_HCI_TIMEOUT);
+		break;
+	case HCI_FM_GET_DET_CH_TH_CMD:
+		ret = radio_hci_request(hdev, hci_fm_get_ch_det_th, arg,
+					RADIO_HCI_TIMEOUT);
+		break;
+	case HCI_FM_GET_BLND_TBL_CMD:
+		ret = radio_hci_request(hdev, hci_fm_get_blend_tbl, arg,
+					RADIO_HCI_TIMEOUT);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+
+static int hci_cmd(unsigned int cmd, struct radio_hci_dev *hdev)
+{
+	return hci_cmd_internal(cmd, hdev, true);
+}
+
+static int hci_cmd_uninterruptible(unsigned int cmd, struct radio_hci_dev *hdev)
+{
+	return hci_cmd_internal(cmd, hdev, false);
+}
+
+static void radio_hci_req_complete(struct radio_hci_dev *hdev, int result)
+{
+
+	if (unlikely(hdev == NULL)) {
+		FMDERR("%s, hci device is null\n", __func__);
+		return;
+	}
+	hdev->req_result = result;
+	hdev->req_status = HCI_REQ_DONE;
+	wake_up(&hdev->req_wait_q);
+}
+
+static void radio_hci_status_complete(struct radio_hci_dev *hdev, int result)
+{
+	if (unlikely(hdev == NULL)) {
+		FMDERR("%s, hci device is null\n", __func__);
+		return;
+	}
+	hdev->req_result = result;
+	hdev->req_status = HCI_REQ_STATUS;
+	wake_up(&hdev->req_wait_q);
+}
+
+static void hci_cc_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
+{
+	__u8 status;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	status = *((__u8 *) skb->data);
+
+	radio_hci_req_complete(hdev, status);
+}
+
+static void hci_cc_fm_disable_rsp(struct radio_hci_dev *hdev,
+	struct sk_buff *skb)
+{
+	__u8 status;
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+	FMDBG("hdev %pK skb %p", hdev, skb);
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null");
+		return;
+	}
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	status = *((__u8 *) skb->data);
+	if ((radio->mode == FM_TURNING_OFF) && (status == 0)) {
+		if (!radio->is_fm_closing)
+			iris_q_event(radio, IRIS_EVT_RADIO_DISABLED);
+		radio_hci_req_complete(hdev, status);
+		radio->mode = FM_OFF;
+	} else if (radio->mode == FM_CALIB) {
+		radio_hci_req_complete(hdev, status);
+	} else if ((radio->mode == FM_RECV) || (radio->mode == FM_TRANS)) {
+		iris_q_event(radio, IRIS_EVT_RADIO_DISABLED);
+		radio->mode = FM_OFF;
+	} else if ((radio->mode == FM_TURNING_OFF) && (status != 0)) {
+		radio_hci_req_complete(hdev, status);
+	}
+}
+
+static void hci_cc_conf_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_fm_conf_rsp  *rsp;
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null");
+		return;
+	}
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	rsp = (struct hci_fm_conf_rsp *)skb->data;
+	if (!rsp->status)
+		radio->recv_conf = rsp->recv_conf_rsp;
+	radio_hci_req_complete(hdev, rsp->status);
+}
+
+static void hci_cc_fm_trans_get_conf_rsp(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct hci_fm_get_trans_conf_rsp  *rsp;
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return;
+	}
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	rsp = (struct hci_fm_get_trans_conf_rsp *)skb->data;
+	if (!rsp->status)
+		memcpy((void *)&radio->trans_conf,
+			(void *)&rsp->trans_conf_rsp,
+			sizeof(rsp->trans_conf_rsp));
+
+	radio_hci_req_complete(hdev, rsp->status);
+}
+
+static void hci_cc_fm_enable_rsp(struct radio_hci_dev *hdev,
+	struct sk_buff *skb)
+{
+	struct hci_fm_conf_rsp  *rsp;
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+	FMDBG("hdev %pK skb %p", hdev, skb);
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return;
+	}
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	rsp = (struct hci_fm_conf_rsp *)skb->data;
+	if (rsp->status) {
+		radio_hci_req_complete(hdev, rsp->status);
+		return;
+	}
+
+	radio_hci_req_complete(hdev, rsp->status);
+}
+
+
+static void hci_cc_fm_trans_set_conf_rsp(struct radio_hci_dev *hdev,
+	struct sk_buff *skb)
+{
+	struct hci_fm_conf_rsp  *rsp;
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return;
+	}
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	rsp = (struct hci_fm_conf_rsp  *)skb->data;
+	if (!rsp->status)
+		iris_q_event(radio, HCI_EV_CMD_COMPLETE);
+
+	radio_hci_req_complete(hdev, rsp->status);
+}
+
+
+static void hci_cc_sig_threshold_rsp(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct hci_fm_sig_threshold_rsp  *rsp;
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return;
+	}
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	rsp = (struct hci_fm_sig_threshold_rsp  *)skb->data;
+	if (!rsp->status)
+		memcpy(&radio->sig_th, rsp,
+			sizeof(struct hci_fm_sig_threshold_rsp));
+	radio_hci_req_complete(hdev, rsp->status);
+}
+
+static void hci_cc_station_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	struct hci_fm_station_rsp *rsp;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return;
+	}
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	rsp = (struct hci_fm_station_rsp *)skb->data;
+	radio->fm_st_rsp = *(rsp);
+
+	/* Tune is always successful */
+	radio_hci_req_complete(hdev, 0);
+}
+
+static void hci_cc_prg_srv_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_fm_prgm_srv_rsp  *rsp;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	rsp = (struct hci_fm_prgm_srv_rsp  *)skb->data;
+
+	radio_hci_req_complete(hdev, rsp->status);
+}
+
+static void hci_cc_rd_txt_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_fm_radio_txt_rsp  *rsp;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	rsp = (struct hci_fm_radio_txt_rsp  *)skb->data;
+	radio_hci_req_complete(hdev, rsp->status);
+}
+
+static void hci_cc_af_list_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb)
+{
+	struct hci_fm_af_list_rsp  *rsp;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	rsp = (struct hci_fm_af_list_rsp  *)skb->data;
+	radio_hci_req_complete(hdev, rsp->status);
+}
+
+static void hci_cc_feature_list_rsp(struct radio_hci_dev *hdev,
+	struct sk_buff *skb)
+{
+	struct v4l2_capability *v4l_cap;
+	struct hci_fm_feature_list_rsp  *rsp;
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return;
+	}
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	rsp = (struct hci_fm_feature_list_rsp  *)skb->data;
+	v4l_cap = &radio->g_cap;
+
+	if (!rsp->status)
+		v4l_cap->capabilities = (rsp->feature_mask & 0x000002) |
+						(rsp->feature_mask & 0x000001);
+
+	radio_hci_req_complete(hdev, rsp->status);
+}
+
+static void hci_cc_dbg_param_rsp(struct radio_hci_dev *hdev,
+	struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	struct hci_fm_dbg_param_rsp *rsp;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return;
+	}
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	rsp = (struct hci_fm_dbg_param_rsp *)skb->data;
+	radio->st_dbg_param = *(rsp);
+	radio_hci_req_complete(hdev, radio->st_dbg_param.status);
+}
+
+static void iris_q_evt_data(struct iris_device *radio,
+				char *data, int len, int event)
+{
+	struct kfifo *data_b;
+
+	FMDBG("radio %pK data %p len %d event %d", radio, data, len, event);
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return;
+	}
+	data_b = &radio->data_buf[event];
+	if (kfifo_in_locked(data_b, data, len, &radio->buf_lock[event]))
+		wake_up_interruptible(&radio->event_queue);
+}
+
+static void hci_cc_riva_peek_rsp(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	__u8 status;
+	int len;
+	char *data;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	status = *((__u8 *) skb->data);
+	if (!status) {
+		len = skb->data[RIVA_PEEK_LEN_OFSET] + RIVA_PEEK_PARAM;
+		data = kmalloc(len, GFP_ATOMIC);
+
+		if (data != NULL) {
+			memcpy(data, &skb->data[PEEK_DATA_OFSET], len);
+			iris_q_evt_data(radio, data, len, IRIS_BUF_PEEK);
+			kfree(data);
+		}
+	}
+
+	radio_hci_req_complete(hdev, status);
+}
+
+static void hci_cc_riva_read_default_rsp(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	__u8 status;
+	__u8 len;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return;
+	}
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	status = *((__u8 *) skb->data);
+	if (!status) {
+		len = skb->data[1];
+		memset(&radio->default_data, 0,
+			sizeof(struct hci_fm_data_rd_rsp));
+		memcpy(&radio->default_data, &skb->data[0], len+2);
+		iris_q_evt_data(radio, &skb->data[0], len+2,
+				IRIS_BUF_RD_DEFAULT);
+	}
+	radio_hci_req_complete(hdev, status);
+}
+
+static void hci_cc_get_spur_tbl(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	__u8 status;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return;
+	}
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	status = *((__u8 *) skb->data);
+	if (!status) {
+		iris_q_evt_data(radio, &skb->data[1], SPUR_DATA_LEN,
+							IRIS_BUF_SPUR);
+		iris_q_event(radio, IRIS_EVT_SPUR_TBL);
+	}
+	radio_hci_req_complete(hdev, status);
+}
+
+static void hci_cc_ssbi_peek_rsp(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	__u8 status;
+	char *data;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	status = *((__u8 *) skb->data);
+	if (!status) {
+		data = kmalloc(SSBI_PEEK_LEN, GFP_ATOMIC);
+		if (data != NULL) {
+			data[0] = skb->data[PEEK_DATA_OFSET];
+			iris_q_evt_data(radio, data, SSBI_PEEK_LEN,
+					IRIS_BUF_SSBI_PEEK);
+			kfree(data);
+		}
+	}
+
+	radio_hci_req_complete(hdev, status);
+}
+
+static void hci_cc_rds_grp_cntrs_rsp(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	__u8 status;
+	char *data;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	status = *((__u8 *) skb->data);
+	if (!status) {
+		data = kmalloc(RDS_GRP_CNTR_LEN, GFP_ATOMIC);
+		if (data != NULL) {
+			memcpy(data, &skb->data[1], RDS_GRP_CNTR_LEN);
+			iris_q_evt_data(radio, data, RDS_GRP_CNTR_LEN,
+						IRIS_BUF_RDS_CNTRS);
+			kfree(data);
+		}
+	}
+	radio_hci_req_complete(hdev, status);
+}
+
+static void hci_cc_do_calibration_rsp(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	static struct hci_cc_do_calibration_rsp rsp;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	rsp.status = skb->data[0];
+	rsp.mode = skb->data[CALIB_MODE_OFSET];
+
+	if (!rsp.status) {
+		if (rsp.mode == PROCS_CALIB_MODE) {
+			memcpy(&rsp.data[0], &skb->data[CALIB_DATA_OFSET],
+				PROCS_CALIB_SIZE);
+			iris_q_evt_data(radio, rsp.data, PROCS_CALIB_SIZE,
+					IRIS_BUF_CAL_DATA);
+		}
+	}
+	radio_hci_req_complete(hdev, rsp.status);
+}
+
+static void hci_cc_get_ch_det_threshold_rsp(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	u8  status;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return;
+	}
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	status = skb->data[0];
+	if (!status)
+		memcpy(&radio->ch_det_threshold, &skb->data[1],
+			sizeof(struct hci_fm_ch_det_threshold));
+
+	radio_hci_req_complete(hdev, status);
+}
+
+static void hci_cc_get_blend_tbl_rsp(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	u8  status;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return;
+	}
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	status = skb->data[0];
+	if (!status)
+		memcpy(&radio->blend_tbl, &skb->data[1],
+			sizeof(struct hci_fm_blend_table));
+
+	radio_hci_req_complete(hdev, status);
+}
+
+static inline void hci_cmd_complete_event(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct hci_ev_cmd_complete *cmd_compl_ev;
+	__u16 opcode;
+
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	cmd_compl_ev = (struct hci_ev_cmd_complete *)skb->data;
+	skb_pull(skb, sizeof(*cmd_compl_ev));
+
+	opcode = __le16_to_cpu(cmd_compl_ev->cmd_opcode);
+
+	FMDBG("opcode 0x%x", opcode);
+	switch (opcode) {
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_ENABLE_RECV_REQ):
+	case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_ENABLE_TRANS_REQ):
+		hci_cc_fm_enable_rsp(hdev, skb);
+		break;
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_RECV_CONF_REQ):
+		hci_cc_conf_rsp(hdev, skb);
+		break;
+
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_DISABLE_RECV_REQ):
+	case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_DISABLE_TRANS_REQ):
+		hci_cc_fm_disable_rsp(hdev, skb);
+		break;
+
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_RECV_CONF_REQ):
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_MUTE_MODE_REQ):
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_STEREO_MODE_REQ):
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_ANTENNA):
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_SIGNAL_THRESHOLD):
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_CANCEL_SEARCH):
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_GRP):
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_GRP_PROCESS):
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_EN_WAN_AVD_CTRL):
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_EN_NOTCH_CTRL):
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_CH_DET_THRESHOLD):
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_BLND_TBL):
+	case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_RT_REQ):
+	case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_PS_REQ):
+	case hci_common_cmd_op_pack(HCI_OCF_FM_DEFAULT_DATA_WRITE):
+		hci_cc_rsp(hdev, skb);
+		break;
+	case hci_common_cmd_op_pack(HCI_OCF_FM_RESET):
+	case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_SSBI_POKE_REG):
+	case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_POKE_DATA):
+	case hci_diagnostic_cmd_op_pack(HCI_FM_SET_INTERNAL_TONE_GENRATOR):
+	case hci_common_cmd_op_pack(HCI_OCF_FM_SET_CALIBRATION):
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_EVENT_MASK):
+	case hci_common_cmd_op_pack(HCI_OCF_FM_SET_SPUR_TABLE):
+		hci_cc_rsp(hdev, skb);
+		break;
+	case hci_common_cmd_op_pack(HCI_OCF_FM_GET_SPUR_TABLE):
+		hci_cc_get_spur_tbl(hdev, skb);
+		break;
+	case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_SSBI_PEEK_REG):
+		hci_cc_ssbi_peek_rsp(hdev, skb);
+		break;
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_SIGNAL_THRESHOLD):
+		hci_cc_sig_threshold_rsp(hdev, skb);
+		break;
+
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_STATION_PARAM_REQ):
+		hci_cc_station_rsp(hdev, skb);
+		break;
+
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_PROGRAM_SERVICE_REQ):
+		hci_cc_prg_srv_rsp(hdev, skb);
+		break;
+
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_RADIO_TEXT_REQ):
+		hci_cc_rd_txt_rsp(hdev, skb);
+		break;
+
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_AF_LIST_REQ):
+		hci_cc_af_list_rsp(hdev, skb);
+		break;
+
+	case hci_common_cmd_op_pack(HCI_OCF_FM_DEFAULT_DATA_READ):
+		hci_cc_riva_read_default_rsp(hdev, skb);
+		break;
+
+	case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_PEEK_DATA):
+		hci_cc_riva_peek_rsp(hdev, skb);
+		break;
+
+	case hci_common_cmd_op_pack(HCI_OCF_FM_GET_FEATURE_LIST):
+		hci_cc_feature_list_rsp(hdev, skb);
+		break;
+
+	case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_STATION_DBG_PARAM):
+		hci_cc_dbg_param_rsp(hdev, skb);
+		break;
+	case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_SET_TRANS_CONF_REQ):
+		hci_cc_fm_trans_set_conf_rsp(hdev, skb);
+		break;
+
+	case hci_status_param_op_pack(HCI_OCF_FM_READ_GRP_COUNTERS):
+		hci_cc_rds_grp_cntrs_rsp(hdev, skb);
+		break;
+	case hci_common_cmd_op_pack(HCI_OCF_FM_DO_CALIBRATION):
+		hci_cc_do_calibration_rsp(hdev, skb);
+		break;
+
+	case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_GET_TRANS_CONF_REQ):
+		hci_cc_fm_trans_get_conf_rsp(hdev, skb);
+		break;
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_CH_DET_THRESHOLD):
+		hci_cc_get_ch_det_threshold_rsp(hdev, skb);
+		break;
+	case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_BLND_TBL):
+		hci_cc_get_blend_tbl_rsp(hdev, skb);
+		break;
+	default:
+		FMDERR("%s opcode 0x%x\n", hdev->name, opcode);
+		break;
+	}
+
+}
+
+static inline void hci_cmd_status_event(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct hci_ev_cmd_status *ev = (void *) skb->data;
+
+	radio_hci_status_complete(hdev, ev->status);
+}
+
+static inline void hci_ev_tune_status(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	int i;
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return;
+	}
+	memcpy(&radio->fm_st_rsp.station_rsp, &skb->data[0],
+				sizeof(struct hci_ev_tune_status));
+	iris_q_event(radio, IRIS_EVT_TUNE_SUCC);
+
+	for (i = 0; i < IRIS_BUF_MAX; i++) {
+		if (i >= IRIS_BUF_RT_RDS)
+			kfifo_reset(&radio->data_buf[i]);
+	}
+	if (radio->fm_st_rsp.station_rsp.serv_avble)
+		iris_q_event(radio, IRIS_EVT_ABOVE_TH);
+	else
+		iris_q_event(radio, IRIS_EVT_BELOW_TH);
+
+	if (radio->fm_st_rsp.station_rsp.stereo_prg)
+		iris_q_event(radio, IRIS_EVT_STEREO);
+	else if (radio->fm_st_rsp.station_rsp.stereo_prg == 0)
+		iris_q_event(radio, IRIS_EVT_MONO);
+
+	if (radio->fm_st_rsp.station_rsp.rds_sync_status)
+		iris_q_event(radio, IRIS_EVT_RDS_AVAIL);
+	else
+		iris_q_event(radio, IRIS_EVT_RDS_NOT_AVAIL);
+}
+
+static inline void hci_ev_search_compl(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+	radio->search_on = 0;
+	iris_q_event(radio, IRIS_EVT_SEEK_COMPLETE);
+}
+
+static inline void hci_ev_srch_st_list_compl(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	struct hci_ev_srch_list_compl *ev;
+	int cnt;
+	int stn_num;
+	int rel_freq;
+	int abs_freq;
+	int len;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return;
+	}
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
+	if (!ev)
+		return;
+
+	ev->num_stations_found = skb->data[STN_NUM_OFFSET];
+	len = ev->num_stations_found * PARAMS_PER_STATION + STN_FREQ_OFFSET;
+
+	for (cnt = STN_FREQ_OFFSET, stn_num = 0;
+		(cnt < len) && (stn_num < ev->num_stations_found)
+		&& (stn_num < ARRAY_SIZE(ev->rel_freq));
+		cnt += PARAMS_PER_STATION, stn_num++) {
+		abs_freq = *((int *)&skb->data[cnt]);
+		rel_freq = abs_freq - radio->recv_conf.band_low_limit;
+		rel_freq = (rel_freq * 20) / KHZ_TO_MHZ;
+
+		ev->rel_freq[stn_num].rel_freq_lsb = GET_LSB(rel_freq);
+		ev->rel_freq[stn_num].rel_freq_msb = GET_MSB(rel_freq);
+	}
+
+	len = ev->num_stations_found * 2 + sizeof(ev->num_stations_found);
+	iris_q_event(radio, IRIS_EVT_NEW_SRCH_LIST);
+	iris_q_evt_data(radio, (char *)ev, len, IRIS_BUF_SRCH_LIST);
+	kfree(ev);
+}
+
+static inline void hci_ev_search_next(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+	iris_q_event(radio, IRIS_EVT_SCAN_NEXT);
+}
+
+static inline void hci_ev_stereo_status(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	__u8 st_status;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	st_status = *((__u8 *) skb->data);
+	if (st_status)
+		iris_q_event(radio, IRIS_EVT_STEREO);
+	else
+		iris_q_event(radio, IRIS_EVT_MONO);
+}
+
+static void hci_ev_raw_rds_group_data(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct iris_device *radio;
+	unsigned char blocknum, index;
+	struct rds_grp_data temp;
+	unsigned int mask_bit;
+	unsigned short int aid, agt, gtc;
+	unsigned short int carrier;
+
+	radio = video_get_drvdata(video_get_dev());
+	index = RDSGRP_DATA_OFFSET;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return;
+	}
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	for (blocknum = 0; blocknum < RDS_BLOCKS_NUM; blocknum++) {
+		temp.rdsBlk[blocknum].rdsLsb =
+			(skb->data[index]);
+		temp.rdsBlk[blocknum].rdsMsb =
+			(skb->data[index+1]);
+		index = index + 2;
+	}
+
+	aid = AID(temp.rdsBlk[3].rdsLsb, temp.rdsBlk[3].rdsMsb);
+	gtc = GTC(temp.rdsBlk[1].rdsMsb);
+	agt = AGT(temp.rdsBlk[1].rdsLsb);
+
+	if (gtc == GRP_3A) {
+		switch (aid) {
+		case ERT_AID:
+			/* calculate the grp mask for RDS grp
+			 * which will contain actual eRT text
+			 *
+			 * Bit Pos  0  1  2  3  4   5  6   7
+			 * Grp Type 0A 0B 1A 1B 2A  2B 3A  3B
+			 *
+			 * similarly for rest grps
+			 */
+			mask_bit = (((agt >> 1) << 1) + (agt & 1));
+			oda_agt = (1 << mask_bit);
+			utf_8_flag = (temp.rdsBlk[2].rdsLsb & 1);
+			formatting_dir = EXTRACT_BIT(temp.rdsBlk[2].rdsLsb,
+							ERT_FORMAT_DIR_BIT);
+			if (ert_carrier != agt)
+				iris_q_event(radio, IRIS_EVT_NEW_ODA);
+			ert_carrier = agt;
+			break;
+		case RT_PLUS_AID:
+			/* calculate the grp mask for RDS grp
+			 * which will contain actual eRT text
+			 *
+			 * Bit Pos  0  1  2  3  4   5  6   7
+			 * Grp Type 0A 0B 1A 1B 2A  2B 3A  3B
+			 *
+			 * similarly for rest grps
+			 */
+			mask_bit = (((agt >> 1) << 1) + (agt & 1));
+			oda_agt =  (1 << mask_bit);
+			/*Extract 5th bit of MSB (b7b6b5b4b3b2b1b0)*/
+			rt_ert_flag = EXTRACT_BIT(temp.rdsBlk[2].rdsMsb,
+					 RT_ERT_FLAG_BIT);
+			if (rt_plus_carrier != agt)
+				iris_q_event(radio, IRIS_EVT_NEW_ODA);
+			rt_plus_carrier = agt;
+			break;
+		default:
+			oda_agt = 0;
+			break;
+		}
+	} else {
+		carrier = gtc;
+		if (carrier == rt_plus_carrier)
+			hci_ev_rt_plus(radio, temp);
+		else if (carrier == ert_carrier)
+			hci_buff_ert(radio, &temp);
+	}
+}
+
+static void hci_buff_ert(struct iris_device *radio,
+	struct rds_grp_data *rds_buf)
+{
+	int i;
+	unsigned short int info_byte = 0;
+	unsigned short int byte_pair_index;
+
+	if (rds_buf == NULL) {
+		FMDERR("%s, rds buffer is null\n", __func__);
+		return;
+	}
+	byte_pair_index = AGT(rds_buf->rdsBlk[1].rdsLsb);
+	if (byte_pair_index == 0) {
+		c_byt_pair_index = 0;
+		ert_len = 0;
+	}
+	if (c_byt_pair_index == byte_pair_index) {
+		c_byt_pair_index++;
+		for (i = 2; i <= 3; i++) {
+			info_byte = rds_buf->rdsBlk[i].rdsLsb;
+			info_byte |= (rds_buf->rdsBlk[i].rdsMsb << 8);
+			ert_buf[ert_len++] = rds_buf->rdsBlk[i].rdsMsb;
+			ert_buf[ert_len++] = rds_buf->rdsBlk[i].rdsLsb;
+			if ((utf_8_flag == 0)
+				 && (info_byte == CARRIAGE_RETURN)) {
+				ert_len -= 2;
+				break;
+			} else if ((utf_8_flag == 1)
+					&&
+					(rds_buf->rdsBlk[i].rdsMsb
+						 == CARRIAGE_RETURN)) {
+				info_byte = CARRIAGE_RETURN;
+				ert_len -= 2;
+				break;
+			} else if ((utf_8_flag == 1)
+					&&
+					(rds_buf->rdsBlk[i].rdsLsb
+						 == CARRIAGE_RETURN)) {
+				info_byte = CARRIAGE_RETURN;
+				ert_len--;
+				break;
+			}
+		}
+		if ((byte_pair_index == MAX_ERT_SEGMENT) ||
+			(info_byte == CARRIAGE_RETURN)) {
+			hci_ev_ert(radio);
+			c_byt_pair_index = 0;
+			ert_len = 0;
+		}
+	} else {
+		ert_len = 0;
+		c_byt_pair_index = 0;
+	}
+}
+static void hci_ev_ert(struct iris_device *radio)
+
+{
+	char *data = NULL;
+
+	if (ert_len <= 0)
+		return;
+	data = kmalloc((ert_len + 3), GFP_ATOMIC);
+	if (data != NULL) {
+		data[0] = ert_len;
+		data[1] = utf_8_flag;
+		data[2] = formatting_dir;
+		memcpy((data + 3), ert_buf, ert_len);
+		iris_q_evt_data(radio, data, (ert_len + 3), IRIS_BUF_ERT);
+		iris_q_event(radio, IRIS_EVT_NEW_ERT);
+		kfree(data);
+	}
+}
+
+static void hci_ev_rt_plus(struct iris_device *radio,
+		 struct rds_grp_data rds_buf)
+{
+	char tag_type1, tag_type2;
+	char *data = NULL;
+	int len = 0;
+	unsigned short int agt;
+
+	agt = AGT(rds_buf.rdsBlk[1].rdsLsb);
+	/*right most 3 bits of Lsb of block 2
+	 * and left most 3 bits of Msb of block 3
+	 */
+	tag_type1 = (((agt & TAG1_MSB_MASK) << TAG1_MSB_OFFSET) |
+			 (rds_buf.rdsBlk[2].rdsMsb >> TAG1_LSB_OFFSET));
+
+	/*right most 1 bit of lsb of 3rd block
+	 * and left most 5 bits of Msb of 4th block
+	 */
+	tag_type2 = (((rds_buf.rdsBlk[2].rdsLsb & TAG2_MSB_MASK)
+			 << TAG2_MSB_OFFSET) |
+			 (rds_buf.rdsBlk[3].rdsMsb >> TAG2_LSB_OFFSET));
+
+	if (tag_type1 != DUMMY_CLASS)
+		len += RT_PLUS_LEN_1_TAG;
+	if (tag_type2 != DUMMY_CLASS)
+		len += RT_PLUS_LEN_1_TAG;
+
+	if (len != 0) {
+		len += 2;
+		data = kmalloc(len, GFP_ATOMIC);
+	} else {
+		FMDERR("Len is zero\n");
+		return;
+	}
+	if (data != NULL) {
+		data[0] = len;
+		len = 1;
+		data[len++] = rt_ert_flag;
+		if (tag_type1 != DUMMY_CLASS) {
+			data[len++] = tag_type1;
+			/*start position of tag1
+			 *right most 5 bits of msb of 3rd block
+			 *and left most bit of lsb of 3rd block
+			 */
+			data[len++] = (((rds_buf.rdsBlk[2].rdsMsb &
+						 TAG1_POS_MSB_MASK)
+						<< TAG1_POS_MSB_OFFSET)
+						|
+					(rds_buf.rdsBlk[2].rdsLsb >>
+						TAG1_POS_LSB_OFFSET));
+			/*length of tag1
+			 *left most 6 bits of lsb of 3rd block
+			 */
+			data[len++] = ((rds_buf.rdsBlk[2].rdsLsb
+						>> TAG1_LEN_OFFSET)
+							 &
+						TAG1_LEN_MASK) + 1;
+		}
+		if (tag_type2 != DUMMY_CLASS) {
+			data[len++] = tag_type2;
+			/*start position of tag2
+			 *right most 3 bit of msb of 4th block
+			 *and left most 3 bits of lsb of 4th block
+			 */
+			data[len++] = (((rds_buf.rdsBlk[3].rdsMsb
+						& TAG2_POS_MSB_MASK)
+						<< TAG2_POS_MSB_OFFSET)
+						|
+					(rds_buf.rdsBlk[3].rdsLsb
+						>> TAG2_POS_LSB_OFFSET));
+			/*length of tag2
+			 *right most 5 bits of lsb of 4th block
+			 */
+			data[len++] = (rds_buf.rdsBlk[3].rdsLsb
+						& TAG2_LEN_MASK) + 1;
+		}
+		iris_q_evt_data(radio, data, len, IRIS_BUF_RT_PLUS);
+		iris_q_event(radio,  IRIS_EVT_NEW_RT_PLUS);
+		kfree(data);
+	}
+}
+
+static inline void hci_ev_program_service(struct radio_hci_dev *hdev,
+		struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	int len;
+	char *data;
+
+	len = (skb->data[RDS_PS_LENGTH_OFFSET] * RDS_STRING) + RDS_OFFSET;
+	iris_q_event(radio, IRIS_EVT_NEW_PS_RDS);
+	data = kmalloc(len, GFP_ATOMIC);
+	if (!data)
+		return;
+
+	data[0] = skb->data[RDS_PS_LENGTH_OFFSET];
+	data[1] = skb->data[RDS_PTYPE];
+	data[2] = skb->data[RDS_PID_LOWER];
+	data[3] = skb->data[RDS_PID_HIGHER];
+	data[4] = 0;
+
+	memcpy(data+RDS_OFFSET, &skb->data[RDS_PS_DATA_OFFSET], len-RDS_OFFSET);
+
+	iris_q_evt_data(radio, data, len, IRIS_BUF_PS_RDS);
+
+	kfree(data);
+}
+
+
+static inline void hci_ev_radio_text(struct radio_hci_dev *hdev,
+	struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	int len = 0;
+	char *data;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	iris_q_event(radio, IRIS_EVT_NEW_RT_RDS);
+
+	while ((skb->data[len+RDS_OFFSET] != 0x0d) && (len < MAX_RT_LENGTH))
+		len++;
+	data = kmalloc(len+RDS_OFFSET, GFP_ATOMIC);
+	if (!data)
+		return;
+
+	data[0] = len;
+	data[1] = skb->data[RDS_PTYPE];
+	data[2] = skb->data[RDS_PID_LOWER];
+	data[3] = skb->data[RDS_PID_HIGHER];
+	data[4] = skb->data[RT_A_B_FLAG_OFFSET];
+
+	memcpy(data+RDS_OFFSET, &skb->data[RDS_OFFSET], len);
+	data[len+RDS_OFFSET] = 0x00;
+
+	iris_q_evt_data(radio, data, len+RDS_OFFSET, IRIS_BUF_RT_RDS);
+
+	kfree(data);
+}
+
+static void hci_ev_af_list(struct radio_hci_dev *hdev,
+	struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	struct hci_ev_af_list ev;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	ev.tune_freq = *((int *) &skb->data[0]);
+	ev.pi_code = *((__le16 *) &skb->data[PI_CODE_OFFSET]);
+	ev.af_size = skb->data[AF_SIZE_OFFSET];
+	if (ev.af_size > AF_LIST_MAX) {
+		FMDERR("AF list size received more than available size\n");
+		return;
+	}
+	memcpy(&ev.af_list[0], &skb->data[AF_LIST_OFFSET],
+					ev.af_size * sizeof(int));
+	iris_q_event(radio, IRIS_EVT_NEW_AF_LIST);
+	iris_q_evt_data(radio, (char *)&ev, (7 + ev.af_size * sizeof(int)),
+							IRIS_BUF_AF_LIST);
+}
+
+static void hci_ev_rds_lock_status(struct radio_hci_dev *hdev,
+	struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	__u8 rds_status;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+
+	rds_status = skb->data[0];
+
+	if (rds_status)
+		iris_q_event(radio, IRIS_EVT_RDS_AVAIL);
+	else
+		iris_q_event(radio, IRIS_EVT_RDS_NOT_AVAIL);
+}
+
+static void hci_ev_service_available(struct radio_hci_dev *hdev,
+	struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	u8 serv_avble;
+
+	if (unlikely(skb == NULL)) {
+		FMDERR("%s, socket buffer is null\n", __func__);
+		return;
+	}
+	serv_avble = skb->data[0];
+	if (serv_avble)
+		iris_q_event(radio, IRIS_EVT_ABOVE_TH);
+	else
+		iris_q_event(radio, IRIS_EVT_BELOW_TH);
+}
+
+static void hci_ev_rds_grp_complete(struct radio_hci_dev *hdev,
+	struct sk_buff *skb)
+{
+	struct iris_device *radio = video_get_drvdata(video_get_dev());
+
+	iris_q_event(radio, IRIS_EVT_TXRDSDONE);
+}
+
+void radio_hci_event_packet(struct radio_hci_dev *hdev, struct sk_buff *skb)
+{
+	struct radio_hci_event_hdr *hdr;
+	u8 event;
+
+	if (skb == NULL) {
+		FMDERR("Socket buffer is NULL\n");
+		return;
+	}
+
+	hdr = (void *) skb->data;
+	event = hdr->evt;
+
+	skb_pull(skb, RADIO_HCI_EVENT_HDR_SIZE);
+
+	FMDBG("event 0x%x", event);
+	switch (event) {
+	case HCI_EV_TUNE_STATUS:
+		hci_ev_tune_status(hdev, skb);
+		break;
+	case HCI_EV_SEARCH_PROGRESS:
+	case HCI_EV_SEARCH_RDS_PROGRESS:
+	case HCI_EV_SEARCH_LIST_PROGRESS:
+		hci_ev_search_next(hdev, skb);
+		break;
+	case HCI_EV_STEREO_STATUS:
+		hci_ev_stereo_status(hdev, skb);
+		break;
+	case HCI_EV_RDS_LOCK_STATUS:
+		hci_ev_rds_lock_status(hdev, skb);
+		break;
+	case HCI_EV_SERVICE_AVAILABLE:
+		hci_ev_service_available(hdev, skb);
+		break;
+	case HCI_EV_RDS_RX_DATA:
+		hci_ev_raw_rds_group_data(hdev, skb);
+		break;
+	case HCI_EV_PROGRAM_SERVICE:
+		hci_ev_program_service(hdev, skb);
+		break;
+	case HCI_EV_RADIO_TEXT:
+		hci_ev_radio_text(hdev, skb);
+		break;
+	case HCI_EV_FM_AF_LIST:
+		hci_ev_af_list(hdev, skb);
+		break;
+	case HCI_EV_TX_RDS_GRP_COMPL:
+		hci_ev_rds_grp_complete(hdev, skb);
+		break;
+	case HCI_EV_TX_RDS_CONT_GRP_COMPL:
+		break;
+
+	case HCI_EV_CMD_COMPLETE:
+		hci_cmd_complete_event(hdev, skb);
+		break;
+
+	case HCI_EV_CMD_STATUS:
+		hci_cmd_status_event(hdev, skb);
+		break;
+
+	case HCI_EV_SEARCH_COMPLETE:
+	case HCI_EV_SEARCH_RDS_COMPLETE:
+		hci_ev_search_compl(hdev, skb);
+		break;
+
+	case HCI_EV_SEARCH_LIST_COMPLETE:
+		hci_ev_srch_st_list_compl(hdev, skb);
+		break;
+
+	default:
+		break;
+	}
+}
+
+/*
+ * fops/IOCTL helper functions
+ */
+
+static int iris_search(struct iris_device *radio, int on, int dir)
+{
+	int retval = 0;
+	enum search_t srch;
+	int saved_val;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return -EINVAL;
+	}
+
+	srch = radio->g_search_mode & SRCH_MODE;
+	saved_val = radio->search_on;
+	radio->search_on = on;
+	if (on) {
+		switch (srch) {
+		case SCAN_FOR_STRONG:
+		case SCAN_FOR_WEAK:
+			radio->srch_st_list.srch_list_dir = dir;
+			radio->srch_st_list.srch_list_mode = srch;
+			retval = hci_fm_search_station_list(
+				&radio->srch_st_list, radio->fm_hdev);
+			break;
+		case RDS_SEEK_PTY:
+		case RDS_SCAN_PTY:
+		case RDS_SEEK_PI:
+			srch = srch - SEARCH_RDS_STNS_MODE_OFFSET;
+			radio->srch_rds.srch_station.srch_mode = srch;
+			radio->srch_rds.srch_station.srch_dir = dir;
+			radio->srch_rds.srch_station.scan_time =
+				radio->g_scan_time;
+			retval = hci_fm_search_rds_stations(&radio->srch_rds,
+				radio->fm_hdev);
+			break;
+		default:
+			radio->srch_st.srch_mode = srch;
+			radio->srch_st.scan_time = radio->g_scan_time;
+			radio->srch_st.srch_dir = dir;
+			retval = hci_fm_search_stations(
+				&radio->srch_st, radio->fm_hdev);
+			break;
+		}
+
+	} else {
+		retval = hci_cmd(HCI_FM_CANCEL_SEARCH_CMD, radio->fm_hdev);
+	}
+
+	if (retval < 0)
+		radio->search_on = saved_val;
+	return retval;
+}
+
+static int set_low_power_mode(struct iris_device *radio, int power_mode)
+{
+
+	int rds_grps_proc = 0x00;
+	int retval = 0;
+	struct hci_fm_rds_grp_req grp_3a;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return -EINVAL;
+	}
+
+	FMDBG("power mode old 0x%x new 0x%x", radio->power_mode, power_mode);
+	if (radio->power_mode != power_mode) {
+
+		if (power_mode) {
+			memcpy(&grp_3a, &radio->rds_grp,
+					sizeof(struct hci_fm_rds_grp_req));
+			/* Disable 3A group */
+			grp_3a.rds_grp_enable_mask &= ~FM_RDS_3A_GRP;
+			retval = hci_fm_rds_grp(&grp_3a, radio->fm_hdev);
+			if (retval < 0)
+				FMDERR("error in disable 3A group mask\n");
+			radio->event_mask = 0x00;
+			if (radio->af_jump_bit)
+				rds_grps_proc = 0x00 | AF_JUMP_ENABLE;
+			else
+				rds_grps_proc = 0x00;
+			retval = hci_fm_rds_grps_process(
+				&rds_grps_proc,
+				radio->fm_hdev);
+			if (retval < 0) {
+				FMDERR("Disable RDS failed\n");
+				return retval;
+			}
+			retval = hci_conf_event_mask(&radio->event_mask,
+				radio->fm_hdev);
+		} else {
+			/* Enable RDS group to normal */
+			retval = hci_fm_rds_grp(&radio->rds_grp,
+							radio->fm_hdev);
+			if (retval < 0)
+				FMDERR("error in enable 3A group mask\n");
+			radio->event_mask = SIG_LEVEL_INTR |
+					RDS_SYNC_INTR | AUDIO_CTRL_INTR;
+			retval = hci_conf_event_mask(&radio->event_mask,
+				radio->fm_hdev);
+			if (retval < 0) {
+				FMDERR("Enable Async events failed\n");
+				return retval;
+			}
+			retval = hci_fm_rds_grps_process(
+				&radio->g_rds_grp_proc_ps,
+				radio->fm_hdev);
+		}
+		radio->power_mode = power_mode;
+	}
+	return retval;
+}
+static int iris_recv_set_region(struct iris_device *radio, int req_region)
+{
+	int retval;
+	int saved_val;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return -EINVAL;
+	}
+	saved_val = radio->region;
+	radio->region = req_region;
+
+	retval = hci_set_fm_recv_conf(
+			&radio->recv_conf,
+			radio->fm_hdev);
+
+	if (retval < 0)
+		radio->region = saved_val;
+
+	return retval;
+}
+
+
+static int iris_trans_set_region(struct iris_device *radio, int req_region)
+{
+	int retval;
+	int saved_val;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return -EINVAL;
+	}
+
+	saved_val = radio->region;
+	radio->region = req_region;
+
+	retval = hci_set_fm_trans_conf(
+			&radio->trans_conf,
+				radio->fm_hdev);
+
+	if (retval < 0)
+		radio->region = saved_val;
+	return retval;
+}
+
+
+static int iris_set_freq(struct iris_device *radio, unsigned int freq)
+{
+
+	int retval;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return -EINVAL;
+	}
+	retval = hci_fm_tune_station(&freq, radio->fm_hdev);
+	if (retval < 0)
+		FMDERR("Error while setting the frequency : %d\n", retval);
+	return retval;
+}
+
+
+static int iris_vidioc_queryctrl(struct file *file, void *priv,
+		struct v4l2_queryctrl *qc)
+{
+	unsigned char i;
+	int retval = -EINVAL;
+
+	if (qc == NULL) {
+		FMDERR("%s, query ctrl is null\n", __func__);
+		return retval;
+	}
+	for (i = 0; i < ARRAY_SIZE(iris_v4l2_queryctrl); i++) {
+		if (qc->id && qc->id == iris_v4l2_queryctrl[i].id) {
+			memcpy(qc, &(iris_v4l2_queryctrl[i]), sizeof(*qc));
+			retval = 0;
+			break;
+		}
+	}
+
+	return retval;
+}
+
+static int iris_do_calibration(struct iris_device *radio)
+{
+	char cal_mode = 0x00;
+	int retval = 0x00;
+
+	FMDBG("radio %pK", radio);
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return -EINVAL;
+	}
+
+	cal_mode = PROCS_CALIB_MODE;
+	radio->mode = FM_CALIB;
+	retval = hci_cmd(HCI_FM_ENABLE_RECV_CMD,
+			radio->fm_hdev);
+	if (retval < 0) {
+		FMDERR("Enable failed before calibration %x\n", retval);
+		radio->mode = FM_OFF;
+		return retval;
+	}
+	retval = radio_hci_request(radio->fm_hdev, hci_fm_do_cal_req,
+		(unsigned long)cal_mode, RADIO_HCI_TIMEOUT);
+	if (retval < 0) {
+		FMDERR("Do Process calibration failed %x\n", retval);
+		radio->mode = FM_RECV;
+		return retval;
+	}
+	retval = hci_cmd(HCI_FM_DISABLE_RECV_CMD,
+			radio->fm_hdev);
+	if (retval < 0)
+		FMDERR("Disable Failed after calibration %d\n", retval);
+
+	return retval;
+}
+static int iris_vidioc_g_ctrl(struct file *file, void *priv,
+		struct v4l2_control *ctrl)
+{
+	struct iris_device *radio = video_get_drvdata(video_devdata(file));
+	int retval = 0;
+	int cf0;
+	struct hci_fm_def_data_rd_req rd;
+	int lsb, msb;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		retval = -EINVAL;
+		goto end;
+	}
+
+	if (ctrl == NULL) {
+		FMDERR("%s, v4l2 ctrl is null\n", __func__);
+		retval = -EINVAL;
+		goto end;
+	}
+
+	FMDBG("id 0x%x", ctrl->id);
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_VOLUME:
+		break;
+	case V4L2_CID_AUDIO_MUTE:
+		if (is_valid_hard_mute(radio->mute_mode.hard_mute))
+			ctrl->value = radio->mute_mode.hard_mute;
+		else
+			retval = -EINVAL;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SRCHMODE:
+		if (is_valid_srch_mode(radio->g_search_mode))
+			ctrl->value = radio->g_search_mode;
+		else
+			retval = -EINVAL;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SCANDWELL:
+		if (is_valid_scan_dwell_prd(radio->g_scan_time))
+			ctrl->value = radio->g_scan_time;
+		else
+			retval = -EINVAL;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SRCHON:
+		ctrl->value = radio->search_on;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_STATE:
+		if (is_valid_fm_state(radio->mode))
+			ctrl->value = radio->mode;
+		else
+			retval = -EINVAL;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_IOVERC:
+		retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
+		if (retval < 0)
+			return retval;
+		ctrl->value = radio->st_dbg_param.io_verc;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_INTDET:
+		retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
+		if (retval == 0)
+			ctrl->value = radio->st_dbg_param.in_det_out;
+		else
+			retval = -EINVAL;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_REGION:
+		ctrl->value = radio->region;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SIGNAL_TH:
+		retval = hci_cmd(HCI_FM_GET_SIGNAL_TH_CMD, radio->fm_hdev);
+		if ((retval == 0) &&
+			is_valid_sig_th(radio->sig_th.sig_threshold))
+			ctrl->value = radio->sig_th.sig_threshold;
+		else
+			retval = -EINVAL;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SRCH_PTY:
+		if (is_valid_pty(radio->srch_rds.srch_pty))
+			ctrl->value = radio->srch_rds.srch_pty;
+		else
+			retval = -EINVAL;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SRCH_PI:
+		if (is_valid_pi(radio->srch_rds.srch_pi))
+			ctrl->value = radio->srch_rds.srch_pi;
+		else
+			retval = -EINVAL;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SRCH_CNT:
+		if (is_valid_srch_station_cnt(
+			radio->srch_st_result.num_stations_found))
+			ctrl->value = radio->srch_st_result.num_stations_found;
+		else
+			retval = -EINVAL;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_EMPHASIS:
+		if (radio->mode == FM_RECV) {
+			retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_emphasis(radio->recv_conf.emphasis))
+				ctrl->value = radio->recv_conf.emphasis;
+			else
+				retval = -EINVAL;
+		} else if (radio->mode == FM_TRANS) {
+			retval =  hci_cmd(HCI_FM_GET_TX_CONFIG,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_emphasis(radio->trans_conf.emphasis))
+				ctrl->value = radio->trans_conf.emphasis;
+			else
+				retval = -EINVAL;
+		} else {
+			retval = -EINVAL;
+			FMDERR("Error in radio mode %d\n", retval);
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_RDS_STD:
+		if (radio->mode == FM_RECV) {
+			retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_rds_std(radio->recv_conf.rds_std))
+				ctrl->value = radio->recv_conf.rds_std;
+			else
+				retval = -EINVAL;
+		} else if (radio->mode == FM_TRANS) {
+			retval =  hci_cmd(HCI_FM_GET_TX_CONFIG,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_rds_std(radio->trans_conf.rds_std))
+				ctrl->value = radio->trans_conf.rds_std;
+			else
+				retval = -EINVAL;
+		} else {
+			retval = -EINVAL;
+			FMDERR("Error in radio mode %d\n", retval);
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SPACING:
+		if (radio->mode == FM_RECV) {
+			retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_chan_spacing(
+						radio->recv_conf.ch_spacing))
+				ctrl->value = radio->recv_conf.ch_spacing;
+			else
+				retval = -EINVAL;
+		} else {
+			retval = -EINVAL;
+			FMDERR("Error in radio mode %d\n", retval);
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_RDSON:
+		if (radio->mode == FM_RECV) {
+			retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+						radio->fm_hdev);
+			if ((retval == 0) &&
+				is_valid_rds_std(radio->recv_conf.rds_std))
+				ctrl->value = radio->recv_conf.rds_std;
+			else
+				retval = -EINVAL;
+		} else {
+			retval = -EINVAL;
+			FMDERR("Error in radio mode %d\n", retval);
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK:
+		ctrl->value = radio->rds_grp.rds_grp_enable_mask;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_RDSGROUP_PROC:
+	case V4L2_CID_PRIVATE_IRIS_PSALL:
+		ctrl->value = radio->g_rds_grp_proc_ps;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_RDSD_BUF:
+		ctrl->value = radio->rds_grp.rds_buf_size;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_LP_MODE:
+		ctrl->value = radio->power_mode;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_ANTENNA:
+		ctrl->value = radio->g_antenna;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SOFT_MUTE:
+		retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
+		if ((retval == 0) &&
+			is_valid_soft_mute(radio->mute_mode.soft_mute))
+			ctrl->value = radio->mute_mode.soft_mute;
+		else
+			retval = -EINVAL;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_DO_CALIBRATION:
+		retval = iris_do_calibration(radio);
+		break;
+	case V4L2_CID_PRIVATE_IRIS_GET_SINR:
+		if (radio->mode == FM_RECV) {
+			retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD,
+						 radio->fm_hdev);
+			if (retval == 0)
+				ctrl->value = radio->fm_st_rsp.station_rsp.sinr;
+		} else
+			retval = -EINVAL;
+		break;
+	case V4L2_CID_PRIVATE_INTF_HIGH_THRESHOLD:
+		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+		if (retval == 0)
+			ctrl->value = radio->ch_det_threshold.high_th;
+		break;
+	case V4L2_CID_PRIVATE_INTF_LOW_THRESHOLD:
+		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+		if (retval == 0)
+			ctrl->value = radio->ch_det_threshold.low_th;
+		break;
+	case V4L2_CID_PRIVATE_SINR_THRESHOLD:
+		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+		if (retval == 0)
+			ctrl->value = radio->ch_det_threshold.sinr;
+		break;
+	case V4L2_CID_PRIVATE_SINR_SAMPLES:
+		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+		if (retval == 0)
+			ctrl->value = radio->ch_det_threshold.sinr_samples;
+		break;
+	case V4L2_CID_PRIVATE_VALID_CHANNEL:
+		ctrl->value = radio->is_station_valid;
+		break;
+	case V4L2_CID_PRIVATE_AF_RMSSI_TH:
+		rd.mode = FM_RDS_CNFG_MODE;
+		rd.length = FM_RDS_CNFG_LEN;
+		rd.param_len = 0;
+		rd.param = 0;
+
+		retval = hci_def_data_read(&rd, radio->fm_hdev);
+		if (retval == 0) {
+			lsb = radio->default_data.data[AF_RMSSI_TH_LSB_OFFSET];
+			msb = radio->default_data.data[AF_RMSSI_TH_MSB_OFFSET];
+			ctrl->value = ((msb << 8) | lsb);
+		}
+		break;
+	case V4L2_CID_PRIVATE_AF_RMSSI_SAMPLES:
+		rd.mode = FM_RDS_CNFG_MODE;
+		rd.length = FM_RDS_CNFG_LEN;
+		rd.param_len = 0;
+		rd.param = 0;
+
+		retval = hci_def_data_read(&rd, radio->fm_hdev);
+		if (retval == 0)
+			ctrl->value =
+			radio->default_data.data[AF_RMSSI_SAMPLES_OFFSET];
+		break;
+	case V4L2_CID_PRIVATE_GOOD_CH_RMSSI_TH:
+		rd.mode = FM_RX_CONFG_MODE;
+		rd.length = FM_RX_CNFG_LEN;
+		rd.param_len = 0;
+		rd.param = 0;
+
+		retval = hci_def_data_read(&rd, radio->fm_hdev);
+		if (retval == 0) {
+			ctrl->value =
+			radio->default_data.data[GD_CH_RMSSI_TH_OFFSET];
+			if (ctrl->value > MAX_GD_CH_RMSSI_TH)
+				ctrl->value -= 256;
+		}
+		break;
+	case V4L2_CID_PRIVATE_SRCHALGOTYPE:
+		rd.mode = FM_RX_CONFG_MODE;
+		rd.length = FM_RX_CNFG_LEN;
+		rd.param_len = 0;
+		rd.param = 0;
+
+		retval = hci_def_data_read(&rd, radio->fm_hdev);
+		if (retval == 0)
+			ctrl->value =
+			radio->default_data.data[SRCH_ALGO_TYPE_OFFSET];
+		break;
+	case V4L2_CID_PRIVATE_SINRFIRSTSTAGE:
+		rd.mode = FM_RX_CONFG_MODE;
+		rd.length = FM_RX_CNFG_LEN;
+		rd.param_len = 0;
+		rd.param = 0;
+
+		retval = hci_def_data_read(&rd, radio->fm_hdev);
+		if (retval == 0) {
+			ctrl->value =
+			radio->default_data.data[SINRFIRSTSTAGE_OFFSET];
+			if (ctrl->value > MAX_SINR_FIRSTSTAGE)
+				ctrl->value -= 256;
+		}
+		break;
+	case V4L2_CID_PRIVATE_RMSSIFIRSTSTAGE:
+		rd.mode = FM_RX_CONFG_MODE;
+		rd.length = FM_RX_CNFG_LEN;
+		rd.param_len = 0;
+		rd.param = 0;
+
+		retval = hci_def_data_read(&rd, radio->fm_hdev);
+		if (retval == 0) {
+			ctrl->value =
+			radio->default_data.data[RMSSIFIRSTSTAGE_OFFSET];
+			if (ctrl->value > MAX_RMSSI_FIRSTSTAGE)
+				ctrl->value -= 256;
+		}
+		break;
+	case V4L2_CID_PRIVATE_CF0TH12:
+		rd.mode = FM_RX_CONFG_MODE;
+		rd.length = FM_RX_CNFG_LEN;
+		rd.param_len = 0;
+		rd.param = 0;
+
+		retval = hci_def_data_read(&rd, radio->fm_hdev);
+		if (retval == 0) {
+			ctrl->value =
+			radio->default_data.data[CF0TH12_BYTE1_OFFSET];
+			cf0 = radio->default_data.data[CF0TH12_BYTE2_OFFSET];
+			ctrl->value |= (cf0 << 8);
+			cf0 = radio->default_data.data[CF0TH12_BYTE3_OFFSET];
+			ctrl->value |= (cf0 << 16);
+			cf0 = radio->default_data.data[CF0TH12_BYTE4_OFFSET];
+			if (cf0 > 127)
+				cf0 -= 256;
+			ctrl->value |= (cf0 << 24);
+		}
+		break;
+	case V4L2_CID_PRIVATE_BLEND_SINRHI:
+		retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Failed to get blend table %d", retval);
+			goto end;
+		}
+		ctrl->value = radio->blend_tbl.scBlendSinrHi;
+		break;
+	case V4L2_CID_PRIVATE_BLEND_RMSSIHI:
+		retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Failed to get blend table %d", retval);
+			goto end;
+		}
+		ctrl->value = radio->blend_tbl.scBlendRmssiHi;
+		break;
+	default:
+		retval = -EINVAL;
+		break;
+	}
+
+end:
+	if (retval > 0)
+		retval = -EINVAL;
+	if (ctrl != NULL && retval < 0)
+		FMDERR("get control failed: %d, ret: %d\n", ctrl->id, retval);
+
+	return retval;
+}
+
+static int iris_vidioc_g_ext_ctrls(struct file *file, void *priv,
+			struct v4l2_ext_controls *ctrl)
+{
+	int retval = 0;
+	char *data = NULL;
+	struct iris_device *radio = video_get_drvdata(video_devdata(file));
+	struct hci_fm_def_data_rd_req default_data_rd;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		retval = -EINVAL;
+		goto end;
+	}
+
+	if ((ctrl == NULL) || (ctrl->count == 0)
+		|| (ctrl->controls == NULL)) {
+		FMDERR("%s, invalid v4l2 ctrl\n", __func__);
+		retval = -EINVAL;
+		goto end;
+	}
+
+	FMDBG("0x%x", ctrl->controls[0].id);
+	switch ((ctrl->controls[0]).id) {
+	case V4L2_CID_PRIVATE_IRIS_READ_DEFAULT:
+		data = (ctrl->controls[0]).string;
+		memset(&default_data_rd, 0, sizeof(default_data_rd));
+		if (copy_from_user(&default_data_rd.mode, data,
+					sizeof(default_data_rd))) {
+			retval = -EFAULT;
+			goto end;
+		}
+		retval = hci_def_data_read(&default_data_rd, radio->fm_hdev);
+		break;
+	default:
+		retval = -EINVAL;
+		break;
+	}
+
+end:
+	if (retval > 0)
+		retval = -EINVAL;
+
+	return retval;
+}
+
+static int iris_vidioc_s_ext_ctrls(struct file *file, void *priv,
+			struct v4l2_ext_controls *ctrl)
+{
+	int retval = 0;
+	size_t bytes_to_copy;
+	struct hci_fm_tx_ps tx_ps;
+	struct hci_fm_tx_rt tx_rt;
+	struct hci_fm_def_data_wr_req default_data;
+	struct hci_fm_set_cal_req_proc proc_cal_req;
+	struct hci_fm_set_spur_table_req spur_tbl_req;
+	char *spur_data;
+	char tmp_buf[2];
+
+	struct iris_device *radio = video_get_drvdata(video_devdata(file));
+	char *data = NULL;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null");
+		retval = -EINVAL;
+		goto end;
+	}
+
+	if ((ctrl == NULL) || (ctrl->count == 0)
+		|| (ctrl->controls == NULL)) {
+		FMDERR("%s, invalid v4l2 ctrl\n", __func__);
+		retval = -EINVAL;
+		goto end;
+	}
+
+	FMDBG("0x%x\n", ctrl->controls[0].id);
+	switch ((ctrl->controls[0]).id) {
+	case V4L2_CID_RDS_TX_PS_NAME:
+		FMDBG("In V4L2_CID_RDS_TX_PS_NAME\n");
+		/*Pass a sample PS string */
+
+		memset(tx_ps.ps_data, 0, MAX_PS_LENGTH);
+		bytes_to_copy = min_t(size_t, ctrl->controls[0].size,
+					MAX_PS_LENGTH);
+		data = (ctrl->controls[0]).string;
+
+		if (copy_from_user(tx_ps.ps_data,
+				data, bytes_to_copy)) {
+			FMDERR("%s: copy from user for tx ps name failed\n",
+				__func__);
+			retval = -EFAULT;
+			goto end;
+		} else {
+			tx_ps.ps_control =  0x01;
+			tx_ps.pi = radio->pi;
+			tx_ps.pty = radio->pty;
+			tx_ps.ps_repeatcount = radio->ps_repeatcount;
+			tx_ps.ps_num = (bytes_to_copy / PS_STRING_LEN);
+
+			retval = radio_hci_request(radio->fm_hdev,
+							hci_trans_ps_req,
+							(unsigned long)&tx_ps,
+							RADIO_HCI_TIMEOUT);
+		}
+		break;
+	case V4L2_CID_RDS_TX_RADIO_TEXT:
+		bytes_to_copy =
+		    min_t(size_t, (ctrl->controls[0]).size, MAX_RT_LENGTH);
+		data = (ctrl->controls[0]).string;
+
+		memset(tx_rt.rt_data, 0, MAX_RT_LENGTH);
+
+		if (copy_from_user(tx_rt.rt_data,
+				data, bytes_to_copy)) {
+			FMDERR("%s: copy from user for tx rt failed\n",
+				 __func__);
+			retval = -EFAULT;
+			goto end;
+		} else {
+			tx_rt.rt_control = 0x01;
+			tx_rt.pi = radio->pi;
+			tx_rt.pty = radio->pty;
+			tx_rt.rt_len = bytes_to_copy;
+
+			retval = radio_hci_request(radio->fm_hdev,
+							hci_trans_rt_req,
+							(unsigned long)&tx_rt,
+							RADIO_HCI_TIMEOUT);
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_WRITE_DEFAULT:
+		data = (ctrl->controls[0]).string;
+		memset(&default_data, 0, sizeof(default_data));
+		/*
+		 * Check if length of the 'FM Default Data' to be sent
+		 * is within the maximum  'FM Default Data' packet limit.
+		 * Max. 'FM Default Data' packet length is 251 bytes:
+		 *	1 byte    - XFR Mode
+		 *	1 byte    - length of the default data
+		 *	249 bytes - actual data to be configured
+		 */
+		if (ctrl->controls[0].size > (DEFAULT_DATA_SIZE + 2)) {
+			pr_err("%s: Default data buffer overflow\n", __func__);
+			retval = -EINVAL;
+			goto end;
+		}
+
+		/* copy only 'size' bytes of data as requested by user */
+		retval = copy_from_user(&default_data, data,
+			ctrl->controls[0].size);
+		if (retval > 0) {
+			FMDERR("Failed to copy %d bytes data\n", retval);
+			retval = -EFAULT;
+			goto end;
+		}
+		FMDBG("XFR Mode\t: 0x%x", default_data.mode);
+		FMDBG("XFR Data Length\t: %d\n", default_data.length);
+		/*
+		 * Check if the 'length' of the actual XFR data to be configured
+		 * is valid or not. Length of actual XFR data should be always
+		 * 2 bytes less than the total length of the 'FM Default Data'.
+		 * Length of 'FM Default Data' DEF_DATA_LEN: (1+1+XFR Data Size)
+		 * Length of 'Actual XFR Data' XFR_DATA_LEN: (DEF_DATA_LEN - 2)
+		 */
+		if (default_data.length != (ctrl->controls[0].size - 2)) {
+			FMDERR("Invalid 'length' parameter\n");
+			retval = -EINVAL;
+			goto end;
+		}
+		retval = hci_def_data_write(&default_data, radio->fm_hdev);
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SET_CALIBRATION:
+		data = (ctrl->controls[0]).string;
+		bytes_to_copy = (ctrl->controls[0]).size;
+		if (bytes_to_copy < PROCS_CALIB_SIZE) {
+			FMDERR("data is less than required size\n");
+			retval = -EFAULT;
+			goto end;
+		}
+		memset(proc_cal_req.data, 0, PROCS_CALIB_SIZE);
+		proc_cal_req.mode = PROCS_CALIB_MODE;
+		if (copy_from_user(&proc_cal_req.data[0],
+				data, sizeof(proc_cal_req.data))) {
+			retval = -EFAULT;
+			goto end;
+		}
+		retval = radio_hci_request(radio->fm_hdev,
+				hci_fm_set_cal_req_proc,
+				(unsigned long)&proc_cal_req,
+				 RADIO_HCI_TIMEOUT);
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SET_SPURTABLE:
+		memset(&spur_tbl_req, 0, sizeof(spur_tbl_req));
+		data = (ctrl->controls[0]).string;
+		if (copy_from_user(&bytes_to_copy, &((ctrl->controls[0]).size),
+					sizeof(bytes_to_copy))) {
+			retval = -EFAULT;
+			goto end;
+		}
+		if (copy_from_user(&tmp_buf[0], &data[0],
+					sizeof(tmp_buf))) {
+			retval = -EFAULT;
+			goto end;
+		}
+		spur_tbl_req.mode = tmp_buf[0];
+		spur_tbl_req.no_of_freqs_entries = tmp_buf[1];
+
+		if (((spur_tbl_req.no_of_freqs_entries * SPUR_DATA_LEN) !=
+					bytes_to_copy - 2) ||
+		    ((spur_tbl_req.no_of_freqs_entries * SPUR_DATA_LEN) >
+					2 * FM_SPUR_TBL_SIZE)) {
+			FMDERR("Invalid data len: data[1] = %d, bytes = %zu\n",
+				spur_tbl_req.no_of_freqs_entries,
+				bytes_to_copy);
+			retval = -EINVAL;
+			goto end;
+		}
+		spur_data =
+		    kmalloc((spur_tbl_req.no_of_freqs_entries * SPUR_DATA_LEN)
+							+ 2, GFP_ATOMIC);
+		if (!spur_data) {
+			retval = -EFAULT;
+			goto end;
+		}
+		if (copy_from_user(spur_data,
+				&data[2], (bytes_to_copy - 2))) {
+			kfree(spur_data);
+			retval = -EFAULT;
+			goto end;
+		}
+
+		if (spur_tbl_req.no_of_freqs_entries <= ENTRIES_EACH_CMD) {
+			memcpy(&spur_tbl_req.spur_data[0], spur_data,
+				(spur_tbl_req.no_of_freqs_entries *
+							SPUR_DATA_LEN));
+			retval = radio_hci_request(radio->fm_hdev,
+					hci_fm_set_spur_tbl_req,
+					(unsigned long)&spur_tbl_req,
+					RADIO_HCI_TIMEOUT);
+		} else {
+			memcpy(&spur_tbl_req.spur_data[0], spur_data,
+				(ENTRIES_EACH_CMD * SPUR_DATA_LEN));
+			retval = radio_hci_request(radio->fm_hdev,
+					hci_fm_set_spur_tbl_req,
+					(unsigned long)&spur_tbl_req,
+					RADIO_HCI_TIMEOUT);
+			if (retval < 0) {
+				FMDERR("Spur command failed to execute\n");
+				kfree(spur_data);
+				goto end;
+			}
+			spur_tbl_req.mode = 0x02;/* 02-Continue mode */
+			spur_tbl_req.no_of_freqs_entries =
+				spur_tbl_req.no_of_freqs_entries
+					- ENTRIES_EACH_CMD;
+			memcpy(&spur_tbl_req.spur_data[0],
+				&spur_data[ENTRIES_EACH_CMD * SPUR_DATA_LEN],
+			(spur_tbl_req.no_of_freqs_entries * SPUR_DATA_LEN));
+			retval = radio_hci_request(radio->fm_hdev,
+					hci_fm_set_spur_tbl_req,
+					(unsigned long)&spur_tbl_req,
+					RADIO_HCI_TIMEOUT);
+		}
+		kfree(spur_data);
+		break;
+	default:
+		FMDBG("Shouldn't reach here\n");
+		retval = -EINVAL;
+		goto end;
+	}
+
+end:
+	if (retval > 0)
+		retval = -EINVAL;
+
+	return retval;
+}
+
+static int iris_vidioc_s_ctrl(struct file *file, void *priv,
+		struct v4l2_control *ctrl)
+{
+	struct iris_device *radio = video_get_drvdata(video_devdata(file));
+	int retval = 0;
+	unsigned int rds_grps_proc = 0;
+	__u8 temp_val = 0;
+	int saved_val;
+	unsigned long arg = 0;
+	struct hci_fm_tx_ps tx_ps = {0};
+	struct hci_fm_tx_rt tx_rt = {0};
+	struct hci_fm_def_data_rd_req rd;
+	struct hci_fm_def_data_wr_req wrd;
+	char sinr_th, sinr;
+	__u8 intf_det_low_th, intf_det_high_th, intf_det_out;
+	unsigned int spur_freq;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		retval = -EINVAL;
+		goto end;
+	}
+
+	if (ctrl == NULL) {
+		FMDERR("%s, v4l2 ctrl is null\n", __func__);
+		retval = -EINVAL;
+		goto end;
+	}
+
+	FMDBG("id 0x%x", ctrl->id);
+	switch (ctrl->id) {
+	case V4L2_CID_PRIVATE_IRIS_TX_TONE:
+		if (!is_valid_tone(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s: tone value is not valid\n", __func__);
+			goto end;
+		}
+		saved_val = radio->tone_freq;
+		radio->tone_freq = ctrl->value;
+		retval = radio_hci_request(radio->fm_hdev,
+				hci_fm_tone_generator, arg,
+				RADIO_HCI_TIMEOUT);
+		if (retval < 0) {
+			FMDERR("Error while setting the tone %d\n", retval);
+			radio->tone_freq = saved_val;
+		}
+		break;
+	case V4L2_CID_AUDIO_VOLUME:
+		break;
+	case V4L2_CID_AUDIO_MUTE:
+		if (!is_valid_hard_mute(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s: hard mute value is not valid\n", __func__);
+			goto end;
+		}
+		saved_val = radio->mute_mode.hard_mute;
+		radio->mute_mode.hard_mute = ctrl->value;
+		retval = hci_set_fm_mute_mode(
+				&radio->mute_mode,
+				radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Error while set FM hard mute %d\n",
+				retval);
+			radio->mute_mode.hard_mute = saved_val;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SRCHMODE:
+		if (is_valid_srch_mode(ctrl->value)) {
+			radio->g_search_mode = ctrl->value;
+		} else {
+			FMDERR("%s: srch mode is not valid\n", __func__);
+			retval = -EINVAL;
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SCANDWELL:
+		if (is_valid_scan_dwell_prd(ctrl->value)) {
+			radio->g_scan_time = ctrl->value;
+		} else {
+			FMDERR("%s: scandwell period is not valid\n", __func__);
+			retval = -EINVAL;
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SRCHON:
+		iris_search(radio, ctrl->value, SRCH_DIR_UP);
+		break;
+	case V4L2_CID_PRIVATE_IRIS_STATE:
+		switch (ctrl->value) {
+		case FM_RECV:
+			if (radio->mode != FM_OFF) {
+				FMDERR("FM mode is not off %d\n", radio->mode);
+				retval = -EINVAL;
+				goto end;
+			}
+			if (is_enable_rx_possible(radio) != 0) {
+				FMDERR("%s: fm is not in proper state\n",
+					 __func__);
+				retval = -EINVAL;
+				goto end;
+			}
+			radio->mode = FM_RECV_TURNING_ON;
+			retval = hci_cmd(HCI_FM_ENABLE_RECV_CMD,
+							 radio->fm_hdev);
+			if (retval < 0) {
+				FMDERR("Enabling RECV FM fail %d\n", retval);
+				radio->mode = FM_OFF;
+				goto end;
+			} else {
+				retval = initialise_recv(radio);
+				if (retval < 0) {
+					FMDERR("Error while initialising\n");
+					FMDERR("radio %d\n", retval);
+					hci_cmd(HCI_FM_DISABLE_RECV_CMD,
+							radio->fm_hdev);
+					radio->mode = FM_OFF;
+					goto end;
+				}
+			}
+			if (radio->mode == FM_RECV_TURNING_ON) {
+				radio->mode = FM_RECV;
+				iris_q_event(radio, IRIS_EVT_RADIO_READY);
+			}
+			break;
+		case FM_TRANS:
+			if (is_enable_tx_possible(radio) != 0) {
+				retval = -EINVAL;
+				goto end;
+			}
+			radio->mode = FM_TRANS_TURNING_ON;
+			retval = hci_cmd(HCI_FM_ENABLE_TRANS_CMD,
+							 radio->fm_hdev);
+			if (retval < 0) {
+				FMDERR("Enabling TRANS FM fail %d\n", retval);
+				radio->mode = FM_OFF;
+				goto end;
+			} else {
+				retval = initialise_trans(radio);
+				if (retval < 0) {
+					FMDERR("Error while initialising\n");
+					FMDERR("radio %d\n", retval);
+					hci_cmd(HCI_FM_DISABLE_TRANS_CMD,
+								radio->fm_hdev);
+					radio->mode = FM_OFF;
+					goto end;
+				}
+			}
+			if (radio->mode == FM_TRANS_TURNING_ON) {
+				radio->mode = FM_TRANS;
+				iris_q_event(radio, IRIS_EVT_RADIO_READY);
+			}
+			break;
+		case FM_OFF:
+			radio->spur_table_size = 0;
+			switch (radio->mode) {
+			case FM_RECV:
+				radio->mode = FM_TURNING_OFF;
+				retval = hci_cmd(HCI_FM_DISABLE_RECV_CMD,
+						radio->fm_hdev);
+				if (retval < 0) {
+					FMDERR("Err on disable recv FM\n");
+					FMDERR("%d\n", retval);
+					radio->mode = FM_RECV;
+					goto end;
+				}
+				break;
+			case FM_TRANS:
+				radio->mode = FM_TURNING_OFF;
+				retval = hci_cmd(HCI_FM_DISABLE_TRANS_CMD,
+						radio->fm_hdev);
+
+				if (retval < 0) {
+					FMDERR("Err disabling trans FM\n");
+					FMDERR("%d\n", retval);
+					radio->mode = FM_TRANS;
+					goto end;
+				}
+				break;
+			default:
+				retval = -EINVAL;
+			}
+			break;
+		default:
+			retval = -EINVAL;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_REGION:
+		if (radio->mode == FM_RECV) {
+			retval = iris_recv_set_region(radio, ctrl->value);
+		} else {
+			if (radio->mode == FM_TRANS) {
+				retval = iris_trans_set_region(radio,
+						ctrl->value);
+			} else {
+				FMDERR("%s: fm is not in proper state\n",
+					__func__);
+				retval = -EINVAL;
+				goto end;
+			}
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SIGNAL_TH:
+		if (!is_valid_sig_th(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s: sig threshold is not valid\n", __func__);
+			goto end;
+		}
+		temp_val = ctrl->value;
+		retval = hci_fm_set_signal_threshold(
+				&temp_val,
+				radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Error while setting signal threshold\n");
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SRCH_PTY:
+		if (is_valid_pty(ctrl->value)) {
+			radio->srch_rds.srch_pty = ctrl->value;
+			radio->srch_st_list.srch_pty = ctrl->value;
+		} else {
+			FMDERR("%s: pty is not valid\n", __func__);
+			retval = -EINVAL;
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SRCH_PI:
+		if (is_valid_pi(ctrl->value)) {
+			radio->srch_rds.srch_pi = ctrl->value;
+		} else {
+			retval = -EINVAL;
+			FMDERR("%s: Pi is not valid\n", __func__);
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SRCH_CNT:
+		if (is_valid_srch_station_cnt(ctrl->value)) {
+			radio->srch_st_list.srch_list_max = ctrl->value;
+		} else {
+			retval = -EINVAL;
+			FMDERR("%s: srch station count is not valid\n",
+				__func__);
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SPACING:
+		if (!is_valid_chan_spacing(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s: channel spacing is not valid\n", __func__);
+			goto end;
+		}
+		if (radio->mode == FM_RECV) {
+			saved_val = radio->recv_conf.ch_spacing;
+			radio->recv_conf.ch_spacing = ctrl->value;
+			retval = hci_set_fm_recv_conf(
+					&radio->recv_conf,
+						radio->fm_hdev);
+			if (retval < 0) {
+				FMDERR("Error in setting channel spacing\n");
+				radio->recv_conf.ch_spacing = saved_val;
+				goto end;
+			}
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_EMPHASIS:
+		if (!is_valid_emphasis(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s, emphasis is not valid\n", __func__);
+			goto end;
+		}
+		switch (radio->mode) {
+		case FM_RECV:
+			saved_val = radio->recv_conf.emphasis;
+			radio->recv_conf.emphasis = ctrl->value;
+			retval = hci_set_fm_recv_conf(
+					&radio->recv_conf,
+						radio->fm_hdev);
+			if (retval < 0) {
+				FMDERR("Error in setting emphasis\n");
+				radio->recv_conf.emphasis = saved_val;
+				goto end;
+			}
+			break;
+		case FM_TRANS:
+			saved_val = radio->trans_conf.emphasis;
+			radio->trans_conf.emphasis = ctrl->value;
+			retval = hci_set_fm_trans_conf(
+					&radio->trans_conf,
+						radio->fm_hdev);
+			if (retval < 0) {
+				FMDERR("Error in setting emphasis\n");
+				radio->trans_conf.emphasis = saved_val;
+				goto end;
+			}
+			break;
+		default:
+			retval = -EINVAL;
+			FMDERR("FM mode is unknown %d\n", radio->mode);
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_RDS_STD:
+		if (!is_valid_rds_std(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s: rds std is not valid\n", __func__);
+			goto end;
+		}
+		switch (radio->mode) {
+		case FM_RECV:
+			saved_val = radio->recv_conf.rds_std;
+			radio->recv_conf.rds_std = ctrl->value;
+			retval = hci_set_fm_recv_conf(
+					&radio->recv_conf,
+						radio->fm_hdev);
+			if (retval < 0) {
+				FMDERR("Error in rds_std\n");
+				radio->recv_conf.rds_std = saved_val;
+				goto end;
+			}
+			break;
+		case FM_TRANS:
+			saved_val = radio->trans_conf.rds_std;
+			radio->trans_conf.rds_std = ctrl->value;
+			retval = hci_set_fm_trans_conf(
+					&radio->trans_conf,
+						radio->fm_hdev);
+			if (retval < 0) {
+				FMDERR("Error in rds_Std\n");
+				radio->trans_conf.rds_std = saved_val;
+				goto end;
+			}
+			break;
+		default:
+			retval = -EINVAL;
+			FMDERR("%s: fm is not in proper state\n", __func__);
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_RDSON:
+		if (!is_valid_rds_std(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s: rds std is not valid\n", __func__);
+			goto end;
+		}
+		switch (radio->mode) {
+		case FM_RECV:
+			saved_val = radio->recv_conf.rds_std;
+			radio->recv_conf.rds_std = ctrl->value;
+			retval = hci_set_fm_recv_conf(
+					&radio->recv_conf,
+						radio->fm_hdev);
+			if (retval < 0) {
+				FMDERR("Error in rds_std\n");
+				radio->recv_conf.rds_std = saved_val;
+				goto end;
+			}
+			break;
+		case FM_TRANS:
+			saved_val = radio->trans_conf.rds_std;
+			radio->trans_conf.rds_std = ctrl->value;
+			retval = hci_set_fm_trans_conf(
+					&radio->trans_conf,
+						radio->fm_hdev);
+			if (retval < 0) {
+				FMDERR("Error in rds_Std\n");
+				radio->trans_conf.rds_std = saved_val;
+				goto end;
+			}
+			break;
+		default:
+			retval = -EINVAL;
+			FMDERR("%s: fm is not in proper state\n", __func__);
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_RDSGROUP_MASK:
+		saved_val = radio->rds_grp.rds_grp_enable_mask;
+		grp_mask = (grp_mask | oda_agt | ctrl->value);
+		radio->rds_grp.rds_grp_enable_mask = grp_mask;
+		radio->rds_grp.rds_buf_size = 1;
+		radio->rds_grp.en_rds_change_filter = 0;
+		retval = hci_fm_rds_grp(&radio->rds_grp, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("error in setting group mask\n");
+			radio->rds_grp.rds_grp_enable_mask = saved_val;
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_RDSGROUP_PROC:
+		saved_val = radio->g_rds_grp_proc_ps;
+		radio->g_rds_grp_proc_ps |= ctrl->value;
+		retval = hci_fm_rds_grps_process(
+				&radio->g_rds_grp_proc_ps,
+				radio->fm_hdev);
+		if (retval < 0) {
+			radio->g_rds_grp_proc_ps = saved_val;
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_RDSD_BUF:
+		radio->rds_grp.rds_buf_size = ctrl->value;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_PSALL:
+		saved_val = radio->g_rds_grp_proc_ps;
+		rds_grps_proc = (ctrl->value << RDS_PS_SIMPLE_OFFSET);
+		radio->g_rds_grp_proc_ps |= rds_grps_proc;
+		retval = hci_fm_rds_grps_process(
+				&radio->g_rds_grp_proc_ps,
+				radio->fm_hdev);
+		if (retval < 0) {
+			radio->g_rds_grp_proc_ps = saved_val;
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_AF_JUMP:
+		saved_val = radio->g_rds_grp_proc_ps;
+		/*Clear the current AF jump settings*/
+		radio->g_rds_grp_proc_ps &= ~(1 << RDS_AF_JUMP_OFFSET);
+		radio->af_jump_bit = ctrl->value;
+		rds_grps_proc = 0x00;
+		rds_grps_proc = (ctrl->value << RDS_AF_JUMP_OFFSET);
+		radio->g_rds_grp_proc_ps |= rds_grps_proc;
+		retval = hci_fm_rds_grps_process(
+				&radio->g_rds_grp_proc_ps,
+				radio->fm_hdev);
+		if (retval < 0) {
+			radio->g_rds_grp_proc_ps = saved_val;
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_LP_MODE:
+		set_low_power_mode(radio, ctrl->value);
+		break;
+	case V4L2_CID_PRIVATE_IRIS_ANTENNA:
+		if (!is_valid_antenna(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s: antenna type is not valid\n", __func__);
+			goto end;
+		}
+		temp_val = ctrl->value;
+		retval = hci_fm_set_antenna(&temp_val, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Set Antenna failed retval = %x\n", retval);
+			goto end;
+		}
+		radio->g_antenna =  ctrl->value;
+		break;
+	case V4L2_CID_RDS_TX_PTY:
+		if (is_valid_pty(ctrl->value)) {
+			radio->pty = ctrl->value;
+		} else {
+			retval = -EINVAL;
+			FMDERR("%s: pty is not valid\n", __func__);
+			goto end;
+		}
+		break;
+	case V4L2_CID_RDS_TX_PI:
+		if (is_valid_pi(ctrl->value)) {
+			radio->pi = ctrl->value;
+		} else {
+			retval = -EINVAL;
+			FMDERR("%s: pi is not valid\n", __func__);
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_PS_NAME:
+		tx_ps.ps_control =  0x00;
+		retval = radio_hci_request(radio->fm_hdev, hci_trans_ps_req,
+				(unsigned long)&tx_ps, RADIO_HCI_TIMEOUT);
+		break;
+	case V4L2_CID_PRIVATE_IRIS_STOP_RDS_TX_RT:
+		tx_rt.rt_control =  0x00;
+		retval = radio_hci_request(radio->fm_hdev, hci_trans_rt_req,
+				(unsigned long)&tx_rt, RADIO_HCI_TIMEOUT);
+		break;
+	case V4L2_CID_PRIVATE_IRIS_TX_SETPSREPEATCOUNT:
+		if (is_valid_ps_repeat_cnt(ctrl->value)) {
+			radio->ps_repeatcount = ctrl->value;
+		} else {
+			retval = -EINVAL;
+			FMDERR("%s: ps repeat count is not valid\n", __func__);
+			goto end;
+		}
+		break;
+	case V4L2_CID_TUNE_POWER_LEVEL:
+		if (ctrl->value > FM_TX_PWR_LVL_MAX)
+			ctrl->value = FM_TX_PWR_LVL_MAX;
+		if (ctrl->value < FM_TX_PWR_LVL_0)
+			ctrl->value = FM_TX_PWR_LVL_0;
+		rd.mode = FM_TX_PHY_CFG_MODE;
+		rd.length = FM_TX_PHY_CFG_LEN;
+		rd.param_len = 0x00;
+		rd.param = 0x00;
+
+		retval = hci_def_data_read(&rd, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Default data read failed for PHY_CFG %d\n",
+				retval);
+			goto end;
+		}
+		memset(&wrd, 0, sizeof(wrd));
+		wrd.mode = FM_TX_PHY_CFG_MODE;
+		wrd.length = FM_TX_PHY_CFG_LEN;
+		memcpy(&wrd.data, &radio->default_data.data,
+					radio->default_data.ret_data_len);
+		wrd.data[FM_TX_PWR_GAIN_OFFSET] =
+				(ctrl->value) * FM_TX_PWR_LVL_STEP_SIZE;
+		retval = hci_def_data_write(&wrd, radio->fm_hdev);
+		if (retval < 0)
+			FMDERR("Default write failed for PHY_TXGAIN %d\n",
+				retval);
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SOFT_MUTE:
+		if (!is_valid_soft_mute(ctrl->value)) {
+			retval = -EINVAL;
+			FMDERR("%s: soft mute is not valid\n", __func__);
+			goto end;
+		}
+		saved_val = radio->mute_mode.soft_mute;
+		radio->mute_mode.soft_mute = ctrl->value;
+		retval = hci_set_fm_mute_mode(
+				&radio->mute_mode,
+				radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Error while setting FM soft mute %d\n",
+				retval);
+			radio->mute_mode.soft_mute = saved_val;
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_RIVA_ACCS_ADDR:
+		radio->riva_data_req.cmd_params.start_addr = ctrl->value;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_RIVA_ACCS_LEN:
+		if (is_valid_peek_len(ctrl->value)) {
+			radio->riva_data_req.cmd_params.length = ctrl->value;
+		} else {
+			retval = -EINVAL;
+			FMDERR("%s: riva access len is not valid\n", __func__);
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_RIVA_POKE:
+		if (radio->riva_data_req.cmd_params.length <=
+		    MAX_RIVA_PEEK_RSP_SIZE) {
+#ifdef CONFIG_COMPAT
+			retval = copy_from_user(
+					radio->riva_data_req.data,
+					(void *)(__s64)ctrl->value,
+					radio->riva_data_req.cmd_params.length);
+#else
+			retval = copy_from_user(
+					radio->riva_data_req.data,
+					(void *)ctrl->value,
+					radio->riva_data_req.cmd_params.length);
+#endif
+			if (retval != 0) {
+				retval = -retval;
+				goto end;
+			}
+			radio->riva_data_req.cmd_params.subopcode =
+						RIVA_POKE_OPCODE;
+			retval = hci_poke_data(
+					&radio->riva_data_req,
+					radio->fm_hdev);
+		} else {
+			FMDERR("Can not copy into driver buffer\n");
+			retval = -EINVAL;
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SSBI_ACCS_ADDR:
+		radio->ssbi_data_accs.start_addr = ctrl->value;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SSBI_POKE:
+		radio->ssbi_data_accs.data = ctrl->value;
+		retval = hci_ssbi_poke_reg(&radio->ssbi_data_accs,
+								radio->fm_hdev);
+		break;
+	case V4L2_CID_PRIVATE_IRIS_RIVA_PEEK:
+		radio->riva_data_req.cmd_params.subopcode = RIVA_PEEK_OPCODE;
+		ctrl->value = hci_peek_data(&radio->riva_data_req.cmd_params,
+						radio->fm_hdev);
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SSBI_PEEK:
+		radio->ssbi_peek_reg.start_address = ctrl->value;
+		hci_ssbi_peek_reg(&radio->ssbi_peek_reg, radio->fm_hdev);
+		break;
+	case V4L2_CID_PRIVATE_IRIS_RDS_GRP_COUNTERS:
+		if (is_valid_reset_cntr(ctrl->value)) {
+			temp_val = ctrl->value;
+			hci_read_grp_counters(&temp_val, radio->fm_hdev);
+		} else {
+			FMDERR("%s: reset counter value is not valid\n",
+				__func__);
+			retval = -EINVAL;
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_IRIS_HLSI:
+		if (!is_valid_hlsi(ctrl->value)) {
+			FMDERR("%s: hlsi value is not valid\n", __func__);
+			retval = -EINVAL;
+			goto end;
+		}
+		retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD,
+						radio->fm_hdev);
+		if (retval)
+			goto end;
+		saved_val = radio->recv_conf.hlsi;
+		radio->recv_conf.hlsi = ctrl->value;
+		retval = hci_set_fm_recv_conf(
+					&radio->recv_conf,
+						radio->fm_hdev);
+		if (retval < 0)
+			radio->recv_conf.hlsi = saved_val;
+		break;
+	case V4L2_CID_PRIVATE_IRIS_SET_NOTCH_FILTER:
+		if (is_valid_notch_filter(ctrl->value)) {
+			temp_val = ctrl->value;
+			retval = hci_set_notch_filter(&temp_val,
+							radio->fm_hdev);
+		} else {
+			FMDERR("%s: notch filter is not valid\n", __func__);
+			retval = -EINVAL;
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_INTF_HIGH_THRESHOLD:
+		if (!is_valid_intf_det_hgh_th(ctrl->value)) {
+			FMDERR("%s: intf high threshold is not valid\n",
+				__func__);
+			retval = -EINVAL;
+			goto end;
+		}
+		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Fail to get chnl det thresholds %d\n", retval);
+			goto end;
+		}
+		saved_val = radio->ch_det_threshold.high_th;
+		radio->ch_det_threshold.high_th = ctrl->value;
+		retval = hci_set_ch_det_thresholds_req(&radio->ch_det_threshold,
+							 radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Failed to set High det threshold %d\n", retval);
+			radio->ch_det_threshold.high_th = saved_val;
+			goto end;
+		}
+		break;
+
+	case V4L2_CID_PRIVATE_INTF_LOW_THRESHOLD:
+		if (!is_valid_intf_det_low_th(ctrl->value)) {
+			FMDERR("%s: intf det low threshold is not valid\n",
+				__func__);
+			retval = -EINVAL;
+			goto end;
+		}
+		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Fail to get chnl det thresholds %d\n", retval);
+			goto end;
+		}
+		saved_val = radio->ch_det_threshold.low_th;
+		radio->ch_det_threshold.low_th = ctrl->value;
+		retval = hci_set_ch_det_thresholds_req(&radio->ch_det_threshold,
+							 radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Fail to Set Low det threshold %d\n", retval);
+			radio->ch_det_threshold.low_th = saved_val;
+			goto end;
+		}
+		break;
+
+	case V4L2_CID_PRIVATE_SINR_THRESHOLD:
+		if (!is_valid_sinr_th(ctrl->value)) {
+			FMDERR("%s: sinr threshold is not valid\n", __func__);
+			retval = -EINVAL;
+			goto end;
+		}
+		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Fail to get chnl det thresholds %d\n", retval);
+			goto end;
+		}
+		saved_val = radio->ch_det_threshold.sinr;
+		radio->ch_det_threshold.sinr = ctrl->value;
+		retval = hci_set_ch_det_thresholds_req(&radio->ch_det_threshold,
+							 radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Fail to set SINR threshold %d\n", retval);
+			radio->ch_det_threshold.sinr = saved_val;
+			goto end;
+		}
+		break;
+
+	case V4L2_CID_PRIVATE_SINR_SAMPLES:
+		if (!is_valid_sinr_samples(ctrl->value)) {
+			FMDERR("%s: sinr samples count is not valid\n",
+				__func__);
+			retval = -EINVAL;
+			goto end;
+		}
+		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Fail to get chnl det thresholds %d\n", retval);
+			goto end;
+		}
+		saved_val = radio->ch_det_threshold.sinr_samples;
+		radio->ch_det_threshold.sinr_samples = ctrl->value;
+		retval = hci_set_ch_det_thresholds_req(&radio->ch_det_threshold,
+							 radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Fail to set SINR samples %d\n", retval);
+			radio->ch_det_threshold.sinr_samples = saved_val;
+			goto end;
+		}
+		break;
+
+	case V4L2_CID_PRIVATE_IRIS_SRCH_ALGORITHM:
+	case V4L2_CID_PRIVATE_IRIS_SET_AUDIO_PATH:
+		/*
+		 * These private controls are place holders to keep the
+		 * driver compatible with changes done in the frameworks
+		 * which are specific to TAVARUA.
+		 */
+		retval = 0;
+		break;
+	case V4L2_CID_PRIVATE_SPUR_FREQ:
+		if (radio->spur_table_size >= MAX_SPUR_FREQ_LIMIT) {
+			FMDERR("%s: Spur Table Full\n", __func__);
+			retval = -1;
+		} else
+			radio->spur_data.freq[radio->spur_table_size] =
+				ctrl->value;
+		break;
+	case V4L2_CID_PRIVATE_SPUR_FREQ_RMSSI:
+		if (radio->spur_table_size >= MAX_SPUR_FREQ_LIMIT) {
+			FMDERR("%s: Spur Table Full\n", __func__);
+			retval = -1;
+		} else
+			radio->spur_data.rmssi[radio->spur_table_size] =
+				ctrl->value;
+		break;
+	case V4L2_CID_PRIVATE_SPUR_SELECTION:
+		if (radio->spur_table_size >= MAX_SPUR_FREQ_LIMIT) {
+			FMDERR("%s: Spur Table Full\n", __func__);
+			retval = -1;
+		} else {
+			radio->spur_data.enable[radio->spur_table_size] =
+				ctrl->value;
+			radio->spur_table_size++;
+		}
+		break;
+	case V4L2_CID_PRIVATE_UPDATE_SPUR_TABLE:
+		update_spur_table(radio);
+		break;
+	case V4L2_CID_PRIVATE_VALID_CHANNEL:
+		retval = hci_cmd(HCI_FM_GET_DET_CH_TH_CMD, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("%s: Failed to determine channel validity\n",
+				__func__);
+			goto end;
+		} else {
+			sinr_th = radio->ch_det_threshold.sinr;
+			intf_det_low_th = radio->ch_det_threshold.low_th;
+			intf_det_high_th = radio->ch_det_threshold.high_th;
+		}
+		if (!is_valid_sinr_th(sinr_th) ||
+			!is_valid_intf_det_low_th(intf_det_low_th) ||
+			!is_valid_intf_det_hgh_th(intf_det_high_th)) {
+			retval = -EINVAL;
+			goto end;
+		}
+		retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("%s: Failed to determine channel validity\n",
+				__func__);
+			goto end;
+		} else
+			sinr = radio->fm_st_rsp.station_rsp.sinr;
+
+		retval = hci_cmd(HCI_FM_STATION_DBG_PARAM_CMD, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("%s: Failed to determine channel validity\n",
+				 __func__);
+			goto end;
+		} else
+			intf_det_out = radio->st_dbg_param.in_det_out;
+
+		if ((sinr >= sinr_th) && (intf_det_out >= intf_det_low_th) &&
+			(intf_det_out <= intf_det_high_th))
+			radio->is_station_valid = VALID_CHANNEL;
+		else
+			radio->is_station_valid = INVALID_CHANNEL;
+		break;
+	case V4L2_CID_PRIVATE_AF_RMSSI_TH:
+		rd.mode = FM_RDS_CNFG_MODE;
+		rd.length = FM_RDS_CNFG_LEN;
+		rd.param_len = 0;
+		rd.param = 0;
+
+		retval = hci_def_data_read(&rd, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("default data read failed %x\n", retval);
+			goto end;
+		}
+		wrd.mode = FM_RDS_CNFG_MODE;
+		wrd.length = FM_RDS_CNFG_LEN;
+		memcpy(&wrd.data, &radio->default_data.data,
+				radio->default_data.ret_data_len);
+		wrd.data[AF_RMSSI_TH_LSB_OFFSET] = ((ctrl->value) & 255);
+		wrd.data[AF_RMSSI_TH_MSB_OFFSET] = ((ctrl->value) >> 8);
+		retval = hci_def_data_write(&wrd, radio->fm_hdev);
+		if (retval < 0)
+			FMDERR("set AF jump RMSSI threshold failed\n");
+		break;
+	case V4L2_CID_PRIVATE_AF_RMSSI_SAMPLES:
+		rd.mode = FM_RDS_CNFG_MODE;
+		rd.length = FM_RDS_CNFG_LEN;
+		rd.param_len = 0;
+		rd.param = 0;
+
+		retval = hci_def_data_read(&rd, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("default data read failed %x\n", retval);
+			goto end;
+		}
+		wrd.mode = FM_RDS_CNFG_MODE;
+		wrd.length = FM_RDS_CNFG_LEN;
+		memcpy(&wrd.data, &radio->default_data.data,
+				radio->default_data.ret_data_len);
+		wrd.data[AF_RMSSI_SAMPLES_OFFSET] = ctrl->value;
+		retval = hci_def_data_write(&wrd, radio->fm_hdev);
+		if (retval < 0)
+			FMDERR("set AF jump RMSSI Samples failed\n");
+		break;
+	case V4L2_CID_PRIVATE_GOOD_CH_RMSSI_TH:
+		rd.mode = FM_RX_CONFG_MODE;
+		rd.length = FM_RX_CNFG_LEN;
+		rd.param_len = 0;
+		rd.param = 0;
+
+		retval = hci_def_data_read(&rd, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("default data read failed %x\n", retval);
+			goto end;
+		}
+		wrd.mode = FM_RX_CONFG_MODE;
+		wrd.length = FM_RX_CNFG_LEN;
+		memcpy(&wrd.data, &radio->default_data.data,
+				radio->default_data.ret_data_len);
+		wrd.data[GD_CH_RMSSI_TH_OFFSET] = ctrl->value;
+		retval = hci_def_data_write(&wrd, radio->fm_hdev);
+		if (retval < 0)
+			FMDERR("set good channel RMSSI th failed\n");
+		break;
+	case V4L2_CID_PRIVATE_SRCHALGOTYPE:
+		rd.mode = FM_RX_CONFG_MODE;
+		rd.length = FM_RX_CNFG_LEN;
+		rd.param_len = 0;
+		rd.param = 0;
+
+		retval = hci_def_data_read(&rd, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("default data read failed %x\n", retval);
+			goto end;
+		}
+		wrd.mode = FM_RX_CONFG_MODE;
+		wrd.length = FM_RX_CNFG_LEN;
+		memcpy(&wrd.data, &radio->default_data.data,
+				radio->default_data.ret_data_len);
+		wrd.data[SRCH_ALGO_TYPE_OFFSET] = ctrl->value;
+		retval = hci_def_data_write(&wrd, radio->fm_hdev);
+		if (retval < 0)
+			FMDERR("set Search Algo Type failed\n");
+		break;
+	case V4L2_CID_PRIVATE_SINRFIRSTSTAGE:
+		rd.mode = FM_RX_CONFG_MODE;
+		rd.length = FM_RX_CNFG_LEN;
+		rd.param_len = 0;
+		rd.param = 0;
+
+		retval = hci_def_data_read(&rd, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("default data read failed %x\n", retval);
+			goto end;
+		}
+		wrd.mode = FM_RX_CONFG_MODE;
+		wrd.length = FM_RX_CNFG_LEN;
+		memcpy(&wrd.data, &radio->default_data.data,
+				radio->default_data.ret_data_len);
+		wrd.data[SINRFIRSTSTAGE_OFFSET] = ctrl->value;
+		retval = hci_def_data_write(&wrd, radio->fm_hdev);
+		if (retval < 0)
+			FMDERR("set SINR First Stage failed\n");
+		break;
+	case V4L2_CID_PRIVATE_RMSSIFIRSTSTAGE:
+		rd.mode = FM_RX_CONFG_MODE;
+		rd.length = FM_RX_CNFG_LEN;
+		rd.param_len = 0;
+		rd.param = 0;
+
+		retval = hci_def_data_read(&rd, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("default data read failed %x\n", retval);
+			goto end;
+		}
+		wrd.mode = FM_RX_CONFG_MODE;
+		wrd.length = FM_RX_CNFG_LEN;
+		memcpy(&wrd.data, &radio->default_data.data,
+				radio->default_data.ret_data_len);
+		wrd.data[RMSSIFIRSTSTAGE_OFFSET] = ctrl->value;
+		retval = hci_def_data_write(&wrd, radio->fm_hdev);
+		if (retval < 0)
+			FMDERR("set RMSSI First Stage failed\n");
+		break;
+	case V4L2_CID_PRIVATE_CF0TH12:
+		rd.mode = FM_RX_CONFG_MODE;
+		rd.length = FM_RX_CNFG_LEN;
+		rd.param_len = 0;
+		rd.param = 0;
+
+		retval = hci_def_data_read(&rd, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("default data read failed %x\n", retval);
+			goto end;
+		}
+		wrd.mode = FM_RX_CONFG_MODE;
+		wrd.length = FM_RX_CNFG_LEN;
+		memcpy(&wrd.data, &radio->default_data.data,
+				radio->default_data.ret_data_len);
+		wrd.data[CF0TH12_BYTE1_OFFSET] = (ctrl->value & 255);
+		wrd.data[CF0TH12_BYTE2_OFFSET] = ((ctrl->value >> 8) & 255);
+		wrd.data[CF0TH12_BYTE3_OFFSET] = ((ctrl->value >> 16) & 255);
+		wrd.data[CF0TH12_BYTE4_OFFSET] = ((ctrl->value >> 24) & 255);
+		retval = hci_def_data_write(&wrd, radio->fm_hdev);
+		if (retval < 0)
+			FMDERR("set CF0 Threshold failed\n");
+		break;
+	case V4L2_CID_PRIVATE_RXREPEATCOUNT:
+		rd.mode = RDS_PS0_XFR_MODE;
+		rd.length = RDS_PS0_LEN;
+		rd.param_len = 0;
+		rd.param = 0;
+
+		retval = hci_def_data_read(&rd, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("default data read failed for PS0 %x\n", retval);
+			goto end;
+		}
+		wrd.mode = RDS_PS0_XFR_MODE;
+		wrd.length = RDS_PS0_LEN;
+		memcpy(&wrd.data, &radio->default_data.data,
+				radio->default_data.ret_data_len);
+		wrd.data[RX_REPEATE_BYTE_OFFSET] = ctrl->value;
+
+		retval = hci_def_data_write(&wrd, radio->fm_hdev);
+		if (retval < 0)
+			FMDERR("set RxRePeat count failed\n");
+		break;
+	case V4L2_CID_PRIVATE_IRIS_GET_SPUR_TBL:
+		spur_freq = ctrl->value;
+		retval = radio_hci_request(radio->fm_hdev,
+					hci_fm_get_spur_tbl_data,
+					(unsigned long)spur_freq,
+					RADIO_HCI_TIMEOUT);
+		if (retval < 0)
+			FMDERR("get Spur data failed\n");
+		break;
+	case V4L2_CID_PRIVATE_BLEND_SINRHI:
+		if (!is_valid_blend_value(ctrl->value)) {
+			FMDERR("%s: blend sinr count is not valid\n",
+				__func__);
+			retval = -EINVAL;
+			goto end;
+		}
+		retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Failed to get blend table %d\n", retval);
+			goto end;
+		}
+		radio->blend_tbl.scBlendSinrHi = ctrl->value;
+		retval = hci_set_blend_tbl_req(&radio->blend_tbl,
+					 radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Failed to set blend table %d\n", retval);
+			goto end;
+		}
+		break;
+	case V4L2_CID_PRIVATE_BLEND_RMSSIHI:
+		if (!is_valid_blend_value(ctrl->value)) {
+			FMDERR("%s: blend rmssi count is not valid\n",
+				__func__);
+			retval = -EINVAL;
+			goto end;
+		}
+		retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Failed to get blend table %d\n", retval);
+			goto end;
+		}
+		radio->blend_tbl.scBlendRmssiHi = ctrl->value;
+		retval = hci_set_blend_tbl_req(&radio->blend_tbl,
+					 radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Failed to set blend table %d\n", retval);
+			goto end;
+		}
+		break;
+	default:
+		retval = -EINVAL;
+		break;
+	}
+
+end:
+	if (retval > 0)
+		retval = -EINVAL;
+
+	return retval;
+}
+
+static int update_spur_table(struct iris_device *radio)
+{
+	struct hci_fm_def_data_wr_req default_data;
+	int len = 0, index = 0, offset = 0, i = 0;
+	int retval = 0, temp = 0, cnt = 0;
+
+	memset(&default_data, 0, sizeof(default_data));
+
+	/* Pass the mode of SPUR_CLK */
+	default_data.mode = CKK_SPUR;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return -EINVAL;
+	}
+	temp = radio->spur_table_size;
+	for (cnt = 0; cnt < (temp / 5); cnt++) {
+		offset = 0;
+		/*
+		 * Program the spur entries in spur table in following order:
+		 *    Spur index
+		 *    Length of the spur data
+		 *    Spur Data:
+		 *        MSB of the spur frequency
+		 *        LSB of the spur frequency
+		 *        Enable/Disable the spur frequency
+		 *        RMSSI value of the spur frequency
+		 */
+		default_data.data[offset++] = ENTRY_0 + cnt;
+		for (i = 0; i < SPUR_ENTRIES_PER_ID; i++) {
+			default_data.data[offset++] = GET_FREQ(COMPUTE_SPUR(
+				radio->spur_data.freq[index]), 0);
+			default_data.data[offset++] = GET_FREQ(COMPUTE_SPUR(
+				radio->spur_data.freq[index]), 1);
+			default_data.data[offset++] =
+				radio->spur_data.enable[index];
+			default_data.data[offset++] =
+				radio->spur_data.rmssi[index];
+			index++;
+		}
+		len = (SPUR_ENTRIES_PER_ID * SPUR_DATA_SIZE);
+		default_data.length = (len + 1);
+		retval = hci_def_data_write(&default_data, radio->fm_hdev);
+		if (retval < 0) {
+			FMDBG("%s: Failed to configure entries for ID : %d\n",
+				__func__, default_data.data[0]);
+			return retval;
+		}
+	}
+
+	/* Compute balance SPUR frequencies to be programmed */
+	temp %= SPUR_ENTRIES_PER_ID;
+	if (temp > 0) {
+		offset = 0;
+		default_data.data[offset++] = (radio->spur_table_size / 5);
+		for (i = 0; i < temp; i++) {
+			default_data.data[offset++] = GET_FREQ(COMPUTE_SPUR(
+				radio->spur_data.freq[index]), 0);
+			default_data.data[offset++] = GET_FREQ(COMPUTE_SPUR(
+				radio->spur_data.freq[index]), 1);
+			default_data.data[offset++] =
+				radio->spur_data.enable[index];
+			default_data.data[offset++] =
+				radio->spur_data.rmssi[index];
+			index++;
+		}
+		len = (temp * SPUR_DATA_SIZE);
+		default_data.length = (len + 1);
+		retval = hci_def_data_write(&default_data, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("%s: Failed to configure entries for ID : %d\n",
+				__func__, default_data.data[0]);
+			return retval;
+		}
+	}
+
+	return retval;
+}
+
+static int iris_vidioc_g_tuner(struct file *file, void *priv,
+		struct v4l2_tuner *tuner)
+{
+	int retval;
+	struct iris_device *radio = video_get_drvdata(video_devdata(file));
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return -EINVAL;
+	}
+	if (tuner == NULL) {
+		FMDERR("%s, tuner is null\n", __func__);
+		return -EINVAL;
+	}
+	if (tuner->index > 0) {
+		FMDERR("Invalid Tuner Index\n");
+		return -EINVAL;
+	}
+	if (radio->mode == FM_RECV) {
+		retval = hci_cmd(HCI_FM_GET_STATION_PARAM_CMD, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("Failed to Get station params\n");
+			return retval;
+		}
+		tuner->type = V4L2_TUNER_RADIO;
+		tuner->rangelow  =
+			radio->recv_conf.band_low_limit * TUNE_PARAM;
+		tuner->rangehigh =
+			radio->recv_conf.band_high_limit * TUNE_PARAM;
+		tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+		tuner->capability = V4L2_TUNER_CAP_LOW;
+		tuner->signal = radio->fm_st_rsp.station_rsp.rssi;
+		tuner->audmode = radio->fm_st_rsp.station_rsp.stereo_prg;
+		tuner->afc = 0;
+	} else if (radio->mode == FM_TRANS) {
+		retval = hci_cmd(HCI_FM_GET_TX_CONFIG, radio->fm_hdev);
+		if (retval < 0) {
+			FMDERR("get Tx config failed %d\n", retval);
+			return retval;
+		}
+		tuner->type = V4L2_TUNER_RADIO;
+		tuner->rangelow =
+			radio->trans_conf.band_low_limit * TUNE_PARAM;
+		tuner->rangehigh =
+			radio->trans_conf.band_high_limit * TUNE_PARAM;
+	} else
+		return -EINVAL;
+	return 0;
+}
+
+static int iris_vidioc_s_tuner(struct file *file, void *priv,
+		const struct v4l2_tuner *tuner)
+{
+	struct iris_device *radio = video_get_drvdata(video_devdata(file));
+	int retval = 0;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return -EINVAL;
+	}
+
+	if (tuner == NULL) {
+		FMDERR("%s, tuner is null\n", __func__);
+		return -EINVAL;
+	}
+
+	if (tuner->index > 0)
+		return -EINVAL;
+
+	if (radio->mode == FM_RECV) {
+		radio->recv_conf.band_low_limit = tuner->rangelow / TUNE_PARAM;
+		radio->recv_conf.band_high_limit =
+			tuner->rangehigh / TUNE_PARAM;
+		if (tuner->audmode == V4L2_TUNER_MODE_MONO) {
+			radio->stereo_mode.stereo_mode = 0x01;
+			retval = hci_set_fm_stereo_mode(
+					&radio->stereo_mode,
+					radio->fm_hdev);
+		} else {
+			radio->stereo_mode.stereo_mode = 0x00;
+			retval = hci_set_fm_stereo_mode(
+					&radio->stereo_mode,
+					radio->fm_hdev);
+		}
+		if (retval < 0)
+			FMDERR(": set tuner failed with %d\n", retval);
+		return retval;
+	} else if (radio->mode == FM_TRANS) {
+		radio->trans_conf.band_low_limit = tuner->rangelow / TUNE_PARAM;
+		radio->trans_conf.band_high_limit =
+			tuner->rangehigh / TUNE_PARAM;
+	} else
+		return -EINVAL;
+
+	return retval;
+}
+
+static int iris_vidioc_g_frequency(struct file *file, void *priv,
+		struct v4l2_frequency *freq)
+{
+	struct iris_device *radio = video_get_drvdata(video_devdata(file));
+
+	if ((freq != NULL) && (radio != NULL)) {
+		freq->frequency =
+			radio->fm_st_rsp.station_rsp.station_freq * TUNE_PARAM;
+	} else
+		return -EINVAL;
+	return 0;
+}
+
+static int iris_vidioc_s_frequency(struct file *file, void *priv,
+					const struct v4l2_frequency *freq)
+{
+	struct iris_device  *radio = video_get_drvdata(video_devdata(file));
+	int retval = -1;
+	u32 f;
+
+	if (freq == NULL) {
+		FMDERR("%s, v4l2 freq is null\n", __func__);
+		return -EINVAL;
+	}
+	f = (freq->frequency / TUNE_PARAM);
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return -EINVAL;
+	}
+	if (freq->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
+
+	/* We turn off RDS prior to tuning to a new station.
+	 * because of a bug in SoC which prevents tuning
+	 * during RDS transmission.
+	 */
+	if (radio->mode == FM_TRANS
+		&& (radio->trans_conf.rds_std == 0 ||
+			radio->trans_conf.rds_std == 1)) {
+		radio->prev_trans_rds = radio->trans_conf.rds_std;
+		radio->trans_conf.rds_std = 2;
+		hci_set_fm_trans_conf(&radio->trans_conf,
+				radio->fm_hdev);
+	}
+
+	retval = iris_set_freq(radio, f);
+
+	if (radio->mode == FM_TRANS
+		 && radio->trans_conf.rds_std == 2
+			&& (radio->prev_trans_rds == 1
+				|| radio->prev_trans_rds == 0)) {
+		radio->trans_conf.rds_std = radio->prev_trans_rds;
+		hci_set_fm_trans_conf(&radio->trans_conf,
+				radio->fm_hdev);
+	}
+
+	if (retval < 0)
+		FMDERR(" set frequency failed with %d\n", retval);
+	return retval;
+}
+
+static int iris_fops_release(struct file *file)
+{
+	struct iris_device *radio = video_get_drvdata(video_devdata(file));
+	int retval = 0;
+
+	FMDBG("radio %pK", radio);
+
+	if (radio == NULL)
+		return -EINVAL;
+
+	FMDBG("state %d", radio->mode);
+	mutex_lock(&radio->lock);
+
+	if (radio->mode == FM_OFF)
+		goto end;
+
+	if (radio->mode == FM_RECV) {
+		radio->is_fm_closing = true;
+		radio->mode = FM_TURNING_OFF;
+		retval = hci_cmd_uninterruptible(HCI_FM_DISABLE_RECV_CMD,
+				radio->fm_hdev);
+		radio->mode = FM_OFF;
+		radio->is_fm_closing = false;
+	} else if (radio->mode == FM_TRANS) {
+		radio->is_fm_closing = true;
+		radio->mode = FM_TURNING_OFF;
+		retval = hci_cmd_uninterruptible(HCI_FM_DISABLE_TRANS_CMD,
+				radio->fm_hdev);
+		radio->mode = FM_OFF;
+		radio->is_fm_closing = false;
+	} else if (radio->mode == FM_CALIB) {
+		radio->mode = FM_OFF;
+		mutex_unlock(&radio->lock);
+		return retval;
+	}
+end:
+	FMDBG("mode %d", radio->mode);
+	mutex_lock(&fm_smd_enable);
+	if (radio->fm_hdev != NULL)
+		radio->fm_hdev->close_smd();
+	mutex_unlock(&fm_smd_enable);
+
+	mutex_unlock(&radio->lock);
+
+	if (retval < 0)
+		FMDERR("Err on disable FM %d\n", retval);
+
+	FMDBG("ret %d", retval);
+	return retval;
+}
+
+static int iris_vidioc_dqbuf(struct file *file, void *priv,
+				struct v4l2_buffer *buffer)
+{
+	struct iris_device  *radio = video_get_drvdata(video_devdata(file));
+	enum iris_buf_t buf_type = -1;
+	unsigned char buf_fifo[STD_BUF_SIZE] = {0};
+	struct kfifo *data_fifo = NULL;
+	unsigned char *buf = NULL;
+	unsigned int len = 0, retval = -1;
+
+	FMDBG("buffer %pK", buffer);
+
+	if ((radio == NULL) || (buffer == NULL)) {
+		FMDERR("radio/buffer is NULL\n");
+		return -ENXIO;
+	}
+	buf_type = buffer->index;
+	buf = (unsigned char *)buffer->m.userptr;
+	len = buffer->length;
+
+	if ((buf_type < IRIS_BUF_MAX) && (buf_type >= 0)) {
+		data_fifo = &radio->data_buf[buf_type];
+		if (buf_type == IRIS_BUF_EVENTS)
+			if (wait_event_interruptible(radio->event_queue,
+				kfifo_len(data_fifo)) < 0)
+				return -EINTR;
+	} else {
+		FMDERR("invalid buffer type\n");
+		return -EINVAL;
+	}
+	if (len <= STD_BUF_SIZE) {
+		buffer->bytesused = kfifo_out_locked(data_fifo, &buf_fifo[0],
+					len, &radio->buf_lock[buf_type]);
+	} else {
+		FMDERR("kfifo_out_locked can not use len more than 128\n");
+		return -EINVAL;
+	}
+	retval = copy_to_user(buf, &buf_fifo[0], buffer->bytesused);
+	if (retval > 0) {
+		FMDERR("Failed to copy %d bytes of data\n", retval);
+		return -EAGAIN;
+	}
+
+	return retval;
+}
+
+static int iris_vidioc_g_fmt_type_private(struct file *file, void *priv,
+						struct v4l2_format *f)
+{
+	return 0;
+
+}
+
+static int iris_vidioc_s_hw_freq_seek(struct file *file, void *priv,
+					const struct v4l2_hw_freq_seek *seek)
+{
+	struct iris_device *radio = video_get_drvdata(video_devdata(file));
+	int dir;
+
+	if (seek == NULL) {
+		FMDERR("%s, v4l2_hw_freq_seek is null\n", __func__);
+		return -EINVAL;
+	}
+	if (seek->seek_upward)
+		dir = SRCH_DIR_UP;
+	else
+		dir = SRCH_DIR_DOWN;
+	return iris_search(radio, CTRL_ON, dir);
+}
+
+static int iris_vidioc_querycap(struct file *file, void *priv,
+	struct v4l2_capability *capability)
+{
+	struct iris_device *radio;
+
+	FMDBG("caps %pK", capability);
+
+	radio = video_get_drvdata(video_devdata(file));
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return -EINVAL;
+	}
+	if (capability == NULL) {
+		FMDERR("%s, capability struct is null\n", __func__);
+		return -EINVAL;
+	}
+	strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
+	strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
+
+	strlcpy(radio->g_cap.driver, DRIVER_NAME, sizeof(radio->g_cap.driver));
+	strlcpy(radio->g_cap.card, DRIVER_CARD, sizeof(radio->g_cap.card));
+
+	radio->g_cap.capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	capability->capabilities = radio->g_cap.capabilities;
+	return 0;
+}
+
+static int initialise_recv(struct iris_device *radio)
+{
+	int retval;
+
+	FMDBG("radio %pK", radio);
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return -EINVAL;
+	}
+
+	radio->mute_mode.soft_mute = CTRL_ON;
+	retval = hci_set_fm_mute_mode(&radio->mute_mode,
+					radio->fm_hdev);
+
+	if (retval < 0) {
+		FMDERR("Failed to enable Smute\n");
+		return retval;
+	}
+
+	radio->stereo_mode.stereo_mode = CTRL_OFF;
+	radio->stereo_mode.sig_blend = sig_blend;
+	radio->stereo_mode.intf_blend = CTRL_ON;
+	radio->stereo_mode.most_switch = CTRL_ON;
+	retval = hci_set_fm_stereo_mode(&radio->stereo_mode,
+						radio->fm_hdev);
+
+	if (retval < 0) {
+		FMDERR("Failed to set stereo mode\n");
+		return retval;
+	}
+
+	radio->event_mask = SIG_LEVEL_INTR | RDS_SYNC_INTR | AUDIO_CTRL_INTR;
+	retval = hci_conf_event_mask(&radio->event_mask, radio->fm_hdev);
+	if (retval < 0) {
+		FMDERR("Enable Async events failed\n");
+		return retval;
+	}
+
+	retval = hci_cmd(HCI_FM_GET_RECV_CONF_CMD, radio->fm_hdev);
+	if (retval < 0)
+		FMDERR("Failed to get the Recv Config\n");
+	return retval;
+}
+
+static int initialise_trans(struct iris_device *radio)
+{
+
+	int retval;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null");
+		return -EINVAL;
+	}
+
+	retval = hci_cmd(HCI_FM_GET_TX_CONFIG, radio->fm_hdev);
+	if (retval < 0)
+		FMDERR("get frequency failed %d\n", retval);
+
+	return retval;
+}
+
+static int is_enable_rx_possible(struct iris_device *radio)
+{
+	int retval = 1;
+
+	if (unlikely(radio == NULL)) {
+		FMDERR(":radio is null\n");
+		return -EINVAL;
+	}
+
+	if (radio->mode == FM_OFF || radio->mode == FM_RECV)
+		retval = 0;
+
+	return retval;
+}
+
+static int is_enable_tx_possible(struct iris_device *radio)
+{
+	int retval = 1;
+
+	if (radio->mode == FM_OFF || radio->mode == FM_TRANS)
+		retval = 0;
+
+	return retval;
+}
+
+static const struct v4l2_ioctl_ops iris_ioctl_ops = {
+	.vidioc_querycap              = iris_vidioc_querycap,
+	.vidioc_queryctrl             = iris_vidioc_queryctrl,
+	.vidioc_g_ctrl                = iris_vidioc_g_ctrl,
+	.vidioc_s_ctrl                = iris_vidioc_s_ctrl,
+	.vidioc_g_tuner               = iris_vidioc_g_tuner,
+	.vidioc_s_tuner               = iris_vidioc_s_tuner,
+	.vidioc_g_frequency           = iris_vidioc_g_frequency,
+	.vidioc_s_frequency           = iris_vidioc_s_frequency,
+	.vidioc_s_hw_freq_seek        = iris_vidioc_s_hw_freq_seek,
+	.vidioc_dqbuf                 = iris_vidioc_dqbuf,
+	.vidioc_g_fmt_type_private    = iris_vidioc_g_fmt_type_private,
+	.vidioc_s_ext_ctrls           = iris_vidioc_s_ext_ctrls,
+	.vidioc_g_ext_ctrls           = iris_vidioc_g_ext_ctrls,
+};
+
+static const struct v4l2_file_operations iris_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = video_ioctl2,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl32 = v4l2_compat_ioctl32,
+#endif
+	.release        = iris_fops_release,
+};
+
+static struct video_device iris_viddev_template = {
+	.fops                   = &iris_fops,
+	.ioctl_ops              = &iris_ioctl_ops,
+	.name                   = DRIVER_NAME,
+	.release                = video_device_release,
+};
+
+static struct video_device *video_get_dev(void)
+{
+	return priv_videodev;
+}
+
+static int iris_probe(struct platform_device *pdev)
+{
+	struct iris_device *radio;
+	int retval;
+	int radio_nr = -1;
+	int i;
+
+	FMDBG("pdev %pK", pdev);
+
+	if (!pdev) {
+		FMDERR(": pdev is null\n");
+		return -ENOMEM;
+	}
+
+	radio = kzalloc(sizeof(struct iris_device), GFP_KERNEL);
+	if (!radio)
+		return -ENOMEM;
+
+	radio->dev = &pdev->dev;
+	platform_set_drvdata(pdev, radio);
+
+	radio->videodev = video_device_alloc();
+	if (!radio->videodev) {
+		kfree(radio);
+		return -ENOMEM;
+	}
+
+	memcpy(radio->videodev, &iris_viddev_template,
+	  sizeof(iris_viddev_template));
+	strlcpy(radio->v4l2_dev.name, DRIVER_NAME,
+			sizeof(radio->v4l2_dev.name));
+	retval = v4l2_device_register(NULL, &radio->v4l2_dev);
+	if (retval)
+		return -EINVAL;
+	radio->videodev->v4l2_dev = &radio->v4l2_dev;
+
+	for (i = 0; i < IRIS_BUF_MAX; i++) {
+		int kfifo_alloc_rc = 0;
+
+		spin_lock_init(&radio->buf_lock[i]);
+
+		if ((i == IRIS_BUF_RAW_RDS) || (i == IRIS_BUF_PEEK))
+			kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
+				rds_buf*3, GFP_KERNEL);
+		else if ((i == IRIS_BUF_CAL_DATA) || (i == IRIS_BUF_RT_RDS))
+			kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
+				STD_BUF_SIZE*2, GFP_KERNEL);
+		else
+			kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
+				STD_BUF_SIZE, GFP_KERNEL);
+
+		if (kfifo_alloc_rc != 0) {
+			FMDERR("failed allocating buffers %d\n",
+				   kfifo_alloc_rc);
+			for (; i > -1; i--)
+				kfifo_free(&radio->data_buf[i]);
+			video_device_release(radio->videodev);
+			kfree(radio);
+			return -ENOMEM;
+		}
+	}
+
+	mutex_init(&radio->lock);
+	init_completion(&radio->sync_xfr_start);
+	radio->tune_req = 0;
+	radio->prev_trans_rds = 2;
+	radio->is_fm_closing = false;
+	init_waitqueue_head(&radio->event_queue);
+	init_waitqueue_head(&radio->read_queue);
+
+	video_set_drvdata(radio->videodev, radio);
+
+	if (video_get_drvdata(radio->videodev) == NULL)
+		FMDERR(": video_get_drvdata failed\n");
+
+	retval = video_register_device(radio->videodev, VFL_TYPE_RADIO,
+								   radio_nr);
+	if (retval) {
+		FMDERR(": Could not register video device\n");
+		video_device_release(radio->videodev);
+		for (; i > -1; i--)
+			kfifo_free(&radio->data_buf[i]);
+		kfree(radio);
+		return retval;
+	}
+	priv_videodev = kzalloc(sizeof(struct video_device),
+			GFP_KERNEL);
+	if (priv_videodev != NULL) {
+		memcpy(priv_videodev, radio->videodev,
+			sizeof(struct video_device));
+	} else {
+		video_unregister_device(radio->videodev);
+		video_device_release(radio->videodev);
+		for (; i > -1; i--)
+			kfifo_free(&radio->data_buf[i]);
+		kfree(radio);
+	}
+	return 0;
+}
+
+
+static int iris_remove(struct platform_device *pdev)
+{
+	int i;
+	struct iris_device *radio = platform_get_drvdata(pdev);
+
+	if (radio == NULL) {
+		FMDERR(":radio is null\n");
+		return -EINVAL;
+	}
+	video_unregister_device(radio->videodev);
+
+	for (i = 0; i < IRIS_BUF_MAX; i++)
+		kfifo_free(&radio->data_buf[i]);
+
+	kfree(radio);
+
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static const struct of_device_id iris_fm_match[] = {
+	{.compatible = "qcom,iris_fm"},
+	{}
+};
+
+static struct platform_driver iris_driver = {
+	.probe	= iris_probe,
+	.driver = {
+		.owner  = THIS_MODULE,
+		.name   = "iris_fm",
+		.of_match_table = iris_fm_match,
+	},
+	.remove = iris_remove,
+};
+
+static int __init iris_radio_init(void)
+{
+	return platform_driver_register(&iris_driver);
+}
+module_init(iris_radio_init);
+
+static void __exit iris_radio_exit(void)
+{
+	platform_driver_unregister(&iris_driver);
+}
+module_exit(iris_radio_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 8be561a..9f98e4d 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -710,7 +710,11 @@
 		SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings);
 		SET_VALID_IOCTL(ops, VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap);
 		SET_VALID_IOCTL(ops, VIDIOC_G_EDID, vidioc_g_edid);
+	} else {
+		/* ioctls valid for radio */
+		SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf);
 	}
+
 	if (is_tx && (is_radio || is_sdr)) {
 		/* radio transmitter only ioctls */
 		SET_VALID_IOCTL(ops, VIDIOC_G_MODULATOR, vidioc_g_modulator);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index e2e23ff..d4ee140 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -982,6 +982,9 @@
 		if (is_sdr && is_tx && ops->vidioc_g_fmt_sdr_out)
 			return 0;
 		break;
+	case V4L2_BUF_TYPE_PRIVATE:
+		if (ops->vidioc_g_fmt_type_private)
+			return 0;
 	default:
 		break;
 	}
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 831b64d..47094d5 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -158,6 +158,8 @@
 #define DDR_CONFIG_PRG_RCLK_DLY_MASK	0x1FF
 #define DDR_CONFIG_PRG_RCLK_DLY		115
 #define DDR_CONFIG_2_POR_VAL		0x80040873
+#define DLL_USR_CTL_POR_VAL		0x10800
+#define ENABLE_DLL_LOCK_STATUS		(1 << 26)
 
 /* 512 descriptors */
 #define SDHCI_MSM_MAX_SEGMENTS  (1 << 9)
@@ -200,6 +202,7 @@
 	u32 CORE_DLL_CONFIG_2;
 	u32 CORE_DDR_CONFIG;
 	u32 CORE_DDR_CONFIG_2;
+	u32 CORE_DLL_USR_CTL; /* Present on SDCC5.1 onwards */
 };
 
 struct sdhci_msm_offset sdhci_msm_offset_mci_removed = {
@@ -229,6 +232,7 @@
 	.CORE_DLL_CONFIG_2 = 0x254,
 	.CORE_DDR_CONFIG = 0x258,
 	.CORE_DDR_CONFIG_2 = 0x25C,
+	.CORE_DLL_USR_CTL = 0x388,
 };
 
 struct sdhci_msm_offset sdhci_msm_offset_mci_present = {
@@ -795,6 +799,15 @@
 				msm_host_offset->CORE_DLL_CONFIG_2);
 	}
 
+	/*
+	 * Configure DLL user control register to enable DLL status
+	 * This setting is applicable to SDCC v5.1 onwards only
+	 */
+	if (msm_host->need_dll_user_ctl) {
+		writel_relaxed(DLL_USR_CTL_POR_VAL | ENABLE_DLL_LOCK_STATUS,
+			host->ioaddr + msm_host_offset->CORE_DLL_USR_CTL);
+	}
+
 	/* Set DLL_EN bit to 1. */
 	writel_relaxed((readl_relaxed(host->ioaddr +
 			msm_host_offset->CORE_DLL_CONFIG) | CORE_DLL_EN),
@@ -4563,6 +4576,10 @@
 		msm_host->ice_hci_support = true;
 		host->cdr_support = true;
 	}
+
+	if ((major == 1) && (minor >= 0x71))
+		msm_host->need_dll_user_ctl = true;
+
 }
 
 #ifdef CONFIG_MMC_CQ_HCI
diff --git a/drivers/mmc/host/sdhci-msm.h b/drivers/mmc/host/sdhci-msm.h
index 1888945..27c4f23 100644
--- a/drivers/mmc/host/sdhci-msm.h
+++ b/drivers/mmc/host/sdhci-msm.h
@@ -257,6 +257,7 @@
 	struct sdhci_msm_regs_restore regs_restore;
 	int soc_min_rev;
 	struct workqueue_struct *pm_qos_wq;
+	bool need_dll_user_ctl;
 };
 
 extern char *saved_command_line;
diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c
index 90be113..795b905 100644
--- a/drivers/net/wireless/cnss2/pci.c
+++ b/drivers/net/wireless/cnss2/pci.c
@@ -865,13 +865,15 @@
 		goto out;
 	}
 
-	num_vectors = pci_enable_msi_range(pci_dev,
-					   msi_config->total_vectors,
-					   msi_config->total_vectors);
+	num_vectors = pci_alloc_irq_vectors(pci_dev,
+					    msi_config->total_vectors,
+					    msi_config->total_vectors,
+					    PCI_IRQ_MSI);
 	if (num_vectors != msi_config->total_vectors) {
 		cnss_pr_err("Failed to get enough MSI vectors (%d), available vectors = %d",
 			    msi_config->total_vectors, num_vectors);
-		ret = -EINVAL;
+		if (num_vectors >= 0)
+			ret = -EINVAL;
 		goto reset_msi_config;
 	}
 
@@ -879,7 +881,7 @@
 	if (!msi_desc) {
 		cnss_pr_err("msi_desc is NULL!\n");
 		ret = -EINVAL;
-		goto disable_msi;
+		goto free_msi_vector;
 	}
 
 	pci_priv->msi_ep_base_data = msi_desc->msg.data;
@@ -892,8 +894,8 @@
 
 	return 0;
 
-disable_msi:
-	pci_disable_msi(pci_priv->pci_dev);
+free_msi_vector:
+	pci_free_irq_vectors(pci_priv->pci_dev);
 reset_msi_config:
 	pci_priv->msi_config = NULL;
 out:
@@ -902,7 +904,7 @@
 
 static void cnss_pci_disable_msi(struct cnss_pci_data *pci_priv)
 {
-	pci_disable_msi(pci_priv->pci_dev);
+	pci_free_irq_vectors(pci_priv->pci_dev);
 }
 
 int cnss_get_user_msi_assignment(struct device *dev, char *user_name,
@@ -946,8 +948,12 @@
 int cnss_get_msi_irq(struct device *dev, unsigned int vector)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
+	int irq_num;
 
-	return pci_dev->irq + vector;
+	irq_num = pci_irq_vector(pci_dev, vector);
+	cnss_pr_dbg("Get IRQ number %d for vector index %d\n", irq_num, vector);
+
+	return irq_num;
 }
 EXPORT_SYMBOL(cnss_get_msi_irq);
 
diff --git a/drivers/platform/msm/Kconfig b/drivers/platform/msm/Kconfig
index 782ce62..5b34bbcd 100644
--- a/drivers/platform/msm/Kconfig
+++ b/drivers/platform/msm/Kconfig
@@ -47,6 +47,16 @@
 	  Kernel and user-space processes can call the IPA driver
 	  to configure IPA core.
 
+config IPA_WDI_UNIFIED_API
+	bool "IPA WDI unified API support"
+	depends on IPA3
+	help
+	  This driver supports IPA WDI unified API.
+	  WDI is the interface between IPA micro controller and WLAN chipset.
+	  It is designed to support IPA HW accelerating path for WLAN use case.
+	  The IPA WDI unified API supports all WDI versions through a unified
+	  interface.
+
 config RMNET_IPA3
 	tristate "IPA3 RMNET WWAN Network Device"
 	depends on IPA3 && MSM_QMI_INTERFACE
@@ -214,4 +224,14 @@
 	  External Display driver was added to support the communication
 	  between external display driver and its counterparts.
 
+config MSM_RMNET_BAM
+        bool "RMNET BAM Driver"
+        depends on MSM_BAM_DMUX
+        default n
+        help
+          Implements RMNET over BAM interface.
+          RMNET provides a virtual ethernet interface
+          for routing IP packets within the MSM using
+          BAM as a physical transport.
+
 endmenu
diff --git a/drivers/platform/msm/Makefile b/drivers/platform/msm/Makefile
index d0f0216f..06ff2ca 100644
--- a/drivers/platform/msm/Makefile
+++ b/drivers/platform/msm/Makefile
@@ -7,6 +7,7 @@
 obj-$(CONFIG_SPS) += sps/
 obj-$(CONFIG_QPNP_COINCELL) += qpnp-coincell.o
 obj-$(CONFIG_QPNP_REVID) += qpnp-revid.o
+obj-$(CONFIG_MSM_RMNET_BAM) += msm_rmnet_bam.o
 obj-$(CONFIG_GPIO_USB_DETECT) += gpio-usbdetect.o
 obj-$(CONFIG_EP_PCIE) += ep_pcie/
 obj-$(CONFIG_MSM_MHI_DEV) += mhi_dev/
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 754c1f4..62bb8f9 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -269,6 +269,9 @@
 	ipa3_transport_release_resource);
 static void ipa_gsi_notify_cb(struct gsi_per_notify *notify);
 
+static int ipa3_attach_to_smmu(void);
+static int ipa3_alloc_pkt_init(void);
+
 static void ipa3_load_ipa_fw(struct work_struct *work);
 static DECLARE_WORK(ipa3_fw_loading_work, ipa3_load_ipa_fw);
 
@@ -277,15 +280,12 @@
 	ipa_dec_clients_disable_clks_on_wq);
 
 static struct ipa3_plat_drv_res ipa3_res = {0, };
-struct msm_bus_scale_pdata *ipa3_bus_scale_table;
 
 static struct clk *ipa3_clk;
 
 struct ipa3_context *ipa3_ctx;
-static struct device *master_dev;
-struct platform_device *ipa3_pdev;
 static struct {
-	bool present;
+	bool present[IPA_SMMU_CB_MAX];
 	bool arm_smmu;
 	bool fast_map;
 	bool s1_bypass_arr[IPA_SMMU_CB_MAX];
@@ -508,42 +508,19 @@
 }
 
 /**
- * ipa3_get_smmu_ctx()- Return the wlan smmu context
+ * ipa3_get_smmu_ctx()- Return smmu context for the given cb_type
  *
  * Return value: pointer to smmu context address
  */
-struct ipa_smmu_cb_ctx *ipa3_get_smmu_ctx(void)
+struct ipa_smmu_cb_ctx *ipa3_get_smmu_ctx(enum ipa_smmu_cb_type cb_type)
 {
-	return &smmu_cb[IPA_SMMU_CB_AP];
-}
-
-/**
- * ipa3_get_wlan_smmu_ctx()- Return the wlan smmu context
- *
- * Return value: pointer to smmu context address
- */
-struct ipa_smmu_cb_ctx *ipa3_get_wlan_smmu_ctx(void)
-{
-	return &smmu_cb[IPA_SMMU_CB_WLAN];
-}
-
-/**
- * ipa3_get_uc_smmu_ctx()- Return the uc smmu context
- *
- * Return value: pointer to smmu context address
- */
-struct ipa_smmu_cb_ctx *ipa3_get_uc_smmu_ctx(void)
-{
-	return &smmu_cb[IPA_SMMU_CB_UC];
+	return &smmu_cb[cb_type];
 }
 
 static int ipa3_open(struct inode *inode, struct file *filp)
 {
-	struct ipa3_context *ctx = NULL;
-
 	IPADBG_LOW("ENTER\n");
-	ctx = container_of(inode->i_cdev, struct ipa3_context, cdev);
-	filp->private_data = ctx;
+	filp->private_data = ipa3_ctx;
 
 	return 0;
 }
@@ -3509,6 +3486,11 @@
 */
 void ipa3_enable_clks(void)
 {
+	if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_NORMAL) {
+		IPAERR("not supported in this mode\n");
+		return;
+	}
+
 	IPADBG("enabling IPA clocks and bus voting\n");
 
 	if (msm_bus_scale_client_update_request(ipa3_ctx->ipa_bus_hdl,
@@ -3540,6 +3522,11 @@
 */
 void ipa3_disable_clks(void)
 {
+	if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_NORMAL) {
+		IPAERR("not supported in this mode\n");
+		return;
+	}
+
 	IPADBG("disabling IPA clocks and bus voting\n");
 
 	ipa3_ctx->ctrl->ipa3_disable_clks();
@@ -3870,6 +3857,11 @@
 	if (!ipa3_ctx->enable_clock_scaling)
 		return 0;
 
+	if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_NORMAL) {
+		IPAERR("not supported in this mode\n");
+		return 0;
+	}
+
 	IPADBG_LOW("idx = %d\n", idx);
 
 	if (idx <= 0 || idx >= ipa3_ctx->ctrl->msm_bus_data_ptr->num_usecases) {
@@ -3921,6 +3913,11 @@
 	enum ipa_voltage_level needed_voltage;
 	u32 clk_rate;
 
+	if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_NORMAL) {
+		IPAERR("not supported in this mode\n");
+		return 0;
+	}
+
 	IPADBG_LOW("floor_voltage=%d, bandwidth_mbps=%u",
 					floor_voltage, bandwidth_mbps);
 
@@ -4177,7 +4174,7 @@
 
 	/*register IPA IRQ handler*/
 	result = ipa3_interrupts_init(ipa3_res.ipa_irq, 0,
-			master_dev);
+			&ipa3_ctx->master_pdev->dev);
 	if (result) {
 		IPAERR("ipa interrupts initialization failed\n");
 		return -ENODEV;
@@ -4195,7 +4192,7 @@
 	return 0;
 
 fail_add_interrupt_handler:
-	free_irq(ipa3_res.ipa_irq, master_dev);
+	free_irq(ipa3_res.ipa_irq, &ipa3_ctx->master_pdev->dev);
 	return result;
 }
 
@@ -4411,6 +4408,78 @@
 	if (ipa3_ctx->ipa_hw_type != IPA_HW_v4_0)
 		ipa3_proxy_clk_vote();
 
+	/* SMMU was already attached if used, safe to do allocations */
+	if (ipahal_init(ipa3_ctx->ipa_hw_type, ipa3_ctx->mmio,
+		ipa3_ctx->pdev)) {
+		IPAERR("fail to init ipahal\n");
+		result = -EFAULT;
+		goto fail_ipahal;
+	}
+
+	result = ipa3_init_hw();
+	if (result) {
+		IPAERR(":error initializing HW\n");
+		result = -ENODEV;
+		goto fail_init_hw;
+	}
+	IPADBG("IPA HW initialization sequence completed");
+
+	ipa3_ctx->ipa_num_pipes = ipa3_get_num_pipes();
+	if (ipa3_ctx->ipa_num_pipes > IPA3_MAX_NUM_PIPES) {
+		IPAERR("IPA has more pipes then supported has %d, max %d\n",
+			ipa3_ctx->ipa_num_pipes, IPA3_MAX_NUM_PIPES);
+		result = -ENODEV;
+		goto fail_init_hw;
+	}
+
+	ipa3_ctx->ctrl->ipa_sram_read_settings();
+	IPADBG("SRAM, size: 0x%x, restricted bytes: 0x%x\n",
+		ipa3_ctx->smem_sz, ipa3_ctx->smem_restricted_bytes);
+
+	IPADBG("hdr_lcl=%u ip4_rt_hash=%u ip4_rt_nonhash=%u\n",
+		ipa3_ctx->hdr_tbl_lcl, ipa3_ctx->ip4_rt_tbl_hash_lcl,
+		ipa3_ctx->ip4_rt_tbl_nhash_lcl);
+
+	IPADBG("ip6_rt_hash=%u ip6_rt_nonhash=%u\n",
+		ipa3_ctx->ip6_rt_tbl_hash_lcl, ipa3_ctx->ip6_rt_tbl_nhash_lcl);
+
+	IPADBG("ip4_flt_hash=%u ip4_flt_nonhash=%u\n",
+		ipa3_ctx->ip4_flt_tbl_hash_lcl,
+		ipa3_ctx->ip4_flt_tbl_nhash_lcl);
+
+	IPADBG("ip6_flt_hash=%u ip6_flt_nonhash=%u\n",
+		ipa3_ctx->ip6_flt_tbl_hash_lcl,
+		ipa3_ctx->ip6_flt_tbl_nhash_lcl);
+
+	if (ipa3_ctx->smem_reqd_sz > ipa3_ctx->smem_sz) {
+		IPAERR("SW expect more core memory, needed %d, avail %d\n",
+			ipa3_ctx->smem_reqd_sz, ipa3_ctx->smem_sz);
+		result = -ENOMEM;
+		goto fail_init_hw;
+	}
+
+	result = ipa3_allocate_dma_task_for_gsi();
+	if (result) {
+		IPAERR("failed to allocate dma task\n");
+		goto fail_dma_task;
+	}
+
+	if (ipa3_nat_ipv6ct_init_devices()) {
+		IPAERR("unable to init NAT and IPv6CT devices\n");
+		result = -ENODEV;
+		goto fail_nat_ipv6ct_init_dev;
+	}
+
+	result = ipa3_alloc_pkt_init();
+	if (result) {
+		IPAERR("Failed to alloc pkt_init payload\n");
+		result = -ENODEV;
+		goto fail_allok_pkt_init;
+	}
+
+	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v3_5)
+		ipa3_enable_dcd();
+
 	/*
 	 * indication whether working in MHI config or non MHI config is given
 	 * in ipa3_write which is launched before ipa3_post_init. i.e. from
@@ -4563,6 +4632,15 @@
 fail_register_device:
 	ipa3_destroy_flt_tbl_idrs();
 	ipa3_proxy_clk_unvote();
+fail_allok_pkt_init:
+	ipa3_nat_ipv6ct_destroy_devices();
+fail_nat_ipv6ct_init_dev:
+	ipa3_free_dma_task_for_gsi();
+fail_dma_task:
+fail_init_hw:
+	ipahal_destroy();
+fail_ipahal:
+
 	return result;
 }
 
@@ -4573,7 +4651,7 @@
 
 	IPADBG("Manual FW loading process initiated\n");
 
-	result = request_firmware(&fw, IPA_FWS_PATH, ipa3_ctx->dev);
+	result = request_firmware(&fw, IPA_FWS_PATH, ipa3_ctx->cdev.dev);
 	if (result < 0) {
 		IPAERR("request_firmware failed, error %d\n", result);
 		return result;
@@ -4629,6 +4707,12 @@
 
 	IPADBG("Entry\n");
 
+	result = ipa3_attach_to_smmu();
+	if (result) {
+		IPAERR("IPA attach to smmu failed %d\n", result);
+		return;
+	}
+
 	IPA_ACTIVE_CLIENTS_INC_SIMPLE();
 
 	if (ipa3_is_msm_device() || (ipa3_ctx->ipa_hw_type >= IPA_HW_v3_5))
@@ -4644,7 +4728,7 @@
 	}
 	pr_info("IPA FW loaded successfully\n");
 
-	result = ipa3_post_init(&ipa3_res, ipa3_ctx->dev);
+	result = ipa3_post_init(&ipa3_res, ipa3_ctx->cdev.dev);
 	if (result)
 		IPAERR("IPA post init failed %d\n", result);
 }
@@ -4867,12 +4951,13 @@
 * Configure GSI registers (in GSI case)
 */
 static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
-		struct device *ipa_dev)
+		struct platform_device *ipa_pdev)
 {
 	int result = 0;
 	int i;
 	struct ipa3_rt_tbl_set *rset;
 	struct ipa_active_client_logging_info log_info;
+	struct cdev *cdev;
 
 	IPADBG("IPA Driver initialization started\n");
 
@@ -4887,8 +4972,8 @@
 	if (ipa3_ctx->logbuf == NULL)
 		IPAERR("failed to create IPC log, continue...\n");
 
-	ipa3_ctx->pdev = ipa_dev;
-	ipa3_ctx->uc_pdev = ipa_dev;
+	/* ipa3_ctx->pdev and ipa3_ctx->uc_pdev will be set in the smmu probes*/
+	ipa3_ctx->master_pdev = ipa_pdev;
 	ipa3_ctx->smmu_present = smmu_info.present;
 	if (!ipa3_ctx->smmu_present) {
 		for (i = 0; i < IPA_SMMU_CB_MAX; i++)
@@ -4917,6 +5002,10 @@
 	ipa3_ctx->ipa3_active_clients_logging.log_rdy = false;
 	ipa3_ctx->mhi_evid_limits[0] = resource_p->mhi_evid_limits[0];
 	ipa3_ctx->mhi_evid_limits[1] = resource_p->mhi_evid_limits[1];
+
+	WARN(ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_NORMAL,
+		"Non NORMAL IPA HW mode, is this emulation platform ?");
+
 	if (resource_p->ipa_tz_unlock_reg) {
 		ipa3_ctx->ipa_tz_unlock_reg_num =
 			resource_p->ipa_tz_unlock_reg_num;
@@ -4961,31 +5050,36 @@
 		goto fail_bind;
 	}
 
-	result = ipa3_init_mem_partition(master_dev->of_node);
+	result = ipa3_init_mem_partition(ipa3_ctx->master_pdev->dev.of_node);
 	if (result) {
 		IPAERR(":ipa3_init_mem_partition failed!\n");
 		result = -ENODEV;
 		goto fail_init_mem_partition;
 	}
 
-	if (ipa3_bus_scale_table) {
+	if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_VIRTUAL) {
+		ipa3_ctx->ctrl->msm_bus_data_ptr =
+			msm_bus_cl_get_pdata(ipa3_ctx->master_pdev);
+		if (ipa3_ctx->ctrl->msm_bus_data_ptr == NULL) {
+			IPAERR("failed to get bus scaling\n");
+			goto fail_bus_reg;
+		}
 		IPADBG("Use bus scaling info from device tree #usecases=%d\n",
-			ipa3_bus_scale_table->num_usecases);
-		ipa3_ctx->ctrl->msm_bus_data_ptr = ipa3_bus_scale_table;
-	}
+			ipa3_ctx->ctrl->msm_bus_data_ptr->num_usecases);
 
-	/* get BUS handle */
-	ipa3_ctx->ipa_bus_hdl =
-		msm_bus_scale_register_client(
-			ipa3_ctx->ctrl->msm_bus_data_ptr);
-	if (!ipa3_ctx->ipa_bus_hdl) {
-		IPAERR("fail to register with bus mgr!\n");
-		result = -ENODEV;
-		goto fail_bus_reg;
+		/* get BUS handle */
+		ipa3_ctx->ipa_bus_hdl =
+			msm_bus_scale_register_client(
+				ipa3_ctx->ctrl->msm_bus_data_ptr);
+		if (!ipa3_ctx->ipa_bus_hdl) {
+			IPAERR("fail to register with bus mgr!\n");
+			result = -ENODEV;
+			goto fail_bus_reg;
+		}
 	}
 
 	/* get IPA clocks */
-	result = ipa3_get_clks(master_dev);
+	result = ipa3_get_clks(&ipa3_ctx->master_pdev->dev);
 	if (result)
 		goto fail_clk;
 
@@ -5013,55 +5107,6 @@
 		goto fail_remap;
 	}
 
-	if (ipahal_init(ipa3_ctx->ipa_hw_type, ipa3_ctx->mmio,
-		ipa3_ctx->pdev)) {
-		IPAERR("fail to init ipahal\n");
-		result = -EFAULT;
-		goto fail_ipahal;
-	}
-
-	result = ipa3_init_hw();
-	if (result) {
-		IPAERR(":error initializing HW.\n");
-		result = -ENODEV;
-		goto fail_init_hw;
-	}
-	IPADBG("IPA HW initialization sequence completed");
-
-	ipa3_ctx->ipa_num_pipes = ipa3_get_num_pipes();
-	if (ipa3_ctx->ipa_num_pipes > IPA3_MAX_NUM_PIPES) {
-		IPAERR("IPA has more pipes then supported! has %d, max %d\n",
-			ipa3_ctx->ipa_num_pipes, IPA3_MAX_NUM_PIPES);
-		result = -ENODEV;
-		goto fail_init_hw;
-	}
-
-	ipa3_ctx->ctrl->ipa_sram_read_settings();
-	IPADBG("SRAM, size: 0x%x, restricted bytes: 0x%x\n",
-		ipa3_ctx->smem_sz, ipa3_ctx->smem_restricted_bytes);
-
-	IPADBG("hdr_lcl=%u ip4_rt_hash=%u ip4_rt_nonhash=%u\n",
-		ipa3_ctx->hdr_tbl_lcl, ipa3_ctx->ip4_rt_tbl_hash_lcl,
-		ipa3_ctx->ip4_rt_tbl_nhash_lcl);
-
-	IPADBG("ip6_rt_hash=%u ip6_rt_nonhash=%u\n",
-		ipa3_ctx->ip6_rt_tbl_hash_lcl, ipa3_ctx->ip6_rt_tbl_nhash_lcl);
-
-	IPADBG("ip4_flt_hash=%u ip4_flt_nonhash=%u\n",
-		ipa3_ctx->ip4_flt_tbl_hash_lcl,
-		ipa3_ctx->ip4_flt_tbl_nhash_lcl);
-
-	IPADBG("ip6_flt_hash=%u ip6_flt_nonhash=%u\n",
-		ipa3_ctx->ip6_flt_tbl_hash_lcl,
-		ipa3_ctx->ip6_flt_tbl_nhash_lcl);
-
-	if (ipa3_ctx->smem_reqd_sz > ipa3_ctx->smem_sz) {
-		IPAERR("SW expect more core memory, needed %d, avail %d\n",
-			ipa3_ctx->smem_reqd_sz, ipa3_ctx->smem_sz);
-		result = -ENOMEM;
-		goto fail_init_hw;
-	}
-
 	mutex_init(&ipa3_ctx->ipa3_active_clients.mutex);
 
 	IPA_ACTIVE_CLIENTS_PREP_SPECIAL(log_info, "PROXY_CLK_VOTE");
@@ -5160,13 +5205,6 @@
 		goto fail_rx_pkt_wrapper_cache;
 	}
 
-	/* allocate memory for DMA_TASK workaround */
-	result = ipa3_allocate_dma_task_for_gsi();
-	if (result) {
-		IPAERR("failed to allocate dma task\n");
-		goto fail_dma_task;
-	}
-
 	/* init the various list heads */
 	INIT_LIST_HEAD(&ipa3_ctx->hdr_tbl.head_hdr_entry_list);
 	for (i = 0; i < IPA_HDR_BIN_MAX; i++) {
@@ -5210,29 +5248,23 @@
 	spin_lock_init(&ipa3_ctx->wc_memb.ipa_tx_mul_spinlock);
 	INIT_LIST_HEAD(&ipa3_ctx->wc_memb.wlan_comm_desc_list);
 
-	ipa3_ctx->class = class_create(THIS_MODULE, DRV_NAME);
+	ipa3_ctx->cdev.class = class_create(THIS_MODULE, DRV_NAME);
 
-	result = alloc_chrdev_region(&ipa3_ctx->dev_num, 0, 1, DRV_NAME);
+	result = alloc_chrdev_region(&ipa3_ctx->cdev.dev_num, 0, 1, DRV_NAME);
 	if (result) {
 		IPAERR("alloc_chrdev_region err.\n");
 		result = -ENODEV;
 		goto fail_alloc_chrdev_region;
 	}
 
-	ipa3_ctx->dev = device_create(ipa3_ctx->class, NULL, ipa3_ctx->dev_num,
-			ipa3_ctx, DRV_NAME);
-	if (IS_ERR(ipa3_ctx->dev)) {
+	ipa3_ctx->cdev.dev = device_create(ipa3_ctx->cdev.class, NULL,
+		 ipa3_ctx->cdev.dev_num, ipa3_ctx, DRV_NAME);
+	if (IS_ERR(ipa3_ctx->cdev.dev)) {
 		IPAERR(":device_create err.\n");
 		result = -ENODEV;
 		goto fail_device_create;
 	}
 
-	if (ipa3_nat_ipv6ct_init_devices()) {
-		IPAERR("unable to init NAT and IPv6CT devices\n");
-		result = -ENODEV;
-		goto fail_nat_ipv6ct_init_dev;
-	}
-
 	/* Create a wakeup source. */
 	wakeup_source_init(&ipa3_ctx->w_lock, "IPA_WS");
 	spin_lock_init(&ipa3_ctx->wakelock_ref_cnt.spinlock);
@@ -5263,16 +5295,6 @@
 		}
 	}
 
-	result = ipa3_alloc_pkt_init();
-	if (result) {
-		IPAERR("Failed to alloc pkt_init payload\n");
-		result = -ENODEV;
-		goto fail_allok_pkt_init;
-	}
-
-	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v3_5)
-		ipa3_enable_dcd();
-
 	INIT_LIST_HEAD(&ipa3_ctx->ipa_ready_cb_list);
 
 	init_completion(&ipa3_ctx->init_completion_obj);
@@ -5301,19 +5323,20 @@
 		}
 	}
 
-	cdev_init(&ipa3_ctx->cdev, &ipa3_drv_fops);
-	ipa3_ctx->cdev.owner = THIS_MODULE;
-	ipa3_ctx->cdev.ops = &ipa3_drv_fops;  /* from LDD3 */
+	cdev = &ipa3_ctx->cdev.cdev;
+	cdev_init(cdev, &ipa3_drv_fops);
+	cdev->owner = THIS_MODULE;
+	cdev->ops = &ipa3_drv_fops;  /* from LDD3 */
 
-	result = cdev_add(&ipa3_ctx->cdev, ipa3_ctx->dev_num, 1);
+	result = cdev_add(cdev, ipa3_ctx->cdev.dev_num, 1);
 	if (result) {
 		IPAERR(":cdev_add err=%d\n", -result);
 		result = -ENODEV;
 		goto fail_cdev_add;
 	}
 	IPADBG("ipa cdev added successful. major:%d minor:%d\n",
-			MAJOR(ipa3_ctx->dev_num),
-			MINOR(ipa3_ctx->dev_num));
+			MAJOR(ipa3_ctx->cdev.dev_num),
+			MINOR(ipa3_ctx->cdev.dev_num));
 	/*
 	 * for IPA 4.0 offline charge is not needed and we need to prevent
 	 * power collapse until IPA uC is loaded.
@@ -5328,7 +5351,6 @@
 fail_gsi_pre_fw_load_init:
 	ipa3_dma_shutdown();
 fail_ipa_dma_setup:
-fail_allok_pkt_init:
 	if (ipa3_ctx->use_ipa_pm)
 		ipa_pm_destroy();
 	else
@@ -5337,11 +5359,9 @@
 	if (!ipa3_ctx->use_ipa_pm)
 		ipa_rm_exit();
 fail_ipa_rm_init:
-	ipa3_nat_ipv6ct_destroy_devices();
-fail_nat_ipv6ct_init_dev:
-	device_destroy(ipa3_ctx->class, ipa3_ctx->dev_num);
+	device_destroy(ipa3_ctx->cdev.class, ipa3_ctx->cdev.dev_num);
 fail_device_create:
-	unregister_chrdev_region(ipa3_ctx->dev_num, 1);
+	unregister_chrdev_region(ipa3_ctx->cdev.dev_num, 1);
 fail_alloc_chrdev_region:
 	idr_destroy(&ipa3_ctx->ipa_idr);
 	rset = &ipa3_ctx->reap_rt_tbl_set[IPA_IP_v6];
@@ -5350,8 +5370,6 @@
 	idr_destroy(&rset->rule_ids);
 	idr_destroy(&ipa3_ctx->rt_tbl_set[IPA_IP_v6].rule_ids);
 	idr_destroy(&ipa3_ctx->rt_tbl_set[IPA_IP_v4].rule_ids);
-	ipa3_free_dma_task_for_gsi();
-fail_dma_task:
 	kmem_cache_destroy(ipa3_ctx->rx_pkt_wrapper_cache);
 fail_rx_pkt_wrapper_cache:
 	kmem_cache_destroy(ipa3_ctx->tx_pkt_wrapper_cache);
@@ -5374,8 +5392,6 @@
 fail_create_transport_wq:
 	destroy_workqueue(ipa3_ctx->power_mgmt_wq);
 fail_init_hw:
-	ipahal_destroy();
-fail_ipahal:
 	iounmap(ipa3_ctx->mmio);
 fail_remap:
 	ipa3_disable_clks();
@@ -5385,12 +5401,11 @@
 		clk_put(ipa3_clk);
 	ipa3_clk = NULL;
 fail_clk:
-	msm_bus_scale_unregister_client(ipa3_ctx->ipa_bus_hdl);
+	if (ipa3_ctx->ipa_bus_hdl)
+		msm_bus_scale_unregister_client(ipa3_ctx->ipa_bus_hdl);
 fail_bus_reg:
-	if (ipa3_bus_scale_table) {
-		msm_bus_cl_clear_pdata(ipa3_bus_scale_table);
-		ipa3_bus_scale_table = NULL;
-	}
+	if (ipa3_ctx->ctrl->msm_bus_data_ptr)
+		msm_bus_cl_clear_pdata(ipa3_ctx->ctrl->msm_bus_data_ptr);
 fail_init_mem_partition:
 fail_bind:
 	kfree(ipa3_ctx->ctrl);
@@ -5777,7 +5792,7 @@
 
 static int ipa_smmu_wlan_cb_probe(struct device *dev)
 {
-	struct ipa_smmu_cb_ctx *cb = ipa3_get_wlan_smmu_ctx();
+	struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_WLAN);
 	int atomic_ctx = 1;
 	int fast = 1;
 	int bypass = 1;
@@ -5788,6 +5803,11 @@
 
 	IPADBG("sub pdev=%p\n", dev);
 
+	if (!smmu_info.present[IPA_SMMU_CB_WLAN]) {
+		IPAERR("WLAN SMMU is disabled\n");
+		return 0;
+	}
+
 	cb->dev = dev;
 	cb->iommu = iommu_domain_alloc(dev->bus);
 	if (!cb->iommu) {
@@ -5797,7 +5817,8 @@
 	}
 	cb->valid = true;
 
-	if (of_property_read_bool(dev->of_node, "qcom,smmu-s1-bypass")) {
+	if (of_property_read_bool(dev->of_node, "qcom,smmu-s1-bypass") ||
+		ipa3_ctx->ipa_config_is_mhi) {
 		smmu_info.s1_bypass_arr[IPA_SMMU_CB_WLAN] = true;
 		ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_WLAN] = true;
 
@@ -5877,7 +5898,7 @@
 
 static int ipa_smmu_uc_cb_probe(struct device *dev)
 {
-	struct ipa_smmu_cb_ctx *cb = ipa3_get_uc_smmu_ctx();
+	struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_UC);
 	int atomic_ctx = 1;
 	int bypass = 1;
 	int fast = 1;
@@ -5886,6 +5907,11 @@
 
 	IPADBG("UC CB PROBE sub pdev=%p\n", dev);
 
+	if (!smmu_info.present[IPA_SMMU_CB_UC]) {
+		IPAERR("UC SMMU is disabled\n");
+		return 0;
+	}
+
 	ret = of_property_read_u32_array(dev->of_node, "qcom,iova-mapping",
 			iova_ap_mapping, 2);
 	if (ret) {
@@ -5925,7 +5951,8 @@
 
 	IPADBG("UC CB PROBE sub pdev=%p set attribute\n", dev);
 
-	if (of_property_read_bool(dev->of_node, "qcom,smmu-s1-bypass")) {
+	if (of_property_read_bool(dev->of_node, "qcom,smmu-s1-bypass") ||
+		ipa3_ctx->ipa_config_is_mhi) {
 		smmu_info.s1_bypass_arr[IPA_SMMU_CB_UC] = true;
 		ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_UC] = true;
 
@@ -5985,7 +6012,7 @@
 
 static int ipa_smmu_ap_cb_probe(struct device *dev)
 {
-	struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx();
+	struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_AP);
 	int result;
 	int atomic_ctx = 1;
 	int fast = 1;
@@ -5999,6 +6026,11 @@
 
 	IPADBG("AP CB probe: sub pdev=%p\n", dev);
 
+	if (!smmu_info.present[IPA_SMMU_CB_AP]) {
+		IPAERR("AP SMMU is disabled");
+		return 0;
+	}
+
 	result = of_property_read_u32_array(dev->of_node, "qcom,iova-mapping",
 		iova_ap_mapping, 2);
 	if (result) {
@@ -6036,8 +6068,9 @@
 	cb->valid = true;
 
 	if (of_property_read_bool(dev->of_node,
-		"qcom,smmu-s1-bypass")) {
+		"qcom,smmu-s1-bypass") || ipa3_ctx->ipa_config_is_mhi) {
 		smmu_info.s1_bypass_arr[IPA_SMMU_CB_AP] = true;
+		ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_AP] = true;
 		if (iommu_domain_set_attr(cb->mapping->domain,
 				DOMAIN_ATTR_S1_BYPASS,
 				&bypass)) {
@@ -6049,6 +6082,7 @@
 		IPADBG("AP/USB SMMU S1 BYPASS\n");
 	} else {
 		smmu_info.s1_bypass_arr[IPA_SMMU_CB_AP] = false;
+		ipa3_ctx->s1_bypass_arr[IPA_SMMU_CB_AP] = false;
 		if (iommu_domain_set_attr(cb->mapping->domain,
 				DOMAIN_ATTR_ATOMIC,
 				&atomic_ctx)) {
@@ -6138,24 +6172,49 @@
 	}
 
 
-	smmu_info.present = true;
-
-	if (!ipa3_bus_scale_table)
-		ipa3_bus_scale_table = msm_bus_cl_get_pdata(ipa3_pdev);
-
-	/* Proceed to real initialization */
-	result = ipa3_pre_init(&ipa3_res, dev);
-	if (result) {
-		IPAERR("ipa_init failed\n");
-		arm_iommu_detach_device(cb->dev);
-		arm_iommu_release_mapping(cb->mapping);
-		cb->valid = false;
-		return result;
-	}
+	smmu_info.present[IPA_SMMU_CB_AP] = true;
+	ipa3_ctx->pdev = dev;
 
 	return result;
 }
 
+static int ipa_smmu_cb_probe(struct device *dev, enum ipa_smmu_cb_type cb_type)
+{
+	switch (cb_type) {
+	case IPA_SMMU_CB_AP:
+		return ipa_smmu_ap_cb_probe(dev);
+	case IPA_SMMU_CB_WLAN:
+		return ipa_smmu_wlan_cb_probe(dev);
+	case IPA_SMMU_CB_UC:
+		return ipa_smmu_uc_cb_probe(dev);
+	case IPA_SMMU_CB_MAX:
+		IPAERR("Invalid cb_type\n");
+	}
+	return 0;
+}
+
+static int ipa3_attach_to_smmu(void)
+{
+	struct ipa_smmu_cb_ctx *cb;
+	int i, result;
+
+	ipa3_ctx->pdev = &ipa3_ctx->master_pdev->dev;
+	ipa3_ctx->uc_pdev = &ipa3_ctx->master_pdev->dev;
+
+	if (smmu_info.arm_smmu) {
+		IPADBG("smmu is enabled\n");
+		for (i = 0; i < IPA_SMMU_CB_MAX; i++) {
+			cb = ipa3_get_smmu_ctx(i);
+			result = ipa_smmu_cb_probe(cb->dev, i);
+			if (result)
+				IPAERR("probe failed for cb %d\n", i);
+		}
+	} else {
+		IPADBG("smmu is disabled\n");
+	}
+	return 0;
+}
+
 static irqreturn_t ipa3_smp2p_modem_clk_query_isr(int irq, void *ctxt)
 {
 	ipa3_freeze_clock_vote_and_notify_modem();
@@ -6226,18 +6285,34 @@
 {
 	int result;
 	struct device *dev = &pdev_p->dev;
+	struct ipa_smmu_cb_ctx *cb;
 
 	IPADBG("IPA driver probing started\n");
 	IPADBG("dev->of_node->name = %s\n", dev->of_node->name);
 
-	if (of_device_is_compatible(dev->of_node, "qcom,ipa-smmu-ap-cb"))
-		return ipa_smmu_ap_cb_probe(dev);
+	if (of_device_is_compatible(dev->of_node, "qcom,ipa-smmu-ap-cb")) {
+		cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_AP);
+		cb->dev = dev;
+		smmu_info.present[IPA_SMMU_CB_AP] = true;
 
-	if (of_device_is_compatible(dev->of_node, "qcom,ipa-smmu-wlan-cb"))
-		return ipa_smmu_wlan_cb_probe(dev);
+		return 0;
+	}
 
-	if (of_device_is_compatible(dev->of_node, "qcom,ipa-smmu-uc-cb"))
-		return ipa_smmu_uc_cb_probe(dev);
+	if (of_device_is_compatible(dev->of_node, "qcom,ipa-smmu-wlan-cb")) {
+		cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_WLAN);
+		cb->dev = dev;
+		smmu_info.present[IPA_SMMU_CB_WLAN] = true;
+
+		return 0;
+	}
+
+	if (of_device_is_compatible(dev->of_node, "qcom,ipa-smmu-uc-cb")) {
+		cb =  ipa3_get_smmu_ctx(IPA_SMMU_CB_UC);
+		cb->dev = dev;
+		smmu_info.present[IPA_SMMU_CB_UC] = true;
+
+		return 0;
+	}
 
 	if (of_device_is_compatible(dev->of_node,
 	    "qcom,smp2pgpio-map-ipa-1-in"))
@@ -6247,10 +6322,6 @@
 	    "qcom,smp2pgpio-map-ipa-1-out"))
 		return ipa3_smp2p_probe(dev);
 
-	master_dev = dev;
-	if (!ipa3_pdev)
-		ipa3_pdev = pdev_p;
-
 	result = get_ipa_dts_configuration(pdev_p, &ipa3_res);
 	if (result) {
 		IPAERR("IPA dts parsing failed\n");
@@ -6292,15 +6363,13 @@
 				return -EOPNOTSUPP;
 			}
 		}
+	}
 
-		if (!ipa3_bus_scale_table)
-			ipa3_bus_scale_table = msm_bus_cl_get_pdata(pdev_p);
-		/* Proceed to real initialization */
-		result = ipa3_pre_init(&ipa3_res, dev);
-		if (result) {
-			IPAERR("ipa3_init failed\n");
-			return result;
-		}
+	/* Proceed to real initialization */
+	result = ipa3_pre_init(&ipa3_res, pdev_p);
+	if (result) {
+		IPAERR("ipa3_init failed\n");
+		return result;
 	}
 
 	result = of_platform_populate(pdev_p->dev.of_node,
@@ -6448,8 +6517,8 @@
 int ipa3_iommu_map(struct iommu_domain *domain,
 	unsigned long iova, phys_addr_t paddr, size_t size, int prot)
 {
-	struct ipa_smmu_cb_ctx *ap_cb = ipa3_get_smmu_ctx();
-	struct ipa_smmu_cb_ctx *uc_cb = ipa3_get_uc_smmu_ctx();
+	struct ipa_smmu_cb_ctx *ap_cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_AP);
+	struct ipa_smmu_cb_ctx *uc_cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_UC);
 
 	IPADBG("domain =0x%p iova 0x%lx\n", domain, iova);
 	IPADBG("paddr =0x%pa size 0x%x\n", &paddr, (u32)size);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index d0db35a..fd81f49 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -1161,11 +1161,22 @@
 };
 
 /**
- * struct ipa3_context - IPA context
+ * struct ipa3_char_device_context - IPA character device
  * @class: pointer to the struct class
  * @dev_num: device number
  * @dev: the dev_t of the device
  * @cdev: cdev of the device
+ */
+struct ipa3_char_device_context {
+	struct class *class;
+	dev_t dev_num;
+	struct device *dev;
+	struct cdev cdev;
+};
+
+/**
+ * struct ipa3_context - IPA context
+ * @cdev: cdev context
  * @ep: list of all end points
  * @skip_ep_cfg_shadow: state to update filter table correctly across
   power-save
@@ -1251,10 +1262,7 @@
  * IPA context - holds all relevant info about IPA driver and its state
  */
 struct ipa3_context {
-	struct class *class;
-	dev_t dev_num;
-	struct device *dev;
-	struct cdev cdev;
+	struct ipa3_char_device_context cdev;
 	struct ipa3_ep_context ep[IPA3_MAX_NUM_PIPES];
 	bool skip_ep_cfg_shadow[IPA3_MAX_NUM_PIPES];
 	u32 ep_flt_bitmap;
@@ -1336,6 +1344,7 @@
 	u32 ipa_bus_hdl;
 	struct ipa3_controller *ctrl;
 	struct idr ipa_idr;
+	struct platform_device *master_pdev;
 	struct device *pdev;
 	struct device *uc_pdev;
 	spinlock_t idr_lock;
@@ -2278,9 +2287,7 @@
 int ipa_reset_all_flt_rt_stats(enum ipa_ip_type ip, bool filtering);
 
 u32 ipa3_get_num_pipes(void);
-struct ipa_smmu_cb_ctx *ipa3_get_smmu_ctx(void);
-struct ipa_smmu_cb_ctx *ipa3_get_wlan_smmu_ctx(void);
-struct ipa_smmu_cb_ctx *ipa3_get_uc_smmu_ctx(void);
+struct ipa_smmu_cb_ctx *ipa3_get_smmu_ctx(enum ipa_smmu_cb_type);
 struct iommu_domain *ipa3_get_smmu_domain(void);
 struct iommu_domain *ipa3_get_uc_smmu_domain(void);
 struct iommu_domain *ipa3_get_wlan_smmu_domain(void);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
index ec777bc..13d2511 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
@@ -495,7 +495,7 @@
 static int ipa_create_uc_smmu_mapping_pa(phys_addr_t pa, size_t len,
 		bool device, unsigned long *iova)
 {
-	struct ipa_smmu_cb_ctx *cb = ipa3_get_uc_smmu_ctx();
+	struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_UC);
 	unsigned long va = roundup(cb->next_addr, PAGE_SIZE);
 	int prot = IOMMU_READ | IOMMU_WRITE;
 	size_t true_len = roundup(len + pa - rounddown(pa, PAGE_SIZE),
@@ -524,7 +524,7 @@
 static int ipa_create_uc_smmu_mapping_sgt(struct sg_table *sgt,
 		unsigned long *iova)
 {
-	struct ipa_smmu_cb_ctx *cb = ipa3_get_uc_smmu_ctx();
+	struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_UC);
 	unsigned long va = roundup(cb->next_addr, PAGE_SIZE);
 	int prot = IOMMU_READ | IOMMU_WRITE;
 	int ret;
@@ -573,7 +573,7 @@
 
 static void ipa_release_uc_smmu_mappings(enum ipa_client_type client)
 {
-	struct ipa_smmu_cb_ctx *cb = ipa3_get_uc_smmu_ctx();
+	struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_UC);
 	int i;
 	int j;
 	int start;
@@ -1810,7 +1810,7 @@
 
 int ipa3_create_wdi_mapping(u32 num_buffers, struct ipa_wdi_buffer_info *info)
 {
-	struct ipa_smmu_cb_ctx *cb = ipa3_get_wlan_smmu_ctx();
+	struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_WLAN);
 	int i;
 	int ret = 0;
 	int prot = IOMMU_READ | IOMMU_WRITE;
@@ -1846,7 +1846,7 @@
 
 int ipa3_release_wdi_mapping(u32 num_buffers, struct ipa_wdi_buffer_info *info)
 {
-	struct ipa_smmu_cb_ctx *cb = ipa3_get_wlan_smmu_ctx();
+	struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_WLAN);
 	int i;
 	int ret = 0;
 
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index 5ea78b9..d26679a 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -1477,53 +1477,6 @@
 			{ 31, 31, 8, 8, IPA_EE_AP } },
 };
 
-static struct msm_bus_vectors ipa_init_vectors_v3_0[]  = {
-	{
-		.src = MSM_BUS_MASTER_IPA,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 0,
-		.ib = 0,
-	},
-	{
-		.src = MSM_BUS_MASTER_IPA,
-		.dst = MSM_BUS_SLAVE_OCIMEM,
-		.ab = 0,
-		.ib = 0,
-	},
-};
-
-static struct msm_bus_vectors ipa_nominal_perf_vectors_v3_0[]  = {
-	{
-		.src = MSM_BUS_MASTER_IPA,
-		.dst = MSM_BUS_SLAVE_EBI_CH0,
-		.ab = 100000000,
-		.ib = 1300000000,
-	},
-	{
-		.src = MSM_BUS_MASTER_IPA,
-		.dst = MSM_BUS_SLAVE_OCIMEM,
-		.ab = 100000000,
-		.ib = 1300000000,
-	},
-};
-
-static struct msm_bus_paths ipa_usecases_v3_0[]  = {
-	{
-		.num_paths = ARRAY_SIZE(ipa_init_vectors_v3_0),
-		.vectors = ipa_init_vectors_v3_0,
-	},
-	{
-		.num_paths = ARRAY_SIZE(ipa_nominal_perf_vectors_v3_0),
-		.vectors = ipa_nominal_perf_vectors_v3_0,
-	},
-};
-
-static struct msm_bus_scale_pdata ipa_bus_client_pdata_v3_0 = {
-	.usecase = ipa_usecases_v3_0,
-	.num_usecases = ARRAY_SIZE(ipa_usecases_v3_0),
-	.name = "ipa",
-};
-
 /**
  * ipa3_get_clients_from_rm_resource() - get IPA clients which are related to an
  * IPA_RM resource
@@ -3786,7 +3739,6 @@
 	ctrl->ipa3_commit_hdr = __ipa_commit_hdr_v3_0;
 	ctrl->ipa3_enable_clks = _ipa_enable_clks_v3_0;
 	ctrl->ipa3_disable_clks = _ipa_disable_clks_v3_0;
-	ctrl->msm_bus_data_ptr = &ipa_bus_client_pdata_v3_0;
 	ctrl->clock_scaling_bw_threshold_svs =
 		IPA_V3_0_BW_THRESHOLD_SVS_MBPS;
 	ctrl->clock_scaling_bw_threshold_nominal =
diff --git a/drivers/platform/msm/msm_rmnet_bam.c b/drivers/platform/msm/msm_rmnet_bam.c
new file mode 100644
index 0000000..8d59af0
--- /dev/null
+++ b/drivers/platform/msm/msm_rmnet_bam.c
@@ -0,0 +1,945 @@
+/* Copyright (c) 2011-2016, 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.
+ *
+ */
+
+/*
+ * RMNET BAM Module.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/msm_rmnet.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+
+#include <net/pkt_sched.h>
+
+#include <soc/qcom/bam_dmux.h>
+
+/* Debug message support */
+static int msm_rmnet_bam_debug_mask;
+module_param_named(debug_enable, msm_rmnet_bam_debug_mask, int, 0664);
+			/* S_IRUGO | S_IWUSR | S_IWGRP */
+
+static unsigned long int msm_rmnet_bam_headroom_check_failure;
+module_param(msm_rmnet_bam_headroom_check_failure, ulong, 0444); /*S_IRUGO*/
+MODULE_PARM_DESC(msm_rmnet_bam_headroom_check_failure,
+		 "Number of packets with insufficient headroom");
+
+/* Packet threshold. */
+static unsigned int pkt_threshold = 1;
+module_param(pkt_threshold, uint, 0664); /* S_IRUGO | S_IWUSR | S_IWGRP */
+
+#define DEBUG_MASK_LVL0 (1U << 0)
+#define DEBUG_MASK_LVL1 (1U << 1)
+#define DEBUG_MASK_LVL2 (1U << 2)
+
+#define DBG(m, x...) do {			   \
+		if (msm_rmnet_bam_debug_mask & m) \
+			pr_info(x);		   \
+} while (0)
+#define DBG0(x...) DBG(DEBUG_MASK_LVL0, x)
+#define DBG1(x...) DBG(DEBUG_MASK_LVL1, x)
+#define DBG2(x...) DBG(DEBUG_MASK_LVL2, x)
+
+/* allow larger frames */
+#define RMNET_DATA_LEN 2000
+
+#define RMNET_BAM_DRIVER_NAME "rmnet_bam"
+
+#define DEVICE_ID_INVALID   -1
+
+#define DEVICE_INACTIVE      2
+#define DEVICE_ACTIVE        1
+#define DEVICE_UNINITIALIZED 0
+
+#define HEADROOM_FOR_BAM   8 /* for mux header */
+#define HEADROOM_FOR_QOS    8
+#define TAILROOM            8 /* for padding by mux layer */
+
+struct rmnet_private {
+	struct net_device_stats stats;
+	uint32_t ch_id;
+#ifdef CONFIG_MSM_RMNET_DEBUG
+	ktime_t last_packet;
+	unsigned long wakeups_xmit;
+	unsigned long wakeups_rcv;
+	unsigned long timeout_us;
+#endif
+	struct sk_buff *waiting_for_ul_skb;
+	spinlock_t lock;
+	spinlock_t tx_queue_lock;
+	struct tasklet_struct tsklt;
+	u32 operation_mode; /* IOCTL specified mode (protocol, QoS header) */
+	uint8_t device_up;
+	uint8_t in_reset;
+};
+
+struct rmnet_free_bam_work {
+	struct work_struct work;
+	uint32_t ch_id;
+};
+
+#ifdef CONFIG_MSM_RMNET_DEBUG
+static unsigned long timeout_us;
+
+/* Returns 1 if packet caused rmnet to wakeup, 0 otherwise. */
+static int rmnet_cause_wakeup(struct rmnet_private *p)
+{
+	int ret = 0;
+	ktime_t now;
+
+	if (p->timeout_us == 0) /* Check if disabled */
+		return 0;
+
+	/* Use real (wall) time. */
+	now = ktime_get_real();
+
+	if (ktime_us_delta(now, p->last_packet) > p->timeout_us)
+		ret = 1;
+
+	p->last_packet = now;
+	return ret;
+}
+
+static ssize_t wakeups_xmit_show(struct device *d,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	struct rmnet_private *p = netdev_priv(to_net_dev(d));
+
+	return snprintf(buf, PAGE_SIZE, "%lu\n", p->wakeups_xmit);
+}
+
+DEVICE_ATTR(wakeups_xmit, 0444, wakeups_xmit_show, NULL);
+
+static ssize_t wakeups_rcv_show(struct device *d, struct device_attribute *attr,
+				char *buf)
+{
+	struct rmnet_private *p = netdev_priv(to_net_dev(d));
+
+	return snprintf(buf, PAGE_SIZE, "%lu\n", p->wakeups_rcv);
+}
+
+DEVICE_ATTR(wakeups_rcv, 0444, wakeups_rcv_show, NULL);
+
+/* Set timeout in us. */
+static ssize_t timeout_store(struct device *d, struct device_attribute *attr,
+			     const char *buf, size_t n)
+{
+	struct rmnet_private *p = netdev_priv(to_net_dev(d));
+	int ret;
+
+	ret = kstrtoul(buf, 0, &timeout_us);
+	if (ret < 0)
+		return n;
+	p->timeout_us = timeout_us;
+	return n;
+}
+
+static ssize_t timeout_show(struct device *d, struct device_attribute *attr,
+			    char *buf)
+{
+	struct rmnet_private *p = netdev_priv(to_net_dev(d));
+
+	p = netdev_priv(to_net_dev(d));
+	return snprintf(buf, PAGE_SIZE, "%lu\n", timeout_us);
+}
+
+DEVICE_ATTR(timeout, 0664, timeout_show, timeout_store);
+#endif
+
+
+/* Forward declaration */
+static int rmnet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
+static struct platform_driver bam_rmnet_drivers[BAM_DMUX_NUM_CHANNELS];
+
+static struct net_device *netdevs[BAM_DMUX_NUM_CHANNELS];
+
+static __be16 rmnet_ip_type_trans(struct sk_buff *skb, struct net_device *dev)
+{
+	__be16 protocol = 0;
+
+	skb->dev = dev;
+
+	/* Determine L3 protocol */
+	switch (skb->data[0] & 0xf0) {
+	case 0x40:
+		protocol = htons(ETH_P_IP);
+		break;
+	case 0x60:
+		protocol = htons(ETH_P_IPV6);
+		break;
+	default:
+		protocol = htons(ETH_P_MAP);
+	}
+	return protocol;
+}
+
+static int count_this_packet(void *_hdr, int len)
+{
+	struct ethhdr *hdr = _hdr;
+
+	if (len >= ETH_HLEN && hdr->h_proto == htons(ETH_P_ARP))
+		return 0;
+
+	return 1;
+}
+
+/* Rx Callback, Called in Work Queue context */
+static void bam_recv_notify(void *dev, struct sk_buff *skb)
+{
+	struct rmnet_private *p = netdev_priv(dev);
+	unsigned long flags;
+	u32 opmode;
+
+	if (skb) {
+		skb->dev = dev;
+		/* Handle Rx frame format */
+		spin_lock_irqsave(&p->lock, flags);
+		opmode = p->operation_mode;
+		spin_unlock_irqrestore(&p->lock, flags);
+
+		if (RMNET_IS_MODE_IP(opmode)) {
+			/* Driver in IP mode */
+			skb->protocol = rmnet_ip_type_trans(skb, dev);
+		} else {
+			/* Driver in Ethernet mode */
+			skb->protocol = eth_type_trans(skb, dev);
+		}
+		if (RMNET_IS_MODE_IP(opmode) ||
+		    count_this_packet(skb->data, skb->len)) {
+#ifdef CONFIG_MSM_RMNET_DEBUG
+			p->wakeups_rcv += rmnet_cause_wakeup(p);
+#endif
+			p->stats.rx_packets++;
+			p->stats.rx_bytes += skb->len;
+		}
+		DBG1("[%s] Rx packet #%lu len=%d\n",
+			((struct net_device *)dev)->name,
+			p->stats.rx_packets, skb->len);
+
+		/* Deliver to network stack */
+		if (pkt_threshold == 1) {
+			netif_rx_ni(skb);
+		} else {
+			/* For every nth packet, use netif_rx_ni(). */
+			if (p->stats.rx_packets % pkt_threshold == 0)
+				netif_rx_ni(skb);
+			else
+				netif_rx(skb);
+		}
+	} else
+		pr_err("[%s] %s: No skb received",
+			((struct net_device *)dev)->name, __func__);
+}
+
+static struct sk_buff *_rmnet_add_headroom(struct sk_buff **skb,
+					   struct net_device *dev)
+{
+	struct sk_buff *skbn;
+
+	if (skb_headroom(*skb) < dev->needed_headroom) {
+		msm_rmnet_bam_headroom_check_failure++;
+		skbn = skb_realloc_headroom(*skb, dev->needed_headroom);
+		kfree_skb(*skb);
+		*skb = skbn;
+	} else {
+		skbn = *skb;
+	}
+
+	return skbn;
+}
+
+static int _rmnet_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct rmnet_private *p = netdev_priv(dev);
+	int bam_ret;
+	struct QMI_QOS_HDR_S *qmih;
+	u32 opmode;
+	unsigned long flags;
+
+	if (unlikely(!_rmnet_add_headroom(&skb, dev))) {
+		dev->stats.tx_dropped++;
+		return NETDEV_TX_OK;
+	}
+	/* For QoS mode, prepend QMI header and assign flow ID from skb->mark */
+	spin_lock_irqsave(&p->lock, flags);
+	opmode = p->operation_mode;
+	spin_unlock_irqrestore(&p->lock, flags);
+
+	if (RMNET_IS_MODE_QOS(opmode)) {
+		qmih = (struct QMI_QOS_HDR_S *)
+			skb_push(skb, sizeof(struct QMI_QOS_HDR_S));
+		qmih->version = 1;
+		qmih->flags = 0;
+		qmih->flow_id = skb->mark;
+	}
+
+	//Mayank dev->trans_start = jiffies;
+	/* if write() succeeds, skb access is unsafe in this process */
+	bam_ret = msm_bam_dmux_write(p->ch_id, skb);
+
+	if (bam_ret != 0 && bam_ret != -EAGAIN && bam_ret != -EFAULT) {
+		pr_err("[%s] %s: write returned error %d",
+			dev->name, __func__, bam_ret);
+		if (RMNET_IS_MODE_QOS(opmode))
+			skb_pull(skb, sizeof(struct QMI_QOS_HDR_S));
+		return -EPERM;
+	}
+
+	return bam_ret;
+}
+
+static void bam_write_done(void *dev, struct sk_buff *skb)
+{
+	struct rmnet_private *p = netdev_priv(dev);
+	u32 opmode = p->operation_mode;
+	unsigned long flags;
+
+	DBG1("%s: write complete\n", __func__);
+	if (RMNET_IS_MODE_IP(opmode) ||
+				count_this_packet(skb->data, skb->len)) {
+		p->stats.tx_packets++;
+		p->stats.tx_bytes += skb->len;
+#ifdef CONFIG_MSM_RMNET_DEBUG
+		p->wakeups_xmit += rmnet_cause_wakeup(p);
+#endif
+	}
+	DBG1("[%s] Tx packet #%lu len=%d mark=0x%x\n",
+	    ((struct net_device *)(dev))->name, p->stats.tx_packets,
+	    skb->len, skb->mark);
+	dev_kfree_skb_any(skb);
+
+	spin_lock_irqsave(&p->tx_queue_lock, flags);
+	if (netif_queue_stopped(dev) &&
+	    msm_bam_dmux_is_ch_low(p->ch_id)) {
+		DBG0("%s: Low WM hit, waking queue=%pK\n",
+		      __func__, skb);
+		netif_wake_queue(dev);
+	}
+	spin_unlock_irqrestore(&p->tx_queue_lock, flags);
+}
+
+static void bam_notify(void *dev, int event, unsigned long data)
+{
+	struct rmnet_private *p = netdev_priv(dev);
+	unsigned long flags;
+
+	switch (event) {
+	case BAM_DMUX_RECEIVE:
+		bam_recv_notify(dev, (struct sk_buff *)(data));
+		break;
+	case BAM_DMUX_WRITE_DONE:
+		bam_write_done(dev, (struct sk_buff *)(data));
+		break;
+	case BAM_DMUX_UL_CONNECTED:
+		spin_lock_irqsave(&p->lock, flags);
+		if (p->waiting_for_ul_skb != NULL) {
+			struct sk_buff *skb;
+			int ret;
+
+			skb = p->waiting_for_ul_skb;
+			p->waiting_for_ul_skb = NULL;
+			spin_unlock_irqrestore(&p->lock, flags);
+			ret = _rmnet_xmit(skb, dev);
+			if (ret) {
+				pr_err("%s: error %d dropping delayed TX SKB %pK\n",
+						__func__, ret, skb);
+				dev_kfree_skb_any(skb);
+			}
+			netif_wake_queue(dev);
+		} else {
+			spin_unlock_irqrestore(&p->lock, flags);
+		}
+		break;
+	case BAM_DMUX_UL_DISCONNECTED:
+		break;
+	}
+}
+
+static int __rmnet_open(struct net_device *dev)
+{
+	int r;
+	struct rmnet_private *p = netdev_priv(dev);
+
+	DBG0("[%s] __rmnet_open()\n", dev->name);
+
+	if (p->device_up == DEVICE_UNINITIALIZED) {
+		r = msm_bam_dmux_open(p->ch_id, dev, bam_notify);
+		if (r < 0) {
+			DBG0("%s: ch=%d failed with rc %d\n",
+					__func__, p->ch_id, r);
+			return -ENODEV;
+		}
+	}
+
+	p->device_up = DEVICE_ACTIVE;
+	return 0;
+}
+
+static int rmnet_open(struct net_device *dev)
+{
+	int rc = 0;
+
+	DBG0("[%s] rmnet_open()\n", dev->name);
+
+	rc = __rmnet_open(dev);
+
+	if (rc == 0)
+		netif_start_queue(dev);
+
+	return rc;
+}
+
+
+static int __rmnet_close(struct net_device *dev)
+{
+	struct rmnet_private *p = netdev_priv(dev);
+	int rc = 0;
+
+	if (p->device_up == DEVICE_ACTIVE) {
+		/* do not close rmnet port once up,  this causes
+		 * remote side to hang if tried to open again
+		 */
+		p->device_up = DEVICE_INACTIVE;
+		return rc;
+	} else
+		return -EBADF;
+}
+
+
+static int rmnet_stop(struct net_device *dev)
+{
+	DBG0("[%s] rmnet_stop()\n", dev->name);
+
+	__rmnet_close(dev);
+	netif_stop_queue(dev);
+
+	return 0;
+}
+
+static int rmnet_change_mtu(struct net_device *dev, int new_mtu)
+{
+	if (0 > new_mtu || RMNET_DATA_LEN < new_mtu)
+		return -EINVAL;
+
+	DBG0("[%s] MTU change: old=%d new=%d\n",
+		dev->name, dev->mtu, new_mtu);
+	dev->mtu = new_mtu;
+
+	return 0;
+}
+
+static int rmnet_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct rmnet_private *p = netdev_priv(dev);
+	unsigned long flags;
+	int awake;
+	int ret = 0;
+
+	if (netif_queue_stopped(dev)) {
+		pr_err("[%s]debug: rmnet_xmit called when netif_queue is stopped\n",
+				dev->name);
+		return NETDEV_TX_BUSY;
+	}
+
+	spin_lock_irqsave(&p->lock, flags);
+	awake = msm_bam_dmux_ul_power_vote();
+	if (!awake) {
+		/* send SKB once wakeup is complete */
+		netif_stop_queue(dev);
+		p->waiting_for_ul_skb = skb;
+		spin_unlock_irqrestore(&p->lock, flags);
+		ret = 0;
+		goto exit;
+	}
+	spin_unlock_irqrestore(&p->lock, flags);
+
+	ret = _rmnet_xmit(skb, dev);
+	if (ret == -EPERM) {
+		ret = NETDEV_TX_BUSY;
+		goto exit;
+	}
+
+	/*
+	 * detected SSR a bit early.  shut some things down now, and leave
+	 * the rest to the main ssr handling code when that happens later
+	 */
+	if (ret == -EFAULT) {
+		netif_carrier_off(dev);
+		dev_kfree_skb_any(skb);
+		ret = 0;
+		goto exit;
+	}
+
+	if (ret == -EAGAIN) {
+		/*
+		 * This should not happen
+		 * EAGAIN means we attempted to overflow the high watermark
+		 * Clearly the queue is not stopped like it should be, so
+		 * stop it and return BUSY to the TCP/IP framework.  It will
+		 * retry this packet with the queue is restarted which happens
+		 * in the write_done callback when the low watermark is hit.
+		 */
+		netif_stop_queue(dev);
+		ret = NETDEV_TX_BUSY;
+		goto exit;
+	}
+
+	spin_lock_irqsave(&p->tx_queue_lock, flags);
+	if (msm_bam_dmux_is_ch_full(p->ch_id)) {
+		netif_stop_queue(dev);
+		DBG0("%s: High WM hit, stopping queue=%pK\n",    __func__, skb);
+	}
+	spin_unlock_irqrestore(&p->tx_queue_lock, flags);
+
+exit:
+	msm_bam_dmux_ul_power_unvote();
+	return ret;
+}
+
+static struct net_device_stats *rmnet_get_stats(struct net_device *dev)
+{
+	struct rmnet_private *p = netdev_priv(dev);
+
+	return &p->stats;
+}
+
+static void rmnet_tx_timeout(struct net_device *dev)
+{
+	pr_warn("[%s] rmnet_tx_timeout()\n", dev->name);
+}
+
+static const struct net_device_ops rmnet_ops_ether = {
+	.ndo_open = rmnet_open,
+	.ndo_stop = rmnet_stop,
+	.ndo_start_xmit = rmnet_xmit,
+	.ndo_get_stats = rmnet_get_stats,
+	.ndo_tx_timeout = rmnet_tx_timeout,
+	.ndo_do_ioctl = rmnet_ioctl,
+	.ndo_change_mtu = rmnet_change_mtu,
+	.ndo_set_mac_address = eth_mac_addr,
+	.ndo_validate_addr = eth_validate_addr,
+};
+
+static const struct net_device_ops rmnet_ops_ip = {
+	.ndo_open = rmnet_open,
+	.ndo_stop = rmnet_stop,
+	.ndo_start_xmit = rmnet_xmit,
+	.ndo_get_stats = rmnet_get_stats,
+	.ndo_tx_timeout = rmnet_tx_timeout,
+	.ndo_do_ioctl = rmnet_ioctl,
+	.ndo_change_mtu = rmnet_change_mtu,
+	.ndo_set_mac_address = NULL,
+	.ndo_validate_addr = NULL,
+};
+
+static void _rmnet_free_bam_later(struct work_struct *work)
+{
+	struct rmnet_free_bam_work *fwork;
+
+	fwork = container_of(work, struct rmnet_free_bam_work, work);
+
+	DBG0("%s: unregister_netdev, done\n", __func__);
+
+	if (bam_rmnet_drivers[fwork->ch_id].remove) {
+		platform_driver_unregister(&bam_rmnet_drivers[fwork->ch_id]);
+		bam_rmnet_drivers[fwork->ch_id].remove = NULL;
+	}
+
+	DBG0("%s: free_netdev, done\n", __func__);
+
+	kfree(work);
+}
+
+static int rmnet_ioctl_extended(struct net_device *dev, struct ifreq *ifr)
+{
+	struct rmnet_ioctl_extended_s ext_cmd;
+	int rc = 0;
+	struct rmnet_private *p = netdev_priv(dev);
+	struct rmnet_free_bam_work *work;
+
+	rc = copy_from_user(&ext_cmd, ifr->ifr_ifru.ifru_data,
+			    sizeof(ext_cmd));
+
+	if (rc) {
+		pr_err("%s: copy_from_user failed ,error %d\n", __func__, rc);
+		return -EFAULT;
+	}
+
+	switch (ext_cmd.extended_ioctl) {
+	case RMNET_IOCTL_SET_MRU:
+		/* Transport MRU is fixed, so do nothing */
+		break;
+	case RMNET_IOCTL_GET_EPID:
+		ext_cmd.u.data = p->ch_id;
+		break;
+	case RMNET_IOCTL_GET_SUPPORTED_FEATURES:
+		ext_cmd.u.data = 0;
+		break;
+	case RMNET_IOCTL_GET_DRIVER_NAME:
+		strlcpy(ext_cmd.u.if_name, RMNET_BAM_DRIVER_NAME,
+			sizeof(ext_cmd.u.if_name));
+		break;
+	case RMNET_IOCTL_DEREGISTER_DEV:
+		work = kmalloc(sizeof(*work), GFP_KERNEL);
+		if (!work)
+			break;
+		INIT_WORK(&work->work, _rmnet_free_bam_later);
+
+		work->ch_id = p->ch_id;
+		schedule_work(&work->work);
+		break;
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	rc = copy_to_user(ifr->ifr_ifru.ifru_data, &ext_cmd, sizeof(ext_cmd));
+
+	if (rc)
+		pr_err("%s: copy_to_user failed, error %d\n", __func__, rc);
+
+	return rc ? -EFAULT : 0;
+}
+
+static int rmnet_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	struct rmnet_private *p = netdev_priv(dev);
+	u32 old_opmode = p->operation_mode;
+	unsigned long flags;
+	int prev_mtu = dev->mtu;
+	int rc = 0;
+	struct rmnet_ioctl_data_s ioctl_data;
+
+	/* Process IOCTL command */
+	switch (cmd) {
+	case RMNET_IOCTL_SET_LLP_ETHERNET:  /* Set Ethernet protocol   */
+		/* Perform Ethernet config only if in IP mode currently*/
+		if (p->operation_mode & RMNET_MODE_LLP_IP) {
+			ether_setup(dev);
+			random_ether_addr(dev->dev_addr);
+			dev->mtu = prev_mtu;
+
+			dev->netdev_ops = &rmnet_ops_ether;
+			spin_lock_irqsave(&p->lock, flags);
+			p->operation_mode &= ~RMNET_MODE_LLP_IP;
+			p->operation_mode |= RMNET_MODE_LLP_ETH;
+			spin_unlock_irqrestore(&p->lock, flags);
+			DBG0("[%s] rmnet_ioctl():set Ethernet protocol mode\n",
+				dev->name);
+		}
+		break;
+
+	case RMNET_IOCTL_SET_LLP_IP:        /* Set RAWIP protocol      */
+		/* Perform IP config only if in Ethernet mode currently*/
+		if (p->operation_mode & RMNET_MODE_LLP_ETH) {
+
+			/* Undo config done in ether_setup() */
+			dev->header_ops         = NULL;  /* No header */
+			dev->type               = ARPHRD_RAWIP;
+			dev->hard_header_len    = 0;
+			dev->mtu                = prev_mtu;
+			dev->addr_len           = 0;
+			dev->flags              &= ~(IFF_BROADCAST|
+						     IFF_MULTICAST);
+
+			dev->needed_headroom = HEADROOM_FOR_BAM +
+			  HEADROOM_FOR_QOS;
+			dev->needed_tailroom = TAILROOM;
+			dev->netdev_ops = &rmnet_ops_ip;
+			spin_lock_irqsave(&p->lock, flags);
+			p->operation_mode &= ~RMNET_MODE_LLP_ETH;
+			p->operation_mode |= RMNET_MODE_LLP_IP;
+			spin_unlock_irqrestore(&p->lock, flags);
+			DBG0("[%s] rmnet_ioctl(): set IP protocol mode\n",
+				dev->name);
+		}
+		break;
+
+	case RMNET_IOCTL_GET_LLP:           /* Get link protocol state */
+		ioctl_data.u.operation_mode = (p->operation_mode &
+				 (RMNET_MODE_LLP_ETH|RMNET_MODE_LLP_IP));
+		if (copy_to_user(ifr->ifr_ifru.ifru_data, &ioctl_data,
+			sizeof(struct rmnet_ioctl_data_s)))
+			rc = -EFAULT;
+		break;
+
+	case RMNET_IOCTL_SET_QOS_ENABLE:    /* Set QoS header enabled  */
+		spin_lock_irqsave(&p->lock, flags);
+		p->operation_mode |= RMNET_MODE_QOS;
+		spin_unlock_irqrestore(&p->lock, flags);
+		DBG0("[%s] rmnet_ioctl(): set QMI QOS header enable\n",
+			dev->name);
+		break;
+
+	case RMNET_IOCTL_SET_QOS_DISABLE:   /* Set QoS header disabled */
+		spin_lock_irqsave(&p->lock, flags);
+		p->operation_mode &= ~RMNET_MODE_QOS;
+		spin_unlock_irqrestore(&p->lock, flags);
+		DBG0("[%s] rmnet_ioctl(): set QMI QOS header disable\n",
+			dev->name);
+		break;
+
+	case RMNET_IOCTL_FLOW_ENABLE:
+		if (copy_from_user(&ioctl_data, ifr->ifr_ifru.ifru_data,
+			sizeof(struct rmnet_ioctl_data_s))) {
+			rc = -EFAULT;
+			break;
+		}
+		tc_qdisc_flow_control(dev, ioctl_data.u.tcm_handle, 1);
+		DBG0("[%s] rmnet_ioctl(): enabled flow\n", dev->name);
+		break;
+
+	case RMNET_IOCTL_FLOW_DISABLE:
+		if (copy_from_user(&ioctl_data, ifr->ifr_ifru.ifru_data,
+			sizeof(struct rmnet_ioctl_data_s))) {
+			rc = -EFAULT;
+			break;
+		}
+		tc_qdisc_flow_control(dev, ioctl_data.u.tcm_handle, 0);
+		DBG0("[%s] rmnet_ioctl(): disabled flow\n", dev->name);
+		break;
+
+	case RMNET_IOCTL_GET_QOS:           /* Get QoS header state    */
+		ioctl_data.u.operation_mode = (p->operation_mode
+						& RMNET_MODE_QOS);
+		if (copy_to_user(ifr->ifr_ifru.ifru_data, &ioctl_data,
+			sizeof(struct rmnet_ioctl_data_s)))
+			rc = -EFAULT;
+		break;
+
+	case RMNET_IOCTL_GET_OPMODE:        /* Get operation mode      */
+		ioctl_data.u.operation_mode = p->operation_mode;
+		if (copy_to_user(ifr->ifr_ifru.ifru_data, &ioctl_data,
+			sizeof(struct rmnet_ioctl_data_s)))
+			rc = -EFAULT;
+		break;
+
+	case RMNET_IOCTL_OPEN:              /* Open transport port     */
+		rc = __rmnet_open(dev);
+		DBG0("[%s] rmnet_ioctl(): open transport port\n",
+			dev->name);
+		break;
+
+	case RMNET_IOCTL_CLOSE:             /* Close transport port    */
+		rc = __rmnet_close(dev);
+		DBG0("[%s] rmnet_ioctl(): close transport port\n",
+			dev->name);
+		break;
+
+	case RMNET_IOCTL_EXTENDED:          /* Extended IOCTL's        */
+		rc = rmnet_ioctl_extended(dev, ifr);
+		break;
+
+	default:
+		pr_err("[%s] error: rmnet_ioct called for unsupported cmd[%x]\n",
+			dev->name, cmd);
+		return -EINVAL;
+	}
+
+	DBG2("[%s] %s: cmd=0x%x opmode old=0x%08x new=0x%08x\n",
+		dev->name, __func__, cmd, old_opmode, p->operation_mode);
+	return rc;
+}
+
+static void rmnet_setup(struct net_device *dev)
+{
+	/* Using Ethernet mode by default */
+	dev->netdev_ops = &rmnet_ops_ether;
+	ether_setup(dev);
+
+	/* set this after calling ether_setup */
+	dev->mtu = RMNET_DATA_LEN;
+	dev->needed_headroom = HEADROOM_FOR_BAM + HEADROOM_FOR_QOS;
+	dev->needed_tailroom = TAILROOM;
+	random_ether_addr(dev->dev_addr);
+
+	dev->watchdog_timeo = 1000; /* 10 seconds? */
+}
+
+
+#ifdef CONFIG_MSM_RMNET_DEBUG
+static int rmnet_debug_init(struct net_device *dev)
+{
+
+	struct device *d;
+	struct rmnet_private *p;
+	int err = 0;
+
+	d = &(dev->dev);
+	p = netdev_priv(dev);
+	p->timeout_us = 0;
+	p->wakeups_xmit = p->wakeups_rcv = 0;
+	err = device_create_file(d, &dev_attr_timeout);
+	if (err)
+		return err;
+	err = device_create_file(d, &dev_attr_wakeups_xmit);
+	if (err)
+		return err;
+	err = device_create_file(d, &dev_attr_wakeups_rcv);
+	return err;
+}
+#else
+static int rmnet_debug_init(struct net_device *dev)
+{
+	return 0;
+}
+#endif
+
+static int bam_rmnet_probe(struct platform_device *pdev)
+{
+	int i, ret;
+	struct rmnet_private *p;
+	struct device *d;
+	char name[BAM_DMUX_CH_NAME_MAX_LEN];
+	struct net_device *dev;
+	const char *dev_name;
+
+	for (i = 0; i < BAM_DMUX_NUM_CHANNELS; ++i) {
+		scnprintf(name, BAM_DMUX_CH_NAME_MAX_LEN, "bam_dmux_ch_%d", i);
+		if (!strcmp(pdev->name, name))
+			break;
+	}
+
+	if (((i > BAM_DMUX_DATA_RMNET_7) && (i < BAM_DMUX_DATA_REV_RMNET_0)) ||
+	    (i >= BAM_DMUX_NUM_CHANNELS)) {
+		pr_err("%s: wrong netdev %s\n", __func__, pdev->name);
+		return -ENODEV;
+	}
+
+	if (i <= BAM_DMUX_DATA_RMNET_7)
+		dev_name = "rmnet%d";
+	else
+		dev_name = "rev_rmnet%d";
+
+	dev = alloc_netdev(sizeof(*p), dev_name, NET_NAME_ENUM, rmnet_setup);
+	if (!dev) {
+		pr_err("%s: no memory for netdev %d\n", __func__, i);
+		return -ENOMEM;
+	}
+
+	netdevs[i] = dev;
+	d = &(dev->dev);
+	p = netdev_priv(dev);
+	/* Initial config uses Ethernet */
+	p->operation_mode = RMNET_MODE_LLP_ETH;
+	p->ch_id = i;
+	p->waiting_for_ul_skb = NULL;
+	p->device_up = DEVICE_UNINITIALIZED;
+	spin_lock_init(&p->lock);
+	spin_lock_init(&p->tx_queue_lock);
+
+	ret = register_netdev(dev);
+	if (ret) {
+		pr_err("%s: unable to register netdev %d rc=%d\n",
+			__func__, i, ret);
+		netdevs[i] = NULL;
+		free_netdev(dev);
+		return ret;
+	}
+
+	rmnet_debug_init(dev);
+
+	return 0;
+}
+
+static int bam_rmnet_remove(struct platform_device *pdev)
+{
+	int i;
+	struct rmnet_private *p;
+	char name[BAM_DMUX_CH_NAME_MAX_LEN];
+
+	for (i = 0; i < BAM_DMUX_NUM_CHANNELS; ++i) {
+		scnprintf(name, BAM_DMUX_CH_NAME_MAX_LEN, "bam_dmux_ch_%d", i);
+		if (!strcmp(pdev->name, name))
+			break;
+	}
+
+	if (((i > BAM_DMUX_DATA_RMNET_7) && (i < BAM_DMUX_DATA_REV_RMNET_0)) ||
+	    (i >= BAM_DMUX_NUM_CHANNELS)) {
+		pr_err("%s: wrong netdev %s\n", __func__, pdev->name);
+		return -ENODEV;
+	}
+
+	p = netdev_priv(netdevs[i]);
+	if (p->waiting_for_ul_skb != NULL) {
+		dev_kfree_skb_any(p->waiting_for_ul_skb);
+		p->waiting_for_ul_skb = NULL;
+	}
+	msm_bam_dmux_close(p->ch_id);
+	netif_carrier_off(netdevs[i]);
+	netif_stop_queue(netdevs[i]);
+
+	unregister_netdev(netdevs[i]);
+	free_netdev(netdevs[i]);
+
+	return 0;
+}
+
+#ifdef CONFIG_MSM_RMNET_DEBUG
+static void rmnet_clear_timeout_us(void)
+{
+	timeout_us = 0;
+}
+#else
+static void rmnet_clear_timeout_us(void)
+{
+	; /*Do Nothing*/
+}
+#endif /* CONFIG_MSM_RMNET_DEBUG */
+
+static int __init rmnet_init(void)
+{
+	unsigned int n;
+	char *tempname;
+
+	rmnet_clear_timeout_us();
+
+	n = 0;
+	while (n <= BAM_DMUX_DATA_REV_RMNET_8) {
+		if ((n > BAM_DMUX_DATA_RMNET_7) &&
+		    (n < BAM_DMUX_DATA_REV_RMNET_0)) {
+			n++;
+			continue;
+		}
+		bam_rmnet_drivers[n].probe = bam_rmnet_probe;
+		bam_rmnet_drivers[n].remove = bam_rmnet_remove;
+		tempname = kmalloc(BAM_DMUX_CH_NAME_MAX_LEN, GFP_KERNEL);
+		if (tempname == NULL) {
+			netdevs[n] = NULL;
+			return -ENOMEM;
+		}
+		scnprintf(tempname, BAM_DMUX_CH_NAME_MAX_LEN, "bam_dmux_ch_%d",
+			  n);
+		bam_rmnet_drivers[n].driver.name = tempname;
+		bam_rmnet_drivers[n].driver.owner = THIS_MODULE;
+		platform_driver_register(&bam_rmnet_drivers[n]);
+		n++;
+	}
+
+	return 0;
+}
+
+module_init(rmnet_init);
+MODULE_DESCRIPTION("MSM RMNET BAM TRANSPORT");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index 6314270..b4cd640 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -2729,12 +2729,12 @@
 
 		if (bam_type == CI_CTRL)
 			msm_hw_bam_disable(0);
-		/* Enable usb irq here which is disabled in function drivers
-		 * during disconnect after BAM reset.
-		 */
-		if (bam_type == CI_CTRL)
-			msm_usb_irq_disable(false);
 	}
+	/* Enable usb irq here which is disabled in function drivers
+	 * during disconnect after BAM reset.
+	 */
+	if (!ctx->pipes_enabled_per_bam && (bam_type == CI_CTRL))
+		msm_usb_irq_disable(false);
 	/* This function is directly called by USB Transport drivers
 	 * to disconnect pipes. Drop runtime usage count here. For
 	 * IPA, caller takes care of it
@@ -3136,6 +3136,7 @@
 					&& bam_type == CI_CTRL) {
 		pr_debug("Register and enable HSUSB BAM\n");
 		props.options |= SPS_BAM_OPT_ENABLE_AT_BOOT;
+		props.options |= SPS_BAM_FORCE_RESET;
 	}
 
 	dev = &ctx->usb_bam_pdev->dev;
@@ -3406,6 +3407,127 @@
 }
 EXPORT_SYMBOL(usb_bam_get_bam_type);
 
+/*
+ * This function makes sure ipa endpoints are disabled for both USB->IPA
+ * and IPA->USB pipes before USB bam reset. USB BAM reset is required to
+ * to avoid EP flush issues while disabling USB endpoints on disconnect.
+ */
+int msm_do_bam_disable_enable(enum usb_ctrl bam)
+{
+	struct usb_bam_ctx_type *ctx = &msm_usb_bam[bam];
+	struct sps_pipe *pipe;
+	u32 timeout = 10, pipe_empty;
+	int ret = 0, i;
+	struct sps_connect *sps_connection;
+	struct usb_bam_sps_type usb_bam_sps = ctx->usb_bam_sps;
+	struct usb_bam_pipe_connect *pipe_connect;
+	int qdss_idx;
+	struct msm_usb_bam_data *usb_bam_data;
+
+	if (!ctx->usb_bam_pdev)
+		return 0;
+
+	usb_bam_data = ctx->usb_bam_data;
+	if ((bam != CI_CTRL) || !usb_bam_data->enable_hsusb_bam_on_boot)
+		return 0;
+
+	if (!ctx->pipes_enabled_per_bam || info[bam].pipes_suspended)
+		return 0;
+
+	if (in_interrupt()) {
+		pr_err("%s:API called in interrupt context\n", __func__);
+		return 0;
+	}
+
+	mutex_lock(&info[bam].suspend_resume_mutex);
+	log_event_dbg("%s: Perform USB BAM reset\n", __func__);
+	/* Get QDSS pipe index to avoid pipe reset */
+	qdss_idx = usb_bam_get_connection_idx(qdss_usb_bam_type, QDSS_P_BAM,
+		PEER_PERIPHERAL_TO_USB, USB_BAM_DEVICE, 0);
+
+	for (i = 0; i < ctx->max_connections; i++) {
+		pipe_connect = &ctx->usb_bam_connections[i];
+		if (pipe_connect->enabled &&
+				(pipe_connect->dir == PEER_PERIPHERAL_TO_USB) &&
+							(qdss_idx != i)) {
+			/* Call to disable IPA producer endpoint */
+			ipa_disable_endpoint(pipe_connect->ipa_clnt_hdl);
+			sps_pipe_reset(ctx->h_bam,
+						pipe_connect->dst_pipe_index);
+		}
+	}
+
+	for (i = 0; i < ctx->max_connections; i++) {
+		pipe_connect = &ctx->usb_bam_connections[i];
+		if (pipe_connect->enabled &&
+				(pipe_connect->dir == USB_TO_PEER_PERIPHERAL) &&
+							(qdss_idx != i)) {
+			pipe = ctx->usb_bam_sps.sps_pipes[i];
+			sps_connection = &usb_bam_sps.sps_connections[i];
+			timeout = 10;
+			/*
+			 * On some platforms, there is a chance that flow
+			 * control is disabled from IPA side, due to this IPA
+			 * core may not consume data from USB. Hence notify IPA
+			 * to enable flow control and then check sps pipe is
+			 * empty or not before processing USB->IPA disconnect.
+			 */
+			ipa_clear_endpoint_delay(pipe_connect->ipa_clnt_hdl);
+
+			/* Make sure pipes are empty before disconnecting it */
+			while (1) {
+				ret = sps_is_pipe_empty(pipe, &pipe_empty);
+				if (ret) {
+					log_event_err("%s: pipeempty fail %d\n",
+								__func__, ret);
+					goto err;
+				}
+				if (pipe_empty || !--timeout)
+					break;
+
+				/* Check again */
+				usleep_range(1000, 2000);
+			}
+			if (!pipe_empty) {
+				log_event_dbg("%s: Inject ZLT\n", __func__);
+				sps_pipe_inject_zlt(sps_connection->destination,
+					sps_connection->dest_pipe_index);
+
+				timeout = 0;
+				while (1) {
+					ret = sps_is_pipe_empty(pipe,
+								&pipe_empty);
+					if (ret)
+						goto err;
+
+					if (pipe_empty)
+						break;
+
+					timeout++;
+					/* Check again */
+					usleep_range(1000, 2000);
+				}
+			}
+			/* Call to disable IPA consumer endpoint */
+			ipa_disable_endpoint(pipe_connect->ipa_clnt_hdl);
+			sps_pipe_reset(ctx->h_bam,
+						pipe_connect->src_pipe_index);
+		}
+	}
+
+	/* Perform USB BAM reset */
+	msm_hw_bam_disable(1);
+	sps_device_reset(ctx->h_bam);
+	msm_hw_bam_disable(0);
+	log_event_dbg("%s: USB BAM reset done\n", __func__);
+	ret = 0;
+
+err:
+	mutex_unlock(&info[bam].suspend_resume_mutex);
+	return ret;
+}
+EXPORT_SYMBOL(msm_do_bam_disable_enable);
+
 bool msm_usb_bam_enable(enum usb_ctrl bam, bool bam_enable)
 {
 	struct msm_usb_bam_data *usb_bam_data;
diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c
index 35c8bb9..03bfd48 100644
--- a/drivers/power/supply/power_supply_sysfs.c
+++ b/drivers/power/supply/power_supply_sysfs.c
@@ -328,6 +328,7 @@
 	POWER_SUPPLY_ATTR(batt_full_current),
 	POWER_SUPPLY_ATTR(recharge_soc),
 	POWER_SUPPLY_ATTR(toggle_stat),
+	POWER_SUPPLY_ATTR(allow_hvdcp3),
 	/* Local extensions of type int64_t */
 	POWER_SUPPLY_ATTR(charge_counter_ext),
 	/* Properties of type `const char *' */
diff --git a/drivers/power/supply/qcom/fg-core.h b/drivers/power/supply/qcom/fg-core.h
index 76bb974..4bd6c4f 100644
--- a/drivers/power/supply/qcom/fg-core.h
+++ b/drivers/power/supply/qcom/fg-core.h
@@ -13,6 +13,7 @@
 #ifndef __FG_CORE_H__
 #define __FG_CORE_H__
 
+#include <linux/alarmtimer.h>
 #include <linux/atomic.h>
 #include <linux/bitops.h>
 #include <linux/debugfs.h>
@@ -249,6 +250,12 @@
 	SLOPE_LIMIT_NUM_COEFFS,
 };
 
+enum esr_filter_status {
+	ROOM_TEMP = 1,
+	LOW_TEMP,
+	RELAX_TEMP,
+};
+
 enum esr_timer_config {
 	TIMER_RETRY = 0,
 	TIMER_MAX,
@@ -296,6 +303,9 @@
 	int	esr_broad_flt_upct;
 	int	esr_tight_lt_flt_upct;
 	int	esr_broad_lt_flt_upct;
+	int	esr_flt_rt_switch_temp;
+	int	esr_tight_rt_flt_upct;
+	int	esr_broad_rt_flt_upct;
 	int	slope_limit_temp;
 	int	esr_pulse_thresh_ma;
 	int	esr_meas_curr_ma;
@@ -434,6 +444,7 @@
 	struct mutex		sram_rw_lock;
 	struct mutex		charge_full_lock;
 	struct mutex		qnovo_esr_ctrl_lock;
+	spinlock_t		suspend_lock;
 	u32			batt_soc_base;
 	u32			batt_info_base;
 	u32			mem_if_base;
@@ -453,8 +464,10 @@
 	int			delta_soc;
 	int			last_msoc;
 	int			last_recharge_volt_mv;
+	int			delta_temp_irq_count;
 	int			esr_timer_charging_default[NUM_ESR_TIMERS];
 	enum slope_limit_status	slope_limit_sts;
+	enum esr_filter_status	esr_flt_sts;
 	bool			profile_available;
 	bool			profile_loaded;
 	enum prof_load_status	profile_load_status;
@@ -470,6 +483,7 @@
 	bool			use_ima_single_mode;
 	bool			use_dma;
 	bool			qnovo_enable;
+	bool			suspended;
 	struct completion	soc_update;
 	struct completion	soc_ready;
 	struct delayed_work	profile_load_work;
@@ -477,6 +491,9 @@
 	struct delayed_work	ttf_work;
 	struct delayed_work	sram_dump_work;
 	struct delayed_work	pl_enable_work;
+	struct work_struct	esr_filter_work;
+	struct alarm		esr_filter_alarm;
+	ktime_t			last_delta_temp_time;
 };
 
 /* Debugfs data structures are below */
diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c
index 420f2fd..5a9b8f6 100644
--- a/drivers/power/supply/qcom/qpnp-fg-gen3.c
+++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c
@@ -2205,10 +2205,66 @@
 	return 0;
 }
 
-static int fg_esr_filter_config(struct fg_chip *chip, int batt_temp)
+static int __fg_esr_filter_config(struct fg_chip *chip,
+				enum esr_filter_status esr_flt_sts)
 {
-	u8 esr_tight_lt_flt, esr_broad_lt_flt;
-	bool cold_temp = false;
+	u8 esr_tight_flt, esr_broad_flt;
+	int esr_tight_flt_upct, esr_broad_flt_upct;
+	int rc;
+
+	if (esr_flt_sts == chip->esr_flt_sts)
+		return 0;
+
+	if (esr_flt_sts == ROOM_TEMP) {
+		esr_tight_flt_upct = chip->dt.esr_tight_flt_upct;
+		esr_broad_flt_upct = chip->dt.esr_broad_flt_upct;
+	} else if (esr_flt_sts == LOW_TEMP) {
+		esr_tight_flt_upct = chip->dt.esr_tight_lt_flt_upct;
+		esr_broad_flt_upct = chip->dt.esr_broad_lt_flt_upct;
+	} else if (esr_flt_sts == RELAX_TEMP) {
+		esr_tight_flt_upct = chip->dt.esr_tight_rt_flt_upct;
+		esr_broad_flt_upct = chip->dt.esr_broad_rt_flt_upct;
+	} else {
+		pr_err("Unknown esr filter config\n");
+		return 0;
+	}
+
+	fg_encode(chip->sp, FG_SRAM_ESR_TIGHT_FILTER, esr_tight_flt_upct,
+		&esr_tight_flt);
+	rc = fg_sram_write(chip, chip->sp[FG_SRAM_ESR_TIGHT_FILTER].addr_word,
+			chip->sp[FG_SRAM_ESR_TIGHT_FILTER].addr_byte,
+			&esr_tight_flt,
+			chip->sp[FG_SRAM_ESR_TIGHT_FILTER].len, FG_IMA_DEFAULT);
+	if (rc < 0) {
+		pr_err("Error in writing ESR LT tight filter, rc=%d\n", rc);
+		return rc;
+	}
+
+	fg_encode(chip->sp, FG_SRAM_ESR_BROAD_FILTER, esr_broad_flt_upct,
+		&esr_broad_flt);
+	rc = fg_sram_write(chip, chip->sp[FG_SRAM_ESR_BROAD_FILTER].addr_word,
+			chip->sp[FG_SRAM_ESR_BROAD_FILTER].addr_byte,
+			&esr_broad_flt,
+			chip->sp[FG_SRAM_ESR_BROAD_FILTER].len, FG_IMA_DEFAULT);
+	if (rc < 0) {
+		pr_err("Error in writing ESR LT broad filter, rc=%d\n", rc);
+		return rc;
+	}
+
+	chip->esr_flt_sts = esr_flt_sts;
+	fg_dbg(chip, FG_STATUS, "applied ESR filter %d values\n", esr_flt_sts);
+	return 0;
+}
+
+#define DT_IRQ_COUNT			3
+#define DELTA_TEMP_IRQ_TIME_MS		300000
+#define ESR_FILTER_ALARM_TIME_MS	900000
+static int fg_esr_filter_config(struct fg_chip *chip, int batt_temp,
+				bool override)
+{
+	enum esr_filter_status esr_flt_sts = ROOM_TEMP;
+	bool qnovo_en, input_present, count_temp_irq = false;
+	s64 time_ms;
 	int rc;
 
 	/*
@@ -2218,6 +2274,47 @@
 	if (batt_temp < -210)
 		return 0;
 
+	qnovo_en = is_qnovo_en(chip);
+	input_present = is_input_present(chip);
+
+	/*
+	 * If Qnovo is enabled, after hitting a lower battery temperature of
+	 * say 6 C, count the delta battery temperature interrupts for a
+	 * certain period of time when the battery temperature increases.
+	 * Switch to relaxed filter coefficients once the temperature increase
+	 * is qualified so that ESR accuracy can be improved.
+	 */
+	if (qnovo_en && !override) {
+		if (input_present) {
+			if (chip->esr_flt_sts == RELAX_TEMP) {
+				/* do nothing */
+				return 0;
+			}
+
+			count_temp_irq =  true;
+			if (chip->delta_temp_irq_count) {
+				/* Don't count when temperature is dropping. */
+				if (batt_temp <= chip->last_batt_temp)
+					count_temp_irq = false;
+			} else {
+				/*
+				 * Starting point for counting. Check if the
+				 * temperature is qualified.
+				 */
+				if (batt_temp > chip->dt.esr_flt_rt_switch_temp)
+					count_temp_irq = false;
+				else
+					chip->last_delta_temp_time =
+						ktime_get();
+			}
+		} else {
+			chip->delta_temp_irq_count = 0;
+			rc = alarm_try_to_cancel(&chip->esr_filter_alarm);
+			if (rc < 0)
+				pr_err("Couldn't cancel esr_filter_alarm\n");
+		}
+	}
+
 	/*
 	 * If battery temperature is lesser than 10 C (default), then apply the
 	 * ESR low temperature tight and broad filter values to ESR room
@@ -2225,47 +2322,82 @@
 	 * than 10 C, then apply back the room temperature ESR filter
 	 * coefficients to ESR room temperature tight and broad filters.
 	 */
-	if (batt_temp > chip->dt.esr_flt_switch_temp
-		&& chip->esr_flt_cold_temp_en) {
-		fg_encode(chip->sp, FG_SRAM_ESR_TIGHT_FILTER,
-			chip->dt.esr_tight_flt_upct, &esr_tight_lt_flt);
-		fg_encode(chip->sp, FG_SRAM_ESR_BROAD_FILTER,
-			chip->dt.esr_broad_flt_upct, &esr_broad_lt_flt);
-	} else if (batt_temp <= chip->dt.esr_flt_switch_temp
-			&& !chip->esr_flt_cold_temp_en) {
-		fg_encode(chip->sp, FG_SRAM_ESR_TIGHT_FILTER,
-			chip->dt.esr_tight_lt_flt_upct, &esr_tight_lt_flt);
-		fg_encode(chip->sp, FG_SRAM_ESR_BROAD_FILTER,
-			chip->dt.esr_broad_lt_flt_upct, &esr_broad_lt_flt);
-		cold_temp = true;
-	} else {
-		return 0;
+	if (batt_temp > chip->dt.esr_flt_switch_temp)
+		esr_flt_sts = ROOM_TEMP;
+	else
+		esr_flt_sts = LOW_TEMP;
+
+	if (count_temp_irq) {
+		time_ms = ktime_ms_delta(ktime_get(),
+				chip->last_delta_temp_time);
+		chip->delta_temp_irq_count++;
+		fg_dbg(chip, FG_STATUS, "dt_irq_count: %d\n",
+			chip->delta_temp_irq_count);
+
+		if (chip->delta_temp_irq_count >= DT_IRQ_COUNT
+			&& time_ms <= DELTA_TEMP_IRQ_TIME_MS) {
+			fg_dbg(chip, FG_STATUS, "%d interrupts in %lld ms\n",
+				chip->delta_temp_irq_count, time_ms);
+			esr_flt_sts = RELAX_TEMP;
+		}
 	}
 
-	rc = fg_sram_write(chip, chip->sp[FG_SRAM_ESR_TIGHT_FILTER].addr_word,
-			chip->sp[FG_SRAM_ESR_TIGHT_FILTER].addr_byte,
-			&esr_tight_lt_flt,
-			chip->sp[FG_SRAM_ESR_TIGHT_FILTER].len, FG_IMA_DEFAULT);
-	if (rc < 0) {
-		pr_err("Error in writing ESR LT tight filter, rc=%d\n", rc);
+	rc = __fg_esr_filter_config(chip, esr_flt_sts);
+	if (rc < 0)
 		return rc;
-	}
 
-	rc = fg_sram_write(chip, chip->sp[FG_SRAM_ESR_BROAD_FILTER].addr_word,
-			chip->sp[FG_SRAM_ESR_BROAD_FILTER].addr_byte,
-			&esr_broad_lt_flt,
-			chip->sp[FG_SRAM_ESR_BROAD_FILTER].len, FG_IMA_DEFAULT);
-	if (rc < 0) {
-		pr_err("Error in writing ESR LT broad filter, rc=%d\n", rc);
-		return rc;
-	}
+	if (esr_flt_sts == RELAX_TEMP)
+		alarm_start_relative(&chip->esr_filter_alarm,
+			ms_to_ktime(ESR_FILTER_ALARM_TIME_MS));
 
-	chip->esr_flt_cold_temp_en = cold_temp;
-	fg_dbg(chip, FG_STATUS, "applied %s ESR filter values\n",
-		cold_temp ? "cold" : "normal");
 	return 0;
 }
 
+#define FG_ESR_FILTER_RESTART_MS	60000
+static void esr_filter_work(struct work_struct *work)
+{
+	struct fg_chip *chip = container_of(work,
+			struct fg_chip, esr_filter_work);
+	int rc, batt_temp;
+
+	rc = fg_get_battery_temp(chip, &batt_temp);
+	if (rc < 0) {
+		pr_err("Error in getting batt_temp\n");
+		alarm_start_relative(&chip->esr_filter_alarm,
+			ms_to_ktime(FG_ESR_FILTER_RESTART_MS));
+		goto out;
+	}
+
+	rc = fg_esr_filter_config(chip, batt_temp, true);
+	if (rc < 0) {
+		pr_err("Error in configuring ESR filter rc:%d\n", rc);
+		alarm_start_relative(&chip->esr_filter_alarm,
+			ms_to_ktime(FG_ESR_FILTER_RESTART_MS));
+	}
+
+out:
+	chip->delta_temp_irq_count = 0;
+	pm_relax(chip->dev);
+}
+
+static enum alarmtimer_restart fg_esr_filter_alarm_cb(struct alarm *alarm,
+							ktime_t now)
+{
+	struct fg_chip *chip = container_of(alarm, struct fg_chip,
+					esr_filter_alarm);
+
+	fg_dbg(chip, FG_STATUS, "ESR filter alarm triggered %lld\n",
+		ktime_to_ms(now));
+	/*
+	 * We cannot vote for awake votable here as that takes a mutex lock
+	 * and this is executed in an atomic context.
+	 */
+	pm_stay_awake(chip->dev);
+	schedule_work(&chip->esr_filter_work);
+
+	return ALARMTIMER_NORESTART;
+}
+
 static int fg_esr_fcc_config(struct fg_chip *chip)
 {
 	union power_supply_propval prop = {0, };
@@ -3891,6 +4023,14 @@
 	struct power_supply *psy = data;
 	struct fg_chip *chip = container_of(nb, struct fg_chip, nb);
 
+	spin_lock(&chip->suspend_lock);
+	if (chip->suspended) {
+		/* Return if we are still suspended */
+		spin_unlock(&chip->suspend_lock);
+		return NOTIFY_OK;
+	}
+	spin_unlock(&chip->suspend_lock);
+
 	if (event != PSY_EVENT_PROP_CHANGED)
 		return NOTIFY_OK;
 
@@ -4385,14 +4525,14 @@
 	union power_supply_propval prop = {0, };
 	int rc, batt_temp;
 
-	fg_dbg(chip, FG_IRQ, "irq %d triggered\n", irq);
 	rc = fg_get_battery_temp(chip, &batt_temp);
 	if (rc < 0) {
 		pr_err("Error in getting batt_temp\n");
 		return IRQ_HANDLED;
 	}
+	fg_dbg(chip, FG_IRQ, "irq %d triggered bat_temp: %d\n", irq, batt_temp);
 
-	rc = fg_esr_filter_config(chip, batt_temp);
+	rc = fg_esr_filter_config(chip, batt_temp, false);
 	if (rc < 0)
 		pr_err("Error in configuring ESR filter rc:%d\n", rc);
 
@@ -4793,8 +4933,11 @@
 #define DEFAULT_ESR_FLT_TEMP_DECIDEGC	100
 #define DEFAULT_ESR_TIGHT_FLT_UPCT	3907
 #define DEFAULT_ESR_BROAD_FLT_UPCT	99610
-#define DEFAULT_ESR_TIGHT_LT_FLT_UPCT	48829
-#define DEFAULT_ESR_BROAD_LT_FLT_UPCT	148438
+#define DEFAULT_ESR_TIGHT_LT_FLT_UPCT	30000
+#define DEFAULT_ESR_BROAD_LT_FLT_UPCT	30000
+#define DEFAULT_ESR_FLT_RT_DECIDEGC	60
+#define DEFAULT_ESR_TIGHT_RT_FLT_UPCT	5860
+#define DEFAULT_ESR_BROAD_RT_FLT_UPCT	156250
 #define DEFAULT_ESR_CLAMP_MOHMS		20
 #define DEFAULT_ESR_PULSE_THRESH_MA	110
 #define DEFAULT_ESR_MEAS_CURR_MA	120
@@ -5128,6 +5271,27 @@
 	else
 		chip->dt.esr_broad_lt_flt_upct = temp;
 
+	rc = of_property_read_u32(node, "qcom,fg-esr-rt-filter-switch-temp",
+			&temp);
+	if (rc < 0)
+		chip->dt.esr_flt_rt_switch_temp = DEFAULT_ESR_FLT_RT_DECIDEGC;
+	else
+		chip->dt.esr_flt_rt_switch_temp = temp;
+
+	rc = of_property_read_u32(node, "qcom,fg-esr-tight-rt-filter-micro-pct",
+			&temp);
+	if (rc < 0)
+		chip->dt.esr_tight_rt_flt_upct = DEFAULT_ESR_TIGHT_RT_FLT_UPCT;
+	else
+		chip->dt.esr_tight_rt_flt_upct = temp;
+
+	rc = of_property_read_u32(node, "qcom,fg-esr-broad-rt-filter-micro-pct",
+			&temp);
+	if (rc < 0)
+		chip->dt.esr_broad_rt_flt_upct = DEFAULT_ESR_BROAD_RT_FLT_UPCT;
+	else
+		chip->dt.esr_broad_rt_flt_upct = temp;
+
 	rc = fg_parse_slope_limit_coefficients(chip);
 	if (rc < 0)
 		pr_err("Error in parsing slope limit coeffs, rc=%d\n", rc);
@@ -5173,6 +5337,7 @@
 			devm_free_irq(chip->dev, fg_irqs[i].irq, chip);
 	}
 
+	alarm_try_to_cancel(&chip->esr_filter_alarm);
 	power_supply_unreg_notifier(&chip->nb);
 	debugfs_remove_recursive(chip->dfs_root);
 	if (chip->awake_votable)
@@ -5285,6 +5450,7 @@
 	mutex_init(&chip->ttf.lock);
 	mutex_init(&chip->charge_full_lock);
 	mutex_init(&chip->qnovo_esr_ctrl_lock);
+	spin_lock_init(&chip->suspend_lock);
 	init_completion(&chip->soc_update);
 	init_completion(&chip->soc_ready);
 	INIT_DELAYED_WORK(&chip->profile_load_work, profile_load_work);
@@ -5292,6 +5458,9 @@
 	INIT_WORK(&chip->status_change_work, status_change_work);
 	INIT_DELAYED_WORK(&chip->ttf_work, ttf_work);
 	INIT_DELAYED_WORK(&chip->sram_dump_work, sram_dump_work);
+	INIT_WORK(&chip->esr_filter_work, esr_filter_work);
+	alarm_init(&chip->esr_filter_alarm, ALARM_BOOTTIME,
+			fg_esr_filter_alarm_cb);
 
 	rc = fg_memif_init(chip);
 	if (rc < 0) {
@@ -5363,7 +5532,7 @@
 	if (!rc) {
 		pr_info("battery SOC:%d voltage: %duV temp: %d\n",
 				msoc, volt_uv, batt_temp);
-		rc = fg_esr_filter_config(chip, batt_temp);
+		rc = fg_esr_filter_config(chip, batt_temp, false);
 		if (rc < 0)
 			pr_err("Error in configuring ESR filter rc:%d\n", rc);
 	}
@@ -5383,6 +5552,10 @@
 	struct fg_chip *chip = dev_get_drvdata(dev);
 	int rc;
 
+	spin_lock(&chip->suspend_lock);
+	chip->suspended = true;
+	spin_unlock(&chip->suspend_lock);
+
 	rc = fg_esr_timer_config(chip, true);
 	if (rc < 0)
 		pr_err("Error in configuring ESR timer, rc=%d\n", rc);
@@ -5406,6 +5579,16 @@
 	if (fg_sram_dump)
 		schedule_delayed_work(&chip->sram_dump_work,
 				msecs_to_jiffies(fg_sram_dump_period_ms));
+
+	if (!work_pending(&chip->status_change_work)) {
+		pm_stay_awake(chip->dev);
+		schedule_work(&chip->status_change_work);
+	}
+
+	spin_lock(&chip->suspend_lock);
+	chip->suspended = false;
+	spin_unlock(&chip->suspend_lock);
+
 	return 0;
 }
 
diff --git a/drivers/power/supply/qcom/qpnp-smbcharger.c b/drivers/power/supply/qcom/qpnp-smbcharger.c
index f9c755c..403b670 100644
--- a/drivers/power/supply/qcom/qpnp-smbcharger.c
+++ b/drivers/power/supply/qcom/qpnp-smbcharger.c
@@ -144,6 +144,7 @@
 	bool				vbat_above_headroom;
 	bool				force_aicl_rerun;
 	bool				hvdcp3_supported;
+	bool				allow_hvdcp3_detection;
 	bool				restricted_charging;
 	bool				skip_usb_suspend_for_fake_battery;
 	bool				hvdcp_not_supported;
@@ -5021,6 +5022,30 @@
 	return 0;
 }
 
+static void smbchg_handle_hvdcp3_disable(struct smbchg_chip *chip)
+{
+	enum power_supply_type usb_supply_type;
+	char *usb_type_name = "NULL";
+
+	if (chip->allow_hvdcp3_detection)
+		return;
+
+	chip->pulse_cnt = 0;
+
+	if (is_hvdcp_present(chip)) {
+		smbchg_change_usb_supply_type(chip,
+			POWER_SUPPLY_TYPE_USB_HVDCP);
+	} else if (is_usb_present(chip)) {
+		read_usb_type(chip, &usb_type_name, &usb_supply_type);
+		smbchg_change_usb_supply_type(chip, usb_supply_type);
+		if (usb_supply_type == POWER_SUPPLY_TYPE_USB_DCP)
+			schedule_delayed_work(&chip->hvdcp_det_work,
+				msecs_to_jiffies(HVDCP_NOTIFY_MS));
+	} else {
+		smbchg_change_usb_supply_type(chip, POWER_SUPPLY_TYPE_UNKNOWN);
+	}
+}
+
 static int smbchg_prepare_for_pulsing(struct smbchg_chip *chip)
 {
 	int rc = 0;
@@ -5241,6 +5266,9 @@
 		pr_smb(PR_MISC, "HVDCP removed\n");
 		update_usb_status(chip, 0, 0);
 	}
+
+	smbchg_handle_hvdcp3_disable(chip);
+
 	return rc;
 }
 
@@ -5425,6 +5453,8 @@
 	if (rc < 0)
 		pr_err("Couldn't retract HVDCP ICL vote rc=%d\n", rc);
 
+	smbchg_handle_hvdcp3_disable(chip);
+
 	return rc;
 }
 
@@ -5713,6 +5743,7 @@
 	POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED,
 	POWER_SUPPLY_PROP_RERUN_AICL,
 	POWER_SUPPLY_PROP_RESTRICTED_CHARGING,
+	POWER_SUPPLY_PROP_ALLOW_HVDCP3,
 };
 
 static int smbchg_battery_set_property(struct power_supply *psy,
@@ -5790,6 +5821,12 @@
 		if (chip->typec_psy)
 			update_typec_otg_status(chip, val->intval, false);
 		break;
+	case POWER_SUPPLY_PROP_ALLOW_HVDCP3:
+		if (chip->allow_hvdcp3_detection != val->intval) {
+			chip->allow_hvdcp3_detection = !!val->intval;
+			power_supply_changed(chip->batt_psy);
+		}
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -5813,6 +5850,7 @@
 	case POWER_SUPPLY_PROP_DP_DM:
 	case POWER_SUPPLY_PROP_RERUN_AICL:
 	case POWER_SUPPLY_PROP_RESTRICTED_CHARGING:
+	case POWER_SUPPLY_PROP_ALLOW_HVDCP3:
 		rc = 1;
 		break;
 	default:
@@ -5913,6 +5951,9 @@
 	case POWER_SUPPLY_PROP_INPUT_CURRENT_NOW:
 		val->intval = smbchg_get_iusb(chip);
 		break;
+	case POWER_SUPPLY_PROP_ALLOW_HVDCP3:
+		val->intval = chip->allow_hvdcp3_detection;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -8247,6 +8288,7 @@
 			goto out;
 		}
 	}
+	chip->allow_hvdcp3_detection = true;
 
 	if (chip->cfg_chg_led_support &&
 			chip->schg_version == QPNP_SCHG_LITE) {
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index 609005cc..7e1aa5d 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -3524,6 +3524,11 @@
 						chg->chg_freq.freq_removal);
 
 	if (vbus_rising) {
+		if (smblib_get_prop_dfp_mode(chg) != POWER_SUPPLY_TYPEC_NONE) {
+			chg->fake_usb_insertion = true;
+			return;
+		}
+
 		rc = smblib_request_dpdm(chg, true);
 		if (rc < 0)
 			smblib_err(chg, "Couldn't to enable DPDM rc=%d\n", rc);
@@ -3537,6 +3542,11 @@
 				!chg->pd_active)
 			pr_err("APSD disabled on vbus rising without PD\n");
 	} else {
+		if (chg->fake_usb_insertion) {
+			chg->fake_usb_insertion = false;
+			return;
+		}
+
 		if (chg->wa_flags & BOOST_BACK_WA) {
 			data = chg->irq_info[SWITCH_POWER_OK_IRQ].irq_data;
 			if (data) {
@@ -3899,6 +3909,9 @@
 	int rc = 0;
 	u8 stat;
 
+	if (chg->fake_usb_insertion)
+		return IRQ_HANDLED;
+
 	rc = smblib_read(chg, APSD_STATUS_REG, &stat);
 	if (rc < 0) {
 		smblib_err(chg, "Couldn't read APSD_STATUS rc=%d\n", rc);
diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h
index 141fa82..b9d1992 100644
--- a/drivers/power/supply/qcom/smb-lib.h
+++ b/drivers/power/supply/qcom/smb-lib.h
@@ -358,6 +358,7 @@
 	bool			try_sink_active;
 	int			boost_current_ua;
 	int			temp_speed_reading_count;
+	bool			fake_usb_insertion;
 
 	/* extcon for VBUS / ID notification to USB for uUSB */
 	struct extcon_dev	*extcon;
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 8811386..46c8268 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -2636,48 +2636,6 @@
 	kfree(testbus);
 }
 
-void ufs_qcom_read_custom_testbus(struct ufs_hba *hba)
-{
-	struct ufs_qcom_host *host = ufshcd_get_variant(hba);
-
-	host->testbus.select_major = TSTBUS_UTP_HCI;
-	host->testbus.select_minor = 5;
-	ufs_qcom_testbus_config(host);
-	hba->tb_ah8_ctrl_0 = ufshcd_readl(hba, UFS_TEST_BUS);
-
-	host->testbus.select_major = TSTBUS_UNIPRO;
-	host->testbus.select_minor = 33;
-	ufs_qcom_testbus_config(host);
-	hba->tb_dme = ufshcd_readl(hba, UFS_TEST_BUS);
-
-	host->testbus.select_major = TSTBUS_UNIPRO;
-	host->testbus.select_minor = 37;
-	ufs_qcom_testbus_config(host);
-	hba->tb_pa_power_ctrl = ufshcd_readl(hba, UFS_TEST_BUS);
-
-	host->testbus.select_major = TSTBUS_UNIPRO;
-	host->testbus.select_minor = 55;
-	ufs_qcom_testbus_config(host);
-	hba->tb_pa_attr_1 = ufshcd_readl(hba, UFS_TEST_BUS);
-
-	host->testbus.select_major = TSTBUS_UNIPRO;
-	host->testbus.select_minor = 56;
-	ufs_qcom_testbus_config(host);
-	hba->tb_pa_attr_2 = ufshcd_readl(hba, UFS_TEST_BUS);
-}
-
-int ufs_qcom_read_pa_vs_status_reg1(struct ufs_hba *hba, u32 *pa_vs_status_reg1)
-{
-	int err;
-
-	err = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_VS_STATUS_REG1),
-				pa_vs_status_reg1);
-	if (err)
-		dev_err(hba->dev, "%s: couldn't read PA_VS_STATUS_REG1 %d\n",
-								__func__, err);
-	return err;
-}
-
 static void ufs_qcom_dump_dbg_regs(struct ufs_hba *hba, bool no_sleep)
 {
 	struct ufs_qcom_host *host = ufshcd_get_variant(hba);
diff --git a/drivers/scsi/ufs/ufs-qcom.h b/drivers/scsi/ufs/ufs-qcom.h
index 1c48a85..a03ecb0 100644
--- a/drivers/scsi/ufs/ufs-qcom.h
+++ b/drivers/scsi/ufs/ufs-qcom.h
@@ -161,7 +161,6 @@
 
 /* QUniPro Vendor specific attributes */
 #define PA_VS_CONFIG_REG1		0x9000
-#define PA_VS_STATUS_REG1		0x9001
 #define SAVECONFIGTIME_MODE_MASK	0x6000
 
 #define PA_VS_CLK_CFG_REG	0x9004
@@ -397,9 +396,6 @@
 void ufs_qcom_print_hw_debug_reg_all(struct ufs_hba *hba, void *priv,
 		void (*print_fn)(struct ufs_hba *hba, int offset, int num_regs,
 				char *str, void *priv));
-void ufs_qcom_read_custom_testbus(struct ufs_hba *hba);
-int ufs_qcom_read_pa_vs_status_reg1(struct ufs_hba *hba,
-		u32 *pa_vs_status_reg1);
 
 static inline bool ufs_qcom_cap_qunipro(struct ufs_qcom_host *host)
 {
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index f3e79e3..d427fb3 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -54,8 +54,6 @@
 
 #ifdef CONFIG_DEBUG_FS
 
-static u32 pa_vs_status_reg1;
-
 static int ufshcd_tag_req_type(struct request *rq)
 {
 	int rq_type = TS_WRITE;
@@ -630,23 +628,6 @@
 	entry->tag = tag;
 	entry->tstamp = ktime_get();
 	entry->outstanding_reqs = hba->outstanding_reqs;
-	if (!strcmp(cmd_type, "custom")) {
-		ufs_qcom_read_custom_testbus(hba);
-		entry->tb_ah8_ctrl_0 = hba->tb_ah8_ctrl_0;
-		entry->tb_dme = hba->tb_dme;
-		entry->tb_pa_power_ctrl = hba->tb_pa_power_ctrl;
-		entry->tb_pa_attr_1 = hba->tb_pa_attr_1;
-		entry->tb_pa_attr_2 = hba->tb_pa_attr_2;
-		entry->pa_vs_status_reg1 = pa_vs_status_reg1;
-		pa_vs_status_reg1 = 0;
-	} else {
-		entry->tb_ah8_ctrl_0 = 0;
-		entry->tb_dme = 0;
-		entry->tb_pa_power_ctrl = 0;
-		entry->tb_pa_attr_1 = 0;
-		entry->tb_pa_attr_2 = 0;
-		entry->pa_vs_status_reg1 = 0;
-	}
 	entry->seq_num = hba->cmd_log.seq_num;
 	hba->cmd_log.seq_num++;
 	hba->cmd_log.pos =
@@ -686,14 +667,11 @@
 		pos = (pos + 1) % UFSHCD_MAX_CMD_LOGGING;
 
 		if (ktime_to_us(p->tstamp)) {
-			pr_err("%s: %s: seq_no=%u lun=0x%x cmd_id=0x%02x lba=0x%llx txfer_len=%d tag=%u, doorbell=0x%x outstanding=0x%x idn=%d ah8_ctrl_0=0x%x dme=0x%x pa_power_ctrl=0x%x pa_attr_1=0x%x pa_attr_2=0x%x pa_vs_status_reg1=0x%x time=%lld us\n",
+			pr_err("%s: %s: seq_no=%u lun=0x%x cmd_id=0x%02x lba=0x%llx txfer_len=%d tag=%u, doorbell=0x%x outstanding=0x%x idn=%d time=%lld us\n",
 				p->cmd_type, p->str, p->seq_num,
 				p->lun, p->cmd_id, (unsigned long long)p->lba,
 				p->transfer_len, p->tag, p->doorbell,
 				p->outstanding_reqs, p->idn,
-				p->tb_ah8_ctrl_0, p->tb_dme,
-				p->tb_pa_power_ctrl, p->tb_pa_attr_1,
-				p->tb_pa_attr_2, p->pa_vs_status_reg1,
 				ktime_to_us(p->tstamp));
 				usleep_range(1000, 1100);
 		}
@@ -10235,7 +10213,6 @@
 	if (ret)
 		goto out;
 
-	ufs_qcom_read_pa_vs_status_reg1(hba, &pa_vs_status_reg1);
 	ufshcd_custom_cmd_log(hba, "waited-for-DB-clear");
 
 	/* scale down the gear before scaling down clocks */
@@ -10243,7 +10220,6 @@
 		ret = ufshcd_scale_gear(hba, false);
 		if (ret)
 			goto clk_scaling_unprepare;
-		ufs_qcom_read_pa_vs_status_reg1(hba, &pa_vs_status_reg1);
 		ufshcd_custom_cmd_log(hba, "Gear-scaled-down");
 	}
 
@@ -10257,14 +10233,12 @@
 		if (ret)
 			/* link will be bad state so no need to scale_up_gear */
 			return ret;
-		ufs_qcom_read_pa_vs_status_reg1(hba, &pa_vs_status_reg1);
 		ufshcd_custom_cmd_log(hba, "Hibern8-entered");
 	}
 
 	ret = ufshcd_scale_clks(hba, scale_up);
 	if (ret)
 		goto scale_up_gear;
-	ufs_qcom_read_pa_vs_status_reg1(hba, &pa_vs_status_reg1);
 	ufshcd_custom_cmd_log(hba, "Clk-freq-switched");
 
 	if (ufshcd_is_auto_hibern8_supported(hba)) {
@@ -10272,7 +10246,6 @@
 		if (ret)
 			/* link will be bad state so no need to scale_up_gear */
 			return ret;
-		ufs_qcom_read_pa_vs_status_reg1(hba, &pa_vs_status_reg1);
 		ufshcd_custom_cmd_log(hba, "Hibern8-Exited");
 	}
 
@@ -10283,7 +10256,6 @@
 			ufshcd_scale_clks(hba, false);
 			goto clk_scaling_unprepare;
 		}
-		ufs_qcom_read_pa_vs_status_reg1(hba, &pa_vs_status_reg1);
 		ufshcd_custom_cmd_log(hba, "Gear-scaled-up");
 	}
 
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index a6b47aa..6e329c0 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -686,12 +686,6 @@
 	u32 seq_num;
 	unsigned int tag;
 	ktime_t tstamp;
-	u32 tb_ah8_ctrl_0;
-	u32 tb_dme;
-	u32 tb_pa_power_ctrl;
-	u32 tb_pa_attr_1;
-	u32 tb_pa_attr_2;
-	u32 pa_vs_status_reg1;
 };
 
 struct ufshcd_cmd_log {
@@ -1001,13 +995,6 @@
 	struct io_latency_state io_lat_write;
 	struct ufs_desc_size desc_size;
 	bool restore_needed;
-
-	/* Custom test bus data */
-	u32 tb_ah8_ctrl_0;
-	u32 tb_dme;
-	u32 tb_pa_power_ctrl;
-	u32 tb_pa_attr_1;
-	u32 tb_pa_attr_2;
 };
 
 static inline void ufshcd_mark_shutdown_ongoing(struct ufs_hba *hba)
diff --git a/drivers/soc/qcom/glink_smem_native_xprt.c b/drivers/soc/qcom/glink_smem_native_xprt.c
index d9cd0fa..baebb25 100644
--- a/drivers/soc/qcom/glink_smem_native_xprt.c
+++ b/drivers/soc/qcom/glink_smem_native_xprt.c
@@ -2548,7 +2548,7 @@
 
 	einfo->irq_line = irq_line;
 	rc = request_irq(irq_line, irq_handler,
-			IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND | IRQF_SHARED,
+			IRQF_TRIGGER_RISING | IRQF_SHARED,
 			node->name, einfo);
 	if (rc < 0) {
 		pr_err("%s: request_irq on %d failed: %d\n", __func__, irq_line,
diff --git a/drivers/soc/qcom/memory_dump_v2.c b/drivers/soc/qcom/memory_dump_v2.c
index b76fe86..5912ff2 100644
--- a/drivers/soc/qcom/memory_dump_v2.c
+++ b/drivers/soc/qcom/memory_dump_v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-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
@@ -39,15 +39,6 @@
 	struct msm_dump_table *table;
 };
 
-struct dump_vaddr_entry {
-	uint32_t id;
-	void *dump_vaddr;
-};
-
-struct msm_mem_dump_vaddr_tbl {
-	uint8_t num_node;
-	struct dump_vaddr_entry *entries;
-};
 
 static struct msm_memory_dump memdump;
 static struct msm_mem_dump_vaddr_tbl vaddr_tbl;
@@ -156,7 +147,7 @@
 }
 EXPORT_SYMBOL(msm_dump_data_register);
 
-void *get_msm_dump_ptr(enum msm_dump_data_ids id)
+struct dump_vaddr_entry *get_msm_dump_ptr(enum msm_dump_data_ids id)
 {
 	int i;
 
@@ -174,7 +165,7 @@
 	if (i == vaddr_tbl.num_node)
 		return NULL;
 
-	return (void *)vaddr_tbl.entries[i].dump_vaddr;
+	return &vaddr_tbl.entries[i];
 }
 EXPORT_SYMBOL(get_msm_dump_ptr);
 
@@ -333,6 +324,7 @@
 		} else if (vaddr_tbl.entries) {
 			vaddr_tbl.entries[i].id = id;
 			vaddr_tbl.entries[i].dump_vaddr = dump_vaddr;
+			vaddr_tbl.entries[i].dump_data_vaddr = dump_data;
 			i++;
 		}
 	}
diff --git a/drivers/soc/qcom/peripheral-loader.c b/drivers/soc/qcom/peripheral-loader.c
index 3b6c0bd..360dbcf 100644
--- a/drivers/soc/qcom/peripheral-loader.c
+++ b/drivers/soc/qcom/peripheral-loader.c
@@ -141,28 +141,50 @@
 
 static int pil_do_minidump(struct pil_desc *desc, void *ramdump_dev)
 {
-	struct md_ss_region __iomem *region_info;
+	struct md_ss_region __iomem *region_info_ss;
+	struct md_ss_region __iomem *region_info_pdr;
 	struct ramdump_segment *ramdump_segs, *s;
 	struct pil_priv *priv = desc->priv;
-	void __iomem *subsys_segtable_base;
+	void __iomem *subsys_segtable_base_ss;
+	void __iomem *subsys_segtable_base_pdr;
 	u64 ss_region_ptr = 0;
-	void __iomem *offset;
-	int ss_mdump_seg_cnt;
+	void __iomem *offset_ss;
+	void __iomem *offset_pdr;
+	int ss_mdump_seg_cnt_ss = 0, ss_mdump_seg_cnt_pdr = 0, total_segs;
 	int ss_valid_seg_cnt;
 	int ret, i;
 
-	ss_region_ptr = desc->minidump->md_ss_smem_regions_baseptr;
 	if (!ramdump_dev)
 		return -ENODEV;
-	ss_mdump_seg_cnt = desc->minidump->ss_region_count;
-	subsys_segtable_base =
+
+	ss_region_ptr = desc->minidump_ss->md_ss_smem_regions_baseptr;
+	ss_mdump_seg_cnt_ss = desc->minidump_ss->ss_region_count;
+	subsys_segtable_base_ss =
 		ioremap((unsigned long)ss_region_ptr,
-		ss_mdump_seg_cnt * sizeof(struct md_ss_region));
-	region_info = (struct md_ss_region __iomem *)subsys_segtable_base;
-	if (!region_info)
+		ss_mdump_seg_cnt_ss * sizeof(struct md_ss_region));
+	region_info_ss =
+		(struct md_ss_region __iomem *)subsys_segtable_base_ss;
+	if (!region_info_ss)
 		return -EINVAL;
-	pr_info("Minidump : Segments in minidump 0x%x\n", ss_mdump_seg_cnt);
-	ramdump_segs = kcalloc(ss_mdump_seg_cnt,
+	pr_info("Minidump : SS Segments in minidump 0x%x\n",
+		ss_mdump_seg_cnt_ss);
+
+	if (desc->minidump_pdr &&
+		(desc->minidump_pdr->md_ss_enable_status == MD_SS_ENABLED)) {
+		ss_region_ptr = desc->minidump_pdr->md_ss_smem_regions_baseptr;
+		ss_mdump_seg_cnt_pdr = desc->minidump_pdr->ss_region_count;
+		subsys_segtable_base_pdr =
+			ioremap((unsigned long)ss_region_ptr,
+			ss_mdump_seg_cnt_pdr * sizeof(struct md_ss_region));
+		region_info_pdr =
+			(struct md_ss_region __iomem *)subsys_segtable_base_pdr;
+		if (!region_info_pdr)
+			return -EINVAL;
+		pr_info("Minidump : PDR Segments in minidump 0x%x\n",
+			ss_mdump_seg_cnt_pdr);
+	}
+	total_segs = ss_mdump_seg_cnt_ss + ss_mdump_seg_cnt_pdr;
+	ramdump_segs = kcalloc(total_segs,
 			       sizeof(*ramdump_segs), GFP_KERNEL);
 	if (!ramdump_segs)
 		return -ENOMEM;
@@ -172,24 +194,47 @@
 			(priv->region_end - priv->region_start));
 
 	s = ramdump_segs;
-	ss_valid_seg_cnt = ss_mdump_seg_cnt;
-	for (i = 0; i < ss_mdump_seg_cnt; i++) {
-		memcpy(&offset, &region_info, sizeof(region_info));
-		offset = offset + sizeof(region_info->name) +
-				sizeof(region_info->seq_num);
-		if (__raw_readl(offset) == MD_REGION_VALID) {
-			memcpy(&s->name, &region_info, sizeof(region_info));
-			offset = offset + sizeof(region_info->md_valid);
-			s->address = __raw_readl(offset);
-			offset = offset +
-				sizeof(region_info->region_base_address);
-			s->size = __raw_readl(offset);
+	ss_valid_seg_cnt = total_segs;
+	for (i = 0; i < ss_mdump_seg_cnt_ss; i++) {
+		memcpy(&offset_ss, &region_info_ss, sizeof(region_info_ss));
+		offset_ss = offset_ss + sizeof(region_info_ss->name) +
+				sizeof(region_info_ss->seq_num);
+		if (__raw_readl(offset_ss) == MD_REGION_VALID) {
+			memcpy(&s->name, &region_info_ss,
+				sizeof(region_info_ss));
+			offset_ss = offset_ss +
+				sizeof(region_info_ss->md_valid);
+			s->address = __raw_readl(offset_ss);
+			offset_ss = offset_ss +
+				sizeof(region_info_ss->region_base_address);
+			s->size = __raw_readl(offset_ss);
 			pr_info("Minidump : Dumping segment %s with address 0x%lx and size 0x%x\n",
 				s->name, s->address, (unsigned int)s->size);
 		} else
 			ss_valid_seg_cnt--;
 		s++;
-		region_info++;
+		region_info_ss++;
+	}
+
+	for (i = 0; i < ss_mdump_seg_cnt_pdr; i++) {
+		memcpy(&offset_pdr, &region_info_pdr, sizeof(region_info_pdr));
+		offset_pdr = offset_pdr + sizeof(region_info_pdr->name) +
+				sizeof(region_info_pdr->seq_num);
+		if (__raw_readl(offset_pdr) == MD_REGION_VALID) {
+			memcpy(&s->name, &region_info_pdr,
+				sizeof(region_info_pdr));
+			offset_pdr = offset_pdr +
+				sizeof(region_info_pdr->md_valid);
+			s->address = __raw_readl(offset_pdr);
+			offset_pdr = offset_pdr +
+				sizeof(region_info_pdr->region_base_address);
+			s->size = __raw_readl(offset_pdr);
+			pr_info("Minidump : Dumping segment %s with address 0x%lx and size 0x%x\n",
+				s->name, s->address, (unsigned int)s->size);
+		} else
+			ss_valid_seg_cnt--;
+		s++;
+		region_info_pdr++;
 	}
 	ret = do_minidump(ramdump_dev, ramdump_segs, ss_valid_seg_cnt);
 	kfree(ramdump_segs);
@@ -219,27 +264,27 @@
 	struct pil_seg *seg;
 	int count = 0, ret;
 
-	if (desc->minidump) {
+	if (desc->minidump_ss) {
 		pr_info("Minidump : md_ss_toc->md_ss_toc_init is 0x%x\n",
-			(unsigned int)desc->minidump->md_ss_toc_init);
+			(unsigned int)desc->minidump_ss->md_ss_toc_init);
 		pr_info("Minidump : md_ss_toc->md_ss_enable_status is 0x%x\n",
-			(unsigned int)desc->minidump->md_ss_enable_status);
+			(unsigned int)desc->minidump_ss->md_ss_enable_status);
 		pr_info("Minidump : md_ss_toc->encryption_status is 0x%x\n",
-			(unsigned int)desc->minidump->encryption_status);
+			(unsigned int)desc->minidump_ss->encryption_status);
 		pr_info("Minidump : md_ss_toc->ss_region_count is 0x%x\n",
-			(unsigned int)desc->minidump->ss_region_count);
+			(unsigned int)desc->minidump_ss->ss_region_count);
 		pr_info("Minidump : md_ss_toc->md_ss_smem_regions_baseptr is 0x%x\n",
 			(unsigned int)
-			desc->minidump->md_ss_smem_regions_baseptr);
+			desc->minidump_ss->md_ss_smem_regions_baseptr);
 		/**
 		 * Collect minidump if SS ToC is valid and segment table
 		 * is initialized in memory and encryption status is set.
 		 */
-		if ((desc->minidump->md_ss_smem_regions_baseptr != 0) &&
-			(desc->minidump->md_ss_toc_init == true) &&
-			(desc->minidump->md_ss_enable_status ==
+		if ((desc->minidump_ss->md_ss_smem_regions_baseptr != 0) &&
+			(desc->minidump_ss->md_ss_toc_init == true) &&
+			(desc->minidump_ss->md_ss_enable_status ==
 				MD_SS_ENABLED)) {
-			if (desc->minidump->encryption_status ==
+			if (desc->minidump_ss->encryption_status ==
 				MD_SS_ENCR_DONE) {
 				pr_info("Minidump : Dumping for %s\n",
 					desc->name);
@@ -1184,9 +1229,15 @@
 	else {
 		if (g_md_toc && g_md_toc->md_toc_init == true) {
 			ss_toc_addr = &g_md_toc->md_ss_toc[desc->minidump_id];
-			pr_debug("Minidump : ss_toc_addr is %pa and desc->minidump_id is %d\n",
+			pr_debug("Minidump : ss_toc_addr for ss is %pa and desc->minidump_id is %d\n",
 				&ss_toc_addr, desc->minidump_id);
-			memcpy(&desc->minidump, &ss_toc_addr,
+			memcpy(&desc->minidump_ss, &ss_toc_addr,
+			       sizeof(ss_toc_addr));
+			ss_toc_addr =
+				&g_md_toc->md_ss_toc[desc->minidump_id + 1];
+			pr_debug("Minidump : ss_toc_addr for pdr is %pa and desc->minidump_id is %d\n",
+				&ss_toc_addr, desc->minidump_id);
+			memcpy(&desc->minidump_pdr, &ss_toc_addr,
 			       sizeof(ss_toc_addr));
 		}
 	}
diff --git a/drivers/soc/qcom/peripheral-loader.h b/drivers/soc/qcom/peripheral-loader.h
index 78c00fe..6ea6b2a 100644
--- a/drivers/soc/qcom/peripheral-loader.h
+++ b/drivers/soc/qcom/peripheral-loader.h
@@ -64,7 +64,8 @@
 	bool signal_aop;
 	struct mbox_client cl;
 	struct mbox_chan *mbox;
-	struct md_ss_toc *minidump;
+	struct md_ss_toc *minidump_ss;
+	struct md_ss_toc *minidump_pdr;
 	int minidump_id;
 };
 
diff --git a/drivers/soc/qcom/pil-msa.c b/drivers/soc/qcom/pil-msa.c
index 80dd2f7..6283477 100644
--- a/drivers/soc/qcom/pil-msa.c
+++ b/drivers/soc/qcom/pil-msa.c
@@ -582,7 +582,7 @@
 	if (ret)
 		goto err_clks;
 
-	if (!pil->minidump || !pil->modem_ssr) {
+	if (!pil->minidump_ss || !pil->modem_ssr) {
 		/* Save state of modem debug register before full reset */
 		debug_val = readl_relaxed(drv->reg_base + QDSP6SS_DBG_CFG);
 	}
@@ -595,7 +595,7 @@
 	if (ret)
 		goto err_restart;
 
-	if (!pil->minidump || !pil->modem_ssr) {
+	if (!pil->minidump_ss || !pil->modem_ssr) {
 		writel_relaxed(debug_val, drv->reg_base + QDSP6SS_DBG_CFG);
 		if (modem_dbg_cfg)
 			writel_relaxed(modem_dbg_cfg,
@@ -799,8 +799,13 @@
 	struct q6v5_data *drv = container_of(pil, struct q6v5_data, desc);
 	int ret;
 
-	if (!pil->minidump)
+	if (!pil->minidump_ss)
 		return 0;
+	if (pil->minidump_ss) {
+		if (pil->minidump_ss->md_ss_enable_status != MD_SS_ENABLED)
+			return 0;
+	}
+
 	/*
 	 * Bring subsystem out of reset and enable required
 	 * regulators and clocks.
@@ -809,7 +814,7 @@
 	if (ret)
 		return ret;
 
-	if (pil->minidump) {
+	if (pil->minidump_ss) {
 		writel_relaxed(0x1, drv->reg_base + QDSP6SS_NMI_CFG);
 		/* Let write complete before proceeding */
 		mb();
@@ -832,7 +837,7 @@
 	 */
 	pr_info("Minidump: waiting encryption to complete\n");
 	msleep(10000);
-	if (pil->minidump) {
+	if (pil->minidump_ss) {
 		writel_relaxed(0x2, drv->reg_base + QDSP6SS_NMI_CFG);
 		/* Let write complete before proceeding */
 		mb();
diff --git a/drivers/soc/qcom/rpmh_master_stat.c b/drivers/soc/qcom/rpmh_master_stat.c
index bc665fd..e696d4d 100644
--- a/drivers/soc/qcom/rpmh_master_stat.c
+++ b/drivers/soc/qcom/rpmh_master_stat.c
@@ -23,6 +23,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/uaccess.h>
+#include <asm/arch_timer.h>
 #include <soc/qcom/smem.h>
 #include "rpmh_master_stat.h"
 
@@ -102,6 +103,17 @@
 				struct msm_rpmh_master_stats *record,
 				const char *name)
 {
+	/*
+	 * If a master is in sleep when reading the sleep stats from SMEM
+	 * adjust the accumulated sleep duration to show actual sleep time.
+	 * This ensures that the displayed stats are real when used for
+	 * the purpose of computing battery utilization.
+	 */
+	if (record->last_entered > record->last_exited)
+		record->accumulated_duration +=
+				(arch_counter_get_cntvct()
+				- record->last_entered);
+
 	return snprintf(prvbuf, length, "%s\n\tVersion:0x%x\n"
 			"\tSleep Count:0x%x\n"
 			"\tSleep Last Entered At:0x%llx\n"
diff --git a/drivers/soc/qcom/scm.c b/drivers/soc/qcom/scm.c
index fec6f17..a64ddae 100644
--- a/drivers/soc/qcom/scm.c
+++ b/drivers/soc/qcom/scm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-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
@@ -635,28 +635,7 @@
 	return 0;
 }
 
-/**
- * scm_call2() - Invoke a syscall in the secure world
- * @fn_id: The function ID for this syscall
- * @desc: Descriptor structure containing arguments and return values
- *
- * Sends a command to the SCM and waits for the command to finish processing.
- * This should *only* be called in pre-emptible context.
- *
- * A note on cache maintenance:
- * Note that any buffers that are expected to be accessed by the secure world
- * must be flushed before invoking scm_call and invalidated in the cache
- * immediately after scm_call returns. An important point that must be noted
- * is that on ARMV8 architectures, invalidation actually also causes a dirty
- * cache line to be cleaned (flushed + unset-dirty-bit). Therefore it is of
- * paramount importance that the buffer be flushed before invoking scm_call2,
- * even if you don't care about the contents of that buffer.
- *
- * Note that cache maintenance on the argument buffer (desc->args) is taken care
- * of by scm_call2; however, callers are responsible for any other cached
- * buffers passed over to the secure world.
-*/
-int scm_call2(u32 fn_id, struct scm_desc *desc)
+static int __scm_call2(u32 fn_id, struct scm_desc *desc, bool retry)
 {
 	int arglen = desc->arginfo & 0xf;
 	int ret, retry_count = 0;
@@ -670,7 +649,6 @@
 		return ret;
 
 	x0 = fn_id | scm_version_mask;
-
 	do {
 		mutex_lock(&scm_lock);
 
@@ -700,13 +678,15 @@
 			mutex_unlock(&scm_lmh_lock);
 
 		mutex_unlock(&scm_lock);
+		if (!retry)
+			goto out;
 
 		if (ret == SCM_V2_EBUSY)
 			msleep(SCM_EBUSY_WAIT_MS);
 		if (retry_count == 33)
 			pr_warn("scm: secure world has been busy for 1 second!\n");
-	}  while (ret == SCM_V2_EBUSY && (retry_count++ < SCM_EBUSY_MAX_RETRY));
-
+	} while (ret == SCM_V2_EBUSY && (retry_count++ < SCM_EBUSY_MAX_RETRY));
+out:
 	if (ret < 0)
 		pr_err("scm_call failed: func id %#llx, ret: %d, syscall returns: %#llx, %#llx, %#llx\n",
 			x0, ret, desc->ret[0], desc->ret[1], desc->ret[2]);
@@ -717,9 +697,47 @@
 		return scm_remap_error(ret);
 	return 0;
 }
+
+/**
+ * scm_call2() - Invoke a syscall in the secure world
+ * @fn_id: The function ID for this syscall
+ * @desc: Descriptor structure containing arguments and return values
+ *
+ * Sends a command to the SCM and waits for the command to finish processing.
+ * This should *only* be called in pre-emptible context.
+ *
+ * A note on cache maintenance:
+ * Note that any buffers that are expected to be accessed by the secure world
+ * must be flushed before invoking scm_call and invalidated in the cache
+ * immediately after scm_call returns. An important point that must be noted
+ * is that on ARMV8 architectures, invalidation actually also causes a dirty
+ * cache line to be cleaned (flushed + unset-dirty-bit). Therefore it is of
+ * paramount importance that the buffer be flushed before invoking scm_call2,
+ * even if you don't care about the contents of that buffer.
+ *
+ * Note that cache maintenance on the argument buffer (desc->args) is taken care
+ * of by scm_call2; however, callers are responsible for any other cached
+ * buffers passed over to the secure world.
+ */
+int scm_call2(u32 fn_id, struct scm_desc *desc)
+{
+	return __scm_call2(fn_id, desc, true);
+}
 EXPORT_SYMBOL(scm_call2);
 
 /**
+ * scm_call2_noretry() - Invoke a syscall in the secure world
+ *
+ * Similar to scm_call2 except that there is no retry mechanism
+ * implemented.
+ */
+int scm_call2_noretry(u32 fn_id, struct scm_desc *desc)
+{
+	return __scm_call2(fn_id, desc, false);
+}
+EXPORT_SYMBOL(scm_call2_noretry);
+
+/**
  * scm_call2_atomic() - Invoke a syscall in the secure world
  *
  * Similar to scm_call2 except that this can be invoked in atomic context.
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index 8713f73..d8fcf5f 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -570,6 +570,7 @@
 
 	/* sdxpoorwills ID */
 	[334] = {SDX_CPU_SDXPOORWILLS, "SDXPOORWILLS"},
+	[335] = {SDX_CPU_SDXPOORWILLS, "SDXPOORWILLS"},
 
 	/* 9650 IDs */
 	[279] = {MSM_CPU_9650, "MDM9650"},
diff --git a/drivers/soc/qcom/watchdog_v2.c b/drivers/soc/qcom/watchdog_v2.c
index 5630dc0..b924bc8 100644
--- a/drivers/soc/qcom/watchdog_v2.c
+++ b/drivers/soc/qcom/watchdog_v2.c
@@ -93,6 +93,7 @@
 
 	bool timer_expired;
 	bool user_pet_complete;
+	unsigned int scandump_size;
 };
 
 /*
@@ -581,6 +582,41 @@
 	return;
 }
 
+static void register_scan_dump(struct msm_watchdog_data *wdog_dd)
+{
+	static void *dump_addr;
+	int ret;
+	struct msm_dump_entry dump_entry;
+	struct msm_dump_data *dump_data;
+
+	if (!wdog_dd->scandump_size)
+		return;
+
+	dump_data = kzalloc(sizeof(struct msm_dump_data), GFP_KERNEL);
+	if (!dump_data)
+		return;
+	dump_addr = kzalloc(wdog_dd->scandump_size, GFP_KERNEL);
+	if (!dump_addr)
+		goto err0;
+
+	dump_data->addr = virt_to_phys(dump_addr);
+	dump_data->len = wdog_dd->scandump_size;
+	strlcpy(dump_data->name, "KSCANDUMP", sizeof(dump_data->name));
+
+	dump_entry.id = MSM_DUMP_DATA_SCANDUMP;
+	dump_entry.addr = virt_to_phys(dump_data);
+	ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry);
+	if (ret) {
+		pr_err("Registering scandump region failed\n");
+		goto err1;
+	}
+	return;
+err1:
+	kfree(dump_addr);
+err0:
+	kfree(dump_data);
+}
+
 static void configure_scandump(struct msm_watchdog_data *wdog_dd)
 {
 	int ret;
@@ -624,6 +660,8 @@
 			devm_kfree(wdog_dd->dev, cpu_data);
 		}
 	}
+
+	register_scan_dump(wdog_dd);
 }
 
 static int init_watchdog_sysfs(struct msm_watchdog_data *wdog_dd)
@@ -805,6 +843,11 @@
 	pdata->wakeup_irq_enable = of_property_read_bool(node,
 							 "qcom,wakeup-enable");
 
+	if (of_property_read_u32(node, "qcom,scandump-size",
+				 &pdata->scandump_size))
+		dev_info(&pdev->dev,
+			 "No need to allocate memory for scandumps\n");
+
 	pdata->irq_ppi = irq_is_percpu(pdata->bark_irq);
 	dump_pdata(pdata);
 	return 0;
diff --git a/drivers/soc/qcom/wcnss/wcnss_vreg.c b/drivers/soc/qcom/wcnss/wcnss_vreg.c
index 29bc834..9d24ce1 100644
--- a/drivers/soc/qcom/wcnss/wcnss_vreg.c
+++ b/drivers/soc/qcom/wcnss/wcnss_vreg.c
@@ -193,27 +193,6 @@
 	}
 }
 
-void wcnss_free_regulator(void)
-{
-	int vreg_i;
-
-	/* Free pronto voltage regulators from device node */
-	for (vreg_i = 0; vreg_i < PRONTO_REGULATORS; vreg_i++) {
-		if (pronto_vregs[vreg_i].state) {
-			regulator_put(pronto_vregs[vreg_i].regulator);
-			pronto_vregs[vreg_i].state = VREG_NULL_CONFIG;
-		}
-	}
-
-	/* Free IRIS voltage regulators from device node */
-	for (vreg_i = 0; vreg_i < IRIS_REGULATORS; vreg_i++) {
-		if (iris_vregs[vreg_i].state) {
-			regulator_put(iris_vregs[vreg_i].regulator);
-			iris_vregs[vreg_i].state = VREG_NULL_CONFIG;
-		}
-	}
-}
-
 static int
 wcnss_dt_parse_vreg_level(struct device *dev, int index,
 			  const char *current_vreg_name, const char *vreg_name,
@@ -256,13 +235,14 @@
 	/* Parse pronto voltage regulators from device node */
 	for (vreg_i = 0; vreg_i < PRONTO_REGULATORS; vreg_i++) {
 		pronto_vregs[vreg_i].regulator =
-			regulator_get(dev, pronto_vregs[vreg_i].name);
+			devm_regulator_get_optional(dev,
+						    pronto_vregs[vreg_i].name);
 		if (IS_ERR(pronto_vregs[vreg_i].regulator)) {
 			if (pronto_vregs[vreg_i].required) {
 				rc = PTR_ERR(pronto_vregs[vreg_i].regulator);
 				dev_err(dev, "regulator get of %s failed (%d)\n",
 					pronto_vregs[vreg_i].name, rc);
-				goto wcnss_vreg_get_err;
+				return rc;
 			} else {
 				dev_dbg(dev, "Skip optional regulator configuration: %s\n",
 					pronto_vregs[vreg_i].name);
@@ -270,27 +250,28 @@
 			}
 		}
 
-		pronto_vregs[vreg_i].state |= VREG_GET_REGULATOR_MASK;
 		rc = wcnss_dt_parse_vreg_level(dev, vreg_i,
 					       pronto_vregs[vreg_i].curr,
 					       pronto_vregs[vreg_i].volt,
 					       wlan_config->pronto_vlevel);
 		if (rc) {
 			dev_err(dev, "error reading voltage-level property\n");
-			goto wcnss_vreg_get_err;
+			return rc;
 		}
+		pronto_vregs[vreg_i].state |= VREG_GET_REGULATOR_MASK;
 	}
 
 	/* Parse iris voltage regulators from device node */
 	for (vreg_i = 0; vreg_i < IRIS_REGULATORS; vreg_i++) {
 		iris_vregs[vreg_i].regulator =
-			regulator_get(dev, iris_vregs[vreg_i].name);
+			devm_regulator_get_optional(dev,
+						    iris_vregs[vreg_i].name);
 		if (IS_ERR(iris_vregs[vreg_i].regulator)) {
 			if (iris_vregs[vreg_i].required) {
 				rc = PTR_ERR(iris_vregs[vreg_i].regulator);
 				dev_err(dev, "regulator get of %s failed (%d)\n",
 					iris_vregs[vreg_i].name, rc);
-				goto wcnss_vreg_get_err;
+				return rc;
 			} else {
 				dev_dbg(dev, "Skip optional regulator configuration: %s\n",
 					iris_vregs[vreg_i].name);
@@ -298,22 +279,18 @@
 			}
 		}
 
-		iris_vregs[vreg_i].state |= VREG_GET_REGULATOR_MASK;
 		rc = wcnss_dt_parse_vreg_level(dev, vreg_i,
 					       iris_vregs[vreg_i].curr,
 					       iris_vregs[vreg_i].volt,
 					       wlan_config->iris_vlevel);
 		if (rc) {
 			dev_err(dev, "error reading voltage-level property\n");
-			goto wcnss_vreg_get_err;
+			return rc;
 		}
+		iris_vregs[vreg_i].state |= VREG_GET_REGULATOR_MASK;
 	}
 
 	return 0;
-
-wcnss_vreg_get_err:
-	wcnss_free_regulator();
-	return rc;
 }
 
 void  wcnss_iris_reset(u32 reg, void __iomem *pmu_conf_reg)
diff --git a/drivers/soc/qcom/wcnss/wcnss_wlan.c b/drivers/soc/qcom/wcnss/wcnss_wlan.c
index 6d5ee04..481dbd0 100644
--- a/drivers/soc/qcom/wcnss/wcnss_wlan.c
+++ b/drivers/soc/qcom/wcnss/wcnss_wlan.c
@@ -3524,7 +3524,6 @@
 static int
 wcnss_wlan_remove(struct platform_device *pdev)
 {
-	wcnss_free_regulator();
 	if (penv->wcnss_notif_hdle)
 		subsys_notif_unregister_notifier(penv->wcnss_notif_hdle, &wnb);
 	wcnss_cdev_unregister(pdev);
diff --git a/drivers/thermal/qpnp-adc-tm.c b/drivers/thermal/qpnp-adc-tm.c
index 6a3c06f..5c0022e 100644
--- a/drivers/thermal/qpnp-adc-tm.c
+++ b/drivers/thermal/qpnp-adc-tm.c
@@ -2232,6 +2232,71 @@
 
 static int qpnp_adc_tm_read_status(struct qpnp_adc_tm_chip *chip)
 {
+	int rc = 0, sensor_notify_num = 0, i = 0, sensor_num = 0;
+	unsigned long flags;
+
+	if (qpnp_adc_tm_is_valid(chip))
+		return -ENODEV;
+
+	mutex_lock(&chip->adc->adc_lock);
+
+	rc = qpnp_adc_tm_req_sts_check(chip);
+	if (rc) {
+		pr_err("adc-tm-tm req sts check failed with %d\n", rc);
+		goto fail;
+	}
+
+	if (chip->th_info.adc_tm_high_enable) {
+		spin_lock_irqsave(&chip->th_info.adc_tm_high_lock, flags);
+		sensor_notify_num = chip->th_info.adc_tm_high_enable;
+		chip->th_info.adc_tm_high_enable = 0;
+		spin_unlock_irqrestore(&chip->th_info.adc_tm_high_lock, flags);
+		while (i < chip->max_channels_available) {
+			if ((sensor_notify_num & 0x1) == 1) {
+				sensor_num = i;
+				rc = qpnp_adc_tm_disable_rearm_high_thresholds(
+						chip, sensor_num);
+				if (rc < 0) {
+					pr_err("rearm threshold failed\n");
+					goto fail;
+				}
+			}
+			sensor_notify_num >>= 1;
+			i++;
+		}
+	}
+
+	if (chip->th_info.adc_tm_low_enable) {
+		spin_lock_irqsave(&chip->th_info.adc_tm_low_lock, flags);
+		sensor_notify_num = chip->th_info.adc_tm_low_enable;
+		chip->th_info.adc_tm_low_enable = 0;
+		spin_unlock_irqrestore(&chip->th_info.adc_tm_low_lock, flags);
+		i = 0;
+		while (i < chip->max_channels_available) {
+			if ((sensor_notify_num & 0x1) == 1) {
+				sensor_num = i;
+				rc = qpnp_adc_tm_disable_rearm_low_thresholds(
+						chip, sensor_num);
+				if (rc < 0) {
+					pr_err("rearm threshold failed\n");
+					goto fail;
+				}
+			}
+			sensor_notify_num >>= 1;
+			i++;
+		}
+	}
+
+fail:
+	mutex_unlock(&chip->adc->adc_lock);
+	if (rc < 0)
+		atomic_dec(&chip->wq_cnt);
+
+	return rc;
+}
+
+static int qpnp_adc_tm_hc_read_status(struct qpnp_adc_tm_chip *chip)
+{
 	int rc = 0, sensor_num = 0;
 
 	if (qpnp_adc_tm_is_valid(chip))
@@ -2300,9 +2365,15 @@
 
 	pr_debug("thr:0x%x\n", chip->th_info.adc_tm_high_enable);
 
-	rc = qpnp_adc_tm_read_status(chip);
-	if (rc < 0)
-		pr_err("adc-tm high thr work failed\n");
+	if (!chip->adc_tm_hc) {
+		rc = qpnp_adc_tm_read_status(chip);
+		if (rc < 0)
+			pr_err("adc-tm high thr work failed\n");
+	} else {
+		rc = qpnp_adc_tm_hc_read_status(chip);
+		if (rc < 0)
+			pr_err("adc-tm-hc high thr work failed\n");
+	}
 }
 
 static irqreturn_t qpnp_adc_tm_high_thr_isr(int irq, void *data)
@@ -2406,9 +2477,15 @@
 
 	pr_debug("thr:0x%x\n", chip->th_info.adc_tm_low_enable);
 
-	rc = qpnp_adc_tm_read_status(chip);
-	if (rc < 0)
-		pr_err("adc-tm low thr work failed\n");
+	if (!chip->adc_tm_hc) {
+		rc = qpnp_adc_tm_read_status(chip);
+		if (rc < 0)
+			pr_err("adc-tm low thr work failed\n");
+	} else {
+		rc = qpnp_adc_tm_hc_read_status(chip);
+		if (rc < 0)
+			pr_err("adc-tm-hc low thr work failed\n");
+	}
 }
 
 static irqreturn_t qpnp_adc_tm_low_thr_isr(int irq, void *data)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index d1a63da..2095579 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -405,7 +405,7 @@
 
 	evt = dwc->ev_buf;
 	dwc3_trace(trace_dwc3_core,
-			"Event buf %p dma %08llx length %d\n",
+			"Event buf %pK dma %08llx length %d\n",
 			evt->buf, (unsigned long long) evt->dma,
 			evt->length);
 
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index ded62f1..defb438 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -792,7 +792,7 @@
 	list_add_tail(&req_complete->list_item, &mdwc->req_complete_list);
 	request->complete = dwc3_msm_req_complete_func;
 
-	dev_vdbg(dwc->dev, "%s: queing request %p to ep %s length %d\n",
+	dev_vdbg(dwc->dev, "%s: queing request %pK to ep %s length %d\n",
 			__func__, request, ep->name, request->length);
 	size = dwc3_msm_read_reg(mdwc->base, DWC3_GEVNTSIZ(0));
 	dbm_event_buffer_config(mdwc->dbm,
@@ -992,7 +992,7 @@
 		dev_dbg(mdwc->dev, "Failed to get GSI DBL address MSB\n");
 
 	offset = dwc3_trb_dma_offset(dep, &dep->trb_pool[num_trbs-1]);
-	dev_dbg(mdwc->dev, "Writing link TRB addr: %pa to %p (%x) for ep:%s\n",
+	dev_dbg(mdwc->dev, "Writing link TRB addr: %pa to %pK (%x) for ep:%s\n",
 		&offset, gsi_dbl_address_lsb, request->db_reg_phs_addr_lsb,
 		ep->name);
 
@@ -1959,7 +1959,7 @@
 			if (!evt)
 				break;
 
-			dev_dbg(mdwc->dev, "Evt buf %p dma %08llx length %d\n",
+			dev_dbg(mdwc->dev, "Evt buf %pK dma %08llx length %d\n",
 				evt->buf, (unsigned long long) evt->dma,
 				evt->length);
 			memset(evt->buf, 0, evt->length);
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 8cf49fa..381ad49 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -240,7 +240,7 @@
 	spin_lock_irqsave(&dwc->lock, flags);
 	if (!dep->endpoint.desc) {
 		dwc3_trace(trace_dwc3_ep0,
-				"trying to queue request %p to disabled %s",
+				"trying to queue request %pK to disabled %s",
 				request, dep->name);
 		ret = -ESHUTDOWN;
 		goto out;
@@ -265,7 +265,7 @@
 	}
 
 	dwc3_trace(trace_dwc3_ep0,
-			"queueing request %p to %s length %d state '%s'",
+			"queueing request %pK to %s length %d state '%s'",
 			request, dep->name, request->length,
 			dwc3_ep0_state_string(dwc->ep0state));
 
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index f90d0c9..3c38ee1 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -937,7 +937,7 @@
 	struct usb_gadget	*gadget = &dwc->gadget;
 	enum usb_device_speed	speed = gadget->speed;
 
-	dwc3_trace(trace_dwc3_gadget, "%s: req %p dma %08llx length %d%s",
+	dwc3_trace(trace_dwc3_gadget, "%s: req %pK dma %08llx length %d%s%s",
 			dep->name, req, (unsigned long long) dma,
 			length, chain ? " chain" : "");
 
@@ -1293,7 +1293,7 @@
 
 	if (!dep->endpoint.desc) {
 		dwc3_trace(trace_dwc3_gadget,
-				"trying to queue request %p to disabled %s",
+				"trying to queue request %pK to disabled %s",
 				&req->request, dep->endpoint.name);
 		return -ESHUTDOWN;
 	}
@@ -1432,13 +1432,13 @@
 
 	spin_lock_irqsave(&dwc->lock, flags);
 	if (!dep->endpoint.desc) {
-		dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n",
+		dev_dbg(dwc->dev, "trying to queue request %pK to disabled %s\n",
 				request, ep->name);
 		ret = -ESHUTDOWN;
 		goto out;
 	}
 
-	if (WARN(req->dep != dep, "request %p belongs to '%s'\n",
+	if (WARN(req->dep != dep, "request %pK belongs to '%s'\n",
 				request, req->dep->name)) {
 		ret = -EINVAL;
 		goto out;
diff --git a/drivers/usb/dwc3/io.h b/drivers/usb/dwc3/io.h
index 1f75b58..bc2a8bc 100644
--- a/drivers/usb/dwc3/io.h
+++ b/drivers/usb/dwc3/io.h
@@ -40,7 +40,7 @@
 	 * documentation, so we revert it back to the proper addresses, the
 	 * same way they are described on SNPS documentation
 	 */
-	dwc3_trace(trace_dwc3_readl, "addr %p value %08x",
+	dwc3_trace(trace_dwc3_readl, "addr %pK value %08x",
 			base - DWC3_GLOBALS_REGS_START + offset, value);
 
 	return value;
@@ -60,7 +60,7 @@
 	 * documentation, so we revert it back to the proper addresses, the
 	 * same way they are described on SNPS documentation
 	 */
-	dwc3_trace(trace_dwc3_writel, "addr %p value %08x",
+	dwc3_trace(trace_dwc3_writel, "addr %pK value %08x",
 			base - DWC3_GLOBALS_REGS_START + offset, value);
 }
 
diff --git a/drivers/usb/dwc3/trace.h b/drivers/usb/dwc3/trace.h
index 88f5fb8..d9873ad 100644
--- a/drivers/usb/dwc3/trace.h
+++ b/drivers/usb/dwc3/trace.h
@@ -137,7 +137,7 @@
 		__entry->short_not_ok = req->request.short_not_ok;
 		__entry->no_interrupt = req->request.no_interrupt;
 	),
-	TP_printk("%s: req %p length %u/%u %s%s%s ==> %d",
+	TP_printk("%s: req %pK length %u/%u %s%s%s ==> %d",
 		__get_str(name), __entry->req, __entry->actual, __entry->length,
 		__entry->zero ? "Z" : "z",
 		__entry->short_not_ok ? "S" : "s",
@@ -253,7 +253,7 @@
 		__entry->size = trb->size;
 		__entry->ctrl = trb->ctrl;
 	),
-	TP_printk("%s: %d/%d trb %p buf %08x%08x size %d ctrl %08x (%c%c%c%c:%c%c:%s)",
+	TP_printk("%s: %d/%d trb %pK buf %08x%08x size %d ctrl %08x (%c%c%c%c:%c%c:%s)",
 		__get_str(name), __entry->queued, __entry->allocated,
 		__entry->trb, __entry->bph, __entry->bpl,
 		__entry->size, __entry->ctrl,
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index f6fc30a..ab2c623 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -20,6 +20,7 @@
 
 #include <linux/usb/composite.h>
 #include <linux/usb/otg.h>
+#include <linux/usb/msm_hsusb.h>
 #include <asm/unaligned.h>
 
 #include "u_os_desc.h"
@@ -856,6 +857,11 @@
 
 	DBG(cdev, "reset config\n");
 
+	if (!cdev->config) {
+		pr_err("%s:cdev->config is already NULL\n", __func__);
+		return;
+	}
+
 	list_for_each_entry(f, &cdev->config->functions, list) {
 		if (f->disable)
 			f->disable(f);
@@ -1120,8 +1126,14 @@
 
 	spin_lock_irqsave(&cdev->lock, flags);
 
-	if (cdev->config == config)
+	if (cdev->config == config) {
+		if (cdev->gadget->is_chipidea && !cdev->suspended) {
+			spin_unlock_irqrestore(&cdev->lock, flags);
+			msm_do_bam_disable_enable(CI_CTRL);
+			spin_lock_irqsave(&cdev->lock, flags);
+		}
 		reset_config(cdev);
+	}
 
 	spin_unlock_irqrestore(&cdev->lock, flags);
 
@@ -2161,8 +2173,14 @@
 	 * disconnect callbacks?
 	 */
 	spin_lock_irqsave(&cdev->lock, flags);
-	if (cdev->config)
+	if (cdev->config) {
+		if (gadget->is_chipidea && !cdev->suspended) {
+			spin_unlock_irqrestore(&cdev->lock, flags);
+			msm_do_bam_disable_enable(CI_CTRL);
+			spin_lock_irqsave(&cdev->lock, flags);
+		}
 		reset_config(cdev);
+	}
 	if (cdev->driver->disconnect)
 		cdev->driver->disconnect(cdev);
 	if (cdev->delayed_status != 0) {
diff --git a/drivers/usb/gadget/function/f_audio_source.c b/drivers/usb/gadget/function/f_audio_source.c
index aaa15da..3f60bf7 100644
--- a/drivers/usb/gadget/function/f_audio_source.c
+++ b/drivers/usb/gadget/function/f_audio_source.c
@@ -337,14 +337,15 @@
 
 /*--------------------------------------------------------------------------*/
 
-static struct usb_request *audio_request_new(struct usb_ep *ep, int buffer_size)
+static struct usb_request *audio_request_new(struct usb_ep *ep, int buffer_size,
+					size_t extra_buf_alloc)
 {
 	struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL);
 
 	if (!req)
 		return NULL;
 
-	req->buf = kmalloc(buffer_size, GFP_KERNEL);
+	req->buf = kmalloc(buffer_size + extra_buf_alloc, GFP_KERNEL);
 	if (!req->buf) {
 		usb_ep_free_request(ep, req);
 		return NULL;
@@ -748,7 +749,8 @@
 	f->ss_descriptors = ss_audio_desc;
 
 	for (i = 0, status = 0; i < IN_EP_REQ_COUNT && status == 0; i++) {
-		req = audio_request_new(ep, IN_EP_MAX_PACKET_SIZE);
+		req = audio_request_new(ep, IN_EP_MAX_PACKET_SIZE,
+						cdev->gadget->extra_buf_alloc);
 		if (req) {
 			req->context = audio;
 			req->complete = audio_data_complete;
diff --git a/drivers/usb/gadget/function/f_ccid.c b/drivers/usb/gadget/function/f_ccid.c
index dbf72ab..76b181a 100644
--- a/drivers/usb/gadget/function/f_ccid.c
+++ b/drivers/usb/gadget/function/f_ccid.c
@@ -337,7 +337,8 @@
 }
 
 static struct usb_request *
-ccid_request_alloc(struct usb_ep *ep, size_t len, gfp_t kmalloc_flags)
+ccid_request_alloc(struct usb_ep *ep, size_t len, size_t extra_buf_alloc,
+							gfp_t kmalloc_flags)
 {
 	struct usb_request *req;
 
@@ -345,7 +346,7 @@
 
 	if (req != NULL) {
 		req->length = len;
-		req->buf = kmalloc(len, kmalloc_flags);
+		req->buf = kmalloc(len + extra_buf_alloc, kmalloc_flags);
 		if (req->buf == NULL) {
 			usb_ep_free_request(ep, req);
 			req = NULL;
@@ -467,7 +468,8 @@
 	int i;
 
 	ccid_dev->notify_req = ccid_request_alloc(ccid_dev->notify,
-			sizeof(struct usb_ccid_notification), GFP_ATOMIC);
+			sizeof(struct usb_ccid_notification),
+			cdev->gadget->extra_buf_alloc, GFP_ATOMIC);
 	if (IS_ERR(ccid_dev->notify_req)) {
 		pr_err("%s: unable to allocate memory for notify req\n",
 				__func__);
@@ -478,7 +480,7 @@
 
 	/* now allocate requests for our endpoints */
 	req = ccid_request_alloc(ccid_dev->out, BULK_OUT_BUFFER_SIZE,
-							GFP_ATOMIC);
+							0, GFP_ATOMIC);
 	if (IS_ERR(req)) {
 		pr_err("%s: unable to allocate memory for out req\n",
 				__func__);
@@ -491,7 +493,7 @@
 
 	for (i = 0; i < TX_REQ_MAX; i++) {
 		req = ccid_request_alloc(ccid_dev->in, BULK_IN_BUFFER_SIZE,
-				GFP_ATOMIC);
+				cdev->gadget->extra_buf_alloc, GFP_ATOMIC);
 		if (IS_ERR(req)) {
 			pr_err("%s: unable to allocate memory for in req\n",
 					__func__);
diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c
index 25b2cdd..1979156 100644
--- a/drivers/usb/gadget/function/f_midi.c
+++ b/drivers/usb/gadget/function/f_midi.c
@@ -218,9 +218,23 @@
 };
 
 static inline struct usb_request *midi_alloc_ep_req(struct usb_ep *ep,
-						    unsigned length)
+				unsigned int length, size_t extra_buf_alloc)
 {
-	return alloc_ep_req(ep, length);
+	struct usb_request      *req;
+
+	req = usb_ep_alloc_request(ep, GFP_ATOMIC);
+	if (!req)
+		return NULL;
+
+	req->length = usb_endpoint_dir_out(ep->desc) ?
+				usb_ep_align(ep, length) : length;
+	req->buf = kmalloc(req->length + extra_buf_alloc, GFP_ATOMIC);
+	if (!req->buf) {
+		usb_ep_free_request(ep, req);
+		return NULL;
+	}
+
+	return req;
 }
 
 static const uint8_t f_midi_cin_length[] = {
@@ -374,7 +388,8 @@
 	/* pre-allocate write usb requests to use on f_midi_transmit. */
 	while (kfifo_avail(&midi->in_req_fifo)) {
 		struct usb_request *req =
-			midi_alloc_ep_req(midi->in_ep, midi->buflen);
+			midi_alloc_ep_req(midi->in_ep, midi->buflen,
+						midi->gadget->extra_buf_alloc);
 
 		if (req == NULL)
 			return -ENOMEM;
@@ -388,7 +403,7 @@
 	/* allocate a bunch of read buffers and queue them all at once. */
 	for (i = 0; i < midi->qlen && err == 0; i++) {
 		struct usb_request *req =
-			midi_alloc_ep_req(midi->out_ep, midi->buflen);
+			midi_alloc_ep_req(midi->out_ep, midi->buflen, 0);
 
 		if (req == NULL)
 			return -ENOMEM;
diff --git a/drivers/usb/gadget/function/u_qdss.c b/drivers/usb/gadget/function/u_qdss.c
index d445e51..6e60258 100644
--- a/drivers/usb/gadget/function/u_qdss.c
+++ b/drivers/usb/gadget/function/u_qdss.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -20,6 +20,7 @@
 {
 	struct usb_request *req = NULL;
 	struct f_qdss *qdss = data_ep->driver_data;
+	struct usb_gadget *gadget = qdss->gadget;
 	u32 sps_params = 0;
 
 	pr_debug("send_sps_req\n");
@@ -30,9 +31,17 @@
 		return -ENOMEM;
 	}
 
-	req->length = 32*1024;
-	sps_params = MSM_SPS_MODE | MSM_DISABLE_WB |
-			qdss->bam_info.usb_bam_pipe_idx;
+	if (!gadget->is_chipidea) {
+		req->length = 32*1024;
+		sps_params = MSM_SPS_MODE | MSM_DISABLE_WB |
+				qdss->bam_info.usb_bam_pipe_idx;
+	} else {
+		/* non DWC3 BAM requires req->length to be 0 */
+		req->length = 0;
+		sps_params = (MSM_SPS_MODE | qdss->bam_info.usb_bam_pipe_idx |
+				MSM_VENDOR_ID) & ~MSM_IS_FINITE_TRANSFER;
+	}
+
 	req->udc_priv = sps_params;
 	qdss->endless_req = req;
 
@@ -107,10 +116,12 @@
 				NULL, bam_info.data_fifo, NULL);
 
 		alloc_sps_req(qdss->port.data);
-		msm_data_fifo_config(qdss->port.data,
-			bam_info.data_fifo->iova,
-			bam_info.data_fifo->size,
-			bam_info.usb_bam_pipe_idx);
+		if (!gadget->is_chipidea)
+			msm_data_fifo_config(qdss->port.data,
+				bam_info.data_fifo->iova,
+				bam_info.data_fifo->size,
+				bam_info.usb_bam_pipe_idx);
+
 		init_data(qdss->port.data);
 
 		res = usb_bam_connect(usb_bam_type, idx,
@@ -132,8 +143,14 @@
 static int init_data(struct usb_ep *ep)
 {
 	struct f_qdss *qdss = ep->driver_data;
+	struct usb_gadget *gadget = qdss->gadget;
 	int res = 0;
 
+	if (gadget->is_chipidea) {
+		pr_debug("QDSS is used with non DWC3 core\n");
+		return res;
+	}
+
 	pr_debug("init_data\n");
 
 	res = msm_ep_config(ep, qdss->endless_req);
@@ -145,8 +162,13 @@
 
 int uninit_data(struct usb_ep *ep)
 {
+	struct f_qdss *qdss = ep->driver_data;
+	struct usb_gadget *gadget = qdss->gadget;
 	int res = 0;
 
+	if (gadget->is_chipidea)
+		return res;
+
 	pr_err("uninit_data\n");
 
 	res = msm_ep_unconfig(ep);
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 3ff6468..73ab200 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -89,7 +89,7 @@
 static void __maybe_unused
 dbg_qtd(const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd)
 {
-	ehci_dbg(ehci, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
+	ehci_dbg(ehci, "%s td %pK n%08x %08x t%08x p0=%08x\n", label, qtd,
 		hc32_to_cpup(ehci, &qtd->hw_next),
 		hc32_to_cpup(ehci, &qtd->hw_alt_next),
 		hc32_to_cpup(ehci, &qtd->hw_token),
@@ -107,7 +107,7 @@
 {
 	struct ehci_qh_hw *hw = qh->hw;
 
-	ehci_dbg(ehci, "%s qh %p n%08x info %x %x qtd %x\n", label,
+	ehci_dbg(ehci, "%s qh %pK n%08x info %x %x qtd %x\n", label,
 		qh, hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current);
 	dbg_qtd("overlay", ehci, (struct ehci_qtd *) &hw->hw_qtd_next);
 }
@@ -115,7 +115,7 @@
 static void __maybe_unused
 dbg_itd(const char *label, struct ehci_hcd *ehci, struct ehci_itd *itd)
 {
-	ehci_dbg(ehci, "%s [%d] itd %p, next %08x, urb %p\n",
+	ehci_dbg(ehci, "%s [%d] itd %pK, next %08x, urb %p\n",
 		label, itd->frame, itd, hc32_to_cpu(ehci, itd->hw_next),
 		itd->urb);
 	ehci_dbg(ehci,
@@ -146,7 +146,7 @@
 static void __maybe_unused
 dbg_sitd(const char *label, struct ehci_hcd *ehci, struct ehci_sitd *sitd)
 {
-	ehci_dbg(ehci, "%s [%d] sitd %p, next %08x, urb %p\n",
+	ehci_dbg(ehci, "%s [%d] sitd %pK, next %08x, urb %p\n",
 		label, sitd->frame, sitd, hc32_to_cpu(ehci, sitd->hw_next),
 		sitd->urb);
 	ehci_dbg(ehci,
@@ -406,7 +406,7 @@
 	scratch = hc32_to_cpup(ehci, &hw->hw_info1);
 	hw_curr = (mark == '*') ? hc32_to_cpup(ehci, &hw->hw_current) : 0;
 	temp = scnprintf(next, size,
-			"qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)"
+			"qh/%pK dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)"
 			" [cur %08x next %08x buf[0] %08x]",
 			qh, scratch & 0x007f,
 			speed_char (scratch),
@@ -454,7 +454,7 @@
 			break;
 		}
 		temp = scnprintf(next, size,
-				"\n\t%p%c%s len=%d %08x urb %p"
+				"\n\t%pK%c%s len=%d %08x urb %pK"
 				" [td %08x buf[0] %08x]",
 				td, mark, type,
 				(scratch >> 16) & 0x7fff,
@@ -674,7 +674,7 @@
 			switch (hc32_to_cpu(ehci, tag)) {
 			case Q_TYPE_QH:
 				hw = p.qh->hw;
-				temp = scnprintf(next, size, " qh%d-%04x/%p",
+				temp = scnprintf(next, size, " qh%d-%04x/%pK",
 						p.qh->ps.period,
 						hc32_to_cpup(ehci,
 							&hw->hw_info2)
@@ -709,21 +709,21 @@
 				p = p.qh->qh_next;
 				break;
 			case Q_TYPE_FSTN:
-				temp = scnprintf(next, size,
-					" fstn-%8x/%p", p.fstn->hw_prev,
+				temp = scnprintf (next, size,
+					" fstn-%8x/%pK", p.fstn->hw_prev,
 					p.fstn);
 				tag = Q_NEXT_TYPE(ehci, p.fstn->hw_next);
 				p = p.fstn->fstn_next;
 				break;
 			case Q_TYPE_ITD:
-				temp = scnprintf(next, size,
-					" itd/%p", p.itd);
+				temp = scnprintf (next, size,
+					" itd/%pK", p.itd);
 				tag = Q_NEXT_TYPE(ehci, p.itd->hw_next);
 				p = p.itd->itd_next;
 				break;
 			case Q_TYPE_SITD:
-				temp = scnprintf(next, size,
-					" sitd%d-%04x/%p",
+				temp = scnprintf (next, size,
+					" sitd%d-%04x/%pK",
 					p.sitd->stream->ps.period,
 					hc32_to_cpup(ehci, &p.sitd->hw_uframe)
 						& 0x0000ffff,
@@ -895,7 +895,7 @@
 	}
 
 	if (!list_empty(&ehci->async_unlink)) {
-		temp = scnprintf(next, size, "async unlink qh %p\n",
+		temp = scnprintf(next, size, "async unlink qh %pK\n",
 				list_first_entry(&ehci->async_unlink,
 						struct ehci_qh, unlink_node));
 		size -= temp;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 0630648..142fe51 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1017,7 +1017,7 @@
 		/* caller was supposed to have unlinked any requests;
 		 * that's not our job.  just leak this memory.
 		 */
-		ehci_err (ehci, "qh %p (#%02x) state %d%s\n",
+		ehci_err (ehci, "qh %pK (#%02x) state %d%s\n",
 			qh, ep->desc.bEndpointAddress, qh->qh_state,
 			list_empty (&qh->qtd_list) ? "" : "(has tds)");
 		break;
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index eca3710..484d9d7 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -268,7 +268,7 @@
 
 #ifdef EHCI_URB_TRACE
 	ehci_dbg (ehci,
-		"%s %s urb %p ep%d%s status %d len %d/%d\n",
+		"%s %s urb %pK ep%d%s status %d len %d/%d\n",
 		__func__, urb->dev->devpath, urb,
 		usb_pipeendpoint (urb->pipe),
 		usb_pipein (urb->pipe) ? "in" : "out",
@@ -354,7 +354,7 @@
 			/* Report Data Buffer Error: non-fatal but useful */
 			if (token & QTD_STS_DBE)
 				ehci_dbg(ehci,
-					"detected DataBufferErr for urb %p ep%d%s len %d, qtd %p [qh %p]\n",
+					"detected DataBufferErr for urb %pK ep%d%s len %d, qtd %pK [qh %pK]\n",
 					urb,
 					usb_endpoint_num(&urb->ep->desc),
 					usb_endpoint_dir_in(&urb->ep->desc) ? "in" : "out",
@@ -933,7 +933,7 @@
 		}
 		break;
 	default:
-		ehci_dbg(ehci, "bogus dev %p speed %d\n", urb->dev,
+		ehci_dbg(ehci, "bogus dev %pK speed %d\n", urb->dev,
 			urb->dev->speed);
 done:
 		qh_destroy(ehci, qh);
@@ -1121,7 +1121,7 @@
 		struct ehci_qtd *qtd;
 		qtd = list_entry(qtd_list->next, struct ehci_qtd, qtd_list);
 		ehci_dbg(ehci,
-			 "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
+			 "%s %s urb %pK ep%d%s len %d, qtd %pK [qh %pK]\n",
 			 __func__, urb->dev->devpath, urb,
 			 epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out",
 			 urb->transfer_buffer_length,
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 1dfe54f..414e122 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -549,7 +549,7 @@
 	unsigned	period = qh->ps.period;
 
 	dev_dbg(&qh->ps.udev->dev,
-		"link qh%d-%04x/%p start %d [%d/%d us]\n",
+		"link qh%d-%04x/%pK start %d [%d/%d us]\n",
 		period, hc32_to_cpup(ehci, &qh->hw->hw_info2)
 			& (QH_CMASK | QH_SMASK),
 		qh, qh->ps.phase, qh->ps.usecs, qh->ps.c_usecs);
@@ -642,7 +642,7 @@
 		: (qh->ps.usecs * 8);
 
 	dev_dbg(&qh->ps.udev->dev,
-		"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
+		"unlink qh%d-%04x/%pK start %d [%d/%d us]\n",
 		qh->ps.period,
 		hc32_to_cpup(ehci, &qh->hw->hw_info2) & (QH_CMASK | QH_SMASK),
 		qh, qh->ps.phase, qh->ps.usecs, qh->ps.c_usecs);
@@ -752,7 +752,7 @@
 		 * FIXME kill the now-dysfunctional queued urbs
 		 */
 		else {
-			ehci_err(ehci, "can't reschedule qh %p, err %d\n",
+			ehci_err(ehci, "can't reschedule qh %pK, err %d\n",
 					qh, rc);
 		}
 	}
@@ -870,7 +870,7 @@
 
 	/* reuse the previous schedule slots, if we can */
 	if (qh->ps.phase != NO_FRAME) {
-		ehci_dbg(ehci, "reused qh %p schedule\n", qh);
+		ehci_dbg(ehci, "reused qh %pK schedule\n", qh);
 		return 0;
 	}
 
@@ -1550,7 +1550,7 @@
 
 			/* no room in the schedule */
 			if (!done) {
-				ehci_dbg(ehci, "iso sched full %p", urb);
+				ehci_dbg(ehci, "iso sched full %pK", urb);
 				status = -ENOSPC;
 				goto fail;
 			}
@@ -1604,7 +1604,7 @@
 
 	/* Is the schedule about to wrap around? */
 	if (unlikely(!empty && start < period)) {
-		ehci_dbg(ehci, "request %p would overflow (%u-%u < %u mod %u)\n",
+		ehci_dbg(ehci, "request %pK would overflow (%u-%u < %u mod %u)\n",
 				urb, stream->next_uframe, base, period, mod);
 		status = -EFBIG;
 		goto fail;
@@ -1633,7 +1633,7 @@
 	/* How many uframes and packets do we need to skip? */
 	skip = (now2 - start + period - 1) & -period;
 	if (skip >= span) {		/* Entirely in the past? */
-		ehci_dbg(ehci, "iso underrun %p (%u+%u < %u) [%u]\n",
+		ehci_dbg(ehci, "iso underrun %pK (%u+%u < %u) [%u]\n",
 				urb, start + base, span - period, now2 + base,
 				base);
 
@@ -1660,7 +1660,7 @@
  use_start:
 	/* Tried to schedule too far into the future? */
 	if (unlikely(start + span - period >= mod + wrap)) {
-		ehci_dbg(ehci, "request %p would overflow (%u+%u >= %u)\n",
+		ehci_dbg(ehci, "request %pK would overflow (%u+%u >= %u)\n",
 				urb, start, span - period, mod + wrap);
 		status = -EFBIG;
 		goto fail;
@@ -1956,7 +1956,7 @@
 
 #ifdef EHCI_URB_TRACE
 	ehci_dbg(ehci,
-		"%s %s urb %p ep%d%s len %d, %d pkts %d uframes [%p]\n",
+		"%s %s urb %p ep%d%s len %d, %d pkts %d uframes [%pK]\n",
 		__func__, urb->dev->devpath, urb,
 		usb_pipeendpoint(urb->pipe),
 		usb_pipein(urb->pipe) ? "in" : "out",
@@ -2336,8 +2336,8 @@
 	}
 
 #ifdef EHCI_URB_TRACE
-	ehci_dbg(ehci,
-		"submit %p dev%s ep%d%s-iso len %d\n",
+	ehci_dbg (ehci,
+		"submit %pK dev%s ep%d%s-iso len %d\n",
 		urb, urb->dev->devpath,
 		usb_pipeendpoint(urb->pipe),
 		usb_pipein(urb->pipe) ? "in" : "out",
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
index c3eded3..5617622 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -256,7 +256,7 @@
 {
 	u32	tmp = hc32_to_cpup (ohci, &td->hwINFO);
 
-	ohci_dbg (ohci, "%s td %p%s; urb %p index %d; hw next td %08x\n",
+	ohci_dbg (ohci, "%s td %pK%s; urb %pK index %d; hw next td %08x\n",
 		label, td,
 		(tmp & TD_DONE) ? " (DONE)" : "",
 		td->urb, td->index,
@@ -314,7 +314,7 @@
 	u32	tmp = hc32_to_cpu (ohci, ed->hwINFO);
 	char	*type = "";
 
-	ohci_dbg (ohci, "%s, ed %p state 0x%x type %s; next ed %08x\n",
+	ohci_dbg (ohci, "%s, ed %pK state 0x%x type %s; next ed %08x\n",
 		label,
 		ed, ed->state, edstring (ed->type),
 		hc32_to_cpup (ohci, &ed->hwNextED));
@@ -415,7 +415,7 @@
 		struct td	*td;
 
 		temp = scnprintf (buf, size,
-			"ed/%p %cs dev%d ep%d%s max %d %08x%s%s %s",
+			"ed/%pK %cs dev%d ep%d%s max %d %08x%s%s %s",
 			ed,
 			(info & ED_LOWSPEED) ? 'l' : 'f',
 			info & 0x7f,
@@ -437,7 +437,7 @@
 			cbp = hc32_to_cpup (ohci, &td->hwCBP);
 			be = hc32_to_cpup (ohci, &td->hwBE);
 			temp = scnprintf (buf, size,
-					"\n\ttd %p %s %d cc=%x urb %p (%08x)",
+					"\n\ttd %pK %s %d cc=%x urb %pK (%08x)",
 					td,
 					({ char *pid;
 					switch (info & TD_DP) {
@@ -516,7 +516,7 @@
 		next += temp;
 
 		do {
-			temp = scnprintf (next, size, " ed%d/%p",
+			temp = scnprintf (next, size, " ed%d/%pK",
 				ed->interval, ed);
 			size -= temp;
 			next += temp;
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index f6c7a27..5635a33 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -279,7 +279,7 @@
 						ed->interval);
 				if (urb_priv->td_cnt >= urb_priv->length) {
 					++urb_priv->td_cnt;	/* Mark it */
-					ohci_dbg(ohci, "iso underrun %p (%u+%u < %u)\n",
+					ohci_dbg(ohci, "iso underrun %pK (%u+%u < %u)\n",
 							urb, frame, length,
 							next);
 				}
@@ -387,7 +387,7 @@
 		/* caller was supposed to have unlinked any requests;
 		 * that's not our job.  can't recover; must leak ed.
 		 */
-		ohci_err (ohci, "leak ed %p (#%02x) state %d%s\n",
+		ohci_err (ohci, "leak ed %pK (#%02x) state %d%s\n",
 			ed, ep->desc.bEndpointAddress, ed->state,
 			list_empty (&ed->td_list) ? "" : " (has tds)");
 		td_free (ohci, ed->dummy);
@@ -1028,7 +1028,7 @@
 		case ED_UNLINK:
 			break;
 		default:
-			ohci_dbg(ohci, "bogus ed %p state %d\n",
+			ohci_dbg(ohci, "bogus ed %pK state %d\n",
 					ed, ed->state);
 		}
 
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c
index c9e315c..99576f3 100644
--- a/drivers/usb/host/ohci-mem.c
+++ b/drivers/usb/host/ohci-mem.c
@@ -109,7 +109,7 @@
 	if (*prev)
 		*prev = td->td_hash;
 	else if ((td->hwINFO & cpu_to_hc32(hc, TD_DONE)) != 0)
-		ohci_dbg (hc, "no hash for td %p\n", td);
+		ohci_dbg (hc, "no hash for td %pK\n", td);
 	dma_pool_free (hc->td_cache, td, td->td_dma);
 }
 
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index 641fed6..4365dc3 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -143,7 +143,7 @@
 {
 	unsigned	i;
 
-	ohci_dbg(ohci, "link %sed %p branch %d [%dus.], interval %d\n",
+	ohci_dbg(ohci, "link %sed %pK branch %d [%dus.], interval %d\n",
 		(ed->hwINFO & cpu_to_hc32 (ohci, ED_ISO)) ? "iso " : "",
 		ed, ed->branch, ed->load, ed->interval);
 
@@ -287,7 +287,7 @@
 	}
 	ohci_to_hcd(ohci)->self.bandwidth_allocated -= ed->load / ed->interval;
 
-	ohci_dbg(ohci, "unlink %sed %p branch %d [%dus.], interval %d\n",
+	ohci_dbg(ohci, "unlink %sed %pK branch %d [%dus.], interval %d\n",
 		(ed->hwINFO & cpu_to_hc32 (ohci, ED_ISO)) ? "iso " : "",
 		ed, ed->branch, ed->load, ed->interval);
 }
@@ -787,7 +787,7 @@
 
 		if (cc != TD_CC_NOERROR)
 			ohci_dbg(ohci,
-				"urb %p iso td %p (%d) len %d cc %d\n",
+				"urb %pK iso td %pK (%d) len %d cc %d\n",
 				urb, td, 1 + td->index, dlen, cc);
 
 	/* BULK, INT, CONTROL ... drivers see aggregate length/status,
@@ -819,7 +819,7 @@
 
 		if (cc != TD_CC_NOERROR && cc < 0x0E)
 			ohci_dbg(ohci,
-				"urb %p td %p (%d) cc %d, len=%d/%d\n",
+				"urb %pK td %pK (%d) cc %d, len=%d/%d\n",
 				urb, td, 1 + td->index, cc,
 				urb->actual_length,
 				urb->transfer_buffer_length);
@@ -885,7 +885,7 @@
 		/* fallthrough */
 	default:
 		ohci_dbg (ohci,
-			"urb %p path %s ep%d%s %08x cc %d --> status %d\n",
+			"urb %pK path %s ep%d%s %08x cc %d --> status %d\n",
 			urb, urb->dev->devpath,
 			usb_pipeendpoint (urb->pipe),
 			usb_pipein (urb->pipe) ? "in" : "out",
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
index 9c6635d..dcb6efa 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -47,7 +47,7 @@
 	u32 status, token;
 
 	status = td_status(uhci, td);
-	out += sprintf(out, "%*s[%p] link (%08x) ", space, "", td,
+	out += sprintf(out, "%*s[%pK] link (%08x) ", space, "", td,
 		hc32_to_cpu(uhci, td->link));
 	out += sprintf(out, "e%d %s%s%s%s%s%s%s%s%s%sLength=%x ",
 		((status >> 27) & 3),
@@ -105,9 +105,9 @@
 	char *ptype;
 
 
-	out += sprintf(out, "urb_priv [%p] ", urbp);
-	out += sprintf(out, "urb [%p] ", urbp->urb);
-	out += sprintf(out, "qh [%p] ", urbp->qh);
+	out += sprintf(out, "urb_priv [%pK] ", urbp);
+	out += sprintf(out, "urb [%pK] ", urbp->urb);
+	out += sprintf(out, "qh [%pK] ", urbp->qh);
 	out += sprintf(out, "Dev=%d ", usb_pipedevice(urbp->urb->pipe));
 	out += sprintf(out, "EP=%x(%s) ", usb_pipeendpoint(urbp->urb->pipe),
 			(usb_pipein(urbp->urb->pipe) ? "IN" : "OUT"));
@@ -177,13 +177,13 @@
 	default: qtype = "Skel" ; break;
 	}
 
-	out += sprintf(out, "%*s[%p] %s QH link (%08x) element (%08x)\n",
+	out += sprintf(out, "%*s[%pK] %s QH link (%08x) element (%08x)\n",
 			space, "", qh, qtype,
 			hc32_to_cpu(uhci, qh->link),
 			hc32_to_cpu(uhci, element));
 	if (qh->type == USB_ENDPOINT_XFER_ISOC)
 		out += sprintf(out,
-				"%*s    period %d phase %d load %d us, frame %x desc [%p]\n",
+				"%*s    period %d phase %d load %d us, frame %x desc [%pK]\n",
 				space, "", qh->period, qh->phase, qh->load,
 				qh->iso_frame, qh->iso_packet_desc);
 	else if (qh->type == USB_ENDPOINT_XFER_INT)
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index c17ea15..11c9d7b 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -124,9 +124,9 @@
 static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td)
 {
 	if (!list_empty(&td->list))
-		dev_WARN(uhci_dev(uhci), "td %p still in list!\n", td);
+		dev_WARN(uhci_dev(uhci), "td %pK still in list!\n", td);
 	if (!list_empty(&td->fl_list))
-		dev_WARN(uhci_dev(uhci), "td %p still in fl_list!\n", td);
+		dev_WARN(uhci_dev(uhci), "td %pK still in fl_list!\n", td);
 
 	dma_pool_free(uhci->td_pool, td, td->dma_handle);
 }
@@ -293,7 +293,7 @@
 {
 	WARN_ON(qh->state != QH_STATE_IDLE && qh->udev);
 	if (!list_empty(&qh->queue))
-		dev_WARN(uhci_dev(uhci), "qh %p list not empty!\n", qh);
+		dev_WARN(uhci_dev(uhci), "qh %pK list not empty!\n", qh);
 
 	list_del(&qh->node);
 	if (qh->udev) {
@@ -743,7 +743,7 @@
 	struct uhci_td *td, *tmp;
 
 	if (!list_empty(&urbp->node))
-		dev_WARN(uhci_dev(uhci), "urb %p still on QH's list!\n",
+		dev_WARN(uhci_dev(uhci), "urb %pK still on QH's list!\n",
 				urbp->urb);
 
 	list_for_each_entry_safe(td, tmp, &urbp->td_list, list) {
@@ -1316,7 +1316,7 @@
 			else if (!uhci_frame_before_eq(next,
 					frame + (urb->number_of_packets - 1) *
 						qh->period))
-				dev_dbg(uhci_dev(uhci), "iso underrun %p (%u+%u < %u)\n",
+				dev_dbg(uhci_dev(uhci), "iso underrun %pK (%u+%u < %u)\n",
 						urb, frame,
 						(urb->number_of_packets - 1) *
 							qh->period,
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
index 3425154..a190c97 100644
--- a/drivers/usb/host/xhci-dbg.c
+++ b/drivers/usb/host/xhci-dbg.c
@@ -30,10 +30,10 @@
 {
 	u32 temp;
 
-	xhci_dbg(xhci, "// xHCI capability registers at %p:\n",
+	xhci_dbg(xhci, "// xHCI capability registers at %pK:\n",
 			xhci->cap_regs);
 	temp = readl(&xhci->cap_regs->hc_capbase);
-	xhci_dbg(xhci, "// @%p = 0x%x (CAPLENGTH AND HCIVERSION)\n",
+	xhci_dbg(xhci, "// @%pK = 0x%x (CAPLENGTH AND HCIVERSION)\n",
 			&xhci->cap_regs->hc_capbase, temp);
 	xhci_dbg(xhci, "//   CAPLENGTH: 0x%x\n",
 			(unsigned int) HC_LENGTH(temp));
@@ -42,17 +42,17 @@
 			(unsigned int) HC_VERSION(temp));
 #endif
 
-	xhci_dbg(xhci, "// xHCI operational registers at %p:\n", xhci->op_regs);
+	xhci_dbg(xhci, "// xHCI operational registers at %pK:\n", xhci->op_regs);
 
 	temp = readl(&xhci->cap_regs->run_regs_off);
-	xhci_dbg(xhci, "// @%p = 0x%x RTSOFF\n",
+	xhci_dbg(xhci, "// @%pK = 0x%x RTSOFF\n",
 			&xhci->cap_regs->run_regs_off,
 			(unsigned int) temp & RTSOFF_MASK);
-	xhci_dbg(xhci, "// xHCI runtime registers at %p:\n", xhci->run_regs);
+	xhci_dbg(xhci, "// xHCI runtime registers at %pK:\n", xhci->run_regs);
 
 	temp = readl(&xhci->cap_regs->db_off);
-	xhci_dbg(xhci, "// @%p = 0x%x DBOFF\n", &xhci->cap_regs->db_off, temp);
-	xhci_dbg(xhci, "// Doorbell array at %p:\n", xhci->dba);
+	xhci_dbg(xhci, "// @%pK = 0x%x DBOFF\n", &xhci->cap_regs->db_off, temp);
+	xhci_dbg(xhci, "// Doorbell array at %pK:\n", xhci->dba);
 }
 
 static void xhci_print_cap_regs(struct xhci_hcd *xhci)
@@ -60,7 +60,7 @@
 	u32 temp;
 	u32 hci_version;
 
-	xhci_dbg(xhci, "xHCI capability registers at %p:\n", xhci->cap_regs);
+	xhci_dbg(xhci, "xHCI capability registers at %pK:\n", xhci->cap_regs);
 
 	temp = readl(&xhci->cap_regs->hc_capbase);
 	hci_version = HC_VERSION(temp);
@@ -157,7 +157,7 @@
 
 static void xhci_print_op_regs(struct xhci_hcd *xhci)
 {
-	xhci_dbg(xhci, "xHCI operational registers at %p:\n", xhci->op_regs);
+	xhci_dbg(xhci, "xHCI operational registers at %pK:\n", xhci->op_regs);
 	xhci_print_command_reg(xhci);
 	xhci_print_status(xhci);
 }
@@ -178,7 +178,7 @@
 	addr = &xhci->op_regs->port_status_base;
 	for (i = 0; i < ports; i++) {
 		for (j = 0; j < NUM_PORT_REGS; ++j) {
-			xhci_dbg(xhci, "%p port %s reg = 0x%x\n",
+			xhci_dbg(xhci, "%pK port %s reg = 0x%x\n",
 					addr, names[j],
 					(unsigned int) readl(addr));
 			addr++;
@@ -198,35 +198,35 @@
 	if (temp == XHCI_INIT_VALUE)
 		return;
 
-	xhci_dbg(xhci, "  %p: ir_set[%i]\n", ir_set, set_num);
+	xhci_dbg(xhci, "  %pK: ir_set[%i]\n", ir_set, set_num);
 
-	xhci_dbg(xhci, "  %p: ir_set.pending = 0x%x\n", addr,
+	xhci_dbg(xhci, "  %pK: ir_set.pending = 0x%x\n", addr,
 			(unsigned int)temp);
 
 	addr = &ir_set->irq_control;
 	temp = readl(addr);
-	xhci_dbg(xhci, "  %p: ir_set.control = 0x%x\n", addr,
+	xhci_dbg(xhci, "  %pK: ir_set.control = 0x%x\n", addr,
 			(unsigned int)temp);
 
 	addr = &ir_set->erst_size;
 	temp = readl(addr);
-	xhci_dbg(xhci, "  %p: ir_set.erst_size = 0x%x\n", addr,
+	xhci_dbg(xhci, "  %pK: ir_set.erst_size = 0x%x\n", addr,
 			(unsigned int)temp);
 
 	addr = &ir_set->rsvd;
 	temp = readl(addr);
 	if (temp != XHCI_INIT_VALUE)
-		xhci_dbg(xhci, "  WARN: %p: ir_set.rsvd = 0x%x\n",
+		xhci_dbg(xhci, "  WARN: %pK: ir_set.rsvd = 0x%x\n",
 				addr, (unsigned int)temp);
 
 	addr = &ir_set->erst_base;
 	temp_64 = xhci_read_64(xhci, addr);
-	xhci_dbg(xhci, "  %p: ir_set.erst_base = @%08llx\n",
+	xhci_dbg(xhci, "  %pK: ir_set.erst_base = @%08llx\n",
 			addr, temp_64);
 
 	addr = &ir_set->erst_dequeue;
 	temp_64 = xhci_read_64(xhci, addr);
-	xhci_dbg(xhci, "  %p: ir_set.erst_dequeue = @%08llx\n",
+	xhci_dbg(xhci, "  %pK: ir_set.erst_dequeue = @%08llx\n",
 			addr, temp_64);
 }
 
@@ -235,15 +235,15 @@
 	u32 temp;
 	int i;
 
-	xhci_dbg(xhci, "xHCI runtime registers at %p:\n", xhci->run_regs);
+	xhci_dbg(xhci, "xHCI runtime registers at %pK:\n", xhci->run_regs);
 	temp = readl(&xhci->run_regs->microframe_index);
-	xhci_dbg(xhci, "  %p: Microframe index = 0x%x\n",
+	xhci_dbg(xhci, "  %pK: Microframe index = 0x%x\n",
 			&xhci->run_regs->microframe_index,
 			(unsigned int) temp);
 	for (i = 0; i < 7; ++i) {
 		temp = readl(&xhci->run_regs->rsvd[i]);
 		if (temp != XHCI_INIT_VALUE)
-			xhci_dbg(xhci, "  WARN: %p: Rsvd[%i] = 0x%x\n",
+			xhci_dbg(xhci, "  WARN: %pK: Rsvd[%i] = 0x%x\n",
 					&xhci->run_regs->rsvd[i],
 					i, (unsigned int) temp);
 	}
@@ -345,13 +345,13 @@
 
 void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring)
 {
-	xhci_dbg(xhci, "Ring deq = %p (virt), 0x%llx (dma)\n",
+	xhci_dbg(xhci, "Ring deq = %pK (virt), 0x%llx (dma)\n",
 			ring->dequeue,
 			(unsigned long long)xhci_trb_virt_to_dma(ring->deq_seg,
 							    ring->dequeue));
 	xhci_dbg(xhci, "Ring deq updated %u times\n",
 			ring->deq_updates);
-	xhci_dbg(xhci, "Ring enq = %p (virt), 0x%llx (dma)\n",
+	xhci_dbg(xhci, "Ring enq = %pK (virt), 0x%llx (dma)\n",
 			ring->enqueue,
 			(unsigned long long)xhci_trb_virt_to_dma(ring->enq_seg,
 							    ring->enqueue));
@@ -441,7 +441,7 @@
 {
 	int i;
 	for (i = 0; i < 4; ++i) {
-		xhci_dbg(xhci, "@%p (virt) @%08llx "
+		xhci_dbg(xhci, "@%pK (virt) @%08llx "
 			 "(dma) %#08llx - rsvd64[%d]\n",
 			 &ctx[4 + i], (unsigned long long)dma,
 			 ctx[4 + i], i);
@@ -480,24 +480,24 @@
 	int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params);
 
 	xhci_dbg(xhci, "Slot Context:\n");
-	xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info\n",
+	xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - dev_info\n",
 			&slot_ctx->dev_info,
 			(unsigned long long)dma, slot_ctx->dev_info);
 	dma += field_size;
-	xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info2\n",
+	xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - dev_info2\n",
 			&slot_ctx->dev_info2,
 			(unsigned long long)dma, slot_ctx->dev_info2);
 	dma += field_size;
-	xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tt_info\n",
+	xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - tt_info\n",
 			&slot_ctx->tt_info,
 			(unsigned long long)dma, slot_ctx->tt_info);
 	dma += field_size;
-	xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_state\n",
+	xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - dev_state\n",
 			&slot_ctx->dev_state,
 			(unsigned long long)dma, slot_ctx->dev_state);
 	dma += field_size;
 	for (i = 0; i < 4; ++i) {
-		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
+		xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
 				&slot_ctx->reserved[i], (unsigned long long)dma,
 				slot_ctx->reserved[i], i);
 		dma += field_size;
@@ -528,24 +528,24 @@
 		xhci_dbg(xhci, "%s Endpoint %02d Context (ep_index %02d):\n",
 				usb_endpoint_out(epaddr) ? "OUT" : "IN",
 				epaddr & USB_ENDPOINT_NUMBER_MASK, i);
-		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n",
+		xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - ep_info\n",
 				&ep_ctx->ep_info,
 				(unsigned long long)dma, ep_ctx->ep_info);
 		dma += field_size;
-		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info2\n",
+		xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - ep_info2\n",
 				&ep_ctx->ep_info2,
 				(unsigned long long)dma, ep_ctx->ep_info2);
 		dma += field_size;
-		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08llx - deq\n",
+		xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08llx - deq\n",
 				&ep_ctx->deq,
 				(unsigned long long)dma, ep_ctx->deq);
 		dma += 2*field_size;
-		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tx_info\n",
+		xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - tx_info\n",
 				&ep_ctx->tx_info,
 				(unsigned long long)dma, ep_ctx->tx_info);
 		dma += field_size;
 		for (j = 0; j < 3; ++j) {
-			xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
+			xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
 					&ep_ctx->reserved[j],
 					(unsigned long long)dma,
 					ep_ctx->reserved[j], j);
@@ -575,16 +575,16 @@
 			return;
 		}
 
-		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - drop flags\n",
+		xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - drop flags\n",
 			 &ctrl_ctx->drop_flags, (unsigned long long)dma,
 			 ctrl_ctx->drop_flags);
 		dma += field_size;
-		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - add flags\n",
+		xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - add flags\n",
 			 &ctrl_ctx->add_flags, (unsigned long long)dma,
 			 ctrl_ctx->add_flags);
 		dma += field_size;
 		for (i = 0; i < 6; ++i) {
-			xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd2[%d]\n",
+			xhci_dbg(xhci, "@%pK (virt) @%08llx (dma) %#08x - rsvd2[%d]\n",
 				 &ctrl_ctx->rsvd2[i], (unsigned long long)dma,
 				 ctrl_ctx->rsvd2[i], i);
 			dma += field_size;
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 2911b72..588e053 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1077,7 +1077,7 @@
 
 	/* Point to output device context in dcbaa. */
 	xhci->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(dev->out_ctx->dma);
-	xhci_dbg(xhci, "Set slot id %d dcbaa entry %p to 0x%llx\n",
+	xhci_dbg(xhci, "Set slot id %d dcbaa entry %pK to 0x%llx\n",
 		 slot_id,
 		 &xhci->dcbaa->dev_context_ptrs[slot_id],
 		 le64_to_cpu(xhci->dcbaa->dev_context_ptrs[slot_id]));
@@ -1251,7 +1251,7 @@
 		if (udev->tt->multi)
 			slot_ctx->dev_info |= cpu_to_le32(DEV_MTT);
 	}
-	xhci_dbg(xhci, "udev->tt = %p\n", udev->tt);
+	xhci_dbg(xhci, "udev->tt = %pK\n", udev->tt);
 	xhci_dbg(xhci, "udev->ttport = 0x%x\n", udev->ttport);
 
 	/* Step 4 - ring already allocated */
@@ -2101,15 +2101,15 @@
 	if (seg != result_seg) {
 		xhci_warn(xhci, "WARN: %s TRB math test %d failed!\n",
 				test_name, test_number);
-		xhci_warn(xhci, "Tested TRB math w/ seg %p and "
+		xhci_warn(xhci, "Tested TRB math w/ seg %pK and "
 				"input DMA 0x%llx\n",
 				input_seg,
 				(unsigned long long) input_dma);
-		xhci_warn(xhci, "starting TRB %p (0x%llx DMA), "
-				"ending TRB %p (0x%llx DMA)\n",
+		xhci_warn(xhci, "starting TRB %pK (0x%llx DMA), "
+				"ending TRB %pK (0x%llx DMA)\n",
 				start_trb, start_dma,
 				end_trb, end_dma);
-		xhci_warn(xhci, "Expected seg %p, got seg %p\n",
+		xhci_warn(xhci, "Expected seg %pK, got seg %pK\n",
 				result_seg, seg);
 		trb_in_td(xhci, input_seg, start_trb, end_trb, input_dma,
 			  true);
@@ -2258,7 +2258,7 @@
 		rhub = &xhci->usb2_rhub;
 	} else {
 		xhci_warn(xhci, "Ignoring unknown port speed, "
-				"Ext Cap %p, revision = 0x%x\n",
+				"Ext Cap %pK, revision = 0x%x\n",
 				addr, major_revision);
 		/* Ignoring port protocol we can't understand. FIXME */
 		return;
@@ -2273,7 +2273,7 @@
 	port_offset = XHCI_EXT_PORT_OFF(temp);
 	port_count = XHCI_EXT_PORT_COUNT(temp);
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init,
-			"Ext Cap %p, port offset = %u, "
+			"Ext Cap %pK, port offset = %u, "
 			"count = %u, revision = 0x%x",
 			addr, port_offset, port_count, major_revision);
 	/* Port count includes the current port offset */
@@ -2335,7 +2335,7 @@
 	for (i = port_offset; i < (port_offset + port_count); i++) {
 		/* Duplicate entry.  Ignore the port if the revisions differ. */
 		if (xhci->port_array[i] != 0) {
-			xhci_warn(xhci, "Duplicate port entry, Ext Cap %p,"
+			xhci_warn(xhci, "Duplicate port entry, Ext Cap %pK,"
 					" port %u\n", addr, i);
 			xhci_warn(xhci, "Port was marked as USB %u, "
 					"duplicated as USB %u\n",
@@ -2470,7 +2470,7 @@
 				NUM_PORT_REGS*i;
 			xhci_dbg_trace(xhci, trace_xhci_dbg_init,
 					"USB 2.0 port at index %u, "
-					"addr = %p", i,
+					"addr = %pK", i,
 					xhci->usb2_ports[port_index]);
 			port_index++;
 			if (port_index == xhci->num_usb2_ports)
@@ -2491,7 +2491,7 @@
 					NUM_PORT_REGS*i;
 				xhci_dbg_trace(xhci, trace_xhci_dbg_init,
 						"USB 3.0 port at index %u, "
-						"addr = %p", i,
+						"addr = %pK", i,
 						xhci->usb3_ports[port_index]);
 				port_index++;
 				if (port_index == xhci->num_usb3_ports)
@@ -2531,7 +2531,7 @@
 	erst->num_entries = ERST_NUM_SEGS;
 	erst->erst_dma_addr = dma;
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init,
-		"intr# %d: num segs = %i, virt addr = %p, dma addr = 0x%llx",
+		"intr# %d: num segs = %i, virt addr = %pK, dma addr = 0x%llx",
 			intr_num,
 			erst->num_entries,
 			erst->entries,
@@ -2603,7 +2603,7 @@
 		|| !xhci->sec_event_ring || !xhci->sec_erst ||
 		intr_num >= xhci->max_interrupters) {
 		xhci_err(xhci,
-		"%s:state %x ir_set %p evt_ring %p erst %p intr# %d\n",
+		"%s:state %x ir_set %pK evt_ring %pK erst %pK intr# %d\n",
 		__func__, xhci->xhc_state, xhci->sec_ir_set,
 		xhci->sec_event_ring, xhci->sec_erst, intr_num);
 		return -EINVAL;
@@ -2730,7 +2730,7 @@
 	memset(xhci->dcbaa, 0, sizeof *(xhci->dcbaa));
 	xhci->dcbaa->dma = dma;
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init,
-			"// Device context base array address = 0x%llx (DMA), %p (virt)",
+			"// Device context base array address = 0x%llx (DMA), %pK (virt)",
 			(unsigned long long)xhci->dcbaa->dma, xhci->dcbaa);
 	xhci_write_64(xhci, dma, &xhci->op_regs->dcbaa_ptr);
 
@@ -2771,7 +2771,7 @@
 	if (!xhci->cmd_ring)
 		goto fail;
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init,
-			"Allocated command ring at %p", xhci->cmd_ring);
+			"Allocated command ring at %pK", xhci->cmd_ring);
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init, "First segment DMA is 0x%llx",
 			(unsigned long long)xhci->cmd_ring->first_seg->dma);
 
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 7020b9e..f7c753f 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -290,7 +290,7 @@
 
 		i_cmd->status = COMP_CMD_STOP;
 
-		xhci_dbg(xhci, "Turn aborted command %p to no-op\n",
+		xhci_dbg(xhci, "Turn aborted command %pK to no-op\n",
 			 i_cmd->command_trb);
 		/* get cycle state from the original cmd trb */
 		cycle_state = le32_to_cpu(
@@ -555,7 +555,7 @@
 			"Cycle state = 0x%x", state->new_cycle_state);
 
 	xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
-			"New dequeue segment = %p (virtual)",
+			"New dequeue segment = %pK (virtual)",
 			state->new_deq_seg);
 	addr = xhci_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr);
 	xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
@@ -590,8 +590,8 @@
 			xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
 					"Cancel (unchain) link TRB");
 			xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
-					"Address = %p (0x%llx dma); "
-					"in seg %p (0x%llx dma)",
+					"Address = %pK (0x%llx dma); "
+					"in seg %pK (0x%llx dma)",
 					cur_trb,
 					(unsigned long long)xhci_trb_virt_to_dma(cur_seg, cur_trb),
 					cur_seg,
@@ -752,7 +752,7 @@
 			 * short, don't muck with the stream ID after
 			 * submission.
 			 */
-			xhci_warn(xhci, "WARN Cancelled URB %p "
+			xhci_warn(xhci, "WARN Cancelled URB %pK "
 					"has invalid stream ID %u.\n",
 					cur_td->urb,
 					cur_td->urb->stream_id);
@@ -1096,7 +1096,7 @@
 				ep_ring, ep_index);
 		} else {
 			xhci_warn(xhci, "Mismatch between completed Set TR Deq Ptr command & xHCI internal state.\n");
-			xhci_warn(xhci, "ep deq seg = %p, deq ptr = %p\n",
+			xhci_warn(xhci, "ep deq seg = %pK, deq ptr = %pK\n",
 				  ep->queued_deq_seg, ep->queued_deq_ptr);
 		}
 	}
@@ -2621,7 +2621,7 @@
 						 URB_SHORT_NOT_OK)) ||
 					(status != 0 &&
 					 !usb_endpoint_xfer_isoc(&urb->ep->desc)))
-				xhci_dbg(xhci, "Giveback URB %p, len = %d, "
+				xhci_dbg(xhci, "Giveback URB %pK, len = %d, "
 						"expected = %d, status = %d\n",
 						urb, urb->actual_length,
 						urb->transfer_buffer_length,
@@ -4182,7 +4182,7 @@
 	int ret;
 
 	xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
-		"Set TR Deq Ptr cmd, new deq seg = %p (0x%llx dma), new deq ptr = %p (0x%llx dma), new cycle = %u",
+		"Set TR Deq Ptr cmd, new deq seg = %pK (0x%llx dma), new deq ptr = %pK (0x%llx dma), new cycle = %u",
 		deq_state->new_deq_seg,
 		(unsigned long long)deq_state->new_deq_seg->dma,
 		deq_state->new_deq_ptr,
@@ -4194,7 +4194,7 @@
 				    deq_state->new_deq_ptr);
 	if (addr == 0) {
 		xhci_warn(xhci, "WARN Cannot submit Set TR Deq Ptr\n");
-		xhci_warn(xhci, "WARN deq seg = %p, deq pt = %p\n",
+		xhci_warn(xhci, "WARN deq seg = %pK, deq pt = %pK\n",
 			  deq_state->new_deq_seg, deq_state->new_deq_ptr);
 		return;
 	}
diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h
index 59c0565..4ef95ac 100644
--- a/drivers/usb/host/xhci-trace.h
+++ b/drivers/usb/host/xhci-trace.h
@@ -103,7 +103,7 @@
 			((HCC_64BYTE_CONTEXT(xhci->hcc_params) + 1) * 32) *
 			((ctx->type == XHCI_CTX_TYPE_INPUT) + ep_num + 1));
 	),
-	TP_printk("\nctx_64=%d, ctx_type=%u, ctx_dma=@%llx, ctx_va=@%p",
+	TP_printk("\nctx_64=%d, ctx_type=%u, ctx_dma=@%llx, ctx_va=@%pK",
 			__entry->ctx_64, __entry->ctx_type,
 			(unsigned long long) __entry->ctx_dma, __entry->ctx_va
 	)
@@ -134,7 +134,7 @@
 		memcpy(__get_dynamic_array(trb), trb_va,
 			sizeof(struct xhci_generic_trb));
 	),
-	TP_printk("\ntrb_dma=@%llx, trb_va=@%p, status=%08x, flags=%08x",
+	TP_printk("\ntrb_dma=@%llx, trb_va=@%pK, status=%08x, flags=%08x",
 			(unsigned long long) __entry->dma, __entry->va,
 			__entry->status, __entry->flags
 	)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 84ace86..fe2bbfb 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -690,7 +690,7 @@
 
 	temp = readl(&xhci->ir_set->irq_pending);
 	xhci_dbg_trace(xhci, trace_xhci_dbg_init,
-			"// Enabling event ring interrupter %p by writing 0x%x to irq_pending",
+			"// Enabling event ring interrupter %pK by writing 0x%x to irq_pending",
 			xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp));
 	writel(ER_IRQ_ENABLE(temp), &xhci->ir_set->irq_pending);
 	xhci_print_ir_set(xhci, 0);
@@ -1496,7 +1496,7 @@
 exit:
 	return ret;
 dying:
-	xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for "
+	xhci_dbg(xhci, "Ep 0x%x: URB %pK submitted for "
 			"non-responsive xHCI host.\n",
 			urb->ep->desc.bEndpointAddress, urb);
 	ret = -ESHUTDOWN;
@@ -1591,7 +1591,7 @@
 	i = urb_priv->td_cnt;
 	if (i < urb_priv->length)
 		xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
-				"Cancel URB %p, dev %s, ep 0x%x, "
+				"Cancel URB %pK, dev %s, ep 0x%x, "
 				"starting at offset 0x%llx",
 				urb, urb->dev->devpath,
 				urb->ep->desc.bEndpointAddress,
@@ -1659,7 +1659,7 @@
 	if (xhci->xhc_state & XHCI_STATE_DYING)
 		return -ENODEV;
 
-	xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
+	xhci_dbg(xhci, "%s called for udev %pK\n", __func__, udev);
 	drop_flag = xhci_get_endpoint_flag(&ep->desc);
 	if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) {
 		xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n",
@@ -1687,7 +1687,7 @@
 	    xhci_get_endpoint_flag(&ep->desc)) {
 		/* Do not warn when called after a usb_device_reset */
 		if (xhci->devs[udev->slot_id]->eps[ep_index].ring != NULL)
-			xhci_warn(xhci, "xHCI %s called with disabled ep %p\n",
+			xhci_warn(xhci, "xHCI %s called with disabled ep %pK\n",
 				  __func__, ep);
 		return 0;
 	}
@@ -1782,7 +1782,7 @@
 	 * ignore this request.
 	 */
 	if (le32_to_cpu(ctrl_ctx->add_flags) & added_ctxs) {
-		xhci_warn(xhci, "xHCI %s called with enabled ep %p\n",
+		xhci_warn(xhci, "xHCI %s called with enabled ep %pK\n",
 				__func__, ep);
 		return 0;
 	}
@@ -2772,7 +2772,7 @@
 		(xhci->xhc_state & XHCI_STATE_REMOVING))
 		return -ENODEV;
 
-	xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
+	xhci_dbg(xhci, "%s called for udev %pK\n", __func__, udev);
 	virt_dev = xhci->devs[udev->slot_id];
 
 	command = xhci_alloc_command(xhci, false, true, GFP_KERNEL);
@@ -2869,7 +2869,7 @@
 		return;
 	xhci = hcd_to_xhci(hcd);
 
-	xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);
+	xhci_dbg(xhci, "%s called for udev %pK\n", __func__, udev);
 	virt_dev = xhci->devs[udev->slot_id];
 	/* Free any rings allocated for added endpoints */
 	for (i = 0; i < 31; ++i) {
@@ -2922,7 +2922,7 @@
 	if (addr == 0) {
 		xhci_warn(xhci, "WARN Cannot submit config ep after "
 				"reset ep command\n");
-		xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n",
+		xhci_warn(xhci, "WARN deq seg = %pK, deq ptr = %pK\n",
 				deq_state->new_deq_seg,
 				deq_state->new_deq_ptr);
 		return;
@@ -3949,7 +3949,7 @@
 	xhci_dbg_trace(xhci, trace_xhci_dbg_address,
 			"Op regs DCBAA ptr = %#016llx", temp_64);
 	xhci_dbg_trace(xhci, trace_xhci_dbg_address,
-		"Slot ID %d dcbaa entry @%p = %#016llx",
+		"Slot ID %d dcbaa entry @%pK = %#016llx",
 		udev->slot_id,
 		&xhci->dcbaa->dev_context_ptrs[udev->slot_id],
 		(unsigned long long)
diff --git a/drivers/usb/phy/phy-msm-snps-hs.c b/drivers/usb/phy/phy-msm-snps-hs.c
index a259790..28a9bf1 100644
--- a/drivers/usb/phy/phy-msm-snps-hs.c
+++ b/drivers/usb/phy/phy-msm-snps-hs.c
@@ -69,6 +69,9 @@
 #define REFCLK_SEL_MASK				(0x3 << 0)
 #define REFCLK_SEL_DEFAULT			(0x2 << 0)
 
+#define USB2PHY_USB_PHY_RTUNE_SEL		(0xb4)
+#define RTUNE_SEL				BIT(0)
+
 #define USB_HSPHY_3P3_VOL_MIN			3050000 /* uV */
 #define USB_HSPHY_3P3_VOL_MAX			3300000 /* uV */
 #define USB_HSPHY_3P3_HPM_LOAD			16000	/* uA */
@@ -390,6 +393,9 @@
 		hsusb_phy_write_seq(phy->base, phy->param_override_seq,
 				phy->param_override_seq_cnt, 0);
 
+	msm_usb_write_readback(phy->base, USB2PHY_USB_PHY_RTUNE_SEL,
+			RTUNE_SEL, RTUNE_SEL);
+
 	msm_usb_write_readback(phy->base, USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON2,
 				VREGBYPASS, VREGBYPASS);
 
diff --git a/drivers/video/fbdev/msm/mdp3.c b/drivers/video/fbdev/msm/mdp3.c
index 5cf439c..00183f8 100644
--- a/drivers/video/fbdev/msm/mdp3.c
+++ b/drivers/video/fbdev/msm/mdp3.c
@@ -44,7 +44,6 @@
 
 #include <linux/msm-bus.h>
 #include <linux/msm-bus-board.h>
-#include <linux/qcom_iommu.h>
 
 #include <linux/msm_dma_iommu_mapping.h>
 
@@ -116,39 +115,14 @@
 	[MDP3_IOMMU_DOMAIN_UNSECURE] = {
 		.domain_type = MDP3_IOMMU_DOMAIN_UNSECURE,
 		.client_name = "mdp_ns",
-		.partitions = {
-			{
-				.start = SZ_128K,
-				.size = SZ_1G - SZ_128K,
-			},
-		},
 		.npartitions = 1,
+		.domain_idx = MDP3_IOMMU_DOMAIN_UNSECURE,
 	},
 	[MDP3_IOMMU_DOMAIN_SECURE] = {
 		.domain_type = MDP3_IOMMU_DOMAIN_SECURE,
 		.client_name = "mdp_secure",
-		.partitions = {
-			{
-				.start = SZ_1G,
-				.size = SZ_1G,
-			},
-		},
 		.npartitions = 1,
-	},
-};
-
-struct mdp3_iommu_ctx_map mdp3_iommu_contexts[MDP3_IOMMU_CTX_MAX] = {
-	[MDP3_IOMMU_CTX_MDP_0] = {
-		.ctx_type = MDP3_IOMMU_CTX_MDP_0,
-		.domain = &mdp3_iommu_domains[MDP3_IOMMU_DOMAIN_UNSECURE],
-		.ctx_name = "mdp_0",
-		.attached = 0,
-	},
-	[MDP3_IOMMU_CTX_MDP_1] = {
-		.ctx_type = MDP3_IOMMU_CTX_MDP_1,
-		.domain = &mdp3_iommu_domains[MDP3_IOMMU_DOMAIN_SECURE],
-		.ctx_name = "mdp_1",
-		.attached = 0,
+		.domain_idx = MDP3_IOMMU_DOMAIN_SECURE,
 	},
 };
 
@@ -785,7 +759,7 @@
 	ret = devm_request_irq(&mdp3_res->pdev->dev,
 				mdp3_hw->irq_info->irq,
 				mdp3_irq_handler,
-				IRQF_DISABLED, "MDP", mdp3_res);
+				0, "MDP", mdp3_res);
 	if (ret) {
 		pr_err("mdp request_irq() failed!\n");
 		return ret;
@@ -795,7 +769,6 @@
 	return 0;
 }
 
-
 static int mdp3_get_iommu_domain(u32 type)
 {
 	if (type >= MDSS_IOMMU_MAX_DOMAIN)
@@ -807,155 +780,6 @@
 	return mdp3_res->domains[type].domain_idx;
 }
 
-int mdp3_iommu_attach(int context)
-{
-	int rc = 0;
-	struct mdp3_iommu_ctx_map *context_map;
-	struct mdp3_iommu_domain_map *domain_map;
-
-	if (context >= MDP3_IOMMU_CTX_MAX)
-		return -EINVAL;
-
-	context_map = mdp3_res->iommu_contexts + context;
-	if (context_map->attached) {
-		pr_warn("mdp iommu already attached\n");
-		return 0;
-	}
-
-	domain_map = context_map->domain;
-
-	rc = iommu_attach_device(domain_map->domain, context_map->ctx);
-	if (rc) {
-		pr_err("mpd3 iommu attach failed\n");
-		return -EINVAL;
-	}
-
-	context_map->attached = true;
-	return 0;
-}
-
-int mdp3_iommu_dettach(int context)
-{
-	struct mdp3_iommu_ctx_map *context_map;
-	struct mdp3_iommu_domain_map *domain_map;
-
-	if (!mdp3_res->iommu_contexts ||
-		context >= MDP3_IOMMU_CTX_MAX)
-		return -EINVAL;
-
-	context_map = mdp3_res->iommu_contexts + context;
-	if (!context_map->attached) {
-		pr_warn("mdp iommu not attached\n");
-		return 0;
-	}
-
-	domain_map = context_map->domain;
-	iommu_detach_device(domain_map->domain, context_map->ctx);
-	context_map->attached = false;
-
-	return 0;
-}
-
-int mdp3_iommu_domain_init(void)
-{
-	struct msm_iova_layout layout;
-	int i;
-
-	if (mdp3_res->domains) {
-		pr_warn("iommu domain already initialized\n");
-		return 0;
-	}
-
-	for (i = 0; i < MDP3_IOMMU_DOMAIN_MAX; i++) {
-		int domain_idx;
-
-		layout.client_name = mdp3_iommu_domains[i].client_name;
-		layout.partitions = mdp3_iommu_domains[i].partitions;
-		layout.npartitions = mdp3_iommu_domains[i].npartitions;
-		layout.is_secure = (i == MDP3_IOMMU_DOMAIN_SECURE);
-
-		domain_idx = msm_register_domain(&layout);
-		if (IS_ERR_VALUE(domain_idx))
-			return -EINVAL;
-
-		mdp3_iommu_domains[i].domain_idx = domain_idx;
-		mdp3_iommu_domains[i].domain = msm_get_iommu_domain(domain_idx);
-		if (IS_ERR_OR_NULL(mdp3_iommu_domains[i].domain)) {
-			pr_err("unable to get iommu domain(%d)\n",
-				domain_idx);
-			if (!mdp3_iommu_domains[i].domain)
-				return -EINVAL;
-			else
-				return PTR_ERR(mdp3_iommu_domains[i].domain);
-		}
-	}
-
-	mdp3_res->domains = mdp3_iommu_domains;
-
-	return 0;
-}
-
-int mdp3_iommu_context_init(void)
-{
-	int i;
-
-	if (mdp3_res->iommu_contexts) {
-		pr_warn("iommu context already initialized\n");
-		return 0;
-	}
-
-	for (i = 0; i < MDP3_IOMMU_CTX_MAX; i++) {
-		mdp3_iommu_contexts[i].ctx =
-			msm_iommu_get_ctx(mdp3_iommu_contexts[i].ctx_name);
-
-		if (IS_ERR_OR_NULL(mdp3_iommu_contexts[i].ctx)) {
-			pr_warn("unable to get iommu ctx(%s)\n",
-				mdp3_iommu_contexts[i].ctx_name);
-			if (!mdp3_iommu_contexts[i].ctx)
-				return -EINVAL;
-			else
-				return PTR_ERR(mdp3_iommu_contexts[i].ctx);
-		}
-	}
-
-	mdp3_res->iommu_contexts = mdp3_iommu_contexts;
-
-	return 0;
-}
-
-int mdp3_iommu_init(void)
-{
-	int ret;
-
-	mutex_init(&mdp3_res->iommu_lock);
-
-	ret = mdp3_iommu_domain_init();
-	if (ret) {
-		pr_err("mdp3 iommu domain init fails\n");
-		return ret;
-	}
-
-	ret = mdp3_iommu_context_init();
-	if (ret) {
-		pr_err("mdp3 iommu context init fails\n");
-		return ret;
-	}
-	return ret;
-}
-
-void mdp3_iommu_deinit(void)
-{
-	int i;
-
-	if (!mdp3_res->domains)
-		return;
-
-	for (i = 0; i < MDP3_IOMMU_DOMAIN_MAX; i++) {
-		if (!IS_ERR_OR_NULL(mdp3_res->domains[i].domain))
-			msm_unregister_domain(mdp3_res->domains[i].domain);
-	}
-}
-
 static int mdp3_check_version(void)
 {
 	int rc;
@@ -1151,11 +975,9 @@
 		mdp3_res->ion_client = NULL;
 		return -EINVAL;
 	}
+	mutex_init(&mdp3_res->iommu_lock);
 
-	rc = mdp3_iommu_init();
-	if (rc)
-		return rc;
-
+	mdp3_res->domains = mdp3_iommu_domains;
 	mdp3_res->bus_handle = mdp3_bus_handle;
 	rc = mdp3_bus_scale_register();
 	if (rc) {
@@ -1171,18 +993,20 @@
 static void mdp3_res_deinit(void)
 {
 	struct mdss_hw *mdp3_hw;
-	int i;
+	int rc = 0;
 
 	mdp3_hw = &mdp3_res->mdp3_hw;
 	mdp3_bus_scale_unregister();
-
 	mutex_lock(&mdp3_res->iommu_lock);
-	for (i = 0; i < MDP3_IOMMU_CTX_MAX; i++)
-		mdp3_iommu_dettach(i);
+	if (mdp3_res->iommu_ref_cnt) {
+		mdp3_res->iommu_ref_cnt--;
+		if (mdp3_res->iommu_ref_cnt == 0)
+			rc = mdss_smmu_detach(mdss_res);
+		} else {
+			pr_err("iommu ref count %d\n", mdp3_res->iommu_ref_cnt);
+		}
 	mutex_unlock(&mdp3_res->iommu_lock);
 
-	mdp3_iommu_deinit();
-
 	if (!IS_ERR_OR_NULL(mdp3_res->ion_client))
 		ion_client_destroy(mdp3_res->ion_client);
 
@@ -1503,317 +1327,6 @@
 	mdp3_batfet_ctrl(enable);
 }
 
-static void mdp3_iommu_heap_unmap_iommu(struct mdp3_iommu_meta *meta)
-{
-	unsigned int domain_num;
-	unsigned int partition_num = 0;
-	struct iommu_domain *domain;
-
-	domain_num = (mdp3_res->domains +
-			MDP3_IOMMU_DOMAIN_UNSECURE)->domain_idx;
-	domain = msm_get_iommu_domain(domain_num);
-
-	if (!domain) {
-		pr_err("Could not get domain %d. Corruption?\n", domain_num);
-		return;
-	}
-
-	iommu_unmap_range(domain, meta->iova_addr, meta->mapped_size);
-	msm_free_iova_address(meta->iova_addr, domain_num, partition_num,
-		meta->mapped_size);
-}
-
-static void mdp3_iommu_meta_destroy(struct kref *kref)
-{
-	struct mdp3_iommu_meta *meta =
-			container_of(kref, struct mdp3_iommu_meta, ref);
-
-	rb_erase(&meta->node, &mdp3_res->iommu_root);
-	mdp3_iommu_heap_unmap_iommu(meta);
-	dma_buf_put(meta->dbuf);
-	kfree(meta);
-}
-
-
-static void mdp3_iommu_meta_put(struct mdp3_iommu_meta *meta)
-{
-	/* Need to lock here to prevent race against map/unmap */
-	mutex_lock(&mdp3_res->iommu_lock);
-	kref_put(&meta->ref, mdp3_iommu_meta_destroy);
-	mutex_unlock(&mdp3_res->iommu_lock);
-}
-
-static struct mdp3_iommu_meta *mdp3_iommu_meta_lookup(struct sg_table *table)
-{
-	struct rb_root *root = &mdp3_res->iommu_root;
-	struct rb_node **p = &root->rb_node;
-	struct rb_node *parent = NULL;
-	struct mdp3_iommu_meta *entry = NULL;
-
-	while (*p) {
-		parent = *p;
-		entry = rb_entry(parent, struct mdp3_iommu_meta, node);
-
-		if (table < entry->table)
-			p = &(*p)->rb_left;
-		else if (table > entry->table)
-			p = &(*p)->rb_right;
-		else
-			return entry;
-	}
-	return NULL;
-}
-
-void mdp3_unmap_iommu(struct ion_client *client, struct ion_handle *handle)
-{
-	struct mdp3_iommu_meta *meta;
-	struct sg_table *table;
-
-	table = ion_sg_table(client, handle);
-
-	mutex_lock(&mdp3_res->iommu_lock);
-	meta = mdp3_iommu_meta_lookup(table);
-	if (!meta) {
-		WARN(1, "%s: buffer was never mapped for %pK\n", __func__,
-				handle);
-		mutex_unlock(&mdp3_res->iommu_lock);
-		return;
-	}
-	mutex_unlock(&mdp3_res->iommu_lock);
-
-	mdp3_iommu_meta_put(meta);
-}
-
-static void mdp3_iommu_meta_add(struct mdp3_iommu_meta *meta)
-{
-	struct rb_root *root = &mdp3_res->iommu_root;
-	struct rb_node **p = &root->rb_node;
-	struct rb_node *parent = NULL;
-	struct mdp3_iommu_meta *entry;
-
-	while (*p) {
-		parent = *p;
-		entry = rb_entry(parent, struct mdp3_iommu_meta, node);
-
-		if (meta->table < entry->table) {
-			p = &(*p)->rb_left;
-		} else if (meta->table > entry->table) {
-			p = &(*p)->rb_right;
-		} else {
-			pr_err("%s: handle %pK already exists\n", __func__,
-				entry->handle);
-			WARN_ON(1);
-		}
-	}
-
-	rb_link_node(&meta->node, parent, p);
-	rb_insert_color(&meta->node, root);
-}
-
-static int mdp3_iommu_map_iommu(struct mdp3_iommu_meta *meta,
-	unsigned long align, unsigned long iova_length,
-	unsigned int padding, unsigned long flags)
-{
-	struct iommu_domain *domain;
-	int ret = 0;
-	unsigned long size;
-	unsigned long unmap_size;
-	struct sg_table *table;
-	int prot = IOMMU_WRITE | IOMMU_READ;
-	unsigned int domain_num = (mdp3_res->domains +
-			MDP3_IOMMU_DOMAIN_UNSECURE)->domain_idx;
-	unsigned int partition_num = 0;
-
-	size = meta->size;
-	table = meta->table;
-
-	/* Use the biggest alignment to allow bigger IOMMU mappings.
-	 * Use the first entry since the first entry will always be the
-	 * biggest entry. To take advantage of bigger mapping sizes both the
-	 * VA and PA addresses have to be aligned to the biggest size.
-	 */
-	if (table->sgl->length > align)
-		align = table->sgl->length;
-
-	ret = msm_allocate_iova_address(domain_num, partition_num,
-			meta->mapped_size, align,
-			(unsigned long *)&meta->iova_addr);
-
-	if (ret)
-		goto out;
-
-	domain = msm_get_iommu_domain(domain_num);
-
-	if (!domain) {
-		ret = -ENOMEM;
-		goto out1;
-	}
-
-	/* Adding padding to before buffer */
-	if (padding) {
-		unsigned long phys_addr = sg_phys(table->sgl);
-
-		ret = msm_iommu_map_extra(domain, meta->iova_addr, phys_addr,
-				padding, SZ_4K, prot);
-		if (ret)
-			goto out1;
-	}
-
-	/* Mapping actual buffer */
-	ret = iommu_map_range(domain, meta->iova_addr + padding,
-			table->sgl, size, prot);
-	if (ret) {
-		pr_err("%s: could not map %pa in domain %pK\n",
-			__func__, &meta->iova_addr, domain);
-			unmap_size = padding;
-		goto out2;
-	}
-
-	/* Adding padding to end of buffer */
-	if (padding) {
-		unsigned long phys_addr = sg_phys(table->sgl);
-		unsigned long extra_iova_addr = meta->iova_addr +
-				padding + size;
-		ret = msm_iommu_map_extra(domain, extra_iova_addr, phys_addr,
-				padding, SZ_4K, prot);
-		if (ret) {
-			unmap_size = padding + size;
-			goto out2;
-		}
-	}
-	return ret;
-
-out2:
-	iommu_unmap_range(domain, meta->iova_addr, unmap_size);
-out1:
-	msm_free_iova_address(meta->iova_addr, domain_num, partition_num,
-				iova_length);
-
-out:
-	return ret;
-}
-
-static struct mdp3_iommu_meta *mdp3_iommu_meta_create(struct ion_client *client,
-	struct ion_handle *handle, struct sg_table *table, unsigned long size,
-	unsigned long align, unsigned long iova_length, unsigned int padding,
-	unsigned long flags, dma_addr_t *iova)
-{
-	struct mdp3_iommu_meta *meta;
-	int ret;
-
-	meta = kzalloc(sizeof(*meta), GFP_KERNEL);
-
-	if (!meta)
-		return ERR_PTR(-ENOMEM);
-
-	meta->handle = handle;
-	meta->table = table;
-	meta->size = size;
-	meta->mapped_size = iova_length;
-	meta->dbuf = ion_share_dma_buf(client, handle);
-	kref_init(&meta->ref);
-
-	ret = mdp3_iommu_map_iommu(meta,
-		align, iova_length, padding, flags);
-	if (ret < 0)	{
-		pr_err("%s: Unable to map buffer\n", __func__);
-		goto out;
-	}
-
-	*iova = meta->iova_addr;
-	mdp3_iommu_meta_add(meta);
-
-	return meta;
-out:
-	kfree(meta);
-	return ERR_PTR(ret);
-}
-
-/*
- * PPP hw reads in tiles of 16 which might be outside mapped region
- * need to map buffers ourseleve to add extra padding
- */
-int mdp3_self_map_iommu(struct ion_client *client, struct ion_handle *handle,
-	unsigned long align, unsigned long padding, dma_addr_t *iova,
-	unsigned long *buffer_size, unsigned long flags,
-	unsigned long iommu_flags)
-{
-	struct mdp3_iommu_meta *iommu_meta = NULL;
-	struct sg_table *table;
-	struct scatterlist *sg;
-	unsigned long size = 0, iova_length = 0;
-	int ret = 0;
-	int i;
-
-	table = ion_sg_table(client, handle);
-	if (IS_ERR_OR_NULL(table))
-		return PTR_ERR(table);
-
-	for_each_sg(table->sgl, sg, table->nents, i)
-		size += sg->length;
-
-	padding = PAGE_ALIGN(padding);
-
-	/* Adding 16 lines padding before and after buffer */
-	iova_length = size + 2 * padding;
-
-	if (size & ~PAGE_MASK) {
-		pr_debug("%s: buffer size %lx is not aligned to %lx",
-			__func__, size, PAGE_SIZE);
-		ret = -EINVAL;
-		goto out;
-	}
-
-	if (iova_length & ~PAGE_MASK) {
-		pr_debug("%s: iova_length %lx is not aligned to %lx",
-			__func__, iova_length, PAGE_SIZE);
-		ret = -EINVAL;
-		goto out;
-	}
-
-	mutex_lock(&mdp3_res->iommu_lock);
-	iommu_meta = mdp3_iommu_meta_lookup(table);
-
-	if (!iommu_meta) {
-		iommu_meta = mdp3_iommu_meta_create(client, handle, table, size,
-				align, iova_length, padding, flags, iova);
-		if (!IS_ERR_OR_NULL(iommu_meta)) {
-			iommu_meta->flags = iommu_flags;
-			ret = 0;
-		} else {
-			ret = PTR_ERR(iommu_meta);
-			goto out_unlock;
-		}
-	} else {
-		if (iommu_meta->flags != iommu_flags) {
-			pr_err("%s: hndl %pK already mapped with diff flag\n",
-				__func__, handle);
-			ret = -EINVAL;
-			goto out_unlock;
-		} else if (iommu_meta->mapped_size != iova_length) {
-			pr_err("%s: hndl %pK already mapped with diff len\n",
-				__func__, handle);
-			ret = -EINVAL;
-			goto out_unlock;
-		} else {
-			kref_get(&iommu_meta->ref);
-			*iova = iommu_meta->iova_addr;
-		}
-	}
-	WARN_ON(iommu_meta->size != size);
-	mutex_unlock(&mdp3_res->iommu_lock);
-
-	*iova = *iova + padding;
-	*buffer_size = size;
-	return ret;
-
-out_unlock:
-	mutex_unlock(&mdp3_res->iommu_lock);
-out:
-	mdp3_iommu_meta_put(iommu_meta);
-	return ret;
-}
-
 int mdp3_put_img(struct mdp3_img_data *data, int client)
 {
 	struct ion_client *iclient = mdp3_res->ion_client;
@@ -1877,10 +1390,10 @@
 					img->memory_id);
 			return -EINVAL;
 		}
-		if (MAJOR(f.file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
-			fb_num = MINOR(f.file->f_dentry->d_inode->i_rdev);
+		if (MAJOR(f.file->f_path.dentry->d_inode->i_rdev) == FB_MAJOR) {
+			fb_num = MINOR(f.file->f_path.dentry->d_inode->i_rdev);
 			ret = mdss_fb_get_phys_info(&data->addr,
-						&data->len, fb_num);
+							&data->len, fb_num);
 			if (ret) {
 				pr_err("mdss_fb_get_phys_info() failed\n");
 				fdput(f);
@@ -2155,29 +1668,6 @@
 	return rc;
 }
 
-void mdp3_free(struct msm_fb_data_type *mfd)
-{
-	size_t size = 0;
-	int dom;
-	unsigned long phys;
-
-	if (!mfd->iova || !mfd->fbi->screen_base) {
-		pr_info("no fbmem allocated\n");
-		return;
-	}
-
-	size = mfd->fbi->fix.smem_len;
-	phys = mfd->fbi->fix.smem_start;
-	dom = mdp3_res->domains[MDP3_IOMMU_DOMAIN_UNSECURE].domain_idx;
-	iommu_unmap(mdp3_res->domains[MDP3_IOMMU_DOMAIN_UNSECURE].domain,
-			phys, size);
-	msm_iommu_unmap_contig_buffer(mfd->iova, dom, 0, size);
-
-	mfd->fbi->screen_base = NULL;
-	mfd->fbi->fix.smem_start = 0;
-	mfd->iova = 0;
-}
-
 void mdp3_release_splash_memory(struct msm_fb_data_type *mfd)
 {
 	/* Give back the reserved memory to the system */
@@ -2188,7 +1678,6 @@
 				mdp3_res->splash_mem_addr,
 				mdp3_res->splash_mem_size);
 		}
-		mdp3_free(mfd);
 		pr_debug("mdp3_release_splash_memory\n");
 		memblock_free(mdp3_res->splash_mem_addr,
 				mdp3_res->splash_mem_size);
@@ -3056,8 +2545,7 @@
 #define mdp3_resume  NULL
 #endif
 
-
-#ifdef CONFIG_PM_RUNTIME
+#ifdef CONFIG_PM
 static int mdp3_runtime_resume(struct device *dev)
 {
 	bool device_on = true;
diff --git a/drivers/video/fbdev/msm/mdp3_ctrl.c b/drivers/video/fbdev/msm/mdp3_ctrl.c
index 1ce1878..4a844e9 100644
--- a/drivers/video/fbdev/msm/mdp3_ctrl.c
+++ b/drivers/video/fbdev/msm/mdp3_ctrl.c
@@ -22,13 +22,13 @@
 #include <linux/delay.h>
 #include <linux/dma-buf.h>
 #include <linux/pm_runtime.h>
-#include <linux/sw_sync.h>
 #include <linux/iommu.h>
 
 #include "mdp3_ctrl.h"
 #include "mdp3.h"
 #include "mdp3_ppp.h"
 #include "mdss_smmu.h"
+#include "mdss_sync.h"
 
 #define VSYNC_EXPIRE_TICK	4
 
@@ -233,7 +233,7 @@
 
 	mutex_lock(&mfd->mdp_sync_pt_data.sync_mutex);
 	if (mdp3_session->retire_cnt > 0) {
-		sw_sync_timeline_inc(mdp3_session->vsync_timeline, val);
+		mdss_inc_timeline(mfd->mdp_sync_pt_data.timeline_retire, val);
 		mdp3_session->retire_cnt -= min(val, mdp3_session->retire_cnt);
 	}
 	mutex_unlock(&mfd->mdp_sync_pt_data.sync_mutex);
@@ -1737,9 +1737,10 @@
 		}
 		break;
 	case metadata_op_get_ion_fd:
-		if (mfd->fb_ion_handle) {
+		if (mfd->fb_ion_handle && mfd->fb_ion_client) {
 			metadata->data.fbmem_ionfd =
-					dma_buf_fd(mfd->fbmem_buf, 0);
+				ion_share_dma_buf_fd(mfd->fb_ion_client,
+					mfd->fb_ion_handle);
 			if (metadata->data.fbmem_ionfd < 0)
 				pr_err("fd allocation failed. fd = %d\n",
 						metadata->data.fbmem_ionfd);
@@ -2116,7 +2117,7 @@
 static int mdp3_histo_ioctl(struct msm_fb_data_type *mfd, u32 cmd,
 				void __user *argp)
 {
-	int ret = -ENOTSUP;
+	int ret = -ENOTSUPP;
 	struct mdp_histogram_data hist;
 	struct mdp_histogram_start_req hist_req;
 	u32 block;
@@ -2820,8 +2821,8 @@
 	mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
 
 	snprintf(name, sizeof(name), "mdss_fb%d_retire", mfd->index);
-	mdp3_session->vsync_timeline = sw_sync_timeline_create(name);
-	if (mdp3_session->vsync_timeline == NULL) {
+	mfd->mdp_sync_pt_data.timeline_retire = mdss_create_timeline(name);
+	if (mfd->mdp_sync_pt_data.timeline_retire == NULL) {
 		pr_err("cannot vsync create time line");
 		return -ENOMEM;
 	}
@@ -2874,8 +2875,9 @@
 	mutex_init(&mdp3_session->lock);
 	INIT_WORK(&mdp3_session->clk_off_work, mdp3_dispatch_clk_off);
 
-	init_kthread_worker(&mdp3_session->worker);
-	init_kthread_work(&mdp3_session->dma_done_work, mdp3_dispatch_dma_done);
+	kthread_init_worker(&mdp3_session->worker);
+	kthread_init_work(&mdp3_session->dma_done_work, mdp3_dispatch_dma_done);
+
 
 	mdp3_session->thread = kthread_run(kthread_worker_fn,
 					   &mdp3_session->worker,
diff --git a/drivers/video/fbdev/msm/mdp3_ctrl.h b/drivers/video/fbdev/msm/mdp3_ctrl.h
index 2cc3421..b7b667b 100644
--- a/drivers/video/fbdev/msm/mdp3_ctrl.h
+++ b/drivers/video/fbdev/msm/mdp3_ctrl.h
@@ -79,7 +79,7 @@
 	int (*wait_for_dma_done)(struct mdp3_session_data *session);
 
 	/* For retire fence */
-	struct sw_sync_timeline *vsync_timeline;
+	struct mdss_timeline *vsync_timeline;
 	int retire_cnt;
 	struct work_struct retire_work;
 };
diff --git a/drivers/video/fbdev/msm/mdp3_layer.c b/drivers/video/fbdev/msm/mdp3_layer.c
index 6c45395..0078466 100644
--- a/drivers/video/fbdev/msm/mdp3_layer.c
+++ b/drivers/video/fbdev/msm/mdp3_layer.c
@@ -21,8 +21,6 @@
 #include <linux/delay.h>
 #include <linux/msm_mdp.h>
 #include <linux/memblock.h>
-#include <linux/sync.h>
-#include <linux/sw_sync.h>
 #include <linux/file.h>
 
 #include <soc/qcom/event_timer.h>
@@ -31,17 +29,18 @@
 #include "mdp3_ppp.h"
 #include "mdp3_ctrl.h"
 #include "mdss_fb.h"
+#include "mdss_sync.h"
 
 enum {
 	MDP3_RELEASE_FENCE = 0,
 	MDP3_RETIRE_FENCE,
 };
 
-static struct sync_fence *__mdp3_create_fence(struct msm_fb_data_type *mfd,
+static struct mdss_fence *__mdp3_create_fence(struct msm_fb_data_type *mfd,
 	struct msm_sync_pt_data *sync_pt_data, u32 fence_type,
 	int *fence_fd, int value)
 {
-	struct sync_fence *sync_fence = NULL;
+	struct mdss_fence *sync_fence = NULL;
 	char fence_name[32];
 	struct mdp3_session_data *mdp3_session;
 
@@ -56,38 +55,42 @@
 
 	if ((fence_type == MDP3_RETIRE_FENCE) &&
 		(mfd->panel.type == MIPI_CMD_PANEL)) {
-		if (mdp3_session->vsync_timeline) {
-			value = mdp3_session->vsync_timeline->value + 1 +
-				mdp3_session->retire_cnt++;
-			sync_fence = mdss_fb_sync_get_fence(
-					mdp3_session->vsync_timeline,
+		if (sync_pt_data->timeline_retire) {
+			value = sync_pt_data->timeline_retire->value + 1 +
+						mdp3_session->retire_cnt++;
+					sync_fence = mdss_fb_sync_get_fence(
+					sync_pt_data->timeline_retire,
 						fence_name, value);
+
 		} else {
 			return ERR_PTR(-EPERM);
 		}
 	} else {
-		sync_fence = mdss_fb_sync_get_fence(sync_pt_data->timeline,
-			fence_name, value);
-	}
+		if (fence_type == MDP3_RETIRE_FENCE)
+			sync_fence = mdss_fb_sync_get_fence(
+						sync_pt_data->timeline_retire,
+							fence_name, value);
+		else
+			sync_fence = mdss_fb_sync_get_fence(
+						sync_pt_data->timeline,
+							fence_name, value);
+		}
 
 	if (IS_ERR_OR_NULL(sync_fence)) {
 		pr_err("%s: unable to retrieve release fence\n", fence_name);
 		goto end;
 	}
 
-	/* get fence fd */
-	*fence_fd = get_unused_fd_flags(0);
+	*fence_fd = mdss_get_sync_fence_fd(sync_fence);
 	if (*fence_fd < 0) {
 		pr_err("%s: get_unused_fd_flags failed error:0x%x\n",
 			fence_name, *fence_fd);
-		sync_fence_put(sync_fence);
-		sync_fence = NULL;
-		goto end;
+			mdss_put_sync_fence(sync_fence);
+			sync_fence = NULL;
+			goto end;
 	}
-
-	sync_fence_install(sync_fence, *fence_fd);
+	pr_debug("%s:val=%d\n", mdss_get_sync_fence_name(sync_fence), value);
 end:
-
 	return sync_fence;
 }
 
@@ -101,7 +104,7 @@
 static int __mdp3_handle_buffer_fences(struct msm_fb_data_type *mfd,
 	struct mdp_layer_commit_v1 *commit, struct mdp_input_layer *layer_list)
 {
-	struct sync_fence *fence, *release_fence, *retire_fence;
+	struct mdss_fence *fence, *release_fence, *retire_fence;
 	struct msm_sync_pt_data *sync_pt_data = NULL;
 	struct mdp_input_layer *layer;
 	int value;
@@ -127,7 +130,7 @@
 		if (layer->buffer.fence < 0)
 			continue;
 
-		fence = sync_fence_fdget(layer->buffer.fence);
+		fence = mdss_get_fd_sync_fence(layer->buffer.fence);
 		if (!fence) {
 			pr_err("%s: sync fence get failed! fd=%d\n",
 				sync_pt_data->fence_name, layer->buffer.fence);
@@ -142,7 +145,7 @@
 	if (ret)
 		goto sync_fence_err;
 
-	value = sync_pt_data->timeline_value + sync_pt_data->threshold +
+	value = sync_pt_data->threshold +
 			atomic_read(&sync_pt_data->commit_cnt);
 
 	release_fence = __mdp3_create_fence(mfd, sync_pt_data,
@@ -166,13 +169,13 @@
 
 retire_fence_err:
 	put_unused_fd(commit->release_fence);
-	sync_fence_put(release_fence);
+	mdss_put_sync_fence(release_fence);
 release_fence_err:
 	commit->retire_fence = -1;
 	commit->release_fence = -1;
 sync_fence_err:
 	for (i = 0; i < sync_pt_data->acq_fen_cnt; i++)
-		sync_fence_put(sync_pt_data->acq_fen[i]);
+		mdss_put_sync_fence(sync_pt_data->acq_fen[i]);
 	sync_pt_data->acq_fen_cnt = 0;
 
 	mutex_unlock(&sync_pt_data->sync_mutex);
diff --git a/drivers/video/fbdev/msm/mdp3_ppp.c b/drivers/video/fbdev/msm/mdp3_ppp.c
index 3b72b2d..612cccc 100644
--- a/drivers/video/fbdev/msm/mdp3_ppp.c
+++ b/drivers/video/fbdev/msm/mdp3_ppp.c
@@ -20,8 +20,6 @@
 #include <linux/uaccess.h>
 #include <linux/sched.h>
 #include <linux/mutex.h>
-#include <linux/sync.h>
-#include <linux/sw_sync.h>
 #include "linux/proc_fs.h"
 #include <linux/delay.h>
 
@@ -30,6 +28,7 @@
 #include "mdp3_hwio.h"
 #include "mdp3.h"
 #include "mdss_debug.h"
+#include "mdss_sync.h"
 
 #define MDP_IS_IMGTYPE_BAD(x) ((x) >= MDP_IMGTYPE_LIMIT)
 #define MDP_RELEASE_BW_TIMEOUT 50
@@ -76,12 +75,12 @@
 	struct mdp_blit_req req_list[MAX_LIST_WINDOW];
 	struct mdp3_img_data src_data[MAX_LIST_WINDOW];
 	struct mdp3_img_data dst_data[MAX_LIST_WINDOW];
-	struct sync_fence *acq_fen[MDP_MAX_FENCE_FD];
+	struct mdss_fence *acq_fen[MDP_MAX_FENCE_FD];
 	u32 acq_fen_cnt;
 	int cur_rel_fen_fd;
 	struct sync_pt *cur_rel_sync_pt;
-	struct sync_fence *cur_rel_fence;
-	struct sync_fence *last_rel_fence;
+	struct mdss_fence *cur_rel_fence;
+	struct mdss_fence *last_rel_fence;
 };
 
 struct blit_req_queue {
@@ -104,7 +103,8 @@
 	struct task_struct *blit_thread;
 	struct blit_req_queue req_q;
 
-	struct sw_sync_timeline *timeline;
+	struct mdss_timeline *timeline;
+
 	int timeline_value;
 
 	struct timer_list free_bw_timer;
@@ -1188,19 +1188,19 @@
 	ATRACE_BEGIN(__func__);
 	/* buf sync */
 	for (i = 0; i < req->acq_fen_cnt; i++) {
-		ret = sync_fence_wait(req->acq_fen[i],
+		ret = mdss_wait_sync_fence(req->acq_fen[i],
 				WAIT_FENCE_FINAL_TIMEOUT);
 		if (ret < 0) {
 			pr_err("%s: sync_fence_wait failed! ret = %x\n",
 				__func__, ret);
 			break;
 		}
-		sync_fence_put(req->acq_fen[i]);
+		mdss_put_sync_fence(req->acq_fen[i]);
 	}
 	ATRACE_END(__func__);
 	if (ret < 0) {
 		while (i < req->acq_fen_cnt) {
-			sync_fence_put(req->acq_fen[i]);
+			mdss_put_sync_fence(req->acq_fen[i]);
 			i++;
 		}
 	}
@@ -1209,7 +1209,7 @@
 
 void mdp3_ppp_signal_timeline(struct blit_req_list *req)
 {
-	sw_sync_timeline_inc(ppp_stat->timeline, 1);
+	mdss_inc_timeline(ppp_stat->timeline, 1);
 	MDSS_XLOG(ppp_stat->timeline->value, ppp_stat->timeline_value);
 	req->last_rel_fence = req->cur_rel_fence;
 	req->cur_rel_fence = 0;
@@ -1221,12 +1221,12 @@
 	int i;
 
 	put_unused_fd(req->cur_rel_fen_fd);
-	sync_fence_put(req->cur_rel_fence);
+	mdss_put_sync_fence(req->cur_rel_fence);
 	req->cur_rel_fence = NULL;
 	req->cur_rel_fen_fd = 0;
 	ppp_stat->timeline_value--;
 	for (i = 0; i < req->acq_fen_cnt; i++)
-		sync_fence_put(req->acq_fen[i]);
+		mdss_put_sync_fence(req->acq_fen[i]);
 	req->acq_fen_cnt = 0;
 }
 
@@ -1235,7 +1235,7 @@
 {
 	int i, fence_cnt = 0, ret = 0;
 	int acq_fen_fd[MDP_MAX_FENCE_FD];
-	struct sync_fence *fence;
+	struct mdss_fence *fence;
 
 	if ((buf_sync->acq_fen_fd_cnt > MDP_MAX_FENCE_FD) ||
 		(ppp_stat->timeline == NULL))
@@ -1249,7 +1249,7 @@
 		return ret;
 	}
 	for (i = 0; i < buf_sync->acq_fen_fd_cnt; i++) {
-		fence = sync_fence_fdget(acq_fen_fd[i]);
+		fence = mdss_get_fd_sync_fence(acq_fen_fd[i]);
 		if (fence == NULL) {
 			pr_info("%s: null fence! i=%d fd=%d\n", __func__, i,
 				acq_fen_fd[i]);
@@ -1265,19 +1265,12 @@
 	if (buf_sync->flags & MDP_BUF_SYNC_FLAG_WAIT)
 		mdp3_ppp_wait_for_fence(req);
 
-	req->cur_rel_sync_pt = sw_sync_pt_create(ppp_stat->timeline,
-			ppp_stat->timeline_value++);
 	MDSS_XLOG(ppp_stat->timeline_value);
-	if (req->cur_rel_sync_pt == NULL) {
-		pr_err("%s: cannot create sync point\n", __func__);
-		ret = -ENOMEM;
-		goto buf_sync_err_2;
-	}
+
 	/* create fence */
-	req->cur_rel_fence = sync_fence_create("ppp-fence",
-			req->cur_rel_sync_pt);
+	req->cur_rel_fence = mdss_get_sync_fence(ppp_stat->timeline,
+				"ppp_fence", NULL, ppp_stat->timeline_value++);
 	if (req->cur_rel_fence == NULL) {
-		sync_pt_free(req->cur_rel_sync_pt);
 		req->cur_rel_sync_pt = NULL;
 		pr_err("%s: cannot create fence\n", __func__);
 		ret = -ENOMEM;
@@ -1289,7 +1282,7 @@
 	ppp_stat->timeline_value--;
 buf_sync_err_1:
 	for (i = 0; i < fence_cnt; i++)
-		sync_fence_put(req->acq_fen[i]);
+		mdss_put_sync_fence(req->acq_fen[i]);
 	req->acq_fen_cnt = 0;
 	return ret;
 }
@@ -1586,7 +1579,7 @@
 {
 	struct blit_req_list *req;
 	struct blit_req_queue *req_q = &ppp_stat->req_q;
-	struct sync_fence *fence = NULL;
+	struct mdss_fence *fence = NULL;
 	int count, rc, idx, i;
 
 	count = req_list_header->count;
@@ -1642,13 +1635,8 @@
 	}
 
 	if (async) {
-		req->cur_rel_fen_fd = get_unused_fd_flags(0);
-		if (req->cur_rel_fen_fd < 0) {
-			pr_err("%s: get_unused_fd_flags failed\n", __func__);
-			rc  = -ENOMEM;
-			goto parse_err_1;
-		}
-		sync_fence_install(req->cur_rel_fence, req->cur_rel_fen_fd);
+		req->cur_rel_fen_fd = mdss_get_sync_fence_fd(
+							req->cur_rel_fence);
 		rc = copy_to_user(req_list_header->sync.rel_fen_fd,
 			&req->cur_rel_fen_fd, sizeof(int));
 		if (rc) {
@@ -1664,12 +1652,12 @@
 	kthread_queue_work(&ppp_stat->kworker, &ppp_stat->blit_work);
 	if (!async) {
 		/* wait for release fence */
-		rc = sync_fence_wait(fence,
+		rc = mdss_wait_sync_fence(fence,
 				5 * MSEC_PER_SEC);
 		if (rc < 0)
 			pr_err("%s: sync blit! rc = %x\n", __func__, rc);
 
-		sync_fence_put(fence);
+		mdss_put_sync_fence(fence);
 		fence = NULL;
 	}
 	return 0;
@@ -1697,15 +1685,15 @@
 		return -ENOMEM;
 
 	/*Setup sync_pt timeline for ppp*/
-	ppp_stat->timeline = sw_sync_timeline_create(timeline_name);
+	ppp_stat->timeline = mdss_create_timeline(timeline_name);
 	if (ppp_stat->timeline == NULL) {
 		pr_err("%s: cannot create time line\n", __func__);
 		return -ENOMEM;
 	}
 	ppp_stat->timeline_value = 1;
 
-	init_kthread_worker(&ppp_stat->kworker);
-	init_kthread_work(&ppp_stat->blit_work, mdp3_ppp_blit_handler);
+	kthread_init_worker(&ppp_stat->kworker);
+	kthread_init_work(&ppp_stat->blit_work, mdp3_ppp_blit_handler);
 	ppp_stat->blit_thread = kthread_run(kthread_worker_fn,
 					&ppp_stat->kworker,
 					"mdp3_ppp");
diff --git a/drivers/video/fbdev/msm/mdp3_ppp_hwio.c b/drivers/video/fbdev/msm/mdp3_ppp_hwio.c
index 6f077e2..ec806cf 100644
--- a/drivers/video/fbdev/msm/mdp3_ppp_hwio.c
+++ b/drivers/video/fbdev/msm/mdp3_ppp_hwio.c
@@ -41,7 +41,7 @@
 	LAYER_MAX,
 };
 
-static long long mdp_do_div(long long num, long long den)
+static long long mdp_do_div(uint64_t num, uint64_t den)
 {
 	do_div(num, den);
 	return num;
diff --git a/drivers/video/fbdev/msm/mdss_debug_xlog.c b/drivers/video/fbdev/msm/mdss_debug_xlog.c
index 49684f4..a651b55 100644
--- a/drivers/video/fbdev/msm/mdss_debug_xlog.c
+++ b/drivers/video/fbdev/msm/mdss_debug_xlog.c
@@ -683,6 +683,11 @@
 
 	if (__mdss_xlog_dump_calc_range()) {
 		len = mdss_xlog_dump_entry(xlog_buf, MDSS_XLOG_BUF_MAX);
+		if (len < 0 || len > count) {
+			pr_err("len is more than the size of user buffer\n");
+			return 0;
+		}
+
 		if (copy_to_user(buff, xlog_buf, len))
 			return -EFAULT;
 		*ppos += len;
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index d70c1e8..6bb0960 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -743,7 +743,7 @@
 	if (blen < 0)
 		return 0;
 
-	if (copy_to_user(buf, buffer, blen))
+	if (copy_to_user(buf, buffer, min(count, (size_t)blen+1)))
 		return -EFAULT;
 
 	*ppos += blen;
diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c
index 25d70f00..27299d10 100644
--- a/drivers/video/fbdev/msm/mdss_fb.c
+++ b/drivers/video/fbdev/msm/mdss_fb.c
@@ -3221,7 +3221,6 @@
 	mfd->msm_fb_backup.info = *info;
 	mfd->msm_fb_backup.disp_commit = *disp_commit;
 
-	atomic_inc(&mfd->mdp_sync_pt_data.commit_cnt);
 	atomic_inc(&mfd->commits_pending);
 	atomic_inc(&mfd->kickoff_pending);
 	wake_up_all(&mfd->commit_wait_q);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index 5088117..344d6ef 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -76,13 +76,15 @@
 	u64 result = val;
 
 	if (val) {
-		u64 temp = -1UL;
+		u64 temp = U64_MAX;
 
 		do_div(temp, val);
 		if (temp > numer) {
 			/* no overflow, so we can do the operation*/
 			result = (val * (u64)numer);
 			do_div(result, denom);
+		} else {
+			pr_warn("Overflow, skip fudge factor\n");
 		}
 	}
 	return result;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
index 05f52a5..80708aa 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
@@ -2913,6 +2913,11 @@
 		}
 	}
 
+	if (!data) {
+		atomic_inc(&mfd->mdp_sync_pt_data.commit_cnt);
+		MDSS_XLOG(atomic_read(&mfd->mdp_sync_pt_data.commit_cnt));
+	}
+
 	/*
 	 * Setup pipe in solid fill before unstaging,
 	 * to ensure no fetches are happening after dettach or reattach.
diff --git a/drivers/video/fbdev/msm/mdss_sync.c b/drivers/video/fbdev/msm/mdss_sync.c
index 6308162..8fe9461 100644
--- a/drivers/video/fbdev/msm/mdss_sync.c
+++ b/drivers/video/fbdev/msm/mdss_sync.c
@@ -218,6 +218,7 @@
 	spin_lock(&tl->list_lock);
 	if (list_empty(&tl->fence_list_head)) {
 		pr_debug("fence list is empty\n");
+		tl->value += 1;
 		spin_unlock(&tl->list_lock);
 		return 0;
 	}
diff --git a/include/linux/ipc_logging.h b/include/linux/ipc_logging.h
index 780a82d..5bc8b6a 100644
--- a/include/linux/ipc_logging.h
+++ b/include/linux/ipc_logging.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 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
@@ -124,6 +124,13 @@
  */
 int ipc_log_string(void *ilctxt, const char *fmt, ...) __printf(2, 3);
 
+/*
+ * ipc_log_ctrl_all - disable/enable logging in all clients
+ *
+ * @ Data specified using format specifiers
+ */
+void ipc_log_ctrl_all(bool disable);
+
 /**
  * ipc_log_extract - Reads and deserializes log
  *
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 7c69d6c..629907a 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -279,6 +279,7 @@
 	POWER_SUPPLY_PROP_BATT_FULL_CURRENT,
 	POWER_SUPPLY_PROP_RECHARGE_SOC,
 	POWER_SUPPLY_PROP_TOGGLE_STAT,
+	POWER_SUPPLY_PROP_ALLOW_HVDCP3,
 	/* Local extensions of type int64_t */
 	POWER_SUPPLY_PROP_CHARGE_COUNTER_EXT,
 	/* Properties of type `const char *' */
diff --git a/include/linux/usb_bam.h b/include/linux/usb_bam.h
index e5d4c04..fc0647a 100644
--- a/include/linux/usb_bam.h
+++ b/include/linux/usb_bam.h
@@ -438,6 +438,7 @@
 bool msm_bam_hsic_lpm_ok(void);
 bool msm_bam_hsic_host_pipe_empty(void);
 bool msm_usb_bam_enable(enum usb_ctrl ctrl, bool bam_enable);
+int msm_do_bam_disable_enable(enum usb_ctrl ctrl);
 #else
 static inline int usb_bam_connect(enum usb_ctrl bam, u8 idx, u32 *bam_pipe_idx,
 							unsigned long iova)
@@ -543,6 +544,7 @@
 static inline bool msm_bam_hsic_host_pipe_empty(void) { return true; }
 static inline bool msm_usb_bam_enable(enum usb_ctrl ctrl, bool bam_enable)
 { return true; }
+int msm_do_bam_disable_enable(enum usb_ctrl ctrl) { return true; }
 
 #endif
 
diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h
index 47fb288..b37f8df 100644
--- a/include/linux/wcnss_wlan.h
+++ b/include/linux/wcnss_wlan.h
@@ -132,7 +132,6 @@
 bool wcnss_cbc_complete(void);
 int wcnss_device_is_shutdown(void);
 void wcnss_riva_dump_pmic_regs(void);
-void wcnss_free_regulator(void);
 int wcnss_xo_auto_detect_enabled(void);
 u32 wcnss_get_wlan_rx_buff_count(void);
 int wcnss_wlan_iris_xo_mode(void);
diff --git a/include/media/msmb_generic_buf_mgr.h b/include/media/msmb_generic_buf_mgr.h
index b3e1a02..95cfcad7 100644
--- a/include/media/msmb_generic_buf_mgr.h
+++ b/include/media/msmb_generic_buf_mgr.h
@@ -43,6 +43,8 @@
 #define VIDIOC_MSM_BUF_MNGR_FLUSH32 \
 	_IOWR('V', BASE_VIDIOC_PRIVATE + 39, struct msm_buf_mngr_info32_t)
 
+#define VIDIOC_MSM_BUF_MNGR_BUF_ERROR32 \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 41, struct msm_buf_mngr_info32_t)
 #endif
 
 #endif
diff --git a/include/media/radio-iris.h b/include/media/radio-iris.h
index 22888b0..aab92ad 100644
--- a/include/media/radio-iris.h
+++ b/include/media/radio-iris.h
@@ -34,6 +34,9 @@
 #include <linux/mutex.h>
 #include <linux/atomic.h>
 
+#define RDS_PS_SIMPLE_OFFSET 2
+extern struct mutex fm_smd_enable;
+
 struct radio_hci_dev {
 	char		name[8];
 	unsigned long	flags;
@@ -75,7 +78,7 @@
 };
 
 int radio_hci_register_dev(struct radio_hci_dev *hdev);
-int radio_hci_unregister_dev(struct radio_hci_dev *hdev);
+int radio_hci_unregister_dev(void);
 int radio_hci_recv_frame(struct sk_buff *skb);
 int radio_hci_send_cmd(struct radio_hci_dev *hdev, __u16 opcode, __u32 plen,
 	void *param);
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index 574ff2a..916f1dc 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -331,7 +331,8 @@
 				    struct v4l2_format *f);
 	int (*vidioc_g_fmt_sdr_out)(struct file *file, void *fh,
 				    struct v4l2_format *f);
-
+	int (*vidioc_g_fmt_type_private)(struct file *file, void *fh,
+					struct v4l2_format *f);
 	/* VIDIOC_S_FMT handlers */
 	int (*vidioc_s_fmt_vid_cap)(struct file *file, void *fh,
 				    struct v4l2_format *f);
diff --git a/include/soc/qcom/memory_dump.h b/include/soc/qcom/memory_dump.h
index 5bc50b5..a962a16 100644
--- a/include/soc/qcom/memory_dump.h
+++ b/include/soc/qcom/memory_dump.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012, 2014-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
@@ -87,7 +87,8 @@
 	MSM_DUMP_DATA_POWER_REGS = 0xED,
 	MSM_DUMP_DATA_TMC_ETF = 0xF0,
 	MSM_DUMP_DATA_TPDM_SWAO_MCMB = 0xF2,
-	MSM_DUMP_DATA_TMC_REG = 0x100,
+	MSM_DUMP_DATA_TMC_ETR_REG = 0x100,
+	MSM_DUMP_DATA_TMC_ETF_REG = 0x101,
 	MSM_DUMP_DATA_LOG_BUF = 0x110,
 	MSM_DUMP_DATA_LOG_BUF_FIRST_IDX = 0x111,
 	MSM_DUMP_DATA_SCANDUMP_PER_CPU = 0x130,
@@ -121,11 +122,22 @@
 	uint64_t addr;
 };
 
+struct dump_vaddr_entry {
+	uint32_t id;
+	void *dump_vaddr;
+	struct msm_dump_data *dump_data_vaddr;
+};
+
+struct msm_mem_dump_vaddr_tbl {
+	uint8_t num_node;
+	struct dump_vaddr_entry *entries;
+};
+
 #ifdef CONFIG_QCOM_MEMORY_DUMP_V2
 extern int msm_dump_data_register(enum msm_dump_table_ids id,
 				  struct msm_dump_entry *entry);
 
-extern void *get_msm_dump_ptr(enum msm_dump_data_ids id);
+extern struct dump_vaddr_entry *get_msm_dump_ptr(enum msm_dump_data_ids id);
 #else
 static inline int msm_dump_data_register(enum msm_dump_table_ids id,
 					 struct msm_dump_entry *entry)
diff --git a/include/soc/qcom/scm.h b/include/soc/qcom/scm.h
index 63698cf..fa64d5d 100644
--- a/include/soc/qcom/scm.h
+++ b/include/soc/qcom/scm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-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
@@ -100,6 +100,8 @@
 
 extern int scm_call2(u32 cmd_id, struct scm_desc *desc);
 
+extern int scm_call2_noretry(u32 cmd_id, struct scm_desc *desc);
+
 extern int scm_call2_atomic(u32 cmd_id, struct scm_desc *desc);
 
 extern int scm_call_noalloc(u32 svc_id, u32 cmd_id, const void *cmd_buf,
@@ -149,6 +151,11 @@
 	return 0;
 }
 
+static inline int scm_call2_noretry(u32 cmd_id, struct scm_desc *desc)
+{
+	return 0;
+}
+
 static inline int scm_call2_atomic(u32 cmd_id, struct scm_desc *desc)
 {
 	return 0;
diff --git a/include/trace/events/trace_msm_pil_event.h b/include/trace/events/trace_msm_pil_event.h
index 4795dc5..072bbbb 100644
--- a/include/trace/events/trace_msm_pil_event.h
+++ b/include/trace/events/trace_msm_pil_event.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017, 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
@@ -40,6 +40,7 @@
 		__get_str(fw_name))
 );
 
+#ifdef CONFIG_MSM_PIL
 TRACE_EVENT(pil_notif,
 
 	TP_PROTO(const char *event_name, unsigned long code,
@@ -64,6 +65,9 @@
 		__entry->code,
 		__get_str(fw_name))
 );
+#else
+#define trace_pil_notif(event_name, code, fw_name) do { } while (0)
+#endif
 
 TRACE_EVENT(pil_func,
 
diff --git a/include/uapi/media/msmb_generic_buf_mgr.h b/include/uapi/media/msmb_generic_buf_mgr.h
index 2961cae..8dad9ae 100644
--- a/include/uapi/media/msmb_generic_buf_mgr.h
+++ b/include/uapi/media/msmb_generic_buf_mgr.h
@@ -62,5 +62,7 @@
 	_IOWR('V', BASE_VIDIOC_PRIVATE + 40, \
 	struct msm_camera_private_ioctl_arg)
 
+#define VIDIOC_MSM_BUF_MNGR_BUF_ERROR \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 41, struct msm_buf_mngr_info)
 #endif
 
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
index 53974cc..895c63f 100644
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -246,7 +246,7 @@
 	if (unlikely(!sysctl_sched_use_walt_cpu_util))
 		return;
 
-	WARN_ON(curr_ws < last_ws);
+	BUG_ON(curr_ws < last_ws);
 	if (curr_ws <= last_ws)
 		return;
 
diff --git a/kernel/trace/ipc_logging.c b/kernel/trace/ipc_logging.c
index ec9bde7..68a9ad7 100644
--- a/kernel/trace/ipc_logging.c
+++ b/kernel/trace/ipc_logging.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -295,6 +295,8 @@
 		return;
 	}
 
+	if (ilctxt->disabled)
+		return;
 	read_lock_irqsave(&context_list_lock_lha1, flags);
 	spin_lock(&ilctxt->context_lock_lhb1);
 	while (ilctxt->write_avail <= ectxt->offset)
@@ -508,11 +510,14 @@
 {
 	struct encode_context ectxt;
 	int avail_size, data_size, hdr_size = sizeof(struct tsv_header);
+	struct ipc_log_context *ctxt = (struct ipc_log_context *)ilctxt;
 	va_list arg_list;
 
 	if (!ilctxt)
 		return -EINVAL;
 
+	if (ctxt->disabled)
+		return -EBUSY;
 	msg_encode_start(&ectxt, TSV_TYPE_STRING);
 	tsv_timestamp_write(&ectxt);
 	tsv_qtimer_write(&ectxt);
@@ -529,6 +534,32 @@
 }
 EXPORT_SYMBOL(ipc_log_string);
 
+/*
+ * ipc_log_ctrl_all - disable/enable logging in all clients
+ *
+ * @ Data specified using format specifiers
+ */
+void ipc_log_ctrl_all(bool disable)
+{
+	struct ipc_log_context *ctxt = NULL;
+	unsigned long flags;
+
+	read_lock_irqsave(&context_list_lock_lha1, flags);
+	list_for_each_entry(ctxt, &ipc_log_context_list, list) {
+		if (disable) {
+			ipc_log_string(ctxt,
+				"LOGGING DISABLED FOR ALL CLIENTS!!\n");
+			ctxt->disabled = disable;
+		} else {
+			ctxt->disabled = disable;
+			ipc_log_string(ctxt,
+				"LOGGING ENABLED FOR ALL CLIENTS!!\n");
+		}
+	}
+	read_unlock_irqrestore(&context_list_lock_lha1, flags);
+}
+EXPORT_SYMBOL(ipc_log_ctrl_all);
+
 /**
  * ipc_log_extract - Reads and deserializes log
  *
diff --git a/kernel/trace/ipc_logging_debug.c b/kernel/trace/ipc_logging_debug.c
index d733724..7a4c630 100644
--- a/kernel/trace/ipc_logging_debug.c
+++ b/kernel/trace/ipc_logging_debug.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015,2017-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
@@ -113,6 +113,83 @@
 	return bsize;
 }
 
+static ssize_t debug_write_ctrl(struct file *file, const char __user *buff,
+				 size_t count, loff_t *ppos)
+{
+	struct ipc_log_context *ilctxt;
+	struct dentry *d = file->f_path.dentry;
+	int bsize = 1;
+	int srcu_idx;
+	int r;
+	char local_buf[3];
+
+	r = debugfs_use_file_start(d, &srcu_idx);
+	if (!r) {
+		ilctxt = file->private_data;
+		r = kref_get_unless_zero(&ilctxt->refcount) ? 0 : -EIO;
+	}
+	debugfs_use_file_finish(srcu_idx);
+	if (r)
+		return r;
+
+	if (copy_from_user(local_buf, buff, bsize)) {
+		count = -EFAULT;
+		goto done;
+	}
+
+	if (*local_buf == '1') {
+		ipc_log_string(ilctxt, "LOGGING DISABLED FOR THIS CLIENT!!\n");
+		ilctxt->disabled = true;
+	} else if (*local_buf == '0') {
+		ilctxt->disabled = false;
+		ipc_log_string(ilctxt, "LOGGING ENABLED FOR THIS CLIENT!!\n");
+	}
+
+done:
+	ipc_log_context_put(ilctxt);
+	return count;
+}
+
+
+static ssize_t debug_write_ctrl_all(struct file *file, const char __user *buff,
+				 size_t count, loff_t *ppos)
+{
+	int bsize = 1;
+	char local_buf[3];
+
+	if (copy_from_user(local_buf, buff, bsize))
+		return -EFAULT;
+	if (*local_buf == '1')
+		ipc_log_ctrl_all(true);
+	else if (*local_buf == '0')
+		ipc_log_ctrl_all(false);
+	return count;
+}
+
+static ssize_t debug_read_ctrl(struct file *file, char __user *buff,
+				 size_t count, loff_t *ppos)
+{
+	struct ipc_log_context *ilctxt;
+	struct dentry *d = file->f_path.dentry;
+	int bsize = 2;
+	int srcu_idx;
+	int r;
+
+	r = debugfs_use_file_start(d, &srcu_idx);
+	if (!r) {
+		ilctxt = file->private_data;
+		r = kref_get_unless_zero(&ilctxt->refcount) ? 0 : -EIO;
+	}
+	debugfs_use_file_finish(srcu_idx);
+	if (r)
+		return r;
+
+	bsize = simple_read_from_buffer(buff, count, ppos,
+				ilctxt->disabled?"1\n":"0\n", bsize);
+	ipc_log_context_put(ilctxt);
+	return bsize;
+}
+
 static ssize_t debug_read(struct file *file, char __user *buff,
 			  size_t count, loff_t *ppos)
 {
@@ -141,6 +218,16 @@
 	.open = debug_open,
 };
 
+static const struct file_operations debug_ops_ctrl = {
+	.read = debug_read_ctrl,
+	.write = debug_write_ctrl,
+	.open = debug_open,
+};
+
+static const struct file_operations debug_ops_ctrl_all = {
+	.write = debug_write_ctrl_all,
+};
+
 static void debug_create(const char *name, mode_t mode,
 			 struct dentry *dent,
 			 struct ipc_log_context *ilctxt,
@@ -176,6 +263,9 @@
 			pr_err("%s: unable to create debugfs %ld\n",
 				__func__, PTR_ERR(root_dent));
 			root_dent = NULL;
+		} else {
+			debug_create("ctrl_all", 0444, root_dent,
+				NULL, &debug_ops_ctrl_all);
 		}
 	}
 	mutex_unlock(&ipc_log_debugfs_init_lock);
@@ -195,6 +285,8 @@
 				     ctxt, &debug_ops);
 			debug_create("log_cont", 0444, ctxt->dent,
 				     ctxt, &debug_ops_cont);
+			debug_create("log_disable", 0444, ctxt->dent,
+				     ctxt, &debug_ops_ctrl);
 		}
 	}
 	add_deserialization_func((void *)ctxt,
diff --git a/kernel/trace/ipc_logging_private.h b/kernel/trace/ipc_logging_private.h
index 47c41e9..bb91dce 100644
--- a/kernel/trace/ipc_logging_private.h
+++ b/kernel/trace/ipc_logging_private.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -121,6 +121,7 @@
 	struct completion read_avail;
 	struct kref refcount;
 	bool destroyed;
+	bool disabled;
 };
 
 struct dfunc_info {
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 9b59170..1d4429d 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -1589,8 +1589,7 @@
 }
 
 /*
- * Stop the automatic memory scanning thread. This function must be called
- * with the scan_mutex held.
+ * Stop the automatic memory scanning thread.
  */
 static void stop_scan_thread(void)
 {
@@ -1853,12 +1852,15 @@
 {
 	stop_scan_thread();
 
+	mutex_lock(&scan_mutex);
 	/*
-	 * Once the scan thread has stopped, it is safe to no longer track
-	 * object freeing. Ordering of the scan thread stopping and the memory
-	 * accesses below is guaranteed by the kthread_stop() function.
+	 * Once it is made sure that kmemleak_scan has stopped, it is safe to no
+	 * longer track object freeing. Ordering of the scan thread stopping and
+	 * the memory accesses below is guaranteed by the kthread_stop()
+	 * function.
 	 */
 	kmemleak_free_enabled = 0;
+	mutex_unlock(&scan_mutex);
 
 	if (!kmemleak_found_leaks)
 		__kmemleak_do_cleanup();
diff --git a/net/wireless/db.txt b/net/wireless/db.txt
index 7fe91b1..eb4cc00 100644
--- a/net/wireless/db.txt
+++ b/net/wireless/db.txt
@@ -1202,9 +1202,12 @@
 	# 60 gHz band channels 1-3, FCC
 	(57240 - 63720 @ 2160), (40)
 
-country QA:
+country QA: DFS-ETSI
 	(2402 - 2482 @ 40), (20)
-	(5735 - 5835 @ 80), (30)
+	(5170 - 5250 @ 80), (23), AUTO-BW
+	(5250 - 5330 @ 80), (23), DFS, AUTO-BW
+	(5490 - 5730 @ 80), (20), DFS
+	(5735 - 5875 @ 80), (20)
 
 country RE: DFS-ETSI
 	(2402 - 2482 @ 40), (20)