Merge "usb_bam: qdss: Add support for OCIMEM type"
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
index b55bd53..a9528c5 100644
--- a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt
@@ -61,6 +61,30 @@
 - qcom,dsi-pwm-gpio :			PWM gpio.
 - qcom,mdss-pan-broadcast-mode:		Boolean used to enable broadcast mode.
 - qcom,cont-splash-enabled:		Boolean used to enable continuous splash mode.
+- qcom,fbc-enabled:			Boolean used to enable frame buffer compression mode.
+- qcom,fbc-mode-select:			An array of length 7 that specifies the fbc mode supported
+					by the panel. FBC enabled panels may or may not support
+					the modes specified here. Each entry will
+					have the format specified below:
+					--> compressed bpp supported by the panel
+					--> component packing
+					--> enable/disable quantization error calculation
+					--> Bias for CD
+					--> enable/disable PAT mode
+					--> enable/disable VLC mode
+					--> enable/disable BFLC mode
+- qcom,fbc-budget-ctl:			An array of length 3 that specifies the budget control settings
+					supported by the fbc enabled panel. Each entry will have the format
+					specified below:
+					--> per line extra budget
+					--> extra budget level
+					--> per block budget
+- qcom,fbc-lossy-mode:			An array of 3 that specifies the lossy mode settings
+					supported by the fbc enabled panel. Each entry will
+					have the format specified below:
+					--> lossless mode threshold
+					--> lossy mode threshold
+					--> lossy RGB threshold
 - qcom,mdss-pan-porch-values:		An array of size 6 that specifies the panel blanking values.
 - qcom,mdss-pan-underflow-clr:		Specifies the controller settings for the panel underflow clear
 					settings. Default value is 0xff.
@@ -184,5 +208,9 @@
 		qcom,on-cmds-dsi-state = "DSI_LP_MODE";
 		qcom,panel-off-cmds = [22 01 00 00 00 00 00];
 		qcom,off-cmds-dsi-state = "DSI LP MODE";
+		qcom,fbc-enabled;
+		qcom,fbc-mode = <12 0 1 2 1 1 1>;
+		qcom,fbc-budget-ctl = <675 5 91>;
+		qcom,fbc-lossy-mode = <0 0xc0 0 3>;
 	};
 };
diff --git a/Documentation/devicetree/bindings/sound/taiko_codec.txt b/Documentation/devicetree/bindings/sound/taiko_codec.txt
index cbc77ad..ffea58f 100644
--- a/Documentation/devicetree/bindings/sound/taiko_codec.txt
+++ b/Documentation/devicetree/bindings/sound/taiko_codec.txt
@@ -61,6 +61,12 @@
  - qcom,cdc-slim-ifd-dev - namme of the codec slim interface device.
  - qcom,cdc-slim-ifd-elemental-addr - codec slimbus slave interface device
 				     enumeration address.
+
+Optional properties:
+ - cdc-dmic-sample-rate: Specifies the sample rate of digital mic in HZ. The
+			 values for 9.6MHZ mclk can be 2400000 Hz, 3200000 Hz
+			 and 4800000 Hz.  The values for 12.288MHz mclk can be
+			 3072200 Hz, 4096000 Hz and 6144000 Hz.
 Example:
 
 taiko_codec {
@@ -112,6 +118,7 @@
 	qcom,cdc-mclk-clk-rate = <9600000>;
 	qcom,cdc-slim-ifd = "taiko-slim-ifd";
 	qcom,cdc-slim-ifd-elemental-addr = [00 00 A0 00 17 02];
+	qcom,cdc-dmic-sample-rate = <4800000>;
 };
 
 Wcd9xxx audio CODEC in I2C mode
diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
index 9ce5421..fd5b93e 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -6,6 +6,9 @@
  - compatible: must be "synopsys,dwc3"
  - reg : Address and length of the register set for the device
  - interrupts: Interrupts used by the dwc3 controller.
+ - interrupt-names : Required interrupt resource entries are:
+	"irq" : Interrupt for DWC3 core
+	"otg_irq" : Interrupt for DWC3 core's OTG Events
 
 Optional properties:
  - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
@@ -15,6 +18,7 @@
 dwc3@4a030000 {
 	compatible = "synopsys,dwc3";
 	reg = <0x4a030000 0xcfff>;
-	interrupts = <0 92 4>
+	interrupts = <0 92 4>, <0 179 0>;
+	interrupt-names = "irq", "otg_irq";
 	tx-fifo-resize;
 };
diff --git a/Documentation/devicetree/bindings/usb/msm-ssusb.txt b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
index 51c0750..5391734 100644
--- a/Documentation/devicetree/bindings/usb/msm-ssusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
@@ -6,9 +6,6 @@
 	offset and length of the TCSR register for routing USB
 	signals to either picoPHY0 or picoPHY1.
 - interrupts: IRQ lines used by this controller
-- interrupt-names : Required interrupt resource entries are:
-	"irq" : Interrupt for DWC3 core
-	"otg_irq" : Interrupt for DWC3 core's OTG Events
 - <supply-name>-supply: phandle to the regulator device tree node
   Required "supply-name" examples are:
 	"SSUSB_lp8" : 1.8v supply for SSPHY
@@ -49,13 +46,18 @@
 		bits 13-19 PARAMETER_OVERRIDE_C
 		bits 20-25 PARAMETER_OVERRIDE_D
 
+Sub nodes:
+- Sub node for "DWC3- USB3 controller".
+  This sub node is required property for device node. The properties of this subnode
+  are specified in dwc3.txt.
+
 Example MSM USB3.0 controller device node :
 	usb@f9200000 {
 		compatible = "qcom,dwc-usb3-msm";
-		reg = <0xF9200000 0xFA000>,
-		      <0xFD4AB000 0x4>;
-		interrupts = <0 131 0>, <0 179 0>, <0 133 0>;
-		interrupt-names = "irq", "otg_irq", "hs_phy_irq";
+		reg = <0xf9200000 0xfc000>,
+		      <0xfd4ab000 0x4>;
+		interrupts = <0 133 0>;
+		interrupt-names = "hs_phy_irq";
 		ssusb_vdd_dig-supply = <&pm8841_s2_corner>;
 		SSUSB_1p8-supply = <&pm8941_l6>;
 		hsusb_vdd_dig-supply = <&pm8841_s2_corner>;
@@ -73,4 +75,11 @@
 		qcom,msm_bus,vectors =
 				<61 512 0 0>,
 				<61 512 240000000 960000000>;
+		dwc3@f9200000 {
+			compatible = "synopsys,dwc3";
+			reg = <0xf9200000 0xfc000>;
+			interrupts = <0 131 0>, <0 179 0>;
+			interrupt-names = "irq", "otg_irq";
+			tx-fifo-resize;
+};
 	};
diff --git a/arch/arm/boot/dts/msm-pm8226.dtsi b/arch/arm/boot/dts/msm-pm8226.dtsi
index e2b6a66..72de900 100644
--- a/arch/arm/boot/dts/msm-pm8226.dtsi
+++ b/arch/arm/boot/dts/msm-pm8226.dtsi
@@ -690,6 +690,13 @@
 			status = "disabled";
 		};
 
+		qcom,vibrator@c000 {
+			compatible = "qcom,qpnp-vibrator";
+			reg = <0xc000 0x100>;
+			label = "vibrator";
+			status = "disabled";
+		};
+
                 qcom,leds@d300 {
                         compatible = "qcom,leds-qpnp";
                         status = "disable";
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 2b1a352..6042f23 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -105,7 +105,7 @@
 			qcom,r-sense-uohm = <10000>;
 			qcom,v-cutoff-uv = <3400000>;
 			qcom,max-voltage-uv = <4200000>;
-			qcom,r-conn-mohm = <18>;
+			qcom,r-conn-mohm = <0>;
 			qcom,shutdown-soc-valid-limit = <20>;
 			qcom,adjust-soc-low-threshold = <25>;
 			qcom,adjust-soc-high-threshold = <45>;
@@ -839,7 +839,7 @@
 				qcom,scale-function = <1>;
 				qcom,hw-settle-time = <0>;
 				qcom,fast-avg-setup = <3>;
-				qcom,btm-channel-number = <0x88>;
+				qcom,btm-channel-number = <0x70>;
 			};
 
 			chan@6 {
@@ -848,10 +848,10 @@
 				qcom,decimation = <0>;
 				qcom,pre-div-channel-scaling = <1>;
 				qcom,calibration-type = "absolute";
-				qcom,scale-function = <3>;
+				qcom,scale-function = <0>;
 				qcom,hw-settle-time = <0>;
 				qcom,fast-avg-setup = <3>;
-				qcom,btm-channel-number = <0x90>;
+				qcom,btm-channel-number = <0x78>;
 			};
 
 			chan@b5 {
@@ -863,7 +863,7 @@
 				qcom,scale-function = <2>;
 				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <3>;
-				qcom,btm-channel-number = <0x70>;
+				qcom,btm-channel-number = <0x80>;
 				qcom,thermal-node;
 			};
 
@@ -876,7 +876,7 @@
 				qcom,scale-function = <2>;
 				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <3>;
-				qcom,btm-channel-number = <0x78>;
+				qcom,btm-channel-number = <0x88>;
 				qcom,thermal-node;
 			};
 
@@ -889,7 +889,7 @@
 				qcom,scale-function = <2>;
 				qcom,hw-settle-time = <2>;
 				qcom,fast-avg-setup = <3>;
-				qcom,btm-channel-number = <0x80>;
+				qcom,btm-channel-number = <0x90>;
 				qcom,thermal-node;
 			};
 
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-cdp-mtp-qrd.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-cdp-qrd.dtsi
similarity index 100%
rename from arch/arm/boot/dts/msm8226-camera-sensor-cdp-mtp-qrd.dtsi
rename to arch/arm/boot/dts/msm8226-camera-sensor-cdp-qrd.dtsi
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
new file mode 100644
index 0000000..02089be
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+/ {
+
+	led_flash0: qcom,camera-led-flash {
+		cell-index = <0>;
+		compatible = "qcom,camera-led-flash";
+		qcom,flash-type = <1>;
+		qcom,flash-source = <&pm8226_flash0 &pm8226_flash1>;
+	};
+};
+
+&cci {
+
+	actuator0: qcom,actuator@6e {
+		cell-index = <3>;
+		reg = <0x6c 0x0>;
+		compatible = "qcom,actuator";
+		qcom,cci-master = <0>;
+	};
+
+	qcom,camera@6f {
+		compatible = "qcom,ov8825";
+		reg = <0x6f>;
+		qcom,slave-id = <0x6c 0x300a 0x8825>;
+		qcom,csiphy-sd-index = <0>;
+		qcom,csid-sd-index = <0>;
+		qcom,actuator-src = <&actuator0>;
+		qcom,led-flash-src = <&led_flash0>;
+		qcom,mount-angle = <90>;
+		qcom,sensor-name = "ov8825";
+		cam_vdig-supply = <&pm8226_l5>;
+		cam_vana-supply = <&pm8226_l19>;
+		cam_vio-supply = <&pm8226_lvs1>;
+		cam_vaf-supply = <&pm8226_l15>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+							 "cam_vaf";
+		qcom,cam-vreg-type = <0 1 0 0>;
+		qcom,cam-vreg-min-voltage = <1200000 0 2850000 2800000>;
+		qcom,cam-vreg-max-voltage = <1200000 0 2850000 2800000>;
+		qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+		qcom,gpio-no-mux = <0>;
+		gpios = <&msmgpio 26 0>,
+			<&msmgpio 37 0>,
+			<&msmgpio 35 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+			"CAM_RESET1",
+			"CAM_STANDBY";
+		qcom,csi-lane-assign = <0x4320>;
+		qcom,csi-lane-mask = <0x1f>;
+		qcom,sensor-position = <0>;
+		qcom,sensor-mode = <1>;
+		qcom,cci-master = <0>;
+	};
+
+	qcom,camera@6d {
+		compatible = "qcom,ov9724";
+		reg = <0x6d>;
+		qcom,slave-id = <0x20 0x0 0x9724>;
+		qcom,csiphy-sd-index = <1>;
+		qcom,csid-sd-index = <0>;
+		qcom,mount-angle = <90>;
+		qcom,sensor-name = "ov9724";
+		cam_vdig-supply = <&pm8226_l5>;
+		cam_vana-supply = <&pm8226_l19>;
+		cam_vio-supply = <&pm8226_lvs1>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+		qcom,cam-vreg-type = <0 1 0>;
+		qcom,cam-vreg-min-voltage = <1200000 0 2850000>;
+		qcom,cam-vreg-max-voltage = <1200000 0 2850000>;
+		qcom,cam-vreg-op-mode = <200000 0 80000>;
+		qcom,gpio-no-mux = <0>;
+		gpios = <&msmgpio 26 0>,
+				<&msmgpio 28 0>,
+				<&msmgpio 36 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+				"CAM_RESET",
+				"CAM_STANDBY";
+		qcom,gpio-set-tbl-num = <1 1>;
+		qcom,gpio-set-tbl-flags = <0 2>;
+		qcom,gpio-set-tbl-delay = <1000 4000>;
+		qcom,csi-lane-assign = <0x4320>;
+		qcom,csi-lane-mask = <0x3>;
+		qcom,sensor-position = <1>;
+		qcom,sensor-mode = <1>;
+		qcom,cci-master = <0>;
+		status = "ok";
+	};
+};
diff --git a/arch/arm/boot/dts/msm8226-cdp.dts b/arch/arm/boot/dts/msm8226-cdp.dts
index eab8b07..52c591f 100644
--- a/arch/arm/boot/dts/msm8226-cdp.dts
+++ b/arch/arm/boot/dts/msm8226-cdp.dts
@@ -13,7 +13,7 @@
 /dts-v1/;
 /include/ "msm8226.dtsi"
 /include/ "dsi-panel-nt35590-720p-video.dtsi"
-/include/ "msm8226-camera-sensor-cdp-mtp-qrd.dtsi"
+/include/ "msm8226-camera-sensor-cdp-qrd.dtsi"
 
 / {
 	model = "Qualcomm MSM 8226 CDP";
diff --git a/arch/arm/boot/dts/msm8226-gpu.dtsi b/arch/arm/boot/dts/msm8226-gpu.dtsi
index ebd7749..6a8ba3a 100644
--- a/arch/arm/boot/dts/msm8226-gpu.dtsi
+++ b/arch/arm/boot/dts/msm8226-gpu.dtsi
@@ -9,61 +9,156 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
+/ {
+	msm_gpu: qcom,kgsl-3d0@fdb00000 {
+		label = "kgsl-3d0";
+		compatible = "qcom,kgsl-3d0", "qcom,kgsl-3d";
+		reg = <0xfdb00000 0x10000
+		       0xfdb20000 0x10000>;
+		reg-names = "kgsl_3d0_reg_memory" , "kgsl_3d0_shader_memory";
+		interrupts = <0 33 0>;
+		interrupt-names = "kgsl_3d0_irq";
+		qcom,id = <0>;
 
-/include/ "msm8974-gpu.dtsi"
+		qcom,chipid = <0x03000510>;
 
-&msm_gpu {
-	qcom,chipid = <0x03000510>;
+		qcom,initial-pwrlevel = <2>;
+		qcom,step-pwrlevel = <2>;
 
-	qcom,clk-map = <0x00000016>; /* KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM_IFACE */
+		qcom,idle-timeout = <8>; //<HZ/12>
+		qcom,nap-allowed = <1>;
+		qcom,strtstp-sleepwake;
+		qcom,clk-map = <0x00000016>; /* KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM_IFACE */
 
-	/* Bus Scale Settings */
-	qcom,msm-bus,name = "grp3d";
-	qcom,msm-bus,num-cases = <4>;
-	qcom,msm-bus,active-only = <0>;
-	qcom,msm-bus,num-paths = <2>;
-	qcom,msm-bus,vectors-KBps =
+		/* Bus Scale Settings */
+		qcom,msm-bus,name = "grp3d";
+		qcom,msm-bus,num-cases = <4>;
+		qcom,msm-bus,active-only = <0>;
+		qcom,msm-bus,num-paths = <2>;
+		qcom,msm-bus,vectors-KBps =
 			<26 512 0 0>, <89 604 0 0>,
 			<26 512 0 1600000>, <89 604 0 3200000>,
 			<26 512 0 3200000>, <89 604 0 5120000>,
 			<26 512 0 4256000>, <89 604 0 6400000>;
 
-	/* GDSC oxili regulators */
-	vddcx-supply = "\0";
-	vdd-supply = <&gdsc_oxili_cx>;
 
-	qcom,gpu-pwrlevels {
-		#address-cells = <1>;
-		#size-cells = <0>;
+		/* GDSC oxili regulators */
+		vddcx-supply = "\0";
+		vdd-supply = <&gdsc_oxili_cx>;
 
-		compatible = "qcom,gpu-pwrlevels";
 
-		qcom,gpu-pwrlevel@0 {
-			reg = <0>;
-			qcom,gpu-freq = <450000000>;
-			qcom,bus-freq = <3>;
-			qcom,io-fraction = <0>;
+		/* IOMMU Data */
+		iommu = <&kgsl_iommu>;
+
+		/* Power levels */
+		qcom,gpu-pwrlevels {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			compatible = "qcom,gpu-pwrlevels";
+
+			qcom,gpu-pwrlevel@0 {
+				reg = <0>;
+				qcom,gpu-freq = <450000000>;
+				qcom,bus-freq = <3>;
+				qcom,io-fraction = <0>;
+			};
+
+			qcom,gpu-pwrlevel@1 {
+				reg = <1>;
+				qcom,gpu-freq = <320000000>;
+				qcom,bus-freq = <2>;
+				qcom,io-fraction = <33>;
+			};
+
+			qcom,gpu-pwrlevel@2 {
+				reg = <2>;
+				qcom,gpu-freq = <200000000>;
+				qcom,bus-freq = <1>;
+				qcom,io-fraction = <100>;
+			};
+
+			qcom,gpu-pwrlevel@3 {
+				reg = <3>;
+				qcom,gpu-freq = <19000000>;
+				qcom,bus-freq = <0>;
+				qcom,io-fraction = <0>;
+			};
 		};
 
-		qcom,gpu-pwrlevel@1 {
-			reg = <1>;
-			qcom,gpu-freq = <320000000>;
-			qcom,bus-freq = <2>;
-			qcom,io-fraction = <33>;
+		qcom,dcvs-core-info {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			compatible = "qcom,dcvs-core-info";
+
+			qcom,num-cores = <1>;
+			qcom,sensors = <0>;
+
+			qcom,core-core-type = <1>;
+
+			qcom,algo-disable-pc-threshold = <0>;
+			qcom,algo-em-win-size-min-us = <100000>;
+			qcom,algo-em-win-size-max-us = <300000>;
+			qcom,algo-em-max-util-pct = <97>;
+			qcom,algo-group-id = <95>;
+			qcom,algo-max-freq-chg-time-us = <100000>;
+			qcom,algo-slack-mode-dynamic = <100000>;
+			qcom,algo-slack-weight-thresh-pct = <0>;
+			qcom,algo-slack-time-min-us = <39000>;
+			qcom,algo-slack-time-max-us = <39000>;
+			qcom,algo-ss-win-size-min-us = <1000000>;
+			qcom,algo-ss-win-size-max-us = <1000000>;
+			qcom,algo-ss-util-pct = <95>;
+			qcom,algo-ss-no-corr-below-freq = <0>;
+
+			qcom,energy-active-coeff-a = <2492>;
+			qcom,energy-active-coeff-b = <0>;
+			qcom,energy-active-coeff-c = <0>;
+			qcom,energy-leakage-coeff-a = <11>;
+			qcom,energy-leakage-coeff-b = <157150>;
+			qcom,energy-leakage-coeff-c = <0>;
+			qcom,energy-leakage-coeff-d = <0>;
+
+			qcom,power-current-temp = <25>;
+			qcom,power-num-freq = <4>;
+
+			qcom,dcvs-freq@0 {
+				reg = <0>;
+				qcom,freq = <0>;
+				qcom,voltage = <0>;
+				qcom,is_trans_level = <0>;
+				qcom,active-energy-offset = <100>;
+				qcom,leakage-energy-offset = <0>;
+			};
+
+			qcom,dcvs-freq@1 {
+				reg = <1>;
+				qcom,freq = <0>;
+				qcom,voltage = <0>;
+				qcom,is_trans_level = <0>;
+				qcom,active-energy-offset = <100>;
+				qcom,leakage-energy-offset = <0>;
+			};
+
+			qcom,dcvs-freq@2 {
+				reg = <2>;
+				qcom,freq = <0>;
+				qcom,voltage = <0>;
+				qcom,is_trans_level = <0>;
+				qcom,active-energy-offset = <100>;
+				qcom,leakage-energy-offset = <0>;
+			};
+
+			qcom,dcvs-freq@3 {
+				reg = <3>;
+				qcom,freq = <0>;
+				qcom,voltage = <0>;
+				qcom,is_trans_level = <0>;
+				qcom,active-energy-offset = <844545>;
+				qcom,leakage-energy-offset = <0>;
+			};
 		};
 
-		qcom,gpu-pwrlevel@2 {
-			reg = <2>;
-			qcom,gpu-freq = <200000000>;
-			qcom,bus-freq = <1>;
-			qcom,io-fraction = <100>;
-		};
-
-		qcom,gpu-pwrlevel@3 {
-			reg = <3>;
-			qcom,gpu-freq = <19000000>;
-			qcom,bus-freq = <0>;
-			qcom,io-fraction = <0>;
-		};
 	};
 };
diff --git a/arch/arm/boot/dts/msm8226-mtp.dts b/arch/arm/boot/dts/msm8226-mtp.dts
index 5c6fbd5..68fa8ba 100644
--- a/arch/arm/boot/dts/msm8226-mtp.dts
+++ b/arch/arm/boot/dts/msm8226-mtp.dts
@@ -13,7 +13,7 @@
 /dts-v1/;
 /include/ "msm8226.dtsi"
 /include/ "dsi-panel-nt35590-720p-video.dtsi"
-/include/ "msm8226-camera-sensor-cdp-mtp-qrd.dtsi"
+/include/ "msm8226-camera-sensor-mtp.dtsi"
 
 / {
 	model = "Qualcomm MSM 8226 MTP";
diff --git a/arch/arm/boot/dts/msm8226-pm.dtsi b/arch/arm/boot/dts/msm8226-pm.dtsi
index 34283e8..99f0631 100644
--- a/arch/arm/boot/dts/msm8226-pm.dtsi
+++ b/arch/arm/boot/dts/msm8226-pm.dtsi
@@ -25,9 +25,9 @@
 		qcom,saw2-spm-ctl = <0x0>;
 		qcom,saw2-spm-cmd-wfi = [60 03 60 0b 0f];
 		qcom,saw2-spm-cmd-spc = [00 20 10 80 30 90 5b 60 03 60 3b 76 76
-				0b 94 5b 80 10 2b 06 26 30 0f];
+				0b 94 5b 80 10 06 26 30 0f];
 		qcom,saw2-spm-cmd-pc = [00 20 10 80 30 90 5b 60 07 60 3b 76 76
-				0b 94 5b 80 10 2b 06 26 30 0f];
+				0b 94 5b 80 10 06 26 30 0f];
 	};
 
 	qcom,spm@f9099000 {
@@ -42,9 +42,9 @@
 		qcom,saw2-spm-ctl = <0x0>;
 		qcom,saw2-spm-cmd-wfi = [60 03 60 0b 0f];
 		qcom,saw2-spm-cmd-spc = [00 20 10 80 30 90 5b 60 03 60 3b 76 76
-				0b 94 5b 80 10 2b 06 26 30 0f];
+				0b 94 5b 80 10 06 26 30 0f];
 		qcom,saw2-spm-cmd-pc = [00 20 10 80 30 90 5b 60 07 60 3b 76 76
-				0b 94 5b 80 10 2b 06 26 30 0f];
+				0b 94 5b 80 10 06 26 30 0f];
 	};
 
 	qcom,spm@f90a9000 {
@@ -57,11 +57,11 @@
 		qcom,saw2-cfg = <0x01>;
 		qcom,saw2-spm-dly= <0x3c102800>;
 		qcom,saw2-spm-ctl = <0x0>;
-		qcom,saw2-spm-cmd-wfi = [60 03 60 76 76 0b 0f];
+		qcom,saw2-spm-cmd-wfi = [60 03 60 0b 0f];
 		qcom,saw2-spm-cmd-spc = [00 20 10 80 30 90 5b 60 03 60 3b 76 76
-				0b 94 5b 80 10 2b 06 26 30 0f];
+				0b 94 5b 80 10 06 26 30 0f];
 		qcom,saw2-spm-cmd-pc = [00 20 10 80 30 90 5b 60 07 60 3b 76 76
-				0b 94 5b 80 10 2b 06 26 30 0f];
+				0b 94 5b 80 10 06 26 30 0f];
 	};
 
 	qcom,spm@f90b9000 {
@@ -74,11 +74,11 @@
 		qcom,saw2-cfg = <0x01>;
 		qcom,saw2-spm-dly= <0x3c102800>;
 		qcom,saw2-spm-ctl = <0x0>;
-		qcom,saw2-spm-cmd-wfi = [60 03 60 76 76 0b 0f];
+		qcom,saw2-spm-cmd-wfi = [60 03 60 0b 0f];
 		qcom,saw2-spm-cmd-spc = [00 20 10 80 30 90 5b 60 03 60 3b 76 76
-				0b 94 5b 80 10 2b 06 26 30 0f];
+				0b 94 5b 80 10 06 26 30 0f];
 		qcom,saw2-spm-cmd-pc = [00 20 10 80 30 90 5b 60 07 60 3b 76 76
-				0b 94 5b 80 10 2b 06 26 30 0f];
+				0b 94 5b 80 10 06 26 30 0f];
 	};
 
 	qcom,spm@f9012000 {
@@ -91,19 +91,16 @@
 		qcom,saw2-cfg = <0x14>;
 		qcom,saw2-spm-dly= <0x3c102800>;
 		qcom,saw2-spm-ctl = <0x0>;
-		qcom,saw2-pmic-data0 = <0x0400009c>;
-		qcom,saw2-pmic-data1 = <0x0000001c>;
+		qcom,saw2-pmic-data0 = <0x02030080>;
+		qcom,saw2-pmic-data1 = <0x00030000>;
 		qcom,vctl-timeout-us = <50>;
 		qcom,vctl-port = <0x0>;
 		qcom,phase-port = <0x1>;
 		qcom,pfm-port = <0x2>;
 		qcom,saw2-spm-cmd-ret = [00 03 00 7b 0f];
-		qcom,saw2-spm-cmd-gdhs = [00 20 32 60 70 80 6b c0 e0 d0 42 07
-				78 1f 80 4e d0 e0 c0 22 6b 50 4b 60 02 32 50 7b
-				0f];
-		qcom,saw2-spm-cmd-pc = [00 32 60 70 80 b0 10 e0 d0 6b c0
-				42 f0 11 07 01 b0 78 1f 80 4e c0 d0 12 e0 6b 50 4b
-				60 02 32 50 f0 7b 0f]; /*APCS_PMIC_OFF_L2RAM_OFF*/
+		qcom,saw2-spm-cmd-pc = [00 32 b0 10 e0 d0 6b c0 42 f0
+				11 07 01 b0 4e c0 d0 12 e0 6b 50 02 32
+				50 f0 7b 0f]; /*APCS_PMIC_OFF_L2RAM_OFF*/
 	};
 
 	qcom,lpm-resources {
@@ -125,8 +122,8 @@
 			qcom,name = "vdd-mem";
 			qcom,type = <0x616F646C>;	/* "ldoa" */
 			qcom,id = <0x03>;
-			qcom,key = <0x7675>;		/* "uv" */
-			qcom,init-value = <1050000>;	/* Super Turbo */
+			qcom,key = <0x6e726f63>;	/* "corn" */
+			qcom,init-value = <3>;		/* Active */
 		};
 
 		qcom,lpm-resources@2 {
@@ -156,10 +153,10 @@
 			qcom,mode = "wfi";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
 			qcom,latency-us = <1>;
 			qcom,ss-power = <784>;
 			qcom,energy-overhead = <190000>;
@@ -171,10 +168,10 @@
 			qcom,mode = "retention";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
 			qcom,latency-us = <75>;
 			qcom,ss-power = <735>;
 			qcom,energy-overhead = <77341>;
@@ -187,10 +184,10 @@
 			qcom,mode = "standalone_pc";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_active";
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
 			qcom,latency-us = <95>;
 			qcom,ss-power = <725>;
 			qcom,energy-overhead = <99500>;
@@ -202,10 +199,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_gdhs";
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
 			qcom,latency-us = <2000>;
 			qcom,ss-power = <138>;
 			qcom,energy-overhead = <1208400>;
@@ -217,10 +214,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_on";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-mem-lower-bound = <750000>;  /* RETENTION HIGH */
-			qcom,vdd-dig-upper-bound = <3>;  /* ACTIVE */
-			qcom,vdd-dig-lower-bound = <2>;  /* RETENTION HIGH */
+			qcom,vdd-mem-upper-bound = <3>; /* NORMAL */
+			qcom,vdd-mem-lower-bound = <2>;  /* SVS SOC */
+			qcom,vdd-dig-upper-bound = <3>;  /* NORMAL */
+			qcom,vdd-dig-lower-bound = <2>;  /* SVS SOC */
 			qcom,latency-us = <3000>;
 			qcom,ss-power = <110>;
 			qcom,energy-overhead = <1250300>;
@@ -232,10 +229,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_off";
 			qcom,l2 = "l2_cache_gdhs";
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
 			qcom,latency-us = <3000>;
 			qcom,ss-power = <68>;
 			qcom,energy-overhead = <1350200>;
@@ -247,10 +244,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_off";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <1150000>; /* MAX */
-			qcom,vdd-mem-lower-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-dig-upper-bound = <5>; /* MAX */
-			qcom,vdd-dig-lower-bound = <3>;  /* ACTIVE */
+			qcom,vdd-mem-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-mem-lower-bound = <3>; /* NORMAL */
+			qcom,vdd-dig-upper-bound = <5>; /* SUPER TURBO */
+			qcom,vdd-dig-lower-bound = <3>;  /* NORMAL */
 			qcom,latency-us = <10300>;
 			qcom,ss-power = <63>;
 			qcom,energy-overhead = <2128000>;
@@ -262,10 +259,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_off";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <1050000>; /* ACTIVE */
-			qcom,vdd-mem-lower-bound = <750000>;  /* RETENTION HIGH */
-			qcom,vdd-dig-upper-bound = <3>;  /* ACTIVE */
-			qcom,vdd-dig-lower-bound = <2>;  /* RETIONTION HIGH */
+			qcom,vdd-mem-upper-bound = <3>; /* NORMAL */
+			qcom,vdd-mem-lower-bound = <2>;  /* SVS SOC */
+			qcom,vdd-dig-upper-bound = <3>;  /* NORMAL */
+			qcom,vdd-dig-lower-bound = <2>;  /* SVS SOC */
 			qcom,latency-us = <18000>;
 			qcom,ss-power = <10>;
 			qcom,energy-overhead = <3202600>;
@@ -277,10 +274,10 @@
 			qcom,mode = "pc";
 			qcom,xo = "xo_off";
 			qcom,l2 = "l2_cache_pc";
-			qcom,vdd-mem-upper-bound = <750000>; /* RETENTION HIGH */
-			qcom,vdd-mem-lower-bound = <750000>; /* RETENTION LOW */
-			qcom,vdd-dig-upper-bound = <2>; /* RETENTION HIGH */
-			qcom,vdd-dig-lower-bound = <0>; /* RETENTION LOW */
+			qcom,vdd-mem-upper-bound = <2>; /* SVS SOC */
+			qcom,vdd-mem-lower-bound = <0>; /* RETENTION */
+			qcom,vdd-dig-upper-bound = <2>; /* SVS SOC */
+			qcom,vdd-dig-lower-bound = <0>; /* RETENTION */
 			qcom,latency-us = <20000>;
 			qcom,ss-power = <2>;
 			qcom,energy-overhead = <4252000>;
@@ -306,6 +303,7 @@
 		qcom,gic-map = <47 172>, /* usb2_hsic_async_wakeup_irq */
 			<53 104>, /* mdss_irq */
 			<62 222>, /* ee0_krait_hlos_spmi_periph_irq */
+			<2 216>, /* tsens_upper_lower_int */
 			<0xff 56>,  /* q6_wdog_expired_irq */
 			<0xff 57>,  /* mss_to_apps_irq(0) */
 			<0xff 58>,  /* mss_to_apps_irq(1) */
diff --git a/arch/arm/boot/dts/msm8226-qrd.dts b/arch/arm/boot/dts/msm8226-qrd.dts
index df74bf9..618412a 100644
--- a/arch/arm/boot/dts/msm8226-qrd.dts
+++ b/arch/arm/boot/dts/msm8226-qrd.dts
@@ -13,7 +13,7 @@
 /dts-v1/;
 /include/ "msm8226.dtsi"
 /include/ "dsi-panel-nt35590-720p-video.dtsi"
-/include/ "msm8226-camera-sensor-cdp-mtp-qrd.dtsi"
+/include/ "msm8226-camera-sensor-cdp-qrd.dtsi"
 
 / {
 	model = "Qualcomm MSM 8226 QRD";
@@ -197,6 +197,13 @@
 				qcom,id = <0>;
 			};
 		};
+
+		qcom,vibrator@c000 {
+			status = "okay";
+			qcom,vib-timeout-ms = <15000>;
+			qcom,vib-vtg-level-mV = <3100>;
+		};
+
 	};
 };
 
diff --git a/arch/arm/boot/dts/msm8226-regulator.dtsi b/arch/arm/boot/dts/msm8226-regulator.dtsi
index 9c21707..f24cea1 100644
--- a/arch/arm/boot/dts/msm8226-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8226-regulator.dtsi
@@ -64,7 +64,7 @@
 			regulator-min-microvolt = <1>;
 			regulator-max-microvolt = <7>;
 			qcom,use-voltage-corner;
-			qcom,consumer-supplies = "vdd_dig", "";
+			qcom,consumer-supplies = "vdd_dig", "", "vdd_sr2_dig", "";
 		};
 		pm8226_s1_corner_ao: regulator-s1-corner-ao {
 			compatible = "qcom,rpm-regulator-smd";
diff --git a/arch/arm/boot/dts/msm8610-coresight.dtsi b/arch/arm/boot/dts/msm8610-coresight.dtsi
index 3612078..89a00f1 100644
--- a/arch/arm/boot/dts/msm8610-coresight.dtsi
+++ b/arch/arm/boot/dts/msm8610-coresight.dtsi
@@ -203,7 +203,7 @@
 		coresight-name = "coresight-csr";
 		coresight-nr-inports = <0>;
 
-		qcom,blk-size = <3>;
+		qcom,blk-size = <1>;
 	};
 
 	cti0: cti@fc310000 {
diff --git a/arch/arm/boot/dts/msm8610-pm.dtsi b/arch/arm/boot/dts/msm8610-pm.dtsi
index ff16b8d..27af9a9 100644
--- a/arch/arm/boot/dts/msm8610-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-pm.dtsi
@@ -306,6 +306,7 @@
 		qcom,gic-map = <47 172>, /* usb2_hsic_async_wakeup_irq */
 			<53 104>, /* mdss_irq */
 			<62 222>, /* ee0_krait_hlos_spmi_periph_irq */
+			<2 216>, /* tsens_upper_lower_int */
 			<0xff 56>,  /* q6_wdog_expired_irq */
 			<0xff 57>,  /* mss_to_apps_irq(0) */
 			<0xff 58>,  /* mss_to_apps_irq(1) */
diff --git a/arch/arm/boot/dts/msm8610-regulator.dtsi b/arch/arm/boot/dts/msm8610-regulator.dtsi
index 5512ccd..d50902c 100644
--- a/arch/arm/boot/dts/msm8610-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8610-regulator.dtsi
@@ -19,7 +19,7 @@
 		qcom,hpm-min-load = <100000>;
 		regulator-min-microvolt = <1>;
 		regulator-max-microvolt = <7>;
-		qcom,consumer-supplies = "vdd_dig", "";
+		qcom,consumer-supplies = "vdd_dig", "", "vdd_sr2_dig", "";
 	};
 };
 
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-cdp.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-cdp.dtsi
new file mode 100644
index 0000000..a6a115c
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-camera-sensor-cdp.dtsi
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+&cci {
+
+	actuator0: qcom,actuator@18 {
+		cell-index = <0>;
+		reg = <0x18 0x0>;
+		compatible = "qcom,actuator";
+		qcom,cci-master = <0>;
+	};
+
+	qcom,camera@6e {
+		compatible = "qcom,s5k3l1yx";
+		reg = <0x6e 0x0>;
+		qcom,slave-id = <0x6e 0x0 0x3121>;
+		qcom,csiphy-sd-index = <0>;
+		qcom,csid-sd-index = <0>;
+		qcom,actuator-src = <&actuator0>;
+		qcom,mount-angle = <90>;
+		qcom,sensor-name = "s5k3l1yx";
+		cam_vdig-supply = <&pm8941_l3>;
+		cam_vana-supply = <&pm8941_l17>;
+		cam_vio-supply = <&pm8941_lvs3>;
+		cam_vaf-supply = <&pm8941_l23>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+				     "cam_vaf";
+		qcom,cam-vreg-type = <0 1 0 0>;
+		qcom,cam-vreg-min-voltage = <1225000 0 2850000 3000000>;
+		qcom,cam-vreg-max-voltage = <1225000 0 2850000 3000000>;
+		qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+		qcom,gpio-no-mux = <0>;
+		gpios = <&msmgpio 15 0>,
+			<&msmgpio 90 0>,
+			<&msmgpio 89 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-standby = <2>;
+		qcom,gpio-req-tbl-num = <0 1 2>;
+		qcom,gpio-req-tbl-flags = <1 0 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+					  "CAM_RESET1",
+					  "CAM_STANDBY";
+		qcom,gpio-set-tbl-num = <1 1>;
+		qcom,gpio-set-tbl-flags = <0 2>;
+		qcom,gpio-set-tbl-delay = <1000 30000>;
+		qcom,csi-lane-assign = <0x4320>;
+		qcom,csi-lane-mask = <0x1F>;
+		qcom,sensor-position = <0>;
+		qcom,sensor-mode = <1>;
+		qcom,cci-master = <0>;
+		status = "ok";
+	};
+
+	qcom,camera@6c {
+		compatible = "qcom,ov2720";
+		reg = <0x6c 0x0>;
+		qcom,slave-id = <0x6c 0x300A 0x2720>;
+		qcom,csiphy-sd-index = <2>;
+		qcom,csid-sd-index = <0>;
+		qcom,mount-angle = <90>;
+		qcom,sensor-name = "ov2720";
+		cam_vdig-supply = <&pm8941_l3>;
+		cam_vana-supply = <&pm8941_l17>;
+		cam_vio-supply = <&pm8941_lvs3>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vana", "cam_vio";
+		qcom,cam-vreg-type = <0 0 1>;
+		qcom,cam-vreg-min-voltage = <1225000 2850000 0>;
+		qcom,cam-vreg-max-voltage = <1225000 2850000 0>;
+		qcom,cam-vreg-op-mode = <105000 80000 0>;
+		qcom,gpio-no-mux = <0>;
+		gpios = <&msmgpio 17 0>,
+			<&msmgpio 18 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-req-tbl-num = <0 1>;
+		qcom,gpio-req-tbl-flags = <1 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+					  "CAM_RESET1";
+		qcom,gpio-set-tbl-num = <1 1>;
+		qcom,gpio-set-tbl-flags = <0 2>;
+		qcom,gpio-set-tbl-delay = <1000 4000>;
+		qcom,csi-lane-assign = <0x4320>;
+		qcom,csi-lane-mask = <0x7>;
+		qcom,sensor-position = <1>;
+		qcom,sensor-mode = <1>;
+		qcom,cci-master = <0>;
+		status = "ok";
+	};
+
+	qcom,camera@90 {
+		compatible = "qcom,mt9m114";
+		reg = <0x90 0x0>;
+		qcom,slave-id = <0x90 0x0 0x2481>;
+		qcom,csiphy-sd-index = <1>;
+		qcom,csid-sd-index = <0>;
+		qcom,mount-angle = <0>;
+		qcom,sensor-name = "mt9m114";
+		cam_vdig-supply = <&pm8941_l3>;
+		cam_vana-supply = <&pm8941_l17>;
+		cam_vio-supply = <&pm8941_lvs3>;
+		qcom,cam-vreg-name = "cam_vdig", "cam_vana", "cam_vio";
+		qcom,cam-vreg-type = <0 0 1>;
+		qcom,cam-vreg-min-voltage = <1225000 2850000 0>;
+		qcom,cam-vreg-max-voltage = <1225000 2850000 0>;
+		qcom,cam-vreg-op-mode = <105000 80000 0>;
+		qcom,gpio-no-mux = <0>;
+		gpios = <&msmgpio 16 0>,
+			<&msmgpio 92 0>;
+		qcom,gpio-reset = <1>;
+		qcom,gpio-req-tbl-num = <0 1>;
+		qcom,gpio-req-tbl-flags = <1 0>;
+		qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+					  "CAM_RESET1";
+		qcom,gpio-set-tbl-num = <1 1>;
+		qcom,gpio-set-tbl-flags = <0 2>;
+		qcom,gpio-set-tbl-delay = <1000 4000>;
+		qcom,csi-lane-assign = <0x4320>;
+		qcom,csi-lane-mask = <0x3>;
+		qcom,sensor-position = <1>;
+		qcom,sensor-mode = <1>;
+		qcom,cci-master = <0>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8974-camera-sensor-cdp-mtp.dtsi b/arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi
similarity index 100%
rename from arch/arm/boot/dts/msm8974-camera-sensor-cdp-mtp.dtsi
rename to arch/arm/boot/dts/msm8974-camera-sensor-mtp.dtsi
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index 2919709..41e3783 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -13,7 +13,7 @@
 /include/ "dsi-panel-toshiba-720p-video.dtsi"
 /include/ "dsi-panel-orise-720p-video.dtsi"
 /include/ "msm8974-leds.dtsi"
-/include/ "msm8974-camera-sensor-cdp-mtp.dtsi"
+/include/ "msm8974-camera-sensor-cdp.dtsi"
 
 / {
 	serial@f991e000 {
diff --git a/arch/arm/boot/dts/msm8974-gpu.dtsi b/arch/arm/boot/dts/msm8974-gpu.dtsi
index ceba72f..a7544ab 100644
--- a/arch/arm/boot/dts/msm8974-gpu.dtsi
+++ b/arch/arm/boot/dts/msm8974-gpu.dtsi
@@ -62,21 +62,21 @@
 				reg = <0>;
 				qcom,gpu-freq = <450000000>;
 				qcom,bus-freq = <5>;
-				qcom,io-fraction = <0>;
+				qcom,io-fraction = <33>;
 			};
 
 			qcom,gpu-pwrlevel@1 {
 				reg = <1>;
 				qcom,gpu-freq = <300000000>;
 				qcom,bus-freq = <4>;
-				qcom,io-fraction = <33>;
+				qcom,io-fraction = <66>;
 			};
 
 			qcom,gpu-pwrlevel@2 {
 				reg = <2>;
 				qcom,gpu-freq = <300000000>;
 				qcom,bus-freq = <3>;
-				qcom,io-fraction = <33>;
+				qcom,io-fraction = <66>;
 			};
 
 			qcom,gpu-pwrlevel@3 {
diff --git a/arch/arm/boot/dts/msm8974-mdss.dtsi b/arch/arm/boot/dts/msm8974-mdss.dtsi
index 0912a33..5c42b2c 100644
--- a/arch/arm/boot/dts/msm8974-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8974-mdss.dtsi
@@ -50,7 +50,13 @@
 				     <0x0160 0x22222222>,
 				     <0x0164 0x00002222>;
 		qcom,mdp-settings = <0x02E0 0x000000AA>,
-				    <0x02E4 0x00000055>;
+				    <0x02E4 0x00000055>,
+				    <0x03AC 0xC0000CCC>,
+				    <0x03B4 0xC0000CCC>,
+				    <0x03BC 0x00CCCCCC>,
+				    <0x04A8 0x0CCCC0C0>,
+				    <0x04B0 0xCCCCC0C0>,
+				    <0x04B8 0xCCCCC000>;
 
 		mdss_fb0: qcom,mdss_fb_primary {
 			cell-index = <0>;
diff --git a/arch/arm/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index 8fa1d75..0090dfd 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.dtsi
@@ -11,7 +11,7 @@
  */
 
 /include/ "dsi-panel-toshiba-720p-video.dtsi"
-/include/ "msm8974-camera-sensor-cdp-mtp.dtsi"
+/include/ "msm8974-camera-sensor-mtp.dtsi"
 /include/ "msm8974-leds.dtsi"
 
 / {
diff --git a/arch/arm/boot/dts/msm8974-rumi.dtsi b/arch/arm/boot/dts/msm8974-rumi.dtsi
index ce9d6c9..c569e58 100644
--- a/arch/arm/boot/dts/msm8974-rumi.dtsi
+++ b/arch/arm/boot/dts/msm8974-rumi.dtsi
@@ -11,7 +11,7 @@
  */
 
 /include/ "msm8974-leds.dtsi"
-/include/ "msm8974-camera-sensor-cdp-mtp.dtsi"
+/include/ "msm8974-camera-sensor-cdp.dtsi"
 
 / {
 	timer {
diff --git a/arch/arm/boot/dts/msm8974-sim.dtsi b/arch/arm/boot/dts/msm8974-sim.dtsi
index a5606b8..786c50c 100644
--- a/arch/arm/boot/dts/msm8974-sim.dtsi
+++ b/arch/arm/boot/dts/msm8974-sim.dtsi
@@ -12,7 +12,7 @@
 
 /include/ "dsi-panel-sim-video.dtsi"
 /include/ "msm8974-leds.dtsi"
-/include/ "msm8974-camera-sensor-cdp-mtp.dtsi"
+/include/ "msm8974-camera-sensor-cdp.dtsi"
 
 / {
 	qcom,mdss_dsi@fd922800 {
diff --git a/arch/arm/boot/dts/msm8974-v2-cdp.dts b/arch/arm/boot/dts/msm8974-v2-cdp.dts
index e591dee..d90abb5 100644
--- a/arch/arm/boot/dts/msm8974-v2-cdp.dts
+++ b/arch/arm/boot/dts/msm8974-v2-cdp.dts
@@ -22,16 +22,13 @@
 };
 
 &usb3 {
-	#address-cells = <0>;
 	interrupt-parent = <&usb3>;
-	interrupts = <0 1 2 3>;
+	interrupts = <0 1>;
 	#interrupt-cells = <1>;
-	interrupt-map-mask = <0xffffffff>;
-	interrupt-map = <0 &intc 0 131 0
-			1 &intc 0 179 0
-			2 &intc 0 133 0
-			3 &spmi_bus 0x0 0x0 0x9 0x0>;
-	interrupt-names = "irq", "otg_irq", "hs_phy_irq", "pmic_id_irq";
+	interrupt-map-mask = <0x0 0xffffffff>;
+	interrupt-map = <0x0 0 &intc 0 133 0
+			 0x0 1 &spmi_bus 0x0 0x0 0x9 0x0>;
+	interrupt-names = "hs_phy_irq", "pmic_id_irq";
 
 	qcom,misc-ref = <&pm8941_misc>;
 };
diff --git a/arch/arm/boot/dts/msm8974-v2-fluid.dts b/arch/arm/boot/dts/msm8974-v2-fluid.dts
index 4efad9e..0a09db1 100644
--- a/arch/arm/boot/dts/msm8974-v2-fluid.dts
+++ b/arch/arm/boot/dts/msm8974-v2-fluid.dts
@@ -22,16 +22,13 @@
 };
 
 &usb3 {
-	#address-cells = <0>;
 	interrupt-parent = <&usb3>;
-	interrupts = <0 1 2 3>;
+	interrupts = <0 1>;
 	#interrupt-cells = <1>;
-	interrupt-map-mask = <0xffffffff>;
-	interrupt-map = <0 &intc 0 131 0
-			1 &intc 0 179 0
-			2 &intc 0 133 0
-			3 &spmi_bus 0x0 0x0 0x9 0x0>;
-	interrupt-names = "irq", "otg_irq", "hs_phy_irq", "pmic_id_irq";
+	interrupt-map-mask = <0x0 0xffffffff>;
+	interrupt-map = <0x0 0 &intc 0 133 0
+			 0x0 1 &spmi_bus 0x0 0x0 0x9 0x0>;
+	interrupt-names = "hs_phy_irq", "pmic_id_irq";
 
 	qcom,misc-ref = <&pm8941_misc>;
 };
diff --git a/arch/arm/boot/dts/msm8974-v2-liquid.dts b/arch/arm/boot/dts/msm8974-v2-liquid.dts
index 86584f8..bbd5071 100644
--- a/arch/arm/boot/dts/msm8974-v2-liquid.dts
+++ b/arch/arm/boot/dts/msm8974-v2-liquid.dts
@@ -22,16 +22,13 @@
 };
 
 &usb3 {
-	#address-cells = <0>;
 	interrupt-parent = <&usb3>;
-	interrupts = <0 1 2 3>;
+	interrupts = <0 1>;
 	#interrupt-cells = <1>;
-	interrupt-map-mask = <0xffffffff>;
-	interrupt-map = <0 &intc 0 131 0
-			1 &intc 0 179 0
-			2 &intc 0 133 0
-			3 &spmi_bus 0x0 0x0 0x9 0x0>;
-	interrupt-names = "irq", "otg_irq", "hs_phy_irq", "pmic_id_irq";
+	interrupt-map-mask = <0x0 0xffffffff>;
+	interrupt-map = <0x0 0 &intc 0 133 0
+			 0x0 1 &spmi_bus 0x0 0x0 0x9 0x0>;
+	interrupt-names = "hs_phy_irq", "pmic_id_irq";
 
 	qcom,misc-ref = <&pm8941_misc>;
 };
diff --git a/arch/arm/boot/dts/msm8974-v2-mtp.dts b/arch/arm/boot/dts/msm8974-v2-mtp.dts
index a2e2ffa..e74651e 100644
--- a/arch/arm/boot/dts/msm8974-v2-mtp.dts
+++ b/arch/arm/boot/dts/msm8974-v2-mtp.dts
@@ -22,16 +22,13 @@
 };
 
 &usb3 {
-	#address-cells = <0>;
 	interrupt-parent = <&usb3>;
-	interrupts = <0 1 2 3>;
+	interrupts = <0 1>;
 	#interrupt-cells = <1>;
-	interrupt-map-mask = <0xffffffff>;
-	interrupt-map = <0 &intc 0 131 0
-			1 &intc 0 179 0
-			2 &intc 0 133 0
-			3 &spmi_bus 0x0 0x0 0x9 0x0>;
-	interrupt-names = "irq", "otg_irq", "hs_phy_irq", "pmic_id_irq";
+	interrupt-map-mask = <0x0 0xffffffff>;
+	interrupt-map = <0x0 0 &intc 0 133 0
+			 0x0 1 &spmi_bus 0x0 0x0 0x9 0x0>;
+	interrupt-names = "hs_phy_irq", "pmic_id_irq";
 
 	qcom,misc-ref = <&pm8941_misc>;
 };
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index f25e0f5..22c5d05 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -593,6 +593,7 @@
 			qcom,cdc-mclk-clk-rate = <9600000>;
 			qcom,cdc-slim-ifd = "taiko-slim-ifd";
 			qcom,cdc-slim-ifd-elemental-addr = [00 00 A0 00 17 02];
+			qcom,cdc-dmic-sample-rate = <4800000>;
 		};
 	};
 
@@ -712,8 +713,11 @@
 		compatible = "qcom,dwc-usb3-msm";
 		reg = <0xf9200000 0xfc000>,
 			  <0xfd4ab000 0x4>;
-		interrupts = <0 131 0>, <0 179 0>, <0 133 0>;
-		interrupt-names = "irq", "otg_irq", "hs_phy_irq";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		interrupts = <0 133 0>;
+		interrupt-names = "hs_phy_irq";
 		ssusb_vdd_dig-supply = <&pm8841_s2_corner>;
 		SSUSB_1p8-supply = <&pm8941_l6>;
 		hsusb_vdd_dig-supply = <&pm8841_s2_corner>;
@@ -731,6 +735,14 @@
 		qcom,msm-bus,vectors-KBps =
 				<61 512 0 0>,
 				<61 512 240000 960000>;
+		dwc3@f9200000 {
+			compatible = "synopsys,dwc3";
+			reg = <0xf9200000 0xfc000>;
+			interrupt-parent = <&intc>;
+			interrupts = <0 131 0>, <0 179 0>;
+			interrupt-names = "irq", "otg_irq";
+			tx-fifo-resize;
+		};
 	};
 
 	ehci: qcom,ehci-host@f9a55000 {
diff --git a/arch/arm/boot/dts/msm9625-smp2p.dtsi b/arch/arm/boot/dts/msm9625-smp2p.dtsi
index 02c95e4..46af1b2 100644
--- a/arch/arm/boot/dts/msm9625-smp2p.dtsi
+++ b/arch/arm/boot/dts/msm9625-smp2p.dtsi
@@ -26,7 +26,6 @@
 		interrupts = <0 158 1>;
 	};
 
-	/* SMP2P Test Driver for inbound entries */
 	smp2pgpio_smp2p_7_in: qcom,smp2pgpio-smp2p-7-in {
 		compatible = "qcom,smp2pgpio";
 		qcom,entry-name = "smp2p";
@@ -43,7 +42,6 @@
 		gpios = <&smp2pgpio_smp2p_7_in 0 0>;
 	};
 
-	/* SMP2P Test Driver for outbound entries */
 	smp2pgpio_smp2p_7_out: qcom,smp2pgpio-smp2p-7-out {
 		compatible = "qcom,smp2pgpio";
 		qcom,entry-name = "smp2p";
@@ -59,7 +57,6 @@
 		gpios = <&smp2pgpio_smp2p_7_out 0 0>;
 	};
 
-	/* SMP2P Test Driver for modem inbound */
 	smp2pgpio_smp2p_1_in: qcom,smp2pgpio-smp2p-1-in {
 		compatible = "qcom,smp2pgpio";
 		qcom,entry-name = "smp2p";
@@ -76,7 +73,6 @@
 		gpios = <&smp2pgpio_smp2p_1_in 0 0>;
 	};
 
-	/* SMP2P Test Driver for modem output */
 	smp2pgpio_smp2p_1_out: qcom,smp2pgpio-smp2p-1-out {
 		compatible = "qcom,smp2pgpio";
 		qcom,entry-name = "smp2p";
@@ -92,7 +88,6 @@
 		gpios = <&smp2pgpio_smp2p_1_out 0 0>;
 	};
 
-	/* SMP2P SSR Driver for inbound entry from modem. */
 	smp2pgpio_ssr_smp2p_1_in: qcom,smp2pgpio-ssr-smp2p-1-in {
 		compatible = "qcom,smp2pgpio";
 		qcom,entry-name = "slave-kernel";
@@ -104,7 +99,6 @@
 		#interrupt-cells = <2>;
 	};
 
-	/* SMP2P SSR Driver for outbound entry to modem */
 	smp2pgpio_ssr_smp2p_1_out: qcom,smp2pgpio-ssr-smp2p-1-out {
 		compatible = "qcom,smp2pgpio";
 		qcom,entry-name = "master-kernel";
@@ -115,7 +109,6 @@
 		#interrupt-cells = <2>;
 	};
 
-	/* SMP2P Test Driver for adsp inbound */
 	smp2pgpio_smp2p_2_in: qcom,smp2pgpio-smp2p-2-in {
 		compatible = "qcom,smp2pgpio";
 		qcom,entry-name = "smp2p";
@@ -132,7 +125,6 @@
 		gpios = <&smp2pgpio_smp2p_2_in 0 0>;
 	};
 
-	/* SMP2P Test Driver for adsp output */
 	smp2pgpio_smp2p_2_out: qcom,smp2pgpio-smp2p-2-out {
 		compatible = "qcom,smp2pgpio";
 		qcom,entry-name = "smp2p";
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index 590692c..ac6be75 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -344,8 +344,20 @@
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_SCHEDSTATS=y
 CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_KMEMLEAK=y
+CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_LIST=y
+CONFIG_FAULT_INJECTION=y
+CONFIG_FAIL_PAGE_ALLOC=y
+CONFIG_FAULT_INJECTION_DEBUG_FS=y
+CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
+CONFIG_DEBUG_PAGEALLOC=y
 CONFIG_ENABLE_DEFAULT_TRACERS=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
@@ -355,3 +367,4 @@
 CONFIG_CRYPTO_TWOFISH=y
 # CONFIG_CRYPTO_HW is not set
 CONFIG_CRC_CCITT=y
+CONFIG_QPNP_VIBRATOR=y
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index c33a236..efca45a 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -330,6 +330,7 @@
 CONFIG_MSM_CSI30_HEADER=y
 CONFIG_MSM_CSIPHY=y
 CONFIG_MSM_CSID=y
+CONFIG_MSM_EEPROM=y
 CONFIG_MSM_ISPIF=y
 CONFIG_S5K3L1YX=y
 CONFIG_MSMB_CAMERA=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 1cda524..a226fe4 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -336,6 +336,7 @@
 CONFIG_MSM_CSI30_HEADER=y
 CONFIG_MSM_CSIPHY=y
 CONFIG_MSM_CSID=y
+CONFIG_MSM_EEPROM=y
 CONFIG_MSM_ISPIF=y
 CONFIG_S5K3L1YX=y
 CONFIG_MSMB_CAMERA=y
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index cef66ec..c440f47 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -742,6 +742,7 @@
 static struct of_device_id armpmu_of_device_ids[] = {
 	{.compatible = "arm,cortex-a9-pmu"},
 	{.compatible = "arm,cortex-a8-pmu"},
+	{.compatible = "arm,cortex-a5-pmu"},
 	{.compatible = "arm,arm1136-pmu"},
 	{.compatible = "arm,arm1176-pmu"},
 	{.compatible = "qcom,krait-pmu"},
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index cd5d55b..e8853b9 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -426,6 +426,7 @@
 	select REGULATOR
 	select MSM_RPM_REGULATOR_SMD
 	select MSM_SPM_REGULATOR
+	select MSM_JTAG_MM if CORESIGHT_ETM
 	select MSM_CPR_REGULATOR
 
 config ARCH_MSM8226
@@ -1078,7 +1079,7 @@
 config KERNEL_MSM_CONTIG_MEM_REGION
 	bool "Enable in-kernel contiguous memory region"
 	default y if ARCH_MSM8X60
-	depends on ANDROID_PMEM && (ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_MSM8974)
+	depends on ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_MSM8974
 	help
 	   Enable the in-kernel contiguous memory allocator. Sets up a
 	   region of physically contiguous memory. This memory is
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index d07b094..dc8b675 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -24,6 +24,7 @@
 endif
 
 obj-y += acpuclock.o
+obj-$(CONFIG_HW_PERF_EVENTS) += perf_trace_counters.o
 obj-$(CONFIG_ARCH_MSM_KRAIT) += acpuclock-krait.o
 ifdef CONFIG_ARCH_MSM_KRAIT
 obj-$(CONFIG_DEBUG_FS) += acpuclock-krait-debug.o
diff --git a/arch/arm/mach-msm/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
index 83c14a8..370be84 100644
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ b/arch/arm/mach-msm/acpuclock-8974.c
@@ -259,16 +259,16 @@
 
 static struct l2_level l2_freq_tbl_v2[] __initdata = {
 	[0]  = { {  300000, PLL_0, 0,   0 }, LVL_LOW,   950000, 0 },
-	[1]  = { {  345600, HFPLL, 2,  36 }, LVL_NOM,   950000, 1 },
-	[2]  = { {  422400, HFPLL, 2,  44 }, LVL_NOM,   950000, 1 },
-	[3]  = { {  499200, HFPLL, 2,  52 }, LVL_NOM,   950000, 2 },
-	[4]  = { {  576000, HFPLL, 1,  30 }, LVL_NOM,   950000, 3 },
+	[1]  = { {  345600, HFPLL, 2,  36 }, LVL_LOW,   950000, 1 },
+	[2]  = { {  422400, HFPLL, 2,  44 }, LVL_LOW,   950000, 1 },
+	[3]  = { {  499200, HFPLL, 2,  52 }, LVL_LOW,   950000, 2 },
+	[4]  = { {  576000, HFPLL, 1,  30 }, LVL_LOW,   950000, 3 },
 	[5]  = { {  652800, HFPLL, 1,  34 }, LVL_NOM,   950000, 3 },
 	[6]  = { {  729600, HFPLL, 1,  38 }, LVL_NOM,   950000, 3 },
-	[7]  = { {  806400, HFPLL, 1,  42 }, LVL_HIGH, 1050000, 4 },
-	[8]  = { {  883200, HFPLL, 1,  46 }, LVL_HIGH, 1050000, 4 },
-	[9]  = { {  960000, HFPLL, 1,  50 }, LVL_HIGH, 1050000, 4 },
-	[10] = { { 1036800, HFPLL, 1,  54 }, LVL_HIGH, 1050000, 5 },
+	[7]  = { {  806400, HFPLL, 1,  42 }, LVL_NOM,   950000, 4 },
+	[8]  = { {  883200, HFPLL, 1,  46 }, LVL_NOM,   950000, 4 },
+	[9]  = { {  960000, HFPLL, 1,  50 }, LVL_NOM,   950000, 4 },
+	[10] = { { 1036800, HFPLL, 1,  54 }, LVL_NOM,   950000, 5 },
 	[11] = { { 1113600, HFPLL, 1,  58 }, LVL_HIGH, 1050000, 5 },
 	[12] = { { 1190400, HFPLL, 1,  62 }, LVL_HIGH, 1050000, 6 },
 	[13] = { { 1267200, HFPLL, 1,  66 }, LVL_HIGH, 1050000, 6 },
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index 413927c..4079b5a 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -2736,16 +2736,20 @@
 
 enum vdd_sr2_pll_levels {
 	VDD_SR2_PLL_OFF,
-	VDD_SR2_PLL_ON,
+	VDD_SR2_PLL_SVS,
+	VDD_SR2_PLL_NOM,
+	VDD_SR2_PLL_TUR,
 	VDD_SR2_PLL_NUM
 };
 
 static const int *vdd_sr2_levels[] = {
-	[VDD_SR2_PLL_OFF] = VDD_UV(0),
-	[VDD_SR2_PLL_ON]  = VDD_UV(1800000),
+	[VDD_SR2_PLL_OFF] = VDD_UV(0,       RPM_REGULATOR_CORNER_NONE),
+	[VDD_SR2_PLL_SVS] = VDD_UV(1800000, RPM_REGULATOR_CORNER_SVS_SOC),
+	[VDD_SR2_PLL_NOM] = VDD_UV(1800000, RPM_REGULATOR_CORNER_NORMAL),
+	[VDD_SR2_PLL_TUR] = VDD_UV(1800000, RPM_REGULATOR_CORNER_SUPER_TURBO),
 };
 
-static DEFINE_VDD_REGULATORS(vdd_sr2_pll, VDD_SR2_PLL_NUM, 1, vdd_sr2_levels);
+static DEFINE_VDD_REGULATORS(vdd_sr2_pll, VDD_SR2_PLL_NUM, 2, vdd_sr2_levels);
 
 static struct pll_freq_tbl apcs_pll_freq[] = {
 	F_APCS_PLL( 384000000, 20, 0x0, 0x1, 0x0, 0x0, 0x0),
@@ -2776,7 +2780,8 @@
 		.ops = &clk_ops_sr2_pll,
 		.vdd_class = &vdd_sr2_pll,
 		.fmax = (unsigned long [VDD_SR2_PLL_NUM]) {
-			[VDD_SR2_PLL_ON] = ULONG_MAX,
+			[VDD_SR2_PLL_SVS] = 1000000000,
+			[VDD_SR2_PLL_NOM] = 1900000000,
 		},
 		.num_fmax = VDD_SR2_PLL_NUM,
 		CLK_INIT(a7sspll.c),
@@ -3514,12 +3519,17 @@
 	if (IS_ERR(vdd_sr2_pll.regulator[0]))
 		panic("clock-8226: Unable to get the sr2_pll regulator!");
 
+	vdd_sr2_pll.regulator[1] = regulator_get(NULL, "vdd_sr2_dig");
+	if (IS_ERR(vdd_sr2_pll.regulator[1]))
+		panic("clock-8226: Unable to get the vdd_sr2_dig regulator!");
+
 	/*
 	 * These regulators are used at boot. Ensure they stay on
 	 * while the clock framework comes online.
 	 */
-	regulator_set_voltage(vdd_sr2_pll.regulator[0], 1800000, 1800000);
+	vote_vdd_level(&vdd_sr2_pll, VDD_SR2_PLL_TUR);
 	regulator_enable(vdd_sr2_pll.regulator[0]);
+	regulator_enable(vdd_sr2_pll.regulator[1]);
 
 	vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
 	regulator_enable(vdd_dig.regulator[0]);
@@ -3548,7 +3558,9 @@
 
 static int __init msm8226_clock_late_init(void)
 {
-	return unvote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
+	unvote_vdd_level(&vdd_sr2_pll, VDD_SR2_PLL_TUR);
+	unvote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
+	return 0;
 }
 
 struct clock_init_data msm8226_clock_init_data __initdata = {
diff --git a/arch/arm/mach-msm/clock-8610.c b/arch/arm/mach-msm/clock-8610.c
index b7c46b4..d63d722 100644
--- a/arch/arm/mach-msm/clock-8610.c
+++ b/arch/arm/mach-msm/clock-8610.c
@@ -524,17 +524,20 @@
 
 enum vdd_sr2_pll_levels {
 	VDD_SR2_PLL_OFF,
-	VDD_SR2_PLL_ON,
+	VDD_SR2_PLL_SVS,
+	VDD_SR2_PLL_NOM,
+	VDD_SR2_PLL_TUR,
 	VDD_SR2_PLL_NUM
 };
 
-static const int *vdd_sr2_pll_levels[] = {
-	[VDD_SR2_PLL_OFF] = VDD_UV(0),
-	[VDD_SR2_PLL_ON]  = VDD_UV(1800000),
+static const int *vdd_sr2_levels[] = {
+	[VDD_SR2_PLL_OFF] = VDD_UV(0,       RPM_REGULATOR_CORNER_NONE),
+	[VDD_SR2_PLL_SVS] = VDD_UV(1800000, RPM_REGULATOR_CORNER_SVS_SOC),
+	[VDD_SR2_PLL_NOM] = VDD_UV(1800000, RPM_REGULATOR_CORNER_NORMAL),
+	[VDD_SR2_PLL_TUR] = VDD_UV(1800000, RPM_REGULATOR_CORNER_SUPER_TURBO),
 };
 
-static DEFINE_VDD_REGULATORS(vdd_sr2_pll, VDD_SR2_PLL_NUM, 1,
-		vdd_sr2_pll_levels);
+static DEFINE_VDD_REGULATORS(vdd_sr2_pll, VDD_SR2_PLL_NUM, 2, vdd_sr2_levels);
 
 static struct pll_freq_tbl apcs_pll_freq[] = {
 	F_APCS_PLL( 384000000, 20, 0x0, 0x1, 0x0, 0x0, 0x0),
@@ -565,7 +568,8 @@
 		.ops = &clk_ops_sr2_pll,
 		.vdd_class = &vdd_sr2_pll,
 		.fmax = (unsigned long [VDD_SR2_PLL_NUM]) {
-			[VDD_SR2_PLL_ON] = ULONG_MAX,
+			[VDD_SR2_PLL_SVS] = 1000000000,
+			[VDD_SR2_PLL_NOM] = 1900000000,
 		},
 		.num_fmax = VDD_SR2_PLL_NUM,
 		CLK_INIT(a7sspll.c),
@@ -2948,8 +2952,13 @@
 	if (IS_ERR(vdd_sr2_pll.regulator[0]))
 		panic("clock-8610: Unable to get the vdd_sr2_pll regulator!");
 
-	regulator_set_voltage(vdd_sr2_pll.regulator[0], 1800000, 1800000);
+	vdd_sr2_pll.regulator[1] = regulator_get(NULL, "vdd_sr2_dig");
+	if (IS_ERR(vdd_sr2_pll.regulator[1]))
+		panic("clock-8610: Unable to get the vdd_sr2_dig regulator!");
+
+	vote_vdd_level(&vdd_sr2_pll, VDD_SR2_PLL_TUR);
 	regulator_enable(vdd_sr2_pll.regulator[0]);
+	regulator_enable(vdd_sr2_pll.regulator[1]);
 
 	/*
 	 * TODO: Set a voltage and enable vdd_dig, leaving the voltage high
@@ -2978,7 +2987,9 @@
 
 static int __init msm8610_clock_late_init(void)
 {
-	return unvote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
+	unvote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
+	unvote_vdd_level(&vdd_sr2_pll, VDD_SR2_PLL_TUR);
+	return 0;
 }
 
 struct clock_init_data msm8610_clock_init_data __initdata = {
diff --git a/arch/arm/mach-msm/clock-9625.c b/arch/arm/mach-msm/clock-9625.c
index d8e4ed5..6817c6c 100644
--- a/arch/arm/mach-msm/clock-9625.c
+++ b/arch/arm/mach-msm/clock-9625.c
@@ -147,6 +147,7 @@
 #define USB_HSIC_SYSTEM_CBCR                     0x040C
 #define USB_HSIC_CBCR                            0x0410
 #define USB_HSIC_IO_CAL_CBCR                     0x0414
+#define USB_HSIC_IO_CAL_SLEEP_CBCR		 0x0418
 #define USB_HSIC_XCVR_FS_CBCR                    0x042C
 #define USB_HS_SYSTEM_CBCR                       0x0484
 #define USB_HS_AHB_CBCR                          0x0488
@@ -187,6 +188,7 @@
 #define PDM2_CBCR                                0x0CCC
 #define PRNG_AHB_CBCR                            0x0D04
 #define BAM_DMA_AHB_CBCR                         0x0D44
+#define BAM_DMA_INACTIVITY_TIMERS_CBCR		 0x0D48
 #define MSG_RAM_AHB_CBCR                         0x0E44
 #define CE1_CBCR                                 0x1044
 #define CE1_AXI_CBCR                             0x1048
@@ -1002,6 +1004,18 @@
 	},
 };
 
+static struct local_vote_clk gcc_bam_dma_inactivity_timers_clk = {
+	.cbcr_reg = BAM_DMA_INACTIVITY_TIMERS_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(11),
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_bam_dma_inactivity_timers_clk",
+		.ops = &clk_ops_vote,
+		CLK_INIT(gcc_bam_dma_inactivity_timers_clk.c),
+	},
+};
+
 static struct local_vote_clk gcc_blsp1_ahb_clk = {
 	.cbcr_reg = BLSP1_AHB_CBCR,
 	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
@@ -1517,6 +1531,17 @@
 	},
 };
 
+static struct branch_clk gcc_usb_hsic_io_cal_sleep_clk = {
+	.cbcr_reg = USB_HSIC_IO_CAL_SLEEP_CBCR,
+	.has_sibling = 1,
+	.base = &virt_bases[GCC_BASE],
+	.c = {
+		.dbg_name = "gcc_usb_hsic_io_cal_sleep_clk",
+		.ops = &clk_ops_branch,
+		CLK_INIT(gcc_usb_hsic_io_cal_sleep_clk.c),
+	},
+};
+
 static struct branch_clk gcc_usb_hsic_system_clk = {
 	.cbcr_reg = USB_HSIC_SYSTEM_CBCR,
 	.bcr_reg = USB_HS_HSIC_BCR,
@@ -1554,6 +1579,7 @@
 
 struct measure_mux_entry measure_mux_common[] __initdata = {
 	{&gcc_pdm_ahb_clk.c,			GCC_BASE, 0x00d0},
+	{&gcc_usb_hsic_io_cal_sleep_clk.c,	GCC_BASE, 0x005c},
 	{&gcc_usb_hsic_xcvr_fs_clk.c,		GCC_BASE, 0x005d},
 	{&gcc_usb_hsic_system_clk.c,		GCC_BASE, 0x0059},
 	{&gcc_usb_hsic_io_cal_clk.c,		GCC_BASE, 0x005b},
@@ -1583,6 +1609,7 @@
 	{&gcc_sdcc2_apps_clk.c,			GCC_BASE, 0x0070},
 	{&gcc_blsp1_uart1_apps_clk.c,		GCC_BASE, 0x008c},
 	{&gcc_blsp1_qup4_i2c_apps_clk.c,	GCC_BASE, 0x0099},
+	{&gcc_bam_dma_inactivity_timers_clk.c,	GCC_BASE, 0x00E1},
 	{&gcc_boot_rom_ahb_clk.c,		GCC_BASE, 0x00f8},
 	{&gcc_ce1_ahb_clk.c,			GCC_BASE, 0x013a},
 	{&gcc_pdm2_clk.c,			GCC_BASE, 0x00d2},
@@ -1786,6 +1813,8 @@
 	CLK_LOOKUP("pll14", apcspll_clk_src.c, "f9010008.qcom,acpuclk"),
 
 	CLK_LOOKUP("dma_bam_pclk", gcc_bam_dma_ahb_clk.c, "msm_sps"),
+	CLK_LOOKUP("inactivity_clk", gcc_bam_dma_inactivity_timers_clk.c,
+								"msm_sps"),
 	CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "msm_serial_hsl.0"),
 	CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f9924000.spi"),
 	CLK_LOOKUP("iface_clk", gcc_blsp1_ahb_clk.c, "f9925000.i2c"),
@@ -1842,6 +1871,8 @@
 	CLK_LOOKUP("cal_clk", gcc_usb_hsic_io_cal_clk.c,  "msm_hsic_host"),
 	CLK_LOOKUP("core_clk", gcc_usb_hsic_system_clk.c, "msm_hsic_host"),
 	CLK_LOOKUP("alt_core_clk", gcc_usb_hsic_xcvr_fs_clk.c, ""),
+	CLK_LOOKUP("inactivity_clk", gcc_usb_hsic_io_cal_sleep_clk.c,
+							"msm_hsic_host"),
 
 	CLK_LOOKUP("core_clk", gcc_ce1_clk.c, "fd400000.qcom,qcedev"),
 	CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, "fd400000.qcom,qcedev"),
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 656c3f4..2f44566 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -2652,8 +2652,8 @@
 		[MSM_RPM_LOG_PAGE_BUFFER]  = 0x000000A0,
 	},
 	.phys_size = SZ_8K,
-	.log_len = 4096,		  /* log's buffer length in bytes */
-	.log_len_mask = (4096 >> 2) - 1,  /* length mask in units of u32 */
+	.log_len = 6144,		  /* log's buffer length in bytes */
+	.log_len_mask = (6144 >> 2) - 1,  /* length mask in units of u32 */
 };
 
 struct platform_device apq8064_rpm_log_device = {
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index 2f8f547..e2a57f9 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -550,14 +550,14 @@
 };
 
 static struct msm_rpm_log_platform_data msm_rpm_log_pdata = {
-	.phys_addr_base = 0x0010C000,
+	.phys_addr_base = 0x10B6A0,
 	.reg_offsets = {
 		[MSM_RPM_LOG_PAGE_INDICES] = 0x00000080,
 		[MSM_RPM_LOG_PAGE_BUFFER]  = 0x000000A0,
 	},
 	.phys_size = SZ_8K,
-	.log_len = 4096,		  /* log's buffer length in bytes */
-	.log_len_mask = (4096 >> 2) - 1,  /* length mask in units of u32 */
+	.log_len = 8192,		  /* log's buffer length in bytes */
+	.log_len_mask = (8192 >> 2) - 1,  /* length mask in units of u32 */
 };
 
 struct platform_device msm8930_rpm_log_device = {
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index e70a0a8..837aef3 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -3961,8 +3961,8 @@
 		[MSM_RPM_LOG_PAGE_BUFFER]  = 0x000000A0,
 	},
 	.phys_size = SZ_8K,
-	.log_len = 4096,		  /* log's buffer length in bytes */
-	.log_len_mask = (4096 >> 2) - 1,  /* length mask in units of u32 */
+	.log_len = 6144,		  /* log's buffer length in bytes */
+	.log_len_mask = (6144 >> 2) - 1,  /* length mask in units of u32 */
 };
 
 struct platform_device msm8960_rpm_log_device = {
diff --git a/arch/arm/mach-msm/include/mach/camera2.h b/arch/arm/mach-msm/include/mach/camera2.h
index b518e56..248c9b0 100644
--- a/arch/arm/mach-msm/include/mach/camera2.h
+++ b/arch/arm/mach-msm/include/mach/camera2.h
@@ -20,6 +20,7 @@
 enum msm_camera_device_type_t {
 	MSM_CAMERA_I2C_DEVICE,
 	MSM_CAMERA_PLATFORM_DEVICE,
+	MSM_CAMERA_SPI_DEVICE,
 };
 
 enum msm_bus_perf_setting {
@@ -100,4 +101,39 @@
 	enum msm_camera_i2c_data_type data_type;
 };
 
+struct eeprom_map_t {
+	uint32_t valid_size;
+	uint32_t addr;
+	uint32_t addr_t;
+	uint32_t data;
+	uint32_t data_t;
+	uint32_t delay;
+};
+
+struct eeprom_memory_map_t {
+	struct eeprom_map_t page;
+	struct eeprom_map_t poll;
+	struct eeprom_map_t mem;
+};
+
+struct msm_camera_power_ctrl_t {
+	struct device *dev;
+	struct msm_sensor_power_setting *power_setting;
+	uint16_t power_setting_size;
+	struct msm_camera_gpio_conf *gpio_conf;
+	struct camera_vreg_t *cam_vreg;
+	int num_vreg;
+	struct msm_camera_i2c_conf *i2c_conf;
+	struct msm_cam_clk_info *clk_info;
+	uint16_t clk_info_size;
+};
+
+struct msm_eeprom_board_info {
+	const char *eeprom_name;
+	uint16_t i2c_slaveaddr;
+	uint32_t num_blocks;
+	struct eeprom_memory_map_t *eeprom_map;
+	struct msm_camera_power_ctrl_t power_info;
+};
+
 #endif
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
index c5c4988..f750dc8 100644
--- a/arch/arm/mach-msm/include/mach/iommu.h
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -123,6 +123,24 @@
 	unsigned int ctx_attach_count;
 };
 
+/**
+ * struct iommu_access_ops - Callbacks for accessing IOMMU
+ * @iommu_power_on:     Turn on power to unit
+ * @iommu_power_off:    Turn off power to unit
+ * @iommu_clk_on:       Turn on clks to unit
+ * @iommu_clk_off:      Turn off clks to unit
+ * @iommu_lock_acquire: Acquire any locks needed
+ * @iommu_lock_release: Release locks needed
+ */
+struct iommu_access_ops {
+	int (*iommu_power_on)(struct msm_iommu_drvdata *);
+	void (*iommu_power_off)(struct msm_iommu_drvdata *);
+	int (*iommu_clk_on)(struct msm_iommu_drvdata *);
+	void (*iommu_clk_off)(struct msm_iommu_drvdata *);
+	void (*iommu_lock_acquire)(void);
+	void (*iommu_lock_release)(void);
+};
+
 void msm_iommu_add_drv(struct msm_iommu_drvdata *drv);
 void msm_iommu_remove_drv(struct msm_iommu_drvdata *drv);
 void program_iommu_bfb_settings(void __iomem *base,
@@ -241,6 +259,7 @@
  * This should only be called on IOMMUs for which kernel programming
  * of global registers is not possible
  */
+void msm_iommu_sec_set_access_ops(struct iommu_access_ops *access_ops);
 int msm_iommu_sec_program_iommu(int sec_id);
 
 static inline int msm_soc_version_supports_iommu_v0(void)
diff --git a/arch/arm/mach-msm/include/mach/iommu_domains.h b/arch/arm/mach-msm/include/mach/iommu_domains.h
index fec734a..9a89508 100644
--- a/arch/arm/mach-msm/include/mach/iommu_domains.h
+++ b/arch/arm/mach-msm/include/mach/iommu_domains.h
@@ -13,6 +13,7 @@
 #ifndef _ARCH_IOMMU_DOMAINS_H
 #define _ARCH_IOMMU_DOMAINS_H
 
+#include <linux/errno.h>
 #include <linux/memory_alloc.h>
 
 #define MSM_IOMMU_DOMAIN_SECURE	0x1
diff --git a/arch/arm/mach-msm/include/mach/iommu_perfmon.h b/arch/arm/mach-msm/include/mach/iommu_perfmon.h
index c03c752..dcae83b 100644
--- a/arch/arm/mach-msm/include/mach/iommu_perfmon.h
+++ b/arch/arm/mach-msm/include/mach/iommu_perfmon.h
@@ -18,20 +18,6 @@
 #define MSM_IOMMU_PERFMON_H
 
 /**
- * struct iommu_access_ops - Callbacks for accessing IOMMU
- * @iommu_power_on:     Turn on clocks/power to unit
- * @iommu_power_off:    Turn off clocks/power to unit
- * @iommu_lock_acquire: Acquire any locks needed
- * @iommu_lock_release: Release locks needed
- */
-struct iommu_access_ops {
-	int (*iommu_power_on)(void *);
-	int (*iommu_power_off)(void *);
-	void (*iommu_lock_acquire)(void);
-	void (*iommu_lock_release)(void);
-};
-
-/**
  * struct iommu_pmon_counter - container for a performance counter.
  * @counter_no:          counter number within the group
  * @absolute_counter_no: counter number within IOMMU PMU
diff --git a/arch/arm/mach-msm/include/mach/rpm-regulator-smd.h b/arch/arm/mach-msm/include/mach/rpm-regulator-smd.h
index 9e70510..cfe8ae7 100644
--- a/arch/arm/mach-msm/include/mach/rpm-regulator-smd.h
+++ b/arch/arm/mach-msm/include/mach/rpm-regulator-smd.h
@@ -38,6 +38,32 @@
 	RPM_REGULATOR_CORNER_SUPER_TURBO,
 };
 
+/**
+ * enum rpm_regulator_mode - control mode for LDO or SMPS type regulators
+ * %RPM_REGULATOR_MODE_AUTO:	For SMPS type regulators, use SMPS auto mode so
+ *				that the hardware can automatically switch
+ *				between PFM and PWM modes based on realtime
+ *				load.
+ *				LDO type regulators do not support this mode.
+ * %RPM_REGULATOR_MODE_IPEAK:	For SMPS type regulators, use aggregated
+ *				software current requests to determine
+ *				usage of PFM or PWM mode.
+ *				For LDO type regulators, use aggregated
+ *				software current requests to determine
+ *				usage of LPM or HPM mode.
+ * %RPM_REGULATOR_MODE_HPM:	For SMPS type regulators, force the
+ *				usage of PWM mode.
+ *				For LDO type regulators, force the
+ *				usage of HPM mode.
+ *
+ * These values should be used in calls to rpm_regulator_set_mode().
+ */
+enum rpm_regulator_mode {
+	RPM_REGULATOR_MODE_AUTO,
+	RPM_REGULATOR_MODE_IPEAK,
+	RPM_REGULATOR_MODE_HPM,
+};
+
 #if defined(CONFIG_MSM_RPM_REGULATOR_SMD) || defined(CONFIG_MSM_RPM_REGULATOR)
 
 struct rpm_regulator *rpm_regulator_get(struct device *dev, const char *supply);
@@ -71,6 +97,14 @@
 
 static inline int __init rpm_regulator_smd_driver_init(void) { return 0; }
 
-#endif /* CONFIG_MSM_RPM_REGULATOR_SMD */
+#endif /* CONFIG_MSM_RPM_REGULATOR_SMD || CONFIG_MSM_RPM_REGULATOR */
+
+#ifdef CONFIG_MSM_RPM_REGULATOR_SMD
+int rpm_regulator_set_mode(struct rpm_regulator *regulator,
+				enum rpm_regulator_mode mode);
+#else
+static inline int rpm_regulator_set_mode(struct rpm_regulator *regulator,
+				enum rpm_regulator_mode mode) { return 0; }
+#endif
 
 #endif
diff --git a/arch/arm/mach-msm/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
index a837ca1..18562a3 100644
--- a/arch/arm/mach-msm/iommu_domains.c
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -27,7 +27,6 @@
 #include <mach/iommu_domains.h>
 #include <mach/msm_iommu_priv.h>
 #include <mach/socinfo.h>
-#include <mach/msm_subsystem_map.h>
 
 struct msm_iova_data {
 	struct rb_node node;
diff --git a/arch/arm/mach-msm/perf_debug.c b/arch/arm/mach-msm/perf_debug.c
index 7f2f528..5bf88a2 100644
--- a/arch/arm/mach-msm/perf_debug.c
+++ b/arch/arm/mach-msm/perf_debug.c
@@ -28,6 +28,8 @@
 	"3  Perf: Correct irq for CPU hotplug detection\n"
 	"4  Perf: Check perf activity on correct CPU\n"
 	"5  Perf: Add DT support for L1 and L2 PMU\n"
+	"6  Perf: Add cortex A5 device tree support\n"
+	"7  Perf: Add L1 counters to tracepoints\n"
 ;
 
 static ssize_t desc_read(struct file *fp, char __user *buf,
diff --git a/arch/arm/mach-msm/perf_trace_counters.c b/arch/arm/mach-msm/perf_trace_counters.c
new file mode 100644
index 0000000..d961994
--- /dev/null
+++ b/arch/arm/mach-msm/perf_trace_counters.c
@@ -0,0 +1,42 @@
+/* Copyright (c) 2013, 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 <asm/thread_notify.h>
+#define CREATE_TRACE_POINTS
+#include "perf_trace_counters.h"
+
+static int tracectr_notifier(struct notifier_block *self, unsigned long cmd,
+		void *v)
+{
+	static int old_pid = -1;
+	struct thread_info *thread = v;
+	int current_pid;
+
+	if (cmd != THREAD_NOTIFY_SWITCH)
+		return old_pid;
+
+	current_pid = thread->task->pid;
+	if (old_pid != -1)
+		trace_sched_switch_with_ctrs(old_pid, current_pid);
+	old_pid = current_pid;
+	return old_pid;
+}
+
+static struct notifier_block tracectr_notifier_block = {
+	.notifier_call  = tracectr_notifier,
+};
+
+int __init init_tracecounters(void)
+{
+	thread_register_notifier(&tracectr_notifier_block);
+	return 0;
+}
+late_initcall(init_tracecounters);
diff --git a/arch/arm/mach-msm/perf_trace_counters.h b/arch/arm/mach-msm/perf_trace_counters.h
new file mode 100644
index 0000000..ce7e336
--- /dev/null
+++ b/arch/arm/mach-msm/perf_trace_counters.h
@@ -0,0 +1,127 @@
+/* Copyright (c) 2013, 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.
+ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM perf_trace_counters
+
+#if !defined(_PERF_TRACE_COUNTERS_H_) || defined(TRACE_HEADER_MULTI_READ)
+#define _PERF_TRACE_COUNTERS_H_
+
+/* Ctr index for PMCNTENSET/CLR */
+#define CC 0x80000000
+#define C0 0x1
+#define C1 0x10
+#define C2 0x100
+#define C3 0x1000
+
+
+#include <linux/sched.h>
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(sched_switch_with_ctrs,
+
+		TP_PROTO(pid_t prev, pid_t next),
+
+		TP_ARGS(prev, next),
+
+		TP_STRUCT__entry(
+			__field(pid_t,	old_pid)
+			__field(pid_t,	new_pid)
+			__field(u32, cctr)
+			__field(u32, ctr0)
+			__field(u32, ctr1)
+			__field(u32, ctr2)
+			__field(u32, ctr3)
+		),
+
+		TP_fast_assign(
+			__entry->old_pid	= prev;
+			__entry->new_pid	= next;
+
+			/* cycle counter */
+			/* Disable */
+			asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r"(CC));
+			/* Read value */
+			asm volatile("mrc p15, 0, %0, c9, c13, 0"
+				: "=r"(__entry->cctr));
+			/* Reset */
+			asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r"(0));
+			/* Enable */
+			asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r"(CC));
+
+			/* ctr 0 */
+			/* Disable */
+			asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r"(C0));
+			/* Select */
+			asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r"(0));
+			/* Read value */
+			asm volatile("mrc p15, 0, %0, c9, c13, 2"
+					: "=r"(__entry->ctr0));
+			/* Reset */
+			asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r"(0));
+			/* Enable */
+			asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r"(C0));
+
+			/* ctr 1 */
+			/* Disable */
+			asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r"(C1));
+			/* Select */
+			asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r"(1));
+			/* Read value */
+			asm volatile("mrc p15, 0, %0, c9, c13, 2"
+					: "=r"(__entry->ctr1));
+			/* Reset */
+			asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r"(0));
+			/* Enable */
+			asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r"(C1));
+
+			/* ctr 2 */
+			/* Disable */
+			asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r"(C2));
+			/* Select */
+			asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r"(2));
+			/* Read value */
+			asm volatile("mrc p15, 0, %0, c9, c13, 2"
+					: "=r"(__entry->ctr2));
+			/* Reset */
+			asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r"(0));
+			/* Enable */
+			asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r"(C2));
+
+			/* ctr 3 */
+			/* Disable */
+			asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r"(C3));
+			/* Select */
+			asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r"(3));
+			/* Read value */
+			asm volatile("mrc p15, 0, %0, c9, c13, 2"
+					: "=r"(__entry->ctr3));
+			/* Reset */
+			asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r"(0));
+			/* Enable */
+			asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r"(C3));
+
+		),
+
+		TP_printk("prev_pid=%d, next_pid=%d, CCNTR: %u, CTR0: %u," \
+				" CTR1: %u, CTR2: %u, CTR3: %u",
+				__entry->old_pid, __entry->new_pid,
+				__entry->cctr, __entry->ctr0, __entry->ctr1,
+				__entry->ctr2, __entry->ctr3)
+);
+
+#endif
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE perf_trace_counters
+#include <trace/define_trace.h>
+
diff --git a/arch/arm/mach-msm/peripheral-loader.c b/arch/arm/mach-msm/peripheral-loader.c
index 958edaf..4e8674c 100644
--- a/arch/arm/mach-msm/peripheral-loader.c
+++ b/arch/arm/mach-msm/peripheral-loader.c
@@ -29,6 +29,7 @@
 #include <linux/list.h>
 #include <linux/list_sort.h>
 #include <linux/idr.h>
+#include <linux/interrupt.h>
 
 #include <asm/uaccess.h>
 #include <asm/setup.h>
@@ -226,10 +227,21 @@
 
 		if (immediate)
 			timeout = 0;
-		schedule_delayed_work(&priv->proxy, msecs_to_jiffies(timeout));
+
+		if (!desc->proxy_unvote_irq || immediate)
+			schedule_delayed_work(&priv->proxy,
+					      msecs_to_jiffies(timeout));
 	}
 }
 
+static irqreturn_t proxy_unvote_intr_handler(int irq, void *dev_id)
+{
+	struct pil_desc *desc = dev_id;
+
+	schedule_delayed_work(&desc->priv->proxy, 0);
+	return IRQ_HANDLED;
+}
+
 static bool segment_is_relocatable(const struct elf32_phdr *p)
 {
 	return !!(p->p_flags & BIT(27));
@@ -685,13 +697,16 @@
 int pil_desc_init(struct pil_desc *desc)
 {
 	struct pil_priv *priv;
-	int id;
+	int ret;
 	void __iomem *addr;
 	char buf[sizeof(priv->info->name)];
 
 	/* Ignore users who don't make any sense */
-	WARN(desc->ops->proxy_unvote && !desc->proxy_timeout,
-			"A proxy timeout of 0 was specified.\n");
+	WARN(desc->ops->proxy_unvote && desc->proxy_unvote_irq == 0
+		 && !desc->proxy_timeout,
+		 "Invalid proxy unvote callback or a proxy timeout of 0"
+		 " was specified or no proxy unvote IRQ was specified.\n");
+
 	if (WARN(desc->ops->proxy_unvote && !desc->ops->proxy_vote,
 				"Invalid proxy voting. Ignoring\n"))
 		((struct pil_reset_ops *)desc->ops)->proxy_unvote = NULL;
@@ -702,23 +717,38 @@
 	desc->priv = priv;
 	priv->desc = desc;
 
-	priv->id = id = ida_simple_get(&pil_ida, 0, 10, GFP_KERNEL);
-	if (id < 0) {
-		kfree(priv);
-		return id;
-	}
-	addr = PIL_IMAGE_INFO_BASE + sizeof(struct pil_image_info) * id;
+	priv->id = ret = ida_simple_get(&pil_ida, 0, 10, GFP_KERNEL);
+	if (priv->id < 0)
+		goto err;
+
+	addr = PIL_IMAGE_INFO_BASE + sizeof(struct pil_image_info) * priv->id;
 	priv->info = (struct pil_image_info __iomem *)addr;
 
 	strncpy(buf, desc->name, sizeof(buf));
 	__iowrite32_copy(priv->info->name, buf, sizeof(buf) / 4);
 
+	if (desc->proxy_unvote_irq > 0) {
+		ret = request_irq(desc->proxy_unvote_irq,
+				  proxy_unvote_intr_handler,
+				  IRQF_TRIGGER_RISING|IRQF_SHARED,
+				  desc->name, desc);
+		if (ret < 0) {
+			dev_err(desc->dev,
+				"Unable to request proxy unvote IRQ: %d\n",
+				ret);
+			goto err;
+		}
+	}
+
 	snprintf(priv->wname, sizeof(priv->wname), "pil-%s", desc->name);
 	wake_lock_init(&priv->wlock, WAKE_LOCK_SUSPEND, priv->wname);
 	INIT_DELAYED_WORK(&priv->proxy, pil_proxy_work);
 	INIT_LIST_HEAD(&priv->segs);
 
 	return 0;
+err:
+	kfree(priv);
+	return ret;
 }
 EXPORT_SYMBOL(pil_desc_init);
 
diff --git a/arch/arm/mach-msm/peripheral-loader.h b/arch/arm/mach-msm/peripheral-loader.h
index c1a4167..ff10fe5 100644
--- a/arch/arm/mach-msm/peripheral-loader.h
+++ b/arch/arm/mach-msm/peripheral-loader.h
@@ -25,6 +25,8 @@
  * @proxy_timeout: delay in ms until proxy vote is removed
  * @flags: bitfield for image flags
  * @priv: DON'T USE - internal only
+ * @proxy_unvote_irq: IRQ to trigger a proxy unvote. proxy_timeout
+ * is ignored if this is set.
  */
 struct pil_desc {
 	const char *name;
@@ -35,6 +37,7 @@
 	unsigned long flags;
 #define PIL_SKIP_ENTRY_CHECK	BIT(0)
 	struct pil_priv *priv;
+	unsigned int proxy_unvote_irq;
 };
 
 /**
diff --git a/arch/arm/mach-msm/rpm-regulator-smd.c b/arch/arm/mach-msm/rpm-regulator-smd.c
index 55ce4b1..923e647 100644
--- a/arch/arm/mach-msm/rpm-regulator-smd.c
+++ b/arch/arm/mach-msm/rpm-regulator-smd.c
@@ -73,6 +73,17 @@
 	RPM_REGULATOR_PARAM_MAX,
 };
 
+enum rpm_regulator_smps_mode {
+	RPM_REGULATOR_SMPS_MODE_AUTO	= 0,
+	RPM_REGULATOR_SMPS_MODE_IPEAK	= 1,
+	RPM_REGULATOR_SMPS_MODE_PWM	= 2,
+};
+
+enum rpm_regulator_ldo_mode {
+	RPM_REGULATOR_LDO_MODE_IPEAK	= 0,
+	RPM_REGULATOR_LDO_MODE_HPM	= 1,
+};
+
 #define RPM_SET_CONFIG_ACTIVE			BIT(0)
 #define RPM_SET_CONFIG_SLEEP			BIT(1)
 #define RPM_SET_CONFIG_BOTH			(RPM_SET_CONFIG_ACTIVE \
@@ -118,6 +129,20 @@
 	PARAM(FLOOR_CORNER,    1,  1,  0,  0, "vfc",  0, 6,          "qcom,init-voltage-floor-corner"),
 };
 
+struct rpm_regulator_mode_map {
+	int			ldo_mode;
+	int			smps_mode;
+};
+
+static struct rpm_regulator_mode_map mode_mapping[] = {
+	[RPM_REGULATOR_MODE_AUTO]
+		= {-1,				 RPM_REGULATOR_SMPS_MODE_AUTO},
+	[RPM_REGULATOR_MODE_IPEAK]
+		= {RPM_REGULATOR_LDO_MODE_IPEAK, RPM_REGULATOR_SMPS_MODE_IPEAK},
+	[RPM_REGULATOR_MODE_HPM]
+		= {RPM_REGULATOR_LDO_MODE_HPM,   RPM_REGULATOR_SMPS_MODE_PWM},
+};
+
 struct rpm_vreg_request {
 	u32			param[RPM_REGULATOR_PARAM_MAX];
 	u32			valid;
@@ -1077,6 +1102,71 @@
 }
 EXPORT_SYMBOL_GPL(rpm_regulator_set_voltage);
 
+/**
+ * rpm_regulator_set_mode() - set regulator operating mode
+ * @regulator: RPM regulator handle
+ * @mode: operating mode requested for the regulator
+ *
+ * Requests that the mode of the regulator be set to the mode specified.  This
+ * parameter is aggregated using a max function such that AUTO < IPEAK < HPM.
+ *
+ * Returns 0 on success or errno on failure.
+ */
+int rpm_regulator_set_mode(struct rpm_regulator *regulator,
+				enum rpm_regulator_mode mode)
+{
+	int index = 0;
+	u32 new_mode, prev_mode;
+	int rc;
+
+	rc = rpm_regulator_check_input(regulator);
+	if (rc)
+		return rc;
+
+	if (mode < 0 || mode >= ARRAY_SIZE(mode_mapping)) {
+		vreg_err(regulator, "invalid mode requested: %d\n", mode);
+		return -EINVAL;
+	}
+
+	switch (regulator->rpm_vreg->regulator_type) {
+	case RPM_REGULATOR_SMD_TYPE_SMPS:
+		index = RPM_REGULATOR_PARAM_MODE_SMPS;
+		new_mode = mode_mapping[mode].smps_mode;
+		break;
+	case RPM_REGULATOR_SMD_TYPE_LDO:
+		index = RPM_REGULATOR_PARAM_MODE_LDO;
+		new_mode = mode_mapping[mode].ldo_mode;
+		break;
+	default:
+		vreg_err(regulator, "unsupported regulator type: %d\n",
+			regulator->rpm_vreg->regulator_type);
+		return -EINVAL;
+	};
+
+	if (new_mode < params[index].min || new_mode > params[index].max) {
+		vreg_err(regulator, "invalid mode requested: %d for type: %d\n",
+			mode, regulator->rpm_vreg->regulator_type);
+		return -EINVAL;
+	}
+
+	rpm_vreg_lock(regulator->rpm_vreg);
+
+	prev_mode = regulator->req.param[index];
+	regulator->req.param[index] = new_mode;
+	regulator->req.modified |= BIT(index);
+
+	rc = rpm_vreg_aggregate_requests(regulator);
+	if (rc) {
+		vreg_err(regulator, "set mode failed, rc=%d", rc);
+		regulator->req.param[index] = prev_mode;
+	}
+
+	rpm_vreg_unlock(regulator->rpm_vreg);
+
+	return rc;
+}
+EXPORT_SYMBOL_GPL(rpm_regulator_set_mode);
+
 static struct regulator_ops ldo_ops = {
 	.enable			= rpm_vreg_enable,
 	.disable		= rpm_vreg_disable,
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 3144113..06a4c29 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -292,8 +292,6 @@
 
 	clock = clockevent_to_clock(evt);
 	clock_state = &__get_cpu_var(msm_clocks_percpu)[clock->index];
-	if (clock_state->stopped)
-		return 0;
 	now = msm_read_timer_count(clock, LOCAL_TIMER);
 	alarm = now + (cycles << clock->shift);
 	if (clock->flags & MSM_CLOCK_FLAGS_ODD_MATCH_WRITE)
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index b0fb9d8..e946b42 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -32,7 +32,6 @@
 #include <mach/msm_bus.h>
 #include <mach/msm_bus_board.h>
 #endif
-#include <mach/msm_subsystem_map.h>
 #include <mach/iommu_domains.h>
 
 #define DRIVER_NAME "msm_rotator"
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index 16c2900..ce25bfd 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -1281,6 +1281,7 @@
 	for_each_sg(table->sgl, sg, table->nents, i) {
 		dma_addr_t addr = buffer_base + i * chunk_size;
 		sg_dma_address(sg) = addr;
+		sg_dma_len(sg) = chunk_size;
 	}
 
 	return table;
diff --git a/drivers/gpu/ion/ion_cp_heap.c b/drivers/gpu/ion/ion_cp_heap.c
index 2ef285b..7bcae01 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -26,7 +26,6 @@
 #include <linux/vmalloc.h>
 #include <linux/memory_alloc.h>
 #include <linux/seq_file.h>
-#include <linux/fmem.h>
 #include <linux/iommu.h>
 #include <linux/dma-mapping.h>
 #include <trace/events/kmem.h>
@@ -70,8 +69,6 @@
  *		user space.
  * @iommu_iova: saved iova when mapping full heap at once.
  * @iommu_partition: partition used to map full heap.
- * @reusable: indicates if the memory should be reused via fmem.
- * @reserved_vrange: reserved virtual address range for use with fmem
  * @iommu_map_all:	Indicates whether we should map whole heap into IOMMU.
  * @iommu_2x_map_domain: Indicates the domain to use for overmapping.
  * @has_outer_cache:    set to 1 if outer cache is used, 0 otherwise.
@@ -95,7 +92,6 @@
 	unsigned long umap_count;
 	unsigned long iommu_iova[MAX_DOMAINS];
 	unsigned long iommu_partition[MAX_DOMAINS];
-	int reusable;
 	void *reserved_vrange;
 	int iommu_map_all;
 	int iommu_2x_map_domain;
@@ -198,12 +194,6 @@
 		container_of(heap, struct ion_cp_heap, heap);
 	int ret_value;
 
-	if (cp_heap->reusable) {
-		ret_value = fmem_set_state(FMEM_C_STATE);
-		if (ret_value)
-			return 1;
-	}
-
 	if (cp_heap->cma) {
 		ret_value = allocate_heap_memory(heap);
 		if (ret_value)
@@ -217,11 +207,6 @@
 	struct ion_cp_heap *cp_heap =
 		container_of(heap, struct ion_cp_heap, heap);
 
-	if (cp_heap->reusable)
-		if (fmem_set_state(FMEM_T_STATE) != 0)
-			pr_err("%s: unable to transition heap to T-state\n",
-				__func__);
-
 	if (cp_heap->cma)
 		free_heap_memory(heap);
 }
@@ -549,29 +534,6 @@
 	return ret_value;
 }
 
-void *ion_map_fmem_buffer(struct ion_buffer *buffer, unsigned long phys_base,
-				void *virt_base, unsigned long flags)
-{
-	int ret;
-	struct ion_cp_buffer *buf = buffer->priv_virt;
-	unsigned int offset = buf->buffer - phys_base;
-	unsigned long start = ((unsigned long)virt_base) + offset;
-	const struct mem_type *type = ION_IS_CACHED(flags) ?
-				get_mem_type(MT_DEVICE_CACHED) :
-				get_mem_type(MT_DEVICE);
-
-	if (phys_base > buf->buffer)
-		return NULL;
-
-
-	ret = ioremap_pages(start, buf->buffer, buffer->size, type);
-
-	if (!ret)
-		return (void *)start;
-	else
-		return NULL;
-}
-
 void *ion_cp_heap_map_kernel(struct ion_heap *heap, struct ion_buffer *buffer)
 {
 	struct ion_cp_heap *cp_heap =
@@ -589,10 +551,7 @@
 			return NULL;
 		}
 
-		if (cp_heap->reusable) {
-			ret_value = ion_map_fmem_buffer(buffer, cp_heap->base,
-				cp_heap->reserved_vrange, buffer->flags);
-		} else if (cp_heap->cma) {
+		if (cp_heap->cma) {
 			int npages = PAGE_ALIGN(buffer->size) / PAGE_SIZE;
 			struct page **pages = vmalloc(
 						sizeof(struct page *) * npages);
@@ -645,9 +604,7 @@
 		container_of(heap, struct ion_cp_heap, heap);
 	struct ion_cp_buffer *buf = buffer->priv_virt;
 
-	if (cp_heap->reusable)
-		unmap_kernel_range((unsigned long)buffer->vaddr, buffer->size);
-	else if (cp_heap->cma)
+	if (cp_heap->cma)
 		vunmap(buffer->vaddr);
 	else
 		__arm_iounmap(buffer->vaddr);
@@ -826,7 +783,6 @@
 	seq_printf(s, "umapping count: %lx\n", umap_count);
 	seq_printf(s, "kmapping count: %lx\n", kmap_count);
 	seq_printf(s, "heap protected: %s\n", heap_protected ? "Yes" : "No");
-	seq_printf(s, "reusable: %s\n", cp_heap->reusable  ? "Yes" : "No");
 
 	if (mem_map) {
 		unsigned long base = cp_heap->base;
@@ -1151,8 +1107,6 @@
 	if (heap_data->extra_data) {
 		struct ion_cp_heap_pdata *extra_data =
 				heap_data->extra_data;
-		cp_heap->reusable = extra_data->reusable;
-		cp_heap->reserved_vrange = extra_data->virt_addr;
 		cp_heap->permission_type = extra_data->permission_type;
 		if (extra_data->secure_size) {
 			cp_heap->secure_base = extra_data->secure_base;
diff --git a/drivers/gpu/ion/ion_iommu_heap.c b/drivers/gpu/ion/ion_iommu_heap.c
index 9ab6b85..512ebf3 100644
--- a/drivers/gpu/ion/ion_iommu_heap.c
+++ b/drivers/gpu/ion/ion_iommu_heap.c
@@ -76,10 +76,14 @@
 		if (max_order < orders[i])
 			continue;
 
-		gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_COMP;
-		if (orders[i])
-			gfp |= __GFP_NOWARN;
+		gfp = __GFP_HIGHMEM;
 
+		if (orders[i]) {
+			gfp |= __GFP_COMP | __GFP_NORETRY |
+			       __GFP_NO_KSWAPD | __GFP_NOWARN;
+		} else {
+			gfp |= GFP_KERNEL;
+		}
 		page = alloc_pages(gfp, orders[i]);
 		if (!page)
 			continue;
diff --git a/drivers/gpu/ion/msm/ion_cp_common.c b/drivers/gpu/ion/msm/ion_cp_common.c
index 48c2efb..7d54cfa 100644
--- a/drivers/gpu/ion/msm/ion_cp_common.c
+++ b/drivers/gpu/ion/msm/ion_cp_common.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2011 Google, Inc
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -20,6 +20,7 @@
 #include "ion_cp_common.h"
 
 #define MEM_PROTECT_LOCK_ID	0x05
+#define MEM_PROTECT_LOCK_ID2 0x0A
 
 struct cp2_mem_chunks {
 	unsigned int *chunk_list;
@@ -27,10 +28,11 @@
 	unsigned int chunk_size;
 } __attribute__ ((__packed__));
 
-struct cp2_lock_req {
+struct cp2_lock2_req {
 	struct cp2_mem_chunks chunks;
 	unsigned int mem_usage;
 	unsigned int lock;
+	unsigned int flags;
 } __attribute__ ((__packed__));
 
 /*  SCM related code for locking down memory for content protection */
@@ -144,17 +146,18 @@
 				enum cp_mem_usage usage,
 				int lock)
 {
-	struct cp2_lock_req request;
+	struct cp2_lock2_req request;
 	u32 resp;
 
 	request.mem_usage = usage;
 	request.lock = lock;
+	request.flags = 0;
 
 	request.chunks.chunk_list = (unsigned int *)chunks;
 	request.chunks.chunk_list_size = nchunks;
 	request.chunks.chunk_size = chunk_size;
 
-	return scm_call(SCM_SVC_MP, MEM_PROTECT_LOCK_ID,
+	return scm_call(SCM_SVC_MP, MEM_PROTECT_LOCK_ID2,
 			&request, sizeof(request), &resp, sizeof(resp));
 
 }
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 6f7e61d..2377397 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1603,6 +1603,8 @@
 	int status = -EINVAL;
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 
+	kgsl_cffdump_open(device);
+
 	if (KGSL_STATE_DUMP_AND_FT != device->state)
 		kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
 
@@ -1686,6 +1688,8 @@
 	/* Power down the device */
 	kgsl_pwrctrl_disable(device);
 
+	kgsl_cffdump_close(device->id);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/msm/adreno_a2xx.c b/drivers/gpu/msm/adreno_a2xx.c
index 335d407..3f31e36 100644
--- a/drivers/gpu/msm/adreno_a2xx.c
+++ b/drivers/gpu/msm/adreno_a2xx.c
@@ -1515,18 +1515,26 @@
 			"Current active context has caused gpu hang\n");
 
 	if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
-
+		kgsl_cffdump_syncmem(NULL, &context->gpustate,
+			context->reg_save[1],
+			context->reg_save[2] << 2, true);
 		/* save registers and constants. */
 		adreno_ringbuffer_issuecmds(device, context,
 			KGSL_CMD_FLAGS_NONE,
 			context->reg_save, 3);
 
 		if (context->flags & CTXT_FLAGS_SHADER_SAVE) {
+			kgsl_cffdump_syncmem(NULL, &context->gpustate,
+				context->shader_save[1],
+				context->shader_save[2] << 2, true);
 			/* save shader partitioning and instructions. */
 			adreno_ringbuffer_issuecmds(device, context,
 				KGSL_CMD_FLAGS_PMODE,
 				context->shader_save, 3);
 
+			kgsl_cffdump_syncmem(NULL, &context->gpustate,
+				context->shader_fixup[1],
+				context->shader_fixup[2] << 2, true);
 			/*
 			 * fixup shader partitioning parameter for
 			 *  SET_SHADER_BASES.
@@ -1541,6 +1549,9 @@
 
 	if ((context->flags & CTXT_FLAGS_GMEM_SAVE) &&
 	    (context->flags & CTXT_FLAGS_GMEM_SHADOW)) {
+		kgsl_cffdump_syncmem(NULL, &context->gpustate,
+			context->context_gmem_shadow.gmem_save[1],
+			context->context_gmem_shadow.gmem_save[2] << 2, true);
 		/* save gmem.
 		 * (note: changes shader. shader must already be saved.)
 		 */
@@ -1548,6 +1559,10 @@
 			KGSL_CMD_FLAGS_PMODE,
 			context->context_gmem_shadow.gmem_save, 3);
 
+		kgsl_cffdump_syncmem(NULL, &context->gpustate,
+			context->chicken_restore[1],
+			context->chicken_restore[2] << 2, true);
+
 		/* Restore TP0_CHICKEN */
 		if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
 			adreno_ringbuffer_issuecmds(device, context,
@@ -1584,21 +1599,24 @@
 					cmds, 5);
 	kgsl_mmu_setstate(&device->mmu, context->pagetable, context->id);
 
-#ifndef CONFIG_MSM_KGSL_CFF_DUMP_NO_CONTEXT_MEM_DUMP
-	kgsl_cffdump_syncmem(NULL, &context->gpustate,
-		context->gpustate.gpuaddr, LCC_SHADOW_SIZE +
-		REG_SHADOW_SIZE + CMD_BUFFER_SIZE + TEX_SHADOW_SIZE, false);
-#endif
-
 	/* restore gmem.
 	 *  (note: changes shader. shader must not already be restored.)
 	 */
 	if (context->flags & CTXT_FLAGS_GMEM_RESTORE) {
+		kgsl_cffdump_syncmem(NULL, &context->gpustate,
+			context->context_gmem_shadow.gmem_restore[1],
+			context->context_gmem_shadow.gmem_restore[2] << 2,
+			true);
+
 		adreno_ringbuffer_issuecmds(device, context,
 			KGSL_CMD_FLAGS_PMODE,
 			context->context_gmem_shadow.gmem_restore, 3);
 
 		if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
+			kgsl_cffdump_syncmem(NULL, &context->gpustate,
+				context->chicken_restore[1],
+				context->chicken_restore[2] << 2, true);
+
 			/* Restore TP0_CHICKEN */
 			adreno_ringbuffer_issuecmds(device, context,
 				KGSL_CMD_FLAGS_NONE,
@@ -1609,6 +1627,9 @@
 	}
 
 	if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
+		kgsl_cffdump_syncmem(NULL, &context->gpustate,
+			context->reg_restore[1],
+			context->reg_restore[2] << 2, true);
 
 		/* restore registers and constants. */
 		adreno_ringbuffer_issuecmds(device, context,
@@ -1616,6 +1637,10 @@
 
 		/* restore shader instructions & partitioning. */
 		if (context->flags & CTXT_FLAGS_SHADER_RESTORE) {
+			kgsl_cffdump_syncmem(NULL, &context->gpustate,
+				context->shader_restore[1],
+				context->shader_restore[2] << 2, true);
+
 			adreno_ringbuffer_issuecmds(device, context,
 				KGSL_CMD_FLAGS_NONE,
 				context->shader_restore, 3);
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 19d9ca2..13c723a 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -2419,6 +2419,11 @@
 		 * already be saved.)
 		 */
 
+		kgsl_cffdump_syncmem(NULL,
+			&context->gpustate,
+			context->context_gmem_shadow.gmem_save[1],
+			context->context_gmem_shadow.gmem_save[2] << 2, true);
+
 		adreno_ringbuffer_issuecmds(device, context,
 					KGSL_CMD_FLAGS_PMODE,
 					    context->context_gmem_shadow.
@@ -2456,6 +2461,12 @@
 	 */
 
 	if (context->flags & CTXT_FLAGS_GMEM_RESTORE) {
+		kgsl_cffdump_syncmem(NULL,
+			&context->gpustate,
+			context->context_gmem_shadow.gmem_restore[1],
+			context->context_gmem_shadow.gmem_restore[2] << 2,
+			true);
+
 		adreno_ringbuffer_issuecmds(device, context,
 					KGSL_CMD_FLAGS_PMODE,
 					    context->context_gmem_shadow.
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index 023b057..176717d 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/msm_kgsl.h>
 
 #include "kgsl.h"
 #include "kgsl_sharedmem.h"
@@ -143,7 +144,7 @@
  */
 int adreno_drawctxt_create(struct kgsl_device *device,
 			struct kgsl_pagetable *pagetable,
-			struct kgsl_context *context, uint32_t flags)
+			struct kgsl_context *context, uint32_t *flags)
 {
 	struct adreno_context *drawctxt;
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
@@ -162,26 +163,36 @@
 	drawctxt->id = context->id;
 	rb->timestamp[context->id] = 0;
 
-	if (flags & KGSL_CONTEXT_PREAMBLE)
+	*flags &= (KGSL_CONTEXT_PREAMBLE |
+		KGSL_CONTEXT_NO_GMEM_ALLOC |
+		KGSL_CONTEXT_PER_CONTEXT_TS |
+		KGSL_CONTEXT_USER_GENERATED_TS |
+		KGSL_CONTEXT_NO_FAULT_TOLERANCE |
+		KGSL_CONTEXT_TYPE_MASK);
+
+	if (*flags & KGSL_CONTEXT_PREAMBLE)
 		drawctxt->flags |= CTXT_FLAGS_PREAMBLE;
 
-	if (flags & KGSL_CONTEXT_NO_GMEM_ALLOC)
+	if (*flags & KGSL_CONTEXT_NO_GMEM_ALLOC)
 		drawctxt->flags |= CTXT_FLAGS_NOGMEMALLOC;
 
-	if (flags & KGSL_CONTEXT_PER_CONTEXT_TS)
+	if (*flags & KGSL_CONTEXT_PER_CONTEXT_TS)
 		drawctxt->flags |= CTXT_FLAGS_PER_CONTEXT_TS;
 
-	if (flags & KGSL_CONTEXT_USER_GENERATED_TS) {
-		if (!(flags & KGSL_CONTEXT_PER_CONTEXT_TS)) {
+	if (*flags & KGSL_CONTEXT_USER_GENERATED_TS) {
+		if (!(*flags & KGSL_CONTEXT_PER_CONTEXT_TS)) {
 			ret = -EINVAL;
 			goto err;
 		}
 		drawctxt->flags |= CTXT_FLAGS_USER_GENERATED_TS;
 	}
 
-	if (flags & KGSL_CONTEXT_NO_FAULT_TOLERANCE)
+	if (*flags & KGSL_CONTEXT_NO_FAULT_TOLERANCE)
 		drawctxt->flags |= CTXT_FLAGS_NO_FAULT_TOLERANCE;
 
+	drawctxt->type =
+		(*flags & KGSL_CONTEXT_TYPE_MASK) >> KGSL_CONTEXT_TYPE_SHIFT;
+
 	ret = adreno_dev->gpudev->ctxt_create(adreno_dev, drawctxt);
 	if (ret)
 		goto err;
diff --git a/drivers/gpu/msm/adreno_drawctxt.h b/drivers/gpu/msm/adreno_drawctxt.h
index aba29ae..f0f3b6b 100644
--- a/drivers/gpu/msm/adreno_drawctxt.h
+++ b/drivers/gpu/msm/adreno_drawctxt.h
@@ -57,6 +57,14 @@
 /* Context no fault tolerance */
 #define CTXT_FLAGS_NO_FAULT_TOLERANCE  BIT(16)
 
+/* Symbolic table for the adreno draw context type */
+#define ADRENO_DRAWCTXT_TYPES \
+	{ KGSL_CONTEXT_TYPE_ANY, "any" }, \
+	{ KGSL_CONTEXT_TYPE_GL, "GL" }, \
+	{ KGSL_CONTEXT_TYPE_CL, "CL" }, \
+	{ KGSL_CONTEXT_TYPE_C2D, "C2D" }, \
+	{ KGSL_CONTEXT_TYPE_RS, "RS" }
+
 struct kgsl_device;
 struct adreno_device;
 struct kgsl_device_private;
@@ -95,6 +103,7 @@
 	uint32_t flags;
 	uint32_t pagefault;
 	unsigned long pagefault_ts;
+	unsigned int type;
 	struct kgsl_pagetable *pagetable;
 	struct kgsl_memdesc gpustate;
 	unsigned int reg_restore[3];
@@ -127,7 +136,7 @@
 int adreno_drawctxt_create(struct kgsl_device *device,
 			struct kgsl_pagetable *pagetable,
 			struct kgsl_context *context,
-			uint32_t flags);
+			uint32_t *flags);
 
 void adreno_drawctxt_destroy(struct kgsl_device *device,
 			  struct kgsl_context *context);
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index 8c23a13..a4bb4fa 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -18,6 +18,7 @@
 #include "kgsl.h"
 #include "kgsl_sharedmem.h"
 #include "kgsl_cffdump.h"
+#include "kgsl_trace.h"
 
 #include "adreno.h"
 #include "adreno_pm4types.h"
@@ -592,6 +593,9 @@
 	if (adreno_is_a20x(adreno_dev))
 		total_sizedwords += 2; /* CACHE_FLUSH */
 
+	if (flags & KGSL_CMD_FLAGS_EOF)
+		total_sizedwords += 2;
+
 	ringcmds = adreno_ringbuffer_allocspace(rb, context, total_sizedwords);
 	if (!ringcmds) {
 		/*
@@ -986,26 +990,31 @@
 {
 	struct kgsl_device *device = dev_priv->device;
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
-	unsigned int *link;
+	unsigned int *link = 0;
 	unsigned int *cmds;
 	unsigned int i;
-	struct adreno_context *drawctxt;
+	struct adreno_context *drawctxt = NULL;
 	unsigned int start_index = 0;
 	int ret;
 
-	if (device->state & KGSL_STATE_HUNG)
-		return -EBUSY;
-	if (!(adreno_dev->ringbuffer.flags & KGSL_FLAGS_STARTED) ||
-	      context == NULL || ibdesc == 0 || numibs == 0)
-		return -EINVAL;
+	if (device->state & KGSL_STATE_HUNG) {
+		ret = -EBUSY;
+		goto done;
+	}
 
+	if (!(adreno_dev->ringbuffer.flags & KGSL_FLAGS_STARTED) ||
+	      context == NULL || ibdesc == 0 || numibs == 0) {
+		ret = -EINVAL;
+		goto done;
+	}
 	drawctxt = context->devctxt;
 
 	if (drawctxt->flags & CTXT_FLAGS_GPU_HANG) {
 		KGSL_CTXT_ERR(device, "proc %s failed fault tolerance"
 			" will not accept commands for context %d\n",
 			drawctxt->pid_name, drawctxt->id);
-		return -EDEADLK;
+		ret = -EDEADLK;
+		goto done;
 	}
 
 	/*When preamble is enabled, the preamble buffer with state restoration
@@ -1032,9 +1041,8 @@
 	cmds = link = kzalloc(sizeof(unsigned int) * (numibs * 3 + 4),
 				GFP_KERNEL);
 	if (!link) {
-		KGSL_CORE_ERR("kzalloc(%d) failed\n",
-			sizeof(unsigned int) * (numibs * 3 + 4));
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto done;
 	}
 
 	if (!start_index) {
@@ -1099,6 +1107,9 @@
 		ret = 0;
 
 done:
+	trace_kgsl_issueibcmds(device, context->id, ibdesc, numibs,
+		*timestamp, flags, ret, drawctxt->type);
+
 	kfree(link);
 	return ret;
 }
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index af25a3f..53ef392 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1214,8 +1214,6 @@
 					     &param->timestamp,
 					     param->flags);
 
-	trace_kgsl_issueibcmds(dev_priv->device, param, ibdesc, result);
-
 free_ibdesc:
 	kfree(ibdesc);
 done:
@@ -1341,7 +1339,7 @@
 	if (dev_priv->device->ftbl->drawctxt_create) {
 		result = dev_priv->device->ftbl->drawctxt_create(
 			dev_priv->device, dev_priv->process_priv->pagetable,
-			context, param->flags);
+			context, &param->flags);
 		if (result)
 			goto done;
 	}
@@ -2976,7 +2974,6 @@
 	if (result)
 		goto error_pwrctrl_close;
 
-	kgsl_cffdump_open(device->id);
 
 	setup_timer(&device->idle_timer, kgsl_timer, (unsigned long) device);
 	status = kgsl_create_device_workqueue(device);
@@ -3105,7 +3102,6 @@
 {
 	kgsl_device_snapshot_close(device);
 
-	kgsl_cffdump_close(device->id);
 	kgsl_pwrctrl_uninit_sysfs(device);
 
 	pm_qos_remove_request(&device->pwrctrl.pm_qos_req_dma);
diff --git a/drivers/gpu/msm/kgsl_cffdump.c b/drivers/gpu/msm/kgsl_cffdump.c
index e06c94d..6dc2ccc 100644
--- a/drivers/gpu/msm/kgsl_cffdump.c
+++ b/drivers/gpu/msm/kgsl_cffdump.c
@@ -28,6 +28,7 @@
 #include "kgsl_log.h"
 #include "kgsl_sharedmem.h"
 #include "adreno_pm4types.h"
+#include "adreno.h"
 
 static struct rchan	*chan;
 static struct dentry	*dir;
@@ -334,7 +335,7 @@
 		return;
 	}
 
-	kgsl_cff_dump_enable = 1;
+	kgsl_cff_dump_enable = 0;
 
 	spin_lock_init(&cffdump_lock);
 
@@ -356,10 +357,21 @@
 		debugfs_remove(dir);
 }
 
-void kgsl_cffdump_open(enum kgsl_deviceid device_id)
+void kgsl_cffdump_open(struct kgsl_device *device)
 {
-	kgsl_cffdump_memory_base(device_id, KGSL_PAGETABLE_BASE,
-			kgsl_mmu_get_ptsize(), SZ_256K);
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
+	if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_get_mmutype()) {
+		kgsl_cffdump_memory_base(device->id,
+			kgsl_mmu_get_base_addr(&device->mmu),
+			kgsl_mmu_get_ptsize(&device->mmu) +
+			KGSL_IOMMU_GLOBAL_MEM_SIZE, adreno_dev->gmem_size);
+	} else {
+		kgsl_cffdump_memory_base(device->id,
+			kgsl_mmu_get_base_addr(&device->mmu),
+			kgsl_mmu_get_ptsize(&device->mmu),
+			adreno_dev->gmem_size);
+	}
 }
 
 void kgsl_cffdump_memory_base(enum kgsl_deviceid device_id, unsigned int base,
@@ -387,7 +399,7 @@
 }
 
 void kgsl_cffdump_syncmem(struct kgsl_device_private *dev_priv,
-	const struct kgsl_memdesc *memdesc, uint gpuaddr, uint sizebytes,
+	struct kgsl_memdesc *memdesc, uint gpuaddr, uint sizebytes,
 	bool clean_cache)
 {
 	const void *src;
@@ -522,7 +534,7 @@
 }
 
 static struct dentry *create_buf_file_handler(const char *filename,
-	struct dentry *parent, int mode, struct rchan_buf *buf,
+	struct dentry *parent, unsigned short mode, struct rchan_buf *buf,
 	int *is_global)
 {
 	return debugfs_create_file(filename, mode, parent, buf,
diff --git a/drivers/gpu/msm/kgsl_cffdump.h b/drivers/gpu/msm/kgsl_cffdump.h
index 2733cc3..d5656f8 100644
--- a/drivers/gpu/msm/kgsl_cffdump.h
+++ b/drivers/gpu/msm/kgsl_cffdump.h
@@ -22,10 +22,10 @@
 
 void kgsl_cffdump_init(void);
 void kgsl_cffdump_destroy(void);
-void kgsl_cffdump_open(enum kgsl_deviceid device_id);
+void kgsl_cffdump_open(struct kgsl_device *device);
 void kgsl_cffdump_close(enum kgsl_deviceid device_id);
 void kgsl_cffdump_syncmem(struct kgsl_device_private *dev_priv,
-	const struct kgsl_memdesc *memdesc, uint physaddr, uint sizebytes,
+	struct kgsl_memdesc *memdesc, uint physaddr, uint sizebytes,
 	bool clean_cache);
 void kgsl_cffdump_setmem(uint addr, uint value, uint sizebytes);
 void kgsl_cffdump_regwrite(enum kgsl_deviceid device_id, uint addr,
@@ -49,7 +49,7 @@
 
 #define kgsl_cffdump_init()					(void)0
 #define kgsl_cffdump_destroy()					(void)0
-#define kgsl_cffdump_open(device_id)				(void)0
+#define kgsl_cffdump_open(device)				(void)0
 #define kgsl_cffdump_close(device_id)				(void)0
 #define kgsl_cffdump_syncmem(dev_priv, memdesc, addr, sizebytes, clean_cache) \
 	(void) 0
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 37b5730..0d11660 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -106,7 +106,7 @@
 			uint32_t flags);
 	int (*drawctxt_create) (struct kgsl_device *device,
 		struct kgsl_pagetable *pagetable, struct kgsl_context *context,
-		uint32_t flags);
+		uint32_t *flags);
 	void (*drawctxt_destroy) (struct kgsl_device *device,
 		struct kgsl_context *context);
 	long (*ioctl) (struct kgsl_device_private *dev_priv,
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index f327c04..739fcff 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -33,6 +33,7 @@
 #include "adreno.h"
 #include "kgsl_trace.h"
 #include "z180.h"
+#include "kgsl_cffdump.h"
 
 
 static struct kgsl_iommu_register_list kgsl_iommuv0_reg[KGSL_IOMMU_REG_MAX] = {
@@ -1548,6 +1549,10 @@
 	kgsl_iommu_lock_rb_in_tlb(mmu);
 	msm_iommu_unlock();
 
+	/* For complete CFF */
+	kgsl_cffdump_setmem(mmu->setstate_memory.gpuaddr +
+				KGSL_IOMMU_SETSTATE_NOP_OFFSET,
+				cp_nop_packet(1), sizeof(unsigned int));
 
 	kgsl_iommu_disable_clk_on_ts(mmu, 0, false);
 	mmu->flags |= KGSL_FLAGS_STARTED;
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index c32fa68..595f78f 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -576,11 +576,10 @@
 	memdesc->pagetable = pagetable;
 	memdesc->ops = &kgsl_page_alloc_ops;
 
-	memdesc->sg = kgsl_sg_alloc(sglen_alloc);
+	memdesc->sglen_alloc = sglen_alloc;
+	memdesc->sg = kgsl_sg_alloc(memdesc->sglen_alloc);
 
 	if (memdesc->sg == NULL) {
-		KGSL_CORE_ERR("vmalloc(%d) failed\n",
-			sglen_alloc * sizeof(struct scatterlist));
 		ret = -ENOMEM;
 		goto done;
 	}
@@ -592,19 +591,17 @@
 	 * two pages; well within the acceptable limits for using kmalloc.
 	 */
 
-	pages = kmalloc(sglen_alloc * sizeof(struct page *), GFP_KERNEL);
+	pages = kmalloc(memdesc->sglen_alloc * sizeof(struct page *),
+		GFP_KERNEL);
 
 	if (pages == NULL) {
-		KGSL_CORE_ERR("kmalloc (%d) failed\n",
-			sglen_alloc * sizeof(struct page *));
 		ret = -ENOMEM;
 		goto done;
 	}
 
 	kmemleak_not_leak(memdesc->sg);
 
-	memdesc->sglen_alloc = sglen_alloc;
-	sg_init_table(memdesc->sg, sglen_alloc);
+	sg_init_table(memdesc->sg, memdesc->sglen_alloc);
 
 	len = size;
 
diff --git a/drivers/gpu/msm/kgsl_sync.c b/drivers/gpu/msm/kgsl_sync.c
index 98edb83..0e3e046 100644
--- a/drivers/gpu/msm/kgsl_sync.c
+++ b/drivers/gpu/msm/kgsl_sync.c
@@ -206,7 +206,7 @@
 	struct kgsl_sync_timeline *ktimeline =
 		(struct kgsl_sync_timeline *) timeline;
 
-	if (timestamp_cmp(timestamp, ktimeline->last_timestamp > 0))
+	if (timestamp_cmp(timestamp, ktimeline->last_timestamp) > 0)
 		ktimeline->last_timestamp = timestamp;
 	sync_timeline_signal(timeline);
 }
diff --git a/drivers/gpu/msm/kgsl_trace.h b/drivers/gpu/msm/kgsl_trace.h
index 8c4811e..5f7ee3c 100644
--- a/drivers/gpu/msm/kgsl_trace.h
+++ b/drivers/gpu/msm/kgsl_trace.h
@@ -24,6 +24,8 @@
 #include <linux/tracepoint.h>
 #include "kgsl_device.h"
 
+#include "adreno_drawctxt.h"
+
 struct kgsl_device;
 struct kgsl_ringbuffer_issueibcmds;
 struct kgsl_device_waittimestamp;
@@ -34,11 +36,16 @@
 TRACE_EVENT(kgsl_issueibcmds,
 
 	TP_PROTO(struct kgsl_device *device,
-			struct kgsl_ringbuffer_issueibcmds *cmd,
+			int drawctxt_id,
 			struct kgsl_ibdesc *ibdesc,
-			int result),
+			int numibs,
+			int timestamp,
+			int flags,
+			int result,
+			unsigned int type),
 
-	TP_ARGS(device, cmd, ibdesc, result),
+	TP_ARGS(device, drawctxt_id, ibdesc, numibs, timestamp, flags,
+		result, type),
 
 	TP_STRUCT__entry(
 		__string(device_name, device->name)
@@ -48,21 +55,23 @@
 		__field(unsigned int, timestamp)
 		__field(unsigned int, flags)
 		__field(int, result)
+		__field(unsigned int, drawctxt_type)
 	),
 
 	TP_fast_assign(
 		__assign_str(device_name, device->name);
-		__entry->drawctxt_id = cmd->drawctxt_id;
+		__entry->drawctxt_id = drawctxt_id;
 		__entry->ibdesc_addr = ibdesc[0].gpuaddr;
-		__entry->numibs = cmd->numibs;
-		__entry->timestamp = cmd->timestamp;
-		__entry->flags = cmd->flags;
+		__entry->numibs = numibs;
+		__entry->timestamp = timestamp;
+		__entry->flags = flags;
 		__entry->result = result;
+		__entry->drawctxt_type = type;
 	),
 
 	TP_printk(
 		"d_name=%s ctx=%u ib=0x%u numibs=%u timestamp=0x%x "
-		"flags=0x%x(%s) result=%d",
+		"flags=0x%x(%s) result=%d type=%s",
 		__get_str(device_name),
 		__entry->drawctxt_id,
 		__entry->ibdesc_addr,
@@ -74,7 +83,9 @@
 			{ KGSL_CONTEXT_SUBMIT_IB_LIST, "IB_LIST" },
 			{ KGSL_CONTEXT_CTX_SWITCH, "CTX_SWITCH" })
 			: "None",
-		__entry->result
+		__entry->result,
+		__print_symbolic(__entry->drawctxt_type,
+			ADRENO_DRAWCTXT_TYPES)
 	)
 );
 
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index b78c6fe..a07959b 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -17,6 +17,7 @@
 #include "kgsl.h"
 #include "kgsl_cffdump.h"
 #include "kgsl_sharedmem.h"
+#include "kgsl_trace.h"
 
 #include "z180.h"
 #include "z180_reg.h"
@@ -483,6 +484,10 @@
 	z180_cmdwindow_write(device, ADDR_VGV3_CONTROL, cmd);
 	z180_cmdwindow_write(device, ADDR_VGV3_CONTROL, 0);
 error:
+
+	trace_kgsl_issueibcmds(device, context->id, ibdesc, numibs,
+		*timestamp, ctrl, result, 0);
+
 	return (int)result;
 }
 
diff --git a/drivers/hwmon/qpnp-adc-common.c b/drivers/hwmon/qpnp-adc-common.c
index b52df44..1458bc5 100644
--- a/drivers/hwmon/qpnp-adc-common.c
+++ b/drivers/hwmon/qpnp-adc-common.c
@@ -637,19 +637,26 @@
 		uint32_t *low_threshold, uint32_t *high_threshold)
 {
 	struct qpnp_vadc_linear_graph vbatt_param;
+	int rc = 0;
 
-	qpnp_get_vadc_gain_and_offset(&vbatt_param, CALIB_ABSOLUTE);
+	rc = qpnp_get_vadc_gain_and_offset(&vbatt_param, CALIB_ABSOLUTE);
+	if (rc < 0)
+		return rc;
 
-	*low_threshold = param->low_thr * vbatt_param.dy;
-	do_div(*low_threshold, vbatt_param.adc_vref);
+	*low_threshold = (((param->low_thr/3) - QPNP_ADC_625_UV) *
+				vbatt_param.dy);
+	do_div(*low_threshold, QPNP_ADC_625_UV);
 	*low_threshold += vbatt_param.adc_gnd;
 
-	*high_threshold = param->high_thr * vbatt_param.dy;
-	do_div(*high_threshold, vbatt_param.adc_vref);
+	*high_threshold = (((param->high_thr/3) - QPNP_ADC_625_UV) *
+				vbatt_param.dy);
+	do_div(*high_threshold, QPNP_ADC_625_UV);
 	*high_threshold += vbatt_param.adc_gnd;
 
 	pr_debug("high_volt:%d, low_volt:%d\n", param->high_thr,
 				param->low_thr);
+	pr_debug("adc_code_high:%x, adc_code_low:%x\n", *high_threshold,
+				*low_threshold);
 	return 0;
 }
 EXPORT_SYMBOL(qpnp_adc_vbatt_rscaler);
diff --git a/drivers/input/touchscreen/synaptics_fw_update.c b/drivers/input/touchscreen/synaptics_fw_update.c
index 7452587..5d66241 100644
--- a/drivers/input/touchscreen/synaptics_fw_update.c
+++ b/drivers/input/touchscreen/synaptics_fw_update.c
@@ -561,8 +561,6 @@
 		goto exit;
 	}
 
-	imagePR = kzalloc(sizeof(MAX_FIRMWARE_ID_LEN), GFP_KERNEL);
-
 	/* Force update firmware when device is in bootloader mode */
 	if (f01_device_status.flash_prog) {
 		dev_info(&i2c_client->dev,
@@ -616,6 +614,11 @@
 	if (imageFirmwareID > deviceFirmwareID) {
 		flash_area = UI_FIRMWARE;
 		goto exit;
+	} else if (imageFirmwareID < deviceFirmwareID) {
+		flash_area = NONE;
+		dev_info(&i2c_client->dev,
+			"Img fw is older than device fw.  Skip fw update.\n");
+		goto exit;
 	}
 
 	/* device config id */
@@ -1650,6 +1653,9 @@
 			&fwu->fwu_work,
 			msecs_to_jiffies(1000));
 #endif
+
+	init_completion(&remove_complete);
+
 	return 0;
 
 exit_remove_attrs:
@@ -1700,7 +1706,6 @@
 
 static void __exit rmi4_fw_update_module_exit(void)
 {
-	init_completion(&remove_complete);
 	synaptics_rmi4_new_function(RMI_FW_UPDATER, false,
 			synaptics_rmi4_fwu_init,
 			synaptics_rmi4_fwu_remove,
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.c b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
index 775d62a..e1b3884 100644
--- a/drivers/input/touchscreen/synaptics_i2c_rmi4.c
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
@@ -65,8 +65,8 @@
 
 #define NORMAL_OPERATION (0 << 0)
 #define SENSOR_SLEEP (1 << 0)
-#define NO_SLEEP_OFF (0 << 3)
-#define NO_SLEEP_ON (1 << 3)
+#define NO_SLEEP_OFF (0 << 2)
+#define NO_SLEEP_ON (1 << 2)
 
 #define RMI4_VTG_MIN_UV		2700000
 #define RMI4_VTG_MAX_UV		3300000
@@ -125,6 +125,19 @@
 static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count);
 
+static ssize_t synaptics_rmi4_flipx_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_flipx_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t synaptics_rmi4_flipy_show(struct device *dev,
+		struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_flipy_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count);
+
+
 struct synaptics_rmi4_f01_device_status {
 	union {
 		struct {
@@ -223,6 +236,12 @@
 	__ATTR(0dbutton, (S_IRUGO | S_IWUGO),
 			synaptics_rmi4_0dbutton_show,
 			synaptics_rmi4_0dbutton_store),
+	__ATTR(flipx, (S_IRUGO | S_IWUGO),
+			synaptics_rmi4_flipx_show,
+			synaptics_rmi4_flipx_store),
+	__ATTR(flipy, (S_IRUGO | S_IWUGO),
+			synaptics_rmi4_flipy_show,
+			synaptics_rmi4_flipy_store),
 };
 
 static bool exp_fn_inited;
@@ -391,6 +410,52 @@
 	return count;
 }
 
+static ssize_t synaptics_rmi4_flipx_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+		rmi4_data->flip_x);
+}
+
+static ssize_t synaptics_rmi4_flipx_store(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned int input;
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	if (sscanf(buf, "%u", &input) != 1)
+		return -EINVAL;
+
+	rmi4_data->flip_x = input > 0 ? 1 : 0;
+
+	return count;
+}
+
+static ssize_t synaptics_rmi4_flipy_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+		rmi4_data->flip_y);
+}
+
+static ssize_t synaptics_rmi4_flipy_store(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned int input;
+	struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+	if (sscanf(buf, "%u", &input) != 1)
+		return -EINVAL;
+
+	rmi4_data->flip_y = input > 0 ? 1 : 0;
+
+	return count;
+}
+
  /**
  * synaptics_rmi4_set_page()
  *
@@ -581,6 +646,7 @@
 	int y;
 	int wx;
 	int wy;
+	int z;
 
 	/*
 	 * The number of finger status registers is determined by the
@@ -634,10 +700,11 @@
 			y = (data[1] << 4) | ((data[2] >> 4) & MASK_4BIT);
 			wx = (data[3] & MASK_4BIT);
 			wy = (data[3] >> 4) & MASK_4BIT;
+			z = data[4];
 
-			if (rmi4_data->board->x_flip)
+			if (rmi4_data->flip_x)
 				x = rmi4_data->sensor_max_x - x;
-			if (rmi4_data->board->y_flip)
+			if (rmi4_data->flip_y)
 				y = rmi4_data->sensor_max_y - y;
 
 			dev_dbg(&rmi4_data->i2c_client->dev,
@@ -655,6 +722,8 @@
 					ABS_MT_POSITION_X, x);
 			input_report_abs(rmi4_data->input_dev,
 					ABS_MT_POSITION_Y, y);
+			input_report_abs(rmi4_data->input_dev,
+					ABS_MT_PRESSURE, z);
 
 #ifdef REPORT_2D_W
 			input_report_abs(rmi4_data->input_dev,
@@ -1007,22 +1076,12 @@
 		if (retval < 0)
 			return retval;
 
-		retval = request_threaded_irq(rmi4_data->irq, NULL,
-				synaptics_rmi4_irq,
-				rmi4_data->board->irq_flags,
-				DRIVER_NAME, rmi4_data);
-		if (retval < 0) {
-			dev_err(&rmi4_data->i2c_client->dev,
-					"%s: Failed to create irq thread\n",
-					__func__);
-			return retval;
-		}
+		enable_irq(rmi4_data->irq);
 
 		rmi4_data->irq_enabled = true;
 	} else {
 		if (rmi4_data->irq_enabled) {
 			disable_irq(rmi4_data->irq);
-			free_irq(rmi4_data->irq, rmi4_data);
 			rmi4_data->irq_enabled = false;
 		}
 	}
@@ -1257,7 +1316,7 @@
 static int synaptics_rmi4_alloc_fh(struct synaptics_rmi4_fn **fhandler,
 		struct synaptics_rmi4_fn_desc *rmi_fd, int page_number)
 {
-	*fhandler = kmalloc(sizeof(**fhandler), GFP_KERNEL);
+	*fhandler = kzalloc(sizeof(**fhandler), GFP_KERNEL);
 	if (!(*fhandler))
 		return -ENOMEM;
 
@@ -1273,6 +1332,7 @@
 	(*fhandler)->full_addr.query_base =
 			(rmi_fd->query_base_addr |
 			(page_number << 8));
+	(*fhandler)->fn_number = rmi_fd->fn_number;
 
 	return 0;
 }
@@ -1331,7 +1391,7 @@
 				__func__, retval);
 		return retval;
 	}
-	return retval;
+	return 0;
 }
 
  /**
@@ -1423,15 +1483,6 @@
 				}
 				break;
 
-			case SYNAPTICS_RMI4_F34:
-				retval = synaptics_rmi4_i2c_read(rmi4_data,
-						rmi_fd.ctrl_base_addr,
-						rmi->config_id,
-						sizeof(rmi->config_id));
-				if (retval < 0)
-					return retval;
-				break;
-
 			case SYNAPTICS_RMI4_F11:
 				if (rmi_fd.intr_src_count == 0)
 					break;
@@ -1530,14 +1581,51 @@
 	return 0;
 }
 
-static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data)
+static int synaptics_rmi4_reset_command(struct synaptics_rmi4_data *rmi4_data)
 {
 	int retval;
+	int page_number;
 	unsigned char command = 0x01;
-	struct synaptics_rmi4_fn *fhandler;
-	struct synaptics_rmi4_device_info *rmi;
+	unsigned short pdt_entry_addr;
+	struct synaptics_rmi4_fn_desc rmi_fd;
+	bool done = false;
 
-	rmi = &(rmi4_data->rmi4_mod_info);
+	/* Scan the page description tables of the pages to service */
+	for (page_number = 0; page_number < PAGES_TO_SERVICE; page_number++) {
+		for (pdt_entry_addr = PDT_START; pdt_entry_addr > PDT_END;
+				pdt_entry_addr -= PDT_ENTRY_SIZE) {
+			retval = synaptics_rmi4_i2c_read(rmi4_data,
+				pdt_entry_addr,
+				(unsigned char *)&rmi_fd,
+				sizeof(rmi_fd));
+			if (retval < 0)
+				return retval;
+
+			if (rmi_fd.fn_number == 0)
+				break;
+
+			switch (rmi_fd.fn_number) {
+			case SYNAPTICS_RMI4_F01:
+				rmi4_data->f01_cmd_base_addr =
+					rmi_fd.cmd_base_addr;
+				done = true;
+				break;
+			}
+		}
+		if (done) {
+			dev_info(&rmi4_data->i2c_client->dev,
+				"%s: Find F01 in page description table 0x%x\n",
+				__func__, rmi4_data->f01_cmd_base_addr);
+			break;
+		}
+	}
+
+	if (!done) {
+		dev_err(&rmi4_data->i2c_client->dev,
+			"%s: Cannot find F01 in page description table\n",
+			__func__);
+		return -EINVAL;
+	}
 
 	retval = synaptics_rmi4_i2c_write(rmi4_data,
 			rmi4_data->f01_cmd_base_addr,
@@ -1551,6 +1639,24 @@
 	}
 
 	msleep(100);
+	return retval;
+};
+
+static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data)
+{
+	int retval;
+	struct synaptics_rmi4_fn *fhandler;
+	struct synaptics_rmi4_device_info *rmi;
+
+	rmi = &(rmi4_data->rmi4_mod_info);
+
+	retval = synaptics_rmi4_reset_command(rmi4_data);
+	if (retval < 0) {
+		dev_err(&rmi4_data->i2c_client->dev,
+			"%s: Failed to send command reset\n",
+			__func__);
+		return retval;
+	}
 
 	if (!list_empty(&rmi->support_fn_list)) {
 		list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
@@ -1921,6 +2027,9 @@
 	rmi4_data->irq_enable = synaptics_rmi4_irq_enable;
 	rmi4_data->reset_device = synaptics_rmi4_reset_device;
 
+	rmi4_data->flip_x = rmi4_data->board->x_flip;
+	rmi4_data->flip_y = rmi4_data->board->y_flip;
+
 	rmi4_data->input_dev->name = DRIVER_NAME;
 	rmi4_data->input_dev->phys = INPUT_PHYS_NAME;
 	rmi4_data->input_dev->id.bustype = BUS_I2C;
@@ -1993,7 +2102,8 @@
 		usleep(RMI4_GPIO_SLEEP_LOW_US);
 		gpio_set_value(platform_data->reset_gpio, 1);
 		msleep(RMI4_GPIO_WAIT_HIGH_MS);
-	}
+	} else
+		synaptics_rmi4_reset_command(rmi4_data);
 
 
 	init_waitqueue_head(&rmi4_data->wait);
@@ -2013,6 +2123,8 @@
 	input_set_abs_params(rmi4_data->input_dev,
 			ABS_MT_POSITION_Y, 0,
 			rmi4_data->sensor_max_y, 0, 0);
+	input_set_abs_params(rmi4_data->input_dev,
+			ABS_PRESSURE, 0, 255, 0, 0);
 #ifdef REPORT_2D_W
 	input_set_abs_params(rmi4_data->input_dev,
 			ABS_MT_TOUCH_MAJOR, 0,
@@ -2074,10 +2186,14 @@
 
 	rmi4_data->irq = gpio_to_irq(platform_data->irq_gpio);
 
-	retval = synaptics_rmi4_irq_enable(rmi4_data, true);
+	retval = request_threaded_irq(rmi4_data->irq, NULL,
+		synaptics_rmi4_irq, platform_data->irq_flags,
+		DRIVER_NAME, rmi4_data);
+	rmi4_data->irq_enabled = true;
+
 	if (retval < 0) {
 		dev_err(&client->dev,
-				"%s: Failed to enable attention interrupt\n",
+				"%s: Failed to create irq thread\n",
 				__func__);
 		goto err_enable_irq;
 	}
@@ -2092,6 +2208,13 @@
 			goto err_sysfs;
 		}
 	}
+	retval = synaptics_rmi4_irq_enable(rmi4_data, true);
+	if (retval < 0) {
+		dev_err(&client->dev,
+			"%s: Failed to enable attention interrupt\n",
+			__func__);
+		goto err_sysfs;
+	}
 
 	return retval;
 
@@ -2162,7 +2285,7 @@
 	rmi4_data->touch_stopped = true;
 	wake_up(&rmi4_data->wait);
 
-	synaptics_rmi4_irq_enable(rmi4_data, false);
+	free_irq(rmi4_data->irq, rmi4_data);
 
 	for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
 		sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.h b/drivers/input/touchscreen/synaptics_i2c_rmi4.h
index b1d2645..9356937 100644
--- a/drivers/input/touchscreen/synaptics_i2c_rmi4.h
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.h
@@ -24,7 +24,7 @@
 #define SYNAPTICS_DS4 (1 << 0)
 #define SYNAPTICS_DS5 (1 << 1)
 #define SYNAPTICS_DSX_DRIVER_PRODUCT SYNAPTICS_DS4
-#define SYNAPTICS_DSX_DRIVER_VERSION 0x1002
+#define SYNAPTICS_DSX_DRIVER_VERSION 0x1004
 
 #include <linux/version.h>
 #ifdef CONFIG_HAS_EARLYSUSPEND
@@ -177,6 +177,8 @@
  * @irq_enabled: flag for indicating interrupt enable status
  * @touch_stopped: flag to stop interrupt thread processing
  * @fingers_on_2d: flag to indicate presence of fingers in 2d area
+ * @flip_x: set to TRUE if desired to flip direction on x-axis
+ * @flip_y: set to TRUE if desired to flip direction on y-axis
  * @sensor_sleep: flag to indicate sleep state of sensor
  * @wait: wait queue for touch data polling in interrupt thread
  * @i2c_read: pointer to i2c read function
@@ -215,6 +217,8 @@
 	bool touch_stopped;
 	bool fingers_on_2d;
 	bool sensor_sleep;
+	bool flip_x;
+	bool flip_y;
 	wait_queue_head_t wait;
 	int (*i2c_read)(struct synaptics_rmi4_data *pdata, unsigned short addr,
 			unsigned char *data, unsigned short length);
diff --git a/drivers/input/touchscreen/synaptics_rmi_dev.c b/drivers/input/touchscreen/synaptics_rmi_dev.c
index 7f1aac5..c6b8a1c 100644
--- a/drivers/input/touchscreen/synaptics_rmi_dev.c
+++ b/drivers/input/touchscreen/synaptics_rmi_dev.c
@@ -619,6 +619,8 @@
 		}
 	}
 
+	init_completion(&remove_complete);
+
 	return 0;
 
 err_sysfs_attrs:
diff --git a/drivers/iommu/msm_iommu-v0.c b/drivers/iommu/msm_iommu-v0.c
index de35f9a..c0a4720 100644
--- a/drivers/iommu/msm_iommu-v0.c
+++ b/drivers/iommu/msm_iommu-v0.c
@@ -156,21 +156,15 @@
 	clk_disable_unprepare(drvdata->pclk);
 }
 
-static int _iommu_power_on(void *data)
+static int __enable_regulators(struct msm_iommu_drvdata *drvdata)
 {
-	struct msm_iommu_drvdata *drvdata;
-
-	drvdata = (struct msm_iommu_drvdata *)data;
-	return __enable_clocks(drvdata);
+	/* No need to do anything. IOMMUv0 is always on. */
+	return 0;
 }
 
-static int _iommu_power_off(void *data)
+static void __disable_regulators(struct msm_iommu_drvdata *drvdata)
 {
-	struct msm_iommu_drvdata *drvdata;
-
-	drvdata = (struct msm_iommu_drvdata *)data;
-	__disable_clocks(drvdata);
-	return 0;
+	/* No need to do anything. IOMMUv0 is always on. */
 }
 
 static void _iommu_lock_acquire(void)
@@ -184,8 +178,10 @@
 }
 
 struct iommu_access_ops iommu_access_ops_v0 = {
-	.iommu_power_on = _iommu_power_on,
-	.iommu_power_off = _iommu_power_off,
+	.iommu_power_on = __enable_regulators,
+	.iommu_power_off = __disable_regulators,
+	.iommu_clk_on = __enable_clocks,
+	.iommu_clk_off = __disable_clocks,
 	.iommu_lock_acquire = _iommu_lock_acquire,
 	.iommu_lock_release = _iommu_lock_release,
 };
diff --git a/drivers/iommu/msm_iommu-v1.c b/drivers/iommu/msm_iommu-v1.c
index f552474..fa5ca8c 100644
--- a/drivers/iommu/msm_iommu-v1.c
+++ b/drivers/iommu/msm_iommu-v1.c
@@ -103,36 +103,6 @@
 	clk_disable_unprepare(drvdata->pclk);
 }
 
-static int _iommu_power_off(void *data)
-{
-	struct msm_iommu_drvdata *drvdata;
-
-	drvdata = (struct msm_iommu_drvdata *)data;
-	__disable_clocks(drvdata);
-	__disable_regulators(drvdata);
-	return 0;
-}
-
-static int _iommu_power_on(void *data)
-{
-	int ret;
-	struct msm_iommu_drvdata *drvdata;
-
-	drvdata = (struct msm_iommu_drvdata *)data;
-	ret = __enable_regulators(drvdata);
-	if (ret)
-		goto fail;
-
-	ret = __enable_clocks(drvdata);
-	if (ret) {
-		__disable_regulators(drvdata);
-		goto fail;
-	}
-	return 0;
-fail:
-	return -EIO;
-}
-
 static void _iommu_lock_acquire(void)
 {
 	mutex_lock(&msm_iommu_lock);
@@ -144,8 +114,10 @@
 }
 
 struct iommu_access_ops iommu_access_ops_v1 = {
-	.iommu_power_on = _iommu_power_on,
-	.iommu_power_off = _iommu_power_off,
+	.iommu_power_on = __enable_regulators,
+	.iommu_power_off = __disable_regulators,
+	.iommu_clk_on = __enable_clocks,
+	.iommu_clk_off = __disable_clocks,
 	.iommu_lock_acquire = _iommu_lock_acquire,
 	.iommu_lock_release = _iommu_lock_release,
 };
diff --git a/drivers/iommu/msm_iommu_dev-v1.c b/drivers/iommu/msm_iommu_dev-v1.c
index f994413..418a086 100644
--- a/drivers/iommu/msm_iommu_dev-v1.c
+++ b/drivers/iommu/msm_iommu_dev-v1.c
@@ -265,6 +265,8 @@
 
 	platform_set_drvdata(pdev, drvdata);
 
+	msm_iommu_sec_set_access_ops(&iommu_access_ops_v1);
+
 	pmon_info = msm_iommu_pm_alloc(&pdev->dev);
 	if (pmon_info != NULL) {
 		ret = msm_iommu_pmon_parse_dt(pdev, pmon_info);
diff --git a/drivers/iommu/msm_iommu_perfmon-v0.c b/drivers/iommu/msm_iommu_perfmon-v0.c
index c80d1e5..1073623 100644
--- a/drivers/iommu/msm_iommu_perfmon-v0.c
+++ b/drivers/iommu/msm_iommu_perfmon-v0.c
@@ -21,6 +21,7 @@
 #include <linux/device.h>
 #include <mach/iommu_hw-v0.h>
 #include <mach/iommu_perfmon.h>
+#include <mach/iommu.h>
 
 #define PM_RESET_MASK		(0xF)
 #define PM_RESET_SHIFT		(0x8)
@@ -280,7 +281,9 @@
 	 * for locking here.
 	 */
 	iommu->ops->iommu_power_on(iommu_drvdata);
+	iommu->ops->iommu_clk_on(iommu_drvdata);
 	iommu_pm_set_int_active_high(iommu);
+	iommu->ops->iommu_clk_off(iommu_drvdata);
 	iommu->ops->iommu_power_off(iommu_drvdata);
 }
 
diff --git a/drivers/iommu/msm_iommu_perfmon-v1.c b/drivers/iommu/msm_iommu_perfmon-v1.c
index d76ee7f..7d6dd34 100644
--- a/drivers/iommu/msm_iommu_perfmon-v1.c
+++ b/drivers/iommu/msm_iommu_perfmon-v1.c
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <mach/iommu_hw-v1.h>
 #include <mach/iommu_perfmon.h>
+#include <mach/iommu.h>
 
 #define PMCR_P_MASK		(0x1)
 #define PMCR_P_SHIFT		(1)
diff --git a/drivers/iommu/msm_iommu_perfmon.c b/drivers/iommu/msm_iommu_perfmon.c
index 41df1ed..fee8a4a 100644
--- a/drivers/iommu/msm_iommu_perfmon.c
+++ b/drivers/iommu/msm_iommu_perfmon.c
@@ -242,6 +242,7 @@
 					dev_get_drvdata(iommu->iommu_dev);
 
 	iommu->ops->iommu_power_on(iommu_drvdata);
+	iommu->ops->iommu_clk_on(iommu_drvdata);
 
 	/* Reset counters in HW */
 	iommu->ops->iommu_lock_acquire();
@@ -294,6 +295,7 @@
 	iommu_pm_read_all_counters(pmon);
 
 	iommu->ops->iommu_lock_release();
+	iommu->ops->iommu_clk_off(iommu_drvdata);
 	iommu->ops->iommu_power_off(iommu_drvdata);
 
 	pr_info("%s: TLB performance monitoring turned OFF\n",
diff --git a/drivers/iommu/msm_iommu_sec.c b/drivers/iommu/msm_iommu_sec.c
index 5ca6fd9..74d8b48 100644
--- a/drivers/iommu/msm_iommu_sec.c
+++ b/drivers/iommu/msm_iommu_sec.c
@@ -43,8 +43,11 @@
 #define IOMMU_SECURE_PTBL_INIT  4
 #define IOMMU_SECURE_MAP	6
 #define IOMMU_SECURE_UNMAP      7
+#define IOMMU_SECURE_MAP2 0x0B
+#define IOMMU_SECURE_UNMAP2 0x0C
+#define IOMMU_TLBINVAL_FLAG 0x00000001
 
-static DEFINE_MUTEX(msm_iommu_lock);
+static struct iommu_access_ops *iommu_access_ops;
 
 struct msm_scm_paddr_list {
 	unsigned int list;
@@ -59,11 +62,22 @@
 	unsigned int size;
 };
 
-struct msm_scm_map_req {
+struct msm_scm_map2_req {
 	struct msm_scm_paddr_list plist;
 	struct msm_scm_mapping_info info;
+	unsigned int flags;
 };
 
+struct msm_scm_unmap2_req {
+	struct msm_scm_mapping_info info;
+	unsigned int flags;
+};
+
+void msm_iommu_sec_set_access_ops(struct iommu_access_ops *access_ops)
+{
+	iommu_access_ops = access_ops;
+}
+
 static int msm_iommu_sec_ptbl_init(void)
 {
 	struct device_node *np;
@@ -153,7 +167,7 @@
 			struct msm_iommu_ctx_drvdata *ctx_drvdata,
 			unsigned long va, phys_addr_t pa, size_t len)
 {
-	struct msm_scm_map_req map;
+	struct msm_scm_map2_req map;
 	int ret = 0;
 
 	map.plist.list = virt_to_phys(&pa);
@@ -163,8 +177,9 @@
 	map.info.ctx_id = ctx_drvdata->num;
 	map.info.va = va;
 	map.info.size = len;
+	map.flags = IOMMU_TLBINVAL_FLAG;
 
-	if (scm_call(SCM_SVC_MP, IOMMU_SECURE_MAP, &map, sizeof(map), &ret,
+	if (scm_call(SCM_SVC_MP, IOMMU_SECURE_MAP2, &map, sizeof(map), &ret,
 								sizeof(ret)))
 		return -EINVAL;
 	if (ret)
@@ -191,7 +206,7 @@
 			unsigned long va, struct scatterlist *sg, size_t len)
 {
 	struct scatterlist *sgiter;
-	struct msm_scm_map_req map;
+	struct msm_scm_map2_req map;
 	unsigned int *pa_list = 0;
 	unsigned int pa, cnt;
 	unsigned int offset = 0, chunk_offset = 0;
@@ -201,6 +216,7 @@
 	map.info.ctx_id = ctx_drvdata->num;
 	map.info.va = va;
 	map.info.size = len;
+	map.flags = IOMMU_TLBINVAL_FLAG;
 
 	if (sg->length == len) {
 		pa = get_phys_addr(sg);
@@ -239,7 +255,7 @@
 		map.plist.size = SZ_1M;
 	}
 
-	ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_MAP, &map, sizeof(map),
+	ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_MAP2, &map, sizeof(map),
 			&scm_ret, sizeof(scm_ret));
 	kfree(pa_list);
 	return ret;
@@ -249,50 +265,20 @@
 			struct msm_iommu_ctx_drvdata *ctx_drvdata,
 			unsigned long va, size_t len)
 {
-	struct msm_scm_mapping_info mi;
+	struct msm_scm_unmap2_req unmap;
 	int ret, scm_ret;
 
-	mi.id = iommu_drvdata->sec_id;
-	mi.ctx_id = ctx_drvdata->num;
-	mi.va = va;
-	mi.size = len;
+	unmap.info.id = iommu_drvdata->sec_id;
+	unmap.info.ctx_id = ctx_drvdata->num;
+	unmap.info.va = va;
+	unmap.info.size = len;
+	unmap.flags = IOMMU_TLBINVAL_FLAG;
 
-	ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_UNMAP, &mi, sizeof(mi),
+	ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_UNMAP2, &unmap, sizeof(unmap),
 			&scm_ret, sizeof(scm_ret));
 	return ret;
 }
 
-static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
-{
-	int ret;
-
-	ret = clk_prepare_enable(drvdata->pclk);
-	if (ret)
-		goto fail;
-
-	ret = clk_prepare_enable(drvdata->clk);
-	if (ret)
-		clk_disable_unprepare(drvdata->pclk);
-
-	if (drvdata->aclk) {
-		ret = clk_prepare_enable(drvdata->aclk);
-		if (ret) {
-			clk_disable_unprepare(drvdata->clk);
-			clk_disable_unprepare(drvdata->pclk);
-		}
-	}
-fail:
-	return ret;
-}
-
-static void __disable_clocks(struct msm_iommu_drvdata *drvdata)
-{
-	if (drvdata->aclk)
-		clk_disable_unprepare(drvdata->aclk);
-	clk_disable_unprepare(drvdata->clk);
-	clk_disable_unprepare(drvdata->pclk);
-}
-
 static int msm_iommu_domain_init(struct iommu_domain *domain, int flags)
 {
 	struct msm_iommu_priv *priv;
@@ -310,12 +296,12 @@
 {
 	struct msm_iommu_priv *priv;
 
-	mutex_lock(&msm_iommu_lock);
+	iommu_access_ops->iommu_lock_acquire();
 	priv = domain->priv;
 	domain->priv = NULL;
 
 	kfree(priv);
-	mutex_unlock(&msm_iommu_lock);
+	iommu_access_ops->iommu_lock_release();
 }
 
 static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
@@ -326,7 +312,7 @@
 	struct msm_iommu_ctx_drvdata *tmp_drvdata;
 	int ret = 0;
 
-	mutex_lock(&msm_iommu_lock);
+	iommu_access_ops->iommu_lock_acquire();
 
 	priv = domain->priv;
 	if (!priv || !dev) {
@@ -352,15 +338,15 @@
 			goto fail;
 		}
 
-	ret = regulator_enable(iommu_drvdata->gdsc);
+	ret = iommu_access_ops->iommu_power_on(iommu_drvdata);
 	if (ret)
 		goto fail;
 
 	/* We can only do this once */
 	if (!iommu_drvdata->ctx_attach_count) {
-		ret = __enable_clocks(iommu_drvdata);
+		ret = iommu_access_ops->iommu_clk_on(iommu_drvdata);
 		if (ret) {
-			regulator_disable(iommu_drvdata->gdsc);
+			iommu_access_ops->iommu_power_off(iommu_drvdata);
 			goto fail;
 		}
 
@@ -370,9 +356,9 @@
 		program_iommu_bfb_settings(iommu_drvdata->base,
 					   iommu_drvdata->bfb_settings);
 
-		__disable_clocks(iommu_drvdata);
+		iommu_access_ops->iommu_clk_off(iommu_drvdata);
 		if (ret) {
-			regulator_disable(iommu_drvdata->gdsc);
+			iommu_access_ops->iommu_power_off(iommu_drvdata);
 			goto fail;
 		}
 	}
@@ -381,12 +367,12 @@
 	ctx_drvdata->attached_domain = domain;
 	++iommu_drvdata->ctx_attach_count;
 
-	mutex_unlock(&msm_iommu_lock);
+	iommu_access_ops->iommu_lock_release();
 
 	msm_iommu_attached(dev->parent);
 	return ret;
 fail:
-	mutex_unlock(&msm_iommu_lock);
+	iommu_access_ops->iommu_lock_release();
 	return ret;
 }
 
@@ -398,7 +384,7 @@
 
 	msm_iommu_detached(dev->parent);
 
-	mutex_lock(&msm_iommu_lock);
+	iommu_access_ops->iommu_lock_acquire();
 	if (!dev)
 		goto fail;
 
@@ -410,11 +396,11 @@
 	list_del_init(&ctx_drvdata->attached_elm);
 	ctx_drvdata->attached_domain = NULL;
 
-	regulator_disable(iommu_drvdata->gdsc);
+	iommu_access_ops->iommu_power_off(iommu_drvdata);
 	BUG_ON(iommu_drvdata->ctx_attach_count == 0);
 	--iommu_drvdata->ctx_attach_count;
 fail:
-	mutex_unlock(&msm_iommu_lock);
+	iommu_access_ops->iommu_lock_release();
 }
 
 static int get_drvdata(struct iommu_domain *domain,
@@ -444,16 +430,18 @@
 	struct msm_iommu_ctx_drvdata *ctx_drvdata;
 	int ret = 0;
 
-	mutex_lock(&msm_iommu_lock);
+	iommu_access_ops->iommu_lock_acquire();
 
 	ret = get_drvdata(domain, &iommu_drvdata, &ctx_drvdata);
 	if (ret)
 		goto fail;
 
+	iommu_access_ops->iommu_clk_on(iommu_drvdata);
 	ret = msm_iommu_sec_ptbl_map(iommu_drvdata, ctx_drvdata,
 					va, pa, len);
+	iommu_access_ops->iommu_clk_off(iommu_drvdata);
 fail:
-	mutex_unlock(&msm_iommu_lock);
+	iommu_access_ops->iommu_lock_release();
 	return ret;
 }
 
@@ -464,16 +452,18 @@
 	struct msm_iommu_ctx_drvdata *ctx_drvdata;
 	int ret = -ENODEV;
 
-	mutex_lock(&msm_iommu_lock);
+	iommu_access_ops->iommu_lock_acquire();
 
 	ret = get_drvdata(domain, &iommu_drvdata, &ctx_drvdata);
 	if (ret)
 		goto fail;
 
+	iommu_access_ops->iommu_clk_on(iommu_drvdata);
 	ret = msm_iommu_sec_ptbl_unmap(iommu_drvdata, ctx_drvdata,
 					va, len);
+	iommu_access_ops->iommu_clk_off(iommu_drvdata);
 fail:
-	mutex_unlock(&msm_iommu_lock);
+	iommu_access_ops->iommu_lock_release();
 
 	/* the IOMMU API requires us to return how many bytes were unmapped */
 	len = ret ? 0 : len;
@@ -488,15 +478,17 @@
 	struct msm_iommu_drvdata *iommu_drvdata;
 	struct msm_iommu_ctx_drvdata *ctx_drvdata;
 
-	mutex_lock(&msm_iommu_lock);
+	iommu_access_ops->iommu_lock_acquire();
 
 	ret = get_drvdata(domain, &iommu_drvdata, &ctx_drvdata);
 	if (ret)
 		goto fail;
+	iommu_access_ops->iommu_clk_on(iommu_drvdata);
 	ret = msm_iommu_sec_ptbl_map_range(iommu_drvdata, ctx_drvdata,
 						va, sg, len);
+	iommu_access_ops->iommu_clk_off(iommu_drvdata);
 fail:
-	mutex_unlock(&msm_iommu_lock);
+	iommu_access_ops->iommu_lock_release();
 	return ret;
 }
 
@@ -508,16 +500,18 @@
 	struct msm_iommu_ctx_drvdata *ctx_drvdata;
 	int ret;
 
-	mutex_lock(&msm_iommu_lock);
+	iommu_access_ops->iommu_lock_acquire();
 
 	ret = get_drvdata(domain, &iommu_drvdata, &ctx_drvdata);
 	if (ret)
 		goto fail;
 
+	iommu_access_ops->iommu_clk_on(iommu_drvdata);
 	ret = msm_iommu_sec_ptbl_unmap(iommu_drvdata, ctx_drvdata, va, len);
+	iommu_access_ops->iommu_clk_off(iommu_drvdata);
 
 fail:
-	mutex_unlock(&msm_iommu_lock);
+	iommu_access_ops->iommu_lock_release();
 	return 0;
 }
 
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index ac06fc5..e88e574 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -991,6 +991,7 @@
 static struct attribute *led_attrs[] = {
 	&dev_attr_led_mode.attr,
 	&dev_attr_strobe.attr,
+	NULL
 };
 
 static const struct attribute_group led_attr_group = {
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
index 92f7463..e8480f7 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
@@ -5,7 +5,7 @@
  * Copyright (C) 2003 Oliver Endriss
  * Copyright (C) 2004 Andrew de Quincey
  *
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * based on code originally found in av7110.c & dvb_ci.c:
  * Copyright (C) 1999-2003 Ralph  Metzler
@@ -334,7 +334,10 @@
 		idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
 	}
 
-	consumed = (idx - rbuf->pread) % rbuf->size;
+	if (idx >= rbuf->pread)
+		consumed = idx - rbuf->pread;
+	else
+		consumed = rbuf->size - (rbuf->pread - idx);
 
 	while((dvb_ringbuffer_avail(rbuf) - consumed) > DVB_RINGBUFFER_PKTHDRSIZE) {
 
diff --git a/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_platform.c b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_platform.c
index 3607f2e..cda36d9 100644
--- a/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_platform.c
+++ b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_platform.c
@@ -16,7 +16,6 @@
 
 #include <mach/clk.h>
 #include <mach/camera.h>
-#include <mach/msm_subsystem_map.h>
 
 #include "msm_mercury_platform.h"
 #include "msm_mercury_sync.h"
diff --git a/drivers/media/platform/msm/camera_v2/Kconfig b/drivers/media/platform/msm/camera_v2/Kconfig
index 269e538..d9552e2 100644
--- a/drivers/media/platform/msm/camera_v2/Kconfig
+++ b/drivers/media/platform/msm/camera_v2/Kconfig
@@ -64,6 +64,15 @@
           based on cid which is mapped to a virtual channel
           and datatype.
 
+config MSM_EEPROM
+        bool "Qualcomm MSM Camera ROM Interface for Calibration support"
+        depends on MSMB_CAMERA
+        ---help---
+          Enable support for ROM Interface for Calibration
+          Provides interface for reading the Claibration data.
+          and also provides support for writing data in case of FLASH ROM.
+	  Currently supports I2C, CCI and SPI protocol
+
 config MSM_ISPIF
         bool "Qualcomm MSM Image Signal Processing interface support"
         depends on MSMB_CAMERA
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
index ff86aae..447c752 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
@@ -113,7 +113,8 @@
 	vfe_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
 	v4l2_set_subdevdata(&vfe_dev->subdev.sd, vfe_dev);
 	platform_set_drvdata(pdev, &vfe_dev->subdev.sd);
-	mutex_init(&vfe_dev->mutex);
+	mutex_init(&vfe_dev->realtime_mutex);
+	mutex_init(&vfe_dev->core_mutex);
 	spin_lock_init(&vfe_dev->tasklet_lock);
 	spin_lock_init(&vfe_dev->shared_data_lock);
 	media_entity_init(&vfe_dev->subdev.sd.entity, 0, NULL, 0);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index cfbe29c..ad8aa82 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -369,7 +369,8 @@
 	struct completion reset_complete;
 	struct completion halt_complete;
 	struct completion stream_config_complete;
-	struct mutex mutex;
+	struct mutex realtime_mutex;
+	struct mutex core_mutex;
 
 	atomic_t irq_cnt;
 	uint8_t taskletq_idx;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index ae89500..3035d93 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -120,55 +120,82 @@
 	long rc = 0;
 	struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
 
-	mutex_lock(&vfe_dev->mutex);
-	ISP_DBG("%s cmd: %d\n", __func__, cmd);
+	/* Use real time mutex for hard real-time ioctls such as
+	 * buffer operations and register updates.
+	 * Use core mutex for other ioctls that could take
+	 * longer time to complete such as start/stop ISP streams
+	 * which blocks until the hardware start/stop streaming
+	 */
+	ISP_DBG("%s cmd: %d\n", __func__, _IOC_TYPE(cmd));
 	switch (cmd) {
 	case VIDIOC_MSM_VFE_REG_CFG: {
+		mutex_lock(&vfe_dev->realtime_mutex);
 		rc = msm_isp_proc_cmd(vfe_dev, arg);
+		mutex_unlock(&vfe_dev->realtime_mutex);
 		break;
 	}
 	case VIDIOC_MSM_ISP_REQUEST_BUF:
 	case VIDIOC_MSM_ISP_ENQUEUE_BUF:
 	case VIDIOC_MSM_ISP_RELEASE_BUF: {
+		mutex_lock(&vfe_dev->realtime_mutex);
 		rc = msm_isp_proc_buf_cmd(vfe_dev->buf_mgr, cmd, arg);
+		mutex_unlock(&vfe_dev->realtime_mutex);
 		break;
 	}
 	case VIDIOC_MSM_ISP_REQUEST_STREAM:
+		mutex_lock(&vfe_dev->core_mutex);
 		rc = msm_isp_request_axi_stream(vfe_dev, arg);
+		mutex_unlock(&vfe_dev->core_mutex);
 		break;
 	case VIDIOC_MSM_ISP_RELEASE_STREAM:
+		mutex_lock(&vfe_dev->core_mutex);
 		rc = msm_isp_release_axi_stream(vfe_dev, arg);
+		mutex_unlock(&vfe_dev->core_mutex);
 		break;
 	case VIDIOC_MSM_ISP_CFG_STREAM:
+		mutex_lock(&vfe_dev->core_mutex);
 		rc = msm_isp_cfg_axi_stream(vfe_dev, arg);
+		mutex_unlock(&vfe_dev->core_mutex);
 		break;
 	case VIDIOC_MSM_ISP_INPUT_CFG:
+		mutex_lock(&vfe_dev->core_mutex);
 		rc = msm_isp_cfg_input(vfe_dev, arg);
+		mutex_unlock(&vfe_dev->core_mutex);
 		break;
 	case VIDIOC_MSM_ISP_SET_SRC_STATE:
+		mutex_lock(&vfe_dev->core_mutex);
 		msm_isp_set_src_state(vfe_dev, arg);
+		mutex_unlock(&vfe_dev->core_mutex);
 		break;
 	case VIDIOC_MSM_ISP_REQUEST_STATS_STREAM:
+		mutex_lock(&vfe_dev->core_mutex);
 		rc = msm_isp_request_stats_stream(vfe_dev, arg);
+		mutex_unlock(&vfe_dev->core_mutex);
 		break;
 	case VIDIOC_MSM_ISP_RELEASE_STATS_STREAM:
+		mutex_lock(&vfe_dev->core_mutex);
 		rc = msm_isp_release_stats_stream(vfe_dev, arg);
+		mutex_unlock(&vfe_dev->core_mutex);
 		break;
 	case VIDIOC_MSM_ISP_CFG_STATS_STREAM:
+		mutex_lock(&vfe_dev->core_mutex);
 		rc = msm_isp_cfg_stats_stream(vfe_dev, arg);
+		mutex_unlock(&vfe_dev->core_mutex);
 		break;
 	case VIDIOC_MSM_ISP_CFG_STATS_COMP_POLICY:
+		mutex_lock(&vfe_dev->core_mutex);
 		rc = msm_isp_cfg_stats_comp_policy(vfe_dev, arg);
+		mutex_unlock(&vfe_dev->core_mutex);
 		break;
 	case VIDIOC_MSM_ISP_UPDATE_STREAM:
+		mutex_lock(&vfe_dev->core_mutex);
 		rc = msm_isp_update_axi_stream(vfe_dev, arg);
+		mutex_unlock(&vfe_dev->core_mutex);
 		break;
 	default:
 		pr_err("%s: Invalid ISP command\n", __func__);
 		rc = -EINVAL;
 	}
-
-	mutex_unlock(&vfe_dev->mutex);
 	return rc;
 }
 
@@ -623,23 +650,27 @@
 	long rc;
 	ISP_DBG("%s\n", __func__);
 
-	mutex_lock(&vfe_dev->mutex);
+	mutex_lock(&vfe_dev->realtime_mutex);
+	mutex_lock(&vfe_dev->core_mutex);
 	if (vfe_dev->vfe_open_cnt == 1) {
 		pr_err("VFE already open\n");
-		mutex_unlock(&vfe_dev->mutex);
+		mutex_unlock(&vfe_dev->core_mutex);
+		mutex_unlock(&vfe_dev->realtime_mutex);
 		return -ENODEV;
 	}
 
 	if (vfe_dev->hw_info->vfe_ops.core_ops.init_hw(vfe_dev) < 0) {
 		pr_err("%s: init hardware failed\n", __func__);
-		mutex_unlock(&vfe_dev->mutex);
+		mutex_unlock(&vfe_dev->core_mutex);
+		mutex_unlock(&vfe_dev->realtime_mutex);
 		return -EBUSY;
 	}
 
 	rc = vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev);
 	if (rc <= 0) {
 		pr_err("%s: reset timeout\n", __func__);
-		mutex_unlock(&vfe_dev->mutex);
+		mutex_unlock(&vfe_dev->core_mutex);
+		mutex_unlock(&vfe_dev->realtime_mutex);
 		return -EINVAL;
 	}
 	vfe_dev->vfe_hw_version = msm_camera_io_r(vfe_dev->vfe_base);
@@ -659,7 +690,8 @@
 	vfe_dev->axi_data.hw_info = vfe_dev->hw_info->axi_hw_info;
 	vfe_dev->vfe_open_cnt++;
 	vfe_dev->taskletq_idx = 0;
-	mutex_unlock(&vfe_dev->mutex);
+	mutex_unlock(&vfe_dev->core_mutex);
+	mutex_unlock(&vfe_dev->realtime_mutex);
 	return 0;
 }
 
@@ -669,10 +701,12 @@
 	long rc;
 	struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
 	ISP_DBG("%s\n", __func__);
-	mutex_lock(&vfe_dev->mutex);
+	mutex_lock(&vfe_dev->realtime_mutex);
+	mutex_lock(&vfe_dev->core_mutex);
 	if (vfe_dev->vfe_open_cnt == 0) {
 		pr_err("%s: Invalid close\n", __func__);
-		mutex_unlock(&vfe_dev->mutex);
+		mutex_unlock(&vfe_dev->core_mutex);
+		mutex_unlock(&vfe_dev->realtime_mutex);
 		return -ENODEV;
 	}
 
@@ -689,6 +723,7 @@
 	vfe_dev->hw_info->vfe_ops.core_ops.release_hw(vfe_dev);
 
 	vfe_dev->vfe_open_cnt--;
-	mutex_unlock(&vfe_dev->mutex);
+	mutex_unlock(&vfe_dev->core_mutex);
+	mutex_unlock(&vfe_dev->realtime_mutex);
 	return 0;
 }
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
index 22ce35b..d30afb2 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -503,6 +503,13 @@
 	BUG_ON(!ispif);
 	BUG_ON(!params);
 
+	if (ispif->ispif_state != ISPIF_POWER_UP) {
+		pr_err("%s: ispif invalid state %d\n", __func__,
+			ispif->ispif_state);
+		rc = -EPERM;
+		return rc;
+	}
+
 	rc = msm_ispif_clk_enable(ispif, params, 1);
 	if (rc < 0) {
 		pr_err("%s: unable to enable clocks", __func__);
@@ -653,6 +660,13 @@
 	BUG_ON(!ispif);
 	BUG_ON(!params);
 
+	if (ispif->ispif_state != ISPIF_POWER_UP) {
+		pr_err("%s: ispif invalid state %d\n", __func__,
+			ispif->ispif_state);
+		rc = -EPERM;
+		return rc;
+	}
+
 	msm_ispif_intf_cmd(ispif, ISPIF_INTF_CMD_DISABLE_IMMEDIATELY, params);
 
 	/* after stop the interface we need to unmask the CID enable bits */
@@ -671,6 +685,13 @@
 {
 	int rc;
 
+	if (ispif->ispif_state != ISPIF_POWER_UP) {
+		pr_err("%s: ispif invalid state %d\n", __func__,
+			ispif->ispif_state);
+		rc = -EPERM;
+		return rc;
+	}
+
 	rc = msm_ispif_clk_enable(ispif, params, 1);
 	if (rc < 0) {
 		pr_err("%s: unable to enable clocks", __func__);
@@ -703,6 +724,13 @@
 	BUG_ON(!params);
 
 
+	if (ispif->ispif_state != ISPIF_POWER_UP) {
+		pr_err("%s: ispif invalid state %d\n", __func__,
+			ispif->ispif_state);
+		rc = -EPERM;
+		return rc;
+	}
+
 	rc = msm_ispif_clk_enable(ispif, params, 1);
 	if (rc < 0) {
 		pr_err("%s: unable to enable clocks", __func__);
diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c
index fbc2b93..e50ac3a 100644
--- a/drivers/media/platform/msm/camera_v2/msm.c
+++ b/drivers/media/platform/msm/camera_v2/msm.c
@@ -277,6 +277,7 @@
 {
 	struct msm_session *session = NULL;
 	struct msm_stream  *stream = NULL;
+	unsigned long flags;
 
 	session = msm_queue_find(msm_session_q, struct msm_session,
 		list, __msm_queue_find_session, &session_id);
@@ -287,9 +288,10 @@
 		list, __msm_queue_find_stream, &stream_id);
 	if (!stream)
 		return;
-
+	spin_lock_irqsave(&(session->stream_q.lock), flags);
 	list_del_init(&stream->list);
 	session->stream_q.len--;
+	spin_unlock_irqrestore(&(session->stream_q.lock), flags);
 	kzfree(stream);
 }
 
@@ -426,6 +428,7 @@
 {
 	struct msm_session *session;
 	struct msm_command_ack *cmd_ack;
+	unsigned long flags;
 
 	session = msm_queue_find(msm_session_q, struct msm_session,
 		list, __msm_queue_find_session, &session_id);
@@ -439,6 +442,11 @@
 		return;
 
 	msm_queue_drain(&cmd_ack->command_q, struct msm_command, list);
+
+	spin_lock_irqsave(&(session->command_ack_q.lock), flags);
+	list_del_init(&cmd_ack->list);
+	session->command_ack_q.len--;
+	spin_unlock_irqrestore(&(session->command_ack_q.lock), flags);
 }
 
 static inline int __msm_v4l2_subdev_shutdown(struct v4l2_subdev *sd)
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index c06b009..2598b07 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -907,7 +907,7 @@
 	struct msm_queue_cmd *frame_qcmd)
 {
 	uint32_t i;
-	int32_t rc = -EINVAL;
+	int32_t rc = -EAGAIN;
 	struct msm_cpp_frame_info_t *process_frame;
 
 	if (cpp_dev->processing_q.len < MAX_CPP_PROCESSING_FRAME) {
@@ -921,6 +921,8 @@
 		do_gettimeofday(&(process_frame->in_time));
 		rc = 0;
 	}
+	if (rc < 0)
+		pr_err("process queue full. drop frame\n");
 	return rc;
 }
 
@@ -940,6 +942,9 @@
 	unsigned long in_phyaddr, out_phyaddr;
 	uint16_t num_stripes = 0;
 	struct msm_buf_mngr_info buff_mgr_info;
+	struct msm_cpp_frame_info_t *u_frame_info =
+		(struct msm_cpp_frame_info_t *)ioctl_ptr->ioctl_ptr;
+	int32_t status = 0;
 
 	int i = 0;
 	if (!new_frame) {
@@ -992,8 +997,8 @@
 	rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_GET_BUF,
 		&buff_mgr_info);
 	if (rc < 0) {
-		pr_err("error getting buffer\n");
-		rc = -EINVAL;
+		rc = -EAGAIN;
+		pr_err("error getting buffer rc:%d\n", rc);
 		goto ERROR2;
 	}
 
@@ -1036,6 +1041,15 @@
 		goto ERROR4;
 	}
 
+	ioctl_ptr->trans_code = rc;
+	status = rc;
+	rc = (copy_to_user((void __user *)u_frame_info->status, &status,
+		sizeof(int32_t)) ? -EFAULT : 0);
+	if (rc) {
+		ERR_COPY_FROM_USER();
+		rc = -EINVAL;
+		goto ERROR4;
+	}
 	return rc;
 ERROR4:
 	kfree(frame_qcmd);
@@ -1046,6 +1060,11 @@
 	kfree(cpp_frame_msg);
 ERROR1:
 	kfree(new_frame);
+	ioctl_ptr->trans_code = rc;
+	status = rc;
+	if (copy_to_user((void __user *)u_frame_info->status, &status,
+		sizeof(int32_t)))
+		pr_err("error cannot copy error\n");
 	return rc;
 }
 
diff --git a/drivers/media/platform/msm/camera_v2/sensor/Makefile b/drivers/media/platform/msm/camera_v2/sensor/Makefile
index b6708a3..5104bcb 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/Makefile
+++ b/drivers/media/platform/msm/camera_v2/sensor/Makefile
@@ -3,7 +3,7 @@
 ccflags-y += -Idrivers/media/platform/msm/camera_v2/camera
 ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
 ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/cci
-obj-$(CONFIG_MSMB_CAMERA) += cci/ io/ csiphy/ csid/ actuator/ flash/
+obj-$(CONFIG_MSMB_CAMERA) += cci/ io/ csiphy/ csid/ actuator/ flash/ eeprom/
 obj-$(CONFIG_MSM_CAMERA_SENSOR) += msm_sensor.o
 obj-$(CONFIG_S5K3L1YX) += s5k3l1yx.o
 obj-$(CONFIG_IMX135) += imx135.o
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
index 12ac4cb..9300ce0 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
@@ -39,6 +39,9 @@
 #define CDBG(fmt, args...) do { } while (0)
 #endif
 
+/* Max bytes that can be read per CCI read transaction */
+#define CCI_READ_MAX 12
+
 static struct v4l2_subdev *g_cci_subdev;
 
 static void msm_cci_set_clk_param(struct cci_device *cci_dev)
@@ -377,6 +380,61 @@
 	return rc;
 }
 
+static int32_t msm_cci_i2c_read_bytes(struct v4l2_subdev *sd,
+	struct msm_camera_cci_ctrl *c_ctrl)
+{
+	int32_t rc = 0;
+	struct cci_device *cci_dev = NULL;
+	enum cci_i2c_master_t master;
+	struct msm_camera_cci_i2c_read_cfg *read_cfg = NULL;
+	uint16_t read_bytes = 0;
+
+	if (!sd || !c_ctrl) {
+		pr_err("%s:%d sd %p c_ctrl %p\n", __func__,
+			__LINE__, sd, c_ctrl);
+		return -EINVAL;
+	}
+	if (!c_ctrl->cci_info) {
+		pr_err("%s:%d cci_info NULL\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+	cci_dev = v4l2_get_subdevdata(sd);
+	if (!cci_dev) {
+		pr_err("%s:%d cci_dev NULL\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+
+	master = c_ctrl->cci_info->cci_i2c_master;
+	read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg;
+	if (!read_cfg->num_byte) {
+		pr_err("%s:%d read num bytes 0\n", __func__, __LINE__);
+		rc = -EINVAL;
+		goto ERROR;
+	}
+
+	read_bytes = read_cfg->num_byte;
+	do {
+		if (read_bytes > CCI_READ_MAX)
+			read_cfg->num_byte = CCI_READ_MAX;
+		else
+			read_cfg->num_byte = read_bytes;
+		rc = msm_cci_i2c_read(sd, c_ctrl);
+		if (rc < 0) {
+			pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc);
+			goto ERROR;
+		}
+		if (read_bytes > CCI_READ_MAX) {
+			read_cfg->addr += CCI_READ_MAX;
+			read_cfg->data += CCI_READ_MAX;
+			read_bytes -= CCI_READ_MAX;
+		} else {
+			read_bytes = 0;
+		}
+	} while (read_bytes);
+ERROR:
+	return rc;
+}
+
 static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
 	struct msm_camera_cci_ctrl *c_ctrl)
 {
@@ -589,7 +647,7 @@
 		rc = msm_cci_i2c_config_sync_timer(sd, cci_ctrl);
 		break;
 	case MSM_CCI_I2C_READ:
-		rc = msm_cci_i2c_read(sd, cci_ctrl);
+		rc = msm_cci_i2c_read_bytes(sd, cci_ctrl);
 		break;
 	case MSM_CCI_I2C_WRITE:
 		rc = msm_cci_i2c_write(sd, cci_ctrl);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/eeprom/Makefile b/drivers/media/platform/msm/camera_v2/sensor/eeprom/Makefile
new file mode 100644
index 0000000..de843fb
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/eeprom/Makefile
@@ -0,0 +1,4 @@
+ccflags-y += -Idrivers/media/platform/msm/camera_v2
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/cci
+obj-$(CONFIG_MSM_EEPROM) += msm_eeprom.o
diff --git a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
new file mode 100644
index 0000000..47e672d
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c
@@ -0,0 +1,932 @@
+/* Copyright (c) 2011-2013, 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/module.h>
+#include <linux/of_gpio.h>
+#include <linux/delay.h>
+#include "msm_sd.h"
+#include "msm_cci.h"
+#include "msm_eeprom.h"
+
+#undef CDBG
+#ifdef MSM_EEPROM_DEBUG
+#define CDBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+#endif
+
+DEFINE_MSM_MUTEX(msm_eeprom_mutex);
+
+int32_t msm_eeprom_config(struct msm_eeprom_ctrl_t *e_ctrl,
+	void __user *argp)
+{
+	struct msm_eeprom_cfg_data *cdata =
+		(struct msm_eeprom_cfg_data *)argp;
+	int32_t rc = 0;
+
+	CDBG("%s E\n", __func__);
+	switch (cdata->cfgtype) {
+	case CFG_EEPROM_GET_INFO:
+	CDBG("%s E CFG_EEPROM_GET_INFO\n", __func__);
+		cdata->is_supported = e_ctrl->is_supported;
+		memcpy(cdata->cfg.eeprom_name,
+			e_ctrl->eboard_info->eeprom_name,
+			sizeof(cdata->cfg.eeprom_name));
+		break;
+	case CFG_EEPROM_GET_DATA:
+		CDBG("%s E CFG_EEPROM_GET_DATA\n", __func__);
+		cdata->cfg.get_data.num_bytes =
+			e_ctrl->num_bytes;
+		break;
+	case CFG_EEPROM_READ_DATA:
+		CDBG("%s E CFG_EEPROM_READ_DATA\n", __func__);
+		rc = copy_to_user(cdata->cfg.read_data.dbuffer,
+			e_ctrl->memory_data,
+			cdata->cfg.read_data.num_bytes);
+		break;
+	default:
+		break;
+	}
+
+	CDBG("%s X\n", __func__);
+	return rc;
+}
+static int32_t msm_eeprom_get_subdev_id(
+	struct msm_eeprom_ctrl_t *e_ctrl, void *arg)
+{
+	uint32_t *subdev_id = (uint32_t *)arg;
+	CDBG("%s E\n", __func__);
+	if (!subdev_id) {
+		pr_err("%s failed\n", __func__);
+		return -EINVAL;
+	}
+	*subdev_id = e_ctrl->subdev_id;
+	CDBG("subdev_id %d\n", *subdev_id);
+	CDBG("%s X\n", __func__);
+	return 0;
+}
+
+static long msm_eeprom_subdev_ioctl(struct v4l2_subdev *sd,
+		unsigned int cmd, void *arg)
+{
+	struct msm_eeprom_ctrl_t *e_ctrl = v4l2_get_subdevdata(sd);
+	void __user *argp = (void __user *)arg;
+	CDBG("%s E\n", __func__);
+	CDBG("%s:%d a_ctrl %p argp %p\n", __func__, __LINE__, e_ctrl, argp);
+	switch (cmd) {
+	case VIDIOC_MSM_SENSOR_GET_SUBDEV_ID:
+		return msm_eeprom_get_subdev_id(e_ctrl, argp);
+	case VIDIOC_MSM_EEPROM_CFG:
+		return msm_eeprom_config(e_ctrl, argp);
+	default:
+		return -ENOIOCTLCMD;
+	}
+
+	CDBG("%s X\n", __func__);
+}
+
+static struct msm_camera_i2c_fn_t msm_eeprom_cci_func_tbl = {
+	.i2c_read = msm_camera_cci_i2c_read,
+	.i2c_read_seq = msm_camera_cci_i2c_read_seq,
+	.i2c_write = msm_camera_cci_i2c_write,
+	.i2c_write_table = msm_camera_cci_i2c_write_table,
+	.i2c_write_seq_table = msm_camera_cci_i2c_write_seq_table,
+	.i2c_write_table_w_microdelay =
+	msm_camera_cci_i2c_write_table_w_microdelay,
+	.i2c_util = msm_sensor_cci_i2c_util,
+	.i2c_poll = msm_camera_cci_i2c_poll,
+};
+
+static struct msm_camera_i2c_fn_t msm_eeprom_qup_func_tbl = {
+	.i2c_read = msm_camera_qup_i2c_read,
+	.i2c_read_seq = msm_camera_qup_i2c_read_seq,
+	.i2c_write = msm_camera_qup_i2c_write,
+	.i2c_write_table = msm_camera_qup_i2c_write_table,
+	.i2c_write_seq_table = msm_camera_qup_i2c_write_seq_table,
+	.i2c_write_table_w_microdelay =
+	msm_camera_qup_i2c_write_table_w_microdelay,
+};
+
+static struct msm_camera_i2c_fn_t msm_eeprom_spi_func_tbl = {
+	.i2c_read = msm_camera_spi_read,
+	.i2c_read_seq = msm_camera_spi_read_seq,
+};
+
+static int msm_eeprom_open(struct v4l2_subdev *sd,
+	struct v4l2_subdev_fh *fh) {
+	int rc = 0;
+	struct msm_eeprom_ctrl_t *e_ctrl =  v4l2_get_subdevdata(sd);
+	CDBG("%s E\n", __func__);
+	if (!e_ctrl) {
+		pr_err("%s failed e_ctrl is NULL\n", __func__);
+		return -EINVAL;
+	}
+	if (e_ctrl->eeprom_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
+		rc = e_ctrl->i2c_client.i2c_func_tbl->i2c_util(
+		&e_ctrl->i2c_client, MSM_CCI_INIT);
+		if (rc < 0)
+			pr_err("%s cci_init failed\n", __func__);
+	}
+	CDBG("%s X\n", __func__);
+	return rc;
+}
+
+static int msm_eeprom_close(struct v4l2_subdev *sd,
+	struct v4l2_subdev_fh *fh) {
+	int rc = 0;
+	struct msm_eeprom_ctrl_t *e_ctrl =  v4l2_get_subdevdata(sd);
+	CDBG("%s E\n", __func__);
+	if (!e_ctrl) {
+		pr_err("%s failed e_ctrl is NULL\n", __func__);
+		return -EINVAL;
+	}
+	if (e_ctrl->eeprom_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
+		rc = e_ctrl->i2c_client.i2c_func_tbl->i2c_util(
+			&e_ctrl->i2c_client, MSM_CCI_RELEASE);
+		if (rc < 0)
+			pr_err("%s cci_init failed\n", __func__);
+	}
+	CDBG("%s X\n", __func__);
+	return rc;
+}
+
+static const struct v4l2_subdev_internal_ops msm_eeprom_internal_ops = {
+	.open = msm_eeprom_open,
+	.close = msm_eeprom_close,
+};
+
+int32_t read_eeprom_memory(struct msm_eeprom_ctrl_t *e_ctrl)
+{
+	int rc = 0;
+	int j;
+	uint8_t *memptr = NULL;
+	struct msm_eeprom_board_info *eb_info = NULL;
+	struct eeprom_memory_map_t *emap = NULL;
+	if (!e_ctrl) {
+		pr_err("%s e_ctrl is NULL", __func__);
+		rc = -1;
+		return rc;
+	}
+	memptr = e_ctrl->memory_data;
+	eb_info = e_ctrl->eboard_info;
+	emap = eb_info->eeprom_map;
+
+	for (j = 0; j < eb_info->num_blocks; j++) {
+		if (emap[j].page.valid_size) {
+			e_ctrl->i2c_client.addr_type = emap[j].page.addr_t;
+			rc = e_ctrl->i2c_client.i2c_func_tbl->i2c_write(
+				&(e_ctrl->i2c_client), emap[j].page.addr,
+				emap[j].page.data, emap[j].page.data_t);
+				msleep(emap[j].page.delay);
+			if (rc < 0) {
+				pr_err("%s: page write failed\n", __func__);
+				return rc;
+			}
+		}
+
+		if (emap[j].poll.valid_size) {
+			e_ctrl->i2c_client.addr_type = emap[j].poll.addr_t;
+			rc = e_ctrl->i2c_client.i2c_func_tbl->i2c_poll(
+				&(e_ctrl->i2c_client), emap[j].poll.addr,
+				emap[j].poll.data, emap[j].poll.data_t);
+				msleep(emap[j].poll.delay);
+			if (rc < 0) {
+				pr_err("%s: poll failed\n", __func__);
+				return rc;
+			}
+		}
+
+		if (emap[j].mem.valid_size) {
+			e_ctrl->i2c_client.addr_type = emap[j].mem.addr_t;
+			rc = e_ctrl->i2c_client.i2c_func_tbl->i2c_read_seq(
+				&(e_ctrl->i2c_client), emap[j].mem.addr,
+				memptr, emap[j].mem.valid_size);
+			if (rc < 0) {
+				pr_err("%s: read failed\n", __func__);
+				return rc;
+			}
+			memptr += emap[j].mem.valid_size;
+		}
+	}
+	return rc;
+}
+
+static int msm_eeprom_alloc_memory_map(struct msm_eeprom_ctrl_t *e_ctrl,
+				       struct device_node *of)
+{
+	int i, rc = 0;
+	char property[12];
+	uint32_t count = 6;
+	struct msm_eeprom_board_info *eb = e_ctrl->eboard_info;
+
+	rc = of_property_read_u32(of, "qcom,num-blocks", &eb->num_blocks);
+	CDBG("%s: qcom,num_blocks %d\n", __func__, eb->num_blocks);
+	if (rc < 0) {
+		pr_err("%s failed rc %d\n", __func__, rc);
+		return rc;
+	}
+
+	eb->eeprom_map = kzalloc((sizeof(struct eeprom_memory_map_t)
+				 * eb->num_blocks), GFP_KERNEL);
+
+	if (!eb->eeprom_map) {
+		pr_err("%s failed line %d\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < eb->num_blocks; i++) {
+		snprintf(property, 12, "qcom,page%d", i);
+		rc = of_property_read_u32_array(of, property,
+			(uint32_t *) &eb->eeprom_map[i].page, count);
+		if (rc < 0) {
+			pr_err("%s: failed %d\n", __func__, __LINE__);
+			goto out;
+		}
+
+		snprintf(property, 12, "qcom,poll%d", i);
+		rc = of_property_read_u32_array(of, property,
+			(uint32_t *) &eb->eeprom_map[i].poll, count);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto out;
+		}
+
+		snprintf(property, 12, "qcom,mem%d", i);
+		rc = of_property_read_u32_array(of, property,
+			(uint32_t *) &eb->eeprom_map[i].mem, count);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto out;
+		}
+		e_ctrl->num_bytes += eb->eeprom_map[i].mem.valid_size;
+	}
+
+	CDBG("%s num_bytes %d\n", __func__, e_ctrl->num_bytes);
+
+	e_ctrl->memory_data = kzalloc(e_ctrl->num_bytes, GFP_KERNEL);
+	if (!e_ctrl->memory_data) {
+		pr_err("%s failed line %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto out;
+	}
+	return rc;
+
+out:
+	kfree(eb->eeprom_map);
+	return rc;
+}
+
+static struct msm_cam_clk_info cam_8960_clk_info[] = {
+	[SENSOR_CAM_MCLK] = {"cam_clk", 24000000},
+};
+
+static struct msm_cam_clk_info cam_8974_clk_info[] = {
+	[SENSOR_CAM_MCLK] = {"cam_src_clk", 19200000},
+	[SENSOR_CAM_CLK] = {"cam_clk", 0},
+};
+
+static struct v4l2_subdev_core_ops msm_eeprom_subdev_core_ops = {
+	.ioctl = msm_eeprom_subdev_ioctl,
+};
+
+static struct v4l2_subdev_ops msm_eeprom_subdev_ops = {
+	.core = &msm_eeprom_subdev_core_ops,
+};
+
+int32_t msm_eeprom_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id) {
+	int rc = 0;
+	struct msm_eeprom_ctrl_t *e_ctrl = NULL;
+	struct msm_camera_power_ctrl_t *power_info = NULL;
+	CDBG("%s E\n", __func__);
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		pr_err("%s i2c_check_functionality failed\n", __func__);
+		goto probe_failure;
+	}
+
+	e_ctrl = kzalloc(sizeof(struct msm_eeprom_ctrl_t), GFP_KERNEL);
+	if (!e_ctrl) {
+		pr_err("%s:%d kzalloc failed\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+	e_ctrl->eeprom_v4l2_subdev_ops = &msm_eeprom_subdev_ops;
+	e_ctrl->eeprom_mutex = &msm_eeprom_mutex;
+	CDBG("%s client = %x\n", __func__, (unsigned int)client);
+	e_ctrl->eboard_info = (struct msm_eeprom_board_info *)(id->driver_data);
+	if (!e_ctrl->eboard_info) {
+		pr_err("%s:%d board info NULL\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+	power_info = &e_ctrl->eboard_info->power_info;
+	e_ctrl->i2c_client.client = client;
+
+	/* Set device type as I2C */
+	e_ctrl->eeprom_device_type = MSM_CAMERA_I2C_DEVICE;
+	e_ctrl->i2c_client.i2c_func_tbl = &msm_eeprom_qup_func_tbl;
+
+	if (e_ctrl->eboard_info->i2c_slaveaddr != 0)
+		e_ctrl->i2c_client.client->addr =
+					e_ctrl->eboard_info->i2c_slaveaddr;
+	power_info->clk_info = cam_8960_clk_info;
+	power_info->clk_info_size = ARRAY_SIZE(cam_8960_clk_info);
+	power_info->dev = &client->dev;
+
+	/*IMPLEMENT READING PART*/
+	/* Initialize sub device */
+	v4l2_i2c_subdev_init(&e_ctrl->msm_sd.sd,
+		e_ctrl->i2c_client.client,
+		e_ctrl->eeprom_v4l2_subdev_ops);
+	v4l2_set_subdevdata(&e_ctrl->msm_sd.sd, e_ctrl);
+	e_ctrl->msm_sd.sd.internal_ops = &msm_eeprom_internal_ops;
+	e_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	media_entity_init(&e_ctrl->msm_sd.sd.entity, 0, NULL, 0);
+	e_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	e_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_EEPROM;
+	msm_sd_register(&e_ctrl->msm_sd);
+	CDBG("%s success result=%d X\n", __func__, rc);
+	return rc;
+
+probe_failure:
+	pr_err("%s failed! rc = %d\n", __func__, rc);
+	return rc;
+}
+
+static int32_t msm_eeprom_i2c_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct msm_eeprom_ctrl_t  *e_ctrl;
+	if (!sd) {
+		pr_err("%s: Subdevice is NULL\n", __func__);
+		return 0;
+	}
+
+	e_ctrl = (struct msm_eeprom_ctrl_t *)v4l2_get_subdevdata(sd);
+	if (!e_ctrl) {
+		pr_err("%s: eeprom device is NULL\n", __func__);
+		return 0;
+	}
+
+	kfree(e_ctrl->memory_data);
+	if (e_ctrl->eboard_info) {
+		kfree(e_ctrl->eboard_info->power_info.gpio_conf);
+		kfree(e_ctrl->eboard_info->eeprom_map);
+	}
+	kfree(e_ctrl->eboard_info);
+	kfree(e_ctrl);
+	return 0;
+}
+
+#define msm_eeprom_spi_parse_cmd(spic, str, name, out, size)		\
+	{								\
+		if (of_property_read_u32_array(				\
+			spic->spi_master->dev.of_node,			\
+			str, out, size)) {				\
+			return -EFAULT;					\
+		} else {						\
+			spic->cmd_tbl.name.opcode = out[0];		\
+			spic->cmd_tbl.name.addr_len = out[1];		\
+			spic->cmd_tbl.name.dummy_len = out[2];		\
+		}							\
+	}
+
+static int msm_eeprom_spi_parse_of(struct msm_camera_spi_client *spic)
+{
+	int rc = -EFAULT;
+	uint32_t tmp[3];
+	msm_eeprom_spi_parse_cmd(spic, "qcom,spiop,read", read, tmp, 3);
+	msm_eeprom_spi_parse_cmd(spic, "qcom,spiop,readseq", read_seq, tmp, 3);
+	msm_eeprom_spi_parse_cmd(spic, "qcom,spiop,queryid", query_id, tmp, 3);
+
+	rc = of_property_read_u32_array(spic->spi_master->dev.of_node,
+					"qcom,eeprom-id", tmp, 2);
+	if (rc) {
+		pr_err("%s: Failed to get eeprom id\n", __func__);
+		return rc;
+	}
+	spic->mfr_id = tmp[0];
+	spic->device_id = tmp[1];
+
+	return 0;
+}
+
+static int msm_eeprom_check_id(struct msm_eeprom_ctrl_t *e_ctrl)
+{
+	int rc;
+	struct msm_camera_i2c_client *client = &e_ctrl->i2c_client;
+	uint8_t id[2];
+
+	rc = msm_camera_spi_query_id(client, 0, &id[0], 2);
+	if (rc)
+		return rc;
+	if (id[0] != client->spi_client->mfr_id
+		    || id[1] != client->spi_client->device_id) {
+		CDBG("%s: read 0x%x 0x%x, check 0x%x 0x%x\n", __func__, id[0],
+		     id[1], client->spi_client->mfr_id,
+		     client->spi_client->device_id);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int msm_eeprom_get_dt_data(struct msm_eeprom_ctrl_t *e_ctrl)
+{
+	int rc = 0, i = 0;
+	struct msm_eeprom_board_info *eb_info;
+	struct msm_camera_power_ctrl_t *power_info =
+		&e_ctrl->eboard_info->power_info;
+	struct spi_device *spi = e_ctrl->i2c_client.spi_client->spi_master;
+	struct device_node *of_node = spi->dev.of_node;
+	struct msm_camera_gpio_conf *gconf = NULL;
+	uint16_t gpio_array_size = 0;
+	uint16_t *gpio_array = NULL;
+
+	eb_info = e_ctrl->eboard_info;
+	rc = msm_camera_get_dt_power_setting_data(spi->dev.of_node,
+		  &power_info->power_setting, &power_info->power_setting_size);
+	if (rc)
+		return rc;
+
+	rc = msm_camera_get_dt_vreg_data(of_node, &power_info->cam_vreg,
+					     &power_info->num_vreg);
+	if (rc)
+		goto ERROR1;
+
+	power_info->gpio_conf = kzalloc(sizeof(struct msm_camera_gpio_conf),
+					GFP_KERNEL);
+	if (!power_info->gpio_conf) {
+		rc = -ENOMEM;
+		goto ERROR2;
+	}
+	gconf = power_info->gpio_conf;
+	gpio_array_size = of_gpio_count(of_node);
+	CDBG("%s gpio count %d\n", __func__, gpio_array_size);
+
+	if (gpio_array_size) {
+		gpio_array = kzalloc(sizeof(uint16_t) * gpio_array_size,
+			GFP_KERNEL);
+		if (!gpio_array) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR3;
+		}
+		for (i = 0; i < gpio_array_size; i++) {
+			gpio_array[i] = of_get_gpio(of_node, i);
+			CDBG("%s gpio_array[%d] = %d\n", __func__, i,
+				gpio_array[i]);
+		}
+
+		rc = msm_camera_get_dt_gpio_req_tbl(of_node, gconf,
+			gpio_array, gpio_array_size);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR4;
+		}
+
+		rc = msm_camera_init_gpio_pin_tbl(of_node, gconf,
+			gpio_array, gpio_array_size);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR4;
+		}
+		kfree(gpio_array);
+	}
+
+	return rc;
+ERROR4:
+	kfree(gpio_array);
+ERROR3:
+	kfree(power_info->gpio_conf);
+ERROR2:
+	kfree(power_info->cam_vreg);
+ERROR1:
+	kfree(power_info->power_setting);
+	return rc;
+}
+
+static int msm_eeprom_spi_setup(struct spi_device *spi)
+{
+	struct msm_eeprom_ctrl_t *e_ctrl = NULL;
+	struct msm_camera_i2c_client *client = NULL;
+	struct msm_camera_spi_client *spi_client;
+	struct msm_eeprom_board_info *eb_info;
+	struct msm_camera_power_ctrl_t *power_info = NULL;
+	int rc = 0;
+
+	e_ctrl = kzalloc(sizeof(struct msm_eeprom_ctrl_t), GFP_KERNEL);
+	if (!e_ctrl) {
+		pr_err("%s:%d kzalloc failed\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+	e_ctrl->eeprom_v4l2_subdev_ops = &msm_eeprom_subdev_ops;
+	e_ctrl->eeprom_mutex = &msm_eeprom_mutex;
+	client = &e_ctrl->i2c_client;
+	e_ctrl->is_supported = 0;
+
+	spi_client = kzalloc(sizeof(spi_client), GFP_KERNEL);
+	if (!spi_client) {
+		pr_err("%s:%d kzalloc failed\n", __func__, __LINE__);
+		kfree(e_ctrl);
+		return -ENOMEM;
+	}
+
+	rc = of_property_read_u32(spi->dev.of_node, "cell-index",
+				  &e_ctrl->subdev_id);
+	CDBG("cell-index %d, rc %d\n", e_ctrl->subdev_id, rc);
+	if (rc) {
+		pr_err("failed rc %d\n", rc);
+		return rc;
+	}
+
+	e_ctrl->eeprom_device_type = MSM_CAMERA_SPI_DEVICE;
+	client->spi_client = spi_client;
+	spi_client->spi_master = spi;
+	client->i2c_func_tbl = &msm_eeprom_spi_func_tbl;
+	client->addr_type = MSM_CAMERA_I2C_3B_ADDR;
+
+	eb_info = kzalloc(sizeof(eb_info), GFP_KERNEL);
+	if (!eb_info)
+		goto spi_free;
+	e_ctrl->eboard_info = eb_info;
+	rc = of_property_read_string(spi->dev.of_node, "qcom,eeprom-name",
+		&eb_info->eeprom_name);
+	CDBG("%s qcom,eeprom-name %s, rc %d\n", __func__,
+		eb_info->eeprom_name, rc);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto board_free;
+	}
+	power_info = &eb_info->power_info;
+
+	power_info->clk_info = cam_8974_clk_info;
+	power_info->clk_info_size = ARRAY_SIZE(cam_8974_clk_info);
+	power_info->dev = &spi->dev;
+
+	rc = msm_eeprom_get_dt_data(e_ctrl);
+	if (rc)
+		goto board_free;
+
+	/* set spi instruction info */
+	spi_client->retry_delay = 1;
+	spi_client->retries = 0;
+
+	if (msm_eeprom_spi_parse_of(spi_client)) {
+		dev_err(&spi->dev,
+			"%s: Error parsing device properties\n", __func__);
+		goto board_free;
+	}
+
+	rc = msm_eeprom_alloc_memory_map(e_ctrl, spi->dev.of_node);
+	if (rc)
+		goto board_free;
+
+	rc = msm_camera_power_up(power_info, e_ctrl->eeprom_device_type,
+		&e_ctrl->i2c_client);
+	if (rc) {
+		pr_err("failed rc %d\n", rc);
+		goto memmap_free;
+	}
+
+	/* check eeprom id */
+	rc = msm_eeprom_check_id(e_ctrl);
+	if (rc) {
+		CDBG("%s: eeprom not matching %d\n", __func__, rc);
+		goto power_down;
+	}
+	/* read eeprom */
+	rc = read_eeprom_memory(e_ctrl);
+	if (rc) {
+		dev_err(&spi->dev, "%s: read eeprom memory failed\n", __func__);
+		goto power_down;
+	}
+
+	rc = msm_camera_power_down(power_info, e_ctrl->eeprom_device_type,
+		&e_ctrl->i2c_client);
+	if (rc) {
+		pr_err("failed rc %d\n", rc);
+		goto memmap_free;
+	}
+
+	/* initiazlie subdev */
+	v4l2_spi_subdev_init(&e_ctrl->msm_sd.sd,
+		e_ctrl->i2c_client.spi_client->spi_master,
+		e_ctrl->eeprom_v4l2_subdev_ops);
+	v4l2_set_subdevdata(&e_ctrl->msm_sd.sd, e_ctrl);
+	e_ctrl->msm_sd.sd.internal_ops = &msm_eeprom_internal_ops;
+	e_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	media_entity_init(&e_ctrl->msm_sd.sd.entity, 0, NULL, 0);
+	e_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	e_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_EEPROM;
+	msm_sd_register(&e_ctrl->msm_sd);
+	e_ctrl->is_supported = 1;
+	CDBG("%s success result=%d X\n", __func__, rc);
+
+	return 0;
+
+power_down:
+	msm_camera_power_down(power_info, e_ctrl->eeprom_device_type,
+		&e_ctrl->i2c_client);
+memmap_free:
+	kfree(e_ctrl->eboard_info->eeprom_map);
+	kfree(e_ctrl->memory_data);
+board_free:
+	kfree(e_ctrl->eboard_info);
+spi_free:
+	kfree(spi_client);
+	return rc;
+}
+
+static int msm_eeprom_spi_probe(struct spi_device *spi)
+{
+	int irq, cs, cpha, cpol, cs_high;
+
+	CDBG("%s\n", __func__);
+	spi->bits_per_word = 8;
+	spi->mode = SPI_MODE_0;
+	spi_setup(spi);
+
+	irq = spi->irq;
+	cs = spi->chip_select;
+	cpha = (spi->mode & SPI_CPHA) ? 1 : 0;
+	cpol = (spi->mode & SPI_CPOL) ? 1 : 0;
+	cs_high = (spi->mode & SPI_CS_HIGH) ? 1 : 0;
+	dev_info(&spi->dev, "irq[%d] cs[%x] CPHA[%x] CPOL[%x] CS_HIGH[%x]\n",
+			irq, cs, cpha, cpol, cs_high);
+	dev_info(&spi->dev, "max_speed[%u]\n", spi->max_speed_hz);
+
+	return msm_eeprom_spi_setup(spi);
+}
+
+static int32_t msm_eeprom_spi_remove(struct spi_device *sdev)
+{
+	struct v4l2_subdev *sd = spi_get_drvdata(sdev);
+	struct msm_eeprom_ctrl_t  *e_ctrl;
+	if (!sd) {
+		pr_err("%s: Subdevice is NULL\n", __func__);
+		return 0;
+	}
+
+	e_ctrl = (struct msm_eeprom_ctrl_t *)v4l2_get_subdevdata(sd);
+	if (!e_ctrl) {
+		pr_err("%s: eeprom device is NULL\n", __func__);
+		return 0;
+	}
+
+	kfree(e_ctrl->i2c_client.spi_client);
+	kfree(e_ctrl->memory_data);
+	if (e_ctrl->eboard_info) {
+		kfree(e_ctrl->eboard_info->power_info.gpio_conf);
+		kfree(e_ctrl->eboard_info->eeprom_map);
+	}
+	kfree(e_ctrl->eboard_info);
+	kfree(e_ctrl);
+	return 0;
+}
+
+static int32_t msm_eeprom_platform_probe(struct platform_device *pdev)
+{
+	int32_t rc = 0;
+	int32_t j = 0;
+	uint32_t temp;
+
+	struct msm_camera_cci_client *cci_client = NULL;
+	struct msm_eeprom_ctrl_t *e_ctrl = NULL;
+	struct msm_eeprom_board_info *eb_info = NULL;
+	struct device_node *of_node = pdev->dev.of_node;
+	struct msm_camera_power_ctrl_t *power_info = NULL;
+
+	CDBG("%s E\n", __func__);
+
+	e_ctrl = kzalloc(sizeof(struct msm_eeprom_ctrl_t), GFP_KERNEL);
+	if (!e_ctrl) {
+		pr_err("%s:%d kzalloc failed\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+	e_ctrl->eeprom_v4l2_subdev_ops = &msm_eeprom_subdev_ops;
+	e_ctrl->eeprom_mutex = &msm_eeprom_mutex;
+
+	e_ctrl->is_supported = 0;
+	if (!of_node) {
+		pr_err("%s dev.of_node NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	rc = of_property_read_u32(of_node, "cell-index",
+		&pdev->id);
+	CDBG("cell-index %d, rc %d\n", pdev->id, rc);
+	if (rc < 0) {
+		pr_err("failed rc %d\n", rc);
+		return rc;
+	}
+	e_ctrl->subdev_id = pdev->id;
+
+	rc = of_property_read_u32(of_node, "qcom,cci-master",
+		&e_ctrl->cci_master);
+	CDBG("qcom,cci-master %d, rc %d\n", e_ctrl->cci_master, rc);
+	if (rc < 0) {
+		pr_err("%s failed rc %d\n", __func__, rc);
+		return rc;
+	}
+	rc = of_property_read_u32(of_node, "qcom,slave-addr",
+		&temp);
+	if (rc < 0) {
+		pr_err("%s failed rc %d\n", __func__, rc);
+		return rc;
+	}
+
+	/* Set platform device handle */
+	e_ctrl->pdev = pdev;
+	/* Set device type as platform device */
+	e_ctrl->eeprom_device_type = MSM_CAMERA_PLATFORM_DEVICE;
+	e_ctrl->i2c_client.i2c_func_tbl = &msm_eeprom_cci_func_tbl;
+	e_ctrl->i2c_client.cci_client = kzalloc(sizeof(
+		struct msm_camera_cci_client), GFP_KERNEL);
+	if (!e_ctrl->i2c_client.cci_client) {
+		pr_err("%s failed no memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	e_ctrl->eboard_info = kzalloc(sizeof(
+		struct msm_eeprom_board_info), GFP_KERNEL);
+	if (!e_ctrl->eboard_info) {
+		pr_err("%s failed line %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto cciclient_free;
+	}
+	eb_info = e_ctrl->eboard_info;
+	power_info = &eb_info->power_info;
+	eb_info->i2c_slaveaddr = temp;
+
+	power_info->clk_info = cam_8974_clk_info;
+	power_info->clk_info_size = ARRAY_SIZE(cam_8974_clk_info);
+	power_info->dev = &pdev->dev;
+
+	CDBG("qcom,slave-addr = 0x%X\n", eb_info->i2c_slaveaddr);
+	cci_client = e_ctrl->i2c_client.cci_client;
+	cci_client->cci_subdev = msm_cci_get_subdev();
+	cci_client->cci_i2c_master = e_ctrl->cci_master;
+	cci_client->sid = eb_info->i2c_slaveaddr >> 1;
+	cci_client->retries = 3;
+	cci_client->id_map = 0;
+
+	rc = of_property_read_string(of_node, "qcom,eeprom-name",
+		&eb_info->eeprom_name);
+	CDBG("%s qcom,eeprom-name %s, rc %d\n", __func__,
+		eb_info->eeprom_name, rc);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto board_free;
+	}
+
+	if (e_ctrl->eeprom_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
+		rc = e_ctrl->i2c_client.i2c_func_tbl->i2c_util(
+		&e_ctrl->i2c_client, MSM_CCI_INIT);
+		if (rc < 0)
+			pr_err("%s cci_init failed\n", __func__);
+	}
+
+	rc = msm_eeprom_alloc_memory_map(e_ctrl, of_node);
+	if (rc)
+		goto board_free;
+
+	rc = read_eeprom_memory(e_ctrl);
+	if (rc < 0) {
+		pr_err("%s read_eeprom_memory failed\n", __func__);
+		goto memdata_free;
+	}
+		pr_err("%s line %d\n", __func__, __LINE__);
+	for (j = 0; j < e_ctrl->num_bytes; j++)
+		CDBG("memory_data[%d] = 0x%X\n", j, e_ctrl->memory_data[j]);
+
+	v4l2_subdev_init(&e_ctrl->msm_sd.sd,
+		e_ctrl->eeprom_v4l2_subdev_ops);
+	v4l2_set_subdevdata(&e_ctrl->msm_sd.sd, e_ctrl);
+	platform_set_drvdata(pdev, &e_ctrl->msm_sd.sd);
+	e_ctrl->msm_sd.sd.internal_ops = &msm_eeprom_internal_ops;
+	e_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(e_ctrl->msm_sd.sd.name,
+		ARRAY_SIZE(e_ctrl->msm_sd.sd.name), "msm_eeprom");
+	media_entity_init(&e_ctrl->msm_sd.sd.entity, 0, NULL, 0);
+	e_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+	e_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_EEPROM;
+	msm_sd_register(&e_ctrl->msm_sd);
+
+
+	if (e_ctrl->eeprom_device_type == MSM_CAMERA_PLATFORM_DEVICE) {
+		rc = e_ctrl->i2c_client.i2c_func_tbl->i2c_util(
+			&e_ctrl->i2c_client, MSM_CCI_RELEASE);
+		if (rc < 0)
+			pr_err("%s cci_init failed\n", __func__);
+	}
+	e_ctrl->is_supported = 1;
+	CDBG("%s X\n", __func__);
+	return rc;
+
+memdata_free:
+	kfree(e_ctrl->memory_data);
+	kfree(eb_info->eeprom_map);
+board_free:
+	kfree(e_ctrl->eboard_info);
+cciclient_free:
+	kfree(e_ctrl->i2c_client.cci_client);
+	return rc;
+}
+
+static int32_t msm_eeprom_platform_remove(struct platform_device *pdev)
+{
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct msm_eeprom_ctrl_t  *e_ctrl;
+	if (!sd) {
+		pr_err("%s: Subdevice is NULL\n", __func__);
+		return 0;
+	}
+
+	e_ctrl = (struct msm_eeprom_ctrl_t *)v4l2_get_subdevdata(sd);
+	if (!e_ctrl) {
+		pr_err("%s: eeprom device is NULL\n", __func__);
+		return 0;
+	}
+
+	kfree(e_ctrl->i2c_client.cci_client);
+	kfree(e_ctrl->memory_data);
+	if (e_ctrl->eboard_info) {
+		kfree(e_ctrl->eboard_info->power_info.gpio_conf);
+		kfree(e_ctrl->eboard_info->eeprom_map);
+	}
+	kfree(e_ctrl->eboard_info);
+	kfree(e_ctrl);
+	return 0;
+}
+
+static const struct of_device_id msm_eeprom_dt_match[] = {
+	{ .compatible = "qcom,eeprom" },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(of, msm_eeprom_dt_match);
+
+static struct platform_driver msm_eeprom_platform_driver = {
+	.driver = {
+		.name = "qcom,eeprom",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_eeprom_dt_match,
+	},
+	.remove = __devexit_p(msm_eeprom_platform_remove),
+};
+
+static const struct i2c_device_id msm_eeprom_i2c_id[] = {
+	{ "msm_eeprom", (kernel_ulong_t)NULL},
+	{ }
+};
+
+static struct i2c_driver msm_eeprom_i2c_driver = {
+	.id_table = msm_eeprom_i2c_id,
+	.probe  = msm_eeprom_i2c_probe,
+	.remove = __devexit_p(msm_eeprom_i2c_remove),
+	.driver = {
+		.name = "msm_eeprom",
+	},
+};
+
+static struct spi_driver msm_eeprom_spi_driver = {
+	.driver = {
+		.name = "qcom_eeprom",
+		.owner = THIS_MODULE,
+		.of_match_table = msm_eeprom_dt_match,
+	},
+	.probe = msm_eeprom_spi_probe,
+	.remove = __devexit_p(msm_eeprom_spi_remove),
+};
+
+static int __init msm_eeprom_init_module(void)
+{
+	int32_t rc = 0;
+	CDBG("%s E\n", __func__);
+	rc = platform_driver_probe(&msm_eeprom_platform_driver,
+		msm_eeprom_platform_probe);
+	CDBG("%s:%d platform rc %d\n", __func__, __LINE__, rc);
+	rc = spi_register_driver(&msm_eeprom_spi_driver);
+	CDBG("%s:%d spi rc %d\n", __func__, __LINE__, rc);
+	return i2c_add_driver(&msm_eeprom_i2c_driver);
+}
+
+static void __exit msm_eeprom_exit_module(void)
+{
+	platform_driver_unregister(&msm_eeprom_platform_driver);
+	spi_unregister_driver(&msm_eeprom_spi_driver);
+	i2c_del_driver(&msm_eeprom_i2c_driver);
+}
+
+module_init(msm_eeprom_init_module);
+module_exit(msm_eeprom_exit_module);
+MODULE_DESCRIPTION("MSM EEPROM driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.h b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.h
new file mode 100644
index 0000000..cebe585
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.h
@@ -0,0 +1,48 @@
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef MSM_EEPROM_H
+#define MSM_EEPROM_H
+
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <mach/camera2.h>
+#include <media/v4l2-subdev.h>
+#include <media/msmb_camera.h>
+#include "msm_camera_i2c.h"
+#include "msm_camera_spi.h"
+#include "msm_camera_io_util.h"
+#include "msm_camera_dt_util.h"
+
+struct msm_eeprom_ctrl_t;
+
+#define DEFINE_MSM_MUTEX(mutexname) \
+	static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
+
+struct msm_eeprom_ctrl_t {
+	struct platform_device *pdev;
+	struct mutex *eeprom_mutex;
+
+	struct v4l2_subdev sdev;
+	struct v4l2_subdev_ops *eeprom_v4l2_subdev_ops;
+	enum msm_camera_device_type_t eeprom_device_type;
+	struct msm_sd_subdev msm_sd;
+	enum cci_i2c_master_t cci_master;
+
+	struct msm_camera_i2c_client i2c_client;
+	uint32_t num_bytes;
+	uint8_t *memory_data;
+	uint8_t is_supported;
+	struct msm_eeprom_board_info *eboard_info;
+	uint32_t subdev_id;
+};
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/Makefile b/drivers/media/platform/msm/camera_v2/sensor/io/Makefile
index f71b09d..0c7c191 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/Makefile
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/Makefile
@@ -1,3 +1,4 @@
 ccflags-y += -Idrivers/media/platform/msm/camera_v2/
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor
 ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/cci
-obj-$(CONFIG_MSMB_CAMERA)   += msm_camera_io_util.o msm_camera_cci_i2c.o msm_camera_qup_i2c.o msm_camera_i2c_mux.o
+obj-$(CONFIG_MSMB_CAMERA)   += msm_camera_io_util.o msm_camera_cci_i2c.o msm_camera_qup_i2c.o msm_camera_i2c_mux.o msm_camera_spi.o msm_camera_dt_util.o
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
index b07f04f..80b1ccb 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
@@ -28,7 +28,7 @@
 #define I2C_POLL_MAX_ITERATION 20
 
 int32_t msm_camera_cci_i2c_read(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t *data,
+	uint32_t addr, uint16_t *data,
 	enum msm_camera_i2c_data_type data_type)
 {
 	int32_t rc = -EFAULT;
@@ -64,10 +64,10 @@
 }
 
 int32_t msm_camera_cci_i2c_read_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte)
+	uint32_t addr, uint8_t *data, uint16_t num_byte)
 {
 	int32_t rc = -EFAULT;
-	unsigned char buf[client->addr_type+num_byte];
+	unsigned char *buf = NULL;
 	int i;
 	struct msm_camera_cci_ctrl cci_ctrl;
 
@@ -76,6 +76,11 @@
 		|| num_byte == 0)
 		return rc;
 
+	buf = kzalloc(num_byte, GFP_KERNEL);
+	if (!buf) {
+		pr_err("%s:%d no memory\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
 	cci_ctrl.cmd = MSM_CCI_I2C_READ;
 	cci_ctrl.cci_info = client->cci_client;
 	cci_ctrl.cfg.cci_i2c_read_cfg.addr = addr;
@@ -93,11 +98,12 @@
 		S_I2C_DBG("Byte %d: 0x%x\n", i, buf[i]);
 		S_I2C_DBG("Data: 0x%x\n", data[i]);
 	}
+	kfree(buf);
 	return rc;
 }
 
 int32_t msm_camera_cci_i2c_write(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
+	uint32_t addr, uint16_t data,
 	enum msm_camera_i2c_data_type data_type)
 {
 	int32_t rc = -EFAULT;
@@ -131,7 +137,7 @@
 }
 
 int32_t msm_camera_cci_i2c_write_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte)
+	uint32_t addr, uint8_t *data, uint16_t num_byte)
 {
 	int32_t rc = -EFAULT;
 	uint8_t i = 0;
@@ -272,7 +278,7 @@
 }
 
 static int32_t msm_camera_cci_i2c_compare(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
+	uint32_t addr, uint16_t data,
 	enum msm_camera_i2c_data_type data_type)
 {
 	int32_t rc;
@@ -327,8 +333,8 @@
 	return rc;
 }
 
-static int32_t msm_camera_cci_i2c_poll(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
+int32_t msm_camera_cci_i2c_poll(struct msm_camera_i2c_client *client,
+	uint32_t addr, uint16_t data,
 	enum msm_camera_i2c_data_type data_type)
 {
 	int32_t rc;
@@ -347,7 +353,7 @@
 }
 
 static int32_t msm_camera_cci_i2c_set_mask(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t mask,
+	uint32_t addr, uint16_t mask,
 	enum msm_camera_i2c_data_type data_type, uint16_t set_mask)
 {
 	int32_t rc;
@@ -376,7 +382,7 @@
 
 static int32_t msm_camera_cci_i2c_set_write_mask_data(
 	struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data, int16_t mask,
+	uint32_t addr, uint16_t data, int16_t mask,
 	enum msm_camera_i2c_data_type data_type)
 {
 	int32_t rc;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c
new file mode 100644
index 0000000..2511651
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c
@@ -0,0 +1,662 @@
+/* Copyright (c) 2013, 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 <mach/gpiomux.h>
+#include "msm_camera_dt_util.h"
+#include "msm_camera_io_util.h"
+#include "msm_camera_i2c_mux.h"
+#include "msm_cci.h"
+
+#undef CDBG
+#ifdef CONFIG_MSM_CAMERA_DT_DEBUG
+#define CDBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#endif
+
+int32_t msm_camera_get_dt_power_setting_data(struct device_node *of_node,
+	struct msm_sensor_power_setting **power_setting,
+	uint16_t *power_setting_size)
+{
+	int32_t rc = 0, i = 0;
+	int32_t count = 0;
+	const char *seq_name = NULL;
+	uint32_t *array = NULL;
+	struct msm_sensor_power_setting *ps;
+
+	if (!power_setting || !power_setting_size)
+		return -EINVAL;
+
+	count = of_property_count_strings(of_node, "qcom,cam-power-seq-type");
+	*power_setting_size = count;
+	CDBG("%s qcom,cam-power-seq-type count %d\n", __func__, count);
+
+	if (count <= 0)
+		return 0;
+
+	ps = kzalloc(sizeof(struct msm_sensor_power_setting) * count,
+		GFP_KERNEL);
+	if (!ps) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+	*power_setting = ps;
+
+	for (i = 0; i < count; i++) {
+		rc = of_property_read_string_index(of_node,
+			"qcom,cam-power-seq-type", i,
+			&seq_name);
+		CDBG("%s seq_name[%d] = %s\n", __func__, i,
+			seq_name);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR1;
+		}
+		if (!strcmp(seq_name, "sensor_vreg")) {
+			ps[i].seq_type = SENSOR_VREG;
+			CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__,
+				i, ps[i].seq_type);
+		} else if (!strcmp(seq_name, "sensor_gpio")) {
+			ps[i].seq_type = SENSOR_GPIO;
+			CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__,
+				i, ps[i].seq_type);
+		} else if (!strcmp(seq_name, "sensor_clk")) {
+			ps[i].seq_type = SENSOR_CLK;
+			CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__,
+				i, ps[i].seq_type);
+		} else if (!strcmp(seq_name, "sensor_i2c_mux")) {
+			ps[i].seq_type = SENSOR_I2C_MUX;
+			CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__,
+				i, ps[i].seq_type);
+		}
+	}
+
+
+	for (i = 0; i < count; i++) {
+		rc = of_property_read_string_index(of_node,
+			"qcom,cam-power-seq-val", i,
+			&seq_name);
+		CDBG("%s seq_name[%d] = %s\n", __func__, i,
+			seq_name);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR1;
+		}
+		if (!strcmp(seq_name, "cam_vdig"))
+			ps[i].seq_val = CAM_VDIG;
+		else if (!strcmp(seq_name, "cam_vio"))
+			ps[i].seq_val = CAM_VIO;
+		else if (!strcmp(seq_name, "cam_vana"))
+			ps[i].seq_val = CAM_VANA;
+		else if (!strcmp(seq_name, "cam_vaf"))
+			ps[i].seq_val = CAM_VAF;
+		else if (!strcmp(seq_name, "sensor_gpio_reset"))
+			ps[i].seq_val = SENSOR_GPIO_RESET;
+		else if (!strcmp(seq_name, "sensor_gpio_standby"))
+			ps[i].seq_val = SENSOR_GPIO_STANDBY;
+		else if (!strcmp(seq_name, "sensor_cam_mclk"))
+			ps[i].seq_val = SENSOR_CAM_MCLK;
+		else if (!strcmp(seq_name, "sensor_cam_clk"))
+			ps[i].seq_val = SENSOR_CAM_CLK;
+		else if (!strcmp(seq_name, "none"))
+			ps[i].seq_val = 0;
+	}
+
+	array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+	if (!array) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+
+
+	rc = of_property_read_u32_array(of_node, "qcom,cam-power-seq-cfg-val",
+		array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		if (ps[i].seq_type == SENSOR_GPIO) {
+			if (array[i] == 0)
+				ps[i].config_val = GPIO_OUT_LOW;
+			else if (array[i] == 1)
+				ps[i].config_val = GPIO_OUT_HIGH;
+		} else {
+			ps[i].config_val = array[i];
+		}
+		CDBG("%s power_setting[%d].config_val = %ld\n", __func__, i,
+			ps[i].config_val);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,cam-power-seq-delay",
+		array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		ps[i].delay = array[i];
+		CDBG("%s power_setting[%d].delay = %d\n", __func__,
+			i, ps[i].delay);
+	}
+	kfree(array);
+	return rc;
+ERROR2:
+	kfree(array);
+ERROR1:
+	kfree(ps);
+	power_setting_size = 0;
+	return rc;
+}
+
+int32_t msm_camera_get_dt_gpio_req_tbl(struct device_node *of_node,
+	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
+	uint16_t gpio_array_size)
+{
+	int32_t rc = 0, i = 0;
+	uint32_t count = 0;
+	uint32_t *val_array = NULL;
+
+	if (!of_get_property(of_node, "qcom,gpio-req-tbl-num", &count))
+		return 0;
+
+	count /= sizeof(uint32_t);
+	if (!count) {
+		pr_err("%s qcom,gpio-req-tbl-num 0\n", __func__);
+		return 0;
+	}
+
+	val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+	if (!val_array) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	gconf->cam_gpio_req_tbl = kzalloc(sizeof(struct gpio) * count,
+		GFP_KERNEL);
+	if (!gconf->cam_gpio_req_tbl) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+	gconf->cam_gpio_req_tbl_size = count;
+
+	rc = of_property_read_u32_array(of_node, "qcom,gpio-req-tbl-num",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		if (val_array[i] >= gpio_array_size) {
+			pr_err("%s gpio req tbl index %d invalid\n",
+				__func__, val_array[i]);
+			return -EINVAL;
+		}
+		gconf->cam_gpio_req_tbl[i].gpio = gpio_array[val_array[i]];
+		CDBG("%s cam_gpio_req_tbl[%d].gpio = %d\n", __func__, i,
+			gconf->cam_gpio_req_tbl[i].gpio);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,gpio-req-tbl-flags",
+		val_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		gconf->cam_gpio_req_tbl[i].flags = val_array[i];
+		CDBG("%s cam_gpio_req_tbl[%d].flags = %ld\n", __func__, i,
+			gconf->cam_gpio_req_tbl[i].flags);
+	}
+
+	for (i = 0; i < count; i++) {
+		rc = of_property_read_string_index(of_node,
+			"qcom,gpio-req-tbl-label", i,
+			&gconf->cam_gpio_req_tbl[i].label);
+		CDBG("%s cam_gpio_req_tbl[%d].label = %s\n", __func__, i,
+			gconf->cam_gpio_req_tbl[i].label);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR2;
+		}
+	}
+
+	kfree(val_array);
+	return rc;
+
+ERROR2:
+	kfree(gconf->cam_gpio_req_tbl);
+ERROR1:
+	kfree(val_array);
+	gconf->cam_gpio_req_tbl_size = 0;
+	return rc;
+}
+
+int32_t msm_camera_init_gpio_pin_tbl(struct device_node *of_node,
+	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
+	uint16_t gpio_array_size)
+{
+	int32_t rc = 0;
+	int32_t val = 0;
+
+	gconf->gpio_num_info = kzalloc(sizeof(struct msm_camera_gpio_num_info),
+		GFP_KERNEL);
+	if (!gconf->gpio_num_info) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	if (of_property_read_bool(of_node, "qcom,gpio-reset") == true) {
+		rc = of_property_read_u32(of_node, "qcom,gpio-reset", &val);
+		if (rc < 0) {
+			pr_err("%s:%d read qcom,gpio-reset failed rc %d\n",
+				__func__, __LINE__, rc);
+			goto ERROR;
+		} else if (val >= gpio_array_size) {
+			pr_err("%s:%d qcom,gpio-reset invalid %d\n",
+				__func__, __LINE__, val);
+			goto ERROR;
+		}
+		gconf->gpio_num_info->gpio_num[SENSOR_GPIO_RESET] =
+			gpio_array[val];
+		CDBG("%s qcom,gpio-reset %d\n", __func__,
+			gconf->gpio_num_info->gpio_num[SENSOR_GPIO_RESET]);
+	}
+
+	if (of_property_read_bool(of_node, "qcom,gpio-standby") == true) {
+		rc = of_property_read_u32(of_node, "qcom,gpio-standby", &val);
+		if (rc < 0) {
+			pr_err("%s:%d read qcom,gpio-standby failed rc %d\n",
+				__func__, __LINE__, rc);
+			goto ERROR;
+		} else if (val >= gpio_array_size) {
+			pr_err("%s:%d qcom,gpio-standby invalid %d\n",
+				__func__, __LINE__, val);
+			goto ERROR;
+		}
+		gconf->gpio_num_info->gpio_num[SENSOR_GPIO_STANDBY] =
+			gpio_array[val];
+		CDBG("%s qcom,gpio-reset %d\n", __func__,
+			gconf->gpio_num_info->gpio_num[SENSOR_GPIO_STANDBY]);
+	}
+	return rc;
+
+ERROR:
+	kfree(gconf->gpio_num_info);
+	gconf->gpio_num_info = NULL;
+	return rc;
+}
+
+int32_t msm_camera_get_dt_vreg_data(struct device_node *of_node,
+	struct camera_vreg_t **cam_vreg, int *num_vreg)
+{
+	int32_t rc = 0, i = 0;
+	uint32_t count = 0;
+	uint32_t *vreg_array = NULL;
+	struct camera_vreg_t *vreg = NULL;
+
+	count = of_property_count_strings(of_node, "qcom,cam-vreg-name");
+	CDBG("%s qcom,cam-vreg-name count %d\n", __func__, count);
+
+	if (!count)
+		return 0;
+
+	vreg = kzalloc(sizeof(struct camera_vreg_t) * count,
+		GFP_KERNEL);
+	if (!vreg) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+	*cam_vreg = vreg;
+	*num_vreg = count;
+	for (i = 0; i < count; i++) {
+		rc = of_property_read_string_index(of_node,
+			"qcom,cam-vreg-name", i,
+			&vreg[i].reg_name);
+		CDBG("%s reg_name[%d] = %s\n", __func__, i,
+			vreg[i].reg_name);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR1;
+		}
+	}
+
+	vreg_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
+	if (!vreg_array) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		rc = -ENOMEM;
+		goto ERROR1;
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-type",
+		vreg_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		vreg[i].type = vreg_array[i];
+		CDBG("%s cam_vreg[%d].type = %d\n", __func__, i,
+			vreg[i].type);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-min-voltage",
+		vreg_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		vreg[i].min_voltage = vreg_array[i];
+		CDBG("%s cam_vreg[%d].min_voltage = %d\n", __func__,
+			i, vreg[i].min_voltage);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-max-voltage",
+		vreg_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		vreg[i].max_voltage = vreg_array[i];
+		CDBG("%s cam_vreg[%d].max_voltage = %d\n", __func__,
+			i, vreg[i].max_voltage);
+	}
+
+	rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-op-mode",
+		vreg_array, count);
+	if (rc < 0) {
+		pr_err("%s failed %d\n", __func__, __LINE__);
+		goto ERROR2;
+	}
+	for (i = 0; i < count; i++) {
+		vreg[i].op_mode = vreg_array[i];
+		CDBG("%s cam_vreg[%d].op_mode = %d\n", __func__, i,
+			vreg[i].op_mode);
+	}
+
+	kfree(vreg_array);
+	return rc;
+ERROR2:
+	kfree(vreg_array);
+ERROR1:
+	kfree(vreg);
+	*num_vreg = 0;
+	return rc;
+}
+
+static int32_t msm_camera_enable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
+{
+	struct v4l2_subdev *i2c_mux_sd =
+		dev_get_drvdata(&i2c_conf->mux_dev->dev);
+	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+		VIDIOC_MSM_I2C_MUX_INIT, NULL);
+	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+		VIDIOC_MSM_I2C_MUX_CFG, (void *)&i2c_conf->i2c_mux_mode);
+	return 0;
+}
+
+static int32_t msm_camera_disable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
+{
+	struct v4l2_subdev *i2c_mux_sd =
+		dev_get_drvdata(&i2c_conf->mux_dev->dev);
+	v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+		VIDIOC_MSM_I2C_MUX_RELEASE, NULL);
+	return 0;
+}
+
+int32_t msm_camera_power_up(struct msm_camera_power_ctrl_t *ctrl,
+	enum msm_camera_device_type_t device_type,
+	struct msm_camera_i2c_client *sensor_i2c_client)
+{
+	int32_t rc = 0, index = 0, no_gpio = 0;
+	struct msm_sensor_power_setting *power_setting = NULL;
+
+	CDBG("%s:%d\n", __func__, __LINE__);
+	if (!ctrl || !sensor_i2c_client) {
+		pr_err("failed ctrl %p sensor_i2c_client %p\n", ctrl,
+			sensor_i2c_client);
+		return -EINVAL;
+	}
+	if (ctrl->gpio_conf->cam_gpiomux_conf_tbl != NULL) {
+		pr_err("%s:%d mux install\n", __func__, __LINE__);
+		msm_gpiomux_install(
+			(struct msm_gpiomux_config *)
+			ctrl->gpio_conf->cam_gpiomux_conf_tbl,
+			ctrl->gpio_conf->cam_gpiomux_conf_tbl_size);
+	}
+
+	rc = msm_camera_request_gpio_table(
+		ctrl->gpio_conf->cam_gpio_req_tbl,
+		ctrl->gpio_conf->cam_gpio_req_tbl_size, 1);
+	if (rc < 0)
+		no_gpio = rc;
+
+	for (index = 0; index < ctrl->power_setting_size; index++) {
+		CDBG("%s index %d\n", __func__, index);
+		power_setting = &ctrl->power_setting[index];
+		CDBG("%s type %d\n", __func__, power_setting->seq_type);
+		switch (power_setting->seq_type) {
+		case SENSOR_CLK:
+			if (power_setting->seq_val >= ctrl->clk_info_size) {
+				pr_err("%s clk index %d >= max %d\n", __func__,
+					power_setting->seq_val,
+					ctrl->clk_info_size);
+				goto power_up_failed;
+			}
+			if (power_setting->config_val)
+				ctrl->clk_info[power_setting->seq_val].
+					clk_rate = power_setting->config_val;
+
+			rc = msm_cam_clk_enable(ctrl->dev,
+				&ctrl->clk_info[0],
+				(struct clk **)&power_setting->data[0],
+				ctrl->clk_info_size,
+				1);
+			if (rc < 0) {
+				pr_err("%s: clk enable failed\n",
+					__func__);
+				goto power_up_failed;
+			}
+			break;
+		case SENSOR_GPIO:
+			if (no_gpio) {
+				pr_err("%s: request gpio failed\n", __func__);
+				return no_gpio;
+			}
+			if (power_setting->seq_val >= SENSOR_GPIO_MAX ||
+				!ctrl->gpio_conf->gpio_num_info) {
+				pr_err("%s gpio index %d >= max %d\n", __func__,
+					power_setting->seq_val,
+					SENSOR_GPIO_MAX);
+				goto power_up_failed;
+			}
+			pr_debug("%s:%d gpio set val %d\n", __func__, __LINE__,
+				ctrl->gpio_conf->gpio_num_info->gpio_num
+				[power_setting->seq_val]);
+			gpio_set_value_cansleep(
+				ctrl->gpio_conf->gpio_num_info->gpio_num
+				[power_setting->seq_val],
+				power_setting->config_val);
+			break;
+		case SENSOR_VREG:
+			if (power_setting->seq_val >= CAM_VREG_MAX) {
+				pr_err("%s vreg index %d >= max %d\n", __func__,
+					power_setting->seq_val,
+					SENSOR_GPIO_MAX);
+				goto power_up_failed;
+			}
+			msm_camera_config_single_vreg(ctrl->dev,
+				&ctrl->cam_vreg[power_setting->seq_val],
+				(struct regulator **)&power_setting->data[0],
+				1);
+			break;
+		case SENSOR_I2C_MUX:
+			if (ctrl->i2c_conf && ctrl->i2c_conf->use_i2c_mux)
+				msm_camera_enable_i2c_mux(ctrl->i2c_conf);
+			break;
+		default:
+			pr_err("%s error power seq type %d\n", __func__,
+				power_setting->seq_type);
+			break;
+		}
+		if (power_setting->delay > 20) {
+			msleep(power_setting->delay);
+		} else if (power_setting->delay) {
+			usleep_range(power_setting->delay * 1000,
+				(power_setting->delay * 1000) + 1000);
+		}
+	}
+
+	if (device_type == MSM_CAMERA_PLATFORM_DEVICE) {
+		rc = sensor_i2c_client->i2c_func_tbl->i2c_util(
+			sensor_i2c_client, MSM_CCI_INIT);
+		if (rc < 0) {
+			pr_err("%s cci_init failed\n", __func__);
+			goto power_up_failed;
+		}
+	}
+
+	CDBG("%s exit\n", __func__);
+	return 0;
+power_up_failed:
+	pr_err("%s:%d failed\n", __func__, __LINE__);
+	if (device_type == MSM_CAMERA_PLATFORM_DEVICE) {
+		sensor_i2c_client->i2c_func_tbl->i2c_util(
+			sensor_i2c_client, MSM_CCI_RELEASE);
+	}
+
+	for (index--; index >= 0; index--) {
+		CDBG("%s index %d\n", __func__, index);
+		power_setting = &ctrl->power_setting[index];
+		CDBG("%s type %d\n", __func__, power_setting->seq_type);
+		switch (power_setting->seq_type) {
+		case SENSOR_CLK:
+			msm_cam_clk_enable(ctrl->dev,
+				&ctrl->clk_info[0],
+				(struct clk **)&power_setting->data[0],
+				ctrl->clk_info_size,
+				0);
+			break;
+		case SENSOR_GPIO:
+			gpio_set_value_cansleep(
+				ctrl->gpio_conf->gpio_num_info->gpio_num
+				[power_setting->seq_val], GPIOF_OUT_INIT_LOW);
+			break;
+		case SENSOR_VREG:
+			msm_camera_config_single_vreg(ctrl->dev,
+				&ctrl->cam_vreg[power_setting->seq_val],
+				(struct regulator **)&power_setting->data[0],
+				0);
+			break;
+		case SENSOR_I2C_MUX:
+			if (ctrl->i2c_conf && ctrl->i2c_conf->use_i2c_mux)
+				msm_camera_disable_i2c_mux(ctrl->i2c_conf);
+			break;
+		default:
+			pr_err("%s error power seq type %d\n", __func__,
+				power_setting->seq_type);
+			break;
+		}
+		if (power_setting->delay > 20) {
+			msleep(power_setting->delay);
+		} else if (power_setting->delay) {
+			usleep_range(power_setting->delay * 1000,
+				(power_setting->delay * 1000) + 1000);
+		}
+	}
+	msm_camera_request_gpio_table(
+		ctrl->gpio_conf->cam_gpio_req_tbl,
+		ctrl->gpio_conf->cam_gpio_req_tbl_size, 0);
+	return rc;
+}
+
+int32_t msm_camera_power_down(struct msm_camera_power_ctrl_t *ctrl,
+	enum msm_camera_device_type_t device_type,
+	struct msm_camera_i2c_client *sensor_i2c_client)
+{
+	int32_t index = 0;
+	struct msm_sensor_power_setting *power_setting = NULL;
+
+	CDBG("%s:%d\n", __func__, __LINE__);
+	if (!ctrl || !sensor_i2c_client) {
+		pr_err("failed ctrl %p sensor_i2c_client %p\n", ctrl,
+			sensor_i2c_client);
+		return -EINVAL;
+	}
+
+	if (device_type == MSM_CAMERA_PLATFORM_DEVICE)
+		sensor_i2c_client->i2c_func_tbl->i2c_util(
+			sensor_i2c_client, MSM_CCI_RELEASE);
+
+	for (index = (ctrl->power_setting_size - 1); index >= 0; index--) {
+		CDBG("%s index %d\n", __func__, index);
+		power_setting = &ctrl->power_setting[index];
+		CDBG("%s type %d\n", __func__, power_setting->seq_type);
+		switch (power_setting->seq_type) {
+		case SENSOR_CLK:
+			msm_cam_clk_enable(ctrl->dev,
+				&ctrl->clk_info[0],
+				(struct clk **)&power_setting->data[0],
+				ctrl->clk_info_size,
+				0);
+			break;
+		case SENSOR_GPIO:
+			if (power_setting->seq_val >= SENSOR_GPIO_MAX ||
+				!ctrl->gpio_conf->gpio_num_info) {
+				pr_err("%s gpio index %d >= max %d\n", __func__,
+					power_setting->seq_val,
+					SENSOR_GPIO_MAX);
+				continue;
+			}
+			gpio_set_value_cansleep(
+				ctrl->gpio_conf->gpio_num_info->gpio_num
+				[power_setting->seq_val], GPIOF_OUT_INIT_LOW);
+			break;
+		case SENSOR_VREG:
+			if (power_setting->seq_val >= CAM_VREG_MAX) {
+				pr_err("%s vreg index %d >= max %d\n", __func__,
+					power_setting->seq_val,
+					SENSOR_GPIO_MAX);
+				continue;
+			}
+			msm_camera_config_single_vreg(ctrl->dev,
+				&ctrl->cam_vreg[power_setting->seq_val],
+				(struct regulator **)&power_setting->data[0],
+				0);
+			break;
+		case SENSOR_I2C_MUX:
+			if (ctrl->i2c_conf && ctrl->i2c_conf->use_i2c_mux)
+				msm_camera_disable_i2c_mux(ctrl->i2c_conf);
+			break;
+		default:
+			pr_err("%s error power seq type %d\n", __func__,
+				power_setting->seq_type);
+			break;
+		}
+		if (power_setting->delay > 20) {
+			msleep(power_setting->delay);
+		} else if (power_setting->delay) {
+			usleep_range(power_setting->delay * 1000,
+				(power_setting->delay * 1000) + 1000);
+		}
+	}
+	msm_camera_request_gpio_table(
+		ctrl->gpio_conf->cam_gpio_req_tbl,
+		ctrl->gpio_conf->cam_gpio_req_tbl_size, 0);
+	CDBG("%s exit\n", __func__);
+	return 0;
+}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.h
new file mode 100644
index 0000000..5a35747
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.h
@@ -0,0 +1,44 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_CAMERA_DT_UTIL_H__
+#define MSM_CAMERA_DT_UTIL_H__
+
+#include <mach/camera2.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include "msm_camera_i2c.h"
+
+int32_t msm_camera_get_dt_power_setting_data(struct device_node *of_node,
+	struct msm_sensor_power_setting **power_setting,
+	uint16_t *power_setting_size);
+
+int32_t msm_camera_get_dt_gpio_req_tbl(struct device_node *of_node,
+	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
+	uint16_t gpio_array_size);
+
+int32_t msm_camera_init_gpio_pin_tbl(struct device_node *of_node,
+	struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array,
+	uint16_t gpio_array_size);
+
+int32_t msm_camera_get_dt_vreg_data(struct device_node *of_node,
+	struct camera_vreg_t **cam_vreg, int *num_vreg);
+
+int32_t msm_camera_power_up(struct msm_camera_power_ctrl_t *ctrl,
+	enum msm_camera_device_type_t device_type,
+	struct msm_camera_i2c_client *sensor_i2c_client);
+
+int32_t msm_camera_power_down(struct msm_camera_power_ctrl_t *ctrl,
+	enum msm_camera_device_type_t device_type,
+	struct msm_camera_i2c_client *sensor_i2c_client);
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h
index 26f1c4f..b1331ab 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h
@@ -21,6 +21,7 @@
 	struct msm_camera_i2c_fn_t *i2c_func_tbl;
 	struct i2c_client *client;
 	struct msm_camera_cci_client *cci_client;
+	struct msm_camera_spi_client *spi_client;
 	enum msm_camera_i2c_reg_addr_type addr_type;
 };
 
@@ -31,13 +32,13 @@
 };
 
 struct msm_camera_i2c_fn_t {
-	int (*i2c_read) (struct msm_camera_i2c_client *, uint16_t, uint16_t *,
+	int (*i2c_read) (struct msm_camera_i2c_client *, uint32_t, uint16_t *,
 		enum msm_camera_i2c_data_type);
-	int32_t (*i2c_read_seq)(struct msm_camera_i2c_client *, uint16_t,
+	int32_t (*i2c_read_seq)(struct msm_camera_i2c_client *, uint32_t,
 		uint8_t *, uint16_t);
-	int (*i2c_write) (struct msm_camera_i2c_client *, uint16_t, uint16_t,
+	int (*i2c_write) (struct msm_camera_i2c_client *, uint32_t, uint16_t,
 		enum msm_camera_i2c_data_type);
-	int (*i2c_write_seq) (struct msm_camera_i2c_client *, uint16_t ,
+	int (*i2c_write_seq) (struct msm_camera_i2c_client *, uint32_t ,
 		uint8_t *, uint16_t);
 	int32_t (*i2c_write_table)(struct msm_camera_i2c_client *,
 		struct msm_camera_i2c_reg_setting *);
@@ -51,21 +52,24 @@
 	int32_t (*i2c_write_conf_tbl)(struct msm_camera_i2c_client *client,
 		struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
 		enum msm_camera_i2c_data_type data_type);
+	int32_t (*i2c_poll)(struct msm_camera_i2c_client *client,
+		uint32_t addr, uint16_t data,
+		enum msm_camera_i2c_data_type data_type);
 };
 
 int32_t msm_camera_cci_i2c_read(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t *data,
+	uint32_t addr, uint16_t *data,
 	enum msm_camera_i2c_data_type data_type);
 
 int32_t msm_camera_cci_i2c_read_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte);
+	uint32_t addr, uint8_t *data, uint16_t num_byte);
 
 int32_t msm_camera_cci_i2c_write(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
+	uint32_t addr, uint16_t data,
 	enum msm_camera_i2c_data_type data_type);
 
 int32_t msm_camera_cci_i2c_write_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte);
+	uint32_t addr, uint8_t *data, uint16_t num_byte);
 
 int32_t msm_camera_cci_i2c_write_table(
 	struct msm_camera_i2c_client *client,
@@ -88,19 +92,23 @@
 int32_t msm_sensor_cci_i2c_util(struct msm_camera_i2c_client *client,
 	uint16_t cci_cmd);
 
+int32_t msm_camera_cci_i2c_poll(struct msm_camera_i2c_client *client,
+	uint32_t addr, uint16_t data,
+	enum msm_camera_i2c_data_type data_type);
+
 int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t *data,
+	uint32_t addr, uint16_t *data,
 	enum msm_camera_i2c_data_type data_type);
 
 int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte);
+	uint32_t addr, uint8_t *data, uint16_t num_byte);
 
 int32_t msm_camera_qup_i2c_write(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
+	uint32_t addr, uint16_t data,
 	enum msm_camera_i2c_data_type data_type);
 
 int32_t msm_camera_qup_i2c_write_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte);
+	uint32_t addr, uint8_t *data, uint16_t num_byte);
 
 int32_t msm_camera_qup_i2c_write_table(struct msm_camera_i2c_client *client,
 	struct msm_camera_i2c_reg_setting *write_setting);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c
index 55f27e0..9222bb5 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c
@@ -69,7 +69,7 @@
 }
 
 int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t *data,
+	uint32_t addr, uint16_t *data,
 	enum msm_camera_i2c_data_type data_type)
 {
 	int32_t rc = -EFAULT;
@@ -103,7 +103,7 @@
 }
 
 int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte)
+	uint32_t addr, uint8_t *data, uint16_t num_byte)
 {
 	int32_t rc = -EFAULT;
 	unsigned char buf[client->addr_type+num_byte];
@@ -136,7 +136,7 @@
 }
 
 int32_t msm_camera_qup_i2c_write(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint16_t data,
+	uint32_t addr, uint16_t data,
 	enum msm_camera_i2c_data_type data_type)
 {
 	int32_t rc = -EFAULT;
@@ -184,7 +184,7 @@
 }
 
 int32_t msm_camera_qup_i2c_write_seq(struct msm_camera_i2c_client *client,
-	uint16_t addr, uint8_t *data, uint16_t num_byte)
+	uint32_t addr, uint8_t *data, uint16_t num_byte)
 {
 	int32_t rc = -EFAULT;
 	unsigned char buf[client->addr_type+num_byte];
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_spi.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_spi.c
new file mode 100644
index 0000000..d1d5f23
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_spi.c
@@ -0,0 +1,154 @@
+/* Copyright (c) 2013, 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 <mach/camera2.h>
+#include "msm_camera_spi.h"
+
+#undef SPIDBG
+#ifdef CONFIG_MSMB_CAMERA_DEBUG
+#define SPIDBG(fmt, args...) pr_debug(fmt, ##args)
+#define S_I2C_DBG(fmt, args...) pr_debug(fmt, ##args)
+#else
+#define SPIDBG(fmt, args...) do { } while (0)
+#define S_I2C_DBG(fmt, args...) do { } while (0)
+#endif
+
+static int msm_camera_spi_txfr(struct spi_device *spi, char *txbuf,
+			       char *rxbuf, int num_byte)
+{
+	struct spi_transfer t;
+	struct spi_message m;
+
+	memset(&t, 0, sizeof(t));
+	t.tx_buf = txbuf;
+	t.rx_buf = rxbuf;
+	t.len = num_byte;
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+
+	return spi_sync(spi, &m);
+}
+
+/**
+  * msm_camera_set_addr() - helper function to set transfer address
+  * @addr:	device address
+  * @addr_len:	the addr field length of an instruction
+  * @type:	type (i.e. byte-length) of @addr
+  * @str:	shifted address output, must be zeroed when passed in
+  *
+  * This helper function sets @str based on the addr field length of an
+  * instruction and the data length.
+  */
+static void msm_camera_set_addr(uint32_t addr, uint8_t addr_len,
+				enum msm_camera_i2c_reg_addr_type type,
+				char *str)
+{
+	int i, len;
+
+	if (addr_len < type)
+		SPIDBG("%s: omitting higher bits in address\n", __func__);
+
+	/* only support transfer MSB first for now */
+	len = addr_len - type;
+	for (i = len; i < addr_len; i++) {
+		if (i >= 0)
+			str[i] = (addr >> (BITS_PER_BYTE * (addr_len - i - 1)))
+				& 0xFF;
+	}
+
+}
+
+static int32_t msm_camera_spi_read_helper(struct msm_camera_i2c_client *client,
+		struct msm_camera_spi_inst *inst, uint32_t addr, uint8_t *data,
+		uint16_t num_byte)
+{
+	int32_t rc = -EFAULT;
+	struct spi_device *spi = client->spi_client->spi_master;
+	char *tx, *rx;
+	uint16_t len;
+	int8_t retries = client->spi_client->retries;
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR)
+	    && (client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+	    && (client->addr_type != MSM_CAMERA_I2C_3B_ADDR))
+		return rc;
+
+	len = sizeof(inst->opcode) + inst->addr_len + inst->dummy_len
+		+ num_byte;
+
+	tx = kmalloc(len, GFP_KERNEL | GFP_DMA);
+	if (!tx)
+		return -ENOMEM;
+	rx = kmalloc(len, GFP_KERNEL | GFP_DMA);
+	if (!rx) {
+		kfree(tx);
+		return -ENOMEM;
+	}
+	memset(tx, 0, len);
+	memset(rx, 0, len);
+
+	tx[0] = inst->opcode;
+	msm_camera_set_addr(addr, inst->addr_len, client->addr_type, tx + 1);
+	while ((rc = msm_camera_spi_txfr(spi, tx, rx, len)) && retries) {
+		retries--;
+		msleep(client->spi_client->retry_delay);
+	}
+	if (rc) {
+		SPIDBG("%s: failed %d\n", __func__, rc);
+		goto out;
+	}
+	len = sizeof(inst->opcode) + inst->addr_len + inst->dummy_len;
+	memcpy(data, rx + len, num_byte);
+out:
+	kfree(tx);
+	kfree(rx);
+	return rc;
+}
+
+int32_t msm_camera_spi_read(struct msm_camera_i2c_client *client,
+	uint32_t addr, uint16_t *data,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int32_t rc = -EFAULT;
+	uint8_t temp[2];
+
+	if ((data_type != MSM_CAMERA_I2C_BYTE_DATA)
+	    && (data_type != MSM_CAMERA_I2C_WORD_DATA))
+		return rc;
+
+	rc = msm_camera_spi_read_helper(client,
+		&client->spi_client->cmd_tbl.read, addr, &temp[0], data_type);
+	if (rc)
+		return rc;
+
+	if (data_type == MSM_CAMERA_I2C_BYTE_DATA)
+		*data = temp[0];
+	else
+		*data = (temp[0] << BITS_PER_BYTE) | temp[1];
+
+	SPIDBG("%s: addr 0x%x, data %u\n", __func__, addr, *data);
+	return rc;
+}
+
+int32_t msm_camera_spi_read_seq(struct msm_camera_i2c_client *client,
+	uint32_t addr, uint8_t *data, uint16_t num_byte)
+{
+	return msm_camera_spi_read_helper(client,
+		&client->spi_client->cmd_tbl.read_seq, addr, data, num_byte);
+}
+
+int32_t msm_camera_spi_query_id(struct msm_camera_i2c_client *client,
+	uint32_t addr, uint8_t *data, uint16_t num_byte)
+{
+	return msm_camera_spi_read_helper(client,
+		&client->spi_client->cmd_tbl.query_id, addr, data, num_byte);
+}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_spi.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_spi.h
new file mode 100644
index 0000000..564e470
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_spi.h
@@ -0,0 +1,51 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MSM_CAMERA_SPI_H
+#define __MSM_CAMERA_SPI_H
+
+#include <linux/spi/spi.h>
+#include <media/msm_cam_sensor.h>
+#include "msm_camera_i2c.h"
+
+struct msm_camera_spi_inst {
+	uint8_t opcode;		/* one-byte opcode */
+	uint8_t addr_len;	/* addr len in bytes */
+	uint8_t dummy_len;	/* setup cycles */
+};
+
+struct msm_camera_spi_inst_tbl {
+	struct msm_camera_spi_inst read;
+	struct msm_camera_spi_inst read_seq;
+	struct msm_camera_spi_inst query_id;
+};
+
+struct msm_camera_spi_client {
+	struct spi_device *spi_master;
+	struct msm_camera_spi_inst_tbl cmd_tbl;
+	uint8_t device_id;
+	uint8_t mfr_id;
+	uint8_t retry_delay;	/* ms */
+	uint8_t retries;	/* retry times upon failure */
+};
+
+int32_t msm_camera_spi_read(struct msm_camera_i2c_client *client,
+	uint32_t addr, uint16_t *data,
+	enum msm_camera_i2c_data_type data_type);
+
+int32_t msm_camera_spi_read_seq(struct msm_camera_i2c_client *client,
+	uint32_t addr, uint8_t *data, uint16_t num_byte);
+
+int32_t msm_camera_spi_query_id(struct msm_camera_i2c_client *client,
+	uint32_t addr, uint8_t *data, uint16_t num_byte);
+
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
index 453b14a..fa63e2b 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c
@@ -78,6 +78,23 @@
 		src_node = NULL;
 	}
 
+	src_node = of_parse_phandle(of_node, "qcom,eeprom-src", 0);
+	if (!src_node) {
+		CDBG("%s:%d eeprom src_node NULL\n", __func__, __LINE__);
+	} else {
+		rc = of_property_read_u32(src_node, "cell-index", &val);
+		CDBG("%s qcom,eeprom cell index %d, rc %d\n", __func__,
+			val, rc);
+		if (rc < 0) {
+			pr_err("%s failed %d\n", __func__, __LINE__);
+			goto ERROR;
+		}
+		sensordata->sensor_info->
+			subdev_id[SUB_MODULE_EEPROM] = val;
+		of_node_put(src_node);
+		src_node = NULL;
+	}
+
 	if (of_property_read_bool(of_node, "qcom,eeprom-sd-index") ==
 		true) {
 		rc = of_property_read_u32(of_node, "qcom,eeprom-sd-index",
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
index b6bc0d7..6775a23 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
@@ -1220,6 +1220,8 @@
 {
 	struct mpq_demux *mpq_demux = feed->demux->priv;
 
+	MPQ_DVB_DBG_PRINT("%s: cookie=%d\n", __func__, cookie);
+
 	if (cookie < 0) {
 		MPQ_DVB_ERR_PRINT("%s: invalid cookie parameter\n", __func__);
 		return -EINVAL;
@@ -2441,9 +2443,15 @@
 
 	data->data_length = 0;
 	data->buf.handle = packet->raw_data_handle;
+
 	/* this has to succeed when called here, after packet was written */
 	data->buf.cookie = mpq_streambuffer_pkt_next(stream_buffer,
 				feed_data->last_pkt_index, &len);
+	if (data->buf.cookie < 0)
+		MPQ_DVB_DBG_PRINT(
+			"%s: received invalid packet index %d\n",
+			__func__, data->buf.cookie);
+
 	data->buf.offset = packet->raw_data_offset;
 	data->buf.len = packet->raw_data_len;
 	data->buf.pts_exists = pts_dts->pts_exist;
@@ -2459,6 +2467,8 @@
 	/* save for next time: */
 	feed_data->last_pkt_index = data->buf.cookie;
 
+	MPQ_DVB_DBG_PRINT("%s: cookie=%d\n", __func__, data->buf.cookie);
+
 	/* reset counters */
 	feed_data->ts_packets_num = 0;
 	feed_data->ts_dropped_bytes = 0;
@@ -4235,7 +4245,12 @@
 				__func__, ret);
 		}
 		mpq_dmx_update_decoder_stat(mpq_demux);
-		mpq_streambuffer_pkt_write(sbuf, &packet, (u8 *)&meta_data);
+		if (mpq_streambuffer_pkt_write(sbuf,
+				&packet,
+				(u8 *)&meta_data) < 0)
+			MPQ_DVB_ERR_PRINT(
+				"%s: Couldn't write packet. Should never happen\n",
+				__func__);
 
 		mpq_dmx_prepare_es_event_data(
 			&packet, &meta_data, &mpq_feed->video_info,
diff --git a/drivers/media/platform/msm/vidc/Kconfig b/drivers/media/platform/msm/vidc/Kconfig
index 3fc2b9e..4a27fd3 100644
--- a/drivers/media/platform/msm/vidc/Kconfig
+++ b/drivers/media/platform/msm/vidc/Kconfig
@@ -4,4 +4,4 @@
 
 menuconfig MSM_VIDC_V4L2
 	bool "Qualcomm MSM V4L2 based video driver"
-		depends on (ARCH_MSM8974 || ARCH_MSM8610) && VIDEO_V4L2
+		depends on (ARCH_MSM8974 || ARCH_MSM8610 || ARCH_MSM8226) && VIDEO_V4L2
diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c
index b3bce5f..3b12a26 100644
--- a/drivers/media/platform/msm/vidc/msm_smem.c
+++ b/drivers/media/platform/msm/vidc/msm_smem.c
@@ -80,12 +80,18 @@
 			goto mem_domain_get_failed;
 		}
 	}
-	rc = ion_map_iommu(clnt, hndl, domain, partition, align,
-			0, iova, buffer_size, 0, 0);
+	if (is_iommu_present(smem_client->res)) {
+		dprintk(VIDC_DBG,
+				"Calling ion_map_iommu - domain: %d, partition: %d",
+				domain, partition);
+		rc = ion_map_iommu(clnt, hndl, domain, partition, align,
+				0, iova, buffer_size, 0, 0);
+	} else {
+		dprintk(VIDC_DBG, "Using physical memory address");
+		rc = ion_phys(clnt, hndl, iova, (size_t *)buffer_size);
+	}
 	if (rc) {
-		dprintk(VIDC_ERR,
-		"ion_map_iommu failed(%d).domain: %d,partition: %d\n",
-		rc, domain, partition);
+		dprintk(VIDC_ERR, "ion memory map failed - %d", rc);
 		goto mem_map_failed;
 	}
 
@@ -97,10 +103,28 @@
 	return rc;
 }
 
-static void put_device_address(struct ion_client *clnt,
+static void put_device_address(struct smem_client *smem_client,
 	struct ion_handle *hndl, int domain_num, int partition_num, u32 flags)
 {
-	ion_unmap_iommu(clnt, hndl, domain_num, partition_num);
+	struct ion_client *clnt = NULL;
+
+	if (!hndl || !smem_client) {
+		dprintk(VIDC_WARN, "Invalid params: %p, %p\n",
+				smem_client, hndl);
+		return;
+	}
+
+	clnt = smem_client->clnt;
+	if (!clnt) {
+		dprintk(VIDC_WARN, "Invalid client");
+		return;
+	}
+	if (is_iommu_present(smem_client->res)) {
+		dprintk(VIDC_DBG,
+				"Calling ion_unmap_iommu - domain: %d, parition: %d",
+				domain_num, partition_num);
+		ion_unmap_iommu(clnt, hndl, domain_num, partition_num);
+	}
 	if (flags & SMEM_SECURE) {
 		if (msm_ion_unsecure_buffer(clnt, hndl))
 			dprintk(VIDC_ERR, "Failed to unsecure memory\n");
@@ -186,7 +210,15 @@
 		align = ALIGN(align, SZ_1M);
 	}
 
-	heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
+	if (is_iommu_present(client->res)) {
+		heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
+	} else {
+		dprintk(VIDC_DBG,
+			"allocate shared memory from adsp heap size %d align %d\n",
+			size, align);
+		heap_mask = ION_HEAP(ION_ADSP_HEAP_ID);
+	}
+
 	if (flags & SMEM_SECURE)
 		heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID);
 
@@ -246,7 +278,7 @@
 	}
 
 	if (mem->device_addr)
-		put_device_address(client->clnt,
+		put_device_address(client,
 			mem->smem_priv, domain, partition, mem->flags);
 	if (mem->kvaddr)
 		ion_unmap_kernel(client->clnt, mem->smem_priv);
diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
index 50adb13..687bd71 100644
--- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
@@ -1061,10 +1061,9 @@
 
 	if (!of_get_property(pdev->dev.of_node, "qcom,iommu-groups",
 				&array_size)) {
-		dprintk(VIDC_ERR, "Could not find iommu_groups property\n");
+		dprintk(VIDC_DBG, "iommu_groups property not present\n");
 		iommu_group_set->count = 0;
-		rc = -ENOENT;
-		goto err_no_of_node;
+		return 0;
 	}
 
 	iommu_group_set->count = array_size / sizeof(u32);
@@ -1359,10 +1358,37 @@
 	return rc;
 }
 
+static ssize_t msm_vidc_link_name_show(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct msm_vidc_core *core = dev_get_drvdata(dev);
+	if (core)
+		if (dev == &core->vdev[MSM_VIDC_DECODER].vdev.dev)
+			if (core->hfi_type == VIDC_HFI_Q6)
+				return snprintf(buf, PAGE_SIZE, "q6_dec");
+			else
+				return snprintf(buf, PAGE_SIZE, "venus_dec");
+		else if (dev == &core->vdev[MSM_VIDC_ENCODER].vdev.dev)
+			if (core->hfi_type == VIDC_HFI_Q6)
+				return snprintf(buf, PAGE_SIZE, "q6_enc");
+			else
+				return snprintf(buf, PAGE_SIZE, "venus_enc");
+		else
+			return 0;
+	else
+		return 0;
+}
+
+static DEVICE_ATTR(link_name, 0644, msm_vidc_link_name_show, NULL);
+
 static int __devinit msm_vidc_probe(struct platform_device *pdev)
 {
 	int rc = 0;
 	struct msm_vidc_core *core;
+	struct device *dev;
+	int nr = BASE_DEVICE_NUMBER;
+
 	core = kzalloc(sizeof(*core), GFP_KERNEL);
 	if (!core || !vidc_driver) {
 		dprintk(VIDC_ERR,
@@ -1375,6 +1401,10 @@
 		dprintk(VIDC_ERR, "Failed to init core\n");
 		goto err_v4l2_register;
 	}
+	if (core->hfi_type == VIDC_HFI_Q6) {
+		dprintk(VIDC_ERR, "Q6 hfi device probe called\n");
+		nr += MSM_VIDC_MAX_DEVICES;
+	}
 	rc = v4l2_device_register(&pdev->dev, &core->v4l2_dev);
 	if (rc) {
 		dprintk(VIDC_ERR, "Failed to register v4l2 device\n");
@@ -1386,12 +1416,19 @@
 	core->vdev[MSM_VIDC_DECODER].vdev.ioctl_ops = &msm_v4l2_ioctl_ops;
 	core->vdev[MSM_VIDC_DECODER].type = MSM_VIDC_DECODER;
 	rc = video_register_device(&core->vdev[MSM_VIDC_DECODER].vdev,
-					VFL_TYPE_GRABBER, BASE_DEVICE_NUMBER);
+					VFL_TYPE_GRABBER, nr);
 	if (rc) {
 		dprintk(VIDC_ERR, "Failed to register video decoder device");
 		goto err_dec_register;
 	}
 	video_set_drvdata(&core->vdev[MSM_VIDC_DECODER].vdev, core);
+	dev = &core->vdev[MSM_VIDC_DECODER].vdev.dev;
+	rc = device_create_file(dev, &dev_attr_link_name);
+	if (rc) {
+		dprintk(VIDC_ERR,
+				"Failed to create link name sysfs for decoder");
+		goto err_dec_attr_link_name;
+	}
 
 	core->vdev[MSM_VIDC_ENCODER].vdev.release =
 		msm_vidc_release_video_device;
@@ -1399,19 +1436,20 @@
 	core->vdev[MSM_VIDC_ENCODER].vdev.ioctl_ops = &msm_v4l2_ioctl_ops;
 	core->vdev[MSM_VIDC_ENCODER].type = MSM_VIDC_ENCODER;
 	rc = video_register_device(&core->vdev[MSM_VIDC_ENCODER].vdev,
-				VFL_TYPE_GRABBER, BASE_DEVICE_NUMBER + 1);
+				VFL_TYPE_GRABBER, nr + 1);
 	if (rc) {
 		dprintk(VIDC_ERR, "Failed to register video encoder device");
 		goto err_enc_register;
 	}
 	video_set_drvdata(&core->vdev[MSM_VIDC_ENCODER].vdev, core);
-
-	core->device = vidc_hfi_initialize(core->hfi_type, core->id,
-				&core->resources, &handle_cmd_response);
-	if (!core->device) {
-		dprintk(VIDC_ERR, "Failed to create HFI device\n");
-		goto err_cores_exceeded;
+	dev = &core->vdev[MSM_VIDC_ENCODER].vdev.dev;
+	rc = device_create_file(dev, &dev_attr_link_name);
+	if (rc) {
+		dprintk(VIDC_ERR,
+				"Failed to create link name sysfs for encoder");
+		goto err_enc_attr_link_name;
 	}
+
 	mutex_lock(&vidc_driver->lock);
 	if (vidc_driver->num_cores  + 1 > MSM_VIDC_CORES_MAX) {
 		mutex_unlock(&vidc_driver->lock);
@@ -1419,8 +1457,20 @@
 				vidc_driver->num_cores);
 		goto err_cores_exceeded;
 	}
-
 	core->id = vidc_driver->num_cores++;
+	mutex_unlock(&vidc_driver->lock);
+
+	core->device = vidc_hfi_initialize(core->hfi_type, core->id,
+				&core->resources, &handle_cmd_response);
+	if (!core->device) {
+		dprintk(VIDC_ERR, "Failed to create HFI device\n");
+		mutex_lock(&vidc_driver->lock);
+		vidc_driver->num_cores--;
+		mutex_unlock(&vidc_driver->lock);
+		goto err_cores_exceeded;
+	}
+
+	mutex_lock(&vidc_driver->lock);
 	list_add_tail(&core->list, &vidc_driver->cores);
 	mutex_unlock(&vidc_driver->lock);
 	core->debugfs_root = msm_vidc_debugfs_init_core(
@@ -1429,8 +1479,14 @@
 	return rc;
 
 err_cores_exceeded:
+	device_remove_file(&core->vdev[MSM_VIDC_ENCODER].vdev.dev,
+			&dev_attr_link_name);
+err_enc_attr_link_name:
 	video_unregister_device(&core->vdev[MSM_VIDC_ENCODER].vdev);
 err_enc_register:
+	device_remove_file(&core->vdev[MSM_VIDC_DECODER].vdev.dev,
+			&dev_attr_link_name);
+err_dec_attr_link_name:
 	video_unregister_device(&core->vdev[MSM_VIDC_DECODER].vdev);
 err_dec_register:
 	v4l2_device_unregister(&core->v4l2_dev);
@@ -1457,7 +1513,11 @@
 	}
 
 	vidc_hfi_deinitialize(core->hfi_type, core->device);
+	device_remove_file(&core->vdev[MSM_VIDC_ENCODER].vdev.dev,
+				&dev_attr_link_name);
 	video_unregister_device(&core->vdev[MSM_VIDC_ENCODER].vdev);
+	device_remove_file(&core->vdev[MSM_VIDC_DECODER].vdev.dev,
+				&dev_attr_link_name);
 	video_unregister_device(&core->vdev[MSM_VIDC_DECODER].vdev);
 	v4l2_device_unregister(&core->v4l2_dev);
 
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 8eecb98..2cf9928 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -375,7 +375,7 @@
 	struct msm_vidc_inst *inst;
 	struct v4l2_control control = {0};
 	struct msm_vidc_cb_event *event_notify;
-	int event = 0;
+	int event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
 	int rc = 0;
 	if (response) {
 		inst = (struct msm_vidc_inst *)response->session_id;
@@ -398,11 +398,14 @@
 		default:
 			break;
 		}
-
-		inst->reconfig_height = event_notify->height;
-		inst->reconfig_width = event_notify->width;
-		inst->in_reconfig = true;
-
+		if (event == V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT) {
+			inst->reconfig_height = event_notify->height;
+			inst->reconfig_width = event_notify->width;
+			inst->in_reconfig = true;
+		} else {
+			inst->prop.height = event_notify->height;
+			inst->prop.width = event_notify->width;
+		}
 		rc = msm_vidc_check_session_supported(inst);
 		if (!rc) {
 			queue_v4l2_event(inst, event);
@@ -821,6 +824,7 @@
 	vb->v4l2_planes[0].bytesused = fill_buf_done->filled_len1;
 
 	vb->v4l2_buf.flags = V4L2_QCOM_BUF_FLAG_CODECCONFIG;
+	vb->v4l2_buf.timestamp = ns_to_timeval(0);
 
 	dprintk(VIDC_DBG, "Filled length = %d; flags %x\n",
 				vb->v4l2_planes[0].bytesused,
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_resources.h b/drivers/media/platform/msm/vidc/msm_vidc_resources.h
index 693c1a5..43af909 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_resources.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_resources.h
@@ -78,5 +78,13 @@
 	struct platform_device *pdev;
 };
 
+static inline int is_iommu_present(struct msm_vidc_platform_resources *res)
+{
+	if (res)
+		return (res->iommu_group_set.count > 0 &&
+				res->iommu_group_set.iommu_maps != NULL);
+	return 0;
+}
+
 #endif
 
diff --git a/drivers/media/platform/msm/wfd/enc-venus-subdev.c b/drivers/media/platform/msm/wfd/enc-venus-subdev.c
index 9ebf763..b719b3f 100644
--- a/drivers/media/platform/msm/wfd/enc-venus-subdev.c
+++ b/drivers/media/platform/msm/wfd/enc-venus-subdev.c
@@ -767,6 +767,7 @@
 	if (inst->secure)
 		msm_ion_unsecure_buffer(venc_ion_client, mregion->ion_handle);
 
+	ion_free(venc_ion_client, mregion->ion_handle);
 	return rc;
 }
 
@@ -1286,9 +1287,11 @@
 		return rc;
 	}
 
-	if (mregion->paddr)
+	if (mregion->paddr) {
 		ion_unmap_iommu(mmap->ion_client, mregion->ion_handle,
 			domain, partition);
+		mregion->paddr = NULL;
+	}
 
 	if (inst->secure)
 		msm_ion_unsecure_buffer(mmap->ion_client, mregion->ion_handle);
diff --git a/drivers/media/platform/msm/wfd/mdp-5-subdev.c b/drivers/media/platform/msm/wfd/mdp-5-subdev.c
index 4089a99..16de0d4 100644
--- a/drivers/media/platform/msm/wfd/mdp-5-subdev.c
+++ b/drivers/media/platform/msm/wfd/mdp-5-subdev.c
@@ -127,9 +127,9 @@
 		if (inst->secure)
 			msm_fb_writeback_set_secure(inst->mdp, false);
 		msm_fb_writeback_terminate(fbi);
-		kfree(inst);
 		/* Unregister wfd node from switch driver */
 		switch_dev_unregister(&inst->sdev);
+		kfree(inst);
 	}
 	return 0;
 }
diff --git a/drivers/media/platform/msm/wfd/wfd-ioctl.c b/drivers/media/platform/msm/wfd/wfd-ioctl.c
index cd54449..e589878 100644
--- a/drivers/media/platform/msm/wfd/wfd-ioctl.c
+++ b/drivers/media/platform/msm/wfd/wfd-ioctl.c
@@ -166,11 +166,15 @@
 	unsigned int alloc_regions = 0, ion_flags = 0, align = 0;
 	int rc = 0;
 
-	alloc_regions = ION_HEAP(ION_CP_MM_HEAP_ID);
-	alloc_regions |= secure ? 0 :
-				ION_HEAP(ION_IOMMU_HEAP_ID);
-	ion_flags |= secure ? ION_SECURE : 0;
-	align = secure ? SZ_1M : SZ_4K;
+	if (secure) {
+		alloc_regions = ION_HEAP(ION_CP_MM_HEAP_ID);
+		ion_flags = ION_SECURE;
+		align = SZ_1M;
+	} else {
+		alloc_regions = ION_HEAP(ION_IOMMU_HEAP_ID);
+		align = SZ_4K;
+	}
+
 	handle = ion_alloc(client, mregion->size, align,
 			alloc_regions, ion_flags);
 
@@ -1546,10 +1550,10 @@
 			WFD_MSG_ERR("Failed to CLOSE vsg subdev: %d\n", rc);
 
 		wfd_stats_deinit(&inst->stats);
+		v4l2_fh_del(&inst->event_handler);
 		kfree(inst);
 	}
 
-	v4l2_fh_del(&inst->event_handler);
 
 	mutex_lock(&wfd_dev->dev_lock);
 	wfd_dev->in_use = false;
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index ff8234e..7c73d6c 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -1153,6 +1153,7 @@
 	char **codec_supplies;
 	u32 num_of_supplies = 0;
 	u32 mclk_rate = 0;
+	u32 dmic_sample_rate = 0;
 
 	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata) {
@@ -1212,6 +1213,38 @@
 		goto err;
 	}
 	pdata->mclk_rate = mclk_rate;
+
+	ret = of_property_read_u32(dev->of_node,
+				"qcom,cdc-dmic-sample-rate",
+				&dmic_sample_rate);
+	if (ret) {
+		dev_err(dev, "Looking up %s property in node %s failed",
+			"qcom,cdc-dmic-sample-rate",
+			dev->of_node->full_name);
+		dmic_sample_rate = TAIKO_DMIC_SAMPLE_RATE_UNDEFINED;
+	}
+	if (pdata->mclk_rate == TAIKO_MCLK_CLK_9P6HZ) {
+		if ((dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_2P4MHZ) &&
+		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_3P2MHZ) &&
+		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_4P8MHZ) &&
+		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_UNDEFINED)) {
+			dev_err(dev, "Invalid dmic rate %d for mclk %d\n",
+				dmic_sample_rate, pdata->mclk_rate);
+			ret = -EINVAL;
+			goto err;
+		}
+	} else if (pdata->mclk_rate == TAIKO_MCLK_CLK_12P288MHZ) {
+		if ((dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_3P072MHZ) &&
+		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_4P096MHZ) &&
+		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_6P144MHZ) &&
+		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_UNDEFINED)) {
+			dev_err(dev, "Invalid dmic rate %d for mclk %d\n",
+				dmic_sample_rate, pdata->mclk_rate);
+			ret = -EINVAL;
+			goto err;
+		}
+	}
+	pdata->dmic_sample_rate = dmic_sample_rate;
 	return pdata;
 err:
 	devm_kfree(dev, pdata);
diff --git a/drivers/misc/tsif.c b/drivers/misc/tsif.c
index 05f6c86..f80fbcc 100644
--- a/drivers/misc/tsif.c
+++ b/drivers/misc/tsif.c
@@ -216,8 +216,6 @@
 		tsif_device->tsif_clk = clk_get(&tsif_device->pdev->dev,
 						pdata->tsif_clk);
 		if (IS_ERR(tsif_device->tsif_clk)) {
-			dev_err(&tsif_device->pdev->dev, "failed to get %s\n",
-				pdata->tsif_clk);
 			rc = PTR_ERR(tsif_device->tsif_clk);
 			tsif_device->tsif_clk = NULL;
 			goto ret;
@@ -227,8 +225,6 @@
 		tsif_device->tsif_pclk = clk_get(&tsif_device->pdev->dev,
 						 pdata->tsif_pclk);
 		if (IS_ERR(tsif_device->tsif_pclk)) {
-			dev_err(&tsif_device->pdev->dev, "failed to get %s\n",
-				pdata->tsif_pclk);
 			rc = PTR_ERR(tsif_device->tsif_pclk);
 			tsif_device->tsif_pclk = NULL;
 			goto ret;
@@ -238,8 +234,6 @@
 		tsif_device->tsif_ref_clk = clk_get(&tsif_device->pdev->dev,
 						    pdata->tsif_ref_clk);
 		if (IS_ERR(tsif_device->tsif_ref_clk)) {
-			dev_err(&tsif_device->pdev->dev, "failed to get %s\n",
-				pdata->tsif_ref_clk);
 			rc = PTR_ERR(tsif_device->tsif_ref_clk);
 			tsif_device->tsif_ref_clk = NULL;
 			goto ret;
@@ -1431,7 +1425,8 @@
 		     (unsigned long)tsif_device);
 	tasklet_init(&tsif_device->clocks_off, tsif_clocks_off,
 		     (unsigned long)tsif_device);
-	if (tsif_get_clocks(tsif_device))
+	rc = tsif_get_clocks(tsif_device);
+	if (rc)
 		goto err_clocks;
 /* map I/O memory */
 	tsif_device->memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/misc/tspp.c b/drivers/misc/tspp.c
index 9ef86a7..dbb4f5e 100644
--- a/drivers/misc/tspp.c
+++ b/drivers/misc/tspp.c
@@ -1569,6 +1569,7 @@
 {
 	int i;
 	int id;
+	int table_idx;
 	u32 val;
 
 	struct sps_connect *config;
@@ -1606,16 +1607,18 @@
 	wmb();
 
 	/* unregister all filters for this channel */
-	for (i = 0; i < TSPP_NUM_PRIORITIES; i++) {
-		struct tspp_pid_filter *tspp_filter =
-			&pdev->filters[channel->src]->filter[i];
-		id = FILTER_GET_PIPE_NUMBER0(tspp_filter);
-		if (id == channel->id) {
-			if (FILTER_HAS_ENCRYPTION(tspp_filter))
-				tspp_free_key_entry(
-					FILTER_GET_KEY_NUMBER(tspp_filter));
-			tspp_filter->config = 0;
-			tspp_filter->filter = 0;
+	for (table_idx = 0; table_idx < TSPP_FILTER_TABLES; table_idx++) {
+		for (i = 0; i < TSPP_NUM_PRIORITIES; i++) {
+			struct tspp_pid_filter *filter =
+				&pdev->filters[table_idx]->filter[i];
+			id = FILTER_GET_PIPE_NUMBER0(filter);
+			if (id == channel->id) {
+				if (FILTER_HAS_ENCRYPTION(filter))
+					tspp_free_key_entry(
+						FILTER_GET_KEY_NUMBER(filter));
+				filter->config = 0;
+				filter->filter = 0;
+			}
 		}
 	}
 	channel->filter_count = 0;
@@ -2836,8 +2839,6 @@
 	if (data->tsif_pclk) {
 		device->tsif_pclk = clk_get(&pdev->dev, data->tsif_pclk);
 		if (IS_ERR(device->tsif_pclk)) {
-			pr_err("tspp: failed to get %s",
-				data->tsif_pclk);
 			rc = PTR_ERR(device->tsif_pclk);
 			device->tsif_pclk = NULL;
 			goto err_pclock;
@@ -2846,8 +2847,6 @@
 	if (data->tsif_ref_clk) {
 		device->tsif_ref_clk = clk_get(&pdev->dev, data->tsif_ref_clk);
 		if (IS_ERR(device->tsif_ref_clk)) {
-			pr_err("tspp: failed to get %s",
-				data->tsif_ref_clk);
 			rc = PTR_ERR(device->tsif_ref_clk);
 			device->tsif_ref_clk = NULL;
 			goto err_refclock;
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index bea8428..38b453b 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -820,7 +820,15 @@
 					context_info->is_done_rcv = false;
 					break; /* return err */
 				} else {
+					/*
+					 * We have stopped the ongoing request
+					 * and are sure that mmc_request_done()
+					 * is not going to get called. Update
+					 * stuff that we ought to do when the
+					 * request actually completes.
+					 */
 					mmc_update_clk_scaling(host);
+					mmc_host_clk_release(host);
 				}
 				err = host->areq->update_interrupted_req(
 						host->card, host->areq);
@@ -2815,7 +2823,13 @@
 	u32 status;
 	bool ret = false;
 
-	if (!card)
+	/*
+	 * If the current partition type is RPMB, clock switching may not
+	 * work properly as sending tuning command (CMD21) is illegal in
+	 * this mode.
+	 */
+	if (!card || (mmc_card_mmc(card) &&
+			card->part_curr == EXT_CSD_PART_CONFIG_ACC_RPMB))
 		goto out;
 
 	if (mmc_send_status(card, &status)) {
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 5090eea..3b1384d 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -2184,6 +2184,7 @@
 	host->quirks |= SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN;
 	host->quirks2 |= SDHCI_QUIRK2_ALWAYS_USE_BASE_CLOCK;
 	host->quirks2 |= SDHCI_QUIRK2_IGNORE_CMDCRC_FOR_TUNING;
+	host->quirks2 |= SDHCI_QUIRK2_USE_MAX_DISCARD_SIZE;
 
 	host_version = readl_relaxed((host->ioaddr + SDHCI_HOST_VERSION));
 	dev_dbg(&pdev->dev, "Host Version: 0x%x Vendor Version 0x%x\n",
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index c247ae9..d58379f 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -66,53 +66,67 @@
 }
 #endif
 
+static void sdhci_dump_state(struct sdhci_host *host)
+{
+	struct mmc_host *mmc = host->mmc;
+
+	pr_info("%s: clk: %d clk-gated: %d claimer: %s pwr: %d\n",
+		mmc_hostname(mmc), host->clock, mmc->clk_gated,
+		mmc->claimer->comm, host->pwr);
+	pr_info("%s: rpmstatus[pltfm](runtime-suspend:usage_count:disable_depth)(%d:%d:%d)\n",
+		mmc_hostname(mmc), mmc->parent->power.runtime_status,
+		atomic_read(&mmc->parent->power.usage_count),
+		mmc->parent->power.disable_depth);
+}
+
 static void sdhci_dumpregs(struct sdhci_host *host)
 {
-	pr_debug(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n",
+	pr_info(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n",
 		mmc_hostname(host->mmc));
 
-	pr_debug(DRIVER_NAME ": Sys addr: 0x%08x | Version:  0x%08x\n",
+	pr_info(DRIVER_NAME ": Sys addr: 0x%08x | Version:  0x%08x\n",
 		sdhci_readl(host, SDHCI_DMA_ADDRESS),
 		sdhci_readw(host, SDHCI_HOST_VERSION));
-	pr_debug(DRIVER_NAME ": Blk size: 0x%08x | Blk cnt:  0x%08x\n",
+	pr_info(DRIVER_NAME ": Blk size: 0x%08x | Blk cnt:  0x%08x\n",
 		sdhci_readw(host, SDHCI_BLOCK_SIZE),
 		sdhci_readw(host, SDHCI_BLOCK_COUNT));
-	pr_debug(DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
+	pr_info(DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
 		sdhci_readl(host, SDHCI_ARGUMENT),
 		sdhci_readw(host, SDHCI_TRANSFER_MODE));
-	pr_debug(DRIVER_NAME ": Present:  0x%08x | Host ctl: 0x%08x\n",
+	pr_info(DRIVER_NAME ": Present:  0x%08x | Host ctl: 0x%08x\n",
 		sdhci_readl(host, SDHCI_PRESENT_STATE),
 		sdhci_readb(host, SDHCI_HOST_CONTROL));
-	pr_debug(DRIVER_NAME ": Power:    0x%08x | Blk gap:  0x%08x\n",
+	pr_info(DRIVER_NAME ": Power:    0x%08x | Blk gap:  0x%08x\n",
 		sdhci_readb(host, SDHCI_POWER_CONTROL),
 		sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL));
-	pr_debug(DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
+	pr_info(DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
 		sdhci_readb(host, SDHCI_WAKE_UP_CONTROL),
 		sdhci_readw(host, SDHCI_CLOCK_CONTROL));
-	pr_debug(DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
+	pr_info(DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
 		sdhci_readb(host, SDHCI_TIMEOUT_CONTROL),
 		sdhci_readl(host, SDHCI_INT_STATUS));
-	pr_debug(DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
+	pr_info(DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
 		sdhci_readl(host, SDHCI_INT_ENABLE),
 		sdhci_readl(host, SDHCI_SIGNAL_ENABLE));
-	pr_debug(DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
+	pr_info(DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
 		sdhci_readw(host, SDHCI_ACMD12_ERR),
 		sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
-	pr_debug(DRIVER_NAME ": Caps:     0x%08x | Caps_1:   0x%08x\n",
+	pr_info(DRIVER_NAME ": Caps:     0x%08x | Caps_1:   0x%08x\n",
 		sdhci_readl(host, SDHCI_CAPABILITIES),
 		sdhci_readl(host, SDHCI_CAPABILITIES_1));
-	pr_debug(DRIVER_NAME ": Cmd:      0x%08x | Max curr: 0x%08x\n",
+	pr_info(DRIVER_NAME ": Cmd:      0x%08x | Max curr: 0x%08x\n",
 		sdhci_readw(host, SDHCI_COMMAND),
 		sdhci_readl(host, SDHCI_MAX_CURRENT));
-	pr_debug(DRIVER_NAME ": Host ctl2: 0x%08x\n",
+	pr_info(DRIVER_NAME ": Host ctl2: 0x%08x\n",
 		sdhci_readw(host, SDHCI_HOST_CONTROL2));
 
 	if (host->flags & SDHCI_USE_ADMA)
-		pr_debug(DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n",
+		pr_info(DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n",
 		       readl(host->ioaddr + SDHCI_ADMA_ERROR),
 		       readl(host->ioaddr + SDHCI_ADMA_ADDRESS));
 
-	pr_debug(DRIVER_NAME ": ===========================================\n");
+	sdhci_dump_state(host);
+	pr_info(DRIVER_NAME ": ===========================================\n");
 }
 
 /*****************************************************************************\
@@ -1372,6 +1386,17 @@
 	}
 }
 
+static bool sdhci_check_state(struct sdhci_host *host)
+{
+	struct mmc_host *mmc = host->mmc;
+
+	if (!host->clock || !host->pwr ||
+	    pm_runtime_suspended(mmc->parent))
+		return true;
+	else
+		return false;
+}
+
 static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
 	struct sdhci_host *host;
@@ -1381,6 +1406,15 @@
 	host = mmc_priv(mmc);
 
 	sdhci_runtime_pm_get(host);
+	if (sdhci_check_state(host)) {
+		sdhci_dump_state(host);
+		WARN(1, "sdhci in bad state");
+		mrq->cmd->error = -EIO;
+		if (mrq->data)
+			mrq->data->error = -EIO;
+		tasklet_schedule(&host->finish_tasklet);
+		return;
+	}
 
 	spin_lock_irqsave(&host->lock, flags);
 
@@ -2217,6 +2251,11 @@
 		sdhci_dumpregs(host);
 
 		if (host->data) {
+			pr_info("%s: bytes to transfer: %d transferred: %d\n",
+				mmc_hostname(host->mmc),
+				(host->data->blksz * host->data->blocks),
+				(sdhci_readw(host, SDHCI_BLOCK_SIZE) & 0xFFF) *
+				sdhci_readw(host, SDHCI_BLOCK_COUNT));
 			host->data->error = -ETIMEDOUT;
 			sdhci_finish_data(host);
 		} else {
@@ -2354,6 +2393,7 @@
 static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
 {
 	u32 command;
+	bool pr_msg = false;
 	BUG_ON(intmask == 0);
 
 	/* CMD19 generates _only_ Buffer Read Ready interrupt */
@@ -2401,10 +2441,25 @@
 		sdhci_show_adma_error(host);
 		host->data->error = -EIO;
 	}
-
-	if (host->data->error)
+	if (host->data->error) {
+		if ((intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT)) &&
+		    (host->quirks2 & SDHCI_QUIRK2_IGNORE_CMDCRC_FOR_TUNING)) {
+			command = SDHCI_GET_CMD(sdhci_readw(host,
+							    SDHCI_COMMAND));
+			if ((command != MMC_SEND_TUNING_BLOCK_HS200) &&
+			    (command != MMC_SEND_TUNING_BLOCK))
+				pr_msg = true;
+		} else {
+			pr_msg = true;
+		}
+		if (pr_msg) {
+			pr_err("%s: data txfr (0x%08x) error: %d\n",
+			       mmc_hostname(host->mmc), intmask,
+			       host->data->error);
+			sdhci_dumpregs(host);
+		}
 		sdhci_finish_data(host);
-	else {
+	} else {
 		if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
 			sdhci_transfer_pio(host);
 
@@ -2962,7 +3017,8 @@
 	if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
 		host->timeout_clk = mmc->f_max / 1000;
 
-	mmc->max_discard_to = (1 << 27) / host->timeout_clk;
+	if (!(host->quirks2 & SDHCI_QUIRK2_USE_MAX_DISCARD_SIZE))
+		mmc->max_discard_to = (1 << 27) / host->timeout_clk;
 
 	mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
 
diff --git a/drivers/platform/msm/ipa/ipa_dp.c b/drivers/platform/msm/ipa/ipa_dp.c
index bd1da2c..86eebf6 100644
--- a/drivers/platform/msm/ipa/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_dp.c
@@ -259,7 +259,7 @@
 	if (unlikely(!in_atomic))
 		mem_flag = GFP_KERNEL;
 
-	transfer.iovec = dma_alloc_coherent(NULL, size, &dma_addr, 0);
+	transfer.iovec = dma_alloc_coherent(NULL, size, &dma_addr, mem_flag);
 	transfer.iovec_phys = dma_addr;
 	transfer.iovec_count = num_desc;
 	spin_lock_irqsave(&sys->spinlock, irq_flags);
@@ -943,7 +943,6 @@
 
 static void ipa_tx_cmd_comp(void *user1, void *user2)
 {
-	IPA_STATS_INC_CNT(ipa_ctx->stats.imm_cmds[IPA_IP_PACKET_INIT]);
 	kfree(user1);
 }
 
@@ -1022,6 +1021,7 @@
 			IPAERR("fail to send immediate command\n");
 			goto fail_send;
 		}
+		IPA_STATS_INC_CNT(ipa_ctx->stats.imm_cmds[IPA_IP_PACKET_INIT]);
 	} else if (dst == IPA_CLIENT_A5_WLAN_AMPDU_PROD) {
 		desc[0].pyld = skb->data;
 		desc[0].len = skb->len;
diff --git a/drivers/power/pm8xxx-ccadc.c b/drivers/power/pm8xxx-ccadc.c
index 7e37daa..5313593 100644
--- a/drivers/power/pm8xxx-ccadc.c
+++ b/drivers/power/pm8xxx-ccadc.c
@@ -81,6 +81,7 @@
 	int			r_sense_uohm;
 	struct delayed_work	calib_ccadc_work;
 	struct mutex		calib_mutex;
+	bool			periodic_wakeup;
 };
 
 static struct pm8xxx_ccadc_chip *the_chip;
@@ -367,7 +368,7 @@
 	return 0;
 }
 
-void pm8xxx_calib_ccadc(void)
+static void __pm8xxx_calib_ccadc(int sample_count)
 {
 	u8 data_msb, data_lsb, sec_cntrl;
 	int result_offset, result_gain;
@@ -379,6 +380,8 @@
 		return;
 	}
 
+	pr_debug("sample_count = %d\n", sample_count);
+
 	mutex_lock(&the_chip->calib_mutex);
 	rc = pm8xxx_readb(the_chip->dev->parent,
 					ADC_ARB_SECP_CNTRL, &sec_cntrl);
@@ -405,7 +408,7 @@
 	}
 
 	result_offset = 0;
-	for (i = 0; i < SAMPLE_COUNT; i++) {
+	for (i = 0; i < sample_count; i++) {
 		/* Short analog inputs to CCADC internally to ground */
 		rc = pm8xxx_writeb(the_chip->dev->parent, ADC_ARB_SECP_RSV,
 							CCADC_CALIB_RSV_GND);
@@ -431,7 +434,7 @@
 		result_offset += result;
 	}
 
-	result_offset = result_offset / SAMPLE_COUNT;
+	result_offset = result_offset / sample_count;
 
 
 	pr_debug("offset result_offset = 0x%x, voltage = %llduV\n",
@@ -470,7 +473,7 @@
 	}
 
 	result_gain = 0;
-	for (i = 0; i < SAMPLE_COUNT; i++) {
+	for (i = 0; i < sample_count; i++) {
 		rc = pm8xxx_writeb(the_chip->dev->parent,
 					ADC_ARB_SECP_RSV, CCADC_CALIB_RSV_25MV);
 		if (rc < 0) {
@@ -494,7 +497,7 @@
 
 		result_gain += result;
 	}
-	result_gain = result_gain / SAMPLE_COUNT;
+	result_gain = result_gain / sample_count;
 
 	/*
 	 * result_offset includes INTRINSIC OFFSET
@@ -519,6 +522,16 @@
 calibration_unlock:
 	mutex_unlock(&the_chip->calib_mutex);
 }
+
+static void pm8xxx_calib_ccadc_quick(void)
+{
+	__pm8xxx_calib_ccadc(2);
+}
+
+void pm8xxx_calib_ccadc(void)
+{
+	__pm8xxx_calib_ccadc(SAMPLE_COUNT);
+}
 EXPORT_SYMBOL(pm8xxx_calib_ccadc);
 
 static void calibrate_ccadc_work(struct work_struct *work)
@@ -737,6 +750,7 @@
 	chip->r_sense_uohm = pdata->r_sense_uohm;
 	chip->calib_delay_ms = pdata->calib_delay_ms;
 	chip->batt_temp_channel = pdata->ccadc_cdata.batt_temp_channel;
+	chip->periodic_wakeup = pdata->periodic_wakeup;
 	mutex_init(&chip->calib_mutex);
 
 	calib_ccadc_read_offset_and_gain(chip,
@@ -793,6 +807,12 @@
 		pr_err("unable to get current time: %d\n", rc);
 		return 0;
 	}
+
+	if (the_chip->periodic_wakeup) {
+		pm8xxx_calib_ccadc_quick();
+		return 0;
+	}
+
 	if (current_time_sec > the_chip->last_calib_time) {
 		time_since_last_calib = current_time_sec -
 					the_chip->last_calib_time;
@@ -803,9 +823,11 @@
 				|| delta_temp > CCADC_CALIB_TEMP_THRESH) {
 			the_chip->last_calib_time = current_time_sec;
 			the_chip->last_calib_temp = batt_temp;
-			pm8xxx_calib_ccadc();
+			cancel_delayed_work(&the_chip->calib_ccadc_work);
+			schedule_delayed_work(&the_chip->calib_ccadc_work, 0);
 		}
 	}
+
 	return 0;
 }
 
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index cb5be3d..37ac7b5 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -71,9 +71,9 @@
 #define BMS1_VBAT_AVG_DATA0		0x9E
 #define BMS1_VBAT_AVG_DATA1		0x9F
 /* Extra bms registers */
-#define BMS1_BMS_DATA_REG_0		0xB0
+#define SOC_STORAGE_REG			0xB0
 #define IAVG_STORAGE_REG		0xB1
-#define SOC_STORAGE_REG			0xB2
+#define BMS1_BMS_DATA_REG_2		0xB2
 #define BMS1_BMS_DATA_REG_3		0xB3
 /* IADC Channel Select */
 #define IADC1_BMS_ADC_CH_SEL_CTL	0x48
@@ -83,7 +83,7 @@
 #define IAVG_STEP_SIZE_MA		50
 #define IAVG_START			600
 #define IAVG_INVALID			0xFF
-#define SOC_ZERO			0xFF
+#define SOC_INVALID			0xFF
 
 #define IAVG_SAMPLES 16
 
@@ -135,6 +135,7 @@
 	struct sf_lut			*pc_sf_lut;
 	struct sf_lut			*rbatt_sf_lut;
 	int				default_rbatt_mohm;
+	int				rbatt_capacitive_mohm;
 
 	struct delayed_work		calculate_soc_delayed_work;
 	struct work_struct		recalc_work;
@@ -184,7 +185,6 @@
 	unsigned int			vadc_v1250;
 
 	int				ibat_max_ua;
-	int				prev_iavg_ua;
 	int				prev_uuc_iavg_ma;
 	int				prev_pc_unusable;
 	int				ibat_at_cv_ua;
@@ -624,7 +624,8 @@
 {
 	int ibat_ua, vbat_uv, ocv_est_uv;
 	int rc;
-	int rbatt_mohm = chip->default_rbatt_mohm + chip->r_conn_mohm;
+	int rbatt_mohm = chip->default_rbatt_mohm + chip->r_conn_mohm
+					+ chip->rbatt_capacitive_mohm;
 
 	rc = get_simultaneous_batt_v_and_i(chip, &ibat_ua, &vbat_uv);
 	if (rc) {
@@ -844,38 +845,35 @@
 	rbatt_mohm += chip->r_conn_mohm;
 	pr_debug("adding r_conn_mohm = %d rbatt = %d\n",
 				chip->r_conn_mohm, rbatt_mohm);
+	rbatt_mohm += chip->rbatt_capacitive_mohm;
+	pr_debug("adding rbatt_capacitive_mohm = %d rbatt = %d\n",
+				chip->rbatt_capacitive_mohm, rbatt_mohm);
 
 	pr_debug("RBATT = %d\n", rbatt_mohm);
 	return rbatt_mohm;
 }
 
+#define IAVG_MINIMAL_TIME	2
 static void calculate_iavg(struct qpnp_bms_chip *chip, int cc_uah,
 				int *iavg_ua, int delta_time_s)
 {
 	int delta_cc_uah = 0;
 
-	/* if anything fails report the previous iavg_ua */
-	*iavg_ua = chip->prev_iavg_ua;
-
-	if (chip->last_cc_uah == INT_MIN) {
+	/*
+	 * use the battery current if called too quickly
+	 */
+	if (delta_time_s < IAVG_MINIMAL_TIME
+			|| chip->last_cc_uah == INT_MIN) {
 		get_battery_current(chip, iavg_ua);
 		goto out;
 	}
 
-	/* use the previous iavg if called within 15 seconds */
-	if (delta_time_s < 15) {
-		*iavg_ua = chip->prev_iavg_ua;
-		goto out;
-	}
-
 	delta_cc_uah = cc_uah - chip->last_cc_uah;
 
 	*iavg_ua = div_s64((s64)delta_cc_uah * 3600, delta_time_s);
 
 out:
 	pr_debug("delta_cc = %d iavg_ua = %d\n", delta_cc_uah, (int)*iavg_ua);
-	/* remember the iavg */
-	chip->prev_iavg_ua = *iavg_ua;
 
 	/* remember cc_uah */
 	chip->last_cc_uah = cc_uah;
@@ -1228,6 +1226,10 @@
 
 	rc = get_simultaneous_batt_v_and_i(chip, &ibat_ua, &vbat_uv);
 
+	/*
+	 * Don't include rbatt and rbatt_capacitative since we expect this to
+	 * be used with a fake battery which does not have internal resistances
+	 */
 	ocv_est_uv = vbat_uv + (ibat_ua * chip->r_conn_mohm) / 1000;
 	pr_debug("forcing ocv to be %d due to bms reset mode\n", ocv_est_uv);
 	chip->last_ocv_uv = ocv_est_uv;
@@ -1734,10 +1736,7 @@
 	rc = qpnp_write_wrapper(chip, &temp,
 			chip->base + IAVG_STORAGE_REG, 1);
 
-	if (soc == 0)
-		temp = SOC_ZERO;
-	else
-		temp = soc;
+	temp = soc;
 
 	/* don't store soc if temperature is below 5degC */
 	if (batt_temp > IGNORE_SOC_TEMP_DECIDEG)
@@ -2069,12 +2068,10 @@
 		} else {
 			chip->shutdown_soc = temp;
 
-			if (chip->shutdown_soc == 0) {
+			if (chip->shutdown_soc == SOC_INVALID) {
 				pr_debug("No shutdown soc available\n");
 				chip->shutdown_soc_invalid = true;
 				chip->shutdown_iavg_ma = 0;
-			} else if (chip->shutdown_soc == SOC_ZERO) {
-				chip->shutdown_soc = 0;
 			}
 		}
 	}
@@ -2145,6 +2142,7 @@
 	chip->pc_sf_lut = batt_data->pc_sf_lut;
 	chip->rbatt_sf_lut = batt_data->rbatt_sf_lut;
 	chip->default_rbatt_mohm = batt_data->default_rbatt_mohm;
+	chip->rbatt_capacitive_mohm = batt_data->rbatt_capacitive_mohm;
 
 	if (chip->pc_temp_ocv_lut == NULL) {
 		pr_err("temp ocv lut table is NULL\n");
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index b479477..f4efa756 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -24,6 +24,7 @@
 #include <linux/qpnp/qpnp-adc.h>
 #include <linux/power_supply.h>
 #include <linux/bitops.h>
+#include <linux/ratelimit.h>
 
 /* Interrupt offsets */
 #define INT_RT_STS(base)			(base + 0x10)
@@ -949,6 +950,7 @@
 get_prop_capacity(struct qpnp_chg_chip *chip)
 {
 	union power_supply_propval ret = {0,};
+	bool usb_online, dc_online;
 
 	if (chip->use_default_batt_values || !get_prop_batt_present(chip))
 		return DEFAULT_CAPACITY;
@@ -956,6 +958,14 @@
 	if (chip->bms_psy) {
 		chip->bms_psy->get_property(chip->bms_psy,
 			  POWER_SUPPLY_PROP_CAPACITY, &ret);
+		if (ret.intval == 0) {
+			usb_online = chip->usb_psy->get_property(chip->usb_psy,
+					  POWER_SUPPLY_PROP_ONLINE, &ret);
+			dc_online = chip->dc_psy.get_property(&chip->dc_psy,
+					  POWER_SUPPLY_PROP_ONLINE, &ret);
+			if (!usb_online && !dc_online)
+				pr_warn_ratelimited("Battery 0, CHG absent\n");
+		}
 		return ret.intval;
 	} else {
 		pr_debug("No BMS supply registered return 50\n");
diff --git a/drivers/staging/android/switch/switch_class.c b/drivers/staging/android/switch/switch_class.c
index 7468044..3852c2c 100644
--- a/drivers/staging/android/switch/switch_class.c
+++ b/drivers/staging/android/switch/switch_class.c
@@ -151,8 +151,8 @@
 {
 	device_remove_file(sdev->dev, &dev_attr_name);
 	device_remove_file(sdev->dev, &dev_attr_state);
-	device_destroy(switch_class, MKDEV(0, sdev->index));
 	dev_set_drvdata(sdev->dev, NULL);
+	device_destroy(switch_class, MKDEV(0, sdev->index));
 }
 EXPORT_SYMBOL_GPL(switch_dev_unregister);
 
diff --git a/drivers/tty/serial/msm_serial_hs_lite.c b/drivers/tty/serial/msm_serial_hs_lite.c
index 8069b35..954848e 100644
--- a/drivers/tty/serial/msm_serial_hs_lite.c
+++ b/drivers/tty/serial/msm_serial_hs_lite.c
@@ -982,10 +982,6 @@
 			}
 		}
 	}
-#ifndef CONFIG_PM_RUNTIME
-	msm_hsl_init_clock(port);
-#endif
-	pm_runtime_get_sync(port->dev);
 
 	/*
 	 * Set RFR Level as 3/4 of UARTDM FIFO Size
@@ -1038,10 +1034,6 @@
 
 	free_irq(port->irq, port);
 
-#ifndef CONFIG_PM_RUNTIME
-	msm_hsl_deinit_clock(port);
-#endif
-	pm_runtime_put_sync(port->dev);
 	if (!(is_console(port)) || (!port->cons) ||
 		(port->cons && (!(port->cons->flags & CON_ENABLED)))) {
 		/* Free UART GPIOs */
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index f9a26cf..6619e96 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -461,6 +461,7 @@
 
 #define DWC3_ALIGN_MASK		(16 - 1)
 
+static u64 dwc3_dma_mask = DMA_BIT_MASK(64);
 static int __devinit dwc3_probe(struct platform_device *pdev)
 {
 	struct device_node	*node = pdev->dev.of_node;
@@ -483,6 +484,11 @@
 	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
 	dwc->mem = mem;
 
+	if (!dev->dma_mask)
+		dev->dma_mask = &dwc3_dma_mask;
+	if (!dev->coherent_dma_mask)
+		dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!res) {
 		dev_err(dev, "missing IRQ\n");
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 9fad90c..435ef3b 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -26,6 +26,7 @@
 #include <linux/types.h>
 #include <linux/delay.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/list.h>
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
@@ -63,6 +64,11 @@
 module_param(override_phy_init, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(override_phy_init, "Override HSPHY Init Seq");
 
+/* Enable Proprietary charger detection */
+static bool prop_chg_detect;
+module_param(prop_chg_detect, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(prop_chg_detect, "Enable Proprietary charger detection");
+
 /**
  *  USB DBM Hardware registers.
  *
@@ -152,7 +158,6 @@
 };
 
 struct dwc3_msm {
-	struct platform_device *dwc3;
 	struct device *dev;
 	void __iomem *base;
 	u32 resource_size;
@@ -220,7 +225,6 @@
 #define USB_SSPHY_1P8_HPM_LOAD		23000	/* uA */
 
 static struct dwc3_msm *context;
-static u64 dwc3_msm_dma_mask = DMA_BIT_MASK(64);
 
 static struct usb_ext_notification *usb_ext;
 
@@ -1391,12 +1395,12 @@
 static bool dwc3_chg_det_check_linestate(struct dwc3_msm *mdwc)
 {
 	u32 chg_det;
-	bool ret = false;
+
+	if (!prop_chg_detect)
+		return false;
 
 	chg_det = dwc3_msm_read_reg(mdwc->base, CHARGING_DET_OUTPUT_REG);
-	ret = chg_det & (3 << 8);
-
-	return ret;
+	return chg_det & (3 << 8);
 }
 
 static bool dwc3_chg_det_check_output(struct dwc3_msm *mdwc)
@@ -2214,10 +2218,10 @@
 static int __devinit dwc3_msm_probe(struct platform_device *pdev)
 {
 	struct device_node *node = pdev->dev.of_node;
-	struct platform_device *dwc3;
 	struct dwc3_msm *msm;
 	struct resource *res;
 	void __iomem *tcsr;
+	unsigned long flags;
 	int ret = 0;
 	int len = 0;
 	u32 tmp[3];
@@ -2430,6 +2434,11 @@
 					dev_err(&pdev->dev, "irqreq IDINT failed\n");
 					goto disable_hs_ldo;
 				}
+				local_irq_save(flags);
+				/* Update initial ID state */
+				msm->id_state = msm->ext_xceiv.id =
+					!!irq_read_line(msm->pmic_id_irq);
+				local_irq_restore(flags);
 				enable_irq_wake(msm->pmic_id_irq);
 			}
 		}
@@ -2476,19 +2485,7 @@
 		goto disable_hs_ldo;
 	}
 
-	dwc3 = platform_device_alloc("dwc3", -1);
-	if (!dwc3) {
-		dev_err(&pdev->dev, "couldn't allocate dwc3 device\n");
-		ret = -ENODEV;
-		goto disable_hs_ldo;
-	}
-
-	dwc3->dev.parent = &pdev->dev;
-	dwc3->dev.coherent_dma_mask = DMA_BIT_MASK(32);
-	dwc3->dev.dma_mask = &dwc3_msm_dma_mask;
-	dwc3->dev.dma_parms = pdev->dev.dma_parms;
 	msm->resource_size = resource_size(res);
-	msm->dwc3 = dwc3;
 
 	if (of_property_read_u32(node, "qcom,dwc-hsphy-init",
 						&msm->hsphy_init_seq))
@@ -2514,7 +2511,7 @@
 			"max: %d, dbm_num_eps: %d\n",
 			DBM_MAX_EPS, msm->dbm_num_eps);
 		ret = -ENODEV;
-		goto put_pdev;
+		goto disable_hs_ldo;
 	}
 
 	msm->usb_psy.name = "usb";
@@ -2534,20 +2531,16 @@
 		dev_err(&pdev->dev,
 				"%s:power_supply_register usb failed\n",
 					__func__);
-		goto put_pdev;
+		goto disable_hs_ldo;
 	}
 
-	ret = platform_device_add_resources(dwc3, pdev->resource,
-		pdev->num_resources);
-	if (ret) {
-		dev_err(&pdev->dev, "couldn't add resources to dwc3 device\n");
-		goto put_psupply;
-	}
-
-	ret = platform_device_add(dwc3);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to register dwc3 device\n");
-		goto put_psupply;
+	if (node) {
+		ret = of_platform_populate(node, NULL, NULL, &pdev->dev);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"failed to add create dwc3 core\n");
+			goto put_psupply;
+		}
 	}
 
 	msm->bus_scale_table = msm_bus_cl_get_pdata(pdev);
@@ -2592,11 +2585,8 @@
 
 put_xcvr:
 	usb_put_transceiver(msm->otg_xceiv);
-	platform_device_del(dwc3);
 put_psupply:
 	power_supply_unregister(&msm->usb_psy);
-put_pdev:
-	platform_device_put(dwc3);
 disable_hs_ldo:
 	dwc3_hsusb_ldo_enable(0);
 free_hs_ldo_init:
@@ -2647,7 +2637,6 @@
 	}
 
 	pm_runtime_disable(msm->dev);
-	platform_device_unregister(msm->dwc3);
 	wake_lock_destroy(&msm->wlock);
 
 	dwc3_hsusb_ldo_enable(0);
diff --git a/drivers/usb/dwc3/dwc3_otg.c b/drivers/usb/dwc3/dwc3_otg.c
index ca1f817..1d67cee 100644
--- a/drivers/usb/dwc3/dwc3_otg.c
+++ b/drivers/usb/dwc3/dwc3_otg.c
@@ -216,6 +216,8 @@
 						ext_xceiv->ext_block_reset)
 			ext_xceiv->ext_block_reset(true);
 
+		dwc3_otg_set_peripheral_regs(dotg);
+
 		/* re-init core and OTG registers as block reset clears these */
 		dwc3_post_host_reset_core_init(dwc);
 		if (ext_xceiv && !ext_xceiv->otg_capability)
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index a1d7a87..66854b2 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -756,6 +756,7 @@
 		dwc3_ep0_stall_and_restart(dwc);
 }
 
+bool zlp_required;
 static void dwc3_ep0_complete_data(struct dwc3 *dwc,
 		const struct dwc3_event_depevt *event)
 {
@@ -775,12 +776,18 @@
 
 	r = next_request(&ep0->request_list);
 	ur = &r->request;
+	if ((epnum & 1) && ur->zero &&
+		(ur->length % ep0->endpoint.maxpacket == 0)) {
+		zlp_required = true;
+		ur->zero = false;
+	}
 
 	trb = dwc->ep0_trb;
 
 	status = DWC3_TRB_SIZE_TRBSTS(trb->size);
 	if (status == DWC3_TRBSTS_SETUP_PENDING) {
 		dev_dbg(dwc->dev, "Setup Pending received\n");
+		zlp_required = false;
 
 		if (r)
 			dwc3_gadget_giveback(ep0, r, -ECONNRESET);
@@ -788,6 +795,9 @@
 		return;
 	}
 
+	if (zlp_required)
+		return;
+
 	length = trb->size & DWC3_TRB_SIZE_MASK;
 
 	if (dwc->ep0_bounced) {
@@ -930,6 +940,10 @@
 			return;
 		}
 
+		if (dep->number &&
+			!(req->request.length % dwc->gadget.ep0->maxpacket))
+			req->request.zero = true;
+
 		ret = dwc3_ep0_start_trans(dwc, dep->number, req->request.dma,
 				req->request.length, DWC3_TRBCTL_CONTROL_DATA);
 	}
@@ -993,7 +1007,11 @@
 static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
 		const struct dwc3_event_depevt *event)
 {
+	u8			epnum;
+	int			ret;
+
 	dwc->setup_packet_pending = true;
+	epnum = event->endpoint_number;
 
 	switch (event->status) {
 	case DEPEVT_STATUS_CONTROL_DATA:
@@ -1017,6 +1035,15 @@
 			return;
 		}
 
+		if (zlp_required) {
+			zlp_required = false;
+			ret = dwc3_ep0_start_trans(dwc, epnum,
+					dwc->ctrl_req_addr, 0,
+					DWC3_TRBCTL_CONTROL_DATA);
+			dbg_event(epnum, "ZLP", ret);
+			WARN_ON(ret < 0);
+		}
+
 		break;
 
 	case DEPEVT_STATUS_CONTROL_STATUS:
@@ -1025,6 +1052,7 @@
 
 		dev_vdbg(dwc->dev, "Control Status\n");
 
+		zlp_required = false;
 		dwc->ep0state = EP0_STATUS_PHASE;
 
 		if (dwc->delayed_status &&
diff --git a/drivers/usb/gadget/f_uac1.c b/drivers/usb/gadget/f_uac1.c
index 8c74381..e8c9667 100644
--- a/drivers/usb/gadget/f_uac1.c
+++ b/drivers/usb/gadget/f_uac1.c
@@ -463,6 +463,8 @@
 	struct list_head		capture_queue;
 	struct usb_request		*capture_req;
 
+	u8				alt_intf[F_AUDIO_NUM_INTERFACES];
+
 	/* Control Set command */
 	struct list_head		fu_cs;
 	struct list_head		ep_cs;
@@ -881,6 +883,18 @@
 	return value;
 }
 
+static int f_audio_get_alt(struct usb_function *f, unsigned intf)
+{
+	struct f_audio	*audio = func_to_audio(f);
+
+	if (intf == ac_header_desc.baInterfaceNr[0])
+		return audio->alt_intf[0];
+	if (intf == ac_header_desc.baInterfaceNr[1])
+		return audio->alt_intf[1];
+
+	return 0;
+}
+
 static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 {
 	struct f_audio		*audio = func_to_audio(f);
@@ -938,6 +952,7 @@
 			}
 			spin_unlock_irqrestore(&audio->capture_lock, flags);
 		}
+		audio->alt_intf[0] = alt;
 	} else if (intf == ac_header_desc.baInterfaceNr[1]) {
 		if (alt == 1) {
 			err = usb_ep_enable(out_ep);
@@ -986,10 +1001,12 @@
 				list_add_tail(&playback_copy_buf->list,
 						&audio->play_queue);
 				schedule_work(&audio->playback_work);
+				audio->playback_copy_buf = NULL;
 			} else {
 				pr_err("playback_buf is empty. Stop.");
 			}
 		}
+		audio->alt_intf[1] = alt;
 	} else {
 		pr_err("Interface %d. Do nothing. Return %d\n", intf, err);
 	}
@@ -1066,6 +1083,7 @@
 	microphone_as_interface_alt_0_desc.bInterfaceNumber = status;
 	microphone_as_interface_alt_1_desc.bInterfaceNumber = status;
 	ac_header_desc.baInterfaceNr[0] = status;
+	audio->alt_intf[0] = 0;
 
 	status = -ENODEV;
 
@@ -1077,6 +1095,7 @@
 	speaker_as_interface_alt_0_desc.bInterfaceNumber = status;
 	speaker_as_interface_alt_1_desc.bInterfaceNumber = status;
 	ac_header_desc.baInterfaceNr[1] = status;
+	audio->alt_intf[1] = 0;
 
 	status = -ENODEV;
 
@@ -1225,6 +1244,7 @@
 	audio->card.func.strings = audio_strings;
 	audio->card.func.bind = f_audio_bind;
 	audio->card.func.unbind = f_audio_unbind;
+	audio->card.func.get_alt = f_audio_get_alt;
 	audio->card.func.set_alt = f_audio_set_alt;
 	audio->card.func.setup = f_audio_setup;
 	audio->card.func.disable = f_audio_disable;
diff --git a/drivers/usb/gadget/u_rmnet_ctrl_smd.c b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
index 5817779..f60aa6a 100644
--- a/drivers/usb/gadget/u_rmnet_ctrl_smd.c
+++ b/drivers/usb/gadget/u_rmnet_ctrl_smd.c
@@ -422,6 +422,7 @@
 	unsigned long		flags;
 	struct smd_ch_info	*c;
 	struct rmnet_ctrl_pkt	*cpkt;
+	int clear_bits;
 
 	pr_debug("%s: grmnet:%p port#%d\n", __func__, gr, port_num);
 
@@ -453,9 +454,11 @@
 
 	spin_unlock_irqrestore(&port->port_lock, flags);
 
-	if (test_and_clear_bit(CH_OPENED, &c->flags))
+	if (test_and_clear_bit(CH_OPENED, &c->flags)) {
+		clear_bits = ~(c->cbits_tomodem | TIOCM_RTS);
 		/* send dtr zero */
-		smd_tiocmset(c->ch, c->cbits_tomodem, ~c->cbits_tomodem);
+		smd_tiocmset(c->ch, c->cbits_tomodem, clear_bits);
+	}
 
 	if (c->ch) {
 		smd_close(c->ch);
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 5750e0d..cae2c17 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -3897,7 +3897,20 @@
 		ret = PTR_ERR(motg->core_clk);
 		goto put_clk;
 	}
-	clk_set_rate(motg->core_clk, INT_MAX);
+
+	/*
+	 * Get Max supported clk frequency for USB Core CLK and request
+	 * to set the same.
+	 */
+	motg->core_clk_rate = clk_round_rate(motg->core_clk, LONG_MAX);
+	if (IS_ERR_VALUE(motg->core_clk_rate)) {
+		dev_err(&pdev->dev, "fail to get core clk max freq.\n");
+	} else {
+		ret = clk_set_rate(motg->core_clk, motg->core_clk_rate);
+		if (ret)
+			dev_err(&pdev->dev, "fail to set core_clk freq:%d\n",
+									ret);
+	}
 
 	motg->pclk = clk_get(&pdev->dev, "iface_clk");
 	if (IS_ERR(motg->pclk)) {
diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
index faf3e6f..8bf8c95 100644
--- a/drivers/video/msm/mdss/mdss_dsi.c
+++ b/drivers/video/msm/mdss/mdss_dsi.c
@@ -477,7 +477,7 @@
 	struct mdss_panel_info *pinfo;
 	struct mipi_panel_info *mipi;
 	u32 hbp, hfp, vbp, vfp, hspw, vspw, width, height;
-	u32 ystride, bpp, data;
+	u32 ystride, bpp, data, dst_bpp;
 	u32 dummy_xres, dummy_yres;
 	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
 
@@ -516,13 +516,22 @@
 	clk_rate = pdata->panel_info.clk_rate;
 	clk_rate = min(clk_rate, pdata->panel_info.clk_max);
 
-	hbp = pdata->panel_info.lcdc.h_back_porch;
-	hfp = pdata->panel_info.lcdc.h_front_porch;
-	vbp = pdata->panel_info.lcdc.v_back_porch;
-	vfp = pdata->panel_info.lcdc.v_front_porch;
-	hspw = pdata->panel_info.lcdc.h_pulse_width;
+	dst_bpp = pdata->panel_info.fbc.enabled ?
+		(pdata->panel_info.fbc.target_bpp) : (pinfo->bpp);
+
+	hbp = mult_frac(pdata->panel_info.lcdc.h_back_porch, dst_bpp,
+			pdata->panel_info.bpp);
+	hfp = mult_frac(pdata->panel_info.lcdc.h_front_porch, dst_bpp,
+			pdata->panel_info.bpp);
+	vbp = mult_frac(pdata->panel_info.lcdc.v_back_porch, dst_bpp,
+			pdata->panel_info.bpp);
+	vfp = mult_frac(pdata->panel_info.lcdc.v_front_porch, dst_bpp,
+			pdata->panel_info.bpp);
+	hspw = mult_frac(pdata->panel_info.lcdc.h_pulse_width, dst_bpp,
+			pdata->panel_info.bpp);
 	vspw = pdata->panel_info.lcdc.v_pulse_width;
-	width = pdata->panel_info.xres;
+	width = mult_frac(pdata->panel_info.xres, dst_bpp,
+			pdata->panel_info.bpp);
 	height = pdata->panel_info.yres;
 
 	mipi  = &pdata->panel_info.mipi;
diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c
index d24ed16..c56cd41 100644
--- a/drivers/video/msm/mdss/mdss_dsi_panel.c
+++ b/drivers/video/msm/mdss/mdss_dsi_panel.c
@@ -227,6 +227,7 @@
 {
 	struct device_node *np = pdev->dev.of_node;
 	u32 res[6], tmp;
+	u32 fbc_res[7];
 	int rc, i, len;
 	int cmd_plen, data_offset;
 	const char *data;
@@ -234,6 +235,7 @@
 	static const char *on_cmds_state, *off_cmds_state;
 	char *on_cmds = NULL, *off_cmds = NULL;
 	int num_of_on_cmds = 0, num_of_off_cmds = 0;
+	bool fbc_enabled = false;
 
 	rc = of_property_read_u32_array(np, "qcom,mdss-pan-res", res, 2);
 	if (rc) {
@@ -480,6 +482,53 @@
 
 	panel_data->panel_info.mipi.dsi_phy_db = &phy_params;
 
+	fbc_enabled = of_property_read_bool(np,
+			"qcom,fbc-enabled");
+	if (fbc_enabled) {
+		pr_debug("%s:%d FBC panel enabled.\n", __func__, __LINE__);
+		panel_data->panel_info.fbc.enabled = 1;
+
+		rc = of_property_read_u32_array(np,
+				"qcom,fbc-mode", fbc_res, 7);
+		panel_data->panel_info.fbc.target_bpp =
+			(!rc ?	fbc_res[0] : panel_data->panel_info.bpp);
+		panel_data->panel_info.fbc.comp_mode = (!rc ? fbc_res[1] : 0);
+		panel_data->panel_info.fbc.qerr_enable =
+			(!rc ? fbc_res[2] : 0);
+		panel_data->panel_info.fbc.cd_bias = (!rc ? fbc_res[3] : 0);
+		panel_data->panel_info.fbc.pat_enable = (!rc ? fbc_res[4] : 0);
+		panel_data->panel_info.fbc.vlc_enable = (!rc ? fbc_res[5] : 0);
+		panel_data->panel_info.fbc.bflc_enable =
+			(!rc ? fbc_res[6] : 0);
+
+		rc = of_property_read_u32_array(np,
+				"qcom,fbc-budget-ctl", fbc_res, 3);
+		panel_data->panel_info.fbc.line_x_budget =
+			(!rc ? fbc_res[0] : 0);
+		panel_data->panel_info.fbc.block_x_budget =
+			(!rc ? fbc_res[1] : 0);
+		panel_data->panel_info.fbc.block_budget =
+			(!rc ? fbc_res[2] : 0);
+
+		rc = of_property_read_u32_array(np,
+				"qcom,fbc-lossy-mode", fbc_res, 4);
+		panel_data->panel_info.fbc.lossless_mode_thd =
+			(!rc ? fbc_res[0] : 0);
+		panel_data->panel_info.fbc.lossy_mode_thd =
+			(!rc ? fbc_res[1] : 0);
+		panel_data->panel_info.fbc.lossy_rgb_thd =
+			(!rc ? fbc_res[2] : 0);
+		panel_data->panel_info.fbc.lossy_mode_idx =
+			(!rc ? fbc_res[3] : 0);
+
+	} else {
+		pr_debug("%s:%d Panel does not support FBC.\n",
+				__func__, __LINE__);
+		panel_data->panel_info.fbc.enabled = 0;
+		panel_data->panel_info.fbc.target_bpp =
+			panel_data->panel_info.bpp;
+	}
+
 	data = of_get_property(np, "qcom,panel-on-cmds", &len);
 	if (!data) {
 		pr_err("%s:%d, Unable to read ON cmds", __func__, __LINE__);
diff --git a/drivers/video/msm/mdss/mdss_hdmi_edid.c b/drivers/video/msm/mdss/mdss_hdmi_edid.c
index 08be337..e87f028 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_edid.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_edid.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -244,14 +244,14 @@
 				continue;
 			if (ret > 0)
 				ret += snprintf(buf+ret, PAGE_SIZE-ret, ",%d",
-					*video_mode++ + 1);
+					*video_mode++);
 			else
 				ret += snprintf(buf+ret, PAGE_SIZE-ret, "%d",
-					*video_mode++ + 1);
+					*video_mode++);
 		}
 	} else {
 		ret += snprintf(buf+ret, PAGE_SIZE-ret, "%d",
-			edid_ctrl->video_resolution+1);
+			edid_ctrl->video_resolution);
 	}
 
 	DEV_DBG("%s: '%s'\n", __func__, buf);
@@ -324,16 +324,16 @@
 				buff_3d);
 			if (ret > 0)
 				ret += snprintf(buf+ret, PAGE_SIZE-ret,
-					",%d=%s", *video_mode++ + 1,
+					",%d=%s", *video_mode++,
 					buff_3d);
 			else
 				ret += snprintf(buf+ret, PAGE_SIZE-ret,
-					"%d=%s", *video_mode++ + 1,
+					"%d=%s", *video_mode++,
 					buff_3d);
 		}
 	} else {
 		ret += snprintf(buf+ret, PAGE_SIZE-ret, "%d",
-			edid_ctrl->video_resolution+1);
+			edid_ctrl->video_resolution);
 	}
 
 	DEV_DBG("%s: '%s'\n", __func__, buf);
@@ -817,25 +817,25 @@
 	hdmi_get_video_3d_fmt_2string(video_3d_format, string);
 
 	DEV_DBG("%s: EDID[3D]: format: %d [%s], %s %s\n", __func__,
-		video_format, hdmi_get_video_fmt_2string(video_format),
+		video_format, msm_hdmi_mode_2string(video_format),
 		string, added ? "added" : "NOT added");
 } /* hdmi_edid_add_sink_3d_format */
 
 static void hdmi_edid_add_sink_video_format(
 	struct hdmi_edid_sink_data *sink_data, u32 video_format)
 {
-	const struct hdmi_disp_mode_timing_type *timing =
+	const struct msm_hdmi_mode_timing_info *timing =
 		hdmi_get_supported_mode(video_format);
 	u32 supported = timing != NULL;
 
 	if (video_format >= HDMI_VFRMT_MAX) {
 		DEV_ERR("%s: video format: %s is not supported\n", __func__,
-			hdmi_get_video_fmt_2string(video_format));
+			msm_hdmi_mode_2string(video_format));
 		return;
 	}
 
 	DEV_DBG("%s: EDID: format: %d [%s], %s\n", __func__,
-		video_format, hdmi_get_video_fmt_2string(video_format),
+		video_format, msm_hdmi_mode_2string(video_format),
 		supported ? "Supported" : "Not-Supported");
 
 	if (supported) {
@@ -1050,7 +1050,7 @@
 			 * while the Video identification code is 1 based in the
 			 * CEA_861D spec
 			 */
-			video_format = (*svd & 0x7F) - 1;
+			video_format = (*svd & 0x7F);
 			hdmi_edid_add_sink_video_format(sink_data,
 				video_format);
 			/* Make a note of the preferred video format */
@@ -1096,7 +1096,7 @@
 
 			DEV_DBG("[%s:%d] Block-0 Adding vid fmt = [%s]\n",
 				__func__, __LINE__,
-				hdmi_get_video_fmt_2string(video_format));
+				msm_hdmi_mode_2string(video_format));
 
 			hdmi_edid_add_sink_video_format(sink_data,
 				video_format);
@@ -1125,7 +1125,7 @@
 
 			DEV_DBG("[%s:%d] Block-0 Adding vid fmt = [%s]\n",
 				__func__, __LINE__,
-				hdmi_get_video_fmt_2string(video_format));
+				msm_hdmi_mode_2string(video_format));
 
 			hdmi_edid_add_sink_video_format(sink_data,
 				video_format);
@@ -1158,7 +1158,7 @@
 
 			DEV_DBG("[%s:%d] Block-1 Adding vid fmt = [%s]\n",
 				__func__, __LINE__,
-				hdmi_get_video_fmt_2string(video_format));
+				msm_hdmi_mode_2string(video_format));
 
 			hdmi_edid_add_sink_video_format(sink_data,
 				video_format);
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index 6a96369..94c0da2 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -207,7 +207,7 @@
 {
 	int new_vic = -1;
 	u32 h_total, v_total;
-	struct hdmi_disp_mode_timing_type timing;
+	struct msm_hdmi_mode_timing_info timing;
 
 	if (!hdmi_ctrl || !pinfo) {
 		DEV_ERR("%s: invalid input\n", __func__);
@@ -215,13 +215,13 @@
 	}
 
 	if (pinfo->vic) {
-		if (hdmi_get_supported_mode(pinfo->vic - 1)) {
-			new_vic = pinfo->vic - 1;
+		if (hdmi_get_supported_mode(pinfo->vic)) {
+			new_vic = pinfo->vic;
 			DEV_DBG("%s: %s is supported\n", __func__,
-				hdmi_get_video_fmt_2string(new_vic));
+				msm_hdmi_mode_2string(new_vic));
 		} else {
-			DEV_ERR("%s: invalid or not supported vic\n",
-				__func__);
+			DEV_ERR("%s: invalid or not supported vic %d\n",
+				__func__, pinfo->vic);
 			return -EPERM;
 		}
 	} else {
@@ -580,7 +580,7 @@
 static int hdmi_tx_init_panel_info(uint32_t resolution,
 	struct mdss_panel_info *pinfo)
 {
-	const struct hdmi_disp_mode_timing_type *timing =
+	const struct msm_hdmi_mode_timing_info *timing =
 		hdmi_get_supported_mode(resolution);
 
 	if (!timing || !pinfo) {
@@ -612,42 +612,12 @@
 	return 0;
 } /* hdmi_tx_init_panel_info */
 
-/* Table indicating the video format supported by the HDMI TX Core */
-/* Valid pclk rates (Mhz): 25.2, 27, 27.03, 74.25, 148.5, 268.5, 297 */
-static void hdmi_tx_setup_video_mode_lut(void)
-{
-	hdmi_init_supported_video_timings();
-
-	hdmi_set_supported_mode(HDMI_VFRMT_640x480p60_4_3);
-	hdmi_set_supported_mode(HDMI_VFRMT_720x480p60_4_3);
-	hdmi_set_supported_mode(HDMI_VFRMT_720x480p60_16_9);
-	hdmi_set_supported_mode(HDMI_VFRMT_720x576p50_4_3);
-	hdmi_set_supported_mode(HDMI_VFRMT_720x576p50_16_9);
-	hdmi_set_supported_mode(HDMI_VFRMT_1440x480i60_4_3);
-	hdmi_set_supported_mode(HDMI_VFRMT_1440x480i60_16_9);
-	hdmi_set_supported_mode(HDMI_VFRMT_1440x576i50_4_3);
-	hdmi_set_supported_mode(HDMI_VFRMT_1440x576i50_16_9);
-	hdmi_set_supported_mode(HDMI_VFRMT_1280x720p50_16_9);
-	hdmi_set_supported_mode(HDMI_VFRMT_1280x720p60_16_9);
-	hdmi_set_supported_mode(HDMI_VFRMT_1920x1080p24_16_9);
-	hdmi_set_supported_mode(HDMI_VFRMT_1920x1080p25_16_9);
-	hdmi_set_supported_mode(HDMI_VFRMT_1920x1080p30_16_9);
-	hdmi_set_supported_mode(HDMI_VFRMT_1920x1080p50_16_9);
-	hdmi_set_supported_mode(HDMI_VFRMT_1920x1080i60_16_9);
-	hdmi_set_supported_mode(HDMI_VFRMT_1920x1080p60_16_9);
-	hdmi_set_supported_mode(HDMI_VFRMT_2560x1600p60_16_9);
-	hdmi_set_supported_mode(HDMI_VFRMT_3840x2160p30_16_9);
-	hdmi_set_supported_mode(HDMI_VFRMT_3840x2160p25_16_9);
-	hdmi_set_supported_mode(HDMI_VFRMT_3840x2160p24_16_9);
-	hdmi_set_supported_mode(HDMI_VFRMT_4096x2160p24_16_9);
-} /* hdmi_tx_setup_video_mode_lut */
-
 /* Table tuned to indicate video formats supported by the MHL Tx */
 /* Valid pclk rates (Mhz): 25.2, 27, 27.03, 74.25 */
 static void hdmi_tx_setup_mhl_video_mode_lut(struct hdmi_tx_ctrl *hdmi_ctrl)
 {
 	u32 i;
-	struct hdmi_disp_mode_timing_type *temp_timing;
+	struct msm_hdmi_mode_timing_info *temp_timing;
 
 	if (!hdmi_ctrl->mhl_max_pclk) {
 		DEV_WARN("%s: mhl max pclk not set!\n", __func__);
@@ -657,7 +627,7 @@
 		__func__, hdmi_ctrl->mhl_max_pclk);
 	for (i = 0; i < HDMI_VFRMT_MAX; i++) {
 		temp_timing =
-		(struct hdmi_disp_mode_timing_type *)hdmi_get_supported_mode(i);
+		(struct msm_hdmi_mode_timing_info *)hdmi_get_supported_mode(i);
 		if (!temp_timing)
 			continue;
 		/* formats that exceed max mhl line clk bw */
@@ -765,7 +735,7 @@
 	struct mdss_panel_info *pinfo)
 {
 	int new_vic = -1;
-	const struct hdmi_disp_mode_timing_type *timing = NULL;
+	const struct msm_hdmi_mode_timing_info *timing = NULL;
 
 	if (!hdmi_ctrl || !pinfo) {
 		DEV_ERR("%s: invalid input\n", __func__);
@@ -779,8 +749,8 @@
 	}
 
 	DEV_DBG("%s: switching from %s => %s", __func__,
-		hdmi_get_video_fmt_2string(hdmi_ctrl->video_resolution),
-		hdmi_get_video_fmt_2string(new_vic));
+		msm_hdmi_mode_2string(hdmi_ctrl->video_resolution),
+		msm_hdmi_mode_2string(new_vic));
 
 	hdmi_ctrl->video_resolution = (u32)new_vic;
 
@@ -808,7 +778,7 @@
 	u32 end_v     = 0;
 	struct dss_io_data *io = NULL;
 
-	const struct hdmi_disp_mode_timing_type *timing =
+	const struct msm_hdmi_mode_timing_info *timing =
 		hdmi_get_supported_mode(video_format);
 	if (timing == NULL) {
 		DEV_ERR("%s: video format not supported: %d\n", __func__,
@@ -1521,7 +1491,7 @@
 	acr_pck_ctrl_reg = DSS_REG_R(io, HDMI_ACR_PKT_CTRL);
 
 	if (enabled) {
-		const struct hdmi_disp_mode_timing_type *timing =
+		const struct msm_hdmi_mode_timing_info *timing =
 			hdmi_get_supported_mode(hdmi_ctrl->video_resolution);
 		const struct hdmi_tx_audio_acr_arry *audio_acr =
 			&hdmi_tx_audio_acr_lut[0];
@@ -2152,7 +2122,7 @@
 
 	hdmi_ctrl->hdcp_feature_on = hdcp_feature_on;
 
-	DEV_INFO("power: ON (%s)\n", hdmi_get_video_fmt_2string(
+	DEV_INFO("power: ON (%s)\n", msm_hdmi_mode_2string(
 		hdmi_ctrl->video_resolution));
 
 	rc = hdmi_tx_core_on(hdmi_ctrl);
@@ -2381,7 +2351,7 @@
 	/* irq enable/disable will be handled in hpd on/off */
 	hdmi_tx_hw.ptr = (void *)hdmi_ctrl;
 
-	hdmi_tx_setup_video_mode_lut();
+	hdmi_setup_video_mode_lut();
 	mutex_init(&hdmi_ctrl->mutex);
 	hdmi_ctrl->workq = create_workqueue("hdmi_tx_workq");
 	if (!hdmi_ctrl->workq) {
diff --git a/drivers/video/msm/mdss/mdss_hdmi_util.c b/drivers/video/msm/mdss/mdss_hdmi_util.c
index 07c2336..0c8b0f8 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_util.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_util.c
@@ -15,38 +15,22 @@
 #include <mach/board.h>
 #include "mdss_hdmi_util.h"
 
-static struct hdmi_disp_mode_timing_type
+static struct msm_hdmi_mode_timing_info
 	hdmi_supported_video_mode_lut[HDMI_VFRMT_MAX];
 
-#define HDMI_SETUP_LUT(MODE) do {					\
-	struct hdmi_disp_mode_timing_type mode = HDMI_SETTINGS_##MODE;	\
-	hdmi_supported_video_mode_lut[mode.video_format] = mode;	\
-	} while (0)
-
-void hdmi_init_supported_video_timings(void)
-{
-	int i;
-
-	for (i = 0; i < HDMI_VFRMT_MAX; i++) {
-		struct hdmi_disp_mode_timing_type mode = VFRMT_NOT_SUPPORTED(i);
-
-		hdmi_supported_video_mode_lut[i] = mode;
-	}
-} /* hdmi_init_supported_video_timings */
-
 void hdmi_del_supported_mode(u32 mode)
 {
-	struct hdmi_disp_mode_timing_type *ret = NULL;
+	struct msm_hdmi_mode_timing_info *ret = NULL;
 	DEV_DBG("%s: removing %s\n", __func__,
-		 hdmi_get_video_fmt_2string(mode));
+		 msm_hdmi_mode_2string(mode));
 	ret = &hdmi_supported_video_mode_lut[mode];
 	if (ret != NULL && ret->supported)
 		ret->supported = false;
 }
 
-const struct hdmi_disp_mode_timing_type *hdmi_get_supported_mode(u32 mode)
+const struct msm_hdmi_mode_timing_info *hdmi_get_supported_mode(u32 mode)
 {
-	const struct hdmi_disp_mode_timing_type *ret = NULL;
+	const struct msm_hdmi_mode_timing_info *ret = NULL;
 
 	if (mode >= HDMI_VFRMT_MAX)
 		return NULL;
@@ -59,7 +43,7 @@
 	return ret;
 } /* hdmi_get_supported_mode */
 
-int hdmi_get_video_id_code(struct hdmi_disp_mode_timing_type *timing_in)
+int hdmi_get_video_id_code(struct msm_hdmi_mode_timing_info *timing_in)
 {
 	int i, vic = -1;
 
@@ -70,7 +54,7 @@
 
 	/* active_low_h, active_low_v and interlaced are not checked against */
 	for (i = 0; i < HDMI_VFRMT_MAX; i++) {
-		struct hdmi_disp_mode_timing_type *supported_timing =
+		struct msm_hdmi_mode_timing_info *supported_timing =
 			&hdmi_supported_video_mode_lut[i];
 
 		if (!supported_timing->supported)
@@ -105,155 +89,29 @@
 
 exit:
 	DEV_DBG("%s: vic = %d timing = %s\n", __func__, vic,
-		hdmi_get_video_fmt_2string((u32)vic));
+		msm_hdmi_mode_2string((u32)vic));
 
 	return vic;
 } /* hdmi_get_video_id_code */
 
-void hdmi_set_supported_mode(u32 mode)
+/* Table indicating the video format supported by the HDMI TX Core */
+/* Valid pclk rates (Mhz): 25.2, 27, 27.03, 74.25, 148.5, 268.5, 297 */
+void hdmi_setup_video_mode_lut(void)
 {
-	switch (mode) {
-	case HDMI_VFRMT_640x480p60_4_3:
-		HDMI_SETUP_LUT(640x480p60_4_3);
-		break;
-	case HDMI_VFRMT_720x480p60_4_3:
-		HDMI_SETUP_LUT(720x480p60_4_3);
-		break;
-	case HDMI_VFRMT_720x480p60_16_9:
-		HDMI_SETUP_LUT(720x480p60_16_9);
-		break;
-	case HDMI_VFRMT_720x576p50_4_3:
-		HDMI_SETUP_LUT(720x576p50_4_3);
-		break;
-	case HDMI_VFRMT_720x576p50_16_9:
-		HDMI_SETUP_LUT(720x576p50_16_9);
-		break;
-	case HDMI_VFRMT_1440x480i60_4_3:
-		HDMI_SETUP_LUT(1440x480i60_4_3);
-		break;
-	case HDMI_VFRMT_1440x480i60_16_9:
-		HDMI_SETUP_LUT(1440x480i60_16_9);
-		break;
-	case HDMI_VFRMT_1440x576i50_4_3:
-		HDMI_SETUP_LUT(1440x576i50_4_3);
-		break;
-	case HDMI_VFRMT_1440x576i50_16_9:
-		HDMI_SETUP_LUT(1440x576i50_16_9);
-		break;
-	case HDMI_VFRMT_1280x720p50_16_9:
-		HDMI_SETUP_LUT(1280x720p50_16_9);
-		break;
-	case HDMI_VFRMT_1280x720p60_16_9:
-		HDMI_SETUP_LUT(1280x720p60_16_9);
-		break;
-	case HDMI_VFRMT_1920x1080p24_16_9:
-		HDMI_SETUP_LUT(1920x1080p24_16_9);
-		break;
-	case HDMI_VFRMT_1920x1080p25_16_9:
-		HDMI_SETUP_LUT(1920x1080p25_16_9);
-		break;
-	case HDMI_VFRMT_1920x1080p30_16_9:
-		HDMI_SETUP_LUT(1920x1080p30_16_9);
-		break;
-	case HDMI_VFRMT_1920x1080p50_16_9:
-		HDMI_SETUP_LUT(1920x1080p50_16_9);
-		break;
-	case HDMI_VFRMT_1920x1080i60_16_9:
-		HDMI_SETUP_LUT(1920x1080i60_16_9);
-		break;
-	case HDMI_VFRMT_1920x1080p60_16_9:
-		HDMI_SETUP_LUT(1920x1080p60_16_9);
-		break;
-	case HDMI_VFRMT_2560x1600p60_16_9:
-		HDMI_SETUP_LUT(2560x1600p60_16_9);
-		break;
-	case HDMI_VFRMT_3840x2160p30_16_9:
-		HDMI_SETUP_LUT(3840x2160p30_16_9);
-		break;
-	case HDMI_VFRMT_3840x2160p25_16_9:
-		HDMI_SETUP_LUT(3840x2160p25_16_9);
-		break;
-	case HDMI_VFRMT_3840x2160p24_16_9:
-		HDMI_SETUP_LUT(3840x2160p24_16_9);
-		break;
-	case HDMI_VFRMT_4096x2160p24_16_9:
-		HDMI_SETUP_LUT(4096x2160p24_16_9);
-		break;
-	default:
-		DEV_ERR("%s: unsupported mode=%d\n", __func__, mode);
-	}
-} /* hdmi_set_supported_mode */
+	MSM_HDMI_MODES_INIT_TIMINGS(hdmi_supported_video_mode_lut);
 
-const char *hdmi_get_video_fmt_2string(u32 format)
-{
-	switch (format) {
-	case HDMI_VFRMT_640x480p60_4_3:    return " 640x 480 p60  4/3";
-	case HDMI_VFRMT_720x480p60_4_3:    return " 720x 480 p60  4/3";
-	case HDMI_VFRMT_720x480p60_16_9:   return " 720x 480 p60 16/9";
-	case HDMI_VFRMT_1280x720p60_16_9:  return "1280x 720 p60 16/9";
-	case HDMI_VFRMT_1920x1080i60_16_9: return "1920x1080 i60 16/9";
-	case HDMI_VFRMT_1440x480i60_4_3:   return "1440x 480 i60  4/3";
-	case HDMI_VFRMT_1440x480i60_16_9:  return "1440x 480 i60 16/9";
-	case HDMI_VFRMT_1440x240p60_4_3:   return "1440x 240 p60  4/3";
-	case HDMI_VFRMT_1440x240p60_16_9:  return "1440x 240 p60 16/9";
-	case HDMI_VFRMT_2880x480i60_4_3:   return "2880x 480 i60  4/3";
-	case HDMI_VFRMT_2880x480i60_16_9:  return "2880x 480 i60 16/9";
-	case HDMI_VFRMT_2880x240p60_4_3:   return "2880x 240 p60  4/3";
-	case HDMI_VFRMT_2880x240p60_16_9:  return "2880x 240 p60 16/9";
-	case HDMI_VFRMT_1440x480p60_4_3:   return "1440x 480 p60  4/3";
-	case HDMI_VFRMT_1440x480p60_16_9:  return "1440x 480 p60 16/9";
-	case HDMI_VFRMT_1920x1080p60_16_9: return "1920x1080 p60 16/9";
-	case HDMI_VFRMT_720x576p50_4_3:    return " 720x 576 p50  4/3";
-	case HDMI_VFRMT_720x576p50_16_9:   return " 720x 576 p50 16/9";
-	case HDMI_VFRMT_1280x720p50_16_9:  return "1280x 720 p50 16/9";
-	case HDMI_VFRMT_1920x1080i50_16_9: return "1920x1080 i50 16/9";
-	case HDMI_VFRMT_1440x576i50_4_3:   return "1440x 576 i50  4/3";
-	case HDMI_VFRMT_1440x576i50_16_9:  return "1440x 576 i50 16/9";
-	case HDMI_VFRMT_1440x288p50_4_3:   return "1440x 288 p50  4/3";
-	case HDMI_VFRMT_1440x288p50_16_9:  return "1440x 288 p50 16/9";
-	case HDMI_VFRMT_2880x576i50_4_3:   return "2880x 576 i50  4/3";
-	case HDMI_VFRMT_2880x576i50_16_9:  return "2880x 576 i50 16/9";
-	case HDMI_VFRMT_2880x288p50_4_3:   return "2880x 288 p50  4/3";
-	case HDMI_VFRMT_2880x288p50_16_9:  return "2880x 288 p50 16/9";
-	case HDMI_VFRMT_1440x576p50_4_3:   return "1440x 576 p50  4/3";
-	case HDMI_VFRMT_1440x576p50_16_9:  return "1440x 576 p50 16/9";
-	case HDMI_VFRMT_1920x1080p50_16_9: return "1920x1080 p50 16/9";
-	case HDMI_VFRMT_1920x1080p24_16_9: return "1920x1080 p24 16/9";
-	case HDMI_VFRMT_1920x1080p25_16_9: return "1920x1080 p25 16/9";
-	case HDMI_VFRMT_1920x1080p30_16_9: return "1920x1080 p30 16/9";
-	case HDMI_VFRMT_2880x480p60_4_3:   return "2880x 480 p60  4/3";
-	case HDMI_VFRMT_2880x480p60_16_9:  return "2880x 480 p60 16/9";
-	case HDMI_VFRMT_2880x576p50_4_3:   return "2880x 576 p50  4/3";
-	case HDMI_VFRMT_2880x576p50_16_9:  return "2880x 576 p50 16/9";
-	case HDMI_VFRMT_1920x1250i50_16_9: return "1920x1250 i50 16/9";
-	case HDMI_VFRMT_1920x1080i100_16_9:return "1920x1080 i100 16/9";
-	case HDMI_VFRMT_1280x720p100_16_9: return "1280x 720 p100 16/9";
-	case HDMI_VFRMT_720x576p100_4_3:   return " 720x 576 p100  4/3";
-	case HDMI_VFRMT_720x576p100_16_9:  return " 720x 576 p100 16/9";
-	case HDMI_VFRMT_1440x576i100_4_3:  return "1440x 576 i100  4/3";
-	case HDMI_VFRMT_1440x576i100_16_9: return "1440x 576 i100 16/9";
-	case HDMI_VFRMT_1920x1080i120_16_9:return "1920x1080 i120 16/9";
-	case HDMI_VFRMT_1280x720p120_16_9: return "1280x 720 p120 16/9";
-	case HDMI_VFRMT_720x480p120_4_3:   return " 720x 480 p120  4/3";
-	case HDMI_VFRMT_720x480p120_16_9:  return " 720x 480 p120 16/9";
-	case HDMI_VFRMT_1440x480i120_4_3:  return "1440x 480 i120  4/3";
-	case HDMI_VFRMT_1440x480i120_16_9: return "1440x 480 i120 16/9";
-	case HDMI_VFRMT_720x576p200_4_3:   return " 720x 576 p200  4/3";
-	case HDMI_VFRMT_720x576p200_16_9:  return " 720x 576 p200 16/9";
-	case HDMI_VFRMT_1440x576i200_4_3:  return "1440x 576 i200  4/3";
-	case HDMI_VFRMT_1440x576i200_16_9: return "1440x 576 i200 16/9";
-	case HDMI_VFRMT_720x480p240_4_3:   return " 720x 480 p240  4/3";
-	case HDMI_VFRMT_720x480p240_16_9:  return " 720x 480 p240 16/9";
-	case HDMI_VFRMT_1440x480i240_4_3:  return "1440x 480 i240  4/3";
-	case HDMI_VFRMT_1440x480i240_16_9: return "1440x 480 i240 16/9";
-	case HDMI_VFRMT_2560x1600p60_16_9: return "2560x1600 p60 16/9";
-	case HDMI_VFRMT_3840x2160p30_16_9: return "3840x2160 p30 16/9";
-	case HDMI_VFRMT_3840x2160p25_16_9: return "3840x2160 p25 16/9";
-	case HDMI_VFRMT_3840x2160p24_16_9: return "3840x2160 p24 16/9";
-	case HDMI_VFRMT_4096x2160p24_16_9: return "4096x2160 p24 16/9";
-	default:                           return "???";
-	}
-} /* hdmi_get_video_fmt_2string */
+	/* Add all supported CEA modes to the lut */
+	MSM_HDMI_MODES_SET_SUPP_TIMINGS(
+		hdmi_supported_video_mode_lut, MSM_HDMI_MODES_CEA);
+
+	/* Add all supported extended hdmi modes to the lut */
+	MSM_HDMI_MODES_SET_SUPP_TIMINGS(
+		hdmi_supported_video_mode_lut, MSM_HDMI_MODES_XTND);
+
+	/* Add any other specific DVI timings (DVI modes, etc.) */
+	MSM_HDMI_MODES_SET_TIMING(hdmi_supported_video_mode_lut,
+		HDMI_VFRMT_2560x1600p60_16_9);
+} /* hdmi_setup_video_mode_lut */
 
 const char *hdmi_get_single_video_3d_fmt_2string(u32 format)
 {
diff --git a/drivers/video/msm/mdss/mdss_hdmi_util.h b/drivers/video/msm/mdss/mdss_hdmi_util.h
index 914aac1..cf42346 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_util.h
+++ b/drivers/video/msm/mdss/mdss_hdmi_util.h
@@ -13,6 +13,7 @@
 #ifndef __HDMI_UTIL_H__
 #define __HDMI_UTIL_H__
 #include "mdss_io_util.h"
+#include "video/msm_hdmi_modes.h"
 
 /* HDMI_TX Registers */
 #define HDMI_CTRL                        (0x00000000)
@@ -218,166 +219,6 @@
 #define HDCP_KSV_LSB                     (0x000060D8)
 #define HDCP_KSV_MSB                     (0x000060DC)
 
-/* all video formats defined by EIA CEA-861-E */
-#define HDMI_VFRMT_640x480p60_4_3	0
-#define HDMI_VFRMT_720x480p60_4_3	1
-#define HDMI_VFRMT_720x480p60_16_9	2
-#define HDMI_VFRMT_1280x720p60_16_9	3
-#define HDMI_VFRMT_1920x1080i60_16_9	4
-#define HDMI_VFRMT_720x480i60_4_3	5
-#define HDMI_VFRMT_1440x480i60_4_3	HDMI_VFRMT_720x480i60_4_3
-#define HDMI_VFRMT_720x480i60_16_9	6
-#define HDMI_VFRMT_1440x480i60_16_9	HDMI_VFRMT_720x480i60_16_9
-#define HDMI_VFRMT_720x240p60_4_3	7
-#define HDMI_VFRMT_1440x240p60_4_3	HDMI_VFRMT_720x240p60_4_3
-#define HDMI_VFRMT_720x240p60_16_9	8
-#define HDMI_VFRMT_1440x240p60_16_9	HDMI_VFRMT_720x240p60_16_9
-#define HDMI_VFRMT_2880x480i60_4_3	9
-#define HDMI_VFRMT_2880x480i60_16_9	10
-#define HDMI_VFRMT_2880x240p60_4_3	11
-#define HDMI_VFRMT_2880x240p60_16_9	12
-#define HDMI_VFRMT_1440x480p60_4_3	13
-#define HDMI_VFRMT_1440x480p60_16_9	14
-#define HDMI_VFRMT_1920x1080p60_16_9	15
-#define HDMI_VFRMT_720x576p50_4_3	16
-#define HDMI_VFRMT_720x576p50_16_9	17
-#define HDMI_VFRMT_1280x720p50_16_9	18
-#define HDMI_VFRMT_1920x1080i50_16_9	19
-#define HDMI_VFRMT_720x576i50_4_3	20
-#define HDMI_VFRMT_1440x576i50_4_3	HDMI_VFRMT_720x576i50_4_3
-#define HDMI_VFRMT_720x576i50_16_9	21
-#define HDMI_VFRMT_1440x576i50_16_9	HDMI_VFRMT_720x576i50_16_9
-#define HDMI_VFRMT_720x288p50_4_3	22
-#define HDMI_VFRMT_1440x288p50_4_3	HDMI_VFRMT_720x288p50_4_3
-#define HDMI_VFRMT_720x288p50_16_9	23
-#define HDMI_VFRMT_1440x288p50_16_9	HDMI_VFRMT_720x288p50_16_9
-#define HDMI_VFRMT_2880x576i50_4_3	24
-#define HDMI_VFRMT_2880x576i50_16_9	25
-#define HDMI_VFRMT_2880x288p50_4_3	26
-#define HDMI_VFRMT_2880x288p50_16_9	27
-#define HDMI_VFRMT_1440x576p50_4_3	28
-#define HDMI_VFRMT_1440x576p50_16_9	29
-#define HDMI_VFRMT_1920x1080p50_16_9	30
-#define HDMI_VFRMT_1920x1080p24_16_9	31
-#define HDMI_VFRMT_1920x1080p25_16_9	32
-#define HDMI_VFRMT_1920x1080p30_16_9	33
-#define HDMI_VFRMT_2880x480p60_4_3	34
-#define HDMI_VFRMT_2880x480p60_16_9	35
-#define HDMI_VFRMT_2880x576p50_4_3	36
-#define HDMI_VFRMT_2880x576p50_16_9	37
-#define HDMI_VFRMT_1920x1250i50_16_9	38
-#define HDMI_VFRMT_1920x1080i100_16_9	39
-#define HDMI_VFRMT_1280x720p100_16_9	40
-#define HDMI_VFRMT_720x576p100_4_3	41
-#define HDMI_VFRMT_720x576p100_16_9	42
-#define HDMI_VFRMT_720x576i100_4_3	43
-#define HDMI_VFRMT_1440x576i100_4_3	HDMI_VFRMT_720x576i100_4_3
-#define HDMI_VFRMT_720x576i100_16_9	44
-#define HDMI_VFRMT_1440x576i100_16_9	HDMI_VFRMT_720x576i100_16_9
-#define HDMI_VFRMT_1920x1080i120_16_9	45
-#define HDMI_VFRMT_1280x720p120_16_9	46
-#define HDMI_VFRMT_720x480p120_4_3	47
-#define HDMI_VFRMT_720x480p120_16_9	48
-#define HDMI_VFRMT_720x480i120_4_3	49
-#define HDMI_VFRMT_1440x480i120_4_3	HDMI_VFRMT_720x480i120_4_3
-#define HDMI_VFRMT_720x480i120_16_9	50
-#define HDMI_VFRMT_1440x480i120_16_9	HDMI_VFRMT_720x480i120_16_9
-#define HDMI_VFRMT_720x576p200_4_3	51
-#define HDMI_VFRMT_720x576p200_16_9	52
-#define HDMI_VFRMT_720x576i200_4_3	53
-#define HDMI_VFRMT_1440x576i200_4_3	HDMI_VFRMT_720x576i200_4_3
-#define HDMI_VFRMT_720x576i200_16_9	54
-#define HDMI_VFRMT_1440x576i200_16_9	HDMI_VFRMT_720x576i200_16_9
-#define HDMI_VFRMT_720x480p240_4_3	55
-#define HDMI_VFRMT_720x480p240_16_9	56
-#define HDMI_VFRMT_720x480i240_4_3	57
-#define HDMI_VFRMT_1440x480i240_4_3	HDMI_VFRMT_720x480i240_4_3
-#define HDMI_VFRMT_720x480i240_16_9	58
-#define HDMI_VFRMT_1440x480i240_16_9	HDMI_VFRMT_720x480i240_16_9
-/* Video Identification Codes from 65-127 are reserved for the future */
-#define HDMI_VFRMT_END			127
-/* extended video formats */
-#define HDMI_VFRMT_3840x2160p30_16_9	(HDMI_VFRMT_END + 1)
-#define HDMI_VFRMT_3840x2160p25_16_9	(HDMI_VFRMT_END + 2)
-#define HDMI_VFRMT_3840x2160p24_16_9	(HDMI_VFRMT_END + 3)
-#define HDMI_VFRMT_4096x2160p24_16_9	(HDMI_VFRMT_END + 4)
-#define HDMI_EVFRMT_END			HDMI_VFRMT_4096x2160p24_16_9
-/* DVI only resolutions */
-#define HDMI_VFRMT_2560x1600p60_16_9	(HDMI_EVFRMT_END + 1)
-#define DVI_VFRMT_END			HDMI_VFRMT_2560x1600p60_16_9
-#define HDMI_VFRMT_MAX			(DVI_VFRMT_END + 1)
-#define HDMI_VFRMT_FORCE_32BIT		0x7FFFFFFF
-
-#define VFRMT_NOT_SUPPORTED(VFRMT) \
-	{VFRMT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false}
-
-#define HDMI_SETTINGS_640x480p60_4_3					\
-	{HDMI_VFRMT_640x480p60_4_3,      640,  16,  96,  48,  true,	\
-	 480, 10, 2, 33, true, 25200, 60000, false, true}
-#define HDMI_SETTINGS_720x480p60_4_3					\
-	{HDMI_VFRMT_720x480p60_4_3,      720,  16,  62,  60,  true,	\
-	 480, 9, 6, 30,  true, 27030, 60000, false, true}
-#define HDMI_SETTINGS_720x480p60_16_9					\
-	{HDMI_VFRMT_720x480p60_16_9,     720,  16,  62,  60,  true,	\
-	 480, 9, 6, 30,  true, 27030, 60000, false, true}
-#define HDMI_SETTINGS_1280x720p60_16_9					\
-	{HDMI_VFRMT_1280x720p60_16_9,    1280, 110, 40,  220, false,	\
-	 720, 5, 5, 20, false, 74250, 60000, false, true}
-#define HDMI_SETTINGS_1920x1080i60_16_9					\
-	{HDMI_VFRMT_1920x1080i60_16_9,   1920, 88,  44,  148, false,	\
-	 540, 2, 5, 5, false, 74250, 60000, false, true}
-#define HDMI_SETTINGS_1440x480i60_4_3					\
-	{HDMI_VFRMT_1440x480i60_4_3,     1440, 38,  124, 114, true,	\
-	 240, 4, 3, 15, true, 27000, 60000, true, true}
-#define HDMI_SETTINGS_1440x480i60_16_9					\
-	{HDMI_VFRMT_1440x480i60_16_9,    1440, 38,  124, 114, true,	\
-	 240, 4, 3, 15, true, 27000, 60000, true, true}
-#define HDMI_SETTINGS_1920x1080p60_16_9					\
-	{HDMI_VFRMT_1920x1080p60_16_9,   1920, 88,  44,  148,  false,	\
-	 1080, 4, 5, 36, false, 148500, 60000, false, true}
-#define HDMI_SETTINGS_720x576p50_4_3					\
-	{HDMI_VFRMT_720x576p50_4_3,      720,  12,  64,  68,   true,	\
-	 576,  5, 5, 39, true, 27000, 50000, false, true}
-#define HDMI_SETTINGS_720x576p50_16_9					\
-	{HDMI_VFRMT_720x576p50_16_9,     720,  12,  64,  68,   true,	\
-	 576,  5, 5, 39, true, 27000, 50000, false, true}
-#define HDMI_SETTINGS_1280x720p50_16_9					\
-	{HDMI_VFRMT_1280x720p50_16_9,    1280, 440, 40,  220,  false,	\
-	 720,  5, 5, 20, false, 74250, 50000, false, true}
-#define HDMI_SETTINGS_1440x576i50_4_3					\
-	{HDMI_VFRMT_1440x576i50_4_3,     1440, 24,  126, 138,  true,	\
-	 288,  2, 3, 19, true, 27000, 50000, true, true}
-#define HDMI_SETTINGS_1440x576i50_16_9					\
-	{HDMI_VFRMT_1440x576i50_16_9,    1440, 24,  126, 138,  true,	\
-	 288,  2, 3, 19, true, 27000, 50000, true, true}
-#define HDMI_SETTINGS_1920x1080p50_16_9					\
-	{HDMI_VFRMT_1920x1080p50_16_9,   1920,  528,  44,  148,  false,	\
-	 1080, 4, 5, 36, false, 148500, 50000, false, true}
-#define HDMI_SETTINGS_1920x1080p24_16_9					\
-	{HDMI_VFRMT_1920x1080p24_16_9,   1920,  638,  44,  148,  false,	\
-	 1080, 4, 5, 36, false, 74250, 24000, false, true}
-#define HDMI_SETTINGS_1920x1080p25_16_9					\
-	{HDMI_VFRMT_1920x1080p25_16_9,   1920,  528,  44,  148,  false,	\
-	 1080, 4, 5, 36, false, 74250, 25000, false, true}
-#define HDMI_SETTINGS_1920x1080p30_16_9					\
-	{HDMI_VFRMT_1920x1080p30_16_9,   1920,  88,   44,  148,  false,	\
-	 1080, 4, 5, 36, false, 74250, 30000, false, true}
-#define HDMI_SETTINGS_2560x1600p60_16_9					\
-	{HDMI_VFRMT_2560x1600p60_16_9,   2560,  48,   32,  80,  false,	\
-	 1600, 3, 6, 37, false, 268500, 60000, false, true}
-#define HDMI_SETTINGS_3840x2160p30_16_9					\
-	{HDMI_VFRMT_3840x2160p30_16_9, 3840, 176, 88, 296, false,	\
-	 2160, 8, 10, 72, false, 297000, 30000, false, true}
-#define HDMI_SETTINGS_3840x2160p25_16_9					\
-	{HDMI_VFRMT_3840x2160p25_16_9, 3840, 1056, 88, 296, false,	\
-	 2160, 8, 10, 72, false, 297000, 25000, false, true}
-#define HDMI_SETTINGS_3840x2160p24_16_9					\
-	{HDMI_VFRMT_3840x2160p24_16_9, 3840, 1276, 88, 296, false,	\
-	 2160, 8, 10, 72, false, 297000, 24000, false, true}
-#define HDMI_SETTINGS_4096x2160p24_16_9					\
-	{HDMI_VFRMT_4096x2160p24_16_9, 4096, 1020, 88, 296, false,	\
-	 2160, 8, 10, 72, false, 297000, 24000, false, true}
-
 #define TOP_AND_BOTTOM		0x10
 #define FRAME_PACKING		0x20
 #define SIDE_BY_SIDE_HALF	0x40
@@ -389,26 +230,6 @@
 	HDMI_TX_FEAT_MAX,
 };
 
-struct hdmi_disp_mode_timing_type {
-	u32	video_format;
-	u32	active_h;
-	u32	front_porch_h;
-	u32	pulse_width_h;
-	u32	back_porch_h;
-	u32	active_low_h;
-	u32	active_v;
-	u32	front_porch_v;
-	u32	pulse_width_v;
-	u32	back_porch_v;
-	u32	active_low_v;
-	/* Must divide by 1000 to get the actual frequency in MHZ */
-	u32	pixel_freq;
-	/* Must divide by 1000 to get the actual frequency in HZ */
-	u32	refresh_rate;
-	u32	interlaced;
-	u32	supported;
-};
-
 struct hdmi_tx_ddc_ctrl {
 	struct dss_io_data *io;
 	struct completion ddc_sw_done;
@@ -426,12 +247,10 @@
 };
 
 /* video timing related utility routines */
-void hdmi_init_supported_video_timings(void);
-int hdmi_get_video_id_code(struct hdmi_disp_mode_timing_type *timing_in);
-const struct hdmi_disp_mode_timing_type *hdmi_get_supported_mode(u32 mode);
-void hdmi_set_supported_mode(u32 mode);
+void hdmi_setup_video_mode_lut(void);
+int hdmi_get_video_id_code(struct msm_hdmi_mode_timing_info *timing_in);
+const struct msm_hdmi_mode_timing_info *hdmi_get_supported_mode(u32 mode);
 void hdmi_del_supported_mode(u32 mode);
-const char *hdmi_get_video_fmt_2string(u32 format);
 ssize_t hdmi_get_video_3d_fmt_2string(u32 format, char *buf);
 
 /* todo: Fix this. Right now this is defined in mdss_hdmi_tx.c */
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index e89fc7a..2745c96 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -895,13 +895,15 @@
 
 void mdss_mdp_footswitch_ctrl_splash(int on)
 {
-	if (mdss_res != NULL) {
+	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+	if (mdata != NULL) {
 		if (on) {
 			pr_debug("Enable MDP FS for splash.\n");
-			regulator_enable(mdss_res->fs);
+			regulator_enable(mdata->fs);
+			mdss_hw_init(mdata);
 		} else {
 			pr_debug("Disable MDP FS for splash.\n");
-			regulator_disable(mdss_res->fs);
+			regulator_disable(mdata->fs);
 		}
 	} else {
 		pr_warn("mdss mdata not initialized\n");
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 108340d..1ced200 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -200,6 +200,20 @@
 		total_ib_quota += ib_quota;
 		if (clk_rate > max_clk_rate)
 			max_clk_rate = clk_rate;
+
+		if (ctl->intf_type) {
+			struct mdss_panel_info *pinfo;
+
+			pinfo = &ctl->panel_data->panel_info;
+			clk_rate = (ctl->intf_type == MDSS_INTF_DSI) ?
+					pinfo->mipi.dsi_pclk_rate :
+					pinfo->clk_rate;
+
+			/* minimum clock rate due to inefficiency in 3dmux */
+			clk_rate = mult_frac(clk_rate >> 1, 9, 8);
+			if (clk_rate > max_clk_rate)
+				max_clk_rate = clk_rate;
+		}
 	}
 
 	/* request minimum bandwidth to have bus clock on when display is on */
@@ -451,6 +465,54 @@
 	return NULL;
 }
 
+static int mdss_mdp_ctl_fbc_enable(int enable,
+		struct mdss_mdp_mixer *mixer, struct mdss_panel_info *pdata)
+{
+	struct fbc_panel_info *fbc;
+	u32 mode = 0, budget_ctl = 0, lossy_mode = 0;
+
+	if (!pdata) {
+		pr_err("Invalid pdata\n");
+		return -EINVAL;
+	}
+
+	fbc = &pdata->fbc;
+
+	if (!fbc || !fbc->enabled) {
+		pr_err("Invalid FBC structure\n");
+		return -EINVAL;
+	}
+
+	if (mixer->num == MDSS_MDP_INTF_LAYERMIXER0)
+		pr_debug("Mixer supports FBC.\n");
+	else {
+		pr_debug("Mixer doesn't support FBC.\n");
+		return -EINVAL;
+	}
+
+	if (enable) {
+		mode = ((pdata->xres) << 16) | ((fbc->comp_mode) << 8) |
+			((fbc->qerr_enable) << 7) | ((fbc->cd_bias) << 4) |
+			((fbc->pat_enable) << 3) | ((fbc->vlc_enable) << 2) |
+			((fbc->bflc_enable) << 1) | enable;
+
+		budget_ctl = ((fbc->line_x_budget) << 12) |
+			((fbc->block_x_budget) << 8) | fbc->block_budget;
+
+		lossy_mode = ((fbc->lossless_mode_thd) << 16) |
+			((fbc->lossy_mode_thd) << 8) |
+			((fbc->lossy_rgb_thd) << 3) | fbc->lossy_mode_idx;
+	}
+
+	mdss_mdp_pingpong_write(mixer, MDSS_MDP_REG_PP_FBC_MODE, mode);
+	mdss_mdp_pingpong_write(mixer, MDSS_MDP_REG_PP_FBC_BUDGET_CTL,
+			budget_ctl);
+	mdss_mdp_pingpong_write(mixer, MDSS_MDP_REG_PP_FBC_LOSSY_MODE,
+			lossy_mode);
+
+	return 0;
+}
+
 int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl)
 {
 	struct mdss_mdp_ctl *split_ctl;
@@ -797,6 +859,7 @@
 	struct mdss_mdp_mixer *mixer;
 	u32 outsize, temp;
 	int ret = 0;
+	int i, nmixers;
 
 	if (ctl->start_fnc)
 		ret = ctl->start_fnc(ctl);
@@ -811,6 +874,10 @@
 
 	pr_debug("ctl_num=%d\n", ctl->num);
 
+	nmixers = MDSS_MDP_INTF_MAX_LAYERMIXER + MDSS_MDP_WB_MAX_LAYERMIXER;
+	for (i = 0; i < nmixers; i++)
+		mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_LAYER(i), 0);
+
 	mixer = ctl->mixer_left;
 	mdss_mdp_pp_resume(mixer->num);
 	mixer->params_changed++;
@@ -822,6 +889,11 @@
 	outsize = (mixer->height << 16) | mixer->width;
 	mdp_mixer_write(mixer, MDSS_MDP_REG_LM_OUT_SIZE, outsize);
 
+	if (ctl->panel_data->panel_info.fbc.enabled) {
+		ret = mdss_mdp_ctl_fbc_enable(1, ctl->mixer_left,
+				&ctl->panel_data->panel_info);
+	}
+
 	return ret;
 }
 
@@ -831,7 +903,7 @@
 	int ret = 0;
 
 	if (ctl->power_on) {
-		pr_debug("%s:%d already on!\n", __func__, __LINE__);
+		pr_debug("%d: panel already on!\n", __LINE__);
 		return 0;
 	}
 
@@ -917,14 +989,6 @@
 		ctl->power_on = false;
 		ctl->play_cnt = 0;
 		ctl->clk_rate = 0;
-		if (ctl->mixer_left) {
-			mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_LAYER(
-					ctl->mixer_left->num), 0);
-		}
-		if (ctl->mixer_right) {
-			mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_LAYER(
-					ctl->mixer_right->num), 0);
-		}
 		mdss_mdp_ctl_perf_commit(ctl->mdata, MDSS_MDP_PERF_UPDATE_ALL);
 	}
 
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index bf78c61..d50f47e 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -445,6 +445,10 @@
 #define MDSS_MDP_REG_PP_LINE_COUNT			0x02C
 #define MDSS_MDP_REG_PP_AUTOREFRESH_CONFIG		0x030
 
+#define MDSS_MDP_REG_PP_FBC_MODE			0x034
+#define MDSS_MDP_REG_PP_FBC_BUDGET_CTL			0x038
+#define MDSS_MDP_REG_PP_FBC_LOSSY_MODE			0x03C
+
 #define MDSS_MDP_REG_SMP_ALLOC_W0			0x00180
 #define MDSS_MDP_REG_SMP_ALLOC_R0			0x00230
 
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index e7f70b6..8c57c8c 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
@@ -373,6 +373,7 @@
 	struct mdss_mdp_video_ctx *ctx;
 	struct mdss_mdp_mixer *mixer;
 	struct intf_timing_params itp = {0};
+	u32 dst_bpp;
 	int i;
 
 	mdata = ctl->mdata;
@@ -411,19 +412,27 @@
 	mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_UNDER_RUN, ctl->intf_num,
 				   mdss_mdp_video_underrun_intr_done, ctl);
 
-	itp.width = pinfo->xres + pinfo->lcdc.xres_pad;
+	dst_bpp = pinfo->fbc.enabled ? (pinfo->fbc.target_bpp) : (pinfo->bpp);
+
+	itp.width = mult_frac((pinfo->xres + pinfo->lcdc.xres_pad),
+				dst_bpp, pinfo->bpp);
 	itp.height = pinfo->yres + pinfo->lcdc.yres_pad;
 	itp.border_clr = pinfo->lcdc.border_clr;
 	itp.underflow_clr = pinfo->lcdc.underflow_clr;
 	itp.hsync_skew = pinfo->lcdc.hsync_skew;
 
-	itp.xres =  pinfo->xres;
+	itp.xres =  mult_frac(pinfo->xres, dst_bpp, pinfo->bpp);
 	itp.yres = pinfo->yres;
-	itp.h_back_porch =  pinfo->lcdc.h_back_porch;
-	itp.h_front_porch =  pinfo->lcdc.h_front_porch;
-	itp.v_back_porch =  pinfo->lcdc.v_back_porch;
-	itp.v_front_porch = pinfo->lcdc.v_front_porch;
-	itp.hsync_pulse_width = pinfo->lcdc.h_pulse_width;
+	itp.h_back_porch =  mult_frac(pinfo->lcdc.h_back_porch, dst_bpp,
+			pinfo->bpp);
+	itp.h_front_porch = mult_frac(pinfo->lcdc.h_front_porch, dst_bpp,
+			pinfo->bpp);
+	itp.v_back_porch =  mult_frac(pinfo->lcdc.v_back_porch, dst_bpp,
+			pinfo->bpp);
+	itp.v_front_porch = mult_frac(pinfo->lcdc.v_front_porch, dst_bpp,
+			pinfo->bpp);
+	itp.hsync_pulse_width = mult_frac(pinfo->lcdc.h_pulse_width, dst_bpp,
+			pinfo->bpp);
 	itp.vsync_pulse_width = pinfo->lcdc.v_pulse_width;
 
 	if (mdss_mdp_video_timegen_setup(ctx, &itp)) {
diff --git a/drivers/video/msm/mdss/mdss_panel.h b/drivers/video/msm/mdss/mdss_panel.h
index 23f7445..d230100 100644
--- a/drivers/video/msm/mdss/mdss_panel.h
+++ b/drivers/video/msm/mdss/mdss_panel.h
@@ -157,6 +157,26 @@
 	char channel_swap;
 };
 
+struct fbc_panel_info {
+	u32 enabled;
+	u32 target_bpp;
+	u32 comp_mode;
+	u32 qerr_enable;
+	u32 cd_bias;
+	u32 pat_enable;
+	u32 vlc_enable;
+	u32 bflc_enable;
+
+	u32 line_x_budget;
+	u32 block_x_budget;
+	u32 block_budget;
+
+	u32 lossless_mode_thd;
+	u32 lossy_mode_thd;
+	u32 lossy_rgb_thd;
+	u32 lossy_mode_idx;
+};
+
 struct mdss_panel_info {
 	u32 xres;
 	u32 yres;
@@ -184,6 +204,7 @@
 	u32 panel_power_on;
 
 	struct lcd_panel_info lcdc;
+	struct fbc_panel_info fbc;
 	struct mipi_panel_info mipi;
 	struct lvds_panel_info lvds;
 };
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
index 7a79a40..383a91b 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h
@@ -12,7 +12,6 @@
  */
 #ifndef _VCD_DDL_H_
 #define _VCD_DDL_H_
-#include <mach/msm_subsystem_map.h>
 #include "vcd_ddl_api.h"
 #include "vcd_ddl_utils.h"
 #include "vcd_ddl_firmware.h"
diff --git a/include/linux/mfd/pm8xxx/ccadc.h b/include/linux/mfd/pm8xxx/ccadc.h
index 955e286..a29486f 100644
--- a/include/linux/mfd/pm8xxx/ccadc.h
+++ b/include/linux/mfd/pm8xxx/ccadc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -26,11 +26,15 @@
  * @ccadc_cdata:	core data for the ccadc driver containing channel info
  * @r_sense_uohm:		sense resistor value in (micro Ohms)
  * @calib_delay_ms:	how often should the adc calculate gain and offset
+ * @periodic_wakeup:	a flag to indicate that this system wakeups periodically
+ *			for calibration/other housekeeping activities. The ccadc
+ *			does a quick calibration while resuming
  */
 struct pm8xxx_ccadc_platform_data {
 	struct pm8xxx_ccadc_core_data	ccadc_cdata;
 	int				r_sense_uohm;
 	unsigned int			calib_delay_ms;
+	bool				periodic_wakeup;
 };
 
 #define CCADC_READING_RESOLUTION_N	542535
diff --git a/include/linux/mfd/wcd9xxx/pdata.h b/include/linux/mfd/wcd9xxx/pdata.h
index 392c0ae..813cac3 100644
--- a/include/linux/mfd/wcd9xxx/pdata.h
+++ b/include/linux/mfd/wcd9xxx/pdata.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, 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
@@ -69,6 +69,21 @@
 #define TABLA_DCYCLE_3839 0xE
 #define TABLA_DCYCLE_4095 0xF
 
+#define TAIKO_MCLK_CLK_12P288MHZ 12288000
+#define TAIKO_MCLK_CLK_9P6HZ 9600000
+
+/* Only valid for 9.6 MHz mclk */
+#define TAIKO_DMIC_SAMPLE_RATE_2P4MHZ 2400000
+#define TAIKO_DMIC_SAMPLE_RATE_3P2MHZ 3200000
+#define TAIKO_DMIC_SAMPLE_RATE_4P8MHZ 4800000
+
+/* Only valid for 12.288 MHz mclk */
+#define TAIKO_DMIC_SAMPLE_RATE_3P072MHZ 3072000
+#define TAIKO_DMIC_SAMPLE_RATE_4P096MHZ 4096000
+#define TAIKO_DMIC_SAMPLE_RATE_6P144MHZ 6144000
+
+#define TAIKO_DMIC_SAMPLE_RATE_UNDEFINED 0
+
 struct wcd9xxx_amic {
 	/*legacy mode, txfe_enable and txfe_buff take 7 input
 	 * each bit represent the channel / TXFE number
@@ -155,6 +170,7 @@
 	struct wcd9xxx_ocp_setting ocp;
 	struct wcd9xxx_regulator regulator[MAX_REGULATOR];
 	u32 mclk_rate;
+	u32 dmic_sample_rate;
 };
 
 #endif
diff --git a/include/linux/mfd/wcd9xxx/wcd9310_registers.h b/include/linux/mfd/wcd9xxx/wcd9310_registers.h
index 46336e2..cec0ce2 100644
--- a/include/linux/mfd/wcd9xxx/wcd9310_registers.h
+++ b/include/linux/mfd/wcd9xxx/wcd9310_registers.h
@@ -1,14 +1,3 @@
-/* Copyright (c) 2012-2013, 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 TABLA_CODEC_DIGITAL_H
 
 #define TABLA_CODEC_DIGITAL_H
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index a5f36b5..407a005 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -116,6 +116,12 @@
  * required frequency.
  */
 #define SDHCI_QUIRK2_ALWAYS_USE_BASE_CLOCK		(1<<4)
+/*
+ * Dont use the max_discard_to in sdhci driver so that the maximum discard
+ * unit gets picked by the mmc queue. Otherwise, it takes a long time for
+ * secure discard kind of operations to complete.
+ */
+#define SDHCI_QUIRK2_USE_MAX_DISCARD_SIZE		(1<<5)
 
 	int irq;		/* Device IRQ */
 	void __iomem *ioaddr;	/* Mapped address */
diff --git a/include/linux/msm_ion.h b/include/linux/msm_ion.h
index 95c4e6a..4fd77d2 100644
--- a/include/linux/msm_ion.h
+++ b/include/linux/msm_ion.h
@@ -1,18 +1,3 @@
-/*
- *
- * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
 #ifndef _LINUX_MSM_ION_H
 #define _LINUX_MSM_ION_H
 
diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h
index 307be2b..2ad040e 100644
--- a/include/linux/msm_kgsl.h
+++ b/include/linux/msm_kgsl.h
@@ -21,7 +21,15 @@
 #define KGSL_CONTEXT_PER_CONTEXT_TS	0x00000040
 #define KGSL_CONTEXT_USER_GENERATED_TS	0x00000080
 #define KGSL_CONTEXT_NO_FAULT_TOLERANCE 0x00000200
+/* bits [12:15] are reserved for future use */
+#define KGSL_CONTEXT_TYPE_MASK          0x01F00000
+#define KGSL_CONTEXT_TYPE_SHIFT         20
 
+#define KGSL_CONTEXT_TYPE_ANY		0
+#define KGSL_CONTEXT_TYPE_GL		1
+#define KGSL_CONTEXT_TYPE_CL		2
+#define KGSL_CONTEXT_TYPE_C2D		3
+#define KGSL_CONTEXT_TYPE_RS		4
 
 #define KGSL_CONTEXT_INVALID 0xffffffff
 
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 84e099d..f551e75 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -170,6 +170,9 @@
  *	%NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS,
  *	%NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY,
  *	%NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT.
+ *	%NL80211_ATTR_ACL_POLICY and %NL80211_ATTR_MAC_ADDRS.
+ *	The channel to use can be set on the interface or be given using the
+ *	%NL80211_ATTR_WIPHY_FREQ and the attributes determining channel width.
  * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP
  * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface
  * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP
@@ -554,6 +557,57 @@
  * @NL80211_CMD_SET_NOACK_MAP: sets a bitmap for the individual TIDs whether
  *      No Acknowledgement Policy should be applied.
  *
+ * @NL80211_CMD_CH_SWITCH_NOTIFY: An AP or GO may decide to switch channels
+ *	independently of the userspace SME, send this event indicating
+ *	%NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ and the
+ *	attributes determining channel width.
+ *
+ * @NL80211_CMD_START_P2P_DEVICE: Start the given P2P Device, identified by
+ *	its %NL80211_ATTR_WDEV identifier. It must have been created with
+ *	%NL80211_CMD_NEW_INTERFACE previously. After it has been started, the
+ *	P2P Device can be used for P2P operations, e.g. remain-on-channel and
+ *	public action frame TX.
+ * @NL80211_CMD_STOP_P2P_DEVICE: Stop the given P2P Device, identified by
+ *	its %NL80211_ATTR_WDEV identifier.
+ *
+ * @NL80211_CMD_CONN_FAILED: connection request to an AP failed; used to
+ *	notify userspace that AP has rejected the connection request from a
+ *	station, due to particular reason. %NL80211_ATTR_CONN_FAILED_REASON
+ *	is used for this.
+ *
+ * @NL80211_CMD_SET_MCAST_RATE: Change the rate used to send multicast frames
+ *	for IBSS or MESH vif.
+ *
+ * @NL80211_CMD_SET_MAC_ACL: sets ACL for MAC address based access control.
+ *	This is to be used with the drivers advertising the support of MAC
+ *	address based access control. List of MAC addresses is passed in
+ *	%NL80211_ATTR_MAC_ADDRS and ACL policy is passed in
+ *	%NL80211_ATTR_ACL_POLICY. Driver will enable ACL with this list, if it
+ *	is not already done. The new list will replace any existing list. Driver
+ *	will clear its ACL when the list of MAC addresses passed is empty. This
+ *	command is used in AP/P2P GO mode. Driver has to make sure to clear its
+ *	ACL list during %NL80211_CMD_STOP_AP.
+ *
+ * @NL80211_CMD_RADAR_DETECT: Start a Channel availability check (CAC). Once
+ *	a radar is detected or the channel availability scan (CAC) has finished
+ *	or was aborted, or a radar was detected, usermode will be notified with
+ *	this event. This command is also used to notify userspace about radars
+ *	while operating on this channel.
+ *	%NL80211_ATTR_RADAR_EVENT is used to inform about the type of the
+ *	event.
+ *
+ * @NL80211_CMD_GET_PROTOCOL_FEATURES: Get global nl80211 protocol features,
+ *	i.e. features for the nl80211 protocol rather than device features.
+ *	Returns the features in the %NL80211_ATTR_PROTOCOL_FEATURES bitmap.
+ *
+ * @NL80211_CMD_UPDATE_FT_IES: Pass down the most up-to-date Fast Transition
+ *	Information Element to the WLAN driver
+ *
+ * @NL80211_CMD_FT_EVENT: Send a Fast transition event from the WLAN driver
+ *	to the supplicant. This will carry the target AP's MAC address along
+ *	with the relevant Information Elements. This event is used to report
+ *	received FT IEs (MDIE, FTIE, RSN IE, TIE, RICIE).
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -695,6 +749,25 @@
 
 	NL80211_CMD_SET_NOACK_MAP,
 
+
+	NL80211_CMD_CH_SWITCH_NOTIFY,
+
+	NL80211_CMD_START_P2P_DEVICE,
+	NL80211_CMD_STOP_P2P_DEVICE,
+
+	NL80211_CMD_CONN_FAILED,
+
+	NL80211_CMD_SET_MCAST_RATE,
+
+	NL80211_CMD_SET_MAC_ACL,
+
+	NL80211_CMD_RADAR_DETECT,
+
+	NL80211_CMD_GET_PROTOCOL_FEATURES,
+
+	NL80211_CMD_UPDATE_FT_IES,
+	NL80211_CMD_FT_EVENT,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -1275,6 +1348,18 @@
  *	advertised to the driver, e.g., to enable TDLS off channel operations
  *	and PU-APSD.
  *
+ * @NL80211_ATTR_PROTOCOL_FEATURES: global nl80211 feature flags, see
+ *	&enum nl80211_protocol_features, the attribute is a u32.
+ *
+ * @NL80211_ATTR_SPLIT_WIPHY_DUMP: flag attribute, userspace supports
+ *	receiving the data for a single wiphy split across multiple
+ *	messages, given with wiphy dump message
+ *
+ * @NL80211_ATTR_MDID: Mobility Domain Identifier
+ *
+ * @NL80211_ATTR_IE_RIC: Resource Information Container Information
+ *	Element
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1561,6 +1646,15 @@
 	NL80211_ATTR_STA_CAPABILITY,
 	NL80211_ATTR_STA_EXT_CAPABILITY,
 
+	NL80211_ATTR_PROTOCOL_FEATURES,
+	NL80211_ATTR_SPLIT_WIPHY_DUMP,
+
+	NL80211_ATTR_DISABLE_VHT,
+	NL80211_ATTR_VHT_CAPABILITY_MASK,
+
+	NL80211_ATTR_MDID,
+	NL80211_ATTR_IE_RIC,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 79fe16b..bf6847a 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -279,6 +279,7 @@
  * @pclk: clock struct of iface_clk.
  * @phy_reset_clk: clock struct of phy_clk.
  * @core_clk: clock struct of core_bus_clk.
+ * @core_clk_rate: core clk max frequency
  * @regs: ioremapped register base address.
  * @inputs: OTG state machine inputs(Id, SessValid etc).
  * @sm_work: OTG state machine work.
@@ -313,6 +314,7 @@
 	struct clk *pclk;
 	struct clk *phy_reset_clk;
 	struct clk *core_clk;
+	long core_clk_rate;
 	void __iomem *regs;
 #define ID		0
 #define B_SESS_VLD	1
diff --git a/include/media/msm/vcd_api.h b/include/media/msm/vcd_api.h
index 944446f..09e1a53 100644
--- a/include/media/msm/vcd_api.h
+++ b/include/media/msm/vcd_api.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -12,6 +12,7 @@
  */
 #ifndef _VCD_API_H_
 #define _VCD_API_H_
+#include <linux/types.h>
 #include "vcd_property.h"
 #include "vcd_status.h"
 
diff --git a/include/media/msm/vcd_property.h b/include/media/msm/vcd_property.h
index 5fcb049..ce6c479 100644
--- a/include/media/msm/vcd_property.h
+++ b/include/media/msm/vcd_property.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -13,6 +13,8 @@
 #ifndef _VCD_DRIVER_PROPERTY_H_
 #define _VCD_DRIVER_PROPERTY_H_
 
+#include <linux/types.h>
+
 #define VCD_START_BASE       0x0
 #define VCD_I_LIVE           (VCD_START_BASE + 0x1)
 #define VCD_I_CODEC          (VCD_START_BASE + 0x2)
diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h
index 4e1fb31..bce6af3 100644
--- a/include/media/msm_cam_sensor.h
+++ b/include/media/msm_cam_sensor.h
@@ -44,9 +44,12 @@
 #define MOVE_NEAR 0
 #define MOVE_FAR  1
 
+#define MAX_EEPROM_NAME 32
+
 enum msm_camera_i2c_reg_addr_type {
 	MSM_CAMERA_I2C_BYTE_ADDR = 1,
 	MSM_CAMERA_I2C_WORD_ADDR,
+	MSM_CAMERA_I2C_3B_ADDR,
 };
 
 enum msm_camera_i2c_data_type {
@@ -283,6 +286,37 @@
 	} cfg;
 };
 
+enum eeprom_cfg_type_t {
+	CFG_EEPROM_GET_INFO,
+	CFG_EEPROM_GET_DATA,
+	CFG_EEPROM_READ_DATA,
+	CFG_EEPROM_WRITE_DATA,
+};
+struct eeprom_get_t {
+	uint16_t num_bytes;
+};
+
+struct eeprom_read_t {
+	uint8_t *dbuffer;
+	uint16_t num_bytes;
+};
+
+struct eeprom_write_t {
+	uint8_t *dbuffer;
+	uint16_t num_bytes;
+};
+
+struct msm_eeprom_cfg_data {
+	enum eeprom_cfg_type_t cfgtype;
+	uint8_t is_supported;
+	union {
+		char eeprom_name[MAX_SENSOR_NAME];
+		struct eeprom_get_t get_data;
+		struct eeprom_read_t read_data;
+		struct eeprom_write_t write_data;
+	} cfg;
+};
+
 enum msm_sensor_cfg_type_t {
 	CFG_SET_SLAVE_INFO,
 	CFG_WRITE_I2C_ARRAY,
@@ -456,6 +490,9 @@
 #define VIDIOC_MSM_FLASH_LED_DATA_CFG \
 	_IOWR('V', BASE_VIDIOC_PRIVATE + 7, struct msm_camera_led_cfg_t)
 
+#define VIDIOC_MSM_EEPROM_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 8, struct msm_eeprom_cfg_data)
+
 #define MSM_V4L2_PIX_FMT_META v4l2_fourcc('M', 'E', 'T', 'A') /* META */
 
 #endif /* __LINUX_MSM_CAM_SENSOR_H */
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 9c310a9..afd5a42 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -1550,6 +1550,7 @@
 enum msm_camera_i2c_reg_addr_type {
 	MSM_CAMERA_I2C_BYTE_ADDR = 1,
 	MSM_CAMERA_I2C_WORD_ADDR,
+	MSM_CAMERA_I2C_3B_ADDR,
 };
 
 struct msm_camera_i2c_reg_array {
diff --git a/include/media/msm_gestures.h b/include/media/msm_gestures.h
index a6efd4f..9388d99 100644
--- a/include/media/msm_gestures.h
+++ b/include/media/msm_gestures.h
@@ -1,15 +1,3 @@
-/* Copyright (c) 2012, 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 __LINUX_MSM_GESTURES_H
 #define __LINUX_MSM_GESTURES_H
 
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index 77455ca..99f418c 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -1,15 +1,3 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
 #ifndef __MSM_ISP_H__
 #define __MSM_ISP_H__
 
diff --git a/include/media/msmb_pproc.h b/include/media/msmb_pproc.h
index 9000774..c185096 100644
--- a/include/media/msmb_pproc.h
+++ b/include/media/msmb_pproc.h
@@ -106,6 +106,7 @@
 	struct ion_handle *dest_ion_handle;
 	struct timeval in_time, out_time;
 	void *cookie;
+	int32_t *status;
 
 	struct msm_cpp_buffer_info_t input_buffer_info;
 	struct msm_cpp_buffer_info_t output_buffer_info;
@@ -145,7 +146,7 @@
 struct msm_camera_v4l2_ioctl_t {
 	uint32_t id;
 	uint32_t len;
-	uint32_t trans_code;
+	int32_t trans_code;
 	void __user *ioctl_ptr;
 };
 
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index bfa0eca..dc29eb9 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1361,6 +1361,21 @@
 };
 
 /**
+ * struct cfg80211_update_ft_ies_params - FT IE Information
+ *
+ * This structure provides information needed to update the fast transition IE
+ *
+ * @md: The Mobility Domain ID, 2 Octet value
+ * @ie: Fast Transition IEs
+ * @ie_len: Length of ft_ie in octets
+ */
+struct cfg80211_update_ft_ies_params {
+	u16 md;
+	const u8 *ie;
+	size_t ie_len;
+};
+
+/**
  * struct cfg80211_ops - backend description for wireless configuration
  *
  * This struct is registered by fullmac card drivers and/or wireless stacks
@@ -1740,6 +1755,8 @@
 				  u16 noack_map);
 
 	struct ieee80211_channel *(*get_channel)(struct wiphy *wiphy);
+	int	(*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev,
+				 struct cfg80211_update_ft_ies_params *ftie);
 };
 
 /*
@@ -3410,6 +3427,31 @@
  */
 u16 cfg80211_calculate_bitrate(struct rate_info *rate);
 
+/**
+ * struct cfg80211_ft_event - FT Information Elements
+ * @ies: FT IEs
+ * @ies_len: length of the FT IE in bytes
+ * @target_ap: target AP's MAC address
+ * @ric_ies: RIC IE
+ * @ric_ies_len: length of the RIC IE in bytes
+ */
+struct cfg80211_ft_event_params {
+	const u8 *ies;
+	size_t ies_len;
+	const u8 *target_ap;
+	const u8 *ric_ies;
+	size_t ric_ies_len;
+};
+
+/**
+ * cfg80211_ft_event - notify userspace about FT IE and RIC IE
+ * @netdev: network device
+ * @ft_event: IE information
+ */
+void cfg80211_ft_event(struct net_device *netdev,
+		       struct cfg80211_ft_event_params *ft_event);
+
+
 /* Logging, debugging and troubleshooting/diagnostic helpers. */
 
 /* wiphy_printk helpers, similar to dev_printk */
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index f9d2a40..0d0670e 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -13,7 +13,6 @@
 #define __Q6_ASM_V2_H__
 
 #include <mach/qdsp6v2/apr.h>
-#include <mach/msm_subsystem_map.h>
 #include <sound/apr_audio-v2.h>
 #include <linux/list.h>
 #include <linux/msm_ion.h>
diff --git a/include/sound/q6lsm.h b/include/sound/q6lsm.h
index 5c9d4b9..e9ca91d 100644
--- a/include/sound/q6lsm.h
+++ b/include/sound/q6lsm.h
@@ -18,7 +18,6 @@
 #include <sound/apr_audio-v2.h>
 #include <sound/lsm_params.h>
 #include <mach/qdsp6v2/apr.h>
-#include <mach/msm_subsystem_map.h>
 
 typedef void (*app_cb)(uint32_t opcode, uint32_t token,
 		       uint32_t *payload, void *priv);
diff --git a/include/video/Kbuild b/include/video/Kbuild
index ad3e622..53e13cb 100644
--- a/include/video/Kbuild
+++ b/include/video/Kbuild
@@ -1,3 +1,4 @@
 header-y += edid.h
 header-y += sisfb.h
 header-y += uvesafb.h
+header-y += msm_hdmi_modes.h
diff --git a/include/video/msm_hdmi_modes.h b/include/video/msm_hdmi_modes.h
new file mode 100644
index 0000000..a15272b
--- /dev/null
+++ b/include/video/msm_hdmi_modes.h
@@ -0,0 +1,334 @@
+#ifndef __MSM_HDMI_MODES_H__
+#define __MSM_HDMI_MODES_H__
+#include <linux/types.h>
+
+struct msm_hdmi_mode_timing_info {
+	uint32_t	video_format;
+	uint32_t	active_h;
+	uint32_t	front_porch_h;
+	uint32_t	pulse_width_h;
+	uint32_t	back_porch_h;
+	uint32_t	active_low_h;
+	uint32_t	active_v;
+	uint32_t	front_porch_v;
+	uint32_t	pulse_width_v;
+	uint32_t	back_porch_v;
+	uint32_t	active_low_v;
+	/* Must divide by 1000 to get the actual frequency in MHZ */
+	uint32_t	pixel_freq;
+	/* Must divide by 1000 to get the actual frequency in HZ */
+	uint32_t	refresh_rate;
+	uint32_t	interlaced;
+	uint32_t	supported;
+};
+
+#define MSM_HDMI_MODES_CEA		(1 << 0)
+#define MSM_HDMI_MODES_XTND		(1 << 1)
+#define MSM_HDMI_MODES_DVI		(1 << 2)
+#define MSM_HDMI_MODES_ALL		(MSM_HDMI_MODES_CEA |\
+					 MSM_HDMI_MODES_XTND |\
+					 MSM_HDMI_MODES_DVI)
+
+/* all video formats defined by CEA 861D */
+#define HDMI_VFRMT_UNKNOWN		0
+#define HDMI_VFRMT_640x480p60_4_3	1
+#define HDMI_VFRMT_720x480p60_4_3	2
+#define HDMI_VFRMT_720x480p60_16_9	3
+#define HDMI_VFRMT_1280x720p60_16_9	4
+#define HDMI_VFRMT_1920x1080i60_16_9	5
+#define HDMI_VFRMT_720x480i60_4_3	6
+#define HDMI_VFRMT_1440x480i60_4_3	HDMI_VFRMT_720x480i60_4_3
+#define HDMI_VFRMT_720x480i60_16_9	7
+#define HDMI_VFRMT_1440x480i60_16_9	HDMI_VFRMT_720x480i60_16_9
+#define HDMI_VFRMT_720x240p60_4_3	8
+#define HDMI_VFRMT_1440x240p60_4_3	HDMI_VFRMT_720x240p60_4_3
+#define HDMI_VFRMT_720x240p60_16_9	9
+#define HDMI_VFRMT_1440x240p60_16_9	HDMI_VFRMT_720x240p60_16_9
+#define HDMI_VFRMT_2880x480i60_4_3	10
+#define HDMI_VFRMT_2880x480i60_16_9	11
+#define HDMI_VFRMT_2880x240p60_4_3	12
+#define HDMI_VFRMT_2880x240p60_16_9	13
+#define HDMI_VFRMT_1440x480p60_4_3	14
+#define HDMI_VFRMT_1440x480p60_16_9	15
+#define HDMI_VFRMT_1920x1080p60_16_9	16
+#define HDMI_VFRMT_720x576p50_4_3	17
+#define HDMI_VFRMT_720x576p50_16_9	18
+#define HDMI_VFRMT_1280x720p50_16_9	19
+#define HDMI_VFRMT_1920x1080i50_16_9	20
+#define HDMI_VFRMT_720x576i50_4_3	21
+#define HDMI_VFRMT_1440x576i50_4_3	HDMI_VFRMT_720x576i50_4_3
+#define HDMI_VFRMT_720x576i50_16_9	22
+#define HDMI_VFRMT_1440x576i50_16_9	HDMI_VFRMT_720x576i50_16_9
+#define HDMI_VFRMT_720x288p50_4_3	23
+#define HDMI_VFRMT_1440x288p50_4_3	HDMI_VFRMT_720x288p50_4_3
+#define HDMI_VFRMT_720x288p50_16_9	24
+#define HDMI_VFRMT_1440x288p50_16_9	HDMI_VFRMT_720x288p50_16_9
+#define HDMI_VFRMT_2880x576i50_4_3	25
+#define HDMI_VFRMT_2880x576i50_16_9	26
+#define HDMI_VFRMT_2880x288p50_4_3	27
+#define HDMI_VFRMT_2880x288p50_16_9	28
+#define HDMI_VFRMT_1440x576p50_4_3	29
+#define HDMI_VFRMT_1440x576p50_16_9	30
+#define HDMI_VFRMT_1920x1080p50_16_9	31
+#define HDMI_VFRMT_1920x1080p24_16_9	32
+#define HDMI_VFRMT_1920x1080p25_16_9	33
+#define HDMI_VFRMT_1920x1080p30_16_9	34
+#define HDMI_VFRMT_2880x480p60_4_3	35
+#define HDMI_VFRMT_2880x480p60_16_9	36
+#define HDMI_VFRMT_2880x576p50_4_3	37
+#define HDMI_VFRMT_2880x576p50_16_9	38
+#define HDMI_VFRMT_1920x1250i50_16_9	39
+#define HDMI_VFRMT_1920x1080i100_16_9	40
+#define HDMI_VFRMT_1280x720p100_16_9	41
+#define HDMI_VFRMT_720x576p100_4_3	42
+#define HDMI_VFRMT_720x576p100_16_9	43
+#define HDMI_VFRMT_720x576i100_4_3	44
+#define HDMI_VFRMT_1440x576i100_4_3	HDMI_VFRMT_720x576i100_4_3
+#define HDMI_VFRMT_720x576i100_16_9	45
+#define HDMI_VFRMT_1440x576i100_16_9	HDMI_VFRMT_720x576i100_16_9
+#define HDMI_VFRMT_1920x1080i120_16_9	46
+#define HDMI_VFRMT_1280x720p120_16_9	47
+#define HDMI_VFRMT_720x480p120_4_3	48
+#define HDMI_VFRMT_720x480p120_16_9	49
+#define HDMI_VFRMT_720x480i120_4_3	50
+#define HDMI_VFRMT_1440x480i120_4_3	HDMI_VFRMT_720x480i120_4_3
+#define HDMI_VFRMT_720x480i120_16_9	51
+#define HDMI_VFRMT_1440x480i120_16_9	HDMI_VFRMT_720x480i120_16_9
+#define HDMI_VFRMT_720x576p200_4_3	52
+#define HDMI_VFRMT_720x576p200_16_9	53
+#define HDMI_VFRMT_720x576i200_4_3	54
+#define HDMI_VFRMT_1440x576i200_4_3	HDMI_VFRMT_720x576i200_4_3
+#define HDMI_VFRMT_720x576i200_16_9	55
+#define HDMI_VFRMT_1440x576i200_16_9	HDMI_VFRMT_720x576i200_16_9
+#define HDMI_VFRMT_720x480p240_4_3	56
+#define HDMI_VFRMT_720x480p240_16_9	57
+#define HDMI_VFRMT_720x480i240_4_3	58
+#define HDMI_VFRMT_1440x480i240_4_3	HDMI_VFRMT_720x480i240_4_3
+#define HDMI_VFRMT_720x480i240_16_9	59
+#define HDMI_VFRMT_1440x480i240_16_9	HDMI_VFRMT_720x480i240_16_9
+#define HDMI_VFRMT_1280x720p24_16_9	60
+#define HDMI_VFRMT_1280x720p25_16_9	61
+#define HDMI_VFRMT_1280x720p30_16_9	62
+#define HDMI_VFRMT_1920x1080p120_16_9	63
+#define HDMI_VFRMT_1920x1080p100_16_9	64
+/* Video Identification Codes from 65-127 are reserved for the future */
+#define HDMI_VFRMT_END			127
+
+/* extended video formats */
+#define HDMI_VFRMT_3840x2160p30_16_9	(HDMI_VFRMT_END + 1)
+#define HDMI_VFRMT_3840x2160p25_16_9	(HDMI_VFRMT_END + 2)
+#define HDMI_VFRMT_3840x2160p24_16_9	(HDMI_VFRMT_END + 3)
+#define HDMI_VFRMT_4096x2160p24_16_9	(HDMI_VFRMT_END + 4)
+#define HDMI_EVFRMT_END			HDMI_VFRMT_4096x2160p24_16_9
+
+/* VESA DMT TIMINGS */
+#define HDMI_VFRMT_2560x1600p60_16_9	(HDMI_EVFRMT_END + 1)
+#define HDMI_VFRMT_1280x1024p60_5_4	(HDMI_EVFRMT_END + 2)
+#define VESA_DMT_VFRMT_END		HDMI_VFRMT_1280x1024p60_5_4
+#define HDMI_VFRMT_MAX			(VESA_DMT_VFRMT_END + 1)
+#define HDMI_VFRMT_FORCE_32BIT		0x7FFFFFFF
+
+/* Timing information for supported modes */
+#define VFRMT_NOT_SUPPORTED(VFRMT) \
+	{VFRMT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false}
+
+#define HDMI_VFRMT_640x480p60_4_3_TIMING				\
+	{HDMI_VFRMT_640x480p60_4_3, 640, 16, 96, 48, true,		\
+	 480, 10, 2, 33, true, 25200, 60000, false, true}
+#define HDMI_VFRMT_720x480p60_4_3_TIMING				\
+	{HDMI_VFRMT_720x480p60_4_3, 720, 16, 62, 60, true,		\
+	 480, 9, 6, 30, true, 27030, 60000, false, true}
+#define HDMI_VFRMT_720x480p60_16_9_TIMING				\
+	{HDMI_VFRMT_720x480p60_16_9, 720, 16, 62, 60, true,		\
+	 480, 9, 6, 30, true, 27030, 60000, false, true}
+#define HDMI_VFRMT_1280x720p60_16_9_TIMING				\
+	{HDMI_VFRMT_1280x720p60_16_9, 1280, 110, 40, 220, false,	\
+	 720, 5, 5, 20, false, 74250, 60000, false, true}
+#define HDMI_VFRMT_1920x1080i60_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080i60_16_9, 1920, 88, 44, 148, false,	\
+	 540, 2, 5, 5, false, 74250, 60000, false, true}
+#define HDMI_VFRMT_1440x480i60_4_3_TIMING				\
+	{HDMI_VFRMT_1440x480i60_4_3, 1440, 38, 124, 114, true,		\
+	 240, 4, 3, 15, true, 27000, 60000, true, true}
+#define HDMI_VFRMT_1440x480i60_16_9_TIMING				\
+	{HDMI_VFRMT_1440x480i60_16_9, 1440, 38, 124, 114, true,		\
+	 240, 4, 3, 15, true, 27000, 60000, true, true}
+#define HDMI_VFRMT_1920x1080p60_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080p60_16_9, 1920, 88, 44, 148, false,	\
+	 1080, 4, 5, 36, false, 148500, 60000, false, true}
+#define HDMI_VFRMT_720x576p50_4_3_TIMING				\
+	{HDMI_VFRMT_720x576p50_4_3, 720, 12, 64, 68, true,		\
+	 576,  5, 5, 39, true, 27000, 50000, false, true}
+#define HDMI_VFRMT_720x576p50_16_9_TIMING				\
+	{HDMI_VFRMT_720x576p50_16_9, 720, 12, 64, 68, true,		\
+	 576,  5, 5, 39, true, 27000, 50000, false, true}
+#define HDMI_VFRMT_1280x720p50_16_9_TIMING				\
+	{HDMI_VFRMT_1280x720p50_16_9, 1280, 440, 40, 220, false,	\
+	 720,  5, 5, 20, false, 74250, 50000, false, true}
+#define HDMI_VFRMT_1440x576i50_4_3_TIMING				\
+	{HDMI_VFRMT_1440x576i50_4_3, 1440, 24, 126, 138, true,		\
+	 288,  2, 3, 19, true, 27000, 50000, true, true}
+#define HDMI_VFRMT_1440x576i50_16_9_TIMING				\
+	{HDMI_VFRMT_1440x576i50_16_9, 1440, 24, 126, 138, true,		\
+	 288,  2, 3, 19, true, 27000, 50000, true, true}
+#define HDMI_VFRMT_1920x1080p50_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080p50_16_9, 1920, 528, 44, 148, false,	\
+	 1080, 4, 5, 36, false, 148500, 50000, false, true}
+#define HDMI_VFRMT_1920x1080p24_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080p24_16_9, 1920, 638, 44, 148, false,	\
+	 1080, 4, 5, 36, false, 74250, 24000, false, true}
+#define HDMI_VFRMT_1920x1080p25_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080p25_16_9, 1920, 528, 44, 148, false,	\
+	 1080, 4, 5, 36, false, 74250, 25000, false, true}
+#define HDMI_VFRMT_1920x1080p30_16_9_TIMING				\
+	{HDMI_VFRMT_1920x1080p30_16_9, 1920, 88, 44, 148, false,	\
+	 1080, 4, 5, 36, false, 74250, 30000, false, true}
+#define HDMI_VFRMT_1280x1024p60_5_4_TIMING				\
+	{HDMI_VFRMT_1280x1024p60_5_4, 1280, 48, 112, 248, false,	\
+	1024, 1, 3, 38, false, 108000, 60000, false, true}
+#define HDMI_VFRMT_2560x1600p60_16_9_TIMING				\
+	{HDMI_VFRMT_2560x1600p60_16_9, 2560, 48, 32, 80, false,		\
+	 1600, 3, 6, 37, false, 268500, 60000, false, true}
+#define HDMI_VFRMT_3840x2160p30_16_9_TIMING				\
+	{HDMI_VFRMT_3840x2160p30_16_9, 3840, 176, 88, 296, false,	\
+	 2160, 8, 10, 72, false, 297000, 30000, false, true}
+#define HDMI_VFRMT_3840x2160p25_16_9_TIMING				\
+	{HDMI_VFRMT_3840x2160p25_16_9, 3840, 1056, 88, 296, false,	\
+	 2160, 8, 10, 72, false, 297000, 25000, false, true}
+#define HDMI_VFRMT_3840x2160p24_16_9_TIMING				\
+	{HDMI_VFRMT_3840x2160p24_16_9, 3840, 1276, 88, 296, false,	\
+	 2160, 8, 10, 72, false, 297000, 24000, false, true}
+#define HDMI_VFRMT_4096x2160p24_16_9_TIMING				\
+	{HDMI_VFRMT_4096x2160p24_16_9, 4096, 1020, 88, 296, false,	\
+	 2160, 8, 10, 72, false, 297000, 24000, false, true}
+
+#define MSM_HDMI_MODES_SET_TIMING(LUT, MODE) do {		\
+	struct msm_hdmi_mode_timing_info mode = MODE##_TIMING;	\
+	LUT[MODE] = mode;\
+	} while (0)
+
+static inline void MSM_HDMI_MODES_INIT_TIMINGS(
+	struct msm_hdmi_mode_timing_info *lut)
+{
+	int i;
+
+	for (i = 0; i < HDMI_VFRMT_MAX; i++) {
+		struct msm_hdmi_mode_timing_info mode = VFRMT_NOT_SUPPORTED(i);
+		lut[i] = mode;
+	}
+}
+
+static inline void MSM_HDMI_MODES_SET_SUPP_TIMINGS(
+	struct msm_hdmi_mode_timing_info *lut, int type)
+{
+	if (type & MSM_HDMI_MODES_CEA) {
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_640x480p60_4_3);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_720x480p60_4_3);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_720x480p60_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1280x720p60_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080i60_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1440x480i60_4_3);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1440x480i60_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080p60_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_720x576p50_4_3);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_720x576p50_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1280x720p50_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1440x576i50_4_3);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1440x576i50_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080p50_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080p24_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080p25_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1920x1080p30_16_9);
+	}
+
+	if (type & MSM_HDMI_MODES_XTND) {
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_3840x2160p30_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_3840x2160p25_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_3840x2160p24_16_9);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_4096x2160p24_16_9);
+	}
+
+	if (type & MSM_HDMI_MODES_DVI) {
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_1280x1024p60_5_4);
+		MSM_HDMI_MODES_SET_TIMING(lut, HDMI_VFRMT_2560x1600p60_16_9);
+	}
+}
+
+static inline const char *msm_hdmi_mode_2string(uint32_t mode)
+{
+	switch (mode) {
+	case HDMI_VFRMT_UNKNOWN:		return "Unknown";
+	case HDMI_VFRMT_640x480p60_4_3:		return "640x480 p60 4/3";
+	case HDMI_VFRMT_720x480p60_4_3:		return "720x480 p60 4/3";
+	case HDMI_VFRMT_720x480p60_16_9:	return "720x480 p60 16/9";
+	case HDMI_VFRMT_1280x720p60_16_9:	return "1280x 720 p60 16/9";
+	case HDMI_VFRMT_1920x1080i60_16_9:	return "1920x1080 i60 16/9";
+	case HDMI_VFRMT_1440x480i60_4_3:	return "1440x480 i60 4/3";
+	case HDMI_VFRMT_1440x480i60_16_9:	return "1440x480 i60 16/9";
+	case HDMI_VFRMT_1440x240p60_4_3:	return "1440x240 p60 4/3";
+	case HDMI_VFRMT_1440x240p60_16_9:	return "1440x240 p60 16/9";
+	case HDMI_VFRMT_2880x480i60_4_3:	return "2880x480 i60 4/3";
+	case HDMI_VFRMT_2880x480i60_16_9:	return "2880x480 i60 16/9";
+	case HDMI_VFRMT_2880x240p60_4_3:	return "2880x240 p60 4/3";
+	case HDMI_VFRMT_2880x240p60_16_9:	return "2880x240 p60 16/9";
+	case HDMI_VFRMT_1440x480p60_4_3:	return "1440x480 p60 4/3";
+	case HDMI_VFRMT_1440x480p60_16_9:	return "1440x480 p60 16/9";
+	case HDMI_VFRMT_1920x1080p60_16_9:	return "1920x1080 p60 16/9";
+	case HDMI_VFRMT_720x576p50_4_3:		return "720x576 p50 4/3";
+	case HDMI_VFRMT_720x576p50_16_9:	return "720x576 p50 16/9";
+	case HDMI_VFRMT_1280x720p50_16_9:	return "1280x720 p50 16/9";
+	case HDMI_VFRMT_1920x1080i50_16_9:	return "1920x1080 i50 16/9";
+	case HDMI_VFRMT_1440x576i50_4_3:	return "1440x576 i50 4/3";
+	case HDMI_VFRMT_1440x576i50_16_9:	return "1440x576 i50 16/9";
+	case HDMI_VFRMT_1440x288p50_4_3:	return "1440x288 p50 4/3";
+	case HDMI_VFRMT_1440x288p50_16_9:	return "1440x288 p50 16/9";
+	case HDMI_VFRMT_2880x576i50_4_3:	return "2880x576 i50 4/3";
+	case HDMI_VFRMT_2880x576i50_16_9:	return "2880x576 i50 16/9";
+	case HDMI_VFRMT_2880x288p50_4_3:	return "2880x288 p50 4/3";
+	case HDMI_VFRMT_2880x288p50_16_9:	return "2880x288 p50 16/9";
+	case HDMI_VFRMT_1440x576p50_4_3:	return "1440x576 p50 4/3";
+	case HDMI_VFRMT_1440x576p50_16_9:	return "1440x576 p50 16/9";
+	case HDMI_VFRMT_1920x1080p50_16_9:	return "1920x1080 p50 16/9";
+	case HDMI_VFRMT_1920x1080p24_16_9:	return "1920x1080 p24 16/9";
+	case HDMI_VFRMT_1920x1080p25_16_9:	return "1920x1080 p25 16/9";
+	case HDMI_VFRMT_1920x1080p30_16_9:	return "1920x1080 p30 16/9";
+	case HDMI_VFRMT_2880x480p60_4_3:	return "2880x480 p60 4/3";
+	case HDMI_VFRMT_2880x480p60_16_9:	return "2880x480 p60 16/9";
+	case HDMI_VFRMT_2880x576p50_4_3:	return "2880x576 p50 4/3";
+	case HDMI_VFRMT_2880x576p50_16_9:	return "2880x576 p50 16/9";
+	case HDMI_VFRMT_1920x1250i50_16_9:	return "1920x1250 i50 16/9";
+	case HDMI_VFRMT_1920x1080i100_16_9:	return "1920x1080 i100 16/9";
+	case HDMI_VFRMT_1280x720p100_16_9:	return "1280x720 p100 16/9";
+	case HDMI_VFRMT_720x576p100_4_3:	return "720x576 p100 4/3";
+	case HDMI_VFRMT_720x576p100_16_9:	return "720x576 p100 16/9";
+	case HDMI_VFRMT_1440x576i100_4_3:	return "1440x576 i100 4/3";
+	case HDMI_VFRMT_1440x576i100_16_9:	return "1440x576 i100 16/9";
+	case HDMI_VFRMT_1920x1080i120_16_9:	return "1920x1080 i120 16/9";
+	case HDMI_VFRMT_1280x720p120_16_9:	return "1280x720 p120 16/9";
+	case HDMI_VFRMT_720x480p120_4_3:	return "720x480 p120 4/3";
+	case HDMI_VFRMT_720x480p120_16_9:	return "720x480 p120 16/9";
+	case HDMI_VFRMT_1440x480i120_4_3:	return "1440x480 i120 4/3";
+	case HDMI_VFRMT_1440x480i120_16_9:	return "1440x480 i120 16/9";
+	case HDMI_VFRMT_720x576p200_4_3:	return "720x576 p200 4/3";
+	case HDMI_VFRMT_720x576p200_16_9:	return "720x576 p200 16/9";
+	case HDMI_VFRMT_1440x576i200_4_3:	return "1440x576 i200 4/3";
+	case HDMI_VFRMT_1440x576i200_16_9:	return "1440x576 i200 16/9";
+	case HDMI_VFRMT_720x480p240_4_3:	return "720x480 p240 4/3";
+	case HDMI_VFRMT_720x480p240_16_9:	return "720x480 p240 16/9";
+	case HDMI_VFRMT_1440x480i240_4_3:	return "1440x480 i240 4/3";
+	case HDMI_VFRMT_1440x480i240_16_9:	return "1440x480 i240 16/9";
+	case HDMI_VFRMT_1280x720p24_16_9:	return "1280x720 p24 16/9";
+	case HDMI_VFRMT_1280x720p25_16_9:	return "1280x720 p25 16/9";
+	case HDMI_VFRMT_1280x720p30_16_9:	return "1280x720 p30 16/9";
+	case HDMI_VFRMT_1920x1080p120_16_9:	return "1920x1080 p120 16/9";
+	case HDMI_VFRMT_1920x1080p100_16_9:	return "1920x1080 p100 16/9";
+	case HDMI_VFRMT_3840x2160p30_16_9:	return "3840x2160 p30 16/9";
+	case HDMI_VFRMT_3840x2160p25_16_9:	return "3840x2160 p25 16/9";
+	case HDMI_VFRMT_3840x2160p24_16_9:	return "3840x2160 p24 16/9";
+	case HDMI_VFRMT_4096x2160p24_16_9:	return "4096x2160 p24 16/9";
+	case HDMI_VFRMT_2560x1600p60_16_9:	return "2560x1600 p60 16/9";
+	case HDMI_VFRMT_1280x1024p60_5_4:	return "1280x1042 p60 5/4";
+	default:				return "???";
+	}
+}
+#endif /* __MSM_HDMI_MODES_H__ */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 5097036..e1fa62e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -212,6 +212,14 @@
 	[NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN },
 	[NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
 	[NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
+	[NL80211_ATTR_SPLIT_WIPHY_DUMP] = { .type = NLA_FLAG, },
+	[NL80211_ATTR_DISABLE_VHT] = { .type = NLA_FLAG },
+	[NL80211_ATTR_VHT_CAPABILITY_MASK] = {
+		.len = NL80211_VHT_CAPABILITY_LEN,
+	},
+	[NL80211_ATTR_MDID] = { .type = NLA_U16 },
+	[NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
+				  .len = IEEE80211_MAX_DATA_LEN },
 };
 
 /* policy for the key attributes */
@@ -6445,6 +6453,27 @@
 	return 0;
 }
 
+static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+	struct cfg80211_update_ft_ies_params ft_params;
+	struct net_device *dev = info->user_ptr[1];
+
+	if (!rdev->ops->update_ft_ies)
+		return -EOPNOTSUPP;
+
+	if (!info->attrs[NL80211_ATTR_MDID] ||
+	    !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+		return -EINVAL;
+
+	memset(&ft_params, 0, sizeof(ft_params));
+	ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
+	ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+	ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+
+	return rdev->ops->update_ft_ies(&rdev->wiphy, dev, &ft_params);
+}
+
 #define NL80211_FLAG_NEED_WIPHY		0x01
 #define NL80211_FLAG_NEED_NETDEV	0x02
 #define NL80211_FLAG_NEED_RTNL		0x04
@@ -7033,6 +7062,14 @@
 		.internal_flags = NL80211_FLAG_NEED_NETDEV |
 				  NL80211_FLAG_NEED_RTNL,
 	},
+	{
+		.cmd = NL80211_CMD_UPDATE_FT_IES,
+		.doit = nl80211_update_ft_ies,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+				  NL80211_FLAG_NEED_RTNL,
+	},
 
 };
 
@@ -8270,6 +8307,48 @@
 	.notifier_call = nl80211_netlink_notify,
 };
 
+void cfg80211_ft_event(struct net_device *netdev,
+		       struct cfg80211_ft_event_params *ft_event)
+{
+	struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+	struct sk_buff *msg;
+	void *hdr;
+	int err;
+
+	if (!ft_event->target_ap)
+		return;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
+	if (!hdr) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+	nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+	nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap);
+	if (ft_event->ies)
+		nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies);
+	if (ft_event->ric_ies)
+		nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
+			ft_event->ric_ies);
+
+	err = genlmsg_end(msg, hdr);
+	if (err < 0) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+				nl80211_mlme_mcgrp.id, GFP_KERNEL);
+}
+EXPORT_SYMBOL(cfg80211_ft_event);
+
 /* initialisation/exit functions */
 
 int nl80211_init(void)
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 5f4490b..08167ca 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -204,8 +204,21 @@
 #define TAIKO_TX_PORT_NUMBER	16
 
 #define TAIKO_I2S_MASTER_MODE_MASK 0x08
-#define TAIKO_MCLK_CLK_12P288MHZ 12288000
-#define TAIKO_MCLK_CLK_9P6HZ 9600000
+
+#define TAIKO_DMIC_SAMPLE_RATE_DIV_2	0x0
+#define TAIKO_DMIC_SAMPLE_RATE_DIV_3	0x1
+#define TAIKO_DMIC_SAMPLE_RATE_DIV_4	0x2
+
+#define TAIKO_DMIC_B1_CTL_DIV_2 0x00
+#define TAIKO_DMIC_B1_CTL_DIV_3 0x22
+#define TAIKO_DMIC_B1_CTL_DIV_4 0x44
+
+#define TAIKO_DMIC_B2_CTL_DIV_2 0x00
+#define TAIKO_DMIC_B2_CTL_DIV_3 0x02
+#define TAIKO_DMIC_B2_CTL_DIV_4 0x04
+
+#define TAIKO_ANC_DMIC_X2_ON	0x1
+#define TAIKO_ANC_DMIC_X2_OFF	0x0
 
 #define TAIKO_SLIM_CLOSE_TIMEOUT 1000
 #define TAIKO_SLIM_IRQ_OVERFLOW (1 << 0)
@@ -5208,6 +5221,9 @@
 	u8 leg_mode, txfe_bypass, txfe_buff, flag;
 	u8 i = 0, j = 0;
 	u8 val_txfe = 0, value = 0;
+	u8 dmic_sample_rate_value = 0;
+	u8 dmic_b1_ctl_value = 0, dmic_b2_ctl_value = 0;
+	u8 anc_ctl_value = 0;
 
 	if (!pdata) {
 		pr_err("%s: NULL pdata\n", __func__);
@@ -5338,6 +5354,96 @@
 		 0x00 : 0x16);
 	snd_soc_update_bits(codec, TAIKO_A_MICB_4_CTL, 0x1E, value);
 
+	/* Set the DMIC sample rate */
+	if (pdata->mclk_rate == TAIKO_MCLK_CLK_9P6HZ) {
+		switch (pdata->dmic_sample_rate) {
+		case TAIKO_DMIC_SAMPLE_RATE_2P4MHZ:
+			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_4;
+			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_4;
+			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_4;
+			anc_ctl_value = TAIKO_ANC_DMIC_X2_OFF;
+			break;
+		case TAIKO_DMIC_SAMPLE_RATE_4P8MHZ:
+			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_2;
+			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_2;
+			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_2;
+			anc_ctl_value = TAIKO_ANC_DMIC_X2_ON;
+			break;
+		case TAIKO_DMIC_SAMPLE_RATE_3P2MHZ:
+		case TAIKO_DMIC_SAMPLE_RATE_UNDEFINED:
+			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_3;
+			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_3;
+			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_3;
+			anc_ctl_value = TAIKO_ANC_DMIC_X2_OFF;
+			break;
+		default:
+			pr_err("%s Invalid sample rate %d for mclk %d\n",
+			__func__, pdata->dmic_sample_rate, pdata->mclk_rate);
+			rc = -EINVAL;
+			goto done;
+			break;
+		}
+	} else if (pdata->mclk_rate == TAIKO_MCLK_CLK_12P288MHZ) {
+		switch (pdata->dmic_sample_rate) {
+		case TAIKO_DMIC_SAMPLE_RATE_3P072MHZ:
+			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_4;
+			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_4;
+			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_4;
+			anc_ctl_value = TAIKO_ANC_DMIC_X2_OFF;
+			break;
+		case TAIKO_DMIC_SAMPLE_RATE_6P144MHZ:
+			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_2;
+			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_2;
+			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_2;
+			anc_ctl_value = TAIKO_ANC_DMIC_X2_ON;
+			break;
+		case TAIKO_DMIC_SAMPLE_RATE_4P096MHZ:
+		case TAIKO_DMIC_SAMPLE_RATE_UNDEFINED:
+			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_3;
+			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_3;
+			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_3;
+			anc_ctl_value = TAIKO_ANC_DMIC_X2_OFF;
+			break;
+		default:
+			pr_err("%s Invalid sample rate %d for mclk %d\n",
+			__func__, pdata->dmic_sample_rate, pdata->mclk_rate);
+			rc = -EINVAL;
+			goto done;
+			break;
+		}
+	} else {
+		pr_err("%s MCLK is not set!\n", __func__);
+		rc = -EINVAL;
+		goto done;
+	}
+
+	snd_soc_update_bits(codec, TAIKO_A_CDC_TX1_DMIC_CTL,
+		0x7, dmic_sample_rate_value);
+	snd_soc_update_bits(codec, TAIKO_A_CDC_TX2_DMIC_CTL,
+		0x7, dmic_sample_rate_value);
+	snd_soc_update_bits(codec, TAIKO_A_CDC_TX3_DMIC_CTL,
+		0x7, dmic_sample_rate_value);
+	snd_soc_update_bits(codec, TAIKO_A_CDC_TX4_DMIC_CTL,
+		0x7, dmic_sample_rate_value);
+	snd_soc_update_bits(codec, TAIKO_A_CDC_TX5_DMIC_CTL,
+		0x7, dmic_sample_rate_value);
+	snd_soc_update_bits(codec, TAIKO_A_CDC_TX6_DMIC_CTL,
+		0x7, dmic_sample_rate_value);
+	snd_soc_update_bits(codec, TAIKO_A_CDC_TX7_DMIC_CTL,
+		0x7, dmic_sample_rate_value);
+	snd_soc_update_bits(codec, TAIKO_A_CDC_TX8_DMIC_CTL,
+		0x7, dmic_sample_rate_value);
+	snd_soc_update_bits(codec, TAIKO_A_CDC_TX9_DMIC_CTL,
+		0x7, dmic_sample_rate_value);
+	snd_soc_update_bits(codec, TAIKO_A_CDC_TX10_DMIC_CTL,
+		0x7, dmic_sample_rate_value);
+	snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_DMIC_B1_CTL,
+		0xEE, dmic_b1_ctl_value);
+	snd_soc_update_bits(codec, TAIKO_A_CDC_CLK_DMIC_B2_CTL,
+		0xE, dmic_b2_ctl_value);
+	snd_soc_update_bits(codec, TAIKO_A_CDC_ANC1_B2_CTL,
+		0x1, anc_ctl_value);
+
 done:
 	return rc;
 }
@@ -5568,22 +5674,6 @@
 	{TAIKO_A_CDC_TX9_MUX_CTL, 0x8, 0x0},
 	{TAIKO_A_CDC_TX10_MUX_CTL, 0x8, 0x0},
 
-	/* config Decimator for DMIC CLK_MODE_1(3.2Mhz@9.6Mhz mclk) */
-	{TAIKO_A_CDC_TX1_DMIC_CTL, 0x7, 0x1},
-	{TAIKO_A_CDC_TX2_DMIC_CTL, 0x7, 0x1},
-	{TAIKO_A_CDC_TX3_DMIC_CTL, 0x7, 0x1},
-	{TAIKO_A_CDC_TX4_DMIC_CTL, 0x7, 0x1},
-	{TAIKO_A_CDC_TX5_DMIC_CTL, 0x7, 0x1},
-	{TAIKO_A_CDC_TX6_DMIC_CTL, 0x7, 0x1},
-	{TAIKO_A_CDC_TX7_DMIC_CTL, 0x7, 0x1},
-	{TAIKO_A_CDC_TX8_DMIC_CTL, 0x7, 0x1},
-	{TAIKO_A_CDC_TX9_DMIC_CTL, 0x7, 0x1},
-	{TAIKO_A_CDC_TX10_DMIC_CTL, 0x7, 0x1},
-
-	/* config DMIC clk to CLK_MODE_1 (3.2Mhz@9.6Mhz mclk) */
-	{TAIKO_A_CDC_CLK_DMIC_B1_CTL, 0xEE, 0x22},
-	{TAIKO_A_CDC_CLK_DMIC_B2_CTL, 0x0E, 0x02},
-
 	/* Compander zone selection */
 	{TAIKO_A_CDC_COMP0_B4_CTL, 0x3F, 0x37},
 	{TAIKO_A_CDC_COMP1_B4_CTL, 0x3F, 0x37},
diff --git a/sound/soc/msm/msm-pcm-afe.c b/sound/soc/msm/msm-pcm-afe.c
index a3bcf23..35b5dcf 100644
--- a/sound/soc/msm/msm-pcm-afe.c
+++ b/sound/soc/msm/msm-pcm-afe.c
@@ -30,7 +30,6 @@
 #include <sound/q6adm.h>
 #include <asm/dma.h>
 #include <linux/memory_alloc.h>
-#include <mach/msm_subsystem_map.h>
 #include "msm-pcm-afe.h"
 #include "msm-pcm-q6.h"
 
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
index e4f3f94..96ddcf6 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
@@ -30,7 +30,6 @@
 #include <sound/q6adm-v2.h>
 #include <asm/dma.h>
 #include <linux/memory_alloc.h>
-#include <mach/msm_subsystem_map.h>
 #include "msm-pcm-afe-v2.h"
 
 #define MIN_PERIOD_SIZE (128 * 2)
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 49b6d03..3dbe49a 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -35,7 +35,6 @@
 #include <mach/memory.h>
 #include <mach/debug_mm.h>
 #include <mach/qdsp6v2/rtac.h>
-#include <mach/msm_subsystem_map.h>
 
 #include <sound/apr_audio-v2.h>
 #include <sound/q6asm-v2.h>
diff --git a/sound/soc/msm/qdsp6v2/q6lsm.c b/sound/soc/msm/qdsp6v2/q6lsm.c
index f2b531a..49e5ede 100644
--- a/sound/soc/msm/qdsp6v2/q6lsm.c
+++ b/sound/soc/msm/qdsp6v2/q6lsm.c
@@ -30,7 +30,6 @@
 #include <asm/ioctls.h>
 #include <mach/memory.h>
 #include <mach/debug_mm.h>
-#include <mach/msm_subsystem_map.h>
 #include "audio_acdb.h"
 
 #define APR_TIMEOUT	(5 * HZ)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 915c3c2..40595bf 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1649,9 +1649,11 @@
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
-	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
 		break;
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
+		break;
 	}
 
 out: