Merge "msm: msm_bus: Fix memory leak during RPM transaction"
diff --git a/Documentation/devicetree/bindings/arm/msm/lpm-levels.txt b/Documentation/devicetree/bindings/arm/msm/lpm-levels.txt
index 4129f7f..b359c49 100644
--- a/Documentation/devicetree/bindings/arm/msm/lpm-levels.txt
+++ b/Documentation/devicetree/bindings/arm/msm/lpm-levels.txt
@@ -8,6 +8,10 @@
 lpm-level. The units for voltage are dependent on the PMIC used on the target
 and are in uV.
 
+The optional properties are:
+
+- qcom,use-qtimer: Indicates whether the target uses the synchronized QTimer.
+
 The required nodes for lpm-levels are:
 
 - compatible: "qcom,lpm-levels"
@@ -34,6 +38,7 @@
 Example:
 
 qcom,lpm-levels {
+	qcom,use-qtimer;
 	qcom,lpm-level@0 {
 		reg = <0>;
 		qcom,mode = <0>;        /* MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT */
diff --git a/Documentation/devicetree/bindings/coresight/coresight.txt b/Documentation/devicetree/bindings/coresight/coresight.txt
index f860618..b3037d8 100644
--- a/Documentation/devicetree/bindings/coresight/coresight.txt
+++ b/Documentation/devicetree/bindings/coresight/coresight.txt
@@ -32,6 +32,7 @@
 - coresight-child-ports : list of input port numbers of the children
 - coresight-default-sink : represents the default compile time CoreSight sink
 - qcom,pc-save : program counter save implemented
+- qcom,blk-size : block size for tmc-etr to usb transfers
 
 Examples:
 
diff --git a/Documentation/devicetree/bindings/power/bq28400-battery.txt b/Documentation/devicetree/bindings/power/bq28400-battery.txt
index 1460d70..a95e61f 100644
--- a/Documentation/devicetree/bindings/power/bq28400-battery.txt
+++ b/Documentation/devicetree/bindings/power/bq28400-battery.txt
@@ -4,15 +4,20 @@
 The device interface is I2C, its I2C slave 7-bit address is 0xb.
 The device is usually embedded inside the "smart battery" pack.
 
-node required properties:
-- compatible:	Must be "ti,bq28400-battery" or "ti,bq30z55-battery"
-- reg:		I2C Address must be 0xb.
+Required properties:
+
+ - compatible : Must be "ti,bq28400-battery" or "ti,bq30z55-battery"
+ - reg : I2C Address must be 0xb.
+ - ti,temp-cold : Cold temperature limit in celsius degree
+ - ti,temp-hot : Hot temperature limit in celsius degree
 
 Example:
 	i2c@f9967000 {
 		battery@b {
 			compatible = "ti,bq28400-battery", "ti,bq30z55-battery";
 			reg = <0xb>;
+			ti,temp-cold = <2>;
+			ti,temp-hot = <43>;
 		};
 	};
 
diff --git a/Documentation/devicetree/bindings/regulator/krait-regulator.txt b/Documentation/devicetree/bindings/regulator/krait-regulator.txt
index fddae80..149445d 100644
--- a/Documentation/devicetree/bindings/regulator/krait-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/krait-regulator.txt
@@ -2,13 +2,25 @@
 
 Required properties:
 - compatible:			Must be "qcom,krait-regulator"
-- reg:				Specifies the address and size for this regulator device
+- reg:				Specifies the address and size for this regulator device,
+				also specifies the address and the size for the MDD area
+				to be used along with the regulator
+- reg-names:			"acs" -string to identify the area where main power control
+					registers reside.
+				"mdd" - string to identify the area where mdd registers reside.
 - qcom,headroom-voltage:	The minimum required voltage drop between the input
 			 	voltage and the output voltage for the LDO to be
-			 	operational, in microvolts
-- qcom,retention-voltage:	The value for retention voltage in microvolts
-- qcom,ldo-default-voltage:	The default value for LDO voltage in microvolts
-- qcom,ldo-threshold-voltage:	The voltage value above which LDO is nonfunctional
+			 	operational, in microvolts. Acceptable values are from
+				50000uV to 250000uV
+- qcom,retention-voltage:	The value for retention voltage in microvolts. Acceptable
+				values are from 465000uV to 750000uV
+- qcom,ldo-default-voltage:	The default value for LDO voltage in microvolts. Acceptable
+				values are from 465000uV to 750000uV
+- qcom,ldo-threshold-voltage:	The voltage value above which LDO is nonfunctional.
+				Acceptable values are from 600000uV to 900000uV
+- qcom,ldo-delta-voltage:	The delta used to reduce the requested voltage in order
+				to derive the LDO output voltage while switching
+				to LDO mode. Acceptable values are from 1000uV to 100000uV
 
 Any property defined as part of the core regulator
 binding, defined in regulator.txt, can also be used.
@@ -17,11 +29,15 @@
 	krait0_vreg: regulator@f9088000 {
 		compatible = "qcom,krait-regulator";
 		regulator-name = "krait0";
-		reg = <0xf9088000 0x1000>;
+		reg = <0xf9088000 0x1000>, /* APCS_ALIAS0_KPSS_ACS */
+			<0xf908a800 0x1000>; /* APCS_ALIAS0_KPSS_MDD */
+		reg-names = "acs", "mdd";
 		regulator-min-microvolt = <500000>;
 		regulator-max-microvolt = <1100000>;
 		qcom,headroom-voltage = <150000>;
 		qcom,retention-voltage = <745000>;
 		qcom,ldo-default-voltage = <745000>;
 		qcom,ldo-threshold-voltage = <750000>;
+		qcom,ldo-delta-voltage = <50000>;
 	};
+
diff --git a/Documentation/devicetree/bindings/tty/serial/msm_serial_hs.txt b/Documentation/devicetree/bindings/tty/serial/msm_serial_hs.txt
index 3534823..dc115e0 100644
--- a/Documentation/devicetree/bindings/tty/serial/msm_serial_hs.txt
+++ b/Documentation/devicetree/bindings/tty/serial/msm_serial_hs.txt
@@ -5,9 +5,13 @@
 	- "qcom,msm-hsuart-v14" to be used for UARTDM Core v1.4
 - reg : offset and length of the register set for both the device,
 	uart core and bam core
-- reg-names : names of the uart core and bam core.
-- interrupts : should contain the uart interrupt.
-- interrupt-names : names of interrupts to be used.
+- reg-names :
+	- "core_mem" to be used as name of the uart core
+	- "bam_mem" to be used as name of the bam core
+- interrupts : interrupts for both the device,uart core and bam core
+- interrupt-names :
+	- "core_irq" to be used as uart irq
+	- "bam irq" to be used as bam irq
 - bam-tx-ep-pipe-index : BAM TX Endpoint Pipe Index for HSUART
 - bam-rx-ep-pipe-index : BAM RX Endpoint Pipe Index for HSUART
 
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index cc64765..2cb2182 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -182,6 +182,8 @@
 Optional properties :
 - qcom,ignore-core-reset-ack: If present then BAM ignores ACK from USB core
 	    while performing PIPE RESET
+- qcom,disable-clk-gating: If present then disable BAM clock gating.
+
 
 Example USB BAM controller device node:
 
diff --git a/arch/arm/boot/dts/msm-iommu.dtsi b/arch/arm/boot/dts/msm-iommu.dtsi
index 5a9e1ee..9bb642d 100755
--- a/arch/arm/boot/dts/msm-iommu.dtsi
+++ b/arch/arm/boot/dts/msm-iommu.dtsi
@@ -40,8 +40,8 @@
 					0x2010
 					0x2014>;
 
-		qcom,iommu-bfb-data =  <0xffffffff
-					0xffffffff
+		qcom,iommu-bfb-data =  <0x0000ffff
+					0x0
 					0x4
 					0x4
 					0x0
@@ -111,7 +111,7 @@
 					0x2020>;
 
 		qcom,iommu-bfb-data =  <0xffffffff
-					0xffffffff
+					0x0
 					0x00000004
 					0x00000010
 					0x00000000
@@ -261,8 +261,8 @@
 					0x2414
 					0x2008>;
 
-		qcom,iommu-bfb-data =  <0xffffffff
-					0xffffffff
+		qcom,iommu-bfb-data =  <0x00000003
+					0x0
 					0x00000004
 					0x00000010
 					0x00000000
@@ -322,7 +322,7 @@
 					0x2020>;
 
 		qcom,iommu-bfb-data =  <0xffffffff
-					0xffffffff
+					0x00000000
 					0x4
 					0x8
 					0x0
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index 9f0ff92..0277a1c 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -71,11 +71,11 @@
         usb@f9a55000 {
 		compatible = "qcom,hsusb-otg";
 		reg = <0xf9a55000 0x400>;
-		interrupts = <0 134 0>;
-		interrupt-names = "core_irq";
-                HSUSB_VDDCX-supply = <&pm8026_s1>;
-                HSUSB_1p8-supply = <&pm8026_l10>;
-                HSUSB_3p3-supply = <&pm8026_l20>;
+		interrupts = <0 134 0>, <0 140 0>;
+		interrupt-names = "core_irq", "async_irq";
+		HSUSB_VDDCX-supply = <&pm8026_s1>;
+		HSUSB_1p8-supply = <&pm8026_l10>;
+		HSUSB_3p3-supply = <&pm8026_l20>;
 
 		qcom,hsusb-otg-phy-type = <2>;
 		qcom,hsusb-otg-mode = <1>;
diff --git a/arch/arm/boot/dts/msm8610-pm.dtsi b/arch/arm/boot/dts/msm8610-pm.dtsi
new file mode 100644
index 0000000..e107b36
--- /dev/null
+++ b/arch/arm/boot/dts/msm8610-pm.dtsi
@@ -0,0 +1,402 @@
+/* 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/ "skeleton.dtsi"
+
+/ {
+	qcom,spm@f9089000 {
+		compatible = "qcom,spm-v2";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf9089000 0x1000>;
+		qcom,core-id = <0>;
+		qcom,saw2-ver-reg = <0xfd0>;
+		qcom,saw2-cfg = <0x01>;
+		qcom,saw2-spm-dly= <0x20000400>;
+		qcom,saw2-spm-ctl = <0x1>;
+		qcom,saw2-spm-cmd-wfi = [60 03 60 76 76 0b 0f];
+		qcom,saw2-spm-cmd-spc = [00 20 10 80 90 5b 60 03 60 3b 76 76 94
+				5b 80 10 2b 30 06 26 30 0f];
+		qcom,saw2-spm-cmd-pc = [00 20 10 80 90 5b 60 07 3b 76 76 0b 94
+				5b 80 10 2b 30 06 26 30 0f];
+	};
+
+	qcom,spm@f9099000 {
+		compatible = "qcom,spm-v2";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf9099000 0x1000>;
+		qcom,core-id = <1>;
+		qcom,saw2-ver-reg = <0xfd0>;
+		qcom,saw2-cfg = <0x01>;
+		qcom,saw2-spm-dly= <0x20000400>;
+		qcom,saw2-spm-ctl = <0x1>;
+		qcom,saw2-spm-cmd-wfi = [60 03 60 76 76 0b 0f];
+		qcom,saw2-spm-cmd-spc = [00 20 10 80 90 5b 60 03 60 3b 76 76 94
+				5b 80 10 2b 30 06 26 30 0f];
+		qcom,saw2-spm-cmd-pc = [00 20 10 80 90 5b 60 07 3b 76 76 0b 94
+				5b 80 10 2b 30 06 26 30 0f];
+	};
+
+	qcom,spm@f90a9000 {
+		compatible = "qcom,spm-v2";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf90a9000 0x1000>;
+		qcom,core-id = <2>;
+		qcom,saw2-ver-reg = <0xfd0>;
+		qcom,saw2-cfg = <0x01>;
+		qcom,saw2-spm-dly= <0x20000400>;
+		qcom,saw2-spm-ctl = <0x1>;
+		qcom,saw2-spm-cmd-wfi = [60 03 60 76 76 0b 0f];
+		qcom,saw2-spm-cmd-spc = [00 20 10 80 90 5b 60 03 60 3b 76 76 94
+				5b 80 10 2b 30 06 26 30 0f];
+		qcom,saw2-spm-cmd-pc = [00 20 10 80 90 5b 60 07 3b 76 76 0b 94
+				5b 80 10 2b 30 06 26 30 0f];
+	};
+
+	qcom,spm@f90b9000 {
+		compatible = "qcom,spm-v2";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf90b9000 0x1000>;
+		qcom,core-id = <3>;
+		qcom,saw2-ver-reg = <0xfd0>;
+		qcom,saw2-cfg = <0x01>;
+		qcom,saw2-spm-dly= <0x20000400>;
+		qcom,saw2-spm-ctl = <0x1>;
+		qcom,saw2-spm-cmd-wfi = [60 03 60 76 76 0b 0f];
+		qcom,saw2-spm-cmd-spc = [00 20 10 80 90 5b 60 03 60 3b 76 76 94
+				5b 80 10 2b 30 06 26 30 0f];
+		qcom,saw2-spm-cmd-pc = [00 20 10 80 90 5b 60 07 3b 76 76 0b 94
+				5b 80 10 2b 30 06 26 30 0f];
+	};
+
+	qcom,spm@f9012000 {
+		compatible = "qcom,spm-v2";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0xf9012000 0x1000>;
+		qcom,core-id = <0xffff>; /* L2/APCS SAW */
+		qcom,saw2-ver-reg = <0xfd0>;
+		qcom,saw2-cfg = <0x14>;
+		qcom,saw2-spm-dly= <0x20000400>;
+		qcom,saw2-spm-ctl = <0x1>;
+		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 = [0b 00 03 00 7b 0f];
+		qcom,saw2-spm-cmd-gdhs = [00 20 32 60 70 80 0b 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 0b 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,lpm-resources {
+		compatible = "qcom,lpm-resources";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		qcom,lpm-resources@0 {
+			reg = <0x0>;
+			qcom,name = "vdd-dig";
+			qcom,resource-type = <0>;
+			qcom,type = <0x62706d73>;	/* "smpb" */
+			qcom,id = <0x02>;
+			qcom,key = <0x6e726f63>;	/* "corn" */
+			qcom,init-value = <5>;		/* Super Turbo */
+		};
+
+		qcom,lpm-resources@1 {
+			reg = <0x1>;
+			qcom,name = "vdd-mem";
+			qcom,resource-type = <0>;
+			qcom,type = <0x62706d73>;	/* "smpb" */
+			qcom,id = <0x01>;
+			qcom,key = <0x7675>;		/* "uv" */
+			qcom,init-value = <1050000>;	/* Super Turbo */
+		};
+
+		qcom,lpm-resources@2 {
+			reg = <0x2>;
+			qcom,name = "pxo";
+			qcom,resource-type = <0>;
+			qcom,type = <0x306b6c63>;	/* "clk0" */
+			qcom,id = <0x00>;
+			qcom,key = <0x62616e45>;	/* "Enab" */
+			qcom,init-value = <1>;		/* On */
+		};
+
+		qcom,lpm-resources@3 {
+			reg = <0x3>;
+			qcom,name = "l2";
+			qcom,resource-type = <1>;
+			qcom,init-value = <2>;		/* Retention */
+		};
+	};
+
+	qcom,lpm-levels {
+		compatible = "qcom,lpm-levels";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		qcom,lpm-level@0 {
+			reg = <0x0>;
+			qcom,mode = <0>;        /* MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT */
+			qcom,xo = <1>;          /* ON */
+			qcom,l2 = <3>;          /* 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,latency-us = <1>;
+			qcom,ss-power = <784>;
+			qcom,energy-overhead = <190000>;
+			qcom,time-overhead = <100>;
+		};
+
+		qcom,lpm-level@1 {
+			reg = <0x1>;
+			qcom,mode = <4>;        /* MSM_PM_SLEEP_MODE_RETENTION*/
+			qcom,xo = <1>;          /* ON */
+			qcom,l2 = <3>;          /* 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,latency-us = <75>;
+			qcom,ss-power = <735>;
+			qcom,energy-overhead = <77341>;
+			qcom,time-overhead = <105>;
+		};
+
+
+		qcom,lpm-level@2 {
+			reg = <0x2>;
+			qcom,mode = <2>;        /* MSM_PM_SLEEP_MODE_STANDALONE_POWER_COLLAPSE */
+			qcom,xo = <1>;          /* ON */
+			qcom,l2 = <3>;          /* 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,latency-us = <95>;
+			qcom,ss-power = <725>;
+			qcom,energy-overhead = <99500>;
+			qcom,time-overhead = <130>;
+		};
+
+		qcom,lpm-level@3 {
+			reg = <0x3>;
+			qcom,mode = <3>;        /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <1>;          /* ON */
+			qcom,l2 = <1>;          /* 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,latency-us = <2000>;
+			qcom,ss-power = <138>;
+			qcom,energy-overhead = <1208400>;
+			qcom,time-overhead = <3200>;
+		};
+
+		qcom,lpm-level@4 {
+			reg = <0x4>;
+			qcom,mode = <3>;        /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <1>;          /* ON */
+			qcom,l2 = <0>;          /* OFF */
+			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,latency-us = <3000>;
+			qcom,ss-power = <110>;
+			qcom,energy-overhead = <1250300>;
+			qcom,time-overhead = <3500>;
+		};
+
+		qcom,lpm-level@5 {
+			reg = <0x5>;
+			qcom,mode = <3>;        /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <0>;          /* OFF */
+			qcom,l2 = <1>;          /* 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,latency-us = <3000>;
+			qcom,ss-power = <68>;
+			qcom,energy-overhead = <1350200>;
+			qcom,time-overhead = <4000>;
+		};
+
+		qcom,lpm-level@6 {
+			reg = <0x6>;
+			qcom,mode = <3>;        /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <0>;          /* OFF */
+			qcom,l2 = <0>;          /* OFF */
+			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,latency-us = <10300>;
+			qcom,ss-power = <63>;
+			qcom,energy-overhead = <2128000>;
+			qcom,time-overhead = <18200>;
+		};
+
+		qcom,lpm-level@7 {
+			reg = <0x7>;
+			qcom,mode= <3>;         /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <0>;          /* OFF */
+			qcom,l2 = <0>;          /* OFF */
+			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,latency-us = <18000>;
+			qcom,ss-power = <10>;
+			qcom,energy-overhead = <3202600>;
+			qcom,time-overhead = <27000>;
+		};
+
+		qcom,lpm-level@8 {
+			reg = <0x8>;
+			qcom,mode= <3>;         /* MSM_PM_SLEEP_MODE_POWER_COLLAPSE */
+			qcom,xo = <0>;          /* OFF */
+			qcom,l2 = <0>;          /* OFF */
+			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,latency-us = <20000>;
+			qcom,ss-power = <2>;
+			qcom,energy-overhead = <4252000>;
+			qcom,time-overhead = <32000>;
+		};
+	};
+
+	qcom,pm-boot {
+		compatible = "qcom,pm-boot";
+		qcom,mode = <0>; /* MSM_PM_BOOT_CONFIG_TZ */
+	};
+
+	qcom,mpm@fc4281d0 {
+		compatible = "qcom,mpm-v2";
+		reg = <0xfc4281d0 0x1000>, /* MSM_RPM_MPM_BASE 4K */
+		    <0xf9011008 0x4>;   /* MSM_APCS_GCC_BASE 4K */
+		reg-names = "vmpm", "ipc";
+		interrupts = <0 171 1>;
+
+		qcom,ipc-bit-offset = <1>;
+
+		qcom,gic-parent = <&intc>;
+		qcom,gic-map = <47 172>, /* usb2_hsic_async_wakeup_irq */
+			<53 104>, /* mdss_irq */
+			<62 222>, /* ee0_krait_hlos_spmi_periph_irq */
+			<0xff 57>,  /* mss_to_apps_irq(0) */
+			<0xff 58>,  /* mss_to_apps_irq(1) */
+			<0xff 59>,  /* mss_to_apps_irq(2) */
+			<0xff 60>,  /* mss_to_apps_irq(3) */
+			<0xff 173>, /* o_wcss_apss_smd_hi */
+			<0xff 174>, /* o_wcss_apss_smd_med */
+			<0xff 175>, /* o_wcss_apss_smd_low */
+			<0xff 176>, /* o_wcss_apss_smsm_irq */
+			<0xff 177>, /* o_wcss_apss_wlan_data_xfer_done */
+			<0xff 178>, /* o_wcss_apss_wlan_rx_data_avail */
+			<0xff 179>, /* o_wcss_apss_asic_intr
+
+			<0xff 188>, /* lpass_irq_out_apcs(0) */
+			<0xff 189>, /* lpass_irq_out_apcs(1) */
+			<0xff 190>, /* lpass_irq_out_apcs(2) */
+			<0xff 191>, /* lpass_irq_out_apcs(3) */
+			<0xff 192>, /* lpass_irq_out_apcs(4) */
+			<0xff 193>, /* lpass_irq_out_apcs(5) */
+			<0xff 194>, /* lpass_irq_out_apcs(6) */
+			<0xff 195>, /* lpass_irq_out_apcs(7) */
+			<0xff 196>, /* lpass_irq_out_apcs(8) */
+			<0xff 197>, /* lpass_irq_out_apcs(9) */
+			<0xff 200>, /* rpm_ipc(4) */
+			<0xff 201>, /* rpm_ipc(5) */
+			<0xff 202>, /* rpm_ipc(6) */
+			<0xff 203>, /* rpm_ipc(7) */
+			<0xff 204>, /* rpm_ipc(24) */
+			<0xff 205>, /* rpm_ipc(25) */
+			<0xff 206>, /* rpm_ipc(26) */
+			<0xff 207>, /* rpm_ipc(27) */
+			<0xff 240>; /* summary_irq_kpss */
+
+		qcom,gpio-parent = <&msmgpio>;
+		qcom,gpio-map = <3  102>,
+			<4  1 >,
+			<5  5 >,
+			<6  9 >,
+			<7  18>,
+			<8  20>,
+			<9  24>,
+			<10  27>,
+			<11  28>,
+			<12  34>,
+			<13  35>,
+			<14  37>,
+			<15  42>,
+			<16  44>,
+			<17  46>,
+			<18  50>,
+			<19  54>,
+			<20  59>,
+			<21  61>,
+			<22  62>,
+			<23  64>,
+			<24  65>,
+			<25  66>,
+			<26  67>,
+			<27  68>,
+			<28  71>,
+			<29  72>,
+			<30  73>,
+			<31  74>,
+			<32  75>,
+			<33  77>,
+			<34  79>,
+			<35  80>,
+			<36  82>,
+			<37  86>,
+			<38  92>,
+			<39  93>,
+			<40  95>;
+	};
+
+	qcom,pc-cntr@fe805664 {
+		compatible = "qcom,pc-cntr";
+		reg = <0xfe805664 0x40>;
+	};
+
+	qcom,pm-8x60 {
+		compatible = "qcom,pm-8x60";
+		qcom,pc-mode = <0>; /*MSM_PC_TZ_L2_INT */
+		qcom,use-sync-timer;
+	};
+
+	qcom,rpm-stats@0xfc19dbd0{
+		compatible = "qcom,rpm-stats";
+		reg = <0xfc19dbd0 0x1000>;
+		reg-names = "phys_addr_base";
+		qcom,sleep-stats-version = <2>;
+	};
+};
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index b80a1c5..ffc9394 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -14,6 +14,7 @@
 /include/ "msm-iommu-v1.dtsi"
 /include/ "msm8610-ion.dtsi"
 /include/ "msm-gdsc.dtsi"
+/include/ "msm8610-pm.dtsi"
 
 / {
 	model = "Qualcomm MSM 8610";
@@ -220,6 +221,13 @@
 		};
 	};
 
+	rpm_bus: qcom,rpm-smd {
+		compatible = "qcom,rpm-smd";
+		rpm-channel-name = "rpm_requests";
+		rpm-channel-type = <15>; /* SMD_APPS_RPM */
+		rpm-standalone;
+	};
+
 	qcom,wdt@f9017000 {
 		compatible = "qcom,msm-watchdog";
 		reg = <0xf9017000 0x1000>;
diff --git a/arch/arm/boot/dts/msm8974-cdp.dtsi b/arch/arm/boot/dts/msm8974-cdp.dtsi
index 3b3402d..06bab30 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8974-cdp.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* 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
@@ -265,6 +265,15 @@
 	wp-gpios = <&pm8941_gpios 29 0x1>;
 };
 
+&uart7 {
+	status = "ok";
+};
+
+&ehci {
+	status = "ok";
+	vbus-supply = <&usb2_otg_sw>;
+};
+
 &usb3 {
 	qcom,otg-capability;
 };
diff --git a/arch/arm/boot/dts/msm8974-coresight.dtsi b/arch/arm/boot/dts/msm8974-coresight.dtsi
index ee3df10..6bb7b28 100644
--- a/arch/arm/boot/dts/msm8974-coresight.dtsi
+++ b/arch/arm/boot/dts/msm8974-coresight.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* 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
@@ -190,5 +190,7 @@
 		coresight-id = <14>;
 		coresight-name = "coresight-csr";
 		coresight-nr-inports = <0>;
+
+		qcom,blk-size = <3>;
 	};
 };
diff --git a/arch/arm/boot/dts/msm8974-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index d8e15b8..7e1f438 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.dtsi
@@ -195,6 +195,12 @@
 	};
 };
 
