Merge "ANDROID: sched/fair: Fix incorrect usage of RCU in CPU select path"
diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt
index 90bc368..c4ada7c 100644
--- a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.txt
@@ -86,7 +86,8 @@
 
 compatible devices:
 		qcom,sdm845-llcc,
-		qcom,sdm670-llcc
+		qcom,sdm670-llcc,
+		qcom,qcs605-llcc
 
 Example:
 
diff --git a/Documentation/devicetree/bindings/input/touchscreen/himax.txt b/Documentation/devicetree/bindings/input/touchscreen/himax.txt
deleted file mode 100644
index b54c859..0000000
--- a/Documentation/devicetree/bindings/input/touchscreen/himax.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Himax touch controller
-
-Required properties:
-
- - compatible			: Should be "himax,hxcommon"
- - reg					: i2c slave address of the device.
- - interrupt-parent		: parent of interrupt.
- - himax,irq-gpio       : irq gpio.
- - himax,reset-gpio		: reset gpio.
- - vdd-supply			: Power supply needed to power up the device.
- - avdd-supply			: Power source required to power up i2c bus.
- - himax,panel-coords 	: panel coordinates for the chip in pixels.
-						  It is a four tuple consisting of min x,
-						  min y, max x and max y values.
- - himax,display-coords : display coordinates in pixels. It is a four
-						  tuple consisting of min x, min y, max x and
-						  max y values
-
-Optional properties:
- - himax,3v3-gpio		: gpio acting as 3.3 v supply.
- - report_type			: Multi-touch protocol type. Default 0.
-						  0 for protocol A, 1 for protocol B.
diff --git a/Documentation/devicetree/bindings/input/touchscreen/himax_i2c_ts.txt b/Documentation/devicetree/bindings/input/touchscreen/himax_i2c_ts.txt
new file mode 100644
index 0000000..9889f55
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/himax_i2c_ts.txt
@@ -0,0 +1,57 @@
+Himax touch controller
+
+Required properties:
+
+ - compatible	: should be "himax,hxcommon"
+ - reg			: i2c slave address of the device
+ - interrupt-parent	: parent of interrupt
+ - interrupts		: touch sample interrupt to indicate presense or release
+				of fingers on the panel.
+ - himax,irq-gpio	: irq gpio
+ - himax,reset-gpio	: reset gpio
+
+Optional property:
+ - vdd-supply		: Analog power supply needed to power device
+ - vcc_i2c-supply		: Power source required to pull up i2c bus
+ - himax,i2c-pull-up	: specify to indicate pull up is needed
+ - himax,disable-gpios	: specify to disable gpios in suspend (power saving)
+ - himax,button-map		: virtual key code mappings to be used
+ - himax,x-flip		: modify orientation of the x axis
+ - himax,y-flip		: modify orientation of the y axis
+ - himax,panel-coords	: touch panel min x, min y, max x and
+					max y resolution
+ - himax,display-coords	: display min x, min y, max x and
+					max y resolution
+ - himax,reset-delay	: reset delay for controller (ms), default 100
+ - himax,fw-image-name	: name of firmware .img file in /etc/firmware
+ - himax,power-down		: fully power down regulators in suspend
+ - himax,do-lockdown	: perform one time lockdown procedure
+
+Example:
+	i2c@f9927000 { /* BLSP1 QUP5 */
+		cell-index = <5>;
+		compatible = "himax,hxcommon";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg-names = "qup_phys_addr";
+		reg = <0xf9927000 0x1000>;
+		interrupt-names = "qup_err_intr";
+		interrupts = <0 99 0>;
+		gpios = <&msmgpio 19 0>, /* SCL */
+			<&msmgpio 18 0>; /* SDA */
+		qcom,i2c-bus-freq = <100000>;
+		qcom,i2c-src-freq = <19200000>;
+
+		himax_ts@20 {
+			compatible = "himax,hxcommon"
+			reg = <0x20>;
+			interrupt-parent = <&tlmm>;
+			interrupts	= <255 0x2008>;
+			vdd-supply 	= <&pm8994_l15>;
+			avdd-supply = <&pm8994_l22>;
+			himax,panel-coords = <0 720 0 1440>;
+			himax,display-coords = <0 720 0 1440>;
+			himax,irq-gpio = <&tlmm 255 0x2008>;
+			himax,rst-gpio = <&tlmm 8 0x00>;
+		};
+	};
diff --git a/Documentation/devicetree/bindings/net/dsa/b53.txt b/Documentation/devicetree/bindings/net/dsa/b53.txt
index d6c6e41..6192f02 100644
--- a/Documentation/devicetree/bindings/net/dsa/b53.txt
+++ b/Documentation/devicetree/bindings/net/dsa/b53.txt
@@ -10,6 +10,7 @@
       "brcm,bcm53128"
       "brcm,bcm5365"
       "brcm,bcm5395"
+      "brcm,bcm5389"
       "brcm,bcm5397"
       "brcm,bcm5398"
 
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index 20cb25b..6c9d8253 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -3290,3 +3290,97 @@
 		qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight",
 					"SpkrLeft", "SpkrRight";
 	}
+
+* QCS605 IPcamera  ASoC Machine driver
+
+Required properties:
+- compatible : "qcom,qcs605-asoc-snd-tavil"
+- qcom,model : The user-visible name of this sound card.
+- qcom,audio-routing : A list of the connections between audio components.
+- qcom,msm-gpios : Lists down all the gpio sets that are supported.
+- qcom,pinctrl-names : Lists all the possible combinations of the gpio sets
+mentioned in qcom,msm-gpios.
+- pinctrl-names : The combinations of gpio sets from above that are supported in
+the flavor.
+- pinctrl-# : Pinctrl states as mentioned in pinctrl-names.
+
+Optional properties:
+- qcom,wsa-disable : Boolean. Disables WSA speaker dailinks from sound node.
+- qcom,msm-spk-ext-pa : GPIO which enables external speaker pa.
+- qcom,msm-mclk-freq : This property is used to inform machine driver about
+mclk frequency needs to be configured for internal and external PA.
+- asoc-platform: This is phandle list containing the references to platform device
+		 nodes that are used as part of the sound card dai-links.
+- asoc-platform-names: This property contains list of platform names. The order of
+		       the platform names should match to that of the phandle order
+		       given in "asoc-platform".
+- asoc-cpu: This is phandle list containing the references to cpu dai device nodes
+	    that are used as part of the sound card dai-links.
+- asoc-cpu-names: This property contains list of cpu dai names. The order of the
+		  cpu dai names should match to that of the phandle order given.
+- asoc-codec: This is phandle list containing the references to codec dai device
+	nodes that are used as part of the sound card dai-links.
+- asoc-codec-names: This property contains list of codec dai names. The order of the
+	codec dai names should match to that of the phandle order given
+	in "asoc-codec".
+- qcom,wsa-max-devs : Maximum number of WSA881x devices present in the target
+- qcom,wsa-devs : List of phandles for all possible WSA881x devices supported for the target
+- qcom,wsa-aux-dev-prefix : Name prefix with Left/Right configuration for WSA881x device
+- qcom,cdc-dmic-gpios : phandle for Digital mic clk and data gpios.
+- qcom,cdc-sdw-gpios : phandle for soundwire clk and data gpios.
+- qcom,pri-mi2s-gpios : phandle for primary MI2S clk, word select and data gpios.
+- qcom,sec-mi2s-gpios : phandle for secondary MI2S clk, word select and data gpios.
+- qcom,tert-mi2s-gpios : phandle for tertiary MI2S clk, word select and data gpios.
+- qcom,quat-mi2s-gpios : phandle for quaternary MI2S clk, word select and data gpios.
+- qcom,quin-mi2s-gpios : phandle for quinary MI2S clk, word select and data gpios.
+
+Example:
+	 sound {
+		compatible = "qcom,qcs605-asoc-snd-tavil";
+		qcom,model = "qcs605-tavil-snd-card";
+		qcom,audio-routing =
+			"RX_BIAS", "INT_MCLK0",
+			"SPK_RX_BIAS", "INT_MCLK0",
+			"DMIC1", "DIGITAL_REGULATOR",
+			"DIGITAL_REGULATOR", "Digital Mic1",
+			"DMIC2", "DIGITAL_REGULATOR",
+			"DIGITAL_REGULATOR", "Digital Mic2",
+			"DMIC3", "DIGITAL_REGULATOR",
+			"DIGITAL_REGULATOR", "Digital Mic3",
+			"DMIC4", "DIGITAL_REGULATOR",
+			"DIGITAL_REGULATOR", "Digital Mic4",
+			"SpkrLeft IN", "SPK1 OUT",
+			"SpkrRight IN", "SPK2 OUT";
+
+		qcom,msm-mi2s-master = <1>, <1>, <1>, <1>, <1>;
+		qcom,msm-mclk-freq = <9600000>;
+		qcom,msm-gpios =
+			"slim",
+			"us_eu_gpio";
+		qcom,pinctrl-names =
+			"all_off",
+			"slim_act",
+			"us_eu_gpio_act",
+			"slim_us_eu_gpio_act";
+		pinctrl-names =
+			"all_off",
+			"slim_act",
+			"us_eu_gpio_act",
+			"slim_us_eu_gpio_act";
+		pinctrl-0 = <&cdc_slim_lines_sus &cross_conn_det_sus>;
+		pinctrl-1 = <&cdc_slim_lines_act &cross_conn_det_sus>;
+		pinctrl-2 = <&cdc_slim_lines_sus &cross_conn_det_act>;
+		pinctrl-3 = <&cdc_slim_lines_act &cross_conn_det_act>;
+		qcom,cdc-dmic-gpios = <&cdc_dmic_gpios>;
+
+		asoc-codec = <&stub_codec>, <&msm_digital_codec>,
+				<&msm_sdw_codec>;
+		asoc-codec-names = "msm-stub-codec.1", "msm-dig-codec",
+					"msm_sdw_codec";
+
+		qcom,wsa-max-devs = <2>;
+		qcom,wsa-devs = <&wsa881x_211_en>, <&wsa881x_212_en>,
+				<&wsa881x_213_en>, <&wsa881x_214_en>;
+		qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight",
+					"SpkrLeft", "SpkrRight";
+	}
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index a22edb5..ed51a77 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -123,13 +123,13 @@
 hannstar	HannStar Display Corporation
 haoyu	Haoyu Microelectronic Co. Ltd.
 hardkernel	Hardkernel Co., Ltd
-himax	Himax Technologies, Inc.
 hisilicon	Hisilicon Limited.
 hit	Hitachi Ltd.
 hitex	Hitex Development Tools
 holt	Holt Integrated Circuits, Inc.
 honeywell	Honeywell
 hp	Hewlett Packard
+himax   Himax Coroporation
 i2se	I2SE GmbH
 ibm	International Business Machines (IBM)
 idt	Integrated Device Technologies, Inc.
diff --git a/Documentation/networking/netdev-FAQ.txt b/Documentation/networking/netdev-FAQ.txt
index a20b2fa..56af008 100644
--- a/Documentation/networking/netdev-FAQ.txt
+++ b/Documentation/networking/netdev-FAQ.txt
@@ -168,6 +168,15 @@
    dash marker line as described in Documentation/SubmittingPatches to
    temporarily embed that information into the patch that you send.
 
+Q: Are all networking bug fixes backported to all stable releases?
+
+A: Due to capacity, Dave could only take care of the backports for the last
+   2 stable releases. For earlier stable releases, each stable branch maintainer
+   is supposed to take care of them. If you find any patch is missing from an
+   earlier stable branch, please notify stable@vger.kernel.org with either a
+   commit ID or a formal patch backported, and CC Dave and other relevant
+   networking developers.
+
 Q: Someone said that the comment style and coding convention is different
    for the networking content.  Is this true?
 
diff --git a/Makefile b/Makefile
index 6fac39b..505a816 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 9
-SUBLEVEL = 106
+SUBLEVEL = 110
 EXTRAVERSION =
 NAME = Roaring Lionus
 
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 54e93a0..04b90d3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1412,6 +1412,16 @@
 	help
 	  This options enables support for the ARM timer and watchdog unit
 
+config ARCH_MSM8953_SOC_SETTINGS
+	bool "Enable MSM8953 SOC settings"
+	depends on ARCH_MSM8953
+	help
+	  Enable MSM8953 SOC related settings, these generic MSM8953
+	  related settings are required for some of CPUSS sub-system
+	  functionality.
+
+	  If you are not sure what to do, select 'N' here.
+
 config MCPM
 	bool "Multi-Cluster Power Management"
 	depends on CPU_V7 && SMP
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dts
index 99e3faa..eb28282 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dts
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dts
@@ -22,3 +22,7 @@
 		"qcom,sdxpoorwills", "qcom,cdp";
 	qcom,board-id = <1 0x102>;
 };
+
+&blsp1_uart2b_hs {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dtsi
index 8c506b9..c836f94 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dtsi
@@ -141,3 +141,11 @@
 	extcon = <&smb1381_charger>;
 	vbus_dwc3-supply = <&smb138x_vbus>;
 };
+
+&soc {
+	bluetooth: bt_qca6174 {
+		compatible = "qca,qca6174";
+		qca,bt-reset-gpio = <&pmxpoorwills_gpios 4 0>; /* BT_EN */
+		qca,bt-vdd-pa-supply = <&vreg_wlan>;
+	};
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-cdp.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-cdp.dtsi
index 16f933f..d447724 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-cdp.dtsi
@@ -36,11 +36,3 @@
 	/delete-property/ qcom,devfreq,freq-table;
 	/delete-property/ cd-gpios;
 };
-
-&soc {
-	bluetooth: bt_qca6174 {
-		compatible = "qca,qca6174";
-		qca,bt-reset-gpio = <&pmxpoorwills_gpios 4 0>; /* BT_EN */
-		qca,bt-vdd-pa-supply = <&vreg_wlan>;
-	};
-};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-mtp.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-mtp.dtsi
index 252fb04..b60225a 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-dualwifi-mtp.dtsi
@@ -36,11 +36,3 @@
 	/delete-property/ qcom,devfreq,freq-table;
 	/delete-property/ cd-gpios;
 };
-
-&soc {
-	bluetooth: bt_qca6174 {
-		compatible = "qca,qca6174";
-		qca,bt-reset-gpio = <&pmxpoorwills_gpios 4 0>; /* BT_EN */
-		qca,bt-vdd-pa-supply = <&vreg_wlan>;
-	};
-};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts
index 3ae5b2c..a383f3e 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts
@@ -24,3 +24,7 @@
 &qcom_seecom {
 	status = "okay";
 };
+
+&blsp1_uart2b_hs {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dtsi
index ef1150a..a6d2463 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dtsi
@@ -141,3 +141,11 @@
 	extcon = <&smb1381_charger>;
 	vbus_dwc3-supply = <&smb138x_vbus>;
 };
+
+&soc {
+	bluetooth: bt_qca6174 {
+		compatible = "qca,qca6174";
+		qca,bt-reset-gpio = <&pmxpoorwills_gpios 4 0>; /* BT_EN */
+		qca,bt-vdd-pa-supply = <&vreg_wlan>;
+	};
+};
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
index cbbf585..d23275e 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dts
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp-256.dts
@@ -20,3 +20,7 @@
 		"qcom,sdxpoorwills", "qcom,cdp";
 	qcom,board-id = <1 0x1>;
 };
+
+&blsp1_uart2b_hs {
+	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 2a2e496..521d948 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dts
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-cdp.dts
@@ -21,3 +21,6 @@
 	qcom,board-id = <1 0x106>;
 };
 
+&blsp1_uart2b_hs {
+	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
index 6b6aab5..236ce73 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dts
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp-256.dts
@@ -20,3 +20,7 @@
 		"qcom,sdxpoorwills", "qcom,mtp";
 	qcom,board-id = <8 0x1>;
 };
+
+&blsp1_uart2b_hs {
+	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 8c22348..11c4e62 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp.dts
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie-ep-mtp.dts
@@ -20,3 +20,7 @@
 		"qcom,sdxpoorwills", "qcom,mtp";
 	qcom,board-id = <8 0x105>;
 };
+
+&blsp1_uart2b_hs {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie.dtsi
index e939bd2..1907209 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-pcie.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pcie.dtsi
@@ -143,6 +143,26 @@
 
 		qcom,cpl-timeout = <0x2>;
 
+		qcom,smmu-sid-base = <0x00A0>;
+
+		iommu-map = <0x0 &apps_smmu 0x00A0 0x1>,
+			<0x100 &apps_smmu 0x00A1 0x1>,
+			<0x200 &apps_smmu 0x00A2 0x1>,
+			<0x300 &apps_smmu 0x00A3 0x1>,
+			<0x400 &apps_smmu 0x00A4 0x1>,
+			<0x500 &apps_smmu 0x00A5 0x1>,
+			<0x600 &apps_smmu 0x00A6 0x1>,
+			<0x700 &apps_smmu 0x00A7 0x1>,
+			<0x800 &apps_smmu 0x00A8 0x1>,
+			<0x900 &apps_smmu 0x00A9 0x1>,
+			<0xa00 &apps_smmu 0x00AA 0x1>,
+			<0xb00 &apps_smmu 0x00AB 0x1>,
+			<0xc00 &apps_smmu 0x00AC 0x1>,
+			<0xd00 &apps_smmu 0x00AD 0x1>,
+			<0xe00 &apps_smmu 0x00AE 0x1>,
+			<0xf00 &apps_smmu 0x00AF 0x1>;
+
+
 		qcom,boot-option = <0x1>;
 
 		linux,pci-domain = <0>;
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-ttp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-ttp.dts
index 775be96..f0363c0 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-ttp.dts
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-ttp.dts
@@ -20,3 +20,7 @@
 		"qcom,sdxpoorwills", "qcom,ttp";
 	qcom,board-id = <30 0x100>;
 };
+
+&blsp1_uart2b_hs {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index ef001fb..b6a4362 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -1288,6 +1288,9 @@
 				<45 512 98572 655360>, <1 512 98572 1600000>,
 				/* Upto 800 Mbps */
 				<45 512 207108 1146880>, <1 512 207108 3124992>;
+
+		qcom,wlan-smmu-iova-address = <0x10000000 0x10000000>;
+		qcom,wlan-smmu-iova-ipa = <0x20000000 0x10000>;
 	};
 
 	cnss_sdio: qcom,cnss_sdio {
@@ -1343,9 +1346,9 @@
 		qcom,msm-bus,num-paths = <2>;
 		qcom,msm-bus,vectors-KBps =
 			<98 512 0 0>, <1 781 0 0>,  /* No vote */
-			<98 512 1250 0>, <1 781 0 40000>,  /* 10Mbps vote */
-			<98 512 12500 0>, <1 781 0 40000>,  /* 100Mbps vote */
-			<98 512 125000 0>, <1 781 0 40000>; /* 1000Mbps vote */
+			<98 512 2500 0>, <1 781 0 40000>,  /* 10Mbps vote */
+			<98 512 25000 0>, <1 781 0 40000>,  /* 100Mbps vote */
+			<98 512 250000 0>, <1 781 0 40000>; /* 1000Mbps vote */
 		qcom,bus-vector-names = "0", "10", "100", "1000";
 		clocks = <&clock_gcc GCC_ETH_AXI_CLK>,
 			<&clock_gcc GCC_ETH_PTP_CLK>,
diff --git a/arch/arm/configs/msm8909-perf_defconfig b/arch/arm/configs/msm8909-perf_defconfig
index d907a0d..5f655b4 100644
--- a/arch/arm/configs/msm8909-perf_defconfig
+++ b/arch/arm/configs/msm8909-perf_defconfig
@@ -63,6 +63,7 @@
 CONFIG_CPU_IDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
+CONFIG_KERNEL_MODE_NEON=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_PM_AUTOSLEEP=y
 CONFIG_PM_WAKELOCKS=y
@@ -230,6 +231,7 @@
 CONFIG_DM_CRYPT=y
 CONFIG_DM_UEVENT=y
 CONFIG_DM_VERITY=y
+CONFIG_DM_VERITY_FEC=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
 CONFIG_TUN=y
@@ -470,4 +472,9 @@
 CONFIG_CRYPTO_DEV_QCEDEV=y
 CONFIG_CRYPTO_DEV_OTA_CRYPTO=y
 CONFIG_CRYPTO_DEV_QCOM_ICE=y
+CONFIG_ARM_CRYPTO=y
+CONFIG_CRYPTO_SHA1_ARM_NEON=y
+CONFIG_CRYPTO_SHA2_ARM_CE=y
+CONFIG_CRYPTO_AES_ARM_BS=y
+CONFIG_CRYPTO_AES_ARM_CE=y
 CONFIG_QMI_ENCDEC=y
diff --git a/arch/arm/configs/msm8937-perf_defconfig b/arch/arm/configs/msm8937-perf_defconfig
index 3747ca3..040ce14 100644
--- a/arch/arm/configs/msm8937-perf_defconfig
+++ b/arch/arm/configs/msm8937-perf_defconfig
@@ -585,6 +585,7 @@
 CONFIG_PWM=y
 CONFIG_PWM_QPNP=y
 CONFIG_PWM_QTI_LPG=y
+CONFIG_QCOM_SHOW_RESUME_IRQ=y
 CONFIG_QTI_MPM=y
 CONFIG_ANDROID=y
 CONFIG_ANDROID_BINDER_IPC=y
diff --git a/arch/arm/configs/msm8953-perf_defconfig b/arch/arm/configs/msm8953-perf_defconfig
index fca07a10..ed7bee7 100644
--- a/arch/arm/configs/msm8953-perf_defconfig
+++ b/arch/arm/configs/msm8953-perf_defconfig
@@ -303,6 +303,7 @@
 # CONFIG_WLAN_VENDOR_ZYDAS is not set
 CONFIG_WCNSS_MEM_PRE_ALLOC=y
 CONFIG_CLD_LL_CORE=y
+CONFIG_QCA402X=y
 CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
@@ -310,6 +311,9 @@
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_FT5X06=y
 CONFIG_TOUCHSCREEN_GEN_VKEYS=y
+CONFIG_TOUCHSCREEN_GT9XX_v28=y
+CONFIG_TOUCHSCREEN_GT9XX_UPDATE=y
+CONFIG_TOUCHSCREEN_GT9XX_TOOL=y
 CONFIG_TOUCHSCREEN_HIMAX_CHIPSET=y
 CONFIG_TOUCHSCREEN_HIMAX_I2C=y
 CONFIG_TOUCHSCREEN_HIMAX_DEBUG=y
@@ -504,6 +508,7 @@
 CONFIG_MMC_PERF_PROFILING=y
 # CONFIG_PWRSEQ_EMMC is not set
 # CONFIG_PWRSEQ_SIMPLE is not set
+CONFIG_MMC_EMBEDDED_SDIO=y
 CONFIG_MMC_PARANOID_SD_INIT=y
 CONFIG_MMC_CLKGATE=y
 CONFIG_MMC_BLOCK_MINORS=32
diff --git a/arch/arm/configs/msm8953_defconfig b/arch/arm/configs/msm8953_defconfig
index 690faf2..30f8d48 100644
--- a/arch/arm/configs/msm8953_defconfig
+++ b/arch/arm/configs/msm8953_defconfig
@@ -308,6 +308,7 @@
 # CONFIG_WLAN_VENDOR_ZYDAS is not set
 CONFIG_WCNSS_MEM_PRE_ALLOC=y
 CONFIG_CLD_LL_CORE=y
+CONFIG_QCA402X=y
 CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
@@ -315,6 +316,9 @@
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_FT5X06=y
 CONFIG_TOUCHSCREEN_GEN_VKEYS=y
+CONFIG_TOUCHSCREEN_GT9XX_v28=y
+CONFIG_TOUCHSCREEN_GT9XX_UPDATE=y
+CONFIG_TOUCHSCREEN_GT9XX_TOOL=y
 CONFIG_TOUCHSCREEN_HIMAX_CHIPSET=y
 CONFIG_TOUCHSCREEN_HIMAX_I2C=y
 CONFIG_TOUCHSCREEN_HIMAX_DEBUG=y
@@ -513,6 +517,7 @@
 # CONFIG_PWRSEQ_EMMC is not set
 # CONFIG_PWRSEQ_SIMPLE is not set
 CONFIG_MMC_RING_BUFFER=y
+CONFIG_MMC_EMBEDDED_SDIO=y
 CONFIG_MMC_PARANOID_SD_INIT=y
 CONFIG_MMC_CLKGATE=y
 CONFIG_MMC_BLOCK_MINORS=32
diff --git a/arch/arm/configs/sdm670_defconfig b/arch/arm/configs/sdm670_defconfig
index 2fda0e2..082a53a 100644
--- a/arch/arm/configs/sdm670_defconfig
+++ b/arch/arm/configs/sdm670_defconfig
@@ -63,6 +63,8 @@
 CONFIG_ARM_PSCI=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_ARM_MODULE_PLTS=y
 CONFIG_CLEANCACHE=y
 CONFIG_CMA=y
 CONFIG_CMA_DEBUGFS=y
@@ -236,6 +238,7 @@
 CONFIG_IPC_ROUTER=y
 CONFIG_IPC_ROUTER_SECURITY=y
 CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
+CONFIG_AQT_REGMAP=y
 CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y
 CONFIG_DMA_CMA=y
 CONFIG_ZRAM=y
@@ -312,6 +315,9 @@
 CONFIG_PINCTRL_SDM670=y
 CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
 CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_QCOM=y
+CONFIG_QCOM_DLOAD_MODE=y
 CONFIG_POWER_SUPPLY=y
 CONFIG_QPNP_FG_GEN3=y
 CONFIG_SMB1355_SLAVE_CHARGER=y
@@ -363,6 +369,7 @@
 # CONFIG_LOGO_LINUX_VGA16 is not set
 CONFIG_SOUND=y
 CONFIG_SND=y
+CONFIG_SND_DYNAMIC_MINORS=y
 CONFIG_SND_USB_AUDIO=y
 CONFIG_SND_USB_AUDIO_QMI=y
 CONFIG_SND_SOC=y
diff --git a/arch/arm/configs/sdxpoorwills-perf_defconfig b/arch/arm/configs/sdxpoorwills-perf_defconfig
index d5930a7..54214d5 100644
--- a/arch/arm/configs/sdxpoorwills-perf_defconfig
+++ b/arch/arm/configs/sdxpoorwills-perf_defconfig
@@ -41,6 +41,9 @@
 CONFIG_NEON=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+# CONFIG_PM_WAKELOCKS_GC is not set
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
diff --git a/arch/arm/configs/sdxpoorwills_defconfig b/arch/arm/configs/sdxpoorwills_defconfig
index f5abbb4..b4862b9 100644
--- a/arch/arm/configs/sdxpoorwills_defconfig
+++ b/arch/arm/configs/sdxpoorwills_defconfig
@@ -43,6 +43,9 @@
 CONFIG_NEON=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+# CONFIG_PM_WAKELOCKS_GC is not set
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index b62eaeb..174346b 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -76,6 +76,8 @@
 #define ARM_CPU_PART_CORTEX_A12		0x4100c0d0
 #define ARM_CPU_PART_CORTEX_A17		0x4100c0e0
 #define ARM_CPU_PART_CORTEX_A15		0x4100c0f0
+#define ARM_CPU_PART_CORTEX_A73		0x4100d090
+#define ARM_CPU_PART_KRYO2XX_GOLD		0x51008000
 #define ARM_CPU_PART_MASK		0xff00fff0
 
 /* DEC implemented cores */
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
index 3cc14dd..0c835ee 100644
--- a/arch/arm/include/asm/mmu_context.h
+++ b/arch/arm/include/asm/mmu_context.h
@@ -24,6 +24,18 @@
 
 void __check_vmalloc_seq(struct mm_struct *mm);
 
+#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
+void arm_init_bp_hardening(void);
+void arm_apply_bp_hardening(void);
+#else
+static inline void arm_init_bp_hardening(void)
+{
+}
+static inline void arm_apply_bp_hardening(void)
+{
+}
+#endif
+
 #ifdef CONFIG_CPU_HAS_ASID
 
 void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk);
@@ -63,8 +75,10 @@
 		 * finish_arch_post_lock_switch() call.
 		 */
 		mm->context.switch_pending = 1;
-	else
+	else {
+		arm_apply_bp_hardening();
 		cpu_switch_mm(mm->pgd, mm);
+	}
 }
 
 #ifndef MODULE
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index 4f14b5c..c2b440b 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -40,8 +40,15 @@
 #ifdef CONFIG_MMU
 void *module_alloc(unsigned long size)
 {
-	void *p = __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
-				GFP_KERNEL, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
+	gfp_t gfp_mask = GFP_KERNEL;
+	void *p;
+
+	/* Silence the initial allocation */
+	if (IS_ENABLED(CONFIG_ARM_MODULE_PLTS))
+		gfp_mask |= __GFP_NOWARN;
+
+	p = __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
+				gfp_mask, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
 				__builtin_return_address(0));
 	if (!IS_ENABLED(CONFIG_ARM_MODULE_PLTS) || p)
 		return p;
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 38ad8b9..b876193 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -150,17 +150,6 @@
 	show_data(regs->ARM_sp - nbytes, nbytes * 2, "SP");
 	show_data(regs->ARM_ip - nbytes, nbytes * 2, "IP");
 	show_data(regs->ARM_fp - nbytes, nbytes * 2, "FP");
-	show_data(regs->ARM_r0 - nbytes, nbytes * 2, "R0");
-	show_data(regs->ARM_r1 - nbytes, nbytes * 2, "R1");
-	show_data(regs->ARM_r2 - nbytes, nbytes * 2, "R2");
-	show_data(regs->ARM_r3 - nbytes, nbytes * 2, "R3");
-	show_data(regs->ARM_r4 - nbytes, nbytes * 2, "R4");
-	show_data(regs->ARM_r5 - nbytes, nbytes * 2, "R5");
-	show_data(regs->ARM_r6 - nbytes, nbytes * 2, "R6");
-	show_data(regs->ARM_r7 - nbytes, nbytes * 2, "R7");
-	show_data(regs->ARM_r8 - nbytes, nbytes * 2, "R8");
-	show_data(regs->ARM_r9 - nbytes, nbytes * 2, "R9");
-	show_data(regs->ARM_r10 - nbytes, nbytes * 2, "R10");
 	set_fs(fs);
 }
 
@@ -256,7 +245,8 @@
 	}
 #endif
 
-	show_extra_register_data(regs, 128);
+	if (!user_mode(regs))
+		show_extra_register_data(regs, 128);
 }
 
 void show_regs(struct pt_regs * regs)
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 09dd8ff..4f451ce 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -243,6 +243,40 @@
 	"?(17)",
 };
 
+#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
+struct arm_btbinv {
+	void (*apply_bp_hardening)(void);
+};
+static DEFINE_PER_CPU_READ_MOSTLY(struct arm_btbinv, arm_btbinv);
+
+static void arm_a73_apply_bp_hardening(void)
+{
+	asm("mov        r2, #0");
+	asm("mcr        p15, 0, r2, c7, c5, 6");
+}
+
+void arm_apply_bp_hardening(void)
+{
+	if (this_cpu_ptr(&arm_btbinv)->apply_bp_hardening)
+		this_cpu_ptr(&arm_btbinv)->apply_bp_hardening();
+}
+
+void arm_init_bp_hardening(void)
+{
+	switch (read_cpuid_part()) {
+	case ARM_CPU_PART_CORTEX_A73:
+	case ARM_CPU_PART_KRYO2XX_GOLD:
+		per_cpu(arm_btbinv.apply_bp_hardening, raw_smp_processor_id())
+			  = arm_a73_apply_bp_hardening;
+		break;
+	default:
+		per_cpu(arm_btbinv.apply_bp_hardening, raw_smp_processor_id())
+			  = NULL;
+		break;
+	}
+}
+#endif
+
 #ifdef CONFIG_CPU_V7M
 static int __get_cpu_architecture(void)
 {
@@ -685,6 +719,7 @@
 	 * types.  The linker builds this table for us from the
 	 * entries in arch/arm/mm/proc-*.S
 	 */
+	arm_init_bp_hardening();
 	list = lookup_processor_type(read_cpuid_id());
 	if (!list) {
 		pr_err("CPU configuration botched (ID %08x), unable to continue.\n",
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 3b2f4ce..0169acb 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -47,6 +47,7 @@
 #include <asm/virt.h>
 #include <asm/mach/arch.h>
 #include <asm/mpu.h>
+#include <asm/cputype.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/ipi.h>
@@ -359,6 +360,7 @@
 	 * The identity mapping is uncached (strongly ordered), so
 	 * switch away from it before attempting any exclusive accesses.
 	 */
+	arm_init_bp_hardening();
 	cpu_switch_mm(mm->pgd, mm);
 	local_flush_bp_all();
 	enter_lazy_tlb(mm, current);
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
index d96863e..7ca9180 100644
--- a/arch/arm/mach-qcom/Kconfig
+++ b/arch/arm/mach-qcom/Kconfig
@@ -64,6 +64,7 @@
 	select HAVE_CLK
 	select HAVE_CLK_PREPARE
 	select COMMON_CLK_MSM
+	select ARCH_MSM8953_SOC_SETTINGS
 
 config ARCH_MSM8953_BOOT_ORDERING
 	bool "Enable support for MSM8953 device boot ordering"
@@ -160,6 +161,7 @@
 	select HAVE_CLK
 	select HAVE_CLK_PREPARE
 	select COMMON_CLK_MSM
+	select ARCH_MSM8953_SOC_SETTINGS
 
 config ARCH_SDM632
 	bool "Enable Support for Qualcomm Technologies Inc. SDM632"
@@ -176,6 +178,7 @@
 	select SND_HWDEP
 	select CPU_FREQ_QCOM
 	select COMMON_CLK_MSM
+	select ARCH_MSM8953_SOC_SETTINGS
 
 config ARCH_SDM670
         bool "Enable Support for SDM670"
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index c1799dd..1a5acee 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -1068,3 +1068,20 @@
 	  additional section-aligned split of rodata from kernel text so it
 	  can be made explicitly non-executable. This padding may waste memory
 	  space to gain the additional protection.
+
+config HARDEN_BRANCH_PREDICTOR
+	bool "Harden the branch predictor against aliasing attacks" if EXPERT
+	default y
+	help
+	  Speculation attacks against some high-performance processors rely on
+	  being able to manipulate the branch predictor for a victim context by
+	  executing aliasing branches in the attacker context.  Such attacks
+	  can be partially mitigated against by clearing internal branch
+	  predictor state and limiting the prediction logic in some situations.
+
+	  This config option will take CPU-specific actions to harden the
+	  branch predictor against aliasing attacks and may rely on specific
+	  instruction sequences or control bits being set by the system
+	  firmware.
+
+	  If unsure, say Y.
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index c8c8b9e..f187439 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -276,5 +276,6 @@
 	raw_spin_unlock_irqrestore(&cpu_asid_lock, flags);
 
 switch_mm_fastpath:
+	arm_apply_bp_hardening();
 	cpu_switch_mm(mm->pgd, mm);
 }
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 203728d..7fa65aa 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -265,6 +265,7 @@
 	unsigned long addr;
 	struct vm_struct *area;
 	phys_addr_t paddr = __pfn_to_phys(pfn);
+	pgprot_t prot;
 
 #ifndef CONFIG_ARM_LPAE
 	/*
@@ -310,6 +311,12 @@
  	addr = (unsigned long)area->addr;
 	area->phys_addr = paddr;
 
+	prot = __pgprot(type->prot_pte);
+#ifdef CONFIG_ARCH_MSM8953_SOC_SETTINGS
+	if (paddr >= MSM8953_TLMM_START_ADDR &&
+	    paddr <= MSM8953_TLMM_END_ADDR)
+		prot = pgprot_stronglyordered(type->prot_pte);
+#endif
 #if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
 	if (DOMAIN_IO == 0 &&
 	    (((cpu_architecture() >= CPU_ARCH_ARMv6) && (get_cr() & CR_XP)) ||
@@ -322,8 +329,7 @@
 		err = remap_area_sections(addr, pfn, size, type);
 	} else
 #endif
-		err = ioremap_page_range(addr, addr + size, paddr,
-					 __pgprot(type->prot_pte));
+		err = ioremap_page_range(addr, addr + size, paddr, prot);
 
 	if (err) {
  		vunmap((void *)addr);
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index f72ce30..ac71d39 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -554,6 +554,16 @@
 
 endchoice
 
+config ARCH_MSM8953_SOC_SETTINGS
+	bool "Enable MSM8953 SOC settings"
+	depends on ARCH_MSM8953
+	help
+	  Enable MSM8953 SOC related settings, these generic MSM8953
+	  related settings are required for some of CPUSS sub-system
+	  functionality.
+
+	  If you are not sure what to do, select 'N' here.
+
 choice
 	prompt "Virtual address space size"
 	default ARM64_VA_BITS_39 if ARM64_4K_PAGES
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index a92f511..4c013ad 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -152,6 +152,7 @@
 	depends on ARCH_QCOM
 	select CPU_FREQ_QCOM
 	select COMMON_CLK_MSM
+	select ARCH_MSM8953_SOC_SETTINGS
 	help
 	  This enables support for the MSM8953 chipset. If you do not
 	  wish to build a kernel that runs on this chipset, say 'N' here.
@@ -179,6 +180,7 @@
 	depends on ARCH_QCOM
 	select CPU_FREQ_QCOM
 	select COMMON_CLK_MSM
+	select ARCH_MSM8953_SOC_SETTINGS
 	help
 	  This enables support for the sdm450 chipset. If you do not
 	  wish to build a kernel that runs on this chipset, say 'N' here.
@@ -188,6 +190,7 @@
 	depends on ARCH_QCOM
 	select CPU_FREQ_QCOM
 	select COMMON_CLK_MSM
+	select ARCH_MSM8953_SOC_SETTINGS
 	help
 	  This enables support for the sdm632 chipset. If you do not
 	  wish to build a kernel that runs on this chipset, say 'N' here.
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index e4d6200..8b0cb9f 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -150,6 +150,7 @@
 		qcs605-mtp-overlay.dtbo \
 		qcs605-360camera-overlay.dtbo \
 		qcs605-external-codec-mtp-overlay.dtbo \
+		qcs605-lc-ipcamera-overlay.dtbo \
 		qcs605-lc-mtp-overlay.dtbo \
 		qcs605-lc-cdp-overlay.dtbo \
 		sdm710-cdp-overlay.dtbo \
@@ -211,6 +212,7 @@
 qcs605-mtp-overlay.dtbo-base := qcs605.dtb
 qcs605-external-codec-mtp-overlay.dtbo-base := qcs605.dtb
 qcs605-lc-mtp-overlay.dtbo-base := qcs605-lc.dtb
+qcs605-lc-ipcamera-overlay.dtbo-base := qcs605-lc.dtb
 qcs605-360camera-overlay.dtbo-base := qcs605.dtb
 qcs605-lc-cdp-overlay.dtbo-base := qcs605-lc-cdp-base.dtb
 sdm710-cdp-overlay.dtbo-base := sdm710.dtb
@@ -271,6 +273,7 @@
 	qcs605-mtp.dtb \
 	qcs605-cdp.dtb \
 	qcs605-external-codec-mtp.dtb \
+	qcs605-lc-ipcamera.dtb \
 	qcs605-lc-mtp.dtb \
 	qcs605-lc-cdp.dtb \
 	sdm710-mtp.dtb \
diff --git a/arch/arm64/boot/dts/qcom/apq8009-robot-pronto-refboard.dts b/arch/arm64/boot/dts/qcom/apq8009-robot-pronto-refboard.dts
new file mode 100644
index 0000000..0ac8a31
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8009-robot-pronto-refboard.dts
@@ -0,0 +1,380 @@
+/* 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
+ * 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 "8909-pm8916.dtsi"
+#include "msm8909-pm8916-mtp.dtsi"
+#include "apq8009-audio-external_codec.dtsi"
+#include "apq8009-memory.dtsi"
+#include <dt-bindings/pinctrl/qcom,pmic-mpp.h>
+#include "msm8909-pm8916-camera.dtsi"
+#include "msm8909-pm8916-camera-sensor-robot.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. APQ8009 Robot-pronto RefBoard";
+	compatible = "qcom,apq8009-mtp", "qcom,apq8009", "qcom,mtp";
+	qcom,msm-id = <265 2>;
+	qcom,board-id= <8 0xE>;
+};
+
+&audio_codec_mtp {
+	status = "disabled";
+};
+
+&pm8916_gpios {
+	nfc_clk {
+		nfc_clk_default: nfc_clk_default {
+			status = "okay";
+		};
+	};
+};
+
+&msm_gpio {
+	hsuart_active: default {
+		mux {
+			pins = "gpio20", "gpio21", "gpio111", "gpio112";
+			function = "blsp_uart2";
+		};
+
+		config {
+			pins = "gpio20", "gpio21", "gpio111", "gpio112";
+			drive-strength = <16>;
+			bias-disable;
+		};
+	};
+
+	hsuart_sleep: sleep {
+		mux {
+			pins = "gpio20", "gpio21", "gpio111", "gpio112";
+			function = "blsp_uart2";
+		};
+
+		config {
+			pins = "gpio20", "gpio21", "gpio111", "gpio112";
+			drive-strength = <2>;
+			bias-disable;
+		};
+	};
+
+	usb_vbus_detect: usb_vbus_detect {
+		mux {
+			pins = "gpio97";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio97";
+			drive-strength = <2>;
+			bias-disable;
+		};
+	};
+
+	usb_id_detect: usb_id_detect {
+		mux {
+			pins = "gpio110";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio110";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+	};
+};
+
+&soc {
+	ext_codec: sound-9335 {
+		qcom,audio-routing =
+			"AIF4 VI", "MCLK",
+			"RX_BIAS", "MCLK",
+			"MADINPUT", "MCLK",
+			"AMIC2", "MIC BIAS2",
+			"MIC BIAS2", "Headset Mic",
+			"DMIC0", "MIC BIAS1",
+			"MIC BIAS1", "Digital Mic0",
+			"DMIC1", "MIC BIAS1",
+			"MIC BIAS1", "Digital Mic1",
+			"DMIC2", "MIC BIAS3",
+			"MIC BIAS3", "Digital Mic2",
+			"DMIC3", "MIC BIAS3",
+			"MIC BIAS3", "Digital Mic3",
+			"SpkrLeft IN", "SPK1 OUT",
+			"SpkrRight IN", "SPK2 OUT";
+
+		qcom,msm-gpios =
+			"us_eu_gpio";
+		qcom,pinctrl-names =
+			"all_off",
+			"us_eu_gpio_act";
+		pinctrl-names =
+			"all_off",
+			"us_eu_gpio_act";
+		pinctrl-0 = <&cross_conn_det_sus>;
+		pinctrl-1 = <&cross_conn_det_act>;
+		qcom,pri-mi2s-gpios = <&cdc_pri_mi2s_gpios>;
+		qcom,quat-mi2s-gpios = <&cdc_quat_mi2s_gpios>;
+
+		qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight",
+					"SpkrLeft", "SpkrRight";
+	};
+
+	i2c@78b9000 {
+		synaptics@20 {
+			status = "disabled";
+		};
+	};
+
+	blsp1_uart2_hs: uart@78b0000 {
+		compatible = "qcom,msm-hsuart-v14";
+		reg = <0x78b0000 0x200>,
+			<0x7884000 0x1f000>;
+		reg-names = "core_mem", "bam_mem";
+		interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+		#address-cells = <0>;
+		interrupt-parent = <&blsp1_uart2_hs>;
+		interrupts = <0 1 2>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0xffffffff>;
+		interrupt-map = <0 &intc 0 108 0
+				1 &intc 0 238 0
+				2 &msm_gpio 21 0>;
+		qcom,inject-rx-on-wakeup;
+		qcom,rx-char-to-inject = <0xfd>;
+		qcom,master-id = <86>;
+		clock-names = "core_clk", "iface_clk";
+		clocks = <&clock_gcc clk_gcc_blsp1_uart2_apps_clk>,
+				<&clock_gcc clk_gcc_blsp1_ahb_clk>;
+		pinctrl-names = "sleep", "default";
+		pinctrl-0 = <&hsuart_sleep>;
+		pinctrl-1 = <&hsuart_active>;
+		qcom,bam-tx-ep-pipe-index = <2>;
+		qcom,bam-rx-ep-pipe-index = <3>;
+		qcom,msm-bus,name = "blsp1_uart2_hs";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<86 512 0 0>,
+				<86 512 500 800>;
+		status = "ok";
+	};
+
+	bluetooth: bt_qca9379 {
+		compatible = "qca,qca9379";
+		qca,bt-reset-gpio = <&msm_gpio 47 0>; /* BT_EN */
+	};
+
+	cnss_sdio: qcom,cnss_sdio {
+		compatible = "qcom,cnss_sdio";
+		subsys-name = "AR6320";
+		/**
+		 * There is no vdd-wlan on board and this is not for DSRC.
+		 * IO and XTAL share the same vreg.
+		 **/
+		vdd-wlan-io-supply = <&pm8916_l5>;
+		qcom,cap-tsf-gpio = <&msm_gpio 42 1>;
+		qcom,wlan-ramdump-dynamic = <0x200000>;
+		qcom,msm-bus,name = "msm-cnss";
+		qcom,msm-bus,num-cases = <4>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<79 512 0 0>,             /* No vote */
+				<79 512 6250 200000>,     /* 50 Mbps */
+				<79 512 25000 200000>,    /* 200 Mbps */
+				<79 512 2048000 4096000>; /* MAX */
+	};
+
+	usb_detect: qcom,gpio-usbdetect {
+		compatible = "qcom,gpio-usbdetect";
+		interrupt-parent = <&msm_gpio>;
+		interrupts = <97 0>;
+		interrupt-names = "vbus_det_irq";
+		pinctrl-names = "usb_vbus_detect", "usb_id_detect";
+		pinctrl-0 = <&usb_vbus_detect>;
+		pinctrl-1 = <&usb_id_detect>;
+		qcom,gpio-mode-sel = <&msm_gpio 97 0>;
+		qcom,id-det-gpio = <&msm_gpio 110 0>;
+		qcom,dpdm_switch_gpio = <&pm8916_gpios 3 0>;
+	};
+
+	i2c@78b8000 {
+		wcd9xxx_codec@d {
+			status = "okay";
+			qcom,wcd-rst-gpio-node = <&wcd_rst_gpio>;
+		};
+	};
+
+	cdc_pri_mi2s_gpios: msm_cdc_pinctrl_pri {
+		compatible = "qcom,msm-cdc-pinctrl";
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&pri_mi2s_active &pri_mi2s_ws_active
+		     &pri_mi2s_dout_active &pri_mi2s_din_active>;
+		pinctrl-1 = <&pri_mi2s_sleep &pri_mi2s_ws_sleep
+		     &pri_mi2s_dout_sleep &pri_mi2s_din_sleep>;
+	};
+
+	cdc_quat_mi2s_gpios: msm_cdc_pinctrl_quat {
+		compatible = "qcom,msm-cdc-pinctrl";
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&quat_mi2s_active &quat_mi2s_din_active>;
+		pinctrl-1 = <&quat_mi2s_sleep &quat_mi2s_din_sleep>;
+	};
+
+	wcd_rst_gpio: wcd_gpio_ctrl {
+		compatible = "qcom,msm-cdc-pinctrl";
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&cdc_reset_active>;
+		pinctrl-1 = <&cdc_reset_sleep>;
+	};
+};
+
+&wcnss {
+	status = "disabled";
+};
+
+&msm_gpio {
+	sdc2_wlan_gpio_on: sdc2_wlan_gpio_on {
+		mux {
+			pins = "gpio43";
+			function = "gpio";
+		};
+		config {
+			pins = "gpio43";
+			drive-strength = <10>;
+			bias-pull-up;
+			output-high;
+		};
+	};
+
+	sdc2_wlan_gpio_off: sdc2_wlan_gpio_off {
+		mux {
+			pins = "gpio43";
+			function = "gpio";
+		};
+		config {
+			pins = "gpio43";
+			drive-strength = <2>;
+			bias-disable;
+			output-low;
+		};
+	};
+};
+
+&sdhc_2 {
+	/delete-property/cd-gpios;
+	#address-cells = <0>;
+	interrupt-parent = <&sdhc_2>;
+	interrupts = <0 1 2>;
+	#interrupt-cells = <1>;
+	interrupt-map-mask = <0xffffffff>;
+	interrupt-map = <0 &intc 0 125 0
+			1 &intc 0 221 0
+			2 &msm_gpio 38 0>;
+	interrupt-names = "hc_irq", "pwr_irq", "sdiowakeup_irq";
+
+	qcom,vdd-voltage-level = <1800000 2950000>;
+	qcom,vdd-current-level = <15000 400000>;
+
+	qcom,vdd-io-voltage-level = <1800000 1800000>;
+	qcom,vdd-io-current-level = <200 50000>;
+	qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+	qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
+
+	pinctrl-names = "active", "sleep";
+	pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on
+	&sdc2_wlan_gpio_on>;
+	pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off
+	&sdc2_wlan_gpio_off>;
+	qcom,nonremovable;
+	qcom,core_3_0v_support;
+	status = "ok";
+};
+
+&i2c_4 {
+	status= "okay";
+	smb1360_otg_supply: smb1360-chg-fg@14 {
+		compatible = "qcom,smb1360-chg-fg";
+		reg = <0x14>;
+		interrupt-parent = <&msm_gpio>;
+		interrupts = <58 8>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&smb_int_default>;
+		qcom,charging-disabled;
+		qcom,empty-soc-disabled;
+		qcom,chg-inhibit-disabled;
+		qcom,float-voltage-mv = <4200>;
+		qcom,iterm-ma = <200>;
+		qcom,recharge-thresh-mv = <100>;
+		qcom,thermal-mitigation = <1500 700 600 0>;
+		status= "okay";
+		smb1360_vbus: qcom,smb1360-vbus {
+			regulator-name = "qcom,smb1360-vbus";
+		};
+	};
+};
+
+&usb_otg {
+	interrupts = <0 134 0>, <0 140 0>, <0 136 0>;
+	interrupt-names = "core_irq", "async_irq", "phy_irq";
+	qcom,hsusb-otg-mode = <3>;
+	vbus_otg-supply = <&smb1360_vbus>;
+	extcon = <&smb1360_otg_supply>;
+};
+
+&mdss_fb0 {
+	status = "disabled";
+	/delete-node/ qcom,cont-splash-memory;
+};
+
+&mdss_mdp {
+	status = "disabled";
+};
+
+&mdss_dsi0_pll {
+	status = "disabled";
+};
+
+&mdss_dsi0 {
+	status = "disabled";
+};
+
+&i2c_1 {
+	status = "disabled";
+};
+
+&i2c_2 {
+	status = "disabled";
+};
+
+&i2c_5 {
+	status = "disabled";
+};
+
+&spi_0 {
+	status = "disabled";
+};
+
+&wcd_rst_gpio {
+	status = "okay";
+};
+
+&ext_codec {
+	status = "okay";
+};
+
+&blsp1_uart2_hs {
+	status = "disabled";
+};
+
+/delete-node/ &cont_splash_mem;
diff --git a/arch/arm64/boot/dts/qcom/apq8009-robot-rome-refboard.dts b/arch/arm64/boot/dts/qcom/apq8009-robot-rome-refboard.dts
new file mode 100644
index 0000000..66070b7
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8009-robot-rome-refboard.dts
@@ -0,0 +1,380 @@
+/* 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
+ * 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 "8909-pm8916.dtsi"
+#include "msm8909-pm8916-mtp.dtsi"
+#include "apq8009-audio-external_codec.dtsi"
+#include "apq8009-memory.dtsi"
+#include <dt-bindings/pinctrl/qcom,pmic-mpp.h>
+#include "msm8909-pm8916-camera.dtsi"
+#include "msm8909-pm8916-camera-sensor-robot.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. APQ8009 Robot-rome RefBoard";
+	compatible = "qcom,apq8009-mtp", "qcom,apq8009", "qcom,mtp";
+	qcom,msm-id = <265 2>;
+	qcom,board-id= <8 0x10>;
+};
+
+&audio_codec_mtp {
+	status = "disabled";
+};
+
+&pm8916_gpios {
+	nfc_clk {
+		nfc_clk_default: nfc_clk_default {
+			status = "okay";
+		};
+	};
+};
+
+&msm_gpio {
+	hsuart_active: default {
+		mux {
+			pins = "gpio20", "gpio21", "gpio111", "gpio112";
+			function = "blsp_uart2";
+		};
+
+		config {
+			pins = "gpio20", "gpio21", "gpio111", "gpio112";
+			drive-strength = <16>;
+			bias-disable;
+		};
+	};
+
+	hsuart_sleep: sleep {
+		mux {
+			pins = "gpio20", "gpio21", "gpio111", "gpio112";
+			function = "blsp_uart2";
+		};
+
+		config {
+			pins = "gpio20", "gpio21", "gpio111", "gpio112";
+			drive-strength = <2>;
+			bias-disable;
+		};
+	};
+
+	usb_vbus_detect: usb_vbus_detect {
+		mux {
+			pins = "gpio97";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio97";
+			drive-strength = <2>;
+			bias-disable;
+		};
+	};
+
+	usb_id_detect: usb_id_detect {
+		mux {
+			pins = "gpio110";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio110";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+	};
+};
+
+&soc {
+	ext_codec: sound-9335 {
+		qcom,audio-routing =
+			"AIF4 VI", "MCLK",
+			"RX_BIAS", "MCLK",
+			"MADINPUT", "MCLK",
+			"AMIC2", "MIC BIAS2",
+			"MIC BIAS2", "Headset Mic",
+			"DMIC0", "MIC BIAS1",
+			"MIC BIAS1", "Digital Mic0",
+			"DMIC1", "MIC BIAS1",
+			"MIC BIAS1", "Digital Mic1",
+			"DMIC2", "MIC BIAS3",
+			"MIC BIAS3", "Digital Mic2",
+			"DMIC3", "MIC BIAS3",
+			"MIC BIAS3", "Digital Mic3",
+			"SpkrLeft IN", "SPK1 OUT",
+			"SpkrRight IN", "SPK2 OUT";
+
+		qcom,msm-gpios =
+			"us_eu_gpio";
+		qcom,pinctrl-names =
+			"all_off",
+			"us_eu_gpio_act";
+		pinctrl-names =
+			"all_off",
+			"us_eu_gpio_act";
+		pinctrl-0 = <&cross_conn_det_sus>;
+		pinctrl-1 = <&cross_conn_det_act>;
+		qcom,pri-mi2s-gpios = <&cdc_pri_mi2s_gpios>;
+		qcom,quat-mi2s-gpios = <&cdc_quat_mi2s_gpios>;
+
+		qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight",
+					"SpkrLeft", "SpkrRight";
+	};
+
+	i2c@78b9000 {
+		synaptics@20 {
+			status = "disabled";
+		};
+	};
+
+	blsp1_uart2_hs: uart@78b0000 {
+		compatible = "qcom,msm-hsuart-v14";
+		reg = <0x78b0000 0x200>,
+			<0x7884000 0x1f000>;
+		reg-names = "core_mem", "bam_mem";
+		interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+		#address-cells = <0>;
+		interrupt-parent = <&blsp1_uart2_hs>;
+		interrupts = <0 1 2>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0xffffffff>;
+		interrupt-map = <0 &intc 0 108 0
+				1 &intc 0 238 0
+				2 &msm_gpio 21 0>;
+		qcom,inject-rx-on-wakeup;
+		qcom,rx-char-to-inject = <0xfd>;
+		qcom,master-id = <86>;
+		clock-names = "core_clk", "iface_clk";
+		clocks = <&clock_gcc clk_gcc_blsp1_uart2_apps_clk>,
+				<&clock_gcc clk_gcc_blsp1_ahb_clk>;
+		pinctrl-names = "sleep", "default";
+		pinctrl-0 = <&hsuart_sleep>;
+		pinctrl-1 = <&hsuart_active>;
+		qcom,bam-tx-ep-pipe-index = <2>;
+		qcom,bam-rx-ep-pipe-index = <3>;
+		qcom,msm-bus,name = "blsp1_uart2_hs";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<86 512 0 0>,
+				<86 512 500 800>;
+		status = "ok";
+	};
+
+	bluetooth: bt_qca9379 {
+		compatible = "qca,qca9379";
+		qca,bt-reset-gpio = <&msm_gpio 47 0>; /* BT_EN */
+	};
+
+	cnss_sdio: qcom,cnss_sdio {
+		compatible = "qcom,cnss_sdio";
+		subsys-name = "AR6320";
+		/**
+		 * There is no vdd-wlan on board and this is not for DSRC.
+		 * IO and XTAL share the same vreg.
+		 **/
+		vdd-wlan-io-supply = <&pm8916_l5>;
+		qcom,cap-tsf-gpio = <&msm_gpio 42 1>;
+		qcom,wlan-ramdump-dynamic = <0x200000>;
+		qcom,msm-bus,name = "msm-cnss";
+		qcom,msm-bus,num-cases = <4>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<79 512 0 0>,             /* No vote */
+				<79 512 6250 200000>,     /* 50 Mbps */
+				<79 512 25000 200000>,    /* 200 Mbps */
+				<79 512 2048000 4096000>; /* MAX */
+	};
+
+	usb_detect: qcom,gpio-usbdetect {
+		compatible = "qcom,gpio-usbdetect";
+		interrupt-parent = <&msm_gpio>;
+		interrupts = <97 0>;
+		interrupt-names = "vbus_det_irq";
+		pinctrl-names = "usb_vbus_detect", "usb_id_detect";
+		pinctrl-0 = <&usb_vbus_detect>;
+		pinctrl-1 = <&usb_id_detect>;
+		qcom,gpio-mode-sel = <&msm_gpio 97 0>;
+		qcom,id-det-gpio = <&msm_gpio 110 0>;
+		qcom,dpdm_switch_gpio = <&pm8916_gpios 3 0>;
+	};
+
+	i2c@78b8000 {
+		wcd9xxx_codec@d {
+			status = "okay";
+			qcom,wcd-rst-gpio-node = <&wcd_rst_gpio>;
+		};
+	};
+
+	cdc_pri_mi2s_gpios: msm_cdc_pinctrl_pri {
+		compatible = "qcom,msm-cdc-pinctrl";
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&pri_mi2s_active &pri_mi2s_ws_active
+		     &pri_mi2s_dout_active &pri_mi2s_din_active>;
+		pinctrl-1 = <&pri_mi2s_sleep &pri_mi2s_ws_sleep
+		     &pri_mi2s_dout_sleep &pri_mi2s_din_sleep>;
+	};
+
+	cdc_quat_mi2s_gpios: msm_cdc_pinctrl_quat {
+		compatible = "qcom,msm-cdc-pinctrl";
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&quat_mi2s_active &quat_mi2s_din_active>;
+		pinctrl-1 = <&quat_mi2s_sleep &quat_mi2s_din_sleep>;
+	};
+
+	wcd_rst_gpio: wcd_gpio_ctrl {
+		compatible = "qcom,msm-cdc-pinctrl";
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&cdc_reset_active>;
+		pinctrl-1 = <&cdc_reset_sleep>;
+	};
+};
+
+&wcnss {
+	status = "disabled";
+};
+
+&msm_gpio {
+	sdc2_wlan_gpio_on: sdc2_wlan_gpio_on {
+		mux {
+			pins = "gpio43";
+			function = "gpio";
+		};
+		config {
+			pins = "gpio43";
+			drive-strength = <10>;
+			bias-pull-up;
+			output-high;
+		};
+	};
+
+	sdc2_wlan_gpio_off: sdc2_wlan_gpio_off {
+		mux {
+			pins = "gpio43";
+			function = "gpio";
+		};
+		config {
+			pins = "gpio43";
+			drive-strength = <2>;
+			bias-disable;
+			output-low;
+		};
+	};
+};
+
+&sdhc_2 {
+	/delete-property/cd-gpios;
+	#address-cells = <0>;
+	interrupt-parent = <&sdhc_2>;
+	interrupts = <0 1 2>;
+	#interrupt-cells = <1>;
+	interrupt-map-mask = <0xffffffff>;
+	interrupt-map = <0 &intc 0 125 0
+			1 &intc 0 221 0
+			2 &msm_gpio 38 0>;
+	interrupt-names = "hc_irq", "pwr_irq", "sdiowakeup_irq";
+
+	qcom,vdd-voltage-level = <1800000 2950000>;
+	qcom,vdd-current-level = <15000 400000>;
+
+	qcom,vdd-io-voltage-level = <1800000 1800000>;
+	qcom,vdd-io-current-level = <200 50000>;
+	qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+	qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
+
+	pinctrl-names = "active", "sleep";
+	pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on
+	&sdc2_wlan_gpio_on>;
+	pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off
+	&sdc2_wlan_gpio_off>;
+	qcom,nonremovable;
+	qcom,core_3_0v_support;
+	status = "ok";
+};
+
+&i2c_4 {
+	status= "okay";
+	smb1360_otg_supply: smb1360-chg-fg@14 {
+		compatible = "qcom,smb1360-chg-fg";
+		reg = <0x14>;
+		interrupt-parent = <&msm_gpio>;
+		interrupts = <58 8>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&smb_int_default>;
+		qcom,charging-disabled;
+		qcom,empty-soc-disabled;
+		qcom,chg-inhibit-disabled;
+		qcom,float-voltage-mv = <4200>;
+		qcom,iterm-ma = <200>;
+		qcom,recharge-thresh-mv = <100>;
+		qcom,thermal-mitigation = <1500 700 600 0>;
+		status= "okay";
+		smb1360_vbus: qcom,smb1360-vbus {
+			regulator-name = "qcom,smb1360-vbus";
+		};
+	};
+};
+
+&usb_otg {
+	interrupts = <0 134 0>, <0 140 0>, <0 136 0>;
+	interrupt-names = "core_irq", "async_irq", "phy_irq";
+	qcom,hsusb-otg-mode = <3>;
+	vbus_otg-supply = <&smb1360_vbus>;
+	extcon = <&smb1360_otg_supply>;
+};
+
+&mdss_fb0 {
+	status = "disabled";
+	/delete-node/ qcom,cont-splash-memory;
+};
+
+&mdss_mdp {
+	status = "disabled";
+};
+
+&mdss_dsi0_pll {
+	status = "disabled";
+};
+
+&mdss_dsi0 {
+	status = "disabled";
+};
+
+&i2c_1 {
+	status = "disabled";
+};
+
+&i2c_2 {
+	status = "disabled";
+};
+
+&i2c_5 {
+	status = "disabled";
+};
+
+&spi_0 {
+	status = "disabled";
+};
+
+&wcd_rst_gpio {
+	status = "okay";
+};
+
+&ext_codec {
+	status = "okay";
+};
+
+&blsp1_uart2_hs {
+	status = "disabled";
+};
+
+/delete-node/ &cont_splash_mem;
diff --git a/arch/arm64/boot/dts/qcom/apq8053-lite-dragon-v2.2.dts b/arch/arm64/boot/dts/qcom/apq8053-lite-dragon-v2.2.dts
index ecc4fea..599f3ef 100644
--- a/arch/arm64/boot/dts/qcom/apq8053-lite-dragon-v2.2.dts
+++ b/arch/arm64/boot/dts/qcom/apq8053-lite-dragon-v2.2.dts
@@ -25,3 +25,12 @@
 &blsp2_uart0 {
 	status = "okay";
 };
+
+&i2c_3 {
+	status = "okay";
+	/delete-node/ himax_ts@48;
+	gt9xx-i2c@14 {
+		status = "okay";
+	};
+};
+
diff --git a/arch/arm64/boot/dts/qcom/apq8053-lite-dragon-v2.3.dtsi b/arch/arm64/boot/dts/qcom/apq8053-lite-dragon-v2.3.dtsi
index 5cf8ac0..c682f58 100644
--- a/arch/arm64/boot/dts/qcom/apq8053-lite-dragon-v2.3.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8053-lite-dragon-v2.3.dtsi
@@ -42,6 +42,7 @@
 
 &i2c_3 {
 	status = "okay";
+	/delete-node/ focaltech@38;
 	/delete-node/ himax_ts@48;
 	focaltech_ts@38 {
 		compatible = "focaltech,fts";
@@ -64,6 +65,7 @@
 };
 
 &wled {
+	qcom,cons-sync-write-delay-us = <1000>;
 	qcom,led-strings-list = [00 01 02];
 };
 
@@ -78,3 +80,19 @@
 &camera2{
 	qcom,mount-angle = <90>;
 };
+
+&mdss_dsi0 {
+	qcom,dsi-pref-prim-pan = <&dsi_hx8394d_kingdisplay_vid>;
+	pinctrl-names = "mdss_default", "mdss_sleep";
+	pinctrl-0 = <&mdss_dsi_active &mdss_te_active>;
+	pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>;
+
+	vdd-supply = <&pm8953_l17>;
+	vddio-supply = <&pm8953_l6>;
+	lab-supply = <&lab_regulator>;
+	ibb-supply = <&ibb_regulator>;
+
+	qcom,platform-te-gpio = <&tlmm 24 0>;
+	qcom,platform-reset-gpio = <&tlmm 61 0>;
+	qcom,platform-bklight-en-gpio = <&tlmm 100 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi b/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi
index 90b1d4f..f7a2026 100644
--- a/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8053-lite-dragon.dtsi
@@ -223,6 +223,79 @@
 		himax,irq-gpio = <&tlmm 65 0x2008>;
 		report_type = <1>;
 	};
+
+	gt9xx-i2c@14 {
+		compatible = "goodix,gt9xx";
+		reg = <0x14>;
+		vdd_ana-supply = <&pm8953_l10>;
+		vcc_i2c-supply = <&pm8953_l6>;
+		interrupt-parent = <&tlmm>;
+		interrupts = <65 0x2008>;
+		pinctrl-names = "gdix_ts_int_default", "gdix_ts_int_output_low",
+			"gdix_ts_int_output_high", "gdix_ts_int_input",
+			"gdix_ts_rst_default", "gdix_ts_rst_output_low",
+			"gdix_ts_rst_output_high", "gdix_ts_rst_input";
+		pinctrl-0 = <&ts_int_default>;
+		pinctrl-1 = <&ts_int_output_low>;
+		pinctrl-2 = <&ts_int_output_high>;
+		pinctrl-3 = <&ts_int_input>;
+		pinctrl-4 = <&ts_rst_default>;
+		pinctrl-5 = <&ts_rst_output_low>;
+		pinctrl-6 = <&ts_rst_output_high>;
+		pinctrl-7 = <&ts_rst_input>;
+
+		reset-gpios = <&tlmm 64 0x00>;
+		irq-gpios = <&tlmm 65 0x2008>;
+		irq-flags = <2>;
+
+		touchscreen-max-id = <11>;
+		touchscreen-size-x = <1200>;
+		touchscreen-size-y = <1920>;
+		touchscreen-max-w = <1024>;
+		touchscreen-max-p = <1024>;
+
+		goodix,type-a-report = <0>;
+		goodix,driver-send-cfg = <1>;
+		goodix,wakeup-with-reset = <0>;
+		goodix,resume-in-workqueue = <0>;
+		goodix,int-sync = <1>;
+		goodix,swap-x2y = <0>;
+		goodix,esd-protect = <1>;
+		goodix,pen-suppress-finger = <0>;
+		goodix,auto-update = <1>;
+		goodix,auto-update-cfg = <0>;
+		goodix,power-off-sleep = <0>;
+
+		goodix,cfg-group0 = [
+			5A B0 04 80 07 0A 35 10 22 08 32 0D 50 3C 0A 04
+			01 01 00 B4 11 11 44 15 19 1B 14 95 35 FF 3A 3C
+			39 13 00 00 00 98 03 1C 00 00 00 00 03 00 00 00
+			00 80 0A 37 46 40 E5 52 23 28 00 04 81 38 00 7F
+			3B 00 7D 3E 00 7C 41 00 7A 44 0C 7A 00 50 33 50
+			0B 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+			00 00 00 00 00 00 00 55 00 01 00 00 02 00 00 00
+			1D 1C 1B 1A 19 18 17 16 15 14 13 12 11 10 0F 0E
+			0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00 2A 29
+			28 27 26 25 24 23 22 21 20 1F 1E 1D 1C 1B 19 18
+			17 16 15 14 13 12 11 10 0F 0E 0D 0C 0B 0A 09 08
+			07 06 05 04 03 02 01 00 08 01
+		];
+
+		goodix,cfg-group2 = [
+			5B B0 04 80 07 0A 35 10 22 08 32 0D 50 32 0A 04
+			01 01 00 B4 11 11 44 2B 31 36 28 95 35 FF 3E 40
+			39 13 00 00 00 DA 03 1C 00 00 00 00 03 00 00 00
+			00 80 0A 32 42 40 E5 52 23 28 00 04 7D 33 00 7D
+			36 00 7E 39 00 7F 3C 00 80 40 0C 80 00 50 33 50
+			0B 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+			00 00 00 00 00 00 00 55 00 01 00 00 02 00 00 00
+			1D 1C 1B 1A 19 18 17 16 15 14 13 12 11 10 0F 0E
+			0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00 2A 29
+			28 27 26 25 24 23 22 21 20 1F 1E 1D 1C 1B 19 18
+			17 16 15 14 13 12 11 10 0F 0E 0D 0C 0B 0A 09 08
+			07 06 05 04 03 02 01 00 81 01
+		];
+	};
 };
 
 &soc {
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-hx8394d-wxga-video.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-hx8394d-wxga-video.dtsi
new file mode 100644
index 0000000..69f168b
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-hx8394d-wxga-video.dtsi
@@ -0,0 +1,86 @@
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+&mdss_mdp {
+	dsi_hx8394d_kingdisplay_vid: qcom,mdss_dsi_hx8394d_kingdisplay_vid {
+		qcom,mdss-dsi-panel-name = "hx8394d wxga video mode dsi panel";
+		qcom,mdss-dsi-panel-type = "dsi_video_mode";
+		qcom,mdss-dsi-panel-framerate = <60>;
+		qcom,mdss-dsi-virtual-channel-id = <0>;
+		qcom,mdss-dsi-stream = <0>;
+		qcom,mdss-dsi-panel-width = <800>;
+		qcom,mdss-dsi-panel-height = <1280>;
+		qcom,mdss-dsi-h-front-porch = <24>;
+		qcom,mdss-dsi-h-back-porch = <132>;
+		qcom,mdss-dsi-h-pulse-width = <4>;
+		qcom,mdss-dsi-h-sync-skew = <0>;
+		qcom,mdss-dsi-v-back-porch = <16>;
+		qcom,mdss-dsi-v-front-porch = <9>;
+		qcom,mdss-dsi-v-pulse-width = <2>;
+		qcom,mdss-dsi-h-left-border = <0>;
+		qcom,mdss-dsi-h-right-border = <0>;
+		qcom,mdss-dsi-v-top-border = <0>;
+		qcom,mdss-dsi-v-bottom-border = <0>;
+		qcom,mdss-dsi-bpp = <24>;
+		qcom,mdss-dsi-color-order = "rgb_swap_rgb";
+		qcom,mdss-dsi-underflow-color = <0xff>;
+		qcom,mdss-dsi-border-color = <0>;
+		qcom,mdss-dsi-on-command = [
+			39 01 00 00 00 00 04 B9 FF 83 94
+			39 01 00 00 32 00 05 D9 00 8B 02 07
+			39 01 00 00 00 00 03 BA 73 83
+			39 01 00 00 00 00 10 B1 6C 10 10 24 E4 11 F1 80 E4 D7 23 80 C0 D2 58
+			39 01 00 00 00 00 0C B2 00 64 10 07 70 1C 08 08 1C 4D 00
+			39 01 00 00 00 00 0D B4 00 FF 03 5A 03 5A 03 5A 01 6A 01 6A
+			39 01 00 00 00 00 1F D3 00 06 00 40 1A 08 00 32 10 07 00 07 54 15 0F 05 04 02 12 10 05 07 33 33 0B 0B 37 10 07 07
+			39 01 00 00 00 00 2D D5 19 19 18 18 1A 1A 1B 1B 04 05 06 07 00 01 02 03 20 21 18 18 18 18 18 18 18 18 18 18 18 18 22 23 18 18 18 18 18 18 18 18 18 18 18 18
+			39 01 00 00 00 00 2D D6 18 18 19 19 1A 1A 1B 1B 03 02 01 00 07 06 05 04 23 22 18 18 18 18 18 18 18 18 18 18 18 18 21 20 18 18 18 18 18 18 18 18 19 18 18 18
+			39 01 00 00 00 00 2B E0 00 00 02 3C 3E 3F 12 3D 06 09 0A 19 0F 11 14 12 13 07 12 15 16 00 00 01 3C 3E 3F 12 3D 07 09 0B 12 0D 11 13 11 13 08 13 14 19
+			15 01 00 00 00 00 02 CC 09
+			15 01 00 00 00 00 02 D2 55
+			39 01 00 00 00 00 03 C0 30 14
+			39 01 00 00 00 00 04 BF 41 0E 01
+			39 01 00 00 00 00 05 C7 00 C0 40 C0
+			15 01 00 00 00 00 02 DF 8E
+			05 01 00 00 C8 00 01 11
+			05 01 00 00 C8 00 01 29
+		];
+		qcom,mdss-dsi-off-command = [
+			05 01 00 00 32 00 02 28 00
+			05 01 00 00 78 00 02 10 00
+		];
+		qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
+		qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
+		qcom,mdss-dsi-h-sync-pulse = <0>;
+		qcom,mdss-dsi-traffic-mode = "non_burst_sync_event";
+		qcom,mdss-dsi-bllp-eof-power-mode;
+		qcom,mdss-dsi-bllp-power-mode;
+		qcom,mdss-dsi-lane-0-state;
+		qcom,mdss-dsi-lane-1-state;
+		qcom,mdss-dsi-lane-2-state;
+		qcom,mdss-dsi-lane-3-state;
+		qcom,mdss-dsi-panel-timings =
+					[8B 1f 14 00 45 4A 19 23 23 03 04 00];
+		qcom,mdss-dsi-t-clk-post = <0x04>;
+		qcom,mdss-dsi-t-clk-pre = <0x1D>;
+		qcom,mdss-dsi-dma-trigger = "trigger_sw";
+		qcom,mdss-dsi-mdp-trigger = "none";
+		qcom,mdss-dsi-reset-sequence = <1 20>, <0 2>, <1 20>;
+		qcom,mdss-dsi-init-delay-us = <50000>;
+		qcom,mdss-dsi-bl-min-level = <1>;
+		qcom,mdss-dsi-bl-max-level = <4095>;
+		qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+		qcom,mdss-pan-physical-width-dimension = <107>;
+		qcom,mdss-pan-physical-height-dimension = <172>;
+	};
+};
+
diff --git a/arch/arm64/boot/dts/qcom/msm8917-cdp-ml-touch-overlay.dts b/arch/arm64/boot/dts/qcom/msm8917-cdp-ml-touch-overlay.dts
index 377eda4..73ea29b 100644
--- a/arch/arm64/boot/dts/qcom/msm8917-cdp-ml-touch-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/msm8917-cdp-ml-touch-overlay.dts
@@ -14,7 +14,6 @@
 /dts-v1/;
 /plugin/;
 
-#include <dt-bindings/clock/msm-clocks-8952.h>
 #include "msm8917-cdp.dtsi"
 #include "msm8917-cdp-mirror-lake-touch.dtsi"
 #include "msm8917-audio-cdp.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/msm8917-cdp.dtsi b/arch/arm64/boot/dts/qcom/msm8917-cdp.dtsi
index 6a2fecd..a804edd 100644
--- a/arch/arm64/boot/dts/qcom/msm8917-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8917-cdp.dtsi
@@ -11,6 +11,8 @@
  * GNU General Public License for more details.
  */
 
+#include <dt-bindings/clock/msm-clocks-8952.h>
+
 &soc {
 	gpio_keys {
 		compatible = "gpio-keys";
@@ -156,6 +158,39 @@
 	};
 };
 
+&pm8937_gpios {
+	nfc_clk {
+		nfc_clk_default: nfc_clk_default {
+			pins = "gpio5";
+			function = "normal";
+			input-enable;
+			power-source = <1>;
+		};
+	};
+};
+
+&i2c_5 { /* BLSP2 QUP1 (NFC) */
+	status = "ok";
+	nq@28 {
+		compatible = "qcom,nq-nci";
+		reg = <0x28>;
+		qcom,nq-irq = <&tlmm 17 0x00>;
+		qcom,nq-ven = <&tlmm 16 0x00>;
+		qcom,nq-firm = <&tlmm 130 0x00>;
+		qcom,nq-clkreq = <&pm8937_gpios 5 0x00>;
+		interrupt-parent = <&tlmm>;
+		qcom,clk-src = "BBCLK2";
+		interrupts = <17 0>;
+		interrupt-names = "nfc_irq";
+		pinctrl-names = "nfc_active", "nfc_suspend";
+		pinctrl-0 = <&nfc_int_active &nfc_disable_active
+						&nfc_clk_default>;
+		pinctrl-1 = <&nfc_int_suspend &nfc_disable_suspend>;
+		clocks = <&clock_gcc clk_bb_clk2_pin>;
+		clock-names = "ref_clk";
+		};
+};
+
 &sdhc_1 {
 	/* device core power supply */
 	vdd-supply = <&pm8937_l8>;
diff --git a/arch/arm64/boot/dts/qcom/msm8917-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/msm8917-mtp-overlay.dts
index 920bcae..0540e09 100644
--- a/arch/arm64/boot/dts/qcom/msm8917-mtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/msm8917-mtp-overlay.dts
@@ -15,7 +15,6 @@
 /plugin/;
 
 #include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/clock/msm-clocks-8952.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include "msm8917-mtp.dtsi"
 
diff --git a/arch/arm64/boot/dts/qcom/msm8917-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8917-mtp.dtsi
index 7f35e1e..9a3b6dae 100644
--- a/arch/arm64/boot/dts/qcom/msm8917-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8917-mtp.dtsi
@@ -11,6 +11,7 @@
  * GNU General Public License for more details.
  */
 
+#include <dt-bindings/clock/msm-clocks-8952.h>
 #include "msm8917-camera-sensor-mtp.dtsi"
 
 &blsp1_uart2 {
@@ -19,6 +20,39 @@
 	pinctrl-0 = <&uart_console_active>;
 };
 
+&pm8937_gpios {
+	nfc_clk {
+		nfc_clk_default: nfc_clk_default {
+			pins = "gpio5";
+			function = "normal";
+			input-enable;
+			power-source = <1>;
+		};
+	};
+};
+
+&i2c_5 { /* BLSP2 QUP1 (NFC) */
+	status = "ok";
+	nq@28 {
+		compatible = "qcom,nq-nci";
+		reg = <0x28>;
+		qcom,nq-irq = <&tlmm 17 0x00>;
+		qcom,nq-ven = <&tlmm 16 0x00>;
+		qcom,nq-firm = <&tlmm 130 0x00>;
+		qcom,nq-clkreq = <&pm8937_gpios 5 0x00>;
+		interrupt-parent = <&tlmm>;
+		qcom,clk-src = "BBCLK2";
+		interrupts = <17 0>;
+		interrupt-names = "nfc_irq";
+		pinctrl-names = "nfc_active", "nfc_suspend";
+		pinctrl-0 = <&nfc_int_active &nfc_disable_active
+						&nfc_clk_default>;
+		pinctrl-1 = <&nfc_int_suspend &nfc_disable_suspend>;
+		clocks = <&clock_gcc clk_bb_clk2_pin>;
+		clock-names = "ref_clk";
+	};
+};
+
 &sdhc_1 {
 	/* device core power supply */
 	vdd-supply = <&pm8937_l8>;
diff --git a/arch/arm64/boot/dts/qcom/msm8917-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8917-pinctrl.dtsi
index 858936d..0e613b6 100644
--- a/arch/arm64/boot/dts/qcom/msm8917-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8917-pinctrl.dtsi
@@ -1345,39 +1345,65 @@
 			};
 		};
 
-		pmx_rd_nfc_int {
-			/*qcom,pins = <&gp 17>;*/
-			pins = "gpio17";
-			qcom,pin-func = <0>;
-			qcom,num-grp-pins = <1>;
-			label = "pmx_nfc_int";
+		nfc {
+			nfc_int_active: nfc_int_active {
+				/* active state */
+				mux {
+					/* GPIO 17 NFC Read Interrupt */
+					pins = "gpio17";
+					function = "gpio";
+				};
 
-			nfc_int_active: active {
-				drive-strength = <6>;
-				bias-pull-up;
+				config {
+					pins = "gpio17";
+					drive-strength = <2>; /* 2 MA */
+					bias-pull-up;
+				};
 			};
 
-			nfc_int_suspend: suspend {
-				drive-strength = <6>;
-				bias-pull-up;
-			};
-		};
+			nfc_int_suspend: nfc_int_suspend {
+				/* sleep state */
+				mux {
+					/* GPIO 17 NFC Read Interrupt */
+					pins = "gpio17";
+					function = "gpio";
+				};
 
-		pmx_nfc_reset {
-			/*qcom,pins = <&gp 16>;*/
-			pins = "gpio16";
-			qcom,pin-func = <0>;
-			qcom,num-grp-pins = <1>;
-			label = "pmx_nfc_disable";
-
-			nfc_disable_active: active {
-				drive-strength = <6>;
-				bias-pull-up;
+				config {
+					pins = "gpio17";
+					drive-strength = <2>; /* 2 MA */
+					bias-pull-up;
+				};
 			};
 
-			nfc_disable_suspend: suspend {
-				drive-strength = <6>;
-				bias-disable;
+			nfc_disable_active: nfc_disable_active {
+				/* active state */
+				mux {
+					/* 16: NFC ENABLE 130: FW DNLD */
+					pins = "gpio16", "gpio130";
+					function = "gpio";
+				};
+
+				config {
+					pins = "gpio16", "gpio130";
+					drive-strength = <2>; /* 2 MA */
+					bias-pull-up;
+				};
+			};
+
+			nfc_disable_suspend: nfc_disable_suspend {
+				/* sleep state */
+				mux {
+					/* 16: NFC ENABLE 130: FW DNLD */
+					pins = "gpio16", "gpio130";
+					function = "gpio";
+				};
+
+				config {
+					pins = "gpio16", "gpio130";
+					drive-strength = <2>; /* 2 MA */
+					bias-disable;
+				};
 			};
 		};
 
diff --git a/arch/arm64/boot/dts/qcom/msm8917-qrd-overlay.dts b/arch/arm64/boot/dts/qcom/msm8917-qrd-overlay.dts
index 6517757..9b4d8f4 100644
--- a/arch/arm64/boot/dts/qcom/msm8917-qrd-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/msm8917-qrd-overlay.dts
@@ -14,7 +14,6 @@
 /dts-v1/;
 /plugin/;
 
-#include <dt-bindings/clock/msm-clocks-8952.h>
 #include "msm8917-qrd.dtsi"
 
 / {
diff --git a/arch/arm64/boot/dts/qcom/msm8917-qrd.dtsi b/arch/arm64/boot/dts/qcom/msm8917-qrd.dtsi
index d5fd1ff..5c63ed3 100644
--- a/arch/arm64/boot/dts/qcom/msm8917-qrd.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8917-qrd.dtsi
@@ -10,6 +10,7 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
+#include <dt-bindings/clock/msm-clocks-8952.h>
 #include "msm8917-camera-sensor-qrd.dtsi"
 #include "msm8937-mdss-panels.dtsi"
 
@@ -19,6 +20,39 @@
 	pinctrl-0 = <&uart_console_active>;
 };
 
+&pm8937_gpios {
+	nfc_clk {
+		nfc_clk_default: nfc_clk_default {
+			pins = "gpio5";
+			function = "normal";
+			input-enable;
+			power-source = <1>;
+		};
+	};
+};
+
+&i2c_5 { /* BLSP2 QUP1 (NFC) */
+	status = "ok";
+	nq@28 {
+		compatible = "qcom,nq-nci";
+		reg = <0x28>;
+		qcom,nq-irq = <&tlmm 17 0x00>;
+		qcom,nq-ven = <&tlmm 16 0x00>;
+		qcom,nq-firm = <&tlmm 130 0x00>;
+		qcom,nq-clkreq = <&pm8937_gpios 5 0x00>;
+		interrupt-parent = <&tlmm>;
+		qcom,clk-src = "BBCLK2";
+		interrupts = <17 0>;
+		interrupt-names = "nfc_irq";
+		pinctrl-names = "nfc_active", "nfc_suspend";
+		pinctrl-0 = <&nfc_int_active &nfc_disable_active
+						&nfc_clk_default>;
+		pinctrl-1 = <&nfc_int_suspend &nfc_disable_suspend>;
+		clocks = <&clock_gcc clk_bb_clk2_pin>;
+		clock-names = "ref_clk";
+	};
+};
+
 &sdhc_1 {
 	/* device core power supply */
 	vdd-supply = <&pm8937_l8>;
diff --git a/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi b/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi
index 7bc181c..be6ab79 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi
@@ -26,6 +26,7 @@
 #include "dsi-panel-hx8399c-fhd-plus-video.dtsi"
 #include "dsi-panel-hx83100a-800p-video.dtsi"
 #include "dsi-panel-boent51021-1200p-video.dtsi"
+#include "dsi-panel-hx8394d-wxga-video.dtsi"
 
 &soc {
 	dsi_panel_pwr_supply: dsi_panel_pwr_supply {
@@ -184,3 +185,11 @@
 		25 20 08 0a 06 03 04 a0
 		25 1d 08 0a 06 03 04 a0];
 };
+
+&dsi_hx8394d_kingdisplay_vid {
+    qcom,mdss-dsi-panel-timings-phy-v2 = [1c 19 02 03 01 03 04 a0
+        1c 19 02 03 01 03 04 a0
+        1c 19 02 03 01 03 04 a0
+        1c 19 02 03 01 03 04 a0
+        1c 07 02 03 01 03 04 a0];
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi
index 65b2397..c58d82e 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi
@@ -1461,6 +1461,103 @@
 		};
 
 		/* add pingrp for touchscreen */
+		ts_int_default: ts_int_default {
+			mux {
+				pins = "gpio65";
+				function = "gpio";
+			};
+			config {
+				pins = "gpio65";
+				drive-strength = <16>;
+				/*bias-pull-up;*/
+				input-enable;
+				bias-disable;
+			};
+		};
+
+		ts_int_output_high: ts_int_output_high {
+			mux {
+				pins = "gpio65";
+				function = "gpio";
+			};
+			config {
+				pins = "gpio65";
+				output-high;
+			};
+		};
+
+		ts_int_output_low: ts_int_output_low {
+			mux {
+				pins = "gpio65";
+				function = "gpio";
+			};
+			config {
+				pins = "gpio65";
+				output-low;
+			};
+		};
+
+		ts_int_input: ts_int_input {
+			mux {
+				pins = "gpio65";
+				function = "gpio";
+			};
+			config {
+				pins = "gpio65";
+				input-enable;
+				bias-disable;
+			};
+		};
+
+		ts_rst_default: ts_rst_default {
+			mux {
+				pins = "gpio64";
+				function = "gpio";
+			};
+			config {
+				pins = "gpio64";
+				drive-strength = <16>;
+				/*bias-pull-up;*/
+				input-enable;
+				bias-disable;
+			};
+		};
+
+		ts_rst_output_high: ts_rst_output_high {
+			mux {
+				pins = "gpio64";
+				function = "gpio";
+			};
+			config {
+				pins = "gpio64";
+				output-high;
+			};
+		};
+
+		ts_rst_output_low: ts_rst_output_low {
+			mux {
+				pins = "gpio64";
+				function = "gpio";
+			};
+			config {
+				pins = "gpio64";
+				output-low;
+			};
+		};
+
+		ts_rst_input: ts_rst_input {
+			mux {
+				pins = "gpio64";
+				function = "gpio";
+			};
+			config {
+				pins = "gpio64";
+				input-enable;
+				bias-disable;
+			};
+		};
+
+		/* add pingrp for touchscreen */
 		pmx_ts_int_active {
 			ts_int_active: ts_int_active {
 				mux {
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera-audio.dtsi b/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera-audio.dtsi
new file mode 100644
index 0000000..ab82fe6
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera-audio.dtsi
@@ -0,0 +1,360 @@
+/*
+ * 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.
+ */
+#include "sdm670-wcd.dtsi"
+#include "sdm670-wsa881x.dtsi"
+#include "sdm670-lpi.dtsi"
+#include <dt-bindings/clock/qcom,audio-ext-clk.h>
+
+&tavil_snd {
+	qcom,msm-mi2s-master = <1>, <1>, <1>, <1>, <1>;
+	qcom,audio-routing =
+		"AIF4 VI", "MCLK",
+		"RX_BIAS", "MCLK",
+		"MADINPUT", "MCLK",
+		"hifi amp", "LINEOUT1",
+		"hifi amp", "LINEOUT2",
+		"AMIC2", "MIC BIAS2",
+		"MIC BIAS2", "Headset Mic",
+		"AMIC3", "MIC BIAS2",
+		"MIC BIAS2", "ANCRight Headset Mic",
+		"AMIC4", "MIC BIAS2",
+		"MIC BIAS2", "ANCLeft Headset Mic",
+		"AMIC5", "MIC BIAS3",
+		"MIC BIAS3", "Handset Mic",
+		"DMIC0", "MIC BIAS1",
+		"MIC BIAS1", "Digital Mic0",
+		"DMIC1", "MIC BIAS1",
+		"MIC BIAS1", "Digital Mic1",
+		"DMIC2", "MIC BIAS3",
+		"MIC BIAS3", "Digital Mic2",
+		"DMIC3", "MIC BIAS3",
+		"MIC BIAS3", "Digital Mic3",
+		"DMIC4", "MIC BIAS4",
+		"MIC BIAS4", "Digital Mic4",
+		"DMIC5", "MIC BIAS4",
+		"MIC BIAS4", "Digital Mic5",
+		"SpkrLeft IN", "SPK1 OUT",
+		"SpkrRight IN", "SPK2 OUT";
+
+	qcom,msm-mbhc-hphl-swh = <1>;
+	qcom,msm-mbhc-gnd-swh = <1>;
+	qcom,hph-en0-gpio = <&tavil_hph_en0>;
+	qcom,hph-en1-gpio = <&tavil_hph_en1>;
+	qcom,msm-mclk-freq = <9600000>;
+	asoc-codec = <&stub_codec>, <&ext_disp_audio_codec>;
+	asoc-codec-names = "msm-stub-codec.1", "msm-ext-disp-audio-codec-rx";
+	qcom,wsa-max-devs = <2>;
+	qcom,wsa-devs = <&wsa881x_0211>, <&wsa881x_0212>,
+		<&wsa881x_0213>, <&wsa881x_0214>;
+	qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight",
+		"SpkrLeft", "SpkrRight";
+};
+
+&tasha_snd {
+	qcom,msm-mi2s-master = <1>, <1>, <1>, <1>, <1>;
+	qcom,audio-routing =
+		"AIF4 VI", "MCLK",
+		"RX_BIAS", "MCLK",
+		"MADINPUT", "MCLK",
+		"hifi amp", "LINEOUT1",
+		"hifi amp", "LINEOUT2",
+		"AMIC2", "MIC BIAS2",
+		"MIC BIAS2", "Headset Mic",
+		"AMIC3", "MIC BIAS2",
+		"MIC BIAS2", "ANCRight Headset Mic",
+		"AMIC4", "MIC BIAS2",
+		"MIC BIAS2", "ANCLeft Headset Mic",
+		"AMIC5", "MIC BIAS3",
+		"MIC BIAS3", "Handset Mic",
+		"DMIC0", "MIC BIAS1",
+		"MIC BIAS1", "Digital Mic0",
+		"DMIC1", "MIC BIAS1",
+		"MIC BIAS1", "Digital Mic1",
+		"DMIC2", "MIC BIAS3",
+		"MIC BIAS3", "Digital Mic2",
+		"DMIC3", "MIC BIAS3",
+		"MIC BIAS3", "Digital Mic3",
+		"DMIC4", "MIC BIAS4",
+		"MIC BIAS4", "Digital Mic4",
+		"DMIC5", "MIC BIAS4",
+		"MIC BIAS4", "Digital Mic5",
+		"SpkrLeft IN", "SPK1 OUT",
+		"SpkrRight IN", "SPK2 OUT";
+
+	qcom,msm-mbhc-hphl-swh = <0>;
+	qcom,msm-mbhc-gnd-swh = <0>;
+	qcom,msm-mclk-freq = <9600000>;
+	asoc-codec = <&stub_codec>;
+	asoc-codec-names = "msm-stub-codec.1";
+	qcom,wsa-max-devs = <2>;
+	qcom,wsa-devs = <&wsa881x_211>, <&wsa881x_212>,
+		<&wsa881x_213>, <&wsa881x_214>;
+	qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight",
+		"SpkrLeft", "SpkrRight";
+};
+
+&soc {
+	wcd_usbc_analog_en1_gpio: msm_cdc_pinctrl_usbc_audio_en1 {
+		compatible = "qcom,msm-cdc-pinctrl";
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&wcd_usbc_analog_en1_active>;
+		pinctrl-1 = <&wcd_usbc_analog_en1_idle>;
+	};
+
+	cdc_pdm_gpios: cdc_pdm_pinctrl {
+		compatible = "qcom,msm-cdc-pinctrl";
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&cdc_pdm_clk_active &cdc_pdm_sync_active
+			     &cdc_pdm_rx0_active &cdc_pdm_rx1_2_active
+			     &cdc_pdm_2_gpios_active>;
+		pinctrl-1 = <&cdc_pdm_clk_sleep &cdc_pdm_sync_sleep
+			     &cdc_pdm_rx0_sleep &cdc_pdm_rx1_2_sleep
+			     &cdc_pdm_2_gpios_sleep>;
+		qcom,lpi-gpios;
+	};
+
+	cdc_comp_gpios: cdc_comp_pinctrl {
+		compatible = "qcom,msm-cdc-pinctrl";
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&cdc_rx0_comp_active &cdc_rx1_comp_active>;
+		pinctrl-1 = <&cdc_rx0_comp_sleep &cdc_rx1_comp_sleep>;
+		qcom,lpi-gpios;
+	};
+
+	cdc_dmic_gpios: cdc_dmic_pinctrl {
+		compatible = "qcom,msm-cdc-pinctrl";
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&cdc_dmic12_gpios_active
+			     &cdc_dmic34_gpios_active>;
+		pinctrl-1 = <&cdc_dmic12_gpios_sleep
+			     &cdc_dmic34_gpios_sleep>;
+		qcom,lpi-gpios;
+	};
+
+	cdc_sdw_gpios: sdw_clk_data_pinctrl {
+		compatible = "qcom,msm-cdc-pinctrl";
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&sdw_clk_active &sdw_data_active>;
+		pinctrl-1 = <&sdw_clk_sleep &sdw_data_sleep>;
+	};
+
+	wsa_spkr_en1: wsa_spkr_en1_pinctrl {
+		compatible = "qcom,msm-cdc-pinctrl";
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&spkr_1_sd_n_active>;
+		pinctrl-1 = <&spkr_1_sd_n_sleep>;
+	};
+
+	wsa_spkr_en2: wsa_spkr_en2_pinctrl {
+		compatible = "qcom,msm-cdc-pinctrl";
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&spkr_2_sd_n_active>;
+		pinctrl-1 = <&spkr_2_sd_n_sleep>;
+	};
+
+	msm_sdw_codec: msm-sdw-codec@62ec1000 {
+		status = "okay";
+		compatible = "qcom,msm-sdw-codec";
+		reg = <0x62ec1000 0x0>;
+		interrupts = <0 88 0>;
+		interrupt-names = "swr_master_irq";
+		qcom,cdc-sdw-gpios = <&cdc_sdw_gpios>;
+
+		swr_master {
+			compatible = "qcom,swr-wcd";
+			#address-cells = <2>;
+			#size-cells = <0>;
+
+			wsa881x_211_en: wsa881x_en@20170211 {
+				compatible = "qcom,wsa881x";
+				reg = <0x0 0x20170211>;
+				qcom,spkr-sd-n-node = <&wsa_spkr_en1>;
+			};
+
+			wsa881x_212_en: wsa881x_en@20170212 {
+				compatible = "qcom,wsa881x";
+				reg = <0x0 0x20170212>;
+				qcom,spkr-sd-n-node = <&wsa_spkr_en2>;
+			};
+
+			wsa881x_213_en: wsa881x_en@21170213 {
+				compatible = "qcom,wsa881x";
+				reg = <0x0 0x21170213>;
+				qcom,spkr-sd-n-node = <&wsa_spkr_en1>;
+			};
+
+			wsa881x_214_en: wsa881x_en@21170214 {
+				compatible = "qcom,wsa881x";
+				reg = <0x0 0x21170214>;
+				qcom,spkr-sd-n-node = <&wsa_spkr_en2>;
+			};
+		};
+	};
+
+	wcd9xxx_intc: wcd9xxx-irq {
+		status = "disabled";
+		compatible = "qcom,wcd9xxx-irq";
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		interrupt-parent = <&tlmm>;
+		qcom,gpio-connect = <&tlmm 80 0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&wcd_intr_default>;
+	};
+
+	clock_audio_native: audio_ext_clk_native {
+		status = "disabled";
+		compatible = "qcom,audio-ref-clk";
+		#clock-cells = <1>;
+		qcom,lpass-mclk-id = <0x116>;
+		qcom,codec-mclk-clk-freq = <11289600>;
+		qcom,audio-ref-clk-gpio = <&lpi_tlmm 19 0>;
+		pinctrl-names = "sleep", "active";
+		pinctrl-0 = <&lpi_mclk0_sleep>;
+		pinctrl-1 = <&lpi_mclk0_active>;
+	};
+
+	clock_audio: audio_ext_clk {
+		status = "disabled";
+		compatible = "qcom,audio-ref-clk";
+		pinctrl-names = "active", "sleep";
+		pinctrl-0 = <&tasha_mclk_default>;
+		pinctrl-1 = <&tasha_mclk_default>;
+		qcom,audio-ref-clk-gpio = <&pm660_gpios 3 0>;
+		clock-names = "osr_clk";
+		clocks = <&pm660_div_clk>;
+		qcom,node_has_rpm_clock;
+		#clock-cells = <1>;
+	};
+
+	clock_audio_lnbb: audio_ext_clk_lnbb {
+		status = "disabled";
+		compatible = "qcom,audio-ref-clk";
+		clock-names = "osr_clk";
+		clocks = <&clock_rpmh RPMH_LN_BB_CLK2>;
+		qcom,node_has_rpm_clock;
+		#clock-cells = <1>;
+	};
+
+	wcd_rst_gpio: msm_cdc_pinctrl@64 {
+		status = "disabled";
+		compatible = "qcom,msm-cdc-pinctrl";
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&lpi_cdc_reset_active>;
+		pinctrl-1 = <&lpi_cdc_reset_sleep>;
+		qcom,lpi-gpios;
+	};
+
+	wdsp_mgr: qcom,wcd-dsp-mgr {
+		compatible = "qcom,wcd-dsp-mgr";
+		qcom,wdsp-components = <&wcd934x_cdc 0>,
+				       <&wcd_spi_0 1>,
+				       <&glink_spi_xprt_wdsp 2>;
+					qcom,img-filename = "cpe_9340";
+	};
+
+	wdsp_glink: qcom,wcd-dsp-glink {
+		compatible = "qcom,wcd-dsp-glink";
+	};
+
+	tert_mi2s_gpios: tert_mi2s_pinctrl {
+		status = "disabled";
+		compatible = "qcom,msm-cdc-pinctrl";
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&ter_i2s_data0_active &ter_i2s_data1_active
+			     &ter_i2s_sck_active>;
+		pinctrl-1 = <&ter_i2s_data0_sleep &ter_i2s_data1_sleep
+			     &ter_i2s_sck_sleep>;
+	};
+};
+
+&slim_aud {
+	wcd9335: tasha_codec {
+		status = "disabled";
+		compatible = "qcom,tasha-slim-pgd";
+		elemental-addr = [00 01 a0 01 17 02];
+
+		interrupt-parent = <&wcd9xxx_intc>;
+		interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+		      17 18 19 20 21 22 23 24 25 26 27 28 29
+		      30>;
+
+		qcom,wcd-rst-gpio-node = <&wcd_rst_gpio>;
+
+		clock-names = "wcd_clk", "wcd_native_clk";
+		clocks = <&clock_audio AUDIO_PMI_CLK>,
+			 <&clock_audio_native AUDIO_LPASS_MCLK>;
+
+		cdc-vdd-mic-bias-supply = <&pm660l_bob>;
+		qcom,cdc-vdd-mic-bias-voltage = <3312000 3312000>;
+		qcom,cdc-vdd-mic-bias-current = <30400>;
+
+		qcom,cdc-static-supplies = "cdc-vdd-mic-bias";
+
+		qcom,cdc-micbias1-mv = <1800>;
+		qcom,cdc-micbias2-mv = <1800>;
+		qcom,cdc-micbias3-mv = <1800>;
+		qcom,cdc-micbias4-mv = <1800>;
+
+		qcom,cdc-mclk-clk-rate = <9600000>;
+		qcom,cdc-slim-ifd = "tasha-slim-ifd";
+		qcom,cdc-slim-ifd-elemental-addr = [00 00 a0 01 17 02];
+		qcom,cdc-dmic-sample-rate = <4800000>;
+		qcom,cdc-mad-dmic-rate = <600000>;
+	};
+
+	wcd934x_cdc: tavil_codec {
+		status = "disabled";
+		compatible = "qcom,tavil-slim-pgd";
+		elemental-addr = [00 01 50 02 17 02];
+
+		interrupt-parent = <&wcd9xxx_intc>;
+		interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+			      17 18 19 20 21 22 23 24 25 26 27 28 29
+			      30 31>;
+
+		qcom,wcd-rst-gpio-node = <&wcd_rst_gpio>;
+
+		clock-names = "wcd_clk";
+		clocks = <&clock_audio_lnbb AUDIO_PMIC_LNBB_CLK>;
+
+		cdc-vdd-mic-bias-supply = <&pm660l_bob>;
+		qcom,cdc-vdd-mic-bias-voltage = <3312000 3312000>;
+		qcom,cdc-vdd-mic-bias-current = <30400>;
+
+		qcom,cdc-static-supplies = "cdc-vdd-mic-bias";
+
+		qcom,cdc-micbias1-mv = <1800>;
+		qcom,cdc-micbias2-mv = <1800>;
+		qcom,cdc-micbias3-mv = <1800>;
+		qcom,cdc-micbias4-mv = <1800>;
+
+		qcom,cdc-mclk-clk-rate = <9600000>;
+		qcom,cdc-slim-ifd = "tavil-slim-ifd";
+		qcom,cdc-slim-ifd-elemental-addr = [00 00 50 02 17 02];
+		qcom,cdc-dmic-sample-rate = <4800000>;
+		qcom,cdc-mad-dmic-rate = <600000>;
+
+		qcom,wdsp-cmpnt-dev-name = "tavil_codec";
+
+		wcd_spi_0: wcd_spi {
+			compatible = "qcom,wcd-spi-v2";
+			qcom,master-bus-num = <0>;
+			qcom,chip-select = <0>;
+			qcom,max-frequency = <24000000>;
+			qcom,mem-base-addr = <0x100000>;
+		};
+	};
+};
+
+
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera-overlay.dts b/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera-overlay.dts
new file mode 100644
index 0000000..c7912d6
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera-overlay.dts
@@ -0,0 +1,30 @@
+/*
+ * 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 "qcs605-lc-ipcamera.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. QC605 LC Groot + PM8005 IPC";
+	compatible = "qcom,qcs605-mtp", "qcom,qcs605", "qcom,mtp";
+	qcom,msm-id = <347 0x0>;
+	qcom,board-id = <8 6>;
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera.dts b/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera.dts
new file mode 100644
index 0000000..90dcd7b
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera.dts
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "qcs605-lc.dtsi"
+#include "qcs605-lc-ipcamera.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. QC605 LC Groot + PM8005 IPC";
+	compatible = "qcom,qcs605-mtp", "qcom,qcs605", "qcom,mtp";
+	qcom,board-id = <8 6>;
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera.dtsi b/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera.dtsi
new file mode 100644
index 0000000..d6d9a17
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-ipcamera.dtsi
@@ -0,0 +1,196 @@
+/* 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.
+ */
+
+#include "qcs605-lc-pmic-overlay.dtsi"
+#include "qcs605-lc-camera-sensor-mtp.dtsi"
+#include "qcs605-lc-ipcamera-audio.dtsi"
+
+&qupv3_se9_2uart {
+	status = "disabled";
+};
+
+&qupv3_se12_2uart {
+	status = "ok";
+};
+
+&sdhc_1 {
+	vdd-supply = <&pm660_l19>;
+	qcom,vdd-voltage-level = <2960000 2960000>;
+	qcom,vdd-current-level = <0 570000>;
+
+	vdd-io-supply = <&pm660_l8>;
+	qcom,vdd-io-always-on;
+	qcom,vdd-io-lpm-sup;
+	qcom,vdd-io-voltage-level = <1800000 1800000>;
+	qcom,vdd-io-current-level = <0 325000>;
+
+	pinctrl-names = "active", "sleep";
+	pinctrl-0 = <&sdc1_clk_on  &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>;
+	pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>;
+
+	status = "ok";
+};
+
+&tlmm {
+	sdc2_cd_on: cd_on {
+		mux {
+			pins = "gpio116";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio116";
+			drive-strength = <2>;
+			bias-pull-up;
+			};
+		};
+
+	sdc2_cd_off: cd_off {
+		mux {
+			pins = "gpio116";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio116";
+			drive-strength = <2>;
+			bias-disable;
+			};
+	};
+};
+
+&sdhc_2 {
+	/* VDD external regulator is enabled/disabled by pm660_l18 regulator */
+	vdd-io-supply = <&pm660_l18>;
+	qcom,vdd-io-voltage-level = <1800000 2960000>;
+	qcom,vdd-io-current-level = <0 22000>;
+
+	pinctrl-names = "active", "sleep";
+	pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
+	pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+
+	cd-gpios = <&tlmm 116 0x1>;
+
+	status = "ok";
+};
+
+&usb0 {
+	dwc3@a600000 {
+		dr_mode = "host";
+	};
+};
+
+&icnss {
+	status = "disabled";
+};
+
+&msm_sdw_codec {
+	status = "disabled";
+};
+
+&cdc_pdm_gpios {
+	status = "disabled";
+};
+
+&cdc_comp_gpios {
+	status = "disabled";
+};
+
+&cdc_dmic_gpios {
+	status = "disabled";
+};
+
+&cdc_sdw_gpios {
+	status = "disabled";
+};
+
+&wsa_spkr_en1 {
+	status = "disabled";
+};
+
+&wsa_spkr_en2 {
+	status = "disabled";
+};
+
+&qupv3_se8_spi {
+	status = "okay";
+};
+
+&wcd9xxx_intc {
+	status = "okay";
+};
+
+&wdsp_mgr {
+	status = "okay";
+};
+
+&wdsp_glink {
+	status = "okay";
+};
+
+&slim_aud {
+	status = "okay";
+};
+
+&dai_slim {
+	status = "okay";
+};
+
+&wcd934x_cdc {
+	status = "okay";
+};
+
+&clock_audio_lnbb {
+	status = "okay";
+};
+
+&tavil_snd {
+	status = "okay";
+	compatible = "qcom,qcs605-asoc-snd-tavil";
+	qcom,model = "qcs605-tavil-snd-card";
+	qcom,audio-routing =
+		"AIF4 VI", "MCLK",
+		"RX_BIAS", "MCLK",
+		"MADINPUT", "MCLK",
+		"DMIC0", "MIC BIAS1",
+		"MIC BIAS1", "Digital Mic0",
+		"DMIC1", "MIC BIAS1",
+		"MIC BIAS1", "Digital Mic1",
+		"DMIC2", "MIC BIAS3",
+		"MIC BIAS3", "Digital Mic2",
+		"DMIC3", "MIC BIAS3",
+		"MIC BIAS3", "Digital Mic3",
+		"SpkrLeft IN", "SPK1 OUT";
+	qcom,wsa-max-devs = <1>;
+	qcom,wsa-devs = <&wsa881x_0211>, <&wsa881x_0213>;
+	qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrLeft";
+};
+
+&soc {
+	wcd_rst_gpio1: msm_cdc_pinctrl@11 {
+		compatible = "qcom,msm-cdc-pinctrl";
+		qcom,cdc-rst-n-gpio = <&tlmm 11 0>;
+		pinctrl-names = "aud_active", "aud_sleep";
+		pinctrl-0 = <&cdc_reset_active>;
+		pinctrl-1 = <&cdc_reset_sleep>;
+	};
+};
+
+&wcd934x_cdc {
+	/delete-property/ cdc-vdd-mic-bias-supply;
+	/delete-property/ qcom,cdc-static-supplies;
+	qcom,wcd-rst-gpio-node = <&wcd_rst_gpio1>;
+};
+
+&wcd9335 {
+	/delete-property/ cdc-vdd-mic-bias-supply;
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs605.dtsi b/arch/arm64/boot/dts/qcom/qcs605.dtsi
index 61a812c..61ea299 100644
--- a/arch/arm64/boot/dts/qcom/qcs605.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs605.dtsi
@@ -76,6 +76,10 @@
 	};
 };
 
+&llcc {
+	compatible = "qcom,qcs605-llcc";
+};
+
 &ipa_hw {
 	status = "disabled";
 };
diff --git a/arch/arm64/boot/dts/qcom/sdm429.dtsi b/arch/arm64/boot/dts/qcom/sdm429.dtsi
index 77da1f3..65f7b5e 100644
--- a/arch/arm64/boot/dts/qcom/sdm429.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm429.dtsi
@@ -69,8 +69,8 @@
 		target-dev = <&cpubw>;
 		cpu-to-dev-map =
 			<  960000  2929 >,
-			< 1305600  5126 >,
-			< 1497600  5859 >,
+			< 1305600  5053 >,
+			< 1497600  5712 >,
 			< 1708800  6445 >,
 			< 1804800  7104 >,
 			< 1958400  7104 >;
@@ -91,7 +91,7 @@
 			target-dev = <&mincpubw>;
 			cpu-to-dev-map =
 				< 1305600 2929 >,
-				< 1804800 5859 >;
+				< 1804800 5712 >;
 		};
 	};
 };
diff --git a/arch/arm64/boot/dts/qcom/sdm439.dtsi b/arch/arm64/boot/dts/qcom/sdm439.dtsi
index be05b6e..9067bc9 100644
--- a/arch/arm64/boot/dts/qcom/sdm439.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm439.dtsi
@@ -78,9 +78,9 @@
 			<  2929 /*  384   MHz */ >,     /* SVS */
 			<  3221 /*  422.4 MHz */ >,
 			<  4248 /*  556.8 MHz */ >,
-			<  5126 /*  662.4 MHz */ >,     /* SVS+  */
-			<  5859 /*  748.8 MHz */ >,     /* NOM   */
-			<  6152 /*  806.4 MHz */ >,     /* NOM+  */
+			<  5053 /*  662.4 MHz */ >,     /* SVS+  */
+			<  5712 /*  748.8 MHz */ >,     /* NOM   */
+			<  6079 /*  796.8 MHz */ >,     /* NOM+  */
 			<  6445 /*  844.8 MHz */ >,
 			<  7104 /*  931.2 MHz */ >;     /* TURBO */
 	};
@@ -98,9 +98,9 @@
 			<  2929 /*  384   MHz */ >,     /* SVS */
 			<  3221 /*  422.4 MHz */ >,
 			<  4248 /*  556.8 MHz */ >,
-			<  5126 /*  662.4 MHz */ >,     /* SVS+  */
-			<  5859 /*  748.8 MHz */ >,     /* NOM   */
-			<  6152 /*  806.4 MHz */ >,     /* NOM+  */
+			<  5053 /*  662.4 MHz */ >,     /* SVS+  */
+			<  5712 /*  748.8 MHz */ >,     /* NOM   */
+			<  6079 /*  796.8 MHz */ >,     /* NOM+  */
 			<  6445 /*  844.8 MHz */ >,
 			<  7104 /*  931.2 MHz */ >;     /* TURBO */
 	};
@@ -124,16 +124,16 @@
 		cpubw-cpufreq {
 		target-dev = <&cpubw>;
 		cpu-to-dev-map-0 =
-			< 1305600  5126 >,
-			< 1497600  5859 >,
+			< 1305600  5053 >,
+			< 1497600  5712 >,
 			< 1708800  6445 >,
 			< 1804800  7104 >,
 			< 1958400  7104 >;
 		cpu-to-dev-map-4 =
 			<  768000  2929 >,
-			<  998400  5126 >,
-			< 1171200  5859 >,
-			< 1305600  6152 >,
+			<  998400  5053 >,
+			< 1171200  5712 >,
+			< 1305600  6079 >,
 			< 1459200  7104 >;
 
 		};
@@ -158,10 +158,10 @@
 			target-dev = <&mincpubw>;
 			cpu-to-dev-map-0 =
 				< 1305600 2929 >,
-				< 1804800 5859 >;
+				< 1804800 5712 >;
 			cpu-to-dev-map-4 =
 				< 1171200 2929 >,
-				< 1459200 5859 >;
+				< 1459200 5712 >;
 		};
 	};
 };
diff --git a/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-360camera.dtsi b/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-360camera.dtsi
index c40fff6..1cfa3ae 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-360camera.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-360camera.dtsi
@@ -1,5 +1,5 @@
 /*
- * 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
@@ -189,7 +189,7 @@
 	rgltr-cntrl-support;
 	rgltr-min-voltage = <1352000 1800000 2850000 0 2800000>;
 	rgltr-max-voltage = <1352000 1800000 2850000 0 2800000>;
-	rgltr-load-current = <105000 0 80000 0>;
+	rgltr-load-current = <105000 0 80000 0 0>;
 	gpio-no-mux = <0>;
 	pinctrl-names = "cam_default", "cam_suspend";
 	pinctrl-0 = <&cam_sensor_mclk1_active
@@ -226,7 +226,7 @@
 	rgltr-cntrl-support;
 	rgltr-min-voltage = <1800000 2850000 1352000 0 2800000>;
 	rgltr-max-voltage = <1800000 2850000 1352000 0 2800000>;
-	rgltr-load-current = <0 80000 105000 0>;
+	rgltr-load-current = <0 80000 105000 0 0>;
 	gpio-no-mux = <0>;
 	pinctrl-names = "cam_default", "cam_suspend";
 	pinctrl-0 = <&cam_sensor_mclk2_active
diff --git a/arch/arm64/boot/dts/qcom/sdm670-ion.dtsi b/arch/arm64/boot/dts/qcom/sdm670-ion.dtsi
index 3fd1229..0968a52 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-ion.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-ion.dtsi
@@ -49,5 +49,12 @@
 			reg = <9>;
 			qcom,ion-heap-type = "SYSTEM_SECURE";
 		};
+
+		qcom,ion-heap@22 { /* ADSP HEAP */
+			reg = <22>;
+			memory-region = <&sdsp_mem>;
+			qcom,ion-heap-type = "DMA";
+		};
+
 	};
 };
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
index 0461429..0453cee 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
@@ -1490,6 +1490,34 @@
 			};
 		};
 
+		cdc_reset_ctrl {
+			cdc_reset_sleep: cdc_reset_sleep {
+				mux {
+					pins = "gpio11";
+					function = "gpio";
+				};
+				config {
+					pins = "gpio11";
+					drive-strength = <2>;
+					bias-disable;
+					output-low;
+				};
+			};
+
+			cdc_reset_active:cdc_reset_active {
+				mux {
+					pins = "gpio11";
+					function = "gpio";
+				};
+				config {
+					pins = "gpio11";
+					drive-strength = <8>;
+					bias-pull-down;
+					output-high;
+				};
+			};
+		};
+
 		/* WSA speaker reset pins */
 		spkr_1_sd_n {
 			spkr_1_sd_n_sleep: spkr_1_sd_n_sleep {
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 575e448..bb07c04 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -560,7 +560,15 @@
 			alloc-ranges = <0 0x00000000 0 0xffffffff>;
 			reusable;
 			alignment = <0 0x400000>;
-			size = <0 0xc00000>;
+			size = <0 0x800000>;
+		};
+
+		sdsp_mem: sdsp_region {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0 0x00000000 0 0xffffffff>;
+			reusable;
+			alignment = <0 0x400000>;
+			size = <0 0x400000>;
 		};
 
 		qseecom_ta_mem: qseecom_ta_region {
diff --git a/arch/arm64/configs/sdm670-perf_defconfig b/arch/arm64/configs/sdm670-perf_defconfig
index 6740bd7..ac21b63 100644
--- a/arch/arm64/configs/sdm670-perf_defconfig
+++ b/arch/arm64/configs/sdm670-perf_defconfig
@@ -513,6 +513,7 @@
 CONFIG_QCOM_RUN_QUEUE_STATS=y
 CONFIG_QCOM_LLCC=y
 CONFIG_QCOM_SDM670_LLCC=y
+CONFIG_QCOM_QCS605_LLCC=y
 CONFIG_QCOM_LLCC_PERFMON=m
 CONFIG_MSM_SERVICE_LOCATOR=y
 CONFIG_MSM_SERVICE_NOTIFIER=y
diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig
index 53fb1cd..9a6da1f 100644
--- a/arch/arm64/configs/sdm670_defconfig
+++ b/arch/arm64/configs/sdm670_defconfig
@@ -527,6 +527,7 @@
 CONFIG_QCOM_RUN_QUEUE_STATS=y
 CONFIG_QCOM_LLCC=y
 CONFIG_QCOM_SDM670_LLCC=y
+CONFIG_QCOM_QCS605_LLCC=y
 CONFIG_QCOM_LLCC_PERFMON=m
 CONFIG_MSM_SERVICE_LOCATOR=y
 CONFIG_MSM_SERVICE_NOTIFIER=y
diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h
index 7457ce0..d32a016 100644
--- a/arch/arm64/include/asm/atomic_lse.h
+++ b/arch/arm64/include/asm/atomic_lse.h
@@ -117,7 +117,7 @@
 	/* LSE atomics */
 	"	mvn	%w[i], %w[i]\n"
 	"	stclr	%w[i], %[v]")
-	: [i] "+r" (w0), [v] "+Q" (v->counter)
+	: [i] "+&r" (w0), [v] "+Q" (v->counter)
 	: "r" (x1)
 	: __LL_SC_CLOBBERS);
 }
@@ -135,7 +135,7 @@
 	/* LSE atomics */						\
 	"	mvn	%w[i], %w[i]\n"					\
 	"	ldclr" #mb "	%w[i], %w[i], %[v]")			\
-	: [i] "+r" (w0), [v] "+Q" (v->counter)				\
+	: [i] "+&r" (w0), [v] "+Q" (v->counter)				\
 	: "r" (x1)							\
 	: __LL_SC_CLOBBERS, ##cl);					\
 									\
@@ -161,7 +161,7 @@
 	/* LSE atomics */
 	"	neg	%w[i], %w[i]\n"
 	"	stadd	%w[i], %[v]")
-	: [i] "+r" (w0), [v] "+Q" (v->counter)
+	: [i] "+&r" (w0), [v] "+Q" (v->counter)
 	: "r" (x1)
 	: __LL_SC_CLOBBERS);
 }
@@ -180,7 +180,7 @@
 	"	neg	%w[i], %w[i]\n"					\
 	"	ldadd" #mb "	%w[i], w30, %[v]\n"			\
 	"	add	%w[i], %w[i], w30")				\
-	: [i] "+r" (w0), [v] "+Q" (v->counter)				\
+	: [i] "+&r" (w0), [v] "+Q" (v->counter)				\
 	: "r" (x1)							\
 	: __LL_SC_CLOBBERS , ##cl);					\
 									\
@@ -207,7 +207,7 @@
 	/* LSE atomics */						\
 	"	neg	%w[i], %w[i]\n"					\
 	"	ldadd" #mb "	%w[i], %w[i], %[v]")			\
-	: [i] "+r" (w0), [v] "+Q" (v->counter)				\
+	: [i] "+&r" (w0), [v] "+Q" (v->counter)				\
 	: "r" (x1)							\
 	: __LL_SC_CLOBBERS, ##cl);					\
 									\
@@ -314,7 +314,7 @@
 	/* LSE atomics */
 	"	mvn	%[i], %[i]\n"
 	"	stclr	%[i], %[v]")
-	: [i] "+r" (x0), [v] "+Q" (v->counter)
+	: [i] "+&r" (x0), [v] "+Q" (v->counter)
 	: "r" (x1)
 	: __LL_SC_CLOBBERS);
 }
@@ -332,7 +332,7 @@
 	/* LSE atomics */						\
 	"	mvn	%[i], %[i]\n"					\
 	"	ldclr" #mb "	%[i], %[i], %[v]")			\
-	: [i] "+r" (x0), [v] "+Q" (v->counter)				\
+	: [i] "+&r" (x0), [v] "+Q" (v->counter)				\
 	: "r" (x1)							\
 	: __LL_SC_CLOBBERS, ##cl);					\
 									\
@@ -358,7 +358,7 @@
 	/* LSE atomics */
 	"	neg	%[i], %[i]\n"
 	"	stadd	%[i], %[v]")
-	: [i] "+r" (x0), [v] "+Q" (v->counter)
+	: [i] "+&r" (x0), [v] "+Q" (v->counter)
 	: "r" (x1)
 	: __LL_SC_CLOBBERS);
 }
@@ -377,7 +377,7 @@
 	"	neg	%[i], %[i]\n"					\
 	"	ldadd" #mb "	%[i], x30, %[v]\n"			\
 	"	add	%[i], %[i], x30")				\
-	: [i] "+r" (x0), [v] "+Q" (v->counter)				\
+	: [i] "+&r" (x0), [v] "+Q" (v->counter)				\
 	: "r" (x1)							\
 	: __LL_SC_CLOBBERS, ##cl);					\
 									\
@@ -404,7 +404,7 @@
 	/* LSE atomics */						\
 	"	neg	%[i], %[i]\n"					\
 	"	ldadd" #mb "	%[i], %[i], %[v]")			\
-	: [i] "+r" (x0), [v] "+Q" (v->counter)				\
+	: [i] "+&r" (x0), [v] "+Q" (v->counter)				\
 	: "r" (x1)							\
 	: __LL_SC_CLOBBERS, ##cl);					\
 									\
@@ -516,7 +516,7 @@
 	"	eor	%[old1], %[old1], %[oldval1]\n"			\
 	"	eor	%[old2], %[old2], %[oldval2]\n"			\
 	"	orr	%[old1], %[old1], %[old2]")			\
-	: [old1] "+r" (x0), [old2] "+r" (x1),				\
+	: [old1] "+&r" (x0), [old2] "+&r" (x1),				\
 	  [v] "+Q" (*(unsigned long *)ptr)				\
 	: [new1] "r" (x2), [new2] "r" (x3), [ptr] "r" (x4),		\
 	  [oldval1] "r" (oldval1), [oldval2] "r" (oldval2)		\
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index b3423f5..829331c 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -9,8 +9,6 @@
 #ifndef __ASM_CPUFEATURE_H
 #define __ASM_CPUFEATURE_H
 
-#include <linux/jump_label.h>
-
 #include <asm/cpucaps.h>
 #include <asm/hwcap.h>
 #include <asm/sysreg.h>
@@ -27,6 +25,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <linux/bug.h>
+#include <linux/jump_label.h>
 #include <linux/kernel.h>
 
 extern const char *machine_name;
@@ -98,6 +98,7 @@
 
 extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
 extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS];
+extern struct static_key_false arm64_const_caps_ready;
 
 bool this_cpu_has_cap(unsigned int cap);
 
@@ -106,14 +107,27 @@
 	return elf_hwcap & (1UL << num);
 }
 
+/* System capability check for constant caps */
+static inline bool __cpus_have_const_cap(int num)
+{
+	if (num >= ARM64_NCAPS)
+		return false;
+	return static_branch_unlikely(&cpu_hwcap_keys[num]);
+}
+
 static inline bool cpus_have_cap(unsigned int num)
 {
 	if (num >= ARM64_NCAPS)
 		return false;
-	if (__builtin_constant_p(num))
-		return static_branch_unlikely(&cpu_hwcap_keys[num]);
+	return test_bit(num, cpu_hwcaps);
+}
+
+static inline bool cpus_have_const_cap(int num)
+{
+	if (static_branch_likely(&arm64_const_caps_ready))
+		return __cpus_have_const_cap(num);
 	else
-		return test_bit(num, cpu_hwcaps);
+		return cpus_have_cap(num);
 }
 
 static inline void cpus_set_cap(unsigned int num)
@@ -123,7 +137,6 @@
 			num, ARM64_NCAPS);
 	} else {
 		__set_bit(num, cpu_hwcaps);
-		static_branch_enable(&cpu_hwcap_keys[num]);
 	}
 }
 
@@ -202,7 +215,7 @@
 
 static inline bool system_supports_32bit_el0(void)
 {
-	return cpus_have_cap(ARM64_HAS_32BIT_EL0);
+	return cpus_have_const_cap(ARM64_HAS_32BIT_EL0);
 }
 
 static inline bool system_supports_mixed_endian_el0(void)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 0a33ea3..2abb449 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -24,6 +24,7 @@
 
 #include <linux/types.h>
 #include <linux/kvm_types.h>
+#include <asm/cpufeature.h>
 #include <asm/kvm.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_mmio.h>
@@ -358,9 +359,12 @@
 				       unsigned long vector_ptr)
 {
 	/*
-	 * Call initialization code, and switch to the full blown
-	 * HYP code.
+	 * Call initialization code, and switch to the full blown HYP code.
+	 * If the cpucaps haven't been finalized yet, something has gone very
+	 * wrong, and hyp will crash and burn when it uses any
+	 * cpus_have_const_cap() wrapper.
 	 */
+	BUG_ON(!static_branch_likely(&arm64_const_caps_ready));
 	__kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr);
 }
 
@@ -398,7 +402,7 @@
 
 static inline bool kvm_arm_harden_branch_predictor(void)
 {
-	return cpus_have_cap(ARM64_HARDEN_BRANCH_PREDICTOR);
+	return cpus_have_const_cap(ARM64_HARDEN_BRANCH_PREDICTOR);
 }
 
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 24a8369..ecc2ae6 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -341,7 +341,7 @@
 		vect = __bp_harden_hyp_vecs_start +
 		       data->hyp_vectors_slot * SZ_2K;
 
-		if (!cpus_have_cap(ARM64_HAS_VIRT_HOST_EXTN))
+		if (!cpus_have_const_cap(ARM64_HAS_VIRT_HOST_EXTN))
 			vect = lm_alias(vect);
 	}
 
diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index 24c780d..1464b50 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -38,7 +38,7 @@
 static inline bool arm64_kernel_unmapped_at_el0(void)
 {
 	return IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0) &&
-	       cpus_have_cap(ARM64_UNMAP_KERNEL_AT_EL0);
+	       cpus_have_const_cap(ARM64_UNMAP_KERNEL_AT_EL0);
 }
 
 typedef void (*bp_hardening_cb_t)(void);
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 675bf45..ff62818 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -762,7 +762,7 @@
 	 * ThunderX leads to apparent I-cache corruption of kernel text, which
 	 * ends as well as you might imagine. Don't even try.
 	 */
-	if (cpus_have_cap(ARM64_WORKAROUND_CAVIUM_27456)) {
+	if (cpus_have_const_cap(ARM64_WORKAROUND_CAVIUM_27456)) {
 		str = "ARM64_WORKAROUND_CAVIUM_27456";
 		__kpti_forced = -1;
 	}
@@ -1051,8 +1051,16 @@
  */
 void __init enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps)
 {
-	for (; caps->matches; caps++)
-		if (caps->enable && cpus_have_cap(caps->capability))
+	for (; caps->matches; caps++) {
+		unsigned int num = caps->capability;
+
+		if (!cpus_have_cap(num))
+			continue;
+
+		/* Ensure cpus_have_const_cap(num) works */
+		static_branch_enable(&cpu_hwcap_keys[num]);
+
+		if (caps->enable) {
 			/*
 			 * Use stop_machine() as it schedules the work allowing
 			 * us to modify PSTATE, instead of on_each_cpu() which
@@ -1060,6 +1068,8 @@
 			 * we return.
 			 */
 			stop_machine(caps->enable, (void *)caps, cpu_online_mask);
+		}
+	}
 }
 
 /*
@@ -1163,6 +1173,14 @@
 	enable_cpu_capabilities(arm64_features);
 }
 
+DEFINE_STATIC_KEY_FALSE(arm64_const_caps_ready);
+EXPORT_SYMBOL(arm64_const_caps_ready);
+
+static void __init mark_const_caps_ready(void)
+{
+	static_branch_enable(&arm64_const_caps_ready);
+}
+
 extern const struct arm64_cpu_capabilities arm64_errata[];
 
 bool this_cpu_has_cap(unsigned int cap)
@@ -1179,6 +1197,7 @@
 	/* Set the CPU feature capabilies */
 	setup_feature_capabilities();
 	enable_errata_workarounds();
+	mark_const_caps_ready();
 	setup_elf_hwcaps(arm64_elf_hwcaps);
 
 	if (system_supports_32bit_el0())
@@ -1203,5 +1222,5 @@
 static bool __maybe_unused
 cpufeature_pan_not_uao(const struct arm64_cpu_capabilities *entry, int __unused)
 {
-	return (cpus_have_cap(ARM64_HAS_PAN) && !cpus_have_cap(ARM64_HAS_UAO));
+	return (cpus_have_const_cap(ARM64_HAS_PAN) && !cpus_have_const_cap(ARM64_HAS_UAO));
 }
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 08ca9dc..0a66fa1d 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -360,7 +360,7 @@
 		memset(childregs, 0, sizeof(struct pt_regs));
 		childregs->pstate = PSR_MODE_EL1h;
 		if (IS_ENABLED(CONFIG_ARM64_UAO) &&
-		    cpus_have_cap(ARM64_HAS_UAO))
+		    cpus_have_const_cap(ARM64_HAS_UAO))
 			childregs->pstate |= PSR_UAO_BIT;
 		p->thread.cpu_context.x19 = stack_start;
 		p->thread.cpu_context.x20 = stk_sz;
diff --git a/arch/arm64/mm/ioremap.c b/arch/arm64/mm/ioremap.c
index 01e88c8..8e2c1d6 100644
--- a/arch/arm64/mm/ioremap.c
+++ b/arch/arm64/mm/ioremap.c
@@ -64,6 +64,11 @@
 	addr = (unsigned long)area->addr;
 	area->phys_addr = phys_addr;
 
+#ifdef CONFIG_ARCH_MSM8953_SOC_SETTINGS
+	if (phys_addr >= MSM8953_TLMM_START_ADDR &&
+	    phys_addr <= MSM8953_TLMM_END_ADDR)
+		prot = __pgprot(PROT_DEVICE_nGnRnE);
+#endif
 	err = ioremap_page_range(addr, addr + size, phys_addr, prot);
 	if (err) {
 		vunmap((void *)addr);
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 6e716a5..ebb575c 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -699,6 +699,10 @@
 	if (value & ~known_bits)
 		return -EOPNOTSUPP;
 
+	/* Setting FRE without FR is not supported.  */
+	if ((value & (PR_FP_MODE_FR | PR_FP_MODE_FRE)) == PR_FP_MODE_FRE)
+		return -EOPNOTSUPP;
+
 	/* Avoid inadvertently triggering emulation */
 	if ((value & PR_FP_MODE_FR) && raw_cpu_has_fpu &&
 	    !(raw_current_cpu_data.fpu_id & MIPS_FPIR_F64))
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 8f7bf74..4f64913 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -838,7 +838,7 @@
 				break;
 			}
 #endif
-			tmp = get_fpr32(&fregs[addr - FPR_BASE], 0);
+			tmp = get_fpr64(&fregs[addr - FPR_BASE], 0);
 			break;
 		case PC:
 			tmp = regs->cp0_epc;
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index bc9afba..b1e9457 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -107,7 +107,7 @@
 						addr & 1);
 				break;
 			}
-			tmp = get_fpr32(&fregs[addr - FPR_BASE], 0);
+			tmp = get_fpr64(&fregs[addr - FPR_BASE], 0);
 			break;
 		case PC:
 			tmp = regs->cp0_epc;
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 903e76a..e220010 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -51,6 +51,27 @@
 #define EX_PPR		88	/* SMT thread status register (priority) */
 #define EX_CTR		96
 
+#define STF_ENTRY_BARRIER_SLOT						\
+	STF_ENTRY_BARRIER_FIXUP_SECTION;				\
+	nop;								\
+	nop;								\
+	nop
+
+#define STF_EXIT_BARRIER_SLOT						\
+	STF_EXIT_BARRIER_FIXUP_SECTION;					\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop;								\
+	nop
+
+/*
+ * r10 must be free to use, r13 must be paca
+ */
+#define INTERRUPT_TO_KERNEL						\
+	STF_ENTRY_BARRIER_SLOT
+
 /*
  * Macros for annotating the expected destination of (h)rfid
  *
@@ -67,16 +88,19 @@
 	rfid
 
 #define RFI_TO_USER							\
+	STF_EXIT_BARRIER_SLOT;						\
 	RFI_FLUSH_SLOT;							\
 	rfid;								\
 	b	rfi_flush_fallback
 
 #define RFI_TO_USER_OR_KERNEL						\
+	STF_EXIT_BARRIER_SLOT;						\
 	RFI_FLUSH_SLOT;							\
 	rfid;								\
 	b	rfi_flush_fallback
 
 #define RFI_TO_GUEST							\
+	STF_EXIT_BARRIER_SLOT;						\
 	RFI_FLUSH_SLOT;							\
 	rfid;								\
 	b	rfi_flush_fallback
@@ -85,21 +109,25 @@
 	hrfid
 
 #define HRFI_TO_USER							\
+	STF_EXIT_BARRIER_SLOT;						\
 	RFI_FLUSH_SLOT;							\
 	hrfid;								\
 	b	hrfi_flush_fallback
 
 #define HRFI_TO_USER_OR_KERNEL						\
+	STF_EXIT_BARRIER_SLOT;						\
 	RFI_FLUSH_SLOT;							\
 	hrfid;								\
 	b	hrfi_flush_fallback
 
 #define HRFI_TO_GUEST							\
+	STF_EXIT_BARRIER_SLOT;						\
 	RFI_FLUSH_SLOT;							\
 	hrfid;								\
 	b	hrfi_flush_fallback
 
 #define HRFI_TO_UNKNOWN							\
+	STF_EXIT_BARRIER_SLOT;						\
 	RFI_FLUSH_SLOT;							\
 	hrfid;								\
 	b	hrfi_flush_fallback
@@ -225,6 +253,7 @@
 #define __EXCEPTION_PROLOG_1(area, extra, vec)				\
 	OPT_SAVE_REG_TO_PACA(area+EX_PPR, r9, CPU_FTR_HAS_PPR);		\
 	OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR);		\
+	INTERRUPT_TO_KERNEL;						\
 	SAVE_CTR(r10, area);						\
 	mfcr	r9;							\
 	extra(vec);							\
diff --git a/arch/powerpc/include/asm/feature-fixups.h b/arch/powerpc/include/asm/feature-fixups.h
index 7b33234..0bf8202 100644
--- a/arch/powerpc/include/asm/feature-fixups.h
+++ b/arch/powerpc/include/asm/feature-fixups.h
@@ -189,6 +189,22 @@
 void setup_feature_keys(void);
 #endif
 
+#define STF_ENTRY_BARRIER_FIXUP_SECTION			\
+953:							\
+	.pushsection __stf_entry_barrier_fixup,"a";	\
+	.align 2;					\
+954:							\
+	FTR_ENTRY_OFFSET 953b-954b;			\
+	.popsection;
+
+#define STF_EXIT_BARRIER_FIXUP_SECTION			\
+955:							\
+	.pushsection __stf_exit_barrier_fixup,"a";	\
+	.align 2;					\
+956:							\
+	FTR_ENTRY_OFFSET 955b-956b;			\
+	.popsection;
+
 #define RFI_FLUSH_FIXUP_SECTION				\
 951:							\
 	.pushsection __rfi_flush_fixup,"a";		\
@@ -200,6 +216,9 @@
 
 #ifndef __ASSEMBLY__
 
+extern long stf_barrier_fallback;
+extern long __start___stf_entry_barrier_fixup, __stop___stf_entry_barrier_fixup;
+extern long __start___stf_exit_barrier_fixup, __stop___stf_exit_barrier_fixup;
 extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;
 
 #endif
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index dc0996b..9d97810 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -313,6 +313,9 @@
 #define H_CPU_CHAR_L1D_FLUSH_ORI30	(1ull << 61) // IBM bit 2
 #define H_CPU_CHAR_L1D_FLUSH_TRIG2	(1ull << 60) // IBM bit 3
 #define H_CPU_CHAR_L1D_THREAD_PRIV	(1ull << 59) // IBM bit 4
+#define H_CPU_CHAR_BRANCH_HINTS_HONORED	(1ull << 58) // IBM bit 5
+#define H_CPU_CHAR_THREAD_RECONFIG_CTRL	(1ull << 57) // IBM bit 6
+#define H_CPU_CHAR_COUNT_CACHE_DISABLED	(1ull << 56) // IBM bit 7
 
 #define H_CPU_BEHAV_FAVOUR_SECURITY	(1ull << 63) // IBM bit 0
 #define H_CPU_BEHAV_L1D_FLUSH_PR	(1ull << 62) // IBM bit 1
diff --git a/arch/powerpc/include/asm/security_features.h b/arch/powerpc/include/asm/security_features.h
new file mode 100644
index 0000000..44989b2
--- /dev/null
+++ b/arch/powerpc/include/asm/security_features.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Security related feature bit definitions.
+ *
+ * Copyright 2018, Michael Ellerman, IBM Corporation.
+ */
+
+#ifndef _ASM_POWERPC_SECURITY_FEATURES_H
+#define _ASM_POWERPC_SECURITY_FEATURES_H
+
+
+extern unsigned long powerpc_security_features;
+extern bool rfi_flush;
+
+/* These are bit flags */
+enum stf_barrier_type {
+	STF_BARRIER_NONE	= 0x1,
+	STF_BARRIER_FALLBACK	= 0x2,
+	STF_BARRIER_EIEIO	= 0x4,
+	STF_BARRIER_SYNC_ORI	= 0x8,
+};
+
+void setup_stf_barrier(void);
+void do_stf_barrier_fixups(enum stf_barrier_type types);
+
+static inline void security_ftr_set(unsigned long feature)
+{
+	powerpc_security_features |= feature;
+}
+
+static inline void security_ftr_clear(unsigned long feature)
+{
+	powerpc_security_features &= ~feature;
+}
+
+static inline bool security_ftr_enabled(unsigned long feature)
+{
+	return !!(powerpc_security_features & feature);
+}
+
+
+// Features indicating support for Spectre/Meltdown mitigations
+
+// The L1-D cache can be flushed with ori r30,r30,0
+#define SEC_FTR_L1D_FLUSH_ORI30		0x0000000000000001ull
+
+// The L1-D cache can be flushed with mtspr 882,r0 (aka SPRN_TRIG2)
+#define SEC_FTR_L1D_FLUSH_TRIG2		0x0000000000000002ull
+
+// ori r31,r31,0 acts as a speculation barrier
+#define SEC_FTR_SPEC_BAR_ORI31		0x0000000000000004ull
+
+// Speculation past bctr is disabled
+#define SEC_FTR_BCCTRL_SERIALISED	0x0000000000000008ull
+
+// Entries in L1-D are private to a SMT thread
+#define SEC_FTR_L1D_THREAD_PRIV		0x0000000000000010ull
+
+// Indirect branch prediction cache disabled
+#define SEC_FTR_COUNT_CACHE_DISABLED	0x0000000000000020ull
+
+
+// Features indicating need for Spectre/Meltdown mitigations
+
+// The L1-D cache should be flushed on MSR[HV] 1->0 transition (hypervisor to guest)
+#define SEC_FTR_L1D_FLUSH_HV		0x0000000000000040ull
+
+// The L1-D cache should be flushed on MSR[PR] 0->1 transition (kernel to userspace)
+#define SEC_FTR_L1D_FLUSH_PR		0x0000000000000080ull
+
+// A speculation barrier should be used for bounds checks (Spectre variant 1)
+#define SEC_FTR_BNDS_CHK_SPEC_BAR	0x0000000000000100ull
+
+// Firmware configuration indicates user favours security over performance
+#define SEC_FTR_FAVOUR_SECURITY		0x0000000000000200ull
+
+
+// Features enabled by default
+#define SEC_FTR_DEFAULT \
+	(SEC_FTR_L1D_FLUSH_HV | \
+	 SEC_FTR_L1D_FLUSH_PR | \
+	 SEC_FTR_BNDS_CHK_SPEC_BAR | \
+	 SEC_FTR_FAVOUR_SECURITY)
+
+#endif /* _ASM_POWERPC_SECURITY_FEATURES_H */
diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h
index 6825a67..3f160cd 100644
--- a/arch/powerpc/include/asm/setup.h
+++ b/arch/powerpc/include/asm/setup.h
@@ -48,7 +48,7 @@
 	L1D_FLUSH_MTTRIG	= 0x8,
 };
 
-void __init setup_rfi_flush(enum l1d_flush_type, bool enable);
+void setup_rfi_flush(enum l1d_flush_type, bool enable);
 void do_rfi_flush_fixups(enum l1d_flush_type types);
 
 #endif /* !__ASSEMBLY__ */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index adb52d1..1388578 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -44,7 +44,7 @@
 obj-$(CONFIG_VDSO32)		+= vdso32/
 obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
 obj-$(CONFIG_PPC_BOOK3S_64)	+= cpu_setup_ppc970.o cpu_setup_pa6t.o
-obj-$(CONFIG_PPC_BOOK3S_64)	+= cpu_setup_power.o
+obj-$(CONFIG_PPC_BOOK3S_64)	+= cpu_setup_power.o security.o
 obj-$(CONFIG_PPC_BOOK3S_64)	+= mce.o mce_power.o
 obj-$(CONFIG_PPC_BOOK3E_64)	+= exceptions-64e.o idle_book3e.o
 obj-$(CONFIG_PPC64)		+= vdso64/
diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S
index 9e05c88..ff45d00 100644
--- a/arch/powerpc/kernel/cpu_setup_power.S
+++ b/arch/powerpc/kernel/cpu_setup_power.S
@@ -28,6 +28,7 @@
 	beqlr
 	li	r0,0
 	mtspr	SPRN_LPID,r0
+	mtspr	SPRN_PCR,r0
 	mfspr	r3,SPRN_LPCR
 	bl	__init_LPCR
 	bl	__init_tlb_power7
@@ -41,6 +42,7 @@
 	beqlr
 	li	r0,0
 	mtspr	SPRN_LPID,r0
+	mtspr	SPRN_PCR,r0
 	mfspr	r3,SPRN_LPCR
 	bl	__init_LPCR
 	bl	__init_tlb_power7
@@ -57,6 +59,7 @@
 	beqlr
 	li	r0,0
 	mtspr	SPRN_LPID,r0
+	mtspr	SPRN_PCR,r0
 	mfspr	r3,SPRN_LPCR
 	ori	r3, r3, LPCR_PECEDH
 	bl	__init_LPCR
@@ -78,6 +81,7 @@
 	beqlr
 	li	r0,0
 	mtspr	SPRN_LPID,r0
+	mtspr	SPRN_PCR,r0
 	mfspr   r3,SPRN_LPCR
 	ori	r3, r3, LPCR_PECEDH
 	bl	__init_LPCR
@@ -98,6 +102,7 @@
 	li	r0,0
 	mtspr	SPRN_LPID,r0
 	mtspr	SPRN_PID,r0
+	mtspr	SPRN_PCR,r0
 	mfspr	r3,SPRN_LPCR
 	LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE)
 	or	r3, r3, r4
@@ -121,6 +126,7 @@
 	li	r0,0
 	mtspr	SPRN_LPID,r0
 	mtspr	SPRN_PID,r0
+	mtspr	SPRN_PCR,r0
 	mfspr   r3,SPRN_LPCR
 	LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE)
 	or	r3, r3, r4
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 94b5dfb..d50cc9b 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -846,7 +846,7 @@
 #endif
 
 
-EXC_REAL_MASKABLE(decrementer, 0x900, 0x980)
+EXC_REAL_OOL_MASKABLE(decrementer, 0x900, 0x980)
 EXC_VIRT_MASKABLE(decrementer, 0x4900, 0x4980, 0x900)
 TRAMP_KVM(PACA_EXGEN, 0x900)
 EXC_COMMON_ASYNC(decrementer_common, 0x900, timer_interrupt)
@@ -884,6 +884,7 @@
 END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)				\
 	mr	r9,r13 ;					\
 	GET_PACA(r13) ;						\
+	INTERRUPT_TO_KERNEL ;					\
 	mfspr	r11,SPRN_SRR0 ;					\
 0:
 
@@ -1353,6 +1354,19 @@
 	##_H##RFI_TO_KERNEL;				\
 	b	.
 
+TRAMP_REAL_BEGIN(stf_barrier_fallback)
+	std	r9,PACA_EXRFI+EX_R9(r13)
+	std	r10,PACA_EXRFI+EX_R10(r13)
+	sync
+	ld	r9,PACA_EXRFI+EX_R9(r13)
+	ld	r10,PACA_EXRFI+EX_R10(r13)
+	ori	31,31,0
+	.rept 14
+	b	1f
+1:
+	.endr
+	blr
+
 /*
  * Real mode exceptions actually use this too, but alternate
  * instruction code patches (which end up in the common .text area)
diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c
new file mode 100644
index 0000000..2277df8
--- /dev/null
+++ b/arch/powerpc/kernel/security.c
@@ -0,0 +1,237 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Security related flags and so on.
+//
+// Copyright 2018, Michael Ellerman, IBM Corporation.
+
+#include <linux/kernel.h>
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/seq_buf.h>
+
+#include <asm/security_features.h>
+
+
+unsigned long powerpc_security_features __read_mostly = SEC_FTR_DEFAULT;
+
+ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	bool thread_priv;
+
+	thread_priv = security_ftr_enabled(SEC_FTR_L1D_THREAD_PRIV);
+
+	if (rfi_flush || thread_priv) {
+		struct seq_buf s;
+		seq_buf_init(&s, buf, PAGE_SIZE - 1);
+
+		seq_buf_printf(&s, "Mitigation: ");
+
+		if (rfi_flush)
+			seq_buf_printf(&s, "RFI Flush");
+
+		if (rfi_flush && thread_priv)
+			seq_buf_printf(&s, ", ");
+
+		if (thread_priv)
+			seq_buf_printf(&s, "L1D private per thread");
+
+		seq_buf_printf(&s, "\n");
+
+		return s.len;
+	}
+
+	if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) &&
+	    !security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR))
+		return sprintf(buf, "Not affected\n");
+
+	return sprintf(buf, "Vulnerable\n");
+}
+
+ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	if (!security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR))
+		return sprintf(buf, "Not affected\n");
+
+	return sprintf(buf, "Vulnerable\n");
+}
+
+ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	bool bcs, ccd, ori;
+	struct seq_buf s;
+
+	seq_buf_init(&s, buf, PAGE_SIZE - 1);
+
+	bcs = security_ftr_enabled(SEC_FTR_BCCTRL_SERIALISED);
+	ccd = security_ftr_enabled(SEC_FTR_COUNT_CACHE_DISABLED);
+	ori = security_ftr_enabled(SEC_FTR_SPEC_BAR_ORI31);
+
+	if (bcs || ccd) {
+		seq_buf_printf(&s, "Mitigation: ");
+
+		if (bcs)
+			seq_buf_printf(&s, "Indirect branch serialisation (kernel only)");
+
+		if (bcs && ccd)
+			seq_buf_printf(&s, ", ");
+
+		if (ccd)
+			seq_buf_printf(&s, "Indirect branch cache disabled");
+	} else
+		seq_buf_printf(&s, "Vulnerable");
+
+	if (ori)
+		seq_buf_printf(&s, ", ori31 speculation barrier enabled");
+
+	seq_buf_printf(&s, "\n");
+
+	return s.len;
+}
+
+/*
+ * Store-forwarding barrier support.
+ */
+
+static enum stf_barrier_type stf_enabled_flush_types;
+static bool no_stf_barrier;
+bool stf_barrier;
+
+static int __init handle_no_stf_barrier(char *p)
+{
+	pr_info("stf-barrier: disabled on command line.");
+	no_stf_barrier = true;
+	return 0;
+}
+
+early_param("no_stf_barrier", handle_no_stf_barrier);
+
+/* This is the generic flag used by other architectures */
+static int __init handle_ssbd(char *p)
+{
+	if (!p || strncmp(p, "auto", 5) == 0 || strncmp(p, "on", 2) == 0 ) {
+		/* Until firmware tells us, we have the barrier with auto */
+		return 0;
+	} else if (strncmp(p, "off", 3) == 0) {
+		handle_no_stf_barrier(NULL);
+		return 0;
+	} else
+		return 1;
+
+	return 0;
+}
+early_param("spec_store_bypass_disable", handle_ssbd);
+
+/* This is the generic flag used by other architectures */
+static int __init handle_no_ssbd(char *p)
+{
+	handle_no_stf_barrier(NULL);
+	return 0;
+}
+early_param("nospec_store_bypass_disable", handle_no_ssbd);
+
+static void stf_barrier_enable(bool enable)
+{
+	if (enable)
+		do_stf_barrier_fixups(stf_enabled_flush_types);
+	else
+		do_stf_barrier_fixups(STF_BARRIER_NONE);
+
+	stf_barrier = enable;
+}
+
+void setup_stf_barrier(void)
+{
+	enum stf_barrier_type type;
+	bool enable, hv;
+
+	hv = cpu_has_feature(CPU_FTR_HVMODE);
+
+	/* Default to fallback in case fw-features are not available */
+	if (cpu_has_feature(CPU_FTR_ARCH_300))
+		type = STF_BARRIER_EIEIO;
+	else if (cpu_has_feature(CPU_FTR_ARCH_207S))
+		type = STF_BARRIER_SYNC_ORI;
+	else if (cpu_has_feature(CPU_FTR_ARCH_206))
+		type = STF_BARRIER_FALLBACK;
+	else
+		type = STF_BARRIER_NONE;
+
+	enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) &&
+		(security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR) ||
+		 (security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) && hv));
+
+	if (type == STF_BARRIER_FALLBACK) {
+		pr_info("stf-barrier: fallback barrier available\n");
+	} else if (type == STF_BARRIER_SYNC_ORI) {
+		pr_info("stf-barrier: hwsync barrier available\n");
+	} else if (type == STF_BARRIER_EIEIO) {
+		pr_info("stf-barrier: eieio barrier available\n");
+	}
+
+	stf_enabled_flush_types = type;
+
+	if (!no_stf_barrier)
+		stf_barrier_enable(enable);
+}
+
+ssize_t cpu_show_spec_store_bypass(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	if (stf_barrier && stf_enabled_flush_types != STF_BARRIER_NONE) {
+		const char *type;
+		switch (stf_enabled_flush_types) {
+		case STF_BARRIER_EIEIO:
+			type = "eieio";
+			break;
+		case STF_BARRIER_SYNC_ORI:
+			type = "hwsync";
+			break;
+		case STF_BARRIER_FALLBACK:
+			type = "fallback";
+			break;
+		default:
+			type = "unknown";
+		}
+		return sprintf(buf, "Mitigation: Kernel entry/exit barrier (%s)\n", type);
+	}
+
+	if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) &&
+	    !security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR))
+		return sprintf(buf, "Not affected\n");
+
+	return sprintf(buf, "Vulnerable\n");
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int stf_barrier_set(void *data, u64 val)
+{
+	bool enable;
+
+	if (val == 1)
+		enable = true;
+	else if (val == 0)
+		enable = false;
+	else
+		return -EINVAL;
+
+	/* Only do anything if we're changing state */
+	if (enable != stf_barrier)
+		stf_barrier_enable(enable);
+
+	return 0;
+}
+
+static int stf_barrier_get(void *data, u64 *val)
+{
+	*val = stf_barrier ? 1 : 0;
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_stf_barrier, stf_barrier_get, stf_barrier_set, "%llu\n");
+
+static __init int stf_barrier_debugfs_init(void)
+{
+	debugfs_create_file("stf_barrier", 0600, powerpc_debugfs_root, NULL, &fops_stf_barrier);
+	return 0;
+}
+device_initcall(stf_barrier_debugfs_init);
+#endif /* CONFIG_DEBUG_FS */
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 5243501..fdba106 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -679,6 +679,7 @@
 	return 0;
 }
 early_initcall(disable_hardlockup_detector);
+#endif /* CONFIG_HARDLOCKUP_DETECTOR */
 
 #ifdef CONFIG_PPC_BOOK3S_64
 static enum l1d_flush_type enabled_flush_types;
@@ -716,9 +717,6 @@
 
 void rfi_flush_enable(bool enable)
 {
-	if (rfi_flush == enable)
-		return;
-
 	if (enable) {
 		do_rfi_flush_fixups(enabled_flush_types);
 		on_each_cpu(do_nothing, NULL, 1);
@@ -728,11 +726,15 @@
 	rfi_flush = enable;
 }
 
-static void init_fallback_flush(void)
+static void __ref init_fallback_flush(void)
 {
 	u64 l1d_size, limit;
 	int cpu;
 
+	/* Only allocate the fallback flush area once (at boot time). */
+	if (l1d_flush_fallback_area)
+		return;
+
 	l1d_size = ppc64_caches.dsize;
 	limit = min(safe_stack_limit(), ppc64_rma_size);
 
@@ -750,18 +752,18 @@
 	}
 }
 
-void __init setup_rfi_flush(enum l1d_flush_type types, bool enable)
+void setup_rfi_flush(enum l1d_flush_type types, bool enable)
 {
 	if (types & L1D_FLUSH_FALLBACK) {
-		pr_info("rfi-flush: Using fallback displacement flush\n");
+		pr_info("rfi-flush: fallback displacement flush available\n");
 		init_fallback_flush();
 	}
 
 	if (types & L1D_FLUSH_ORI)
-		pr_info("rfi-flush: Using ori type flush\n");
+		pr_info("rfi-flush: ori type flush available\n");
 
 	if (types & L1D_FLUSH_MTTRIG)
-		pr_info("rfi-flush: Using mttrig type flush\n");
+		pr_info("rfi-flush: mttrig type flush available\n");
 
 	enabled_flush_types = types;
 
@@ -772,13 +774,19 @@
 #ifdef CONFIG_DEBUG_FS
 static int rfi_flush_set(void *data, u64 val)
 {
+	bool enable;
+
 	if (val == 1)
-		rfi_flush_enable(true);
+		enable = true;
 	else if (val == 0)
-		rfi_flush_enable(false);
+		enable = false;
 	else
 		return -EINVAL;
 
+	/* Only do anything if we're changing state */
+	if (enable != rfi_flush)
+		rfi_flush_enable(enable);
+
 	return 0;
 }
 
@@ -797,13 +805,4 @@
 }
 device_initcall(rfi_flush_debugfs_init);
 #endif
-
-ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	if (rfi_flush)
-		return sprintf(buf, "Mitigation: RFI Flush\n");
-
-	return sprintf(buf, "Vulnerable\n");
-}
 #endif /* CONFIG_PPC_BOOK3S_64 */
-#endif
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index b61fb79..c16fddb 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -134,6 +134,20 @@
 
 #ifdef CONFIG_PPC64
 	. = ALIGN(8);
+	__stf_entry_barrier_fixup : AT(ADDR(__stf_entry_barrier_fixup) - LOAD_OFFSET) {
+		__start___stf_entry_barrier_fixup = .;
+		*(__stf_entry_barrier_fixup)
+		__stop___stf_entry_barrier_fixup = .;
+	}
+
+	. = ALIGN(8);
+	__stf_exit_barrier_fixup : AT(ADDR(__stf_exit_barrier_fixup) - LOAD_OFFSET) {
+		__start___stf_exit_barrier_fixup = .;
+		*(__stf_exit_barrier_fixup)
+		__stop___stf_exit_barrier_fixup = .;
+	}
+
+	. = ALIGN(8);
 	__rfi_flush_fixup : AT(ADDR(__rfi_flush_fixup) - LOAD_OFFSET) {
 		__start___rfi_flush_fixup = .;
 		*(__rfi_flush_fixup)
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index 46c8338..cf1398e 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -22,6 +22,7 @@
 #include <asm/page.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
+#include <asm/security_features.h>
 #include <asm/firmware.h>
 #include <asm/setup.h>
 
@@ -117,6 +118,120 @@
 }
 
 #ifdef CONFIG_PPC_BOOK3S_64
+void do_stf_entry_barrier_fixups(enum stf_barrier_type types)
+{
+	unsigned int instrs[3], *dest;
+	long *start, *end;
+	int i;
+
+	start = PTRRELOC(&__start___stf_entry_barrier_fixup),
+	end = PTRRELOC(&__stop___stf_entry_barrier_fixup);
+
+	instrs[0] = 0x60000000; /* nop */
+	instrs[1] = 0x60000000; /* nop */
+	instrs[2] = 0x60000000; /* nop */
+
+	i = 0;
+	if (types & STF_BARRIER_FALLBACK) {
+		instrs[i++] = 0x7d4802a6; /* mflr r10		*/
+		instrs[i++] = 0x60000000; /* branch patched below */
+		instrs[i++] = 0x7d4803a6; /* mtlr r10		*/
+	} else if (types & STF_BARRIER_EIEIO) {
+		instrs[i++] = 0x7e0006ac; /* eieio + bit 6 hint */
+	} else if (types & STF_BARRIER_SYNC_ORI) {
+		instrs[i++] = 0x7c0004ac; /* hwsync		*/
+		instrs[i++] = 0xe94d0000; /* ld r10,0(r13)	*/
+		instrs[i++] = 0x63ff0000; /* ori 31,31,0 speculation barrier */
+	}
+
+	for (i = 0; start < end; start++, i++) {
+		dest = (void *)start + *start;
+
+		pr_devel("patching dest %lx\n", (unsigned long)dest);
+
+		patch_instruction(dest, instrs[0]);
+
+		if (types & STF_BARRIER_FALLBACK)
+			patch_branch(dest + 1, (unsigned long)&stf_barrier_fallback,
+				     BRANCH_SET_LINK);
+		else
+			patch_instruction(dest + 1, instrs[1]);
+
+		patch_instruction(dest + 2, instrs[2]);
+	}
+
+	printk(KERN_DEBUG "stf-barrier: patched %d entry locations (%s barrier)\n", i,
+		(types == STF_BARRIER_NONE)                  ? "no" :
+		(types == STF_BARRIER_FALLBACK)              ? "fallback" :
+		(types == STF_BARRIER_EIEIO)                 ? "eieio" :
+		(types == (STF_BARRIER_SYNC_ORI))            ? "hwsync"
+		                                           : "unknown");
+}
+
+void do_stf_exit_barrier_fixups(enum stf_barrier_type types)
+{
+	unsigned int instrs[6], *dest;
+	long *start, *end;
+	int i;
+
+	start = PTRRELOC(&__start___stf_exit_barrier_fixup),
+	end = PTRRELOC(&__stop___stf_exit_barrier_fixup);
+
+	instrs[0] = 0x60000000; /* nop */
+	instrs[1] = 0x60000000; /* nop */
+	instrs[2] = 0x60000000; /* nop */
+	instrs[3] = 0x60000000; /* nop */
+	instrs[4] = 0x60000000; /* nop */
+	instrs[5] = 0x60000000; /* nop */
+
+	i = 0;
+	if (types & STF_BARRIER_FALLBACK || types & STF_BARRIER_SYNC_ORI) {
+		if (cpu_has_feature(CPU_FTR_HVMODE)) {
+			instrs[i++] = 0x7db14ba6; /* mtspr 0x131, r13 (HSPRG1) */
+			instrs[i++] = 0x7db04aa6; /* mfspr r13, 0x130 (HSPRG0) */
+		} else {
+			instrs[i++] = 0x7db243a6; /* mtsprg 2,r13	*/
+			instrs[i++] = 0x7db142a6; /* mfsprg r13,1    */
+	        }
+		instrs[i++] = 0x7c0004ac; /* hwsync		*/
+		instrs[i++] = 0xe9ad0000; /* ld r13,0(r13)	*/
+		instrs[i++] = 0x63ff0000; /* ori 31,31,0 speculation barrier */
+		if (cpu_has_feature(CPU_FTR_HVMODE)) {
+			instrs[i++] = 0x7db14aa6; /* mfspr r13, 0x131 (HSPRG1) */
+		} else {
+			instrs[i++] = 0x7db242a6; /* mfsprg r13,2 */
+		}
+	} else if (types & STF_BARRIER_EIEIO) {
+		instrs[i++] = 0x7e0006ac; /* eieio + bit 6 hint */
+	}
+
+	for (i = 0; start < end; start++, i++) {
+		dest = (void *)start + *start;
+
+		pr_devel("patching dest %lx\n", (unsigned long)dest);
+
+		patch_instruction(dest, instrs[0]);
+		patch_instruction(dest + 1, instrs[1]);
+		patch_instruction(dest + 2, instrs[2]);
+		patch_instruction(dest + 3, instrs[3]);
+		patch_instruction(dest + 4, instrs[4]);
+		patch_instruction(dest + 5, instrs[5]);
+	}
+	printk(KERN_DEBUG "stf-barrier: patched %d exit locations (%s barrier)\n", i,
+		(types == STF_BARRIER_NONE)                  ? "no" :
+		(types == STF_BARRIER_FALLBACK)              ? "fallback" :
+		(types == STF_BARRIER_EIEIO)                 ? "eieio" :
+		(types == (STF_BARRIER_SYNC_ORI))            ? "hwsync"
+		                                           : "unknown");
+}
+
+
+void do_stf_barrier_fixups(enum stf_barrier_type types)
+{
+	do_stf_entry_barrier_fixups(types);
+	do_stf_exit_barrier_fixups(types);
+}
+
 void do_rfi_flush_fixups(enum l1d_flush_type types)
 {
 	unsigned int instrs[3], *dest;
@@ -153,7 +268,14 @@
 		patch_instruction(dest + 2, instrs[2]);
 	}
 
-	printk(KERN_DEBUG "rfi-flush: patched %d locations\n", i);
+	printk(KERN_DEBUG "rfi-flush: patched %d locations (%s flush)\n", i,
+		(types == L1D_FLUSH_NONE)       ? "no" :
+		(types == L1D_FLUSH_FALLBACK)   ? "fallback displacement" :
+		(types &  L1D_FLUSH_ORI)        ? (types & L1D_FLUSH_MTTRIG)
+							? "ori+mttrig type"
+							: "ori type" :
+		(types &  L1D_FLUSH_MTTRIG)     ? "mttrig type"
+						: "unknown");
 }
 #endif /* CONFIG_PPC_BOOK3S_64 */
 
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index 6f8b4c1..17203ab 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -37,53 +37,92 @@
 #include <asm/smp.h>
 #include <asm/tm.h>
 #include <asm/setup.h>
+#include <asm/security_features.h>
 
 #include "powernv.h"
 
+
+static bool fw_feature_is(const char *state, const char *name,
+			  struct device_node *fw_features)
+{
+	struct device_node *np;
+	bool rc = false;
+
+	np = of_get_child_by_name(fw_features, name);
+	if (np) {
+		rc = of_property_read_bool(np, state);
+		of_node_put(np);
+	}
+
+	return rc;
+}
+
+static void init_fw_feat_flags(struct device_node *np)
+{
+	if (fw_feature_is("enabled", "inst-spec-barrier-ori31,31,0", np))
+		security_ftr_set(SEC_FTR_SPEC_BAR_ORI31);
+
+	if (fw_feature_is("enabled", "fw-bcctrl-serialized", np))
+		security_ftr_set(SEC_FTR_BCCTRL_SERIALISED);
+
+	if (fw_feature_is("enabled", "inst-l1d-flush-ori30,30,0", np))
+		security_ftr_set(SEC_FTR_L1D_FLUSH_ORI30);
+
+	if (fw_feature_is("enabled", "inst-l1d-flush-trig2", np))
+		security_ftr_set(SEC_FTR_L1D_FLUSH_TRIG2);
+
+	if (fw_feature_is("enabled", "fw-l1d-thread-split", np))
+		security_ftr_set(SEC_FTR_L1D_THREAD_PRIV);
+
+	if (fw_feature_is("enabled", "fw-count-cache-disabled", np))
+		security_ftr_set(SEC_FTR_COUNT_CACHE_DISABLED);
+
+	/*
+	 * The features below are enabled by default, so we instead look to see
+	 * if firmware has *disabled* them, and clear them if so.
+	 */
+	if (fw_feature_is("disabled", "speculation-policy-favor-security", np))
+		security_ftr_clear(SEC_FTR_FAVOUR_SECURITY);
+
+	if (fw_feature_is("disabled", "needs-l1d-flush-msr-pr-0-to-1", np))
+		security_ftr_clear(SEC_FTR_L1D_FLUSH_PR);
+
+	if (fw_feature_is("disabled", "needs-l1d-flush-msr-hv-1-to-0", np))
+		security_ftr_clear(SEC_FTR_L1D_FLUSH_HV);
+
+	if (fw_feature_is("disabled", "needs-spec-barrier-for-bound-checks", np))
+		security_ftr_clear(SEC_FTR_BNDS_CHK_SPEC_BAR);
+}
+
 static void pnv_setup_rfi_flush(void)
 {
 	struct device_node *np, *fw_features;
 	enum l1d_flush_type type;
-	int enable;
+	bool enable;
 
 	/* Default to fallback in case fw-features are not available */
 	type = L1D_FLUSH_FALLBACK;
-	enable = 1;
 
 	np = of_find_node_by_name(NULL, "ibm,opal");
 	fw_features = of_get_child_by_name(np, "fw-features");
 	of_node_put(np);
 
 	if (fw_features) {
-		np = of_get_child_by_name(fw_features, "inst-l1d-flush-trig2");
-		if (np && of_property_read_bool(np, "enabled"))
+		init_fw_feat_flags(fw_features);
+		of_node_put(fw_features);
+
+		if (security_ftr_enabled(SEC_FTR_L1D_FLUSH_TRIG2))
 			type = L1D_FLUSH_MTTRIG;
 
-		of_node_put(np);
-
-		np = of_get_child_by_name(fw_features, "inst-l1d-flush-ori30,30,0");
-		if (np && of_property_read_bool(np, "enabled"))
+		if (security_ftr_enabled(SEC_FTR_L1D_FLUSH_ORI30))
 			type = L1D_FLUSH_ORI;
-
-		of_node_put(np);
-
-		/* Enable unless firmware says NOT to */
-		enable = 2;
-		np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-hv-1-to-0");
-		if (np && of_property_read_bool(np, "disabled"))
-			enable--;
-
-		of_node_put(np);
-
-		np = of_get_child_by_name(fw_features, "needs-l1d-flush-msr-pr-0-to-1");
-		if (np && of_property_read_bool(np, "disabled"))
-			enable--;
-
-		of_node_put(np);
-		of_node_put(fw_features);
 	}
 
-	setup_rfi_flush(type, enable > 0);
+	enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) && \
+		 (security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR)   || \
+		  security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV));
+
+	setup_rfi_flush(type, enable);
 }
 
 static void __init pnv_setup_arch(void)
@@ -91,6 +130,7 @@
 	set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
 
 	pnv_setup_rfi_flush();
+	setup_stf_barrier();
 
 	/* Initialize SMP */
 	pnv_smp_init();
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index 6a5e746..3784a7a 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -314,6 +314,9 @@
 		printk(KERN_ERR "Post-mobility device tree update "
 			"failed: %d\n", rc);
 
+	/* Possibly switch to a new RFI flush type */
+	pseries_setup_rfi_flush();
+
 	return;
 }
 
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index b1be7b7..62ff57c 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -79,4 +79,6 @@
 
 unsigned long pseries_memory_block_size(void);
 
+void pseries_setup_rfi_flush(void);
+
 #endif /* _PSERIES_PSERIES_H */
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 1845fc6..91ade77 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -66,6 +66,7 @@
 #include <asm/reg.h>
 #include <asm/plpar_wrappers.h>
 #include <asm/kexec.h>
+#include <asm/security_features.h>
 
 #include "pseries.h"
 
@@ -450,35 +451,78 @@
 	of_pci_check_probe_only();
 }
 
-static void pseries_setup_rfi_flush(void)
+static void init_cpu_char_feature_flags(struct h_cpu_char_result *result)
+{
+	/*
+	 * The features below are disabled by default, so we instead look to see
+	 * if firmware has *enabled* them, and set them if so.
+	 */
+	if (result->character & H_CPU_CHAR_SPEC_BAR_ORI31)
+		security_ftr_set(SEC_FTR_SPEC_BAR_ORI31);
+
+	if (result->character & H_CPU_CHAR_BCCTRL_SERIALISED)
+		security_ftr_set(SEC_FTR_BCCTRL_SERIALISED);
+
+	if (result->character & H_CPU_CHAR_L1D_FLUSH_ORI30)
+		security_ftr_set(SEC_FTR_L1D_FLUSH_ORI30);
+
+	if (result->character & H_CPU_CHAR_L1D_FLUSH_TRIG2)
+		security_ftr_set(SEC_FTR_L1D_FLUSH_TRIG2);
+
+	if (result->character & H_CPU_CHAR_L1D_THREAD_PRIV)
+		security_ftr_set(SEC_FTR_L1D_THREAD_PRIV);
+
+	if (result->character & H_CPU_CHAR_COUNT_CACHE_DISABLED)
+		security_ftr_set(SEC_FTR_COUNT_CACHE_DISABLED);
+
+	/*
+	 * The features below are enabled by default, so we instead look to see
+	 * if firmware has *disabled* them, and clear them if so.
+	 */
+	if (!(result->behaviour & H_CPU_BEHAV_FAVOUR_SECURITY))
+		security_ftr_clear(SEC_FTR_FAVOUR_SECURITY);
+
+	if (!(result->behaviour & H_CPU_BEHAV_L1D_FLUSH_PR))
+		security_ftr_clear(SEC_FTR_L1D_FLUSH_PR);
+
+	if (!(result->behaviour & H_CPU_BEHAV_BNDS_CHK_SPEC_BAR))
+		security_ftr_clear(SEC_FTR_BNDS_CHK_SPEC_BAR);
+}
+
+void pseries_setup_rfi_flush(void)
 {
 	struct h_cpu_char_result result;
 	enum l1d_flush_type types;
 	bool enable;
 	long rc;
 
-	/* Enable by default */
-	enable = true;
+	/*
+	 * Set features to the defaults assumed by init_cpu_char_feature_flags()
+	 * so it can set/clear again any features that might have changed after
+	 * migration, and in case the hypercall fails and it is not even called.
+	 */
+	powerpc_security_features = SEC_FTR_DEFAULT;
 
 	rc = plpar_get_cpu_characteristics(&result);
-	if (rc == H_SUCCESS) {
-		types = L1D_FLUSH_NONE;
+	if (rc == H_SUCCESS)
+		init_cpu_char_feature_flags(&result);
 
-		if (result.character & H_CPU_CHAR_L1D_FLUSH_TRIG2)
-			types |= L1D_FLUSH_MTTRIG;
-		if (result.character & H_CPU_CHAR_L1D_FLUSH_ORI30)
-			types |= L1D_FLUSH_ORI;
+	/*
+	 * We're the guest so this doesn't apply to us, clear it to simplify
+	 * handling of it elsewhere.
+	 */
+	security_ftr_clear(SEC_FTR_L1D_FLUSH_HV);
 
-		/* Use fallback if nothing set in hcall */
-		if (types == L1D_FLUSH_NONE)
-			types = L1D_FLUSH_FALLBACK;
+	types = L1D_FLUSH_FALLBACK;
 
-		if (!(result.behaviour & H_CPU_BEHAV_L1D_FLUSH_PR))
-			enable = false;
-	} else {
-		/* Default to fallback if case hcall is not available */
-		types = L1D_FLUSH_FALLBACK;
-	}
+	if (security_ftr_enabled(SEC_FTR_L1D_FLUSH_TRIG2))
+		types |= L1D_FLUSH_MTTRIG;
+
+	if (security_ftr_enabled(SEC_FTR_L1D_FLUSH_ORI30))
+		types |= L1D_FLUSH_ORI;
+
+	enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) && \
+		 security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR);
 
 	setup_rfi_flush(types, enable);
 }
@@ -501,6 +545,7 @@
 	fwnmi_init();
 
 	pseries_setup_rfi_flush();
+	setup_stf_barrier();
 
 	/* By default, only probe PCI (can be overridden by rtas_pci) */
 	pci_add_flags(PCI_PROBE_ONLY);
diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c
index f87a55d..9b3f2e2 100644
--- a/arch/sparc/kernel/ds.c
+++ b/arch/sparc/kernel/ds.c
@@ -908,7 +908,7 @@
 		pbuf.req.handle = cp->handle;
 		pbuf.req.major = 1;
 		pbuf.req.minor = 0;
-		strcpy(pbuf.req.svc_id, cp->service_id);
+		strcpy(pbuf.id_buf, cp->service_id);
 
 		err = __ds_send(lp, &pbuf, msg_len);
 		if (err > 0)
diff --git a/arch/sparc/lib/multi3.S b/arch/sparc/lib/multi3.S
index d6b6c97..703127a 100644
--- a/arch/sparc/lib/multi3.S
+++ b/arch/sparc/lib/multi3.S
@@ -5,26 +5,26 @@
 	.align	4
 ENTRY(__multi3) /* %o0 = u, %o1 = v */
 	mov	%o1, %g1
-	srl	%o3, 0, %g4
-	mulx	%g4, %g1, %o1
+	srl	%o3, 0, %o4
+	mulx	%o4, %g1, %o1
 	srlx	%g1, 0x20, %g3
-	mulx	%g3, %g4, %g5
-	sllx	%g5, 0x20, %o5
-	srl	%g1, 0, %g4
+	mulx	%g3, %o4, %g7
+	sllx	%g7, 0x20, %o5
+	srl	%g1, 0, %o4
 	sub	%o1, %o5, %o5
 	srlx	%o5, 0x20, %o5
-	addcc	%g5, %o5, %g5
+	addcc	%g7, %o5, %g7
 	srlx	%o3, 0x20, %o5
-	mulx	%g4, %o5, %g4
+	mulx	%o4, %o5, %o4
 	mulx	%g3, %o5, %o5
 	sethi	%hi(0x80000000), %g3
-	addcc	%g5, %g4, %g5
-	srlx	%g5, 0x20, %g5
+	addcc	%g7, %o4, %g7
+	srlx	%g7, 0x20, %g7
 	add	%g3, %g3, %g3
 	movcc	%xcc, %g0, %g3
-	addcc	%o5, %g5, %o5
-	sllx	%g4, 0x20, %g4
-	add	%o1, %g4, %o1
+	addcc	%o5, %g7, %o5
+	sllx	%o4, 0x20, %o4
+	add	%o1, %o4, %o1
 	add	%o5, %g3, %g2
 	mulx	%g1, %o2, %g1
 	add	%g1, %g2, %g1
diff --git a/arch/x86/crypto/crc32c-intel_glue.c b/arch/x86/crypto/crc32c-intel_glue.c
index 60a391b..dd19584 100644
--- a/arch/x86/crypto/crc32c-intel_glue.c
+++ b/arch/x86/crypto/crc32c-intel_glue.c
@@ -58,16 +58,11 @@
 asmlinkage unsigned int crc_pcl(const u8 *buffer, int len,
 				unsigned int crc_init);
 static int crc32c_pcl_breakeven = CRC32C_PCL_BREAKEVEN_EAGERFPU;
-#if defined(X86_FEATURE_EAGER_FPU)
 #define set_pcl_breakeven_point()					\
 do {									\
 	if (!use_eager_fpu())						\
 		crc32c_pcl_breakeven = CRC32C_PCL_BREAKEVEN_NOEAGERFPU;	\
 } while (0)
-#else
-#define set_pcl_breakeven_point()					\
-	(crc32c_pcl_breakeven = CRC32C_PCL_BREAKEVEN_NOEAGERFPU)
-#endif
 #endif /* CONFIG_X86_64 */
 
 static u32 crc32c_intel_le_hw_byte(u32 crc, unsigned char const *data, size_t length)
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index c278f27..aea30af 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -104,7 +104,7 @@
 #define X86_FEATURE_EXTD_APICID	( 3*32+26) /* has extended APICID (8 bits) */
 #define X86_FEATURE_AMD_DCM     ( 3*32+27) /* multi-node processor */
 #define X86_FEATURE_APERFMPERF	( 3*32+28) /* APERFMPERF */
-#define X86_FEATURE_EAGER_FPU	( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
+/* free, was #define X86_FEATURE_EAGER_FPU	( 3*32+29) * "eagerfpu" Non lazy FPU restore */
 #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h
index 2737366..8852e3a 100644
--- a/arch/x86/include/asm/fpu/internal.h
+++ b/arch/x86/include/asm/fpu/internal.h
@@ -62,7 +62,7 @@
  */
 static __always_inline __pure bool use_eager_fpu(void)
 {
-	return static_cpu_has(X86_FEATURE_EAGER_FPU);
+	return true;
 }
 
 static __always_inline __pure bool use_xsaveopt(void)
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index fc3c7e4..ae357d0 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -105,11 +105,12 @@
 	 *  @addr:  [IN ] Linear address from which to read.
 	 *  @val:   [OUT] Value read from memory, zero-extended to 'u_long'.
 	 *  @bytes: [IN ] Number of bytes to read from memory.
+	 *  @system:[IN ] Whether the access is forced to be at CPL0.
 	 */
 	int (*read_std)(struct x86_emulate_ctxt *ctxt,
 			unsigned long addr, void *val,
 			unsigned int bytes,
-			struct x86_exception *fault);
+			struct x86_exception *fault, bool system);
 
 	/*
 	 * read_phys: Read bytes of standard (non-emulated/special) memory.
@@ -127,10 +128,11 @@
 	 *  @addr:  [IN ] Linear address to which to write.
 	 *  @val:   [OUT] Value write to memory, zero-extended to 'u_long'.
 	 *  @bytes: [IN ] Number of bytes to write to memory.
+	 *  @system:[IN ] Whether the access is forced to be at CPL0.
 	 */
 	int (*write_std)(struct x86_emulate_ctxt *ctxt,
 			 unsigned long addr, void *val, unsigned int bytes,
-			 struct x86_exception *fault);
+			 struct x86_exception *fault, bool system);
 	/*
 	 * fetch: Read bytes of standard (non-emulated/special) memory.
 	 *        Used for instruction fetch.
diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c
index 6f0ab305..9f36578 100644
--- a/arch/x86/kernel/fpu/init.c
+++ b/arch/x86/kernel/fpu/init.c
@@ -15,10 +15,7 @@
  */
 static void fpu__init_cpu_ctx_switch(void)
 {
-	if (!boot_cpu_has(X86_FEATURE_EAGER_FPU))
-		stts();
-	else
-		clts();
+	clts();
 }
 
 /*
@@ -234,82 +231,16 @@
 }
 
 /*
- * FPU context switching strategies:
- *
- * Against popular belief, we don't do lazy FPU saves, due to the
- * task migration complications it brings on SMP - we only do
- * lazy FPU restores.
- *
- * 'lazy' is the traditional strategy, which is based on setting
- * CR0::TS to 1 during context-switch (instead of doing a full
- * restore of the FPU state), which causes the first FPU instruction
- * after the context switch (whenever it is executed) to fault - at
- * which point we lazily restore the FPU state into FPU registers.
- *
- * Tasks are of course under no obligation to execute FPU instructions,
- * so it can easily happen that another context-switch occurs without
- * a single FPU instruction being executed. If we eventually switch
- * back to the original task (that still owns the FPU) then we have
- * not only saved the restores along the way, but we also have the
- * FPU ready to be used for the original task.
- *
- * 'lazy' is deprecated because it's almost never a performance win
- * and it's much more complicated than 'eager'.
- *
- * 'eager' switching is by default on all CPUs, there we switch the FPU
- * state during every context switch, regardless of whether the task
- * has used FPU instructions in that time slice or not. This is done
- * because modern FPU context saving instructions are able to optimize
- * state saving and restoration in hardware: they can detect both
- * unused and untouched FPU state and optimize accordingly.
- *
- * [ Note that even in 'lazy' mode we might optimize context switches
- *   to use 'eager' restores, if we detect that a task is using the FPU
- *   frequently. See the fpu->counter logic in fpu/internal.h for that. ]
- */
-static enum { ENABLE, DISABLE } eagerfpu = ENABLE;
-
-/*
  * Find supported xfeatures based on cpu features and command-line input.
  * This must be called after fpu__init_parse_early_param() is called and
  * xfeatures_mask is enumerated.
  */
 u64 __init fpu__get_supported_xfeatures_mask(void)
 {
-	/* Support all xfeatures known to us */
-	if (eagerfpu != DISABLE)
-		return XCNTXT_MASK;
-
-	/* Warning of xfeatures being disabled for no eagerfpu mode */
-	if (xfeatures_mask & XFEATURE_MASK_EAGER) {
-		pr_err("x86/fpu: eagerfpu switching disabled, disabling the following xstate features: 0x%llx.\n",
-			xfeatures_mask & XFEATURE_MASK_EAGER);
-	}
-
-	/* Return a mask that masks out all features requiring eagerfpu mode */
-	return ~XFEATURE_MASK_EAGER;
+	return XCNTXT_MASK;
 }
 
-/*
- * Disable features dependent on eagerfpu.
- */
-static void __init fpu__clear_eager_fpu_features(void)
-{
-	setup_clear_cpu_cap(X86_FEATURE_MPX);
-}
-
-/*
- * Pick the FPU context switching strategy:
- *
- * When eagerfpu is AUTO or ENABLE, we ensure it is ENABLE if either of
- * the following is true:
- *
- * (1) the cpu has xsaveopt, as it has the optimization and doing eager
- *     FPU switching has a relatively low cost compared to a plain xsave;
- * (2) the cpu has xsave features (e.g. MPX) that depend on eager FPU
- *     switching. Should the kernel boot with noxsaveopt, we support MPX
- *     with eager FPU switching at a higher cost.
- */
+/* Legacy code to initialize eager fpu mode. */
 static void __init fpu__init_system_ctx_switch(void)
 {
 	static bool on_boot_cpu __initdata = 1;
@@ -318,17 +249,6 @@
 	on_boot_cpu = 0;
 
 	WARN_ON_FPU(current->thread.fpu.fpstate_active);
-
-	if (boot_cpu_has(X86_FEATURE_XSAVEOPT) && eagerfpu != DISABLE)
-		eagerfpu = ENABLE;
-
-	if (xfeatures_mask & XFEATURE_MASK_EAGER)
-		eagerfpu = ENABLE;
-
-	if (eagerfpu == ENABLE)
-		setup_force_cpu_cap(X86_FEATURE_EAGER_FPU);
-
-	printk(KERN_INFO "x86/fpu: Using '%s' FPU context switches.\n", eagerfpu == ENABLE ? "eager" : "lazy");
 }
 
 /*
@@ -337,11 +257,6 @@
  */
 static void __init fpu__init_parse_early_param(void)
 {
-	if (cmdline_find_option_bool(boot_command_line, "eagerfpu=off")) {
-		eagerfpu = DISABLE;
-		fpu__clear_eager_fpu_features();
-	}
-
 	if (cmdline_find_option_bool(boot_command_line, "no387"))
 		setup_clear_cpu_cap(X86_FEATURE_FPU);
 
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 4ef267f..e783a5d 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -352,8 +352,6 @@
 	DISCARDS
 	/DISCARD/ : {
 		*(.eh_frame)
-		*(__func_stack_frame_non_standard)
-		*(__unreachable)
 	}
 }
 
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
index c383697..8a841b9 100644
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
@@ -179,7 +179,7 @@
 	if (best && (best->ebx & bit(X86_FEATURE_AMD_IBRS)))
 		return true;
 	best = kvm_find_cpuid_entry(vcpu, 7, 0);
-	return best && (best->edx & (bit(X86_FEATURE_SPEC_CTRL) | bit(X86_FEATURE_SSBD)));
+	return best && (best->edx & (bit(X86_FEATURE_SPEC_CTRL) | bit(X86_FEATURE_SPEC_CTRL_SSBD)));
 }
 
 static inline bool guest_cpuid_has_arch_capabilities(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index c8d5738..510cfc0 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -802,6 +802,19 @@
 	return assign_eip_near(ctxt, ctxt->_eip + rel);
 }
 
+static int linear_read_system(struct x86_emulate_ctxt *ctxt, ulong linear,
+			      void *data, unsigned size)
+{
+	return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception, true);
+}
+
+static int linear_write_system(struct x86_emulate_ctxt *ctxt,
+			       ulong linear, void *data,
+			       unsigned int size)
+{
+	return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception, true);
+}
+
 static int segmented_read_std(struct x86_emulate_ctxt *ctxt,
 			      struct segmented_address addr,
 			      void *data,
@@ -813,7 +826,7 @@
 	rc = linearize(ctxt, addr, size, false, &linear);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
-	return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception);
+	return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception, false);
 }
 
 static int segmented_write_std(struct x86_emulate_ctxt *ctxt,
@@ -827,7 +840,7 @@
 	rc = linearize(ctxt, addr, size, true, &linear);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
-	return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception);
+	return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception, false);
 }
 
 /*
@@ -1500,8 +1513,7 @@
 		return emulate_gp(ctxt, index << 3 | 0x2);
 
 	addr = dt.address + index * 8;
-	return ctxt->ops->read_std(ctxt, addr, desc, sizeof *desc,
-				   &ctxt->exception);
+	return linear_read_system(ctxt, addr, desc, sizeof *desc);
 }
 
 static void get_descriptor_table_ptr(struct x86_emulate_ctxt *ctxt,
@@ -1564,8 +1576,7 @@
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
-	return ctxt->ops->read_std(ctxt, *desc_addr_p, desc, sizeof(*desc),
-				   &ctxt->exception);
+	return linear_read_system(ctxt, *desc_addr_p, desc, sizeof(*desc));
 }
 
 /* allowed just for 8 bytes segments */
@@ -1579,8 +1590,7 @@
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
-	return ctxt->ops->write_std(ctxt, addr, desc, sizeof *desc,
-				    &ctxt->exception);
+	return linear_write_system(ctxt, addr, desc, sizeof *desc);
 }
 
 static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
@@ -1741,8 +1751,7 @@
 				return ret;
 		}
 	} else if (ctxt->mode == X86EMUL_MODE_PROT64) {
-		ret = ctxt->ops->read_std(ctxt, desc_addr+8, &base3,
-				sizeof(base3), &ctxt->exception);
+		ret = linear_read_system(ctxt, desc_addr+8, &base3, sizeof(base3));
 		if (ret != X86EMUL_CONTINUE)
 			return ret;
 		if (is_noncanonical_address(get_desc_base(&seg_desc) |
@@ -2055,11 +2064,11 @@
 	eip_addr = dt.address + (irq << 2);
 	cs_addr = dt.address + (irq << 2) + 2;
 
-	rc = ops->read_std(ctxt, cs_addr, &cs, 2, &ctxt->exception);
+	rc = linear_read_system(ctxt, cs_addr, &cs, 2);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
-	rc = ops->read_std(ctxt, eip_addr, &eip, 2, &ctxt->exception);
+	rc = linear_read_system(ctxt, eip_addr, &eip, 2);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
@@ -2903,12 +2912,12 @@
 #ifdef CONFIG_X86_64
 	base |= ((u64)base3) << 32;
 #endif
-	r = ops->read_std(ctxt, base + 102, &io_bitmap_ptr, 2, NULL);
+	r = ops->read_std(ctxt, base + 102, &io_bitmap_ptr, 2, NULL, true);
 	if (r != X86EMUL_CONTINUE)
 		return false;
 	if (io_bitmap_ptr + port/8 > desc_limit_scaled(&tr_seg))
 		return false;
-	r = ops->read_std(ctxt, base + io_bitmap_ptr + port/8, &perm, 2, NULL);
+	r = ops->read_std(ctxt, base + io_bitmap_ptr + port/8, &perm, 2, NULL, true);
 	if (r != X86EMUL_CONTINUE)
 		return false;
 	if ((perm >> bit_idx) & mask)
@@ -3037,35 +3046,30 @@
 			  u16 tss_selector, u16 old_tss_sel,
 			  ulong old_tss_base, struct desc_struct *new_desc)
 {
-	const struct x86_emulate_ops *ops = ctxt->ops;
 	struct tss_segment_16 tss_seg;
 	int ret;
 	u32 new_tss_base = get_desc_base(new_desc);
 
-	ret = ops->read_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg,
-			    &ctxt->exception);
+	ret = linear_read_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
 
 	save_state_to_tss16(ctxt, &tss_seg);
 
-	ret = ops->write_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg,
-			     &ctxt->exception);
+	ret = linear_write_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
 
-	ret = ops->read_std(ctxt, new_tss_base, &tss_seg, sizeof tss_seg,
-			    &ctxt->exception);
+	ret = linear_read_system(ctxt, new_tss_base, &tss_seg, sizeof tss_seg);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
 
 	if (old_tss_sel != 0xffff) {
 		tss_seg.prev_task_link = old_tss_sel;
 
-		ret = ops->write_std(ctxt, new_tss_base,
-				     &tss_seg.prev_task_link,
-				     sizeof tss_seg.prev_task_link,
-				     &ctxt->exception);
+		ret = linear_write_system(ctxt, new_tss_base,
+					  &tss_seg.prev_task_link,
+					  sizeof tss_seg.prev_task_link);
 		if (ret != X86EMUL_CONTINUE)
 			return ret;
 	}
@@ -3181,38 +3185,34 @@
 			  u16 tss_selector, u16 old_tss_sel,
 			  ulong old_tss_base, struct desc_struct *new_desc)
 {
-	const struct x86_emulate_ops *ops = ctxt->ops;
 	struct tss_segment_32 tss_seg;
 	int ret;
 	u32 new_tss_base = get_desc_base(new_desc);
 	u32 eip_offset = offsetof(struct tss_segment_32, eip);
 	u32 ldt_sel_offset = offsetof(struct tss_segment_32, ldt_selector);
 
-	ret = ops->read_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg,
-			    &ctxt->exception);
+	ret = linear_read_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
 
 	save_state_to_tss32(ctxt, &tss_seg);
 
 	/* Only GP registers and segment selectors are saved */
-	ret = ops->write_std(ctxt, old_tss_base + eip_offset, &tss_seg.eip,
-			     ldt_sel_offset - eip_offset, &ctxt->exception);
+	ret = linear_write_system(ctxt, old_tss_base + eip_offset, &tss_seg.eip,
+				  ldt_sel_offset - eip_offset);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
 
-	ret = ops->read_std(ctxt, new_tss_base, &tss_seg, sizeof tss_seg,
-			    &ctxt->exception);
+	ret = linear_read_system(ctxt, new_tss_base, &tss_seg, sizeof tss_seg);
 	if (ret != X86EMUL_CONTINUE)
 		return ret;
 
 	if (old_tss_sel != 0xffff) {
 		tss_seg.prev_task_link = old_tss_sel;
 
-		ret = ops->write_std(ctxt, new_tss_base,
-				     &tss_seg.prev_task_link,
-				     sizeof tss_seg.prev_task_link,
-				     &ctxt->exception);
+		ret = linear_write_system(ctxt, new_tss_base,
+					  &tss_seg.prev_task_link,
+					  sizeof tss_seg.prev_task_link);
 		if (ret != X86EMUL_CONTINUE)
 			return ret;
 	}
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index ebceda2..7cb1077 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -6928,8 +6928,7 @@
 			vmcs_read32(VMX_INSTRUCTION_INFO), false, &gva))
 		return 1;
 
-	if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &vmptr,
-				sizeof(vmptr), &e)) {
+	if (kvm_read_guest_virt(vcpu, gva, &vmptr, sizeof(vmptr), &e)) {
 		kvm_inject_page_fault(vcpu, &e);
 		return 1;
 	}
@@ -7469,8 +7468,8 @@
 				vmx_instruction_info, true, &gva))
 			return 1;
 		/* _system ok, as nested_vmx_check_permission verified cpl=0 */
-		kvm_write_guest_virt_system(&vcpu->arch.emulate_ctxt, gva,
-			     &field_value, (is_long_mode(vcpu) ? 8 : 4), NULL);
+		kvm_write_guest_virt_system(vcpu, gva, &field_value,
+					    (is_long_mode(vcpu) ? 8 : 4), NULL);
 	}
 
 	nested_vmx_succeed(vcpu);
@@ -7505,8 +7504,8 @@
 		if (get_vmx_mem_address(vcpu, exit_qualification,
 				vmx_instruction_info, false, &gva))
 			return 1;
-		if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva,
-			   &field_value, (is_64_bit_mode(vcpu) ? 8 : 4), &e)) {
+		if (kvm_read_guest_virt(vcpu, gva, &field_value,
+					(is_64_bit_mode(vcpu) ? 8 : 4), &e)) {
 			kvm_inject_page_fault(vcpu, &e);
 			return 1;
 		}
@@ -7603,9 +7602,9 @@
 			vmx_instruction_info, true, &vmcs_gva))
 		return 1;
 	/* ok to use *_system, as nested_vmx_check_permission verified cpl=0 */
-	if (kvm_write_guest_virt_system(&vcpu->arch.emulate_ctxt, vmcs_gva,
-				 (void *)&to_vmx(vcpu)->nested.current_vmptr,
-				 sizeof(u64), &e)) {
+	if (kvm_write_guest_virt_system(vcpu, vmcs_gva,
+					(void *)&to_vmx(vcpu)->nested.current_vmptr,
+					sizeof(u64), &e)) {
 		kvm_inject_page_fault(vcpu, &e);
 		return 1;
 	}
@@ -7659,8 +7658,7 @@
 	if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION),
 			vmx_instruction_info, false, &gva))
 		return 1;
-	if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &operand,
-				sizeof(operand), &e)) {
+	if (kvm_read_guest_virt(vcpu, gva, &operand, sizeof(operand), &e)) {
 		kvm_inject_page_fault(vcpu, &e);
 		return 1;
 	}
@@ -7723,8 +7721,7 @@
 	if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION),
 			vmx_instruction_info, false, &gva))
 		return 1;
-	if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &vpid,
-				sizeof(u32), &e)) {
+	if (kvm_read_guest_virt(vcpu, gva, &vpid, sizeof(u32), &e)) {
 		kvm_inject_page_fault(vcpu, &e);
 		return 1;
 	}
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 4aa265a..5ca23af 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4395,11 +4395,10 @@
 	return X86EMUL_CONTINUE;
 }
 
-int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt,
+int kvm_read_guest_virt(struct kvm_vcpu *vcpu,
 			       gva_t addr, void *val, unsigned int bytes,
 			       struct x86_exception *exception)
 {
-	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
 	u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
 
 	return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access,
@@ -4407,12 +4406,17 @@
 }
 EXPORT_SYMBOL_GPL(kvm_read_guest_virt);
 
-static int kvm_read_guest_virt_system(struct x86_emulate_ctxt *ctxt,
-				      gva_t addr, void *val, unsigned int bytes,
-				      struct x86_exception *exception)
+static int emulator_read_std(struct x86_emulate_ctxt *ctxt,
+			     gva_t addr, void *val, unsigned int bytes,
+			     struct x86_exception *exception, bool system)
 {
 	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
-	return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, exception);
+	u32 access = 0;
+
+	if (!system && kvm_x86_ops->get_cpl(vcpu) == 3)
+		access |= PFERR_USER_MASK;
+
+	return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access, exception);
 }
 
 static int kvm_read_guest_phys_system(struct x86_emulate_ctxt *ctxt,
@@ -4424,18 +4428,16 @@
 	return r < 0 ? X86EMUL_IO_NEEDED : X86EMUL_CONTINUE;
 }
 
-int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt,
-				       gva_t addr, void *val,
-				       unsigned int bytes,
-				       struct x86_exception *exception)
+static int kvm_write_guest_virt_helper(gva_t addr, void *val, unsigned int bytes,
+				      struct kvm_vcpu *vcpu, u32 access,
+				      struct x86_exception *exception)
 {
-	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
 	void *data = val;
 	int r = X86EMUL_CONTINUE;
 
 	while (bytes) {
 		gpa_t gpa =  vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr,
-							     PFERR_WRITE_MASK,
+							     access,
 							     exception);
 		unsigned offset = addr & (PAGE_SIZE-1);
 		unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset);
@@ -4456,6 +4458,27 @@
 out:
 	return r;
 }
+
+static int emulator_write_std(struct x86_emulate_ctxt *ctxt, gva_t addr, void *val,
+			      unsigned int bytes, struct x86_exception *exception,
+			      bool system)
+{
+	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
+	u32 access = PFERR_WRITE_MASK;
+
+	if (!system && kvm_x86_ops->get_cpl(vcpu) == 3)
+		access |= PFERR_USER_MASK;
+
+	return kvm_write_guest_virt_helper(addr, val, bytes, vcpu,
+					   access, exception);
+}
+
+int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu, gva_t addr, void *val,
+				unsigned int bytes, struct x86_exception *exception)
+{
+	return kvm_write_guest_virt_helper(addr, val, bytes, vcpu,
+					   PFERR_WRITE_MASK, exception);
+}
 EXPORT_SYMBOL_GPL(kvm_write_guest_virt_system);
 
 static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva,
@@ -5180,8 +5203,8 @@
 static const struct x86_emulate_ops emulate_ops = {
 	.read_gpr            = emulator_read_gpr,
 	.write_gpr           = emulator_write_gpr,
-	.read_std            = kvm_read_guest_virt_system,
-	.write_std           = kvm_write_guest_virt_system,
+	.read_std            = emulator_read_std,
+	.write_std           = emulator_write_std,
 	.read_phys           = kvm_read_guest_phys_system,
 	.fetch               = kvm_fetch_guest_virt,
 	.read_emulated       = emulator_read_emulated,
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index e8ff3e4..2133a18 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -161,11 +161,11 @@
 void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr);
 u64 get_kvmclock_ns(struct kvm *kvm);
 
-int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt,
+int kvm_read_guest_virt(struct kvm_vcpu *vcpu,
 	gva_t addr, void *val, unsigned int bytes,
 	struct x86_exception *exception);
 
-int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt,
+int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu,
 	gva_t addr, void *val, unsigned int bytes,
 	struct x86_exception *exception);
 
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index e3a3f5a..2986a13 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -472,6 +472,12 @@
 		cpuid_leaf1_ecx_set_mask = (1 << (X86_FEATURE_MWAIT % 32));
 }
 
+static void __init xen_init_capabilities(void)
+{
+	if (xen_pv_domain())
+		setup_force_cpu_cap(X86_FEATURE_XENPV);
+}
+
 static void xen_set_debugreg(int reg, unsigned long val)
 {
 	HYPERVISOR_set_debugreg(reg, val);
@@ -1634,6 +1640,7 @@
 
 	xen_init_irq_ops();
 	xen_init_cpuid_mask();
+	xen_init_capabilities();
 
 #ifdef CONFIG_X86_LOCAL_APIC
 	/*
@@ -1978,12 +1985,6 @@
 }
 EXPORT_SYMBOL_GPL(xen_hvm_need_lapic);
 
-static void xen_set_cpu_features(struct cpuinfo_x86 *c)
-{
-	if (xen_pv_domain())
-		set_cpu_cap(c, X86_FEATURE_XENPV);
-}
-
 static void xen_pin_vcpu(int cpu)
 {
 	static bool disable_pinning;
@@ -2030,7 +2031,6 @@
 	.init_platform		= xen_hvm_guest_init,
 #endif
 	.x2apic_available	= xen_x2apic_para_available,
-	.set_cpu_features       = xen_set_cpu_features,
 	.pin_vcpu               = xen_pin_vcpu,
 };
 EXPORT_SYMBOL(x86_hyper_xen);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 0e2c0ac..82c59a1 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4426,9 +4426,6 @@
 						ATA_HORKAGE_ZERO_AFTER_TRIM |
 						ATA_HORKAGE_NOLPM, },
 
-	/* Sandisk devices which are known to not handle LPM well */
-	{ "SanDisk SD7UB3Q*G1001",	NULL,	ATA_HORKAGE_NOLPM, },
-
 	/* devices that don't properly handle queued TRIM commands */
 	{ "Micron_M500IT_*",		"MU01",	ATA_HORKAGE_NO_NCQ_TRIM |
 						ATA_HORKAGE_ZERO_AFTER_TRIM, },
diff --git a/drivers/ata/libata-zpodd.c b/drivers/ata/libata-zpodd.c
index f3a65a3..0ad96c6 100644
--- a/drivers/ata/libata-zpodd.c
+++ b/drivers/ata/libata-zpodd.c
@@ -34,7 +34,7 @@
 static int eject_tray(struct ata_device *dev)
 {
 	struct ata_taskfile tf;
-	const char cdb[] = {  GPCMD_START_STOP_UNIT,
+	static const char cdb[ATAPI_CDB_LEN] = {  GPCMD_START_STOP_UNIT,
 		0, 0, 0,
 		0x02,     /* LoEj */
 		0, 0, 0, 0, 0, 0, 0,
@@ -55,7 +55,7 @@
 	unsigned int ret;
 	struct rm_feature_desc *desc = (void *)(buf + 8);
 	struct ata_taskfile tf;
-	char cdb[] = {  GPCMD_GET_CONFIGURATION,
+	static const char cdb[] = {  GPCMD_GET_CONFIGURATION,
 			2,      /* only 1 feature descriptor requested */
 			0, 3,   /* 3, removable medium feature */
 			0, 0, 0,/* reserved */
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index 81bfeec..d0fac64 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -1151,8 +1151,8 @@
 }
 
 
-static unsigned char eprom_try_esi(struct atm_dev *dev, unsigned short cmd,
-				   int offset, int swap)
+static int eprom_try_esi(struct atm_dev *dev, unsigned short cmd, int offset,
+			 int swap)
 {
 	unsigned char buf[ZEPROM_SIZE];
 	struct zatm_dev *zatm_dev;
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 4272868..4bb8016 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -764,7 +764,7 @@
 
 	dir = kzalloc(sizeof(*dir), GFP_KERNEL);
 	if (!dir)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	dir->class = class;
 	kobject_init(&dir->kobj, &class_dir_ktype);
@@ -774,7 +774,7 @@
 	retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name);
 	if (retval < 0) {
 		kobject_put(&dir->kobj);
-		return NULL;
+		return ERR_PTR(retval);
 	}
 	return &dir->kobj;
 }
@@ -1081,6 +1081,10 @@
 
 	parent = get_device(dev->parent);
 	kobj = get_device_parent(dev, parent);
+	if (IS_ERR(kobj)) {
+		error = PTR_ERR(kobj);
+		goto parent_error;
+	}
 	if (kobj)
 		dev->kobj.parent = kobj;
 
@@ -1179,6 +1183,7 @@
 	kobject_del(&dev->kobj);
  Error:
 	cleanup_glue_dir(dev, glue_dir);
+parent_error:
 	put_device(parent);
 name_error:
 	kfree(dev->p);
@@ -1996,6 +2001,11 @@
 	device_pm_lock();
 	new_parent = get_device(new_parent);
 	new_parent_kobj = get_device_parent(dev, new_parent);
+	if (IS_ERR(new_parent_kobj)) {
+		error = PTR_ERR(new_parent_kobj);
+		put_device(new_parent);
+		goto out;
+	}
 
 	pr_debug("device: '%s': %s: moving to '%s'\n", dev_name(dev),
 		 __func__, new_parent ? dev_name(new_parent) : "<NULL>");
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index d84dea6..6aa60b1 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -3512,8 +3512,16 @@
 				pdr->domain_list[i].name,
 				pdr->domain_list[i].instance_id,
 				&spd->pdrnb, &curr_state);
-			if (IS_ERR(spd->pdrhandle))
+			if (IS_ERR(spd->pdrhandle)) {
 				pr_err("ADSPRPC: Unable to register notifier\n");
+			} else if (curr_state ==
+				SERVREG_NOTIF_SERVICE_STATE_UP_V01) {
+				pr_info("ADSPRPC: STATE_UP_V01 received\n");
+				spd->ispdup = 1;
+			} else if (curr_state ==
+				SERVREG_NOTIF_SERVICE_STATE_UNINIT_V01) {
+				pr_info("ADSPRPC: STATE_UNINIT_V01 received\n");
+			}
 			break;
 		}
 	}
diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c
index a7f29e6..acee74a 100644
--- a/drivers/char/diag/diag_debugfs.c
+++ b/drivers/char/diag/diag_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-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
@@ -797,6 +797,7 @@
 	return ret;
 }
 
+#ifdef CONFIG_IPC_LOGGING
 static ssize_t diag_dbgfs_write_debug(struct file *fp, const char __user *buf,
 				      size_t count, loff_t *ppos)
 {
@@ -827,6 +828,7 @@
 	diag_debug_mask = (uint16_t)value;
 	return count;
 }
+#endif
 
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
 #ifdef CONFIG_USB_QCOM_DIAG_BRIDGE
@@ -1086,9 +1088,11 @@
 	.read = diag_dbgfs_read_power,
 };
 
+#ifdef CONFIG_IPC_LOGGING
 const struct file_operations diag_dbgfs_debug_ops = {
 	.write = diag_dbgfs_write_debug
 };
+#endif
 
 int diag_debugfs_init(void)
 {
@@ -1145,11 +1149,12 @@
 	if (!entry)
 		goto err;
 
+#ifdef CONFIG_IPC_LOGGING
 	entry = debugfs_create_file("debug", 0444, diag_dbgfs_dent, 0,
 				    &diag_dbgfs_debug_ops);
 	if (!entry)
 		goto err;
-
+#endif
 #ifdef CONFIG_DIAGFWD_BRIDGE_CODE
 	entry = debugfs_create_file("bridge", 0444, diag_dbgfs_dent, 0,
 				    &diag_dbgfs_bridge_ops);
diff --git a/drivers/char/diag/diag_ipc_logging.h b/drivers/char/diag/diag_ipc_logging.h
index 4b8dd1b..839c8ca 100644
--- a/drivers/char/diag/diag_ipc_logging.h
+++ b/drivers/char/diag/diag_ipc_logging.h
@@ -26,9 +26,7 @@
 #define DIAG_DEBUG_BRIDGE	0x0040
 #define DIAG_DEBUG_CONTROL	0x0080
 
-#define DIAG_DEBUG
-
-#ifdef DIAG_DEBUG
+#ifdef CONFIG_IPC_LOGGING
 extern uint16_t diag_debug_mask;
 extern void *diag_ipc_log;
 
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index a169230..8b089eb 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -162,7 +162,7 @@
 
 #define DIAGPKT_MAX_DELAYED_RSP 0xFFFF
 
-#ifdef DIAG_DEBUG
+#ifdef CONFIG_IPC_LOGGING
 uint16_t diag_debug_mask;
 void *diag_ipc_log;
 #endif
@@ -3804,7 +3804,7 @@
 		pm_relax(driver->diag_dev);
 }
 
-#ifdef DIAG_DEBUG
+#ifdef CONFIG_IPC_LOGGING
 static void diag_debug_init(void)
 {
 	diag_ipc_log = ipc_log_context_create(DIAG_IPC_LOG_PAGES, "diag", 0);
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 9ff8532..8d097d1 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -26,6 +26,7 @@
 #include <linux/spinlock.h>
 #include <linux/freezer.h>
 #include <linux/major.h>
+#include <linux/of.h>
 #include "tpm.h"
 #include "tpm_eventlog.h"
 
@@ -388,8 +389,20 @@
  */
 int tpm_chip_register(struct tpm_chip *chip)
 {
+#ifdef CONFIG_OF
+	struct device_node *np;
+#endif
 	int rc;
 
+#ifdef CONFIG_OF
+	np = of_find_node_by_name(NULL, "vtpm");
+	if (np) {
+		if (of_property_read_bool(np, "powered-while-suspended"))
+			chip->flags |= TPM_CHIP_FLAG_ALWAYS_POWERED;
+	}
+	of_node_put(np);
+#endif
+
 	if (chip->ops->flags & TPM_OPS_AUTO_STARTUP) {
 		if (chip->flags & TPM_CHIP_FLAG_TPM2)
 			rc = tpm2_auto_startup(chip);
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 830d7e3..faf2db1 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -803,6 +803,10 @@
 	loops = jiffies_to_msecs(duration) / delay_msec;
 
 	rc = tpm_continue_selftest(chip);
+	if (rc == TPM_ERR_INVALID_POSTINIT) {
+		chip->flags |= TPM_CHIP_FLAG_ALWAYS_POWERED;
+		dev_info(&chip->dev, "TPM not ready (%d)\n", rc);
+	}
 	/* This may fail if there was no TPM driver during a suspend/resume
 	 * cycle; some may return 10 (BAD_ORDINAL), others 28 (FAILEDSELFTEST)
 	 */
@@ -969,6 +973,9 @@
 	if (chip == NULL)
 		return -ENODEV;
 
+	if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED)
+		return 0;
+
 	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
 		tpm2_shutdown(chip, TPM2_SU_STATE);
 		return 0;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index aa4299c..a4fc2ba 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -143,6 +143,7 @@
 	TPM_CHIP_FLAG_TPM2		= BIT(1),
 	TPM_CHIP_FLAG_IRQ		= BIT(2),
 	TPM_CHIP_FLAG_VIRTUAL		= BIT(3),
+	TPM_CHIP_FLAG_ALWAYS_POWERED	= BIT(5),
 };
 
 struct tpm_chip {
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index f474e70..6e16d9f 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -773,6 +773,8 @@
 	struct cpufreq_policy new_policy;				\
 									\
 	memcpy(&new_policy, policy, sizeof(*policy));			\
+	new_policy.min = policy->user_policy.min;			\
+	new_policy.max = policy->user_policy.max;			\
 									\
 	new_policy.min = new_policy.user_policy.min;			\
 	new_policy.max = new_policy.user_policy.max;			\
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index d8305dd..ff6ac4e 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -1081,7 +1081,7 @@
 
 	if (test_bit(FLAGS_SGS_COPIED, &dd->flags))
 		free_pages((unsigned long)sg_virt(ctx->sg),
-			   get_order(ctx->sg->length));
+			   get_order(ctx->sg->length + ctx->bufcnt));
 
 	if (test_bit(FLAGS_SGS_ALLOCED, &dd->flags))
 		kfree(ctx->sg);
diff --git a/drivers/crypto/vmx/aes.c b/drivers/crypto/vmx/aes.c
index 022c7ab..b0cd5af 100644
--- a/drivers/crypto/vmx/aes.c
+++ b/drivers/crypto/vmx/aes.c
@@ -53,8 +53,6 @@
 		       alg, PTR_ERR(fallback));
 		return PTR_ERR(fallback);
 	}
-	printk(KERN_INFO "Using '%s' as fallback implementation.\n",
-	       crypto_tfm_alg_driver_name((struct crypto_tfm *) fallback));
 
 	crypto_cipher_set_flags(fallback,
 				crypto_cipher_get_flags((struct
diff --git a/drivers/crypto/vmx/aes_cbc.c b/drivers/crypto/vmx/aes_cbc.c
index 94ad5c0..4613170 100644
--- a/drivers/crypto/vmx/aes_cbc.c
+++ b/drivers/crypto/vmx/aes_cbc.c
@@ -55,8 +55,6 @@
 		       alg, PTR_ERR(fallback));
 		return PTR_ERR(fallback);
 	}
-	printk(KERN_INFO "Using '%s' as fallback implementation.\n",
-	       crypto_tfm_alg_driver_name((struct crypto_tfm *) fallback));
 
 	crypto_blkcipher_set_flags(
 		fallback,
diff --git a/drivers/crypto/vmx/aes_ctr.c b/drivers/crypto/vmx/aes_ctr.c
index 7cf6d31..6ef7548 100644
--- a/drivers/crypto/vmx/aes_ctr.c
+++ b/drivers/crypto/vmx/aes_ctr.c
@@ -53,8 +53,6 @@
 		       alg, PTR_ERR(fallback));
 		return PTR_ERR(fallback);
 	}
-	printk(KERN_INFO "Using '%s' as fallback implementation.\n",
-	       crypto_tfm_alg_driver_name((struct crypto_tfm *) fallback));
 
 	crypto_blkcipher_set_flags(
 		fallback,
diff --git a/drivers/crypto/vmx/ghash.c b/drivers/crypto/vmx/ghash.c
index 27a94a1..1c4b5b8 100644
--- a/drivers/crypto/vmx/ghash.c
+++ b/drivers/crypto/vmx/ghash.c
@@ -64,8 +64,6 @@
 		       alg, PTR_ERR(fallback));
 		return PTR_ERR(fallback);
 	}
-	printk(KERN_INFO "Using '%s' as fallback implementation.\n",
-	       crypto_tfm_alg_driver_name(crypto_shash_tfm(fallback)));
 
 	crypto_shash_set_flags(fallback,
 			       crypto_shash_get_flags((struct crypto_shash
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 6b54e02..e48140e 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -551,7 +551,7 @@
 struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
 					enum dma_data_direction direction)
 {
-	struct sg_table *sg_table = ERR_PTR(-EINVAL);
+	struct sg_table *sg_table;
 
 	might_sleep();
 
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 56b2419..dd00764 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -3204,6 +3204,8 @@
 	struct gpio_desc *desc = NULL;
 	int status;
 	enum gpio_lookup_flags lookupflags = 0;
+	/* Maybe we have a device name, maybe not */
+	const char *devname = dev ? dev_name(dev) : "?";
 
 	dev_dbg(dev, "GPIO lookup for consumer %s\n", con_id);
 
@@ -3232,8 +3234,11 @@
 		return desc;
 	}
 
-	/* If a connection label was passed use that, else use the device name as label */
-	status = gpiod_request(desc, con_id ? con_id : dev_name(dev));
+	/*
+	 * If a connection label was passed use that, else attempt to use
+	 * the device name as label
+	 */
+	status = gpiod_request(desc, con_id ? con_id : devname);
 	if (status < 0)
 		return ERR_PTR(status);
 
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 6394109..876a2d9 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -1062,6 +1062,7 @@
 	static const u16 psr_setup_time_us[] = {
 		PSR_SETUP_TIME(330),
 		PSR_SETUP_TIME(275),
+		PSR_SETUP_TIME(220),
 		PSR_SETUP_TIME(165),
 		PSR_SETUP_TIME(110),
 		PSR_SETUP_TIME(55),
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index ca227e8..847ba40 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -205,6 +205,7 @@
 		return -ENOMEM;
 
 	filp->private_data = priv;
+	filp->f_mode |= FMODE_UNSIGNED_OFFSET;
 	priv->filp = filp;
 	priv->pid = get_pid(task_pid(current));
 	priv->minor = minor;
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 3517c0e..479d641 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -864,6 +864,14 @@
 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"),
 		},
 	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Radiant P845",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Radiant Systems Inc"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "P845"),
+		},
+	},
 
 	{ }	/* terminating entry */
 };
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index fcdddb3..978aba2 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -158,6 +158,7 @@
 	CRTC_PROP_CAPTURE_OUTPUT,
 
 	CRTC_PROP_ENABLE_SUI_ENHANCEMENT,
+	CRTC_PROP_IDLE_PC_STATE,
 
 	/* total # of properties */
 	CRTC_PROP_COUNT
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index 34d8400..8af8298 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -3689,6 +3689,7 @@
 	struct sde_kms *sde_kms;
 	struct sde_crtc_state *cstate;
 	bool is_error, reset_req;
+	enum sde_crtc_idle_pc_state idle_pc_state;
 
 	if (!crtc) {
 		SDE_ERROR("invalid argument\n");
@@ -3719,6 +3720,8 @@
 
 	is_error = _sde_crtc_prepare_for_kickoff_rot(dev, crtc);
 
+	idle_pc_state = sde_crtc_get_property(cstate, CRTC_PROP_IDLE_PC_STATE);
+
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 		struct sde_encoder_kickoff_params params = { 0 };
 
@@ -3734,6 +3737,10 @@
 				crtc->state);
 		if (sde_encoder_prepare_for_kickoff(encoder, &params))
 			reset_req = true;
+
+		if (idle_pc_state != IDLE_PC_NONE)
+			sde_encoder_control_idle_pc(encoder,
+			    (idle_pc_state == IDLE_PC_ENABLE) ? true : false);
 	}
 
 	/*
@@ -4233,6 +4240,13 @@
 		sde_encoder_register_frame_event_callback(encoder, NULL, NULL);
 		cstate->rsc_client = NULL;
 		cstate->rsc_update = false;
+
+		/*
+		 * reset idle power-collapse to original state during suspend;
+		 * user-mode will change the state on resume, if required
+		 */
+		if (sde_kms->catalog->has_idle_pc)
+			sde_encoder_control_idle_pc(encoder, true);
 	}
 
 	if (sde_crtc->power_event)
@@ -4976,6 +4990,12 @@
 		{CAPTURE_DSPP_OUT, "capture_pp_out"},
 	};
 
+	static const struct drm_prop_enum_list e_idle_pc_state[] = {
+		{IDLE_PC_NONE, "idle_pc_none"},
+		{IDLE_PC_ENABLE, "idle_pc_enable"},
+		{IDLE_PC_DISABLE, "idle_pc_disable"},
+	};
+
 	SDE_DEBUG("\n");
 
 	if (!crtc || !catalog) {
@@ -5055,6 +5075,12 @@
 		"enable_sui_enhancement", 0, 0, U64_MAX, 0,
 		CRTC_PROP_ENABLE_SUI_ENHANCEMENT);
 
+	if (catalog->has_idle_pc)
+		msm_property_install_enum(&sde_crtc->property_info,
+			"idle_pc_state", 0x0, 0, e_idle_pc_state,
+			ARRAY_SIZE(e_idle_pc_state),
+			CRTC_PROP_IDLE_PC_STATE);
+
 	if (catalog->has_cwb_support)
 		msm_property_install_enum(&sde_crtc->property_info,
 				"capture_mode", 0, 0, e_cwb_data_points,
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h
index 99177b1..709a51f 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.h
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.h
@@ -59,6 +59,18 @@
 };
 
 /**
+ * enum sde_crtc_idle_pc_state: states of idle power collapse
+ * @IDLE_PC_NONE: no-op
+ * @IDLE_PC_ENABLE: enable idle power-collapse
+ * @IDLE_PC_DISABLE: disable idle power-collapse
+ */
+enum sde_crtc_idle_pc_state {
+	IDLE_PC_NONE,
+	IDLE_PC_ENABLE,
+	IDLE_PC_DISABLE,
+};
+
+/**
  * @connectors    : Currently associated drm connectors for retire event
  * @num_connectors: Number of associated drm connectors for retire event
  * @list:	event list
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index 73864b6..a6643bb 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -200,7 +200,8 @@
  * @disp_info:			local copy of msm_display_info struct
  * @misr_enable:		misr enable/disable status
  * @misr_frame_count:		misr frame count before start capturing the data
- * @idle_pc_supported:		indicate if idle power collaps is supported
+ * @idle_pc_enabled:		indicate if idle power collapse is enabled
+ *				currently. This can be controlled by user-mode
  * @rc_lock:			resource control mutex lock to protect
  *				virt encoder over various state changes
  * @rc_state:			resource controller state
@@ -250,7 +251,7 @@
 	bool misr_enable;
 	u32 misr_frame_count;
 
-	bool idle_pc_supported;
+	bool idle_pc_enabled;
 	struct mutex rc_lock;
 	enum sde_enc_rc_states rc_state;
 	struct kthread_delayed_work delayed_off_work;
@@ -1922,6 +1923,25 @@
 				&sde_enc->input_event_work);
 }
 
+void sde_encoder_control_idle_pc(struct drm_encoder *drm_enc, bool enable)
+{
+	struct sde_encoder_virt *sde_enc;
+
+	if (!drm_enc) {
+		SDE_ERROR("invalid encoder\n");
+		return;
+	}
+	sde_enc = to_sde_encoder_virt(drm_enc);
+
+	/* return early if there is no state change */
+	if (sde_enc->idle_pc_enabled == enable)
+		return;
+
+	sde_enc->idle_pc_enabled = enable;
+
+	SDE_DEBUG("idle-pc state:%d\n", sde_enc->idle_pc_enabled);
+	SDE_EVT32(sde_enc->idle_pc_enabled);
+}
 
 static int sde_encoder_resource_control(struct drm_encoder *drm_enc,
 		u32 sw_event)
@@ -1948,7 +1968,7 @@
 	 * when idle_pc is not supported, process only KICKOFF, STOP and MODESET
 	 * events and return early for other events (ie wb display).
 	 */
-	if (!sde_enc->idle_pc_supported &&
+	if (!sde_enc->idle_pc_enabled &&
 			(sw_event != SDE_ENC_RC_EVENT_KICKOFF &&
 			sw_event != SDE_ENC_RC_EVENT_PRE_MODESET &&
 			sw_event != SDE_ENC_RC_EVENT_POST_MODESET &&
@@ -1956,9 +1976,9 @@
 			sw_event != SDE_ENC_RC_EVENT_PRE_STOP))
 		return 0;
 
-	SDE_DEBUG_ENC(sde_enc, "sw_event:%d, idle_pc_supported:%d\n", sw_event,
-			sde_enc->idle_pc_supported);
-	SDE_EVT32_VERBOSE(DRMID(drm_enc), sw_event, sde_enc->idle_pc_supported,
+	SDE_DEBUG_ENC(sde_enc, "sw_event:%d, idle_pc:%d\n",
+			sw_event, sde_enc->idle_pc_enabled);
+	SDE_EVT32_VERBOSE(DRMID(drm_enc), sw_event, sde_enc->idle_pc_enabled,
 			sde_enc->rc_state, SDE_EVTLOG_FUNC_ENTRY);
 
 	switch (sw_event) {
@@ -2348,7 +2368,7 @@
 		break;
 	}
 
-	SDE_EVT32_VERBOSE(DRMID(drm_enc), sw_event, sde_enc->idle_pc_supported,
+	SDE_EVT32_VERBOSE(DRMID(drm_enc), sw_event, sde_enc->idle_pc_enabled,
 			sde_enc->rc_state, SDE_EVTLOG_FUNC_EXIT);
 	return 0;
 }
@@ -4483,7 +4503,7 @@
 
 	if ((disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) ||
 	    (disp_info->capabilities & MSM_DISPLAY_CAP_VID_MODE))
-		sde_enc->idle_pc_supported = sde_kms->catalog->has_idle_pc;
+		sde_enc->idle_pc_enabled = sde_kms->catalog->has_idle_pc;
 
 	mutex_lock(&sde_enc->enc_lock);
 	for (i = 0; i < disp_info->num_of_h_tiles && !ret; i++) {
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.h b/drivers/gpu/drm/msm/sde/sde_encoder.h
index 42b9e58..c40db41 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.h
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.h
@@ -257,4 +257,11 @@
  */
 int sde_encoder_in_clone_mode(struct drm_encoder *enc);
 
+/**
+ * sde_encoder_control_idle_pc - control enable/disable of idle power collapse
+ * @drm_enc:    Pointer to drm encoder structure
+ * @enable:	enable/disable flag
+ */
+void sde_encoder_control_idle_pc(struct drm_encoder *enc, bool enable);
+
 #endif /* __SDE_ENCODER_H__ */
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
index d363d62..74bf518 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
@@ -40,6 +40,20 @@
 #define POLL_TIME_USEC_FOR_LN_CNT 500
 #define MAX_POLL_CNT 10
 
+static bool _sde_encoder_phys_is_ppsplit(struct sde_encoder_phys *phys_enc)
+{
+	enum sde_rm_topology_name topology;
+
+	if (!phys_enc)
+		return false;
+
+	topology = sde_connector_get_topology_name(phys_enc->connector);
+	if (topology == SDE_RM_TOPOLOGY_PPSPLIT)
+		return true;
+
+	return false;
+}
+
 static bool sde_encoder_phys_vid_is_master(
 		struct sde_encoder_phys *phys_enc)
 {
@@ -313,12 +327,14 @@
 	if (!phys_enc->sde_kms->splash_data.cont_splash_en) {
 		SDE_EVT32(DRMID(phys_enc->parent), f.enable, f.fetch_start);
 
-		phys_enc->hw_ctl->ops.get_bitmask_intf(
-				phys_enc->hw_ctl, &flush_mask,
-				vid_enc->hw_intf->idx);
-		phys_enc->hw_ctl->ops.update_pending_flush(
-				phys_enc->hw_ctl, flush_mask);
-
+		if (!_sde_encoder_phys_is_ppsplit(phys_enc) ||
+			sde_encoder_phys_vid_is_master(phys_enc)) {
+			phys_enc->hw_ctl->ops.get_bitmask_intf(
+					phys_enc->hw_ctl, &flush_mask,
+					vid_enc->hw_intf->idx);
+			phys_enc->hw_ctl->ops.update_pending_flush(
+					phys_enc->hw_ctl, flush_mask);
+		}
 		spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
 		vid_enc->hw_intf->ops.setup_rot_start(vid_enc->hw_intf, &f);
 		spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
@@ -496,20 +512,6 @@
 			phys_enc);
 }
 
-static bool _sde_encoder_phys_is_ppsplit(struct sde_encoder_phys *phys_enc)
-{
-	enum sde_rm_topology_name topology;
-
-	if (!phys_enc)
-		return false;
-
-	topology = sde_connector_get_topology_name(phys_enc->connector);
-	if (topology == SDE_RM_TOPOLOGY_PPSPLIT)
-		return true;
-
-	return false;
-}
-
 static bool _sde_encoder_phys_is_dual_ctl(struct sde_encoder_phys *phys_enc)
 {
 	enum sde_rm_topology_name topology;
diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
index 20d647d..00aafe0 100644
--- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c
+++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
@@ -202,8 +202,7 @@
 	kfree(ishtp_dev);
 }
 
-#ifdef CONFIG_PM
-static struct device *ish_resume_device;
+static struct device __maybe_unused *ish_resume_device;
 
 /**
  * ish_resume_handler() - Work function to complete resume
@@ -214,7 +213,7 @@
  * in that case a simple resume message is enough, others we need
  * a reset sequence.
  */
-static void ish_resume_handler(struct work_struct *work)
+static void __maybe_unused ish_resume_handler(struct work_struct *work)
 {
 	struct pci_dev *pdev = to_pci_dev(ish_resume_device);
 	struct ishtp_device *dev = pci_get_drvdata(pdev);
@@ -245,7 +244,7 @@
  *
  * Return: 0 to the pm core
  */
-static int ish_suspend(struct device *device)
+static int __maybe_unused ish_suspend(struct device *device)
 {
 	struct pci_dev *pdev = to_pci_dev(device);
 	struct ishtp_device *dev = pci_get_drvdata(pdev);
@@ -271,7 +270,7 @@
 	return 0;
 }
 
-static DECLARE_WORK(resume_work, ish_resume_handler);
+static __maybe_unused DECLARE_WORK(resume_work, ish_resume_handler);
 /**
  * ish_resume() - ISH resume callback
  * @device:	device pointer
@@ -280,7 +279,7 @@
  *
  * Return: 0 to the pm core
  */
-static int ish_resume(struct device *device)
+static int __maybe_unused ish_resume(struct device *device)
 {
 	struct pci_dev *pdev = to_pci_dev(device);
 	struct ishtp_device *dev = pci_get_drvdata(pdev);
@@ -294,21 +293,14 @@
 	return 0;
 }
 
-static const struct dev_pm_ops ish_pm_ops = {
-	.suspend = ish_suspend,
-	.resume = ish_resume,
-};
-#define ISHTP_ISH_PM_OPS	(&ish_pm_ops)
-#else
-#define ISHTP_ISH_PM_OPS	NULL
-#endif /* CONFIG_PM */
+static SIMPLE_DEV_PM_OPS(ish_pm_ops, ish_suspend, ish_resume);
 
 static struct pci_driver ish_driver = {
 	.name = KBUILD_MODNAME,
 	.id_table = ish_pci_tbl,
 	.probe = ish_probe,
 	.remove = ish_remove,
-	.driver.pm = ISHTP_ISH_PM_OPS,
+	.driver.pm = &ish_pm_ops,
 };
 
 module_pci_driver(ish_driver);
diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c
index b8e2992..f260922 100644
--- a/drivers/hwtracing/stm/core.c
+++ b/drivers/hwtracing/stm/core.c
@@ -27,6 +27,7 @@
 #include <linux/stm.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
+#include <linux/vmalloc.h>
 #include "stm.h"
 
 #include <uapi/linux/stm.h>
@@ -689,7 +690,7 @@
 {
 	struct stm_device *stm = to_stm_device(dev);
 
-	kfree(stm);
+	vfree(stm);
 }
 
 int stm_register_device(struct device *parent, struct stm_data *stm_data,
@@ -706,7 +707,7 @@
 		return -EINVAL;
 
 	nmasters = stm_data->sw_end - stm_data->sw_start + 1;
-	stm = kzalloc(sizeof(*stm) + nmasters * sizeof(void *), GFP_KERNEL);
+	stm = vzalloc(sizeof(*stm) + nmasters * sizeof(void *));
 	if (!stm)
 		return -ENOMEM;
 
@@ -759,7 +760,7 @@
 	/* matches device_initialize() above */
 	put_device(&stm->dev);
 err_free:
-	kfree(stm);
+	vfree(stm);
 
 	return err;
 }
diff --git a/drivers/iio/buffer/kfifo_buf.c b/drivers/iio/buffer/kfifo_buf.c
index c5b999f..7ef9b13 100644
--- a/drivers/iio/buffer/kfifo_buf.c
+++ b/drivers/iio/buffer/kfifo_buf.c
@@ -24,6 +24,13 @@
 	if ((length == 0) || (bytes_per_datum == 0))
 		return -EINVAL;
 
+	/*
+	 * Make sure we don't overflow an unsigned int after kfifo rounds up to
+	 * the next power of 2.
+	 */
+	if (roundup_pow_of_two(length) > UINT_MAX / bytes_per_datum)
+		return -EINVAL;
+
 	return __kfifo_alloc((struct __kfifo *)&buf->kf, length,
 			     bytes_per_datum, GFP_KERNEL);
 }
diff --git a/drivers/iio/imu/inv_icm20602/inv_icm20602_core.c b/drivers/iio/imu/inv_icm20602/inv_icm20602_core.c
index 7dda14e..bf8e968 100644
--- a/drivers/iio/imu/inv_icm20602/inv_icm20602_core.c
+++ b/drivers/iio/imu/inv_icm20602/inv_icm20602_core.c
@@ -31,6 +31,9 @@
 #include "inv_icm20602_iio.h"
 #include <linux/regulator/consumer.h>
 
+
+static struct regulator *reg_ldo;
+
 /* Attribute of icm20602 device init show */
 static ssize_t inv_icm20602_init_show(struct device *dev,
 	struct device_attribute *attr, char *buf)
@@ -384,19 +387,19 @@
 	int ret = 0;
 
 	if (enable) {
-		ret = regulator_set_voltage(st->reg_ldo,
+		ret = regulator_set_voltage(reg_ldo,
 			ICM20602_LDO_VTG_MIN_UV, ICM20602_LDO_VTG_MAX_UV);
 		if (ret)
 			pr_err("Failed to request LDO voltage.\n");
 
-		ret = regulator_enable(st->reg_ldo);
+		ret = regulator_enable(reg_ldo);
 		if (ret)
 			pr_err("Failed to enable LDO %d\n", ret);
 	} else {
-		ret = regulator_disable(st->reg_ldo);
+		ret = regulator_disable(reg_ldo);
+		regulator_set_load(reg_ldo, 0);
 		if (ret)
 			pr_err("Failed to disable LDO %d\n", ret);
-		regulator_set_load(st->reg_ldo, 0);
 	}
 
 	return MPU_SUCCESS;
@@ -405,14 +408,13 @@
 static int icm20602_init_regulators(struct inv_icm20602_state *st)
 {
 	struct regulator *reg;
-
 	reg = regulator_get(&st->client->dev, "vdd-ldo");
 	if (IS_ERR_OR_NULL(reg)) {
 		pr_err("Unable to get regulator for LDO\n");
 		return -MPU_FAIL;
 	}
 
-	st->reg_ldo = reg;
+	reg_ldo = reg;
 
 	return MPU_SUCCESS;
 }
diff --git a/drivers/iio/imu/inv_icm20602/inv_icm20602_iio.h b/drivers/iio/imu/inv_icm20602/inv_icm20602_iio.h
index b369ae4..36f8e9c 100644
--- a/drivers/iio/imu/inv_icm20602/inv_icm20602_iio.h
+++ b/drivers/iio/imu/inv_icm20602/inv_icm20602_iio.h
@@ -41,8 +41,8 @@
 #define INV20602_SMD_IRQ_TRIGGER    1
 #endif
 
-#define ICM20602_LDO_VTG_MIN_UV 3300000
-#define ICM20602_LDO_VTG_MAX_UV 3300000
+#define ICM20602_LDO_VTG_MIN_UV 1800000
+#define ICM20602_LDO_VTG_MAX_UV 1800000
 
 #define INV_ICM20602_TIME_STAMP_TOR           5
 #define ICM20602_PACKAGE_SIZE 14
@@ -220,7 +220,6 @@
 	struct struct_icm20602_data *data_push;
 	enum inv_devices chip_type;
 	int gpio;
-	struct regulator *reg_ldo;
 	DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE);
 };
 
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index ae04826..a32dd85 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -437,7 +437,7 @@
 		return -EINVAL;
 
 	if (table->data_vec[index].props & GID_TABLE_ENTRY_INVALID)
-		return -EAGAIN;
+		return -EINVAL;
 
 	memcpy(gid, &table->data_vec[index].gid, sizeof(*gid));
 	if (attr) {
diff --git a/drivers/input/misc/qpnp-power-on.c b/drivers/input/misc/qpnp-power-on.c
index 93c28ef..65379ed 100644
--- a/drivers/input/misc/qpnp-power-on.c
+++ b/drivers/input/misc/qpnp-power-on.c
@@ -487,6 +487,19 @@
 	return size;
 }
 
+static struct qpnp_pon_config *
+qpnp_get_cfg(struct qpnp_pon *pon, u32 pon_type)
+{
+	int i;
+
+	for (i = 0; i < pon->num_pon_config; i++) {
+		if (pon_type == pon->pon_cfg[i].pon_type)
+			return  &pon->pon_cfg[i];
+	}
+
+	return NULL;
+}
+
 static DEVICE_ATTR(debounce_us, 0664, qpnp_pon_dbc_show, qpnp_pon_dbc_store);
 
 #define PON_TWM_ENTRY_PBS_BIT           BIT(0)
@@ -496,6 +509,7 @@
 	int rc;
 	bool disable = false;
 	u16 rst_en_reg;
+	struct qpnp_pon_config *cfg;
 
 	/* Ignore the PS_HOLD reset config if TWM ENTRY is enabled */
 	if (pon->support_twm_config && pon->twm_state == PMIC_TWM_ENABLE) {
@@ -506,6 +520,18 @@
 							rc);
 			return rc;
 		}
+
+		cfg = qpnp_get_cfg(pon, PON_KPDPWR);
+		if (cfg) {
+			/* configure KPDPWR_S2 to Hard reset */
+			rc = qpnp_pon_masked_write(pon, cfg->s2_cntl_addr,
+						QPNP_PON_S2_CNTL_TYPE_MASK,
+						PON_POWER_OFF_HARD_RESET);
+			if (rc < 0)
+				pr_err("Unable to config KPDPWR_N S2 for hard-reset rc=%d\n",
+					rc);
+		}
+
 		pr_crit("PMIC configured for TWM entry\n");
 		return 0;
 	}
@@ -901,19 +927,6 @@
 	return 0;
 }
 
-static struct qpnp_pon_config *
-qpnp_get_cfg(struct qpnp_pon *pon, u32 pon_type)
-{
-	int i;
-
-	for (i = 0; i < pon->num_pon_config; i++) {
-		if (pon_type == pon->pon_cfg[i].pon_type)
-			return  &pon->pon_cfg[i];
-	}
-
-	return NULL;
-}
-
 static int
 qpnp_pon_input_dispatch(struct qpnp_pon *pon, u32 pon_type)
 {
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
index 3851d57..aeb8250 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -1249,6 +1249,7 @@
 	{ "ELAN060B", 0 },
 	{ "ELAN060C", 0 },
 	{ "ELAN0611", 0 },
+	{ "ELAN0612", 0 },
 	{ "ELAN1000", 0 },
 	{ }
 };
diff --git a/drivers/input/mouse/elan_i2c_smbus.c b/drivers/input/mouse/elan_i2c_smbus.c
index e23b249..05b8695 100644
--- a/drivers/input/mouse/elan_i2c_smbus.c
+++ b/drivers/input/mouse/elan_i2c_smbus.c
@@ -130,7 +130,7 @@
 					bool max_baseline, u8 *value)
 {
 	int error;
-	u8 val[3];
+	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 
 	error = i2c_smbus_read_block_data(client,
 					  max_baseline ?
@@ -149,7 +149,7 @@
 				  bool iap, u8 *version)
 {
 	int error;
-	u8 val[3];
+	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 
 	error = i2c_smbus_read_block_data(client,
 					  iap ? ETP_SMBUS_IAP_VERSION_CMD :
@@ -169,7 +169,7 @@
 				     u8 *ic_type, u8 *version)
 {
 	int error;
-	u8 val[3];
+	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 
 	error = i2c_smbus_read_block_data(client,
 					  ETP_SMBUS_SM_VERSION_CMD, val);
@@ -186,7 +186,7 @@
 static int elan_smbus_get_product_id(struct i2c_client *client, u16 *id)
 {
 	int error;
-	u8 val[3];
+	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 
 	error = i2c_smbus_read_block_data(client,
 					  ETP_SMBUS_UNIQUEID_CMD, val);
@@ -203,7 +203,7 @@
 				   bool iap, u16 *csum)
 {
 	int error;
-	u8 val[3];
+	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 
 	error = i2c_smbus_read_block_data(client,
 					  iap ? ETP_SMBUS_FW_CHECKSUM_CMD :
@@ -224,7 +224,7 @@
 {
 	int ret;
 	int error;
-	u8 val[3];
+	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 
 	ret = i2c_smbus_read_block_data(client, ETP_SMBUS_RANGE_CMD, val);
 	if (ret != 3) {
@@ -244,7 +244,7 @@
 {
 	int ret;
 	int error;
-	u8 val[3];
+	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 
 	ret = i2c_smbus_read_block_data(client, ETP_SMBUS_RESOLUTION_CMD, val);
 	if (ret != 3) {
@@ -265,7 +265,7 @@
 {
 	int ret;
 	int error;
-	u8 val[3];
+	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 
 	ret = i2c_smbus_read_block_data(client, ETP_SMBUS_XY_TRACENUM_CMD, val);
 	if (ret != 3) {
@@ -292,7 +292,7 @@
 {
 	int error;
 	u16 constant;
-	u8 val[3];
+	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 
 	error = i2c_smbus_read_block_data(client, ETP_SMBUS_IAP_CTRL_CMD, val);
 	if (error < 0) {
@@ -343,7 +343,7 @@
 	int len;
 	int error;
 	enum tp_mode mode;
-	u8 val[3];
+	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 	u8 cmd[4] = {0x0F, 0x78, 0x00, 0x06};
 	u16 password;
 
@@ -417,7 +417,7 @@
 	struct device *dev = &client->dev;
 	int error;
 	u16 result;
-	u8 val[3];
+	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 
 	/*
 	 * Due to the limitation of smbus protocol limiting
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index e9c1d69..ea37a9f 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -1299,8 +1299,7 @@
 	  HIMAX controllers are multi touch controllers which can
 	  report 10 touches at a time.
 
-	  If unsure, say N.
+          If unsure, say N.
 
 source "drivers/input/touchscreen/hxchipset/Kconfig"
-
 endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index c8e0104..acd4045 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -104,5 +104,5 @@
 obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50)	+= colibri-vf50-ts.o
 obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023)	+= rohm_bu21023.o
 obj-$(CONFIG_TOUCHSCREEN_FTS)		+= focaltech_touch/
+obj-$(CONFIG_TOUCHSCREEN_GT9XX_v28)		+= gt9xx_v2.8/
 obj-$(CONFIG_TOUCHSCREEN_HIMAX_CHIPSET)	+= hxchipset/
-obj-$(CONFIG_TOUCHSCREEN_GT9XX_v28)		+= gt9xx_v2.8/
\ No newline at end of file
diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_core.c b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c
index b3d7322..7639c9f 100644
--- a/drivers/input/touchscreen/focaltech_touch/focaltech_core.c
+++ b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c
@@ -514,11 +514,11 @@
 #endif
 		} else {
 			uppoint++;
-			input_mt_report_slot_state(data->input_dev,
-						MT_TOOL_FINGER, false);
 #if FTS_REPORT_PRESSURE_EN
 			input_report_abs(data->input_dev, ABS_MT_PRESSURE, 0);
 #endif
+			input_mt_report_slot_state(data->input_dev,
+						MT_TOOL_FINGER, false);
 			data->touchs &= ~BIT(event->au8_finger_id[i]);
 			FTS_DEBUG("[B]P%d UP!", event->au8_finger_id[i]);
 		}
diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c
index 5907fdd..c599b5a 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -858,6 +858,7 @@
 #ifdef CONFIG_ACPI
 static const struct acpi_device_id goodix_acpi_match[] = {
 	{ "GDIX1001", 0 },
+	{ "GDIX1002", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(acpi, goodix_acpi_match);
diff --git a/drivers/input/touchscreen/hxchipset/HX83100_Amber_0901_030B.i b/drivers/input/touchscreen/hxchipset/HX83100_Amber_0901_030B.i
deleted file mode 100644
index e69de29..0000000
--- a/drivers/input/touchscreen/hxchipset/HX83100_Amber_0901_030B.i
+++ /dev/null
diff --git a/drivers/input/touchscreen/hxchipset/HX_CRC_124.i b/drivers/input/touchscreen/hxchipset/HX_CRC_124.i
deleted file mode 100644
index e69de29..0000000
--- a/drivers/input/touchscreen/hxchipset/HX_CRC_124.i
+++ /dev/null
diff --git a/drivers/input/touchscreen/hxchipset/HX_CRC_128.i b/drivers/input/touchscreen/hxchipset/HX_CRC_128.i
deleted file mode 100644
index e69de29..0000000
--- a/drivers/input/touchscreen/hxchipset/HX_CRC_128.i
+++ /dev/null
diff --git a/drivers/input/touchscreen/hxchipset/HX_CRC_60.i b/drivers/input/touchscreen/hxchipset/HX_CRC_60.i
deleted file mode 100644
index e69de29..0000000
--- a/drivers/input/touchscreen/hxchipset/HX_CRC_60.i
+++ /dev/null
diff --git a/drivers/input/touchscreen/hxchipset/HX_CRC_64.i b/drivers/input/touchscreen/hxchipset/HX_CRC_64.i
deleted file mode 100644
index e69de29..0000000
--- a/drivers/input/touchscreen/hxchipset/HX_CRC_64.i
+++ /dev/null
diff --git a/drivers/input/touchscreen/hxchipset/Kconfig b/drivers/input/touchscreen/hxchipset/Kconfig
index ebf3aa4..3dc5a02 100644
--- a/drivers/input/touchscreen/hxchipset/Kconfig
+++ b/drivers/input/touchscreen/hxchipset/Kconfig
@@ -3,19 +3,44 @@
 #
 
 config TOUCHSCREEN_HIMAX_I2C
-        tristate "HIMAX chipset i2c touchscreen"
-		depends on TOUCHSCREEN_HIMAX_CHIPSET
-		help
+	tristate "HIMAX chipset i2c touchscreen"
+	depends on TOUCHSCREEN_HIMAX_CHIPSET
+	help
+		Say Y here to enable support for HIMAX CHIPSET over I2C based touchscreens.
+		If unsure, say N.
+
+		To compile this driver as a module,
 		This enables support for HIMAX CHIPSET over I2C based touchscreens.
 
 config TOUCHSCREEN_HIMAX_DEBUG
-        tristate "HIMAX debug function"
-		depends on TOUCHSCREEN_HIMAX_I2C
-		help
+	tristate "HIMAX debug function"
+	depends on TOUCHSCREEN_HIMAX_I2C
+	help
+		Say Y here to enable support for HIMAX debug function.
+
+		If unsure, say N.
+
+		To compile this driver as a module,
 		This enables support for HIMAX debug function.
 
+config TOUCHSCREEN_HIMAX_ITO_TEST
+	tristate "HIMAX driver test over Dragon Board"
+	depends on TOUCHSCREEN_HIMAX_I2C
+	help
+		Say Y here to enable support for HIMAX driver test over Dragon Board.
+
+		If unsure, say N.
+
+		To compile this driver as a module,
+		this enables support for HIMAX driver test over Dragon Board.
+
 config HMX_DB
 	tristate "HIMAX driver test over Dragon Board"
 	depends on TOUCHSCREEN_HIMAX_I2C
 	help
-	  This enables support for HIMAX driver test over Dragon Board.
+		Say Y here to enable support for HIMAX driver test over Dragon Board.
+
+		If unsure, say N.
+
+		To compile this driver as a module,
+		this enables support for HIMAX driver test over Dragon Board.
diff --git a/drivers/input/touchscreen/hxchipset/Makefile b/drivers/input/touchscreen/hxchipset/Makefile
index 509d491..522907a 100644
--- a/drivers/input/touchscreen/hxchipset/Makefile
+++ b/drivers/input/touchscreen/hxchipset/Makefile
@@ -1,3 +1,4 @@
 # Makefile for the Himax touchscreen drivers.
 
 obj-$(CONFIG_TOUCHSCREEN_HIMAX_I2C)   	+= himax_platform.o himax_ic.o himax_common.o himax_debug.o
+obj-$(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST)   	+= 	himax_ito_test.o
\ No newline at end of file
diff --git a/drivers/input/touchscreen/hxchipset/himax_common.c b/drivers/input/touchscreen/hxchipset/himax_common.c
index 417b0c0..d4bc5be 100644
--- a/drivers/input/touchscreen/hxchipset/himax_common.c
+++ b/drivers/input/touchscreen/hxchipset/himax_common.c
@@ -1,4 +1,4 @@
-/* Himax Android Driver Sample Code for Himax chipset
+	/* Himax Android Driver Sample Code for Himax chipset
 *
 * Copyright (C) 2015 Himax Corporation.
 *
@@ -21,107 +21,32 @@
 #define FRAME_COUNT 5
 
 #if defined(HX_AUTO_UPDATE_FW)
-	static unsigned char i_CTPM_FW[]=
-	{
-		#include "HX83100_Amber_0901_030B.i"
-	};
+	char *i_CTPM_firmware_name = "HX83100_Amber_0B01_030E.bin";
+	const struct firmware *i_CTPM_FW = NULL;
 #endif
 
-#ifdef HX_ESD_WORKAROUND
-	extern void HX_report_ESD_event(void);
-	unsigned char ESD_00_counter = 0;
-	unsigned char ESD_00_Flag = 0;
-#endif
-
-//static int		tpd_keys_local[HX_KEY_MAX_COUNT] = HX_KEY_ARRAY; // for Virtual key array
+/*static int tpd_keys_local[HX_KEY_MAX_COUNT] = HX_KEY_ARRAY;
+// for Virtual key array */
 
 struct himax_ts_data *private_ts;
-struct himax_ic_data* ic_data;
+struct himax_ic_data *ic_data;
 
-static int		HX_TOUCH_INFO_POINT_CNT;
+static int HX_TOUCH_INFO_POINT_CNT;
 
-#ifdef HX_AUTO_UPDATE_FW
-extern unsigned long	FW_VER_MAJ_FLASH_ADDR;
-extern unsigned long 	FW_VER_MIN_FLASH_ADDR;
-extern unsigned long 	CFG_VER_MAJ_FLASH_ADDR;
-extern unsigned long 	CFG_VER_MIN_FLASH_ADDR;
-#endif
-extern unsigned long 	FW_VER_MAJ_FLASH_LENG;
-extern unsigned long 	FW_VER_MIN_FLASH_LENG;
-extern unsigned long 	CFG_VER_MAJ_FLASH_LENG;
-extern unsigned long 	CFG_VER_MIN_FLASH_LENG;
-extern unsigned char	IC_TYPE;
-extern unsigned char	IC_CHECKSUM;
-
-#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
-extern int himax_touch_proc_init(void);
-extern void himax_touch_proc_deinit(void);
-//PROC-START
-#ifdef HX_TP_PROC_FLASH_DUMP
-extern void	himax_ts_flash_func(void);
-extern void setFlashBuffer(void);
-extern bool getFlashDumpGoing(void);
-extern uint8_t getSysOperation(void);
-extern void setSysOperation(uint8_t operation);
-#endif
-
-#ifdef HX_TP_PROC_HITOUCH
-extern bool hitouch_is_connect;
-#endif
-
-#ifdef HX_TP_PROC_DIAG
-	extern int touch_monitor_stop_flag;
-	extern int touch_monitor_stop_limit;
-	extern void	himax_ts_diag_func(void);
-	extern int16_t *getMutualBuffer(void);
-	extern int16_t *getMutualNewBuffer(void);
-	extern int16_t *getMutualOldBuffer(void);
-	extern int16_t *getSelfBuffer(void);
-	extern uint8_t getXChannel(void);
-	extern uint8_t getYChannel(void);
-	extern uint8_t getDiagCommand(void);
-	extern void setXChannel(uint8_t x);
-	extern void setYChannel(uint8_t y);
-	extern void setMutualBuffer(void);
-	extern void setMutualNewBuffer(void);
-	extern void setMutualOldBuffer(void);
-	extern uint8_t	coordinate_dump_enable;
-	extern struct file	*coordinate_fn;
-	extern uint8_t diag_coor[128];
-#ifdef HX_TP_PROC_2T2R
-	extern int16_t *getMutualBuffer_2(void);
-	extern uint8_t getXChannel_2(void);
-	extern uint8_t getYChannel_2(void);
-	extern void setXChannel_2(uint8_t x);
-	extern void setYChannel_2(uint8_t y);
-	extern void setMutualBuffer_2(void);
-#endif
-#endif
-//PROC-END
-#endif
-
-extern int himax_parse_dt(struct himax_ts_data *ts,
-				struct himax_i2c_platform_data *pdata);
-extern int himax_ts_pinctrl_init(struct himax_ts_data *ts);
-
-static uint8_t 	vk_press;
-static uint8_t 	AA_press;
-static uint8_t 	EN_NoiseFilter;
-static uint8_t	Last_EN_NoiseFilter;
-static int	hx_point_num;																	// for himax_ts_work_func use
-static int	p_point_num	= 0xFFFF;
-static int	tpd_key;
-static int	tpd_key_old;
-static int	probe_fail_flag;
-static bool	config_load;
+static uint8_t vk_press = 0x00;
+static uint8_t AA_press = 0x00;
+static uint8_t EN_NoiseFilter = 0x00;
+static int hx_point_num; /*for himax_ts_work_func use*/
+static int p_point_num = 0xFFFF;
+static int tpd_key = 0x00;
+static int tpd_key_old = 0x00;
+static int probe_fail_flag;
+static bool config_load;
 static struct himax_config *config_selected;
 
-//static int iref_number = 11;
-//static bool iref_found = false;    
+/*static int iref_number = 11;*/
+/*static bool iref_found = false;*/
 
-#ifdef HX_USB_DETECT2
-extern bool USB_Flag;
-#endif
 
 #if defined(CONFIG_FB)
 int fb_notifier_callback(struct notifier_block *self,
@@ -134,6 +59,7 @@
 int himax_input_register(struct himax_ts_data *ts)
 {
 	int ret;
+
 	ts->input_dev = input_allocate_device();
 	if (ts->input_dev == NULL) {
 		ret = -ENOMEM;
@@ -175,25 +101,36 @@
 	set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
 
 	if (ts->protocol_type == PROTOCOL_TYPE_A) {
-		//ts->input_dev->mtsize = ts->nFinger_support;
+		/*ts->input_dev->mtsize = ts->nFinger_support;*/
 		input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID,
 		0, 3, 0, 0);
 	} else {/* PROTOCOL_TYPE_B */
 		set_bit(MT_TOOL_FINGER, ts->input_dev->keybit);
-		input_mt_init_slots(ts->input_dev, ts->nFinger_support,0);
+		input_mt_init_slots(ts->input_dev, ts->nFinger_support, 0);
 	}
 
 	I("input_set_abs_params: mix_x %d, max_x %d, min_y %d, max_y %d\n",
-		ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max);
+		ts->pdata->abs_x_min, ts->pdata->abs_x_max,
+		ts->pdata->abs_y_min, ts->pdata->abs_y_max);
 
-	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_x_fuzz, 0);
-	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,ts->pdata->abs_y_min, ts->pdata->abs_y_max, ts->pdata->abs_y_fuzz, 0);
-	input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR,ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max, ts->pdata->abs_pressure_fuzz, 0);
-	input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE,ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max, ts->pdata->abs_pressure_fuzz, 0);
-	input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR,ts->pdata->abs_width_min, ts->pdata->abs_width_max, ts->pdata->abs_pressure_fuzz, 0);
+	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,
+	ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_x_fuzz, 0);
+	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,
+	ts->pdata->abs_y_min, ts->pdata->abs_y_max, ts->pdata->abs_y_fuzz, 0);
+	input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR,
+	ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max,
+	ts->pdata->abs_pressure_fuzz, 0);
+	input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE,
+	ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max,
+	ts->pdata->abs_pressure_fuzz, 0);
+	input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR,
+	ts->pdata->abs_width_min, ts->pdata->abs_width_max,
+	ts->pdata->abs_pressure_fuzz, 0);
 
-//	input_set_abs_params(ts->input_dev, ABS_MT_AMPLITUDE, 0, ((ts->pdata->abs_pressure_max << 16) | ts->pdata->abs_width_max), 0, 0);
-//	input_set_abs_params(ts->input_dev, ABS_MT_POSITION, 0, (BIT(31) | (ts->pdata->abs_x_max << 16) | ts->pdata->abs_y_max), 0, 0);
+/*input_set_abs_params(ts->input_dev, ABS_MT_AMPLITUDE, 0,
+((ts->pdata->abs_pressure_max << 16) | ts->pdata->abs_width_max), 0, 0);*/
+/*input_set_abs_params(ts->input_dev, ABS_MT_POSITION, 0,
+(BIT(31) | (ts->pdata->abs_x_max << 16) | ts->pdata->abs_y_max), 0, 0);*/
 
 	return input_register_device(ts->input_dev);
 }
@@ -201,87 +138,103 @@
 static void calcDataSize(uint8_t finger_num)
 {
 	struct himax_ts_data *ts_data = private_ts;
+
 	ts_data->coord_data_size = 4 * finger_num;
-	ts_data->area_data_size = ((finger_num / 4) + (finger_num % 4 ? 1 : 0)) * 4;
-	ts_data->raw_data_frame_size = 128 - ts_data->coord_data_size - ts_data->area_data_size - 4 - 4 - 1;
-	ts_data->raw_data_nframes  = ((uint32_t)ts_data->x_channel * ts_data->y_channel +
-																					ts_data->x_channel + ts_data->y_channel) / ts_data->raw_data_frame_size +
-															(((uint32_t)ts_data->x_channel * ts_data->y_channel +
-		  																		ts_data->x_channel + ts_data->y_channel) % ts_data->raw_data_frame_size)? 1 : 0;
-	I("%s: coord_data_size: %d, area_data_size:%d, raw_data_frame_size:%d, raw_data_nframes:%d", __func__, ts_data->coord_data_size, ts_data->area_data_size, ts_data->raw_data_frame_size, ts_data->raw_data_nframes);
+	ts_data->area_data_size = ((finger_num / 4) +
+	(finger_num % 4 ? 1 : 0)) * 4;
+	ts_data->raw_data_frame_size = 128 -
+	ts_data->coord_data_size -
+	ts_data->area_data_size - 4 - 4 - 1;
+
+	ts_data->raw_data_nframes =
+	((uint32_t)ts_data->x_channel *
+	ts_data->y_channel + ts_data->x_channel + ts_data->y_channel) /
+	ts_data->raw_data_frame_size + (((uint32_t)ts_data->x_channel *
+	ts_data->y_channel + ts_data->x_channel + ts_data->y_channel) %
+	ts_data->raw_data_frame_size) ? 1 : 0;
+
+	I("%s: coord_data_size: %d, area_data_size:%d",
+	__func__, ts_data->coord_data_size, ts_data->area_data_size);
+	I("raw_data_frame_size:%d, raw_data_nframes:%d",
+	ts_data->raw_data_frame_size, ts_data->raw_data_nframes);
 }
 
 static void calculate_point_number(void)
 {
-	HX_TOUCH_INFO_POINT_CNT = ic_data->HX_MAX_PT * 4 ;
+	HX_TOUCH_INFO_POINT_CNT = ic_data->HX_MAX_PT * 4;
 
-	if ( (ic_data->HX_MAX_PT % 4) == 0)
-		HX_TOUCH_INFO_POINT_CNT += (ic_data->HX_MAX_PT / 4) * 4 ;
+	if ((ic_data->HX_MAX_PT % 4) == 0)
+		HX_TOUCH_INFO_POINT_CNT += (ic_data->HX_MAX_PT / 4) * 4;
 	else
-		HX_TOUCH_INFO_POINT_CNT += ((ic_data->HX_MAX_PT / 4) +1) * 4 ;
+		HX_TOUCH_INFO_POINT_CNT += ((ic_data->HX_MAX_PT / 4) + 1) * 4;
 }
 
-#if 0
+/*#if 0*/
+#ifdef HX_EN_CHECK_PATCH
 static int himax_read_Sensor_ID(struct i2c_client *client)
-{	
-	uint8_t val_high[1], val_low[1], ID0=0, ID1=0;
+{
+	uint8_t val_high[1], val_low[1], ID0 = 0, ID1 = 0;
 	char data[3];
 	const int normalRetry = 10;
 	int sensor_id;
-	
-	data[0] = 0x56; data[1] = 0x02; data[2] = 0x02;/*ID pin PULL High*/
-	i2c_himax_master_write(client, &data[0],3,normalRetry);
-	usleep_range(1000, 2000);
 
-	//read id pin high
+	data[0] = 0x56; data[1] = 0x02;
+	data[2] = 0x02;/*ID pin PULL High*/
+	i2c_himax_master_write(client, &data[0], 3, normalRetry);
+	usleep(1000);
+
+	/*read id pin high*/
 	i2c_himax_read(client, 0x57, val_high, 1, normalRetry);
 
-	data[0] = 0x56; data[1] = 0x01; data[2] = 0x01;/*ID pin PULL Low*/
-	i2c_himax_master_write(client, &data[0],3,normalRetry);
-	usleep_range(1000, 2000);
+	data[0] = 0x56; data[1] = 0x01;
+	data[2] = 0x01;/*ID pin PULL Low*/
+	i2c_himax_master_write(client, &data[0], 3, normalRetry);
+	usleep(1000);
 
-	//read id pin low
+	/*read id pin low*/
 	i2c_himax_read(client, 0x57, val_low, 1, normalRetry);
 
-	if((val_high[0] & 0x01) ==0)
-		ID0=0x02;/*GND*/
-	else if((val_low[0] & 0x01) ==0)
-		ID0=0x01;/*Floating*/
+	if ((val_high[0] & 0x01) == 0)
+		ID0 = 0x02;/*GND*/
+	else if ((val_low[0] & 0x01) == 0)
+		ID0 = 0x01;/*Floating*/
 	else
-		ID0=0x04;/*VCC*/
-	
-	if((val_high[0] & 0x02) ==0)
-		ID1=0x02;/*GND*/
-	else if((val_low[0] & 0x02) ==0)
-		ID1=0x01;/*Floating*/
+		ID0 = 0x04;/*VCC*/
+
+	if ((val_high[0] & 0x02) == 0)
+		ID1 = 0x02;/*GND*/
+	else if ((val_low[0] & 0x02) == 0)
+		ID1 = 0x01;/*Floating*/
 	else
-		ID1=0x04;/*VCC*/
-	if((ID0==0x04)&&(ID1!=0x04))
-		{
-			data[0] = 0x56; data[1] = 0x02; data[2] = 0x01;/*ID pin PULL High,Low*/
-			i2c_himax_master_write(client, &data[0],3,normalRetry);
-			usleep_range(1000, 2000);
+		ID1 = 0x04;/*VCC*/
+	if ((ID0 == 0x04) && (ID1 != 0x04)) {
+			data[0] = 0x56; data[1] = 0x02;
+			data[2] = 0x01;/*ID pin PULL High,Low*/
+			i2c_himax_master_write(client,
+			&data[0], 3, normalRetry);
+			usleep(1000);
 
-		}
-	else if((ID0!=0x04)&&(ID1==0x04))
-		{
-			data[0] = 0x56; data[1] = 0x01; data[2] = 0x02;/*ID pin PULL Low,High*/
-			i2c_himax_master_write(client, &data[0],3,normalRetry);
-			usleep_range(1000, 2000);
+	} else if ((ID0 != 0x04) && (ID1 == 0x04)) {
+			data[0] = 0x56; data[1] = 0x01;
+			data[2] = 0x02;/*ID pin PULL Low,High*/
+			i2c_himax_master_write(client,
+			&data[0], 3, normalRetry);
+			usleep(1000);
 
-		}
-	else if((ID0==0x04)&&(ID1==0x04))
-		{
-			data[0] = 0x56; data[1] = 0x02; data[2] = 0x02;/*ID pin PULL High,High*/
-			i2c_himax_master_write(client, &data[0],3,normalRetry);
-			usleep_range(1000, 2000);
+	} else if ((ID0 == 0x04) && (ID1 == 0x04)) {
+			data[0] = 0x56; data[1] = 0x02;
+			data[2] = 0x02;/*ID pin PULL High,High*/
+			i2c_himax_master_write(client,
+			&data[0], 3, normalRetry);
+			usleep(1000);
 
-		}
-	sensor_id=(ID1<<4)|ID0;
+	}
+	sensor_id = (ID1<<4)|ID0;
 
 	data[0] = 0xE4; data[1] = sensor_id;
-	i2c_himax_master_write(client, &data[0],2,normalRetry);/*Write to MCU*/
-	usleep_range(1000, 2000);
+	i2c_himax_master_write(client,
+	&data[0], 2, normalRetry);/*Write to MCU*/
+	usleep(1000);
 
 	return sensor_id;
 
@@ -290,125 +243,173 @@
 static void himax_power_on_initCMD(struct i2c_client *client)
 {
 	I("%s:\n", __func__);
-
 	himax_touch_information(client);
-
-    //himax_sense_on(private_ts->client, 0x01);//1=Flash, 0=SRAM
+    /*himax_sense_on(private_ts->client, 0x01);//1=Flash, 0=SRAM */
 }
 
 #ifdef HX_AUTO_UPDATE_FW
 static int i_update_FW(void)
 {
 	int upgrade_times = 0;
-	unsigned char* ImageBuffer = i_CTPM_FW;
-	int fullFileLength = sizeof(i_CTPM_FW);
+	int fullFileLength = 0;
 	int i_FW_VER = 0, i_CFG_VER = 0;
-	uint8_t ret = -1, result = 0;
-//	uint8_t tmp_addr[4];
-//	uint8_t tmp_data[4];
+	int ret = -1, result = 0;
+	/*uint8_t tmp_addr[4];*/
+	/*uint8_t tmp_data[4];*/
 	int CRC_from_FW = 0;
 	int CRC_Check_result = 0;
 
-	i_FW_VER = i_CTPM_FW[FW_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW[FW_VER_MIN_FLASH_ADDR];
-	i_CFG_VER = i_CTPM_FW[CFG_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW[CFG_VER_MIN_FLASH_ADDR];
+	ret = himax_load_CRC_bin_file(private_ts->client);
+	if (ret < 0) {
+		E("%s: himax_load_CRC_bin_file fail Error Code=%d.\n",
+		__func__, ret);
+		ret = -1;
+		return ret;
+	}
+	I("file name = %s\n", i_CTPM_firmware_name);
+	ret = request_firmware(&i_CTPM_FW,
+	i_CTPM_firmware_name, private_ts->dev);
+	if (ret < 0) {
+		E("%s,fail in line%d error code=%d\n",
+		__func__, __LINE__, ret);
+		ret = -2;
+		return ret;
+	}
 
-	I("%s: i_fullFileLength = %d\n", __func__,fullFileLength);
+	if (i_CTPM_FW == NULL) {
+		I("%s: i_CTPM_FW = NULL\n", __func__);
+		ret = -3;
+		return ret;
+	}
+	fullFileLength = i_CTPM_FW->size;
+
+	i_FW_VER = i_CTPM_FW->data[FW_VER_MAJ_FLASH_ADDR]<<8
+	| i_CTPM_FW->data[FW_VER_MIN_FLASH_ADDR];
+	i_CFG_VER = i_CTPM_FW->data[CFG_VER_MAJ_FLASH_ADDR]<<8
+	| i_CTPM_FW->data[CFG_VER_MIN_FLASH_ADDR];
+
+	I("%s: i_fullFileLength = %d\n", __func__, fullFileLength);
 
 	himax_sense_off(private_ts->client);
 	msleep(500);
 
-	CRC_from_FW = himax_check_CRC(private_ts->client,fw_image_64k);
-	CRC_Check_result = Calculate_CRC_with_AP(ImageBuffer, CRC_from_FW,fw_image_64k);
-	I("%s: Check sum result = %d\n", __func__,CRC_Check_result);
-	//I("%s: ic_data->vendor_fw_ver = %X, i_FW_VER = %X,\n", __func__,ic_data->vendor_fw_ver, i_FW_VER);
-	//I("%s: ic_data->vendor_config_ver = %X, i_CFG_VER = %X,\n", __func__,ic_data->vendor_config_ver, i_CFG_VER);
-	
-	if ((CRC_Check_result == 0)|| ( ic_data->vendor_fw_ver < i_FW_VER ) || ( ic_data->vendor_config_ver < i_CFG_VER ))
-		{
-			himax_int_enable(private_ts->client->irq,0);
+	CRC_from_FW = himax_check_CRC(private_ts->client, fw_image_64k);
+	CRC_Check_result =
+	Calculate_CRC_with_AP((unsigned char *)i_CTPM_FW->data,
+	CRC_from_FW, fw_image_64k);
+	I("%s: Check sum result = %d\n", __func__, CRC_Check_result);
+	/*I("%s: ic_data->vendor_fw_ver = %X, i_FW_VER = %X,\n",
+	__func__, ic_data->vendor_fw_ver, i_FW_VER);*/
+	/*I("%s: ic_data->vendor_config_ver = %X, i_CFG_VER = %X,\n",
+	__func__, ic_data->vendor_config_ver, i_CFG_VER);*/
+
+	if ((CRC_Check_result == 0) ||
+	(ic_data->vendor_fw_ver < i_FW_VER) ||
+	(ic_data->vendor_config_ver < i_CFG_VER)) {
+		himax_int_enable(private_ts->client->irq, 0);
 update_retry:
-			if(fullFileLength == FW_SIZE_60k){
-				ret = fts_ctpm_fw_upgrade_with_sys_fs_60k(private_ts->client,ImageBuffer,fullFileLength,false);
-			}else if (fullFileLength == FW_SIZE_64k){
-				ret = fts_ctpm_fw_upgrade_with_sys_fs_64k(private_ts->client,ImageBuffer,fullFileLength,false);
-			}else if (fullFileLength == FW_SIZE_124k){
-				ret = fts_ctpm_fw_upgrade_with_sys_fs_124k(private_ts->client,ImageBuffer,fullFileLength,false);
-			}else if (fullFileLength == FW_SIZE_128k){
-				ret = fts_ctpm_fw_upgrade_with_sys_fs_128k(private_ts->client,ImageBuffer,fullFileLength,false);
-			}
-			if(ret == 0){
-				upgrade_times++;
-				E("%s: TP upgrade error, upgrade_times = %d\n", __func__, upgrade_times);
-				if(upgrade_times < 3)
-					goto update_retry;
-				else
-				{
-					himax_sense_on(private_ts->client, 0x01);
-					msleep(120);
-#ifdef HX_ESD_WORKAROUND
-					HX_ESD_RESET_ACTIVATE = 1;
-#endif
-					result = -1;//upgrade fail
-				}
-			}
-			else if(ret == 1){
-/*
-				// 1. Set DDREG_Req = 1 (0x9000_0020 = 0x0000_0001) (Lock register R/W from driver)
-				tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
-				tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x01;
-				himax_register_write(private_ts->client, tmp_addr, 1, tmp_data);
-
-				// 2. Write driver initial code condition
-				//	  write value from AHB I2C : 0x8001_C603 = 0x000000FF
-				tmp_addr[3] = 0x80; tmp_addr[2] = 0x01; tmp_addr[1] = 0xC6; tmp_addr[0] = 0x03;
-				tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0xFF;
-				himax_register_write(private_ts->client, tmp_addr, 1, tmp_data);
-
-				// 1. Set DDREG_Req = 0 (0x9000_0020 = 0x0000_0001) (Lock register R/W from driver)
-				tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
-				tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
-				himax_register_write(private_ts->client, tmp_addr, 1, tmp_data);
-*/
+		if (fullFileLength == FW_SIZE_60k) {
+			ret = fts_ctpm_fw_upgrade_with_sys_fs_60k
+			(private_ts->client,
+			(unsigned char *)i_CTPM_FW->data,
+			fullFileLength, false);
+		} else if (fullFileLength == FW_SIZE_64k) {
+			ret = fts_ctpm_fw_upgrade_with_sys_fs_64k
+			(private_ts->client,
+			(unsigned char *)i_CTPM_FW->data,
+			fullFileLength, false);
+		} else if (fullFileLength == FW_SIZE_124k) {
+			ret = fts_ctpm_fw_upgrade_with_sys_fs_124k
+			(private_ts->client,
+			(unsigned char *)i_CTPM_FW->data,
+			fullFileLength, false);
+		} else if (fullFileLength == FW_SIZE_128k) {
+			ret = fts_ctpm_fw_upgrade_with_sys_fs_128k
+			(private_ts->client,
+			(unsigned char *)i_CTPM_FW->data,
+			fullFileLength, false);
+		}
+		if (ret == 0) {
+			upgrade_times++;
+			E("%s: TP upgrade error, upgrade_times = %d\n",
+			__func__, upgrade_times);
+			if (upgrade_times < 3)
+				goto update_retry;
+			else {
 				himax_sense_on(private_ts->client, 0x01);
 				msleep(120);
 #ifdef HX_ESD_WORKAROUND
 				HX_ESD_RESET_ACTIVATE = 1;
 #endif
-
-				ic_data->vendor_fw_ver = i_FW_VER;
-				ic_data->vendor_config_ver = i_CFG_VER;
-				result = 1;//upgrade success
-				I("%s: TP upgrade OK\n", __func__);
+				result = -1;/*upgrade fail*/
 			}
+		} else if (ret == 1) {
+			/*
+			// 1. Set DDREG_Req = 1 (0x9000_0020 = 0x0000_0001)
+					(Lock register R/W from driver)
+					tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+					tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+					tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+					tmp_data[1] = 0x00; tmp_data[0] = 0x01;
+					himax_register_write(private_ts->client,
+					tmp_addr, 1, tmp_data);
 
-				himax_int_enable(private_ts->client->irq,1);
-			return result;
-		}
-	else
-		{
+			// 2. Write driver initial code condition
+			//write value from AHB I2C:0x8001_C603 = 0x000000FF
+					tmp_addr[3] = 0x80; tmp_addr[2] = 0x01;
+					tmp_addr[1] = 0xC6; tmp_addr[0] = 0x03;
+					tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+					tmp_data[1] = 0x00; tmp_data[0] = 0xFF;
+					himax_register_write(private_ts->client,
+					tmp_addr, 1, tmp_data);
+
+			// 1. Set DDREG_Req = 0(0x9000_0020 = 0x0000_0001)
+					(Lock register R/W from driver)
+					tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+					tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+					tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+					tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+					himax_register_write(private_ts->client,
+					tmp_addr, 1, tmp_data);
+			*/
 			himax_sense_on(private_ts->client, 0x01);
-			return 0;//NO upgrade
+			msleep(120);
+#ifdef HX_ESD_WORKAROUND
+			HX_ESD_RESET_ACTIVATE = 1;
+#endif
+
+			ic_data->vendor_fw_ver = i_FW_VER;
+			ic_data->vendor_config_ver = i_CFG_VER;
+			result = 1;/*upgrade success*/
+			I("%s: TP upgrade OK\n", __func__);
 		}
+
+		himax_int_enable(private_ts->client->irq, 1);
+		return result;
+
+	} else {
+		himax_sense_on(private_ts->client, 0x01);
+		return 0;/*NO upgrade*/
+	}
 }
-#endif 
+#endif
 
 #ifdef HX_RST_PIN_FUNC
-void himax_HW_reset(uint8_t loadconfig,uint8_t int_off)
+void himax_HW_reset(uint8_t loadconfig, uint8_t int_off)
 {
 	struct himax_ts_data *ts = private_ts;
 	int ret = 0;
 
 	return;
 	if (ts->rst_gpio) {
-		if(int_off)
-			{
-				if (ts->use_irq)
-					himax_int_enable(private_ts->client->irq,0);
-				else {
-					hrtimer_cancel(&ts->timer);
-					ret = cancel_work_sync(&ts->work);
-				}
+		if (int_off) {
+			if (ts->use_irq)
+				himax_int_enable(private_ts->client->irq, 0);
+			else {
+				hrtimer_cancel(&ts->timer);
+				ret = cancel_work_sync(&ts->work);
 			}
+		}
 
 		I("%s: Now reset the Touch chip.\n", __func__);
 
@@ -417,51 +418,51 @@
 		himax_rst_gpio_set(ts->rst_gpio, 1);
 		msleep(20);
 
-		if(loadconfig)
-			himax_loadSensorConfig(private_ts->client,private_ts->pdata);
+		if (loadconfig)
+			himax_loadSensorConfig(private_ts->client,
+			private_ts->pdata);
 
-		if(int_off)
-			{
-				if (ts->use_irq)
-					himax_int_enable(private_ts->client->irq,1);
-				else
-					hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
-			}
+		if (int_off) {
+			if (ts->use_irq)
+				himax_int_enable(private_ts->client->irq, 1);
+			else
+				hrtimer_start(&ts->timer,
+				ktime_set(1, 0), HRTIMER_MODE_REL);
+		}
 	}
 }
 #endif
 
-int himax_loadSensorConfig(struct i2c_client *client, struct himax_i2c_platform_data *pdata)
+int himax_loadSensorConfig(struct i2c_client *client,
+struct himax_i2c_platform_data *pdata)
 {
+	int err = -1;
 
 	if (!client) {
 		E("%s: Necessary parameters client are null!\n", __func__);
-		return -EINVAL;
+		return err;
 	}
-
-	if(config_load == false)
-		{
-			config_selected = kzalloc(sizeof(*config_selected), GFP_KERNEL);
-			if (config_selected == NULL) {
-				E("%s: alloc config_selected fail!\n", __func__);
-				return -ENOMEM;
-			}
+	if (config_load == false) {
+		config_selected = kzalloc(sizeof(*config_selected), GFP_KERNEL);
+		if (config_selected == NULL) {
+			E("%s: alloc config_selected fail!\n", __func__);
+			return err;
 		}
+	}
+	himax_power_on_initCMD(client);
 
-		himax_power_on_initCMD(client);
-
-		himax_int_enable(client->irq,0);
-		himax_read_FW_ver(client);
+	himax_int_enable(client->irq, 0);
+	himax_read_FW_ver(client);
 #ifdef HX_RST_PIN_FUNC
-	himax_HW_reset(true,false);
+	himax_HW_reset(true, false);
 #endif
-	himax_int_enable(client->irq,1);
-		I("FW_VER : %X \n",ic_data->vendor_fw_ver);
+	himax_int_enable(client->irq, 1);
+	I("FW_VER : %X\n", ic_data->vendor_fw_ver);
 
-		ic_data->vendor_sensor_id=0x2602;
-		I("sensor_id=%x.\n",ic_data->vendor_sensor_id);
+	ic_data->vendor_sensor_id = 0x2602;
+	I("sensor_id=%x.\n", ic_data->vendor_sensor_id);
 
-	himax_sense_on(private_ts->client, 0x01);//1=Flash, 0=SRAM
+	himax_sense_on(private_ts->client, 0x01);/*1=Flash, 0=SRAM*/
 	msleep(120);
 #ifdef HX_ESD_WORKAROUND
 	HX_ESD_RESET_ACTIVATE = 1;
@@ -474,47 +475,49 @@
 #ifdef HX_ESD_WORKAROUND
 void ESD_HW_REST(void)
 {
-	I("START_Himax TP: ESD - Reset\n");	
-	
+	I("START_Himax TP: ESD - Reset\n");
+
 	HX_report_ESD_event();
 	ESD_00_counter = 0;
 	ESD_00_Flag = 0;
-	/*************************************/
-		if (private_ts->protocol_type == PROTOCOL_TYPE_A)
+    /*************************************/
+	if (private_ts->protocol_type == PROTOCOL_TYPE_A)
 		input_mt_sync(private_ts->input_dev);
-		input_report_key(private_ts->input_dev, BTN_TOUCH, 0);
-		input_sync(private_ts->input_dev);
-		/*************************************/
+	input_report_key(private_ts->input_dev, BTN_TOUCH, 0);
+	input_sync(private_ts->input_dev);
+	/*************************************/
 
 	I("END_Himax TP: ESD - Reset\n");
 }
 #endif
 #ifdef HX_HIGH_SENSE
-void himax_set_HSEN_func(struct i2c_client *client,uint8_t HSEN_enable)
+void himax_set_HSEN_func(struct i2c_client *client, uint8_t HSEN_enable)
 {
 	uint8_t tmp_data[4];
 
-	if(HSEN_enable)
-	{
+	if (HSEN_enable) {
 		I(" %s in", __func__);
-		HSEN_bit_retry:
-		himax_set_HSEN_enable(client,HSEN_enable);
+HSEN_bit_retry:
+		himax_set_HSEN_enable(client, HSEN_enable);
 		msleep(20);
-		himax_get_HSEN_enable(client,tmp_data);
-		I("%s: Read HSEN bit data[0]=%x data[1]=%x data[2]=%x data[3]=%x\n", __func__
-			,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]);
-		if(tmp_data[0]!= 0x01)
-			{
-				I("%s: retry HSEN bit write data[0]=%x  \n",__func__,tmp_data[0]);
-				goto HSEN_bit_retry;
-			}
+		himax_get_HSEN_enable(client, tmp_data);
+		I("%s: Read HSEN bit data[0]=%x data[1]=%x",
+		__func__, tmp_data[0], tmp_data[1]);
+		I("data[2]=%x data[3]=%x\n",
+		tmp_data[2], tmp_data[3]);
+
+		if (tmp_data[0] != 0x01) {
+			I("%s: retry HSEN bit write data[0]=%x\n",
+			__func__, tmp_data[0]);
+			goto HSEN_bit_retry;
+		}
 	}
 }
 
 static void himax_HSEN_func(struct work_struct *work)
 {
-	struct himax_ts_data *ts = container_of(work, struct himax_ts_data,
-							hsen_work.work);
+	struct himax_ts_data *ts =
+	container_of(work, struct himax_ts_data, hsen_work.work);
 
 	himax_set_HSEN_func(ts->client, ts->HSEN_enable);
 }
@@ -525,9 +528,10 @@
 #ifdef HX_GESTURE_TRACK
 static void gest_pt_log_coordinate(int rx, int tx)
 {
-	//driver report x y with range 0 - 255 , we scale it up to x/y pixel
-	gest_pt_x[gest_pt_cnt] = rx*(ic_data->HX_X_RES)/255;
-	gest_pt_y[gest_pt_cnt] = tx*(ic_data->HX_Y_RES)/255;
+	/*driver report x y with range 0 - 255*/
+	/* And we scale it up to x/y coordinates*/
+	gest_pt_x[gest_pt_cnt] = rx * (ic_data->HX_X_RES) / 255;
+	gest_pt_y[gest_pt_cnt] = tx * (ic_data->HX_Y_RES) / 255;
 }
 #endif
 static int himax_parse_wake_event(struct himax_ts_data *ts)
@@ -535,145 +539,143 @@
 	uint8_t buf[64];
 	unsigned char check_sum_cal = 0;
 #ifdef HX_GESTURE_TRACK
-	int tmp_max_x=0x00,tmp_min_x=0xFFFF,tmp_max_y=0x00,tmp_min_y=0xFFFF;
+	int tmp_max_x = 0x00, tmp_min_x = 0xFFFF,
+	tmp_max_y = 0x00, tmp_min_y = 0xFFFF;
 	int gest_len;
 #endif
-	int i=0, check_FC = 0, gesture_flag = 0;
+	int i = 0, check_FC = 0, gesture_flag = 0;
 
 	himax_burst_enable(ts->client, 0);
-	himax_read_event_stack(ts->client,buf,56);
+	himax_read_event_stack(ts->client, buf, 56);
 
-	for(i=0;i<GEST_PTLG_ID_LEN;i++)
-	{
-		if (check_FC==0)
-		{
-			if((buf[0]!=0x00)&&((buf[0]<=0x0F)||(buf[0]==0x80)))
-			{
+	for (i = 0 ; i < GEST_PTLG_ID_LEN ; i++) {
+		if (check_FC == 0) {
+			if ((buf[0] != 0x00) &&
+			((buf[0] <= 0x0F) || (buf[0] == 0x80))) {
 				check_FC = 1;
 				gesture_flag = buf[i];
-			}
-			else
-			{
+			} else {
 				check_FC = 0;
-				I("ID START at %x , value = %x skip the event\n", i, buf[i]);
+				I("ID START at %x,value = %x skip event\n",
+				i, buf[i]);
 				break;
 			}
-		}
-		else
-		{
-			if(buf[i]!=gesture_flag)
-			{
+		} else {
+			if (buf[i] != gesture_flag) {
 				check_FC = 0;
-				I("ID NOT the same %x != %x So STOP parse event\n", buf[i], gesture_flag);
+				I("ID NOT same %x != %x So STOP parse event\n",
+				buf[i], gesture_flag);
 				break;
 			}
 		}
 
 		I("0x%2.2X ", buf[i]);
 		if (i % 8 == 7)
-				I("\n");
+			I("\n");
 	}
-	I("Himax gesture_flag= %x\n",gesture_flag );
+	I("Himax gesture_flag= %x\n", gesture_flag);
 	I("Himax check_FC is %d\n", check_FC);
 
 	if (check_FC == 0)
 		return 0;
-	if(buf[GEST_PTLG_ID_LEN] != GEST_PTLG_HDR_ID1 ||
-			buf[GEST_PTLG_ID_LEN+1] != GEST_PTLG_HDR_ID2)
+	if (buf[GEST_PTLG_ID_LEN] != GEST_PTLG_HDR_ID1
+	|| buf[GEST_PTLG_ID_LEN+1] != GEST_PTLG_HDR_ID2)
 		return 0;
-	for(i=0;i<(GEST_PTLG_ID_LEN+GEST_PTLG_HDR_LEN);i++)
-	{
-		I("P[%x]=0x%2.2X \n", i, buf[i]);
-		I("checksum=0x%2.2X \n", check_sum_cal);
+	for (i = 0 ; i < (GEST_PTLG_ID_LEN + GEST_PTLG_HDR_LEN) ; i++) {
+		I("P[%x]=0x%2.2X\n", i, buf[i]);
+		I("checksum=0x%2.2X\n", check_sum_cal);
 		check_sum_cal += buf[i];
 	}
-	if ((check_sum_cal != 0x00) )
-	{
-		I(" %s : check_sum_cal: 0x%02X\n",__func__ ,check_sum_cal);
+	if ((check_sum_cal != 0x00)) {
+		I(" %s : check_sum_cal: 0x%02X\n", __func__ , check_sum_cal);
 		return 0;
 	}
 #ifdef HX_GESTURE_TRACK
-	if(buf[GEST_PTLG_ID_LEN] == GEST_PTLG_HDR_ID1 &&
-			buf[GEST_PTLG_ID_LEN+1] == GEST_PTLG_HDR_ID2)
-	{
-		gest_len = buf[GEST_PTLG_ID_LEN+2];
-
-		I("gest_len = %d ",gest_len);
-
+	if (buf[GEST_PTLG_ID_LEN] == GEST_PTLG_HDR_ID1
+	&& buf[GEST_PTLG_ID_LEN+1] == GEST_PTLG_HDR_ID2) {
+		gest_len = buf[GEST_PTLG_ID_LEN + 2];
+		I("gest_len = %d ", gest_len);
 		i = 0;
 		gest_pt_cnt = 0;
-		I("gest doornidate start \n %s",__func__);
-		while(i<(gest_len+1)/2)
-		{
-			gest_pt_log_coordinate(buf[GEST_PTLG_ID_LEN+4+i*2],buf[GEST_PTLG_ID_LEN+4+i*2+1]);
+		I("gest doornidate start\n %s", __func__);
+		while (i < (gest_len + 1) / 2) {
+			gest_pt_log_coordinate
+			(buf[GEST_PTLG_ID_LEN + 4 + i * 2],
+			buf[GEST_PTLG_ID_LEN + 4 + i * 2 + 1]);
 			i++;
 
-			I("gest_pt_x[%d]=%d \n",gest_pt_cnt,gest_pt_x[gest_pt_cnt]);
-			I("gest_pt_y[%d]=%d \n",gest_pt_cnt,gest_pt_y[gest_pt_cnt]);
+			I("gest_pt_x[%d]=%d\n",
+			gest_pt_cnt, gest_pt_x[gest_pt_cnt]);
+			I("gest_pt_y[%d]=%d\n",
+			gest_pt_cnt, gest_pt_y[gest_pt_cnt]);
 
-			gest_pt_cnt +=1;
+			gest_pt_cnt += 1;
 		}
-		if(gest_pt_cnt)
-			{
-				for(i=0; i<gest_pt_cnt; i++)
-					{
-						if(tmp_max_x<gest_pt_x[i])
-							tmp_max_x=gest_pt_x[i];
-						if(tmp_min_x>gest_pt_x[i])
-							tmp_min_x=gest_pt_x[i];
-						if(tmp_max_y<gest_pt_y[i])
-							tmp_max_y=gest_pt_y[i];
-						if(tmp_min_y>gest_pt_y[i])
-							tmp_min_y=gest_pt_y[i];
-					}
-				I("gest_point x_min= %d, x_max= %d, y_min= %d, y_max= %d\n",tmp_min_x,tmp_max_x,tmp_min_y,tmp_max_y);
-				gest_start_x=gest_pt_x[0];
-				gn_gesture_coor[0] = gest_start_x;
-				gest_start_y=gest_pt_y[0];
-				gn_gesture_coor[1] = gest_start_y;
-				gest_end_x=gest_pt_x[gest_pt_cnt-1];
-				gn_gesture_coor[2] = gest_end_x;
-				gest_end_y=gest_pt_y[gest_pt_cnt-1];
-				gn_gesture_coor[3] = gest_end_y;
-				gest_width = tmp_max_x - tmp_min_x;
-				gn_gesture_coor[4] = gest_width;
-				gest_height = tmp_max_y - tmp_min_y;
-				gn_gesture_coor[5] = gest_height;
-				gest_mid_x = (tmp_max_x + tmp_min_x)/2;
-				gn_gesture_coor[6] = gest_mid_x;
-				gest_mid_y = (tmp_max_y + tmp_min_y)/2;
-				gn_gesture_coor[7] = gest_mid_y;
-				gn_gesture_coor[8] = gest_mid_x;//gest_up_x
-				gn_gesture_coor[9] = gest_mid_y-gest_height/2;//gest_up_y
-				gn_gesture_coor[10] = gest_mid_x;//gest_down_x
-				gn_gesture_coor[11] = gest_mid_y+gest_height/2;	//gest_down_y
-				gn_gesture_coor[12] = gest_mid_x-gest_width/2;	//gest_left_x
-				gn_gesture_coor[13] = gest_mid_y;	//gest_left_y
-				gn_gesture_coor[14] = gest_mid_x+gest_width/2;	//gest_right_x
-				gn_gesture_coor[15] = gest_mid_y; //gest_right_y
-
+		if (gest_pt_cnt) {
+			for (i = 0 ; i < gest_pt_cnt ; i++) {
+				if (tmp_max_x < gest_pt_x[i])
+					tmp_max_x = gest_pt_x[i];
+				if (tmp_min_x > gest_pt_x[i])
+					tmp_min_x = gest_pt_x[i];
+				if (tmp_max_y < gest_pt_y[i])
+					tmp_max_y = gest_pt_y[i];
+				if (tmp_min_y > gest_pt_y[i])
+					tmp_min_y = gest_pt_y[i];
 			}
+			I("gest_point x_min= %d, x_max= %d\n",
+			tmp_min_x, tmp_max_x);
+			I("y_min= %d, y_max= %d\n",
+			tmp_min_y, tmp_max_y);
+			gest_start_x = gest_pt_x[0];
+			gn_gesture_coor[0] = gest_start_x;
+			gest_start_y = gest_pt_y[0];
+			gn_gesture_coor[1] = gest_start_y;
+			gest_end_x = gest_pt_x[gest_pt_cnt - 1];
+			gn_gesture_coor[2] = gest_end_x;
+			gest_end_y = gest_pt_y[gest_pt_cnt - 1];
+			gn_gesture_coor[3] = gest_end_y;
+			gest_width = tmp_max_x - tmp_min_x;
+			gn_gesture_coor[4] = gest_width;
+			gest_height = tmp_max_y - tmp_min_y;
+			gn_gesture_coor[5] = gest_height;
+			gest_mid_x = (tmp_max_x + tmp_min_x) / 2;
+			gn_gesture_coor[6] = gest_mid_x;
+			gest_mid_y = (tmp_max_y + tmp_min_y) / 2;
+			gn_gesture_coor[7] = gest_mid_y;
+			/*gest_up_x*/
+			gn_gesture_coor[8] = gest_mid_x;
+			/*gest_up_y*/
+			gn_gesture_coor[9] = gest_mid_y - gest_height / 2;
+			/*gest_down_x*/
+			gn_gesture_coor[10] = gest_mid_x;
+			/*gest_down_y*/
+			gn_gesture_coor[11] = gest_mid_y + gest_height / 2;
+			/*gest_left_x*/
+			gn_gesture_coor[12] = gest_mid_x - gest_width / 2;
+			/*gest_left_y*/
+			gn_gesture_coor[13] = gest_mid_y;
+			/*gest_right_x*/
+			gn_gesture_coor[14] = gest_mid_x + gest_width / 2;
+			/*gest_right_y*/
+			gn_gesture_coor[15] = gest_mid_y;
+
+		}
 
 	}
 #endif
-	if(gesture_flag != 0x80)
-	{
-		if(!ts->gesture_cust_en[gesture_flag])
-			{
-				I("%s NOT report customer key \n ",__func__);
-				return 0;//NOT report customer key
-			}
-	}
-	else
-	{
-		if(!ts->gesture_cust_en[0])
-			{
-				I("%s NOT report report double click \n",__func__);
-				return 0;//NOT report power key
-			}
+	if (gesture_flag != 0x80) {
+		if (!ts->gesture_cust_en[gesture_flag]) {
+			I("%s NOT report customer key\n ", __func__);
+			return 0;/*NOT report customer key*/
+		}
+	} else {
+		if (!ts->gesture_cust_en[0]) {
+			I("%s NOT report report double click\n", __func__);
+			return 0;/*NOT report power key*/
+		}
 	}
 
-	if(gesture_flag == 0x80)
+	if (gesture_flag == 0x80)
 		return EV_GESTURE_PWR;
 	else
 		return gesture_flag;
@@ -685,225 +687,242 @@
 
 	ret_event = himax_parse_wake_event(private_ts);
 	switch (ret_event) {
-		case EV_GESTURE_PWR:
-			KEY_EVENT = KEY_POWER;
+	case EV_GESTURE_PWR:
+		KEY_EVENT = KEY_POWER;
 		break;
-		case EV_GESTURE_01:
-			KEY_EVENT = KEY_CUST_01;
+	case EV_GESTURE_01:
+		KEY_EVENT = KEY_CUST_01;
 		break;
-		case EV_GESTURE_02:
-			KEY_EVENT = KEY_CUST_02;
+	case EV_GESTURE_02:
+		KEY_EVENT = KEY_CUST_02;
 		break;
-		case EV_GESTURE_03:
-			KEY_EVENT = KEY_CUST_03;
+	case EV_GESTURE_03:
+		KEY_EVENT = KEY_CUST_03;
 		break;
-		case EV_GESTURE_04:
-			KEY_EVENT = KEY_CUST_04;
+	case EV_GESTURE_04:
+		KEY_EVENT = KEY_CUST_04;
 		break;
-		case EV_GESTURE_05:
-			KEY_EVENT = KEY_CUST_05;
+	case EV_GESTURE_05:
+		KEY_EVENT = KEY_CUST_05;
 		break;
-		case EV_GESTURE_06:
-			KEY_EVENT = KEY_CUST_06;
+	case EV_GESTURE_06:
+		KEY_EVENT = KEY_CUST_06;
 		break;
-		case EV_GESTURE_07:
-			KEY_EVENT = KEY_CUST_07;
+	case EV_GESTURE_07:
+		KEY_EVENT = KEY_CUST_07;
 		break;
-		case EV_GESTURE_08:
-			KEY_EVENT = KEY_CUST_08;
+	case EV_GESTURE_08:
+		KEY_EVENT = KEY_CUST_08;
 		break;
-		case EV_GESTURE_09:
-			KEY_EVENT = KEY_CUST_09;
+	case EV_GESTURE_09:
+		KEY_EVENT = KEY_CUST_09;
 		break;
-		case EV_GESTURE_10:
-			KEY_EVENT = KEY_CUST_10;
+	case EV_GESTURE_10:
+		KEY_EVENT = KEY_CUST_10;
 		break;
-		case EV_GESTURE_11:
-			KEY_EVENT = KEY_CUST_11;
+	case EV_GESTURE_11:
+		KEY_EVENT = KEY_CUST_11;
 		break;
-		case EV_GESTURE_12:
-			KEY_EVENT = KEY_CUST_12;
+	case EV_GESTURE_12:
+		KEY_EVENT = KEY_CUST_12;
 		break;
-		case EV_GESTURE_13:
-			KEY_EVENT = KEY_CUST_13;
+	case EV_GESTURE_13:
+		KEY_EVENT = KEY_CUST_13;
 		break;
-		case EV_GESTURE_14:
-			KEY_EVENT = KEY_CUST_14;
+	case EV_GESTURE_14:
+		KEY_EVENT = KEY_CUST_14;
 		break;
-		case EV_GESTURE_15:
-			KEY_EVENT = KEY_CUST_15;
+	case EV_GESTURE_15:
+		KEY_EVENT = KEY_CUST_15;
 		break;
 	}
-	if(ret_event)
-		{
-			I(" %s SMART WAKEUP KEY event %x press\n",__func__,KEY_EVENT);
-			input_report_key(private_ts->input_dev, KEY_EVENT, 1);
-			input_sync(private_ts->input_dev);
-			//msleep(100);
-			I(" %s SMART WAKEUP KEY event %x release\n",__func__,KEY_EVENT);
-			input_report_key(private_ts->input_dev, KEY_EVENT, 0);
-			input_sync(private_ts->input_dev);
-			FAKE_POWER_KEY_SEND=true;
+	if (ret_event) {
+		I(" %s SMART WAKEUP KEY event %x press\n",
+		__func__, KEY_EVENT);
+		input_report_key(private_ts->input_dev, KEY_EVENT, 1);
+		input_sync(private_ts->input_dev);
+		/*msleep(100);*/
+		I(" %s SMART WAKEUP KEY event %x release\n",
+		__func__, KEY_EVENT);
+		input_report_key(private_ts->input_dev, KEY_EVENT, 0);
+		input_sync(private_ts->input_dev);
+		FAKE_POWER_KEY_SEND = true;
 #ifdef HX_GESTURE_TRACK
-			I("gest_start_x= %d, gest_start_y= %d, gest_end_x= %d, gest_end_y= %d\n",gest_start_x,gest_start_y,
-			gest_end_x,gest_end_y);
-			I("gest_width= %d, gest_height= %d, gest_mid_x= %d, gest_mid_y= %d\n",gest_width,gest_height,
-			gest_mid_x,gest_mid_y);
-			I("gest_up_x= %d, gest_up_y= %d, gest_down_x= %d, gest_down_y= %d\n",gn_gesture_coor[8],gn_gesture_coor[9],
-			gn_gesture_coor[10],gn_gesture_coor[11]);
-			I("gest_left_x= %d, gest_left_y= %d, gest_right_x= %d, gest_right_y= %d\n",gn_gesture_coor[12],gn_gesture_coor[13],
-			gn_gesture_coor[14],gn_gesture_coor[15]);
+		I("gest_start_x= %d, gest_start_y= %d\n",
+		gest_start_x, gest_start_y);
+		I("gest_end_x= %d, gest_end_y= %d\n",
+		gest_end_x, gest_end_y);
+		I("gest_width= %d, gest_height= %d\n",
+		gest_width, gest_height);
+		I("gest_mid_x= %d, gest_mid_y= %d\n",
+		gest_mid_x, gest_mid_y);
+		I("gest_up_x= %d, gest_up_y= %d\n",
+		gn_gesture_coor[8], gn_gesture_coor[9]);
+		I("gest_down_x= %d, gest_down_y= %d\n",
+		gn_gesture_coor[10], gn_gesture_coor[11]);
+		I("gest_left_x= %d, gest_left_y= %d\n",
+		gn_gesture_coor[12], gn_gesture_coor[13]);
+		I("gest_right_x= %d, gest_right_y= %d\n",
+		gn_gesture_coor[14], gn_gesture_coor[15]);
 #endif
-		}
+	}
 }
 
 #endif
-static void himax_ts_button_func(int tp_key_index,struct himax_ts_data *ts)
+static void himax_ts_button_func(int tp_key_index, struct himax_ts_data *ts)
 {
 	uint16_t x_position = 0, y_position = 0;
-if ( tp_key_index != 0x00)
-	{
-		I("virtual key index =%x\n",tp_key_index);
-		if ( tp_key_index == 0x01) {
+
+	if (tp_key_index != 0x00) {
+		I("virtual key index =%x\n", tp_key_index);
+		if (tp_key_index == 0x01) {
 			vk_press = 1;
 			I("back key pressed\n");
-				if (ts->pdata->virtual_key)
-				{
-					if (ts->button[0].index) {
-						x_position = (ts->button[0].x_range_min + ts->button[0].x_range_max) / 2;
-						y_position = (ts->button[0].y_range_min + ts->button[0].y_range_max) / 2;
-					}
-					if (ts->protocol_type == PROTOCOL_TYPE_A) {
-						input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0);
-						input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_PRESSURE,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
-							x_position);
-						input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
-							y_position);
-						input_mt_sync(ts->input_dev);
-					} else if (ts->protocol_type == PROTOCOL_TYPE_B) {
-						input_mt_slot(ts->input_dev, 0);
-						input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER,
-						1);
-						input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_PRESSURE,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
-							x_position);
-						input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
-							y_position);
-					}
+			if (ts->pdata->virtual_key) {
+				if (ts->button[0].index) {
+					x_position = (ts->button[0].x_range_min
+					+ ts->button[0].x_range_max) / 2;
+					y_position = (ts->button[0].y_range_min
+					+ ts->button[0].y_range_max) / 2;
 				}
-				else
-					input_report_key(ts->input_dev, KEY_BACK, 1);
-		}
-		else if ( tp_key_index == 0x02) {
+				if (ts->protocol_type == PROTOCOL_TYPE_A) {
+					input_report_abs(ts->input_dev,
+					ABS_MT_TRACKING_ID, 0);
+					input_report_abs(ts->input_dev,
+					ABS_MT_TOUCH_MAJOR, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_WIDTH_MAJOR, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_PRESSURE, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_POSITION_X, x_position);
+					input_report_abs(ts->input_dev,
+					ABS_MT_POSITION_Y, y_position);
+					input_mt_sync(ts->input_dev);
+				} else if (ts->protocol_type
+					== PROTOCOL_TYPE_B) {
+					input_mt_slot(ts->input_dev, 0);
+
+					input_mt_report_slot_state
+					(ts->input_dev, MT_TOOL_FINGER, 1);
+
+					input_report_abs(ts->input_dev,
+					ABS_MT_TOUCH_MAJOR, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_WIDTH_MAJOR, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_PRESSURE, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_POSITION_X, x_position);
+					input_report_abs(ts->input_dev,
+					ABS_MT_POSITION_Y, y_position);
+				}
+			} else
+				input_report_key(ts->input_dev, KEY_BACK, 1);
+		} else if (tp_key_index == 0x02) {
 			vk_press = 1;
 			I("home key pressed\n");
-				if (ts->pdata->virtual_key)
-				{
-					if (ts->button[1].index) {
-						x_position = (ts->button[1].x_range_min + ts->button[1].x_range_max) / 2;
-						y_position = (ts->button[1].y_range_min + ts->button[1].y_range_max) / 2;
-					}
-						if (ts->protocol_type == PROTOCOL_TYPE_A) {
-						input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0);
-						input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_PRESSURE,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
-							x_position);
-						input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
-							y_position);
-						input_mt_sync(ts->input_dev);
-					} else if (ts->protocol_type == PROTOCOL_TYPE_B) {
-						input_mt_slot(ts->input_dev, 0);
-						input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER,
-						1);
-						input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_PRESSURE,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
-							x_position);
-						input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
-							y_position);
-					}
+			if (ts->pdata->virtual_key) {
+				if (ts->button[1].index) {
+					x_position = (ts->button[1].x_range_min
+					+ ts->button[1].x_range_max) / 2;
+					y_position = (ts->button[1].y_range_min
+					+ ts->button[1].y_range_max) / 2;
 				}
-				else
-					input_report_key(ts->input_dev, KEY_HOME, 1);
-		}
-		else if ( tp_key_index == 0x04) {
+				if (ts->protocol_type == PROTOCOL_TYPE_A) {
+					input_report_abs(ts->input_dev,
+					ABS_MT_TRACKING_ID, 0);
+					input_report_abs(ts->input_dev,
+					ABS_MT_TOUCH_MAJOR, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_WIDTH_MAJOR, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_PRESSURE, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_POSITION_X, x_position);
+					input_report_abs(ts->input_dev,
+					ABS_MT_POSITION_Y, y_position);
+					input_mt_sync(ts->input_dev);
+				} else if (ts->protocol_type
+				== PROTOCOL_TYPE_B) {
+					input_mt_slot(ts->input_dev, 0);
+
+					input_mt_report_slot_state
+					(ts->input_dev, MT_TOOL_FINGER, 1);
+
+					input_report_abs(ts->input_dev,
+					ABS_MT_TOUCH_MAJOR, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_WIDTH_MAJOR, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_PRESSURE, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_POSITION_X, x_position);
+					input_report_abs(ts->input_dev,
+					ABS_MT_POSITION_Y, y_position);
+				}
+			} else
+				input_report_key(ts->input_dev, KEY_HOME, 1);
+		} else if (tp_key_index == 0x04) {
 			vk_press = 1;
 			I("APP_switch key pressed\n");
-				if (ts->pdata->virtual_key)
-				{
-					if (ts->button[2].index) {
-						x_position = (ts->button[2].x_range_min + ts->button[2].x_range_max) / 2;
-						y_position = (ts->button[2].y_range_min + ts->button[2].y_range_max) / 2;
-					}
-						if (ts->protocol_type == PROTOCOL_TYPE_A) {
-						input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0);
-						input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_PRESSURE,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
-							x_position);
-						input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
-							y_position);
-						input_mt_sync(ts->input_dev);
-					} else if (ts->protocol_type == PROTOCOL_TYPE_B) {
-						input_mt_slot(ts->input_dev, 0);
-						input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER,
-						1);
-						input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_PRESSURE,
-							100);
-						input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
-							x_position);
-						input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
-							y_position);
-					}
+			if (ts->pdata->virtual_key) {
+				if (ts->button[2].index) {
+					x_position = (ts->button[2].x_range_min
+					+ ts->button[2].x_range_max) / 2;
+					y_position = (ts->button[2].y_range_min
+					+ ts->button[2].y_range_max) / 2;
 				}
-				else
-					input_report_key(ts->input_dev, KEY_F10, 1);	
+				if (ts->protocol_type == PROTOCOL_TYPE_A) {
+					input_report_abs(ts->input_dev,
+					ABS_MT_TRACKING_ID, 0);
+					input_report_abs(ts->input_dev,
+					ABS_MT_TOUCH_MAJOR, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_WIDTH_MAJOR, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_PRESSURE, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_POSITION_X, x_position);
+					input_report_abs(ts->input_dev,
+					ABS_MT_POSITION_Y, y_position);
+					input_mt_sync(ts->input_dev);
+				} else if (ts->protocol_type ==
+				PROTOCOL_TYPE_B) {
+					input_mt_slot(ts->input_dev, 0);
+
+					input_mt_report_slot_state
+					(ts->input_dev, MT_TOOL_FINGER, 1);
+
+					input_report_abs(ts->input_dev,
+					ABS_MT_TOUCH_MAJOR, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_WIDTH_MAJOR, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_PRESSURE, 100);
+					input_report_abs(ts->input_dev,
+					ABS_MT_POSITION_X, x_position);
+					input_report_abs(ts->input_dev,
+					ABS_MT_POSITION_Y, y_position);
+				}
+			} else
+				input_report_key(ts->input_dev, KEY_F10, 1);
 		}
 		input_sync(ts->input_dev);
-	}
-else/*tp_key_index =0x00*/
-	{
+	} else {/*tp_key_index =0x00*/
 		I("virtual key released\n");
 		vk_press = 0;
 		if (ts->protocol_type == PROTOCOL_TYPE_A) {
 			input_mt_sync(ts->input_dev);
-		}
-		else if (ts->protocol_type == PROTOCOL_TYPE_B) {
+		} else if (ts->protocol_type == PROTOCOL_TYPE_B) {
 			input_mt_slot(ts->input_dev, 0);
-			input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0);
+			input_mt_report_slot_state(ts->input_dev,
+			MT_TOOL_FINGER, 0);
 		}
 		input_report_key(ts->input_dev, KEY_BACK, 0);
 		input_report_key(ts->input_dev, KEY_HOME, 0);
 		input_report_key(ts->input_dev, KEY_F10, 0);
-	input_sync(ts->input_dev);
+		input_sync(ts->input_dev);
 	}
 }
 
@@ -915,8 +934,8 @@
 	uint8_t finger_on = 0;
 	int32_t loop_i;
 	uint16_t check_sum_cal = 0;
-	int raw_cnt_max ;
-	int raw_cnt_rmd ;
+	int raw_cnt_max;
+	int raw_cnt_rmd;
 	int hx_touch_info_size;
 	uint8_t coordInfoSize = ts->coord_data_size + ts->area_data_size + 4;
 
@@ -924,121 +943,111 @@
 	int16_t *mutual_data;
 	int16_t *self_data;
 	uint8_t diag_cmd;
-	int  	i;
-	int 	mul_num;
-	int 	self_num;
+	int i;
+	int mul_num;
+	int self_num;
 	int RawDataLen = 0;
-	//coordinate dump start
-	char coordinate_char[15+(ic_data->HX_MAX_PT+5)*2*5+2];
-	//coordinate dump end
+	/*coordinate dump start*/
+	char coordinate_char[15 + (ic_data->HX_MAX_PT + 5) * 2 * 5 + 2];
+	struct timeval t;
+	struct tm broken;
+	/*coordinate dump end*/
 #endif
 
 	memset(buf, 0x00, sizeof(buf));
 	memset(hw_reset_check, 0x00, sizeof(hw_reset_check));
 
-	raw_cnt_max = ic_data->HX_MAX_PT/4;
-	raw_cnt_rmd = ic_data->HX_MAX_PT%4;
-	
+	raw_cnt_max = ic_data->HX_MAX_PT / 4;
+	raw_cnt_rmd = ic_data->HX_MAX_PT % 4;
 #if defined(HX_USB_DETECT2)
 	himax_cable_detect_func();
 #endif
 
-	if (raw_cnt_rmd != 0x00) //more than 4 fingers
-	{
-		RawDataLen = cal_data_len(raw_cnt_rmd, ic_data->HX_MAX_PT, raw_cnt_max);
-		hx_touch_info_size = (ic_data->HX_MAX_PT+raw_cnt_max+2)*4;
-	}
-	else //less than 4 fingers
-	{
-		RawDataLen = cal_data_len(raw_cnt_rmd, ic_data->HX_MAX_PT, raw_cnt_max);
-		hx_touch_info_size = (ic_data->HX_MAX_PT+raw_cnt_max+1)*4;
+	if (raw_cnt_rmd != 0x00) { /*more than 4 fingers*/
+		RawDataLen = cal_data_len(raw_cnt_rmd,
+		ic_data->HX_MAX_PT, raw_cnt_max);
+		hx_touch_info_size = (ic_data->HX_MAX_PT + raw_cnt_max + 2) * 4;
+	} else { /*less than 4 fingers*/
+		RawDataLen = cal_data_len(raw_cnt_rmd,
+		ic_data->HX_MAX_PT, raw_cnt_max);
+		hx_touch_info_size = (ic_data->HX_MAX_PT + raw_cnt_max + 1) * 4;
 	}
 
 #ifdef HX_TP_PROC_DIAG
 	diag_cmd = getDiagCommand();
-	if( diag_cmd ){
+	if (diag_cmd) {
 		ret = read_event_stack(ts->client, buf, 128);
-	}
-	else{
-		if(touch_monitor_stop_flag != 0){
+	} else {
+		if (touch_monitor_stop_flag != 0) {
 			ret = read_event_stack(ts->client, buf, 128);
-			touch_monitor_stop_flag-- ;
-		}
-		else{
-			ret = read_event_stack(ts->client, buf, hx_touch_info_size);
+			touch_monitor_stop_flag--;
+		} else {
+			ret = read_event_stack(ts->client,
+					buf, hx_touch_info_size);
 		}
 	}
 
 	if (!ret)
 #else
-	if(!read_event_stack(ts->client, buf, hx_touch_info_size))
-#endif		
-	{
-		E("%s: can't read data from chip!\n", __func__);
-		goto err_workqueue_out;
-	}
+	if (!read_event_stack(ts->client, buf, hx_touch_info_size))
+#endif
+		{
+			E("%s: can't read data from chip!\n", __func__);
+			goto err_workqueue_out;
+		}
 	post_read_event_stack(ts->client);
 #ifdef HX_ESD_WORKAROUND
-	for(i = 0; i < hx_touch_info_size; i++)
-	{
-		if(buf[i] == 0xED)/*case 1 ESD recovery flow*/
-		{
+	for (i = 0; i < hx_touch_info_size; i++) {
+		if (buf[i] == 0xED)	{ /*case 1 ESD recovery flow*/
 			check_sum_cal = 1;
 
-		}else if(buf[i] == 0x00)
-		{
+		} else if (buf[i] == 0x00) {
 			ESD_00_Flag = 1;
-		}
-		else
-		{
+		} else {
 			check_sum_cal = 0;
 			ESD_00_counter = 0;
-	    ESD_00_Flag = 0;
+			ESD_00_Flag = 0;
 			i = hx_touch_info_size;
 			break;
-		}		
+		}
 	}
-	if (ESD_00_Flag == 1){
-		ESD_00_counter ++;
-	}
-	if (ESD_00_counter > 1){
+	if (ESD_00_Flag == 1)
+		ESD_00_counter++;
+	if (ESD_00_counter > 1)
 		check_sum_cal = 2;
-	}
-	
-	 if (check_sum_cal == 2 && HX_ESD_RESET_ACTIVATE == 0)
-	 {
-	  I("[HIMAX TP MSG]: ESD event checked - ALL Zero.\n");
-	  ESD_HW_REST();
-	  return;
-	 }
-	 
-	if (check_sum_cal == 1 && HX_ESD_RESET_ACTIVATE == 0)
-	{
-		I("[HIMAX TP MSG]: ESD event checked - ALL 0xED.\n");
+	if (check_sum_cal == 2 && HX_ESD_RESET_ACTIVATE == 0) {
+		I("[HIMAX TP MSG]: ESD event checked - ALL Zero.\n");
 		ESD_HW_REST();
 		return;
 	}
-	else if (HX_ESD_RESET_ACTIVATE)
-	{
+	if (check_sum_cal == 1 && HX_ESD_RESET_ACTIVATE == 0) {
+		I("[HIMAX TP MSG]: ESD event checked - ALL 0xED.\n");
+		ESD_HW_REST();
+		return;
+	} else if (HX_ESD_RESET_ACTIVATE) {
 #ifdef HX_SMART_WAKEUP
-		queue_delayed_work(ts->himax_smwp_wq, &ts->smwp_work, msecs_to_jiffies(50));
+		queue_delayed_work(ts->himax_smwp_wq,
+		&ts->smwp_work, msecs_to_jiffies(50));
 #endif
 #ifdef HX_HIGH_SENSE
-		queue_delayed_work(ts->himax_hsen_wq, &ts->hsen_work, msecs_to_jiffies(50));
+		queue_delayed_work(ts->himax_hsen_wq,
+		&ts->hsen_work, msecs_to_jiffies(50));
 #endif
-		HX_ESD_RESET_ACTIVATE = 0;/*drop 1st interrupts after chip reset*/
-		I("[HIMAX TP MSG]:%s: Back from reset, ready to serve.\n", __func__);
+/*drop 1st interrupts after chip reset*/
+		HX_ESD_RESET_ACTIVATE = 0;
+		I("[HIMAX TP MSG]:%s: Back from reset,ready to serve.\n",
+		__func__);
 	}
 #endif
-	for (loop_i = 0, check_sum_cal = 0; loop_i < hx_touch_info_size; loop_i++)
+	for (loop_i = 0, check_sum_cal = 0;
+	loop_i < hx_touch_info_size; loop_i++)
 		check_sum_cal += buf[loop_i];
-	
-	if ((check_sum_cal % 0x100 != 0) )
-	{
-		I("[HIMAX TP MSG] checksum fail : check_sum_cal: 0x%02X\n", check_sum_cal);
+
+	if ((check_sum_cal % 0x100 != 0)) {
+		I("[HIMAX TP MSG] checksum fail : check_sum_cal: 0x%02X\n",
+		check_sum_cal);
 		return;
 	}
-
 	if (ts->debug_log_level & BIT(0)) {
 		I("%s: raw data:\n", __func__);
 		for (loop_i = 0; loop_i < hx_touch_info_size; loop_i++) {
@@ -1048,260 +1057,289 @@
 		}
 	}
 
-	//touch monitor raw data fetch
+	/*touch monitor raw data fetch*/
 #ifdef HX_TP_PROC_DIAG
 	diag_cmd = getDiagCommand();
-	if (diag_cmd >= 1 && diag_cmd <= 6)
-	{
-		//Check 124th byte CRC
-		if(!diag_check_sum(hx_touch_info_size, buf))
-		{
+	if (diag_cmd >= 1 && diag_cmd <= 6) {
+		/*Check 124th byte CRC*/
+		if (!diag_check_sum(hx_touch_info_size, buf))
 			goto bypass_checksum_failed_packet;
-		}
-#ifdef HX_TP_PROC_2T2R
-		if(Is_2T2R && diag_cmd == 4)
-		{
-			mutual_data = getMutualBuffer_2();
-			self_data 	= getSelfBuffer();
 
-			// initiallize the block number of mutual and self
+#ifdef HX_TP_PROC_2T2R
+		if (Is_2T2R && diag_cmd == 4) {
+			mutual_data = getMutualBuffer_2();
+			self_data = getSelfBuffer();
+
+			/* initiallize the block number of mutual and self*/
 			mul_num = getXChannel_2() * getYChannel_2();
 
 #ifdef HX_EN_SEL_BUTTON
-			self_num = getXChannel_2() + getYChannel_2() + ic_data->HX_BT_NUM;
+			self_num = getXChannel_2() +
+					getYChannel_2() + ic_data->HX_BT_NUM;
 #else
 			self_num = getXChannel_2() + getYChannel_2();
 #endif
-		}
-		else
-#endif			
+		} else
+#endif
 		{
 			mutual_data = getMutualBuffer();
-			self_data 	= getSelfBuffer();
+			self_data = getSelfBuffer();
 
-			// initiallize the block number of mutual and self
+			/* initiallize the block number of mutual and self*/
 			mul_num = getXChannel() * getYChannel();
 
 #ifdef HX_EN_SEL_BUTTON
-			self_num = getXChannel() + getYChannel() + ic_data->HX_BT_NUM;
+			self_num = getXChannel() +
+					getYChannel() + ic_data->HX_BT_NUM;
 #else
 			self_num = getXChannel() + getYChannel();
 #endif
 		}
 
-		diag_parse_raw_data(hx_touch_info_size, RawDataLen, mul_num, self_num, buf, diag_cmd, mutual_data,	self_data);
+		diag_parse_raw_data(hx_touch_info_size,
+		RawDataLen, mul_num, self_num, buf,
+		diag_cmd, mutual_data, self_data);
 
-	}
-	else if (diag_cmd == 7)
-	{
+	} else if (diag_cmd == 7) {
 		memcpy(&(diag_coor[0]), &buf[0], 128);
 	}
-	//coordinate dump start
-	if (coordinate_dump_enable == 1)
-	{
-		for(i=0; i<(15 + (ic_data->HX_MAX_PT+5)*2*5); i++)
-		{
+	/*coordinate dump start*/
+	if (coordinate_dump_enable == 1) {
+		for (i = 0; i < (15 + (ic_data->
+			HX_MAX_PT + 5) * 2 * 5);
+		i++) {
 			coordinate_char[i] = 0x20;
 		}
-		coordinate_char[15 + (ic_data->HX_MAX_PT+5)*2*5] = 0xD;
-		coordinate_char[15 + (ic_data->HX_MAX_PT+5)*2*5 + 1] = 0xA;
+		coordinate_char[15 +
+		(ic_data->HX_MAX_PT + 5) * 2 * 5] = 0xD;
+		coordinate_char[15 +
+		(ic_data->HX_MAX_PT + 5) * 2 * 5 + 1] = 0xA;
 	}
-	//coordinate dump end
+	/*coordinate dump end*/
 bypass_checksum_failed_packet:
 #endif
-		EN_NoiseFilter = (buf[HX_TOUCH_INFO_POINT_CNT+2]>>3);
-		//I("EN_NoiseFilter=%d\n",EN_NoiseFilter);
-		EN_NoiseFilter = EN_NoiseFilter & 0x01;
-		//I("EN_NoiseFilter2=%d\n",EN_NoiseFilter);
+	EN_NoiseFilter = (buf[HX_TOUCH_INFO_POINT_CNT + 2] >> 3);
+	/*I("EN_NoiseFilter=%d\n",EN_NoiseFilter);*/
+	EN_NoiseFilter = EN_NoiseFilter & 0x01;
+	/*I("EN_NoiseFilter2=%d\n",EN_NoiseFilter);*/
 
 #if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON)
-		tpd_key = (buf[HX_TOUCH_INFO_POINT_CNT+2]>>4);
-		if (tpd_key == 0x0F)/*All (VK+AA)leave*/
-		{
-			tpd_key = 0x00;
-		}
-		//I("[DEBUG] tpd_key:  %x\r\n", tpd_key);
-#else
+	tpd_key = (buf[HX_TOUCH_INFO_POINT_CNT + 2] >> 4);
+	if (tpd_key == 0x0F) {/*All (VK+AA)leave*/
 		tpd_key = 0x00;
+	}
+	/*I("[DEBUG] tpd_key:  %x\r\n", tpd_key);*/
+#else
+	tpd_key = 0x00;
 #endif
 
-		p_point_num = hx_point_num;
+	p_point_num = hx_point_num;
 
-		if (buf[HX_TOUCH_INFO_POINT_CNT] == 0xff)
-			hx_point_num = 0;
-		else
-			hx_point_num= buf[HX_TOUCH_INFO_POINT_CNT] & 0x0f;
+	if (buf[HX_TOUCH_INFO_POINT_CNT] == 0xff)
+		hx_point_num = 0;
+	else
+		hx_point_num = buf[HX_TOUCH_INFO_POINT_CNT] & 0x0f;
 
-		// Touch Point information
-		if (hx_point_num != 0 ) {
-			if(vk_press == 0x00)
-				{
-					uint16_t old_finger = ts->pre_finger_mask;
-					ts->pre_finger_mask = 0;
-					finger_num = buf[coordInfoSize - 4] & 0x0F;
-					finger_on = 1;
-					AA_press = 1;
-					for (loop_i = 0; loop_i < ts->nFinger_support; loop_i++) {
-							int base = loop_i * 4;
-							int x = buf[base] << 8 | buf[base + 1];
-							int y = (buf[base + 2] << 8 | buf[base + 3]);
-							int w = buf[(ts->nFinger_support * 4) + loop_i];
-						if(x >= 0 && x <= ts->pdata->abs_x_max && y >= 0 && y <= ts->pdata->abs_y_max){
-							finger_num--;
+	/* Touch Point information*/
+	if ((hx_point_num != 0) && (vk_press == 0x00)) {
+		uint16_t old_finger = ts->pre_finger_mask;
 
-							if ((ts->debug_log_level & BIT(3)) > 0)
-							{
-								if (old_finger >> loop_i == 0)
-								{
-									if (ts->useScreenRes)
-									{
-										I("status: Screen:F:%02d Down, X:%d, Y:%d, W:%d, N:%d\n",
-										loop_i+1, x * ts->widthFactor >> SHIFTBITS,
-										y * ts->heightFactor >> SHIFTBITS, w, EN_NoiseFilter);
-									}
-									else
-									{
-										I("status: Raw:F:%02d Down, X:%d, Y:%d, W:%d, N:%d\n",
-										loop_i+1, x, y, w, EN_NoiseFilter);
-									}
-								}
-							}
+		ts->pre_finger_mask = 0;
+		finger_num = buf[coordInfoSize - 4] & 0x0F;
+		finger_on = 1;
+		AA_press = 1;
+		for (i = 0; i < ts->nFinger_support; i++) {
+			int base = i * 4;
+			int x = buf[base] << 8 | buf[base + 1];
+			int y = (buf[base + 2] << 8 | buf[base + 3]);
+			int w = buf[(ts->nFinger_support * 4) + i];
 
-							if (ts->protocol_type == PROTOCOL_TYPE_B)
-							{
-								input_mt_slot(ts->input_dev, loop_i);
-							}
-
-							input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w);
-							input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);
-							input_report_abs(ts->input_dev, ABS_MT_PRESSURE, w);
-							input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
-							input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
-							
-							if (ts->protocol_type == PROTOCOL_TYPE_A)
-							{
-								input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, loop_i);
-								input_mt_sync(ts->input_dev);
-							}
-							else
-							{
-								ts->last_slot = loop_i;
-								input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 1);
-							}
-
-							if (!ts->first_pressed)
-							{
-								ts->first_pressed = 1;
-								I("S1@%d, %d\n", x, y);
-							}
-
-							ts->pre_finger_data[loop_i][0] = x;
-							ts->pre_finger_data[loop_i][1] = y;
-
-
-							if (ts->debug_log_level & BIT(1))
-								I("Finger %d=> X:%d, Y:%d W:%d, Z:%d, F:%d, N:%d\n",
-									loop_i + 1, x, y, w, w, loop_i + 1, EN_NoiseFilter);
-										
-							ts->pre_finger_mask = ts->pre_finger_mask + (1 << loop_i);
-											
-						} else {
-							if (ts->protocol_type == PROTOCOL_TYPE_B)
-							{
-								input_mt_slot(ts->input_dev, loop_i);
-								input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0);
-							}
-
-							if (loop_i == 0 && ts->first_pressed == 1)
-							{
-								ts->first_pressed = 2;
-								I("E1@%d, %d\n",
-								ts->pre_finger_data[0][0] , ts->pre_finger_data[0][1]);
-							}
-							if ((ts->debug_log_level & BIT(3)) > 0)
-							{
-								if (old_finger >> loop_i == 1)
-								{
-									if (ts->useScreenRes)
-									{
-										I("status: Screen:F:%02d Up, X:%d, Y:%d, N:%d\n",
-										loop_i+1, ts->pre_finger_data[loop_i][0] * ts->widthFactor >> SHIFTBITS,
-										ts->pre_finger_data[loop_i][1] * ts->heightFactor >> SHIFTBITS, Last_EN_NoiseFilter);
-									}
-									else
-									{
-										I("status: Raw:F:%02d Up, X:%d, Y:%d, N:%d\n",
-										loop_i+1, ts->pre_finger_data[loop_i][0],
-										ts->pre_finger_data[loop_i][1], Last_EN_NoiseFilter);
-									}
-								}
-							}
-						}
-					}
-
-				}else if ((tpd_key_old != 0x00)&&(tpd_key == 0x00)) {
-					//temp_x[0] = 0xFFFF;
-					//temp_y[0] = 0xFFFF;
-					//temp_x[1] = 0xFFFF;
-					//temp_y[1] = 0xFFFF;
-					himax_ts_button_func(tpd_key,ts);
-					finger_on = 0;
+			if (x >= 0 && x <= ts->pdata->abs_x_max
+			&& y >= 0 && y <= ts->pdata->abs_y_max) {
+				finger_num--;
+				if ((((ts->debug_log_level & BIT(3)) > 0)
+				&& (old_finger >> i == 0))
+				&& (ts->useScreenRes)) {
+					I("status:Screen:F:%02d", i + 1);
+					I("Down,X:%d,Y:%d,W:%d,N:%d\n",
+					x * ts->widthFactor >> SHIFTBITS,
+					y * ts->heightFactor >> SHIFTBITS,
+					w, EN_NoiseFilter);
+				} else if ((((ts->debug_log_level & BIT(3)) > 0)
+				&& (old_finger >> i == 0))
+				&& !(ts->useScreenRes)) {
+					I("status:Raw:F:%02d", i + 1);
+					I("Down,X:%d,Y:%d,W:%d,N:%d\n",
+					x, y, w, EN_NoiseFilter);
 				}
-			input_report_key(ts->input_dev, BTN_TOUCH, finger_on);
-			input_sync(ts->input_dev);
-		} else if (hx_point_num == 0){
-			if(AA_press)
-				{
-				// leave event
-				finger_on = 0;
-				AA_press = 0;
-				if (ts->protocol_type == PROTOCOL_TYPE_A)
+
+				if (ts->protocol_type == PROTOCOL_TYPE_B)
+					input_mt_slot(ts->input_dev, i);
+
+				input_report_abs(ts->input_dev,
+				ABS_MT_TOUCH_MAJOR, w);
+				input_report_abs(ts->input_dev,
+				ABS_MT_WIDTH_MAJOR, w);
+				input_report_abs(ts->input_dev,
+				ABS_MT_PRESSURE, w);
+				input_report_abs(ts->input_dev,
+				ABS_MT_POSITION_X, x);
+				input_report_abs(ts->input_dev,
+				ABS_MT_POSITION_Y, y);
+
+				if (ts->protocol_type == PROTOCOL_TYPE_A) {
+					input_report_abs(ts->input_dev,
+					ABS_MT_TRACKING_ID, i);
 					input_mt_sync(ts->input_dev);
-
-				for (loop_i = 0; loop_i < ts->nFinger_support; loop_i++) {
-						if (((ts->pre_finger_mask >> loop_i) & 1) == 1) {
-							if (ts->protocol_type == PROTOCOL_TYPE_B) {
-								input_mt_slot(ts->input_dev, loop_i);
-								input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0);
-							}
-						}
-					}
-				if (ts->pre_finger_mask > 0) {
-					for (loop_i = 0; loop_i < ts->nFinger_support && (ts->debug_log_level & BIT(3)) > 0; loop_i++) {
-						if (((ts->pre_finger_mask >> loop_i) & 1) == 1) {
-							if (ts->useScreenRes) {
-								I("status:%X, Screen:F:%02d Up, X:%d, Y:%d, N:%d\n", 0, loop_i+1, ts->pre_finger_data[loop_i][0] * ts->widthFactor >> SHIFTBITS,
-									ts->pre_finger_data[loop_i][1] * ts->heightFactor >> SHIFTBITS, Last_EN_NoiseFilter);
-							} else {
-								I("status:%X, Raw:F:%02d Up, X:%d, Y:%d, N:%d\n",0, loop_i+1, ts->pre_finger_data[loop_i][0],ts->pre_finger_data[loop_i][1], Last_EN_NoiseFilter);
-							}
-						}
-					}
-					ts->pre_finger_mask = 0;
+				} else {
+					ts->last_slot = i;
+					input_mt_report_slot_state
+					(ts->input_dev,
+					MT_TOOL_FINGER, 1);
 				}
 
-				if (ts->first_pressed == 1) {
+				if (!ts->first_pressed) {
+					ts->first_pressed = 1;
+					I("S1@%d, %d\n", x, y);
+				}
+
+				ts->pre_finger_data[i][0] = x;
+				ts->pre_finger_data[i][1] = y;
+
+				if (ts->debug_log_level & BIT(1)) {
+					I("Finger %d=> X:%d,Y:%d,W:%d,",
+					i + 1, x, y, w);
+					I("Z:%d,F:%d,N:%d\n",
+					w, i + 1, EN_NoiseFilter);
+				}
+				ts->pre_finger_mask =
+				ts->pre_finger_mask + (1 << i);
+
+			} else {
+				if (ts->protocol_type == PROTOCOL_TYPE_B) {
+					input_mt_slot(ts->input_dev, i);
+					input_mt_report_slot_state
+					(ts->input_dev, MT_TOOL_FINGER, 0);
+				}
+				if (i == 0 && ts->first_pressed == 1) {
 					ts->first_pressed = 2;
-					I("E1@%d, %d\n",ts->pre_finger_data[0][0] , ts->pre_finger_data[0][1]);
+					I("E1@%d, %d\n",
+					ts->pre_finger_data[0][0],
+					ts->pre_finger_data[0][1]);
 				}
-
-				if (ts->debug_log_level & BIT(1))
-					I("All Finger leave\n");
-
+				if ((((ts->debug_log_level & BIT(3)) > 0)
+				&& (old_finger >> i == 1))
+				&& (ts->useScreenRes)) {
+					I("status:Screen:F:%02d,Up,X:%d,Y:%d\n",
+					i + 1, ts->pre_finger_data[i][0]
+					* ts->widthFactor >> SHIFTBITS,
+					ts->pre_finger_data[i][1]
+					* ts->heightFactor >> SHIFTBITS);
+				} else if ((((ts->debug_log_level & BIT(3)) > 0)
+				&& (old_finger >> i == 1))
+				&& !(ts->useScreenRes)) {
+					I("status:Raw:F:%02d,Up,X:%d,Y:%d\n",
+					i + 1, ts->pre_finger_data[i][0],
+					ts->pre_finger_data[i][1]);
+				}
 			}
-			else if (tpd_key != 0x00) {
-				himax_ts_button_func(tpd_key,ts);
-				finger_on = 1;
-			}
-			else if ((tpd_key_old != 0x00)&&(tpd_key == 0x00)) {
-				himax_ts_button_func(tpd_key,ts);
-				finger_on = 0;
-			}
-			input_report_key(ts->input_dev, BTN_TOUCH, finger_on);
-			input_sync(ts->input_dev);
 		}
-		tpd_key_old = tpd_key;
-		Last_EN_NoiseFilter = EN_NoiseFilter;
+		input_report_key(ts->input_dev, BTN_TOUCH, finger_on);
+		input_sync(ts->input_dev);
+	} else if ((hx_point_num != 0)
+		&& ((tpd_key_old != 0x00) && (tpd_key == 0x00))) {
+		/*temp_x[0] = 0xFFFF;*/
+		/*temp_y[0] = 0xFFFF;*/
+		/*temp_x[1] = 0xFFFF;*/
+		/*temp_y[1] = 0xFFFF;*/
+		himax_ts_button_func(tpd_key, ts);
+		finger_on = 0;
+		input_report_key(ts->input_dev, BTN_TOUCH, finger_on);
+		input_sync(ts->input_dev);
+	} else if (hx_point_num == 0) {
+		if (AA_press) {
+			/*leave event*/
+			finger_on = 0;
+			AA_press = 0;
+			if (ts->protocol_type == PROTOCOL_TYPE_A)
+				input_mt_sync(ts->input_dev);
+
+			for (i = 0 ; i < ts->nFinger_support ; i++) {
+				if ((((ts->pre_finger_mask >> i) & 1) == 1)
+				&& (ts->protocol_type == PROTOCOL_TYPE_B)) {
+					input_mt_slot(ts->input_dev, i);
+					input_mt_report_slot_state
+					(ts->input_dev, MT_TOOL_FINGER, 0);
+				}
+			}
+			if (ts->pre_finger_mask > 0) {
+				for (i = 0; i < ts->nFinger_support
+				&& (ts->debug_log_level & BIT(3)) > 0; i++) {
+					if ((((ts->pre_finger_mask
+					>> i) & 1) == 1)
+					&& (ts->useScreenRes)) {
+						I("status:%X,", 0);
+						I("Screen:F:%02d,", i + 1);
+						I("Up,X:%d,Y:%d\n",
+						ts->pre_finger_data[i][0]
+						* ts->widthFactor >> SHIFTBITS,
+						ts->pre_finger_data[i][1]
+						* ts->heightFactor >> SHIFTBITS
+						);
+					} else if ((((ts->pre_finger_mask
+					>> i) & 1) == 1)
+					&& !(ts->useScreenRes)) {
+						I("status:%X,", 0);
+						I("Screen:F:%02d,", i + 1);
+						I("Up,X:%d,Y:%d\n",
+						ts->pre_finger_data[i][0],
+						ts->pre_finger_data[i][1]);
+					}
+				}
+				ts->pre_finger_mask = 0;
+			}
+
+			if (ts->first_pressed == 1) {
+				ts->first_pressed = 2;
+				I("E1@%d, %d\n", ts->pre_finger_data[0][0],
+				ts->pre_finger_data[0][1]);
+			}
+
+			if (ts->debug_log_level & BIT(1))
+				I("All Finger leave\n");
+
+#ifdef HX_TP_PROC_DIAG
+				/*coordinate dump start*/
+				if (coordinate_dump_enable == 1) {
+					do_gettimeofday(&t);
+					time_to_tm(t.tv_sec, 0, &broken);
+					snprintf(&coordinate_char[0], 15,
+					"%2d:%2d:%2d:%lu,", broken.tm_hour,
+					broken.tm_min, broken.tm_sec,
+					t.tv_usec / 1000);
+
+					snprintf(&coordinate_char[15], 10,
+					"Touch up!");
+
+					coordinate_fn->f_op->write
+					(coordinate_fn, &coordinate_char[0],
+					15 + (ic_data->HX_MAX_PT + 5)
+					* 2 * sizeof(char) * 5 + 2,
+					&coordinate_fn->f_pos);
+				}
+				/*coordinate dump end*/
+#endif
+		} else if (tpd_key != 0x00) {
+			himax_ts_button_func(tpd_key, ts);
+			finger_on = 1;
+		} else if ((tpd_key_old != 0x00) && (tpd_key == 0x00)) {
+			himax_ts_button_func(tpd_key, ts);
+			finger_on = 0;
+		}
+		input_report_key(ts->input_dev, BTN_TOUCH, finger_on);
+		input_sync(ts->input_dev);
+	}
+	tpd_key_old = tpd_key;
 
 workqueue_out:
 	return;
@@ -1310,7 +1348,7 @@
 	I("%s: Now reset the Touch chip.\n", __func__);
 
 #ifdef HX_RST_PIN_FUNC
-	himax_HW_reset(true,false);
+	himax_HW_reset(true, false);
 #endif
 
 	goto workqueue_out;
@@ -1329,6 +1367,7 @@
 static void himax_cable_tp_status_handler_func(int connect_status)
 {
 	struct himax_ts_data *ts;
+
 	I("Touch: cable change to %d\n", connect_status);
 	ts = private_ts;
 	if (ts->cable_config) {
@@ -1342,18 +1381,23 @@
 					ts->usb_connected = 0x00;
 				}
 
-				i2c_himax_master_write(ts->client, ts->cable_config,
-					sizeof(ts->cable_config), HIMAX_I2C_RETRY_TIMES);
+				i2c_himax_master_write(ts->client,
+				ts->cable_config,
+				sizeof(ts->cable_config),
+				HIMAX_I2C_RETRY_TIMES);
 
-				I("%s: Cable status change: 0x%2.2X\n", __func__, ts->cable_config[1]);
+				I("%s: Cable status change: 0x%2.2X\n",
+				__func__, ts->cable_config[1]);
 			} else
-				I("%s: Cable status is the same as previous one, ignore.\n", __func__);
+				I("%s: Cable status is same, ignore.\n",
+				__func__);
 		} else {
 			if (connect_status)
 				ts->usb_connected = 0x01;
 			else
 				ts->usb_connected = 0x00;
-			I("%s: Cable status remembered: 0x%2.2X\n", __func__, ts->usb_connected);
+			I("%s: Cable status remembered: 0x%2.2X\n",
+			__func__, ts->usb_connected);
 		}
 	}
 }
@@ -1373,16 +1417,20 @@
 	struct himax_ts_data *ts;
 	u32 connect_status = 0;
 
-	connect_status = USB_Flag;//upmu_is_chr_det();
+	connect_status = USB_Flag;/*upmu_is_chr_det();*/
 	ts = private_ts;
-	//I("Touch: cable status=%d, cable_config=%p, usb_connected=%d \n", connect_status,ts->cable_config, ts->usb_connected);
+	/*I("Touch: cable status=%d, cable_config=%p,
+	usb_connected=%d\n", connect_status,
+	ts->cable_config, ts->usb_connected);*/
+
 	if (ts->cable_config) {
 		if ((!!connect_status) != ts->usb_connected) {
-			//notify USB plug/unplug
-			// 0x9008_8060 ==> 0x0000_0000/0001
-			tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x60;
-			tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00;
-			
+			/*notify USB plug/unplug*/
+			/*0x9008_8060 ==> 0x0000_0000/0001*/
+			tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+			tmp_addr[1] = 0x80; tmp_addr[0] = 0x60;
+			tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+			tmp_data[1] = 0x00;
 			if (!!connect_status) {
 				tmp_data[0] = 0x01;
 				ts->usb_connected = 0x01;
@@ -1393,10 +1441,13 @@
 
 			himax_flash_write_burst(ts->client, tmp_addr, tmp_data);
 
-			I("%s: Cable status change: 0x%2.2X\n", __func__, ts->usb_connected);
-			}
-		//else
-			//I("%s: Cable status is the same as previous one, ignore.\n", __func__);
+			I("%s: Cable status change: 0x%2.2X\n",
+			__func__, ts->usb_connected);
+		}
+		/*else*/
+			/*I("%s: Cable status is the same as previous one,
+			ignore.\n", __func__);*/
+
 	}
 }
 #endif
@@ -1417,52 +1468,52 @@
 #endif
 
 #ifdef HX_SMART_WAKEUP
-void himax_set_SMWP_func(struct i2c_client *client,uint8_t SMWP_enable)
+void himax_set_SMWP_func(struct i2c_client *client, uint8_t SMWP_enable)
 {
 	uint8_t tmp_data[4];
 
-	if(SMWP_enable)
-	{
-		SMWP_bit_retry:
+	if (SMWP_enable) {
+SMWP_bit_retry:
 		himax_set_SMWP_enable(client, SMWP_enable);
 		msleep(20);
-		himax_get_SMWP_enable(client,tmp_data);
-		I("%s: Read SMWP bit data[0]=%x data[1]=%x data[2]=%x data[3]=%x\n", __func__
-			,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]);
-		if(tmp_data[0]!= 0x01)
-			{
-				I("%s: retry SMWP bit write data[0]=%x  \n",__func__,tmp_data[0]);
-				goto SMWP_bit_retry;
-			}
+		himax_get_SMWP_enable(client, tmp_data);
+I("%s: Read SMWP bit data[0]=%x data[1]=%x data[2]=%x data[3]=%x\n",
+__func__, tmp_data[0], tmp_data[1], tmp_data[2], tmp_data[3]);
+
+		if (tmp_data[0] != 0x01) {
+			I("%s: retry SMWP bit write data[0]=%x\n",
+			__func__, tmp_data[0]);
+			goto SMWP_bit_retry;
+		}
 	}
 }
 
 static void himax_SMWP_work(struct work_struct *work)
 {
-	struct himax_ts_data *ts = container_of(work, struct himax_ts_data,
-							smwp_work.work);
+	struct himax_ts_data *ts =
+	container_of(work, struct himax_ts_data, smwp_work.work);
 	I(" %s in", __func__);
 
-	himax_set_SMWP_func(ts->client,ts->SMWP_enable);
+	himax_set_SMWP_func(ts->client, ts->SMWP_enable);
 
 }
 #endif
 
-#ifdef  HX_TP_PROC_FLASH_DUMP
+#ifdef HX_TP_PROC_FLASH_DUMP
 static void himax_ts_flash_work_func(struct work_struct *work)
 {
 	himax_ts_flash_func();
 }
 #endif
 
-#ifdef  HX_TP_PROC_DIAG
+#ifdef HX_TP_PROC_DIAG
 static void himax_ts_diag_work_func(struct work_struct *work)
 {
 	himax_ts_diag_func();
 }
 #endif
 
-void himax_ts_init(struct himax_ts_data *ts)
+bool himax_ts_init(struct himax_ts_data *ts)
 {
 	int ret = 0, err = 0;
 	struct himax_i2c_platform_data *pdata;
@@ -1476,15 +1527,14 @@
 	/* Set pinctrl in active state */
 	if (ts->ts_pinctrl) {
 		ret = pinctrl_select_state(ts->ts_pinctrl,
-					ts->pinctrl_state_active);
-		if (ret < 0) {
-			E("Failed to set pin in active state %d",ret);
-		}
+		ts->pinctrl_state_active);
+		if (ret < 0)
+			E("Failed to set pin in active state %d", ret);
 	}
 
 	himax_burst_enable(client, 0);
 
-	//Get Himax IC Type / FW information / Calculate the point number
+	/*Get Himax IC Type / FW information / Calculate the point number */
 	if (himax_check_chip_version(ts->client) == false) {
 		E("Himax chip doesn NOT EXIST");
 		goto err_ic_package_failed;
@@ -1496,10 +1546,9 @@
 
 	if (pdata->virtual_key)
 		ts->button = pdata->virtual_key;
-#ifdef  HX_TP_PROC_FLASH_DUMP
+#ifdef HX_TP_PROC_FLASH_DUMP
 	ts->flash_wq = create_singlethread_workqueue("himax_flash_wq");
-	if (!ts->flash_wq)
-	{
+	if (!ts->flash_wq) {
 		E("%s: create flash workqueue failed\n", __func__);
 		err = -ENOMEM;
 		goto err_create_wq_failed;
@@ -1511,10 +1560,9 @@
 	setFlashBuffer();
 #endif
 
-#ifdef  HX_TP_PROC_DIAG
+#ifdef HX_TP_PROC_DIAG
 	ts->himax_diag_wq = create_singlethread_workqueue("himax_diag");
-	if (!ts->himax_diag_wq)
-	{
+	if (!ts->himax_diag_wq) {
 		E("%s: create diag workqueue failed\n", __func__);
 		err = -ENOMEM;
 		goto err_create_wq_failed;
@@ -1526,40 +1574,42 @@
 
 #ifdef HX_AUTO_UPDATE_FW
 	I(" %s in", __func__);
-	if(i_update_FW() == false)
-		I("NOT Have new FW=NOT UPDATE=\n");
+	if (i_update_FW() <= 0)
+		I("FW NOT UPDATE=\n");
 	else
 		I("Have new FW=UPDATE=\n");
 #endif
 
-	//Himax Power On and Load Config
+	/*Himax Power On and Load Config*/
 	if (himax_loadSensorConfig(client, pdata) < 0) {
-		E("%s: Load Sesnsor configuration failed, unload driver.\n", __func__);
+		E("%s: Load Sesnsor config failed,unload driver.\n",
+		__func__);
 		goto err_detect_failed;
 	}
 
 	calculate_point_number();
 #ifdef HX_TP_PROC_DIAG
-	setXChannel(ic_data->HX_RX_NUM); // X channel
-	setYChannel(ic_data->HX_TX_NUM); // Y channel
+	setXChannel(ic_data->HX_RX_NUM); /*X channel*/
+	setYChannel(ic_data->HX_TX_NUM); /*Y channel*/
 
 	setMutualBuffer();
 	setMutualNewBuffer();
 	setMutualOldBuffer();
 	if (getMutualBuffer() == NULL) {
 		E("%s: mutual buffer allocate fail failed\n", __func__);
-		return;
+		return false;
 	}
 #ifdef HX_TP_PROC_2T2R
-	if(Is_2T2R){
-		setXChannel_2(ic_data->HX_RX_NUM_2); // X channel
-		setYChannel_2(ic_data->HX_TX_NUM_2); // Y channel
+	if (Is_2T2R) {
+		setXChannel_2(ic_data->HX_RX_NUM_2); /*X channel*/
+		setYChannel_2(ic_data->HX_TX_NUM_2); /*Y channel*/
 
 		setMutualBuffer_2();
 
 		if (getMutualBuffer_2() == NULL) {
-			E("%s: mutual buffer 2 allocate fail failed\n", __func__);
-			return;
+			E("%s: mutual buffer 2 allocate fail failed\n",
+			__func__);
+			return false;
 		}
 	}
 #endif
@@ -1572,7 +1622,7 @@
 	ts->x_channel = ic_data->HX_RX_NUM;
 	ts->y_channel = ic_data->HX_TX_NUM;
 	ts->nFinger_support = ic_data->HX_MAX_PT;
-	//calculate the i2c data size
+	/*calculate the i2c data size*/
 	calcDataSize(ts->nFinger_support);
 	I("%s: calcDataSize complete\n", __func__);
 #ifdef CONFIG_OF
@@ -1584,14 +1634,13 @@
 	pdata->cable_config[1] = 0x00;
 #endif
 	ts->suspended = false;
-#if defined(HX_USB_DETECT)||defined(HX_USB_DETECT2)
+#if defined(HX_USB_DETECT) || defined(HX_USB_DETECT2)
 	ts->usb_connected = 0x00;
 	ts->cable_config = pdata->cable_config;
 #endif
 	ts->protocol_type = pdata->protocol_type;
 	I("%s: Use Protocol Type %c\n", __func__,
 	ts->protocol_type == PROTOCOL_TYPE_A ? 'A' : 'B');
-
 	ret = himax_input_register(ts);
 	if (ret) {
 		E("%s: Unable to register %s input device\n",
@@ -1599,8 +1648,9 @@
 		goto err_input_register_device_failed;
 	}
 #ifdef HX_SMART_WAKEUP
-	ts->SMWP_enable=0;
-	wake_lock_init(&ts->ts_SMWP_wake_lock, WAKE_LOCK_SUSPEND, HIMAX_common_NAME);
+	ts->SMWP_enable = 0;
+	wakeup_source_init(&ts->ts_SMWP_wake_lock,
+	WAKE_LOCK_SUSPEND, HIMAX_common_NAME);
 
 	ts->himax_smwp_wq = create_singlethread_workqueue("HMX_SMWP_WORK");
 	if (!ts->himax_smwp_wq) {
@@ -1611,7 +1661,7 @@
 	INIT_DELAYED_WORK(&ts->smwp_work, himax_SMWP_work);
 #endif
 #ifdef HX_HIGH_SENSE
-	ts->HSEN_enable=0;
+	ts->HSEN_enable = 0;
 	ts->himax_hsen_wq = create_singlethread_workqueue("HMX_HSEN_WORK");
 	if (!ts->himax_hsen_wq) {
 		E(" allocate himax_hsen_wq failed\n");
@@ -1633,7 +1683,7 @@
 	err = himax_ts_register_interrupt(ts->client);
 	if (err)
 		goto err_register_interrupt_failed;
-	return;
+	return true;
 
 err_register_interrupt_failed:
 #ifdef HX_HIGH_SENSE
@@ -1641,26 +1691,26 @@
 #endif
 #ifdef HX_SMART_WAKEUP
 err_smwp_wq_failed:
-	wake_lock_destroy(&ts->ts_SMWP_wake_lock);
+	wakeup_source_trash(&ts->ts_SMWP_wake_lock);
 #endif
 err_input_register_device_failed:
 	input_free_device(ts->input_dev);
 err_detect_failed:
-#ifdef  HX_TP_PROC_FLASH_DUMP
+#ifdef HX_TP_PROC_FLASH_DUMP
 err_create_wq_failed:
 #endif
 err_ic_package_failed:
-
-return;
+return false;
 }
 
-int himax_chip_common_probe(struct i2c_client *client, const struct i2c_device_id *id)
+int himax_chip_common_probe(struct i2c_client *client,
+const struct i2c_device_id *id)
 {
 	int err = 0;
 	struct himax_ts_data *ts;
 	struct himax_i2c_platform_data *pdata;
 
-	//Check I2C functionality
+	/*Check I2C functionality*/
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
 		E("%s: i2c check functionality error\n", __func__);
 		err = -ENODEV;
@@ -1677,6 +1727,7 @@
 	i2c_set_clientdata(client, ts);
 	ts->client = client;
 	ts->dev = &client->dev;
+	mutex_init(&ts->rw_lock);
 
 	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
 	if (pdata == NULL) { /*Allocate Platform data space*/
@@ -1691,7 +1742,8 @@
 	}
 
 #ifdef CONFIG_OF
-	if (client->dev.of_node) { /*DeviceTree Init Platform_data*/
+	/*DeviceTree Init Platform_data*/
+	if (client->dev.of_node) {
 		err = himax_parse_dt(ts, pdata);
 		if (err < 0) {
 			I(" pdata is NULL for DT\n");
@@ -1704,12 +1756,11 @@
 	ts->rst_gpio = pdata->gpio_reset;
 #endif
 
-himax_gpio_power_config(ts->client, pdata);
+	himax_gpio_power_config(ts->client, pdata);
 
 	err = himax_ts_pinctrl_init(ts);
-	if (err || ts->ts_pinctrl == NULL) {
+	if (err || ts->ts_pinctrl == NULL)
 		E(" Pinctrl init failed\n");
-	}
 
 #ifndef CONFIG_OF
 	if (pdata->power) {
@@ -1736,7 +1787,7 @@
 	}
 #endif
 
-    return 0;
+	return 0;
 
 #ifdef CONFIG_FB
 err_fb_notif_wq_create:
@@ -1783,8 +1834,10 @@
 	himax_touch_proc_deinit();
 #endif
 #ifdef CONFIG_FB
-	if (fb_unregister_client(&ts->fb_notif))
-		dev_err(&client->dev, "Error occurred while unregistering fb_notifier.\n");
+	if (fb_unregister_client(&ts->fb_notif)) {
+		dev_err(&client->dev,
+		"Error occurred while unregistering fb_notifier.\n");
+	}
 #endif
 
 	if (!ts->use_irq)
@@ -1810,7 +1863,7 @@
 		}
 	}
 #ifdef HX_SMART_WAKEUP
-		wake_lock_destroy(&ts->ts_SMWP_wake_lock);
+		wakeup_source_trash(&ts->ts_SMWP_wake_lock);
 #endif
 	kfree(ts);
 
@@ -1822,38 +1875,36 @@
 {
 	int ret;
 
-	if(ts->suspended)
-	{
-		I("%s: Already suspended. Skipped. \n", __func__);
+	if (ts->suspended) {
+		I("%s: Already suspended. Skipped.\n", __func__);
 		return 0;
-	}
-	else
-	{
+
+	} else {
 		ts->suspended = true;
-		I("%s: enter \n", __func__);
+		I("%s: enter\n", __func__);
 	}
 
 #ifdef HX_TP_PROC_FLASH_DUMP
-	if (getFlashDumpGoing())
-	{
-		I("[himax] %s: Flash dump is going, reject suspend\n",__func__);
+	if (getFlashDumpGoing()) {
+		I("[himax] %s: Flash dump is going,reject suspend\n",
+		__func__);
 		return 0;
 	}
 #endif
 #ifdef HX_TP_PROC_HITOUCH
-	if(hitouch_is_connect)
-	{
-		I("[himax] %s: Hitouch connect, reject suspend\n",__func__);
+	if (hitouch_is_connect) {
+		I("[himax] %s: Hitouch connect,reject suspend\n",
+		__func__);
 		return 0;
 	}
 #endif
 #ifdef HX_SMART_WAKEUP
-	if(ts->SMWP_enable)
-	{
+	if (ts->SMWP_enable) {
 		atomic_set(&ts->suspend_mode, 1);
 		ts->pre_finger_mask = 0;
-		FAKE_POWER_KEY_SEND=false;
-		I("[himax] %s: SMART_WAKEUP enable, reject suspend\n",__func__);
+		FAKE_POWER_KEY_SEND = false;
+		I("[himax] %s: SMART_WAKEUP enable,reject suspend\n",
+		__func__);
 		return 0;
 	}
 #endif
@@ -1864,19 +1915,18 @@
 	if (!ts->use_irq) {
 		ret = cancel_work_sync(&ts->work);
 		if (ret)
-			himax_int_enable(ts->client->irq,1);
+			himax_int_enable(ts->client->irq, 1);
 	}
 
-	//ts->first_pressed = 0;
+	/*ts->first_pressed = 0;*/
 	atomic_set(&ts->suspend_mode, 1);
 	ts->pre_finger_mask = 0;
 
 	if (ts->ts_pinctrl) {
 		ret = pinctrl_select_state(ts->ts_pinctrl,
 				ts->pinctrl_state_suspend);
-		if (ret < 0) {
+		if (ret < 0)
 			E("Failed to get idle pinctrl state %d\n", ret);
-		}
 	}
 
 	if (ts->pdata->powerOff3V3 && ts->pdata->power)
@@ -1889,20 +1939,16 @@
 {
 	int retval;
 
-	I("%s: enter \n", __func__);
+	I("%s: enter\n", __func__);
 
 	if (ts->pdata->powerOff3V3 && ts->pdata->power)
 		ts->pdata->power(1);
-		
-		
-		/*************************************/
+
 		if (ts->protocol_type == PROTOCOL_TYPE_A)
-		input_mt_sync(ts->input_dev);
+			input_mt_sync(ts->input_dev);
 		input_report_key(ts->input_dev, BTN_TOUCH, 0);
 		input_sync(ts->input_dev);
-		/*************************************/
-		
-		
+
 	if (ts->ts_pinctrl) {
 		retval = pinctrl_select_state(ts->ts_pinctrl,
 				ts->pinctrl_state_active);
@@ -1914,7 +1960,7 @@
 
 	atomic_set(&ts->suspend_mode, 0);
 
-	himax_int_enable(ts->client->irq,1);
+	himax_int_enable(ts->client->irq, 1);
 
 	ts->suspended = false;
 #if defined(HX_USB_DETECT2)
@@ -1922,10 +1968,12 @@
 	himax_cable_detect_func();
 #endif
 #ifdef HX_SMART_WAKEUP
-	queue_delayed_work(ts->himax_smwp_wq, &ts->smwp_work, msecs_to_jiffies(1000));
+	queue_delayed_work(ts->himax_smwp_wq,
+	&ts->smwp_work, msecs_to_jiffies(1000));
 #endif
 #ifdef HX_HIGH_SENSE
-	queue_delayed_work(ts->himax_hsen_wq, &ts->hsen_work, msecs_to_jiffies(1000));
+	queue_delayed_work(ts->himax_hsen_wq,
+	&ts->hsen_work, msecs_to_jiffies(1000));
 #endif
 	return 0;
 err_pinctrl_select_resume:
diff --git a/drivers/input/touchscreen/hxchipset/himax_common.h b/drivers/input/touchscreen/hxchipset/himax_common.h
index 27ce9aa..c4e24ba 100644
--- a/drivers/input/touchscreen/hxchipset/himax_common.h
+++ b/drivers/input/touchscreen/hxchipset/himax_common.h
@@ -16,9 +16,13 @@
 #ifndef HIMAX_COMMON_H
 #define HIMAX_COMMON_H
 
+#include "himax_platform.h"
+
 #include <asm/segment.h>
-#include <asm/uaccess.h>
-#include <asm/atomic.h>
+/*#include <asm/uaccess.h>*/
+/*#include <asm/atomic.h>*/
+#include <linux/uaccess.h>
+#include <linux/atomic.h>
 
 #include <linux/delay.h>
 #include <linux/i2c.h>
@@ -36,7 +40,6 @@
 #include <linux/buffer_head.h>
 #include <linux/seq_file.h>
 #include <linux/proc_fs.h>
-#include "himax_platform.h"
 
 #if defined(CONFIG_FB)
 #include <linux/notifier.h>
@@ -48,7 +51,7 @@
 #ifdef CONFIG_OF
 #include <linux/of_gpio.h>
 #endif
-#define HIMAX_DRIVER_VER "0.2.4.0"
+#define HIMAX_DRIVER_VER "0.3.1.0"
 
 #define FLASH_DUMP_FILE "/data/user/Flash_Dump.bin"
 #define DIAG_COORDINATE_FILE "/sdcard/Coordinate_Dump.csv"
@@ -62,39 +65,39 @@
 #define HX_TP_PROC_SELF_TEST
 #define HX_TP_PROC_RESET
 #define HX_TP_PROC_SENSE_ON_OFF
-//#define HX_TP_PROC_2T2R
+/*#define HX_TP_PROC_2T2R*/
 
 int himax_touch_proc_init(void);
 void himax_touch_proc_deinit(void);
 #endif
 
-//===========Himax Option function=============
-//#define HX_RST_PIN_FUNC
-//#define HX_AUTO_UPDATE_FW
-//#define HX_HIGH_SENSE
-//#define HX_SMART_WAKEUP
-//#define HX_USB_DETECT
-//#define HX_ESD_WORKAROUND
-//#define HX_USB_DETECT2
+/*===========Himax Option function=============*/
+/*#define HX_RST_PIN_FUNC*/
+#define HX_AUTO_UPDATE_FW
+/*#define HX_HIGH_SENSE*/
+/*#define HX_SMART_WAKEUP*/
+/*#define HX_USB_DETECT*/
+/*#define HX_ESD_WORKAROUND*/
+/*#define HX_USB_DETECT2*/
+/*#define HX_EN_SEL_BUTTON*//* Support Self Virtual key ,default is close*/
+#define HX_EN_MUT_BUTTON/*  Support Mutual Virtual Key ,default is close*/
+/*#define HX_EN_CHECK_PATCH*/
 
-//#define HX_EN_SEL_BUTTON		       // Support Self Virtual key		,default is close
-#define HX_EN_MUT_BUTTON		    // Support Mutual Virtual Key	,default is close
+#define HX_KEY_MAX_COUNT  4
+#define DEFAULT_RETRY_CNT 3
 
-#define HX_KEY_MAX_COUNT             4			
-#define DEFAULT_RETRY_CNT            3
-
-#define HX_VKEY_0   KEY_BACK
-#define HX_VKEY_1   KEY_HOME
-#define HX_VKEY_2   KEY_RESERVED
-#define HX_VKEY_3   KEY_RESERVED
-#define HX_KEY_ARRAY    {HX_VKEY_0, HX_VKEY_1, HX_VKEY_2, HX_VKEY_3}
+#define HX_VKEY_0 KEY_BACK
+#define HX_VKEY_1 KEY_HOME
+#define HX_VKEY_2 KEY_RESERVED
+#define HX_VKEY_3 KEY_RESERVED
+#define HX_KEY_ARRAY {HX_VKEY_0, HX_VKEY_1, HX_VKEY_2, HX_VKEY_3}
 
 #define SHIFTBITS 5
-//#define FLASH_SIZE 131072
-#define  FW_SIZE_60k 	61440
-#define  FW_SIZE_64k 	65536
-#define  FW_SIZE_124k 	126976
-#define  FW_SIZE_128k 	131072
+/*#define FLASH_SIZE 131072*/
+#define  FW_SIZE_60k  61440
+#define  FW_SIZE_64k  65536
+#define  FW_SIZE_124k 126976
+#define  FW_SIZE_128k 131072
 
 struct himax_ic_data {
 	int vendor_fw_ver;
@@ -183,12 +186,12 @@
 	bool suspended;
 	bool probe_done;
 	struct mutex fb_mutex;
+	struct mutex rw_lock;
 	atomic_t suspend_mode;
 	uint8_t x_channel;
 	uint8_t y_channel;
 	uint8_t useScreenRes;
 	uint8_t diag_command;
-	
 	uint8_t protocol_type;
 	uint8_t first_pressed;
 	uint8_t coord_data_size;
@@ -198,11 +201,9 @@
 	uint8_t nFinger_support;
 	uint8_t irq_enabled;
 	uint8_t diag_self[50];
-	
 	uint16_t finger_pressed;
 	uint16_t last_slot;
 	uint16_t pre_finger_mask;
-
 	uint32_t debug_log_level;
 	uint32_t widthFactor;
 	uint32_t heightFactor;
@@ -214,20 +215,20 @@
 	uint32_t pl_x_max;
 	uint32_t pl_y_min;
 	uint32_t pl_y_max;
-	
+
 	int use_irq;
 	int (*power)(int on);
 	int pre_finger_data[10][2];
-	
+
 	struct device *dev;
 	struct workqueue_struct *himax_wq;
 	struct work_struct work;
 	struct input_dev *input_dev;
 	struct hrtimer timer;
 	struct i2c_client *client;
-	struct himax_i2c_platform_data *pdata;	
+	struct himax_i2c_platform_data *pdata;
 	struct himax_virtual_key *button;
-	
+
 #if defined(CONFIG_FB)
 	struct notifier_block fb_notif;
 #elif defined(CONFIG_HAS_EARLYSUSPEND)
@@ -235,8 +236,8 @@
 #endif
 
 #ifdef HX_TP_PROC_FLASH_DUMP
-	struct workqueue_struct 			*flash_wq;
-	struct work_struct 					flash_work;
+	struct workqueue_struct *flash_wq;
+	struct work_struct flash_work;
 #endif
 
 #ifdef HX_RST_PIN_FUNC
@@ -250,7 +251,7 @@
 #ifdef HX_SMART_WAKEUP
 	uint8_t SMWP_enable;
 	uint8_t gesture_cust_en[16];
-	struct wake_lock ts_SMWP_wake_lock;
+	struct wakeup_source ts_SMWP_wake_lock;
 	struct workqueue_struct *himax_smwp_wq;
 	struct delayed_work smwp_work;
 #endif
@@ -261,7 +262,7 @@
 	struct delayed_work hsen_work;
 #endif
 
-#if defined(HX_USB_DETECT)||defined(HX_USB_DETECT2)
+#if defined(HX_USB_DETECT) || defined(HX_USB_DETECT2)
 	uint8_t usb_connected;
 	uint8_t *cable_config;
 #endif
@@ -273,30 +274,30 @@
 	struct pinctrl_state *pinctrl_state_release;
 };
 
-#define HX_CMD_NOP					 0x00	
-#define HX_CMD_SETMICROOFF			 0x35	
-#define HX_CMD_SETROMRDY			 0x36	
-#define HX_CMD_TSSLPIN				 0x80	
-#define HX_CMD_TSSLPOUT 			 0x81	
-#define HX_CMD_TSSOFF				 0x82	
-#define HX_CMD_TSSON				 0x83	
-#define HX_CMD_ROE					 0x85	
-#define HX_CMD_RAE					 0x86	
-#define HX_CMD_RLE					 0x87	
-#define HX_CMD_CLRES				 0x88	
-#define HX_CMD_TSSWRESET			 0x9E	
-#define HX_CMD_SETDEEPSTB			 0xD7	
-#define HX_CMD_SET_CACHE_FUN		 0xDD	
-#define HX_CMD_SETIDLE				 0xF2	
-#define HX_CMD_SETIDLEDELAY 		 0xF3	
-#define HX_CMD_SELFTEST_BUFFER		 0x8D	
+#define HX_CMD_NOP					 0x00
+#define HX_CMD_SETMICROOFF			 0x35
+#define HX_CMD_SETROMRDY			 0x36
+#define HX_CMD_TSSLPIN				 0x80
+#define HX_CMD_TSSLPOUT				 0x81
+#define HX_CMD_TSSOFF				 0x82
+#define HX_CMD_TSSON				 0x83
+#define HX_CMD_ROE					 0x85
+#define HX_CMD_RAE					 0x86
+#define HX_CMD_RLE					 0x87
+#define HX_CMD_CLRES				 0x88
+#define HX_CMD_TSSWRESET			 0x9E
+#define HX_CMD_SETDEEPSTB			 0xD7
+#define HX_CMD_SET_CACHE_FUN		 0xDD
+#define HX_CMD_SETIDLE				 0xF2
+#define HX_CMD_SETIDLEDELAY			 0xF3
+#define HX_CMD_SELFTEST_BUFFER		 0x8D
 #define HX_CMD_MANUALMODE			 0x42
-#define HX_CMD_FLASH_ENABLE 		 0x43
+#define HX_CMD_FLASH_ENABLE			 0x43
 #define HX_CMD_FLASH_SET_ADDRESS	 0x44
 #define HX_CMD_FLASH_WRITE_REGISTER  0x45
 #define HX_CMD_FLASH_SET_COMMAND	 0x47
 #define HX_CMD_FLASH_WRITE_BUFFER	 0x48
-#define HX_CMD_FLASH_PAGE_ERASE 	 0x4D
+#define HX_CMD_FLASH_PAGE_ERASE		 0x4D
 #define HX_CMD_FLASH_SECTOR_ERASE	 0x4E
 #define HX_CMD_CB					 0xCB
 #define HX_CMD_EA					 0xEA
@@ -311,7 +312,7 @@
 };
 
 #ifdef HX_HIGH_SENSE
-void himax_set_HSEN_func(struct i2c_client *client,uint8_t HSEN_enable);
+void himax_set_HSEN_func(struct i2c_client *client, uint8_t HSEN_enable);
 #endif
 
 #ifdef HX_SMART_WAKEUP
@@ -319,18 +320,18 @@
 #define GEST_PTLG_HDR_LEN	(4)
 #define GEST_PTLG_HDR_ID1	(0xCC)
 #define GEST_PTLG_HDR_ID2	(0x44)
-#define GEST_PT_MAX_NUM 	(128)
+#define GEST_PT_MAX_NUM		(128)
 
 #ifdef HX_GESTURE_TRACK
 static int gest_pt_cnt;
 static int gest_pt_x[GEST_PT_MAX_NUM];
 static int gest_pt_y[GEST_PT_MAX_NUM];
-static int gest_start_x,gest_start_y,gest_end_x,gest_end_y;
-static int gest_width,gest_height,gest_mid_x,gest_mid_y;
+static int gest_start_x, gest_start_y, gest_end_x, gest_end_y;
+static int gest_width, gest_height, gest_mid_x, gest_mid_y;
 static int gn_gesture_coor[16];
 #endif
 
-void himax_set_SMWP_func(struct i2c_client *client,uint8_t SMWP_enable);
+void himax_set_SMWP_func(struct i2c_client *client, uint8_t SMWP_enable);
 extern bool FAKE_POWER_KEY_SEND;
 
 	enum gesture_event_type {
@@ -380,16 +381,91 @@
 int himax_input_register(struct himax_ts_data *ts);
 #endif
 
-extern int himax_chip_common_probe(struct i2c_client *client, const struct i2c_device_id *id);
-extern int himax_chip_common_remove(struct i2c_client *client);
-extern int himax_chip_common_suspend(struct himax_ts_data *ts);
-extern int himax_chip_common_resume(struct himax_ts_data *ts);
-int himax_loadSensorConfig(struct i2c_client *client, struct himax_i2c_platform_data *pdata);
+int himax_chip_common_probe(struct i2c_client *client,
+const struct i2c_device_id *id);
+int himax_chip_common_remove(struct i2c_client *client);
+int himax_chip_common_suspend(struct himax_ts_data *ts);
+int himax_chip_common_resume(struct himax_ts_data *ts);
+int himax_loadSensorConfig(struct i2c_client *client,
+struct himax_i2c_platform_data *pdata);
 
 #ifdef HX_USB_DETECT2
-//extern kal_bool upmu_is_chr_det(void);
+/*extern kal_bool upmu_is_chr_det(void);*/
 void himax_cable_detect_func(void);
 #endif
 
+#ifdef HX_AUTO_UPDATE_FW
+extern unsigned long	FW_VER_MAJ_FLASH_ADDR;
+extern unsigned long	FW_VER_MIN_FLASH_ADDR;
+extern unsigned long	CFG_VER_MAJ_FLASH_ADDR;
+extern unsigned long	CFG_VER_MIN_FLASH_ADDR;
+#endif
+extern unsigned long	FW_VER_MAJ_FLASH_LENG;
+extern unsigned long	FW_VER_MIN_FLASH_LENG;
+extern unsigned long	CFG_VER_MAJ_FLASH_LENG;
+extern unsigned long	CFG_VER_MIN_FLASH_LENG;
+extern unsigned char	IC_TYPE;
+extern unsigned char	IC_CHECKSUM;
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+extern int himax_touch_proc_init(void);
+extern void himax_touch_proc_deinit(void);
+/*PROC-START*/
+#ifdef HX_TP_PROC_FLASH_DUMP
+extern void	himax_ts_flash_func(void);
+extern void setFlashBuffer(void);
+extern bool getFlashDumpGoing(void);
+extern uint8_t getSysOperation(void);
+extern void setSysOperation(uint8_t operation);
+#endif
+
+#ifdef HX_TP_PROC_HITOUCH
+extern bool hitouch_is_connect;
+#endif
+
+#ifdef HX_TP_PROC_DIAG
+	extern int touch_monitor_stop_flag;
+
+	extern int touch_monitor_stop_limit;
+
+	extern void	himax_ts_diag_func(void);
+
+	extern int16_t *getMutualBuffer(void);
+	extern int16_t *getMutualNewBuffer(void);
+	extern int16_t *getMutualOldBuffer(void);
+	extern int16_t *getSelfBuffer(void);
+	extern uint8_t getXChannel(void);
+	extern uint8_t getYChannel(void);
+	extern uint8_t getDiagCommand(void);
+	extern void setXChannel(uint8_t x);
+	extern void setYChannel(uint8_t y);
+	extern void setMutualBuffer(void);
+	extern void setMutualNewBuffer(void);
+	extern void setMutualOldBuffer(void);
+	extern uint8_t coordinate_dump_enable;
+	extern struct file *coordinate_fn;
+	extern uint8_t diag_coor[128];
+#ifdef HX_TP_PROC_2T2R
+	extern int16_t *getMutualBuffer_2(void);
+	extern uint8_t getXChannel_2(void);
+	extern uint8_t getYChannel_2(void);
+	extern void setXChannel_2(uint8_t x);
+	extern void setYChannel_2(uint8_t y);
+	extern void setMutualBuffer_2(void);
+#endif
+#endif
+/*PROC-END*/
+#endif
+
+#ifdef HX_USB_DETECT2
+	extern bool USB_Flag;
+#endif
+#ifdef HX_ESD_WORKAROUND
+	extern void HX_report_ESD_event(void);
+	unsigned char ESD_00_counter = 0;
+	unsigned char ESD_00_Flag = 0;
+#endif
+bool himax_ts_init(struct himax_ts_data *ts);
+
 #endif
 
diff --git a/drivers/input/touchscreen/hxchipset/himax_debug.c b/drivers/input/touchscreen/hxchipset/himax_debug.c
index f8bee11..a5bdbf2 100644
--- a/drivers/input/touchscreen/hxchipset/himax_debug.c
+++ b/drivers/input/touchscreen/hxchipset/himax_debug.c
@@ -16,32 +16,16 @@
 #include "himax_debug.h"
 #include "himax_ic.h"
 
-//struct himax_debug_data* debug_data;
-
-extern struct himax_ic_data* ic_data;
-extern struct himax_ts_data *private_ts;
-extern unsigned char	IC_TYPE;
-extern unsigned char	IC_CHECKSUM;
-extern int himax_input_register(struct himax_ts_data *ts);
-#ifdef QCT
-extern irqreturn_t himax_ts_thread(int irq, void *ptr);
-#endif
-#ifdef MTK
-#ifdef CONFIG_OF_TOUCH
-extern irqreturn_t tpd_eint_interrupt_handler(int irq, void *desc);
-#else
-extern void tpd_eint_interrupt_handler(void);
-#endif
-#endif
+/*struct himax_debug_data* debug_data;*/
 
 #ifdef HX_TP_PROC_DIAG
 #ifdef HX_TP_PROC_2T2R
-int	HX_RX_NUM_2			= 0;
-int	HX_TX_NUM_2			= 0;
+int	HX_RX_NUM_2;
+int	HX_TX_NUM_2;
 #endif
-int	touch_monitor_stop_flag		= 0;
+int	touch_monitor_stop_flag;
 int	touch_monitor_stop_limit	= 5;
-uint8_t	g_diag_arr_num			= 0;
+uint8_t	g_diag_arr_num;
 #endif
 
 #ifdef HX_ESD_WORKAROUND
@@ -52,11 +36,11 @@
 bool FAKE_POWER_KEY_SEND;
 #endif
 
-//=============================================================================================================
-//
-//	Segment : Himax PROC Debug Function
-//
-//=============================================================================================================
+/*========================================================
+
+Segment : Himax PROC Debug Function
+
+==========================================================*/
 #if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
 
 static ssize_t himax_vendor_read(struct file *file, char *buf,
@@ -65,33 +49,26 @@
 	ssize_t ret = 0;
 	char *temp_buf;
 
-	if(!HX_PROC_SEND_FLAG)
-	{
+	if (!HX_PROC_SEND_FLAG) {
 		temp_buf = kzalloc(len, GFP_KERNEL);
-		if (!temp_buf) {
-			HX_PROC_SEND_FLAG=0;
-			return ret;
-		}
+		ret += snprintf(temp_buf, len,
+		"%s_FW:%#x_CFG:%#x_SensorId:%#x\n",
+		HIMAX_common_NAME, ic_data->vendor_fw_ver,
+		ic_data->vendor_config_ver, ic_data->vendor_sensor_id);
 
-		ret += snprintf(temp_buf, len, "%s_FW:%#x_CFG:%#x_SensorId:%#x\n", HIMAX_common_NAME,
-		ic_data->vendor_fw_ver, ic_data->vendor_config_ver, ic_data->vendor_sensor_id);
-		HX_PROC_SEND_FLAG=1;
+		HX_PROC_SEND_FLAG = 1;
 
 		if (copy_to_user(buf, temp_buf, len))
-		{
 			I("%s,here:%d\n", __func__, __LINE__);
-		}
 
 		kfree(temp_buf);
-	}
-	else
-		HX_PROC_SEND_FLAG=0;
+	} else
+		HX_PROC_SEND_FLAG = 0;
 
 	return ret;
 }
 
-static const struct file_operations himax_proc_vendor_ops =
-{
+const struct file_operations himax_proc_vendor_ops = {
 	.owner = THIS_MODULE,
 	.read = himax_vendor_read,
 };
@@ -107,29 +84,21 @@
 
 	if (!HX_PROC_SEND_FLAG) {
 		temp_buf = kzalloc(len, GFP_KERNEL);
-		if (!temp_buf) {
-			HX_PROC_SEND_FLAG=0;
-			return ret;
-		}
-		ret += snprintf(temp_buf, len, "attn = %x\n", himax_int_gpio_read(ts_data->pdata->gpio_irq));
+		ret += snprintf(temp_buf, len, "attn = %x\n",
+		himax_int_gpio_read(ts_data->pdata->gpio_irq));
 
 		if (copy_to_user(buf, temp_buf, len))
-		{
 			I("%s,here:%d\n", __func__, __LINE__);
-		}
 
 		kfree(temp_buf);
 		HX_PROC_SEND_FLAG = 1;
-	}
-	else
-		HX_PROC_SEND_FLAG=0;
+	} else
+		HX_PROC_SEND_FLAG = 0;
 
 	return ret;
 }
 
-
-static const struct file_operations himax_proc_attn_ops =
-{
+const struct file_operations himax_proc_attn_ops = {
 	.owner = THIS_MODULE,
 	.read = himax_attn_read,
 };
@@ -143,23 +112,16 @@
 
 	if (!HX_PROC_SEND_FLAG) {
 		temp_buf = kzalloc(len, GFP_KERNEL);
-		if (!temp_buf) {
-			HX_PROC_SEND_FLAG=0;
-			return ret;
-		}
-		ret += snprintf(temp_buf, len, "%d ", ts->irq_enabled);
-		ret += snprintf(temp_buf+ret, len-ret, "\n");
+		ret += snprintf(temp_buf, len-1, "%d ", ts->irq_enabled);
+		ret += snprintf(temp_buf, 1, "\n");
 
 		if (copy_to_user(buf, temp_buf, len))
-		{
 			I("%s,here:%d\n", __func__, __LINE__);
-		}
 
 		kfree(temp_buf);
 		HX_PROC_SEND_FLAG = 1;
-	}
-	else
-		HX_PROC_SEND_FLAG=0;
+	} else
+		HX_PROC_SEND_FLAG = 0;
 	return ret;
 }
 
@@ -167,18 +129,15 @@
 	size_t len, loff_t *pos)
 {
 	struct himax_ts_data *ts = private_ts;
-	char buf_tmp[12]= {0};
-	int value, ret=0;
+	char buf_tmp[12] = {0};
+	int value, ret = 0;
 
-	if (len >= 12)
-	{
+	if (len >= 12) {
 		I("%s: no command exceeds 12 chars.\n", __func__);
 		return -EFAULT;
 	}
 	if (copy_from_user(buf_tmp, buff, len))
-	{
 		return -EFAULT;
-	}
 
 	if (buf_tmp[0] == '0')
 		value = false;
@@ -188,36 +147,43 @@
 		return -EINVAL;
 
 	if (value) {
-		if(ic_data->HX_INT_IS_EDGE)
-		{
+		if (ic_data->HX_INT_IS_EDGE) {
 #ifdef MTK
 #ifdef CONFIG_OF_TOUCH
-			himax_int_enable(ts->client->irq,1);
+			himax_int_enable(ts->client->irq, 1);
 #else
-			//mt_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_TYPE);
-			//mt_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN);
-			mt_eint_registration(ts->client->irq, EINTF_TRIGGER_FALLING, tpd_eint_interrupt_handler, 1);
+			/*mt_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM,
+			CUST_EINT_TOUCH_PANEL_TYPE);
+			mt_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM,
+			CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN);*/
+			mt_eint_registration(ts->client->irq,
+			EINTF_TRIGGER_FALLING, tpd_eint_interrupt_handler, 1);
 #endif
 #endif
 #ifdef QCT
-			ret = request_threaded_irq(ts->client->irq, NULL, himax_ts_thread,
-					IRQF_TRIGGER_FALLING | IRQF_ONESHOT, ts->client->name, ts);
+			ret = request_threaded_irq(ts->client->irq,
+					NULL, himax_ts_thread,
+					IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+					ts->client->name, ts);
 #endif
-		}
-		else
-		{
+		} else {
 #ifdef MTK
 #ifdef CONFIG_OF_TOUCH
-			himax_int_enable(ts->client->irq,1);
+			himax_int_enable(ts->client->irq, 1);
 #else
-			//mt_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_TYPE);
-			//mt_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN);
-			mt_eint_registration(ts->client->irq, EINTF_TRIGGER_LOW, tpd_eint_interrupt_handler, 1);
+			/*mt_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM,
+			CUST_EINT_TOUCH_PANEL_TYPE);
+			mt_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM,
+			CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN);*/
+			mt_eint_registration(ts->client->irq,
+			EINTF_TRIGGER_LOW, tpd_eint_interrupt_handler, 1);
 #endif
 #endif
 #ifdef QCT
-			ret = request_threaded_irq(ts->client->irq, NULL, himax_ts_thread,
-					IRQF_TRIGGER_LOW | IRQF_ONESHOT, ts->client->name, ts);
+			ret = request_threaded_irq(ts->client->irq,
+					NULL, himax_ts_thread,
+					IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					ts->client->name, ts);
 #endif
 		}
 		if (ret == 0) {
@@ -225,7 +191,7 @@
 			irq_enable_count = 1;
 		}
 	} else {
-		himax_int_enable(ts->client->irq,0);
+		himax_int_enable(ts->client->irq, 0);
 		free_irq(ts->client->irq, ts);
 		ts->irq_enabled = 0;
 	}
@@ -233,8 +199,7 @@
 	return len;
 }
 
-static const struct file_operations himax_proc_int_en_ops =
-{
+const struct file_operations himax_proc_int_en_ops = {
 	.owner = THIS_MODULE,
 	.read = himax_int_en_read,
 	.write = himax_int_en_write,
@@ -249,26 +214,19 @@
 
 	if (!HX_PROC_SEND_FLAG) {
 		temp_buf = kzalloc(len, GFP_KERNEL);
-		if (!temp_buf) {
-			HX_PROC_SEND_FLAG=0;
-			return ret;
-		}
-		ret += snprintf(temp_buf, len,  "%d ", ts->pdata->abs_x_min);
-		ret += snprintf(temp_buf+ret, len-ret, "%d ", ts->pdata->abs_x_max);
-		ret += snprintf(temp_buf+ret, len-ret, "%d ", ts->pdata->abs_y_min);
-		ret += snprintf(temp_buf+ret, len-ret, "%d ", ts->pdata->abs_y_max);
-		ret += snprintf(temp_buf+ret, len-ret, "\n");
+		ret += snprintf(temp_buf, len, "%d ", ts->pdata->abs_x_min);
+		ret += snprintf(temp_buf, len, "%d ", ts->pdata->abs_x_max);
+		ret += snprintf(temp_buf, len, "%d ", ts->pdata->abs_y_min);
+		ret += snprintf(temp_buf, len, "%d ", ts->pdata->abs_y_max);
+		ret += snprintf(temp_buf, len, "\n");
 
 		if (copy_to_user(buf, temp_buf, len))
-		{
 			I("%s,here:%d\n", __func__, __LINE__);
-		}
 
 		kfree(temp_buf);
 		HX_PROC_SEND_FLAG = 1;
-	}
-	else
-		HX_PROC_SEND_FLAG=0;
+	} else
+		HX_PROC_SEND_FLAG = 0;
 
 	return ret;
 }
@@ -283,17 +241,14 @@
 	int layout[4] = {0};
 	char buf[80] = {0};
 
-	if (len >= 80)
-	{
+	if (len >= 80) {
 		I("%s: no command exceeds 80 chars.\n", __func__);
 		return -EFAULT;
 	}
 	if (copy_from_user(buf, buff, len))
-	{
 		return -EFAULT;
-	}
 
-	for (i = 0; i < 20; i++) {
+	for (i = 0 ; i < 20 ; i++) {
 		if (buf[i] == ',' || buf[i] == '\n') {
 			memset(buf_tmp, 0x0, sizeof(buf_tmp));
 			if (i - j <= 5)
@@ -310,20 +265,24 @@
 		}
 	}
 	if (k == 4) {
-		ts->pdata->abs_x_min=layout[0];
-		ts->pdata->abs_x_max=layout[1];
-		ts->pdata->abs_y_min=layout[2];
-		ts->pdata->abs_y_max=layout[3];
-		I("%d, %d, %d, %d\n",ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max);
+		ts->pdata->abs_x_min = layout[0];
+		ts->pdata->abs_x_max = layout[1];
+		ts->pdata->abs_y_min = layout[2];
+		ts->pdata->abs_y_max = layout[3];
+		I("%d, %d, %d, %d\n", ts->pdata->abs_x_min,
+		ts->pdata->abs_x_max, ts->pdata->abs_y_min,
+		ts->pdata->abs_y_max);
 		input_unregister_device(ts->input_dev);
 		himax_input_register(ts);
-	} else
-		I("ERR@%d, %d, %d, %d\n",ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max);
+	} else {
+		I("ERR@%d, %d, %d, %d\n", ts->pdata->abs_x_min,
+		ts->pdata->abs_x_max, ts->pdata->abs_y_min,
+		ts->pdata->abs_y_max);
+	}
 	return len;
 }
 
-static const struct file_operations himax_proc_layout_ops =
-{
+const struct file_operations himax_proc_layout_ops = {
 	.owner = THIS_MODULE,
 	.read = himax_layout_read,
 	.write = himax_layout_write,
@@ -335,26 +294,21 @@
 	struct himax_ts_data *ts_data;
 	size_t ret = 0;
 	char *temp_buf;
+
 	ts_data = private_ts;
 
 	if (!HX_PROC_SEND_FLAG) {
 		temp_buf = kzalloc(len, GFP_KERNEL);
-		if (!temp_buf) {
-			HX_PROC_SEND_FLAG=0;
-			return ret;
-		}
-		ret += snprintf(temp_buf, len, "%d\n", ts_data->debug_log_level);
+		ret += snprintf(temp_buf, len, "%d\n",
+		ts_data->debug_log_level);
 
 		if (copy_to_user(buf, temp_buf, len))
-		{
 			I("%s,here:%d\n", __func__, __LINE__);
-		}
 
 		kfree(temp_buf);
 		HX_PROC_SEND_FLAG = 1;
-	}
-	else
-		HX_PROC_SEND_FLAG=0;
+	} else
+		HX_PROC_SEND_FLAG = 0;
 
 	return ret;
 }
@@ -365,29 +319,26 @@
 	struct himax_ts_data *ts;
 	char buf_tmp[11];
 	int i;
+
 	ts = private_ts;
 
-	if (len >= 12)
-	{
+	if (len >= 12) {
 		I("%s: no command exceeds 12 chars.\n", __func__);
 		return -EFAULT;
 	}
 	if (copy_from_user(buf_tmp, buff, len))
-	{
 		return -EFAULT;
-	}
 
 	ts->debug_log_level = 0;
-	for(i=0; i<len-1; i++)
-	{
-		if( buf_tmp[i]>='0' && buf_tmp[i]<='9' )
-			ts->debug_log_level |= (buf_tmp[i]-'0');
-		else if( buf_tmp[i]>='A' && buf_tmp[i]<='F' )
-			ts->debug_log_level |= (buf_tmp[i]-'A'+10);
-		else if( buf_tmp[i]>='a' && buf_tmp[i]<='f' )
-			ts->debug_log_level |= (buf_tmp[i]-'a'+10);
+	for (i = 0 ; i < len - 1 ; i++) {
+		if (buf_tmp[i] >= '0' && buf_tmp[i] <= '9')
+			ts->debug_log_level |= (buf_tmp[i] - '0');
+		else if (buf_tmp[i] >= 'A' && buf_tmp[i] <= 'F')
+			ts->debug_log_level |= (buf_tmp[i]-'A' + 10);
+		else if (buf_tmp[i] >= 'a' && buf_tmp[i] <= 'f')
+			ts->debug_log_level |= (buf_tmp[i] - 'a' + 10);
 
-		if(i!=len-2)
+		if (i != len - 2)
 			ts->debug_log_level <<= 4;
 	}
 
@@ -395,8 +346,12 @@
 		if (ts->pdata->screenWidth > 0 && ts->pdata->screenHeight > 0 &&
 		 (ts->pdata->abs_x_max - ts->pdata->abs_x_min) > 0 &&
 		 (ts->pdata->abs_y_max - ts->pdata->abs_y_min) > 0) {
-			ts->widthFactor = (ts->pdata->screenWidth << SHIFTBITS)/(ts->pdata->abs_x_max - ts->pdata->abs_x_min);
-			ts->heightFactor = (ts->pdata->screenHeight << SHIFTBITS)/(ts->pdata->abs_y_max - ts->pdata->abs_y_min);
+			ts->widthFactor =
+			(ts->pdata->screenWidth << SHIFTBITS)
+			/ (ts->pdata->abs_x_max - ts->pdata->abs_x_min);
+			ts->heightFactor =
+			(ts->pdata->screenHeight << SHIFTBITS)
+			/ (ts->pdata->abs_y_max - ts->pdata->abs_y_min);
 			if (ts->widthFactor > 0 && ts->heightFactor > 0)
 				ts->useScreenRes = 1;
 			else {
@@ -415,8 +370,7 @@
 	return len;
 }
 
-static const struct file_operations himax_proc_debug_level_ops =
-{
+const struct file_operations himax_proc_debug_level_ops = {
 	.owner = THIS_MODULE,
 	.read = himax_debug_level_read,
 	.write = himax_debug_level_write,
@@ -433,35 +387,33 @@
 
 	memset(data, 0x00, sizeof(data));
 
-	I("himax_register_show: %x,%x,%x,%x\n", register_command[0],register_command[1],register_command[2],register_command[3]);
-	if(!HX_PROC_SEND_FLAG)
-	{
+	I("himax_register_show: %x,%x,%x,%x\n", register_command[0],
+	register_command[1], register_command[2], register_command[3]);
+
+	if (!HX_PROC_SEND_FLAG) {
 		temp_buf = kzalloc(len, GFP_KERNEL);
-		if (!temp_buf) {
-			HX_PROC_SEND_FLAG=0;
-			return ret;
-		}
-		himax_register_read(private_ts->client, register_command, 1, data);
+		himax_register_read(private_ts->client,
+		register_command, 1, data);
 
-		ret += snprintf(temp_buf, len, "command:  %x,%x,%x,%x\n", register_command[0],register_command[1],register_command[2],register_command[3]);
+		ret += snprintf(temp_buf, len, "command: %x,%x,%x,%x\n",
+		register_command[0], register_command[1],
+		register_command[2], register_command[3]);
 
-		for (loop_i = 0; loop_i < 128; loop_i++) {
-			ret += snprintf(temp_buf+ret, len-ret, "0x%2.2X ", data[loop_i]);
+		for (loop_i = 0 ; loop_i < 128 ; loop_i++) {
+			ret += snprintf(temp_buf + ret,
+			sizeof(data[loop_i]), "0x%2.2X ", data[loop_i]);
 			if ((loop_i % 16) == 15)
-				ret += snprintf(temp_buf+ret, len-ret, "\n");
+				ret += snprintf(temp_buf + ret, 1, "\n");
 		}
-		ret += snprintf(temp_buf+ret, len-ret, "\n");
-		HX_PROC_SEND_FLAG=1;
+		ret += snprintf(temp_buf + ret, len, "\n");
+		HX_PROC_SEND_FLAG = 1;
 
 		if (copy_to_user(buf, temp_buf, len))
-		{
 			I("%s,here:%d\n", __func__, __LINE__);
-		}
 
 		kfree(temp_buf);
-	}
-	else
-		HX_PROC_SEND_FLAG=0;
+	} else
+		HX_PROC_SEND_FLAG = 0;
 	return ret;
 }
 
@@ -475,40 +427,48 @@
 	uint8_t write_da[128];
 	char buf[80] = {0};
 
-	if (len >= 80)
-	{
+	if (len >= 80) {
 		I("%s: no command exceeds 80 chars.\n", __func__);
 		return -EFAULT;
 	}
 	if (copy_from_user(buf, buff, len))
-	{
 		return -EFAULT;
-	}
 
 	memset(buf_tmp, 0x0, sizeof(buf_tmp));
 	memset(write_da, 0x0, sizeof(write_da));
 
-	I("himax %s \n",buf);
+	I("himax %s\n", buf);
 
 	if ((buf[0] == 'r' || buf[0] == 'w') && buf[1] == ':') {
 
 		if (buf[2] == 'x') {
 			memcpy(buf_tmp, buf + 3, 8);
-			if (!kstrtoul(buf_tmp, 16, &result))
-				{
-					register_command[0] = (uint8_t)result;
-					register_command[1] = (uint8_t)(result >> 8);
-					register_command[2] = (uint8_t)(result >> 16);
-					register_command[3] = (uint8_t)(result >> 24);
-				}
+			if (!kstrtoul(buf_tmp, 16, &result)) {
+					register_command[0] =
+					(uint8_t)result;
+					register_command[1] =
+					(uint8_t)(result >> 8);
+					register_command[2] =
+					(uint8_t)(result >> 16);
+					register_command[3] =
+					(uint8_t)(result >> 24);
+			}
 			base = 11;
-			I("CMD: %x,%x,%x,%x\n", register_command[0],register_command[1],register_command[2],register_command[3]);
+			I("CMD: %x,%x,%x,%x\n", register_command[0],
+			register_command[1], register_command[2],
+			register_command[3]);
 
-			for (loop_i = 0; loop_i < 128 && (base+10)<80; loop_i++) {
+			for (loop_i = 0 ; loop_i < 128 ; loop_i++) {
 				if (buf[base] == '\n') {
 					if (buf[0] == 'w') {
-						himax_register_write(private_ts->client, register_command, 1, write_da);
-						I("CMD: %x, %x, %x, %x, len=%d\n", write_da[0], write_da[1],write_da[2],write_da[3],length);
+						himax_register_write
+						(private_ts->client,
+						register_command
+						, 1, write_da);
+						I("CMD:%x, %x, %x, %x,len=%d\n",
+						write_da[0], write_da[1],
+						write_da[2], write_da[3],
+						length);
 					}
 					I("\n");
 					return len;
@@ -518,12 +478,16 @@
 					buf_tmp[11] = '\0';
 					memcpy(buf_tmp, buf + base + 2, 8);
 					if (!kstrtoul(buf_tmp, 16, &result)) {
-						write_da[loop_i] = (uint8_t)result;
-						write_da[loop_i+1] = (uint8_t)(result >> 8);
-						write_da[loop_i+2] = (uint8_t)(result >> 16);
-						write_da[loop_i+3] = (uint8_t)(result >> 24);
+						write_da[loop_i] =
+						(uint8_t)result;
+						write_da[loop_i+1] =
+						(uint8_t)(result >> 8);
+						write_da[loop_i+2] =
+						(uint8_t)(result >> 16);
+						write_da[loop_i+3] =
+						(uint8_t)(result >> 24);
 					}
-					length+=4;
+					length += 4;
 				}
 				base += 10;
 			}
@@ -532,8 +496,7 @@
 	return len;
 }
 
-static const struct file_operations himax_proc_register_ops =
-{
+const struct file_operations himax_proc_register_ops = {
 	.owner = THIS_MODULE,
 	.read = himax_proc_register_read,
 	.write = himax_proc_register_write,
@@ -579,15 +542,18 @@
 }
 void setMutualBuffer(void)
 {
-	diag_mutual = kzalloc(x_channel * y_channel * sizeof(int16_t), GFP_KERNEL);
+	diag_mutual = kzalloc
+	(x_channel * y_channel * sizeof(int16_t), GFP_KERNEL);
 }
 void setMutualNewBuffer(void)
 {
-	diag_mutual_new = kzalloc(x_channel * y_channel * sizeof(int16_t), GFP_KERNEL);
+	diag_mutual_new = kzalloc
+	(x_channel * y_channel * sizeof(int16_t), GFP_KERNEL);
 }
 void setMutualOldBuffer(void)
 {
-	diag_mutual_old = kzalloc(x_channel * y_channel * sizeof(int16_t), GFP_KERNEL);
+	diag_mutual_old = kzalloc
+	(x_channel * y_channel * sizeof(int16_t), GFP_KERNEL);
 }
 
 #ifdef HX_TP_PROC_2T2R
@@ -613,94 +579,82 @@
 }
 void setMutualBuffer_2(void)
 {
-	diag_mutual_2 = kzalloc(x_channel_2 * y_channel_2 * sizeof(int16_t), GFP_KERNEL);
+	diag_mutual_2 = kzalloc
+	(x_channel_2 * y_channel_2 * sizeof(int16_t), GFP_KERNEL);
 }
 #endif
 
 static ssize_t himax_diag_arrange_write(struct file *file, const char *buff,
 	size_t len, loff_t *pos)
 {
-	//struct himax_ts_data *ts = private_ts;
+	/*struct himax_ts_data *ts = private_ts;*/
 	char buf[80] = {0};
 
-	if (len >= 80)
-	{
+	if (len >= 80) {
 		I("%s: no command exceeds 80 chars.\n", __func__);
 		return -EFAULT;
 	}
 	if (copy_from_user(buf, buff, len))
-	{
 		return -EFAULT;
-	}
 
 	g_diag_arr_num = buf[0] - '0';
-	I("%s: g_diag_arr_num = %d \n", __func__,g_diag_arr_num);
+	I("%s: g_diag_arr_num = %d\n", __func__, g_diag_arr_num);
 
 	return len;
 }
 
-static const struct file_operations himax_proc_diag_arrange_ops =
-{
+const struct file_operations himax_proc_diag_arrange_ops = {
 	.owner = THIS_MODULE,
 	.write = himax_diag_arrange_write,
 };
 
-static void himax_diag_arrange_print(struct seq_file *s, int i, int j, int transpose)
+static void himax_diag_arrange_print
+(struct seq_file *s, int i, int j, int transpose)
 {
-	if(transpose)
-		seq_printf(s, "%6d", diag_mutual[ j + i*x_channel]);
+	if (transpose)
+		seq_printf(s, "%6d", diag_mutual[j + i * x_channel]);
 	else
-		seq_printf(s, "%6d", diag_mutual[ i + j*x_channel]);
+		seq_printf(s, "%6d", diag_mutual[i + j * x_channel]);
 }
 
-static void himax_diag_arrange_inloop(struct seq_file *s, int in_init,bool transpose, int j)
+static void himax_diag_arrange_inloop
+(struct seq_file *s, int in_init, bool transpose, int j)
 {
 	int i;
 	int in_max = 0;
 
-	if(transpose)
+	if (transpose)
 		in_max = y_channel;
 	else
 		in_max = x_channel;
 
-	if (in_init > 0)
-	{
-		for(i = in_init-1;i >= 0;i--)
-		{
+	if (in_init > 0) {
+		for (i = in_init - 1 ; i >= 0 ; i--)
 			himax_diag_arrange_print(s, i, j, transpose);
-		}
-	}
-	else
-	{
-		for (i = 0; i < in_max; i++)
-		{
+	} else {
+		for (i = 0 ; i < in_max ; i++)
 			himax_diag_arrange_print(s, i, j, transpose);
-		}
 	}
 }
 
-static void himax_diag_arrange_outloop(struct seq_file *s, int transpose, int out_init, int in_init)
+static void himax_diag_arrange_outloop
+(struct seq_file *s, int transpose, int out_init, int in_init)
 {
 	int j;
 	int out_max = 0;
 
-	if(transpose)
+	if (transpose)
 		out_max = x_channel;
 	else
 		out_max = y_channel;
 
-	if(out_init > 0)
-	{
-		for(j = out_init-1;j >= 0;j--)
-		{
+	if (out_init > 0) {
+		for (j = out_init - 1 ; j >= 0 ; j--) {
 			himax_diag_arrange_inloop(s, in_init, transpose, j);
 			seq_printf(s, " %5d\n", diag_self[j]);
 		}
-	}
-	else
-	{
-		for(j = 0;j < out_max;j++)
-		{
+	} else {
+		for (j = 0 ; j < out_max ; j++) {
 			himax_diag_arrange_inloop(s, in_init, transpose, j);
 			seq_printf(s, " %5d\n", diag_self[j]);
 		}
@@ -709,33 +663,35 @@
 
 static void himax_diag_arrange(struct seq_file *s)
 {
-	int bit2,bit1,bit0;
+	int bit2, bit1, bit0;
 	int i;
 
 	bit2 = g_diag_arr_num >> 2;
 	bit1 = g_diag_arr_num >> 1 & 0x1;
 	bit0 = g_diag_arr_num & 0x1;
 
-	if (g_diag_arr_num < 4)
-	{
-		himax_diag_arrange_outloop(s, bit2, bit1 * y_channel, bit0 * x_channel);
-		for (i = y_channel; i < x_channel + y_channel; i++) {
+	if (g_diag_arr_num < 4) {
+		himax_diag_arrange_outloop(s,
+		bit2, bit1 * y_channel, bit0 * x_channel);
+
+		for (i = y_channel ; i < x_channel + y_channel ; i++)
 			seq_printf(s, "%6d", diag_self[i]);
-		}
-	}
-	else
-	{
-		himax_diag_arrange_outloop(s, bit2, bit1 * x_channel, bit0 * y_channel);
-		for (i = x_channel; i < x_channel + y_channel; i++) {
+
+	} else {
+		himax_diag_arrange_outloop(s,
+		bit2, bit1 * x_channel, bit0 * y_channel);
+
+		for (i = x_channel ; i < x_channel + y_channel ; i++)
 			seq_printf(s, "%6d", diag_self[i]);
-		}
+
 	}
 }
 
 static void *himax_diag_seq_start(struct seq_file *s, loff_t *pos)
 {
-	if (*pos>=1) return NULL;
-	return (void *)((unsigned long) *pos+1);
+	if (*pos >= 1)
+		return NULL;
+	return (void *)((unsigned long) *pos + 1);
 }
 
 static void *himax_diag_seq_next(struct seq_file *s, void *v, loff_t *pos)
@@ -748,87 +704,96 @@
 static int himax_diag_seq_read(struct seq_file *s, void *v)
 {
 	size_t count = 0;
-	int32_t loop_i;//,loop_j
+	int32_t loop_i;/*loop_j*/
 	uint16_t mutual_num, self_num, width;
 
 #ifdef HX_TP_PROC_2T2R
-	if(Is_2T2R && diag_command == 4)
-	{
+	if (Is_2T2R && diag_command == 4) {
 		mutual_num	= x_channel_2 * y_channel_2;
-		self_num	= x_channel_2 + y_channel_2; //don't add KEY_COUNT
+		/*don't add KEY_COUNT*/
+		self_num	= x_channel_2 + y_channel_2;
 		width		= x_channel_2;
-		seq_printf(s, "ChannelStart: %4d, %4d\n\n", x_channel_2, y_channel_2);
-	}
-	else
+		seq_printf(s, "ChannelStart: %4d, %4d\n\n",
+		x_channel_2, y_channel_2);
+	} else
 #endif
 	{
 		mutual_num	= x_channel * y_channel;
-		self_num	= x_channel + y_channel; //don't add KEY_COUNT
+		/*don't add KEY_COUNT*/
+		self_num	= x_channel + y_channel;
 		width		= x_channel;
-		seq_printf(s, "ChannelStart: %4d, %4d\n\n", x_channel, y_channel);
+		seq_printf(s, "ChannelStart: %4d, %4d\n\n",
+		x_channel, y_channel);
 	}
 
-	// start to show out the raw data in adb shell
+	/* start to show out the raw data in adb shell*/
 	if (diag_command >= 1 && diag_command <= 6) {
 		if (diag_command <= 3) {
 			himax_diag_arrange(s);
-			seq_printf(s, "\n\n");
+			seq_puts(s, "\n\n");
 #ifdef HX_EN_SEL_BUTTON
-			seq_printf(s, "\n");
-			for (loop_i = 0; loop_i < HX_BT_NUM; loop_i++)
-					seq_printf(s, "%6d", diag_self[HX_RX_NUM + HX_TX_NUM + loop_i]);
+			seq_putc(s, '\n');
+			for (loop_i = 0 ; loop_i < HX_BT_NUM ; loop_i++)
+				seq_printf(s, "%6d",
+				diag_self[HX_RX_NUM + HX_TX_NUM + loop_i]);
 #endif
 #ifdef HX_TP_PROC_2T2R
-		}else if(Is_2T2R && diag_command == 4 ) {
-			for (loop_i = 0; loop_i < mutual_num; loop_i++) {
+		} else if (Is_2T2R && diag_command == 4) {
+			for (loop_i = 0 ; loop_i < mutual_num ; loop_i++) {
 				seq_printf(s, "%4d", diag_mutual_2[loop_i]);
 				if ((loop_i % width) == (width - 1))
-					seq_printf(s, " %6d\n", diag_self[width + loop_i/width]);
+					seq_printf(s, " %6d\n",
+					diag_self[width + loop_i / width]);
 			}
-			seq_printf(s, "\n");
-			for (loop_i = 0; loop_i < width; loop_i++) {
+			seq_putc(s, '\n');
+			for (loop_i = 0 ; loop_i < width ; loop_i++) {
 				seq_printf(s, "%6d", diag_self[loop_i]);
 				if (((loop_i) % width) == (width - 1))
-					seq_printf(s, "\n");
+					seq_putc(s, '\n');
 			}
 #ifdef HX_EN_SEL_BUTTON
-			seq_printf(s, "\n");
-			for (loop_i = 0; loop_i < HX_BT_NUM; loop_i++)
-				seq_printf(s, "%4d", diag_self[HX_RX_NUM_2 + HX_TX_NUM_2 + loop_i]);
+			seq_putc(s, '\n');
+			for (loop_i = 0 ; loop_i < HX_BT_NUM ; loop_i++) {
+				seq_printf(s, "%4d",
+				diag_self[HX_RX_NUM_2 + HX_TX_NUM_2 + loop_i]);
+			}
 #endif
 #endif
 		} else if (diag_command > 4) {
-			for (loop_i = 0; loop_i < self_num; loop_i++) {
+			for (loop_i = 0 ; loop_i < self_num ; loop_i++) {
 				seq_printf(s, "%4d", diag_self[loop_i]);
-				if (((loop_i - mutual_num) % width) == (width - 1))
-					seq_printf(s, "\n");
+				if (((loop_i - mutual_num) % width)
+				== (width - 1)) {
+					seq_putc(s, '\n');
+				}
 			}
 		} else {
-			for (loop_i = 0; loop_i < mutual_num; loop_i++) {
+			for (loop_i = 0 ; loop_i < mutual_num ; loop_i++) {
 				seq_printf(s, "%4d", diag_mutual[loop_i]);
 				if ((loop_i % width) == (width - 1))
-					seq_printf(s, "\n");
+					seq_putc(s, '\n');
 			}
 		}
-		seq_printf(s, "ChannelEnd");
-		seq_printf(s, "\n");
+		seq_puts(s, "ChannelEnd");
+		seq_putc(s, '\n');
 	} else if (diag_command == 7) {
-		for (loop_i = 0; loop_i < 128 ;loop_i++) {
+		for (loop_i = 0; loop_i < 128 ; loop_i++) {
 			if ((loop_i % 16) == 0)
-				seq_printf(s, "LineStart:");
+				seq_puts(s, "LineStart:");
 				seq_printf(s, "%4d", diag_coor[loop_i]);
 			if ((loop_i % 16) == 15)
-				seq_printf(s, "\n");
+				seq_putc(s, '\n');
 		}
-	} else if (diag_command == 9 || diag_command == 91 || diag_command == 92){
+	} else if (diag_command == 9 ||
+	diag_command == 91 || diag_command == 92) {
+
 		himax_diag_arrange(s);
-		seq_printf(s, "\n");
+		seq_putc(s, '\n');
 	}
 
 	return count;
 }
-static const struct seq_operations himax_diag_seq_ops =
-{
+const struct seq_operations himax_diag_seq_ops = {
 	.start	= himax_diag_seq_start,
 	.next	= himax_diag_seq_next,
 	.stop	= himax_diag_seq_stop,
@@ -838,25 +803,24 @@
 {
 	return seq_open(file, &himax_diag_seq_ops);
 };
-bool DSRAM_Flag;
+bool DSRAM_Flag = false;
 
-//DSRAM thread
+/*DSRAM thread*/
 void himax_ts_diag_func(void)
 {
-	int i=0, j=0;
+	int i = 0, j = 0;
 	unsigned int index = 0;
 	int total_size = ic_data->HX_TX_NUM * ic_data->HX_RX_NUM * 2;
 	uint8_t  info_data[total_size];
-	int16_t *mutual_data     = NULL;
+	int16_t *mutual_data = NULL;
 	int16_t *mutual_data_new = NULL;
 	int16_t *mutual_data_old = NULL;
 	int16_t new_data;
 
 	himax_burst_enable(private_ts->client, 1);
-	if(diag_command == 9 || diag_command == 91)
-	{
+	if (diag_command == 9 || diag_command == 91) {
 		mutual_data = getMutualBuffer();
-	}else if(diag_command == 92){
+	} else if (diag_command == 92) {
 		mutual_data = getMutualBuffer();
 		mutual_data_new = getMutualNewBuffer();
 		mutual_data_old = getMutualOldBuffer();
@@ -864,49 +828,63 @@
 	himax_get_DSRAM_data(private_ts->client, info_data);
 
 	index = 0;
-	for (i = 0; i < ic_data->HX_TX_NUM; i++)
-	{
-		for (j = 0; j < ic_data->HX_RX_NUM; j++)
-		{
-			new_data = (short)(info_data[index + 1] << 8 | info_data[index]);
-			if(diag_command == 9){
-				mutual_data[i*ic_data->HX_RX_NUM+j] = new_data;
-			}else if(diag_command == 91){ //Keep max data for 100 frame
-				if(mutual_data[i * ic_data->HX_RX_NUM + j] < new_data)
-				mutual_data[i * ic_data->HX_RX_NUM + j] = new_data;
-			}else if(diag_command == 92){ //Cal data for [N]-[N-1] frame
-				mutual_data_new[i * ic_data->HX_RX_NUM + j] = new_data;
-				mutual_data[i * ic_data->HX_RX_NUM + j] = mutual_data_new[i * ic_data->HX_RX_NUM + j] - mutual_data_old[i * ic_data->HX_RX_NUM + j];
+	for (i = 0 ; i < ic_data->HX_TX_NUM ; i++) {
+		for (j = 0 ; j < ic_data->HX_RX_NUM ; j++) {
+			new_data = (short)(info_data[index + 1]
+			<< 8 | info_data[index]);
+			if (diag_command == 9) {
+				mutual_data[i * ic_data->HX_RX_NUM + j]
+				= new_data;
+			/*Keep max data for 100 frame*/
+			} else if (diag_command == 91) {
+				if (mutual_data[i * ic_data->HX_RX_NUM + j]
+				< new_data) {
+					mutual_data[i * ic_data->HX_RX_NUM + j]
+					= new_data;
+				}
+			/*Cal data for [N]-[N-1] frame*/
+			} else if (diag_command == 92) {
+				mutual_data_new[i * ic_data->HX_RX_NUM + j]
+				= new_data;
+
+				mutual_data[i * ic_data->HX_RX_NUM + j] =
+				mutual_data_new[i * ic_data->HX_RX_NUM + j] -
+				mutual_data_old[i * ic_data->HX_RX_NUM + j];
 			}
 			index += 2;
 		}
 	}
-	if(diag_command == 92){
-		memcpy(mutual_data_old,mutual_data_new,x_channel * y_channel * sizeof(int16_t)); //copy N data to N-1 array
+	/*copy N data to N-1 array*/
+	if (diag_command == 92) {
+		memcpy(mutual_data_old, mutual_data_new,
+		x_channel * y_channel * sizeof(int16_t));
 	}
+
 	diag_max_cnt++;
-	if(diag_command == 9 || diag_command == 92){
-		queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 1/10*HZ);
-	}else if(diag_command == 91){
-		if(diag_max_cnt > 100) //count for 100 frame
-		{
-			//Clear DSRAM flag
+	if (diag_command == 9 || diag_command == 92) {
+		queue_delayed_work(private_ts->himax_diag_wq,
+		&private_ts->himax_diag_delay_wrok, 1/10*HZ);
+	} else if (diag_command == 91) {
+		if (diag_max_cnt > 100) {/*count for 100 frame*/
+			/*Clear DSRAM flag*/
 			DSRAM_Flag = false;
 
-			//Enable ISR
-			himax_int_enable(private_ts->client->irq,1);
+			/*Enable ISR*/
+			himax_int_enable(private_ts->client->irq, 1);
 
-			//=====================================
-			// test result command : 0x8002_0324 ==> 0x00
-			//=====================================
+			/*=====================================
+			test result command : 0x8002_0324 ==> 0x00
+			=====================================*/
 			himax_diag_register_set(private_ts->client, 0x00);
-		}else{
-			queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 1/10*HZ);
+		} else {
+			queue_delayed_work(private_ts->himax_diag_wq,
+			&private_ts->himax_diag_delay_wrok, 1 / 10 * HZ);
 		}
 	}
 }
 
-static ssize_t himax_diag_write(struct file *filp, const char __user *buff, size_t len, loff_t *data)
+static ssize_t himax_diag_write
+(struct file *filp, const char __user *buff, size_t len, loff_t *data)
 {
 	char messages[80] = {0};
 
@@ -915,67 +893,66 @@
 
 	memset(receive, 0x00, sizeof(receive));
 
-	if (len >= 80)
-	{
+	if (len >= 80) {
 		I("%s: no command exceeds 80 chars.\n", __func__);
 		return -EFAULT;
 	}
 	if (copy_from_user(messages, buff, len))
-	{
 		return -EFAULT;
-	}
-	if (messages[1] == 0x0A){
-		diag_command =messages[0] - '0';
-	}else{
-		diag_command =(messages[0] - '0')*10 + (messages[1] - '0');
-	}
 
-	I("[Himax]diag_command=0x%x\n",diag_command);
-	if (diag_command < 0x04){
-		if(DSRAM_Flag)
-		{
-			//1. Clear DSRAM flag
+	if (messages[1] == 0x0A)
+		diag_command = messages[0] - '0';
+	else
+		diag_command = (messages[0] - '0') * 10 + (messages[1] - '0');
+
+
+	I("[Himax]diag_command=0x%x\n", diag_command);
+	if (diag_command < 0x04) {
+		if (DSRAM_Flag) {
+			/*1. Clear DSRAM flag*/
 			DSRAM_Flag = false;
 
-			//2. Stop DSRAM thread
-			cancel_delayed_work_sync(&private_ts->himax_diag_delay_wrok);
+			/*2. Stop DSRAM thread*/
+			cancel_delayed_work_sync
+			(&private_ts->himax_diag_delay_wrok);
 
-			//3. Enable ISR
-			himax_int_enable(private_ts->client->irq,1);
+			/*3. Enable ISR*/
+			himax_int_enable(private_ts->client->irq, 1);
 		}
 		command[0] = diag_command;
 		himax_diag_register_set(private_ts->client, command[0]);
-	}
-	//coordinate dump start
-	else if (diag_command == 0x08)	{
-		E("%s: coordinate_dump_file_create error\n", __func__);
-	}
-	else if (diag_command == 0x09 || diag_command == 91 || diag_command == 92){
+	/*coordinate dump start*/
+	} else if (diag_command == 0x09 ||
+	diag_command == 91 || diag_command == 92) {
+
 		diag_max_cnt = 0;
-		memset(diag_mutual, 0x00, x_channel * y_channel * sizeof(int16_t)); //Set data 0 everytime
+		 /*Set data 0 everytime*/
+		memset(diag_mutual, 0x00,
+		x_channel * y_channel * sizeof(int16_t));
 
-		//1. Disable ISR
-		himax_int_enable(private_ts->client->irq,0);
+		/*1. Disable ISR*/
+		himax_int_enable(private_ts->client->irq, 0);
 
-		//2. Start DSRAM thread
-		//himax_diag_register_set(private_ts->client, 0x0A);
+		/*2. Start DSRAM thread*/
+		/*himax_diag_register_set(private_ts->client, 0x0A);*/
 
-		queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 2*HZ/100);
+		queue_delayed_work(private_ts->himax_diag_wq,
+		&private_ts->himax_diag_delay_wrok, 2 * HZ / 100);
 
 		I("%s: Start get raw data in DSRAM\n", __func__);
 
-		//3. Set DSRAM flag
+		/*3. Set DSRAM flag*/
 		DSRAM_Flag = true;
-	}else{
+	} else {
 		command[0] = 0x00;
 		himax_diag_register_set(private_ts->client, command[0]);
-		E("[Himax]Diag command error!diag_command=0x%x\n",diag_command);
+		E("[Himax]Diag command error!diag_command=0x%x\n",
+		diag_command);
 	}
 	return len;
 }
 
-static const struct file_operations himax_proc_diag_ops =
-{
+const struct file_operations himax_proc_diag_ops = {
 	.owner = THIS_MODULE,
 	.open = himax_diag_proc_open,
 	.read = seq_read,
@@ -989,23 +966,20 @@
 {
 	char buf_tmp[12];
 
-	if (len >= 12)
-	{
+	if (len >= 12) {
 		I("%s: no command exceeds 12 chars.\n", __func__);
 		return -EFAULT;
 	}
 	if (copy_from_user(buf_tmp, buff, len))
-	{
 		return -EFAULT;
-	}
-	//if (buf_tmp[0] == '1')
-	//	ESD_HW_REST();
+
+	/*if (buf_tmp[0] == '1')
+		ESD_HW_REST();*/
 
 	return len;
 }
 
-static const struct file_operations himax_proc_reset_ops =
-{
+const struct file_operations himax_proc_reset_ops = {
 	.owner = THIS_MODULE,
 	.write = himax_reset_write,
 };
@@ -1018,291 +992,263 @@
 	size_t count = 0;
 	char *temp_buf;
 
-	if(!HX_PROC_SEND_FLAG)
-	{
+	if (!HX_PROC_SEND_FLAG) {
 		temp_buf = kzalloc(len, GFP_KERNEL);
-		if (!temp_buf){
-			HX_PROC_SEND_FLAG=0;
-			return count;
-		}
-
-		if (debug_level_cmd == 't')
-		{
-			if (fw_update_complete)
-				count += snprintf(temp_buf+count, len-count, "FW Update Complete ");
-			else
-			{
-				count += snprintf(temp_buf+count, len-count, "FW Update Fail ");
-			}
-		}
-		else if (debug_level_cmd == 'h')
-		{
-			if (handshaking_result == 0)
-			{
-				count += snprintf(temp_buf+count, len-count, "Handshaking Result = %d (MCU Running)\n", handshaking_result);
-			}
-			else if (handshaking_result == 1)
-			{
-				count += snprintf(temp_buf+count, len-count, "Handshaking Result = %d (MCU Stop)\n", handshaking_result);
-			}
-			else if (handshaking_result == 2)
-			{
-				count += snprintf(temp_buf+count, len-count, "Handshaking Result = %d (I2C Error)\n", handshaking_result);
-			}
-			else
-			{
-				count += snprintf(temp_buf+count, len-count, "Handshaking Result = error\n");
-			}
-		}
-		else if (debug_level_cmd == 'v')
-		{
-			count += snprintf(temp_buf+count, len-count, "FW_VER = ");
-			count += snprintf(temp_buf+count, len-count, "0x%2.2X\n", ic_data->vendor_fw_ver);
-			count += snprintf(temp_buf+count, len-count, "CONFIG_VER = ");
-			count += snprintf(temp_buf+count, len-count, "0x%2.2X\n", ic_data->vendor_config_ver);
-			count += snprintf(temp_buf+count, len-count, "\n");
-		}
-		else if (debug_level_cmd == 'd')
-		{
-			count += snprintf(temp_buf+count, len-count, "Himax Touch IC Information :\n");
-			if (IC_TYPE == HX_85XX_D_SERIES_PWON)
-			{
-				count += snprintf(temp_buf+count, len-count, "IC Type : D\n");
-			}
-			else if (IC_TYPE == HX_85XX_E_SERIES_PWON)
-			{
-				count += snprintf(temp_buf+count, len-count, "IC Type : E\n");
-			}
-			else if (IC_TYPE == HX_85XX_ES_SERIES_PWON)
-			{
-				count += snprintf(temp_buf+count, len-count, "IC Type : ES\n");
-			}
-			else if (IC_TYPE == HX_85XX_F_SERIES_PWON)
-			{
-				count += snprintf(temp_buf+count, len-count, "IC Type : F\n");
-			}
-			else
-			{
-				count += snprintf(temp_buf+count, len-count, "IC Type error.\n");
+		if (debug_level_cmd == 't') {
+			if (fw_update_complete) {
+				count += snprintf(temp_buf, len,
+				"FW Update Complete ");
+			} else {
+				count += snprintf(temp_buf, len,
+				"FW Update Fail ");
 			}
 
-			if (IC_CHECKSUM == HX_TP_BIN_CHECKSUM_SW)
-			{
-				count += snprintf(temp_buf+count, len-count, "IC Checksum : SW\n");
+		} else if (debug_level_cmd == 'h') {
+			if (handshaking_result == 0) {
+				count += snprintf(temp_buf, len,
+				"Handshaking Result = %d (MCU Running)\n",
+				handshaking_result);
+			} else if (handshaking_result == 1) {
+				count += snprintf(temp_buf, len,
+				"Handshaking Result = %d (MCU Stop)\n",
+				handshaking_result);
+			} else if (handshaking_result == 2) {
+				count += snprintf(temp_buf, len,
+				"Handshaking Result = %d (I2C Error)\n",
+				handshaking_result);
+			} else {
+				count += snprintf(temp_buf, len,
+				"Handshaking Result = error\n");
 			}
-			else if (IC_CHECKSUM == HX_TP_BIN_CHECKSUM_HW)
-			{
-				count += snprintf(temp_buf+count, len-count, "IC Checksum : HW\n");
+		} else if (debug_level_cmd == 'v') {
+			count += snprintf(temp_buf + count, len,
+			"FW_VER = ");
+			count += snprintf(temp_buf + count, len,
+			"0x%2.2X\n", ic_data->vendor_fw_ver);
+			count += snprintf(temp_buf + count, len,
+			"CONFIG_VER = ");
+			count += snprintf(temp_buf + count, len,
+			"0x%2.2X\n", ic_data->vendor_config_ver);
+			count += snprintf(temp_buf + count, len,
+			"\n");
+		} else if (debug_level_cmd == 'd') {
+			count += snprintf(temp_buf + count, len,
+			"Himax Touch IC Information :\n");
+			if (IC_TYPE == HX_85XX_D_SERIES_PWON) {
+				count += snprintf(temp_buf + count, len,
+				"IC Type : D\n");
+			} else if (IC_TYPE == HX_85XX_E_SERIES_PWON) {
+				count += snprintf(temp_buf + count, len,
+				"IC Type : E\n");
+			} else if (IC_TYPE == HX_85XX_ES_SERIES_PWON) {
+				count += snprintf(temp_buf + count, len,
+				"IC Type : ES\n");
+			} else if (IC_TYPE == HX_85XX_F_SERIES_PWON) {
+				count += snprintf(temp_buf + count, len,
+				"IC Type : F\n");
+			} else {
+				count += snprintf(temp_buf + count, len,
+				"IC Type error.\n");
 			}
-			else if (IC_CHECKSUM == HX_TP_BIN_CHECKSUM_CRC)
-			{
-				count += snprintf(temp_buf+count, len-count, "IC Checksum : CRC\n");
+			if (IC_CHECKSUM == HX_TP_BIN_CHECKSUM_SW) {
+				count += snprintf(temp_buf + count, len,
+				"IC Checksum : SW\n");
+			} else if (IC_CHECKSUM == HX_TP_BIN_CHECKSUM_HW) {
+				count += snprintf(temp_buf + count, len,
+				"IC Checksum : HW\n");
+			} else if (IC_CHECKSUM == HX_TP_BIN_CHECKSUM_CRC) {
+				count += snprintf(temp_buf + count, len,
+				"IC Checksum : CRC\n");
+			} else {
+				count += snprintf(temp_buf + count, len,
+				"IC Checksum error.\n");
 			}
-			else
-			{
-				count += snprintf(temp_buf+count, len-count, "IC Checksum error.\n");
+			if (ic_data->HX_INT_IS_EDGE) {
+				count += snprintf(temp_buf + count, len,
+				"Interrupt : EDGE TIRGGER\n");
+			} else {
+				count += snprintf(temp_buf + count, len,
+				"Interrupt : LEVEL TRIGGER\n");
 			}
-
-			if (ic_data->HX_INT_IS_EDGE)
-			{
-				count += snprintf(temp_buf+count, len-count, "Interrupt : EDGE TIRGGER\n");
-			}
-			else
-			{
-				count += snprintf(temp_buf+count, len-count, "Interrupt : LEVEL TRIGGER\n");
-			}
-
-			count += snprintf(temp_buf+count, len-count, "RX Num : %d\n", ic_data->HX_RX_NUM);
-			count += snprintf(temp_buf+count, len-count, "TX Num : %d\n", ic_data->HX_TX_NUM);
-			count += snprintf(temp_buf+count, len-count, "BT Num : %d\n", ic_data->HX_BT_NUM);
-			count += snprintf(temp_buf+count, len-count, "X Resolution : %d\n", ic_data->HX_X_RES);
-			count += snprintf(temp_buf+count, len-count, "Y Resolution : %d\n", ic_data->HX_Y_RES);
-			count += snprintf(temp_buf+count, len-count, "Max Point : %d\n", ic_data->HX_MAX_PT);
-			count += snprintf(temp_buf+count, len-count, "XY reverse : %d\n", ic_data->HX_XY_REVERSE);
+			count += snprintf(temp_buf + count, len,
+			"RX Num : %d\n", ic_data->HX_RX_NUM);
+			count += snprintf(temp_buf + count, len,
+			"TX Num : %d\n", ic_data->HX_TX_NUM);
+			count += snprintf(temp_buf + count, len,
+			"BT Num : %d\n", ic_data->HX_BT_NUM);
+			count += snprintf(temp_buf + count, len,
+			"X Resolution : %d\n", ic_data->HX_X_RES);
+			count += snprintf(temp_buf + count, len,
+			"Y Resolution : %d\n", ic_data->HX_Y_RES);
+			count += snprintf(temp_buf + count, len,
+			"Max Point : %d\n", ic_data->HX_MAX_PT);
+			count += snprintf(temp_buf + count, len,
+			"XY reverse : %d\n", ic_data->HX_XY_REVERSE);
 	#ifdef HX_TP_PROC_2T2R
-			if(Is_2T2R)
-			{
-				count += snprintf(temp_buf+count, len-count, "2T2R panel\n");
-				count += snprintf(temp_buf+count, len-count, "RX Num_2 : %d\n", HX_RX_NUM_2);
-				count += snprintf(temp_buf+count, len-count, "TX Num_2 : %d\n", HX_TX_NUM_2);
+			if (Is_2T2R) {
+				count += snprintf(temp_buf + count, len,
+				"2T2R panel\n");
+				count += snprintf(temp_buf + count, len,
+				"RX Num_2 : %d\n", HX_RX_NUM_2);
+				count += snprintf(temp_buf + count, len,
+				"TX Num_2 : %d\n", HX_TX_NUM_2);
 			}
 	#endif
-		}
-		else if (debug_level_cmd == 'i')
-		{
-			count += snprintf(temp_buf+count, len-count, "Himax Touch Driver Version:\n");
-			count += snprintf(temp_buf+count, len-count, "%s\n", HIMAX_DRIVER_VER);
+		} else if (debug_level_cmd == 'i') {
+			count += snprintf(temp_buf + count, len,
+			"Himax Touch Driver Version:\n");
+			count += snprintf(temp_buf + count, len,
+			"%s\n", HIMAX_DRIVER_VER);
 		}
 		if (copy_to_user(buf, temp_buf, len))
-		{
 			I("%s,here:%d\n", __func__, __LINE__);
-		}
 
 		kfree(temp_buf);
-		HX_PROC_SEND_FLAG=1;
-	}
-	else
-		HX_PROC_SEND_FLAG=0;
+		HX_PROC_SEND_FLAG = 1;
+	} else
+		HX_PROC_SEND_FLAG = 0;
 	return count;
 }
 
 static ssize_t himax_debug_write(struct file *file, const char *buff,
 	size_t len, loff_t *pos)
 {
-	const struct firmware *fw = NULL;
-	unsigned char *fw_data = NULL;
+	int result = 0;
 	char fileName[128];
 	char buf[80] = {0};
-	int result;
+	const struct firmware *fw = NULL;
 
-	if (len >= 80)
-	{
+	if (len >= 80) {
 		I("%s: no command exceeds 80 chars.\n", __func__);
 		return -EFAULT;
 	}
 	if (copy_from_user(buf, buff, len))
-	{
 		return -EFAULT;
-	}
 
-	if ( buf[0] == 'h') //handshaking
-	{
+	if (buf[0] == 'h') {/*handshaking*/
 		debug_level_cmd = buf[0];
 
-		himax_int_enable(private_ts->client->irq,0);
+		himax_int_enable(private_ts->client->irq, 0);
 
-		handshaking_result = himax_hand_shaking(private_ts->client); //0:Running, 1:Stop, 2:I2C Fail
+		/*0:Running, 1:Stop, 2:I2C Fail*/
+		handshaking_result = himax_hand_shaking(private_ts->client);
 
-		himax_int_enable(private_ts->client->irq,1);
+		himax_int_enable(private_ts->client->irq, 1);
 
 		return len;
-	}
-
-	else if ( buf[0] == 'v') //firmware version
-	{
+	} else if (buf[0] == 'v') { /*firmware version*/
 		debug_level_cmd = buf[0];
-		himax_int_enable(private_ts->client->irq,0);
+		himax_int_enable(private_ts->client->irq, 0);
 #ifdef HX_RST_PIN_FUNC
-		himax_HW_reset(false,false);
+		himax_HW_reset(false, false);
 #endif
 		himax_read_FW_ver(private_ts->client);
-		//himax_check_chip_version();
+		/*himax_check_chip_version();*/
 #ifdef HX_RST_PIN_FUNC
-	himax_HW_reset(true,false);
+	himax_HW_reset(true, false);
 #endif
-	himax_int_enable(private_ts->client->irq,1);
+	himax_int_enable(private_ts->client->irq, 1);
 		return len;
-	}
+	} else if (buf[0] == 'd') { /*ic information*/
 
-	else if ( buf[0] == 'd') //ic information
-	{
 		debug_level_cmd = buf[0];
 		return len;
-	}
+	} else if (buf[0] == 'i') {/*driver version*/
 
-	else if ( buf[0] == 'i') //driver version
-	{
 		debug_level_cmd = buf[0];
 		return len;
-	}
+	} else if (buf[0] == 't') {
 
-	else if (buf[0] == 't')
-	{
+		himax_int_enable(private_ts->client->irq, 0);
+		debug_level_cmd = buf[0];
+		fw_update_complete = false;
 
-		himax_int_enable(private_ts->client->irq,0);
-
-		debug_level_cmd 		= buf[0];
-		fw_update_complete		= false;
-
-		memset(fileName, 0, 128);
-		// parse the file name
-		snprintf(fileName, len-4, "%s", &buf[4]);
-		I("%s: upgrade from file(%s) start!\n", __func__, fileName);
-		// open file
-		result = request_firmware(&fw, fileName, private_ts->dev);
-		if (result) {
-			E("%s: open firmware file failed\n", __func__);
-			goto firmware_upgrade_done;
-			//return len;
+		result = himax_load_CRC_bin_file(private_ts->client);
+		if (result < 0) {
+			E("%s: himax_load_CRC_bin_file fail Error Code=%d.\n",
+			__func__, result);
+			return result;
 		}
 
-		I("%s: FW len %d\n", __func__, fw->size);
-		fw_data = (unsigned char *)fw->data;
+		memset(fileName, 0, 128);
+/* parse the file name*/
+		snprintf(fileName, len-4, "%s", &buf[4]);
+		I("%s: upgrade from file(%s) start!\n", __func__, fileName);
+		result = request_firmware(&fw, fileName, private_ts->dev);
+		if (result < 0) {
+			I("fail to request_firmware fwpath: %s (ret:%d)\n",
+			fileName, result);
+			return result;
+		}
+		I("%s: FW image: %02X, %02X, %02X, %02X ret=%d\n", __func__,
+		fw->data[0], fw->data[1], fw->data[2], fw->data[3], result);
+		if (result >= 0) {
+			/*start to upgrade*/
+			himax_int_enable(private_ts->client->irq, 0);
 
-		I("%s: FW image,len %d: %02X, %02X, %02X, %02X\n", __func__, result, upgrade_fw[0], upgrade_fw[1], upgrade_fw[2], upgrade_fw[3]);
-
-		if (fw_data != NULL)
-		{
-			// start to upgrade
-			himax_int_enable(private_ts->client->irq,0);
-
-			if ((buf[1] == '6') && (buf[2] == '0'))
-			{
-				if (fts_ctpm_fw_upgrade_with_sys_fs_60k(private_ts->client,upgrade_fw, result, false) == 0)
-				{
-					E("%s: TP upgrade error, line: %d\n", __func__, __LINE__);
+			if ((buf[1] == '6') && (buf[2] == '0')) {
+				if (fts_ctpm_fw_upgrade_with_sys_fs_60k
+				(private_ts->client, (unsigned char *)fw->data,
+				fw->size, false) == 0) {
+					E("%s: TP upgrade error, line: %d\n",
+					__func__, __LINE__);
 					fw_update_complete = false;
-				}
-				else
-				{
-					I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__);
+				} else {
+					I("%s: TP upgrade OK, line: %d\n",
+					__func__, __LINE__);
 					fw_update_complete = true;
 				}
-			}
-			else if ((buf[1] == '6') && (buf[2] == '4'))
-			{
-				if (fts_ctpm_fw_upgrade_with_sys_fs_64k(private_ts->client,upgrade_fw, result, false) == 0)
-				{
-					E("%s: TP upgrade error, line: %d\n", __func__, __LINE__);
+			} else if ((buf[1] == '6') && (buf[2] == '4')) {
+				if (fts_ctpm_fw_upgrade_with_sys_fs_64k
+				(private_ts->client, (unsigned char *)fw->data,
+				fw->size, false) == 0) {
+					E("%s: TP upgrade error, line: %d\n",
+					__func__, __LINE__);
 					fw_update_complete = false;
-				}
-				else
-				{
-					I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__);
+				} else {
+					I("%s: TP upgrade OK, line: %d\n",
+					__func__, __LINE__);
 					fw_update_complete = true;
 				}
-			}
-			else if ((buf[1] == '2') && (buf[2] == '4'))
-			{
-				if (fts_ctpm_fw_upgrade_with_sys_fs_124k(private_ts->client,upgrade_fw, result, false) == 0)
-				{
-					E("%s: TP upgrade error, line: %d\n", __func__, __LINE__);
+			} else if ((buf[1] == '2') && (buf[2] == '4')) {
+				if (fts_ctpm_fw_upgrade_with_sys_fs_124k
+				(private_ts->client, (unsigned char *)fw->data,
+				fw->size, false) == 0) {
+					E("%s: TP upgrade error, line: %d\n",
+					__func__, __LINE__);
 					fw_update_complete = false;
-				}
-				else
-				{
-					I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__);
+				} else {
+					I("%s: TP upgrade OK, line: %d\n",
+					__func__, __LINE__);
 					fw_update_complete = true;
 				}
-			}
-			else if ((buf[1] == '2') && (buf[2] == '8'))
-			{
-				if (fts_ctpm_fw_upgrade_with_sys_fs_128k(private_ts->client,upgrade_fw, result, false) == 0)
-				{
-					E("%s: TP upgrade error, line: %d\n", __func__, __LINE__);
+			} else if ((buf[1] == '2') && (buf[2] == '8')) {
+				if (fts_ctpm_fw_upgrade_with_sys_fs_128k
+				(private_ts->client, (unsigned char *)fw->data,
+				fw->size, false) == 0) {
+					E("%s: TP upgrade error, line: %d\n",
+					__func__, __LINE__);
 					fw_update_complete = false;
-				}
-				else
-				{
-					I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__);
+				} else {
+					I("%s: TP upgrade OK, line: %d\n",
+					__func__, __LINE__);
 					fw_update_complete = true;
 				}
-			}
-			else
-			{
-				E("%s: Flash command fail: %d\n", __func__, __LINE__);
+			} else {
+				E("%s: Flash command fail: %d\n",
+				__func__, __LINE__);
 				fw_update_complete = false;
 			}
 			release_firmware(fw);
 			goto firmware_upgrade_done;
-			//return count;
+			/*return count;*/
 		}
 	}
 
-	firmware_upgrade_done:
+firmware_upgrade_done:
 
 #ifdef HX_RST_PIN_FUNC
-	himax_HW_reset(true,false);
+	himax_HW_reset(true, false);
 #endif
 
 	himax_sense_on(private_ts->client, 0x01);
@@ -1310,16 +1256,15 @@
 #ifdef HX_ESD_WORKAROUND
 	HX_ESD_RESET_ACTIVATE = 1;
 #endif
-	himax_int_enable(private_ts->client->irq,1);
+	himax_int_enable(private_ts->client->irq, 1);
 
-	//todo himax_chip->tp_firmware_upgrade_proceed = 0;
-	//todo himax_chip->suspend_state = 0;
-	//todo enable_irq(himax_chip->irq);
+	/*todo himax_chip->tp_firmware_upgrade_proceed = 0;
+	todo himax_chip->suspend_state = 0;
+	todo enable_irq(himax_chip->irq);*/
 	return len;
 }
 
-static const struct file_operations himax_proc_debug_ops =
-{
+const struct file_operations himax_proc_debug_ops = {
 	.owner = THIS_MODULE,
 	.read = himax_debug_read,
 	.write = himax_debug_write,
@@ -1376,9 +1321,9 @@
 
 void setFlashBuffer(void)
 {
-	flash_buffer = kzalloc(Flash_Size * sizeof(uint8_t), GFP_KERNEL);
-	if (flash_buffer)
-		memset(flash_buffer,0x00,Flash_Size);
+	flash_buffer = kzalloc
+	(Flash_Size * sizeof(uint8_t), GFP_KERNEL);
+	memset(flash_buffer, 0x00, Flash_Size);
 }
 
 void setSysOperation(uint8_t operation)
@@ -1389,7 +1334,8 @@
 static void setFlashDumpProgress(uint8_t progress)
 {
 	flash_progress = progress;
-	//I("setFlashDumpProgress : progress = %d ,flash_progress = %d \n",progress,flash_progress);
+	/*I("setFlashDumpProgress : progress = %d ,
+	flash_progress = %d\n",progress,flash_progress);*/
 }
 
 static void setFlashDumpComplete(uint8_t status)
@@ -1432,130 +1378,113 @@
 {
 	int ret = 0;
 	int loop_i;
-	uint8_t local_flash_read_step=0;
+	uint8_t local_flash_read_step = 0;
 	uint8_t local_flash_complete = 0;
 	uint8_t local_flash_progress = 0;
 	uint8_t local_flash_command = 0;
 	uint8_t local_flash_fail = 0;
 	char *temp_buf;
+
 	local_flash_complete = getFlashDumpComplete();
 	local_flash_progress = getFlashDumpProgress();
 	local_flash_command = getFlashCommand();
 	local_flash_fail = getFlashDumpFail();
 
-	I("flash_progress = %d \n",local_flash_progress);
-	if(!HX_PROC_SEND_FLAG)
-	{
+	I("flash_progress = %d\n", local_flash_progress);
+	if (!HX_PROC_SEND_FLAG) {
 		temp_buf = kzalloc(len, GFP_KERNEL);
-		if (!temp_buf) {
-			HX_PROC_SEND_FLAG=0;
-			return ret;
-		}
-
-		if (local_flash_fail)
-		{
-			ret += snprintf(temp_buf+ret, len-ret, "FlashStart:Fail \n");
-			ret += snprintf(temp_buf+ret, len-ret, "FlashEnd");
-			ret += snprintf(temp_buf+ret, len-ret, "\n");
+		if (local_flash_fail) {
+			ret += snprintf(temp_buf + ret, len,
+			"FlashStart:Fail\n");
+			ret += snprintf(temp_buf + ret, len,
+			"FlashEnd");
+			ret += snprintf(temp_buf + ret, len,
+			"\n");
 
 			if (copy_to_user(buf, temp_buf, len))
-			{
 				I("%s,here:%d\n", __func__, __LINE__);
-			}
 
 			kfree(temp_buf);
 			HX_PROC_SEND_FLAG = 1;
 			return ret;
 		}
 
-		if (!local_flash_complete)
-		{
-			ret += snprintf(temp_buf+ret, len-ret, "FlashStart:Ongoing:0x%2.2x \n",flash_progress);
-			ret += snprintf(temp_buf+ret, len-ret, "FlashEnd");
-			ret += snprintf(temp_buf+ret, len-ret, "\n");
+		if (!local_flash_complete) {
+			ret += snprintf(temp_buf+ret, len,
+			"FlashStart:Ongoing:0x%2.2x\n", flash_progress);
+			ret += snprintf(temp_buf + ret, len, "FlashEnd");
+			ret += snprintf(temp_buf + ret, len, "\n");
 
 			if (copy_to_user(buf, temp_buf, len))
-			{
 				I("%s,here:%d\n", __func__, __LINE__);
-			}
 
 			kfree(temp_buf);
 			HX_PROC_SEND_FLAG = 1;
 			return ret;
 		}
 
-		if (local_flash_command == 1 && local_flash_complete)
-		{
-			ret += snprintf(temp_buf+ret, len-ret, "FlashStart:Complete \n");
-			ret += snprintf(temp_buf+ret, len-ret, "FlashEnd");
-			ret += snprintf(temp_buf+ret, len-ret, "\n");
+		if (local_flash_command == 1 && local_flash_complete) {
+			ret += snprintf(temp_buf+ret, len,
+			"FlashStart:Complete\n");
+			ret += snprintf(temp_buf + ret, len, "FlashEnd");
+			ret += snprintf(temp_buf + ret, len, "\n");
 
 			if (copy_to_user(buf, temp_buf, len))
-			{
 				I("%s,here:%d\n", __func__, __LINE__);
-			}
 
 			kfree(temp_buf);
 			HX_PROC_SEND_FLAG = 1;
 			return ret;
 		}
 
-		if (local_flash_command == 3 && local_flash_complete)
-		{
-			ret += snprintf(temp_buf+ret, len-ret, "FlashStart: \n");
-			for(loop_i = 0; loop_i < 128; loop_i++)
-			{
-				ret += snprintf(temp_buf+ret, len-ret, "x%2.2x", flash_buffer[loop_i]);
+		if (local_flash_command == 3 && local_flash_complete) {
+			ret += snprintf(temp_buf+ret, len, "FlashStart:\n");
+			for (loop_i = 0 ; loop_i < 128 ; loop_i++) {
+				ret += snprintf(temp_buf + ret, len,
+				"x%2.2x", flash_buffer[loop_i]);
 				if ((loop_i % 16) == 15)
-				{
-					ret += snprintf(temp_buf+ret, len-ret, "\n");
-				}
+					ret += snprintf(temp_buf + ret, len,
+					"\n");
 			}
-			ret += snprintf(temp_buf+ret, len-ret, "FlashEnd");
-			ret += snprintf(temp_buf+ret, len-ret, "\n");
+			ret += snprintf(temp_buf + ret, len, "FlashEnd");
+			ret += snprintf(temp_buf + ret, len, "\n");
 
 			if (copy_to_user(buf, temp_buf, len))
-			{
 				I("%s,here:%d\n", __func__, __LINE__);
-			}
 
 			kfree(temp_buf);
 			HX_PROC_SEND_FLAG = 1;
 			return ret;
 		}
 
-		//flash command == 0 , report the data
+		/*flash command == 0 , report the data*/
 		local_flash_read_step = getFlashReadStep();
 
-		ret += snprintf(temp_buf+ret, len-ret, "FlashStart:%2.2x \n",local_flash_read_step);
+		ret += snprintf(temp_buf + ret, len,
+		"FlashStart:%2.2x\n", local_flash_read_step);
 
-		for (loop_i = 0; loop_i < 1024; loop_i++)
-		{
-			ret += snprintf(temp_buf+ret, len-ret, "x%2.2X", flash_buffer[local_flash_read_step*1024 + loop_i]);
+		for (loop_i = 0 ; loop_i < 1024 ; loop_i++) {
+			ret += snprintf(temp_buf + ret, len, "x%2.2X",
+			flash_buffer[local_flash_read_step * 1024 + loop_i]);
 
 			if ((loop_i % 16) == 15)
-			{
-				ret += snprintf(temp_buf+ret, len-ret, "\n");
-			}
+				ret += snprintf(temp_buf + ret, len, "\n");
 		}
 
-		ret += snprintf(temp_buf+ret, len-ret, "FlashEnd");
-		ret += snprintf(temp_buf+ret, len-ret, "\n");
+		ret += snprintf(temp_buf + ret, len, "FlashEnd");
+		ret += snprintf(temp_buf + ret, len, "\n");
 		if (copy_to_user(buf, temp_buf, len))
-		{
 			I("%s,here:%d\n", __func__, __LINE__);
-		}
 
 		kfree(temp_buf);
 		HX_PROC_SEND_FLAG = 1;
-	}
-	else
-		HX_PROC_SEND_FLAG=0;
+	} else
+		HX_PROC_SEND_FLAG = 0;
 	return ret;
 }
 
-static ssize_t himax_proc_flash_write(struct file *file, const char *buff,
-	size_t len, loff_t *pos)
+static ssize_t himax_proc_flash_write(struct file *file,
+const char *buff, size_t len, loff_t *pos)
 {
 	char buf_tmp[6];
 	unsigned long result = 0;
@@ -1563,85 +1492,74 @@
 	int base = 0;
 	char buf[80] = {0};
 
-	if (len >= 80)
-	{
+	if (len >= 80) {
 		I("%s: no command exceeds 80 chars.\n", __func__);
 		return -EFAULT;
 	}
 	if (copy_from_user(buf, buff, len))
-	{
 		return -EFAULT;
-	}
 	memset(buf_tmp, 0x0, sizeof(buf_tmp));
 
 	I("%s: buf[0] = %s\n", __func__, buf);
 
-	if (getSysOperation() == 1)
-	{
+	if (getSysOperation() == 1) {
 		E("%s: PROC is busy , return!\n", __func__);
 		return len;
 	}
 
-	if (buf[0] == '0')
-	{
+	if (buf[0] == '0') {
 		setFlashCommand(0);
-		if (buf[1] == ':' && buf[2] == 'x')
-		{
+		if (buf[1] == ':' && buf[2] == 'x') {
 			memcpy(buf_tmp, buf + 3, 2);
 			I("%s: read_Step = %s\n", __func__, buf_tmp);
-			if (!kstrtoul(buf_tmp, 16, &result))
-			{
-				I("%s: read_Step = %lu \n", __func__, result);
+			if (!kstrtoul(buf_tmp, 16, &result)) {
+				I("%s: read_Step = %lu\n", __func__, result);
 				setFlashReadStep(result);
 			}
 		}
-	}
-	else if (buf[0] == '1')// 1_60,1_64,1_24,1_28 for flash size 60k,64k,124k,128k
-	{
+	/* 1_60,1_64,1_24,1_28 for flash size 60k,64k,124k,128k*/
+	} else if (buf[0] == '1') {
+
 		setSysOperation(1);
 		setFlashCommand(1);
 		setFlashDumpProgress(0);
 		setFlashDumpComplete(0);
 		setFlashDumpFail(0);
-		if ((buf[1] == '_' ) && (buf[2] == '6' )){
-			if (buf[3] == '0'){
+		if ((buf[1] == '_') && (buf[2] == '6')) {
+			if (buf[3] == '0')
 				Flash_Size = FW_SIZE_60k;
-			}else if (buf[3] == '4'){
+			else if (buf[3] == '4')
 				Flash_Size = FW_SIZE_64k;
-			}
-		}else if ((buf[1] == '_' ) && (buf[2] == '2' )){
-			if (buf[3] == '4'){
+
+		} else if ((buf[1] == '_') && (buf[2] == '2')) {
+			if (buf[3] == '4')
 				Flash_Size = FW_SIZE_124k;
-			}else if (buf[3] == '8'){
+			else if (buf[3] == '8')
 				Flash_Size = FW_SIZE_128k;
-			}
 		}
 		queue_work(private_ts->flash_wq, &private_ts->flash_work);
-	}
-	else if (buf[0] == '2') // 2_60,2_64,2_24,2_28 for flash size 60k,64k,124k,128k
-	{
+	/* 2_60,2_64,2_24,2_28 for flash size 60k,64k,124k,128k*/
+	} else if (buf[0] == '2') {
 		setSysOperation(1);
 		setFlashCommand(2);
 		setFlashDumpProgress(0);
 		setFlashDumpComplete(0);
 		setFlashDumpFail(0);
-		if ((buf[1] == '_' ) && (buf[2] == '6' )){
-			if (buf[3] == '0'){
+		if ((buf[1] == '_') && (buf[2] == '6')) {
+			if (buf[3] == '0')
 				Flash_Size = FW_SIZE_60k;
-			}else if (buf[3] == '4'){
+			else if (buf[3] == '4')
 				Flash_Size = FW_SIZE_64k;
-			}
-		}else if ((buf[1] == '_' ) && (buf[2] == '2' )){
-			if (buf[3] == '4'){
+
+		} else if ((buf[1] == '_') && (buf[2] == '2')) {
+			if (buf[3] == '4')
 				Flash_Size = FW_SIZE_124k;
-			}else if (buf[3] == '8'){
+			else if (buf[3] == '8')
 				Flash_Size = FW_SIZE_128k;
-			}
+
 		}
 		queue_work(private_ts->flash_wq, &private_ts->flash_work);
-	}
-	else if (buf[0] == '3')
-	{
+	} else if (buf[0] == '3') {
 		setSysOperation(1);
 		setFlashCommand(3);
 		setFlashDumpProgress(0);
@@ -1650,20 +1568,14 @@
 
 		memcpy(buf_tmp, buf + 3, 2);
 		if (!kstrtoul(buf_tmp, 16, &result))
-		{
 			setFlashDumpSector(result);
-		}
 
 		memcpy(buf_tmp, buf + 7, 2);
 		if (!kstrtoul(buf_tmp, 16, &result))
-		{
 			setFlashDumpPage(result);
-		}
 
 		queue_work(private_ts->flash_wq, &private_ts->flash_work);
-	}
-	else if (buf[0] == '4')
-	{
+	} else if (buf[0] == '4') {
 		I("%s: command 4 enter.\n", __func__);
 		setSysOperation(1);
 		setFlashCommand(4);
@@ -1673,40 +1585,29 @@
 
 		memcpy(buf_tmp, buf + 3, 2);
 		if (!kstrtoul(buf_tmp, 16, &result))
-		{
 			setFlashDumpSector(result);
-		}
 		else
-		{
 			E("%s: command 4 , sector error.\n", __func__);
 			return len;
-		}
+
 
 		memcpy(buf_tmp, buf + 7, 2);
 		if (!kstrtoul(buf_tmp, 16, &result))
-		{
 			setFlashDumpPage(result);
-		}
 		else
-		{
 			E("%s: command 4 , page error.\n", __func__);
 			return len;
-		}
 
 		base = 11;
 
 		I("=========Himax flash page buffer start=========\n");
-		for(loop_i=0;loop_i<128 && base<80;loop_i++)
-		{
+		for (loop_i = 0 ; loop_i < 128 ; loop_i++) {
 			memcpy(buf_tmp, buf + base, 2);
-			if (!kstrtoul(buf_tmp, 16, &result))
-			{
+			if (!kstrtoul(buf_tmp, 16, &result)) {
 				flash_buffer[loop_i] = result;
-				I("%d ",flash_buffer[loop_i]);
+				I("%d ", flash_buffer[loop_i]);
 				if (loop_i % 16 == 15)
-				{
 					I("\n");
-				}
 			}
 			base += 3;
 		}
@@ -1717,8 +1618,7 @@
 	return len;
 }
 
-static const struct file_operations himax_proc_flash_ops =
-{
+const struct file_operations himax_proc_flash_ops = {
 	.owner = THIS_MODULE,
 	.read = himax_proc_flash_read,
 	.write = himax_proc_flash_write,
@@ -1728,31 +1628,44 @@
 {
 	uint8_t local_flash_command = 0;
 
-	himax_int_enable(private_ts->client->irq,0);
+	himax_int_enable(private_ts->client->irq, 0);
 	setFlashDumpGoing(true);
 
-	//sector = getFlashDumpSector();
-	//page = getFlashDumpPage();
+	/*sector = getFlashDumpSector();*/
+	/*page = getFlashDumpPage();*/
 
 	local_flash_command = getFlashCommand();
 
 	msleep(100);
 
-	I("%s: local_flash_command = %d enter.\n", __func__,local_flash_command);
+	I("%s: local_flash_command = %d enter.\n",
+	__func__, local_flash_command);
 
-	if ((local_flash_command == 1 || local_flash_command == 2)|| (local_flash_command==0x0F))
-	{
-		himax_flash_dump_func(private_ts->client, local_flash_command,Flash_Size, flash_buffer);
+	if ((local_flash_command == 1 || local_flash_command == 2)
+		|| (local_flash_command == 0x0F)) {
+		himax_flash_dump_func(private_ts->client,
+		local_flash_command, Flash_Size, flash_buffer);
 	}
 
+
 	I("Complete~~~~~~~~~~~~~~~~~~~~~~~\n");
 
-	if (local_flash_command == 2)
-	{
-		E("Flash dump failed\n");
+	if (local_flash_command == 2) {
+		struct file *fn;
+		struct filename *vts_name;
+
+		vts_name = getname_kernel(FLASH_DUMP_FILE);
+		fn = file_open_name(vts_name, O_CREAT | O_WRONLY, 0);
+		if (!IS_ERR(fn)) {
+			I("%s create file and ready to write\n", __func__);
+			fn->f_op->write(fn, flash_buffer,
+			Flash_Size * sizeof(uint8_t), &fn->f_pos);
+
+			filp_close(fn, NULL);
+		}
 	}
 
-	himax_int_enable(private_ts->client->irq,1);
+	himax_int_enable(private_ts->client->irq, 1);
 	setFlashDumpGoing(false);
 
 	setFlashDumpComplete(1);
@@ -1761,7 +1674,7 @@
 
 /*	Flash_Dump_i2c_transfer_error:
 
-	himax_int_enable(private_ts->client->irq,1);
+	himax_int_enable(private_ts->client->irq, 1);
 	setFlashDumpGoing(false);
 	setFlashDumpComplete(0);
 	setFlashDumpFail(1);
@@ -1776,53 +1689,47 @@
 static ssize_t himax_self_test_read(struct file *file, char *buf,
 	size_t len, loff_t *pos)
 {
-	int val=0x00;
+	int val = 0x00;
 	int ret = 0;
 	char *temp_buf;
 
-	I("%s: enter, %d \n", __func__, __LINE__);
-	if(!HX_PROC_SEND_FLAG)
-	{
+	I("%s:enter, %d\n", __func__, __LINE__);
+	if (!HX_PROC_SEND_FLAG) {
 		temp_buf = kzalloc(len, GFP_KERNEL);
-		if (!temp_buf) {
-			HX_PROC_SEND_FLAG=0;
-			return ret;
-		}
-		himax_int_enable(private_ts->client->irq,0);//disable irq
+		himax_int_enable(private_ts->client->irq, 0);/*disable irq*/
 		val = himax_chip_self_test(private_ts->client);
 #ifdef HX_ESD_WORKAROUND
 		HX_ESD_RESET_ACTIVATE = 1;
 #endif
-		himax_int_enable(private_ts->client->irq,1);//enable irq
+		himax_int_enable(private_ts->client->irq, 1);/*enable irq*/
 
 		if (val == 0x01) {
-			ret += snprintf(temp_buf+ret, len-ret, "Self_Test Pass\n");
+			ret += snprintf(temp_buf + ret, len,
+			"Self_Test Pass\n");
 		} else {
-			ret += snprintf(temp_buf+ret, len-ret, "Self_Test Fail\n");
+			ret += snprintf(temp_buf + ret, len,
+			"Self_Test Fail\n");
 		}
-
 		if (copy_to_user(buf, temp_buf, len))
-		{
 			I("%s,here:%d\n", __func__, __LINE__);
-		}
 
 		kfree(temp_buf);
 		HX_PROC_SEND_FLAG = 1;
-	}
-	else
-		HX_PROC_SEND_FLAG=0;
+	} else
+		HX_PROC_SEND_FLAG = 0;
 	return ret;
 }
 
 /*
-static ssize_t himax_chip_self_test_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t himax_chip_self_test_store(struct device *dev,
+struct device_attribute *attr, const char *buf, size_t count)
 {
 	char buf_tmp[2];
 	unsigned long result = 0;
 
 	memset(buf_tmp, 0x0, sizeof(buf_tmp));
 	memcpy(buf_tmp, buf, 2);
-	if(!kstrtoul(buf_tmp, 16, &result))
+	if (!kstrtoul(buf_tmp, 16, &result))
 		{
 			sel_type = (uint8_t)result;
 		}
@@ -1831,8 +1738,7 @@
 }
 */
 
-static const struct file_operations himax_proc_self_test_ops =
-{
+const struct file_operations himax_proc_self_test_ops = {
 	.owner = THIS_MODULE,
 	.read = himax_self_test_read,
 };
@@ -1844,42 +1750,33 @@
 {
 	char buf[80] = {0};
 
-	if (len >= 80)
-	{
+	if (len >= 80) {
 		I("%s: no command exceeds 80 chars.\n", __func__);
 		return -EFAULT;
 	}
 	if (copy_from_user(buf, buff, len))
-	{
 		return -EFAULT;
-	}
 
-	if(buf[0] == '0')
-	{
+	if (buf[0] == '0') {
 		himax_sense_off(private_ts->client);
-		I("Sense off \n");
-	}
-	else if(buf[0] == '1')
-	{
-		if(buf[1] == '1'){
+		I("Sense off\n");
+	} else if (buf[0] == '1') {
+		if (buf[1] == '1') {
 			himax_sense_on(private_ts->client, 0x01);
-			I("Sense on re-map off, run flash \n");
-		}else if(buf[1] == '0'){
+			I("Sense on re-map off, run flash\n");
+		} else if (buf[1] == '0') {
 			himax_sense_on(private_ts->client, 0x00);
-			I("Sense on re-map on, run sram \n");
-		}else{
-			I("Do nothing \n");
+			I("Sense on re-map on, run sram\n");
+		} else {
+			I("Do nothing\n");
 		}
-	}
-	else
-	{
-		I("Do nothing \n");
+	} else {
+		I("Do nothing\n");
 	}
 	return len;
 }
 
-static const struct file_operations himax_proc_sense_on_off_ops =
-{
+const struct file_operations himax_proc_sense_on_off_ops = {
 	.owner = THIS_MODULE,
 	.write = himax_sense_on_off_write,
 };
@@ -1893,25 +1790,18 @@
 	size_t count = 0;
 	char *temp_buf;
 
-	if(!HX_PROC_SEND_FLAG)
-	{
+	if (!HX_PROC_SEND_FLAG) {
 		temp_buf = kzalloc(len, GFP_KERNEL);
-		if (!temp_buf) {
-			HX_PROC_SEND_FLAG=0;
-			return count;
-		}
 		count = snprintf(temp_buf, len, "%d\n", ts->HSEN_enable);
-		HX_PROC_SEND_FLAG=1;
+		HX_PROC_SEND_FLAG = 1;
 
 		if (copy_to_user(buf, temp_buf, len))
-		{
 			I("%s,here:%d\n", __func__, __LINE__);
-		}
+
 
 		kfree(temp_buf);
-	}
-	else
-		HX_PROC_SEND_FLAG=0;
+	} else
+		HX_PROC_SEND_FLAG = 0;
 	return count;
 }
 
@@ -1922,22 +1812,17 @@
 	char buf[80] = {0};
 
 
-	if (len >= 80)
-	{
+	if (len >= 80) {
 		I("%s: no command exceeds 80 chars.\n", __func__);
 		return -EFAULT;
 	}
 	if (copy_from_user(buf, buff, len))
-	{
 		return -EFAULT;
-	}
 
-	if (buf[0] == '0'){
+	if (buf[0] == '0')
 		ts->HSEN_enable = 0;
-	}
-	else if (buf[0] == '1'){
+	else if (buf[0] == '1')
 		ts->HSEN_enable = 1;
-	}
 	else
 		return -EINVAL;
 
@@ -1948,8 +1833,7 @@
 	return len;
 }
 
-static const struct file_operations himax_proc_HSEN_ops =
-{
+const struct file_operations himax_proc_HSEN_ops = {
 	.owner = THIS_MODULE,
 	.read = himax_HSEN_read,
 	.write = himax_HSEN_write,
@@ -1964,25 +1848,17 @@
 	struct himax_ts_data *ts = private_ts;
 	char *temp_buf;
 
-	if(!HX_PROC_SEND_FLAG)
-	{
+	if (!HX_PROC_SEND_FLAG) {
 		temp_buf = kzalloc(len, GFP_KERNEL);
-		if (!temp_buf) {
-			HX_PROC_SEND_FLAG=0;
-			return count;
-		}
-		count = snprintf(temp_buf, len, "%d\n", ts->SMWP_enable);
+		count = snprintf(temp_buf, "%d\n", len, ts->SMWP_enable);
 
 		if (copy_to_user(buf, temp_buf, len))
-		{
 			I("%s,here:%d\n", __func__, __LINE__);
-		}
 
 		kfree(temp_buf);
-		HX_PROC_SEND_FLAG=1;
-	}
-	else
-		HX_PROC_SEND_FLAG=0;
+		HX_PROC_SEND_FLAG = 1;
+	} else
+		HX_PROC_SEND_FLAG = 0;
 
 	return count;
 }
@@ -1993,25 +1869,17 @@
 	struct himax_ts_data *ts = private_ts;
 	char buf[80] = {0};
 
-	if (len >= 80)
-	{
+	if (len >= 80) {
 		I("%s: no command exceeds 80 chars.\n", __func__);
 		return -EFAULT;
 	}
 	if (copy_from_user(buf, buff, len))
-	{
 		return -EFAULT;
-	}
-
 
 	if (buf[0] == '0')
-	{
 		ts->SMWP_enable = 0;
-	}
 	else if (buf[0] == '1')
-	{
 		ts->SMWP_enable = 1;
-	}
 	else
 		return -EINVAL;
 
@@ -2022,41 +1890,33 @@
 	return len;
 }
 
-static const struct file_operations himax_proc_SMWP_ops =
-{
+const struct file_operations himax_proc_SMWP_ops = {
 	.owner = THIS_MODULE,
 	.read = himax_SMWP_read,
 	.write = himax_SMWP_write,
 };
 
-static ssize_t himax_GESTURE_read(struct file *file, char *buf,
-	size_t len, loff_t *pos)
+static ssize_t himax_GESTURE_read(struct file *file,
+char *buf, size_t len, loff_t *pos)
 {
 	struct himax_ts_data *ts = private_ts;
-	int i =0;
+	int i = 0;
 	int ret = 0;
 	char *temp_buf;
 
-	if(!HX_PROC_SEND_FLAG)
-	{
+	if (!HX_PROC_SEND_FLAG) {
 		temp_buf = kzalloc(len, GFP_KERNEL);
-		if (!temp_buf) {
-			HX_PROC_SEND_FLAG=0;
-			return ret;
-		}
-		for(i=0;i<16;i++)
-			ret += snprintf(temp_buf+ret, len-ret, "ges_en[%d]=%d\n", i, ts->gesture_cust_en[i]);
+		for (i = 0 ; i < 16 ; i++)
+			ret += snprintf(temp_buf + ret, len,
+			"ges_en[%d]=%d\n", i, ts->gesture_cust_en[i]);
+
 		HX_PROC_SEND_FLAG = 1;
 		if (copy_to_user(buf, temp_buf, len))
-		{
 			I("%s,here:%d\n", __func__, __LINE__);
-		}
 
 		kfree(temp_buf);
 		HX_PROC_SEND_FLAG = 1;
-	}
-	else
-	{
+	} else {
 		HX_PROC_SEND_FLAG = 0;
 		ret = 0;
 	}
@@ -2067,35 +1927,30 @@
 	size_t len, loff_t *pos)
 {
 	struct himax_ts_data *ts = private_ts;
-	int i =0;
+	int i = 0;
 	char buf[80] = {0};
 
-	if (len >= 80)
-	{
+	if (len >= 80) {
 		I("%s: no command exceeds 80 chars.\n", __func__);
 		return -EFAULT;
 	}
 	if (copy_from_user(buf, buff, len))
-	{
 		return -EFAULT;
-	}
 
-	I("himax_GESTURE_store= %s \n",buf);
-	for (i=0;i<16;i++)
-	{
+	I("himax_GESTURE_store= %s\n", buf);
+	for (i = 0 ; i < 16 ; i++) {
 		if (buf[i] == '0')
-			ts->gesture_cust_en[i]= 0;
+			ts->gesture_cust_en[i] = 0;
 		else if (buf[i] == '1')
-			ts->gesture_cust_en[i]= 1;
+			ts->gesture_cust_en[i] = 1;
 		else
-			ts->gesture_cust_en[i]= 0;
-		I("gesture en[%d]=%d \n", i, ts->gesture_cust_en[i]);
+			ts->gesture_cust_en[i] = 0;
+		I("gesture en[%d]=%d\n", i, ts->gesture_cust_en[i]);
 	}
 	return len;
 }
 
-static const struct file_operations himax_proc_Gesture_ops =
-{
+const struct file_operations himax_proc_Gesture_ops = {
 	.owner = THIS_MODULE,
 	.read = himax_GESTURE_read,
 	.write = himax_GESTURE_write,
@@ -2104,202 +1959,223 @@
 
 int himax_touch_proc_init(void)
 {
-	himax_touch_proc_dir = proc_mkdir( HIMAX_PROC_TOUCH_FOLDER, NULL);
-	if (himax_touch_proc_dir == NULL)
-	{
+	himax_touch_proc_dir = proc_mkdir(HIMAX_PROC_TOUCH_FOLDER, NULL);
+	if (himax_touch_proc_dir == NULL) {
 		E(" %s: himax_touch_proc_dir file create failed!\n", __func__);
 		return -ENOMEM;
 	}
 
-	himax_proc_debug_level_file = proc_create(HIMAX_PROC_DEBUG_LEVEL_FILE, (S_IWUSR|S_IRUGO), himax_touch_proc_dir, &himax_proc_debug_level_ops);
-	if (himax_proc_debug_level_file == NULL)
-	{
+	himax_proc_debug_level_file = proc_create(HIMAX_PROC_DEBUG_LEVEL_FILE,
+	(S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_debug_level_ops);
+
+	if (himax_proc_debug_level_file == NULL) {
 		E(" %s: proc debug_level file create failed!\n", __func__);
 		goto fail_1;
 	}
 
-	himax_proc_vendor_file = proc_create(HIMAX_PROC_VENDOR_FILE, (S_IRUGO),himax_touch_proc_dir, &himax_proc_vendor_ops);
-	if(himax_proc_vendor_file == NULL)
-	{
+	himax_proc_vendor_file = proc_create(HIMAX_PROC_VENDOR_FILE,
+	(S_IRUGO), himax_touch_proc_dir, &himax_proc_vendor_ops);
+
+	if (himax_proc_vendor_file == NULL) {
 		E(" %s: proc vendor file create failed!\n", __func__);
 		goto fail_2;
 	}
 
-	himax_proc_attn_file = proc_create(HIMAX_PROC_ATTN_FILE, (S_IRUGO),himax_touch_proc_dir, &himax_proc_attn_ops);
-	if(himax_proc_attn_file == NULL)
-	{
+	himax_proc_attn_file = proc_create(HIMAX_PROC_ATTN_FILE,
+	(S_IRUGO), himax_touch_proc_dir, &himax_proc_attn_ops);
+
+	if (himax_proc_attn_file == NULL) {
 		E(" %s: proc attn file create failed!\n", __func__);
 		goto fail_3;
 	}
 
-	himax_proc_int_en_file = proc_create(HIMAX_PROC_INT_EN_FILE, (S_IWUSR|S_IRUGO), himax_touch_proc_dir, &himax_proc_int_en_ops);
-	if(himax_proc_int_en_file == NULL)
-	{
+	himax_proc_int_en_file = proc_create(HIMAX_PROC_INT_EN_FILE,
+	(S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_int_en_ops);
+
+	if (himax_proc_int_en_file == NULL) {
 		E(" %s: proc int en file create failed!\n", __func__);
 		goto fail_4;
 	}
 
-	himax_proc_layout_file = proc_create(HIMAX_PROC_LAYOUT_FILE, (S_IWUSR|S_IRUGO), himax_touch_proc_dir, &himax_proc_layout_ops);
-	if(himax_proc_layout_file == NULL)
-	{
+	himax_proc_layout_file = proc_create(HIMAX_PROC_LAYOUT_FILE,
+	(S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_layout_ops);
+
+	if (himax_proc_layout_file == NULL) {
 		E(" %s: proc layout file create failed!\n", __func__);
 		goto fail_5;
 	}
 
 #ifdef HX_TP_PROC_RESET
-	himax_proc_reset_file = proc_create(HIMAX_PROC_RESET_FILE, (S_IWUSR), himax_touch_proc_dir, &himax_proc_reset_ops);
-	if(himax_proc_reset_file == NULL)
-	{
+	himax_proc_reset_file = proc_create(HIMAX_PROC_RESET_FILE,
+	(S_IWUSR), himax_touch_proc_dir, &himax_proc_reset_ops);
+
+	if (himax_proc_reset_file == NULL) {
 		E(" %s: proc reset file create failed!\n", __func__);
 		goto fail_6;
 	}
 #endif
 
 #ifdef HX_TP_PROC_DIAG
-	himax_proc_diag_file = proc_create(HIMAX_PROC_DIAG_FILE, (S_IWUSR|S_IRUGO), himax_touch_proc_dir, &himax_proc_diag_ops);
-	if(himax_proc_diag_file == NULL)
-	{
+	himax_proc_diag_file = proc_create(HIMAX_PROC_DIAG_FILE,
+	(S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_diag_ops);
+
+	if (himax_proc_diag_file == NULL) {
 		E(" %s: proc diag file create failed!\n", __func__);
 		goto fail_7;
 	}
-	himax_proc_diag_arrange_file = proc_create(HIMAX_PROC_DIAG_ARR_FILE, (S_IWUSR|S_IRUGO), himax_touch_proc_dir, &himax_proc_diag_arrange_ops);
-	if(himax_proc_diag_arrange_file == NULL)
-	{
+	himax_proc_diag_arrange_file = proc_create(HIMAX_PROC_DIAG_ARR_FILE,
+	(S_IWUSR | S_IRUGO),
+	himax_touch_proc_dir, &himax_proc_diag_arrange_ops);
+
+	if (himax_proc_diag_arrange_file == NULL) {
 		E(" %s: proc diag file create failed!\n", __func__);
 		goto fail_7_1;
 	}
 #endif
 
 #ifdef HX_TP_PROC_REGISTER
-	himax_proc_register_file = proc_create(HIMAX_PROC_REGISTER_FILE, (S_IWUSR|S_IRUGO), himax_touch_proc_dir, &himax_proc_register_ops);
-	if(himax_proc_register_file == NULL)
-	{
+	himax_proc_register_file = proc_create(HIMAX_PROC_REGISTER_FILE,
+	(S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_register_ops);
+
+	if (himax_proc_register_file == NULL) {
 		E(" %s: proc register file create failed!\n", __func__);
 		goto fail_8;
 	}
 #endif
 
 #ifdef HX_TP_PROC_DEBUG
-	himax_proc_debug_file = proc_create(HIMAX_PROC_DEBUG_FILE, (S_IWUSR|S_IRUGO), himax_touch_proc_dir, &himax_proc_debug_ops);
-	if(himax_proc_debug_file == NULL)
-	{
+	himax_proc_debug_file = proc_create(HIMAX_PROC_DEBUG_FILE,
+	(S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_debug_ops);
+
+	if (himax_proc_debug_file == NULL) {
 		E(" %s: proc debug file create failed!\n", __func__);
 		goto fail_9;
 	}
 #endif
 
 #ifdef HX_TP_PROC_FLASH_DUMP
-	himax_proc_flash_dump_file = proc_create(HIMAX_PROC_FLASH_DUMP_FILE, (S_IWUSR|S_IRUGO), himax_touch_proc_dir, &himax_proc_flash_ops);
-	if(himax_proc_flash_dump_file == NULL)
-	{
+	himax_proc_flash_dump_file = proc_create(HIMAX_PROC_FLASH_DUMP_FILE,
+	(S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_flash_ops);
+
+	if (himax_proc_flash_dump_file == NULL) {
 		E(" %s: proc flash dump file create failed!\n", __func__);
 		goto fail_10;
 	}
 #endif
 
 #ifdef HX_TP_PROC_SELF_TEST
-	himax_proc_self_test_file = proc_create(HIMAX_PROC_SELF_TEST_FILE, (S_IRUGO), himax_touch_proc_dir, &himax_proc_self_test_ops);
-	if(himax_proc_self_test_file == NULL)
-	{
+	himax_proc_self_test_file = proc_create(HIMAX_PROC_SELF_TEST_FILE,
+	(S_IRUGO), himax_touch_proc_dir, &himax_proc_self_test_ops);
+
+	if (himax_proc_self_test_file == NULL) {
 		E(" %s: proc self_test file create failed!\n", __func__);
 		goto fail_11;
 	}
 #endif
 
 #ifdef HX_HIGH_SENSE
-	himax_proc_HSEN_file = proc_create(HIMAX_PROC_HSEN_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), himax_touch_proc_dir, &himax_proc_HSEN_ops);
-	if(himax_proc_HSEN_file == NULL)
-	{
+	himax_proc_HSEN_file = proc_create(HIMAX_PROC_HSEN_FILE,
+	(S_IWUSR | S_IRUGO | S_IWUGO),
+	himax_touch_proc_dir, &himax_proc_HSEN_ops);
+
+	if (himax_proc_HSEN_file == NULL) {
 		E(" %s: proc HSEN file create failed!\n", __func__);
 		goto fail_12;
 	}
 #endif
 
 #ifdef HX_SMART_WAKEUP
-	himax_proc_SMWP_file = proc_create(HIMAX_PROC_SMWP_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), himax_touch_proc_dir, &himax_proc_SMWP_ops);
-	if(himax_proc_SMWP_file == NULL)
-	{
+	himax_proc_SMWP_file = proc_create(HIMAX_PROC_SMWP_FILE,
+	(S_IWUSR | S_IRUGO | S_IWUGO),
+	himax_touch_proc_dir, &himax_proc_SMWP_ops);
+
+	if (himax_proc_SMWP_file == NULL) {
 		E(" %s: proc SMWP file create failed!\n", __func__);
 		goto fail_13;
 	}
-	himax_proc_GESTURE_file = proc_create(HIMAX_PROC_GESTURE_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), himax_touch_proc_dir, &himax_proc_Gesture_ops);
-	if(himax_proc_GESTURE_file == NULL)
-	{
+
+	himax_proc_GESTURE_file = proc_create(HIMAX_PROC_GESTURE_FILE,
+	(S_IWUSR | S_IRUGO | S_IWUGO),
+	himax_touch_proc_dir, &himax_proc_Gesture_ops);
+
+	if (himax_proc_GESTURE_file == NULL) {
 		E(" %s: proc GESTURE file create failed!\n", __func__);
 		goto fail_14;
 	}
 #endif
 
 #ifdef HX_TP_PROC_SENSE_ON_OFF
-	himax_proc_SENSE_ON_OFF_file = proc_create(HIMAX_PROC_SENSE_ON_OFF_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), himax_touch_proc_dir, &himax_proc_sense_on_off_ops);
-	if(himax_proc_SENSE_ON_OFF_file == NULL)
-	{
+	himax_proc_SENSE_ON_OFF_file = proc_create(HIMAX_PROC_SENSE_ON_OFF_FILE,
+	(S_IWUSR | S_IRUGO | S_IWUGO),
+	himax_touch_proc_dir, &himax_proc_sense_on_off_ops);
+
+	if (himax_proc_SENSE_ON_OFF_file == NULL) {
 		E(" %s: proc SENSE_ON_OFF file create failed!\n", __func__);
 		goto fail_15;
 	}
 #endif
 
-	return 0 ;
+	return 0;
 
 #ifdef HX_TP_PROC_SENSE_ON_OFF
-	fail_15:
+fail_15:
 #endif
 #ifdef HX_SMART_WAKEUP
-	remove_proc_entry( HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir );
-	fail_14:
-	remove_proc_entry( HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir );
-	fail_13:
+	remove_proc_entry(HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir);
+fail_14:
+	remove_proc_entry(HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir);
+fail_13:
 #endif
 #ifdef HX_HIGH_SENSE
-	remove_proc_entry( HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir );
-	fail_12:
+	remove_proc_entry(HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir);
+fail_12:
 #endif
 #ifdef HX_TP_PROC_SELF_TEST
-	remove_proc_entry( HIMAX_PROC_SELF_TEST_FILE, himax_touch_proc_dir );
-	fail_11:
+	remove_proc_entry(HIMAX_PROC_SELF_TEST_FILE, himax_touch_proc_dir);
+fail_11:
 #endif
 #ifdef HX_TP_PROC_FLASH_DUMP
-	remove_proc_entry( HIMAX_PROC_FLASH_DUMP_FILE, himax_touch_proc_dir );
-	fail_10:
+	remove_proc_entry(HIMAX_PROC_FLASH_DUMP_FILE, himax_touch_proc_dir);
+fail_10:
 #endif
 #ifdef HX_TP_PROC_DEBUG
-	remove_proc_entry( HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir );
-	fail_9:
+	remove_proc_entry(HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir);
+fail_9:
 #endif
 #ifdef HX_TP_PROC_REGISTER
-	remove_proc_entry( HIMAX_PROC_REGISTER_FILE, himax_touch_proc_dir );
-	fail_8:
+	remove_proc_entry(HIMAX_PROC_REGISTER_FILE, himax_touch_proc_dir);
+fail_8:
 #endif
 #ifdef HX_TP_PROC_DIAG
-	remove_proc_entry( HIMAX_PROC_DIAG_FILE, himax_touch_proc_dir );
-	fail_7:
-	remove_proc_entry( HIMAX_PROC_DIAG_ARR_FILE, himax_touch_proc_dir );
-	fail_7_1:
+	remove_proc_entry(HIMAX_PROC_DIAG_FILE, himax_touch_proc_dir);
+fail_7:
+	remove_proc_entry(HIMAX_PROC_DIAG_ARR_FILE, himax_touch_proc_dir);
+fail_7_1:
 #endif
 #ifdef HX_TP_PROC_RESET
-	remove_proc_entry( HIMAX_PROC_RESET_FILE, himax_touch_proc_dir );
-	fail_6:
+	remove_proc_entry(HIMAX_PROC_RESET_FILE, himax_touch_proc_dir);
+fail_6:
 #endif
-	remove_proc_entry( HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir );
-	fail_5: remove_proc_entry( HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir );
-	fail_4: remove_proc_entry( HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir );
-	fail_3: remove_proc_entry( HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir );
-	fail_2: remove_proc_entry( HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir );
-	fail_1: remove_proc_entry( HIMAX_PROC_TOUCH_FOLDER, NULL );
+	remove_proc_entry(HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir);
+fail_5: remove_proc_entry(HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir);
+fail_4: remove_proc_entry(HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir);
+fail_3: remove_proc_entry(HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir);
+fail_2: remove_proc_entry(HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir);
+fail_1: remove_proc_entry(HIMAX_PROC_TOUCH_FOLDER, NULL);
 	return -ENOMEM;
 }
 
 void himax_touch_proc_deinit(void)
 {
 #ifdef HX_TP_PROC_SENSE_ON_OFF
-	remove_proc_entry( HIMAX_PROC_SENSE_ON_OFF_FILE, himax_touch_proc_dir );
+	remove_proc_entry(HIMAX_PROC_SENSE_ON_OFF_FILE, himax_touch_proc_dir);
 #endif
 #ifdef HX_SMART_WAKEUP
-	remove_proc_entry( HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir );
-	remove_proc_entry( HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir );
+	remove_proc_entry(HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir);
+	remove_proc_entry(HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir);
 #endif
 #ifdef HX_DOT_VIEW
-	remove_proc_entry( HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir );
+	remove_proc_entry(HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir);
 #endif
 #ifdef HX_TP_PROC_SELF_TEST
 	remove_proc_entry(HIMAX_PROC_SELF_TEST_FILE, himax_touch_proc_dir);
@@ -2308,7 +2184,7 @@
 	remove_proc_entry(HIMAX_PROC_FLASH_DUMP_FILE, himax_touch_proc_dir);
 #endif
 #ifdef HX_TP_PROC_DEBUG
-	remove_proc_entry( HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir );
+	remove_proc_entry(HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir);
 #endif
 #ifdef HX_TP_PROC_REGISTER
 	remove_proc_entry(HIMAX_PROC_REGISTER_FILE, himax_touch_proc_dir);
@@ -2317,13 +2193,13 @@
 	remove_proc_entry(HIMAX_PROC_DIAG_FILE, himax_touch_proc_dir);
 #endif
 #ifdef HX_TP_PROC_RESET
-	remove_proc_entry( HIMAX_PROC_RESET_FILE, himax_touch_proc_dir );
+	remove_proc_entry(HIMAX_PROC_RESET_FILE, himax_touch_proc_dir);
 #endif
-	remove_proc_entry( HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir );
-	remove_proc_entry( HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir );
-	remove_proc_entry( HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir );
-	remove_proc_entry( HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir );
-	remove_proc_entry( HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir );
-	remove_proc_entry( HIMAX_PROC_TOUCH_FOLDER, NULL );
+	remove_proc_entry(HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir);
+	remove_proc_entry(HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir);
+	remove_proc_entry(HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir);
+	remove_proc_entry(HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir);
+	remove_proc_entry(HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir);
+	remove_proc_entry(HIMAX_PROC_TOUCH_FOLDER, NULL);
 }
 #endif
diff --git a/drivers/input/touchscreen/hxchipset/himax_debug.h b/drivers/input/touchscreen/hxchipset/himax_debug.h
index 91a7ae2..7a24a17 100644
--- a/drivers/input/touchscreen/hxchipset/himax_debug.h
+++ b/drivers/input/touchscreen/hxchipset/himax_debug.h
@@ -17,7 +17,7 @@
 #include "himax_common.h"
 
 #if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
-	#define HIMAX_PROC_TOUCH_FOLDER 	"android_touch"
+	#define HIMAX_PROC_TOUCH_FOLDER	"android_touch"
 	#define HIMAX_PROC_DEBUG_LEVEL_FILE	"debug_level"
 	#define HIMAX_PROC_VENDOR_FILE		"vendor"
 	#define HIMAX_PROC_ATTN_FILE		"attn"
@@ -33,60 +33,76 @@
 
 	uint8_t HX_PROC_SEND_FLAG;
 
-extern int himax_touch_proc_init(void);
-extern void himax_touch_proc_deinit(void);
-bool getFlashDumpGoing(void);
+	extern int himax_touch_proc_init(void);
+	extern void himax_touch_proc_deinit(void);
+	bool getFlashDumpGoing(void);
+
+	extern struct himax_ic_data *ic_data;
+	extern struct himax_ts_data *private_ts;
+	extern unsigned char	IC_TYPE;
+	extern unsigned char	IC_CHECKSUM;
+
+#ifdef QCT
+	extern irqreturn_t himax_ts_thread(int irq, void *ptr);
+#endif
+#ifdef MTK
+#ifdef CONFIG_OF_TOUCH
+	extern irqreturn_t tpd_eint_interrupt_handler(int irq, void *desc);
+#else
+	extern void tpd_eint_interrupt_handler(void);
+#endif
+#endif
 
 #ifdef HX_TP_PROC_REGISTER
 	#define HIMAX_PROC_REGISTER_FILE	"register"
-	struct proc_dir_entry *himax_proc_register_file;
+	struct proc_dir_entry *himax_proc_register_file = NULL;
 	uint8_t register_command[4];
 #endif
 
 #ifdef HX_TP_PROC_DIAG
 	#define HIMAX_PROC_DIAG_FILE	"diag"
-	struct proc_dir_entry *himax_proc_diag_file;
+	struct proc_dir_entry *himax_proc_diag_file = NULL;
 	#define HIMAX_PROC_DIAG_ARR_FILE	"diag_arr"
-	struct proc_dir_entry *himax_proc_diag_arrange_file;
+	struct proc_dir_entry *himax_proc_diag_arrange_file = NULL;
 
 #ifdef HX_TP_PROC_2T2R
 	static bool Is_2T2R;
 	static uint8_t x_channel_2;
 	static uint8_t y_channel_2;
 	static uint8_t *diag_mutual_2;
-	
-	int16_t *getMutualBuffer_2(void);
-	uint8_t 	getXChannel_2(void);
-	uint8_t 	getYChannel_2(void);
-	
-	void 	setMutualBuffer_2(void);
-	void 	setXChannel_2(uint8_t x);
-	void 	setYChannel_2(uint8_t y);
-#endif
-	uint8_t x_channel;
-	uint8_t y_channel;
-	int16_t *diag_mutual;
-	int16_t *diag_mutual_new;
-	int16_t *diag_mutual_old;
-	uint8_t diag_max_cnt;
 
-	int diag_command;
-	uint8_t diag_coor[128];// = {0xFF};
+	int16_t *getMutualBuffer_2(void);
+	uint8_t	getXChannel_2(void);
+	uint8_t	getYChannel_2(void);
+
+	void	setMutualBuffer_2(void);
+	void	setXChannel_2(uint8_t x);
+	void	setYChannel_2(uint8_t y);
+#endif
+	uint8_t x_channel	= 0;
+	uint8_t y_channel	= 0;
+	int16_t *diag_mutual = NULL;
+	int16_t *diag_mutual_new = NULL;
+	int16_t *diag_mutual_old = NULL;
+	uint8_t diag_max_cnt = 0;
+
+	int diag_command = 0;
+	uint8_t diag_coor[128];/* = {0xFF};*/
 	int16_t diag_self[100] = {0};
 
 	int16_t *getMutualBuffer(void);
 	int16_t *getMutualNewBuffer(void);
 	int16_t *getMutualOldBuffer(void);
 	int16_t *getSelfBuffer(void);
-	uint8_t 	getDiagCommand(void);
-	uint8_t 	getXChannel(void);
-	uint8_t 	getYChannel(void);
-	
-	void 	setMutualBuffer(void);
-	void 	setMutualNewBuffer(void);
-	void 	setMutualOldBuffer(void);
-	void 	setXChannel(uint8_t x);
-	void 	setYChannel(uint8_t y);
+	uint8_t	getDiagCommand(void);
+	uint8_t	getXChannel(void);
+	uint8_t	getYChannel(void);
+
+	void	setMutualBuffer(void);
+	void	setMutualNewBuffer(void);
+	void	setMutualOldBuffer(void);
+	void	setXChannel(uint8_t x);
+	void	setYChannel(uint8_t y);
 	uint8_t	coordinate_dump_enable = 0;
 	struct file	*coordinate_fn;
 #endif
@@ -106,24 +122,24 @@
 	struct proc_dir_entry *himax_proc_flash_dump_file = NULL;
 
 	static int Flash_Size = 131072;
-	static uint8_t *flash_buffer 				= NULL;
-	static uint8_t flash_command 				= 0;
-	static uint8_t flash_read_step 			= 0;
-	static uint8_t flash_progress 			= 0;
-	static uint8_t flash_dump_complete	= 0;
-	static uint8_t flash_dump_fail 			= 0;
-	static uint8_t sys_operation				= 0;
-	static uint8_t flash_dump_sector	 	= 0;
-	static uint8_t flash_dump_page 			= 0;
-	static bool    flash_dump_going			= false;
+	static uint8_t *flash_buffer;
+	static uint8_t flash_command;
+	static uint8_t flash_read_step;
+	static uint8_t flash_progress;
+	static uint8_t flash_dump_complete;
+	static uint8_t flash_dump_fail;
+	static uint8_t sys_operation;
+	static uint8_t flash_dump_sector;
+	static uint8_t flash_dump_page;
+	static bool    flash_dump_going;
 
 	static uint8_t getFlashCommand(void);
 	static uint8_t getFlashDumpComplete(void);
 	static uint8_t getFlashDumpFail(void);
 	static uint8_t getFlashDumpProgress(void);
 	static uint8_t getFlashReadStep(void);
-	//static uint8_t getFlashDumpSector(void);
-	//static uint8_t getFlashDumpPage(void);
+	/*static uint8_t getFlashDumpSector(void);*/
+	/*static uint8_t getFlashDumpPage(void);*/
 
 	void setFlashBuffer(void);
 	uint8_t getSysOperation(void);
@@ -150,8 +166,8 @@
 
 #ifdef HX_TP_PROC_RESET
 #define HIMAX_PROC_RESET_FILE		"reset"
-extern void himax_HW_reset(uint8_t loadconfig,uint8_t int_off);
-struct proc_dir_entry *himax_proc_reset_file 		= NULL;
+extern void himax_HW_reset(uint8_t loadconfig, uint8_t int_off);
+struct proc_dir_entry *himax_proc_reset_file;
 #endif
 
 #ifdef HX_HIGH_SENSE
@@ -165,16 +181,16 @@
 #endif
 
 #ifdef HX_RST_PIN_FUNC
-	void himax_HW_reset(uint8_t loadconfig,uint8_t int_off);
+	void himax_HW_reset(uint8_t loadconfig, uint8_t int_off);
 #endif
 
 #ifdef HX_SMART_WAKEUP
 #define HIMAX_PROC_SMWP_FILE "SMWP"
-struct proc_dir_entry *himax_proc_SMWP_file = NULL;
+struct proc_dir_entry *himax_proc_SMWP_file;
 #define HIMAX_PROC_GESTURE_FILE "GESTURE"
-struct proc_dir_entry *himax_proc_GESTURE_file = NULL;
-uint8_t HX_SMWP_EN = 0;
-//extern bool FAKE_POWER_KEY_SEND;
+struct proc_dir_entry *himax_proc_GESTURE_file;
+uint8_t HX_SMWP_EN;
+/*extern bool FAKE_POWER_KEY_SEND;*/
 #endif
 
 #endif
diff --git a/drivers/input/touchscreen/hxchipset/himax_ic.c b/drivers/input/touchscreen/hxchipset/himax_ic.c
index 6ad8dc0..e2934c2 100644
--- a/drivers/input/touchscreen/hxchipset/himax_ic.c
+++ b/drivers/input/touchscreen/hxchipset/himax_ic.c
@@ -15,45 +15,31 @@
 
 #include "himax_ic.h"
 
-static unsigned char i_TP_CRC_FW_128K[]=
-{
-	#include "HX_CRC_128.i"
-};
-static unsigned char i_TP_CRC_FW_64K[]=
-{
-	#include "HX_CRC_64.i"
-};
-static unsigned char i_TP_CRC_FW_124K[]=
-{
-	#include "HX_CRC_124.i"
-};
-static unsigned char i_TP_CRC_FW_60K[]=
-{
-	#include "HX_CRC_60.i"
-};
+const struct firmware *i_TP_CRC_FW_128K;
+const struct firmware *i_TP_CRC_FW_64K;
+const struct firmware *i_TP_CRC_FW_124K;
+const struct firmware *i_TP_CRC_FW_60K;
 
+unsigned long FW_VER_MAJ_FLASH_ADDR;
+unsigned long FW_VER_MAJ_FLASH_LENG;
+unsigned long FW_VER_MIN_FLASH_ADDR;
+unsigned long FW_VER_MIN_FLASH_LENG;
+unsigned long CFG_VER_MAJ_FLASH_ADDR;
+unsigned long CFG_VER_MAJ_FLASH_LENG;
+unsigned long CFG_VER_MIN_FLASH_ADDR;
+unsigned long CFG_VER_MIN_FLASH_LENG;
 
-unsigned long	FW_VER_MAJ_FLASH_ADDR;
-unsigned long 	FW_VER_MAJ_FLASH_LENG;
-unsigned long 	FW_VER_MIN_FLASH_ADDR;
-unsigned long 	FW_VER_MIN_FLASH_LENG;
-unsigned long 	CFG_VER_MAJ_FLASH_ADDR;
-unsigned long 	CFG_VER_MAJ_FLASH_LENG;
-unsigned long 	CFG_VER_MIN_FLASH_ADDR;
-unsigned long 	CFG_VER_MIN_FLASH_LENG;
+unsigned char IC_TYPE;
+unsigned char IC_CHECKSUM;
 
-unsigned char	IC_TYPE = 0;
-unsigned char	IC_CHECKSUM = 0;
-
-extern struct himax_ic_data* ic_data;
-
-int himax_hand_shaking(struct i2c_client *client)    //0:Running, 1:Stop, 2:I2C Fail
+ /*0:Running, 1:Stop, 2:I2C Fail*/
+int himax_hand_shaking(struct i2c_client *client)
 {
 	int ret, result;
 	uint8_t hw_reset_check[1];
 	uint8_t hw_reset_check_2[1];
 	uint8_t buf0[2];
-	uint8_t	IC_STATUS_CHECK = 0xAA;	
+	uint8_t	IC_STATUS_CHECK = 0xAA;
 
 	memset(hw_reset_check, 0x00, sizeof(hw_reset_check));
 	memset(hw_reset_check_2, 0x00, sizeof(hw_reset_check_2));
@@ -67,45 +53,50 @@
 		IC_STATUS_CHECK = 0xAA;
 	}
 
-	ret = i2c_himax_master_write(client, buf0, 2, HIMAX_I2C_RETRY_TIMES);
+	ret = i2c_himax_master_write(client,
+	buf0, 2, HIMAX_I2C_RETRY_TIMES);
 	if (ret < 0) {
-		E("[Himax]:write 0xF2 failed line: %d \n",__LINE__);
+		E("[Himax]:write 0xF2 failed line: %d\n", __LINE__);
 		goto work_func_send_i2c_msg_fail;
 	}
-	msleep(50); 
-  	
+	msleep(50);
+
 	buf0[0] = 0xF2;
 	buf0[1] = 0x00;
-	ret = i2c_himax_master_write(client, buf0, 2, HIMAX_I2C_RETRY_TIMES);
+	ret = i2c_himax_master_write(client,
+	buf0, 2, HIMAX_I2C_RETRY_TIMES);
 	if (ret < 0) {
-		E("[Himax]:write 0x92 failed line: %d \n",__LINE__);
+		E("[Himax]:write 0x92 failed line: %d\n", __LINE__);
 		goto work_func_send_i2c_msg_fail;
 	}
-	usleep_range(2000, 4000);
-  	
-	ret = i2c_himax_read(client, 0xD1, hw_reset_check, 1, HIMAX_I2C_RETRY_TIMES);
+	usleep_range(1999, 2000);
+
+	ret = i2c_himax_read(client, 0xD1,
+	hw_reset_check, 1, HIMAX_I2C_RETRY_TIMES);
 	if (ret < 0) {
-		E("[Himax]:i2c_himax_read 0xD1 failed line: %d \n",__LINE__);
+		E("[Himax]:i2c_himax_read 0xD1 failed line: %d\n", __LINE__);
 		goto work_func_send_i2c_msg_fail;
 	}
-	
-	if ((IC_STATUS_CHECK != hw_reset_check[0])) {
-		usleep_range(2000, 4000);
-		ret = i2c_himax_read(client, 0xD1, hw_reset_check_2, 1, HIMAX_I2C_RETRY_TIMES);
+
+	if (IC_STATUS_CHECK != hw_reset_check[0]) {
+		usleep_range(1999, 2000);
+		ret = i2c_himax_read(client, 0xD1,
+		hw_reset_check_2, 1, HIMAX_I2C_RETRY_TIMES);
 		if (ret < 0) {
-			E("[Himax]:i2c_himax_read 0xD1 failed line: %d \n",__LINE__);
+			E("[Himax]:i2c_himax_read 0xD1 failed line: %d\n",
+			__LINE__);
 			goto work_func_send_i2c_msg_fail;
 		}
-	
-		if (hw_reset_check[0] == hw_reset_check_2[0]) {
-			result = 1; 
-		} else {
-			result = 0; 
-		}
+
+		if (hw_reset_check[0] == hw_reset_check_2[0])
+			result = 1;
+		else
+			result = 0;
+
 	} else {
-		result = 0; 
+		result = 0;
 	}
-	
+
 	return result;
 
 work_func_send_i2c_msg_fail:
@@ -117,66 +108,71 @@
 	uint8_t tmp_addr[4];
 	uint8_t tmp_data[4];
 
-	if(diag_command != 0)
+	if (diag_command != 0)
 		diag_command = diag_command + 5;
 
-	tmp_addr[3] = 0x80; tmp_addr[2] = 0x02; tmp_addr[1] = 0x01; tmp_addr[0] = 0x80;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = diag_command;
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x02;
+	tmp_addr[1] = 0x01; tmp_addr[0] = 0x80;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = diag_command;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 }
 
-void himax_flash_dump_func(struct i2c_client *client, uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer)
+void himax_flash_dump_func(struct i2c_client *client,
+uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer)
 {
-	//struct himax_ts_data *ts = container_of(work, struct himax_ts_data, flash_work);
-
-//	uint8_t sector = 0;
-//	uint8_t page = 0;
+	/*struct himax_ts_data *ts =
+	container_of(work, struct himax_ts_data, flash_work);*/
+	/*uint8_t sector = 0;*/
+	/*uint8_t page = 0;*/
 	uint8_t tmp_addr[4];
 	uint8_t tmp_data[4];
 	uint8_t out_buffer[20];
-	uint8_t in_buffer[260] = {0};
+	uint8_t in_buffer[260];
 	int page_prog_start = 0;
 	int i = 0;
 
 	himax_sense_off(client);
 	himax_burst_enable(client, 0);
 	/*=============Dump Flash Start=============*/
-	//=====================================
-	// SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
-	//=====================================
-	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x02; tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+	/*=====================================*/
+	/* SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780*/
+	/*=====================================*/
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+	tmp_data[1] = 0x07; tmp_data[0] = 0x80;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-	for (page_prog_start = 0; page_prog_start < Flash_Size; page_prog_start = page_prog_start + 256)
-	{
-		//=================================
-		// SPI Transfer Control
-		// Set 256 bytes page read : 0x8000_0020 ==> 0x6940_02FF
-		// Set read start address  : 0x8000_0028 ==> 0x0000_0000
-		// Set command			   : 0x8000_0024 ==> 0x0000_003B
-		//=================================
-		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
-		tmp_data[3] = 0x69; tmp_data[2] = 0x40; tmp_data[1] = 0x02; tmp_data[0] = 0xFF;
+	for (page_prog_start = 0 ; page_prog_start < Flash_Size;
+		page_prog_start = page_prog_start + 256) {
+		/*=====================================
+		SPI Transfer Control
+		Set 256 bytes page read : 0x8000_0020 ==> 0x6940_02FF
+		Set read start address  : 0x8000_0028 ==> 0x0000_0000
+		Set command			   : 0x8000_0024 ==> 0x0000_003B
+		=====================================*/
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+		tmp_data[3] = 0x69; tmp_data[2] = 0x40;
+		tmp_data[1] = 0x02; tmp_data[0] = 0xFF;
 		himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
-		if (page_prog_start < 0x100)
-		{
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
+		if (page_prog_start < 0x100) {
 			tmp_data[3] = 0x00;
 			tmp_data[2] = 0x00;
 			tmp_data[1] = 0x00;
 			tmp_data[0] = (uint8_t)page_prog_start;
-		}
-		else if (page_prog_start >= 0x100 && page_prog_start < 0x10000)
-		{
+		} else if (page_prog_start >= 0x100
+			&& page_prog_start < 0x10000) {
 			tmp_data[3] = 0x00;
 			tmp_data[2] = 0x00;
 			tmp_data[1] = (uint8_t)(page_prog_start >> 8);
 			tmp_data[0] = (uint8_t)page_prog_start;
-		}
-		else if (page_prog_start >= 0x10000 && page_prog_start < 0x1000000)
-		{
+		} else if (page_prog_start >= 0x10000
+			&& page_prog_start < 0x1000000) {
 			tmp_data[3] = 0x00;
 			tmp_data[2] = (uint8_t)(page_prog_start >> 16);
 			tmp_data[1] = (uint8_t)(page_prog_start >> 8);
@@ -184,43 +180,46 @@
 		}
 		himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
-		tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x3B;
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+		tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+		tmp_data[1] = 0x00; tmp_data[0] = 0x3B;
 		himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-		//==================================
-		// AHB_I2C Burst Read
-		// Set SPI data register : 0x8000_002C ==> 0x00
-		//==================================
+		/*=====================================
+		AHB_I2C Burst Read
+		Set SPI data register : 0x8000_002C ==> 0x00
+		=====================================*/
 		out_buffer[0] = 0x2C;
 		out_buffer[1] = 0x00;
 		out_buffer[2] = 0x00;
 		out_buffer[3] = 0x80;
-		i2c_himax_write(client, 0x00 ,out_buffer, 4, 3);
+		i2c_himax_write(client, 0x00, out_buffer, 4, 3);
 
-		//==================================
-		// Read access : 0x0C ==> 0x00
-		//==================================
+		/*=====================================
+		Read access : 0x0C ==> 0x00
+		=====================================*/
 		out_buffer[0] = 0x00;
-		i2c_himax_write(client, 0x0C ,out_buffer, 1, 3);
+		i2c_himax_write(client, 0x0C, out_buffer, 1, 3);
 
-		//==================================
-		// Read 128 bytes two times
-		//==================================
-		i2c_himax_read(client, 0x08 ,in_buffer, 128, 3);
-		for (i = 0; i < 128; i++)
-			flash_buffer[i + page_prog_start] = in_buffer[i];
+		/*=====================================
+		Read 128 bytes two times
+		=====================================*/
+		i2c_himax_read(client, 0x08, in_buffer, 128, 3);
+		for (i = 0 ; i < 128 ; i++)
+			flash_buffer[i + page_prog_start]
+			= in_buffer[i];
 
-		i2c_himax_read(client, 0x08 ,in_buffer, 128, 3);
-		for (i = 0; i < 128; i++)
-			flash_buffer[(i + 128) + page_prog_start] = in_buffer[i];
+		i2c_himax_read(client, 0x08 , in_buffer, 128, 3);
+		for (i = 0 ; i < 128 ; i++)
+			flash_buffer[(i + 128) + page_prog_start]
+			= in_buffer[i];
 
 		I("%s:Verify Progress: %x\n", __func__, page_prog_start);
 	}
 
 /*=============Dump Flash End=============*/
-		//msleep(100);
-		/*
+		/*//msleep(100);
 		for( i=0 ; i<8 ;i++)
 		{
 			for(j=0 ; j<64 ; j++)
@@ -239,7 +238,7 @@
 {
 	uint8_t tmp_addr[4];
 	uint8_t tmp_data[128];
-	int pf_value=0x00;
+	int pf_value = 0x00;
 	uint8_t test_result_id = 0;
 	int j;
 
@@ -249,19 +248,24 @@
 	himax_interface_on(client);
 	himax_sense_off(client);
 
-	//Set criteria
+	/*Set criteria*/
 	himax_burst_enable(client, 1);
 
-	tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x94;
-	tmp_data[3] = 0x14; tmp_data[2] = 0xC8; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
-	tmp_data[7] = 0x13; tmp_data[6] = 0x60; tmp_data[5] = 0x0A; tmp_data[4] = 0x99;
+	tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+	tmp_addr[1] = 0x80; tmp_addr[0] = 0x94;
+	tmp_data[3] = 0x14; tmp_data[2] = 0xC8;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+	tmp_data[7] = 0x13; tmp_data[6] = 0x60;
+	tmp_data[5] = 0x0A; tmp_data[4] = 0x99;
 
-	himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 8);
+	himax_flash_write_burst_length(client, tmp_addr, tmp_data, 8);
 
-	//start selftest
-	// 0x9008_805C ==> 0x0000_0001
-	tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x5C;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x01;
+	/*start selftest*/
+	/* 0x9008_805C ==> 0x0000_0001*/
+	tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+	tmp_addr[1] = 0x80; tmp_addr[0] = 0x5C;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x01;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 
 	himax_sense_on(client, 1);
@@ -271,19 +275,21 @@
 	himax_sense_off(client);
 	msleep(20);
 
-	//=====================================
-	// Read test result ID : 0x9008_8078 ==> 0xA/0xB/0xC/0xF
-	//=====================================
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
-	tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x78;
+	/*=====================================
+	Read test result ID : 0x9008_8078 ==> 0xA/0xB/0xC/0xF
+	=====================================*/
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+	tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+	tmp_addr[1] = 0x80; tmp_addr[0] = 0x78;
 	himax_register_read(client, tmp_addr, 1, tmp_data);
 
 	test_result_id = tmp_data[0];
 
-	I("%s: check test result, test_result_id=%x, test_result=%x\n", __func__
-	,test_result_id,tmp_data[0]);
+	I("%s: check test result, test_result_id=%x, test_result=%x\n",
+	__func__ , test_result_id, tmp_data[0]);
 
-	if (test_result_id==0xF) {
+	if (test_result_id == 0xF) {
 		I("[Himax]: self-test pass\n");
 		pf_value = 0x1;
 	} else {
@@ -292,22 +298,28 @@
 	}
 	himax_burst_enable(client, 1);
 
-	for (j = 0;j < 10; j++){
-		tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
-		tmp_addr[3] = 0x90; tmp_addr[2] = 0x06; tmp_addr[1] = 0x00; tmp_addr[0] = 0x0C;
+	for (j = 0 ; j < 10 ; j++) {
+		tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+		tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+		tmp_addr[3] = 0x90; tmp_addr[2] = 0x06;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x0C;
 		himax_register_read(client, tmp_addr, 1, tmp_data);
 		I("[Himax]: 9006000C = %d\n", tmp_data[0]);
-		if (tmp_data[0] != 0){
-		tmp_data[3] = 0x90; tmp_data[2] = 0x06; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
-		if ( i2c_himax_write(client, 0x00 ,tmp_data, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
-			E("%s: i2c access fail!\n", __func__);
-		}
-		tmp_data[0] = 0x00;
-		if ( i2c_himax_write(client, 0x0C ,tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
-			E("%s: i2c access fail!\n", __func__);
-		}
-			i2c_himax_read(client, 0x08, tmp_data, 124,HIMAX_I2C_RETRY_TIMES);
-		}else{
+		if (tmp_data[0] != 0) {
+			tmp_data[3] = 0x90; tmp_data[2] = 0x06;
+			tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+			if (i2c_himax_write(client, 0x00,
+			tmp_data, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+				E("%s: i2c access fail!\n", __func__);
+			}
+			tmp_data[0] = 0x00;
+			if (i2c_himax_write(client, 0x0C,
+			tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+				E("%s: i2c access fail!\n", __func__);
+			}
+				i2c_himax_read(client, 0x08,
+				tmp_data, 124, HIMAX_I2C_RETRY_TIMES);
+		} else {
 			break;
 		}
 	}
@@ -324,15 +336,18 @@
 	uint8_t tmp_data[4];
 
 	himax_burst_enable(client, 0);
-	tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x50;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = HSEN_enable;
+	tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+	tmp_addr[1] = 0x80; tmp_addr[0] = 0x50;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = HSEN_enable;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 }
-void himax_get_HSEN_enable(struct i2c_client *client,uint8_t *tmp_data)
+void himax_get_HSEN_enable(struct i2c_client *client, uint8_t *tmp_data)
 {
 	uint8_t tmp_addr[4];
 
-	tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x50;
+	tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+	tmp_addr[1] = 0x80; tmp_addr[0] = 0x50;
 	himax_register_read(client, tmp_addr, 1, tmp_data);
 }
 
@@ -341,206 +356,232 @@
 	uint8_t tmp_addr[4];
 	uint8_t tmp_data[4];
 
-	tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x54;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = SMWP_enable;
+	tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+	tmp_addr[1] = 0x80; tmp_addr[0] = 0x54;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = SMWP_enable;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 }
 
-void himax_get_SMWP_enable(struct i2c_client *client,uint8_t *tmp_data)
+void himax_get_SMWP_enable(struct i2c_client *client,
+uint8_t *tmp_data)
 {
 	uint8_t tmp_addr[4];
 
-	tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x54;
+	tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+	tmp_addr[1] = 0x80; tmp_addr[0] = 0x54;
 	himax_register_read(client, tmp_addr, 1, tmp_data);
 }
 
 int himax_burst_enable(struct i2c_client *client, uint8_t auto_add_4_byte)
 {
 	uint8_t tmp_data[4];
+	int err = -1;
 
 	tmp_data[0] = 0x31;
-	if ( i2c_himax_write(client, 0x13 ,tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+
+	if (i2c_himax_write(client, 0x13,
+	tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
-		return -EBUSY;
+		return err;
 	}
-	
+
 	tmp_data[0] = (0x10 | auto_add_4_byte);
-	if ( i2c_himax_write(client, 0x0D ,tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(client, 0x0D,
+	tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
-		return -EBUSY;
+		return err;
 	}
 	return 0;
 
 }
 
-void himax_register_read(struct i2c_client *client, uint8_t *read_addr, int read_length, uint8_t *read_data)
+void himax_register_read(struct i2c_client *client,
+uint8_t *read_addr, int read_length, uint8_t *read_data)
 {
 	uint8_t tmp_data[4];
 	int i = 0;
 	int address = 0;
 
-	if(read_length>256)
-	{
+	if (read_length > 256) {
 		E("%s: read len over 256!\n", __func__);
 		return;
 	}
 	if (read_length > 1)
 		himax_burst_enable(client, 1);
 	else
-	himax_burst_enable(client, 0);
-	address = (read_addr[3] << 24) + (read_addr[2] << 16) + (read_addr[1] << 8) + read_addr[0];
+		himax_burst_enable(client, 0);
+
+	address = (read_addr[3] << 24) +
+	(read_addr[2] << 16) +
+	(read_addr[1] << 8) +
+	read_addr[0];
+
 	i = address;
-		tmp_data[0] = (uint8_t)i;
-		tmp_data[1] = (uint8_t)(i >> 8);
-		tmp_data[2] = (uint8_t)(i >> 16);
-		tmp_data[3] = (uint8_t)(i >> 24);
-		if ( i2c_himax_write(client, 0x00 ,tmp_data, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
-				E("%s: i2c access fail!\n", __func__);
-				return;
-		 	}
-		tmp_data[0] = 0x00;
-		if ( i2c_himax_write(client, 0x0C ,tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
-				E("%s: i2c access fail!\n", __func__);
-				return;
-		 	}
-		
-		if ( i2c_himax_read(client, 0x08 ,read_data, read_length * 4, HIMAX_I2C_RETRY_TIMES) < 0) {
-			E("%s: i2c access fail!\n", __func__);
-			return;
-		}
+	tmp_data[0] = (uint8_t)i;
+	tmp_data[1] = (uint8_t)(i >> 8);
+	tmp_data[2] = (uint8_t)(i >> 16);
+	tmp_data[3] = (uint8_t)(i >> 24);
+	if (i2c_himax_write(client, 0x00,
+	tmp_data, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+		E("%s: i2c access fail!\n", __func__);
+		return;
+	}
+	tmp_data[0] = 0x00;
+	if (i2c_himax_write(client, 0x0C,
+	tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+		E("%s: i2c access fail!\n", __func__);
+		return;
+	}
+	if (i2c_himax_read(client, 0x08,
+	read_data, read_length * 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+		E("%s: i2c access fail!\n", __func__);
+		return;
+	}
 	if (read_length > 1)
 		himax_burst_enable(client, 0);
 }
 
-void himax_flash_read(struct i2c_client *client, uint8_t *reg_byte, uint8_t *read_data)
+void himax_flash_read(struct i2c_client *client,
+uint8_t *reg_byte, uint8_t *read_data)
 {
-    uint8_t tmpbyte[2];
-    
-    if ( i2c_himax_write(client, 0x00 ,&reg_byte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	uint8_t tmpbyte[2];
+
+	if (i2c_himax_write(client, 0x00,
+	&reg_byte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_write(client, 0x01 ,&reg_byte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(client, 0x01,
+	&reg_byte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_write(client, 0x02 ,&reg_byte[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(client, 0x02,
+	&reg_byte[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_write(client, 0x03 ,&reg_byte[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(client, 0x03,
+	&reg_byte[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-    tmpbyte[0] = 0x00;
-    if ( i2c_himax_write(client, 0x0C ,&tmpbyte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	tmpbyte[0] = 0x00;
+	if (i2c_himax_write(client, 0x0C,
+	&tmpbyte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_read(client, 0x08 ,&read_data[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_read(client, 0x08,
+	&read_data[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_read(client, 0x09 ,&read_data[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_read(client, 0x09,
+	&read_data[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_read(client, 0x0A ,&read_data[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_read(client, 0x0A,
+	&read_data[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_read(client, 0x0B ,&read_data[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_read(client, 0x0B,
+	&read_data[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_read(client, 0x18 ,&tmpbyte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_read(client, 0x18,
+	&tmpbyte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
-	}// No bus request
+	} /* No bus request*/
 
-	if ( i2c_himax_read(client, 0x0F ,&tmpbyte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_read(client, 0x0F,
+	&tmpbyte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
-	}// idle state
+	} /* idle state*/
 
 }
 
-void himax_flash_write_burst(struct i2c_client *client, uint8_t * reg_byte, uint8_t * write_data)
+void himax_flash_write_burst(struct i2c_client *client,
+uint8_t *reg_byte, uint8_t *write_data)
 {
-    uint8_t data_byte[8];
+	uint8_t data_byte[8];
 	int i = 0, j = 0;
 
-     for (i = 0; i < 4; i++)
-     { 
-         data_byte[i] = reg_byte[i];
-     }
-     for (j = 4; j < 8; j++)
-     {
-         data_byte[j] = write_data[j-4];
-     }
-	 
-	 if ( i2c_himax_write(client, 0x00 ,data_byte, 8, HIMAX_I2C_RETRY_TIMES) < 0) {
-		 E("%s: i2c access fail!\n", __func__);
-		 return;
-	 }
+	for (i = 0 ; i < 4; i++)
+		data_byte[i] = reg_byte[i];
 
-}
+	for (j = 4 ; j < 8; j++)
+		data_byte[j] = write_data[j-4];
 
-int himax_flash_write_burst_lenth(struct i2c_client *client, uint8_t *reg_byte, uint8_t *write_data, int length)
-{
-    uint8_t data_byte[256];
-	int i = 0, j = 0;
-
-    for (i = 0; i < 4; i++)
-    {
-        data_byte[i] = reg_byte[i];
-    }
-    for (j = 4; j < length + 4; j++)
-    {
-        data_byte[j] = write_data[j - 4];
-    }
-   
-	if ( i2c_himax_write(client, 0x00 ,data_byte, length + 4, HIMAX_I2C_RETRY_TIMES) < 0) {
-		 E("%s: i2c access fail!\n", __func__);
-		 return -EBUSY;
+	if (i2c_himax_write(client, 0x00,
+		data_byte, 8, HIMAX_I2C_RETRY_TIMES) < 0) {
+		E("%s: i2c access fail!\n", __func__);
+		return;
 	}
 
-    return 0;
 }
 
-int himax_register_write(struct i2c_client *client, uint8_t *write_addr, int write_length, uint8_t *write_data)
+int himax_flash_write_burst_length(struct i2c_client *client,
+uint8_t *reg_byte, uint8_t *write_data, int length)
 {
-	int i =0, address = 0;
-	int ret = 0;
+	uint8_t data_byte[256];
+	int i = 0, j = 0, err = -1;
 
-	address = (write_addr[3] << 24) + (write_addr[2] << 16) + (write_addr[1] << 8) + write_addr[0];
+	for (i = 0 ; i < 4 ; i++)
+		data_byte[i] = reg_byte[i];
 
-	for (i = address; i < address + write_length * 4; i = i + 4)
-	{
-		if (write_length > 1)
-		{
+	for (j = 4 ; j < length + 4 ; j++)
+		data_byte[j] = write_data[j - 4];
+
+	if (i2c_himax_write(client, 0x00,
+	data_byte, length + 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+		E("%s: i2c access fail!\n", __func__);
+		return err;
+	}
+	return 0;
+}
+
+int himax_register_write(struct i2c_client *client,
+uint8_t *write_addr, int write_length, uint8_t *write_data)
+{
+	int i = 0, address = 0;
+	int ret = 0, err = -1;
+
+	address = (write_addr[3] << 24) +
+				(write_addr[2] << 16) +
+				(write_addr[1] << 8) +
+				write_addr[0];
+
+	for (i = address ; i < address + write_length * 4;
+		i = i + 4) {
+		if (write_length > 1) {
 			ret = himax_burst_enable(client, 1);
-			if(ret)
-				return ret;
-		}
-		else
-		{
+			if (ret)
+				return err;
+		} else {
 			ret = himax_burst_enable(client, 0);
-			if(ret)
-				return ret;
+			if (ret)
+				return err;
 		}
-	ret = himax_flash_write_burst_lenth(client, write_addr, write_data, write_length * 4);
-	if(ret < 0)
-		return ret;
+	ret = himax_flash_write_burst_length(client,
+		write_addr, write_data, write_length * 4);
+	if (ret < 0)
+		return err;
 	}
 
 	return 0;
@@ -550,50 +591,62 @@
 {
 	uint8_t wdt_off = 0x00;
 	uint8_t tmp_addr[4];
-	uint8_t tmp_data[5];	
+	uint8_t tmp_data[5];
 
 	himax_burst_enable(client, 0);
 
-	while(wdt_off == 0x00)
-	{
-		// 0x9000_800C ==> 0x0000_AC53
-		tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x80; tmp_addr[0] = 0x0C;
-		tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0xAC; tmp_data[0] = 0x53;
+	while (wdt_off == 0x00) {
+		/* 0x9000_800C ==> 0x0000_AC53*/
+		tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x80; tmp_addr[0] = 0x0C;
+		tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+		tmp_data[1] = 0xAC; tmp_data[0] = 0x53;
 		himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-		//=====================================
-    // Read Watch Dog disable password : 0x9000_800C ==> 0x0000_AC53
-    //=====================================
-		tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x80; tmp_addr[0] = 0x0C;
+		/*=====================================*/
+		/* Read Watch Dog disable password :
+		0x9000_800C ==> 0x0000_AC53 */
+		/*=====================================*/
+		tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x80; tmp_addr[0] = 0x0C;
 		himax_register_read(client, tmp_addr, 1, tmp_data);
-		
-		//Check WDT
-		if (tmp_data[0] == 0x53 && tmp_data[1] == 0xAC && tmp_data[2] == 0x00 && tmp_data[3] == 0x00)
+
+		/*Check WDT*/
+		if (tmp_data[0] == 0x53 && tmp_data[1] == 0xAC
+		&& tmp_data[2] == 0x00 && tmp_data[3] == 0x00)
 			wdt_off = 0x01;
 		else
 			wdt_off = 0x00;
 	}
 
-	// VCOM		//0x9008_806C ==> 0x0000_0001
-	tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x6C;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x01;
+	/* VCOM		//0x9008_806C ==> 0x0000_0001*/
+	tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+	tmp_addr[1] = 0x80; tmp_addr[0] = 0x6C;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x01;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 
 	msleep(20);
 
-	// 0x9000_0010 ==> 0x0000_00DA
-	tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0xDA;
+	/* 0x9000_0010 ==> 0x0000_00DA*/
+	tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0xDA;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-	//=====================================
-	// Read CPU clock off password : 0x9000_0010 ==> 0x0000_00DA
-	//=====================================
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
-	tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+	/*=====================================
+	Read CPU clock off password : 0x9000_0010 ==> 0x0000_00DA
+	=====================================*/
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+	tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
 	himax_register_read(client, tmp_addr, 1, tmp_data);
-	I("%s: CPU clock off password data[0]=%x data[1]=%x data[2]=%x data[3]=%x\n", __func__
-		,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]);
+	I("%s: CPU clock off password data[0]=%x",
+	__func__, tmp_data[0]);
+	I(" data[1]=%x data[2]=%x data[3]=%x\n",
+	tmp_data[1], tmp_data[2], tmp_data[3]);
 
 }
 
@@ -602,11 +655,12 @@
 	uint8_t tmp_addr[4];
 	uint8_t tmp_data[5];
 
-    //===========================================
-    //  Any Cmd for ineterface on : 0x9000_0000 ==> 0x0000_0000
-    //===========================================
-    tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
-    himax_flash_read(client, tmp_addr, tmp_data); //avoid RD/WR fail
+    /*=====================================
+	Any Cmd for ineterface on : 0x9000_0000 ==> 0x0000_0000
+	=====================================*/
+	tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
+	himax_flash_read(client, tmp_addr, tmp_data); /*avoid RD/WR fail*/
 }
 
 bool wait_wip(struct i2c_client *client, int Timing)
@@ -614,55 +668,64 @@
 	uint8_t tmp_addr[4];
 	uint8_t tmp_data[4];
 	uint8_t in_buffer[10];
-	//uint8_t out_buffer[20];
+	/*uint8_t out_buffer[20];*/
 	int retry_cnt = 0;
 
-	//=====================================
-	// SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
-	//=====================================
-	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x02; tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+	/*=====================================
+	SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+	=====================================*/
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+	tmp_data[1] = 0x07; tmp_data[0] = 0x80;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 
 	in_buffer[0] = 0x01;
 
-	do
-	{
-		//=====================================
-		// SPI Transfer Control : 0x8000_0020 ==> 0x4200_0003
-		//=====================================
-		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
-		tmp_data[3] = 0x42; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x03;
+	do {
+		/*=====================================
+		SPI Transfer Control : 0x8000_0020 ==> 0x4200_0003
+		=====================================*/
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+		tmp_data[3] = 0x42; tmp_data[2] = 0x00;
+		tmp_data[1] = 0x00; tmp_data[0] = 0x03;
 		himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-		//=====================================
-		// SPI Command : 0x8000_0024 ==> 0x0000_0005
-		// read 0x8000_002C for 0x01, means wait success
-		//=====================================
-		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
-		tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x05;
+		/*=====================================
+		SPI Command : 0x8000_0024 ==> 0x0000_0005
+		read 0x8000_002C for 0x01, means wait success
+		=====================================*/
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+		tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+		tmp_data[1] = 0x00; tmp_data[0] = 0x05;
 		himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-		in_buffer[0] = in_buffer[1] = in_buffer[2] = in_buffer[3] = 0xFF;
-		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x2C;
+		in_buffer[0] = in_buffer[1] =
+		in_buffer[2] = in_buffer[3] = 0xFF;
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x2C;
 		himax_register_read(client, tmp_addr, 1, in_buffer);
-		
+
 		if ((in_buffer[0] & 0x01) == 0x00)
 			return true;
 
 		retry_cnt++;
-		
-		if (in_buffer[0] != 0x00 || in_buffer[1] != 0x00 || in_buffer[2] != 0x00 || in_buffer[3] != 0x00)
-        	I("%s:Wait wip retry_cnt:%d, buffer[0]=%d, buffer[1]=%d, buffer[2]=%d, buffer[3]=%d \n", __func__, 
-            retry_cnt,in_buffer[0],in_buffer[1],in_buffer[2],in_buffer[3]);
 
-		if (retry_cnt > 100)
-        {        	
+		if (in_buffer[0] != 0x00 || in_buffer[1] != 0x00
+		|| in_buffer[2] != 0x00 || in_buffer[3] != 0x00){
+			I("%s:Wait wip retry_cnt:%d, buffer[0]=%d, ",
+			__func__, retry_cnt, in_buffer[0]);
+			I("buffer[1]=%d, buffer[2]=%d, buffer[3]=%d\n",
+			in_buffer[1], in_buffer[2], in_buffer[3]);
+		}
+		if (retry_cnt > 100) {
 			E("%s: Wait wip error!\n", __func__);
-            return false;
-        }
+			return false;
+		}
 		msleep(Timing);
-	}while ((in_buffer[0] & 0x01) == 0x01);
+	} while ((in_buffer[0] & 0x01) == 0x01);
 	return true;
 }
 
@@ -673,74 +736,93 @@
 
 	himax_interface_on(client);
 	himax_burst_enable(client, 0);
-	//CPU reset
-	// 0x9000_0014 ==> 0x0000_00CA
-	tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0xCA;
+	/*CPU reset*/
+	/* 0x9000_0014 ==> 0x0000_00CA*/
+	tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0xCA;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-	//=====================================
-	// Read pull low CPU reset signal : 0x9000_0014 ==> 0x0000_00CA
-	//=====================================
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
-	tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
+	/*=====================================
+	Read pull low CPU reset signal : 0x9000_0014 ==> 0x0000_00CA
+	=====================================*/
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+	tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
 	himax_register_read(client, tmp_addr, 1, tmp_data);
 
-	I("%s: check pull low CPU reset signal  data[0]=%x data[1]=%x data[2]=%x data[3]=%x\n", __func__
-	,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]);
+	I("%s: check pull low CPU reset signal  data[0]=%x data[1]=%x ",
+	__func__, tmp_data[0], tmp_data[1]);
+	I("data[2]=%x data[3]=%x\n",
+	tmp_data[2], tmp_data[3]);
 
-	// 0x9000_0014 ==> 0x0000_0000
-	tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+	/* 0x9000_0014 ==> 0x0000_0000*/
+	tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x00;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-	//=====================================
-	// Read revert pull low CPU reset signal : 0x9000_0014 ==> 0x0000_0000
-	//=====================================
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
-	tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
+	/*=====================================
+	Read revert pull low CPU reset signal : 0x9000_0014 ==> 0x0000_0000
+	=====================================*/
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+	tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
 	himax_register_read(client, tmp_addr, 1, tmp_data);
 
-	I("%s: revert pull low CPU reset signal data[0]=%x data[1]=%x data[2]=%x data[3]=%x\n", __func__
-	,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]);
+	I("%s: revert pull low CPU reset signal data[0]=%x data[1]=%x ",
+	__func__, tmp_data[0], tmp_data[1]);
+	I("data[2]=%x data[3]=%x\n",
+	tmp_data[2], tmp_data[3]);
 
-	//=====================================
-  // Reset TCON
-  //=====================================
-  tmp_addr[3] = 0x80; tmp_addr[2] = 0x02; tmp_addr[1] = 0x01; tmp_addr[0] = 0xE0;
-  tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
-  himax_flash_write_burst(client, tmp_addr, tmp_data);
-	usleep_range(10000, 20000);
-  tmp_addr[3] = 0x80; tmp_addr[2] = 0x02; tmp_addr[1] = 0x01; tmp_addr[0] = 0xE0;
-  tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x01;
-  himax_flash_write_burst(client, tmp_addr, tmp_data);
+	/*=====================================
+	Reset TCON
+	=====================================*/
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x02;
+	tmp_addr[1] = 0x01; tmp_addr[0] = 0xE0;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+	himax_flash_write_burst(client, tmp_addr, tmp_data);
+	usleep_range(9999, 10000);
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x02;
+	tmp_addr[1] = 0x01; tmp_addr[0] = 0xE0;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x01;
+	himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-	if (FlashMode == 0x00)	//SRAM
-	{
-		//=====================================
-		//			Re-map
-		//=====================================
-		tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
-		tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0xF1;
-		himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 4);
+	if (FlashMode == 0x00) { /*SRAM*/
+		/*=====================================
+					Re-map
+		=====================================*/
+		tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
+		tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+		tmp_data[1] = 0x00; tmp_data[0] = 0xF1;
+		himax_flash_write_burst_length(client, tmp_addr, tmp_data, 4);
 		I("%s:83100_Chip_Re-map ON\n", __func__);
-	}
-	else
-	{
-		//=====================================
-		//			Re-map off
-		//=====================================
-		tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
-		tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
-		himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 4);
+	} else {
+		/*=====================================
+					Re-map off
+		=====================================*/
+		tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
+		tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+		tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+		himax_flash_write_burst_length(client, tmp_addr, tmp_data, 4);
 		I("%s:83100_Chip_Re-map OFF\n", __func__);
 	}
-	//=====================================
-	//			CPU clock on
-	//=====================================
-	tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
-	himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 4);
+	/*=====================================
+				CPU clock on
+	=====================================*/
+	tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+	himax_flash_write_burst_length(client, tmp_addr, tmp_data, 4);
 
 }
 
@@ -751,36 +833,45 @@
 
 	himax_burst_enable(client, 0);
 
-	//=====================================
-	// SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
-	//=====================================
-	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x02; tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+	/*=====================================
+	SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+	=====================================*/
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+	tmp_data[1] = 0x07; tmp_data[0] = 0x80;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-	//=====================================
-	// Chip Erase
-	// Write Enable : 1. 0x8000_0020 ==> 0x4700_0000
-	//				  2. 0x8000_0024 ==> 0x0000_0006
-	//=====================================
-	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
-	tmp_data[3] = 0x47; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+	/*=====================================
+	Chip Erase
+	Write Enable :
+	1. 0x8000_0020 ==> 0x4700_0000
+	2. 0x8000_0024 ==> 0x0000_0006
+	=====================================*/
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+	tmp_data[3] = 0x47; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x00;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x06;
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x06;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-	//=====================================
-	// Chip Erase
-	// Erase Command : 0x8000_0024 ==> 0x0000_00C7
-	//=====================================
-	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0xC7;
+	/*=====================================
+	Chip Erase
+	Erase Command : 0x8000_0024 ==> 0x0000_00C7
+	=====================================*/
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0xC7;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
-	
+
 	msleep(2000);
-	
+
 	if (!wait_wip(client, 100))
 		E("%s:83100_Chip_Erase Fail\n", __func__);
 
@@ -793,53 +884,64 @@
 
 	himax_burst_enable(client, 0);
 
-	//=====================================
-	// SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
-	//=====================================
-	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x02; tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+	/*=====================================
+	SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+	=====================================*/
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+	tmp_data[1] = 0x07; tmp_data[0] = 0x80;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-	//=====================================
-	// Chip Erase
-	// Write Enable : 1. 0x8000_0020 ==> 0x4700_0000
-	//				  2. 0x8000_0024 ==> 0x0000_0006
-	//=====================================
-	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
-	tmp_data[3] = 0x47; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+	/*=====================================
+	Chip Erase
+	Write Enable :
+	1. 0x8000_0020 ==> 0x4700_0000
+	2. 0x8000_0024 ==> 0x0000_0006
+	=====================================*/
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+	tmp_data[3] = 0x47; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x00;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x06;
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x06;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-	//=====================================
-	// Block Erase
-	// Erase Command : 0x8000_0028 ==> 0x0000_0000 //SPI addr
-	//				   0x8000_0020 ==> 0x6700_0000 //control
-	//				   0x8000_0024 ==> 0x0000_0052 //BE
-	//=====================================
-	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+	/*=====================================
+	Block Erase
+	Erase Command :
+	0x8000_0028 ==> 0x0000_0000 //SPI addr
+	0x8000_0020 ==> 0x6700_0000 //control
+	0x8000_0024 ==> 0x0000_0052 //BE
+	=====================================*/
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x00;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
-	
-	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
-	tmp_data[3] = 0x67; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+	tmp_data[3] = 0x67; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x00;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
-	
-	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x52;
+
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x52;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 
 	msleep(1000);
 
-	if (!wait_wip(client, 100))
-	{
+	if (!wait_wip(client, 100)) {
 		E("%s:83100_Erase Fail\n", __func__);
 		return false;
-	}
-	else
-	{
+	} else {
 		return true;
 	}
 
@@ -853,97 +955,110 @@
 
 	himax_burst_enable(client, 0);
 
-	//=====================================
-	// SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
-	//=====================================
-	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x02; tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+	/*=====================================
+	SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+	=====================================*/
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+	tmp_data[1] = 0x07; tmp_data[0] = 0x80;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
-	for (page_prog_start = start_addr; page_prog_start < start_addr + 0x0F000; page_prog_start = page_prog_start + 0x1000)
-		{
-			//=====================================
-			// Chip Erase
-			// Write Enable : 1. 0x8000_0020 ==> 0x4700_0000
-			//				  2. 0x8000_0024 ==> 0x0000_0006
-			//=====================================
-			tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
-			tmp_data[3] = 0x47; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
-			himax_flash_write_burst(client, tmp_addr, tmp_data);
+	for (page_prog_start = start_addr;
+	page_prog_start < start_addr + 0x0F000;
+	page_prog_start = page_prog_start + 0x1000) {
+		/*=====================================
+		Chip Erase
+		Write Enable :
+		1. 0x8000_0020 ==> 0x4700_0000
+		2. 0x8000_0024 ==> 0x0000_0006
+		=====================================*/
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+		tmp_data[3] = 0x47; tmp_data[2] = 0x00;
+		tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+		himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-			tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
-			tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x06;
-			himax_flash_write_burst(client, tmp_addr, tmp_data);
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+		tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+		tmp_data[1] = 0x00; tmp_data[0] = 0x06;
+		himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-			//=====================================
-			// Sector Erase
-			// Erase Command : 0x8000_0028 ==> 0x0000_0000 //SPI addr
-			// 				0x8000_0020 ==> 0x6700_0000 //control
-			// 				0x8000_0024 ==> 0x0000_0020 //SE
-			//=====================================
-			tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
-			if (page_prog_start < 0x100)
-			{
-			 tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = (uint8_t)page_prog_start;
-			}
-			else if (page_prog_start >= 0x100 && page_prog_start < 0x10000)
-			{
-			 tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = (uint8_t)(page_prog_start >> 8); tmp_data[0] = (uint8_t)page_prog_start;
-			}
-			else if (page_prog_start >= 0x10000 && page_prog_start < 0x1000000)
-			{
-			 tmp_data[3] = 0x00; tmp_data[2] = (uint8_t)(page_prog_start >> 16); tmp_data[1] = (uint8_t)(page_prog_start >> 8); tmp_data[0] = (uint8_t)page_prog_start;
-			}
-			himax_flash_write_burst(client, tmp_addr, tmp_data);
+		/*=====================================
+		Sector Erase
+		Erase Command :
+		0x8000_0028 ==> 0x0000_0000 //SPI addr
+		0x8000_0020 ==> 0x6700_0000 //control
+		0x8000_0024 ==> 0x0000_0020 //SE
+		=====================================*/
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
+		if (page_prog_start < 0x100) {
+			tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+			tmp_data[1] = 0x00;
+			tmp_data[0] = (uint8_t)page_prog_start;
+		} else if (page_prog_start >= 0x100
+		&& page_prog_start < 0x10000) {
+			tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+			tmp_data[1] = (uint8_t)(page_prog_start >> 8);
+			tmp_data[0] = (uint8_t)page_prog_start;
+		} else if (page_prog_start >= 0x10000
+		&& page_prog_start < 0x1000000) {
+			tmp_data[3] = 0x00;
+			tmp_data[2] = (uint8_t)(page_prog_start >> 16);
+			tmp_data[1] = (uint8_t)(page_prog_start >> 8);
+			tmp_data[0] = (uint8_t)page_prog_start;
+		}
+		himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-			tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
-			tmp_data[3] = 0x67; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
-			himax_flash_write_burst(client, tmp_addr, tmp_data);
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+		tmp_data[3] = 0x67; tmp_data[2] = 0x00;
+		tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+		himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-			tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
-			tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x20;
-			himax_flash_write_burst(client, tmp_addr, tmp_data);
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+		tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+		tmp_data[1] = 0x00; tmp_data[0] = 0x20;
+		himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-			msleep(200);
+		msleep(200);
 
-			if (!wait_wip(client, 100))
-			{
-				E("%s:83100_Erase Fail\n", __func__);
-				return false;
-			}
-		}	
-		return true;
+		if (!wait_wip(client, 100)) {
+			E("%s:83100_Erase Fail\n", __func__);
+			return false;
+		}
+	}
+	return true;
 }
 
 void himax_sram_write(struct i2c_client *client, uint8_t *FW_content)
 {
 	int i = 0;
 	uint8_t tmp_addr[4];
-	uint8_t tmp_data[128];
-	int FW_length = 0x4000; // 0x4000 = 16K bin file
-	
-	//himax_sense_off(client);
+	uint8_t tmp_data[64];
+	int FW_length = 0x4000; /* 0x4000 = 16K bin file */
 
-	for (i = 0; i < FW_length; i = i + 128) 
-	{
+	/*himax_sense_off(client);*/
+
+	for (i = 0; i < FW_length; i = i + 64) {
 		himax_burst_enable(client, 1);
 
-		if (i < 0x100)
-		{
-			tmp_addr[3] = 0x08; 
-			tmp_addr[2] = 0x00; 
-			tmp_addr[1] = 0x00; 
+		if (i < 0x100) {
+			tmp_addr[3] = 0x08;
+			tmp_addr[2] = 0x00;
+			tmp_addr[1] = 0x00;
 			tmp_addr[0] = i;
-		}
-		else if (i >= 0x100 && i < 0x10000)
-		{
-			tmp_addr[3] = 0x08; 
-			tmp_addr[2] = 0x00; 
-			tmp_addr[1] = (i >> 8); 
+		} else if (i >= 0x100 && i < 0x10000) {
+			tmp_addr[3] = 0x08;
+			tmp_addr[2] = 0x00;
+			tmp_addr[1] = (i >> 8);
 			tmp_addr[0] = i;
 		}
 
-		memcpy(&tmp_data[0], &FW_content[i], 128);
-		himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 128);
+		memcpy(&tmp_data[0], &FW_content[i], 64);
+		himax_flash_write_burst_length(client, tmp_addr, tmp_data, 64);
 
 	}
 
@@ -951,182 +1066,197 @@
 		E("%s:83100_Sram_Write Fail\n", __func__);
 }
 
-bool himax_sram_verify(struct i2c_client *client, uint8_t *FW_File, int FW_Size)
+bool himax_sram_verify(struct i2c_client *client,
+uint8_t *FW_File, int FW_Size)
 {
 	int i = 0;
 	uint8_t out_buffer[20];
 	uint8_t in_buffer[128];
 	uint8_t *get_fw_content;
 
-	get_fw_content = kzalloc(0x4000*sizeof(uint8_t), GFP_KERNEL);
-	if (!get_fw_content)
-		return false;
+	get_fw_content = kzalloc(0x4000 * sizeof(uint8_t), GFP_KERNEL);
 
-	for (i = 0; i < 0x4000; i = i + 128)
-	{
+	for (i = 0 ; i < 0x4000 ; i = i + 128) {
 		himax_burst_enable(client, 1);
 
-		//==================================
-		//	AHB_I2C Burst Read
-		//==================================
-		if (i < 0x100)
-		{
-			out_buffer[3] = 0x08; 
-			out_buffer[2] = 0x00; 
-			out_buffer[1] = 0x00; 
+		/*=====================================
+				AHB_I2C Burst Read
+		=====================================*/
+		if (i < 0x100) {
+			out_buffer[3] = 0x08;
+			out_buffer[2] = 0x00;
+			out_buffer[1] = 0x00;
 			out_buffer[0] = i;
-		}
-		else if (i >= 0x100 && i < 0x10000)
-		{
-			out_buffer[3] = 0x08; 
-			out_buffer[2] = 0x00; 
-			out_buffer[1] = (i >> 8); 
+		} else if (i >= 0x100 && i < 0x10000) {
+			out_buffer[3] = 0x08;
+			out_buffer[2] = 0x00;
+			out_buffer[1] = (i >> 8);
 			out_buffer[0] = i;
 		}
 
-		if ( i2c_himax_write(client, 0x00 ,out_buffer, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+		if (i2c_himax_write(client, 0x00, out_buffer,
+		4, HIMAX_I2C_RETRY_TIMES) < 0) {
 			E("%s: i2c access fail!\n", __func__);
 			return false;
 		}
 
-		out_buffer[0] = 0x00;		
-		if ( i2c_himax_write(client, 0x0C ,out_buffer, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+		out_buffer[0] = 0x00;
+		if (i2c_himax_write(client, 0x0C, out_buffer,
+		1, HIMAX_I2C_RETRY_TIMES) < 0) {
 			E("%s: i2c access fail!\n", __func__);
 			return false;
 		}
 
-		if ( i2c_himax_read(client, 0x08 ,in_buffer, 128, HIMAX_I2C_RETRY_TIMES) < 0) {
+		if (i2c_himax_read(client, 0x08, in_buffer,
+		128, HIMAX_I2C_RETRY_TIMES) < 0) {
 			E("%s: i2c access fail!\n", __func__);
 			return false;
 		}
 		memcpy(&get_fw_content[i], &in_buffer[0], 128);
 	}
 
-	for (i = 0; i < FW_Size; i++)
-		{
-	        if (FW_File[i] != get_fw_content[i])
-	        	{
-					E("%s: fail! SRAM[%x]=%x NOT CRC_ifile=%x\n", __func__,i,get_fw_content[i],FW_File[i]);
-		            return false;
-	        	}
+	for (i = 0 ; i < FW_Size ; i++) {
+		if (FW_File[i] != get_fw_content[i]) {
+			E("%s: fail! SRAM[%x]=%x NOT CRC_ifile=%x\n",
+			__func__, i, get_fw_content[i], FW_File[i]);
+			return false;
 		}
+	}
 
 	kfree(get_fw_content);
 
 	return true;
 }
 
-void himax_flash_programming(struct i2c_client *client, uint8_t *FW_content, int FW_Size)
+void himax_flash_programming(struct i2c_client *client,
+uint8_t *FW_content, int FW_Size)
 {
 	int page_prog_start = 0;
 	int program_length = 48;
 	int i = 0, j = 0, k = 0;
 	uint8_t tmp_addr[4];
 	uint8_t tmp_data[4];
-	uint8_t buring_data[256];    // Read for flash data, 128K
-									 // 4 bytes for 0x80002C padding
+	/* // Read for flash data, 128K //4 bytes for 0x80002C padding */
+	uint8_t buring_data[256];
 
-	//himax_interface_on(client);
+	/*himax_interface_on(client);*/
 	himax_burst_enable(client, 0);
 
-	//=====================================
-	// SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
-	//=====================================
-	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x02; tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+	/*=====================================
+	SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+	=====================================*/
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+	tmp_data[1] = 0x07; tmp_data[0] = 0x80;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-	for (page_prog_start = 0; page_prog_start < FW_Size; page_prog_start = page_prog_start + 256)
-	{
-		//msleep(5);
-		//=====================================
-		// Write Enable : 1. 0x8000_0020 ==> 0x4700_0000
-		//				  2. 0x8000_0024 ==> 0x0000_0006
-		//=====================================
-		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
-		tmp_data[3] = 0x47; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+	for (page_prog_start = 0 ; page_prog_start < FW_Size;
+	page_prog_start = page_prog_start + 256) {
+		/*msleep(5);*/
+		/*=====================================
+		Write Enable :
+		1. 0x8000_0020 ==> 0x4700_0000
+		2. 0x8000_0024 ==> 0x0000_0006
+		=====================================*/
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+		tmp_data[3] = 0x47; tmp_data[2] = 0x00;
+		tmp_data[1] = 0x00; tmp_data[0] = 0x00;
 		himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
-		tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x06;
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+		tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+		tmp_data[1] = 0x00; tmp_data[0] = 0x06;
 		himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-		//=================================
-		// SPI Transfer Control
-		// Set 256 bytes page write : 0x8000_0020 ==> 0x610F_F000
-		// Set read start address	: 0x8000_0028 ==> 0x0000_0000			
-		//=================================
-		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
-		tmp_data[3] = 0x61; tmp_data[2] = 0x0F; tmp_data[1] = 0xF0; tmp_data[0] = 0x00;
-		// data bytes should be 0x6100_0000 + ((word_number)*4-1)*4096 = 0x6100_0000 + 0xFF000 = 0x610F_F000
-		// Programmable size = 1 page = 256 bytes, word_number = 256 byte / 4 = 64
+		/*=====================================
+		SPI Transfer Control
+		Set 256 bytes page write : 0x8000_0020 ==> 0x610F_F000
+		Set read start address	: 0x8000_0028 ==> 0x0000_0000
+		=====================================*/
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+		tmp_data[3] = 0x61; tmp_data[2] = 0x0F;
+		tmp_data[1] = 0xF0; tmp_data[0] = 0x00;
+		/*data bytes should be 0x6100_0000 +
+		((word_number)*4-1)*4096 = 0x6100_0000 +
+		0xFF000 = 0x610F_F000
+		Programmable size = 1 page = 256 bytes,
+		word_number = 256 byte / 4 = 64*/
 		himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
-		//tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00; // Flash start address 1st : 0x0000_0000
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
+		/* tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+		tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+		// Flash start address 1st : 0x0000_0000 */
 
-		if (page_prog_start < 0x100)
-		{
-			tmp_data[3] = 0x00; 
-			tmp_data[2] = 0x00; 
-			tmp_data[1] = 0x00; 
+		if (page_prog_start < 0x100) {
+			tmp_data[3] = 0x00;
+			tmp_data[2] = 0x00;
+			tmp_data[1] = 0x00;
+			tmp_data[0] = (uint8_t)page_prog_start;
+		} else if (page_prog_start >= 0x100
+		&& page_prog_start < 0x10000) {
+			tmp_data[3] = 0x00;
+			tmp_data[2] = 0x00;
+			tmp_data[1] = (uint8_t)(page_prog_start >> 8);
+			tmp_data[0] = (uint8_t)page_prog_start;
+		} else if (page_prog_start >= 0x10000
+		&& page_prog_start < 0x1000000) {
+			tmp_data[3] = 0x00;
+			tmp_data[2] = (uint8_t)(page_prog_start >> 16);
+			tmp_data[1] = (uint8_t)(page_prog_start >> 8);
 			tmp_data[0] = (uint8_t)page_prog_start;
 		}
-		else if (page_prog_start >= 0x100 && page_prog_start < 0x10000)
-		{
-			tmp_data[3] = 0x00; 
-			tmp_data[2] = 0x00; 
-			tmp_data[1] = (uint8_t)(page_prog_start >> 8); 
-			tmp_data[0] = (uint8_t)page_prog_start;
-		}
-		else if (page_prog_start >= 0x10000 && page_prog_start < 0x1000000)
-		{
-			tmp_data[3] = 0x00; 
-			tmp_data[2] = (uint8_t)(page_prog_start >> 16); 
-			tmp_data[1] = (uint8_t)(page_prog_start >> 8); 
-			tmp_data[0] = (uint8_t)page_prog_start;
-		}
-		
+
 		himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-
-		//=================================
-		// Send 16 bytes data : 0x8000_002C ==> 16 bytes data	  
-		//=================================
+		/*=====================================
+		Send 16 bytes data : 0x8000_002C ==> 16 bytes data
+		=====================================*/
 		buring_data[0] = 0x2C;
 		buring_data[1] = 0x00;
 		buring_data[2] = 0x00;
 		buring_data[3] = 0x80;
-		
-		for (i = /*0*/page_prog_start, j = 0; i < 16 + page_prog_start/**/; i++, j++)	/// <------ bin file
-		{
+
+		for (i = /*0*/page_prog_start, j = 0;
+			i < 16 + page_prog_start/**/;
+			i++, j++) {	/* <------ bin file*/
+
 			buring_data[j + 4] = FW_content[i];
 		}
 
-
-		if ( i2c_himax_write(client, 0x00 ,buring_data, 20, HIMAX_I2C_RETRY_TIMES) < 0) {
+		if (i2c_himax_write(client, 0x00, buring_data,
+			20, HIMAX_I2C_RETRY_TIMES) < 0) {
 			E("%s: i2c access fail!\n", __func__);
 			return;
 		}
-		//=================================
-		// Write command : 0x8000_0024 ==> 0x0000_0002
-		//=================================
-		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
-		tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x02;
+		/*=====================================
+		Write command : 0x8000_0024 ==> 0x0000_0002
+		=====================================*/
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+		tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+		tmp_data[1] = 0x00; tmp_data[0] = 0x02;
 		himax_flash_write_burst(client, tmp_addr, tmp_data);
 
-		//=================================
-		// Send 240 bytes data : 0x8000_002C ==> 240 bytes data	 
-		//=================================
+		/*=====================================
+		Send 240 bytes data : 0x8000_002C ==> 240 bytes data
+		=====================================*/
 
-		for (j = 0; j < 5; j++)
-		{
-			for (i = (page_prog_start + 16 + (j * 48)), k = 0; i < (page_prog_start + 16 + (j * 48)) + program_length; i++, k++)   /// <------ bin file
-			{
-				buring_data[k+4] = FW_content[i];//(byte)i;
+		for (j = 0; j < 5; j++) {
+			for (i = (page_prog_start + 16 + (j * 48)), k = 0;
+			i < (page_prog_start + 16 + (j * 48)) + program_length;
+			i++, k++) {  /*<------ bin file*/
+				buring_data[k+4] = FW_content[i];/*(byte)i;*/
 			}
 
-			if ( i2c_himax_write(client, 0x00 ,buring_data, program_length+4, HIMAX_I2C_RETRY_TIMES) < 0) {
+			if (i2c_himax_write(client, 0x00, buring_data,
+				program_length + 4,
+				HIMAX_I2C_RETRY_TIMES) < 0) {
 				E("%s: i2c access fail!\n", __func__);
 				return;
 			}
@@ -1145,52 +1275,61 @@
 	uint8_t ret_data = 0x00;
 	int i = 0;
 	int ret = 0;
+
 	himax_sense_off(client);
-	for (i = 0; i < 5; i++)
-	{
-		// 1. Set DDREG_Req = 1 (0x9000_0020 = 0x0000_0001) (Lock register R/W from driver)
-		tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
-		tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x01;
+
+	for (i = 0 ; i < 5 ; i++) {
+		/* 1. Set DDREG_Req = 1 (0x9000_0020 = 0x0000_0001)
+		(Lock register R/W from driver) */
+		tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+		tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+		tmp_data[1] = 0x00; tmp_data[0] = 0x01;
 		ret = himax_register_write(client, tmp_addr, 1, tmp_data);
-		if(ret)
+		if (ret)
 			return false;
 
-		// 2. Set bank as 0 (0x8001_BD01 = 0x0000_0000)
-		tmp_addr[3] = 0x80; tmp_addr[2] = 0x01; tmp_addr[1] = 0xBD; tmp_addr[0] = 0x01;
-		tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+		/* 2. Set bank as 0 (0x8001_BD01 = 0x0000_0000)*/
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x01;
+		tmp_addr[1] = 0xBD; tmp_addr[0] = 0x01;
+		tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+		tmp_data[1] = 0x00; tmp_data[0] = 0x00;
 		ret = himax_register_write(client, tmp_addr, 1, tmp_data);
-		if(ret)
+		if (ret)
 			return false;
 
-		// 3. Read driver ID register RF4H 1 byte (0x8001_F401)
-		//	  Driver register RF4H 1 byte value = 0x84H, read back value will become 0x84848484
-		tmp_addr[3] = 0x80; tmp_addr[2] = 0x01; tmp_addr[1] = 0xF4; tmp_addr[0] = 0x01;
+		/* 3. Read driver ID register RF4H 1 byte (0x8001_F401)
+		//	  Driver register RF4H 1 byte value = 0x84H,
+		read back value will become 0x84848484 */
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x01;
+		tmp_addr[1] = 0xF4; tmp_addr[0] = 0x01;
 		himax_register_read(client, tmp_addr, 1, tmp_data);
 		ret_data = tmp_data[0];
 
 		I("%s:Read driver IC ID = %X\n", __func__, ret_data);
-		if (ret_data == 0x84)
-		{
+		if (ret_data == 0x84) {
 			IC_TYPE         = HX_83100_SERIES_PWON;
-			//himax_sense_on(client, 0x01);
+			/*himax_sense_on(client, 0x01);*/
 			ret_data = true;
 			break;
-		}
-		else
-		{
+
+		} else {
 			ret_data = false;
 			E("%s:Read driver ID register Fail:\n", __func__);
 		}
 	}
-	// 4. After read finish, set DDREG_Req = 0 (0x9000_0020 = 0x0000_0000) (Unlock register R/W from driver)
-	tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+	/* 4. After read finish, set DDREG_Req = 0
+	(0x9000_0020 = 0x0000_0000) (Unlock register R/W from driver)*/
+	tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x00; tmp_data[0] = 0x00;
 	himax_register_write(client, tmp_addr, 1, tmp_data);
-	//himax_sense_on(client, 0x01);
+	/*himax_sense_on(client, 0x01);*/
 	return ret_data;
 }
 
-#if 1
+/*#if 1*/
 int himax_check_CRC(struct i2c_client *client, int mode)
 {
 	bool burnFW_success = false;
@@ -1200,52 +1339,70 @@
 	int CRC_value = 0;
 
 	memset(tmp_data, 0x00, sizeof(tmp_data));
+	if (i_TP_CRC_FW_60K == NULL) {
+		I("%s: i_TP_CRC_FW_60K = NULL\n", __func__);
+		return 0;
+	} else if (i_TP_CRC_FW_64K == NULL) {
+		I("%s: i_TP_CRC_FW_64K = NULL\n", __func__);
+		return 0;
+	} else if (i_TP_CRC_FW_124K == NULL) {
+		I("%s: i_TP_CRC_FW_124K = NULL\n", __func__);
+		return 0;
+	} else if (i_TP_CRC_FW_128K == NULL) {
+		I("%s: i_TP_CRC_FW_128K = NULL\n", __func__);
+		return 0;
+	}
 
-	if (1)
-	{
-		if(mode == fw_image_60k)
-		{
-			himax_sram_write(client, (i_TP_CRC_FW_60K));
-			burnFW_success = himax_sram_verify(client, i_TP_CRC_FW_60K, 0x4000);
+	if (1) {
+		if (mode == fw_image_60k) {
+			himax_sram_write(client,
+			(unsigned char *)i_TP_CRC_FW_60K->data);
+			burnFW_success = himax_sram_verify(client,
+			(unsigned char *)i_TP_CRC_FW_60K->data, 0x4000);
+		} else if (mode == fw_image_64k) {
+			himax_sram_write(client,
+			(unsigned char *)i_TP_CRC_FW_64K->data);
+			burnFW_success = himax_sram_verify(client,
+			(unsigned char *)i_TP_CRC_FW_64K->data, 0x4000);
+		} else if (mode == fw_image_124k) {
+			himax_sram_write(client,
+			(unsigned char *)i_TP_CRC_FW_124K->data);
+			burnFW_success = himax_sram_verify(client,
+			(unsigned char *)i_TP_CRC_FW_124K->data, 0x4000);
+		} else if (mode == fw_image_128k) {
+			himax_sram_write(client,
+			(unsigned char *)i_TP_CRC_FW_128K->data);
+			burnFW_success = himax_sram_verify(client,
+			(unsigned char *)i_TP_CRC_FW_128K->data, 0x4000);
 		}
-		else if(mode == fw_image_64k)
-		{
-			himax_sram_write(client, (i_TP_CRC_FW_64K));
-			burnFW_success = himax_sram_verify(client, i_TP_CRC_FW_64K, 0x4000);
-		}
-		else if(mode == fw_image_124k)
-		{
-			himax_sram_write(client, (i_TP_CRC_FW_124K));
-			burnFW_success = himax_sram_verify(client, i_TP_CRC_FW_124K, 0x4000);
-		}
-		else if(mode == fw_image_128k)
-		{
-			himax_sram_write(client, (i_TP_CRC_FW_128K));
-			burnFW_success = himax_sram_verify(client, i_TP_CRC_FW_128K, 0x4000);
-		}
-		if (burnFW_success)
-		{
-			I("%s: Start to do CRC FW mode=%d \n", __func__,mode);
-			himax_sense_on(client, 0x00);	// run CRC firmware
+		if (burnFW_success) {
+			I("%s: Start to do CRC FW mode=%d\n", __func__, mode);
+			himax_sense_on(client, 0x00);	/* run CRC firmware*/
 
-			while(true)
-			{
+			while (true) {
 				msleep(100);
-
-				tmp_addr[3] = 0x90; 
-				tmp_addr[2] = 0x08; 
-				tmp_addr[1] = 0x80; 
+				tmp_addr[3] = 0x90;
+				tmp_addr[2] = 0x08;
+				tmp_addr[1] = 0x80;
 				tmp_addr[0] = 0x94;
-				himax_register_read(client, tmp_addr, 1, tmp_data);
+				himax_register_read(client,
+				tmp_addr, 1, tmp_data);
 
-				I("%s: CRC from firmware is %x, %x, %x, %x \n", __func__,tmp_data[3],
-					tmp_data[2],tmp_data[1],tmp_data[0]);
-
-				if (tmp_data[3] == 0xFF && tmp_data[2] == 0xFF && tmp_data[1] == 0xFF && tmp_data[0] == 0xFF)
-				{ 
-					}
-				else
+				I("%s: CRC from firmware is %x, %x, %x, %x\n",
+				__func__, tmp_data[3], tmp_data[2],
+				tmp_data[1], tmp_data[0]);
+/*
+				if (tmp_data[3] == 0xFF && tmp_data[2] == 0xFF
+				&& tmp_data[1] == 0xFF && tmp_data[0] == 0xFF) {
+				} else
 					break;
+				*/
+				if (!(tmp_data[3] == 0xFF
+				&& tmp_data[2] == 0xFF
+				&& tmp_data[1] == 0xFF
+				&& tmp_data[0] == 0xFF)) {
+					break;
+				}
 			}
 
 			CRC_value = tmp_data[3];
@@ -1259,30 +1416,32 @@
 			tmp_value = tmp_data[0] << 24;
 			CRC_value += tmp_value;
 
-			I("%s: CRC Value is %x \n", __func__, CRC_value);
+			I("%s: CRC Value is %x\n", __func__, CRC_value);
 
-			//Close Remapping
-	        //=====================================
-	        //          Re-map close
-	        //=====================================
-	        tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
-	        tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
-	        himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 4);
-			return CRC_value;				
-		}
-		else
-		{
+			/*Close Remapping*/
+			/*=====================================
+			Re-map close
+			=====================================*/
+			tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+			tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
+			tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+			tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+			himax_flash_write_burst_length(client,
+			tmp_addr, tmp_data, 4);
+			return CRC_value;
+
+		} else {
 			E("%s: SRAM write fail\n", __func__);
 			return 0;
-		}		
-	}
-	else
-		I("%s: NO CRC Check File \n", __func__);
+		}
+	} else
+		I("%s: NO CRC Check File\n", __func__);
 
 	return 0;
 }
 
-bool Calculate_CRC_with_AP(unsigned char *FW_content , int CRC_from_FW, int mode)
+bool Calculate_CRC_with_AP(unsigned char *FW_content,
+int CRC_from_FW, int mode)
 {
 	uint8_t tmp_data[4];
 	int i, j;
@@ -1291,42 +1450,35 @@
 	int CRC = 0xFFFFFFFF;
 	int PolyNomial = 0x82F63B78;
 	int length = 0;
-	
+
 	if (mode == fw_image_128k)
 		length = 0x8000;
 	else if (mode == fw_image_124k)
 		length = 0x7C00;
 	else if (mode == fw_image_64k)
 		length = 0x4000;
-	else //if (mode == fw_image_60k)
+	else /*if (mode == fw_image_60k)*/
 		length = 0x3C00;
 
-	for (i = 0; i < length; i++)
-	{
-		fw_data = FW_content[i * 4 ];
-		
-		for (j = 1; j < 4; j++)
-		{
+	for (i = 0 ; i < length ; i++) {
+		fw_data = FW_content[i * 4];
+
+		for (j = 1 ; j < 4 ; j++) {
 			fw_data_2 = FW_content[i * 4 + j];
 			fw_data += (fw_data_2) << (8 * j);
 		}
 
 		CRC = fw_data ^ CRC;
 
-		for (j = 0; j < 32; j++)
-		{
+		for (j = 0 ; j < 32 ; j++) {
 			if ((CRC % 2) != 0)
-			{
-				CRC = ((CRC >> 1) & 0x7FFFFFFF) ^ PolyNomial;				
-			}
+				CRC = ((CRC >> 1) & 0x7FFFFFFF) ^ PolyNomial;
 			else
-			{
-				CRC = (((CRC >> 1) ^ 0x7FFFFFFF)& 0x7FFFFFFF);				
-			}
+				CRC = (((CRC >> 1) ^ 0x7FFFFFFF) & 0x7FFFFFFF);
 		}
 	}
 
-	I("%s: CRC calculate from bin file is %x \n", __func__, CRC);
+	I("%s: CRC calculate from bin file is %x\n", __func__, CRC);
 
 	tmp_data[0] = (uint8_t)(CRC >> 24);
 	tmp_data[1] = (uint8_t)(CRC >> 16);
@@ -1334,58 +1486,129 @@
 	tmp_data[3] = (uint8_t) CRC;
 
 	CRC = tmp_data[0];
-	CRC += tmp_data[1] << 8;			
+	CRC += tmp_data[1] << 8;
 	CRC += tmp_data[2] << 16;
 	CRC += tmp_data[3] << 24;
 
-	I("%s: CRC calculate from bin file REVERSE %x \n", __func__, CRC);
-	I("%s: CRC calculate from FWis %x \n", __func__, CRC_from_FW);
+	I("%s: CRC calculate from bin file REVERSE %x\n", __func__, CRC);
+	I("%s: CRC calculate from FWis %x\n", __func__, CRC_from_FW);
 	if (CRC_from_FW == CRC)
 		return true;
 	else
 		return false;
 }
-#endif
+/*#endif*/
 
-int fts_ctpm_fw_upgrade_with_sys_fs_60k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref)
+int himax_load_CRC_bin_file(struct i2c_client *client)
+{
+	int err = 0;
+	char *CRC_60_firmware_name = "HX_CRC_60.bin";
+	char *CRC_64_firmware_name = "HX_CRC_64.bin";
+	char *CRC_124_firmware_name = "HX_CRC_124.bin";
+	char *CRC_128_firmware_name = "HX_CRC_128.bin";
+
+	I("%s,Entering\n", __func__);
+	if (i_TP_CRC_FW_60K == NULL)	{
+		I("load file name = %s\n", CRC_60_firmware_name);
+		err = request_firmware(&i_TP_CRC_FW_60K,
+		CRC_60_firmware_name, private_ts->dev);
+		if (err < 0) {
+			E("%s,fail in line%d error code=%d\n",
+			__func__, __LINE__, err);
+			err = -1;
+			goto request_60k_fw_fail;
+		}
+	} else
+		I("%s already load i_TP_CRC_FW_60K\n", __func__);
+
+	if (i_TP_CRC_FW_64K == NULL)	{
+		I("load file name = %s\n", CRC_64_firmware_name);
+		err = request_firmware(&i_TP_CRC_FW_64K,
+		CRC_64_firmware_name, private_ts->dev);
+		if (err < 0) {
+			E("%s,fail in line%d error code=%d\n",
+			__func__, __LINE__, err);
+			err = -2;
+			goto request_64k_fw_fail;
+		}
+	} else
+		I("%s already load i_TP_CRC_FW_64K\n", __func__);
+
+	if (i_TP_CRC_FW_124K == NULL) {
+		I("load file name = %s\n", CRC_124_firmware_name);
+		err = request_firmware(&i_TP_CRC_FW_124K,
+		CRC_124_firmware_name, private_ts->dev);
+		if (err < 0) {
+			E("%s,fail in line%d error code=%d\n",
+			__func__, __LINE__, err);
+			err = -3;
+			goto request_124k_fw_fail;
+		}
+	} else
+		I("%s already load i_TP_CRC_FW_124K\n", __func__);
+
+	if (i_TP_CRC_FW_128K == NULL) {
+		I("load file name = %s\n", CRC_128_firmware_name);
+		err = request_firmware(&i_TP_CRC_FW_128K,
+		CRC_128_firmware_name, private_ts->dev);
+		if (err < 0) {
+			E("%s,fail in line%d error code=%d\n",
+			__func__, __LINE__, err);
+			err = -4;
+			goto request_128k_fw_fail;
+		}
+	} else
+		I("%s already load  i_TP_CRC_FW_128K\n", __func__);
+
+	return err;
+
+request_128k_fw_fail:
+	release_firmware(i_TP_CRC_FW_124K);
+request_124k_fw_fail:
+	release_firmware(i_TP_CRC_FW_64K);
+request_64k_fw_fail:
+	release_firmware(i_TP_CRC_FW_60K);
+request_60k_fw_fail:
+	return err;
+}
+int fts_ctpm_fw_upgrade_with_sys_fs_60k(struct i2c_client *client,
+unsigned char *fw, int len, bool change_iref)
 {
 	int CRC_from_FW = 0;
 	int burnFW_success = 0;
 
-	if (len != 0x10000)   //64k
-    {
-    	E("%s: The file size is not 64K bytes\n", __func__);
-    	return false;
-		}
+	if (len != 0x10000) {/*64k*/
+		E("%s: The file size is not 64K bytes\n", __func__);
+		return false;
+	}
 	himax_sense_off(client);
 	msleep(500);
 	himax_interface_on(client);
-  if (!himax_sector_erase(client, 0x00000))
-			{
-            E("%s:Sector erase fail!Please restart the IC.\n", __func__);
-            return false;
-      }
+	if (!himax_sector_erase(client, 0x00000)) {
+		E("%s:Sector erase fail!Please restart the IC.\n", __func__);
+		return false;
+	}
 	himax_flash_programming(client, fw, 0x0F000);
 
-	//burnFW_success = himax_83100_Verify(fw, len);
-	//if(burnFW_success==false)
-	//	return burnFW_success;
+	/*burnFW_success = himax_83100_Verify(fw, len);
+	if(burnFW_success==false)
+		return burnFW_success;*/
 
-	CRC_from_FW = himax_check_CRC(client,fw_image_60k);
-	burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW,fw_image_60k);
-	//himax_sense_on(client, 0x01);
+	CRC_from_FW = himax_check_CRC(client, fw_image_60k);
+	burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW, fw_image_60k);
+	/*himax_sense_on(client, 0x01);*/
 	return burnFW_success;
 }
 
-int fts_ctpm_fw_upgrade_with_sys_fs_64k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref)
+int fts_ctpm_fw_upgrade_with_sys_fs_64k(struct i2c_client *client,
+unsigned char *fw, int len, bool change_iref)
 {
 	int CRC_from_FW = 0;
 	int burnFW_success = 0;
 
-	if (len != 0x10000)   //64k
-  {
-    	E("%s: The file size is not 64K bytes\n", __func__);
-    	return false;
+	if (len != 0x10000) {   /*64k*/
+		E("%s: The file size is not 64K bytes\n", __func__);
+		return false;
 	}
 	himax_sense_off(client);
 	msleep(500);
@@ -1393,62 +1616,58 @@
 	himax_chip_erase(client);
 	himax_flash_programming(client, fw, len);
 
-	//burnFW_success = himax_83100_Verify(fw, len);
-	//if(burnFW_success==false)
-	//	return burnFW_success;
+	/*burnFW_success = himax_83100_Verify(fw, len);
+	if(burnFW_success==false)
+		return burnFW_success;*/
 
-	CRC_from_FW = himax_check_CRC(client,fw_image_64k);
-	burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW,fw_image_64k);
-	//himax_sense_on(client, 0x01);
+	CRC_from_FW = himax_check_CRC(client, fw_image_64k);
+	burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW, fw_image_64k);
+	/*himax_sense_on(client, 0x01);*/
 	return burnFW_success;
 }
 
-int fts_ctpm_fw_upgrade_with_sys_fs_124k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref)
+int fts_ctpm_fw_upgrade_with_sys_fs_124k(struct i2c_client *client,
+unsigned char *fw, int len, bool change_iref)
 {
 	int CRC_from_FW = 0;
 	int burnFW_success = 0;
 
-	if (len != 0x20000)   //128k
-  {
-    	E("%s: The file size is not 128K bytes\n", __func__);
-    	return false;
+	if (len != 0x20000) {   /*128k*/
+		E("%s: The file size is not 128K bytes\n", __func__);
+		return false;
 	}
 	himax_sense_off(client);
 	msleep(500);
 	himax_interface_on(client);
-	if (!himax_block_erase(client))
-    	{
-            E("%s:Block erase fail!Please restart the IC.\n", __func__);
-            return false;
-      }
-
-    if (!himax_sector_erase(client, 0x10000))
-    	{
-            E("%s:Sector erase fail!Please restart the IC.\n", __func__);
-            return false;
-      }
+	if (!himax_block_erase(client)) {
+		E("%s:Block erase fail!Please restart the IC.\n", __func__);
+		return false;
+	}
+	if (!himax_sector_erase(client, 0x10000)) {
+		E("%s:Sector erase fail!Please restart the IC.\n", __func__);
+		return false;
+	}
 	himax_flash_programming(client, fw, 0x1F000);
 
+	/*burnFW_success = himax_83100_Verify(fw, len);
+	if(burnFW_success==false)
+		return burnFW_success;*/
 
-	//burnFW_success = himax_83100_Verify(fw, len);
-	//if(burnFW_success==false)
-	//	return burnFW_success;
-
-	CRC_from_FW = himax_check_CRC(client,fw_image_124k);
-	burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW,fw_image_124k);
-	//himax_sense_on(client, 0x01);
+	CRC_from_FW = himax_check_CRC(client, fw_image_124k);
+	burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW, fw_image_124k);
+	/*himax_sense_on(client, 0x01);*/
 	return burnFW_success;
 }
 
-int fts_ctpm_fw_upgrade_with_sys_fs_128k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref)
+int fts_ctpm_fw_upgrade_with_sys_fs_128k(struct i2c_client *client,
+unsigned char *fw, int len, bool change_iref)
 {
 	int CRC_from_FW = 0;
 	int burnFW_success = 0;
 
-	if (len != 0x20000)   //128k
-  {
-    	E("%s: The file size is not 128K bytes\n", __func__);
-    	return false;
+	if (len != 0x20000) {   /*128k*/
+		E("%s: The file size is not 128K bytes\n", __func__);
+		return false;
 	}
 	himax_sense_off(client);
 	msleep(500);
@@ -1457,13 +1676,13 @@
 
 	himax_flash_programming(client, fw, len);
 
-	//burnFW_success = himax_83100_Verify(fw, len);
-	//if(burnFW_success==false)
-	//	return burnFW_success;
+	/*burnFW_success = himax_83100_Verify(fw, len);
+	if(burnFW_success==false)
+		return burnFW_success;*/
 
-	CRC_from_FW = himax_check_CRC(client,fw_image_128k);
-	burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW,fw_image_128k);
-	//himax_sense_on(client, 0x01);
+	CRC_from_FW = himax_check_CRC(client, fw_image_128k);
+	burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW, fw_image_128k);
+	/*himax_sense_on(client, 0x01); */
 	return burnFW_success;
 }
 
@@ -1472,10 +1691,9 @@
 	uint8_t cmd[4];
 	char data[12] = {0};
 
-	I("%s:IC_TYPE =%d\n", __func__,IC_TYPE);
+	I("%s:IC_TYPE =%d\n", __func__, IC_TYPE);
 
-	if(IC_TYPE == HX_83100_SERIES_PWON)
-	{
+	if (IC_TYPE == HX_83100_SERIES_PWON) {
 		cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0xF8;
 		himax_register_read(client, cmd, 1, data);
 
@@ -1486,11 +1704,11 @@
 		cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0xFC;
 		himax_register_read(client, cmd, 1, data);
 
-	  if((data[1] & 0x04) == 0x04) {
+		if ((data[1] & 0x04) == 0x04)
 			ic_data->HX_XY_REVERSE = true;
-	  } else {
+		else
 			ic_data->HX_XY_REVERSE = false;
-	  }
+
 		ic_data->HX_Y_RES = data[3]*256;
 		cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x01; cmd[0] = 0x00;
 		himax_register_read(client, cmd, 1, data);
@@ -1498,32 +1716,35 @@
 		ic_data->HX_X_RES = data[1]*256 + data[2];
 		cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0x8C;
 		himax_register_read(client, cmd, 1, data);
-	  if((data[0] & 0x01) == 1) {
+		if ((data[0] & 0x01) == 1)
 			ic_data->HX_INT_IS_EDGE = true;
-	  } else {
+		else
 			ic_data->HX_INT_IS_EDGE = false;
-	  }
-	  if (ic_data->HX_RX_NUM > 40)
+
+		if (ic_data->HX_RX_NUM > 40)
 			ic_data->HX_RX_NUM = 29;
-	  if (ic_data->HX_TX_NUM > 20)
+		if (ic_data->HX_TX_NUM > 20)
 			ic_data->HX_TX_NUM = 16;
-	  if (ic_data->HX_MAX_PT > 10)
+		if (ic_data->HX_MAX_PT > 10)
 			ic_data->HX_MAX_PT = 10;
-	  if (ic_data->HX_Y_RES > 2000)
+		if (ic_data->HX_Y_RES > 2000)
 			ic_data->HX_Y_RES = 1280;
-	  if (ic_data->HX_X_RES > 2000)
+		if (ic_data->HX_X_RES > 2000)
 			ic_data->HX_X_RES = 720;
 #ifdef HX_EN_MUT_BUTTON
 		cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0xE8;
 		himax_register_read(client, cmd, 1, data);
 		ic_data->HX_BT_NUM				= data[3];
 #endif
-		I("%s:HX_RX_NUM =%d,HX_TX_NUM =%d,HX_MAX_PT=%d \n", __func__,ic_data->HX_RX_NUM,ic_data->HX_TX_NUM,ic_data->HX_MAX_PT);
-		I("%s:HX_XY_REVERSE =%d,HX_Y_RES =%d,HX_X_RES=%d \n", __func__,ic_data->HX_XY_REVERSE,ic_data->HX_Y_RES,ic_data->HX_X_RES);
-		I("%s:HX_INT_IS_EDGE =%d \n", __func__,ic_data->HX_INT_IS_EDGE);
-	}
-	else
-	{
+		I("%s:HX_RX_NUM =%d,HX_TX_NUM =%d,HX_MAX_PT=%d\n",
+		__func__, ic_data->HX_RX_NUM,
+		ic_data->HX_TX_NUM, ic_data->HX_MAX_PT);
+		I("%s:HX_XY_REVERSE =%d,HX_Y_RES =%d,HX_X_RES=%d\n",
+		__func__, ic_data->HX_XY_REVERSE,
+		ic_data->HX_Y_RES, ic_data->HX_X_RES);
+		I("%s:HX_INT_IS_EDGE =%d\n",
+		__func__, ic_data->HX_INT_IS_EDGE);
+	} else {
 		ic_data->HX_RX_NUM				= 0;
 		ic_data->HX_TX_NUM				= 0;
 		ic_data->HX_BT_NUM				= 0;
@@ -1538,35 +1759,34 @@
 void himax_read_FW_ver(struct i2c_client *client)
 {
 	uint8_t cmd[4];
-	uint8_t data[64] = {0};
+	uint8_t data[64];
 
-	//=====================================
-	// Read FW version : 0x0000_E303
-	//=====================================
+	/*=====================================
+	Read FW version : 0x0000_E303
+	=====================================*/
 	cmd[3] = 0x00; cmd[2] = 0x00; cmd[1] = 0xE3; cmd[0] = 0x00;
 	himax_register_read(client, cmd, 1, data);
 
-	ic_data->vendor_config_ver = data[3]<<8;
+	ic_data->vendor_config_ver = data[3] << 8;
 
 	cmd[3] = 0x00; cmd[2] = 0x00; cmd[1] = 0xE3; cmd[0] = 0x04;
 	himax_register_read(client, cmd, 1, data);
 
 	ic_data->vendor_config_ver = data[0] | ic_data->vendor_config_ver;
-	I("CFG_VER : %X \n",ic_data->vendor_config_ver);
+	I("CFG_VER : %X\n", ic_data->vendor_config_ver);
 
 	cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0x28;
 	himax_register_read(client, cmd, 1, data);
 
 	ic_data->vendor_fw_ver = data[0]<<8 | data[1];
-	I("FW_VER : %X \n",ic_data->vendor_fw_ver);
+	I("FW_VER : %X\n", ic_data->vendor_fw_ver);
 
-
-	return;
 }
 
 bool himax_ic_package_check(struct i2c_client *client)
 {
-#if 0
+/*#if 0*/
+#ifdef HX_EN_CHECK_PATCH
 	uint8_t cmd[3];
 	uint8_t data[3];
 
@@ -1574,260 +1794,284 @@
 	memset(data, 0x00, sizeof(data));
 
 	if (i2c_himax_read(client, 0xD1, cmd, 3, HIMAX_I2C_RETRY_TIMES) < 0)
-		return false ;
+		return false;
 
 	if (i2c_himax_read(client, 0x31, data, 3, HIMAX_I2C_RETRY_TIMES) < 0)
 		return false;
 
-	if((data[0] == 0x85 && data[1] == 0x29))
-		{
-			IC_TYPE         = HX_85XX_F_SERIES_PWON;
-    	IC_CHECKSUM 		= HX_TP_BIN_CHECKSUM_CRC;
-    	//Himax: Set FW and CFG Flash Address                                          
-    	FW_VER_MAJ_FLASH_ADDR   = 64901;  //0xFD85                              
-    	FW_VER_MAJ_FLASH_LENG   = 1;
-    	FW_VER_MIN_FLASH_ADDR   = 64902;  //0xFD86                                     
-    	FW_VER_MIN_FLASH_LENG   = 1;
-    	CFG_VER_MAJ_FLASH_ADDR 	= 64928;   //0xFDA0         
-    	CFG_VER_MAJ_FLASH_LENG 	= 12;
-    	CFG_VER_MIN_FLASH_ADDR 	= 64940;   //0xFDAC
-    	CFG_VER_MIN_FLASH_LENG 	= 12;
-			I("Himax IC package 852x F\n");
-			}
-	if((data[0] == 0x85 && data[1] == 0x30) || (cmd[0] == 0x05 && cmd[1] == 0x85 && cmd[2] == 0x29))
-		{
-			IC_TYPE 		= HX_85XX_E_SERIES_PWON;
-			IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
-			//Himax: Set FW and CFG Flash Address                                          
-			FW_VER_MAJ_FLASH_ADDR	= 133;	//0x0085                              
-			FW_VER_MAJ_FLASH_LENG	= 1;                                               
-			FW_VER_MIN_FLASH_ADDR	= 134;  //0x0086                                     
-			FW_VER_MIN_FLASH_LENG	= 1;                                                
-			CFG_VER_MAJ_FLASH_ADDR = 160;	//0x00A0         
-			CFG_VER_MAJ_FLASH_LENG = 12; 	                                 
-			CFG_VER_MIN_FLASH_ADDR = 172;	//0x00AC
-			CFG_VER_MIN_FLASH_LENG = 12;   
-			I("Himax IC package 852x E\n");
-		}
-	else if((data[0] == 0x85 && data[1] == 0x31))
-		{
-			IC_TYPE         = HX_85XX_ES_SERIES_PWON;
-    	IC_CHECKSUM 		= HX_TP_BIN_CHECKSUM_CRC;
-    	//Himax: Set FW and CFG Flash Address                                          
-    	FW_VER_MAJ_FLASH_ADDR   = 133;  //0x0085                              
-    	FW_VER_MAJ_FLASH_LENG   = 1;
-    	FW_VER_MIN_FLASH_ADDR   = 134;  //0x0086                                     
-    	FW_VER_MIN_FLASH_LENG   = 1;
-    	CFG_VER_MAJ_FLASH_ADDR 	= 160;   //0x00A0         
-    	CFG_VER_MAJ_FLASH_LENG 	= 12;
-    	CFG_VER_MIN_FLASH_ADDR 	= 172;   //0x00AC
-    	CFG_VER_MIN_FLASH_LENG 	= 12;
-			I("Himax IC package 852x ES\n");
-			}
-	else if ((data[0] == 0x85 && data[1] == 0x28) || (cmd[0] == 0x04 && cmd[1] == 0x85 &&
-		(cmd[2] == 0x26 || cmd[2] == 0x27 || cmd[2] == 0x28))) {
-		IC_TYPE                = HX_85XX_D_SERIES_PWON;
-		IC_CHECKSUM            = HX_TP_BIN_CHECKSUM_CRC;
-		//Himax: Set FW and CFG Flash Address
-		FW_VER_MAJ_FLASH_ADDR  = 133;                    // 0x0085
-		FW_VER_MAJ_FLASH_LENG  = 1;
-		FW_VER_MIN_FLASH_ADDR  = 134;                    // 0x0086
-		FW_VER_MIN_FLASH_LENG  = 1;
-		CFG_VER_MAJ_FLASH_ADDR = 160;                    // 0x00A0
+	if ((data[0] == 0x85 && data[1] == 0x29)) {
+		IC_TYPE = HX_85XX_F_SERIES_PWON;
+		IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
+		/*Himax: Set FW and CFG Flash Address*/
+		FW_VER_MAJ_FLASH_ADDR = 64901;  /*0xFD85*/
+		FW_VER_MAJ_FLASH_LENG = 1;
+		FW_VER_MIN_FLASH_ADDR = 64902;  /*0xFD86*/
+		FW_VER_MIN_FLASH_LENG = 1;
+		CFG_VER_MAJ_FLASH_ADDR = 64928;   /*0xFDA0*/
 		CFG_VER_MAJ_FLASH_LENG = 12;
-		CFG_VER_MIN_FLASH_ADDR = 172;                    // 0x00AC
+		CFG_VER_MIN_FLASH_ADDR = 64940;   /*0xFDAC*/
+		CFG_VER_MIN_FLASH_LENG = 12;
+		I("Himax IC package 852x F\n");
+	}
+	if ((data[0] == 0x85 && data[1] == 0x30)
+		|| (cmd[0] == 0x05 && cmd[1] == 0x85 && cmd[2] == 0x29)) {
+		IC_TYPE = HX_85XX_E_SERIES_PWON;
+		IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
+		/*Himax: Set FW and CFG Flash Address*/
+		FW_VER_MAJ_FLASH_ADDR = 133;	/*0x0085*/
+		FW_VER_MAJ_FLASH_LENG = 1;
+		FW_VER_MIN_FLASH_ADDR = 134;  /*0x0086*/
+		FW_VER_MIN_FLASH_LENG = 1;
+		CFG_VER_MAJ_FLASH_ADDR = 160;	/*0x00A0*/
+		CFG_VER_MAJ_FLASH_LENG = 12;
+		CFG_VER_MIN_FLASH_ADDR = 172;	/*0x00AC*/
+		CFG_VER_MIN_FLASH_LENG = 12;
+		I("Himax IC package 852x E\n");
+	} else if ((data[0] == 0x85 && data[1] == 0x31)) {
+		IC_TYPE = HX_85XX_ES_SERIES_PWON;
+		IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
+		/*Himax: Set FW and CFG Flash Address*/
+		FW_VER_MAJ_FLASH_ADDR = 133;  /*0x0085*/
+		FW_VER_MAJ_FLASH_LENG = 1;
+		FW_VER_MIN_FLASH_ADDR = 134;  /*0x0086*/
+		FW_VER_MIN_FLASH_LENG = 1;
+		CFG_VER_MAJ_FLASH_ADDR = 160;   /*0x00A0*/
+		CFG_VER_MAJ_FLASH_LENG = 12;
+		CFG_VER_MIN_FLASH_ADDR = 172;   /*0x00AC*/
+		CFG_VER_MIN_FLASH_LENG = 12;
+		I("Himax IC package 852x ES\n");
+	} else if ((data[0] == 0x85 && data[1] == 0x28)
+		|| (cmd[0] == 0x04 && cmd[1] == 0x85
+		&& (cmd[2] == 0x26 || cmd[2] == 0x27
+		|| cmd[2] == 0x28))) {
+		IC_TYPE = HX_85XX_D_SERIES_PWON;
+		IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
+		/*Himax: Set FW and CFG Flash Address*/
+		FW_VER_MAJ_FLASH_ADDR = 133;    /*0x0085*/
+		FW_VER_MAJ_FLASH_LENG = 1;
+		FW_VER_MIN_FLASH_ADDR = 134;   /*0x0086*/
+		FW_VER_MIN_FLASH_LENG = 1;
+		CFG_VER_MAJ_FLASH_ADDR = 160;  /*0x00A0*/
+		CFG_VER_MAJ_FLASH_LENG = 12;
+		CFG_VER_MIN_FLASH_ADDR = 172;  /* 0x00AC*/
 		CFG_VER_MIN_FLASH_LENG = 12;
 		I("Himax IC package 852x D\n");
-	} else if ((data[0] == 0x85 && data[1] == 0x23) || (cmd[0] == 0x03 && cmd[1] == 0x85 &&
-			(cmd[2] == 0x26 || cmd[2] == 0x27 || cmd[2] == 0x28 || cmd[2] == 0x29))) {
-		IC_TYPE                = HX_85XX_C_SERIES_PWON;
-		IC_CHECKSUM            = HX_TP_BIN_CHECKSUM_SW;
-		//Himax: Set FW and CFG Flash Address
-		FW_VER_MAJ_FLASH_ADDR  = 133;                   // 0x0085
-		FW_VER_MAJ_FLASH_LENG  = 1;
-		FW_VER_MIN_FLASH_ADDR  = 134;                   // 0x0086
-		FW_VER_MIN_FLASH_LENG  = 1;
-		CFG_VER_MAJ_FLASH_ADDR = 135;                   // 0x0087
+	} else if ((data[0] == 0x85 && data[1] == 0x23) ||
+		(cmd[0] == 0x03 && cmd[1] == 0x85 &&
+		(cmd[2] == 0x26 || cmd[2] == 0x27 ||
+		cmd[2] == 0x28 || cmd[2] == 0x29))) {
+		IC_TYPE = HX_85XX_C_SERIES_PWON;
+		IC_CHECKSUM = HX_TP_BIN_CHECKSUM_SW;
+		/*Himax: Set FW and CFG Flash Address*/
+		FW_VER_MAJ_FLASH_ADDR = 133;                   /*0x0085*/
+		FW_VER_MAJ_FLASH_LENG = 1;
+		FW_VER_MIN_FLASH_ADDR = 134;                   /*0x0086*/
+		FW_VER_MIN_FLASH_LENG = 1;
+		CFG_VER_MAJ_FLASH_ADDR = 135;                   /*0x0087*/
 		CFG_VER_MAJ_FLASH_LENG = 12;
-		CFG_VER_MIN_FLASH_ADDR = 147;                   // 0x0093
+		CFG_VER_MIN_FLASH_ADDR = 147;                   /*0x0093*/
 		CFG_VER_MIN_FLASH_LENG = 12;
 		I("Himax IC package 852x C\n");
 	} else if ((data[0] == 0x85 && data[1] == 0x26) ||
-		   (cmd[0] == 0x02 && cmd[1] == 0x85 &&
-		   (cmd[2] == 0x19 || cmd[2] == 0x25 || cmd[2] == 0x26))) {
+		(cmd[0] == 0x02 && cmd[1] == 0x85 &&
+		(cmd[2] == 0x19 || cmd[2] == 0x25 || cmd[2] == 0x26))) {
 		IC_TYPE                = HX_85XX_B_SERIES_PWON;
 		IC_CHECKSUM            = HX_TP_BIN_CHECKSUM_SW;
-		//Himax: Set FW and CFG Flash Address
-		FW_VER_MAJ_FLASH_ADDR  = 133;                   // 0x0085
-		FW_VER_MAJ_FLASH_LENG  = 1;
-		FW_VER_MIN_FLASH_ADDR  = 728;                   // 0x02D8
-		FW_VER_MIN_FLASH_LENG  = 1;
-		CFG_VER_MAJ_FLASH_ADDR = 692;                   // 0x02B4
+		/*Himax: Set FW and CFG Flash Address*/
+		FW_VER_MAJ_FLASH_ADDR = 133;                   /*0x0085*/
+		FW_VER_MAJ_FLASH_LENG = 1;
+		FW_VER_MIN_FLASH_ADDR = 728;                   /*0x02D8*/
+		FW_VER_MIN_FLASH_LENG = 1;
+		CFG_VER_MAJ_FLASH_ADDR = 692;                   /*0x02B4*/
 		CFG_VER_MAJ_FLASH_LENG = 3;
-		CFG_VER_MIN_FLASH_ADDR = 704;                   // 0x02C0
+		CFG_VER_MIN_FLASH_ADDR = 704;                   /*0x02C0*/
 		CFG_VER_MIN_FLASH_LENG = 3;
 		I("Himax IC package 852x B\n");
 	} else if ((data[0] == 0x85 && data[1] == 0x20) || (cmd[0] == 0x01 &&
-			cmd[1] == 0x85 && cmd[2] == 0x19)) {
+		cmd[1] == 0x85 && cmd[2] == 0x19)) {
 		IC_TYPE     = HX_85XX_A_SERIES_PWON;
 		IC_CHECKSUM = HX_TP_BIN_CHECKSUM_SW;
 		I("Himax IC package 852x A\n");
 	} else {
 		E("Himax IC package incorrect!!\n");
-	}*/
+	}
 #else
-		IC_TYPE         = HX_83100_SERIES_PWON;
-    IC_CHECKSUM 		= HX_TP_BIN_CHECKSUM_CRC;
-    //Himax: Set FW and CFG Flash Address
-    FW_VER_MAJ_FLASH_ADDR   = 57384;   //0xE028
-    FW_VER_MAJ_FLASH_LENG   = 1;
-    FW_VER_MIN_FLASH_ADDR   = 57385;   //0xE029
-    FW_VER_MIN_FLASH_LENG   = 1;
-    CFG_VER_MAJ_FLASH_ADDR 	= 58115;  //0xE303
-    CFG_VER_MAJ_FLASH_LENG 	= 1;
-    CFG_VER_MIN_FLASH_ADDR 	= 58116;  //0xE304
-    CFG_VER_MIN_FLASH_LENG 	= 1;
+		IC_TYPE = HX_83100_SERIES_PWON;
+		IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
+		/*Himax: Set FW and CFG Flash Address*/
+		FW_VER_MAJ_FLASH_ADDR = 57384;   /*0xE028*/
+		FW_VER_MAJ_FLASH_LENG = 1;
+		FW_VER_MIN_FLASH_ADDR = 57385;   /*0xE029*/
+		FW_VER_MIN_FLASH_LENG = 1;
+		CFG_VER_MAJ_FLASH_ADDR = 58115;  /*0xE303*/
+		CFG_VER_MAJ_FLASH_LENG = 1;
+		CFG_VER_MIN_FLASH_ADDR = 58116;  /*0xE304*/
+		CFG_VER_MIN_FLASH_LENG = 1;
 		I("Himax IC package 83100_in\n");
 
 #endif
 	return true;
 }
 
-void himax_read_event_stack(struct i2c_client *client, 	uint8_t *buf, uint8_t length)
+void himax_read_event_stack(struct i2c_client *client,
+uint8_t *buf, uint8_t length)
 {
 	uint8_t cmd[4];
 
-	cmd[3] = 0x90; cmd[2] = 0x06; cmd[1] = 0x00; cmd[0] = 0x00;	
-	if ( i2c_himax_write(client, 0x00 ,cmd, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
-		E("%s: i2c access fail!\n", __func__);		
+	cmd[3] = 0x90; cmd[2] = 0x06;
+	cmd[1] = 0x00; cmd[0] = 0x00;
+	if (i2c_himax_write(client, 0x00,
+		cmd, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+		E("%s: i2c access fail!\n", __func__);
 	}
 
-	cmd[0] = 0x00;		
-	if ( i2c_himax_write(client, 0x0C ,cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
-		E("%s: i2c access fail!\n", __func__);		
+	cmd[0] = 0x00;
+	if (i2c_himax_write(client, 0x0C,
+		cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+		E("%s: i2c access fail!\n", __func__);
 	}
 
-	i2c_himax_read(client, 0x08, buf, length, HIMAX_I2C_RETRY_TIMES);
+	i2c_himax_read(client, 0x08,
+	buf, length, HIMAX_I2C_RETRY_TIMES);
 }
 
-#if 0
-static void himax_83100_Flash_Write(uint8_t * reg_byte, uint8_t * write_data)
+/*#if 0*/
+#ifdef HX_EN_CHECK_PATCH
+static void himax_83100_Flash_Write(uint8_t *reg_byte, uint8_t *write_data)
 {
 	uint8_t tmpbyte[2];
 
-    if ( i2c_himax_write(private_ts->client, 0x00 ,&reg_byte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(private_ts->client, 0x00,
+		&reg_byte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_write(private_ts->client, 0x01 ,&reg_byte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(private_ts->client, 0x01,
+		&reg_byte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_write(private_ts->client, 0x02 ,&reg_byte[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(private_ts->client, 0x02,
+		&reg_byte[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_write(private_ts->client, 0x03 ,&reg_byte[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(private_ts->client,
+		0x03, &reg_byte[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_write(private_ts->client, 0x04 ,&write_data[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(private_ts->client,
+		0x04, &write_data[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_write(private_ts->client, 0x05 ,&write_data[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(private_ts->client,
+		0x05, &write_data[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_write(private_ts->client, 0x06 ,&write_data[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(private_ts->client,
+		0x06, &write_data[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_write(private_ts->client, 0x07 ,&write_data[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(private_ts->client,
+		0x07, &write_data[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-    if (isBusrtOn == false)
-    {
-        tmpbyte[0] = 0x01;
-		if ( i2c_himax_write(private_ts->client, 0x0C ,&tmpbyte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
-		E("%s: i2c access fail!\n", __func__);
-		return;
+	if (isBusrtOn == false) {
+		tmpbyte[0] = 0x01;
+		if (i2c_himax_write(private_ts->client,
+			0x0C, &tmpbyte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+			E("%s: i2c access fail!\n", __func__);
+			return;
 		}
-    }
+	}
 }
 #endif
-#if 0
-static void himax_83100_Flash_Burst_Write(uint8_t * reg_byte, uint8_t * write_data)
+/*#if 0*/
+#ifdef HX_EN_CHECK_PATCH
+static void himax_83100_Flash_Burst_Write
+(uint8_t *reg_byte, uint8_t *write_data)
 {
-    //uint8_t tmpbyte[2];
+    /*uint8_t tmpbyte[2];*/
 	int i = 0;
 
-	if ( i2c_himax_write(private_ts->client, 0x00 ,&reg_byte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(private_ts->client, 0x00,
+		&reg_byte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_write(private_ts->client, 0x01 ,&reg_byte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(private_ts->client, 0x01,
+		&reg_byte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_write(private_ts->client, 0x02 ,&reg_byte[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(private_ts->client, 0x02,
+		&reg_byte[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-	if ( i2c_himax_write(private_ts->client, 0x03 ,&reg_byte[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(private_ts->client, 0x03,
+		&reg_byte[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		return;
 	}
 
-    // Write 256 bytes with continue burst mode
-    for (i = 0; i < 256; i = i + 4)
+    /*Write 256 bytes with continue burst mode*/
+	for (i = 0 ; i < 256 ; i = i + 4) {
+		if (i2c_himax_write(private_ts->client,
+			0x04, &write_data[i], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+			E("%s: i2c access fail!\n", __func__);
+			return;
+		}
+
+		if (i2c_himax_write(private_ts->client, 0x05,
+			&write_data[i+1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+			E("%s: i2c access fail!\n", __func__);
+			return;
+		}
+
+		if (i2c_himax_write(private_ts->client, 0x06,
+			&write_data[i+2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+			E("%s: i2c access fail!\n", __func__);
+			return;
+		}
+
+		if (i2c_himax_write(private_ts->client, 0x07,
+			&write_data[i+3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+			E("%s: i2c access fail!\n", __func__);
+			return;
+		}
+	}
+
+    /*if (isBusrtOn == false)
     {
-		if ( i2c_himax_write(private_ts->client, 0x04 ,&write_data[i], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
-			E("%s: i2c access fail!\n", __func__);
-			return;
-		}
-
-		if ( i2c_himax_write(private_ts->client, 0x05 ,&write_data[i+1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
-			E("%s: i2c access fail!\n", __func__);
-			return;
-		}
-
-		if ( i2c_himax_write(private_ts->client, 0x06 ,&write_data[i+2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
-			E("%s: i2c access fail!\n", __func__);
-			return;
-		}
-
-		if ( i2c_himax_write(private_ts->client, 0x07 ,&write_data[i+3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
-			E("%s: i2c access fail!\n", __func__);
-			return;
-		}
-    }
-
-    //if (isBusrtOn == false)
-    //{
-    //   tmpbyte[0] = 0x01;
-	//	if ( i2c_himax_write(private_ts->client, 0x0C ,&tmpbyte[0], 1, 3) < 0) {
-	//	E("%s: i2c access fail!\n", __func__);
-	//	return;
-	//	}
-    //}
+       tmpbyte[0] = 0x01;
+		if (i2c_himax_write(private_ts->client,
+		0x0C, &tmpbyte[0], 1, 3) < 0) {
+		E("%s: i2c access fail!\n", __func__);
+		return;
+    }*/
 
 }
 #endif
 
-#if 0
+/*#if 0*/
+#ifdef HX_EN_CHECK_PATCH
 static bool himax_83100_Verify(uint8_t *FW_File, int FW_Size)
 {
 	uint8_t tmp_addr[4];
@@ -1835,49 +2079,51 @@
 	uint8_t out_buffer[20];
 	uint8_t in_buffer[260];
 
-	int fail_addr=0, fail_cnt=0;
+	int fail_addr = 0, fail_cnt = 0;
 	int page_prog_start = 0;
 	int i = 0;
 
 	himax_interface_on(private_ts->client);
 	himax_burst_enable(private_ts->client, 0);
 
-	//=====================================
-	// SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
-	//=====================================
-	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x02; tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+	/*=====================================
+	SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+	=====================================*/
+	tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+	tmp_data[1] = 0x07; tmp_data[0] = 0x80;
 	himax_83100_Flash_Write(tmp_addr, tmp_data);
 
-	for (page_prog_start = 0; page_prog_start < FW_Size; page_prog_start = page_prog_start + 256)
-	{
-		//=================================
-		// SPI Transfer Control
-		// Set 256 bytes page read : 0x8000_0020 ==> 0x6940_02FF
-		// Set read start address  : 0x8000_0028 ==> 0x0000_0000
-		// Set command			   : 0x8000_0024 ==> 0x0000_003B
-		//=================================
-		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
-		tmp_data[3] = 0x69; tmp_data[2] = 0x40; tmp_data[1] = 0x02; tmp_data[0] = 0xFF;
+	for (page_prog_start = 0; page_prog_start < FW_Size;
+	page_prog_start = page_prog_start + 256) {
+		/*=====================================
+		SPI Transfer Control
+		Set 256 bytes page read : 0x8000_0020 ==> 0x6940_02FF
+		Set read start address  : 0x8000_0028 ==> 0x0000_0000
+		Set command			   : 0x8000_0024 ==> 0x0000_003B
+		=====================================*/
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+		tmp_data[3] = 0x69; tmp_data[2] = 0x40;
+		tmp_data[1] = 0x02; tmp_data[0] = 0xFF;
 		himax_83100_Flash_Write(tmp_addr, tmp_data);
 
-		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
-		if (page_prog_start < 0x100)
-		{
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
+		if (page_prog_start < 0x100) {
 			tmp_data[3] = 0x00;
 			tmp_data[2] = 0x00;
 			tmp_data[1] = 0x00;
 			tmp_data[0] = (uint8_t)page_prog_start;
-		}
-		else if (page_prog_start >= 0x100 && page_prog_start < 0x10000)
-		{
+		} else if (page_prog_start >= 0x100
+		&& page_prog_start < 0x10000) {
 			tmp_data[3] = 0x00;
 			tmp_data[2] = 0x00;
 			tmp_data[1] = (uint8_t)(page_prog_start >> 8);
 			tmp_data[0] = (uint8_t)page_prog_start;
-		}
-		else if (page_prog_start >= 0x10000 && page_prog_start < 0x1000000)
-		{
+		} else if (page_prog_start >= 0x10000
+		&& page_prog_start < 0x1000000) {
 			tmp_data[3] = 0x00;
 			tmp_data[2] = (uint8_t)(page_prog_start >> 16);
 			tmp_data[1] = (uint8_t)(page_prog_start >> 8);
@@ -1885,65 +2131,73 @@
 		}
 		himax_83100_Flash_Write(tmp_addr, tmp_data);
 
-		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
-		tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x3B;
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+		tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+		tmp_data[1] = 0x00; tmp_data[0] = 0x3B;
 		himax_83100_Flash_Write(tmp_addr, tmp_data);
 
-		//==================================
-		// AHB_I2C Burst Read
-		// Set SPI data register : 0x8000_002C ==> 0x00
-		//==================================
+		/*==================================
+		AHB_I2C Burst Read
+		Set SPI data register : 0x8000_002C ==> 0x00
+		==================================*/
 		out_buffer[0] = 0x2C;
 		out_buffer[1] = 0x00;
 		out_buffer[2] = 0x00;
 		out_buffer[3] = 0x80;
-		i2c_himax_write(private_ts->client, 0x00 ,out_buffer, 4, HIMAX_I2C_RETRY_TIMES);
+		i2c_himax_write(private_ts->client, 0x00,
+		out_buffer, 4, HIMAX_I2C_RETRY_TIMES);
 
-		//==================================
-		// Read access : 0x0C ==> 0x00
-		//==================================
+		/*==================================
+		Read access : 0x0C ==> 0x00
+		==================================*/
 		out_buffer[0] = 0x00;
-		i2c_himax_write(private_ts->client, 0x0C ,out_buffer, 1, HIMAX_I2C_RETRY_TIMES);
+		i2c_himax_write(private_ts->client, 0x0C,
+		out_buffer, 1, HIMAX_I2C_RETRY_TIMES);
 
-		//==================================
-		// Read 128 bytes two times
-		//==================================
-		i2c_himax_read(private_ts->client, 0x08 ,in_buffer, 128, HIMAX_I2C_RETRY_TIMES);
+		/*==================================
+		Read 128 bytes two times
+		==================================*/
+		i2c_himax_read(private_ts->client, 0x08,
+		in_buffer, 128, HIMAX_I2C_RETRY_TIMES);
 		for (i = 0; i < 128; i++)
 			flash_buffer[i + page_prog_start] = in_buffer[i];
 
-		i2c_himax_read(private_ts->client, 0x08 ,in_buffer, 128, HIMAX_I2C_RETRY_TIMES);
+		i2c_himax_read(private_ts->client, 0x08,
+		in_buffer, 128, HIMAX_I2C_RETRY_TIMES);
 		for (i = 0; i < 128; i++)
-			flash_buffer[(i + 128) + page_prog_start] = in_buffer[i];
+			flash_buffer[(i + 128)
+			+ page_prog_start] = in_buffer[i];
 
-		//tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x2C;
-		//himax_register_read(tmp_addr, 32, out in_buffer);
-		//for (int i = 0; i < 128; i++)
-		//	  flash_buffer[i + page_prog_start] = in_buffer[i];
-		//tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x2C;
-		//himax_register_read(tmp_addr, 32, out in_buffer);
-		//for (int i = 0; i < 128; i++)
-		//	  flash_buffer[i + page_prog_start] = in_buffer[i];
-
+		/*tmp_addr[3] = 0x80;
+		tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x2C;
+		himax_register_read(tmp_addr, 32, out in_buffer);
+		for (int i = 0; i < 128; i++)
+			  flash_buffer[i + page_prog_start] = in_buffer[i];
+		tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+		tmp_addr[1] = 0x00; tmp_addr[0] = 0x2C;
+		himax_register_read(tmp_addr, 32, out in_buffer);
+		for (int i = 0; i < 128; i++)
+			  flash_buffer[i + page_prog_start] = in_buffer[i];
+		*/
 		I("%s:Verify Progress: %x\n", __func__, page_prog_start);
 	}
 
 	fail_cnt = 0;
-	for (i = 0; i < FW_Size; i++)
-	{
-		if (FW_File[i] != flash_buffer[i])
-		{
+	for (i = 0; i < FW_Size; i++) {
+		if (FW_File[i] != flash_buffer[i]) {
 			if (fail_cnt == 0)
 				fail_addr = i;
 
 			fail_cnt++;
-			//E("%s Fail Block:%x\n", __func__, i);
-			//return false;
+			/*E("%s Fail Block:%x\n", __func__, i);
+			return false;*/
 		}
 	}
-	if (fail_cnt > 0)
-	{
-		E("%s:Start Fail Block:%x and fail block count=%x\n" , __func__,fail_addr,fail_cnt);
+	if (fail_cnt > 0) {
+		E("%s:Start Fail Block:%x and fail block count=%x\n",
+		__func__, fail_addr, fail_cnt);
 		return false;
 	}
 
@@ -1959,56 +2213,60 @@
 	int cnt = 0;
 	unsigned char tmp_addr[4];
 	unsigned char tmp_data[4];
-  uint8_t max_i2c_size = 32;
+	uint8_t max_i2c_size = 32;
 	int total_size = ic_data->HX_TX_NUM * ic_data->HX_RX_NUM * 2;
 	int total_size_4bytes = total_size / 4;
 	int total_read_times = 0;
 	unsigned long address = 0x08000468;
-  tmp_addr[3] = 0x08; tmp_addr[2] = 0x00; tmp_addr[1] = 0x04; tmp_addr[0] = 0x64;
-	tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x5A; tmp_data[0] = 0xA5;
+
+	tmp_addr[3] = 0x08; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x04; tmp_addr[0] = 0x64;
+	tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+	tmp_data[1] = 0x5A; tmp_data[0] = 0xA5;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
-  do
-	{
+	do {
 		cnt++;
 		himax_register_read(client, tmp_addr, 1, tmp_data);
-		usleep_range(10000, 20000);
+		usleep_range(9999, 10000);
 	} while ((tmp_data[1] != 0xA5 || tmp_data[0] != 0x5A) && cnt < 100);
-  tmp_addr[3] = 0x08; tmp_addr[2] = 0x00; tmp_addr[1] = 0x04; tmp_addr[0] = 0x68;
-  if (total_size_4bytes % max_i2c_size == 0)
-	{
+	tmp_addr[3] = 0x08; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x04; tmp_addr[0] = 0x68;
+	if (total_size_4bytes % max_i2c_size == 0)
 		total_read_times = total_size_4bytes / max_i2c_size;
-	}
 	else
-	{
 		total_read_times = total_size_4bytes / max_i2c_size + 1;
-	}
-	for (i = 0; i < (total_read_times); i++)
-	{
-		if ( total_size_4bytes >= max_i2c_size)
-		{
-			himax_register_read(client, tmp_addr, max_i2c_size, &info_data[i*max_i2c_size*4]);
+
+	for (i = 0 ; i < (total_read_times) ; i++) {
+		if (total_size_4bytes >= max_i2c_size) {
+			himax_register_read(client, tmp_addr,
+			max_i2c_size,
+			&info_data[i*max_i2c_size*4]);
 			total_size_4bytes = total_size_4bytes - max_i2c_size;
+		} else {
+			himax_register_read(client, tmp_addr,
+			total_size_4bytes % max_i2c_size,
+			&info_data[i*max_i2c_size*4]);
 		}
-		else
-		{
-			himax_register_read(client, tmp_addr, total_size_4bytes % max_i2c_size, &info_data[i*max_i2c_size*4]);
-		}
-		address += max_i2c_size*4;
-		tmp_addr[1] = (uint8_t)((address>>8)&0x00FF);
-		tmp_addr[0] = (uint8_t)((address)&0x00FF);
+		address += max_i2c_size * 4;
+		tmp_addr[1] = (uint8_t)((address>>8) & 0x00FF);
+		tmp_addr[0] = (uint8_t)((address) & 0x00FF);
 	}
-	tmp_addr[3] = 0x08; tmp_addr[2] = 0x00; tmp_addr[1] = 0x04; tmp_addr[0] = 0x64;
-	tmp_data[3] = 0x11; tmp_data[2] = 0x22; tmp_data[1] = 0x33; tmp_data[0] = 0x44;
+	tmp_addr[3] = 0x08; tmp_addr[2] = 0x00;
+	tmp_addr[1] = 0x04; tmp_addr[0] = 0x64;
+	tmp_data[3] = 0x11; tmp_data[2] = 0x22;
+	tmp_data[1] = 0x33; tmp_data[0] = 0x44;
 	himax_flash_write_burst(client, tmp_addr, tmp_data);
 }
-//ts_work
-int cal_data_len(int raw_cnt_rmd, int HX_MAX_PT, int raw_cnt_max){
+/*ts_work*/
+int cal_data_len(int raw_cnt_rmd, int HX_MAX_PT, int raw_cnt_max)
+{
 	int RawDataLen;
-	if (raw_cnt_rmd != 0x00) {
-		RawDataLen = 124 - ((HX_MAX_PT+raw_cnt_max+3)*4) - 1;
-	}else{
-		RawDataLen = 124 - ((HX_MAX_PT+raw_cnt_max+2)*4) - 1;
-	}
+
+	if (raw_cnt_rmd != 0x00)
+		RawDataLen = 124 - ((HX_MAX_PT + raw_cnt_max + 3) * 4) - 1;
+	else
+		RawDataLen = 124 - ((HX_MAX_PT + raw_cnt_max + 2) * 4) - 1;
+
 	return RawDataLen;
 }
 
@@ -2016,40 +2274,40 @@
 {
 	uint8_t cmd[4];
 
-	if(length > 56)
+	if (length > 56)
 		length = 124;
-	//=====================
-	//AHB I2C Burst Read
-	//=====================
+	/*=====================
+	AHB I2C Burst Read
+	=====================*/
 	cmd[0] = 0x31;
-	if ( i2c_himax_write(client, 0x13 ,cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(client, 0x13, cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		goto err_workqueue_out;
 	}
 
 	cmd[0] = 0x10;
-	if ( i2c_himax_write(client, 0x0D ,cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(client, 0x0D, cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		goto err_workqueue_out;
 	}
-	//=====================
-	//Read event stack
-	//=====================
+	/*=====================
+	Read event stack
+	=====================*/
 	cmd[3] = 0x90; cmd[2] = 0x06; cmd[1] = 0x00; cmd[0] = 0x00;
-	if ( i2c_himax_write(client, 0x00 ,cmd, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(client, 0x00, cmd, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		goto err_workqueue_out;
 	}
 
 	cmd[0] = 0x00;
-	if ( i2c_himax_write(client, 0x0C ,cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+	if (i2c_himax_write(client, 0x0C, cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
 		E("%s: i2c access fail!\n", __func__);
 		goto err_workqueue_out;
 	}
-	i2c_himax_read(client, 0x08, buf, length,HIMAX_I2C_RETRY_TIMES);
+	i2c_himax_read(client, 0x08, buf, length, HIMAX_I2C_RETRY_TIMES);
 	return 1;
-	
-	err_workqueue_out:
+
+err_workqueue_out:
 	return 0;
 }
 
@@ -2057,62 +2315,67 @@
 {
 	return 1;
 }
-bool diag_check_sum( uint8_t hx_touch_info_size, uint8_t *buf) //return checksum value
+bool diag_check_sum(uint8_t hx_touch_info_size,
+uint8_t *buf) /*return checksum value*/
 {
 	uint16_t check_sum_cal = 0;
 	int i;
 
-	//Check 124th byte CRC
-	for (i = hx_touch_info_size, check_sum_cal = 0; i < 124; i=i+2)
-	{
-		check_sum_cal += (buf[i+1]*256 + buf[i]);
-	}
-	if (check_sum_cal % 0x10000 != 0)
-	{
-		I("%s: diag check sum fail! check_sum_cal=%X, hx_touch_info_size=%d, \n",__func__,check_sum_cal, hx_touch_info_size);
+	/*Check 124th byte CRC*/
+	for (i = hx_touch_info_size, check_sum_cal = 0 ; i < 124 ; i = i + 2)
+		check_sum_cal += (buf[i + 1] * 256 + buf[i]);
+
+	if (check_sum_cal % 0x10000 != 0) {
+		I("%s:diag chksum fail!check_sum_cal=%X,hx_touchinfo_sz=%d,\n",
+		__func__, check_sum_cal, hx_touch_info_size);
 		return 0;
 	}
 	return 1;
 }
 
-
-void diag_parse_raw_data(int hx_touch_info_size, int RawDataLen, int mul_num, int self_num, uint8_t *buf, uint8_t diag_cmd, int16_t *mutual_data, int16_t *self_data)
+void diag_parse_raw_data(int hx_touch_info_size,
+int RawDataLen, int mul_num, int self_num, uint8_t *buf,
+uint8_t diag_cmd, int16_t *mutual_data, int16_t *self_data)
 {
 	int RawDataLen_word;
 	int index = 0;
-	int temp1, temp2,i;
-	
-	if (buf[hx_touch_info_size] == 0x3A && buf[hx_touch_info_size+1] == 0xA3 && buf[hx_touch_info_size+2] > 0 && buf[hx_touch_info_size+3] == diag_cmd+5 )
-	{
-			RawDataLen_word = RawDataLen/2;
-			index = (buf[hx_touch_info_size+2] - 1) * RawDataLen_word;
-		//I("Header[%d]: %x, %x, %x, %x, mutual: %d, self: %d\n", index, buf[56], buf[57], buf[58], buf[59], mul_num, self_num);
-			for (i = 0; i < RawDataLen_word; i++)
-		{
+	int temp1, temp2, i;
+
+	if (buf[hx_touch_info_size] == 0x3A &&
+		buf[hx_touch_info_size + 1] == 0xA3 &&
+		buf[hx_touch_info_size + 2] > 0 &&
+		buf[hx_touch_info_size + 3] == diag_cmd + 5) {
+		RawDataLen_word = RawDataLen / 2;
+		index = (buf[hx_touch_info_size + 2] - 1) * RawDataLen_word;
+		/*I("Header[%d]: %x, %x, %x, %x, mutual: %d, self: %d\n",
+		index, buf[56], buf[57], buf[58], buf[59], mul_num, self_num);*/
+		for (i = 0; i < RawDataLen_word; i++) {
 			temp1 = index + i;
 
-			if (temp1 < mul_num)
-			{ //mutual
-					mutual_data[index + i] = buf[i*2 + hx_touch_info_size+4+1]*256 + buf[i*2 + hx_touch_info_size+4];	//4: RawData Header, 1:HSB
-			}
-			else
-			{//self
+			if (temp1 < mul_num) { /*mutual*/
+					/*4: RawData Header, 1:HSB */
+					mutual_data[index + i]
+					= buf[i*2 + hx_touch_info_size + 4 + 1]
+					* 256
+					+ buf[i * 2 + hx_touch_info_size + 4];
+			} else { /*self*/
 				temp1 = i + index;
 				temp2 = self_num + mul_num;
-				
-				if (temp1 >= temp2)
-				{
-					break;
-				}
 
-					self_data[i+index-mul_num] = buf[i*2 + hx_touch_info_size+4];	//4: RawData Header
-					self_data[i+index-mul_num+1] = buf[i*2 + hx_touch_info_size+4+1];
+				if (temp1 >= temp2)
+					break;
+
+				/*4: RawData Header*/
+				self_data[i + index - mul_num]
+				= buf[i * 2 + hx_touch_info_size + 4];
+				self_data[i + index - mul_num + 1]
+				= buf[i * 2 + hx_touch_info_size + 4 + 1];
 			}
 		}
-	}
-	else
-	{
+	} else {
 		I("[HIMAX TP MSG]%s: header format is wrong!\n", __func__);
-			I("Header[%d]: %x, %x, %x, %x, mutual: %d, self: %d\n", index, buf[56], buf[57], buf[58], buf[59], mul_num, self_num);
+			I("Header[%d]: %x, %x, %x, %x, mutual: %d, self: %d\n",
+			index, buf[56], buf[57], buf[58], buf[59],
+			mul_num, self_num);
 	}
 }
diff --git a/drivers/input/touchscreen/hxchipset/himax_ic.h b/drivers/input/touchscreen/hxchipset/himax_ic.h
index 18cd12b..ce7d0d4 100644
--- a/drivers/input/touchscreen/hxchipset/himax_ic.h
+++ b/drivers/input/touchscreen/hxchipset/himax_ic.h
@@ -18,7 +18,6 @@
 
 #include <linux/slab.h>
 
-
 #define HX_85XX_A_SERIES_PWON		1
 #define HX_85XX_B_SERIES_PWON		2
 #define HX_85XX_C_SERIES_PWON		3
@@ -40,43 +39,110 @@
 };
 
 int himax_hand_shaking(struct i2c_client *client);
-void himax_set_SMWP_enable(struct i2c_client *client,uint8_t SMWP_enable);
-void himax_get_SMWP_enable(struct i2c_client *client,uint8_t *tmp_data);
-void himax_set_HSEN_enable(struct i2c_client *client,uint8_t HSEN_enable);
-void himax_get_HSEN_enable(struct i2c_client *client,uint8_t *tmp_data);
+void himax_set_SMWP_enable(struct i2c_client *client, uint8_t SMWP_enable);
+void himax_get_SMWP_enable(struct i2c_client *client, uint8_t *tmp_data);
+void himax_set_HSEN_enable(struct i2c_client *client, uint8_t HSEN_enable);
+void himax_get_HSEN_enable(struct i2c_client *client, uint8_t *tmp_data);
 void himax_diag_register_set(struct i2c_client *client, uint8_t diag_command);
-void himax_flash_dump_func(struct i2c_client *client, uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer);
+
+void himax_flash_dump_func(struct i2c_client *client,
+uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer);
+
 int himax_chip_self_test(struct i2c_client *client);
-int himax_burst_enable(struct i2c_client *client, uint8_t auto_add_4_byte); ////himax_83100_BURST_INC0_EN
-void himax_register_read(struct i2c_client *client, uint8_t *read_addr, int read_length, uint8_t *read_data); ////RegisterRead83100
-void himax_flash_read(struct i2c_client *client, uint8_t *reg_byte, uint8_t *read_data); ////himax_83100_Flash_Read
-void himax_flash_write_burst(struct i2c_client *client, uint8_t * reg_byte, uint8_t * write_data); ////himax_83100_Flash_Write_Burst
-int himax_flash_write_burst_lenth(struct i2c_client *client, uint8_t *reg_byte, uint8_t *write_data, int length); ////himax_83100_Flash_Write_Burst_lenth
-int himax_register_write(struct i2c_client *client, uint8_t *write_addr, int write_length, uint8_t *write_data); ////RegisterWrite83100
-void himax_sense_off(struct i2c_client *client); ////himax_83100_SenseOff
-void himax_interface_on(struct i2c_client *client); ////himax_83100_Interface_on
+
+/*himax_83100_BURST_INC0_EN*/
+int himax_burst_enable(struct i2c_client *client, uint8_t auto_add_4_byte);
+
+/*RegisterRead83100*/
+void himax_register_read(struct i2c_client *client,
+	uint8_t *read_addr, int read_length, uint8_t *read_data);
+
+/*himax_83100_Flash_Read*/
+void himax_flash_read(struct i2c_client *client,
+	uint8_t *reg_byte, uint8_t *read_data);
+
+/*himax_83100_Flash_Write_Burst*/
+void himax_flash_write_burst(struct i2c_client *client,
+	uint8_t *reg_byte, uint8_t *write_data);
+
+/*himax_83100_Flash_Write_Burst_length*/
+int himax_flash_write_burst_length(struct i2c_client *client,
+	uint8_t *reg_byte, uint8_t *write_data, int length);
+
+/*RegisterWrite83100*/
+int himax_register_write(struct i2c_client *client,
+	uint8_t *write_addr, int write_length, uint8_t *write_data);
+
+/*himax_83100_SenseOff*/
+void himax_sense_off(struct i2c_client *client);
+/*himax_83100_Interface_on*/
+void himax_interface_on(struct i2c_client *client);
 bool wait_wip(struct i2c_client *client, int Timing);
-void himax_sense_on(struct i2c_client *client, uint8_t FlashMode); ////himax_83100_SenseOn
-void himax_chip_erase(struct i2c_client *client); ////himax_83100_Chip_Erase
-bool himax_block_erase(struct i2c_client *client); ////himax_83100_Block_Erase
-bool himax_sector_erase(struct i2c_client *client, int start_addr); ////himax_83100_Sector_Erase
-void himax_sram_write(struct i2c_client *client, uint8_t *FW_content); ////himax_83100_Sram_Write
-bool himax_sram_verify(struct i2c_client *client, uint8_t *FW_File, int FW_Size); ////himax_83100_Sram_Verify
-void himax_flash_programming(struct i2c_client *client, uint8_t *FW_content, int FW_Size); ////himax_83100_Flash_Programming
-bool himax_check_chip_version(struct i2c_client *client); ////himax_83100_CheckChipVersion
-int himax_check_CRC(struct i2c_client *client, int mode); ////himax_83100_Check_CRC
-bool Calculate_CRC_with_AP(unsigned char *FW_content , int CRC_from_FW, int mode);
-int fts_ctpm_fw_upgrade_with_sys_fs_60k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref);
-int fts_ctpm_fw_upgrade_with_sys_fs_64k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref);
-int fts_ctpm_fw_upgrade_with_sys_fs_124k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref);
-int fts_ctpm_fw_upgrade_with_sys_fs_128k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref);
+
+/*himax_83100_SenseOn*/
+void himax_sense_on(struct i2c_client *client,
+	uint8_t FlashMode);
+
+/*himax_83100_Chip_Erase*/
+void himax_chip_erase(struct i2c_client *client);
+/*himax_83100_Block_Erase*/
+bool himax_block_erase(struct i2c_client *client);
+
+/*himax_83100_Sector_Erase*/
+bool himax_sector_erase(struct i2c_client *client, int start_addr);
+
+/*himax_83100_Sram_Write*/
+void himax_sram_write(struct i2c_client *client, uint8_t *FW_content);
+
+/*himax_83100_Sram_Verify*/
+bool himax_sram_verify(struct i2c_client *client,
+	uint8_t *FW_File, int FW_Size);
+
+/*himax_83100_Flash_Programming*/
+void himax_flash_programming(struct i2c_client *client,
+	uint8_t *FW_content, int FW_Size);
+
+/*himax_83100_CheckChipVersion*/
+bool himax_check_chip_version(struct i2c_client *client);
+
+/*himax_83100_Check_CRC*/
+int himax_check_CRC(struct i2c_client *client, int mode);
+
+bool Calculate_CRC_with_AP(unsigned char *FW_content,
+	int CRC_from_FW, int mode);
+
+int fts_ctpm_fw_upgrade_with_sys_fs_60k(struct i2c_client *client,
+	unsigned char *fw, int len, bool change_iref);
+
+int fts_ctpm_fw_upgrade_with_sys_fs_64k(struct i2c_client *client,
+	unsigned char *fw, int len, bool change_iref);
+
+int fts_ctpm_fw_upgrade_with_sys_fs_124k(struct i2c_client *client,
+	unsigned char *fw, int len, bool change_iref);
+
+int fts_ctpm_fw_upgrade_with_sys_fs_128k(struct i2c_client *client,
+	unsigned char *fw, int len, bool change_iref);
+
 void himax_touch_information(struct i2c_client *client);
 void himax_read_FW_ver(struct i2c_client *client);
 bool himax_ic_package_check(struct i2c_client *client);
-void himax_read_event_stack(struct i2c_client *client, uint8_t *buf, uint8_t length);
+
+void himax_read_event_stack(struct i2c_client *client,
+	uint8_t *buf, uint8_t length);
+
 int cal_data_len(int raw_cnt_rmd, int HX_MAX_PT, int raw_cnt_max);
 bool read_event_stack(struct i2c_client *client, uint8_t *buf_ts, int length);
 bool post_read_event_stack(struct i2c_client *client);
-bool diag_check_sum( uint8_t hx_touch_info_size, uint8_t *buf_ts); //return checksum value
-void diag_parse_raw_data(int hx_touch_info_size, int RawDataLen, int mul_num, int self_num, uint8_t *buf_ts, uint8_t diag_cmd, int16_t *mutual_data,	int16_t *self_data);
-void himax_get_DSRAM_data(struct i2c_client *client, uint8_t *info_data);
\ No newline at end of file
+
+/*return checksum value*/
+bool diag_check_sum(uint8_t hx_touch_info_size, uint8_t *buf_ts);
+
+void diag_parse_raw_data(int hx_touch_info_size, int RawDataLen,
+	int mul_num, int self_num, uint8_t *buf_ts,
+	uint8_t diag_cmd, int16_t *mutual_data, int16_t *self_data);
+
+void himax_get_DSRAM_data(struct i2c_client *client, uint8_t *info_data);
+extern struct himax_ts_data *private_ts;
+extern struct himax_ic_data *ic_data;
+
+int himax_load_CRC_bin_file(struct i2c_client *client);
diff --git a/drivers/input/touchscreen/hxchipset/himax_platform.c b/drivers/input/touchscreen/hxchipset/himax_platform.c
index 7e8a1d6..309bb5e 100644
--- a/drivers/input/touchscreen/hxchipset/himax_platform.c
+++ b/drivers/input/touchscreen/hxchipset/himax_platform.c
@@ -16,6 +16,13 @@
 #include "himax_platform.h"
 #include "himax_common.h"
 
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+#define D(x...) pr_info("[HXTP][DEBUG] " x)
+#define I(x...) pr_info("[HXTP][INFO] " x)
+#define W(x...) pr_info("[HXTP][WARNING] " x)
+#define E(x...) pr_info("[HXTP][ERROR] " x)
+#endif
+
 int irq_enable_count = 0;
 #ifdef HX_SMART_WAKEUP
 #define TS_WAKE_LOCK_TIMEOUT		(2 * HZ)
@@ -25,16 +32,7 @@
 #define PINCTRL_STATE_SUSPEND	"pmx_ts_suspend"
 #define PINCTRL_STATE_RELEASE	"pmx_ts_release"
 
-extern struct himax_ic_data* ic_data;
-extern void himax_ts_work(struct himax_ts_data *ts);
-extern enum hrtimer_restart himax_ts_timer_func(struct hrtimer *timer);
-extern int himax_ts_init(struct himax_ts_data *ts);
-
-extern int tp_rst_gpio;
-
-#ifdef HX_TP_PROC_DIAG
-extern uint8_t getDiagCommand(void);
-#endif
+/*extern int himax_ts_init(struct himax_ts_data *ts);*/
 
 void himax_vk_parser(struct device_node *dt,
 				struct himax_i2c_platform_data *pdata)
@@ -49,30 +47,34 @@
 	if (node == NULL) {
 		I(" DT-No vk info in DT");
 		return;
+
 	} else {
 		while ((pp = of_get_next_child(node, pp)))
 			cnt++;
 		if (!cnt)
 			return;
 
-		vk = kzalloc(cnt * (sizeof *vk), GFP_KERNEL);
-		if (!vk)
-			return;
+		vk = kcalloc(cnt, sizeof(*vk), GFP_KERNEL);
 		pp = NULL;
 		while ((pp = of_get_next_child(node, pp))) {
 			if (of_property_read_u32(pp, "idx", &data) == 0)
 				vk[i].index = data;
-			if (of_property_read_u32_array(pp, "range", coords, 4) == 0) {
-				vk[i].x_range_min = coords[0], vk[i].x_range_max = coords[1];
-				vk[i].y_range_min = coords[2], vk[i].y_range_max = coords[3];
+			if (of_property_read_u32_array(pp, "range",
+				coords, 4) == 0) {
+				vk[i].x_range_min = coords[0],
+				vk[i].x_range_max = coords[1];
+				vk[i].y_range_min = coords[2],
+				vk[i].y_range_max = coords[3];
 			} else
 				I(" range faile");
 			i++;
 		}
 		pdata->virtual_key = vk;
 		for (i = 0; i < cnt; i++)
-			I(" vk[%d] idx:%d x_min:%d, y_max:%d", i,pdata->virtual_key[i].index,
-				pdata->virtual_key[i].x_range_min, pdata->virtual_key[i].y_range_max);
+			I(" vk[%d] idx:%d x_min:%d, y_max:%d",
+				i, pdata->virtual_key[i].index,
+				pdata->virtual_key[i].x_range_min,
+				pdata->virtual_key[i].y_range_max);
 	}
 }
 
@@ -89,25 +91,31 @@
 	if (prop) {
 		coords_size = prop->length / sizeof(u32);
 		if (coords_size != 4)
-			D(" %s:Invalid panel coords size %d", __func__, coords_size);
+			D(" %s:Invalid panel coords size %d",
+		__func__, coords_size);
 	}
 
-	if (of_property_read_u32_array(dt, "himax,panel-coords", coords, coords_size) == 0) {
+	if (of_property_read_u32_array(dt, "himax,panel-coords",
+		coords, coords_size) == 0) {
 		pdata->abs_x_min = coords[0], pdata->abs_x_max = coords[1];
 		pdata->abs_y_min = coords[2], pdata->abs_y_max = coords[3];
-		I(" DT-%s:panel-coords = %d, %d, %d, %d\n", __func__, pdata->abs_x_min,
-				pdata->abs_x_max, pdata->abs_y_min, pdata->abs_y_max);
+		I(" DT-%s:panel-coords = %d, %d, %d, %d\n",
+		__func__, pdata->abs_x_min, pdata->abs_x_max,
+		pdata->abs_y_min, pdata->abs_y_max);
 	}
 
 	prop = of_find_property(dt, "himax,display-coords", NULL);
 	if (prop) {
 		coords_size = prop->length / sizeof(u32);
 		if (coords_size != 4)
-			D(" %s:Invalid display coords size %d", __func__, coords_size);
+			D(" %s:Invalid display coords size %d",
+			__func__, coords_size);
 	}
-	rc = of_property_read_u32_array(dt, "himax,display-coords", coords, coords_size);
+	rc = of_property_read_u32_array(dt, "himax,display-coords",
+		coords, coords_size);
 	if (rc && (rc != -EINVAL)) {
-		D(" %s:Fail to read display-coords %d\n", __func__, rc);
+		D(" %s:Fail to read display-coords %d\n",
+		__func__, rc);
 		return rc;
 	}
 	pdata->screenWidth  = coords[1];
@@ -116,19 +124,19 @@
 		pdata->screenHeight);
 
 	pdata->gpio_irq = of_get_named_gpio(dt, "himax,irq-gpio", 0);
-	if (!gpio_is_valid(pdata->gpio_irq)) {
+	if (!gpio_is_valid(pdata->gpio_irq))
 		I(" DT:gpio_irq value is not valid\n");
-	}
 
 	pdata->gpio_reset = of_get_named_gpio(dt, "himax,rst-gpio", 0);
-	if (!gpio_is_valid(pdata->gpio_reset)) {
+	if (!gpio_is_valid(pdata->gpio_reset))
 		I(" DT:gpio_rst value is not valid\n");
-	}
+
 	pdata->gpio_3v3_en = of_get_named_gpio(dt, "himax,3v3-gpio", 0);
-	if (!gpio_is_valid(pdata->gpio_3v3_en)) {
+	if (!gpio_is_valid(pdata->gpio_3v3_en))
 		I(" DT:gpio_3v3_en value is not valid\n");
-	}
-	I(" DT:gpio_irq=%d, gpio_rst=%d, gpio_3v3_en=%d", pdata->gpio_irq, pdata->gpio_reset, pdata->gpio_3v3_en);
+
+	I(" DT:gpio_irq=%d, gpio_rst=%d, gpio_3v3_en=%d",
+	pdata->gpio_irq, pdata->gpio_reset, pdata->gpio_3v3_en);
 
 	if (of_property_read_u32(dt, "report_type", &data) == 0) {
 		pdata->protocol_type = data;
@@ -140,7 +148,8 @@
 	return 0;
 }
 
-int i2c_himax_read(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry)
+int i2c_himax_read(struct i2c_client *client,
+uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry)
 {
 	int retry;
 	struct i2c_msg msg[] = {
@@ -157,7 +166,7 @@
 			.buf = data,
 		}
 	};
-
+	mutex_lock(&private_ts->rw_lock);
 	for (retry = 0; retry < toRetry; retry++) {
 		if (i2c_transfer(client->adapter, msg, 2) == 2)
 			break;
@@ -166,13 +175,16 @@
 	if (retry == toRetry) {
 		E("%s: i2c_read_block retry over %d\n",
 			__func__, toRetry);
+		mutex_unlock(&private_ts->rw_lock);
 		return -EIO;
 	}
+	mutex_unlock(&private_ts->rw_lock);
 	return 0;
 
 }
 
-int i2c_himax_write(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry)
+int i2c_himax_write(struct i2c_client *client,
+uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry)
 {
 	int retry/*, loop_i*/;
 	uint8_t buf[length + 1];
@@ -188,7 +200,7 @@
 
 	buf[0] = command;
 	memcpy(buf+1, data, length);
-	
+	mutex_lock(&private_ts->rw_lock);
 	for (retry = 0; retry < toRetry; retry++) {
 		if (i2c_transfer(client->adapter, msg, 1) == 1)
 			break;
@@ -198,13 +210,16 @@
 	if (retry == toRetry) {
 		E("%s: i2c_write_block retry over %d\n",
 			__func__, toRetry);
+		mutex_unlock(&private_ts->rw_lock);
 		return -EIO;
 	}
+	mutex_unlock(&private_ts->rw_lock);
 	return 0;
 
 }
 
-int i2c_himax_read_command(struct i2c_client *client, uint8_t length, uint8_t *data, uint8_t *readlength, uint8_t toRetry)
+int i2c_himax_read_command(struct i2c_client *client,
+uint8_t length, uint8_t *data, uint8_t *readlength, uint8_t toRetry)
 {
 	int retry;
 	struct i2c_msg msg[] = {
@@ -215,7 +230,7 @@
 		.buf = data,
 		}
 	};
-
+	mutex_lock(&private_ts->rw_lock);
 	for (retry = 0; retry < toRetry; retry++) {
 		if (i2c_transfer(client->adapter, msg, 1) == 1)
 			break;
@@ -224,17 +239,21 @@
 	if (retry == toRetry) {
 		E("%s: i2c_read_block retry over %d\n",
 		       __func__, toRetry);
+		mutex_unlock(&private_ts->rw_lock);
 		return -EIO;
 	}
+	mutex_unlock(&private_ts->rw_lock);
 	return 0;
 }
 
-int i2c_himax_write_command(struct i2c_client *client, uint8_t command, uint8_t toRetry)
+int i2c_himax_write_command(struct i2c_client *client,
+uint8_t command, uint8_t toRetry)
 {
 	return i2c_himax_write(client, command, NULL, 0, toRetry);
 }
 
-int i2c_himax_master_write(struct i2c_client *client, uint8_t *data, uint8_t length, uint8_t toRetry)
+int i2c_himax_master_write(struct i2c_client *client,
+uint8_t *data, uint8_t length, uint8_t toRetry)
 {
 	int retry/*, loop_i*/;
 	uint8_t buf[length];
@@ -249,7 +268,7 @@
 	};
 
 	memcpy(buf, data, length);
-	
+	mutex_lock(&private_ts->rw_lock);
 	for (retry = 0; retry < toRetry; retry++) {
 		if (i2c_transfer(client->adapter, msg, 1) == 1)
 			break;
@@ -259,8 +278,10 @@
 	if (retry == toRetry) {
 		E("%s: i2c_write_block retry over %d\n",
 		       __func__, toRetry);
+		mutex_unlock(&private_ts->rw_lock);
 		return -EIO;
 	}
+	mutex_unlock(&private_ts->rw_lock);
 	return 0;
 }
 
@@ -287,62 +308,51 @@
 }
 
 #if defined(CONFIG_HMX_DB)
-static int himax_regulator_configure(struct i2c_client *client,struct himax_i2c_platform_data *pdata)
+static int himax_regulator_configure(struct i2c_client *client,
+struct himax_i2c_platform_data *pdata)
 {
-    int retval;
-    pdata->vcc_dig = regulator_get(&client->dev,
-                                   "vdd");
-    if (IS_ERR(pdata->vcc_dig))
-    {
-        E("%s: Failed to get regulator vdd\n",
-          __func__);
-        retval = PTR_ERR(pdata->vcc_dig);
-        return retval;
-    }
-    pdata->vcc_ana = regulator_get(&client->dev,
-                                   "avdd");
-    if (IS_ERR(pdata->vcc_ana))
-    {
-        E("%s: Failed to get regulator avdd\n",
-          __func__);
-        retval = PTR_ERR(pdata->vcc_ana);
-        regulator_put(pdata->vcc_ana);
-        return retval;
-    }
+	int retval;
 
-    return 0;
+	pdata->vcc_dig = regulator_get(&client->dev, "vdd");
+	if (IS_ERR(pdata->vcc_dig)) {
+		E("%s: Failed to get regulator vdd\n", __func__);
+		retval = PTR_ERR(pdata->vcc_dig);
+		return retval;
+	}
+	pdata->vcc_ana = regulator_get(&client->dev, "avdd");
+	if (IS_ERR(pdata->vcc_ana)) {
+		E("%s: Failed to get regulator avdd\n", __func__);
+		retval = PTR_ERR(pdata->vcc_ana);
+		regulator_put(pdata->vcc_ana);
+		return retval;
+	}
+
+	return 0;
 };
 
-static int himax_power_on(struct himax_i2c_platform_data *pdata, bool on)
+static int himax_power_on(struct himax_i2c_platform_data *pdata,
+bool on)
 {
-    int retval;
+	int retval;
 
-    if (on)
-    {
-        retval = regulator_enable(pdata->vcc_dig);
-        if (retval)
-        {
-            E("%s: Failed to enable regulator vdd\n",
-              __func__);
-            return retval;
-        }
-        msleep(100);
-        retval = regulator_enable(pdata->vcc_ana);
-        if (retval)
-        {
-            E("%s: Failed to enable regulator avdd\n",
-              __func__);
-            regulator_disable(pdata->vcc_dig);
-            return retval;
-        }
-    }
-    else
-    {
-        regulator_disable(pdata->vcc_dig);
-        regulator_disable(pdata->vcc_ana);
-    }
-
-    return 0;
+	if (on) {
+		retval = regulator_enable(pdata->vcc_dig);
+		if (retval) {
+			E("%s: Failed to enable regulator vdd\n", __func__);
+			return retval;
+		}
+		msleep(100);
+		retval = regulator_enable(pdata->vcc_ana);
+		if (retval) {
+			E("%s: Failed to enable regulator avdd\n", __func__);
+			regulator_disable(pdata->vcc_dig);
+			return retval;
+		}
+	} else {
+		regulator_disable(pdata->vcc_dig);
+		regulator_disable(pdata->vcc_ana);
+	}
+	return 0;
 }
 
 int himax_ts_pinctrl_init(struct himax_ts_data *ts)
@@ -353,41 +363,35 @@
 	ts->ts_pinctrl = devm_pinctrl_get(&(ts->client->dev));
 	if (IS_ERR_OR_NULL(ts->ts_pinctrl)) {
 		retval = PTR_ERR(ts->ts_pinctrl);
-		dev_dbg(&ts->client->dev,
-			"Target does not use pinctrl %d\n", retval);
+		dev_dbg(&ts->client->dev, "Target does not use pinctrl %d\n",
+		retval);
 		goto err_pinctrl_get;
 	}
 
-	ts->pinctrl_state_active
-		= pinctrl_lookup_state(ts->ts_pinctrl,
-				PINCTRL_STATE_ACTIVE);
+	ts->pinctrl_state_active = pinctrl_lookup_state(ts->ts_pinctrl,
+						PINCTRL_STATE_ACTIVE);
 	if (IS_ERR_OR_NULL(ts->pinctrl_state_active)) {
 		retval = PTR_ERR(ts->pinctrl_state_active);
-		dev_err(&ts->client->dev,
-			"Can not lookup %s pinstate %d\n",
-			PINCTRL_STATE_ACTIVE, retval);
+		dev_err(&ts->client->dev, "Can not lookup %s pinstate %d\n",
+		PINCTRL_STATE_ACTIVE, retval);
 		goto err_pinctrl_lookup;
 	}
 
-	ts->pinctrl_state_suspend
-		= pinctrl_lookup_state(ts->ts_pinctrl,
-			PINCTRL_STATE_SUSPEND);
+	ts->pinctrl_state_suspend = pinctrl_lookup_state(ts->ts_pinctrl,
+						PINCTRL_STATE_SUSPEND);
 	if (IS_ERR_OR_NULL(ts->pinctrl_state_suspend)) {
 		retval = PTR_ERR(ts->pinctrl_state_suspend);
-		dev_err(&ts->client->dev,
-			"Can not lookup %s pinstate %d\n",
-			PINCTRL_STATE_SUSPEND, retval);
+		dev_err(&ts->client->dev, "Can not lookup %s pinstate %d\n",
+		PINCTRL_STATE_SUSPEND, retval);
 		goto err_pinctrl_lookup;
 	}
 
-	ts->pinctrl_state_release
-		= pinctrl_lookup_state(ts->ts_pinctrl,
-			PINCTRL_STATE_RELEASE);
+	ts->pinctrl_state_release = pinctrl_lookup_state(ts->ts_pinctrl,
+						PINCTRL_STATE_RELEASE);
 	if (IS_ERR_OR_NULL(ts->pinctrl_state_release)) {
 		retval = PTR_ERR(ts->pinctrl_state_release);
-		dev_dbg(&ts->client->dev,
-			"Can not lookup %s pinstate %d\n",
-			PINCTRL_STATE_RELEASE, retval);
+		dev_dbg(&ts->client->dev, "Can not lookup %s pinstate %d\n",
+		PINCTRL_STATE_RELEASE, retval);
 	}
 
 	return 0;
@@ -399,187 +403,163 @@
 	return retval;
 }
 
-int himax_gpio_power_config(struct i2c_client *client,struct himax_i2c_platform_data *pdata)
+int himax_gpio_power_config(struct i2c_client *client,
+struct himax_i2c_platform_data *pdata)
 {
-    int error;
+	int error;
 
-    error = himax_regulator_configure(client, pdata);
-    if (error)
-    {
-        E("Failed to intialize hardware\n");
-        goto err_regulator_not_on;
-    }
+	error = himax_regulator_configure(client, pdata);
+	if (error) {
+		E("Failed to initialize hardware\n");
+		goto err_regulator_not_on;
+	}
 
 #ifdef HX_RST_PIN_FUNC
-    if (gpio_is_valid(pdata->gpio_reset))
-    {
-        /* configure touchscreen reset out gpio */
-        error = gpio_request(pdata->gpio_reset, "hmx_reset_gpio");
-        if (error)
-        {
-            E("unable to request gpio [%d]\n",
-              pdata->gpio_reset);
-            goto err_regulator_on;
-        }
-
-        error = gpio_direction_output(pdata->gpio_reset, 0);
-        if (error)
-        {
-            E("unable to set direction for gpio [%d]\n",
-              pdata->gpio_reset);
-            goto err_gpio_reset_req;
-        }
-    }
+	if (gpio_is_valid(pdata->gpio_reset)) {
+		/* configure touchscreen reset out gpio */
+		error = gpio_request(pdata->gpio_reset, "hmx_reset_gpio");
+		if (error) {
+			E("unable to request gpio [%d]\n",
+			pdata->gpio_reset);
+			goto err_regulator_on;
+		}
+		error = gpio_direction_output(pdata->gpio_reset, 0);
+		if (error) {
+			E("unable to set direction for gpio [%d]\n",
+			pdata->gpio_reset);
+			goto err_gpio_reset_req;
+		}
+	}
 #endif
 
-    error = himax_power_on(pdata, true);
-    if (error)
-    {
-        E("Failed to power on hardware\n");
-        goto err_gpio_reset_req;
-    }
+	error = himax_power_on(pdata, true);
+	if (error) {
+		E("Failed to power on hardware\n");
+		goto err_gpio_reset_req;
+	}
 #ifdef HX_IRQ_PIN_FUNC
-    if (gpio_is_valid(pdata->gpio_irq))
-    {
-        /* configure touchscreen irq gpio */
-        error = gpio_request(pdata->gpio_irq, "hmx_gpio_irq");
-        if (error)
-        {
-            E("unable to request gpio [%d]\n",
-              pdata->gpio_irq);
-            goto err_power_on;
-        }
-        error = gpio_direction_input(pdata->gpio_irq);
-        if (error)
-        {
-            E("unable to set direction for gpio [%d]\n",
-              pdata->gpio_irq);
-            goto err_gpio_irq_req;
-        }
-        client->irq = gpio_to_irq(pdata->gpio_irq);
-    }
-    else
-    {
-        E("irq gpio not provided\n");
-        goto err_power_on;
-    }
+	/* configure touchscreen irq gpio */
+	if (gpio_is_valid(pdata->gpio_irq)) {
+		error = gpio_request(pdata->gpio_irq, "hmx_gpio_irq");
+		if (error) {
+			E("unable to request gpio [%d]\n", pdata->gpio_irq);
+			goto err_power_on;
+		}
+		error = gpio_direction_input(pdata->gpio_irq);
+		if (error) {
+			E("unable to set direction for gpio [%d]\n",
+			pdata->gpio_irq);
+			goto err_gpio_irq_req;
+		}
+		client->irq = gpio_to_irq(pdata->gpio_irq);
+	} else {
+		E("irq gpio not provided\n");
+		goto err_power_on;
+	}
 #endif
-
-    msleep(20);
+	msleep(20);
 
 #ifdef HX_RST_PIN_FUNC
-    if (gpio_is_valid(pdata->gpio_reset))
-    {
-        error = gpio_direction_output(pdata->gpio_reset, 1);
-        if (error)
-        {
-            E("unable to set direction for gpio [%d]\n",
-              pdata->gpio_reset);
-            goto err_gpio_irq_req;
-        }
-    }
+	if (gpio_is_valid(pdata->gpio_reset)) {
+		error = gpio_direction_output(pdata->gpio_reset, 1);
+		if (error) {
+			E("unable to set direction for gpio [%d]\n",
+			pdata->gpio_reset);
+			goto err_gpio_irq_req;
+		}
+	}
 #endif
-    return 0;
+	return 0;
 #ifdef HX_RST_PIN_FUNC
-	err_gpio_irq_req:
+err_gpio_irq_req:
 #endif
 #ifdef HX_IRQ_PIN_FUNC
-    if (gpio_is_valid(pdata->gpio_irq))
-        gpio_free(pdata->gpio_irq);
-	err_power_on:
+	if (gpio_is_valid(pdata->gpio_irq))
+		gpio_free(pdata->gpio_irq);
+err_power_on:
 #endif
-    himax_power_on(pdata, false);
-	err_gpio_reset_req:
+	himax_power_on(pdata, false);
+err_gpio_reset_req:
 #ifdef HX_RST_PIN_FUNC
-    if (gpio_is_valid(pdata->gpio_reset))
-        gpio_free(pdata->gpio_reset);
-	err_regulator_on:
+	if (gpio_is_valid(pdata->gpio_reset))
+		gpio_free(pdata->gpio_reset);
+err_regulator_on:
 #endif
-	err_regulator_not_on:
+err_regulator_not_on:
 
-    return error;
+	return error;
 }
 
 #else
-int himax_gpio_power_config(struct i2c_client *client,struct himax_i2c_platform_data *pdata)
+int himax_gpio_power_config(struct i2c_client *client,
+struct himax_i2c_platform_data *pdata)
 {
-		int error=0;
-	
-#ifdef HX_RST_PIN_FUNC
-		if (pdata->gpio_reset >= 0)
-		{
-			error = gpio_request(pdata->gpio_reset, "himax-reset");
-			if (error < 0)
-			{
-				E("%s: request reset pin failed\n", __func__);
-				return error;
-			}
-			error = gpio_direction_output(pdata->gpio_reset, 0);
-			if (error)
-			{
-				E("unable to set direction for gpio [%d]\n",
-				  pdata->gpio_reset);
-				return error;
-			}
-		}
-#endif
-		if (pdata->gpio_3v3_en >= 0)
-		{
-			error = gpio_request(pdata->gpio_3v3_en, "himax-3v3_en");
-			if (error < 0)
-			{
-				E("%s: request 3v3_en pin failed\n", __func__);
-				return error;
-			}
-			gpio_direction_output(pdata->gpio_3v3_en, 1);
-			I("3v3_en pin =%d\n", gpio_get_value(pdata->gpio_3v3_en));
-		}
+	int error = 0;
 
-#ifdef HX_IRQ_PIN_FUNC
-		if (gpio_is_valid(pdata->gpio_irq))
-		{
-			/* configure touchscreen irq gpio */
-			error = gpio_request(pdata->gpio_irq, "himax_gpio_irq");
-			if (error)
-			{
-				E("unable to request gpio [%d]\n",pdata->gpio_irq);
-				return error;
-			}
-			error = gpio_direction_input(pdata->gpio_irq);
-			if (error)
-			{
-				E("unable to set direction for gpio [%d]\n",pdata->gpio_irq);
-				return error;
-			}
-			client->irq = gpio_to_irq(pdata->gpio_irq);
-		}
-		else
-		{
-			E("irq gpio not provided\n");
+#ifdef HX_RST_PIN_FUNC
+	if (pdata->gpio_reset >= 0) {
+		error = gpio_request(pdata->gpio_reset, "himax-reset");
+		if (error < 0) {
+			E("%s: request reset pin failed\n", __func__);
 			return error;
 		}
-#endif
-
-		msleep(20);
-	
-#ifdef HX_RST_PIN_FUNC
-		if (pdata->gpio_reset >= 0)
-		{
-			error = gpio_direction_output(pdata->gpio_reset, 1);
-			if (error)
-			{
-				E("unable to set direction for gpio [%d]\n",
-				  pdata->gpio_reset);
-				return error;
-			}
+		error = gpio_direction_output(pdata->gpio_reset, 0);
+		if (error) {
+			E("unable to set direction for gpio [%d]\n",
+			  pdata->gpio_reset);
+			return error;
 		}
-		msleep(20);
+	}
 #endif
-	
+	if (pdata->gpio_3v3_en >= 0) {
+		error = gpio_request(pdata->gpio_3v3_en, "himax-3v3_en");
+		if (error < 0) {
+			E("%s: request 3v3_en pin failed\n", __func__);
+			return error;
+		}
+		gpio_direction_output(pdata->gpio_3v3_en, 1);
+		I("3v3_en pin =%d\n", gpio_get_value(pdata->gpio_3v3_en));
+	}
+
+#ifdef HX_IRQ_PIN_FUNC
+	if (gpio_is_valid(pdata->gpio_irq)) {
+		/* configure touchscreen irq gpio */
+		error = gpio_request(pdata->gpio_irq, "himax_gpio_irq");
+		if (error) {
+			E("unable to request gpio [%d]\n", pdata->gpio_irq);
+			return error;
+		}
+		error = gpio_direction_input(pdata->gpio_irq);
+		if (error) {
+			E("unable to set direction for gpio [%d]\n",
+			pdata->gpio_irq);
+			return error;
+		}
+		client->irq = gpio_to_irq(pdata->gpio_irq);
+	} else {
+		E("irq gpio not provided\n");
 		return error;
 	}
 #endif
 
+	msleep(20);
+
+#ifdef HX_RST_PIN_FUNC
+	if (pdata->gpio_reset >= 0) {
+		error = gpio_direction_output(pdata->gpio_reset, 1);
+		if (error) {
+			E("unable to set direction for gpio [%d]\n",
+			  pdata->gpio_reset);
+			return error;
+		}
+	}
+	msleep(20);
+#endif
+
+	return error;
+}
+#endif
+
 static void himax_ts_isr_func(struct himax_ts_data *ts)
 {
 	himax_ts_work(ts);
@@ -595,34 +575,40 @@
 
 	if (ts->debug_log_level & BIT(2)) {
 			getnstimeofday(&timeStart);
-			usleep_range(5000, 7000);
-			//I(" Irq start time = %ld.%06ld s\n",
-			//	timeStart.tv_sec, timeStart.tv_nsec/1000);
+			usleep_range(4999, 5000);
+			/*I(" Irq start time = %ld.%06ld s\n",
+			timeStart.tv_sec, timeStart.tv_nsec/1000);*/
 	}
 
 #ifdef HX_SMART_WAKEUP
-	if (atomic_read(&ts->suspend_mode)&&(!FAKE_POWER_KEY_SEND)&&(ts->SMWP_enable)&&(!diag_cmd)) {
-		wake_lock_timeout(&ts->ts_SMWP_wake_lock, TS_WAKE_LOCK_TIMEOUT);
+	if (atomic_read(&ts->suspend_mode)
+		&& (!FAKE_POWER_KEY_SEND)
+		&& (ts->SMWP_enable)
+		&& (!diag_cmd)) {
+		__pm_wakeup_event(&ts->ts_SMWP_wake_lock, TS_WAKE_LOCK_TIMEOUT);
 		msleep(200);
 		himax_wake_check_func();
 		return IRQ_HANDLED;
 	}
 #endif
 	himax_ts_isr_func((struct himax_ts_data *)ptr);
-	if(ts->debug_log_level & BIT(2)) {
-			getnstimeofday(&timeEnd);
-				timeDelta.tv_nsec = (timeEnd.tv_sec*1000000000+timeEnd.tv_nsec)
-				-(timeStart.tv_sec*1000000000+timeStart.tv_nsec);
-			//I("Irq finish time = %ld.%06ld s\n",
-			//	timeEnd.tv_sec, timeEnd.tv_nsec/1000);
-			//I("Touch latency = %ld us\n", timeDelta.tv_nsec/1000);
+	if (ts->debug_log_level & BIT(2)) {
+		getnstimeofday(&timeEnd);
+		timeDelta.tv_nsec
+		= (timeEnd.tv_sec * 1000000000 + timeEnd.tv_nsec)
+		- (timeStart.tv_sec * 1000000000 + timeStart.tv_nsec);
+		/*I("Irq finish time = %ld.%06ld s\n",
+			timeEnd.tv_sec, timeEnd.tv_nsec/1000);
+		I("Touch latency = %ld us\n", timeDelta.tv_nsec/1000);*/
 	}
 	return IRQ_HANDLED;
 }
 
 static void himax_ts_work_func(struct work_struct *work)
 {
-	struct himax_ts_data *ts = container_of(work, struct himax_ts_data, work);
+	struct himax_ts_data *ts =
+	container_of(work, struct himax_ts_data, work);
+
 	himax_ts_work(ts);
 }
 
@@ -634,24 +620,26 @@
 	int ret = 0;
 
 	ts->irq_enabled = 0;
-	//Work functon
+	/*Work functon*/
 	if (client->irq) {/*INT mode*/
 		ts->use_irq = 1;
-		if(ic_data->HX_INT_IS_EDGE)
-			{
-				I("%s edge triiger falling\n ",__func__);
-				ret = request_threaded_irq(client->irq, NULL, himax_ts_thread,IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->name, ts);
-			}
-		else
-			{
-				I("%s level trigger low\n ",__func__);
-				ret = request_threaded_irq(client->irq, NULL, himax_ts_thread,IRQF_TRIGGER_LOW | IRQF_ONESHOT, client->name, ts);
+		if (ic_data->HX_INT_IS_EDGE) {
+				I("%s edge triiger falling\n ", __func__);
+				ret = request_threaded_irq(client->irq,
+				NULL, himax_ts_thread, IRQF_TRIGGER_FALLING
+				| IRQF_ONESHOT, client->name, ts);
+			} else {
+				I("%s level trigger low\n ", __func__);
+				ret = request_threaded_irq(client->irq,
+				NULL, himax_ts_thread, IRQF_TRIGGER_LOW
+				| IRQF_ONESHOT, client->name, ts);
 			}
 		if (ret == 0) {
 			ts->irq_enabled = 1;
 			irq_enable_count = 1;
 			tp_irq = client->irq;
-			I("%s: irq enabled at qpio: %d\n", __func__, client->irq);
+			I("%s: irq enabled at qpio: %d\n",
+			__func__, client->irq);
 #ifdef HX_SMART_WAKEUP
 			irq_set_irq_wake(client->irq, 1);
 #endif
@@ -662,8 +650,8 @@
 	} else {
 		I("%s: client->irq is empty, use polling mode.\n", __func__);
 	}
-
-	if (!ts->use_irq) {/*if use polling mode need to disable HX_ESD_WORKAROUND function*/
+	/*if use polling mode need to disable HX_ESD_WORKAROUND function*/
+	if (!ts->use_irq) {
 		ts->himax_wq = create_singlethread_workqueue("himax_touch");
 
 		INIT_WORK(&ts->work, himax_ts_work_func);
@@ -680,7 +668,7 @@
 {
 	struct himax_ts_data *ts = dev_get_drvdata(dev);
 
-	I("%s: enter \n", __func__);
+	I("%s: enter\n", __func__);
 
 	himax_chip_common_suspend(ts);
 	return 0;
@@ -690,7 +678,7 @@
 {
 	struct himax_ts_data *ts = dev_get_drvdata(dev);
 
-	I("%s: enter \n", __func__);
+	I("%s: enter\n", __func__);
 
 	himax_chip_common_resume(ts);
 	return 0;
@@ -702,23 +690,28 @@
 {
 	struct fb_event *evdata = data;
 	int *blank;
-	struct himax_ts_data *ts=
-		container_of(self, struct himax_ts_data, fb_notif);
+	struct himax_ts_data *ts
+	= container_of(self, struct himax_ts_data, fb_notif);
+	int ERR = 1;
 
 	I(" %s\n", __func__);
-	if (evdata && evdata->data && event == FB_EVENT_BLANK && ts &&
-			ts->client) {
+	if (evdata && evdata->data && event
+	== FB_EVENT_BLANK && ts && ts->client) {
 		blank = evdata->data;
 
 		mutex_lock(&ts->fb_mutex);
 		switch (*blank) {
 		case FB_BLANK_UNBLANK:
 			if (!ts->probe_done) {
-				himax_ts_init(ts);
-				ts->probe_done = true;
-			} else {
+				if (himax_ts_init(ts) == true) {
+					I("himax_ts_init return OK\n");
+					ts->probe_done = true;
+				} else {
+					I("himax_ts_init return Fail\n");
+					return -ERR;
+				}
+			} else
 				himax_common_resume(&ts->client->dev);
-			}
 		break;
 
 		case FB_BLANK_POWERDOWN:
@@ -748,7 +741,7 @@
 };
 
 #ifdef CONFIG_OF
-static const struct of_device_id himax_match_table[] = {
+static struct of_device_id himax_match_table[] = {
 	{.compatible = "himax,hxcommon" },
 	{},
 };
@@ -770,16 +763,10 @@
 	},
 };
 
-static void __init himax_common_init_async(void *unused, async_cookie_t cookie)
-{
-	I("%s:Enter \n", __func__);
-	i2c_add_driver(&himax_common_driver);
-}
-
 static int __init himax_common_init(void)
 {
 	I("Himax common touch panel driver init\n");
-	async_schedule(himax_common_init_async, NULL);
+	i2c_add_driver(&himax_common_driver);
 	return 0;
 }
 
@@ -792,5 +779,5 @@
 module_exit(himax_common_exit);
 
 MODULE_DESCRIPTION("Himax_common driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 
diff --git a/drivers/input/touchscreen/hxchipset/himax_platform.h b/drivers/input/touchscreen/hxchipset/himax_platform.h
index 1223685..6871e53 100644
--- a/drivers/input/touchscreen/hxchipset/himax_platform.h
+++ b/drivers/input/touchscreen/hxchipset/himax_platform.h
@@ -22,6 +22,7 @@
 #include <linux/types.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
+
 #if defined(CONFIG_HMX_DB)
 #include <linux/regulator/consumer.h>
 #endif
@@ -31,15 +32,11 @@
 #define HIMAX_I2C_RETRY_TIMES 10
 
 #if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
-#define D(x...) pr_debug("[HXTP] " x)
-#define I(x...) pr_info("[HXTP] " x)
-#define W(x...) pr_warning("[HXTP][WARNING] " x)
-#define E(x...) pr_err("[HXTP][ERROR] " x)
-#define DIF(x...) \
-do {\
-	if (debug_flag) \
-	pr_debug("[HXTP][DEBUG] " x) \
-} while(0)
+#define D(x...) pr_info("[HXTP][DEBUG] " x)
+#define I(x...) pr_info("[HXTP][INFO] " x)
+#define W(x...) pr_info("[HXTP][WARNING] " x)
+#define E(x...) pr_info("[HXTP][ERROR] " x)
+#define DIF(x...) do { if (debug_flag) pr_info("[HXTP][DEBUG] " x) } while (0)
 #else
 #define D(x...)
 #define I(x...)
@@ -53,24 +50,24 @@
 #define HX_VTG_MIN_UV			2700000
 #define HX_VTG_MAX_UV			3300000
 #define HX_ACTIVE_LOAD_UA		15000
-#define HX_LPM_LOAD_UA 			10
+#define HX_LPM_LOAD_UA			10
 /* Digital voltage @1.8 V */
 #define HX_VTG_DIG_MIN_UV		1800000
 #define HX_VTG_DIG_MAX_UV		1800000
 #define HX_ACTIVE_LOAD_DIG_UA	10000
-#define HX_LPM_LOAD_DIG_UA 		10
+#define HX_LPM_LOAD_DIG_UA		10
 
 #define HX_I2C_VTG_MIN_UV		1800000
 #define HX_I2C_VTG_MAX_UV		1800000
-#define HX_I2C_LOAD_UA 			10000
-#define HX_I2C_LPM_LOAD_UA 		10
+#define HX_I2C_LOAD_UA			10000
+#define HX_I2C_LPM_LOAD_UA		10
 #endif
 
-#define HIMAX_common_NAME 				"himax_tp"
+#define HIMAX_common_NAME				"himax_tp"
 #define HIMAX_I2C_ADDR					0x48
 #define INPUT_DEV_NAME					"himax-touchscreen"
 
-struct himax_i2c_platform_data {	
+struct himax_i2c_platform_data {
 	int abs_x_min;
 	int abs_x_max;
 	int abs_x_fuzz;
@@ -108,28 +105,53 @@
 	int irq_gpio;
 	u32 irq_gpio_flags;
 
-	struct regulator *vcc_ana; //For Dragon Board
-	struct regulator *vcc_dig; //For Dragon Board
-	struct regulator *vcc_i2c; //For Dragon Board
-#endif	
+	struct regulator *vcc_ana; /*For Dragon Board*/
+	struct regulator *vcc_dig; /*For Dragon Board*/
+	struct regulator *vcc_i2c; /*For Dragon Board*/
+#endif
 };
 
 
 extern int irq_enable_count;
-extern int i2c_himax_read(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry);
-extern int i2c_himax_write(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry);
-extern int i2c_himax_write_command(struct i2c_client *client, uint8_t command, uint8_t toRetry);
-extern int i2c_himax_master_write(struct i2c_client *client, uint8_t *data, uint8_t length, uint8_t toRetry);
-extern int i2c_himax_read_command(struct i2c_client *client, uint8_t length, uint8_t *data, uint8_t *readlength, uint8_t toRetry);
-extern void himax_int_enable(int irqnum, int enable);
-extern int himax_ts_register_interrupt(struct i2c_client *client);
-extern void himax_rst_gpio_set(int pinnum, uint8_t value);
-extern uint8_t himax_int_gpio_read(int pinnum);
+int i2c_himax_read(struct i2c_client *client,
+	uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry);
 
-extern int himax_gpio_power_config(struct i2c_client *client,struct himax_i2c_platform_data *pdata);
+int i2c_himax_write(struct i2c_client *client,
+	uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry);
+
+int i2c_himax_write_command(struct i2c_client *client,
+	uint8_t command, uint8_t toRetry);
+
+int i2c_himax_master_write(struct i2c_client *client,
+	uint8_t *data, uint8_t length, uint8_t toRetry);
+
+int i2c_himax_read_command(struct i2c_client *client,
+	uint8_t length, uint8_t *data, uint8_t *readlength, uint8_t toRetry);
+
+void himax_int_enable(int irqnum, int enable);
+int himax_ts_register_interrupt(struct i2c_client *client);
+void himax_rst_gpio_set(int pinnum, uint8_t value);
+uint8_t himax_int_gpio_read(int pinnum);
+
+int himax_gpio_power_config(struct i2c_client *client,
+	struct himax_i2c_platform_data *pdata);
 
 #if defined(CONFIG_FB)
-extern int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data);
+extern int fb_notifier_callback(struct notifier_block *self,
+	unsigned long event, void *data);
 #endif
+extern struct himax_ts_data *private_ts;
+extern struct himax_ic_data *ic_data;
+extern void himax_ts_work(struct himax_ts_data *ts);
+extern enum hrtimer_restart himax_ts_timer_func(struct hrtimer *timer);
+extern int tp_rst_gpio;
+
+#ifdef HX_TP_PROC_DIAG
+extern uint8_t getDiagCommand(void);
+#endif
+
+int himax_parse_dt(struct himax_ts_data *ts,
+		struct himax_i2c_platform_data *pdata);
+int himax_ts_pinctrl_init(struct himax_ts_data *ts);
 
 #endif
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 6b71457..08fcdbf 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -213,11 +213,10 @@
 }
 
 #ifdef CONFIG_ARM64
-static DEFINE_STATIC_KEY_FALSE(is_cavium_thunderx);
 
 static u64 __maybe_unused gic_read_iar(void)
 {
-	if (static_branch_unlikely(&is_cavium_thunderx))
+	if (cpus_have_const_cap(ARM64_WORKAROUND_CAVIUM_23154))
 		return gic_read_iar_cavium_thunderx();
 	else
 		return gic_read_iar_common();
@@ -1334,14 +1333,6 @@
 	.select = gic_irq_domain_select,
 };
 
-static void gicv3_enable_quirks(void)
-{
-#ifdef CONFIG_ARM64
-	if (cpus_have_cap(ARM64_WORKAROUND_CAVIUM_23154))
-		static_branch_enable(&is_cavium_thunderx);
-#endif
-}
-
 static int __init gic_init_bases(void __iomem *dist_base,
 				 struct redist_region *rdist_regs,
 				 u32 nr_redist_regions,
@@ -1364,8 +1355,6 @@
 	gic_data.nr_redist_regions = nr_redist_regions;
 	gic_data.redist_stride = redist_stride;
 
-	gicv3_enable_quirks();
-
 	/*
 	 * Find out how many interrupts are supported.
 	 * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI)
diff --git a/drivers/isdn/hardware/eicon/diva.c b/drivers/isdn/hardware/eicon/diva.c
index d91dd58..37aaea8 100644
--- a/drivers/isdn/hardware/eicon/diva.c
+++ b/drivers/isdn/hardware/eicon/diva.c
@@ -387,10 +387,10 @@
 **  Receive and process command from user mode utility
 */
 void *diva_xdi_open_adapter(void *os_handle, const void __user *src,
-			    int length,
+			    int length, void *mptr,
 			    divas_xdi_copy_from_user_fn_t cp_fn)
 {
-	diva_xdi_um_cfg_cmd_t msg;
+	diva_xdi_um_cfg_cmd_t *msg = (diva_xdi_um_cfg_cmd_t *)mptr;
 	diva_os_xdi_adapter_t *a = NULL;
 	diva_os_spin_lock_magic_t old_irql;
 	struct list_head *tmp;
@@ -400,21 +400,21 @@
 			 length, sizeof(diva_xdi_um_cfg_cmd_t)))
 			return NULL;
 	}
-	if ((*cp_fn) (os_handle, &msg, src, sizeof(msg)) <= 0) {
+	if ((*cp_fn) (os_handle, msg, src, sizeof(*msg)) <= 0) {
 		DBG_ERR(("A: A(?) open, write error"))
 			return NULL;
 	}
 	diva_os_enter_spin_lock(&adapter_lock, &old_irql, "open_adapter");
 	list_for_each(tmp, &adapter_queue) {
 		a = list_entry(tmp, diva_os_xdi_adapter_t, link);
-		if (a->controller == (int)msg.adapter)
+		if (a->controller == (int)msg->adapter)
 			break;
 		a = NULL;
 	}
 	diva_os_leave_spin_lock(&adapter_lock, &old_irql, "open_adapter");
 
 	if (!a) {
-		DBG_ERR(("A: A(%d) open, adapter not found", msg.adapter))
+		DBG_ERR(("A: A(%d) open, adapter not found", msg->adapter))
 			}
 
 	return (a);
@@ -436,8 +436,10 @@
 
 int
 diva_xdi_write(void *adapter, void *os_handle, const void __user *src,
-	       int length, divas_xdi_copy_from_user_fn_t cp_fn)
+	       int length, void *mptr,
+	       divas_xdi_copy_from_user_fn_t cp_fn)
 {
+	diva_xdi_um_cfg_cmd_t *msg = (diva_xdi_um_cfg_cmd_t *)mptr;
 	diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) adapter;
 	void *data;
 
@@ -458,7 +460,13 @@
 			return (-2);
 	}
 
-	length = (*cp_fn) (os_handle, data, src, length);
+	if (msg) {
+		*(diva_xdi_um_cfg_cmd_t *)data = *msg;
+		length = (*cp_fn) (os_handle, (char *)data + sizeof(*msg),
+				   src + sizeof(*msg), length - sizeof(*msg));
+	} else {
+		length = (*cp_fn) (os_handle, data, src, length);
+	}
 	if (length > 0) {
 		if ((*(a->interface.cmd_proc))
 		    (a, (diva_xdi_um_cfg_cmd_t *) data, length)) {
diff --git a/drivers/isdn/hardware/eicon/diva.h b/drivers/isdn/hardware/eicon/diva.h
index e979085..a0a607c 100644
--- a/drivers/isdn/hardware/eicon/diva.h
+++ b/drivers/isdn/hardware/eicon/diva.h
@@ -19,10 +19,11 @@
 		  int max_length, divas_xdi_copy_to_user_fn_t cp_fn);
 
 int diva_xdi_write(void *adapter, void *os_handle, const void __user *src,
-		   int length, divas_xdi_copy_from_user_fn_t cp_fn);
+		   int length, void *msg,
+		   divas_xdi_copy_from_user_fn_t cp_fn);
 
 void *diva_xdi_open_adapter(void *os_handle, const void __user *src,
-			    int length,
+			    int length, void *msg,
 			    divas_xdi_copy_from_user_fn_t cp_fn);
 
 void diva_xdi_close_adapter(void *adapter, void *os_handle);
diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c
index 32f3451..1e8b991 100644
--- a/drivers/isdn/hardware/eicon/divasmain.c
+++ b/drivers/isdn/hardware/eicon/divasmain.c
@@ -591,19 +591,22 @@
 static ssize_t divas_write(struct file *file, const char __user *buf,
 			   size_t count, loff_t *ppos)
 {
+	diva_xdi_um_cfg_cmd_t msg;
 	int ret = -EINVAL;
 
 	if (!file->private_data) {
 		file->private_data = diva_xdi_open_adapter(file, buf,
-							   count,
+							   count, &msg,
 							   xdi_copy_from_user);
-	}
-	if (!file->private_data) {
-		return (-ENODEV);
+		if (!file->private_data)
+			return (-ENODEV);
+		ret = diva_xdi_write(file->private_data, file,
+				     buf, count, &msg, xdi_copy_from_user);
+	} else {
+		ret = diva_xdi_write(file->private_data, file,
+				     buf, count, NULL, xdi_copy_from_user);
 	}
 
-	ret = diva_xdi_write(file->private_data, file,
-			     buf, count, xdi_copy_from_user);
 	switch (ret) {
 	case -1:		/* Message should be removed from rx mailbox first */
 		ret = -EBUSY;
@@ -622,11 +625,12 @@
 static ssize_t divas_read(struct file *file, char __user *buf,
 			  size_t count, loff_t *ppos)
 {
+	diva_xdi_um_cfg_cmd_t msg;
 	int ret = -EINVAL;
 
 	if (!file->private_data) {
 		file->private_data = diva_xdi_open_adapter(file, buf,
-							   count,
+							   count, &msg,
 							   xdi_copy_from_user);
 	}
 	if (!file->private_data) {
diff --git a/drivers/leds/leds-qpnp-haptics.c b/drivers/leds/leds-qpnp-haptics.c
index 8a850c5..3f97c803 100644
--- a/drivers/leds/leds-qpnp-haptics.c
+++ b/drivers/leds/leds-qpnp-haptics.c
@@ -2515,6 +2515,16 @@
 	return 0;
 }
 
+static void qpnp_haptics_shutdown(struct platform_device *pdev)
+{
+	struct hap_chip *chip = dev_get_drvdata(&pdev->dev);
+
+	cancel_work_sync(&chip->haptics_work);
+
+	/* disable haptics */
+	qpnp_haptics_mod_enable(chip, false);
+}
+
 static const struct dev_pm_ops qpnp_haptics_pm_ops = {
 	.suspend	= qpnp_haptics_suspend,
 };
@@ -2532,6 +2542,7 @@
 	},
 	.probe		= qpnp_haptics_probe,
 	.remove		= qpnp_haptics_remove,
+	.shutdown	= qpnp_haptics_shutdown,
 };
 module_platform_driver(qpnp_haptics_driver);
 
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index 89fc93b..dafa981 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -551,4 +551,24 @@
 	  of the metadata contents are verified against the key included
 	  in the system keyring. Upon success, the underlying verity
 	  target is setup.
+
+config DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED
+	bool "Verity will validate blocks at most once"
+   depends on DM_VERITY
+   ---help---
+	  Default enables at_most_once option for dm-verity
+
+	  Verify data blocks only the first time they are read from the
+	  data device, rather than every time.  This reduces the overhead
+	  of dm-verity so that it can be used on systems that are memory
+	  and/or CPU constrained.  However, it provides a reduced level
+	  of security because only offline tampering of the data device's
+	  content will be detected, not online tampering.
+
+	  Hash blocks are still verified each time they are read from the
+	  hash device, since verification of hash blocks is less performance
+	  critical than data blocks, and a hash block will not be verified
+	  any more after all the data blocks it covers have been verified anyway.
+
+	  If unsure, say N.
 endif # MD
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
index 809a4df..6deb1fe 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -373,9 +373,6 @@
 static void *alloc_buffer_data(struct dm_bufio_client *c, gfp_t gfp_mask,
 			       enum data_mode *data_mode)
 {
-	unsigned noio_flag;
-	void *ptr;
-
 	if (c->block_size <= DM_BUFIO_BLOCK_SIZE_SLAB_LIMIT) {
 		*data_mode = DATA_MODE_SLAB;
 		return kmem_cache_alloc(DM_BUFIO_CACHE(c), gfp_mask);
@@ -399,16 +396,16 @@
 	 * all allocations done by this process (including pagetables) are done
 	 * as if GFP_NOIO was specified.
 	 */
+	if (gfp_mask & __GFP_NORETRY) {
+		unsigned noio_flag = memalloc_noio_save();
+		void *ptr = __vmalloc(c->block_size, gfp_mask | __GFP_HIGHMEM,
+				      PAGE_KERNEL);
 
-	if (gfp_mask & __GFP_NORETRY)
-		noio_flag = memalloc_noio_save();
-
-	ptr = __vmalloc(c->block_size, gfp_mask | __GFP_HIGHMEM, PAGE_KERNEL);
-
-	if (gfp_mask & __GFP_NORETRY)
 		memalloc_noio_restore(noio_flag);
+		return ptr;
+	}
 
-	return ptr;
+	return __vmalloc(c->block_size, gfp_mask | __GFP_HIGHMEM, PAGE_KERNEL);
 }
 
 /*
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index d96aa84..0a7a828 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -1049,6 +1049,14 @@
 			goto bad;
 	}
 
+#ifdef CONFIG_DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED
+	if (!v->validated_blocks) {
+		r = verity_alloc_most_once(v);
+		if (r)
+			goto bad;
+	}
+#endif
+
 	v->hash_per_block_bits =
 		__fls((1 << v->hash_dev_block_bits) / v->digest_size);
 
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c
index 21bac16..b5a6f44 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c
@@ -25,12 +25,16 @@
 	struct msm_vfe_axi_shared_data *axi_data,
 	struct msm_vfe32_axi_stream_request_cmd *stream_cfg_cmd)
 {
-	uint32_t i = stream_cfg_cmd->stream_src;
+	int i, rc = -1;
 
-	if (i >= VFE_AXI_SRC_MAX) {
-		pr_err("%s:%d invalid stream_src %d\n", __func__, __LINE__,
-			stream_cfg_cmd->stream_src);
-		return -EINVAL;
+	for (i = 0; i < MAX_NUM_STREAM; i++) {
+		if (axi_data->stream_info[i].state == AVAILABLE)
+			break;
+	}
+
+	if (i == MAX_NUM_STREAM) {
+		pr_err("%s: No free stream\n", __func__);
+		return rc;
 	}
 
 	if ((axi_data->stream_handle_cnt << 8) == 0)
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
index ce50dcd..ca3b010 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
@@ -303,7 +303,7 @@
 	int ret = 0;
 
 	if (mgr->regulator_enable == on) {
-		SDEROT_ERR("Regulators already in selected mode on=%d\n", on);
+		SDEROT_DBG("Regulators already in selected mode on=%d\n", on);
 		return 0;
 	}
 
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index bf87ed2..0ee8208 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -189,6 +189,7 @@
 	wait_queue_head_t          listener_block_app_wq;
 	struct sglist_info sglistinfo_ptr[MAX_ION_FD];
 	uint32_t sglist_cnt;
+	int abort;
 };
 
 struct qseecom_registered_app_list {
@@ -1223,6 +1224,23 @@
 	return ret;
 }
 
+static void __qseecom_listener_abort_all(int abort)
+{
+	struct qseecom_registered_listener_list *entry = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&qseecom.registered_listener_list_lock, flags);
+	list_for_each_entry(entry,
+			&qseecom.registered_listener_list_head, list) {
+		pr_debug("set abort %d for listener %d\n",
+				abort, entry->svc.listener_id);
+		entry->abort = abort;
+	}
+	if (abort)
+		wake_up_interruptible_all(&qseecom.send_resp_wq);
+	spin_unlock_irqrestore(&qseecom.registered_listener_list_lock, flags);
+}
+
 static int qseecom_unregister_listener(struct qseecom_dev_handle *data)
 {
 	int ret = 0;
@@ -1256,6 +1274,7 @@
 	list_for_each_entry(ptr_svc, &qseecom.registered_listener_list_head,
 			list) {
 		if (ptr_svc->svc.listener_id == data->listener.id) {
+			ptr_svc->abort = 1;
 			wake_up_all(&ptr_svc->rcv_req_wq);
 			break;
 		}
@@ -1602,12 +1621,13 @@
 	return 0;
 }
 
-static int __qseecom_listener_has_sent_rsp(struct qseecom_dev_handle *data)
+static int __qseecom_listener_has_sent_rsp(struct qseecom_dev_handle *data,
+			struct qseecom_registered_listener_list *ptr_svc)
 {
 	int ret;
 
 	ret = (qseecom.send_resp_flag != 0);
-	return ret || data->abort;
+	return ret || data->abort || ptr_svc->abort;
 }
 
 static int __qseecom_reentrancy_listener_has_sent_rsp(
@@ -1617,56 +1637,7 @@
 	int ret;
 
 	ret = (ptr_svc->send_resp_flag != 0);
-	return ret || data->abort;
-}
-
-static int __qseecom_qseos_fail_return_resp_tz(struct qseecom_dev_handle *data,
-					struct qseecom_command_scm_resp *resp,
-			struct qseecom_client_listener_data_irsp *send_data_rsp,
-			struct qseecom_registered_listener_list *ptr_svc,
-							uint32_t lstnr) {
-	int ret = 0;
-
-	send_data_rsp->status = QSEOS_RESULT_FAILURE;
-	qseecom.send_resp_flag = 0;
-	send_data_rsp->qsee_cmd_id = QSEOS_LISTENER_DATA_RSP_COMMAND;
-	send_data_rsp->listener_id = lstnr;
-	if (ptr_svc)
-		pr_warn("listener_id:%x, lstnr: %x\n",
-					ptr_svc->svc.listener_id, lstnr);
-	if (ptr_svc && ptr_svc->ihandle) {
-		ret = msm_ion_do_cache_op(qseecom.ion_clnt, ptr_svc->ihandle,
-					ptr_svc->sb_virt, ptr_svc->sb_length,
-					ION_IOC_CLEAN_INV_CACHES);
-		if (ret) {
-			pr_err("cache operation failed %d\n", ret);
-			return ret;
-		}
-	}
-
-	if (lstnr == RPMB_SERVICE) {
-		ret = __qseecom_enable_clk(CLK_QSEE);
-		if (ret)
-			return ret;
-	}
-	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, send_data_rsp,
-				sizeof(send_data_rsp), resp, sizeof(*resp));
-	if (ret) {
-		pr_err("scm_call() failed with err: %d (app_id = %d)\n",
-						ret, data->client.app_id);
-		if (lstnr == RPMB_SERVICE)
-			__qseecom_disable_clk(CLK_QSEE);
-		return ret;
-	}
-	if ((resp->result != QSEOS_RESULT_SUCCESS) &&
-			(resp->result != QSEOS_RESULT_INCOMPLETE)) {
-		pr_err("fail:resp res= %d,app_id = %d,lstr = %d\n",
-				resp->result, data->client.app_id, lstnr);
-		ret = -EINVAL;
-	}
-	if (lstnr == RPMB_SERVICE)
-		__qseecom_disable_clk(CLK_QSEE);
-	return ret;
+	return ret || data->abort || ptr_svc->abort;
 }
 
 static void __qseecom_clean_listener_sglistinfo(
@@ -1717,23 +1688,33 @@
 
 		if (ptr_svc == NULL) {
 			pr_err("Listener Svc %d does not exist\n", lstnr);
-			__qseecom_qseos_fail_return_resp_tz(data, resp,
-					&send_data_rsp, ptr_svc, lstnr);
-			return -EINVAL;
+			rc = -EINVAL;
+			status = QSEOS_RESULT_FAILURE;
+			goto err_resp;
 		}
 
 		if (!ptr_svc->ihandle) {
 			pr_err("Client handle is not initialized\n");
-			__qseecom_qseos_fail_return_resp_tz(data, resp,
-					&send_data_rsp, ptr_svc, lstnr);
-			return -EINVAL;
+			rc = -EINVAL;
+			status = QSEOS_RESULT_FAILURE;
+			goto err_resp;
 		}
 
 		if (ptr_svc->svc.listener_id != lstnr) {
-			pr_warn("Service requested does not exist\n");
-			__qseecom_qseos_fail_return_resp_tz(data, resp,
-					&send_data_rsp, NULL, lstnr);
-			return -ERESTARTSYS;
+			pr_err("Service %d does not exist\n",
+						lstnr);
+			rc = -ERESTARTSYS;
+			ptr_svc = NULL;
+			status = QSEOS_RESULT_FAILURE;
+			goto err_resp;
+		}
+
+		if (ptr_svc->abort == 1) {
+			pr_err("Service %d abort %d\n",
+						lstnr, ptr_svc->abort);
+			rc = -ENODEV;
+			status = QSEOS_RESULT_FAILURE;
+			goto err_resp;
 		}
 		pr_debug("waking up rcv_req_wq and waiting for send_resp_wq\n");
 
@@ -1750,7 +1731,8 @@
 			 */
 			if (!qseecom.qsee_reentrancy_support &&
 				!wait_event_freezable(qseecom.send_resp_wq,
-				__qseecom_listener_has_sent_rsp(data))) {
+				__qseecom_listener_has_sent_rsp(
+						data, ptr_svc))) {
 				break;
 			}
 
@@ -1764,7 +1746,7 @@
 
 		/* restore signal mask */
 		sigprocmask(SIG_SETMASK, &old_sigset, NULL);
-		if (data->abort) {
+		if (data->abort || ptr_svc->abort) {
 			pr_err("Abort clnt %d waiting on lstnr svc %d, ret %d",
 				data->client.app_id, lstnr, ret);
 			rc = -ENODEV;
@@ -1772,7 +1754,7 @@
 		} else {
 			status = QSEOS_RESULT_SUCCESS;
 		}
-
+err_resp:
 		qseecom.send_resp_flag = 0;
 		ptr_svc->send_resp_flag = 0;
 		table = ptr_svc->sglistinfo_ptr;
@@ -1832,6 +1814,8 @@
 				__qseecom_disable_clk(CLK_QSEE);
 			return ret;
 		}
+		pr_debug("resp status %d, res= %d, app_id = %d, lstr = %d\n",
+			status, resp->result, data->client.app_id, lstnr);
 		if ((resp->result != QSEOS_RESULT_SUCCESS) &&
 			(resp->result != QSEOS_RESULT_INCOMPLETE)) {
 			pr_err("fail:resp res= %d,app_id = %d,lstr = %d\n",
@@ -1985,7 +1969,7 @@
 	size_t cmd_len;
 	struct sglist_info *table = NULL;
 
-	while (ret == 0 && rc == 0 && resp->result == QSEOS_RESULT_INCOMPLETE) {
+	while (ret == 0 && resp->result == QSEOS_RESULT_INCOMPLETE) {
 		lstnr = resp->data;
 		/*
 		 * Wake up blocking lsitener service with the lstnr id
@@ -2006,17 +1990,33 @@
 
 		if (ptr_svc == NULL) {
 			pr_err("Listener Svc %d does not exist\n", lstnr);
-			return -EINVAL;
+			rc = -EINVAL;
+			status = QSEOS_RESULT_FAILURE;
+			goto err_resp;
 		}
 
 		if (!ptr_svc->ihandle) {
 			pr_err("Client handle is not initialized\n");
-			return -EINVAL;
+			rc = -EINVAL;
+			status = QSEOS_RESULT_FAILURE;
+			goto err_resp;
 		}
 
 		if (ptr_svc->svc.listener_id != lstnr) {
-			pr_warn("Service requested does not exist\n");
-			return -ERESTARTSYS;
+			pr_err("Service %d does not exist\n",
+						lstnr);
+			rc = -ERESTARTSYS;
+			ptr_svc = NULL;
+			status = QSEOS_RESULT_FAILURE;
+			goto err_resp;
+		}
+
+		if (ptr_svc->abort == 1) {
+			pr_err("Service %d abort %d\n",
+						lstnr, ptr_svc->abort);
+			rc = -ENODEV;
+			status = QSEOS_RESULT_FAILURE;
+			goto err_resp;
 		}
 		pr_debug("waking up rcv_req_wq and waiting for send_resp_wq\n");
 
@@ -2042,7 +2042,7 @@
 
 		/* restore signal mask */
 		sigprocmask(SIG_SETMASK, &old_sigset, NULL);
-		if (data->abort) {
+		if (data->abort || ptr_svc->abort) {
 			pr_err("Abort clnt %d waiting on lstnr svc %d, ret %d",
 				data->client.app_id, lstnr, ret);
 			rc = -ENODEV;
@@ -2050,6 +2050,7 @@
 		} else {
 			status  = QSEOS_RESULT_SUCCESS;
 		}
+err_resp:
 		table = ptr_svc->sglistinfo_ptr;
 		if (qseecom.qsee_version < QSEE_VERSION_40) {
 			send_data_rsp.listener_id  = lstnr;
@@ -3813,7 +3814,7 @@
 	int ret;
 
 	ret = (svc->rcv_req_flag != 0);
-	return ret || data->abort;
+	return ret || data->abort || svc->abort;
 }
 
 static int qseecom_receive_req(struct qseecom_dev_handle *data)
@@ -3837,9 +3838,9 @@
 			return -ERESTARTSYS;
 		}
 
-		if (data->abort) {
+		if (data->abort || this_lstnr->abort) {
 			pr_err("Aborting Listener Service = %d\n",
-						(uint32_t)data->listener.id);
+					(uint32_t)data->listener.id);
 			return -ENODEV;
 		}
 		this_lstnr->rcv_req_flag = 0;
@@ -6154,7 +6155,7 @@
 }
 static int qseecom_is_es_activated(void __user *argp)
 {
-	struct qseecom_is_es_activated_req req;
+	struct qseecom_is_es_activated_req req = {0};
 	struct qseecom_command_scm_resp resp;
 	int ret;
 
@@ -6999,12 +7000,14 @@
 			break;
 		}
 		pr_debug("ioctl unregister_listener_req()\n");
+		__qseecom_listener_abort_all(1);
 		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_unregister_listener(data);
 		atomic_dec(&data->ioctl_count);
 		wake_up_all(&data->abort_wq);
 		mutex_unlock(&app_access_lock);
+		__qseecom_listener_abort_all(0);
 		if (ret)
 			pr_err("failed qseecom_unregister_listener: %d\n", ret);
 		break;
@@ -7671,9 +7674,11 @@
 			data->type, data->mode, data);
 		switch (data->type) {
 		case QSEECOM_LISTENER_SERVICE:
+			__qseecom_listener_abort_all(1);
 			mutex_lock(&app_access_lock);
 			ret = qseecom_unregister_listener(data);
 			mutex_unlock(&app_access_lock);
+			__qseecom_listener_abort_all(0);
 			break;
 		case QSEECOM_CLIENT_APP:
 			mutex_lock(&app_access_lock);
diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c
index 1e688bf..fe90b7e 100644
--- a/drivers/misc/vmw_balloon.c
+++ b/drivers/misc/vmw_balloon.c
@@ -576,15 +576,9 @@
 		}
 	}
 
-	if (b->batch_page) {
-		vunmap(b->batch_page);
-		b->batch_page = NULL;
-	}
-
-	if (b->page) {
-		__free_page(b->page);
-		b->page = NULL;
-	}
+	/* Clearing the batch_page unconditionally has no adverse effect */
+	free_page((unsigned long)b->batch_page);
+	b->batch_page = NULL;
 }
 
 /*
@@ -991,16 +985,13 @@
 
 static bool vmballoon_init_batching(struct vmballoon *b)
 {
-	b->page = alloc_page(VMW_PAGE_ALLOC_NOSLEEP);
-	if (!b->page)
+	struct page *page;
+
+	page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+	if (!page)
 		return false;
 
-	b->batch_page = vmap(&b->page, 1, VM_MAP, PAGE_KERNEL);
-	if (!b->batch_page) {
-		__free_page(b->page);
-		return false;
-	}
-
+	b->batch_page = page_address(page);
 	return true;
 }
 
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 7d24213..1119292 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -5239,19 +5239,50 @@
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_msm_host *msm_host = pltfm_host->priv;
 	struct sdhci_msm_pltfm_data *pdata = msm_host->pdata;
+	int nr_groups = msm_host->pdata->pm_qos_data.cpu_group_map.nr_groups;
+	int i;
 	int dead = (readl_relaxed(host->ioaddr + SDHCI_INT_STATUS) ==
 			0xffffffff);
 
-	pr_debug("%s: %s\n", dev_name(&pdev->dev), __func__);
+	pr_debug("%s: %s Enter\n", dev_name(&pdev->dev), __func__);
 	if (!gpio_is_valid(msm_host->pdata->status_gpio))
 		device_remove_file(&pdev->dev, &msm_host->polling);
+
+	device_remove_file(&pdev->dev, &msm_host->auto_cmd21_attr);
 	device_remove_file(&pdev->dev, &msm_host->msm_bus_vote.max_bus_bw);
 	pm_runtime_disable(&pdev->dev);
 
+	if (msm_host->pm_qos_group_enable) {
+		struct sdhci_msm_pm_qos_group *group;
+
+		for (i = 0; i < nr_groups; i++)
+			cancel_delayed_work_sync(
+					&msm_host->pm_qos[i].unvote_work);
+
+		device_remove_file(&msm_host->pdev->dev,
+			&msm_host->pm_qos_group_enable_attr);
+		device_remove_file(&msm_host->pdev->dev,
+			&msm_host->pm_qos_group_status_attr);
+
+		for (i = 0; i < nr_groups; i++) {
+			group = &msm_host->pm_qos[i];
+			pm_qos_remove_request(&group->req);
+		}
+	}
+
+	if (msm_host->pm_qos_irq.enabled) {
+		cancel_delayed_work_sync(&msm_host->pm_qos_irq.unvote_work);
+		device_remove_file(&pdev->dev,
+				&msm_host->pm_qos_irq.enable_attr);
+		device_remove_file(&pdev->dev,
+				&msm_host->pm_qos_irq.status_attr);
+		pm_qos_remove_request(&msm_host->pm_qos_irq.req);
+	}
+
 	if (msm_host->pm_qos_wq)
 		destroy_workqueue(msm_host->pm_qos_wq);
+
 	sdhci_remove_host(host, dead);
-	sdhci_pltfm_free(pdev);
 
 	sdhci_msm_vreg_init(&pdev->dev, msm_host->pdata, false);
 
@@ -5262,6 +5293,9 @@
 		sdhci_msm_bus_cancel_work_and_set_vote(host, 0);
 		sdhci_msm_bus_unregister(msm_host);
 	}
+
+	sdhci_pltfm_free(pdev);
+
 	return 0;
 }
 
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 1a139d0..f5fcc08 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -384,20 +384,15 @@
 	slave->duplex = DUPLEX_UNKNOWN;
 
 	res = __ethtool_get_link_ksettings(slave_dev, &ecmd);
-	if (res < 0) {
-		slave->link = BOND_LINK_DOWN;
+	if (res < 0)
 		return 1;
-	}
-	if (ecmd.base.speed == 0 || ecmd.base.speed == ((__u32)-1)) {
-		slave->link = BOND_LINK_DOWN;
+	if (ecmd.base.speed == 0 || ecmd.base.speed == ((__u32)-1))
 		return 1;
-	}
 	switch (ecmd.base.duplex) {
 	case DUPLEX_FULL:
 	case DUPLEX_HALF:
 		break;
 	default:
-		slave->link = BOND_LINK_DOWN;
 		return 1;
 	}
 
@@ -1536,7 +1531,9 @@
 	new_slave->delay = 0;
 	new_slave->link_failure_count = 0;
 
-	bond_update_speed_duplex(new_slave);
+	if (bond_update_speed_duplex(new_slave) &&
+	    bond_needs_speed_duplex(bond))
+		new_slave->link = BOND_LINK_DOWN;
 
 	new_slave->last_rx = jiffies -
 		(msecs_to_jiffies(bond->params.arp_interval) + 1);
@@ -2140,7 +2137,14 @@
 			continue;
 
 		case BOND_LINK_UP:
-			bond_update_speed_duplex(slave);
+			if (bond_update_speed_duplex(slave) &&
+			    bond_needs_speed_duplex(bond)) {
+				slave->link = BOND_LINK_DOWN;
+				netdev_warn(bond->dev,
+					    "failed to get link speed/duplex for %s\n",
+					    slave->dev->name);
+				continue;
+			}
 			bond_set_slave_link_state(slave, BOND_LINK_UP,
 						  BOND_SLAVE_NOTIFY_NOW);
 			slave->last_link_up = jiffies;
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index 577e57c..473da3b 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -1114,6 +1114,7 @@
 				    slave->dev->name);
 			rcu_assign_pointer(bond->primary_slave, slave);
 			strcpy(bond->params.primary, slave->dev->name);
+			bond->force_primary = true;
 			bond_select_active_slave(bond);
 			goto out;
 		}
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index c26debc..7152595 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1516,6 +1516,18 @@
 		.duplex_reg = B53_DUPLEX_STAT_FE,
 	},
 	{
+		.chip_id = BCM5389_DEVICE_ID,
+		.dev_name = "BCM5389",
+		.vlans = 4096,
+		.enabled_ports = 0x1f,
+		.arl_entries = 4,
+		.cpu_port = B53_CPU_PORT,
+		.vta_regs = B53_VTA_REGS,
+		.duplex_reg = B53_DUPLEX_STAT_GE,
+		.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
+		.jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+	},
+	{
 		.chip_id = BCM5395_DEVICE_ID,
 		.dev_name = "BCM5395",
 		.vlans = 4096,
@@ -1825,6 +1837,7 @@
 		else
 			dev->chip_id = BCM5365_DEVICE_ID;
 		break;
+	case BCM5389_DEVICE_ID:
 	case BCM5395_DEVICE_ID:
 	case BCM5397_DEVICE_ID:
 	case BCM5398_DEVICE_ID:
diff --git a/drivers/net/dsa/b53/b53_mdio.c b/drivers/net/dsa/b53/b53_mdio.c
index 477a16b..6f47ff1 100644
--- a/drivers/net/dsa/b53/b53_mdio.c
+++ b/drivers/net/dsa/b53/b53_mdio.c
@@ -285,6 +285,7 @@
 #define B53_BRCM_OUI_1	0x0143bc00
 #define B53_BRCM_OUI_2	0x03625c00
 #define B53_BRCM_OUI_3	0x00406000
+#define B53_BRCM_OUI_4	0x01410c00
 
 static int b53_mdio_probe(struct mdio_device *mdiodev)
 {
@@ -311,7 +312,8 @@
 	 */
 	if ((phy_id & 0xfffffc00) != B53_BRCM_OUI_1 &&
 	    (phy_id & 0xfffffc00) != B53_BRCM_OUI_2 &&
-	    (phy_id & 0xfffffc00) != B53_BRCM_OUI_3) {
+	    (phy_id & 0xfffffc00) != B53_BRCM_OUI_3 &&
+	    (phy_id & 0xfffffc00) != B53_BRCM_OUI_4) {
 		dev_err(&mdiodev->dev, "Unsupported device: 0x%08x\n", phy_id);
 		return -ENODEV;
 	}
@@ -360,6 +362,7 @@
 	{ .compatible = "brcm,bcm53125" },
 	{ .compatible = "brcm,bcm53128" },
 	{ .compatible = "brcm,bcm5365" },
+	{ .compatible = "brcm,bcm5389" },
 	{ .compatible = "brcm,bcm5395" },
 	{ .compatible = "brcm,bcm5397" },
 	{ .compatible = "brcm,bcm5398" },
diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h
index f192a67..68ab20b 100644
--- a/drivers/net/dsa/b53/b53_priv.h
+++ b/drivers/net/dsa/b53/b53_priv.h
@@ -47,6 +47,7 @@
 enum {
 	BCM5325_DEVICE_ID = 0x25,
 	BCM5365_DEVICE_ID = 0x65,
+	BCM5389_DEVICE_ID = 0x89,
 	BCM5395_DEVICE_ID = 0x95,
 	BCM5397_DEVICE_ID = 0x97,
 	BCM5398_DEVICE_ID = 0x98,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index 1fb8010..912900d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -594,7 +594,7 @@
 	 * slots for the highest priority.
 	 */
 	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS :
-		   NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
+		   NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
 	/* Mapping between the CREDIT_WEIGHT registers and actual client
 	 * numbers
 	 */
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index dda63b2..99f593b 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -2541,11 +2541,11 @@
 	pci_set_master(pdev);
 
 	/* Query PCI controller on system for DMA addressing
-	 * limitation for the device.  Try 64-bit first, and
+	 * limitation for the device.  Try 47-bit first, and
 	 * fail to 32-bit.
 	 */
 
-	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(47));
 	if (err) {
 		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 		if (err) {
@@ -2559,10 +2559,10 @@
 			goto err_out_release_regions;
 		}
 	} else {
-		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(47));
 		if (err) {
 			dev_err(dev, "Unable to obtain %u-bit DMA "
-				"for consistent allocations, aborting\n", 64);
+				"for consistent allocations, aborting\n", 47);
 			goto err_out_release_regions;
 		}
 		using_dac = 1;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index bcbb80f..1a92cd7 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -142,16 +142,17 @@
 			      struct mlx4_en_rx_alloc *frags,
 			      int i)
 {
-	const struct mlx4_en_frag_info *frag_info = &priv->frag_info[i];
-	u32 next_frag_end = frags[i].page_offset + 2 * frag_info->frag_stride;
+	if (frags[i].page) {
+		const struct mlx4_en_frag_info *frag_info = &priv->frag_info[i];
+		u32 next_frag_end = frags[i].page_offset +
+				2 * frag_info->frag_stride;
 
-
-	if (next_frag_end > frags[i].page_size)
-		dma_unmap_page(priv->ddev, frags[i].dma, frags[i].page_size,
-			       frag_info->dma_dir);
-
-	if (frags[i].page)
+		if (next_frag_end > frags[i].page_size) {
+			dma_unmap_page(priv->ddev, frags[i].dma,
+				       frags[i].page_size, frag_info->dma_dir);
+		}
 		put_page(frags[i].page);
+	}
 }
 
 static int mlx4_en_init_allocator(struct mlx4_en_priv *priv,
@@ -586,21 +587,28 @@
 				    int length)
 {
 	struct skb_frag_struct *skb_frags_rx = skb_shinfo(skb)->frags;
-	struct mlx4_en_frag_info *frag_info;
 	int nr;
 	dma_addr_t dma;
 
 	/* Collect used fragments while replacing them in the HW descriptors */
 	for (nr = 0; nr < priv->num_frags; nr++) {
-		frag_info = &priv->frag_info[nr];
+		struct mlx4_en_frag_info *frag_info = &priv->frag_info[nr];
+		u32 next_frag_end = frags[nr].page_offset +
+				2 * frag_info->frag_stride;
+
 		if (length <= frag_info->frag_prefix_size)
 			break;
 		if (unlikely(!frags[nr].page))
 			goto fail;
 
 		dma = be64_to_cpu(rx_desc->data[nr].addr);
-		dma_sync_single_for_cpu(priv->ddev, dma, frag_info->frag_size,
-					DMA_FROM_DEVICE);
+		if (next_frag_end > frags[nr].page_size)
+			dma_unmap_page(priv->ddev, frags[nr].dma,
+				       frags[nr].page_size, frag_info->dma_dir);
+		else
+			dma_sync_single_for_cpu(priv->ddev, dma,
+						frag_info->frag_size,
+						DMA_FROM_DEVICE);
 
 		/* Save page reference in skb */
 		__skb_frag_set_page(&skb_frags_rx[nr], frags[nr].page);
diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c
index 474ff36..71578d4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/qp.c
+++ b/drivers/net/ethernet/mellanox/mlx4/qp.c
@@ -392,11 +392,11 @@
 	struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
 	struct mlx4_qp *qp;
 
-	spin_lock(&qp_table->lock);
+	spin_lock_irq(&qp_table->lock);
 
 	qp = __mlx4_qp_lookup(dev, qpn);
 
-	spin_unlock(&qp_table->lock);
+	spin_unlock_irq(&qp_table->lock);
 	return qp;
 }
 
diff --git a/drivers/net/ethernet/natsemi/sonic.c b/drivers/net/ethernet/natsemi/sonic.c
index 612c7a4..2382154 100644
--- a/drivers/net/ethernet/natsemi/sonic.c
+++ b/drivers/net/ethernet/natsemi/sonic.c
@@ -71,7 +71,7 @@
 	for (i = 0; i < SONIC_NUM_RRS; i++) {
 		dma_addr_t laddr = dma_map_single(lp->device, skb_put(lp->rx_skb[i], SONIC_RBSIZE),
 		                                  SONIC_RBSIZE, DMA_FROM_DEVICE);
-		if (!laddr) {
+		if (dma_mapping_error(lp->device, laddr)) {
 			while(i > 0) { /* free any that were mapped successfully */
 				i--;
 				dma_unmap_single(lp->device, lp->rx_laddr[i], SONIC_RBSIZE, DMA_FROM_DEVICE);
diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.c b/drivers/net/ethernet/qlogic/qed/qed_cxt.c
index 457e304..f1956c4 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c
@@ -54,7 +54,7 @@
 #define ILT_CFG_REG(cli, reg)	PSWRQ2_REG_ ## cli ## _ ## reg ## _RT_OFFSET
 
 /* ILT entry structure */
-#define ILT_ENTRY_PHY_ADDR_MASK		0x000FFFFFFFFFFFULL
+#define ILT_ENTRY_PHY_ADDR_MASK		(~0ULL >> 12)
 #define ILT_ENTRY_PHY_ADDR_SHIFT	0
 #define ILT_ENTRY_VALID_MASK		0x1ULL
 #define ILT_ENTRY_VALID_SHIFT		52
diff --git a/drivers/net/phy/bcm-cygnus.c b/drivers/net/phy/bcm-cygnus.c
index 49bbc68..9a7dca2 100644
--- a/drivers/net/phy/bcm-cygnus.c
+++ b/drivers/net/phy/bcm-cygnus.c
@@ -61,17 +61,17 @@
 		return rc;
 
 	/* make rcal=100, since rdb default is 000 */
-	rc = bcm_phy_write_exp(phydev, MII_BRCM_CORE_EXPB1, 0x10);
+	rc = bcm_phy_write_exp_sel(phydev, MII_BRCM_CORE_EXPB1, 0x10);
 	if (rc < 0)
 		return rc;
 
 	/* CORE_EXPB0, Reset R_CAL/RC_CAL Engine */
-	rc = bcm_phy_write_exp(phydev, MII_BRCM_CORE_EXPB0, 0x10);
+	rc = bcm_phy_write_exp_sel(phydev, MII_BRCM_CORE_EXPB0, 0x10);
 	if (rc < 0)
 		return rc;
 
 	/* CORE_EXPB0, Disable Reset R_CAL/RC_CAL Engine */
-	rc = bcm_phy_write_exp(phydev, MII_BRCM_CORE_EXPB0, 0x00);
+	rc = bcm_phy_write_exp_sel(phydev, MII_BRCM_CORE_EXPB0, 0x00);
 
 	return 0;
 }
diff --git a/drivers/net/phy/bcm-phy-lib.h b/drivers/net/phy/bcm-phy-lib.h
index b2091c8..ce16b26 100644
--- a/drivers/net/phy/bcm-phy-lib.h
+++ b/drivers/net/phy/bcm-phy-lib.h
@@ -14,11 +14,18 @@
 #ifndef _LINUX_BCM_PHY_LIB_H
 #define _LINUX_BCM_PHY_LIB_H
 
+#include <linux/brcmphy.h>
 #include <linux/phy.h>
 
 int bcm_phy_write_exp(struct phy_device *phydev, u16 reg, u16 val);
 int bcm_phy_read_exp(struct phy_device *phydev, u16 reg);
 
+static inline int bcm_phy_write_exp_sel(struct phy_device *phydev,
+					u16 reg, u16 val)
+{
+	return bcm_phy_write_exp(phydev, reg | MII_BCM54XX_EXP_SEL_ER, val);
+}
+
 int bcm_phy_write_misc(struct phy_device *phydev,
 		       u16 reg, u16 chl, u16 value);
 int bcm_phy_read_misc(struct phy_device *phydev,
diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c
index 9636da0..caff474 100644
--- a/drivers/net/phy/bcm7xxx.c
+++ b/drivers/net/phy/bcm7xxx.c
@@ -48,10 +48,10 @@
 static void r_rc_cal_reset(struct phy_device *phydev)
 {
 	/* Reset R_CAL/RC_CAL Engine */
-	bcm_phy_write_exp(phydev, 0x00b0, 0x0010);
+	bcm_phy_write_exp_sel(phydev, 0x00b0, 0x0010);
 
 	/* Disable Reset R_AL/RC_CAL Engine */
-	bcm_phy_write_exp(phydev, 0x00b0, 0x0000);
+	bcm_phy_write_exp_sel(phydev, 0x00b0, 0x0000);
 }
 
 static int bcm7xxx_28nm_b0_afe_config_init(struct phy_device *phydev)
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 3696368..f9ec009 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -1004,7 +1004,8 @@
 static void ___team_compute_features(struct team *team)
 {
 	struct team_port *port;
-	u32 vlan_features = TEAM_VLAN_FEATURES & NETIF_F_ALL_FOR_ALL;
+	netdev_features_t vlan_features = TEAM_VLAN_FEATURES &
+					  NETIF_F_ALL_FOR_ALL;
 	netdev_features_t enc_features  = TEAM_ENC_FEATURES;
 	unsigned short max_hard_header_len = ETH_HLEN;
 	unsigned int dst_release_flag = IFF_XMIT_DST_RELEASE |
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
index 3a98f37..4c8baba 100644
--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -608,7 +608,7 @@
  */
 static const struct driver_info cdc_mbim_info_avoid_altsetting_toggle = {
 	.description = "CDC MBIM",
-	.flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN,
+	.flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN | FLAG_SEND_ZLP,
 	.bind = cdc_mbim_bind,
 	.unbind = cdc_mbim_unbind,
 	.manage_power = cdc_mbim_manage_power,
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 1d56c73..85bc0ca 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -808,6 +808,7 @@
 	{QMI_FIXED_INTF(0x05c6, 0x920d, 5)},
 	{QMI_QUIRK_SET_DTR(0x05c6, 0x9625, 4)},	/* YUGA CLM920-NC5 */
 	{QMI_FIXED_INTF(0x0846, 0x68a2, 8)},
+	{QMI_FIXED_INTF(0x0846, 0x68d3, 8)},	/* Netgear Aircard 779S */
 	{QMI_FIXED_INTF(0x12d1, 0x140c, 1)},	/* Huawei E173 */
 	{QMI_FIXED_INTF(0x12d1, 0x14ac, 1)},	/* Huawei E1820 */
 	{QMI_FIXED_INTF(0x1435, 0xd181, 3)},	/* Wistron NeWeb D18Q1 */
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index bb2270b..c915ded 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -114,3 +114,5 @@
 source "drivers/net/wireless/cnss_genl/Kconfig"
 
 endif # WLAN
+
+source "drivers/net/wireless/qca402x/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 917a876..6cf62b66 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -32,3 +32,4 @@
 obj-$(CONFIG_CNSS_UTILS) += cnss_utils/
 obj-$(CONFIG_CNSS_GENL) += cnss_genl/
 obj-$(CONFIG_CNSS_CRYPTO) += cnss_crypto/
+obj-$(CONFIG_QCA402X) += qca402x/
diff --git a/drivers/net/wireless/cnss/Kconfig b/drivers/net/wireless/cnss/Kconfig
index 0b37af6..c18cea7 100644
--- a/drivers/net/wireless/cnss/Kconfig
+++ b/drivers/net/wireless/cnss/Kconfig
@@ -61,6 +61,19 @@
 	  Say N, if you are building a release kernel for production use.
 	  Only say Y, if you are building a kernel with debug support.
 
+config CLD_USB_CORE
+	tristate "Qualcomm Technologies Inc. Core wlan driver for QCA USB interface"
+	select WIRELESS_EXT
+	select WEXT_PRIV
+	select WEXT_CORE
+	select WEXT_SPY
+	select NL80211_TESTMODE
+	---help---
+	  This section contains the necessary modules needed to enable the
+	  core WLAN driver for Qualcomm Technologies Inc USB wlan chipset.
+	  Select Y to compile the driver in order to have WLAN functionality
+	  support.
+
 config CLD_HL_SDIO_CORE
 	tristate "Qualcomm Technologies Inc. Core wlan driver for QCA SDIO interface"
 	select WIRELESS_EXT
diff --git a/drivers/net/wireless/cnss/cnss_pci.c b/drivers/net/wireless/cnss/cnss_pci.c
index 8797e68..b99a813 100644
--- a/drivers/net/wireless/cnss/cnss_pci.c
+++ b/drivers/net/wireless/cnss/cnss_pci.c
@@ -234,8 +234,11 @@
 	struct pci_dev *pdev;
 	const struct pci_device_id *id;
 	struct dma_iommu_mapping *smmu_mapping;
+	bool smmu_s1_bypass;
 	dma_addr_t smmu_iova_start;
 	size_t smmu_iova_len;
+	dma_addr_t smmu_iova_ipa_start;
+	size_t smmu_iova_ipa_len;
 	struct cnss_wlan_vreg_info vreg_info;
 	bool wlan_en_vreg_support;
 	struct cnss_wlan_gpio_info gpio_info;
@@ -1438,6 +1441,8 @@
 {
 	struct dma_iommu_mapping *mapping;
 	int atomic_ctx = 1;
+	int s1_bypass = 1;
+	int fast = 1;
 	int ret;
 
 	mapping = arm_iommu_create_mapping(&platform_bus_type,
@@ -1449,13 +1454,33 @@
 		goto map_fail;
 	}
 
-	ret = iommu_domain_set_attr(mapping->domain,
-				    DOMAIN_ATTR_ATOMIC,
-				    &atomic_ctx);
-	if (ret) {
-		pr_err("%s: set atomic_ctx attribute failed, err = %d\n",
-		       __func__, ret);
-		goto set_attr_fail;
+	if (penv->smmu_s1_bypass) {
+		ret = iommu_domain_set_attr(mapping->domain,
+					    DOMAIN_ATTR_S1_BYPASS,
+					    &s1_bypass);
+		if (ret) {
+			pr_err("%s: set s1 bypass attr failed, err = %d\n",
+			       __func__, ret);
+			goto set_attr_fail;
+		}
+	} else {
+		ret = iommu_domain_set_attr(mapping->domain,
+					    DOMAIN_ATTR_ATOMIC,
+					    &atomic_ctx);
+		if (ret) {
+			pr_err("%s: set atomic_ctx attr failed, err = %d\n",
+			       __func__, ret);
+			goto set_attr_fail;
+		}
+
+		ret = iommu_domain_set_attr(mapping->domain,
+					    DOMAIN_ATTR_FAST,
+					    &fast);
+		if (ret) {
+			pr_err("%s: set fast map attr failed, err = %d\n",
+			       __func__, ret);
+			goto set_attr_fail;
+		}
 	}
 
 	ret = arm_iommu_attach_device(dev, mapping);
@@ -1618,7 +1643,6 @@
 		if (ret) {
 			pr_err("%s: SMMU init failed, err = %d\n",
 			       __func__, ret);
-			goto smmu_init_fail;
 		}
 	}
 
@@ -1714,7 +1738,6 @@
 	dma_free_coherent(dev, EVICT_BIN_MAX_SIZE, cpu_addr, dma_handle);
 err_unknown:
 err_pcie_suspend:
-smmu_init_fail:
 	cnss_pcie_reset_platform_ops(dev);
 	return ret;
 }
@@ -2717,10 +2740,14 @@
 	cnss_configure_wlan_en_gpio(WLAN_EN_LOW);
 	cnss_wlan_vreg_set(vreg_info, VREG_OFF);
 	if (penv->pdev) {
-		pr_err("%d: Unregistering pci device\n", __LINE__);
-		pci_unregister_driver(&cnss_wlan_pci_driver);
-		penv->pdev = NULL;
-		penv->pci_register_again = true;
+		if (wdrv && wdrv->update_status)
+			wdrv->update_status(penv->pdev, CNSS_SSR_FAIL);
+		if (!penv->recovery_in_progress) {
+			pr_err("%d: Unregistering pci device\n", __LINE__);
+			pci_unregister_driver(&cnss_wlan_pci_driver);
+			penv->pdev = NULL;
+			penv->pci_register_again = true;
+		}
 	}
 
 err_wlan_vreg_on:
@@ -2867,6 +2894,55 @@
 	return msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry);
 }
 
+struct dma_iommu_mapping *cnss_smmu_get_mapping(void)
+{
+	if (!penv) {
+		pr_err("Invalid penv: data %pK\n", penv);
+		return NULL;
+	}
+
+	return penv->smmu_mapping;
+}
+EXPORT_SYMBOL(cnss_smmu_get_mapping);
+
+int cnss_smmu_map(phys_addr_t paddr, uint32_t *iova_addr, size_t size)
+{
+	unsigned long iova;
+	size_t len;
+	int ret = 0;
+
+	if (!iova_addr) {
+		pr_err("iova_addr is NULL, paddr %pa, size %zu\n",
+		       &paddr, size);
+		return -EINVAL;
+	}
+
+	len = roundup(size + paddr - rounddown(paddr, PAGE_SIZE), PAGE_SIZE);
+	iova = roundup(penv->smmu_iova_ipa_start, PAGE_SIZE);
+
+	if (iova >= penv->smmu_iova_ipa_start + penv->smmu_iova_ipa_len) {
+		pr_err("No IOVA space to map, iova %lx, smmu_iova_ipa_start %pad, smmu_iova_ipa_len %zu\n",
+		       iova,
+		       &penv->smmu_iova_ipa_start,
+		       penv->smmu_iova_ipa_len);
+		return -ENOMEM;
+	}
+
+	ret = iommu_map(penv->smmu_mapping->domain, iova,
+			rounddown(paddr, PAGE_SIZE), len,
+			IOMMU_READ | IOMMU_WRITE);
+	if (ret) {
+		pr_err("PA to IOVA mapping failed, ret %d\n", ret);
+		return ret;
+	}
+
+	penv->smmu_iova_ipa_start = iova + len;
+	*iova_addr = (uint32_t)(iova + paddr - rounddown(paddr, PAGE_SIZE));
+
+	return 0;
+}
+EXPORT_SYMBOL(cnss_smmu_map);
+
 static int cnss_probe(struct platform_device *pdev)
 {
 	int ret = 0;
@@ -2877,6 +2953,7 @@
 	struct resource *res;
 	u32 ramdump_size = 0;
 	u32 smmu_iova_address[2];
+	u32 smmu_iova_ipa[2];
 
 	if (penv)
 		return -ENODEV;
@@ -3028,6 +3105,17 @@
 		penv->smmu_iova_len = smmu_iova_address[1];
 	}
 
+	if (of_property_read_u32_array(dev->of_node,
+				       "qcom,wlan-smmu-iova-ipa",
+				       smmu_iova_ipa, 2) == 0) {
+		penv->smmu_iova_ipa_start = smmu_iova_ipa[0];
+		penv->smmu_iova_ipa_len = smmu_iova_ipa[1];
+	}
+
+	if (of_property_read_bool(dev->of_node,
+				  "qcom,smmu-s1-bypass"))
+		penv->smmu_s1_bypass = true;
+
 	ret = pci_register_driver(&cnss_wlan_pci_driver);
 	if (ret)
 		goto err_pci_reg;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index fe32de2..e7b8730 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -1509,14 +1509,13 @@
 					struct iwl_trans *trans)
 {
 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-	int max_irqs, num_irqs, i, ret, nr_online_cpus;
+	int max_irqs, num_irqs, i, ret;
 	u16 pci_cmd;
 
 	if (!trans->cfg->mq_rx_supported)
 		goto enable_msi;
 
-	nr_online_cpus = num_online_cpus();
-	max_irqs = min_t(u32, nr_online_cpus + 2, IWL_MAX_RX_HW_QUEUES);
+	max_irqs = min_t(u32, num_online_cpus() + 2, IWL_MAX_RX_HW_QUEUES);
 	for (i = 0; i < max_irqs; i++)
 		trans_pcie->msix_entries[i].entry = i;
 
@@ -1542,16 +1541,17 @@
 	 * Two interrupts less: non rx causes shared with FBQ and RSS.
 	 * More than two interrupts: we will use fewer RSS queues.
 	 */
-	if (num_irqs <= nr_online_cpus) {
+	if (num_irqs <= max_irqs - 2) {
 		trans_pcie->trans->num_rx_queues = num_irqs + 1;
 		trans_pcie->shared_vec_mask = IWL_SHARED_IRQ_NON_RX |
 			IWL_SHARED_IRQ_FIRST_RSS;
-	} else if (num_irqs == nr_online_cpus + 1) {
+	} else if (num_irqs == max_irqs - 1) {
 		trans_pcie->trans->num_rx_queues = num_irqs;
 		trans_pcie->shared_vec_mask = IWL_SHARED_IRQ_NON_RX;
 	} else {
 		trans_pcie->trans->num_rx_queues = num_irqs - 1;
 	}
+	WARN_ON(trans_pcie->trans->num_rx_queues > IWL_MAX_RX_HW_QUEUES);
 
 	trans_pcie->alloc_vecs = num_irqs;
 	trans_pcie->msix_enabled = true;
diff --git a/drivers/net/wireless/qca402x/Kconfig b/drivers/net/wireless/qca402x/Kconfig
new file mode 100644
index 0000000..bae2a49
--- /dev/null
+++ b/drivers/net/wireless/qca402x/Kconfig
@@ -0,0 +1,10 @@
+config QCA402X
+	tristate "Qualcomm QCA402X wireless support"
+	default n
+	---help---
+	Software for Qualcomm QCA402x including HIF and HTCA.
+
+	Say Y here if support for Qualcomm's QCA402x wireless SoC
+	via host-target communication protocol is required.
+	Say N to disable completely if support for that device is
+	not needed or if not sure.
diff --git a/drivers/net/wireless/qca402x/Makefile b/drivers/net/wireless/qca402x/Makefile
new file mode 100644
index 0000000..c052f73
--- /dev/null
+++ b/drivers/net/wireless/qca402x/Makefile
@@ -0,0 +1,9 @@
+obj-$(CONFIG_QCA402X) += htca_mbox/htca_mbox.o
+obj-$(CONFIG_QCA402X) += htca_mbox/htca_mbox_compl.o
+obj-$(CONFIG_QCA402X) += htca_mbox/htca_mbox_events.o
+obj-$(CONFIG_QCA402X) += htca_mbox/htca_mbox_intr.o
+obj-$(CONFIG_QCA402X) += htca_mbox/htca_mbox_recv.o
+obj-$(CONFIG_QCA402X) += htca_mbox/htca_mbox_send.o
+obj-$(CONFIG_QCA402X) += htca_mbox/htca_mbox_task.o
+obj-$(CONFIG_QCA402X) += htca_mbox/htca_mbox_utils.o
+obj-$(CONFIG_QCA402X) += hif_sdio/hif.o
diff --git a/drivers/net/wireless/qca402x/README.txt b/drivers/net/wireless/qca402x/README.txt
new file mode 100644
index 0000000..50873a8
--- /dev/null
+++ b/drivers/net/wireless/qca402x/README.txt
@@ -0,0 +1,52 @@
+This directory contains support to communicate beteween an APQ8053 Host
+and Qualcomm's QCA402x wireless SoC.
+
+QCA4020 SoC supports
+    802.11 (i.e. WiFi/WLAN)
+    802.15.4 (i.e. Zigbee, Thread)
+    BT LE
+
+Contents of this directory may eventually include:
+	cfg80211 support
+	SoftMAC wireless driver
+	Perhaps a mac80211 driver
+	Zigbee APIs
+	Thread APIs
+	BT APIs
+
+For now, all that is present are the bottommost layers of a communication stack:
+
+	HTCA - Host/Target Communications protocol
+		htca_mbox
+		    Quartz SDIO/SPI address space
+		    Quartz mailboxes and associated SDIO/SPI registers
+		    Quartz mbox credit-based flow control
+		htca_uart (TBD)
+
+	HIF - a shim layer which abstracts the underlying Master/Host-side
+		interconnect controller (e.g. SDIO controller) to provide
+		an interconnect-independent API for use by HTCA.
+		hif_sdio
+			Host Interface layer for SDIO Master controllers
+		hif_spi (TBD)
+			Host Interface layer for SPI Master controllers
+		hif_uart (TBD)
+			Host Interface layer for UART-based controllers
+
+	qrtzdev-a simple driver used for HTCA TESTING.
+
+Note: The initial implementation supports HTCA Protocol Version 1 over SDIO.
+It is based on previous HTCA implementations for Atheros SoCs, but uses a
+revised design which appropriately leverages kernel threads.
+
+This implementation is likely to evolve with increasing focus on performance,
+especially for use cases of current interest such as streaming video from
+Host over SDIO to WLAN; however this evolution may differ from the existing
+implementation of HTCA Protocol Version 2 used by earlier Atheros SoC's.
+
+However there are several issues with this code:
+  it is based on HTCA v2 protocol which adds complexity
+  it is based on a non-threaded design, originally for a non-threaded RTOS
+TBD: Ideally, these two implementations ought to be merged so that the resulting
+implementation is based on a proper threaded design and supports both HTCA
+protocol v1 and v2.
diff --git a/drivers/net/wireless/qca402x/hif_sdio/hif.c b/drivers/net/wireless/qca402x/hif_sdio/hif.c
new file mode 100644
index 0000000..56d3b95
--- /dev/null
+++ b/drivers/net/wireless/qca402x/hif_sdio/hif.c
@@ -0,0 +1,1230 @@
+/* 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.
+ */
+
+/* This file was originally distributed by Qualcomm Atheros, Inc.
+ * before Copyright ownership was assigned to the Linux Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "hif_internal.h"
+#include "hif.h"
+
+#if defined(DEBUG)
+#define hifdebug(fmt, a...)\
+	pr_err("hif %s:%d: " fmt, __func__, __LINE__, ##a)
+#else
+#define hifdebug(args...)
+#endif
+
+#define MAX_HIF_DEVICES 2
+#define ENABLE_SDIO_TIMEOUT 100 /* ms */
+
+static unsigned int hif_mmcbuswidth;
+EXPORT_SYMBOL(hif_mmcbuswidth);
+module_param(hif_mmcbuswidth, uint, 0644);
+MODULE_PARM_DESC(hif_mmcbuswidth, "Set MMC driver Bus Width: 1-1Bit, 4-4Bit, 8-8Bit");
+
+static unsigned int hif_mmcclock;
+EXPORT_SYMBOL(hif_mmcclock);
+module_param(hif_mmcclock, uint, 0644);
+MODULE_PARM_DESC(hif_mmcclock, "Set MMC driver Clock value");
+
+static unsigned int hif_writecccr1;
+module_param(hif_writecccr1, uint, 0644);
+static unsigned int hif_writecccr1value;
+module_param(hif_writecccr1value, uint, 0644);
+
+static unsigned int hif_writecccr2;
+module_param(hif_writecccr2, uint, 0644);
+static unsigned int hif_writecccr2value;
+module_param(hif_writecccr2value, uint, 0644);
+
+static unsigned int hif_writecccr3;
+module_param(hif_writecccr3, uint, 0644);
+static unsigned int hif_writecccr3value;
+module_param(hif_writecccr3value, uint, 0644);
+
+static unsigned int hif_writecccr4;
+module_param(hif_writecccr4, uint, 0644);
+
+static unsigned int hif_writecccr4value;
+module_param(hif_writecccr4value, uint, 0644);
+
+static int hif_device_inserted(struct sdio_func *func,
+			       const struct sdio_device_id *id);
+static void hif_device_removed(struct sdio_func *func);
+static void *add_hif_device(struct sdio_func *func);
+static struct hif_device *get_hif_device(struct sdio_func *func);
+static void del_hif_device(struct hif_device *device);
+static int func0_CMD52_write_byte(struct mmc_card *card, unsigned int address,
+				  unsigned char byte);
+static int func0_CMD52_read_byte(struct mmc_card *card, unsigned int address,
+				 unsigned char *byte);
+static void hif_stop_hif_task(struct hif_device *device);
+static struct bus_request *hif_allocate_bus_request(void *device);
+static void hif_free_bus_request(struct hif_device *device,
+				 struct bus_request *busrequest);
+static void hif_add_to_req_list(struct hif_device *device,
+				struct bus_request *busrequest);
+
+static int hif_reset_sdio_on_unload;
+module_param(hif_reset_sdio_on_unload, int, 0644);
+
+static u32 hif_forcedriverstrength = 1; /* force driver strength to type D */
+
+static const struct sdio_device_id hif_sdio_id_table[] = {
+	{SDIO_DEVICE(SDIO_ANY_ID,
+	SDIO_ANY_ID)}, /* QCA402x IDs are hardwired to 0 */
+	{/* null */},
+};
+
+MODULE_DEVICE_TABLE(sdio, hif_sdio_id_table);
+
+static struct sdio_driver hif_sdio_driver = {
+	.name = "hif_sdio",
+	.id_table = hif_sdio_id_table,
+	.probe = hif_device_inserted,
+	.remove = hif_device_removed,
+};
+
+/* make sure we unregister only when registered. */
+/* TBD: synchronization needed.... */
+/* device->completion_task, registered, ... */
+static int registered;
+
+static struct cbs_from_os hif_callbacks;
+
+static struct hif_device *hif_devices[MAX_HIF_DEVICES];
+
+static int hif_disable_func(struct hif_device *device, struct sdio_func *func);
+static int hif_enable_func(struct hif_device *device, struct sdio_func *func);
+
+static int hif_sdio_register_driver(struct cbs_from_os *callbacks)
+{
+	/* store the callback handlers */
+	hif_callbacks = *callbacks; /* structure copy */
+
+	/* Register with bus driver core */
+	registered++;
+
+	return sdio_register_driver(&hif_sdio_driver);
+}
+
+static void hif_sdio_unregister_driver(void)
+{
+	sdio_unregister_driver(&hif_sdio_driver);
+	registered--;
+}
+
+int hif_init(struct cbs_from_os *callbacks)
+{
+	int status;
+
+	hifdebug("Enter\n");
+	if (!callbacks)
+		return HIF_ERROR;
+
+	hifdebug("calling hif_sdio_register_driver\n");
+	status = hif_sdio_register_driver(callbacks);
+	hifdebug("hif_sdio_register_driver returns %d\n", status);
+	if (status != 0)
+		return HIF_ERROR;
+
+	return HIF_OK;
+}
+
+static int __hif_read_write(struct hif_device *device, u32 address,
+			    u8 *buffer, u32 length,
+			    u32 request, void *context)
+{
+	u8 opcode;
+	int status = HIF_OK;
+	int ret = 0;
+	u8 temp[4];
+
+	if (!device || !device->func)
+		return HIF_ERROR;
+
+	if (!buffer)
+		return HIF_EINVAL;
+
+	if (length == 0)
+		return HIF_EINVAL;
+
+	do {
+		if (!(request & HIF_EXTENDED_IO)) {
+			status = HIF_EINVAL;
+			break;
+		}
+
+		if (request & HIF_BLOCK_BASIS) {
+			if (WARN_ON(length & (HIF_MBOX_BLOCK_SIZE - 1)))
+				return HIF_EINVAL;
+		} else if (request & HIF_BYTE_BASIS) {
+		} else {
+			status = HIF_EINVAL;
+			break;
+		}
+
+		if (request & HIF_FIXED_ADDRESS) {
+			opcode = CMD53_FIXED_ADDRESS;
+		} else if (request & HIF_INCREMENTAL_ADDRESS) {
+			opcode = CMD53_INCR_ADDRESS;
+		} else {
+			status = HIF_EINVAL;
+			break;
+		}
+
+		if (request & HIF_WRITE) {
+			if (opcode == CMD53_FIXED_ADDRESS) {
+				/* TBD: Why special handling? */
+				if (length == 1) {
+					memset(temp, *buffer, 4);
+					ret = sdio_writesb(device->func,
+							   address, temp, 4);
+				} else {
+					ret =
+					    sdio_writesb(device->func, address,
+							 buffer, length);
+				}
+			} else {
+				ret = sdio_memcpy_toio(device->func, address,
+						       buffer, length);
+			}
+		} else if (request & HIF_READ) {
+			if (opcode == CMD53_FIXED_ADDRESS) {
+				if (length ==
+				    1) { /* TBD: Why special handling? */
+					memset(temp, 0, 4);
+					ret = sdio_readsb(device->func, temp,
+							  address, 4);
+					buffer[0] = temp[0];
+				} else {
+					ret = sdio_readsb(device->func, buffer,
+							  address, length);
+				}
+			} else {
+				ret = sdio_memcpy_fromio(device->func, buffer,
+							 address, length);
+			}
+		} else {
+			status = HIF_EINVAL; /* Neither read nor write */
+			break;
+		}
+
+		if (ret) {
+			hifdebug("SDIO op returns %d\n", ret);
+			status = HIF_ERROR;
+		}
+	} while (false);
+
+	return status;
+}
+
+/* Add busrequest to tail of sdio_request request list */
+static void hif_add_to_req_list(struct hif_device *device,
+				struct bus_request *busrequest)
+{
+	unsigned long flags;
+
+	busrequest->next = NULL;
+
+	spin_lock_irqsave(&device->req_qlock, flags);
+	if (device->req_qhead)
+		device->req_qtail->next = (void *)busrequest;
+	else
+		device->req_qhead = busrequest;
+	device->req_qtail = busrequest;
+	spin_unlock_irqrestore(&device->req_qlock, flags);
+}
+
+int hif_sync_read(void *hif_device, u32 address, u8 *buffer,
+		  u32 length, u32 request, void *context)
+{
+	int status;
+	struct hif_device *device = (struct hif_device *)hif_device;
+
+	if (!device || !device->func)
+		return HIF_ERROR;
+
+	sdio_claim_host(device->func);
+	status = __hif_read_write(device, address, buffer, length,
+				  request & ~HIF_SYNCHRONOUS, NULL);
+	sdio_release_host(device->func);
+	return status;
+}
+
+/* Queue a read/write request and optionally wait for it to complete. */
+int hif_read_write(void *hif_device, u32 address, void *buffer,
+		   u32 length, u32 req_type, void *context)
+{
+	struct bus_request *busrequest;
+	int status;
+	struct hif_device *device = (struct hif_device *)hif_device;
+
+	if (!device || !device->func)
+		return HIF_ERROR;
+
+	if (!(req_type & HIF_ASYNCHRONOUS) && !(req_type & HIF_SYNCHRONOUS))
+		return HIF_EINVAL;
+
+	/* Serialize all requests through the reqlist and HIFtask */
+	busrequest = hif_allocate_bus_request(device);
+	if (!busrequest)
+		return HIF_ERROR;
+
+	/* TBD: caller may pass buffers ON THE STACK, especially 4 Byte buffers.
+	 * If this is a problem on some platforms/drivers, this is one
+	 * reasonable
+	 * place to handle it. If poentially using DMA
+	 * reject large buffers on stack
+	 * copy 4B buffers allow register writes (no DMA)
+	 */
+
+	busrequest->address = address;
+	busrequest->buffer = buffer;
+	busrequest->length = length;
+	busrequest->req_type = req_type;
+	busrequest->context = context;
+
+	hif_add_to_req_list(device, busrequest);
+	device->hif_task_work = 1;
+	wake_up(&device->hif_wait); /* Notify HIF task */
+
+	if (req_type & HIF_ASYNCHRONOUS)
+		return HIF_PENDING;
+
+	/* Synchronous request -- wait for completion. */
+	wait_for_completion(&busrequest->comp_req);
+	status = busrequest->status;
+	hif_free_bus_request(device, busrequest);
+	return status;
+}
+
+/* add_to_completion_list() - Queue a completed request
+ * @device:    context to the hif device.
+ * @comple: SDIO bus access request.
+ *
+ * This function adds an sdio bus access request to the
+ * completion list.
+ *
+ * Return: No return.
+ */
+static void add_to_completion_list(struct hif_device *device,
+				   struct bus_request *comple)
+{
+	unsigned long flags;
+
+	comple->next = NULL;
+
+	spin_lock_irqsave(&device->compl_qlock, flags);
+	if (device->compl_qhead)
+		device->compl_qtail->next = (void *)comple;
+	else
+		device->compl_qhead = comple;
+
+	device->compl_qtail = comple;
+	spin_unlock_irqrestore(&device->compl_qlock, flags);
+}
+
+/* process_completion_list() - Remove completed requests from
+ * the completion list, and invoke the corresponding callbacks.
+ *
+ * @device:  HIF device handle.
+ *
+ * Function to clean the completion list.
+ *
+ * Return: No
+ */
+static void process_completion_list(struct hif_device *device)
+{
+	unsigned long flags;
+	struct bus_request *next_comple;
+	struct bus_request *request;
+
+	/* Pull the entire chain of completions from the list */
+	spin_lock_irqsave(&device->compl_qlock, flags);
+	request = device->compl_qhead;
+	device->compl_qhead = NULL;
+	device->compl_qtail = NULL;
+	spin_unlock_irqrestore(&device->compl_qlock, flags);
+
+	while (request) {
+		int status;
+		void *context;
+
+		hifdebug("HIF top of loop\n");
+		next_comple = (struct bus_request *)request->next;
+
+		status = request->status;
+		context = request->context;
+		hif_free_bus_request(device, request);
+		device->cbs_from_hif.rw_completion_hdl(context, status);
+
+		request = next_comple;
+	}
+}
+
+/* completion_task() - Thread to process request completions
+ *
+ * @param:   context to the hif device.
+ *
+ * Completed asynchronous requests are added to a completion
+ * queue where they are processed by this task. This serves
+ * multiple purposes:
+ * -minimizes processing by the HIFTask, which allows
+ *	that task to keep SDIO busy
+ * -allows request processing to be parallelized on
+ *	multiprocessor systems
+ * -provides a suspendable context for use by the
+ *	caller's callback function, though this should
+ *	not be abused since it will cause requests to
+ *	sit on the completion queue (which makes us
+ *	more likely to exhaust free requests).
+ *
+ * Return: 0 thread exits
+ */
+static int completion_task(void *param)
+{
+	struct hif_device *device;
+
+	device = (struct hif_device *)param;
+	set_current_state(TASK_INTERRUPTIBLE);
+
+	for (;;) {
+		hifdebug("HIF top of loop\n");
+		wait_event_interruptible(device->completion_wait,
+					 device->completion_work);
+		if (!device->completion_work)
+			break;
+
+		if (device->completion_shutdown)
+			break;
+
+		device->completion_work = 0;
+		process_completion_list(device);
+	}
+
+	/* Process any remaining completions.
+	 * This task should not be shut down
+	 * until after all requests are stopped.
+	 */
+	process_completion_list(device);
+
+	complete_and_exit(&device->completion_exit, 0);
+	return 0;
+}
+
+/* hif_request_complete() - Completion processing after a request
+ * is processed.
+ *
+ * @device:    device handle.
+ * @request:   SIDO bus access request.
+ *
+ * All completed requests are queued onto a completion list
+ * which is processed by complete_task.
+ *
+ * Return: None.
+ */
+static inline void hif_request_complete(struct hif_device *device,
+					struct bus_request *request)
+{
+	add_to_completion_list(device, request);
+	device->completion_work = 1;
+	wake_up(&device->completion_wait);
+}
+
+/* hif_stop_completion_thread() - Destroy the completion task
+ * @device: device handle.
+ *
+ * This function will destroy the completion thread.
+ *
+ * Return: None.
+ */
+static inline void hif_stop_completion_thread(struct hif_device *device)
+{
+	if (device->completion_task) {
+		init_completion(&device->completion_exit);
+		device->completion_shutdown = 1;
+
+		device->completion_work = 1;
+		wake_up(&device->completion_wait);
+		wait_for_completion(&device->completion_exit);
+		device->completion_task = NULL;
+	}
+}
+
+/* This task tries to keep the SDIO bus as busy as it
+ * can. It pulls both requests off the request queue and
+ * it uses the underlying sdio API to make them happen.
+ *
+ * Requests may be one of
+ * synchronous (a thread is suspended until it completes)
+ * asynchronous (a completion callback will be invoked)
+ * and one of
+ * reads (from Target SDIO space into Host RAM)
+ * writes (from Host RAM into Target SDIO space)
+ * and it is to one of
+ * Target's mailbox space
+ * Target's register space
+ * and lots of other choices.
+ */
+static int hif_task(void *param)
+{
+	struct hif_device *device;
+	struct bus_request *request;
+	int status;
+	unsigned long flags;
+
+	set_user_nice(current, -3);
+	device = (struct hif_device *)param;
+	set_current_state(TASK_INTERRUPTIBLE);
+
+	for (;;) {
+		hifdebug("top of loop\n");
+		/* wait for work */
+		wait_event_interruptible(device->hif_wait,
+					 device->hif_task_work);
+		if (!device->hif_task_work)
+			/* interrupted, exit */
+			break;
+
+		if (device->hif_shutdown)
+			break;
+
+		device->hif_task_work = 0;
+
+		/* We want to hold the host over multiple cmds if possible;
+		 * but holding the host blocks card interrupts.
+		 */
+		sdio_claim_host(device->func);
+
+		for (;;) {
+			hifdebug("pull next request\n");
+			/* Pull the next request to work on */
+			spin_lock_irqsave(&device->req_qlock, flags);
+			request = device->req_qhead;
+			if (!request) {
+				spin_unlock_irqrestore(&device->req_qlock,
+						       flags);
+				break;
+			}
+
+			/* Remove request from queue */
+			device->req_qhead = (struct bus_request *)request->next;
+			/* Note: No need to clean up req_qtail */
+
+			spin_unlock_irqrestore(&device->req_qlock, flags);
+
+			/* call __hif_read_write to do the work */
+			hifdebug("before HIFRW: address=0x%08x buffer=0x%pK\n",
+				 request->address, request->buffer);
+			hifdebug("before HIFRW: length=%d req_type=0x%08x\n",
+				 request->length, request->req_type);
+
+			if (request->req_type & HIF_WRITE) {
+				int i;
+				int dbgcount;
+
+				if (request->length <= 16)
+					dbgcount = request->length;
+				else
+					dbgcount = 16;
+
+				for (i = 0; i < dbgcount; i++)
+					hifdebug("|0x%02x", request->buffer[i]);
+				hifdebug("\n");
+			}
+			status = __hif_read_write(
+			    device, request->address, request->buffer,
+			    request->length,
+			    request->req_type & ~HIF_SYNCHRONOUS, NULL);
+			hifdebug("after HIFRW: address=0x%08x buffer=0x%pK\n",
+				 request->address, request->buffer);
+			hifdebug("after HIFRW: length=%d req_type=0x%08x\n",
+				 request->length, request->req_type);
+
+			if (request->req_type & HIF_READ) {
+				int i;
+				int dbgcount;
+
+				if (request->length <= 16)
+					dbgcount = request->length;
+				else
+					dbgcount = 16;
+
+				for (i = 0; i < dbgcount; i++)
+					hifdebug("|0x%02x", request->buffer[i]);
+				hifdebug("\n");
+			}
+
+			/* When we return, the read/write is done */
+			request->status = status;
+
+			if (request->req_type & HIF_ASYNCHRONOUS)
+				hif_request_complete(device, request);
+			else
+				/* notify thread that's waiting on this request
+				 */
+				complete(&request->comp_req);
+		}
+		sdio_release_host(device->func);
+	}
+
+	complete_and_exit(&device->hif_exit, 0);
+	return 0;
+}
+
+int hif_configure_device(void *hif_device,
+			 enum hif_device_config_opcode opcode,
+			 void *config, u32 config_len)
+{
+	int status = HIF_OK;
+	struct hif_device *device = (struct hif_device *)hif_device;
+
+	switch (opcode) {
+	case HIF_DEVICE_GET_MBOX_BLOCK_SIZE:
+		((u32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE;
+		((u32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE;
+		((u32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE;
+		((u32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE;
+		break;
+
+	case HIF_DEVICE_SET_CONTEXT:
+		device->context = config;
+		break;
+
+	case HIF_DEVICE_GET_CONTEXT:
+		if (!config)
+			return HIF_ERROR;
+		*(void **)config = device->context;
+		break;
+
+	default:
+		status = HIF_ERROR;
+	}
+
+	return status;
+}
+
+void hif_shutdown_device(void *device)
+{
+	if (!device) {
+		int i;
+		/* since we are unloading the driver, reset all cards
+		 * in case the SDIO card is externally powered and we
+		 * are unloading the SDIO stack.  This avoids the problem
+		 * when the SDIO stack is reloaded and attempts are made
+		 * to re-enumerate a card that is already enumerated.
+		 */
+
+		/* Unregister with bus driver core */
+		if (registered) {
+			registered = 0;
+			hif_sdio_unregister_driver();
+			WARN_ON(1);
+			return;
+		}
+
+		for (i = 0; i < MAX_HIF_DEVICES; ++i) {
+			if (hif_devices[i] && !hif_devices[i]->func) {
+				del_hif_device(hif_devices[i]);
+				hif_devices[i] = NULL;
+			}
+		}
+	}
+}
+
+static void hif_irq_handler(struct sdio_func *func)
+{
+	int status;
+	struct hif_device *device;
+
+	device = get_hif_device(func);
+	device->irq_handling = 1;
+	/* release the host during ints so we can pick it back up when we
+	 * process cmds
+	 */
+	sdio_release_host(device->func);
+	status = device->cbs_from_hif.dsr_hdl(device->cbs_from_hif.context);
+	sdio_claim_host(device->func);
+	device->irq_handling = 0;
+}
+
+static void hif_force_driver_strength(struct sdio_func *func)
+{
+	unsigned int addr = SDIO_CCCR_DRIVE_STRENGTH;
+	unsigned char value = 0;
+
+	if (func0_CMD52_read_byte(func->card, addr, &value))
+		goto cmd_fail;
+
+	value = (value & (~(SDIO_DRIVE_DTSx_MASK << SDIO_DRIVE_DTSx_SHIFT))) |
+			SDIO_DTSx_SET_TYPE_D;
+	if (func0_CMD52_write_byte(func->card, addr, value))
+		goto cmd_fail;
+
+	addr = CCCR_SDIO_DRIVER_STRENGTH_ENABLE_ADDR;
+	value = 0;
+	if (func0_CMD52_read_byte(func->card, addr, &value))
+		goto cmd_fail;
+
+	value = (value & (~CCCR_SDIO_DRIVER_STRENGTH_ENABLE_MASK)) |
+			CCCR_SDIO_DRIVER_STRENGTH_ENABLE_A |
+			CCCR_SDIO_DRIVER_STRENGTH_ENABLE_C |
+			CCCR_SDIO_DRIVER_STRENGTH_ENABLE_D;
+	if (func0_CMD52_write_byte(func->card, addr, value))
+		goto cmd_fail;
+	return;
+cmd_fail:
+	hifdebug("set fail\n");
+}
+
+static int hif_set_mmc_buswidth(struct sdio_func *func,
+				struct hif_device *device)
+{
+	int ret = -1;
+
+	if (hif_mmcbuswidth == 1) {
+		ret = func0_CMD52_write_byte(func->card, SDIO_CCCR_IF,
+					     SDIO_BUS_CD_DISABLE |
+					     SDIO_BUS_WIDTH_1BIT);
+		if (ret)
+			return ret;
+		device->host->ios.bus_width = MMC_BUS_WIDTH_1;
+		device->host->ops->set_ios(device->host, &device->host->ios);
+	} else if (hif_mmcbuswidth == 4 &&
+		   (device->host->caps & MMC_CAP_4_BIT_DATA)) {
+		ret = func0_CMD52_write_byte(func->card, SDIO_CCCR_IF,
+					     SDIO_BUS_CD_DISABLE |
+					     SDIO_BUS_WIDTH_4BIT);
+		if (ret)
+			return ret;
+		device->host->ios.bus_width = MMC_BUS_WIDTH_4;
+		device->host->ops->set_ios(device->host, &device->host->ios);
+	}
+#ifdef SDIO_BUS_WIDTH_8BIT
+	else if (hif_mmcbuswidth == 8 &&
+		 (device->host->caps & MMC_CAP_8_BIT_DATA)) {
+		ret = func0_CMD52_write_byte(func->card, SDIO_CCCR_IF,
+					     SDIO_BUS_CD_DISABLE |
+					     SDIO_BUS_WIDTH_8BIT);
+		if (ret)
+			return ret;
+		device->host->ios.bus_width = MMC_BUS_WIDTH_8;
+		device->host->ops->set_ios(device->host, &device->host->ios);
+	}
+#endif /* SDIO_BUS_WIDTH_8BIT */
+	return ret;
+}
+
+static int hif_device_inserted(struct sdio_func *func,
+			       const struct sdio_device_id *id)
+{
+	int i;
+	int ret = -1;
+	struct hif_device *device = NULL;
+	int count;
+
+	hifdebug("Enter\n");
+
+	/* dma_mask should be populated here.
+	 * Use the parent device's setting.
+	 */
+	func->dev.dma_mask = mmc_dev(func->card->host)->dma_mask;
+
+	if (!add_hif_device(func))
+		return ret;
+	device = get_hif_device(func);
+
+	for (i = 0; i < MAX_HIF_DEVICES; ++i) {
+		if (!hif_devices[i]) {
+			hif_devices[i] = device;
+			break;
+		}
+	}
+	if (WARN_ON(i >= MAX_HIF_DEVICES))
+		return ret;
+
+	device->id = id;
+	device->host = func->card->host;
+	device->is_enabled = false;
+
+	{
+		u32 clock, clock_set = SDIO_CLOCK_FREQUENCY_DEFAULT;
+
+		sdio_claim_host(func);
+
+		/* force driver strength to type D */
+		if (hif_forcedriverstrength == 1)
+			hif_force_driver_strength(func);
+
+		if (hif_writecccr1)
+			(void)func0_CMD52_write_byte(func->card, hif_writecccr1,
+						     hif_writecccr1value);
+		if (hif_writecccr2)
+			(void)func0_CMD52_write_byte(func->card, hif_writecccr2,
+						     hif_writecccr2value);
+		if (hif_writecccr3)
+			(void)func0_CMD52_write_byte(func->card, hif_writecccr3,
+						     hif_writecccr3value);
+		if (hif_writecccr4)
+			(void)func0_CMD52_write_byte(func->card, hif_writecccr4,
+						     hif_writecccr4value);
+		/* Set MMC Clock */
+		if (hif_mmcclock > 0)
+			clock_set = hif_mmcclock;
+		if (mmc_card_hs(func->card))
+			clock = 50000000;
+		else
+			clock = func->card->cis.max_dtr;
+		if (clock > device->host->f_max)
+			clock = device->host->f_max;
+		hifdebug("clock is %d", clock);
+
+		/* only when hif_mmcclock module parameter is specified,
+		 * set the clock explicitly
+		 */
+		if (hif_mmcclock > 0) {
+			device->host->ios.clock = clock_set;
+			device->host->ops->set_ios(device->host,
+						   &device->host->ios);
+		}
+		/* Set MMC Bus Width: 1-1Bit, 4-4Bit, 8-8Bit */
+		if (hif_mmcbuswidth > 0)
+			ret = hif_set_mmc_buswidth(func, device);
+
+		sdio_release_host(func);
+	}
+
+	spin_lock_init(&device->req_free_qlock);
+	spin_lock_init(&device->req_qlock);
+
+	/* Initialize the bus requests to be used later */
+	memset(device->bus_request, 0, sizeof(device->bus_request));
+	for (count = 0; count < BUS_REQUEST_MAX_NUM; count++) {
+		init_completion(&device->bus_request[count].comp_req);
+		hif_free_bus_request(device, &device->bus_request[count]);
+	}
+	init_waitqueue_head(&device->hif_wait);
+	spin_lock_init(&device->compl_qlock);
+	init_waitqueue_head(&device->completion_wait);
+
+	ret = hif_enable_func(device, func);
+	if ((ret == HIF_OK) || (ret == HIF_PENDING)) {
+		hifdebug("Function is ENABLED");
+		return 0;
+	}
+
+	for (i = 0; i < MAX_HIF_DEVICES; i++) {
+		if (hif_devices[i] == device) {
+			hif_devices[i] = NULL;
+			break;
+		}
+	}
+	sdio_set_drvdata(func, NULL);
+	del_hif_device(device);
+	return ret;
+}
+
+void hif_un_mask_interrupt(void *hif_device)
+{
+	struct hif_device *device = (struct hif_device *)hif_device;
+
+	if (!device || !device->func)
+		return;
+
+	/* Unmask our function IRQ */
+	sdio_claim_host(device->func);
+	device->func->card->host->ops->enable_sdio_irq(device->func->card->host,
+						       1);
+	device->is_intr_enb = true;
+	sdio_release_host(device->func);
+}
+
+void hif_mask_interrupt(void *hif_device)
+{
+	struct hif_device *device = (struct hif_device *)hif_device;
+
+	if (!device || !device->func)
+		return;
+
+	/* Mask our function IRQ */
+	sdio_claim_host(device->func);
+	device->func->card->host->ops->enable_sdio_irq(device->func->card->host,
+						       0);
+	device->is_intr_enb = false;
+	sdio_release_host(device->func);
+}
+
+static struct bus_request *hif_allocate_bus_request(void *hif_device)
+{
+	struct bus_request *busrequest;
+	unsigned long flag;
+	struct hif_device *device = (struct hif_device *)hif_device;
+
+	spin_lock_irqsave(&device->req_free_qlock, flag);
+	/* Remove first in list */
+	busrequest = device->bus_req_free_qhead;
+	if (busrequest)
+		device->bus_req_free_qhead =
+			(struct bus_request *)busrequest->next;
+	spin_unlock_irqrestore(&device->req_free_qlock, flag);
+
+	return busrequest;
+}
+
+static void hif_free_bus_request(struct hif_device *device,
+				 struct bus_request *busrequest)
+{
+	unsigned long flag;
+
+	if (!busrequest)
+		return;
+
+	busrequest->next = NULL;
+
+	/* Insert first in list */
+	spin_lock_irqsave(&device->req_free_qlock, flag);
+	busrequest->next = (struct bus_request *)device->bus_req_free_qhead;
+	device->bus_req_free_qhead = busrequest;
+	spin_unlock_irqrestore(&device->req_free_qlock, flag);
+}
+
+static int hif_disable_func(struct hif_device *device, struct sdio_func *func)
+{
+	int ret;
+	int status = HIF_OK;
+
+	device = get_hif_device(func);
+
+	hif_stop_completion_thread(device);
+	hif_stop_hif_task(device);
+
+	/* Disable the card */
+	sdio_claim_host(device->func);
+	ret = sdio_disable_func(device->func);
+	if (ret)
+		status = HIF_ERROR;
+
+	if (hif_reset_sdio_on_unload && (status == HIF_OK)) {
+		/* Reset the SDIO interface.  This is useful in
+		 * automated testing where the card does not need
+		 * to be removed at the end of the test.  It is
+		 * expected that the user will also unload/reload
+		 * the host controller driver to force the bus driver
+		 * to re-enumerate the slot.
+		 */
+
+		/* NOTE : sdio_f0_writeb() cannot be used here, that API only
+		 * allows access to undefined registers in the range of:
+		 * 0xF0-0xFF
+		 */
+
+		ret = func0_CMD52_write_byte(device->func->card,
+					     SDIO_CCCR_ABORT, (1 << 3));
+		if (ret)
+			status = HIF_ERROR;
+	}
+
+	sdio_release_host(device->func);
+
+	if (status == HIF_OK)
+		device->is_enabled = false;
+	return status;
+}
+
+static int hif_enable_func(struct hif_device *device, struct sdio_func *func)
+{
+	int ret = HIF_OK;
+
+	device = get_hif_device(func);
+
+	if (!device)
+		return HIF_EINVAL;
+
+	if (!device->is_enabled) {
+		/* enable the SDIO function */
+		sdio_claim_host(func);
+
+		/* give us some time to enable, in ms */
+		func->enable_timeout = ENABLE_SDIO_TIMEOUT;
+		ret = sdio_enable_func(func);
+		if (ret) {
+			sdio_release_host(func);
+			return HIF_ERROR;
+		}
+		ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE);
+
+		sdio_release_host(func);
+		if (ret)
+			return HIF_ERROR;
+		device->is_enabled = true;
+
+		if (!device->completion_task) {
+			device->compl_qhead = NULL;
+			device->compl_qtail = NULL;
+			device->completion_shutdown = 0;
+			device->completion_task = kthread_create(
+			    completion_task, (void *)device, "HIFCompl");
+			if (IS_ERR(device->completion_task)) {
+				device->completion_shutdown = 1;
+				return HIF_ERROR;
+			}
+			wake_up_process(device->completion_task);
+		}
+
+		/* create HIF I/O thread */
+		if (!device->hif_task) {
+			device->hif_shutdown = 0;
+			device->hif_task =
+			    kthread_create(hif_task, (void *)device, "HIF");
+			if (IS_ERR(device->hif_task)) {
+				device->hif_shutdown = 1;
+				return HIF_ERROR;
+			}
+			wake_up_process(device->hif_task);
+		}
+	}
+
+	if (!device->claimed_context) {
+		ret = hif_callbacks.dev_inserted_hdl(hif_callbacks.context,
+						     device);
+		if (ret != HIF_OK) {
+			/* Disable the SDIO func & Reset the sdio
+			 * for automated tests to move ahead, where
+			 * the card does not need to be removed at
+			 * the end of the test.
+			 */
+			hif_disable_func(device, func);
+		}
+		(void)sdio_claim_irq(func, hif_irq_handler);
+	}
+
+	return ret;
+}
+
+static void hif_device_removed(struct sdio_func *func)
+{
+	int i;
+	int status = HIF_OK;
+	struct hif_device *device;
+
+	device = get_hif_device(func);
+	if (!device)
+		return;
+
+	for (i = 0; i < MAX_HIF_DEVICES; ++i) {
+		if (hif_devices[i] == device)
+			hif_devices[i] = NULL;
+	}
+
+	if (device->claimed_context) {
+		status = hif_callbacks.dev_removed_hdl(
+		    device->claimed_context, device);
+	}
+
+	/* TBD: Release IRQ (opposite of sdio_claim_irq) */
+	hif_mask_interrupt(device);
+
+	if (device->is_enabled)
+		status = hif_disable_func(device, func);
+
+	del_hif_device(device);
+}
+
+static void *add_hif_device(struct sdio_func *func)
+{
+	struct hif_device *hifdevice = NULL;
+
+	if (!func)
+		return NULL;
+
+	hifdevice = kmalloc(sizeof(*hifdevice), GFP_KERNEL);
+	if (!hifdevice)
+		return NULL;
+
+	memset(hifdevice, 0, sizeof(*hifdevice));
+	hifdevice->func = func;
+	sdio_set_drvdata(func, hifdevice);
+
+	return (void *)hifdevice;
+}
+
+static struct hif_device *get_hif_device(struct sdio_func *func)
+{
+	return (struct hif_device *)sdio_get_drvdata(func);
+}
+
+static void del_hif_device(struct hif_device *device)
+{
+	if (!device)
+		return;
+	kfree(device);
+}
+
+void hif_claim_device(void *hif_device, void *context)
+{
+	struct hif_device *device = (struct hif_device *)hif_device;
+
+	device->claimed_context = context;
+}
+
+void hif_release_device(void *hif_device)
+{
+	struct hif_device *device = (struct hif_device *)hif_device;
+
+	device->claimed_context = NULL;
+}
+
+int hif_attach(void *hif_device, struct cbs_from_hif *callbacks)
+{
+	struct hif_device *device = (struct hif_device *)hif_device;
+
+	if (device->cbs_from_hif.context) {
+		/* already in use! */
+		return HIF_ERROR;
+	}
+	device->cbs_from_hif = *callbacks;
+	return HIF_OK;
+}
+
+static void hif_stop_hif_task(struct hif_device *device)
+{
+	if (device->hif_task) {
+		init_completion(&device->hif_exit);
+		device->hif_shutdown = 1;
+		device->hif_task_work = 1;
+		wake_up(&device->hif_wait);
+		wait_for_completion(&device->hif_exit);
+		device->hif_task = NULL;
+	}
+}
+
+/* hif_reset_target() - Reset target device
+ * @struct hif_device: pointer to struct hif_device structure
+ *
+ * Reset the target by invoking power off and power on
+ * sequence to bring back target into active state.
+ * This API shall be called only when driver load/unload
+ * is in progress.
+ *
+ * Return: 0 on success, error for failure case.
+ */
+static int hif_reset_target(struct hif_device *hif_device)
+{
+	int ret;
+
+	if (!hif_device || !hif_device->func || !hif_device->func->card)
+		return -ENODEV;
+	/* Disable sdio func->pull down WLAN_EN-->pull down DAT_2 line */
+	ret = mmc_power_save_host(hif_device->func->card->host);
+	if (ret)
+		goto done;
+
+	/* pull up DAT_2 line->pull up WLAN_EN-->Enable sdio func */
+	ret = mmc_power_restore_host(hif_device->func->card->host);
+
+done:
+	return ret;
+}
+
+void hif_detach(void *hif_device)
+{
+	struct hif_device *device = (struct hif_device *)hif_device;
+
+	hif_stop_hif_task(device);
+	if (device->ctrl_response_timeout) {
+		/* Reset the target by invoking power off and power on sequence
+		 * to the card to bring back into active state.
+		 */
+		if (hif_reset_target(device))
+			panic("BUG");
+		device->ctrl_response_timeout = false;
+	}
+
+	memset(&device->cbs_from_hif, 0, sizeof(device->cbs_from_hif));
+}
+
+#define SDIO_SET_CMD52_ARG(arg, rw, func, raw, address, writedata) \
+	((arg) = ((((rw) & 1) << 31) | (((func) & 0x7) << 28) | \
+		 (((raw) & 1) << 27) | (1 << 26) | \
+		 (((address) & 0x1FFFF) << 9) | (1 << 8) | \
+		 ((writedata) & 0xFF)))
+
+#define SDIO_SET_CMD52_READ_ARG(arg, func, address) \
+	SDIO_SET_CMD52_ARG(arg, 0, (func), 0, address, 0x00)
+#define SDIO_SET_CMD52_WRITE_ARG(arg, func, address, value) \
+	SDIO_SET_CMD52_ARG(arg, 1, (func), 0, address, value)
+
+static int func0_CMD52_write_byte(struct mmc_card *card, unsigned int address,
+				  unsigned char byte)
+{
+	struct mmc_command ioCmd;
+	unsigned long arg;
+	int status;
+
+	memset(&ioCmd, 0, sizeof(ioCmd));
+	SDIO_SET_CMD52_WRITE_ARG(arg, 0, address, byte);
+	ioCmd.opcode = SD_IO_RW_DIRECT;
+	ioCmd.arg = arg;
+	ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
+	status = mmc_wait_for_cmd(card->host, &ioCmd, 0);
+
+	return status;
+}
+
+static int func0_CMD52_read_byte(struct mmc_card *card, unsigned int address,
+				 unsigned char *byte)
+{
+	struct mmc_command ioCmd;
+	unsigned long arg;
+	s32 err;
+
+	memset(&ioCmd, 0, sizeof(ioCmd));
+	SDIO_SET_CMD52_READ_ARG(arg, 0, address);
+	ioCmd.opcode = SD_IO_RW_DIRECT;
+	ioCmd.arg = arg;
+	ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
+
+	err = mmc_wait_for_cmd(card->host, &ioCmd, 0);
+
+	if ((!err) && (byte))
+		*byte = ioCmd.resp[0] & 0xFF;
+
+	return err;
+}
+
+void hif_set_handle(void *hif_handle, void *handle)
+{
+	struct hif_device *device = (struct hif_device *)hif_handle;
+
+	device->caller_handle = handle;
+}
+
+size_t hif_get_device_size(void)
+{
+	return sizeof(struct hif_device);
+}
diff --git a/drivers/net/wireless/qca402x/hif_sdio/hif.h b/drivers/net/wireless/qca402x/hif_sdio/hif.h
new file mode 100644
index 0000000..924d2e4
--- /dev/null
+++ b/drivers/net/wireless/qca402x/hif_sdio/hif.h
@@ -0,0 +1,335 @@
+/* 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.
+ */
+
+/* This file was originally distributed by Qualcomm Atheros, Inc.
+ * before Copyright ownership was assigned to the Linux Foundation.
+ */
+
+#ifndef _HIF_H_
+#define _HIF_H_
+
+#define DEBUG
+#undef DEBUG
+
+#define HIF_OK 0
+#define HIF_PENDING 1
+#define HIF_ERROR 2
+#define HIF_EINVAL 3
+
+/* direction - Direction of transfer (HIF_READ/HIF_WRITE). */
+#define HIF_READ 0x00000001
+#define HIF_WRITE 0x00000002
+#define HIF_DIR_MASK (HIF_READ | HIF_WRITE)
+
+/* type - An interface may support different kind of read/write commands.
+ * For example: SDIO supports CMD52/CMD53s. In case of MSIO it
+ * translates to using different kinds of TPCs. The command type
+ * is thus divided into a basic and an extended command and can
+ * be specified using HIF_BASIC_IO/HIF_EXTENDED_IO.
+ */
+#define HIF_BASIC_IO 0x00000004
+#define HIF_EXTENDED_IO 0x00000008
+#define HIF_TYPE_MASK (HIF_BASIC_IO | HIF_EXTENDED_IO)
+
+/* emode - This indicates the whether the command is to be executed in a
+ * blocking or non-blocking fashion (HIF_SYNCHRONOUS/
+ * HIF_ASYNCHRONOUS). The read/write data paths in HTCA have been
+ * implemented using the asynchronous mode allowing the the bus
+ * driver to indicate the completion of operation through the
+ * registered callback routine. The requirement primarily comes
+ * from the contexts these operations get called from (a driver's
+ * transmit context or the ISR context in case of receive).
+ * Support for both of these modes is essential.
+ */
+#define HIF_SYNCHRONOUS 0x00000010
+#define HIF_ASYNCHRONOUS 0x00000020
+#define HIF_EMODE_MASK (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS)
+
+/* dmode - An interface may support different kinds of commands based on
+ * the tradeoff between the amount of data it can carry and the
+ * setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/
+ * HIF_BLOCK_BASIS). In case of latter, the data is rounded off
+ * to the nearest block size by padding. The size of the block is
+ * configurable at compile time using the HIF_BLOCK_SIZE and is
+ * negotiated with the target during initialization after the
+ * AR6000 interrupts are enabled.
+ */
+#define HIF_BYTE_BASIS 0x00000040
+#define HIF_BLOCK_BASIS 0x00000080
+#define HIF_DMODE_MASK (HIF_BYTE_BASIS | HIF_BLOCK_BASIS)
+
+/* amode - This indicates if the address has to be incremented on AR6000
+ * after every read/write operation (HIF?FIXED_ADDRESS/
+ * HIF_INCREMENTAL_ADDRESS).
+ */
+#define HIF_FIXED_ADDRESS 0x00000100
+#define HIF_INCREMENTAL_ADDRESS 0x00000200
+#define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | HIF_INCREMENTAL_ADDRESS)
+
+#define HIF_WR_ASYNC_BYTE_FIX \
+	(HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | \
+	 HIF_FIXED_ADDRESS)
+#define HIF_WR_ASYNC_BYTE_INC \
+	(HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | \
+	 HIF_INCREMENTAL_ADDRESS)
+#define HIF_WR_ASYNC_BLOCK_INC \
+	(HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | \
+	 HIF_INCREMENTAL_ADDRESS)
+#define HIF_WR_SYNC_BYTE_FIX \
+	(HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | \
+	 HIF_FIXED_ADDRESS)
+#define HIF_WR_SYNC_BYTE_INC \
+	(HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | \
+	 HIF_INCREMENTAL_ADDRESS)
+#define HIF_WR_SYNC_BLOCK_INC \
+	(HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | \
+	 HIF_INCREMENTAL_ADDRESS)
+#define HIF_WR_ASYNC_BLOCK_FIX \
+	(HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | \
+	 HIF_FIXED_ADDRESS)
+#define HIF_WR_SYNC_BLOCK_FIX \
+	(HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | \
+	 HIF_FIXED_ADDRESS)
+#define HIF_RD_SYNC_BYTE_INC \
+	(HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | \
+	 HIF_INCREMENTAL_ADDRESS)
+#define HIF_RD_SYNC_BYTE_FIX \
+	(HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | \
+	 HIF_FIXED_ADDRESS)
+#define HIF_RD_ASYNC_BYTE_FIX \
+	(HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | \
+	 HIF_FIXED_ADDRESS)
+#define HIF_RD_ASYNC_BLOCK_FIX \
+	(HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | \
+	 HIF_FIXED_ADDRESS)
+#define HIF_RD_ASYNC_BYTE_INC \
+	(HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | \
+	 HIF_INCREMENTAL_ADDRESS)
+#define HIF_RD_ASYNC_BLOCK_INC \
+	(HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | \
+	 HIF_INCREMENTAL_ADDRESS)
+#define HIF_RD_SYNC_BLOCK_INC \
+	(HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | \
+	 HIF_INCREMENTAL_ADDRESS)
+#define HIF_RD_SYNC_BLOCK_FIX \
+	(HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | \
+	 HIF_FIXED_ADDRESS)
+
+enum hif_device_config_opcode {
+	HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
+	HIF_DEVICE_SET_CONTEXT,
+	HIF_DEVICE_GET_CONTEXT,
+};
+
+/* HIF CONFIGURE definitions:
+ *
+ * HIF_DEVICE_GET_MBOX_BLOCK_SIZE
+ * input : none
+ * output : array of 4 u32s
+ * notes: block size is returned for each mailbox (4)
+ *
+ * HIF_DEVICE_SET_CONTEXT
+ * input : arbitrary pointer-sized value
+ * output: none
+ * notes: stores an arbitrary value which can be retrieved later
+ *
+ * HIF_DEVICE_GET_CONTEXT
+ * input: none
+ * output : arbitrary pointer-sized value
+ * notes: retrieves an arbitrary value which was set earlier
+ */
+struct cbs_from_hif {
+	void *context; /* context to pass to the dsrhandler
+			* note : rw_completion_hdl is provided the context
+			* passed to hif_read_write
+			*/
+	int (*rw_completion_hdl)(void *rw_context, int status);
+	int (*dsr_hdl)(void *context);
+};
+
+struct cbs_from_os {
+	void *context; /* context to pass for all callbacks except
+			* dev_removed_hdl the dev_removed_hdl is only called if
+			* the device is claimed
+			*/
+	int (*dev_inserted_hdl)(void *context, void *hif_handle);
+	int (*dev_removed_hdl)(void *claimed_context, void *hif_handle);
+	int (*dev_suspend_hdl)(void *context);
+	int (*dev_resume_hdl)(void *context);
+	int (*dev_wakeup_hdl)(void *context);
+#if defined(DEVICE_POWER_CHANGE)
+	int (*dev_pwr_change_hdl)(void *context,
+				  HIF_DEVICE_POWER_CHANGE_TYPE config);
+#endif /* DEVICE_POWER_CHANGE */
+};
+
+/* other interrupts (non-Recv) are pending, host
+ * needs to read the register table to figure out what
+ */
+#define HIF_OTHER_EVENTS BIT(0)
+
+#define HIF_RECV_MSG_AVAIL BIT(1) /* pending recv packet */
+
+struct hif_pending_events_info {
+	u32 events;
+	u32 look_ahead;
+	u32 available_recv_bytes;
+};
+
+/* function to get pending events , some HIF modules use special mechanisms
+ * to detect packet available and other interrupts
+ */
+typedef int (*HIF_PENDING_EVENTS_FUNC)(void *device,
+				       struct hif_pending_events_info *p_events,
+				       void *async_context);
+
+#define HIF_MASK_RECV TRUE
+#define HIF_UNMASK_RECV FALSE
+/* function to mask recv events */
+typedef int (*HIF_MASK_UNMASK_RECV_EVENT)(void *device, bool mask,
+					  void *async_context);
+
+#ifdef HIF_MBOX_SLEEP_WAR
+/* This API is used to update the target sleep state */
+void hif_set_mbox_sleep(void *device, bool sleep, bool wait,
+			bool cache);
+#endif
+/* This API is used to perform any global initialization of the HIF layer
+ * and to set OS driver callbacks (i.e. insertion/removal) to the HIF layer
+ */
+int hif_init(struct cbs_from_os *callbacks);
+
+/* This API claims the HIF device and provides a context for handling removal.
+ * The device removal callback is only called when the OS claims
+ * a device.  The claimed context must be non-NULL
+ */
+void hif_claim_device(void *device, void *claimed_context);
+
+/* release the claimed device */
+void hif_release_device(void *device);
+
+/* This API allows the calling layer to attach callbacks from HIF */
+int hif_attach(void *device, struct cbs_from_hif *callbacks);
+
+/* This API allows the calling layer to detach callbacks from HIF */
+void hif_detach(void *device);
+
+void hif_set_handle(void *hif_handle, void *handle);
+
+int hif_sync_read(void *device, u32 address, u8 *buffer,
+		  u32 length, u32 request, void *context);
+
+size_t hif_get_device_size(void);
+
+/* This API is used to provide the read/write interface over the specific bus
+ * interface.
+ * address - Starting address in the AR6000's address space. For mailbox
+ * writes, it refers to the start of the mbox boundary. It should
+ * be ensured that the last byte falls on the mailbox's EOM. For
+ * mailbox reads, it refers to the end of the mbox boundary.
+ * buffer - Pointer to the buffer containg the data to be transmitted or
+ * received.
+ * length - Amount of data to be transmitted or received.
+ * request - Characterizes the attributes of the command.
+ */
+int hif_read_write(void *device, u32 address, void *buffer,
+		   u32 length, u32 request, void *context);
+
+/* This can be initiated from the unload driver context when the OS has no more
+ * use for
+ * the device.
+ */
+void hif_shutdown_device(void *device);
+void hif_surprise_removed(void *device);
+
+void hif_mask_interrupt(void *device);
+
+void hif_un_mask_interrupt(void *device);
+
+int hif_configure_device(void *device,
+			 enum hif_device_config_opcode opcode,
+			 void *config, u32 config_len);
+
+/* This API wait for the remaining MBOX messages to be drained
+ * This should be moved to HTCA AR6K layer
+ */
+int hif_wait_for_pending_recv(void *device);
+
+/* BMI and Diag window abstraction
+ */
+
+#define HIF_BMI_EXCHANGE_NO_TIMEOUT ((u32)(0))
+
+#define DIAG_TRANSFER_LIMIT 2048U /* maximum number of bytes that can be handled
+				   * atomically by DiagRead/DiagWrite
+				   */
+
+#ifdef FEATURE_RUNTIME_PM
+/* Runtime power management API of HIF to control
+ * runtime pm. During Runtime Suspend the get API
+ * return -EAGAIN. The caller can queue the cmd or return.
+ * The put API decrements the usage count.
+ * The get API increments the usage count.
+ * The API's are exposed to HTT and WMI Services only.
+ */
+int hif_pm_runtime_get(void *device);
+int hif_pm_runtime_put(void *device);
+void *hif_runtime_pm_prevent_suspend_init(const char *name);
+void hif_runtime_pm_prevent_suspend_deinit(void *data);
+int hif_pm_runtime_prevent_suspend(void *ol_sc, void *data);
+int hif_pm_runtime_allow_suspend(void *ol_sc, void *data);
+int hif_pm_runtime_prevent_suspend_timeout(void *ol_sc, void *data,
+					   unsigned int delay);
+void hif_request_runtime_pm_resume(void *ol_sc);
+#else
+static inline int hif_pm_runtime_get(void *device)
+{
+	return 0;
+}
+
+static inline int hif_pm_runtime_put(void *device)
+{
+	return 0;
+}
+
+static inline int hif_pm_runtime_prevent_suspend(void *ol_sc, void *context)
+{
+	return 0;
+}
+
+static inline int hif_pm_runtime_allow_suspend(void *ol_sc, void *context)
+{
+	return 0;
+}
+
+static inline int hif_pm_runtime_prevent_suspend_timeout(void *ol_sc,
+							 void *context,
+							 unsigned int msec)
+{
+	return 0;
+}
+
+static inline void *hif_runtime_pm_prevent_suspend_init(const char *name)
+{
+	return NULL;
+}
+
+static inline void hif_runtime_pm_prevent_suspend_deinit(void *context)
+{
+}
+
+static inline void hif_request_runtime_pm_resume(void *ol_sc)
+{
+}
+#endif
+
+#endif /* _HIF_H_ */
diff --git a/drivers/net/wireless/qca402x/hif_sdio/hif_internal.h b/drivers/net/wireless/qca402x/hif_sdio/hif_internal.h
new file mode 100644
index 0000000..8b4c11e
--- /dev/null
+++ b/drivers/net/wireless/qca402x/hif_sdio/hif_internal.h
@@ -0,0 +1,117 @@
+/* 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.
+ */
+
+/* This file was originally distributed by Qualcomm Atheros, Inc.
+ * before Copyright ownership was assigned to the Linux Foundation.
+ */
+
+#ifndef _HIF_INTERNAL_H_
+#define _HIF_INTERNAL_H_
+
+#include "hif.h"
+#include "hif_sdio_common.h"
+
+/* Make this large enough to avoid ever failing due to lack of bus requests.
+ * A number that accounts for the total number of credits on the Target plus
+ * outstanding register requests is good.
+ *
+ * FUTURE: could dyanamically allocate busrequest structs as needed.
+ * FUTURE: would be nice for HIF to use HTCA's htca_request. Seems
+ * wasteful to use multiple structures -- one for HTCA and another
+ * for HIF -- and to copy info from one to the other. Maybe should
+ * semi-merge these layers?
+ */
+#define BUS_REQUEST_MAX_NUM 128
+
+#define SDIO_CLOCK_FREQUENCY_DEFAULT 25000000 /* TBD: Can support 50000000
+					       * on real HW?
+					       */
+#define SDWLAN_ENABLE_DISABLE_TIMEOUT 20
+#define FLAGS_CARD_ENAB 0x02
+#define FLAGS_CARD_IRQ_UNMSK 0x04
+
+/* The block size is an attribute of the SDIO function which is
+ * shared by all four mailboxes. We cannot support per-mailbox
+ * block sizes over SDIO.
+ */
+#define HIF_MBOX_BLOCK_SIZE HIF_DEFAULT_IO_BLOCK_SIZE
+#define HIF_MBOX0_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE
+#define HIF_MBOX1_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE
+#define HIF_MBOX2_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE
+#define HIF_MBOX3_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE
+
+struct bus_request {
+	/*struct bus_request*/ void *next; /* link list of available requests */
+	struct completion comp_req;
+	u32 address; /* request data */
+	u8 *buffer;
+	u32 length;
+	u32 req_type;
+	void *context;
+	int status;
+};
+
+struct hif_device {
+	struct sdio_func *func;
+
+	/* Main HIF task */
+	struct task_struct *hif_task; /* task to handle SDIO requests */
+	wait_queue_head_t hif_wait;
+	int hif_task_work;	    /* Signals HIFtask that there is work */
+	int hif_shutdown;	    /* signals HIFtask to stop */
+	struct completion hif_exit; /* HIFtask completion */
+
+	/* HIF Completion task */
+	/* task to handle SDIO completions */
+	struct task_struct *completion_task;
+	wait_queue_head_t completion_wait;
+	int completion_work;
+	int completion_shutdown;
+	struct completion completion_exit;
+
+	/* pending request queue */
+	spinlock_t req_qlock;
+	struct bus_request *req_qhead; /* head of request queue */
+	struct bus_request *req_qtail; /* tail of request queue */
+
+	/* completed request queue */
+	spinlock_t compl_qlock;
+	struct bus_request *compl_qhead;
+	struct bus_request *compl_qtail;
+
+	/* request free list */
+	spinlock_t req_free_qlock;
+	struct bus_request *bus_req_free_qhead; /* free queue */
+
+	/* Space for requests, initially queued to busRequestFreeQueue */
+	struct bus_request bus_request[BUS_REQUEST_MAX_NUM];
+
+	void *claimed_context;
+	struct cbs_from_hif
+	    cbs_from_hif; /* Callbacks made from HIF to caller */
+	bool is_enabled;  /* device is currently enabled? */
+	bool is_intr_enb; /* interrupts are currently unmasked at
+			   * Host - dbg only
+			   */
+	int irq_handling; /* currently processing interrupts */
+	const struct sdio_device_id *id;
+	struct mmc_host *host;
+	void *context;
+	bool ctrl_response_timeout;
+	/* for debug; links hif device back to caller (e.g.HTCA target) */
+	void *caller_handle;
+};
+
+#define CMD53_FIXED_ADDRESS 1
+#define CMD53_INCR_ADDRESS 2
+
+#endif /* _HIF_INTERNAL_H_ */
diff --git a/drivers/net/wireless/qca402x/hif_sdio/hif_sdio_common.h b/drivers/net/wireless/qca402x/hif_sdio/hif_sdio_common.h
new file mode 100644
index 0000000..c325c06
--- /dev/null
+++ b/drivers/net/wireless/qca402x/hif_sdio/hif_sdio_common.h
@@ -0,0 +1,43 @@
+/* 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.
+ */
+
+/* This file was originally distributed by Qualcomm Atheros, Inc.
+ * before Copyright ownership was assigned to the Linux Foundation.
+ */
+
+#ifndef _HIF_SDIO_COMMON_H_
+#define _HIF_SDIO_COMMON_H_
+
+/* The purpose of these blocks is to amortize SDIO command setup time
+ * across multiple bytes of data. In byte mode, we must issue a command
+ * for each byte. In block mode, we issue a command (8B?) for each
+ * BLOCK_SIZE bytes.
+ *
+ * Every mailbox read/write must be padded to this block size. If the
+ * value is too large, we spend more time sending padding bytes over
+ * SDIO. If the value is too small we see less benefit from amortizing
+ * the cost of a command across data bytes.
+ */
+#define HIF_DEFAULT_IO_BLOCK_SIZE 256
+
+#define FIFO_TIMEOUT_AND_CHIP_CONTROL 0x00000868
+#define FIFO_TIMEOUT_AND_CHIP_CONTROL_DISABLE_SLEEP_OFF 0xFFFEFFFF
+#define FIFO_TIMEOUT_AND_CHIP_CONTROL_DISABLE_SLEEP_ON 0x10000
+
+/* Vendor Specific Driver Strength Settings */
+#define CCCR_SDIO_DRIVER_STRENGTH_ENABLE_ADDR 0xf2
+#define CCCR_SDIO_DRIVER_STRENGTH_ENABLE_MASK 0x0e
+#define CCCR_SDIO_DRIVER_STRENGTH_ENABLE_A 0x02
+#define CCCR_SDIO_DRIVER_STRENGTH_ENABLE_C 0x04
+#define CCCR_SDIO_DRIVER_STRENGTH_ENABLE_D 0x08
+
+#endif /* _HIF_SDIO_COMMON_H_ */
diff --git a/drivers/net/wireless/qca402x/htca_mbox/htca.h b/drivers/net/wireless/qca402x/htca_mbox/htca.h
new file mode 100644
index 0000000..ce2e0eb
--- /dev/null
+++ b/drivers/net/wireless/qca402x/htca_mbox/htca.h
@@ -0,0 +1,132 @@
+/* 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.
+ */
+
+/* Host-Target Communication API */
+
+#ifndef _HTCA_H_
+#define _HTCA_H_
+
+#define DEBUG
+#undef DEBUG
+
+/* The HTCA API is independent of the underlying interconnect and
+ * independent of the protocols used across that interconnect.
+ */
+
+#define HTCA_OK 0        /* Success */
+#define HTCA_ERROR 1     /* generic error */
+#define HTCA_EINVAL 2    /* Invalid parameter */
+#define HTCA_ECANCELED 3 /* Operation canceled */
+#define HTCA_EPROTO 4    /* Protocol error */
+#define HTCA_ENOMEM 5    /* Memory exhausted */
+
+/* Note: An Endpoint ID is always Interconnect-relative. So we
+ * are likely to see the same Endpoint ID with different Targets
+ * on a multi-Target system.
+ */
+#define HTCA_EP_UNUSED (0xff)
+
+#define HTCA_EVENT_UNUSED 0
+
+/* Start global events */
+#define HTCA_EVENT_GLOBAL_START 1
+#define HTCA_EVENT_TARGET_AVAILABLE 1
+#define HTCA_EVENT_TARGET_UNAVAILABLE 2
+#define HTCA_EVENT_GLOBAL_END 2
+#define HTCA_EVENT_GLOBAL_COUNT                                                \
+		(HTCA_EVENT_GLOBAL_END - HTCA_EVENT_GLOBAL_START + 1)
+/* End global events */
+
+/* Start endpoint-specific events */
+#define HTCA_EVENT_EP_START 3
+#define HTCA_EVENT_BUFFER_RECEIVED 3
+#define HTCA_EVENT_BUFFER_SENT 4
+#define HTCA_EVENT_DATA_AVAILABLE 5
+#define HTCA_EVENT_EP_END 5
+#define HTCA_EVENT_EP_COUNT (HTCA_EVENT_EP_END - HTCA_EVENT_EP_START + 1)
+/* End endpoint-specific events */
+
+/* Maximum size of an HTC header across relevant implementations
+ * (e.g. across interconnect types and platforms and OSes of interest).
+ *
+ * Callers of HTC must leave HTCA_HEADER_LEN_MAX bytes
+ * reserved BEFORE the start of a buffer passed to HTCA htca_buffer_send
+ * AT the start of a buffer passed to HTCBufferReceive
+ * for use by HTC itself.
+ *
+ * FUTURE: Investigate ways to remove the need for callers to accommodate
+ * for HTC headers.* Doesn't seem that hard to do....just tack on the
+ * length in a separate buffer and send buffer pairs to HIF. When extracting,
+ * first pull header then pull payload into paired buffers.
+ */
+
+#define HTCA_HEADER_LEN_MAX 2
+
+struct htca_event_info {
+	u8 *buffer;
+	void *cookie;
+	u32 buffer_length;
+	u32 actual_length;
+	int status;
+};
+
+typedef void (*htca_event_handler)(void *target,
+				   u8 ep,
+				   u8 event_id,
+				   struct htca_event_info *event_info,
+				   void *context);
+
+int htca_init(void);
+
+void htca_shutdown(void);
+
+int htca_start(void *target);
+
+void htca_stop(void *target);
+
+int htca_event_reg(void *target,
+		   u8 end_point_id,
+		   u8 event_id,
+		   htca_event_handler event_handler, void *context);
+
+/* Notes:
+ * buffer should be multiple of blocksize.
+ * buffer should be large enough for header+largest message, rounded up to
+ * blocksize.
+ * buffer passed in should be start of the buffer -- where header will go.
+ * length should be full length, including header.
+ * On completion, buffer points to start of payload (AFTER header).
+ * On completion, actual_length is the length of payload. Does not include
+ * header nor padding. On completion, buffer_length matches the length that
+ * was passed in here.
+ */
+int htca_buffer_receive(void *target,
+			u8 end_point_id, u8 *buffer,
+			u32 length, void *cookie);
+
+/* Notes:
+ * buffer should be multiple of blocksize.
+ * buffer passed in should be start of payload; header will be tacked on BEFORE
+ * this.
+ * extra bytes will be sent, padding the message to blocksize.
+ * length should be the number of payload bytes to be sent.
+ * The actual number of bytes that go over SDIO is length+header, rounded up to
+ * blocksize.
+ * On completion, buffer points to start of payload (AFTER header).
+ * On completion, actual_length is the length of payload. Does not include
+ * header nor padding. On completion buffer_length is irrelevant.
+ */
+int htca_buffer_send(void *target,
+		     u8 end_point_id,
+		     u8 *buffer, u32 length, void *cookie);
+
+#endif /* _HTCA_H_ */
diff --git a/drivers/net/wireless/qca402x/htca_mbox/htca_mbox.c b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox.c
new file mode 100644
index 0000000..fbf3549
--- /dev/null
+++ b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox.c
@@ -0,0 +1,497 @@
+/* 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.
+ */
+
+/* Implementation of Host Target Communication
+ * API v1 and HTCA Protocol v1
+ * over Qualcomm QCA mailbox-based SDIO/SPI interconnects.
+ */
+
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "../hif_sdio/hif.h"
+#include "htca.h"
+#include "htca_mbox_internal.h"
+
+struct htca_target *htca_target_list[HTCA_NUM_DEVICES_MAX];
+
+/* Single thread module initialization, module shutdown,
+ * target start and target stop.
+ */
+static DEFINE_MUTEX(htca_startup_mutex);
+static bool htca_initialized;
+
+/* Initialize the HTCA software module.
+ * Typically invoked exactly once.
+ */
+int htca_init(void)
+{
+	struct cbs_from_os callbacks;
+
+	if (mutex_lock_interruptible(&htca_startup_mutex))
+		return HTCA_ERROR; /* interrupted */
+
+	if (htca_initialized) {
+		mutex_unlock(&htca_startup_mutex);
+		return HTCA_OK; /* Already initialized */
+	}
+
+	htca_initialized = true;
+
+	htca_event_table_init();
+
+	memset(&callbacks, 0, sizeof(callbacks));
+	callbacks.dev_inserted_hdl = htca_target_inserted_handler;
+	callbacks.dev_removed_hdl = htca_target_removed_handler;
+	hif_init(&callbacks);
+
+	mutex_unlock(&htca_startup_mutex);
+
+	return HTCA_OK;
+}
+
+/* Shutdown the entire module and free all module data.
+ * Inverse of htca_init.
+ *
+ * May be invoked only after all Targets are stopped.
+ */
+void htca_shutdown(void)
+{
+	int i;
+
+	if (mutex_lock_interruptible(&htca_startup_mutex))
+		return; /* interrupted */
+
+	if (!htca_initialized) {
+		mutex_unlock(&htca_startup_mutex);
+		return; /* Not initialized, so nothing to shut down */
+	}
+
+	for (i = 0; i < HTCA_NUM_DEVICES_MAX; i++) {
+		if (htca_target_instance(i)) {
+			/* One or more Targets are still active --
+			 * cannot shutdown software.
+			 */
+			mutex_unlock(&htca_startup_mutex);
+			WARN_ON(1);
+			return;
+		}
+	}
+
+	hif_shutdown_device(NULL); /* Tell HIF that we're all done */
+	htca_initialized = false;
+
+	mutex_unlock(&htca_startup_mutex);
+}
+
+/* Start a Target. This typically happens once per Target after
+ * the module has been initialized and a Target is powered on.
+ *
+ * When a Target starts, it posts a single credit to each mailbox
+ * and it enters "HTCA configuration". During configuration
+ * negotiation, block sizes for each HTCA endpoint are established
+ * that both Host and Target agree. Once this is complete, the
+ * Target starts normal operation so it can send/receive.
+ */
+int htca_start(void *tar)
+{
+	int status;
+	u32 address;
+	struct htca_target *target = (struct htca_target *)tar;
+
+	mutex_lock(&htca_startup_mutex);
+
+	if (!htca_initialized) {
+		mutex_unlock(&htca_startup_mutex);
+		return HTCA_ERROR;
+	}
+
+	init_waitqueue_head(&target->target_init_wait);
+
+	/* Unmask Host controller interrupts associated with this Target */
+	hif_un_mask_interrupt(target->hif_handle);
+
+	/* Enable all interrupts of interest on the Target. */
+
+	target->enb.int_status_enb = INT_STATUS_ENABLE_ERROR_SET(0x01) |
+				     INT_STATUS_ENABLE_CPU_SET(0x01) |
+				     INT_STATUS_ENABLE_COUNTER_SET(0x01) |
+				     INT_STATUS_ENABLE_MBOX_DATA_SET(0x0F);
+
+	target->enb.cpu_int_status_enb = CPU_INT_STATUS_ENABLE_BIT_SET(0x00);
+
+	target->enb.err_status_enb =
+	    ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(0x01) |
+	    ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(0x01);
+
+	target->enb.counter_int_status_enb =
+	    COUNTER_INT_STATUS_ENABLE_BIT_SET(0xFF);
+
+	/* Commit interrupt register values to Target HW. */
+	address = get_reg_addr(INTR_ENB_REG, ENDPOINT_UNUSED);
+	status =
+	    hif_read_write(target->hif_handle, address, &target->enb,
+			   sizeof(target->enb), HIF_WR_SYNC_BYTE_INC, NULL);
+	if (status != HIF_OK) {
+		_htca_stop(target);
+		mutex_unlock(&htca_startup_mutex);
+		return HTCA_ERROR;
+	}
+
+	/* At this point, we're waiting for the Target to post
+	 * 1 credit to each mailbox. This allows us to begin
+	 * configuration negotiation. We should see an interrupt
+	 * as soon as the first credit is posted. The remaining
+	 * credits should be posted almost immediately after.
+	 */
+
+	/* Wait indefinitely until configuration negotiation with
+	 * the Target completes and the Target tells us it is ready to go.
+	 */
+	if (!target->ready) {
+		/* NB: Retain the htca_statup_mutex during this wait.
+		 * This serializes startup but should be OK.
+		 */
+
+		wait_event_interruptible(target->target_init_wait,
+					 target->ready);
+
+		if (target->ready) {
+			status = HTCA_OK;
+		} else {
+			status = HTCA_ERROR;
+			_htca_stop(target);
+		}
+	}
+
+	mutex_unlock(&htca_startup_mutex);
+	return status;
+}
+
+void _htca_stop(struct htca_target *target)
+{
+	uint ep;
+	struct htca_endpoint *end_point;
+	u32 address;
+
+	/* Note: htca_startup_mutex must be held on entry */
+	if (!htca_initialized)
+		return;
+
+	htca_work_task_stop(target);
+
+	/* Disable interrupts at source, on Target */
+	target->enb.int_status_enb = 0;
+	target->enb.cpu_int_status_enb = 0;
+	target->enb.err_status_enb = 0;
+	target->enb.counter_int_status_enb = 0;
+
+	address = get_reg_addr(INTR_ENB_REG, ENDPOINT_UNUSED);
+
+	/* Try to disable all interrupts on the Target. */
+	(void)hif_read_write(target->hif_handle, address, &target->enb,
+			     sizeof(target->enb), HIF_WR_SYNC_BYTE_INC, NULL);
+
+	/* Disable Host controller interrupts */
+	hif_mask_interrupt(target->hif_handle);
+
+	/* Flush all the queues and return the buffers to their owner */
+	for (ep = 0; ep < HTCA_NUM_MBOX; ep++) {
+		unsigned long flags;
+
+		end_point = &target->end_point[ep];
+
+		spin_lock_irqsave(&end_point->tx_credit_lock, flags);
+		end_point->tx_credits_available = 0;
+		spin_unlock_irqrestore(&end_point->tx_credit_lock, flags);
+
+		end_point->enabled = false;
+
+		/* Flush the Pending Receive Queue */
+		htca_mbox_queue_flush(end_point, &end_point->recv_pending_queue,
+				      &end_point->recv_free_queue,
+				      HTCA_EVENT_BUFFER_RECEIVED);
+
+		/* Flush the Pending Send Queue */
+		htca_mbox_queue_flush(end_point, &end_point->send_pending_queue,
+				      &end_point->send_free_queue,
+				      HTCA_EVENT_BUFFER_SENT);
+	}
+
+	target->ready = false;
+
+	hif_detach(target->hif_handle);
+
+	/* Remove this Target from the global list */
+	htca_target_instance_remove(target);
+
+	/* Free target memory */
+	kfree(target);
+}
+
+void htca_stop(void *tar)
+{
+	struct htca_target *target = (struct htca_target *)tar;
+
+	htca_work_task_stop(target);
+	htca_compl_task_stop(target);
+
+	mutex_lock(&htca_startup_mutex);
+	_htca_stop(target);
+	mutex_unlock(&htca_startup_mutex);
+}
+
+/* Provides an interface for the caller to register for
+ * various events supported by the HTCA module.
+ */
+int htca_event_reg(void *tar,
+		   u8 end_point_id,
+		   u8 event_id,
+		   htca_event_handler event_handler, void *param)
+{
+	int status;
+	struct htca_endpoint *end_point;
+	struct htca_event_info event_info;
+	struct htca_target *target = (struct htca_target *)tar;
+
+	/* Register a new handler BEFORE dispatching events.
+	 * UNregister a handler AFTER dispatching events.
+	 */
+	if (event_handler) {
+		/* Register a new event handler */
+
+		status = htca_add_to_event_table(target, end_point_id, event_id,
+						 event_handler, param);
+		if (status != HTCA_OK)
+			return status; /* Fail to register handler */
+	}
+
+	/* Handle events associated with this handler */
+	switch (event_id) {
+	case HTCA_EVENT_TARGET_AVAILABLE:
+		if (event_handler) {
+			struct htca_target *targ;
+			int i;
+
+			/* Dispatch a Target Available event for all Targets
+			 * that are already present.
+			 */
+			for (i = 0; i < HTCA_NUM_DEVICES_MAX; i++) {
+				targ = htca_target_list[i];
+				if (targ) {
+					size_t size = hif_get_device_size();
+
+					htca_frame_event(&event_info,
+							 (u8 *)targ->hif_handle,
+							 size, size,
+							 HTCA_OK, NULL);
+
+					htca_dispatch_event(
+					    targ, ENDPOINT_UNUSED,
+					    HTCA_EVENT_TARGET_AVAILABLE,
+					    &event_info);
+				}
+			}
+		}
+		break;
+
+	case HTCA_EVENT_TARGET_UNAVAILABLE:
+		break;
+
+	case HTCA_EVENT_BUFFER_RECEIVED:
+		if (!event_handler) {
+			/* Flush the Pending Recv queue before unregistering
+			 * the event handler.
+			 */
+			end_point = &target->end_point[end_point_id];
+			htca_mbox_queue_flush(end_point,
+					      &end_point->recv_pending_queue,
+					      &end_point->recv_free_queue,
+					      HTCA_EVENT_BUFFER_RECEIVED);
+		}
+		break;
+
+	case HTCA_EVENT_BUFFER_SENT:
+		if (!event_handler) {
+			/* Flush the Pending Send queue before unregistering
+			 * the event handler.
+			 */
+			end_point = &target->end_point[end_point_id];
+			htca_mbox_queue_flush(end_point,
+					      &end_point->send_pending_queue,
+					      &end_point->send_free_queue,
+					      HTCA_EVENT_BUFFER_SENT);
+		}
+		break;
+
+	case HTCA_EVENT_DATA_AVAILABLE:
+		/* We could dispatch a data available event. Instead,
+		 * we require users to register this event handler
+		 * before posting receive buffers.
+		 */
+		break;
+
+	default:
+		return HTCA_EINVAL; /* unknown event? */
+	}
+
+	if (!event_handler) {
+		/* Unregister an event handler */
+		status = htca_remove_from_event_table(target,
+						      end_point_id, event_id);
+		if (status != HTCA_OK)
+			return status;
+	}
+
+	return HTCA_OK;
+}
+
+/* Enqueue to the endpoint's recv_pending_queue an empty buffer
+ * which will receive data from the Target.
+ */
+int htca_buffer_receive(void *tar,
+			u8 end_point_id, u8 *buffer,
+			u32 length, void *cookie)
+{
+	struct htca_endpoint *end_point;
+	struct htca_mbox_request *mbox_request;
+	struct htca_event_table_element *ev;
+	unsigned long flags;
+	struct htca_target *target = (struct htca_target *)tar;
+
+	end_point = &target->end_point[end_point_id];
+
+	if (!end_point->enabled)
+		return HTCA_ERROR;
+
+	/* Length must be a multiple of block_size.
+	 * (Ideally, length should match the largest message that can be sent
+	 * over this endpoint, including HTCA header, rounded up to blocksize.)
+	 */
+	if (length % end_point->block_size)
+		return HTCA_EINVAL;
+
+	if (length > HTCA_MESSAGE_SIZE_MAX)
+		return HTCA_EINVAL;
+
+	if (length < HTCA_HEADER_LEN_MAX)
+		return HTCA_EINVAL;
+
+	ev = htca_event_id_to_event(target, end_point_id,
+				    HTCA_EVENT_BUFFER_RECEIVED);
+	if (!ev->handler) {
+		/* In order to use this API, caller must
+		 * register an event handler for HTCA_EVENT_BUFFER_RECEIVED.
+		 */
+		return HTCA_ERROR;
+	}
+
+	spin_lock_irqsave(&end_point->mbox_queue_lock, flags);
+	mbox_request = (struct htca_mbox_request *)htca_request_deq_head(
+	    &end_point->recv_free_queue);
+	spin_unlock_irqrestore(&end_point->mbox_queue_lock, flags);
+	if (!mbox_request)
+		return HTCA_ENOMEM;
+
+	if (WARN_ON(mbox_request->req.target != target))
+		return HTCA_ERROR;
+
+	mbox_request->buffer = buffer;
+	/* includes space for HTCA header */
+	mbox_request->buffer_length = length;
+	/* filled in after message is received */
+	mbox_request->actual_length = 0;
+	mbox_request->end_point = end_point;
+	mbox_request->cookie = cookie;
+
+	spin_lock_irqsave(&end_point->mbox_queue_lock, flags);
+	htca_request_enq_tail(&end_point->recv_pending_queue,
+			      (struct htca_request *)mbox_request);
+	spin_unlock_irqrestore(&end_point->mbox_queue_lock, flags);
+
+	/* Alert the work_task that there may be work to do */
+	htca_work_task_poke(target);
+
+	return HTCA_OK;
+}
+
+/* Enqueue a buffer to be sent to the Target.
+ *
+ * Supplied buffer must be preceded by HTCA_HEADER_LEN_MAX bytes for the
+ * HTCA header (of which HTCA_HEADER_LEN bytes are actually used, and the
+ * remaining are padding).
+ *
+ * Must be followed with sufficient space for block-size padding.
+ *
+ * Example:
+ * To send a 10B message over an endpoint that uses 64B blocks, caller
+ * specifies length=10. HTCA adds HTCA_HEADER_LEN_MAX bytes just before
+ * buffer, consisting of HTCA_HEADER_LEN header bytes followed by
+ * HTCA_HEADER_LEN_MAX-HTCA_HEADER_LEN pad bytes. HTC sends blockSize
+ * bytes starting at buffer-HTCA_HEADER_LEN_MAX.
+ */
+int htca_buffer_send(void *tar,
+		     u8 end_point_id,
+		     u8 *buffer, u32 length, void *cookie)
+{
+	struct htca_endpoint *end_point;
+	struct htca_mbox_request *mbox_request;
+	struct htca_event_table_element *ev;
+	unsigned long flags;
+	struct htca_target *target = (struct htca_target *)tar;
+
+	end_point = &target->end_point[end_point_id];
+
+	if (!end_point->enabled)
+		return HTCA_ERROR;
+
+	if (length + HTCA_HEADER_LEN_MAX > HTCA_MESSAGE_SIZE_MAX)
+		return HTCA_EINVAL;
+
+	ev = htca_event_id_to_event(target, end_point_id,
+				    HTCA_EVENT_BUFFER_SENT);
+	if (!ev->handler) {
+		/* In order to use this API, caller must
+		 * register an event handler for HTCA_EVENT_BUFFER_SENT.
+		 */
+		return HTCA_ERROR;
+	}
+
+	spin_lock_irqsave(&end_point->mbox_queue_lock, flags);
+	mbox_request = (struct htca_mbox_request *)htca_request_deq_head(
+	    &end_point->send_free_queue);
+	spin_unlock_irqrestore(&end_point->mbox_queue_lock, flags);
+	if (!mbox_request)
+		return HTCA_ENOMEM;
+
+	/* Buffer will be adjusted by HTCA_HEADER_LEN later, in
+	 * htca_send_request_to_hif.
+	 */
+	mbox_request->buffer = buffer;
+	mbox_request->buffer_length = length;
+	mbox_request->actual_length = length;
+	mbox_request->end_point = end_point;
+	mbox_request->cookie = cookie;
+
+	spin_lock_irqsave(&end_point->mbox_queue_lock, flags);
+	htca_request_enq_tail(&end_point->send_pending_queue,
+			      (struct htca_request *)mbox_request);
+	spin_unlock_irqrestore(&end_point->mbox_queue_lock, flags);
+
+	/* Alert the work_task that there may be work to do */
+	htca_work_task_poke(target);
+
+	return HTCA_OK;
+}
diff --git a/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_compl.c b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_compl.c
new file mode 100644
index 0000000..c7f8e953
--- /dev/null
+++ b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_compl.c
@@ -0,0 +1,503 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/completion.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/spinlock_types.h>
+#include <linux/wait.h>
+
+#include "../hif_sdio/hif.h"
+#include "htca.h"
+#include "htca_mbox_internal.h"
+
+/* Host Target Communications Completion Management */
+
+/* Top-level callback handler, registered with HIF to be invoked
+ * whenever a read/write HIF operation completes. Executed in the
+ * context of an HIF task, so we don't want to take much time
+ * here. Pass processing to HTCA's compl_task.
+ *
+ * Used for both reg_requests and mbox_requests.
+ */
+int htca_rw_completion_handler(void *context, int status)
+{
+	struct htca_request *req;
+	struct htca_target *target;
+	unsigned long flags;
+
+	req = (struct htca_request *)context;
+	if (!context) {
+		/* No completion required for this request.
+		 * (e.g. Fire-and-forget register write.)
+		 */
+		return HTCA_OK;
+	}
+
+	target = req->target;
+	req->status = status;
+
+	/* Enqueue this completed request on the
+	 * Target completion queue.
+	 */
+	spin_lock_irqsave(&target->compl_queue_lock, flags);
+	htca_request_enq_tail(&target->compl_queue, (struct htca_request *)req);
+	spin_unlock_irqrestore(&target->compl_queue_lock, flags);
+
+	/* Notify the completion task that it has work */
+	htca_compl_task_poke(target);
+
+	return HTCA_OK;
+}
+
+/* Request-specific callback invoked by the HTCA Completion Task
+ * when a Mbox Send Request completes. Note: Used for Mbox Send
+ * requests; not used for Reg requests.
+ *
+ * Simply dispatch a BUFFER_SENT event to the originator of the request.
+ */
+void htca_send_compl(struct htca_request *req, int status)
+{
+	struct htca_target *target;
+	u8 end_point_id;
+	struct htca_event_info event_info;
+	struct htca_endpoint *end_point;
+	struct htca_mbox_request *mbox_request =
+			(struct htca_mbox_request *)req;
+	unsigned long flags;
+
+	end_point = mbox_request->end_point;
+	target = end_point->target;
+	end_point_id = get_endpoint_id(end_point);
+
+	/* Strip off the HTCA header that was added earlier */
+	mbox_request->buffer += HTCA_HEADER_LEN_MAX;
+
+	/* Prepare event frame to notify caller */
+	htca_frame_event(&event_info, mbox_request->buffer,
+			 mbox_request->buffer_length,
+			 mbox_request->actual_length,
+			 (status == HIF_OK) ? HTCA_OK : HTCA_ECANCELED,
+			 mbox_request->cookie);
+
+	/* Recycle the request */
+	spin_lock_irqsave(&end_point->mbox_queue_lock, flags);
+	htca_request_enq_tail(&end_point->send_free_queue,
+			      (struct htca_request *)mbox_request);
+	spin_unlock_irqrestore(&end_point->mbox_queue_lock, flags);
+	/* Regardless of success/failure, notify caller that HTCA is done
+	 * with his buffer.
+	 */
+	htca_dispatch_event(target, end_point_id, HTCA_EVENT_BUFFER_SENT,
+			    &event_info);
+}
+
+/* Request-specific callback invoked by the HTCA Completion Task
+ * when a Mbox Recv Request completes. Note: Used for Mbox Recv
+ * requests; not used for Reg requests.
+ *
+ * Simply dispatch a BUFFER_RECEIVED event to the originator
+ * of the request.
+ */
+void htca_recv_compl(struct htca_request *req, int status)
+{
+	struct htca_target *target;
+	struct htca_event_info event_info;
+	u8 end_point_id;
+	struct htca_endpoint *end_point;
+	struct htca_mbox_request *mbox_request =
+	    (struct htca_mbox_request *)req;
+	unsigned long flags;
+
+	end_point = mbox_request->end_point;
+	target = end_point->target;
+	end_point_id = get_endpoint_id(end_point);
+
+	/* Signaling:
+	 * Now that we have consumed recv data, clar rx_frame_length so that
+	 * htca_manage_pending_recvs will not try to re-read the same data.
+	 *
+	 * Set need_register_refresh so we can determine whether or not there
+	 * is additional data waiting to be read.
+	 *
+	 * Clear our endpoint from the pending_recv_mask so
+	 * htca_manage_pending_recvs
+	 * is free to issue another read.
+	 *
+	 * Finally, poke the work_task.
+	 */
+	end_point->rx_frame_length = 0;
+	target->need_register_refresh = 1;
+	spin_lock_irqsave(&target->pending_op_lock, flags);
+	target->pending_recv_mask &= ~(1 << end_point_id);
+	spin_unlock_irqrestore(&target->pending_op_lock, flags);
+	htca_work_task_poke(target);
+
+	if (status == HIF_OK) {
+		u32 check_length;
+		/* Length coming from Target is always LittleEndian */
+		check_length = ((mbox_request->buffer[0] << 0) |
+				(mbox_request->buffer[1] << 8));
+		WARN_ON(mbox_request->actual_length != check_length);
+	}
+
+	/* Strip off header */
+	mbox_request->buffer += HTCA_HEADER_LEN_MAX;
+
+	htca_frame_event(&event_info, mbox_request->buffer,
+			 mbox_request->buffer_length,
+			 mbox_request->actual_length,
+			 (status == HIF_OK) ? HTCA_OK : HTCA_ECANCELED,
+			 mbox_request->cookie);
+
+	/* Recycle the request */
+	spin_lock_irqsave(&end_point->mbox_queue_lock, flags);
+	htca_request_enq_tail(&end_point->recv_free_queue,
+			      (struct htca_request *)mbox_request);
+	spin_unlock_irqrestore(&end_point->mbox_queue_lock, flags);
+
+	htca_dispatch_event(target, end_point_id, HTCA_EVENT_BUFFER_RECEIVED,
+			    &event_info);
+}
+
+/* Request-specific callback invoked when a register read/write
+ * request completes. reg_request structures are not used for
+ * register WRITE requests so there's not much to do for writes.
+ *
+ * Note: For Mbox Request completions see htca_send_compl
+ * and htca_recv_compl.
+ */
+
+/* Request-specific callback invoked by the HTCA Completion Task
+ * when a Reg Request completes. Note: Used for Reg requests;
+ * not used for Mbox requests.
+ */
+void htca_reg_compl(struct htca_request *req, int status)
+{
+	struct htca_target *target;
+	struct htca_reg_request *reg_request = (struct htca_reg_request *)req;
+	unsigned long flags;
+
+	if (WARN_ON(!reg_request))
+		return;
+
+	htcadebug("purpose=0x%x\n", reg_request->purpose);
+
+	/* Process async register read/write completion */
+
+	target = reg_request->req.target;
+	if (status != HIF_OK) {
+		/* Recycle the request */
+		reg_request->purpose = UNUSED_PURPOSE;
+		spin_lock_irqsave(&target->reg_queue_lock, flags);
+		htca_request_enq_tail(&target->reg_free_queue,
+				      (struct htca_request *)reg_request);
+		spin_unlock_irqrestore(&target->reg_queue_lock, flags);
+
+		/* A register read/write accepted by HIF
+		 * should never fail.
+		 */
+		WARN_ON(1);
+		return;
+	}
+
+	switch (reg_request->purpose) {
+	case INTR_REFRESH:
+		/* Target register state, including interrupt
+		 * registers, has been fetched.
+		 */
+		htca_register_refresh_compl(target, reg_request);
+		break;
+
+	case CREDIT_REFRESH:
+		htca_credit_refresh_compl(target, reg_request);
+		break;
+
+	case UPDATE_TARG_INTRS:
+	case UPDATE_TARG_AND_ENABLE_HOST_INTRS:
+		htca_update_intr_enbs_compl(target, reg_request);
+		break;
+
+	default:
+		WARN_ON(1); /* unhandled request type */
+		break;
+	}
+
+	/* Recycle this register read/write request */
+	reg_request->purpose = UNUSED_PURPOSE;
+	spin_lock_irqsave(&target->reg_queue_lock, flags);
+	htca_request_enq_tail(&target->reg_free_queue,
+			      (struct htca_request *)reg_request);
+	spin_unlock_irqrestore(&target->reg_queue_lock, flags);
+}
+
+/* After a Register Refresh, uppdate tx_credits_to_reap for each end_point.  */
+static void htca_update_tx_credits_to_reap(struct htca_target *target,
+					   struct htca_reg_request *reg_request)
+{
+	struct htca_endpoint *end_point;
+	int ep;
+
+	for (ep = 0; ep < HTCA_NUM_MBOX; ep++) {
+		end_point = &target->end_point[ep];
+
+		if (reg_request->u.reg_table.status.counter_int_status &
+		    (0x10 << ep)) {
+			end_point->tx_credits_to_reap = true;
+		} else {
+			end_point->tx_credits_to_reap = false;
+		}
+	}
+}
+
+/* After a Register Refresh, uppdate rx_frame_length for each end_point.  */
+static void htca_update_rx_frame_lengths(struct htca_target *target,
+					 struct htca_reg_request *reg_request)
+{
+	struct htca_endpoint *end_point;
+	u32 rx_lookahead;
+	u32 frame_length;
+	int ep;
+
+	htcadebug("Enter\n");
+	for (ep = 0; ep < HTCA_NUM_MBOX; ep++) {
+		end_point = &target->end_point[ep];
+
+		if (end_point->rx_frame_length != 0) {
+			/* NB: Will be cleared in htca_recv_compl after
+			 * frame is read
+			 */
+			continue;
+		}
+
+		if (!(reg_request->u.reg_table.rx_lookahead_valid &
+		      (1 << ep))) {
+			continue;
+		}
+
+		/* The length of the incoming message is contained
+		 * in the first two (HTCA_HEADER_LEN) bytes in
+		 * LittleEndian order.
+		 *
+		 * This length does NOT include the HTCA header nor block
+		 * padding.
+		 */
+		rx_lookahead = reg_request->u.reg_table.rx_lookahead[ep];
+		frame_length = rx_lookahead & 0x0000ffff;
+
+		end_point->rx_frame_length = frame_length;
+		htcadebug("ep#%d : %d\n", ep,
+			  frame_length);
+	}
+}
+
+static unsigned int htca_debug_no_pending; /* debug only */
+
+/* Completion for a register refresh.
+ *
+ * Update rxFrameLengths and tx_credits_to_reap info for
+ * each endpoint. Then handle all pending interrupts (o
+ * if interrupts are currently masked at the Host, handle
+ * all interrupts that would be pending if interrupts
+ * were enabled).
+ *
+ * Called in the context of HIF's completion task whenever
+ * results from a register refresh are received.
+ */
+void htca_register_refresh_compl(struct htca_target *target,
+				 struct htca_reg_request *req)
+{
+	u8 host_int_status;
+	u8 pnd_enb_intrs; /* pending and enabled interrupts */
+	u8 pending_int;
+	u8 enabled_int;
+	unsigned long flags;
+
+	htcadebug("Enter\n");
+
+	if (WARN_ON(target->pending_register_refresh == 0))
+		return;
+
+	spin_lock_irqsave(&target->pending_op_lock, flags);
+	target->pending_register_refresh--;
+	spin_unlock_irqrestore(&target->pending_op_lock, flags);
+
+	htcadebug(
+	    "REGDUMP: hostis=0x%02x cpuis=0x%02x erris=0x%02x cntris=0x%02x\n",
+	    req->u.reg_table.status.host_int_status,
+	    req->u.reg_table.status.cpu_int_status,
+	    req->u.reg_table.status.err_int_status,
+	    req->u.reg_table.status.counter_int_status);
+	htcadebug(
+	    "mbox_frame=0x%02x lav=0x%02x la0=0x%08x la1=0x%08x la2=0x%08x la3=0x%08x\n",
+	    req->u.reg_table.mbox_frame, req->u.reg_table.rx_lookahead_valid,
+	    req->u.reg_table.rx_lookahead[0], req->u.reg_table.rx_lookahead[1],
+	    req->u.reg_table.rx_lookahead[2], req->u.reg_table.rx_lookahead[3]);
+
+	/* Update rxFrameLengths */
+	htca_update_rx_frame_lengths(target, req);
+
+	/* Update tx_credits_to_reap */
+	htca_update_tx_credits_to_reap(target, req);
+
+	/* Process pending Target interrupts. */
+
+	/* Restrict attention to pending interrupts of interest */
+	host_int_status = req->u.reg_table.status.host_int_status;
+
+	/* Unexpected and unhandled */
+	if (WARN_ON(host_int_status & HOST_INT_STATUS_DRAGON_INT_MASK))
+		return;
+
+	/* Form software's idea of pending and enabled interrupts.
+	 * Start with ERRORs and CPU interrupts.
+	 */
+	pnd_enb_intrs = host_int_status &
+			(HOST_INT_STATUS_ERROR_MASK | HOST_INT_STATUS_CPU_MASK);
+
+	/* Software may have intended to enable/disable credit
+	 * counter interrupts; but we commit these updates to
+	 * Target hardware lazily, just before re-enabling
+	 * interrupts. So registers that we have now may not
+	 * reflect the intended state of interrupt enables.
+	 */
+
+	/* Based on software credit enable bits, update pnd_enb_intrs
+	 * (which is like a software copy of host_int_status) as if
+	 * all desired interrupt enables had been committed to HW.
+	 */
+	pending_int = req->u.reg_table.status.counter_int_status;
+	enabled_int = target->enb.counter_int_status_enb;
+	if (pending_int & enabled_int)
+		pnd_enb_intrs |= HOST_INT_STATUS_COUNTER_MASK;
+
+	/* Based on software recv data enable bits, update
+	 * pnd_enb_intrs AS IF all the interrupt enables had
+	 * been committed to HW.
+	 */
+	pending_int = host_int_status;
+	enabled_int = target->enb.int_status_enb;
+	pnd_enb_intrs |= (pending_int & enabled_int);
+
+	if (!pnd_enb_intrs) {
+		/* No enabled interrupts are pending. */
+		htca_debug_no_pending++;
+	}
+
+	/* Invoke specific handlers for each enabled and pending interrupt.
+	 * The goal of each service routine is to clear interrupts at the
+	 * source (on the Target).
+	 *
+	 * We deal with four types of interrupts in the HOST_INT_STATUS
+	 * summary register:
+	 * errors
+	 * This remains set until bits in ERROR_INT_STATUS are cleared
+	 *
+	 * CPU
+	 * This remains set until bits in CPU_INT_STATUS are cleared
+	 *
+	 * rx data available
+	 * These remain set as long as rx data is available. HW clears
+	 * the rx data available enable bits when receive buffers
+	 * are exhausted. If we exhaust Host-side received buffers, we
+	 * mask the rx data available interrupt.
+	 *
+	 * tx credits available
+	 * This remains set until all bits in COUNTER_INT_STATUS are
+	 * cleared by HW after Host SW reaps all credits on a mailbox.
+	 * If credits on an endpoint are sufficient, we mask the
+	 * corresponding COUNTER_INT_STATUS bit. We avoid "dribbling"
+	 * one credit at a time and instead reap them en masse.
+	 *
+	 * The HOST_INT_STATUS register is read-only these bits are cleared
+	 * by HW when the underlying condition is cleared.
+	 */
+
+	if (HOST_INT_STATUS_ERROR_GET(pnd_enb_intrs))
+		htca_service_error_interrupt(target, req);
+
+	if (HOST_INT_STATUS_CPU_GET(pnd_enb_intrs))
+		htca_service_cpu_interrupt(target, req);
+
+	if (HOST_INT_STATUS_COUNTER_GET(pnd_enb_intrs))
+		htca_service_credit_counter_interrupt(target, req);
+
+	/* Always needed in order to at least unmask Host interrupts */
+	htca_work_task_poke(target);
+}
+
+/* Complete an update of interrupt enables. */
+void htca_update_intr_enbs_compl(struct htca_target *target,
+				 struct htca_reg_request *req)
+{
+	htcadebug("Enter\n");
+	if (req->purpose == UPDATE_TARG_AND_ENABLE_HOST_INTRS) {
+		/* NB: non-intuitive, but correct */
+
+		/* While waiting for rxdata and txcred
+		 * interrupts to be disabled at the Target,
+		 * we temporarily masked interrupts at
+		 * the Host. It is now safe to allow
+		 * interrupts (esp. ERROR and CPU) at
+		 * the Host.
+		 */
+		htcadebug("Unmasking\n");
+		hif_un_mask_interrupt(target->hif_handle);
+	}
+}
+
+/* Called to complete htca_credit_refresh_start.
+ *
+ * Ends a credit refresh cycle. Called after decrementing a
+ * credit counter register (many times in a row). HW atomically
+ * decrements the counter and returns the OLD value but HW will
+ * never reduce it below 0.
+ *
+ * Called in the context of the work_task when the credit counter
+ * decrement operation completes synchronously. Called in the
+ * context of the compl_task when the credit counter decrement
+ * operation completes asynchronously.
+ */
+void htca_credit_refresh_compl(struct htca_target *target,
+			       struct htca_reg_request *reg_request)
+{
+	struct htca_endpoint *end_point;
+	unsigned long flags;
+	int reaped;
+	int i;
+
+	/* A non-zero value indicates 1 credit reaped.
+	 * Typically, we will find monotonically descending
+	 * values that reach 0 with the remaining values
+	 * all zero. But we must scan the entire results
+	 * to handle the case where the Target just happened
+	 * to increment credits simultaneously with our
+	 * series of credit decrement operations.
+	 */
+	htcadebug("ep=%d\n", reg_request->epid);
+	end_point = &target->end_point[reg_request->epid];
+	reaped = 0;
+	for (i = 0; i < HTCA_TX_CREDITS_REAP_MAX; i++) {
+		htcadebug("|R0x%02x", reg_request->u.credit_dec_results[i]);
+		if (reg_request->u.credit_dec_results[i])
+			reaped++;
+	}
+
+	htcadebug("\nreaped %d credits on ep=%d\n", reaped, reg_request->epid);
+
+	spin_lock_irqsave(&end_point->tx_credit_lock, flags);
+	end_point->tx_credits_available += reaped;
+	end_point->tx_credit_refresh_in_progress = false;
+	spin_unlock_irqrestore(&end_point->tx_credit_lock, flags);
+
+	htca_work_task_poke(target);
+}
diff --git a/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_events.c b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_events.c
new file mode 100644
index 0000000..d034277
--- /dev/null
+++ b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_events.c
@@ -0,0 +1,130 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/completion.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/spinlock_types.h>
+#include <linux/wait.h>
+
+#include "../hif_sdio/hif.h"
+#include "htca.h"
+#include "htca_mbox_internal.h"
+
+/* Host Target Communications Event Management */
+
+/* Protect all event tables -- global as well as per-endpoint. */
+static spinlock_t event_lock; /* protects all event tables */
+
+/* Mapping table for global events -- avail/unavail */
+static struct htca_event_table_element
+	global_event_table[HTCA_EVENT_GLOBAL_COUNT];
+
+struct htca_event_table_element *
+htca_event_id_to_event(struct htca_target *target,
+		       u8 end_point_id,
+		       u8 event_id)
+{
+	struct htca_event_table_element *ev = NULL;
+
+	/* is ep event */
+	if ((event_id >= HTCA_EVENT_EP_START) &&
+	    (event_id <= HTCA_EVENT_EP_END)) {
+		struct htca_endpoint *end_point;
+		int ep_evid;
+
+		ep_evid = event_id - HTCA_EVENT_EP_START;
+		end_point = &target->end_point[end_point_id];
+		ev = &end_point->endpoint_event_tbl[ep_evid];
+	/* is global event */
+	} else if ((event_id >= HTCA_EVENT_GLOBAL_START) &&
+		   (event_id <= HTCA_EVENT_GLOBAL_END)) {
+		int global_evid;
+
+		global_evid = event_id - HTCA_EVENT_GLOBAL_START;
+		ev = &global_event_table[global_evid];
+	} else {
+		WARN_ON(1); /* unknown event */
+	}
+
+	return ev;
+}
+
+void htca_dispatch_event(struct htca_target *target,
+			 u8 end_point_id,
+			 u8 event_id,
+			 struct htca_event_info *event_info)
+{
+	struct htca_event_table_element *ev;
+
+	ev = htca_event_id_to_event(target, end_point_id, event_id);
+	if (!ev) {
+		panic("BUG");
+		return;
+	}
+	if (ev->handler) {
+		htca_event_handler handler;
+		void *param;
+		unsigned long flags;
+
+		spin_lock_irqsave(&event_lock, flags);
+		handler = ev->handler;
+		param = ev->param;
+		spin_unlock_irqrestore(&event_lock, flags);
+
+		handler((void *)target, end_point_id, event_id,
+			event_info, param);
+	}
+}
+
+int htca_add_to_event_table(struct htca_target *target,
+			    u8 end_point_id,
+			    u8 event_id,
+			    htca_event_handler handler, void *param) {
+	struct htca_event_table_element *ev;
+	unsigned long flags;
+
+	ev = htca_event_id_to_event(target, end_point_id, event_id);
+	if (!ev)
+		return HTCA_ERROR;
+
+	spin_lock_irqsave(&event_lock, flags);
+	ev->handler = handler;
+	ev->param = param;
+	spin_unlock_irqrestore(&event_lock, flags);
+
+	return HTCA_OK;
+}
+
+int htca_remove_from_event_table(struct htca_target *target,
+				 u8 end_point_id,
+				 u8 event_id) {
+	struct htca_event_table_element *ev;
+	unsigned long flags;
+
+	ev = htca_event_id_to_event(target, end_point_id, event_id);
+	if (!ev)
+		return HTCA_ERROR;
+
+	spin_lock_irqsave(&event_lock, flags);
+	/* Clear event handler info */
+	memset(ev, 0, sizeof(*ev));
+	spin_unlock_irqrestore(&event_lock, flags);
+
+	return HTCA_OK;
+}
+
+/* Called once during module initialization */
+void htca_event_table_init(void)
+{
+	spin_lock_init(&event_lock);
+}
diff --git a/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_internal.h b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_internal.h
new file mode 100644
index 0000000..b1c7c6b
--- /dev/null
+++ b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_internal.h
@@ -0,0 +1,581 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _HTCA_INTERNAL_H_
+#define _HTCA_INTERNAL_H_
+
+#include "mbox_host_reg.h"
+
+#if defined(DEBUG)
+#define htcadebug(fmt, a...) \
+	pr_err("htca %s:%d: " fmt, __func__, __LINE__, ##a)
+#else
+#define htcadebug(args...)
+#endif
+
+/* HTCA internal specific declarations and prototypes */
+
+/* Target-side SDIO/SPI (mbox) controller supplies 4 mailboxes */
+#define HTCA_NUM_MBOX 4
+
+/* Software supports at most this many Target devices */
+#define HTCA_NUM_DEVICES_MAX 2
+
+/* Maximum supported mailbox message size.
+ *
+ * Quartz' SDIO/SPI mailbox alias spaces are 2KB each; so changes
+ * would be required to exceed that. WLAN restricts packets to
+ * under 1500B.
+ */
+#define HTCA_MESSAGE_SIZE_MAX 2048
+
+#define HTCA_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */
+
+/* The maximum number of credits that we will reap
+ * from the Target at one time.
+ */
+#define HTCA_TX_CREDITS_REAP_MAX 8
+
+/* Mailbox address in SDIO address space */
+#define MBOX_BASE_ADDR 0x800 /* Start of MBOX alias spaces */
+#define MBOX_WIDTH 0x800     /* Width of each mailbox alias space */
+
+#define MBOX_START_ADDR(mbox) (MBOX_BASE_ADDR + ((mbox) * (MBOX_WIDTH)))
+
+/* The byte just before this causes an EndOfMessage interrupt to be generated */
+#define MBOX_END_ADDR(mbox) (MBOX_START_ADDR(mbox) + MBOX_WIDTH)
+
+/* extended MBOX address for larger MBOX writes to MBOX 0 (not used) */
+#define MBOX0_EXTENDED_BASE_ADDR 0x2800
+#define MBOX0_EXTENDED_WIDTH (6 * 1024)
+
+/* HTCA message header */
+struct HTCA_header {
+	u16 total_msg_length;
+} __packed;
+
+#define HTCA_HEADER_LEN sizeof(struct HTCA_header)
+
+/* Populate an htca_event_info structure to be passed to
+ * a user's event handler.
+ */
+static inline void htca_frame_event(struct htca_event_info *event_info,
+				    u8 *buffer, size_t buffer_length,
+				    size_t actual_length, u32 status,
+				    void *cookie)
+{
+	if (event_info) {
+		event_info->buffer = buffer;
+		event_info->buffer_length = buffer_length;
+		event_info->actual_length = actual_length;
+		event_info->status = status;
+		event_info->cookie = cookie;
+	}
+}
+
+/* Global and endpoint-specific event tables use these to
+ * map an event ID --> handler + param.
+ */
+struct htca_event_table_element {
+	htca_event_handler handler;
+	void *param;
+};
+
+/* This layout MUST MATCH Target hardware layout! */
+struct htca_intr_status {
+	u8 host_int_status;
+	u8 cpu_int_status;
+	u8 err_int_status;
+	u8 counter_int_status;
+} __packed;
+
+/* This layout MUST MATCH Target hardware layout! */
+struct htca_intr_enables {
+	u8 int_status_enb;
+	u8 cpu_int_status_enb;
+	u8 err_status_enb;
+	u8 counter_int_status_enb;
+} __packed;
+
+/* The Register table contains Target SDIO/SPI interrupt/rxstatus
+ * registers used by HTCA. Rather than read particular registers,
+ * we use a bulk "register refresh" to read all at once.
+ *
+ * This layout MUST MATCH Target hardware layout!
+ */
+struct htca_register_table {
+	struct htca_intr_status status;
+
+	u8 mbox_frame;
+	u8 rx_lookahead_valid;
+	u8 hole[2];
+
+	/* Four lookahead bytes for each mailbox */
+	u32 rx_lookahead[HTCA_NUM_MBOX];
+} __packed;
+
+/* Two types of requests/responses are supported:
+ * "mbox requests" are messages or data which
+ * are sent to a Target mailbox
+ * "register requests" are to read/write Target registers
+ *
+ * Mbox requests are managed with a per-endpoint
+ * pending list and free list.
+ *
+ * Register requests are managed with a per-Target
+ * pending list and free list.
+ *
+ * A generic HTCA request -- one which is either an
+ * htca_mbox_request or an htca_reg_request is represented
+ * by an htca_request.
+ */
+
+/* Number of mbox_requests and reg_requests allocated initially.  */
+#define HTCA_MBOX_REQUEST_COUNT 16		   /* per mailbox */
+#define HTCA_REG_REQUEST_COUNT (4 * HTCA_NUM_MBOX) /* per target */
+
+/* An htca_request is at the start of a mbox_request structure
+ * and at the start of a reg_request structure.
+ *
+ * Specific request types may be cast to a generic htca_request
+ * (e.g. in order to invoke the completion callback function)
+ */
+struct htca_request {
+	/*struct htca_request*/ void *next; /* linkage */
+	struct htca_target *target;
+	void (*completion_cb)(struct htca_request *req, int status);
+	int status; /* completion status from HIF */
+};
+
+struct htca_endpoint; /* forward reference */
+
+/* Mailbox request -- a message or bulk data */
+struct htca_mbox_request {
+	struct htca_request req; /* Must be first -- (cast to htca_request) */
+
+	/* Caller-supplied cookie associated with this request */
+	void *cookie;
+
+	/* Pointer to the start of the buffer. In the transmit
+	 * direction this points to the start of the payload. In the
+	 * receive direction, however, the buffer when queued up
+	 * points to the start of the HTCA header but when returned
+	 * to the caller points to the start of the payload
+	 *
+	 * Note: buffer is set to NULL whenever this request is free.
+	 */
+	u8 *buffer;
+
+	/* length, in bytes, of the buffer */
+	u32 buffer_length;
+
+	/* length, in bytes, of the payload within the buffer */
+	u32 actual_length;
+
+	struct htca_endpoint *end_point;
+};
+
+/* Round up a value (e.g. length) to a power of 2 (e.g. block size).  */
+static inline u32 htca_round_up(u32 value, u32 pwrof2)
+{
+	return (((value) + (pwrof2) - 1) & ~((pwrof2) - 1));
+}
+
+/* Indicates reasons that we might access Target register space */
+enum htca_req_purpose {
+	UNUSED_PURPOSE,
+	INTR_REFRESH,	/* Fetch latest interrupt/status registers */
+	CREDIT_REFRESH, /* Reap credits */
+	UPDATE_TARG_INTRS,
+	UPDATE_TARG_AND_ENABLE_HOST_INTRS,
+};
+
+/* Register read request -- used to read registers from SDIO/SPI space.
+ * Register writes are fire and forget; no completion is needed.
+ *
+ */
+struct htca_reg_request {
+	struct htca_request req; /* Must be first -- (cast to htca_request) */
+	u8 *buffer;	 /* register value(s) */
+	u32 length;
+
+	/* Indicates the purpose this request was made */
+	enum htca_req_purpose purpose;
+
+	/* Which endpoint this read is for.
+	 * Used when processing a completed credit refresh request.
+	 */
+	u8 epid; /* which endpoint ID [0..3] */
+
+	/* A read to Target register space returns
+	 * one specific Target register value OR
+	 * all values in the register_table OR
+	 * a special repeated read-and-dec from a credit register
+	 *
+	 * FUTURE: We could separate these into separate request
+	 * types in order to perhaps save a bit of space....
+	 * eliminate the union.
+	 */
+	union {
+		struct htca_intr_enables enb;
+		struct htca_register_table reg_table;
+		u8 credit_dec_results[HTCA_TX_CREDITS_REAP_MAX];
+	} u;
+};
+
+struct htca_request_queue {
+	struct htca_request *head;
+	struct htca_request *tail;
+};
+
+#define HTCA_IS_QUEUE_EMPTY(q) (!((q)->head))
+
+/* List of Target registers in SDIO/SPI space which can be accessed by Host */
+enum target_registers {
+	UNUSED_REG = 0,
+	INTR_ENB_REG = INT_STATUS_ENABLE_ADDRESS,
+	ALL_STATUS_REG = HOST_INT_STATUS_ADDRESS,
+	ERROR_INT_STATUS_REG = ERROR_INT_STATUS_ADDRESS,
+	CPU_INT_STATUS_REG = CPU_INT_STATUS_ADDRESS,
+	TX_CREDIT_COUNTER_DECREMENT_REG = COUNT_DEC_ADDRESS,
+	INT_TARGET_REG = INT_TARGET_ADDRESS,
+};
+
+static inline u32 get_reg_addr(enum target_registers which,
+			       u8 epid)
+{
+	return (((which) == TX_CREDIT_COUNTER_DECREMENT_REG)
+	     ? (COUNT_DEC_ADDRESS + (HTCA_NUM_MBOX + (epid)) * 4)
+	     : (which));
+}
+
+/* FUTURE: See if we can use lock-free operations
+ * to manage credits and linked lists.
+ * FUTURE: Use standard Linux queue ops; ESPECIALLY
+ * if they support lock-free operation.
+ */
+
+/* One of these per endpoint */
+struct htca_endpoint {
+	/* Enabled or Disabled */
+	bool enabled;
+
+	/* If data is available, rxLengthPending
+	 * indicates the length of the incoming message.
+	 */
+	u32 rx_frame_length; /* incoming frame length on this endpoint */
+	/* includes HTCA header */
+	/* Modified only by compl_task */
+
+	bool rx_data_alerted; /* Caller was sent a BUFFER_AVAILABLE event */
+	/* and has not supplied a new recv buffer */
+	/* since that warning was sent.  */
+	/* Modified only by work_task */
+
+	bool tx_credits_to_reap; /* At least one credit available at the */
+	/* Target waiting to be reaped. */
+	/* Modified only by compl_task */
+
+	/* Guards tx_credits_available and tx_credit_refresh_in_progress */
+	spinlock_t tx_credit_lock;
+
+	/* The number of credits that we have already reaped
+	 * from the Target. (i.e. we have decremented the Target's
+	 * count register so that we have ability to send future
+	 * messages). We have the ability to send tx_credits_available
+	 * messages without blocking.
+	 *
+	 * The size of a message is endpoint-dependent and always
+	 * a multiple of the device's block_size.
+	 */
+	u32 tx_credits_available;
+
+	/* Maximum message size */
+	u32 max_msg_sz;
+
+	/* Indicates that we are in the midst of a credit refresh cycle */
+	bool tx_credit_refresh_in_progress;
+
+	/* Free/Pending Send/Recv queues are used for mbox requests.
+	 * An mbox Send request cannot be given to HIF until we have
+	 * a tx credit. An mbox Recv request cannot be given to HIF
+	 * until we have a pending rx msg.
+	 *
+	 * The HIF layer maintains its own queue of requests, which
+	 * it uses to serialize access to SDIO. Its queue contains
+	 * a mixture of sends/recvs and mbox/reg requests. HIF is
+	 * "beyond" flow control so once a requets is given to HIF
+	 * it is guaranteed to complete (after all previous requests
+	 * complete).
+	 */
+
+	/* Guards Free/Pending send/recv queues */
+	spinlock_t mbox_queue_lock;
+	struct htca_request_queue send_free_queue;
+	struct htca_request_queue send_pending_queue;
+	struct htca_request_queue recv_free_queue;
+	struct htca_request_queue recv_pending_queue;
+
+	/* Inverse reference to the target */
+	struct htca_target *target;
+
+	/* Block size configured for the endpoint -- common across all endpoints
+	 */
+	u32 block_size;
+
+	/* Mapping table for per-endpoint events */
+	struct htca_event_table_element endpoint_event_tbl[HTCA_EVENT_EP_COUNT];
+
+	/* Location of the endpoint's mailbox space */
+	u32 mbox_start_addr;
+	u32 mbox_end_addr;
+};
+
+#define ENDPOINT_UNUSED 0
+
+/* Target interrupt states. */
+enum intr_state_e {
+	/* rxdata and txcred interrupts enabled.
+	 * Only the DSR context can switch us to
+	 * polled state.
+	 */
+	HTCA_INTERRUPT,
+
+	/* rxdata and txcred interrupts are disabled.
+	 * We are polling (via RegisterRefresh).
+	 * Only the work_task can switch us to
+	 * interrupt state.
+	 */
+	HTCA_POLL,
+};
+
+/* One of these per connected QCA402X device. */
+struct htca_target {
+	/* Target device is initialized and ready to go?
+	 * This has little o do with Host state;
+	 * it reflects readiness of the Target.
+	 */
+	bool ready;
+
+	/* Handle passed to HIF layer for SDIO/SPI Host controller access */
+	void *hif_handle; /* hif_device */
+
+	/* Per-endpoint info */
+	struct htca_endpoint end_point[HTCA_NUM_MBOX];
+
+	/* Used during startup while the Host waits for the
+	 * Target to initialize.
+	 */
+	wait_queue_head_t target_init_wait;
+
+	/* Free queue for htca_reg_requests.
+	 *
+	 * We don't need a regPendingQueue because reads/writes to
+	 * Target register space are not flow controlled by the Target.
+	 * There is no need to wait for credits in order to hand off a
+	 * register read/write to HIF.
+	 *
+	 * The register read/write may end up queued in a HIF queue
+	 * behind both register and mbox reads/writes that were
+	 * handed to HIF earlier. But they will never be queued
+	 * by HTCA.
+	 */
+	spinlock_t reg_queue_lock;
+	struct htca_request_queue reg_free_queue;
+
+	/* comp task synchronization */
+	struct mutex task_mutex;
+
+	struct task_struct *work_task;
+	struct task_struct *compl_task;
+
+	/* work_task synchronization */
+	wait_queue_head_t work_task_wait; /* wait for work to do */
+	bool work_task_has_work;	  /* work available? */
+	bool work_task_shutdown;	  /* requested stop? */
+	struct completion work_task_completion;
+
+	/* compl_task synchronization */
+	wait_queue_head_t compl_task_wait; /* wait for work to do */
+	bool compl_task_has_work;	   /* work available? */
+	bool compl_task_shutdown;	   /* requested stop? */
+	struct completion compl_cask_completion;
+
+	/* Queue of completed mailbox and register requests */
+	spinlock_t compl_queue_lock;
+	struct htca_request_queue compl_queue;
+
+	/* Software's shadow copy of interrupt enables.
+	 * Only the work_task changes intr_enable bits,
+	 * so no locking necessary.
+	 *
+	 * Committed to Target HW when
+	 * we convert from polling to interrupts or
+	 * we are using interrupts and enables have changed
+	 */
+	struct htca_intr_enables enb;
+	struct htca_intr_enables last_committed_enb;
+
+	enum intr_state_e intr_state;
+	int need_start_polling;
+
+	/* Set after we read data from a mailbox (to
+	 * update lookahead and mailbox status bits).
+	 * used only by work_task even though refreshes
+	 * may be started in other contexts.
+	 */
+	int need_register_refresh;
+
+	/* Guards pending_register_refresh and pending_recv_mask */
+	spinlock_t pending_op_lock;
+
+	/* Incremented when a RegisterRefresh is started;
+	 * Decremented when it completes.
+	 */
+	int pending_register_refresh;
+
+	/* Non-zero if a recv operation has been started
+	 * but not yet completed. 1 bit for each ep.
+	 */
+	int pending_recv_mask;
+};
+
+/* Convert an endpoint POINTER into an endpoint ID [0..3] */
+static inline u32 get_endpoint_id(struct htca_endpoint *ep)
+{
+	return (u32)(ep - ep->target->end_point);
+}
+
+void htca_receive_frame(struct htca_endpoint *end_point);
+
+u32 htca_get_frame_length(struct htca_endpoint *end_point);
+
+void htca_send_frame(struct htca_endpoint *end_point);
+
+void htca_send_blk_size(struct htca_endpoint *end_point);
+
+int htca_rw_completion_handler(void *req, int status);
+
+void htca_send_compl(struct htca_request *req, int status);
+
+void htca_recv_compl(struct htca_request *req, int status);
+
+void htca_reg_compl(struct htca_request *req, int status);
+
+int htca_target_inserted_handler(void *context,
+				 void *hif_handle);
+
+int htca_target_removed_handler(void *context, void *hif_handle);
+
+int htca_dsr_handler(void *target_ctxt);
+
+void htca_service_cpu_interrupt(struct htca_target *target,
+				struct htca_reg_request *req);
+
+void htca_service_error_interrupt(struct htca_target *target,
+				  struct htca_reg_request *req);
+
+void htca_service_credit_counter_interrupt(struct htca_target *target,
+					   struct htca_reg_request *req);
+
+void htca_enable_credit_counter_interrupt(struct htca_target *target,
+					  u8 end_point_id);
+
+void htca_disable_credit_counter_interrupt(struct htca_target *target,
+					   u8 end_point_id);
+
+int htca_add_to_mbox_queue(struct htca_mbox_request *queue,
+			   u8 *buffer,
+			   u32 buffer_length,
+			   u32 actual_length, void *cookie);
+
+struct htca_mbox_request *
+htca_remove_from_mbox_queue(struct htca_mbox_request *queue);
+
+void htca_mbox_queue_flush(struct htca_endpoint *end_point,
+			   struct htca_request_queue *pending_queue,
+			   struct htca_request_queue *free_queue,
+			   u8 event_id);
+
+int htca_add_to_event_table(struct htca_target *target,
+			    u8 end_point_id,
+			    u8 event_id,
+			    htca_event_handler handler,
+			    void *param);
+
+int htca_remove_from_event_table(struct htca_target *target,
+				 u8 end_point_id,
+				 u8 event_id);
+
+void htca_dispatch_event(struct htca_target *target,
+			 u8 end_point_id,
+			 u8 event_id,
+			 struct htca_event_info *event_info);
+
+struct htca_target *htca_target_instance(int i);
+
+void htca_target_instance_add(struct htca_target *target);
+
+void htca_target_instance_remove(struct htca_target *target);
+
+u8 htca_get_bit_num_set(u32 data);
+
+void htca_register_refresh(struct htca_target *target);
+
+void free_request(struct htca_request *req,
+		  struct htca_request_queue *queue);
+
+extern struct htca_target *htca_target_list[HTCA_NUM_DEVICES_MAX];
+
+int htca_work_task_start(struct htca_target *target);
+int htca_compl_task_start(struct htca_target *target);
+void htca_work_task_stop(struct htca_target *target);
+void htca_compl_task_stop(struct htca_target *target);
+void htca_work_task_poke(struct htca_target *target);
+void htca_compl_task_poke(struct htca_target *target);
+
+void htca_event_table_init(void);
+struct htca_event_table_element *
+htca_event_id_to_event(struct htca_target *target,
+		       u8 end_point_id,
+		       u8 event_id);
+
+void htca_request_enq_tail(struct htca_request_queue *queue,
+			   struct htca_request *req);
+struct htca_request *htca_request_deq_head(struct htca_request_queue *queue);
+
+void htca_register_refresh_start(struct htca_target *target);
+void htca_register_refresh_compl(struct htca_target *target,
+				 struct htca_reg_request *req);
+
+int htca_credit_refresh_start(struct htca_endpoint *end_point);
+void htca_credit_refresh_compl(struct htca_target *target,
+			       struct htca_reg_request *req);
+
+void htca_update_intr_enbs(struct htca_target *target,
+			   int enable_host_intrs);
+void htca_update_intr_enbs_compl(struct htca_target *target,
+				 struct htca_reg_request *req);
+
+bool htca_negotiate_config(struct htca_target *target);
+
+int htca_recv_request_to_hif(struct htca_endpoint *end_point,
+			     struct htca_mbox_request *mbox_request);
+int htca_send_request_to_hif(struct htca_endpoint *endpoint,
+			     struct htca_mbox_request *mbox_request);
+
+int htca_manage_pending_sends(struct htca_target *target, int epid);
+int htca_manage_pending_recvs(struct htca_target *target, int epid);
+
+void _htca_stop(struct htca_target *target);
+
+#endif /* _HTCA_INTERNAL_H_ */
diff --git a/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_intr.c b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_intr.c
new file mode 100644
index 0000000..0486f59
--- /dev/null
+++ b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_intr.c
@@ -0,0 +1,627 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/completion.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/spinlock_types.h>
+#include <linux/wait.h>
+
+#include "../hif_sdio/hif.h"
+#include "htca.h"
+#include "htca_mbox_internal.h"
+
+/* Host Target Communications Interrupt Management */
+
+/* Interrupt Management
+ * When an interrupt occurs at the Host, it is to tell us about
+ * a high-priority error interrupt
+ * a CPU interrupt (TBD)
+ * rx data available
+ * tx credits available
+ *
+ * From an interrupt management perspective, rxdata and txcred
+ * interrupts are grouped together. When either of these occurs,
+ * we enter a mode where we repeatedly refresh register state
+ * and act on all interrupt information in the refreshed registers.
+ * We are basically polling with rxdata and txcred interrupts
+ * masked. Eventually, we refresh registers and find no rxdata
+ * and no txcred interrupts pending. At this point, we unmask
+ * those types of interrupts.
+ *
+ * Unmasking is selective: We unmask only the interrupts that
+ * we want to receive which include
+ * -rxdata interrupts for endpoints that have received
+ * buffers on the recv pending queue
+ * -txcred interrupts for endpoints with a very low
+ * count of creditsAvailable
+ * Other rxdata and txcred interrupts are masked. These include:
+ * -rxdata interrupts for endpoint that lack recv buffers
+ * -txcred interrupts for endpoint with lots of credits
+ *
+ * Very little activity takes place in the context of the
+ * interrupt function (Delayed Service Routine). We mask
+ * interrupts at the Host, send a command to disable all
+ * rxdata/txcred interrupts and finally start a register
+ * refresh. When the register refresh completes, we unmask
+ * interrupts on the Host and poke the work_task which now
+ * has valid register state to examine.
+ *
+ * The work_task repeatedly
+ * handles outstanding rx and tx service
+ * starts another register refresh
+ * Every time a register refresh completes, it pokes the
+ * work_task. This cycle continues until the work_task finds
+ * nothing to do after a register refresh. At this point,
+ * it unmasks rxdata/txcred interrupts at the Target (again,
+ * selectively).
+ *
+ * While in the work_task polling cycle, we maintain a notion
+ * of interrupt enables in software rather than commit these
+ * to Target HW.
+ *
+ *
+ * Credit State Machine:
+ * Credits are
+ * -Added by the Target whenever a Target-side receive
+ * buffer is added to a mailbox
+ * -Never rescinded by the Target
+ * -Reaped by this software after a credit refresh cycle
+ * which is initiated
+ * -as a result of a credit counter interrupt
+ * -after a send completes and the number of credits
+ * are below an acceptable threshold
+ * -used by this software when it sends a message HIF to
+ * be sent to the Target
+ *
+ * The process of "reaping" credits involves first issuing
+ * a sequence of reads to the COUNTER_DEC register. (This is
+ * known as the start of a credit refresh.) We issue a large
+ * number of reads in order to reap as many credits at once
+ * as we can. When these reads complete, we determine how
+ * many credits were available and increase software's notion
+ * of tx_credits_available accordingly.
+ *
+ * Note: All Target reads/writes issued from the interrupt path
+ * should be asynchronous. HIF adds such a request to a queue
+ * and immediately returns.
+ *
+ * TBD: It might be helpful for HIF to support a "priority
+ * queue" -- requests that should be issued prior to anything
+ * in its normal queue. Even with this, a request might have
+ * to wait for a while as the current, read/write request
+ * completes on SDIO and then wait for all prior priority
+ * requests to finish. So probably not worth the additional
+ * complexity.
+ */
+
+/* Maximum message sizes for each endpoint.
+ * Must be a multiple of the block size.
+ * Must be no greater than HTCA_MESSAGE_SIZE_MAX.
+ *
+ * TBD: These should be tunable. Example anticipated usage:
+ * ep0: Host-side networking control messages
+ * ep1: Host-side networking data messages
+ * ep2: OEM control messages
+ * ep3: OEM data messages
+ */
+static u32 htca_msg_size[HTCA_NUM_MBOX] = {256, 3 * 512, 512, 2048};
+
+/* Commit the shadow interrupt enables in software to
+ * Target Hardware. This is where the "lazy commit"
+ * occurs. Always called in the context of work_task.
+ *
+ * When the host's intr_state is POLL:
+ * -All credit count interrupts and all rx data interrupts
+ * are disabled at the Target.
+ *
+ * When the host's intr_state is INTERRUPT:
+ * -We commit the shadow copy of interrupt enables.
+ * -A mailbox with low credit count will have the credit
+ * interrupt enabled. A mailbox with high credit count
+ * will have the credit interrupt disabled.
+ * -A mailbox with no available receive buffers will have
+ * the mailbox data interrupt disabled. A mailbox with
+ * at least one receive buffer will have the mailbox
+ * data interrupt enabled.
+ */
+void htca_update_intr_enbs(struct htca_target *target,
+			   int enable_host_intrs)
+{
+	int status;
+	struct htca_reg_request *reg_request;
+	struct htca_intr_enables *enbregs;
+	unsigned long flags;
+	u32 address;
+
+	htcadebug("Enter: enable_host_intrs=%d\n",
+		  enable_host_intrs);
+	htcadebug("ints: 0x%02x  --> 0x%02x\n",
+		  target->last_committed_enb.int_status_enb,
+		  target->enb.int_status_enb);
+	htcadebug("cpu: 0x%02x	--> 0x%02x\n",
+		  target->last_committed_enb.cpu_int_status_enb,
+		  target->enb.cpu_int_status_enb);
+	htcadebug("error: 0x%02x  --> 0x%02x\n",
+		  target->last_committed_enb.err_status_enb,
+		  target->enb.err_status_enb);
+	htcadebug("counters: 0x%02x  --> 0x%02x\n",
+		  target->last_committed_enb.counter_int_status_enb,
+		  target->enb.counter_int_status_enb);
+	if ((target->enb.int_status_enb ==
+			target->last_committed_enb.int_status_enb) &&
+		(target->enb.counter_int_status_enb ==
+			target->last_committed_enb.counter_int_status_enb) &&
+		(target->enb.cpu_int_status_enb ==
+			target->last_committed_enb.cpu_int_status_enb) &&
+		(target->enb.err_status_enb ==
+			target->last_committed_enb.err_status_enb)) {
+		/* No changes to Target-side interrupt enables are required.
+		 * But we must still need to enable Host-side interrupts.
+		 */
+		if (enable_host_intrs) {
+			htcadebug("Unmasking - no change to Target enables\n");
+			hif_un_mask_interrupt(target->hif_handle);
+		}
+		return;
+	}
+
+	spin_lock_irqsave(&target->reg_queue_lock, flags);
+	reg_request = (struct htca_reg_request *)htca_request_deq_head(
+	    &target->reg_free_queue);
+	spin_unlock_irqrestore(&target->reg_queue_lock, flags);
+	if (!reg_request) {
+		WARN_ON(1);
+		return;
+	}
+	if (WARN_ON(reg_request->purpose != UNUSED_PURPOSE))
+		return;
+
+	reg_request->buffer = NULL;
+	reg_request->length = 0;
+	reg_request->epid = 0; /* unused */
+	enbregs = &reg_request->u.enb;
+
+	if (target->intr_state == HTCA_INTERRUPT) {
+		enbregs->int_status_enb = target->enb.int_status_enb;
+		enbregs->counter_int_status_enb =
+		    target->enb.counter_int_status_enb;
+	} else {
+		enbregs->int_status_enb = (target->enb.int_status_enb &
+					   ~HOST_INT_STATUS_MBOX_DATA_MASK);
+		enbregs->counter_int_status_enb = 0;
+	}
+
+	enbregs->cpu_int_status_enb = target->enb.cpu_int_status_enb;
+	enbregs->err_status_enb = target->enb.err_status_enb;
+
+	target->last_committed_enb = *enbregs; /* structure copy */
+
+	if (enable_host_intrs)
+		reg_request->purpose = UPDATE_TARG_AND_ENABLE_HOST_INTRS;
+	else
+		reg_request->purpose = UPDATE_TARG_INTRS;
+
+	address = get_reg_addr(INTR_ENB_REG, ENDPOINT_UNUSED);
+
+	status = hif_read_write(target->hif_handle, address, enbregs,
+				sizeof(*enbregs), HIF_WR_ASYNC_BYTE_INC,
+				reg_request);
+	if (status == HIF_OK && reg_request->req.completion_cb) {
+		reg_request->req.completion_cb(
+		    (struct htca_request *)reg_request, HIF_OK);
+		/* htca_update_intr_enbs_compl */
+	} else if (status == HIF_PENDING) {
+		/* Will complete later */
+	} else { /* HIF error */
+		WARN_ON(1);
+	}
+}
+
+/* Delayed Service Routine, invoked from HIF in thread context
+ * (from sdio's irqhandler) in order to handle interrupts
+ * caused by the Target.
+ *
+ * This serves as a top-level interrupt dispatcher for HTCA.
+ */
+int htca_dsr_handler(void *htca_handle)
+{
+	struct htca_target *target = (struct htca_target *)htca_handle;
+
+	htcadebug("Enter\n");
+	if (target->ready) {
+		/* Transition state to polling mode.
+		 * Temporarily disable intrs at Host
+		 * until interrupts are stopped in
+		 * Target HW.
+		 */
+		htcadebug("Masking interrupts\n");
+		hif_mask_interrupt(target->hif_handle);
+		target->need_start_polling = 1;
+
+		/* Kick off a register refresh so we
+		 * use updated registers in order to
+		 * figure out what needs to be serviced.
+		 *
+		 * RegisterRefresh completion wakes the
+		 * work_task which re-enables Host-side
+		 * interrupts.
+		 */
+		htca_register_refresh_start(target);
+	} else { /* startup time */
+		 /* Assumption is that we are receiving an interrupt
+		  * because the Target made a TX Credit available
+		  * on each endpoint (for configuration negotiation).
+		  */
+
+		hif_mask_interrupt(target->hif_handle);
+		if (htca_negotiate_config(target)) {
+			/* All endpoints are configured.
+			 * Target is now ready for normal operation.
+			 */
+			/* TBDXXX - Fix Quartz-side and remove this */
+			{
+				/* HACK: Signal Target to read mbox Cfg info.
+				 * TBD: Target should use EOM rather than an
+				 * an explicit Target Interrupt for this.
+				 */
+				u8 my_targ_int;
+				u32 address;
+				int status;
+
+				/* Set HTCA_INT_TARGET_INIT_HOST_REQ */
+				my_targ_int = 1;
+
+				address =
+				    get_reg_addr(
+					INT_TARGET_REG, ENDPOINT_UNUSED);
+				status = hif_read_write(
+				    target->hif_handle, address, &my_targ_int,
+				    sizeof(my_targ_int), HIF_WR_SYNC_BYTE_INC,
+				    NULL);
+				if (WARN_ON(status != HIF_OK))
+					return status;
+			}
+			target->ready = true;
+			htcadebug("HTCA TARGET IS READY\n");
+			wake_up(&target->target_init_wait);
+		}
+		hif_un_mask_interrupt(target->hif_handle);
+	}
+	return HTCA_OK;
+}
+
+/* Handler for CPU interrupts that are explicitly
+ * initiated by Target firmware. Not used by system firmware today.
+ */
+void htca_service_cpu_interrupt(struct htca_target *target,
+				struct htca_reg_request *req)
+{
+	int status;
+	u32 address;
+	u8 cpu_int_status;
+
+	htcadebug("Enter\n");
+	cpu_int_status = req->u.reg_table.status.cpu_int_status &
+			 target->enb.cpu_int_status_enb;
+
+	/* Clear pending interrupts on Target -- Write 1 to Clear */
+	address = get_reg_addr(CPU_INT_STATUS_REG, ENDPOINT_UNUSED);
+
+	status =
+	    hif_read_write(target->hif_handle, address, &cpu_int_status,
+			   sizeof(cpu_int_status), HIF_WR_SYNC_BYTE_INC, NULL);
+
+	WARN_ON(status != HIF_OK);
+
+	/* Handle cpu_int_status actions here. None are currently used */
+}
+
+/* Handler for error interrupts on Target.
+ * If everything is working properly we hope never to see these.
+ */
+void htca_service_error_interrupt(struct htca_target *target,
+				  struct htca_reg_request *req)
+{
+	int status = HIF_ERROR;
+	u32 address;
+	u8 err_int_status;
+	struct htca_endpoint *end_point;
+
+	htcadebug("Enter\n");
+	err_int_status =
+	    req->u.reg_table.status.err_int_status & target->enb.err_status_enb;
+
+	end_point = &target->end_point[req->epid];
+	htcadebug("epid=%d txCreditsAvailable=%d\n",
+		  (int)req->epid, end_point->tx_credits_available);
+	htcadebug("statusregs host=0x%02x cpu=0x%02x err=0x%02x cnt=0x%02x\n",
+		  req->u.reg_table.status.host_int_status,
+		  req->u.reg_table.status.cpu_int_status,
+		  req->u.reg_table.status.err_int_status,
+		  req->u.reg_table.status.counter_int_status);
+
+	/* Clear pending interrupts on Target -- Write 1 to Clear */
+	address = get_reg_addr(ERROR_INT_STATUS_REG, ENDPOINT_UNUSED);
+	status =
+	    hif_read_write(target->hif_handle, address, &err_int_status,
+			   sizeof(err_int_status), HIF_WR_SYNC_BYTE_INC, NULL);
+
+	if (WARN_ON(status != HIF_OK))
+		return;
+
+	if (ERROR_INT_STATUS_WAKEUP_GET(err_int_status)) {
+		/* Wakeup */
+		htcadebug("statusregs host=0x%x\n",
+			  ERROR_INT_STATUS_WAKEUP_GET(err_int_status));
+		/* Nothing needed here */
+	}
+
+	if (ERROR_INT_STATUS_RX_UNDERFLOW_GET(err_int_status)) {
+		/* TBD: Rx Underflow */
+		/* Host posted a read to an empty mailbox? */
+		/* Target DMA was not able to keep pace with Host reads? */
+		if (WARN_ON(2)) /* TBD */
+			return;
+	}
+
+	if (ERROR_INT_STATUS_TX_OVERFLOW_GET(err_int_status)) {
+		/* TBD: Tx Overflow */
+		/* Host posted a write to a mailbox with no credits? */
+		/* Target DMA was not able to keep pace with Host writes? */
+		if (WARN_ON(1)) /* TBD */
+			return;
+	}
+}
+
+/* Handler for Credit Counter interrupts from Target.
+ *
+ * This occurs when the number of credits available on a mailbox
+ * increases from 0 to non-zero. (i.e. when Target firmware queues a
+ * DMA Receive buffer to an endpoint that previously had no buffers.)
+ *
+ * This interrupt is masked when we have a sufficient number of
+ * credits available. It is unmasked only when we have reaped all
+ * available credits and are still below a desired threshold.
+ */
+void htca_service_credit_counter_interrupt(struct htca_target *target,
+					   struct htca_reg_request *req)
+{
+	struct htca_endpoint *end_point;
+	u8 counter_int_status;
+	u8 eps_with_credits;
+	int ep;
+
+	htcadebug("Enter\n");
+	counter_int_status = req->u.reg_table.status.counter_int_status;
+
+	/* Service the credit counter interrupt.
+	 * COUNTER bits [4..7] are used for credits on endpoints [0..3].
+	 */
+	eps_with_credits =
+	    counter_int_status & target->enb.counter_int_status_enb;
+	htcadebug("eps_with_credits=0x%02x\n", eps_with_credits);
+	htcadebug("counter_int_status=0x%02x\n", counter_int_status);
+	htcadebug("counter_int_status_enb=0x%02x\n",
+		  target->enb.counter_int_status_enb);
+
+	for (ep = 0; ep < HTCA_NUM_MBOX; ep++) {
+		if (!(eps_with_credits & (0x10 << ep)))
+			continue;
+
+		end_point = &target->end_point[ep];
+
+		/* We need credits on this endpoint AND
+		 * the target tells us that there are some.
+		 * Start a credit refresh cycle on this
+		 * endpoint.
+		 */
+		(void)htca_credit_refresh_start(end_point);
+	}
+}
+
+/* Callback registered with HIF to be invoked when Target
+ * presence is first detected.
+ *
+ * Allocate memory for Target, endpoints, requests, etc.
+ */
+int htca_target_inserted_handler(void *unused_context,
+				 void *hif_handle)
+{
+	struct htca_target *target;
+	struct htca_endpoint *end_point;
+	int ep;
+	struct htca_event_info event_info;
+	struct htca_request_queue *send_free_queue, *recv_free_queue;
+	struct htca_request_queue *reg_queue;
+	u32 block_size[HTCA_NUM_MBOX];
+	struct cbs_from_hif htca_callbacks; /* Callbacks from HIF to HTCA */
+	int status = HTCA_OK;
+	int i;
+
+	htcadebug("Enter\n");
+
+	target = kzalloc(sizeof(*target), GFP_KERNEL);
+	/* target->ready = false; */
+
+	/* Give a handle to HIF for this target */
+	target->hif_handle = hif_handle;
+	hif_set_handle(hif_handle, (void *)target);
+
+	/* Register htca_callbacks from HIF */
+	memset(&htca_callbacks, 0, sizeof(htca_callbacks));
+	htca_callbacks.rw_completion_hdl = htca_rw_completion_handler;
+	htca_callbacks.dsr_hdl = htca_dsr_handler;
+	htca_callbacks.context = target;
+	(void)hif_attach(hif_handle, &htca_callbacks);
+
+	/* Get block sizes and start addresses for each mailbox */
+	hif_configure_device(hif_handle,
+			     HIF_DEVICE_GET_MBOX_BLOCK_SIZE, &block_size,
+			     sizeof(block_size));
+
+	/* Initial software copies of interrupt enables */
+	target->enb.int_status_enb =
+	    INT_STATUS_ENABLE_ERROR_MASK | INT_STATUS_ENABLE_CPU_MASK |
+	    INT_STATUS_ENABLE_COUNTER_MASK | INT_STATUS_ENABLE_MBOX_DATA_MASK;
+
+	/* All 8 CPU interrupts enabled */
+	target->enb.cpu_int_status_enb = CPU_INT_STATUS_ENABLE_BIT_MASK;
+
+	target->enb.err_status_enb = ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK |
+				     ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK;
+
+	/* credit counters in upper bits */
+	target->enb.counter_int_status_enb = COUNTER_INT_STATUS_ENABLE_BIT_MASK;
+
+	spin_lock_init(&target->reg_queue_lock);
+	spin_lock_init(&target->compl_queue_lock);
+	spin_lock_init(&target->pending_op_lock);
+	mutex_init(&target->task_mutex);
+
+	status = htca_work_task_start(target);
+	if (status != HTCA_OK)
+		goto done;
+
+	status = htca_compl_task_start(target);
+	if (status != HTCA_OK)
+		goto done;
+
+	/* Initialize the register request free list */
+	reg_queue = &target->reg_free_queue;
+	for (i = 0; i < HTCA_REG_REQUEST_COUNT; i++) {
+		struct htca_reg_request *reg_request;
+
+		/* Add a reg_request to the Reg Free Queue */
+		reg_request = kzalloc(sizeof(*reg_request), GFP_DMA);
+		reg_request->req.target = target;
+		reg_request->req.completion_cb = htca_reg_compl;
+
+		/* no lock required -- startup */
+		htca_request_enq_tail(reg_queue,
+				      (struct htca_request *)reg_request);
+	}
+
+	/* Initialize endpoints, mbox queues and event tables */
+	for (ep = 0; ep < HTCA_NUM_MBOX; ep++) {
+		end_point = &target->end_point[ep];
+
+		spin_lock_init(&end_point->tx_credit_lock);
+		spin_lock_init(&end_point->mbox_queue_lock);
+
+		end_point->tx_credits_available = 0;
+		end_point->max_msg_sz = htca_msg_size[ep];
+		end_point->rx_frame_length = 0;
+		end_point->tx_credits_to_reap = false;
+		end_point->target = target;
+		end_point->enabled = false;
+		end_point->block_size = block_size[ep];
+		end_point->mbox_start_addr = MBOX_START_ADDR(ep);
+		end_point->mbox_end_addr = MBOX_END_ADDR(ep);
+
+		/* Initialize per-endpoint queues */
+		end_point->send_pending_queue.head = NULL;
+		end_point->send_pending_queue.tail = NULL;
+		end_point->recv_pending_queue.head = NULL;
+		end_point->recv_pending_queue.tail = NULL;
+
+		send_free_queue = &end_point->send_free_queue;
+		recv_free_queue = &end_point->recv_free_queue;
+		for (i = 0; i < HTCA_MBOX_REQUEST_COUNT; i++) {
+			struct htca_mbox_request *mbox_request;
+
+			/* Add an mbox_request to the mbox SEND Free Queue */
+			mbox_request = kzalloc(sizeof(*mbox_request),
+					       GFP_KERNEL);
+			mbox_request->req.target = target;
+			mbox_request->req.completion_cb = htca_send_compl;
+			mbox_request->end_point = end_point;
+			htca_request_enq_tail(
+			    send_free_queue,
+			    (struct htca_request *)mbox_request);
+
+			/* Add an mbox_request to the mbox RECV Free Queue */
+			mbox_request = kzalloc(sizeof(*mbox_request),
+					       GFP_KERNEL);
+			mbox_request->req.target = target;
+			mbox_request->req.completion_cb = htca_recv_compl;
+			mbox_request->end_point = end_point;
+			htca_request_enq_tail(
+			    recv_free_queue,
+			    (struct htca_request *)mbox_request);
+		}
+	}
+
+	/* Target and endpoint structures are now completely initialized.
+	 * Add the target instance to the global list of targets.
+	 */
+	htca_target_instance_add(target);
+
+	/* Frame a TARGET_AVAILABLE event and send it to
+	 * the caller. Return the hif_device handle as a
+	 * parameter with the event.
+	 */
+	htca_frame_event(&event_info, (u8 *)hif_handle,
+			 hif_get_device_size(),
+			 hif_get_device_size(), HTCA_OK, NULL);
+	htca_dispatch_event(target, ENDPOINT_UNUSED,
+			    HTCA_EVENT_TARGET_AVAILABLE, &event_info);
+
+done:
+	return status;
+}
+
+/* Callback registered with HIF to be invoked when Target
+ * is removed
+ *
+ * Also see htca_stop
+ * Stop tasks
+ * Free memory for Target, endpoints, requests, etc.
+ *
+ * TBD: Not yet supported
+ */
+int htca_target_removed_handler(void *unused_context,
+				void *htca_handle)
+{
+	struct htca_target *target = (struct htca_target *)htca_handle;
+	struct htca_event_info event_info;
+	struct htca_endpoint *end_point;
+	int ep;
+
+	htcadebug("Enter\n");
+	/* Disable each of the endpoints to stop accepting requests. */
+	for (ep = 0; ep < HTCA_NUM_MBOX; ep++) {
+		end_point = &target->end_point[ep];
+		end_point->enabled = false;
+	}
+
+	if (target) {
+		/* Frame a TARGET_UNAVAILABLE event and send it to the host */
+		htca_frame_event(&event_info, NULL, 0, 0, HTCA_OK, NULL);
+		htca_dispatch_event(target, ENDPOINT_UNUSED,
+				    HTCA_EVENT_TARGET_UNAVAILABLE, &event_info);
+	}
+
+	/* TBD: call htca_stop? */
+	/* TBD: Must be sure that nothing is going on before we free. */
+	if (WARN_ON(1)) /* TBD */
+		return HTCA_ERROR;
+
+	/* Free everything allocated earlier, including target
+	 * structure and all request structures.
+	 */
+	/* TBD: kfree .... */
+
+	return HTCA_OK;
+}
diff --git a/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_recv.c b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_recv.c
new file mode 100644
index 0000000..0d4eae8
--- /dev/null
+++ b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_recv.c
@@ -0,0 +1,205 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/completion.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/spinlock_types.h>
+#include <linux/wait.h>
+
+#include "../hif_sdio/hif.h"
+#include "htca.h"
+#include "htca_mbox_internal.h"
+
+/* If there is data available to read on the specified mailbox,
+ * pull a Mailbox Recv Request off of the PendingRecv queue
+ * and request HIF to pull data from the mailbox into the
+ * request's recv buffer.
+ *
+ * If we are not aware of data waiting on the endpoint, simply
+ * return. Note that our awareness is based on slightly stale
+ * data from Quartz registers. Upper layers insure that we are
+ * called shortly after data becomes available on an endpoint.
+ *
+ * If we exhaust receive buffers, disable the mailbox's interrupt
+ * until additional buffers are available.
+ *
+ * Returns 0 if no request was sent to HIF
+ * returns 1 if at least one request was sent to HIF
+ */
+int htca_manage_pending_recvs(struct htca_target *target, int epid)
+{
+	struct htca_endpoint *end_point;
+	struct htca_request_queue *recv_queue;
+	struct htca_mbox_request *mbox_request;
+	u32 rx_frame_length;
+	unsigned long flags;
+	int work_done = 0;
+
+	if (target->pending_recv_mask & (1 << epid)) {
+		/* Receive operation is already in progress on this endpoint */
+		return 0;
+	}
+
+	end_point = &target->end_point[epid];
+
+	/* Hand off requests as long as we have both
+	 * something to recv into
+	 * data waiting to be read on the mailbox
+	 */
+
+	/* rx_frame_length of 0 --> nothing waiting; otherwise, it's
+	 * the length of data waiting to be read, NOT including
+	 * HTCA header nor block padding.
+	 */
+	rx_frame_length = end_point->rx_frame_length;
+
+	recv_queue = &end_point->recv_pending_queue;
+	if (HTCA_IS_QUEUE_EMPTY(recv_queue)) {
+		htcadebug("no recv buff for ep#%d\n", epid);
+		/* Not interested in rxdata interrupts
+		 * since we have no recv buffers.
+		 */
+		target->enb.int_status_enb &= ~(1 << epid);
+
+		if (rx_frame_length) {
+			struct htca_event_info event_info;
+
+			htcadebug("frame waiting (%d): %d\n",
+				  epid, rx_frame_length);
+			/* No buffer ready to receive but data
+			 * is ready. Alert the caller with a
+			 * DATA_AVAILABLE event.
+			 */
+			if (!end_point->rx_data_alerted) {
+				end_point->rx_data_alerted = true;
+
+				htca_frame_event(&event_info, NULL,
+						 rx_frame_length,
+						 0, HTCA_OK, NULL);
+
+				htca_dispatch_event(target, epid,
+						    HTCA_EVENT_DATA_AVAILABLE,
+						    &event_info);
+			}
+		}
+		return 0;
+	}
+
+	/* We have recv buffers available, so we are
+	 * interested in rxdata interrupts.
+	 */
+	target->enb.int_status_enb |= (1 << epid);
+	end_point->rx_data_alerted = false;
+
+	if (rx_frame_length == 0) {
+		htcadebug(
+		    "htca_manage_pending_recvs: buffer available (%d), but no data to recv\n",
+		    epid);
+		/* We have a buffer but there's nothing
+		 * available on the Target to read.
+		 */
+		return 0;
+	}
+
+	/* There is rxdata waiting and a buffer to read it into */
+
+	/* Pull the request buffer off the Pending Recv Queue */
+	spin_lock_irqsave(&end_point->mbox_queue_lock, flags);
+	mbox_request =
+	    (struct htca_mbox_request *)htca_request_deq_head(recv_queue);
+
+	spin_unlock_irqrestore(&end_point->mbox_queue_lock, flags);
+
+	if (!mbox_request)
+		goto done;
+
+	htcadebug("ep#%d receiving frame: %d bytes\n", epid, rx_frame_length);
+
+	spin_lock_irqsave(&target->pending_op_lock, flags);
+	target->pending_recv_mask |= (1 << epid);
+	spin_unlock_irqrestore(&target->pending_op_lock, flags);
+
+	/* Hand off this Mbox Recv request to HIF */
+	mbox_request->actual_length = rx_frame_length;
+	if (htca_recv_request_to_hif(end_point, mbox_request) == HTCA_ERROR) {
+		struct htca_event_info event_info;
+
+		/* TBD: Could requeue this at the HEAD of the
+		 * pending recv queue. Try again later?
+		 */
+
+		/* Frame an event to send to caller */
+		htca_frame_event(&event_info, mbox_request->buffer,
+				 mbox_request->buffer_length,
+				 mbox_request->actual_length, HTCA_ECANCELED,
+				 mbox_request->cookie);
+
+		/* Free the Mailbox request */
+		spin_lock_irqsave(&end_point->mbox_queue_lock, flags);
+		htca_request_enq_tail(&end_point->recv_free_queue,
+				      (struct htca_request *)mbox_request);
+		spin_unlock_irqrestore(&end_point->mbox_queue_lock, flags);
+
+		spin_lock_irqsave(&target->pending_op_lock, flags);
+		target->pending_recv_mask &= ~(1 << epid);
+		spin_unlock_irqrestore(&target->pending_op_lock, flags);
+
+		htca_dispatch_event(target, epid, HTCA_EVENT_BUFFER_RECEIVED,
+				    &event_info);
+		goto done;
+	} else {
+		work_done = 1;
+	}
+
+done:
+	return work_done;
+}
+
+int htca_recv_request_to_hif(struct htca_endpoint *end_point,
+			     struct htca_mbox_request *mbox_request)
+{
+	int status;
+	struct htca_target *target;
+	u32 padded_length;
+	u32 mbox_address;
+	u32 req_type;
+
+	target = end_point->target;
+
+	/* Adjust length for power-of-2 block size */
+	padded_length =
+	    htca_round_up(mbox_request->actual_length + HTCA_HEADER_LEN_MAX,
+			  end_point->block_size);
+
+	req_type = (end_point->block_size > 1) ? HIF_RD_ASYNC_BLOCK_INC
+					       : HIF_RD_ASYNC_BYTE_INC;
+
+	mbox_address = end_point->mbox_start_addr;
+
+	status = hif_read_write(target->hif_handle, mbox_address,
+				&mbox_request->buffer
+				[HTCA_HEADER_LEN_MAX - HTCA_HEADER_LEN],
+				padded_length, req_type, mbox_request);
+
+	if (status == HIF_OK && mbox_request->req.completion_cb) {
+		mbox_request->req.completion_cb(
+		    (struct htca_request *)mbox_request, HTCA_OK);
+		/* htca_recv_compl */
+	} else if (status == HIF_PENDING) {
+		/* Will complete later */
+	} else { /* HIF error */
+		return HTCA_ERROR;
+	}
+
+	return HTCA_OK;
+}
diff --git a/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_send.c b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_send.c
new file mode 100644
index 0000000..ebccf72
--- /dev/null
+++ b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_send.c
@@ -0,0 +1,392 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/completion.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/spinlock_types.h>
+#include <linux/wait.h>
+
+#include "../hif_sdio/hif.h"
+#include "htca.h"
+#include "htca_mbox_internal.h"
+
+/* Decide when an endpoint is low on tx credits and we should
+ * initiate a credit refresh. If this is set very low, we may
+ * exhaust credits entirely and pause while we wait for credits
+ * to be reaped from the Target. If set very high we may end
+ * up spending excessive time trying to reap when nothing is
+ * available.
+ *
+ * TBD: We could make this something like a percentage of the
+ * most credits we've ever seen on this endpoint. Or make it
+ * a value that automatically adjusts -- increase by one whenever
+ * we exhaust credits; decrease by one whenever a CREDIT_REFRESH
+ * fails to reap any credits.
+ * For now, wait until credits are completely exhausted; then
+ * initiate a credit refresh cycle.
+ */
+#define HTCA_EP_CREDITS_ARE_LOW(_endp) ((_endp)->tx_credits_available == 0)
+
+/* Pull as many Mailbox Send Requests off of the PendingSend queue
+ * as we can (must have a credit for each send) and hand off the
+ * request to HIF.
+ *
+ * This function returns when we exhaust Send Requests OR when we
+ * exhaust credits.
+ *
+ * If we are low on credits, it starts a credit refresh cycle.
+ *
+ * Returns 0 if nothing was send to HIF
+ * returns 1 if at least one request was sent to HIF
+ */
+int htca_manage_pending_sends(struct htca_target *target, int epid)
+{
+	struct htca_endpoint *end_point;
+	struct htca_request_queue *send_queue;
+	struct htca_mbox_request *mbox_request;
+	unsigned long flags;
+	u8 tx_credits_available;
+	int work_done = 0;
+
+	end_point = &target->end_point[epid];
+	send_queue = &end_point->send_pending_queue;
+
+	/* Transmit messages as long as we have both something to send
+	 * tx credits that permit us to send
+	 */
+	while (!HTCA_IS_QUEUE_EMPTY(send_queue)) {
+		spin_lock_irqsave(&end_point->tx_credit_lock, flags);
+		tx_credits_available = end_point->tx_credits_available;
+		if (tx_credits_available)
+			end_point->tx_credits_available--;
+		spin_unlock_irqrestore(&end_point->tx_credit_lock, flags);
+		htcadebug("(ep=%d) tx_credits_available=%d\n",
+			  epid, tx_credits_available);
+		if (!tx_credits_available) {
+			/* We exhausted tx credits */
+			break;
+		}
+
+		/* Get the request buffer from the Pending Send Queue */
+		spin_lock_irqsave(&end_point->mbox_queue_lock, flags);
+		mbox_request =
+		    (struct htca_mbox_request *)htca_request_deq_head(
+			send_queue);
+
+		spin_unlock_irqrestore(&end_point->mbox_queue_lock, flags);
+
+		if (!mbox_request)
+			break;
+
+		/* Hand off this Mbox Send request to HIF */
+		if (htca_send_request_to_hif(end_point, mbox_request) ==
+		    HTCA_ERROR) {
+			struct htca_event_info event_info;
+
+			/* TBD: Could requeue this at the HEAD of the
+			 * pending send queue. Try again later?
+			 */
+
+			/* Restore tx credit, since it was not used */
+			spin_lock_irqsave(&end_point->tx_credit_lock, flags);
+			end_point->tx_credits_available++;
+			spin_unlock_irqrestore(&end_point->tx_credit_lock,
+					       flags);
+
+			/* Frame an event to send to caller */
+			htca_frame_event(&event_info, mbox_request->buffer,
+					 mbox_request->buffer_length,
+					 mbox_request->actual_length,
+					 HTCA_ECANCELED,
+					 mbox_request->cookie);
+
+			/* Free the Mailbox request */
+			spin_lock_irqsave(&end_point->mbox_queue_lock, flags);
+			htca_request_enq_tail(
+			    &end_point->send_free_queue,
+			    (struct htca_request *)mbox_request);
+			spin_unlock_irqrestore(&end_point->mbox_queue_lock,
+					       flags);
+
+			htca_dispatch_event(
+			    target, epid, HTCA_EVENT_BUFFER_SENT, &event_info);
+			goto done;
+		}
+		work_done = 1;
+	}
+
+	htcadebug("ep=%d credsAvail=%d toReap=%d\n",
+		  epid, end_point->tx_credits_available,
+		  end_point->tx_credits_to_reap);
+	if (HTCA_EP_CREDITS_ARE_LOW(end_point)) {
+		target->enb.counter_int_status_enb |= (0x10 << epid);
+		if (end_point->tx_credits_to_reap)
+			htca_credit_refresh_start(end_point);
+	} else {
+		target->enb.counter_int_status_enb &= ~(0x10 << epid);
+	}
+
+done:
+	return work_done;
+}
+
+/* Send one send request to HIF.
+ *
+ * Called from the HTCA task while processing requests from
+ * an endpoint's pendingSendQueue.
+ *
+ * Note: May consider calling this in the context of a process
+ * submitting a new Send Request (i.e. when nothing else is
+ * pending and credits are available). This would save the
+ * cost of context switching to the HTCA Work Task; but it would
+ * require additional synchronization and would add some
+ * complexity. For the high throughput case this optimization
+ * would not help since we are likely to have requests
+ * pending which must be submitted to HIF in the order received.
+ */
+int htca_send_request_to_hif(struct htca_endpoint *end_point,
+			     struct htca_mbox_request *mbox_request)
+{
+	int status;
+	struct htca_target *target;
+	u32 padded_length;
+	u32 mbox_address;
+	u32 req_type;
+
+	target = end_point->target;
+
+	/* Adjust length for power-of-2 block size */
+	padded_length =
+	    htca_round_up(mbox_request->actual_length + HTCA_HEADER_LEN_MAX,
+			  end_point->block_size);
+
+	/* Prepend the message's actual length to the  outgoing message.
+	 * Caller is REQUIRED to leave HTCA_HEADER_LEN_MAX bytes before
+	 * the message for this purpose (of which the first HTCA_HEADER_LEN
+	 * bytes are actually used).
+	 *
+	 * TBD: We may enhance HIF so that a single write request
+	 * may have TWO consecutive components: one for the HTCA header
+	 * and another for the payload. This would remove the burden
+	 * on callers to reserve space in their buffer for HTCA.
+	 *
+	 * TBD: Since the messaging layer sitting on top of HTCA may
+	 * have this same issue it may make sense to allow a Send
+	 * to pass in a "header buffer" along with a "payload buffer".
+	 * So two buffers (or more generally, a list of buffers)
+	 * rather than one on each call.  These buffers would be
+	 * guaranteed to be sent to HIF as a group and they would
+	 * be sent over SDIO back to back.
+	 */
+	mbox_request->buffer -= HTCA_HEADER_LEN_MAX;
+
+	if (HTCA_HEADER_LEN_MAX > HTCA_HEADER_LEN) {
+		/* Sanity: clear padding bytes, if used */
+		memset(&mbox_request->buffer[HTCA_HEADER_LEN], 0,
+		       HTCA_HEADER_LEN_MAX - HTCA_HEADER_LEN);
+	}
+	/* Target receives length in LittleEndian byte order
+	 * regardeless of Host endianness.
+	 */
+	mbox_request->buffer[0] = mbox_request->actual_length & 0xff;
+	mbox_request->buffer[1] = (mbox_request->actual_length >> 8) & 0xff;
+
+	req_type = (end_point->block_size > 1) ? HIF_WR_ASYNC_BLOCK_INC
+					       : HIF_WR_ASYNC_BYTE_INC;
+
+	/* Arrange for last byte of the message to generate an
+	 * EndOfMessage interrupt to the Target.
+	 */
+	mbox_address = end_point->mbox_end_addr - padded_length;
+
+	/* Send the request to HIF */
+	status = hif_read_write(target->hif_handle, mbox_address,
+				mbox_request->buffer, padded_length, req_type,
+				mbox_request);
+
+	if (status == HIF_OK && mbox_request->req.completion_cb) {
+		mbox_request->req.completion_cb(
+		    (struct htca_request *)mbox_request, HTCA_OK);
+		/* htcaSendCompletionCB */
+	} else if (status == HIF_PENDING) {
+		/* Will complete later */
+	} else { /* HIF error */
+		/* Restore mbox_request buffer */
+		mbox_request->buffer += HTCA_HEADER_LEN_MAX;
+		return HTCA_ERROR;
+	}
+
+	return HTCA_OK;
+}
+
+/* Start a credit refresh cycle. Credits will appear in
+ * end_point->tx_credits_available when this refresh completes.
+ *
+ * Called in the context of the work_task when we are unable
+ * to send any more requests because credits are exhausted.
+ * Also called from HIF completion's context when a credit
+ * interrupt occurs.
+ *
+ * TBD: Consider HTCA v2 features: Quartz FW can send
+ * in-band TX Credit hint
+ * RX Length hint
+ * interrupt status registers
+ * as opportunistic trailer(s) on an RX message.
+ * This increases code complexity but may reduce overhead
+ * since we may reduce the number of explicit SDIO register
+ * read operations which are relatively expensive "byte basis"
+ * operations.
+ */
+int htca_credit_refresh_start(struct htca_endpoint *end_point)
+{
+	u8 end_point_id;
+	int status;
+	struct htca_target *target;
+	struct htca_reg_request *reg_request;
+	unsigned long flags;
+	bool already_in_progress;
+	u32 address;
+
+	htcadebug("Enter\n");
+
+	spin_lock_irqsave(&end_point->tx_credit_lock, flags);
+	already_in_progress = end_point->tx_credit_refresh_in_progress;
+	end_point->tx_credit_refresh_in_progress = true;
+	spin_unlock_irqrestore(&end_point->tx_credit_lock, flags);
+
+	if (already_in_progress)
+		return 0;
+
+	target = end_point->target;
+	end_point_id = get_endpoint_id(end_point);
+	htcadebug("on endpoint %d\n", end_point_id);
+
+	spin_lock_irqsave(&target->reg_queue_lock, flags);
+	reg_request = (struct htca_reg_request *)htca_request_deq_head(
+	    &target->reg_free_queue);
+	spin_unlock_irqrestore(&target->reg_queue_lock, flags);
+
+	if (!reg_request) {
+		WARN_ON(1);
+		return 1;
+	}
+
+	if (WARN_ON(reg_request->purpose != UNUSED_PURPOSE))
+		return 1;
+
+	reg_request->buffer = NULL;
+	reg_request->length = 0;
+	reg_request->purpose = CREDIT_REFRESH;
+	reg_request->epid = end_point_id;
+
+	address = get_reg_addr(TX_CREDIT_COUNTER_DECREMENT_REG, end_point_id);
+
+	/* Note: reading many times FROM a FIXed register address, the
+	 * "atomic decrement address". The function htca_credit_refresh_compl
+	 * examines the results upon completion.
+	 */
+	status = hif_read_write(
+	    target->hif_handle, address, reg_request->u.credit_dec_results,
+	    HTCA_TX_CREDITS_REAP_MAX, HIF_RD_ASYNC_BYTE_FIX, reg_request);
+	if (status == HIF_OK && reg_request->req.completion_cb) {
+		reg_request->req.completion_cb(
+		    (struct htca_request *)reg_request, HIF_OK);
+		/* htca_credit_refresh_compl */
+	} else if (status == HIF_PENDING) {
+		/* Will complete later */
+	} else { /* HIF error */
+		WARN_ON(1);
+	}
+	return 1;
+}
+
+/* Used during Configuration Negotiation at startup
+ * to configure max message sizes for each endpoint.
+ *
+ * Returns true if all endpoints have been configured,
+ * by this pass and/or all earlier calls. (Typically
+ * there should be only a single call which enables
+ * all endpoints at once.)
+ *
+ * Returns false if at least one endpoint has not
+ * yet been configured.
+ */
+bool htca_negotiate_config(struct htca_target *target)
+{
+	int status;
+	struct htca_endpoint *end_point;
+	u32 address;
+	int enb_count = 0;
+	int ep;
+
+	htcadebug("Enter\n");
+
+	/* The Target should have posted 1 credit to
+	 * each endpoint by the time we reach here.
+	 */
+	for (ep = 0; ep < HTCA_NUM_MBOX; ep++) {
+		end_point = &target->end_point[ep];
+		if (end_point->enabled) {
+			/* This endpoint was already enabled */
+			enb_count++;
+			continue;
+		}
+		htcadebug("try epid=%d\n", ep);
+
+		address = get_reg_addr(TX_CREDIT_COUNTER_DECREMENT_REG, ep);
+		end_point->tx_credits_available = 0;
+		status =
+		    hif_read_write(target->hif_handle, address,
+				   (u8 *)&end_point->tx_credits_available,
+				   1, HIF_RD_SYNC_BYTE_FIX, NULL);
+		if (status != HIF_OK) {
+			htcadebug("DBG: address=0x%08x status=%d\n", address,
+				  status);
+		}
+		if (WARN_ON(status != HIF_OK))
+			return false;
+
+		if (!end_point->tx_credits_available) {
+			/* not yet ready -- no credit posted.  Odd case. */
+			continue;
+		}
+		if (WARN_ON(end_point->tx_credits_available != 1))
+			return false;
+
+		end_point->tx_credits_available--;
+
+		/* TBD: Tacitly assumes LittleEndian Host.
+		 * This -- rather than an explicit Host interrupt -- is
+		 * what should trigger Target to fetch blocksize.
+		 */
+		htcadebug("good to go epid=%d\n", ep);
+
+		/* "Negotiate" the message size for this endpoint by writing
+		 * the maximum message size (and trigger EOM).
+		 */
+		address =
+		    end_point->mbox_end_addr - sizeof(end_point->max_msg_sz);
+		status = hif_read_write(target->hif_handle, address,
+					(u8 *)&end_point->max_msg_sz,
+					sizeof(end_point->max_msg_sz),
+					HIF_WR_SYNC_BYTE_INC, NULL);
+		if (WARN_ON(status != HIF_OK))
+			return false;
+
+		end_point->enabled = true;
+		enb_count++;
+	}
+
+	htcadebug("enb_count=%d\n", enb_count);
+	return (enb_count == HTCA_NUM_MBOX);
+}
diff --git a/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_task.c b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_task.c
new file mode 100644
index 0000000..6598cba
--- /dev/null
+++ b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_task.c
@@ -0,0 +1,340 @@
+/* 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.
+ */
+
+/* Implementation of Host Target Communication tasks,
+ * WorkTask and compl_task, which are used to manage
+ * the Mbox Pending Queues.
+ *
+ * A mailbox Send request is queued in arrival order on
+ * a per-mailbox Send queue until a credit is available
+ * from the Target. Requests in this queue are
+ * waiting for the Target to provide tx credits (i.e. recv
+ * buffers on the Target-side).
+ *
+ * A mailbox Recv request is queued in arrival order on
+ * a per-mailbox Recv queue until a message is available
+ * to be read. So requests in this queue are waiting for
+ * the Target to provide rx data.
+ *
+ * htca_work_task dequeues requests from the SendPendingQueue
+ * (once credits are available) and dequeues requests from
+ * the RecvPendingQueue (once rx data is available) and
+ * hands them to HIF for processing.
+ *
+ * htca_compl_task handles completion processing after
+ * HIF completes a request.
+ *
+ * The main purpose of these tasks is to provide a
+ * suitable suspendable context for processing requests
+ * and completions.
+ */
+
+#include <linux/completion.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/spinlock_types.h>
+#include <linux/wait.h>
+
+#include "../hif_sdio/hif.h"
+#include "htca.h"
+#include "htca_mbox_internal.h"
+
+/* Wakeup the htca_work_task.
+ *
+ * Invoked whenever send/recv state changes:
+ * new Send buffer added to the send_pending_queue
+ * new Recv buffer added to the recv_pending_queue
+ * tx credits are reaped
+ * rx data available recognized
+ */
+void htca_work_task_poke(struct htca_target *target)
+{
+	target->work_task_has_work = true;
+	wake_up_interruptible_sync(&target->work_task_wait);
+}
+
+/* Body of the htca_work_task, which hands Send and
+ * Receive requests to HIF.
+ */
+static int htca_work_task_core(struct htca_target *target)
+{
+	int ep;
+	int work_done = 0;
+
+	/* TBD: We might consider alternative ordering policies, here,
+	 * between Sends and Recvs and among mailboxes. The current
+	 * algorithm is simple.
+	 */
+
+	/* Process sends/recvs */
+	for (ep = 0; ep < HTCA_NUM_MBOX; ep++) {
+		htcadebug("Call (%d)\n", ep);
+		work_done += htca_manage_pending_sends(target, ep);
+		htcadebug("Call (%d)\n", ep);
+		work_done += htca_manage_pending_recvs(target, ep);
+	}
+
+	return work_done;
+}
+
+/* Only this work_task is permitted to update
+ * interrupt enables. That restriction eliminates
+ * complex race conditions.
+ */
+static int htca_work_task(void *param)
+{
+	struct htca_target *target = (struct htca_target *)param;
+
+	/* set_user_nice(current, -3); */
+	set_current_state(TASK_INTERRUPTIBLE);
+
+	for (;;) {
+		htcadebug("top of loop. intr_state=%d\n", target->intr_state);
+		/* Wait for htca_work_task_poke */
+		wait_event_interruptible(target->work_task_wait,
+					 target->work_task_has_work);
+
+		if (target->work_task_shutdown)
+			break; /* htcaTaskStop invoked */
+
+		if (!target->work_task_has_work)
+			break; /* exit, if this task was interrupted */
+
+		/* reset before we start work */
+		target->work_task_has_work = false;
+		barrier();
+
+		if (target->need_start_polling) {
+			/* reset for next time */
+			target->need_start_polling = 0;
+			target->intr_state = HTCA_POLL;
+			htca_update_intr_enbs(target, 1);
+		}
+
+		while (htca_work_task_core(target))
+			;
+
+		if (target->pending_recv_mask ||
+		    target->pending_register_refresh) {
+			continue;
+		}
+
+		/* When a Recv completes, it sets need_register_refresh=1
+		 * and pokes the work_task.
+		 *
+		 * We won't actually initiate a register refresh until
+		 * pending recvs on ALL eps have completed. This may
+		 * increase latency slightly but it increases efficiency
+		 * and reduces chatter which should improve throughput.
+		 * Note that even though we don't initiate the register
+		 * refresh immediately, SDIO is still 100% busy doing
+		 * useful work. The refresh is issued shortly after.
+		 */
+		if (target->need_register_refresh) {
+			/* Continue to poll. When the RegsiterRefresh
+			 * completes, the WorkTask will be poked.
+			 */
+			target->need_register_refresh = 0;
+			htca_register_refresh_start(target);
+			continue;
+		}
+
+		/* If more work has arrived since we last checked,
+		 * make another pass.
+		 */
+		if (target->work_task_has_work)
+			continue;
+
+		/* As long as we are constantly refreshing register
+		 * state and reprocessing, there is no need to
+		 * enable interrupts. We are essentially POLLING for
+		 * interrupts anyway. But if
+		 * -we were in POLL mode and
+		 * -we have processed all outstanding sends/recvs and
+		 * -there are no PENDING recv operations and
+		 * -there is no pending register refresh (so
+		 * no recv operations have completed since the
+		 * last time we refreshed register state)
+		 * then we switch to INTERRUPT mode and re-enable
+		 * Target-side interrupts.
+		 *
+		 * We'll sleep until poked:
+		 * -DSR handler receives an interrupt
+		 * -application enqueues a new send/recv buffer
+		 * We must also UPDATE interrupt enables even if we
+		 * were already in INTERRUPT mode, since some bits
+		 * may have changed.
+		 */
+		if (target->intr_state == HTCA_POLL) {
+			target->intr_state = HTCA_INTERRUPT;
+			htca_update_intr_enbs(target, 0);
+		}
+	}
+	complete_and_exit(&target->work_task_completion, 0);
+
+	return 0;
+}
+
+int htca_work_task_start(struct htca_target *target)
+{
+	int status = HTCA_ERROR;
+
+	if (mutex_lock_interruptible(&target->task_mutex))
+		return HTCA_ERROR; /* interrupted */
+
+	if (target->work_task)
+		goto done; /* already started */
+
+	target->work_task = kthread_create(htca_work_task, target, "htcaWork");
+	if (!target->work_task)
+		goto done; /* Failed to create task */
+
+	target->work_task_shutdown = false;
+	init_waitqueue_head(&target->work_task_wait);
+	init_completion(&target->work_task_completion);
+	wake_up_process(target->work_task);
+	status = HTCA_OK;
+
+done:
+	mutex_unlock(&target->task_mutex);
+	return status;
+}
+
+void htca_work_task_stop(struct htca_target *target)
+{
+	if (mutex_lock_interruptible(&target->task_mutex))
+		return; /* interrupted */
+
+	if (!target->work_task)
+		goto done;
+
+	target->work_task_shutdown = true;
+	htca_work_task_poke(target);
+	wait_for_completion(&target->work_task_completion);
+	target->work_task = NULL;
+
+done:
+	mutex_unlock(&target->task_mutex);
+}
+
+/* Wakeup the compl_task.
+ * Invoked after adding a new completion to the compl_queue.
+ */
+void htca_compl_task_poke(struct htca_target *target)
+{
+	target->compl_task_has_work = true;
+	wake_up_interruptible_sync(&target->compl_task_wait);
+}
+
+static int htca_manage_compl(struct htca_target *target)
+{
+	struct htca_request *req;
+	unsigned long flags;
+
+	/* Pop a request from the completion queue */
+	spin_lock_irqsave(&target->compl_queue_lock, flags);
+	req = htca_request_deq_head(&target->compl_queue);
+	spin_unlock_irqrestore(&target->compl_queue_lock, flags);
+
+	if (!req)
+		return 0; /* nothing to do */
+
+	/* Invoke request's corresponding completion function */
+	if (req->completion_cb)
+		req->completion_cb(req, req->status);
+
+	return 1;
+}
+
+static int htca_compl_task(void *param)
+{
+	struct htca_target *target = (struct htca_target *)param;
+
+	/* set_user_nice(current, -3); */
+	set_current_state(TASK_INTERRUPTIBLE);
+
+	for (;;) {
+		/* Wait for htca_compl_task_poke */
+		wait_event_interruptible(target->compl_task_wait,
+					 target->compl_task_has_work);
+		if (target->compl_task_shutdown)
+			break; /* htcaTaskStop invoked */
+
+		if (!target->compl_task_has_work)
+			break; /* exit, if this task was interrupted */
+
+		/* reset before we start work */
+		target->compl_task_has_work = false;
+		barrier();
+
+		/* TBD: We could try to prioritize completions rather than
+		 * handle them strictly in order. Could use separate queues for
+		 * register completions and mailbox completion on each endpoint.
+		 * In general, completion processing is expected to be short
+		 * so this probably isn't worth the additional complexity.
+		 */
+		{
+			int did_work;
+
+			do {
+				did_work = htca_manage_compl(target);
+			} while (did_work);
+		}
+	}
+	complete_and_exit(&target->compl_cask_completion, 0);
+
+	return 0;
+}
+
+int htca_compl_task_start(struct htca_target *target)
+{
+	int status = HTCA_ERROR;
+
+	if (mutex_lock_interruptible(&target->task_mutex))
+		return HTCA_ERROR; /* interrupted */
+
+	if (target->compl_task)
+		goto done; /* already started */
+
+	target->compl_task =
+	    kthread_create(htca_compl_task, target, "htcaCompl");
+	if (!target->compl_task)
+		goto done; /* Failed to create task */
+
+	target->compl_task_shutdown = false;
+	init_waitqueue_head(&target->compl_task_wait);
+	init_completion(&target->compl_cask_completion);
+	wake_up_process(target->compl_task);
+	status = HTCA_OK;
+
+done:
+	mutex_unlock(&target->task_mutex);
+	return status;
+}
+
+void htca_compl_task_stop(struct htca_target *target)
+{
+	if (mutex_lock_interruptible(&target->task_mutex))
+		return; /* interrupted */
+
+	if (!target->compl_task)
+		goto done;
+
+	target->compl_task_shutdown = true;
+	htca_compl_task_poke(target);
+	wait_for_completion(&target->compl_cask_completion);
+	target->compl_task = NULL;
+
+done:
+	mutex_unlock(&target->task_mutex);
+}
diff --git a/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_utils.c b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_utils.c
new file mode 100644
index 0000000..4cf137c
--- /dev/null
+++ b/drivers/net/wireless/qca402x/htca_mbox/htca_mbox_utils.c
@@ -0,0 +1,182 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/completion.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/spinlock_types.h>
+#include <linux/wait.h>
+
+#include "../hif_sdio/hif.h"
+#include "htca.h"
+#include "htca_mbox_internal.h"
+
+/* HTCA utility routines  */
+
+/* Invoked when shutting down */
+void htca_mbox_queue_flush(struct htca_endpoint *end_point,
+			   struct htca_request_queue *pending_queue,
+			   struct htca_request_queue *free_queue,
+			   u8 event_id)
+{
+	struct htca_event_info event_info;
+	u8 end_point_id;
+	struct htca_target *target;
+	struct htca_mbox_request *mbox_request;
+	unsigned long flags;
+
+	target = end_point->target;
+	end_point_id = get_endpoint_id(end_point);
+
+	spin_lock_irqsave(&end_point->mbox_queue_lock, flags);
+	for (;;) {
+		mbox_request =
+		    (struct htca_mbox_request *)htca_request_deq_head(
+			pending_queue);
+		spin_unlock_irqrestore(&end_point->mbox_queue_lock, flags);
+
+		if (!mbox_request)
+			break;
+
+		htca_frame_event(&event_info, mbox_request->buffer,
+				 mbox_request->buffer_length, 0, HTCA_ECANCELED,
+				 mbox_request->cookie);
+
+		htca_dispatch_event(target, end_point_id, event_id,
+				    &event_info);
+
+		/* Recycle the request */
+		spin_lock_irqsave(&end_point->mbox_queue_lock, flags);
+		htca_request_enq_tail(free_queue,
+				      (struct htca_request *)mbox_request);
+	}
+	spin_unlock_irqrestore(&end_point->mbox_queue_lock, flags);
+}
+
+struct htca_target *htca_target_instance(int i)
+{
+	return htca_target_list[i];
+}
+
+void htca_target_instance_add(struct htca_target *target)
+{
+	int i;
+
+	for (i = 0; i < HTCA_NUM_DEVICES_MAX; i++) {
+		if (!htca_target_list[i]) {
+			htca_target_list[i] = target;
+			break;
+		}
+	}
+	WARN_ON(i >= HTCA_NUM_DEVICES_MAX);
+}
+
+void htca_target_instance_remove(struct htca_target *target)
+{
+	int i;
+
+	for (i = 0; i < HTCA_NUM_DEVICES_MAX; i++) {
+		if (htca_target_list[i] == target) {
+			htca_target_list[i] = NULL;
+			break;
+		}
+	}
+	WARN_ON(i >= HTCA_NUM_DEVICES_MAX);
+}
+
+/* Add a request to the tail of a queue.
+ * Caller must handle any locking required.
+ * TBD: Use Linux queue support
+ */
+void htca_request_enq_tail(struct htca_request_queue *queue,
+			   struct htca_request *req)
+{
+	req->next = NULL;
+
+	if (queue->tail)
+		queue->tail->next = (void *)req;
+	else
+		queue->head = req;
+
+	queue->tail = req;
+}
+
+/* Remove a request from the start of a queue.
+ * Caller must handle any locking required.
+ * TBD: Use Linux queue support
+ * TBD: If cannot allocate from FREE queue, caller may add more elements.
+ */
+struct htca_request *htca_request_deq_head(struct htca_request_queue *queue)
+{
+	struct htca_request *req;
+
+	req = queue->head;
+	if (!req)
+		return NULL;
+
+	queue->head = req->next;
+	if (!queue->head)
+		queue->tail = NULL;
+	req->next = NULL;
+
+	return req;
+}
+
+/* Start a Register Refresh cycle.
+ *
+ * Submits a request to fetch ALL relevant registers from Target.
+ * When this completes, we'll take actions based on the new
+ * register values.
+ */
+void htca_register_refresh_start(struct htca_target *target)
+{
+	int status;
+	struct htca_reg_request *reg_request;
+	u32 address;
+	unsigned long flags;
+
+	htcadebug("Enter\n");
+	spin_lock_irqsave(&target->reg_queue_lock, flags);
+	reg_request = (struct htca_reg_request *)htca_request_deq_head(
+	    &target->reg_free_queue);
+	spin_unlock_irqrestore(&target->reg_queue_lock, flags);
+	if (!reg_request) {
+		WARN_ON(1);
+		return;
+	}
+	if (WARN_ON(reg_request->purpose != UNUSED_PURPOSE))
+		return;
+
+	spin_lock_irqsave(&target->pending_op_lock, flags);
+	target->pending_register_refresh++;
+	spin_unlock_irqrestore(&target->pending_op_lock, flags);
+
+	reg_request->buffer = (u8 *)&reg_request->u.reg_table;
+	reg_request->length = sizeof(reg_request->u.reg_table);
+	reg_request->purpose = INTR_REFRESH;
+	reg_request->epid = 0; /* not used */
+
+	address = get_reg_addr(ALL_STATUS_REG, ENDPOINT_UNUSED);
+	status = hif_read_write(target->hif_handle, address,
+				&reg_request->u.reg_table,
+				sizeof(reg_request->u.reg_table),
+				HIF_RD_ASYNC_BYTE_INC, reg_request);
+	if (status == HIF_OK && reg_request->req.completion_cb) {
+		reg_request->req.completion_cb(
+		    (struct htca_request *)reg_request, HIF_OK);
+		/* htca_register_refresh_compl */
+	} else if (status == HIF_PENDING) {
+		/* Will complete later */
+	} else { /* HIF error */
+		WARN_ON(1);
+	}
+}
diff --git a/drivers/net/wireless/qca402x/htca_mbox/mbox_host_reg.h b/drivers/net/wireless/qca402x/htca_mbox/mbox_host_reg.h
new file mode 100644
index 0000000..81ce632
--- /dev/null
+++ b/drivers/net/wireless/qca402x/htca_mbox/mbox_host_reg.h
@@ -0,0 +1,412 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MBOX_HOST_REG_REG_H_
+#define _MBOX_HOST_REG_REG_H_
+
+/* TBD: REMOVE things that are not needed, especially Diag Window */
+
+#define HOST_INT_STATUS_ADDRESS 0x00000400
+#define HOST_INT_STATUS_OFFSET 0x00000400
+#define HOST_INT_STATUS_ERROR_MSB 7
+#define HOST_INT_STATUS_ERROR_LSB 7
+#define HOST_INT_STATUS_ERROR_MASK 0x00000080
+#define HOST_INT_STATUS_ERROR_GET(x) \
+	(((x) & HOST_INT_STATUS_ERROR_MASK) >> HOST_INT_STATUS_ERROR_LSB)
+#define HOST_INT_STATUS_ERROR_SET(x) \
+	(((x) << HOST_INT_STATUS_ERROR_LSB) & HOST_INT_STATUS_ERROR_MASK)
+#define HOST_INT_STATUS_CPU_MSB 6
+#define HOST_INT_STATUS_CPU_LSB 6
+#define HOST_INT_STATUS_CPU_MASK 0x00000040
+#define HOST_INT_STATUS_CPU_GET(x) \
+	(((x) & HOST_INT_STATUS_CPU_MASK) >> HOST_INT_STATUS_CPU_LSB)
+#define HOST_INT_STATUS_CPU_SET(x) \
+	(((x) << HOST_INT_STATUS_CPU_LSB) & HOST_INT_STATUS_CPU_MASK)
+#define HOST_INT_STATUS_DRAGON_INT_MSB 5
+#define HOST_INT_STATUS_DRAGON_INT_LSB 5
+#define HOST_INT_STATUS_DRAGON_INT_MASK 0x00000020
+#define HOST_INT_STATUS_DRAGON_INT_GET(x) \
+	(((x) & HOST_INT_STATUS_DRAGON_INT_MASK) >> \
+	 HOST_INT_STATUS_DRAGON_INT_LSB)
+#define HOST_INT_STATUS_DRAGON_INT_SET(x) \
+	(((x) << HOST_INT_STATUS_DRAGON_INT_LSB) & \
+	 HOST_INT_STATUS_DRAGON_INT_MASK)
+#define HOST_INT_STATUS_COUNTER_MSB 4
+#define HOST_INT_STATUS_COUNTER_LSB 4
+#define HOST_INT_STATUS_COUNTER_MASK 0x00000010
+#define HOST_INT_STATUS_COUNTER_GET(x) \
+	(((x) & HOST_INT_STATUS_COUNTER_MASK) >> HOST_INT_STATUS_COUNTER_LSB)
+#define HOST_INT_STATUS_COUNTER_SET(x) \
+	(((x) << HOST_INT_STATUS_COUNTER_LSB) & HOST_INT_STATUS_COUNTER_MASK)
+#define HOST_INT_STATUS_MBOX_DATA_MSB 3
+#define HOST_INT_STATUS_MBOX_DATA_LSB 0
+#define HOST_INT_STATUS_MBOX_DATA_MASK 0x0000000f
+#define HOST_INT_STATUS_MBOX_DATA_GET(x) \
+	(((x) & HOST_INT_STATUS_MBOX_DATA_MASK) >> \
+						HOST_INT_STATUS_MBOX_DATA_LSB)
+#define HOST_INT_STATUS_MBOX_DATA_SET(x) \
+	(((x) << HOST_INT_STATUS_MBOX_DATA_LSB) & \
+	 HOST_INT_STATUS_MBOX_DATA_MASK)
+
+#define CPU_INT_STATUS_ADDRESS 0x00000401
+#define CPU_INT_STATUS_OFFSET 0x00000401
+#define CPU_INT_STATUS_BIT_MSB 7
+#define CPU_INT_STATUS_BIT_LSB 0
+#define CPU_INT_STATUS_BIT_MASK 0x000000ff
+#define CPU_INT_STATUS_BIT_GET(x) \
+	(((x) & CPU_INT_STATUS_BIT_MASK) >> CPU_INT_STATUS_BIT_LSB)
+#define CPU_INT_STATUS_BIT_SET(x) \
+	(((x) << CPU_INT_STATUS_BIT_LSB) & CPU_INT_STATUS_BIT_MASK)
+
+#define ERROR_INT_STATUS_ADDRESS 0x00000402
+#define ERROR_INT_STATUS_OFFSET 0x00000402
+#define ERROR_INT_STATUS_SPI_MSB 3
+#define ERROR_INT_STATUS_SPI_LSB 3
+#define ERROR_INT_STATUS_SPI_MASK 0x00000008
+#define ERROR_INT_STATUS_SPI_GET(x) \
+	(((x) & ERROR_INT_STATUS_SPI_MASK) >> ERROR_INT_STATUS_SPI_LSB)
+#define ERROR_INT_STATUS_SPI_SET(x) \
+	(((x) << ERROR_INT_STATUS_SPI_LSB) & ERROR_INT_STATUS_SPI_MASK)
+#define ERROR_INT_STATUS_WAKEUP_MSB 2
+#define ERROR_INT_STATUS_WAKEUP_LSB 2
+#define ERROR_INT_STATUS_WAKEUP_MASK 0x00000004
+#define ERROR_INT_STATUS_WAKEUP_GET(x) \
+	(((x) & ERROR_INT_STATUS_WAKEUP_MASK) >> ERROR_INT_STATUS_WAKEUP_LSB)
+#define ERROR_INT_STATUS_WAKEUP_SET(x) \
+	(((x) << ERROR_INT_STATUS_WAKEUP_LSB) & ERROR_INT_STATUS_WAKEUP_MASK)
+#define ERROR_INT_STATUS_RX_UNDERFLOW_MSB 1
+#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB 1
+#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK 0x00000002
+#define ERROR_INT_STATUS_RX_UNDERFLOW_GET(x) \
+	(((x) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) >> \
+	 ERROR_INT_STATUS_RX_UNDERFLOW_LSB)
+#define ERROR_INT_STATUS_RX_UNDERFLOW_SET(x) \
+	(((x) << ERROR_INT_STATUS_RX_UNDERFLOW_LSB) & \
+	 ERROR_INT_STATUS_RX_UNDERFLOW_MASK)
+#define ERROR_INT_STATUS_TX_OVERFLOW_MSB 0
+#define ERROR_INT_STATUS_TX_OVERFLOW_LSB 0
+#define ERROR_INT_STATUS_TX_OVERFLOW_MASK 0x00000001
+#define ERROR_INT_STATUS_TX_OVERFLOW_GET(x) \
+	(((x) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) >> \
+	 ERROR_INT_STATUS_TX_OVERFLOW_LSB)
+#define ERROR_INT_STATUS_TX_OVERFLOW_SET(x) \
+	(((x) << ERROR_INT_STATUS_TX_OVERFLOW_LSB) & \
+	 ERROR_INT_STATUS_TX_OVERFLOW_MASK)
+
+#define COUNTER_INT_STATUS_ADDRESS 0x00000403
+#define COUNTER_INT_STATUS_OFFSET 0x00000403
+#define COUNTER_INT_STATUS_COUNTER_MSB 7
+#define COUNTER_INT_STATUS_COUNTER_LSB 0
+#define COUNTER_INT_STATUS_COUNTER_MASK 0x000000ff
+#define COUNTER_INT_STATUS_COUNTER_GET(x) \
+	(((x) & COUNTER_INT_STATUS_COUNTER_MASK) >> \
+	 COUNTER_INT_STATUS_COUNTER_LSB)
+#define COUNTER_INT_STATUS_COUNTER_SET(x) \
+	(((x) << COUNTER_INT_STATUS_COUNTER_LSB) & \
+	 COUNTER_INT_STATUS_COUNTER_MASK)
+
+#define MBOX_FRAME_ADDRESS 0x00000404
+#define MBOX_FRAME_OFFSET 0x00000404
+#define MBOX_FRAME_RX_EOM_MSB 7
+#define MBOX_FRAME_RX_EOM_LSB 4
+#define MBOX_FRAME_RX_EOM_MASK 0x000000f0
+#define MBOX_FRAME_RX_EOM_GET(x) \
+	(((x) & MBOX_FRAME_RX_EOM_MASK) >> MBOX_FRAME_RX_EOM_LSB)
+#define MBOX_FRAME_RX_EOM_SET(x) \
+	(((x) << MBOX_FRAME_RX_EOM_LSB) & MBOX_FRAME_RX_EOM_MASK)
+#define MBOX_FRAME_RX_SOM_MSB 3
+#define MBOX_FRAME_RX_SOM_LSB 0
+#define MBOX_FRAME_RX_SOM_MASK 0x0000000f
+#define MBOX_FRAME_RX_SOM_GET(x) \
+	(((x) & MBOX_FRAME_RX_SOM_MASK) >> MBOX_FRAME_RX_SOM_LSB)
+#define MBOX_FRAME_RX_SOM_SET(x) \
+	(((x) << MBOX_FRAME_RX_SOM_LSB) & MBOX_FRAME_RX_SOM_MASK)
+
+#define RX_LOOKAHEAD_VALID_ADDRESS 0x00000405
+#define RX_LOOKAHEAD_VALID_OFFSET 0x00000405
+#define RX_LOOKAHEAD_VALID_MBOX_MSB 3
+#define RX_LOOKAHEAD_VALID_MBOX_LSB 0
+#define RX_LOOKAHEAD_VALID_MBOX_MASK 0x0000000f
+#define RX_LOOKAHEAD_VALID_MBOX_GET(x) \
+	(((x) & RX_LOOKAHEAD_VALID_MBOX_MASK) >> RX_LOOKAHEAD_VALID_MBOX_LSB)
+#define RX_LOOKAHEAD_VALID_MBOX_SET(x) \
+	(((x) << RX_LOOKAHEAD_VALID_MBOX_LSB) & RX_LOOKAHEAD_VALID_MBOX_MASK)
+
+#define RX_LOOKAHEAD0_ADDRESS 0x00000408
+#define RX_LOOKAHEAD0_OFFSET 0x00000408
+#define RX_LOOKAHEAD0_DATA_MSB 7
+#define RX_LOOKAHEAD0_DATA_LSB 0
+#define RX_LOOKAHEAD0_DATA_MASK 0x000000ff
+#define RX_LOOKAHEAD0_DATA_GET(x) \
+	(((x) & RX_LOOKAHEAD0_DATA_MASK) >> RX_LOOKAHEAD0_DATA_LSB)
+#define RX_LOOKAHEAD0_DATA_SET(x) \
+	(((x) << RX_LOOKAHEAD0_DATA_LSB) & RX_LOOKAHEAD0_DATA_MASK)
+
+#define RX_LOOKAHEAD1_ADDRESS 0x0000040c
+#define RX_LOOKAHEAD1_OFFSET 0x0000040c
+#define RX_LOOKAHEAD1_DATA_MSB 7
+#define RX_LOOKAHEAD1_DATA_LSB 0
+#define RX_LOOKAHEAD1_DATA_MASK 0x000000ff
+#define RX_LOOKAHEAD1_DATA_GET(x) \
+	(((x) & RX_LOOKAHEAD1_DATA_MASK) >> RX_LOOKAHEAD1_DATA_LSB)
+#define RX_LOOKAHEAD1_DATA_SET(x) \
+	(((x) << RX_LOOKAHEAD1_DATA_LSB) & RX_LOOKAHEAD1_DATA_MASK)
+
+#define RX_LOOKAHEAD2_ADDRESS 0x00000410
+#define RX_LOOKAHEAD2_OFFSET 0x00000410
+#define RX_LOOKAHEAD2_DATA_MSB 7
+#define RX_LOOKAHEAD2_DATA_LSB 0
+#define RX_LOOKAHEAD2_DATA_MASK 0x000000ff
+#define RX_LOOKAHEAD2_DATA_GET(x) \
+	(((x) & RX_LOOKAHEAD2_DATA_MASK) >> RX_LOOKAHEAD2_DATA_LSB)
+#define RX_LOOKAHEAD2_DATA_SET(x) \
+	(((x) << RX_LOOKAHEAD2_DATA_LSB) & RX_LOOKAHEAD2_DATA_MASK)
+
+#define RX_LOOKAHEAD3_ADDRESS 0x00000414
+#define RX_LOOKAHEAD3_OFFSET 0x00000414
+#define RX_LOOKAHEAD3_DATA_MSB 7
+#define RX_LOOKAHEAD3_DATA_LSB 0
+#define RX_LOOKAHEAD3_DATA_MASK 0x000000ff
+#define RX_LOOKAHEAD3_DATA_GET(x) \
+	(((x) & RX_LOOKAHEAD3_DATA_MASK) >> RX_LOOKAHEAD3_DATA_LSB)
+#define RX_LOOKAHEAD3_DATA_SET(x) \
+	(((x) << RX_LOOKAHEAD3_DATA_LSB) & RX_LOOKAHEAD3_DATA_MASK)
+
+#define INT_STATUS_ENABLE_ADDRESS 0x00000418
+#define INT_STATUS_ENABLE_OFFSET 0x00000418
+#define INT_STATUS_ENABLE_ERROR_MSB 7
+#define INT_STATUS_ENABLE_ERROR_LSB 7
+#define INT_STATUS_ENABLE_ERROR_MASK 0x00000080
+#define INT_STATUS_ENABLE_ERROR_GET(x) \
+	(((x) & INT_STATUS_ENABLE_ERROR_MASK) >> INT_STATUS_ENABLE_ERROR_LSB)
+#define INT_STATUS_ENABLE_ERROR_SET(x) \
+	(((x) << INT_STATUS_ENABLE_ERROR_LSB) & INT_STATUS_ENABLE_ERROR_MASK)
+#define INT_STATUS_ENABLE_CPU_MSB 6
+#define INT_STATUS_ENABLE_CPU_LSB 6
+#define INT_STATUS_ENABLE_CPU_MASK 0x00000040
+#define INT_STATUS_ENABLE_CPU_GET(x) \
+	(((x) & INT_STATUS_ENABLE_CPU_MASK) >> INT_STATUS_ENABLE_CPU_LSB)
+#define INT_STATUS_ENABLE_CPU_SET(x) \
+	(((x) << INT_STATUS_ENABLE_CPU_LSB) & INT_STATUS_ENABLE_CPU_MASK)
+#define INT_STATUS_ENABLE_DRAGON_INT_MSB 5
+#define INT_STATUS_ENABLE_DRAGON_INT_LSB 5
+#define INT_STATUS_ENABLE_DRAGON_INT_MASK 0x00000020
+#define INT_STATUS_ENABLE_DRAGON_INT_GET(x) \
+	(((x) & INT_STATUS_ENABLE_DRAGON_INT_MASK) >> \
+	 INT_STATUS_ENABLE_DRAGON_INT_LSB)
+#define INT_STATUS_ENABLE_DRAGON_INT_SET(x) \
+	(((x) << INT_STATUS_ENABLE_DRAGON_INT_LSB) & \
+	 INT_STATUS_ENABLE_DRAGON_INT_MASK)
+#define INT_STATUS_ENABLE_COUNTER_MSB 4
+#define INT_STATUS_ENABLE_COUNTER_LSB 4
+#define INT_STATUS_ENABLE_COUNTER_MASK 0x00000010
+#define INT_STATUS_ENABLE_COUNTER_GET(x) \
+	(((x) & INT_STATUS_ENABLE_COUNTER_MASK) >> \
+						INT_STATUS_ENABLE_COUNTER_LSB)
+#define INT_STATUS_ENABLE_COUNTER_SET(x) \
+	(((x) << INT_STATUS_ENABLE_COUNTER_LSB) & \
+	 INT_STATUS_ENABLE_COUNTER_MASK)
+#define INT_STATUS_ENABLE_MBOX_DATA_MSB 3
+#define INT_STATUS_ENABLE_MBOX_DATA_LSB 0
+#define INT_STATUS_ENABLE_MBOX_DATA_MASK 0x0000000f
+#define INT_STATUS_ENABLE_MBOX_DATA_GET(x) \
+	(((x) & INT_STATUS_ENABLE_MBOX_DATA_MASK) >> \
+	 INT_STATUS_ENABLE_MBOX_DATA_LSB)
+#define INT_STATUS_ENABLE_MBOX_DATA_SET(x) \
+	(((x) << INT_STATUS_ENABLE_MBOX_DATA_LSB) & \
+	 INT_STATUS_ENABLE_MBOX_DATA_MASK)
+
+#define CPU_INT_STATUS_ENABLE_ADDRESS 0x00000419
+#define CPU_INT_STATUS_ENABLE_OFFSET 0x00000419
+#define CPU_INT_STATUS_ENABLE_BIT_MSB 7
+#define CPU_INT_STATUS_ENABLE_BIT_LSB 0
+#define CPU_INT_STATUS_ENABLE_BIT_MASK 0x000000ff
+#define CPU_INT_STATUS_ENABLE_BIT_GET(x) \
+	(((x) & CPU_INT_STATUS_ENABLE_BIT_MASK) >> \
+						CPU_INT_STATUS_ENABLE_BIT_LSB)
+#define CPU_INT_STATUS_ENABLE_BIT_SET(x) \
+	(((x) << CPU_INT_STATUS_ENABLE_BIT_LSB) & \
+	 CPU_INT_STATUS_ENABLE_BIT_MASK)
+
+#define ERROR_STATUS_ENABLE_ADDRESS 0x0000041a
+#define ERROR_STATUS_ENABLE_OFFSET 0x0000041a
+#define ERROR_STATUS_ENABLE_WAKEUP_MSB 2
+#define ERROR_STATUS_ENABLE_WAKEUP_LSB 2
+#define ERROR_STATUS_ENABLE_WAKEUP_MASK 0x00000004
+#define ERROR_STATUS_ENABLE_WAKEUP_GET(x) \
+	(((x) & ERROR_STATUS_ENABLE_WAKEUP_MASK) >> \
+	 ERROR_STATUS_ENABLE_WAKEUP_LSB)
+#define ERROR_STATUS_ENABLE_WAKEUP_SET(x) \
+	(((x) << ERROR_STATUS_ENABLE_WAKEUP_LSB) & \
+	 ERROR_STATUS_ENABLE_WAKEUP_MASK)
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MSB 1
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB 1
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK 0x00000002
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_GET(x) \
+	(((x) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) >> \
+	 ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB)
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(x) \
+	(((x) << ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) & \
+	 ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK)
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MSB 0
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB 0
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK 0x00000001
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_GET(x) \
+	(((x) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) >> \
+	 ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB)
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(x) \
+	(((x) << ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) & \
+	 ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK)
+
+#define COUNTER_INT_STATUS_ENABLE_ADDRESS 0x0000041b
+#define COUNTER_INT_STATUS_ENABLE_OFFSET 0x0000041b
+#define COUNTER_INT_STATUS_ENABLE_BIT_MSB 7
+#define COUNTER_INT_STATUS_ENABLE_BIT_LSB 0
+#define COUNTER_INT_STATUS_ENABLE_BIT_MASK 0x000000ff
+#define COUNTER_INT_STATUS_ENABLE_BIT_GET(x) \
+	(((x) & COUNTER_INT_STATUS_ENABLE_BIT_MASK) >> \
+	 COUNTER_INT_STATUS_ENABLE_BIT_LSB)
+#define COUNTER_INT_STATUS_ENABLE_BIT_SET(x) \
+	(((x) << COUNTER_INT_STATUS_ENABLE_BIT_LSB) & \
+	 COUNTER_INT_STATUS_ENABLE_BIT_MASK)
+
+#define COUNT_ADDRESS 0x00000420
+#define COUNT_OFFSET 0x00000420
+#define COUNT_VALUE_MSB 7
+#define COUNT_VALUE_LSB 0
+#define COUNT_VALUE_MASK 0x000000ff
+#define COUNT_VALUE_GET(x) (((x) & COUNT_VALUE_MASK) >> COUNT_VALUE_LSB)
+#define COUNT_VALUE_SET(x) (((x) << COUNT_VALUE_LSB) & COUNT_VALUE_MASK)
+
+#define COUNT_DEC_ADDRESS 0x00000440
+#define COUNT_DEC_OFFSET 0x00000440
+#define COUNT_DEC_VALUE_MSB 7
+#define COUNT_DEC_VALUE_LSB 0
+#define COUNT_DEC_VALUE_MASK 0x000000ff
+#define COUNT_DEC_VALUE_GET(x) \
+	(((x) & COUNT_DEC_VALUE_MASK) >> COUNT_DEC_VALUE_LSB)
+#define COUNT_DEC_VALUE_SET(x) \
+	(((x) << COUNT_DEC_VALUE_LSB) & COUNT_DEC_VALUE_MASK)
+
+#define SCRATCH_ADDRESS 0x00000460
+#define SCRATCH_OFFSET 0x00000460
+#define SCRATCH_VALUE_MSB 7
+#define SCRATCH_VALUE_LSB 0
+#define SCRATCH_VALUE_MASK 0x000000ff
+#define SCRATCH_VALUE_GET(x) (((x) & SCRATCH_VALUE_MASK) >> SCRATCH_VALUE_LSB)
+#define SCRATCH_VALUE_SET(x) (((x) << SCRATCH_VALUE_LSB) & SCRATCH_VALUE_MASK)
+
+#define FIFO_TIMEOUT_ADDRESS 0x00000468
+#define FIFO_TIMEOUT_OFFSET 0x00000468
+#define FIFO_TIMEOUT_VALUE_MSB 7
+#define FIFO_TIMEOUT_VALUE_LSB 0
+#define FIFO_TIMEOUT_VALUE_MASK 0x000000ff
+#define FIFO_TIMEOUT_VALUE_GET(x) \
+	(((x) & FIFO_TIMEOUT_VALUE_MASK) >> FIFO_TIMEOUT_VALUE_LSB)
+#define FIFO_TIMEOUT_VALUE_SET(x) \
+	(((x) << FIFO_TIMEOUT_VALUE_LSB) & FIFO_TIMEOUT_VALUE_MASK)
+
+#define FIFO_TIMEOUT_ENABLE_ADDRESS 0x00000469
+#define FIFO_TIMEOUT_ENABLE_OFFSET 0x00000469
+#define FIFO_TIMEOUT_ENABLE_SET_MSB 0
+#define FIFO_TIMEOUT_ENABLE_SET_LSB 0
+#define FIFO_TIMEOUT_ENABLE_SET_MASK 0x00000001
+#define FIFO_TIMEOUT_ENABLE_SET_GET(x) \
+	(((x) & FIFO_TIMEOUT_ENABLE_SET_MASK) >> FIFO_TIMEOUT_ENABLE_SET_LSB)
+#define FIFO_TIMEOUT_ENABLE_SET_SET(x) \
+	(((x) << FIFO_TIMEOUT_ENABLE_SET_LSB) & FIFO_TIMEOUT_ENABLE_SET_MASK)
+
+#define INT_WLAN_ADDRESS 0x00000472
+#define INT_TARGET_ADDRESS INT_WLAN_ADDRESS
+#define INT_WLAN_OFFSET 0x00000472
+#define INT_WLAN_VECTOR_MSB 7
+#define INT_WLAN_VECTOR_LSB 0
+#define INT_WLAN_VECTOR_MASK 0x000000ff
+#define INT_WLAN_VECTOR_GET(x) \
+	(((x) & INT_WLAN_VECTOR_MASK) >> INT_WLAN_VECTOR_LSB)
+#define INT_WLAN_VECTOR_SET(x) \
+	(((x) << INT_WLAN_VECTOR_LSB) & INT_WLAN_VECTOR_MASK)
+
+#define SPI_CONFIG_ADDRESS 0x00000480
+#define SPI_CONFIG_OFFSET 0x00000480
+#define SPI_CONFIG_SPI_RESET_MSB 4
+#define SPI_CONFIG_SPI_RESET_LSB 4
+#define SPI_CONFIG_SPI_RESET_MASK 0x00000010
+#define SPI_CONFIG_SPI_RESET_GET(x) \
+	(((x) & SPI_CONFIG_SPI_RESET_MASK) >> SPI_CONFIG_SPI_RESET_LSB)
+#define SPI_CONFIG_SPI_RESET_SET(x) \
+	(((x) << SPI_CONFIG_SPI_RESET_LSB) & SPI_CONFIG_SPI_RESET_MASK)
+#define SPI_CONFIG_INTERRUPT_ENABLE_MSB 3
+#define SPI_CONFIG_INTERRUPT_ENABLE_LSB 3
+#define SPI_CONFIG_INTERRUPT_ENABLE_MASK 0x00000008
+#define SPI_CONFIG_INTERRUPT_ENABLE_GET(x) \
+	(((x) & SPI_CONFIG_INTERRUPT_ENABLE_MASK) >> \
+	 SPI_CONFIG_INTERRUPT_ENABLE_LSB)
+#define SPI_CONFIG_INTERRUPT_ENABLE_SET(x) \
+	(((x) << SPI_CONFIG_INTERRUPT_ENABLE_LSB) & \
+	 SPI_CONFIG_INTERRUPT_ENABLE_MASK)
+#define SPI_CONFIG_TEST_MODE_MSB 2
+#define SPI_CONFIG_TEST_MODE_LSB 2
+#define SPI_CONFIG_TEST_MODE_MASK 0x00000004
+#define SPI_CONFIG_TEST_MODE_GET(x) \
+	(((x) & SPI_CONFIG_TEST_MODE_MASK) >> SPI_CONFIG_TEST_MODE_LSB)
+#define SPI_CONFIG_TEST_MODE_SET(x) \
+	(((x) << SPI_CONFIG_TEST_MODE_LSB) & SPI_CONFIG_TEST_MODE_MASK)
+#define SPI_CONFIG_DATA_SIZE_MSB 1
+#define SPI_CONFIG_DATA_SIZE_LSB 0
+#define SPI_CONFIG_DATA_SIZE_MASK 0x00000003
+#define SPI_CONFIG_DATA_SIZE_GET(x) \
+	(((x) & SPI_CONFIG_DATA_SIZE_MASK) >> SPI_CONFIG_DATA_SIZE_LSB)
+#define SPI_CONFIG_DATA_SIZE_SET(x) \
+	(((x) << SPI_CONFIG_DATA_SIZE_LSB) & SPI_CONFIG_DATA_SIZE_MASK)
+
+#define SPI_STATUS_ADDRESS 0x00000481
+#define SPI_STATUS_OFFSET 0x00000481
+#define SPI_STATUS_ADDR_ERR_MSB 3
+#define SPI_STATUS_ADDR_ERR_LSB 3
+#define SPI_STATUS_ADDR_ERR_MASK 0x00000008
+#define SPI_STATUS_ADDR_ERR_GET(x) \
+	(((x) & SPI_STATUS_ADDR_ERR_MASK) >> SPI_STATUS_ADDR_ERR_LSB)
+#define SPI_STATUS_ADDR_ERR_SET(x) \
+	(((x) << SPI_STATUS_ADDR_ERR_LSB) & SPI_STATUS_ADDR_ERR_MASK)
+#define SPI_STATUS_RD_ERR_MSB 2
+#define SPI_STATUS_RD_ERR_LSB 2
+#define SPI_STATUS_RD_ERR_MASK 0x00000004
+#define SPI_STATUS_RD_ERR_GET(x) \
+	(((x) & SPI_STATUS_RD_ERR_MASK) >> SPI_STATUS_RD_ERR_LSB)
+#define SPI_STATUS_RD_ERR_SET(x) \
+	(((x) << SPI_STATUS_RD_ERR_LSB) & SPI_STATUS_RD_ERR_MASK)
+#define SPI_STATUS_WR_ERR_MSB 1
+#define SPI_STATUS_WR_ERR_LSB 1
+#define SPI_STATUS_WR_ERR_MASK 0x00000002
+#define SPI_STATUS_WR_ERR_GET(x) \
+	(((x) & SPI_STATUS_WR_ERR_MASK) >> SPI_STATUS_WR_ERR_LSB)
+#define SPI_STATUS_WR_ERR_SET(x) \
+	(((x) << SPI_STATUS_WR_ERR_LSB) & SPI_STATUS_WR_ERR_MASK)
+#define SPI_STATUS_READY_MSB 0
+#define SPI_STATUS_READY_LSB 0
+#define SPI_STATUS_READY_MASK 0x00000001
+#define SPI_STATUS_READY_GET(x) \
+	(((x) & SPI_STATUS_READY_MASK) >> SPI_STATUS_READY_LSB)
+#define SPI_STATUS_READY_SET(x) \
+	(((x) << SPI_STATUS_READY_LSB) & SPI_STATUS_READY_MASK)
+#define INT_WLAN_ADDRESS 0x00000472
+#define INT_WLAN_OFFSET 0x00000472
+#define INT_WLAN_VECTOR_MSB 7
+#define INT_WLAN_VECTOR_LSB 0
+#define INT_WLAN_VECTOR_MASK 0x000000ff
+#define INT_WLAN_VECTOR_GET(x) \
+	(((x) & INT_WLAN_VECTOR_MASK) >> INT_WLAN_VECTOR_LSB)
+#define INT_WLAN_VECTOR_SET(x) \
+	(((x) << INT_WLAN_VECTOR_LSB) & INT_WLAN_VECTOR_MASK)
+
+#endif /* _MBOX_HOST_REG_H_ */
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c
index ec2ea56..fdbd359 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rf.c
@@ -304,9 +304,6 @@
 			writeVal = 0x00000000;
 		if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1)
 			writeVal = writeVal - 0x06060606;
-		else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
-			 TXHIGHPWRLEVEL_BT2)
-			writeVal = writeVal;
 		*(p_outwriteval + rf) = writeVal;
 	}
 }
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 642ee00..a55d112 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -1126,11 +1126,11 @@
 	if (result < 0)
 		goto release_cq;
 
+	nvme_init_queue(nvmeq, qid);
 	result = queue_request_irq(nvmeq);
 	if (result < 0)
 		goto release_sq;
 
-	nvme_init_queue(nvmeq, qid);
 	return result;
 
  release_sq:
@@ -1248,6 +1248,7 @@
 		return result;
 
 	nvmeq->cq_vector = 0;
+	nvme_init_queue(nvmeq, 0);
 	result = queue_request_irq(nvmeq);
 	if (result) {
 		nvmeq->cq_vector = -1;
@@ -1776,7 +1777,6 @@
 	if (result)
 		goto out;
 
-	nvme_init_queue(dev->queues[0], 0);
 	result = nvme_alloc_admin_tags(dev);
 	if (result)
 		goto out;
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
index f791d46..2caed28 100644
--- a/drivers/nvme/target/admin-cmd.c
+++ b/drivers/nvme/target/admin-cmd.c
@@ -166,11 +166,21 @@
 	nvmet_req_complete(req, status);
 }
 
+static void copy_and_pad(char *dst, int dst_len, const char *src, int src_len)
+{
+	int len = min(src_len, dst_len);
+
+	memcpy(dst, src, len);
+	if (dst_len > len)
+		memset(dst + len, ' ', dst_len - len);
+}
+
 static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
 {
 	struct nvmet_ctrl *ctrl = req->sq->ctrl;
 	struct nvme_id_ctrl *id;
 	u16 status = 0;
+	const char model[] = "Linux";
 
 	id = kzalloc(sizeof(*id), GFP_KERNEL);
 	if (!id) {
@@ -182,14 +192,10 @@
 	id->vid = 0;
 	id->ssvid = 0;
 
-	memset(id->sn, ' ', sizeof(id->sn));
-	snprintf(id->sn, sizeof(id->sn), "%llx", ctrl->serial);
-
-	memset(id->mn, ' ', sizeof(id->mn));
-	strncpy((char *)id->mn, "Linux", sizeof(id->mn));
-
-	memset(id->fr, ' ', sizeof(id->fr));
-	strncpy((char *)id->fr, UTS_RELEASE, sizeof(id->fr));
+	bin2hex(id->sn, &ctrl->subsys->serial,
+		min(sizeof(ctrl->subsys->serial), sizeof(id->sn) / 2));
+	copy_and_pad(id->mn, sizeof(id->mn), model, sizeof(model) - 1);
+	copy_and_pad(id->fr, sizeof(id->fr), UTS_RELEASE, strlen(UTS_RELEASE));
 
 	id->rab = 6;
 
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 3a04492..64b40a1 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -743,9 +743,6 @@
 	memcpy(ctrl->subsysnqn, subsysnqn, NVMF_NQN_SIZE);
 	memcpy(ctrl->hostnqn, hostnqn, NVMF_NQN_SIZE);
 
-	/* generate a random serial number as our controllers are ephemeral: */
-	get_random_bytes(&ctrl->serial, sizeof(ctrl->serial));
-
 	kref_init(&ctrl->ref);
 	ctrl->subsys = subsys;
 
@@ -904,6 +901,8 @@
 		return NULL;
 
 	subsys->ver = NVME_VS(1, 2, 1); /* NVMe 1.2.1 */
+	/* generate a random serial number as our controllers are ephemeral: */
+	get_random_bytes(&subsys->serial, sizeof(subsys->serial));
 
 	switch (type) {
 	case NVME_NQN_NVME:
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 26b87dc..0bc530c 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -110,7 +110,6 @@
 
 	struct mutex		lock;
 	u64			cap;
-	u64			serial;
 	u32			cc;
 	u32			csts;
 
@@ -151,6 +150,7 @@
 	u16			max_qid;
 
 	u64			ver;
+	u64			serial;
 	char			*subsysnqn;
 
 	struct config_group	group;
diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c
index f9a2454..6a25bfd 100644
--- a/drivers/platform/chrome/cros_ec_lpc.c
+++ b/drivers/platform/chrome/cros_ec_lpc.c
@@ -49,7 +49,6 @@
 static int cros_ec_pkt_xfer_lpc(struct cros_ec_device *ec,
 				struct cros_ec_command *msg)
 {
-	struct ec_host_request *request;
 	struct ec_host_response response;
 	u8 sum = 0;
 	int i;
@@ -62,8 +61,6 @@
 	for (i = 0; i < ret; i++)
 		outb(ec->dout[i], EC_LPC_ADDR_HOST_PACKET + i);
 
-	request = (struct ec_host_request *)ec->dout;
-
 	/* Here we go */
 	outb(EC_COMMAND_PROTOCOL_3, EC_LPC_ADDR_HOST_CMD);
 
diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c
index 5d8b12b..c38f1be 100644
--- a/drivers/platform/msm/gsi/gsi.c
+++ b/drivers/platform/msm/gsi/gsi.c
@@ -23,7 +23,7 @@
 #include "gsi_emulation.h"
 
 #define GSI_CMD_TIMEOUT (5*HZ)
-#define GSI_STOP_CMD_TIMEOUT_MS 20
+#define GSI_STOP_CMD_TIMEOUT_MS 50
 #define GSI_MAX_CH_LOW_WEIGHT 15
 
 #define GSI_RESET_WA_MIN_SLEEP 1000
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa.c b/drivers/platform/msm/ipa/ipa_v2/ipa.c
index 10468f3..6f9afa6 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa.c
@@ -3938,11 +3938,8 @@
 	}
 
 	ipa_ctx->logbuf = ipc_log_context_create(IPA_IPC_LOG_PAGES, "ipa", 0);
-	if (ipa_ctx->logbuf == NULL) {
-		IPAERR("failed to get logbuf\n");
-		result = -ENOMEM;
-		goto fail_logbuf;
-	}
+	if (ipa_ctx->logbuf == NULL)
+		IPADBG("failed to create IPC log, continue...\n");
 
 	ipa_ctx->pdev = ipa_dev;
 	ipa_ctx->uc_pdev = ipa_dev;
@@ -4488,7 +4485,6 @@
 	kfree(ipa_ctx->ctrl);
 fail_mem_ctrl:
 	ipc_log_context_destroy(ipa_ctx->logbuf);
-fail_logbuf:
 	kfree(ipa_ctx);
 	ipa_ctx = NULL;
 fail_mem_ctx:
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c
index c2f7aae..7d315a4 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c
@@ -1903,7 +1903,7 @@
 				ipc_log_context_create(IPA_IPC_LOG_PAGES,
 				"ipa_low", 0);
 			if (ipa_ipc_low_buff == NULL)
-				IPAERR("failed to get logbuf_low\n");
+				IPADBG("failed to get logbuf_low\n");
 		}
 		ipa_ctx->logbuf_low = ipa_ipc_low_buff;
 	} else {
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index c7422c7..8a773e4 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -5018,7 +5018,7 @@
 
 	ipa3_ctx->logbuf = ipc_log_context_create(IPA_IPC_LOG_PAGES, "ipa", 0);
 	if (ipa3_ctx->logbuf == NULL)
-		IPAERR("failed to create IPC log, continue...\n");
+		IPADBG("failed to create IPC log, continue...\n");
 
 	/* ipa3_ctx->pdev and ipa3_ctx->uc_pdev will be set in the smmu probes*/
 	ipa3_ctx->master_pdev = ipa_pdev;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
index 5bcd49e..cfac126 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
@@ -63,7 +63,15 @@
 	IPADBG("Enabling data path\n");
 	if (IPA_CLIENT_IS_CONS(ep->client)) {
 		memset(&holb_cfg, 0, sizeof(holb_cfg));
-		holb_cfg.en = IPA_HOLB_TMR_DIS;
+		/*
+		 * Set HOLB on USB DPL CONS to avoid IPA stall
+		 * if DPL client is not pulling the data
+		 * on other end from IPA hw.
+		 */
+		if (ep->client == IPA_CLIENT_USB_DPL_CONS)
+			holb_cfg.en = IPA_HOLB_TMR_EN;
+		else
+			holb_cfg.en = IPA_HOLB_TMR_DIS;
 		holb_cfg.tmr_val = 0;
 		res = ipa3_cfg_ep_holb(clnt_hdl, &holb_cfg);
 	}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
index 10abdcf..3728a43 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
@@ -2089,7 +2089,7 @@
 					"ipa_low", 0);
 		}
 			if (ipa_ipc_low_buff == NULL)
-				IPAERR("failed to get logbuf_low\n");
+				IPADBG("failed to get logbuf_low\n");
 		ipa3_ctx->logbuf_low = ipa_ipc_low_buff;
 	} else {
 		ipa3_ctx->logbuf_low = NULL;
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 8a1bfd4..ed27768 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -161,6 +161,16 @@
 
 static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL };
 
+static bool ashs_present(void)
+{
+	int i = 0;
+	while (ashs_ids[i]) {
+		if (acpi_dev_found(ashs_ids[i++]))
+			return true;
+	}
+	return false;
+}
+
 struct bios_args {
 	u32 arg0;
 	u32 arg1;
@@ -966,6 +976,9 @@
 
 static void asus_wmi_rfkill_exit(struct asus_wmi *asus)
 {
+	if (asus->driver->wlan_ctrl_by_user && ashs_present())
+		return;
+
 	asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P5");
 	asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P6");
 	asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P7");
@@ -2062,16 +2075,6 @@
 	return 0;
 }
 
-static bool ashs_present(void)
-{
-	int i = 0;
-	while (ashs_ids[i]) {
-		if (acpi_dev_found(ashs_ids[i++]))
-			return true;
-	}
-	return false;
-}
-
 /*
  * WMI Driver
  */
diff --git a/drivers/power/supply/qcom/qg-core.h b/drivers/power/supply/qcom/qg-core.h
index b3bf42a..b0ff18c 100644
--- a/drivers/power/supply/qcom/qg-core.h
+++ b/drivers/power/supply/qcom/qg-core.h
@@ -134,6 +134,7 @@
 	u32			esr_last;
 	ktime_t			last_user_update_time;
 	ktime_t			last_fifo_update_time;
+	unsigned long		last_maint_soc_update_time;
 
 	/* soc params */
 	int			catch_up_soc;
@@ -143,6 +144,9 @@
 	int			batt_soc;
 	int			cc_soc;
 	int			full_soc;
+	int			sys_soc;
+	int			last_adj_ssoc;
+	int			recharge_soc;
 	struct alarm		alarm_timer;
 	u32			sdam_data[SDAM_MAX];
 
diff --git a/drivers/power/supply/qcom/qg-soc.c b/drivers/power/supply/qcom/qg-soc.c
index af8b158..711bd2b 100644
--- a/drivers/power/supply/qcom/qg-soc.c
+++ b/drivers/power/supply/qcom/qg-soc.c
@@ -17,15 +17,19 @@
 #include <linux/module.h>
 #include <linux/power_supply.h>
 #include <uapi/linux/qg.h>
+#include <uapi/linux/qg-profile.h>
 #include "fg-alg.h"
 #include "qg-sdam.h"
 #include "qg-core.h"
 #include "qg-reg.h"
 #include "qg-util.h"
 #include "qg-defs.h"
+#include "qg-soc.h"
 
 #define DEFAULT_UPDATE_TIME_MS			64000
 #define SOC_SCALE_HYST_MS			2000
+#define VBAT_LOW_HYST_UV			50000
+#define FULL_SOC				100
 
 static int qg_delta_soc_interval_ms = 20000;
 module_param_named(
@@ -37,6 +41,44 @@
 	soc_cold_interval_ms, qg_delta_soc_cold_interval_ms, int, 0600
 );
 
+static int qg_maint_soc_update_ms = 120000;
+module_param_named(
+	maint_soc_update_ms, qg_maint_soc_update_ms, int, 0600
+);
+
+int qg_adjust_sys_soc(struct qpnp_qg *chip)
+{
+	int soc, vbat_uv, rc;
+	int vcutoff_uv = chip->dt.vbatt_cutoff_mv * 1000;
+
+	chip->sys_soc = CAP(QG_MIN_SOC, QG_MAX_SOC, chip->sys_soc);
+
+	if (chip->sys_soc == QG_MIN_SOC) {
+		/* Hold SOC to 1% of VBAT has not dropped below cutoff */
+		rc = qg_get_battery_voltage(chip, &vbat_uv);
+		if (!rc && vbat_uv >= (vcutoff_uv + VBAT_LOW_HYST_UV))
+			soc = 1;
+		else
+			soc = 0;
+	} else if (chip->sys_soc == QG_MAX_SOC) {
+		soc = FULL_SOC;
+	} else if (chip->sys_soc >= (QG_MAX_SOC - 100)) {
+		/* Hold SOC to 100% if we are dropping from 100 to 99 */
+		if (chip->last_adj_ssoc == FULL_SOC)
+			soc = FULL_SOC;
+		else /* Hold SOC at 99% until we hit 100% */
+			soc = FULL_SOC - 1;
+	} else {
+		soc = DIV_ROUND_CLOSEST(chip->sys_soc, 100);
+	}
+
+	qg_dbg(chip, QG_DEBUG_SOC, "last_adj_sys_soc=%d  adj_sys_soc=%d\n",
+					chip->last_adj_ssoc, soc);
+	chip->last_adj_ssoc = soc;
+
+	return soc;
+}
+
 static void get_next_update_time(struct qpnp_qg *chip)
 {
 	int soc_points = 0, batt_temp = 0;
@@ -56,10 +98,11 @@
 
 	/* Lower the delta soc interval by half at cold */
 	rc = qg_get_battery_temp(chip, &batt_temp);
-	if (rc < 0)
-		pr_err("Failed to read battery temperature rc=%d\n", rc);
-	else if (batt_temp < chip->dt.cold_temp_threshold)
+	if (!rc && batt_temp < chip->dt.cold_temp_threshold)
 		min_delta_soc_interval_ms = qg_delta_soc_cold_interval_ms;
+	else if (chip->maint_soc > 0 && chip->maint_soc >= chip->recharge_soc)
+		/* if in maintenance mode scale slower */
+		min_delta_soc_interval_ms = qg_maint_soc_update_ms;
 
 	if (!min_delta_soc_interval_ms)
 		min_delta_soc_interval_ms = 1000;	/* 1 second */
@@ -98,9 +141,34 @@
 	return true;
 }
 
+static bool maint_soc_timeout(struct qpnp_qg *chip)
+{
+	unsigned long now;
+	int rc;
+
+	if (chip->maint_soc < 0)
+		return false;
+
+	rc = get_rtc_time(&now);
+	if (rc < 0)
+		return true;
+
+	/* Do not scale if we have dropped below recharge-soc */
+	if (chip->maint_soc < chip->recharge_soc)
+		return true;
+
+	if ((now - chip->last_maint_soc_update_time) >=
+			(qg_maint_soc_update_ms / 1000)) {
+		chip->last_maint_soc_update_time = now;
+		return true;
+	}
+
+	return false;
+}
+
 static void update_msoc(struct qpnp_qg *chip)
 {
-	int rc = 0, batt_temp = 0,  batt_soc_32bit = 0;
+	int rc = 0, sdam_soc, batt_temp = 0,  batt_soc_32bit = 0;
 	bool usb_present = is_usb_present(chip);
 
 	if (chip->catch_up_soc > chip->msoc) {
@@ -113,7 +181,8 @@
 	}
 	chip->msoc = CAP(0, 100, chip->msoc);
 
-	if (chip->maint_soc > 0 && chip->msoc < chip->maint_soc) {
+	if (chip->maint_soc > 0 && chip->msoc < chip->maint_soc
+				&& maint_soc_timeout(chip)) {
 		chip->maint_soc -= chip->dt.delta_soc;
 		chip->maint_soc = CAP(0, 100, chip->maint_soc);
 	}
@@ -128,8 +197,9 @@
 		pr_err("Failed to update MSOC register rc=%d\n", rc);
 
 	/* update SDAM with the new MSOC */
-	chip->sdam_data[SDAM_SOC] = chip->msoc;
-	rc = qg_sdam_write(SDAM_SOC, chip->msoc);
+	sdam_soc = (chip->maint_soc > 0) ? chip->maint_soc : chip->msoc;
+	chip->sdam_data[SDAM_SOC] = sdam_soc;
+	rc = qg_sdam_write(SDAM_SOC, sdam_soc);
 	if (rc < 0)
 		pr_err("Failed to update SDAM with MSOC rc=%d\n", rc);
 
diff --git a/drivers/power/supply/qcom/qg-soc.h b/drivers/power/supply/qcom/qg-soc.h
index 3b4eb60..cd64bd5 100644
--- a/drivers/power/supply/qcom/qg-soc.h
+++ b/drivers/power/supply/qcom/qg-soc.h
@@ -16,5 +16,6 @@
 int qg_scale_soc(struct qpnp_qg *chip, bool force_soc);
 int qg_soc_init(struct qpnp_qg *chip);
 void qg_soc_exit(struct qpnp_qg *chip);
+int qg_adjust_sys_soc(struct qpnp_qg *chip);
 
 #endif /* __QG_SOC_H__ */
diff --git a/drivers/power/supply/qcom/qg-util.c b/drivers/power/supply/qcom/qg-util.c
index 85efdbf..a3e045e 100644
--- a/drivers/power/supply/qcom/qg-util.c
+++ b/drivers/power/supply/qcom/qg-util.c
@@ -367,3 +367,25 @@
 				BURST_AVG_HOLD_FOR_READ_BIT, 0);
 	return rc;
 }
+
+int qg_get_battery_voltage(struct qpnp_qg *chip, int *vbat_uv)
+{
+	int rc = 0;
+	u64 last_vbat = 0;
+
+	if (chip->battery_missing) {
+		*vbat_uv = 3700000;
+		return 0;
+	}
+
+	rc = qg_read(chip, chip->qg_base + QG_LAST_ADC_V_DATA0_REG,
+				(u8 *)&last_vbat, 2);
+	if (rc < 0) {
+		pr_err("Failed to read LAST_ADV_V reg, rc=%d\n", rc);
+		return rc;
+	}
+
+	*vbat_uv = V_RAW_TO_UV(last_vbat);
+
+	return rc;
+}
diff --git a/drivers/power/supply/qcom/qg-util.h b/drivers/power/supply/qcom/qg-util.h
index 2dbafe7..5dd6c85 100644
--- a/drivers/power/supply/qcom/qg-util.h
+++ b/drivers/power/supply/qcom/qg-util.h
@@ -26,5 +26,6 @@
 int qg_write_monotonic_soc(struct qpnp_qg *chip, int msoc);
 int qg_get_battery_temp(struct qpnp_qg *chip, int *batt_temp);
 int qg_get_battery_current(struct qpnp_qg *chip, int *ibat_ua);
+int qg_get_battery_voltage(struct qpnp_qg *chip, int *vbat_uv);
 
 #endif
diff --git a/drivers/power/supply/qcom/qpnp-qg.c b/drivers/power/supply/qcom/qpnp-qg.c
index 41b8d3c..613fb74 100644
--- a/drivers/power/supply/qcom/qpnp-qg.c
+++ b/drivers/power/supply/qcom/qpnp-qg.c
@@ -1029,11 +1029,23 @@
 	if (chip->udata.param[QG_FULL_SOC].valid)
 		chip->full_soc = chip->udata.param[QG_FULL_SOC].data;
 
-	if (chip->udata.param[QG_SOC].valid) {
-		qg_dbg(chip, QG_DEBUG_SOC, "udata SOC=%d last SOC=%d\n",
-			chip->udata.param[QG_SOC].data, chip->catch_up_soc);
+	if (chip->udata.param[QG_SOC].valid ||
+			chip->udata.param[QG_SYS_SOC].valid) {
 
-		chip->catch_up_soc = chip->udata.param[QG_SOC].data;
+		qg_dbg(chip, QG_DEBUG_SOC, "udata update: QG_SOC=%d QG_SYS_SOC=%d last_catchup_soc=%d\n",
+				chip->udata.param[QG_SOC].valid ?
+				chip->udata.param[QG_SOC].data : -EINVAL,
+				chip->udata.param[QG_SYS_SOC].valid ?
+				chip->udata.param[QG_SYS_SOC].data : -EINVAL,
+				chip->catch_up_soc);
+
+		if (chip->udata.param[QG_SYS_SOC].valid) {
+			chip->sys_soc = chip->udata.param[QG_SYS_SOC].data;
+			chip->catch_up_soc = qg_adjust_sys_soc(chip);
+		} else {
+			chip->catch_up_soc = chip->udata.param[QG_SOC].data;
+		}
+
 		qg_scale_soc(chip, false);
 
 		/* update parameters to SDAM */
@@ -1500,28 +1512,6 @@
 	return DEFAULT_BATT_TYPE;
 }
 
-static int qg_get_battery_voltage(struct qpnp_qg *chip, int *vbat_uv)
-{
-	int rc = 0;
-	u64 last_vbat = 0;
-
-	if (chip->battery_missing) {
-		*vbat_uv = 3700000;
-		return 0;
-	}
-
-	rc = qg_read(chip, chip->qg_base + QG_LAST_ADC_V_DATA0_REG,
-				(u8 *)&last_vbat, 2);
-	if (rc < 0) {
-		pr_err("Failed to read LAST_ADV_V reg, rc=%d\n", rc);
-		return rc;
-	}
-
-	*vbat_uv = V_RAW_TO_UV(last_vbat);
-
-	return rc;
-}
-
 #define DEBUG_BATT_SOC		67
 #define BATT_MISSING_SOC	50
 #define EMPTY_SOC		0
@@ -1868,9 +1858,11 @@
 		recharge_soc = DEFAULT_RECHARGE_SOC;
 	}
 	recharge_soc = prop.intval;
+	chip->recharge_soc = recharge_soc;
 
-	qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d health=%d charge_full=%d\n",
-				chip->msoc, health, chip->charge_full);
+	qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d health=%d charge_full=%d charge_done=%d\n",
+				chip->msoc, health, chip->charge_full,
+				chip->charge_done);
 	if (chip->charge_done && !chip->charge_full) {
 		if (chip->msoc >= 99 && health == POWER_SUPPLY_HEALTH_GOOD) {
 			chip->charge_full = true;
@@ -1881,10 +1873,18 @@
 			qg_dbg(chip, QG_DEBUG_STATUS, "Terminated charging @ msoc=%d\n",
 					chip->msoc);
 		}
-	} else if ((!chip->charge_done || chip->msoc < recharge_soc)
+	} else if ((!chip->charge_done || chip->msoc <= recharge_soc)
 				&& chip->charge_full) {
 
-		if (chip->wa_flags & QG_RECHARGE_SOC_WA) {
+		bool usb_present = is_usb_present(chip);
+
+		/*
+		 * force a recharge only if SOC <= recharge SOC and
+		 * we have not started charging.
+		 */
+		if ((chip->wa_flags & QG_RECHARGE_SOC_WA) &&
+			usb_present && chip->msoc <= recharge_soc &&
+			chip->charge_status != POWER_SUPPLY_STATUS_CHARGING) {
 			/* Force recharge */
 			prop.intval = 0;
 			rc = power_supply_set_property(chip->batt_psy,
@@ -1892,23 +1892,33 @@
 			if (rc < 0)
 				pr_err("Failed to force recharge rc=%d\n", rc);
 			else
-				qg_dbg(chip, QG_DEBUG_STATUS,
-					"Forced recharge\n");
+				qg_dbg(chip, QG_DEBUG_STATUS, "Forced recharge\n");
 		}
 
+
+		if (chip->charge_done)
+			return 0;	/* wait for recharge */
+
 		/*
-		 * If recharge or discharge has started and
-		 * if linearize soc dtsi property defined
-		 * scale msoc from 100% for better UX.
+		 * If SOC has indeed dropped below recharge-SOC or
+		 * the USB is removed, if linearize-soc is set scale
+		 * msoc from 100% for better UX.
 		 */
-		if (chip->dt.linearize_soc && chip->msoc < 99) {
-			chip->maint_soc = FULL_SOC;
-			qg_scale_soc(chip, false);
-		}
-
-		qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d recharge_soc=%d charge_full (1->0)\n",
+		if (chip->msoc < recharge_soc || !usb_present) {
+			if (chip->dt.linearize_soc) {
+				get_rtc_time(&chip->last_maint_soc_update_time);
+				chip->maint_soc = FULL_SOC;
+				qg_scale_soc(chip, false);
+			}
+			chip->charge_full = false;
+			qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d recharge_soc=%d charge_full (1->0)\n",
 					chip->msoc, recharge_soc);
-		chip->charge_full = false;
+		} else {
+			/* continue with charge_full state */
+			qg_dbg(chip, QG_DEBUG_STATUS, "msoc=%d recharge_soc=%d charge_full=%d usb_present=%d\n",
+					chip->msoc, recharge_soc,
+					chip->charge_full, usb_present);
+		}
 	}
 out:
 	return 0;
@@ -2620,7 +2630,7 @@
 		return rc;
 	}
 
-	chip->pon_soc = chip->catch_up_soc = chip->msoc = soc;
+	chip->last_adj_ssoc = chip->catch_up_soc = chip->msoc = soc;
 	chip->kdata.param[QG_PON_OCV_UV].data = ocv_uv;
 	chip->kdata.param[QG_PON_OCV_UV].valid = true;
 
@@ -2875,10 +2885,6 @@
 				PROFILE_IRQ_DISABLE, true, 0);
 		vote(chip->good_ocv_irq_disable_votable,
 				PROFILE_IRQ_DISABLE, true, 0);
-	} else {
-		/* disable GOOD_OCV IRQ at init */
-		vote(chip->good_ocv_irq_disable_votable,
-				QG_INIT_STATE_IRQ_DISABLE, true, 0);
 	}
 
 	/* restore ESR data */
@@ -3606,6 +3612,7 @@
 	chip->maint_soc = -EINVAL;
 	chip->batt_soc = INT_MIN;
 	chip->cc_soc = INT_MIN;
+	chip->sys_soc = INT_MIN;
 	chip->full_soc = QG_SOC_FULL;
 	chip->chg_iterm_ma = INT_MIN;
 	chip->soh = -EINVAL;
diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c
index e3cd3ec..c3d1891 100644
--- a/drivers/scsi/scsi_transport_srp.c
+++ b/drivers/scsi/scsi_transport_srp.c
@@ -52,6 +52,8 @@
 	struct transport_container rport_attr_cont;
 };
 
+static int scsi_is_srp_rport(const struct device *dev);
+
 #define to_srp_internal(tmpl) container_of(tmpl, struct srp_internal, t)
 
 #define	dev_to_rport(d)	container_of(d, struct srp_rport, dev)
@@ -61,9 +63,24 @@
 	return dev_to_shost(r->dev.parent);
 }
 
+static int find_child_rport(struct device *dev, void *data)
+{
+	struct device **child = data;
+
+	if (scsi_is_srp_rport(dev)) {
+		WARN_ON_ONCE(*child);
+		*child = dev;
+	}
+	return 0;
+}
+
 static inline struct srp_rport *shost_to_rport(struct Scsi_Host *shost)
 {
-	return transport_class_to_srp_rport(&shost->shost_gendev);
+	struct device *child = NULL;
+
+	WARN_ON_ONCE(device_for_each_child(&shost->shost_gendev, &child,
+					   find_child_rport) < 0);
+	return child ? dev_to_rport(child) : NULL;
 }
 
 /**
@@ -637,7 +654,8 @@
 	struct srp_rport *rport = shost_to_rport(shost);
 
 	pr_debug("timeout for sdev %s\n", dev_name(&sdev->sdev_gendev));
-	return rport->fast_io_fail_tmo < 0 && rport->dev_loss_tmo < 0 &&
+	return rport && rport->fast_io_fail_tmo < 0 &&
+		rport->dev_loss_tmo < 0 &&
 		i->f->reset_timer_if_blocked && scsi_device_blocked(sdev) ?
 		BLK_EH_RESET_TIMER : BLK_EH_NOT_HANDLED;
 }
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index c6cfd18..0d72cd0 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -10239,7 +10239,15 @@
 	 * racing during clock frequency scaling sequence.
 	 */
 	if (ufshcd_is_auto_hibern8_supported(hba)) {
+		/*
+		 * Scaling prepare acquires the rw_sem: lock
+		 * h8 may sleep in case of errors.
+		 * e.g. link_recovery. Hence, release the rw_sem
+		 * before hibern8.
+		 */
+		up_write(&hba->lock);
 		ret = ufshcd_uic_hibern8_enter(hba);
+		down_write(&hba->lock);
 		if (ret)
 			/* link will be bad state so no need to scale_up_gear */
 			return ret;
@@ -10370,6 +10378,8 @@
 
 	hba->clk_scaling.is_allowed = value;
 
+	flush_work(&hba->eh_work);
+
 	if (value) {
 		ufshcd_resume_clkscaling(hba);
 	} else {
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 3ecca59..52d9f65 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -52,6 +52,14 @@
 	  can start using the LLCC slices.
 	  Say yes here to enable llcc driver for SDM670.
 
+config QCOM_QCS605_LLCC
+	tristate "Qualcomm Technologies, Inc. QCS605 LLCC driver"
+	depends on QCOM_LLCC
+	help
+	  This provides Last level cache controller driver for QCS605.
+	  This driver provides data required to configure LLCC, so that clients
+	  can start using the LLCC slices.
+	  Say yes here to enable llcc driver for QCS605.
 
 config QCOM_LLCC_AMON
 	tristate "Qualcomm Technologies, Inc. LLCC Activity Monitor(AMON) driver"
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 0b71121..1da8346 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -7,6 +7,7 @@
 obj-$(CONFIG_QCOM_LLCC) += llcc-core.o llcc-slice.o
 obj-$(CONFIG_QCOM_SDM845_LLCC) += llcc-sdm845.o
 obj-$(CONFIG_QCOM_SDM670_LLCC) += llcc-sdm670.o
+obj-$(CONFIG_QCOM_QCS605_LLCC) += llcc-qcs605.o
 obj-$(CONFIG_QCOM_LLCC_PERFMON) += llcc_perfmon.o
 obj-$(CONFIG_QCOM_LLCC_AMON) += llcc-amon.o
 obj-$(CONFIG_QPNP_PBS) += qpnp-pbs.o
diff --git a/drivers/soc/qcom/bgcom_interface.c b/drivers/soc/qcom/bgcom_interface.c
index 1cde8c6..75c9928 100644
--- a/drivers/soc/qcom/bgcom_interface.c
+++ b/drivers/soc/qcom/bgcom_interface.c
@@ -306,10 +306,23 @@
 
 int bg_soft_reset(void)
 {
-	/*pull down reset gpio */
-	gpio_direction_output(bgreset_gpio, 0);
+	pr_debug("do BG reset using gpio %d\n", bgreset_gpio);
+	if (!gpio_is_valid(bgreset_gpio)) {
+		pr_err("gpio %d is not valid\n", bgreset_gpio);
+		return -ENXIO;
+	}
+	if (gpio_direction_output(bgreset_gpio, 1))
+		pr_err("gpio %d direction not set\n", bgreset_gpio);
+
+	/* Sleep for 50ms for hardware to detect signal as high */
+	msleep(50);
+
+	gpio_set_value(bgreset_gpio, 0);
+
+	/* Sleep for 50ms for hardware to detect signal as high */
 	msleep(50);
 	gpio_set_value(bgreset_gpio, 1);
+
 	return 0;
 }
 EXPORT_SYMBOL(bg_soft_reset);
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index b8e9268..39b79f6 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -284,6 +284,7 @@
 	ICNSS_HOST_TRIGGERED_PDR,
 	ICNSS_FW_DOWN,
 	ICNSS_DRIVER_UNLOADING,
+	ICNSS_REJUVENATE,
 };
 
 struct ce_irq_list {
@@ -1172,6 +1173,14 @@
 }
 EXPORT_SYMBOL(icnss_is_fw_down);
 
+bool icnss_is_rejuvenate(void)
+{
+	if (!penv)
+		return false;
+	else
+		return test_bit(ICNSS_REJUVENATE, &penv->state);
+}
+EXPORT_SYMBOL(icnss_is_rejuvenate);
 
 int icnss_power_off(struct device *dev)
 {
@@ -2093,6 +2102,7 @@
 		event_data->crashed = true;
 		event_data->fw_rejuvenate = true;
 		fw_down_data.crashed = true;
+		set_bit(ICNSS_REJUVENATE, &penv->state);
 		icnss_call_driver_uevent(penv, ICNSS_UEVENT_FW_DOWN,
 					 &fw_down_data);
 		icnss_driver_event_post(ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
@@ -2283,6 +2293,7 @@
 
 	icnss_call_driver_shutdown(priv);
 
+	clear_bit(ICNSS_REJUVENATE, &penv->state);
 	clear_bit(ICNSS_PD_RESTART, &priv->state);
 	priv->early_crash_ind = false;
 
@@ -3525,6 +3536,7 @@
 	int atomic_ctx = 1;
 	int s1_bypass = 1;
 	int fast = 1;
+	int stall_disable = 1;
 	int ret = 0;
 
 	icnss_pr_dbg("Initializing SMMU\n");
@@ -3568,6 +3580,16 @@
 			goto set_attr_fail;
 		}
 		icnss_pr_dbg("SMMU FAST map set\n");
+
+		ret = iommu_domain_set_attr(mapping->domain,
+					    DOMAIN_ATTR_CB_STALL_DISABLE,
+					    &stall_disable);
+		if (ret < 0) {
+			icnss_pr_err("Set stall disable map attribute failed, err = %d\n",
+				     ret);
+			goto set_attr_fail;
+		}
+		icnss_pr_dbg("SMMU STALL DISABLE map set\n");
 	}
 
 	ret = arm_iommu_attach_device(&priv->pdev->dev, mapping);
@@ -3989,6 +4011,9 @@
 		case ICNSS_FW_DOWN:
 			seq_puts(s, "FW DOWN");
 			continue;
+		case ICNSS_REJUVENATE:
+			seq_puts(s, "FW REJUVENATE");
+			continue;
 		case ICNSS_DRIVER_UNLOADING:
 			seq_puts(s, "DRIVER UNLOADING");
 		}
diff --git a/drivers/soc/qcom/llcc-qcs605.c b/drivers/soc/qcom/llcc-qcs605.c
new file mode 100644
index 0000000..d3d3390
--- /dev/null
+++ b/drivers/soc/qcom/llcc-qcs605.c
@@ -0,0 +1,106 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/soc/qcom/llcc-qcom.h>
+
+/*
+ * SCT entry contains of the following parameters
+ * name: Name of the client's use case for which the llcc slice is used
+ * uid: Unique id for the client's use case
+ * slice_id: llcc slice id for each client
+ * max_cap: The maximum capacity of the cache slice provided in KB
+ * priority: Priority of the client used to select victim line for replacement
+ * fixed_size: Determine of the slice has a fixed capacity
+ * bonus_ways: Bonus ways to be used by any slice, bonus way is used only if
+ *             it't not a reserved way.
+ * res_ways: Reserved ways for the cache slice, the reserved ways cannot be used
+ *           by any other client than the one its assigned to.
+ * cache_mode: Each slice operates as a cache, this controls the mode of the
+ *             slice normal or TCM
+ * probe_target_ways: Determines what ways to probe for access hit. When
+ *                    configured to 1 only bonus and reseved ways are probed.
+ *                    when configured to 0 all ways in llcc are probed.
+ * dis_cap_alloc: Disable capacity based allocation for a client
+ * retain_on_pc: If this bit is set and client has maitained active vote
+ *               then the ways assigned to this client are not flushed on power
+ *               collapse.
+ * activate_on_init: Activate the slice immidiately after the SCT is programmed
+ */
+#define SCT_ENTRY(n, uid, sid, mc, p, fs, bway, rway, cmod, ptw, dca, rp, a) \
+	{					\
+		.name = n,			\
+		.usecase_id = uid,		\
+		.slice_id = sid,		\
+		.max_cap = mc,			\
+		.priority = p,			\
+		.fixed_size = fs,		\
+		.bonus_ways = bway,		\
+		.res_ways = rway,		\
+		.cache_mode = cmod,		\
+		.probe_target_ways = ptw,	\
+		.dis_cap_alloc = dca,		\
+		.retain_on_pc = rp,		\
+		.activate_on_init = a,		\
+	}
+
+static struct llcc_slice_config qcs605_data[] =  {
+	SCT_ENTRY("cpuss",	 1,  1, 512, 1, 0, 0xF, 0x0, 0, 0, 1, 1, 1),
+	SCT_ENTRY("vidsc0",	 2,  2, 256, 2, 1, 0x3, 0x0, 0, 0, 1, 1, 0),
+	SCT_ENTRY("vidsc1",	 3,  3, 256, 2, 1, 0x3, 0x0, 0, 0, 1, 1, 0),
+	SCT_ENTRY("voice",	 5,  5, 512, 1, 0, 0xF, 0x0, 0, 0, 1, 1, 0),
+	SCT_ENTRY("audio",	 6,  6, 512, 1, 0, 0xF, 0x0, 0, 0, 1, 1, 0),
+	SCT_ENTRY("modem",	 8,  8, 512, 1, 0, 0xF, 0x0, 0, 0, 1, 1, 0),
+	SCT_ENTRY("compute",	10, 10, 512, 1, 0, 0xF, 0x0, 0, 0, 1, 1, 0),
+	SCT_ENTRY("gpu",	12, 12, 512, 1, 0, 0xF, 0x0, 0, 0, 1, 1, 0),
+	SCT_ENTRY("mmuhwt",	13, 13, 512, 1, 0, 0xF, 0x0, 0, 0, 1, 0, 1),
+	SCT_ENTRY("audiohw",	22, 22, 512, 1, 1, 0xF, 0x0, 0, 0, 1, 1, 0),
+};
+
+static int qcs605_qcom_llcc_probe(struct platform_device *pdev)
+{
+	return qcom_llcc_probe(pdev, qcs605_data,
+				 ARRAY_SIZE(qcs605_data));
+}
+
+static const struct of_device_id qcs605_qcom_llcc_of_match[] = {
+	{ .compatible = "qcom,qcs605-llcc", },
+	{ },
+};
+
+static struct platform_driver qcs605_qcom_llcc_driver = {
+	.driver = {
+		.name = "qcs605-llcc",
+		.owner = THIS_MODULE,
+		.of_match_table = qcs605_qcom_llcc_of_match,
+	},
+	.probe = qcs605_qcom_llcc_probe,
+	.remove = qcom_llcc_remove,
+};
+
+static int __init qcs605_init_qcom_llcc_init(void)
+{
+	return platform_driver_register(&qcs605_qcom_llcc_driver);
+}
+module_init(qcs605_init_qcom_llcc_init);
+
+static void __exit qcs605_exit_qcom_llcc_exit(void)
+{
+	platform_driver_unregister(&qcs605_qcom_llcc_driver);
+}
+module_exit(qcs605_exit_qcom_llcc_exit);
+
+MODULE_DESCRIPTION("QTI qcs605 LLCC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/qcom/msm_glink_pkt.c b/drivers/soc/qcom/msm_glink_pkt.c
index a292879..4559f11 100644
--- a/drivers/soc/qcom/msm_glink_pkt.c
+++ b/drivers/soc/qcom/msm_glink_pkt.c
@@ -398,7 +398,10 @@
 	GLINK_PKT_INFO("%s(): priv[%p] pkt_priv[%p] ptr[%p]\n",
 					__func__, priv, pkt_priv, ptr);
 	/* Free Tx buffer allocated in glink_pkt_write */
-	kvfree(ptr);
+	if (is_vmalloc_addr(ptr))
+		vfree_atomic(ptr);
+	else
+		kfree(ptr);
 }
 
 /**
@@ -787,14 +790,20 @@
 		GLINK_PKT_ERR(
 		"%s copy_from_user failed ret[%d] on dev id:%d size %zu\n",
 		 __func__, ret, devp->i, count);
-		kvfree(data);
+		if (is_vmalloc_addr(data))
+			vfree_atomic(data);
+		else
+			kfree(data);
 		return -EFAULT;
 	}
 
 	ret = glink_tx(devp->handle, data, data, count, GLINK_TX_REQ_INTENT);
 	if (ret) {
 		GLINK_PKT_ERR("%s glink_tx failed ret[%d]\n", __func__, ret);
-		kvfree(data);
+		if (is_vmalloc_addr(data))
+			vfree_atomic(data);
+		else
+			kfree(data);
 		return ret;
 	}
 
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 6000707..94a405f 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -279,8 +279,11 @@
 
 void ion_buffer_destroy(struct ion_buffer *buffer)
 {
-	if (WARN_ON(buffer->kmap_cnt > 0))
+	if (buffer->kmap_cnt > 0) {
+		pr_warn_once("%s: buffer still mapped in the kernel\n",
+			     __func__);
 		buffer->heap->ops->unmap_kernel(buffer->heap, buffer);
+	}
 	buffer->heap->ops->unmap_dma(buffer->heap, buffer);
 
 	atomic_long_sub(buffer->size, &buffer->heap->total_allocated);
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
index e8b34f1..a3adf21 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -1078,13 +1078,14 @@
 	return 0;
 }
 
+static const u8 omap4_habit = UART_ERRATA_CLOCK_DISABLE;
 static const u8 am3352_habit = OMAP_DMA_TX_KICK | UART_ERRATA_CLOCK_DISABLE;
 static const u8 dra742_habit = UART_ERRATA_CLOCK_DISABLE;
 
 static const struct of_device_id omap8250_dt_ids[] = {
 	{ .compatible = "ti,omap2-uart" },
 	{ .compatible = "ti,omap3-uart" },
-	{ .compatible = "ti,omap4-uart" },
+	{ .compatible = "ti,omap4-uart", .data = &omap4_habit, },
 	{ .compatible = "ti,am3352-uart", .data = &am3352_habit, },
 	{ .compatible = "ti,am4372-uart", .data = &am3352_habit, },
 	{ .compatible = "ti,dra742-uart", .data = &dra742_habit, },
@@ -1326,6 +1327,19 @@
 	int sysc;
 	int syss;
 
+	/*
+	 * At least on omap4, unused uarts may not idle after reset without
+	 * a basic scr dma configuration even with no dma in use. The
+	 * module clkctrl status bits will be 1 instead of 3 blocking idle
+	 * for the whole clockdomain. The softreset below will clear scr,
+	 * and we restore it on resume so this is safe to do on all SoCs
+	 * needing omap8250_soft_reset() quirk. Do it in two writes as
+	 * recommended in the comment for omap8250_update_scr().
+	 */
+	serial_out(up, UART_OMAP_SCR, OMAP_UART_SCR_DMAMODE_1);
+	serial_out(up, UART_OMAP_SCR,
+		   OMAP_UART_SCR_DMAMODE_1 | OMAP_UART_SCR_DMAMODE_CTL);
+
 	sysc = serial_in(up, UART_OMAP_SYSC);
 
 	/* softreset the UART */
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index b42d7f1..41b0dd6 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -1726,10 +1726,26 @@
  */
 static void pl011_enable_interrupts(struct uart_amba_port *uap)
 {
+	unsigned int i;
+
 	spin_lock_irq(&uap->port.lock);
 
 	/* Clear out any spuriously appearing RX interrupts */
 	pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR);
+
+	/*
+	 * RXIS is asserted only when the RX FIFO transitions from below
+	 * to above the trigger threshold.  If the RX FIFO is already
+	 * full to the threshold this can't happen and RXIS will now be
+	 * stuck off.  Drain the RX FIFO explicitly to fix this:
+	 */
+	for (i = 0; i < uap->fifosize * 2; ++i) {
+		if (pl011_read(uap, REG_FR) & UART01x_FR_RXFE)
+			break;
+
+		pl011_read(uap, REG_DR);
+	}
+
 	uap->im = UART011_RTIM;
 	if (!pl011_dma_rx_running(uap))
 		uap->im |= UART011_RXIM;
@@ -2320,12 +2336,67 @@
 	return uart_set_options(&uap->port, co, baud, parity, bits, flow);
 }
 
+/**
+ *	pl011_console_match - non-standard console matching
+ *	@co:	  registering console
+ *	@name:	  name from console command line
+ *	@idx:	  index from console command line
+ *	@options: ptr to option string from console command line
+ *
+ *	Only attempts to match console command lines of the form:
+ *	    console=pl011,mmio|mmio32,<addr>[,<options>]
+ *	    console=pl011,0x<addr>[,<options>]
+ *	This form is used to register an initial earlycon boot console and
+ *	replace it with the amba_console at pl011 driver init.
+ *
+ *	Performs console setup for a match (as required by interface)
+ *	If no <options> are specified, then assume the h/w is already setup.
+ *
+ *	Returns 0 if console matches; otherwise non-zero to use default matching
+ */
+static int __init pl011_console_match(struct console *co, char *name, int idx,
+				      char *options)
+{
+	unsigned char iotype;
+	resource_size_t addr;
+	int i;
+
+	if (strcmp(name, "pl011") != 0)
+		return -ENODEV;
+
+	if (uart_parse_earlycon(options, &iotype, &addr, &options))
+		return -ENODEV;
+
+	if (iotype != UPIO_MEM && iotype != UPIO_MEM32)
+		return -ENODEV;
+
+	/* try to match the port specified on the command line */
+	for (i = 0; i < ARRAY_SIZE(amba_ports); i++) {
+		struct uart_port *port;
+
+		if (!amba_ports[i])
+			continue;
+
+		port = &amba_ports[i]->port;
+
+		if (port->mapbase != addr)
+			continue;
+
+		co->index = i;
+		port->cons = co;
+		return pl011_console_setup(co, options);
+	}
+
+	return -ENODEV;
+}
+
 static struct uart_driver amba_reg;
 static struct console amba_console = {
 	.name		= "ttyAMA",
 	.write		= pl011_console_write,
 	.device		= uart_console_device,
 	.setup		= pl011_console_setup,
+	.match		= pl011_console_match,
 	.flags		= CON_PRINTBUFFER,
 	.index		= -1,
 	.data		= &amba_reg,
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index addb287..5a341b1 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -1803,7 +1803,6 @@
 {
 	struct platform_device *pdev = to_platform_device(port->dev);
 	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
-	struct tty_struct *tty = port->state->port.tty;
 	int retval;
 
 	/*
@@ -1818,8 +1817,8 @@
 	 * Allocate the IRQ
 	 */
 	retval = request_irq(port->irq, atmel_interrupt,
-			IRQF_SHARED | IRQF_COND_SUSPEND,
-			tty ? tty->name : "atmel_serial", port);
+			     IRQF_SHARED | IRQF_COND_SUSPEND,
+			     dev_name(&pdev->dev), port);
 	if (retval) {
 		dev_err(port->dev, "atmel_startup - Can't get irq\n");
 		return retval;
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index f2ab6d8a..5609305 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -866,15 +866,12 @@
 	dma->rx_conf.direction		= DMA_DEV_TO_MEM;
 	dma->rx_conf.src_addr_width	= DMA_SLAVE_BUSWIDTH_1_BYTE;
 	dma->rx_conf.src_addr		= p->port.mapbase + S3C2410_URXH;
-	dma->rx_conf.src_maxburst	= 16;
+	dma->rx_conf.src_maxburst	= 1;
 
 	dma->tx_conf.direction		= DMA_MEM_TO_DEV;
 	dma->tx_conf.dst_addr_width	= DMA_SLAVE_BUSWIDTH_1_BYTE;
 	dma->tx_conf.dst_addr		= p->port.mapbase + S3C2410_UTXH;
-	if (dma_get_cache_alignment() >= 16)
-		dma->tx_conf.dst_maxburst = 16;
-	else
-		dma->tx_conf.dst_maxburst = 1;
+	dma->tx_conf.dst_maxburst	= 1;
 
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_SLAVE, mask);
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 107f0d1..da46f0f 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -2626,8 +2626,8 @@
 			dev_dbg(dev, "failed to get %s (%ld)\n", clk_names[i],
 				PTR_ERR(clk));
 		else
-			dev_dbg(dev, "clk %s is %pC rate %pCr\n", clk_names[i],
-				clk, clk);
+			dev_dbg(dev, "clk %s is %pC rate %lu\n", clk_names[i],
+				clk, clk_get_rate(clk));
 		sci_port->clks[i] = IS_ERR(clk) ? NULL : clk;
 	}
 	return 0;
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 876679a..f794741 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -763,18 +763,21 @@
 		return;
 
 	if (dev->rawdescriptors) {
-		for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
+		for (i = 0; i < dev->descriptor.bNumConfigurations &&
+				i < USB_MAXCONFIG; i++)
 			kfree(dev->rawdescriptors[i]);
 
 		kfree(dev->rawdescriptors);
 		dev->rawdescriptors = NULL;
 	}
 
-	for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
+	for (c = 0; c < dev->descriptor.bNumConfigurations &&
+			c < USB_MAXCONFIG; c++) {
 		struct usb_host_config *cf = &dev->config[c];
 
 		kfree(cf->string);
-		for (i = 0; i < cf->desc.bNumInterfaces; i++) {
+		for (i = 0; i < cf->desc.bNumInterfaces &&
+				i < USB_MAXINTERFACES; i++) {
 			if (cf->intf_cache[i])
 				kref_put(&cf->intf_cache[i]->ref,
 					  usb_release_interface_cache);
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 2c30660..f99b2bd 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -255,6 +255,7 @@
 	struct notifier_block	id_nb;
 	struct notifier_block	eud_event_nb;
 	struct notifier_block	host_restart_nb;
+	struct notifier_block	self_power_nb;
 
 	struct notifier_block	host_nb;
 	bool			xhci_ss_compliance_enable;
@@ -296,6 +297,8 @@
 						unsigned int value);
 static int dwc3_restart_usb_host_mode(struct notifier_block *nb,
 					unsigned long event, void *ptr);
+static int dwc3_notify_pd_status(struct notifier_block *nb,
+				unsigned long event, void *ptr);
 
 /**
  *
@@ -3041,12 +3044,19 @@
 	if (!IS_ERR(edev)) {
 		mdwc->extcon_vbus = edev;
 		mdwc->vbus_nb.notifier_call = dwc3_msm_vbus_notifier;
+		mdwc->self_power_nb.notifier_call = dwc3_notify_pd_status;
 		ret = extcon_register_notifier(edev, EXTCON_USB,
 				&mdwc->vbus_nb);
 		if (ret < 0) {
 			dev_err(mdwc->dev, "failed to register notifier for USB\n");
 			return ret;
 		}
+		ret = extcon_register_blocking_notifier(edev, EXTCON_USB,
+							&mdwc->self_power_nb);
+		if (ret < 0) {
+			dev_err(mdwc->dev, "failed to register blocking notifier\n");
+			goto err1;
+		}
 	}
 
 	/*
@@ -4148,6 +4158,28 @@
 	return 0;
 }
 
+static int dwc3_notify_pd_status(struct notifier_block *nb,
+				unsigned long event, void *ptr)
+{
+	struct dwc3_msm *mdwc;
+	struct dwc3 *dwc;
+	int ret = 0;
+	union extcon_property_value val;
+
+	mdwc = container_of(nb, struct dwc3_msm, self_power_nb);
+	dwc = platform_get_drvdata(mdwc->dwc3);
+
+	ret = extcon_get_property(mdwc->extcon_vbus, EXTCON_USB,
+					EXTCON_PROP_USB_PD_CONTRACT, &val);
+
+	if (!ret)
+		dwc->gadget.self_powered = val.intval;
+	else
+		dwc->gadget.self_powered = 0;
+
+	return ret;
+}
+
 /* speed: 0 - USB_SPEED_HIGH, 1 - USB_SPEED_SUPER */
 static int dwc3_restart_usb_host_mode(struct notifier_block *nb,
 				unsigned long event, void *ptr)
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 6f8a04e..32729c6 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -594,6 +594,10 @@
 	c->iConfiguration = config->iConfiguration;
 	c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes;
 	c->bMaxPower = encode_bMaxPower(speed, config);
+	if (config->cdev->gadget->self_powered) {
+		c->bmAttributes |= USB_CONFIG_ATT_SELFPOWER;
+		c->bMaxPower = 0;
+	}
 
 	/* There may be e.g. OTG descriptors */
 	if (config->descriptors) {
diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c
index 2197a50..b1ae944 100644
--- a/drivers/usb/gadget/udc/renesas_usb3.c
+++ b/drivers/usb/gadget/udc/renesas_usb3.c
@@ -521,6 +521,13 @@
 	usb3_usb2_pullup(usb3, 0);
 	usb3_clear_bit(usb3, USB30_CON_B3_CONNECT, USB3_USB30_CON);
 	usb3_reset_epc(usb3);
+	usb3_disable_irq_1(usb3, USB_INT_1_B2_RSUM | USB_INT_1_B3_PLLWKUP |
+			   USB_INT_1_B3_LUPSUCS | USB_INT_1_B3_DISABLE |
+			   USB_INT_1_SPEED | USB_INT_1_B3_WRMRST |
+			   USB_INT_1_B3_HOTRST | USB_INT_1_B2_SPND |
+			   USB_INT_1_B2_L1SPND | USB_INT_1_B2_USBRST);
+	usb3_clear_bit(usb3, USB_COM_CON_SPD_MODE, USB3_USB_COM_CON);
+	usb3_init_epc_registers(usb3);
 
 	if (usb3->driver)
 		usb3->driver->disconnect(&usb3->gadget);
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index e2bc915..19b5f08 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -2554,8 +2554,11 @@
 {
 	struct musb	*musb = hcd_to_musb(hcd);
 	u8		devctl;
+	int		ret;
 
-	musb_port_suspend(musb, true);
+	ret = musb_port_suspend(musb, true);
+	if (ret)
+		return ret;
 
 	if (!is_host_active(musb))
 		return 0;
diff --git a/drivers/usb/musb/musb_host.h b/drivers/usb/musb/musb_host.h
index 7bbf01b..54d02ed 100644
--- a/drivers/usb/musb/musb_host.h
+++ b/drivers/usb/musb/musb_host.h
@@ -92,7 +92,7 @@
 extern void musb_root_disconnect(struct musb *musb);
 extern void musb_host_resume_root_hub(struct musb *musb);
 extern void musb_host_poke_root_hub(struct musb *musb);
-extern void musb_port_suspend(struct musb *musb, bool do_suspend);
+extern int musb_port_suspend(struct musb *musb, bool do_suspend);
 extern void musb_port_reset(struct musb *musb, bool do_reset);
 extern void musb_host_finish_resume(struct work_struct *work);
 #else
@@ -124,7 +124,10 @@
 static inline void musb_host_resume_root_hub(struct musb *musb)	{}
 static inline void musb_host_poll_rh_status(struct musb *musb)	{}
 static inline void musb_host_poke_root_hub(struct musb *musb)	{}
-static inline void musb_port_suspend(struct musb *musb, bool do_suspend) {}
+static inline int musb_port_suspend(struct musb *musb, bool do_suspend)
+{
+	return 0;
+}
 static inline void musb_port_reset(struct musb *musb, bool do_reset) {}
 static inline void musb_host_finish_resume(struct work_struct *work) {}
 #endif
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c
index 61b5f1c..71678a4 100644
--- a/drivers/usb/musb/musb_virthub.c
+++ b/drivers/usb/musb/musb_virthub.c
@@ -73,14 +73,14 @@
 	spin_unlock_irqrestore(&musb->lock, flags);
 }
 
-void musb_port_suspend(struct musb *musb, bool do_suspend)
+int musb_port_suspend(struct musb *musb, bool do_suspend)
 {
 	struct usb_otg	*otg = musb->xceiv->otg;
 	u8		power;
 	void __iomem	*mbase = musb->mregs;
 
 	if (!is_host_active(musb))
-		return;
+		return 0;
 
 	/* NOTE:  this doesn't necessarily put PHY into low power mode,
 	 * turning off its clock; that's a function of PHY integration and
@@ -91,16 +91,20 @@
 	if (do_suspend) {
 		int retries = 10000;
 
-		power &= ~MUSB_POWER_RESUME;
-		power |= MUSB_POWER_SUSPENDM;
-		musb_writeb(mbase, MUSB_POWER, power);
+		if (power & MUSB_POWER_RESUME)
+			return -EBUSY;
 
-		/* Needed for OPT A tests */
-		power = musb_readb(mbase, MUSB_POWER);
-		while (power & MUSB_POWER_SUSPENDM) {
+		if (!(power & MUSB_POWER_SUSPENDM)) {
+			power |= MUSB_POWER_SUSPENDM;
+			musb_writeb(mbase, MUSB_POWER, power);
+
+			/* Needed for OPT A tests */
 			power = musb_readb(mbase, MUSB_POWER);
-			if (retries-- < 1)
-				break;
+			while (power & MUSB_POWER_SUSPENDM) {
+				power = musb_readb(mbase, MUSB_POWER);
+				if (retries-- < 1)
+					break;
+			}
 		}
 
 		musb_dbg(musb, "Root port suspended, power %02x", power);
@@ -137,6 +141,7 @@
 		schedule_delayed_work(&musb->finish_resume_work,
 				      msecs_to_jiffies(USB_RESUME_TIMEOUT));
 	}
+	return 0;
 }
 
 void musb_port_reset(struct musb *musb, bool do_reset)
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index 2c0c0ed..a9adf0b 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -533,6 +533,22 @@
 	extcon_set_state_sync(pd->extcon, EXTCON_USB, 1);
 }
 
+static void notify_pd_contract_status(struct usbpd *pd)
+{
+	int ret = 0;
+	union extcon_property_value val;
+
+	if (!pd)
+		return;
+
+	val.intval = pd->in_explicit_contract;
+	extcon_set_property(pd->extcon, EXTCON_USB,
+			EXTCON_PROP_USB_PD_CONTRACT, val);
+	ret = extcon_blocking_sync(pd->extcon, EXTCON_USB, 0);
+	if (ret)
+		usbpd_err(&pd->dev, "err(%d) while notifying pd status", ret);
+}
+
 /**
  * This API allows client driver to request for releasing SS lanes. It should
  * not be called from atomic context.
@@ -1252,6 +1268,7 @@
 
 	case PE_SRC_READY:
 		pd->in_explicit_contract = true;
+		notify_pd_contract_status(pd);
 
 		if (pd->vdm_tx)
 			kick_sm(pd, 0);
@@ -1398,6 +1415,7 @@
 
 	case PE_SNK_READY:
 		pd->in_explicit_contract = true;
+		notify_pd_contract_status(pd);
 
 		if (pd->vdm_tx)
 			kick_sm(pd, 0);
@@ -1433,6 +1451,7 @@
 				POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val);
 
 		pd->in_explicit_contract = false;
+		notify_pd_contract_status(pd);
 
 		/*
 		 * need to update PR bit in message header so that
@@ -1929,6 +1948,22 @@
 	else
 		pd->vbus_enabled = true;
 
+	count = 10;
+	/*
+	 * Check to make sure VBUS voltage reaches above Vsafe5Vmin (4.75v)
+	 * before proceeding.
+	 */
+	while (count--) {
+		ret = power_supply_get_property(pd->usb_psy,
+				POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
+		if (ret || val.intval >= 4750000) /*vsafe5Vmin*/
+			break;
+		usleep_range(10000, 12000); /* Delay between two reads */
+	}
+
+	if (ret)
+		msleep(100); /* Delay to wait for VBUS ramp up if read fails */
+
 	return ret;
 }
 
@@ -1996,6 +2031,7 @@
 		pd->in_pr_swap = false;
 		pd->pd_connected = false;
 		pd->in_explicit_contract = false;
+		notify_pd_contract_status(pd);
 		pd->hard_reset_recvd = false;
 		pd->caps_count = 0;
 		pd->hard_reset_count = 0;
@@ -2079,6 +2115,7 @@
 				POWER_SUPPLY_PROP_PR_SWAP, &val);
 
 		pd->in_explicit_contract = false;
+		notify_pd_contract_status(pd);
 		pd->selected_pdo = pd->requested_pdo = 0;
 		pd->rdo = 0;
 		rx_msg_cleanup(pd);
@@ -2302,6 +2339,7 @@
 
 		pd_send_hard_reset(pd);
 		pd->in_explicit_contract = false;
+		notify_pd_contract_status(pd);
 		pd->rdo = 0;
 		rx_msg_cleanup(pd);
 		reset_vdm_state(pd);
@@ -2752,6 +2790,7 @@
 
 		pd_send_hard_reset(pd);
 		pd->in_explicit_contract = false;
+		notify_pd_contract_status(pd);
 		pd->selected_pdo = pd->requested_pdo = 0;
 		pd->rdo = 0;
 		reset_vdm_state(pd);
@@ -2783,6 +2822,7 @@
 		power_supply_set_property(pd->usb_psy,
 				POWER_SUPPLY_PROP_PR_SWAP, &val);
 		pd->in_explicit_contract = false;
+		notify_pd_contract_status(pd);
 
 		if (pd->vbus_enabled) {
 			regulator_disable(pd->vbus);
@@ -2843,7 +2883,6 @@
 
 	case PE_PRS_SNK_SRC_SOURCE_ON:
 		enable_vbus(pd);
-		msleep(200); /* allow time VBUS ramp-up, must be < tNewSrc */
 
 		ret = pd_send_msg(pd, MSG_PS_RDY, NULL, 0, SOP_MSG);
 		if (ret) {
@@ -3991,6 +4030,8 @@
 	extcon_set_property_capability(pd->extcon, EXTCON_USB,
 			EXTCON_PROP_USB_TYPEC_POLARITY);
 	extcon_set_property_capability(pd->extcon, EXTCON_USB,
+			EXTCON_PROP_USB_PD_CONTRACT);
+	extcon_set_property_capability(pd->extcon, EXTCON_USB,
 			EXTCON_PROP_USB_SS);
 	extcon_set_property_capability(pd->extcon, EXTCON_USB_HOST,
 			EXTCON_PROP_USB_TYPEC_POLARITY);
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 90d7c6e..2c31015 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -33,7 +33,7 @@
 static void cp210x_close(struct usb_serial_port *);
 static void cp210x_get_termios(struct tty_struct *, struct usb_serial_port *);
 static void cp210x_get_termios_port(struct usb_serial_port *port,
-	unsigned int *cflagp, unsigned int *baudp);
+	tcflag_t *cflagp, unsigned int *baudp);
 static void cp210x_change_speed(struct tty_struct *, struct usb_serial_port *,
 							struct ktermios *);
 static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *,
@@ -728,7 +728,7 @@
 			&tty->termios.c_cflag, &baud);
 		tty_encode_baud_rate(tty, baud, baud);
 	} else {
-		unsigned int cflag;
+		tcflag_t cflag;
 		cflag = 0;
 		cp210x_get_termios_port(port, &cflag, &baud);
 	}
@@ -739,10 +739,10 @@
  * This is the heart of cp210x_get_termios which always uses a &usb_serial_port.
  */
 static void cp210x_get_termios_port(struct usb_serial_port *port,
-	unsigned int *cflagp, unsigned int *baudp)
+	tcflag_t *cflagp, unsigned int *baudp)
 {
 	struct device *dev = &port->dev;
-	unsigned int cflag;
+	tcflag_t cflag;
 	struct cp210x_flow_ctl flow_ctl;
 	u32 baud;
 	u16 bits = 0;
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index a96dcc6..8dd200f 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -836,6 +836,12 @@
 	if (devinfo->flags & US_FL_BROKEN_FUA)
 		sdev->broken_fua = 1;
 
+	/* UAS also needs to support FL_ALWAYS_SYNC */
+	if (devinfo->flags & US_FL_ALWAYS_SYNC) {
+		sdev->skip_ms_page_3f = 1;
+		sdev->skip_ms_page_8 = 1;
+		sdev->wce_default_on = 1;
+	}
 	scsi_change_queue_depth(sdev, devinfo->qdepth - 2);
 	return 0;
 }
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index ca3a5d4..fc5ed35 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -2340,6 +2340,15 @@
 		"Micro Mini 1GB",
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ),
 
+/* "G-DRIVE" external HDD hangs on write without these.
+ * Patch submitted by Alexander Kappner <agk@godking.net>
+ */
+UNUSUAL_DEV(0x4971, 0x8024, 0x0000, 0x9999,
+		"SimpleTech",
+		"External HDD",
+		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+		US_FL_ALWAYS_SYNC),
+
 /*
  * Nick Bowler <nbowler@elliptictech.com>
  * SCSI stack spams (otherwise harmless) error messages.
diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h
index 719ec68..f15aa47 100644
--- a/drivers/usb/storage/unusual_uas.h
+++ b/drivers/usb/storage/unusual_uas.h
@@ -183,3 +183,12 @@
 		"External HDD",
 		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 		US_FL_NO_REPORT_OPCODES),
+
+/* "G-DRIVE" external HDD hangs on write without these.
+ * Patch submitted by Alexander Kappner <agk@godking.net>
+ */
+UNUSUAL_DEV(0x4971, 0x8024, 0x0000, 0x9999,
+		"SimpleTech",
+		"External HDD",
+		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+		US_FL_ALWAYS_SYNC),
diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c
index c287ccc..e8a008d 100644
--- a/drivers/usb/usbip/vhci_sysfs.c
+++ b/drivers/usb/usbip/vhci_sysfs.c
@@ -24,6 +24,9 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
+/* Hardening for Spectre-v1 */
+#include <linux/nospec.h>
+
 #include "usbip_common.h"
 #include "vhci.h"
 
@@ -181,16 +184,20 @@
 	return 0;
 }
 
-static int valid_port(__u32 pdev_nr, __u32 rhport)
+static int valid_port(__u32 *pdev_nr, __u32 *rhport)
 {
-	if (pdev_nr >= vhci_num_controllers) {
-		pr_err("pdev %u\n", pdev_nr);
+	if (*pdev_nr >= vhci_num_controllers) {
+		pr_err("pdev %u\n", *pdev_nr);
 		return 0;
 	}
-	if (rhport >= VHCI_HC_PORTS) {
-		pr_err("rhport %u\n", rhport);
+	*pdev_nr = array_index_nospec(*pdev_nr, vhci_num_controllers);
+
+	if (*rhport >= VHCI_HC_PORTS) {
+		pr_err("rhport %u\n", *rhport);
 		return 0;
 	}
+	*rhport = array_index_nospec(*rhport, VHCI_HC_PORTS);
+
 	return 1;
 }
 
@@ -207,7 +214,7 @@
 	pdev_nr = port_to_pdev_nr(port);
 	rhport = port_to_rhport(port);
 
-	if (!valid_port(pdev_nr, rhport))
+	if (!valid_port(&pdev_nr, &rhport))
 		return -EINVAL;
 
 	hcd = platform_get_drvdata(*(vhci_pdevs + pdev_nr));
@@ -226,7 +233,8 @@
 }
 static DEVICE_ATTR(detach, S_IWUSR, NULL, store_detach);
 
-static int valid_args(__u32 pdev_nr, __u32 rhport, enum usb_device_speed speed)
+static int valid_args(__u32 *pdev_nr, __u32 *rhport,
+		      enum usb_device_speed speed)
 {
 	if (!valid_port(pdev_nr, rhport)) {
 		return 0;
@@ -288,7 +296,7 @@
 			     sockfd, devid, speed);
 
 	/* check received parameters */
-	if (!valid_args(pdev_nr, rhport, speed))
+	if (!valid_args(&pdev_nr, &rhport, speed))
 		return -EINVAL;
 
 	hcd = platform_get_drvdata(*(vhci_pdevs + pdev_nr));
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index fce49eb..8b6489a 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -938,6 +938,7 @@
 {
 	int ret = 0;
 
+	mutex_lock(&dev->mutex);
 	vhost_dev_lock_vqs(dev);
 	switch (msg->type) {
 	case VHOST_IOTLB_UPDATE:
@@ -967,6 +968,8 @@
 	}
 
 	vhost_dev_unlock_vqs(dev);
+	mutex_unlock(&dev->mutex);
+
 	return ret;
 }
 ssize_t vhost_chr_write_iter(struct vhost_dev *dev,
@@ -2292,6 +2295,9 @@
 	struct vhost_msg_node *node = kmalloc(sizeof *node, GFP_KERNEL);
 	if (!node)
 		return NULL;
+
+	/* Make sure all padding within the structure is initialized. */
+	memset(&node->msg, 0, sizeof node->msg);
 	node->vq = vq;
 	node->msg.type = type;
 	return node;
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index 2ef33d4..52bbbc4 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -1219,8 +1219,6 @@
 		console_unlock();
 		break;
 	default:
-		if (!lock_fb_info(info))
-			return -ENODEV;
 		fb = info->fbops;
 		if (fb->fb_ioctl_v2)
 			ret = fb->fb_ioctl_v2(info, cmd, arg, file);
@@ -1228,7 +1226,6 @@
 			ret = fb->fb_ioctl(info, cmd, arg);
 		else
 			ret = -ENOTTY;
-		unlock_fb_info(info);
 	}
 	return ret;
 }
diff --git a/drivers/video/fbdev/msm/mdss_compat_utils.c b/drivers/video/fbdev/msm/mdss_compat_utils.c
index a81f149..23d4a27 100644
--- a/drivers/video/fbdev/msm/mdss_compat_utils.c
+++ b/drivers/video/fbdev/msm/mdss_compat_utils.c
@@ -2879,26 +2879,28 @@
 			*pp = compat_alloc_user_space(alloc_size);
 			if (*pp == NULL)
 				return -ENOMEM;
-			memset(*pp, 0, alloc_size);
-
-			(*pp)->data.lut_cfg_data.data.pgc_lut_data.r_data =
-					(struct mdp_ar_gc_lut_data *)
-					((unsigned long) *pp +
-					sizeof(struct msmfb_mdp_pp));
-			(*pp)->data.lut_cfg_data.data.pgc_lut_data.g_data =
-					(struct mdp_ar_gc_lut_data *)
+			if (clear_user(*pp, alloc_size))
+				return -EFAULT;
+			if (put_user((struct mdp_ar_gc_lut_data *)
+				((unsigned long) *pp +
+				sizeof(struct msmfb_mdp_pp)),
+			&(*pp)->data.lut_cfg_data.data.pgc_lut_data.r_data) ||
+				put_user((struct mdp_ar_gc_lut_data *)
 					((unsigned long) *pp +
 					sizeof(struct msmfb_mdp_pp) +
-					pgc_size);
-			(*pp)->data.lut_cfg_data.data.pgc_lut_data.b_data =
-					(struct mdp_ar_gc_lut_data *)
+					pgc_size),
+			&(*pp)->data.lut_cfg_data.data.pgc_lut_data.g_data) ||
+				put_user((struct mdp_ar_gc_lut_data *)
 					((unsigned long) *pp +
 					sizeof(struct msmfb_mdp_pp) +
-					(2 * pgc_size));
-			(*pp)->data.lut_cfg_data.data.pgc_lut_data.cfg_payload
-					 = (void *)((unsigned long) *pp +
+					(2 * pgc_size)),
+			&(*pp)->data.lut_cfg_data.data.pgc_lut_data.b_data) ||
+				put_user((void *)((unsigned long) *pp +
 					sizeof(struct msmfb_mdp_pp) +
-					(3 * pgc_size));
+					(3 * pgc_size)),
+					&(*pp)->data.lut_cfg_data.data.
+						pgc_lut_data.cfg_payload))
+				return -EFAULT;
 			break;
 		case mdp_lut_igc:
 			alloc_size += __pp_compat_size_igc();
@@ -2908,10 +2910,13 @@
 					alloc_size);
 				return -ENOMEM;
 			}
-			memset(*pp, 0, alloc_size);
-			(*pp)->data.lut_cfg_data.data.igc_lut_data.cfg_payload
-					= (void *)((unsigned long)(*pp) +
-					   sizeof(struct msmfb_mdp_pp));
+			if (clear_user(*pp, alloc_size))
+				return -EFAULT;
+			if (put_user((void *)((unsigned long)(*pp) +
+					sizeof(struct msmfb_mdp_pp)),
+					&(*pp)->data.lut_cfg_data.data.
+						igc_lut_data.cfg_payload))
+				return -EFAULT;
 			break;
 		case mdp_lut_hist:
 			alloc_size += __pp_compat_size_hist_lut();
@@ -2921,10 +2926,13 @@
 					alloc_size);
 				return -ENOMEM;
 			}
-			memset(*pp, 0, alloc_size);
-			(*pp)->data.lut_cfg_data.data.hist_lut_data.cfg_payload
-					= (void *)((unsigned long)(*pp) +
-					   sizeof(struct msmfb_mdp_pp));
+			if (clear_user(*pp, alloc_size))
+				return -EFAULT;
+			if (put_user((void *)((unsigned long)(*pp) +
+					sizeof(struct msmfb_mdp_pp)),
+					&(*pp)->data.lut_cfg_data.data.
+						hist_lut_data.cfg_payload))
+				return -EFAULT;
 			break;
 		default:
 			*pp = compat_alloc_user_space(alloc_size);
@@ -2933,7 +2941,8 @@
 					alloc_size, lut_type);
 				return -ENOMEM;
 			}
-			memset(*pp, 0, alloc_size);
+			if (clear_user(*pp, alloc_size))
+				return -EFAULT;
 			break;
 		}
 		break;
@@ -2945,10 +2954,12 @@
 				alloc_size);
 			return -ENOMEM;
 		}
-		memset(*pp, 0, alloc_size);
-		(*pp)->data.pcc_cfg_data.cfg_payload =
-				(void *)((unsigned long)(*pp) +
-				 sizeof(struct msmfb_mdp_pp));
+		if (clear_user(*pp, alloc_size))
+			return -EFAULT;
+		if (put_user((void *)((unsigned long)(*pp) +
+				sizeof(struct msmfb_mdp_pp)),
+			&(*pp)->data.pcc_cfg_data.cfg_payload))
+			return -EFAULT;
 		break;
 	case mdp_op_gamut_cfg:
 		alloc_size += __pp_compat_size_gamut();
@@ -2958,10 +2969,12 @@
 				alloc_size);
 			return -ENOMEM;
 		}
-		memset(*pp, 0, alloc_size);
-		(*pp)->data.gamut_cfg_data.cfg_payload =
-				(void *)((unsigned long)(*pp) +
-				 sizeof(struct msmfb_mdp_pp));
+		if (clear_user(*pp, alloc_size))
+			return -EFAULT;
+		if (put_user((void *)((unsigned long)(*pp) +
+				sizeof(struct msmfb_mdp_pp)),
+			&(*pp)->data.gamut_cfg_data.cfg_payload))
+			return -EFAULT;
 		break;
 	case mdp_op_pa_v2_cfg:
 		alloc_size += __pp_compat_size_pa();
@@ -2971,16 +2984,19 @@
 				alloc_size);
 			return -ENOMEM;
 		}
-		memset(*pp, 0, alloc_size);
-		(*pp)->data.pa_v2_cfg_data.cfg_payload =
-				(void *)((unsigned long)(*pp) +
-				sizeof(struct msmfb_mdp_pp));
+		if (clear_user(*pp, alloc_size))
+			return -EFAULT;
+		if (put_user((void *)((unsigned long)(*pp) +
+				sizeof(struct msmfb_mdp_pp)),
+			&(*pp)->data.pa_v2_cfg_data.cfg_payload))
+			return -EFAULT;
 		break;
 	default:
 		*pp = compat_alloc_user_space(alloc_size);
 		if (*pp == NULL)
 			return -ENOMEM;
-		memset(*pp, 0, alloc_size);
+		if (clear_user(*pp, alloc_size))
+			return -EFAULT;
 		break;
 	}
 	return 0;
@@ -3398,7 +3414,9 @@
 				 sizeof(struct mdp_histogram_start_req));
 			return -EINVAL;
 		}
-		memset(hist_req, 0, sizeof(struct mdp_histogram_start_req));
+		if (clear_user(hist_req,
+				 sizeof(struct mdp_histogram_start_req)))
+			return -EFAULT;
 		ret = __from_user_hist_start_req(hist_req32, hist_req);
 		if (ret)
 			goto histo_compat_err;
@@ -3418,7 +3436,8 @@
 				 sizeof(struct mdp_histogram_data));
 			return -EINVAL;
 		}
-		memset(hist, 0, sizeof(struct mdp_histogram_data));
+		if (clear_user(hist, sizeof(struct mdp_histogram_data)))
+			return -EFAULT;
 		ret = __from_user_hist_data(hist32, hist);
 		if (ret)
 			goto histo_compat_err;
@@ -3921,7 +3940,7 @@
 }
 
 
-static int __from_user_mdp_overlay(struct mdp_overlay *ov,
+static int __from_user_mdp_overlay(struct mdp_overlay __user *ov,
 				   struct mdp_overlay32 __user *ov32)
 {
 	__u32 data;
@@ -3980,12 +3999,12 @@
 	return 0;
 }
 
-static int __from_user_mdp_overlaylist(struct mdp_overlay_list *ovlist,
-				   struct mdp_overlay_list32 *ovlist32,
+static int __from_user_mdp_overlaylist(struct mdp_overlay_list __user *ovlist,
+				   struct mdp_overlay_list32 __user *ovlist32,
 				   struct mdp_overlay **to_list_head)
 {
 	__u32 i, ret;
-	unsigned long data, from_list_head;
+	unsigned long data, from_list_head, num_overlays;
 	struct mdp_overlay32 *iter;
 
 	if (!to_list_head || !ovlist32 || !ovlist) {
@@ -4006,11 +4025,13 @@
 			 sizeof(ovlist32->processed_overlays)))
 		return -EFAULT;
 
-	if (get_user(data, &ovlist32->overlay_list)) {
+	if (get_user(data, &ovlist32->overlay_list) ||
+		get_user(num_overlays, &ovlist32->num_overlays)) {
 		ret = -EFAULT;
 		goto validate_exit;
 	}
-	for (i = 0; i < ovlist32->num_overlays; i++) {
+
+	for (i = 0; i < num_overlays; i++) {
 		if (get_user(from_list_head, (__u32 *)data + i)) {
 			ret = -EFAULT;
 			goto validate_exit;
@@ -4023,7 +4044,8 @@
 			goto validate_exit;
 		}
 	}
-	ovlist->overlay_list = to_list_head;
+	if (put_user(to_list_head, &ovlist->overlay_list))
+		return -EFAULT;
 
 	return 0;
 
@@ -4032,8 +4054,8 @@
 	return -EFAULT;
 }
 
-static int __to_user_mdp_overlaylist(struct mdp_overlay_list32 *ovlist32,
-				   struct mdp_overlay_list *ovlist,
+static int __to_user_mdp_overlaylist(struct mdp_overlay_list32 __user *ovlist32,
+				   struct mdp_overlay_list __user *ovlist,
 				   struct mdp_overlay **l_ptr)
 {
 	__u32 i, ret;
@@ -4106,31 +4128,33 @@
 	return size;
 }
 
-static int __pp_sspp_set_offsets(struct mdp_overlay *ov)
+static int __pp_sspp_set_offsets(struct mdp_overlay __user *ov)
 {
 	if (!ov) {
 		pr_err("invalid overlay pointer\n");
 		return -EFAULT;
 	}
-	ov->overlay_pp_cfg.igc_cfg.cfg_payload = (void *)((unsigned long)ov +
-				sizeof(struct mdp_overlay));
-	ov->overlay_pp_cfg.pa_v2_cfg_data.cfg_payload =
-		ov->overlay_pp_cfg.igc_cfg.cfg_payload +
-		sizeof(struct mdp_igc_lut_data_v1_7);
-	ov->overlay_pp_cfg.pcc_cfg_data.cfg_payload =
-		ov->overlay_pp_cfg.pa_v2_cfg_data.cfg_payload +
-		sizeof(struct mdp_pa_data_v1_7);
-	ov->overlay_pp_cfg.hist_lut_cfg.cfg_payload =
-		ov->overlay_pp_cfg.pcc_cfg_data.cfg_payload +
-		sizeof(struct mdp_pcc_data_v1_7);
+	if (put_user((void *)((unsigned long)ov + sizeof(struct mdp_overlay)),
+			 &(ov->overlay_pp_cfg.igc_cfg.cfg_payload)) ||
+		put_user(ov->overlay_pp_cfg.igc_cfg.cfg_payload +
+			sizeof(struct mdp_igc_lut_data_v1_7),
+			&(ov->overlay_pp_cfg.pa_v2_cfg_data.cfg_payload)) ||
+		put_user(ov->overlay_pp_cfg.pa_v2_cfg_data.cfg_payload +
+			 sizeof(struct mdp_pa_data_v1_7),
+			&(ov->overlay_pp_cfg.pcc_cfg_data.cfg_payload)) ||
+		put_user(ov->overlay_pp_cfg.pcc_cfg_data.cfg_payload +
+			sizeof(struct mdp_pcc_data_v1_7),
+			&(ov->overlay_pp_cfg.hist_lut_cfg.cfg_payload)))
+		return -EFAULT;
 	return 0;
 }
 
 int mdss_compat_overlay_ioctl(struct fb_info *info, unsigned int cmd,
 			 unsigned long arg, struct file *file)
 {
-	struct mdp_overlay *ov, **layers_head;
-	struct mdp_overlay32 *ov32;
+	struct mdp_overlay **layers_head;
+	struct mdp_overlay __user *ov;
+	struct mdp_overlay32 __user *ov32;
 	struct mdp_overlay_list __user *ovlist;
 	struct mdp_overlay_list32 __user *ovlist32;
 	size_t layers_refs_sz, layers_sz, prepare_sz;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index 4cfb48d..0b6195d 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -2559,7 +2559,7 @@
 			mixer_pool += ctl->mdata->ndspp;
 			nmixers -= ctl->mdata->ndspp;
 		} else if ((ctl->panel_data->panel_info.is_pluggable) &&
-				nmixers_active) {
+				nmixers_active > 1) {
 			mixer_pool += ctl->mdata->ndspp;
 			nmixers -= ctl->mdata->ndspp;
 		}
diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c
index a462175..dacb591 100644
--- a/drivers/w1/masters/mxc_w1.c
+++ b/drivers/w1/masters/mxc_w1.c
@@ -113,6 +113,10 @@
 	if (IS_ERR(mdev->clk))
 		return PTR_ERR(mdev->clk);
 
+	err = clk_prepare_enable(mdev->clk);
+	if (err)
+		return err;
+
 	clkrate = clk_get_rate(mdev->clk);
 	if (clkrate < 10000000)
 		dev_warn(&pdev->dev,
@@ -126,12 +130,10 @@
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	mdev->regs = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(mdev->regs))
-		return PTR_ERR(mdev->regs);
-
-	err = clk_prepare_enable(mdev->clk);
-	if (err)
-		return err;
+	if (IS_ERR(mdev->regs)) {
+		err = PTR_ERR(mdev->regs);
+		goto out_disable_clk;
+	}
 
 	/* Software reset 1-Wire module */
 	writeb(MXC_W1_RESET_RST, mdev->regs + MXC_W1_RESET);
@@ -147,8 +149,12 @@
 
 	err = w1_add_master_device(&mdev->bus_master);
 	if (err)
-		clk_disable_unprepare(mdev->clk);
+		goto out_disable_clk;
 
+	return 0;
+
+out_disable_clk:
+	clk_disable_unprepare(mdev->clk);
 	return err;
 }
 
diff --git a/fs/aio.c b/fs/aio.c
index 42d8c09..b1170a7 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -636,9 +636,8 @@
 	while (!list_empty(&ctx->active_reqs)) {
 		req = list_first_entry(&ctx->active_reqs,
 				       struct aio_kiocb, ki_list);
-
-		list_del_init(&req->ki_list);
 		kiocb_cancel(req);
+		list_del_init(&req->ki_list);
 	}
 
 	spin_unlock_irq(&ctx->ctx_lock);
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 9b4688a..f842261 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -384,8 +384,13 @@
 		s = strchr(p, del);
 		if (!s)
 			goto einval;
-		*s++ = '\0';
-		e->offset = simple_strtoul(p, &p, 10);
+		*s = '\0';
+		if (p != s) {
+			int r = kstrtoint(p, 10, &e->offset);
+			if (r != 0 || e->offset < 0)
+				goto einval;
+		}
+		p = s;
 		if (*p++)
 			goto einval;
 		pr_debug("register: offset: %#x\n", e->offset);
@@ -425,7 +430,8 @@
 		if (e->mask &&
 		    string_unescape_inplace(e->mask, UNESCAPE_HEX) != e->size)
 			goto einval;
-		if (e->size + e->offset > BINPRM_BUF_SIZE)
+		if (e->size > BINPRM_BUF_SIZE ||
+		    BINPRM_BUF_SIZE - e->size < e->offset)
 			goto einval;
 		pr_debug("register: magic/mask length: %i\n", e->size);
 		if (USE_DEBUG) {
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 9557a31..8dc7034 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -59,7 +59,8 @@
 				 BTRFS_HEADER_FLAG_RELOC |\
 				 BTRFS_SUPER_FLAG_ERROR |\
 				 BTRFS_SUPER_FLAG_SEEDING |\
-				 BTRFS_SUPER_FLAG_METADUMP)
+				 BTRFS_SUPER_FLAG_METADUMP |\
+				 BTRFS_SUPER_FLAG_METADUMP_V2)
 
 static const struct extent_io_ops btree_extent_io_ops;
 static void end_workqueue_fn(struct btrfs_work *work);
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index d3dd631..cbf512b 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2708,8 +2708,10 @@
 	}
 
 	/* Check for compatibility reject unknown flags */
-	if (vol_args->flags & ~BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED)
-		return -EOPNOTSUPP;
+	if (vol_args->flags & ~BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED) {
+		ret = -EOPNOTSUPP;
+		goto out;
+	}
 
 	if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running,
 			1)) {
@@ -3887,11 +3889,6 @@
 	    src->i_sb != inode->i_sb)
 		return -EXDEV;
 
-	/* don't make the dst file partly checksummed */
-	if ((BTRFS_I(src)->flags & BTRFS_INODE_NODATASUM) !=
-	    (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM))
-		return -EINVAL;
-
 	if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode))
 		return -EISDIR;
 
@@ -3901,6 +3898,13 @@
 		inode_lock(src);
 	}
 
+	/* don't make the dst file partly checksummed */
+	if ((BTRFS_I(src)->flags & BTRFS_INODE_NODATASUM) !=
+	    (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) {
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
 	/* determine range to clone */
 	ret = -EINVAL;
 	if (off + len > src->i_size || off + len < off)
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index fffb9ab..16c0585 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -2519,7 +2519,7 @@
 			have_csum = scrub_find_csum(sctx, logical, csum);
 			if (have_csum == 0)
 				++sctx->stat.no_csum;
-			if (sctx->is_dev_replace && !have_csum) {
+			if (0 && sctx->is_dev_replace && !have_csum) {
 				ret = copy_nocow_pages(sctx, logical, l,
 						       mirror_num,
 						      physical_for_dev_replace);
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 44b7ccb..e021433 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -1004,6 +1004,7 @@
 	sess_data->ses = ses;
 	sess_data->buf0_type = CIFS_NO_BUFFER;
 	sess_data->nls_cp = (struct nls_table *) nls_cp;
+	sess_data->previous_session = ses->Suid;
 
 	while (sess_data->func)
 		sess_data->func(sess_data);
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
index bc15c2c..58229c1 100644
--- a/fs/ext4/indirect.c
+++ b/fs/ext4/indirect.c
@@ -560,10 +560,16 @@
 		unsigned epb = inode->i_sb->s_blocksize / sizeof(u32);
 		int i;
 
-		/* Count number blocks in a subtree under 'partial' */
-		count = 1;
-		for (i = 0; partial + i != chain + depth - 1; i++)
-			count *= epb;
+		/*
+		 * Count number blocks in a subtree under 'partial'. At each
+		 * level we count number of complete empty subtrees beyond
+		 * current offset and then descend into the subtree only
+		 * partially beyond current offset.
+		 */
+		count = 0;
+		for (i = partial - chain + 1; i < depth; i++)
+			count = count * epb + (epb - offsets[i] - 1);
+		count++;
 		/* Fill in size of a hole we found */
 		map->m_pblk = 0;
 		map->m_len = min_t(unsigned int, map->m_len, count);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index ecee29a..d0d9624 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4101,28 +4101,28 @@
 		EXT4_BLOCK_SIZE_BITS(sb);
 	stop_block = (offset + length) >> EXT4_BLOCK_SIZE_BITS(sb);
 
-	/* If there are no blocks to remove, return now */
-	if (first_block >= stop_block)
-		goto out_stop;
+	/* If there are blocks to remove, do it */
+	if (stop_block > first_block) {
 
-	down_write(&EXT4_I(inode)->i_data_sem);
-	ext4_discard_preallocations(inode);
+		down_write(&EXT4_I(inode)->i_data_sem);
+		ext4_discard_preallocations(inode);
 
-	ret = ext4_es_remove_extent(inode, first_block,
-				    stop_block - first_block);
-	if (ret) {
+		ret = ext4_es_remove_extent(inode, first_block,
+					    stop_block - first_block);
+		if (ret) {
+			up_write(&EXT4_I(inode)->i_data_sem);
+			goto out_stop;
+		}
+
+		if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
+			ret = ext4_ext_remove_space(inode, first_block,
+						    stop_block - 1);
+		else
+			ret = ext4_ind_remove_space(handle, inode, first_block,
+						    stop_block);
+
 		up_write(&EXT4_I(inode)->i_data_sem);
-		goto out_stop;
 	}
-
-	if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
-		ret = ext4_ext_remove_space(inode, first_block,
-					    stop_block - 1);
-	else
-		ret = ext4_ind_remove_space(handle, inode, first_block,
-					    stop_block);
-
-	up_write(&EXT4_I(inode)->i_data_sem);
 	if (IS_SYNC(inode))
 		ext4_handle_sync(handle);
 
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 95bf466..eb720d9 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1903,7 +1903,7 @@
 		return 0;
 
 	n_group = ext4_get_group_number(sb, n_blocks_count - 1);
-	if (n_group > (0xFFFFFFFFUL / EXT4_INODES_PER_GROUP(sb))) {
+	if (n_group >= (0xFFFFFFFFUL / EXT4_INODES_PER_GROUP(sb))) {
 		ext4_warning(sb, "resize would cause inodes_count overflow");
 		return -EINVAL;
 	}
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 98fe1ed..f04781b 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2439,9 +2439,18 @@
 
 	__init_discard_policy(sbi, &dpolicy, DPOLICY_FSTRIM, cpc.trim_minlen);
 	__issue_discard_cmd_range(sbi, &dpolicy, start_block, end_block);
-	trimmed = __wait_discard_cmd_range(sbi, &dpolicy,
+
+	/*
+	 * We filed discard candidates, but actually we don't need to wait for
+	 * all of them, since they'll be issued in idle time along with runtime
+	 * discard option. User configuration looks like using runtime discard
+	 * or periodic fstrim instead of it.
+	 */
+	if (!test_opt(sbi, DISCARD)) {
+		trimmed = __wait_discard_cmd_range(sbi, &dpolicy,
 					start_block, end_block);
-	range->len = F2FS_BLK_TO_BYTES(trimmed);
+		range->len = F2FS_BLK_TO_BYTES(trimmed);
+	}
 out:
 	return err;
 }
diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c
index 561497a..5fe4586 100644
--- a/fs/orangefs/namei.c
+++ b/fs/orangefs/namei.c
@@ -312,6 +312,13 @@
 		ret = PTR_ERR(inode);
 		goto out;
 	}
+	/*
+	 * This is necessary because orangefs_inode_getattr will not
+	 * re-read symlink size as it is impossible for it to change.
+	 * Invalidating the cache does not help.  orangefs_new_inode
+	 * does not set the correct size (it does not know symname).
+	 */
+	inode->i_size = strlen(symname);
 
 	gossip_debug(GOSSIP_NAME_DEBUG,
 		     "Assigned symlink inode new number of %pU\n",
diff --git a/fs/sdcardfs/inode.c b/fs/sdcardfs/inode.c
index fafc09c..30d4db2 100644
--- a/fs/sdcardfs/inode.c
+++ b/fs/sdcardfs/inode.c
@@ -270,6 +270,7 @@
 	struct dentry *lower_dentry;
 	struct vfsmount *lower_mnt;
 	struct dentry *lower_parent_dentry = NULL;
+	struct dentry *parent_dentry = NULL;
 	struct path lower_path;
 	struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
 	const struct cred *saved_cred = NULL;
@@ -289,11 +290,14 @@
 	OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir));
 
 	/* check disk space */
-	if (!check_min_free_space(dentry, 0, 1)) {
+	parent_dentry = dget_parent(dentry);
+	if (!check_min_free_space(parent_dentry, 0, 1)) {
 		pr_err("sdcardfs: No minimum free space.\n");
 		err = -ENOSPC;
+		dput(parent_dentry);
 		goto out_revert;
 	}
+	dput(parent_dentry);
 
 	/* the lower_dentry is negative here */
 	sdcardfs_get_lower_path(dentry, &lower_path);
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index c3702cd..e567551 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -2035,6 +2035,93 @@
 }
 
 /*
+ * Check the agfl fields of the agf for inconsistency or corruption. The purpose
+ * is to detect an agfl header padding mismatch between current and early v5
+ * kernels. This problem manifests as a 1-slot size difference between the
+ * on-disk flcount and the active [first, last] range of a wrapped agfl. This
+ * may also catch variants of agfl count corruption unrelated to padding. Either
+ * way, we'll reset the agfl and warn the user.
+ *
+ * Return true if a reset is required before the agfl can be used, false
+ * otherwise.
+ */
+static bool
+xfs_agfl_needs_reset(
+	struct xfs_mount	*mp,
+	struct xfs_agf		*agf)
+{
+	uint32_t		f = be32_to_cpu(agf->agf_flfirst);
+	uint32_t		l = be32_to_cpu(agf->agf_fllast);
+	uint32_t		c = be32_to_cpu(agf->agf_flcount);
+	int			agfl_size = XFS_AGFL_SIZE(mp);
+	int			active;
+
+	/* no agfl header on v4 supers */
+	if (!xfs_sb_version_hascrc(&mp->m_sb))
+		return false;
+
+	/*
+	 * The agf read verifier catches severe corruption of these fields.
+	 * Repeat some sanity checks to cover a packed -> unpacked mismatch if
+	 * the verifier allows it.
+	 */
+	if (f >= agfl_size || l >= agfl_size)
+		return true;
+	if (c > agfl_size)
+		return true;
+
+	/*
+	 * Check consistency between the on-disk count and the active range. An
+	 * agfl padding mismatch manifests as an inconsistent flcount.
+	 */
+	if (c && l >= f)
+		active = l - f + 1;
+	else if (c)
+		active = agfl_size - f + l + 1;
+	else
+		active = 0;
+
+	return active != c;
+}
+
+/*
+ * Reset the agfl to an empty state. Ignore/drop any existing blocks since the
+ * agfl content cannot be trusted. Warn the user that a repair is required to
+ * recover leaked blocks.
+ *
+ * The purpose of this mechanism is to handle filesystems affected by the agfl
+ * header padding mismatch problem. A reset keeps the filesystem online with a
+ * relatively minor free space accounting inconsistency rather than suffer the
+ * inevitable crash from use of an invalid agfl block.
+ */
+static void
+xfs_agfl_reset(
+	struct xfs_trans	*tp,
+	struct xfs_buf		*agbp,
+	struct xfs_perag	*pag)
+{
+	struct xfs_mount	*mp = tp->t_mountp;
+	struct xfs_agf		*agf = XFS_BUF_TO_AGF(agbp);
+
+	ASSERT(pag->pagf_agflreset);
+	trace_xfs_agfl_reset(mp, agf, 0, _RET_IP_);
+
+	xfs_warn(mp,
+	       "WARNING: Reset corrupted AGFL on AG %u. %d blocks leaked. "
+	       "Please unmount and run xfs_repair.",
+	         pag->pag_agno, pag->pagf_flcount);
+
+	agf->agf_flfirst = 0;
+	agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1);
+	agf->agf_flcount = 0;
+	xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLFIRST | XFS_AGF_FLLAST |
+				    XFS_AGF_FLCOUNT);
+
+	pag->pagf_flcount = 0;
+	pag->pagf_agflreset = false;
+}
+
+/*
  * Decide whether to use this allocation group for this allocation.
  * If so, fix up the btree freelist's size.
  */
@@ -2095,6 +2182,10 @@
 		}
 	}
 
+	/* reset a padding mismatched agfl before final free space check */
+	if (pag->pagf_agflreset)
+		xfs_agfl_reset(tp, agbp, pag);
+
 	/* If there isn't enough total space or single-extent, reject it. */
 	need = xfs_alloc_min_freelist(mp, pag);
 	if (!xfs_alloc_space_available(args, need, flags))
@@ -2251,6 +2342,7 @@
 		agf->agf_flfirst = 0;
 
 	pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
+	ASSERT(!pag->pagf_agflreset);
 	be32_add_cpu(&agf->agf_flcount, -1);
 	xfs_trans_agflist_delta(tp, -1);
 	pag->pagf_flcount--;
@@ -2362,6 +2454,7 @@
 		agf->agf_fllast = 0;
 
 	pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
+	ASSERT(!pag->pagf_agflreset);
 	be32_add_cpu(&agf->agf_flcount, 1);
 	xfs_trans_agflist_delta(tp, 1);
 	pag->pagf_flcount++;
@@ -2568,6 +2661,7 @@
 		pag->pagb_count = 0;
 		pag->pagb_tree = RB_ROOT;
 		pag->pagf_init = 1;
+		pag->pagf_agflreset = xfs_agfl_needs_reset(mp, agf);
 	}
 #ifdef DEBUG
 	else if (!XFS_FORCED_SHUTDOWN(mp)) {
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 5415f90..7cb099e 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -368,6 +368,7 @@
 	char		pagi_inodeok;	/* The agi is ok for inodes */
 	__uint8_t	pagf_levels[XFS_BTNUM_AGF];
 					/* # of levels in bno & cnt btree */
+	bool		pagf_agflreset; /* agfl requires reset before use */
 	__uint32_t	pagf_flcount;	/* count of blocks in freelist */
 	xfs_extlen_t	pagf_freeblks;	/* total free blocks */
 	xfs_extlen_t	pagf_longest;	/* longest free space */
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index bdf69e1..42a7c0d 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -1516,7 +1516,7 @@
 		  __entry->lsn)
 );
 
-TRACE_EVENT(xfs_agf,
+DECLARE_EVENT_CLASS(xfs_agf_class,
 	TP_PROTO(struct xfs_mount *mp, struct xfs_agf *agf, int flags,
 		 unsigned long caller_ip),
 	TP_ARGS(mp, agf, flags, caller_ip),
@@ -1572,6 +1572,13 @@
 		  __entry->longest,
 		  (void *)__entry->caller_ip)
 );
+#define DEFINE_AGF_EVENT(name) \
+DEFINE_EVENT(xfs_agf_class, name, \
+	TP_PROTO(struct xfs_mount *mp, struct xfs_agf *agf, int flags, \
+		 unsigned long caller_ip), \
+	TP_ARGS(mp, agf, flags, caller_ip))
+DEFINE_AGF_EVENT(xfs_agf);
+DEFINE_AGF_EVENT(xfs_agfl_reset);
 
 TRACE_EVENT(xfs_free_extent,
 	TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, xfs_agblock_t agbno,
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index eba9285..a6d1bf2 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -210,7 +210,7 @@
 #ifdef CONFIG_STACK_VALIDATION
 #define annotate_unreachable() ({					\
 	asm("1:\t\n"							\
-	    ".pushsection __unreachable, \"a\"\t\n"			\
+	    ".pushsection .discard.unreachable\t\n"			\
 	    ".long 1b\t\n"						\
 	    ".popsection\t\n");						\
 })
diff --git a/include/linux/extcon.h b/include/linux/extcon.h
index a9a16f2..94c7be2 100644
--- a/include/linux/extcon.h
+++ b/include/linux/extcon.h
@@ -113,14 +113,19 @@
  * @type:       integer (intval)
  * @value:      0 (USB/USB2) or 1 (USB3)
  * @default:    0 (USB/USB2)
+ * -EXTCON_PROP_USB_PD_CONTRACT
+ * @type:	integer (intval)
+ * @value:	0 (bus powered) or 1 (self powered)
+ * @default:	0 (bus powered)
  *
  */
 #define EXTCON_PROP_USB_VBUS		0
 #define EXTCON_PROP_USB_TYPEC_POLARITY	1
 #define EXTCON_PROP_USB_SS		2
+#define EXTCON_PROP_USB_PD_CONTRACT	3
 
 #define EXTCON_PROP_USB_MIN		0
-#define EXTCON_PROP_USB_MAX		2
+#define EXTCON_PROP_USB_MAX		3
 #define EXTCON_PROP_USB_CNT	(EXTCON_PROP_USB_MAX - EXTCON_PROP_USB_MIN + 1)
 
 /* Properties of EXTCON_TYPE_CHG. */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 9d5d808..e7b9652 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -269,6 +269,11 @@
 /* This mask is used to clear all the VMA flags used by mlock */
 #define VM_LOCKED_CLEAR_MASK	(~(VM_LOCKED | VM_LOCKONFAULT))
 
+#ifdef CONFIG_ARCH_MSM8953_SOC_SETTINGS
+#define MSM8953_TLMM_START_ADDR	0x01000000
+#define MSM8953_TLMM_END_ADDR	(0x01300000 - 1)
+#endif
+
 /*
  * mapping from the currently active vm_flags protection bits (the
  * low four bits) to a page protection mask..
@@ -360,7 +365,7 @@
 /*
  * These are the virtual MM functions - opening of an area, closing and
  * unmapping it (needed to keep files on disk up-to-date etc), pointer
- * to the functions called when a no-page or a wp-page exception occurs. 
+ * to the functions called when a no-page or a wp-page exception occurs.
  */
 struct vm_operations_struct {
 	void (*open)(struct vm_area_struct * area);
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index fc11641..b8ea15a 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -338,7 +338,7 @@
 
 /* Receiver queue space */
 	struct {
-		int	space;
+		u32	space;
 		u32	seq;
 		u32	time;
 	} rcvq_space;
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 3f3a7e4..0267bed 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -539,6 +539,7 @@
 	u32				extra_buf_alloc;
 	bool				l1_supported;
 	bool				is_chipidea;
+	bool				self_powered;
 };
 #define work_to_gadget(w)	(container_of((w), struct usb_gadget, work))
 
diff --git a/include/net/bonding.h b/include/net/bonding.h
index 7734cc9..714428c 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -277,6 +277,11 @@
 	       BOND_MODE(bond) == BOND_MODE_ALB;
 }
 
+static inline bool bond_needs_speed_duplex(const struct bonding *bond)
+{
+	return BOND_MODE(bond) == BOND_MODE_8023AD || bond_is_lb(bond);
+}
+
 static inline bool bond_is_nondyn_tlb(const struct bonding *bond)
 {
 	return (BOND_MODE(bond) == BOND_MODE_TLB)  &&
diff --git a/include/net/cnss.h b/include/net/cnss.h
index 368d01e..3b864fc 100644
--- a/include/net/cnss.h
+++ b/include/net/cnss.h
@@ -102,11 +102,14 @@
 	u32 cap_flag;
 };
 
-/* WLAN driver status */
+/* WLAN driver status, keep it aligned with cnss2 */
 enum cnss_driver_status {
 	CNSS_UNINITIALIZED,
 	CNSS_INITIALIZED,
-	CNSS_LOAD_UNLOAD
+	CNSS_LOAD_UNLOAD,
+	CNSS_RECOVERY,
+	CNSS_FW_DOWN,
+	CNSS_SSR_FAIL,
 };
 
 enum cnss_runtime_request {
@@ -120,6 +123,8 @@
 	CNSS_PM_GET_NORESUME,
 };
 
+extern struct dma_iommu_mapping *cnss_smmu_get_mapping(void);
+extern int cnss_smmu_map(phys_addr_t paddr, uint32_t *iova_addr, size_t size);
 extern int cnss_get_fw_image(struct image_desc_info *image_desc_info);
 extern void cnss_runtime_init(struct device *dev, int auto_delay);
 extern void cnss_runtime_exit(struct device *dev);
diff --git a/include/soc/qcom/icnss.h b/include/soc/qcom/icnss.h
index 31b4cce..7ef3db4 100644
--- a/include/soc/qcom/icnss.h
+++ b/include/soc/qcom/icnss.h
@@ -142,5 +142,6 @@
 extern bool icnss_is_qmi_disable(struct device *dev);
 extern bool icnss_is_fw_ready(void);
 extern bool icnss_is_fw_down(void);
+extern bool icnss_is_rejuvenate(void);
 extern int icnss_trigger_recovery(struct device *dev);
 #endif /* _ICNSS_WLAN_H_ */
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index b355ebf..b3ec962 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -657,6 +657,10 @@
 		__field(unsigned int, capacity_orig		)
 		__field(int, idle_state				)
 		__field(u64, irqload				)
+		__field(int, online				)
+		__field(int, isolated				)
+		__field(int, reserved				)
+		__field(int, high_irq_load			)
 	),
 
 	TP_fast_assign(
@@ -669,10 +673,14 @@
 		__entry->capacity_orig		= capacity_orig_of(cpu);
 		__entry->idle_state		= idle_get_state_idx(cpu_rq(cpu));
 		__entry->irqload		= sched_irqload(cpu);
+		__entry->online			= cpu_online(cpu);
+		__entry->isolated		= cpu_isolated(cpu);
+		__entry->reserved		= is_reserved(cpu);
+		__entry->high_irq_load          = sched_cpu_high_irqload(cpu);
 	),
 
-	TP_printk("cpu=%d nr_running=%d cpu_util=%ld cpu_util_cum=%ld capacity_curr=%u capacity=%u capacity_orig=%u idle_state=%d irqload=%llu",
-		__entry->cpu, __entry->nr_running, __entry->cpu_util, __entry->cpu_util_cum, __entry->capacity_curr, __entry->capacity, __entry->capacity_orig, __entry->idle_state, __entry->irqload)
+	TP_printk("cpu=%d nr_running=%d cpu_util=%ld cpu_util_cum=%ld capacity_curr=%u capacity=%u capacity_orig=%u idle_state=%d irqload=%llu online=%u isolated=%u reserved=%u high_irq_load=%u",
+		__entry->cpu, __entry->nr_running, __entry->cpu_util, __entry->cpu_util_cum, __entry->capacity_curr, __entry->capacity, __entry->capacity_orig, __entry->idle_state, __entry->irqload, __entry->online, __entry->isolated, __entry->reserved, __entry->high_irq_load)
 );
 
 TRACE_EVENT(sched_energy_diff,
@@ -1637,10 +1645,11 @@
 
 	TP_PROTO(struct task_struct *tsk, bool prefer_idle,
 		unsigned long min_util, int start_cpu,
-		int best_idle, int best_active, int target),
+		int best_idle, int best_active, int target,
+		int backup_cpu),
 
 	TP_ARGS(tsk, prefer_idle, min_util, start_cpu,
-		best_idle, best_active, target),
+		best_idle, best_active, target, backup_cpu),
 
 	TP_STRUCT__entry(
 		__array( char,	comm,	TASK_COMM_LEN	)
@@ -1651,6 +1660,7 @@
 		__field( int,	best_idle		)
 		__field( int,	best_active		)
 		__field( int,	target			)
+		__field( int,	backup_cpu		)
 	),
 
 	TP_fast_assign(
@@ -1662,14 +1672,16 @@
 		__entry->best_idle	= best_idle;
 		__entry->best_active	= best_active;
 		__entry->target		= target;
+		__entry->backup_cpu	= backup_cpu;
 	),
 
 	TP_printk("pid=%d comm=%s prefer_idle=%d start_cpu=%d "
-		  "best_idle=%d best_active=%d target=%d",
+		  "best_idle=%d best_active=%d target=%d backup=%d",
 		__entry->pid, __entry->comm,
 		__entry->prefer_idle, __entry->start_cpu,
 		__entry->best_idle, __entry->best_active,
-		__entry->target)
+		__entry->target,
+		__entry->backup_cpu)
 );
 
 TRACE_EVENT(sched_group_energy,
diff --git a/include/uapi/linux/btrfs_tree.h b/include/uapi/linux/btrfs_tree.h
index d5ad15a..c794c9a 100644
--- a/include/uapi/linux/btrfs_tree.h
+++ b/include/uapi/linux/btrfs_tree.h
@@ -452,6 +452,7 @@
 
 #define BTRFS_SUPER_FLAG_SEEDING	(1ULL << 32)
 #define BTRFS_SUPER_FLAG_METADUMP	(1ULL << 33)
+#define BTRFS_SUPER_FLAG_METADUMP_V2	(1ULL << 34)
 
 
 /*
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 20a01ca..8143af6 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2603,7 +2603,7 @@
 #define NL80211_ATTR_KEYS NL80211_ATTR_KEYS
 #define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS
 
-#define NL80211_WIPHY_NAME_MAXLEN		128
+#define NL80211_WIPHY_NAME_MAXLEN		64
 
 #define NL80211_MAX_SUPP_RATES			32
 #define NL80211_MAX_SUPP_HT_RATES		77
diff --git a/include/uapi/linux/qg.h b/include/uapi/linux/qg.h
index 40882a7..54aa362 100644
--- a/include/uapi/linux/qg.h
+++ b/include/uapi/linux/qg.h
@@ -20,7 +20,7 @@
 	QG_ESR_DISCHARGE_SF,
 	QG_FULL_SOC,
 	QG_CLEAR_LEARNT_DATA,
-	QG_RESERVED_9,
+	QG_SYS_SOC,
 	QG_RESERVED_10,
 	QG_MAX,
 };
@@ -33,6 +33,7 @@
 #define QG_ESR_DISCHARGE_SF QG_ESR_DISCHARGE_SF
 #define QG_FULL_SOC QG_FULL_SOC
 #define QG_CLEAR_LEARNT_DATA QG_CLEAR_LEARNT_DATA
+#define QG_SYS_SOC QG_SYS_SOC
 
 struct fifo_data {
 	unsigned int			v;
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
index b71f116..dc9518b 100644
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -365,11 +365,10 @@
 	raw_spin_unlock(&sg_policy->update_lock);
 }
 
-static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu)
+static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu, u64 time)
 {
 	struct sugov_policy *sg_policy = sg_cpu->sg_policy;
 	struct cpufreq_policy *policy = sg_policy->policy;
-	u64 last_freq_update_time = sg_policy->last_freq_update_time;
 	unsigned long util = 0, max = 1;
 	unsigned int j;
 
@@ -385,7 +384,7 @@
 		 * enough, don't take the CPU into account as it probably is
 		 * idle now (and clear iowait_boost for it).
 		 */
-		delta_ns = last_freq_update_time - j_sg_cpu->last_update;
+		delta_ns = time - j_sg_cpu->last_update;
 		if (delta_ns > stale_ns) {
 			j_sg_cpu->iowait_boost = 0;
 			continue;
@@ -450,7 +449,7 @@
 		if (flags & SCHED_CPUFREQ_RT_DL)
 			next_f = sg_policy->policy->cpuinfo.max_freq;
 		else
-			next_f = sugov_next_freq_shared(sg_cpu);
+			next_f = sugov_next_freq_shared(sg_cpu, time);
 
 		sugov_update_commit(sg_policy, time, next_f);
 	}
diff --git a/kernel/sched/energy.c b/kernel/sched/energy.c
index 77d8361..01daf82 100644
--- a/kernel/sched/energy.c
+++ b/kernel/sched/energy.c
@@ -25,6 +25,7 @@
 #include <linux/sched_energy.h>
 #include <linux/stddef.h>
 #include <linux/cpu.h>
+#include <linux/cpuset.h>
 #include <linux/pm_opp.h>
 #include <linux/platform_device.h>
 
@@ -49,6 +50,17 @@
 	}
 }
 
+static int update_topology;
+
+/*
+ * Ideally this should be arch specific implementation,
+ * let's define here to help rebuild sched_domain with new capacities.
+ */
+int arch_update_cpu_topology(void)
+{
+	return update_topology;
+}
+
 void init_sched_energy_costs(void)
 {
 	struct device_node *cn, *cp;
@@ -273,8 +285,22 @@
 
 	kfree(max_frequencies);
 
-	if (is_sge_valid)
+	if (is_sge_valid) {
+		/*
+		 * Sched_domains might have built with default cpu capacity
+		 * values on bootup.
+		 *
+		 * Let's rebuild them again with actual cpu capacities.
+		 * And partition_sched_domain() expects update in cpu topology
+		 * to rebuild the domains, so make it satisfied..
+		 */
+		update_topology = 1;
+		rebuild_sched_domains();
+		update_topology = 0;
+
 		walt_sched_energy_populated_callback();
+	}
+
 	dev_info(&pdev->dev, "Sched-energy-costs capacity updated\n");
 	return 0;
 
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index ca683db..91a909f 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -6194,13 +6194,14 @@
 	if (boost >= 0) {
 		margin  = SCHED_CAPACITY_SCALE - signal;
 		margin *= boost;
-	} else
+	} else {
 		margin = -signal * boost;
+	}
 
 	margin  = reciprocal_divide(margin, schedtune_spc_rdiv);
-
 	if (boost < 0)
 		margin *= -1;
+
 	return margin;
 }
 
@@ -6930,6 +6931,7 @@
 	int cpu, i;
 	unsigned int active_cpus_count = 0;
 	int isolated_candidate = -1;
+	int prev_cpu = task_cpu(p);
 
 	*backup_cpu = -1;
 
@@ -6976,19 +6978,18 @@
 
 			cpumask_clear_cpu(i, &search_cpus);
 
+			trace_sched_cpu_util(i);
 			if (!cpu_online(i) || cpu_isolated(i))
 				continue;
 
 			isolated_candidate = i;
 
-			if (avoid_prev_cpu && i == task_cpu(p))
+			if (avoid_prev_cpu && i == prev_cpu)
 				continue;
 
 			if (walt_cpu_high_irqload(i) || is_reserved(i))
 				continue;
 
-			trace_sched_cpu_util(i);
-
 			/*
 			 * p's blocked utilization is still accounted for on prev_cpu
 			 * so prev_cpu will receive a negative bias due to the double
@@ -7057,7 +7058,8 @@
 					trace_sched_find_best_target(p,
 							prefer_idle, min_util,
 							cpu, best_idle_cpu,
-							best_active_cpu, i);
+							best_active_cpu,
+							i, -1);
 
 					return i;
 				}
@@ -7234,7 +7236,7 @@
 
 	if (best_idle_cpu != -1 && !is_packing_eligible(p, target_cpu, fbt_env,
 					active_cpus_count, best_idle_cstate)) {
-		if (target_cpu == task_cpu(p))
+		if (target_cpu == prev_cpu)
 			fbt_env->avoid_prev_cpu = true;
 
 		target_cpu = best_idle_cpu;
@@ -7270,15 +7272,31 @@
 		? best_active_cpu
 		: best_idle_cpu;
 
-	if (target_cpu == -1 && cpu_isolated(task_cpu(p)) &&
+	if (target_cpu == -1 && cpu_isolated(prev_cpu) &&
 			isolated_candidate != -1) {
 		target_cpu = isolated_candidate;
 		fbt_env->avoid_prev_cpu = true;
 	}
 
+	/*
+	 * - It is possible for target and backup
+	 *   to select same CPU - if so, drop backup
+	 *
+	 * - The next step of energy evaluation includes
+	 *   prev_cpu. Drop target or backup if it is
+	 *   same as prev_cpu.
+	 */
+	if (*backup_cpu == target_cpu || *backup_cpu == prev_cpu)
+		*backup_cpu = -1;
+
+	if (target_cpu == prev_cpu) {
+		target_cpu = *backup_cpu;
+		*backup_cpu = -1;
+	}
+
 	trace_sched_find_best_target(p, prefer_idle, min_util, cpu,
 				     best_idle_cpu, best_active_cpu,
-				     target_cpu);
+				     target_cpu, *backup_cpu);
 
 	schedstat_inc(p->se.statistics.nr_wakeups_fbt_count);
 	schedstat_inc(this_rq()->eas_stats.fbt_count);
diff --git a/kernel/sched/tune.c b/kernel/sched/tune.c
index 192e8c7..a8fab0c 100644
--- a/kernel/sched/tune.c
+++ b/kernel/sched/tune.c
@@ -110,6 +110,64 @@
 
 /*
  * EAS scheduler tunables for task groups.
+ *
+ * When CGroup support is enabled, we have to synchronize two different
+ * paths:
+ *  - slow path: where CGroups are created/updated/removed
+ *  - fast path: where tasks in a CGroups are accounted
+ *
+ * The slow path tracks (a limited number of) CGroups and maps each on a
+ * "boost_group" index. The fastpath accounts tasks currently RUNNABLE on each
+ * "boost_group".
+ *
+ * Once a new CGroup is created, a boost group idx is assigned and the
+ * corresponding "boost_group" marked as valid on each CPU.
+ * Once a CGroup is release, the corresponding "boost_group" is marked as
+ * invalid on each CPU. The CPU boost value (boost_max) is aggregated by
+ * considering only valid boost_groups with a non null tasks counter.
+ *
+ * .:: Locking strategy
+ *
+ * The fast path uses a spin lock for each CPU boost_group which protects the
+ * tasks counter.
+ *
+ * The "valid" and "boost" values of each CPU boost_group is instead
+ * protected by the RCU lock provided by the CGroups callbacks. Thus, only the
+ * slow path can access and modify the boost_group attribtues of each CPU.
+ * The fast path will catch up the most updated values at the next scheduling
+ * event (i.e. enqueue/dequeue).
+ *
+ *                                                        |
+ *                                             SLOW PATH  |   FAST PATH
+ *                              CGroup add/update/remove  |   Scheduler enqueue/dequeue events
+ *                                                        |
+ *                                                        |
+ *                                                        |     DEFINE_PER_CPU(struct boost_groups)
+ *                                                        |     +--------------+----+---+----+----+
+ *                                                        |     |  idle        |    |   |    |    |
+ *                                                        |     |  boost_max   |    |   |    |    |
+ *                                                        |  +---->lock        |    |   |    |    |
+ *  struct schedtune                  allocated_groups    |  |  |  group[    ] |    |   |    |    |
+ *  +------------------------------+         +-------+    |  |  +--+---------+-+----+---+----+----+
+ *  | idx                          |         |       |    |  |     |  valid  |
+ *  | boots / prefer_idle          |         |       |    |  |     |  boost  |
+ *  | perf_{boost/constraints}_idx | <---------+(*)  |    |  |     |  tasks  | <------------+
+ *  | css                          |         +-------+    |  |     +---------+              |
+ *  +-+----------------------------+         |       |    |  |     |         |              |
+ *    ^                                      |       |    |  |     |         |              |
+ *    |                                      +-------+    |  |     +---------+              |
+ *    |                                      |       |    |  |     |         |              |
+ *    |                                      |       |    |  |     |         |              |
+ *    |                                      +-------+    |  |     +---------+              |
+ *    | zmalloc                              |       |    |  |     |         |              |
+ *    |                                      |       |    |  |     |         |              |
+ *    |                                      +-------+    |  |     +---------+              |
+ *    +                              BOOSTGROUPS_COUNT    |  |     BOOSTGROUPS_COUNT        |
+ *  schedtune_boostgroup_init()                           |  +                              |
+ *                                                        |  schedtune_{en,de}queue_task()  |
+ *                                                        |                                 +
+ *                                                        |          schedtune_tasks_update()
+ *                                                        |
  */
 
 /* SchdTune tunables for a group of tasks */
@@ -259,10 +317,11 @@
  * maximum per-CPU boosting value.
  */
 struct boost_groups {
-	bool idle;
 	/* Maximum boost value for all RUNNABLE tasks on a CPU */
 	int boost_max;
 	struct {
+		/* True when this boost group maps an actual cgroup */
+		bool valid;
 		/* The boost for tasks on that boost group */
 		int boost;
 		/* Count of RUNNABLE tasks on that boost group */
@@ -358,6 +417,11 @@
 	/* The root boost group is always active */
 	boost_max = bg->group[0].boost;
 	for (idx = 1; idx < BOOSTGROUPS_COUNT; ++idx) {
+
+		/* Ignore non boostgroups not mapping a cgroup */
+		if (!bg->group[idx].valid)
+			continue;
+
 		/*
 		 * A boost group affects a CPU only if it has
 		 * RUNNABLE tasks on that CPU
@@ -367,6 +431,7 @@
 
 		boost_max = max(boost_max, bg->group[idx].boost);
 	}
+
 	/* Ensures boost_max is non-negative when all cgroup boost values
 	 * are neagtive. Avoids under-accounting of cpu capacity which may cause
 	 * task stacking and frequency spikes.*/
@@ -386,6 +451,9 @@
 	for_each_possible_cpu(cpu) {
 		bg = &per_cpu(cpu_boost_groups, cpu);
 
+		/* CGroups are never associated to non active cgroups */
+		BUG_ON(!bg->group[idx].valid);
+
 		/*
 		 * Keep track of current boost values to compute the per CPU
 		 * maximum only when it has been affected by the new value of
@@ -827,24 +895,22 @@
 	{ }	/* terminate */
 };
 
-
-static int
-schedtune_boostgroup_init(struct schedtune *st)
+static void
+schedtune_boostgroup_init(struct schedtune *st, int idx)
 {
 	struct boost_groups *bg;
 	int cpu;
 
-	/* Keep track of allocated boost groups */
-	allocated_group[st->idx] = st;
-
-	/* Initialize the per CPU boost groups */
+	/* Initialize per CPUs boost group support */
 	for_each_possible_cpu(cpu) {
 		bg = &per_cpu(cpu_boost_groups, cpu);
-		bg->group[st->idx].boost = 0;
-		bg->group[st->idx].tasks = 0;
+		bg->group[idx].boost = 0;
+		bg->group[idx].valid = true;
 	}
 
-	return 0;
+	/* Keep track of allocated boost groups */
+	allocated_group[idx] = st;
+	st->idx = idx;
 }
 
 static struct cgroup_subsys_state *
@@ -877,15 +943,11 @@
 		goto out;
 
 	/* Initialize per CPUs boost group support */
-	st->idx = idx;
 	init_sched_boost(st);
-	if (schedtune_boostgroup_init(st))
-		goto release;
+	schedtune_boostgroup_init(st, idx);
 
 	return &st->css;
 
-release:
-	kfree(st);
 out:
 	return ERR_PTR(-ENOMEM);
 }
@@ -893,8 +955,15 @@
 static void
 schedtune_boostgroup_release(struct schedtune *st)
 {
-	/* Reset this boost group */
-	schedtune_boostgroup_update(st->idx, 0);
+	struct boost_groups *bg;
+	int cpu;
+
+	/* Reset per CPUs boost group support */
+	for_each_possible_cpu(cpu) {
+		bg = &per_cpu(cpu_boost_groups, cpu);
+		bg->group[st->idx].valid = false;
+		bg->group[st->idx].boost = 0;
+	}
 
 	/* Keep track of allocated boost groups */
 	allocated_group[st->idx] = NULL;
@@ -905,6 +974,7 @@
 {
 	struct schedtune *st = css_st(css);
 
+	/* Release per CPUs boost group support */
 	schedtune_boostgroup_release(st);
 	kfree(st);
 }
@@ -930,6 +1000,7 @@
 	for_each_possible_cpu(cpu) {
 		bg = &per_cpu(cpu_boost_groups, cpu);
 		memset(bg, 0, sizeof(struct boost_groups));
+		bg->group[0].valid = true;
 		raw_spin_lock_init(&bg->lock);
 	}
 
diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
index 6721a1e8..88f398a 100644
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -481,9 +481,10 @@
 	struct trace_event_file *file;
 
 	list_for_each_entry(file, &tr->events, list) {
-		struct event_trigger_data *data;
-		list_for_each_entry_rcu(data, &file->triggers, list) {
+		struct event_trigger_data *data, *n;
+		list_for_each_entry_safe(data, n, &file->triggers, list) {
 			trace_event_trigger_enable_disable(file, 0);
+			list_del_rcu(&data->list);
 			if (data->ops->free)
 				data->ops->free(data->ops, data);
 		}
diff --git a/mm/mmap.c b/mm/mmap.c
index f549597..9ba15d8 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1398,6 +1398,35 @@
 	return 0;
 }
 
+static inline u64 file_mmap_size_max(struct file *file, struct inode *inode)
+{
+	if (S_ISREG(inode->i_mode))
+		return MAX_LFS_FILESIZE;
+
+	if (S_ISBLK(inode->i_mode))
+		return MAX_LFS_FILESIZE;
+
+	/* Special "we do even unsigned file positions" case */
+	if (file->f_mode & FMODE_UNSIGNED_OFFSET)
+		return 0;
+
+	/* Yes, random drivers might want more. But I'm tired of buggy drivers */
+	return ULONG_MAX;
+}
+
+static inline bool file_mmap_ok(struct file *file, struct inode *inode,
+				unsigned long pgoff, unsigned long len)
+{
+	u64 maxsize = file_mmap_size_max(file, inode);
+
+	if (maxsize && len > maxsize)
+		return false;
+	maxsize -= len;
+	if (pgoff > maxsize >> PAGE_SHIFT)
+		return false;
+	return true;
+}
+
 /*
  * The caller must hold down_write(&current->mm->mmap_sem).
  */
@@ -1470,6 +1499,9 @@
 	if (file) {
 		struct inode *inode = file_inode(file);
 
+		if (!file_mmap_ok(file, inode, pgoff, len))
+			return -EOVERFLOW;
+
 		switch (flags & MAP_TYPE) {
 		case MAP_SHARED:
 			if ((prot&PROT_WRITE) && !(file->f_mode&FMODE_WRITE))
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 7b3865c..6b5f0bc 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -543,7 +543,7 @@
 		}
 	}
 
-	if (printk_ratelimit())
+	if (!(gfp_mask & __GFP_NOWARN) && printk_ratelimit())
 		pr_warn("vmap allocation for size %lu failed: use vmalloc=<size> to increase size\n",
 			size);
 	kfree(va);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 4daac9a..abcc8be 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1455,7 +1455,7 @@
 				return ret;
 
 			mapping = page_mapping(page);
-			migrate_dirty = mapping && mapping->a_ops->migratepage;
+			migrate_dirty = !mapping || mapping->a_ops->migratepage;
 			unlock_page(page);
 			if (!migrate_dirty)
 				return ret;
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 0a9222e..da3d373 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1923,7 +1923,8 @@
 	int off, pad = 0;
 	unsigned int size_kern, match_size = mwt->match_size;
 
-	strlcpy(name, mwt->u.name, sizeof(name));
+	if (strscpy(name, mwt->u.name, sizeof(name)) < 0)
+		return -EINVAL;
 
 	if (state->buf_kern_start)
 		dst = state->buf_kern_start + state->buf_kern_offset;
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index c2339b8..f3a0ad1 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1914,6 +1914,10 @@
 	const struct net_device_ops *ops = dev->netdev_ops;
 	int err;
 
+	err = validate_linkmsg(dev, tb);
+	if (err < 0)
+		return err;
+
 	if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD]) {
 		struct net *net = rtnl_link_get_net(dev_net(dev), tb);
 		if (IS_ERR(net)) {
@@ -2234,10 +2238,6 @@
 		goto errout;
 	}
 
-	err = validate_linkmsg(dev, tb);
-	if (err < 0)
-		goto errout;
-
 	err = do_setlink(skb, dev, ifm, tb, ifname, 0);
 errout:
 	return err;
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index ff3b058..936dab1 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -280,9 +280,7 @@
 
 	dccp_clear_xmit_timers(sk);
 	ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
-	ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
 	dp->dccps_hc_rx_ccid = NULL;
-	dp->dccps_hc_tx_ccid = NULL;
 
 	__skb_queue_purge(&sk->sk_receive_queue);
 	__skb_queue_purge(&sk->sk_write_queue);
diff --git a/net/ipc_router/ipc_router_socket.c b/net/ipc_router/ipc_router_socket.c
index a758a09..4e53861 100644
--- a/net/ipc_router/ipc_router_socket.c
+++ b/net/ipc_router/ipc_router_socket.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-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
@@ -146,6 +146,7 @@
 			return -EINVAL;
 		}
 		ctl_msg = (union rr_control_msg *)(temp->data);
+		memset(addr, 0x0, sizeof(*addr));
 		addr->family = AF_MSM_IPC;
 		addr->address.addrtype = MSM_IPC_ADDR_ID;
 		addr->address.addr.port_addr.node_id = ctl_msg->cli.node_id;
@@ -154,6 +155,7 @@
 		return offset;
 	}
 	if (addr && (hdr->type == IPC_ROUTER_CTRL_CMD_DATA)) {
+		memset(addr, 0x0, sizeof(*addr));
 		addr->family = AF_MSM_IPC;
 		addr->address.addrtype = MSM_IPC_ADDR_ID;
 		addr->address.addr.port_addr.node_id = hdr->src_node_id;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index e1be244..d476b79 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -979,6 +979,8 @@
 			if (val == TCP_CA_UNSPEC)
 				return -EINVAL;
 		} else {
+			if (nla_len(nla) != sizeof(u32))
+				return false;
 			val = nla_get_u32(nla);
 		}
 		if (type == RTAX_ADVMSS && val > 65535 - 40)
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 5ddd649..dd80276 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -503,8 +503,6 @@
 	int err;
 	int copied;
 
-	WARN_ON_ONCE(sk->sk_family == AF_INET6);
-
 	err = -EAGAIN;
 	skb = sock_dequeue_err_skb(sk);
 	if (!skb)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index c2ad59d..f0fc835 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -582,8 +582,8 @@
 void tcp_rcv_space_adjust(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
+	u32 copied;
 	int time;
-	int copied;
 
 	time = tcp_time_stamp - tp->rcvq_space.time;
 	if (time < (tp->rcv_rtt_est.rtt >> 3) || tp->rcv_rtt_est.rtt == 0)
@@ -605,12 +605,13 @@
 
 	if (sysctl_tcp_moderate_rcvbuf &&
 	    !(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) {
-		int rcvwin, rcvmem, rcvbuf;
+		int rcvmem, rcvbuf;
+		u64 rcvwin;
 
 		/* minimal window to cope with packet losses, assuming
 		 * steady state. Add some cushion because of small variations.
 		 */
-		rcvwin = (copied << 1) + 16 * tp->advmss;
+		rcvwin = ((u64)copied << 1) + 16 * tp->advmss;
 
 		/* If rate increased by 25%,
 		 *	assume slow start, rcvwin = 3 * copied
@@ -630,12 +631,13 @@
 		while (tcp_win_from_space(rcvmem) < tp->advmss)
 			rcvmem += 128;
 
-		rcvbuf = min(rcvwin / tp->advmss * rcvmem, sysctl_tcp_rmem[2]);
+		do_div(rcvwin, tp->advmss);
+		rcvbuf = min_t(u64, rcvwin * rcvmem, sysctl_tcp_rmem[2]);
 		if (rcvbuf > sk->sk_rcvbuf) {
 			sk->sk_rcvbuf = rcvbuf;
 
 			/* Make the window clamp follow along.  */
-			tp->window_clamp = rcvwin;
+			tp->window_clamp = tcp_win_from_space(rcvbuf);
 		}
 	}
 	tp->rcvq_space.space = copied;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 71335ac..0f457be 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1669,6 +1669,10 @@
 			reqsk_put(req);
 			goto discard_it;
 		}
+		if (tcp_checksum_complete(skb)) {
+			reqsk_put(req);
+			goto csum_error;
+		}
 		if (unlikely(sk->sk_state != TCP_LISTEN)) {
 			inet_csk_reqsk_queue_drop_and_put(sk, req);
 			goto lookup;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 0b5a75b..ae5e38b 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -496,7 +496,8 @@
 	   send redirects to source routed frames.
 	   We don't send redirects to frames decapsulated from IPsec.
 	 */
-	if (skb->dev == dst->dev && opt->srcrt == 0 && !skb_sec_path(skb)) {
+	if (IP6CB(skb)->iif == dst->dev->ifindex &&
+	    opt->srcrt == 0 && !skb_sec_path(skb)) {
 		struct in6_addr *target = NULL;
 		struct inet_peer *peer;
 		struct rt6_info *rt;
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index a30e7e9..4b93ad4 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1789,7 +1789,8 @@
 		ret = 0;
 		if (!ip6mr_new_table(net, v))
 			ret = -ENOMEM;
-		raw6_sk(sk)->ip6mr_table = v;
+		else
+			raw6_sk(sk)->ip6mr_table = v;
 		rtnl_unlock();
 		return ret;
 	}
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 52236be..984d48b 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1540,6 +1540,12 @@
 	   ops_data_buf[NDISC_OPS_REDIRECT_DATA_SPACE], *ops_data = NULL;
 	bool ret;
 
+	if (netif_is_l3_master(skb->dev)) {
+		dev = __dev_get_by_index(dev_net(skb->dev), IPCB(skb)->iif);
+		if (!dev)
+			return;
+	}
+
 	if (ipv6_get_lladdr(dev, &saddr_buf, IFA_F_TENTATIVE)) {
 		ND_PRINTK(2, warn, "Redirect: no link-local address on %s\n",
 			  dev->name);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 0fbc5ba..efe939d 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1364,9 +1364,6 @@
 {
 	struct rt6_info *rt6 = (struct rt6_info *)dst;
 
-	if (rt6->rt6i_flags & RTF_LOCAL)
-		return;
-
 	if (dst_metric_locked(dst, RTAX_MTU))
 		return;
 
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 8efeff6..ed5d635 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1436,6 +1436,10 @@
 			reqsk_put(req);
 			goto discard_it;
 		}
+		if (tcp_checksum_complete(skb)) {
+			reqsk_put(req);
+			goto csum_error;
+		}
 		if (unlikely(sk->sk_state != TCP_LISTEN)) {
 			inet_csk_reqsk_queue_drop_and_put(sk, req);
 			goto lookup;
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 4003b28..d82f427 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -124,7 +124,7 @@
 	struct flowi6 *fl6 = &fl->u.ip6;
 	int onlyproto = 0;
 	const struct ipv6hdr *hdr = ipv6_hdr(skb);
-	u16 offset = sizeof(*hdr);
+	u32 offset = sizeof(*hdr);
 	struct ipv6_opt_hdr *exthdr;
 	const unsigned char *nh = skb_network_header(skb);
 	u16 nhoff = IP6CB(skb)->nhoff;
diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
index cc306de..553d0ad 100644
--- a/net/kcm/kcmsock.c
+++ b/net/kcm/kcmsock.c
@@ -1671,7 +1671,7 @@
 	__module_get(newsock->ops->owner);
 
 	newsk = sk_alloc(sock_net(osock->sk), PF_KCM, GFP_KERNEL,
-			 &kcm_proto, true);
+			 &kcm_proto, false);
 	if (!newsk) {
 		sock_release(newsock);
 		return ERR_PTR(-ENOMEM);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 15150b4..3ba903f 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -437,6 +437,24 @@
 	return 0;
 }
 
+static inline int sadb_key_len(const struct sadb_key *key)
+{
+	int key_bytes = DIV_ROUND_UP(key->sadb_key_bits, 8);
+
+	return DIV_ROUND_UP(sizeof(struct sadb_key) + key_bytes,
+			    sizeof(uint64_t));
+}
+
+static int verify_key_len(const void *p)
+{
+	const struct sadb_key *key = p;
+
+	if (sadb_key_len(key) > key->sadb_key_len)
+		return -EINVAL;
+
+	return 0;
+}
+
 static inline int pfkey_sec_ctx_len(const struct sadb_x_sec_ctx *sec_ctx)
 {
 	return DIV_ROUND_UP(sizeof(struct sadb_x_sec_ctx) +
@@ -533,16 +551,25 @@
 				return -EINVAL;
 			if (ext_hdrs[ext_type-1] != NULL)
 				return -EINVAL;
-			if (ext_type == SADB_EXT_ADDRESS_SRC ||
-			    ext_type == SADB_EXT_ADDRESS_DST ||
-			    ext_type == SADB_EXT_ADDRESS_PROXY ||
-			    ext_type == SADB_X_EXT_NAT_T_OA) {
+			switch (ext_type) {
+			case SADB_EXT_ADDRESS_SRC:
+			case SADB_EXT_ADDRESS_DST:
+			case SADB_EXT_ADDRESS_PROXY:
+			case SADB_X_EXT_NAT_T_OA:
 				if (verify_address_len(p))
 					return -EINVAL;
-			}
-			if (ext_type == SADB_X_EXT_SEC_CTX) {
+				break;
+			case SADB_X_EXT_SEC_CTX:
 				if (verify_sec_ctx_len(p))
 					return -EINVAL;
+				break;
+			case SADB_EXT_KEY_AUTH:
+			case SADB_EXT_KEY_ENCRYPT:
+				if (verify_key_len(p))
+					return -EINVAL;
+				break;
+			default:
+				break;
 			}
 			ext_hdrs[ext_type-1] = (void *) p;
 		}
@@ -1111,14 +1138,12 @@
 	key = ext_hdrs[SADB_EXT_KEY_AUTH - 1];
 	if (key != NULL &&
 	    sa->sadb_sa_auth != SADB_X_AALG_NULL &&
-	    ((key->sadb_key_bits+7) / 8 == 0 ||
-	     (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t)))
+	    key->sadb_key_bits == 0)
 		return ERR_PTR(-EINVAL);
 	key = ext_hdrs[SADB_EXT_KEY_ENCRYPT-1];
 	if (key != NULL &&
 	    sa->sadb_sa_encrypt != SADB_EALG_NULL &&
-	    ((key->sadb_key_bits+7) / 8 == 0 ||
-	     (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t)))
+	    key->sadb_key_bits == 0)
 		return ERR_PTR(-EINVAL);
 
 	x = xfrm_state_alloc(net);
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index c5f2350..079b3c4 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -2390,8 +2390,10 @@
 			struct ipvs_sync_daemon_cfg cfg;
 
 			memset(&cfg, 0, sizeof(cfg));
-			strlcpy(cfg.mcast_ifn, dm->mcast_ifn,
-				sizeof(cfg.mcast_ifn));
+			ret = -EINVAL;
+			if (strscpy(cfg.mcast_ifn, dm->mcast_ifn,
+				    sizeof(cfg.mcast_ifn)) <= 0)
+				goto out_dec;
 			cfg.syncid = dm->syncid;
 			ret = start_sync_thread(ipvs, &cfg, dm->state);
 		} else {
@@ -2429,12 +2431,19 @@
 		}
 	}
 
+	if ((cmd == IP_VS_SO_SET_ADD || cmd == IP_VS_SO_SET_EDIT) &&
+	    strnlen(usvc.sched_name, IP_VS_SCHEDNAME_MAXLEN) ==
+	    IP_VS_SCHEDNAME_MAXLEN) {
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
 	/* Check for valid protocol: TCP or UDP or SCTP, even for fwmark!=0 */
 	if (usvc.protocol != IPPROTO_TCP && usvc.protocol != IPPROTO_UDP &&
 	    usvc.protocol != IPPROTO_SCTP) {
-		pr_err("set_ctl: invalid protocol: %d %pI4:%d %s\n",
+		pr_err("set_ctl: invalid protocol: %d %pI4:%d\n",
 		       usvc.protocol, &usvc.addr.ip,
-		       ntohs(usvc.port), usvc.sched_name);
+		       ntohs(usvc.port));
 		ret = -EFAULT;
 		goto out_unlock;
 	}
@@ -2863,7 +2872,7 @@
 static const struct nla_policy ip_vs_daemon_policy[IPVS_DAEMON_ATTR_MAX + 1] = {
 	[IPVS_DAEMON_ATTR_STATE]	= { .type = NLA_U32 },
 	[IPVS_DAEMON_ATTR_MCAST_IFN]	= { .type = NLA_NUL_STRING,
-					    .len = IP_VS_IFNAME_MAXLEN },
+					    .len = IP_VS_IFNAME_MAXLEN - 1 },
 	[IPVS_DAEMON_ATTR_SYNC_ID]	= { .type = NLA_U32 },
 	[IPVS_DAEMON_ATTR_SYNC_MAXLEN]	= { .type = NLA_U16 },
 	[IPVS_DAEMON_ATTR_MCAST_GROUP]	= { .type = NLA_U32 },
@@ -2881,7 +2890,7 @@
 	[IPVS_SVC_ATTR_PORT]		= { .type = NLA_U16 },
 	[IPVS_SVC_ATTR_FWMARK]		= { .type = NLA_U32 },
 	[IPVS_SVC_ATTR_SCHED_NAME]	= { .type = NLA_NUL_STRING,
-					    .len = IP_VS_SCHEDNAME_MAXLEN },
+					    .len = IP_VS_SCHEDNAME_MAXLEN - 1 },
 	[IPVS_SVC_ATTR_PE_NAME]		= { .type = NLA_NUL_STRING,
 					    .len = IP_VS_PENAME_MAXLEN },
 	[IPVS_SVC_ATTR_FLAGS]		= { .type = NLA_BINARY,
diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c
index d2141a6..7f51f6d 100644
--- a/net/netfilter/xt_qtaguid.c
+++ b/net/netfilter/xt_qtaguid.c
@@ -1191,11 +1191,6 @@
 		       par->hooknum, __func__);
 		BUG();
 	}
-	if (unlikely(!(*el_dev)->name)) {
-		pr_err("qtaguid[%d]: %s(): no dev->name?!!\n",
-		       par->hooknum, __func__);
-		BUG();
-	}
 	if (skb->dev && *el_dev != skb->dev) {
 		MT_DEBUG("qtaguid[%d]: skb->dev=%pK %s vs par->%s=%pK %s\n",
 			 par->hooknum, skb->dev, skb->dev->name,
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 3ec89bb..8ab2b53 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -4299,7 +4299,7 @@
 			goto out;
 		if (po->tp_version >= TPACKET_V3 &&
 		    req->tp_block_size <=
-			  BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv))
+		    BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv) + sizeof(struct tpacket3_hdr))
 			goto out;
 		if (unlikely(req->tp_frame_size < po->tp_hdrlen +
 					po->tp_reserve))
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index 289af6f..8b2e87e 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -55,22 +55,22 @@
 	kfree(d->tcfd_defdata);
 }
 
-static int alloc_defdata(struct tcf_defact *d, char *defdata)
+static int alloc_defdata(struct tcf_defact *d, const struct nlattr *defdata)
 {
 	d->tcfd_defdata = kzalloc(SIMP_MAX_DATA, GFP_KERNEL);
 	if (unlikely(!d->tcfd_defdata))
 		return -ENOMEM;
-	strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
+	nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
 	return 0;
 }
 
-static void reset_policy(struct tcf_defact *d, char *defdata,
+static void reset_policy(struct tcf_defact *d, const struct nlattr *defdata,
 			 struct tc_defact *p)
 {
 	spin_lock_bh(&d->tcf_lock);
 	d->tcf_action = p->action;
 	memset(d->tcfd_defdata, 0, SIMP_MAX_DATA);
-	strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
+	nla_strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
 	spin_unlock_bh(&d->tcf_lock);
 }
 
@@ -89,7 +89,6 @@
 	struct tcf_defact *d;
 	bool exists = false;
 	int ret = 0, err;
-	char *defdata;
 
 	if (nla == NULL)
 		return -EINVAL;
@@ -112,8 +111,6 @@
 		return -EINVAL;
 	}
 
-	defdata = nla_data(tb[TCA_DEF_DATA]);
-
 	if (!exists) {
 		ret = tcf_hash_create(tn, parm->index, est, a,
 				      &act_simp_ops, bind, false);
@@ -121,7 +118,7 @@
 			return ret;
 
 		d = to_defact(*a);
-		ret = alloc_defdata(d, defdata);
+		ret = alloc_defdata(d, tb[TCA_DEF_DATA]);
 		if (ret < 0) {
 			tcf_hash_cleanup(*a, est);
 			return ret;
@@ -135,7 +132,7 @@
 		if (!ovr)
 			return -EEXIST;
 
-		reset_policy(d, defdata, parm);
+		reset_policy(d, tb[TCA_DEF_DATA], parm);
 	}
 
 	if (ret == ACT_P_CREATED)
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index ce54dce..03d71cd 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -608,7 +608,7 @@
 	    trans->state != SCTP_PF)
 		timeout += trans->hbinterval;
 
-	return timeout;
+	return max_t(unsigned long, timeout, HZ / 5);
 }
 
 /* Reset transport variables to their initial values */
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index a9c1da5..fcffce4 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -296,6 +296,9 @@
 ifndef CONFIG_FRAME_POINTER
 objtool_args += --no-fp
 endif
+ifdef CONFIG_GCOV_KERNEL
+objtool_args += --no-unreachable
+endif
 
 # 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory
 # 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 297b079..27aac27 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -745,7 +745,7 @@
 	struct menu *menu;
 	const char *basename;
 	const char *str;
-	char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1];
+	char dirname[PATH_MAX+1], tmpname[PATH_MAX+22], newname[PATH_MAX+8];
 	char *env;
 
 	dirname[0] = 0;
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 7bf8b00..1e6f23f7 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -389,14 +389,10 @@
 	result = ima_protect_xattr(dentry, xattr_name, xattr_value,
 				   xattr_value_len);
 	if (result == 1) {
-		bool digsig;
-
 		if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST))
 			return -EINVAL;
-		digsig = (xvalue->type == EVM_IMA_XATTR_DIGSIG);
-		if (!digsig && (ima_appraise & IMA_APPRAISE_ENFORCE))
-			return -EPERM;
-		ima_reset_appraise_flags(d_backing_inode(dentry), digsig);
+		ima_reset_appraise_flags(d_backing_inode(dentry),
+			 (xvalue->type == EVM_IMA_XATTR_DIGSIG) ? 1 : 0);
 		result = 0;
 	}
 	return result;
diff --git a/security/pfe/pfk_ice.c b/security/pfe/pfk_ice.c
index e1d0100..a86042c 100644
--- a/security/pfe/pfk_ice.c
+++ b/security/pfe/pfk_ice.c
@@ -138,9 +138,10 @@
 		if (ret1)
 			pr_err("%s: Invalidate Key Error: %d\n", __func__,
 					ret1);
-		goto out;
 	}
-	ret = qcom_ice_setup_ice_hw((const char *)s_type, false);
+	ret1 = qcom_ice_setup_ice_hw((const char *)s_type, false);
+	if (ret1)
+		pr_err("%s: Error %d disabling clocks\n", __func__, ret1);
 
 out:
 	return ret;
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 0af1132..56af730 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -748,8 +748,10 @@
 		return err;
 	strlcpy(pcm->name, cpcm->name, sizeof(pcm->name));
 	apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
-	if (apcm == NULL)
+	if (apcm == NULL) {
+		snd_device_free(chip->card, pcm);
 		return -ENOMEM;
+	}
 	apcm->chip = chip;
 	apcm->pcm = pcm;
 	apcm->codec = codec;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index b3851b9..6b5804e 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -851,6 +851,8 @@
 	SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK),
 	SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK),
 	SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK),
+	SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK),
+	SND_PCI_QUIRK(0x103c, 0x83d3, "HP ProBook 640 G4", CXT_FIXUP_HP_DOCK),
 	SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE),
 	SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC),
 	SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 39cd35f..183436e 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -333,6 +333,7 @@
 	case 0x10ec0236:
 	case 0x10ec0255:
 	case 0x10ec0256:
+	case 0x10ec0257:
 	case 0x10ec0282:
 	case 0x10ec0283:
 	case 0x10ec0286:
@@ -2663,6 +2664,7 @@
 	ALC269_TYPE_ALC298,
 	ALC269_TYPE_ALC255,
 	ALC269_TYPE_ALC256,
+	ALC269_TYPE_ALC257,
 	ALC269_TYPE_ALC225,
 	ALC269_TYPE_ALC294,
 	ALC269_TYPE_ALC700,
@@ -2695,6 +2697,7 @@
 	case ALC269_TYPE_ALC298:
 	case ALC269_TYPE_ALC255:
 	case ALC269_TYPE_ALC256:
+	case ALC269_TYPE_ALC257:
 	case ALC269_TYPE_ALC225:
 	case ALC269_TYPE_ALC294:
 	case ALC269_TYPE_ALC700:
@@ -6375,6 +6378,10 @@
 		spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
 		alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
 		break;
+	case 0x10ec0257:
+		spec->codec_variant = ALC269_TYPE_ALC257;
+		spec->gen.mixer_nid = 0;
+		break;
 	case 0x10ec0225:
 	case 0x10ec0295:
 	case 0x10ec0299:
@@ -7361,6 +7368,7 @@
 	HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
+	HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
 	HDA_CODEC_ENTRY(0x10ec0262, "ALC262", patch_alc262),
 	HDA_CODEC_ENTRY(0x10ec0267, "ALC267", patch_alc268),
diff --git a/sound/soc/intel/common/sst-firmware.c b/sound/soc/intel/common/sst-firmware.c
index a086c35..79a9fdf 100644
--- a/sound/soc/intel/common/sst-firmware.c
+++ b/sound/soc/intel/common/sst-firmware.c
@@ -274,7 +274,6 @@
 	struct sst_pdata *sst_pdata = sst->pdata;
 	struct sst_dma *dma;
 	struct resource mem;
-	const char *dma_dev_name;
 	int ret = 0;
 
 	if (sst->pdata->resindex_dma_base == -1)
@@ -285,7 +284,6 @@
 	* is attached to the ADSP IP. */
 	switch (sst->pdata->dma_engine) {
 	case SST_DMA_TYPE_DW:
-		dma_dev_name = "dw_dmac";
 		break;
 	default:
 		dev_err(sst->dev, "error: invalid DMA engine %d\n",
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h
index c278f27..aea30af 100644
--- a/tools/arch/x86/include/asm/cpufeatures.h
+++ b/tools/arch/x86/include/asm/cpufeatures.h
@@ -104,7 +104,7 @@
 #define X86_FEATURE_EXTD_APICID	( 3*32+26) /* has extended APICID (8 bits) */
 #define X86_FEATURE_AMD_DCM     ( 3*32+27) /* multi-node processor */
 #define X86_FEATURE_APERFMPERF	( 3*32+28) /* APERFMPERF */
-#define X86_FEATURE_EAGER_FPU	( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
+/* free, was #define X86_FEATURE_EAGER_FPU	( 3*32+29) * "eagerfpu" Non lazy FPU restore */
 #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
diff --git a/tools/objtool/.gitignore b/tools/objtool/.gitignore
index d3102c8..914cff1 100644
--- a/tools/objtool/.gitignore
+++ b/tools/objtool/.gitignore
@@ -1,3 +1,3 @@
-arch/x86/insn/inat-tables.c
+arch/x86/lib/inat-tables.c
 objtool
 fixdep