+&slim_msm {
+	taiko_codec {
+		qcom,cdc-micbias2-ext-cap;
+	};
+};
+
 &spmi_bus {
 	qcom,pm8941@1 {
 		qcom,leds@d800 {
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index 7368788..f0f79b0 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -26,6 +26,8 @@
 		battery@b {
 			compatible = "ti,bq28400-battery";
 			reg = <0xb>;
+			ti,temp-cold = <2>; /* degree celsius */
+			ti,temp-hot = <43>; /* degree celsius */
 		};
 
 		charger@2b {
diff --git a/arch/arm/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index c295353..dc52fda6 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* 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
@@ -257,6 +257,10 @@
 	qcom,hsusb-otg-otg-control = <2>;
 };
 
+&uart7 {
+	status = "ok";
+};
+
 &usb3 {
 	qcom,otg-capability;
 };
diff --git a/arch/arm/boot/dts/msm8974-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index 9b8e506..c6c5452 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -426,49 +426,61 @@
 	krait0_vreg: regulator@f9088000 {
 		compatible = "qcom,krait-regulator";
 		regulator-name = "krait0";
-		reg = <0xf9088000 0x1000>;
+		reg = <0xf9088000 0x1000>, /* APCS_ALIAS0_KPSS_ACS */
+			<0xf908a800 0x1000>; /* APCS_ALIAS0_KPSS_MDD */
+		reg-names = "acs", "mdd";
 		regulator-min-microvolt = <500000>;
 		regulator-max-microvolt = <1100000>;
 		qcom,headroom-voltage = <150000>;
-		qcom,retention-voltage = <745000>;
-		qcom,ldo-default-voltage = <745000>;
-		qcom,ldo-threshold-voltage = <750000>;
+		qcom,retention-voltage = <675000>;
+		qcom,ldo-default-voltage = <750000>;
+		qcom,ldo-threshold-voltage = <850000>;
+		qcom,ldo-delta-voltage = <50000>;
 	};
 
 	krait1_vreg: regulator@f9098000 {
 		compatible = "qcom,krait-regulator";
 		regulator-name = "krait1";
-		reg = <0xf9098000 0x1000>;
+		reg = <0xf9098000 0x1000>, /* APCS_ALIAS1_KPSS_ACS */
+			<0xf909a800 0x1000>; /* APCS_ALIAS1_KPSS_MDD */
+		reg-names = "acs", "mdd";
 		regulator-min-microvolt = <500000>;
 		regulator-max-microvolt = <1100000>;
 		qcom,headroom-voltage = <150000>;
-		qcom,retention-voltage = <745000>;
-		qcom,ldo-default-voltage = <745000>;
-		qcom,ldo-threshold-voltage = <750000>;
+		qcom,retention-voltage = <675000>;
+		qcom,ldo-default-voltage = <750000>;
+		qcom,ldo-threshold-voltage = <850000>;
+		qcom,ldo-delta-voltage = <50000>;
 	};
 
 	krait2_vreg: regulator@f90a8000 {
 		compatible = "qcom,krait-regulator";
 		regulator-name = "krait2";
-		reg = <0xf90a8000 0x1000>;
+		reg = <0xf90a8000 0x1000>, /* APCS_ALIAS2_KPSS_ACS */
+			<0xf90aa800 0x1000>; /* APCS_ALIAS2_KPSS_MDD */
+		reg-names = "acs", "mdd";
 		regulator-min-microvolt = <500000>;
 		regulator-max-microvolt = <1100000>;
 		qcom,headroom-voltage = <150000>;
-		qcom,retention-voltage = <745000>;
-		qcom,ldo-default-voltage = <745000>;
-		qcom,ldo-threshold-voltage = <750000>;
+		qcom,retention-voltage = <675000>;
+		qcom,ldo-default-voltage = <750000>;
+		qcom,ldo-threshold-voltage = <850000>;
+		qcom,ldo-delta-voltage = <50000>;
 	};
 
 	krait3_vreg: regulator@f90b8000 {
 		compatible = "qcom,krait-regulator";
 		regulator-name = "krait3";
-		reg = <0xf90b8000 0x1000>;
+		reg = <0xf90b8000 0x1000>, /* APCS_ALIAS3_KPSS_ACS */
+			<0xf90ba800 0x1000>; /* APCS_ALIAS3_KPSS_MDD */
+		reg-names = "acs", "mdd";
 		regulator-min-microvolt = <500000>;
 		regulator-max-microvolt = <1100000>;
 		qcom,headroom-voltage = <150000>;
-		qcom,retention-voltage = <745000>;
-		qcom,ldo-default-voltage = <745000>;
-		qcom,ldo-threshold-voltage = <750000>;
+		qcom,retention-voltage = <675000>;
+		qcom,ldo-default-voltage = <750000>;
+		qcom,ldo-threshold-voltage = <850000>;
+		qcom,ldo-delta-voltage = <50000>;
 	};
 
 	spi_eth_vreg: spi_eth_phy_vreg {
diff --git a/arch/arm/boot/dts/msm8974-cdp.dts b/arch/arm/boot/dts/msm8974-v1-cdp.dts
similarity index 86%
rename from arch/arm/boot/dts/msm8974-cdp.dts
rename to arch/arm/boot/dts/msm8974-v1-cdp.dts
index b8b3141..15ff424 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dts
+++ b/arch/arm/boot/dts/msm8974-v1-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -12,7 +12,7 @@
 
 /dts-v1/;
 
-/include/ "msm8974.dtsi"
+/include/ "msm8974-v1.dtsi"
 /include/ "msm8974-cdp.dtsi"
 
 / {
diff --git a/arch/arm/boot/dts/msm8974-fluid.dts b/arch/arm/boot/dts/msm8974-v1-fluid.dts
similarity index 86%
rename from arch/arm/boot/dts/msm8974-fluid.dts
rename to arch/arm/boot/dts/msm8974-v1-fluid.dts
index b014e14..0b435a3 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dts
+++ b/arch/arm/boot/dts/msm8974-v1-fluid.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* 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
@@ -12,7 +12,7 @@
 
 /dts-v1/;
 
-/include/ "msm8974.dtsi"
+/include/ "msm8974-v1.dtsi"
 /include/ "msm8974-fluid.dtsi"
 
 / {
diff --git a/arch/arm/boot/dts/msm8974-liquid.dts b/arch/arm/boot/dts/msm8974-v1-liquid.dts
similarity index 86%
rename from arch/arm/boot/dts/msm8974-liquid.dts
rename to arch/arm/boot/dts/msm8974-v1-liquid.dts
index ef38036..5c12569 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dts
+++ b/arch/arm/boot/dts/msm8974-v1-liquid.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* 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
@@ -12,7 +12,7 @@
 
 /dts-v1/;
 
-/include/ "msm8974.dtsi"
+/include/ "msm8974-v1.dtsi"
 /include/ "msm8974-liquid.dtsi"
 
 / {
diff --git a/arch/arm/boot/dts/msm8974-mtp.dts b/arch/arm/boot/dts/msm8974-v1-mtp.dts
similarity index 86%
rename from arch/arm/boot/dts/msm8974-mtp.dts
rename to arch/arm/boot/dts/msm8974-v1-mtp.dts
index 9946cf0..01e9fe2 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dts
+++ b/arch/arm/boot/dts/msm8974-v1-mtp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* 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
@@ -12,7 +12,7 @@
 
 /dts-v1/;
 
-/include/ "msm8974.dtsi"
+/include/ "msm8974-v1.dtsi"
 /include/ "msm8974-mtp.dtsi"
 
 / {
diff --git a/arch/arm/boot/dts/msm8974-rumi.dts b/arch/arm/boot/dts/msm8974-v1-rumi.dts
similarity index 86%
rename from arch/arm/boot/dts/msm8974-rumi.dts
rename to arch/arm/boot/dts/msm8974-v1-rumi.dts
index 738ff86..ebb37b7 100644
--- a/arch/arm/boot/dts/msm8974-rumi.dts
+++ b/arch/arm/boot/dts/msm8974-v1-rumi.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -12,7 +12,7 @@
 
 /dts-v1/;
 
-/include/ "msm8974.dtsi"
+/include/ "msm8974-v1.dtsi"
 /include/ "msm8974-rumi.dtsi"
 
 / {
diff --git a/arch/arm/boot/dts/msm8974-sim.dts b/arch/arm/boot/dts/msm8974-v1-sim.dts
similarity index 86%
rename from arch/arm/boot/dts/msm8974-sim.dts
rename to arch/arm/boot/dts/msm8974-v1-sim.dts
index 09ea419..29add5d 100644
--- a/arch/arm/boot/dts/msm8974-sim.dts
+++ b/arch/arm/boot/dts/msm8974-v1-sim.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -12,7 +12,7 @@
 
 /dts-v1/;
 
-/include/ "msm8974.dtsi"
+/include/ "msm8974-v1.dtsi"
 /include/ "msm8974-sim.dtsi"
 
 / {
diff --git a/arch/arm/boot/dts/msm8974-fluid.dts b/arch/arm/boot/dts/msm8974-v1.dtsi
similarity index 66%
copy from arch/arm/boot/dts/msm8974-fluid.dts
copy to arch/arm/boot/dts/msm8974-v1.dtsi
index b014e14..6f91ee8 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dts
+++ b/arch/arm/boot/dts/msm8974-v1.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* 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
@@ -10,13 +10,10 @@
  * GNU General Public License for more details.
  */
 
-/dts-v1/;
+/*
+ * As a general rule, only version-specific property overrides should be placed
+ * inside this file. However, device definitions should be placed inside the
+ * msm8974.dtsi file.
+ */
 
 /include/ "msm8974.dtsi"
-/include/ "msm8974-fluid.dtsi"
-
-/ {
-	model = "Qualcomm MSM 8974 FLUID";
-	compatible = "qcom,msm8974-fluid", "qcom,msm8974";
-	qcom,msm-id = <126 3 0>;
-};
diff --git a/arch/arm/boot/dts/msm8974-cdp.dts b/arch/arm/boot/dts/msm8974-v2-cdp.dts
similarity index 77%
copy from arch/arm/boot/dts/msm8974-cdp.dts
copy to arch/arm/boot/dts/msm8974-v2-cdp.dts
index b8b3141..58e172f 100644
--- a/arch/arm/boot/dts/msm8974-cdp.dts
+++ b/arch/arm/boot/dts/msm8974-v2-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -12,11 +12,11 @@
 
 /dts-v1/;
 
-/include/ "msm8974.dtsi"
+/include/ "msm8974-v2.dtsi"
 /include/ "msm8974-cdp.dtsi"
 
 / {
-	model = "Qualcomm MSM 8974 CDP";
+	model = "Qualcomm MSM 8974v2 CDP";
 	compatible = "qcom,msm8974-cdp", "qcom,msm8974";
-	qcom,msm-id = <126 1 0>;
+	qcom,msm-id = <126 1 0x20000>;
 };
diff --git a/arch/arm/boot/dts/msm8974-fluid.dts b/arch/arm/boot/dts/msm8974-v2-fluid.dts
similarity index 77%
copy from arch/arm/boot/dts/msm8974-fluid.dts
copy to arch/arm/boot/dts/msm8974-v2-fluid.dts
index b014e14..5759b56 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dts
+++ b/arch/arm/boot/dts/msm8974-v2-fluid.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* 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
@@ -12,11 +12,11 @@
 
 /dts-v1/;
 
-/include/ "msm8974.dtsi"
+/include/ "msm8974-v2.dtsi"
 /include/ "msm8974-fluid.dtsi"
 
 / {
-	model = "Qualcomm MSM 8974 FLUID";
+	model = "Qualcomm MSM 8974v2 FLUID";
 	compatible = "qcom,msm8974-fluid", "qcom,msm8974";
-	qcom,msm-id = <126 3 0>;
+	qcom,msm-id = <126 3 0x20000>;
 };
diff --git a/arch/arm/boot/dts/msm8974-liquid.dts b/arch/arm/boot/dts/msm8974-v2-liquid.dts
similarity index 77%
copy from arch/arm/boot/dts/msm8974-liquid.dts
copy to arch/arm/boot/dts/msm8974-v2-liquid.dts
index ef38036..6812f60 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dts
+++ b/arch/arm/boot/dts/msm8974-v2-liquid.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* 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
@@ -12,11 +12,11 @@
 
 /dts-v1/;
 
-/include/ "msm8974.dtsi"
+/include/ "msm8974-v2.dtsi"
 /include/ "msm8974-liquid.dtsi"
 
 / {
-	model = "Qualcomm MSM 8974 LIQUID";
+	model = "Qualcomm MSM 8974v2 LIQUID";
 	compatible = "qcom,msm8974-liquid", "qcom,msm8974";
-	qcom,msm-id = <126 9 0>;
+	qcom,msm-id = <126 9 0x20000>;
 };
diff --git a/arch/arm/boot/dts/msm8974-mtp.dts b/arch/arm/boot/dts/msm8974-v2-mtp.dts
similarity index 77%
copy from arch/arm/boot/dts/msm8974-mtp.dts
copy to arch/arm/boot/dts/msm8974-v2-mtp.dts
index 9946cf0..b29d4ca 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dts
+++ b/arch/arm/boot/dts/msm8974-v2-mtp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* 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
@@ -12,11 +12,11 @@
 
 /dts-v1/;
 
-/include/ "msm8974.dtsi"
+/include/ "msm8974-v2.dtsi"
 /include/ "msm8974-mtp.dtsi"
 
 / {
-	model = "Qualcomm MSM 8974 MTP";
+	model = "Qualcomm MSM 8974v2 MTP";
 	compatible = "qcom,msm8974-mtp", "qcom,msm8974";
-	qcom,msm-id = <126 8 0>;
+	qcom,msm-id = <126 8 0x20000>;
 };
diff --git a/arch/arm/boot/dts/msm8974-fluid.dts b/arch/arm/boot/dts/msm8974-v2.dtsi
similarity index 66%
copy from arch/arm/boot/dts/msm8974-fluid.dts
copy to arch/arm/boot/dts/msm8974-v2.dtsi
index b014e14..6f91ee8 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dts
+++ b/arch/arm/boot/dts/msm8974-v2.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* 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
@@ -10,13 +10,10 @@
  * GNU General Public License for more details.
  */
 
-/dts-v1/;
+/*
+ * As a general rule, only version-specific property overrides should be placed
+ * inside this file. However, device definitions should be placed inside the
+ * msm8974.dtsi file.
+ */
 
 /include/ "msm8974.dtsi"
-/include/ "msm8974-fluid.dtsi"
-
-/ {
-	model = "Qualcomm MSM 8974 FLUID";
-	compatible = "qcom,msm8974-fluid", "qcom,msm8974";
-	qcom,msm-id = <126 3 0>;
-};
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index ac869f2..1072e7e 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -672,6 +672,19 @@
 				<61 512 240000 960000>;
 	};
 
+	ehci: qcom,ehci-host@f9a55000 {
+		compatible = "qcom,ehci-host";
+		status = "disabled";
+		reg = <0xf9a55000 0x400>;
+		interrupts = <0 134 0>, <0 140 0>;
+		interrupt-names = "core_irq", "async_irq";
+		HSUSB_VDDCX-supply = <&pm8841_s2>;
+		HSUSB_1p8-supply = <&pm8941_l6>;
+		HSUSB_3p3-supply = <&pm8941_l24>;
+		qcom,usb2-enable-hsphy2;
+		qcom,usb2-power-budget = <500>;
+	};
+
 	gdsc_oxili_gx: qcom,gdsc@fd8c4024 {
 		parent-supply = <&pm8841_s4_corner>;
 	};
@@ -1102,6 +1115,7 @@
 		qcom,usb-bam-num-pipes = <16>;
 		qcom,usb-base-address = <0xf9200000>;
 		qcom,ignore-core-reset-ack;
+		qcom,disable-clk-gating;
 
 		qcom,pipe1 {
 			label = "usb-to-peri-qdss-dwc3";
@@ -1185,6 +1199,20 @@
                 qcom,memblock-remove = <0x7f00000 0x8000000>; /* Address and Size of Hole */
         };
 
+	uart7: uart@f995d000 { /*BLSP #2, UART #7 */
+		cell-index = <0>;
+		compatible = "qcom,msm-hsuart-v14";
+		status = "disabled";
+		reg = <0xf995d000 0x1000>,
+			<0xf9944000 0x5000>;
+		reg-names = "core_mem", "bam_mem";
+		interrupts = <0 113 0>, <0 239 0>;
+		interrupt-names = "core_irq", "bam_irq";
+
+		qcom,bam-tx-ep-pipe-index = <0>;
+		qcom,bam-rx-ep-pipe-index = <1>;
+	};
+
 	qcom,smem@fa00000 {
 		compatible = "qcom,smem";
 		reg = <0xfa00000 0x200000>,
diff --git a/arch/arm/boot/dts/msm9625-coresight.dtsi b/arch/arm/boot/dts/msm9625-coresight.dtsi
index 9a49c32..f352c3f 100644
--- a/arch/arm/boot/dts/msm9625-coresight.dtsi
+++ b/arch/arm/boot/dts/msm9625-coresight.dtsi
@@ -126,5 +126,7 @@
 		coresight-id = <9>;
 		coresight-name = "coresight-csr";
 		coresight-nr-inports = <0>;
+
+		qcom,blk-size = <1>;
 	};
 };
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 7e32126..c2ed824 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -111,6 +111,7 @@
 		qcom,usb-total-bam-num = <3>;
 		qcom,usb-bam-num-pipes = <16>;
 		qcom,ignore-core-reset-ack;
+		qcom,disable-clk-gating;
 
 		qcom,pipe0 {
 			label = "usb-to-ipa";
@@ -608,6 +609,12 @@
 			<0xfc330000 0x1000>;
 		reg-names = "etm-base","debug-base";
 	};
+
+	qcom,msm-rtb {
+		compatible = "qcom,msm-rtb";
+		qcom,memory-reservation-type = "EBI1";
+		qcom,memory-reservation-size = <0x1000>; /* 4K EBI1 buffer */
+	};
 };
 
 /include/ "msm-pm8019-rpm-regulator.dtsi"
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index fda9074..ecf1c68 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -217,6 +217,9 @@
 CONFIG_USB_GADGET=y
 CONFIG_USB_CI13XXX_MSM=y
 CONFIG_USB_G_ANDROID=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MSM_HSIC=y
 CONFIG_MMC=y
 CONFIG_MMC_PERF_PROFILING=y
 CONFIG_MMC_UNSAFE_RESUME=y
@@ -302,3 +305,4 @@
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
 CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_MSM_RTB=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index baaa09d..6fb791b 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -951,6 +951,15 @@
 	help
 	  Support for the Qualcomm APQ8064 CDP device.
 
+config MACH_FSM8064_EP
+	depends on ARCH_APQ8064
+	bool "FSM8064 EP"
+	help
+	  Support for the Qualcomm FSM8064 EP device.
+	  This board also known as Femto development platform (FDP)
+	  is based on APQ8064 chipset. This board does not support
+	  keyboard, display or multimedia.
+
 config MACH_APQ8064_MTP
 	depends on ARCH_APQ8064
 	bool "APQ8064 MTP"
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
index 377c4af..e04a9a0 100644
--- a/arch/arm/mach-msm/Makefile.boot
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -47,12 +47,16 @@
 
 # MSM8974
    zreladdr-$(CONFIG_ARCH_MSM8974)	:= 0x00008000
-        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-cdp.dtb
-        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-fluid.dtb
-        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-liquid.dtb
-        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-mtp.dtb
-        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-rumi.dtb
-        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-sim.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v1-cdp.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v1-fluid.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v1-liquid.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v1-mtp.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v1-rumi.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v1-sim.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v2-cdp.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v2-fluid.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v2-liquid.dtb
+        dtb-$(CONFIG_ARCH_MSM8974)	+= msm8974-v2-mtp.dtb
 
 # MSM9615
    zreladdr-$(CONFIG_ARCH_MSM9615)	:= 0x40808000
diff --git a/arch/arm/mach-msm/acpuclock-8064.c b/arch/arm/mach-msm/acpuclock-8064.c
index 359a156..a0727b7 100644
--- a/arch/arm/mach-msm/acpuclock-8064.c
+++ b/arch/arm/mach-msm/acpuclock-8064.c
@@ -650,6 +650,7 @@
 	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
 	.bus_scale = &bus_scale_data,
 	.pte_efuse_phys = 0x007000C0,
+	.get_bin_info = get_krait_bin_format_a,
 	.stby_khz = 384000,
 };
 
diff --git a/arch/arm/mach-msm/acpuclock-8627.c b/arch/arm/mach-msm/acpuclock-8627.c
index ac29cac..405b26b 100644
--- a/arch/arm/mach-msm/acpuclock-8627.c
+++ b/arch/arm/mach-msm/acpuclock-8627.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. 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
@@ -142,6 +142,7 @@
 	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
 	.bus_scale = &bus_scale_data,
 	.pte_efuse_phys = 0x007000C0,
+	.get_bin_info = get_krait_bin_format_a,
 	.stby_khz = 384000,
 };
 
diff --git a/arch/arm/mach-msm/acpuclock-8930.c b/arch/arm/mach-msm/acpuclock-8930.c
index 40326cb..6915343 100644
--- a/arch/arm/mach-msm/acpuclock-8930.c
+++ b/arch/arm/mach-msm/acpuclock-8930.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. 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
@@ -227,6 +227,7 @@
 	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
 	.bus_scale = &bus_scale_data,
 	.pte_efuse_phys = 0x007000C0,
+	.get_bin_info = get_krait_bin_format_a,
 	.stby_khz = 384000,
 };
 
diff --git a/arch/arm/mach-msm/acpuclock-8930aa.c b/arch/arm/mach-msm/acpuclock-8930aa.c
index 7d1ce09..9aebac9 100644
--- a/arch/arm/mach-msm/acpuclock-8930aa.c
+++ b/arch/arm/mach-msm/acpuclock-8930aa.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. 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
@@ -203,6 +203,7 @@
 	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
 	.bus_scale = &bus_scale_data,
 	.pte_efuse_phys = 0x007000C0,
+	.get_bin_info = get_krait_bin_format_a,
 	.stby_khz = 384000,
 };
 
diff --git a/arch/arm/mach-msm/acpuclock-8930ab.c b/arch/arm/mach-msm/acpuclock-8930ab.c
index 5003862..bddac00 100644
--- a/arch/arm/mach-msm/acpuclock-8930ab.c
+++ b/arch/arm/mach-msm/acpuclock-8930ab.c
@@ -1,5 +1,5 @@
 /*
- * 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
@@ -257,6 +257,7 @@
 	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
 	.bus_scale = &bus_scale_data,
 	.pte_efuse_phys = 0x007000C0,
+	.get_bin_info = get_krait_bin_format_a,
 	.stby_khz = 384000,
 };
 
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index d7d3edd..317729f 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. 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
@@ -210,6 +210,7 @@
 	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
 	.bus_scale = &bus_scale_data,
 	.pte_efuse_phys = 0x007000C0,
+	.get_bin_info = get_krait_bin_format_a,
 	.stby_khz = 384000,
 };
 
diff --git a/arch/arm/mach-msm/acpuclock-8960ab.c b/arch/arm/mach-msm/acpuclock-8960ab.c
index d2e88fb..38658a2 100644
--- a/arch/arm/mach-msm/acpuclock-8960ab.c
+++ b/arch/arm/mach-msm/acpuclock-8960ab.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. 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
@@ -252,6 +252,7 @@
 	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
 	.bus_scale = &bus_scale_data,
 	.pte_efuse_phys = 0x007000C0,
+	.get_bin_info = get_krait_bin_format_a,
 	.stby_khz = 384000,
 };
 
diff --git a/arch/arm/mach-msm/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
index 94a4d3e..8eb4b28 100644
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ b/arch/arm/mach-msm/acpuclock-8974.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ * 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
@@ -112,14 +112,14 @@
 };
 
 static struct l2_level l2_freq_tbl[] __initdata = {
-	[0]  = { {  300000, PLL_0, 0,   0 }, LVL_LOW,  1050000, 0 },
-	[1]  = { {  345600, HFPLL, 2,  36 }, LVL_NOM,  1050000, 1 },
-	[2]  = { {  422400, HFPLL, 2,  44 }, LVL_NOM,  1050000, 1 },
-	[3]  = { {  499200, HFPLL, 2,  52 }, LVL_NOM,  1050000, 2 },
-	[4]  = { {  576000, HFPLL, 1,  30 }, LVL_NOM,  1050000, 2 },
-	[5]  = { {  652800, HFPLL, 1,  34 }, LVL_NOM,  1050000, 3 },
-	[6]  = { {  729600, HFPLL, 1,  38 }, LVL_NOM,  1050000, 3 },
-	[7]  = { {  806400, HFPLL, 1,  42 }, LVL_NOM,  1050000, 3 },
+	[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, 2 },
+	[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, 3 },
 	[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, 4 },
@@ -129,50 +129,135 @@
 	[14] = { { 1344000, HFPLL, 1,  70 }, LVL_HIGH, 1050000, 6 },
 	[15] = { { 1420800, HFPLL, 1,  74 }, LVL_HIGH, 1050000, 7 },
 	[16] = { { 1497600, HFPLL, 1,  78 }, LVL_HIGH, 1050000, 7 },
-	[17] = { { 1574400, HFPLL, 1,  82 }, LVL_HIGH, 1050000, 7 },
-	[18] = { { 1651200, HFPLL, 1,  86 }, LVL_HIGH, 1050000, 7 },
-	[19] = { { 1728000, HFPLL, 1,  90 }, LVL_HIGH, 1050000, 7 },
-	[20] = { { 1804800, HFPLL, 1,  94 }, LVL_HIGH, 1050000, 7 },
-	[21] = { { 1881600, HFPLL, 1,  98 }, LVL_HIGH, 1050000, 7 },
-	[22] = { { 1958400, HFPLL, 1, 102 }, LVL_HIGH, 1050000, 7 },
-	[23] = { { 2035200, HFPLL, 1, 106 }, LVL_HIGH, 1050000, 7 },
-	[24] = { { 2112000, HFPLL, 1, 110 }, LVL_HIGH, 1050000, 7 },
-	[25] = { { 2188800, HFPLL, 1, 114 }, LVL_HIGH, 1050000, 7 },
 	{ }
 };
 
-static struct acpu_level acpu_freq_tbl[] __initdata = {
-	{ 1, {  300000, PLL_0, 0,   0 }, L2(0),   850000,  400000 },
-	{ 0, {  345600, HFPLL, 2,  36 }, L2(0),   850000, 3200000 },
-	{ 1, {  422400, HFPLL, 2,  44 }, L2(0),   850000, 3200000 },
-	{ 0, {  499200, HFPLL, 2,  52 }, L2(0),   850000, 3200000 },
-	{ 1, {  576000, HFPLL, 1,  30 }, L2(0),   850000, 3200000 },
-	{ 1, {  652800, HFPLL, 1,  34 }, L2(16),  850000, 3200000 },
-	{ 0, {  729600, HFPLL, 1,  38 }, L2(16),  850000, 3200000 },
-	{ 1, {  806400, HFPLL, 1,  42 }, L2(16),  850000, 3200000 },
-	{ 1, {  883200, HFPLL, 1,  46 }, L2(16),  870000, 3200000 },
-	{ 1, {  960000, HFPLL, 1,  50 }, L2(16),  880000, 3200000 },
-	{ 1, { 1036800, HFPLL, 1,  54 }, L2(16),  900000, 3200000 },
-	{ 1, { 1113600, HFPLL, 1,  58 }, L2(16),  915000, 3200000 },
-	{ 1, { 1190400, HFPLL, 1,  62 }, L2(16),  935000, 3200000 },
-	{ 1, { 1267200, HFPLL, 1,  66 }, L2(16),  950000, 3200000 },
-	{ 1, { 1344000, HFPLL, 1,  70 }, L2(16),  970000, 3200000 },
-	{ 1, { 1420800, HFPLL, 1,  74 }, L2(16),  985000, 3200000 },
-	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16), 1000000, 3200000 },
+static struct acpu_level acpu_freq_tbl_pvs0[] __initdata = {
+	{ 1, {  300000, PLL_0, 0,   0 }, L2(0),   825000,  400000 },
+	{ 0, {  345600, HFPLL, 2,  36 }, L2(3),   825000, 3200000 },
+	{ 1, {  422400, HFPLL, 2,  44 }, L2(3),   825000, 3200000 },
+	{ 0, {  499200, HFPLL, 2,  52 }, L2(6),   825000, 3200000 },
+	{ 1, {  576000, HFPLL, 1,  30 }, L2(6),   825000, 3200000 },
+	{ 1, {  652800, HFPLL, 1,  34 }, L2(6),   825000, 3200000 },
+	{ 0, {  729600, HFPLL, 1,  38 }, L2(6),   825000, 3200000 },
+	{ 1, {  806400, HFPLL, 1,  42 }, L2(8),   835000, 3200000 },
+	{ 1, {  883200, HFPLL, 1,  46 }, L2(8),   845000, 3200000 },
+	{ 1, {  960000, HFPLL, 1,  50 }, L2(8),   860000, 3200000 },
+	{ 1, { 1036800, HFPLL, 1,  54 }, L2(8),   880000, 3200000 },
+	{ 1, { 1113600, HFPLL, 1,  58 }, L2(12),  905000, 3200000 },
+	{ 1, { 1190400, HFPLL, 1,  62 }, L2(12),  920000, 3200000 },
+	{ 1, { 1267200, HFPLL, 1,  66 }, L2(12),  940000, 3200000 },
+	{ 1, { 1344000, HFPLL, 1,  70 }, L2(12),  960000, 3200000 },
+	{ 1, { 1420800, HFPLL, 1,  74 }, L2(16),  980000, 3200000 },
+	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  995000, 3200000 },
 	{ 1, { 1574400, HFPLL, 1,  82 }, L2(16), 1015000, 3200000 },
 	{ 1, { 1651200, HFPLL, 1,  86 }, L2(16), 1030000, 3200000 },
 	{ 1, { 1728000, HFPLL, 1,  90 }, L2(16), 1050000, 3200000 },
-	{ 0, { 1804800, HFPLL, 1,  94 }, L2(16), 1050000, 3200000 },
-	{ 0, { 1881600, HFPLL, 1,  98 }, L2(16), 1050000, 3200000 },
-	{ 0, { 1958400, HFPLL, 1, 102 }, L2(16), 1050000, 3200000 },
-	{ 0, { 1996800, HFPLL, 1, 104 }, L2(16), 1050000, 3200000 },
 	{ 0, { 0 } }
 };
 
-static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS]  __initdata = {
-	[0][PVS_SLOW]    = { acpu_freq_tbl, sizeof(acpu_freq_tbl) },
-	[0][PVS_NOMINAL] = { acpu_freq_tbl, sizeof(acpu_freq_tbl) },
-	[0][PVS_FAST]    = { acpu_freq_tbl, sizeof(acpu_freq_tbl) },
+static struct acpu_level acpu_freq_tbl_pvs1[] __initdata = {
+	{ 1, {  300000, PLL_0, 0,   0 }, L2(0),   825000,  400000 },
+	{ 0, {  345600, HFPLL, 2,  36 }, L2(3),   825000, 3200000 },
+	{ 1, {  422400, HFPLL, 2,  44 }, L2(3),   825000, 3200000 },
+	{ 0, {  499200, HFPLL, 2,  52 }, L2(6),   825000, 3200000 },
+	{ 1, {  576000, HFPLL, 1,  30 }, L2(6),   825000, 3200000 },
+	{ 1, {  652800, HFPLL, 1,  34 }, L2(6),   825000, 3200000 },
+	{ 0, {  729600, HFPLL, 1,  38 }, L2(6),   825000, 3200000 },
+	{ 1, {  806400, HFPLL, 1,  42 }, L2(8),   835000, 3200000 },
+	{ 1, {  883200, HFPLL, 1,  46 }, L2(8),   845000, 3200000 },
+	{ 1, {  960000, HFPLL, 1,  50 }, L2(8),   860000, 3200000 },
+	{ 1, { 1036800, HFPLL, 1,  54 }, L2(8),   880000, 3200000 },
+	{ 1, { 1113600, HFPLL, 1,  58 }, L2(12),  905000, 3200000 },
+	{ 1, { 1190400, HFPLL, 1,  62 }, L2(12),  920000, 3200000 },
+	{ 1, { 1267200, HFPLL, 1,  66 }, L2(12),  940000, 3200000 },
+	{ 1, { 1344000, HFPLL, 1,  70 }, L2(12),  960000, 3200000 },
+	{ 1, { 1420800, HFPLL, 1,  74 }, L2(16),  980000, 3200000 },
+	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  995000, 3200000 },
+	{ 1, { 1574400, HFPLL, 1,  82 }, L2(16), 1015000, 3200000 },
+	{ 1, { 1651200, HFPLL, 1,  86 }, L2(16), 1030000, 3200000 },
+	{ 1, { 1728000, HFPLL, 1,  90 }, L2(16), 1050000, 3200000 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level acpu_freq_tbl_pvs2[] __initdata = {
+	{ 1, {  300000, PLL_0, 0,   0 }, L2(0),   825000,  400000 },
+	{ 0, {  345600, HFPLL, 2,  36 }, L2(3),   825000, 3200000 },
+	{ 1, {  422400, HFPLL, 2,  44 }, L2(3),   825000, 3200000 },
+	{ 0, {  499200, HFPLL, 2,  52 }, L2(6),   825000, 3200000 },
+	{ 1, {  576000, HFPLL, 1,  30 }, L2(6),   825000, 3200000 },
+	{ 1, {  652800, HFPLL, 1,  34 }, L2(6),   825000, 3200000 },
+	{ 0, {  729600, HFPLL, 1,  38 }, L2(6),   825000, 3200000 },
+	{ 1, {  806400, HFPLL, 1,  42 }, L2(8),   825000, 3200000 },
+	{ 1, {  883200, HFPLL, 1,  46 }, L2(8),   825000, 3200000 },
+	{ 1, {  960000, HFPLL, 1,  50 }, L2(8),   835000, 3200000 },
+	{ 1, { 1036800, HFPLL, 1,  54 }, L2(8),   855000, 3200000 },
+	{ 1, { 1113600, HFPLL, 1,  58 }, L2(12),  875000, 3200000 },
+	{ 1, { 1190400, HFPLL, 1,  62 }, L2(12),  895000, 3200000 },
+	{ 1, { 1267200, HFPLL, 1,  66 }, L2(12),  915000, 3200000 },
+	{ 1, { 1344000, HFPLL, 1,  70 }, L2(12),  930000, 3200000 },
+	{ 1, { 1420800, HFPLL, 1,  74 }, L2(16),  945000, 3200000 },
+	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  960000, 3200000 },
+	{ 1, { 1574400, HFPLL, 1,  82 }, L2(16),  975000, 3200000 },
+	{ 1, { 1651200, HFPLL, 1,  86 }, L2(16),  990000, 3200000 },
+	{ 1, { 1728000, HFPLL, 1,  90 }, L2(16), 1000000, 3200000 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level acpu_freq_tbl_pvs3[] __initdata = {
+	{ 1, {  300000, PLL_0, 0,   0 }, L2(0),   825000,  400000 },
+	{ 0, {  345600, HFPLL, 2,  36 }, L2(3),   825000, 3200000 },
+	{ 1, {  422400, HFPLL, 2,  44 }, L2(3),   825000, 3200000 },
+	{ 0, {  499200, HFPLL, 2,  52 }, L2(6),   825000, 3200000 },
+	{ 1, {  576000, HFPLL, 1,  30 }, L2(6),   825000, 3200000 },
+	{ 1, {  652800, HFPLL, 1,  34 }, L2(6),   825000, 3200000 },
+	{ 0, {  729600, HFPLL, 1,  38 }, L2(6),   825000, 3200000 },
+	{ 1, {  806400, HFPLL, 1,  42 }, L2(8),   825000, 3200000 },
+	{ 1, {  883200, HFPLL, 1,  46 }, L2(8),   825000, 3200000 },
+	{ 1, {  960000, HFPLL, 1,  50 }, L2(8),   835000, 3200000 },
+	{ 1, { 1036800, HFPLL, 1,  54 }, L2(8),   855000, 3200000 },
+	{ 1, { 1113600, HFPLL, 1,  58 }, L2(12),  875000, 3200000 },
+	{ 1, { 1190400, HFPLL, 1,  62 }, L2(12),  895000, 3200000 },
+	{ 1, { 1267200, HFPLL, 1,  66 }, L2(12),  915000, 3200000 },
+	{ 1, { 1344000, HFPLL, 1,  70 }, L2(12),  930000, 3200000 },
+	{ 1, { 1420800, HFPLL, 1,  74 }, L2(16),  945000, 3200000 },
+	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16),  960000, 3200000 },
+	{ 1, { 1574400, HFPLL, 1,  82 }, L2(16),  975000, 3200000 },
+	{ 1, { 1651200, HFPLL, 1,  86 }, L2(16),  990000, 3200000 },
+	{ 1, { 1728000, HFPLL, 1,  90 }, L2(16), 1000000, 3200000 },
+	{ 0, { 0 } }
+};
+
+static struct acpu_level acpu_freq_tbl_pvs4[] __initdata = {
+	{ 1, {  300000, PLL_0, 0,   0 }, L2(0),  825000,  400000 },
+	{ 0, {  345600, HFPLL, 2,  36 }, L2(3),  825000, 3200000 },
+	{ 1, {  422400, HFPLL, 2,  44 }, L2(3),  825000, 3200000 },
+	{ 0, {  499200, HFPLL, 2,  52 }, L2(6),  825000, 3200000 },
+	{ 1, {  576000, HFPLL, 1,  30 }, L2(6),  825000, 3200000 },
+	{ 1, {  652800, HFPLL, 1,  34 }, L2(6),  825000, 3200000 },
+	{ 0, {  729600, HFPLL, 1,  38 }, L2(6),  825000, 3200000 },
+	{ 1, {  806400, HFPLL, 1,  42 }, L2(8),  825000, 3200000 },
+	{ 1, {  883200, HFPLL, 1,  46 }, L2(8),  825000, 3200000 },
+	{ 1, {  960000, HFPLL, 1,  50 }, L2(8),  825000, 3200000 },
+	{ 1, { 1036800, HFPLL, 1,  54 }, L2(8),  825000, 3200000 },
+	{ 1, { 1113600, HFPLL, 1,  58 }, L2(12), 835000, 3200000 },
+	{ 1, { 1190400, HFPLL, 1,  62 }, L2(12), 855000, 3200000 },
+	{ 1, { 1267200, HFPLL, 1,  66 }, L2(12), 870000, 3200000 },
+	{ 1, { 1344000, HFPLL, 1,  70 }, L2(12), 885000, 3200000 },
+	{ 1, { 1420800, HFPLL, 1,  74 }, L2(16), 900000, 3200000 },
+	{ 1, { 1497600, HFPLL, 1,  78 }, L2(16), 910000, 3200000 },
+	{ 1, { 1574400, HFPLL, 1,  82 }, L2(16), 925000, 3200000 },
+	{ 1, { 1651200, HFPLL, 1,  86 }, L2(16), 940000, 3200000 },
+	{ 1, { 1728000, HFPLL, 1,  90 }, L2(16), 950000, 3200000 },
+	{ 0, { 0 } }
+};
+
+static struct pvs_table pvs_tables[NUM_SPEED_BINS][NUM_PVS] __initdata = {
+	[0][0] = { acpu_freq_tbl_pvs0, sizeof(acpu_freq_tbl_pvs0) },
+	[0][1] = { acpu_freq_tbl_pvs1, sizeof(acpu_freq_tbl_pvs1) },
+	[0][2] = { acpu_freq_tbl_pvs2, sizeof(acpu_freq_tbl_pvs2) },
+	[0][3] = { acpu_freq_tbl_pvs3, sizeof(acpu_freq_tbl_pvs3) },
+	[0][4] = { acpu_freq_tbl_pvs4, sizeof(acpu_freq_tbl_pvs4) },
 };
 
 static struct acpuclk_krait_params acpuclk_8974_params __initdata = {
@@ -184,11 +269,41 @@
 	.l2_freq_tbl_size = sizeof(l2_freq_tbl),
 	.bus_scale = &bus_scale_data,
 	.pte_efuse_phys = 0xFC4B80B0,
+	.get_bin_info = get_krait_bin_format_b,
 	.stby_khz = 300000,
 };
 
+static void __init apply_l2_workaround(void)
+{
+	static struct l2_level resticted_l2_tbl[] __initdata = {
+		[0] = { {  300000, PLL_0, 0,   0 }, LVL_LOW,  1050000, 0 },
+		[1] = { { 1497600, HFPLL, 1,  78 }, LVL_HIGH, 1050000, 7 },
+		{ }
+	};
+	struct acpu_level *l;
+	int s, p;
+
+	for (s = 0; s < NUM_SPEED_BINS; s++)
+		for (p = 0; p < NUM_PVS; p++)
+			for (l = pvs_tables[s][p].table; l && l->speed.khz; l++)
+				l->l2_level = l->l2_level > 5 ? 1 : 0;
+
+	acpuclk_8974_params.l2_freq_tbl = resticted_l2_tbl;
+	acpuclk_8974_params.l2_freq_tbl_size = sizeof(resticted_l2_tbl);
+}
+
 static int __init acpuclk_8974_probe(struct platform_device *pdev)
 {
+	/*
+	 * 8974 hardware revisions older than v1.2 may experience L2 parity
+	 * errors when running at some performance points between 300MHz
+	 * and 1497.6MHz (non-inclusive), or when vdd_mx is less than 1.05V.
+	 * Restrict L2 operation to safe performance points on these devices.
+	 */
+	if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) < 2 &&
+	    SOCINFO_VERSION_MINOR(socinfo_get_version()) < 2)
+		apply_l2_workaround();
+
 	return acpuclk_krait_init(&pdev->dev, &acpuclk_8974_params);
 }
 
diff --git a/arch/arm/mach-msm/acpuclock-krait.c b/arch/arm/mach-msm/acpuclock-krait.c
index 10c4d6c..9566cea 100644
--- a/arch/arm/mach-msm/acpuclock-krait.c
+++ b/arch/arm/mach-msm/acpuclock-krait.c
@@ -1,5 +1,5 @@
 /*
- * 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
@@ -1019,7 +1019,7 @@
 	.notifier_call = acpuclk_cpu_callback,
 };
 
-static const int krait_needs_vmin(void)
+static const int __init krait_needs_vmin(void)
 {
 	switch (read_cpuid_id()) {
 	case 0x511F04D0: /* KR28M2A20 */
@@ -1031,7 +1031,7 @@
 	};
 }
 
-static void krait_apply_vmin(struct acpu_level *tbl)
+static void __init krait_apply_vmin(struct acpu_level *tbl)
 {
 	for (; tbl->speed.khz != 0; tbl++) {
 		if (tbl->vdd_core < 1150000)
@@ -1040,62 +1040,78 @@
 	}
 }
 
-static int __init get_speed_bin(u32 pte_efuse)
+void __init get_krait_bin_format_a(void __iomem *base, struct bin_info *bin)
 {
-	uint32_t speed_bin;
+	u32 pte_efuse = readl_relaxed(base);
 
-	speed_bin = pte_efuse & 0xF;
-	if (speed_bin == 0xF)
-		speed_bin = (pte_efuse >> 4) & 0xF;
+	bin->speed = pte_efuse & 0xF;
+	if (bin->speed == 0xF)
+		bin->speed = (pte_efuse >> 4) & 0xF;
+	bin->speed_valid = bin->speed != 0xF;
 
-	if (speed_bin == 0xF) {
-		speed_bin = 0;
-		dev_warn(drv.dev, "SPEED BIN: Defaulting to %d\n", speed_bin);
-	} else {
-		dev_info(drv.dev, "SPEED BIN: %d\n", speed_bin);
-	}
-
-	return speed_bin;
+	bin->pvs = (pte_efuse >> 10) & 0x7;
+	if (bin->pvs == 0x7)
+		bin->pvs = (pte_efuse >> 13) & 0x7;
+	bin->pvs_valid = bin->pvs != 0x7;
 }
 
-static int __init get_pvs_bin(u32 pte_efuse)
+void __init get_krait_bin_format_b(void __iomem *base, struct bin_info *bin)
 {
-	uint32_t pvs_bin;
+	u32 pte_efuse, redundant_sel;
 
-	pvs_bin = (pte_efuse >> 10) & 0x7;
-	if (pvs_bin == 0x7)
-		pvs_bin = (pte_efuse >> 13) & 0x7;
+	pte_efuse = readl_relaxed(base);
+	redundant_sel = (pte_efuse >> 24) & 0x7;
+	bin->speed = pte_efuse & 0x7;
+	bin->pvs = (pte_efuse >> 6) & 0x7;
 
-	if (pvs_bin == 0x7) {
-		pvs_bin = 0;
-		dev_warn(drv.dev, "ACPU PVS: Defaulting to %d\n", pvs_bin);
-	} else {
-		dev_info(drv.dev, "ACPU PVS: %d\n", pvs_bin);
+	switch (redundant_sel) {
+	case 1:
+		bin->speed = (pte_efuse >> 27) & 0x7;
+		break;
+	case 2:
+		bin->pvs = (pte_efuse >> 27) & 0x7;
+		break;
 	}
+	bin->speed_valid = true;
 
-	return pvs_bin;
+	/* Check PVS_BLOW_STATUS */
+	pte_efuse = readl_relaxed(base + 0x4);
+	bin->pvs_valid = !!(pte_efuse & BIT(21));
 }
 
-static struct pvs_table * __init select_freq_plan(u32 pte_efuse_phys,
-			struct pvs_table (*pvs_tables)[NUM_PVS])
+static struct pvs_table * __init select_freq_plan(
+		const struct acpuclk_krait_params *params)
 {
-	void __iomem *pte_efuse;
-	u32 pte_efuse_val;
+	void __iomem *pte_efuse_base;
+	struct bin_info bin;
 
-	pte_efuse = ioremap(pte_efuse_phys, 4);
-	if (!pte_efuse) {
-		dev_err(drv.dev, "Unable to map QFPROM base\n");
+	pte_efuse_base = ioremap(params->pte_efuse_phys, 8);
+	if (!pte_efuse_base) {
+		dev_err(drv.dev, "Unable to map PTE eFuse base\n");
 		return NULL;
 	}
+	params->get_bin_info(pte_efuse_base, &bin);
+	iounmap(pte_efuse_base);
 
-	pte_efuse_val = readl_relaxed(pte_efuse);
-	iounmap(pte_efuse);
+	if (bin.speed_valid) {
+		drv.speed_bin = bin.speed;
+		dev_info(drv.dev, "SPEED BIN: %d\n", drv.speed_bin);
+	} else {
+		drv.speed_bin = 0;
+		dev_warn(drv.dev, "SPEED BIN: Defaulting to %d\n",
+			 drv.speed_bin);
+	}
 
-	/* Select frequency tables. */
-	drv.speed_bin = get_speed_bin(pte_efuse_val);
-	drv.pvs_bin = get_pvs_bin(pte_efuse_val);
+	if (bin.pvs_valid) {
+		drv.pvs_bin = bin.pvs;
+		dev_info(drv.dev, "ACPU PVS: %d\n", drv.pvs_bin);
+	} else {
+		drv.pvs_bin = 0;
+		dev_warn(drv.dev, "ACPU PVS: Defaulting to %d\n",
+			 drv.pvs_bin);
+	}
 
-	return &pvs_tables[drv.speed_bin][drv.pvs_bin];
+	return &params->pvs_tables[drv.speed_bin][drv.pvs_bin];
 }
 
 static void __init drv_data_init(struct device *dev,
@@ -1124,7 +1140,7 @@
 		GFP_KERNEL);
 	BUG_ON(!drv.bus_scale->usecase);
 
-	pvs = select_freq_plan(params->pte_efuse_phys, params->pvs_tables);
+	pvs = select_freq_plan(params);
 	BUG_ON(!pvs->table);
 
 	drv.acpu_freq_tbl = kmemdup(pvs->table, pvs->size, GFP_KERNEL);
diff --git a/arch/arm/mach-msm/acpuclock-krait.h b/arch/arm/mach-msm/acpuclock-krait.h
index ca8013e..00f64fc 100644
--- a/arch/arm/mach-msm/acpuclock-krait.h
+++ b/arch/arm/mach-msm/acpuclock-krait.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. 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
@@ -152,7 +152,7 @@
 struct acpu_level {
 	const int use_for_scaling;
 	const struct core_speed speed;
-	const unsigned int l2_level;
+	unsigned int l2_level;
 	int vdd_core;
 	int ua_core;
 	unsigned int avsdscr_setting;
@@ -227,6 +227,20 @@
 };
 
 /**
+ * struct bin_info - Hardware speed and voltage binning info.
+ * @speed_valid: @speed field is valid
+ * @pvs_valid: @pvs field is valid
+ * @speed: Speed bin ID
+ * @pvs: PVS bin ID
+ */
+struct bin_info {
+	bool speed_valid;
+	bool pvs_valid;
+	int speed;
+	int pvs;
+};
+
+/**
  * struct pvs_table - CPU performance level table and size.
  * @table: CPU performance level table
  * @size: sizeof(@table)
@@ -247,6 +261,7 @@
  * @l2_freq_tbl: L2 frequency table.
  * @l2_freq_tbl_size: Size of @l2_freq_tbl.
  * @pte_efuse_phys: Physical address of PTE EFUSE.
+ * @get_bin_info: Function to populate bin_info from pte_efuse.
  * @bus_scale: MSM bus driver parameters.
  * @stby_khz: KHz value corresponding to an always-on clock source.
  */
@@ -258,6 +273,7 @@
 	struct l2_level *l2_freq_tbl;
 	size_t l2_freq_tbl_size;
 	phys_addr_t pte_efuse_phys;
+	void (*get_bin_info)(void __iomem *base, struct bin_info *bin);
 	struct msm_bus_scale_pdata *bus_scale;
 	unsigned long stby_khz;
 };
@@ -297,6 +313,16 @@
 };
 
 /**
+ * get_krait_bin_format_a - Populate bin_info from a 'Format A' pte_efuse
+ */
+void __init get_krait_bin_format_a(void __iomem *base, struct bin_info *bin);
+
+/**
+ * get_krait_bin_format_b - Populate bin_info from a 'Format B' pte_efuse
+ */
+void __init get_krait_bin_format_b(void __iomem *base, struct bin_info *bin);
+
+/**
  * acpuclk_krait_init - Initialize the Krait CPU clock driver give SoC params.
  */
 extern int acpuclk_krait_init(struct device *dev,
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 040660a..9da5436 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. 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
@@ -891,6 +891,7 @@
 write_fail3:
 	kfree(pkt);
 write_fail2:
+	skb_pull(skb, sizeof(struct bam_mux_hdr));
 	if (new_skb)
 		dev_kfree_skb_any(new_skb);
 write_fail:
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 476a191..dc9120a 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -143,6 +143,11 @@
 #define PCIE_PWR_EN_PMIC_GPIO 13
 #define PCIE_RST_N_PMIC_MPP 1
 
+/* PCIe pmic gpios for fsm8064_ep */
+/* Unused pin. The WAKE feature is not supported on fsm8064_ep */
+#define PCIE_EP_WAKE_N_PMIC_GPIO	11
+#define PCIE_EP_RST_N_PMIC_GPIO		37
+
 #ifdef CONFIG_KERNEL_MSM_CONTIG_MEM_REGION
 static unsigned msm_contig_mem_size = MSM_CONTIG_MEM_SIZE;
 static int __init msm_contig_mem_size_setup(char *p)
@@ -959,7 +964,7 @@
 {
 	if (machine_is_apq8064_liquid() || machine_is_mpq8064_cdp() ||
 		machine_is_mpq8064_hrd() || machine_is_mpq8064_dtv() ||
-					machine_is_apq8064_cdp()) {
+			machine_is_apq8064_cdp() || machine_is_fsm8064_ep()) {
 		if (machine_is_apq8064_liquid())
 			msm_ehci_host_pdata3.dock_connect_irq =
 					PM8921_MPP_IRQ(PM8921_IRQ_BASE, 9);
@@ -2479,6 +2484,19 @@
 	.wake_n = PM8921_GPIO_IRQ(PM8921_IRQ_BASE, PCIE_WAKE_N_PMIC_GPIO),
 };
 
+/* FSM8064_EP PCIe gpios */
+static struct msm_pcie_gpio_info_t ep_pcie_gpio_info[MSM_PCIE_MAX_GPIO] = {
+	{"rst_n", PM8921_GPIO_PM_TO_SYS(PCIE_EP_RST_N_PMIC_GPIO), 0},
+	{"pwr_en", PM8921_GPIO_PM_TO_SYS(PCIE_PWR_EN_PMIC_GPIO), 1},
+};
+
+static struct msm_pcie_platform ep_pcie_platform_data = {
+	.gpio = ep_pcie_gpio_info,
+	.axi_addr = PCIE_AXI_BAR_PHYS,
+	.axi_size = PCIE_AXI_BAR_SIZE,
+	.wake_n = PM8921_GPIO_IRQ(PM8921_IRQ_BASE, PCIE_EP_WAKE_N_PMIC_GPIO),
+};
+
 static int __init mpq8064_pcie_enabled(void)
 {
 	return !((readl_relaxed(QFPROM_RAW_FEAT_CONFIG_ROW0_MSB) & BIT(21)) ||
@@ -2493,6 +2511,12 @@
 	}
 }
 
+static void __init fsm8064_ep_pcie_init(void)
+{
+	msm_device_pcie.dev.platform_data = &ep_pcie_platform_data;
+	platform_device_register(&msm_device_pcie);
+}
+
 static struct platform_device mpq8064_device_ext_3p3v_vreg = {
 	.name			= "reg-fixed-voltage",
 	.dev			= {
@@ -2588,6 +2612,100 @@
 	&mpq_cpudai_pseudo,
 };
 
+static struct platform_device *ep_devices[] __initdata = {
+	&msm_device_smd_apq8064,
+	&apq8064_device_gadget_peripheral,
+	&apq8064_device_hsusb_host,
+	&android_usb_device,
+	&msm_device_wcnss_wlan,
+	&msm_device_iris_fm,
+	&apq8064_fmem_device,
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+	&apq8064_android_pmem_device,
+	&apq8064_android_pmem_adsp_device,
+	&apq8064_android_pmem_audio_device,
+#endif /*CONFIG_MSM_MULTIMEDIA_USE_ION*/
+#endif /*CONFIG_ANDROID_PMEM*/
+#ifdef CONFIG_ION_MSM
+	&apq8064_ion_dev,
+#endif
+	&msm8064_device_watchdog,
+	&msm8064_device_saw_regulator_core0,
+	&msm8064_device_saw_regulator_core1,
+	&msm8064_device_saw_regulator_core2,
+	&msm8064_device_saw_regulator_core3,
+#if defined(CONFIG_QSEECOM)
+	&qseecom_device,
+#endif
+
+	&msm_8064_device_tsif[0],
+	&msm_8064_device_tsif[1],
+
+#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
+		defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
+	&qcrypto_device,
+#endif
+
+#if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
+		defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
+	&qcedev_device,
+#endif
+
+#ifdef CONFIG_HW_RANDOM_MSM
+	&apq8064_device_rng,
+#endif
+	&apq_pcm,
+	&apq_pcm_routing,
+	&apq8064_rpm_device,
+	&apq8064_rpm_log_device,
+	&apq8064_rpm_stat_device,
+	&apq8064_rpm_master_stat_device,
+	&apq_device_tz_log,
+	&msm_bus_8064_apps_fabric,
+	&msm_bus_8064_sys_fabric,
+	&msm_bus_8064_mm_fabric,
+	&msm_bus_8064_sys_fpb,
+	&msm_bus_8064_cpss_fpb,
+	&msm_pil_dsps,
+	&msm_8960_q6_lpass,
+	&msm_pil_vidc,
+	&msm_gss,
+	&apq8064_rtb_device,
+	&apq8064_dcvs_device,
+	&apq8064_msm_gov_device,
+	&apq8064_device_cache_erp,
+	&msm8960_device_ebi1_ch0_erp,
+	&msm8960_device_ebi1_ch1_erp,
+	&epm_adc_device,
+	&coresight_tpiu_device,
+	&coresight_etb_device,
+	&apq8064_coresight_funnel_device,
+	&coresight_etm0_device,
+	&coresight_etm1_device,
+	&coresight_etm2_device,
+	&coresight_etm3_device,
+#ifdef CONFIG_MSM_GEMINI
+	&msm8960_gemini_device,
+#endif
+	&msm_tsens_device,
+	&apq8064_cache_dump_device,
+	&msm_8064_device_tspp,
+#ifdef CONFIG_BATTERY_BCL
+	&battery_bcl_device,
+#endif
+	&apq8064_msm_mpd_device,
+	&apq8064_device_qup_i2c_gsbi1,
+	&apq8064_device_uart_gsbi2,
+	&apq8064_device_uart_gsbi1,
+	&apq8064_device_uart_gsbi4,
+	&msm_device_sps_apq8064,
+#ifdef CONFIG_MSM_ROTATOR
+	&msm_rotator_device,
+#endif
+	&msm8064_pc_cntr,
+};
+
 static struct platform_device *common_i2s_devices[] __initdata = {
 	&apq_cpudai_mi2s,
 	&apq_cpudai_i2s_rx,
@@ -2998,12 +3116,14 @@
 	wmb();
 	iounmap(gsbi_mem);
 	apq8064_i2c_qup_gsbi1_pdata.use_gsbi_shared_mode = 1;
-	apq8064_device_qup_i2c_gsbi3.dev.platform_data =
-					&apq8064_i2c_qup_gsbi3_pdata;
 	apq8064_device_qup_i2c_gsbi1.dev.platform_data =
 					&apq8064_i2c_qup_gsbi1_pdata;
-	apq8064_device_qup_i2c_gsbi4.dev.platform_data =
-					&apq8064_i2c_qup_gsbi4_pdata;
+	if (!machine_is_fsm8064_ep()) {
+		apq8064_device_qup_i2c_gsbi3.dev.platform_data =
+						&apq8064_i2c_qup_gsbi3_pdata;
+		apq8064_device_qup_i2c_gsbi4.dev.platform_data =
+						&apq8064_i2c_qup_gsbi4_pdata;
+	}
 	mpq8064_device_qup_i2c_gsbi5.dev.platform_data =
 					&mpq8064_i2c_qup_gsbi5_pdata;
 }
@@ -3519,6 +3639,8 @@
 		mach_mask = I2C_LIQUID;
 	else if (PLATFORM_IS_MPQ8064())
 		mach_mask = I2C_MPQ_CDP;
+	else if (machine_is_fsm8064_ep())
+		mach_mask = I2C_SURF;
 	else
 		pr_err("unmatched machine ID in register_i2c_devices\n");
 
@@ -3644,9 +3766,11 @@
 					ARRAY_SIZE(pm8917_common_devices));
 	if (machine_is_apq8064_cdp() || machine_is_apq8064_liquid())
 		platform_device_register(&apq8064_device_ext_ts_sw_vreg);
-	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
+	if (!machine_is_fsm8064_ep())
+		platform_add_devices(common_devices,
+				ARRAY_SIZE(common_devices));
 	if (!(machine_is_mpq8064_cdp() || machine_is_mpq8064_hrd() ||
-			machine_is_mpq8064_dtv()))
+			machine_is_mpq8064_dtv() || machine_is_fsm8064_ep()))
 		platform_add_devices(common_not_mpq_devices,
 			ARRAY_SIZE(common_not_mpq_devices));
 
@@ -3797,6 +3921,26 @@
 	}
 }
 
+static void __init fsm8064_ep_init(void)
+{
+	if (meminfo_init(SYS_MEMORY, SZ_256M) < 0)
+		pr_err("meminfo_init() failed!\n");
+
+	apq8064_common_init();
+	ethernet_init();
+	msm_rotator_set_split_iommu_domain();
+	fsm8064_ep_pcie_init();
+	platform_add_devices(ep_devices, ARRAY_SIZE(ep_devices));
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+	apq8064_init_gpu();
+	platform_add_devices(apq8064_footswitch, apq8064_num_footswitch);
+	platform_device_register(&cdp_kp_pdev);
+#ifdef CONFIG_MSM_CAMERA
+	apq8064_init_cam();
+#endif
+	change_memory_power = &apq8064_change_memory_power;
+}
+
 MACHINE_START(APQ8064_CDP, "QCT APQ8064 CDP")
 	.map_io = apq8064_map_io,
 	.reserve = apq8064_reserve,
@@ -3810,6 +3954,18 @@
 	.smp = &msm8960_smp_ops,
 MACHINE_END
 
+MACHINE_START(FSM8064_EP, "QCT FSM8064 EP")
+	.map_io = apq8064_map_io,
+	.reserve = apq8064_reserve,
+	.init_irq = apq8064_init_irq,
+	.handle_irq = gic_handle_irq,
+	.timer = &msm_timer,
+	.init_machine = fsm8064_ep_init,
+	.init_early = apq8064_allocate_memory_regions,
+	.init_very_early = apq8064_early_reserve,
+	.restart = msm_restart,
+MACHINE_END
+
 MACHINE_START(APQ8064_MTP, "QCT APQ8064 MTP")
 	.map_io = apq8064_map_io,
 	.reserve = apq8064_reserve,
diff --git a/arch/arm/mach-msm/board-8610.c b/arch/arm/mach-msm/board-8610.c
index 0e514dc..322d696 100644
--- a/arch/arm/mach-msm/board-8610.c
+++ b/arch/arm/mach-msm/board-8610.c
@@ -40,9 +40,14 @@
 #include <mach/socinfo.h>
 #include <mach/board.h>
 #include <mach/clk-provider.h>
+#include <mach/msm_smd.h>
+#include <mach/rpm-smd.h>
+#include <linux/msm_thermal.h>
 #include "board-dt.h"
 #include "clock.h"
 #include "platsmp.h"
+#include "spm.h"
+#include "lpm_resources.h"
 
 static struct memtype_reserve msm8610_reserve_table[] __initdata = {
 	[MEMTYPE_SMI] = {
@@ -84,6 +89,14 @@
 	msm_reserve();
 }
 
+void __init msm8610_add_drivers(void)
+{
+	msm_rpm_driver_init();
+	msm_lpmrs_module_init();
+	msm_spm_device_init();
+	msm_thermal_device_init();
+}
+
 void __init msm8610_init(void)
 {
 	struct of_dev_auxdata *adata = msm8610_auxdata_lookup;
@@ -92,11 +105,13 @@
 		pr_err("%s: socinfo_init() failed\n", __func__);
 
 	msm8610_init_gpiomux();
+	msm8610_add_drivers();
 
 	if (machine_is_msm8610_rumi())
 		msm_clock_init(&msm8610_rumi_clock_init_data);
 	else
 		msm_clock_init(&msm8610_clock_init_data);
+
 	of_platform_populate(NULL, of_default_bus_match_table, adata, NULL);
 }
 
@@ -107,7 +122,7 @@
 
 DT_MACHINE_START(MSM8610_DT, "Qualcomm MSM 8610 (Flattened Device Tree)")
 	.map_io = msm_map_msm8610_io,
-	.init_irq = msm_dt_init_irq_nompm,
+	.init_irq = msm_dt_init_irq,
 	.init_machine = msm8610_init,
 	.handle_irq = gic_handle_irq,
 	.timer = &msm_dt_timer,
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 928b5aa..14f369df 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -3049,22 +3049,30 @@
 	return -ENXIO;
 }
 
-static enum handoff pix_rdi_clk_handoff(struct clk *c)
+static struct clk *pix_rdi_clk_get_parent(struct clk *c)
 {
 	u32 reg;
 	struct pix_rdi_clk *rdi = to_pix_rdi_clk(c);
+
+	reg = readl_relaxed(rdi->s_reg);
+	rdi->cur_rate = reg & rdi->s_mask ? 1 : 0;
+	reg = readl_relaxed(rdi->s2_reg);
+	rdi->cur_rate = reg & rdi->s2_mask ? 2 : rdi->cur_rate;
+
+	return pix_rdi_mux_map[rdi->cur_rate];
+}
+
+static enum handoff pix_rdi_clk_handoff(struct clk *c)
+{
+	struct pix_rdi_clk *rdi = to_pix_rdi_clk(c);
 	enum handoff ret;
 
 	ret = branch_handoff(&rdi->b, &rdi->c);
 	if (ret == HANDOFF_DISABLED_CLK)
 		return ret;
 
-	reg = readl_relaxed(rdi->s_reg);
-	rdi->cur_rate = reg & rdi->s_mask ? 1 : 0;
-	reg = readl_relaxed(rdi->s2_reg);
-	rdi->cur_rate = reg & rdi->s2_mask ? 2 : rdi->cur_rate;
-	c->parent = pix_rdi_mux_map[rdi->cur_rate];
-
+	rdi->prepared = true;
+	rdi->enabled = true;
 	return HANDOFF_ENABLED_CLK;
 }
 
@@ -3078,6 +3086,7 @@
 	.get_rate = pix_rdi_clk_get_rate,
 	.list_rate = pix_rdi_clk_list_rate,
 	.reset = pix_rdi_clk_reset,
+	.get_parent = pix_rdi_clk_get_parent,
 };
 
 static struct pix_rdi_clk csi_pix_clk = {
@@ -5283,8 +5292,10 @@
 	CLK_LOOKUP("core_clk",		gp2_clk.c,		""),
 	CLK_LOOKUP("core_clk",		gsbi1_uart_clk.c, "msm_serial_hsl.1"),
 	CLK_LOOKUP("core_clk",		gsbi2_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi2_uart_clk.c, "msm_serial_hsl.3"),
 	CLK_LOOKUP("core_clk",		gsbi3_uart_clk.c,	""),
 	CLK_LOOKUP("core_clk",		gsbi4_uart_clk.c,	""),
+	CLK_LOOKUP("core_clk",		gsbi4_uart_clk.c, "msm_serial_hsl.4"),
 	CLK_LOOKUP("core_clk",		gsbi5_uart_clk.c, "msm_serial_hsl.2"),
 	CLK_LOOKUP("core_clk",		gsbi6_uart_clk.c, "msm_serial_hs.0"),
 	CLK_LOOKUP("core_clk",		gsbi7_uart_clk.c, "msm_serial_hsl.0"),
@@ -5332,6 +5343,7 @@
 	CLK_LOOKUP("iface_clk",		gsbi1_p_clk.c,	"msm_serial_hsl.1"),
 	CLK_LOOKUP("iface_clk",		gsbi1_p_clk.c,	"qup_i2c.0"),
 	CLK_LOOKUP("iface_clk",		gsbi2_p_clk.c,		""),
+	CLK_LOOKUP("iface_clk",		gsbi2_p_clk.c,	"msm_serial_hsl.3"),
 	CLK_LOOKUP("iface_clk",		gsbi3_p_clk.c,		"qup_i2c.3"),
 	CLK_LOOKUP("iface_clk",		gsbi4_p_clk.c,		"qup_i2c.4"),
 	CLK_LOOKUP("iface_clk",		gsbi5_p_clk.c,	"msm_serial_hsl.2"),
@@ -5340,6 +5352,7 @@
 	CLK_LOOKUP("iface_clk",		gsbi6_p_clk.c,	"msm_serial_hs.0"),
 	CLK_LOOKUP("iface_clk",		gsbi6_p_clk.c,		"spi_qsd.1"),
 	CLK_LOOKUP("iface_clk",		gsbi7_p_clk.c,	"msm_serial_hsl.0"),
+	CLK_LOOKUP("iface_clk",		gsbi7_p_clk.c,	"msm_serial_hsl.4"),
 	CLK_LOOKUP("ref_clk",	tsif_ref_clk.c,	"msm_tspp.0"),
 	CLK_LOOKUP("iface_clk",		tsif_p_clk.c,		"msm_tspp.0"),
 	CLK_LOOKUP("iface_clk",		usb_fs1_p_clk.c,	""),
@@ -6369,7 +6382,7 @@
 		writel_relaxed(0x3C7097F9, AHB_EN2_REG);
 	}
 
-	if (cpu_is_apq8064() || cpu_is_apq8064ab())
+	if (soc_class_is_apq8064())
 		rmwreg(0x00000000, AHB_EN3_REG, 0x00000001);
 
 	/* Deassert all locally-owned MM AHB resets. */
@@ -6392,7 +6405,7 @@
 	rmwreg(0x0027FCFF, MAXI_EN3_REG, 0x003FFFFF);
 	rmwreg(0x0027FCFF, MAXI_EN4_REG, 0x017FFFFF);
 
-	if (cpu_is_apq8064() || cpu_is_apq8064ab())
+	if (soc_class_is_apq8064())
 		rmwreg(0x019FECFF, MAXI_EN5_REG, 0x01FFEFFF);
 	if (cpu_is_msm8930() || cpu_is_msm8930aa() || cpu_is_msm8627() ||
 	    cpu_is_msm8930ab())
@@ -6429,8 +6442,7 @@
 	rmwreg(0x80FF0000, VFE_CC_REG,        0xE0FF4010);
 	rmwreg(0x800000FF, VFE_CC2_REG,       0xE00000FF);
 	rmwreg(0x80FF0000, VPE_CC_REG,        0xE0FF0010);
-	if (cpu_is_msm8960ab() || cpu_is_msm8960() || cpu_is_apq8064()
-		 || cpu_is_apq8064ab()) {
+	if (cpu_is_msm8960ab() || cpu_is_msm8960() || soc_class_is_apq8064()) {
 		rmwreg(0x80FF0000, DSI2_BYTE_CC_REG,  0xE0FF0010);
 		rmwreg(0x80FF0000, DSI2_PIXEL_CC_REG, 0xE0FF0010);
 		rmwreg(0x80FF0000, JPEGD_CC_REG,      0xE0FF0010);
@@ -6448,7 +6460,7 @@
 		rmwreg(0x80FF0000, GFX2D0_CC_REG,     0xE0FF0010);
 		rmwreg(0x80FF0000, GFX2D1_CC_REG,     0xE0FF0010);
 	}
-	if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
+	if (soc_class_is_apq8064()) {
 		rmwreg(0x00000000, TV_CC_REG,         0x00004010);
 		rmwreg(0x80FF0000, VCAP_CC_REG,       0xE0FF1010);
 	}
@@ -6459,7 +6471,7 @@
 	 * and wake-up value to max.
 	 */
 	rmwreg(0x0000004F, USB_HS1_HCLK_FS_REG, 0x0000007F);
-	if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
+	if (soc_class_is_apq8064()) {
 		rmwreg(0x0000004F, USB_HS3_HCLK_FS_REG, 0x0000007F);
 		rmwreg(0x0000004F, USB_HS4_HCLK_FS_REG, 0x0000007F);
 	}
@@ -6481,8 +6493,7 @@
 
 	/* Source the dsi_byte_clks from the DSI PHY PLLs */
 	rmwreg(0x1, DSI1_BYTE_NS_REG, 0x7);
-	if (cpu_is_msm8960ab() || cpu_is_msm8960() || cpu_is_apq8064()
-		|| cpu_is_apq8064ab())
+	if (cpu_is_msm8960ab() || cpu_is_msm8960() || soc_class_is_apq8064())
 		rmwreg(0x2, DSI2_BYTE_NS_REG, 0x7);
 
 	/* Source the dsi1_esc_clk from the DSI1 PHY PLLs */
@@ -6492,7 +6503,7 @@
 	 * Source the sata_phy_ref_clk from PXO and set predivider of
 	 * sata_pmalive_clk to 1.
 	 */
-	if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
+	if (soc_class_is_apq8064()) {
 		rmwreg(0, SATA_PHY_REF_CLK_CTL_REG, 0x1);
 		rmwreg(0, SATA_PMALIVE_CLK_CTL_REG, 0x3);
 	}
@@ -6501,7 +6512,7 @@
 	 * TODO: Programming below PLLs and prng_clk is temporary and
 	 *	 needs to be removed after bootloaders program them.
 	 */
-	if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
+	if (soc_class_is_apq8064()) {
 		u32 is_pll_enabled;
 
 		/* Program pxo_src_clk to source from PXO */
@@ -6527,7 +6538,7 @@
 			writel_relaxed(0x2B, PRNG_CLK_NS_REG);
 	}
 
-	if (cpu_is_apq8064()) {
+	if (cpu_is_apq8064() || cpu_is_apq8064aa()) {
 		/* Program PLL15 to 975MHz with ref clk = 27MHz */
 		configure_sr_pll(&pll15_config, &pll15_regs, 0);
 	} else if (cpu_is_apq8064ab()) {
@@ -6564,7 +6575,7 @@
 	/* Initialize clock registers. */
 	reg_init();
 
-	if (cpu_is_apq8064() || cpu_is_apq8064ab())
+	if (soc_class_is_apq8064())
 		vdd_sr2_hdmi_pll.set_vdd = set_vdd_sr2_hdmi_pll_8064;
 
 	/* Detect PLL4 programmed for alternate 491.52MHz clock plan. */
@@ -6608,21 +6619,21 @@
 	 * Change the freq tables for and voltage requirements for
 	 * clocks which differ between chips.
 	 */
-	if (cpu_is_apq8064()) {
+	if (cpu_is_apq8064() || cpu_is_apq8064aa())
 		gfx3d_clk.c.fmax = fmax_gfx3d_8064;
-	}
-	if (cpu_is_apq8064ab()) {
+
+	if (cpu_is_apq8064ab())
 		gfx3d_clk.c.fmax = fmax_gfx3d_8064ab;
-	}
+
 	if ((cpu_is_apq8064() &&
 		SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) ||
-		cpu_is_apq8064ab()) {
+		cpu_is_apq8064ab() || cpu_is_apq8064aa()) {
 
 		vcodec_clk.c.fmax = fmax_vcodec_8064v2;
 		ce3_src_clk.c.fmax = fmax_ce3_8064v2;
 		sdc1_clk.c.fmax = fmax_sdc1_8064v2;
 	}
-	if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
+	if (soc_class_is_apq8064()) {
 		ijpeg_clk.c.fmax = fmax_ijpeg_8064;
 		mdp_clk.c.fmax = fmax_mdp_8064;
 		tv_src_clk.c.fmax = fmax_tv_src_8064;
@@ -6695,7 +6706,7 @@
 	clk_set_rate(&tsif_ref_clk.c, 105000);
 	clk_set_rate(&tssc_clk.c, 27000000);
 	clk_set_rate(&usb_hs1_xcvr_clk.c, 60000000);
-	if (cpu_is_apq8064() || cpu_is_apq8064ab()) {
+	if (soc_class_is_apq8064()) {
 		clk_set_rate(&usb_hs3_xcvr_clk.c, 60000000);
 		clk_set_rate(&usb_hs4_xcvr_clk.c, 60000000);
 	}
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index 4432795..a173ba9 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-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
@@ -598,20 +598,21 @@
 static enum handoff branch_clk_handoff(struct clk *c)
 {
 	struct branch_clk *br = to_branch_clk(c);
-	return branch_handoff(&br->b, &br->c);
+	if (branch_handoff(&br->b, &br->c) == HANDOFF_ENABLED_CLK) {
+		br->enabled = true;
+		return HANDOFF_ENABLED_CLK;
+	}
+
+	return HANDOFF_DISABLED_CLK;
 }
 
-static enum handoff rcg_clk_handoff(struct clk *c)
+static struct clk *rcg_clk_get_parent(struct clk *c)
 {
 	struct rcg_clk *rcg = to_rcg_clk(c);
 	uint32_t ctl_val, ns_val, md_val, ns_mask;
 	struct clk_freq_tbl *freq;
-	enum handoff ret;
 
 	ctl_val = readl_relaxed(rcg->b.ctl_reg);
-	ret = branch_handoff(&rcg->b, &rcg->c);
-	if (ret == HANDOFF_DISABLED_CLK)
-		return HANDOFF_DISABLED_CLK;
 
 	if (rcg->bank_info) {
 		const struct bank_masks *bank_masks = rcg->bank_info;
@@ -628,21 +629,40 @@
 		ns_mask = rcg->ns_mask;
 		md_val = rcg->md_reg ? readl_relaxed(rcg->md_reg) : 0;
 	}
+
 	if (!ns_mask)
-		return HANDOFF_UNKNOWN_RATE;
+		return NULL;
+
 	ns_val = readl_relaxed(rcg->ns_reg) & ns_mask;
 	for (freq = rcg->freq_tbl; freq->freq_hz != FREQ_END; freq++) {
 		if ((freq->ns_val & ns_mask) == ns_val &&
 		    (!freq->md_val || freq->md_val == md_val))
 			break;
 	}
+
 	if (freq->freq_hz == FREQ_END)
-		return HANDOFF_UNKNOWN_RATE;
+		return NULL;
 
+	/* Cache the results for the handoff code. */
 	rcg->current_freq = freq;
-	c->parent = freq->src_clk;
-	c->rate = freq->freq_hz;
 
+	return freq->src_clk;
+}
+
+static enum handoff rcg_clk_handoff(struct clk *c)
+{
+	struct rcg_clk *rcg = to_rcg_clk(c);
+	enum handoff ret;
+
+	if (rcg->current_freq && rcg->current_freq->freq_hz != FREQ_END)
+		c->rate = rcg->current_freq->freq_hz;
+
+	ret = branch_handoff(&rcg->b, &rcg->c);
+	if (ret == HANDOFF_DISABLED_CLK)
+		return HANDOFF_DISABLED_CLK;
+
+	rcg->prepared = true;
+	rcg->enabled = true;
 	return HANDOFF_ENABLED_CLK;
 }
 
@@ -861,6 +881,7 @@
 	.round_rate = rcg_clk_round_rate,
 	.reset = rcg_clk_reset,
 	.set_flags = rcg_clk_set_flags,
+	.get_parent = rcg_clk_get_parent,
 };
 
 static int cdiv_clk_enable(struct clk *c)
@@ -940,6 +961,7 @@
 		reg_val >>= cdiv->div_offset;
 		cdiv->cur_div = (reg_val & (cdiv->max_div - 1)) + 1;
 	}
+	c->rate = cdiv->cur_div;
 
 	return HANDOFF_ENABLED_CLK;
 }
diff --git a/arch/arm/mach-msm/clock-local2.c b/arch/arm/mach-msm/clock-local2.c
index cf42355..dd78557 100644
--- a/arch/arm/mach-msm/clock-local2.c
+++ b/arch/arm/mach-msm/clock-local2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -69,8 +69,8 @@
 #define MND_MODE_MASK			BM(13, 12)
 #define MND_DUAL_EDGE_MODE_BVAL		BVAL(13, 12, 0x2)
 #define CMD_RCGR_CONFIG_DIRTY_MASK	BM(7, 4)
-#define CBCR_BRANCH_CDIV_MASK		BM(24, 16)
-#define CBCR_BRANCH_CDIV_MASKED(val)	BVAL(24, 16, (val));
+#define CBCR_CDIV_LSB			16
+#define CBCR_CDIV_MSB			24
 
 enum branch_state {
 	BRANCH_ON,
@@ -235,21 +235,17 @@
 	return (rcg->freq_tbl + n)->freq_hz;
 }
 
-static enum handoff _rcg_clk_handoff(struct rcg_clk *rcg, int has_mnd)
+static struct clk *_rcg_clk_get_parent(struct rcg_clk *rcg, int has_mnd)
 {
 	u32 n_regval = 0, m_regval = 0, d_regval = 0;
 	u32 cfg_regval;
 	struct clk_freq_tbl *freq;
 	u32 cmd_rcgr_regval;
 
-	/* Is the root enabled? */
-	cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg));
-	if ((cmd_rcgr_regval & CMD_RCGR_ROOT_STATUS_BIT))
-		return HANDOFF_DISABLED_CLK;
-
 	/* Is there a pending configuration? */
+	cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg));
 	if (cmd_rcgr_regval & CMD_RCGR_CONFIG_DIRTY_MASK)
-		return HANDOFF_UNKNOWN_RATE;
+		return NULL;
 
 	/* Get values of m, n, d, div and src_sel registers. */
 	if (has_mnd) {
@@ -299,23 +295,45 @@
 
 	/* No known frequency found */
 	if (freq->freq_hz == FREQ_END)
-		return HANDOFF_UNKNOWN_RATE;
+		return NULL;
 
 	rcg->current_freq = freq;
-	rcg->c.parent = freq->src_clk;
-	rcg->c.rate = freq->freq_hz;
+	return freq->src_clk;
+}
+
+static enum handoff _rcg_clk_handoff(struct rcg_clk *rcg)
+{
+	u32 cmd_rcgr_regval;
+
+	if (rcg->current_freq && rcg->current_freq->freq_hz != FREQ_END)
+		rcg->c.rate = rcg->current_freq->freq_hz;
+
+	/* Is the root enabled? */
+	cmd_rcgr_regval = readl_relaxed(CMD_RCGR_REG(rcg));
+	if ((cmd_rcgr_regval & CMD_RCGR_ROOT_STATUS_BIT))
+		return HANDOFF_DISABLED_CLK;
 
 	return HANDOFF_ENABLED_CLK;
 }
 
+static struct clk *rcg_mnd_clk_get_parent(struct clk *c)
+{
+	return _rcg_clk_get_parent(to_rcg_clk(c), 1);
+}
+
+static struct clk *rcg_clk_get_parent(struct clk *c)
+{
+	return _rcg_clk_get_parent(to_rcg_clk(c), 0);
+}
+
 static enum handoff rcg_mnd_clk_handoff(struct clk *c)
 {
-	return _rcg_clk_handoff(to_rcg_clk(c), 1);
+	return _rcg_clk_handoff(to_rcg_clk(c));
 }
 
 static enum handoff rcg_clk_handoff(struct clk *c)
 {
-	return _rcg_clk_handoff(to_rcg_clk(c), 0);
+	return _rcg_clk_handoff(to_rcg_clk(c));
 }
 
 #define BRANCH_CHECK_MASK	BM(31, 28)
@@ -412,8 +430,8 @@
 
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
 	regval = readl_relaxed(CBCR_REG(branch));
-	regval &= ~CBCR_BRANCH_CDIV_MASK;
-	regval |= CBCR_BRANCH_CDIV_MASKED(rate);
+	regval &= ~BM(CBCR_CDIV_MSB, CBCR_CDIV_LSB);
+	regval |= BVAL(CBCR_CDIV_MSB, CBCR_CDIV_LSB, rate);
 	writel_relaxed(regval, CBCR_REG(branch));
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 
@@ -496,9 +514,12 @@
 	if ((cbcr_regval & CBCR_BRANCH_OFF_BIT))
 		return HANDOFF_DISABLED_CLK;
 
-	if (c->parent) {
-		if (c->parent->ops->handoff)
-			return c->parent->ops->handoff(c->parent);
+	if (branch->max_div) {
+		cbcr_regval &= BM(CBCR_CDIV_MSB, CBCR_CDIV_LSB);
+		cbcr_regval >>= CBCR_CDIV_LSB;
+		c->rate = cbcr_regval;
+	} else if (!branch->has_sibling) {
+		c->rate = clk_get_rate(c->parent);
 	}
 
 	return HANDOFF_ENABLED_CLK;
@@ -611,6 +632,7 @@
 	.list_rate = rcg_clk_list_rate,
 	.round_rate = rcg_clk_round_rate,
 	.handoff = rcg_clk_handoff,
+	.get_parent = rcg_clk_get_parent,
 };
 
 struct clk_ops clk_ops_rcg_mnd = {
@@ -619,6 +641,7 @@
 	.list_rate = rcg_clk_list_rate,
 	.round_rate = rcg_clk_round_rate,
 	.handoff = rcg_mnd_clk_handoff,
+	.get_parent = rcg_mnd_clk_get_parent,
 };
 
 struct clk_ops clk_ops_branch = {
diff --git a/arch/arm/mach-msm/clock-mdss-8974.c b/arch/arm/mach-msm/clock-mdss-8974.c
index 79bc639..aca6494 100644
--- a/arch/arm/mach-msm/clock-mdss-8974.c
+++ b/arch/arm/mach-msm/clock-mdss-8974.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -348,6 +348,16 @@
 	return ret;
 }
 
+static enum handoff mdss_dsi_pll_handoff(struct clk *c)
+{
+	/*
+	 * FIXME: Continuous display is not implemented. So the display is
+	 * always off. Implement a poor man's handoff by always returning
+	 * "disabled".
+	 */
+	return HANDOFF_DISABLED_CLK;
+}
+
 void hdmi_pll_disable(void)
 {
 	clk_enable(mdss_dsi_ahb_clk);
@@ -766,6 +776,7 @@
 	.disable = mdss_dsi_pll_disable,
 	.set_rate = mdss_dsi_pll_pixel_set_rate,
 	.round_rate = mdss_dsi_pll_pixel_round_rate,
+	.handoff = mdss_dsi_pll_handoff,
 };
 
 struct clk_ops clk_ops_dsi_byte_pll = {
@@ -773,4 +784,5 @@
 	.disable = mdss_dsi_pll_disable,
 	.set_rate = mdss_dsi_pll_byte_set_rate,
 	.round_rate = mdss_dsi_pll_byte_round_rate,
+	.handoff = mdss_dsi_pll_handoff,
 };
diff --git a/arch/arm/mach-msm/clock-rpm.c b/arch/arm/mach-msm/clock-rpm.c
index a4def28..c1cc27b 100644
--- a/arch/arm/mach-msm/clock-rpm.c
+++ b/arch/arm/mach-msm/clock-rpm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -285,6 +285,18 @@
 	if (rc < 0)
 		return HANDOFF_DISABLED_CLK;
 
+	/*
+	 * Since RPM handoff code may update the software rate of the clock by
+	 * querying the RPM, we need to make sure our request to RPM now
+	 * matches the software rate of the clock. When we send the request
+	 * to RPM, we also need to update any other state info we would
+	 * normally update. So, call the appropriate clock function instead
+	 * of directly using the RPM driver APIs.
+	 */
+	rc = rpm_clk_prepare(clk);
+	if (rc < 0)
+		return HANDOFF_DISABLED_CLK;
+
 	return HANDOFF_ENABLED_CLK;
 }
 
diff --git a/arch/arm/mach-msm/clock-voter.c b/arch/arm/mach-msm/clock-voter.c
index 7421ba6..c3145ef 100644
--- a/arch/arm/mach-msm/clock-voter.c
+++ b/arch/arm/mach-msm/clock-voter.c
@@ -1,5 +1,4 @@
-/*
- * Copyright (c) 2010-2011, Code Aurora Forum. 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
@@ -139,11 +138,17 @@
 
 static enum handoff voter_clk_handoff(struct clk *clk)
 {
-	/* Apply default rate vote */
-	if (clk->rate)
-		return HANDOFF_ENABLED_CLK;
+	if (!clk->rate)
+		return HANDOFF_DISABLED_CLK;
 
-	return HANDOFF_DISABLED_CLK;
+	/*
+	 * Send the default rate to the parent if necessary and update the
+	 * software state of the voter clock.
+	 */
+	if (voter_clk_prepare(clk) < 0)
+		return HANDOFF_DISABLED_CLK;
+
+	return HANDOFF_ENABLED_CLK;
 }
 
 struct clk_ops clk_ops_voter = {
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index c2bf5ba..e0ee084 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/clock.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-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
@@ -467,56 +467,83 @@
 }
 EXPORT_SYMBOL(msm_clock_register);
 
-static enum handoff __init __handoff_clk(struct clk *clk)
+static int __init __handoff_clk(struct clk *clk)
 {
-	enum handoff ret;
-	struct handoff_clk *h;
-	unsigned long rate;
-	int err = 0;
+	enum handoff state = HANDOFF_DISABLED_CLK;
+	struct handoff_clk *h = NULL;
+	int rc;
+
+	if (clk == NULL || clk->flags & CLKFLAG_INIT_DONE ||
+	    clk->flags & CLKFLAG_SKIP_HANDOFF)
+		return 0;
+
+	if (clk->flags & CLKFLAG_INIT_ERR)
+		return -ENXIO;
+
+	/* Handoff any 'depends' clock first. */
+	rc = __handoff_clk(clk->depends);
+	if (rc)
+		goto err;
 
 	/*
-	 * Tree roots don't have parents, but need to be handed off. So,
-	 * terminate recursion by returning "enabled". Also return "enabled"
-	 * for clocks with non-zero enable counts since they must have already
-	 * been handed off.
+	 * Handoff functions for the parent must be called before the
+	 * children can be handed off. Without handing off the parents and
+	 * knowing their rate and state (on/off), it's impossible to figure
+	 * out the rate and state of the children.
 	 */
-	if (clk == NULL || clk->count)
-		return HANDOFF_ENABLED_CLK;
+	if (clk->ops->get_parent)
+		clk->parent = clk->ops->get_parent(clk);
 
-	/* Clocks without handoff functions are assumed to be disabled. */
-	if (!clk->ops->handoff || (clk->flags & CLKFLAG_SKIP_HANDOFF))
-		return HANDOFF_DISABLED_CLK;
+	if (IS_ERR(clk->parent)) {
+		rc = PTR_ERR(clk->parent);
+		goto err;
+	}
 
-	/*
-	 * Handoff functions for children must be called before their parents'
-	 * so that the correct parent is available below.
-	 */
-	ret = clk->ops->handoff(clk);
-	if (ret == HANDOFF_ENABLED_CLK) {
-		ret = __handoff_clk(clk->parent);
-		if (ret == HANDOFF_ENABLED_CLK) {
-			h = kmalloc(sizeof(*h), GFP_KERNEL);
-			if (!h) {
-				err = -ENOMEM;
-				goto out;
-			}
-			err = clk_prepare_enable(clk);
-			if (err)
-				goto out;
-			rate = clk_get_rate(clk);
-			if (rate)
-				pr_debug("%s rate=%lu\n", clk->dbg_name, rate);
-			h->clk = clk;
-			list_add_tail(&h->list, &handoff_list);
+	rc = __handoff_clk(clk->parent);
+	if (rc)
+		goto err;
+
+	if (clk->ops->handoff)
+		state = clk->ops->handoff(clk);
+
+	if (state == HANDOFF_ENABLED_CLK) {
+
+		h = kmalloc(sizeof(*h), GFP_KERNEL);
+		if (!h) {
+			rc = -ENOMEM;
+			goto err;
 		}
+
+		rc = clk_prepare_enable(clk->parent);
+		if (rc)
+			goto err;
+
+		rc = clk_prepare_enable(clk->depends);
+		if (rc)
+			goto err_depends;
+
+		rc = vote_rate_vdd(clk, clk->rate);
+		WARN(rc, "%s unable to vote for voltage!\n", clk->dbg_name);
+
+		clk->count = 1;
+		clk->prepare_count = 1;
+		h->clk = clk;
+		list_add_tail(&h->list, &handoff_list);
+
+		pr_debug("Handed off %s rate=%lu\n", clk->dbg_name, clk->rate);
 	}
-out:
-	if (err) {
-		pr_err("%s handoff failed (%d)\n", clk->dbg_name, err);
-		kfree(h);
-		ret = HANDOFF_DISABLED_CLK;
-	}
-	return ret;
+
+	clk->flags |= CLKFLAG_INIT_DONE;
+
+	return 0;
+
+err_depends:
+	clk_disable_unprepare(clk->parent);
+err:
+	kfree(h);
+	clk->flags |= CLKFLAG_INIT_ERR;
+	pr_err("%s handoff failed (%d)\n", clk->dbg_name, rc);
+	return rc;
 }
 
 /**
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index c986064..f87c540 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -24,6 +24,7 @@
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
 #include <mach/usbdiag.h>
+#include <mach/msm_serial_hs_lite.h>
 #include <mach/msm_sps.h>
 #include <mach/dma.h>
 #include <mach/msm_dsps.h>
@@ -51,6 +52,7 @@
 
 /* Address of GSBI blocks */
 #define MSM_GSBI1_PHYS		0x12440000
+#define MSM_GSBI2_PHYS		0x12480000
 #define MSM_GSBI3_PHYS		0x16200000
 #define MSM_GSBI4_PHYS		0x16300000
 #define MSM_GSBI5_PHYS		0x1A200000
@@ -59,7 +61,9 @@
 
 /* GSBI UART devices */
 #define MSM_UART1DM_PHYS	(MSM_GSBI1_PHYS + 0x10000)
+#define MSM_UART2DM_PHYS	(MSM_GSBI2_PHYS + 0x10000)
 #define MSM_UART3DM_PHYS	(MSM_GSBI3_PHYS + 0x40000)
+#define MSM_UART4DM_PHYS	(MSM_GSBI4_PHYS + 0x40000)
 #define MSM_UART5DM_PHYS	(MSM_GSBI5_PHYS + 0x40000)
 #define MSM_UART6DM_PHYS	(MSM_GSBI6_PHYS + 0x40000)
 #define MSM_UART7DM_PHYS	(MSM_GSBI7_PHYS + 0x40000)
@@ -203,6 +207,38 @@
 	.resource	= resources_uart_gsbi1,
 };
 
+static struct resource resources_uart_gsbi2[] = {
+	{
+		.start	= APQ8064_GSBI2_UARTDM_IRQ,
+		.end	= APQ8064_GSBI2_UARTDM_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= MSM_UART2DM_PHYS,
+		.end	= MSM_UART2DM_PHYS + PAGE_SIZE - 1,
+		.name	= "uartdm_resource",
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= MSM_GSBI2_PHYS,
+		.end	= MSM_GSBI2_PHYS + PAGE_SIZE - 1,
+		.name	= "gsbi_resource",
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct msm_serial_hslite_platform_data uart_gsbi2_pdata = {
+	.line		= 0,
+};
+
+struct platform_device apq8064_device_uart_gsbi2 = {
+	.name	= "msm_serial_hsl",
+	.id	= 3,
+	.num_resources	= ARRAY_SIZE(resources_uart_gsbi2),
+	.resource	= resources_uart_gsbi2,
+	.dev.platform_data = &uart_gsbi2_pdata,
+};
+
 static struct resource resources_uart_gsbi3[] = {
 	{
 		.start	= GSBI3_UARTDM_IRQ,
@@ -350,6 +386,38 @@
 	.resource	= resources_qup_i2c_gsbi4,
 };
 
+static struct resource resources_uart_gsbi4[] = {
+	{
+		.start	= GSBI4_UARTDM_IRQ,
+		.end	= GSBI4_UARTDM_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= MSM_UART4DM_PHYS,
+		.end	= MSM_UART4DM_PHYS + PAGE_SIZE - 1,
+		.name	= "uartdm_resource",
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= MSM_GSBI4_PHYS,
+		.end	= MSM_GSBI4_PHYS + PAGE_SIZE - 1,
+		.name	= "gsbi_resource",
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct msm_serial_hslite_platform_data uart_gsbi4_pdata = {
+	.line		= 2,
+};
+
+struct platform_device apq8064_device_uart_gsbi4 = {
+	.name	= "msm_serial_hsl",
+	.id	= 4,
+	.num_resources	= ARRAY_SIZE(resources_uart_gsbi4),
+	.resource	= resources_uart_gsbi4,
+	.dev.platform_data = &uart_gsbi4_pdata,
+};
+
 static struct resource resources_qup_spi_gsbi5[] = {
 	{
 		.name   = "spi_base",
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 248af88..8301c29 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -85,7 +85,9 @@
 extern struct platform_device msm8960_device_ebi1_ch1_erp;
 
 extern struct platform_device apq8064_device_uart_gsbi1;
+extern struct platform_device apq8064_device_uart_gsbi2;
 extern struct platform_device apq8064_device_uart_gsbi3;
+extern struct platform_device apq8064_device_uart_gsbi4;
 extern struct platform_device apq8064_device_uart_gsbi7;
 extern struct platform_device apq8064_device_qup_i2c_gsbi1;
 extern struct platform_device apq8064_device_qup_i2c_gsbi3;
diff --git a/arch/arm/mach-msm/include/mach/clk-provider.h b/arch/arm/mach-msm/include/mach/clk-provider.h
index 0f2feaa..475b483 100644
--- a/arch/arm/mach-msm/include/mach/clk-provider.h
+++ b/arch/arm/mach-msm/include/mach/clk-provider.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2007-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
@@ -69,7 +69,6 @@
 enum handoff {
 	HANDOFF_ENABLED_CLK,
 	HANDOFF_DISABLED_CLK,
-	HANDOFF_UNKNOWN_RATE,
 };
 
 struct clk_ops {
diff --git a/arch/arm/mach-msm/include/mach/clk.h b/arch/arm/mach-msm/include/mach/clk.h
index d69b372..1191bb7 100644
--- a/arch/arm/mach-msm/include/mach/clk.h
+++ b/arch/arm/mach-msm/include/mach/clk.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2012 Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 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
@@ -21,6 +21,8 @@
 #define CLKFLAG_SKIP_HANDOFF		0x00000100
 #define CLKFLAG_MIN			0x00000400
 #define CLKFLAG_MAX			0x00000800
+#define CLKFLAG_INIT_DONE		0x00001000
+#define CLKFLAG_INIT_ERR		0x00002000
 
 struct clk_lookup;
 struct clk;
diff --git a/arch/arm/mach-msm/ipc_router_smd_xprt.c b/arch/arm/mach-msm/ipc_router_smd_xprt.c
index 8c0bf4b..5d1b5e4 100644
--- a/arch/arm/mach-msm/ipc_router_smd_xprt.c
+++ b/arch/arm/mach-msm/ipc_router_smd_xprt.c
@@ -40,7 +40,7 @@
 
 #define MIN_FRAG_SZ (IPC_ROUTER_HDR_SIZE + sizeof(union rr_control_msg))
 
-#define NUM_SMD_XPRTS 3
+#define NUM_SMD_XPRTS 4
 #define XPRT_NAME_LEN (SMD_MAX_CH_NAME_LEN + 12)
 
 struct msm_ipc_router_smd_xprt {
@@ -76,6 +76,7 @@
 	{"RPCRPY_CNTL", "ipc_rtr_smd_rpcrpy_cntl", SMD_APPS_MODEM, 1},
 	{"IPCRTR", "ipc_rtr_smd_ipcrtr", SMD_APPS_MODEM, 1},
 	{"IPCRTR", "ipc_rtr_q6_ipcrtr", SMD_APPS_QDSP, 1},
+	{"IPCRTR", "ipc_rtr_wcnss_ipcrtr", SMD_APPS_WCNSS, 1},
 };
 
 static struct msm_ipc_router_smd_xprt smd_remote_xprt[NUM_SMD_XPRTS];
diff --git a/arch/arm/mach-msm/krait-regulator.c b/arch/arm/mach-msm/krait-regulator.c
index dd61db3..aa03a6a 100644
--- a/arch/arm/mach-msm/krait-regulator.c
+++ b/arch/arm/mach-msm/krait-regulator.c
@@ -27,28 +27,28 @@
 #include <linux/regulator/machine.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/regulator/krait-regulator.h>
+#include <linux/debugfs.h>
 #include <mach/msm_iomap.h>
 
 #include "spm.h"
+#include "pm.h"
 
 /*
  *                   supply
  *                   from
  *                   pmic
  *                   gang
- *                    |        LDO BYP [6]
- *                    |         /
- *                    |        /
- *                    |_______/   _____
- *                    |                |
- *                 ___|___             |
- *		  |       |            |
- *		  |       |               /
- *		  |  LDO  |              /
- *		  |       |             /    BHS[6]
- *                |_______|            |
- *                    |                |
- *                    |________________|
+ *                    |
+ *                    |________________________________
+ *                    |                |               |
+ *                 ___|___             |               |
+ *		  |       |            |               |
+ *		  |       |               /               /
+ *		  |  LDO  |              /               /LDO BYP [6]
+ *		  |       |             /    BHS[6]     /(bypass is a weak BHS
+ *                |_______|            |               |  needs to be on when in
+ *                    |                |               |  BHS mode)
+ *                    |________________|_______________|
  *                    |
  *            ________|________
  *           |                 |
@@ -88,6 +88,10 @@
 #define PWR_GATE_CONFIG		0x00000044
 #define VERSION			0x00000FD0
 
+/* MDD register group */
+#define MDD_CONFIG_CTL		0x00000000
+#define MDD_MODE		0x00000010
+
 /* bit definitions for APC_PWR_GATE_CTL */
 #define BHS_CNT_BIT_POS		24
 #define BHS_CNT_MASK		KRAIT_MASK(31, 24)
@@ -117,6 +121,18 @@
 #define VREF_LDO_BIT_POS	0
 #define VREF_LDO_MASK		KRAIT_MASK(6, 0)
 
+#define LDO_HDROOM_MIN		50000
+#define LDO_HDROOM_MAX		250000
+
+#define LDO_UV_MIN		465000
+#define LDO_UV_MAX		750000
+
+#define LDO_TH_MIN		600000
+#define LDO_TH_MAX		900000
+
+#define LDO_DELTA_MIN		10000
+#define LDO_DELTA_MAX		100000
+
 /**
  * struct pmic_gang_vreg -
  * @name:			the string used to represent the gang
@@ -136,6 +152,8 @@
 	struct list_head	krait_power_vregs;
 	struct mutex		krait_power_vregs_lock;
 	bool			pfm_mode;
+	int			pmic_min_uV_for_retention;
+	bool			retention_enabled;
 };
 
 static struct pmic_gang_vreg *the_gang;
@@ -155,15 +173,26 @@
 	int				load_uA;
 	enum krait_supply_mode		mode;
 	void __iomem			*reg_base;
+	void __iomem			*mdd_base;
 	int				ldo_default_uV;
 	int				retention_uV;
 	int				headroom_uV;
 	int				ldo_threshold_uV;
+	int				ldo_delta_uV;
 	bool				online;
 };
 
 static u32 version;
 
+static int is_between(int left, int right, int value)
+{
+	if (left >= right && left >= value && value >= right)
+		return 1;
+	if (left <= right && left <= value && value <= right)
+		return 1;
+	return 0;
+}
+
 static void krait_masked_write(struct krait_power_vreg *kvreg,
 					int reg, uint32_t mask, uint32_t val)
 {
@@ -182,6 +211,23 @@
 	mb();
 }
 
+static int get_krait_retention_ldo_uv(struct krait_power_vreg *kvreg)
+{
+	uint32_t reg_val;
+	int uV;
+
+	reg_val = readl_relaxed(kvreg->reg_base + APC_LDO_VREF_SET);
+	reg_val &= VREF_RET_MASK;
+	reg_val >>= VREF_RET_POS;
+
+	if (reg_val == 0)
+		uV = 0;
+	else
+		uV = KRAIT_LDO_VOLTAGE_OFFSET + reg_val * KRAIT_LDO_STEP;
+
+	return uV;
+}
+
 static int get_krait_ldo_uv(struct krait_power_vreg *kvreg)
 {
 	uint32_t reg_val;
@@ -225,15 +271,13 @@
 {
 	if (kvreg->mode == HS_MODE)
 		return 0;
-
-	/*
-	 * enable ldo bypass - the krait is powered still by LDO since
-	 * LDO is enabled and BHS is disabled
-	 */
-	krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_BYP_MASK, LDO_BYP_MASK);
-
 	/* enable bhs */
-	krait_masked_write(kvreg, APC_PWR_GATE_CTL, BHS_EN_MASK, BHS_EN_MASK);
+	krait_masked_write(kvreg, APC_PWR_GATE_CTL,
+		BHS_SEG_EN_MASK | BHS_EN_MASK,
+		BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS | BHS_EN_MASK);
+
+	/* complete the above write before the delay */
+	mb();
 
 	/*
 	 * wait for the bhs to settle - note that
@@ -242,6 +286,12 @@
 	 */
 	udelay(BHS_SETTLING_DELAY_US);
 
+	/*
+	 * enable ldo bypass - the krait is powered still by LDO since
+	 * LDO is enabled
+	 */
+	krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_BYP_MASK, LDO_BYP_MASK);
+
 	/* disable ldo - only the BHS provides voltage to the cpu after this */
 	krait_masked_write(kvreg, APC_PWR_GATE_CTL,
 				LDO_PWR_DWN_MASK, LDO_PWR_DWN_MASK);
@@ -253,7 +303,8 @@
 
 static int switch_to_using_ldo(struct krait_power_vreg *kvreg)
 {
-	if (kvreg->mode == LDO_MODE && get_krait_ldo_uv(kvreg) == kvreg->uV)
+	if (kvreg->mode == LDO_MODE
+		&& get_krait_ldo_uv(kvreg) == kvreg->uV - kvreg->ldo_delta_uV)
 		return 0;
 
 	/*
@@ -263,7 +314,7 @@
 	if (kvreg->mode == LDO_MODE)
 		switch_to_using_hs(kvreg);
 
-	set_krait_ldo_uv(kvreg, kvreg->uV);
+	set_krait_ldo_uv(kvreg, kvreg->uV - kvreg->ldo_delta_uV);
 
 	/*
 	 * enable ldo - note that both LDO and BHS are are supplying voltage to
@@ -272,6 +323,9 @@
 	 */
 	krait_masked_write(kvreg, APC_PWR_GATE_CTL, LDO_PWR_DWN_MASK, 0);
 
+	/* complete the writes before the delay */
+	mb();
+
 	/* wait for the ldo to settle */
 	udelay(LDO_SETTLING_DELAY_US);
 
@@ -281,6 +335,7 @@
 	 */
 	krait_masked_write(kvreg, APC_PWR_GATE_CTL,
 		BHS_EN_MASK | LDO_BYP_MASK, 0);
+	krait_masked_write(kvreg, APC_PWR_GATE_CTL, BHS_SEG_EN_MASK, 0);
 
 	kvreg->mode = LDO_MODE;
 	pr_debug("%s using LDO\n", kvreg->name);
@@ -317,6 +372,22 @@
 		uV = PMIC_VOLTAGE_MAX;
 	}
 
+	if (uV < pvreg->pmic_min_uV_for_retention) {
+		if (pvreg->retention_enabled) {
+			pr_debug("Disabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
+					uV, pvreg->pmic_min_uV_for_retention);
+			msm_pm_enable_retention(false);
+			pvreg->retention_enabled = false;
+		}
+	} else {
+		if (!pvreg->retention_enabled) {
+			pr_debug("Enabling Retention pmic = %duV, pmic_min_uV_for_retention = %duV",
+					uV, pvreg->pmic_min_uV_for_retention);
+			msm_pm_enable_retention(true);
+			pvreg->retention_enabled = true;
+		}
+	}
+
 	setpoint = DIV_ROUND_UP(uV, LV_RANGE_STEP);
 
 	rc = msm_spm_apcs_set_vdd(setpoint);
@@ -338,18 +409,19 @@
 	list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
 		if (!kvreg->online)
 			continue;
-		if (kvreg->uV > kvreg->ldo_threshold_uV
-			 || kvreg->uV > vmax - kvreg->headroom_uV) {
-			rc = switch_to_using_hs(kvreg);
+		if (kvreg->uV <= kvreg->ldo_threshold_uV
+			&& kvreg->uV - kvreg->ldo_delta_uV + kvreg->headroom_uV
+				<= vmax) {
+			rc = switch_to_using_ldo(kvreg);
 			if (rc < 0) {
-				pr_err("could not switch %s to hs rc = %d\n",
+				pr_err("could not switch %s to ldo rc = %d\n",
 							kvreg->name, rc);
 				return rc;
 			}
 		} else {
-			rc = switch_to_using_ldo(kvreg);
+			rc = switch_to_using_hs(kvreg);
 			if (rc < 0) {
-				pr_err("could not switch %s to ldo rc = %d\n",
+				pr_err("could not switch %s to hs rc = %d\n",
 							kvreg->name, rc);
 				return rc;
 			}
@@ -378,6 +450,10 @@
 		return rc;
 	}
 
+
+	/* complete the above writes before the delay */
+	mb();
+
 	/* delay until the voltage is settled when it is raised */
 	settling_us = DIV_ROUND_UP(vmax - pvreg->pmic_vmax_uV, SLEW_RATE);
 	udelay(settling_us);
@@ -438,6 +514,9 @@
 			return rc;
 		}
 
+		/* complete the writes before the delay */
+		mb();
+
 		/*
 		 * delay until the phases are settled when
 		 * the count is raised
@@ -464,6 +543,8 @@
 	pvreg->name = "pmic_gang";
 	pvreg->pmic_vmax_uV = PMIC_VOLTAGE_MIN;
 	pvreg->pmic_phase_count = 1;
+	pvreg->retention_enabled = true;
+	pvreg->pmic_min_uV_for_retention = INT_MAX;
 
 	mutex_init(&pvreg->krait_power_vregs_lock);
 	INIT_LIST_HEAD(&pvreg->krait_power_vregs);
@@ -722,24 +803,57 @@
 	.is_enabled		= krait_power_is_enabled,
 };
 
+static struct dentry *dent;
+static int get_retention_dbg_uV(void *data, u64 *val)
+{
+	struct pmic_gang_vreg *pvreg = data;
+	struct krait_power_vreg *kvreg;
+
+	mutex_lock(&pvreg->krait_power_vregs_lock);
+	if (!list_empty(&pvreg->krait_power_vregs)) {
+		/* return the retention voltage on just the first cpu */
+		kvreg = list_entry((&pvreg->krait_power_vregs)->next,
+			typeof(*kvreg), link);
+		*val = get_krait_retention_ldo_uv(kvreg);
+	}
+	mutex_unlock(&pvreg->krait_power_vregs_lock);
+	return 0;
+}
+
+static int set_retention_dbg_uV(void *data, u64 val)
+{
+	struct pmic_gang_vreg *pvreg = data;
+	struct krait_power_vreg *kvreg;
+	int retention_uV = val;
+
+	if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV))
+		return -EINVAL;
+
+	mutex_lock(&pvreg->krait_power_vregs_lock);
+	list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
+		kvreg->retention_uV = retention_uV;
+		set_krait_retention_uv(kvreg, retention_uV);
+	}
+	mutex_unlock(&pvreg->krait_power_vregs_lock);
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(retention_fops,
+			get_retention_dbg_uV, set_retention_dbg_uV, "%llu\n");
+
 static void kvreg_hw_init(struct krait_power_vreg *kvreg)
 {
 	/*
 	 * bhs_cnt value sets the ramp-up time from power collapse,
 	 * initialize the ramp up time
 	 */
-	krait_masked_write(kvreg, APC_PWR_GATE_CTL,
-		BHS_CNT_MASK, BHS_CNT_DEFAULT << BHS_CNT_BIT_POS);
-
-	krait_masked_write(kvreg, APC_PWR_GATE_CTL,
-		CLK_SRC_SEL_MASK, CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS);
-
-	/* BHS has six different segments, turn them all on */
-	krait_masked_write(kvreg, APC_PWR_GATE_CTL,
-		BHS_SEG_EN_MASK, BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS);
-
 	set_krait_retention_uv(kvreg, kvreg->retention_uV);
 	set_krait_ldo_uv(kvreg, kvreg->ldo_default_uV);
+
+	/* setup the bandgap that configures the reference to the LDO */
+	writel_relaxed(0x00000190, kvreg->mdd_base + MDD_CONFIG_CTL);
+	/* Enable MDD */
+	writel_relaxed(0x00000002, kvreg->mdd_base + MDD_MODE);
+	mb();
 }
 
 static void glb_init(struct platform_device *pdev)
@@ -751,31 +865,14 @@
 	pr_debug("version= 0x%x\n", version);
 }
 
-static int is_between(int left, int right, int value)
-{
-	if (left >= right && left >= value && value >= right)
-		return 1;
-	if (left <= right && left <= value && value <= right)
-		return 1;
-	return 0;
-}
-
-#define LDO_HDROOM_MIN		50000
-#define LDO_HDROOM_MAX		250000
-
-#define LDO_UV_MIN		465000
-#define LDO_UV_MAX		750000
-
-#define LDO_TH_MIN		600000
-#define LDO_TH_MAX		800000
-
 static int __devinit krait_power_probe(struct platform_device *pdev)
 {
 	struct krait_power_vreg *kvreg;
-	struct resource *res;
+	struct resource *res, *res_mdd;
 	struct regulator_init_data *init_data = pdev->dev.platform_data;
 	int rc = 0;
 	int headroom_uV, retention_uV, ldo_default_uV, ldo_threshold_uV;
+	int ldo_delta_uV;
 
 	/* Initialize the pmic gang if it hasn't been initialized already */
 	if (the_gang == NULL) {
@@ -789,6 +886,12 @@
 		glb_init(pdev);
 	}
 
+	if (dent == NULL) {
+		dent = debugfs_create_dir(KRAIT_REGULATOR_DRIVER_NAME, NULL);
+		debugfs_create_file("retention_uV",
+				0644, dent, the_gang, &retention_fops);
+	}
+
 	if (pdev->dev.of_node) {
 		/* Get init_data from device tree. */
 		init_data = of_get_regulator_init_data(&pdev->dev,
@@ -851,6 +954,19 @@
 					ldo_threshold_uV);
 			return -EINVAL;
 		}
+
+		rc = of_property_read_u32(pdev->dev.of_node,
+					"qcom,ldo-delta-voltage",
+					&ldo_delta_uV);
+		if (rc < 0) {
+			pr_err("ldo-delta-voltage missing rc=%d\n", rc);
+			return rc;
+		}
+		if (!is_between(LDO_DELTA_MIN, LDO_DELTA_MAX, ldo_delta_uV)) {
+			pr_err("bad ldo-delta-voltage = %d specified\n",
+					ldo_delta_uV);
+			return -EINVAL;
+		}
 	}
 
 	if (!init_data) {
@@ -864,12 +980,18 @@
 		return -EINVAL;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acs");
 	if (!res) {
 		dev_err(&pdev->dev, "missing physical register addresses\n");
 		return -EINVAL;
 	}
 
+	res_mdd = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mdd");
+	if (!res_mdd) {
+		dev_err(&pdev->dev, "missing mdd register addresses\n");
+		return -EINVAL;
+	}
+
 	kvreg = devm_kzalloc(&pdev->dev,
 			sizeof(struct krait_power_vreg), GFP_KERNEL);
 	if (!kvreg) {
@@ -880,6 +1002,9 @@
 	kvreg->reg_base = devm_ioremap(&pdev->dev,
 				res->start, resource_size(res));
 
+	kvreg->mdd_base = devm_ioremap(&pdev->dev,
+				res_mdd->start, resource_size(res));
+
 	kvreg->pvreg		= the_gang;
 	kvreg->name		= init_data->constraints.name;
 	kvreg->desc.name	= kvreg->name;
@@ -893,10 +1018,14 @@
 	kvreg->retention_uV	= retention_uV;
 	kvreg->ldo_default_uV	= ldo_default_uV;
 	kvreg->ldo_threshold_uV = ldo_threshold_uV;
+	kvreg->ldo_delta_uV	= ldo_delta_uV;
 
 	platform_set_drvdata(pdev, kvreg);
 
 	mutex_lock(&the_gang->krait_power_vregs_lock);
+	the_gang->pmic_min_uV_for_retention
+		= min(the_gang->pmic_min_uV_for_retention,
+			kvreg->retention_uV + kvreg->headroom_uV);
 	list_add_tail(&kvreg->link, &the_gang->krait_power_vregs);
 	mutex_unlock(&the_gang->krait_power_vregs_lock);
 
@@ -959,25 +1088,36 @@
 {
 	platform_driver_unregister(&krait_power_driver);
 }
-
 module_exit(krait_power_exit);
 
 void secondary_cpu_hs_init(void *base_ptr)
 {
-	/* 605mV retention and 705mV operational voltage */
-	writel_relaxed(0x1C30, base_ptr + APC_LDO_VREF_SET);
-	/* HS_EN_DLY=3; LDO_BYP_DLY=1; */
-	writel_relaxed(0x430000, base_ptr + APC_PWR_GATE_DLY);
-	/* MODE = BHS; EN=1; */
-	writel_relaxed(0x21, base_ptr + APC_PWR_GATE_MODE);
-
 	/* Turn on the BHS, turn off LDO Bypass and power down LDO */
-	writel_relaxed(0x403F007F, base_ptr + APC_PWR_GATE_CTL);
+	writel_relaxed(
+		BHS_CNT_DEFAULT << BHS_CNT_BIT_POS
+		| LDO_PWR_DWN_MASK
+		| CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS
+		| BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS
+		| BHS_EN_MASK,
+		base_ptr + APC_PWR_GATE_CTL);
+
+	/* complete the above write before the delay */
 	mb();
-	udelay(1);
+
+	/*
+	 * wait for the bhs to settle
+	 */
+	udelay(BHS_SETTLING_DELAY_US);
 
 	/* Finally turn on the bypass so that BHS supplies power */
-	writel_relaxed(0x403F3F7F, base_ptr + APC_PWR_GATE_CTL);
+	writel_relaxed(
+		BHS_CNT_DEFAULT << BHS_CNT_BIT_POS
+		| LDO_PWR_DWN_MASK
+		| CLK_SRC_DEFAULT << CLK_SRC_SEL_BIT_POS
+		| LDO_BYP_MASK
+		| BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS
+		| BHS_EN_MASK,
+		base_ptr + APC_PWR_GATE_CTL);
 }
 
 MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/lpm_levels.c b/arch/arm/mach-msm/lpm_levels.c
index b84d345..463f2a5 100644
--- a/arch/arm/mach-msm/lpm_levels.c
+++ b/arch/arm/mach-msm/lpm_levels.c
@@ -353,6 +353,9 @@
 
 	lpm_test_pdata.msm_lpm_test_levels = msm_lpm_levels;
 	lpm_test_pdata.msm_lpm_test_level_count = msm_lpm_level_count;
+	key = "qcom,use-qtimer";
+	lpm_test_pdata.use_qtimer =
+			of_property_read_bool(pdev->dev.of_node, key);
 
 	for_each_possible_cpu(m_cpu)
 		per_cpu(lpm_permitted_level, m_cpu) =
diff --git a/arch/arm/mach-msm/pm-data.c b/arch/arm/mach-msm/pm-data.c
index 08cdf5d..ccc2519 100644
--- a/arch/arm/mach-msm/pm-data.c
+++ b/arch/arm/mach-msm/pm-data.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils.c b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
index 6a23e37..33bbac0 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -19,7 +19,7 @@
 #include <linux/wait.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
 #include <asm/ioctls.h>
 #include "audio_utils.h"
 
@@ -109,8 +109,8 @@
 
 		rc = q6asm_cmd(audio->ac, CMD_CLOSE);
 		if (rc < 0)
-			pr_err("%s:session id %d: Failed to close the"
-				"session rc=%d\n", __func__, audio->ac->session,
+			pr_err("%s:session id %d: Failed to close the session rc=%d\n",
+				__func__, audio->ac->session,
 				rc);
 		audio->stopped = 1;
 		memset(audio->out_frame_info, 0,
@@ -135,8 +135,8 @@
 				ALIGN_BUF_SIZE(audio->pcm_cfg.buffer_size),
 				audio->pcm_cfg.buffer_count);
 			if (rc < 0) {
-				pr_err("%s:session id %d: Buffer Alloc"
-						"failed\n", __func__,
+				pr_err("%s:session id %d: Buffer Alloc failed\n",
+						__func__,
 						audio->ac->session);
 				rc = -ENOMEM;
 				break;
@@ -172,8 +172,8 @@
 				ALIGN_BUF_SIZE(audio->pcm_cfg.buffer_size),
 				audio->pcm_cfg.buffer_count);
 			if (rc < 0) {
-				pr_err("%s:session id %d: Buffer Alloc"
-					"failed\n", __func__,
+				pr_err("%s:session id %d: Buffer Alloc failed\n",
+					__func__,
 					audio->ac->session);
 				rc = -ENOMEM;
 				break;
@@ -303,15 +303,15 @@
 		}
 		audio->buf_cfg.meta_info_enable = cfg.meta_info_enable;
 		audio->buf_cfg.frames_per_buf = cfg.frames_per_buf;
-		pr_debug("%s:session id %d: Set-buf-cfg: meta[%d]"
-				"framesperbuf[%d]\n", __func__,
+		pr_debug("%s:session id %d: Set-buf-cfg: meta[%d] framesperbuf[%d]\n",
+				__func__,
 				audio->ac->session, cfg.meta_info_enable,
 				cfg.frames_per_buf);
 		break;
 	}
 	case AUDIO_GET_BUF_CFG: {
-		pr_debug("%s:session id %d: Get-buf-cfg: meta[%d]"
-			"framesperbuf[%d]\n", __func__,
+		pr_debug("%s:session id %d: Get-buf-cfg: meta[%d] framesperbuf[%d]\n",
+			__func__,
 			audio->ac->session, audio->buf_cfg.meta_info_enable,
 			audio->buf_cfg.frames_per_buf);
 
@@ -334,8 +334,8 @@
 			break;
 		}
 		if (audio->feedback != NON_TUNNEL_MODE) {
-			pr_err("%s:session id %d: Not sufficient permission to"
-					"change the record mode\n", __func__,
+			pr_err("%s:session id %d: Not sufficient permission to change the record mode\n",
+					__func__,
 					audio->ac->session);
 			rc = -EACCES;
 			break;
@@ -399,15 +399,22 @@
 			audio->read_wait,
 			((atomic_read(&audio->out_count) > 0) ||
 			(audio->stopped) ||
-			 audio->rflush || audio->eos_rsp));
+			 audio->rflush || audio->eos_rsp ||
+			audio->event_abort));
+
+		if (audio->event_abort) {
+			rc = -EIO;
+			break;
+		}
+
 
 		if (rc < 0)
 			break;
 
 		if ((audio->stopped && !(atomic_read(&audio->out_count))) ||
 			audio->rflush) {
-			pr_debug("%s:session id %d: driver in stop state or"
-				"flush,No more buf to read", __func__,
+			pr_debug("%s:session id %d: driver in stop state or flush,No more buf to read",
+				__func__,
 				audio->ac->session);
 			rc = 0;/* End of File */
 			break;
@@ -473,8 +480,8 @@
 			count -= bytes_to_copy;
 			buf += bytes_to_copy;
 		} else {
-			pr_err("%s:session id %d: short read data[%p]"
-				"bytesavail[%d]bytesrequest[%d]\n", __func__,
+			pr_err("%s:session id %d: short read data[%p] bytesavail[%d]bytesrequest[%d]\n",
+				__func__,
 				audio->ac->session,
 				data, size, count);
 		}
@@ -529,7 +536,13 @@
 		rc = wait_event_interruptible(audio->write_wait,
 				     ((atomic_read(&audio->in_count) > 0) ||
 				      (audio->stopped) ||
-				      (audio->wflush)));
+				      (audio->wflush) || (audio->event_abort)));
+
+		if (audio->event_abort) {
+			rc = -EIO;
+			break;
+		}
+
 		if (rc < 0)
 			break;
 		if (audio->stopped || audio->wflush) {
@@ -554,8 +567,8 @@
 						&nflags);
 			buf += mfield_size;
 			/* send the EOS and return */
-			pr_debug("%s:session id %d: send EOS"
-				"0x%8x\n", __func__,
+			pr_debug("%s:session id %d: send EOS 0x%8x\n",
+				__func__,
 				audio->ac->session, nflags);
 			break;
 		}
@@ -582,8 +595,8 @@
 				buf += mfield_size;
 				count -= mfield_size;
 			} else {
-				pr_debug("%s:session id %d: continuous"
-				"buffer\n", __func__, audio->ac->session);
+				pr_debug("%s:session id %d: continuous buffer\n",
+						__func__, audio->ac->session);
 			}
 		}
 		xfer = (count > (audio->pcm_cfg.buffer_size)) ?
@@ -603,8 +616,8 @@
 		buf += xfer;
 	}
 	mutex_unlock(&audio->write_lock);
-	pr_debug("%s:session id %d: eos_condition 0x%8x buf[0x%x]"
-			"start[0x%x]\n", __func__, audio->ac->session,
+	pr_debug("%s:session id %d: eos_condition 0x%8x buf[0x%x] start[0x%x]\n",
+				__func__, audio->ac->session,
 				nflags,	(int) buf, (int) start);
 	if (nflags & AUD_EOS_SET) {
 		rc = q6asm_cmd(audio->ac, CMD_EOS);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils.h b/arch/arm/mach-msm/qdsp6v2/audio_utils.h
index df963f9..7209724 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils.h
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -30,13 +30,13 @@
 struct timestamp {
 	unsigned long lowpart;
 	unsigned long highpart;
-} __attribute__ ((packed));
+} __packed;
 
 struct meta_in {
 	unsigned short offset;
 	struct timestamp ntimestamp;
 	unsigned int nflags;
-} __attribute__ ((packed));
+} __packed;
 
 struct meta_out_dsp {
 	u32 offset_to_frame;
@@ -45,12 +45,12 @@
 	u32 msw_ts;
 	u32 lsw_ts;
 	u32 nflags;
-} __attribute__ ((packed));
+} __packed;
 
 struct meta_out {
 	unsigned char num_of_frames;
 	struct meta_out_dsp meta_out_dsp[];
-} __attribute__ ((packed));
+} __packed;
 
 struct q6audio_in {
 	spinlock_t			dsp_lock;
@@ -80,6 +80,7 @@
 	int				opened;
 	int				enabled;
 	int				stopped;
+	int				event_abort;
 	int				feedback; /* Flag indicates whether used
 							in Non Tunnel mode */
 	int				rflush;
diff --git a/arch/arm/mach-msm/qdsp6v2/evrc_in.c b/arch/arm/mach-msm/qdsp6v2/evrc_in.c
index b95d659..a785266 100644
--- a/arch/arm/mach-msm/qdsp6v2/evrc_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/evrc_in.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -20,7 +20,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/msm_audio_qcp.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
 #include <asm/ioctls.h>
 #include "audio_utils.h"
 
@@ -64,8 +64,8 @@
 			enc_cfg->max_bit_rate, 0);
 
 		if (rc < 0) {
-			pr_err("%s:session id %d: cmd evrc media format block"
-				"failed\n", __func__, audio->ac->session);
+			pr_err("%s:session id %d: cmd evrc media format block failed\n",
+					__func__, audio->ac->session);
 			break;
 		}
 		if (audio->feedback == NON_TUNNEL_MODE) {
@@ -74,8 +74,8 @@
 				audio->pcm_cfg.channel_count);
 
 			if (rc < 0) {
-				pr_err("%s:session id %d: media format block"
-				"failed\n", __func__, audio->ac->session);
+				pr_err("%s:session id %d: media format block failed\n",
+					__func__, audio->ac->session);
 				break;
 			}
 		}
@@ -86,8 +86,8 @@
 			audio->enabled = 1;
 		} else {
 			audio->enabled = 0;
-			pr_err("%s:session id %d: Audio Start procedure failed"
-				"rc=%d\n", __func__, audio->ac->session, rc);
+			pr_err("%s:session id %d: Audio Start procedure failed rc=%d\n",
+					__func__, audio->ac->session, rc);
 			break;
 		}
 		while (cnt++ < audio->str_cfg.buffer_count)
@@ -102,8 +102,8 @@
 				audio->ac->session);
 		rc = audio_in_disable(audio);
 		if (rc  < 0) {
-			pr_err("%s:session id %d: Audio Stop procedure failed"
-				"rc=%d\n", __func__, audio->ac->session, rc);
+			pr_err("%s:session id %d: Audio Stop procedure failed rc=%d\n",
+				__func__, audio->ac->session, rc);
 			break;
 		}
 		break;
@@ -143,8 +143,8 @@
 		}
 		enc_cfg->min_bit_rate = cfg.min_bit_rate;
 		enc_cfg->max_bit_rate = cfg.max_bit_rate;
-		pr_debug("%s:session id %d: min_bit_rate= 0x%x"
-			"max_bit_rate=0x%x\n", __func__,
+		pr_debug("%s:session id %d: min_bit_rate= 0x%x max_bit_rate=0x%x\n",
+			__func__,
 			audio->ac->session, enc_cfg->min_bit_rate,
 			enc_cfg->max_bit_rate);
 		break;
@@ -164,16 +164,16 @@
 	audio = kzalloc(sizeof(struct q6audio_in), GFP_KERNEL);
 
 	if (audio == NULL) {
-		pr_err("%s: Could not allocate memory for evrc"
-				"driver\n", __func__);
+		pr_err("%s: Could not allocate memory for evrc driver\n",
+				__func__);
 		return -ENOMEM;
 	}
 	/* Allocate memory for encoder config param */
 	audio->enc_cfg = kzalloc(sizeof(struct msm_audio_evrc_enc_config),
 				GFP_KERNEL);
 	if (audio->enc_cfg == NULL) {
-		pr_err("%s:session id %d: Could not allocate memory for aac"
-				"config param\n", __func__, audio->ac->session);
+		pr_err("%s:session id %d: Could not allocate memory for aac config param\n",
+				__func__, audio->ac->session);
 		kfree(audio);
 		return -ENOMEM;
 	}
@@ -200,13 +200,14 @@
 	audio->pcm_cfg.sample_rate = 8000;
 	audio->buf_cfg.meta_info_enable = 0x01;
 	audio->buf_cfg.frames_per_buf = 0x01;
+	audio->event_abort = 0;
 
 	audio->ac = q6asm_audio_client_alloc((app_cb)q6asm_in_cb,
 				(void *)audio);
 
 	if (!audio->ac) {
-		pr_err("%s: Could not allocate memory for audio"
-				"client\n", __func__);
+		pr_err("%s: Could not allocate memory for audio client\n",
+				__func__);
 		kfree(audio->enc_cfg);
 		kfree(audio);
 		return -ENOMEM;
@@ -239,8 +240,8 @@
 		/* register for tx overflow (valid for tunnel mode only) */
 		rc = q6asm_reg_tx_overflow(audio->ac, 0x01);
 		if (rc < 0) {
-			pr_err("%s:session id %d: TX Overflow registration"
-				"failed rc=%d\n", __func__,
+			pr_err("%s:session id %d: TX Overflow registration failed rc=%d\n",
+				__func__,
 				audio->ac->session, rc);
 			rc = -ENODEV;
 			goto fail;
diff --git a/arch/arm/mach-msm/qdsp6v2/q6audio_v2.c b/arch/arm/mach-msm/qdsp6v2/q6audio_v2.c
index 0db1ef4..7786fc0 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6audio_v2.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6audio_v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -19,7 +19,7 @@
 #include <linux/wait.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
 #include <asm/ioctls.h>
 #include "audio_utils.h"
 
@@ -51,6 +51,14 @@
 		pr_err("%s:session id %d: ASM_SESSION_EVENT_TX_OVERFLOW\n",
 			__func__, audio->ac->session);
 		break;
+	case RESET_EVENTS:
+		pr_debug("%s:received RESET EVENTS\n", __func__);
+		audio->enabled = 0;
+		audio->stopped = 1;
+		audio->event_abort = 1;
+		wake_up(&audio->read_wait);
+		wake_up(&audio->write_wait);
+		break;
 	default:
 		pr_debug("%s:session id %d: Ignore opcode[0x%x]\n", __func__,
 			audio->ac->session, opcode);
diff --git a/arch/arm/mach-msm/qdsp6v2/qcelp_in.c b/arch/arm/mach-msm/qdsp6v2/qcelp_in.c
index a48df39..3a5411e 100644
--- a/arch/arm/mach-msm/qdsp6v2/qcelp_in.c
+++ b/arch/arm/mach-msm/qdsp6v2/qcelp_in.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -20,7 +20,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/msm_audio_qcp.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
 #include <asm/ioctls.h>
 #include "audio_utils.h"
 
@@ -64,8 +64,8 @@
 			enc_cfg->max_bit_rate, 0, 0);
 
 		if (rc < 0) {
-			pr_err("%s:session id %d: cmd qcelp media format block"
-				"failed\n", __func__, audio->ac->session);
+			pr_err("%s:session id %d: cmd qcelp media format block failed\n",
+					__func__, audio->ac->session);
 			break;
 		}
 		if (audio->feedback == NON_TUNNEL_MODE) {
@@ -74,8 +74,8 @@
 				audio->pcm_cfg.channel_count);
 
 			if (rc < 0) {
-				pr_err("%s:session id %d: media format block"
-				"failed\n", __func__, audio->ac->session);
+				pr_err("%s:session id %d: media format block failed\n",
+					__func__, audio->ac->session);
 				break;
 			}
 		}
@@ -86,8 +86,8 @@
 			audio->enabled = 1;
 		} else {
 			audio->enabled = 0;
-			pr_err("%s:session id %d: Audio Start procedure failed"
-				"rc=%d\n", __func__, audio->ac->session, rc);
+			pr_err("%s:session id %d: Audio Start procedure failed rc=%d\n",
+					__func__, audio->ac->session, rc);
 			break;
 		}
 		while (cnt++ < audio->str_cfg.buffer_count)
@@ -102,8 +102,8 @@
 				audio->ac->session);
 		rc = audio_in_disable(audio);
 		if (rc  < 0) {
-			pr_err("%s:session id %d: Audio Stop procedure failed"
-					"rc=%d\n", __func__, audio->ac->session,
+			pr_err("%s:session id %d: Audio Stop procedure failed rc=%d\n",
+				__func__, audio->ac->session,
 					rc);
 			break;
 		}
@@ -141,8 +141,8 @@
 		}
 		enc_cfg->min_bit_rate = cfg.min_bit_rate;
 		enc_cfg->max_bit_rate = cfg.max_bit_rate;
-		pr_debug("%s:session id %d: min_bit_rate= 0x%x"
-			"max_bit_rate=0x%x\n", __func__,
+		pr_debug("%s:session id %d: min_bit_rate= 0x%x max_bit_rate=0x%x\n",
+			__func__,
 			audio->ac->session, enc_cfg->min_bit_rate,
 			enc_cfg->max_bit_rate);
 		break;
@@ -162,16 +162,16 @@
 	audio = kzalloc(sizeof(struct q6audio_in), GFP_KERNEL);
 
 	if (audio == NULL) {
-		pr_err("%s: Could not allocate memory for qcelp"
-				"driver\n", __func__);
+		pr_err("%s: Could not allocate memory for qcelp driver\n",
+				__func__);
 		return -ENOMEM;
 	}
 	/* Allocate memory for encoder config param */
 	audio->enc_cfg = kzalloc(sizeof(struct msm_audio_qcelp_enc_config),
 				GFP_KERNEL);
 	if (audio->enc_cfg == NULL) {
-		pr_err("%s:session id %d: Could not allocate memory for aac"
-				"config param\n", __func__, audio->ac->session);
+		pr_err("%s:session id %d: Could not allocate memory for aac config param\n",
+				__func__, audio->ac->session);
 		kfree(audio);
 		return -ENOMEM;
 	}
@@ -199,13 +199,14 @@
 	audio->pcm_cfg.sample_rate = 8000;
 	audio->buf_cfg.meta_info_enable = 0x01;
 	audio->buf_cfg.frames_per_buf = 0x01;
+	audio->event_abort = 0;
 
 	audio->ac = q6asm_audio_client_alloc((app_cb)q6asm_in_cb,
 				(void *)audio);
 
 	if (!audio->ac) {
-		pr_err("%s: Could not allocate memory for audio"
-				"client\n", __func__);
+		pr_err("%s: Could not allocate memory for audio client\n",
+				__func__);
 		kfree(audio->enc_cfg);
 		kfree(audio);
 		return -ENOMEM;
@@ -238,8 +239,8 @@
 		/* register for tx overflow (valid for tunnel mode only) */
 		rc = q6asm_reg_tx_overflow(audio->ac, 0x01);
 		if (rc < 0) {
-			pr_err("%s:session id %d: TX Overflow registration"
-			"failed rc=%d\n", __func__, audio->ac->session, rc);
+			pr_err("%s:session id %d: TX Overflow registration failed rc=%d\n",
+				__func__, audio->ac->session, rc);
 			rc = -ENODEV;
 			goto fail;
 		}
diff --git a/drivers/coresight/coresight-csr.c b/drivers/coresight/coresight-csr.c
index 1f6bd1d..e734ece 100644
--- a/drivers/coresight/coresight-csr.c
+++ b/drivers/coresight/coresight-csr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* 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
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/slab.h>
+#include <linux/of.h>
 #include <linux/of_coresight.h>
 #include <linux/coresight.h>
 
@@ -74,6 +75,7 @@
 	void __iomem		*base;
 	struct device		*dev;
 	struct coresight_device	*csdev;
+	uint32_t		blksize;
 };
 
 static struct csr_drvdata *csrdrvdata;
@@ -86,7 +88,7 @@
 	CSR_UNLOCK(drvdata);
 
 	usbbamctrl = csr_readl(drvdata, CSR_USBBAMCTRL);
-	usbbamctrl = (usbbamctrl & ~0x3) | BLKSIZE_2048;
+	usbbamctrl = (usbbamctrl & ~0x3) | drvdata->blksize;
 	csr_writel(drvdata, usbbamctrl, CSR_USBBAMCTRL);
 
 	usbflshctrl = csr_readl(drvdata, CSR_USBFLSHCTRL);
@@ -119,6 +121,7 @@
 
 static int __devinit csr_probe(struct platform_device *pdev)
 {
+	int ret;
 	struct device *dev = &pdev->dev;
 	struct coresight_platform_data *pdata;
 	struct csr_drvdata *drvdata;
@@ -148,6 +151,13 @@
 	if (!drvdata->base)
 		return -ENOMEM;
 
+	if (pdev->dev.of_node) {
+		ret = of_property_read_u32(pdev->dev.of_node, "qcom,blk-size",
+					   &drvdata->blksize);
+		if (ret)
+			drvdata->blksize = BLKSIZE_256;
+	}
+
 	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
 	if (!desc)
 		return -ENOMEM;
diff --git a/drivers/crypto/msm/qcryptohw_50.h b/drivers/crypto/msm/qcryptohw_50.h
index d77311d..0fb924f 100644
--- a/drivers/crypto/msm/qcryptohw_50.h
+++ b/drivers/crypto/msm/qcryptohw_50.h
@@ -59,77 +59,78 @@
 #define CRYPTO_ENCR_XTS_KEY6_REG		0x1D038
 #define CRYPTO_ENCR_XTS_KEY7_REG		0x1D03C
 
-#define CRYPTO_ENCR_PIP0_KEY0_REG		0x1E000
-#define CRYPTO_ENCR_PIP0_KEY1_REG		0x1E004
-#define CRYPTO_ENCR_PIP0_KEY2_REG		0x1E008
-#define CRYPTO_ENCR_PIP0_KEY3_REG		0x1E00C
-#define CRYPTO_ENCR_PIP0_KEY4_REG		0x1E010
-#define CRYPTO_ENCR_PIP0_KEY5_REG		0x1E004
-#define CRYPTO_ENCR_PIP0_KEY6_REG		0x1E008
-#define CRYPTO_ENCR_PIP0_KEY7_REG		0x1E00C
+#define CRYPTO_ENCR_PIPE0_KEY0_REG		0x1E000
+#define CRYPTO_ENCR_PIPE0_KEY1_REG		0x1E004
+#define CRYPTO_ENCR_PIPE0_KEY2_REG		0x1E008
+#define CRYPTO_ENCR_PIPE0_KEY3_REG		0x1E00C
+#define CRYPTO_ENCR_PIPE0_KEY4_REG		0x1E010
+#define CRYPTO_ENCR_PIPE0_KEY5_REG		0x1E004
+#define CRYPTO_ENCR_PIPE0_KEY6_REG		0x1E008
+#define CRYPTO_ENCR_PIPE0_KEY7_REG		0x1E00C
 
-#define CRYPTO_ENCR_PIP1_KEY0_REG		0x1E000
-#define CRYPTO_ENCR_PIP1_KEY1_REG		0x1E004
-#define CRYPTO_ENCR_PIP1_KEY2_REG		0x1E008
-#define CRYPTO_ENCR_PIP1_KEY3_REG		0x1E00C
-#define CRYPTO_ENCR_PIP1_KEY4_REG		0x1E010
-#define CRYPTO_ENCR_PIP1_KEY5_REG		0x1E014
-#define CRYPTO_ENCR_PIP1_KEY6_REG		0x1E018
-#define CRYPTO_ENCR_PIP1_KEY7_REG		0x1E01C
+#define CRYPTO_ENCR_PIPE1_KEY0_REG		0x1E020
+#define CRYPTO_ENCR_PIPE1_KEY1_REG		0x1E024
+#define CRYPTO_ENCR_PIPE1_KEY2_REG		0x1E028
+#define CRYPTO_ENCR_PIPE1_KEY3_REG		0x1E02C
+#define CRYPTO_ENCR_PIPE1_KEY4_REG		0x1E030
+#define CRYPTO_ENCR_PIPE1_KEY5_REG		0x1E034
+#define CRYPTO_ENCR_PIPE1_KEY6_REG		0x1E038
+#define CRYPTO_ENCR_PIPE1_KEY7_REG		0x1E03C
 
-#define CRYPTO_ENCR_PIP2_KEY0_REG		0x1E020
-#define CRYPTO_ENCR_PIP2_KEY1_REG		0x1E024
-#define CRYPTO_ENCR_PIP2_KEY2_REG		0x1E028
-#define CRYPTO_ENCR_PIP2_KEY3_REG		0x1E02C
-#define CRYPTO_ENCR_PIP2_KEY4_REG		0x1E030
-#define CRYPTO_ENCR_PIP2_KEY5_REG		0x1E034
-#define CRYPTO_ENCR_PIP2_KEY6_REG		0x1E038
-#define CRYPTO_ENCR_PIP2_KEY7_REG		0x1E03C
+#define CRYPTO_ENCR_PIPE2_KEY0_REG		0x1E040
+#define CRYPTO_ENCR_PIPE2_KEY1_REG		0x1E044
+#define CRYPTO_ENCR_PIPE2_KEY2_REG		0x1E048
+#define CRYPTO_ENCR_PIPE2_KEY3_REG		0x1E04C
+#define CRYPTO_ENCR_PIPE2_KEY4_REG		0x1E050
+#define CRYPTO_ENCR_PIPE2_KEY5_REG		0x1E054
+#define CRYPTO_ENCR_PIPE2_KEY6_REG		0x1E058
+#define CRYPTO_ENCR_PIPE2_KEY7_REG		0x1E05C
 
-#define CRYPTO_ENCR_PIP3_KEY0_REG		0x1E040
-#define CRYPTO_ENCR_PIP3_KEY1_REG		0x1E044
-#define CRYPTO_ENCR_PIP3_KEY2_REG		0x1E048
-#define CRYPTO_ENCR_PIP3_KEY3_REG		0x1E04C
-#define CRYPTO_ENCR_PIP3_KEY4_REG		0x1E050
-#define CRYPTO_ENCR_PIP3_KEY5_REG		0x1E054
-#define CRYPTO_ENCR_PIP3_KEY6_REG		0x1E058
-#define CRYPTO_ENCR_PIP3_KEY7_REG		0x1E05C
+#define CRYPTO_ENCR_PIPE3_KEY0_REG		0x1E060
+#define CRYPTO_ENCR_PIPE3_KEY1_REG		0x1E064
+#define CRYPTO_ENCR_PIPE3_KEY2_REG		0x1E068
+#define CRYPTO_ENCR_PIPE3_KEY3_REG		0x1E06C
+#define CRYPTO_ENCR_PIPE3_KEY4_REG		0x1E070
+#define CRYPTO_ENCR_PIPE3_KEY5_REG		0x1E074
+#define CRYPTO_ENCR_PIPE3_KEY6_REG		0x1E078
+#define CRYPTO_ENCR_PIPE3_KEY7_REG		0x1E07C
 
-#define CRYPTO_ENCR_PIP0_XTS_KEY0_REG		0x1E200
-#define CRYPTO_ENCR_PIP0_XTS_KEY1_REG		0x1E204
-#define CRYPTO_ENCR_PIP0_XTS_KEY2_REG		0x1E208
-#define CRYPTO_ENCR_PIP0_XTS_KEY3_REG		0x1E20C
-#define CRYPTO_ENCR_PIP0_XTS_KEY4_REG		0x1E210
-#define CRYPTO_ENCR_PIP0_XTS_KEY5_REG		0x1E214
-#define CRYPTO_ENCR_PIP0_XTS_KEY6_REG		0x1E218
-#define CRYPTO_ENCR_PIP0_XTS_KEY7_REG		0x1E21C
 
-#define CRYPTO_ENCR_PIP1_XTS_KEY0_REG		0x1E220
-#define CRYPTO_ENCR_PIP1_XTS_KEY1_REG		0x1E224
-#define CRYPTO_ENCR_PIP1_XTS_KEY2_REG		0x1E228
-#define CRYPTO_ENCR_PIP1_XTS_KEY3_REG		0x1E22C
-#define CRYPTO_ENCR_PIP1_XTS_KEY4_REG		0x1E230
-#define CRYPTO_ENCR_PIP1_XTS_KEY5_REG		0x1E234
-#define CRYPTO_ENCR_PIP1_XTS_KEY6_REG		0x1E238
-#define CRYPTO_ENCR_PIP1_XTS_KEY7_REG		0x1E23C
+#define CRYPTO_ENCR_PIPE0_XTS_KEY0_REG		0x1E200
+#define CRYPTO_ENCR_PIPE0_XTS_KEY1_REG		0x1E204
+#define CRYPTO_ENCR_PIPE0_XTS_KEY2_REG		0x1E208
+#define CRYPTO_ENCR_PIPE0_XTS_KEY3_REG		0x1E20C
+#define CRYPTO_ENCR_PIPE0_XTS_KEY4_REG		0x1E210
+#define CRYPTO_ENCR_PIPE0_XTS_KEY5_REG		0x1E214
+#define CRYPTO_ENCR_PIPE0_XTS_KEY6_REG		0x1E218
+#define CRYPTO_ENCR_PIPE0_XTS_KEY7_REG		0x1E21C
 
-#define CRYPTO_ENCR_PIP2_XTS_KEY0_REG		0x1E240
-#define CRYPTO_ENCR_PIP2_XTS_KEY1_REG		0x1E244
-#define CRYPTO_ENCR_PIP2_XTS_KEY2_REG		0x1E248
-#define CRYPTO_ENCR_PIP2_XTS_KEY3_REG		0x1E24C
-#define CRYPTO_ENCR_PIP2_XTS_KEY4_REG		0x1E250
-#define CRYPTO_ENCR_PIP2_XTS_KEY5_REG		0x1E254
-#define CRYPTO_ENCR_PIP2_XTS_KEY6_REG		0x1E258
-#define CRYPTO_ENCR_PIP2_XTS_KEY7_REG		0x1E25C
+#define CRYPTO_ENCR_PIPE1_XTS_KEY0_REG		0x1E220
+#define CRYPTO_ENCR_PIPE1_XTS_KEY1_REG		0x1E224
+#define CRYPTO_ENCR_PIPE1_XTS_KEY2_REG		0x1E228
+#define CRYPTO_ENCR_PIPE1_XTS_KEY3_REG		0x1E22C
+#define CRYPTO_ENCR_PIPE1_XTS_KEY4_REG		0x1E230
+#define CRYPTO_ENCR_PIPE1_XTS_KEY5_REG		0x1E234
+#define CRYPTO_ENCR_PIPE1_XTS_KEY6_REG		0x1E238
+#define CRYPTO_ENCR_PIPE1_XTS_KEY7_REG		0x1E23C
 
-#define CRYPTO_ENCR_PIP3_XTS_KEY0_REG		0x1E260
-#define CRYPTO_ENCR_PIP3_XTS_KEY1_REG		0x1E264
-#define CRYPTO_ENCR_PIP3_XTS_KEY2_REG		0x1E268
-#define CRYPTO_ENCR_PIP3_XTS_KEY3_REG		0x1E26C
-#define CRYPTO_ENCR_PIP3_XTS_KEY4_REG		0x1E270
-#define CRYPTO_ENCR_PIP3_XTS_KEY5_REG		0x1E274
-#define CRYPTO_ENCR_PIP3_XTS_KEY6_REG		0x1E278
-#define CRYPTO_ENCR_PIP3_XTS_KEY7_REG		0x1E27C
+#define CRYPTO_ENCR_PIPE2_XTS_KEY0_REG		0x1E240
+#define CRYPTO_ENCR_PIPE2_XTS_KEY1_REG		0x1E244
+#define CRYPTO_ENCR_PIPE2_XTS_KEY2_REG		0x1E248
+#define CRYPTO_ENCR_PIPE2_XTS_KEY3_REG		0x1E24C
+#define CRYPTO_ENCR_PIPE2_XTS_KEY4_REG		0x1E250
+#define CRYPTO_ENCR_PIPE2_XTS_KEY5_REG		0x1E254
+#define CRYPTO_ENCR_PIPE2_XTS_KEY6_REG		0x1E258
+#define CRYPTO_ENCR_PIPE2_XTS_KEY7_REG		0x1E25C
+
+#define CRYPTO_ENCR_PIPE3_XTS_KEY0_REG		0x1E260
+#define CRYPTO_ENCR_PIPE3_XTS_KEY1_REG		0x1E264
+#define CRYPTO_ENCR_PIPE3_XTS_KEY2_REG		0x1E268
+#define CRYPTO_ENCR_PIPE3_XTS_KEY3_REG		0x1E26C
+#define CRYPTO_ENCR_PIPE3_XTS_KEY4_REG		0x1E270
+#define CRYPTO_ENCR_PIPE3_XTS_KEY5_REG		0x1E274
+#define CRYPTO_ENCR_PIPE3_XTS_KEY6_REG		0x1E278
+#define CRYPTO_ENCR_PIPE3_XTS_KEY7_REG		0x1E27C
 
 
 #define CRYPTO_CNTR0_IV0_REG			0x1A20C
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 607fd6e..5c98599 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -981,9 +981,17 @@
 			goto err;
 		}
 
-		if (adreno_of_read_property(child, "qcom,iommu-ctx-sids",
-			&ctxs[ctx_index].ctx_id))
+		ret = of_property_read_u32_array(child, "reg", reg_val, 2);
+		if (ret) {
+			KGSL_CORE_ERR("Unable to read KGSL IOMMU 'reg'\n");
 			goto err;
+		}
+		if (msm_soc_version_supports_iommu_v1())
+			ctxs[ctx_index].ctx_id = (reg_val[0] -
+				data->physstart) >> KGSL_IOMMU_CTX_SHIFT;
+		else
+			ctxs[ctx_index].ctx_id = ((reg_val[0] -
+				data->physstart) >> KGSL_IOMMU_CTX_SHIFT) - 8;
 
 		ctx_index++;
 	}
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
index 0326c79..05d3570 100644
--- a/drivers/media/video/msm_vidc/msm_venc.c
+++ b/drivers/media/video/msm_vidc/msm_venc.c
@@ -390,10 +390,16 @@
 		.name = "Slice Mode",
 		.type = V4L2_CTRL_TYPE_MENU,
 		.minimum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
-		.maximum = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES,
+		.maximum = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB,
 		.default_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
 		.step = 1,
-		.menu_skip_mask = 0,
+		.menu_skip_mask = ~(
+		(1 << V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) |
+		(1 << V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) |
+		(1 << V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) |
+		(1 << V4L2_MPEG_VIDEO_MULTI_SLICE_GOB)
+		),
+		.qmenu = NULL,
 		.cluster = MSM_VENC_CTRL_CLUSTER_SLICING,
 	},
 	{
@@ -421,6 +427,18 @@
 		.cluster = MSM_VENC_CTRL_CLUSTER_SLICING,
 	},
 	{
+		.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_GOB,
+		.name = "Slice GOB",
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.minimum = 1,
+		.maximum = MAX_SLICE_MB_SIZE,
+		.default_value = 1,
+		.step = 1,
+		.menu_skip_mask = 0,
+		.qmenu = NULL,
+		.cluster = MSM_VENC_CTRL_CLUSTER_SLICING,
+	},
+	{
 		.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE,
 		.name = "Intra Refresh Mode",
 		.type = V4L2_CTRL_TYPE_MENU,
@@ -1281,6 +1299,9 @@
 		case V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES:
 			temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
 			break;
+		case V4L2_MPEG_VIDEO_MULTI_SLICE_GOB:
+			temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_GOB;
+			break;
 		case V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE:
 		default:
 			temp = 0;
@@ -1300,6 +1321,7 @@
 	}
 	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
 	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
+	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_GOB:
 		temp_ctrl = TRY_GET_CTRL(V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE);
 
 		property_id =
diff --git a/drivers/media/video/msm_vidc/msm_vidc_debug.c b/drivers/media/video/msm_vidc/msm_vidc_debug.c
index 65a518f..0a2075d 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_debug.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_debug.c
@@ -17,6 +17,7 @@
 #define MAX_DBG_BUF_SIZE 4096
 int msm_vidc_debug = 0x3;
 int msm_fw_debug = 0x18;
+int msm_fw_debug_mode = 0x1;
 
 struct debug_buffer {
 	char ptr[MAX_DBG_BUF_SIZE];
@@ -149,6 +150,11 @@
 		dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
 		goto failed_create_dir;
 	}
+	if (!debugfs_create_u32("fw_debug_mode", S_IRUGO | S_IWUSR,
+			parent, &msm_fw_debug_mode)) {
+		dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
+		goto failed_create_dir;
+	}
 failed_create_dir:
 	return dir;
 }
diff --git a/drivers/media/video/msm_vidc/msm_vidc_debug.h b/drivers/media/video/msm_vidc/msm_vidc_debug.h
index b3bb6e1..07568ef 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_debug.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_debug.h
@@ -43,6 +43,7 @@
 
 extern int msm_vidc_debug;
 extern int msm_fw_debug;
+extern int msm_fw_debug_mode;
 
 #define dprintk(__level, __fmt, arg...)	\
 	do { \
diff --git a/drivers/media/video/msm_vidc/venus_hfi.c b/drivers/media/video/msm_vidc/venus_hfi.c
index 0cd6b9f..bffba30 100644
--- a/drivers/media/video/msm_vidc/venus_hfi.c
+++ b/drivers/media/video/msm_vidc/venus_hfi.c
@@ -37,6 +37,17 @@
 
 #define SHARED_QSIZE 0x1000000
 
+static const u32 venus_qdss_entries[][2] = {
+	{0xFC307000, 0x1000},
+	{0xFC322000, 0x1000},
+	{0xFC319000, 0x1000},
+	{0xFC31A000, 0x1000},
+	{0xFC31B000, 0x1000},
+	{0xFC321000, 0x1000},
+	{0xFA180000, 0x1000},
+	{0xFA181000, 0x1000},
+};
+
 static struct msm_bus_vectors enc_ocmem_init_vectors[]  = {
 	{
 		.src = MSM_BUS_MASTER_VIDEO_P0_OCMEM,
@@ -926,8 +937,28 @@
 static void venus_hfi_interface_queues_release(struct venus_hfi_device *device)
 {
 	int i;
+	struct hfi_mem_map_table *qdss;
+	struct hfi_mem_map *mem_map;
+	int num_entries = sizeof(venus_qdss_entries)/(2 * sizeof(u32));
 
-	venus_hfi_free(device->hal_client, device->mem_addr.mem_data);
+	if (device->qdss.mem_data) {
+		qdss = (struct hfi_mem_map_table *)
+			device->qdss.align_virtual_addr;
+		qdss->mem_map_num_entries = num_entries;
+		qdss->mem_map_table_base_addr =
+			(u32 *)((u32)device->qdss.align_device_addr +
+				sizeof(struct hfi_mem_map_table));
+		mem_map = (struct hfi_mem_map *)(qdss + 1);
+		for (i = 0; i < num_entries; i++) {
+			msm_iommu_unmap_contig_buffer(
+				(unsigned long)(mem_map[i].virtual_addr),
+				device->resources.io_map[NS_MAP].domain,
+				1, SZ_4K);
+		}
+		venus_hfi_free(device->hal_client, device->qdss.mem_data);
+	}
+	venus_hfi_free(device->hal_client, device->iface_q_table.mem_data);
+	venus_hfi_free(device->hal_client, device->sfr.mem_data);
 
 	for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) {
 		device->iface_queues[i].q_hdr = NULL;
@@ -950,6 +981,41 @@
 	msm_smem_delete_client(device->hal_client);
 	device->hal_client = NULL;
 }
+static int venus_hfi_get_qdss_iommu_virtual_addr(struct hfi_mem_map *mem_map,
+	int domain)
+{
+	int i;
+	int rc = 0;
+	unsigned long iova = 0;
+	int num_entries = sizeof(venus_qdss_entries)/(2 * sizeof(u32));
+
+	for (i = 0; i < num_entries; i++) {
+		rc = msm_iommu_map_contig_buffer(venus_qdss_entries[i][0],
+			domain, 1 , venus_qdss_entries[i][1],
+			SZ_4K, 0, &iova);
+		if (rc) {
+			dprintk(VIDC_ERR,
+				"IOMMU QDSS mapping failed for addr 0x%x",
+				venus_qdss_entries[i][0]);
+			rc = -ENOMEM;
+			break;
+		}
+		mem_map[i].virtual_addr = (u32) iova;
+		mem_map[i].physical_addr = venus_qdss_entries[i][0];
+		mem_map[i].size = venus_qdss_entries[i][1];
+		mem_map[i].attr = 0x0;
+	}
+	if (i < num_entries) {
+		dprintk(VIDC_ERR,
+			"IOMMU QDSS mapping failed, Freeing entries %d", i);
+		for (--i; i >= 0; i--) {
+			msm_iommu_unmap_contig_buffer(
+				(unsigned long)(mem_map[i].virtual_addr),
+				domain, 1, SZ_4K);
+		}
+	}
+	return rc;
+}
 
 static int venus_hfi_interface_queues_init(struct venus_hfi_device *dev,
 					int domain)
@@ -958,24 +1024,25 @@
 	struct hfi_queue_header *q_hdr;
 	u8 i;
 	int rc = 0;
+	struct hfi_mem_map_table *qdss;
+	struct hfi_mem_map *mem_map;
 	struct vidc_iface_q_info *iface_q;
 	struct hfi_sfr_struct *vsfr;
 	struct vidc_mem_addr *mem_addr;
 	int offset = 0;
-	int size_1m = 1024 * 1024;
-	int uc_size = (UC_SIZE + size_1m - 1) & (~(size_1m - 1));
+	int num_entries = sizeof(venus_qdss_entries)/(2 * sizeof(u32));
 	mem_addr = &dev->mem_addr;
 	rc = venus_hfi_alloc((void *) mem_addr,
-			dev->hal_client, uc_size, 1,
+			dev->hal_client, QUEUE_SIZE, 1,
 			0, domain);
 	if (rc) {
 		dprintk(VIDC_ERR, "iface_q_table_alloc_fail");
-		return -ENOMEM;
+		goto fail_alloc_queue;
 	}
 	dev->iface_q_table.align_virtual_addr = mem_addr->align_virtual_addr;
 	dev->iface_q_table.align_device_addr = mem_addr->align_device_addr;
 	dev->iface_q_table.mem_size = VIDC_IFACEQ_TABLE_SIZE;
-	dev->iface_q_table.mem_data = NULL;
+	dev->iface_q_table.mem_data = mem_addr->mem_data;
 	offset += dev->iface_q_table.mem_size;
 
 	for (i = 0; i < VIDC_IFACEQ_NUMQ; i++) {
@@ -992,18 +1059,31 @@
 		venus_hfi_set_queue_hdr_defaults(iface_q->q_hdr);
 	}
 
-	dev->qdss.align_device_addr = mem_addr->align_device_addr + offset;
-	dev->qdss.align_virtual_addr = mem_addr->align_virtual_addr + offset;
-	dev->qdss.mem_size = QDSS_SIZE;
-	dev->qdss.mem_data = NULL;
-	offset += dev->qdss.mem_size;
-
-	dev->sfr.align_device_addr = mem_addr->align_device_addr + offset;
-	dev->sfr.align_virtual_addr = mem_addr->align_virtual_addr + offset;
-	dev->sfr.mem_size = SFR_SIZE;
-	dev->sfr.mem_data = NULL;
-	offset += dev->sfr.mem_size;
-
+	rc = venus_hfi_alloc((void *) mem_addr,
+			dev->hal_client, QDSS_SIZE, 1,
+			0, domain);
+	if (rc) {
+		dprintk(VIDC_WARN,
+			"qdss_alloc_fail: QDSS messages logging will not work");
+		dev->qdss.align_device_addr = NULL;
+	} else {
+		dev->qdss.align_device_addr = mem_addr->align_device_addr;
+		dev->qdss.align_virtual_addr = mem_addr->align_virtual_addr;
+		dev->qdss.mem_size = QDSS_SIZE;
+		dev->qdss.mem_data = mem_addr->mem_data;
+	}
+	rc = venus_hfi_alloc((void *) mem_addr,
+			dev->hal_client, SFR_SIZE, 1,
+			0, domain);
+	if (rc) {
+		dprintk(VIDC_WARN, "sfr_alloc_fail: SFR not will work");
+		dev->sfr.align_device_addr = NULL;
+	} else {
+		dev->sfr.align_device_addr = mem_addr->align_device_addr;
+		dev->sfr.align_virtual_addr = mem_addr->align_virtual_addr;
+		dev->sfr.mem_size = SFR_SIZE;
+		dev->sfr.mem_data = mem_addr->mem_data;
+	}
 	q_tbl_hdr = (struct hfi_queue_table_header *)
 			dev->iface_q_table.align_virtual_addr;
 	q_tbl_hdr->qtbl_version = 0;
@@ -1035,9 +1115,9 @@
 
 	venus_hfi_write_register(dev->hal_data->register_base_addr,
 			VIDC_UC_REGION_ADDR,
-			(u32) mem_addr->align_device_addr, 0);
+			(u32) dev->iface_q_table.align_device_addr, 0);
 	venus_hfi_write_register(dev->hal_data->register_base_addr,
-			VIDC_UC_REGION_SIZE, mem_addr->mem_size, 0);
+			VIDC_UC_REGION_SIZE, SHARED_QSIZE, 0);
 	venus_hfi_write_register(dev->hal_data->register_base_addr,
 		VIDC_CPU_CS_SCIACMDARG2,
 		(u32) dev->iface_q_table.align_device_addr,
@@ -1045,16 +1125,33 @@
 	venus_hfi_write_register(dev->hal_data->register_base_addr,
 		VIDC_CPU_CS_SCIACMDARG1, 0x01,
 		dev->iface_q_table.align_virtual_addr);
-	venus_hfi_write_register(dev->hal_data->register_base_addr,
+
+	qdss = (struct hfi_mem_map_table *) dev->qdss.align_virtual_addr;
+	qdss->mem_map_num_entries = num_entries;
+	qdss->mem_map_table_base_addr =
+		(u32 *)	((u32)dev->qdss.align_device_addr +
+		sizeof(struct hfi_mem_map_table));
+	mem_map = (struct hfi_mem_map *)(qdss + 1);
+	rc = venus_hfi_get_qdss_iommu_virtual_addr(mem_map, domain);
+	if (rc) {
+		dprintk(VIDC_ERR,
+			"IOMMU mapping failed, Freeing qdss memdata");
+		venus_hfi_free(dev->hal_client, dev->qdss.mem_data);
+		dev->qdss.mem_data = NULL;
+	}
+	if (!IS_ERR_OR_NULL(dev->qdss.align_device_addr))
+		venus_hfi_write_register(dev->hal_data->register_base_addr,
 			VIDC_MMAP_ADDR,
 			(u32) dev->qdss.align_device_addr, 0);
 
 	vsfr = (struct hfi_sfr_struct *) dev->sfr.align_virtual_addr;
 	vsfr->bufSize = SFR_SIZE;
-
-	venus_hfi_write_register(dev->hal_data->register_base_addr,
+	if (!IS_ERR_OR_NULL(dev->sfr.align_device_addr))
+		venus_hfi_write_register(dev->hal_data->register_base_addr,
 			VIDC_SFR_ADDR, (u32)dev->sfr.align_device_addr , 0);
 	return 0;
+fail_alloc_queue:
+	return -ENOMEM;
 }
 
 static int venus_hfi_core_start_cpu(struct venus_hfi_device *device)
@@ -1139,6 +1236,8 @@
 	hfi = (struct hfi_debug_config *) &pkt->rg_property_data[1];
 	hfi->debug_config = debug;
 	hfi->debug_mode = HFI_DEBUG_MODE_QUEUE;
+	if (msm_fw_debug_mode <= HFI_DEBUG_MODE_QDSS)
+		hfi->debug_mode = msm_fw_debug_mode;
 	if (venus_hfi_iface_cmdq_write(device, pkt))
 		return -ENOTEMPTY;
 	return 0;
diff --git a/drivers/media/video/msm_vidc/venus_hfi.h b/drivers/media/video/msm_vidc/venus_hfi.h
index f825c20..8770ace 100644
--- a/drivers/media/video/msm_vidc/venus_hfi.h
+++ b/drivers/media/video/msm_vidc/venus_hfi.h
@@ -19,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <mach/ocmem.h>
+#include <mach/iommu_domains.h>
 
 #include "vidc_hfi_api.h"
 #include "msm_smem.h"
@@ -79,6 +80,18 @@
 	u32 qhdr_write_idx;
 };
 
+struct hfi_mem_map_table {
+	u32 mem_map_num_entries;
+	u32 *mem_map_table_base_addr;
+};
+
+struct hfi_mem_map {
+	u32 virtual_addr;
+	u32 physical_addr;
+	u32 size;
+	u32 attr;
+};
+
 #define VIDC_IFACEQ_TABLE_SIZE (sizeof(struct hfi_queue_table_header) \
 	+ sizeof(struct hfi_queue_header) * VIDC_IFACEQ_NUMQ)
 
@@ -92,8 +105,8 @@
 #define QDSS_SIZE 4096
 #define SFR_SIZE 4096
 
-#define UC_SIZE (VIDC_IFACEQ_TABLE_SIZE + \
-	(VIDC_IFACEQ_QUEUE_SIZE * VIDC_IFACEQ_NUMQ) + QDSS_SIZE + SFR_SIZE)
+#define QUEUE_SIZE (VIDC_IFACEQ_TABLE_SIZE + \
+	(VIDC_IFACEQ_QUEUE_SIZE * VIDC_IFACEQ_NUMQ))
 
 enum vidc_hw_reg {
 	VIDC_HWREG_CTRL_STATUS =  0x1,
diff --git a/drivers/media/video/msmb/isp/msm_buf_mgr.h b/drivers/media/video/msmb/isp/msm_buf_mgr.h
index a44b5ec..b96d9fe 100644
--- a/drivers/media/video/msmb/isp/msm_buf_mgr.h
+++ b/drivers/media/video/msmb/isp/msm_buf_mgr.h
@@ -17,9 +17,8 @@
 #include <mach/iommu_domains.h>
 #include "msm_sd.h"
 
-#define BUF_SRC_SHIFT 16
 /*Buffer source can be from userspace / HAL*/
-#define BUF_SRC(id) (id >> BUF_SRC_SHIFT)
+#define BUF_SRC(id) (id & ISP_NATIVE_BUF_BIT)
 
 struct msm_isp_buf_mgr;
 
diff --git a/drivers/media/video/msmb/isp/msm_isp.h b/drivers/media/video/msmb/isp/msm_isp.h
index c320a1a..1c82f45 100644
--- a/drivers/media/video/msmb/isp/msm_isp.h
+++ b/drivers/media/video/msmb/isp/msm_isp.h
@@ -132,6 +132,10 @@
 	int (*get_platform_data) (struct vfe_device *vfe_dev);
 };
 struct msm_vfe_stats_ops {
+	void (*cfg_framedrop) (struct vfe_device *vfe_dev,
+		struct msm_vfe_stats_stream *stream_info);
+	void (*clear_framedrop) (struct vfe_device *vfe_dev,
+		struct msm_vfe_stats_stream *stream_info);
 	void (*cfg_comp_mask) (struct vfe_device *vfe_dev,
 		struct msm_vfe_stats_stream *stream_info);
 	void (*clear_comp_mask) (struct vfe_device *vfe_dev,
@@ -142,7 +146,7 @@
 		struct msm_vfe_stats_stream *stream_info);
 
 	void (*cfg_wm_reg) (struct vfe_device *vfe_dev,
-		struct msm_vfe_stats_stream_request_cmd *stream_cfg_cmd);
+		struct msm_vfe_stats_stream *stream_info);
 	void (*clear_wm_reg) (struct vfe_device *vfe_dev,
 		struct msm_vfe_stats_stream *stream_info);
 
@@ -158,6 +162,10 @@
 	uint32_t (*get_frame_id) (struct vfe_device *vfe_dev);
 	uint32_t (*get_wm_mask) (uint32_t irq_status0, uint32_t irq_status1);
 	uint32_t (*get_comp_mask) (uint32_t irq_status0, uint32_t irq_status1);
+	uint32_t (*get_pingpong_status) (struct vfe_device *vfe_dev);
+	uint32_t (*get_active_pingpong_idx) (uint32_t pingpong_status,
+				enum msm_isp_stats_type stats_type);
+
 };
 
 struct msm_vfe_ops {
@@ -180,6 +188,7 @@
 	uint8_t num_rdi_master;
 	uint8_t num_comp_mask;
 	uint32_t min_wm_ub;
+	uint8_t num_stats_comp_mask;
 };
 
 enum msm_vfe_axi_state {
@@ -241,23 +250,33 @@
 	enum msm_vfe_inputmux input_mux;
 };
 
-
+enum msm_vfe_stats_state {
+	STATE_AVALIABLE,
+	STATE_INACTIVE,
+	STATE_ACTIVE,
+	STATE_START_PENDING,
+	STATE_STOP_PENDING,
+	STATE_STOPPING,
+};
 struct msm_vfe_stats_stream {
 	uint32_t frame_id;
 	uint8_t enable;
 	enum msm_isp_stats_type stats_type;
-	uint8_t comp_mask_index;
+	int8_t comp_mask_index;
 	struct msm_isp_buffer *buf[2];
 	uint32_t session_id;
 	uint32_t stream_id;
 	uint32_t bufq_handle;
 	uint32_t stream_handle;
 	uint32_t framedrop_pattern;
+	uint8_t comp_flag;
+	uint8_t comp_idx;
+	enum msm_vfe_stats_state state;
 };
 
 struct msm_vfe_stats_composite_info {
-	uint32_t stream_handle;
-	uint32_t stream_composite_mask;
+	uint32_t stats_mask;
+	uint8_t comp_flag;
 };
 
 enum msm_wm_ub_cfg_type {
@@ -288,7 +307,7 @@
 struct msm_vfe_stats_shared_data {
 	struct msm_vfe_stats_stream stream_info[MSM_ISP_STATS_MAX];
 	struct msm_vfe_stats_composite_info
-		comp_info[MAX_NUM_STATS_COMP_MASK];
+		composite_info[MAX_NUM_STATS_COMP_MASK];
 	uint8_t num_active_stream;
 	uint8_t num_used_composite_mask;
 	uint16_t stream_handle_cnt;
diff --git a/drivers/media/video/msmb/isp/msm_isp40.c b/drivers/media/video/msmb/isp/msm_isp40.c
index b9788eb..6c90763 100644
--- a/drivers/media/video/msmb/isp/msm_isp40.c
+++ b/drivers/media/video/msmb/isp/msm_isp40.c
@@ -862,7 +862,7 @@
 static void msm_vfe40_cfg_axi_ub(struct vfe_device *vfe_dev)
 {
 	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
-
+	axi_data->wm_ub_cfg_policy = MSM_WM_UB_EQUAL_SLICING;
 	if (axi_data->wm_ub_cfg_policy == MSM_WM_UB_EQUAL_SLICING)
 		msm_vfe40_cfg_axi_ub_equal_slicing(vfe_dev);
 	else
@@ -937,7 +937,7 @@
 
 static void msm_vfe40_stats_cfg_wm_reg(
 	struct vfe_device *vfe_dev,
-	struct msm_vfe_stats_stream_request_cmd *stream_cfg_cmd)
+	struct msm_vfe_stats_stream *stream_info)
 {
 
 }
@@ -984,6 +984,56 @@
 {
 	return vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
 }
+
+static uint32_t msm_vfe40_stats_get_active_pingpong_idx(
+	uint32_t pingpong_status,
+	enum msm_isp_stats_type stats_type)
+{
+	int pingpong_bit = 0;
+	switch (stats_type) {
+	case MSM_ISP_STATS_AWB:
+		if (pingpong_status & (1 << 11))
+			pingpong_bit = 1; /* pong is active */
+			break;
+	case MSM_ISP_STATS_RS:
+		if (pingpong_status & (1 << 12))
+			pingpong_bit = 1; /* pong is active */
+			break;
+	case MSM_ISP_STATS_CS:
+		if (pingpong_status & (1 << 13))
+			pingpong_bit = 1; /* pong is active */
+			break;
+	case MSM_ISP_STATS_IHIST:
+		if (pingpong_status & (1 << 14))
+			pingpong_bit = 1; /* pong is active */
+			break;
+	case MSM_ISP_STATS_BG:
+		if (pingpong_status & (1 << 9))
+			pingpong_bit = 1; /* pong is active */
+			break;
+	case MSM_ISP_STATS_BF:
+		if (pingpong_status & (1 << 10))
+			pingpong_bit = 1; /* pong is active */
+			break;
+	case MSM_ISP_STATS_BE:
+		if (pingpong_status & (1 << 8))
+			pingpong_bit = 1; /* pong is active */
+			break;
+	case MSM_ISP_STATS_BHIST:
+		if (pingpong_status & (1 << 15))
+			pingpong_bit = 1; /* pong is active */
+			break;
+	case MSM_ISP_STATS_SKIN:
+	case MSM_ISP_STATS_AEC:
+	case MSM_ISP_STATS_AF:
+	default:
+		pr_err("%s: not supported stats type = %d\n",
+			__func__, stats_type);
+		return -EINVAL;
+	}
+	return pingpong_bit;
+}
+
 static int msm_vfe40_get_platform_data(struct vfe_device *vfe_dev)
 {
 	int rc = 0;
@@ -1041,6 +1091,7 @@
 	.num_rdi = 3,
 	.num_rdi_master = 3,
 	.min_wm_ub = 64,
+	.num_stats_comp_mask = 2,
 };
 
 static struct v4l2_subdev_core_ops msm_vfe40_subdev_core_ops = {
@@ -1118,6 +1169,9 @@
 			.get_comp_mask = msm_vfe40_stats_get_comp_mask,
 			.get_wm_mask = msm_vfe40_stats_get_wm_mask,
 			.get_frame_id = msm_vfe40_stats_get_frame_id,
+			.get_pingpong_status = msm_vfe40_get_pingpong_status,
+			.get_active_pingpong_idx =
+				msm_vfe40_stats_get_active_pingpong_idx,
 		},
 	},
 	.axi_hw_info = &msm_vfe40_axi_hw_info,
diff --git a/drivers/media/video/msmb/isp/msm_isp_axi_util.c b/drivers/media/video/msmb/isp/msm_isp_axi_util.c
index fe55b40..7e62071 100644
--- a/drivers/media/video/msmb/isp/msm_isp_axi_util.c
+++ b/drivers/media/video/msmb/isp/msm_isp_axi_util.c
@@ -637,7 +637,6 @@
 		complete(&vfe_dev->stream_config_complete);
 	}
 }
-
 #define VFE_PING_FLAG 0xFFFFFFFF
 #define VFE_PONG_FLAG 0x0
 
@@ -687,7 +686,7 @@
 		vfe_dev, stream_info->wm[i],
 		pingpong_status, buf->mapped_info[i].paddr);
 
-	if (stream_info->buf[pingpong_bit]) {
+	if (stream_info->buf[pingpong_bit] && tv) {
 		if (stream_info->buf_divert) {
 			buf_event.frame_id = stream_info->frame_id;
 			buf_event.timestamp = *tv;
diff --git a/drivers/media/video/msmb/isp/msm_isp_stats_util.c b/drivers/media/video/msmb/isp/msm_isp_stats_util.c
index 15f4c23..86a4a3d 100644
--- a/drivers/media/video/msmb/isp/msm_isp_stats_util.c
+++ b/drivers/media/video/msmb/isp/msm_isp_stats_util.c
@@ -13,6 +13,41 @@
 #include <media/v4l2-subdev.h>
 #include "msm_isp_util.h"
 #include "msm_isp_stats_util.h"
+#define VFE_PING_ACTIVE_FLAG 0xFFFFFFFF
+#define VFE_PONG_ACTIVE_FLAG 0x0
+
+int msm_isp_stats_cfg_ping_pong_address(struct vfe_device *vfe_dev,
+	struct msm_vfe_stats_stream *stream_info, uint32_t pingpong_status,
+	struct msm_isp_buffer *out_buf)
+{
+	int rc = -1;
+	struct msm_isp_buffer *buf;
+	int active_bit = 0;
+	int buf_idx;
+	uint32_t bufq_handle = stream_info->bufq_handle;
+
+	out_buf = NULL;
+	active_bit = vfe_dev->hw_info->vfe_ops.stats_ops.
+		get_active_pingpong_idx(pingpong_status,
+			stream_info->stats_type);
+	buf_idx = active_bit^0x1;
+
+	rc = vfe_dev->buf_mgr->ops->get_buf(
+		vfe_dev->buf_mgr, bufq_handle, &buf);
+	if (rc < 0) {
+		pr_err("%s: No free buffer, stats_type = %d\n",
+			__func__, stream_info->stats_type);
+		return rc;
+	}
+	vfe_dev->hw_info->vfe_ops.stats_ops.update_ping_pong_addr(
+		vfe_dev, stream_info->stats_type,
+		pingpong_status, buf->mapped_info[buf_idx].paddr);
+
+	if (stream_info->buf[buf_idx])
+		out_buf = stream_info->buf[buf_idx];
+	stream_info->buf[buf_idx] = buf;
+	return 0;
+}
 
 void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
 	uint32_t irq_status0, uint32_t irq_status1,
@@ -22,7 +57,7 @@
 	uint32_t stats_comp_mask = 0, stats_mask = 0;
 	ISP_DBG("%s: status: 0x%x\n", __func__, irq_status0);
 	stats_comp_mask = vfe_dev->hw_info->vfe_ops.stats_ops.
-	get_comp_mask(irq_status0, irq_status1);
+		get_comp_mask(irq_status0, irq_status1);
 	stats_mask = vfe_dev->hw_info->vfe_ops.stats_ops.
 		get_wm_mask(irq_status0, irq_status1);
 	if (!(stats_comp_mask || stats_mask))
@@ -31,10 +66,100 @@
 	/* TD: process comp/non comp stats */
 }
 
+static int msm_isp_stats_reserve_comp_mask(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_stats_shared_data *stats_data,
+	struct msm_vfe_stats_stream *stream_info)
+{
+	int i;
+	uint8_t num_stats_comp;
+	int8_t comp_idx = -1;
+	if (stream_info->comp_flag == 0)
+		return 0;
+
+	num_stats_comp = vfe_dev->axi_data.hw_info->num_stats_comp_mask;
+	for (i = 0; i < num_stats_comp; i++) {
+		if (!stats_data->composite_info[i].stats_mask == 0 &&
+				comp_idx < 0)
+			comp_idx = i;
+		if (stats_data->composite_info[i].comp_flag ==
+				stream_info->comp_flag) {
+			comp_idx = i;
+			break;
+		}
+	}
+	if (comp_idx < 0) {
+		pr_err("%s: no more stats comp idx\n", __func__);
+		return -EACCES;
+	}
+	stats_data->composite_info[comp_idx].stats_mask |=
+		(1 << stream_info->stats_type);
+	if (stats_data->composite_info[comp_idx].comp_flag == 0)
+		stats_data->composite_info[comp_idx].comp_flag =
+			stream_info->comp_flag;
+	stream_info->comp_idx = comp_idx;
+	return 0;
+}
+
+static int msm_isp_stats_unreserve_comp_mask(
+	struct vfe_device *vfe_dev,
+	struct msm_vfe_stats_shared_data *stats_data,
+	struct msm_vfe_stats_stream *stream_info)
+{
+	uint8_t comp_idx = stream_info->comp_idx;
+
+	if (stream_info->comp_flag == 0)
+		return 0;
+	stats_data->composite_info[comp_idx].stats_mask &=
+		~(1 << stream_info->stats_type);
+	if (stats_data->composite_info[comp_idx].stats_mask == 0)
+		memset(&stats_data->composite_info[comp_idx], 0,
+			sizeof(struct msm_vfe_stats_composite_info));
+	return 0;
+}
+
 int msm_isp_request_stats_stream(struct vfe_device *vfe_dev, void *arg)
 {
 	int rc = 0;
-	/*To Do*/
+	struct msm_vfe_stats_stream_request_cmd *stream_cfg_cmd = arg;
+	struct msm_vfe_stats_stream *stream_info = NULL;
+	struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
+
+	if (stream_cfg_cmd->stats_type < MSM_ISP_STATS_AEC ||
+			stream_cfg_cmd->stats_type >= MSM_ISP_STATS_MAX) {
+		pr_err("%s: invalid stats type %d received\n",
+		__func__, stream_cfg_cmd->stats_type);
+		return -EINVAL;
+	}
+	stream_info = &stats_data->stream_info[stream_cfg_cmd->stats_type];
+	if (stream_info->stream_handle != 0) {
+		pr_err("%s: stats type %d has been used already\n",
+			__func__, stream_cfg_cmd->stats_type);
+			return -EBUSY;
+	}
+
+	stats_data->stream_handle_cnt++;
+	if (stats_data->stream_handle_cnt == 0)
+		stats_data->stream_handle_cnt++;
+	stream_info->stream_handle =
+		stats_data->stream_handle_cnt << 16 |
+			stream_cfg_cmd->stats_type;
+	stream_info->enable = 0;
+	stream_info->stats_type = stream_cfg_cmd->stats_type;
+	stream_info->comp_flag = stream_cfg_cmd->comp_flag;
+	stream_info->session_id = stream_cfg_cmd->session_id;
+	stream_info->stream_id = stream_cfg_cmd->stream_id;
+	stream_info->framedrop_pattern = stream_cfg_cmd->framedrop_pattern;
+	stream_cfg_cmd->stream_handle =	stream_info->stream_handle;
+	msm_isp_stats_reserve_comp_mask(vfe_dev, stats_data, stream_info);
+	if (stream_info->comp_flag)
+		vfe_dev->hw_info->vfe_ops.stats_ops.
+			cfg_comp_mask(vfe_dev, stream_info);
+	else
+		vfe_dev->hw_info->vfe_ops.stats_ops.
+			cfg_wm_irq_mask(vfe_dev, stream_info);
+	vfe_dev->hw_info->vfe_ops.stats_ops.
+		cfg_wm_reg(vfe_dev, stream_info);
 	return rc;
 }
 
@@ -45,25 +170,94 @@
 	struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
 	struct msm_vfe_stats_stream *stream_info =
 		&stats_data->stream_info[
-			(stream_release_cmd->stream_handle & 0xFF)];
+		(stream_release_cmd->stream_handle & 0xFF)];
 
-	if (stream_info == NULL)
-		rc = -1;
+	if (stream_info == NULL ||
+			stream_info->stream_handle !=
+				stream_release_cmd->stream_handle) {
+		pr_err("%s: handle mismatch(0x%x, 0x%x\n",
+			__func__, stream_info->stream_handle,
+			stream_release_cmd->stream_handle);
+		rc = -EINVAL;
+	}
+	if (stream_info->enable) {
+		struct msm_vfe_stats_stream_cfg_cmd stop_cmd;
+		memset(&stop_cmd, 0, sizeof(stop_cmd));
+		stop_cmd.num_streams = 1;
+		stop_cmd.stream_handle[0] = stream_release_cmd->stream_handle;
+		stop_cmd.enable = 0;
+		rc = msm_isp_cfg_stats_stream(vfe_dev, (void *)&stop_cmd);
+		if (rc < 0) {
+			pr_err("%s: cannot stop stats type %d\n",
+				__func__, stream_info->stats_type);
+			return -EPERM;
+		}
+	}
+	if (stream_info->bufq_handle) {
+		vfe_dev->buf_mgr->ops->release_buf(vfe_dev->buf_mgr,
+			stream_info->bufq_handle);
+		stream_info->bufq_handle = 0;
+	}
+	vfe_dev->hw_info->vfe_ops.stats_ops.
+		clear_wm_reg(vfe_dev, stream_info);
+	if (stream_info->comp_flag) {
+		msm_isp_stats_unreserve_comp_mask(vfe_dev,
+			stats_data, stream_info);
+		vfe_dev->hw_info->vfe_ops.stats_ops.
+		clear_comp_mask(vfe_dev, stream_info);
+	} else {
+		vfe_dev->hw_info->vfe_ops.stats_ops.
+		clear_wm_irq_mask(vfe_dev, stream_info);
+	}
+	vfe_dev->hw_info->vfe_ops.stats_ops.
+		clear_framedrop(vfe_dev, stream_info);
+	memset(stream_info, 0, sizeof(struct msm_vfe_stats_stream));
 	return rc;
 }
 
 int msm_isp_cfg_stats_stream(struct vfe_device *vfe_dev, void *arg)
 {
-	int rc = 0;
-	uint32_t stats_mask = 0;
-	uint8_t enable = 0;
+	int i, rc = 0;
 	uint32_t pingpong_status = 0;
 	struct msm_isp_buffer *buf = NULL;
-	enum msm_isp_stats_type stats_type = MSM_ISP_STATS_BE;
+	struct msm_vfe_stats_stream_cfg_cmd *stream_cfg_cmd = arg;
+	struct msm_vfe_stats_stream *stream_info;
+	struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
+	int idx;
+	uint32_t stats_mask = 0;
+	uint8_t enable = stream_cfg_cmd->enable;
+
+	for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
+		idx = stream_cfg_cmd->stream_handle[i] & 0xF;
+		stream_info = &stats_data->stream_info[idx];
+		if (stream_info->stream_handle !=
+				stream_cfg_cmd->stream_handle[i]) {
+			pr_err("%s: invalid stream handle -0x%x received\n",
+				__func__, stream_cfg_cmd->stream_handle[i]);
+			continue;
+		}
+		if (enable) {
+			stream_info->bufq_handle =
+				vfe_dev->buf_mgr->ops->get_bufq_handle(
+				vfe_dev->buf_mgr, stream_info->session_id,
+				stream_info->stream_id);
+				if (stream_info->bufq_handle == 0) {
+					pr_err("%s: no buf configured for stats type = %d\n",
+						__func__,
+						stream_info->stats_type);
+					return -EINVAL;
+				}
+		}
+		/* config ping address */
+		pingpong_status = VFE_PONG_ACTIVE_FLAG;
+		stats_mask |= (1 << stream_info->stats_type);
+		msm_isp_stats_cfg_ping_pong_address(vfe_dev,
+			stream_info, pingpong_status, buf);
+		pingpong_status = VFE_PING_ACTIVE_FLAG;
+		msm_isp_stats_cfg_ping_pong_address(vfe_dev,
+			stream_info, pingpong_status, buf);
+	}
 	vfe_dev->hw_info->vfe_ops.stats_ops.
-	stats_enable(vfe_dev, stats_mask, enable);
-	vfe_dev->hw_info->vfe_ops.stats_ops.
-	update_ping_pong_addr(vfe_dev, stats_type,
-		pingpong_status, buf->mapped_info[0].paddr);
+		stats_enable(vfe_dev, stats_mask, enable);
 	return rc;
 }
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index 4012fec..3222ea0 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -259,6 +259,7 @@
 		"Single",
 		"Max Macroblocks",
 		"Max Bytes",
+		"GOB",
 		NULL,
 	};
 	static const char * const entropy_mode[] = {
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index cc021c0..8953475 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -881,6 +881,7 @@
 		dev_set_drvdata(&client->dev, wcd9xxx);
 		wcd9xxx->dev = &client->dev;
 		wcd9xxx->reset_gpio = pdata->reset_gpio;
+		wcd9xxx->slim_device_bootup = true;
 		if (client->dev.of_node)
 			wcd9xxx->mclk_rate = pdata->mclk_rate;
 		ret = wcd9xxx_enable_supplies(wcd9xxx, pdata);
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index a808e0b..233ea99 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -943,6 +943,9 @@
 	pdata->ignore_core_reset_ack = of_property_read_bool(node,
 					"qcom,ignore-core-reset-ack");
 
+	pdata->disable_clk_gating = of_property_read_bool(node,
+					"qcom,disable-clk-gating");
+
 	for_each_child_of_node(pdev->dev.of_node, node)
 		pipe_entry++;
 
@@ -1103,6 +1106,8 @@
 	 */
 	if (pdata->ignore_core_reset_ack && pdata->usb_active_bam != SSUSB_BAM)
 		usb_props.options = SPS_BAM_NO_EXT_P_RST;
+	if (pdata->disable_clk_gating)
+		usb_props.options |= SPS_BAM_NO_LOCAL_CLK_GATING;
 
 	ret = sps_register_bam_device(&usb_props, &h_bam);
 	if (ret < 0) {
diff --git a/drivers/power/bq28400_battery.c b/drivers/power/bq28400_battery.c
index 1852687..beab4e2 100644
--- a/drivers/power/bq28400_battery.c
+++ b/drivers/power/bq28400_battery.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 The Linux Foundation. All rights reserved.
+/* 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
@@ -136,6 +136,8 @@
 	struct power_supply	batt_psy;
 	struct power_supply	*dc_psy;
 	bool			is_charging_enabled;
+	u32			temp_cold;	/* in degree celsius */
+	u32			temp_hot;	/* in degree celsius */
 };
 
 static struct bq28400_device *bq28400_dev;
@@ -486,10 +488,14 @@
 	int rsoc;
 	s16 current_ma = 0;
 	u16 battery_status;
+	int temperature;
+	struct bq28400_device *dev = i2c_get_clientdata(client);
 
 	battery_status = bq28400_read_reg(client, SBS_BATTERY_STATUS);
 	rsoc = bq28400_read_rsoc(client);
 	current_ma = bq28400_read_current(client);
+	temperature = bq28400_read_temperature(client);
+	temperature = temperature / 10; /* in degree celsius */
 
 	if (battery_status & BAT_STATUS_EMPTY)
 		pr_debug("Battery report Empty.\n");
@@ -513,8 +519,11 @@
 		return POWER_SUPPLY_STATUS_FULL;
 	}
 
-	/* Enable charging when battery is not full */
-	bq28400_enable_charging(bq28400_dev, true);
+	/* Enable charging when battery is not full and temperature is ok */
+	if ((temperature > dev->temp_cold) && (temperature < dev->temp_hot))
+		bq28400_enable_charging(bq28400_dev, true);
+	else
+		bq28400_enable_charging(bq28400_dev, false);
 
 	/*
 	* Positive current indicates charging
@@ -825,6 +834,12 @@
 				   const struct i2c_device_id *id)
 {
 	int ret = 0;
+	struct device_node *dev_node = client->dev.of_node;
+
+	if (dev_node == NULL) {
+		pr_err("Device Tree node doesn't exist.\n");
+		return -ENODEV;
+	}
 
 	if (!i2c_check_functionality(client->adapter,
 				I2C_FUNC_SMBUS_BYTE_DATA)) {
@@ -843,6 +858,23 @@
 		return -ENOMEM;
 	}
 
+	/* Note: Lithium-ion battery normal temperature range 0..40 C */
+	ret = of_property_read_u32(dev_node, "ti,temp-cold",
+				   &(bq28400_dev->temp_cold));
+	if (ret) {
+		pr_err("Unable to read cold temperature. ret=%d.\n", ret);
+		goto err_dev_node;
+	}
+	pr_debug("cold temperature limit = %d C.\n", bq28400_dev->temp_cold);
+
+	ret = of_property_read_u32(dev_node, "ti,temp-hot",
+				   &(bq28400_dev->temp_hot));
+	if (ret) {
+		pr_err("Unable to read hot temperature. ret=%d.\n", ret);
+		goto err_dev_node;
+	}
+	pr_debug("hot temperature limit = %d C.\n", bq28400_dev->temp_hot);
+
 	bq28400_dev->client = client;
 	i2c_set_clientdata(client, bq28400_dev);
 
@@ -864,7 +896,7 @@
 	schedule_delayed_work(&bq28400_dev->periodic_user_space_update_work,
 			      msecs_to_jiffies(1000));
 
-	pr_info("Device is ready.\n");
+	pr_debug("Device is ready.\n");
 
 	return 0;
 
@@ -873,6 +905,7 @@
 		debugfs_remove_recursive(bq28400_dev->dent);
 	power_supply_unregister(&bq28400_dev->batt_psy);
 err_register_psy:
+err_dev_node:
 	kfree(bq28400_dev);
 	bq28400_dev = NULL;
 
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 8002e9e..63cab43 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -34,6 +34,8 @@
 /* Coulomb counter clear registers */
 #define BMS1_CC_DATA_CTL		0x42
 #define BMS1_CC_CLEAR_CTL		0x43
+/* BMS Tolerances */
+#define BMS1_TOL_CTL			0X44
 /* OCV limit registers */
 #define BMS1_OCV_USE_LOW_LIMIT_THR0	0x48
 #define BMS1_OCV_USE_LOW_LIMIT_THR1	0x49
@@ -203,6 +205,7 @@
 	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
 };
 
+static bool bms_reset;
 
 static int qpnp_read_wrapper(struct qpnp_bms_chip *chip, u8 *val,
 			u16 base, int count)
@@ -889,6 +892,12 @@
 						chip->iavg_num_samples);
 	}
 
+	/*
+	 * if we're in bms reset mode, force uuc to be 3% of fcc
+	 */
+	if (bms_reset)
+		return (params->fcc_uah * 3) / 100;
+
 	uuc_uah_iavg = calculate_termination_uuc(chip, params, uuc_iavg_ma,
 						batt_temp, &pc_unusable);
 	pr_debug("uuc_iavg_ma = %d uuc with iavg = %d\n",
@@ -1177,6 +1186,76 @@
 	return soc;
 }
 
+#define IBAT_TOL_MASK		0x0F
+#define OCV_TOL_MASK		0xF0
+#define IBAT_TOL_DEFAULT	0x03
+#define IBAT_TOL_NOCHG		0x0F
+#define OCV_TOL_DEFAULT		0x20
+#define OCV_TOL_NO_OCV		0x00
+static int stop_ocv_updates(struct qpnp_bms_chip *chip)
+{
+	pr_debug("stopping ocv updates\n");
+	return qpnp_masked_write(chip, BMS1_TOL_CTL,
+			OCV_TOL_MASK, OCV_TOL_NO_OCV);
+}
+
+static int reset_bms_for_test(struct qpnp_bms_chip *chip)
+{
+	int ibat_ua, vbat_uv, rc;
+	int ocv_est_uv;
+
+	if (!chip) {
+		pr_err("BMS driver has not been initialized yet!\n");
+		return -EINVAL;
+	}
+
+	rc = get_simultaneous_batt_v_and_i(chip, &ibat_ua, &vbat_uv);
+
+	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;
+	chip->last_soc = -EINVAL;
+	reset_cc(chip);
+	chip->last_cc_uah = INT_MIN;
+	stop_ocv_updates(chip);
+
+	pr_debug("bms reset to ocv = %duv vbat_ua = %d ibat_ua = %d\n",
+			chip->last_ocv_uv, vbat_uv, ibat_ua);
+
+	return rc;
+}
+
+static int bms_reset_set(const char *val, const struct kernel_param *kp)
+{
+	int rc;
+
+	rc = param_set_bool(val, kp);
+	if (rc) {
+		pr_err("Unable to set bms_reset: %d\n", rc);
+		return rc;
+	}
+
+	if (*(bool *)kp->arg) {
+		struct power_supply *bms_psy = power_supply_get_by_name("bms");
+		struct qpnp_bms_chip *chip = container_of(bms_psy,
+					struct qpnp_bms_chip, bms_psy);
+
+		rc = reset_bms_for_test(chip);
+		if (rc) {
+			pr_err("Unable to modify bms_reset: %d\n", rc);
+			return rc;
+		}
+	}
+	return 0;
+}
+
+static struct kernel_param_ops bms_reset_ops = {
+	.set = bms_reset_set,
+	.get = param_get_bool,
+};
+
+module_param_cb(bms_reset, &bms_reset_ops, &bms_reset, 0644);
+
 static int charging_adjustments(struct qpnp_bms_chip *chip,
 				struct soc_params *params, int soc,
 				int vbat_uv, int ibat_ua, int batt_temp)
@@ -1268,6 +1347,12 @@
 				(s64)params->fcc_uah - params->uuc_uah);
 	soc_est = bound_soc(soc_est);
 
+	/* never adjust during bms reset mode */
+	if (bms_reset) {
+		pr_debug("bms reset mode, SOC adjustment skipped\n");
+		goto out;
+	}
+
 	if (ibat_ua < 0 && !is_batfet_open(chip)) {
 		soc = charging_adjustments(chip, params, soc, vbat_uv, ibat_ua,
 				batt_temp);
@@ -1631,6 +1716,8 @@
 
 	chg_time_sec = DIV_ROUND_UP(chip->charge_time_us, USEC_PER_SEC);
 	catch_up_sec = DIV_ROUND_UP(chip->catch_up_time_us, USEC_PER_SEC);
+	if (catch_up_sec == 0)
+		return new_soc;
 	pr_debug("cts= %d catch_up_sec = %d\n", chg_time_sec, catch_up_sec);
 
 	/*
@@ -1730,8 +1817,7 @@
 	}
 
 	/* last_soc < soc  ... scale and catch up */
-	if (chip->last_soc != -EINVAL && chip->last_soc < soc
-			&& soc != 100 && chip->catch_up_time_us != 0)
+	if (chip->last_soc != -EINVAL && chip->last_soc < soc && soc != 100)
 		soc = scale_soc_while_chg(chip, delta_time_us,
 						soc, chip->last_soc);
 
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 19e2151..7645df4 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -64,6 +64,7 @@
 #include <mach/dma.h>
 #include <mach/sps.h>
 #include <mach/msm_serial_hs.h>
+#include <mach/msm_bus.h>
 
 #include "msm_serial_hs_hwreg.h"
 #define UART_SPS_CONS_PERIPHERAL 0
@@ -211,6 +212,10 @@
 	 * callback event object registered for an SPS connection end point.
 	 */
 	struct sps_event_notify notify;
+	/* bus client handler */
+	u32 bus_perf_client;
+	/* BLSP UART required BUS Scaling data */
+	struct msm_bus_scale_pdata *bus_scale_table;
 };
 
 #define MSM_UARTDM_BURST_SIZE 16   /* DM burst size (in bytes) */
@@ -1622,6 +1627,7 @@
 {
 	unsigned long sr_status;
 	unsigned long flags;
+	int ret;
 	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
 	struct circ_buf *tx_buf = &uport->state->xmit;
 
@@ -1702,6 +1708,15 @@
 	wake_unlock(&msm_uport->dma_wake_lock);
 
 	spin_unlock_irqrestore(&uport->lock, flags);
+
+	/* Reset PNOC Bus Scaling */
+	if (is_blsp_uart(msm_uport)) {
+		ret = msm_bus_scale_client_update_request(
+				msm_uport->bus_perf_client, 0);
+		if (ret)
+			pr_err("%s(): Failed to reset bus bw vote\n", __func__);
+	}
+
 	mutex_unlock(&msm_uport->clk_mutex);
 	return 1;
 }
@@ -1872,6 +1887,16 @@
 		wake_lock(&msm_uport->dma_wake_lock);
 		disable_irq_nosync(msm_uport->wakeup.irq);
 		spin_unlock_irqrestore(&uport->lock, flags);
+
+		/* Vote for PNOC BUS Scaling */
+		if (is_blsp_uart(msm_uport)) {
+			ret = msm_bus_scale_client_update_request(
+					msm_uport->bus_perf_client, 1);
+			if (ret)
+				pr_err("%s():Failed to vote for bus scaling.\n",
+								__func__);
+		}
+
 		ret = clk_prepare_enable(msm_uport->clk);
 		if (ret) {
 			dev_err(uport->dev, "Clock ON Failure"
@@ -2116,6 +2141,15 @@
 		disable_irq(msm_uport->wakeup.irq);
 	}
 
+	/* Vote for PNOC BUS Scaling */
+	if (is_blsp_uart(msm_uport)) {
+		ret = msm_bus_scale_client_update_request(
+				msm_uport->bus_perf_client, 1);
+		if (ret)
+			pr_err("%s(): Failed to vote for bus scaling\n",
+								__func__);
+	}
+
 	spin_lock_irqsave(&uport->lock, flags);
 
 	msm_hs_start_rx_locked(uport);
@@ -2555,7 +2589,7 @@
 
 static int __devinit msm_hs_probe(struct platform_device *pdev)
 {
-	int ret;
+	int ret = 0;
 	struct uart_port *uport;
 	struct msm_hs_port *msm_uport;
 	struct resource *core_resource;
@@ -2637,6 +2671,20 @@
 		uport->irq = core_irqres;
 		msm_uport->bam_irq = bam_irqres;
 
+		msm_uport->bus_scale_table = msm_bus_cl_get_pdata(pdev);
+		if (!msm_uport->bus_scale_table) {
+			pr_err("BLSP UART: Bus scaling is disabled\n");
+			goto unmap_memory;
+		} else {
+			msm_uport->bus_perf_client =
+				msm_bus_scale_register_client
+					(msm_uport->bus_scale_table);
+			if (IS_ERR(&msm_uport->bus_perf_client)) {
+				pr_err("%s(): Bus client register failed.\n",
+								__func__);
+				goto unmap_memory;
+			}
+		}
 	} else {
 
 		resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -2907,6 +2955,15 @@
 	 * Hence mb() requires here.
 	 */
 	mb();
+
+	/* Reset PNOC Bus Scaling */
+	if (is_blsp_uart(msm_uport)) {
+		ret = msm_bus_scale_client_update_request(
+				msm_uport->bus_perf_client, 0);
+		if (ret)
+			pr_err("%s(): Failed to reset bus bw vote\n", __func__);
+	}
+
 	if (msm_uport->clk_state != MSM_HS_CLK_OFF) {
 		/* to balance clk_state */
 		clk_disable_unprepare(msm_uport->clk);
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index 0411baa..9333e57 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -1205,45 +1205,33 @@
 static void hdmi_edid_extract_speaker_allocation_data(const uint8 *in_buf)
 {
 	uint8 len;
-	const uint8 *sad = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 4,
+	const uint8 *sadb = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 4,
 			&len);
 
-	if (sad == NULL)
+	if (sadb == NULL)
 		return;
 
-	external_common_state->speaker_allocation_block = sad[1];
-	DEV_DBG("EDID: speaker allocation data SP byte = %08x %s%s%s%s%s%s%s\n",
-		sad[1],
-		(sad[1] & BIT(0)) ? "FL/FR," : "",
-		(sad[1] & BIT(1)) ? "LFE," : "",
-		(sad[1] & BIT(2)) ? "FC," : "",
-		(sad[1] & BIT(3)) ? "RL/RR," : "",
-		(sad[1] & BIT(4)) ? "RC," : "",
-		(sad[1] & BIT(5)) ? "FLC/FRC," : "",
-		(sad[1] & BIT(6)) ? "RLC/RRC," : "");
+	if (len != MAX_SPKR_ALLOC_DATA_BLOCK_SIZE)
+		return;
+
+	memcpy(external_common_state->spkr_alloc_data_block, sadb + 1, len);
+	external_common_state->sadb_size = len;
 }
 
 static void hdmi_edid_extract_audio_data_blocks(const uint8 *in_buf)
 {
 	uint8 len;
-	const uint8 *sad = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 1,
+	const uint8 *adb = hdmi_edid_find_block(in_buf, DBC_START_OFFSET, 1,
 			&len);
-	uint32 *adb = external_common_state->audio_data_blocks;
 
-	if (sad == NULL)
+	if (external_common_state->audio_data_block == NULL)
 		return;
 
-	external_common_state->audio_data_block_cnt = 0;
-	while (len >= 3 && external_common_state->audio_data_block_cnt < 16) {
-		DEV_DBG("EDID: Audio Data Block=<ch=%d, format=%d "
-			"sampling=0x%02x bit-depth=0x%02x>\n",
-			(sad[1] & 0x7)+1, sad[1] >> 3, sad[2], sad[3]);
-		*adb++ = (uint32)sad[1] + ((uint32)sad[2] << 8)
-			+ ((uint32)sad[2] << 16);
-		++external_common_state->audio_data_block_cnt;
-		len -= 3;
-		sad += 3;
-	}
+	if (len > MAX_AUDIO_DATA_BLOCK_SIZE)
+		return;
+
+	memcpy(external_common_state->audio_data_block, adb + 1, len);
+	external_common_state->adb_size = len;
 }
 
 static void hdmi_edid_extract_extended_data_blocks(const uint8 *in_buf)
@@ -1874,6 +1862,12 @@
 		sizeof(external_common_state->disp_mode_list));
 	memset(edid_buf, 0, sizeof(edid_buf));
 	external_common_state->default_res_supported = false;
+	memset(external_common_state->audio_data_block, 0,
+		sizeof(external_common_state->audio_data_block));
+	memset(external_common_state->spkr_alloc_data_block, 0,
+		sizeof(external_common_state->spkr_alloc_data_block));
+	external_common_state->adb_size = 0;
+	external_common_state->sadb_size = 0;
 
 	status = hdmi_common_read_edid_block(0, edid_buf);
 	if (status || !check_edid_header(edid_buf)) {
diff --git a/drivers/video/msm/external_common.h b/drivers/video/msm/external_common.h
index 70a99ee..b27e4c8 100644
--- a/drivers/video/msm/external_common.h
+++ b/drivers/video/msm/external_common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -206,6 +206,14 @@
 };
 #endif
 
+/*
+ * As per the CEA-861E spec, there can be a total of 10 short audio
+ * descriptors with each SAD being 3 bytes long.
+ * Thus, the maximum length of the audio data block would be 30 bytes
+ */
+#define MAX_AUDIO_DATA_BLOCK_SIZE	30
+#define MAX_SPKR_ALLOC_DATA_BLOCK_SIZE	3
+
 struct external_common_state_type {
 	boolean hpd_state;
 	struct kobject *uevent_kobj;
@@ -223,9 +231,7 @@
 	boolean hpd_feature_on;
 	boolean hdmi_sink;
 	struct hdmi_disp_mode_list_type disp_mode_list;
-	uint8 speaker_allocation_block;
 	uint16 video_latency, audio_latency;
-	uint8 audio_data_block_cnt;
 	uint16 physical_address;
 	uint32 preferred_video_format;
 	uint8 pt_scan_info;
@@ -235,7 +241,10 @@
 	uint8 spd_product_description[16];
 	boolean present_3d;
 	boolean present_hdcp;
-	uint32 audio_data_blocks[16];
+	uint8 audio_data_block[MAX_AUDIO_DATA_BLOCK_SIZE];
+	int adb_size;
+	uint8 spkr_alloc_data_block[MAX_SPKR_ALLOC_DATA_BLOCK_SIZE];
+	int sadb_size;
 	int (*read_edid_block)(int block, uint8 *edid_buf);
 	int (*hpd_feature)(int on);
 #endif
diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c
index 38fc969..2423de5 100644
--- a/drivers/video/msm/mdp4_util.c
+++ b/drivers/video/msm/mdp4_util.c
@@ -3087,14 +3087,11 @@
 	int ret = 0;
 	unsigned int ptr;
 
-	if (addr == NULL)
-		goto end;
-
 	ptr = (unsigned int) addr;
 
 	if (mdp_rev >= MDP_REV_30 && mdp_rev < MDP_REV_40) {
 		/* if request is outside the MDP reg-map or is not aligned 4 */
-		if (ptr > 0xF0600 || ptr % 0x4)
+		if (ptr == 0x0 || ptr > 0xF0600 || ptr % 0x4)
 			goto end;
 
 		if (ptr >= 0x90000 && ptr < 0x94000) {
@@ -3119,7 +3116,8 @@
 			goto end;
 
 		if (ptr < 0x90000) {
-			if (ptr == 0x4 || ptr == 0x28200 || ptr == 0x28204)
+			if (ptr == 0x0 || ptr == 0x4 || ptr == 0x28200 ||
+								ptr == 0x28204)
 				ret = 1;
 		} else if (ptr < 0x95000) {
 			if (ptr == 0x90000 || ptr == 0x90070)
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 80db0b2..a283e0a 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -588,10 +588,10 @@
 
 			msleep(20);
 			ret = mfd->off_fnc(mfd);
-			if (ret) {
+			if (ret)
 				mfd->panel_power_on = curr_pwr_state;
+			else
 				mdss_fb_release_fences(mfd);
-			}
 			mfd->op_enable = true;
 		}
 		break;
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 2f4c2ed..6030cbc 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -698,6 +698,14 @@
 		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(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 a7f0148..d2b2eab 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -185,6 +185,7 @@
 #define MDSS_MDP_REG_VIG_QSEED2_C03_INIT_PHASEY		0x224
 #define MDSS_MDP_REG_VIG_QSEED2_C12_INIT_PHASEX		0x228
 #define MDSS_MDP_REG_VIG_QSEED2_C12_INIT_PHASEY		0x22C
+#define MDSS_MDP_REG_VIG_PA_BASE			0x310
 
 #define MDSS_MDP_REG_SCALE_CONFIG			0x204
 #define MDSS_MDP_REG_SCALE_PHASE_STEP_X			0x210
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
index a1f1bcc..2c0ddda 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* 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
@@ -265,6 +265,9 @@
 
 	ctx = (struct mdss_mdp_writeback_ctx *) ctl->priv_data;
 	if (ctx) {
+		mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num,
+				   NULL, NULL);
+
 		ctl->priv_data = NULL;
 		ctx->ref_cnt--;
 	}
@@ -318,8 +321,6 @@
 	flush_bits = BIT(16); /* WB */
 	mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_FLUSH, flush_bits);
 
-	mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num,
-				   mdss_mdp_writeback_intr_done, ctx);
 	mdss_mdp_irq_enable(ctx->intr_type, ctx->intf_num);
 
 	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
@@ -353,6 +354,9 @@
 	ctx->wb_num = ctl->num;	/* wb num should match ctl num */
 	ctx->initialized = false;
 
+	mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num,
+				   mdss_mdp_writeback_intr_done, ctx);
+
 	if (ctx->type == MDSS_MDP_WRITEBACK_TYPE_ROTATOR)
 		ctl->prepare_fnc = mdss_mdp_writeback_prepare_rot;
 	else /* wfd or line mode */
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index 42e7337..242be60 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -409,12 +409,14 @@
 
 static int pp_vig_pipe_setup(struct mdss_mdp_pipe *pipe, u32 *op)
 {
-	u32 opmode = 0;
+	struct pp_sts_type pp_sts;
+	u32 opmode = 0, base = 0;
+	unsigned long flags = 0;
 
 	pr_debug("pnum=%x\n", pipe->num);
 
-	if (pipe->flags & MDP_OVERLAY_PP_CFG_EN) {
-		if (pipe->pp_cfg.config_ops & MDP_OVERLAY_PP_CSC_CFG) {
+	if ((pipe->flags & MDP_OVERLAY_PP_CFG_EN) &&
+		(pipe->pp_cfg.config_ops & MDP_OVERLAY_PP_CSC_CFG)) {
 			opmode |= !!(pipe->pp_cfg.csc_cfg.flags &
 						MDP_CSC_FLAG_ENABLE) << 17;
 			opmode |= !!(pipe->pp_cfg.csc_cfg.flags &
@@ -428,7 +430,6 @@
 			if (pipe->play_cnt == 0)
 				mdss_mdp_csc_setup_data(MDSS_MDP_BLOCK_SSPP,
 				  pipe->num, 1, &pipe->pp_cfg.csc_cfg);
-		}
 	} else {
 		if (pipe->src_fmt->is_yuv)
 			opmode |= (0 << 19) |	/* DST_DATA=RGB */
@@ -444,6 +445,19 @@
 		}
 	}
 
+	if (pipe->flags & MDP_OVERLAY_PP_CFG_EN) {
+		if (pipe->pp_cfg.config_ops & MDP_OVERLAY_PP_PA_CFG) {
+			flags = PP_FLAGS_DIRTY_PA;
+			base = MDSS_MDP_REG_SSPP_OFFSET(pipe->num) +
+				MDSS_MDP_REG_VIG_PA_BASE;
+			pp_sts.pa_sts = 0;
+			pp_pa_config(flags, base, &pp_sts,
+					&pipe->pp_cfg.pa_cfg);
+			if (pp_sts.pa_sts & PP_STS_ENABLE)
+				opmode |= (1 << 4); /* PA_EN */
+		}
+	}
+
 	*op = opmode;
 
 	return 0;
diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c
index 75a926a..911e29f 100644
--- a/drivers/video/msm/mdss/mdss_mdp_util.c
+++ b/drivers/video/msm/mdss/mdss_mdp_util.c
@@ -78,7 +78,7 @@
 			       void (*fnc_ptr)(void *), void *arg)
 {
 	unsigned long flags;
-	int index, ret;
+	int index;
 
 	index = mdss_mdp_intr2index(intr_type, intf_num);
 	if (index < 0) {
@@ -88,16 +88,13 @@
 	}
 
 	spin_lock_irqsave(&mdss_mdp_intr_lock, flags);
-	if (!mdp_intr_cb[index].func) {
-		mdp_intr_cb[index].func = fnc_ptr;
-		mdp_intr_cb[index].arg = arg;
-		ret = 0;
-	} else {
-		ret = -EBUSY;
-	}
+	WARN(mdp_intr_cb[index].func && fnc_ptr,
+		"replacing current intr callback for ndx=%d\n", index);
+	mdp_intr_cb[index].func = fnc_ptr;
+	mdp_intr_cb[index].arg = arg;
 	spin_unlock_irqrestore(&mdss_mdp_intr_lock, flags);
 
-	return ret;
+	return 0;
 }
 
 static inline void mdss_mdp_intr_done(int index)
diff --git a/include/linux/test-iosched.h b/include/linux/test-iosched.h
index ec28463..3690160 100644
--- a/include/linux/test-iosched.h
+++ b/include/linux/test-iosched.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, Code Aurora Forum. All rights reserved.
+/* 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
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 671889b..c588420 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -474,6 +474,7 @@
  * @active_conn_num: number of active pipe connections.
  * @usb_base_address: BAM physical address.
  * @ignore_core_reset_ack: BAM can ignore ACK from USB core during PIPE RESET
+ * @disable_clk_gating: Disable clock gating
  */
 struct msm_usb_bam_platform_data {
 	struct usb_bam_pipe_connect *connections;
@@ -483,6 +484,7 @@
 	u32 usb_base_address;
 	bool ignore_core_reset_ack;
 	bool reset_on_connect[MAX_BAMS];
+	bool disable_clk_gating;
 };
 
 /**
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index bc25e24..9d38db32 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1498,6 +1498,7 @@
 	V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE		= 0,
 	V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB		= 1,
 	V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES	= 2,
+	V4L2_MPEG_VIDEO_MULTI_SLICE_GOB			= 3,
 };
 #define V4L2_CID_MPEG_VIDEO_VBV_SIZE			(V4L2_CID_MPEG_BASE+222)
 #define V4L2_CID_MPEG_VIDEO_DEC_PTS			(V4L2_CID_MPEG_BASE+223)
@@ -1845,7 +1846,8 @@
 	V4L2_CID_MPEG_VIDC_PERF_LEVEL_PERFORMANCE		= 0,
 	V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO			= 1,
 };
-
+#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_GOB		\
+		(V4L2_CID_MPEG_MSM_VIDC_BASE+27)
 /*  Camera class control IDs */
 #define V4L2_CID_CAMERA_CLASS_BASE 	(V4L2_CTRL_CLASS_CAMERA | 0x900)
 #define V4L2_CID_CAMERA_CLASS 		(V4L2_CTRL_CLASS_CAMERA | 1)
diff --git a/include/media/msmb_isp.h b/include/media/msmb_isp.h
index 01276bd..4e92f70 100644
--- a/include/media/msmb_isp.h
+++ b/include/media/msmb_isp.h
@@ -8,7 +8,8 @@
 
 #define ISP_VERSION_40        40
 #define ISP_VERSION_32        32
-
+#define ISP_NATIVE_BUF_BIT    0x10000
+#define ISP_STATS_STREAM_BIT  0x80000000
 
 enum ISP_START_PIXEL_PATTERN {
 	ISP_BAYER_RGRGRG,
@@ -160,6 +161,8 @@
 	uint32_t session_id;
 	uint32_t stream_id;
 	enum msm_isp_stats_type stats_type;
+	uint8_t comp_flag;
+	uint32_t framedrop_pattern;
 	uint32_t stream_handle;
 };
 struct msm_vfe_stats_stream_release_cmd {
diff --git a/include/sound/msm-dai-q6-v2.h b/include/sound/msm-dai-q6-v2.h
index 347503d..c34a397 100644
--- a/include/sound/msm-dai-q6-v2.h
+++ b/include/sound/msm-dai-q6-v2.h
@@ -40,7 +40,7 @@
 };
 
 struct msm_dai_auxpcm_pdata {
-	const char *clk;
+	void *clk_cfg;
 	struct msm_dai_auxpcm_config mode_8k;
 	struct msm_dai_auxpcm_config mode_16k;
 };
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index ad1546d..41a9cc5 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -4902,11 +4902,6 @@
 	taiko = snd_soc_codec_get_drvdata(codec);
 	mutex_lock(&codec->mutex);
 	WCD9XXX_BCL_LOCK(&taiko->resmgr);
-	if (spkr_drv_wrnd == 1) {
-		wcd9xxx_resmgr_post_ssr(&taiko->resmgr);
-		snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x80);
-	}
-	WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
 
 	if (codec->reg_def_copy) {
 		pr_debug("%s: Update ASOC cache", __func__);
@@ -4915,11 +4910,23 @@
 						codec->reg_size, GFP_KERNEL);
 	}
 
+	wcd9xxx_resmgr_post_ssr(&taiko->resmgr);
+	if (spkr_drv_wrnd == 1)
+		snd_soc_update_bits(codec, TAIKO_A_SPKR_DRV_EN, 0x80, 0x80);
+	WCD9XXX_BCL_UNLOCK(&taiko->resmgr);
+
 	taiko_update_reg_defaults(codec);
 	taiko_codec_init_reg(codec);
 	ret = taiko_handle_pdata(taiko);
 	if (IS_ERR_VALUE(ret))
 		pr_err("%s: bad pdata\n", __func__);
+
+	wcd9xxx_mbhc_deinit(&taiko->mbhc);
+	ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec);
+	if (ret)
+		pr_err("%s: mbhc init failed %d\n", __func__, ret);
+	else
+		wcd9xxx_mbhc_start(&taiko->mbhc, taiko->mbhc.mbhc_cfg);
 	mutex_unlock(&codec->mutex);
 	return ret;
 }
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index 0f2a19c..8acc334 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* 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
@@ -3177,23 +3177,28 @@
 	mbhc->resmgr = resmgr;
 	mbhc->resmgr->mbhc = mbhc;
 
-	ret = snd_soc_jack_new(codec, "Headset Jack", WCD9XXX_JACK_MASK,
-			       &mbhc->headset_jack);
-	if (ret) {
-		pr_err("%s: Failed to create new jack\n", __func__);
-		return ret;
-	}
+	if (mbhc->headset_jack.jack == NULL) {
+		ret = snd_soc_jack_new(codec, "Headset Jack", WCD9XXX_JACK_MASK,
+				       &mbhc->headset_jack);
+		if (ret) {
+			pr_err("%s: Failed to create new jack\n", __func__);
+			return ret;
+		}
 
-	ret = snd_soc_jack_new(codec, "Button Jack", WCD9XXX_JACK_BUTTON_MASK,
-			       &mbhc->button_jack);
-	if (ret) {
-		pr_err("Failed to create new jack\n");
-		return ret;
-	}
+		ret = snd_soc_jack_new(codec, "Button Jack",
+				       WCD9XXX_JACK_BUTTON_MASK,
+				       &mbhc->button_jack);
+		if (ret) {
+			pr_err("Failed to create new jack\n");
+			return ret;
+		}
 
-	INIT_DELAYED_WORK(&mbhc->mbhc_firmware_dwork, wcd9xxx_mbhc_fw_read);
-	INIT_DELAYED_WORK(&mbhc->mbhc_btn_dwork, wcd9xxx_btn_lpress_fn);
-	INIT_DELAYED_WORK(&mbhc->mbhc_insert_dwork, wcd9xxx_mbhc_insert_work);
+		INIT_DELAYED_WORK(&mbhc->mbhc_firmware_dwork,
+				  wcd9xxx_mbhc_fw_read);
+		INIT_DELAYED_WORK(&mbhc->mbhc_btn_dwork, wcd9xxx_btn_lpress_fn);
+		INIT_DELAYED_WORK(&mbhc->mbhc_insert_dwork,
+				  wcd9xxx_mbhc_insert_work);
+	}
 
 	/* Register event notifier */
 	mbhc->nblock.notifier_call = wcd9xxx_event_notify;
@@ -3294,6 +3299,11 @@
 	wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_MBHC_REMOVAL, mbhc);
 	wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_MBHC_INSERTION, mbhc);
 
+	wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_MBHC_JACK_SWITCH, mbhc);
+	wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_HPH_PA_OCPL_FAULT, mbhc);
+	wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_HPH_PA_OCPR_FAULT, mbhc);
+	wcd9xxx_free_irq(cdata, WCD9XXX_IRQ_MBHC_RELEASE, mbhc);
+
 	if (mbhc->mbhc_fw)
 		release_firmware(mbhc->mbhc_fw);
 
diff --git a/sound/soc/codecs/wcd9xxx-resmgr.c b/sound/soc/codecs/wcd9xxx-resmgr.c
index 0ab650e..17edd4a 100644
--- a/sound/soc/codecs/wcd9xxx-resmgr.c
+++ b/sound/soc/codecs/wcd9xxx-resmgr.c
@@ -198,19 +198,44 @@
 void wcd9xxx_resmgr_post_ssr(struct wcd9xxx_resmgr *resmgr)
 {
 	int old_bg_audio_users, old_bg_mbhc_users;
+	int old_clk_rco_users, old_clk_mclk_users;
 
+	pr_debug("%s: enter\n", __func__);
 	WCD9XXX_BCL_ASSERT_LOCKED(resmgr);
 
 	old_bg_audio_users = resmgr->bg_audio_users;
-	resmgr->bg_audio_users = 0;
 	old_bg_mbhc_users = resmgr->bg_mbhc_users;
+	old_clk_rco_users = resmgr->clk_rco_users;
+	old_clk_mclk_users = resmgr->clk_mclk_users;
+	resmgr->bg_audio_users = 0;
 	resmgr->bg_mbhc_users = 0;
+	resmgr->bandgap_type = WCD9XXX_BANDGAP_OFF;
+	resmgr->clk_rco_users = 0;
+	resmgr->clk_mclk_users = 0;
+	resmgr->clk_type = WCD9XXX_CLK_OFF;
 
-	while (old_bg_audio_users && --old_bg_audio_users)
-		wcd9xxx_resmgr_get_bandgap(resmgr, WCD9XXX_BANDGAP_AUDIO_MODE);
+	if (old_bg_audio_users) {
+		while (old_bg_audio_users--)
+			wcd9xxx_resmgr_get_bandgap(resmgr,
+						  WCD9XXX_BANDGAP_AUDIO_MODE);
+	}
 
-	while (old_bg_mbhc_users && --old_bg_mbhc_users)
-		wcd9xxx_resmgr_get_bandgap(resmgr, WCD9XXX_BANDGAP_MBHC_MODE);
+	if (old_bg_mbhc_users) {
+		while (old_bg_mbhc_users--)
+			wcd9xxx_resmgr_get_bandgap(resmgr,
+						  WCD9XXX_BANDGAP_MBHC_MODE);
+	}
+
+	if (old_clk_mclk_users) {
+		while (old_clk_mclk_users--)
+			wcd9xxx_resmgr_get_clk_block(resmgr, WCD9XXX_CLK_MCLK);
+	}
+
+	if (old_clk_rco_users) {
+		while (old_clk_rco_users--)
+			wcd9xxx_resmgr_get_clk_block(resmgr, WCD9XXX_CLK_RCO);
+	}
+	pr_debug("%s: leave\n", __func__);
 }
 
 /*
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index 4f90400..cf7f182 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -28,6 +28,15 @@
 #include <sound/pcm_params.h>
 #include <mach/clk.h>
 
+static const struct afe_clk_cfg lpass_clk_cfg_default = {
+	AFE_API_VERSION_I2S_CONFIG,
+	Q6AFE_LPASS_OSR_CLK_2_P048_MHZ,
+	0,
+	Q6AFE_LPASS_CLK_SRC_INTERNAL,
+	Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+	Q6AFE_LPASS_MODE_CLK1_VALID,
+	0,
+};
 enum {
 	STATUS_PORT_STARTED, /* track if AFE port has started */
 	STATUS_MAX
@@ -76,11 +85,6 @@
 	SOC_ENUM_SINGLE_EXT(4, mi2s_format),
 };
 
-static struct clk *pcm_src_clk;
-static struct clk *pcm_branch_clk;
-static struct clk *pcm_oe_src_clk;
-static struct clk *pcm_oe_branch_clk;
-
 static DEFINE_MUTEX(aux_pcm_mutex);
 static int aux_pcm_count;
 
@@ -148,6 +152,9 @@
 				struct snd_soc_dai *dai)
 {
 	int rc = 0;
+	struct afe_clk_cfg *lpass_pcm_src_clk = NULL;
+	struct afe_clk_cfg lpass_pcm_oe_clk;
+	struct msm_dai_auxpcm_pdata *auxpcm_pdata = NULL;
 
 	mutex_lock(&aux_pcm_mutex);
 
@@ -176,6 +183,9 @@
 	pr_debug("%s: dai->id = %d aux_pcm_count = %d\n", __func__,
 			dai->id, aux_pcm_count);
 
+	auxpcm_pdata = (struct msm_dai_auxpcm_pdata *)dai->dev->platform_data;
+	lpass_pcm_src_clk = (struct afe_clk_cfg *)auxpcm_pdata->clk_cfg;
+
 	rc = afe_close(PCM_RX); /* can block */
 	if (IS_ERR_VALUE(rc))
 		dev_err(dai->dev, "fail to close PCM_RX  AFE port\n");
@@ -184,8 +194,14 @@
 	if (IS_ERR_VALUE(rc))
 		dev_err(dai->dev, "fail to close AUX PCM TX port\n");
 
-	clk_disable_unprepare(pcm_branch_clk);
-	clk_disable_unprepare(pcm_oe_branch_clk);
+	lpass_pcm_src_clk->clk_val1 = 0;
+	afe_set_lpass_clock(PCM_TX, lpass_pcm_src_clk);
+	afe_set_lpass_clock(PCM_RX, lpass_pcm_src_clk);
+
+	memcpy(&lpass_pcm_oe_clk, &lpass_clk_cfg_default,
+			 sizeof(struct afe_clk_cfg));
+	lpass_pcm_oe_clk.clk_val1 = 0;
+	afe_set_lpass_clock(PCM_RX, &lpass_pcm_oe_clk);
 
 	mutex_unlock(&aux_pcm_mutex);
 }
@@ -197,8 +213,11 @@
 	struct msm_dai_auxpcm_pdata *auxpcm_pdata = NULL;
 	int rc = 0;
 	unsigned long pcm_clk_rate;
+	struct afe_clk_cfg lpass_pcm_oe_clk;
+	struct afe_clk_cfg *lpass_pcm_src_clk = NULL;
 
 	auxpcm_pdata = dai->dev->platform_data;
+	lpass_pcm_src_clk = (struct afe_clk_cfg *)auxpcm_pdata->clk_cfg;
 
 	mutex_lock(&aux_pcm_mutex);
 
@@ -252,32 +271,32 @@
 		return -EINVAL;
 	}
 
-	rc = clk_set_rate(pcm_src_clk, pcm_clk_rate);
+	memcpy(lpass_pcm_src_clk, &lpass_clk_cfg_default,
+			sizeof(struct afe_clk_cfg));
+	lpass_pcm_src_clk->clk_val1 = pcm_clk_rate;
 
+	memcpy(&lpass_pcm_oe_clk, &lpass_clk_cfg_default,
+			sizeof(struct afe_clk_cfg));
+	lpass_pcm_oe_clk.clk_val1 = Q6AFE_LPASS_OSR_CLK_12_P288_MHZ;
+
+	rc = afe_set_lpass_clock(PCM_RX, lpass_pcm_src_clk);
 	if (rc < 0) {
-		pr_err("%s: clk_set_rate failed\n", __func__);
-		mutex_unlock(&aux_pcm_mutex);
+		pr_err("%s:afe_set_lpass_clock on RX pcm_src_clk failed\n",
+							__func__);
 		goto fail;
 	}
 
-	rc = clk_prepare_enable(pcm_branch_clk);
-	if (rc) {
-		pr_err("%s: clk enable failed\n", __func__);
-		mutex_unlock(&aux_pcm_mutex);
-		goto fail;
-	}
-
-	rc = clk_set_rate(pcm_oe_src_clk, 24576000>>1);
+	rc = afe_set_lpass_clock(PCM_TX, lpass_pcm_src_clk);
 	if (rc < 0) {
-		pr_err("%s: clk_set_rate on pcm oe failed\n", __func__);
-		mutex_unlock(&aux_pcm_mutex);
+		pr_err("%s:afe_set_lpass_clock on TX pcm_src_clk failed\n",
+							__func__);
 		goto fail;
 	}
 
-	rc = clk_prepare_enable(pcm_oe_branch_clk);
-	if (rc) {
-		pr_err("%s: clk enable pcm_oe_branch_clk failed\n", __func__);
-		mutex_unlock(&aux_pcm_mutex);
+	rc = afe_set_lpass_clock(PCM_RX, &lpass_pcm_oe_clk);
+	if (rc < 0) {
+		pr_err("%s:afe_set_lpass_clock on pcm_oe_clk failed\n",
+							__func__);
 		goto fail;
 	}
 
@@ -285,9 +304,8 @@
 
 	afe_open(PCM_TX, &dai_data->port_config, dai_data->rate);
 
-	mutex_unlock(&aux_pcm_mutex);
-
 fail:
+	mutex_unlock(&aux_pcm_mutex);
 	return rc;
 }
 
@@ -331,49 +349,6 @@
 	dai->dev->platform_data = auxpcm_pdata;
 	dai->id = dai->dev->id;
 
-	mutex_lock(&aux_pcm_mutex);
-
-	/*
-	 * The clk name for AUX PCM operation is passed as platform
-	 * data to the cpu driver, since cpu drive is unaware of any
-	 * boarc specific configuration.
-	 */
-	if ((!pcm_src_clk) || (!pcm_branch_clk)) {
-		pcm_src_clk = clk_get(dai->dev, auxpcm_pdata->clk);
-
-		if (IS_ERR(pcm_src_clk)) {
-			pr_err("%s: could not get pcm_src_clk\n", __func__);
-			pcm_src_clk = NULL;
-			return -ENODEV;
-		}
-
-		pcm_branch_clk = clk_get(dai->dev, "ibit_clk");
-
-		if (IS_ERR(pcm_branch_clk)) {
-			pr_err("%s: could not get pcm_branch_clk\n", __func__);
-			pcm_branch_clk = NULL;
-			return -ENODEV;
-		}
-	}
-
-	if ((!pcm_oe_src_clk) || (!pcm_oe_branch_clk)) {
-
-		pcm_oe_src_clk = clk_get(dai->dev, "core_oe_src_clk");
-
-		if (IS_ERR(pcm_oe_src_clk)) {
-			pr_err("%s: could not get pcm_oe_src_clk\n", __func__);
-			pcm_oe_src_clk = NULL;
-			return -ENODEV;
-		}
-
-		pcm_oe_branch_clk = clk_get(dai->dev, "core_oe_clk");
-		if (IS_ERR(pcm_oe_branch_clk)) {
-			pr_err("%s: could not get pcm_oe_clk\n", __func__);
-			pcm_oe_branch_clk = NULL;
-			return -ENODEV;
-		}
-	}
-	mutex_unlock(&aux_pcm_mutex);
 
 	dai_data = kzalloc(sizeof(struct msm_dai_q6_dai_data), GFP_KERNEL);
 
@@ -1107,6 +1082,7 @@
 {
 	int rc = 0;
 	struct msm_dai_auxpcm_pdata *auxpcm_pdata = NULL;
+	struct afe_clk_cfg *clk_cfg = NULL;
 	uint32_t val_array[RATE_MAX_NUM_OF_AUX_PCM_RATES];
 
 	auxpcm_pdata = kzalloc(sizeof(struct msm_dai_auxpcm_pdata),
@@ -1117,15 +1093,6 @@
 		return -ENOMEM;
 	}
 
-	rc = of_property_read_string(pdev->dev.of_node,
-			"qcom,msm-cpudai-auxpcm-clk",
-			&auxpcm_pdata->clk);
-	if (rc) {
-		dev_err(&pdev->dev, "%s: qcom,msm-cpudai-auxpcm-clk missing in DT node\n",
-			__func__);
-		goto fail_free_plat;
-	}
-
 	rc = of_property_read_u32_array(pdev->dev.of_node,
 			"qcom,msm-cpudai-auxpcm-mode",
 			val_array, RATE_MAX_NUM_OF_AUX_PCM_RATES);
@@ -1200,17 +1167,26 @@
 	auxpcm_pdata->mode_8k.pcm_clk_rate = (int)val_array[RATE_8KHZ];
 	auxpcm_pdata->mode_16k.pcm_clk_rate = (int)val_array[RATE_16KHZ];
 
+	clk_cfg = kzalloc(sizeof(struct afe_clk_cfg), GFP_KERNEL);
+	if (clk_cfg == NULL) {
+		pr_err("%s: Failed to allocate memory for clk cfg\n", __func__);
+		goto fail_free_plat;
+	}
+	auxpcm_pdata->clk_cfg = clk_cfg;
+
 	platform_set_drvdata(pdev, auxpcm_pdata);
 
 	rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
 	if (rc) {
 		dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n",
 				__func__, rc);
-		goto fail_free_plat;
+		goto fail_free_plat1;
 	}
 
 	return rc;
 
+fail_free_plat1:
+	kfree(clk_cfg);
 fail_free_plat:
 	kfree(auxpcm_pdata);
 	return rc;
@@ -1225,9 +1201,12 @@
 static int __devexit msm_auxpcm_resource_remove(
 				struct platform_device *pdev)
 {
-	void *auxpcm_pdata;
+	struct msm_dai_auxpcm_pdata *auxpcm_pdata;
+	struct afe_clk_cfg *clk_cfg;
 
 	auxpcm_pdata = dev_get_drvdata(&pdev->dev);
+	clk_cfg = (struct afe_clk_cfg *)auxpcm_pdata->clk_cfg;
+	kfree(clk_cfg);
 	kfree(auxpcm_pdata);
 
 	return 0;